1
0
mirror of https://github.com/dschmenk/PLASMA.git synced 2026-03-12 01:41:40 +00:00
Files
PLASMA/src/libsrc/jitcore.pla
2019-12-12 01:13:05 -08:00

1549 lines
70 KiB
Plaintext

//
// 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
defptr=>interpaddr = indirectentry // assume compile will fail
addrxlate = heapmark // heapalloc(512 + defptr->bytecodesize)
if isult(heapavail, 512 + defptr->bytecodesize) // 256 * sizeof(word) address xlate
//
// Not enough heap available
//
//puts("Not enough free heap\n")
return
fin
//
// Copy bytecode def from AUX to heap for compiling
//
bytecode = addrxlate + 512 // def bytecode
defcpy(bytecode, defptr)
//puts("JITC:$"); puth(defptr=>bytecodeaddr); puts("=>$"); puth(bytecode)
//puts(",$"); puth(defptr->bytecodesize); 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
memset(isdata, 0, 256) // Clear isdata buffer
i = 0
while i < defptr->bytecodesize
if not ^(isdata+i)
//puth(bytecode+i); putc(':'); putb(^(bytecode+i) & $FE); putln; getc
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 // BRNE
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++
dest = i + *(bytecode+i)
i++
^(bytecode+dest) = ^(bytecode+dest) | 1 // Flag as branch dest
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
//
// Compile the bytecodes
//
memset(addrxlate, 0, 512) // Clear xlate buffer
//puts("Bytecode: $"); puth(bytecode); putln; getc
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 = directentry
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 = estkl8+$95//+(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 = estkl8+$95+(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 = estkh8+$94+(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 = estkl8+$95+(VX<<8) // STA ESTKL,X
codeptr = codeptr + 2
fin
VX-- // DEX
codeptr=>0 = $FFA9 // LDA #$FF
codeptr=>2 = estkh8+$95+(VX<<8) // STA ESTKH,X
codeptr = codeptr + 4
A_IS_TOSL = TOS_DIRTY // STA ESTKL,X
break
is $22 // BREQ
is $24 // BRNE
i++
dest = i + *(bytecode+i)
i++
codeptr, VX = resolveX(codeptr, VX + 2) // INX; INX
if not A_IS_TOSL
*codeptr = estkl8+$B5-$0200//+(VX<<8) // LDA ESTKL-2,X
codeptr = codeptr + 2
fin
if opcode == $22
//puts("BREQ "); puti(dest)
codeptr=>2 = $09D0 // BNE +9
codeptr=>8 = $03D0 // BNE +3
else
//puts("BRNE "); puti(dest)
codeptr=>2 = $06D0 // BNE +6
codeptr=>8 = $03F0 // BEQ +3
fin
codeptr=>0 = estkl8+$D5-$0100//+(VX<<8) // CMP ESTKL-1,X
codeptr=>4 = estkh8+$B5-$0200//+(VX<<8) // LDA ESTKH-2,X
codeptr=>6 = estkh8+$D5-$0100//+(VX<<8) // CMP ESTKH-1,X
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 = estkl8+$95+(VX<<8) // STA ESTKL,X
codeptr = codeptr + 2
fin
VX-- // DEX
codeptr=>0 = $A9+(dest&$FF00) // LDA #<VAL
codeptr=>2 = estkh8+$95+(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 = estkl8+$95+(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 = ifpl8+$65 // ADC IFPL
codeptr=>3 = estkl8+$95+(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 = ifph8+$65 // ADC IFPH
codeptr=>2 = estkh8+$95+(VX<<8) // STA ESTKH,X
codeptr = codeptr + 4
A_IS_TOSL = FALSE
break
is $2A // CB
is $5E // CFFB
i++
if A_IS_TOSL & TOS_DIRTY
*codeptr = estkl8+$95+(VX<<8) // STA ESTKL,X
codeptr = codeptr + 2
fin
VX-- // DEX
if opcode == $2A
//puts("CB $"); putb(^(bytecode+i))
if VY <> 0
*codeptr = $00A0 // LDY #$00
codeptr = codeptr + 2
VY = 0
fin
codeptr=>0 = estkh8+$94+(VX<<8) // STY ESTKH,X
codeptr = codeptr + 2
else
//puts("CFFB $FF"); putb(^(bytecode+i))
codeptr=>0 = $FFA9 // LDA #$FF
codeptr=>2 = estkh8+$95+(VX<<8) // STA ESTKH,X
codeptr = codeptr + 4
fin
*codeptr = $A9+(^(bytecode+i)<<8) // LDA #imm
codeptr = codeptr + 2
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 = estkl8+$95+(VX<<8) // STA ESTKL,X
codeptr = codeptr + 2
fin
VX-- // DEX
codeptr=>0 = $A9+((codeptr+9)&$FF00) // LDA #>STRING
codeptr=>2 = estkh8+$95+(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 = estkl8+$B5+(VX<<8) // LDA ESTKL,X
codeptr = codeptr + 2
elsif A_IS_TOSL & TOS_DIRTY
*codeptr = estkl8+$95+(VX<<8) // STA ESTKL,X
codeptr = codeptr + 2
fin
codeptr=>0 = estkh8+$B4+(VX<<8) // LDY ESTKH,X
VX-- // DEX
codeptr=>2 = estkh8+$94+(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++
j = ^(bytecode+i)
//puts("ADDI $"); putb(^(bytecode+i))
is $8C // INCR
if opcode == $8C
//puts("INCR")
j = 1
fin
if not A_IS_TOSL
*codeptr = estkl8+$B5+(VX<<8) // LDA ESTKL,X
codeptr = codeptr + 2
fin
codeptr->0 = $18 // CLC
codeptr=>1 = $69+(j<<8) // ADC #imm
codeptr=>3 = $0290 // BCC +2
codeptr=>5 = estkh8+$F6+(VX<<8) // INC ESTKH,X
codeptr = codeptr + 7
A_IS_TOSL = TOS_DIRTY // STA ESTKL,X
break
is $3A // SUBI
i++
j = ^(bytecode+i)
//puts("SUBI $"); putb(^(bytecode+i))
is $8E // DECR
if opcode == $8E
//puts("DECR")
j = 1
fin
if not A_IS_TOSL
*codeptr = estkl8+$B5+(VX<<8) // LDA ESTKL,X
codeptr = codeptr + 2
fin
codeptr->0 = $38 // SEC
codeptr=>1 = $E9+(j<<8) // SBC #imm
codeptr=>3 = $02B0 // BCS +2
codeptr=>5 = estkh8+$D6+(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 = estkl8+$B5+(VX<<8) // LDA ESTKL,X
codeptr = codeptr + 2
fin
codeptr=>0 = $29+(^(bytecode+i)<<8) // AND #imm
codeptr=>2 = estkh8+$94+(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 = estkl8+$B5+(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
is $42 // ISNE
if VY <> 0
*codeptr = $00A0 // LDY #$00
codeptr = codeptr + 2
fin
if not A_IS_TOSL
*codeptr = estkl8+$B5+(VX<<8) // LDA ESTKL,X
codeptr = codeptr + 2
fin
if opcode == $40
//puts("ISEQ")
codeptr=>2 = $07D0 // BNE +7
codeptr=>8 = $01D0 // BNE +1
else
//puts("ISNE")
codeptr=>2 = $06D0 // BNE +6
codeptr=>8 = $01F0 // BEQ +1
fin
codeptr=>0 = estkl8+$D5+$0100+(VX<<8) // CMP ESTKL+1,X
codeptr=>4 = estkh8+$B5+(VX<<8) // LDA ESTKH,X
codeptr=>6 = estkh8+$D5+$0100+(VX<<8) // CMP ESTKH+1
codeptr=>10 = $9888 // DEY; TYA
codeptr=>12 = estkh8+$94+$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
is $4A // ISLE
if VY <> 0
*codeptr = $00A0 // LDY #$00
codeptr = codeptr + 2
fin
if not A_IS_TOSL
*codeptr = estkl8+$B5+(VX<<8) // LDA ESTKL,X
codeptr = codeptr + 2
fin
codeptr=>0 = estkl8+$D5+$0100+(VX<<8) // CMP ESTKL+1,X
codeptr=>2 = estkh8+$B5+(VX<<8) // LDA ESTKH,X
codeptr=>4 = estkh8+$F5+$0100+(VX<<8) // SBC ESTKH+1
codeptr=>6 = $0250 // BVC +2
codeptr=>8 = $8049 // EOR #$80
if opcode == $44
//puts("ISGT")
codeptr=>10 = $0110 // BPL +1
else
//puts("ISLE")
codeptr=>10 = $0130 // BMI +1
fin
codeptr=>12 = $9888 // DEY TYA
codeptr=>14 = estkh8+$94+$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 // ISLT
is $48 // ISGE
if A_IS_TOSL & TOS_DIRTY
*codeptr = estkl8+$95+(VX<<8) // STA ESTKL,X
codeptr = codeptr + 2
fin
if VY <> 0
*codeptr = $00A0 // LDY #$00
codeptr = codeptr + 2
fin
codeptr=>0 = estkl8+$B5+$0100+(VX<<8) // LDA ESTKL+1,X
codeptr=>2 = estkl8+$D5+(VX<<8) // CMP ESTKL,X
codeptr=>4 = estkh8+$B5+$0100+(VX<<8) // LDA ESTKH+1,X
codeptr=>6 = estkh8+$F5+(VX<<8) // SBC ESTKH
codeptr=>8 = $0250 // BVC +2
codeptr=>10 = $8049 // EOR #$80
if opcode == $46
//puts("ISLT")
codeptr=>12 = $0110 // BPL +1
else
//puts("ISGE")
codeptr=>12 = $0130 // BMI +1
fin
codeptr=>14 = $9888 // DEY; TYA
codeptr=>16 = estkh8+$94+$0100+(VX<<8) // STY ESTKH+1,X
codeptr = codeptr + 18
VX++ // INX
VY = UNKNOWN
A_IS_TOSL = TOS_DIRTY // STA ESTKL,X
break
is $4C // BRFLS
is $4E // BRTRU
i++
dest = i + *(bytecode+i)
i++
codeptr, VX = resolveX(codeptr, VX + 1) // INX
if not A_IS_TOSL
*codeptr = estkl8+$B5-$0100//+(VX<<8) // LDA ESTKL-1,X
codeptr = codeptr + 2
fin
codeptr=>0 = estkh8+$15-$0100//+(VX<<8) // ORA ESTKH-1,X
if opcode == $4C
//puts("BRFLS "); puti(dest)
codeptr=>2 = $03D0 // BNE +3
else
//puts("BRTRU "); puti(dest)
codeptr=>2 = $03F0 // BEQ +3
fin
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 = estkl8+$95//+(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 = estkl8+$B5+(VX<<8) // LDA ESTKL,X
codeptr = codeptr + 2
fin
codeptr=>0 = estkh8+$B4+(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 = estkl8+$95//+(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 = estkl8+$B5+(VX<<8) // LDA ESTKL,X
codeptr = codeptr + 2
fin
codeptr=>0 = tmpl8+$85 // STA $E7:TMPL
codeptr=>2 = estkh8+$B5+(VX<<8) // LDA ESTKH,X
codeptr=>4 = tmph8+$85 // STA $E8:TMPH
codeptr, VX = resolveX(codeptr + 6, VX + 1) // INX
//
// Call through TMP
//
codeptr->0 = $20 // JSR abs
codeptr=>1 = jmptmp // $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 = estkl8+$95//+(VX<<8) // STA ESTKL,X
codeptr = codeptr + 2
fin
codeptr->0 = $20 // JSR abs
codeptr=>1 = directentry // 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 = estkl8+$95//+(VX<<8) // STA ESTKL,X
codeptr = codeptr + 2
fin
^codeptr = $60; codeptr++ // RTS
A_IS_TOSL = FALSE
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 = estkl8+$B5+(VX<<8) // LDA ESTKL,X
codeptr = codeptr + 2
fin
codeptr=>0 = estkh8+$95-$0100+(VX<<8) // STA ESTKH-1,X
codeptr=>2 = estkh8+$A1-$0100+(VX<<8) // LDA (ESTKH-1,X)
codeptr=>4 = estkh8+$94+(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 = estkl8+$B5+(VX<<8) // LDA ESTKL,X
codeptr = codeptr + 2
fin
codeptr=>0 = estkh8+$95-$0100+(VX<<8) // STA ESTKH-1,X
codeptr=>2 = estkh8+$A1-$0100+(VX<<8) // LDA (ESTKH-1,X)
codeptr=>4 = estkl8+$95+(VX<<8) // STA ESTKL,X
codeptr=>6 = estkh8+$F6-$0100+(VX<<8) // INC ESTKH-1,X
codeptr=>8 = $02D0 // BNE +2
codeptr=>10 = estkh8+$F6+(VX<<8) // INC ESTKH,X
codeptr=>12 = estkh8+$A1-$0100+(VX<<8) // LDA (ESTKH-1,X)
codeptr=>14 = estkh8+$95+(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 = estkl8+$95+(VX<<8) // STA ESTKL,X
codeptr = codeptr + 2
fin
VX-- // DEX
if VY <> j
*codeptr = $A0+(j<<8) // LDY #imm
codeptr = codeptr + 2
fin
*codeptr = ifpl8+$B1 // LDA (IFP),Y
codeptr = codeptr + 2
if j <> 0
*codeptr = $00A0 // LDY #$00
codeptr = codeptr + 2
fin
*codeptr = estkh8+$94+(VX<<8) // STY ESTKH,X
codeptr = codeptr + 2
VY = 0
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 = estkl8+$95+(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 = ifpl8+$B1 // LDA (IFP),Y
codeptr=>2 = estkh8+$95+(VX<<8) // STA ESTKH,X
codeptr->4 = $88 // DEY
codeptr=>5 = ifpl8+$B1 // LDA (IFP),Y
codeptr = codeptr + 7
A_IS_TOSL = TOS_DIRTY // STA ESTKL,X
break
is $68 // LAB
is $6A // LAW
dest = *(bytecode+i+1)
i = i + 2
if A_IS_TOSL & TOS_DIRTY
*codeptr = estkl8+$95+(VX<<8) // STA ESTKL,X
codeptr = codeptr + 2
fin
VX-- // DEX
if opcode == $68
//puts("LAB $"); puth(dest)
if VY <> 0
*codeptr = $00A0 // LDY #$00
codeptr = codeptr + 2
VY = 0
fin
*codeptr = estkh8+$94+(VX<<8) // STY ESTKH,X
codeptr = codeptr + 2
else
//puts("LAW $"); puth(dest)
codeptr->0 = $AD // LDA abs+1
codeptr=>1 = dest+1
codeptr=>3 = estkh8+$95+(VX<<8) // STA ESTKH,X
codeptr = codeptr + 5
fin
codeptr->0 = $AD // LDA abs
codeptr=>1 = dest
codeptr = codeptr + 3
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 = estkl8+$B5+(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 = ifpl8+$91 // STA (IFP),Y
codeptr = codeptr + 2
if VY <> 0
*codeptr = $00A0 // LDY #$00
codeptr = codeptr + 2
VY = 0
fin
*codeptr = estkh8+$94+(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 = estkl8+$95+(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 = estkh8+$B5+(VX<<8) // LDA ESTKH,X
codeptr=>2 = ifpl8+$91 // STA (IFP),Y
codeptr->4 = $88 // DEY
codeptr=>5 = estkl8+$B5+(VX<<8) // LDA ESTKL,X
codeptr=>7 = ifpl8+$91 // STA (IFP),Y
codeptr = codeptr + 9
A_IS_TOSL = TOS_CLEAN
break
is $70 // SB
is $72 // SW
if not A_IS_TOSL
*codeptr = estkl8+$B5+(VX<<8) // LDA ESTKL,X
codeptr = codeptr + 2
fin
codeptr=>0 = estkh8+$95-$0100+(VX<<8) // STA ESTKH-1,X
codeptr=>2 = estkl8+$B5+$0100+(VX<<8) // LDA ESTKL+1,X
codeptr=>4 = estkh8+$81-$0100+(VX<<8) // STA (ESTKH-1,X)
if opcode == $70
//puts("SB")
codeptr = codeptr + 6
else
//puts("SW")
codeptr=>6 = estkh8+$B5+$0100+(VX<<8) // LDA ESTKH+1,X
codeptr=>8 = estkh8+$F6-$0100+(VX<<8) // INC ESTKH-1,X
codeptr=>10 = $02D0 // BNE +2
codeptr=>12 = estkh8+$F6+(VX<<8) // INC ESTKH,X
codeptr=>14 = estkh8+$81-$0100+(VX<<8) // STA (ESTKH-1,X)
codeptr = codeptr + 16
fin
VX = VX + 2 // INX; INX
A_IS_TOSL = FALSE
break
is $74 // SLB
is $76 // SLW
i++
j = ^(bytecode+i)
if not A_IS_TOSL
*codeptr = estkl8+$B5+(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 = ifpl8+$91 // STA (IFP),Y
if opcode == $74
//puts("SLB "); puti(j)
codeptr = codeptr + 2
else
//puts("SLW "); puti(j)
codeptr->2 = $C8 // INY
codeptr=>3 = estkh8+$B5+(VX<<8) // LDA ESTKH,X
codeptr=>5 = ifpl8+$91 // STA (IFP),Y
codeptr = codeptr + 7
VY++
fin
VX++ // INX
A_IS_TOSL = FALSE
break
is $78 // SAB
is $7A // SAW
dest = *(bytecode+i+1)
i = i + 2
if not A_IS_TOSL
*codeptr = estkl8+$B5+(VX<<8) // LDA ESTKL,X
codeptr = codeptr + 2
fin
codeptr->0 = $8D // STA abs
codeptr=>1 = dest
if opcode == $78
//puts("SAB $"); puth(dest)
codeptr = codeptr + 3
else
//puts("SAW $"); puth(dest)
codeptr=>3 = estkh8+$B5+(VX<<8) // LDA ESTKH,X
codeptr->5 = $8D // STA abs+1
codeptr=>6 = dest+1
codeptr = codeptr + 8
fin
VX++ // INX
A_IS_TOSL = FALSE
break
is $7C // DAB
is $7E // DAW
dest = *(bytecode+i+1)
i = i + 2
if not A_IS_TOSL
*codeptr = estkl8+$B5+(VX<<8) // LDA ESTKL,X
codeptr = codeptr + 2
A_IS_TOSL = TOS_CLEAN
fin
codeptr->0 = $8D // STA abs
codeptr=>1 = dest
if opcode == $7C
//puts("DAB $"); puth(dest)
codeptr = codeptr + 3
if VY <> 0
*codeptr = $00A0 // LDY #$00
codeptr = codeptr + 2
VY = 0
fin
*codeptr = estkh8+$94+(VX<<8) // STY ESTKH,X
codeptr = codeptr + 2
else
//puts("DAW $"); puth(dest)
codeptr=>3 = estkh8+$B4+(VX<<8) // LDY ESTKH,X
codeptr->5 = $8C // STY abs+1
codeptr=>6 = dest+1
codeptr = codeptr + 8
VY = UNKNOWN
fin
break
is $80 // NOT
//puts("NOT")
if not A_IS_TOSL
*codeptr = estkl8+$B5+(VX<<8) // LDA ESTKL,X
codeptr = codeptr + 2
fin
codeptr=>0 = estkh8+$15+(VX<<8) // ORA ESTKH,X
codeptr=>2 = $02F0 // BEQ +2
codeptr=>4 = $FFA9 // LDA #$FF
codeptr=>6 = $FF49 // EOR #$FF
codeptr=>8 = estkh8+$95+(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 = estkl8+$B5+(VX<<8) // LDA ESTKL,X
codeptr = codeptr + 2
fin
codeptr->0 = $18 // CLC
codeptr=>1 = estkl8+$75+$0100+(VX<<8) // ADC ESTKL+1,X
codeptr=>3 = estkl8+$95+$0100+(VX<<8) // STA ESTKL+1,X
codeptr=>5 = estkh8+$B5+(VX<<8) // LDA ESTKH,X
codeptr=>7 = estkh8+$75+$0100+(VX<<8) // ADC ESTKH+1,X
codeptr=>9 = estkh8+$95+$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 = estkl8+$95+(VX<<8) // STA ESTKL,X
codeptr = codeptr + 2
fin
codeptr=>0 = estkl8+$B5+$0100+(VX<<8) // LDA ESTKL+1,X
codeptr->2 = $38 // SEC
codeptr=>3 = estkl8+$F5+(VX<<8) // SBC ESTKL,X
codeptr=>5 = estkl8+$95+$0100+(VX<<8) // STA ESTKL+1,X
codeptr=>7 = estkh8+$B5+$0100+(VX<<8) // LDA ESTKH+1,X
codeptr=>9 = estkh8+$F5+(VX<<8) // SBC ESTKH,X
codeptr=>11 = estkh8+$95+$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 = estkl8+$95//+(VX<<8) // STA ESTKL,X
codeptr = codeptr + 2
fin
codeptr->0 = $20 // JSR INTERP
codeptr=>1 = directentry // INTERP
codeptr=>3 = $C000+opcode // OPCODE; NATV CODE
codeptr = codeptr + 5
VY = UNKNOWN
A_IS_TOSL = FALSE
break
is $90 // NEG
//puts("NEG")
if A_IS_TOSL & TOS_DIRTY
*codeptr = estkl8+$95+(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 = estkl8+$F5+(VX<<8) // SBC ESTKL,X
codeptr=>4 = estkl8+$95+(VX<<8) // STA ESTKL,X
codeptr->6 = $98 // TYA -> LDA #00
codeptr=>7 = estkh8+$F5+(VX<<8) // SBC ESTKH,X
codeptr=>9 = estkh8+$95+(VX<<8) // STA ESTKH,X
codeptr = codeptr + 11
A_IS_TOSL = FALSE
break
is $92 // COMP
//puts("COMP")
if not A_IS_TOSL
*codeptr = estkl8+$B5+(VX<<8) // LDA ESTKL,X
codeptr = codeptr + 2
fin
codeptr=>0 = $FF49 // EOR #$FF
codeptr=>2 = estkl8+$95+(VX<<8) // STA ESTKL,X
codeptr=>4 = estkh8+$B5+(VX<<8) // LDA ESTKH,X
codeptr=>6 = $FF49 // EOR #$FF
codeptr=>8 = estkh8+$95+(VX<<8) // STA ESTKH,X
codeptr = codeptr + 10
A_IS_TOSL = FALSE
break
is $94 // AND
is $96 // OR
is $98 // XOR
when opcode
is $94
//puts("AND")
j = $35
break
is $96
//puts("OR")
j = $15
break
is $98
//puts("XOR")
j = $55
wend
if not A_IS_TOSL
*codeptr = estkl8+$B5+(VX<<8) // LDA ESTKL,X
codeptr = codeptr + 2
fin
codeptr->0 = j // OP
codeptr->1 = estkl+$01+VX // ESTKL+1,X
codeptr=>2 = estkl8+$95+$0100+(VX<<8) // STA ESTKL+1,X
codeptr=>4 = estkh8+$B5+(VX<<8) // LDA ESTKH,X
codeptr->6 = j // OP
codeptr->7 = estkh+$01+VX // ESTKH+1,X
codeptr=>8 = estkh8+$95+$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 = estkl8+$B5+(VX<<8) // LDA ESTKL,X
codeptr = codeptr + 2
fin
codeptr->0 = $0A // ASL
codeptr=>1 = estkh8+$36+(VX<<8) // ROL ESTKH,X
codeptr->3 = $18 // CLC
codeptr=>4 = estkl8+$75+$0100+(VX<<8) // ADC ESTKL+1,X
codeptr=>6 = estkl8+$95+$0100+(VX<<8) // STA ESTKL+1,X
codeptr=>8 = estkh8+$B5+(VX<<8) // LDA ESTKH,X
codeptr=>10 = estkh8+$75+$0100+(VX<<8) // ADC ESTKH+1,X
codeptr=>12 = estkh8+$95+$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)
i++
//puts("BRGT "); puti(dest)
codeptr, VX = resolveX(codeptr, VX)
if A_IS_TOSL & TOS_DIRTY
*codeptr = estkl8+$95//+(VX<<8) // STA ESTKL,X
codeptr = codeptr + 2
fin
codeptr=>0 = estkl8+$B5+$0100//+(VX<<8) // LDA ESTKL+1,X
codeptr=>2 = estkl8+$D5//+(VX<<8) // CMP ESTKL,X
codeptr=>4 = estkh8+$B5+$0100//+(VX<<8) // LDA ESTKH+1,X
codeptr=>6 = estkh8+$F5//+(VX<<8) // SBC ESTKH
codeptr=>8 = $0250 // BVC +2
codeptr=>10 = $8049 // EOR #$80
codeptr=>12 = $0310 // BPL +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 = codeptr + 17
A_IS_TOSL = FALSE
break
is $A2 // BRLT - FOR/NEXT SPECIFIC TEST & BRANCH
i++
dest = i + *(bytecode+i)
i++
//puts("BRLT "); puti(dest)
codeptr, VX = resolveX(codeptr, VX)
if not A_IS_TOSL
*codeptr = estkl8+$B5//+(VX<<8) // LDA ESTKL,X
codeptr = codeptr + 2
elsif A_IS_TOSL & TOS_DIRTY
*codeptr = estkl8+$95//+(VX<<8) // STA ESTKL,X
codeptr = codeptr + 2
fin
codeptr=>0 = estkl8+$D5+$0100//+(VX<<8) // CMP ESTKL+1,X
codeptr=>2 = estkh8+$B5//+(VX<<8) // LDA ESTKH,X
codeptr=>4 = estkh8+$F5+$0100//+(VX<<8) // SBC ESTKH+1
codeptr=>6 = $0250 // BVC +2
codeptr=>8 = $8049 // EOR #$80
codeptr=>10 = $0310 // BPL +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 = codeptr + 15
A_IS_TOSL = FALSE
break
is $A4 // INCBRLE - FOR/NEXT SPECIFIC INC & TEST & BRANCH
is $A6 // ADDBRLE - FOR/NEXT SPECIFIC ADD & TEST & BRANCH
i++
dest = i + *(bytecode+i)
i++
if not A_IS_TOSL
*codeptr = estkl8+$B5+(VX<<8) // LDA ESTKL,X
codeptr = codeptr + 2
fin
if opcode == $A4
//
// INCR
//
//puts("INCBRLE "); puti(dest)
codeptr->0 = $18 // CLC
codeptr=>1 = $0169 // ADC #$01
codeptr=>3 = estkl8+$95+(VX<<8) // STA ESTKL,X
codeptr=>5 = $0290 // BCC +2
codeptr=>7 = estkh8+$F6+(VX<<8) // INC ESTKH,X
codeptr, VX = resolveX(codeptr + 9, VX)
else
//
// ADD
//
//puts("ADDBRLE "); puti(dest)
codeptr->0 = $18 // CLC
codeptr=>1 = estkl8+$75+$0100+(VX<<8) // ADC ESTKL+1,X
codeptr=>3 = estkl8+$95+$0100+(VX<<8) // STA ESTKL+1,X
codeptr=>5 = estkh8+$B5+(VX<<8) // LDA ESTKH,X
codeptr=>7 = estkh8+$75+$0100+(VX<<8) // ADC ESTKH+1,X
codeptr=>9 = estkh8+$95+$0100+(VX<<8) // STA ESTKH+1,X
codeptr, VX = resolveX(codeptr + 11, VX + 1) // INX
fin
//
// BRLE
//
codeptr=>0 = estkl8+$B5+$0100//+(VX<<8) // LDA ESTKL+1,X
codeptr=>2 = estkl8+$D5//+(VX<<8) // CMP ESTKL,X
codeptr=>4 = estkh8+$B5+$0100//+(VX<<8) // LDA ESTKH+1,X
codeptr=>6 = estkh8+$F5//+(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 = codeptr + 17
A_IS_TOSL = FALSE
break
is $A8 // DECBRGR - FOR/NEXT SPECIFIC DEC & TEST & BRANCH
is $AA // SUBBRGE - FOR/NEXT SPECIFIC SUB & TEST & BRANCH
i++
dest = i + *(bytecode+i)
i++
if A_IS_TOSL & TOS_DIRTY
*codeptr = estkl8+$95+(VX<<8) // STA ESTKL,X
codeptr = codeptr + 2
fin
if opcode == $A8
//
// DECR
//
//puts("DECBRGE "); puti(dest)
if not A_IS_TOSL
*codeptr = estkl8+$B5+(VX<<8) // LDA ESTKL,X
codeptr = codeptr + 2
fin
codeptr->0 = $38 // SEC
codeptr=>1 = $01E9 // SBC #$01
codeptr=>3 = estkl8+$95+(VX<<8) // STA ESTKL,X
codeptr=>5 = $02B0 // BCS +2
codeptr=>7 = estkh8+$D6+(VX<<8) // DEC ESTKH,X
codeptr, VX = resolveX(codeptr + 9, VX)
else
//
// SUB
//
//puts("SUBBRGE "); puti(dest)
if A_IS_TOSL & TOS_DIRTY
*codeptr = estkl8+$95+(VX<<8) // STA ESTKL,X
codeptr = codeptr + 2
fin
codeptr=>0 = estkl8+$B5+$0100+(VX<<8) // LDA ESTKL+1,X
codeptr->2 = $38 // SEC
codeptr=>3 = estkl8+$F5+(VX<<8) // SBC ESTKL,X
codeptr=>5 = estkl8+$95+$0100+(VX<<8) // STA ESTKL+1,X
codeptr=>7 = estkh8+$B5+$0100+(VX<<8) // LDA ESTKH+1,X
codeptr=>9 = estkh8+$F5+(VX<<8) // SBC ESTKH,X
codeptr=>11 = estkh8+$95+$0100+(VX<<8) // STA ESTKH+1,X
codeptr, VX = resolveX(codeptr + 13, VX + 1) // INX
*codeptr = estkl8+$B5//+(VX<<8) // LDA ESTKL,X
codeptr = codeptr + 2
fin
//
// BRGE
//
codeptr=>0 = estkl8+$D5+$0100//+(VX<<8) // CMP ESTKL+1,X
codeptr=>2 = estkh8+$B5//+(VX<<8) // LDA ESTKH,X
codeptr=>4 = estkh8+$F5+$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 = codeptr + 15
A_IS_TOSL = FALSE
break
is $AC // BRAND - LOGICAL AND SPECIFIC BRANCH
is $AE // BROR - LOGICAL OR SPECIFIC BRANCH
i++
dest = i + *(bytecode+i)
i++
codeptr, VX = resolveX(codeptr, VX)
if not A_IS_TOSL
*codeptr = estkl8+$B5//+(VX<<8) // LDA ESTKL,X
codeptr = codeptr + 2
elsif A_IS_TOSL & TOS_DIRTY
*codeptr = estkl8+$95//+(VX<<8) // STA ESTKL,X
codeptr = codeptr + 2
fin
codeptr=>0 = estkh8+$15//+(VX<<8) // ORA ESTKH,X
if opcode == $AC
//puts("BRAND "); puti(dest)
codeptr=>2 = $03D0 // BNE +3
else
//puts("BROR "); puti(dest)
codeptr=>2 = $03F0 // BEQ +3
fin
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
is $B2 // ADDLW
i++
j = ^(bytecode+i)
if not A_IS_TOSL
*codeptr = estkl8+$B5+(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 = ifpl8+$71 // ADC (IFP),Y
if opcode == $B0
//puts("ADDLB "); puti(j)
codeptr=>3 = $0290 // BCC +2
codeptr=>5 = estkh8+$F6+(VX<<8) // INC ESTKH,X
codeptr = codeptr + 7
A_IS_TOSL = TOS_DIRTY // STA ESTKL,X
else
//puts("ADDLW "); puti(j)
codeptr=>3 = estkl8+$95+(VX<<8) // STA ESTKL,X
codeptr=>5 = estkh8+$B5+(VX<<8) // LDA ESTKH,X
codeptr->7 = $C8 // INY
codeptr=>8 = ifpl8+$71 // ADC (IFP),Y
codeptr=>10 = estkh8+$95+(VX<<8) // STA ESTKH,X
codeptr = codeptr + 12
VY++
A_IS_TOSL = FALSE
fin
break
is $B4 // ADDAB
is $B6 // ADDAW
dest = *(bytecode+i+1)
i = i + 2
if not A_IS_TOSL
*codeptr = estkl8+$B5+(VX<<8) // LDA ESTKL,X
codeptr = codeptr + 2
fin
codeptr=>0 = $6D18 // CLC; ADC abs
codeptr=>2 = dest
if opcode == $B4
//puts("ADDAB $"); puth(dest)
codeptr=>4 = $0290 // BCC +2
codeptr=>6 = estkh8+$F6+(VX<<8) // INC ESTKH,X
codeptr = codeptr + 8
A_IS_TOSL = TOS_DIRTY // STA ESTKL,X
else
//puts("ADDAW $"); puth(dest)
codeptr=>4 = estkl8+$95+(VX<<8) // STA ESTKL,X
codeptr=>6 = estkh8+$B5+(VX<<8) // LDA ESTKH,X
codeptr->8 = $6D // ADC abs
codeptr=>9 = dest+1
codeptr=>11 = estkh8+$95+(VX<<8) // STA ESTKH,X
codeptr = codeptr + 13
A_IS_TOSL = FALSE
fin
break
is $B8 // IDXLB
i++
j = ^(bytecode+i)
//puts("IDXLB "); puti(j)
if A_IS_TOSL & TOS_DIRTY
*codeptr = estkl8+$95+(VX<<8) // STA ESTKL,X
codeptr = codeptr + 2
fin
if VY <> j
*codeptr = $A0+(j<<8) // LDY #imm
codeptr = codeptr + 2
fin
*codeptr = ifpl8+$B1 // LDA (IFP),Y
codeptr = codeptr + 2
if j <> 0
*codeptr = $00A0 // LDY #$00
codeptr = codeptr + 2
fin
codeptr->0 = $0A // ASL
codeptr=>1 = $0290 // BCC +2
codeptr=>3 = $18C8 // INY; CLC
codeptr=>5 = estkl8+$75+(VX<<8) // ADC ESTKL,X
codeptr=>7 = estkl8+$95+(VX<<8) // STA ESTKL,X
codeptr->9 = $98 // TYA
codeptr=>10 = estkh8+$75+(VX<<8) // ADC ESTKH,X
codeptr=>12 = estkh8+$95+(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 = estkl8+$95+(VX<<8) // STA ESTKL,X
codeptr = codeptr + 2
fin
if VY <> j
*codeptr = $A0+(j<<8) // LDY #imm
codeptr = codeptr + 2
fin
codeptr=>0 = ifpl8+$B1 // LDA (IFP),Y
codeptr->2 = $0A // ASL
codeptr=>3 = tmpl8+$85 // STA $E7:TMPL
codeptr->5 = $C8 // INY
codeptr=>6 = ifpl8+$B1 // LDA (IFP),Y
codeptr=>8 = $A82A // ROL; TAY
codeptr=>10 = tmpl8+$A5 // LDA $E7:TMPL
codeptr->12 = $18 // CLC
codeptr=>13 = estkl8+$75+(VX<<8) // ADC ESTKL,X
codeptr=>15 = estkl8+$95+(VX<<8) // STA ESTKL,X
codeptr->17 = $98 // TYA
codeptr=>18 = estkh8+$75+(VX<<8) // ADC ESTKH,X
codeptr=>20 = estkh8+$95+(VX<<8) // STA ESTKH,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 = estkl8+$95+(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 = estkl8+$75+(VX<<8) // ADC ESTKL,X
codeptr=>10 = estkl8+$95+(VX<<8) // STA ESTKL,X
codeptr->12 = $98 // TYA
codeptr=>13 = estkh8+$75+(VX<<8) // ADC ESTKH,X
codeptr=>15 = estkh8+$95+(VX<<8) // STA ESTKH,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 = estkl8+$95+(VX<<8) // STA ESTKL,X
codeptr = codeptr + 2
fin
codeptr->0 = $AD // LDA abs
codeptr=>1 = dest
codeptr->3 = $0A // ASL
codeptr=>4 = tmpl8+$85 // STA $E7:TMPL
codeptr->6 = $AD // LDA abs+1
codeptr=>7 = dest+1
codeptr=>9 = $A82A // ROL; TAY
codeptr=>11 = tmpl8+$A5 // LDA $E7:TMPL
codeptr->13 = $18 // CLC
codeptr=>14 = estkl8+$75+(VX<<8) // ADC ESTKL,X
codeptr=>16 = estkl8+$95+(VX<<8) // STA ESTKL,X
codeptr->18 = $98 // TYA
codeptr=>19 = estkh8+$75+(VX<<8) // ADC ESTKH,X
codeptr=>21 = estkh8+$95+(VX<<8) // STA ESTKH,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
//puts("Done compiling: $"); puth(defptr=>interpaddr)
//puts("->$"); puth(*jitcodeptr); putln
//getc
return
fin
loop
//
// If we got here we ran out of code buffer space.
//
//puts("Ran out of code buffer\n")
//getc
end