mirror of
https://github.com/dschmenk/PLASMA.git
synced 2026-03-12 01:41:40 +00:00
1549 lines
70 KiB
Plaintext
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
|