From ST2975@SIUCVMB.SIU.EDU Sat Jan 9 04:44:28 1993 Received: from calvin.sfasu.edu by umaxc.weeg.uiowa.edu (5.61.jnf/920629) on Sat, 9 Jan 93 04:44:25 -0600 id AA31439 with SMTP Received: from SIUCVMB.SIU.EDU by calvin.sfasu.EDU with SMTP (5.59/25-eef) id AA06789; Sat, 9 Jan 93 04:36:19 CST Return-Path: Message-Id: <9301091036.AA06789@calvin.sfasu.EDU> Received: from SIUCVMB.SIU.EDU by SIUCVMB.SIU.EDU (IBM VM SMTP V2R1) with BSMTP id 5196; Sat, 09 Jan 93 04:35:44 CST Date: Sat, 9 Jan 93 04:35:43 CST From: ST2975@SIUCVMB.SIU.EDU To: hyperc-l@calvin.sfasu.edu Subject: Re:rfd:mli interface for 802/816 ml modules Status: R For those familiar with 65816 assembly, following is the overhead that is involved in switching between an 8 bit emulation stack and a 16 bit native stack. These are the entry and exit points to the cp-interpreter. I like to conceptualize the interpreter like a house: the _brk is the front door and _jsr/_jsi are the back doors from which you can exit and return to the interpreter. Within the 16 bit interpreter is native 65802/816 machine code. Unless a signature byte of zero is seen by _jsr/_jsi, it must be assumed that a 6502 or emulation mode ml module is being called and switching of stacks and conditioning of the processor status register occurs. If anyone has an alternative idea of distinguishing a native mode module in memory, I'm all ears. Currently I look for a signature byte of $ea (nop) to signify that a native mode module is coming up and no stack switching happens. It saves a lot of overhead. code follows: .entry __brk __brk: clc xce bcc mode16 mode8: ; here on the (un)usual case of 6502 brk ldx 0xc088 ; this switch turns on upper 16k ram read/nowrite lda #0x21 ; this is essential for 65802's without support trb 0x48 ; for 16 bit vectors in ROM. brk vector set up ldy 0x48 ; by hc.sys802. phy ; if an irq happens here, stack is in page 1 plp ; must eventually return to 6502 code that hit ; ply ; brk in the first place, hence $1 lda #<$1-1 .byte >$1-1 ; return address later picked up by lnk/lnkv sta jp ; restored and rts'd to later via rtn/rtnv sei ; protect sp until the switch is made tsx ; get 8 bit stack pointer lda sp ; get interpreter stack pointer and decrement it dea ; because the machine sp points to C engine sp-1 tcs ; put 16 bit stack pointer in machine sp stx sp ; store 8 bit stack pointer here phy plp ; now irqs are re-enabled, using 16 bit stack lda pc ; sp low points to valid 8 bit stack pointer pha lda 0x3a dea ;Get the program counter sta pc bra _nextop $1: shorta ; here on return to 6502 code calling longi ; brk php ; save emulation status register for later pla ; m bit is 1, x-brk/irq bit is 0 tay longa ; get ready for stack switch ldx sp ; get 8 bit stack pointer stored previously sei ; point of no return... tsc ; get 16 bit stack pointer ina ; increment it so later 8 bit accesses work sta sp ; store it sec ; entering emulation mode xce ; txs ; now 8 bit stack pointer phy ; restore processor status register which was... plp ; ...modified by entering emulation mode bit 0xc08a ; now reading ROM rts ; return to 6502 machine code that called brk mode16: plp ; pull processor status register and restore it longai ; set up registers lda pc ; get old interpreter pc plx ; get new pc plb ; turn program bank register into data bank reg dex ; decrement pc.. was pointing to brk+2 stx pc ; store new interpreter pc plx ; now pull return address from stack put there stx jp ; store return address in jp.picked up by lnk(v) pha ; by jsr. push old pc on stack .entry _nextop _nextop: shortai ldy #0 lda [pc] asl a ;Put the high bit into the tax ;carry. longa inc pc jmp [_jmptable,x] ... .entry _jsr _jsr: jsr _getAddr ; get address we're jsr'ing to shorta ; get ready to look ahead lda [jp] ; look for brk machine code beq $1 ; it is... cmp #0xea ; check for 658xx sig... or whatever we choose beq $1 ; it is. support for 65802/816 native macros! $3: ; not 658xx sig... longi ; not brk, assume 6502 and set up stacks php ; set up processor status register shorti need 16 bit stack irq support for 65802s! ply ; b bit equals zero, m/1 bit = 1 ; tay accumulator and x register used to switch longa ; stacks ldx sp sei tsc ina ; still 16 bit stack register. sta sp ; still 16 bit stack register... sec xce txs ; now 8 bit stack register phy plp bit 0xc08a ; read rom so hgrlib works pea $2-1 ldx #0 jmp [jp,x] ; program bank register used (0 in this case) $2: ldx 0xc088 ; ram read/no write, so 16 bit irq/brk can work php ply clc ; on a 65802/816 IIe/c and no firmware support xce ; sigh! rep 0x21 lda sp dea sei tsx tcs phy stx sp plp jmp _nextop $1: longa ; enters with longa, short index regs pea _nextop-1 ; set up return address, finally figured it out jmp [jp] ; and it works in native or emulation mode.^ .entry _jsi _jsi: shorta lda [r1] beq $1 cmp #0xea ; same as above... beq $1 $3: ; dummy local longi php shorti ply longa ldx sp sei tsc ina ; copiously commented above sta sp sec xce txs phy plp bit 0xc08a pea $2-1 ldx #0 jmp [r1,x] $2: bit 0xc088 ; same as above... php ply clc xce rep 0x21 lda sp dea sei tsx tcs stx sp phy plp jmp _nextop $1: _cpbrk: longa pea _nextop-1 jmp [r1] /* Andy Werner hybrid concepts st2975@siucvmb.siu.edu * * HyperC enthusiast 65802/816 support for HyperC * * Laser 128EX 4Mhz 65802 st2975@siucvmb.bitnet */