|
@@ -0,0 +1,233 @@
|
|
|
+.define WRCH, RDCH, Earray, Erange, Eset
|
|
|
+.define Eiovfl, Eidivz, Eiund, Econv
|
|
|
+.define Estack, Eheap, Eillins, Eoddz
|
|
|
+.define Ecase , Ebadmon, OSBYTE, MON
|
|
|
+.define Ebadlin, Ebadgto, BASE, NBYTES
|
|
|
+.define hol0, IGNMASK, ADDR, PROGNAME
|
|
|
+.define LB, LBl, SP, HP, ERRPROC, UNSIGN
|
|
|
+.define Ytmp, EXG, ARTH, RETURN, SIGN
|
|
|
+.define RETSIZE, TRAPVAL, STACK, BRANCH
|
|
|
+.define start, Push, Pop, STACKTh, STACKTl
|
|
|
+.define F_DUM
|
|
|
+.sect .zero
|
|
|
+.sect .text
|
|
|
+.sect .rom
|
|
|
+.sect .data
|
|
|
+.sect .bss
|
|
|
+.sect .text
|
|
|
+
|
|
|
+! DEFINITIONS
|
|
|
+
|
|
|
+ ! The next three definitions are special for the
|
|
|
+ ! BBC microcomputer
|
|
|
+
|
|
|
+WRCH = 0x0FFEE ! This subroutine writes the character in
|
|
|
+ ! register A to the screen
|
|
|
+RDCH = 0x0FFE0 ! This subroutine returns a character in
|
|
|
+ ! register A from the current input stream
|
|
|
+OSBYTE = 0x0FFF4 ! This subroutine performs miscelaneous
|
|
|
+ ! operating system calls
|
|
|
+
|
|
|
+F_DUM = 0 ! Dummy floating point constant
|
|
|
+
|
|
|
+ ! Here are the error numbers
|
|
|
+
|
|
|
+Earray = 0
|
|
|
+Erange = 1
|
|
|
+Eset = 2
|
|
|
+Eiovfl = 3
|
|
|
+Eidivz = 6
|
|
|
+Eiund = 8
|
|
|
+Econv = 10
|
|
|
+Estack = 16
|
|
|
+Eheap = 17
|
|
|
+Eillins = 18
|
|
|
+Eoddz = 19
|
|
|
+Ecase = 20
|
|
|
+Ebadmon = 25
|
|
|
+Ebadlin = 26
|
|
|
+Ebadgto = 27
|
|
|
+MON = 0x78D0
|
|
|
+
|
|
|
+BASE = 240 ! This is the offset from the localbase
|
|
|
+ ! for the second localbase
|
|
|
+
|
|
|
+STACKTh = 0x78 ! This is the top of the stack
|
|
|
+STACKTl = 0x0D0
|
|
|
+
|
|
|
+ ! Some zeropage declarations
|
|
|
+
|
|
|
+.sect .zero
|
|
|
+
|
|
|
+RES: .space 76 ! special for the operating system
|
|
|
+
|
|
|
+hol0: .space 16 ! the hol0 block
|
|
|
+
|
|
|
+IGNMASK: .space 2 ! can hold the ingnore mask
|
|
|
+
|
|
|
+ADDR: .space 4 ! used for indirect addressing
|
|
|
+
|
|
|
+LB: .space 2 ! the localbase
|
|
|
+
|
|
|
+LBl: .space 2 ! the second localbase (localbase-BASE)
|
|
|
+
|
|
|
+SP: .space 3 ! the stackpointer (real_stack)
|
|
|
+
|
|
|
+HP: .space 2 ! the heap pointer
|
|
|
+
|
|
|
+BRANCH: .space 2 ! used for branch instructions
|
|
|
+
|
|
|
+ERRPROC: .space 2 ! can hold the address of the error handler
|
|
|
+
|
|
|
+Ytmp: .space 1 ! used for intermediate storage in Y
|
|
|
+
|
|
|
+EXG: .space 2 ! used by the exchange subroutine Exg
|
|
|
+
|
|
|
+ARTH: .space 16 ! used for arithmetic
|
|
|
+
|
|
|
+NBYTES: .space 2 ! containes the number of bytes for a block move
|
|
|
+
|
|
|
+
|
|
|
+RETURN: .space 4 ! the return area
|
|
|
+
|
|
|
+RETSIZE: .space 1 ! the size of the object returned
|
|
|
+
|
|
|
+SIGN: .space 1 ! the sign of the calculation
|
|
|
+
|
|
|
+UNSIGN : .space 1 ! is it signed or unsigned arithmetic
|
|
|
+
|
|
|
+TRAPVAL: .space 1 ! intermediate storage of the error number
|
|
|
+
|
|
|
+STACK: .space 1 ! contains the hardware stackpointer on
|
|
|
+ ! entering _m_a_i_n for a neat return
|
|
|
+
|
|
|
+RESERVED: .space 112 ! used by the operating system
|
|
|
+
|
|
|
+.sect .text
|
|
|
+.base 0x0E02 ! where to start in the BBC micro
|
|
|
+! GENERAL PURPOSE ROUTINES
|
|
|
+
|
|
|
+start:
|
|
|
+ tsx
|
|
|
+ stx STACK ! save stackpointer for exit and error
|
|
|
+
|
|
|
+ ! The following three operating system calls are only
|
|
|
+ ! for the BBC microcomputer
|
|
|
+
|
|
|
+ lda #2
|
|
|
+ ldx #0
|
|
|
+ ldy #0
|
|
|
+ jsr OSBYTE ! return control to the keyboard
|
|
|
+ lda #15
|
|
|
+ ldx #0
|
|
|
+ ldy #0
|
|
|
+ jsr OSBYTE ! clear all internal buffers
|
|
|
+ lda #3
|
|
|
+ ldx #5
|
|
|
+ ldy #0
|
|
|
+ jsr OSBYTE ! output to screen and RS423
|
|
|
+
|
|
|
+ lda #STACKTl
|
|
|
+ sta LB ! set localbase (lowbyte)
|
|
|
+ sta SP+2
|
|
|
+ lda #0
|
|
|
+ sta SP ! set stackpointer (lowbyte)
|
|
|
+ sta ERRPROC ! set start address for error handler (lowbyte)
|
|
|
+ sta ERRPROC+1 ! set start address for error handler (highbyte)
|
|
|
+ sta hol0 ! set the line number (lowbyte)
|
|
|
+ sta hol0+1 ! set the line number (highbyte)
|
|
|
+ lda #STACKTh
|
|
|
+ sta SP+1 ! set the stacpointer (highbyte)
|
|
|
+ sta LB+1 ! set the localbase (highbyte)
|
|
|
+ lda #[endbss].l
|
|
|
+ sta HP ! set the heap pointer (lowbyte)
|
|
|
+ lda #[endbss].h
|
|
|
+ sta HP+1 ! set the heap pointer (highbyte)
|
|
|
+ lda #[PROGNAME].l
|
|
|
+ sta hol0+4 ! set fake programname pointer (lowbyte)
|
|
|
+ lda #[PROGNAME].h
|
|
|
+ sta hol0+5 ! set fake programname pointer (highbyte)
|
|
|
+ lda #[beginbss].l
|
|
|
+ sta ADDR ! start address of bss block (lowbyte)
|
|
|
+ lda #[beginbss].h
|
|
|
+ sta ADDR+1 ! start address of bss block (highbyte)
|
|
|
+ ldy #0
|
|
|
+ lda #0
|
|
|
+ 4: ldx #[endbss].h ! clear bss block
|
|
|
+ cpx ADDR+1
|
|
|
+ bcc 1f ! end of bss block reached
|
|
|
+ bne 2f
|
|
|
+ ldx #[endbss].l
|
|
|
+ cpx ADDR
|
|
|
+ bcc 1f ! end of bss block reached
|
|
|
+ 2: sta (ADDR),y
|
|
|
+ inc ADDR
|
|
|
+ bne 3f
|
|
|
+ inc ADDR+1
|
|
|
+ 3: jmp 4b
|
|
|
+ 1: lda #0
|
|
|
+ tax
|
|
|
+ jsr Push ! push fake envelope pointer
|
|
|
+ lda #[PROGNAME].h
|
|
|
+ ldx #[PROGNAME].l
|
|
|
+ jsr Push ! push argv[0]
|
|
|
+ lda #0
|
|
|
+ ldx #1
|
|
|
+ jsr Push ! push argc
|
|
|
+ jsr __m_a_i_n ! start the real program
|
|
|
+
|
|
|
+ lda #0x0FF
|
|
|
+ jsr WRCH ! send end of program to R423
|
|
|
+ lda #3
|
|
|
+ ldx #0
|
|
|
+ jsr OSBYTE ! send output to screen only
|
|
|
+ lda #2
|
|
|
+ ldx #1
|
|
|
+ jsr OSBYTE ! input only from R423
|
|
|
+ rts
|
|
|
+
|
|
|
+
|
|
|
+! The subroutine Push pushes the registerpair AX onto the stack.
|
|
|
+
|
|
|
+Push:
|
|
|
+ sty Ytmp ! save Y
|
|
|
+ ldy SP+2
|
|
|
+ bne 1f ! lowbyte of stackpointer <> 0
|
|
|
+ dec SP+1 ! decrement highbyte of stackpointer
|
|
|
+ 1: dey
|
|
|
+ dey ! decrement lowbyte of stackpointer
|
|
|
+ sty SP+2 ! save lowbyte of stackpointer
|
|
|
+ pha ! save A
|
|
|
+ txa
|
|
|
+ sta (SP),y ! push X onto the stack
|
|
|
+ iny
|
|
|
+ pla ! get A
|
|
|
+ sta (SP),y ! push A onto the stack
|
|
|
+ ldy Ytmp ! restore Y
|
|
|
+ rts
|
|
|
+
|
|
|
+
|
|
|
+! The subroutine Pop pops the registerpair AX from the stack.
|
|
|
+
|
|
|
+Pop:
|
|
|
+ sty Ytmp ! save Y
|
|
|
+ ldy SP+2
|
|
|
+ lda (SP),y ! pop X from the stack
|
|
|
+ tax
|
|
|
+ iny
|
|
|
+ lda (SP),y ! pop A from the stack
|
|
|
+ iny
|
|
|
+ bne 1f ! lowbyte of stackpointer <> 0
|
|
|
+ inc SP+1 ! increment highbyte of stackpointer
|
|
|
+ 1: sty SP+2 ! store lowbyte of stackpointer
|
|
|
+ pha ! save A
|
|
|
+ pla ! get A
|
|
|
+ ldy Ytmp ! restore Y
|
|
|
+ rts
|
|
|
+
|
|
|
+
|
|
|
+.sect .data
|
|
|
+PROGNAME: ! for initialising the programname pointer
|
|
|
+.asciz "program"
|
|
|
+.sect .bss
|
|
|
+beginbss:
|