From 5060a9fcd6953941976bd5115571a952ba4d9b3c Mon Sep 17 00:00:00 2001 From: keie Date: Mon, 17 Dec 1984 10:44:08 +0000 Subject: [PATCH] *** empty log message *** --- mach/6500/libem/head_em.s | 224 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 224 insertions(+) create mode 100644 mach/6500/libem/head_em.s diff --git a/mach/6500/libem/head_em.s b/mach/6500/libem/head_em.s new file mode 100644 index 000000000..9cdfbb8a7 --- /dev/null +++ b/mach/6500/libem/head_em.s @@ -0,0 +1,224 @@ +.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 + +! DEFINITIONS + + ! The next three definitions are special for the + ! BBC microcomputer + +WRCH = 0FFEEh ! This subroutine writes the character in + ! register A to the screen +RDCH = 0FFE0h ! This subroutine returns a character in + ! register A from the current input stream +OSBYTE = 0FFF4h ! This subroutine performs miscelaneous + ! operating system calls + + ! 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 = 78D0h + +BASE = 240 ! This is the offset from the localbase + ! for the second localbase + +STACKTh = 78h ! This is the top of the stack +STACKTl = 0D0h + + ! Some zeropage declarations + +.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 + +.base 0E02h ! where to start in the BBC micro +.text +! 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 #0FFh + 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 + + +.data +PROGNAME: ! for initialising the programname pointer +.asciz "program" +.bss +beginbss: