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