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: <ST2975@SIUCVMB.SIU.EDU>
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   */


