mirror of
https://github.com/dschmenk/PLASMA.git
synced 2026-03-12 16:42:08 +00:00
1333 lines
54 KiB
Plaintext
1333 lines
54 KiB
Plaintext
//
|
|
// TOS and NOS stack offsets
|
|
//
|
|
const TOS = $01 // TOS
|
|
const NOS = $03 // TOS-1
|
|
//
|
|
// JIT compiler entry
|
|
//
|
|
def compiler(defptr)#0
|
|
word codeptr, isdata[], addrxlate, bytecode, i, case, dest
|
|
byte opcode, j, A_IS_TOS, X_IS_IFP
|
|
|
|
//puts("JIT compiler invoked for :$"); puth(defptr=>bytecodeaddr); putln
|
|
addrxlate = heapmark // heapalloc(512 + defptr->bytecodesize)
|
|
//if not addrxlate
|
|
if isult(heapavail, 512 + defptr->bytecodesize) // 256 * sizeof(word) address xlate
|
|
//
|
|
// Not enough heap available
|
|
//
|
|
//puts("Not enough free heap\n")
|
|
defptr=>interpaddr = indirectentry
|
|
return
|
|
fin
|
|
//
|
|
// Copy bytecode def from AUX to heap for compiling
|
|
//
|
|
bytecode = addrxlate + 512 // def bytecode
|
|
defcpy(bytecode, defptr)
|
|
//puts("Addr Xlate: $"); puth(addrxlate); 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_TOS = FALSE
|
|
X_IS_IFP = FALSE
|
|
codeptr->0 = $20 // JSR INTERP
|
|
codeptr=>1 = directentry
|
|
if ^bytecode == $58
|
|
//putc('$'); puth(codeptr);//puts(":[0] ENTER "); puti(^(bytecode+1)); putc(',');puti(^(bytecode+2)); putln
|
|
//
|
|
// Call into VM
|
|
//
|
|
codeptr->3 = $58 // ENTER CODE
|
|
codeptr=>4 = *(bytecode+1) // ENTER FRAME SIZE & ARG COUNT
|
|
codeptr->6 = $C0 // NATV CODE
|
|
codeptr = codeptr + 7
|
|
i = 3
|
|
else
|
|
//
|
|
// Call into VM
|
|
//
|
|
codeptr->3 = $C0 // NATV CODE
|
|
codeptr = codeptr + 4
|
|
i = 0
|
|
|
|
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
|
|
//
|
|
if A_IS_TOS
|
|
^codeptr = $48; codeptr++ // PHA
|
|
fin
|
|
A_IS_TOS = FALSE
|
|
X_IS_IFP = 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_TOS
|
|
^codeptr = $48; codeptr++ // PHA
|
|
fin
|
|
codeptr->0 = $A9 // LDA #(CN/2)
|
|
codeptr=>1 = opcode/2
|
|
codeptr = codeptr + 3
|
|
A_IS_TOS = TRUE // PHA
|
|
else
|
|
when opcode
|
|
is $20 // MINUS ONE
|
|
//puts("MINUS_ONE")
|
|
if A_IS_TOS
|
|
^codeptr = $48; codeptr++ // PHA
|
|
fin
|
|
codeptr->0 = $A9 // LDA #$FFFF
|
|
codeptr=>1 = $FFFF
|
|
codeptr = codeptr + 3
|
|
A_IS_TOS = TRUE // PHA
|
|
break
|
|
is $22 // BREQ
|
|
is $24 // BRNE
|
|
i++
|
|
dest = i + *(bytecode+i)
|
|
i++
|
|
if not A_IS_TOS
|
|
^codeptr = $68; codeptr++ // PLA
|
|
fin
|
|
codeptr=>0 = $C3+(TOS<<8) // CMP TOS,S
|
|
if opcode == $22
|
|
//puts("BREQ "); puti(dest)
|
|
codeptr=>2 = $04D0 // BNE +4
|
|
else
|
|
//puts("BRNE "); puti(dest)
|
|
codeptr=>2 = $04F0 // BEQ +4
|
|
fin
|
|
codeptr=>4 = $4C68 // PLA; JMP abs
|
|
codeptr=>6 = addrxlate=>[dest]
|
|
if not (codeptr->7 & $80) // Unresolved address list
|
|
addrxlate=>[dest] = codeptr + 6 - *jitcodeptr
|
|
fin
|
|
codeptr->8 = $68 // PLA
|
|
codeptr = codeptr + 9
|
|
A_IS_TOS = FALSE
|
|
break
|
|
is $26 // LA
|
|
is $2C // CW
|
|
dest = *(bytecode+i+1)
|
|
i = i + 2
|
|
//puts("LA/CW $"); puth(dest)
|
|
if A_IS_TOS
|
|
^codeptr = $48; codeptr++ // PHA
|
|
fin
|
|
codeptr->0 = $A9 // LDA #imm
|
|
codeptr=>1 = dest
|
|
codeptr = codeptr + 3
|
|
A_IS_TOS = TRUE // PHA
|
|
break
|
|
is $28 // LLA
|
|
i++
|
|
j = ^(bytecode+i)
|
|
//puts("LLA "); puti(^(bytecode+i))
|
|
if A_IS_TOS
|
|
^codeptr = $48; codeptr++ // PHA
|
|
fin
|
|
if not X_IS_IFP
|
|
*codeptr = $E0A6 // LDX IFP
|
|
codeptr = codeptr + 2
|
|
X_IS_IFP = TRUE
|
|
fin
|
|
^codeptr = $8A; codeptr++ // TXA
|
|
if j <> 0
|
|
codeptr=>0 = $6918 // CLC; ADC #imm
|
|
codeptr=>2 = j
|
|
codeptr = codeptr + 4
|
|
fin
|
|
A_IS_TOS = TRUE
|
|
break
|
|
is $2A // CB
|
|
is $5E // CFFB
|
|
i++
|
|
if A_IS_TOS
|
|
^codeptr = $48; codeptr++ // PHA
|
|
fin
|
|
codeptr->0 = $A9
|
|
if opcode == $2A // LDA #imm
|
|
dest = ^(bytecode+i)
|
|
//puts("CB $"); putb(dest)
|
|
else
|
|
dest = ^(bytecode+i) | $FF00
|
|
//puts("CFFB $FF"); puth(dest)
|
|
fin
|
|
codeptr=>1 = dest
|
|
codeptr = codeptr + 3
|
|
A_IS_TOS = TRUE // PHA
|
|
break
|
|
is $2E // CS
|
|
i++
|
|
j = ^(bytecode+i)
|
|
dest = codeptr + 7 + j
|
|
//puts("CS "); //puts(bytecode+i); //puts("-->"); puti(dest)
|
|
if isule(dest, codemax)
|
|
if A_IS_TOS
|
|
^codeptr = $48; codeptr++ // PHA
|
|
fin
|
|
dest = codeptr + 7 + j
|
|
codeptr->0 = $A9 // LDA #STRING
|
|
codeptr=>1 = codeptr + 6
|
|
codeptr->3 = $4C // JMP abs
|
|
codeptr=>4 = dest
|
|
strcpy(codeptr + 6, bytecode + i)
|
|
i = i + j
|
|
fin
|
|
codeptr = dest
|
|
A_IS_TOS = TRUE // PHA
|
|
break
|
|
is $32 // DROP2
|
|
//puts("DROP2")
|
|
if not A_IS_TOS
|
|
^codeptr = $68; codeptr++ // PLA
|
|
fin
|
|
A_IS_TOS = FALSE
|
|
is $30 // DROP
|
|
//puts("DROP")
|
|
if not A_IS_TOS
|
|
^codeptr = $68; codeptr++ // PLA
|
|
fin
|
|
A_IS_TOS = FALSE
|
|
break
|
|
is $34 // DUP
|
|
//puts("DUP")
|
|
if not A_IS_TOS
|
|
*codeptr = $A3+(TOS<<8) // LDA S, TOS
|
|
codeptr = codeptr + 2
|
|
else
|
|
^codeptr = $48; codeptr++ // PHA
|
|
fin
|
|
A_IS_TOS = TRUE // PHA
|
|
break
|
|
//is $36
|
|
//puts("DIVMOD")
|
|
//
|
|
// Should never happen
|
|
//
|
|
//break
|
|
is $38 // ADDI
|
|
i++
|
|
//puts("ADDI $"); putb(^(bytecode+i))
|
|
if not A_IS_TOS
|
|
^codeptr = $68; codeptr++ // PLA
|
|
fin
|
|
codeptr=>0 = $6918 // CLC; ADC #imm
|
|
codeptr=>2 = ^(bytecode+i)
|
|
codeptr = codeptr + 4
|
|
A_IS_TOS = TRUE // PHA
|
|
break
|
|
is $3A // SUBI
|
|
i++
|
|
//puts("SUBI $"); putb(^(bytecode+i))
|
|
if not A_IS_TOS
|
|
^codeptr = $68; codeptr++ // PLA
|
|
fin
|
|
codeptr=>0 = $E938 // SEC; SBC #imm
|
|
codeptr=>2 = ^(bytecode+i)
|
|
codeptr = codeptr + 4
|
|
A_IS_TOS = TRUE // PHA
|
|
break
|
|
is $3C // ANDI
|
|
i++
|
|
//puts("ANDI $"); putb(^(bytecode+i))
|
|
if not A_IS_TOS
|
|
^codeptr = $68; codeptr++ // PLA
|
|
fin
|
|
codeptr->0 = $29 // AND #imm
|
|
codeptr=>1 = ^(bytecode+i)
|
|
codeptr = codeptr + 3
|
|
A_IS_TOS = TRUE // PHA
|
|
break
|
|
is $3E // ORI
|
|
i++
|
|
//puts("ORI $"); putb(^(bytecode+i))
|
|
if not A_IS_TOS
|
|
^codeptr = $68; codeptr++ // PLA
|
|
fin
|
|
codeptr->0 = $09 // ORA #imm
|
|
codeptr=>1 = ^(bytecode+i)
|
|
codeptr = codeptr + 3
|
|
A_IS_TOS = TRUE // PHA
|
|
break
|
|
is $40 // ISEQ
|
|
is $42 // ISNE
|
|
if not A_IS_TOS
|
|
^codeptr = $68; codeptr++ // PLA
|
|
fin
|
|
codeptr->0 = $A0 // LDY #$0000
|
|
codeptr=>1 = $0000
|
|
codeptr=>3 = $C3+(TOS<<8) // CMP TOS,S
|
|
if opcode == $40
|
|
//puts("ISEQ")
|
|
codeptr=>5 = $01D0 // BNE +1
|
|
else
|
|
//puts("ISNE")
|
|
codeptr=>5 = $01F0 // BEQ +1
|
|
fin
|
|
codeptr=>7 = $9888 // DEY; TYA
|
|
codeptr->9 = $7A // PLY
|
|
codeptr = codeptr + 10
|
|
A_IS_TOS = TRUE // PHA
|
|
break
|
|
is $44 // ISGT
|
|
is $4A // ISLE
|
|
if not A_IS_TOS
|
|
^codeptr = $68; codeptr++ // PLA
|
|
fin
|
|
codeptr->0 = $A0 // LDY #$0000
|
|
codeptr=>1 = $0000
|
|
codeptr->3 = $38 // SEC
|
|
codeptr=>4 = $E3+(TOS<<8) // SBC TOS,S
|
|
codeptr=>6 = $0350 // BVC +3
|
|
codeptr->8 = $49 // EOR #$8000
|
|
codeptr=>9 = $8000
|
|
if opcode == $44
|
|
//puts("ISGT")
|
|
codeptr=>11 = $0110 // BPL +1
|
|
else
|
|
//puts("ISLE")
|
|
codeptr=>11 = $0130 // BMI +1
|
|
fin
|
|
codeptr=>13 = $9888 // DEY; TYA
|
|
codeptr->15 = $7A // PLY
|
|
codeptr = codeptr + 16
|
|
A_IS_TOS = TRUE // PHA
|
|
break
|
|
is $46 // ISLT
|
|
is $48 // ISGE
|
|
if not A_IS_TOS
|
|
^codeptr = $68; codeptr++ // PLA
|
|
fin
|
|
codeptr->0 = $A0 // LDY #$0000
|
|
codeptr=>1 = $0000
|
|
codeptr=>3 = $E785 // STA TMP
|
|
codeptr=>5 = $3868 // PLA; SEC
|
|
codeptr=>7 = $E7E5 // SBC TMP
|
|
codeptr=>9 = $0350 // BVC +3
|
|
codeptr->11 = $49 // EOR #$8000
|
|
codeptr=>12 = $8000
|
|
if opcode == $46
|
|
//puts("ISLT")
|
|
codeptr=>14 = $0110 // BPL +1
|
|
else
|
|
//puts("ISGE")
|
|
codeptr=>14 = $0130 // BMI +1
|
|
fin
|
|
codeptr=>16 = $9888 // DEY; TYA
|
|
codeptr = codeptr + 18
|
|
A_IS_TOS = TRUE // PHA
|
|
break
|
|
is $4C // BRFLS
|
|
is $4E // BRTRU
|
|
i++
|
|
dest = i + *(bytecode+i)
|
|
i++
|
|
if not A_IS_TOS
|
|
codeptr->0 = $68 // PLA
|
|
else
|
|
codeptr->0 = $A8 // TAY
|
|
fin
|
|
if opcode == $4C
|
|
//puts("BRFLS "); puti(dest)
|
|
codeptr=>1 = $03D0 // BNE +3
|
|
else
|
|
//puts("BRTRU "); puti(dest)
|
|
codeptr=>1 = $03F0 // BEQ +3
|
|
fin
|
|
codeptr->3 = $4C // JMP abs
|
|
codeptr=>4 = addrxlate=>[dest]
|
|
if not (codeptr->5 & $80) // Unresolved address list
|
|
addrxlate=>[dest] = codeptr + 4 - *jitcodeptr
|
|
fin
|
|
codeptr = codeptr + 6
|
|
A_IS_TOS = FALSE
|
|
break
|
|
is $50 // BRNCH
|
|
i++
|
|
dest = i + *(bytecode+i)
|
|
i++
|
|
//puts("BRNCH "); puti(dest)
|
|
if A_IS_TOS
|
|
^codeptr = $48; codeptr++ // PHA
|
|
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_TOS = 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_TOS
|
|
codeptr->0 = $68; codeptr++ // PLA
|
|
fin
|
|
repeat
|
|
dest = *(bytecode+case)
|
|
//puts(" $"); puth(dest)
|
|
codeptr->0 = $C9 // CMP #imm
|
|
codeptr=>1 = dest
|
|
codeptr=>3 = $03D0 // BNE +3
|
|
*(bytecode+case) = $FEFE
|
|
case = case + 2
|
|
dest = case + *(bytecode+case)
|
|
//puts("-->"); puti(dest); putln
|
|
codeptr->5 = $4C // JMP abs
|
|
codeptr=>6 = addrxlate=>[dest]
|
|
if not (codeptr->7 & $80) // Unresolved address list
|
|
addrxlate=>[dest] = codeptr + 6 - *jitcodeptr
|
|
fin
|
|
codeptr = codeptr + 8
|
|
*(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
|
|
A_IS_TOS = FALSE
|
|
break
|
|
is $54 // CALL
|
|
is $56 // ICAL
|
|
is $5A // LEAVE
|
|
is $5C // RET
|
|
if A_IS_TOS
|
|
^codeptr = $48; codeptr++ // PHA
|
|
fin
|
|
codeptr=>0 = $10E2 // SEP #$10 -> 8 BIT X/Y
|
|
codeptr->2 = $A9 // LDA #imm
|
|
codeptr=>3 = codeptr + 12
|
|
codeptr=>5 = $F285 // STA IP
|
|
codeptr=>7 = $00A0 // LDY #$00
|
|
codeptr->9 = $4C // JMP FETCHOP
|
|
codeptr=>10 = $00F1 // FETCHOP
|
|
codeptr->12 = opcode // OP
|
|
when opcode
|
|
is $54 // CALL
|
|
//
|
|
// Call address
|
|
//
|
|
//puts("CALL $"); puth(*(bytecode+i))
|
|
codeptr=>13 = *(bytecode+i+1) // CALL ADDR
|
|
codeptr->15 = $C0 // NATV
|
|
codeptr = codeptr + 16
|
|
i = i + 2
|
|
break
|
|
is $56 // ICAL
|
|
//
|
|
// Call address off stack
|
|
//
|
|
//puts("ICAL")
|
|
codeptr->13 = $C0 // NATV
|
|
codeptr = codeptr + 14
|
|
break
|
|
is $5A // LEAVE
|
|
//
|
|
// Leave routine
|
|
//
|
|
i++
|
|
//puts("LEAVE "); puti(^(bytecode+i))
|
|
codeptr->13 = ^(bytecode+i) // LEAVE CODE OPERAND
|
|
codeptr = codeptr + 14
|
|
break
|
|
is $5C // RET
|
|
//
|
|
// Quick return from routine
|
|
//
|
|
//puts("RET")
|
|
codeptr = codeptr + 13
|
|
break
|
|
wend
|
|
X_IS_IFP = FALSE
|
|
A_IS_TOS = FALSE
|
|
break
|
|
is $60 // LB
|
|
//puts("LB")
|
|
if not A_IS_TOS
|
|
^codeptr = $68; codeptr++ // PLA
|
|
fin
|
|
codeptr=>0 = $E785 // STA TMP
|
|
codeptr=>2 = $20E2 // SEP #$20 -> 8 BIT ACCUM/MEM
|
|
codeptr=>4 = $E7B2 // LDA (TMP)
|
|
codeptr=>6 = $20C2 // REP #$20 -> 16 BIT ACCUM/MEM
|
|
codeptr->8 = $29 // AND #$00FF
|
|
codeptr=>9 = $00FF
|
|
codeptr = codeptr + 11
|
|
A_IS_TOS = TRUE // PHA
|
|
break
|
|
is $62 // LW
|
|
//puts("LW")
|
|
if not A_IS_TOS
|
|
^codeptr = $68; codeptr++ // PLA
|
|
fin
|
|
codeptr=>0 = $E785 // STA TMP
|
|
codeptr=>2 = $E7B2 // LDA (TMP)
|
|
codeptr = codeptr + 4
|
|
A_IS_TOS = TRUE // PHA
|
|
break
|
|
is $64 // LLB
|
|
i++
|
|
j = ^(bytecode+i)
|
|
//puts("LLB "); puti(j)
|
|
if A_IS_TOS
|
|
^codeptr = $48; codeptr++ // PHA
|
|
fin
|
|
if not X_IS_IFP
|
|
*codeptr = $E0A6 // LDX IFP
|
|
codeptr = codeptr + 2
|
|
X_IS_IFP = TRUE
|
|
fin
|
|
codeptr=>0 = $B5+(j<<8) // LDA dp,X
|
|
codeptr->2 = $29 // AND #$00FF
|
|
codeptr=>3 = $00FF
|
|
codeptr = codeptr + 5
|
|
A_IS_TOS = TRUE // PHA
|
|
break
|
|
is $66 // LLW
|
|
i++
|
|
j = ^(bytecode+i)
|
|
//puts("LLW "); puti(j)
|
|
if A_IS_TOS
|
|
^codeptr = $48; codeptr++ // PHA
|
|
fin
|
|
if not X_IS_IFP
|
|
*codeptr = $E0A6 // LDX IFP
|
|
codeptr = codeptr + 2
|
|
X_IS_IFP = TRUE
|
|
fin
|
|
codeptr=>0 = $B5+(j<<8) // LDA dp,X
|
|
codeptr = codeptr + 2
|
|
A_IS_TOS = TRUE // PHA
|
|
break
|
|
is $68 // LAB
|
|
dest = *(bytecode+i+1)
|
|
i = i + 2
|
|
//puts("LAB $"); puth(dest)
|
|
if A_IS_TOS
|
|
^codeptr = $48; codeptr++ // PHA
|
|
fin
|
|
if is_hwaddr(dest)
|
|
//
|
|
// Ensure we only do byte sized accesses to H/W
|
|
//
|
|
codeptr=>0 = $20E2 // SEP #$20 -> 8 BIT ACCUM/MEM
|
|
codeptr->2 = $AD // LDA abs
|
|
codeptr=>3 = dest
|
|
codeptr=>5 = $20C2 // REP #$20 -> 16 BIT ACCUM/MEM
|
|
codeptr->7 = $29 // AND #$00FF
|
|
codeptr=>8 = $00FF
|
|
codeptr = codeptr + 10
|
|
else
|
|
codeptr->0 = $AD // LDA abs
|
|
codeptr=>1 = dest
|
|
codeptr->3 = $29 // AND #$00FF
|
|
codeptr=>4 = $00FF
|
|
codeptr = codeptr + 6
|
|
fin
|
|
A_IS_TOS = TRUE // PHA
|
|
break
|
|
is $6A // LAW
|
|
dest = *(bytecode+i+1)
|
|
i = i + 2
|
|
//puts("LAW $"); puth(dest)
|
|
if A_IS_TOS
|
|
^codeptr = $48; codeptr++ // PHA
|
|
fin
|
|
codeptr->0 = $AD // LDA abs
|
|
codeptr=>1 = dest
|
|
codeptr = codeptr + 3
|
|
A_IS_TOS = TRUE // PHA
|
|
break
|
|
is $6C // DLB
|
|
is $74 // SLB
|
|
i++
|
|
j = ^(bytecode+i)
|
|
if not A_IS_TOS
|
|
^codeptr = $68; codeptr++ // PLA
|
|
fin
|
|
if not X_IS_IFP
|
|
*codeptr = $E0A6 // LDX IFP
|
|
codeptr = codeptr + 2
|
|
X_IS_IFP = TRUE
|
|
fin
|
|
codeptr=>0 = $20E2 // SEP #$20 -> 8 BIT ACCUM/MEM
|
|
codeptr=>2 = $95+(j<<8) // STA dp,X
|
|
codeptr=>4 = $20C2 // REP #$20 -> 16 BIT ACCUM/MEM
|
|
if opcode == $6C
|
|
//puts("DLB "); puti(j)
|
|
codeptr->6 = $29 // AND #$00FF
|
|
codeptr=>7 = $00FF
|
|
codeptr = codeptr + 9
|
|
A_IS_TOS = TRUE // PHA
|
|
else
|
|
//puts("SLB "); puti(j)
|
|
codeptr = codeptr + 6
|
|
A_IS_TOS = FALSE
|
|
fin
|
|
break
|
|
is $6E // DLW
|
|
is $76 // SLW
|
|
i++
|
|
j = ^(bytecode+i)
|
|
if not A_IS_TOS
|
|
^codeptr = $68; codeptr++ // PLA
|
|
fin
|
|
if not X_IS_IFP
|
|
*codeptr = $E0A6 // LDX IFP
|
|
codeptr = codeptr + 2
|
|
X_IS_IFP = TRUE
|
|
fin
|
|
codeptr=>0 = $95+(j<<8) // STA dp,X
|
|
codeptr = codeptr + 2
|
|
if opcode == $6E
|
|
//puts("DLW "); puti(j)
|
|
A_IS_TOS = TRUE // PHA
|
|
else
|
|
//puts("SLW "); puti(j)
|
|
A_IS_TOS = FALSE
|
|
fin
|
|
break
|
|
is $70 // SB
|
|
//puts("SB")
|
|
if not A_IS_TOS
|
|
^codeptr = $68; codeptr++ // PLA
|
|
fin
|
|
codeptr=>0 = $E785 // STA TMP
|
|
codeptr->2 = $68 // PLA
|
|
codeptr=>3 = $20E2 // SEP #$20 -> 8 BIT ACCUM/MEM
|
|
codeptr=>5 = $E792 // STA (TMP)
|
|
codeptr=>7 = $20C2 // REP #$20 -> 16 BIT ACCUM/MEM
|
|
codeptr = codeptr + 9
|
|
A_IS_TOS = FALSE
|
|
break
|
|
is $72 // SW
|
|
//puts("SW")
|
|
if not A_IS_TOS
|
|
^codeptr = $68; codeptr++ // PLA
|
|
fin
|
|
codeptr=>0 = $E785 // STA TMP
|
|
codeptr->2 = $68 // PLA
|
|
codeptr=>3 = $E792 // STA (TMP)
|
|
codeptr = codeptr + 5
|
|
A_IS_TOS = FALSE
|
|
break
|
|
is $78 // SAB
|
|
is $7C // DAB
|
|
dest = *(bytecode+i+1)
|
|
i = i + 2
|
|
if not A_IS_TOS
|
|
^codeptr = $68; codeptr++ // PLA
|
|
fin
|
|
codeptr=>0 = $20E2 // SEP #$20 -> 8 BIT ACCUM/MEM
|
|
codeptr->2 = $8D // STA abs
|
|
codeptr=>3 = dest
|
|
codeptr=>5 = $20C2 // REP #$20 -> 16 BIT ACCUM/MEM
|
|
if opcode == $78
|
|
//puts("SAB $"); puth(*(bytecode+i))
|
|
codeptr = codeptr + 7
|
|
A_IS_TOS = FALSE
|
|
else
|
|
//puts("DAB $"); puth(*(bytecode+i))
|
|
codeptr->7 = $29 // AND #$00FF
|
|
codeptr=>8 = $00FF
|
|
codeptr = codeptr + 10
|
|
A_IS_TOS = TRUE
|
|
fin
|
|
break
|
|
is $7A // SAW
|
|
is $7E // DAW
|
|
dest = *(bytecode+i+1)
|
|
i = i + 2
|
|
if not A_IS_TOS
|
|
^codeptr = $68; codeptr++ // PLA
|
|
fin
|
|
codeptr->0 = $8D // STA abs
|
|
codeptr=>1 = dest
|
|
codeptr = codeptr + 3
|
|
if opcode == $7A
|
|
//puts("SAW $"); puth(dest)
|
|
A_IS_TOS = FALSE
|
|
else
|
|
//puts("DAW $"); puth(*(bytecode+i))
|
|
A_IS_TOS = TRUE
|
|
fin
|
|
break
|
|
is $80 // NOT
|
|
//puts("NOT")
|
|
if not A_IS_TOS
|
|
codeptr->0 = $68 // PLA
|
|
else
|
|
codeptr->0 = $A8 // TAY
|
|
fin
|
|
codeptr=>1 = $03F0 // BEQ +3
|
|
codeptr->3 = $A9 // LDA #$FFFF
|
|
codeptr=>4 = $FFFF
|
|
codeptr->6 = $49 // EOR #$FFFF
|
|
codeptr=>7 = $FFFF
|
|
codeptr = codeptr + 9
|
|
A_IS_TOS = TRUE
|
|
break
|
|
is $82 // ADD
|
|
//puts("ADD")
|
|
if not A_IS_TOS
|
|
^codeptr = $68; codeptr++ // PLA
|
|
fin
|
|
codeptr->0 = $18 // CLC
|
|
codeptr=>1 = $63+(TOS<<8) // ADC S,TOS
|
|
codeptr->3 = $7A // PLY
|
|
codeptr = codeptr + 4
|
|
A_IS_TOS = TRUE
|
|
break
|
|
is $84 // SUB
|
|
//puts("SUB")
|
|
if not A_IS_TOS
|
|
^codeptr = $68; codeptr++ // PLA
|
|
fin
|
|
codeptr=>0 = $E785 // STA TMP
|
|
codeptr=>2 = $3868 // PLA; SEC
|
|
codeptr=>4 = $E7E5 // SBC TMP
|
|
codeptr = codeptr + 6
|
|
A_IS_TOS = TRUE
|
|
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
|
|
//
|
|
if A_IS_TOS
|
|
^codeptr = $48; codeptr++ // PHA
|
|
fin
|
|
codeptr=>0 = $10E2 // SEP #$10 -> 8 BIT X/Y
|
|
codeptr->2 = $A9 // LDA #imm
|
|
codeptr=>3 = codeptr + 12
|
|
codeptr=>5 = $F285 // STA IP
|
|
codeptr=>7 = $00A0 // LDY #$00
|
|
codeptr->9 = $4C // JMP FETCHOP
|
|
codeptr=>10 = $00F1 // FETCHOP
|
|
codeptr=>12 = $C000+opcode // OPCODE; NATV CODE
|
|
codeptr = codeptr + 14
|
|
X_IS_IFP = FALSE
|
|
A_IS_TOS = FALSE
|
|
break
|
|
is $8C // INCR
|
|
//puts("INCR")
|
|
if not A_IS_TOS
|
|
^codeptr = $68; codeptr++ // PLA
|
|
fin
|
|
^codeptr = $1A; codeptr++ // INC A
|
|
A_IS_TOS = TRUE // PHA
|
|
break
|
|
is $8E // DECR
|
|
//puts("DECR")
|
|
if not A_IS_TOS
|
|
^codeptr = $68; codeptr++ // PLA
|
|
fin
|
|
^codeptr = $3A; codeptr++ // DEC A
|
|
A_IS_TOS = TRUE // PHA
|
|
break
|
|
is $90 // NEG
|
|
//puts("NEG")
|
|
if not A_IS_TOS
|
|
^codeptr = $68; codeptr++ // PLA
|
|
fin
|
|
codeptr->0 = $49 // EOR #$FFFF
|
|
codeptr=>1 = $FFFF
|
|
codeptr->3 = $1A // INC A
|
|
codeptr = codeptr + 4
|
|
A_IS_TOS = TRUE
|
|
break
|
|
is $92 // COMP
|
|
//puts("COMP")
|
|
if not A_IS_TOS
|
|
^codeptr = $68; codeptr++ // PLA
|
|
fin
|
|
codeptr->0 = $49 // EOR #$FFFF
|
|
codeptr=>1 = $FFFF
|
|
codeptr = codeptr + 3
|
|
A_IS_TOS = TRUE
|
|
break
|
|
is $94 // AND
|
|
//puts("AND")
|
|
if not A_IS_TOS
|
|
^codeptr = $68; codeptr++ // PLA
|
|
fin
|
|
codeptr=>0 = $23+(TOS<<8) // AND S,TOS
|
|
codeptr->2 = $7A // PLY
|
|
codeptr = codeptr + 3
|
|
A_IS_TOS = TRUE
|
|
break
|
|
is $96 // OR
|
|
//puts("OR")
|
|
if not A_IS_TOS
|
|
^codeptr = $68; codeptr++ // PLA
|
|
fin
|
|
codeptr=>0 = $03+(TOS<<8) // OR S,TOS
|
|
codeptr->2 = $7A // PLY
|
|
codeptr = codeptr + 3
|
|
A_IS_TOS = TRUE
|
|
break
|
|
is $98 // XOR
|
|
//puts("XOR")
|
|
if not A_IS_TOS
|
|
^codeptr = $68; codeptr++ // PLA
|
|
fin
|
|
codeptr=>0 = $43+(TOS<<8) // EOR S,TOS
|
|
codeptr->2 = $7A // PLY
|
|
codeptr = codeptr + 3
|
|
A_IS_TOS = TRUE
|
|
break
|
|
is $9E // IDXW
|
|
//puts("IDXW")
|
|
if not A_IS_TOS
|
|
^codeptr = $68; codeptr++ // PLA
|
|
fin
|
|
codeptr=>0 = $180A // ASL; CLC
|
|
codeptr=>2 = $63+(TOS<<8) // ADC S,TOS
|
|
codeptr->4 = $7A // PLY
|
|
codeptr = codeptr + 5
|
|
A_IS_TOS = TRUE
|
|
break
|
|
is $A0 // BRGT - FOR/NEXT SPECIFIC TEST & BRANCH
|
|
i++
|
|
dest = i + *(bytecode+i)
|
|
i++
|
|
//puts("BRGT "); puti(dest)
|
|
if A_IS_TOS
|
|
^codeptr = $48; codeptr++ // PHA
|
|
fin
|
|
codeptr=>0 = $A3+(NOS<<8) // LDA S,NOS
|
|
codeptr->2 = $38 // SEC
|
|
codeptr=>3 = $E3+(TOS<<8) // SBC S,TOS
|
|
codeptr=>5 = $0350 // BVC +3
|
|
codeptr->7 = $49 // EOR #$8000
|
|
codeptr=>8 = $8000
|
|
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_TOS = FALSE
|
|
break
|
|
is $A2 // BRLT - FOR/NEXT SPECIFIC TEST & BRANCH
|
|
i++
|
|
dest = i + *(bytecode+i)
|
|
i++
|
|
//puts("BRLT "); puti(dest)
|
|
if A_IS_TOS
|
|
^codeptr = $48; codeptr++ // PHA
|
|
fin
|
|
codeptr->0 = $38 // SEC
|
|
codeptr=>1 = $E3+(NOS<<8) // SBC S,NOS
|
|
codeptr=>3 = $0350 // BVC +3
|
|
codeptr->5 = $49 // EOR #$8000
|
|
codeptr=>6 = $8000
|
|
codeptr=>8 = $0310 // BPL +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_TOS = 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_TOS
|
|
^codeptr = $68; codeptr++ // PLA
|
|
fin
|
|
if opcode == $A4
|
|
//
|
|
// INCR
|
|
//
|
|
//puts("INCBRLE "); puti(dest)
|
|
codeptr=>0 = $481A // INC A; PHA
|
|
codeptr = codeptr + 2
|
|
else
|
|
//
|
|
// ADD
|
|
//
|
|
//puts("ADDBRLE "); puti(dest)
|
|
codeptr->0 = $18 // CLC
|
|
codeptr=>1 = $63+(TOS<<8) // ADC S,TOS
|
|
codeptr=>3 = $83+(TOS<<8) // STA S,TOS
|
|
codeptr = codeptr + 5
|
|
fin
|
|
//
|
|
// BRLE
|
|
//
|
|
codeptr=>0 = $A3+(NOS<<8) // LDA S,NOS
|
|
codeptr->2 = $38 // SEC
|
|
codeptr=>3 = $E3+(TOS<<8) // SBC S,TOS
|
|
codeptr=>5 = $0350 // BVC +3
|
|
codeptr->7 = $49 // EOR #$8000
|
|
codeptr=>8 = $8000
|
|
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_TOS = 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 not A_IS_TOS
|
|
^codeptr = $68; codeptr++ // PLA
|
|
fin
|
|
if opcode == $A8
|
|
//
|
|
// DECR
|
|
//
|
|
//puts("DECBRGE "); puti(dest)
|
|
codeptr=>0 = $483A // DEC A; PHA
|
|
codeptr = codeptr + 2
|
|
else
|
|
//
|
|
// SUB
|
|
//
|
|
//puts("SUBBRGE "); puti(dest)
|
|
codeptr=>0 = $E785 // STA TMP
|
|
codeptr=>2 = $A3+(TOS<<8) // LDA S,TOS
|
|
codeptr->4 = $68 // SEC
|
|
codeptr=>5 = $E7E5 // SBC TMP
|
|
codeptr=>7 = $83+(TOS<<8) // STA S,TOS
|
|
codeptr = codeptr + 9
|
|
fin
|
|
//
|
|
// BRGE
|
|
//
|
|
codeptr->0 = $38 // SEC
|
|
codeptr=>1 = $E3+(NOS<<8) // SBC S,NOS
|
|
codeptr=>3 = $0350 // BVC +3
|
|
codeptr->5 = $49 // EOR #$8000
|
|
codeptr=>6 = $8000
|
|
codeptr=>8 = $0330 // BMI +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_TOS = FALSE
|
|
break
|
|
is $AC // BRAND - LOGICAL AND SPECIFIC BRANCH
|
|
is $AE // BROR - LOGICAL OR SPECIFIC BRANCH
|
|
i++
|
|
dest = i + *(bytecode+i)
|
|
i++
|
|
if not A_IS_TOS
|
|
codeptr->0 = $68 // PLA
|
|
else
|
|
codeptr->0 = $A8 // TAY
|
|
fin
|
|
if opcode == $AC
|
|
//puts("BRAND "); puti(dest)
|
|
codeptr=>1 = $04D0 // BNE +4
|
|
else
|
|
//puts("BROR "); puti(dest)
|
|
codeptr=>1 = $04F0 // BEQ +4
|
|
fin
|
|
codeptr=>3 = $4C48 // PHA; 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_TOS = FALSE
|
|
break
|
|
is $B0 // ADDLB
|
|
//puts("ADDLB "); puti(j)
|
|
i++
|
|
j = ^(bytecode+i)
|
|
if not A_IS_TOS
|
|
^codeptr = $68; codeptr++ // PLA
|
|
fin
|
|
if not X_IS_IFP
|
|
*codeptr = $E0A6 // LDX IFP
|
|
codeptr = codeptr + 2
|
|
X_IS_IFP = TRUE
|
|
fin
|
|
codeptr=>0 = $E785 // STA TMP
|
|
codeptr=>2 = $B5+(j<<8) // LDA dp,X
|
|
codeptr->4 = $29 // AND #$00FF
|
|
codeptr=>5 = $00FF
|
|
codeptr->7 = $18 // CLC
|
|
codeptr=>8 = $E765 // ADC TMP
|
|
codeptr = codeptr + 10
|
|
A_IS_TOS = TRUE // PHA
|
|
break
|
|
is $B2 // ADDLW
|
|
i++
|
|
j = ^(bytecode+i)
|
|
//puts("ADDLW "); puti(j)
|
|
if not A_IS_TOS
|
|
^codeptr = $68; codeptr++ // PLA
|
|
fin
|
|
if not X_IS_IFP
|
|
*codeptr = $E0A6 // LDX IFP
|
|
codeptr = codeptr + 2
|
|
X_IS_IFP = TRUE
|
|
fin
|
|
codeptr->0 = $18 // CLC
|
|
codeptr=>1 = $75+(j<<8) // ADC dp,X
|
|
codeptr = codeptr + 3
|
|
A_IS_TOS = TRUE // PHA
|
|
break
|
|
is $B4 // ADDAB
|
|
dest = *(bytecode+i+1)
|
|
i = i + 2
|
|
//puts("ADDAB $"); puth(dest)
|
|
if not A_IS_TOS
|
|
^codeptr = $68; codeptr++ // PLA
|
|
fin
|
|
if is_hwaddr(dest)
|
|
//
|
|
// Ensure only byte sized accesses to H/W addresses
|
|
//
|
|
codeptr=>0 = $E785 // STA TMP
|
|
codeptr=>2 = $20E2 // SEP #$20 -> 8 BIT ACCUM/MEM
|
|
codeptr->4 = $AD // LDA abs
|
|
codeptr=>5 = dest
|
|
codeptr=>7 = $20C2 // REP #$20 -> 16 BIT ACCUM/MEM
|
|
codeptr->9 = $29 // AND #$00FF
|
|
codeptr=>10 = $00FF
|
|
codeptr->12 = $18 // CLC
|
|
codeptr=>13 = $E765 // ADC TMP
|
|
codeptr = codeptr + 15
|
|
else
|
|
codeptr=>0 = $E785 // STA TMP
|
|
codeptr->2 = $AD // LDA abs
|
|
codeptr=>3 = dest
|
|
codeptr->5 = $29 // AND #$00FF
|
|
codeptr=>6 = $00FF
|
|
codeptr->8 = $18 // CLC
|
|
codeptr=>9 = $E765 // ADC TMP
|
|
codeptr = codeptr + 11
|
|
fin
|
|
A_IS_TOS = TRUE // PHA
|
|
break
|
|
is $B6 // ADDAW
|
|
dest = *(bytecode+i+1)
|
|
i = i + 2
|
|
if not A_IS_TOS
|
|
^codeptr = $68; codeptr++ // PLA
|
|
fin
|
|
codeptr=>0 = $6D18 // CLC; ADC abs
|
|
codeptr=>2 = dest
|
|
codeptr = codeptr + 4
|
|
A_IS_TOS = TRUE // PHA
|
|
break
|
|
is $B8 // IDXLB
|
|
i++
|
|
j = ^(bytecode+i)
|
|
//puts("IDXLB "); puti(j)
|
|
if not A_IS_TOS
|
|
^codeptr = $68; codeptr++ // PLA
|
|
fin
|
|
if not X_IS_IFP
|
|
*codeptr = $E0A6 // LDX IFP
|
|
codeptr = codeptr + 2
|
|
X_IS_IFP = TRUE
|
|
fin
|
|
codeptr=>0 = $E785 // STA TMP
|
|
codeptr=>2 = $B5+(j<<8) // LDA dp,X
|
|
codeptr->4 = $29 // AND #$00FF
|
|
codeptr=>5 = $00FF
|
|
codeptr->7 = $0A // ASL
|
|
codeptr=>8 = $E765 // ADC TMP
|
|
codeptr = codeptr + 10
|
|
A_IS_TOS = TRUE // PHA
|
|
break
|
|
is $BA // IDXLW
|
|
i++
|
|
j = ^(bytecode+i)
|
|
//puts("IDXLW "); puti(j)
|
|
if not A_IS_TOS
|
|
^codeptr = $68; codeptr++ // PLA
|
|
fin
|
|
if not X_IS_IFP
|
|
*codeptr = $E0A6 // LDX IFP
|
|
codeptr = codeptr + 2
|
|
X_IS_IFP = TRUE
|
|
fin
|
|
codeptr->0 = $18 // CLC
|
|
codeptr=>1 = $75+(j<<8) // ADC dp,X
|
|
codeptr->3 = $18 // CLC
|
|
codeptr=>4 = $75+(j<<8) // ADC dp,X
|
|
codeptr = codeptr + 6
|
|
A_IS_TOS = TRUE // PHA
|
|
break
|
|
is $BC // IDXAB
|
|
dest = *(bytecode+i+1)
|
|
i = i + 2
|
|
//puts("IDXAB $"); puth(*(bytecode+i))
|
|
if not A_IS_TOS
|
|
^codeptr = $68; codeptr++ // PLA
|
|
fin
|
|
if is_hwaddr(dest)
|
|
//
|
|
// Ensure only byte sized accesses to H/W addresses
|
|
//
|
|
codeptr=>0 = $E785 // STA TMP
|
|
codeptr=>2 = $20E2 // SEP #$20 -> 8 BIT ACCUM/MEM
|
|
codeptr->4 = $AD // LDA abs
|
|
codeptr=>5 = dest
|
|
codeptr=>7 = $20C2 // REP #$20 -> 16 BIT ACCUM/MEM
|
|
codeptr->9 = $29 // AND #$00FF
|
|
codeptr=>10 = $00FF
|
|
codeptr->12 = $0A // ASL
|
|
codeptr=>13 = $E765 // ADC TMP
|
|
codeptr = codeptr + 15
|
|
else
|
|
codeptr=>0 = $E785 // STA TMP
|
|
codeptr->2 = $AD // LDA abs
|
|
codeptr=>3 = dest
|
|
codeptr->5 = $29 // AND #$00FF
|
|
codeptr=>6 = $00FF
|
|
codeptr->8 = $0A // ASL
|
|
codeptr=>9 = $E765 // ADC TMP
|
|
codeptr = codeptr + 11
|
|
fin
|
|
A_IS_TOS = TRUE // PHA
|
|
break
|
|
is $BE // IDXAW
|
|
dest = *(bytecode+i+1)
|
|
i = i + 2
|
|
//puts("IDXAW $"); puth(dest)
|
|
if not A_IS_TOS
|
|
^codeptr = $68; codeptr++ // PLA
|
|
fin
|
|
codeptr=>0 = $6D18 // CLC; ADC abs
|
|
codeptr=>2 = dest
|
|
codeptr=>4 = $6D18 // CLC; ADC abs
|
|
codeptr=>6 = dest
|
|
codeptr = codeptr + 8
|
|
A_IS_TOS = TRUE // PHA
|
|
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
|
|
loop
|
|
//
|
|
// If we got here. we ran out of code buffer space. Overwrite interpreter
|
|
// entrypoint with standard bytecode interpreter
|
|
//
|
|
defptr=>interpaddr = indirectentry
|
|
//
|
|
// Free working bufffers
|
|
//
|
|
//heaprelease(addrxlate)
|
|
//puts("Ran out of code buffer\n")
|
|
//getc
|
|
end
|