//
// PLASMA JIT bytecode compiler
//
include "inc/cmdsys.plh"
//
// Module don't free memory
//
const modkeep     = $2000
const modinitkeep = $4000
//
// Indirect interpreter DEFinition entrypoint
//
struc t_defentry
    byte interpjsr
    word interpaddr
    word bytecodeaddr
    byte callcount
    byte bytecodesize
end
//
// JIT compiler constants
//
const jitcount    = $10
const jitcomp     = $03E2
const jitcodeptr  = $03E4
const codemax     = $BEE0
//
// AUX bytecode interpreter entrypoint
//
const interpentry = $03DC
//
// TOS caching values
//
const TOS_DIRTY   = 1
const TOS_CLEAN   = 2
//
// Y unknown value
//
const UNKNOWN     = -1
//
// Resolve virtual X with real X
//
def resolveX(codeptr, VX)#2
    while VX > 0
        ^codeptr = $E8; codeptr++ // INX
        VX--
    loop
    while VX < 0
        ^codeptr = $CA; codeptr++ // DEX
        VX++
    loop
    return codeptr, 0
end
//
// JIT compiler entry
//
def compiler(defptr)#0
    word codeptr, isdata, addrxlate, bytecode, i, case, dest, VX, VY
    byte opcode, j, A_IS_TOSL
    
    //puts("JIT compiler invoked for :$"); puth(defptr=>bytecodeaddr); putln
    if isult(heapavail, 512 + defptr->bytecodesize) // 256 * sizeof(word) address xlate
        //
        // Not enough heap available
        //
        defptr=>interpaddr = interpentry
        return
    fin
    addrxlate = heapmark
    memset(addrxlate, 0, 512) // Clear xlate buffer
    //
    // Copy bytecode def from AUX to heap for compiling
    //
    bytecode = addrxlate + 512 // def bytecode
    *$003C   = defptr=>bytecodeaddr
    *$003E   = *$003C + defptr->bytecodesize
    *$0042   = bytecode
    call($C311, 0, 0, 0, $04) // CALL XMOVE with carry clear (AUX->MAIN) and ints disabled
    //^$C053 // MIX TEXT
    //puts("Addr Xlate: $"); puth(addrxlate); putln
    //puts("Bytecode:   $"); puth(bytecode); putln
    //
    // Find all branch targets and optimization fences. Tag the opcode with the LSB set
    //
    // All PLASMA ops are even (LSB clear), so this will flag when to fence optimizations
    // During compiling.
    //
    isdata = addrxlate // Use this buffer
    i = 0
    while i < defptr->bytecodesize
        if not ^(isdata+i)
            when (^(bytecode+i) & $FE)
                //
                // Double byte operands
                //
                is $26 // LA
                is $2C // CW
                is $54 // CALL
                is $58 // ENTER
                is $68 // LAB
                is $6A // LAW
                is $78 // SAB
                is $7A // SAW
                is $7C // DAB
                is $7E // DAW
                is $B4 // ADDAB
                is $B6 // ADDAW
                is $BC // IDXAB
                is $BE // IDXAW
                    i = i + 2
                    break
                //
                // Multi-byte operands
                //
                is $2E // CS
                    i = i + ^(bytecode+i+1)
                //
                // Single byte operands
                //
                is $2A // CB
                is $28 // LLA
                is $38 // ADDI
                is $3A // SUBI
                is $3C // ANDI
                is $3E // ORI
                is $5A // LEAVE
                is $5E // CFFB
                is $64 // LLB
                is $66 // LLW
                is $6C // DLB
                is $6E // DLW
                is $74 // SLB
                is $76 // SLW
                is $B0 // ADDLB
                is $B2 // ADDLW
                is $B8 // IDXLB
                is $BA // IDXLW
                    i++
                    break
                //
                // Branches
                //
                is $50 // BRNCH
                is $22 // BREQ
                is $24 // BENE
                is $4C // BRFLS
                is $4E // BRTRU
                is $A0 // BRGT
                is $A2 // BRLT
                is $A4 // INCBRLE
                is $A6 // ADDBRLE
                is $A8 // DECBRGE
                is $AA // SUBBRGE
                is $AC // BRAND
                is $AE // BROR
                    i++
                    //
                    // Flag branch destination
                    //
                    dest = i + *(bytecode+i)
                    ^(bytecode+dest) = ^(bytecode+dest) | 1
                    i++
                    break
                //
                // SELect/caseblock
                //
                is $52 // SEL
                    i++
                    case = i + *(bytecode+i)
                    i++
                    ^(isdata+case) = TRUE // Flag as data
                    j = ^(bytecode+case)
                    case++
                    repeat
                        *(isdata+case)   = TRUE // Flag as data
                        case             = case + 2
                        dest             = case + *(bytecode+case)
                        ^(bytecode+dest) = ^(bytecode+dest) | 1 // Flag as branch dest
                        *(isdata+case)   = TRUE // Flag as data
                        case             = case + 2
                        j--
                    until not j
                    break
            wend
        fin
        i++
    loop
    memset(isdata, 0, 256) // Clear part of xlate buffer used for isdata
    //
    // Compile the bytecodes
    //
    codeptr   = *jitcodeptr
    A_IS_TOSL = FALSE
    VY        = UNKNOWN // Virtual Y register
    VX        = 0       // Virtual X register
    i         = 0
    if ^bytecode == $58
        //putc('$'); puth(codeptr);//puts(":[0] ENTER "); puti(^(bytecode+1)); putc(',');puti(^(bytecode+2)); putln
        //
        // Call into VM
        //
        codeptr->0 = $20           // JSR INTERP
        codeptr=>1 = $3D0
        codeptr->3 = $58           // ENTER CODE
        codeptr=>4 = *(bytecode+1) // ENTER FRAME SIZE & ARG COUNT
        codeptr->6 = $C0           // NATV CODE
        codeptr    = codeptr + 7
        i          = 3
    fin
    while isule(codeptr, codemax)
        //putc('$'); puth(codeptr); putc(':')
        //putc('['); puti(i); //puts("] ")
        opcode = ^(bytecode+i)
        if opcode & 1
            //
            // Optimization fence. Sync A and X registers
            //
            codeptr, VX = resolveX(codeptr, VX)
            if A_IS_TOSL & TOS_DIRTY
                *codeptr = $D095//+(VX<<8) // STA ESTKL,X
                codeptr  = codeptr + 2
            fin
            VY        = UNKNOWN
            A_IS_TOSL = FALSE
            opcode    = opcode & $FE
        fin
        //
        // Update bytecode->native code address translation.
        //
        // Here's how it works:
        //
        //  The code buffer is above address $8000 so MSBit set.
        //  When we compile a bytecode, update the destination address in
        //  the address xlate buffer with actual address (MSBit set). But, if a branch
        //  opcode jumps to a bytecode address that hasn't been compiled yet, add the
        //  address offset in the code buffer to the list of addresses needing resolution.
        //  The offset will be less than $8000, so MSBit clear. This is how we know if
        //  an address has been resolved or is a list of addresses needing resolution.
        //  Before updating the address xlate buffer with the known address as we
        //  compile, look for existing resolution list and traverse it if there.
        //
        if addrxlate=>[i]
            //
            // Address list awaiting resolution
            //
            dest = addrxlate=>[i] + *jitcodeptr
            repeat
                case  = *dest
                *dest = codeptr
                dest  = case + *jitcodeptr
            until not case
        fin
        //
        // Update address translate buffer with bytecode->native address
        //
        addrxlate=>[i] = codeptr
        //
        // Compile this bad boy...
        //
        if opcode < $20 // CONSTANT NYBBLE
            //puts("CN $"); putb(opcode/2)
            if A_IS_TOSL & TOS_DIRTY
                *codeptr = $D095+(VX<<8)            // STA ESTKL,X
                codeptr  = codeptr + 2
            fin
            VX--                                    // DEX
            if VY <> 0
                *codeptr = $00A0                    // LDY #$00
                codeptr  = codeptr + 2
                VY       = 0
            fin
            *codeptr  = $C094+(VX<<8)               // STY ESTKH,X
            codeptr   = codeptr + 2
            if opcode == 0
                ^codeptr = $98; codeptr++           // TYA -> LDA #$00
            else
                *codeptr = $A9+(opcode/2<<8)        // LDA #(CN/2)
                codeptr  = codeptr + 2
            fin
            A_IS_TOSL = TOS_DIRTY                   // STA ESTKL,X
        else
            when opcode
                is $20 // MINUS ONE
                    //puts("MINUS_ONE")
                    if A_IS_TOSL & TOS_DIRTY
                        *codeptr = $D095+(VX<<8) // STA ESTKL,X
                        codeptr  = codeptr + 2
                    fin
                    VX--                         // DEX
                    codeptr=>0 = $FFA9           // LDA #$FF
                    codeptr=>2 = $C095+(VX<<8)   // STA ESTKH,X
                    codeptr    = codeptr + 4
                    A_IS_TOSL  = TOS_DIRTY       // STA ESTKL,X
                    break
                is $22 // BREQ
                    i++
                    dest = i + *(bytecode+i)
                    i++
                    //puts("BREQ "); puti(dest)
                    codeptr, VX = resolveX(codeptr, VX + 2) // INX; INX
                    if not A_IS_TOSL
                        *codeptr = $D0B5-$0200//+(VX<<8)    // LDA ESTKL-2,X
                        codeptr  = codeptr + 2
                    fin
                    codeptr=>0  = $D0D5-$0100//+(VX<<8)     // CMP ESTKL-1,X
                    codeptr=>2  = $09D0                     // BNE +9
                    codeptr=>4  = $C0B5-$0200//+(VX<<8)     // LDA ESTKH-2,X
                    codeptr=>6  = $C0D5-$0100//+(VX<<8)     // CMP ESTKH-1,X
                    codeptr=>8  = $03D0                     // BNE +3
                    codeptr->10 = $4C                       // JMP abs
                    codeptr=>11 = addrxlate=>[dest]
                    if not (codeptr->12 & $80) // Unresolved address list
                        addrxlate=>[dest] = codeptr + 11 - *jitcodeptr
                    fin
                    codeptr   = codeptr + 13
                    A_IS_TOSL = FALSE
                    break
                is $24 // BRNE
                    i++
                    dest = i + *(bytecode+i)
                    i++
                    //puts("BRNE "); puti(dest)
                    codeptr, VX = resolveX(codeptr, VX + 2) // INX; INX
                    if not A_IS_TOSL
                        *codeptr = $D0B5-$0200//+(VX<<8)    // LDA ESTKL-2,X
                        codeptr  = codeptr + 2
                    fin
                    codeptr=>0  = $D0D5-$0100//+(VX<<8)     // CMP ESTKL-1,X
                    codeptr=>2  = $06D0                     // BNE +6
                    codeptr=>4  = $C0B5-$0200//+(VX<<8)     // LDA ESTKH-2,X
                    codeptr=>6  = $C0D5-$0100//+(VX<<8)     // CMP ESTKH-1,X
                    codeptr=>8  = $03F0                     // BEQ +3
                    codeptr->10 = $4C                       // JMP abs
                    codeptr=>11 = addrxlate=>[dest]
                    if not (codeptr->12 & $80) // Unresolved address list
                        addrxlate=>[dest] = codeptr + 11 - *jitcodeptr
                    fin
                    codeptr   = codeptr + 13
                    A_IS_TOSL = FALSE
                    break
                is $26 // LA
                is $2C // CW
                    dest = *(bytecode+i+1)
                    i    = i + 2
                    //puts("LA/CW $"); puth(dest)
                    if A_IS_TOSL & TOS_DIRTY
                        *codeptr = $D095+(VX<<8)  // STA ESTKL,X
                        codeptr  = codeptr + 2
                    fin
                    VX--                          // DEX
                    codeptr=>0 = $A9+(dest&$FF00) // LDA #<VAL
                    codeptr=>2 = $C095+(VX<<8)    // STA ESTKH,X
                    codeptr=>4 = $A9+(dest<<8)    // LDA #>VAL
                    codeptr    = codeptr + 6
                    A_IS_TOSL = TOS_DIRTY         // STA ESTKL,X
                    break
                is $28 // LLA
                    i++
                    j = ^(bytecode+i)
                    //puts("LLA "); puti(^(bytecode+i))
                    if A_IS_TOSL & TOS_DIRTY
                        *codeptr = $D095+(VX<<8)  // STA ESTKL,X
                        codeptr  = codeptr + 2
                    fin
                    VX--                          // DEX
                    if VY == j
                        ^codeptr = $98; codeptr++ // TYA -> LDA #imm
                    else
                        *codeptr = $A9+(j<<8)     // LDA #imm
                        codeptr  = codeptr + 2
                    fin
                    codeptr->0 = $18              // CLC
                    codeptr=>1 = $E065            // ADC IFPL
                    codeptr=>3 = $D095+(VX<<8)    // STA ESTKL,X
                    if VY == 0
                        codeptr->5 = $98          // TYA -> LDA #00
                        codeptr    = codeptr + 6
                    else
                        codeptr=>5 = $00A9        // LDA #$00
                        codeptr    = codeptr + 7
                    fin
                    codeptr=>0 = $E165            // ADC IFPH
                    codeptr=>2 = $C095+(VX<<8)    // STA ESTKH,X
                    codeptr    = codeptr + 4
                    A_IS_TOSL  = FALSE
                    break
                is $2A // CB
                    i++
                    //puts("CB $"); putb(^(bytecode+i))
                    if A_IS_TOSL & TOS_DIRTY
                        *codeptr = $D095+(VX<<8)        // STA ESTKL,X
                        codeptr  = codeptr + 2
                    fin
                    VX--                                // DEX
                    if VY <> 0
                        *codeptr = $00A0                // LDY #$00
                        codeptr  = codeptr + 2
                        VY       = 0
                    fin
                    codeptr=>0 = $C094+(VX<<8)          // STY ESTKH,X
                    codeptr=>2 = $A9+(^(bytecode+i)<<8) // LDA #imm
                    codeptr    = codeptr + 4
                    A_IS_TOSL  = TOS_DIRTY              // STA ESTKL,X
                    break
                is $2E // CS
                    i++
                    j    = ^(bytecode+i)
                    dest = codeptr + 10 + j
                    //puts("CS "); //puts(bytecode+i); //puts("-->"); puti(dest)
                    if isule(dest, codemax)
                        if A_IS_TOSL & TOS_DIRTY
                            *codeptr = $D095+(VX<<8)         // STA ESTKL,X
                            codeptr  = codeptr + 2
                        fin
                        VX--                                 // DEX
                        codeptr=>0 = $A9+((codeptr+9)&$FF00) // LDA #>STRING
                        codeptr=>2 = $C095+(VX<<8)           // STA ESTKH,X
                        codeptr=>4 = $A9+((codeptr+9)<<8)    // LDA #<STRING
                        codeptr->6 = $4C                     // JMP abs
                        dest       = codeptr + 10 + j
                        codeptr=>7 = dest
                        strcpy(codeptr + 9, bytecode + i)
                        i = i + j
                    fin
                    codeptr   = dest
                    A_IS_TOSL = TOS_DIRTY                    // STA ESTKL,X
                    break
                is $32 // DROP2
                    //puts("DROP2")
                    VX++              // INX
                is $30 // DROP
                    //puts("DROP")
                    VX++              // INX
                    A_IS_TOSL = FALSE
                    break
                is $34 // DUP
                    //puts("DUP")
                    if not A_IS_TOSL
                        *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X
                        codeptr  = codeptr + 2
                    elsif A_IS_TOSL & TOS_DIRTY
                        *codeptr = $D095+(VX<<8) // STA ESTKL,X
                        codeptr  = codeptr + 2
                    fin
                    codeptr=>0 = $C0B4+(VX<<8)   // LDY ESTKH,X
                    VX--                         // DEX
                    codeptr=>2 = $C094+(VX<<8)   // STY ESTKH,X
                    codeptr    = codeptr + 4
                    VY         = UNKNOWN
                    A_IS_TOSL  = TOS_DIRTY       // STA ESTKL,X
                    break
                //is $36
                    //puts("DIVMOD")
                    //
                    // Should never happen
                    //
                    //break
                is $38 // ADDI
                    i++
                    //puts("ADDI $"); putb(^(bytecode+i))
                    if not A_IS_TOSL
                        *codeptr = $D0B5+(VX<<8)        // LDA ESTKL,X
                        codeptr  = codeptr + 2
                    fin
                    codeptr->0 = $18                    // CLC                    
                    codeptr=>1 = $69+(^(bytecode+i)<<8) // ADC #imm
                    codeptr=>3 = $0290                  // BCC +2
                    codeptr=>5 = $C0F6+(VX<<8)          // INC ESTKH,X
                    codeptr    = codeptr + 7
                    A_IS_TOSL  = TOS_DIRTY              // STA ESTKL,X
                    break
                is $3A // SUBI
                    i++
                    //puts("SUBI $"); putb(^(bytecode+i))
                    if not A_IS_TOSL
                        *codeptr = $D0B5+(VX<<8)        // LDA ESTKL,X
                        codeptr  = codeptr + 2
                    fin
                    codeptr->0 = $38                    // SEC                    
                    codeptr=>1 = $E9+(^(bytecode+i)<<8) // SBC #imm
                    codeptr=>3 = $02B0                  // BCS +2
                    codeptr=>5 = $C0D6+(VX<<8)          // DEC ESTKH,X
                    codeptr    = codeptr + 7
                    A_IS_TOSL  = TOS_DIRTY              // STA ESTKL,X
                    break
                is $3C // ANDI
                    i++
                    //puts("ANDI $"); putb(^(bytecode+i))
                    if VY <> 0
                        *codeptr = $00A0                // LDY #$00
                        codeptr  = codeptr + 2
                        VY       = 0
                    fin
                    if not A_IS_TOSL
                        *codeptr = $D0B5+(VX<<8)        // LDA ESTKL,X
                        codeptr  = codeptr + 2
                    fin
                    codeptr=>0 = $29+(^(bytecode+i)<<8) // AND #imm
                    codeptr=>2 = $C094+(VX<<8)          // STY ESTKH,X
                    codeptr    = codeptr + 4
                    A_IS_TOSL  = TOS_DIRTY              // STA ESTKL,X
                    break
                is $3E // ORI
                    i++
                    //puts("ORI $"); putb(^(bytecode+i))
                    if not A_IS_TOSL
                        *codeptr = $D0B5+(VX<<8)       // LDA ESTKL,X
                        codeptr  = codeptr + 2
                    fin
                    *codeptr  = $09+(^(bytecode+i)<<8) // ORA #imm
                    codeptr   = codeptr + 2
                    A_IS_TOSL = TOS_DIRTY              // STA ESTKL,X
                    break
                is $40 // ISEQ
                    //puts("ISEQ")
                    if VY <> 0
                        *codeptr = $00A0              // LDY #$00
                        codeptr  = codeptr + 2
                    fin
                    if not A_IS_TOSL
                        *codeptr = $D0B5+(VX<<8)      // LDA ESTKL,X
                        codeptr  = codeptr + 2
                    fin
                    codeptr=>0  = $D0D5+$0100+(VX<<8) // CMP ESTKL+1,X
                    codeptr=>2  = $07D0               // BNE +7
                    codeptr=>4  = $C0B5+(VX<<8)       // LDA ESTKH,X
                    codeptr=>6  = $C0D5+$0100+(VX<<8) // CMP ESTKH+1
                    codeptr=>8  = $01D0               // BNE +1
                    codeptr=>10 = $9888               // DEY; TYA                    
                    codeptr=>12 = $C094+$0100+(VX<<8) // STY ESTKH+1,X
                    codeptr     = codeptr + 14
                    VX++                              // INX
                    VY          = UNKNOWN
                    A_IS_TOSL   = TOS_DIRTY           // STA ESTKL,X
                    break
                is $42 // ISNE
                    //puts("ISNE")
                    if VY <> 0
                        *codeptr = $00A0              // LDY #$00
                        codeptr  = codeptr + 2
                    fin
                    if not A_IS_TOSL
                        *codeptr = $D0B5+(VX<<8)      // LDA ESTKL,X
                        codeptr  = codeptr + 2
                    fin
                    codeptr=>0  = $D0D5+$0100+(VX<<8) // CMP ESTKL+1,X
                    codeptr=>2  = $06D0               // BNE +6
                    codeptr=>4  = $C0B5+(VX<<8)       // LDA ESTKH,X
                    codeptr=>6  = $C0D5+$0100+(VX<<8) // CMP ESTKH+1
                    codeptr=>8  = $01F0               // BEQ +1
                    codeptr=>10 = $9888               // DEY; TYA                    
                    codeptr=>12 = $C094+$0100+(VX<<8) // STY ESTKH+1,X
                    codeptr     = codeptr + 14
                    VX++                              // INX
                    VY          = UNKNOWN
                    A_IS_TOSL   = TOS_DIRTY           // STA ESTKL,X
                    break
                is $44 // ISGT
                    //puts("ISGT")
                    if VY <> 0
                        *codeptr = $00A0              // LDY #$00
                        codeptr  = codeptr + 2
                    fin
                    if not A_IS_TOSL
                        *codeptr = $D0B5+(VX<<8)      // LDA ESTKL,X
                        codeptr  = codeptr + 2
                    fin
                    codeptr=>0  = $D0D5+$0100+(VX<<8) // CMP ESTKL+1,X
                    codeptr=>2  = $C0B5+(VX<<8)       // LDA ESTKH,X
                    codeptr=>4  = $C0F5+$0100+(VX<<8) // SBC ESTKH+1
                    codeptr=>6  = $0250               // BVC +2
                    codeptr=>8  = $8049               // EOR #$80
                    codeptr=>10 = $0110               // BPL +1
                    codeptr=>12 = $9888               // DEY TYA                    
                    codeptr=>14 = $C094+$0100+(VX<<8) // STY ESTKH+1,X
                    codeptr     = codeptr + 16
                    VX++                              // INX
                    VY          = UNKNOWN
                    A_IS_TOSL   = TOS_DIRTY           // STA ESTKL,X
                    break
                is $46
                    //puts("ISLT")
                    if A_IS_TOSL & TOS_DIRTY
                        *codeptr = $D095+(VX<<8)      // STA ESTKL,X
                        codeptr  = codeptr + 2
                    fin
                    if VY <> 0
                        *codeptr = $00A0              // LDY #$00
                        codeptr  = codeptr + 2
                    fin
                    codeptr=>0  = $D0B5+$0100+(VX<<8) // LDA ESTKL+1,X
                    codeptr=>2  = $D0D5+(VX<<8)       // CMP ESTKL,X
                    codeptr=>4  = $C0B5+$0100+(VX<<8) // LDA ESTKH+1,X
                    codeptr=>6  = $C0F5+(VX<<8)       // SBC ESTKH
                    codeptr=>8  = $0250               // BVC +2
                    codeptr=>10 = $8049               // EOR #$80
                    codeptr=>12 = $0110               // BPL +1
                    codeptr=>14 = $9888               // DEY; TYA                    
                    codeptr=>16 = $C094+$0100+(VX<<8) // STY ESTKH+1,X
                    codeptr     = codeptr + 18
                    VX++                              // INX
                    VY          = UNKNOWN
                    A_IS_TOSL   = TOS_DIRTY           // STA ESTKL,X
                    break
                is $48
                    //puts("ISGE")
                    if A_IS_TOSL & TOS_DIRTY
                        *codeptr = $D095+(VX<<8)      // STA ESTKL,X
                        codeptr  = codeptr + 2
                    fin
                    if VY <> 0
                        *codeptr = $00A0              // LDY #$00
                        codeptr  = codeptr + 2
                    fin
                    codeptr=>0  = $D0B5+$0100+(VX<<8) // LDA ESTKL+1,X
                    codeptr=>2  = $D0D5+(VX<<8)       // CMP ESTKL,X
                    codeptr=>4  = $C0B5+$0100+(VX<<8) // LDA ESTKH+1,X
                    codeptr=>6  = $C0F5+(VX<<8)       // SBC ESTKH
                    codeptr=>8  = $0250               // BVC +2
                    codeptr=>10 = $8049               // EOR #$80
                    codeptr=>12 = $0130               // BMI +1
                    codeptr=>14 = $9888               // DEY; TYA                    
                    codeptr=>16 = $C094+$0100+(VX<<8) // STY ESTKH+1,X
                    codeptr     = codeptr + 18
                    VX++                              // INX
                    VY          = UNKNOWN
                    A_IS_TOSL   = TOS_DIRTY           // STA ESTKL,X
                    break
                is $4A // ISLE
                    //puts("ISLE")
                    if VY <> 0
                        *codeptr = $00A0              // LDY #$00
                        codeptr  = codeptr + 2
                    fin
                    if not A_IS_TOSL
                        *codeptr = $D0B5+(VX<<8)      // LDA ESTKL,X
                        codeptr  = codeptr + 2
                    fin
                    codeptr=>0  = $D0D5+$0100+(VX<<8) // CMP ESTKL+1,X
                    codeptr=>2  = $C0B5+(VX<<8)       // LDA ESTKH,X
                    codeptr=>4  = $C0F5+$0100+(VX<<8) // SBC ESTKH+1
                    codeptr=>6  = $0250               // BVC +2
                    codeptr=>8  = $8049               // EOR #$80
                    codeptr=>10 = $0130               // BMI +1
                    codeptr=>12 = $9888               // DEY; TYA                    
                    codeptr=>14 = $C094+$0100+(VX<<8) // STY ESTKH+1,X
                    codeptr     = codeptr + 16
                    VX++                              // INX
                    VY          = UNKNOWN
                    A_IS_TOSL   = TOS_DIRTY           // STA ESTKL,X
                    break
                is $4C // BRFLS
                    i++
                    dest = i + *(bytecode+i)
                    i++
                    //puts("BRFLS "); puti(dest)
                    codeptr, VX = resolveX(codeptr, VX + 1) // INX
                    if not A_IS_TOSL
                        *codeptr = $D0B5-$0100//+(VX<<8)    // LDA ESTKL-1,X
                        codeptr  = codeptr + 2
                    fin
                    codeptr=>0 = $C015-$0100//+(VX<<8)      // ORA ESTKH-1,X
                    codeptr=>2 = $03D0                      // BNE +3
                    codeptr->4 = $4C                        // JMP abs
                    codeptr=>5 = addrxlate=>[dest]
                    if not (codeptr->6 & $80) // Unresolved address list
                        addrxlate=>[dest] = codeptr + 5 - *jitcodeptr
                    fin
                    codeptr   = codeptr + 7
                    A_IS_TOSL = FALSE
                    break
                is $4E // BRTRU
                    i++
                    dest = i + *(bytecode+i)
                    i++
                    //puts("BRTRU "); puti(dest)
                    codeptr, VX = resolveX(codeptr, VX + 1) // INX
                    if not A_IS_TOSL
                        *codeptr = $D0B5-$0100//+(VX<<8)    // LDA ESTKL-1,X
                        codeptr  = codeptr + 2
                    fin
                    codeptr=>0 = $C015-$0100//+(VX<<8)      // ORA ESTKH-1,X
                    codeptr=>2 = $03F0                      // BEQ +3
                    codeptr->4 = $4C                        // JMP abs
                    codeptr=>5 = addrxlate=>[dest]
                    if not (codeptr->6 & $80) // Unresolved address list
                        addrxlate=>[dest] = codeptr + 5 - *jitcodeptr
                    fin
                    codeptr   = codeptr + 7
                    A_IS_TOSL = FALSE
                    break
                is $50 // BRNCH
                    i++
                    dest = i + *(bytecode+i)
                    i++
                    //puts("BRNCH "); puti(dest)
                    codeptr, VX = resolveX(codeptr, VX)
                    if A_IS_TOSL & TOS_DIRTY
                        *codeptr = $D095//+(VX<<8) // STA ESTKL,X
                        codeptr  = codeptr + 2
                    fin
                    codeptr->0 = $4C               // JMP abs
                    codeptr=>1 = addrxlate=>[dest]
                    if not (codeptr->2 & $80) // Unresolved address list
                        addrxlate=>[dest] = codeptr + 1 - *jitcodeptr
                    fin
                    codeptr   = codeptr + 3
                    A_IS_TOSL = FALSE
                    break
                is $52 // SEL
                    i++
                    case = i + *(bytecode+i)
                    i++
                    //puts("SEL "); puti(case); putln
                    j = ^(bytecode+case)
                    dest = codeptr + 9 + case * 11)
                    if isule(dest, codemax)
                        ^(bytecode+case) = $FE // Flag as NOP
                        case++
                        if not A_IS_TOSL
                            *codeptr = $D0B5+(VX<<8)                // LDA ESTKL,X
                            codeptr  = codeptr + 2
                        fin
                        codeptr=>0 = $C0B4+(VX<<8)                  // LDY ESTKH,X
                        codeptr, VX = resolveX(codeptr + 2, VX + 1) // INX
                        repeat
                            dest = *(bytecode+case)
                            //puts("    $"); puth(dest)
                            codeptr=>0 = $C9+(dest<<8)              // CMP #imm
                            codeptr=>2 = $07D0                      // BNE +7
                            codeptr=>4 = $C0+(dest&$FF00)           // CPY #imm
                            codeptr=>6 = $03D0                      // BNE +3
                            *(bytecode+case) = $FEFE
                            case = case + 2
                            dest = case + *(bytecode+case)
                            //puts("-->"); puti(dest); putln
                            codeptr->8 = $4C                        // JMP abs
                            codeptr=>9 = addrxlate=>[dest]
                            if not (codeptr->10 & $80) // Unresolved address list
                                addrxlate=>[dest] = codeptr + 9 - *jitcodeptr
                            fin
                            codeptr          = codeptr + 11
                            *(bytecode+case) = $FEFE
                            case = case + 2
                            j--
                        until not j
                        codeptr->0 = $4C                            // JMP abs
                        codeptr=>1 = addrxlate=>[case]
                        if not (codeptr->2 & $80) // Unresolved address list
                            addrxlate=>[case] = codeptr + 1 - *jitcodeptr
                        fin
                        codeptr = codeptr + 3
                    else
                        codeptr = dest
                    fin
                    VY        = UNKNOWN
                    A_IS_TOSL = FALSE
                    break
                is $54 // CALL
                    //puts("CALL $"); puth(*(bytecode+i))
                    //
                    // Call address
                    //
                    codeptr, VX = resolveX(codeptr, VX)
                    if A_IS_TOSL & TOS_DIRTY
                        *codeptr = $D095//+(VX<<8) // STA ESTKL,X
                        codeptr  = codeptr + 2
                    fin
                    codeptr->0 = $20               // JSR abs
                    codeptr=>1 = *(bytecode+i+1)
                    codeptr    = codeptr + 3
                    VY         = UNKNOWN
                    A_IS_TOSL  = FALSE
                    i          = i + 2
                    break
                is $56 // ICAL
                    //puts("ICAL")
                    //
                    // Pull address off stack
                    //
                    if not A_IS_TOSL
                        *codeptr = $D0B5+(VX<<8)                // LDA ESTKL,X
                        codeptr  = codeptr + 2
                    fin
                    codeptr=>0 = $E785                          // STA $E7:TMPL
                    codeptr=>2 = $C0B5+(VX<<8)                  // LDA ESTKH,X
                    codeptr=>4 = $E885                          // STA $E8:TMPH
                    codeptr, VX = resolveX(codeptr + 6, VX + 1) // INX
                    //
                    // Call through TMP
                    //
                    codeptr->0 = $20                            // JSR abs
                    codeptr=>1 = $00E6                          // $E6:JMPTMP
                    codeptr    = codeptr + 3
                    VY         = UNKNOWN
                    A_IS_TOSL  = FALSE
                   break
                is $5A // LEAVE
                    i++
                    //puts("LEAVE "); puti(^(bytecode+i))
                    //
                    // Call into VM
                    //
                    codeptr, VX = resolveX(codeptr, VX)
                    if A_IS_TOSL & TOS_DIRTY
                        *codeptr = $D095//+(VX<<8)        // STA ESTKL,X
                        codeptr  = codeptr + 2
                    fin
                    codeptr->0 = $20                      // JSR abs
                    codeptr=>1 = $03D0                    // INTERP
                    codeptr=>3 = $5A + (^(bytecode+i)<<8) // LEAVE CODE AND OPERAND
                    codeptr    = codeptr + 5
                    A_IS_TOSL  = FALSE
                    break
                is $5C // RET
                    //puts("RET")
                    codeptr, VX = resolveX(codeptr, VX)
                    if A_IS_TOSL & TOS_DIRTY
                        *codeptr = $D095//+(VX<<8) // STA ESTKL,X
                        codeptr  = codeptr + 2
                    fin
                    ^codeptr  = $60; codeptr++     // RTS
                    A_IS_TOSL = FALSE
                   break
                is $5E // CFFB
                    i++
                    //puts("CFFB $FF"); putb(^(bytecode+i))
                    if A_IS_TOSL & TOS_DIRTY
                        *codeptr = $D095+(VX<<8)        // STA ESTKL,X
                        codeptr  = codeptr + 2
                    fin
                    VX--                                // DEX
                    codeptr=>0 = $FFA9                  // LDA #$FF
                    codeptr=>2 = $C095+(VX<<8)          // STA ESTKH,X
                    codeptr=>4 = $A9+(^(bytecode+i)<<8) // LDA #imm
                    codeptr    = codeptr + 6
                    A_IS_TOSL  = TOS_DIRTY              // STA ESTKL,X
                    break
                is $60 // LB
                    //puts("LB")
                    if VY <> 0
                        *codeptr = $00A0              // LDY #$00
                        codeptr  = codeptr + 2
                        VY       = 0
                    fin
                    if not A_IS_TOSL
                        *codeptr = $D0B5+(VX<<8)     // LDA ESTKL,X
                        codeptr  = codeptr + 2
                    fin
                    codeptr=>0 = $C095-$0100+(VX<<8) // STA ESTKH-1,X
                    codeptr=>2 = $C0A1-$0100+(VX<<8) // LDA (ESTKH-1,X)
                    codeptr=>4 = $C094+(VX<<8)       // STY ESTKH,X
                    codeptr    = codeptr + 6
                    A_IS_TOSL  = TOS_DIRTY           // STA ESTKL,X
                    break
                is $62 // LW
                    //puts("LW")
                    if not A_IS_TOSL
                        *codeptr = $D0B5+(VX<<8)      // LDA ESTKL,X
                        codeptr  = codeptr + 2
                    fin
                    codeptr=>0  = $C095-$0100+(VX<<8) // STA ESTKH-1,X
                    codeptr=>2  = $C0A1-$0100+(VX<<8) // LDA (ESTKH-1,X)
                    codeptr=>4  = $D095+(VX<<8)       // STA ESTKL,X
                    codeptr=>6  = $C0F6-$0100+(VX<<8) // INC ESTKH-1,X
                    codeptr=>8  = $02D0               // BNE +2
                    codeptr=>10 = $C0F6+(VX<<8)       // INC ESTKH,X
                    codeptr=>12 = $C0A1-$0100+(VX<<8) // LDA (ESTKH-1,X)
                    codeptr=>14 = $C095+(VX<<8)       // STA ESTKH,X
                    codeptr     = codeptr + 16
                    A_IS_TOSL   = FALSE
                    break
                is $64 // LLB
                    i++
                    j = ^(bytecode+i)
                    //puts("LLB "); puti(j)
                    if A_IS_TOSL & TOS_DIRTY
                        *codeptr = $D095+(VX<<8)          // STA ESTKL,X
                        codeptr  = codeptr + 2
                    fin
                    VX--                                  // DEX
                    if VY <> j
                        *codeptr = $A0+(j<<8)             // LDY #imm
                        codeptr  = codeptr + 2
                        VY       = j
                    fin
                    *codeptr = $E0B1                      // LDA (IFP),Y
                    codeptr  = codeptr + 2
                    if VY
                        *codeptr = $00A0                  // LDY #$00
                        codeptr  = codeptr + 2
                        VY       = 0
                    fin
                    *codeptr  = $C094+(VX<<8)             // STY ESTKH,X
                    codeptr   = codeptr + 2
                    A_IS_TOSL = TOS_DIRTY                 // STA ESTKL,X
                    break
                is $66 // LLW
                    i++
                    j = ^(bytecode+i)
                    //puts("LLW "); puti(j)
                    if A_IS_TOSL & TOS_DIRTY
                        *codeptr = $D095+(VX<<8)  // STA ESTKL,X
                        codeptr  = codeptr + 2
                    fin
                    VX--                          // DEX
                    if VY <> j
                        *codeptr = $A0+((j+1)<<8) // LDY #imm
                        codeptr  = codeptr + 2
                        VY       = j
                    else
                        ^codeptr = $C8; codeptr++ // INY
                    fin
                    codeptr=>0 = $E0B1            // LDA (IFP),Y
                    codeptr=>2 = $C095+(VX<<8)    // STA ESTKH,X
                    codeptr->4 = $88              // DEY
                    codeptr=>5 = $E0B1            // LDA (IFP),Y
                    codeptr    = codeptr + 7
                    A_IS_TOSL  = TOS_DIRTY        // STA ESTKL,X
                    break
                is $68 // LAB
                    i++
                    //puts("LAB $"); puth(*(bytecode+i))
                    if A_IS_TOSL & TOS_DIRTY
                        *codeptr = $D095+(VX<<8) // STA ESTKL,X
                        codeptr  = codeptr + 2
                    fin
                    VX--                         // DEX
                    if VY <> 0
                        *codeptr = $00A0         // LDY #$00
                        codeptr  = codeptr + 2
                        VY       = 0
                    fin
                    codeptr=>0 = $C094+(VX<<8)   // STY ESTKH,X
                    codeptr->2 = $AD             // LDA abs
                    codeptr=>3 = *(bytecode+i)
                    codeptr    = codeptr + 5
                    A_IS_TOSL  = TOS_DIRTY       // STA ESTKL,X
                    i++
                    break
                is $6A // LAW
                    dest = *(bytecode+i+1)
                    i    = i + 2
                    //puts("LAW $"); puth(dest)
                    if A_IS_TOSL & TOS_DIRTY
                        *codeptr = $D095+(VX<<8) // STA ESTKL,X
                        codeptr  = codeptr + 2
                    fin
                    VX--                         // DEX
                    codeptr->0 = $AD             // LDA abs
                    codeptr=>1 = dest+1
                    codeptr=>3 = $C095+(VX<<8)   // STA ESTKH,X
                    codeptr->5 = $AD             // LDA abs
                    codeptr=>6 = dest
                    codeptr    = codeptr + 8
                    A_IS_TOSL  = TOS_DIRTY       // STA ESTKL,X
                    break
                is $6C // DLB
                    i++
                    j = ^(bytecode+i)
                    //puts("DLB "); puti(j)
                    if not A_IS_TOSL
                        *codeptr  = $D0B5+(VX<<8) // LDA ESTKL,X
                        codeptr   = codeptr + 2
                        A_IS_TOSL = TOS_CLEAN
                    fin
                    if VY <> j
                        *codeptr = $A0+(j<<8)     // LDY #imm
                        codeptr  = codeptr + 2
                        VY       = j
                    fin
                    *codeptr = $E091              // STA (IFP),Y
                    codeptr  = codeptr + 2
                    if VY <> 0
                        *codeptr = $00A0          // LDY #$00
                        codeptr  = codeptr + 2
                        VY       = 0
                    fin
                    *codeptr = $C094+(VX<<8)      // STY ESTKH,X
                    codeptr  = codeptr + 2
                    break
                is $6E // DLW
                    i++
                    j = ^(bytecode+i)
                    //puts("DLW "); puti(j)
                    if A_IS_TOSL & TOS_DIRTY
                        *codeptr = $D095+(VX<<8)  // STA ESTKL,X
                        codeptr  = codeptr + 2
                    fin
                    if VY <> j
                        *codeptr = $A0+((j+1)<<8) // LDY #imm
                        codeptr  = codeptr + 2
                        VY       = j
                    else
                        ^codeptr = $C8; codeptr++ // INY
                    fin
                    codeptr=>0 = $C0B5+(VX<<8)    // LDA ESTKH,X
                    codeptr=>2 = $E091            // STA (IFP),Y
                    codeptr->4 = $88              // DEY
                    codeptr=>5 = $D0B5+(VX<<8)    // LDA ESTKL,X
                    codeptr=>7 = $E091            // STA (IFP),Y
                    codeptr    = codeptr + 9
                    A_IS_TOSL  = TOS_CLEAN
                    break
                is $70 // SB
                    //puts("SB")
                    if not A_IS_TOSL
                        *codeptr = $D0B5+(VX<<8)     // LDA ESTKL,X
                        codeptr  = codeptr + 2
                    fin
                    codeptr=>0 = $C095-$0100+(VX<<8) // STA ESTKH-1,X
                    codeptr=>2 = $D0B5+$0100+(VX<<8) // LDA ESTKL+1,X
                    codeptr=>4 = $C081-$0100+(VX<<8) // STA (ESTKH-1,X)
                    codeptr    = codeptr + 6
                    VX         = VX + 2              // INX; INX
                    A_IS_TOSL  = FALSE
                    break
                is $72 // SW
                    //puts("SW")
                    if not A_IS_TOSL
                        *codeptr = $D0B5+(VX<<8)      // LDA ESTKL,X
                        codeptr  = codeptr + 2
                    fin
                    codeptr=>0  = $C095-$0100+(VX<<8) // STA ESTKH-1,X
                    codeptr=>2  = $D0B5+$0100+(VX<<8) // LDA ESTKL+1,X
                    codeptr=>4  = $C081-$0100+(VX<<8) // STA (ESTKH-1,X)
                    codeptr=>6  = $C0B5+$0100+(VX<<8) // LDA ESTKH+1,X
                    codeptr=>8  = $C0F6-$0100+(VX<<8) // INC ESTKH-1,X
                    codeptr=>10 = $02D0               // BNE +2
                    codeptr=>12 = $C0F6+(VX<<8)       // INC ESTKH,X
                    codeptr=>14 = $C081-$0100+(VX<<8) // STA (ESTKH-1,X)
                    codeptr     = codeptr + 16
                    VX          = VX + 2              // INX; INX
                    A_IS_TOSL   = FALSE
                    break
                is $74 // SLB
                    i++
                    j = ^(bytecode+i)
                    //puts("SLB "); puti(j)
                    if not A_IS_TOSL
                        *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X
                        codeptr  = codeptr + 2
                    fin
                    if VY <> j                   
                        *codeptr = $A0+(j<<8)    // LDY #imm
                        codeptr  = codeptr + 2
                        VY       = j
                    fin
                    *codeptr = $E091             // STA (IFP),Y
                    codeptr  = codeptr + 2
                    VX++                         // INX
                    A_IS_TOSL = FALSE
                    break
                is $76 // SLW
                    i++
                    j = ^(bytecode+i)
                    //puts("SLW "); puti(j)
                    if not A_IS_TOSL
                        *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X
                        codeptr  = codeptr + 2
                    fin
                    if VY <> j                  
                        *codeptr = $A0+(j<<8)    // LDY #imm
                        codeptr  = codeptr + 2
                    fin
                    codeptr=>0 = $E091           // STA (IFP),Y
                    codeptr->2 = $C8             // INY
                    codeptr=>3 = $C0B5+(VX<<8)   // LDA ESTKH,X
                    codeptr=>5 = $E091           // STA (IFP),Y
                    codeptr    = codeptr + 7
                    VX++                         // INX
                    VY         = j + 1
                    A_IS_TOSL  = FALSE
                    break
                is $78 // SAB
                    dest = *(bytecode+i+1)
                    i    = i + 2
                    //puts("SAB $"); puth(*(bytecode+i))
                    if not A_IS_TOSL
                        *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X
                        codeptr  = codeptr + 2
                    fin
                    codeptr->0 = $8D             // STA abs
                    codeptr=>1 = dest
                    codeptr    = codeptr + 3
                    VX++                         // INX
                    A_IS_TOSL  = FALSE
                    break
                is $7A // SAW
                    dest = *(bytecode+i+1)
                    i    = i + 2
                    //puts("SAW $"); puth(dest)
                    if not A_IS_TOSL
                        *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X
                        codeptr  = codeptr + 2
                    fin
                    codeptr->0 = $8D             // STA abs
                    codeptr=>1 = dest
                    codeptr=>3 = $C0B5+(VX<<8)   // LDA ESTKH,X
                    codeptr->5 = $8D             // STA abs+1
                    codeptr=>6 = dest+1
                    codeptr    = codeptr + 8
                    VX++                         // INX
                    A_IS_TOSL  = FALSE
                    break
                is $7C // DAB
                    dest = *(bytecode+i+1)
                    i    = i + 2
                    //puts("DAB $"); puth(*(bytecode+i))
                    if not A_IS_TOSL
                        *codeptr  = $D0B5+(VX<<8) // LDA ESTKL,X
                        codeptr   = codeptr + 2
                        A_IS_TOSL = TOS_CLEAN
                    fin
                    if VY <> 0
                        *codeptr = $00A0          // LDY #$00
                        codeptr  = codeptr + 2
                        VY       = 0
                    fin
                    codeptr->0 = $8D              // STA abs
                    codeptr=>1 = dest
                    codeptr=>3 = $C094+(VX<<8)    // STY ESTKH,X
                    codeptr    = codeptr + 5
                    break
                is $7E // DAW
                    dest = *(bytecode+i+1)
                    i    = i + 2
                    //puts("DAW $"); puth(*(bytecode+i))
                    if not A_IS_TOSL
                        *codeptr  = $D0B5+(VX<<8) // LDA ESTKL,X
                        codeptr   = codeptr + 2
                        A_IS_TOSL = TOS_CLEAN
                    fin
                    codeptr->0 = $8D             // STA abs
                    codeptr=>1 = dest
                    codeptr=>3 = $C0B4+(VX<<8)   // LDY ESTKH,X
                    codeptr->5 = $8C             // STY abs+1
                    codeptr=>6 = dest+1
                    codeptr    = codeptr + 8
                    VY         = UNKNOWN
                    break
                is $80 // NOT
                    //puts("NOT")
                    if not A_IS_TOSL
                        *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X
                        codeptr  = codeptr + 2
                    fin
                    codeptr=>0 = $C015+(VX<<8)   // ORA ESTKH,X
                    codeptr=>2 = $02F0           // BEQ +2
                    codeptr=>4 = $FFA9           // LDA #$FF
                    codeptr=>6 = $FF49           // EOR #$FF
                    codeptr=>8 = $C095+(VX<<8)   // STA ESTKH,X
                    codeptr    = codeptr + 10
                    A_IS_TOSL  = TOS_DIRTY       // STA ESTKL,X
                    break
                is $82 // ADD
                    //puts("ADD")
                    if not A_IS_TOSL
                        *codeptr = $D0B5+(VX<<8)     // LDA ESTKL,X
                        codeptr  = codeptr + 2
                    fin
                    codeptr->0 = $18                 // CLC
                    codeptr=>1 = $D075+$0100+(VX<<8) // ADC ESTKL+1,X
                    codeptr=>3 = $D095+$0100+(VX<<8) // STA ESTKL+1,X
                    codeptr=>5 = $C0B5+(VX<<8)       // LDA ESTKH,X
                    codeptr=>7 = $C075+$0100+(VX<<8) // ADC ESTKH+1,X
                    codeptr=>9 = $C095+$0100+(VX<<8) // STA ESTKH+1,X
                    codeptr    = codeptr + 11
                    VX++                             // INX
                    A_IS_TOSL  = FALSE
                    break
                is $84 // SUB
                    //puts("SUB")
                    if A_IS_TOSL & TOS_DIRTY
                        *codeptr = $D095+(VX<<8)      // STA ESTKL,X
                        codeptr  = codeptr + 2
                    fin
                    codeptr=>0  = $D0B5+$0100+(VX<<8) // LDA ESTKL+1,X
                    codeptr->2  = $38                 // SEC
                    codeptr=>3  = $D0F5+(VX<<8)       // SBC ESTKL,X
                    codeptr=>5  = $D095+$0100+(VX<<8) // STA ESTKL+1,X
                    codeptr=>7  = $C0B5+$0100+(VX<<8) // LDA ESTKH+1,X
                    codeptr=>9  = $C0F5+(VX<<8)       // SBC ESTKH,X
                    codeptr=>11 = $C095+$0100+(VX<<8) // STA ESTKH+1,X
                    codeptr     = codeptr + 13
                    VX++                              // INX
                    A_IS_TOSL   = FALSE
                    break
                is $86 // MUL
                is $88 // DIV
                is $8A // MOD
                is $9A // SHL
                is $9C // SHR
                    //puts("MUL,DIV,MOD,SHL,SHR")
                    //  when opcode
                    //        is $86
                    //            //puts("MUL")
                    //        is $88
                    //            //puts("DIV")
                    //        is $8A
                    //            //puts("MOD")
                    //         is $9A
                    //            //puts("SHL")
                    //        is $9C
                    //            //puts("SHR")
                    //  wend
                    //
                    // Call into VM
                    //
                    codeptr, VX = resolveX(codeptr, VX)
                    if A_IS_TOSL & TOS_DIRTY
                        *codeptr = $D095//+(VX<<8) // STA ESTKL,X
                        codeptr  = codeptr + 2
                    fin
                    codeptr->0 = $20               // JSR INTERP
                    codeptr=>1 = $3D0              // INTERP
                    codeptr=>3 = $C000+opcode      // OPCODE; NATV CODE
                    codeptr    = codeptr + 5
                    VY         = UNKNOWN
                    A_IS_TOSL  = FALSE
                    break
               is $8C // INCR
                    //puts("INCR")
                    if not A_IS_TOSL
                        *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X
                        codeptr  = codeptr + 2
                    fin
                    codeptr->0 = $18             // CLC
                    codeptr=>1 = $0169           // ADC #$01
                    codeptr=>3 = $0290           // BCC +2
                    codeptr=>5 = $C0F6+(VX<<8)   // INC ESTKH,X
                    codeptr    = codeptr + 7
                    A_IS_TOSL  = TOS_DIRTY       // STA ESTKL,X
                    break
                is $8E // DECR
                    //puts("DECR")
                    if not A_IS_TOSL
                        *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X
                        codeptr  = codeptr + 2
                    fin
                    codeptr->0 = $38             // SEC
                    codeptr=>1 = $01E9           // SBC #$01
                    codeptr=>3 = $02B0           // BCS +2
                    codeptr=>5 = $C0D6+(VX<<8)   // DEC ESTKH,X
                    codeptr    = codeptr + 7
                    A_IS_TOSL  = TOS_DIRTY       // STA ESTKL,X
                    break
                is $90 // NEG
                    //puts("NEG")
                    if A_IS_TOSL & TOS_DIRTY
                        *codeptr = $D095+(VX<<8) // STA ESTKL,X
                        codeptr  = codeptr + 2
                    fin
                    if VY <> 0
                        *codeptr = $00A0         // LDY #$00
                        codeptr  = codeptr + 2
                        VY       = 0
                    fin
                    codeptr=>0 = $3898           // TYA -> LDA #$00; SEC
                    codeptr=>2 = $D0F5+(VX<<8)   // SBC ESTKL,X
                    codeptr=>4 = $D095+(VX<<8)   // STA ESTKL,X
                    codeptr->6 = $98             // TYA -> LDA #00
                    codeptr=>7 = $C0F5+(VX<<8)   // SBC ESTKH,X
                    codeptr=>9 = $C095+(VX<<8)   // STA ESTKH,X
                    codeptr    = codeptr + 11
                    A_IS_TOSL  = FALSE
                    break
                is $92 // COMP
                    //puts("COMP")
                    if not A_IS_TOSL
                        *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X
                        codeptr  = codeptr + 2
                    fin
                    codeptr=>0 = $FF49           // EOR #$FF
                    codeptr=>2 = $D095+(VX<<8)   // STA ESTKL,X
                    codeptr=>4 = $C0B5+(VX<<8)   // LDA ESTKH,X
                    codeptr=>6 = $FF49           // EOR #$FF
                    codeptr=>8 = $C095+(VX<<8)   // STA ESTKH,X
                    codeptr    = codeptr + 10
                    A_IS_TOSL  = FALSE
                    break
                is $94 // AND
                    //puts("AND")
                    if not A_IS_TOSL
                        *codeptr = $D0B5+(VX<<8)      // LDA ESTKL,X
                        codeptr  = codeptr + 2
                    fin
                    codeptr=>0  = $D035+$0100+(VX<<8) // AND ESTKL+1,X
                    codeptr=>2  = $D095+$0100+(VX<<8) // STA ESTKL+1,X
                    codeptr=>4  = $C0B5+(VX<<8)       // LDA ESTKH,X
                    codeptr=>6  = $C035+$0100+(VX<<8) // AND ESTKH+1,X
                    codeptr=>8  = $C095+$0100+(VX<<8) // STA ESTKH+1,X
                    codeptr     = codeptr + 10
                    VX++                              // INX
                    A_IS_TOSL   = FALSE
                    break
                is $96 // OR
                    //puts("OR")
                    if not A_IS_TOSL
                        *codeptr = $D0B5+(VX<<8)      // LDA ESTKL,X
                        codeptr  = codeptr + 2
                    fin
                    codeptr=>0  = $D015+$0100+(VX<<8) // ORA ESTKL+1,X
                    codeptr=>2  = $D095+$0100+(VX<<8) // STA ESTKL+1,X
                    codeptr=>4  = $C0B5+(VX<<8)       // LDA ESTKH,X
                    codeptr=>6  = $C015+$0100+(VX<<8) // ORA ESTKH+1,X
                    codeptr=>8  = $C095+$0100+(VX<<8) // STA ESTKH+1,X
                    codeptr     = codeptr + 10
                    VX++                              // INX
                    A_IS_TOSL   = FALSE
                    break
                is $98 // XOR
                    //puts("XOR")
                    if not A_IS_TOSL
                        *codeptr = $D0B5+(VX<<8)      // LDA ESTKL,X
                        codeptr  = codeptr + 2
                    fin
                    codeptr=>0  = $D055+$0100+(VX<<8) // EOR ESTKL+1,X
                    codeptr=>2  = $D095+$0100+(VX<<8) // STA ESTKL+1,X
                    codeptr=>4  = $C0B5+(VX<<8)       // LDA ESTKH,X
                    codeptr=>6  = $C055+$0100+(VX<<8) // EOR ESTKH+1,X
                    codeptr=>8  = $C095+$0100+(VX<<8) // STA ESTKH+1,X
                    codeptr     = codeptr + 10
                    VX++                              // INX
                    A_IS_TOSL   = FALSE
                    break
                is $9E // IDXW
                    //puts("IDXW")
                    if not A_IS_TOSL
                        *codeptr = $D0B5+(VX<<8)      // LDA ESTKL,X
                        codeptr  = codeptr + 2
                    fin
                    codeptr->0  = $0A                 // ASL
                    codeptr=>1  = $C036+(VX<<8)       // ROL ESTKH,X
                    codeptr->3  = $18                 // CLC
                    codeptr=>4  = $D075+$0100+(VX<<8) // ADC ESTKL+1,X
                    codeptr=>6  = $D095+$0100+(VX<<8) // STA ESTKL+1,X
                    codeptr=>8  = $C0B5+(VX<<8)       // LDA ESTKH,X
                    codeptr=>10 = $C075+$0100+(VX<<8) // ADC ESTKH+1,X
                    codeptr=>12 = $C095+$0100+(VX<<8) // STA ESTKH+1,X
                    codeptr     = codeptr + 14
                    VX++                              // INX
                    A_IS_TOSL   = FALSE
                    break
                is $A0 // BRGT - FOR/NEXT SPECIFIC TEST & BRANCH
                    i++
                    dest = i + *(bytecode+i)
                    //puts("BRGT "); puti(dest)
                    i++
                    codeptr, VX = resolveX(codeptr, VX)
                    if A_IS_TOSL & TOS_DIRTY
                        *codeptr = $D095//+(VX<<8)      // STA ESTKL,X
                        codeptr  = codeptr + 2
                    fin
                    codeptr=>0  = $D0B5+$0100//+(VX<<8) // LDA ESTKL+1,X
                    codeptr=>2  = $D0D5//+(VX<<8)       // CMP ESTKL,X
                    codeptr=>4  = $C0B5+$0100//+(VX<<8) // LDA ESTKH+1,X
                    codeptr=>6  = $C0F5//+(VX<<8)       // SBC ESTKH
                    codeptr=>8  = $0250                 // BVC +2
                    codeptr=>10 = $8049                 // EOR #$80
                    codeptr=>12 = $0510                 // BPL +5
                    codeptr=>14 = $E8E8                 // INX; INX
                    codeptr->16 = $4C                   // JMP abs
                    codeptr=>17 = addrxlate=>[dest]
                    if not (codeptr->18 & $80) // Unresolved address list
                        addrxlate=>[dest] = codeptr + 17 - *jitcodeptr
                    fin
                    codeptr   = codeptr + 19
                    A_IS_TOSL = FALSE
                    break
                is $A2 // BRLT - FOR/NEXT SPECIFIC TEST & BRANCH 
                    i++
                    dest = i + *(bytecode+i)
                    //puts("BRLT "); puti(dest)
                    i++
                    codeptr, VX = resolveX(codeptr, VX)
                    if not A_IS_TOSL
                        *codeptr = $D0B5//+(VX<<8)      // LDA ESTKL,X
                        codeptr  = codeptr + 2
                    elsif A_IS_TOSL & TOS_DIRTY
                        *codeptr = $D095//+(VX<<8)      // STA ESTKL,X
                        codeptr  = codeptr + 2
                    fin
                    codeptr=>0  = $D0D5+$0100//+(VX<<8) // CMP ESTKL+1,X
                    codeptr=>2  = $C0B5//+(VX<<8)       // LDA ESTKH,X
                    codeptr=>4  = $C0F5+$0100//+(VX<<8) // SBC ESTKH+1
                    codeptr=>6  = $0250                 // BVC +2
                    codeptr=>8  = $8049                 // EOR #$80
                    codeptr=>10 = $0510                 // BPL +5
                    codeptr=>12 = $E8E8                 // INX; INX
                    codeptr->14 = $4C                   // JMP abs
                    codeptr=>15 = addrxlate=>[dest]
                    if not (codeptr->16 & $80) // Unresolved address list
                        addrxlate=>[dest] = codeptr + 15 - *jitcodeptr
                    fin
                    codeptr   = codeptr + 17
                    A_IS_TOSL = FALSE
                    break
                is $A4 // INCBRLE - FOR/NEXT SPECIFIC INC & TEST & BRANCH
                    i++
                    dest = i + *(bytecode+i)
                    //puts("INCBRLE "); puti(dest)
                    i++
                    //
                    // INCR
                    //
                    if not A_IS_TOSL
                        *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X
                        codeptr  = codeptr + 2
                    fin
                    codeptr->0 = $18             // CLC
                    codeptr=>1 = $0169           // ADC #$01
                    codeptr=>3 = $D095+(VX<<8)   // STA ESTKL,X
                    codeptr=>5 = $0290           // BCC +2
                    codeptr=>7 = $C0F6+(VX<<8)   // INC ESTKH,X
                    codeptr, VX = resolveX(codeptr + 9, VX)
                    //
                    // BRLE
                    //
                    codeptr=>0  = $D0B5+$0100//+(VX<<8) // LDA ESTKL+1,X
                    codeptr=>2  = $D0D5//+(VX<<8)       // CMP ESTKL,X
                    codeptr=>4  = $C0B5+$0100//+(VX<<8) // LDA ESTKH+1,X
                    codeptr=>6  = $C0F5//+(VX<<8)       // SBC ESTKH
                    codeptr=>8  = $0250                 // BVC +2
                    codeptr=>10 = $8049                 // EOR #$80
                    codeptr=>12 = $0330                 // BMI +3
                    codeptr->14 = $4C                   // JMP abs
                    codeptr=>15 = addrxlate=>[dest]
                    if not (codeptr->16 & $80) // Unresolved address list
                        addrxlate=>[dest] = codeptr + 15 - *jitcodeptr
                    fin
                    codeptr=>17 = $E8E8 //VX=VX+2       // INX; INX
                    codeptr     = codeptr + 19
                    A_IS_TOSL   = FALSE
                    break
                is $A6 // ADDBRLE - FOR/NEXT SPECIFIC ADD & TEST & BRANCH
                    i++
                    dest = i + *(bytecode+i)
                    //puts("ADDBRLE "); puti(dest)
                    i++
                    //
                    // ADD
                    //
                    if not A_IS_TOSL
                        *codeptr = $D0B5+(VX<<8)                 // LDA ESTKL,X
                        codeptr  = codeptr + 2
                    fin
                    codeptr->0 = $18                             // CLC
                    codeptr=>1 = $D075+$0100+(VX<<8)             // ADC ESTKL+1,X
                    codeptr=>3 = $D095+$0100+(VX<<8)             // STA ESTKL+1,X
                    codeptr=>5 = $C0B5+(VX<<8)                   // LDA ESTKH,X
                    codeptr=>7 = $C075+$0100+(VX<<8)             // ADC ESTKH+1,X
                    codeptr=>9 = $C095+$0100+(VX<<8)             // STA ESTKH+1,X
                    codeptr, VX = resolveX(codeptr + 11, VX + 1) // INX
                    //
                    // BRLE
                    //
                    codeptr=>0  = $D0B5+$0100//+(VX<<8) // LDA ESTKL+1,X
                    codeptr=>2  = $D0D5+(VX<<8)         // CMP ESTKL,X
                    codeptr=>4  = $C0B5+$0100//+(VX<<8) // LDA ESTKH+1,X
                    codeptr=>6  = $C0F5+(VX<<8)         // SBC ESTKH
                    codeptr=>8  = $0250                 // BVC +2
                    codeptr=>10 = $8049                 // EOR #$80
                    codeptr=>12 = $0330                 // BMI +3
                    codeptr->14 = $4C                   // JMP abs
                    codeptr=>15 = addrxlate=>[dest]
                    if not (codeptr->16 & $80) // Unresolved address list
                        addrxlate=>[dest] = codeptr + 15 - *jitcodeptr
                    fin
                    codeptr=>17 = $E8E8 //VX=VX+2       // INX; INX
                    codeptr     = codeptr + 19
                    A_IS_TOSL   = FALSE
                    break
                is $A8 // DECBRGR - FOR/NEXT SPECIFIC DEC & TEST & BRANCH
                    i++
                    dest = i + *(bytecode+i)
                    //puts("DECBRGE "); puti(dest)
                    i++
                    //
                    // DECR
                    //
                    if not A_IS_TOSL
                        *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X
                        codeptr  = codeptr + 2
                    fin
                    codeptr->0 = $38             // SEC
                    codeptr=>1 = $01E9           // SBC #$01
                    codeptr=>3 = $D095+(VX<<8)   // STA ESTKL,X
                    codeptr=>5 = $02B0           // BCS +2
                    codeptr=>7 = $C0D6+(VX<<8)   // DEC ESTKH,X
                    codeptr, VX = resolveX(codeptr + 9, VX)
                    //
                    // BRGE
                    //
                    codeptr=>0  = $D0D5+$0100//+(VX<<8) // CMP ESTKL+1,X
                    codeptr=>2  = $C0B5//+(VX<<8)       // LDA ESTKH,X
                    codeptr=>4  = $C0F5+$0100//+(VX<<8) // SBC ESTKH+1,X
                    codeptr=>6  = $0250                 // BVC +2
                    codeptr=>8  = $8049                 // EOR #$80
                    codeptr=>10 = $0330                 // BMI +3
                    codeptr->12 = $4C                   // JMP abs
                    codeptr=>13 = addrxlate=>[dest]
                    if not (codeptr->14 & $80) // Unresolved address list
                        addrxlate=>[dest] = codeptr + 13 - *jitcodeptr
                    fin
                    codeptr=>15 = $E8E8 //VX=VX+2       // INX; INX
                    codeptr     = codeptr + 17
                    A_IS_TOSL   = FALSE
                    break
                is $AA // SUBBRGE - FOR/NEXT SPECIFIC SUB & TEST & BRANCH
                    i++
                    dest = i + *(bytecode+i)
                    //puts("SUBBRGE "); puti(dest)
                    i++
                    //
                    // SUB
                    //
                    if A_IS_TOSL & TOS_DIRTY
                        *codeptr = $D095+(VX<<8)                 // STA ESTKL,X
                        codeptr  = codeptr + 2
                    fin
                    codeptr=>0  = $D0B5+$0100+(VX<<8)            // LDA ESTKL+1,X
                    codeptr->2  = $38                            // SEC
                    codeptr=>3  = $D0F5+(VX<<8)                  // SBC ESTKL,X
                    codeptr=>5  = $D095+$0100+(VX<<8)            // STA ESTKL+1,X
                    codeptr=>7  = $C0B5+$0100+(VX<<8)            // LDA ESTKH+1,X
                    codeptr=>9  = $C0F5+(VX<<8)                  // SBC ESTKH,X
                    codeptr=>11 = $C095+$0100+(VX<<8)            // STA ESTKH+1,X
                    codeptr, VX = resolveX(codeptr + 13, VX + 1) // INX
                    //
                    // BRGE
                    //
                    codeptr=>0  = $D0B5//+(VX<<8)       // LDA ESTKL,X
                    codeptr=>2  = $D0D5+$0100//+(VX<<8) // CMP ESTKL+1,X
                    codeptr=>4  = $C0B5//+(VX<<8)       // LDA ESTKH,X
                    codeptr=>6  = $C0F5+$0100//+(VX<<8) // SBC ESTKH+1,X
                    codeptr=>8  = $0250                 // BVC +2
                    codeptr=>10 = $8049                 // EOR #$80
                    codeptr=>12 = $0330                 // BMI +3
                    codeptr->14 = $4C                   // JMP abs
                    codeptr=>15 = addrxlate=>[dest]
                    if not (codeptr->16 & $80) // Unresolved address list
                        addrxlate=>[dest] = codeptr + 15 - *jitcodeptr
                    fin
                    codeptr=>17 = $E8E8 //VX=VX+2       // INX; INX
                    codeptr     = codeptr + 19
                    A_IS_TOSL   = FALSE
                    break
                is $AC // BRAND - LOGICAL AND SPECIFIC BRANCH
                    i++
                    dest = i + *(bytecode+i)
                    i++
                    //puts("BRAND "); puti(dest)
                    codeptr, VX = resolveX(codeptr, VX)
                    if not A_IS_TOSL
                        *codeptr = $D0B5//+(VX<<8) // LDA ESTKL,X
                        codeptr  = codeptr + 2
                    elsif A_IS_TOSL & TOS_DIRTY
                        *codeptr = $D095//+(VX<<8) // STA ESTKL,X
                        codeptr  = codeptr + 2
                    fin
                    codeptr=>0 = $C015//+(VX<<8)   // ORA ESTKH,X
                    codeptr=>2 = $03D0             // BNE +3
                    codeptr->4 = $4C               // JMP abs
                    codeptr=>5 = addrxlate=>[dest]
                    if not (codeptr->6 & $80) // Unresolved address list
                        addrxlate=>[dest] = codeptr + 5 - *jitcodeptr
                    fin
                    codeptr   = codeptr + 7
                    VX++                           // INX
                    A_IS_TOSL = FALSE
                    break
                is $AE // BROR - LOGICAL OR SPECIFIC BRANCH
                    i++
                    dest = i + *(bytecode+i)
                    i++
                    //puts("BROR "); puti(dest)
                    codeptr, VX = resolveX(codeptr, VX)
                    if not A_IS_TOSL
                        *codeptr = $D0B5//+(VX<<8) // LDA ESTKL,X
                        codeptr  = codeptr + 2
                    elsif A_IS_TOSL & TOS_DIRTY
                        *codeptr = $D095//+(VX<<8) // STA ESTKL,X
                        codeptr  = codeptr + 2
                    fin
                    codeptr=>0 = $C015//+(VX<<8)   // ORA ESTKH,X
                    codeptr=>2 = $03F0             // BEQ +3
                    codeptr->4 = $4C               // JMP abs
                    codeptr=>5 = addrxlate=>[dest]
                    if not (codeptr->6 & $80) // Unresolved address list
                        addrxlate=>[dest] = codeptr + 5 - *jitcodeptr
                    fin
                    codeptr   = codeptr + 7
                    VX++                           // INX
                    A_IS_TOSL = FALSE
                    break
                is $B0 // ADDLB
                    i++
                    j = ^(bytecode+i)
                    //puts("ADDLB "); puti(j)
                    if not A_IS_TOSL
                        *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X
                        codeptr  = codeptr + 2
                    fin
                    if VY <> j                  
                        *codeptr = $A0+(j<<8)    // LDY #imm
                        codeptr  = codeptr + 2
                        VY       = j
                    fin
                    codeptr->0 = $18             // CLC                    
                    codeptr=>1 = $E071           // ADC (IFP),Y
                    codeptr=>3 = $0290           // BCC +2
                    codeptr=>5 = $C0F6+(VX<<8)   // INC ESTKH,X
                    codeptr    = codeptr + 7
                    A_IS_TOSL  = TOS_DIRTY       // STA ESTKL,X
                    break
                is $B2 // ADDLW
                    i++
                    j = ^(bytecode+i)
                    //puts("ADDLW "); puti(j)
                    if not A_IS_TOSL
                        *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X
                        codeptr  = codeptr + 2
                    fin
                    if VY <> j                
                        *codeptr = $A0+(j<<8)    // LDY #imm
                        codeptr  = codeptr + 2
                    fin
                    codeptr->0  = $18            // CLC                    
                    codeptr=>1  = $E071          // ADC (IFP),Y
                    codeptr=>3  = $D095+(VX<<8)  // STA ESTKL,X
                    codeptr=>5  = $C0B5+(VX<<8)  // LDA ESTKH,X
                    codeptr->7  = $C8            // INY
                    codeptr=>8  = $E071          // ADC (IFP),Y
                    codeptr=>10 = $C095+(VX<<8)  // STA ESTKH,X
                    codeptr     = codeptr + 12
                    VY          = j + 1
                    A_IS_TOSL = FALSE
                    break
                is $B4 // ADDAB
                    dest = *(bytecode+i+1)
                    i    = i + 2
                    //puts("ADDAB $"); puth(*(bytecode+i))
                    if not A_IS_TOSL
                        *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X
                        codeptr  = codeptr + 2
                    fin
                    codeptr=>0 = $6D18           // CLC; ADC abs                    
                    codeptr=>2 = dest
                    codeptr=>4 = $0290           // BCC +2
                    codeptr=>6 = $C0F6+(VX<<8)   // INC ESTKH,X
                    codeptr    = codeptr + 8
                    A_IS_TOSL  = TOS_DIRTY       // STA ESTKL,X
                    break
                is $B6 // ADDAW
                    dest = *(bytecode+i+1)
                    i    = i + 2
                    //puts("ADDAW $"); puth(dest)
                    if not A_IS_TOSL
                        *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X
                        codeptr  = codeptr + 2
                    fin
                    codeptr=>0  = $6D18          // CLC; ADC abs                    
                    codeptr=>2  = dest
                    codeptr=>4  = $D095+(VX<<8)  // STA ESTKL,X
                    codeptr=>6  = $C0B5+(VX<<8)  // LDA ESTKH,X
                    codeptr->8  = $6D            // ADC abs                    
                    codeptr=>9  = dest+1
                    codeptr=>11 = $C095+(VX<<8)  // STA ESTKH,X
                    codeptr     = codeptr + 13
                    A_IS_TOSL   = FALSE
                    break
                is $B8 // IDXLB
                    i++
                    j = ^(bytecode+i)
                    //puts("IDXLB "); puti(j)
                    if A_IS_TOSL & TOS_DIRTY
                        *codeptr = $D095+(VX<<8) // STA ESTKL,X
                        codeptr  = codeptr + 2
                    fin
                    if VY <> j                  
                        *codeptr = $A0+(j<<8)    // LDY #imm
                        codeptr  = codeptr + 2
                    fin
                    *codeptr = $E0B1             // LDA (IFP),Y
                    codeptr  = codeptr + 2
                    if j                    
                        *codeptr = $00A0         // LDY #$00
                        codeptr  = codeptr + 2
                    fin
                    codeptr->0  = $0A            // ASL
                    codeptr=>1  = $0290          // BCC +2
                    codeptr=>3  = $18C8          // INY; CLC
                    codeptr=>5  = $D075+(VX<<8)  // ADC ESTKL,X
                    codeptr=>7  = $D095+(VX<<8)  // STA ESTKL,X
                    codeptr->9  = $98            // TYA
                    codeptr=>10 = $C075+(VX<<8)  // ADC ESTKH,X
                    codeptr=>12 = $C095+(VX<<8)  // STA ESTKH,X
                    codeptr     = codeptr + 14
                    VY          = UNKNOWN
                    A_IS_TOSL   = FALSE
                    break
                is $BA // IDXLW
                    i++
                    j = ^(bytecode+i)
                    //puts("IDXLW "); puti(j)
                    if A_IS_TOSL & TOS_DIRTY
                        *codeptr = $D095+(VX<<8) // STA ESTKL,X
                        codeptr  = codeptr + 2
                    fin
                    if VY <> j                  
                        *codeptr = $A0+(j<<8)    // LDY #imm
                        codeptr  = codeptr + 2
                    fin
                    codeptr=>0  = $E0B1          // LDA (IFP),Y
                    codeptr->2  = $0A            // ASL
                    codeptr=>3  = $E785          // STA $E7:TMPL
                    codeptr->5  = $C8            // INY
                    codeptr=>6  = $E0B1          // LDA (IFP),Y
                    codeptr=>8  = $A82A          // ROL; TAY
                    codeptr=>10 = $E7A5          // LDA $E7:TMPL
                    codeptr->12 = $18            // CLC
                    codeptr=>13 = $D075+(VX<<8)  // ADC ESTKL,X
                    codeptr=>15 = $D095+(VX<<8)  // STA ESTKL,X
                    codeptr->17 = $98            // TYA
                    codeptr=>18 = $C075+(VX<<8)  // ADC ESTKLH,X
                    codeptr=>20 = $C095+(VX<<8)  // STA ESTKLH,X
                    codeptr     = codeptr + 22
                    VY          = UNKNOWN
                    A_IS_TOSL   = FALSE
                    break
                is $BC // IDXAB
                    dest = *(bytecode+i+1)
                    i    = i + 2
                    //puts("IDXAB $"); puth(*(bytecode+i))
                    if A_IS_TOSL & TOS_DIRTY
                        *codeptr = $D095+(VX<<8) // STA ESTKL,X
                        codeptr  = codeptr + 2
                    fin
                    if VY <> 0
                        *codeptr = $00A0         // LDY #$00
                        codeptr  = codeptr + 2
                    fin
                    codeptr->0  = $AD            // LDA abs
                    codeptr=>1  = dest
                    codeptr->3  = $0A            // ASL
                    codeptr=>4  = $0290          // BCC +2
                    codeptr=>6  = $18C8          // INY; CLC
                    codeptr=>8  = $D075+(VX<<8)  // ADC ESTKL,X
                    codeptr=>10 = $D095+(VX<<8)  // STA ESTKL,X
                    codeptr->12 = $98            // TYA
                    codeptr=>13 = $C075+(VX<<8)  // ADC ESTKH,X
                    codeptr=>15 = $C095+(VX<<8)  // STA ESTKLH,X
                    codeptr     = codeptr + 17
                    VY          = UNKNOWN
                    A_IS_TOSL   = FALSE
                    break
                is $BE // IDXAW
                    dest = *(bytecode+i+1)
                    i    = i + 2
                    //puts("IDXAW $"); puth(dest)
                    if A_IS_TOSL & TOS_DIRTY
                        *codeptr = $D095+(VX<<8) // STA ESTKL,X
                        codeptr  = codeptr + 2
                    fin
                    codeptr->0  = $AD            // LDA abs
                    codeptr=>1  = dest
                    codeptr->3  = $0A            // ASL
                    codeptr=>4  = $E785          // STA $E7:TMPL
                    codeptr->6  = $AD            // LDA abs                    
                    codeptr=>7  = dest+1
                    codeptr=>9  = $A82A          // ROL; TAY
                    codeptr=>11 = $E7A5          // LDA $E7:TMPL
                    codeptr->13 = $18            // CLC
                    codeptr=>14 = $D075+(VX<<8)  // ADC ESTKL,X
                    codeptr=>16 = $D095+(VX<<8)  // STA ESTKL,X
                    codeptr->18 = $98            // TYA
                    codeptr=>19 = $C075+(VX<<8)  // ADC ESTKH,X
                    codeptr=>21 = $C095+(VX<<8)  // STA ESTKLH,X
                    codeptr     = codeptr + 23
                    VY          = UNKNOWN
                    A_IS_TOSL   = FALSE
                    break
                is $FE // NOPed out earlier by SELect
                    break
                otherwise
                    //puts("???: $"); puth(^(bytecode+i)); putln
            wend
        fin
        //putln
        i++
        if i >= defptr->bytecodesize
            //
            // Done compiling. Update DEF entry with JMP to compiled code
            //
            defptr->interpjsr  = $4C // JMP
            defptr=>interpaddr = *jitcodeptr
            *jitcodeptr        = codeptr
            //
            // Free working bufffers
            //
            //heaprelease(addrxlate)
            //puts("Done compiling: $"); puth(defptr=>interpaddr); putln
            //getc
            return
        fin
        //if opcode == $B6; getc; fin
    loop
    //
    // If we got here. we ran out of code buffer space. Overwrite interpreter
    // entrypoint with standard bytecode interpreter
    //
    defptr=>interpaddr = interpentry
    //
    // Free working bufffers
    //
    //heaprelease(addrxlate)
    //puts("Ran out of code buffer\n")
    //getc
end
//
// Install JIT compiler
//
if *jitcomp
    puts("JIT compiler already installed!\n")
    return 0
fin
puts("Installing JIT compiler\n")
*jitcomp = @compiler
return modkeep
done
