From 40c3dcd1972e9060bf70b8ed028c9b00932b0fb9 Mon Sep 17 00:00:00 2001 From: Dave Schmenk Date: Fri, 2 Mar 2018 21:43:09 -0800 Subject: [PATCH 001/147] Better FOR/NEXT ops --- src/toolsrc/codegen.c | 43 ++++++--- src/toolsrc/codegen.h | 5 +- src/toolsrc/codegen.pla | 28 +++++- src/toolsrc/codeopt.pla | 2 +- src/toolsrc/parse.c | 84 ++++++++++++----- src/toolsrc/parse.pla | 80 +++++++++++----- src/toolsrc/plasm.pla | 1 + src/vmsrc/apple/plvm02.s | 191 +++++++++++++++++++++++---------------- 8 files changed, 292 insertions(+), 142 deletions(-) diff --git a/src/toolsrc/codegen.c b/src/toolsrc/codegen.c index 1ceb4f6..1acbbb7 100755 --- a/src/toolsrc/codegen.c +++ b/src/toolsrc/codegen.c @@ -769,12 +769,12 @@ void emit_brnch(int tag) printf("\t%s\t$50\t\t\t; BRNCH\t_B%03d\n", DB, tag); printf("\t%s\t_B%03d-*\n", DW, tag); } -void emit_breq(int tag) -{ - emit_pending_seq(); - printf("\t%s\t$3C\t\t\t; BREQ\t_B%03d\n", DB, tag); - printf("\t%s\t_B%03d-*\n", DW, tag); -} +//void emit_breq(int tag) +//{ +// emit_pending_seq(); +// printf("\t%s\t$3C\t\t\t; BREQ\t_B%03d\n", DB, tag); +// printf("\t%s\t_B%03d-*\n", DW, tag); +//} void emit_brne(int tag) { emit_pending_seq(); @@ -793,6 +793,30 @@ void emit_brlt(int tag) printf("\t%s\t$3A\t\t\t; BRLT\t_B%03d\n", DB, tag); printf("\t%s\t_B%03d-*\n", DW, tag); } +void emit_nxtup(int tag) +{ + emit_pending_seq(); + printf("\t%s\t$32\t\t\t; NXTUP\t_B%03d\n", DB, tag); + printf("\t%s\t_B%03d-*\n", DW, tag); +} +void emit_inxtup(int tag) +{ + emit_pending_seq(); + printf("\t%s\t$34\t\t\t; INXTUP\t_B%03d\n", DB, tag); + printf("\t%s\t_B%03d-*\n", DW, tag); +} +void emit_nxtdn(int tag) +{ + emit_pending_seq(); + printf("\t%s\t$3C\t\t\t; NXTDN\t_B%03d\n", DB, tag); + printf("\t%s\t_B%03d-*\n", DW, tag); +} +void emit_dnxtdn(int tag) +{ + emit_pending_seq(); + printf("\t%s\t$52\t\t\t; DNXTDN\t_B%03d\n", DB, tag); + printf("\t%s\t_B%03d-*\n", DW, tag); +} void emit_call(int tag, int type) { if (type == CONST_TYPE) @@ -841,10 +865,6 @@ void emit_drop(void) emit_pending_seq(); printf("\t%s\t$30\t\t\t; DROP\n", DB); } -void emit_dup(void) -{ - printf("\t%s\t$32\t\t\t; DUP\n", DB); -} int emit_unaryop(t_token op) { emit_pending_seq(); @@ -1656,9 +1676,6 @@ int emit_pending_seq() case DROP_CODE: emit_drop(); break; - case DUP_CODE: - emit_dup(); - break; case BRNCH_CODE: emit_brnch(op->tag); break; diff --git a/src/toolsrc/codegen.h b/src/toolsrc/codegen.h index 243b751..86679b6 100755 --- a/src/toolsrc/codegen.h +++ b/src/toolsrc/codegen.h @@ -132,9 +132,12 @@ void emit_brgt(int tag); void emit_brlt(int tag); void emit_brne(int tag); void emit_brnch(int tag); +void emit_nxtup(int tag); +void emit_inxtup(int tag); +void emit_nxtdn(int tag); +void emit_dnxtdn(int tag); void emit_empty(void); void emit_drop(void); -void emit_dup(void); void emit_leave(void); void emit_ret(void); void emit_enter(int cparams); diff --git a/src/toolsrc/codegen.pla b/src/toolsrc/codegen.pla index 299fd2c..fb38ec5 100644 --- a/src/toolsrc/codegen.pla +++ b/src/toolsrc/codegen.pla @@ -171,6 +171,16 @@ def emit_daw(tag, offset)#0 emit_byte($7E) emit_addr(tag, offset) end +def emit_brne(tag)#0 + emit_pending_seq + emit_byte($3E) + emit_reladdr(tag) +end +def emit_branch(tag)#0 + emit_pending_seq + emit_byte($50) + emit_reladdr(tag) +end def emit_brgt(tag)#0 emit_pending_seq emit_byte($38) @@ -181,14 +191,24 @@ def emit_brlt(tag)#0 emit_byte($3A) emit_reladdr(tag) end -def emit_brne(tag)#0 +def emit_nxtup(tag)#0 emit_pending_seq - emit_byte($3E) + emit_byte($32) emit_reladdr(tag) end -def emit_branch(tag)#0 +def emit_inxtup(tag)#0 emit_pending_seq - emit_byte($50) + emit_byte($34) + emit_reladdr(tag) +end +def emit_nxtdn(tag)#0 + emit_pending_seq + emit_byte($3C) + emit_reladdr(tag) +end +def emit_dnxtdn(tag)#0 + emit_pending_seq + emit_byte($52) emit_reladdr(tag) end def emit_leave#0 diff --git a/src/toolsrc/codeopt.pla b/src/toolsrc/codeopt.pla index c0481d8..bca0424 100644 --- a/src/toolsrc/codeopt.pla +++ b/src/toolsrc/codeopt.pla @@ -129,7 +129,7 @@ def crunch_seq(seq, pass) if not op=>opval op->opcode = LOGIC_NOT_CODE // Replace ZERO:ISEQ op->opgroup = STACK_GROUP - freeops = 1 + freeops = 1 fin break is CONST_CODE // Collapse constant operation diff --git a/src/toolsrc/parse.c b/src/toolsrc/parse.c index e10561f..aa9c3b3 100755 --- a/src/toolsrc/parse.c +++ b/src/toolsrc/parse.c @@ -5,7 +5,7 @@ #define RVALUE 1 #define MAX_LAMBDA 64 -int infunc = 0, break_tag = 0, cont_tag = 0, stack_loop = 0; +int infunc = 0, break_tag = 0, cont_tag = 0, stack_loop = 0, for_loop = 0; long infuncvals = 0; t_token prevstmnt; static int lambda_num = 0; @@ -798,9 +798,9 @@ t_opseq *parse_set(t_opseq *codeseq) int parse_stmnt(void) { int tag_prevbrk, tag_prevcnt, tag_else, tag_endif, tag_while, tag_wend, tag_repeat, tag_for, tag_choice, tag_of; - int type, addr, step, cfnvals; + int type, addr, step, cfnvals, prev_forlp; char *idptr; - t_opseq *seq; + t_opseq *seq, *fromseq, *toseq; /* * Optimization for last function LEAVE and OF clause. @@ -856,6 +856,8 @@ int parse_stmnt(void) parse_error("Missing IF/FIN"); break; case WHILE_TOKEN: + prev_forlp = for_loop; + for_loop = 0; tag_while = tag_new(BRANCH_TYPE); tag_wend = tag_new(BRANCH_TYPE); tag_prevcnt = cont_tag; @@ -879,8 +881,11 @@ int parse_stmnt(void) emit_codetag(tag_wend); break_tag = tag_prevbrk; cont_tag = tag_prevcnt; + for_loop = prev_forlp; break; case REPEAT_TOKEN: + prev_forlp = for_loop; + for_loop = 0; tag_prevbrk = break_tag; break_tag = tag_new(BRANCH_TYPE); tag_repeat = tag_new(BRANCH_TYPE); @@ -904,48 +909,43 @@ int parse_stmnt(void) emit_seq(seq); emit_codetag(break_tag); break_tag = tag_prevbrk; + for_loop = prev_forlp; break; case FOR_TOKEN: - stack_loop++; + prev_forlp = for_loop; + for_loop = 1; + stack_loop += 2; tag_prevbrk = break_tag; break_tag = tag_new(BRANCH_TYPE); tag_for = tag_new(BRANCH_TYPE); tag_prevcnt = cont_tag; - cont_tag = tag_for; + cont_tag = tag_new(BRANCH_TYPE); if (scan() != ID_TOKEN) parse_error("Missing FOR variable"); type = id_type(tokenstr, tokenlen); addr = id_tag(tokenstr, tokenlen); if (scan() != SET_TOKEN) parse_error("Missing FOR ="); - if (!(seq = parse_expr(NULL, &cfnvals))) + if (!(fromseq = parse_expr(NULL, &cfnvals))) parse_error("Bad FOR expression"); if (cfnvals > 1) { parse_warn("Expression value overflow"); while (cfnvals-- > 1) seq = gen_drop(seq); } - emit_seq(seq); - emit_codetag(tag_for); - if (type & LOCAL_TYPE) - type & BYTE_TYPE ? emit_dlb(addr) : emit_dlw(addr); - else - type & BYTE_TYPE ? emit_dab(addr, 0, type) : emit_daw(addr, 0, type); if (scantoken == TO_TOKEN) step = 1; else if (scantoken == DOWNTO_TOKEN) step = -1; else parse_error("Missing FOR TO"); - if (!(seq = parse_expr(NULL, &cfnvals))) + if (!(toseq = parse_expr(NULL, &cfnvals))) parse_error("Bad FOR TO expression"); if (cfnvals > 1) { parse_warn("Expression value overflow"); while (cfnvals-- > 1) seq = gen_drop(seq); } - emit_seq(seq); - step > 0 ? emit_brgt(break_tag) : emit_brlt(break_tag); if (scantoken == STEP_TOKEN) { if (!(seq = parse_expr(NULL, &cfnvals))) @@ -955,22 +955,54 @@ int parse_stmnt(void) parse_warn("Expression value overflow"); while (cfnvals-- > 1) seq = gen_drop(seq); } - emit_seq(seq); - emit_op(step > 0 ? ADD_TOKEN : SUB_TOKEN); } else - emit_unaryop(step > 0 ? INC_TOKEN : DEC_TOKEN); + { + seq = NULL; + } + emit_seq(toseq); + emit_seq(fromseq); + step > 0 ? emit_brgt(break_tag) : emit_brlt(break_tag); + emit_codetag(tag_for); + if (type & LOCAL_TYPE) + type & BYTE_TYPE ? emit_dlb(addr) : emit_dlw(addr); + else + type & BYTE_TYPE ? emit_dab(addr, 0, type) : emit_daw(addr, 0, type); while (parse_stmnt()) next_line(); if (scantoken != NEXT_TOKEN) parse_error("Missing FOR/NEXT"); - emit_brnch(tag_for); + emit_codetag(cont_tag); cont_tag = tag_prevcnt; + if (step > 0) + { + if (seq) + { + emit_seq(seq); + emit_op(ADD_TOKEN); + emit_nxtup(tag_for); + } + else + emit_inxtup(tag_for); + } + else + { + if (seq) + { + emit_seq(seq); + emit_op(SUB_TOKEN); + emit_nxtdn(tag_for); + } + else + emit_dnxtdn(tag_for); + } emit_codetag(break_tag); - emit_drop(); - break_tag = tag_prevbrk; - stack_loop--; + break_tag = tag_prevbrk; + stack_loop -= 2; + for_loop = prev_forlp; break; case CASE_TOKEN: + prev_forlp = for_loop; + for_loop = 0; stack_loop++; tag_prevbrk = break_tag; break_tag = tag_new(BRANCH_TYPE); @@ -1026,10 +1058,18 @@ int parse_stmnt(void) emit_drop(); break_tag = tag_prevbrk; stack_loop--; + for_loop = prev_forlp; break; case BREAK_TOKEN: if (break_tag) + { + if (for_loop) + { + emit_drop(); + emit_drop(); + } emit_brnch(break_tag); + } else parse_error("BREAK without loop"); break; diff --git a/src/toolsrc/parse.pla b/src/toolsrc/parse.pla index c444eb4..417f889 100644 --- a/src/toolsrc/parse.pla +++ b/src/toolsrc/parse.pla @@ -587,8 +587,8 @@ def parse_set(codeseq) return codeseq end def parse_stmnt - byte type, elem_type, elem_size, i, cfnvals - word seq, tag_prevbrk, tag_prevcnt, tag_else, tag_endif, tag_while, tag_wend + byte type, elem_type, elem_size, i, cfnvals, prev_forlp + word seq, fromseq, toseq, tag_prevbrk, tag_prevcnt, tag_else, tag_endif, tag_while, tag_wend word tag_repeat, tag_for, tag_choice, tag_of, idptr, addr, stepdir if token <> END_TKN and token <> DONE_TKN and token <> OF_TKN and token <> DEFAULT_TKN @@ -640,6 +640,8 @@ def parse_stmnt if token <> FIN_TKN; exit_err(ERR_MISS|ERR_CLOSE|ERR_STATE); fin break is WHILE_TKN + prev_forlp = for_loop + for_loop = FALSE tag_while = new_tag(RELATIVE_FIXUP) tag_wend = new_tag(RELATIVE_FIXUP) tag_prevcnt = cont_tag @@ -663,8 +665,11 @@ def parse_stmnt emit_tag(tag_wend) break_tag = tag_prevbrk cont_tag = tag_prevcnt + for_loop = prev_forlp break is REPEAT_TKN + prev_forlp = for_loop + for_loop = FALSE tag_repeat = new_tag(RELATIVE_FIXUP) tag_prevbrk = break_tag break_tag = new_tag(RELATIVE_FIXUP) @@ -688,12 +693,15 @@ def parse_stmnt emit_seq(seq) emit_tag(break_tag) break_tag = tag_prevbrk + for_loop = prev_forlp break is FOR_TKN - stack_loop++ + prev_forlp = for_loop + for_loop = TRUE + stack_loop = stack_loop + 2 tag_for = new_tag(RELATIVE_FIXUP) tag_prevcnt = cont_tag - cont_tag = tag_for + cont_tag = new_tag(RELATIVE_FIXUP) tag_prevbrk = break_tag break_tag = new_tag(RELATIVE_FIXUP) if scan <> ID_TKN; exit_err(ERR_MISS|ERR_ID); fin @@ -705,19 +713,12 @@ def parse_stmnt exit_err(ERR_INVAL|ERR_ID) fin if scan <> SET_TKN; exit_err(ERR_INVAL|ERR_STATE); fin - seq, cfnvals = parse_expr(NULL) - if !seq; exit_err(ERR_INVAL|ERR_STATE); fin + fromseq, cfnvals = parse_expr(NULL) + if !fromseq; exit_err(ERR_INVAL|ERR_STATE); fin if cfnvals > 1 parse_warn("Expression value overflow") while cfnvals > 1;cfnvals--; seq = gen_op(seq, DROP_CODE); loop fin - emit_seq(seq) - emit_tag(tag_for) - if type & LOCAL_TYPE - if type & BYTE_TYPE; emit_dlb(addr); else; emit_dlw(addr); fin - else - if type & BYTE_TYPE; emit_dab(addr, 0); else; emit_daw(addr, 0); fin - fin if token == TO_TKN stepdir = 1 elsif token == DOWNTO_TKN @@ -725,14 +726,12 @@ def parse_stmnt else exit_err(ERR_INVAL|ERR_STATE) fin - seq, cfnvals = parse_expr(NULL) - if !seq; exit_err(ERR_INVAL|ERR_STATE); fin + toseq, cfnvals = parse_expr(NULL) + if !toseq; exit_err(ERR_INVAL|ERR_STATE); fin if cfnvals > 1 parse_warn("Expression value overflow") while cfnvals > 1;cfnvals--; seq = gen_op(seq, DROP_CODE); loop fin - emit_seq(seq) - if stepdir > 0; emit_brgt(break_tag); else; emit_brlt(break_tag); fin if token == STEP_TKN seq, cfnvals = parse_expr(NULL) if !seq; exit_err(ERR_INVAL|ERR_STATE); fin @@ -740,23 +739,51 @@ def parse_stmnt parse_warn("Expression value overflow") while cfnvals > 1;cfnvals--; seq = gen_op(seq, DROP_CODE); loop fin - emit_seq(seq) - emit_code(stepdir > 0 ?? ADD_CODE :: SUB_CODE) else - emit_code(stepdir > 0 ?? INC_CODE :: DEC_CODE) + seq = NULL + fin + emit_seq(toseq) + emit_seq(fromseq) + if stepdir > 0; emit_brgt(break_tag); else; emit_brlt(break_tag); fin + + emit_tag(tag_for) + if type & LOCAL_TYPE + if type & BYTE_TYPE; emit_dlb(addr); else; emit_dlw(addr); fin + else + if type & BYTE_TYPE; emit_dab(addr, 0); else; emit_daw(addr, 0); fin fin while parse_stmnt nextln loop if token <> NEXT_TKN; exit_err(ERR_MISS|ERR_CLOSE|ERR_STATE); fin - emit_branch(tag_for) + emit_tag(cont_tag) cont_tag = tag_prevcnt + if stepdir > 0 + if seq + emit_seq(seq) + emit_code(ADD_CODE) + emit_nxtup(tag_for) + else + emit_inxtup(tag_for) + fin + else + if seq + emit_seq(seq) + emit_code(SUB_CODE) + emit_nxtdn(tag_for) + else + emit_dnxtdn(tag_for) + fin + fin + emit_tag(break_tag) - emit_code(DROP_CODE) - break_tag = tag_prevbrk - stack_loop-- + break_tag = tag_prevbrk + stack_loop = stack_loop - 2 + for_loop = prev_forlp break is CASE_TKN + prev_forlp = for_loop + for_loop = FALSE stack_loop++ tag_prevbrk = break_tag break_tag = new_tag(RELATIVE_FIXUP) @@ -815,9 +842,14 @@ def parse_stmnt emit_code(DROP_CODE) break_tag = tag_prevbrk stack_loop-- + for_loop = prev_forlp break is BREAK_TKN if break_tag + if for_loop + emit_code(DROP_CODE) + emit_code(DROP_CODE) + fin emit_branch(break_tag) else exit_err(ERR_INVAL|ERR_STATE) diff --git a/src/toolsrc/plasm.pla b/src/toolsrc/plasm.pla index 5da3dc6..e68f37b 100644 --- a/src/toolsrc/plasm.pla +++ b/src/toolsrc/plasm.pla @@ -300,6 +300,7 @@ word strconstbuff word strconstptr byte infunc, inlambda byte stack_loop +byte for_loop byte prevstmnt word infuncvals word break_tag diff --git a/src/vmsrc/apple/plvm02.s b/src/vmsrc/apple/plvm02.s index 1194c64..164ed2c 100755 --- a/src/vmsrc/apple/plvm02.s +++ b/src/vmsrc/apple/plvm02.s @@ -193,12 +193,14 @@ VMCORE = * ;* * ;**************** !ALIGN 255,0 +;OPTBL !WORD CONST,CONST,CONST,CONST,CONST,CONST,CONST,CONST ; 00 02 04 06 08 0A 0C 0E +; !WORD CONST,CONST,CONST,CONST,CONST,CONST,CONST,CONST ; 10 12 14 16 18 1A 1C 1E OPTBL !WORD ZERO,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 00 02 04 06 08 0A 0C 0E !WORD NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 10 12 14 16 18 1A 1C 1E !WORD LNOT,LOR,LAND,LA,LLA,CB,CW,CS ; 20 22 24 26 28 2A 2C 2E - !WORD DROP,DUP,NEXTOP,DIVMOD,BRGT,BRLT,BREQ,BRNE ; 30 32 34 36 38 3A 3C 3E + !WORD DROP,NXTUP,INXTUP,DIVMOD,BRGT,BRLT,NXTDN,BRNE ; 30 32 34 36 38 3A 3C 3E !WORD ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E - !WORD BRNCH,IBRNCH,CALL,ICAL,ENTER,LEAVE,RET,CFFB ; 50 52 54 56 58 5A 5C 5E + !WORD BRNCH,DNXTDN,CALL,ICAL,ENTER,LEAVE,RET,CFFB ; 50 52 54 56 58 5A 5C 5E !WORD LB,LW,LLB,LLW,LAB,LAW,DLB,DLW ; 60 62 64 66 68 6A 6C 6E !WORD SB,SW,SLB,SLW,SAB,SAW,DAB,DAW ; 70 72 74 76 78 7A 7C 7E ;* @@ -400,12 +402,14 @@ LCDEFCMD = *-28 ; DEFCMD IN LC MEMORY ;* * ;***************** !ALIGN 255,0 +;OPXTBL !WORD CONST,CONST,CONST,CONST,CONST,CONST,CONST,CONST ; 00 02 04 06 08 0A 0C 0E +; !WORD CONST,CONST,CONST,CONST,CONST,CONST,CONST,CONST ; 10 12 14 16 18 1A 1C 1E OPXTBL !WORD ZERO,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 00 02 04 06 08 0A 0C 0E !WORD NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 10 12 14 16 18 1A 1C 1E !WORD LNOT,LOR,LAND,LA,LLA,CB,CW,CSX ; 20 22 24 26 28 2A 2C 2E - !WORD DROP,DUP,NEXTOP,DIVMOD,BRGT,BRLT,BREQ,BRNE ; 30 32 34 36 38 3A 3C 3E + !WORD DROP,NXTUP,INXTUP,DIVMOD,BRGT,BRLT,NXTDN,BRNE ; 30 32 34 36 38 3A 3C 3E !WORD ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E - !WORD BRNCH,IBRNCH,CALLX,ICALX,ENTER,LEAVEX,RETX,CFFB; 50 52 54 56 58 5A 5C 5E + !WORD BRNCH,DNXTDN,CALLX,ICALX,ENTER,LEAVEX,RETX,CFFB ; 50 52 54 56 58 5A 5C 5E !WORD LBX,LWX,LLBX,LLWX,LABX,LAWX,DLB,DLW ; 60 62 64 66 68 6A 6C 6E !WORD SB,SW,SLB,SLW,SAB,SAW,DAB,DAW ; 70 72 74 76 78 7A 7C 7E ;* @@ -706,28 +710,31 @@ LOR LDA ESTKL,X ;* ;* DUPLICATE TOS ;* -DUP DEX - LDA ESTKL+1,X - STA ESTKL,X - LDA ESTKH+1,X - STA ESTKH,X - JMP NEXTOP +;DUP DEX +; LDA ESTKL+1,X +; STA ESTKL,X +; LDA ESTKH+1,X +; STA ESTKH,X +; JMP NEXTOP ;* ;* LOGICAL NOT ;* LNOT LDA ESTKL,X ORA ESTKH,X - BNE + - LDA #$FF + BEQ + + LDA #$00 ++ EOR #$FF STA ESTKL,X STA ESTKH,X JMP NEXTOP ;* ;* CONSTANT ;* -ZERO DEX -+ LDA #$00 +ZERO +CONST DEX + LSR ;LDA #$00 STA ESTKL,X + LDA #$00 STA ESTKH,X JMP NEXTOP CFFB DEX @@ -1256,14 +1263,6 @@ ISLT LDA ESTKL+1,X ;* ;* BRANCHES ;* -BRTRU INX - LDA ESTKH-1,X - ORA ESTKL-1,X - BNE BRNCH -NOBRNCH INY ;+INC_IP - INY - BMI FIXNEXT - JMP NEXTOP FIXNEXT TYA LDY #$00 CLC @@ -1272,6 +1271,30 @@ FIXNEXT TYA BCC + INC IPH + JMP NEXTOP +;BREQ INX +; LDA ESTKL-1,X +; CMP ESTKL,X +; BNE NOBRNCH +; LDA ESTKH-1,X +; CMP ESTKH,X +; BEQ BRNCH +; BNE NOBRNCH +BRNE INX + LDA ESTKL-1,X + CMP ESTKL,X + BNE BRNCH + LDA ESTKH-1,X + CMP ESTKH,X + BEQ NOBRNCH + BNE BRNCH +BRTRU INX + LDA ESTKH-1,X + ORA ESTKL-1,X + BNE BRNCH +NOBRNCH INY ;+INC_IP + INY + BMI FIXNEXT + JMP NEXTOP BRFLS INX LDA ESTKH-1,X ORA ESTKL-1,X @@ -1294,58 +1317,72 @@ BRNCH TYA ; FLATTEN IP STA IPH DEY JMP FETCHOP -BREQ INX - LDA ESTKL-1,X +;* +;* FOR LOOPS PUT TERMINAL VALUE AT ESTK+1 AND CURRENT COUNT ON ESTK +;* +BRGT LDA ESTKL+1,X ; $D95D CMP ESTKL,X - BNE NOBRNCH - LDA ESTKH-1,X - CMP ESTKH,X - BEQ BRNCH - BNE NOBRNCH -BRNE INX - LDA ESTKL-1,X - CMP ESTKL,X - BNE BRNCH - LDA ESTKH-1,X - CMP ESTKH,X - BEQ NOBRNCH - BNE BRNCH -BRGT INX - LDA ESTKL-1,X - CMP ESTKL,X - LDA ESTKH-1,X + LDA ESTKH+1,X SBC ESTKH,X BVS + BPL NOBRNCH - BMI BRNCH -+ BPL BRNCH - BMI NOBRNCH -BRLT INX - LDA ESTKL,X - CMP ESTKL-1,X +- INX ; DROP FOR VALUES + INX + BNE BRNCH ; BMI BRNCH +BRLT LDA ESTKL,X + CMP ESTKL+1,X LDA ESTKH,X - SBC ESTKH-1,X + SBC ESTKH+1,X BVS + BPL NOBRNCH - BMI BRNCH -+ BPL BRNCH - BMI NOBRNCH -IBRNCH TYA ; FLATTEN IP - CLC - ADC IPL - STA TMPL - LDA #$00 - TAY - ADC IPH - STA TMPH ; ADD BRANCH OFFSET - LDA TMPL - ;CLC ; BETTER NOT CARRY OUT OF IP+Y - ADC ESTKL,X - STA IPL - LDA TMPH - ADC ESTKH,X - STA IPH - JMP DROP + INX ; DROP FOR VALUES + INX + BNE BRNCH ; BMI BRNCH ++ BMI NOBRNCH + BPL - +DNXTDN LDA ESTKL,X + BNE + + DEC ESTKH,X ++ DEC ESTKL,X +NXTDN LDA ESTKL,X ; BRGE + CMP ESTKL+1,X + LDA ESTKH,X + SBC ESTKH+1,X + BVS + + BPL BRNCH +- INX ; DROP FOR VALUES + INX + BNE NOBRNCH ; BMI NOBRNCH +INXTUP INC ESTKL,X + BNE NXTUP + INC ESTKH,X +NXTUP LDA ESTKL+1,X ; BRLE + CMP ESTKL,X + LDA ESTKH+1,X + SBC ESTKH,X + BVS + + BPL BRNCH + INX ; DROP FOR VALUES + INX + BNE NOBRNCH ; BMI NOBRNCH ++ BMI BRNCH + BPL - +;IBRNCH TYA ; FLATTEN IP +; CLC +; ADC IPL +; STA TMPL +; LDA #$00 +; TAY +; ADC IPH +; STA TMPH ; ADD BRANCH OFFSET +; LDA TMPL +; ;CLC ; BETTER NOT CARRY OUT OF IP+Y +; ADC ESTKL,X +; STA IPL +; LDA TMPH +; ADC ESTKH,X +; STA IPH +; JMP DROP ;* ;* CALL INTO ABSOLUTE ADDRESS (NATIVE CODE) ;* @@ -1583,15 +1620,15 @@ CDINTRP PLY JMP FETCHOP CDINTRPEND ; - LDA #ZERO - LDY #(CZEROEND-CZERO) - JSR OPCPY -CZERO DEX - STZ ESTKL,X - STZ ESTKH,X - JMP NEXTOP -CZEROEND +; LDA #ZERO +; LDY #(CZEROEND-CZERO) +; JSR OPCPY +;CZERO DEX +; STZ ESTKL,X +; STZ ESTKH,X +; JMP NEXTOP +;CZEROEND ; LDA #CB @@ -1884,7 +1921,7 @@ OPCPY STA DST INC SRC BNE + INC SRC+1 -+ ++ DEY - LDA (SRC),Y STA (DST),Y DEY From 793b1760a0a1b6d982896f2e94790cf47cc4941e Mon Sep 17 00:00:00 2001 From: Dave Schmenk Date: Sat, 3 Mar 2018 18:55:39 -0800 Subject: [PATCH 002/147] Constant op codes --- src/toolsrc/codegen.c | 69 +++++++++++++++++++++++++++++++++++----- src/toolsrc/codegen.h | 29 ++++++++++------- src/toolsrc/codegen.pla | 19 ++++++----- src/toolsrc/codeopt.pla | 18 +++++++++++ src/toolsrc/codeseq.plh | 3 ++ src/toolsrc/parse.c | 8 ++--- src/toolsrc/parse.pla | 8 ++--- src/vmsrc/apple/plvm02.s | 59 +++++++++++++++++++++++++--------- 8 files changed, 163 insertions(+), 50 deletions(-) diff --git a/src/toolsrc/codegen.c b/src/toolsrc/codegen.c index 1acbbb7..d253cb1 100755 --- a/src/toolsrc/codegen.c +++ b/src/toolsrc/codegen.c @@ -614,6 +614,21 @@ void emit_conststr(long conststr) printf("\t%s\t$2E\t\t\t; CS\n", DB); emit_data(0, STRING_TYPE, conststr, 0); } +void emit_addi(int cval) +{ + emit_pending_seq(); + printf("\t%s\t$34,$%02X\t\t\t; ADDI\t%d\n", DB, cval, cval); +} +void emit_andi(int cval) +{ + emit_pending_seq(); + printf("\t%s\t$3C,$%02X\t\t\t; ANDI\t%d\n", DB, cval, cval); +} +void emit_ori(int cval) +{ + emit_pending_seq(); + printf("\t%s\t$52,$%02X\t\t\t; IORI\t%d\n", DB, cval, cval); +} void emit_lb(void) { printf("\t%s\t$60\t\t\t; LB\n", DB); @@ -793,28 +808,28 @@ void emit_brlt(int tag) printf("\t%s\t$3A\t\t\t; BRLT\t_B%03d\n", DB, tag); printf("\t%s\t_B%03d-*\n", DW, tag); } -void emit_nxtup(int tag) +void emit_brle(int tag) { emit_pending_seq(); - printf("\t%s\t$32\t\t\t; NXTUP\t_B%03d\n", DB, tag); + printf("\t%s\t$80\t\t\t; NXTUP\t_B%03d\n", DB, tag); printf("\t%s\t_B%03d-*\n", DW, tag); } -void emit_inxtup(int tag) +void emit_incbrle(int tag) { emit_pending_seq(); - printf("\t%s\t$34\t\t\t; INXTUP\t_B%03d\n", DB, tag); + printf("\t%s\t$82\t\t\t; INXTUP\t_B%03d\n", DB, tag); printf("\t%s\t_B%03d-*\n", DW, tag); } -void emit_nxtdn(int tag) +void emit_brge(int tag) { emit_pending_seq(); - printf("\t%s\t$3C\t\t\t; NXTDN\t_B%03d\n", DB, tag); + printf("\t%s\t$84\t\t\t; NXTDN\t_B%03d\n", DB, tag); printf("\t%s\t_B%03d-*\n", DW, tag); } -void emit_dnxtdn(int tag) +void emit_decbrge(int tag) { emit_pending_seq(); - printf("\t%s\t$52\t\t\t; DNXTDN\t_B%03d\n", DB, tag); + printf("\t%s\t$84\t\t\t; DNXTDN\t_B%03d\n", DB, tag); printf("\t%s\t_B%03d-*\n", DW, tag); } void emit_call(int tag, int type) @@ -865,6 +880,11 @@ void emit_drop(void) emit_pending_seq(); printf("\t%s\t$30\t\t\t; DROP\n", DB); } +void emit_dup(void) +{ + emit_pending_seq(); + printf("\t%s\t$32\t\t\t; DUP\n", DB); +} int emit_unaryop(t_token op) { emit_pending_seq(); @@ -1240,6 +1260,27 @@ int crunch_seq(t_opseq **seq, int pass) if ((pass > 0) && (freeops == 0) && (op->val != 0)) crunched = try_dupify(op); break; // CONST_CODE + case BINARY_CODE(ADD_TOKEN): + if (op->val >= 0 && op->val <= 255) + { + op->code = ADDI_CODE; + freeops = 1; + } + break; + case BINARY_CODE(AND_TOKEN): + if (op->val >= 0 && op->val <= 255) + { + op->code = ANDI_CODE; + freeops = 1; + } + break; + case BINARY_CODE(OR_TOKEN): + if (op->val >= 0 && op->val <= 255) + { + op->code = ORI_CODE; + freeops = 1; + } + break; case BINARY_CODE(MUL_TOKEN): for (shiftcnt = 0; shiftcnt < 16; shiftcnt++) { @@ -1607,6 +1648,15 @@ int emit_pending_seq() case STR_CODE: emit_conststr(op->val); break; + case ADDI_CODE: + emit_addi(op->val); + break; + case ANDI_CODE: + emit_andi(op->val); + break; + case ORI_CODE: + emit_ori(op->val); + break; case LB_CODE: emit_lb(); break; @@ -1676,6 +1726,9 @@ int emit_pending_seq() case DROP_CODE: emit_drop(); break; + case DUP_CODE: + emit_dup(); + break; case BRNCH_CODE: emit_brnch(op->tag); break; diff --git a/src/toolsrc/codegen.h b/src/toolsrc/codegen.h index 86679b6..44c979d 100755 --- a/src/toolsrc/codegen.h +++ b/src/toolsrc/codegen.h @@ -59,11 +59,14 @@ typedef struct _opseq { #define INDEXW_CODE 0x0317 #define DROP_CODE 0x0318 #define DUP_CODE 0x0319 -#define BRNCH_CODE 0x031C -#define BRFALSE_CODE 0x031D -#define BRTRUE_CODE 0x031E -#define CODETAG_CODE 0x031F -#define NOP_CODE 0x0320 +#define ADDI_CODE 0x031A +#define ANDI_CODE 0x031B +#define ORI_CODE 0x31C +#define BRNCH_CODE 0x031D +#define BRFALSE_CODE 0x031E +#define BRTRUE_CODE 0x031F +#define CODETAG_CODE 0x0320 +#define NOP_CODE 0x0321 #define gen_uop(seq,op) gen_seq(seq,UNARY_CODE(op),0,0,0,0) #define gen_op(seq,op) gen_seq(seq,BINARY_CODE(op),0,0,0,0) @@ -102,6 +105,9 @@ int emit_data(int vartype, int consttype, long constval, int constsize); void emit_codetag(int tag); void emit_const(int cval); void emit_conststr(long conststr); +void emit_addi(int cval); +void emit_andi(int cval); +void emit_ori(int cval); void emit_lb(void); void emit_lw(void); void emit_llb(int index); @@ -128,16 +134,17 @@ int emit_unaryop(t_token op); int emit_op(t_token op); void emit_brtru(int tag); void emit_brfls(int tag); -void emit_brgt(int tag); -void emit_brlt(int tag); void emit_brne(int tag); void emit_brnch(int tag); -void emit_nxtup(int tag); -void emit_inxtup(int tag); -void emit_nxtdn(int tag); -void emit_dnxtdn(int tag); +void emit_brgt(int tag); +void emit_brlt(int tag); +void emit_brle(int tag); +void emit_incbrle(int tag); +void emit_brge(int tag); +void emit_decbrge(int tag); void emit_empty(void); void emit_drop(void); +void emit_dup(void); void emit_leave(void); void emit_ret(void); void emit_enter(int cparams); diff --git a/src/toolsrc/codegen.pla b/src/toolsrc/codegen.pla index fb38ec5..22c6b8e 100644 --- a/src/toolsrc/codegen.pla +++ b/src/toolsrc/codegen.pla @@ -191,24 +191,24 @@ def emit_brlt(tag)#0 emit_byte($3A) emit_reladdr(tag) end -def emit_nxtup(tag)#0 +def emit_brle(tag)#0 emit_pending_seq - emit_byte($32) + emit_byte($80) emit_reladdr(tag) end -def emit_inxtup(tag)#0 +def emit_incbrle(tag)#0 emit_pending_seq - emit_byte($34) + emit_byte($82) emit_reladdr(tag) end -def emit_nxtdn(tag)#0 +def emit_brge(tag)#0 emit_pending_seq - emit_byte($3C) + emit_byte($84) emit_reladdr(tag) end -def emit_dnxtdn(tag)#0 +def emit_decbrge(tag)#0 emit_pending_seq - emit_byte($52) + emit_byte($86) emit_reladdr(tag) end def emit_leave#0 @@ -300,6 +300,9 @@ def emit_pending_seq#0 codeptr=>1 = op=>opval codeptr = codeptr + 3 fin + else + *codeptr = op->opcode | (op->opval << 8) + codeptr = codeptr + 2 fin break // diff --git a/src/toolsrc/codeopt.pla b/src/toolsrc/codeopt.pla index bca0424..bff131d 100644 --- a/src/toolsrc/codeopt.pla +++ b/src/toolsrc/codeopt.pla @@ -214,6 +214,24 @@ def crunch_seq(seq, pass) crunched = try_dupify(op) fin break // CONST_CODE + is ADD_CODE + if op=>opval >= 0 and op=>opval <= 255 + op->opcode = ADDI_CODE + freeops = 1 + fin + break + is AND_CODE + if op=>opval >= 0 and op=>opval <= 255 + op->opcode = ANDI_CODE + freeops = 1 + fin + break + is OR_CODE + if op=>opval >= 0 and op=>opval <= 255 + op->opcode = ORI_CODE + freeops = 1 + fin + break is MUL_CODE for shiftcnt = 0 to 15 if op=>opval == 1 << shiftcnt diff --git a/src/toolsrc/codeseq.plh b/src/toolsrc/codeseq.plh index 6cc4cf3..0ed844b 100644 --- a/src/toolsrc/codeseq.plh +++ b/src/toolsrc/codeseq.plh @@ -3,6 +3,9 @@ // const CONST_GROUP = $00 const CONST_CODE = $2C +const ADDI_CODE = $34 +const ANDI_CODE = $3C +const ORI_CODE = $52 const CONSTR_GROUP = $01 const CONSTR_CODE = $2E // diff --git a/src/toolsrc/parse.c b/src/toolsrc/parse.c index aa9c3b3..f9ff562 100755 --- a/src/toolsrc/parse.c +++ b/src/toolsrc/parse.c @@ -979,10 +979,10 @@ int parse_stmnt(void) { emit_seq(seq); emit_op(ADD_TOKEN); - emit_nxtup(tag_for); + emit_brle(tag_for); } else - emit_inxtup(tag_for); + emit_incbrle(tag_for); } else { @@ -990,10 +990,10 @@ int parse_stmnt(void) { emit_seq(seq); emit_op(SUB_TOKEN); - emit_nxtdn(tag_for); + emit_brge(tag_for); } else - emit_dnxtdn(tag_for); + emit_decbrge(tag_for); } emit_codetag(break_tag); break_tag = tag_prevbrk; diff --git a/src/toolsrc/parse.pla b/src/toolsrc/parse.pla index 417f889..ce00a4b 100644 --- a/src/toolsrc/parse.pla +++ b/src/toolsrc/parse.pla @@ -762,17 +762,17 @@ def parse_stmnt if seq emit_seq(seq) emit_code(ADD_CODE) - emit_nxtup(tag_for) + emit_brle(tag_for) else - emit_inxtup(tag_for) + emit_incbrle(tag_for) fin else if seq emit_seq(seq) emit_code(SUB_CODE) - emit_nxtdn(tag_for) + emit_brge(tag_for) else - emit_dnxtdn(tag_for) + emit_decbrge(tag_for) fin fin diff --git a/src/vmsrc/apple/plvm02.s b/src/vmsrc/apple/plvm02.s index 164ed2c..db60d29 100755 --- a/src/vmsrc/apple/plvm02.s +++ b/src/vmsrc/apple/plvm02.s @@ -198,11 +198,12 @@ VMCORE = * OPTBL !WORD ZERO,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 00 02 04 06 08 0A 0C 0E !WORD NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 10 12 14 16 18 1A 1C 1E !WORD LNOT,LOR,LAND,LA,LLA,CB,CW,CS ; 20 22 24 26 28 2A 2C 2E - !WORD DROP,NXTUP,INXTUP,DIVMOD,BRGT,BRLT,NXTDN,BRNE ; 30 32 34 36 38 3A 3C 3E + !WORD DROP,DUP,ADDI,DIVMOD,BRGT,BRLT,ANDI,BRNE ; 30 32 34 36 38 3A 3C 3E !WORD ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E - !WORD BRNCH,DNXTDN,CALL,ICAL,ENTER,LEAVE,RET,CFFB ; 50 52 54 56 58 5A 5C 5E + !WORD BRNCH,ORI,CALL,ICAL,ENTER,LEAVE,RET,CFFB ; 50 52 54 56 58 5A 5C 5E !WORD LB,LW,LLB,LLW,LAB,LAW,DLB,DLW ; 60 62 64 66 68 6A 6C 6E !WORD SB,SW,SLB,SLW,SAB,SAW,DAB,DAW ; 70 72 74 76 78 7A 7C 7E + !WORD BRLE,INCBRLE,BRGE,DECBRGE ; 80 82 84 86 88 8A 8C 8E ;* ;* ENTER INTO BYTECODE INTERPRETER ;* @@ -407,11 +408,12 @@ LCDEFCMD = *-28 ; DEFCMD IN LC MEMORY OPXTBL !WORD ZERO,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 00 02 04 06 08 0A 0C 0E !WORD NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 10 12 14 16 18 1A 1C 1E !WORD LNOT,LOR,LAND,LA,LLA,CB,CW,CSX ; 20 22 24 26 28 2A 2C 2E - !WORD DROP,NXTUP,INXTUP,DIVMOD,BRGT,BRLT,NXTDN,BRNE ; 30 32 34 36 38 3A 3C 3E + !WORD DROP,DUP,ADDI,DIVMOD,BRGT,BRLT,ANDI,BRNE ; 30 32 34 36 38 3A 3C 3E !WORD ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E - !WORD BRNCH,DNXTDN,CALLX,ICALX,ENTER,LEAVEX,RETX,CFFB ; 50 52 54 56 58 5A 5C 5E + !WORD BRNCH,ORI,CALLX,ICALX,ENTER,LEAVEX,RETX,CFFB ; 50 52 54 56 58 5A 5C 5E !WORD LBX,LWX,LLBX,LLWX,LABX,LAWX,DLB,DLW ; 60 62 64 66 68 6A 6C 6E !WORD SB,SW,SLB,SLW,SAB,SAW,DAB,DAW ; 70 72 74 76 78 7A 7C 7E + !WORD BRLE,INCBRLE,BRGE,DECBRGE ; 80 82 84 86 88 8A 8C 8E ;* ;* ADD TOS TO TOS-1 ;* @@ -710,12 +712,12 @@ LOR LDA ESTKL,X ;* ;* DUPLICATE TOS ;* -;DUP DEX -; LDA ESTKL+1,X -; STA ESTKL,X -; LDA ESTKH+1,X -; STA ESTKH,X -; JMP NEXTOP +DUP DEX + LDA ESTKL+1,X + STA ESTKL,X + LDA ESTKH+1,X + STA ESTKH,X + JMP NEXTOP ;* ;* LOGICAL NOT ;* @@ -752,6 +754,33 @@ CB DEX STA ESTKL,X JMP NEXTOP ;* +;* ADD IMMEDIATE TO TOS +;* +ADDI INY ;+INC_IP + LDA (IP),Y + CLC + ADC ESTKL,X + STA ESTKL,X + BCC + + INC ESTKH,X ++ JMP NEXTOP +;* +;* AND IMMEDIATE TO TOS +;* +ANDI INY ;+INC_IP + LDA (IP),Y + AND ESTKL,X + STA ESTKL,X + JMP NEXTOP +;* +;* IOR IMMEDIATE TO TOS +;* +ORI INY ;+INC_IP + LDA (IP),Y + ORA ESTKL,X + STA ESTKL,X + JMP NEXTOP +;* ;* LOAD ADDRESS & LOAD CONSTANT WORD (SAME THING, WITH OR WITHOUT FIXUP) ;* - TYA ; RENORMALIZE IP @@ -1340,11 +1369,11 @@ BRLT LDA ESTKL,X BNE BRNCH ; BMI BRNCH + BMI NOBRNCH BPL - -DNXTDN LDA ESTKL,X +DECBRGE LDA ESTKL,X BNE + DEC ESTKH,X + DEC ESTKL,X -NXTDN LDA ESTKL,X ; BRGE +BRGE LDA ESTKL,X ; BRGE CMP ESTKL+1,X LDA ESTKH,X SBC ESTKH+1,X @@ -1353,10 +1382,10 @@ NXTDN LDA ESTKL,X ; BRGE - INX ; DROP FOR VALUES INX BNE NOBRNCH ; BMI NOBRNCH -INXTUP INC ESTKL,X - BNE NXTUP +INCBRLE INC ESTKL,X + BNE BRLE INC ESTKH,X -NXTUP LDA ESTKL+1,X ; BRLE +BRLE LDA ESTKL+1,X ; BRLE CMP ESTKL,X LDA ESTKH+1,X SBC ESTKH,X From 2b2e464c9b65c27d4db8d269a26075ee119b535e Mon Sep 17 00:00:00 2001 From: Dave Schmenk Date: Sun, 4 Mar 2018 10:18:31 -0800 Subject: [PATCH 003/147] More immidiate ops, add/sub next branches --- src/toolsrc/codegen.c | 49 +++++++---- src/toolsrc/codegen.h | 21 +++-- src/toolsrc/codegen.pla | 10 +-- src/toolsrc/codeopt.pla | 6 ++ src/toolsrc/codeseq.plh | 8 +- src/toolsrc/parse.c | 41 ++++----- src/toolsrc/parse.pla | 37 ++++---- src/toolsrc/plasm.pla | 3 +- src/vmsrc/apple/plvm02.s | 64 ++++++++++---- src/vmsrc/plvm.c | 177 ++++++++++++++++++++++++++++++--------- 10 files changed, 280 insertions(+), 136 deletions(-) diff --git a/src/toolsrc/codegen.c b/src/toolsrc/codegen.c index d253cb1..8076a86 100755 --- a/src/toolsrc/codegen.c +++ b/src/toolsrc/codegen.c @@ -617,7 +617,12 @@ void emit_conststr(long conststr) void emit_addi(int cval) { emit_pending_seq(); - printf("\t%s\t$34,$%02X\t\t\t; ADDI\t%d\n", DB, cval, cval); + printf("\t%s\t$38,$%02X\t\t\t; ADDI\t%d\n", DB, cval, cval); +} +void emit_subi(int cval) +{ + emit_pending_seq(); + printf("\t%s\t$3A,$%02X\t\t\t; SUBI\t%d\n", DB, cval, cval); } void emit_andi(int cval) { @@ -627,7 +632,7 @@ void emit_andi(int cval) void emit_ori(int cval) { emit_pending_seq(); - printf("\t%s\t$52,$%02X\t\t\t; IORI\t%d\n", DB, cval, cval); + printf("\t%s\t$3E,$%02X\t\t\t; ORI\t%d\n", DB, cval, cval); } void emit_lb(void) { @@ -784,52 +789,46 @@ void emit_brnch(int tag) printf("\t%s\t$50\t\t\t; BRNCH\t_B%03d\n", DB, tag); printf("\t%s\t_B%03d-*\n", DW, tag); } -//void emit_breq(int tag) -//{ -// emit_pending_seq(); -// printf("\t%s\t$3C\t\t\t; BREQ\t_B%03d\n", DB, tag); -// printf("\t%s\t_B%03d-*\n", DW, tag); -//} void emit_brne(int tag) { emit_pending_seq(); - printf("\t%s\t$3E\t\t\t; BRNE\t_B%03d\n", DB, tag); + printf("\t%s\t$52\t\t\t; BRNE\t_B%03d\n", DB, tag); printf("\t%s\t_B%03d-*\n", DW, tag); } void emit_brgt(int tag) { emit_pending_seq(); - printf("\t%s\t$38\t\t\t; BRGT\t_B%03d\n", DB, tag); + printf("\t%s\t$88\t\t\t; BRGT\t_B%03d\n", DB, tag); printf("\t%s\t_B%03d-*\n", DW, tag); } void emit_brlt(int tag) { emit_pending_seq(); - printf("\t%s\t$3A\t\t\t; BRLT\t_B%03d\n", DB, tag); + printf("\t%s\t$8A\t\t\t; BRLT\t_B%03d\n", DB, tag); printf("\t%s\t_B%03d-*\n", DW, tag); } -void emit_brle(int tag) +void emit_addbrle(int tag) { emit_pending_seq(); - printf("\t%s\t$80\t\t\t; NXTUP\t_B%03d\n", DB, tag); + printf("\t%s\t$80\t\t\t; BRLE\t_B%03d\n", DB, tag); printf("\t%s\t_B%03d-*\n", DW, tag); } void emit_incbrle(int tag) { emit_pending_seq(); - printf("\t%s\t$82\t\t\t; INXTUP\t_B%03d\n", DB, tag); + printf("\t%s\t$82\t\t\t; INCBRLE\t_B%03d\n", DB, tag); printf("\t%s\t_B%03d-*\n", DW, tag); } -void emit_brge(int tag) +void emit_subbrge(int tag) { emit_pending_seq(); - printf("\t%s\t$84\t\t\t; NXTDN\t_B%03d\n", DB, tag); + printf("\t%s\t$84\t\t\t; BRGE\t_B%03d\n", DB, tag); printf("\t%s\t_B%03d-*\n", DW, tag); } void emit_decbrge(int tag) { emit_pending_seq(); - printf("\t%s\t$84\t\t\t; DNXTDN\t_B%03d\n", DB, tag); + printf("\t%s\t$86\t\t\t; DECBRGE\t_B%03d\n", DB, tag); printf("\t%s\t_B%03d-*\n", DW, tag); } void emit_call(int tag, int type) @@ -880,11 +879,16 @@ void emit_drop(void) emit_pending_seq(); printf("\t%s\t$30\t\t\t; DROP\n", DB); } -void emit_dup(void) +void emit_drop2(void) { emit_pending_seq(); printf("\t%s\t$32\t\t\t; DUP\n", DB); } +void emit_dup(void) +{ + emit_pending_seq(); + printf("\t%s\t$34\t\t\t; DUP\n", DB); +} int emit_unaryop(t_token op) { emit_pending_seq(); @@ -1267,6 +1271,12 @@ int crunch_seq(t_opseq **seq, int pass) freeops = 1; } break; + case BINARY_CODE(SUB_TOKEN): + if (op->val >= 0 && op->val <= 255) + { + op->code = SUBI_CODE; + freeops = 1; + } case BINARY_CODE(AND_TOKEN): if (op->val >= 0 && op->val <= 255) { @@ -1651,6 +1661,9 @@ int emit_pending_seq() case ADDI_CODE: emit_addi(op->val); break; + case SUBI_CODE: + emit_subi(op->val); + break; case ANDI_CODE: emit_andi(op->val); break; diff --git a/src/toolsrc/codegen.h b/src/toolsrc/codegen.h index 44c979d..4861c45 100755 --- a/src/toolsrc/codegen.h +++ b/src/toolsrc/codegen.h @@ -60,13 +60,14 @@ typedef struct _opseq { #define DROP_CODE 0x0318 #define DUP_CODE 0x0319 #define ADDI_CODE 0x031A -#define ANDI_CODE 0x031B -#define ORI_CODE 0x31C -#define BRNCH_CODE 0x031D -#define BRFALSE_CODE 0x031E -#define BRTRUE_CODE 0x031F -#define CODETAG_CODE 0x0320 -#define NOP_CODE 0x0321 +#define SUBI_CODE 0x031B +#define ANDI_CODE 0x031C +#define ORI_CODE 0x31D +#define BRNCH_CODE 0x0320 +#define BRFALSE_CODE 0x0321 +#define BRTRUE_CODE 0x0322 +#define CODETAG_CODE 0x0323 +#define NOP_CODE 0x0324 #define gen_uop(seq,op) gen_seq(seq,UNARY_CODE(op),0,0,0,0) #define gen_op(seq,op) gen_seq(seq,BINARY_CODE(op),0,0,0,0) @@ -106,6 +107,7 @@ void emit_codetag(int tag); void emit_const(int cval); void emit_conststr(long conststr); void emit_addi(int cval); +void emit_subi(int cval); void emit_andi(int cval); void emit_ori(int cval); void emit_lb(void); @@ -138,12 +140,13 @@ void emit_brne(int tag); void emit_brnch(int tag); void emit_brgt(int tag); void emit_brlt(int tag); -void emit_brle(int tag); +void emit_addbrle(int tag); void emit_incbrle(int tag); -void emit_brge(int tag); +void emit_subbrge(int tag); void emit_decbrge(int tag); void emit_empty(void); void emit_drop(void); +void emit_drop2(void); void emit_dup(void); void emit_leave(void); void emit_ret(void); diff --git a/src/toolsrc/codegen.pla b/src/toolsrc/codegen.pla index 22c6b8e..4ec8a89 100644 --- a/src/toolsrc/codegen.pla +++ b/src/toolsrc/codegen.pla @@ -173,7 +173,7 @@ def emit_daw(tag, offset)#0 end def emit_brne(tag)#0 emit_pending_seq - emit_byte($3E) + emit_byte($52) emit_reladdr(tag) end def emit_branch(tag)#0 @@ -183,15 +183,15 @@ def emit_branch(tag)#0 end def emit_brgt(tag)#0 emit_pending_seq - emit_byte($38) + emit_byte($88) emit_reladdr(tag) end def emit_brlt(tag)#0 emit_pending_seq - emit_byte($3A) + emit_byte($8A) emit_reladdr(tag) end -def emit_brle(tag)#0 +def emit_addbrle(tag)#0 emit_pending_seq emit_byte($80) emit_reladdr(tag) @@ -201,7 +201,7 @@ def emit_incbrle(tag)#0 emit_byte($82) emit_reladdr(tag) end -def emit_brge(tag)#0 +def emit_subbrge(tag)#0 emit_pending_seq emit_byte($84) emit_reladdr(tag) diff --git a/src/toolsrc/codeopt.pla b/src/toolsrc/codeopt.pla index bff131d..b49e37d 100644 --- a/src/toolsrc/codeopt.pla +++ b/src/toolsrc/codeopt.pla @@ -220,6 +220,12 @@ def crunch_seq(seq, pass) freeops = 1 fin break + is SUB_CODE + if op=>opval >= 0 and op=>opval <= 255 + op->opcode = SUBI_CODE + freeops = 1 + fin + break is AND_CODE if op=>opval >= 0 and op=>opval <= 255 op->opcode = ANDI_CODE diff --git a/src/toolsrc/codeseq.plh b/src/toolsrc/codeseq.plh index 0ed844b..cf14e2d 100644 --- a/src/toolsrc/codeseq.plh +++ b/src/toolsrc/codeseq.plh @@ -3,9 +3,10 @@ // const CONST_GROUP = $00 const CONST_CODE = $2C -const ADDI_CODE = $34 +const ADDI_CODE = $38 +const SUBI_CODE = $3A const ANDI_CODE = $3C -const ORI_CODE = $52 +const ORI_CODE = $3E const CONSTR_GROUP = $01 const CONSTR_CODE = $2E // @@ -32,7 +33,8 @@ const LOGIC_NOT_CODE = $20 const LOGIC_OR_CODE = $22 const LOGIC_AND_CODE = $24 const DROP_CODE = $30 -const DUP_CODE = $32 +const DROP2_CODE = $32 +const DUP_CODE = $34 const EQ_CODE = $40 const NE_CODE = $42 const GT_CODE = $44 diff --git a/src/toolsrc/parse.c b/src/toolsrc/parse.c index f9ff562..a8f3408 100755 --- a/src/toolsrc/parse.c +++ b/src/toolsrc/parse.c @@ -5,7 +5,7 @@ #define RVALUE 1 #define MAX_LAMBDA 64 -int infunc = 0, break_tag = 0, cont_tag = 0, stack_loop = 0, for_loop = 0; +int infunc = 0, break_tag = 0, cont_tag = 0, stack_loop = 0, infor = 0; long infuncvals = 0; t_token prevstmnt; static int lambda_num = 0; @@ -798,7 +798,7 @@ t_opseq *parse_set(t_opseq *codeseq) int parse_stmnt(void) { int tag_prevbrk, tag_prevcnt, tag_else, tag_endif, tag_while, tag_wend, tag_repeat, tag_for, tag_choice, tag_of; - int type, addr, step, cfnvals, prev_forlp; + int type, addr, step, cfnvals, prev_for; char *idptr; t_opseq *seq, *fromseq, *toseq; @@ -856,8 +856,8 @@ int parse_stmnt(void) parse_error("Missing IF/FIN"); break; case WHILE_TOKEN: - prev_forlp = for_loop; - for_loop = 0; + prev_for = infor; + infor = 0; tag_while = tag_new(BRANCH_TYPE); tag_wend = tag_new(BRANCH_TYPE); tag_prevcnt = cont_tag; @@ -881,11 +881,11 @@ int parse_stmnt(void) emit_codetag(tag_wend); break_tag = tag_prevbrk; cont_tag = tag_prevcnt; - for_loop = prev_forlp; + infor = prev_for; break; case REPEAT_TOKEN: - prev_forlp = for_loop; - for_loop = 0; + prev_for = infor; + infor = 0; tag_prevbrk = break_tag; break_tag = tag_new(BRANCH_TYPE); tag_repeat = tag_new(BRANCH_TYPE); @@ -909,11 +909,11 @@ int parse_stmnt(void) emit_seq(seq); emit_codetag(break_tag); break_tag = tag_prevbrk; - for_loop = prev_forlp; + infor = prev_for; break; case FOR_TOKEN: - prev_forlp = for_loop; - for_loop = 1; + prev_for = infor; + infor = 1; stack_loop += 2; tag_prevbrk = break_tag; break_tag = tag_new(BRANCH_TYPE); @@ -978,8 +978,7 @@ int parse_stmnt(void) if (seq) { emit_seq(seq); - emit_op(ADD_TOKEN); - emit_brle(tag_for); + emit_addbrle(tag_for); } else emit_incbrle(tag_for); @@ -989,8 +988,7 @@ int parse_stmnt(void) if (seq) { emit_seq(seq); - emit_op(SUB_TOKEN); - emit_brge(tag_for); + emit_subbrge(tag_for); } else emit_decbrge(tag_for); @@ -998,11 +996,11 @@ int parse_stmnt(void) emit_codetag(break_tag); break_tag = tag_prevbrk; stack_loop -= 2; - for_loop = prev_forlp; + infor = prev_for; break; case CASE_TOKEN: - prev_forlp = for_loop; - for_loop = 0; + prev_for = infor; + infor = 0; stack_loop++; tag_prevbrk = break_tag; break_tag = tag_new(BRANCH_TYPE); @@ -1058,16 +1056,13 @@ int parse_stmnt(void) emit_drop(); break_tag = tag_prevbrk; stack_loop--; - for_loop = prev_forlp; + infor = prev_for; break; case BREAK_TOKEN: if (break_tag) { - if (for_loop) - { - emit_drop(); - emit_drop(); - } + if (infor) + emit_drop2(); emit_brnch(break_tag); } else diff --git a/src/toolsrc/parse.pla b/src/toolsrc/parse.pla index ce00a4b..0e58b6c 100644 --- a/src/toolsrc/parse.pla +++ b/src/toolsrc/parse.pla @@ -587,7 +587,7 @@ def parse_set(codeseq) return codeseq end def parse_stmnt - byte type, elem_type, elem_size, i, cfnvals, prev_forlp + byte type, elem_type, elem_size, i, cfnvals, prev_for word seq, fromseq, toseq, tag_prevbrk, tag_prevcnt, tag_else, tag_endif, tag_while, tag_wend word tag_repeat, tag_for, tag_choice, tag_of, idptr, addr, stepdir @@ -640,8 +640,8 @@ def parse_stmnt if token <> FIN_TKN; exit_err(ERR_MISS|ERR_CLOSE|ERR_STATE); fin break is WHILE_TKN - prev_forlp = for_loop - for_loop = FALSE + prev_for = infor + infor = FALSE tag_while = new_tag(RELATIVE_FIXUP) tag_wend = new_tag(RELATIVE_FIXUP) tag_prevcnt = cont_tag @@ -665,11 +665,11 @@ def parse_stmnt emit_tag(tag_wend) break_tag = tag_prevbrk cont_tag = tag_prevcnt - for_loop = prev_forlp + infor = prev_for break is REPEAT_TKN - prev_forlp = for_loop - for_loop = FALSE + prev_for = infor + infor = FALSE tag_repeat = new_tag(RELATIVE_FIXUP) tag_prevbrk = break_tag break_tag = new_tag(RELATIVE_FIXUP) @@ -693,11 +693,11 @@ def parse_stmnt emit_seq(seq) emit_tag(break_tag) break_tag = tag_prevbrk - for_loop = prev_forlp + infor = prev_for break is FOR_TKN - prev_forlp = for_loop - for_loop = TRUE + prev_for = infor + infor = TRUE stack_loop = stack_loop + 2 tag_for = new_tag(RELATIVE_FIXUP) tag_prevcnt = cont_tag @@ -761,16 +761,14 @@ def parse_stmnt if stepdir > 0 if seq emit_seq(seq) - emit_code(ADD_CODE) - emit_brle(tag_for) + emit_addbrle(tag_for) else emit_incbrle(tag_for) fin else if seq emit_seq(seq) - emit_code(SUB_CODE) - emit_brge(tag_for) + emit_subbrge(tag_for) else emit_decbrge(tag_for) fin @@ -779,11 +777,11 @@ def parse_stmnt emit_tag(break_tag) break_tag = tag_prevbrk stack_loop = stack_loop - 2 - for_loop = prev_forlp + infor = prev_for break is CASE_TKN - prev_forlp = for_loop - for_loop = FALSE + prev_for = infor + infor = FALSE stack_loop++ tag_prevbrk = break_tag break_tag = new_tag(RELATIVE_FIXUP) @@ -842,14 +840,11 @@ def parse_stmnt emit_code(DROP_CODE) break_tag = tag_prevbrk stack_loop-- - for_loop = prev_forlp + infor = prev_for break is BREAK_TKN if break_tag - if for_loop - emit_code(DROP_CODE) - emit_code(DROP_CODE) - fin + if infor; emit_code(DROP2_CODE); fin emit_branch(break_tag) else exit_err(ERR_INVAL|ERR_STATE) diff --git a/src/toolsrc/plasm.pla b/src/toolsrc/plasm.pla index e68f37b..fdb5aa2 100644 --- a/src/toolsrc/plasm.pla +++ b/src/toolsrc/plasm.pla @@ -298,9 +298,8 @@ const RVALUE = 1 const LAMBDANUM = 16 word strconstbuff word strconstptr -byte infunc, inlambda +byte infunc, inlambda, infor byte stack_loop -byte for_loop byte prevstmnt word infuncvals word break_tag diff --git a/src/vmsrc/apple/plvm02.s b/src/vmsrc/apple/plvm02.s index db60d29..4798177 100755 --- a/src/vmsrc/apple/plvm02.s +++ b/src/vmsrc/apple/plvm02.s @@ -198,12 +198,12 @@ VMCORE = * OPTBL !WORD ZERO,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 00 02 04 06 08 0A 0C 0E !WORD NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 10 12 14 16 18 1A 1C 1E !WORD LNOT,LOR,LAND,LA,LLA,CB,CW,CS ; 20 22 24 26 28 2A 2C 2E - !WORD DROP,DUP,ADDI,DIVMOD,BRGT,BRLT,ANDI,BRNE ; 30 32 34 36 38 3A 3C 3E + !WORD DROP,DROP2,DUP,DIVMOD,ADDI,SUBI,ANDI,ORI ; 30 32 34 36 38 3A 3C 3E !WORD ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E - !WORD BRNCH,ORI,CALL,ICAL,ENTER,LEAVE,RET,CFFB ; 50 52 54 56 58 5A 5C 5E + !WORD BRNCH,BRNE,CALL,ICAL,ENTER,LEAVE,RET,CFFB ; 50 52 54 56 58 5A 5C 5E !WORD LB,LW,LLB,LLW,LAB,LAW,DLB,DLW ; 60 62 64 66 68 6A 6C 6E !WORD SB,SW,SLB,SLW,SAB,SAW,DAB,DAW ; 70 72 74 76 78 7A 7C 7E - !WORD BRLE,INCBRLE,BRGE,DECBRGE ; 80 82 84 86 88 8A 8C 8E + !WORD ADDBRLE,INCBRLE,SUBBRGE,DECBRGE,BRGT,BRLT ; 80 82 84 86 88 8A 8C 8E ;* ;* ENTER INTO BYTECODE INTERPRETER ;* @@ -408,12 +408,12 @@ LCDEFCMD = *-28 ; DEFCMD IN LC MEMORY OPXTBL !WORD ZERO,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 00 02 04 06 08 0A 0C 0E !WORD NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 10 12 14 16 18 1A 1C 1E !WORD LNOT,LOR,LAND,LA,LLA,CB,CW,CSX ; 20 22 24 26 28 2A 2C 2E - !WORD DROP,DUP,ADDI,DIVMOD,BRGT,BRLT,ANDI,BRNE ; 30 32 34 36 38 3A 3C 3E + !WORD DROP,DROP2,DUP,DIVMOD,ADDI,SUBI,ANDI,ORI ; 30 32 34 36 38 3A 3C 3E !WORD ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E - !WORD BRNCH,ORI,CALLX,ICALX,ENTER,LEAVEX,RETX,CFFB ; 50 52 54 56 58 5A 5C 5E + !WORD BRNCH,BRNE,CALLX,ICALX,ENTER,LEAVEX,RETX,CFFB ; 50 52 54 56 58 5A 5C 5E !WORD LBX,LWX,LLBX,LLWX,LABX,LAWX,DLB,DLW ; 60 62 64 66 68 6A 6C 6E !WORD SB,SW,SLB,SLW,SAB,SAW,DAB,DAW ; 70 72 74 76 78 7A 7C 7E - !WORD BRLE,INCBRLE,BRGE,DECBRGE ; 80 82 84 86 88 8A 8C 8E + !WORD ADDBRLE,INCBRLE,SUBBRGE,DECBRGE,BRGT,BRLT ; 80 82 84 86 88 8A 8C 8E ;* ;* ADD TOS TO TOS-1 ;* @@ -765,12 +765,25 @@ ADDI INY ;+INC_IP INC ESTKH,X + JMP NEXTOP ;* +;* SUB IMMEDIATE FROM TOS +;* +SUBI INY ;+INC_IP + LDA ESTKL,X + SEC + SBC (IP),Y + STA ESTKL,X + BCS + + DEC ESTKH,X ++ JMP NEXTOP +;* ;* AND IMMEDIATE TO TOS ;* ANDI INY ;+INC_IP LDA (IP),Y AND ESTKL,X STA ESTKL,X + LDA #$00 + STA ESTKH,X JMP NEXTOP ;* ;* IOR IMMEDIATE TO TOS @@ -1105,7 +1118,10 @@ SW LDA ESTKL,X JMP DROP + INC ESTKH,X STA (ESTKH-1,X) - INX +;* +;* DROP TOS, TOS-1 +;* +DROP2 INX JMP DROP ;* ;* STORE VALUE TO LOCAL FRAME OFFSET @@ -1349,7 +1365,7 @@ BRNCH TYA ; FLATTEN IP ;* ;* FOR LOOPS PUT TERMINAL VALUE AT ESTK+1 AND CURRENT COUNT ON ESTK ;* -BRGT LDA ESTKL+1,X ; $D95D +BRGT LDA ESTKL+1,X CMP ESTKL,X LDA ESTKH+1,X SBC ESTKH,X @@ -1370,11 +1386,13 @@ BRLT LDA ESTKL,X + BMI NOBRNCH BPL - DECBRGE LDA ESTKL,X - BNE + + SEC + SBC #$01 + STA ESTKL,X + BCS + DEC ESTKH,X -+ DEC ESTKL,X -BRGE LDA ESTKL,X ; BRGE - CMP ESTKL+1,X +_BRGE LDA ESTKL,X ; BRGE ++ CMP ESTKL+1,X LDA ESTKH,X SBC ESTKH+1,X BVS + @@ -1383,9 +1401,9 @@ BRGE LDA ESTKL,X ; BRGE INX BNE NOBRNCH ; BMI NOBRNCH INCBRLE INC ESTKL,X - BNE BRLE + BNE _BRLE INC ESTKH,X -BRLE LDA ESTKL+1,X ; BRLE +_BRLE LDA ESTKL+1,X ; BRLE CMP ESTKL,X LDA ESTKH+1,X SBC ESTKH,X @@ -1396,6 +1414,24 @@ BRLE LDA ESTKL+1,X ; BRLE BNE NOBRNCH ; BMI NOBRNCH + BMI BRNCH BPL - +SUBBRGE LDA ESTKL+1,X + SEC + SBC ESTKL,X + STA ESTKL+1,X + LDA ESTKH+1,X + SBC ESTKH,X + STA ESTKH+1,X + INX + BNE _BRGE +ADDBRLE LDA ESTKL,X + CLC + ADC ESTKL+1,X + STA ESTKL+1,X + LDA ESTKH,X + ADC ESTKH+1,X + STA ESTKH+1,X + INX + BNE _BRLE ;IBRNCH TYA ; FLATTEN IP ; CLC ; ADC IPL diff --git a/src/vmsrc/plvm.c b/src/vmsrc/plvm.c index 5395c44..1aef4ab 100755 --- a/src/vmsrc/plvm.c +++ b/src/vmsrc/plvm.c @@ -36,7 +36,7 @@ uword sp = 0x01FE, fp = 0xFFFF, heap = 0x0200, deftbl = DEF_CALL, lastdef = DEF_ #define UPOP ((uword)(*(esp++))) #define TOS (esp[0]) word eval_stack[EVAL_STACKSZ]; -word *esp = eval_stack + EVAL_STACKSZ; +word *esp = &eval_stack[EVAL_STACKSZ]; #define SYMTBLSZ 1024 #define SYMSZ 16 @@ -517,21 +517,28 @@ void call(uword pc) /* * OPCODE TABLE * -OPTBL: DW ZERO,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 00 02 04 06 08 0A 0C 0E - DW NEG,COMP,AND,IOR,XOR,SHL,SHR,IDXW ; 10 12 14 16 18 1A 1C 1E - DW NOT,LOR,LAND,LA,LLA,CB,CW,CS ; 20 22 24 26 28 2A 2C 2E - DW DROP,DUP,PUSH,PULL,BRGT,BRLT,BREQ,BRNE ; 30 32 34 36 38 3A 3C 3E +OPTBL: DW ZERO,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 00 02 04 06 08 0A 0C 0E + DW NEG,COMP,AND,IOR,XOR,SHL,SHR,IDXW ; 10 12 14 16 18 1A 1C 1E + DW NOT,LOR,LAND,LA,LLA,CB,CW,CS ; 20 22 24 26 28 2A 2C 2E + DW DROP,DROP2,DUP,DIVMOD,ADDI,SUBI,ANDI,ORI ; 30 32 34 36 38 3A 3C 3E DW ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E - DW BRNCH,IBRNCH,CALL,ICAL,ENTER,LEAVE,RET,CFFB ; 50 52 54 56 58 5A 5C 5E - DW LB,LW,LLB,LLW,LAB,LAW,DLB,DLW ; 60 62 64 66 68 6A 6C 6E - DW SB,SW,SLB,SLW,SAB,SAW,DAB,DAW ; 70 72 74 76 78 7A 7C 7E + DW BRNCH,BRNE,CALL,ICAL,ENTER,LEAVE,RET,CFFB ; 50 52 54 56 58 5A 5C 5E + DW LB,LW,LLB,LLW,LAB,LAW,DLB,DLW ; 60 62 64 66 68 6A 6C 6E + DW SB,SW,SLB,SLW,SAB,SAW,DAB,DAW ; 70 72 74 76 78 7A 7C 7E + DW ADDBRLE,INCBRLE,SUBBRGE,DECBRGE,BRGT,BRLT ; 80 82 84 86 88 8A 8C 8E */ void interp(code *ip) { int val, ea, frmsz, parmcnt; + code *previp = ip; while (1) { + if ((esp - eval_stack) < 0 || (esp - eval_stack) > EVAL_STACKSZ) + { + printf("Eval stack over/underflow! - $%04X: $%02X [%d]\n", previp - mem_data, *previp, EVAL_STACKSZ - (esp - eval_stack)); + show_state = 1; + } if (show_state) { char cmdline[16]; @@ -542,11 +549,12 @@ void interp(code *ip) printf("]\n"); gets(cmdline); } + previp = ip; switch (*ip++) { - /* - * 0x00-0x0F - */ + /* + * 0x00-0x0F + */ case 0x00: // ZERO : TOS = 0 PUSH(0); break; @@ -662,41 +670,31 @@ void interp(code *ip) case 0x30: // DROP : TOS = POP; break; - case 0x32: // DUP : TOS = TOS + case 0x32: // DROP2 : TOS == + POP; + POP; + break; + case 0x34: // DUP : TOS = TOS val = TOS; PUSH(val); break; - case 0x34: // NOP + case 0x36: // DIVMOD break; - case 0x36: // NOP + case 0x38: // ADDI + PUSH(POP + BYTE_PTR(ip)); + ip++; break; - case 0x38: // BRGT : TOS-1 > TOS ? IP += (IP) - val = POP; - if (TOS > val) - ip += WORD_PTR(ip); - else - ip += 2; + case 0x3A: // SUBI + PUSH(POP - BYTE_PTR(ip)); + ip++; break; - case 0x3A: // BRLT : TOS-1 < TOS ? IP += (IP) - val = POP; - if (TOS < val) - ip += WORD_PTR(ip); - else - ip += 2; + case 0x3C: // ANDI + PUSH(POP & BYTE_PTR(ip)); + ip++; break; - case 0x3C: // BREQ : TOS == TOS-1 ? IP += (IP) - val = POP; - if (TOS == val) - ip += WORD_PTR(ip); - else - ip += 2; - break; - case 0x3E: // BRNE : TOS != TOS-1 ? IP += (IP) - val = POP; - if (TOS != val) - ip += WORD_PTR(ip); - else - ip += 2; + case 0x3E: // ORI + PUSH(POP | BYTE_PTR(ip)); + ip++; break; /* * 0x40-0x4F @@ -749,8 +747,18 @@ void interp(code *ip) case 0x50: // BRNCH : IP += (IP) ip += WORD_PTR(ip); break; - case 0x52: // IBRNCH : IP += TOS - ip += POP; + case 0x52: // BRNE : TOS != TOS-1 ? IP += (IP) + val = POP; + if (TOS != val) + { + PUSH(val); + ip += WORD_PTR(ip); + } + else + { + PUSH(val); + ip += 2; + } break; case 0x54: // CALL : TOFP = IP, IP = (IP) ; call call(UWORD_PTR(ip)); @@ -873,6 +881,93 @@ void interp(code *ip) mem_data[ea + 1] = TOS >> 8; ip += 2; break; + /* + * 0x80-0x8F + */ + case 0x80: // ADDBRLE : TOS = TOS + TOS-1 + val = POP; + ea = POP; + val = ea + val; + if (TOS >= val) + { + PUSH(val); + ip += WORD_PTR(ip); + } + else + { + POP; + ip += 2; + } + break; + case 0x82: // INCBRLE : TOS = TOS + 1 + val = POP; + val++; + if (TOS >= val) + { + PUSH(val); + ip += WORD_PTR(ip); + } + else + { + POP; + ip += 2; + } + break; + case 0x84: // SUBBRGE : TOS = TOS-1 - TOS + val = POP; + ea = POP; + val = ea - val; + if (TOS <= val) + { + PUSH(val); + ip += WORD_PTR(ip); + } + else + { + POP; + ip += 2; + } + break; + case 0x86: // DECBRGE : TOS = TOS - 1 + val = POP; + val--; + if (TOS <= val) + { + PUSH(val); + ip += WORD_PTR(ip); + } + else + { + POP; + ip += 2; + } + break; + case 0x88: // BRGT : TOS-1 > TOS ? IP += (IP) + val = POP; + if (TOS < val) + { + POP; + ip += WORD_PTR(ip); + } + else + { + PUSH(val); + ip += 2; + } + break; + case 0x8A: // BRLT : TOS-1 < TOS ? IP += (IP) + val = POP; + if (TOS > val) + { + POP; + ip += WORD_PTR(ip); + } + else + { + PUSH(val); + ip += 2; + } + break; /* * Odd codes and everything else are errors. */ From 5b41fd07c44c20e93ea179aad9d50dfce964d59c Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Sun, 4 Mar 2018 13:15:02 -0800 Subject: [PATCH 004/147] More work on for/next --- src/samplesrc/rogue.combat.pla | 57 ++++++++++---------- src/toolsrc/codegen.c | 25 ++++----- src/toolsrc/codegen.pla | 7 +-- src/toolsrc/lex.pla | 11 ++-- src/toolsrc/parse.pla | 27 +++++----- src/vmsrc/apple/plvm02.s | 40 +++++++------- src/vmsrc/plvm.c | 95 +++++++++++++++++----------------- 7 files changed, 132 insertions(+), 130 deletions(-) diff --git a/src/samplesrc/rogue.combat.pla b/src/samplesrc/rogue.combat.pla index 8e88b1a..57154ee 100644 --- a/src/samplesrc/rogue.combat.pla +++ b/src/samplesrc/rogue.combat.pla @@ -162,38 +162,37 @@ export def fight(player, enemy) if toupper(conio:getkey()) == 'R' conio:echo(ECHO_OFF) return 1 + fin + // + // Turn player in random direction + // + player->angle = conio:rnd() & 7 + // + // Calculate attack (with a little random variation) + // + p_atck = player->skill + player->energy / 10 - enemy->power / 25 + (conio:rnd() & 7) + e_atck = enemy->power - player->skill / 5 - player->energy / 20 + (conio:rnd() & 7) + if enemy->life > p_atck + enemy->life = enemy->life - p_atck else + win + enemy->life = 0 + p_atck = player->skill + enemy->power / 3 + if p_atck > 100 // Limit skill + p_atck = 100 + fin + player->skill = p_atck // - // Turn player in random direction + // Unlink dead enemy from entities list // - player->angle = conio:rnd() & 7 - // - // Calculate attack (with a little random variation) - // - p_atck = player->skill + player->energy / 10 - enemy->power / 25 + (conio:rnd() & 7) - e_atck = enemy->power - player->skill / 5 - player->energy / 20 + (conio:rnd() & 7) - if enemy->life > p_atck - enemy->life = enemy->life - p_atck - else - win - enemy->life = 0 - p_atck = player->skill + enemy->power / 3 - if p_atck > 100 // Limit skill - p_atck = 100 - fin - player->skill = p_atck - // - // Unlink dead enemy from entities list - // - if enemy == entities - entities = enemy=>next_other - fin - if enemy=>next_other - enemy=>next_other=>prev_other = enemy=>prev_other - fin - if enemy=>prev_other - enemy=>prev_other=>next_other = enemy=>next_other - fin + if enemy == entities + entities = enemy=>next_other + fin + if enemy=>next_other + enemy=>next_other=>prev_other = enemy=>prev_other + fin + if enemy=>prev_other + enemy=>prev_other=>next_other = enemy=>next_other fin if player->health > e_atck player->health = player->health - e_atck diff --git a/src/toolsrc/codegen.c b/src/toolsrc/codegen.c index 8076a86..e9208f9 100755 --- a/src/toolsrc/codegen.c +++ b/src/toolsrc/codegen.c @@ -798,37 +798,37 @@ void emit_brne(int tag) void emit_brgt(int tag) { emit_pending_seq(); - printf("\t%s\t$88\t\t\t; BRGT\t_B%03d\n", DB, tag); + printf("\t%s\t$80\t\t\t; BRGT\t_B%03d\n", DB, tag); printf("\t%s\t_B%03d-*\n", DW, tag); } void emit_brlt(int tag) { emit_pending_seq(); - printf("\t%s\t$8A\t\t\t; BRLT\t_B%03d\n", DB, tag); - printf("\t%s\t_B%03d-*\n", DW, tag); -} -void emit_addbrle(int tag) -{ - emit_pending_seq(); - printf("\t%s\t$80\t\t\t; BRLE\t_B%03d\n", DB, tag); + printf("\t%s\t$82\t\t\t; BRLT\t_B%03d\n", DB, tag); printf("\t%s\t_B%03d-*\n", DW, tag); } void emit_incbrle(int tag) { emit_pending_seq(); - printf("\t%s\t$82\t\t\t; INCBRLE\t_B%03d\n", DB, tag); + printf("\t%s\t$84\t\t\t; INCBRLE\t_B%03d\n", DB, tag); printf("\t%s\t_B%03d-*\n", DW, tag); } -void emit_subbrge(int tag) +void emit_addbrle(int tag) { emit_pending_seq(); - printf("\t%s\t$84\t\t\t; BRGE\t_B%03d\n", DB, tag); + printf("\t%s\t$86\t\t\t; BRLE\t_B%03d\n", DB, tag); printf("\t%s\t_B%03d-*\n", DW, tag); } void emit_decbrge(int tag) { emit_pending_seq(); - printf("\t%s\t$86\t\t\t; DECBRGE\t_B%03d\n", DB, tag); + printf("\t%s\t$88\t\t\t; DECBRGE\t_B%03d\n", DB, tag); + printf("\t%s\t_B%03d-*\n", DW, tag); +} +void emit_subbrge(int tag) +{ + emit_pending_seq(); + printf("\t%s\t$8A\t\t\t; BRGE\t_B%03d\n", DB, tag); printf("\t%s\t_B%03d-*\n", DW, tag); } void emit_call(int tag, int type) @@ -1277,6 +1277,7 @@ int crunch_seq(t_opseq **seq, int pass) op->code = SUBI_CODE; freeops = 1; } + break; case BINARY_CODE(AND_TOKEN): if (op->val >= 0 && op->val <= 255) { diff --git a/src/toolsrc/codegen.pla b/src/toolsrc/codegen.pla index 4ec8a89..4c72ea2 100644 --- a/src/toolsrc/codegen.pla +++ b/src/toolsrc/codegen.pla @@ -405,9 +405,10 @@ def idmatch(nameptr, len, idptr, idcnt) while idcnt if len == idptr->idname - for i = 1 to len - if nameptr->[i - 1] <> idptr->idname.[i]; break; fin - next + i = 1; while i <= len and nameptr->[i - 1] == idptr->idname.[i]; i++; loop + //for i = 1 to len + // if nameptr->[i - 1] <> idptr->idname.[i]; break; fin + //next if i > len; return idptr; fin fin idptr = idptr + idptr->idname + t_id diff --git a/src/toolsrc/lex.pla b/src/toolsrc/lex.pla index 2a6474c..b20e863 100644 --- a/src/toolsrc/lex.pla +++ b/src/toolsrc/lex.pla @@ -36,11 +36,12 @@ def keymatch loop chrptr = tknptr - 1 while keywrds[keypos] == tknlen - for i = 1 to tknlen - if ^(chrptr + i) <> keywrds[keypos + i] - break - fin - next + i = 1; while i <= tknlen and ^(chrptr + i) == keywrds[keypos + i]; i++; loop + //for i = 1 to tknlen + // if ^(chrptr + i) <> keywrds[keypos + i] + // break + // fin + //next if i > tknlen return keywrds[keypos + keywrds[keypos] + 1] fin diff --git a/src/toolsrc/parse.pla b/src/toolsrc/parse.pla index 0e58b6c..95e3812 100644 --- a/src/toolsrc/parse.pla +++ b/src/toolsrc/parse.pla @@ -640,8 +640,8 @@ def parse_stmnt if token <> FIN_TKN; exit_err(ERR_MISS|ERR_CLOSE|ERR_STATE); fin break is WHILE_TKN - prev_for = infor - infor = FALSE + prev_for = infor + infor = FALSE tag_while = new_tag(RELATIVE_FIXUP) tag_wend = new_tag(RELATIVE_FIXUP) tag_prevcnt = cont_tag @@ -665,11 +665,11 @@ def parse_stmnt emit_tag(tag_wend) break_tag = tag_prevbrk cont_tag = tag_prevcnt - infor = prev_for + infor = prev_for break is REPEAT_TKN - prev_for = infor - infor = FALSE + prev_for = infor + infor = FALSE tag_repeat = new_tag(RELATIVE_FIXUP) tag_prevbrk = break_tag break_tag = new_tag(RELATIVE_FIXUP) @@ -693,11 +693,11 @@ def parse_stmnt emit_seq(seq) emit_tag(break_tag) break_tag = tag_prevbrk - infor = prev_for + infor = prev_for break is FOR_TKN - prev_for = infor - infor = TRUE + prev_for = infor + infor = TRUE stack_loop = stack_loop + 2 tag_for = new_tag(RELATIVE_FIXUP) tag_prevcnt = cont_tag @@ -773,15 +773,14 @@ def parse_stmnt emit_decbrge(tag_for) fin fin - emit_tag(break_tag) - break_tag = tag_prevbrk - stack_loop = stack_loop - 2 - infor = prev_for + break_tag = tag_prevbrk + stack_loop = stack_loop - 2 + infor = prev_for break is CASE_TKN - prev_for = infor - infor = FALSE + prev_for = infor + infor = FALSE stack_loop++ tag_prevbrk = break_tag break_tag = new_tag(RELATIVE_FIXUP) diff --git a/src/vmsrc/apple/plvm02.s b/src/vmsrc/apple/plvm02.s index 4798177..c5ade84 100755 --- a/src/vmsrc/apple/plvm02.s +++ b/src/vmsrc/apple/plvm02.s @@ -203,7 +203,8 @@ OPTBL !WORD ZERO,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 00 02 04 06 08 !WORD BRNCH,BRNE,CALL,ICAL,ENTER,LEAVE,RET,CFFB ; 50 52 54 56 58 5A 5C 5E !WORD LB,LW,LLB,LLW,LAB,LAW,DLB,DLW ; 60 62 64 66 68 6A 6C 6E !WORD SB,SW,SLB,SLW,SAB,SAW,DAB,DAW ; 70 72 74 76 78 7A 7C 7E - !WORD ADDBRLE,INCBRLE,SUBBRGE,DECBRGE,BRGT,BRLT ; 80 82 84 86 88 8A 8C 8E + !WORD BRGT,BRLT,INCBRLE,ADDBRLE,DECBRGE,SUBBRGE ; 80 82 84 86 88 8A 8C 8E +;* ;* ;* ENTER INTO BYTECODE INTERPRETER ;* @@ -413,7 +414,7 @@ OPXTBL !WORD ZERO,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 00 02 04 06 08 !WORD BRNCH,BRNE,CALLX,ICALX,ENTER,LEAVEX,RETX,CFFB ; 50 52 54 56 58 5A 5C 5E !WORD LBX,LWX,LLBX,LLWX,LABX,LAWX,DLB,DLW ; 60 62 64 66 68 6A 6C 6E !WORD SB,SW,SLB,SLW,SAB,SAW,DAB,DAW ; 70 72 74 76 78 7A 7C 7E - !WORD ADDBRLE,INCBRLE,SUBBRGE,DECBRGE,BRGT,BRLT ; 80 82 84 86 88 8A 8C 8E + !WORD BRGT,BRLT,INCBRLE,ADDBRLE,DECBRGE,SUBBRGE ; 80 82 84 86 88 8A 8C 8E ;* ;* ADD TOS TO TOS-1 ;* @@ -710,6 +711,17 @@ LOR LDA ESTKL,X STA ESTKH+1,X + JMP DROP ;* +;* LOGICAL NOT +;* +LNOT LDA ESTKL,X + ORA ESTKH,X + BEQ + + LDA #$FF ++ EOR #$FF + STA ESTKL,X + STA ESTKH,X + JMP NEXTOP +;* ;* DUPLICATE TOS ;* DUP DEX @@ -719,17 +731,6 @@ DUP DEX STA ESTKH,X JMP NEXTOP ;* -;* LOGICAL NOT -;* -LNOT LDA ESTKL,X - ORA ESTKH,X - BEQ + - LDA #$00 -+ EOR #$FF - STA ESTKL,X - STA ESTKH,X - JMP NEXTOP -;* ;* CONSTANT ;* ZERO @@ -1385,13 +1386,12 @@ BRLT LDA ESTKL,X BNE BRNCH ; BMI BRNCH + BMI NOBRNCH BPL - -DECBRGE LDA ESTKL,X - SEC - SBC #$01 - STA ESTKL,X - BCS + +DECBRGE DEC ESTKL,X + LDA ESTKL,X + CMP #$FF + BNE + DEC ESTKH,X -_BRGE LDA ESTKL,X ; BRGE +_BRGE LDA ESTKL,X + CMP ESTKL+1,X LDA ESTKH,X SBC ESTKH+1,X @@ -1403,7 +1403,7 @@ _BRGE LDA ESTKL,X ; BRGE INCBRLE INC ESTKL,X BNE _BRLE INC ESTKH,X -_BRLE LDA ESTKL+1,X ; BRLE +_BRLE LDA ESTKL+1,X CMP ESTKL,X LDA ESTKH+1,X SBC ESTKH,X diff --git a/src/vmsrc/plvm.c b/src/vmsrc/plvm.c index 1aef4ab..a28178d 100755 --- a/src/vmsrc/plvm.c +++ b/src/vmsrc/plvm.c @@ -526,6 +526,7 @@ OPTBL: DW ZERO,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 00 02 04 06 08 0A 0C 0 DW LB,LW,LLB,LLW,LAB,LAW,DLB,DLW ; 60 62 64 66 68 6A 6C 6E DW SB,SW,SLB,SLW,SAB,SAW,DAB,DAW ; 70 72 74 76 78 7A 7C 7E DW ADDBRLE,INCBRLE,SUBBRGE,DECBRGE,BRGT,BRLT ; 80 82 84 86 88 8A 8C 8E + DW BRGT,BRLT,INCBRLE,ADDBRLE,DECBRGE,SUBBRGE ; 80 82 84 86 88 8A 8C 8E */ void interp(code *ip) { @@ -884,7 +885,47 @@ void interp(code *ip) /* * 0x80-0x8F */ - case 0x80: // ADDBRLE : TOS = TOS + TOS-1 + case 0x80: // BRGT : TOS-1 > TOS ? IP += (IP) + val = POP; + if (TOS < val) + { + POP; + ip += WORD_PTR(ip); + } + else + { + PUSH(val); + ip += 2; + } + break; + case 0x82: // BRLT : TOS-1 < TOS ? IP += (IP) + val = POP; + if (TOS > val) + { + POP; + ip += WORD_PTR(ip); + } + else + { + PUSH(val); + ip += 2; + } + break; + case 0x84: // INCBRLE : TOS = TOS + 1 + val = POP; + val++; + if (TOS >= val) + { + PUSH(val); + ip += WORD_PTR(ip); + } + else + { + POP; + ip += 2; + } + break; + case 0x86: // ADDBRLE : TOS = TOS + TOS-1 val = POP; ea = POP; val = ea + val; @@ -899,36 +940,7 @@ void interp(code *ip) ip += 2; } break; - case 0x82: // INCBRLE : TOS = TOS + 1 - val = POP; - val++; - if (TOS >= val) - { - PUSH(val); - ip += WORD_PTR(ip); - } - else - { - POP; - ip += 2; - } - break; - case 0x84: // SUBBRGE : TOS = TOS-1 - TOS - val = POP; - ea = POP; - val = ea - val; - if (TOS <= val) - { - PUSH(val); - ip += WORD_PTR(ip); - } - else - { - POP; - ip += 2; - } - break; - case 0x86: // DECBRGE : TOS = TOS - 1 + case 0x88: // DECBRGE : TOS = TOS - 1 val = POP; val--; if (TOS <= val) @@ -942,29 +954,18 @@ void interp(code *ip) ip += 2; } break; - case 0x88: // BRGT : TOS-1 > TOS ? IP += (IP) + case 0x8A: // SUBBRGE : TOS = TOS-1 - TOS val = POP; - if (TOS < val) + ea = POP; + val = ea - val; + if (TOS <= val) { - POP; + PUSH(val); ip += WORD_PTR(ip); } else - { - PUSH(val); - ip += 2; - } - break; - case 0x8A: // BRLT : TOS-1 < TOS ? IP += (IP) - val = POP; - if (TOS > val) { POP; - ip += WORD_PTR(ip); - } - else - { - PUSH(val); ip += 2; } break; From 18301b6ce9e3e3509e01744bc972505c6383252c Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Sun, 4 Mar 2018 14:21:40 -0800 Subject: [PATCH 005/147] Adjust to new for/next --- src/toolsrc/codegen.pla | 22 +++++++++++----------- src/toolsrc/parse.pla | 1 - 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/toolsrc/codegen.pla b/src/toolsrc/codegen.pla index 4c72ea2..acbb04c 100644 --- a/src/toolsrc/codegen.pla +++ b/src/toolsrc/codegen.pla @@ -183,32 +183,32 @@ def emit_branch(tag)#0 end def emit_brgt(tag)#0 emit_pending_seq - emit_byte($88) + emit_byte($80) emit_reladdr(tag) end def emit_brlt(tag)#0 emit_pending_seq - emit_byte($8A) - emit_reladdr(tag) -end -def emit_addbrle(tag)#0 - emit_pending_seq - emit_byte($80) + emit_byte($82) emit_reladdr(tag) end def emit_incbrle(tag)#0 emit_pending_seq - emit_byte($82) + emit_byte($84) emit_reladdr(tag) end -def emit_subbrge(tag)#0 +def emit_addbrle(tag)#0 emit_pending_seq - emit_byte($84) + emit_byte($86) emit_reladdr(tag) end def emit_decbrge(tag)#0 emit_pending_seq - emit_byte($86) + emit_byte($88) + emit_reladdr(tag) +end +def emit_subbrge(tag)#0 + emit_pending_seq + emit_byte($8A) emit_reladdr(tag) end def emit_leave#0 diff --git a/src/toolsrc/parse.pla b/src/toolsrc/parse.pla index 95e3812..47a467c 100644 --- a/src/toolsrc/parse.pla +++ b/src/toolsrc/parse.pla @@ -745,7 +745,6 @@ def parse_stmnt emit_seq(toseq) emit_seq(fromseq) if stepdir > 0; emit_brgt(break_tag); else; emit_brlt(break_tag); fin - emit_tag(tag_for) if type & LOCAL_TYPE if type & BYTE_TYPE; emit_dlb(addr); else; emit_dlw(addr); fin From e1090c012cdd2072c6e7a1aa71cb91b870af7331 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Sun, 4 Mar 2018 15:00:40 -0800 Subject: [PATCH 006/147] Better WHILE/LOOP --- src/toolsrc/parse.c | 9 +++++---- src/toolsrc/parse.pla | 9 +++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/toolsrc/parse.c b/src/toolsrc/parse.c index a8f3408..7d8e4d4 100755 --- a/src/toolsrc/parse.c +++ b/src/toolsrc/parse.c @@ -861,9 +861,10 @@ int parse_stmnt(void) tag_while = tag_new(BRANCH_TYPE); tag_wend = tag_new(BRANCH_TYPE); tag_prevcnt = cont_tag; - cont_tag = tag_while; + cont_tag = tag_new(BRANCH_TYPE); tag_prevbrk = break_tag; break_tag = tag_wend; + emit_brnch(cont_tag); emit_codetag(tag_while); if (!(seq = parse_expr(NULL, &cfnvals))) parse_error("Bad expression"); @@ -872,12 +873,12 @@ int parse_stmnt(void) parse_warn("Expression value overflow"); while (cfnvals-- > 1) seq = gen_drop(seq); } - seq = gen_brfls(seq, tag_wend); - emit_seq(seq); + seq = gen_brtru(seq, tag_while); while (parse_stmnt()) next_line(); if (scantoken != LOOP_TOKEN) parse_error("Missing WHILE/END"); - emit_brnch(tag_while); + emit_codetag(cont_tag); + emit_seq(seq); emit_codetag(tag_wend); break_tag = tag_prevbrk; cont_tag = tag_prevcnt; diff --git a/src/toolsrc/parse.pla b/src/toolsrc/parse.pla index 47a467c..a5cab82 100644 --- a/src/toolsrc/parse.pla +++ b/src/toolsrc/parse.pla @@ -645,9 +645,10 @@ def parse_stmnt tag_while = new_tag(RELATIVE_FIXUP) tag_wend = new_tag(RELATIVE_FIXUP) tag_prevcnt = cont_tag - cont_tag = tag_while + cont_tag = new_tag(RELATIVE_FIXUP) tag_prevbrk = break_tag break_tag = tag_wend + emit_branch(cont_tag) emit_tag(tag_while) seq, cfnvals = parse_expr(NULL) if !seq; exit_err(ERR_INVAL|ERR_STATE); fin @@ -655,13 +656,13 @@ def parse_stmnt parse_warn("Expression value overflow") while cfnvals > 1;cfnvals--; seq = gen_op(seq, DROP_CODE); loop fin - seq = gen_oprel(seq, BRFALSE_CODE, tag_wend) - emit_seq(seq) + seq = gen_oprel(seq, BRTRUE_CODE, tag_while) while parse_stmnt nextln loop if token <> LOOP_TKN; exit_err(ERR_MISS|ERR_CLOSE|ERR_STATE); fin - emit_branch(tag_while) + emit_tag(cont_tag) + emit_seq(seq) emit_tag(tag_wend) break_tag = tag_prevbrk cont_tag = tag_prevcnt From 3ee19e86f691b9307995b2bbf10eabd261aeed40 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Sun, 4 Mar 2018 21:36:23 -0800 Subject: [PATCH 007/147] SWITCH/CASE table optimization --- src/samplesrc/rogue.combat.pla | 18 +++---- src/toolsrc/codegen.c | 17 ++++++ src/toolsrc/codegen.h | 2 + src/toolsrc/parse.c | 94 ++++++++++++++++++++++++---------- src/toolsrc/parse.pla | 9 +++- src/vmsrc/apple/plvm02.s | 64 +++++++++++++++++++---- src/vmsrc/plvm.c | 24 +++++---- 7 files changed, 170 insertions(+), 58 deletions(-) diff --git a/src/samplesrc/rogue.combat.pla b/src/samplesrc/rogue.combat.pla index 57154ee..4faea46 100644 --- a/src/samplesrc/rogue.combat.pla +++ b/src/samplesrc/rogue.combat.pla @@ -194,15 +194,15 @@ export def fight(player, enemy) if enemy=>prev_other enemy=>prev_other=>next_other = enemy=>next_other fin - if player->health > e_atck - player->health = player->health - e_atck - else - player->energy = 0 - player->health = 0 - fin - if player->energy >= 4 - player->energy = player->energy - 4 - fin + fin + if player->health > e_atck + player->health = player->health - e_atck + else + player->energy = 0 + player->health = 0 + fin + if player->energy >= 4 + player->energy = player->energy - 4 fin until player->health == 0 or enemy->life == 0 conio:echo(ECHO_OFF) diff --git a/src/toolsrc/codegen.c b/src/toolsrc/codegen.c index e9208f9..9ab4119 100755 --- a/src/toolsrc/codegen.c +++ b/src/toolsrc/codegen.c @@ -773,6 +773,23 @@ void emit_indexword(void) { printf("\t%s\t$1E\t\t\t; IDXW\n", DB); } +void emit_select(int tag) +{ + emit_pending_seq(); + printf("\t%s\t$52\t\t\t; SEL\n", DB); + printf("\t%s\t_B%03d-*\n", DW, tag); +} +void emit_caseblock(int casecnt, int *caseof, int *casetag) +{ + int i; + + printf("\t%s\t$%02lX\t\t\t; CASEBLOCK\n", DB, casecnt & 0xFF); + for (i = 0; i < casecnt; i++) + { + printf("\t%s\t$%04lX\n", DW, caseof[i] & 0xFFFF); + printf("\t%s\t_B%03d-*\n", DW, casetag[i]); + } +} void emit_brfls(int tag) { printf("\t%s\t$4C\t\t\t; BRFLS\t_B%03d\n", DB, tag); diff --git a/src/toolsrc/codegen.h b/src/toolsrc/codegen.h index 4861c45..f8d3695 100755 --- a/src/toolsrc/codegen.h +++ b/src/toolsrc/codegen.h @@ -134,6 +134,8 @@ void emit_indexbyte(void); void emit_indexword(void); int emit_unaryop(t_token op); int emit_op(t_token op); +void emit_select(int tag); +void emit_caseblock(int casecnt, int *caseof, int *casetag); void emit_brtru(int tag); void emit_brfls(int tag); void emit_brne(int tag); diff --git a/src/toolsrc/parse.c b/src/toolsrc/parse.c index 7d8e4d4..0ca84f5 100755 --- a/src/toolsrc/parse.c +++ b/src/toolsrc/parse.c @@ -1,5 +1,6 @@ #include #include +#include #include "plasm.h" #define LVALUE 0 #define RVALUE 1 @@ -798,7 +799,9 @@ t_opseq *parse_set(t_opseq *codeseq) int parse_stmnt(void) { int tag_prevbrk, tag_prevcnt, tag_else, tag_endif, tag_while, tag_wend, tag_repeat, tag_for, tag_choice, tag_of; - int type, addr, step, cfnvals, prev_for; + int type, addr, step, cfnvals, prev_for, constsize, casecnt; + int *caseval, *casetag; + long constval; char *idptr; t_opseq *seq, *fromseq, *toseq; @@ -913,9 +916,9 @@ int parse_stmnt(void) infor = prev_for; break; case FOR_TOKEN: + stack_loop += 2; prev_for = infor; infor = 1; - stack_loop += 2; tag_prevbrk = break_tag; break_tag = tag_new(BRANCH_TYPE); tag_for = tag_new(BRANCH_TYPE); @@ -996,17 +999,19 @@ int parse_stmnt(void) } emit_codetag(break_tag); break_tag = tag_prevbrk; - stack_loop -= 2; infor = prev_for; + stack_loop -= 2; break; case CASE_TOKEN: prev_for = infor; infor = 0; - stack_loop++; tag_prevbrk = break_tag; break_tag = tag_new(BRANCH_TYPE); tag_choice = tag_new(BRANCH_TYPE); - tag_of = tag_new(BRANCH_TYPE); + caseval = malloc(sizeof(int)*256); + casetag = malloc(sizeof(int)*256); + casecnt = 0; + //stack_loop++; if (!(seq = parse_expr(NULL, &cfnvals))) parse_error("Bad CASE expression"); if (cfnvals > 1) @@ -1015,33 +1020,53 @@ int parse_stmnt(void) while (cfnvals-- > 1) seq = gen_drop(seq); } emit_seq(seq); + emit_select(tag_choice); next_line(); while (scantoken != ENDCASE_TOKEN) { if (scantoken == OF_TOKEN) { - if (!(seq = parse_expr(NULL, &cfnvals))) - parse_error("Bad CASE OF expression"); - if (cfnvals > 1) - { - parse_warn("Expression value overflow"); - while (cfnvals-- > 1) seq = gen_drop(seq); - } - emit_seq(seq); - emit_brne(tag_choice); + constval = 0; + parse_constexpr(&constval, &constsize); + //if (!(seq = parse_expr(NULL, &cfnvals))) + // parse_error("Bad CASE OF expression"); + //if (cfnvals > 1) + //{ + // parse_warn("Expression value overflow"); + // while (cfnvals-- > 1) seq = gen_drop(seq); + //} + //emit_seq(seq); + //emit_brne(tag_choice); + //tag_choice = tag_new(BRANCH_TYPE); + tag_of = tag_new(BRANCH_TYPE); + caseval[casecnt] = constval; + casetag[casecnt] = tag_of; + casecnt++; + if (casecnt > 255) + parse_error("CASE clause overflow"); emit_codetag(tag_of); while (parse_stmnt()) next_line(); - tag_of = tag_new(BRANCH_TYPE); - if (prevstmnt != BREAK_TOKEN) // Fall through to next OF if no break - emit_brnch(tag_of); - emit_codetag(tag_choice); - tag_choice = tag_new(BRANCH_TYPE); + //tag_of = tag_new(BRANCH_TYPE); + //if (prevstmnt != BREAK_TOKEN) // Fall through to next OF if no break + // emit_brnch(tag_of); + //emit_codetag(tag_choice); + //tag_choice = tag_new(BRANCH_TYPE); } else if (scantoken == DEFAULT_TOKEN) { - emit_codetag(tag_of); - tag_of = 0; + if (prevstmnt != BREAK_TOKEN) // Fall through to next OF if no break + { + tag_of = tag_new(BRANCH_TYPE); + emit_brnch(tag_of); + } + else + tag_of = 0; + emit_codetag(tag_choice); + emit_caseblock(casecnt, caseval, casetag); + tag_choice = 0; scan(); + if (tag_of) + emit_codetag(tag_of); while (parse_stmnt()) next_line(); if (scantoken != ENDCASE_TOKEN) parse_error("Bad CASE DEFAULT clause"); @@ -1051,13 +1076,21 @@ int parse_stmnt(void) else parse_error("Bad CASE clause"); } - if (tag_of) - emit_codetag(tag_of); + if (tag_choice) + { + emit_brnch(break_tag); + emit_codetag(tag_choice); + emit_caseblock(casecnt, caseval, casetag); + } + free(caseval); + free(casetag); + //if (tag_of) + // emit_codetag(tag_of); emit_codetag(break_tag); - emit_drop(); + //emit_drop(); + //stack_loop--; break_tag = tag_prevbrk; - stack_loop--; - infor = prev_for; + infor = prev_for; break; case BREAK_TOKEN: if (break_tag) @@ -1079,7 +1112,14 @@ int parse_stmnt(void) if (infunc) { int i; - for (i = 0; i < stack_loop; i++) + + i = stack_loop; + while (i >= 2) + { + emit_drop2(); + i -= 2; + } + if (i) emit_drop(); cfnvals = 0; emit_seq(parse_list(NULL, &cfnvals)); diff --git a/src/toolsrc/parse.pla b/src/toolsrc/parse.pla index a5cab82..59be13d 100644 --- a/src/toolsrc/parse.pla +++ b/src/toolsrc/parse.pla @@ -858,9 +858,14 @@ def parse_stmnt break is RETURN_TKN if infunc - for i = 1 to stack_loop + i = stack_loop + while i >= 2 + emit_code(DROP2_CODE) + i = i - 2 + loop + if i emit_code(DROP_CODE) - next + fin seq, cfnvals = parse_list emit_seq(seq) if cfnvals > infuncvals diff --git a/src/vmsrc/apple/plvm02.s b/src/vmsrc/apple/plvm02.s index c5ade84..362b52c 100755 --- a/src/vmsrc/apple/plvm02.s +++ b/src/vmsrc/apple/plvm02.s @@ -200,7 +200,7 @@ OPTBL !WORD ZERO,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 00 02 04 06 08 !WORD LNOT,LOR,LAND,LA,LLA,CB,CW,CS ; 20 22 24 26 28 2A 2C 2E !WORD DROP,DROP2,DUP,DIVMOD,ADDI,SUBI,ANDI,ORI ; 30 32 34 36 38 3A 3C 3E !WORD ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E - !WORD BRNCH,BRNE,CALL,ICAL,ENTER,LEAVE,RET,CFFB ; 50 52 54 56 58 5A 5C 5E + !WORD BRNCH,SEL,CALL,ICAL,ENTER,LEAVE,RET,CFFB ; 50 52 54 56 58 5A 5C 5E !WORD LB,LW,LLB,LLW,LAB,LAW,DLB,DLW ; 60 62 64 66 68 6A 6C 6E !WORD SB,SW,SLB,SLW,SAB,SAW,DAB,DAW ; 70 72 74 76 78 7A 7C 7E !WORD BRGT,BRLT,INCBRLE,ADDBRLE,DECBRGE,SUBBRGE ; 80 82 84 86 88 8A 8C 8E @@ -411,7 +411,7 @@ OPXTBL !WORD ZERO,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 00 02 04 06 08 !WORD LNOT,LOR,LAND,LA,LLA,CB,CW,CSX ; 20 22 24 26 28 2A 2C 2E !WORD DROP,DROP2,DUP,DIVMOD,ADDI,SUBI,ANDI,ORI ; 30 32 34 36 38 3A 3C 3E !WORD ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E - !WORD BRNCH,BRNE,CALLX,ICALX,ENTER,LEAVEX,RETX,CFFB ; 50 52 54 56 58 5A 5C 5E + !WORD BRNCH,SEL,CALLX,ICALX,ENTER,LEAVEX,RETX,CFFB ; 50 52 54 56 58 5A 5C 5E !WORD LBX,LWX,LLBX,LLWX,LABX,LAWX,DLB,DLW ; 60 62 64 66 68 6A 6C 6E !WORD SB,SW,SLB,SLW,SAB,SAW,DAB,DAW ; 70 72 74 76 78 7A 7C 7E !WORD BRGT,BRLT,INCBRLE,ADDBRLE,DECBRGE,SUBBRGE ; 80 82 84 86 88 8A 8C 8E @@ -1309,6 +1309,50 @@ ISLT LDA ESTKL+1,X ;* ;* BRANCHES ;* +SEL INX + TYA ; FLATTEN IP + SEC + ADC IPL + STA TMPL + LDA #$00 + TAY + ADC IPH + STA TMPH ; ADD BRANCH OFFSET + LDA (TMP),Y + ;CLC ; BETTER NOT CARRY OUT OF IP+Y + ADC TMPL + STA IPL + INY + LDA (TMP),Y + ADC TMPH + STA IPH + DEY + LDA (IP),Y + STA TMPL ; CASE COUNT + INC IPL + BNE + + INC IPH ++ LDA ESTKL-1,X +CASELP CMP (IP),Y + BNE + + LDA ESTKH-1,X + INY + CMP (IP),Y + BEQ BRNCH + LDA ESTKL-1,X + DEY ++ DEC TMPL + BEQ + + INY + INY + INY + INY + BNE CASELP + INC IPH + BNE CASELP ++ INY + INY + INY FIXNEXT TYA LDY #$00 CLC @@ -1325,14 +1369,14 @@ FIXNEXT TYA ; CMP ESTKH,X ; BEQ BRNCH ; BNE NOBRNCH -BRNE INX - LDA ESTKL-1,X - CMP ESTKL,X - BNE BRNCH - LDA ESTKH-1,X - CMP ESTKH,X - BEQ NOBRNCH - BNE BRNCH +;BRNE INX +; LDA ESTKL-1,X +; CMP ESTKL,X +; BNE BRNCH +; LDA ESTKH-1,X +; CMP ESTKH,X +; BEQ NOBRNCH +; BNE BRNCH BRTRU INX LDA ESTKH-1,X ORA ESTKL-1,X diff --git a/src/vmsrc/plvm.c b/src/vmsrc/plvm.c index a28178d..ada061d 100755 --- a/src/vmsrc/plvm.c +++ b/src/vmsrc/plvm.c @@ -522,7 +522,7 @@ OPTBL: DW ZERO,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 00 02 04 06 08 0A 0C 0 DW NOT,LOR,LAND,LA,LLA,CB,CW,CS ; 20 22 24 26 28 2A 2C 2E DW DROP,DROP2,DUP,DIVMOD,ADDI,SUBI,ANDI,ORI ; 30 32 34 36 38 3A 3C 3E DW ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E - DW BRNCH,BRNE,CALL,ICAL,ENTER,LEAVE,RET,CFFB ; 50 52 54 56 58 5A 5C 5E + DW BRNCH,SEL,CALL,ICAL,ENTER,LEAVE,RET,CFFB ; 50 52 54 56 58 5A 5C 5E DW LB,LW,LLB,LLW,LAB,LAW,DLB,DLW ; 60 62 64 66 68 6A 6C 6E DW SB,SW,SLB,SLW,SAB,SAW,DAB,DAW ; 70 72 74 76 78 7A 7C 7E DW ADDBRLE,INCBRLE,SUBBRGE,DECBRGE,BRGT,BRLT ; 80 82 84 86 88 8A 8C 8E @@ -748,17 +748,21 @@ void interp(code *ip) case 0x50: // BRNCH : IP += (IP) ip += WORD_PTR(ip); break; - case 0x52: // BRNE : TOS != TOS-1 ? IP += (IP) + case 0x52: // SELECT val = POP; - if (TOS != val) + ip += WORD_PTR(ip); + parmcnt = BYTE_PTR(ip); + ip++; + while (parmcnt--) { - PUSH(val); - ip += WORD_PTR(ip); - } - else - { - PUSH(val); - ip += 2; + if (WORD_PTR(ip) == val) + { + ip += 2; + ip += WORD_PTR(ip); + parmcnt = 0; + } + else + ip += 4; } break; case 0x54: // CALL : TOFP = IP, IP = (IP) ; call From 6de120ec8952462fb0e5d95608bd5fc7d7d39527 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Mon, 5 Mar 2018 08:58:21 -0800 Subject: [PATCH 008/147] New WHEN/IS for hosted compiler --- src/toolsrc/codegen.pla | 11 ++++++++- src/toolsrc/parse.c | 24 ++------------------ src/toolsrc/parse.pla | 49 ++++++++++++++++++++++------------------ src/vmsrc/apple/plvm02.s | 5 ++-- 4 files changed, 42 insertions(+), 47 deletions(-) diff --git a/src/toolsrc/codegen.pla b/src/toolsrc/codegen.pla index acbb04c..da40fb7 100644 --- a/src/toolsrc/codegen.pla +++ b/src/toolsrc/codegen.pla @@ -171,11 +171,20 @@ def emit_daw(tag, offset)#0 emit_byte($7E) emit_addr(tag, offset) end -def emit_brne(tag)#0 +def emit_select(tag)#0 emit_pending_seq emit_byte($52) emit_reladdr(tag) end +def emit_caseblock(cnt, oflist, taglist)#0 + byte i + + emit_byte(cnt) + for i = 0 to cnt-1 + emit_word(oflist=>[i]) + emit_reladdr(taglist=>[i]) + next +end def emit_branch(tag)#0 emit_pending_seq emit_byte($50) diff --git a/src/toolsrc/parse.c b/src/toolsrc/parse.c index 0ca84f5..b315209 100755 --- a/src/toolsrc/parse.c +++ b/src/toolsrc/parse.c @@ -1011,7 +1011,6 @@ int parse_stmnt(void) caseval = malloc(sizeof(int)*256); casetag = malloc(sizeof(int)*256); casecnt = 0; - //stack_loop++; if (!(seq = parse_expr(NULL, &cfnvals))) parse_error("Bad CASE expression"); if (cfnvals > 1) @@ -1028,33 +1027,18 @@ int parse_stmnt(void) { constval = 0; parse_constexpr(&constval, &constsize); - //if (!(seq = parse_expr(NULL, &cfnvals))) - // parse_error("Bad CASE OF expression"); - //if (cfnvals > 1) - //{ - // parse_warn("Expression value overflow"); - // while (cfnvals-- > 1) seq = gen_drop(seq); - //} - //emit_seq(seq); - //emit_brne(tag_choice); - //tag_choice = tag_new(BRANCH_TYPE); tag_of = tag_new(BRANCH_TYPE); caseval[casecnt] = constval; casetag[casecnt] = tag_of; casecnt++; - if (casecnt > 255) + if (casecnt > 256) parse_error("CASE clause overflow"); emit_codetag(tag_of); while (parse_stmnt()) next_line(); - //tag_of = tag_new(BRANCH_TYPE); - //if (prevstmnt != BREAK_TOKEN) // Fall through to next OF if no break - // emit_brnch(tag_of); - //emit_codetag(tag_choice); - //tag_choice = tag_new(BRANCH_TYPE); } else if (scantoken == DEFAULT_TOKEN) { - if (prevstmnt != BREAK_TOKEN) // Fall through to next OF if no break + if (prevstmnt != BREAK_TOKEN) // Branch around caseblock if falling through { tag_of = tag_new(BRANCH_TYPE); emit_brnch(tag_of); @@ -1084,11 +1068,7 @@ int parse_stmnt(void) } free(caseval); free(casetag); - //if (tag_of) - // emit_codetag(tag_of); emit_codetag(break_tag); - //emit_drop(); - //stack_loop--; break_tag = tag_prevbrk; infor = prev_for; break; diff --git a/src/toolsrc/parse.pla b/src/toolsrc/parse.pla index 59be13d..9c759f7 100644 --- a/src/toolsrc/parse.pla +++ b/src/toolsrc/parse.pla @@ -590,6 +590,7 @@ def parse_stmnt byte type, elem_type, elem_size, i, cfnvals, prev_for word seq, fromseq, toseq, tag_prevbrk, tag_prevcnt, tag_else, tag_endif, tag_while, tag_wend word tag_repeat, tag_for, tag_choice, tag_of, idptr, addr, stepdir + word caseconst, casecnt, caseval, casetag if token <> END_TKN and token <> DONE_TKN and token <> OF_TKN and token <> DEFAULT_TKN prevstmnt = token @@ -781,11 +782,12 @@ def parse_stmnt is CASE_TKN prev_for = infor infor = FALSE - stack_loop++ tag_prevbrk = break_tag break_tag = new_tag(RELATIVE_FIXUP) tag_choice = new_tag(RELATIVE_FIXUP) - tag_of = new_tag(RELATIVE_FIXUP) + caseval = heapalloc(512) + casetag = heapalloc(512) + casecnt = 0 seq, cfnvals = parse_expr(NULL) if !seq; exit_err(ERR_INVAL|ERR_STATE); fin if cfnvals > 1 @@ -793,32 +795,34 @@ def parse_stmnt while cfnvals > 1;cfnvals--; seq = gen_op(seq, DROP_CODE); loop fin emit_seq(seq) + emit_select(tag_choice) nextln while token <> ENDCASE_TKN when token is OF_TKN - seq, cfnvals = parse_expr(NULL) - if !seq; exit_err(ERR_INVAL|ERR_STATE); fin - if cfnvals > 1 - parse_warn("Expression value overflow") - while cfnvals > 1;cfnvals--; seq = gen_op(seq, DROP_CODE); loop - fin - emit_seq(seq) - emit_brne(tag_choice) + caseconst, drop, drop = parse_constexpr + tag_of = new_tag(RELATIVE_FIXUP) + caseval=>[casecnt] = caseconst + casetag=>[casecnt] = tag_of + casecnt++ + if casecnt > 256; exit_err(ERR_OVER|ERR_STATE); fin emit_tag(tag_of) while parse_stmnt nextln loop - tag_of = new_tag(RELATIVE_FIXUP) - if prevstmnt <> BREAK_TKN // Fall through to next OF if no break + break + is DEFAULT_TKN + tag_of = 0 + if prevstmnt <> BREAK_TKN // Branch around caseblock if falling through + tag_of = new_tag(RELATIVE_FIXUP) emit_branch(tag_of) fin emit_tag(tag_choice) - tag_choice = new_tag(RELATIVE_FIXUP) - break - is DEFAULT_TKN - emit_tag(tag_of) - tag_of = 0 + emit_caseblock(casecnt, caseval, casetag) + tag_choice = 0 + if tag_of + emit_tag(tag_of) + fin scan while parse_stmnt nextln @@ -832,14 +836,15 @@ def parse_stmnt exit_err(ERR_MISS|ERR_CLOSE|ERR_STATE) wend loop - if (tag_of) - emit_tag(tag_of) + if tag_choice + emit_branch(break_tag) + emit_tag(tag_choice) + emit_caseblock(casecnt, caseval, casetag) fin + heaprelease(caseval) emit_tag(break_tag) - emit_code(DROP_CODE) break_tag = tag_prevbrk - stack_loop-- - infor = prev_for + infor = prev_for break is BREAK_TKN if break_tag diff --git a/src/vmsrc/apple/plvm02.s b/src/vmsrc/apple/plvm02.s index 362b52c..b9f7d5a 100755 --- a/src/vmsrc/apple/plvm02.s +++ b/src/vmsrc/apple/plvm02.s @@ -1328,6 +1328,7 @@ SEL INX STA IPH DEY LDA (IP),Y + BEQ ++ STA TMPL ; CASE COUNT INC IPL BNE + @@ -1358,9 +1359,9 @@ FIXNEXT TYA CLC ADC IPL STA IPL - BCC + + BCC ++ INC IPH -+ JMP NEXTOP +++ JMP NEXTOP ;BREQ INX ; LDA ESTKL-1,X ; CMP ESTKL,X From eff01c5f12f5b20d0ca3b666099e754c21a01fb9 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Mon, 5 Mar 2018 10:55:19 -0800 Subject: [PATCH 009/147] Short circuit AND/OR --- src/toolsrc/codegen.c | 48 +++++++++++++++++++------------ src/toolsrc/codegen.h | 14 ++++++--- src/toolsrc/codegen.pla | 18 +++++++++--- src/toolsrc/codeopt.pla | 16 +++++------ src/toolsrc/codeseq.plh | 6 ++-- src/toolsrc/parse.c | 50 ++++++++++++++++++++++++++------ src/toolsrc/parse.pla | 27 +++++++++++------ src/toolsrc/plasm.pla | 8 +++--- src/vmsrc/apple/plvm02.s | 62 ++++++++++++++++++---------------------- src/vmsrc/plvm.c | 40 ++++++++++++++++++++------ 10 files changed, 190 insertions(+), 99 deletions(-) diff --git a/src/toolsrc/codegen.c b/src/toolsrc/codegen.c index 9ab4119..ade048e 100755 --- a/src/toolsrc/codegen.c +++ b/src/toolsrc/codegen.c @@ -806,10 +806,16 @@ void emit_brnch(int tag) printf("\t%s\t$50\t\t\t; BRNCH\t_B%03d\n", DB, tag); printf("\t%s\t_B%03d-*\n", DW, tag); } -void emit_brne(int tag) +void emit_brand(int tag) { emit_pending_seq(); - printf("\t%s\t$52\t\t\t; BRNE\t_B%03d\n", DB, tag); + printf("\t%s\t$8C\t\t\t; BRAND\t_B%03d\n", DB, tag); + printf("\t%s\t_B%03d-*\n", DW, tag); +} +void emit_bror(int tag) +{ + emit_pending_seq(); + printf("\t%s\t$8E\t\t\t; BROR\t_B%03d\n", DB, tag); printf("\t%s\t_B%03d-*\n", DW, tag); } void emit_brgt(int tag) @@ -991,12 +997,12 @@ int emit_op(t_token op) case LE_TOKEN: printf("\t%s\t$4A\t\t\t; ISLE\n", DB); break; - case LOGIC_OR_TOKEN: - printf("\t%s\t$22\t\t\t; LOR\n", DB); - break; - case LOGIC_AND_TOKEN: - printf("\t%s\t$24\t\t\t; LAND\n", DB); - break; +// case LOGIC_OR_TOKEN: +// printf("\t%s\t$22\t\t\t; LOR\n", DB); +// break; +// case LOGIC_AND_TOKEN: +// printf("\t%s\t$24\t\t\t; LAND\n", DB); +// break; case COMMA_TOKEN: break; default: @@ -1268,14 +1274,14 @@ int crunch_seq(t_opseq **seq, int pass) op->val = op->val <= opnext->val ? 1 : 0; freeops = 2; break; - case BINARY_CODE(LOGIC_OR_TOKEN): - op->val = op->val || opnext->val ? 1 : 0; - freeops = 2; - break; - case BINARY_CODE(LOGIC_AND_TOKEN): - op->val = op->val && opnext->val ? 1 : 0; - freeops = 2; - break; +// case BINARY_CODE(LOGIC_OR_TOKEN): +// op->val = op->val || opnext->val ? 1 : 0; +// freeops = 2; +// break; +// case BINARY_CODE(LOGIC_AND_TOKEN): +// op->val = op->val && opnext->val ? 1 : 0; +// freeops = 2; +// break; } // End of collapse constant operation if ((pass > 0) && (freeops == 0) && (op->val != 0)) @@ -1666,8 +1672,8 @@ int emit_pending_seq() case LT_CODE: case GT_CODE: case LE_CODE: - case LOGIC_OR_CODE: - case LOGIC_AND_CODE: +// case LOGIC_OR_CODE: +// case LOGIC_AND_CODE: emit_op(op->code); break; case CONST_CODE: @@ -1763,6 +1769,12 @@ int emit_pending_seq() case BRNCH_CODE: emit_brnch(op->tag); break; + case BRAND_CODE: + emit_brand(op->tag); + break; + case BROR_CODE: + emit_bror(op->tag); + break; case BRFALSE_CODE: emit_brfls(op->tag); break; diff --git a/src/toolsrc/codegen.h b/src/toolsrc/codegen.h index f8d3695..32b3dca 100755 --- a/src/toolsrc/codegen.h +++ b/src/toolsrc/codegen.h @@ -31,8 +31,8 @@ typedef struct _opseq { #define LT_CODE (0x0200|LT_TOKEN) #define GT_CODE (0x0200|GT_TOKEN) #define LE_CODE (0x0200|LE_TOKEN) -#define LOGIC_OR_CODE (0x0200|LOGIC_OR_TOKEN) -#define LOGIC_AND_CODE (0x0200|LOGIC_AND_TOKEN) +//#define LOGIC_OR_CODE (0x0200|LOGIC_OR_TOKEN) +//#define LOGIC_AND_CODE (0x0200|LOGIC_AND_TOKEN) #define CONST_CODE 0x0300 #define STR_CODE 0x0301 #define LB_CODE 0x0302 @@ -66,8 +66,10 @@ typedef struct _opseq { #define BRNCH_CODE 0x0320 #define BRFALSE_CODE 0x0321 #define BRTRUE_CODE 0x0322 -#define CODETAG_CODE 0x0323 -#define NOP_CODE 0x0324 +#define BRAND_CODE 0x323 +#define BROR_CODE 0x324 +#define CODETAG_CODE 0x0325 +#define NOP_CODE 0x0326 #define gen_uop(seq,op) gen_seq(seq,UNARY_CODE(op),0,0,0,0) #define gen_op(seq,op) gen_seq(seq,BINARY_CODE(op),0,0,0,0) @@ -83,6 +85,8 @@ typedef struct _opseq { #define gen_sw(seq) gen_seq(seq,SW_CODE,0,0,0,0) #define gen_icall(seq) gen_seq(seq,ICAL_CODE,0,0,0,0) #define gen_drop(seq) gen_seq(seq,DROP_CODE,0,0,0,0) +#define gen_brand(seq,tag) gen_seq(seq,BRAND_CODE,0,tag,0,0) +#define gen_bror(seq,tag) gen_seq(seq,BROR_CODE,0,tag,0,0) #define gen_brfls(seq,tag) gen_seq(seq,BRFALSE_CODE,0,tag,0,0) #define gen_brtru(seq,tag) gen_seq(seq,BRTRUE_CODE,0,tag,0,0) #define gen_brnch(seq,tag) gen_seq(seq,BRNCH_CODE,0,tag,0,0) @@ -136,6 +140,8 @@ int emit_unaryop(t_token op); int emit_op(t_token op); void emit_select(int tag); void emit_caseblock(int casecnt, int *caseof, int *casetag); +void emit_brand(int tag); +void emit_bror(int tag); void emit_brtru(int tag); void emit_brfls(int tag); void emit_brne(int tag); diff --git a/src/toolsrc/codegen.pla b/src/toolsrc/codegen.pla index da40fb7..f0c1130 100644 --- a/src/toolsrc/codegen.pla +++ b/src/toolsrc/codegen.pla @@ -190,6 +190,16 @@ def emit_branch(tag)#0 emit_byte($50) emit_reladdr(tag) end +def emit_brand(tag)#0 + emit_pending_seq + emit_byte($8C) + emit_reladdr(tag) +end +def emit_bror(tag)#0 + emit_pending_seq + emit_byte($8E) + emit_reladdr(tag) +end def emit_brgt(tag)#0 emit_pending_seq emit_byte($80) @@ -788,10 +798,10 @@ def gen_bop(seq, tkn) code = $44; break is LE_TKN code = $4A; break - is LOGIC_OR_TKN - code = $22; break - is LOGIC_AND_TKN - code = $24; break + //is LOGIC_OR_TKN + // code = $22; break + //is LOGIC_AND_TKN + // code = $24; break otherwise exit_err(ERR_INVAL|ERR_SYNTAX) wend diff --git a/src/toolsrc/codeopt.pla b/src/toolsrc/codeopt.pla index b49e37d..5978d22 100644 --- a/src/toolsrc/codeopt.pla +++ b/src/toolsrc/codeopt.pla @@ -200,14 +200,14 @@ def crunch_seq(seq, pass) op=>opval = op=>opval <= nextop=>opval freeops = 2 break - is LOGIC_OR_CODE - op=>opval = op=>opval or nextop=>opval - freeops = 2 - break - is LOGIC_AND_CODE - op=>opval = op=>opval and nextop=>opval - freeops = 2 - break +// is LOGIC_OR_CODE +// op=>opval = op=>opval or nextop=>opval +// freeops = 2 +// break +// is LOGIC_AND_CODE +// op=>opval = op=>opval and nextop=>opval +// freeops = 2 +// break wend // End of collapse constant operation fin if pass and not freeops and op=>opval diff --git a/src/toolsrc/codeseq.plh b/src/toolsrc/codeseq.plh index cf14e2d..5efa4c6 100644 --- a/src/toolsrc/codeseq.plh +++ b/src/toolsrc/codeseq.plh @@ -30,8 +30,8 @@ const SHL_CODE = $1A const SHR_CODE = $1C const INDEXW_CODE = $1E const LOGIC_NOT_CODE = $20 -const LOGIC_OR_CODE = $22 -const LOGIC_AND_CODE = $24 +//const LOGIC_OR_CODE = $22 +//const LOGIC_AND_CODE = $24 const DROP_CODE = $30 const DROP2_CODE = $32 const DUP_CODE = $34 @@ -79,6 +79,8 @@ const RELATIVE_GROUP = $05 const BRFALSE_CODE = $4C const BRTRUE_CODE = $4E const BRNCH_CODE = $50 +const BRAND_CODE = $8C +const BROR_CODE = $8E // // Code tag address group // diff --git a/src/toolsrc/parse.c b/src/toolsrc/parse.c index b315209..edd75c8 100755 --- a/src/toolsrc/parse.c +++ b/src/toolsrc/parse.c @@ -25,8 +25,8 @@ t_token binary_ops_table[] = { OR_TOKEN, GT_TOKEN, GE_TOKEN, LT_TOKEN, LE_TOKEN, EQ_TOKEN, NE_TOKEN, - LOGIC_AND_TOKEN, - LOGIC_OR_TOKEN +// LOGIC_AND_TOKEN, +// LOGIC_OR_TOKEN /* Lowest precedence */ }; t_token binary_ops_precedence[] = { @@ -39,8 +39,8 @@ t_token binary_ops_precedence[] = { 6, 7, 7, 7, 7, 8, 8, - 9, - 10 +// 9, +// 10 /* Lowest precedence */ }; @@ -730,14 +730,48 @@ t_opseq *parse_expr(t_opseq *codeseq, int *stackdepth) if (stackdepth) (*stackdepth)--; } - /* - * Look for ternary operator - */ - if (scantoken == TERNARY_TOKEN) + if (scantoken == LOGIC_AND_TOKEN) + { + int tag_and; + int stackdepth1; + + /* + * Short-circuit AND + */ + if (*stackdepth != 1) + parse_error("AND must evaluate to single value"); + tag_and = tag_new(BRANCH_TYPE); + codeseq = gen_brand(codeseq, tag_and); + codeseq = parse_expr(codeseq, &stackdepth1); + if (stackdepth1 != *stackdepth) + parse_error("Inconsistent AND value counts"); + codeseq = gen_codetag(codeseq, tag_and); + } + else if (scantoken == LOGIC_OR_TOKEN) + { + int tag_or; + int stackdepth1; + + /* + * Short-circuit OR + */ + if (*stackdepth != 1) + parse_error("OR must evaluate to single value"); + tag_or = tag_new(BRANCH_TYPE); + codeseq = gen_bror(codeseq, tag_or); + codeseq = parse_expr(codeseq, &stackdepth1); + if (stackdepth1 != *stackdepth) + parse_error("Inconsistent AND value counts"); + codeseq = gen_codetag(codeseq, tag_or); + } + else if (scantoken == TERNARY_TOKEN) { int tag_else, tag_endtri; int stackdepth1; + /* + * Look for ternary operator + */ if (*stackdepth != 1) parse_error("Ternary op must evaluate to single value"); tag_else = tag_new(BRANCH_TYPE); diff --git a/src/toolsrc/parse.pla b/src/toolsrc/parse.pla index 9c759f7..eadc9d9 100644 --- a/src/toolsrc/parse.pla +++ b/src/toolsrc/parse.pla @@ -494,7 +494,7 @@ end def parse_expr(codeseq)#2 byte stackdepth, matchdepth, stkdepth1, prevmatch, matchop, i word optos - word tag_else, tag_endtri + word tag_else, tag_endop stackdepth = 0 matchop = 0 @@ -524,21 +524,32 @@ def parse_expr(codeseq)#2 codeseq = gen_bop(codeseq, pop_op) stackdepth-- loop - // - // Look for ternary operator - // - if token == TERNARY_TKN + if token == LOGIC_AND_TKN + if stackdepth <> 1; exit_err(ERR_OVER|ERR_SYNTAX); fin + tag_endop = new_tag(RELATIVE_FIXUP) + codeseq = gen_oprel(codeseq, BRAND_CODE, tag_endop) + codeseq, stkdepth1 = parse_expr(codeseq) + if stkdepth1 <> stackdepth; exit_err(ERR_INVAL|ERR_CODE); fin + codeseq = gen_ctag(codeseq, tag_endop) + elsif token == LOGIC_OR_TKN + if stackdepth <> 1; exit_err(ERR_OVER|ERR_SYNTAX); fin + tag_endop = new_tag(RELATIVE_FIXUP) + codeseq = gen_oprel(codeseq, BROR_CODE, tag_endop) + codeseq, stkdepth1 = parse_expr(codeseq) + if stkdepth1 <> stackdepth; exit_err(ERR_INVAL|ERR_CODE); fin + codeseq = gen_ctag(codeseq, tag_endop) + elsif token == TERNARY_TKN if stackdepth <> 1; exit_err(ERR_OVER|ERR_SYNTAX); fin tag_else = new_tag(RELATIVE_FIXUP) - tag_endtri = new_tag(RELATIVE_FIXUP) + tag_endop = new_tag(RELATIVE_FIXUP) codeseq = gen_oprel(codeseq, BRFALSE_CODE, tag_else) codeseq, stkdepth1 = parse_expr(codeseq) if token <> TRIELSE_TKN; exit_err(ERR_MISS|ERR_SYNTAX); fin - codeseq = gen_oprel(codeseq, BRNCH_CODE, tag_endtri) + codeseq = gen_oprel(codeseq, BRNCH_CODE, tag_endop) codeseq = gen_ctag(codeseq, tag_else) codeseq, stackdepth = parse_expr(codeseq) if stkdepth1 <> stackdepth; exit_err(ERR_INVAL|ERR_CODE); fin - codeseq = gen_ctag(codeseq, tag_endtri) + codeseq = gen_ctag(codeseq, tag_endop) fin return codeseq, stackdepth end diff --git a/src/toolsrc/plasm.pla b/src/toolsrc/plasm.pla index fdb5aa2..7c6cf82 100644 --- a/src/toolsrc/plasm.pla +++ b/src/toolsrc/plasm.pla @@ -194,8 +194,8 @@ byte = EOR_TKN byte = OR_TKN byte = GT_TKN, GE_TKN, LT_TKN, LE_TKN byte = EQ_TKN, NE_TKN -byte = LOGIC_AND_TKN -byte = LOGIC_OR_TKN +//byte = LOGIC_AND_TKN +//byte = LOGIC_OR_TKN // Lowest precedence byte[] bops_prec // Highest precedence byte = 1, 1, 1 @@ -206,8 +206,8 @@ byte = 5 byte = 6 byte = 7, 7, 7, 7 byte = 8, 8 -byte = 9 -byte = 10 +//byte = 9 +//byte = 10 // Lowest precedence byte[16] opstack byte[16] precstack diff --git a/src/vmsrc/apple/plvm02.s b/src/vmsrc/apple/plvm02.s index b9f7d5a..54f7880 100755 --- a/src/vmsrc/apple/plvm02.s +++ b/src/vmsrc/apple/plvm02.s @@ -195,15 +195,15 @@ VMCORE = * !ALIGN 255,0 ;OPTBL !WORD CONST,CONST,CONST,CONST,CONST,CONST,CONST,CONST ; 00 02 04 06 08 0A 0C 0E ; !WORD CONST,CONST,CONST,CONST,CONST,CONST,CONST,CONST ; 10 12 14 16 18 1A 1C 1E -OPTBL !WORD ZERO,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 00 02 04 06 08 0A 0C 0E - !WORD NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 10 12 14 16 18 1A 1C 1E - !WORD LNOT,LOR,LAND,LA,LLA,CB,CW,CS ; 20 22 24 26 28 2A 2C 2E - !WORD DROP,DROP2,DUP,DIVMOD,ADDI,SUBI,ANDI,ORI ; 30 32 34 36 38 3A 3C 3E - !WORD ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E - !WORD BRNCH,SEL,CALL,ICAL,ENTER,LEAVE,RET,CFFB ; 50 52 54 56 58 5A 5C 5E - !WORD LB,LW,LLB,LLW,LAB,LAW,DLB,DLW ; 60 62 64 66 68 6A 6C 6E - !WORD SB,SW,SLB,SLW,SAB,SAW,DAB,DAW ; 70 72 74 76 78 7A 7C 7E - !WORD BRGT,BRLT,INCBRLE,ADDBRLE,DECBRGE,SUBBRGE ; 80 82 84 86 88 8A 8C 8E +OPTBL !WORD ZERO,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 00 02 04 06 08 0A 0C 0E + !WORD NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 10 12 14 16 18 1A 1C 1E + !WORD LNOT,LOR,LAND,LA,LLA,CB,CW,CS ; 20 22 24 26 28 2A 2C 2E + !WORD DROP,DROP2,DUP,DIVMOD,ADDI,SUBI,ANDI,ORI ; 30 32 34 36 38 3A 3C 3E + !WORD ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E + !WORD BRNCH,SEL,CALL,ICAL,ENTER,LEAVE,RET,CFFB ; 50 52 54 56 58 5A 5C 5E + !WORD LB,LW,LLB,LLW,LAB,LAW,DLB,DLW ; 60 62 64 66 68 6A 6C 6E + !WORD SB,SW,SLB,SLW,SAB,SAW,DAB,DAW ; 70 72 74 76 78 7A 7C 7E + !WORD BRGT,BRLT,INCBRLE,ADDBRLE,DECBRGE,SUBBRGE,BRAND,BROR ; 80 82 84 86 88 8A 8C 8E ;* ;* ;* ENTER INTO BYTECODE INTERPRETER @@ -406,15 +406,15 @@ LCDEFCMD = *-28 ; DEFCMD IN LC MEMORY !ALIGN 255,0 ;OPXTBL !WORD CONST,CONST,CONST,CONST,CONST,CONST,CONST,CONST ; 00 02 04 06 08 0A 0C 0E ; !WORD CONST,CONST,CONST,CONST,CONST,CONST,CONST,CONST ; 10 12 14 16 18 1A 1C 1E -OPXTBL !WORD ZERO,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 00 02 04 06 08 0A 0C 0E - !WORD NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 10 12 14 16 18 1A 1C 1E - !WORD LNOT,LOR,LAND,LA,LLA,CB,CW,CSX ; 20 22 24 26 28 2A 2C 2E - !WORD DROP,DROP2,DUP,DIVMOD,ADDI,SUBI,ANDI,ORI ; 30 32 34 36 38 3A 3C 3E - !WORD ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E - !WORD BRNCH,SEL,CALLX,ICALX,ENTER,LEAVEX,RETX,CFFB ; 50 52 54 56 58 5A 5C 5E - !WORD LBX,LWX,LLBX,LLWX,LABX,LAWX,DLB,DLW ; 60 62 64 66 68 6A 6C 6E - !WORD SB,SW,SLB,SLW,SAB,SAW,DAB,DAW ; 70 72 74 76 78 7A 7C 7E - !WORD BRGT,BRLT,INCBRLE,ADDBRLE,DECBRGE,SUBBRGE ; 80 82 84 86 88 8A 8C 8E +OPXTBL !WORD ZERO,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 00 02 04 06 08 0A 0C 0E + !WORD NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 10 12 14 16 18 1A 1C 1E + !WORD LNOT,LOR,LAND,LA,LLA,CB,CW,CSX ; 20 22 24 26 28 2A 2C 2E + !WORD DROP,DROP2,DUP,DIVMOD,ADDI,SUBI,ANDI,ORI ; 30 32 34 36 38 3A 3C 3E + !WORD ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E + !WORD BRNCH,SEL,CALLX,ICALX,ENTER,LEAVEX,RETX,CFFB ; 50 52 54 56 58 5A 5C 5E + !WORD LBX,LWX,LLBX,LLWX,LABX,LAWX,DLB,DLW ; 60 62 64 66 68 6A 6C 6E + !WORD SB,SW,SLB,SLW,SAB,SAW,DAB,DAW ; 70 72 74 76 78 7A 7C 7E + !WORD BRGT,BRLT,INCBRLE,ADDBRLE,DECBRGE,SUBBRGE,BRAND,BROR ; 80 82 84 86 88 8A 8C 8E ;* ;* ADD TOS TO TOS-1 ;* @@ -1362,22 +1362,16 @@ FIXNEXT TYA BCC ++ INC IPH ++ JMP NEXTOP -;BREQ INX -; LDA ESTKL-1,X -; CMP ESTKL,X -; BNE NOBRNCH -; LDA ESTKH-1,X -; CMP ESTKH,X -; BEQ BRNCH -; BNE NOBRNCH -;BRNE INX -; LDA ESTKL-1,X -; CMP ESTKL,X -; BNE BRNCH -; LDA ESTKH-1,X -; CMP ESTKH,X -; BEQ NOBRNCH -; BNE BRNCH +BRAND LDA ESTKL,X + ORA ESTKH,X + BEQ BRNCH + INX ; DROP LEFT HALF OF AND + BNE NOBRNCH +BROR LDA ESTKL,X + ORA ESTKH,X + BNE BRNCH + INX ; DROP LEFT HALF OF OR + BNE NOBRNCH BRTRU INX LDA ESTKH-1,X ORA ESTKL-1,X diff --git a/src/vmsrc/plvm.c b/src/vmsrc/plvm.c index ada061d..3beff8a 100755 --- a/src/vmsrc/plvm.c +++ b/src/vmsrc/plvm.c @@ -517,15 +517,15 @@ void call(uword pc) /* * OPCODE TABLE * -OPTBL: DW ZERO,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 00 02 04 06 08 0A 0C 0E - DW NEG,COMP,AND,IOR,XOR,SHL,SHR,IDXW ; 10 12 14 16 18 1A 1C 1E - DW NOT,LOR,LAND,LA,LLA,CB,CW,CS ; 20 22 24 26 28 2A 2C 2E - DW DROP,DROP2,DUP,DIVMOD,ADDI,SUBI,ANDI,ORI ; 30 32 34 36 38 3A 3C 3E - DW ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E - DW BRNCH,SEL,CALL,ICAL,ENTER,LEAVE,RET,CFFB ; 50 52 54 56 58 5A 5C 5E - DW LB,LW,LLB,LLW,LAB,LAW,DLB,DLW ; 60 62 64 66 68 6A 6C 6E - DW SB,SW,SLB,SLW,SAB,SAW,DAB,DAW ; 70 72 74 76 78 7A 7C 7E - DW ADDBRLE,INCBRLE,SUBBRGE,DECBRGE,BRGT,BRLT ; 80 82 84 86 88 8A 8C 8E +OPTBL: DW ZERO,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 00 02 04 06 08 0A 0C 0E + DW NEG,COMP,AND,IOR,XOR,SHL,SHR,IDXW ; 10 12 14 16 18 1A 1C 1E + DW NOT,LOR,LAND,LA,LLA,CB,CW,CS ; 20 22 24 26 28 2A 2C 2E + DW DROP,DROP2,DUP,DIVMOD,ADDI,SUBI,ANDI,ORI ; 30 32 34 36 38 3A 3C 3E + DW ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E + DW BRNCH,SEL,CALL,ICAL,ENTER,LEAVE,RET,CFFB ; 50 52 54 56 58 5A 5C 5E + DW LB,LW,LLB,LLW,LAB,LAW,DLB,DLW ; 60 62 64 66 68 6A 6C 6E + DW SB,SW,SLB,SLW,SAB,SAW,DAB,DAW ; 70 72 74 76 78 7A 7C 7E + DW ADDBRLE,INCBRLE,SUBBRGE,DECBRGE,BRGT,BRLT ; 80 82 84 86 88 8A 8C 8E DW BRGT,BRLT,INCBRLE,ADDBRLE,DECBRGE,SUBBRGE ; 80 82 84 86 88 8A 8C 8E */ void interp(code *ip) @@ -973,6 +973,28 @@ void interp(code *ip) ip += 2; } break; + case 0x8C: // BRAND : SHORT CIRCUIT AND + if (TOS) // EVALUATE RIGHT HAND OF AND + { + POP; + ip += 2; + } + else // MUST BE FALSE, SKIP RIGHT HAND + { + ip += WORD_PTR(ip); + } + break; + case 0x8E: // BROR : SHORT CIRCUIT OR + if (!TOS) // EVALUATE RIGHT HAND OF OR + { + POP; + ip += 2; + } + else // MUST BE TRUE, SKIP RIGHT HAND + { + ip += WORD_PTR(ip); + } + break; /* * Odd codes and everything else are errors. */ From 334bf1ec4dca0dbefd35985586c12248c71c455a Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Mon, 5 Mar 2018 11:38:16 -0800 Subject: [PATCH 010/147] Nybble constants encoded in opcode --- src/toolsrc/codegen.c | 54 ++++++++++++++++---------------- src/toolsrc/codegen.pla | 67 +++++++++++++++++++++------------------- src/toolsrc/codeseq.plh | 36 ++++++++++----------- src/toolsrc/ed.pla | 2 +- src/toolsrc/plasm.pla | 2 +- src/vmsrc/apple/cmd.pla | 4 +-- src/vmsrc/apple/plvm02.s | 40 +++++++++++++----------- 7 files changed, 107 insertions(+), 98 deletions(-) diff --git a/src/toolsrc/codegen.c b/src/toolsrc/codegen.c index ade048e..dc8df89 100755 --- a/src/toolsrc/codegen.c +++ b/src/toolsrc/codegen.c @@ -600,8 +600,10 @@ void emit_codetag(int tag) void emit_const(int cval) { emit_pending_seq(); - if (cval == 0x0000) - printf("\t%s\t$00\t\t\t; ZERO\n", DB); + if ((cval & 0xFFFF) == 0xFFFF) + printf("\t%s\t$80\t\t\t; MINUS ONE\n", DB); + else if ((cval & 0xFFF0) == 0x0000) + printf("\t%s\t$%02X\t\t\t; CN\t%d\n", DB, cval*2, cval); else if ((cval & 0xFF00) == 0x0000) printf("\t%s\t$2A,$%02X\t\t\t; CB\t%d\n", DB, cval, cval); else if ((cval & 0xFF00) == 0xFF00) @@ -767,11 +769,11 @@ void emit_globaladdr(int tag, int offset, int type) } void emit_indexbyte(void) { - printf("\t%s\t$02\t\t\t; IDXB\n", DB); + printf("\t%s\t$82\t\t\t; IDXB\n", DB); } void emit_indexword(void) { - printf("\t%s\t$1E\t\t\t; IDXW\n", DB); + printf("\t%s\t$9E\t\t\t; IDXW\n", DB); } void emit_select(int tag) { @@ -809,49 +811,49 @@ void emit_brnch(int tag) void emit_brand(int tag) { emit_pending_seq(); - printf("\t%s\t$8C\t\t\t; BRAND\t_B%03d\n", DB, tag); + printf("\t%s\t$AC\t\t\t; BRAND\t_B%03d\n", DB, tag); printf("\t%s\t_B%03d-*\n", DW, tag); } void emit_bror(int tag) { emit_pending_seq(); - printf("\t%s\t$8E\t\t\t; BROR\t_B%03d\n", DB, tag); + printf("\t%s\t$AE\t\t\t; BROR\t_B%03d\n", DB, tag); printf("\t%s\t_B%03d-*\n", DW, tag); } void emit_brgt(int tag) { emit_pending_seq(); - printf("\t%s\t$80\t\t\t; BRGT\t_B%03d\n", DB, tag); + printf("\t%s\t$A0\t\t\t; BRGT\t_B%03d\n", DB, tag); printf("\t%s\t_B%03d-*\n", DW, tag); } void emit_brlt(int tag) { emit_pending_seq(); - printf("\t%s\t$82\t\t\t; BRLT\t_B%03d\n", DB, tag); + printf("\t%s\t$A2\t\t\t; BRLT\t_B%03d\n", DB, tag); printf("\t%s\t_B%03d-*\n", DW, tag); } void emit_incbrle(int tag) { emit_pending_seq(); - printf("\t%s\t$84\t\t\t; INCBRLE\t_B%03d\n", DB, tag); + printf("\t%s\t$A4\t\t\t; INCBRLE\t_B%03d\n", DB, tag); printf("\t%s\t_B%03d-*\n", DW, tag); } void emit_addbrle(int tag) { emit_pending_seq(); - printf("\t%s\t$86\t\t\t; BRLE\t_B%03d\n", DB, tag); + printf("\t%s\t$A6\t\t\t; BRLE\t_B%03d\n", DB, tag); printf("\t%s\t_B%03d-*\n", DW, tag); } void emit_decbrge(int tag) { emit_pending_seq(); - printf("\t%s\t$88\t\t\t; DECBRGE\t_B%03d\n", DB, tag); + printf("\t%s\t$A8\t\t\t; DECBRGE\t_B%03d\n", DB, tag); printf("\t%s\t_B%03d-*\n", DW, tag); } void emit_subbrge(int tag) { emit_pending_seq(); - printf("\t%s\t$8A\t\t\t; BRGE\t_B%03d\n", DB, tag); + printf("\t%s\t$AA\t\t\t; BRGE\t_B%03d\n", DB, tag); printf("\t%s\t_B%03d-*\n", DW, tag); } void emit_call(int tag, int type) @@ -918,19 +920,19 @@ int emit_unaryop(t_token op) switch (op) { case NEG_TOKEN: - printf("\t%s\t$10\t\t\t; NEG\n", DB); + printf("\t%s\t$90\t\t\t; NEG\n", DB); break; case COMP_TOKEN: - printf("\t%s\t$12\t\t\t; COMP\n", DB); + printf("\t%s\t$92\t\t\t; COMP\n", DB); break; case LOGIC_NOT_TOKEN: printf("\t%s\t$20\t\t\t; NOT\n", DB); break; case INC_TOKEN: - printf("\t%s\t$0C\t\t\t; INCR\n", DB); + printf("\t%s\t$8C\t\t\t; INCR\n", DB); break; case DEC_TOKEN: - printf("\t%s\t$0E\t\t\t; DECR\n", DB); + printf("\t%s\t$8E\t\t\t; DECR\n", DB); break; case BPTR_TOKEN: emit_lb(); @@ -950,34 +952,34 @@ int emit_op(t_token op) switch (op) { case MUL_TOKEN: - printf("\t%s\t$06\t\t\t; MUL\n", DB); + printf("\t%s\t$86\t\t\t; MUL\n", DB); break; case DIV_TOKEN: - printf("\t%s\t$08\t\t\t; DIV\n", DB); + printf("\t%s\t$88\t\t\t; DIV\n", DB); break; case MOD_TOKEN: - printf("\t%s\t$0A\t\t\t; MOD\n", DB); + printf("\t%s\t$8A\t\t\t; MOD\n", DB); break; case ADD_TOKEN: - printf("\t%s\t$02\t\t\t; ADD\n", DB); + printf("\t%s\t$82\t\t\t; ADD\n", DB); break; case SUB_TOKEN: - printf("\t%s\t$04\t\t\t; SUB\n", DB); + printf("\t%s\t$84\t\t\t; SUB\n", DB); break; case SHL_TOKEN: - printf("\t%s\t$1A\t\t\t; SHL\n", DB); + printf("\t%s\t$9A\t\t\t; SHL\n", DB); break; case SHR_TOKEN: - printf("\t%s\t$1C\t\t\t; SHR\n", DB); + printf("\t%s\t$9C\t\t\t; SHR\n", DB); break; case AND_TOKEN: - printf("\t%s\t$14\t\t\t; AND\n", DB); + printf("\t%s\t$94\t\t\t; AND\n", DB); break; case OR_TOKEN: - printf("\t%s\t$16\t\t\t; IOR\n", DB); + printf("\t%s\t$96\t\t\t; IOR\n", DB); break; case EOR_TOKEN: - printf("\t%s\t$18\t\t\t; XOR\n", DB); + printf("\t%s\t$98\t\t\t; XOR\n", DB); break; case EQ_TOKEN: printf("\t%s\t$40\t\t\t; ISEQ\n", DB); diff --git a/src/toolsrc/codegen.pla b/src/toolsrc/codegen.pla index f0c1130..136b5c3 100644 --- a/src/toolsrc/codegen.pla +++ b/src/toolsrc/codegen.pla @@ -132,8 +132,10 @@ def emit_codeseg#0 end def emit_const(cval)#0 emit_pending_seq - if cval == $0000 // ZERO - emit_byte($00) + if cval == $FFFF // MINUS ONE + emit_byte($80) + elsif cval & $FFF0 == $0000 // Constant NYBBLE + emit_byte(cval*2) elsif cval & $FF00 == $0000 // Constant BYTE emit_byte($2A) emit_byte(cval) @@ -179,6 +181,7 @@ end def emit_caseblock(cnt, oflist, taglist)#0 byte i + emit_pending_seq emit_byte(cnt) for i = 0 to cnt-1 emit_word(oflist=>[i]) @@ -190,44 +193,44 @@ def emit_branch(tag)#0 emit_byte($50) emit_reladdr(tag) end -def emit_brand(tag)#0 - emit_pending_seq - emit_byte($8C) - emit_reladdr(tag) -end -def emit_bror(tag)#0 - emit_pending_seq - emit_byte($8E) - emit_reladdr(tag) -end def emit_brgt(tag)#0 emit_pending_seq - emit_byte($80) + emit_byte($A0) emit_reladdr(tag) end def emit_brlt(tag)#0 emit_pending_seq - emit_byte($82) + emit_byte($A2) emit_reladdr(tag) end def emit_incbrle(tag)#0 emit_pending_seq - emit_byte($84) + emit_byte($A4) emit_reladdr(tag) end def emit_addbrle(tag)#0 emit_pending_seq - emit_byte($86) + emit_byte($A6) emit_reladdr(tag) end def emit_decbrge(tag)#0 emit_pending_seq - emit_byte($88) + emit_byte($A8) emit_reladdr(tag) end def emit_subbrge(tag)#0 emit_pending_seq - emit_byte($8A) + emit_byte($AA) + emit_reladdr(tag) +end +def emit_brand(tag)#0 + emit_pending_seq + emit_byte($AC) + emit_reladdr(tag) +end +def emit_bror(tag)#0 + emit_pending_seq + emit_byte($AE) emit_reladdr(tag) end def emit_leave#0 @@ -732,15 +735,15 @@ def gen_uop(seq, tkn) fin when tkn is NEG_TKN - code = $10; break + code = $90; break is COMP_TKN - code = $12; break + code = $92; break is LOGIC_NOT_TKN code = $20; break is INC_TKN - code = $0C; break + code = $8C; break is DEC_TKN - code = $0E; break + code = $8E; break is BPTR_TKN code = $60; break is WPTR_TKN @@ -767,25 +770,25 @@ def gen_bop(seq, tkn) fin when tkn is MUL_TKN - code = $06; break + code = $86; break is DIV_TKN - code = $08; break + code = $88; break is MOD_TKN - code = $0A; break + code = $8A; break is ADD_TKN - code = $02; break + code = $82; break is SUB_TKN - code = $04; break + code = $84; break is SHL_TKN - code = $1A; break + code = $9A; break is SHR_TKN - code = $1C; break + code = $9C; break is AND_TKN - code = $14; break + code = $94; break is OR_TKN - code = $16; break + code = $96; break is EOR_TKN - code = $18; break + code = $98; break is EQ_TKN code = $40; break is NE_TKN diff --git a/src/toolsrc/codeseq.plh b/src/toolsrc/codeseq.plh index 5efa4c6..a65f621 100644 --- a/src/toolsrc/codeseq.plh +++ b/src/toolsrc/codeseq.plh @@ -13,22 +13,22 @@ const CONSTR_CODE = $2E // Stack code group // const STACK_GROUP = $02 -const INDEXB_CODE = $02 -const ADD_CODE = $02 -const SUB_CODE = $04 -const MUL_CODE = $06 -const DIV_CODE = $08 -const MOD_CODE = $0A -const INC_CODE = $0C -const DEC_CODE = $0E -const NEG_CODE = $10 -const COMP_CODE = $12 -const AND_CODE = $14 -const OR_CODE = $16 -const EOR_CODE = $18 -const SHL_CODE = $1A -const SHR_CODE = $1C -const INDEXW_CODE = $1E +const INDEXB_CODE = $82 +const ADD_CODE = $82 +const SUB_CODE = $84 +const MUL_CODE = $86 +const DIV_CODE = $88 +const MOD_CODE = $8A +const INC_CODE = $8C +const DEC_CODE = $8E +const NEG_CODE = $90 +const COMP_CODE = $92 +const AND_CODE = $94 +const OR_CODE = $96 +const EOR_CODE = $98 +const SHL_CODE = $9A +const SHR_CODE = $9C +const INDEXW_CODE = $9E const LOGIC_NOT_CODE = $20 //const LOGIC_OR_CODE = $22 //const LOGIC_AND_CODE = $24 @@ -79,8 +79,8 @@ const RELATIVE_GROUP = $05 const BRFALSE_CODE = $4C const BRTRUE_CODE = $4E const BRNCH_CODE = $50 -const BRAND_CODE = $8C -const BROR_CODE = $8E +const BRAND_CODE = $AC +const BROR_CODE = $AE // // Code tag address group // diff --git a/src/toolsrc/ed.pla b/src/toolsrc/ed.pla index 2a96be4..059ac59 100755 --- a/src/toolsrc/ed.pla +++ b/src/toolsrc/ed.pla @@ -1123,7 +1123,7 @@ def cmdmode#0 word cmdptr clrscrn - puts("PLASMA Editor, Version 1.01\n") + puts("PLASMA Editor, Version 2.0 Dev\n") while not exit puts(@filename) cmdptr = gets($BA) diff --git a/src/toolsrc/plasm.pla b/src/toolsrc/plasm.pla index 7c6cf82..92a5b9f 100644 --- a/src/toolsrc/plasm.pla +++ b/src/toolsrc/plasm.pla @@ -411,7 +411,7 @@ include "toolsrc/parse.pla" // // Look at command line arguments and compile module // -puts("PLASMA Compiler, Version 1.02\n") +puts("PLASMA Compiler, Version 2.0 Dev\n") arg = argNext(argFirst) if ^arg and ^(arg + 1) == '-' opt = arg + 2 diff --git a/src/vmsrc/apple/cmd.pla b/src/vmsrc/apple/cmd.pla index 68309fb..5457b4e 100755 --- a/src/vmsrc/apple/cmd.pla +++ b/src/vmsrc/apple/cmd.pla @@ -38,7 +38,7 @@ predef execmod(modfile)#1 // // Exported CMDSYS table // -word version = $0101 // 01.01 +word version = $0200 // 02.00 Dev word syspath word syscmdln word = @execmod @@ -1433,7 +1433,7 @@ heap = *freemem // // Print PLASMA version // -prstr("PLASMA "); prbyte(version.1); cout('.'); prbyte(version.0); crout +prstr("PLASMA 2.0 Dev\n")//; prbyte(version.1); cout('.'); prbyte(version.0); crout // // Init symbol table. // diff --git a/src/vmsrc/apple/plvm02.s b/src/vmsrc/apple/plvm02.s index 54f7880..7dc6090 100755 --- a/src/vmsrc/apple/plvm02.s +++ b/src/vmsrc/apple/plvm02.s @@ -193,17 +193,17 @@ VMCORE = * ;* * ;**************** !ALIGN 255,0 -;OPTBL !WORD CONST,CONST,CONST,CONST,CONST,CONST,CONST,CONST ; 00 02 04 06 08 0A 0C 0E -; !WORD CONST,CONST,CONST,CONST,CONST,CONST,CONST,CONST ; 10 12 14 16 18 1A 1C 1E -OPTBL !WORD ZERO,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 00 02 04 06 08 0A 0C 0E - !WORD NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 10 12 14 16 18 1A 1C 1E +OPTBL !WORD CN,CN,CN,CN,CN,CN,CN,CN ; 00 02 04 06 08 0A 0C 0E + !WORD CN,CN,CN,CN,CN,CN,CN,CN ; 10 12 14 16 18 1A 1C 1E !WORD LNOT,LOR,LAND,LA,LLA,CB,CW,CS ; 20 22 24 26 28 2A 2C 2E !WORD DROP,DROP2,DUP,DIVMOD,ADDI,SUBI,ANDI,ORI ; 30 32 34 36 38 3A 3C 3E !WORD ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E !WORD BRNCH,SEL,CALL,ICAL,ENTER,LEAVE,RET,CFFB ; 50 52 54 56 58 5A 5C 5E !WORD LB,LW,LLB,LLW,LAB,LAW,DLB,DLW ; 60 62 64 66 68 6A 6C 6E !WORD SB,SW,SLB,SLW,SAB,SAW,DAB,DAW ; 70 72 74 76 78 7A 7C 7E - !WORD BRGT,BRLT,INCBRLE,ADDBRLE,DECBRGE,SUBBRGE,BRAND,BROR ; 80 82 84 86 88 8A 8C 8E + !WORD MINUS1,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 80 82 84 86 88 8A 8C 8E + !WORD NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 90 92 94 96 98 9A 9C 9E + !WORD BRGT,BRLT,INCBRLE,ADDBRLE,DECBRGE,SUBBRGE,BRAND,BROR ; A0 A2 A4 A6 A8 AA AC AE ;* ;* ;* ENTER INTO BYTECODE INTERPRETER @@ -404,17 +404,17 @@ LCDEFCMD = *-28 ; DEFCMD IN LC MEMORY ;* * ;***************** !ALIGN 255,0 -;OPXTBL !WORD CONST,CONST,CONST,CONST,CONST,CONST,CONST,CONST ; 00 02 04 06 08 0A 0C 0E -; !WORD CONST,CONST,CONST,CONST,CONST,CONST,CONST,CONST ; 10 12 14 16 18 1A 1C 1E -OPXTBL !WORD ZERO,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 00 02 04 06 08 0A 0C 0E - !WORD NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 10 12 14 16 18 1A 1C 1E +OPXTBL !WORD CN,CN,CN,CN,CN,CN,CN,CN ; 00 02 04 06 08 0A 0C 0E + !WORD CN,CN,CN,CN,CN,CN,CN,CN ; 10 12 14 16 18 1A 1C 1E !WORD LNOT,LOR,LAND,LA,LLA,CB,CW,CSX ; 20 22 24 26 28 2A 2C 2E !WORD DROP,DROP2,DUP,DIVMOD,ADDI,SUBI,ANDI,ORI ; 30 32 34 36 38 3A 3C 3E !WORD ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E !WORD BRNCH,SEL,CALLX,ICALX,ENTER,LEAVEX,RETX,CFFB ; 50 52 54 56 58 5A 5C 5E !WORD LBX,LWX,LLBX,LLWX,LABX,LAWX,DLB,DLW ; 60 62 64 66 68 6A 6C 6E !WORD SB,SW,SLB,SLW,SAB,SAW,DAB,DAW ; 70 72 74 76 78 7A 7C 7E - !WORD BRGT,BRLT,INCBRLE,ADDBRLE,DECBRGE,SUBBRGE,BRAND,BROR ; 80 82 84 86 88 8A 8C 8E + !WORD MINUS1,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 80 82 84 86 88 8A 8C 8E + !WORD NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 90 92 94 96 98 9A 9C 9E + !WORD BRGT,BRLT,INCBRLE,ADDBRLE,DECBRGE,SUBBRGE,BRAND,BROR ; A0 A2 A4 A6 A8 AA AC AE ;* ;* ADD TOS TO TOS-1 ;* @@ -731,24 +731,28 @@ DUP DEX STA ESTKH,X JMP NEXTOP ;* -;* CONSTANT +;* CONSTANT -1, NYBBLE, BYTE, $FF BYTE, WORD (BELOW) ;* -ZERO -CONST DEX - LSR ;LDA #$00 +MINUS1 DEX + LDA #$FF + STA ESTKL,X + STA ESTKH,X + JMP NEXTOP +CN DEX + LSR ; A = CONST * 2 STA ESTKL,X LDA #$00 STA ESTKH,X JMP NEXTOP -CFFB DEX - LDA #$FF +CB DEX + LDA #$00 STA ESTKH,X INY ;+INC_IP LDA (IP),Y STA ESTKL,X JMP NEXTOP -CB DEX - LDA #$00 +CFFB DEX + LDA #$FF STA ESTKH,X INY ;+INC_IP LDA (IP),Y From f3ef1b4820d666cb951dde14e7e5c6f9940adb42 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Mon, 5 Mar 2018 12:19:47 -0800 Subject: [PATCH 011/147] Enable 65C02 ConstantNybble --- src/vmsrc/apple/plvm02.s | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/vmsrc/apple/plvm02.s b/src/vmsrc/apple/plvm02.s index 7dc6090..78c165b 100755 --- a/src/vmsrc/apple/plvm02.s +++ b/src/vmsrc/apple/plvm02.s @@ -1728,15 +1728,16 @@ CDINTRP PLY JMP FETCHOP CDINTRPEND ; -; LDA #ZERO -; LDY #(CZEROEND-CZERO) -; JSR OPCPY -;CZERO DEX -; STZ ESTKL,X -; STZ ESTKH,X -; JMP NEXTOP -;CZEROEND + LDA #CN + LDY #(CCNEND-CCN) + JSR OPCPY +CCN DEX + LSR + STA ESTKL,X + STZ ESTKH,X + JMP NEXTOP +CCNEND ; LDA #CB From a8553cfdb71bc5cf456b68fc61995a48a1bbaa8a Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Mon, 5 Mar 2018 15:40:43 -0800 Subject: [PATCH 012/147] re-arrange some ops --- src/toolsrc/codegen.c | 20 ++------------------ src/toolsrc/codegen.h | 2 -- src/toolsrc/codegen.pla | 11 +++++++---- src/toolsrc/codeseq.plh | 4 +--- src/toolsrc/parse.c | 8 ++------ src/toolsrc/plasm.pla | 4 ---- src/vmsrc/apple/plvm02.s | 33 ++++----------------------------- 7 files changed, 16 insertions(+), 66 deletions(-) diff --git a/src/toolsrc/codegen.c b/src/toolsrc/codegen.c index dc8df89..ce18984 100755 --- a/src/toolsrc/codegen.c +++ b/src/toolsrc/codegen.c @@ -601,7 +601,7 @@ void emit_const(int cval) { emit_pending_seq(); if ((cval & 0xFFFF) == 0xFFFF) - printf("\t%s\t$80\t\t\t; MINUS ONE\n", DB); + printf("\t%s\t$20\t\t\t; MINUS ONE\n", DB); else if ((cval & 0xFFF0) == 0x0000) printf("\t%s\t$%02X\t\t\t; CN\t%d\n", DB, cval*2, cval); else if ((cval & 0xFF00) == 0x0000) @@ -926,7 +926,7 @@ int emit_unaryop(t_token op) printf("\t%s\t$92\t\t\t; COMP\n", DB); break; case LOGIC_NOT_TOKEN: - printf("\t%s\t$20\t\t\t; NOT\n", DB); + printf("\t%s\t$80\t\t\t; NOT\n", DB); break; case INC_TOKEN: printf("\t%s\t$8C\t\t\t; INCR\n", DB); @@ -999,12 +999,6 @@ int emit_op(t_token op) case LE_TOKEN: printf("\t%s\t$4A\t\t\t; ISLE\n", DB); break; -// case LOGIC_OR_TOKEN: -// printf("\t%s\t$22\t\t\t; LOR\n", DB); -// break; -// case LOGIC_AND_TOKEN: -// printf("\t%s\t$24\t\t\t; LAND\n", DB); -// break; case COMMA_TOKEN: break; default: @@ -1276,14 +1270,6 @@ int crunch_seq(t_opseq **seq, int pass) op->val = op->val <= opnext->val ? 1 : 0; freeops = 2; break; -// case BINARY_CODE(LOGIC_OR_TOKEN): -// op->val = op->val || opnext->val ? 1 : 0; -// freeops = 2; -// break; -// case BINARY_CODE(LOGIC_AND_TOKEN): -// op->val = op->val && opnext->val ? 1 : 0; -// freeops = 2; -// break; } // End of collapse constant operation if ((pass > 0) && (freeops == 0) && (op->val != 0)) @@ -1674,8 +1660,6 @@ int emit_pending_seq() case LT_CODE: case GT_CODE: case LE_CODE: -// case LOGIC_OR_CODE: -// case LOGIC_AND_CODE: emit_op(op->code); break; case CONST_CODE: diff --git a/src/toolsrc/codegen.h b/src/toolsrc/codegen.h index 32b3dca..af7d4af 100755 --- a/src/toolsrc/codegen.h +++ b/src/toolsrc/codegen.h @@ -31,8 +31,6 @@ typedef struct _opseq { #define LT_CODE (0x0200|LT_TOKEN) #define GT_CODE (0x0200|GT_TOKEN) #define LE_CODE (0x0200|LE_TOKEN) -//#define LOGIC_OR_CODE (0x0200|LOGIC_OR_TOKEN) -//#define LOGIC_AND_CODE (0x0200|LOGIC_AND_TOKEN) #define CONST_CODE 0x0300 #define STR_CODE 0x0301 #define LB_CODE 0x0302 diff --git a/src/toolsrc/codegen.pla b/src/toolsrc/codegen.pla index 136b5c3..5a7880b 100644 --- a/src/toolsrc/codegen.pla +++ b/src/toolsrc/codegen.pla @@ -133,7 +133,7 @@ end def emit_const(cval)#0 emit_pending_seq if cval == $FFFF // MINUS ONE - emit_byte($80) + emit_byte($20) elsif cval & $FFF0 == $0000 // Constant NYBBLE emit_byte(cval*2) elsif cval & $FF00 == $0000 // Constant BYTE @@ -308,8 +308,11 @@ def emit_pending_seq#0 // is CONST_GROUP if op->opcode == CONST_CODE - if op=>opval == $0000 // ZERO - ^codeptr = $00 + if op=>opval == $FFFF // MINUS 1 + ^codeptr = $20 + codeptr++ + elsif op=>opval & $FFF0 == $0000 // Constant NYBBLE + ^codeptr = op->opval*2) codeptr++ elsif op=>opval & $FF00 == $0000 // Constant BYTE *codeptr = $2A | (op->opval << 8) @@ -739,7 +742,7 @@ def gen_uop(seq, tkn) is COMP_TKN code = $92; break is LOGIC_NOT_TKN - code = $20; break + code = $80; break is INC_TKN code = $8C; break is DEC_TKN diff --git a/src/toolsrc/codeseq.plh b/src/toolsrc/codeseq.plh index a65f621..5a23e6c 100644 --- a/src/toolsrc/codeseq.plh +++ b/src/toolsrc/codeseq.plh @@ -29,9 +29,7 @@ const EOR_CODE = $98 const SHL_CODE = $9A const SHR_CODE = $9C const INDEXW_CODE = $9E -const LOGIC_NOT_CODE = $20 -//const LOGIC_OR_CODE = $22 -//const LOGIC_AND_CODE = $24 +const LOGIC_NOT_CODE = $80 const DROP_CODE = $30 const DROP2_CODE = $32 const DUP_CODE = $34 diff --git a/src/toolsrc/parse.c b/src/toolsrc/parse.c index edd75c8..97305d3 100755 --- a/src/toolsrc/parse.c +++ b/src/toolsrc/parse.c @@ -24,9 +24,7 @@ t_token binary_ops_table[] = { EOR_TOKEN, OR_TOKEN, GT_TOKEN, GE_TOKEN, LT_TOKEN, LE_TOKEN, - EQ_TOKEN, NE_TOKEN, -// LOGIC_AND_TOKEN, -// LOGIC_OR_TOKEN + EQ_TOKEN, NE_TOKEN /* Lowest precedence */ }; t_token binary_ops_precedence[] = { @@ -38,9 +36,7 @@ t_token binary_ops_precedence[] = { 5, 6, 7, 7, 7, 7, - 8, 8, -// 9, -// 10 + 8, 8 /* Lowest precedence */ }; diff --git a/src/toolsrc/plasm.pla b/src/toolsrc/plasm.pla index 92a5b9f..7b44939 100644 --- a/src/toolsrc/plasm.pla +++ b/src/toolsrc/plasm.pla @@ -194,8 +194,6 @@ byte = EOR_TKN byte = OR_TKN byte = GT_TKN, GE_TKN, LT_TKN, LE_TKN byte = EQ_TKN, NE_TKN -//byte = LOGIC_AND_TKN -//byte = LOGIC_OR_TKN // Lowest precedence byte[] bops_prec // Highest precedence byte = 1, 1, 1 @@ -206,8 +204,6 @@ byte = 5 byte = 6 byte = 7, 7, 7, 7 byte = 8, 8 -//byte = 9 -//byte = 10 // Lowest precedence byte[16] opstack byte[16] precstack diff --git a/src/vmsrc/apple/plvm02.s b/src/vmsrc/apple/plvm02.s index 78c165b..f2684b8 100755 --- a/src/vmsrc/apple/plvm02.s +++ b/src/vmsrc/apple/plvm02.s @@ -195,13 +195,13 @@ VMCORE = * !ALIGN 255,0 OPTBL !WORD CN,CN,CN,CN,CN,CN,CN,CN ; 00 02 04 06 08 0A 0C 0E !WORD CN,CN,CN,CN,CN,CN,CN,CN ; 10 12 14 16 18 1A 1C 1E - !WORD LNOT,LOR,LAND,LA,LLA,CB,CW,CS ; 20 22 24 26 28 2A 2C 2E + !WORD MINUS1,NEXTOP,NEXTOP,LA,LLA,CB,CW,CS ; 20 22 24 26 28 2A 2C 2E !WORD DROP,DROP2,DUP,DIVMOD,ADDI,SUBI,ANDI,ORI ; 30 32 34 36 38 3A 3C 3E !WORD ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E !WORD BRNCH,SEL,CALL,ICAL,ENTER,LEAVE,RET,CFFB ; 50 52 54 56 58 5A 5C 5E !WORD LB,LW,LLB,LLW,LAB,LAW,DLB,DLW ; 60 62 64 66 68 6A 6C 6E !WORD SB,SW,SLB,SLW,SAB,SAW,DAB,DAW ; 70 72 74 76 78 7A 7C 7E - !WORD MINUS1,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 80 82 84 86 88 8A 8C 8E + !WORD LNOT,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 80 82 84 86 88 8A 8C 8E !WORD NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 90 92 94 96 98 9A 9C 9E !WORD BRGT,BRLT,INCBRLE,ADDBRLE,DECBRGE,SUBBRGE,BRAND,BROR ; A0 A2 A4 A6 A8 AA AC AE ;* @@ -406,13 +406,13 @@ LCDEFCMD = *-28 ; DEFCMD IN LC MEMORY !ALIGN 255,0 OPXTBL !WORD CN,CN,CN,CN,CN,CN,CN,CN ; 00 02 04 06 08 0A 0C 0E !WORD CN,CN,CN,CN,CN,CN,CN,CN ; 10 12 14 16 18 1A 1C 1E - !WORD LNOT,LOR,LAND,LA,LLA,CB,CW,CSX ; 20 22 24 26 28 2A 2C 2E + !WORD MINUS1,NEXTOP,NEXTOP,LA,LLA,CB,CW,CSX ; 20 22 24 26 28 2A 2C 2E !WORD DROP,DROP2,DUP,DIVMOD,ADDI,SUBI,ANDI,ORI ; 30 32 34 36 38 3A 3C 3E !WORD ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E !WORD BRNCH,SEL,CALLX,ICALX,ENTER,LEAVEX,RETX,CFFB ; 50 52 54 56 58 5A 5C 5E !WORD LBX,LWX,LLBX,LLWX,LABX,LAWX,DLB,DLW ; 60 62 64 66 68 6A 6C 6E !WORD SB,SW,SLB,SLW,SAB,SAW,DAB,DAW ; 70 72 74 76 78 7A 7C 7E - !WORD MINUS1,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 80 82 84 86 88 8A 8C 8E + !WORD LNOT,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 80 82 84 86 88 8A 8C 8E !WORD NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 90 92 94 96 98 9A 9C 9E !WORD BRGT,BRLT,INCBRLE,ADDBRLE,DECBRGE,SUBBRGE,BRAND,BROR ; A0 A2 A4 A6 A8 AA AC AE ;* @@ -686,31 +686,6 @@ SHR STY IPY + LDY IPY JMP DROP ;* -;* LOGICAL AND -;* -LAND LDA ESTKL+1,X - ORA ESTKH+1,X - BEQ ++ - LDA ESTKL,X - ORA ESTKH,X - BEQ + - LDA #$FF -+ STA ESTKL+1,X - STA ESTKH+1,X -++ JMP DROP -;* -;* LOGICAL OR -;* -LOR LDA ESTKL,X - ORA ESTKH,X - ORA ESTKL+1,X - ORA ESTKH+1,X - BEQ + - LDA #$FF - STA ESTKL+1,X - STA ESTKH+1,X -+ JMP DROP -;* ;* LOGICAL NOT ;* LNOT LDA ESTKL,X From 2e952bfde3e122a24fd940b76720edbe50e784d9 Mon Sep 17 00:00:00 2001 From: Dave Schmenk Date: Mon, 5 Mar 2018 22:14:49 -0800 Subject: [PATCH 013/147] New FOR/NEXT changes for terminal variable value --- src/samplesrc/rogue.map.pla | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/samplesrc/rogue.map.pla b/src/samplesrc/rogue.map.pla index b068fe1..3190296 100644 --- a/src/samplesrc/rogue.map.pla +++ b/src/samplesrc/rogue.map.pla @@ -279,7 +279,7 @@ export def drawmap(xorg, yorg, viewfield, viewdir, lightdist, viewdist) // darkness = 1 imap = (yorg << rowshift) + xorg - if ^(map + imap) & LIT_TILE or lightdist + if lightdist or ^(map + imap) & LIT_TILE // // Update current spot in viewmap // @@ -358,7 +358,7 @@ export def drawmap(xorg, yorg, viewfield, viewdir, lightdist, viewdist) // // Run through visible octant beam points // - for l = l to dbeam[viewdist] + for l = dbeam[lightdist]+1 to dbeam[viewdist] // // Check parent visiblity // @@ -429,7 +429,7 @@ export def drawmap(xorg, yorg, viewfield, viewdir, lightdist, viewdist) vispix[l] = 0 fin next - for l = l to dbeam[viewdist] + for l = dbeam[lightdist]+1 to dbeam[viewdist] if vispix[vbeam[l]] imap = ((yorg - xbeam[l]) << rowshift) + xorg + ybeam[l] tile = ^(map + imap) @@ -479,7 +479,7 @@ export def drawmap(xorg, yorg, viewfield, viewdir, lightdist, viewdist) vispix[l] = 0 fin next - for l = l to dbeam[viewdist] + for l = dbeam[lightdist]+1 to dbeam[viewdist] if vispix[vbeam[l]] imap = ((yorg + xbeam[l]) << rowshift) + xorg + ybeam[l] tile = ^(map + imap) @@ -529,7 +529,7 @@ export def drawmap(xorg, yorg, viewfield, viewdir, lightdist, viewdist) vispix[l] = 0 fin next - for l = l to dbeam[viewdist] + for l = dbeam[lightdist]+1 to dbeam[viewdist] if vispix[vbeam[l]] imap = ((yorg + ybeam[l]) << rowshift) + xorg + xbeam[l] tile = ^(map + imap) @@ -579,7 +579,7 @@ export def drawmap(xorg, yorg, viewfield, viewdir, lightdist, viewdist) vispix[l] = 0 fin next - for l = l to dbeam[viewdist] + for l = dbeam[lightdist]+1 to dbeam[viewdist] if vispix[vbeam[l]] imap = ((yorg + ybeam[l]) << rowshift) + xorg - xbeam[l] tile = ^(map + imap) @@ -629,7 +629,7 @@ export def drawmap(xorg, yorg, viewfield, viewdir, lightdist, viewdist) vispix[l] = 0 fin next - for l = l to dbeam[viewdist] + for l = dbeam[lightdist]+1 to dbeam[viewdist] if vispix[vbeam[l]] imap = ((yorg + xbeam[l]) << rowshift) + xorg - ybeam[l] tile = ^(map + imap) @@ -679,7 +679,7 @@ export def drawmap(xorg, yorg, viewfield, viewdir, lightdist, viewdist) vispix[l] = 0 fin next - for l = l to dbeam[viewdist] + for l = dbeam[lightdist]+1 to dbeam[viewdist] if vispix[vbeam[l]] imap = ((yorg - xbeam[l]) << rowshift) + xorg - ybeam[l] tile = ^(map + imap) @@ -729,7 +729,7 @@ export def drawmap(xorg, yorg, viewfield, viewdir, lightdist, viewdist) vispix[l] = 0 fin next - for l = l to dbeam[viewdist] + for l = dbeam[lightdist]+1 to dbeam[viewdist] imap = ((yorg - ybeam[l]) << rowshift) + xorg - xbeam[l] if vispix[vbeam[l]] tile = ^(map + imap) From 25599c00c8ed2590365db3e9eb75d601ee0075e8 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Tue, 6 Mar 2018 19:20:59 -0800 Subject: [PATCH 014/147] Apple 3 VM updates --- PLASMA-BLD2.PO | Bin 0 -> 143360 bytes PLASMA-DEM2.PO | Bin 0 -> 143360 bytes PLASMA-SOS2.PO | Bin 0 -> 143360 bytes PLASMA-SYS2.PO | Bin 0 -> 143360 bytes src/vmsrc/apple/plvm02.s | 72 ++++------ src/vmsrc/apple/plvm03.s | 266 +++++++++++++++++++++++++------------ src/vmsrc/apple/soscmd.pla | 4 +- 7 files changed, 211 insertions(+), 131 deletions(-) create mode 100644 PLASMA-BLD2.PO create mode 100644 PLASMA-DEM2.PO create mode 100644 PLASMA-SOS2.PO create mode 100644 PLASMA-SYS2.PO diff --git a/PLASMA-BLD2.PO b/PLASMA-BLD2.PO new file mode 100644 index 0000000000000000000000000000000000000000..bb1d25479ab4c0e69fae7455f9a2bd7d08c0b334 GIT binary patch literal 143360 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

Q>@wO&DQ2`#dD=WSfUp|#miFb=m zk*2)Xc)vB4;#cMvFYoWQ#+1G5dSz_P1T6(`9XIrkP};hgHltYhlu4&qWi?Lm4(s%Y zwCk{R4#x+FL+b|Qko4{mC!Ro=?-*81#6(It4yF2U!-PW}=NSiY z*b&#MB7DhR?Ql#2aS}Vs#V*cIlnq$L;ZoxX2iv=QW7;R4*5W}7oH(Zq?ig`6T#+O6 zcEuU3=X+jy<1t-Y5|4NpiVepTTVlNq8RiT}2MKa|IJri8oP@KeIB5KKZ|+t_B1sg# z>ju^hh{!t10@dJ*jLH5^i=4UYIfEmYZQ*tzZ}dp+2eZ1ArEBlrlnAP0s5yQ*?kq;J zOXzZ(dvTmgeYmvQlp^j|tI^1l;EtXxs>?=sbIkO};6N-GE?W?)EY!Xw(#?bP zixV7`h89Q<>hrgtG*ssE*2lKG%9m=y)H~OG9BXN{g^mqBJLL`{KoQ85vFwfy^922;~{lQ0^;^ z&BKG;Iv10aM>TRl+)t}PL{limCgr7-hp)n@KshO#()IL; z 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 literal 0 HcmV?d00001 diff --git a/PLASMA-DEM2.PO b/PLASMA-DEM2.PO new file mode 100644 index 0000000000000000000000000000000000000000..62ca12c48ea175ca4584b8b441a33af9119cebcc GIT binary patch literal 143360 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 M%z(_m|8oZZ2ejohxBvhE literal 0 HcmV?d00001 diff --git a/PLASMA-SOS2.PO b/PLASMA-SOS2.PO new file mode 100644 index 0000000000000000000000000000000000000000..6c8829017667c9ea27ad2b6614ef7ec6a885cb46 GIT binary patch literal 143360 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 literal 0 HcmV?d00001 diff --git a/PLASMA-SYS2.PO b/PLASMA-SYS2.PO new file mode 100644 index 0000000000000000000000000000000000000000..0437ae0e35da7fcbce78345146f6c9ce5f34a118 GIT binary patch literal 143360 zcmeFa4O~>!x<9^V?*V3bkY1Vp8GN-I#o0Y@Of*Xo|J!UJaNDKqn)ZcvU9 zv28eINyRx6r|~cxhK34@bE6sZ}^t85qlD6!5|0b^2rZuJ5 zHdu)JqGPH_zuve$b-iJI+WOgz>t{5sPqqb`mYC-7p;||7_Y(X|wkErM&EMNeV2~i^G|jRuF(ob66U~_M_b1I>bM`><);S+lZJDGq8a~z9{-n2g^fpyFF+6*g zUwFkbsxCuYTJ2NFT`+@Z<*z%Aj@#-;^cwx&Vqcu6&&#jJTHU3dCrhBckQ?1F%Qd3Qd{-y`4Nv4TgCe^>} z;y=}PPwc+8`(6hN=ck1(qcy?bl!c;ZTeD0V@kbtz!X4`FEHkq+E1rKsYt7K{E4AXc zmgm=JYNFzIW=eZ>nnLMZeX)zXOn&|QRRUfKu;fyPAu(%i;*_jKS+{t@;>T;k37IuEq7AxkgcbK z_>t-UIV3C6MItVF3ynbui@SnR90i&eXSy_!EvJcZ_F( zC>rN20!g|Ki^zvbC|NU(P|g)<-Xf5!#55Fe;7>jeIUUpf2yFo2|A!6+BLDU8pH~7b z@%iU1{I4bdwfFzp27X=w_j~By&&U57^S@pKtQWTQuA-|UQzbH|C(?2*phoKw`; zCpveBIHgHdw>ax=bw;0Ye<)#zb2e^d-EGd&Tb&ZyD4w%(P9f514{-_;oqKL^#=hvn zf7@Y`uZ=hPS;%^gO*Cn1d`mQq;>B*iZmm`8?h?OW?`vx|`PKNA60TAF!A3?(EPr%T z9|KajZJDr8w0$Wo5^Y_=V(NNO|#x}JhpOMs!rEtzvo^zGwEcz_YXS^)b zeX@99bSC^+UozBf8 zrZW}-k^EpdMRH9?b4@)Krsk;WOd%ep3;QB8xu#=le;$ia{qM@@8p8Sar6&V_I%gCT9 zQ>J7mWhG_u>Dm0Eq&fVev_yW&thqD!*=Z?RSt)aS8tXhB(}m?kjLml$@|EZ7%F{0X zk`(^aJ?H;Mg8!WUJNW;k{|8m;xQeqZNRg~Mm9Ak_bff?2;9_A zEA~?xCf?~P6pwCdc<(UC+6W~p+6c(HjGzz#+t^W4PpvCD-*lYw;g7a-AFplTv^{V& zbsrbiLz|@u!58%v2F27P=DaAe^yR{%R+N19i*W20_fx;kGmrA` znFs!9bn_jGlmWXKT6RHo|>*NSe9+5e;F*BdP4_2y%m3dz5=*`Kn1 zX;ZTzpgtV#qlVX;UHKMbRu#V95Kl1!Ya878%hog(ia+!Tv$lC?1A@h&E{U;uHZ}KE z)KJ$@8sR$-)KuHNNvv(~G7N0dA5o&>Z9=8>yF8m*jWwq?(ZbT;0ncV#&S}$WGt+&> z;%SUK)kJY9A}xQDl48KOIi8}@`mM-0V>+|RRdc$6VtK>+LapDJj#|Gp_3Sug)`&B$ zM|X5N?iCnU%~6b<&8Nlj6@xrMh2p9H+7a)tkp8InoTH|rHj>k0>JdLiCMh0W&NrrS zXwBq&YxxGfaxfG^q{wqnxlwmtT}oupS~otZ2hUcg&CX>v4hk0 z=SU@0+g#x6p$enVUE2Wp_Br&PzBhhJloLU&bd~px&3j+xTA3*MXPn4Ygna@+s++`YvVq<7Q%fH zw}aajS5@2GpDND6eHd56z136e9J*H=-Pj0zQP{!ak%%|)TcvBEE6@(tQ*#vk;xy_P z9pg+PCZavHd)q|uvs!1HOKKChdcC_8uT9*pcx#;sqi@C4BGcDICmE#g%iG zxB^AU{W(~VJ}sI~TYH{%na*4%VTz@=Gr6YIbhd0!fs1QR=^7TAl=YZC z3dqWA8cnJ%5hl?}qFU(oT9>J(=USQ{Q~n90>k0puE|^L2#OHLGx*W{TL-0w#{uQ;Z z!ji69u?J7_jD-cy)i1oTX|&~+ih&QwL~DkZ;;W@foSzl4nsC$`F=|fP-(ZOn$Vl+D+r|= z(omGl8{t(Kwj+oOMI5;4S8}VpI?Fbs{D4JwEea{AT3byusM57M@IIK#|$j0BPiP6exdGqbb=?iTwd6wDe$bfDVubks9DU#ZQdkKg){Q@G*cRO(WfU~-JHJt_6?k?}JjDf$u=hBY*fzoklf%b&2&~(__ffX}2Daija&uPtbsKx~Xu^_k_C~bu#LU@) z@#L{s{q68>A`YT9{>DAFao#;Px=}X>ZFp+>q8alRFYaefjs&&Ge@tzber85L4&L${ z6k*(tiZCHLWkyowH9R>TXkXL4$?GzmkTokgF?$eN7D_tqMsV;|-Zc&&$>)Wu_%%-|8hOKY{Jl-v!@D?dDmt2NeJ%U4u;1ev~O$ zkYt#dJ~xTaPUk_F_wKgx-Ywj5LHGXBUrv$C?+FT`M=xe(XBsBY;qT?=WnA;8 z!apm0LE4lcN;h@h+zgOPpO-dEp_-kvFdNx|3i26DW&x5Z$b)Gu?hm8{uVsW@oGn+1+h@QF!TGZQnCCepI=3sMXQ zK4Tti8tL=+lr$cKpPLBGx#_c#AeZFK^trTLnMn%5%)~T4X<KVwl)Qd)LWCbHru zJ}{9-5`JQ4Que&ew24y&P!kPV=|SGm{>t>$BGN+`sHcp~Bp6S???B?9pvfU&;X{WF zPdz-)I)8QiQ%PX5^5<==*L8kAC5unwVQizll=ifszUGvip2-iiN7@$AhEp=;84|N; z+fw=@4b4iQmpL;DZG2Xe(no2}r#-?;B`7`3u!zr^mywa4nVrSo9tT9jyt&W}v`;4* zvi0fnX6u6tDQQVrJnacH(8)7s!@lcoex^P#GjS$*L>6yIPn$hO>1lk{%*>>uG;b$^ zI~{#ZpPrerI6W;p(O_51)(qMDU}83NIokmE4IG}D_xQn3`q3VAD-2xl&EUy(}6rx1kGD1 z1V5m26fM(_G8n_FeyD;(@x5x4diqePeEJn8RciwngX6E)cXMcR{0+t!tR_>v(bvUa zPa$ytL(#DVWl%JD|2euo1$>QtC3eB}NeAb<`1+{pvwYzCNJaGyR=eKlzC5Y&r2$Hg zvj$SmN-`v6d*yyDdf^SxQ)fawQ>k7r1T6l!nC9XHy|Wm zkC2EaW-z2LpgR4>$k_wPsp%LelwNR+p&0|Q+3B-qqj#pH!B(C<6|E|BL1s#}m-p<% z8B-MrqyYWiJ{&$PBXK5r6dj~#M+1^V*E>oL(9K$ql08#TvHFH6rM)YdeNyzIVsO4D zRBvMjQvbltCnqIhkV--?;CZi}8T|B)sag7zzY13}8NVBW4DQ{`+f~vj;GLb1l#?5U6AUoicOIAUcCO??8E@`q)mN6-|o)aY0(p z7v5kx)}pW;h`NVsW?~ktEvQo{odxNcbD(pxFzRO{LA}j_ zHleI3MV>jpBys*-*(O|NK@EQ*@4lz(>R(|qodH97nee)-C0a-N+0=#r;$_(yY> zJh|l2)j3ZB>9;v6a-LkWdgYUR-ioJIFIm1k=doBN*`rHV@Jm-d`DhN12Bm#0@2OSG zmpn`7ZL4#0o_r?nshn6~JiTgF&Xc@C{h7Sw%lSug_&&^>$M_X1pL_z8p9S6{Pp=+K z?Z>!zD}a@^VolDIPvy`dA~)|T9{-US|5(n_B~LG3t%xCU)vDz={M4yAiu9&Vee^$Q zT>~wR3ML!GCT67@Qf5t7>S7}Qc+RuD!pjpYAIn=x8AXOU5EUYx>eJd;iIe;0Q;O{G z<&~~Ipd1iAsA-^`U9SykYC3i7Q^`Nlhluaf=$Vv!UwofNMC4#~-WRFpM6lW~i>d#S z3d}!)lk`Lm4UOtHY1^J|}P?`^_ za@7(v?umm-k7l{@nWwzYw~`(WOd%k75tJFkMU3BJ@sf`BS22KUnh#6 z7`%aV=g;6=8~=b5|6`=V12`~l{TYmb(GWOyUxzbznS;pNejGVC?Oi{L=2#|&kV#w+ zc`bC??(HodgV*FY&V&~-su*V7a4sfn?M>WLvUU^~^F?GBhb3^_VrC#R{3jw~R5aPB zwd1d)cxa)TiSePqBb5Z}MsZ7-bz`m}ELIO-jQCj$jXK8vCur!_^4wDOx^di6-*q<+ zBB>c5sr#>!WCoLr38vXA)YP;HzO)ER_GBP?-P#Ed*Sbhrz^LoE0s8?oJu|?K8tH)s z_I=ky^odM`^w%V4|wYe65ml?4W`#)vQC#{_7?VN**{+QA3ej zH}a+%Yx!6IKam7}q8BeEB-wB)iBYW$<8ni|wc%XMuD)JQ)`oE2@K7Z@X&~Hh1W?n| zWHA%N4y22`iCZ_6i_y@w$|-G?s*JF;qd9`M3PNLP1LwJz;I(M#*HlR^Au*?C7)FvQ z+_kZ8<%;FcVyQ>Szjz)(%MasX3BN8J&p)jjM#<|ybOaZZ(8p5l2ySgC7n8r%Z-jz9 z#czt&eu*?>?J$mjDJ4N;e}Z8gN=F`ICgDp2Js=10EZ}WGJ)jrBg%IZVfDZtt07F7a z0lt|ixDzl9kU&VuOcGF#1~)Wm0j#A34 zHvxFS1V9X6D&Tg&-N2a+oEdP>1{eSj0OkW81Q-E1fMtM{fYrc%2KX<){Su%UPy%=Z z@HW5#umUQ9X9wOVaMuGq2Ydk#0d0UU0bc_S1C9arJK$b``wBqCkOE(ZlxUfNf}7wT z0~iO0L|8P!roeq0;7-8Zfcp@hi0~A+vjFn}ivSM+egk+6kOx=+cna_g;P-$6zy`o8 zNWYN@D0!VxmAucW3qD3zJzyK45wHu;44hWv(GK@N07n3)0OtS~0apPGOGE5-=>((pomTmiX z>`2q(aKPEUcYl)RSx(%wH(T>Ix68dJNmEZ>J6h8yY=&3 z*_sbRw(n~=uzT{(r==gbDGE{|)>8o&|zC-2E17?1TDZ zv((SxU*p?o(&*_^t2~d^_?mjK)#PjP#Ssoat7eC$(lDfMG+xp7cPj$Dp z+i&Ml@zl;9@uYN*^=OX9q_OtoXiZujJV*_XpUH2hcBh}kV?8P{-95@S6wX+vX&};m zkF+OpP1v>4EZ2~QYE_JCHM5kgW@D0~7$}9`6N34I4}y$K8DoMWn!vSO9izHuBpI@l zJf>z4PMAdbGUs~z9{_6MZ$U zN})poR{_?LjKiK7)pDw6<0q0ps8)snUaDa@MSF}CCf$0!(8tMe5^>BmK3e`7PI9 zl^Wpx`uAU!z`cI7{wu<;-QOqWzOnz)p%r1{hEEtidH5ZD&vC=Y4JTxS?|MIr248Pn zz~=-%? z>wA7SruK7v?LK|ae}quGO<&srwCnLc5^G%>j%d~jTKYW-{_8jEdD2Ds9N?l^keS*B z!NX8wB)=Zp?qT$HnfXzweZm!{_H*GXQ+s{-pCw?w3PM+YOsGY;#MEvRE;F@1OY%RY zX}=8GmwrrJk@^3tfcc1<$4~e#x1L`U{%@DSf6xPex`W-&`hT|fNS^EZ+|M@kpCd5P zdwxU+z321)rrvWs?F~oDiRHFBGOX0&DJmty3b`{|j?e&t0DKA4WQ51#QDQFiIq3&8 zMs(zUrkbgiXrNj`gqG1ss(2isecGj{smei$2A$V51HITZ6DqE4^}U#^EhRA;#t6q0W*nWo zEsF*s0@chTu*~`~OPNPvRVupnS;{Q-Tgt@vt5-0OtWm?osMjz{)iAa!n+(I_t&gam z90(k;MxAlQgS3MYd5{3sBTEUW{s{eRpfC1Y2s^?WHp*`qLl;a->4PqmmNSMYse29k z7_*d(C5*EAq3&D3X$-?WLIc+LJjN)i9WcbxwV4ziayFJ#CRe{5CG&6+|FBxGlYuK`zSHZfd>#yFhl}>-GiZcyhk4-Eb_Kcn1LhnLSbQz{2&x2){L7ePFDyX zDvA>w8YzZQoZ}%BCxGI_s8AhhCi`%>ArRP0nPoR~^B1eJ5LGYqWohsbC3vZN*#t!R zBEol}MolBQzKEs1%O)a9gD4Hk1qRc`sip)ZXWV&5+^zk^TQ`}b5h$QeX)HfoK9CqF z;H@NbABUxF4qG>gi}8t^%4MJ9;xgVQeN`hR z7~)7wE=0Y8#N5uT(}khk;eA_J_K+~NL0SicNn{K~G;IVV@@9qbG)frUuFFxL&nr)h z@@(X&96@m1ePNLgDeSFO*n63y>{W7LPigAlYc7|)l2bZJA|M(t31EjoX&b99*~R*lw6N-e{V*)~t4Ybj0HZprBu5=ylB*t7@;h~4 z$#Zyb1iYahRq!_A|D;wGe5@t~I{{z9e^4D97hK@QxxfX4wV z5Vi(5{|fiN0SW-?0WSfH00O`acn$CdpcL>9;9bBLfDKRucpvZqpce26;NJnC0U7{} zfG+@h04;$1fDS+>;A_A)fFpn&zzIMv;1u8@zytn9`Kb#c{7}b$TL5?a_0PSrl)2Gj z2*Y6t=cBA*2QO%M?b+m8C#Y0AGS z>%V{TuAx2>*Y`9v(GRrtZTfsu%cgC%^!V6S_{8q^*f`gFJ+Y6uxbf#(Vsl&^e|{gX zuIjFcUE<>K6&cR@SHwP|I5G7%9_RjXocmfNB23jydppFvS(<=fS7|?62mg~1E@l6B zPKcU()wll(+cLCs{~x^oLW4h7g-QkRr}sgqRK7&TuE-U^pSmF*}J5?>CG4~!u`3|UPr zB``?GcxF7Nj!8%!ZF z7|MMXhWad3(BEdYpBp@LU9c zVnX%H5miMId}OraX53WZ5j@Vh9%sB51&7_^6nXm#E`HGjhp#m-nipAvKBD@Sh^k_m z0MWwPtBz&BsQ&PBm#;X())niztO4d-Q5j5Jutuwi;?&v%&aZc&b`_(|Hw6MWo*yea zhWEY}VI#t2HUFAyKRr(Ld$pb%;>S+1KNlgaj}YRV{3nriuOo9pwGdIYQDO0ZdSwJJ zO|yL`sGYVef{)Ywq6`1a|J@RSsMyyd#Ng=9-7iSm>Q^JG%n`ktXfj)`Ktw)sf|;_f zTsn~wCk`w3XmY8&V53Tf>9#&f@OSYf)?VPMl0DTP5AeJ2sik8CP#_kSYNN+fEYsDE z*I`o$=e|Y}JhJ_@2+6nCBO7*(0}XqrGg<>d?HMNoxa>aL-0|W>yWcjq4x$X$=2nR# z?19^GiDACTQC1q=F6nmrrETt5X);m^DwiXTXbA)87XB@~QGY*i32GSQ~^q^qd zpVOHA+{sdsA^T=~fyVufcppL=U)6|r;@uqJFHW%s`-{=`A^z?^IU1F4 zO`N|Ng7+?+zowKkG$bJPzYd;yVXL?tp1xcH#9*O zA>k_DLuZfm9y^N~2vKfB<>+mwCe9IxmpRxPl4|yMYo#$ZwTbHvv2Zre1DyC}MGYsl zMF*oUaSy;Q2O~XKQSMvAJv`3eU#u@|;?7#|tt`C-Mw?%HO1mo`#s!-Nx3+H13lr3| zFpWO`;*!1+FQO%0;VtoRZz!?k>z*%VD#D@Vo?>69mHh3*<$haa1kc6vXU%>^GD)5d!6~6dV{`#T72}`)``j#GSE4#lvr$ewAV@y0pl% z*s#ds{eQw~f5nCWxGusJNJqkWX`C&;%U8O|me6%v46Yt?xyvpMv58$pA`@@4F(u*R zXj32t7+WOx}j|mk>yY4Sv1MPrZ!6mVa4p zN3SjStG_?8>=QNWr+jq%?8q{^4|N9A=R}rm^`*|p`rk#CWzY&N53AoCS@tD$f}XKK z6miq7+ue7^?I)J~HPv;NzQ3BS_NKO7_Buy@0DW)UD|YO2|Glx*;!V44?`|w{cI>ON zxc6+UuCmnBeexlaH0;`CQP5f}`*yVK*tdVj_G)j1c%S8DL->ZF8@Q&8w>WJ>gsqXb z&rKoxkmwa3N80|bxEv3mLridc9NEH0kruxi4&!iHltr%LqFFZ^FW$?u(K=14HADBFv&RyIYqRte{Z?mg*{#l=!s4xw-))UF<5&dH5uuNM zer}x8Uu1F{o4D^0wpj|d$2o!96c<_;r%B0IoPIQQ6L*oH86~MPkQ)upPw)u^dJn?= zjppB2(91h+ixNi`;yx#9$gu|De1tLwum(y^T9qkKoNn={;V}2OnTi3EkDDw3c&o%P zCUs%!wgA;ze4>%KB+hL8VTi)M+H5hL6Hbchz(lGc+8Z zkguzn7FFXP{q+;mqJ(KtQ>H~V?z%5ZJh|B)e-(45MdbyEtThlF!lB=jVukJ&T&p7YRDRb`ara>H%gbs3j3lEFSJAnViYBB znu%^U!!*m3j60t>QxZ><-a9VZUKJ^gcQdF+YlwS?I3o7rNG=?KZq^*+Rx54gi749+ zQ;6ZNiL^=3d#_EQM!RP(6&0izFZw{7XLUxFR7H{v-1-oEt}9v=a$Pvp!nu7MPgX*B zrf~WgN*}}MV|d)dMbe|x6>8Eo>T-seM#3Ft8j&;HbW@Y`#73VgEqcSNlxrVx=Mc%ozT=Xv3}1xPJQC7=B)iVM{b(ZREY-QeZ_%c%yi^ zd+5&L;<@*RNgC?kKFoX(=)eIcj^}VD4##ssjMlInL(KtVtTl8;xS18l8{Zp_&%eV= zVR#NT4W-EoYeGxHH;X^)9J(`X=WtFkT8MSH6ih?u9d1Lr5sF(=hDll_X!|hng0aeH zQelmbFNm@GOybL8%-Hbkc(*t5g+)v-|U-#C;gxv2RGdeJa#>b2Xc;oxugB8p5Zp~WV z<&qD}W-5nrO}LPPp;3RBMA5uRIV*@*+fwecVZl}ZF?ThiIm^I8` zEBPag#*tR!-s@0nInh^m(MA6Q)5Yqmoh)5b1_~|~GIp}St)P2AHTRVy6pH8Q3e(Bv zA~wpQ6<%@SKmQqH_==^^WtgLb43ao7g>zk(&IdD)9N{Eu^BB&v_IfteF&f#KW||W1 zP8KRN0c@J?HPK3*Zn{spiAKUpBjKl!Kvk4$LihdMiAMewmfuD*?$5HKWO~Vch2lk{ zTP><>e&P^!u=&e!g1h`5Hv1gQFql}}EaeU{`yLDF;VzI0mrC?4(&cHy(4Hcyy21En zi7DKyd!m8$=UszIJHq%oSzJcbL{8h)$!&bZNb3({#|Wzu<{A z8i8tm(F5GvC?jTWP>F+TRqevHmXwy^HqZY+qaT!Id#>Uu_l2Ik-Fa{M31ekNjSLbs<;MWxWgvFl!$~DQg6O0jcQI1 zAFW??)tw^^@#n%Fqf?_Yir!9)tI&CUQUCkf*%CXbpqgh*%P&$L) z+OjQ48`67vtg|Fl55MJ#L&G2b%E3nIj5LXLX0&9Q3HB@Nabf8ZxgHmmcFW6;$hh9m zXqw?>%)b26tB%RWR7Y$%TmNrPaTwOQ3DU^2e{&YrB$PepEJ`gbNzfU4db$EIDW3oi zvOw3O0@69m1y1?n3KbxiJ@3>Rtw}v?!E9IAJN!gLBJ>n1c0;lA|U-;S_Wq*;nE`4ntV>eOP)vwLr z_Lr!Obea8o&wnlY*i?L=v;0#1k*k{s(pJCX#3G8+?UnV7E>65aa}KR4a#p_#)WsT3xAfQ@2{+PT%`i8xe5W> zc;P+S?8D6s=5;GJ18^rcj z$f6H@1iGh4U%KPWf$n?E``n3UwfjMHQ@kw!^U>G}nNx#IQx6hICpK=BEA17sn{#w+ zw9D0%GD55EvRIAJ;(49XHYeVwQ)G}v`%^kZ z|AlNz5Sp++yW;rPLO`xkQm1(Gn36PUSYtgoP?8ocLG4Zz&-aMmH`=C_r0I-Gb9~UP zbu7>yBdN=lEfZdlD{?zXyO>xP(9X}iQoTo(CT^I6(^4sQs&?2_?Ym`Ds!5M-(b1u5 zmpJHW-h9gDk7i{Hz@wgYKr96^SR|z{$hMjBM*hMnu-7DmLz-W-1TvDJjYE*g_I{yo ze4C9_HOYk~Y2sy}QpS=-jNs?=K&JJ7lY!2^{EfX**5z@CgnXO0BT%45{^1_Sv~pr& z_}wR}3uJR}MSVzz=vziQ%D9fr4xaMjgP^!T{*xX@h;2cvRgUuqCeIzSO)-zr^H;vf zZ7fN1FA%xL>Mb(LRFVc(t+H)Fyb-BU(N&c)93^QzjeAh_XW<2NA!$^2eB}{`+BQ4h z=uQ?dVVRWRR-)VT3Plx<)FJ{$Uh|>Ki#6Y&erpmxr}tyGo71~VL0e1Dq}j!$iW`*0*&4ZLe+Q4w8ZhU ztrI_*qt-P^+9&Ro%@?{;9A`{=OIVHm*^a9v`o_&EI`Irm6l~CZYa^AQ>Lq04w|b@=(99WcKM3u?PsqFkIVLRSB2#=tlW>t_EcF|E!*eF!qYNs^j*>& zT-dTV4Y8j8vQ{~LY9J$^gmrbNN_C#5T>4d}_cL_$h zc!_LEUO$_bEUI@VZA7zVe(Pb!O@?(RydtSilNG5X%H|)uQZd@iPN}bit7r-BPsl;< z$zY#$G_-4jTs@bH)zQY69j;203+vM554ylao}(aFSX6a0 z<+QvM_MM-=o@z=o03J}8a*BX<2`|ZfbGO-OFO*NdB%8G&xBF#TnjmWTybR@Mdm!E@6e>;6&UC_z#CA$2s?m0L zpD=GTqRERl4TOgX2HDPb3Ug^YNRvUH&pjG1v9?)8Te6W~a#UK5Nsb=&1X1juj(FE7uHJDC+A>CcWb} z%99vGixS1xb@$@UM+f)5BtspbHynf}=Xx->P=_D1f_PeI+*2gSOBc~hbvb(TzjvqT z%v<^VqYnJkl4VBeov4mWPzpkd3`Q*~XrP|@(2mmCa{b7T(j>VqnUto=v>g?qUvY;a zq~c212wek}ACEp)A^OtfuTno%tW|G0W27$jkf`kO4`XS;r|CB+-zJ@_{a|M13ruh1|1n@n{xPm}lS;3gYW zPH5wA;Q!j=_!Q(FAJe4uxG7#jf+p@9d?=j7LkE}L$jE0S9Y<){)Qxb`p+@|6bDTaVN{Ueg{kJT%1O2xwtizgIHmt)syKHy|dUDyw4trE* z*-ag2K9s~k(y=jL76U4R@)b((!yW`;XLQy1GKy6R9vs0`n&FuEDMOT`DbhuEp~ldA zG3adEB14!E+0c&B;T>WoA9!3SmeC*A$ig!+R?_G`>rOb*D9XqVQ*!-H9p1W{&hI_8 zr&x~Db|;J9ch5Em$AE(78^@Q8>aaf}mksT(uaV2bJLrgBa!`3UiYH@Vk-1PL3VKGCFt#6$KUqw>uhHME>0LuL?lZEMh^HvKpN4gy zF^j6g&2+kN+*mB@DTiSlyNl&q^NPx7zlu6FOLf7mXa@R`9YgxVUyhZ0cGh! zI_X#pWdMrUi!Od0-Q`PhWTW^)@9T2!Yw-O;45U6-v13n|4;qXAfW22L+s*z{o{{^Z zGT#0=S~IX6EC|Fn*dFmxs`={1HFEXqXlBS)V!=dz=2Zo9U3kYaRcUyKLsK`j;}|I& z+M$E&s-8g~Mr2qA6->vd4ryB5s1EF%m5%B_L1`4)`5Q9Kbtv{2uU~jWuG%EW`Oty~ z(4bKr{=#dtWT+~geUr?cW@ua-6oqbp z5YZ>?Z_>`a8J*j{;W+>8iOO6AnpH(cQ}PBnykJ*B+zVi6GFzu+ttkm=VixB4Xm{mw z&SRQ6us%X7eL=P`^`Y%02|bN2AMqU6n~RpDMtDz8JZ1u$QCA0tw!>uD-Bh?aMJ1l7 zdI6GXkCxGz?QcU5qfxKHl+Ddxp7f5~5#A2l$8#s^{Mse_terW~@cv253#Fu;P9PB| zY>?|T?a>Jm^ir=Qj}i;-BleC$%sd8^Mpkc-o5W{9KQ-tbS^Sr}z;;t|T~NE>sgpEy zK2n$VIwk=NM$!q$HdSNui^2}ppHDX7X8~h-9l@Y%O)eeMZk=5k+-{y?L=+9bK#?nI z^xY}VdNIIFM8BOWHr8<4N&GY*Mys7Ed~mO0A4Nju%lZ*#0P#MXYG(?lj?lE1YT8p% z`3Fy$@8MHUqOdsPi&+{>u_?-HXA0CrMM)|RnWMaR&O!au=y#@|pPxVJhypX9)Yw?g z)P=T}Jtx<{C6|V_W9}g7tf?jgvW`~e%rVV1Qu(03KOje=I|wVYR4kj&BvUcYp%!+( zEt`i}2>s$hF`A z+w&lJw<7t0b(bGs_PtqS%ZOJNQHZy{Nay7<;*I5Fv1TFd*jl-0^R1+0>h&@L3Y##g zO_ymet}OLy$ILOB?Ftf^XjQ4UJ(`hx>@Ue;br)v;2(2vlMJIbf9vz6}Mw%SIZfQ!U z`4mwffA+FtJl}oD{<^dDrgk)K7>y>`Jf-37*gq$wZ_&8|f9H4RQFd27WIorF{nt4Dh3q~ zBE&J9wZ7QtMfgFzEOIE{Sxj&0l)_+#adUJR9cp2iz|xKHJf-Kgr*orK5K@{r-aLV3 zH?;laTQXhKmC1F(+E2bs7k9!R@DWU_FJx zIlkgAN&NUzs}4C%+5ae~N+*Or$^5Z%(Fx)qpWdzl>cM_Ec0-*fC5)CEn+N^e!#8mLNajb67i#bHDB zz*nx*thLU;{*PkyF>j92gHo=Z|5k#KExz$6z{xVXB%#s%g?#dla2W3V4keGbrlI7f zH0+P2*Ntu0N&fM|yKyI_&4-jZoItS*y{Mff!wu#^e5n`#UtX^vZpq!CSx;u-7Q z?sQrT7NzK(n>0r{^hw54ii&Z{*NOm)^9xhRGH*iMhwQ@=*;zzEt(@&$>=dhAPrYbLHx^S%;9?e&eORlE)7Hf<#(KMe8-PC>o|%4ZN8#62O3g$ z3Z_t%CD6i9pe3|dmU8Vy(0o+7VP`Um(8T+yn>N&@nzRx_ku(Osb<|(iw8et&xniMG z;|D*wy#v{-CL_O0=raWaplk4nn$^F&Mr(KFN^83y>X3~zuq6l!`MT>AN zWxN8cf@Otu$~k2^7)%do=by(QXGl@{qYAnuw%6=7(sYTmQUlxdG-YXEJ4Q`C%3T`N z-j~oqx>Ir~Ej%cZ5M+$0j9+`5rd_L{>>26$d?e+TgSSrCPNzD$_PP=6d8Bj%jfb=) z@q$;un`XiW0!s*{88hf!tY$6kiBN%2x=MWh0<#E=BSngZO1xdDrt@GZ zyz2Aox>4o3gZ0ci#l0v2S!iA1 z&0TX~MN;e?2T#Cmz`t{Z7E0F+!wN(zJSvwH+Ib$6doZcdq6*7kj1j-9^J!Q1OfcP| zwwoZ#x6&0W$w-=fRD1OErK8$m`@jTL^q~__EC(zqJ&NzE%SD-txqY(;qb&`^rRv*p zPN7)SH&Ps>z3>}QQzj%z|3$w&Z&8;+Q$QuabD^9;r$6`>EV-f%#;m>>BBF=3Hx;@V z$2mjVC0bE`+@jbRx1?^M9jtGLL(>iSst*K~lX_*k(};44XZhS?=nleGI++w|G4ByR zrlUft@R7WtR<>`IgFcqU(e_$7{+J5!HpUUO=OdZZpuRq$34l)J5ZErfFQcss4%)yz zkcAIr-grr)kN0NyzD&D~gL=cV4&hjF2`gni)?&g6Oo@T`h@6Xc9$HA>zyviBv5r&GIthb6#zhznCDyR>uwmxB3`CEtk9VDF^s0!a=8#UNRiCX-86NvZdj8!&DB>o8-bOA!RYHFYD zq(%}LK{~-@0vhWe!|W+o-)RAlVb*8MaC}22ZwXMwC=8@REl-lhonVF)NjymzXg~&^ zkpr8bB?o8*Q~=)DU$j&?La~E(iJ}f>`RXN#0kFi&khY5!ay=wdPGHvbvU}dpae~@N z8%^j|rWAv@%R*wS;^cLUM+!hKf~3FRMtX`T#g->vKp*_E@8*;Is>5jB z3QL`yF0f~S7py2@iKWX&$8E6FVZS4?6Kf61v7qjx=FCwr1-ezR4vLI<8_hld0e!|o z{5%p}mEc2b+7U;!La<4uet0vPlHdvCt=9xG$qq~zCk`psm%dK z{<+JJeUzi!Rkd;>OeIM3IZaa!|DZJ018F#;oiaxgM$?4jt3H+`-$HRz)mHTHQgX0S zyo4Z83x6r;gb%IAh}uIP8esKz$VGbi^pK`^jKnTI>7>nq9E29bs_v`H@etuL4lM$l zpc8uc8;S+=9Mr~VTuPx(9mhdKzsUcf~h7-R8ElqyVG zh>58vXA5gc34_B=-KuW3Nj#N{T~(|De>m3TIgZ;WWAWPcRE* zV{@*q_0ozzg}86x z4iz5yxOdTo6W^~o{lwYMvm?G^zdL(w_J!?NYOh${E&ua+A78)1l+-z~lhe{O9>~m6 z5yFtC>E^$3K7s@*KmM&D`3XFyQ8TK*Al(RD20w-y%jduL`Z(MSpc^srCVKv|wP9at z|1n#f;iM$~m;FV}jK1aW_}eDO->uvL>*fBtE5tCziL(jD83zn(mm#Q&RDJc!|HuvJ zH9*&UrEL6dnze?Hov33&J8)b-Egw|DFZ}&P>|D|%`QUK97+^o=#F=0Tr%GJ83Gpl5 zcG^joa28KdIM>(S4CE`jfSsr~O{zHvAFntxK*ny3;ItPy6JlR+;lCmCYcB`N@fl5Z z#)0~HAHD6*d_V)QY0#CcErE4}iS{$ykO{DPxn(>;ZSm;rWI&~0U(>4Mp* zi5~mxUk{j>JRI}!b6m;uJ2K6|d>lqe%GF167^aDs(k|i0=ujMC0ZyRlZ5eu- zT5r3gwMQ z$LzXzS&Ois1!qfEneOA?-p_y8sUxsTu6Vjj6CuZ25n zo499Li+GQHaf{wRk5i(>Ayq3|b}ep^f@$bxf4-$P7i7(i_7yF=7qp0fx6Vj4hw@ij z9Q8IL#tREUu)fe`0|1PU4{#yzp%1}pU}*oYOO~J7Pr_}wv;Vu z;csiUu$%cJ{GRT`w8bsh-FUKPH!?L~;_-M3au$Bq5`Xf^7U?dBUy7%9af{g}Pu{b* zW%uJPX4d|A3l1bO74iH_&2>+;(8B(%MF(Pazo(ww$6LgDymcTG&BplLS6QF$+H#+f zsPWZdpoa_BK{>fRo>4s1;`pf8xZ6FR_~{9=^af8x_QHpZkL41ci~Fkb1U>(?+_P%+ zTD*Vn@#L@f6c(Fb-~5h+Xw-q8_bRG9j*mY1)V00QbQzk zonTqjcZ9Gf8N&9e2#fP=>}kTVXBdV(i|;efu?%~jsMrgPioJ+YLEfyBH3Qx5PFSiP1t-=Sb)>-c*3GcTSJ6hw9Wjj=b!kewd zo8ewS-K$!Qf7fc^3#GdhdMRz<*#UZ|`&@SHeOF>eaZmMk;JKbOm(JgpbWfw$YpJB0 zn)uCYCE{Vy{Mr0{50iaZ-0P#SSSkmHs`e>Ajs2YxhR7<4oxSg2hK4JFNELkrp<*Dq zup*qV=rtp`mU$(!jOf4Uw#F^@;ZR<&iy4(2fHd`fq*zwqGnJ;1%)w0O5 zud<%qx8=SvsF7lPCw{_ukA*BET=W$hUT*Y;*U=yPK4zUJWm@l-5>u_yyusG##~U5G zMI_`#?2twTZomJ>!RCDq;s~-&BVGcOzb*F;%E&_WxyO&!ZExm}wKclb*vf)(17k*= zJ{L()DkH66e6@x{B|ADd6BcEbMR$bR=t`-?~Iw^V}bXtuJxt65(+pSp5K zyWp(yIxWrm%_*Kr>@A~_w!Js2aQ*$(Swd!;G$h4SQ8TOYfmvSeP1B@6>;0)Uv&<~Q zOw%o%8pN3HeJ`naUR&|fw#MQY+lpUrE8g5z{MWWE_icQ*ZR0C#`1!q!JKKzN7q$3H zqcD80YOybBiC$GH1@oP)l7Ii0As#bg^uh8!-&OyDtA4$!egn!k1Ew9$n!IK9#`!Ih zwn=!`$zd)sfA*5d0e{_ehSgYcaY{a|Pa{bmSkti)l1@?m8Q@iEFJ+g@Rz z6JK}z{YogFJFn31Q8xH0+yA?9APfhoPgUcG+J_0JLJh?sTYS5Ss0K<;lY)d$7|HPE z5z_9ELLJGN5Xc?`Z@t5iNkEW;;>q^y83X@!fS0uv^%VK^KX$Uhib9_oFO`T_DY!eqkUv)Rb@EoN=SdRs3OhW~}SINuzr`3J`toQG9~f!ZEVD3?1YyZ za8iNrJO3gwJ1bU<;mvkC$Gd|iwc8_>Z-EKHv1n61zakXpmBi(Nt&}UpXtqKAP__tUgLndMcZ>Y*gT}1U>Qn%BC{p9X@l0#7-INW z+)?P<)f?*Ax<$Jo7`jGVBx(748F;8MJAvN8XL#d^J8nU21sznKV=LH1#*H;WJrMhLjrkn-c~4uHPvTg^%k=w3D%^<>E}YGf z#2LFP3<8DxP&o*LtTlLnC$l=&@Ki{Y;}SjrG>xy{7K$2@uA+vF+I)j_)vBdNM^lh( zSROH9)3PSWq`}qz#D(K&d10pUR&8{!F3*R5@G}1qN?n^D=VN;xbqo%{9vtBAyv<_B z3$>pN70!hUB+SUT_ib;nFgsfD6`6(U*ddT@`z$+Jwpm&mKDV@p4cm4Ig7S%<4ud)U z<`iG{@w7MK+f$|;4IbkMR(2d#cKpiAHp~CV-gy81OhIwLO?*oh+%I)#K?^iv9V$l!3Zlxv7iwJj9w5_>`J5wiVy%jdO`n+QZHqlIW{|`jDJG+O})1G z6N>sy)AB@_{-o+_$%b{@lMY5vZZpCB5Se&zQQm`{4ZD2HOO}4_tJ>?U{D89hvyae! z@dcOpmJc#Y>z7hmF*a2))3WlT%8wU)ozh5|4SG8@=KZ|rqoem%e)IsB)_yhD{@``r z?D}ZeM|yevlJfff1Z(AogtB?3Lhl=Xp0Vp2%IeXLjW4bLnu6LW1@)-|1$F7-Jv*l_ zZ&O_y9F!=ipHomb9PNpJzH3kYobbtdQTxKT{0FHNM*dpciaW#30D)jnUvPa%^*fUvv`YxsTW#g&(X{V{)iMHNKBKCyOk%X-O*0=nd#k)x>7dEW;TrcgP8l`>r z)5VJRdg2CcGHwu`8q_`d&C!eZ7rxx(D-sz|O|h{UEyoAWhmBo1)1>lO5MO_PPLcw0X(#o#E z`+Y=__yucyYd@9ZUT>|vgXf2g;92{@SKP2}`;Laq&(v)D z=C!ZCKuh6&re^gAAAPQP+Pv{*rmC0zwu#bDsZTC)?cb~Shj~j&>#F9ye)N{A(mGk| zRLh4Ke+w;cS;6#SaOvFFxl&pxUvhlXmGW&@n#BiTX_h?7sqVR}&~(ADwA;R7W#E88 z1AC1+vta1ZQ8|MKoLO-Am(HK2|7CK3gVi|3&>iHD<3o-YHSw1?bS8P47FSP7UP5g? z3aJl=u_c`!dl(A`pQwc|c?VfK{Fz!<(~p=-SWO(gbI?IqSmC&!=D#yIt?KZHVYyqL zVU;-5<@BKiXAK`Pw4iS=!clUAI2UYa4?Pj*42cvC7&5pQ=QJiSoGYj31cPTa2ZeA( z5a-5ekwb&0%Mp}=@udgmLkoKK)z7=r9i1IKCwcK)F6yUq87EfeHV2fnaJ25C*TF96 zTjB;B@UTzw7R`Dr`t;&#yCMDc>%(;Sk>KgZ9?m^<3&RTZb068$S-)BsJZD&VNYS}^ zTF&4!yP-#g2mO~Ri+@Js-=70LhASM{(aD>0s+YZiG;_#W#D|;9N!U>hJDi-O+fiHEu_f$ihMf)xJBc(z%(BhDFK4heF+ikpa=nI{ zrR8L6Ia%67pKQ3_H|J%q!Vc6UrpfUkoK<2X&dRh?;WTfki6ob%YdPIDSJ{E2k_{x) zrKeT7Iz#Kc$I`8p;$pAM5qYJZyrGo*Fxy`9|Kp}ST)XfVC1mYuTXj`CmZ$$%P-c?48T^=ncmQG+!<^miqJuun1K)M(talAkdy-{ ziH|j<#4j+J<7K9l*bnTOZskl0JLgt-%|87cjS%`{(RW9G267+h2Lmu0WNw>0FC#vI z>vB%Ubj+)eZ%2Lrc?I&b$ef80-+}x->W8@7jrtkt*IfG+I1?lO6Z$4pi=}PM&bEbV zz&_(K&Vr6*LOTdTN63XPa6FvImWQX}rYGtE)WMjIg>f(*E`&?DHkE5vAy0=H=&!f5 zjn}Y6;{E6sqkq_9jx9r8f&93|5_=N$8B1F^ildKa7G=|5;)5zDbD+pRd#|p0RkqOc zDY6Zk*7o23K>nLU9Io&G_LIgIgw6ZE|C^(5xZsj!j_g5jtgNeavK#g@*MD4-^K_jO zm)*zf*mU>1S&ZtN;tr;PKkzYTiV11)$9FFNq&VrmCMRL{5F5(K6cZbj1`F9zEfkdP zVAU%*+{l^LnJ!x%u&Zy;!UL6wx3K-I$y{OKbR%|lGj-2ZRQ9XofTXrc$du#L*wU>m zYRMUjkUd4;(-zCJ=RLKmPs91Np&I*D%JyuWG@|dUA1*SSvVm@yQf{U)!IR>s(wn_s z6Pj`}8^$4HrPwekiz=nJYWd+zv4UhSo_ecBu!z~?igswDEl5R^ykpqxSK?|VuC5>hcc z(p<(agDLXr_E1idP$>GkiHgWZ%pufJ7&QlVA8IFaS*E8GP&a6dc<55uFd z5}tw8@Cr1*o4^Y{_8BB!_&*}=2gbx=HjtOS3h9u1*&m6_%RP1)^ngAPh9L~R>8G?L zHnm;9x`8dyiX1;_NZYn=i8v;Ck=DI|*#?nhK0=XWi->P-T(_yOW2O&r!;2hz^@2#u zSlIDufrGsM^Y8EEz!H<3|52c2Dhm?le{HMZSihyA2(t^d8QP879IaZrUE8d^rR~zJ z-c;{E?+kCH_Xh8c-r3$N?;LO3dzV+=`Lvvxf){5Vu+e)OZ&X)_yh-!qg-O+sI0J?w zV`LN5JQ}rzW&P+-wpy1B?vuaDn1n8|QEI{}ueBy=U9)*=iB*CyyGrDPg^DC96$@`z zjwsDw)A0oyF(Y!Tq--S;%|WM&o2VW+q|w$;CW>tG9W_%8_6^(FYTjI74zJ_F@P=LQ<+##=-6t=G#6@1oANVucs*Gv*FVsG@k{0 z@5DF|E*1p3e`B2>2XY|h}dh`{Sdp2T;GfNub`OP$L*%o)i0kS`=oNF2c_Ur4VvY}~$X^^SfF3h3r9t`*G@ zNzEt?muuI*SmdBn;D7kvDy!80r)iy(j6mZ2uYTGM+C$p6T9)@dZ#&;?-;+MGf2{v1 z|7QP>i5F^e*HWpYsoFW-%goo5h{mam6_(IT`l*alIZ{MEdr~+zx||A_3;E?Kzq=?0 zgXtbLJ6?Z~V@?J!U3siV{hGnKC9-XHMM`LGuGIVDzd6^gzjsQpk};BwDT`qxYOdfy zxieu^d`L~aR2+%ulv|Vvt5RVLZPf$Ji(2JK4Wcv6%v*tTQ{)TL+E>01t@4E!9>I?~ znMs4ZABcx7Mv;;B zkQA8|N{HDc&y)UG>xJ_KX*?y0U4EE%L!wym%u@Qwt)WfH5|<|qQz9?Z1yUdnT}sQt zS~uwrn(;K-ESz)B{`ei_h!`=ljZ`g^OB?=iL{Wt!YOP3BDqNwLb8U%d-8EX}m>db< zkLSwcq{S$LQvPjB{6lKdZ7Sdrbv=41ITvWtyjsqya+Y__U0#mR z$@$JJCk37Flaqqp_Q@GR$NA;RoxA;V*v?x0Sf4NDSf9vP4yNicO367*_hY&?&9CLu z=sta+aRPV3KacKTy6)dppB(M;i0Ca$8g?&$=}-f&!WZDt+r^6cJJfXCo)1&u5qKMZf#YyL z0xpHSVJ&>gm%W#^4DZNTI{Xu-{KQ9dboaTmfi6Skk%-@pdMAD?Mt%nQdDQiaFSZf& z6ZCsf9j3H+FOxeK;R}BZNH4)MU@EHg1jOIuIPG_kKR|YIY_*54^VZNAy3s9vCT4?? zhr+q&FF{YwK>Rw?8&DUc)^hDJwBa$s91GEf?c?K#$#ccug1iY(r8^Tazeb&^HtUZ$uM7ic9GdJvm>htK02mE%X44EqqMJ2j&zg9(Z7^VnE3yByWzv%)jv)D({dnD5Nh%}(3w?YRXI%P<0g93|WE`aGc(p zbEek2Q}|R0e6dR};8BI5$&o{C%Q?|eifSOMTvQ7NiK1L$_5~7UnJ+jQb1RlF5BYov zRplpyMDS*nfiHqL^N~bYoO5J$6`kdsYze1xtfSa2qC4SPiBtZ3G0)f&%8hVyB+YZLF% z2*mK2L?}Ga*a(@X(fKxQ2{Q&3!o5HPV(NXE)k56pdMvHdLXJQGO5$QEGJh!ln7n$6G3ue0U<=@YYbPZexwe^Kk3E0|X^wzkFSpqqam)DH4=T z4=SZ3r8%e+3CdBDk_akA56Tg>=|QDPLhfzKi$oIP^#7x9Y{irQzMrlV-NPp+mZ?%w zcrE&r()+cE4{K%U$L^CdI>xv%I9DMRr8SIvm)@(Hr#&pTil^SMl|GQPAF@i(PuQmf zmfoxlb}5PLBny3Lx;&A|AZ})!&du7GqFXX1)@r5qX+;g`MSsf>{b3*UtAA%nic+h- za)_=Jo+W6g5+;gjrA~+hlIC(*DhsJ7nk$d{w1dLL8AA)lDiW6^x^E;E6XIW^yQay( zg@dBNFlb1d#8d86)S`H+$PeVB2}=@Qzwq%1zg)x&KSHhg8J@X_N`(1OdOZKwzqb

2MI!ce( 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

    -pZ8%RR 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 Date: Tue, 6 Mar 2018 22:24:42 -0800 Subject: [PATCH 015/147] 65802 VM updates --- src/vmsrc/apple/plvm03.s | 2 +- src/vmsrc/apple/plvm802.s | 254 ++++++++++++++++++++++++++------------ 2 files changed, 175 insertions(+), 81 deletions(-) diff --git a/src/vmsrc/apple/plvm03.s b/src/vmsrc/apple/plvm03.s index eb2e2ab..f7eb269 100755 --- a/src/vmsrc/apple/plvm03.s +++ b/src/vmsrc/apple/plvm03.s @@ -938,7 +938,7 @@ SEL INX LDA #$00 TAY ADC IPH - STA TMPH ; ADD BRANCH OFFSET + STA TMPH ; ADD CASEBLOCK OFFSET LDA (TMP),Y ;CLC ; BETTER NOT CARRY OUT OF IP+Y ADC TMPL diff --git a/src/vmsrc/apple/plvm802.s b/src/vmsrc/apple/plvm802.s index 5335412..564ecef 100644 --- a/src/vmsrc/apple/plvm802.s +++ b/src/vmsrc/apple/plvm802.s @@ -231,14 +231,17 @@ VMCORE = * ;* * ;**************** !ALIGN 255,0 -OPTBL !WORD ZERO,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 00 02 04 06 08 0A 0C 0E - !WORD NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 10 12 14 16 18 1A 1C 1E - !WORD LNOT,LOR,LAND,LA,LLA,CB,CW,CS ; 20 22 24 26 28 2A 2C 2E - !WORD DROP,DUP,NEXTOP,DIVMOD,BRGT,BRLT,BREQ,BRNE ; 30 32 34 36 38 3A 3C 3E - !WORD ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E - !WORD BRNCH,IBRNCH,CALL,ICAL,ENTER,LEAVE,RET,CFFB ; 50 52 54 56 58 5A 5C 5E - !WORD LB,LW,LLB,LLW,LAB,LAW,DLB,DLW ; 60 62 64 66 68 6A 6C 6E - !WORD SB,SW,SLB,SLW,SAB,SAW,DAB,DAW ; 70 72 74 76 78 7A 7C 7E +OPTBL !WORD CN,CN,CN,CN,CN,CN,CN,CN ; 00 02 04 06 08 0A 0C 0E + !WORD CN,CN,CN,CN,CN,CN,CN,CN ; 10 12 14 16 18 1A 1C 1E + !WORD MINUS1,NEXTOP,NEXTOP,LA,LLA,CB,CW,CS ; 20 22 24 26 28 2A 2C 2E + !WORD DROP,DROP2,DUP,DIVMOD,ADDI,SUBI,ANDI,ORI ; 30 32 34 36 38 3A 3C 3E + !WORD ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E + !WORD BRNCH,SEL,CALL,ICAL,ENTER,LEAVE,RET,CFFB ; 50 52 54 56 58 5A 5C 5E + !WORD LB,LW,LLB,LLW,LAB,LAW,DLB,DLW ; 60 62 64 66 68 6A 6C 6E + !WORD SB,SW,SLB,SLW,SAB,SAW,DAB,DAW ; 70 72 74 76 78 7A 7C 7E + !WORD LNOT,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 80 82 84 86 88 8A 8C 8E + !WORD NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 90 92 94 96 98 9A 9C 9E + !WORD BRGT,BRLT,INCBRLE,ADDBRLE,DECBRGE,SUBBRGE,BRAND,BROR ; A0 A2 A4 A6 A8 AA AC AE ;* ;* ENTER INTO BYTECODE INTERPRETER - IMMEDIATELY SWITCH TO NATIVE ;* @@ -482,14 +485,17 @@ LCDEFCMD = *-28 ; DEFCMD IN LC MEMORY ;* * ;***************** !ALIGN 255,0 -OPXTBL !WORD ZERO,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 00 02 04 06 08 0A 0C 0E - !WORD NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 10 12 14 16 18 1A 1C 1E - !WORD LNOT,LOR,LAND,LA,LLA,CB,CW,CSX ; 20 22 24 26 28 2A 2C 2E - !WORD DROP,DUP,NEXTOP,DIVMOD,BRGT,BRLT,BREQ,BRNE ; 30 32 34 36 38 3A 3C 3E - !WORD ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E - !WORD BRNCH,IBRNCH,CALLX,ICALX,ENTER,LEAVEX,RETX,CFFB ; 50 52 54 56 58 5A 5C 5E - !WORD LBX,LWX,LLBX,LLWX,LABX,LAWX,DLB,DLW ; 60 62 64 66 68 6A 6C 6E - !WORD SB,SW,SLB,SLW,SAB,SAW,DAB,DAW ; 70 72 74 76 78 7A 7C 7E +OPXTBL !WORD CN,CN,CN,CN,CN,CN,CN,CN ; 00 02 04 06 08 0A 0C 0E + !WORD CN,CN,CN,CN,CN,CN,CN,CN ; 10 12 14 16 18 1A 1C 1E + !WORD MINUS1,NEXTOP,NEXTOP,LA,LLA,CB,CW,CSX ; 20 22 24 26 28 2A 2C 2E + !WORD DROP,DROP2,DUP,DIVMOD,ADDI,SUBI,ANDI,ORI ; 30 32 34 36 38 3A 3C 3E + !WORD ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E + !WORD BRNCH,SEL,CALLX,ICALX,ENTER,LEAVEX,RETX,CFFB ; 50 52 54 56 58 5A 5C 5E + !WORD LBX,LWX,LLBX,LLWX,LABX,LAWX,DLB,DLW ; 60 62 64 66 68 6A 6C 6E + !WORD SB,SW,SLB,SLW,SAB,SAW,DAB,DAW ; 70 72 74 76 78 7A 7C 7E + !WORD LNOT,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 80 82 84 86 88 8A 8C 8E + !WORD NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 90 92 94 96 98 9A 9C 9E + !WORD BRGT,BRLT,INCBRLE,ADDBRLE,DECBRGE,SUBBRGE,BRAND,BROR ; A0 A2 A4 A6 A8 AA AC AE ;********************************************************************* ;* ;* CODE BELOW HERE DEFAULTS TO NATIVE 16 BIT A/M, 8 BIT X,Y @@ -706,25 +712,6 @@ SHR PLA STA TOS,S + JMP NEXTOP ;* -;* LOGICAL AND -;* -LAND PLA - BEQ LAND1 - LDA TOS,S - BEQ LAND2 - LDA #$FFFF -LAND1 STA TOS,S -LAND2 JMP NEXTOP -;* -;* LOGICAL OR -;* -LOR PLA - ORA TOS,S - BEQ LOR1 - LDA #$FFFF - STA TOS,S -LOR1 JMP NEXTOP -;* ;* DUPLICATE TOS ;* DUP LDA TOS,S @@ -734,17 +721,57 @@ DUP LDA TOS,S ;* LOGICAL NOT ;* LNOT PLA - BNE ZERO + BNE + PEA $FFFF JMP NEXTOP -;* -;* CONSTANT -;* -ZERO PEA $0000 ++ PEA $0000 JMP NEXTOP -CFFB INY ;+INC_IP +;* +;* ADD IMMEDIATE TO TOS +;* +ADDI INY ;+INC_IP LDA (IP),Y - ORA #$FF00 + AND #$00FF + CLC + ADC TOS,S + STA TOS,S + JMP NEXTOP +;* +;* SUB IMMEDIATE FROM TOS +;* +SUBI INY ;+INC_IP + LDA (IP),Y + AND #$00FF + EOR #$FFFF + SEC + ADC TOS,S + STA TOS,S + JMP NEXTOP +;* +;* AND IMMEDIATE TO TOS +;* +ANDI INY ;+INC_IP + LDA (IP),Y + AND #$00FF + AND TOS,S + STA TOS,S + JMP NEXTOP +;* +;* IOR IMMEDIATE TO TOS +;* +ORI INY ;+INC_IP + LDA (IP),Y + AND #$00FF + ORA TOS,S + STA TOS,S + JMP NEXTOP +;* +;* CONSTANT -1, NYBBLE, BYTE, $FF BYTE, WORD (BELOW) +;* +MINUS1 PEA $FFFF + JMP NEXTOP +CN TXA + LSR ; A = CONST * 2 PHA JMP NEXTOP CB INY ;+INC_IP @@ -752,6 +779,11 @@ CB INY ;+INC_IP AND #$00FF PHA JMP NEXTOP +CFFB INY ;+INC_IP + LDA (IP),Y + ORA #$FF00 + PHA + JMP NEXTOP ;* ;* LOAD ADDRESS & LOAD CONSTANT WORD (SAME THING, WITH OR WITHOUT FIXUP) ;* @@ -990,7 +1022,10 @@ SW TYX LDA NOS,S STA (TOS,S),Y TXY - PLA +;* +;* DROP TOS, TOS-1 +;* +DROP2 PLA JMP DROP ;* ;* STORE VALUE TO LOCAL FRAME OFFSET @@ -1137,18 +1172,53 @@ ISLT PLA ;* ;* BRANCHES ;* +SEL TYA ; FLATTEN IP + CLC + ADC IP + INY ;+INC_IP + ;CLC ; ADD BRANCH OFFSET (BETTER NOT CARRY OUT OF IP+Y) + ADC (IP),Y + STA IP + LDY #$00 + LDA (IP),Y + TAX ; CASE COUNT + BEQ ++ + INC IP + PLA +CASELP CMP (IP),Y + BEQ +++ + INY + INY + INY + INY + BNE + + +ACCMEM8 ; 8 BIT A/M + INC IPH + +ACCMEM16 ; 16 BIT A/M ++ DEX + BEQ CASELP +FIXNEXT TYA + LDY #$00 + SEC + ADC IP + STA IP +++ JMP NEXTOP ++++ INY + BRA BRNCH +BRAND LDA TOS,S + BEQ BRNCH + PLA ; DROP LEFT HALF OF AND + BNE NOBRNCH +BROR LDA TOS,S + BNE BRNCH + PLA ; DROP LEFT HALF OF OR + BNE NOBRNCH BRTRU PLA BNE BRNCH NOBRNCH INY ;+INC_IP INY BMI FIXNEXT JMP NEXTOP -FIXNEXT TYA - SEC - ADC IP - STA IP - LDY #$00 - JMP FETCHOP BRFLS PLA BNE NOBRNCH BRNCH TYA ; FLATTEN IP @@ -1160,42 +1230,66 @@ BRNCH TYA ; FLATTEN IP STA IP LDY #$01 JMP FETCHOP -BREQ PLA - CMP TOS,S - BEQ BRNCH - BNE NOBRNCH -BRNE PLA - CMP TOS,S - BNE BRNCH - BEQ NOBRNCH -BRGT PLA +;* +;* FOR LOOPS PUT TERMINAL VALUE AT ESTK+1 AND CURRENT COUNT ON ESTK +;* +BRGT LDA NOS,S SEC SBC TOS,S BVS + BPL NOBRNCH - BMI BRNCH -+ BMI NOBRNCH - BPL BRNCH -BRLT PLA - SEC - SBC TOS,S - BVS + - BMI NOBRNCH - BEQ NOBRNCH - BPL BRNCH -+ BMI BRNCH - BEQ BRNCH - BPL NOBRNCH -IBRNCH TYA ; FLATTEN IP - CLC - ADC IP - STA IP + PLA ; DROP FOR VALUES PLA - ;CLC ; ADD BRANCH OFFSET (BETTER NOT CARRY OUT OF IP+Y) - ADC IP - STA IP - LDY #$01 - JMP FETCHOP + BRA BRNCH ; BMI BRNCH +BRLT LDA TOS,S + SEC + SBC NOS,S + BVS + + BPL NOBRNCH + PLA ; DROP FOR VALUES + PLA + BRA BRNCH ; BMI BRNCH ++ BMI NOBRNCH + PLA ; DROP FOR VALUES + PLA + BRA BRNCH ; BMI BRNCH +DECBRGE LDA TOS,S + DEC + STA TOS,S +_BRGE LDA TOS,S + SEC + SBC NOS,S + BVS + + BPL BRNCH + PLA ; DROP FOR VALUES + PLA + BRA NOBRNCH ; BMI NOBRNCH +INCBRLE LDA TOS,S + INC + STA TOS,S +_BRLE LDA NOS,S + SEC + SBC TOS,S + BVS + + BPL BRNCH + PLA ; DROP FOR VALUES + PLA + BNE NOBRNCH ; BMI NOBRNCH ++ BMI BRNCH + PLA ; DROP FOR VALUES + PLA + BRA NOBRNCH ; BMI NOBRNCH +SUBBRGE LDA NOS,S + SEC + SBC TOS,S + STA NOS,S + PLA + BRA _BRGE +ADDBRLE PLA + CLC + ADC TOS,S + STA TOS,S + BRA _BRLE ;* ;* INDIRECT CALL TO ADDRESS (NATIVE CODE) ;* From b0a9cb3e0efce1aa2b54805a40cb86b94e371135 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Wed, 7 Mar 2018 20:05:17 -0800 Subject: [PATCH 016/147] Update images --- PLASMA-BLD1.PO | Bin 143360 -> 0 bytes PLASMA-BLD2.PO | Bin 143360 -> 143360 bytes PLASMA-DEM1.PO | Bin 143360 -> 0 bytes PLASMA-DEM2.PO | Bin 143360 -> 143360 bytes PLASMA-SOS1.PO | Bin 143360 -> 0 bytes PLASMA-SOS2.PO | Bin 143360 -> 143360 bytes PLASMA-SYS1.PO | Bin 143360 -> 0 bytes PLASMA-SYS2.PO | Bin 143360 -> 143360 bytes 8 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 PLASMA-BLD1.PO delete mode 100644 PLASMA-DEM1.PO delete mode 100644 PLASMA-SOS1.PO delete mode 100644 PLASMA-SYS1.PO diff --git a/PLASMA-BLD1.PO b/PLASMA-BLD1.PO deleted file mode 100644 index bb1d25479ab4c0e69fae7455f9a2bd7d08c0b334..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 143360 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

    2MI!ce( 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

      -pZ8%RR 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 delta 33583 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 From ce29a7c361fe421cc81a2ba3d8ee75f87f5f54c5 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Fri, 9 Mar 2018 19:50:31 -0800 Subject: [PATCH 017/147] 65802 bug fixes --- src/vmsrc/apple/plvm02.s | 8 ++--- src/vmsrc/apple/plvm03.s | 6 ++-- src/vmsrc/apple/plvm802.s | 76 +++++++++++++++++++++------------------ 3 files changed, 49 insertions(+), 41 deletions(-) diff --git a/src/vmsrc/apple/plvm02.s b/src/vmsrc/apple/plvm02.s index 7c0c0c6..0875fa8 100755 --- a/src/vmsrc/apple/plvm02.s +++ b/src/vmsrc/apple/plvm02.s @@ -348,7 +348,7 @@ CMDENTRY = * ; PRINT FAIL MESSAGE, WAIT FOR KEYPRESS, AND REBOOT ; FAIL INC $3F4 ; INVALIDATE POWER-UP BYTE - LDY #33 + LDY #31 - LDA FAILMSG,Y ORA #$80 JSR $FDED @@ -1335,12 +1335,12 @@ CASELP CMP (IP),Y INY FIXNEXT TYA LDY #$00 - CLC + SEC ADC IPL STA IPL BCC ++ INC IPH -++ JMP NEXTOP +++ JMP FETCHOP BRAND LDA ESTKL,X ORA ESTKH,X BEQ BRNCH @@ -1428,7 +1428,7 @@ _BRLE LDA ESTKL+1,X BVS + BPL BRNCH INX ; DROP FOR VALUES - INX + INX BNE NOBRNCH ; BMI NOBRNCH + BMI BRNCH BPL - diff --git a/src/vmsrc/apple/plvm03.s b/src/vmsrc/apple/plvm03.s index f7eb269..d17fada 100755 --- a/src/vmsrc/apple/plvm03.s +++ b/src/vmsrc/apple/plvm03.s @@ -977,12 +977,12 @@ CASELP CMP (IP),Y INY FIXNEXT TYA LDY #$00 - CLC + SEC ADC IPL STA IPL BCC ++ INC IPH -++ JMP NEXTOP +++ JMP FETCHOP BRAND LDA ESTKL,X ORA ESTKH,X BEQ BRNCH @@ -1060,7 +1060,7 @@ _BRLE LDA ESTKL+1,X BVS + BPL BRNCH - INX ; DROP FOR VALUES - INX + INX BNE NOBRNCH ; BMI NOBRNCH DECBRGE DEC ESTKL,X LDA ESTKL,X diff --git a/src/vmsrc/apple/plvm802.s b/src/vmsrc/apple/plvm802.s index 564ecef..a7312ce 100644 --- a/src/vmsrc/apple/plvm802.s +++ b/src/vmsrc/apple/plvm802.s @@ -246,28 +246,6 @@ OPTBL !WORD CN,CN,CN,CN,CN,CN,CN,CN ; 00 02 ;* ENTER INTO BYTECODE INTERPRETER - IMMEDIATELY SWITCH TO NATIVE ;* !AS -DINTRP PHP - PLA - STA PSR - SEI - CLC ; SWITCH TO NATIVE MODE - XCE - +ACCMEM16 ; 16 BIT A/M - PLA - INC - STA IP - STX ESP - TSX - STX HWSP - LDX #>OPTBL -!IF DEBUG { - BRA SETDBG -} ELSE { - STX OPPAGE - LDY #$00 - JMP FETCHOP -} - !AS IINTRP PHP PLA STA PSR @@ -422,7 +400,7 @@ CMDENTRY = * ; PRINT FAIL MESSAGE, WAIT FOR KEYPRESS, AND REBOOT ; FAIL INC $3F4 ; INVALIDATE POWER-UP BYTE - LDY #33 + LDY #31 - LDA FAILMSG,Y ORA #$80 JSR $FDED @@ -496,6 +474,28 @@ OPXTBL !WORD CN,CN,CN,CN,CN,CN,CN,CN ; 00 02 !WORD LNOT,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 80 82 84 86 88 8A 8C 8E !WORD NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 90 92 94 96 98 9A 9C 9E !WORD BRGT,BRLT,INCBRLE,ADDBRLE,DECBRGE,SUBBRGE,BRAND,BROR ; A0 A2 A4 A6 A8 AA AC AE + !AS +DINTRP PHP + PLA + STA PSR + SEI + CLC ; SWITCH TO NATIVE MODE + XCE + +ACCMEM16 ; 16 BIT A/M + PLA + INC + STA IP + STX ESP + TSX + STX HWSP + LDX #>OPTBL +!IF DEBUG { + JMP SETDBG +} ELSE { + STX OPPAGE + LDY #$00 + JMP FETCHOP +} ;********************************************************************* ;* ;* CODE BELOW HERE DEFAULTS TO NATIVE 16 BIT A/M, 8 BIT X,Y @@ -1173,7 +1173,7 @@ ISLT PLA ;* BRANCHES ;* SEL TYA ; FLATTEN IP - CLC + SEC ADC IP INY ;+INC_IP ;CLC ; ADD BRANCH OFFSET (BETTER NOT CARRY OUT OF IP+Y) @@ -1182,37 +1182,42 @@ SEL TYA ; FLATTEN IP LDY #$00 LDA (IP),Y TAX ; CASE COUNT + PLA + CPX #$00 BEQ ++ INC IP - PLA CASELP CMP (IP),Y BEQ +++ + DEX + BEQ + INY INY INY INY - BNE + + BNE CASELP +ACCMEM8 ; 8 BIT A/M INC IPH +ACCMEM16 ; 16 BIT A/M -+ DEX - BEQ CASELP + BRA CASELP ++ INY + INY + INY FIXNEXT TYA LDY #$00 SEC ADC IP STA IP -++ JMP NEXTOP +++ JMP FETCHOP +++ INY BRA BRNCH BRAND LDA TOS,S BEQ BRNCH PLA ; DROP LEFT HALF OF AND - BNE NOBRNCH + BRA NOBRNCH BROR LDA TOS,S BNE BRNCH PLA ; DROP LEFT HALF OF OR - BNE NOBRNCH + BRA NOBRNCH BRTRU PLA BNE BRNCH NOBRNCH INY ;+INC_IP @@ -1273,7 +1278,7 @@ _BRLE LDA NOS,S BVS + BPL BRNCH PLA ; DROP FOR VALUES - PLA + PLA BNE NOBRNCH ; BMI NOBRNCH + BMI BRNCH PLA ; DROP FOR VALUES @@ -1689,6 +1694,9 @@ DBGTBL !WORD STEP,STEP,STEP,STEP,STEP,STEP,STEP,STEP ; 00 02 04 06 08 !WORD STEP,STEP,STEP,STEP,STEP,STEP,STEP,STEP ; 50 52 54 56 58 5A 5C 5E !WORD STEP,STEP,STEP,STEP,STEP,STEP,STEP,STEP ; 60 62 64 66 68 6A 6C 6E !WORD STEP,STEP,STEP,STEP,STEP,STEP,STEP,STEP ; 70 72 74 76 78 7A 7C 7E + !WORD STEP,STEP,STEP,STEP,STEP,STEP,STEP,STEP ; 80 82 84 86 88 8A 8C 8E + !WORD STEP,STEP,STEP,STEP,STEP,STEP,STEP,STEP ; 90 92 94 96 98 9A 9C 9E + !WORD STEP,STEP,STEP,STEP,STEP,STEP,STEP,STEP ; A0 A2 A4 A6 A8 AA AC AE ;* ;* DEBUG PRINT ROUTINES ;* @@ -1848,8 +1856,8 @@ STEP STX TMPL CMP #$10 BCC DBGKEY LDX TMPL - CPX #$00 ; FORCE PAUSE AT 'ZERO' - BEQ DBGKEY +; CPX #$00 ; FORCE PAUSE AT 'ZERO' +; BEQ DBGKEY - LDX $C000 CPX #$9B BNE + From 9dbb1671a45133df8c0cc20da1449306e5041410 Mon Sep 17 00:00:00 2001 From: Dave Schmenk Date: Fri, 9 Mar 2018 20:40:50 -0800 Subject: [PATCH 018/147] Update images --- PLASMA-SOS2.PO | Bin 143360 -> 143360 bytes PLASMA-SYS2.PO | Bin 143360 -> 143360 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/PLASMA-SOS2.PO b/PLASMA-SOS2.PO index 2c2e83a565287622418e55bb3e080a469720313c..6e6497090eafb7afcab1af2458c71223dba53167 100644 GIT binary patch delta 53 zcmZp8z|ru4V}mmbud9lc5C_9!28K)(W|7SSEKEY&7O9_FKTTkI_SxrSbF5fk^s&M5yk)j delta 53 zcmZp8z|ru4V}mmbuZxP5fHK2l28MJMbK%VaEKEY&5~-hBKTTkI_Sxq{bF5fk^s+}5zYVr diff --git a/PLASMA-SYS2.PO b/PLASMA-SYS2.PO index 26c5fe47bd47ae1574307d4209450c4be0f69345..d1fe04cf54e0c77b3ba80ecd785471d1610fcf49 100644 GIT binary patch delta 669 zcmZp8z|ru4W5Yxi-V9}ZVGf4J3=Ekn%p#NLv4{)sa5LztFpI(kHy>qLsmmz8Ip0W; zgWDqYQ|qS*OwT_1eB35Vu!$YA07e51}4v|_@VRF4-6j|lCPRy^S@efwc_e~ zhG*BlUJ1X#byec3=2f$+IoB(%&$zzjdfWA7*ClW8-;lX+?0V;owi|Ibr`)`CGxF-& ztADS$T?@U|ac$-`-s^JL&t1EB?UnVlKi9Oc+g|s(9)JD!mD886Tz+xc`ij?;MORi` znSN!{l|5IETsd>)%9Y1g?p@ZpVSXd#M%@js8znawZ*bh0e8W*gdNX53>!*yir@Pu- z^)VkEfpk@~1xVodALhpC2ha`+P{D;WdymV*vv=%>YC7 uM1%BV#t-5d4P1*EF9>8bZ2sx(!N_=dvXk$D$pTFGnwk8zGx;(8dk6rGUv9bp delta 659 zcmZp8z|ru4W5Yxi-uc}O0?G`J85q)4%!Mb}dUz z(e`v#+p9k21B&uK9E;=*J` zCYebtyp#VKJ)30AR*ydb^sb=>K^9R#aN*`zU=UQ^+6oMUx7V1jyIqgI-gSK;A_x#6 zU`T2Z+?agBtx({_m8H*{nKQb)HU#*5U{H85InrH@@x|r}cVFT)B-f~ qM1%BV#t-5d7q}KPUJ%H*uvyyMgOTyd Date: Sat, 10 Mar 2018 08:30:39 -0800 Subject: [PATCH 019/147] Sync all VMs and update images --- PLASMA-BLD2.PO | Bin 143360 -> 143360 bytes PLASMA-DEM2.PO | Bin 143360 -> 143360 bytes PLASMA-SOS2.PO | Bin 143360 -> 143360 bytes PLASMA-SYS2.PO | Bin 143360 -> 143360 bytes src/toolsrc/codegen.c | 3 + src/toolsrc/codegen.pla | 1 + src/toolsrc/parse.c | 2 - src/toolsrc/parse.pla | 1 - src/vmsrc/apple/plvm01.s | 276 +++++++++++++++++++++++++------------- src/vmsrc/apple/plvm02.s | 18 +-- src/vmsrc/apple/plvm03.s | 18 +-- src/vmsrc/apple/plvm802.s | 23 ++-- src/vmsrc/c64/plvmc64.s | 276 +++++++++++++++++++++++++------------- 13 files changed, 399 insertions(+), 219 deletions(-) diff --git a/PLASMA-BLD2.PO b/PLASMA-BLD2.PO index 7b53330ce41ba27925f59677379ee91d540970e1..dc22c356055b7c785892ae4f6b1e927fa6169d48 100644 GIT binary patch delta 12234 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 delta 12467 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

      lqt{ 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 NicH1j0_7rt+w3+C-89Q)0|D^@Ua8z~idI?> zv7&$)6)&i`&g7YCX7tT*bjB-h4m#rl!wfS%`M@|jQyAHLHrp)g(tXH&-`QXO=ls8O zc1NxXBUgosQ9gV*oy(>Y;9g=iAOM5G*08V;u0eUh;J2)tGg4}{!in>y#C{o2j0$4k z#rTw1MArrql1gcZ9oo7d1UOqy$!aTEYXt_4dPerjSv@3o1pQc8PU?n|bu(KD!fxJy z{VHjis>EGEQ3hN&h1bh^CYe)Q48)-+Oq8}&eJ&LENb|6BQr|}E19WUG63wYbDlNrh zS!IK*5v+k)=$h`<++cgGhDBLJ(hXhdpX7p#PzQ@=`mwO4N}DH@Y&Gj{s-@p+joWf1 zWZSWX=O?g6sGU|<9}*j;Q|tzo*o6tPgeN9&+Ki@|v%<}HwalI~mmd9t=4jK{ab)Lk z0nWZ{qKZreBJI7Bk&xU21#3P8;75BZJpGvmHkR~s+-e05-&gsuC}ErQl%dGk{<4V< z!Y+9+opc>JE$7L)h`2oW%XN~Ru1NBv8dysR`^hV3tC7b>EVd$J_bi~bg~bl!frV}D zw7G@F81iBdvOwhCPAAYyfu$6PE{-{YZVU$Q>ssn;)*>%7Fkavno42|Rr*;F6wDlQ= z<{49KIaI;5>i<_AhnCcUtmI>TMq0Jc0Qf5Edo8%1-B@nzjBR?_BQG`|pv zGmurUUh}}(bq`7uyMe`7SZ994#*T7U;2~c{LZs6f^q7{)ms16Mp&M|ATTyugWe6vG z^Rkl8lo|T5UZjdn`YMv0iW=B*CE1r+->;?zGTH_`YveX=%5UEC(AI|^dGxVu+aG`8 z$)}!vX2;;OJ9q8gvv=SA0|yTse(w1rFVMe#Mzd+qIlQkuZ;L%>HIZofT}x!rJh->1VqQ^L+@ck16XFe^#>Ch~}Rx@Y3)It#6@uotr-};n>S3UOD;d=xY=kNApt1{D!ep zZ_v&{^E+n#%|fTozWLVMg?HY4@7((zeE1PP`3ueQ7V~!&Jpak37d|t;L>X_Qc_ma_ HkAM6J^?WMz delta 1455 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 delta 2398 zcmY*aeN0=|6~BHw90SG>*L)s{=g$7Kw^!Gfxz$e!@7-8mE-zeNy0L!eXyLtczq);=dti?5Z2dr+n247Z3mk{w8`sixcN0(1{q$*iU4Mq&(nqL} zP0;S_Svrt?iH>DoruVYvXVzMlHMzE)Ts``!GPx81YYKFTa_xoj0a(q28^Jb!A(qZaqc^XX# z@AaFKfOkiNh0>$EkiU3>L$OvGu0Z}n6c=WPTPd*qBh-rP=YmWYof~eWO{0}6inUQ* zMEIe(V3ac~Ed*_EmtCl-vK&rZsfc)H6|tKP#~4F(I~KCN%*0}zBsjc28|+616H$xl z39Jc95u`91g7zs%1zcN^3oP$PLtU~RNzEW5XhKBv5D|zW_}`}_4DS^P7-gJEad#HB%|QNcNXGV~gH=fdJQ&;ty{XY}!S^5_ET+VQ zMCR-T^E$i*XqAJ7pyczDy2xQ~MlMAt$`g*Ep163TyoB(wjTsUC>m1>JFs@n|V|^tx zXxlKeZJL!6TeKX20tEv`4v-%Kzh+FM7(5r*j$#Ep{&NVb;LoOkNR2Qi#eh-{j)wnO z+&u4K3MP~4=RT)HTz|=ZrUaQ@LM7nF>=mA4MdIL3!JXQ71@Dp0Y48nflAs|1_hZ$p z2Q9+k!!v`t+>8hxFX;GRnL%sVjihfwXA@qu;qPRE(jh<>$bl^G);<=zmTzi~T{}aI zkh6G*DZpBo9pu8>fEN}2U5XufkV$#i;Y0=4Blb2f;;haWHIp|NZzwxCZ$SBQU~*aFd$s-O6k@KTXD z>@TM9f!v^=HXzb4M7Xe%CCE}UBhRWl@uvp;VxLysP+JbF^~6tjfGF7Ds#|BrJUS|` z70sZ4PCd?OPc(G-ru2{#|9CE_`uu4U3<;NMX@H!-g;90467?mffg7K&pv7DK_A-{Nsa8 z12y8DfH&#G#vO^_xv+@D3aF=8A-eJRXT!B9P%5;x2`xE75ze#7U3c#M>7z{j$R&r-b`q>~gA@*dz+AdSp^#Da#e~G-ypc|Dle0JUbmyuHc7yO_79)W1BHhiqLt>;6RCxu@brYB zZCP74@9wd5YR~RIW?9jGySqMNwD`Eu-+1NCelA+V?6z4r*2)NGdnO~FWO=9$z|5&N z@k_c|2jazi6B4@QJ&4q>IeY*HHd2G2rsKm?`bN1G{O(*3MB%>{BUXgqz?@1pdZZ3I zIku31GHip0cy%sN6_Fn~-t&mCHxLv$PN|iED5{pWvJM(4=t1c4C((HbcHc<^5PD7T zgX|#9AZ);exIUc8F@hg?jS2d~A3{0qQkbxj1JwT{9eId7nj^gcb#Ht=$Qz7MX3N=@Qlyqgwck$mAPis81ErnEjv2R#UD4siH?CBM0^DQW?55pW7O!!Zb@vtgb{0?r1X=!& Xapdoxq2Bqe)+?5z^rB=*OPuw8dcvBi diff --git a/PLASMA-SYS2.PO b/PLASMA-SYS2.PO index d1fe04cf54e0c77b3ba80ecd785471d1610fcf49..8abe2a9d74a3c1d147fa0ddee90e7631bc918697 100644 GIT binary patch delta 2159 zcmZWqYfuwc6ux&!!V-tDpf>VQ0|`*DMe3l_aR_6Y2Luxm2~?po9qddy9n=#q@ToT9h{OPr3Y2zE7yd)G$hJvsPaJ9M&MUl7=$m1eH?MHphns8M_C54ISxfSur`O~4 z)Oi}b7ro`f2Zm44s!Vm#JrC(!{l4h zmJaDFOXSIpg2sWyGw{IfWjwYyGKaIZWEG|FfhRsk_mIiRv5FbAmVbmLRS_GZK zqN>n_FmUBFkq8YYMAJ#jO*PL{*VcxRd=9X!ie=N3sm&owfNiN2n!qtlWb5?LXe+0H zya`}E0hfzIE*Fy&%C=~9s;UT>1$vzw(`$}SZ_w&ZVI2P~5+Y0d1e-OY*DUQLlYsc= zPzw587F{*3x~fcDS)r|35M<=nz{DJoM8o8o(ufYA*EgVQaj@!CQ5aq(OTyM-B5qb% zx)T%sVfJ|}U|CEM8FS#C$Lt|YFuMtM6DEYREV&{Zq7N{;6_f1C@Z>PTn00Zv2IE9B z;}EbSAgeGh3zCU}YzL54R>A!^?!+y49J3OLR4;epqd=d6Ma*#p+l2{o^((J7tbOhE zMu6VKY!6iEgNF$iQ$=aH)fl!A|2f!fbBxU%4=FUcLw+yN z<;BqDY6C**r`T-Z?GZA%hg^$UZ#GqieP-oZpeu+qt=d!(;WES@0>P!xf}_U*ToE|_ zDD;qnqpQx-nHMcATo67wkps+#vH)fc&cNi+DfHmP2qpNlFax(@XTYd68Y2wJ_kvyx zF?!`#Dl``DvM?Xt58kdzdSr71NpGXAPU3Kh9&JwYH)H2M{+Z{^Vc_VR&Kec*)vGjtJFzyu8^zd)^loZ z4R`-Krn^)c!F7*!xD%g%-Lz|Jh;ZT^?lvUu^0?`GT}-00OV^F@-_8wXd*MQ-mM?*| zwtTyE)DK_04EWsj`KGztV>e}^V`pVecUqR_i=Tec?^^5M;ZG7{B-KWe&`32!$wLvcUv(lE;ruc|1EGrwVgMKClC$z){0HY_UnJp>Lk&#G- z2tt(KS8|GeTj_r(??3r19bI|J`gG08?F0UiX*4p0X z_2k()D=yshM72Y6{5Ck`7=S@t#rR~BZIiEG(eA+Gw|L8kEXe98zoYpJS=;EVmdF&F zyd$s5QEJzCko6K+M*A$K_V!cWDu>S|rn@b1DK_)1gk)?pMND^(6mv)u5X>KFyb=qY~O0m`LOj?B- zj^iR69q$x56Py=%-gj$ zNz^}#2knlM#VYc1f;G)9L>Qe%$ajhSlJ*T`C@ovB%hhwh2oyIe6edyT4<#+jYYqtgu*ga8kN>4&(4aS1tsGmdB{;;SLwV^O*;}H7=ib6th zfXzRU!K*|Y)bw1!YNOg?(A6n%tH+ur}+Lzv&k^l?7Nx(ryOx9|99=f}IuyQ}t8@BQS{eKnsoMwj5* z6PYQP@b+5{_!*ciOws?4NV@hQbLg=3$d_RK7t?peCK;5Uo|CUo=Pn6s1bZAdt2<0T z(p;UYAOHe2o<=-$lNYjCC@xQ5G{3O8cm&DT!yQ-^b_e1#dRm`5Vo&V76S0$A^1S}CAw3Hk0K z%!Y9tK0J(>8cYNomwve1>FD|q%y%$j!9w~OLatneDU0bjgvkTJb~{}#e}EYsrkGh^ ca9{hGGdv3lb`quqqFoa(?eH1kGY(wxKe@BJC;$Ke diff --git a/src/toolsrc/codegen.c b/src/toolsrc/codegen.c index ce18984..630188b 100755 --- a/src/toolsrc/codegen.c +++ b/src/toolsrc/codegen.c @@ -785,6 +785,9 @@ void emit_caseblock(int casecnt, int *caseof, int *casetag) { int i; + if (casecnt < 1 || casecnt > 256) + parse_error("Switch count under/overflow\n"); + emit_pending_seq(); printf("\t%s\t$%02lX\t\t\t; CASEBLOCK\n", DB, casecnt & 0xFF); for (i = 0; i < casecnt; i++) { diff --git a/src/toolsrc/codegen.pla b/src/toolsrc/codegen.pla index 5a7880b..e0c20d8 100644 --- a/src/toolsrc/codegen.pla +++ b/src/toolsrc/codegen.pla @@ -181,6 +181,7 @@ end def emit_caseblock(cnt, oflist, taglist)#0 byte i + if not cnt or cnt > 256; exit_err(ERR_OVER|ERR_STATE); fin emit_pending_seq emit_byte(cnt) for i = 0 to cnt-1 diff --git a/src/toolsrc/parse.c b/src/toolsrc/parse.c index 97305d3..82bc69c 100755 --- a/src/toolsrc/parse.c +++ b/src/toolsrc/parse.c @@ -1061,8 +1061,6 @@ int parse_stmnt(void) caseval[casecnt] = constval; casetag[casecnt] = tag_of; casecnt++; - if (casecnt > 256) - parse_error("CASE clause overflow"); emit_codetag(tag_of); while (parse_stmnt()) next_line(); } diff --git a/src/toolsrc/parse.pla b/src/toolsrc/parse.pla index eadc9d9..831beec 100644 --- a/src/toolsrc/parse.pla +++ b/src/toolsrc/parse.pla @@ -816,7 +816,6 @@ def parse_stmnt caseval=>[casecnt] = caseconst casetag=>[casecnt] = tag_of casecnt++ - if casecnt > 256; exit_err(ERR_OVER|ERR_STATE); fin emit_tag(tag_of) while parse_stmnt nextln diff --git a/src/vmsrc/apple/plvm01.s b/src/vmsrc/apple/plvm01.s index b391d3c..d8dc4b6 100644 --- a/src/vmsrc/apple/plvm01.s +++ b/src/vmsrc/apple/plvm01.s @@ -109,14 +109,17 @@ COMP LDA #$FF ;* OPCODE TABLE ;* !ALIGN 255,0 -OPTBL !WORD ZERO,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 00 02 04 06 08 0A 0C 0E - !WORD NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 10 12 14 16 18 1A 1C 1E - !WORD LNOT,LOR,LAND,LA,LLA,CB,CW,CS ; 20 22 24 26 28 2A 2C 2E - !WORD DROP,DUP,NEXTOP,DIVMOD,BRGT,BRLT,BREQ,BRNE ; 30 32 34 36 38 3A 3C 3E - !WORD ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E - !WORD BRNCH,IBRNCH,CALL,ICAL,ENTER,LEAVE,RET,CFFB ; 50 52 54 56 58 5A 5C 5E - !WORD LB,LW,LLB,LLW,LAB,LAW,DLB,DLW ; 60 62 64 66 68 6A 6C 6E - !WORD SB,SW,SLB,SLW,SAB,SAW,DAB,DAW ; 70 72 74 76 78 7A 7C 7E +OPTBL !WORD CN,CN,CN,CN,CN,CN,CN,CN ; 00 02 04 06 08 0A 0C 0E + !WORD CN,CN,CN,CN,CN,CN,CN,CN ; 10 12 14 16 18 1A 1C 1E + !WORD MINUS1,NEXTOP,NEXTOP,LA,LLA,CB,CW,CS ; 20 22 24 26 28 2A 2C 2E + !WORD DROP,DROP2,DUP,DIVMOD,ADDI,SUBI,ANDI,ORI ; 30 32 34 36 38 3A 3C 3E + !WORD ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E + !WORD BRNCH,SEL,CALL,ICAL,ENTER,LEAVE,RET,CFFB ; 50 52 54 56 58 5A 5C 5E + !WORD LB,LW,LLB,LLW,LAB,LAW,DLB,DLW ; 60 62 64 66 68 6A 6C 6E + !WORD SB,SW,SLB,SLW,SAB,SAW,DAB,DAW ; 70 72 74 76 78 7A 7C 7E + !WORD LNOT,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 80 82 84 86 88 8A 8C 8E + !WORD NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 90 92 94 96 98 9A 9C 9E + !WORD BRGT,BRLT,INCBRLE,ADDBRLE,DECBRGE,SUBBRGE,BRAND,BROR ; A0 A2 A4 A6 A8 AA AC AE ;* ;* DIV TOS-1 BY TOS ;* @@ -325,31 +328,6 @@ SHR STY IPY + LDY IPY JMP DROP ;* -;* LOGICAL AND -;* -LAND LDA ESTKL+1,X - ORA ESTKH+1,X - BEQ ++ - LDA ESTKL,X - ORA ESTKH,X - BEQ + - LDA #$FF -+ STA ESTKL+1,X - STA ESTKH+1,X -++ JMP DROP -;* -;* LOGICAL OR -;* -LOR LDA ESTKL,X - ORA ESTKH,X - ORA ESTKL+1,X - ORA ESTKH+1,X - BEQ + - LDA #$FF - STA ESTKL+1,X - STA ESTKH+1,X -+ JMP DROP -;* ;* DUPLICATE TOS ;* DUP DEX @@ -363,17 +341,64 @@ DUP DEX ;* LNOT LDA ESTKL,X ORA ESTKH,X - BNE + + BEQ + LDA #$FF ++ EOR #$FF STA ESTKL,X STA ESTKH,X JMP NEXTOP ;* -;* CONSTANT +;* ADD IMMEDIATE TO TOS ;* -ZERO DEX -+ LDA #$00 +ADDI INY ;+INC_IP + LDA (IP),Y + CLC + ADC ESTKL,X STA ESTKL,X + BCC + + INC ESTKH,X ++ JMP NEXTOP +;* +;* SUB IMMEDIATE FROM TOS +;* +SUBI INY ;+INC_IP + LDA ESTKL,X + SEC + SBC (IP),Y + STA ESTKL,X + BCS + + DEC ESTKH,X ++ JMP NEXTOP +;* +;* AND IMMEDIATE TO TOS +;* +ANDI INY ;+INC_IP + LDA (IP),Y + AND ESTKL,X + STA ESTKL,X + LDA #$00 + STA ESTKH,X + JMP NEXTOP +;* +;* IOR IMMEDIATE TO TOS +;* +ORI INY ;+INC_IP + LDA (IP),Y + ORA ESTKL,X + STA ESTKL,X + JMP NEXTOP +;* +;* CONSTANT -1, NYBBLE, BYTE, $FF BYTE, WORD (BELOW) +;* +MINUS1 DEX + LDA #$FF + STA ESTKL,X + STA ESTKH,X + JMP NEXTOP +CN DEX + LSR ; A = CONST * 2 + STA ESTKL,X + LDA #$00 STA ESTKH,X JMP NEXTOP CFFB LDA #$FF @@ -552,7 +577,10 @@ SW LDA ESTKL,X JMP DROP + INC ESTKH,X STA (ESTKH-1,X) - INX +;* +;* DROP2 +;* +DROP2 INX JMP DROP ;* ;* STORE VALUE TO LOCAL FRAME OFFSET @@ -738,6 +766,65 @@ ISLT LDA ESTKL+1,X ;* ;* BRANCHES ;* +SEL INX + TYA ; FLATTEN IP + SEC + ADC IPL + STA TMPL + LDA #$00 + TAY + ADC IPH + STA TMPH ; ADD BRANCH OFFSET + LDA (TMP),Y + ;CLC ; BETTER NOT CARRY OUT OF IP+Y + ADC TMPL + STA IPL + INY + LDA (TMP),Y + ADC TMPH + STA IPH + DEY + LDA (IP),Y + STA TMPL ; CASE COUNT + LDA ESTKL-1,X + INC IPL + BNE CASELP + INC IPH +CASELP CMP (IP),Y + BNE + + LDA ESTKH-1,X + INY + CMP (IP),Y + BEQ BRNCH + LDA ESTKL-1,X + DEY ++ INY + INY + INY + DEC TMPL + BEQ FIXNEXT + INY + BNE CASELP + INC IPH + BNE CASELP +FIXNEXT TYA + LDY #$00 + SEC + ADC IPL + STA IPL + BCC + + INC IPH ++ JMP FETCHOP +BRAND LDA ESTKL,X + ORA ESTKH,X + BEQ BRNCH + INX ; DROP LEFT HALF OF AND + BNE NOBRNCH +BROR LDA ESTKL,X + ORA ESTKH,X + BNE BRNCH + INX ; DROP LEFT HALF OF OR + BNE NOBRNCH BRTRU INX LDA ESTKH-1,X ORA ESTKL-1,X @@ -746,14 +833,6 @@ NOBRNCH INY ;+INC_IP INY ;+INC_IP BMI FIXNEXT JMP NEXTOP -FIXNEXT TYA - LDY #$00 - CLC - ADC IPL - STA IPL - BCC + - INC IPH -+ JMP NEXTOP BRFLS INX LDA ESTKH-1,X ORA ESTKL-1,X @@ -776,58 +855,75 @@ BRNCH TYA ; FLATTEN IP STA IPH DEY JMP FETCHOP -BREQ INX - LDA ESTKL-1,X +;* +;* FOR LOOPS PUT TERMINAL VALUE AT ESTK+1 AND CURRENT COUNT ON ESTK +;* +BRGT LDA ESTKL+1,X CMP ESTKL,X - BNE NOBRNCH - LDA ESTKH-1,X - CMP ESTKH,X - BEQ BRNCH - BNE NOBRNCH -BRNE INX - LDA ESTKL-1,X - CMP ESTKL,X - BNE BRNCH - LDA ESTKH-1,X - CMP ESTKH,X - BEQ NOBRNCH - BNE BRNCH -BRGT INX - LDA ESTKL-1,X - CMP ESTKL,X - LDA ESTKH-1,X + LDA ESTKH+1,X SBC ESTKH,X BVS + BPL NOBRNCH - BMI BRNCH -+ BPL BRNCH - BMI NOBRNCH -BRLT INX - LDA ESTKL,X - CMP ESTKL-1,X +- INX ; DROP FOR VALUES + INX + BNE BRNCH ; BMI BRNCH +BRLT LDA ESTKL,X + CMP ESTKL+1,X LDA ESTKH,X - SBC ESTKH-1,X + SBC ESTKH+1,X BVS + BPL NOBRNCH - BMI BRNCH -+ BPL BRNCH - BMI NOBRNCH -IBRNCH TYA ; FLATTEN IP + INX ; DROP FOR VALUES + INX + BNE BRNCH ; BMI BRNCH ++ BMI NOBRNCH + BPL - +DECBRGE DEC ESTKL,X + LDA ESTKL,X + CMP #$FF + BNE + + DEC ESTKH,X +_BRGE LDA ESTKL,X ++ CMP ESTKL+1,X + LDA ESTKH,X + SBC ESTKH+1,X + BVS + + BPL BRNCH +- INX ; DROP FOR VALUES + INX + BNE NOBRNCH ; BMI NOBRNCH +INCBRLE INC ESTKL,X + BNE _BRLE + INC ESTKH,X +_BRLE LDA ESTKL+1,X + CMP ESTKL,X + LDA ESTKH+1,X + SBC ESTKH,X + BVS + + BPL BRNCH + INX ; DROP FOR VALUES + INX + BNE NOBRNCH ; BMI NOBRNCH ++ BMI BRNCH + BPL - +SUBBRGE LDA ESTKL+1,X + SEC + SBC ESTKL,X + STA ESTKL+1,X + LDA ESTKH+1,X + SBC ESTKH,X + STA ESTKH+1,X + INX + BNE _BRGE +ADDBRLE LDA ESTKL,X CLC - ADC IPL - STA TMPL - LDA #$00 - TAY - ADC IPH - STA TMPH ; ADD BRANCH OFFSET - LDA TMPL - ;CLC ; BETTER NOT CARRY OUT OF IP+Y - ADC ESTKL,X - STA IPL - LDA TMPH - ADC ESTKH,X - STA IPH - JMP DROP + ADC ESTKL+1,X + STA ESTKL+1,X + LDA ESTKH,X + ADC ESTKH+1,X + STA ESTKH+1,X + INX + BNE _BRLE ;* ;* INDIRECT CALL TO ADDRESS (NATIVE CODE) ;* diff --git a/src/vmsrc/apple/plvm02.s b/src/vmsrc/apple/plvm02.s index 0875fa8..c4dccd5 100755 --- a/src/vmsrc/apple/plvm02.s +++ b/src/vmsrc/apple/plvm02.s @@ -1307,12 +1307,11 @@ SEL INX STA IPH DEY LDA (IP),Y - BEQ ++ STA TMPL ; CASE COUNT + LDA ESTKL-1,X INC IPL - BNE + + BNE CASELP INC IPH -+ LDA ESTKL-1,X CASELP CMP (IP),Y BNE + LDA ESTKH-1,X @@ -1321,26 +1320,23 @@ CASELP CMP (IP),Y BEQ BRNCH LDA ESTKL-1,X DEY -+ DEC TMPL - BEQ + - INY ++ INY INY INY + DEC TMPL + BEQ FIXNEXT INY BNE CASELP INC IPH BNE CASELP -+ INY - INY - INY FIXNEXT TYA LDY #$00 SEC ADC IPL STA IPL - BCC ++ + BCC + INC IPH -++ JMP FETCHOP ++ JMP FETCHOP BRAND LDA ESTKL,X ORA ESTKH,X BEQ BRNCH diff --git a/src/vmsrc/apple/plvm03.s b/src/vmsrc/apple/plvm03.s index d17fada..c02679a 100755 --- a/src/vmsrc/apple/plvm03.s +++ b/src/vmsrc/apple/plvm03.s @@ -949,12 +949,11 @@ SEL INX STA IPH DEY LDA (IP),Y - BEQ ++ STA TMPL ; CASE COUNT + LDA ESTKL-1,X INC IPL - BNE + + BNE CASELP INC IPH -+ LDA ESTKL-1,X CASELP CMP (IP),Y BNE + LDA ESTKH-1,X @@ -963,26 +962,23 @@ CASELP CMP (IP),Y BEQ BRNCH LDA ESTKL-1,X DEY -+ DEC TMPL - BEQ + - INY ++ INY INY INY + DEC TMPL + BEQ FIXNEXT INY BNE CASELP INC IPH BNE CASELP -+ INY - INY - INY FIXNEXT TYA LDY #$00 SEC ADC IPL STA IPL - BCC ++ + BCC + INC IPH -++ JMP FETCHOP ++ JMP FETCHOP BRAND LDA ESTKL,X ORA ESTKH,X BEQ BRNCH diff --git a/src/vmsrc/apple/plvm802.s b/src/vmsrc/apple/plvm802.s index a7312ce..2e9ca82 100644 --- a/src/vmsrc/apple/plvm802.s +++ b/src/vmsrc/apple/plvm802.s @@ -1183,32 +1183,27 @@ SEL TYA ; FLATTEN IP LDA (IP),Y TAX ; CASE COUNT PLA - CPX #$00 - BEQ ++ INC IP CASELP CMP (IP),Y - BEQ +++ + BEQ ++ + INY + INY + INY DEX - BEQ + - INY - INY - INY + BEQ FIXNEXT INY BNE CASELP +ACCMEM8 ; 8 BIT A/M INC IPH +ACCMEM16 ; 16 BIT A/M BRA CASELP -+ INY - INY - INY FIXNEXT TYA LDY #$00 SEC ADC IP STA IP -++ JMP FETCHOP -+++ INY + JMP FETCHOP +++ INY BRA BRNCH BRAND LDA TOS,S BEQ BRNCH @@ -1227,13 +1222,13 @@ NOBRNCH INY ;+INC_IP BRFLS PLA BNE NOBRNCH BRNCH TYA ; FLATTEN IP - CLC + SEC ADC IP INY ;+INC_IP ;CLC ; ADD BRANCH OFFSET (BETTER NOT CARRY OUT OF IP+Y) ADC (IP),Y STA IP - LDY #$01 + LDY #$00 JMP FETCHOP ;* ;* FOR LOOPS PUT TERMINAL VALUE AT ESTK+1 AND CURRENT COUNT ON ESTK diff --git a/src/vmsrc/c64/plvmc64.s b/src/vmsrc/c64/plvmc64.s index bfaa45c..a225723 100644 --- a/src/vmsrc/c64/plvmc64.s +++ b/src/vmsrc/c64/plvmc64.s @@ -109,14 +109,17 @@ COMP LDA #$FF ;* OPCODE TABLE ;* !ALIGN 255,0 -OPTBL !WORD ZERO,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 00 02 04 06 08 0A 0C 0E - !WORD NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 10 12 14 16 18 1A 1C 1E - !WORD LNOT,LOR,LAND,LA,LLA,CB,CW,CS ; 20 22 24 26 28 2A 2C 2E - !WORD DROP,DUP,NEXTOP,DIVMOD,BRGT,BRLT,BREQ,BRNE ; 30 32 34 36 38 3A 3C 3E - !WORD ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E - !WORD BRNCH,IBRNCH,CALL,ICAL,ENTER,LEAVE,RET,CFFB ; 50 52 54 56 58 5A 5C 5E - !WORD LB,LW,LLB,LLW,LAB,LAW,DLB,DLW ; 60 62 64 66 68 6A 6C 6E - !WORD SB,SW,SLB,SLW,SAB,SAW,DAB,DAW ; 70 72 74 76 78 7A 7C 7E +OPTBL !WORD CN,CN,CN,CN,CN,CN,CN,CN ; 00 02 04 06 08 0A 0C 0E + !WORD CN,CN,CN,CN,CN,CN,CN,CN ; 10 12 14 16 18 1A 1C 1E + !WORD MINUS1,NEXTOP,NEXTOP,LA,LLA,CB,CW,CS ; 20 22 24 26 28 2A 2C 2E + !WORD DROP,DROP2,DUP,DIVMOD,ADDI,SUBI,ANDI,ORI ; 30 32 34 36 38 3A 3C 3E + !WORD ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E + !WORD BRNCH,SEL,CALL,ICAL,ENTER,LEAVE,RET,CFFB ; 50 52 54 56 58 5A 5C 5E + !WORD LB,LW,LLB,LLW,LAB,LAW,DLB,DLW ; 60 62 64 66 68 6A 6C 6E + !WORD SB,SW,SLB,SLW,SAB,SAW,DAB,DAW ; 70 72 74 76 78 7A 7C 7E + !WORD LNOT,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 80 82 84 86 88 8A 8C 8E + !WORD NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 90 92 94 96 98 9A 9C 9E + !WORD BRGT,BRLT,INCBRLE,ADDBRLE,DECBRGE,SUBBRGE,BRAND,BROR ; A0 A2 A4 A6 A8 AA AC AE ;* ;* DIV TOS-1 BY TOS ;* @@ -325,31 +328,6 @@ SHR STY IPY + LDY IPY JMP DROP ;* -;* LOGICAL AND -;* -LAND LDA ESTKL+1,X - ORA ESTKH+1,X - BEQ ++ - LDA ESTKL,X - ORA ESTKH,X - BEQ + - LDA #$FF -+ STA ESTKL+1,X - STA ESTKH+1,X -++ JMP DROP -;* -;* LOGICAL OR -;* -LOR LDA ESTKL,X - ORA ESTKH,X - ORA ESTKL+1,X - ORA ESTKH+1,X - BEQ + - LDA #$FF - STA ESTKL+1,X - STA ESTKH+1,X -+ JMP DROP -;* ;* DUPLICATE TOS ;* DUP DEX @@ -363,17 +341,64 @@ DUP DEX ;* LNOT LDA ESTKL,X ORA ESTKH,X - BNE + + BEQ + LDA #$FF ++ EOR #$FF STA ESTKL,X STA ESTKH,X JMP NEXTOP ;* -;* CONSTANT +;* ADD IMMEDIATE TO TOS ;* -ZERO DEX -+ LDA #$00 +ADDI INY ;+INC_IP + LDA (IP),Y + CLC + ADC ESTKL,X STA ESTKL,X + BCC + + INC ESTKH,X ++ JMP NEXTOP +;* +;* SUB IMMEDIATE FROM TOS +;* +SUBI INY ;+INC_IP + LDA ESTKL,X + SEC + SBC (IP),Y + STA ESTKL,X + BCS + + DEC ESTKH,X ++ JMP NEXTOP +;* +;* AND IMMEDIATE TO TOS +;* +ANDI INY ;+INC_IP + LDA (IP),Y + AND ESTKL,X + STA ESTKL,X + LDA #$00 + STA ESTKH,X + JMP NEXTOP +;* +;* IOR IMMEDIATE TO TOS +;* +ORI INY ;+INC_IP + LDA (IP),Y + ORA ESTKL,X + STA ESTKL,X + JMP NEXTOP +;* +;* CONSTANT -1, NYBBLE, BYTE, $FF BYTE, WORD (BELOW) +;* +MINUS1 DEX + LDA #$FF + STA ESTKL,X + STA ESTKH,X + JMP NEXTOP +CN DEX + LSR ; A = CONST * 2 + STA ESTKL,X + LDA #$00 STA ESTKH,X JMP NEXTOP CFFB LDA #$FF @@ -552,7 +577,10 @@ SW LDA ESTKL,X JMP DROP + INC ESTKH,X STA (ESTKH-1,X) - INX +;* +;* DROP2 +;* +DROP2 INX JMP DROP ;* ;* STORE VALUE TO LOCAL FRAME OFFSET @@ -738,6 +766,65 @@ ISLT LDA ESTKL+1,X ;* ;* BRANCHES ;* +SEL INX + TYA ; FLATTEN IP + SEC + ADC IPL + STA TMPL + LDA #$00 + TAY + ADC IPH + STA TMPH ; ADD BRANCH OFFSET + LDA (TMP),Y + ;CLC ; BETTER NOT CARRY OUT OF IP+Y + ADC TMPL + STA IPL + INY + LDA (TMP),Y + ADC TMPH + STA IPH + DEY + LDA (IP),Y + STA TMPL ; CASE COUNT + LDA ESTKL-1,X + INC IPL + BNE CASELP + INC IPH +CASELP CMP (IP),Y + BNE + + LDA ESTKH-1,X + INY + CMP (IP),Y + BEQ BRNCH + LDA ESTKL-1,X + DEY ++ INY + INY + INY + DEC TMPL + BEQ FIXNEXT + INY + BNE CASELP + INC IPH + BNE CASELP +FIXNEXT TYA + LDY #$00 + SEC + ADC IPL + STA IPL + BCC + + INC IPH ++ JMP FETCHOP +BRAND LDA ESTKL,X + ORA ESTKH,X + BEQ BRNCH + INX ; DROP LEFT HALF OF AND + BNE NOBRNCH +BROR LDA ESTKL,X + ORA ESTKH,X + BNE BRNCH + INX ; DROP LEFT HALF OF OR + BNE NOBRNCH BRTRU INX LDA ESTKH-1,X ORA ESTKL-1,X @@ -746,14 +833,6 @@ NOBRNCH INY ;+INC_IP INY ;+INC_IP BMI FIXNEXT JMP NEXTOP -FIXNEXT TYA - LDY #$00 - CLC - ADC IPL - STA IPL - BCC + - INC IPH -+ JMP NEXTOP BRFLS INX LDA ESTKH-1,X ORA ESTKL-1,X @@ -776,58 +855,75 @@ BRNCH TYA ; FLATTEN IP STA IPH DEY JMP FETCHOP -BREQ INX - LDA ESTKL-1,X +;* +;* FOR LOOPS PUT TERMINAL VALUE AT ESTK+1 AND CURRENT COUNT ON ESTK +;* +BRGT LDA ESTKL+1,X CMP ESTKL,X - BNE NOBRNCH - LDA ESTKH-1,X - CMP ESTKH,X - BEQ BRNCH - BNE NOBRNCH -BRNE INX - LDA ESTKL-1,X - CMP ESTKL,X - BNE BRNCH - LDA ESTKH-1,X - CMP ESTKH,X - BEQ NOBRNCH - BNE BRNCH -BRGT INX - LDA ESTKL-1,X - CMP ESTKL,X - LDA ESTKH-1,X + LDA ESTKH+1,X SBC ESTKH,X BVS + BPL NOBRNCH - BMI BRNCH -+ BPL BRNCH - BMI NOBRNCH -BRLT INX - LDA ESTKL,X - CMP ESTKL-1,X +- INX ; DROP FOR VALUES + INX + BNE BRNCH ; BMI BRNCH +BRLT LDA ESTKL,X + CMP ESTKL+1,X LDA ESTKH,X - SBC ESTKH-1,X + SBC ESTKH+1,X BVS + BPL NOBRNCH - BMI BRNCH -+ BPL BRNCH - BMI NOBRNCH -IBRNCH TYA ; FLATTEN IP + INX ; DROP FOR VALUES + INX + BNE BRNCH ; BMI BRNCH ++ BMI NOBRNCH + BPL - +DECBRGE DEC ESTKL,X + LDA ESTKL,X + CMP #$FF + BNE + + DEC ESTKH,X +_BRGE LDA ESTKL,X ++ CMP ESTKL+1,X + LDA ESTKH,X + SBC ESTKH+1,X + BVS + + BPL BRNCH +- INX ; DROP FOR VALUES + INX + BNE NOBRNCH ; BMI NOBRNCH +INCBRLE INC ESTKL,X + BNE _BRLE + INC ESTKH,X +_BRLE LDA ESTKL+1,X + CMP ESTKL,X + LDA ESTKH+1,X + SBC ESTKH,X + BVS + + BPL BRNCH + INX ; DROP FOR VALUES + INX + BNE NOBRNCH ; BMI NOBRNCH ++ BMI BRNCH + BPL - +SUBBRGE LDA ESTKL+1,X + SEC + SBC ESTKL,X + STA ESTKL+1,X + LDA ESTKH+1,X + SBC ESTKH,X + STA ESTKH+1,X + INX + BNE _BRGE +ADDBRLE LDA ESTKL,X CLC - ADC IPL - STA TMPL - LDA #$00 - TAY - ADC IPH - STA TMPH ; ADD BRANCH OFFSET - LDA TMPL - ;CLC ; BETTER NOT CARRY OUT OF IP+Y - ADC ESTKL,X - STA IPL - LDA TMPH - ADC ESTKH,X - STA IPH - JMP DROP + ADC ESTKL+1,X + STA ESTKL+1,X + LDA ESTKH,X + ADC ESTKH+1,X + STA ESTKH+1,X + INX + BNE _BRLE ;* ;* INDIRECT CALL TO ADDRESS (NATIVE CODE) ;* From 20790d2dbb4f6540bcef95aa443f41598d1016e8 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Sat, 10 Mar 2018 15:38:57 -0800 Subject: [PATCH 020/147] Make sure sequnce opcode is invalidated for gen_ctag --- src/toolsrc/codegen.c | 49 +++++++++++++++++++++++++++++++---------- src/toolsrc/codegen.pla | 9 +++----- src/toolsrc/codeopt.pla | 47 +++++++++++++++++++++++---------------- src/toolsrc/codeseq.plh | 4 ++++ 4 files changed, 72 insertions(+), 37 deletions(-) diff --git a/src/toolsrc/codegen.c b/src/toolsrc/codegen.c index 630188b..85b89f3 100755 --- a/src/toolsrc/codegen.c +++ b/src/toolsrc/codegen.c @@ -1129,13 +1129,6 @@ int crunch_seq(t_opseq **seq, int pass) freeops = 1; break; } - if (opnext->code == BINARY_CODE(SHL_TOKEN)) - { - op->code = DUP_CODE; - opnext->code = BINARY_CODE(ADD_TOKEN); - crunched = 1; - break; - } } switch (opnext->code) { @@ -1193,6 +1186,14 @@ int crunch_seq(t_opseq **seq, int pass) freeops = 1; } break; + case BROR_CODE: + if (!op->val) + freeops = -2; // Remove zero constant + break; + case BRAND_CODE: + if (op->val) + freeops = -2; // Remove non-zero constant + break; case NE_CODE: if (!op->val) freeops = -2; // Remove ZERO:ISNE @@ -1279,16 +1280,36 @@ int crunch_seq(t_opseq **seq, int pass) crunched = try_dupify(op); break; // CONST_CODE case BINARY_CODE(ADD_TOKEN): - if (op->val >= 0 && op->val <= 255) + if (op->val == 0) + { + freeops = -2; + } + else if (op->val > 0 && op->val <= 255) { op->code = ADDI_CODE; freeops = 1; } - break; - case BINARY_CODE(SUB_TOKEN): - if (op->val >= 0 && op->val <= 255) + else if (op->val >= -255 && op->val < 0) { op->code = SUBI_CODE; + op->val = -op->val; + freeops = 1; + } + break; + case BINARY_CODE(SUB_TOKEN): + if (op->val == 0) + { + freeops = -2; + } + else if (op->val > 0 && op->val <= 255) + { + op->code = SUBI_CODE; + freeops = 1; + } + else if (op->val >= -255 && op->val < 0) + { + op->code = ADDI_CODE; + op->val = -op->val; freeops = 1; } break; @@ -1300,7 +1321,11 @@ int crunch_seq(t_opseq **seq, int pass) } break; case BINARY_CODE(OR_TOKEN): - if (op->val >= 0 && op->val <= 255) + if (op->val == 0) + { + freeops = -2; + } + else if (op->val > 0 && op->val <= 255) { op->code = ORI_CODE; freeops = 1; diff --git a/src/toolsrc/codegen.pla b/src/toolsrc/codegen.pla index e0c20d8..f77ba3b 100644 --- a/src/toolsrc/codegen.pla +++ b/src/toolsrc/codegen.pla @@ -313,7 +313,7 @@ def emit_pending_seq#0 ^codeptr = $20 codeptr++ elsif op=>opval & $FFF0 == $0000 // Constant NYBBLE - ^codeptr = op->opval*2) + ^codeptr = op->opval*2 codeptr++ elsif op=>opval & $FF00 == $0000 // Constant BYTE *codeptr = $2A | (op->opval << 8) @@ -327,7 +327,7 @@ def emit_pending_seq#0 codeptr = codeptr + 3 fin else - *codeptr = op->opcode | (op->opval << 8) + *codeptr = op->opcode | (op->opval << 8) // IMMEDIATE BYTE OP codeptr = codeptr + 2 fin break @@ -720,6 +720,7 @@ def gen_ctag(seq, tag) op=>opnext = new_op op = op=>opnext fin + op->opcode = INVALID_CODE op->opgroup = CODETAG_GROUP op=>optag = tag return seq @@ -805,10 +806,6 @@ def gen_bop(seq, tkn) code = $44; break is LE_TKN code = $4A; break - //is LOGIC_OR_TKN - // code = $22; break - //is LOGIC_AND_TKN - // code = $24; break otherwise exit_err(ERR_INVAL|ERR_SYNTAX) wend diff --git a/src/toolsrc/codeopt.pla b/src/toolsrc/codeopt.pla index 5978d22..565e76e 100644 --- a/src/toolsrc/codeopt.pla +++ b/src/toolsrc/codeopt.pla @@ -79,13 +79,6 @@ def crunch_seq(seq, pass) freeops = 1 break fin - if nextop->opcode == SHL_CODE - op->opcode = DUP_CODE - op->opgroup = STACK_GROUP - nextop->opcode = ADD_CODE - crunched = 1 - break - fin fin when nextop->opcode is NEG_CODE @@ -120,6 +113,16 @@ def crunch_seq(seq, pass) freeops = 1 fin break + is BROR_CODE + if not op=>opval + freeops = -2 // Remove zero constant + fin + break + is BRAND_CODE + if op=>opval + freeops = -2 // Remove non-zero constant + fin + break is NE_CODE if not op=>opval freeops = -2 // Remove ZERO:ISNE @@ -133,7 +136,7 @@ def crunch_seq(seq, pass) fin break is CONST_CODE // Collapse constant operation - nextopnext = nextop->nextop + nextopnext = nextop=>opnext if nextopnext when nextopnext->opcode is MUL_CODE @@ -200,14 +203,6 @@ def crunch_seq(seq, pass) op=>opval = op=>opval <= nextop=>opval freeops = 2 break -// is LOGIC_OR_CODE -// op=>opval = op=>opval or nextop=>opval -// freeops = 2 -// break -// is LOGIC_AND_CODE -// op=>opval = op=>opval and nextop=>opval -// freeops = 2 -// break wend // End of collapse constant operation fin if pass and not freeops and op=>opval @@ -215,15 +210,27 @@ def crunch_seq(seq, pass) fin break // CONST_CODE is ADD_CODE - if op=>opval >= 0 and op=>opval <= 255 + if op=>opval == 0 + freeops = -2 + elsif op=>opval > 0 and op=>opval <= 255 op->opcode = ADDI_CODE freeops = 1 + elsif op=>opval >= -255 and op=>opval < 0 + op->opcode = SUBI_CODE + op=>opval = -op=>opval + freeops = 1 fin break is SUB_CODE - if op=>opval >= 0 and op=>opval <= 255 + if op=>opval == 0 + freeops = -2 + elsif op=>opval > 0 and op=>opval <= 255 op->opcode = SUBI_CODE freeops = 1 + elsif op=>opval >= -255 and op=>opval < 0 + op->opcode = ADDI_CODE + op=>opval = -op=>opval + freeops = 1 fin break is AND_CODE @@ -233,7 +240,9 @@ def crunch_seq(seq, pass) fin break is OR_CODE - if op=>opval >= 0 and op=>opval <= 255 + if op=>opval == 0 + freeops = -2 + elsif op=>opval > 0 and op=>opval <= 255 op->opcode = ORI_CODE freeops = 1 fin diff --git a/src/toolsrc/codeseq.plh b/src/toolsrc/codeseq.plh index 5a23e6c..610c358 100644 --- a/src/toolsrc/codeseq.plh +++ b/src/toolsrc/codeseq.plh @@ -84,6 +84,10 @@ const BROR_CODE = $AE // const CODETAG_GROUP = $06 // +// Invalid code +// +const INVALID_CODE = $FF +// // Code sequence op // struc t_opseq From 4f11cad9552db6df1d3d009acbde201297482da2 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Sat, 10 Mar 2018 15:45:01 -0800 Subject: [PATCH 021/147] Update XBYTE in SELect --- src/vmsrc/apple/plvm03.s | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/vmsrc/apple/plvm03.s b/src/vmsrc/apple/plvm03.s index c02679a..b201959 100755 --- a/src/vmsrc/apple/plvm03.s +++ b/src/vmsrc/apple/plvm03.s @@ -939,6 +939,8 @@ SEL INX TAY ADC IPH STA TMPH ; ADD CASEBLOCK OFFSET + LDA IPX ; COPY XBYTE FROM IP + STA TMPX LDA (TMP),Y ;CLC ; BETTER NOT CARRY OUT OF IP+Y ADC TMPL @@ -948,6 +950,7 @@ SEL INX ADC TMPH STA IPH DEY + STY TMPX ; CLEAR TMPX LDA (IP),Y STA TMPL ; CASE COUNT LDA ESTKL-1,X From 214f9c163dc7c2b07e41c0185d69865d695711f3 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Sat, 10 Mar 2018 18:55:24 -0800 Subject: [PATCH 022/147] Update images --- PLASMA-BLD2.PO | Bin 143360 -> 143360 bytes PLASMA-SOS2.PO | Bin 143360 -> 143360 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/PLASMA-BLD2.PO b/PLASMA-BLD2.PO index dc22c356055b7c785892ae4f6b1e927fa6169d48..d11ea7cdc21cbcd96dfde4151fcfde528faff75d 100644 GIT binary patch delta 7851 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 R>Mg(KlF~C0mzH?T{{Txcr||#) From f5a94313f275261d72b73734982c0f59eb1a7b93 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Mon, 12 Mar 2018 15:13:35 -0700 Subject: [PATCH 023/147] Add assembly helper for lexical scanner ID/Keyword match --- src/toolsrc/lex.pla | 56 ++++++++++------------- src/toolsrc/plasm.pla | 100 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 124 insertions(+), 32 deletions(-) diff --git a/src/toolsrc/lex.pla b/src/toolsrc/lex.pla index b20e863..6d8f062 100644 --- a/src/toolsrc/lex.pla +++ b/src/toolsrc/lex.pla @@ -26,29 +26,24 @@ // fin // return FALSE //end -def keymatch - byte i, keypos - word chrptr - - keypos = 0 - while keywrds[keypos] < tknlen - keypos = keypos + keywrds[keypos] + 2 - loop - chrptr = tknptr - 1 - while keywrds[keypos] == tknlen - i = 1; while i <= tknlen and ^(chrptr + i) == keywrds[keypos + i]; i++; loop - //for i = 1 to tknlen - // if ^(chrptr + i) <> keywrds[keypos + i] - // break - // fin - //next - if i > tknlen - return keywrds[keypos + keywrds[keypos] + 1] - fin - keypos = keypos + keywrds[keypos] + 2 - loop - return ID_TKN -end +//def keymatch +// byte i, keypos +// word chrptr +// +// keypos = 0 +// while keywrds[keypos] < tknlen +// keypos = keypos + keywrds[keypos] + 2 +// loop +// chrptr = tknptr - 1 +// while keywrds[keypos] == tknlen +// i = 1; while i <= tknlen and ^(chrptr + i) == keywrds[keypos + i]; i++; loop +// if i > tknlen +// return keywrds[keypos + keywrds[keypos] + 1] +// fin +// keypos = keypos + keywrds[keypos] + 2 +// loop +// return ID_TKN +//end def scannum word num num = 0 @@ -85,23 +80,20 @@ def scan scanptr++ loop tknptr = scanptr - scanchr = toupper(^scanptr) + scanchr, scanptr, token = scanid(scanptr, @keywrds) //scanchr = toupper(^scanptr) // // Scan for token based on first character // - //if isalpha(scanchr) - if (scanchr >= 'A' and scanchr <= 'Z') or (scanchr == '_') + if token //if isalpha(scanchr) // // ID, either variable name or reserved word // - repeat - ^scanptr = scanchr - scanptr++ - scanchr = toupper(^scanptr) + //repeat + // ^scanptr = scanchr + // scanptr++ + // scanchr = toupper(^scanptr) //until not isalphanum(scanchr) - until not ((scanchr >= 'A' and scanchr <= 'Z') or (scanchr >= '0' and scanchr <= '9' ) or (scanchr == '_')) tknlen = scanptr - tknptr - token = keymatch elsif scanchr >= '0' and scanchr <= '9' // isnum() // // Decimal constant diff --git a/src/toolsrc/plasm.pla b/src/toolsrc/plasm.pla index 7b44939..f63106d 100644 --- a/src/toolsrc/plasm.pla +++ b/src/toolsrc/plasm.pla @@ -338,6 +338,106 @@ const ERR_SYNTAX = $8000 // //===================================== +// +// Lexical scanner helper for keyword/IDs +// +asm scanid(scanptr, keywrds)#3 + !SOURCE "vmsrc/plvmzp.inc" + LDA ESTKL,X + STA DSTL + LDA ESTKH,X + STA DSTH + LDA ESTKL+1,X + STA ESTKL,X ; COPY OUTPUT SCANPTR + STA SRCL + LDA ESTKH+1,X + STA ESTKH,X + STA SRCH + DEX + LDA #$00 + STA ESTKL,X ; CLEAR OUTPUT TOKEN + STA ESTKH,X + STA ESTKH+2,X ; CLEAR MSB OF SCANCHR + TAY + LDA (SRC),Y + AND #$7F + CMP #'a' + BCC + + CMP #'z'+1 + BCS + + SBC #$1F + STA (SRC),Y ++ STA ESTKL+2,X ; SET SCANCHR + CMP #'_' + BEQ + + CMP #'A' + BCC SCANEX + CMP #'Z'+1 + BCS SCANEX ++ LDA #$D6 ; ID_TKN + STA ESTKL,X ; SET OUTPUT TOKEN = ID_TKN +SCANID INY + LDA (SRC),Y + AND #$7F + BEQ ++ + CMP #'a' + BCC + + CMP #'z'+1 + BCS ++ + SBC #$1F + STA (SRC),Y ; COPY UPPERCASE CHAR BACK TO ^SCANPTR + BNE SCANID ++ CMP #'_' + BEQ SCANID + CMP #'0' + BCC ++ + CMP #'9'+1 + BCC SCANID + CMP #'A' + BCC ++ + CMP #'Z'+1 + BCC SCANID +++ STY TMPL + TYA + LDY #$00 + CLC + ADC SRCL + STA ESTKL+1,X ; UPDATE SCANPTR + BCC MATCHLEN + INC ESTKH+1,X +MATCHLEN LDA (DST),Y + CMP TMPL + BCS + + ADC #$02 + ADC DSTL + STA DSTL + BCC MATCHLEN + INC DSTH + BNE MATCHLEN ++ BNE SCANEX ; NO KEY MATCH + TAY + DEY + INC DSTL + BNE MATCHKEY + INC DSTH +MATCHKEY LDA (SRC),Y + CMP (DST),Y + BNE NEXTKEY + DEY + BPL MATCHKEY + LDY TMPL + LDA (DST),Y + STA ESTKL,X ; SET OUTPUT TOKEN +SCANEX RTS +NEXTKEY LDY #$00 + LDA TMPL + SEC + ADC DSTL + STA DSTL + BCC MATCHLEN + INC DSTH + BNE MATCHLEN +end // // Handy functions // From 35539e8f6eb41adadc383d39e52bcc10e3eb2fff Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Tue, 13 Mar 2018 08:16:01 -0700 Subject: [PATCH 024/147] Update test case, portable VM WIP --- src/samplesrc/test.pla | 10 ++++++- src/vmsrc/plvm.c | 67 +++++++++++++++++++++++++++++++++++------- 2 files changed, 65 insertions(+), 12 deletions(-) diff --git a/src/samplesrc/test.pla b/src/samplesrc/test.pla index 915a0b5..a8a1c26 100755 --- a/src/samplesrc/test.pla +++ b/src/samplesrc/test.pla @@ -85,7 +85,7 @@ def vals123#3 return 1, 2, 3 end export def main(range)#0 - byte a, b, c + word a, b, c word lambda a = 10 @@ -127,6 +127,14 @@ export def main(range)#0 drop, b, drop = vals123 drop, drop, c = vals123 puts("a, b, c = "); puti(a); puts(", "); puti(b); puts(", "); puti(c); putln + puts(" 7 / 3 = "); puti(7/3); puts(" ; 7 % 3 = "); puti(7%3); putln + puts(" 7 / -3 = "); puti(7/-3); puts("; 7 % -3 = "); puti(7%-3); putln + puts("-7 / 3 = "); puti(-7/3); puts("; -7 % 3 = "); puti(-7%3); putln + puts("-7 / -3 = "); puti(-7/-3); puts(" ; -7 % -3 = "); puti(-7%-3); putln + a,b=divmod(7,3); puts("divmod( 7, 3) = "); puti(a); puts(", "); puti(b); putln + a,b=divmod(7,-3); puts("divmod( 7,-3) = "); puti(a); puts(", "); puti(b); putln + a,b=divmod(-7,3); puts("divmod(-7, 3) = "); puti(a); puts(", "); puti(b); putln + a,b=divmod(-7,-3);puts("divmod(-7,-3) = "); puti(a); puts(", "); puti(b); putln end def dummy(zz)#2 diff --git a/src/vmsrc/plvm.c b/src/vmsrc/plvm.c index 3beff8a..2035f52 100755 --- a/src/vmsrc/plvm.c +++ b/src/vmsrc/plvm.c @@ -455,6 +455,7 @@ void interp(code *ip); void call(uword pc) { unsigned int i, s; + int a, b; char c, sz[64]; if (show_state) @@ -508,6 +509,12 @@ void call(uword pc) mem_data[0x1FF] = i; PUSH(0x1FF); break; + case 24: // LIBRARY CMDSYS::DIVMOD + a = POP; + b = POP; + PUSH(b / a); + PUSH(b % a); + break; default: printf("\nUnimplemented call code:$%02X\n", mem_data[pc - 1]); exit(1); @@ -517,20 +524,21 @@ void call(uword pc) /* * OPCODE TABLE * -OPTBL: DW ZERO,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 00 02 04 06 08 0A 0C 0E - DW NEG,COMP,AND,IOR,XOR,SHL,SHR,IDXW ; 10 12 14 16 18 1A 1C 1E - DW NOT,LOR,LAND,LA,LLA,CB,CW,CS ; 20 22 24 26 28 2A 2C 2E - DW DROP,DROP2,DUP,DIVMOD,ADDI,SUBI,ANDI,ORI ; 30 32 34 36 38 3A 3C 3E - DW ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E - DW BRNCH,SEL,CALL,ICAL,ENTER,LEAVE,RET,CFFB ; 50 52 54 56 58 5A 5C 5E - DW LB,LW,LLB,LLW,LAB,LAW,DLB,DLW ; 60 62 64 66 68 6A 6C 6E - DW SB,SW,SLB,SLW,SAB,SAW,DAB,DAW ; 70 72 74 76 78 7A 7C 7E - DW ADDBRLE,INCBRLE,SUBBRGE,DECBRGE,BRGT,BRLT ; 80 82 84 86 88 8A 8C 8E - DW BRGT,BRLT,INCBRLE,ADDBRLE,DECBRGE,SUBBRGE ; 80 82 84 86 88 8A 8C 8E +OPTBL DW CN,CN,CN,CN,CN,CN,CN,CN ; 00 02 04 06 08 0A 0C 0E + DW CN,CN,CN,CN,CN,CN,CN,CN ; 10 12 14 16 18 1A 1C 1E + DW MINUS1,NEXTOP,NEXTOP,LA,LLA,CB,CW,CS ; 20 22 24 26 28 2A 2C 2E + DW DROP,DROP2,DUP,DIVMOD,ADDI,SUBI,ANDI,ORI ; 30 32 34 36 38 3A 3C 3E + DW ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E + DW BRNCH,SEL,CALL,ICAL,ENTER,LEAVE,RET,CFFB ; 50 52 54 56 58 5A 5C 5E + DW LB,LW,LLB,LLW,LAB,LAW,DLB,DLW ; 60 62 64 66 68 6A 6C 6E + DW SB,SW,SLB,SLW,SAB,SAW,DAB,DAW ; 70 72 74 76 78 7A 7C 7E + DW LNOT,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 80 82 84 86 88 8A 8C 8E + DW NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 90 92 94 96 98 9A 9C 9E + DW BRGT,BRLT,INCBRLE,ADDBRLE,DECBRGE,SUBBRGE,BRAND,BROR ; A0 A2 A4 A6 A8 AA AC AE */ void interp(code *ip) { - int val, ea, frmsz, parmcnt; + int val, ea, frmsz, parmcnt, nybble; code *previp = ip; while (1) @@ -550,9 +558,46 @@ void interp(code *ip) printf("]\n"); gets(cmdline); } + nybble = 15; previp = ip; switch (*ip++) { + /* + * 0x00-0x1F + */ + case 0x00: + nybble--; + case 0x02: + nybble--; + case 0x04: + nybble--; + case 0x06: + nybble--; + case 0x08: + nybble--; + case 0x0A: + nybble--; + case 0x0C: + nybble--; + case 0x0E: + nybble--; + case 0x10: + nybble--; + case 0x12: + nybble--; + case 0x14: + nybble--; + case 0x16: + nybble--; + case 0x18: + nybble--; + case 0x1A: + nybble--; + case 0x1C: + nybble--; + case 0x1E: + PUSH)nybble); + break; /* * 0x00-0x0F */ From 5d531f53b1e4bd23b7c8562543d2a0bafd712731 Mon Sep 17 00:00:00 2001 From: Dave Schmenk Date: Tue, 13 Mar 2018 09:19:18 -0700 Subject: [PATCH 025/147] Fix sign of mod and divmod --- src/vmsrc/apple/plvm01.s | 19 ++--- src/vmsrc/apple/plvm02.s | 19 ++--- src/vmsrc/apple/plvm03.s | 19 ++--- src/vmsrc/apple/plvm802.s | 11 +-- src/vmsrc/c64/plvmc64.s | 19 ++--- src/vmsrc/plvm.c | 172 +++++++++++++++++++------------------- 6 files changed, 128 insertions(+), 131 deletions(-) diff --git a/src/vmsrc/apple/plvm01.s b/src/vmsrc/apple/plvm01.s index d8dc4b6..a3c04ba 100644 --- a/src/vmsrc/apple/plvm01.s +++ b/src/vmsrc/apple/plvm01.s @@ -150,7 +150,7 @@ DIVMOD JSR _DIV STA ESTKL,X LDA TMPH ; REMNDRH STA ESTKH,X - LDA DVSIGN ; REMAINDER IS SIGN OF DIVIDEND + ASL DVSIGN ; REMAINDER IS SIGN OF DIVIDEND BMI NEG JMP NEXTOP ;* @@ -174,21 +174,20 @@ _DIV STY IPY LDA #$00 STA TMPL ; REMNDRL STA TMPH ; REMNDRH - LDA ESTKH,X - AND #$80 STA DVSIGN - BPL + - JSR _NEG - INC DVSIGN -+ LDA ESTKH+1,X + LDA ESTKH+1,X BPL + INX JSR _NEG DEX - INC DVSIGN - BNE _DIV1 -+ ORA ESTKL+1,X ; DVDNDL + LDA #$81 + STA DVSIGN ++ ORA ESTKL+1,X ; DVDNDL BEQ _DIVEX + LDA ESTKH,X + BPL _DIV1 + JSR _NEG + INC DVSIGN _DIV1 ASL ESTKL+1,X ; DVDNDL ROL ESTKH+1,X ; DVDNDH DEY diff --git a/src/vmsrc/apple/plvm02.s b/src/vmsrc/apple/plvm02.s index c4dccd5..e62151b 100755 --- a/src/vmsrc/apple/plvm02.s +++ b/src/vmsrc/apple/plvm02.s @@ -496,21 +496,20 @@ _DIV STY IPY LDA #$00 STA TMPL ; REMNDRL STA TMPH ; REMNDRH - LDA ESTKH,X - AND #$80 STA DVSIGN - BPL + - JSR _NEG - INC DVSIGN -+ LDA ESTKH+1,X + LDA ESTKH+1,X BPL + INX JSR _NEG DEX - INC DVSIGN - BNE _DIV1 -+ ORA ESTKL+1,X ; DVDNDL + LDA #$81 + STA DVSIGN ++ ORA ESTKL+1,X ; DVDNDL BEQ _DIVEX + LDA ESTKH,X + BPL _DIV1 + JSR _NEG + INC DVSIGN _DIV1 ASL ESTKL+1,X ; DVDNDL ROL ESTKH+1,X ; DVDNDH DEY @@ -575,7 +574,7 @@ DIVMOD JSR _DIV STA ESTKL,X LDA TMPH ; REMNDRH STA ESTKH,X - LDA DVSIGN ; REMAINDER IS SIGN OF DIVIDEND + ASL DVSIGN ; REMAINDER IS SIGN OF DIVIDEND BMI NEG JMP NEXTOP ;* diff --git a/src/vmsrc/apple/plvm03.s b/src/vmsrc/apple/plvm03.s index b201959..14d7912 100755 --- a/src/vmsrc/apple/plvm03.s +++ b/src/vmsrc/apple/plvm03.s @@ -196,21 +196,20 @@ _DIV STY IPY LDA #$00 STA TMPL ; REMNDRL STA TMPH ; REMNDRH - LDA ESTKH,X - AND #$80 STA DVSIGN - BPL + - JSR _NEG - INC DVSIGN -+ LDA ESTKH+1,X + LDA ESTKH+1,X BPL + INX JSR _NEG DEX - INC DVSIGN - BNE _DIV1 -+ ORA ESTKL+1,X ; DVDNDL + LDA #$81 + STA DVSIGN ++ ORA ESTKL+1,X ; DVDNDL BEQ _DIVEX + LDA ESTKH,X + BPL _DIV1 + JSR _NEG + INC DVSIGN _DIV1 ASL ESTKL+1,X ; DVDNDL ROL ESTKH+1,X ; DVDNDH DEY @@ -299,7 +298,7 @@ DIVMOD JSR _DIV STA ESTKL,X LDA TMPH ; REMNDRH STA ESTKH,X - LDA DVSIGN ; REMAINDER IS SIGN OF DIVIDEND + ASL DVSIGN ; REMAINDER IS SIGN OF DIVIDEND BMI NEG JMP NEXTOP ;* diff --git a/src/vmsrc/apple/plvm802.s b/src/vmsrc/apple/plvm802.s index 2e9ca82..a27073a 100644 --- a/src/vmsrc/apple/plvm802.s +++ b/src/vmsrc/apple/plvm802.s @@ -549,19 +549,20 @@ _MULLP ASL _DIV STY IPY LDY #$11 ; #BITS+1 LDX #$00 - LDA TOS+2,S ; WE JSR'ED HERE SO OFFSET ACCORDINGLY + LDA NOS+2,S ; WE JSR'ED HERE SO OFFSET ACCORDINGLY + BEQ _DIVEX BPL + LDX #$81 EOR #$FFFF INC - STA TOS+2,S -+ LDA NOS+2,S ++ STA TMP ; NOS,S + LDA TOS+2,S BPL + INX EOR #$FFFF INC -+ STA TMP ; NOS,S - BEQ _DIVEX + STA TOS+2,S ++ LDA TMP _DIV1 ASL ; DVDND DEY BCC _DIV1 diff --git a/src/vmsrc/c64/plvmc64.s b/src/vmsrc/c64/plvmc64.s index a225723..345fcf3 100644 --- a/src/vmsrc/c64/plvmc64.s +++ b/src/vmsrc/c64/plvmc64.s @@ -150,7 +150,7 @@ DIVMOD JSR _DIV STA ESTKL,X LDA TMPH ; REMNDRH STA ESTKH,X - LDA DVSIGN ; REMAINDER IS SIGN OF DIVIDEND + ASL DVSIGN ; REMAINDER IS SIGN OF DIVIDEND BMI NEG JMP NEXTOP ;* @@ -174,21 +174,20 @@ _DIV STY IPY LDA #$00 STA TMPL ; REMNDRL STA TMPH ; REMNDRH - LDA ESTKH,X - AND #$80 STA DVSIGN - BPL + - JSR _NEG - INC DVSIGN -+ LDA ESTKH+1,X + LDA ESTKH+1,X BPL + INX JSR _NEG DEX - INC DVSIGN - BNE _DIV1 -+ ORA ESTKL+1,X ; DVDNDL + LDA #$81 + STA DVSIGN ++ ORA ESTKL+1,X ; DVDNDL BEQ _DIVEX + LDA ESTKH,X + BPL _DIV1 + JSR _NEG + INC DVSIGN _DIV1 ASL ESTKL+1,X ; DVDNDL ROL ESTKH+1,X ; DVDNDH DEY diff --git a/src/vmsrc/plvm.c b/src/vmsrc/plvm.c index 2035f52..64a3764 100755 --- a/src/vmsrc/plvm.c +++ b/src/vmsrc/plvm.c @@ -596,83 +596,7 @@ void interp(code *ip) case 0x1C: nybble--; case 0x1E: - PUSH)nybble); - break; - /* - * 0x00-0x0F - */ - case 0x00: // ZERO : TOS = 0 - PUSH(0); - break; - case 0x02: // ADD : TOS = TOS + TOS-1 - val = POP; - ea = POP; - PUSH(ea + val); - break; - case 0x04: // SUB : TOS = TOS-1 - TOS - val = POP; - ea = POP; - PUSH(ea - val); - break; - case 0x06: // MUL : TOS = TOS * TOS-1 - val = POP; - ea = POP; - PUSH(ea * val); - break; - case 0x08: // DIV : TOS = TOS-1 / TOS - val = POP; - ea = POP; - PUSH(ea / val); - break; - case 0x0A: // MOD : TOS = TOS-1 % TOS - val = POP; - ea = POP; - PUSH(ea % val); - break; - case 0x0C: // INCR : TOS = TOS + 1 - TOS++;; - break; - case 0x0E: // DECR : TOS = TOS - 1 - TOS--; - break; - /* - * 0x10-0x1F - */ - case 0x10: // NEG : TOS = -TOS - TOS = -TOS; - break; - case 0x12: // COMP : TOS = ~TOS - TOS = ~TOS; - break; - case 0x14: // AND : TOS = TOS & TOS-1 - val = POP; - ea = POP; - PUSH(ea & val); - break; - case 0x16: // IOR : TOS = TOS ! TOS-1 - val = POP; - ea = POP; - PUSH(ea | val); - break; - case 0x18: // XOR : TOS = TOS ^ TOS-1 - val = POP; - ea = POP; - PUSH(ea ^ val); - break; - case 0x1A: // SHL : TOS = TOS-1 << TOS - val = POP; - ea = POP; - PUSH(ea << val); - break; - case 0x1C: // SHR : TOS = TOS-1 >> TOS - val = POP; - ea = POP; - PUSH(ea >> val); - break; - case 0x1E: // IDXW : TOS = TOS * 2 + TOS-1 - val = POP; - ea = POP; - PUSH(ea + val * 2); + PUSH(nybble); break; /* * 0x20-0x2F @@ -931,10 +855,86 @@ void interp(code *ip) mem_data[ea + 1] = TOS >> 8; ip += 2; break; + /* + * 0x080-0x08F + */ + case 0x80: // ZERO : TOS = 0 + PUSH(0); + break; + case 0x82: // ADD : TOS = TOS + TOS-1 + val = POP; + ea = POP; + PUSH(ea + val); + break; + case 0x84: // SUB : TOS = TOS-1 - TOS + val = POP; + ea = POP; + PUSH(ea - val); + break; + case 0x86: // MUL : TOS = TOS * TOS-1 + val = POP; + ea = POP; + PUSH(ea * val); + break; + case 0x88: // DIV : TOS = TOS-1 / TOS + val = POP; + ea = POP; + PUSH(ea / val); + break; + case 0x8A: // MOD : TOS = TOS-1 % TOS + val = POP; + ea = POP; + PUSH(ea % val); + break; + case 0x8C: // INCR : TOS = TOS + 1 + TOS++;; + break; + case 0x8E: // DECR : TOS = TOS - 1 + TOS--; + break; /* - * 0x80-0x8F + * 0x90-0x9F */ - case 0x80: // BRGT : TOS-1 > TOS ? IP += (IP) + case 0x90: // NEG : TOS = -TOS + TOS = -TOS; + break; + case 0x92: // COMP : TOS = ~TOS + TOS = ~TOS; + break; + case 0x94: // AND : TOS = TOS & TOS-1 + val = POP; + ea = POP; + PUSH(ea & val); + break; + case 0x96: // IOR : TOS = TOS ! TOS-1 + val = POP; + ea = POP; + PUSH(ea | val); + break; + case 0x98: // XOR : TOS = TOS ^ TOS-1 + val = POP; + ea = POP; + PUSH(ea ^ val); + break; + case 0x9A: // SHL : TOS = TOS-1 << TOS + val = POP; + ea = POP; + PUSH(ea << val); + break; + case 0x9C: // SHR : TOS = TOS-1 >> TOS + val = POP; + ea = POP; + PUSH(ea >> val); + break; + case 0x9E: // IDXW : TOS = TOS * 2 + TOS-1 + val = POP; + ea = POP; + PUSH(ea + val * 2); + break; + /* + * 0xA0-0xAF + */ + case 0xA0: // BRGT : TOS-1 > TOS ? IP += (IP) val = POP; if (TOS < val) { @@ -947,7 +947,7 @@ void interp(code *ip) ip += 2; } break; - case 0x82: // BRLT : TOS-1 < TOS ? IP += (IP) + case 0xA2: // BRLT : TOS-1 < TOS ? IP += (IP) val = POP; if (TOS > val) { @@ -960,7 +960,7 @@ void interp(code *ip) ip += 2; } break; - case 0x84: // INCBRLE : TOS = TOS + 1 + case 0xA4: // INCBRLE : TOS = TOS + 1 val = POP; val++; if (TOS >= val) @@ -974,7 +974,7 @@ void interp(code *ip) ip += 2; } break; - case 0x86: // ADDBRLE : TOS = TOS + TOS-1 + case 0xA6: // ADDBRLE : TOS = TOS + TOS-1 val = POP; ea = POP; val = ea + val; @@ -989,7 +989,7 @@ void interp(code *ip) ip += 2; } break; - case 0x88: // DECBRGE : TOS = TOS - 1 + case 0xA8: // DECBRGE : TOS = TOS - 1 val = POP; val--; if (TOS <= val) @@ -1003,7 +1003,7 @@ void interp(code *ip) ip += 2; } break; - case 0x8A: // SUBBRGE : TOS = TOS-1 - TOS + case 0xAA: // SUBBRGE : TOS = TOS-1 - TOS val = POP; ea = POP; val = ea - val; @@ -1018,7 +1018,7 @@ void interp(code *ip) ip += 2; } break; - case 0x8C: // BRAND : SHORT CIRCUIT AND + case 0xAC: // BRAND : SHORT CIRCUIT AND if (TOS) // EVALUATE RIGHT HAND OF AND { POP; @@ -1029,7 +1029,7 @@ void interp(code *ip) ip += WORD_PTR(ip); } break; - case 0x8E: // BROR : SHORT CIRCUIT OR + case 0xAE: // BROR : SHORT CIRCUIT OR if (!TOS) // EVALUATE RIGHT HAND OF OR { POP; From 6f75211e7ed04080c1b8bbddead995822beac278 Mon Sep 17 00:00:00 2001 From: Dave Schmenk Date: Tue, 13 Mar 2018 09:29:51 -0700 Subject: [PATCH 026/147] Reduce makefile noise --- src/makefile | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/makefile b/src/makefile index d77eab5..1f7a289 100755 --- a/src/makefile +++ b/src/makefile @@ -76,10 +76,10 @@ TXTTYPE = .TXT #TXTTYPE = \#040000 apple: $(PLVMZP_APL) $(PLASM) $(PLVM) $(PLVM01) $(PLVM02) $(PLVM802) $(PLVM03) $(CMD) $(PLASMAPLASM) $(CODEOPT) $(ARGS) $(MEMMGR) $(MEMTEST) $(FIBER) $(FIBERTEST) $(LONGJMP) $(ED) $(MON) $(SOS) $(ROD) $(SIEVE) $(UTHERNET2) $(UTHERNET) $(ETHERIP) $(INET) $(DHCP) $(HTTPD) $(ROGUE) $(ROGUEMAP) $(ROGUECOMBAT) $(GRAFIX) $(GFXDEMO) $(DGR) $(DGRTEST) $(FILEIO_APL) $(CONIO_APL) $(JOYBUZZ) $(PORTIO) $(SPIPORT) $(SDFAT) $(FATCAT) $(FATGET) $(FATPUT) $(FATWDSK) $(FATRDSK) $(SANE) $(FPSTR) $(FPU) $(SANITY) $(RPNCALC) $(SNDSEQ) $(PLAYSEQ) - -rm vmsrc/plvmzp.inc + @rm vmsrc/plvmzp.inc c64: $(PLVMZP_C64) $(PLASM) $(PLVM) $(PLVMC64) - -rm vmsrc/plvmzp.inc + @rm vmsrc/plvmzp.inc all: apple c64 @@ -121,16 +121,16 @@ $(PLVM): vmsrc/plvm.c cc vmsrc/plvm.c -o $(PLVM) $(PLVMZP_APL): FORCE - -mkdir rel - -mkdir rel/apple - -rm vmsrc/plvmzp.inc - -ln -s apple/plvmzp.inc vmsrc/plvmzp.inc + @mkdir rel + @mkdir rel/apple + @rm vmsrc/plvmzp.inc + @ln -s apple/plvmzp.inc vmsrc/plvmzp.inc $(PLVMZP_C64): FORCE - -mkdir rel - -mkdir rel/c64 - -rm vmsrc/plvmzp.inc - -ln -s c64/plvmzp.inc vmsrc/plvmzp.inc + @mkdir rel + @mkdir rel/c64 + @rm vmsrc/plvmzp.inc + @ln -s c64/plvmzp.inc vmsrc/plvmzp.inc FORCE: From 19bacbc7eaf637e9fc590fa8fc3c8d1dede95939 Mon Sep 17 00:00:00 2001 From: Dave Schmenk Date: Tue, 13 Mar 2018 09:39:46 -0700 Subject: [PATCH 027/147] Reduce noise doesn't work on OSX --- src/makefile | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/src/makefile b/src/makefile index 1f7a289..66537bb 100755 --- a/src/makefile +++ b/src/makefile @@ -76,18 +76,16 @@ TXTTYPE = .TXT #TXTTYPE = \#040000 apple: $(PLVMZP_APL) $(PLASM) $(PLVM) $(PLVM01) $(PLVM02) $(PLVM802) $(PLVM03) $(CMD) $(PLASMAPLASM) $(CODEOPT) $(ARGS) $(MEMMGR) $(MEMTEST) $(FIBER) $(FIBERTEST) $(LONGJMP) $(ED) $(MON) $(SOS) $(ROD) $(SIEVE) $(UTHERNET2) $(UTHERNET) $(ETHERIP) $(INET) $(DHCP) $(HTTPD) $(ROGUE) $(ROGUEMAP) $(ROGUECOMBAT) $(GRAFIX) $(GFXDEMO) $(DGR) $(DGRTEST) $(FILEIO_APL) $(CONIO_APL) $(JOYBUZZ) $(PORTIO) $(SPIPORT) $(SDFAT) $(FATCAT) $(FATGET) $(FATPUT) $(FATWDSK) $(FATRDSK) $(SANE) $(FPSTR) $(FPU) $(SANITY) $(RPNCALC) $(SNDSEQ) $(PLAYSEQ) - @rm vmsrc/plvmzp.inc + -rm vmsrc/plvmzp.inc c64: $(PLVMZP_C64) $(PLASM) $(PLVM) $(PLVMC64) - @rm vmsrc/plvmzp.inc + -rm vmsrc/plvmzp.inc all: apple c64 clean: -rm *FE1000 *FF2000 $(PLASM) $(PLVM) $(PLVM01) $(PLVM02) $(PLVM03) - -rm rel/* - -rm rel/apple/* - -rm rel/c64/* + -rm -rf rel -rm samplesrc/*.o samplesrc/*~ samplesrc/*.a -rm toolsrc/*.o toolsrc/*~ toolsrc/*.a -rm toolsrc/apple/*.o toolsrc/apple/*~ toolsrc/apple/*.a @@ -121,16 +119,16 @@ $(PLVM): vmsrc/plvm.c cc vmsrc/plvm.c -o $(PLVM) $(PLVMZP_APL): FORCE - @mkdir rel - @mkdir rel/apple - @rm vmsrc/plvmzp.inc - @ln -s apple/plvmzp.inc vmsrc/plvmzp.inc + -mkdir rel + -mkdir rel/apple + -rm vmsrc/plvmzp.inc + -ln -s apple/plvmzp.inc vmsrc/plvmzp.inc $(PLVMZP_C64): FORCE - @mkdir rel - @mkdir rel/c64 - @rm vmsrc/plvmzp.inc - @ln -s c64/plvmzp.inc vmsrc/plvmzp.inc + -mkdir rel + -mkdir rel/c64 + -rm vmsrc/plvmzp.inc + -ln -s c64/plvmzp.inc vmsrc/plvmzp.inc FORCE: From 2da878889b407ba8c6c22ec81fcd65d6f5d5612f Mon Sep 17 00:00:00 2001 From: Dave Schmenk Date: Tue, 13 Mar 2018 10:23:01 -0700 Subject: [PATCH 028/147] Reduce makefile noise for OSX too --- src/makefile | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/makefile b/src/makefile index 66537bb..0a72c46 100755 --- a/src/makefile +++ b/src/makefile @@ -119,15 +119,15 @@ $(PLVM): vmsrc/plvm.c cc vmsrc/plvm.c -o $(PLVM) $(PLVMZP_APL): FORCE - -mkdir rel - -mkdir rel/apple - -rm vmsrc/plvmzp.inc + -mkdir -p rel + -mkdir -p rel/apple + -rm -f vmsrc/plvmzp.inc -ln -s apple/plvmzp.inc vmsrc/plvmzp.inc $(PLVMZP_C64): FORCE - -mkdir rel - -mkdir rel/c64 - -rm vmsrc/plvmzp.inc + -mkdir -p rel + -mkdir -p rel/c64 + -rm -f vmsrc/plvmzp.inc -ln -s c64/plvmzp.inc vmsrc/plvmzp.inc FORCE: From d515ab59690ccdbe4807b6c9bd954d5ba2fa8f63 Mon Sep 17 00:00:00 2001 From: Dave Schmenk Date: Tue, 13 Mar 2018 10:28:04 -0700 Subject: [PATCH 029/147] Update images --- PLASMA-BLD2.PO | Bin 143360 -> 143360 bytes PLASMA-SOS2.PO | Bin 143360 -> 143360 bytes PLASMA-SYS2.PO | Bin 143360 -> 143360 bytes 3 files changed, 0 insertions(+), 0 deletions(-) diff --git a/PLASMA-BLD2.PO b/PLASMA-BLD2.PO index d11ea7cdc21cbcd96dfde4151fcfde528faff75d..d54a451bda29886dd60705ae30a2d697c309e9be 100644 GIT binary patch delta 14171 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 TtCd6l_}BgaQq&chs`Y;X5m{9` delta 13818 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 EFKpBYO#lD@ diff --git a/PLASMA-SYS2.PO b/PLASMA-SYS2.PO index 8abe2a9d74a3c1d147fa0ddee90e7631bc918697..fc312ff0d8f594df3f4ff64832ce993a6faec9dd 100644 GIT binary patch delta 1305 zcmb`GYe-XJ7{|})%-c*GURtgkCtK3ZwIaGfbOEEwjQnJ#1Qmi171cg;gK0U6$_&=B ztIVb4p)zewO~f;a!WP7_y|=SL2wB>wwlt~_mA%I))fXv<_rrPK|NsBI&+mMA%KGBV z`r@0`s5CE#*KgkWW%BvjjLlGj^BIPvko2tyClVIO2rG72+UTGAex7$E%5<_ctN? zqV!TW)_pZSLB-~|>oPcQccbxWX^+I}Du!&sPDYSyU(FvGL3BZ90^ex#ZE{E!uQ|d9 zKB^=tipAU0JmioRE!l;fT1C6Oyky8mMS&?9whcSH4~7~PKZW*W@r`zMrok%EY!c0S zB!^flj=u`1nmVRdPVz>LN^W$b(S@BU)T84n`Wt-BeM(bZzw&SawWj^DXlK-=ozcKK z8c2%<99;@;s#x3Q8=vZ;?hMN1&D75mX|4M`DJmS%>=;OpMwH)(*Bjz$T*S%Kx>%o~ zF>&TFW6mRjM8)Z&Vx~69B|GEjdzM~HH?;*q?|Qz`eL;VaJ;Ar~Y*LkVGo1M3j&4H< zT!Hf8L3k8~nL+dg6oSc62j|1(a34N~ui{pG8aLoHq9$6>gDXfmDU_>ZC>Oyn9Dy59 z0Xl=Op(&Wh66!P2pw^7%B!LIIXVT*Jz zksM8|t9;|gh|V@}lhecvD&~;FB&S+=X(ChYgwvM~i$y$B_ D<>KvE delta 1268 zcmb`GYe-XJ7{|}qC8wqyYNk!MMlQ&TT+sajMIk7X21QBHg%TnPqSh74Sxx#fE7sB= z>U6TpNut%VMGf7c!j{CT^WM%GiD1~Ui)&IuH+zp2(HAL*_rv)=|L6Am@Emuy$=z)V zEHrQ+n<;S=W*0F%470_NVe(ZOYB*yiGu<&a=ePO5uqbPWLzksFoK_YbZFHsQ@l&of zwHG@dIg@6w$h%4s;?q91RsDAn&E6H$sZMyI#XS*7OGWhPzeWpIm-I;&3RUBsIEtVD7iyo+?6$Q=irt<*&S=jAy?w1wE( z$%viQ$aQL@)=+HO9 zS*Q|jhkIc^(~I7Nl^_G=!(uoSZpHg>6TXG(@g+Qpm`E;ph!2rkvQqKV!>@*K;8$3R zR-mKkG|Iv@`~-EOKJ*1m#tZOLyv~U~gU2$E6Y@Mz4g_!&G=iJ-;O~P@06-7ul8cCw ztRQ>HV)~bS!fYsfou!vPJaifS6WjAw*sn-}VxLqbifuwRv;pl#7g6}XU^j+uv8(g- zoJpuF8yvJ8)?YAk#)Kw4FOy?J(^}aImVF&Mc$+;#zl{ZV*o8D)bBAr#hrZoob*}Fm Clh927 From c3f9ee0911ea6e6ab3975a783ec30f58e75fd87f Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Tue, 13 Mar 2018 16:02:08 -0700 Subject: [PATCH 030/147] Save a few more bytes in the VM --- src/vmsrc/apple/plvm01.s | 31 ++++++++++++------------------- src/vmsrc/apple/plvm02.s | 37 ++++++++++++------------------------- src/vmsrc/apple/plvm03.s | 30 ++++++++++++------------------ src/vmsrc/apple/plvm802.s | 10 ---------- src/vmsrc/c64/plvmc64.s | 31 ++++++++++++------------------- 5 files changed, 48 insertions(+), 91 deletions(-) diff --git a/src/vmsrc/apple/plvm01.s b/src/vmsrc/apple/plvm01.s index a3c04ba..13eb955 100644 --- a/src/vmsrc/apple/plvm01.s +++ b/src/vmsrc/apple/plvm01.s @@ -711,7 +711,6 @@ ISTRU LDA #$FF STA ESTKL+1,X STA ESTKH+1,X JMP DROP -; ISNE LDA ESTKL,X CMP ESTKL+1,X BNE ISTRU @@ -722,7 +721,6 @@ ISFLS LDA #$00 STA ESTKL+1,X STA ESTKH+1,X JMP DROP -; ISGE LDA ESTKL+1,X CMP ESTKL,X LDA ESTKH+1,X @@ -730,9 +728,16 @@ ISGE LDA ESTKL+1,X BVS + BPL ISTRU BMI ISFLS -+ BPL ISFLS ++ + - BPL ISFLS BMI ISTRU -; +ISLE LDA ESTKL,X + CMP ESTKL+1,X + LDA ESTKH,X + SBC ESTKH+1,X + BVS - + BPL ISTRU + BMI ISFLS ISGT LDA ESTKL,X CMP ESTKL+1,X LDA ESTKH,X @@ -740,28 +745,16 @@ ISGT LDA ESTKL,X BVS + BMI ISTRU BPL ISFLS -+ BMI ISFLS ++ +- BMI ISFLS BPL ISTRU -; -ISLE LDA ESTKL,X - CMP ESTKL+1,X - LDA ESTKH,X - SBC ESTKH+1,X - BVS + - BPL ISTRU - BMI ISFLS -+ BPL ISFLS - BMI ISTRU -; ISLT LDA ESTKL+1,X CMP ESTKL,X LDA ESTKH+1,X SBC ESTKH,X - BVS + + BVS - BMI ISTRU BPL ISFLS -+ BMI ISFLS - BPL ISTRU ;* ;* BRANCHES ;* diff --git a/src/vmsrc/apple/plvm02.s b/src/vmsrc/apple/plvm02.s index e62151b..69c75f2 100755 --- a/src/vmsrc/apple/plvm02.s +++ b/src/vmsrc/apple/plvm02.s @@ -817,7 +817,6 @@ CS DEX LDA (IP),Y TAY JMP NEXTOP -; CSX DEX ;INY ;+INC_IP TYA ; NORMALIZE IP @@ -911,7 +910,6 @@ LW LDA ESTKL,X LDA (ESTKH-1,X) STA ESTKH,X JMP NEXTOP -; LBX LDA ESTKL,X STA ESTKH-1,X STA ALTRDOFF @@ -984,7 +982,6 @@ LLW INY ;+INC_IP STA ESTKH,X LDY IPY JMP NEXTOP -; LLBX INY ;+INC_IP LDA (IP),Y STY IPY @@ -1043,7 +1040,6 @@ LAW INY ;+INC_IP STA ESTKH,X LDY IPY JMP NEXTOP -; LABX INY ;+INC_IP LDA (IP),Y STA ESTKH-2,X @@ -1233,7 +1229,6 @@ ISTRU LDA #$FF STA ESTKL+1,X STA ESTKH+1,X JMP DROP -; ISNE LDA ESTKL,X CMP ESTKL+1,X BNE ISTRU @@ -1244,7 +1239,6 @@ ISFLS LDA #$00 STA ESTKL+1,X STA ESTKH+1,X JMP DROP -; ISGE LDA ESTKL+1,X CMP ESTKL,X LDA ESTKH+1,X @@ -1252,9 +1246,16 @@ ISGE LDA ESTKL+1,X BVS + BPL ISTRU BMI ISFLS -+ BPL ISFLS ++ +- BPL ISFLS BMI ISTRU -; +ISLE LDA ESTKL,X + CMP ESTKL+1,X + LDA ESTKH,X + SBC ESTKH+1,X + BVS - + BPL ISTRU + BMI ISFLS ISGT LDA ESTKL,X CMP ESTKL+1,X LDA ESTKH,X @@ -1262,28 +1263,16 @@ ISGT LDA ESTKL,X BVS + BMI ISTRU BPL ISFLS -+ BMI ISFLS ++ +- BMI ISFLS BPL ISTRU -; -ISLE LDA ESTKL,X - CMP ESTKL+1,X - LDA ESTKH,X - SBC ESTKH+1,X - BVS + - BPL ISTRU - BMI ISFLS -+ BPL ISFLS - BMI ISTRU -; ISLT LDA ESTKL+1,X CMP ESTKL,X LDA ESTKH+1,X SBC ESTKH,X - BVS + + BVS - BMI ISTRU BPL ISFLS -+ BMI ISFLS - BPL ISTRU ;* ;* BRANCHES ;* @@ -1470,7 +1459,6 @@ CALL INY ;+INC_IP STA OPPAGE LDY #$01 JMP FETCHOP -; CALLX INY ;+INC_IP LDA (IP),Y STA TMPL @@ -1526,7 +1514,6 @@ ICAL LDA ESTKL,X STA OPPAGE LDY #$01 JMP FETCHOP -; ICALX LDA ESTKL,X STA TMPL LDA ESTKH,X diff --git a/src/vmsrc/apple/plvm03.s b/src/vmsrc/apple/plvm03.s index 14d7912..34559d7 100755 --- a/src/vmsrc/apple/plvm03.s +++ b/src/vmsrc/apple/plvm03.s @@ -886,7 +886,6 @@ ISFLS LDA #$00 STA ESTKL+1,X STA ESTKH+1,X JMP DROP -; ISGE LDA ESTKL+1,X CMP ESTKL,X LDA ESTKH+1,X @@ -894,9 +893,16 @@ ISGE LDA ESTKL+1,X BVS + BPL ISTRU BMI ISFLS -+ BPL ISFLS ++ +- BPL ISFLS BMI ISTRU -; +ISLE LDA ESTKL,X + CMP ESTKL+1,X + LDA ESTKH,X + SBC ESTKH+1,X + BVS - + BPL ISTRU + BMI ISFLS ISGT LDA ESTKL,X CMP ESTKL+1,X LDA ESTKH,X @@ -904,28 +910,16 @@ ISGT LDA ESTKL,X BVS + BMI ISTRU BPL ISFLS -+ BMI ISFLS ++ +- BMI ISFLS BPL ISTRU -; -ISLE LDA ESTKL,X - CMP ESTKL+1,X - LDA ESTKH,X - SBC ESTKH+1,X - BVS + - BPL ISTRU - BMI ISFLS -+ BPL ISFLS - BMI ISTRU -; ISLT LDA ESTKL+1,X CMP ESTKL,X LDA ESTKH+1,X SBC ESTKH,X - BVS + + BVS - BMI ISTRU BPL ISFLS -+ BMI ISFLS - BPL ISTRU ;* ;* BRANCHES ;* diff --git a/src/vmsrc/apple/plvm802.s b/src/vmsrc/apple/plvm802.s index a27073a..022a62b 100644 --- a/src/vmsrc/apple/plvm802.s +++ b/src/vmsrc/apple/plvm802.s @@ -812,7 +812,6 @@ CS ;INY ;+INC_IP LDA (IP) TAY JMP NEXTOP -; CSX ;INY ;+INC_IP TYA ; NORMALIZE IP SEC @@ -885,7 +884,6 @@ LW TYX STA TOS,S TXY JMP NEXTOP -; LBX TYX LDY #$00 TYA ; QUICKY CLEAR OUT MSB @@ -941,7 +939,6 @@ LLW INY ;+INC_IP PHA TXY JMP NEXTOP -; LLBX INY ;+INC_IP TYX LDA (IP),Y @@ -983,7 +980,6 @@ LAW INY ;+INC_IP PHA INY ;+INC_IP JMP NEXTOP -; LABX INY ;+INC_IP LDA (IP),Y STA TMP @@ -1123,14 +1119,12 @@ ISEQ PLA ISTRU LDA #$FFFF STA TOS,S JMP NEXTOP -; ISNE PLA CMP TOS,S BNE ISTRU ISFLS LDA #$0000 STA TOS,S JMP NEXTOP -; ISGE PLA SEC SBC TOS,S @@ -1141,7 +1135,6 @@ ISGE PLA + BMI ISFLS BEQ ISFLS BPL ISTRU -; ISGT PLA SEC SBC TOS,S @@ -1150,7 +1143,6 @@ ISGT PLA BPL ISFLS + BMI ISFLS BPL ISTRU -; ISLE PLA SEC SBC TOS,S @@ -1159,7 +1151,6 @@ ISLE PLA BMI ISFLS + BPL ISFLS BMI ISTRU -; ISLT PLA SEC SBC TOS,S @@ -1627,7 +1618,6 @@ LEAVEX INY ;+INC_IP PLP RTS !AL -; RETX STX ALTRDOFF RET SEC ; SWITCH TO EMULATION MODE XCE diff --git a/src/vmsrc/c64/plvmc64.s b/src/vmsrc/c64/plvmc64.s index 345fcf3..9769664 100644 --- a/src/vmsrc/c64/plvmc64.s +++ b/src/vmsrc/c64/plvmc64.s @@ -711,7 +711,6 @@ ISTRU LDA #$FF STA ESTKL+1,X STA ESTKH+1,X JMP DROP -; ISNE LDA ESTKL,X CMP ESTKL+1,X BNE ISTRU @@ -722,7 +721,6 @@ ISFLS LDA #$00 STA ESTKL+1,X STA ESTKH+1,X JMP DROP -; ISGE LDA ESTKL+1,X CMP ESTKL,X LDA ESTKH+1,X @@ -730,9 +728,16 @@ ISGE LDA ESTKL+1,X BVS + BPL ISTRU BMI ISFLS -+ BPL ISFLS ++ +- BPL ISFLS BMI ISTRU -; +ISLE LDA ESTKL,X + CMP ESTKL+1,X + LDA ESTKH,X + SBC ESTKH+1,X + BVS - + BPL ISTRU + BMI ISFLS ISGT LDA ESTKL,X CMP ESTKL+1,X LDA ESTKH,X @@ -740,28 +745,16 @@ ISGT LDA ESTKL,X BVS + BMI ISTRU BPL ISFLS -+ BMI ISFLS ++ +- BMI ISFLS BPL ISTRU -; -ISLE LDA ESTKL,X - CMP ESTKL+1,X - LDA ESTKH,X - SBC ESTKH+1,X - BVS + - BPL ISTRU - BMI ISFLS -+ BPL ISFLS - BMI ISTRU -; ISLT LDA ESTKL+1,X CMP ESTKL,X LDA ESTKH+1,X SBC ESTKH,X - BVS + + BVS - BMI ISTRU BPL ISFLS -+ BMI ISFLS - BPL ISTRU ;* ;* BRANCHES ;* From 518b4e2680e415ee765e217b8ab27854610c2a79 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Wed, 14 Mar 2018 11:56:16 -0700 Subject: [PATCH 031/147] local and absolute address ADDs --- src/toolsrc/codegen.c | 141 +++++++++++++++++++++++++++++++- src/toolsrc/codegen.h | 8 ++ src/toolsrc/codeopt.pla | 106 ++++++++++++++++++------ src/toolsrc/codeseq.plh | 8 ++ src/vmsrc/apple/plvm01.s | 84 ++++++++++++++++--- src/vmsrc/apple/plvm02.s | 161 +++++++++++++++++++++++++++++++------ src/vmsrc/apple/plvm03.s | 90 ++++++++++++++------- src/vmsrc/apple/plvm802.s | 128 ++++++++++++++++++++++++++--- src/vmsrc/apple/soscmd.pla | 5 +- src/vmsrc/c64/plvmc64.s | 96 +++++++++++++++++++--- 10 files changed, 711 insertions(+), 116 deletions(-) diff --git a/src/toolsrc/codegen.c b/src/toolsrc/codegen.c index 85b89f3..1b4b3c1 100755 --- a/src/toolsrc/codegen.c +++ b/src/toolsrc/codegen.c @@ -652,6 +652,22 @@ void emit_llw(int index) { printf("\t%s\t$66,$%02X\t\t\t; LLW\t[%d]\n", DB, index, index); } +void emit_addlb(int index) +{ + printf("\t%s\t$B0,$%02X\t\t\t; ADDLB\t[%d]\n", DB, index, index); +} +void emit_addlw(int index) +{ + printf("\t%s\t$B2,$%02X\t\t\t; ADDLW\t[%d]\n", DB, index, index); +} +void emit_idxlb(int index) +{ + printf("\t%s\t$B8,$%02X\t\t\t; IDXLB\t[%d]\n", DB, index, index); +} +void emit_idxlw(int index) +{ + printf("\t%s\t$BA,$%02X\t\t\t; IDXLW\t[%d]\n", DB, index, index); +} void emit_lab(int tag, int offset, int type) { if (type) @@ -680,6 +696,62 @@ void emit_law(int tag, int offset, int type) printf("\t%s\t$6A,$%02X,$%02X\t\t; LAW\t%d\n", DB, offset&0xFF,(offset>>8)&0xFF, offset); } } +void emit_addab(int tag, int offset, int type) +{ + if (type) + { + int fixup = fixup_new(tag, type, FIXUP_WORD); + char *taglbl = tag_string(tag, type); + printf("\t%s\t$B4\t\t\t; ADDAB\t%s+%d\n", DB, taglbl, offset); + printf("_F%03d%c\t%s\t%s+%d\t\t\n", fixup, LBL, DW, type & EXTERN_TYPE ? "0" : taglbl, offset); + } + else + { + printf("\t%s\t$B4,$%02X,$%02X\t\t; ADDAB\t%d\n", DB, offset&0xFF,(offset>>8)&0xFF, offset); + } +} +void emit_addaw(int tag, int offset, int type) +{ + if (type) + { + int fixup = fixup_new(tag, type, FIXUP_WORD); + char *taglbl = tag_string(tag, type); + printf("\t%s\t$B6\t\t\t; ADDAW\t%s+%d\n", DB, taglbl, offset); + printf("_F%03d%c\t%s\t%s+%d\t\t\n", fixup, LBL, DW, type & EXTERN_TYPE ? "0" : taglbl, offset); + } + else + { + printf("\t%s\t$B6,$%02X,$%02X\t\t; ADDAW\t%d\n", DB, offset&0xFF,(offset>>8)&0xFF, offset); + } +} +void emit_idxab(int tag, int offset, int type) +{ + if (type) + { + int fixup = fixup_new(tag, type, FIXUP_WORD); + char *taglbl = tag_string(tag, type); + printf("\t%s\t$BC\t\t\t; IDXAB\t%s+%d\n", DB, taglbl, offset); + printf("_F%03d%c\t%s\t%s+%d\t\t\n", fixup, LBL, DW, type & EXTERN_TYPE ? "0" : taglbl, offset); + } + else + { + printf("\t%s\t$BC,$%02X,$%02X\t\t; IDXAB\t%d\n", DB, offset&0xFF,(offset>>8)&0xFF, offset); + } +} +void emit_idxaw(int tag, int offset, int type) +{ + if (type) + { + int fixup = fixup_new(tag, type, FIXUP_WORD); + char *taglbl = tag_string(tag, type); + printf("\t%s\t$BE\t\t\t; IDXAW\t%s+%d\n", DB, taglbl, offset); + printf("_F%03d%c\t%s\t%s+%d\t\t\n", fixup, LBL, DW, type & EXTERN_TYPE ? "0" : taglbl, offset); + } + else + { + printf("\t%s\t$BE,$%02X,$%02X\t\t; IDXAW\t%d\n", DB, offset&0xFF,(offset>>8)&0xFF, offset); + } +} void emit_sb(void) { printf("\t%s\t$70\t\t\t; SB\n", DB); @@ -1436,7 +1508,17 @@ int crunch_seq(t_opseq **seq, int pass) crunched = try_dupify(op); break; // GADDR_CODE case LLB_CODE: - if (pass > 0) + if ((opnext->code == ADD_CODE) || (opnext->code == INDEXB_CODE)) + { + op->code = ADDLB_CODE; + freeops = 1; + } + else if (opnext->code == INDEXW_CODE) + { + op->code = IDXLB_CODE; + freeops = 1; + } + if ((pass > 0) && (freeops == 0)) crunched = try_dupify(op); break; // LLB_CODE case LLW_CODE: @@ -1454,11 +1536,32 @@ int crunch_seq(t_opseq **seq, int pass) } } } + else if ((opnext->code == ADD_CODE) || (opnext->code == INDEXB_CODE)) + { + op->code = ADDLW_CODE; + freeops = 1; + } + else if (opnext->code == INDEXW_CODE) + { + op->code = IDXLW_CODE; + freeops = 1; + } if ((pass > 0) && (freeops == 0)) crunched = try_dupify(op); break; // LLW_CODE case LAB_CODE: - if ((pass > 0) && (op->type || !is_hardware_address(op->offsz))) + if ((opnext->code == ADD_CODE) || (opnext->code == INDEXB_CODE)) + { + op->code = ADDAB_CODE; + freeops = 1; + } + else if (opnext->code == INDEXW_CODE) + { + op->code = IDXAB_CODE; + freeops = 1; + } + if ((pass > 0) && (freeops == 0) && + (op->type || !is_hardware_address(op->offsz))) crunched = try_dupify(op); break; // LAB_CODE case LAW_CODE: @@ -1476,6 +1579,16 @@ int crunch_seq(t_opseq **seq, int pass) } } } + else if ((opnext->code == ADD_CODE) || (opnext->code == INDEXB_CODE)) + { + op->code = ADDAW_CODE; + freeops = 1; + } + else if (opnext->code == INDEXW_CODE) + { + op->code = IDXAW_CODE; + freeops = 1; + } if ((pass > 0) && (freeops == 0) && (op->type || !is_hardware_address(op->offsz))) crunched = try_dupify(op); @@ -1720,12 +1833,36 @@ int emit_pending_seq() case LLW_CODE: emit_llw(op->offsz); break; + case ADDLB_CODE: + emit_addlb(op->offsz); + break; + case ADDLW_CODE: + emit_addlw(op->offsz); + break; + case IDXLB_CODE: + emit_idxlb(op->offsz); + break; + case IDXLW_CODE: + emit_idxlw(op->offsz); + break; case LAB_CODE: emit_lab(op->tag, op->offsz, op->type); break; case LAW_CODE: emit_law(op->tag, op->offsz, op->type); break; + case ADDAB_CODE: + emit_addab(op->tag, op->offsz, op->type); + break; + case ADDAW_CODE: + emit_addaw(op->tag, op->offsz, op->type); + break; + case IDXAB_CODE: + emit_idxab(op->tag, op->offsz, op->type); + break; + case IDXAW_CODE: + emit_idxaw(op->tag, op->offsz, op->type); + break; case SB_CODE: emit_sb(); break; diff --git a/src/toolsrc/codegen.h b/src/toolsrc/codegen.h index af7d4af..2ea225b 100755 --- a/src/toolsrc/codegen.h +++ b/src/toolsrc/codegen.h @@ -68,6 +68,14 @@ typedef struct _opseq { #define BROR_CODE 0x324 #define CODETAG_CODE 0x0325 #define NOP_CODE 0x0326 +#define ADDLB_CODE 0x0330 +#define ADDLW_CODE 0x0331 +#define ADDAB_CODE 0x0332 +#define ADDAW_CODE 0x0333 +#define IDXLB_CODE 0x0334 +#define IDXLW_CODE 0x0335 +#define IDXAB_CODE 0x0336 +#define IDXAW_CODE 0x0337 #define gen_uop(seq,op) gen_seq(seq,UNARY_CODE(op),0,0,0,0) #define gen_op(seq,op) gen_seq(seq,BINARY_CODE(op),0,0,0,0) diff --git a/src/toolsrc/codeopt.pla b/src/toolsrc/codeopt.pla index 565e76e..9249adf 100644 --- a/src/toolsrc/codeopt.pla +++ b/src/toolsrc/codeopt.pla @@ -273,7 +273,8 @@ def crunch_seq(seq, pass) if nextop=>opnext nextopnext = nextop=>opnext when nextopnext->opcode - is INDEXB_CODE // ADD_CODE + is ADD_CODE + is INDEXB_CODE op=>opoffset = op=>opoffset + nextop=>opval freeops = 2 break @@ -311,7 +312,8 @@ def crunch_seq(seq, pass) if nextop=>opnext nextopnext = nextop=>opnext when nextopnext->opcode - is INDEXB_CODE // ADD_CODE + is ADD_CODE + is INDEXB_CODE op=>opoffset = op=>opoffset + nextop=>opval freeops = 2 break @@ -348,45 +350,97 @@ def crunch_seq(seq, pass) fin break // GADDR_CODE is LLB_CODE - if pass + when nextop->opcode + is ADD_CODE + is INDEXB_CODE + op->opcode = ADDLB_CODE + freeops = 1 + putc(':') + break + is INDEXW_CODE + op->opcode = IDXLB_CODE + freeops = 1 + putc(';') + break + wend + if pass and not freeops crunched = try_dupify(op) fin break // LLB_CODE is LLW_CODE - // LLW [n]:CB 8:SHR -> LLB [n+1] - if nextop->opcode == CONST_CODE and nextop=>opval == 8 - if nextop=>opnext - nextopnext = nextop=>opnext - if nextopnext->opcode == SHR_CODE - op->opcode = LLB_CODE - op=>opoffset++ - freeops = 2 - break + when nextop->opcode + is ADD_CODE + is INDEXB_CODE + op->opcode = ADDLW_CODE + freeops = 1 + putc(':') + break + is INDEXW_CODE + op->opcode = IDXLW_CODE + freeops = 1 + putc(';') + break + is CONST_CODE + // LLW [n]:CB 8:SHR -> LLB [n+1] + if nextop=>opval == 8 and nextop=>opnext + nextopnext = nextop=>opnext + if nextopnext->opcode == SHR_CODE + op->opcode = LLB_CODE + op=>opoffset++ + freeops = 2 + break + fin fin - fin - fin + break + wend if pass and not freeops crunched = try_dupify(op) fin break // LLW_CODE is LAB_CODE - if pass and not is_hardware_address(op=>opoffset) + when nextop->opcode + is ADD_CODE + is INDEXB_CODE + op->opcode = ADDAB_CODE + freeops = 1 + putc(':') + break + is INDEXW_CODE + op->opcode = IDXAB_CODE + freeops = 1 + putc(';') + break + wend + if pass and not freeops and not is_hardware_address(op=>opoffset) crunched = try_dupify(op) fin break // LAB_CODE is LAW_CODE - // LAW x:CB 8:SHR -> LAB x+1 - if nextop->opcode == CONST_CODE and nextop=>opval == 8 - if nextop=>opnext - nextopnext = nextop=>opnext - if nextopnext->opcode == SHR_CODE - op->opcode = LAB_CODE - op=>opoffset++ - freeops = 2 - break + when nextop->opcode + is ADD_CODE + is INDEXB_CODE + op->opcode = ADDAW_CODE + freeops = 1 + putc(':') + break + is INDEXW_CODE + op->opcode = IDXAW_CODE + freeops = 1 + putc(';') + break + is CONST_CODE + // LLW [n]:CB 8:SHR -> LLB [n+1] + if nextop=>opval == 8 and nextop=>opnext + nextopnext = nextop=>opnext + if nextopnext->opcode == SHR_CODE + op->opcode = LAB_CODE + op=>opoffset++ + freeops = 2 + break + fin fin - fin - fin + break + wend if pass and not freeops and not is_hardware_address(op=>opoffset) crunched = try_dupify(op) fin diff --git a/src/toolsrc/codeseq.plh b/src/toolsrc/codeseq.plh index 610c358..605786f 100644 --- a/src/toolsrc/codeseq.plh +++ b/src/toolsrc/codeseq.plh @@ -58,6 +58,10 @@ const DLB_CODE = $6C const DLW_CODE = $6E const SLB_CODE = $74 const SLW_CODE = $76 +const ADDLB_CODE = $B0 +const ADDLW_CODE = $B2 +const IDXLB_CODE = $B8 +const IDXLW_CODE = $BA // // Global address code group // @@ -70,6 +74,10 @@ const SAB_CODE = $78 const SAW_CODE = $7A const DAB_CODE = $7C const DAW_CODE = $7E +const ADDAB_CODE = $B4 +const ADDAW_CODE = $B6 +const IDXAB_CODE = $BC +const IDXAW_CODE = $BE // // Relative address code group // diff --git a/src/vmsrc/apple/plvm01.s b/src/vmsrc/apple/plvm01.s index 13eb955..bf71e31 100644 --- a/src/vmsrc/apple/plvm01.s +++ b/src/vmsrc/apple/plvm01.s @@ -120,6 +120,7 @@ OPTBL !WORD CN,CN,CN,CN,CN,CN,CN,CN ; 00 02 !WORD LNOT,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 80 82 84 86 88 8A 8C 8E !WORD NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 90 92 94 96 98 9A 9C 9E !WORD BRGT,BRLT,INCBRLE,ADDBRLE,DECBRGE,SUBBRGE,BRAND,BROR ; A0 A2 A4 A6 A8 AA AC AE + !WORD ADDLB,ADDLW,ADDAB,ADDAW,IDXLB,IDXLW,IDXAB,IDXAW ; B0 B2 B4 B6 B8 BA BC BE ;* ;* DIV TOS-1 BY TOS ;* @@ -336,17 +337,6 @@ DUP DEX STA ESTKH,X JMP NEXTOP ;* -;* LOGICAL NOT -;* -LNOT LDA ESTKL,X - ORA ESTKH,X - BEQ + - LDA #$FF -+ EOR #$FF - STA ESTKL,X - STA ESTKH,X - JMP NEXTOP -;* ;* ADD IMMEDIATE TO TOS ;* ADDI INY ;+INC_IP @@ -387,10 +377,20 @@ ORI INY ;+INC_IP STA ESTKL,X JMP NEXTOP ;* +;* LOGICAL NOT +;* +LNOT LDA ESTKL,X + ORA ESTKH,X + BEQ + + LDA #$00 + STA ESTKL,X + STA ESTKH,X + JMP NEXTOP +;* ;* CONSTANT -1, NYBBLE, BYTE, $FF BYTE, WORD (BELOW) ;* MINUS1 DEX - LDA #$FF ++ LDA #$FF STA ESTKL,X STA ESTKH,X JMP NEXTOP @@ -525,6 +525,36 @@ LLW INY ;+INC_IP LDY IPY JMP NEXTOP ;* +;* ADD VALUE FROM LOCAL FRAME OFFSET +;* +ADDLB LDA #$60 ; RTS + STA NEXTOP + JSR LLB + LDA #$C8 ; INY + STA NEXTOP + JMP ADD +ADDLW LDA #$60 ; RTS + STA NEXTOP + JSR LLW + LDA #$C8 ; INY + STA NEXTOP + JMP ADD +;* +;* INDEX VALUE FROM LOCAL FRAME OFFSET +;* +IDXLB LDA #$60 ; RTS + STA NEXTOP + JSR LLB + LDA #$C8 ; INY + STA NEXTOP + JMP IDXW +IDXLW LDA #$60 ; RTS + STA NEXTOP + JSR LLW + LDA #$C8 ; INY + STA NEXTOP + JMP IDXW +;* ;* LOAD VALUE FROM ABSOLUTE ADDRESS ;* LAB INY ;+INC_IP @@ -556,6 +586,36 @@ LAW INY ;+INC_IP LDY IPY JMP NEXTOP ;* +;* ADD VALUE FROM ABSOLUTE ADDRESS +;* +ADDAB LDA #$60 ; RTS + STA NEXTOP + JSR LAB + LDA #$C8 ; INY + STA NEXTOP + JMP ADD +ADDAW LDA #$60 ; RTS + STA NEXTOP + JSR LAW + LDA #$C8 ; INY + STA NEXTOP + JMP ADD +;* +;* INDEX VALUE FROM ABSOLUTE ADDRESS +;* +IDXAB LDA #$60 ; RTS + STA NEXTOP + JSR LAB + LDA #$C8 ; INY + STA NEXTOP + JMP IDXW +IDXAW LDA #$60 ; RTS + STA NEXTOP + JSR LAW + LDA #$C8 ; INY + STA NEXTOP + JMP IDXW +;* ;* STORE VALUE TO ADDRESS ;* SB LDA ESTKL,X diff --git a/src/vmsrc/apple/plvm02.s b/src/vmsrc/apple/plvm02.s index 69c75f2..29cd6be 100755 --- a/src/vmsrc/apple/plvm02.s +++ b/src/vmsrc/apple/plvm02.s @@ -204,21 +204,11 @@ OPTBL !WORD CN,CN,CN,CN,CN,CN,CN,CN ; 00 02 !WORD LNOT,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 80 82 84 86 88 8A 8C 8E !WORD NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 90 92 94 96 98 9A 9C 9E !WORD BRGT,BRLT,INCBRLE,ADDBRLE,DECBRGE,SUBBRGE,BRAND,BROR ; A0 A2 A4 A6 A8 AA AC AE + !WORD ADDLB,ADDLW,ADDAB,ADDAW,IDXLB,IDXLW,IDXAB,IDXAW ; B0 B2 B4 B6 B8 BA BC BE ;* ;* -;* ENTER INTO BYTECODE INTERPRETER +;* INDIRECTLY ENTER INTO BYTECODE INTERPRETER ;* -DINTRP PLA - CLC - ADC #$01 - STA IPL - PLA - ADC #$00 - STA IPH - LDY #$00 - LDA #>OPTBL - STA OPPAGE - JMP FETCHOP IINTRP PLA STA TMPL PLA @@ -415,6 +405,22 @@ OPXTBL !WORD CN,CN,CN,CN,CN,CN,CN,CN ; 00 02 !WORD LNOT,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 80 82 84 86 88 8A 8C 8E !WORD NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 90 92 94 96 98 9A 9C 9E !WORD BRGT,BRLT,INCBRLE,ADDBRLE,DECBRGE,SUBBRGE,BRAND,BROR ; A0 A2 A4 A6 A8 AA AC AE + !WORD ADDLBX,ADDLWX,ADDABX,ADDAWX,IDXLBX,IDXLWX,IDXABX,IDXAWX ; B0 B2 B4 B6 B8 BA BC BE +;* +;* +;* DIRECTLY ENTER INTO BYTECODE INTERPRETER +;* +DINTRP PLA + CLC + ADC #$01 + STA IPL + PLA + ADC #$00 + STA IPH + LDY #$00 + LDA #>OPTBL + STA OPPAGE + JMP FETCHOP ;* ;* ADD TOS TO TOS-1 ;* @@ -685,17 +691,6 @@ SHR STY IPY + LDY IPY JMP DROP ;* -;* LOGICAL NOT -;* -LNOT LDA ESTKL,X - ORA ESTKH,X - BEQ + - LDA #$FF -+ EOR #$FF - STA ESTKL,X - STA ESTKH,X - JMP NEXTOP -;* ;* DUPLICATE TOS ;* DUP DEX @@ -745,10 +740,20 @@ ORI INY ;+INC_IP STA ESTKL,X JMP NEXTOP ;* +;* LOGICAL NOT +;* +LNOT LDA ESTKL,X + ORA ESTKH,X + BEQ + + LDA #$00 + STA ESTKL,X + STA ESTKH,X + JMP NEXTOP +;* ;* CONSTANT -1, NYBBLE, BYTE, $FF BYTE, WORD (BELOW) ;* MINUS1 DEX - LDA #$FF ++ LDA #$FF STA ESTKL,X STA ESTKH,X JMP NEXTOP @@ -1010,6 +1015,60 @@ LLWX INY ;+INC_IP LDY IPY JMP NEXTOP ;* +;* ADD VALUE FROM LOCAL FRAME OFFSET +;* +ADDLB LDA #$60 ; RTS + STA NEXTOP + JSR LLB + LDA #$C8 ; INY + STA NEXTOP + JMP ADD +ADDLBX LDA #$60 ; RTS + STA NEXTOP + JSR LLBX + LDA #$C8 ; INY + STA NEXTOP + JMP ADD +ADDLW LDA #$60 ; RTS + STA NEXTOP + JSR LLW + LDA #$C8 ; INY + STA NEXTOP + JMP ADD +ADDLWX LDA #$60 ; RTS + STA NEXTOP + JSR LLWX + LDA #$C8 ; INY + STA NEXTOP + JMP ADD +;* +;* INDEX VALUE FROM LOCAL FRAME OFFSET +;* +IDXLB LDA #$60 ; RTS + STA NEXTOP + JSR LLB + LDA #$C8 ; INY + STA NEXTOP + JMP IDXW +IDXLBX LDA #$60 ; RTS + STA NEXTOP + JSR LLBX + LDA #$C8 ; INY + STA NEXTOP + JMP IDXW +IDXLW LDA #$60 ; RTS + STA NEXTOP + JSR LLW + LDA #$C8 ; INY + STA NEXTOP + JMP IDXW +IDXLWX LDA #$60 ; RTS + STA NEXTOP + JSR LLWX + LDA #$C8 ; INY + STA NEXTOP + JMP IDXW +;* ;* LOAD VALUE FROM ABSOLUTE ADDRESS ;* LAB INY ;+INC_IP @@ -1073,6 +1132,60 @@ LAWX INY ;+INC_IP LDY IPY JMP NEXTOP ;* +;* ADD VALUE FROM ABSOLUTE ADDRESS +;* +ADDAB LDA #$60 ; RTS + STA NEXTOP + JSR LAB + LDA #$C8 ; INY + STA NEXTOP + JMP ADD +ADDABX LDA #$60 ; RTS + STA NEXTOP + JSR LABX + LDA #$C8 ; INY + STA NEXTOP + JMP ADD +ADDAW LDA #$60 ; RTS + STA NEXTOP + JSR LAW + LDA #$C8 ; INY + STA NEXTOP + JMP ADD +ADDAWX LDA #$60 ; RTS + STA NEXTOP + JSR LAWX + LDA #$C8 ; INY + STA NEXTOP + JMP ADD +;* +;* INDEX VALUE FROM ABSOLUTE ADDRESS +;* +IDXAB LDA #$60 ; RTS + STA NEXTOP + JSR LAB + LDA #$C8 ; INY + STA NEXTOP + JMP IDXW +IDXABX LDA #$60 ; RTS + STA NEXTOP + JSR LABX + LDA #$C8 ; INY + STA NEXTOP + JMP IDXW +IDXAW LDA #$60 ; RTS + STA NEXTOP + JSR LAW + LDA #$C8 ; INY + STA NEXTOP + JMP IDXW +IDXAWX LDA #$60 ; RTS + STA NEXTOP + JSR LAWX + LDA #$C8 ; INY + STA NEXTOP + JMP IDXW +;* ;* STORE VALUE TO ADDRESS ;* SB LDA ESTKL,X diff --git a/src/vmsrc/apple/plvm03.s b/src/vmsrc/apple/plvm03.s index 34559d7..0343c1a 100755 --- a/src/vmsrc/apple/plvm03.s +++ b/src/vmsrc/apple/plvm03.s @@ -149,6 +149,7 @@ OPTBL !WORD CN,CN,CN,CN,CN,CN,CN,CN ; 00 02 !WORD LNOT,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 80 82 84 86 88 8A 8C 8E !WORD NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 90 92 94 96 98 9A 9C 9E !WORD BRGT,BRLT,INCBRLE,ADDBRLE,DECBRGE,SUBBRGE,BRAND,BROR ; A0 A2 A4 A6 A8 AA AC AE + !WORD ADDLB,ADDLW,ADDAB,ADDAW,IDXLB,IDXLW,IDXAB,IDXAW ; B0 B2 B4 B6 B8 BA BC BE ;* ;* SYSTEM INTERPRETER ENTRYPOINT ;* @@ -451,17 +452,6 @@ DUP DEX STA ESTKH,X JMP NEXTOP ;* -;* LOGICAL NOT -;* -LNOT LDA ESTKL,X - ORA ESTKH,X - BEQ + - LDA #$FF -+ EOR #$FF - STA ESTKL,X - STA ESTKH,X - JMP NEXTOP -;* ;* ADD IMMEDIATE TO TOS ;* ADDI INY ;+INC_IP @@ -502,10 +492,20 @@ ORI INY ;+INC_IP STA ESTKL,X JMP NEXTOP ;* +;* LOGICAL NOT +;* +LNOT LDA ESTKL,X + ORA ESTKH,X + BEQ + + LDA #$00 + STA ESTKL,X + STA ESTKH,X + JMP NEXTOP +;* ;* CONSTANT -1, NYBBLE, BYTE, $FF BYTE, WORD (BELOW) ;* MINUS1 DEX - LDA #$FF ++ LDA #$FF STA ESTKL,X STA ESTKH,X JMP NEXTOP @@ -534,6 +534,7 @@ CB LDA #$00 BCC + INC IPH + LDY #$FF +CW LA INY ;+INC_IP BMI - DEX @@ -543,14 +544,14 @@ LA INY ;+INC_IP LDA (IP),Y STA ESTKH,X JMP NEXTOP -CW DEX - INY ;+INC_IP - LDA (IP),Y - STA ESTKL,X - INY - LDA (IP),Y - STA ESTKH,X - JMP NEXTOP +;CW DEX +; INY ;+INC_IP +; LDA (IP),Y +; STA ESTKL,X +; INY +; LDA (IP),Y +; STA ESTKH,X +; JMP NEXTOP ;* ;* CONSTANT STRING ;* @@ -665,7 +666,7 @@ LLA INY ;+INC_IP ;* ;* LOAD VALUE FROM LOCAL FRAME OFFSET ;* -LLB INY ;+INC_IP +_LLB INY ;+INC_IP LDA (IP),Y STY IPY TAY @@ -675,8 +676,8 @@ LLB INY ;+INC_IP LDA #$00 STA ESTKH,X LDY IPY - JMP NEXTOP -LLW INY ;+INC_IP + RTS +_LLW INY ;+INC_IP LDA (IP),Y STY IPY TAY @@ -687,11 +688,29 @@ LLW INY ;+INC_IP LDA (IFP),Y STA ESTKH,X LDY IPY + RTS +LLB JSR _LLB JMP NEXTOP +LLW JSR _LLW + JMP NEXTOP +;* +;* ADD VALUE FROM LOCAL FRAME OFFSET +;* +ADDLB JSR _LLB + JMP ADD +ADDLW JSR _LLW + JMP ADD +;* +;* INDEX VALUE FROM LOCAL FRAME OFFSET +;* +IDXLB JSR _LLB + JMP IDXW +IDXLW JSR _LLW + JMP IDXW ;* ;* LOAD VALUE FROM ABSOLUTE ADDRESS ;* -LAB INY ;+INC_IP +_LAB INY ;+INC_IP LDA (IP),Y STA ESTKH-2,X INY ;+INC_IP @@ -702,8 +721,8 @@ LAB INY ;+INC_IP STA ESTKL,X LDA #$00 STA ESTKH,X - JMP NEXTOP -LAW INY ;+INC_IP + RTS +_LAW INY ;+INC_IP LDA (IP),Y STA TMPL INY ;+INC_IP @@ -718,7 +737,25 @@ LAW INY ;+INC_IP LDA (TMP),Y STA ESTKH,X LDY IPY + RTS +LAB JSR _LAB JMP NEXTOP +LAW JSR _LAW + JMP NEXTOP +;* +;* ADD VALUE FROM ABSOLUTE ADDRESS +;* +ADDAB JSR _LAB + JMP ADD +ADDAW JSR _LAW + JMP ADD +;* +;* INDEX VALUE FROM ABSOLUTE ADDRESS +;* +IDXAB JSR _LAB + JMP IDXW +IDXAW JSR _LAW + JMP IDXW ;* ;* STORE VALUE TO ADDRESS ;* @@ -875,7 +912,6 @@ ISTRU LDA #$FF STA ESTKL+1,X STA ESTKH+1,X JMP DROP -; ISNE LDA ESTKL,X CMP ESTKL+1,X BNE ISTRU diff --git a/src/vmsrc/apple/plvm802.s b/src/vmsrc/apple/plvm802.s index 022a62b..8bf8ac8 100644 --- a/src/vmsrc/apple/plvm802.s +++ b/src/vmsrc/apple/plvm802.s @@ -242,6 +242,7 @@ OPTBL !WORD CN,CN,CN,CN,CN,CN,CN,CN ; 00 02 !WORD LNOT,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 80 82 84 86 88 8A 8C 8E !WORD NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 90 92 94 96 98 9A 9C 9E !WORD BRGT,BRLT,INCBRLE,ADDBRLE,DECBRGE,SUBBRGE,BRAND,BROR ; A0 A2 A4 A6 A8 AA AC AE + !WORD ADDLB,ADDLW,ADDAB,ADDAW,IDXLB,IDXLW,IDXAB,IDXAW ; B0 B2 B4 B6 B8 BA BC BE ;* ;* ENTER INTO BYTECODE INTERPRETER - IMMEDIATELY SWITCH TO NATIVE ;* @@ -474,6 +475,7 @@ OPXTBL !WORD CN,CN,CN,CN,CN,CN,CN,CN ; 00 02 !WORD LNOT,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 80 82 84 86 88 8A 8C 8E !WORD NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 90 92 94 96 98 9A 9C 9E !WORD BRGT,BRLT,INCBRLE,ADDBRLE,DECBRGE,SUBBRGE,BRAND,BROR ; A0 A2 A4 A6 A8 AA AC AE + !WORD ADDLBX,ADDLWX,ADDABX,ADDAWX,IDXLBX,IDXLWX,IDXABX,IDXAWX ; B0 B2 B4 B6 B8 BA BC BE !AS DINTRP PHP PLA @@ -719,15 +721,6 @@ DUP LDA TOS,S PHA JMP NEXTOP ;* -;* LOGICAL NOT -;* -LNOT PLA - BNE + - PEA $FFFF - JMP NEXTOP -+ PEA $0000 - JMP NEXTOP -;* ;* ADD IMMEDIATE TO TOS ;* ADDI INY ;+INC_IP @@ -767,6 +760,13 @@ ORI INY ;+INC_IP STA TOS,S JMP NEXTOP ;* +;* LOGICAL NOT +;* +LNOT PLA + BEQ MINUS1 + PEA $0000 + JMP NEXTOP +;* ;* CONSTANT -1, NYBBLE, BYTE, $FF BYTE, WORD (BELOW) ;* MINUS1 PEA $FFFF @@ -961,6 +961,60 @@ LLWX INY ;+INC_IP TXY JMP NEXTOP ;* +;* ADD VALUE FROM LOCAL FRAME OFFSET +;* +ADDLB LDX #$60 ; RTS + STX NEXTOP + JSR LLB + LDX #$C8 ; INY + STX NEXTOP + JMP ADD +ADDLBX LDX #$60 ; RTS + STX NEXTOP + JSR LLBX + LDX #$C8 ; INY + STX NEXTOP + JMP ADD +ADDLW LDX #$60 ; RTS + STX NEXTOP + JSR LLW + LDX #$C8 ; INY + STX NEXTOP + JMP ADD +ADDLWX LDX #$60 ; RTS + STX NEXTOP + JSR LLWX + LDX #$C8 ; INY + STX NEXTOP + JMP ADD +;* +;* INDEX VALUE FROM LOCAL FRAME OFFSET +;* +IDXLB LDX #$60 ; RTS + STX NEXTOP + JSR LLB + LDX #$C8 ; INY + STX NEXTOP + JMP IDXW +IDXLBX LDX #$60 ; RTS + STX NEXTOP + JSR LLBX + LDX #$C8 ; INY + STX NEXTOP + JMP IDXW +IDXLW LDX #$60 ; RTS + STX NEXTOP + JSR LLW + LDX #$C8 ; INY + STX NEXTOP + JMP IDXW +IDXLWX LDX #$60 ; RTS + STX NEXTOP + JSR LLWX + LDX #$C8 ; INY + STX NEXTOP + JMP IDXW +;* ;* LOAD VALUE FROM ABSOLUTE ADDRESS ;* LAB INY ;+INC_IP @@ -1001,7 +1055,60 @@ LAWX INY ;+INC_IP PHA INY ;+INC_IP JMP NEXTOP -; +;* +;* ADD VALUE FROM ABSOLUTE ADDRESS +;* +ADDAB LDX #$60 ; RTS + STX NEXTOP + JSR LAB + LDX #$C8 ; INY + STX NEXTOP + JMP ADD +ADDABX LDX #$60 ; RTS + STX NEXTOP + JSR LABX + LDX #$C8 ; INY + STX NEXTOP + JMP ADD +ADDAW LDX #$60 ; RTS + STX NEXTOP + JSR LAW + LDX #$C8 ; INY + STX NEXTOP + JMP ADD +ADDAWX LDX #$60 ; RTS + STX NEXTOP + JSR LAWX + LDX #$C8 ; INY + STX NEXTOP + JMP ADD +;* +;* INDEX VALUE FROM ABSOLUTE ADDRESS +;* +IDXAB LDX #$60 ; RTS + STX NEXTOP + JSR LAB + LDX #$C8 ; INY + STX NEXTOP + JMP IDXW +IDXABX LDX #$60 ; RTS + STX NEXTOP + JSR LABX + LDX #$C8 ; INY + STX NEXTOP + JMP IDXW +IDXAW LDX #$60 ; RTS + STX NEXTOP + JSR LAW + LDX #$C8 ; INY + STX NEXTOP + JMP IDXW +IDXAWX LDX #$60 ; RTS + STX NEXTOP + JSR LAWX + LDX #$C8 ; INY + STX NEXTOP + JMP IDXW ;* ;* STORE VALUE TO ADDRESS ;* @@ -1683,6 +1790,7 @@ DBGTBL !WORD STEP,STEP,STEP,STEP,STEP,STEP,STEP,STEP ; 00 02 04 06 08 !WORD STEP,STEP,STEP,STEP,STEP,STEP,STEP,STEP ; 80 82 84 86 88 8A 8C 8E !WORD STEP,STEP,STEP,STEP,STEP,STEP,STEP,STEP ; 90 92 94 96 98 9A 9C 9E !WORD STEP,STEP,STEP,STEP,STEP,STEP,STEP,STEP ; A0 A2 A4 A6 A8 AA AC AE + !WORD STEP,STEP,STEP,STEP,STEP,STEP,STEP,STEP ; B0 B2 B4 B6 B8 BA BC BE ;* ;* DEBUG PRINT ROUTINES ;* diff --git a/src/vmsrc/apple/soscmd.pla b/src/vmsrc/apple/soscmd.pla index 12c8101..7b89fc1 100755 --- a/src/vmsrc/apple/soscmd.pla +++ b/src/vmsrc/apple/soscmd.pla @@ -122,7 +122,7 @@ word heap = $2000 byte modid = 0 byte modseg[15] word symtbl, lastsym -byte perr, terr, lerr +byte perr, terr // // Utility functions // @@ -1078,7 +1078,7 @@ def loadmod(mod)#1 word addr, defaddr, modaddr, modfix, modofst, modend word deftbl, deflast, codeseg word moddep, rld, esd, sym - byte defext, str[16], filename[33] + byte lerr, defext, str[16], filename[33] byte header[128] lerr = 0 // @@ -1510,7 +1510,6 @@ while 1 terr = perr prstr("ERR:$") prbyte(terr) - perr = 0 else prstr("OK") fin diff --git a/src/vmsrc/c64/plvmc64.s b/src/vmsrc/c64/plvmc64.s index 9769664..cb61aad 100644 --- a/src/vmsrc/c64/plvmc64.s +++ b/src/vmsrc/c64/plvmc64.s @@ -120,6 +120,7 @@ OPTBL !WORD CN,CN,CN,CN,CN,CN,CN,CN ; 00 02 !WORD LNOT,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 80 82 84 86 88 8A 8C 8E !WORD NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 90 92 94 96 98 9A 9C 9E !WORD BRGT,BRLT,INCBRLE,ADDBRLE,DECBRGE,SUBBRGE,BRAND,BROR ; A0 A2 A4 A6 A8 AA AC AE + !WORD ADDLB,ADDLW,ADDAB,ADDAW,IDXLB,IDXLW,IDXAB,IDXAW ; B0 B2 B4 B6 B8 BA BC BE ;* ;* DIV TOS-1 BY TOS ;* @@ -336,17 +337,6 @@ DUP DEX STA ESTKH,X JMP NEXTOP ;* -;* LOGICAL NOT -;* -LNOT LDA ESTKL,X - ORA ESTKH,X - BEQ + - LDA #$FF -+ EOR #$FF - STA ESTKL,X - STA ESTKH,X - JMP NEXTOP -;* ;* ADD IMMEDIATE TO TOS ;* ADDI INY ;+INC_IP @@ -387,10 +377,20 @@ ORI INY ;+INC_IP STA ESTKL,X JMP NEXTOP ;* +;* LOGICAL NOT +;* +LNOT LDA ESTKL,X + ORA ESTKH,X + BEQ + + LDA #$00 + STA ESTKL,X + STA ESTKH,X + JMP NEXTOP +;* ;* CONSTANT -1, NYBBLE, BYTE, $FF BYTE, WORD (BELOW) ;* MINUS1 DEX - LDA #$FF ++ LDA #$FF STA ESTKL,X STA ESTKH,X JMP NEXTOP @@ -525,6 +525,48 @@ LLW INY ;+INC_IP LDY IPY JMP NEXTOP ;* +;* ADD VALUE FROM LOCAL FRAME OFFSET +;* +ADDLB LDA #$60 ; RTS + STA NEXTOP + JSR LLB + LDA #$C8 ; INY + STA NEXTOP + JMP ADD +ADDLBX LDA #$60 ; RTS + STA NEXTOP + JSR LLBX + LDA #$C8 ; INY + STA NEXTOP + JMP ADD +ADDLW LDA #$60 ; RTS + STA NEXTOP + JSR LLW + LDA #$C8 ; INY + STA NEXTOP + JMP ADD +ADDLWX LDA #$60 ; RTS + STA NEXTOP + JSR LLWX + LDA #$C8 ; INY + STA NEXTOP + JMP ADD +;* +;* INDEX VALUE FROM LOCAL FRAME OFFSET +;* +IDXLB LDA #$60 ; RTS + STA NEXTOP + JSR LLB + LDA #$C8 ; INY + STA NEXTOP + JMP IDXW +IDXLW LDA #$60 ; RTS + STA NEXTOP + JSR LLW + LDA #$C8 ; INY + STA NEXTOP + JMP IDXW +;* ;* LOAD VALUE FROM ABSOLUTE ADDRESS ;* LAB INY ;+INC_IP @@ -556,6 +598,36 @@ LAW INY ;+INC_IP LDY IPY JMP NEXTOP ;* +;* ADD VALUE FROM ABSOLUTE ADDRESS +;* +ADDAB LDA #$60 ; RTS + STA NEXTOP + JSR LAB + LDA #$C8 ; INY + STA NEXTOP + JMP ADD +ADDAW LDA #$60 ; RTS + STA NEXTOP + JSR LAW + LDA #$C8 ; INY + STA NEXTOP + JMP ADD +;* +;* INDEX VALUE FROM ABSOLUTE ADDRESS +;* +IDXAB LDA #$60 ; RTS + STA NEXTOP + JSR LAB + LDA #$C8 ; INY + STA NEXTOP + JMP IDXW +IDXAW LDA #$60 ; RTS + STA NEXTOP + JSR LAW + LDA #$C8 ; INY + STA NEXTOP + JMP IDXW +;* ;* STORE VALUE TO ADDRESS ;* SB LDA ESTKL,X From 0045d0eabb77f2c79818d2f52ab785650d5ac844 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Wed, 14 Mar 2018 11:59:39 -0700 Subject: [PATCH 032/147] Remove debug prints --- src/toolsrc/codeopt.pla | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/toolsrc/codeopt.pla b/src/toolsrc/codeopt.pla index 9249adf..e5ab340 100644 --- a/src/toolsrc/codeopt.pla +++ b/src/toolsrc/codeopt.pla @@ -355,12 +355,10 @@ def crunch_seq(seq, pass) is INDEXB_CODE op->opcode = ADDLB_CODE freeops = 1 - putc(':') break is INDEXW_CODE op->opcode = IDXLB_CODE freeops = 1 - putc(';') break wend if pass and not freeops @@ -373,12 +371,10 @@ def crunch_seq(seq, pass) is INDEXB_CODE op->opcode = ADDLW_CODE freeops = 1 - putc(':') break is INDEXW_CODE op->opcode = IDXLW_CODE freeops = 1 - putc(';') break is CONST_CODE // LLW [n]:CB 8:SHR -> LLB [n+1] @@ -403,12 +399,10 @@ def crunch_seq(seq, pass) is INDEXB_CODE op->opcode = ADDAB_CODE freeops = 1 - putc(':') break is INDEXW_CODE op->opcode = IDXAB_CODE freeops = 1 - putc(';') break wend if pass and not freeops and not is_hardware_address(op=>opoffset) @@ -421,12 +415,10 @@ def crunch_seq(seq, pass) is INDEXB_CODE op->opcode = ADDAW_CODE freeops = 1 - putc(':') break is INDEXW_CODE op->opcode = IDXAW_CODE freeops = 1 - putc(';') break is CONST_CODE // LLW [n]:CB 8:SHR -> LLB [n+1] From 852b5b72680cb8455349d724ea617d0a54efa345 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Wed, 14 Mar 2018 12:30:51 -0700 Subject: [PATCH 033/147] Update images --- PLASMA-BLD2.PO | Bin 143360 -> 143360 bytes PLASMA-DEM2.PO | Bin 143360 -> 143360 bytes PLASMA-SOS2.PO | Bin 143360 -> 143360 bytes PLASMA-SYS2.PO | Bin 143360 -> 143360 bytes src/toolsrc/codegen.c | 10 ++++------ 5 files changed, 4 insertions(+), 6 deletions(-) diff --git a/PLASMA-BLD2.PO b/PLASMA-BLD2.PO index d54a451bda29886dd60705ae30a2d697c309e9be..096af24cd1813318120332a509063e3da91f1486 100644 GIT binary patch delta 14898 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 diff --git a/src/toolsrc/codegen.c b/src/toolsrc/codegen.c index e4419d2..7c24b4e 100755 --- a/src/toolsrc/codegen.c +++ b/src/toolsrc/codegen.c @@ -1268,6 +1268,14 @@ int crunch_seq(t_opseq **seq, int pass) freeops = 1; } break; + case BRGT_CODE: + if (opprev && (opprev->code == CONST_CODE) && (op->val <= opprev->val)) + freeops = 1; + break; + case BRLT_CODE: + if (opprev && (opprev->code == CONST_CODE) && (op->val >= opprev->val)) + freeops = 1; + break; case BROR_CODE: if (!op->val) freeops = -2; // Remove zero constant @@ -1355,7 +1363,7 @@ int crunch_seq(t_opseq **seq, int pass) case BINARY_CODE(LE_TOKEN): op->val = op->val <= opnext->val ? 1 : 0; freeops = 2; - break; + break; } // End of collapse constant operation if ((pass > 0) && (freeops == 0) && (op->val != 0)) @@ -1976,6 +1984,12 @@ int emit_pending_seq() case BRTRUE_CODE: emit_brtru(op->tag); break; + case BRGT_CODE: + emit_brgt(op->tag); + break; + case BRLT_CODE: + emit_brlt(op->tag); + break; case CODETAG_CODE: printf("_B%03d%c\n", op->tag, LBL); break; diff --git a/src/toolsrc/codegen.h b/src/toolsrc/codegen.h index 6288330..ffde6de 100755 --- a/src/toolsrc/codegen.h +++ b/src/toolsrc/codegen.h @@ -66,10 +66,12 @@ typedef struct _opseq { #define BRTRUE_CODE 0x0322 #define BREQ_CODE 0x0323 #define BRNE_CODE 0x0324 -#define BRAND_CODE 0x325 -#define BROR_CODE 0x326 -#define CODETAG_CODE 0x0327 -#define NOP_CODE 0x0328 +#define BRAND_CODE 0x0325 +#define BROR_CODE 0x0326 +#define BRLT_CODE 0x0327 +#define BRGT_CODE 0x0328 +#define CODETAG_CODE 0x0329 +#define NOP_CODE 0x032A #define ADDLB_CODE 0x0330 #define ADDLW_CODE 0x0331 #define ADDAB_CODE 0x0332 @@ -95,6 +97,8 @@ typedef struct _opseq { #define gen_drop(seq) gen_seq(seq,DROP_CODE,0,0,0,0) #define gen_brand(seq,tag) gen_seq(seq,BRAND_CODE,0,tag,0,0) #define gen_bror(seq,tag) gen_seq(seq,BROR_CODE,0,tag,0,0) +#define gen_brgt(seq,tag) gen_seq(seq,BRGT_CODE,0,tag,0,0) +#define gen_brlt(seq,tag) gen_seq(seq,BRLT_CODE,0,tag,0,0) #define gen_brfls(seq,tag) gen_seq(seq,BRFALSE_CODE,0,tag,0,0) #define gen_brtru(seq,tag) gen_seq(seq,BRTRUE_CODE,0,tag,0,0) #define gen_brnch(seq,tag) gen_seq(seq,BRNCH_CODE,0,tag,0,0) diff --git a/src/toolsrc/codeopt.pla b/src/toolsrc/codeopt.pla index e5ab340..92dd64b 100644 --- a/src/toolsrc/codeopt.pla +++ b/src/toolsrc/codeopt.pla @@ -113,6 +113,16 @@ def crunch_seq(seq, pass) freeops = 1 fin break + is BRGT_CODE + if opprev and (opprev->opcode == CONST_CODE) and (op=>opval <= opprev=>opval) + freeops = 1 + fin + break + is BRLT_CODE + if opprev and (opprev->opcode == CONST_CODE) and (op=>opval >= opprev=>opval) + freeops = 1 + fin + break is BROR_CODE if not op=>opval freeops = -2 // Remove zero constant diff --git a/src/toolsrc/codeseq.plh b/src/toolsrc/codeseq.plh index 605786f..21dd605 100644 --- a/src/toolsrc/codeseq.plh +++ b/src/toolsrc/codeseq.plh @@ -87,6 +87,8 @@ const BRTRUE_CODE = $4E const BRNCH_CODE = $50 const BRAND_CODE = $AC const BROR_CODE = $AE +const BRGT_CODE = $A0 +const BRLT_CODE = $A2 // // Code tag address group // diff --git a/src/toolsrc/parse.c b/src/toolsrc/parse.c index 82bc69c..77bee1e 100755 --- a/src/toolsrc/parse.c +++ b/src/toolsrc/parse.c @@ -994,9 +994,8 @@ int parse_stmnt(void) { seq = NULL; } - emit_seq(toseq); - emit_seq(fromseq); - step > 0 ? emit_brgt(break_tag) : emit_brlt(break_tag); + toseq = cat_seq(toseq, fromseq); + emit_seq(step > 0 ? gen_brgt(toseq, break_tag) : gen_brlt(toseq, break_tag)); emit_codetag(tag_for); if (type & LOCAL_TYPE) type & BYTE_TYPE ? emit_dlb(addr) : emit_dlw(addr); diff --git a/src/toolsrc/parse.pla b/src/toolsrc/parse.pla index 831beec..249850f 100644 --- a/src/toolsrc/parse.pla +++ b/src/toolsrc/parse.pla @@ -755,9 +755,7 @@ def parse_stmnt else seq = NULL fin - emit_seq(toseq) - emit_seq(fromseq) - if stepdir > 0; emit_brgt(break_tag); else; emit_brlt(break_tag); fin + emit_seq(gen_oprel(cat_seq(toseq, fromseq), stepdir > 0 ?? BRGT_CODE :: BRLT_CODE, break_tag)) emit_tag(tag_for) if type & LOCAL_TYPE if type & BYTE_TYPE; emit_dlb(addr); else; emit_dlw(addr); fin From 7ffe5a67673c6816a58458ec05c6679c9705d8dd Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Thu, 15 Mar 2018 11:24:35 -0700 Subject: [PATCH 040/147] Update images --- PLASMA-BLD2.PO | Bin 143360 -> 143360 bytes PLASMA-DEM2.PO | Bin 143360 -> 143360 bytes PLASMA-SOS2.PO | Bin 143360 -> 143360 bytes PLASMA-SYS2.PO | Bin 143360 -> 143360 bytes 4 files changed, 0 insertions(+), 0 deletions(-) diff --git a/PLASMA-BLD2.PO b/PLASMA-BLD2.PO index 26f70593374db6bf555d6855d58746002867d7d2..8162723659d8aa117038342d6e318849661b01b3 100644 GIT binary patch delta 9425 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 eGX_QbEGR@-P_$YbBz%w7FS&DM!~Y9a&@!n2 delta 9342 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

      jcYm;n_#@CM$;hxi2h@dXa! zI8NhtoX15NyYqa(+MTan-HmD{acAWEICMuoig7bs7=ck3gRz*5Y0&e}$0K+QORyYI zVI#I+E4E_?-oX3Vj{`W2WB4Aw!FQ2^=)uP=Za^DEAr=WJLO%?|aQp+~a37{)0T!YL z8dl;-tj7jy#ZJ75-Pnr{@EN}8!TKL1_#Som8GoT3#-4NnozWdba69hAI81~WGcXGa zun;v^j;F958?g=V;X@q2VI0HBo~-|Af;0FTzu`PC;4)-BI~BqZi5NJLh8%Q7KKh~* zWf+Vh7=|j0##r2gNq7)5pyF{~zVN@9Z}h*NALoBJKVE&0#1F6^M{o>3kmpQ(nEw*7 zxqxrVXjdTonFU6*GjSJmMK2Vi9|qxO@(e8qQ%4iujyrKTCXhav^aqK3Gdax0eAIAb zc|p9of_N3y;aSo)6@;kIao)zg?WFC%F1$tBJKWnx{1Ne|#0QBF;TxR5Dg1)-xQNT( zf79@{D-2O>g{*%h7xqHC>foHpxnm(yOWch(pSTzLqJ*@8h3(XG&Q7j}U^uF9D`|If zZ!G737AC3plI9_vQfT)-R%le0aJ`J{6@@1MszQVMB=OVKzoD>5__q?gL_#g+*U9)F z?8aWw_EEtJDmX>_W1-PsS7`8?dKuNgUcw*L%jj>{%i!-->!^_L%b+5Q{xf!j)hN1a zK~8x(p!*GO%b3ck+C`^K81ZnR+c+j;j>9H07P&1Gjc&`riHf(4bCRB3S#NM#Zc=Vv ztRE-o$(dvzVac_Gn5Kj>vk?3@`h;ug2F-J`OjEu#XlrhksXbq4s;I&&ZoN!3Pd8ms zs`0X><=r_~F58QYnQqIol~M`1-m!aX2fO5_Qa+(243i^dAN`b~tsN%2B%b0oKRPG+ zZ{cSfJ<4bp$S*h<`3y|&{9f(%Vf=>mxQG{PleG@RWwLofQ#^>cq*OSIgmtkn)Gra% z`k5lGzD(rQSBPQt&x;4^w}^T5eTBciw^&u5DYn(m64Niw5uaUND$*O4i;{+UVqyco zBh|h>Tq;I6S9@cm+$H~`O&cX0-9I<5ott^+kQTt#b)3epm=wsX7byI1-w@~j5SI~X ZiBo%6gukHnt5Gsl)>xI&XK$7J{|~ANCcppy diff --git a/PLASMA-DEM2.PO b/PLASMA-DEM2.PO index a0aa4a2ad9cc94275a9fb7f12d21c307d9e6d240..c0e4b40bbc0062eea5589b815458422825e00b15 100644 GIT binary patch delta 6931 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 delta 7012 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 CzadNj diff --git a/PLASMA-SOS2.PO b/PLASMA-SOS2.PO index db90822c518fd1dbf1d0c462b5d89e541e4cd834..282707a36d24c25e6264e65b248b1112727c8e50 100644 GIT binary patch delta 2717 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 diff --git a/PLASMA-SYS2.PO b/PLASMA-SYS2.PO index 5f51cf2e9d66ec678057d080ae6f33ad7aa2b252..e8a23130138cf48140d6faa05a6aeea82ab6827a 100644 GIT binary patch delta 10712 zcmZYF3!F^l|G@F*IWs#uyR*ibnY~}^T6VC+(q#+D{j$~?YY44e)3z-lNgKvNQn_?Y z98p5PmYHeP?xXYi+HXTBi@M?Q@m;B3$(~+GONp zxqR2RQTxbAZSt?>L=oGnutRt8&)<~{A;os}4*zNvUXYU-`qy%zNXYBjyLFE~eXehK zr4E}t_@B)ZMeVj7+XSw+p}dkW?BbmL#=R$stoEH+w=4Xo-IV~%=H1v#y24Exr{3^k z1~g8{y)*K^JIid>_Mbhe_bd`#@leK%&BCv;?E~%`D-%VnwjKWUZ?Ns7B0}W+=Pk-F zH?|FS&9rIv3DMbO7jKli=5&zZ9@gCWQqS$$#QueE3dfk*9{(MlA@w$&rdUNXY$D>buNMi}2nVVuVWDax-34NLVo$m2W_FVAv_D=R5@Mihi_-6Uu3O8K+TXMb_B4!K| z`K?3)VILx<=yh$JqR|l!E!=WVPMR(pTB#=dP4tc0$R!u9iawFOG%5OMy`rQe99}at zO6wIN9imhlvUsgl9<%NzS%18zEJ^nt@RX(K{v2;vn(kljEvu>fFM7*r>HYz}vO2nd zs;{h`?q3)7zn+nMt-YhF{aKG{-`-o6uKUMUZB<#dRhq9XOZPXsVcT)9*Qq&~>*WG^ zdxbU`2ax3xS{uy5Tj9#r({CM5ivu`|99p!;SS&{+E+UQA%`gB{u`Zlc{%EKL*Ig$( zjA@vSWn72rrOVhzyqWk6vARZof#CE{QZ&LzH!xDRn(N`rDTbu)-p60auSKzxY! zDCI{sX?#ZAmo{Og6vr1wZPA7riks>|6gM7f_7rOsu+kF6+5sdbw-E>`40n zk)04;zWE+|M-@bE+2rXEU$Rm!UZe--#s&Mw7X>?nk8R0_xEB3yOQ&i?CChcuHvcBU zy1+YiGN|b#g~--RMX*J}ivL~hBWY1GQ=id3KSwp1_fB@&zZ*@w)~I-~+D%o9FaK%b zW-t5yZjc>lpMSI3N5ic*#r(Ao)xsMt**ZFUT70l9G5^xl;DYdXTYr$#!pGko$ZOMW zC!)6`l`Yi+HH3e6IDLDZtQo#_``7js3BgU_j2)firf|uQWxh@Efd~=2toP~GtDE3o zo)#Pvu2uPxeN%jJVt8j|E4e=G+&Nly2#0nylKsQ4?zD(I>}p6nde>deJH!_+R7a|= z7R*z}Do~RzTK25k$)c_{q%e5W6Z~(BlBIgj(KHIK5C6QYS+}CZ990wiF|DwP79$V^VU0>hsCs>3VZ5-zkEQw1EECr)1qk4n=(6D-pamHE^1n zcM69qdm;ZyPVi!K`1{>0?qKx{QOtS$rFJz@93|rYYxE%hGM_5gvR3gly&&<%)oZV< z-c&wtk0IsU@RxfV@aow&UhW7#yDvp*;nn-v$u;3$_SLT5A|=pA1hraYrs;ibK`orM zf1JkqF4N3#~t7=Q;*iihwpMxzYlFaeYC6sBV~ z=3@btVhz^e4TlIB8wuXVJJ^Ow?8bh)kE8eyCvh5I;%j_|AMrDO#bwAydND-7jaVci z1?i}TI;f9EXc8F`#;pXmqZ#f(2jrmu-Ow9-F$hEO07@|&k7E+1UA>&rIewKPM5Kt1_yBr+oFV#6)lY0&>ZE_!n_nM4e1hw9nq+U4Aep$ zarPQS)PLFm__|Om)Cfacp;Wym5cMghTwH<#1_1Z9oU6^cn^ng z6vuHAr`XvUcJ>YNIsA&>@h7fAixGwsE>uSx(vgWe$i_{`i3xF~$9Ro9SZI#B&>HQL zhb|~Y58Q)+xDUfI5~J}r#v_b5co7R@gt?skt|fjA>+u#gV=H!G7Y>AYc^^k{93SHp zKF2rso*n(nj(#P+gg>EG<21mHSR^A2+}4a7+>Bh@SxuO&s(Fp}#0BVvAd1irgIOQC zp9Uo?497@}#^V?d15@z~W?~lRVm=n&Wh}=lSc}(i9+z;1ojctgqnexh31X3eWMm=> zx4Sw2EeSd!fV0~ti&3u!yBl;QG9~0 zaTe!!uixDvuW^|LS)HpJPE>;rNytP!G(;2JiWX>v_F$f11keM$a1ZXq0NjsJFfawv zF}u1jpRevU77;JO^1-~U#;e$h?O^U`?7@3Dgrhi#Z}9_u!UbHypU`w+M(NV@=v?VY zL@F}iM}u&`V~s*%h#tozOuT=z`_g#JcUCbaSuAZXWR1 z%p)GR`7z6H)g*KT(8YUW@}^`@IMz17XI*JiHtdX0l#VSeM~ME~h!p5qf{ zU7y{kPua*9XXg5BW^94K0={4KC=2M-u$#5z9b1Rx|s?+RXm38RkQ=cJpD% z(Xmc*0`a6+=2EnqK|3>68uN)45HE^NGnd5HFqX5t3a{Y}>MLS>#wN;oTVn0TyHr+U zFAm@^j^RU`z^C}E{GH>iG)C86*Q?QLbp3~(AR3jsKJIG|Klo|gsJgEw(I1`2UD4a|{2Iab>#jS0t8sh2Nc27AyRlck+Kk#H6<0*WC3dUUSaOT(HkjZ@KBYc6g_=CC6 z6)j0kpUo&+vXRNur4fp;6G!kVe!w4aFpIehOYl10!G0Xa8T^V=MrHNT1x0uek77au zU!>^_*Pe|?GUigwk4QGwvBJja$AuiUfEun9F^qe_;jS8n&1HEx%ArPEJ6U(iQQZ)X zD_qD$%Sd5%iF6x7iO1p@SXfB?j!4=vJm}|S#1tl2jMuOo`*0Ya;w$`!OOT8uoJc^L z8du;J4G-?gAaUYEa|D4g`4 zL}7Trg@h1O?i-ShiK0%sV8?cao&MQ&5npIVkN<7fJHj%eiNfE#pl$bd-TwY3uDmaz#LxdP4Jpo-%Zq!XD&CXQ=Jf36 zOK}vR@WnV2nQES`_&iExY85g@Uac>mtB|+LC#Chw9r6*IUYxk0sgzoUy}4{ELr;=# zc^We@4-2sbD^Y<>cn90C3wv=8hjAPq;}kx}*Z2-U;v9a(@Aw}sLvn9Yc}H?Ph6k~l zXlbMns3cEaG(mH;;|6x0W;aSGM{1h+h-Nd!P*2j)7!L!JS@)!trqXv6u`T2e(#;|B zI8^`efnHtgs&KWGZYeid$*p9L9Ab5DCG+gV(t?Am7h1_|`INP*mAu0?#6ECCYpH2g zL|Zw+daSLy$y(V~9+XF|$J)u7@?~p&JL#8CSlimkjy0OgA&%Rl`WLPg{?7WanEVbZ zVXF-cKB13xJ2k6*dpSq;w6?WpZc=2m?I34`2KiJU(XXnH$n>f{VsBL+ao(%?h)Z78 zM_l!)J|e=W`iS9is*fm-Q++3?Wa#M+XKRLXR^ojWO8+LA&>M}p2&+)p{u<~AOq&pD0naRJfv zF9~RbW_DqYvwIDTcs^EQ4|RvAJ4yT><21wqEivZ=pA5 zu;?Sno~v|OT@lQ+X7rMyWZ1IxmNngLyg7jwZUfnMvlD}BtR}r>16Qs$M`Xul*L70y zKyTSr+N`y`WwX#wZ<$B;m;1_mx_`X4EKc`N^Ohy({;*di-q(0l;$8YwB0bWl66t&q zNx#pjN}lggiT6OB@SoQI*~yQ(+Wd;HHczU`!>3o};j=ty^ZFjOd1H^t+pEn(dceg~ z8u8dwr+DisUvLhN))QazB_BXJ78TfrW3cfh&%$Ze{|II?S`zi?$U=QEanW*VQ;4A$ zk7)>F4J6lAB)CaLYjX(7vB&zkkIW5S5H?ejHZz(BM)%5SbBv5O%DFonpgcr*n!4|a zFLGD-6IZD#&|KyN7{T4(QSJg0DW_7-VLx zwApEM7<-8iLM8Q2lGG=mZ+wmKY*uEGEMRoM=#7Gk?M3oVS#i0qwE115<}$ z<(e#uDoQ5H+0y=^2#O6;=teF3RM}W=v2L3xGo^0zo+@ivc$GnS6HsV7O1BmJajXUQ=Y^re69(%@fCr3+V%r}vdpLCaP`Q`72#5! z@EJW`6jZpLmYH_s%6jNonIcbBOnX+&l`_}LnkD;K6KBam4re^y>Z{h-S@PBz19_kp z-ODcdPd18y8|A>!+F-4@tuR+T2gtKpg*jn)*72}xO_BVZe70iEb8?z?8`E%Y3}1j% zIE6eWSZ^bjuG2{ZJQ<~kCGkBBtMF5THQbUtL+UZ98mZ*rUOd79U&tfSrNryN2{1m! zH@JWlF1T7ekj%y%JgIEMMOQ#wPvW7(BQO@~4*nW;<7ZsLRj8Y@x-qM6GR@AEOFemN zfC3D_Q2N4AcE<0NPuf$>Id~CEs9VSSt=NveIDkWlpi6VZgGAIoChDRAZl-&?D78VS{qKNxOHc+liz2 z7?;6#-LNzFi*dvl@x(Qdg~k{~{RHNVlZZ*(n_-8?m_xZBMB^0%uQ;T!o|S*4>&;3> zvhg0vhoI8*pWrvBlzRiHjQU7CkG0r_^N3(>n2DQEND{h-GsfseT!cX=!B9NPy0PS^ zLlan-gsGSb3-hoD%di$|GP;2cHaWe<7UCV)g}u}rbfy|diBIATzQ^ydGxv*T&ZkEu z8u7%*$bcV>a4YMYMJ0xeRxGHQYG-tVnx*!|U>cON@krt^#N&x46F&_#Ayt#n7w{66 zv3^aI*H}lq5u30DD&tp@LYb8#2i;jc-mnxGo}F$AS}1Y=-eDrSL6r|~=%vhU^5USriAEUdwL zY@~7%Z@86sC-&eVKEP>whjX|@yQ|UGqx0p^u5ZU~JKWis8+Sw%&iLI2Di7>D+|HR? z6}?w^x3jb=+JA6+XJ>4JT7B%js)b=y3x_M)J6BajJ1X;?KP52c`&`y&P?emj?yV*^ zCtdsDz|KAUEBADL_wcUnqHjfw1#-4s4zk`@EbG{t3Abi_zF1!LB=}0E>pVT=HJIQN zqukbr;Q0?`v zcbNOvJFwRw!eOmlE(h5B1aT|mosmtGuI;h+3Yq4rb+z~=T~p7e9oFO(vaX{kKX$M? zto18oH#x_OTq%3kF7+{h3Xl%#n?Rt8QnF;t^o{nB!rw&|OMbelTTic)H*4n-t#?++ z5qZfXUX16r4W_=OmOjw_!nI)Jk{{IQs3{K@UqD~(!PU8M--M314~xN((@JrUq}a>W zxK*-i=n}WxKcT7HC!&#oI%tU7z!XLOctnja)Ne+r#ufc3Ri;eclGOlP%~sU!MhrZG zr=SMgCT2qoxL?FVEX696+qgxmfyWN)$6*}9hft|E^=krke!M!NP z2pBN25Nb-a1{HV<>ehZ3AL0Z)!0A^YNH_!h-?n^B(^O&;rdh9VZ`Gw0qTkCEU2ffYa%)S?-P6kk}}5U z_y!lDIvWoXkb=6n1x=xzl&Ytsolt;o2%iakW)#<3tCK4{hA_+B64>zL)+CybSyP^<%pt7LDF&ZlAIR#JQdeZYb z;<-I|Q5nyLSc})`Jl>3Qm|LP`RhDxPb^CD;hjEPc=g4^SJ2)c(F2o@bD%)8TwWGsZ zk0*pDbg^6O*UFS?O_L5BJF;i{k)sC#&KImt*2*T@%Sqgfb-7`kOxNWMD`TrnigMQA z7e)N7uV}qhW>v2!IVd+tS#0?a$=Vd156R{o%Tv|3bYNVmmR}?WYh>j!f(znC+k$av zLu~n-7)mynpaow}P_1rDUF{XcA|pG$NPOYFgjp^|D#su60d$C@tVwyM^0Gi6kj z*!R{WB&CWVlv2A=Em}%uDvfk@G$hEmC>Q%BZ_4li~DS?VaXNlLG2iN1e~ zagOwahX2aP3TNA_PQArHe|M6E6nl(E_*XOEqVxpszw)snrfbjac71Yk?jLxk7Kc6e z&|$HnMn>oM?)z;>?_>(IxNd&%?6IO|$1d$UWc}0bj+@V!%m81uo`QGE$$<_x8V?}aCr++;SjvX(8MEXMyQGC0BX^>^E zNqJU?ZZ@+hEw;?-B$Xnkub2NV$4FZ<<&^<)_S+rb+^`fzczw1%vsP$?(v;j&_*eW z^~JoMCKvlM-p=xlvhj=0JO5*oPKTs09+Ae}UoZurWKgK8I zkC8t^`Z?)E$}Zy@{D7bFJO02e2$Rr)5rznp&~2s!Es->dv?gVZ&=f7u4qd71PF)sp zA5$Hn^`qbkQ-VI$WY#87_yYM!CPjOdcna|}lS!LNI=gu1!j^LBB5S=_X5&h>RBMRK zjy;F>o;cfEbW~qcSE}EsHrsSth3#4U9Q#>&14mECBF8>oz4gB*_7r*IjS(UM)z!*gkf^$f?FH3Tm)TK}th$Cf3TmmYHys7FRo8Z3{HCO)ciRUC z+TXAl?X&C!RaMv2z){ES#!BZh^Ri z&$QzMTleUpYt;NDs%L(bCoj6cr@QaSj-;Tw(QiAtR3aL>N);KIbp>@@ch*X#q@NTb zRb3h`h6ztb%<7vJIg&<0XRB{?%uF}h={r-C9%?t^ZoB-Y#>oPW&ivEJdiPvs{%(`% z?wHxgI8)VKbtCVc>0YC1zJ9yLg%?J9X2xdzS>f5}JG1KtS?DV-%jJK{?sG{;;|f-& z?kd9dS*#I63DYF;eZ^F9wPKg}p~BV3m%QhyIU~kX=CkhYBFlXJ_O5i4MZ1H9=eC;D zt6wj{Ynkbp?z5FIHkUdQReJNx{^P4?F#9<=|lR^6lX zi;Q#n2UM-*GhZ?Dt*R-?G<;*mR@BQ<0d} zQ1YI-Uy_~~G4Aowb0)_9y!2Fybw4LP6Jp%YN>6!=`)TQkjCE&APybkVZ|OM}?d~o; z*Q4E?q~}OwcU$R6@;&!ao%Sy!Dj)K*GnsPM!ly48EHlDZkZ718c1 z!ZRwteNniYRpwnwE#j%9d%`RG&VJOoIn{57e6IQbYE%;WVItbKLG|#Ic~zdQF2^zHbk8^LCFG zN*)SPhGV#nj2NLzzzme*3?gHNQVsnv0yD7@pW$enP#VPx9z-b3;Kp>3byGTgY8-m z@_mtwC-DphV$4>0VF`UJhUjALiH~1dE;s$O*gz~Bo zj4(tX9@S9?_0SMa&>HQ~8QtMVZ}der28Rm$wNQ&bH8e^05icVyCG{Q*wP@#Q@FlL| zWEdlYa886CC=VC9#UeF_h0g^NP!$c)1kKS7gD?W)EJA<5V%A@_n6x*@&&Ogcr+mG| zuDwUR3GZXOh3mhQU@s2hC{Exs&f*JP#3fw8xA+OaaIzbm>?W}i!8?R7SYd+`@km59 z)ItL^Msu{nV`vxQ6?*3gyVi|N5A=cu{m>szV-N;oIL2T+G)%@+%)%V3z-qjQO%X!h z%6WGY@40rb>1#xRTH;u)>K1B*BF=)W;)e zhYsk1o|S~&n`8SC55P0X!w5W&anyS!(%?lh8YW{ZW?>F|Sb%r11k14&8?X^uuoWL- z7xo~?$`gfZ6?(kYrd1`b4i{=84UN$hU9DXIEP^MIiy<5|+-ldx5>Ld7@ZxpMz#Gsp z4-3JNP+NwTScCQ0gb%P2yRi=ka0S=!CqyJqG*akckzTtNNydR_#G@)|q7E9PCE6eZ zo!~}q^utrg#b6A@aE!u#FcDMW!+b2pDjsxQq+Kf}F2PpgBs)-s<2Z#gIERb4ge&+7 zw{Qni66nGNn2)!y7|XB{Yp@<0QGy-V zi;r*!M{o+~a2}U%6+hy4+=8(2U4#Xyjf)#iPz5zmi-}ZSo79^SH%BY9L3?zhE|WSB zaX&nPr?C}>sXJw>s()@X>lbV${cD?5|AGAfY)Seb2(eeyd)v+WK)a%k!vgY4?2-Bk zyVsmtrglMyf z=QyIY`5gB)7}aabum~`BSDa@3HPWfhP`!|NuG6H=r(F^4mN})ifp{Zvu`^LGaaPf` zlHZO!cw`?H2b>P=FzHdJSvx`Dr}!Kfa2Z$e9e%{m_|@s(*y#<)2T9s3TnI>bT%gr6@-DMqQ}td;h%GWX#r@UPynqa#5hddhvcm zc;KkwP8avci1!rZJc3!=1f|&VRdrL%BCmWgO3jZ_JymTl#;L6?_ZT9{1$$Im`rXpt z8r^-5f1M=Ld=tKY+n5g8ue5(UGP*z!E{~llg=>qgAXvC=*$YC2tAV2+T)3>xf(YTN z6jfjquD7E2O1KWi7TAR=Ij+DdTt}h`;)Uy4R6zn0(4_u6N`9PbJYK50^0hlj{gudQ z-{va~tKDM4W=!#{PN7ta63SaRf@?U$m@L^Ba@FU3lZn&?e2d>8nG2asae?`Fq$yrY zVV=|k&*L~Q;5+<*5GF)+^gs#r;uy~3Tiie}Ber^IiKj6FFJT%AgZR=dW;nMrC{9~T zx*;fD+f79jBcw!hKyT#Zd4_o}2V1p8#2c_3#t7^f&QbSUaHJN+I3x*~=o2FJ+z_kw z3bBqNtj8A0&xX*J;lr3vMpUZ_7+h%ka0VA)j4gh}EhvmJtcXS;($Eksz(8B;i7fQN zlNg9+!AM>kiT_|6CgNqhf+?7WIbQzF#anm>MOcB=SciAVu1NzS`ICulfa+Hhu2v4=rKFWcKXQscZMY*BS4;&06HE53NP| z7G00=x*l9o438DHI(RyF$m;UXu}k=7^9guh`IBb7-Cf*0vsmM~`*&v*3zT((9&T2% zea{|Udfsou^5Hs`53PSM9|qrjPQDg5?!ThI348-@+!`$^n6D#C<4^1)+cg}7cU|2P>sh0pK>zQWh|4nN{&{E8d6iQ5p|oXjv*Fe|}{ z7)7+vst{B|9W=pX=*-ekzGBvfla5sseS%`rUZ9-iOHIRMyiVP8CDHfeXPE!3wlY;t@$YRbo0qiXt&q9% zGUR_uMJdAnpA1>oR8&X!i!$U9`Kf}o6xE4iN6)Nxk&nwG*}wWFLTd;3c|N=;__n{|?f-eC@-!^jPE7&YxihjAj% zVf?lT%5pP zP$&;Ix(hhb2CVKVFJPy?OK17C_bo1iafyqt9GkHV`@yBvKaqCrH1T=dznni28<#PJ zcRUS^&=OB!1Qy{eSK@Oe&R84PuPX6cJbh3ieGqHDdJ26|N762)IIq@=z(c_((icqJ z+v$Y9#c!y9gAT`7ylaV0W^PhuyS9vY6}I3MWnWPC4KX_r+HLYdEF*-{_o$@N^gRiv z1{dm3-Zdyv^N{8Q^|EVE5J?iMMgx$MzHAwSeEYZ#YLqO#yBf3c5wj@)y){wUS#titx1X&*&$|$a(X!Wi{(Yd%8Pu1X}OAC9tNOh*Bgi?@~Ei+`W ze_gh0=^bS+u&J&RM}b3iY4(CB)iv8*5Tm;0*^M25jdo)PfK`81^ury-ihc`+u@CT8 zU={z6u>;`lDqI)Ue@^nFY8);D8wd%34T0)`4S^J!adwk}4Wn*6=_HfQ*ih1Ek`_`o7wfPMJ7Mf9954lI zhl!8lQ}P!~QoBlQjGTWo`EoY5{(l<{S*5%B%SYwPr=-jBr($$OUDXirz27of_E(Df zl;%yA^Q0^)nL_6)J^qTOzSy?$>%x#j5q??S2Be z7>rRcdec|oqs;;(QhS&5zlx}*eMsS6?8he*enI*bzQ+B{ziY(*!|(nX)8t4?yv2CQ zGt_7?pwu#5RyRABE)*k#tFpRH;ekV_MuWP3Wf z5~Hq)NS)+4^-tc)4dPzbUw@8locO(CT$a0?vF#u{i`kDzX*bj?`ljb)jPQ8AFP$_; z&X=;iKdw;bn3k?!G*Bp?33EnsQ>a+_i12@2D4SGyx8Kkr_ zWi@5V-qY7#-zVqFzW#EbY)2CMrktY`9Vzv{DQ78^?$!x@ae> z@-9p;QdZ+9VLN23KgTcodW{X|V-Q(K>{)JM>P zJ=UI-IQez*jwwZZeLxN_=!Ej8Z@10~$(58|4 z%nABZtieXgwo`uyM{pWv@da#jo$*LS4Wz=DTsB5CJVv+LEhtX!8x)~u2UXT`$>$Rn z1bO52*McI9S*JcT$g0hzu^$Vu1ncl$7<&t)9IzARv^z}Maa_a|gfZESfYD>e21jVs ziBr)4kAnRKeKwQSLgM+vOM`9N3epW;8kZ7m3zphmD(~$Z=qH2YwJ*qD#3fvVu`iGc zW0~Jr-k*$h*oBh_Vp1A|#&`^aSQ#H28lep(9)YoV5nfEA?hO{ry@h1vVgZ(5J>EkJ zKENIrGvJRo;Ap5_J3)LFpW^~$mqQb@Z;5}wO)#<0A`pkFOgL+X#cFkk>!S%;A_HBi zbBD!xwZ3F>FaUWNhS6YJtZN+nI`J%GAF(kTUJPRhA8dtml^nEX+k zz^C|(x-Y1^NPG##O!!;MehN#_ehp*g{5ru+3MDho5QIZTG_%qw%t}*;>!S%;qa%#j zu?IQG#l6|FHkSAWXqb*!n1^?;3e0%5cd>V%Ovqdz)a zet6&U4xz3<^hx>Sp%Vhpp(A^`g}P#l>QkQtGLr(CrP(@LU zzrk|(L~wm0PW8`TF85oq;*#jHj7{Th{(&oGqHWrpp>@=uwbZVeEuE97V? zP5z3Na!TTPN!$~7d0fM**ehOvOxQhnb% zTDZC!$?|IzM!A338ret*jq@*ABcJb{D56DCtazE9+46CsLB_?j?#z<#Bj^Gr|fK>|Z zOI*fpFmcNcMkFf3=nI--00vR;#$qB~gcq-1DrVp<7*o3K zM#X*{#i#fRS8)x$BZ%90ERvCiMre)p=!RYxh%xYDDs;RFWB++2?(aPt3!P=ykApC_ zo4qIbXY?7y-tzCLfQ7!n24gQd4hb;!l54=&OHM;WG=s5?+y?E@8QoxPBeQC%J&9*g zfN3zcj0<6G6>kJv!(QzI!8iB;zrffA4xwK#I;LdQMqRW(M{sKhZ1WmhyiZ^NoqpZsAnLlZlj0>|=VO5O3_eb` zkI7bbOA?F`Zf?{tC9}U6q_As{ Date: Thu, 15 Mar 2018 21:54:11 -0700 Subject: [PATCH 041/147] BREQ/BRNE optimizations --- src/toolsrc/codeopt.pla | 32 ++++++++++++++++++++++++++++++++ src/toolsrc/codeseq.plh | 2 ++ 2 files changed, 34 insertions(+) diff --git a/src/toolsrc/codeopt.pla b/src/toolsrc/codeopt.pla index e5ab340..aa56418 100644 --- a/src/toolsrc/codeopt.pla +++ b/src/toolsrc/codeopt.pla @@ -453,6 +453,38 @@ def crunch_seq(seq, pass) break wend break // LOGIC_NOT_CODE + is EQ_CODE + when nextop->opcode + is BRFALSE_CODE + op->opcode = BRNE_CODE + op->opgroup = RELATIVE_GROUP + op=>optag = nextop=>optag + freeops = 1 + break + is BRTRUE_CODE + op->opcode = BREQ_CODE + op->opgroup = RELATIVE_GROUP + op=>optag = nextop=>optag + freeops = 1 + break + wend + break // EQ_CODE + is NE_CODE + when nextop->opcode + is BRFALSE_CODE + op->opcode = BREQ_CODE + op->opgroup = RELATIVE_GROUP + op=>optag = nextop=>optag + freeops = 1 + break + is BRTRUE_CODE + op->opcode = BRNE_CODE + op->opgroup = RELATIVE_GROUP + op=>optag = nextop=>optag + freeops = 1 + break + wend + break // NE_CODE is SLB_CODE if nextop->opcode == LLB_CODE and op=>opoffset == nextop=>opoffset op->opcode = DLB_CODE diff --git a/src/toolsrc/codeseq.plh b/src/toolsrc/codeseq.plh index 605786f..9555920 100644 --- a/src/toolsrc/codeseq.plh +++ b/src/toolsrc/codeseq.plh @@ -82,6 +82,8 @@ const IDXAW_CODE = $BE // Relative address code group // const RELATIVE_GROUP = $05 +const BREQ_CODE = $22 +const BRNE_CODE = $24 const BRFALSE_CODE = $4C const BRTRUE_CODE = $4E const BRNCH_CODE = $50 From f9a007398faae3c6cf400e05dec00bfacdfc8fd1 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Fri, 16 Mar 2018 07:00:22 -0700 Subject: [PATCH 042/147] CASE checking and limit to 64 cases on self-hosted compiler --- src/toolsrc/codeopt.pla | 18 ++++++------------ src/toolsrc/ed.pla | 2 -- src/toolsrc/parse.c | 5 ++++- src/toolsrc/parse.pla | 12 ++++++++---- src/toolsrc/plasm.pla | 1 + 5 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/toolsrc/codeopt.pla b/src/toolsrc/codeopt.pla index 66a425d..385cd7f 100644 --- a/src/toolsrc/codeopt.pla +++ b/src/toolsrc/codeopt.pla @@ -283,8 +283,7 @@ def crunch_seq(seq, pass) if nextop=>opnext nextopnext = nextop=>opnext when nextopnext->opcode - is ADD_CODE - is INDEXB_CODE + is ADD_CODE // INDEXB_CODE op=>opoffset = op=>opoffset + nextop=>opval freeops = 2 break @@ -322,8 +321,7 @@ def crunch_seq(seq, pass) if nextop=>opnext nextopnext = nextop=>opnext when nextopnext->opcode - is ADD_CODE - is INDEXB_CODE + is ADD_CODE // INDEXB_CODE op=>opoffset = op=>opoffset + nextop=>opval freeops = 2 break @@ -361,8 +359,7 @@ def crunch_seq(seq, pass) break // GADDR_CODE is LLB_CODE when nextop->opcode - is ADD_CODE - is INDEXB_CODE + is ADD_CODE // INDEXB_CODE op->opcode = ADDLB_CODE freeops = 1 break @@ -377,8 +374,7 @@ def crunch_seq(seq, pass) break // LLB_CODE is LLW_CODE when nextop->opcode - is ADD_CODE - is INDEXB_CODE + is ADD_CODE // INDEXB_CODE op->opcode = ADDLW_CODE freeops = 1 break @@ -405,8 +401,7 @@ def crunch_seq(seq, pass) break // LLW_CODE is LAB_CODE when nextop->opcode - is ADD_CODE - is INDEXB_CODE + is ADD_CODE // INDEXB_CODE op->opcode = ADDAB_CODE freeops = 1 break @@ -421,8 +416,7 @@ def crunch_seq(seq, pass) break // LAB_CODE is LAW_CODE when nextop->opcode - is ADD_CODE - is INDEXB_CODE + is ADD_CODE // INDEXB_CODE op->opcode = ADDAW_CODE freeops = 1 break diff --git a/src/toolsrc/ed.pla b/src/toolsrc/ed.pla index 059ac59..5d470f2 100755 --- a/src/toolsrc/ed.pla +++ b/src/toolsrc/ed.pla @@ -623,8 +623,6 @@ def keyin3 key = keyctrlf; break is $80 | '\\' key = keydelete; break // Delete - is keyenter - key = keyctrlf; break // // Map OA+keypad // diff --git a/src/toolsrc/parse.c b/src/toolsrc/parse.c index 77bee1e..0543420 100755 --- a/src/toolsrc/parse.c +++ b/src/toolsrc/parse.c @@ -829,7 +829,7 @@ t_opseq *parse_set(t_opseq *codeseq) int parse_stmnt(void) { int tag_prevbrk, tag_prevcnt, tag_else, tag_endif, tag_while, tag_wend, tag_repeat, tag_for, tag_choice, tag_of; - int type, addr, step, cfnvals, prev_for, constsize, casecnt; + int type, addr, step, cfnvals, prev_for, constsize, casecnt, i; int *caseval, *casetag; long constval; char *idptr; @@ -1056,6 +1056,9 @@ int parse_stmnt(void) { constval = 0; parse_constexpr(&constval, &constsize); + for (i = 0; i < casecnt; i++) + if (caseval[i] == constval) + parse_error("Duplicate CASE"); tag_of = tag_new(BRANCH_TYPE); caseval[casecnt] = constval; casetag[casecnt] = tag_of; diff --git a/src/toolsrc/parse.pla b/src/toolsrc/parse.pla index 249850f..ac44f8f 100644 --- a/src/toolsrc/parse.pla +++ b/src/toolsrc/parse.pla @@ -598,10 +598,10 @@ def parse_set(codeseq) return codeseq end def parse_stmnt - byte type, elem_type, elem_size, i, cfnvals, prev_for + byte type, elem_type, elem_size, cfnvals, prev_for word seq, fromseq, toseq, tag_prevbrk, tag_prevcnt, tag_else, tag_endif, tag_while, tag_wend word tag_repeat, tag_for, tag_choice, tag_of, idptr, addr, stepdir - word caseconst, casecnt, caseval, casetag + word caseconst, casecnt, caseval, casetag, i if token <> END_TKN and token <> DONE_TKN and token <> OF_TKN and token <> DEFAULT_TKN prevstmnt = token @@ -794,8 +794,8 @@ def parse_stmnt tag_prevbrk = break_tag break_tag = new_tag(RELATIVE_FIXUP) tag_choice = new_tag(RELATIVE_FIXUP) - caseval = heapalloc(512) - casetag = heapalloc(512) + caseval = heapalloc(CASENUM) + casetag = heapalloc(CASENUM) casecnt = 0 seq, cfnvals = parse_expr(NULL) if !seq; exit_err(ERR_INVAL|ERR_STATE); fin @@ -809,7 +809,11 @@ def parse_stmnt while token <> ENDCASE_TKN when token is OF_TKN + if casecnt == CASENUM; exit_err(ERR_OVER|ERR_TABLE); fin caseconst, drop, drop = parse_constexpr + for i = 0 to casecnt-1 + if caseval=>[i] == caseconst; exit_err(ERR_DUP|ERR_STATE); fin + next tag_of = new_tag(RELATIVE_FIXUP) caseval=>[casecnt] = caseconst casetag=>[casecnt] = tag_of diff --git a/src/toolsrc/plasm.pla b/src/toolsrc/plasm.pla index f63106d..7854c0f 100644 --- a/src/toolsrc/plasm.pla +++ b/src/toolsrc/plasm.pla @@ -237,6 +237,7 @@ const FIXUPNUM = 2048 const MODDEPNUM = 8 const IDGLOBALSZ = 4096 const IDLOCALSZ = 512 +const CASENUM = 64 word fixup_cnt, tag_cnt = -1 word fixup_tag, fixup_addr word tag_addr, tag_type From d485654d0e03beb91ba59898db58dfac0f4118d3 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Fri, 16 Mar 2018 07:06:17 -0700 Subject: [PATCH 043/147] Update images --- PLASMA-BLD2.PO | Bin 143360 -> 143360 bytes PLASMA-SYS2.PO | Bin 143360 -> 143360 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/PLASMA-BLD2.PO b/PLASMA-BLD2.PO index 8162723659d8aa117038342d6e318849661b01b3..3f0b25457f2b6ca8e1677c560c6dc27f1bf4196b 100644 GIT binary patch delta 4287 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 Nygx;)`{h)%=igN6j;s5#jr*|L`)Av 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 B+5G?j diff --git a/PLASMA-SYS2.PO b/PLASMA-SYS2.PO index e8a23130138cf48140d6faa05a6aeea82ab6827a..baf66839dbcb4761378b62d1286c7dbc96ccc632 100644 GIT binary patch delta 2185 zcmXBTdr(wm9LDkAIlC&bu%*?lyN)J#j6u^P!~==8Pz_`J{azVGgDXKzc|6PC0m z)UES+iw1am#5a1iA%WRhQZyj1dybrz|4MvkZvHagaZ{fy(iIpbC2?QFmr1c>GD{{d z70X^IkwaoRM3Y!+h}~kXBkIH|CANv>64hdr5$naOBwiD11yLc^a-vi$Ma0B4g zbFZrWMv?ol6( zjMkzar?5HqmU-bDqkDTsx@k{T1a8qMBuMn{j7UJ{ZVi-2uillUU%fsn(McJRb{P~7 z^Mcl<=&8OpMlU+wH9w?{h!1bsp!qAZ=g5o+88S!8XDrm6O|9vP6B5~3SIrg=!mY4vRhv^H2{@hUk;z(9;cKBoFaJ>v7KM|~c9KKo*n;3dvi`V4y&y%Ov3 z2CA_YI}rCt%x<7G;zN9dgE)*9wBZ=OV%TwpouvPa^SFRZ_!FJzf+UOWMG{P;BLkVp z#=vAz*CiYFP@HKQ-JAs40G`m=3^nAMGQ+(ikDH2m8ir< zRO2md!*;ab3w)2$IOi92f!F$-ei>KL<>&j?Q^ihzAL;0a91MnqVHk-#jK)}u$GwPP z5~iR4PvRLAqXf%SMZJ=0*sJMlQH9NT6T7e{#Fx-sWFc$Y99}nPR#AdS0LlG9C7>iMYQoM|Etb~KL*o>`s z2Rl)ZJ!ryy97ZcX$9MPvr*R$~_ybp<1^NH?2=Xq1q5?rp^`d7W6FC@!Yq`6DyHWH! z+=?-%LLGN|f|+Vx(5nsvJ*qkASD&%}I+&$S;8*%c!>jHzbTt((7@2CBk*dlJkJ@M$ z_Qys{)Je)EL+rl{QGG*RJ1Zn=KqyUJAM&W&kjK86{llEkB%5oAD-U(SW^Z!hU=lV`;?~3_KCav^(it5R<-pSF&jrhTUF08MA1RA@HXo0VoR(3N zUn;hmB%z~XM~Ql|%ZXiLR}x#rE+ICF?GUwhcdNvn#qJZa7ZDX=&nC3kr3Aw?F+=PR zh^cpnO};y9oY*rt94+>AVuaWQi^-S7t|0OyG+2VOWU{kJ3Z2cpLd^_}aB5+2?@bWSoeQ{G?cv#Y~bQ?tUiqKyZJ z8U14S*H;-vMRfncZmc&B7I)Z_9u~=8EpHfO=lQ}dEk@@Ug=N0bAqkrq(fNl47`4$8 zhdTRmQbI%T92L&-4RzhQYSl2+xD_pF$ZrvsCIx1{=$VFS|LtwX?9@)oTgXfiGY5s( z25);YhoeQRn02@c{?x4PBxXgrn0sJm#A1zyU6Ea_M0JT5)f?G}#fxr^HDhQ9AtI_j zB@YAf4DvAq!!Q!BV>~8e3W`vSC>Em%)eNp-@LKu?)ZrU!!w&4hel+4Jns5@QA}nX| zGcMr@gZ^aD4SF+f!%XC3fEO0pAr+mGg@@1wk0*-GO$?|!`m=ZrVHDsMjN*PY_haef zF%gj|EJY}W!Ys_jJS;#3mSPz`Lk+&fT5P~|G~-`}$9erK(JRUa3$4)(>F9#K=!d5f z!V6xB=waS~dX3F!jK$lSjQ21V5zIs>=0am3%2A1Ge1Tf5$0lq+6Mn?6xQ6Rq(Kq>D z|Im#j9&W@X@%blGf@q6$+>ajUg-4KsT;yR8LKuP)`XUDd zFcAELspnCEkr;!>IF>>bVFpU@5z3&k5ap=EGOWNFY{X`KgKgN2dNkk|PT&We$7Ni@ z4K(9lxc#CM{Cxidlw`l?6u+S}=v`r>2YTXR?jGZ=KRpjm;ThCmD|fs79rZ!KTQ~Y$ z`ncb#Pq9DePtzCi7dM7e^Z?+d!s z1LT9jWZfs|(%C_m8o+)G=i|tCf^Iz}*iseIi-XCkB*?pkInXFa6{@ikpJNTyp$dvOqr_zoxVJ$}F$ Y{A87XTVQmL9X;8_oPKK6DdYM70AGfAw*UYD From d1655092931cd422984fd11eb44bb6aedbfc3023 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Fri, 16 Mar 2018 07:39:42 -0700 Subject: [PATCH 044/147] Allow CONST/PREDEF before IMPORT --- src/toolsrc/parse.c | 11 ++++++++++- src/toolsrc/parse.pla | 4 ++++ src/toolsrc/plasm.pla | 1 + 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/toolsrc/parse.c b/src/toolsrc/parse.c index 0543420..2bba2a3 100755 --- a/src/toolsrc/parse.c +++ b/src/toolsrc/parse.c @@ -6,6 +6,8 @@ #define RVALUE 1 #define MAX_LAMBDA 64 +int parse_mods(void); + int infunc = 0, break_tag = 0, cont_tag = 0, stack_loop = 0, infor = 0; long infuncvals = 0; t_token prevstmnt; @@ -1329,7 +1331,7 @@ int parse_struc(void) int parse_vars(int type) { long value; - int idlen, size, cfnparms; + int idlen, size, cfnparms, emit = 0; long cfnvals; char *idstr; @@ -1392,6 +1394,7 @@ int parse_vars(int type) if (type & WORD_TYPE) cfnvals *= 2; do parse_var(type, cfnvals); while (scantoken == COMMA_TOKEN); + emit = type == GLOBAL_TYPE; break; case PREDEF_TOKEN: /* @@ -1432,6 +1435,12 @@ int parse_vars(int type) else parse_error("Bad function pre-declaration"); } while (scantoken == COMMA_TOKEN); + break; + case IMPORT_TOKEN: + if (emit || type != GLOBAL_TYPE) + parse_error("IMPORT after emitting data"); + parse_mods(); + break; case EOL_TOKEN: break; default: diff --git a/src/toolsrc/parse.pla b/src/toolsrc/parse.pla index ac44f8f..521d864 100644 --- a/src/toolsrc/parse.pla +++ b/src/toolsrc/parse.pla @@ -1124,6 +1124,10 @@ def parse_vars(type) fin until token <> COMMA_TKN break + is IMPORT_TKN + if codeptr <> codebuff or type <> GLOBAL_TYPE; exit_err(ERR_INVAL|ERR_INIT); fin + parse_mods + break is EOL_TKN break otherwise diff --git a/src/toolsrc/plasm.pla b/src/toolsrc/plasm.pla index 7854c0f..381afaa 100644 --- a/src/toolsrc/plasm.pla +++ b/src/toolsrc/plasm.pla @@ -251,6 +251,7 @@ word codebuff, codeptr, entrypoint word modsysflags byte[16] moddep_tbl[MODDEPNUM] byte moddep_cnt, def_cnt = 1 +predef parse_mods predef emit_pending_seq#0 // // Module relocation base address From 4af5c37dea957039d7614da8f1b50afe55834cdb Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Fri, 16 Mar 2018 07:41:17 -0700 Subject: [PATCH 045/147] Update images --- PLASMA-BLD2.PO | Bin 143360 -> 143360 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/PLASMA-BLD2.PO b/PLASMA-BLD2.PO index 3f0b25457f2b6ca8e1677c560c6dc27f1bf4196b..4f218de4b9e9eade3e9feda2d4e74f5a8e656994 100644 GIT binary patch delta 1331 zcmY+?e`wTo9LMqZ=X>9CCyT|oMw_+GxjBFA#L<=WuKRv(sbh1PUU|~MBB5!+VTK|N zM}F_4V1<+Io3zWa$zUzR{89Vka%w?J35KhsYb4gu43ZnzF38fn^(6YIFFZc)*ZckX z!1v4d`%R>MiL~$3m)^SPHpt6W)p?aNA^!$L=C4@0vSDp3F8^J*4<%3b=l}oM&^@nb zGT(_Bn?(L7Y?bea^0S%wDw4WgqN@Drc=F*IRie%$m)59oUP8sQ4Y6IxS87y`x|#F^ z)RBf&vSr-AWz4_)gejY4wNC=3FTVMK_*7GEY_Y@^$;_lYol8htu2+ua`lLUn zB()=`wkdB{vly{d=27*0k#lsJ=wlehIb?AM-jHY?@=*XkicyYvs6`NUsK+X-4vE_u zGIbl7`{|dk6CFt40DABi-p1jOIC_9^5})D>&f_aw!exx&I&R=sWN-^v+<`aD17a46 zQHBaEK^-E9q5(}&v70j%tv{MtK@O~gr6-(++VCheUr^eHg7S^;xGKoY?{3pw&=b#(E_W~4roK%7E&Wy7>yFzVeU1DhH<+MisJ~Hv zr{3n=JxG)vH7f3mXt`T4Cu-_Sn(CX-HLR9LMqhbMCdS*viEm8%-m%1USz72=<8&a(OcP0O14T?2b^!RRbJOhHKk*G=`?3qw%Vy~I=&orc+gNO9V|Xa zesF7~*4-nG?jdP%wY+lINt=66#=bY?VYDqrt@Nn7&b)w1RaMaq0hMK_fOBTJ`n7xU zmtvHS5MzE&jFhM|LRG8yyMC0JjV;P<6m^*J>r6*d%=$+ zq+=*@f?^j0y}FQGgo&7nGE`y#7UD-N$7hj0`pP=|Un;S#Rm79Qg{ zI?xFhMu@9|58coce)K_Kq+%ex#z>4tWDKtY6k`&~FdZ}T9papj4hQ@3 z6V8Rieh~874@0T;qfkHnnC=H<`ECyKQp+Eo}UO zKPmra^C|fsavS+S@@u?>SfV}X4nLC67wMMRS(aaaMIK4cx6 Date: Fri, 16 Mar 2018 09:57:01 -0700 Subject: [PATCH 046/147] opcode statistics --- src/opstat | 82 +++++++++++++++++++++++++++++++++++++++++++ src/toolsrc/codegen.c | 16 ++++----- 2 files changed, 90 insertions(+), 8 deletions(-) create mode 100755 src/opstat diff --git a/src/opstat b/src/opstat new file mode 100755 index 0000000..38ae4bf --- /dev/null +++ b/src/opstat @@ -0,0 +1,82 @@ +echo -n "CN "; grep -c '; CN' $1 +echo -n "MINUS1 "; grep -c '; MINUS' $1 +echo -n "BREQ "; grep -c '; BREQ' $1 +echo -n "BRNE "; grep -c '; BRNE' $1 +echo -n "LA "; grep -c '; LA' $1 +echo -n "LLA "; grep -c '; LLA' $1 +echo -n "CB "; grep -c '; CB' $1 +echo -n "CW "; grep -c '; CW' $1 +echo -n "CS "; grep -c '; CS' $1 +echo -n "DROP "; grep -c '; DROP ' $1 +echo -n "DROP2 "; grep -c '; DROP2' $1 +echo -n "DUP "; grep -c '; DUP' $1 +echo -n "DIVMOD "; grep -c '; DIVMOD' $1 +echo -n "ADDI "; grep -c '; ADDI' $1 +echo -n "SUBI "; grep -c '; SUBI' $1 +echo -n "ANDI "; grep -c '; ANDI' $1 +echo -n "ORI "; grep -c '; ORI' $1 +echo -n "ISEQ "; grep -c '; ISEQ' $1 +echo -n "ISNE "; grep -c '; ISNE' $1 +echo -n "ISGT "; grep -c '; ISGT' $1 +echo -n "ISLT "; grep -c '; ISLT' $1 +echo -n "ISGE "; grep -c '; ISGE' $1 +echo -n "ISLE "; grep -c '; ISLE' $1 +echo -n "BRFLS "; grep -c '; BRFLS' $1 +echo -n "BRTRU "; grep -c '; BRTRU' $1 +echo -n "BRNCH "; grep -c '; BRNCH' $1 +echo -n "SEL "; grep -c '; SEL' $1 +echo -n "CALL "; grep -c '; CALL' $1 +echo -n "ICAL "; grep -c '; ICAL' $1 +echo -n "ENTER "; grep -c '; ENTER' $1 +echo -n "LEAVE "; grep -c '; LEAVE' $1 +echo -n "RET "; grep -c '; RET' $1 +echo -n "CFFB "; grep -c '; CFFB' $1 +echo -n "LB "; grep -c '; LB' $1 +echo -n "LW "; grep -c '; LW' $1 +echo -n "LLB "; grep -c '; LLB' $1 +echo -n "LLW "; grep -c '; LLW' $1 +echo -n "LAB "; grep -c '; LAB' $1 +echo -n "LAW "; grep -c '; LAW' $1 +echo -n "DLB "; grep -c '; DLB' $1 +echo -n "DLW "; grep -c '; DLW' $1 +echo -n "SB "; grep -c '; SB' $1 +echo -n "SW "; grep -c '; SW' $1 +echo -n "SLB "; grep -c '; SLB' $1 +echo -n "SLW "; grep -c '; SLW' $1 +echo -n "SAB "; grep -c '; SAB' $1 +echo -n "SAW "; grep -c '; SAW' $1 +echo -n "DAB "; grep -c '; DAB' $1 +echo -n "DAW "; grep -c '; DAW' $1 +echo -n "NOT "; grep -c '; NOT' $1 +echo -n "ADD "; grep -c '; ADD ' $1 +echo -n "SUB "; grep -c '; SUB ' $1 +echo -n "MUL "; grep -c '; MUL' $1 +echo -n "DIV "; grep -c '; DIV' $1 +echo -n "MOD "; grep -c '; MOD' $1 +echo -n "INCR "; grep -c '; INCR' $1 +echo -n "DECR "; grep -c '; DECR' $1 +echo -n "NEG "; grep -c '; NEG' $1 +echo -n "COMP "; grep -c '; COMP' $1 +echo -n "AND "; grep -c '; AND ' $1 +echo -n "OR "; grep -c '; OR' $1 +echo -n "XOR "; grep -c '; XOR' $1 +echo -n "SHL "; grep -c '; SHL' $1 +echo -n "SHR "; grep -c '; SHR' $1 +echo -n "IDXW "; grep -c '; IDXW' $1 +echo -n "BRGT "; grep -c '; BRGT' $1 +echo -n "BRLT "; grep -c '; BRLT' $1 +echo -n "INCBRLE "; grep -c '; INCBRLE' $1 +echo -n "ADDBRLE "; grep -c '; ADDBRLE' $1 +echo -n "DECBRGE "; grep -c '; DECBRGE' $1 +echo -n "SUBBRGE "; grep -c '; SUBBRGE' $1 +echo -n "BRAND "; grep -c '; BRAND' $1 +echo -n "BROR "; grep -c '; BROR' $1 +echo -n "ADDLB "; grep -c '; ADDLB' $1 +echo -n "ADDLW "; grep -c '; ADDLW' $1 +echo -n "ADDAB "; grep -c '; ADDAB' $1 +echo -n "ADDAW "; grep -c '; ADDAW' $1 +echo -n "IDXLB "; grep -c '; IDXLB' $1 +echo -n "IDXLW "; grep -c '; IDXLW' $1 +echo -n "IDXAB "; grep -c '; IDXAB' $1 +echo -n "IDXAW "; grep -c '; IDXAW' $1 + diff --git a/src/toolsrc/codegen.c b/src/toolsrc/codegen.c index 7c24b4e..9e2f6a5 100755 --- a/src/toolsrc/codegen.c +++ b/src/toolsrc/codegen.c @@ -926,7 +926,7 @@ void emit_incbrle(int tag) void emit_addbrle(int tag) { emit_pending_seq(); - printf("\t%s\t$A6\t\t\t; BRLE\t_B%03d\n", DB, tag); + printf("\t%s\t$A6\t\t\t; ADDBRLE\t_B%03d\n", DB, tag); printf("\t%s\t_B%03d-*\n", DW, tag); } void emit_decbrge(int tag) @@ -938,7 +938,7 @@ void emit_decbrge(int tag) void emit_subbrge(int tag) { emit_pending_seq(); - printf("\t%s\t$AA\t\t\t; BRGE\t_B%03d\n", DB, tag); + printf("\t%s\t$AA\t\t\t; SUBBRGE\t_B%03d\n", DB, tag); printf("\t%s\t_B%03d-*\n", DW, tag); } void emit_call(int tag, int type) @@ -987,12 +987,12 @@ void emit_start(void) void emit_drop(void) { emit_pending_seq(); - printf("\t%s\t$30\t\t\t; DROP\n", DB); + printf("\t%s\t$30\t\t\t; DROP \n", DB); } void emit_drop2(void) { emit_pending_seq(); - printf("\t%s\t$32\t\t\t; DUP\n", DB); + printf("\t%s\t$32\t\t\t; DROP2\n", DB); } void emit_dup(void) { @@ -1046,10 +1046,10 @@ int emit_op(t_token op) printf("\t%s\t$8A\t\t\t; MOD\n", DB); break; case ADD_TOKEN: - printf("\t%s\t$82\t\t\t; ADD\n", DB); + printf("\t%s\t$82\t\t\t; ADD \n", DB); break; case SUB_TOKEN: - printf("\t%s\t$84\t\t\t; SUB\n", DB); + printf("\t%s\t$84\t\t\t; SUB \n", DB); break; case SHL_TOKEN: printf("\t%s\t$9A\t\t\t; SHL\n", DB); @@ -1058,10 +1058,10 @@ int emit_op(t_token op) printf("\t%s\t$9C\t\t\t; SHR\n", DB); break; case AND_TOKEN: - printf("\t%s\t$94\t\t\t; AND\n", DB); + printf("\t%s\t$94\t\t\t; AND \n", DB); break; case OR_TOKEN: - printf("\t%s\t$96\t\t\t; IOR\n", DB); + printf("\t%s\t$96\t\t\t; OR \n", DB); break; case EOR_TOKEN: printf("\t%s\t$98\t\t\t; XOR\n", DB); From ec0fdde7477575e117294de16cf5fa2612d50448 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Fri, 16 Mar 2018 14:52:27 -0700 Subject: [PATCH 047/147] Order caseblock values in ascending order --- src/toolsrc/parse.c | 25 +++++++++++++++++-------- src/toolsrc/parse.pla | 17 ++++++++++++----- 2 files changed, 29 insertions(+), 13 deletions(-) diff --git a/src/toolsrc/parse.c b/src/toolsrc/parse.c index 2bba2a3..6f2aa02 100755 --- a/src/toolsrc/parse.c +++ b/src/toolsrc/parse.c @@ -761,7 +761,7 @@ t_opseq *parse_expr(t_opseq *codeseq, int *stackdepth) if (stackdepth1 != *stackdepth) parse_error("Inconsistent AND value counts"); codeseq = gen_codetag(codeseq, tag_or); - } + } else if (scantoken == TERNARY_TOKEN) { int tag_else, tag_endtri; @@ -1056,14 +1056,23 @@ int parse_stmnt(void) { if (scantoken == OF_TOKEN) { + tag_of = tag_new(BRANCH_TYPE); constval = 0; parse_constexpr(&constval, &constsize); - for (i = 0; i < casecnt; i++) - if (caseval[i] == constval) - parse_error("Duplicate CASE"); - tag_of = tag_new(BRANCH_TYPE); - caseval[casecnt] = constval; - casetag[casecnt] = tag_of; + i = casecnt; + while ((i > 0) && (caseval[i-1] > constval)) + { + // + // Move larger case consts up + // + caseval[i] = caseval[i-1]; + casetag[i] = casetag[i-1]; + i--; + } + if (casecnt && (caseval[i] == constval)) + parse_error("Duplicate CASE"); + caseval[i] = constval; + casetag[i] = tag_of; casecnt++; emit_codetag(tag_of); while (parse_stmnt()) next_line(); @@ -1124,7 +1133,7 @@ int parse_stmnt(void) if (infunc) { int i; - + i = stack_loop; while (i >= 2) { diff --git a/src/toolsrc/parse.pla b/src/toolsrc/parse.pla index 521d864..37c653d 100644 --- a/src/toolsrc/parse.pla +++ b/src/toolsrc/parse.pla @@ -811,12 +811,19 @@ def parse_stmnt is OF_TKN if casecnt == CASENUM; exit_err(ERR_OVER|ERR_TABLE); fin caseconst, drop, drop = parse_constexpr - for i = 0 to casecnt-1 - if caseval=>[i] == caseconst; exit_err(ERR_DUP|ERR_STATE); fin - next tag_of = new_tag(RELATIVE_FIXUP) - caseval=>[casecnt] = caseconst - casetag=>[casecnt] = tag_of + i = casecnt + while i > 0 and caseval=>[i-1] > caseconst + // + // Move larger case consts up + // + caseval=>[i] = caseval=>[i-1] + casetag=>[i] = casetag=>[i-1] + i-- + loop + if casecnt and caseval=>[i] == caseconst; exit_err(ERR_DUP|ERR_STATE); fin + caseval=>[i] = caseconst + casetag=>[i] = tag_of casecnt++ emit_tag(tag_of) while parse_stmnt From 010750efed4a30ea81670d077af42c187c321d13 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Fri, 16 Mar 2018 15:14:58 -0700 Subject: [PATCH 048/147] Early exit caseblock if value less than ordered list --- src/vmsrc/apple/plvm802.s | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/vmsrc/apple/plvm802.s b/src/vmsrc/apple/plvm802.s index 9351938..517f194 100644 --- a/src/vmsrc/apple/plvm802.s +++ b/src/vmsrc/apple/plvm802.s @@ -1380,8 +1380,10 @@ SEL TYA ; FLATTEN IP PLA INC IP CASELP CMP (IP),Y - BEQ ++ - INY + BEQ + + BVS ++ + BMI CASEEND ; CASE VALS IN ASCENDING ORDER, EXIT WHEN LESS +- INY INY INY DEX @@ -1392,14 +1394,21 @@ CASELP CMP (IP),Y INC IPH +ACCMEM16 ; 16 BIT A/M BRA CASELP ++ INY + BRA BRNCH +++ BPL - +CASEEND TXA ; SKIP REMAINING CASES + ASL + ASL + CLC + ADC IP + STA IP FIXNEXT TYA LDY #$00 SEC ADC IP STA IP JMP FETCHOP -++ INY - BRA BRNCH BRAND LDA TOS,S BEQ BRNCH PLA ; DROP LEFT HALF OF AND From 423ca66fc01faac70858376a050bd400a892ef8c Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Fri, 16 Mar 2018 16:36:39 -0700 Subject: [PATCH 049/147] No need for SANDBOX anymore. Tests for codeblock on 65802 --- SANDBOX.PO | Bin 143360 -> 0 bytes src/vmsrc/apple/plvm802.s | 4 +--- 2 files changed, 1 insertion(+), 3 deletions(-) delete mode 100755 SANDBOX.PO diff --git a/SANDBOX.PO b/SANDBOX.PO deleted file mode 100755 index 30f66ef9c74c1cec3f82c8dc5018d490937a244f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 143360 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 OIli1O{wj Date: Fri, 16 Mar 2018 16:57:42 -0700 Subject: [PATCH 050/147] Fix check for duplicate CASE and updates images --- PLASMA-BLD2.PO | Bin 143360 -> 143360 bytes PLASMA-DEM2.PO | Bin 143360 -> 143360 bytes PLASMA-SOS2.PO | Bin 143360 -> 143360 bytes PLASMA-SYS2.PO | Bin 143360 -> 143360 bytes src/toolsrc/parse.c | 2 +- src/toolsrc/parse.pla | 2 +- 6 files changed, 2 insertions(+), 2 deletions(-) diff --git a/PLASMA-BLD2.PO b/PLASMA-BLD2.PO index 4f218de4b9e9eade3e9feda2d4e74f5a8e656994..2df2119062919f5de134440e63eeaa4ffed9e6b3 100644 GIT binary patch delta 4156 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 delta 4125 zcmZwJ3s{s@8o=@Q41-{pAtWHKSCBhOqN2q8B4Au5n7p7pnJKHenpv6Uv%x5f*Ma=H@j?U7p<+-Vb1=s^)~E0&+q%*Ip2BDIq&(tdFCrS z>sfZzb9=h+&c}j%y@KSNNPAFeG6oKLEZFaQi=UT4BF&ja=G>gLfu`J4;bTk^H*q&y z>whz``dZ>GLy=f$%1=+tO}~+tDZWw>enV35%Cf{e@plexX<_K)** z@sOonw|A>-bMNCisefKU{>{}h>Bpj^vvQf#)TzU2dt_(k<`&#cH6AB%*dMp%maXoX z7@0M4Y({3@ja1_a%8YU?^TPj0%*ZNizrWY#G#W`-4*1 z*DuKBHkkZe3iFa4BXiO+3z;PQkF7L%Q`qVbg>_7fFy)TUD>eph6~cPXs$VgC+`4=YN|&%C*IF$PK(x!B!hj~Y5Ah8Jaw zOl{xV>s5!c_(xps%FZ_bKJm9dL0%GAl%G+QdH;=6<3Ls);JSKKVTZK_q!wls-ALon z8$x1ihmG!-7&_AQz%6-Vj1zbH-ovHH3x$D0Z~KLLNzYLQk)n>^L~ z$#t?!H^@r8K`M24E>gX@y+XhLLGg0!K(Nf`zl!MMB`N^3egLJ$s*2%I}i!|wb!{%W^kJGanvGhJ)xR>!b!vX$FO zYqnhpP>vx9Idi-vBBaDy%=ZM%@hkCMKF8A(CmzS;vhyRE#c+SoE%H~rnW1+vK>Paa z5rJ&L-6v$DvsL``XX2x`aTgk8wYHD@le*}p_S*03tA;2w%U0G;9aOcp-2Q5x;f%Z8 zCrFJps71DE1JsiHj>yzzpTf7KBs3x=*i)jsQ_LlIo5#k+#LO8`61rU0`^(JelJLgp zNhJf?uPbk^*M6^!<}QA7dX)^|Qt0fGUL}!@p|&SN)RTcrB}-RGjW);+Ix4KaHxooG z3y#!w6{?ce*aedO`(l}Oxl)E-SuU5aERnpnDmmqRQ5?>7;!WaF{WodRbNr{E}gdjZ*I= zT+EI!MT;pyI@_esSte7RYvdJYwbVE*a@09rK6Sn%A^K%`pNT)$QhZ0>;yc<`{Bm%z z*iwU3cUxw(>ZW|`W1`h6gYvO`H%RU1b1^&rcWvq<=B9x$V)n_(|4o}$2mG(WTw!mF zQ4t1ZvVApJ9q)EATMT(U#V|Hj4AV!5A;JDhta?Os`z1qIt{8l>#85Fx3?_TZP*v|! z8a!Amk;ue-D8P73#x%^t(P%3~o0?-dp7=(D_<3UWs<9G%Y zScUbd$J_X@l*4J9!wCdc1}Ya2TKAEWU*U z8h6BrV`v@k17rLSw0?-Eo5QA96 zA!P*jKZhW9gjgq!Fj}S(^Q*DU#8a4yGAzSNtj1crgjzJ z@gpwb3f$vaU?~S51fVziVG!bwfMjGM8xLSCCZIiU0T!YXFJdEh;BD-~0USmPj^hN* z;vCN7ca&b`Aouc{ga__IAbO!6!V!g`7>*Q-#dJJ{6{toHHew6jKqK~G9}eI!nsEwe z@g*+Y%l+qt!Qu%Y1fVziV*tVsg+YkLFvKGf>9`+ejKM@q#th8HTs(*QSd67ufmK+8 zb*N3?{%I$FV7hSYmhU2;wwkVH9ms z6OESX#E)S%=AjG=un5cOV@>RCSw~!5%Ap1uP|t-1F4&3R!MkX}VcMHn#4+MloWU2g zeU<2I`IhqquKh^cC0vGsHqEt8Nn+`oB-SoTz7}6%e*~g0f)I_;SPpTBM+%)s(K(;k zOguiRk7Xj~M>zkPwi(1v5YHu^hv#6SZDCSZ%k!Ko_`U*_Sc59sYPeR*c~eq<%U0U9 z6YoswV?CH;v>Zy3V#^U4jwQKUTa(-@Cx}lo!8y+7Ise4@XU@No*ak`FK}{BGr{q4? zzR5;Q5OGMd(HfrYW=-XL2H&&zK8o-2>~H0(Y*p!P7`n!!7W+oY8#;`C-pR5@mq?=y zk&o>!npC)Z%0j7fE|x9MC9>z*e{{Kg;jEHh_^~JM8~T#-my)dacq%tN1Ci~ zq)3$`O13%X%RFbf9C5xNp-hp^`^QYZn71zbJ7ZLi@}0;l$Rznd&ys)gQhHR6mJ_ys zajM>HKCgJyypu#pqwUZ*Wxut-zOqSw9OK4XHaZ22#$rw8f) diff --git a/PLASMA-DEM2.PO b/PLASMA-DEM2.PO index c0e4b40bbc0062eea5589b815458422825e00b15..21c38ce06f1ed40dab1ca485601e1795b53e64b9 100644 GIT binary patch delta 950 zcmZvaPiPZC7{%YL35g9&QsW^W}8HV9t1rU|A2Zac!*FG zH0aGe6jXvY6+ub@=3wc?LqSoYh4va64B-u2{*1gQ|&HTRizBfBxvCmiR zi<6fAyZ#gIVN`*}MpG@`<2@A#YtuA?uFn+)0i@>r4p?Y{k#?(yTY@K*RJu5@(*nFh z1lV;=+u8}P%c`27;ceEX{7-S*>g_dOx@!Gsw=~BXat@2LmW;cx(Nw25(o?bFfSQmm zrRhvthaDC&ag#q=iAdK-iMS7jjMmXk>*gq$8f|3OHIok`XXH#aHI<=CI^Jl{j>3Xv zt7-H?wBxCH$^DJm-l2R0_aB@^fqo;;)&8w?nhW_MVc^*Vbjg$0r)#p~6*jvzMq z2)^-SSk-E|&psKed=eix74-zx`LtNmc+WE^@+(*_ZQQ4QhEBetW2Bll=_oCoCxf>Q zq~1Y{wCbj`atI{oMVc6EzXL2!u?ypkKddWMtxz|mmBW!#^6Uk=&4IndZj@cUV6K(c z-(Rsqeys5TzVjfy@KLPr5I*sfc*mo7&0`C;3G&sI#3P=IA8g0YA0` z_)~yC1X$sr^5!WrCwcsci27Smr=reT4DN-SF_Km7*w6alU=H#2{dmmwVGkREmyP1N xP<=t|lyB8H2KkimQ29`!i&ti!o@dEV#qe8124oP5oZuQ^`K zSqHO$5$71TfaXC{t=`jp6$?HuC~5RO?l2f&Y4vx(Vhi+iMtPhTc#;XZhl75ez%0Fi zo;GdgAXt@DHLisBS-1Q@#TlEo-+cL&ZOvhAtug8vqr0}uQ1hUvF7KJXiX9_rT)LK0 z7CSon36hDK{MpOQa+{Ue(6Nv)I?^58T18VM&CGgs@?+wHl+GmQ(~6vmHOK3xV8y!4 zw0bep_0+oZW1PUGBFP2^eVV{mCeTlwJggM;1r19}2P`dlU453qgcMlm&ejp<1U`u= zRK+;HYW3WPe-1B23hN?`H$uWYaT6ONj*mj2z6DgvUsjX>L#NQyF;XpPE54#Bu`Rf$h`z5}dJa0oNaKddKIt=KT7mBYzo;^Gx$pM(Akhf#6&gSmEE zdq1MbBX}*&VoijwN$bBClXxqlR0~ioxN4teAKXdg#C5EQ1Rhc%k1AWUtj>l**dgFM z0o&AE6T!;2bL_swGYKaR@KJ4w?j;e#^VPdimQm-C=a=x5$57&zvB?*)%`^DJo%qR9 u_{|5f%O(8c4%E4fzx*hjN3q8TaYIiaOD^w`*s_R_oe&;~%CN+C>;C|T_W5oA diff --git a/PLASMA-SOS2.PO b/PLASMA-SOS2.PO index 282707a36d24c25e6264e65b248b1112727c8e50..7ce4590a26716b1afa6f1f7ae3f3260bf22ffaf4 100644 GIT binary patch delta 69 zcmV-L0J{Hx;0S==2(U~91aKrZ5VKGOv>*rm0P_F;0Ozv{CHVpuD*)&JF94qZLjYd? bPyl29QvkRBRshX|8z_exC;_({C<5gN)s-7A delta 69 zcmV-L0J{Hx;0S==2(U~91aBl03$suJv>*rn0PFw$0PeF3CHVpuLjY#~PylQHF94eV bQvkdFRshleD*)4j8z_exC;_({C<5gN$Z#75 diff --git a/PLASMA-SYS2.PO b/PLASMA-SYS2.PO index baf66839dbcb4761378b62d1286c7dbc96ccc632..0bc72573be1c69a5b9019f6337766640664ff5fb 100644 GIT binary patch delta 1358 zcmZvbZETZO6vzL!?bbnM>oQ;szNE>9O-7uZ8A=*HIJ&ZzbZz$n>W~kHm>|r6A&MFx zbqhF(i;@R;5M&WS36gD;YM&YAGMQvWz|71NpQ5se5s8GbX_#Mjk7w2HrS@v#C@*&9{U>tRMN@4u zK2nf1ZyE16&h9K?a(RlJ%H>>AK1Z=(VMRk#BW6Bnhrr-erP*L-CRkYOe{R*9=H?VC z9Sm+x2k&HpOIO#d@-(C{Kn7sK5mQ=4SJ{%Z=3mHA+RGlY%R!J@v%J2@kek%M&7>^ zGC08PRiK{SI7uFiP&K#a<8}i$M)mlT8c?Qo?XUDCN0$9I@&Wtw1zP_#>HUnGFZB9-Rkd}2)S%^2_D5T~ zKRPo(ho`C9(@--59!EB=#L#f|1FIsLvwUM%nm?^5Ika zSBsWx(M2#E)tptrRlsiSXE(m8z0xf1t*`)bGT>((+ko1li0v%gWZ?!2->Y{O(Zs?K z3xh25YIO%h*CNg^${B_<@u?^^8(-6RsZWH3BVWWB0a-Ize)heYo6CUsL-xbsfx zVf~u^xBj($SKp{_(fYz-n`r@4`j)u++Pe6T_(!m-#nZg>pBEh^1E?GAz(F>A OE3L(VwsS5KWU6nn0|b*#}aLadf4u>DulOGftyXBt~2^jT&My zLS;_JCYt4L+&SF@j1oi`rP_-yaj=+_G1&;I=5`|thkhAZ_+wc7u=9G-xsA2nFZbN{ zp5ODn=R8kjA}2DDb21=F4R(vHgr(Az4fX=L2$R5@cFC;tN`-li523{F&P^B7+kTP! z>HRUwvgI4Zsz6q3t|CEN=EylM*Xoib6)PStt@2f4@!>Ww3<68GDZSZXp+EH8=52L# z^C))+@QqCHRyMeHOZjGR)jS69FeG$K86Dllt22gwIjhoAyhh$+`tM>knUucbtm74x z`5tH`n(e|exXeqN#b%2eBjy3TMmabfi=3KT<>|y8YQtV?MKkS33yq_VzQ-pNM?0NH z2c3dS8oDWp9{LdnDTc4;2Yf>(aFkBsJ35X&<;3~g+)ku~&NZPkA#^5VmJ4okpbfwB zR*di#T;ZL#%2gzJH-6{uL+1*{css7~W?bi8xWNx#l7EOl`KMSR1T546C+&la_Tp)3 z!gh*%cCppqD8)9a!mIQwJ|K@6CycLYD~?em&XX5|1pG`v{1o#KKW4Q`Vn!n_62lD& z%P<%)GRyEfk40{Nk)N55_1=KDqT1;Rm3h;anLa{3U|YDryt!cA&${`-Kq%<*SA^${ z=AVmvG-c+aHyd<#Yqol;$``>yFkv`np<{ZX+{y;mdP2eS(0o7P^)cbKoZ+?Np2-T< z%;NCr<5*!Y4|;1BmB0sKMADcsL*D~n`j-{!s)J?K-pU1(k77CQtXc}jW@q9-IUluT z!eL>j92%baFoz5b5+WRyAb_vw4|kM;HXKl*+Ba!MNW zt2?92liRHy(TDYE{fvH7e^K9|^+(y;(n>+;4N1>$&nFv`?dnre_UHotO6sN5<&-?; zQ+LMykB_rUjD@w9)9h~p3#+@&vS-BW+*!8YwkDBC4BeI!qxb%>{dMnxEi%=05F2;g zZN3}0gG9uszT3|nY)I?rXWNZRo?%6NfI0Hagel^f)|{iP#P~=h4v46CiKzF`6C&=l S;)))}5N*JSw)-k;df{K&@V&4A diff --git a/src/toolsrc/parse.c b/src/toolsrc/parse.c index 6f2aa02..43d20c1 100755 --- a/src/toolsrc/parse.c +++ b/src/toolsrc/parse.c @@ -1069,7 +1069,7 @@ int parse_stmnt(void) casetag[i] = casetag[i-1]; i--; } - if (casecnt && (caseval[i] == constval)) + if ((i < casecnt) && (caseval[i] == constval)) parse_error("Duplicate CASE"); caseval[i] = constval; casetag[i] = tag_of; diff --git a/src/toolsrc/parse.pla b/src/toolsrc/parse.pla index 37c653d..141d2b0 100644 --- a/src/toolsrc/parse.pla +++ b/src/toolsrc/parse.pla @@ -821,7 +821,7 @@ def parse_stmnt casetag=>[i] = casetag=>[i-1] i-- loop - if casecnt and caseval=>[i] == caseconst; exit_err(ERR_DUP|ERR_STATE); fin + if i < casecnt and caseval=>[i] == caseconst; exit_err(ERR_DUP|ERR_STATE); fin caseval=>[i] = caseconst casetag=>[i] = tag_of casecnt++ From 68479c16069a142b5492f8e86d2d5982f0626e1c Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Fri, 16 Mar 2018 19:08:13 -0700 Subject: [PATCH 051/147] Fix Y adjust on cse early exit --- src/vmsrc/apple/plvm802.s | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vmsrc/apple/plvm802.s b/src/vmsrc/apple/plvm802.s index 59f40f8..dafb39a 100644 --- a/src/vmsrc/apple/plvm802.s +++ b/src/vmsrc/apple/plvm802.s @@ -1398,9 +1398,10 @@ CASELP CMP (IP),Y CASEEND TXA ; SKIP REMAINING CASES ASL ASL - CLC +; CLC ADC IP STA IP + DEY FIXNEXT TYA LDY #$00 SEC From 463db3c170d7c6edfb5457649c66ad5766b31c84 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Fri, 16 Mar 2018 20:44:09 -0700 Subject: [PATCH 052/147] Fix 65802 caseblock early exit --- PLASMA-SYS2.PO | Bin 143360 -> 143360 bytes src/vmsrc/apple/plvm802.s | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/PLASMA-SYS2.PO b/PLASMA-SYS2.PO index 0bc72573be1c69a5b9019f6337766640664ff5fb..26d994e71c62ddd1e71c46e91ece895b742006ce 100644 GIT binary patch delta 40 wcmZp8z|ru4W5W&>UKbSs0cD2A3=9P-iXzQNS+*Z#VO+4C(Q13z9>!V402ZSS=Kufz delta 40 wcmZp8z|ru4W5W&>UK157er1No3=9P-rUK1JS+*Z#VO+4CQDS@A9>!V402zi2?f?J) diff --git a/src/vmsrc/apple/plvm802.s b/src/vmsrc/apple/plvm802.s index dafb39a..9c3df63 100644 --- a/src/vmsrc/apple/plvm802.s +++ b/src/vmsrc/apple/plvm802.s @@ -1398,10 +1398,10 @@ CASELP CMP (IP),Y CASEEND TXA ; SKIP REMAINING CASES ASL ASL + DEC ; CLC ADC IP STA IP - DEY FIXNEXT TYA LDY #$00 SEC From c02bcd413d48b49c18201107d360c56b8f24f3e7 Mon Sep 17 00:00:00 2001 From: Dave Schmenk Date: Fri, 16 Mar 2018 22:42:57 -0700 Subject: [PATCH 053/147] BYTE size variables --- src/samplesrc/rod.pla | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/samplesrc/rod.pla b/src/samplesrc/rod.pla index 3b4bdf4..d754adb 100644 --- a/src/samplesrc/rod.pla +++ b/src/samplesrc/rod.pla @@ -4,7 +4,7 @@ include "inc/conio.plh" // Rod's Colors // def rod - var i, j, k, w, fmi, fmk, color + byte i, j, k, w, fmi, fmk, color while TRUE for w = 3 to 50 From d379cefe2a66e35c664a343b5176e3fcdca85b72 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Sat, 17 Mar 2018 08:44:02 -0700 Subject: [PATCH 054/147] 6502 caseblock early exit test --- src/vmsrc/apple/plvm01.s | 37 ++++++++++++++++++++++++++++--------- src/vmsrc/apple/plvm02.s | 37 ++++++++++++++++++++++++++++--------- 2 files changed, 56 insertions(+), 18 deletions(-) diff --git a/src/vmsrc/apple/plvm01.s b/src/vmsrc/apple/plvm01.s index cf9c67d..6ae2223 100644 --- a/src/vmsrc/apple/plvm01.s +++ b/src/vmsrc/apple/plvm01.s @@ -814,20 +814,17 @@ SEL INX DEY LDA (IP),Y STA TMPL ; CASE COUNT - LDA ESTKL-1,X INC IPL BNE CASELP INC IPH -CASELP CMP (IP),Y - BNE + +CASELP LDA ESTKL-1,X + CMP (IP),Y + BEQ + LDA ESTKH-1,X INY - CMP (IP),Y - BEQ BRNCH - LDA ESTKL-1,X - DEY -+ INY - INY + SBC (IP),Y + BMI CASEEND +- INY INY DEC TMPL BEQ FIXNEXT @@ -835,6 +832,28 @@ CASELP CMP (IP),Y BNE CASELP INC IPH BNE CASELP ++ LDA ESTKH-1,X + INY + SBC (IP),Y + BEQ BRNCH + BPL - +CASEEND LDA #$00 + STA TMPH + LDA TMPL + ASL ; SKIP REMAINING CASES + ROL TMPH + ASL + ROL TMPH + SBC #$00 ; CARRY CLEAR = SUB #1 + BCS + + DEC TMPH ++ CLC + ADC IPL + STA IPL + LDA TMPH + ADC IPH + STA IPH + DEY FIXNEXT TYA LDY #$00 SEC diff --git a/src/vmsrc/apple/plvm02.s b/src/vmsrc/apple/plvm02.s index e26c33b..1ab890e 100755 --- a/src/vmsrc/apple/plvm02.s +++ b/src/vmsrc/apple/plvm02.s @@ -1606,20 +1606,17 @@ SEL INX DEY LDA (IP),Y STA TMPL ; CASE COUNT - LDA ESTKL-1,X INC IPL BNE CASELP INC IPH -CASELP CMP (IP),Y - BNE + +CASELP LDA ESTKL-1,X + CMP (IP),Y + BEQ + LDA ESTKH-1,X INY - CMP (IP),Y - BEQ BRNCH - LDA ESTKL-1,X - DEY -+ INY - INY + SBC (IP),Y + BMI CASEEND +- INY INY DEC TMPL BEQ FIXNEXT @@ -1627,6 +1624,28 @@ CASELP CMP (IP),Y BNE CASELP INC IPH BNE CASELP ++ LDA ESTKH-1,X + INY + SBC (IP),Y + BEQ BRNCH + BPL - +CASEEND LDA #$00 + STA TMPH + LDA TMPL + ASL ; SKIP REMAINING CASES + ROL TMPH + ASL + ROL TMPH + SBC #$00 ; CARRY CLEAR = SUB #1 + BCS + + DEC TMPH ++ CLC + ADC IPL + STA IPL + LDA TMPH + ADC IPH + STA IPH + DEY FIXNEXT TYA LDY #$00 SEC From 3975e54c298837a1cc3f5bb3ccc66abc12432dd4 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Sat, 17 Mar 2018 08:48:51 -0700 Subject: [PATCH 055/147] Update image --- PLASMA-SYS2.PO | Bin 143360 -> 143360 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/PLASMA-SYS2.PO b/PLASMA-SYS2.PO index 26d994e71c62ddd1e71c46e91ece895b742006ce..6c64a638f9f7828601553c5ff812b263db264136 100644 GIT binary patch delta 422 zcmZp8z|ru4V}k>WfUh8fzKRT=GQ(pAhC&q`j?Doq=3Fw8`fF$G*EBe3@IhqdoZg5F zEARG3URWvA8+Bpjy~&IDl9}c1=uPJ2R~PiTV|OR`&a~Sv@3`DOd{^O~$z(@~fFCJmod@LdgN2 z4-6~cEV{aYTLCCia^S?qPg5^|#0(Z)TOh8WIoUy89;hQhUQ1llaO;Js`xowq>G}p# zAq-TpP+l6SVz0aukh~$U03?6P%K%9+1r;D^t)K)X;}o=jWT%1#kldu8EU0N%aWfR-SGzKRT=GQ(pAh5{8+fz1Id=3Fx0^w!SUuW4}7;DgA@%HD_z zEARG3URe3QHwws_yqGVU`S)$^$(;P^f|_@v?-<;fcKg^J#k&jc{=F+W*^%E_!0%4n zot`_}?iAfwcIV~oPq#Nu;V)u==n+wuhv|89#|^0G^4;fme_s7|jr)4#^~u+7-uOD% zpWhUV2_kG9DqGJ#`*eZn+2@O&E^uw#f8ye&59wRacbqtJ;@I;K>?ba~c=q|ilg$rh z?3ozZCM(KIyR#Xd@|t>~IKCJ-Bn*sGGDX>j$me(?7Gu(P%>i&iMVdi}U>J6(C0nKZFd&P0nOl4{61NLNx4a>O^I=t5)&T)8n)F> From 95e15e4b8670a47dfa3387026aef870d335577a9 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Sat, 17 Mar 2018 09:46:13 -0700 Subject: [PATCH 056/147] Better CASE END --- src/vmsrc/apple/plvm01.s | 9 ++++----- src/vmsrc/apple/plvm02.s | 9 ++++----- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/vmsrc/apple/plvm01.s b/src/vmsrc/apple/plvm01.s index 6ae2223..651be40 100644 --- a/src/vmsrc/apple/plvm01.s +++ b/src/vmsrc/apple/plvm01.s @@ -839,21 +839,20 @@ CASELP LDA ESTKL-1,X BPL - CASEEND LDA #$00 STA TMPH + DEC TMPL LDA TMPL ASL ; SKIP REMAINING CASES ROL TMPH ASL ROL TMPH - SBC #$00 ; CARRY CLEAR = SUB #1 - BCS + - DEC TMPH -+ CLC +; CLC ADC IPL STA IPL LDA TMPH ADC IPH STA IPH - DEY + INY + INY FIXNEXT TYA LDY #$00 SEC diff --git a/src/vmsrc/apple/plvm02.s b/src/vmsrc/apple/plvm02.s index 1ab890e..a33d4c8 100755 --- a/src/vmsrc/apple/plvm02.s +++ b/src/vmsrc/apple/plvm02.s @@ -1631,21 +1631,20 @@ CASELP LDA ESTKL-1,X BPL - CASEEND LDA #$00 STA TMPH + DEC TMPL LDA TMPL ASL ; SKIP REMAINING CASES ROL TMPH ASL ROL TMPH - SBC #$00 ; CARRY CLEAR = SUB #1 - BCS + - DEC TMPH -+ CLC +; CLC ADC IPL STA IPL LDA TMPH ADC IPH STA IPH - DEY + INY + INY FIXNEXT TYA LDY #$00 SEC From 3356cdd036e4a3164eb00400d5f726aa6f0eb84a Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Sat, 17 Mar 2018 15:06:31 -0700 Subject: [PATCH 057/147] Break out cmd into module --- src/inc/cmdsys.plh | 12 +- src/makefile | 13 +- src/mkrel | 1 + src/vmsrc/apple/plvm03.s | 230 ++++-- src/vmsrc/apple/soscmd.pla | 1353 ++---------------------------------- src/vmsrc/apple/sossys.pla | 1229 ++++++++++++++++++++++++++++++++ 6 files changed, 1494 insertions(+), 1344 deletions(-) create mode 100755 src/vmsrc/apple/sossys.pla diff --git a/src/inc/cmdsys.plh b/src/inc/cmdsys.plh index a5bb328..b204545 100644 --- a/src/inc/cmdsys.plh +++ b/src/inc/cmdsys.plh @@ -2,7 +2,7 @@ import cmdsys // // Useful values for everyone // - const _SYSVER_ = $0100 // Version built against + const _SYSVER_ = $0200 // Version built against const FALSE = 0 const TRUE = not FALSE const NULL = 0 @@ -46,8 +46,14 @@ import cmdsys word syspath word cmdline word modexec - byte refcons - byte devcons + word sysopen + word sysclose + word sysread + word syswrite + byte syserr + byte modid // Apple /// specific + byte refcons // Apple /// specific + byte devcons // Apple /// specific end // // CMD exported functions diff --git a/src/makefile b/src/makefile index 0a72c46..82e749c 100755 --- a/src/makefile +++ b/src/makefile @@ -6,6 +6,7 @@ PLVM01 = rel/apple/A1PLASMA\#060280 PLVM02 = rel/apple/PLASMA.SYSTEM\#FF2000 PLVM802 = rel/apple/PLASMA16.SYSTEM\#FF2000 PLVM03 = rel/apple/SOS.INTERP\#050000 +SOSCMD = rel/apple/SOS.CMD\#0FE1000 CMD = rel/apple/CMD\#061000 PLVMZP_C64 = vmsrc/c64/plvmzp.inc PLVMC64 = rel/c64/PLASMA @@ -75,7 +76,7 @@ TXTTYPE = .TXT #SYSTYPE = \#FF2000 #TXTTYPE = \#040000 -apple: $(PLVMZP_APL) $(PLASM) $(PLVM) $(PLVM01) $(PLVM02) $(PLVM802) $(PLVM03) $(CMD) $(PLASMAPLASM) $(CODEOPT) $(ARGS) $(MEMMGR) $(MEMTEST) $(FIBER) $(FIBERTEST) $(LONGJMP) $(ED) $(MON) $(SOS) $(ROD) $(SIEVE) $(UTHERNET2) $(UTHERNET) $(ETHERIP) $(INET) $(DHCP) $(HTTPD) $(ROGUE) $(ROGUEMAP) $(ROGUECOMBAT) $(GRAFIX) $(GFXDEMO) $(DGR) $(DGRTEST) $(FILEIO_APL) $(CONIO_APL) $(JOYBUZZ) $(PORTIO) $(SPIPORT) $(SDFAT) $(FATCAT) $(FATGET) $(FATPUT) $(FATWDSK) $(FATRDSK) $(SANE) $(FPSTR) $(FPU) $(SANITY) $(RPNCALC) $(SNDSEQ) $(PLAYSEQ) +apple: $(PLVMZP_APL) $(PLASM) $(PLVM) $(PLVM01) $(PLVM02) $(PLVM802) $(PLVM03) $(CMD) $(SOSCMD) $(PLASMAPLASM) $(CODEOPT) $(ARGS) $(MEMMGR) $(MEMTEST) $(FIBER) $(FIBERTEST) $(LONGJMP) $(ED) $(MON) $(SOS) $(ROD) $(SIEVE) $(UTHERNET2) $(UTHERNET) $(ETHERIP) $(INET) $(DHCP) $(HTTPD) $(ROGUE) $(ROGUEMAP) $(ROGUECOMBAT) $(GRAFIX) $(GFXDEMO) $(DGR) $(DGRTEST) $(FILEIO_APL) $(CONIO_APL) $(JOYBUZZ) $(PORTIO) $(SPIPORT) $(SDFAT) $(FATCAT) $(FATGET) $(FATPUT) $(FATWDSK) $(FATRDSK) $(SANE) $(FPSTR) $(FPU) $(SANITY) $(RPNCALC) $(SNDSEQ) $(PLAYSEQ) -rm vmsrc/plvmzp.inc c64: $(PLVMZP_C64) $(PLASM) $(PLVM) $(PLVMC64) @@ -148,16 +149,20 @@ $(CMD): vmsrc/apple/cmd.pla vmsrc/apple/cmdstub.s $(PLVM02) $(PLASM) ./$(PLASM) -AOW < vmsrc/apple/cmd.pla > vmsrc/apple/cmd.a acme --setpc 8192 -o $(CMD) vmsrc/apple/cmdstub.s +$(SOSCMD): vmsrc/apple/soscmd.pla $(PLVM03) $(PLASM) + ./$(PLASM) -AMOW < vmsrc/apple/soscmd.pla > vmsrc/apple/soscmd.a + acme --setpc 4094 -o $(SOSCMD) vmsrc/apple/soscmd.a + $(PLVM02): vmsrc/apple/plvm02.s acme -o $(PLVM02) -l vmsrc/apple/plvm02.sym vmsrc/apple/plvm02.s $(PLVM802): vmsrc/apple/plvm802.s acme -o $(PLVM802) -l vmsrc/apple/plvm802.sym vmsrc/apple/plvm802.s -vmsrc/apple/soscmd.a: vmsrc/apple/soscmd.pla $(PLASM) - ./$(PLASM) -AOW < vmsrc/apple/soscmd.pla > vmsrc/apple/soscmd.a +vmsrc/apple/sossys.a: vmsrc/apple/sossys.pla $(PLASM) + ./$(PLASM) -AOW < vmsrc/apple/sossys.pla > vmsrc/apple/sossys.a -$(PLVM03): vmsrc/apple/plvm03.s vmsrc/apple/soscmd.a +$(PLVM03): vmsrc/apple/plvm03.s vmsrc/apple/sossys.a acme -o $(PLVM03) -l vmsrc/apple/plvm03.sym vmsrc/apple/plvm03.s # diff --git a/src/mkrel b/src/mkrel index 687e882..e8a1af0 100755 --- a/src/mkrel +++ b/src/mkrel @@ -2,6 +2,7 @@ cp rel/apple/CMD#061000 prodos/CMD.BIN cp rel/apple/PLASMA.SYSTEM#FF2000 prodos/PLASMA.SYSTEM.SYS cp rel/apple/PLASMA16.SYSTEM#FF2000 prodos/PLASMA16.SYSTEM.SYS cp rel/apple/SOS.INTERP#050000 prodos/SOS.INTERP.\$05 +cp rel/apple/SOS.CMD#FE1000 prodos/SOS.CMD.REL cp ../doc/Editor.md prodos/EDITOR.README.TXT rm -rf prodos/sys diff --git a/src/vmsrc/apple/plvm03.s b/src/vmsrc/apple/plvm03.s index fd1a9fd..e7afc82 100755 --- a/src/vmsrc/apple/plvm03.s +++ b/src/vmsrc/apple/plvm03.s @@ -534,7 +534,6 @@ CB LDA #$00 BCC + INC IPH + LDY #$FF -CW LA INY ;+INC_IP BMI - DEX @@ -544,14 +543,14 @@ LA INY ;+INC_IP LDA (IP),Y STA ESTKH,X JMP NEXTOP -;CW DEX -; INY ;+INC_IP -; LDA (IP),Y -; STA ESTKL,X -; INY -; LDA (IP),Y -; STA ESTKH,X -; JMP NEXTOP +CW DEX + INY ;+INC_IP + LDA (IP),Y + STA ESTKL,X + INY + LDA (IP),Y + STA ESTKH,X + JMP NEXTOP ;* ;* CONSTANT STRING ;* @@ -663,7 +662,7 @@ LLA INY ;+INC_IP ;* ;* LOAD VALUE FROM LOCAL FRAME OFFSET ;* -_LLB INY ;+INC_IP +LLB INY ;+INC_IP LDA (IP),Y STY IPY TAY @@ -673,8 +672,8 @@ _LLB INY ;+INC_IP LDA #$00 STA ESTKH,X LDY IPY - RTS -_LLW INY ;+INC_IP + JMP NEXTOP +LLW INY ;+INC_IP LDA (IP),Y STY IPY TAY @@ -685,29 +684,81 @@ _LLW INY ;+INC_IP LDA (IFP),Y STA ESTKH,X LDY IPY - RTS -LLB JSR _LLB - JMP NEXTOP -LLW JSR _LLW JMP NEXTOP ;* ;* ADD VALUE FROM LOCAL FRAME OFFSET ;* -ADDLB JSR _LLB - JMP ADD -ADDLW JSR _LLW - JMP ADD +ADDLB INY ;+INC_IP + LDA (IP),Y + STY IPY + TAY + LDA (IFP),Y + CLC + ADC ESTKL,X + STA ESTKL,X + BCC + + INC ESTKH,X ++ LDY IPY + JMP NEXTOP +ADDLW INY ;+INC_IP + LDA (IP),Y + STY IPY + TAY + LDA (IFP),Y + CLC + ADC ESTKL,X + STA ESTKL,X + INY + LDA (IFP),Y + ADC ESTKH,X + STA ESTKH,X + LDY IPY + JMP NEXTOP ;* ;* INDEX VALUE FROM LOCAL FRAME OFFSET ;* -IDXLB JSR _LLB - JMP IDXW -IDXLW JSR _LLW - JMP IDXW +IDXLB INY ;+INC_IP + LDA (IP),Y + STY IPY + TAY + LDA (IFP),Y + LDY #$00 + ASL + BCC + + INY + CLC ++ ADC ESTKL,X + STA ESTKL,X + TYA + ADC ESTKH,X + STA ESTKH,X + LDY IPY + JMP NEXTOP +IDXLW INY ;+INC_IP + LDA (IP),Y + STY IPY + TAY + STA TMPL + LDA (IFP),Y + ASL + STA TMPL + INY + LDA (IFP),Y + ROL + STA TMPH + LDA TMPL + CLC + ADC ESTKL,X + STA ESTKL,X + LDA TMPH + ADC ESTKH,X + STA ESTKH,X + LDY IPY + JMP NEXTOP ;* ;* LOAD VALUE FROM ABSOLUTE ADDRESS ;* -_LAB INY ;+INC_IP +LAB INY ;+INC_IP LDA (IP),Y STA ESTKH-2,X INY ;+INC_IP @@ -718,8 +769,8 @@ _LAB INY ;+INC_IP STA ESTKL,X LDA #$00 STA ESTKH,X - RTS -_LAW INY ;+INC_IP + JMP NEXTOP +LAW INY ;+INC_IP LDA (IP),Y STA TMPL INY ;+INC_IP @@ -734,25 +785,88 @@ _LAW INY ;+INC_IP LDA (TMP),Y STA ESTKH,X LDY IPY - RTS -LAB JSR _LAB - JMP NEXTOP -LAW JSR _LAW JMP NEXTOP ;* ;* ADD VALUE FROM ABSOLUTE ADDRESS ;* -ADDAB JSR _LAB - JMP ADD -ADDAW JSR _LAW - JMP ADD +ADDAB INY ;+INC_IP + LDA (IP),Y + STA ESTKH-2,X + INY ;+INC_IP + LDA (IP),Y + STA ESTKH-1,X + LDA (ESTKH-2,X) + CLC + ADC ESTKL,X + STA ESTKL,X + BCC + + INC ESTKH,X ++ JMP NEXTOP +ADDAW INY ;+INC_IP + LDA (IP),Y + STA SRCL + INY ;+INC_IP + LDA (IP),Y + STA SRCH + STY IPY + LDY #$00 + LDA (SRC),Y + CLC + ADC ESTKL,X + STA ESTKL,X + INY + LDA (SRC),Y + ADC ESTKH,X + STA ESTKH,X + LDY IPY + JMP NEXTOP ;* ;* INDEX VALUE FROM ABSOLUTE ADDRESS ;* -IDXAB JSR _LAB - JMP IDXW -IDXAW JSR _LAW - JMP IDXW +IDXAB INY ;+INC_IP + LDA (IP),Y + STA ESTKH-2,X + INY ;+INC_IP + LDA (IP),Y + STA ESTKH-1,X + LDA (ESTKH-2,X) + STY IPY + LDY #$00 + ASL + BCC + + INY + CLC ++ ADC ESTKL,X + STA ESTKL,X + TYA + ADC ESTKH,X + STA ESTKH,X + LDY IPY + JMP NEXTOP +IDXAW INY ;+INC_IP + LDA (IP),Y + STA SRCL + INY ;+INC_IP + LDA (IP),Y + STA SRCH + STY IPY + LDY #$00 + LDA (SRC),Y + ASL + STA TMPL + INY + LDA (SRC),Y + ROL + STA TMPH + LDA TMPL + CLC + ADC ESTKL,X + STA ESTKL,X + LDA TMPH + ADC ESTKH,X + STA ESTKH,X + LDY IPY + JMP NEXTOP ;* ;* STORE VALUE TO ADDRESS ;* @@ -976,20 +1090,17 @@ SEL INX STY TMPX ; CLEAR TMPX LDA (IP),Y STA TMPL ; CASE COUNT - LDA ESTKL-1,X INC IPL BNE CASELP INC IPH -CASELP CMP (IP),Y - BNE + +CASELP LDA ESTKL-1,X + CMP (IP),Y + BEQ + LDA ESTKH-1,X INY - CMP (IP),Y - BEQ BRNCH - LDA ESTKL-1,X - DEY -+ INY - INY + SBC (IP),Y + BMI CASEEND +- INY INY DEC TMPL BEQ FIXNEXT @@ -997,6 +1108,27 @@ CASELP CMP (IP),Y BNE CASELP INC IPH BNE CASELP ++ LDA ESTKH-1,X + INY + SBC (IP),Y + BEQ BRNCH + BPL - +CASEEND LDA #$00 + STA TMPH + DEC TMPL + LDA TMPL + ASL ; SKIP REMAINING CASES + ROL TMPH + ASL + ROL TMPH +; CLC + ADC IPL + STA IPL + LDA TMPH + ADC IPH + STA IPH + INY + INY FIXNEXT TYA LDY #$00 SEC @@ -1217,6 +1349,6 @@ LEAVE INY ;+INC_IP STA IFPH RET RTS SOSCMD = * - !SOURCE "vmsrc/apple/soscmd.a" + !SOURCE "vmsrc/apple/sossys.a" } SEGEND = * diff --git a/src/vmsrc/apple/soscmd.pla b/src/vmsrc/apple/soscmd.pla index b5bf840..02d8b3d 100755 --- a/src/vmsrc/apple/soscmd.pla +++ b/src/vmsrc/apple/soscmd.pla @@ -1,128 +1,10 @@ -const membank = $FFEF -const RELADDR = $1000 -// -// System flags: memory allocator screen holes. -// -const restxt1 = $0001 -const restxt2 = $0002 -const resxtxt1 = $0004 -const resxtxt2 = $0008 -const reshgr1 = $0010 -const reshgr2 = $0020 -const resxhgr1 = $0040 -const resxhgr2 = $0080 -// -// Module don't free memory -// -const modkeep = $2000 -const modinitkeep = $4000 -// -// Pedefined functions. -// -predef syscall(cmd,params)#1, call(addr,areg,xreg,yreg,status)#1 -predef crout()#0, cout(c)#0, prstr(s)#0, print(i)#0, prbyte(b)#0, prword(w)#0 -predef cin()#1, rdstr(p)#1, toupper(c)#1, strcpy(dst,src)#1, strcat(dst,src)#1 -predef markheap()#1, allocheap(size)#1, allocalignheap(size, pow2, freeaddr), releaseheap(newheap)#1, availheap()#1 -predef memset(addr,value,size)#0, memcpy(dst,src,size)#0 -predef uword_isgt(a,b)#1, uword_isge(a,b)#1, uword_islt(a,b)#1, uword_isle(a,b)#1, sext(a)#1, divmod(a,b)#2 -predef execmod(modfile)#1 -// -// Exported CMDSYS table -// -word version = $0202 // 02.00 -word syspath -word cmdlnptr -word = @execmod -byte refcons = 0 -byte devcons = 0 -// -// String pool. -// +include "inc/cmdsys.plh" byte console[] = ".CONSOLE" byte textmode[] = 16, 0, 15 -byte hexchar[] = '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' -// -// Exported Machine ID. -// -byte machid = $F2 // Apple ///, 80 columns -// -// Working input buffer overlayed with strings table -// +byte prefix[64] = "" +byte err[] +byte autorun word cmdptr -byte cmdln = "" -// -// Standard Library exported functions. -// -byte sysmodstr[] = "CMDSYS" -byte machidstr[] = "MACHID" -byte sysstr[] = "SYSCALL" -byte callstr[] = "CALL" -byte putcstr[] = "PUTC" -byte putlnstr[] = "PUTLN" -byte putsstr[] = "PUTS" -byte putistr[] = "PUTI" -byte putbstr[] = "PUTB" -byte putwstr[] = "PUTH" -byte getcstr[] = "GETC" -byte getsstr[] = "GETS" -byte toupstr[] = "TOUPPER" -byte strcpystr[] = "STRCPY" -byte strcatstr[] = "STRCAT" -byte hpmarkstr[] = "HEAPMARK" -byte hpalignstr[] = "HEAPALLOCALIGN" -byte hpallocstr[] = "HEAPALLOC" -byte hprelstr[] = "HEAPRELEASE" -byte hpavlstr[] = "HEAPAVAIL" -byte sysmods[] = "" // overlay with exported strings -byte memsetstr[] = "MEMSET" -byte memcpystr[] = "MEMCPY" -byte uisgtstr[] = "ISUGT" -byte uisgestr[] = "ISUGE" -byte uisltstr[] = "ISULT" -byte uislestr[] = "ISULE" -byte sextstr[] = "SEXT" -byte divmodstr[] = "DIVMOD" -byte autorun[] = "AUTORUN" -byte prefix[] = "" // Overlay with exported symbols table -word exports[] = @sysmodstr, @version -word = @sysstr, @syscall -word = @callstr, @call -word = @putcstr, @cout -word = @putlnstr, @crout -word = @putsstr, @prstr -word = @putistr, @print -word = @putbstr, @prbyte -word = @putwstr, @prword -word = @getcstr, @cin -word = @getsstr, @rdstr -word = @toupstr, @toupper -word = @hpmarkstr, @markheap -word = @hpallocstr,@allocheap -word = @hpalignstr,@allocalignheap -word = @hprelstr, @releaseheap -word = @hpavlstr, @availheap -word = @memsetstr, @memset -word = @memcpystr, @memcpy -word = @strcpystr, @strcpy -word = @strcatstr, @strcat -word = @uisgtstr, @uword_isgt -word = @uisgestr, @uword_isge -word = @uisltstr, @uword_islt -word = @uislestr, @uword_isle -word = @sextstr, @sext -word = @divmodstr, @divmod -word = @machidstr, @machid -word = 0 -word sysmodsym = @exports -// -// System variables. -// -word systemflags = 0 -word heap = $2000 -byte modid = 0 -byte modseg[15] -word symtbl, lastsym -byte perr, terr // // Utility functions // @@ -134,655 +16,6 @@ XREG LDX #$00 RTS end // -// CALL SOS -// SYSCALL(CMD, PARAMS) -// -asm syscall(cmd,params)#1 - LDA ESTKL,X - LDY ESTKH,X - STA PARAMS - STY PARAMS+1 - INX - LDA ESTKL,X - STA CMD - BRK -CMD !BYTE 00 -PARAMS !WORD 0000 - LDY #$00 - STA ESTKL,X - STY ESTKH,X - RTS -end -// -// CALL 6502 ROUTINE -// CALL(AREG, XREG, YREG, STATUS, ADDR) -// -asm call(addr,areg,xreg,yreg,sstatus)#1 -REGVALS = SRC - PHP - LDA ESTKL,X - STA TMPL - LDA ESTKH,X - STA TMPH - INX - LDA ESTKL,X - PHA - INX - LDY ESTKL,X - INX - LDA ESTKL+1,X - PHA - LDA ESTKL,X - INX - STX ESP - TAX - PLA - PLP - JSR JMPTMP - PHP - STA REGVALS+0 - STX REGVALS+1 - STY REGVALS+2 - PLA - STA REGVALS+3 - LDX ESP - LDA #REGVALS - STA ESTKL,X - STY ESTKH,X - PLP - RTS -end -// -// SET MEMORY TO VALUE -// MEMSET(ADDR, VALUE, SIZE) -// With optimizations from Peter Ferrie -// -asm memset(addr,value,size)#0 - LDA ESTKL+2,X - STA DSTL - LDA ESTKH+2,X - STA DSTH - LDY ESTKL,X - BEQ + - INC ESTKH,X - LDY #$00 -+ LDA ESTKH,X - BEQ SETMEX -SETMLPL CLC - LDA ESTKL+1,X -SETMLPH STA (DST),Y - DEC ESTKL,X - BEQ ++ -- INY - BEQ + --- BCS SETMLPL - SEC - LDA ESTKH+1,X - BCS SETMLPH -+ INC DSTH - BNE -- -++ DEC ESTKH,X - BNE - -SETMEX INX - INX - INX - RTS -end -// -// COPY MEMORY -// MEMCPY(DSTADDR, SRCADDR, SIZE) -// -asm memcpy(dst,src,size)#0 - INX - INX - INX - LDA ESTKL-3,X - ORA ESTKH-3,X - BEQ CPYMEX - LDA ESTKL-2,X - CMP ESTKL-1,X - LDA ESTKH-2,X - SBC ESTKH-1,X - BCC REVCPY -; -; FORWARD COPY -; - LDA ESTKL-1,X - STA DSTL - LDA ESTKH-1,X - STA DSTH - LDA ESTKL-2,X - STA SRCL - LDA ESTKH-2,X - STA SRCH - LDY ESTKL-3,X - BEQ FORCPYLP - INC ESTKH-3,X - LDY #$00 -FORCPYLP LDA (SRC),Y - STA (DST),Y - INY - BNE + - INC DSTH - INC SRCH -+ DEC ESTKL-3,X - BNE FORCPYLP - DEC ESTKH-3,X - BNE FORCPYLP - RTS -; -; REVERSE COPY -; -REVCPY ;CLC - LDA ESTKL-3,X - ADC ESTKL-1,X - STA DSTL - LDA ESTKH-3,X - ADC ESTKH-1,X - STA DSTH - CLC - LDA ESTKL-3,X - ADC ESTKL-2,X - STA SRCL - LDA ESTKH-3,X - ADC ESTKH-2,X - STA SRCH - DEC DSTH - DEC SRCH - LDY #$FF - LDA ESTKL-3,X - BEQ REVCPYLP - INC ESTKH-3,X -REVCPYLP LDA (SRC),Y - STA (DST),Y - DEY - CPY #$FF - BNE + - DEC DSTH - DEC SRCH -+ DEC ESTKL-3,X - BNE REVCPYLP - DEC ESTKH-3,X - BNE REVCPYLP -CPYMEX RTS -end -// -// COPY FROM MAIN MEM TO EXT MEM. -// -// MEMXCPY(DSTSEG, SRC, SIZE) -// -asm memxcpy(dst,src,size)#0 - LDA ESTKL,X - ORA ESTKH,X - BEQ CPYXMEX - LDY #$00 - STY DSTL - LDA ESTKH+2,X - CLC - ADC #$60 - STA DSTH - LDA ESTKL+2,X - CLC - ADC #$7F - STA DSTX - LDA ESTKL+1,X - STA SRCL - LDA ESTKH+1,X - STA SRCH - INC ESTKH,X -CPYXLP LDA (SRC),Y - STA (DST),Y - INY - BNE + - INC DSTH - INC SRCH -+ DEC ESTKL,X - BNE CPYXLP - DEC ESTKH,X - BNE CPYXLP - LDA #$00 - STA DSTX -CPYXMEX INX - INX - INX - RTS -end -// -// POKE BYTE VAL INTO EXT MEM. -// -// XPOKEB(SEG, DST, BYTEVAL) -// -asm xpokeb(seg, dst, byteval)#0 - LDA ESTKL+1,X - STA DSTL - LDA ESTKH+1,X - CLC - ADC #$60 - STA DSTH - LDA ESTKL+2,X - CLC - ADC #$7F - STA DSTX - LDY #$00 - LDA ESTKL,X - STA (DST),Y - STY DSTX - INX - INX - INX - RTS -end -// -// Unsigned word comparisons. -// -asm uword_isge(a,b)#1 - LDA ESTKL+1,X - CMP ESTKL,X - LDA ESTKH+1,X - SBC ESTKH,X - LDA #$FF - ADC #$00 - EOR #$FF - STA ESTKL+1,X - STA ESTKH+1,X - INX - RTS -end -asm uword_isle(a,b)#1 - LDA ESTKL,X - CMP ESTKL+1,X - LDA ESTKH,X - SBC ESTKH+1,X - LDA #$FF - ADC #$00 - EOR #$FF - STA ESTKL+1,X - STA ESTKH+1,X - INX - RTS -end -asm uword_isgt(a,b)#1 - LDA ESTKL,X - CMP ESTKL+1,X - LDA ESTKH,X - SBC ESTKH+1,X - LDA #$FF - ADC #$00 - STA ESTKL+1,X - STA ESTKH+1,X - INX - RTS -end -asm uword_islt(a,b)#1 - LDA ESTKL+1,X - CMP ESTKL,X - LDA ESTKH+1,X - SBC ESTKH,X - LDA #$FF - ADC #$00 - STA ESTKL+1,X - STA ESTKH+1,X - INX - RTS -end -asm divmod(a,b)#2 - JSR INTERP ; CALL INTERP - !BYTE $36, $5C ; DIVMOD, RET -end -asm sext(a)#1 - LDY #$00 - LDA ESTKL,X - BPL + - DEY -+ STY ESTKH,X - RTS -end -// -// Addresses of internal routines. -// -asm interp()#1 - DEX - LDA #XINTERP - STA ESTKH,X - RTS -end -// -// A DCI string is one that has the high bit set for every character except the last. -// More efficient than C or Pascal strings. -// -//def dcitos(dci, str) -// byte len, c -// len = 0 -// repeat -// c = (dci).[len] -// len = len + 1 -// (str).[len] = c & $7F -// until !(c & $80) -// ^str = len -// return len -//end -asm dcitos(dci, str)#1 - LDA ESTKL,X - STA DSTL - LDA ESTKH,X - STA DSTH - LDA ESTKL+1,X - STA SRCL - LDA ESTKH+1,X - STA SRCH - LDY #$00 -- LDA (SRC),Y - CMP #$80 - AND #$7F - INY - STA (DST),Y - BCS - - TYA - LDY #$00 - STA (DST),Y - INX - STA ESTKL,X - STY ESTKH,X - RTS -end -//def stodci(str, dci) -// byte len, c -// len = ^str -// if len == 0 -// return -// fin -// c = toupper((str).[len]) & $7F -// len = len - 1 -// (dci).[len] = c -// while len -// c = toupper((str).[len]) | $80 -// len = len - 1 -// (dci).[len] = c -// loop -// return ^str -//end -asm stodci(str, dci)#1 - LDA ESTKL,X - STA DSTL - LDA ESTKH,X - STA DSTH - LDA ESTKL+1,X - STA SRCL - LDA ESTKH+1,X - STA SRCH - INX - LDY #$00 - LDA (SRC),Y - BEQ ++ - TAY - LDA (SRC),Y - JSR TOUPR - BNE + -- LDA (SRC),Y - JSR TOUPR - ORA #$80 -+ DEY - STA (DST),Y - BNE - - LDA (SRC),Y -++ STA ESTKL,X - STY ESTKH,X - RTS -end -asm toupper(c)#1 - LDA ESTKL,X -TOUPR AND #$7F - CMP #'a' - BCC + - CMP #'z'+1 - BCS + - SBC #$1F -+ STA ESTKL,X - RTS -end -// -// Lookup routines. -// -//def lookuptbl(dci, tbl) -// word match -// while ^tbl -// match = dci -// while ^tbl == ^match -// if !(^tbl & $80) -// return (tbl):1 -// fin -// tbl = tbl + 1 -// match = match + 1 -// loop -// while (^tbl & $80) -// tbl = tbl + 1 -// loop -// tbl = tbl + 3 -// loop -// return 0 -asm lookuptbl(dci, tbl)#1 - LDY #$00 - STY DSTL - LDA ESTKH,X - CLC - ADC #$60 - STA DSTH - LDA ESTKL,X - CLC - ADC #$7F - STA DSTX - LDA ESTKL+1,X - STA SRCL - LDA ESTKH+1,X - STA SRCH -- LDA (DST),Y - BEQ + - CMP (SRC),Y - BNE ++ - INY - ASL - BCS - - LDA (DST),Y - PHA - INY - LDA (DST),Y - TAY - PLA -+ INX - STA ESTKL,X - STY ESTKH,X - LDA #$00 - STA DSTX - RTS -++ LDY #$00 --- LDA (DST),Y - INC DSTL - BEQ + ---- ASL - BCS -- - LDA #$02 - ADC DSTL - STA DSTL - BCC - - INC DSTH - BCS - -+ INC DSTH - BNE --- -end -// def lookupidx(esd, index) -// word sym -// while ^esd -// sym = esd -// esd = sym + dcitos(sym, @str) -// if esd->0 & $10 and esd->1 == index -// return sym -// fin -// esd = esd + 3 -// loop -//end -asm lookupidx(esd, index)#1 - LDA ESTKL,X - STA TMPL - INX ---- LDA ESTKH,X - STA SRCH - LDA ESTKL,X --- STA SRCL - LDY #$00 -- LDA (SRC),Y - BPL + - INY - BNE - -+ BEQ ++ ; END OF ESD - INY - LDA (SRC),Y - INY - AND #$10 ; EXTERN FLAG? - BEQ + - LDA (SRC),Y - CMP TMPL - BEQ +++ ; MATCH -+ INY - TYA - SEC - ADC SRCL - STA ESTKL,X ; SYM PTRL - BCC -- - INC ESTKH,X ; SYM PTRH - BNE --- -++ STA ESTKL,X ; END OF ESD - STA ESTKH,X -+++ RTS -end -//def lookupdef(addr, deftbl)#1 -// while deftbl->0 == $20 -// if deftbl=>3 == addr -// return deftbl -// fin -// deftbl = deftbl + 6 -// loop -// return 0 -//end -asm lookupdef(addr, deftbl)#1 - LDA ESTKH,X - STA SRCH - LDA ESTKL,X - STA SRCL - INX -- LDY #$00 - LDA (SRC),Y - CMP #$20 ; JSR OPCODE? - BNE ++ - LDY #$03 - LDA (SRC),Y - CMP ESTKL,X - BNE + - INY - LDA (SRC),Y - CMP ESTKH,X - BNE + - LDA SRCL ; MATCH - STA ESTKL,X - LDA SRCH - STA ESTKH,X - RTS -+ LDA #$06 - CLC - ADC SRCL - STA SRCL - BCC - - INC SRCH - BNE - -++ STY ESTKL,X - STY ESTKH,X - RTS -end -// -// Reloc internal data -// -//def reloc(modfix, modofst, bytecode, rld)#3 -// word addr, fixup -// while ^rld -// if ^rld & $10 // EXTERN reference. -// return rld, addr, fixup -// fin -// addr = rld=>1 + modfix -// fixup = *addr + modofst -// if uword_isge(fixup, bytecode) // Bytecode address. -// return rld, addr, fixup -// fin -// *addr = fixup -// rld = rld + 4 -// loop -// return rld, addr, fixup -//end -asm reloc(modfix, modofst, bytecode, rld)#3 - LDA ESTKL,X - STA SRCL - LDA ESTKH,X - STA SRCH - LDY #$00 -- LDA (SRC),Y - BEQ RLDEX ; END OF RLD - PHA - INY - LDA (SRC),Y - INY - CLC - ADC ESTKL+3,X ; ADDR=ENTRY=>1+MODFIX - STA DSTL - LDA (SRC),Y - ADC ESTKH+3,X - STA DSTH - PLA - AND #$10 ; EXTERN REF - EXIT - BNE RLDEX - TAY ; FIXUP=*ADDR+MODOFST - LDA (DST),Y - INY - CLC - ADC ESTKL+2,X - STA TMPL - LDA (DST),Y - ADC ESTKH+2,X - CMP ESTKH+1,X ; FIXUP >= BYTECODE? - BCC + - STA TMPH - BNE RLDEX ; YEP, EXIT - LDA TMPL - CMP ESTKL+1,X - BCS RLDEX ; YEP, EXIT - LDA TMPH -+ STA (DST),Y ; *ADDR=FIXUP - DEY - LDA TMPL - STA (DST),Y - LDA SRCL ; NEXT ENTRY -; CLC - ADC #$04 - STA SRCL - BCC - - INC SRCH - BNE - -RLDEX INX - LDA TMPL - STA ESTKL,X - LDA TMPH - STA ESTKH,X - LDA DSTL - STA ESTKL+1,X - LDA DSTH - STA ESTKH+1,X - LDA SRCL - STA ESTKL+2,X - LDA SRCH - STA ESTKH+2,X - RTS -end -// // SOS routines // FILE I/O // @@ -793,7 +26,7 @@ def getpfx(path)#1 params.0 = 2 params:1 = path params.3 = 128 - perr = syscall($C7, @params) + syscall($C7, @params) return path end def setpfx(path)#1 @@ -804,69 +37,17 @@ def setpfx(path)#1 params:1 = path params:3 = @fileinfo params.5 = 2 - perr = syscall($C4, @params) // Get file info - if not perr and (fileinfo.1 == $00 or fileinfo.1 == $0F) // Make sure it's a directory + if not syscall($C4, @params) and (fileinfo.1 == $00 or fileinfo.1 == $0F) // Make sure it's a directory params.0 = 1 params:1 = path - perr = syscall($C6, @params) + syscall($C6, @params) else - perr = $44 + getpfx(path) // Get current path fin return path end -def volume(devname, volname)#1 - byte params[9] - - params.0 = 4 - params:1 = devname - params:3 = volname - params:5 = 0 - params:7 = 0 - perr = syscall($C5, @params) - return perr -end -def open(path)#1 - byte params[7] - - params.0 = 4 - params:1 = path - params.3 = 0 - params:4 = 0 - params.6 = 0 - perr = syscall($C8, @params) - return params.3 -end -def close(refnum)#1 - byte params[2] - - params.0 = 1 - params.1 = refnum - perr = syscall($CC, @params) - return perr -end -def read(refnum, buff, len)#1 - byte params[8] - - params.0 = 4 - params.1 = refnum - params:2 = buff - params:4 = len - params:6 = 0 - perr = syscall($CA, @params) - return params:6 -end -def write(refnum, buff, len)#1 - byte params[6] - - params.0 = 3 - params.1 = refnum - params:2 = buff - params:4 = len - perr = syscall($CB, @params) - return perr -end // -// DEVICE I/O +// CONSOLE I/O // def dev_control(devnum, code, list)#1 byte params[5] @@ -875,8 +56,7 @@ def dev_control(devnum, code, list)#1 params.1 = devnum params.2 = code params:3 = list - perr = syscall($83, @params) - return perr + return syscall($83, @params) end def dev_getnum(name)#1 byte params[4] @@ -884,7 +64,7 @@ def dev_getnum(name)#1 params.0 = 2 params:1 = name params.3 = 0 - perr = syscall($84, @params) + syscall($84, @params) return params.3 end def dev_info(devnum, name, list, listlen)#1 @@ -895,390 +75,29 @@ def dev_info(devnum, name, list, listlen)#1 params:2 = name params:4 = list params.6 = listlen - perr = syscall($85, @params) - return perr + return syscall($85, @params) end -// -// MEMORY CALLS -// -def seg_find(search, pages, id)#3 - byte params[10] - - params.0 = 6 - params.1 = search - params.2 = id - params:3 = pages - params:5 = 0 - params:7 = 0 - params.9 = 0 - perr = syscall($41, @params) - return params.9, params:5, params:7 -end -def seg_release(segnum)#1 - byte params[2] - - params.0 = 1 - params.1 = segnum - perr = syscall($45, @params) - return perr -end -// -// CONSOLE I/O -// def init_cons()#0 byte nlmode[2] - if !refcons - refcons = open(@console) + if !cmdsys.refcons + cmdsys.refcons = cmdsys:sysopen(@console) fin - write(refcons, @textmode, 3) - devcons = dev_getnum(@console) - nlmode:0 = $0D80 + cmdsys:syswrite(refcons, @textmode, 3) + cmdsys.devcons = dev_getnum(@console) + nlmode:0 = $0D80 //nlmode.0 = $80 //nlmode.1 = $0D dev_control(devcons, $02, @nlmode) end -def cout(ch)#0 - byte nc - - nc = 1 - if ch == $0D - ch = $0A0D - nc = 2 - fin - write(refcons, @ch, nc) -end -def crout()#0 - cout($0D) -end -def cin()#1 - byte ch - read(refcons, @ch, 1) - return ch & $7F -end -def prstr(str)#0 - write(refcons, str + 1, ^str) - if str->[^str] == $0D - cout($0A) - fin -end -def print(i)#0 - if i < 0; cout('-'); i = -i; fin - if i >= 10; print(i / 10); fin - cout(i % 10 + '0') -end -def rdstr(prompt)#1 - cout(prompt) - ^heap = read(refcons, heap + 1, 128) - if heap->[^heap] == $0D - ^heap-- - fin - crout - return heap -end -def prbyte(v)#0 - cout(hexchar[(v >> 4) & $0F]) - cout(hexchar[v & $0F]) -end -def prword(v)#0 - prbyte(v >> 8) - prbyte(v) -end -// -// Heap routines. -// -def availheap()#1 - byte fp - return @fp - heap -end -def allocheap(size)#1 - word addr - addr = heap - heap = heap + size - if uword_isge(heap, @addr) - return 0 - fin - return addr -end -def allocalignheap(size, pow2, freeaddr)#1 - word align, addr - if freeaddr - *freeaddr = heap - fin - align = (1 << pow2) - 1 - addr = (heap | align) + 1 - heap = addr + size - if uword_isge(heap, @addr) - return 0 - fin - return addr -end -def markheap()#1 - return heap -end -def releaseheap(newheap)#1 - heap = newheap - return @newheap - heap -end -// -// Symbol table routines. -// -def addsym(sym, addr)#0 - while ^sym & $80 - xpokeb(symtbl.0, lastsym, ^sym) - lastsym = lastsym + 1 - sym = sym + 1 - loop - xpokeb(symtbl.0, lastsym, ^sym) - xpokeb(symtbl.0, lastsym + 1, addr.0) - xpokeb(symtbl.0, lastsym + 2, addr.1) - xpokeb(symtbl.0, lastsym + 3, 0) - lastsym = lastsym + 3 -end -// -// String routines. -// -def strcpy(dst, src)#1 - memcpy(dst+1, src+1, ^src) - ^dst = ^src - return dst -end -def strcat(dst, src)#1 - memcpy(dst + ^dst + 1, src + 1, ^src) - ^dst = ^dst + ^src - return dst -end -// -// Module routines. -// -def lookupextern(esd, index)#1 - word sym, addr - byte str[16] - sym = lookupidx(esd, index) - if sym - addr = lookuptbl(sym, symtbl) - if !addr - perr = $81 - dcitos(sym, @str) - cout('?'); prstr(@str); crout - fin - return addr - fin - return 0 -end -def adddef(ext, addr, deflast)#1 - word defentry - defentry = *deflast - *deflast = defentry + 6 - defentry->0 = $20 - defentry=>1 = interp - defentry=>3 = addr - defentry=>5 = ext // ext is byte, so this nulls out next entry - return defentry -end -def loadmod(mod)#1 - word refnum, rdlen, modsize, bytecode, codefix, defofst, defcnt, init, fixup - word addr, defaddr, modaddr, modfix, modofst, modend - word deftbl, deflast, codeseg - word moddep, rld, esd, sym - byte lerr, defext, str[16], filename[33] - byte header[128] - lerr = 0 - // - // Read the RELocatable module header (first 128 bytes) - // - dcitos(mod, @filename) - refnum = open(@filename) - if !refnum - // - // Try system path - // - refnum = open(strcpy(@filename,strcat(strcpy(@header, @sysmods), @filename))) - fin - if refnum - rdlen = read(refnum, @header, 128) - modsize = header:0 - moddep = @header.1 - defofst = modsize + RELADDR - defext = 0 - init = 0 - if rdlen > 4 and header:2 == $6502 // magic number - // - // This is an EXTended RELocatable (data+bytecode) module. - // - systemflags = header:4 | systemflags - defofst = header:6 - defcnt = header:8 - init = header:10 - moddep = @header.12 - // - // Load module dependencies. - // - while ^moddep - if !lookuptbl(moddep, symtbl) - if refnum - close(refnum) - refnum = 0 - fin - if loadmod(moddep) < 0 - return -perr - fin - fin - moddep = moddep + dcitos(moddep, @str) - loop - // - // Init def table. - // - deftbl = allocheap(defcnt * 6 + 1) - deflast = deftbl - ^deflast = 0 - if !refnum - // - // Reset read pointer. - // - refnum = open(@filename) - rdlen = read(refnum, @header, 128) - fin - fin - // - // Alloc heap space for relocated module (data + bytecode). - // - moddep++ - modfix = moddep - @header.2 // Adjust to skip header - modsize = modsize - modfix - rdlen = rdlen - modfix - 2 - modaddr = allocheap(modsize) - memcpy(modaddr, moddep, rdlen) - // - // Read in remainder of module into memory for fixups. - // - addr = modaddr - repeat - addr = addr + rdlen - rdlen = read(refnum, addr, 4096) - until rdlen <= 0 - close(refnum) - // - // Add module to symbol table. - // - addsym(mod, modaddr) - // - // Apply all fixups and symbol import/export. - // - modfix = modaddr - modfix - modofst = modfix - RELADDR - modend = modaddr + modsize - bytecode = defofst + modofst - rld = modend // Re-Locatable Directory - esd = rld // Extern+Entry Symbol Directory - while ^esd // Scan to end of ESD - esd = esd + 4 - loop - esd++ - if defcnt - // - // Locate bytecode defs in allocated segment. - // - modseg[modid], codeseg, drop = seg_find($00, (rld - bytecode + 255) >> 8, modid + $12) - if perr - return -perr - fin - modid++ - defext = codeseg.0 + $7F // (codeseg.0 | $80) - 1 - defaddr = (codeseg & $FF00) + $6000 - codefix = defaddr - bytecode - defofst = defaddr - defofst - fin - // - // Run through the DeFinition Dictionary. - // - while ^rld == $02 - // - // This is a bytcode def entry - add it to the def directory. - // - adddef(defext, rld=>1 + defofst, @deflast) - rld = rld + 4 - loop - // - // Run through the Re-Location Dictionary. - // - while ^rld - rld, addr, fixup = reloc(modfix, modofst, bytecode, rld) - if ^rld - *addr = ^rld & $10 ?? *addr + lookupextern(esd, rld->3) :: lookupdef(fixup + codefix, deftbl) - rld = rld + 4 - fin - //addr = rld=>1 + modfix - //if uword_isge(addr, modaddr) // Skip fixups to header - // if type & $80 // WORD sized fixup. - // fixup = *addr - // else // BYTE sized fixup. - // fixup = ^addr - // fin - // if ^rld & $10 // EXTERN reference. - // fixup = fixup + lookupextern(esd, rld->3) - // else // INTERN fixup. - // fixup = fixup + modofst - // if uword_isge(fixup, bytecode) - // // - // // Bytecode address - replace with call def directory. - // // - // fixup = lookupdef(fixup + codefix, deftbl) - // fin - // fin - // if type & $80 // WORD sized fixup. - // *addr = fixup - // else // BYTE sized fixup. - // ^addr = fixup - // fin - //fin - //rld = rld + 4 - loop - // - // Run through the External/Entry Symbol Directory. - // - while ^esd - sym = esd - esd = esd + dcitos(esd, @str) - if ^esd & $08 - // - // EXPORT symbol - add it to the global symbol table. - // - addr = esd=>1 + modofst - if uword_isge(addr, bytecode) - // - // Use the def directory address for bytecode. - // - addr = lookupdef(addr + codefix, deftbl) - fin - addsym(sym, addr) - fin - esd = esd + 3 - loop - if defext - // - // Copy bytecode to code segment. - // - memxcpy(codeseg, bytecode, modsize - (bytecode - modaddr)) - fin - fin - if lerr - return -lerr - fin - // - // Free up end-of-module main memory. - // - releaseheap(bytecode) - // - // Call init routine if it exists. - // - fixup = 0 - if init - fixup = adddef(defext, init + defofst, @deflast)() - if fixup < 0 - perr = -fixup - fin - fin - return fixup +def volume(devname, volname)#1 + byte params[9] + + params.0 = 4 + params:1 = devname + params:3 = volname + params:5 = 0 + params:7 = 0 + return syscall($C5, @params) end // // Command mode @@ -1291,39 +110,39 @@ def volumes()#0 for i = $01 to $18 if dev_info(i, @devname, @info, 11) == 0 - prstr(@devname) + puts(@devname) if volume(@devname, @volname) == 0 - prstr(" => /") - prstr(@volname) - cout('/') + puts(" => /") + puts(@volname) + putc('/') fin - crout + putln fin next - perr = 0 end def catalog(path)#0 byte refnum byte firstblk byte entrylen, entriesblk byte i, type, len - word entry, filecnt + word entry, filecnt, catptr if !^path path = @prefix fin - refnum = open(path) - if perr + refnum = cmdsys:sysopen(path) + if not refnum return fin + catptr = heapmark firstblk = 1 repeat - if read(refnum, heap, 512) == 512 - entry = heap + 4 + if cmdsys:sysread(refnum, catptr, 512) == 512 + entry = catptr + 4 if firstblk - entrylen = heap->$23 - entriesblk = heap->$24 - filecnt = heap=>$25 + entrylen = catptr->$23 + entriesblk = catptr->$24 + filecnt = catptr=>$25 entry = entry + entrylen fin for i = firstblk to entriesblk @@ -1331,7 +150,7 @@ def catalog(path)#0 if type len = type & $0F ^entry = len - prstr(entry) + puts(entry) type = ' ' when entry->$10 is $0F // Is it a directory? @@ -1343,9 +162,9 @@ def catalog(path)#0 is $FE // REL file type = '+' wend - cout(type) + putc(type) for len = 18 - len downto 0 - cout(' ') + putc(' ') next filecnt-- fin @@ -1356,8 +175,8 @@ def catalog(path)#0 filecnt = 0 fin until filecnt == 0 - close(refnum) - crout() + cmdsys:sysclose(refnum) + putln() end def stripchars(strptr)#1 while ^strptr and ^(strptr + 1) > ' ' @@ -1399,30 +218,6 @@ def parsecmd(strptr)#1 stripspaces(strptr) return cmd end -def execmod(modfile)#1 - byte moddci[17] - word saveheap, savesym, saveflags - - perr = 1 - if stodci(modfile, @moddci) - saveheap = heap - savesym = lastsym - saveflags = systemflags - if loadmod(@moddci) < modkeep - lastsym = savesym - heap = saveheap - while modid - modid-- - seg_release(modseg[modid]) - loop - else - modid = 0 - fin - xpokeb(symtbl.0, lastsym, 0) - systemflags = saveflags - fin - return -perr -end // // Init console. // @@ -1430,42 +225,24 @@ init_cons // // Print PLASMA version // -prstr("PLASMA 2.0 Dev\n")//; prbyte(version.1); cout('.'); prbyte(version.0); crout -// -// Init 2K symbol table. -// -drop, symtbl, drop = seg_find($00, $08, $11) -lastsym = symtbl & $FF00 -xpokeb(symtbl.0, lastsym, 0) -while *sysmodsym - stodci(sysmodsym=>0, heap) - addsym(heap, sysmodsym=>2) - sysmodsym = sysmodsym + 4 -loop -// -// Clear system path -// -sysmods = 0 -syspath = @sysmods +puts("PLASMA 2.0 Dev\n")//; prbyte(version.1); cout('.'); prbyte(version.0); crout // // Try to load autorun. // -cmdlnptr = @cmdln -cmdptr = heap +cmdptr = heapmark ^cmdptr = 0 -autorun = open(@autorun) +autorun = cmdsys:sysopen("AUTORUN") if autorun > 0 - ^cmdptr = read(autorun, cmdptr + 1, 64) - close(autorun) + ^cmdptr = cmdsys:sysread(autorun, cmdptr + 1, 64) + cmdsys:sysclose(autorun) else // // Print some startup info. // - prstr("MEM:$") - prword(availheap) - crout + puts("MEM:$") + puth(heapavail) + putln fin -perr = 0 // // Handle commands. // @@ -1493,32 +270,32 @@ while 1 break is 'S' setpfx(cmdptr) - strcat(getpfx(@sysmods), "SYS/")) + strcat(getpfx(cmdsys:syspath), "SYS/")) break is 'V' volumes break is '+' saveX - execmod(striptrail(cmdptr)) + cmdsys:modexec(striptrail(cmdptr)) restoreX //close(0) init_cons break otherwise - prstr("?\n") + puts("?\n") wend - if perr - terr = perr - prstr("ERR:$") - prbyte(terr) + if cmdsys.syserr + err = cmdsys.syserr + puts("ERR:$") + putb(err) else - prstr("OK") + puts("OK") fin - crout() + putln fin - prstr(getpfx(@prefix)) - cmdptr = rdstr($BA) - strcpy(@cmdln, cmdptr) + puts(getpfx(@prefix)) + cmdptr = gets($BA) + strcpy(cmdsys:cmdline, cmdptr) loop done diff --git a/src/vmsrc/apple/sossys.pla b/src/vmsrc/apple/sossys.pla new file mode 100755 index 0000000..674db6f --- /dev/null +++ b/src/vmsrc/apple/sossys.pla @@ -0,0 +1,1229 @@ +const membank = $FFEF +const RELADDR = $1000 +// +// System flags: memory allocator screen holes. +// +const restxt1 = $0001 +const restxt2 = $0002 +const resxtxt1 = $0004 +const resxtxt2 = $0008 +const reshgr1 = $0010 +const reshgr2 = $0020 +const resxhgr1 = $0040 +const resxhgr2 = $0080 +// +// Module don't free memory +// +const modkeep = $2000 +const modinitkeep = $4000 +// +// Pedefined functions. +// +predef syscall(cmd,params)#1, call(addr,areg,xreg,yreg,status)#1 +predef crout()#0, cout(c)#0, prstr(s)#0, print(i)#0, prbyte(b)#0, prword(w)#0 +predef cin()#1, rdstr(p)#1, toupper(c)#1, strcpy(dst,src)#1, strcat(dst,src)#1 +predef markheap()#1, allocheap(size)#1, allocalignheap(size, pow2, freeaddr), releaseheap(newheap)#1, availheap()#1 +predef memset(addr,value,size)#0, memcpy(dst,src,size)#0 +predef uword_isgt(a,b)#1, uword_isge(a,b)#1, uword_islt(a,b)#1, uword_isle(a,b)#1, sext(a)#1, divmod(a,b)#2 +predef execmod(modfile)#1, open(path)#1, close(refnum)#1, read(refnum, buff, len)#1, write(refnum, buff, len)#1 +// +// Exported CMDSYS table +// +word version = $0200 // 02.00 +word syspath +word cmdlnptr +word = @execmod, @open, @close, @read, @write +byte refcons = 0 +byte devcons = 0 +byte modid = 0 +// +// String pool. +// +byte hexchar[] = '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' +// +// Exported Machine ID. +// +byte machid = $F2 // Apple ///, 80 columns +// +// Working input buffer overlayed with strings table +// +byte cmdln = "" +// +// Standard Library exported functions. +// +byte sysmodstr[] = "CMDSYS" +byte machidstr[] = "MACHID" +byte sysstr[] = "SYSCALL" +byte callstr[] = "CALL" +byte putcstr[] = "PUTC" +byte putlnstr[] = "PUTLN" +byte putsstr[] = "PUTS" +byte putistr[] = "PUTI" +byte putbstr[] = "PUTB" +byte putwstr[] = "PUTH" +byte getcstr[] = "GETC" +byte getsstr[] = "GETS" +byte toupstr[] = "TOUPPER" +byte strcpystr[] = "STRCPY" +byte strcatstr[] = "STRCAT" +byte hpmarkstr[] = "HEAPMARK" +byte hpalignstr[] = "HEAPALLOCALIGN" +byte hpallocstr[] = "HEAPALLOC" +byte hprelstr[] = "HEAPRELEASE" +byte hpavlstr[] = "HEAPAVAIL" +byte memsetstr[] = "MEMSET" +byte memcpystr[] = "MEMCPY" +byte uisgtstr[] = "ISUGT" +byte uisgestr[] = "ISUGE" +byte uisltstr[] = "ISULT" +byte uislestr[] = "ISULE" +byte sextstr[] = "SEXT" +byte divmodstr[] = "DIVMOD" +byte sysmods[] = "" // overlay sys path with exports +word exports[] = @sysmodstr, @version +word = @sysstr, @syscall +word = @callstr, @call +word = @putcstr, @cout +word = @putlnstr, @crout +word = @putsstr, @prstr +word = @putistr, @print +word = @putbstr, @prbyte +word = @putwstr, @prword +word = @getcstr, @cin +word = @getsstr, @rdstr +word = @toupstr, @toupper +word = @hpmarkstr, @markheap +word = @hpallocstr,@allocheap +word = @hpalignstr,@allocalignheap +word = @hprelstr, @releaseheap +word = @hpavlstr, @availheap +word = @memsetstr, @memset +word = @memcpystr, @memcpy +word = @strcpystr, @strcpy +word = @strcatstr, @strcat +word = @uisgtstr, @uword_isgt +word = @uisgestr, @uword_isge +word = @uisltstr, @uword_islt +word = @uislestr, @uword_isle +word = @sextstr, @sext +word = @divmodstr, @divmod +word = @machidstr, @machid +word = 0 +word sysmodsym = @exports +// +// System variables. +// +word systemflags = 0 +word heap = $2000 +byte modseg[15] +word symtbl, lastsym +byte perr +// +// CALL SOS +// SYSCALL(CMD, PARAMS) +// +asm syscall(cmd,params)#1 + LDA ESTKL,X + LDY ESTKH,X + STA PARAMS + STY PARAMS+1 + INX + LDA ESTKL,X + STA CMD + BRK +CMD !BYTE 00 +PARAMS !WORD 0000 + LDY #$00 + STA ESTKL,X + STY ESTKH,X + RTS +end +// +// CALL 6502 ROUTINE +// CALL(AREG, XREG, YREG, STATUS, ADDR) +// +asm call(addr,areg,xreg,yreg,sstatus)#1 +REGVALS = SRC + PHP + LDA ESTKL,X + STA TMPL + LDA ESTKH,X + STA TMPH + INX + LDA ESTKL,X + PHA + INX + LDY ESTKL,X + INX + LDA ESTKL+1,X + PHA + LDA ESTKL,X + INX + STX ESP + TAX + PLA + PLP + JSR JMPTMP + PHP + STA REGVALS+0 + STX REGVALS+1 + STY REGVALS+2 + PLA + STA REGVALS+3 + LDX ESP + LDA #REGVALS + STA ESTKL,X + STY ESTKH,X + PLP + RTS +end +// +// SET MEMORY TO VALUE +// MEMSET(ADDR, VALUE, SIZE) +// With optimizations from Peter Ferrie +// +asm memset(addr,value,size)#0 + LDA ESTKL+2,X + STA DSTL + LDA ESTKH+2,X + STA DSTH + LDY ESTKL,X + BEQ + + INC ESTKH,X + LDY #$00 ++ LDA ESTKH,X + BEQ SETMEX +SETMLPL CLC + LDA ESTKL+1,X +SETMLPH STA (DST),Y + DEC ESTKL,X + BEQ ++ +- INY + BEQ + +-- BCS SETMLPL + SEC + LDA ESTKH+1,X + BCS SETMLPH ++ INC DSTH + BNE -- +++ DEC ESTKH,X + BNE - +SETMEX INX + INX + INX + RTS +end +// +// COPY MEMORY +// MEMCPY(DSTADDR, SRCADDR, SIZE) +// +asm memcpy(dst,src,size)#0 + INX + INX + INX + LDA ESTKL-3,X + ORA ESTKH-3,X + BEQ CPYMEX + LDA ESTKL-2,X + CMP ESTKL-1,X + LDA ESTKH-2,X + SBC ESTKH-1,X + BCC REVCPY +; +; FORWARD COPY +; + LDA ESTKL-1,X + STA DSTL + LDA ESTKH-1,X + STA DSTH + LDA ESTKL-2,X + STA SRCL + LDA ESTKH-2,X + STA SRCH + LDY ESTKL-3,X + BEQ FORCPYLP + INC ESTKH-3,X + LDY #$00 +FORCPYLP LDA (SRC),Y + STA (DST),Y + INY + BNE + + INC DSTH + INC SRCH ++ DEC ESTKL-3,X + BNE FORCPYLP + DEC ESTKH-3,X + BNE FORCPYLP + RTS +; +; REVERSE COPY +; +REVCPY ;CLC + LDA ESTKL-3,X + ADC ESTKL-1,X + STA DSTL + LDA ESTKH-3,X + ADC ESTKH-1,X + STA DSTH + CLC + LDA ESTKL-3,X + ADC ESTKL-2,X + STA SRCL + LDA ESTKH-3,X + ADC ESTKH-2,X + STA SRCH + DEC DSTH + DEC SRCH + LDY #$FF + LDA ESTKL-3,X + BEQ REVCPYLP + INC ESTKH-3,X +REVCPYLP LDA (SRC),Y + STA (DST),Y + DEY + CPY #$FF + BNE + + DEC DSTH + DEC SRCH ++ DEC ESTKL-3,X + BNE REVCPYLP + DEC ESTKH-3,X + BNE REVCPYLP +CPYMEX RTS +end +// +// COPY FROM MAIN MEM TO EXT MEM. +// +// MEMXCPY(DSTSEG, SRC, SIZE) +// +asm memxcpy(dst,src,size)#0 + LDA ESTKL,X + ORA ESTKH,X + BEQ CPYXMEX + LDY #$00 + STY DSTL + LDA ESTKH+2,X + CLC + ADC #$60 + STA DSTH + LDA ESTKL+2,X + CLC + ADC #$7F + STA DSTX + LDA ESTKL+1,X + STA SRCL + LDA ESTKH+1,X + STA SRCH + INC ESTKH,X +CPYXLP LDA (SRC),Y + STA (DST),Y + INY + BNE + + INC DSTH + INC SRCH ++ DEC ESTKL,X + BNE CPYXLP + DEC ESTKH,X + BNE CPYXLP + LDA #$00 + STA DSTX +CPYXMEX INX + INX + INX + RTS +end +// +// POKE BYTE VAL INTO EXT MEM. +// +// XPOKEB(SEG, DST, BYTEVAL) +// +asm xpokeb(seg, dst, byteval)#0 + LDA ESTKL+1,X + STA DSTL + LDA ESTKH+1,X + CLC + ADC #$60 + STA DSTH + LDA ESTKL+2,X + CLC + ADC #$7F + STA DSTX + LDY #$00 + LDA ESTKL,X + STA (DST),Y + STY DSTX + INX + INX + INX + RTS +end +// +// Unsigned word comparisons. +// +asm uword_isge(a,b)#1 + LDA ESTKL+1,X + CMP ESTKL,X + LDA ESTKH+1,X + SBC ESTKH,X + LDA #$FF + ADC #$00 + EOR #$FF + STA ESTKL+1,X + STA ESTKH+1,X + INX + RTS +end +asm uword_isle(a,b)#1 + LDA ESTKL,X + CMP ESTKL+1,X + LDA ESTKH,X + SBC ESTKH+1,X + LDA #$FF + ADC #$00 + EOR #$FF + STA ESTKL+1,X + STA ESTKH+1,X + INX + RTS +end +asm uword_isgt(a,b)#1 + LDA ESTKL,X + CMP ESTKL+1,X + LDA ESTKH,X + SBC ESTKH+1,X + LDA #$FF + ADC #$00 + STA ESTKL+1,X + STA ESTKH+1,X + INX + RTS +end +asm uword_islt(a,b)#1 + LDA ESTKL+1,X + CMP ESTKL,X + LDA ESTKH+1,X + SBC ESTKH,X + LDA #$FF + ADC #$00 + STA ESTKL+1,X + STA ESTKH+1,X + INX + RTS +end +asm divmod(a,b)#2 + JSR INTERP ; CALL INTERP + !BYTE $36, $5C ; DIVMOD, RET +end +asm sext(a)#1 + LDY #$00 + LDA ESTKL,X + BPL + + DEY ++ STY ESTKH,X + RTS +end +// +// Addresses of internal routines. +// +asm interp()#1 + DEX + LDA #XINTERP + STA ESTKH,X + RTS +end +// +// A DCI string is one that has the high bit set for every character except the last. +// More efficient than C or Pascal strings. +// +//def dcitos(dci, str) +// byte len, c +// len = 0 +// repeat +// c = (dci).[len] +// len = len + 1 +// (str).[len] = c & $7F +// until !(c & $80) +// ^str = len +// return len +//end +asm dcitos(dci, str)#1 + LDA ESTKL,X + STA DSTL + LDA ESTKH,X + STA DSTH + LDA ESTKL+1,X + STA SRCL + LDA ESTKH+1,X + STA SRCH + LDY #$00 +- LDA (SRC),Y + CMP #$80 + AND #$7F + INY + STA (DST),Y + BCS - + TYA + LDY #$00 + STA (DST),Y + INX + STA ESTKL,X + STY ESTKH,X + RTS +end +//def stodci(str, dci) +// byte len, c +// len = ^str +// if len == 0 +// return +// fin +// c = toupper((str).[len]) & $7F +// len = len - 1 +// (dci).[len] = c +// while len +// c = toupper((str).[len]) | $80 +// len = len - 1 +// (dci).[len] = c +// loop +// return ^str +//end +asm stodci(str, dci)#1 + LDA ESTKL,X + STA DSTL + LDA ESTKH,X + STA DSTH + LDA ESTKL+1,X + STA SRCL + LDA ESTKH+1,X + STA SRCH + INX + LDY #$00 + LDA (SRC),Y + BEQ ++ + TAY + LDA (SRC),Y + JSR TOUPR + BNE + +- LDA (SRC),Y + JSR TOUPR + ORA #$80 ++ DEY + STA (DST),Y + BNE - + LDA (SRC),Y +++ STA ESTKL,X + STY ESTKH,X + RTS +end +asm toupper(c)#1 + LDA ESTKL,X +TOUPR AND #$7F + CMP #'a' + BCC + + CMP #'z'+1 + BCS + + SBC #$1F ++ STA ESTKL,X + RTS +end +// +// Lookup routines. +// +//def lookuptbl(dci, tbl) +// word match +// while ^tbl +// match = dci +// while ^tbl == ^match +// if !(^tbl & $80) +// return (tbl):1 +// fin +// tbl = tbl + 1 +// match = match + 1 +// loop +// while (^tbl & $80) +// tbl = tbl + 1 +// loop +// tbl = tbl + 3 +// loop +// return 0 +asm lookuptbl(dci, tbl)#1 + LDY #$00 + STY DSTL + LDA ESTKH,X + CLC + ADC #$60 + STA DSTH + LDA ESTKL,X + CLC + ADC #$7F + STA DSTX + LDA ESTKL+1,X + STA SRCL + LDA ESTKH+1,X + STA SRCH +- LDA (DST),Y + BEQ + + CMP (SRC),Y + BNE ++ + INY + ASL + BCS - + LDA (DST),Y + PHA + INY + LDA (DST),Y + TAY + PLA ++ INX + STA ESTKL,X + STY ESTKH,X + LDA #$00 + STA DSTX + RTS +++ LDY #$00 +-- LDA (DST),Y + INC DSTL + BEQ + +--- ASL + BCS -- + LDA #$02 + ADC DSTL + STA DSTL + BCC - + INC DSTH + BCS - ++ INC DSTH + BNE --- +end +// def lookupidx(esd, index) +// word sym +// while ^esd +// sym = esd +// esd = sym + dcitos(sym, @str) +// if esd->0 & $10 and esd->1 == index +// return sym +// fin +// esd = esd + 3 +// loop +//end +asm lookupidx(esd, index)#1 + LDA ESTKL,X + STA TMPL + INX +--- LDA ESTKH,X + STA SRCH + LDA ESTKL,X +-- STA SRCL + LDY #$00 +- LDA (SRC),Y + BPL + + INY + BNE - ++ BEQ ++ ; END OF ESD + INY + LDA (SRC),Y + INY + AND #$10 ; EXTERN FLAG? + BEQ + + LDA (SRC),Y + CMP TMPL + BEQ +++ ; MATCH ++ INY + TYA + SEC + ADC SRCL + STA ESTKL,X ; SYM PTRL + BCC -- + INC ESTKH,X ; SYM PTRH + BNE --- +++ STA ESTKL,X ; END OF ESD + STA ESTKH,X ++++ RTS +end +//def lookupdef(addr, deftbl)#1 +// while deftbl->0 == $20 +// if deftbl=>3 == addr +// return deftbl +// fin +// deftbl = deftbl + 6 +// loop +// return 0 +//end +asm lookupdef(addr, deftbl)#1 + LDA ESTKH,X + STA SRCH + LDA ESTKL,X + STA SRCL + INX +- LDY #$00 + LDA (SRC),Y + CMP #$20 ; JSR OPCODE? + BNE ++ + LDY #$03 + LDA (SRC),Y + CMP ESTKL,X + BNE + + INY + LDA (SRC),Y + CMP ESTKH,X + BNE + + LDA SRCL ; MATCH + STA ESTKL,X + LDA SRCH + STA ESTKH,X + RTS ++ LDA #$06 + CLC + ADC SRCL + STA SRCL + BCC - + INC SRCH + BNE - +++ STY ESTKL,X + STY ESTKH,X + RTS +end +// +// Reloc internal data +// +//def reloc(modfix, modofst, bytecode, rld)#3 +// word addr, fixup +// while ^rld +// if ^rld & $10 // EXTERN reference. +// return rld, addr, fixup +// fin +// addr = rld=>1 + modfix +// fixup = *addr + modofst +// if uword_isge(fixup, bytecode) // Bytecode address. +// return rld, addr, fixup +// fin +// *addr = fixup +// rld = rld + 4 +// loop +// return rld, addr, fixup +//end +asm reloc(modfix, modofst, bytecode, rld)#3 + LDA ESTKL,X + STA SRCL + LDA ESTKH,X + STA SRCH + LDY #$00 +- LDA (SRC),Y + BEQ RLDEX ; END OF RLD + PHA + INY + LDA (SRC),Y + INY + CLC + ADC ESTKL+3,X ; ADDR=ENTRY=>1+MODFIX + STA DSTL + LDA (SRC),Y + ADC ESTKH+3,X + STA DSTH + PLA + AND #$10 ; EXTERN REF - EXIT + BNE RLDEX + TAY ; FIXUP=*ADDR+MODOFST + LDA (DST),Y + INY + CLC + ADC ESTKL+2,X + STA TMPL + LDA (DST),Y + ADC ESTKH+2,X + CMP ESTKH+1,X ; FIXUP >= BYTECODE? + BCC + + STA TMPH + BNE RLDEX ; YEP, EXIT + LDA TMPL + CMP ESTKL+1,X + BCS RLDEX ; YEP, EXIT + LDA TMPH ++ STA (DST),Y ; *ADDR=FIXUP + DEY + LDA TMPL + STA (DST),Y + LDA SRCL ; NEXT ENTRY +; CLC + ADC #$04 + STA SRCL + BCC - + INC SRCH + BNE - +RLDEX INX + LDA TMPL + STA ESTKL,X + LDA TMPH + STA ESTKH,X + LDA DSTL + STA ESTKL+1,X + LDA DSTH + STA ESTKH+1,X + LDA SRCL + STA ESTKL+2,X + LDA SRCH + STA ESTKH+2,X + RTS +end +// +// SOS routines +// FILE I/O +// +def open(path)#1 + byte params[7] + + params.0 = 4 + params:1 = path + params.3 = 0 + params:4 = 0 + params.6 = 0 + perr = syscall($C8, @params) + return params.3 +end +def close(refnum)#1 + byte params[2] + + params.0 = 1 + params.1 = refnum + perr = syscall($CC, @params) + return perr +end +def read(refnum, buff, len)#1 + byte params[8] + + params.0 = 4 + params.1 = refnum + params:2 = buff + params:4 = len + params:6 = 0 + perr = syscall($CA, @params) + return params:6 +end +def write(refnum, buff, len)#1 + byte params[6] + + params.0 = 3 + params.1 = refnum + params:2 = buff + params:4 = len + perr = syscall($CB, @params) + return perr +end +// +// MEMORY CALLS +// +def seg_find(search, pages, id)#3 + byte params[10] + + params.0 = 6 + params.1 = search + params.2 = id + params:3 = pages + params:5 = 0 + params:7 = 0 + params.9 = 0 + perr = syscall($41, @params) + return params.9, params:5, params:7 +end +def seg_release(segnum)#1 + byte params[2] + + params.0 = 1 + params.1 = segnum + perr = syscall($45, @params) + return perr +end +// +// CONSOLE I/O +// +def cout(ch)#0 + byte nc + + nc = 1 + if ch == $0D + ch = $0A0D + nc = 2 + fin + write(refcons, @ch, nc) +end +def crout()#0 + cout($0D) +end +def cin()#1 + byte ch + read(refcons, @ch, 1) + return ch & $7F +end +def prstr(str)#0 + write(refcons, str + 1, ^str) + if str->[^str] == $0D + cout($0A) + fin +end +def print(i)#0 + if i < 0; cout('-'); i = -i; fin + if i >= 10; print(i / 10); fin + cout(i % 10 + '0') +end +def rdstr(prompt)#1 + cout(prompt) + ^heap = read(refcons, heap + 1, 128) + if heap->[^heap] == $0D + ^heap-- + fin + crout + return heap +end +def prbyte(v)#0 + cout(hexchar[(v >> 4) & $0F]) + cout(hexchar[v & $0F]) +end +def prword(v)#0 + prbyte(v >> 8) + prbyte(v) +end +// +// Heap routines. +// +def availheap()#1 + byte fp + return @fp - heap +end +def allocheap(size)#1 + word addr + addr = heap + heap = heap + size + if uword_isge(heap, @addr) + return 0 + fin + return addr +end +def allocalignheap(size, pow2, freeaddr)#1 + word align, addr + if freeaddr + *freeaddr = heap + fin + align = (1 << pow2) - 1 + addr = (heap | align) + 1 + heap = addr + size + if uword_isge(heap, @addr) + return 0 + fin + return addr +end +def markheap()#1 + return heap +end +def releaseheap(newheap)#1 + heap = newheap + return @newheap - heap +end +// +// Symbol table routines. +// +def addsym(sym, addr)#0 + while ^sym & $80 + xpokeb(symtbl.0, lastsym, ^sym) + lastsym = lastsym + 1 + sym = sym + 1 + loop + xpokeb(symtbl.0, lastsym, ^sym) + xpokeb(symtbl.0, lastsym + 1, addr.0) + xpokeb(symtbl.0, lastsym + 2, addr.1) + xpokeb(symtbl.0, lastsym + 3, 0) + lastsym = lastsym + 3 +end +// +// String routines. +// +def strcpy(dst, src)#1 + memcpy(dst+1, src+1, ^src) + ^dst = ^src + return dst +end +def strcat(dst, src)#1 + memcpy(dst + ^dst + 1, src + 1, ^src) + ^dst = ^dst + ^src + return dst +end +// +// Module routines. +// +def lookupextern(esd, index)#1 + word sym, addr + byte str[16] + sym = lookupidx(esd, index) + if sym + addr = lookuptbl(sym, symtbl) + if !addr + perr = $81 + dcitos(sym, @str) + cout('?'); prstr(@str); crout + fin + return addr + fin + return 0 +end +def adddef(ext, addr, deflast)#1 + word defentry + defentry = *deflast + *deflast = defentry + 6 + defentry->0 = $20 + defentry=>1 = interp + defentry=>3 = addr + defentry=>5 = ext // ext is byte, so this nulls out next entry + return defentry +end +def loadmod(mod)#1 + word refnum, rdlen, modsize, bytecode, codefix, defofst, defcnt, init, fixup + word addr, defaddr, modaddr, modfix, modofst, modend + word deftbl, deflast, codeseg + word moddep, rld, esd, sym + byte lerr, defext, str[16], filename[33] + byte header[128] + lerr = 0 + // + // Read the RELocatable module header (first 128 bytes) + // + dcitos(mod, @filename) + refnum = open(@filename) + if !refnum + // + // Try system path + // + refnum = open(strcpy(@filename,strcat(strcpy(@header, @sysmods), @filename))) + fin + if refnum + rdlen = read(refnum, @header, 128) + modsize = header:0 + moddep = @header.1 + defofst = modsize + RELADDR + defext = 0 + init = 0 + if rdlen > 4 and header:2 == $6502 // magic number + // + // This is an EXTended RELocatable (data+bytecode) module. + // + systemflags = header:4 | systemflags + defofst = header:6 + defcnt = header:8 + init = header:10 + moddep = @header.12 + // + // Load module dependencies. + // + while ^moddep + if !lookuptbl(moddep, symtbl) + if refnum + close(refnum) + refnum = 0 + fin + if loadmod(moddep) < 0 + return -perr + fin + fin + moddep = moddep + dcitos(moddep, @str) + loop + // + // Init def table. + // + deftbl = allocheap(defcnt * 6 + 1) + deflast = deftbl + ^deflast = 0 + if !refnum + // + // Reset read pointer. + // + refnum = open(@filename) + rdlen = read(refnum, @header, 128) + fin + fin + // + // Alloc heap space for relocated module (data + bytecode). + // + moddep++ + modfix = moddep - @header.2 // Adjust to skip header + modsize = modsize - modfix + rdlen = rdlen - modfix - 2 + modaddr = allocheap(modsize) + memcpy(modaddr, moddep, rdlen) + // + // Read in remainder of module into memory for fixups. + // + addr = modaddr + repeat + addr = addr + rdlen + rdlen = read(refnum, addr, 4096) + until rdlen <= 0 + close(refnum) + // + // Add module to symbol table. + // + addsym(mod, modaddr) + // + // Apply all fixups and symbol import/export. + // + modfix = modaddr - modfix + modofst = modfix - RELADDR + modend = modaddr + modsize + bytecode = defofst + modofst + rld = modend // Re-Locatable Directory + esd = rld // Extern+Entry Symbol Directory + while ^esd // Scan to end of ESD + esd = esd + 4 + loop + esd++ + if defcnt + // + // Locate bytecode defs in allocated segment. + // + modseg[modid], codeseg, drop = seg_find($00, (rld - bytecode + 255) >> 8, modid + $12) + if perr + return -perr + fin + modid++ + defext = codeseg.0 + $7F // (codeseg.0 | $80) - 1 + defaddr = (codeseg & $FF00) + $6000 + codefix = defaddr - bytecode + defofst = defaddr - defofst + fin + // + // Run through the DeFinition Dictionary. + // + while ^rld == $02 + // + // This is a bytcode def entry - add it to the def directory. + // + adddef(defext, rld=>1 + defofst, @deflast) + rld = rld + 4 + loop + // + // Run through the Re-Location Dictionary. + // + while ^rld + rld, addr, fixup = reloc(modfix, modofst, bytecode, rld) + if ^rld + *addr = ^rld & $10 ?? *addr + lookupextern(esd, rld->3) :: lookupdef(fixup + codefix, deftbl) + rld = rld + 4 + fin + //addr = rld=>1 + modfix + //if uword_isge(addr, modaddr) // Skip fixups to header + // if type & $80 // WORD sized fixup. + // fixup = *addr + // else // BYTE sized fixup. + // fixup = ^addr + // fin + // if ^rld & $10 // EXTERN reference. + // fixup = fixup + lookupextern(esd, rld->3) + // else // INTERN fixup. + // fixup = fixup + modofst + // if uword_isge(fixup, bytecode) + // // + // // Bytecode address - replace with call def directory. + // // + // fixup = lookupdef(fixup + codefix, deftbl) + // fin + // fin + // if type & $80 // WORD sized fixup. + // *addr = fixup + // else // BYTE sized fixup. + // ^addr = fixup + // fin + //fin + //rld = rld + 4 + loop + // + // Run through the External/Entry Symbol Directory. + // + while ^esd + sym = esd + esd = esd + dcitos(esd, @str) + if ^esd & $08 + // + // EXPORT symbol - add it to the global symbol table. + // + addr = esd=>1 + modofst + if uword_isge(addr, bytecode) + // + // Use the def directory address for bytecode. + // + addr = lookupdef(addr + codefix, deftbl) + fin + addsym(sym, addr) + fin + esd = esd + 3 + loop + if defext + // + // Copy bytecode to code segment. + // + memxcpy(codeseg, bytecode, modsize - (bytecode - modaddr)) + fin + fin + if lerr + return -lerr + fin + // + // Free up end-of-module main memory. + // + releaseheap(bytecode) + // + // Call init routine if it exists. + // + fixup = 0 + if init + fixup = adddef(defext, init + defofst, @deflast)() + if fixup < 0 + perr = -fixup + fin + fin + return fixup +end +def execmod(modfile)#1 + byte moddci[17] + word saveheap, savesym, saveflags + + perr = 1 + if stodci(modfile, @moddci) + saveheap = heap + savesym = lastsym + saveflags = systemflags + if loadmod(@moddci) < modkeep + lastsym = savesym + heap = saveheap + while modid + modid-- + seg_release(modseg[modid]) + loop + else + modid = 0 + fin + xpokeb(symtbl.0, lastsym, 0) + systemflags = saveflags + fin + return -perr +end +// +// Init 2K symbol table. +// +drop, symtbl, drop = seg_find($00, $08, $11) +lastsym = symtbl & $FF00 +xpokeb(symtbl.0, lastsym, 0) +while *sysmodsym + stodci(sysmodsym=>0, heap) + addsym(heap, sysmodsym=>2) + sysmodsym = sysmodsym + 4 +loop +// +// Clear system path and command line +// +sysmods = 0 +syspath = @sysmods +cmdlnptr = @cmdln +// +// Exec command line parser +// +execmod("SOS.CMD") +done From a9237f58cc1f1bcac2b3aa86cb09d070c94982c9 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Sat, 17 Mar 2018 15:52:15 -0700 Subject: [PATCH 058/147] Sync cmd exported sysroutines --- src/makefile | 2 +- src/vmsrc/apple/cmd.pla | 17 ++++++++++++++--- src/vmsrc/apple/soscmd.pla | 14 ++++++++------ src/vmsrc/apple/sossys.pla | 4 ++-- 4 files changed, 25 insertions(+), 12 deletions(-) diff --git a/src/makefile b/src/makefile index 82e749c..3c94fc5 100755 --- a/src/makefile +++ b/src/makefile @@ -6,7 +6,7 @@ PLVM01 = rel/apple/A1PLASMA\#060280 PLVM02 = rel/apple/PLASMA.SYSTEM\#FF2000 PLVM802 = rel/apple/PLASMA16.SYSTEM\#FF2000 PLVM03 = rel/apple/SOS.INTERP\#050000 -SOSCMD = rel/apple/SOS.CMD\#0FE1000 +SOSCMD = rel/apple/SOS.CMD\#FE1000 CMD = rel/apple/CMD\#061000 PLVMZP_C64 = vmsrc/c64/plvmzp.inc PLVMC64 = rel/c64/PLASMA diff --git a/src/vmsrc/apple/cmd.pla b/src/vmsrc/apple/cmd.pla index 5457b4e..367a250 100755 --- a/src/vmsrc/apple/cmd.pla +++ b/src/vmsrc/apple/cmd.pla @@ -34,14 +34,15 @@ predef crout()#0, cout(c)#0, prstr(s)#0, prbyte(b)#0, prword(w)#0, print(i)#0, c predef markheap()#1, allocheap(size)#1, allocalignheap(size, pow2, freeaddr)#1, releaseheap(newheap)#1, availheap()#1 predef memset(addr,value,size)#0, memcpy(dst,src,size)#0, strcpy(dst,src)#1, strcat(dst,src)#1 predef uword_isgt(a,b)#1, uword_isge(a,b)#1, uword_islt(a,b)#1, uword_isle(a,b)#1, sext(a)#1, divmod(a,b)#2 -predef execmod(modfile)#1 +predef execmod(modfile)#1, open(path)#1, close(refnum)#1, read(refnum, buff, len)#1, write(refnum, buff, len)#1 // // Exported CMDSYS table // word version = $0200 // 02.00 Dev word syspath word syscmdln -word = @execmod +word = @execmod, @open, @close, @read, @write +byte perr // // Working input buffer overlayed with strings table // @@ -117,7 +118,6 @@ word sysmodsym = @exports // System variable. // word systemflags = 0 -byte perr word heap word xheap = $0800 word lastsym = symtbl @@ -898,6 +898,17 @@ def read(refnum, buff, len)#1 perr = syscall($CA, @params) return params:6 end +def write(refnum, buf, len)#1 + byte params[8] + + params.0 = 4 + params.1 = refnum + params:2 = buf + params:4 = len + params:6 = 0 + perr = syscall($CB, @params) + return params:6 +end // // Heap routines. // diff --git a/src/vmsrc/apple/soscmd.pla b/src/vmsrc/apple/soscmd.pla index 02d8b3d..2a0697b 100755 --- a/src/vmsrc/apple/soscmd.pla +++ b/src/vmsrc/apple/soscmd.pla @@ -79,15 +79,13 @@ def dev_info(devnum, name, list, listlen)#1 end def init_cons()#0 byte nlmode[2] - if !cmdsys.refcons - cmdsys.refcons = cmdsys:sysopen(@console) - fin - cmdsys:syswrite(refcons, @textmode, 3) + cmdsys.refcons = cmdsys:sysopen(@console) + cmdsys:syswrite(cmdsys.refcons, @textmode, 3) cmdsys.devcons = dev_getnum(@console) nlmode:0 = $0D80 //nlmode.0 = $80 //nlmode.1 = $0D - dev_control(devcons, $02, @nlmode) + dev_control(cmdsys.devcons, $02, @nlmode) end def volume(devname, volname)#1 byte params[9] @@ -219,6 +217,10 @@ def parsecmd(strptr)#1 return cmd end // +// Clear out module memory segment +// +cmdsys.modid = 0 +// // Init console. // init_cons @@ -279,7 +281,7 @@ while 1 saveX cmdsys:modexec(striptrail(cmdptr)) restoreX - //close(0) + cmdsys:sysclose(0) init_cons break otherwise diff --git a/src/vmsrc/apple/sossys.pla b/src/vmsrc/apple/sossys.pla index 674db6f..9e12fa4 100755 --- a/src/vmsrc/apple/sossys.pla +++ b/src/vmsrc/apple/sossys.pla @@ -33,9 +33,10 @@ word version = $0200 // 02.00 word syspath word cmdlnptr word = @execmod, @open, @close, @read, @write +byte perr +byte modid = 0 byte refcons = 0 byte devcons = 0 -byte modid = 0 // // String pool. // @@ -117,7 +118,6 @@ word systemflags = 0 word heap = $2000 byte modseg[15] word symtbl, lastsym -byte perr // // CALL SOS // SYSCALL(CMD, PARAMS) From 0d1b2d5db9d65f4b47bca262d8b0e1c722c53b09 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Sat, 17 Mar 2018 15:58:41 -0700 Subject: [PATCH 059/147] Update images --- PLASMA-BLD2.PO | Bin 143360 -> 143360 bytes PLASMA-DEM2.PO | Bin 143360 -> 143360 bytes PLASMA-SOS2.PO | Bin 143360 -> 143360 bytes PLASMA-SYS2.PO | Bin 143360 -> 143360 bytes 4 files changed, 0 insertions(+), 0 deletions(-) diff --git a/PLASMA-BLD2.PO b/PLASMA-BLD2.PO index 2df2119062919f5de134440e63eeaa4ffed9e6b3..89a775317499b97bc29ab8e94b9043f298b32da7 100644 GIT binary patch delta 2569 zcmaKtTW}L)6vw~w^=me539Y3_(*jlsy`^nvD^*dEG`FVaMv~UHV5OIU#X?J3t`CL> zN1c)3!3b5nfC~n>SePu+Iz0FwqYvItQBYJwP!I&<4lT6x?1rRaGs8Y4JLmiD|Not{ z=R3RZgmT>pSTcdrp8;mGSLWcl>U)Le3kNH>&d3}%PrkE^MMoBNQG?DW^NPsK>IixY0>J3JlBWjsR5=e1^ z98*^tt=1@nJIg|~%J9Bp5-6@VyUJoRV3Uc0994>H{@6qdt34j4A>xU0)5v&oLoIhb zY_aPjB@_QswS*!pg(O$;4$EdU+G0!zYe8nNtZaTtCfOYJF;5ioViHMlC7FTMciSWr z>1Sjy(ULdj%QuI{jA)Q;a2w}EWZ5PxUk{bD`7Vb)CSA0C8@V}gW!AbJ=2~N^-eIef z-Y_lah^;d z>vQE;q1$4tGe#g(8^s(TF4uzCS0S2GNFk~Tv*dCbk+WK=B7#f>2_#V_Cp2?g6hSA@ zL@p^gWt=dtU@rvHsI}h%s^kGx8ode$uh3Aa6e$13F2K!4U|40#P{xjtF@YRM!VB4ZHN|53zl$6;z|I*ftr zF~l~;Z_Z?~8ZF|<4`<r<&;i~W#=qudtLzpNTx zfhq2V7CEhTwnk@ZaQ2eG8xOH}8sXwNT>|`9d zJW+lE3*83%@&NBOSS-AGvjj5xSbYpe-XW>SQEhXZzWd?uk3Stb`tvWxe*NwD z?&{yu%?pR?!inbQz#fpY#en*Q&Fi~n7^eC6u3>o;!R8XUTPXBd|+LTJ5u z+JHKfo&gxy1{4M$n~u`pCZI}4V2KJ&nbZsE^p*moYf~N_3T}pUek~1VQOdtWgHvhx E{~sz+8vp#X`XW+a(pL#}{%V_qkr*Ksa~xz?!F zJ8V^v*x5{yPIjuqa)s3%kJAtn!|0pHAaYS7#!9NquCk=)*b*WmN8|%BFD1iGmMWtw z0kY);$O0J1QIhX+B>6VzSF6#)=K*q?Tb0X~2j(W%3H$7Gs?;78+tokPt`;jtLvVH*z~gvG9pHAwhfo=ZN=R|+K%wgn#tV}B(1#crp?>2L{aP%U6giMhR<Grsiup1CNEo!%d6gjPRwg#s* zmI}+n;9M!esV#P6JORwX%Z8wwJw+}HSKek$xMepYW=g?^Vt*2$VGctPyOM%s3$qx# zXQCxhBi16M>P@<+6r{kdvkPsEKthGH$aUo0kbzU7AX#RY&SaSx2iaJZTb<&y&~3o` zF-{Sdk0qHiaFwY_!H3_aG?+!9Lq#F<9!Gg@Ll3mKr15D>`hl0PybOVMN;3xI%!DDZ zg@)D&%%&a)EfOBy?*$&V^@Bo_J#6@hkvXGA=Z-=20tB`X4y~3^UKZ*FnpY5gy^G>q zOh}Q*Vl`TXHHqfRitz&I6y4mIsoQRdF5NXui8Pd^%bIgqn&-_~ylAO1=h`Q7IJdb~IOJE%UqgK=y1%`NK13@*Vbn2~W2t#lfrGXEqWO|i85>Vh{7Ca0z!(cL3TWW5z z+UySJ442zeTZiVe&~+3vqy42dpzbcKfP;{Bdws*KJMO&e?%8O*1YMONQ}ME@UQjm9 zncF9)6XEr{& z>A7~_^P9K$x4y9L#g|^*zGLSrfsW2sgS)yLOKCaf8xQTM4-BHR*LLrDHTT0A-WedHuCfd*@U7X5JS_)kBd_~qA=r+z#A`yYRv zIs4b&=l(hW?}dw(F8B0ax!M=*$4g(rq%zJ2^zs%dmHSy9J=|pnrHfY%I}Z|hx&lpo ae)Q1K_m9kC-I}X#3UK>rCtd<0XvTj&7ATGY diff --git a/PLASMA-DEM2.PO b/PLASMA-DEM2.PO index 21c38ce06f1ed40dab1ca485601e1795b53e64b9..d759ddc5f5bbe80d22da12cf6f9cbf80cf51f5a3 100644 GIT binary patch delta 1634 zcmZvcTTmNS7{|YJ_T&PEgf^+9RO^LHXwo7Ci-?tyCQC@kWxLs=DOLqsE5+2d8Wpd> z8ZlO_NW9;wTPDw)=D`=ond+mDj+e*I_~MHX>NwLny79|y5@5@|?Du`=cfQO2?AgVu z*2SyVOJ0`y$u9^Ieh})9-2w!FYHla|s)s4G2ScL7C!{*29zg7O0%y90>>5@zDEt^r zCc=R_1YjTAG}{j`zLqJcv-b3+oI{KU*OCFK4 z)Yri}3@2NSL;RcwCZ%vBQBP=J-XvXl#&pqIWCho;D%J_#xmzj9M%^A=&^{rY))JVT zUg>`6#|Q4;ydKAklOpau4B-#F12c#{z+9Q6;@ zC@{yN83wkl!x&CJhE2_o%lio}ldcNcaxln`hbF>@CL>W?`I{)cPNj`D#e~CRLQ1BN zVDLIAQ)k6qB*%Ad6x-zPo{%JA-6x_>feC)GG-_%_8al$UAfN7=kfIT7R`wtcI%OC% zjipfRIm(XSf9wHt{v}Grx{~k6SwOe|9-leGc^otY9tUKI43|ij%EY`R!!TEnLFSfR zg|k_+r&or2mf?%$vnJU*zYS9TxJ>7rRfEc)8%#FohDm1irJBL&Flfwf+-9n6n+Hfm zn!)Gu;RTwqtS(emPghpwD#C09-SW5jQBrK9tjMmdJ8cu5w#D5O;ZuC1zkb-jW`Tnd zx>2iX(6NCv>=9@J&ThoI4R=m`9I>y~VG5RV@8Ygb-<1{nNdGN$X*u&7_C z)m5Jd8(i68!0=EUq~s)&&OD5^N=hz5OO#NneEiY56Z4N{FnW!Y%*0k2!sy9Ur_Vg` zWcDdNIznv9Ka_iV;aT+mBZ|sO9fY<%_ri-Wt0;WB!Gq~U-X9DmCiSYHA@}tS>AZ*?5yKK+cvrLIm?hECjwrgd!wQLjrX7B&^+s-E;5#-T%4g zoO?ENfy-Rr&Uk40d?XPM1)%;|ng9U^Ol|42Zib(rY!LV^&L^Z$I9}r{8&<@=84;u! zQu9vX zg(7}mS6tXr(l9iG5qehF&ulHl*aV$%$sdzq!f=%{*uVta)@m__820b0DwWjK>)Ba` z8$+WdxdM_2Ea1r^Hgm>RrWUisx|+>h!U8#6v=nf*h^yAv*Iwgru4`R??R9MFZ&b4O z#Tg_ga3ik25`>-wp>wql`lW!so={M403Dny-HL|#Y=9CLY^b=p1t=`*wU~!tdt)I< z;N!#PAUd>IjOkY7#6*MFPR7NlR?f}jVuGKqs)5?guurvKS&TN!Z$d&gZeq5I`F5nb z&28;$a2fNRNb|dq=v-Uf<<;Z;*s^5i@ef_Tn@xMRbyc|SXwco*;#~=I9yc z{(9M2(Sf?!h9pUBxU6a~=;8aOtIzI(*3bwqjCBo3k#H#!KyPOC9B-^A%Y=`4%c8PK z==L2q^|8UfsC>fZtw@@7_TReew%vXi-fB)DxbNn}_g zDJm1goD6-stPHYY&Y7J_ncN*R%%(W@p|dHYY)YW|E8fmEQ|`_p4vfy&OkHhEcJlOMh)w} zg1yXIZD(Vvm6~H3I?7%nez8ibuYnoPuG7l3X?|YnN#=D)>y<@lL**BudnTP>_GMIl zqso_rd-l26=jUF?zR2b-qVly_IY-D#udtDd$`?fWi?qD@`WtV~=iYkz_=$JkeUB~t eiONN%@&hrv|G|f+PJgt71NaXrKbrGH`160X(_-NO diff --git a/PLASMA-SOS2.PO b/PLASMA-SOS2.PO index 7ce4590a26716b1afa6f1f7ae3f3260bf22ffaf4..bcc2064a34d9e3bab37a392c985a60377854b027 100644 GIT binary patch delta 3820 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 JzOSj7{|6hRKve($ delta 2470 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 From f7cf0be03ec7c7e43a086a3e2c74de6f3be861f6 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Sat, 17 Mar 2018 16:51:00 -0700 Subject: [PATCH 060/147] more cmdsys rearrangement --- src/inc/cmdsys.plh | 2 +- src/vmsrc/apple/soscmd.pla | 151 ++++++++++++++++++------------------- src/vmsrc/apple/sossys.pla | 21 ++++-- 3 files changed, 90 insertions(+), 84 deletions(-) diff --git a/src/inc/cmdsys.plh b/src/inc/cmdsys.plh index b204545..1dd3ae8 100644 --- a/src/inc/cmdsys.plh +++ b/src/inc/cmdsys.plh @@ -51,9 +51,9 @@ import cmdsys word sysread word syswrite byte syserr - byte modid // Apple /// specific byte refcons // Apple /// specific byte devcons // Apple /// specific + byte cmdparser end // // CMD exported functions diff --git a/src/vmsrc/apple/soscmd.pla b/src/vmsrc/apple/soscmd.pla index 2a0697b..5eefeb7 100755 --- a/src/vmsrc/apple/soscmd.pla +++ b/src/vmsrc/apple/soscmd.pla @@ -2,9 +2,6 @@ include "inc/cmdsys.plh" byte console[] = ".CONSOLE" byte textmode[] = 16, 0, 15 byte prefix[64] = "" -byte err[] -byte autorun -word cmdptr // // Utility functions // @@ -217,9 +214,78 @@ def parsecmd(strptr)#1 return cmd end // -// Clear out module memory segment +// Command line handler // -cmdsys.modid = 0 +def shell#0 + byte err[] + byte autorun + word cmdptr + // + // Try to load autorun. + // + cmdptr = heapmark + ^cmdptr = 0 + autorun = cmdsys:sysopen("AUTORUN") + if autorun > 0 + ^cmdptr = cmdsys:sysread(autorun, cmdptr + 1, 64) + cmdsys:sysclose(autorun) + fin + // + // Handle commands. + // + while 1 + if ^cmdptr + when toupper(parsecmd(cmdptr)) + is 'C' + catalog(cmdptr) + break + is 'P' + if ^cmdptr and ^(cmdptr + 1) <> '/' + strcat(@prefix, cmdptr) + else + strcpy(@prefix, cmdptr) + fin + setpfx(@prefix) + break + is '/' + repeat + prefix-- + until prefix[prefix] == '/' + if prefix > 1 + setpfx(@prefix) + fin + break + is 'S' + setpfx(cmdptr) + strcat(getpfx(cmdsys:syspath), "SYS/")) + break + is 'V' + volumes + break + is '+' + saveX + cmdsys:modexec(striptrail(cmdptr)) + restoreX + cmdsys:sysclose(0) + init_cons + break + otherwise + puts("?\n") + wend + if cmdsys.syserr + err = cmdsys.syserr + puts("ERR:$") + putb(err) + else + puts("OK") + fin + putln + fin + puts(getpfx(@prefix)) + cmdptr = gets($BA) + strcpy(cmdsys:cmdline, cmdptr) + loop +end // // Init console. // @@ -227,77 +293,10 @@ init_cons // // Print PLASMA version // -puts("PLASMA 2.0 Dev\n")//; prbyte(version.1); cout('.'); prbyte(version.0); crout +puts("PLASMA 2.0 Dev\n")//; putb(version.1); putc('.'); putb(version.0); putln +puts("MEM:$"); puth(heapavail); putln // -// Try to load autorun. +// Save pointer to command line handler // -cmdptr = heapmark -^cmdptr = 0 -autorun = cmdsys:sysopen("AUTORUN") -if autorun > 0 - ^cmdptr = cmdsys:sysread(autorun, cmdptr + 1, 64) - cmdsys:sysclose(autorun) -else - // - // Print some startup info. - // - puts("MEM:$") - puth(heapavail) - putln -fin -// -// Handle commands. -// -while 1 - if ^cmdptr - when toupper(parsecmd(cmdptr)) - is 'C' - catalog(cmdptr) - break - is 'P' - if ^cmdptr and ^(cmdptr + 1) <> '/' - strcat(@prefix, cmdptr) - else - strcpy(@prefix, cmdptr) - fin - setpfx(@prefix) - break - is '/' - repeat - prefix-- - until prefix[prefix] == '/' - if prefix > 1 - setpfx(@prefix) - fin - break - is 'S' - setpfx(cmdptr) - strcat(getpfx(cmdsys:syspath), "SYS/")) - break - is 'V' - volumes - break - is '+' - saveX - cmdsys:modexec(striptrail(cmdptr)) - restoreX - cmdsys:sysclose(0) - init_cons - break - otherwise - puts("?\n") - wend - if cmdsys.syserr - err = cmdsys.syserr - puts("ERR:$") - putb(err) - else - puts("OK") - fin - putln - fin - puts(getpfx(@prefix)) - cmdptr = gets($BA) - strcpy(cmdsys:cmdline, cmdptr) -loop +cmdsys:cmdparser = @shell done diff --git a/src/vmsrc/apple/sossys.pla b/src/vmsrc/apple/sossys.pla index 9e12fa4..5664b20 100755 --- a/src/vmsrc/apple/sossys.pla +++ b/src/vmsrc/apple/sossys.pla @@ -29,14 +29,14 @@ predef execmod(modfile)#1, open(path)#1, close(refnum)#1, read(refnum, buff, len // // Exported CMDSYS table // -word version = $0200 // 02.00 +word version = $0200 // 02.00 word syspath word cmdlnptr -word = @execmod, @open, @close, @read, @write +word = @execmod, @open, @close, @read, @write byte perr -byte modid = 0 -byte refcons = 0 -byte devcons = 0 +byte refcons = 0 +byte devcons = 0 +word cmdparser // // String pool. // @@ -48,7 +48,11 @@ byte machid = $F2 // Apple ///, 80 columns // // Working input buffer overlayed with strings table // -byte cmdln = "" +byte cmdln = "" +// +// SOS.CMD as DCI string +// +byte soscmd = 'S'|$80,'O'|$80,'S'|$80,'.'|$80,'C'|$80,'M'|$80,'D' // // Standard Library exported functions. // @@ -116,6 +120,7 @@ word sysmodsym = @exports // word systemflags = 0 word heap = $2000 +byte modid = 0 byte modseg[15] word symtbl, lastsym // @@ -1225,5 +1230,7 @@ cmdlnptr = @cmdln // // Exec command line parser // -execmod("SOS.CMD") +loadmod(@soscmd) +modid = 0 +cmdparser()#0 done From 773e0d0af02aba41310555773d7b438cd286174f Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Sat, 17 Mar 2018 17:14:21 -0700 Subject: [PATCH 061/147] update images --- PLASMA-BLD2.PO | Bin 143360 -> 143360 bytes PLASMA-DEM2.PO | Bin 143360 -> 143360 bytes PLASMA-SOS2.PO | Bin 143360 -> 143360 bytes PLASMA-SYS2.PO | Bin 143360 -> 143360 bytes 4 files changed, 0 insertions(+), 0 deletions(-) diff --git a/PLASMA-BLD2.PO b/PLASMA-BLD2.PO index 89a775317499b97bc29ab8e94b9043f298b32da7..ea8b416694ec3562122d0c2878813b1b2c28cb3a 100644 GIT binary patch delta 2361 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 diff --git a/PLASMA-SOS2.PO b/PLASMA-SOS2.PO index bcc2064a34d9e3bab37a392c985a60377854b027..f28dab32b8b54239fe7c8bdad4ef8f27b8dfe9ec 100644 GIT binary patch delta 1009 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 X+QU>6(?-eX7C}2hN3l`6fNTE;APScw delta 1789 zcmZWqYj9Il5Z*nxX_C@5Y2pYKEVX%*!dOdZ%s3riX_J&-UgoCSR>Z1BL3{z?TT`VV zg5slEv?}6NkBC*PL4q%=6tG3a2h;~DqWtiW&XgHvtV6kR?@g1Y$@!6Uck|tEchBy3 zZs&1*=W%`iJi%^l47ed{73jeL{}{n-Gn=e%0!%AxPGfgisP>;5_PfM@t43@Uqn-dj zat0KFuM}S12r3d3B!lx(u=&mjV6qbQu&#&*O_Q+heL}VUFfnCC2BRMsfS|gR(CUg? zw14aQ05ZMKP&loqxWpJoHimpJ3j6>TN+nFHEHRkM&YC&v?DE+a^yj}QnN7SOneH5` z&F-kWjC}tg-$CH8m+wXv19%5cBN*>ew~I?XUecC56tL~%a<_5qsUk=9LKFP_O#$Cvjqz0Kr~{m z?SM9HVYt+?d2I_GLQ5jrihY9g7Zb$hE3Tw@8b@igKPFU`zE{tfW952bi z<_mhF84z`02WVhKlM9=^Fx1-6+}4&x$~#G1%k#uF-5&}zEsO;w2QxvqHF-Ekz!L~4 z0-IR!ht&JoQ+rRzof!^AqS=GFhu9pLo19H_1yg!S(Z%GwiX05NIJ@Zfy0VIu4^XYM z@@jR6LAU6+Je?cJU(r2#vLu(yDu%MJ8<4*zHod|&RW(&&*r(Ky=97P-M$FA?#GGbD z(v!`Qeyo(eR|A5RSCU89_Q3^8d zM8-EDGwk~4<4-=_{n^0h>Im^oXyS{JNexUpxNrX#L*zY$l2 Date: Sat, 17 Mar 2018 19:07:36 -0700 Subject: [PATCH 062/147] Working Apple 3 again --- src/vmsrc/apple/plvm03.s | 2 +- src/vmsrc/apple/soscmd.pla | 17 ++--------------- src/vmsrc/apple/sossys.pla | 4 ++-- 3 files changed, 5 insertions(+), 18 deletions(-) diff --git a/src/vmsrc/apple/plvm03.s b/src/vmsrc/apple/plvm03.s index e7afc82..1ca104a 100755 --- a/src/vmsrc/apple/plvm03.s +++ b/src/vmsrc/apple/plvm03.s @@ -74,7 +74,7 @@ SEGSTART = $2000 STA PPH STA IFPH !IF 1 { - LDA #VMCORE STA SRCH diff --git a/src/vmsrc/apple/soscmd.pla b/src/vmsrc/apple/soscmd.pla index 5eefeb7..3632df0 100755 --- a/src/vmsrc/apple/soscmd.pla +++ b/src/vmsrc/apple/soscmd.pla @@ -3,16 +3,6 @@ byte console[] = ".CONSOLE" byte textmode[] = 16, 0, 15 byte prefix[64] = "" // -// Utility functions -// -asm saveX#0 - STX XREG+1 -end -asm restoreX#0 -XREG LDX #$00 - RTS -end -// // SOS routines // FILE I/O // @@ -225,6 +215,7 @@ def shell#0 // cmdptr = heapmark ^cmdptr = 0 + puts("MEM:$"); puth(heapavail); putln autorun = cmdsys:sysopen("AUTORUN") if autorun > 0 ^cmdptr = cmdsys:sysread(autorun, cmdptr + 1, 64) @@ -263,11 +254,8 @@ def shell#0 volumes break is '+' - saveX cmdsys:modexec(striptrail(cmdptr)) - restoreX - cmdsys:sysclose(0) - init_cons + cmdsys:syswrite(cmdsys.refcons, @textmode, 3) break otherwise puts("?\n") @@ -294,7 +282,6 @@ init_cons // Print PLASMA version // puts("PLASMA 2.0 Dev\n")//; putb(version.1); putc('.'); putb(version.0); putln -puts("MEM:$"); puth(heapavail); putln // // Save pointer to command line handler // diff --git a/src/vmsrc/apple/sossys.pla b/src/vmsrc/apple/sossys.pla index 5664b20..91325db 100755 --- a/src/vmsrc/apple/sossys.pla +++ b/src/vmsrc/apple/sossys.pla @@ -1202,11 +1202,11 @@ def execmod(modfile)#1 modid-- seg_release(modseg[modid]) loop + xpokeb(symtbl.0, lastsym, 0) + systemflags = saveflags else modid = 0 fin - xpokeb(symtbl.0, lastsym, 0) - systemflags = saveflags fin return -perr end From 6d2336a34358604784d2dfc55af69ef9f4cfaaa0 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Sat, 17 Mar 2018 19:14:42 -0700 Subject: [PATCH 063/147] Update image --- PLASMA-SOS2.PO | Bin 143360 -> 143360 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/PLASMA-SOS2.PO b/PLASMA-SOS2.PO index f28dab32b8b54239fe7c8bdad4ef8f27b8dfe9ec..9982850bf9a12d5bf56c43de5c276c7bf65dc46c 100644 GIT binary patch delta 2343 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 Date: Sun, 18 Mar 2018 13:23:39 -0700 Subject: [PATCH 064/147] Shuffle routines around based on available INTERP mem --- src/vmsrc/apple/soscmd.pla | 70 +++++++------------------------------- src/vmsrc/apple/sossys.pla | 61 +++++++++++++++++++++++++++++++-- 2 files changed, 71 insertions(+), 60 deletions(-) diff --git a/src/vmsrc/apple/soscmd.pla b/src/vmsrc/apple/soscmd.pla index 3632df0..69a1c5c 100755 --- a/src/vmsrc/apple/soscmd.pla +++ b/src/vmsrc/apple/soscmd.pla @@ -1,7 +1,4 @@ include "inc/cmdsys.plh" -byte console[] = ".CONSOLE" -byte textmode[] = 16, 0, 15 -byte prefix[64] = "" // // SOS routines // FILE I/O @@ -33,27 +30,6 @@ def setpfx(path)#1 fin return path end -// -// CONSOLE I/O -// -def dev_control(devnum, code, list)#1 - byte params[5] - - params.0 = 3 - params.1 = devnum - params.2 = code - params:3 = list - return syscall($83, @params) -end -def dev_getnum(name)#1 - byte params[4] - - params.0 = 2 - params:1 = name - params.3 = 0 - syscall($84, @params) - return params.3 -end def dev_info(devnum, name, list, listlen)#1 byte params[7] @@ -64,16 +40,6 @@ def dev_info(devnum, name, list, listlen)#1 params.6 = listlen return syscall($85, @params) end -def init_cons()#0 - byte nlmode[2] - cmdsys.refcons = cmdsys:sysopen(@console) - cmdsys:syswrite(cmdsys.refcons, @textmode, 3) - cmdsys.devcons = dev_getnum(@console) - nlmode:0 = $0D80 - //nlmode.0 = $80 - //nlmode.1 = $0D - dev_control(cmdsys.devcons, $02, @nlmode) -end def volume(devname, volname)#1 byte params[9] @@ -113,7 +79,7 @@ def catalog(path)#0 word entry, filecnt, catptr if !^path - path = @prefix + getpfx(path) fin refnum = cmdsys:sysopen(path) if not refnum @@ -206,25 +172,19 @@ end // // Command line handler // -def shell#0 +def shell#1 + byte textmode[3] + byte prefix[64] byte err[] - byte autorun word cmdptr // - // Try to load autorun. + // Copy AUTORUN commmand line // - cmdptr = heapmark - ^cmdptr = 0 - puts("MEM:$"); puth(heapavail); putln - autorun = cmdsys:sysopen("AUTORUN") - if autorun > 0 - ^cmdptr = cmdsys:sysread(autorun, cmdptr + 1, 64) - cmdsys:sysclose(autorun) - fin + cmdptr = strcpy(heapmark, cmdsys:cmdline) // // Handle commands. // - while 1 + repeat if ^cmdptr when toupper(parsecmd(cmdptr)) is 'C' @@ -254,8 +214,9 @@ def shell#0 volumes break is '+' - cmdsys:modexec(striptrail(cmdptr)) - cmdsys:syswrite(cmdsys.refcons, @textmode, 3) + //cmdsys:modexec(striptrail(cmdptr)) + return striptrail(cmdptr) + //cmdsys:syswrite(cmdsys.refcons, @textmode, 3) break otherwise puts("?\n") @@ -272,17 +233,10 @@ def shell#0 puts(getpfx(@prefix)) cmdptr = gets($BA) strcpy(cmdsys:cmdline, cmdptr) - loop + until 0 + return 0 end // -// Init console. -// -init_cons -// -// Print PLASMA version -// -puts("PLASMA 2.0 Dev\n")//; putb(version.1); putc('.'); putb(version.0); putln -// // Save pointer to command line handler // cmdsys:cmdparser = @shell diff --git a/src/vmsrc/apple/sossys.pla b/src/vmsrc/apple/sossys.pla index 91325db..2d1d79d 100755 --- a/src/vmsrc/apple/sossys.pla +++ b/src/vmsrc/apple/sossys.pla @@ -45,6 +45,12 @@ byte hexchar[] = '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E', // Exported Machine ID. // byte machid = $F2 // Apple ///, 80 columns +// +// Console and textmode control characters +// +byte console[] = ".CONSOLE" +byte textmode[] = 16, 0, 15 + // // Working input buffer overlayed with strings table // @@ -120,8 +126,9 @@ word sysmodsym = @exports // word systemflags = 0 word heap = $2000 -byte modid = 0 +byte autorun[] byte modseg[15] +byte modid = 0 word symtbl, lastsym // // CALL SOS @@ -817,6 +824,38 @@ def write(refnum, buff, len)#1 return perr end // +// CONSOLE I/O +// +def dev_control(devnum, code, list)#1 + byte params[5] + + params.0 = 3 + params.1 = devnum + params.2 = code + params:3 = list + return syscall($83, @params) +end +def dev_getnum(name)#1 + byte params[4] + + params.0 = 2 + params:1 = name + params.3 = 0 + syscall($84, @params) + return params.3 +end +def init_cons()#0 + byte nlmode[2] + + refcons = open(@console) + devcons = dev_getnum(@console) + nlmode:0 = $0D80 + //nlmode.0 = $80 + //nlmode.1 = $0D + dev_control(devcons, $02, @nlmode) + write(refcons, @textmode, 3) +end +// // MEMORY CALLS // def seg_find(search, pages, id)#3 @@ -1228,9 +1267,27 @@ sysmods = 0 syspath = @sysmods cmdlnptr = @cmdln // +// Print PLASMA version +// +init_cons +prstr("PLASMA 2.0 Dev\n")//; putb(version.1); putc('.'); putb(version.0); putln +prstr("MEM:$"); prword(availheap); crout +// // Exec command line parser // loadmod(@soscmd) modid = 0 -cmdparser()#0 +autorun = open("AUTORUN") +if autorun > 0 + cmdln = read(autorun, @cmdln.1, 64) + close(autorun) +fin +// +// Call cmd line parser +// +repeat + execmod(cmdparser()) + write(refcons, @textmode, 3) + cmdln = 0 +until 0 done From 5a0d9e57513dd674cb0b15eb66fad0d4978eb72a Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Sun, 18 Mar 2018 13:38:13 -0700 Subject: [PATCH 065/147] VerifyREL module filetype before trying to load --- src/vmsrc/apple/sossys.pla | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/vmsrc/apple/sossys.pla b/src/vmsrc/apple/sossys.pla index 2d1d79d..4dc0ee9 100755 --- a/src/vmsrc/apple/sossys.pla +++ b/src/vmsrc/apple/sossys.pla @@ -1025,7 +1025,7 @@ def loadmod(mod)#1 word addr, defaddr, modaddr, modfix, modofst, modend word deftbl, deflast, codeseg word moddep, rld, esd, sym - byte lerr, defext, str[16], filename[33] + byte lerr, defext, fileinfo[], str[16], filename[33] byte header[128] lerr = 0 // @@ -1040,6 +1040,15 @@ def loadmod(mod)#1 refnum = open(strcpy(@filename,strcat(strcpy(@header, @sysmods), @filename))) fin if refnum + header.0 = 3 + header:1 = @filename + header:3 = @fileinfo + header.5 = 2 + if not syscall($C4, @header) and fileinfo.1 <> $FE // Make sure it's a REL module + close(refnum) + perr = $4A // Incompatible type + return -perr + fin rdlen = read(refnum, @header, 128) modsize = header:0 moddep = @header.1 From 1a8f3048b5326af1b9bb74e00aaf6b6f6aec7185 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Sun, 18 Mar 2018 13:47:14 -0700 Subject: [PATCH 066/147] Verify REL module tyoe before loading --- src/vmsrc/apple/cmd.pla | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/vmsrc/apple/cmd.pla b/src/vmsrc/apple/cmd.pla index 367a250..da0a26e 100755 --- a/src/vmsrc/apple/cmd.pla +++ b/src/vmsrc/apple/cmd.pla @@ -1064,6 +1064,13 @@ def loadmod(mod)#1 refnum = open(strcpy(@filename,strcat(strcpy(@header, @sysmods), @filename))) fin if refnum + header.0 = $0A + header:1 = @filename + if not syscall($C4, @header) and header.4 <> $FE // Make sure it's a REL module + close(refnum) + perr = $4A // Incompatible type + return -perr + fin rdlen = read(refnum, @header, 128) modsize = header:0 moddep = @header.1 From 571e8d8eb09fe80b562d212e6a1428ff48134238 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Sun, 18 Mar 2018 14:31:36 -0700 Subject: [PATCH 067/147] All out speed CFFB --- src/vmsrc/apple/plvm03.s | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/vmsrc/apple/plvm03.s b/src/vmsrc/apple/plvm03.s index 1ca104a..269529d 100755 --- a/src/vmsrc/apple/plvm03.s +++ b/src/vmsrc/apple/plvm03.s @@ -516,7 +516,12 @@ CN DEX STA ESTKH,X JMP NEXTOP CFFB LDA #$FF - !BYTE $2C ; BIT $00A9 - effectively skips LDA #$00, no harm in reading this address + DEX + STA ESTKH,X + INY ;+INC_IP + LDA (IP),Y + STA ESTKL,X + JMP NEXTOP CB LDA #$00 DEX STA ESTKH,X @@ -1282,7 +1287,7 @@ CALL INY ;+INC_IP LDA (IP),Y STA CALLADR+2 _CALL TYA - CLC + SEC ADC IPL PHA LDA IPH @@ -1297,7 +1302,7 @@ CALLADR JSR $FFFF STA IPH PLA STA IPL - LDY #$01 + LDY #$00 JMP FETCHOP ;* ;* ENTER FUNCTION WITH FRAME SIZE AND PARAM COUNT From b3c05c9797982aaefed9a8184c9695647e234650 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Sun, 18 Mar 2018 15:49:55 -0700 Subject: [PATCH 068/147] Case-ify more of the editor if/ifelse/else --- src/toolsrc/ed.pla | 73 +++++++++++++++++++++++++--------------------- 1 file changed, 39 insertions(+), 34 deletions(-) diff --git a/src/toolsrc/ed.pla b/src/toolsrc/ed.pla index 5d470f2..86f0844 100755 --- a/src/toolsrc/ed.pla +++ b/src/toolsrc/ed.pla @@ -690,33 +690,45 @@ def keyin2 fin until key >= 128 ^keystrobe - if key == keyctrln - key = $DB // '[' - elsif key == $9E // SHIFT+CTRL+N - key = $FE // '~' - elsif key == keyctrlp - key = $DC // '\' - elsif key == $80 // SHIFT+CTRL+P -> CTRL+@ - key = $FC // '|' - elsif key == keyctrlg - key = $DF // '_' - elsif key == keyarrowleft - if ^pushbttn3 < 128 - key = keydelete - fin - elsif key >= $C0 and flags < shiftlock - if ^pushbttn3 < 128 - if key == $C0 - key = $D0 // P - elsif key == $DD - key = $CD // M - elsif key == $DE - key = $CE // N + when key + is keyctrln + key = $DB // '[' + break + is $9E // SHIFT+CTRL+N + key = $FE // '~' + break + is keyctrlp + key = $DC // '\' + break + is $80 // SHIFT+CTRL+P -> CTRL+@ + key = $FC // '|' + break + is keyctrlg + key = $DF // '_' + break + is keyarrowleft + if ^pushbttn3 < 128 + key = keydelete fin - else - key = key | $E0 - fin - fin + break + otherwise + if key >= $C0 and flags < shiftlock + if ^pushbttn3 < 128 + when key + is $C0 + key = $D0 // P + break + is $DD + key = $CD // M + break + is $DE + key = $CE // N + wend + else + key = key | $E0 + fin + fin + wend return key end def setkeyin#0 @@ -834,13 +846,7 @@ def splitline#0 fin end def editkey(key) - if key >= keyspace - return TRUE - elsif key == keydelete - return TRUE - elsif key == keyctrld - return TRUE - elsif key == keyctrlr + if key >= keyspace or key == keydelete or key == keyctrld or key == keyctrlr return TRUE fin return FALSE @@ -1020,7 +1026,6 @@ def editmode#0 fin redraw fin - break wend until exit end From 45779837997a30950d89b8d67ecf69ee2f042f92 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Sun, 18 Mar 2018 16:26:09 -0700 Subject: [PATCH 069/147] Update images --- PLASMA-SOS2.PO | Bin 143360 -> 143360 bytes PLASMA-SYS2.PO | Bin 143360 -> 143360 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/PLASMA-SOS2.PO b/PLASMA-SOS2.PO index 9982850bf9a12d5bf56c43de5c276c7bf65dc46c..4c07b34050b41a6c362c7496dcc8b3238f895ce1 100644 GIT binary patch delta 2790 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 J3|(Ow{|DjTqrCyIJ3LpiJBhp< zk(p_tSC>&^CiyZsb#F@R(fjX2Z#)^OBnSnCJ87=H`Yws}sMO-h6yhXKq;K5iyL98` zvG}zMU@@NPpa!XOScOGEBa$5$s7S8S5 zch-xxFFMba#+!<_22g&nO&j14DBmV6?~q~}Jl7(u%DY*4y_SvCv)yG+)UgCKv+7vi z`vRjPr#(Nx+;PF~U>+FWDIzi|IwtlW592qO+bpQt z84rj{NK8t8+<|@nW9klOaEs~cE~YOcdY3M=det-IX-{(drZ?OecEsBZNVcZtWV9R- zEsGfKp~jJI91-6TJ1KEsc2;I~)7idHO(Z`u2DDC#Ps_+5!u6XsZ3yyG+TchbG- zV((rlJ#XKh|0+BL#ofN@-#3?-F6K%tuj=Q}LAy5N=oV1zd1? zw8uDCCB}8xPvp2v6(t^lKgZNz%-{VZ*Gog69EM4Alew??yVr8v@DU@?^)e4H*L22R zRz88~mhd3udyG4OXQokO#*TYxeEx)qlM0@mJmr~xO!b&P?A0zirx)42EhJGPn}%j7 z*}g-wfNVF>%q81dG&8ASe6_7O-QiC*FZvV6znIQ?7g2+EFM|w zDbo2);z8Gun$F>F@||q(o&1$W^do7j#dp#&m#{yag}J)yj~aHT018W!j>xrQ=!|y{WB3emSYy zdV1blP%1bIJ?{Mpj7@XxJJ1!M*AL8#S|2A7EVj{-LwFqF36H($J2{KeQwHC-@Ei3xP(GgFt|e z@Cew!X(T1bs8@y!PcLdPIdVuH+a9O6Xi4EI8J zxF32472(Mc^n)~b9I{{-jDRta50hXn6aoJA%1cmq6$+OjE{6)(3@W?@@4$B02_Hcf zRKp&qfrC&7M^R8Yg+iy%X@HAx1%87Ya0_(pN%n{K&=Ddb7LwYNVry@fyCZ%O9)?H3 z4uimn<06jdA|3`KU<~BLB$y0E)A3OVvtbU%un-nODXfAuPzL322xL6%7_6_21;S4muCHM(`gPXw^e_aSB4+KF7ghK?xLK4`Z zJM@HJ&<7rYRLFu6Fcv1kv=CCB4Kd4e5YGb{N?-|;!v@$0o8e7(y9gin<0|ijJ@6&$ zha*rA$Kg8^y%55bD~PYcukc^^6G*_^fFLkKI7CAN*dPUZLthvGgCGZnz$hphi;wXz z38uhQm=1+78|Fa?l)@@l17)xQHiHUp!@KYSRKXsofx}P_C*TZx4?n_Hft23`rrZ)R z{>((O9t>cFU=t};6H_7)$3i?L!#r4xW96n8Ws^y-yk^oVTTH>qd+1l1VwEbWMI3I{ zD@kUqJOX3PG0H@9h%(u%Q;N-ISv8aLDcX87$)^x|%|&{dTS)P@bWnmVI>lnq$r0#3 zX3@)bw1X^q#c2tUa}W=)bdX0`FxD_03ScS}!gDYeieLehKq;()4X_b5g9=+=2kKQ> zV&s#)6V5^dT!NqA8r*`eR#JLcx$=Njr#xtlRWhu4WiVQ&)u23yIM1q+M_EapfV=`L zlV>2FiFmd(N||Ggmgk`_!(v#5{VS{%c{SRXt$KMK_PqkpoAB`(yaij~U3ecpfDf%@ zpN?erd5(OO!pqJDvG_{AAodp%rcIymY~jpV&&_`Rg*kIyoL7X^%{8V9EL!c)xL@)7 z1q)xouD_U?hDCD)*Oe?@g8nV$cI(|+xqfNs@)eDJ58Lkba|v8usUOR3GSfzhl+P0earjyIJn()RjR+kvg~5_8kiQ(HW&b`Z}R+2&c3aS{P>BcoPJz&V7i|C_B-@%F;!%GwGVcjK6|cdM_96PL;nsrvlJA!E{*yFR8bFU&9t*lx@SwVPY)o2qdWU-Cdxg5wZ$UKB z!UZasI_1snjS+3;scdyRxSy{p14GH zd|YN;YDU(`_H)U-aM|a4T5hfVl0qrQo_pU7$`Pa@jjD5+DK#(CPB?$tpBzPu4zxb0 z4&^NN)EsMD4)$_1`BHuN&gDXe<>n6=QBcs9DaWJQq^{M{ho1SHlwvcohFJ6NCCWU~R&`CYr)Q)J9nu8ctGUa)#${yLtXaA3dGfR5Lr-+WNgel{ zHQIXLn` zL+j+xjN?>2!^|GWH8b~Ergm3jCOi_c%-mZT=c?q~3mND0K#V0e4zqtUcNx>TU&RWa z;i}_Jg>E!4&|1koP9)Vx%U|7HZe~9%*gzLmW(tzJ!ttn=d7JF>O<( z_YJMqP*J%~nNMj;NNibA4nH+5ocJ&$yr_gHa9E%cU9zCa$!X*{e<+4ylb!!N^2s2Z zhN22MK90ttzNIzjsRZ-y1_4U2%;KY@Q2{qnVB<-s@|-$)ov|wC_Ty=`tKoV5neb!? zKbr}2L-^O3P#?kOUCKGDH z_*AT#`4s2S`o4oFhb0L+gLxl@TYQ|u6$*cvc^ysMs4EkcwYee6^7kaz&HQDG3k!R5 zgD&Ai;c9r2@N+Nzq;qTigKUHIQhji*#Z*L;@QWpoiVPGSw^=6?h9(J_!NNeN_C&;U z&k%1XlSqy7T$C;U{0?oF%PHQwgo3>iotB++SYA%a z-W9Y_uAnpWyR<=m5BaNToxGZ6c#Fz(wqnox6BfqGotsW3VtfANobc_@_!{O_(Rem- ziB9Nd!p%L&W|r&t<0LdWiyN%W<*aM41Put|3osKsvrJc@!paW~v)RwiqEmUk&5=~d z4Rr21wffPYdl45FM%)0H3^kxK6K97%p(>oXtAIl|*8{|rM-#Ulnmo%-f2(qQgb9FcDsb zVweVRfCJ`1DJ+6ASOP0x4Y*(fY=UYy3SYoCa1E~GWIy3#zhL}3+=gc0f=JYW7D9sX z{v$Amfp|!O0gwzSkP2292HC)a9iD+gm;f_i7R-gWgGgE&WDqMbUI~@37S_X7*akac z4;+9)4s4FXX}APe;9u|~+=NDGLQy%0NxnLK(jgG^&;!EY0f>h_FaREf!C-}_VK_Vs zqhJh7hAA);9J8>Q19PDi7C{*-0Vk}4wXhLBhEJgew!t3w3=Y9DI0aw9CAbDR;3oVE zw}I(N>;`^%l5~0|h3fJC&6tRU7>I-3SbP|ZgD_5kCt(Ow!WOJ;(??2s^=fIqUL_sT zYo!Ln=k!t11^5BuWP@5tH*iuu%r-ekN&So}@lnL1jB0TV_T!CeX_B#b0*a>^!Gx!{i!564^!5AqvIS@1hnea6Nf6zi03^S3GYvQCllS&$4iju~e)KU@l zlS~?EI>s|iDsdL_<{_`t#Kff-J29>>g-a_<5n?6c55NtZFkfvlid(SvnABn|=5|2D zUTpTmVK@dS;1ryJ^CstBcOOs9g(S|spK+SWf1OhN+SF;&(cJvO+=tK{9b*Bmk2v*= znQy#_$vezd?du3dqZgCGk7(~8F_35DCq_5jeeE1N*95E0nr-i!mYd$%HTy0gJ<+`$ zvgPN1(%|xTp+kF!|FLSS>(bzc*m83+hdHv_duIF(W;Cx$U;SWPOM3ST<@Zr8rc1ea ztJ1k<-K(}%Y34PZ?;+mKXYsjt?TxiV-iUGuU4ClBrsd{zXsb#77#*(v{T(hINw89@ zL!SI8?jeqKKI=mneDc7g{_T&>_wVSwDH>^ayY#z{&XR@JyThB151{Ek*R|=-wq|E{ z=)mPecwdoS-dCJGC*5ux-d;~Wg=W6-{${?VOV2_R?en)ejuNqsaSSbZ4%0bxoZ6$l zbcg9m7cP4HowD-9OO{H@oXb~K;G=VkxvoaIhoBjMcjYR?=rSJb7M|v^y3iC4eYmDoD@bHnN z$Bx&ZIEjTO=AOZH?p63kG@Sn8%-M72zr-xQ5o?&%mCkkh>gx;NT)gxx=590BP>riX zy-XX)b~&T8J^hj+lwZ(9*TOw%+TBcZ`RcXrzW?|28!ZJ~26gQb#yAfPZsfQ~&SUOb zsAd(;H^MF0t_gp9%oTGIdhUrmUg2zoG?q)Gs3^hRV}?pd3m>ntWuZY&Ea8OHAxhR* zb2WZ4P*j5Lsp{@DQ5BVV^X5~wFysgo<|3b{@$^F3P@6v``eLXYqa1q0?0F)>pBV$f zg&&Q16G+&t=ij14FB9H!J{S3ysFW~1ttEUZoPUgjQF>+RidndZj{60@kmmG6PWL_A Zz-zYmdUtmf>&NZug Date: Mon, 19 Mar 2018 15:21:15 -0700 Subject: [PATCH 070/147] Slight improvement to return address calc for ICAL/CALL --- src/vmsrc/apple/plvm01.s | 4 ++-- src/vmsrc/apple/plvm02.s | 16 ++++++++-------- src/vmsrc/apple/plvm03.s | 25 +++++++++++++++++++++---- src/vmsrc/apple/plvm802.s | 8 ++++---- 4 files changed, 35 insertions(+), 18 deletions(-) diff --git a/src/vmsrc/apple/plvm01.s b/src/vmsrc/apple/plvm01.s index 651be40..4e73678 100644 --- a/src/vmsrc/apple/plvm01.s +++ b/src/vmsrc/apple/plvm01.s @@ -1007,7 +1007,7 @@ CALL INY ;+INC_IP LDA (IP),Y STA TMPH _CALL TYA - CLC + SEC ADC IPL PHA LDA IPH @@ -1018,7 +1018,7 @@ _CALL TYA STA IPH PLA STA IPL - LDY #$01 + LDY #$00 JMP FETCHOP ;* ;* JUMP INDIRECT TRHOUGH TMP diff --git a/src/vmsrc/apple/plvm02.s b/src/vmsrc/apple/plvm02.s index a33d4c8..6b32904 100755 --- a/src/vmsrc/apple/plvm02.s +++ b/src/vmsrc/apple/plvm02.s @@ -1790,7 +1790,7 @@ CALL INY ;+INC_IP LDA (IP),Y STA TMPH TYA - CLC + SEC ADC IPL PHA LDA IPH @@ -1803,7 +1803,7 @@ CALL INY ;+INC_IP STA IPL LDA #>OPTBL ; MAKE SURE WE'RE INDEXING THE RIGHT TABLE STA OPPAGE - LDY #$01 + LDY #$00 JMP FETCHOP CALLX INY ;+INC_IP LDA (IP),Y @@ -1812,7 +1812,7 @@ CALLX INY ;+INC_IP LDA (IP),Y STA TMPH TYA - CLC + SEC ADC IPL PHA LDA IPH @@ -1834,7 +1834,7 @@ CALLX INY ;+INC_IP STA IPL LDA #>OPXTBL ; MAKE SURE WE'RE INDEXING THE RIGHT TABLE STA OPPAGE - LDY #$01 + LDY #$00 JMP FETCHOP ;* ;* INDIRECT CALL TO ADDRESS (NATIVE CODE) @@ -1845,7 +1845,7 @@ ICAL LDA ESTKL,X STA TMPH INX TYA - CLC + SEC ADC IPL PHA LDA IPH @@ -1858,7 +1858,7 @@ ICAL LDA ESTKL,X STA IPL LDA #>OPTBL ; MAKE SURE WE'RE INDEXING THE RIGHT TABLE STA OPPAGE - LDY #$01 + LDY #$00 JMP FETCHOP ICALX LDA ESTKL,X STA TMPL @@ -1866,7 +1866,7 @@ ICALX LDA ESTKL,X STA TMPH INX TYA - CLC + SEC ADC IPL PHA LDA IPH @@ -1887,7 +1887,7 @@ ICALX LDA ESTKL,X STA IPL LDA #>OPXTBL ; MAKE SURE WE'RE INDEXING THE RIGHT TABLE STA OPPAGE - LDY #$01 + LDY #$0 JMP FETCHOP ;* ;* JUMP INDIRECT TRHOUGH TMP diff --git a/src/vmsrc/apple/plvm03.s b/src/vmsrc/apple/plvm03.s index 269529d..3a3abc4 100755 --- a/src/vmsrc/apple/plvm03.s +++ b/src/vmsrc/apple/plvm03.s @@ -1272,11 +1272,28 @@ ADDBRLE LDA ESTKL,X ;* INDIRECT CALL TO ADDRESS (NATIVE CODE) ;* ICAL LDA ESTKL,X - STA CALLADR+1 + STA ICALADR+1 LDA ESTKH,X - STA CALLADR+2 + STA ICALADR+2 INX - BNE _CALL + TYA + SEC + ADC IPL + PHA + LDA IPH + ADC #$00 + PHA + LDA IPX + PHA +ICALADR JSR $FFFF + PLA + STA IPX + PLA + STA IPH + PLA + STA IPL + LDY #$00 + JMP FETCHOP ;* ;* CALL INTO ABSOLUTE ADDRESS (NATIVE CODE) ;* @@ -1286,7 +1303,7 @@ CALL INY ;+INC_IP INY ;+INC_IP LDA (IP),Y STA CALLADR+2 -_CALL TYA + TYA SEC ADC IPL PHA diff --git a/src/vmsrc/apple/plvm802.s b/src/vmsrc/apple/plvm802.s index 9c3df63..9f8b860 100644 --- a/src/vmsrc/apple/plvm802.s +++ b/src/vmsrc/apple/plvm802.s @@ -1518,7 +1518,7 @@ CALL INY ;+INC_IP INY EMUSTK STA TMP TYA ; FLATTEN IP - CLC + SEC ADC IP STA IP SEC ; SWITCH TO EMULATED MODE @@ -1614,7 +1614,7 @@ EMUSTK STA TMP LDX #>DBGTBL } STX OPPAGE - LDY #$01 + LDY #$00 JMP FETCHOP ;* ;* INDIRECT CALL TO ADDRESS (NATIVE CODE) @@ -1629,7 +1629,7 @@ CALLX INY ;+INC_IP INY EMUSTKX STA TMP TYA ; FLATTEN IP - CLC + SEC ADC IP STA IP SEC ; SWITCH TO EMULATION MODE @@ -1727,7 +1727,7 @@ EMUSTKX STA TMP LDX #>DBGTBL } STX OPPAGE - LDY #$01 + LDY #$00 JMP FETCHOP ;* ;* JUMP INDIRECT THROUGH TMP From 4dcc033ed0be81dbda6da65fce08eb69597d3019 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Tue, 20 Mar 2018 14:19:17 -0700 Subject: [PATCH 071/147] Invokable JIT compiler version --- src/libsrc/apple/jit.pla | 48 + src/makefile | 21 +- src/mkrel | 3 + src/vmsrc/apple/cmdjit.pla | 1529 ++++++++++++++++++++++ src/vmsrc/apple/cmdjitstub.s | 48 + src/vmsrc/apple/plvm02.s | 8 +- src/vmsrc/apple/plvmjit02.s | 2353 ++++++++++++++++++++++++++++++++++ 7 files changed, 4003 insertions(+), 7 deletions(-) create mode 100644 src/libsrc/apple/jit.pla create mode 100755 src/vmsrc/apple/cmdjit.pla create mode 100644 src/vmsrc/apple/cmdjitstub.s create mode 100755 src/vmsrc/apple/plvmjit02.s diff --git a/src/libsrc/apple/jit.pla b/src/libsrc/apple/jit.pla new file mode 100644 index 0000000..968e99f --- /dev/null +++ b/src/libsrc/apple/jit.pla @@ -0,0 +1,48 @@ +// +// PLASMA JIT bytecode compiler +// +include "inc/cmdsys.plh" +// +// Module don't free memory +// +const modkeep = $2000 +const modinitkeep = $4000 +// +// Indirect interpreter DEFinition entrypoint +// +struc t_defentry + byte interpjsr + word interpaddr + word bytecodeaddr + byte callcount + byte bytecodesize +end +// +// JIT compiler constants +// +const jitcount = $10 +const jitcomp = $03E2 +const jitcodeptr = $03E4 +// +// AUX bytecode interpreter entrypoint +// +const interpentry = $03DC +// +// JIT compiler entry +// +def compiler(defptr)#0 + puts("JIT compiler invoked!\n") + + defptr=>interpaddr = interpentry +end +// +// Install JIT compiler +// +if *jitcomp + puts("JIT compiler already installed!\n") + return 0 +fin +puts("Installing JIT compiler\n") +*jitcomp = @compiler +return modkeep +done diff --git a/src/makefile b/src/makefile index 3c94fc5..48a8ba8 100755 --- a/src/makefile +++ b/src/makefile @@ -4,13 +4,16 @@ PLVM = plvm PLVMZP_APL = vmsrc/apple/plvmzp.inc PLVM01 = rel/apple/A1PLASMA\#060280 PLVM02 = rel/apple/PLASMA.SYSTEM\#FF2000 +PLVMJIT = rel/apple/PLASMAJIT.SYSTEM\#FF2000 PLVM802 = rel/apple/PLASMA16.SYSTEM\#FF2000 PLVM03 = rel/apple/SOS.INTERP\#050000 SOSCMD = rel/apple/SOS.CMD\#FE1000 CMD = rel/apple/CMD\#061000 +CMDJIT = rel/apple/CMDJIT\#061000 PLVMZP_C64 = vmsrc/c64/plvmzp.inc PLVMC64 = rel/c64/PLASMA ED = rel/ED\#FE1000 +JIT = rel/apple/JIT\#FE1000 SOS = rel/apple/SOS\#FE1000 ROD = rel/ROD\#FE1000 SIEVE = rel/SIEVE\#FE1000 @@ -76,7 +79,7 @@ TXTTYPE = .TXT #SYSTYPE = \#FF2000 #TXTTYPE = \#040000 -apple: $(PLVMZP_APL) $(PLASM) $(PLVM) $(PLVM01) $(PLVM02) $(PLVM802) $(PLVM03) $(CMD) $(SOSCMD) $(PLASMAPLASM) $(CODEOPT) $(ARGS) $(MEMMGR) $(MEMTEST) $(FIBER) $(FIBERTEST) $(LONGJMP) $(ED) $(MON) $(SOS) $(ROD) $(SIEVE) $(UTHERNET2) $(UTHERNET) $(ETHERIP) $(INET) $(DHCP) $(HTTPD) $(ROGUE) $(ROGUEMAP) $(ROGUECOMBAT) $(GRAFIX) $(GFXDEMO) $(DGR) $(DGRTEST) $(FILEIO_APL) $(CONIO_APL) $(JOYBUZZ) $(PORTIO) $(SPIPORT) $(SDFAT) $(FATCAT) $(FATGET) $(FATPUT) $(FATWDSK) $(FATRDSK) $(SANE) $(FPSTR) $(FPU) $(SANITY) $(RPNCALC) $(SNDSEQ) $(PLAYSEQ) +apple: $(PLVMZP_APL) $(PLASM) $(PLVM) $(PLVM01) $(PLVM02) $(PLVMJIT) $(PLVM802) $(PLVM03) $(CMD) $(CMDJIT) $(JIT) $(SOSCMD) $(PLASMAPLASM) $(CODEOPT) $(ARGS) $(MEMMGR) $(MEMTEST) $(FIBER) $(FIBERTEST) $(LONGJMP) $(ED) $(MON) $(SOS) $(ROD) $(SIEVE) $(UTHERNET2) $(UTHERNET) $(ETHERIP) $(INET) $(DHCP) $(HTTPD) $(ROGUE) $(ROGUEMAP) $(ROGUECOMBAT) $(GRAFIX) $(GFXDEMO) $(DGR) $(DGRTEST) $(FILEIO_APL) $(CONIO_APL) $(JOYBUZZ) $(PORTIO) $(SPIPORT) $(SDFAT) $(FATCAT) $(FATGET) $(FATPUT) $(FATWDSK) $(FATRDSK) $(SANE) $(FPSTR) $(FPU) $(SANITY) $(RPNCALC) $(SNDSEQ) $(PLAYSEQ) -rm vmsrc/plvmzp.inc c64: $(PLVMZP_C64) $(PLASM) $(PLVM) $(PLVMC64) @@ -85,7 +88,7 @@ c64: $(PLVMZP_C64) $(PLASM) $(PLVM) $(PLVMC64) all: apple c64 clean: - -rm *FE1000 *FF2000 $(PLASM) $(PLVM) $(PLVM01) $(PLVM02) $(PLVM03) + -rm *FE1000 *FF2000 $(PLASM) $(PLVM) $(PLVM01) $(PLVM02) $(PLVMJIT) $(PLVM03) -rm -rf rel -rm samplesrc/*.o samplesrc/*~ samplesrc/*.a -rm toolsrc/*.o toolsrc/*~ toolsrc/*.a @@ -149,6 +152,10 @@ $(CMD): vmsrc/apple/cmd.pla vmsrc/apple/cmdstub.s $(PLVM02) $(PLASM) ./$(PLASM) -AOW < vmsrc/apple/cmd.pla > vmsrc/apple/cmd.a acme --setpc 8192 -o $(CMD) vmsrc/apple/cmdstub.s +$(CMDJIT): vmsrc/apple/cmdjit.pla vmsrc/apple/cmdjitstub.s $(PLVMJIT) $(PLASM) + ./$(PLASM) -AOW < vmsrc/apple/cmdjit.pla > vmsrc/apple/cmdjit.a + acme --setpc 8192 -o $(CMDJIT) vmsrc/apple/cmdjitstub.s + $(SOSCMD): vmsrc/apple/soscmd.pla $(PLVM03) $(PLASM) ./$(PLASM) -AMOW < vmsrc/apple/soscmd.pla > vmsrc/apple/soscmd.a acme --setpc 4094 -o $(SOSCMD) vmsrc/apple/soscmd.a @@ -156,6 +163,9 @@ $(SOSCMD): vmsrc/apple/soscmd.pla $(PLVM03) $(PLASM) $(PLVM02): vmsrc/apple/plvm02.s acme -o $(PLVM02) -l vmsrc/apple/plvm02.sym vmsrc/apple/plvm02.s +$(PLVMJIT): vmsrc/apple/plvmjit02.s + acme -o $(PLVMJIT) -l vmsrc/apple/plvmjit02.sym vmsrc/apple/plvmjit02.s + $(PLVM802): vmsrc/apple/plvm802.s acme -o $(PLVM802) -l vmsrc/apple/plvm802.sym vmsrc/apple/plvm802.s @@ -351,7 +361,12 @@ $(MON): samplesrc/mon.pla $(PLVM02) $(PLASM) ./$(PLASM) -AMOW < samplesrc/mon.pla > samplesrc/mon.a acme --setpc 4094 -o $(MON) samplesrc/mon.a -$(SOS): libsrc/apple/sos.pla $(PLVM02) $(PLASM) +$(SOS): libsrc/apple/sos.pla $(PLVM03) $(PLASM) ./$(PLASM) -AMO < libsrc/apple/sos.pla > libsrc/apple/sos.a acme --setpc 4094 -o $(SOS) libsrc/apple/sos.a +$(JIT): libsrc/apple/jit.pla $(PLVMJIT) $(PLASM) + ./$(PLASM) -AMO < libsrc/apple/jit.pla > libsrc/apple/jit.a + acme --setpc 4094 -o $(JIT) libsrc/apple/jit.a + + diff --git a/src/mkrel b/src/mkrel index e8a1af0..311722b 100755 --- a/src/mkrel +++ b/src/mkrel @@ -1,5 +1,7 @@ cp rel/apple/CMD#061000 prodos/CMD.BIN +cp rel/apple/CMDJIT#061000 prodos/CMDJIT.BIN cp rel/apple/PLASMA.SYSTEM#FF2000 prodos/PLASMA.SYSTEM.SYS +cp rel/apple/PLASMAJIT.SYSTEM#FF2000 prodos/PLAJIT.SYSTEM.SYS cp rel/apple/PLASMA16.SYSTEM#FF2000 prodos/PLASMA16.SYSTEM.SYS cp rel/apple/SOS.INTERP#050000 prodos/SOS.INTERP.\$05 cp rel/apple/SOS.CMD#FE1000 prodos/SOS.CMD.REL @@ -30,6 +32,7 @@ cp rel/apple/UTHERNET#FE1000 prodos/sys/UTHERNET.REL cp rel/apple/UTHERNET2#FE1000 prodos/sys/UTHERNET2.REL cp rel/apple/SOS#FE1000 prodos/sys/SOS.REL cp rel/apple/GRAFIX#FE1000 prodos/sys/GRAFIX.REL +cp rel/apple/JIT#FE1000 prodos/sys/JIT.REL cp ../sysfiles/FP6502.CODE#060000 prodos/sys/FP6502.CODE.BIN cp ../sysfiles/ELEMS.CODE#060000 prodos/sys/ELEMS.CODE.BIN diff --git a/src/vmsrc/apple/cmdjit.pla b/src/vmsrc/apple/cmdjit.pla new file mode 100755 index 0000000..1b65fbd --- /dev/null +++ b/src/vmsrc/apple/cmdjit.pla @@ -0,0 +1,1529 @@ +const MACHID = $BF98 +const iobuffer = $0800 +const databuff = $2000 +const RELADDR = $1000 +const symtbl = $0C00 +const freemem = $0006 +const getlnbuf = $01FF +// +// System flags: memory allocator screen holes. +// +const restxt1 = $0001 +const restxt2 = $0002 +const resxtxt1 = $0004 +const resxtxt2 = $0008 +const reshgr1 = $0010 +const reshgr2 = $0020 +const resxhgr1 = $0040 +const resxhgr2 = $0080 +// +// Module don't free memory +// +const modkeep = $2000 +const modinitkeep = $4000 +// +// Prefix commands +// +const GET_PFX = $C7 +const SET_PFX = $C6 +// +// Indirect interpreter DEFinition entrypoint +// +struc t_defentry + byte interpjsr + word interpaddr + word bytecodeaddr + byte callcount + byte bytecodesize +end +// +// JIT compiler constants +// +const jitcount = $10 +const jitcomp = $03E2 +const jitcodeptr = $03E4 +const jitcode = $BF00 +// +// Pedefined functions. +// +predef syscall(cmd,params)#1, call(addr,areg,xreg,yreg,status)#1 +predef crout()#0, cout(c)#0, prstr(s)#0, prbyte(b)#0, prword(w)#0, print(i)#0, cin()#1, rdstr(p)#1, toupper(c)#1 +predef markheap()#1, allocheap(size)#1, allocalignheap(size, pow2, freeaddr)#1, releaseheap(newheap)#1, availheap()#1 +predef memset(addr,value,size)#0, memcpy(dst,src,size)#0, strcpy(dst,src)#1, strcat(dst,src)#1 +predef uword_isgt(a,b)#1, uword_isge(a,b)#1, uword_islt(a,b)#1, uword_isle(a,b)#1, sext(a)#1, divmod(a,b)#2 +predef execmod(modfile)#1, open(path)#1, close(refnum)#1, read(refnum, buff, len)#1, write(refnum, buff, len)#1 +// +// Exported CMDSYS table +// +word version = $0200 // 02.00 Dev +word syspath +word syscmdln +word = @execmod, @open, @close, @read, @write +byte perr +// +// Working input buffer overlayed with strings table +// +byte cmdln = "" +// +// DCI version of JIT +// +byte jitmod = 'J'|$80, 'I'|$80, 'T' +// +// Name for auto-run file (must follow cmdln) +// +byte autorun = "AUTORUN" +// +// Standard Library exported functions. +// +byte sysmodstr = "CMDSYS" +byte putsstr = "PUTS" +byte putistr = "PUTI" +byte putcstr = "PUTC" +byte putlnstr = "PUTLN" +byte putbstr = "PUTB" +byte putwstr = "PUTH" +byte getcstr = "GETC" +byte getsstr = "GETS" +byte toupstr = "TOUPPER" +byte strcpystr = "STRCPY" +byte strcatstr = "STRCAT" +byte hpmarkstr = "HEAPMARK" +byte hpalignstr = "HEAPALLOCALIGN" +byte hpallocstr = "HEAPALLOC" +byte hprelstr = "HEAPRELEASE" +byte hpavlstr = "HEAPAVAIL" +byte sysmods[] // overlay with exported strings +word memsetstr = "MEMSET" +byte memcpystr = "MEMCPY" +byte uisgtstr = "ISUGT" +byte uisgestr = "ISUGE" +byte uisltstr = "ISULT" +byte uislestr = "ISULE" +byte sextstr = "SEXT" +byte divmodstr = "DIVMOD" +byte machidstr = "MACHID" +byte sysstr = "SYSCALL" +byte callstr = "CALL" +byte prefix[] // overlay with exported symbols table +word exports = @sysmodstr, @version +word = @sysstr, @syscall +word = @callstr, @call +word = @putcstr, @cout +word = @putlnstr, @crout +word = @putsstr, @prstr +word = @putbstr, @prbyte +word = @putwstr, @prword +word = @putistr, @print +word = @getcstr, @cin +word = @getsstr, @rdstr +word = @toupstr, @toupper +word = @hpmarkstr, @markheap +word = @hpallocstr,@allocheap +word = @hpalignstr,@allocalignheap +word = @hprelstr, @releaseheap +word = @hpavlstr, @availheap +word = @memsetstr, @memset +word = @memcpystr, @memcpy +word = @uisgtstr, @uword_isgt +word = @uisgestr, @uword_isge +word = @uisltstr, @uword_islt +word = @uislestr, @uword_isle +word = @strcpystr, @strcpy +word = @strcatstr, @strcat +word = @sextstr, @sext +word = @divmodstr, @divmod +word = @machidstr, MACHID +word = 0 +word sysmodsym = @exports +// +// System variable. +// +word systemflags = 0 +word heap +word xheap = $0800 +word lastsym = symtbl +// +// Utility functions +// +//asm equates included from cmdstub.s +// +asm saveX#0 + STX XREG+1 +end +asm restoreX#0 +XREG LDX #$00 + RTS +end +// CALL PRODOS +// SYSCALL(CMD, PARAMS) +// +asm syscall(cmd,params)#1 + LDA ESTKL,X + LDY ESTKH,X + STA PARAMS + STY PARAMS+1 + INX + LDA ESTKL,X + STA CMD + JSR $BF00 +CMD: !BYTE 00 +PARAMS: !WORD 0000 +; LDY #$00 + STA ESTKL,X +; STY ESTKH,X + RTS +end +// +// CALL 6502 ROUTINE +// CALL(ADDR, AREG, XREG, YREG, STATUS) +// +asm call(addr,areg,xreg,yreg,status)#1 +REGVALS = SRC + PHP + LDA ESTKL+4,X + STA TMPL + LDA ESTKH+4,X + STA TMPH + LDA ESTKL,X + PHA + LDY ESTKL+1,X + LDA ESTKL+3,X + PHA + LDA ESTKL+2,X + INX + INX + INX + INX + STX ESP + TAX + PLA + BIT ROMEN + PLP + JSR JMPTMP + PHP + BIT LCRDEN+LCBNK2 + STA REGVALS+0 + STX REGVALS+1 + STY REGVALS+2 + PLA + STA REGVALS+3 + LDX ESP + LDA #REGVALS + STA ESTKL,X + STY ESTKH,X + PLP + RTS +end +// +// CALL LOADED SYSTEM PROGRAM +// +asm exec()#0 + BIT ROMEN + JMP $2000 +end +// +// EXIT +// +asm reboot()#0 + BIT ROMEN + DEC $03F4 ; INVALIDATE POWER-UP BYTE + JMP ($FFFC) ; RESET +end +// +// SET MEMORY TO VALUE +// MEMSET(ADDR, VALUE, SIZE) +// With optimizations from Peter Ferrie +// +asm memset(addr,value,size)#0 + LDA ESTKL+2,X + STA DSTL + LDA ESTKH+2,X + STA DSTH + LDY ESTKL,X + BEQ + + INC ESTKH,X + LDY #$00 ++ LDA ESTKH,X + BEQ SETMEX +SETMLPL CLC + LDA ESTKL+1,X +SETMLPH STA (DST),Y + DEC ESTKL,X + BEQ ++ +- INY + BEQ + +-- BCS SETMLPL + SEC + LDA ESTKH+1,X + BCS SETMLPH ++ INC DSTH + BNE -- +++ DEC ESTKH,X + BNE - +SETMEX INX + INX + INX + RTS +end +// +// COPY MEMORY +// MEMCPY(DSTADDR, SRCADDR, SIZE) +// +asm memcpy(dst,src,size)#0 + INX + INX + INX + LDA ESTKL-3,X + ORA ESTKH-3,X + BEQ CPYMEX + LDA ESTKL-2,X + CMP ESTKL-1,X + LDA ESTKH-2,X + SBC ESTKH-1,X + BCC REVCPY +; +; FORWARD COPY +; + LDA ESTKL-1,X + STA DSTL + LDA ESTKH-1,X + STA DSTH + LDA ESTKL-2,X + STA SRCL + LDA ESTKH-2,X + STA SRCH + LDY ESTKL-3,X + BEQ FORCPYLP + INC ESTKH-3,X + LDY #$00 +FORCPYLP LDA (SRC),Y + STA (DST),Y + INY + BNE + + INC DSTH + INC SRCH ++ DEC ESTKL-3,X + BNE FORCPYLP + DEC ESTKH-3,X + BNE FORCPYLP + RTS +; +; REVERSE COPY +; +REVCPY ;CLC + LDA ESTKL-3,X + ADC ESTKL-1,X + STA DSTL + LDA ESTKH-3,X + ADC ESTKH-1,X + STA DSTH + CLC + LDA ESTKL-3,X + ADC ESTKL-2,X + STA SRCL + LDA ESTKH-3,X + ADC ESTKH-2,X + STA SRCH + DEC DSTH + DEC SRCH + LDY #$FF + LDA ESTKL-3,X + BEQ REVCPYLP + INC ESTKH-3,X +REVCPYLP LDA (SRC),Y + STA (DST),Y + DEY + CPY #$FF + BNE + + DEC DSTH + DEC SRCH ++ DEC ESTKL-3,X + BNE REVCPYLP + DEC ESTKH-3,X + BNE REVCPYLP +CPYMEX RTS +end +// +// COPY FROM MAIN MEM TO AUX MEM. +// +// MEMXCPY(DST, SRC, SIZE) +// +asm memxcpy(dst,src,size)#0 + LDA ESTKL+1,X + STA $3C + CLC + ADC ESTKL,X + STA $3E + LDA ESTKH+1,X + STA $3D + ADC ESTKH,X + STA $3F + LDA ESTKL+2,X + STA $42 + LDA ESTKH+2,X + STA $43 + STX ESP + BIT ROMEN + SEC + JSR $C311 + BIT LCRDEN+LCBNK2 + LDX ESP + INX + INX + INX + RTS +end +asm crout()#0 + LDA #$8D + BNE ++ +end +// +// CHAR OUT +// COUT(CHAR) +// +asm cout(c)#0 + LDA ESTKL,X + BIT $BF98 + BMI + + JSR TOUPR ++ ORA #$80 + INX +++ BIT ROMEN + JSR $FDED + BIT LCRDEN+LCBNK2 + RTS +end +// +// CHAR IN +// RDKEY() +// +asm cin()#1 + BIT ROMEN + JSR $FD0C + BIT LCRDEN+LCBNK2 + DEX + LDY #$00 + AND #$7F + STA ESTKL,X + STY ESTKH,X + RTS +end +// +// PRINT STRING +// PRSTR(STR) +// +asm prstr(s)#0 + LDY #$00 + LDA ESTKL,X + STA SRCL + LDA ESTKH,X + STA SRCH + LDA (SRC),Y + BEQ ++ + STA TMP + BIT ROMEN +- INY + LDA (SRC),Y + BIT $BF98 + BMI + + JSR TOUPR ++ ORA #$80 + JSR $FDED + CPY TMP + BNE - + BIT LCRDEN+LCBNK2 +++ INX + RTS +end +// +// PRINT WORD +// +asm prword(w)#0 + LDA ESTKH,X + JSR + + DEX + ; FALL THROUGH TO PRBYTE +end +// +// PRINT BYTE +// +asm prbyte(b)#0 + LDA ESTKL,X ++ STX ESP + BIT ROMEN + JSR $FDDA + LDX ESP + BIT LCRDEN+LCBNK2 + INX + RTS +end +// +// READ STRING +// STR = RDSTR(PROMPTCHAR) +// +asm rdstr(p)#1 + LDA ESTKL,X + STA $33 + STX ESP + BIT ROMEN + JSR $FD6A + STX $01FF +- LDA $01FF,X + AND #$7F + STA $01FF,X + DEX + BPL - + TXA + LDX ESP + STA ESTKL,X + LDA #$01 + STA ESTKH,X + BIT LCRDEN+LCBNK2 + RTS +end +asm uword_isge(a,b)#1 + LDA ESTKL+1,X + CMP ESTKL,X + LDA ESTKH+1,X + SBC ESTKH,X + LDA #$FF + ADC #$00 + EOR #$FF + STA ESTKL+1,X + STA ESTKH+1,X + INX + RTS +end +asm uword_isle(a,b)#1 + LDA ESTKL,X + CMP ESTKL+1,X + LDA ESTKH,X + SBC ESTKH+1,X + LDA #$FF + ADC #$00 + EOR #$FF + STA ESTKL+1,X + STA ESTKH+1,X + INX + RTS +end +asm uword_isgt(a,b)#1 + LDA ESTKL,X + CMP ESTKL+1,X + LDA ESTKH,X + SBC ESTKH+1,X + LDA #$FF + ADC #$00 + STA ESTKL+1,X + STA ESTKH+1,X + INX + RTS +end +asm uword_islt(a,b)#1 + LDA ESTKL+1,X + CMP ESTKL,X + LDA ESTKH+1,X + SBC ESTKH,X + LDA #$FF + ADC #$00 + STA ESTKL+1,X + STA ESTKH+1,X + INX + RTS +end +asm divmod(a,b)#2 + JSR INTERP ; CALL INTERP + !BYTE $36, $5C ; DIVMOD, RET +end +asm sext(a)#1 + LDY #$00 + LDA ESTKL,X + BPL + + DEY ++ STY ESTKH,X + RTS +end +// +// Utility routines. +// +// A DCI string is one that has the high bit set for every character except the last. +// More efficient than C or Pascal strings. +// +//def dcitos(dci, str) +// byte len, c +// len = 0 +// repeat +// c = (dci).[len] +// len = len + 1 +// (str).[len] = c & $7F +// until !(c & $80) +// ^str = len +// return len +//end +asm dcitos(dci, str)#1 + LDA ESTKL,X + STA DSTL + LDA ESTKH,X + STA DSTH + LDA ESTKL+1,X + STA SRCL + LDA ESTKH+1,X + STA SRCH + LDY #$00 +- LDA (SRC),Y + CMP #$80 + AND #$7F + INY + STA (DST),Y + BCS - + TYA + LDY #$00 + STA (DST),Y + INX + STA ESTKL,X + STY ESTKH,X + RTS +end +//def stodci(str, dci) +// byte len, c +// len = ^str +// if len == 0 +// return +// fin +// c = toupper((str).[len]) & $7F +// len = len - 1 +// (dci).[len] = c +// while len +// c = toupper((str).[len]) | $80 +// len = len - 1 +// (dci).[len] = c +// loop +// return ^str +//end +asm stodci(str,dci)#1 + LDA ESTKL,X + STA DSTL + LDA ESTKH,X + STA DSTH + LDA ESTKL+1,X + STA SRCL + LDA ESTKH+1,X + STA SRCH + INX + LDY #$00 + LDA (SRC),Y + BEQ ++ + TAY + LDA (SRC),Y + JSR TOUPR + BNE + +- LDA (SRC),Y + JSR TOUPR + ORA #$80 ++ DEY + STA (DST),Y + BNE - + LDA (SRC),Y +++ STA ESTKL,X + STY ESTKH,X + RTS +end +asm toupper(c)#1 + LDA ESTKL,X +TOUPR AND #$7F + CMP #'a' + BCC + + CMP #'z'+1 + BCS + + SBC #$1F ++ STA ESTKL,X + RTS +end +// +// Lookup routines. +// +//def lookuptbl(dci, tbl) +// word match +// while ^tbl +// match = dci +// while ^tbl == ^match +// if !(^tbl & $80) +// return (tbl):1 +// fin +// tbl = tbl + 1 +// match = match + 1 +// loop +// while (^tbl & $80) +// tbl = tbl + 1 +// loop +// tbl = tbl + 3 +// loop +// return 0 +asm lookuptbl(dci, tbl)#1 + LDA ESTKL,X + STA DSTL + LDA ESTKH,X + STA DSTH + INX + LDA ESTKL,X + STA SRCL + LDA ESTKH,X + STA SRCH +-- LDY #$00 +- LDA (DST),Y + BEQ + + CMP (SRC),Y + BNE ++ + INY + ASL + BCS - + LDA (DST),Y + STA ESTKL,X ; MATCH + INY + LDA (DST),Y + STA ESTKH,X + RTS ++ STA ESTKL,X ; NO MATCH + STA ESTKH,X + RTS +++ +- LDA (DST),Y ; NEXT ENTRY + BPL + + INY + BNE - ++ TYA + CLC + ADC #$03 + ADC DSTL + STA DSTL + BCC -- + INC DSTH + BNE -- +end +// def lookupidx(esd, index) +// word sym +// while ^esd +// sym = esd +// esd = sym + dcitos(sym, @str) +// if esd->0 & $10 and esd->1 == index +// return sym +// fin +// esd = esd + 3 +// loop +//end +asm lookupidx(esd, index)#1 + LDA ESTKL,X + STA TMPL + INX +--- LDA ESTKH,X + STA SRCH + LDA ESTKL,X +-- STA SRCL + LDY #$00 +- LDA (SRC),Y + BPL + + INY + BNE - ++ BEQ ++ ; END OF ESD + INY + LDA (SRC),Y + INY + AND #$10 ; EXTERN FLAG? + BEQ + + LDA (SRC),Y + CMP TMPL + BEQ +++ ; MATCH ++ INY + TYA + SEC + ADC SRCL + STA ESTKL,X ; SYM PTRL + BCC -- + INC ESTKH,X ; SYM PTRH + BNE --- +++ STA ESTKL,X ; END OF ESD + STA ESTKH,X ++++ RTS +end +//def lookupdef(addr, deftbl)#1 +// while deftbl->interpjsr == $20 +// if deftbl=>bytecodeaddr == addr +// return deftbl +// fin +// deftbl = deftbl + t_defentry +// loop +// return 0 +//end +asm lookupdef(addr, deftbl)#1 + LDA ESTKH,X + STA SRCH + LDA ESTKL,X + STA SRCL + INX +- LDY #$00 + LDA (SRC),Y + CMP #$20 ; JSR OPCODE? + BNE ++ + LDY #$03 + LDA (SRC),Y + CMP ESTKL,X + BNE + + INY + LDA (SRC),Y + CMP ESTKH,X + BNE + + LDA SRCL ; MATCH + STA ESTKL,X + LDA SRCH + STA ESTKH,X + RTS ++ LDA #$07 ; NEXT ENTRY + CLC + ADC SRCL + STA SRCL + BCC - + INC SRCH + BNE - +++ STY ESTKL,X + STY ESTKH,X + RTS +end +// +// Reloc internal data +// +//def reloc(modfix, modofst, bytecode, rld)#3 +// word addr, fixup +// while ^rld +// if ^rld & $10 // EXTERN reference. +// return rld, addr, fixup +// fin +// addr = rld=>1 + modfix +// fixup = *addr + modofst +// if uword_isge(fixup, bytecode) // Bytecode address. +// return rld, addr, fixup +// fin +// *addr = fixup +// rld = rld + 4 +// loop +// return rld, addr, fixup +//end +asm reloc(modfix, modofst, bytecode, rld)#3 + LDA ESTKL,X + STA SRCL + LDA ESTKH,X + STA SRCH + LDY #$00 +- LDA (SRC),Y + BEQ RLDEX ; END OF RLD + PHA + INY + LDA (SRC),Y + INY + CLC + ADC ESTKL+3,X ; ADDR=ENTRY=>1+MODFIX + STA DSTL + LDA (SRC),Y + ADC ESTKH+3,X + STA DSTH + PLA + AND #$10 ; EXTERN REF - EXIT + BNE RLDEX + TAY ; FIXUP=*ADDR+MODOFST + LDA (DST),Y + INY + CLC + ADC ESTKL+2,X + STA TMPL + LDA (DST),Y + ADC ESTKH+2,X + CMP ESTKH+1,X ; FIXUP >= BYTECODE? + BCC + + STA TMPH + BNE RLDEX ; YEP, EXIT + LDA TMPL + CMP ESTKL+1,X + BCS RLDEX ; YEP, EXIT + LDA TMPH ++ STA (DST),Y ; *ADDR=FIXUP + DEY + LDA TMPL + STA (DST),Y + LDA SRCL ; NEXT ENTRY +; CLC + ADC #$04 + STA SRCL + BCC - + INC SRCH + BNE - +RLDEX INX + LDA TMPL + STA ESTKL,X + LDA TMPH + STA ESTKH,X + LDA DSTL + STA ESTKL+1,X + LDA DSTH + STA ESTKH+1,X + LDA SRCL + STA ESTKL+2,X + LDA SRCH + STA ESTKH+2,X + RTS +end +// +// Cheap and dirty print integer +// +def print(i)#0 + if i < 0; cout('-'); i = -i; fin + if i >= 10; print(i / 10); fin + cout(i % 10 + '0') +end +// +// ProDOS routines +// +def pfxop(path, op)#1 + byte params[3] + + params.0 = 1 + params:1 = path + perr = syscall(op, @params) + return path +end +def open(path)#1 + byte params[6] + + params.0 = 3 + params:1 = path + params:3 = iobuffer + params.5 = 0 + perr = syscall($C8, @params) + return params.5 +end +def close(refnum)#1 + byte params[2] + + params.0 = 1 + params.1 = refnum + perr = syscall($CC, @params) + return perr +end +def read(refnum, buff, len)#1 + byte params[8] + + params.0 = 4 + params.1 = refnum + params:2 = buff + params:4 = len + params:6 = 0 + perr = syscall($CA, @params) + return params:6 +end +def write(refnum, buf, len)#1 + byte params[8] + + params.0 = 4 + params.1 = refnum + params:2 = buf + params:4 = len + params:6 = 0 + perr = syscall($CB, @params) + return params:6 +end +// +// Heap routines. +// +def availheap()#1 + byte fp + return @fp - heap +end +def allocheap(size)#1 + word addr + addr = heap + heap = heap + size + if systemflags & reshgr1 + if uword_islt(addr, $4000) and uword_isgt(heap, $2000) + addr = $4000 + heap = addr + size + fin + fin + if systemflags & reshgr2 + if uword_islt(addr, $6000) and uword_isgt(heap, $4000) + addr = $6000 + heap = addr + size + fin + fin + if uword_isge(heap, @addr) + return 0 + fin + return addr +end +def allocalignheap(size, pow2, freeaddr) + word align, addr + if freeaddr + *freeaddr = heap + fin + align = (1 << pow2) - 1 + addr = (heap | align) + 1 + heap = addr + size + if uword_isge(heap, @addr) + return 0 + fin + return addr +end +def markheap()#1 + return heap +end +def releaseheap(newheap)#1 + heap = newheap + return @newheap - heap +end +def allocxheap(size)#1 + word xaddr + xaddr = xheap + xheap = xheap + size + if systemflags & restxt1 + if uword_isle(xaddr, $0800) and uword_isgt(xheap, $0400) + xaddr = $0800 + xheap = xaddr + size + fin + fin + if systemflags & restxt2 + if uword_isle(xaddr, $0C00) and uword_isgt(xheap, $0800) + xaddr = $0C00 + xheap = xaddr + size + fin + fin + if systemflags & resxhgr1 + if uword_isle(xaddr, $4000) and uword_isgt(xheap, $2000) + xaddr = $4000 + xheap = xaddr + size + fin + fin + if systemflags & resxhgr2 + if uword_isle(xaddr, $6000) and uword_isgt(xheap, $4000) + xaddr = $6000 + xheap = xaddr + size + fin + fin + if uword_isge(xheap, $BF00) + return 0 + fin + return xaddr +end +// +// Symbol table routines. +// +def addsym(sym, addr)#0 + while ^sym & $80 + ^lastsym = ^sym + lastsym++ + sym++ + loop + lastsym->0 = ^sym + lastsym=>1 = addr + lastsym = lastsym + 3 + ^lastsym = 0 +end +// +// String routines. +// +def strcpy(dst, src)#1 + memcpy(dst+1, src+1, ^src) + ^dst = ^src + return dst +end +def strcat(dst, src)#1 + memcpy(dst + ^dst + 1, src + 1, ^src) + ^dst = ^dst + ^src + return dst +end +// +// Module routines. +// +def lookupextern(esd, index)#1 + word sym, addr + byte str[16] + sym = lookupidx(esd, index) + if sym + addr = lookuptbl(sym, symtbl) + if !addr + perr = $81 + dcitos(sym, @str) + cout('?'); prstr(@str); crout + fin + return addr + fin + return 0 +end +// +// Indirect interpreter DEFinition entrypoint +// +def adddef(isfirst, addr, deflast)#1 + word preventry, defentry, defsize + + defentry = *deflast + *deflast = defentry + t_defentry + if not isfirst + preventry = defentry - t_defentry + defsize = addr - preventry=>bytecodeaddr + if *jitcomp and defsize < 256 + preventry=>interpaddr = $03D6 // JSR $03D6 (JIT INTERP) + preventry->callcount = jitcount // Set count + preventry->bytecodesize = defsize // Set size + fin + fin + defentry->interpjsr = $20 + defentry=>interpaddr = $03DC // JSR $03DC (BYTECODE INTERP) + defentry=>bytecodeaddr = addr + //defentry=>5 = 0 // Clear count and size + defentry->t_defentry = 0 // NULL out next entry + return defentry +end +def loadmod(mod)#1 + word rdlen, modsize, bytecode, codefix, defofst, defcnt, init, fixup + word addr, defaddr, modaddr, modfix, modofst, modend + word deftbl, deflast + word moddep, rld, esd, sym + byte refnum[], deffirst, str[16], filename[64] + byte header[128] + // + // Read the RELocatable module header (first 128 bytes) + // + dcitos(mod, @filename) + refnum = open(@filename) + if !refnum + // + // Try system path + // + refnum = open(strcpy(@filename,strcat(strcpy(@header, @sysmods), @filename))) + fin + if refnum + header.0 = $0A + header:1 = @filename + if not syscall($C4, @header) and header.4 <> $FE // Make sure it's a REL module + close(refnum) + perr = $4A // Incompatible type + return -perr + fin + rdlen = read(refnum, @header, 128) + modsize = header:0 + moddep = @header.1 + defofst = modsize + RELADDR + init = 0 + if rdlen > 4 and header:2 == $6502 // magic number + // + // This is an EXTended RELocatable (data+bytecode) module. + // + systemflags = header:4 | systemflags + defofst = header:6 + defcnt = header:8 + init = header:10 + moddep = @header.12 + // + // Load module dependencies. + // + while ^moddep + if !lookuptbl(moddep, symtbl) + close(refnum) + refnum = 0 + if loadmod(moddep) < 0 + return -perr + fin + fin + moddep = moddep + dcitos(moddep, @str) + loop + // + // Init def table. + // + deftbl = allocheap(defcnt * t_defentry + 1) + deflast = deftbl + if !refnum + // + // Reset read pointer. + // + refnum = open(@filename) + rdlen = read(refnum, @header, 128) + fin + fin + // + // Alloc heap space for relocated module (data + bytecode). + // + moddep = moddep + 1 + modfix = moddep - @header.2 // Adjust to skip header + modsize = modsize - modfix + rdlen = rdlen - modfix - 2 + modaddr = allocheap(modsize) + memcpy(modaddr, moddep, rdlen) + // + // Read in remainder of module into memory for fixups. + // + addr = modaddr + repeat + addr = addr + rdlen + rdlen = read(refnum, addr, 4096) + until rdlen <= 0 + close(refnum) + // + // Add module to symbol table. + // + addsym(mod, modaddr) + // + // Apply all fixups and symbol import/export. + // + modfix = modaddr - modfix + modofst = modfix - RELADDR + modend = modaddr + modsize + bytecode = defofst + modofst + rld = modend // Re-Locatable Directory + esd = rld // Extern+Entry Symbol Directory + while ^esd // Scan to end of ESD + esd = esd + 4 + loop + esd = esd + 1 + defaddr = allocxheap(rld - bytecode) + modend = bytecode + codefix = defaddr - bytecode + defofst = defaddr - defofst + // + // Run through the DeFinition Dictionary. + // + deffirst = 1 + while ^rld == $02 + // + // This is a bytcode def entry - add it to the def directory. + // + adddef(deffirst, rld=>1 + defofst, @deflast) + deffirst = 0 + rld = rld + 4 + loop + // + // Run through the Re-Location Dictionary. + // + while ^rld + rld, addr, fixup = reloc(modfix, modofst, bytecode, rld) + if ^rld + *addr = ^rld & $10 ?? *addr + lookupextern(esd, rld->3) :: lookupdef(fixup + codefix, deftbl) + rld = rld + 4 + fin + loop + // + // Run through the External/Entry Symbol Directory. + // + while ^esd + sym = esd + esd = esd + dcitos(esd, @str) + if ^esd & $08 + // + // EXPORT symbol - add it to the global symbol table. + // + addr = esd=>1 + modofst + if uword_isge(addr, bytecode) + // + // Use the def directory address for bytecode. + // + addr = lookupdef(addr + codefix, deftbl) + fin + addsym(sym, addr) + fin + esd = esd + 3 + loop + // + // Move bytecode to AUX bank. + // + memxcpy(defaddr, bytecode, modsize - (bytecode - modaddr)) + fin + if perr + return -perr + fin + // + // Free up rld+esd (and bytecode on 128K) in main memory. + // + releaseheap(modend) + // + // Call init routine if it exists. + // + fixup = 0 // This is repurposed for the return code + if init + init = init + defofst + fixup = adddef(deffirst, init, @deflast)() + if fixup < modinitkeep + // + // Free init routine unless initkeep + // + xheap = init + if fixup < 0 + perr = -fixup + fin + else + fixup = fixup & ~modinitkeep + fin + fin + return fixup +end +// +// Command mode +// +def volumes()#0 + byte params[4] + word strbuf + byte i + + params.0 = 2 + params.1 = 0 + params:2 = databuff + perr = syscall($C5, @params) + strbuf = databuff + for i = 0 to 15 + ^strbuf = ^strbuf & $0F + if ^strbuf + cout('/'); prstr(strbuf); crout() + fin + strbuf = strbuf + 16 + next +end +def catalog(path)#0 + byte refnum + byte firstblk + byte entrylen, entriesblk + byte i, type, len + word entry, filecnt + + if !^path + path = @prefix + fin + refnum = open(path) + if perr + return + fin + firstblk = 1 + repeat + if read(refnum, databuff, 512) == 512 + entry = databuff + 4 + if firstblk + entrylen = databuff.$23 + entriesblk = databuff.$24 + filecnt = databuff:$25 + entry = entry + entrylen + fin + for i = firstblk to entriesblk + type = ^entry + if type + len = type & $0F + ^entry = len + prstr(entry) + type = ' ' + when entry->$10 + is $0F // Is it a directory? + type = '/' + break + is $FF // SYSTEM file + type = '-' + break + is $FE // REL file + type = '+' + wend + cout(type) + for len = 18 - len downto 0 + cout(' ') + next + filecnt-- + fin + entry = entry + entrylen + next + firstblk = 0 + else + filecnt = 0 + fin + until !filecnt + close(refnum) + crout() +end +def stripchars(strptr)#1 + while ^strptr and ^(strptr + 1) > ' ' + memcpy(strptr + 1, strptr + 2, ^strptr) + ^strptr-- + loop + return ^strptr +end +def stripspaces(strptr)#0 + while ^strptr and ^(strptr + ^strptr) <= ' ' + ^strptr-- + loop + while ^strptr and ^(strptr + 1) <= ' ' + memcpy(strptr + 1, strptr + 2, ^strptr) + ^strptr-- + loop +end +def striptrail(strptr)#1 + byte i + + for i = 1 to ^strptr + if ^(strptr + i) <= ' ' + ^strptr = i - 1 + break + fin + next + return strptr +end +def parsecmd(strptr)#1 + byte cmd + + cmd = 0 + stripspaces(strptr) + if ^strptr + cmd = ^(strptr + 1) + memcpy(strptr + 1, strptr + 2, ^strptr) + ^strptr-- + fin + stripspaces(strptr) + return cmd +end +def resetmemfiles()#0 + // + // Close all files + // + ^$BFD8 = 0 + close(0) + // + // Set memory bitmap + // + memset($BF58, 0, 24) + ^$BF58 = $CF + ^$BF6F = $01 +end +def execsys(sysfile)#0 + byte refnum + word len + + if ^sysfile + strcpy($280, sysfile) + striptrail(sysfile) + refnum = open(sysfile) + if refnum + len = read(refnum, databuff, $FFFF) + resetmemfiles() + if len + strcpy(sysfile, $280) + if stripchars(sysfile) and ^$2000 == $4C and *$2003 == $EEEE + stripspaces(sysfile) + if ^$2005 >= ^sysfile + 1 + strcpy($2006, sysfile) + fin + fin + striptrail($280) + exec() + fin + fin + fin +end +def execmod(modfile)#1 + byte moddci[17] + word saveheap, savexheap, savesym, saveflags, savejit + + perr = 1 + if stodci(modfile, @moddci) + saveheap = heap + savexheap = xheap + savesym = lastsym + saveflags = systemflags + savejit = *jitcodeptr + if loadmod(@moddci) < modkeep + lastsym = savesym + xheap = savexheap + heap = saveheap + *jitcodeptr = savejit + fin + ^lastsym = 0 + systemflags = saveflags + fin + return -perr +end +// +// Get heap start. +// +heap = *freemem +// +// Print PLASMA version +// +prstr("PLASMA 2.0 Dev\n")//; prbyte(version.1); cout('.'); prbyte(version.0); crout +// +// Init symbol table. +// +while *sysmodsym + stodci(sysmodsym=>0, heap) + addsym(heap, sysmodsym=>2) + sysmodsym = sysmodsym + 4 +loop +// +// Set system path +// +strcat(strcpy(@sysmods, $280), "SYS/")) // This is the path to CMD +syspath = @sysmods // Update external interface table +syscmdln = @cmdln +loadmod(@jitmod) +// +// Try to load autorun. +// +autorun = open(@autorun) +if autorun > 0 + cmdln = read(autorun, @autorun, 128) + close(0) +else + // + // Print some startup info. + // + prstr("MEM FREE:$"); prword(availheap); crout +fin +perr = 0 +while 1 + if ^getlnbuf + when toupper(parsecmd(getlnbuf)) + is 'Q' + reboot() + break + is 'C' + catalog(getlnbuf) + break + is 'P' + pfxop(getlnbuf, SET_PFX) + break + is '/' + repeat + prefix-- + until prefix[prefix] == '/' + if prefix > 1 + pfxop(@prefix, SET_PFX) + fin + break + is 'V' + volumes() + break + is '-' + execsys(getlnbuf) + break + is '+' + saveX + execmod(striptrail(getlnbuf)) + // + // Clean up + // + restoreX + resetmemfiles + break + otherwise + cout('?') + wend + if perr + prstr("ERR:$") + prbyte(perr) + perr = 0 + else + prstr("OK") + fin + crout() + fin + prstr(pfxop(@prefix, GET_PFX)) + strcpy(@cmdln, rdstr($BA)) +loop +done diff --git a/src/vmsrc/apple/cmdjitstub.s b/src/vmsrc/apple/cmdjitstub.s new file mode 100644 index 0000000..69f3a4e --- /dev/null +++ b/src/vmsrc/apple/cmdjitstub.s @@ -0,0 +1,48 @@ +INTERP = $03D0 +LCRDEN = $C080 +LCWTEN = $C081 +ROMEN = $C082 +LCRWEN = $C083 +LCBNK2 = $00 +LCBNK1 = $08 + !SOURCE "vmsrc/plvmzp.inc" +;* +;* MOVE CMD DOWN TO $1000-$2000 +;* + LDA #<_CMDBEGIN + STA SRCL + LDA #>_CMDBEGIN + STA SRCH + LDY #$00 + STY DSTL + LDX #$10 + STX DSTH +- LDA (SRC),Y + STA (DST),Y + INY + BNE - + INC SRCH + INC DSTH + DEX ; STOP WHEN DST=$2000 REACHED + BNE - + LDA #<_CMDEND + STA SRCL + LDA #>_CMDEND + STA SRCH +; +; INIT VM ENVIRONMENT STACK POINTERS +; + STY PPL + STY IFPL ; INIT FRAME POINTER + LDA #$B0 + STA PPH + STA IFPH + LDX #$FE ; INIT STACK POINTER (YES, $FE. SEE GETS) + TXS + LDX #ESTKSZ/2 ; INIT EVAL STACK INDEX + JMP $1000 +_CMDBEGIN = * + !PSEUDOPC $1000 { + !SOURCE "vmsrc/apple/cmdjit.a" +_CMDEND = * +} diff --git a/src/vmsrc/apple/plvm02.s b/src/vmsrc/apple/plvm02.s index a33d4c8..fddb3dd 100755 --- a/src/vmsrc/apple/plvm02.s +++ b/src/vmsrc/apple/plvm02.s @@ -338,7 +338,7 @@ CMDENTRY = * ; PRINT FAIL MESSAGE, WAIT FOR KEYPRESS, AND REBOOT ; FAIL INC $3F4 ; INVALIDATE POWER-UP BYTE - LDY #31 + LDY #11 - LDA FAILMSG,Y ORA #$80 JSR $FDED @@ -358,7 +358,7 @@ READPARMS !BYTE 4 CLOSEPARMS !BYTE 1 !BYTE 0 DISABLE80 !BYTE 21, 13, '1', 26, 13 -FAILMSG !TEXT "...TESER OT YEK YNA .DMC GNISSIM" +FAILMSG !TEXT ".DMC GNISSIM" PAGE0 = * ;****************************** ;* * @@ -384,10 +384,10 @@ PAGE3 = * BIT LCRDEN+LCBNK2 ; $03DC - INDIRECT INTERPX ENTRY JMP IINTRPX } -DEFCMD !FILL 28 +DEFCMD = * ;!FILL 28 ENDBYE = * } -LCDEFCMD = *-28 ; DEFCMD IN LC MEMORY +LCDEFCMD = * ;*-28 ; DEFCMD IN LC MEMORY ;***************** ;* * ;* OPXCODE TABLE * diff --git a/src/vmsrc/apple/plvmjit02.s b/src/vmsrc/apple/plvmjit02.s new file mode 100755 index 0000000..0c4b626 --- /dev/null +++ b/src/vmsrc/apple/plvmjit02.s @@ -0,0 +1,2353 @@ +;********************************************************** +;* +;* APPLE ][ 64K/128K PLASMA INTERPRETER +;* +;* SYSTEM ROUTINES AND LOCATIONS +;* +;********************************************************** + !CPU 65C02 +;* +;* MONITOR SPECIAL LOCATIONS +;* +CSWL = $36 +CSWH = $37 +PROMPT = $33 +;* +;* PRODOS +;* +PRODOS = $BF00 +DEVCNT = $BF31 ; GLOBAL PAGE DEVICE COUNT +DEVLST = $BF32 ; GLOBAL PAGE DEVICE LIST +MACHID = $BF98 ; GLOBAL PAGE MACHINE ID BYTE +RAMSLOT = $BF26 ; SLOT 3, DRIVE 2 IS /RAM'S DRIVER VECTOR +NODEV = $BF10 +;* +;* HARDWARE ADDRESSES +;* +KEYBD = $C000 +CLRKBD = $C010 +SPKR = $C030 +LCRDEN = $C080 +LCWTEN = $C081 +ROMEN = $C082 +LCRWEN = $C083 +LCBNK2 = $00 +LCBNK1 = $08 +ALTZPOFF= $C008 +ALTZPON = $C009 +ALTRDOFF= $C002 +ALTRDON = $C003 +ALTWROFF= $C004 +ALTWRON = $C005 + !SOURCE "vmsrc/plvmzp.inc" +PSR = TMP+2 +DVSIGN = PSR+1 +DROP = $EF +NEXTOP = $F0 +FETCHOP = NEXTOP+1 +IP = FETCHOP+1 +IPL = IP +IPH = IPL+1 +OPIDX = FETCHOP+6 +OPPAGE = OPIDX+1 +STRBUF = $0280 +INTERP = $03D0 +JITCOMP = $03E2 +;****************************** +;* * +;* INTERPRETER INITIALIZATION * +;* * +;****************************** +* = $2000 + LDX #$FE + TXS + LDX #$00 + STX $01FF +;* +;* MUST HAVE 128K FOR JIT +;* ++ LDA MACHID + AND #$30 + CMP #$30 + BEQ ++ + LDY #$00 +- LDA NEEDAUX,Y + BEQ + + ORA #$80 + JSR $FDED + INY + BNE - ++ LDA $C000 + BPL - + LDA $C010 + JSR PRODOS + !BYTE $65 + !WORD BYEPARMS +BYEPARMS !BYTE 4 + !BYTE 4 + !WORD 0 + !BYTE 0 + !WORD 0 +NEEDAUX !TEXT "128K MEMORY REQUIRED.", 13 + !TEXT "PRESS ANY KEY...", 0 +;* +;* DISCONNECT /RAM +;* +++ ;SEI ; DISABLE /RAM + LDA RAMSLOT + CMP NODEV + BNE RAMCONT + LDA RAMSLOT+1 + CMP NODEV+1 + BEQ RAMDONE +RAMCONT LDY DEVCNT +RAMLOOP LDA DEVLST,Y + AND #$F3 + CMP #$B3 + BEQ GETLOOP + DEY + BPL RAMLOOP + BMI RAMDONE +GETLOOP LDA DEVLST+1,Y + STA DEVLST,Y + BEQ RAMEXIT + INY + BNE GETLOOP +RAMEXIT LDA NODEV + STA RAMSLOT + LDA NODEV+1 + STA RAMSLOT+1 + DEC DEVCNT +RAMDONE ;CLI UNTIL I KNOW WHAT TO DO WITH THE UNENHANCED IIE +;* +;* MOVE VM INTO LANGUAGE CARD +;* + BIT LCRWEN+LCBNK2 + BIT LCRWEN+LCBNK2 + LDA #VMCORE + STA SRCH + LDY #$00 + STY DSTL + LDA #$D0 + STA DSTH +- LDA (SRC),Y ; COPY VM+CMD INTO LANGUAGE CARD + STA (DST),Y + INY + BNE - + INC SRCH + INC DSTH + LDA DSTH + CMP #$E0 + BNE - +;* +;* MOVE FIRST PAGE OF 'BYE' INTO PLACE +;* + STY SRCL + LDA #$D1 + STA SRCH +- LDA (SRC),Y + STA $1000,Y + INY + BNE - +;* +;* INSERT 65C02 OPS IF APPLICABLE +;* + LDA #$00 + INC + BEQ + + JSR C02OPS +;* +;* SAVE DEFAULT COMMAND INTERPRETER PATH IN LC +;* ++ JSR PRODOS ; GET PREFIX + !BYTE $C7 + !WORD GETPFXPARMS + LDY STRBUF ; APPEND "CMDJIT" + LDA #"/" + CMP STRBUF,Y + BEQ + + INY + STA STRBUF,Y ++ LDA #"C" + INY + STA STRBUF,Y + LDA #"M" + INY + STA STRBUF,Y + LDA #"D" + INY + STA STRBUF,Y + LDA #"J" + INY + STA STRBUF,Y + LDA #"I" + INY + STA STRBUF,Y + LDA #"T" + INY + STA STRBUF,Y + STY STRBUF + BIT LCRWEN+LCBNK2 ; COPY TO LC FOR BYE + BIT LCRWEN+LCBNK2 +- LDA STRBUF,Y + STA LCDEFCMD,Y + DEY + BPL - + JMP CMDENTRY +GETPFXPARMS !BYTE 1 + !WORD STRBUF ; PATH STRING GOES HERE +;************************************************ +;* * +;* LANGUAGE CARD RESIDENT PLASMA VM STARTS HERE * +;* * +;************************************************ +VMCORE = * + !PSEUDOPC $D000 { +;**************** +;* * +;* OPCODE TABLE * +;* * +;**************** + !ALIGN 255,0 +OPTBL !WORD CN,CN,CN,CN,CN,CN,CN,CN ; 00 02 04 06 08 0A 0C 0E + !WORD CN,CN,CN,CN,CN,CN,CN,CN ; 10 12 14 16 18 1A 1C 1E + !WORD MINUS1,BREQ,BRNE,LA,LLA,CB,CW,CS ; 20 22 24 26 28 2A 2C 2E + !WORD DROP,DROP2,DUP,DIVMOD,ADDI,SUBI,ANDI,ORI ; 30 32 34 36 38 3A 3C 3E + !WORD ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E + !WORD BRNCH,SEL,CALL,ICAL,ENTER,LEAVE,RET,CFFB ; 50 52 54 56 58 5A 5C 5E + !WORD LB,LW,LLB,LLW,LAB,LAW,DLB,DLW ; 60 62 64 66 68 6A 6C 6E + !WORD SB,SW,SLB,SLW,SAB,SAW,DAB,DAW ; 70 72 74 76 78 7A 7C 7E + !WORD LNOT,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 80 82 84 86 88 8A 8C 8E + !WORD NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 90 92 94 96 98 9A 9C 9E + !WORD BRGT,BRLT,INCBRLE,ADDBRLE,DECBRGE,SUBBRGE,BRAND,BROR ; A0 A2 A4 A6 A8 AA AC AE + !WORD ADDLB,ADDLW,ADDAB,ADDAW,IDXLB,IDXLW,IDXAB,IDXAW ; B0 B2 B4 B6 B8 BA BC BE +;* +;* DIRECTLY ENTER INTO BYTECODE INTERPRETER +;* +DINTRP PLA + CLC + ADC #$01 + STA IPL + PLA + ADC #$00 + STA IPH + LDY #$00 + LDA #>OPTBL + STA OPPAGE + JMP FETCHOP +;* +;* INDIRECTLY ENTER INTO BYTECODE INTERPRETER +;* +IINTRPX PHP + PLA + STA PSR + SEI + PLA + STA TMPL + PLA + STA TMPH + LDY #$02 + LDA (TMP),Y + STA IPH + DEY + LDA (TMP),Y + STA IPL + DEY + LDA #>OPXTBL + STA OPPAGE + STA ALTRDON + JMP FETCHOP +;************************************************************ +;* * +;* 'BYE' PROCESSING - COPIED TO $1000 ON PRODOS BYE COMMAND * +;* * +;************************************************************ + !ALIGN 255,0 + !PSEUDOPC $1000 { +BYE LDY DEFCMD +- LDA DEFCMD,Y ; SET DEFAULT COMMAND WHEN CALLED FROM 'BYE' + STA STRBUF,Y + DEY + BPL - +; INY ; CLEAR CMDLINE BUFF +; STY $01FF +CMDENTRY = * +; +; DEACTIVATE 80 COL CARDS +; + BIT ROMEN + LDY #4 +- LDA DISABLE80,Y + ORA #$80 + JSR $FDED + DEY + BPL - + BIT $C054 ; SET TEXT MODE + BIT $C051 + BIT $C05F + JSR $FC58 ; HOME +; +; INSTALL PAGE 0 FETCHOP ROUTINE +; + LDY #$0F +- LDA PAGE0,Y + STA DROP,Y + DEY + BPL - +; +; SET JMPTMP OPCODE +; + LDA #$4C + STA JMPTMP +; +; INSTALL PAGE 3 VECTORS +; + LDY #$16 +- LDA PAGE3,Y + STA INTERP,Y + DEY + BPL - +; +; READ CMD INTO MEMORY +; + JSR PRODOS ; CLOSE EVERYTHING + !BYTE $CC + !WORD CLOSEPARMS + BNE FAIL + JSR PRODOS ; OPEN CMD + !BYTE $C8 + !WORD OPENPARMS + BNE FAIL + LDA REFNUM + STA READPARMS+1 + JSR PRODOS + !BYTE $CA + !WORD READPARMS + BNE FAIL + JSR PRODOS + !BYTE $CC + !WORD CLOSEPARMS + BNE FAIL +; +; INIT VM ENVIRONMENT STACK POINTERS +; +; LDA #$00 + STA $01FF ; CLEAR CMDLINE BUFF + STA PPL ; INIT FRAME POINTER + STA IFPL + LDA #$B0 ; FRAME POINTER AT $B000, BELOW JIT BUFFER + STA PPH + STA IFPH + LDX #$FE ; INIT STACK POINTER (YES, $FE. SEE GETS) + TXS + LDX #ESTKSZ/2 ; INIT EVAL STACK INDEX +; +; CHANGE CMD STRING TO SYSPATH STRING +; + LDA STRBUF + SEC + SBC #$06 + STA STRBUF + JMP $2000 ; JUMP TO LOADED SYSTEM COMMAND +; +; PRINT FAIL MESSAGE, WAIT FOR KEYPRESS, AND REBOOT +; +FAIL INC $3F4 ; INVALIDATE POWER-UP BYTE + LDY #11 +- LDA FAILMSG,Y + ORA #$80 + JSR $FDED + DEY + BPL - + JSR $FD0C ; WAIT FOR KEYPRESS + JMP ($FFFC) ; RESET +OPENPARMS !BYTE 3 + !WORD STRBUF + !WORD $0800 +REFNUM !BYTE 0 +READPARMS !BYTE 4 + !BYTE 0 + !WORD $2000 + !WORD $9F00 + !WORD 0 +CLOSEPARMS !BYTE 1 + !BYTE 0 +DISABLE80 !BYTE 21, 13, '1', 26, 13 +FAILMSG !TEXT ".DMC GNISSIM" +PAGE0 = * +;****************************** +;* * +;* INTERP BYTECODE INNER LOOP * +;* * +;****************************** + !PSEUDOPC DROP { + INX ; DROP @ $EF + INY ; NEXTOP @ $F0 + LDA $FFFF,Y ; FETCHOP @ $F3, IP MAPS OVER $FFFF @ $F4 + STA OPIDX + JMP (OPTBL) ; OPIDX AND OPPAGE MAP OVER OPTBL +} +PAGE3 = * +;* +;* PAGE 3 VECTORS INTO INTERPRETER +;* + !PSEUDOPC $03D0 { + BIT LCRDEN+LCBNK2 ; $03D0 - BYTECODE DIRECT INTERP ENTRY + JMP DINTRP + BIT LCRDEN+LCBNK2 ; $03D6 - JIT INDIRECT INTERPX ENTRY + JMP JITINTRPX + BIT LCRDEN+LCBNK2 ; $03DC - BYTECODE INDIRECT INTERPX ENTRY + JMP IINTRPX +} +DEFCMD !FILL 28 +ENDBYE = * +} +LCDEFCMD = *-28 ; DEFCMD IN LC MEMORY +;***************** +;* * +;* OPXCODE TABLE * +;* * +;***************** + !ALIGN 255,0 +OPXTBL !WORD CN,CN,CN,CN,CN,CN,CN,CN ; 00 02 04 06 08 0A 0C 0E + !WORD CN,CN,CN,CN,CN,CN,CN,CN ; 10 12 14 16 18 1A 1C 1E + !WORD MINUS1,BREQ,BRNE,LA,LLA,CB,CW,CSX ; 20 22 24 26 28 2A 2C 2E + !WORD DROP,DROP2,DUP,DIVMOD,ADDI,SUBI,ANDI,ORI ; 30 32 34 36 38 3A 3C 3E + !WORD ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E + !WORD BRNCH,SEL,CALLX,ICALX,ENTER,LEAVEX,RETX,CFFB ; 50 52 54 56 58 5A 5C 5E + !WORD LBX,LWX,LLBX,LLWX,LABX,LAWX,DLB,DLW ; 60 62 64 66 68 6A 6C 6E + !WORD SB,SW,SLB,SLW,SAB,SAW,DAB,DAW ; 70 72 74 76 78 7A 7C 7E + !WORD LNOT,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 80 82 84 86 88 8A 8C 8E + !WORD NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 90 92 94 96 98 9A 9C 9E + !WORD BRGT,BRLT,INCBRLE,ADDBRLE,DECBRGE,SUBBRGE,BRAND,BROR ; A0 A2 A4 A6 A8 AA AC AE + !WORD ADDLBX,ADDLWX,ADDABX,ADDAWX,IDXLBX,IDXLWX,IDXABX,IDXAWX ; B0 B2 B4 B6 B8 BA BC BE +;* +;* JIT PROFILING ENTRY INTO INTERPRETER +;* +JITINTRPX PHP + PLA + STA PSR + SEI + PLA + SEC + SBC #$02 ; POINT TO DEF ENTRY + STA TMPL + PLA + SBC #$00 + STA TMPH + LDY #$05 ; DEC JIT COUNT + LDA (TMP),Y + SEC + SBC #$01 + STA (TMP),Y + BEQ RUNJIT + DEY +- LDA (TMP),Y + STA IPH + DEY + LDA (TMP),Y + STA IPL + LDY #$00 + LDA #>OPXTBL + STA OPPAGE + STA ALTRDON + JMP FETCHOP +RUNJIT LDA JITCOMP + STA SRCL + LDA JITCOMP+1 + STA SRCH + DEY ; LDY #$04 + LDA (SRC),Y + STA IPH + DEY + LDA (SRC),Y + STA IPL + DEX ; ADD PARAMETER TO DEF ENTRY + LDA TMPL + PHA + STA ESTKL,X + LDA TMPH + PHA + STA ESTKH,X + LDY #$00 + LDA #>OPXTBL + STA OPPAGE + STA ALTRDON + JSR FETCHOP ; CALL JIT COMPILER + PLA + STA TMPH + PLA + STA TMPL + JMP JMPTMP ; RE-CALL ORIGINAL ROUTINE +;* +;* ADD TOS TO TOS-1 +;* +ADD LDA ESTKL,X + CLC + ADC ESTKL+1,X + STA ESTKL+1,X + LDA ESTKH,X + ADC ESTKH+1,X + STA ESTKH+1,X + JMP DROP +;* +;* SUB TOS FROM TOS-1 +;* +SUB LDA ESTKL+1,X + SEC + SBC ESTKL,X + STA ESTKL+1,X + LDA ESTKH+1,X + SBC ESTKH,X + STA ESTKH+1,X + JMP DROP +;* +;* SHIFT TOS LEFT BY 1, ADD TO TOS-1 +;* +IDXW LDA ESTKL,X + ASL + ROL ESTKH,X + CLC + ADC ESTKL+1,X + STA ESTKL+1,X + LDA ESTKH,X + ADC ESTKH+1,X + STA ESTKH+1,X + JMP DROP +;* +;* MUL TOS-1 BY TOS +;* +MUL STY IPY + LDY #$10 + LDA ESTKL+1,X + EOR #$FF + STA TMPL + LDA ESTKH+1,X + EOR #$FF + STA TMPH + LDA #$00 + STA ESTKL+1,X ; PRODL +; STA ESTKH+1,X ; PRODH +_MULLP LSR TMPH ; MULTPLRH + ROR TMPL ; MULTPLRL + BCS + + STA ESTKH+1,X ; PRODH + LDA ESTKL,X ; MULTPLNDL + ADC ESTKL+1,X ; PRODL + STA ESTKL+1,X + LDA ESTKH,X ; MULTPLNDH + ADC ESTKH+1,X ; PRODH ++ ASL ESTKL,X ; MULTPLNDL + ROL ESTKH,X ; MULTPLNDH + DEY + BNE _MULLP + STA ESTKH+1,X ; PRODH + LDY IPY + JMP DROP +;* +;* INTERNAL DIVIDE ALGORITHM +;* +_NEG LDA #$00 + SEC + SBC ESTKL,X + STA ESTKL,X + LDA #$00 + SBC ESTKH,X + STA ESTKH,X + RTS +_DIV STY IPY + LDY #$11 ; #BITS+1 + LDA #$00 + STA TMPL ; REMNDRL + STA TMPH ; REMNDRH + STA DVSIGN + LDA ESTKH+1,X + BPL + + INX + JSR _NEG + DEX + LDA #$81 + STA DVSIGN ++ ORA ESTKL+1,X ; DVDNDL + BEQ _DIVEX + LDA ESTKH,X + BPL _DIV1 + JSR _NEG + INC DVSIGN +_DIV1 ASL ESTKL+1,X ; DVDNDL + ROL ESTKH+1,X ; DVDNDH + DEY + BCC _DIV1 +_DIVLP ROL TMPL ; REMNDRL + ROL TMPH ; REMNDRH + LDA TMPL ; REMNDRL + CMP ESTKL,X ; DVSRL + LDA TMPH ; REMNDRH + SBC ESTKH,X ; DVSRH + BCC + + STA TMPH ; REMNDRH + LDA TMPL ; REMNDRL + SBC ESTKL,X ; DVSRL + STA TMPL ; REMNDRL + SEC ++ ROL ESTKL+1,X ; DVDNDL + ROL ESTKH+1,X ; DVDNDH + DEY + BNE _DIVLP +_DIVEX INX + LDY IPY + RTS +;* +;* NEGATE TOS +;* +NEG LDA #$00 + SEC + SBC ESTKL,X + STA ESTKL,X + LDA #$00 + SBC ESTKH,X + STA ESTKH,X + JMP NEXTOP +;* +;* DIV TOS-1 BY TOS +;* +DIV JSR _DIV + LSR DVSIGN ; SIGN(RESULT) = (SIGN(DIVIDEND) + SIGN(DIVISOR)) & 1 + BCS NEG + JMP NEXTOP +;* +;* MOD TOS-1 BY TOS +;* +MOD JSR _DIV + LDA TMPL ; REMNDRL + STA ESTKL,X + LDA TMPH ; REMNDRH + STA ESTKH,X + LDA DVSIGN ; REMAINDER IS SIGN OF DIVIDEND + BMI NEG + JMP NEXTOP +;* +;* DIVMOD TOS-1 BY TOS +;* +DIVMOD JSR _DIV + LSR DVSIGN ; SIGN(RESULT) = (SIGN(DIVIDEND) + SIGN(DIVISOR)) & 1 + BCC + + JSR _NEG ++ DEX + LDA TMPL ; REMNDRL + STA ESTKL,X + LDA TMPH ; REMNDRH + STA ESTKH,X + ASL DVSIGN ; REMAINDER IS SIGN OF DIVIDEND + BMI NEG + JMP NEXTOP +;* +;* INCREMENT TOS +;* +INCR INC ESTKL,X + BEQ + + JMP NEXTOP ++ INC ESTKH,X + JMP NEXTOP +;* +;* DECREMENT TOS +;* +DECR LDA ESTKL,X + BEQ + + DEC ESTKL,X + JMP NEXTOP ++ DEC ESTKL,X + DEC ESTKH,X + JMP NEXTOP +;* +;* BITWISE COMPLIMENT TOS +;* +COMP LDA #$FF + EOR ESTKL,X + STA ESTKL,X + LDA #$FF + EOR ESTKH,X + STA ESTKH,X + JMP NEXTOP +;* +;* BITWISE AND TOS TO TOS-1 +;* +BAND LDA ESTKL+1,X + AND ESTKL,X + STA ESTKL+1,X + LDA ESTKH+1,X + AND ESTKH,X + STA ESTKH+1,X + JMP DROP +;* +;* INCLUSIVE OR TOS TO TOS-1 +;* +IOR LDA ESTKL+1,X + ORA ESTKL,X + STA ESTKL+1,X + LDA ESTKH+1,X + ORA ESTKH,X + STA ESTKH+1,X + JMP DROP +;* +;* EXLUSIVE OR TOS TO TOS-1 +;* +XOR LDA ESTKL+1,X + EOR ESTKL,X + STA ESTKL+1,X + LDA ESTKH+1,X + EOR ESTKH,X + STA ESTKH+1,X + JMP DROP +;* +;* SHIFT TOS-1 LEFT BY TOS +;* +SHL STY IPY + LDA ESTKL,X + CMP #$08 + BCC + + LDY ESTKL+1,X + STY ESTKH+1,X + LDY #$00 + STY ESTKL+1,X + SBC #$08 ++ TAY + BEQ + + LDA ESTKL+1,X +- ASL + ROL ESTKH+1,X + DEY + BNE - + STA ESTKL+1,X ++ LDY IPY + JMP DROP +;* +;* SHIFT TOS-1 RIGHT BY TOS +;* +SHR STY IPY + LDA ESTKL,X + CMP #$08 + BCC ++ + LDY ESTKH+1,X + STY ESTKL+1,X + CPY #$80 + LDY #$00 + BCC + + DEY ++ STY ESTKH+1,X + SEC + SBC #$08 +++ TAY + BEQ + + LDA ESTKH+1,X +- CMP #$80 + ROR + ROR ESTKL+1,X + DEY + BNE - + STA ESTKH+1,X ++ LDY IPY + JMP DROP +;* +;* DUPLICATE TOS +;* +DUP DEX + LDA ESTKL+1,X + STA ESTKL,X + LDA ESTKH+1,X + STA ESTKH,X + JMP NEXTOP +;* +;* ADD IMMEDIATE TO TOS +;* +ADDI INY ;+INC_IP + LDA (IP),Y + CLC + ADC ESTKL,X + STA ESTKL,X + BCC + + INC ESTKH,X ++ JMP NEXTOP +;* +;* SUB IMMEDIATE FROM TOS +;* +SUBI INY ;+INC_IP + LDA ESTKL,X + SEC + SBC (IP),Y + STA ESTKL,X + BCS + + DEC ESTKH,X ++ JMP NEXTOP +;* +;* AND IMMEDIATE TO TOS +;* +ANDI INY ;+INC_IP + LDA (IP),Y + AND ESTKL,X + STA ESTKL,X + LDA #$00 + STA ESTKH,X + JMP NEXTOP +;* +;* IOR IMMEDIATE TO TOS +;* +ORI INY ;+INC_IP + LDA (IP),Y + ORA ESTKL,X + STA ESTKL,X + JMP NEXTOP +;* +;* LOGICAL NOT +;* +LNOT LDA ESTKL,X + ORA ESTKH,X + BEQ + + LDA #$00 + STA ESTKL,X + STA ESTKH,X + JMP NEXTOP +;* +;* CONSTANT -1, NYBBLE, BYTE, $FF BYTE, WORD (BELOW) +;* +MINUS1 DEX ++ LDA #$FF + STA ESTKL,X + STA ESTKH,X + JMP NEXTOP +CN DEX + LSR ; A = CONST * 2 + STA ESTKL,X + LDA #$00 + STA ESTKH,X + JMP NEXTOP +CB DEX + LDA #$00 + STA ESTKH,X + INY ;+INC_IP + LDA (IP),Y + STA ESTKL,X + JMP NEXTOP +CFFB DEX + LDA #$FF + STA ESTKH,X + INY ;+INC_IP + LDA (IP),Y + STA ESTKL,X + JMP NEXTOP +;* +;* LOAD ADDRESS & LOAD CONSTANT WORD (SAME THING, WITH OR WITHOUT FIXUP) +;* +- TYA ; RENORMALIZE IP + CLC + ADC IPL + STA IPL + BCC + + INC IPH ++ LDY #$FF +LA INY ;+INC_IP + BMI - + DEX + LDA (IP),Y + STA ESTKL,X + INY + LDA (IP),Y + STA ESTKH,X + JMP NEXTOP +CW DEX + INY ;+INC_IP + LDA (IP),Y + STA ESTKL,X + INY + LDA (IP),Y + STA ESTKH,X + JMP NEXTOP +;* +;* CONSTANT STRING +;* +CS DEX + ;INY ;+INC_IP + TYA ; NORMALIZE IP AND SAVE STRING ADDR ON ESTK + SEC + ADC IPL + STA IPL + STA ESTKL,X + LDA #$00 + TAY + ADC IPH + STA IPH + STA ESTKH,X + LDA (IP),Y + TAY + JMP NEXTOP +CSX DEX + ;INY ;+INC_IP + TYA ; NORMALIZE IP + SEC + ADC IPL + STA IPL + LDA #$00 + TAY + ADC IPH + STA IPH + LDA PPL ; SCAN POOL FOR STRING ALREADY THERE + STA TMPL + LDA PPH + STA TMPH +_CMPPSX ;LDA TMPH ; CHECK FOR END OF POOL + CMP IFPH + BCC _CMPSX ; CHECK FOR MATCHING STRING + BNE _CPYSX ; BEYOND END OF POOL, COPY STRING OVER + LDA TMPL + CMP IFPL + BCS _CPYSX ; AT OR BEYOND END OF POOL, COPY STRING OVER +_CMPSX STA ALTRDOFF + LDA (TMP),Y ; COMPARE STRINGS FROM AUX MEM TO STRINGS IN MAIN MEM + STA ALTRDON + CMP (IP),Y ; COMPARE STRING LENGTHS + BNE _CNXTSX1 + TAY +_CMPCSX STA ALTRDOFF + LDA (TMP),Y ; COMPARE STRING CHARS FROM END + STA ALTRDON + CMP (IP),Y + BNE _CNXTSX + DEY + BNE _CMPCSX + LDA TMPL ; MATCH - SAVE EXISTING ADDR ON ESTK AND MOVE ON + STA ESTKL,X + LDA TMPH + STA ESTKH,X + BNE _CEXSX +_CNXTSX LDY #$00 + STA ALTRDOFF + LDA (TMP),Y + STA ALTRDON +_CNXTSX1 SEC + ADC TMPL + STA TMPL + LDA #$00 + ADC TMPH + STA TMPH + BNE _CMPPSX +_CPYSX LDA (IP),Y ; COPY STRING FROM AUX TO MAIN MEM POOL + TAY ; MAKE ROOM IN POOL AND SAVE ADDR ON ESTK + EOR #$FF + CLC + ADC PPL + STA PPL + STA ESTKL,X + LDA #$FF + ADC PPH + STA PPH + STA ESTKH,X ; COPY STRING FROM AUX MEM BYTECODE TO MAIN MEM POOL +_CPYSX1 LDA (IP),Y ; ALTRD IS ON, NO NEED TO CHANGE IT HERE + STA (PP),Y ; ALTWR IS OFF, NO NEED TO CHANGE IT HERE + DEY + CPY #$FF + BNE _CPYSX1 + INY +_CEXSX LDA (IP),Y ; SKIP TO NEXT OP ADDR AFTER STRING + TAY + JMP NEXTOP +;* +;* LOAD VALUE FROM ADDRESS TAG +;* +LB LDA ESTKL,X + STA ESTKH-1,X + LDA (ESTKH-1,X) + STA ESTKL,X + LDA #$00 + STA ESTKH,X + JMP NEXTOP +LW LDA ESTKL,X + STA ESTKH-1,X + LDA (ESTKH-1,X) + STA ESTKL,X + INC ESTKH-1,X + BEQ + + LDA (ESTKH-1,X) + STA ESTKH,X + JMP NEXTOP ++ INC ESTKH,X + LDA (ESTKH-1,X) + STA ESTKH,X + JMP NEXTOP +LBX LDA ESTKL,X + STA ESTKH-1,X + STA ALTRDOFF + LDA (ESTKH-1,X) + STA ESTKL,X + LDA #$00 + STA ESTKH,X + STA ALTRDON + JMP NEXTOP +LWX LDA ESTKL,X + STA ESTKH-1,X + STA ALTRDOFF + LDA (ESTKH-1,X) + STA ESTKL,X + INC ESTKH-1,X + BEQ + + LDA (ESTKH-1,X) + STA ESTKH,X + STA ALTRDON + JMP NEXTOP ++ INC ESTKH,X + LDA (ESTKH-1,X) + STA ESTKH,X + STA ALTRDON + JMP NEXTOP +;* +;* LOAD ADDRESS OF LOCAL FRAME OFFSET +;* +- TYA ; RENORMALIZE IP + CLC + ADC IPL + STA IPL + BCC + + INC IPH ++ LDY #$FF +LLA INY ;+INC_IP + BMI - + LDA (IP),Y + DEX + CLC + ADC IFPL + STA ESTKL,X + LDA #$00 + ADC IFPH + STA ESTKH,X + JMP NEXTOP +;* +;* LOAD VALUE FROM LOCAL FRAME OFFSET +;* +LLB INY ;+INC_IP + LDA (IP),Y + STY IPY + TAY + DEX + LDA (IFP),Y + STA ESTKL,X + LDA #$00 + STA ESTKH,X + LDY IPY + JMP NEXTOP +LLW INY ;+INC_IP + LDA (IP),Y + STY IPY + TAY + DEX + LDA (IFP),Y + STA ESTKL,X + INY + LDA (IFP),Y + STA ESTKH,X + LDY IPY + JMP NEXTOP +LLBX INY ;+INC_IP + LDA (IP),Y + STY IPY + TAY + DEX + STA ALTRDOFF + LDA (IFP),Y + STA ESTKL,X + LDA #$00 + STA ESTKH,X + STA ALTRDON + LDY IPY + JMP NEXTOP +LLWX INY ;+INC_IP + LDA (IP),Y + STY IPY + TAY + DEX + STA ALTRDOFF + LDA (IFP),Y + STA ESTKL,X + INY + LDA (IFP),Y + STA ESTKH,X + STA ALTRDON + LDY IPY + JMP NEXTOP +;* +;* ADD VALUE FROM LOCAL FRAME OFFSET +;* +ADDLB INY ;+INC_IP + LDA (IP),Y + STY IPY + TAY + LDA (IFP),Y + CLC + ADC ESTKL,X + STA ESTKL,X + BCC + + INC ESTKH,X ++ LDY IPY + JMP NEXTOP +ADDLBX INY ;+INC_IP + LDA (IP),Y + STY IPY + TAY + STA ALTRDOFF + LDA (IFP),Y + CLC + ADC ESTKL,X + STA ESTKL,X + BCC + + INC ESTKH,X ++ STA ALTRDON + LDY IPY + JMP NEXTOP +ADDLW INY ;+INC_IP + LDA (IP),Y + STY IPY + TAY + LDA (IFP),Y + CLC + ADC ESTKL,X + STA ESTKL,X + INY + LDA (IFP),Y + ADC ESTKH,X + STA ESTKH,X + LDY IPY + JMP NEXTOP +ADDLWX INY ;+INC_IP + LDA (IP),Y + STY IPY + TAY + STA ALTRDOFF + LDA (IFP),Y + CLC + ADC ESTKL,X + STA ESTKL,X + INY + LDA (IFP),Y + ADC ESTKH,X + STA ESTKH,X + STA ALTRDON + LDY IPY + JMP NEXTOP +;* +;* INDEX VALUE FROM LOCAL FRAME OFFSET +;* +IDXLB INY ;+INC_IP + LDA (IP),Y + STY IPY + TAY + LDA (IFP),Y + LDY #$00 + ASL + BCC + + INY + CLC ++ ADC ESTKL,X + STA ESTKL,X + TYA + ADC ESTKH,X + STA ESTKH,X + LDY IPY + JMP NEXTOP +IDXLBX INY ;+INC_IP + LDA (IP),Y + STY IPY + TAY + STA ALTRDOFF + LDA (IFP),Y + LDY #$00 + ASL + BCC + + INY + CLC ++ ADC ESTKL,X + STA ESTKL,X + TYA + ADC ESTKH,X + STA ESTKH,X + STA ALTRDON + LDY IPY + JMP NEXTOP +IDXLW INY ;+INC_IP + LDA (IP),Y + STY IPY + TAY + STA TMPL + LDA (IFP),Y + ASL + STA TMPL + INY + LDA (IFP),Y + ROL + STA TMPH + LDA TMPL + CLC + ADC ESTKL,X + STA ESTKL,X + LDA TMPH + ADC ESTKH,X + STA ESTKH,X + LDY IPY + JMP NEXTOP +IDXLWX INY ;+INC_IP + LDA (IP),Y + STY IPY + TAY + STA ALTRDOFF + LDA (IFP),Y + ASL + STA TMPL + INY + LDA (IFP),Y + ROL + STA TMPH + LDA TMPL + CLC + ADC ESTKL,X + STA ESTKL,X + LDA TMPH + ADC ESTKH,X + STA ESTKH,X + STA ALTRDON + LDY IPY + JMP NEXTOP +;* +;* LOAD VALUE FROM ABSOLUTE ADDRESS +;* +LAB INY ;+INC_IP + LDA (IP),Y + STA ESTKH-2,X + INY ;+INC_IP + LDA (IP),Y + STA ESTKH-1,X + LDA (ESTKH-2,X) + DEX + STA ESTKL,X + LDA #$00 + STA ESTKH,X + JMP NEXTOP +LAW INY ;+INC_IP + LDA (IP),Y + STA TMPL + INY ;+INC_IP + LDA (IP),Y + STA TMPH + STY IPY + LDY #$00 + LDA (TMP),Y + DEX + STA ESTKL,X + INY + LDA (TMP),Y + STA ESTKH,X + LDY IPY + JMP NEXTOP +LABX INY ;+INC_IP + LDA (IP),Y + STA ESTKH-2,X + INY ;+INC_IP + LDA (IP),Y + STA ESTKH-1,X + STA ALTRDOFF + LDA (ESTKH-2,X) + DEX + STA ESTKL,X + LDA #$00 + STA ESTKH,X + STA ALTRDON + JMP NEXTOP +LAWX INY ;+INC_IP + LDA (IP),Y + STA TMPL + INY ;+INC_IP + LDA (IP),Y + STA TMPH + STY IPY + STA ALTRDOFF + LDY #$00 + LDA (TMP),Y + DEX + STA ESTKL,X + INY + LDA (TMP),Y + STA ESTKH,X + STA ALTRDON + LDY IPY + JMP NEXTOP +;* +;* ADD VALUE FROM ABSOLUTE ADDRESS +;* +ADDAB INY ;+INC_IP + LDA (IP),Y + STA ESTKH-2,X + INY ;+INC_IP + LDA (IP),Y + STA ESTKH-1,X + LDA (ESTKH-2,X) + CLC + ADC ESTKL,X + STA ESTKL,X + BCC + + INC ESTKH,X ++ JMP NEXTOP +ADDABX INY ;+INC_IP + LDA (IP),Y + STA ESTKH-2,X + INY ;+INC_IP + LDA (IP),Y + STA ESTKH-1,X + STA ALTRDOFF + LDA (ESTKH-2,X) + CLC + ADC ESTKL,X + STA ESTKL,X + BCC + + INC ESTKH,X ++ STA ALTRDON + JMP NEXTOP +ADDAW INY ;+INC_IP + LDA (IP),Y + STA SRCL + INY ;+INC_IP + LDA (IP),Y + STA SRCH + STY IPY + LDY #$00 + LDA (SRC),Y + CLC + ADC ESTKL,X + STA ESTKL,X + INY + LDA (SRC),Y + ADC ESTKH,X + STA ESTKH,X + LDY IPY + JMP NEXTOP +ADDAWX INY ;+INC_IP + LDA (IP),Y + STA SRCL + INY ;+INC_IP + LDA (IP),Y + STA SRCH + STY IPY + STA ALTRDOFF + LDY #$00 + LDA (SRC),Y + CLC + ADC ESTKL,X + STA ESTKL,X + INY + LDA (SRC),Y + ADC ESTKH,X + STA ESTKH,X + STA ALTRDON + LDY IPY + JMP NEXTOP +;* +;* INDEX VALUE FROM ABSOLUTE ADDRESS +;* +IDXAB INY ;+INC_IP + LDA (IP),Y + STA ESTKH-2,X + INY ;+INC_IP + LDA (IP),Y + STA ESTKH-1,X + LDA (ESTKH-2,X) + STY IPY + LDY #$00 + ASL + BCC + + INY + CLC ++ ADC ESTKL,X + STA ESTKL,X + TYA + ADC ESTKH,X + STA ESTKH,X + LDY IPY + JMP NEXTOP +IDXABX INY ;+INC_IP + LDA (IP),Y + STA ESTKH-2,X + INY ;+INC_IP + LDA (IP),Y + STA ESTKH-1,X + STA ALTRDOFF + LDA (ESTKH-2,X) + STY IPY + LDY #$00 + ASL + BCC + + INY + CLC ++ ADC ESTKL,X + STA ESTKL,X + TYA + ADC ESTKH,X + STA ESTKH,X + LDY IPY + STA ALTRDON + JMP NEXTOP +IDXAW INY ;+INC_IP + LDA (IP),Y + STA SRCL + INY ;+INC_IP + LDA (IP),Y + STA SRCH + STY IPY + LDY #$00 + LDA (SRC),Y + ASL + STA TMPL + INY + LDA (SRC),Y + ROL + STA TMPH + LDA TMPL + CLC + ADC ESTKL,X + STA ESTKL,X + LDA TMPH + ADC ESTKH,X + STA ESTKH,X + LDY IPY + JMP NEXTOP +IDXAWX INY ;+INC_IP + LDA (IP),Y + STA SRCL + INY ;+INC_IP + LDA (IP),Y + STA SRCH + STY IPY + STA ALTRDOFF + LDY #$00 + LDA (SRC),Y + ASL + STA TMPL + INY + LDA (SRC),Y + ROL + STA TMPH + LDA TMPL + CLC + ADC ESTKL,X + STA ESTKL,X + LDA TMPH + ADC ESTKH,X + STA ESTKH,X + STA ALTRDON + LDY IPY + JMP NEXTOP +;* +;* STORE VALUE TO ADDRESS +;* +SB LDA ESTKL,X + STA ESTKH-1,X + LDA ESTKL+1,X + STA (ESTKH-1,X) + INX + JMP DROP +SW LDA ESTKL,X + STA ESTKH-1,X + LDA ESTKL+1,X + STA (ESTKH-1,X) + LDA ESTKH+1,X + INC ESTKH-1,X + BEQ + + STA (ESTKH-1,X) + INX + JMP DROP ++ INC ESTKH,X + STA (ESTKH-1,X) +;* +;* DROP TOS, TOS-1 +;* +DROP2 INX + JMP DROP +;* +;* STORE VALUE TO LOCAL FRAME OFFSET +;* +SLB INY ;+INC_IP + LDA (IP),Y + STY IPY + TAY + LDA ESTKL,X + STA (IFP),Y + LDY IPY + BMI FIXDROP + JMP DROP +SLW INY ;+INC_IP + LDA (IP),Y + STY IPY + TAY + LDA ESTKL,X + STA (IFP),Y + INY + LDA ESTKH,X + STA (IFP),Y + LDY IPY + BMI FIXDROP + JMP DROP +FIXDROP TYA + LDY #$00 + CLC + ADC IPL + STA IPL + BCC + + INC IPH ++ JMP DROP +;* +;* STORE VALUE TO LOCAL FRAME OFFSET WITHOUT POPPING STACK +;* +DLB INY ;+INC_IP + LDA (IP),Y + STY IPY + TAY + LDA ESTKL,X + STA (IFP),Y + LDY IPY + JMP NEXTOP +DLW INY ;+INC_IP + LDA (IP),Y + STY IPY + TAY + LDA ESTKL,X + STA (IFP),Y + INY + LDA ESTKH,X + STA (IFP),Y + LDY IPY + JMP NEXTOP +;* +;* STORE VALUE TO ABSOLUTE ADDRESS +;* +- TYA ; RENORMALIZE IP + CLC + ADC IPL + STA IPL + BCC + + INC IPH ++ LDY #$FF +SAB INY ;+INC_IP + BMI - + LDA (IP),Y + STA ESTKH-2,X + INY ;+INC_IP + LDA (IP),Y + STA ESTKH-1,X + LDA ESTKL,X + STA (ESTKH-2,X) + JMP DROP +SAW INY ;+INC_IP + LDA (IP),Y + STA TMPL + INY ;+INC_IP + LDA (IP),Y + STA TMPH + STY IPY + LDY #$00 + LDA ESTKL,X + STA (TMP),Y + INY + LDA ESTKH,X + STA (TMP),Y + LDY IPY + BMI + + JMP DROP ++ JMP FIXDROP +;* +;* STORE VALUE TO ABSOLUTE ADDRESS WITHOUT POPPING STACK +;* +DAB INY ;+INC_IP + LDA (IP),Y + STA ESTKH-2,X + INY ;+INC_IP + LDA (IP),Y + STA ESTKH-1,X + LDA ESTKL,X + STA (ESTKH-2,X) + JMP NEXTOP +DAW INY ;+INC_IP + LDA (IP),Y + STA TMPL + INY ;+INC_IP + LDA (IP),Y + STA TMPH + STY IPY + LDY #$00 + LDA ESTKL,X + STA (TMP),Y + INY + LDA ESTKH,X + STA (TMP),Y + LDY IPY + JMP NEXTOP +;* +;* COMPARES +;* +ISEQ LDA ESTKL,X + CMP ESTKL+1,X + BNE ISFLS + LDA ESTKH,X + CMP ESTKH+1,X + BNE ISFLS +ISTRU LDA #$FF + STA ESTKL+1,X + STA ESTKH+1,X + JMP DROP +ISNE LDA ESTKL,X + CMP ESTKL+1,X + BNE ISTRU + LDA ESTKH,X + CMP ESTKH+1,X + BNE ISTRU +ISFLS LDA #$00 + STA ESTKL+1,X + STA ESTKH+1,X + JMP DROP +ISGE LDA ESTKL+1,X + CMP ESTKL,X + LDA ESTKH+1,X + SBC ESTKH,X + BVS + + BPL ISTRU + BMI ISFLS ++ +- BPL ISFLS + BMI ISTRU +ISLE LDA ESTKL,X + CMP ESTKL+1,X + LDA ESTKH,X + SBC ESTKH+1,X + BVS - + BPL ISTRU + BMI ISFLS +ISGT LDA ESTKL,X + CMP ESTKL+1,X + LDA ESTKH,X + SBC ESTKH+1,X + BVS + + BMI ISTRU + BPL ISFLS ++ +- BMI ISFLS + BPL ISTRU +ISLT LDA ESTKL+1,X + CMP ESTKL,X + LDA ESTKH+1,X + SBC ESTKH,X + BVS - + BMI ISTRU + BPL ISFLS +;* +;* BRANCHES +;* +SEL INX + TYA ; FLATTEN IP + SEC + ADC IPL + STA TMPL + LDA #$00 + TAY + ADC IPH + STA TMPH ; ADD BRANCH OFFSET + LDA (TMP),Y + ;CLC ; BETTER NOT CARRY OUT OF IP+Y + ADC TMPL + STA IPL + INY + LDA (TMP),Y + ADC TMPH + STA IPH + DEY + LDA (IP),Y + STA TMPL ; CASE COUNT + INC IPL + BNE CASELP + INC IPH +CASELP LDA ESTKL-1,X + CMP (IP),Y + BEQ + + LDA ESTKH-1,X + INY + SBC (IP),Y + BMI CASEEND +- INY + INY + DEC TMPL + BEQ FIXNEXT + INY + BNE CASELP + INC IPH + BNE CASELP ++ LDA ESTKH-1,X + INY + SBC (IP),Y + BEQ BRNCH + BPL - +CASEEND LDA #$00 + STA TMPH + DEC TMPL + LDA TMPL + ASL ; SKIP REMAINING CASES + ROL TMPH + ASL + ROL TMPH +; CLC + ADC IPL + STA IPL + LDA TMPH + ADC IPH + STA IPH + INY + INY +FIXNEXT TYA + LDY #$00 + SEC + ADC IPL + STA IPL + BCC + + INC IPH ++ JMP FETCHOP +BRAND LDA ESTKL,X + ORA ESTKH,X + BEQ BRNCH + INX ; DROP LEFT HALF OF AND + BNE NOBRNCH +BROR LDA ESTKL,X + ORA ESTKH,X + BNE BRNCH + INX ; DROP LEFT HALF OF OR + BNE NOBRNCH +BREQ INX + INX + LDA ESTKL-2,X + CMP ESTKL-1,X + BNE NOBRNCH + LDA ESTKH-2,X + CMP ESTKH-1,X + BEQ BRNCH + BNE NOBRNCH +BRNE INX + INX + LDA ESTKL-2,X + CMP ESTKL-1,X + BNE BRNCH + LDA ESTKH-2,X + CMP ESTKH-1,X + BNE BRNCH + BEQ NOBRNCH +BRTRU INX + LDA ESTKH-1,X + ORA ESTKL-1,X + BNE BRNCH +NOBRNCH INY ;+INC_IP + INY + BMI FIXNEXT + JMP NEXTOP +BRFLS INX + LDA ESTKH-1,X + ORA ESTKL-1,X + BNE NOBRNCH +BRNCH TYA ; FLATTEN IP + SEC + ADC IPL + STA TMPL + LDA #$00 + TAY + ADC IPH + STA TMPH ; ADD BRANCH OFFSET + LDA (TMP),Y + ;CLC ; BETTER NOT CARRY OUT OF IP+Y + ADC TMPL + STA IPL + INY + LDA (TMP),Y + ADC TMPH + STA IPH + DEY + JMP FETCHOP +;* +;* FOR LOOPS PUT TERMINAL VALUE AT ESTK+1 AND CURRENT COUNT ON ESTK +;* +BRGT LDA ESTKL+1,X + CMP ESTKL,X + LDA ESTKH+1,X + SBC ESTKH,X + BVS + + BPL NOBRNCH +- INX ; DROP FOR VALUES + INX + BNE BRNCH ; BMI BRNCH +BRLT LDA ESTKL,X + CMP ESTKL+1,X + LDA ESTKH,X + SBC ESTKH+1,X + BVS + + BPL NOBRNCH + INX ; DROP FOR VALUES + INX + BNE BRNCH ; BMI BRNCH ++ BMI NOBRNCH + BPL - +DECBRGE DEC ESTKL,X + LDA ESTKL,X + CMP #$FF + BNE + + DEC ESTKH,X +_BRGE LDA ESTKL,X ++ CMP ESTKL+1,X + LDA ESTKH,X + SBC ESTKH+1,X + BVS + + BPL BRNCH +- INX ; DROP FOR VALUES + INX + BNE NOBRNCH ; BMI NOBRNCH +INCBRLE INC ESTKL,X + BNE _BRLE + INC ESTKH,X +_BRLE LDA ESTKL+1,X + CMP ESTKL,X + LDA ESTKH+1,X + SBC ESTKH,X + BVS + + BPL BRNCH + INX ; DROP FOR VALUES + INX + BNE NOBRNCH ; BMI NOBRNCH ++ BMI BRNCH + BPL - +SUBBRGE LDA ESTKL+1,X + SEC + SBC ESTKL,X + STA ESTKL+1,X + LDA ESTKH+1,X + SBC ESTKH,X + STA ESTKH+1,X + INX + BNE _BRGE +ADDBRLE LDA ESTKL,X + CLC + ADC ESTKL+1,X + STA ESTKL+1,X + LDA ESTKH,X + ADC ESTKH+1,X + STA ESTKH+1,X + INX + BNE _BRLE +;* +;* CALL INTO ABSOLUTE ADDRESS (NATIVE CODE) +;* +CALL INY ;+INC_IP + LDA (IP),Y + STA TMPL + INY ;+INC_IP + LDA (IP),Y + STA TMPH + TYA + CLC + ADC IPL + PHA + LDA IPH + ADC #$00 + PHA + JSR JMPTMP + PLA + STA IPH + PLA + STA IPL + LDA #>OPTBL ; MAKE SURE WE'RE INDEXING THE RIGHT TABLE + STA OPPAGE + LDY #$01 + JMP FETCHOP +CALLX INY ;+INC_IP + LDA (IP),Y + STA TMPL + INY ;+INC_IP + LDA (IP),Y + STA TMPH + TYA + CLC + ADC IPL + PHA + LDA IPH + ADC #$00 + PHA + STA ALTRDOFF + LDA PSR + PHA + PLP + JSR JMPTMP + PHP + PLA + STA PSR + SEI + STA ALTRDON + PLA + STA IPH + PLA + STA IPL + LDA #>OPXTBL ; MAKE SURE WE'RE INDEXING THE RIGHT TABLE + STA OPPAGE + LDY #$01 + JMP FETCHOP +;* +;* INDIRECT CALL TO ADDRESS (NATIVE CODE) +;* +ICAL LDA ESTKL,X + STA TMPL + LDA ESTKH,X + STA TMPH + INX + TYA + CLC + ADC IPL + PHA + LDA IPH + ADC #$00 + PHA + JSR JMPTMP + PLA + STA IPH + PLA + STA IPL + LDA #>OPTBL ; MAKE SURE WE'RE INDEXING THE RIGHT TABLE + STA OPPAGE + LDY #$01 + JMP FETCHOP +ICALX LDA ESTKL,X + STA TMPL + LDA ESTKH,X + STA TMPH + INX + TYA + CLC + ADC IPL + PHA + LDA IPH + ADC #$00 + PHA + STA ALTRDOFF + LDA PSR + PHA + PLP + JSR JMPTMP + PHP + PLA + STA PSR + STA ALTRDON + PLA + STA IPH + PLA + STA IPL + LDA #>OPXTBL ; MAKE SURE WE'RE INDEXING THE RIGHT TABLE + STA OPPAGE + LDY #$01 + JMP FETCHOP +;* +;* JUMP INDIRECT TRHOUGH TMP +;* +;JMPTMP JMP (TMP) +;* +;* ENTER FUNCTION WITH FRAME SIZE AND PARAM COUNT +;* +ENTER LDA IFPH + PHA ; SAVE ON STACK FOR LEAVE + LDA IFPL + PHA + INY + LDA (IP),Y + EOR #$FF ; ALLOCATE FRAME + SEC + ADC PPL + STA PPL + STA IFPL + LDA #$FF + ADC PPH + STA PPH + STA IFPH + INY + LDA (IP),Y + BEQ + + ASL + TAY +- LDA ESTKH,X + DEY + STA (IFP),Y + LDA ESTKL,X + INX + DEY + STA (IFP),Y + BNE - ++ LDY #$03 + JMP FETCHOP +;* +;* LEAVE FUNCTION +;* +LEAVEX INY ;+INC_IP + LDA (IP),Y + CLC + ADC IFPL + STA PPL + LDA #$00 + ADC IFPH + STA PPH + PLA ; RESTORE PREVIOUS FRAME + STA IFPL + PLA + STA IFPH +RETX STA ALTRDOFF + LDA PSR + PHA + PLP + RTS +LEAVE INY ;+INC_IP + LDA (IP),Y + CLC + ADC IFPL + STA PPL + LDA #$00 + ADC IFPH + STA PPH + PLA ; RESTORE PREVIOUS FRAME + STA IFPL + PLA + STA IFPH +RET RTS +VMEND = * +} +;*************************************** +;* * +;* 65C02 OPS TO OVERWRITE STANDARD OPS * +;* * +;*************************************** +C02OPS LDA #DINTRP + LDY #(CDINTRPEND-CDINTRP) + JSR OPCPY +CDINTRP PLY + PLA + INY + BNE + + INC ++ STY IPL + STA IPH + LDY #$00 + LDA #>OPTBL + STA OPPAGE + JMP FETCHOP +CDINTRPEND +; + LDA #CN + LDY #(CCNEND-CCN) + JSR OPCPY +CCN DEX + LSR + STA ESTKL,X + STZ ESTKH,X + JMP NEXTOP +CCNEND +; + LDA #CB + LDY #(CCBEND-CCB) + JSR OPCPY +CCB DEX + STZ ESTKH,X + INY + LDA (IP),Y + STA ESTKL,X + JMP NEXTOP +CCBEND +; + LDA #CS + LDY #(CCSEND-CCS) + JSR OPCPY +CCS DEX + ;INY ;+INC_IP + TYA ; NORMALIZE IP AND SAVE STRING ADDR ON ESTK + SEC + ADC IPL + STA IPL + STA ESTKL,X + LDA #$00 + ADC IPH + STA IPH + STA ESTKH,X + LDA (IP) + TAY + JMP NEXTOP +CCSEND +; + LDA #SHL + LDY #(CSHLEND-CSHL) + JSR OPCPY +CSHL STY IPY + LDA ESTKL,X + CMP #$08 + BCC + + LDY ESTKL+1,X + STY ESTKH+1,X + STZ ESTKL+1,X + SBC #$08 ++ TAY + BEQ + + LDA ESTKL+1,X +- ASL + ROL ESTKH+1,X + DEY + BNE - + STA ESTKL+1,X ++ LDY IPY + JMP DROP +CSHLEND +; + LDA #LB + LDY #(CLBEND-CLB) + JSR OPCPY +CLB LDA ESTKL,X + STA ESTKH-1,X + LDA (ESTKH-1,X) + STA ESTKL,X + STZ ESTKH,X + JMP NEXTOP +CLBEND +; + LDA #LBX + LDY #(CLBXEND-CLBX) + JSR OPCPY +CLBX LDA ESTKL,X + STA ESTKH-1,X + STA ALTRDOFF + LDA (ESTKH-1,X) + STA ESTKL,X + STZ ESTKH,X + STA ALTRDON + JMP NEXTOP +CLBXEND +; + LDA #LLB + LDY #(CLLBEND-CLLB) + JSR OPCPY +CLLB INY ;+INC_IP + LDA (IP),Y + STY IPY + TAY + DEX + LDA (IFP),Y + STA ESTKL,X + STZ ESTKH,X + LDY IPY + JMP NEXTOP +CLLBEND +; + LDA #LLBX + LDY #(CLLBXEND-CLLBX) + JSR OPCPY +CLLBX INY ;+INC_IP + LDA (IP),Y + STY IPY + TAY + DEX + STA ALTRDOFF + LDA (IFP),Y + STA ESTKL,X + STZ ESTKH,X + STA ALTRDON + LDY IPY + JMP NEXTOP +CLLBXEND +; + LDA #LAB + LDY #(CLABEND-CLAB) + JSR OPCPY +CLAB INY ;+INC_IP + LDA (IP),Y + STA ESTKH-2,X + INY ;+INC_IP + LDA (IP),Y + STA ESTKH-1,X + LDA (ESTKH-2,X) + DEX + STA ESTKL,X + STZ ESTKH,X + JMP NEXTOP +CLABEND +; + LDA #LAW + LDY #(CLAWEND-CLAW) + JSR OPCPY +CLAW INY ;+INC_IP + LDA (IP),Y + STA TMPL + INY ;+INC_IP + LDA (IP),Y + STA TMPH + STY IPY + LDA (TMP) + DEX + STA ESTKL,X + LDY #$01 + LDA (TMP),Y + STA ESTKH,X + LDY IPY + JMP NEXTOP +CLAWEND +; + LDA #LABX + LDY #(CLABXEND-CLABX) + JSR OPCPY +CLABX INY ;+INC_IP + LDA (IP),Y + STA ESTKH-2,X + INY ;+INC_IP + LDA (IP),Y + STA ESTKH-1,X + STA ALTRDOFF + LDA (ESTKH-2,X) + DEX + STA ESTKL,X + STZ ESTKH,X + STA ALTRDON + JMP NEXTOP +CLABXEND +; + LDA #LAWX + LDY #(CLAWXEND-CLAWX) + JSR OPCPY +CLAWX INY ;+INC_IP + LDA (IP),Y + STA TMPL + INY ;+INC_IP + LDA (IP),Y + STA TMPH + STY IPY + STA ALTRDOFF + LDA (TMP) + DEX + STA ESTKL,X + LDY #$01 + LDA (TMP),Y + STA ESTKH,X + STA ALTRDON + LDY IPY + JMP NEXTOP +CLAWXEND +; + LDA #SAW + LDY #(CSAWEND-CSAW) + JSR OPCPY +CSAW INY ;+INC_IP + LDA (IP),Y + STA TMPL + INY ;+INC_IP + LDA (IP),Y + STA TMPH + STY IPY + LDA ESTKL,X + STA (TMP) + LDY #$01 + LDA ESTKH,X + STA (TMP),Y + LDY IPY + BMI + + JMP DROP ++ JMP FIXDROP +CSAWEND +; + LDA #DAW + LDY #(CDAWEND-CDAW) + JSR OPCPY +CDAW INY ;+INC_IP + LDA (IP),Y + STA TMPL + INY ;+INC_IP + LDA (IP),Y + STA TMPH + STY IPY + LDA ESTKL,X + STA (TMP) + LDY #$01 + LDA ESTKH,X + STA (TMP),Y + LDY IPY + JMP NEXTOP +CDAWEND +; + LDA #ISFLS + LDY #(CISFLSEND-CISFLS) + JSR OPCPY +CISFLS STZ ESTKL+1,X + STZ ESTKH+1,X + JMP DROP +CISFLSEND +; + LDA #BRNCH + LDY #(CBRNCHEND-CBRNCH) + JSR OPCPY +CBRNCH TYA ; FLATTEN IP + SEC + ADC IPL + STA TMPL + LDA #$00 + ADC IPH + STA TMPH ; ADD BRANCH OFFSET + LDA (TMP) + ;CLC ; BETTER NOT CARRY OUT OF IP+Y + ADC TMPL + STA IPL + LDY #$01 + LDA (TMP),Y + ADC TMPH + STA IPH + DEY + JMP FETCHOP +CBRNCHEND +; + RTS +;* +;* COPY OP TO VM +;* +OPCPY STA DST + STX DST+1 + PLA + STA SRC + PLA + STA SRC+1 + TYA + CLC + ADC SRC + TAX + LDA #$00 + ADC SRC+1 + PHA + PHX + INC SRC + BNE + + INC SRC+1 ++ DEY +- LDA (SRC),Y + STA (DST),Y + DEY + BPL - + RTS From 3fc34fe02805f16eebd3eb23fdaddec7d80315b3 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Tue, 20 Mar 2018 16:54:44 -0700 Subject: [PATCH 072/147] Parsing bytecode to compile --- src/libsrc/apple/jit.pla | 374 +++++++++++++++++++++++++++++++++++ src/vmsrc/apple/cmdjitstub.s | 7 + src/vmsrc/apple/plvmjit02.s | 4 +- 3 files changed, 383 insertions(+), 2 deletions(-) diff --git a/src/libsrc/apple/jit.pla b/src/libsrc/apple/jit.pla index 968e99f..94b97ee 100644 --- a/src/libsrc/apple/jit.pla +++ b/src/libsrc/apple/jit.pla @@ -31,8 +31,382 @@ const interpentry = $03DC // JIT compiler entry // def compiler(defptr)#0 + word codeptr, addrxlate, bytecode, i, case + byte j + puts("JIT compiler invoked!\n") + addrxlate = heapmark // 256 * sizeof(word) address xlate + bytecode = addrxlate + 512 // def bytecode + // + // Copy bytecode def from AUX to heap for compiling + // + *$003C = defptr=>bytecodeaddr + *$003E = *$003C + defptr->bytecodesize + *$0042 = bytecode + call($C311, 0, 0, 0, $00) // CALL XMOVE with carry clear (AUX->MAIN) + // + // Print out bytecode + // + i = 0 + repeat + putc('['); puti(i); puts("] ") + if bytecode->[i] < $20 + // CN,CN,CN,CN,CN,CN,CN,CN ; 00 02 04 06 08 0A 0C 0E + // CN,CN,CN,CN,CN,CN,CN,CN ; 10 12 14 16 18 1A 1C 1E + puts("CN $"); putb(bytecode->[i]/2) + else + when bytecode->[i] + // MINUS1,BREQ,BRNE,LA,LLA,CB,CW,CS ; 20 22 24 26 28 2A 2C 2E + is $20 + puts("MINUS_ONE") + break + is $22 + i++ + puts("BREQ "); puti(i + *(bytecode+i)) + i++ + break + is $24 + i++ + puts("BRNE "); puti(i + *(bytecode+i)) + i++ + break + is $26 + i++ + puts("LA $"); puth(*(bytecode+i)) + i++ + break + is $28 + i++ + puts("LLA "); puti(^(bytecode+i)) + break + is $2A + i++ + puts("CB $"); putb(^(bytecode+i)) + break + is $2C + i++ + puts("CW $"); puth(*(bytecode+i)) + i++ + break + is $2E + i++ + puts("CS "); puts(bytecode+i) + i = i + ^(bytecode+i) + break + // DROP,DROP2,DUP,DIVMOD,ADDI,SUBI,ANDI,ORI ; 30 32 34 36 38 3A 3C 3E + is $30 + puts("DROP") + break + is $32 + puts("DROP2") + break + is $34 + puts("DUP") + break + is $36 + puts("DIVMOD") + break + is $38 + i++ + puts("ADDI $"); putb(^(bytecode+i)) + break + is $3A + i++ + puts("SUBI $"); putb(^(bytecode+i)) + break + is $3C + i++ + puts("ANDI $"); putb(^(bytecode+i)) + break + is $3E + i++ + puts("ORI $"); putb(^(bytecode+i)) + break + // ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E + is $40 + puts("ISEQ") + break + is $42 + puts("ISNE") + break + is $44 + puts("ISGT") + break + is $46 + puts("ISLT") + break + is $48 + puts("ISGE") + break + is $4A + puts("ISLE") + break + is $4C + i++ + puts("BRFLS "); puti(i + *(bytecode+i)) + i++ + break + is $4E + i++ + puts("BRTRU "); puti(i + *(bytecode+i)) + i++ + break + // BRNCH,SEL,CALL,ICAL,ENTER,LEAVE,RET,CFFB ; 50 52 54 56 58 5A 5C 5E + is $50 + i++ + puts("BRNCH "); puti(i + *(bytecode+i)) + i++ + break + is $52 + i++ + case = i + *(bytecode+i) + puts("SEL "); puti(case) + j = ^case + ^case = $FF // Flag as NOP + case++ + repeat + puts(" $"); puth(*case) + *case = $FFFF + case = case + 2 + puts("-->"); puti(case + *case) + *case = $FFFF + case = case + 2 + j-- + until not j + i++ + break + is $54 + i++ + puts("CALL $"); puth(*(bytecode+i)) + i++ + break + is $56 + puts("ICAL") + break + is $58 + i++ + puts("ENTER "); puti(^(bytecode+i)) + break + is $5A + i++ + puts("LEAVE "); puti(^(bytecode+i)) + break + is $5C + puts("RET") + break + is $5E + i++ + puts("CFFB $FF"); putb(^(bytecode+i)) + break + // LB,LW,LLB,LLW,LAB,LAW,DLB,DLW ; 60 62 64 66 68 6A 6C 6E + is $60 + puts("LB") + break + is $62 + puts("LW") + break + is $64 + i++ + puts("LLB "); puti(^(bytecode+i)) + break + is $66 + i++ + puts("LLW "); puti(^(bytecode+i)) + break + is $68 + i++ + puts("LAB $"); puth(*(bytecode+i)) + i++ + break + is $6A + i++ + puts("LAW $"); puth(*(bytecode+i)) + i++ + break + is $6C + i++ + puts("DLB "); puti(^(bytecode+i)) + break + is $6E + i++ + puts("DLW "); puti(^(bytecode+i)) + break + // SB,SW,SLB,SLW,SAB,SAW,DAB,DAW ; 70 72 74 76 78 7A 7C 7E + is $70 + puts("SB") + break + is $72 + puts("SW") + break + is $74 + i++ + puts("SLB "); puti(^(bytecode+i)) + break + is $76 + i++ + puts("SLW "); puti(^(bytecode+i)) + break + is $78 + i++ + puts("SAB $"); puth(*(bytecode+i)) + i++ + break + is $7A + i++ + puts("SAW $"); puth(*(bytecode+i)) + i++ + break + is $7C + i++ + puts("DAB $"); puth(*(bytecode+i)) + i++ + break + is $7E + i++ + puts("DAW $"); puth(*(bytecode+i)) + i++ + break + // LNOT,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 80 82 84 86 88 8A 8C 8E + is $80 + puts("NOT") + break + is $82 + puts("ADD") + break + is $84 + puts("SUB") + break + is $86 + puts("MUL") + break + is $88 + puts("DIV") + break + is $8A + puts("MOD") + break + is $8C + puts("INCR") + break + is $8E + puts("DECR") + break + // NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 90 92 94 96 98 9A 9C 9E + is $90 + puts("NEG") + break + is $92 + puts("COMP") + break + is $94 + puts("AND") + break + is $96 + puts("OR") + break + is $98 + puts("XOR") + break + is $9A + puts("SHL") + break + is $9C + puts("SHR") + break + is $9E + puts("IDXW") + break + // BRGT,BRLT,INCBRLE,ADDBRLE,DECBRGE,SUBBRGE,BRAND,BROR ; A0 A2 A4 A6 A8 AA AC AE + is $A0 + i++ + puts("BRGT "); puti(i + *(bytecode+i)) + i++ + break + is $A2 + i++ + puts("BRLT "); puti(i + *(bytecode+i)) + i++ + break + is $A4 + i++ + puts("INCBRLE "); puti(i + *(bytecode+i)) + i++ + break + is $A6 + i++ + puts("ADDBRLE "); puti(i + *(bytecode+i)) + i++ + break + is $A8 + i++ + puts("DECBRGE "); puti(i + *(bytecode+i)) + i++ + break + is $AA + i++ + puts("SUBBRGE "); puti(i + *(bytecode+i)) + i++ + break + is $AC + i++ + puts("BRAND "); puti(i + *(bytecode+i)) + i++ + break + is $AE + i++ + puts("BROR "); puti(i + *(bytecode+i)) + i++ + break + // ADDLB,ADDLW,ADDAB,ADDAW,IDXLB,IDXLW,IDXAB,IDXAW ; B0 B2 B4 B6 B8 BA BC BE + is $B0 + i++ + puts("ADDLB "); puti(^(bytecode+i)) + break + is $B2 + i++ + puts("ADDLW "); puti(^(bytecode+i)) + break + is $B4 + i++ + puts("ADDAB $"); puth(*(bytecode+i)) + i++ + break + is $B6 + i++ + puts("ADDAW $"); puth(*(bytecode+i)) + i++ + break + is $B8 + i++ + puts("IDXLB "); puti(^(bytecode+i)) + break + is $BA + i++ + puts("IDXLW "); puti(^(bytecode+i)) + break + is $BC + i++ + puts("IDXAB $"); puth(*(bytecode+i)) + i++ + break + is $BE + i++ + puts("IDXAW $"); puth(*(bytecode+i)) + i++ + break + is $FF // NOPed out earlier by SELect + break + otherwise + putc('$'); puth(^(bytecode+i)) + wend + fin + putln + i++ + until i >= defptr->bytecodesize + // + // Overwrite interpreter entrypoint with standard bytecode interpreter + // defptr=>interpaddr = interpentry end // diff --git a/src/vmsrc/apple/cmdjitstub.s b/src/vmsrc/apple/cmdjitstub.s index 69f3a4e..ab4e8f9 100644 --- a/src/vmsrc/apple/cmdjitstub.s +++ b/src/vmsrc/apple/cmdjitstub.s @@ -5,6 +5,8 @@ ROMEN = $C082 LCRWEN = $C083 LCBNK2 = $00 LCBNK1 = $08 +JITCOMP = $03E2 +JITCODE = $03E4 !SOURCE "vmsrc/plvmzp.inc" ;* ;* MOVE CMD DOWN TO $1000-$2000 @@ -34,12 +36,17 @@ LCBNK1 = $08 ; STY PPL STY IFPL ; INIT FRAME POINTER + STY JITCOMP + STY JITCOMP+1 + STY JITCODE LDA #$B0 STA PPH STA IFPH + STA JITCODE+1 LDX #$FE ; INIT STACK POINTER (YES, $FE. SEE GETS) TXS LDX #ESTKSZ/2 ; INIT EVAL STACK INDEX + JMP $1000 _CMDBEGIN = * !PSEUDOPC $1000 { diff --git a/src/vmsrc/apple/plvmjit02.s b/src/vmsrc/apple/plvmjit02.s index 0c4b626..3dc6df7 100755 --- a/src/vmsrc/apple/plvmjit02.s +++ b/src/vmsrc/apple/plvmjit02.s @@ -401,10 +401,10 @@ PAGE3 = * BIT LCRDEN+LCBNK2 ; $03DC - BYTECODE INDIRECT INTERPX ENTRY JMP IINTRPX } -DEFCMD !FILL 28 +DEFCMD = * ;!FILL 28 ENDBYE = * } -LCDEFCMD = *-28 ; DEFCMD IN LC MEMORY +LCDEFCMD = * ;*-28 ; DEFCMD IN LC MEMORY ;***************** ;* * ;* OPXCODE TABLE * From 3afd11fd033c678eb6e6bdfcad9af82b79558f27 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Tue, 20 Mar 2018 21:01:59 -0700 Subject: [PATCH 073/147] New code translations --- src/libsrc/apple/jit.pla | 188 +++++++++++++++++++++++++++++++++--- src/vmsrc/apple/plvmjit02.s | 13 +++ 2 files changed, 186 insertions(+), 15 deletions(-) diff --git a/src/libsrc/apple/jit.pla b/src/libsrc/apple/jit.pla index 94b97ee..42e1394 100644 --- a/src/libsrc/apple/jit.pla +++ b/src/libsrc/apple/jit.pla @@ -31,40 +31,102 @@ const interpentry = $03DC // JIT compiler entry // def compiler(defptr)#0 - word codeptr, addrxlate, bytecode, i, case + word codeptr, addrxlate, bytecode, i, case, dest byte j puts("JIT compiler invoked!\n") - addrxlate = heapmark // 256 * sizeof(word) address xlate - bytecode = addrxlate + 512 // def bytecode + addrxlate = heapalloc(512 + defptr->bytecodesize) // 256 * sizeof(word) address xlate + if not addrxlate + // + // Not enough heap available + // + defptr=>interpaddr = interpentry + return + fin + memset(addrxlate, 0, 512) // Clear xlate buffer // // Copy bytecode def from AUX to heap for compiling // - *$003C = defptr=>bytecodeaddr - *$003E = *$003C + defptr->bytecodesize - *$0042 = bytecode + bytecode = addrxlate + 512 // def bytecode + *$003C = defptr=>bytecodeaddr + *$003E = *$003C + defptr->bytecodesize + *$0042 = bytecode call($C311, 0, 0, 0, $00) // CALL XMOVE with carry clear (AUX->MAIN) // - // Print out bytecode + // Compile the bytecodes // - i = 0 - repeat + codeptr = *jitcodeptr + i = 0 + while isule(codeptr, $BEF0) + // + // Update bytecode->native code address translation + // + if addrxlate=>[i] + // + // Address list awaiting resolution + // + dest = addrxlate=>[i] + *jitcodeptr + repeat + case = *dest + *dest = codeptr + dest = case + *jitcodeptr + until not dest + fin + addrxlate=>[i] = codeptr + putc('$'); puth(codeptr); putc(':') putc('['); puti(i); puts("] ") if bytecode->[i] < $20 // CN,CN,CN,CN,CN,CN,CN,CN ; 00 02 04 06 08 0A 0C 0E // CN,CN,CN,CN,CN,CN,CN,CN ; 10 12 14 16 18 1A 1C 1E - puts("CN $"); putb(bytecode->[i]/2) + puts("CN $"); putb(^(bytecode+i)/2) + ^codeptr = $CA; codeptr++ // DEX + ^codeptr = $A9; codeptr++ // LDA #imm + ^codeptr = ^(bytecode+i)/2; codeptr++ + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $A9; codeptr++ // LDA #imm + ^codeptr = $00; codeptr++ // $00 + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0; codeptr++ // ESTKH else when bytecode->[i] // MINUS1,BREQ,BRNE,LA,LLA,CB,CW,CS ; 20 22 24 26 28 2A 2C 2E is $20 puts("MINUS_ONE") + ^codeptr = $CA; codeptr++ // DEX + ^codeptr = $A9; codeptr++ // LDA #imm + ^codeptr = $FF; codeptr++ // $FF + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0; codeptr++ // ESTKH break is $22 i++ - puts("BREQ "); puti(i + *(bytecode+i)) + dest = i + *(bytecode+i) i++ + puts("BREQ "); puti(dest) + ^codeptr = $E8; codeptr++ // INX + ^codeptr = $E8; codeptr++ // INX + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0-2; codeptr++ // ESTKL-2 + ^codeptr = $D5; codeptr++ // CMP zp,X + ^codeptr = $D0-1; codeptr++ // ESTKL-1 + ^codeptr = $D0; codeptr++ // BNE rel + ^codeptr = $0A; codeptr++ // +10 + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $C0-2; codeptr++ // ESTKH-2 + ^codeptr = $D5; codeptr++ // CMP zp,X + ^codeptr = $C0-1; codeptr++ // ESTKH-1 + ^codeptr = $D0; codeptr++ // BNE rel + ^codeptr = $04; codeptr++ // +4 + ^codeptr = $4C; codeptr++ // JMP xxyy + *codeptr = addrxlate=>[dest] + if not (*codeptr & $8000) // Unresolved address list + addrxlate=>[dest] = codeptr - *jitcodeptr + fin + codeptr = codeptr + 2 break is $24 i++ @@ -74,7 +136,16 @@ def compiler(defptr)#0 is $26 i++ puts("LA $"); puth(*(bytecode+i)) + ^codeptr = $CA; codeptr++ // DEX + ^codeptr = $A9; codeptr++ // LDA #imm + ^codeptr = ^(bytecode+i); codeptr++ i++ + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $A9; codeptr++ // LDA #imm + ^codeptr = ^(bytecode+i); codeptr++ + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0; codeptr++ // ESTKH break is $28 i++ @@ -83,11 +154,29 @@ def compiler(defptr)#0 is $2A i++ puts("CB $"); putb(^(bytecode+i)) + ^codeptr = $CA; codeptr++ // DEX + ^codeptr = $A9; codeptr++ // LDA #imm + ^codeptr = ^(bytecode+i); codeptr++ + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $A9; codeptr++ // LDA #imm + ^codeptr = $00; codeptr++ // $00 + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0; codeptr++ // ESTKH break is $2C i++ puts("CW $"); puth(*(bytecode+i)) + ^codeptr = $CA; codeptr++ // DEX + ^codeptr = $A9; codeptr++ // LDA #imm + ^codeptr = ^(bytecode+i); codeptr++ i++ + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $A9; codeptr++ // LDA #imm + ^codeptr = ^(bytecode+i); codeptr++ + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0; codeptr++ // ESTKH break is $2E i++ @@ -179,25 +268,73 @@ def compiler(defptr)#0 is $54 i++ puts("CALL $"); puth(*(bytecode+i)) + // + // Call address + // + ^codeptr = $20; codeptr++ // JSR xxyy + *codeptr = *(bytecode+i); codeptr = codeptr + 2 i++ break is $56 puts("ICAL") - break + // + // Pull address off stack + // + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $85; codeptr++ // STA zp + ^codeptr = $E7; codeptr++ // $E7:TMPL + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $85; codeptr++ // STA zp + ^codeptr = $E8; codeptr++ // $E8:TMPH + ^codeptr = $E8; codeptr++ // INX + // + // Call through TMP + // + ^codeptr = $20; codeptr++ // JSR xxyy + ^codeptr = $E6; codeptr++ // JMPTMP + break is $58 i++ puts("ENTER "); puti(^(bytecode+i)) + // + // Call into VM + // + ^codeptr = $20; codeptr++ // JSR INTERP + *codeptr = $3D0; codeptr = codeptr + 2 + ^codeptr = $58; codeptr++ // ENTER CODE + ^codeptr = i; codeptr++ // ENTER OPERAND + ^codeptr = $C0; codeptr++ // NATIVE CODE break is $5A i++ puts("LEAVE "); puti(^(bytecode+i)) + // + // Call into VM + // + ^codeptr = $20; codeptr++ // JSR INTERP + *codeptr = $3D0; codeptr = codeptr + 2 + ^codeptr = $58; codeptr++ // LEAVE CODE + ^codeptr = i; codeptr++ // LEAVE OPERAND break is $5C puts("RET") - break + ^codeptr = $60; codeptr++ // RTS + break is $5E i++ puts("CFFB $FF"); putb(^(bytecode+i)) + ^codeptr = $CA; codeptr++ // DEX + ^codeptr = $A9; codeptr++ // LDA #imm + ^codeptr = ^(bytecode+i); codeptr++ + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $A9; codeptr++ // LDA #imm + ^codeptr = $FF; codeptr++ + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0; codeptr++ // ESTKH break // LB,LW,LLB,LLW,LAB,LAW,DLB,DLW ; 60 62 64 66 68 6A 6C 6E is $60 @@ -403,11 +540,32 @@ def compiler(defptr)#0 fin putln i++ - until i >= defptr->bytecodesize + 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) + return + fin + loop // - // Overwrite interpreter entrypoint with standard bytecode interpreter + // 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) end // // Install JIT compiler diff --git a/src/vmsrc/apple/plvmjit02.s b/src/vmsrc/apple/plvmjit02.s index 3dc6df7..41f0457 100755 --- a/src/vmsrc/apple/plvmjit02.s +++ b/src/vmsrc/apple/plvmjit02.s @@ -223,6 +223,7 @@ OPTBL !WORD CN,CN,CN,CN,CN,CN,CN,CN ; 00 02 !WORD NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 90 92 94 96 98 9A 9C 9E !WORD BRGT,BRLT,INCBRLE,ADDBRLE,DECBRGE,SUBBRGE,BRAND,BROR ; A0 A2 A4 A6 A8 AA AC AE !WORD ADDLB,ADDLW,ADDAB,ADDAW,IDXLB,IDXLW,IDXAB,IDXAW ; B0 B2 B4 B6 B8 BA BC BE + !WORD NATIVE ; C0 ;* ;* DIRECTLY ENTER INTO BYTECODE INTERPRETER ;* @@ -423,6 +424,7 @@ OPXTBL !WORD CN,CN,CN,CN,CN,CN,CN,CN ; 00 02 !WORD NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 90 92 94 96 98 9A 9C 9E !WORD BRGT,BRLT,INCBRLE,ADDBRLE,DECBRGE,SUBBRGE,BRAND,BROR ; A0 A2 A4 A6 A8 AA AC AE !WORD ADDLBX,ADDLWX,ADDABX,ADDAWX,IDXLBX,IDXLWX,IDXABX,IDXAWX ; B0 B2 B4 B6 B8 BA BC BE + !WORD NATIVE ; C0 ;* ;* JIT PROFILING ENTRY INTO INTERPRETER ;* @@ -2019,6 +2021,17 @@ LEAVE INY ;+INC_IP PLA STA IFPH RET RTS +;* +;* RETURN TO NATIVE CODE +;* +NATIVE TYA ; FLATTEN IP + SEC + ADC IPL + STA TMPL + LDA #$00 + ADC IPH + STA TMPH + JMP JMPTMP VMEND = * } ;*************************************** From e16f45f59b119b53adf113d2ae521c5a1f2c645e Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Wed, 21 Mar 2018 13:00:23 -0700 Subject: [PATCH 074/147] First pass at JIT --- src/libsrc/apple/jit.pla | 1083 +++++++++++++++++++++++++++++++++-- src/vmsrc/apple/plvm02.s | 1 - src/vmsrc/apple/plvm03.s | 1 - src/vmsrc/apple/plvmjit02.s | 7 +- 4 files changed, 1052 insertions(+), 40 deletions(-) diff --git a/src/libsrc/apple/jit.pla b/src/libsrc/apple/jit.pla index 42e1394..2eab9c3 100644 --- a/src/libsrc/apple/jit.pla +++ b/src/libsrc/apple/jit.pla @@ -23,6 +23,7 @@ end const jitcount = $10 const jitcomp = $03E2 const jitcodeptr = $03E4 +const codemax = $BEF0 // // AUX bytecode interpreter entrypoint // @@ -58,7 +59,7 @@ def compiler(defptr)#0 // codeptr = *jitcodeptr i = 0 - while isule(codeptr, $BEF0) + while isule(codeptr, codemax) // // Update bytecode->native code address translation // @@ -114,14 +115,14 @@ def compiler(defptr)#0 ^codeptr = $D5; codeptr++ // CMP zp,X ^codeptr = $D0-1; codeptr++ // ESTKL-1 ^codeptr = $D0; codeptr++ // BNE rel - ^codeptr = $0A; codeptr++ // +10 + ^codeptr = $09; codeptr++ // +9 ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $C0-2; codeptr++ // ESTKH-2 ^codeptr = $D5; codeptr++ // CMP zp,X ^codeptr = $C0-1; codeptr++ // ESTKH-1 ^codeptr = $D0; codeptr++ // BNE rel - ^codeptr = $04; codeptr++ // +4 - ^codeptr = $4C; codeptr++ // JMP xxyy + ^codeptr = $03; codeptr++ // +3 + ^codeptr = $4C; codeptr++ // JMP abs *codeptr = addrxlate=>[dest] if not (*codeptr & $8000) // Unresolved address list addrxlate=>[dest] = codeptr - *jitcodeptr @@ -130,8 +131,29 @@ def compiler(defptr)#0 break is $24 i++ - puts("BRNE "); puti(i + *(bytecode+i)) + dest = i + *(bytecode+i) i++ + puts("BRNE "); puti(dest) + ^codeptr = $E8; codeptr++ // INX + ^codeptr = $E8; codeptr++ // INX + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0-2; codeptr++ // ESTKL-2 + ^codeptr = $D5; codeptr++ // CMP zp,X + ^codeptr = $D0-1; codeptr++ // ESTKL-1 + ^codeptr = $D0; codeptr++ // BNE rel + ^codeptr = $06; codeptr++ // +6 + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $C0-2; codeptr++ // ESTKH-2 + ^codeptr = $D5; codeptr++ // CMP zp,X + ^codeptr = $C0-1; codeptr++ // ESTKH-1 + ^codeptr = $F0; codeptr++ // BEQ rel + ^codeptr = $03; codeptr++ // +3 + ^codeptr = $4C; codeptr++ // JMP abs + *codeptr = addrxlate=>[dest] + if not (*codeptr & $8000) // Unresolved address list + addrxlate=>[dest] = codeptr - *jitcodeptr + fin + codeptr = codeptr + 2 break is $26 i++ @@ -150,6 +172,20 @@ def compiler(defptr)#0 is $28 i++ puts("LLA "); puti(^(bytecode+i)) + ^codeptr = $CA; codeptr++ // DEX + ^codeptr = $A9; codeptr++ // LDA #imm + ^codeptr = ^(bytecode+i); codeptr++ + ^codeptr = $18; codeptr++ // CLC + ^codeptr = $65; codeptr++ // ADC zp + ^codeptr = $E0; codeptr++ // IFPL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $A9; codeptr++ // LDA #imm + ^codeptr = $00; codeptr++ // $00 + ^codeptr = $65; codeptr++ // ADC zp + ^codeptr = $E1; codeptr++ // IFPH + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0; codeptr++ // ESTKH break is $2A i++ @@ -180,90 +216,362 @@ def compiler(defptr)#0 break is $2E i++ + j = ^(bytecode+i) puts("CS "); puts(bytecode+i) - i = i + ^(bytecode+i) + i++ + if isule(codeptr + 12 + j, codemax) + ^codeptr = $CA; codeptr++ // DEX + ^codeptr = $A9; codeptr++ // LDA #imm + ^codeptr = codeptr+10; codeptr++ + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $A9; codeptr++ // LDA #imm + ^codeptr = (codeptr+6)>>8; codeptr++ + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $4C; codeptr++ // JMP abs + *codeptr = addrxlate=>[i+j] + if not (*codeptr & $8000) // Unresolved address list + addrxlate=>[i+j] = codeptr - *jitcodeptr + fin + codeptr = codeptr + 2 + ^codeptr = j; codeptr++ + while j + ^(bytecode+i); codeptr++ + i++ + j-- + loop + else + codeptr = codeptr + 12 + j // Flag buffer overflow + fin break // DROP,DROP2,DUP,DIVMOD,ADDI,SUBI,ANDI,ORI ; 30 32 34 36 38 3A 3C 3E is $30 puts("DROP") + ^codeptr = $E8; codeptr++ // INX break is $32 puts("DROP2") + ^codeptr = $E8; codeptr++ // INX + ^codeptr = $E8; codeptr++ // INX break is $34 puts("DUP") + ^codeptr = $CA; codeptr++ // DEX + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0-1; codeptr++ // ESTKL-1 + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $C0-1; codeptr++ // ESTKH-1 + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0; codeptr++ // ESTKH break is $36 puts("DIVMOD") + // + // Should never happen + // break is $38 i++ puts("ADDI $"); putb(^(bytecode+i)) + ^codeptr = $A9; codeptr++ // LDA #imm + ^codeptr = ^(bytecode+i); codeptr++ + ^codeptr = $18; codeptr++ // CLC + ^codeptr = $75; codeptr++ // ADC zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $90; codeptr++ // BCC rel + ^codeptr = $02; codeptr++ // +2 + ^codeptr = $F6; codeptr++ // INC zp,X + ^codeptr = $C0; codeptr++ // ESTKH break is $3A i++ puts("SUBI $"); putb(^(bytecode+i)) + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $18; codeptr++ // SEC + ^codeptr = $E9; codeptr++ // SBC #imm + ^codeptr = ^(bytecode+i); codeptr++ + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $B0; codeptr++ // BCS rel + ^codeptr = $02; codeptr++ // +2 + ^codeptr = $D6; codeptr++ // DEC zp,X + ^codeptr = $C0; codeptr++ // ESTKH break is $3C i++ puts("ANDI $"); putb(^(bytecode+i)) + ^codeptr = $A9; codeptr++ // LDA #imm + ^codeptr = ^(bytecode+i); codeptr++ + ^codeptr = $35; codeptr++ // AND zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $A9; codeptr++ // LDA #imm + ^codeptr = $00; codeptr++ // $00 + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0; codeptr++ // ESTKH break is $3E i++ puts("ORI $"); putb(^(bytecode+i)) + ^codeptr = $A9; codeptr++ // LDA #imm + ^codeptr = ^(bytecode+i); codeptr++ + ^codeptr = $15; codeptr++ // ORA zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0; codeptr++ // ESTKL break // ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E is $40 puts("ISEQ") + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $00; codeptr++ // $00 + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+1; codeptr++ // ESTKL+1 + ^codeptr = $D5; codeptr++ // CMP zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $D0; codeptr++ // BNE rel + ^codeptr = $07; codeptr++ // +7 + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $C0+1; codeptr++ // ESTKH+1 + ^codeptr = $D5; codeptr++ // CMP zp,X + ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $D0; codeptr++ // BNE rel + ^codeptr = $01; codeptr++ // +1 + ^codeptr = $88; codeptr++ // DEY + ^codeptr = $E8; codeptr++ // INX + ^codeptr = $94; codeptr++ // STY zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $94; codeptr++ // STY zp,X + ^codeptr = $C0; codeptr++ // ESTKH break is $42 puts("ISNE") + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $00; codeptr++ // $FF + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+1; codeptr++ // ESTKL+1 + ^codeptr = $D5; codeptr++ // CMP zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $D0; codeptr++ // BNE rel + ^codeptr = $07; codeptr++ // +7 + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $C0+1; codeptr++ // ESTKH+1 + ^codeptr = $D5; codeptr++ // CMP zp,X + ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $D0; codeptr++ // BNE rel + ^codeptr = $01; codeptr++ // +1 + ^codeptr = $C8; codeptr++ // INY + ^codeptr = $E8; codeptr++ // INX + ^codeptr = $94; codeptr++ // STY zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $94; codeptr++ // STY zp,X + ^codeptr = $C0; codeptr++ // ESTKH break is $44 puts("ISGT") + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $00; codeptr++ // $FF + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $D5; codeptr++ // CMP zp,X + ^codeptr = $D0+1; codeptr++ // ESTKL+1 + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $F5; codeptr++ // SBC zp,X + ^codeptr = $C0+1; codeptr++ // ESTKH+1 + ^codeptr = $50; codeptr++ // BVC rel + ^codeptr = $02; codeptr++ // +2 + ^codeptr = $49; codeptr++ // EOR #imm + ^codeptr = $80; codeptr++ // $80 + ^codeptr = $30; codeptr++ // BMI rel + ^codeptr = $01; codeptr++ // +1 + ^codeptr = $C8; codeptr++ // INY + ^codeptr = $E8; codeptr++ // INX + ^codeptr = $94; codeptr++ // STY zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $94; codeptr++ // STY zp,X + ^codeptr = $C0; codeptr++ // ESTKH break is $46 puts("ISLT") + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $00; codeptr++ // $FF + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+1; codeptr++ // ESTKL+1 + ^codeptr = $D5; codeptr++ // CMP zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $C0+1; codeptr++ // ESTKH+1 + ^codeptr = $F5; codeptr++ // SBC zp,X + ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $50; codeptr++ // BVC rel + ^codeptr = $02; codeptr++ // +2 + ^codeptr = $49; codeptr++ // EOR #imm + ^codeptr = $80; codeptr++ // $80 + ^codeptr = $30; codeptr++ // BMI rel + ^codeptr = $01; codeptr++ // +1 + ^codeptr = $C8; codeptr++ // INY + ^codeptr = $E8; codeptr++ // INX + ^codeptr = $94; codeptr++ // STY zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $94; codeptr++ // STY zp,X + ^codeptr = $C0; codeptr++ // ESTKH break is $48 puts("ISGE") + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $00; codeptr++ // $FF + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+1; codeptr++ // ESTKL+1 + ^codeptr = $D5; codeptr++ // CMP zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $C0+1; codeptr++ // ESTKH+1 + ^codeptr = $F5; codeptr++ // SBC zp,X + ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $50; codeptr++ // BVC rel + ^codeptr = $02; codeptr++ // +2 + ^codeptr = $49; codeptr++ // EOR #imm + ^codeptr = $80; codeptr++ // $80 + ^codeptr = $10; codeptr++ // BPL rel + ^codeptr = $01; codeptr++ // +1 + ^codeptr = $C8; codeptr++ // INY + ^codeptr = $E8; codeptr++ // INX + ^codeptr = $94; codeptr++ // STY zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $94; codeptr++ // STY zp,X + ^codeptr = $C0; codeptr++ // ESTKH break is $4A puts("ISLE") + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $00; codeptr++ // $FF + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $D5; codeptr++ // CMP zp,X + ^codeptr = $D0+1; codeptr++ // ESTKL+1 + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $F5; codeptr++ // SBC zp,X + ^codeptr = $C0+1; codeptr++ // ESTKH+1 + ^codeptr = $50; codeptr++ // BVC rel + ^codeptr = $02; codeptr++ // +2 + ^codeptr = $49; codeptr++ // EOR #imm + ^codeptr = $80; codeptr++ // $80 + ^codeptr = $10; codeptr++ // BPL rel + ^codeptr = $01; codeptr++ // +1 + ^codeptr = $C8; codeptr++ // INY + ^codeptr = $E8; codeptr++ // INX + ^codeptr = $94; codeptr++ // STY zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $94; codeptr++ // STY zp,X + ^codeptr = $C0; codeptr++ // ESTKH break is $4C i++ - puts("BRFLS "); puti(i + *(bytecode+i)) + dest = i + *(bytecode+i) i++ + puts("BRFLS "); puti(dest) + ^codeptr = $E8; codeptr++ // INX + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0-1; codeptr++ // ESTKL-1 + ^codeptr = $15; codeptr++ // ORA zp,X + ^codeptr = $C0-1; codeptr++ // ESTKH-1 + ^codeptr = $D0; codeptr++ // BNE rel + ^codeptr = $03; codeptr++ // +3 + ^codeptr = $4C; codeptr++ // JMP abs + *codeptr = addrxlate=>[dest] + if not (*codeptr & $8000) // Unresolved address list + addrxlate=>[dest] = codeptr - *jitcodeptr + fin + codeptr = codeptr + 2 break is $4E i++ - puts("BRTRU "); puti(i + *(bytecode+i)) + dest = i + *(bytecode+i) i++ + puts("BRTRU "); puti(dest) + ^codeptr = $E8; codeptr++ // INX + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0-1; codeptr++ // ESTKL-1 + ^codeptr = $15; codeptr++ // ORA zp,X + ^codeptr = $C0-1; codeptr++ // ESTKH-1 + ^codeptr = $F0; codeptr++ // BEQ rel + ^codeptr = $03; codeptr++ // +3 + ^codeptr = $4C; codeptr++ // JMP abs + *codeptr = addrxlate=>[dest] + if not (*codeptr & $8000) // Unresolved address list + addrxlate=>[dest] = codeptr - *jitcodeptr + fin + codeptr = codeptr + 2 break // BRNCH,SEL,CALL,ICAL,ENTER,LEAVE,RET,CFFB ; 50 52 54 56 58 5A 5C 5E is $50 i++ - puts("BRNCH "); puti(i + *(bytecode+i)) + dest = i + *(bytecode+i) i++ + puts("BRNCH "); puti(dest) + ^codeptr = $4C; codeptr++ // JMP abs + *codeptr = addrxlate=>[dest] + if not (*codeptr & $8000) // Unresolved address list + addrxlate=>[dest] = codeptr - *jitcodeptr + fin + codeptr = codeptr + 2 break is $52 i++ case = i + *(bytecode+i) puts("SEL "); puti(case) j = ^case - ^case = $FF // Flag as NOP - case++ - repeat - puts(" $"); puth(*case) - *case = $FFFF - case = case + 2 - puts("-->"); puti(case + *case) - *case = $FFFF - case = case + 2 - j-- - until not j - i++ + dest = codeptr + 8 + case * 11) + if isule(dest, codemax) + ^case = $FF // Flag as NOP + case++ + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $B4; codeptr++ // LDY zp,X + ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $E8; codeptr++ // INX + repeat + puts(" $"); puth(*case) + ^codeptr = $C9; codeptr++ // CMP #imm + ^codeptr = ^(bytecode+case); codeptr++ + ^codeptr = $D0; codeptr++ // BNE rel + ^codeptr = $07; codeptr++ // +7 + ^codeptr = $C0; codeptr++ // CPY #imm + ^codeptr = ^(bytecode+case+1); codeptr++ + ^codeptr = $D0; codeptr++ // BNE rel + ^codeptr = $03; codeptr++ // +3 + *case = $FFFF + case = case + 2 + puts("-->"); puti(case + *case) + ^codeptr = $4C; codeptr++ // JMP abs + *codeptr = addrxlate=>[case] + if not (*codeptr & $8000) // Unresolved address list + addrxlate=>[case] = codeptr - *jitcodeptr + fin + codeptr = codeptr + 2 + *case = $FFFF + case = case + 2 + j-- + until not j + ^codeptr = $4C; codeptr++ // JMP abs + *codeptr = addrxlate=>[case] + if not (*codeptr & $8000) // Unresolved address list + addrxlate=>[case] = codeptr - *jitcodeptr + fin + codeptr = codeptr + 2 + i++ + else + codeptr = dest + fin break is $54 i++ @@ -271,7 +579,7 @@ def compiler(defptr)#0 // // Call address // - ^codeptr = $20; codeptr++ // JSR xxyy + ^codeptr = $20; codeptr++ // JSR abs *codeptr = *(bytecode+i); codeptr = codeptr + 2 i++ break @@ -292,7 +600,7 @@ def compiler(defptr)#0 // // Call through TMP // - ^codeptr = $20; codeptr++ // JSR xxyy + ^codeptr = $20; codeptr++ // JSR abs ^codeptr = $E6; codeptr++ // JMPTMP break @@ -306,7 +614,7 @@ def compiler(defptr)#0 *codeptr = $3D0; codeptr = codeptr + 2 ^codeptr = $58; codeptr++ // ENTER CODE ^codeptr = i; codeptr++ // ENTER OPERAND - ^codeptr = $C0; codeptr++ // NATIVE CODE + ^codeptr = $C0; codeptr++ // NATV CODE break is $5A i++ @@ -332,204 +640,911 @@ def compiler(defptr)#0 ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0; codeptr++ // ESTKL ^codeptr = $A9; codeptr++ // LDA #imm - ^codeptr = $FF; codeptr++ + ^codeptr = $FF; codeptr++ // $FF ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $C0; codeptr++ // ESTKH break // LB,LW,LLB,LLW,LAB,LAW,DLB,DLW ; 60 62 64 66 68 6A 6C 6E is $60 puts("LB") + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0-1; codeptr++ // ESTKH-1 + ^codeptr = $A1; codeptr++ // LDA (zp,X) + ^codeptr = $C0-1; codeptr++ // ESTKH-1 + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $A9; codeptr++ // LDA #imm + ^codeptr = $00; codeptr++ // $00 + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0; codeptr++ // ESTKH break is $62 puts("LW") + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0-1; codeptr++ // ESTKH-1 + ^codeptr = $A1; codeptr++ // LDA (zp,X) + ^codeptr = $C0-1; codeptr++ // ESTKH-1 + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $A9; codeptr++ // LDA #imm + ^codeptr = $00; codeptr++ // $00 + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $F6; codeptr++ // INC zp,X + ^codeptr = $C0-1; codeptr++ // ESTKH-1 + ^codeptr = $D0; codeptr++ // BNE rel + ^codeptr = $02; codeptr++ // +2 + ^codeptr = $F6; codeptr++ // INC zp,X + ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $A1; codeptr++ // LDA (zp,X) + ^codeptr = $C0-1; codeptr++ // ESTKH-1 + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0; codeptr++ // ESTKH break is $64 i++ puts("LLB "); puti(^(bytecode+i)) + ^codeptr = $CA; codeptr++ // DEX + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = ^(bytecode+i); codeptr++ + ^codeptr = $B1; codeptr++ // LDA (zp),Y + ^codeptr = $E0; codeptr++ // IFP + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $A9; codeptr++ // LDA #imm + ^codeptr = $FF; codeptr++ // $00 + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0; codeptr++ // ESTKH break is $66 i++ puts("LLW "); puti(^(bytecode+i)) + ^codeptr = $CA; codeptr++ // DEX + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = ^(bytecode+i); codeptr++ + ^codeptr = $B1; codeptr++ // LDA (zp),Y + ^codeptr = $E0; codeptr++ // IFP + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $C8; codeptr++ // INY + ^codeptr = $B1; codeptr++ // LDA (zp),Y + ^codeptr = $E0; codeptr++ // IFP + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0; codeptr++ // ESTKH break is $68 i++ puts("LAB $"); puth(*(bytecode+i)) + ^codeptr = $CA; codeptr++ // DEX + ^codeptr = $AD; codeptr++ // LDA abs + *codeptr = *(bytecode+i); codeptr = codeptr + 2 + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $A9; codeptr++ // LDA #imm + ^codeptr = $FF; codeptr++ // $00 + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0; codeptr++ // ESTKH i++ break is $6A i++ puts("LAW $"); puth(*(bytecode+i)) + ^codeptr = $CA; codeptr++ // DEX + ^codeptr = $AD; codeptr++ // LDA abs + *codeptr = *(bytecode+i); codeptr = codeptr + 2 + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $AD; codeptr++ // LDA abs + *codeptr = *(bytecode+i)+1; codeptr = codeptr + 2 + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0; codeptr++ // ESTKH i++ break is $6C i++ puts("DLB "); puti(^(bytecode+i)) + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = ^(bytecode+i); codeptr++ + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $91; codeptr++ // STA (zp),Y + ^codeptr = $E0; codeptr++ // IFP break is $6E i++ puts("DLW "); puti(^(bytecode+i)) + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = ^(bytecode+i); codeptr++ + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $91; codeptr++ // STA (zp),Y + ^codeptr = $E0; codeptr++ // IFP + ^codeptr = $C8; codeptr++ // INY + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $91; codeptr++ // STA (zp),Y + ^codeptr = $E0; codeptr++ // IFP break // SB,SW,SLB,SLW,SAB,SAW,DAB,DAW ; 70 72 74 76 78 7A 7C 7E is $70 puts("SB") + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0-1; codeptr++ // ESTKH-1 + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+1; codeptr++ // ESTKL+1 + ^codeptr = $81; codeptr++ // STA (zp,X) + ^codeptr = $C0-1; codeptr++ // ESTKH-1 + ^codeptr = $E8; codeptr++ // INX + ^codeptr = $E8; codeptr++ // INX break is $72 puts("SW") + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0-1; codeptr++ // ESTKH-1 + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+1; codeptr++ // ESTKL+1 + ^codeptr = $81; codeptr++ // STA (zp,X) + ^codeptr = $C0-1; codeptr++ // ESTKH-1 + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $C0+1; codeptr++ // ESTKH+1 + ^codeptr = $F6; codeptr++ // INC zp,X + ^codeptr = $C0-1; codeptr++ // ESTKH-1 + ^codeptr = $D0; codeptr++ // BNE rel + ^codeptr = $02; codeptr++ // +2 + ^codeptr = $F6; codeptr++ // INC zp,X + ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $81; codeptr++ // STA (zp,X) + ^codeptr = $C0-1; codeptr++ // ESTKH-1 + ^codeptr = $E8; codeptr++ // INX + ^codeptr = $E8; codeptr++ // INX break is $74 i++ puts("SLB "); puti(^(bytecode+i)) + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = ^(bytecode+i); codeptr++ + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $91; codeptr++ // STA (zp),Y + ^codeptr = $E0; codeptr++ // IFP + ^codeptr = $E8; codeptr++ // INX break is $76 i++ puts("SLW "); puti(^(bytecode+i)) + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = ^(bytecode+i); codeptr++ + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $91; codeptr++ // STA (zp),Y + ^codeptr = $E0; codeptr++ // IFP + ^codeptr = $C8; codeptr++ // INY + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $91; codeptr++ // STA (zp),Y + ^codeptr = $E0; codeptr++ // IFP + ^codeptr = $E8; codeptr++ // INX break is $78 i++ puts("SAB $"); puth(*(bytecode+i)) + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $8D; codeptr++ // STA abs + *codeptr = *(bytecode+i); codeptr = codeptr + 2 + ^codeptr = $E8; codeptr++ // INX i++ break is $7A i++ puts("SAW $"); puth(*(bytecode+i)) + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $8D; codeptr++ // STA abs + *codeptr = *(bytecode+i); codeptr = codeptr + 2 + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $8D; codeptr++ // STA abs + *codeptr = *(bytecode+i)+1; codeptr = codeptr + 2 + ^codeptr = $E8; codeptr++ // INX i++ break is $7C i++ puts("DAB $"); puth(*(bytecode+i)) + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $8D; codeptr++ // STA abs + *codeptr = *(bytecode+i); codeptr = codeptr + 2 i++ break is $7E i++ puts("DAW $"); puth(*(bytecode+i)) + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $8D; codeptr++ // STA abs + *codeptr = *(bytecode+i); codeptr = codeptr + 2 + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $8D; codeptr++ // STA abs + *codeptr = *(bytecode+i)+1; codeptr = codeptr + 2 i++ break // LNOT,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 80 82 84 86 88 8A 8C 8E is $80 puts("NOT") + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $15; codeptr++ // ORA zp,X + ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $F0; codeptr++ // BEQ rel + ^codeptr = $02; codeptr++ // +2 + ^codeptr = $A9; codeptr++ // LDA #imm + ^codeptr = $FF; codeptr++ // $FF + ^codeptr = $49; codeptr++ // EOR #imm + ^codeptr = $FF; codeptr++ // $FF + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0; codeptr++ // ESTKH break is $82 puts("ADD") + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $18; codeptr++ // CLC + ^codeptr = $75; codeptr++ // ADC zp,X + ^codeptr = $D0+1; codeptr++ // ESTKL+1 + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+1; codeptr++ // ESTKL+1 + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $75; codeptr++ // ADC zp,X + ^codeptr = $C0+1; codeptr++ // ESTKH+1 + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0+1; codeptr++ // ESTKH+1 + ^codeptr = $E8; codeptr++ // INX break is $84 puts("SUB") + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+1; codeptr++ // ESTKL+1 + ^codeptr = $38; codeptr++ // SEC + ^codeptr = $F5; codeptr++ // SBC zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+1; codeptr++ // ESTKL+1 + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $C0+1; codeptr++ // ESTKH+1 + ^codeptr = $F5; codeptr++ // SBC zp,X + ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0+1; codeptr++ // ESTKH+1 + ^codeptr = $E8; codeptr++ // INX break is $86 puts("MUL") - break + // + // Call into VM + // + ^codeptr = $20; codeptr++ // JSR INTERP + *codeptr = $3D0; codeptr = codeptr + 2 + ^codeptr = $86; codeptr++ // MUL CODE + ^codeptr = $C0; codeptr++ // NATV CODE + break is $88 puts("DIV") + // + // Call into VM + // + ^codeptr = $20; codeptr++ // JSR INTERP + *codeptr = $3D0; codeptr = codeptr + 2 + ^codeptr = $88; codeptr++ // DIV CODE + ^codeptr = $C0; codeptr++ // NATV CODE break is $8A puts("MOD") + // + // Call into VM + // + ^codeptr = $20; codeptr++ // JSR INTERP + *codeptr = $3D0; codeptr = codeptr + 2 + ^codeptr = $8A; codeptr++ // MOD CODE + ^codeptr = $C0; codeptr++ // NATV CODE break is $8C puts("INCR") + ^codeptr = $F6; codeptr++ // INC zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $D0; codeptr++ // BNE rel + ^codeptr = $02; codeptr++ // +2 + ^codeptr = $F6; codeptr++ // INC zp,X + ^codeptr = $C0; codeptr++ // ESTKH break is $8E puts("DECR") + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $D0; codeptr++ // BNE rel + ^codeptr = $02; codeptr++ // +2 + ^codeptr = $D6; codeptr++ // DEC zp,X + ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $D6; codeptr++ // DEC zp,X + ^codeptr = $D0; codeptr++ // ESTKL break // NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 90 92 94 96 98 9A 9C 9E is $90 puts("NEG") + ^codeptr = $A9; codeptr++ // LDA #imm + ^codeptr = $00; codeptr++ // $00 + ^codeptr = $38; codeptr++ // SEC + ^codeptr = $F5; codeptr++ // SBC zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $A9; codeptr++ // LDA #imm + ^codeptr = $00; codeptr++ // $00 + ^codeptr = $F5; codeptr++ // SBC zp,X + ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0; codeptr++ // ESTKH break is $92 puts("COMP") + ^codeptr = $A9; codeptr++ // LDA #imm + ^codeptr = $FF; codeptr++ // $FF + ^codeptr = $55; codeptr++ // EOR zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $A9; codeptr++ // LDA #imm + ^codeptr = $FF; codeptr++ // $FF + ^codeptr = $55; codeptr++ // EOR zp,X + ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0; codeptr++ // ESTKH break is $94 puts("AND") + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $35; codeptr++ // AND zp,X + ^codeptr = $D0+1; codeptr++ // ESTKL+1 + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+1; codeptr++ // ESTKL+1 + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $35; codeptr++ // AND zp,X + ^codeptr = $C0+1; codeptr++ // ESTKH+1 + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0+1; codeptr++ // ESTKH+1 + ^codeptr = $E8; codeptr++ // INX break is $96 puts("OR") + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $15; codeptr++ // ORA zp,X + ^codeptr = $D0+1; codeptr++ // ESTKL+1 + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+1; codeptr++ // ESTKL+1 + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $15; codeptr++ // ORA zp,X + ^codeptr = $C0+1; codeptr++ // ESTKH+1 + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0+1; codeptr++ // ESTKH+1 + ^codeptr = $E8; codeptr++ // INX break is $98 puts("XOR") + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $55; codeptr++ // EOR zp,X + ^codeptr = $D0+1; codeptr++ // ESTKL+1 + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+1; codeptr++ // ESTKL+1 + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $55; codeptr++ // EOR zp,X + ^codeptr = $C0+1; codeptr++ // ESTKH+1 + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0+1; codeptr++ // ESTKH+1 + ^codeptr = $E8; codeptr++ // INX break is $9A puts("SHL") + // + // Call into VM + // + ^codeptr = $20; codeptr++ // JSR INTERP + *codeptr = $3D0; codeptr = codeptr + 2 + ^codeptr = $9A; codeptr++ // MOD CODE + ^codeptr = $C0; codeptr++ // NATV CODE break is $9C puts("SHR") + // + // Call into VM + // + ^codeptr = $20; codeptr++ // JSR INTERP + *codeptr = $3D0; codeptr = codeptr + 2 + ^codeptr = $9C; codeptr++ // MOD CODE + ^codeptr = $C0; codeptr++ // NATV CODE break is $9E puts("IDXW") + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $0A; codeptr++ // ASL + ^codeptr = $36; codeptr++ // ROL zp,X + ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $18; codeptr++ // CLC + ^codeptr = $75; codeptr++ // ADC zp,X + ^codeptr = $D0+1; codeptr++ // ESTKL+1 + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+1; codeptr++ // ESTKL+1 + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $75; codeptr++ // ADC zp,X + ^codeptr = $C0+1; codeptr++ // ESTKH+1 + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0+1; codeptr++ // ESTKH+1 + ^codeptr = $E8; codeptr++ // INX break // BRGT,BRLT,INCBRLE,ADDBRLE,DECBRGE,SUBBRGE,BRAND,BROR ; A0 A2 A4 A6 A8 AA AC AE is $A0 i++ - puts("BRGT "); puti(i + *(bytecode+i)) + dest = i + *(bytecode+i) + puts("BRGT "); puti(dest) i++ + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+1; codeptr++ // ESTKL+1 + ^codeptr = $D5; codeptr++ // CMP zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $C0+1; codeptr++ // ESTKH+1 + ^codeptr = $F5; codeptr++ // SBC zp,X + ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $50; codeptr++ // BVC rel + ^codeptr = $02; codeptr++ // +2 + ^codeptr = $49; codeptr++ // EOR #imm + ^codeptr = $80; codeptr++ // $80 + ^codeptr = $10; codeptr++ // BPL rel + ^codeptr = $05; codeptr++ // +5 + ^codeptr = $E8; codeptr++ // INX + ^codeptr = $E8; codeptr++ // INX + ^codeptr = $4C; codeptr++ // JMP abs + *codeptr = addrxlate=>[dest] + if not (*codeptr & $8000) // Unresolved address list + addrxlate=>[dest] = codeptr - *jitcodeptr + fin + codeptr = codeptr + 2 break is $A2 i++ - puts("BRLT "); puti(i + *(bytecode+i)) + dest = i + *(bytecode+i) + puts("BRLT "); puti(dest) i++ + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $D5; codeptr++ // CMP zp,X + ^codeptr = $D0+1; codeptr++ // ESTKL+1 + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $F5; codeptr++ // SBC zp,X + ^codeptr = $C0+1; codeptr++ // ESTKH+1 + ^codeptr = $50; codeptr++ // BVC rel + ^codeptr = $02; codeptr++ // +2 + ^codeptr = $49; codeptr++ // EOR #imm + ^codeptr = $80; codeptr++ // $80 + ^codeptr = $10; codeptr++ // BPL rel + ^codeptr = $05; codeptr++ // +5 + ^codeptr = $E8; codeptr++ // INX + ^codeptr = $E8; codeptr++ // INX + ^codeptr = $4C; codeptr++ // JMP abs + *codeptr = addrxlate=>[dest] + if not (*codeptr & $8000) // Unresolved address list + addrxlate=>[dest] = codeptr - *jitcodeptr + fin + codeptr = codeptr + 2 break is $A4 i++ - puts("INCBRLE "); puti(i + *(bytecode+i)) + dest = i + *(bytecode+i) + puts("INCBRLE "); puti(dest) i++ + // + // INCR + // + ^codeptr = $F6; codeptr++ // INC zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $D0; codeptr++ // BNE rel + ^codeptr = $02; codeptr++ // +2 + ^codeptr = $F6; codeptr++ // INC zp,X + ^codeptr = $C0; codeptr++ // ESTKH + // + // BRLE + // + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+1; codeptr++ // ESTKL+1 + ^codeptr = $D5; codeptr++ // CMP zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $C0+1; codeptr++ // ESTKH+1 + ^codeptr = $F5; codeptr++ // SBC zp,X + ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $50; codeptr++ // BVC rel + ^codeptr = $02; codeptr++ // +2 + ^codeptr = $49; codeptr++ // EOR #imm + ^codeptr = $80; codeptr++ // $80 + ^codeptr = $30; codeptr++ // BMI rel + ^codeptr = $03; codeptr++ // +3 + ^codeptr = $4C; codeptr++ // JMP abs + ^codeptr = $E8; codeptr++ // INX + ^codeptr = $E8; codeptr++ // INX + *codeptr = addrxlate=>[dest] + if not (*codeptr & $8000) // Unresolved address list + addrxlate=>[dest] = codeptr - *jitcodeptr + fin + codeptr = codeptr + 2 break is $A6 i++ - puts("ADDBRLE "); puti(i + *(bytecode+i)) + dest = i + *(bytecode+i) + puts("ADDBRLE "); puti(dest) i++ + // + // ADD + // + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $18; codeptr++ // CLC + ^codeptr = $75; codeptr++ // ADC zp,X + ^codeptr = $D0+1; codeptr++ // ESTKL+1 + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+1; codeptr++ // ESTKL+1 + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $75; codeptr++ // ADC zp,X + ^codeptr = $C0+1; codeptr++ // ESTKH+1 + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0+1; codeptr++ // ESTKH+1 + ^codeptr = $E8; codeptr++ // INX + // + // BRLE + // + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+1; codeptr++ // ESTKL+1 + ^codeptr = $D5; codeptr++ // CMP zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $C0+1; codeptr++ // ESTKH+1 + ^codeptr = $F5; codeptr++ // SBC zp,X + ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $50; codeptr++ // BVC rel + ^codeptr = $02; codeptr++ // +2 + ^codeptr = $49; codeptr++ // EOR #imm + ^codeptr = $80; codeptr++ // $80 + ^codeptr = $30; codeptr++ // BMI rel + ^codeptr = $03; codeptr++ // +3 + ^codeptr = $4C; codeptr++ // JMP abs + ^codeptr = $E8; codeptr++ // INX + ^codeptr = $E8; codeptr++ // INX + *codeptr = addrxlate=>[dest] + if not (*codeptr & $8000) // Unresolved address list + addrxlate=>[dest] = codeptr - *jitcodeptr + fin + codeptr = codeptr + 2 break is $A8 i++ - puts("DECBRGE "); puti(i + *(bytecode+i)) + dest = i + *(bytecode+i) + puts("DECBRGE "); puti(dest) i++ + // + // DECR + // + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $D0; codeptr++ // BNE rel + ^codeptr = $02; codeptr++ // +2 + ^codeptr = $D6; codeptr++ // DEC zp,X + ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $D6; codeptr++ // DEC zp,X + ^codeptr = $D0; codeptr++ // ESTKL + // + // BRGE + // + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $D5; codeptr++ // CMP zp,X + ^codeptr = $D0+1; codeptr++ // ESTKL+1 + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $F5; codeptr++ // SBC zp,X + ^codeptr = $C0+1; codeptr++ // ESTKH+1 + ^codeptr = $50; codeptr++ // BVC rel + ^codeptr = $02; codeptr++ // +2 + ^codeptr = $49; codeptr++ // EOR #imm + ^codeptr = $80; codeptr++ // $80 + ^codeptr = $30; codeptr++ // BMI rel + ^codeptr = $03; codeptr++ // +3 + ^codeptr = $4C; codeptr++ // JMP abs + ^codeptr = $E8; codeptr++ // INX + ^codeptr = $E8; codeptr++ // INX + *codeptr = addrxlate=>[dest] + if not (*codeptr & $8000) // Unresolved address list + addrxlate=>[dest] = codeptr - *jitcodeptr + fin + codeptr = codeptr + 2 break is $AA i++ - puts("SUBBRGE "); puti(i + *(bytecode+i)) + dest = i + *(bytecode+i) + puts("SUBBRGE "); puti(dest) i++ + // + // SUB + // + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+1; codeptr++ // ESTKL+1 + ^codeptr = $38; codeptr++ // SEC + ^codeptr = $F5; codeptr++ // SBC zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+1; codeptr++ // ESTKL+1 + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $C0+1; codeptr++ // ESTKH+1 + ^codeptr = $F5; codeptr++ // SBC zp,X + ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0+1; codeptr++ // ESTKH+1 + ^codeptr = $E8; codeptr++ // INX + // + // BRGE + // + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $D5; codeptr++ // CMP zp,X + ^codeptr = $D0+1; codeptr++ // ESTKL+1 + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $F5; codeptr++ // SBC zp,X + ^codeptr = $C0+1; codeptr++ // ESTKH+1 + ^codeptr = $50; codeptr++ // BVC rel + ^codeptr = $02; codeptr++ // +2 + ^codeptr = $49; codeptr++ // EOR #imm + ^codeptr = $80; codeptr++ // $80 + ^codeptr = $30; codeptr++ // BMI rel + ^codeptr = $03; codeptr++ // +3 + ^codeptr = $4C; codeptr++ // JMP abs + ^codeptr = $E8; codeptr++ // INX + ^codeptr = $E8; codeptr++ // INX + *codeptr = addrxlate=>[dest] + if not (*codeptr & $8000) // Unresolved address list + addrxlate=>[dest] = codeptr - *jitcodeptr + fin + codeptr = codeptr + 2 break is $AC i++ - puts("BRAND "); puti(i + *(bytecode+i)) + dest = i + *(bytecode+i) i++ + puts("BRAND "); puti(dest) + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $15; codeptr++ // ORA zp,X + ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $D0; codeptr++ // BNE rel + ^codeptr = $03; codeptr++ // +3 + ^codeptr = $4C; codeptr++ // JMP abs + *codeptr = addrxlate=>[dest] + if not (*codeptr & $8000) // Unresolved address list + addrxlate=>[dest] = codeptr - *jitcodeptr + fin + codeptr = codeptr + 2 + ^codeptr = $E8; codeptr++ // INX break is $AE i++ - puts("BROR "); puti(i + *(bytecode+i)) + dest = i + *(bytecode+i) i++ + puts("BROR "); puti(dest) + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $15; codeptr++ // ORA zp,X + ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $F0; codeptr++ // BEQ rel + ^codeptr = $03; codeptr++ // +3 + ^codeptr = $4C; codeptr++ // JMP abs + *codeptr = addrxlate=>[dest] + if not (*codeptr & $8000) // Unresolved address list + addrxlate=>[dest] = codeptr - *jitcodeptr + fin + codeptr = codeptr + 2 + ^codeptr = $E8; codeptr++ // INX break // ADDLB,ADDLW,ADDAB,ADDAW,IDXLB,IDXLW,IDXAB,IDXAW ; B0 B2 B4 B6 B8 BA BC BE is $B0 i++ puts("ADDLB "); puti(^(bytecode+i)) + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = ^(bytecode+i); codeptr++ + ^codeptr = $B1; codeptr++ // LDA (zp),Y + ^codeptr = $E0; codeptr++ // IFP + ^codeptr = $18; codeptr++ // CLC + ^codeptr = $75; codeptr++ // ADC zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $90; codeptr++ // BCC rel + ^codeptr = $02; codeptr++ // +2 + ^codeptr = $F6; codeptr++ // INC zp,X + ^codeptr = $C0; codeptr++ // ESTKH break is $B2 i++ puts("ADDLW "); puti(^(bytecode+i)) + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = ^(bytecode+i); codeptr++ + ^codeptr = $B1; codeptr++ // LDA (zp),Y + ^codeptr = $E0; codeptr++ // IFP + ^codeptr = $18; codeptr++ // CLC + ^codeptr = $75; codeptr++ // ADC zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $C8; codeptr++ // INY + ^codeptr = $B1; codeptr++ // LDA (zp),Y + ^codeptr = $E0; codeptr++ // IFP + ^codeptr = $75; codeptr++ // ADC zp,X + ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0; codeptr++ // ESTKH break is $B4 i++ puts("ADDAB $"); puth(*(bytecode+i)) + ^codeptr = $AD; codeptr++ // LDA abs + *codeptr = *(bytecode+i); codeptr = codeptr + 2 + ^codeptr = $18; codeptr++ // CLC + ^codeptr = $75; codeptr++ // ADC zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $90; codeptr++ // BCC rel + ^codeptr = $02; codeptr++ // +2 + ^codeptr = $F6; codeptr++ // INC zp,X + ^codeptr = $C0; codeptr++ // ESTKH i++ break is $B6 i++ puts("ADDAW $"); puth(*(bytecode+i)) + ^codeptr = $AD; codeptr++ // LDA abs + *codeptr = *(bytecode+i); codeptr = codeptr + 2 + ^codeptr = $18; codeptr++ // CLC + ^codeptr = $75; codeptr++ // ADC zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $AD; codeptr++ // LDA abs + *codeptr = *(bytecode+i)+1; codeptr = codeptr + 2 + ^codeptr = $75; codeptr++ // ADC zp,X + ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0; codeptr++ // ESTKH i++ break is $B8 i++ puts("IDXLB "); puti(^(bytecode+i)) + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = ^(bytecode+i); codeptr++ + ^codeptr = $B1; codeptr++ // LDA (zp),Y + ^codeptr = $E0; codeptr++ // IFP + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $00; codeptr++ // $00 + ^codeptr = $0A; codeptr++ // ASL + ^codeptr = $90; codeptr++ // BCC rel + ^codeptr = $02; codeptr++ // +2 + ^codeptr = $C8; codeptr++ // INY + ^codeptr = $18; codeptr++ // CLC + ^codeptr = $75; codeptr++ // ADC zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $98; codeptr++ // TYA + ^codeptr = $75; codeptr++ // ADC zp,X + ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0; codeptr++ // ESTKH break is $BA i++ puts("IDXLW "); puti(^(bytecode+i)) + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = ^(bytecode+i); codeptr++ + ^codeptr = $B1; codeptr++ // LDA (zp),Y + ^codeptr = $E0; codeptr++ // IFP + ^codeptr = $0A; codeptr++ // ASL + ^codeptr = $85; codeptr++ // STA zp + ^codeptr = $E7; codeptr++ // $E7:TMPL + ^codeptr = $C8; codeptr++ // INY + ^codeptr = $B1; codeptr++ // LDA (zp),Y + ^codeptr = $E0; codeptr++ // IFP + ^codeptr = $2A; codeptr++ // ROL + ^codeptr = $A8; codeptr++ // TAY + ^codeptr = $A5; codeptr++ // LDA zp + ^codeptr = $E7; codeptr++ // $E7:TMPL + ^codeptr = $18; codeptr++ // CLC + ^codeptr = $75; codeptr++ // ADC zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $98; codeptr++ // TYA + ^codeptr = $75; codeptr++ // ADC zp,X + ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0; codeptr++ // ESTKH break is $BC i++ puts("IDXAB $"); puth(*(bytecode+i)) + ^codeptr = $AD; codeptr++ // LDA abs + *codeptr = *(bytecode+i); codeptr = codeptr + 2 + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $00; codeptr++ // $00 + ^codeptr = $0A; codeptr++ // ASL + ^codeptr = $90; codeptr++ // BCC rel + ^codeptr = $02; codeptr++ // +2 + ^codeptr = $C8; codeptr++ // INY + ^codeptr = $18; codeptr++ // CLC + ^codeptr = $75; codeptr++ // ADC zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $98; codeptr++ // TYA + ^codeptr = $75; codeptr++ // ADC zp,X + ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0; codeptr++ // ESTKH i++ break is $BE i++ puts("IDXAW $"); puth(*(bytecode+i)) + ^codeptr = $AD; codeptr++ // LDA abs + *codeptr = *(bytecode+i); codeptr = codeptr + 2 + ^codeptr = $0A; codeptr++ // ASL + ^codeptr = $85; codeptr++ // STA zp + ^codeptr = $E7; codeptr++ // $E7:TMPL + ^codeptr = $AD; codeptr++ // LDA abs + *codeptr = *(bytecode+i)+1; codeptr = codeptr + 2 + ^codeptr = $2A; codeptr++ // ROL + ^codeptr = $A8; codeptr++ // TAY + ^codeptr = $A5; codeptr++ // LDA zp + ^codeptr = $E7; codeptr++ // $E7:TMPL + ^codeptr = $18; codeptr++ // CLC + ^codeptr = $75; codeptr++ // ADC zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $98; codeptr++ // TYA + ^codeptr = $75; codeptr++ // ADC zp,X + ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0; codeptr++ // ESTKH i++ break is $FF // NOPed out earlier by SELect diff --git a/src/vmsrc/apple/plvm02.s b/src/vmsrc/apple/plvm02.s index 2fd6d3a..758ff06 100755 --- a/src/vmsrc/apple/plvm02.s +++ b/src/vmsrc/apple/plvm02.s @@ -1116,7 +1116,6 @@ IDXLW INY ;+INC_IP LDA (IP),Y STY IPY TAY - STA TMPL LDA (IFP),Y ASL STA TMPL diff --git a/src/vmsrc/apple/plvm03.s b/src/vmsrc/apple/plvm03.s index 3a3abc4..6f92cb1 100755 --- a/src/vmsrc/apple/plvm03.s +++ b/src/vmsrc/apple/plvm03.s @@ -743,7 +743,6 @@ IDXLW INY ;+INC_IP LDA (IP),Y STY IPY TAY - STA TMPL LDA (IFP),Y ASL STA TMPL diff --git a/src/vmsrc/apple/plvmjit02.s b/src/vmsrc/apple/plvmjit02.s index 41f0457..56b5899 100755 --- a/src/vmsrc/apple/plvmjit02.s +++ b/src/vmsrc/apple/plvmjit02.s @@ -223,7 +223,7 @@ OPTBL !WORD CN,CN,CN,CN,CN,CN,CN,CN ; 00 02 !WORD NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 90 92 94 96 98 9A 9C 9E !WORD BRGT,BRLT,INCBRLE,ADDBRLE,DECBRGE,SUBBRGE,BRAND,BROR ; A0 A2 A4 A6 A8 AA AC AE !WORD ADDLB,ADDLW,ADDAB,ADDAW,IDXLB,IDXLW,IDXAB,IDXAW ; B0 B2 B4 B6 B8 BA BC BE - !WORD NATIVE ; C0 + !WORD NATV ; C0 ;* ;* DIRECTLY ENTER INTO BYTECODE INTERPRETER ;* @@ -424,7 +424,7 @@ OPXTBL !WORD CN,CN,CN,CN,CN,CN,CN,CN ; 00 02 !WORD NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 90 92 94 96 98 9A 9C 9E !WORD BRGT,BRLT,INCBRLE,ADDBRLE,DECBRGE,SUBBRGE,BRAND,BROR ; A0 A2 A4 A6 A8 AA AC AE !WORD ADDLBX,ADDLWX,ADDABX,ADDAWX,IDXLBX,IDXLWX,IDXABX,IDXAWX ; B0 B2 B4 B6 B8 BA BC BE - !WORD NATIVE ; C0 + !WORD NATV ; C0 ;* ;* JIT PROFILING ENTRY INTO INTERPRETER ;* @@ -1178,7 +1178,6 @@ IDXLW INY ;+INC_IP LDA (IP),Y STY IPY TAY - STA TMPL LDA (IFP),Y ASL STA TMPL @@ -2024,7 +2023,7 @@ RET RTS ;* ;* RETURN TO NATIVE CODE ;* -NATIVE TYA ; FLATTEN IP +NATV TYA ; FLATTEN IP SEC ADC IPL STA TMPL From fa71ec3948f6b862ab68e8a015e942a78c2f0dd0 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Wed, 21 Mar 2018 14:01:17 -0700 Subject: [PATCH 075/147] Fix ENTER/LEAVE --- src/libsrc/apple/jit.pla | 47 +++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/src/libsrc/apple/jit.pla b/src/libsrc/apple/jit.pla index 2eab9c3..5d1593c 100644 --- a/src/libsrc/apple/jit.pla +++ b/src/libsrc/apple/jit.pla @@ -54,6 +54,8 @@ def compiler(defptr)#0 *$003E = *$003C + defptr->bytecodesize *$0042 = bytecode call($C311, 0, 0, 0, $00) // CALL XMOVE with carry clear (AUX->MAIN) + puts("Addr Xlate: $"); puth(addrxlate); putln + puts("Bytecode: $"); puth(bytecode); putln // // Compile the bytecodes // @@ -72,12 +74,12 @@ def compiler(defptr)#0 case = *dest *dest = codeptr dest = case + *jitcodeptr - until not dest + until not case fin addrxlate=>[i] = codeptr putc('$'); puth(codeptr); putc(':') putc('['); puti(i); puts("] ") - if bytecode->[i] < $20 + if ^(bytecode+i) < $20 // CN,CN,CN,CN,CN,CN,CN,CN ; 00 02 04 06 08 0A 0C 0E // CN,CN,CN,CN,CN,CN,CN,CN ; 10 12 14 16 18 1A 1C 1E puts("CN $"); putb(^(bytecode+i)/2) @@ -91,7 +93,7 @@ def compiler(defptr)#0 ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $C0; codeptr++ // ESTKH else - when bytecode->[i] + when ^(bytecode+i) // MINUS1,BREQ,BRNE,LA,LLA,CB,CW,CS ; 20 22 24 26 28 2A 2C 2E is $20 puts("MINUS_ONE") @@ -216,9 +218,9 @@ def compiler(defptr)#0 break is $2E i++ - j = ^(bytecode+i) - puts("CS "); puts(bytecode+i) - i++ + j = ^(bytecode+i) + dest = i + j + 1 + puts("CS "); puts(bytecode+i); puts("-->"); puti(dest) if isule(codeptr + 12 + j, codemax) ^codeptr = $CA; codeptr++ // DEX ^codeptr = $A9; codeptr++ // LDA #imm @@ -230,17 +232,14 @@ def compiler(defptr)#0 ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $C0; codeptr++ // ESTKH ^codeptr = $4C; codeptr++ // JMP abs - *codeptr = addrxlate=>[i+j] + *codeptr = addrxlate=>[dest] if not (*codeptr & $8000) // Unresolved address list - addrxlate=>[i+j] = codeptr - *jitcodeptr + addrxlate=>[dest] = codeptr - *jitcodeptr fin codeptr = codeptr + 2 - ^codeptr = j; codeptr++ - while j - ^(bytecode+i); codeptr++ - i++ - j-- - loop + strcpy(codeptr, bytecode+i) + codeptr = codeptr + j + 1 + i = i + j else codeptr = codeptr + 12 + j // Flag buffer overflow fin @@ -606,14 +605,16 @@ def compiler(defptr)#0 break is $58 i++ - puts("ENTER "); puti(^(bytecode+i)) + puts("ENTER "); puti(^(bytecode+i)); putc(',');puti(^(bytecode+i+1)) // // Call into VM // ^codeptr = $20; codeptr++ // JSR INTERP *codeptr = $3D0; codeptr = codeptr + 2 ^codeptr = $58; codeptr++ // ENTER CODE - ^codeptr = i; codeptr++ // ENTER OPERAND + ^codeptr = ^(bytecode+i); codeptr++ // ENTER FRAME SIZE + i++ + ^codeptr = ^(bytecode+i); codeptr++ // ENTER ARG COUNT ^codeptr = $C0; codeptr++ // NATV CODE break is $5A @@ -624,8 +625,8 @@ def compiler(defptr)#0 // ^codeptr = $20; codeptr++ // JSR INTERP *codeptr = $3D0; codeptr = codeptr + 2 - ^codeptr = $58; codeptr++ // LEAVE CODE - ^codeptr = i; codeptr++ // LEAVE OPERAND + ^codeptr = $5A; codeptr++ // LEAVE CODE + ^codeptr = ^(bytecode+i); codeptr++ // LEAVE OPERAND break is $5C puts("RET") @@ -1557,10 +1558,7 @@ def compiler(defptr)#0 i++ if i >= defptr->bytecodesize // - // Done compiling - // - // - // Update DEF entry with JMP to compiled code + // Done compiling. Update DEF entry with JMP to compiled code // defptr->interpjsr = $4C // JMP defptr=>interpaddr = *jitcodeptr @@ -1569,8 +1567,11 @@ def compiler(defptr)#0 // Free working bufffers // heaprelease(addrxlate) + puts("Done compiling\n") + getc return fin + getc loop // // If we got here. we ran out of code buffer space. Overwrite interpreter @@ -1581,6 +1582,8 @@ def compiler(defptr)#0 // Free working bufffers // heaprelease(addrxlate) + puts("Ran out of code buffer\n") + getc end // // Install JIT compiler From cb7f86a9113df5b4527a2d9785b8f180678850e2 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Wed, 21 Mar 2018 16:23:32 -0700 Subject: [PATCH 076/147] Order DFD by address --- src/libsrc/apple/jit.pla | 66 +++++++++++++++++++------------------- src/toolsrc/codegen.c | 11 ++++++- src/toolsrc/codegen.pla | 34 ++++++++++++++------ src/toolsrc/parse.c | 25 ++++++++------- src/toolsrc/parse.pla | 9 +++--- src/toolsrc/plasm.pla | 4 ++- src/vmsrc/apple/cmdjit.pla | 2 +- 7 files changed, 89 insertions(+), 62 deletions(-) diff --git a/src/libsrc/apple/jit.pla b/src/libsrc/apple/jit.pla index 5d1593c..a918733 100644 --- a/src/libsrc/apple/jit.pla +++ b/src/libsrc/apple/jit.pla @@ -344,11 +344,11 @@ def compiler(defptr)#0 ^codeptr = $D0; codeptr++ // BNE rel ^codeptr = $01; codeptr++ // +1 ^codeptr = $88; codeptr++ // DEY + ^codeptr = $94; codeptr++ // STY zp,X + ^codeptr = $D0+1; codeptr++ // ESTKL+1 + ^codeptr = $94; codeptr++ // STY zp,X + ^codeptr = $C0+1; codeptr++ // ESTKH+1 ^codeptr = $E8; codeptr++ // INX - ^codeptr = $94; codeptr++ // STY zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $94; codeptr++ // STY zp,X - ^codeptr = $C0; codeptr++ // ESTKH break is $42 puts("ISNE") @@ -367,11 +367,11 @@ def compiler(defptr)#0 ^codeptr = $D0; codeptr++ // BNE rel ^codeptr = $01; codeptr++ // +1 ^codeptr = $C8; codeptr++ // INY + ^codeptr = $94; codeptr++ // STY zp,X + ^codeptr = $D0+1; codeptr++ // ESTKL+1 + ^codeptr = $94; codeptr++ // STY zp,X + ^codeptr = $C0+1; codeptr++ // ESTKH+1 ^codeptr = $E8; codeptr++ // INX - ^codeptr = $94; codeptr++ // STY zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $94; codeptr++ // STY zp,X - ^codeptr = $C0; codeptr++ // ESTKH break is $44 puts("ISGT") @@ -392,11 +392,11 @@ def compiler(defptr)#0 ^codeptr = $30; codeptr++ // BMI rel ^codeptr = $01; codeptr++ // +1 ^codeptr = $C8; codeptr++ // INY + ^codeptr = $94; codeptr++ // STY zp,X + ^codeptr = $D0+1; codeptr++ // ESTKL+1 + ^codeptr = $94; codeptr++ // STY zp,X + ^codeptr = $C0+1; codeptr++ // ESTKH+1 ^codeptr = $E8; codeptr++ // INX - ^codeptr = $94; codeptr++ // STY zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $94; codeptr++ // STY zp,X - ^codeptr = $C0; codeptr++ // ESTKH break is $46 puts("ISLT") @@ -417,11 +417,11 @@ def compiler(defptr)#0 ^codeptr = $30; codeptr++ // BMI rel ^codeptr = $01; codeptr++ // +1 ^codeptr = $C8; codeptr++ // INY + ^codeptr = $94; codeptr++ // STY zp,X + ^codeptr = $D0+1; codeptr++ // ESTKL+1 + ^codeptr = $94; codeptr++ // STY zp,X + ^codeptr = $C0+1; codeptr++ // ESTKH+1 ^codeptr = $E8; codeptr++ // INX - ^codeptr = $94; codeptr++ // STY zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $94; codeptr++ // STY zp,X - ^codeptr = $C0; codeptr++ // ESTKH break is $48 puts("ISGE") @@ -442,11 +442,11 @@ def compiler(defptr)#0 ^codeptr = $10; codeptr++ // BPL rel ^codeptr = $01; codeptr++ // +1 ^codeptr = $C8; codeptr++ // INY + ^codeptr = $94; codeptr++ // STY zp,X + ^codeptr = $D0+1; codeptr++ // ESTKL+1 + ^codeptr = $94; codeptr++ // STY zp,X + ^codeptr = $C0+1; codeptr++ // ESTKH+1 ^codeptr = $E8; codeptr++ // INX - ^codeptr = $94; codeptr++ // STY zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $94; codeptr++ // STY zp,X - ^codeptr = $C0; codeptr++ // ESTKH break is $4A puts("ISLE") @@ -467,11 +467,11 @@ def compiler(defptr)#0 ^codeptr = $10; codeptr++ // BPL rel ^codeptr = $01; codeptr++ // +1 ^codeptr = $C8; codeptr++ // INY + ^codeptr = $94; codeptr++ // STY zp,X + ^codeptr = $D0+1; codeptr++ // ESTKL+1 + ^codeptr = $94; codeptr++ // STY zp,X + ^codeptr = $C0+1; codeptr++ // ESTKH+1 ^codeptr = $E8; codeptr++ // INX - ^codeptr = $94; codeptr++ // STY zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $94; codeptr++ // STY zp,X - ^codeptr = $C0; codeptr++ // ESTKH break is $4C i++ @@ -527,11 +527,12 @@ def compiler(defptr)#0 is $52 i++ case = i + *(bytecode+i) - puts("SEL "); puti(case) - j = ^case + i++ + puts("SEL "); puti(case); putln + j = ^(bytecode+case) dest = codeptr + 8 + case * 11) if isule(dest, codemax) - ^case = $FF // Flag as NOP + ^(bytecode+case) = $FF // Flag as NOP case++ ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0; codeptr++ // ESTKL @@ -539,7 +540,7 @@ def compiler(defptr)#0 ^codeptr = $C0; codeptr++ // ESTKH ^codeptr = $E8; codeptr++ // INX repeat - puts(" $"); puth(*case) + puts(" $"); puth(*(bytecode+case)) ^codeptr = $C9; codeptr++ // CMP #imm ^codeptr = ^(bytecode+case); codeptr++ ^codeptr = $D0; codeptr++ // BNE rel @@ -548,16 +549,16 @@ def compiler(defptr)#0 ^codeptr = ^(bytecode+case+1); codeptr++ ^codeptr = $D0; codeptr++ // BNE rel ^codeptr = $03; codeptr++ // +3 - *case = $FFFF + *(bytecode+case) = $FFFF case = case + 2 - puts("-->"); puti(case + *case) + puts("-->"); puti(case + *(bytecode+case)); putln ^codeptr = $4C; codeptr++ // JMP abs *codeptr = addrxlate=>[case] if not (*codeptr & $8000) // Unresolved address list addrxlate=>[case] = codeptr - *jitcodeptr fin - codeptr = codeptr + 2 - *case = $FFFF + codeptr = codeptr + 2 + *(bytecode+case) = $FFFF case = case + 2 j-- until not j @@ -567,7 +568,6 @@ def compiler(defptr)#0 addrxlate=>[case] = codeptr - *jitcodeptr fin codeptr = codeptr + 2 - i++ else codeptr = dest fin diff --git a/src/toolsrc/codegen.c b/src/toolsrc/codegen.c index 9e2f6a5..9f5efba 100755 --- a/src/toolsrc/codegen.c +++ b/src/toolsrc/codegen.c @@ -382,12 +382,13 @@ void emit_header(void) } void emit_rld(void) { - int i; + int i, j; printf(";\n; RE-LOCATEABLE DICTIONARY\n;\n"); /* * First emit the bytecode definition entrypoint information. */ + /* for (i = 0; i < globals; i++) if (!(idglobal_type[i] & EXTERN_TYPE) && (idglobal_type[i] & DEF_TYPE)) { @@ -395,6 +396,14 @@ void emit_rld(void) printf("\t%s\t_C%03d\t\t\n", DW, idglobal_tag[i]); printf("\t%s\t$00\n", DB); } + */ + j = outflags & INIT ? defs - 1 : defs; + for (i = 0; i < j; i++) + { + printf("\t%s\t$02\t\t\t; CODE TABLE FIXUP\n", DB); + printf("\t%s\t_C%03d\t\t\n", DW, i); + printf("\t%s\t$00\n", DB); + } /* * Now emit the fixup table. */ diff --git a/src/toolsrc/codegen.pla b/src/toolsrc/codegen.pla index f77ba3b..adceeea 100644 --- a/src/toolsrc/codegen.pla +++ b/src/toolsrc/codegen.pla @@ -529,11 +529,13 @@ def init_idglobal#0 word op word i + dfd_num = DFDNUM tag_num = TAGNUM fixup_num = FIXUPNUM globalbufsz = IDGLOBALSZ localbufsz = IDLOCALSZ - if isult(heapavail, $8000) + if isult(heapavail, $4000) + dfd_num = DFDNUM/2 tag_num = TAGNUM/2 fixup_num = FIXUPNUM/2 globalbufsz = IDGLOBALSZ @@ -552,6 +554,7 @@ def init_idglobal#0 // // Allocate remaining buffers // + dfd_tag = heapalloc(dfd_num*2) tag_addr = heapalloc(tag_num*2) tag_type = heapalloc(tag_num) fixup_tag = heapalloc(fixup_num*2) @@ -604,6 +607,14 @@ def new_moddep(nameptr, len)#0 if moddep_cnt > MODDEPNUM; parse_warn("Module dependency overflow"); fin end // +// DFD list +// +def new_dfd(tag)#0 + if dfd_cnt >= dfd_num; exit_err(ERR_OVER|ERR_CODE|ERR_TABLE); fin + dfd_tag=>[dfd_cnt] = tag + dfd_cnt++ +end +// // Generate/add to a sequence of code // def gen_op(seq, code) @@ -870,20 +881,23 @@ end // Write DeFinition Directory // def writeDFD(refnum, modfix)#0 - word dfd, idptr, idcnt + word dfd, idptr, cnt byte defdir[128] - dfd, idptr, idcnt = @defdir, idglobal_tbl, globals - while idcnt - if idptr=>idtype & (FUNC_TYPE|EXTERN_TYPE) == FUNC_TYPE + dfd = @defdir + for cnt = 0 to dfd_cnt-1 + //dfd, idptr, cnt = @defdir, idglobal_tbl, globals + //while cnt + //if idptr=>idtype & (FUNC_TYPE|EXTERN_TYPE) == FUNC_TYPE dfd->0 = $02 - dfd=>1 = tag_addr=>[idptr=>idval] + modfix + dfd=>1 = tag_addr=>[dfd_tag=>[cnt]] + modfix dfd->3 = 0 dfd = dfd + 4 - fin - idptr = idptr + idptr->idname + t_id - idcnt-- - loop + //fin + //idptr = idptr + idptr->idname + t_id + //cnt-- + //loop + next fileio:write(refnum, @defdir, dfd - @defdir) end // diff --git a/src/toolsrc/parse.c b/src/toolsrc/parse.c index 43d20c1..d43ba50 100755 --- a/src/toolsrc/parse.c +++ b/src/toolsrc/parse.c @@ -1624,8 +1624,9 @@ int parse_defs(void) emit_const(0); emit_leave(); } - while (lambda_cnt--) - emit_lambdafunc(lambda_tag[lambda_cnt], lambda_id[lambda_cnt], lambda_cparams[lambda_cnt], lambda_seq[lambda_cnt]); + for (cfnvals = 0; cfnvals < lambda_cnt; cfnvals++) + emit_lambdafunc(lambda_tag[cfnvals], lambda_id[cfnvals], lambda_cparams[cfnvals], lambda_seq[cfnvals]); + lambda_cnt = 0; return (1); } else if (scantoken == ASM_TOKEN) @@ -1705,21 +1706,21 @@ int parse_module(void) while (parse_mods()) next_line(); while (parse_vars(GLOBAL_TYPE)) next_line(); while (parse_defs()) next_line(); + emit_bytecode_seg(); + emit_start(); + idlocal_reset(); + emit_idfunc(0, 0, NULL, 1); + prevstmnt = 0; if (scantoken != DONE_TOKEN && scantoken != EOF_TOKEN) { - emit_bytecode_seg(); - emit_start(); - idlocal_reset(); - emit_idfunc(0, 0, NULL, 1); - prevstmnt = 0; while (parse_stmnt()) next_line(); if (scantoken != DONE_TOKEN) parse_error("Missing DONE"); - if (prevstmnt != RETURN_TOKEN) - { - emit_const(0); - emit_ret(); - } + } + if (prevstmnt != RETURN_TOKEN) + { + emit_const(0); + emit_ret(); } } emit_trailer(); diff --git a/src/toolsrc/parse.pla b/src/toolsrc/parse.pla index 141d2b0..6080e97 100644 --- a/src/toolsrc/parse.pla +++ b/src/toolsrc/parse.pla @@ -1259,6 +1259,7 @@ def parse_defs new_idfunc(idstr, idlen, type, func_tag, cfnparms, infuncvals) fin emit_tag(func_tag) + new_dfd(func_tag) while parse_vars(LOCAL_TYPE); nextln; loop emit_enter(cfnparms) prevstmnt = 0 @@ -1273,10 +1274,10 @@ def parse_defs next emit_leave fin - while lambda_cnt - lambda_cnt-- - emit_lambdafunc(lambda_tag[lambda_cnt], lambda_cparms[lambda_cnt], lambda_seq[lambda_cnt]) - loop + for cfnvals = 0 to lambda_cnt-1 + emit_lambdafunc(lambda_tag[cfnvals], lambda_cparms[cfnvals], lambda_seq[cfnvals]) + new_dfd(lambda_tag[cfnvals]) + next fin return token == EOL_TKN ?? TRUE :: FALSE end diff --git a/src/toolsrc/plasm.pla b/src/toolsrc/plasm.pla index 381afaa..9320212 100644 --- a/src/toolsrc/plasm.pla +++ b/src/toolsrc/plasm.pla @@ -232,6 +232,7 @@ end // Generated code buffers // const OPSEQNUM = 256 +const DFDNUM = 128 const TAGNUM = 1024 const FIXUPNUM = 2048 const MODDEPNUM = 8 @@ -239,12 +240,13 @@ const IDGLOBALSZ = 4096 const IDLOCALSZ = 512 const CASENUM = 64 word fixup_cnt, tag_cnt = -1 +word dfd_tag, dfd_cnt word fixup_tag, fixup_addr word tag_addr, tag_type word idglobal_tbl, idlocal_tbl word pending_seq word globals, lastglobal, lastglobalsize, lastlocal, savelast -word tag_num, fixup_num, globalbufsz, localbufsz, codebufsz +word dfd_num, tag_num, fixup_num, globalbufsz, localbufsz, codebufsz word datasize, framesize, savesize byte locals, savelocals word codebuff, codeptr, entrypoint diff --git a/src/vmsrc/apple/cmdjit.pla b/src/vmsrc/apple/cmdjit.pla index 1b65fbd..0cd4799 100755 --- a/src/vmsrc/apple/cmdjit.pla +++ b/src/vmsrc/apple/cmdjit.pla @@ -39,7 +39,7 @@ end // // JIT compiler constants // -const jitcount = $10 +const jitcount = $01//$10 const jitcomp = $03E2 const jitcodeptr = $03E4 const jitcode = $BF00 From 71d17a99e4e1abe9df83806292edb283ab970ce2 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Wed, 21 Mar 2018 18:24:15 -0700 Subject: [PATCH 077/147] Fix immediate value loads --- src/libsrc/apple/jit.pla | 40 ++++++++++++++++++---------------------- 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/src/libsrc/apple/jit.pla b/src/libsrc/apple/jit.pla index a918733..c617908 100644 --- a/src/libsrc/apple/jit.pla +++ b/src/libsrc/apple/jit.pla @@ -353,7 +353,7 @@ def compiler(defptr)#0 is $42 puts("ISNE") ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = $00; codeptr++ // $FF + ^codeptr = $FF; codeptr++ // $FF ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+1; codeptr++ // ESTKL+1 ^codeptr = $D5; codeptr++ // CMP zp,X @@ -376,7 +376,7 @@ def compiler(defptr)#0 is $44 puts("ISGT") ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = $00; codeptr++ // $FF + ^codeptr = $FF; codeptr++ // $FF ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0; codeptr++ // ESTKL ^codeptr = $D5; codeptr++ // CMP zp,X @@ -401,7 +401,7 @@ def compiler(defptr)#0 is $46 puts("ISLT") ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = $00; codeptr++ // $FF + ^codeptr = $FF; codeptr++ // $FF ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+1; codeptr++ // ESTKL+1 ^codeptr = $D5; codeptr++ // CMP zp,X @@ -426,7 +426,7 @@ def compiler(defptr)#0 is $48 puts("ISGE") ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = $00; codeptr++ // $FF + ^codeptr = $FF; codeptr++ // $FF ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+1; codeptr++ // ESTKL+1 ^codeptr = $D5; codeptr++ // CMP zp,X @@ -451,7 +451,7 @@ def compiler(defptr)#0 is $4A puts("ISLE") ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = $00; codeptr++ // $FF + ^codeptr = $FF; codeptr++ // $FF ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0; codeptr++ // ESTKL ^codeptr = $D5; codeptr++ // CMP zp,X @@ -671,10 +671,6 @@ def compiler(defptr)#0 ^codeptr = $C0-1; codeptr++ // ESTKH-1 ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $A9; codeptr++ // LDA #imm - ^codeptr = $00; codeptr++ // $00 - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0; codeptr++ // ESTKH ^codeptr = $F6; codeptr++ // INC zp,X ^codeptr = $C0-1; codeptr++ // ESTKH-1 ^codeptr = $D0; codeptr++ // BNE rel @@ -697,7 +693,7 @@ def compiler(defptr)#0 ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0; codeptr++ // ESTKL ^codeptr = $A9; codeptr++ // LDA #imm - ^codeptr = $FF; codeptr++ // $00 + ^codeptr = $00; codeptr++ // $00 ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $C0; codeptr++ // ESTKH break @@ -726,7 +722,7 @@ def compiler(defptr)#0 ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0; codeptr++ // ESTKL ^codeptr = $A9; codeptr++ // LDA #imm - ^codeptr = $FF; codeptr++ // $00 + ^codeptr = $00; codeptr++ // $00 ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $C0; codeptr++ // ESTKH i++ @@ -1191,13 +1187,13 @@ def compiler(defptr)#0 ^codeptr = $30; codeptr++ // BMI rel ^codeptr = $03; codeptr++ // +3 ^codeptr = $4C; codeptr++ // JMP abs - ^codeptr = $E8; codeptr++ // INX - ^codeptr = $E8; codeptr++ // INX *codeptr = addrxlate=>[dest] if not (*codeptr & $8000) // Unresolved address list addrxlate=>[dest] = codeptr - *jitcodeptr fin codeptr = codeptr + 2 + ^codeptr = $E8; codeptr++ // INX + ^codeptr = $E8; codeptr++ // INX break is $A6 i++ @@ -1239,13 +1235,13 @@ def compiler(defptr)#0 ^codeptr = $30; codeptr++ // BMI rel ^codeptr = $03; codeptr++ // +3 ^codeptr = $4C; codeptr++ // JMP abs - ^codeptr = $E8; codeptr++ // INX - ^codeptr = $E8; codeptr++ // INX *codeptr = addrxlate=>[dest] if not (*codeptr & $8000) // Unresolved address list addrxlate=>[dest] = codeptr - *jitcodeptr fin codeptr = codeptr + 2 + ^codeptr = $E8; codeptr++ // INX + ^codeptr = $E8; codeptr++ // INX break is $A8 i++ @@ -1281,13 +1277,13 @@ def compiler(defptr)#0 ^codeptr = $30; codeptr++ // BMI rel ^codeptr = $03; codeptr++ // +3 ^codeptr = $4C; codeptr++ // JMP abs - ^codeptr = $E8; codeptr++ // INX - ^codeptr = $E8; codeptr++ // INX *codeptr = addrxlate=>[dest] if not (*codeptr & $8000) // Unresolved address list addrxlate=>[dest] = codeptr - *jitcodeptr fin codeptr = codeptr + 2 + ^codeptr = $E8; codeptr++ // INX + ^codeptr = $E8; codeptr++ // INX break is $AA i++ @@ -1329,13 +1325,13 @@ def compiler(defptr)#0 ^codeptr = $30; codeptr++ // BMI rel ^codeptr = $03; codeptr++ // +3 ^codeptr = $4C; codeptr++ // JMP abs - ^codeptr = $E8; codeptr++ // INX - ^codeptr = $E8; codeptr++ // INX *codeptr = addrxlate=>[dest] if not (*codeptr & $8000) // Unresolved address list addrxlate=>[dest] = codeptr - *jitcodeptr fin codeptr = codeptr + 2 + ^codeptr = $E8; codeptr++ // INX + ^codeptr = $E8; codeptr++ // INX break is $AC i++ @@ -1567,11 +1563,11 @@ def compiler(defptr)#0 // Free working bufffers // heaprelease(addrxlate) - puts("Done compiling\n") - getc + puts("Done compiling: $"); puth(defptr=>interpaddr); putln + //getc return fin - getc + //getc loop // // If we got here. we ran out of code buffer space. Overwrite interpreter From 8c18a28e494db878356a4927ff43c8f471af2dfc Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Wed, 21 Mar 2018 20:54:16 -0700 Subject: [PATCH 078/147] JIT WIP --- src/libsrc/apple/jit.pla | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/libsrc/apple/jit.pla b/src/libsrc/apple/jit.pla index c617908..134637e 100644 --- a/src/libsrc/apple/jit.pla +++ b/src/libsrc/apple/jit.pla @@ -54,6 +54,7 @@ def compiler(defptr)#0 *$003E = *$003C + defptr->bytecodesize *$0042 = bytecode call($C311, 0, 0, 0, $00) // CALL XMOVE with carry clear (AUX->MAIN) + ^$C053 // MIX TEXT puts("Addr Xlate: $"); puth(addrxlate); putln puts("Bytecode: $"); puth(bytecode); putln // @@ -77,8 +78,8 @@ def compiler(defptr)#0 until not case fin addrxlate=>[i] = codeptr - putc('$'); puth(codeptr); putc(':') - putc('['); puti(i); puts("] ") + //putc('$'); puth(codeptr); putc(':') + //putc('['); puti(i); puts("] ") if ^(bytecode+i) < $20 // CN,CN,CN,CN,CN,CN,CN,CN ; 00 02 04 06 08 0A 0C 0E // CN,CN,CN,CN,CN,CN,CN,CN ; 10 12 14 16 18 1A 1C 1E @@ -258,11 +259,11 @@ def compiler(defptr)#0 puts("DUP") ^codeptr = $CA; codeptr++ // DEX ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0-1; codeptr++ // ESTKL-1 + ^codeptr = $D0+1; codeptr++ // ESTKL+1 ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0; codeptr++ // ESTKL ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $C0-1; codeptr++ // ESTKH-1 + ^codeptr = $C0+1; codeptr++ // ESTKH+1 ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $C0; codeptr++ // ESTKH break @@ -1065,7 +1066,7 @@ def compiler(defptr)#0 // ^codeptr = $20; codeptr++ // JSR INTERP *codeptr = $3D0; codeptr = codeptr + 2 - ^codeptr = $9A; codeptr++ // MOD CODE + ^codeptr = $9A; codeptr++ // SHL CODE ^codeptr = $C0; codeptr++ // NATV CODE break is $9C @@ -1075,7 +1076,7 @@ def compiler(defptr)#0 // ^codeptr = $20; codeptr++ // JSR INTERP *codeptr = $3D0; codeptr = codeptr + 2 - ^codeptr = $9C; codeptr++ // MOD CODE + ^codeptr = $9C; codeptr++ // SHR CODE ^codeptr = $C0; codeptr++ // NATV CODE break is $9E @@ -1457,7 +1458,7 @@ def compiler(defptr)#0 ^codeptr = $02; codeptr++ // +2 ^codeptr = $C8; codeptr++ // INY ^codeptr = $18; codeptr++ // CLC - ^codeptr = $75; codeptr++ // ADC zp,X + ^codeptr = $75; codeptr++ // ADC zp,X ^codeptr = $D0; codeptr++ // ESTKL ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0; codeptr++ // ESTKL @@ -1564,10 +1565,10 @@ def compiler(defptr)#0 // heaprelease(addrxlate) puts("Done compiling: $"); puth(defptr=>interpaddr); putln - //getc + getc return fin - //getc + getc loop // // If we got here. we ran out of code buffer space. Overwrite interpreter From 81574a8a6271def1b92231160b53204b331371b0 Mon Sep 17 00:00:00 2001 From: Dave Schmenk Date: Wed, 21 Mar 2018 22:31:06 -0700 Subject: [PATCH 079/147] JIT tuning parameters --- src/libsrc/apple/jit.pla | 190 ++++++++++++++++++------------------ src/libsrc/apple/jitune.pla | 38 ++++++++ src/vmsrc/apple/cmdjit.pla | 29 +++--- src/vmsrc/apple/plvmjit02.s | 16 ++- 4 files changed, 164 insertions(+), 109 deletions(-) create mode 100644 src/libsrc/apple/jitune.pla diff --git a/src/libsrc/apple/jit.pla b/src/libsrc/apple/jit.pla index 134637e..5b0b02c 100644 --- a/src/libsrc/apple/jit.pla +++ b/src/libsrc/apple/jit.pla @@ -35,7 +35,7 @@ def compiler(defptr)#0 word codeptr, addrxlate, bytecode, i, case, dest byte j - puts("JIT compiler invoked!\n") + //puts("JIT compiler invoked!\n") addrxlate = heapalloc(512 + defptr->bytecodesize) // 256 * sizeof(word) address xlate if not addrxlate @@ -54,9 +54,9 @@ def compiler(defptr)#0 *$003E = *$003C + defptr->bytecodesize *$0042 = bytecode call($C311, 0, 0, 0, $00) // CALL XMOVE with carry clear (AUX->MAIN) - ^$C053 // MIX TEXT - puts("Addr Xlate: $"); puth(addrxlate); putln - puts("Bytecode: $"); puth(bytecode); putln + //^$C053 // MIX TEXT + ////puts("Addr Xlate: $"); puth(addrxlate); putln + ////puts("Bytecode: $"); puth(bytecode); putln // // Compile the bytecodes // @@ -79,11 +79,11 @@ def compiler(defptr)#0 fin addrxlate=>[i] = codeptr //putc('$'); puth(codeptr); putc(':') - //putc('['); puti(i); puts("] ") + //putc('['); puti(i); //puts("] ") if ^(bytecode+i) < $20 // CN,CN,CN,CN,CN,CN,CN,CN ; 00 02 04 06 08 0A 0C 0E // CN,CN,CN,CN,CN,CN,CN,CN ; 10 12 14 16 18 1A 1C 1E - puts("CN $"); putb(^(bytecode+i)/2) + //puts("CN $"); putb(^(bytecode+i)/2) ^codeptr = $CA; codeptr++ // DEX ^codeptr = $A9; codeptr++ // LDA #imm ^codeptr = ^(bytecode+i)/2; codeptr++ @@ -97,7 +97,7 @@ def compiler(defptr)#0 when ^(bytecode+i) // MINUS1,BREQ,BRNE,LA,LLA,CB,CW,CS ; 20 22 24 26 28 2A 2C 2E is $20 - puts("MINUS_ONE") + //puts("MINUS_ONE") ^codeptr = $CA; codeptr++ // DEX ^codeptr = $A9; codeptr++ // LDA #imm ^codeptr = $FF; codeptr++ // $FF @@ -110,7 +110,7 @@ def compiler(defptr)#0 i++ dest = i + *(bytecode+i) i++ - puts("BREQ "); puti(dest) + //puts("BREQ "); puti(dest) ^codeptr = $E8; codeptr++ // INX ^codeptr = $E8; codeptr++ // INX ^codeptr = $B5; codeptr++ // LDA zp,X @@ -136,7 +136,7 @@ def compiler(defptr)#0 i++ dest = i + *(bytecode+i) i++ - puts("BRNE "); puti(dest) + //puts("BRNE "); puti(dest) ^codeptr = $E8; codeptr++ // INX ^codeptr = $E8; codeptr++ // INX ^codeptr = $B5; codeptr++ // LDA zp,X @@ -160,7 +160,7 @@ def compiler(defptr)#0 break is $26 i++ - puts("LA $"); puth(*(bytecode+i)) + //puts("LA $"); puth(*(bytecode+i)) ^codeptr = $CA; codeptr++ // DEX ^codeptr = $A9; codeptr++ // LDA #imm ^codeptr = ^(bytecode+i); codeptr++ @@ -174,7 +174,7 @@ def compiler(defptr)#0 break is $28 i++ - puts("LLA "); puti(^(bytecode+i)) + //puts("LLA "); puti(^(bytecode+i)) ^codeptr = $CA; codeptr++ // DEX ^codeptr = $A9; codeptr++ // LDA #imm ^codeptr = ^(bytecode+i); codeptr++ @@ -192,7 +192,7 @@ def compiler(defptr)#0 break is $2A i++ - puts("CB $"); putb(^(bytecode+i)) + //puts("CB $"); putb(^(bytecode+i)) ^codeptr = $CA; codeptr++ // DEX ^codeptr = $A9; codeptr++ // LDA #imm ^codeptr = ^(bytecode+i); codeptr++ @@ -205,7 +205,7 @@ def compiler(defptr)#0 break is $2C i++ - puts("CW $"); puth(*(bytecode+i)) + //puts("CW $"); puth(*(bytecode+i)) ^codeptr = $CA; codeptr++ // DEX ^codeptr = $A9; codeptr++ // LDA #imm ^codeptr = ^(bytecode+i); codeptr++ @@ -221,7 +221,7 @@ def compiler(defptr)#0 i++ j = ^(bytecode+i) dest = i + j + 1 - puts("CS "); puts(bytecode+i); puts("-->"); puti(dest) + //puts("CS "); //puts(bytecode+i); //puts("-->"); puti(dest) if isule(codeptr + 12 + j, codemax) ^codeptr = $CA; codeptr++ // DEX ^codeptr = $A9; codeptr++ // LDA #imm @@ -247,16 +247,16 @@ def compiler(defptr)#0 break // DROP,DROP2,DUP,DIVMOD,ADDI,SUBI,ANDI,ORI ; 30 32 34 36 38 3A 3C 3E is $30 - puts("DROP") + //puts("DROP") ^codeptr = $E8; codeptr++ // INX break is $32 - puts("DROP2") + //puts("DROP2") ^codeptr = $E8; codeptr++ // INX ^codeptr = $E8; codeptr++ // INX break is $34 - puts("DUP") + //puts("DUP") ^codeptr = $CA; codeptr++ // DEX ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+1; codeptr++ // ESTKL+1 @@ -268,14 +268,14 @@ def compiler(defptr)#0 ^codeptr = $C0; codeptr++ // ESTKH break is $36 - puts("DIVMOD") + //puts("DIVMOD") // // Should never happen // break is $38 i++ - puts("ADDI $"); putb(^(bytecode+i)) + //puts("ADDI $"); putb(^(bytecode+i)) ^codeptr = $A9; codeptr++ // LDA #imm ^codeptr = ^(bytecode+i); codeptr++ ^codeptr = $18; codeptr++ // CLC @@ -290,7 +290,7 @@ def compiler(defptr)#0 break is $3A i++ - puts("SUBI $"); putb(^(bytecode+i)) + //puts("SUBI $"); putb(^(bytecode+i)) ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0; codeptr++ // ESTKL ^codeptr = $18; codeptr++ // SEC @@ -305,7 +305,7 @@ def compiler(defptr)#0 break is $3C i++ - puts("ANDI $"); putb(^(bytecode+i)) + //puts("ANDI $"); putb(^(bytecode+i)) ^codeptr = $A9; codeptr++ // LDA #imm ^codeptr = ^(bytecode+i); codeptr++ ^codeptr = $35; codeptr++ // AND zp,X @@ -319,7 +319,7 @@ def compiler(defptr)#0 break is $3E i++ - puts("ORI $"); putb(^(bytecode+i)) + //puts("ORI $"); putb(^(bytecode+i)) ^codeptr = $A9; codeptr++ // LDA #imm ^codeptr = ^(bytecode+i); codeptr++ ^codeptr = $15; codeptr++ // ORA zp,X @@ -329,7 +329,7 @@ def compiler(defptr)#0 break // ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E is $40 - puts("ISEQ") + //puts("ISEQ") ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = $00; codeptr++ // $00 ^codeptr = $B5; codeptr++ // LDA zp,X @@ -352,7 +352,7 @@ def compiler(defptr)#0 ^codeptr = $E8; codeptr++ // INX break is $42 - puts("ISNE") + //puts("ISNE") ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = $FF; codeptr++ // $FF ^codeptr = $B5; codeptr++ // LDA zp,X @@ -375,7 +375,7 @@ def compiler(defptr)#0 ^codeptr = $E8; codeptr++ // INX break is $44 - puts("ISGT") + //puts("ISGT") ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = $FF; codeptr++ // $FF ^codeptr = $B5; codeptr++ // LDA zp,X @@ -400,7 +400,7 @@ def compiler(defptr)#0 ^codeptr = $E8; codeptr++ // INX break is $46 - puts("ISLT") + //puts("ISLT") ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = $FF; codeptr++ // $FF ^codeptr = $B5; codeptr++ // LDA zp,X @@ -425,7 +425,7 @@ def compiler(defptr)#0 ^codeptr = $E8; codeptr++ // INX break is $48 - puts("ISGE") + //puts("ISGE") ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = $FF; codeptr++ // $FF ^codeptr = $B5; codeptr++ // LDA zp,X @@ -450,7 +450,7 @@ def compiler(defptr)#0 ^codeptr = $E8; codeptr++ // INX break is $4A - puts("ISLE") + //puts("ISLE") ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = $FF; codeptr++ // $FF ^codeptr = $B5; codeptr++ // LDA zp,X @@ -478,7 +478,7 @@ def compiler(defptr)#0 i++ dest = i + *(bytecode+i) i++ - puts("BRFLS "); puti(dest) + //puts("BRFLS "); puti(dest) ^codeptr = $E8; codeptr++ // INX ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0-1; codeptr++ // ESTKL-1 @@ -497,7 +497,7 @@ def compiler(defptr)#0 i++ dest = i + *(bytecode+i) i++ - puts("BRTRU "); puti(dest) + //puts("BRTRU "); puti(dest) ^codeptr = $E8; codeptr++ // INX ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0-1; codeptr++ // ESTKL-1 @@ -517,7 +517,7 @@ def compiler(defptr)#0 i++ dest = i + *(bytecode+i) i++ - puts("BRNCH "); puti(dest) + //puts("BRNCH "); puti(dest) ^codeptr = $4C; codeptr++ // JMP abs *codeptr = addrxlate=>[dest] if not (*codeptr & $8000) // Unresolved address list @@ -529,7 +529,7 @@ def compiler(defptr)#0 i++ case = i + *(bytecode+i) i++ - puts("SEL "); puti(case); putln + //puts("SEL "); puti(case); putln j = ^(bytecode+case) dest = codeptr + 8 + case * 11) if isule(dest, codemax) @@ -541,7 +541,7 @@ def compiler(defptr)#0 ^codeptr = $C0; codeptr++ // ESTKH ^codeptr = $E8; codeptr++ // INX repeat - puts(" $"); puth(*(bytecode+case)) + //puts(" $"); puth(*(bytecode+case)) ^codeptr = $C9; codeptr++ // CMP #imm ^codeptr = ^(bytecode+case); codeptr++ ^codeptr = $D0; codeptr++ // BNE rel @@ -552,7 +552,7 @@ def compiler(defptr)#0 ^codeptr = $03; codeptr++ // +3 *(bytecode+case) = $FFFF case = case + 2 - puts("-->"); puti(case + *(bytecode+case)); putln + //puts("-->"); puti(case + *(bytecode+case)); putln ^codeptr = $4C; codeptr++ // JMP abs *codeptr = addrxlate=>[case] if not (*codeptr & $8000) // Unresolved address list @@ -575,7 +575,7 @@ def compiler(defptr)#0 break is $54 i++ - puts("CALL $"); puth(*(bytecode+i)) + //puts("CALL $"); puth(*(bytecode+i)) // // Call address // @@ -584,7 +584,7 @@ def compiler(defptr)#0 i++ break is $56 - puts("ICAL") + //puts("ICAL") // // Pull address off stack // @@ -606,7 +606,7 @@ def compiler(defptr)#0 break is $58 i++ - puts("ENTER "); puti(^(bytecode+i)); putc(',');puti(^(bytecode+i+1)) + //puts("ENTER "); puti(^(bytecode+i)); putc(',');puti(^(bytecode+i+1)) // // Call into VM // @@ -620,7 +620,7 @@ def compiler(defptr)#0 break is $5A i++ - puts("LEAVE "); puti(^(bytecode+i)) + //puts("LEAVE "); puti(^(bytecode+i)) // // Call into VM // @@ -630,12 +630,12 @@ def compiler(defptr)#0 ^codeptr = ^(bytecode+i); codeptr++ // LEAVE OPERAND break is $5C - puts("RET") + //puts("RET") ^codeptr = $60; codeptr++ // RTS break is $5E i++ - puts("CFFB $FF"); putb(^(bytecode+i)) + //puts("CFFB $FF"); putb(^(bytecode+i)) ^codeptr = $CA; codeptr++ // DEX ^codeptr = $A9; codeptr++ // LDA #imm ^codeptr = ^(bytecode+i); codeptr++ @@ -648,7 +648,7 @@ def compiler(defptr)#0 break // LB,LW,LLB,LLW,LAB,LAW,DLB,DLW ; 60 62 64 66 68 6A 6C 6E is $60 - puts("LB") + //puts("LB") ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0; codeptr++ // ESTKL ^codeptr = $95; codeptr++ // STA zp,X @@ -663,7 +663,7 @@ def compiler(defptr)#0 ^codeptr = $C0; codeptr++ // ESTKH break is $62 - puts("LW") + //puts("LW") ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0; codeptr++ // ESTKL ^codeptr = $95; codeptr++ // STA zp,X @@ -685,7 +685,7 @@ def compiler(defptr)#0 break is $64 i++ - puts("LLB "); puti(^(bytecode+i)) + //puts("LLB "); puti(^(bytecode+i)) ^codeptr = $CA; codeptr++ // DEX ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = ^(bytecode+i); codeptr++ @@ -700,7 +700,7 @@ def compiler(defptr)#0 break is $66 i++ - puts("LLW "); puti(^(bytecode+i)) + //puts("LLW "); puti(^(bytecode+i)) ^codeptr = $CA; codeptr++ // DEX ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = ^(bytecode+i); codeptr++ @@ -716,7 +716,7 @@ def compiler(defptr)#0 break is $68 i++ - puts("LAB $"); puth(*(bytecode+i)) + //puts("LAB $"); puth(*(bytecode+i)) ^codeptr = $CA; codeptr++ // DEX ^codeptr = $AD; codeptr++ // LDA abs *codeptr = *(bytecode+i); codeptr = codeptr + 2 @@ -730,7 +730,7 @@ def compiler(defptr)#0 break is $6A i++ - puts("LAW $"); puth(*(bytecode+i)) + //puts("LAW $"); puth(*(bytecode+i)) ^codeptr = $CA; codeptr++ // DEX ^codeptr = $AD; codeptr++ // LDA abs *codeptr = *(bytecode+i); codeptr = codeptr + 2 @@ -744,7 +744,7 @@ def compiler(defptr)#0 break is $6C i++ - puts("DLB "); puti(^(bytecode+i)) + //puts("DLB "); puti(^(bytecode+i)) ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = ^(bytecode+i); codeptr++ ^codeptr = $B5; codeptr++ // LDA zp,X @@ -754,7 +754,7 @@ def compiler(defptr)#0 break is $6E i++ - puts("DLW "); puti(^(bytecode+i)) + //puts("DLW "); puti(^(bytecode+i)) ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = ^(bytecode+i); codeptr++ ^codeptr = $B5; codeptr++ // LDA zp,X @@ -769,7 +769,7 @@ def compiler(defptr)#0 break // SB,SW,SLB,SLW,SAB,SAW,DAB,DAW ; 70 72 74 76 78 7A 7C 7E is $70 - puts("SB") + //puts("SB") ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0; codeptr++ // ESTKL ^codeptr = $95; codeptr++ // STA zp,X @@ -782,7 +782,7 @@ def compiler(defptr)#0 ^codeptr = $E8; codeptr++ // INX break is $72 - puts("SW") + //puts("SW") ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0; codeptr++ // ESTKL ^codeptr = $95; codeptr++ // STA zp,X @@ -806,7 +806,7 @@ def compiler(defptr)#0 break is $74 i++ - puts("SLB "); puti(^(bytecode+i)) + //puts("SLB "); puti(^(bytecode+i)) ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = ^(bytecode+i); codeptr++ ^codeptr = $B5; codeptr++ // LDA zp,X @@ -817,7 +817,7 @@ def compiler(defptr)#0 break is $76 i++ - puts("SLW "); puti(^(bytecode+i)) + //puts("SLW "); puti(^(bytecode+i)) ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = ^(bytecode+i); codeptr++ ^codeptr = $B5; codeptr++ // LDA zp,X @@ -833,7 +833,7 @@ def compiler(defptr)#0 break is $78 i++ - puts("SAB $"); puth(*(bytecode+i)) + //puts("SAB $"); puth(*(bytecode+i)) ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0; codeptr++ // ESTKL ^codeptr = $8D; codeptr++ // STA abs @@ -843,7 +843,7 @@ def compiler(defptr)#0 break is $7A i++ - puts("SAW $"); puth(*(bytecode+i)) + //puts("SAW $"); puth(*(bytecode+i)) ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0; codeptr++ // ESTKL ^codeptr = $8D; codeptr++ // STA abs @@ -857,7 +857,7 @@ def compiler(defptr)#0 break is $7C i++ - puts("DAB $"); puth(*(bytecode+i)) + //puts("DAB $"); puth(*(bytecode+i)) ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0; codeptr++ // ESTKL ^codeptr = $8D; codeptr++ // STA abs @@ -866,7 +866,7 @@ def compiler(defptr)#0 break is $7E i++ - puts("DAW $"); puth(*(bytecode+i)) + //puts("DAW $"); puth(*(bytecode+i)) ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0; codeptr++ // ESTKL ^codeptr = $8D; codeptr++ // STA abs @@ -879,7 +879,7 @@ def compiler(defptr)#0 break // LNOT,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 80 82 84 86 88 8A 8C 8E is $80 - puts("NOT") + //puts("NOT") ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0; codeptr++ // ESTKL ^codeptr = $15; codeptr++ // ORA zp,X @@ -896,7 +896,7 @@ def compiler(defptr)#0 ^codeptr = $C0; codeptr++ // ESTKH break is $82 - puts("ADD") + //puts("ADD") ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0; codeptr++ // ESTKL ^codeptr = $18; codeptr++ // CLC @@ -913,7 +913,7 @@ def compiler(defptr)#0 ^codeptr = $E8; codeptr++ // INX break is $84 - puts("SUB") + //puts("SUB") ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+1; codeptr++ // ESTKL+1 ^codeptr = $38; codeptr++ // SEC @@ -930,7 +930,7 @@ def compiler(defptr)#0 ^codeptr = $E8; codeptr++ // INX break is $86 - puts("MUL") + //puts("MUL") // // Call into VM // @@ -940,7 +940,7 @@ def compiler(defptr)#0 ^codeptr = $C0; codeptr++ // NATV CODE break is $88 - puts("DIV") + //puts("DIV") // // Call into VM // @@ -950,7 +950,7 @@ def compiler(defptr)#0 ^codeptr = $C0; codeptr++ // NATV CODE break is $8A - puts("MOD") + //puts("MOD") // // Call into VM // @@ -960,7 +960,7 @@ def compiler(defptr)#0 ^codeptr = $C0; codeptr++ // NATV CODE break is $8C - puts("INCR") + //puts("INCR") ^codeptr = $F6; codeptr++ // INC zp,X ^codeptr = $D0; codeptr++ // ESTKL ^codeptr = $D0; codeptr++ // BNE rel @@ -969,7 +969,7 @@ def compiler(defptr)#0 ^codeptr = $C0; codeptr++ // ESTKH break is $8E - puts("DECR") + //puts("DECR") ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0; codeptr++ // ESTKL ^codeptr = $D0; codeptr++ // BNE rel @@ -981,7 +981,7 @@ def compiler(defptr)#0 break // NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 90 92 94 96 98 9A 9C 9E is $90 - puts("NEG") + //puts("NEG") ^codeptr = $A9; codeptr++ // LDA #imm ^codeptr = $00; codeptr++ // $00 ^codeptr = $38; codeptr++ // SEC @@ -997,7 +997,7 @@ def compiler(defptr)#0 ^codeptr = $C0; codeptr++ // ESTKH break is $92 - puts("COMP") + //puts("COMP") ^codeptr = $A9; codeptr++ // LDA #imm ^codeptr = $FF; codeptr++ // $FF ^codeptr = $55; codeptr++ // EOR zp,X @@ -1012,7 +1012,7 @@ def compiler(defptr)#0 ^codeptr = $C0; codeptr++ // ESTKH break is $94 - puts("AND") + //puts("AND") ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0; codeptr++ // ESTKL ^codeptr = $35; codeptr++ // AND zp,X @@ -1028,7 +1028,7 @@ def compiler(defptr)#0 ^codeptr = $E8; codeptr++ // INX break is $96 - puts("OR") + //puts("OR") ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0; codeptr++ // ESTKL ^codeptr = $15; codeptr++ // ORA zp,X @@ -1044,7 +1044,7 @@ def compiler(defptr)#0 ^codeptr = $E8; codeptr++ // INX break is $98 - puts("XOR") + //puts("XOR") ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0; codeptr++ // ESTKL ^codeptr = $55; codeptr++ // EOR zp,X @@ -1060,7 +1060,7 @@ def compiler(defptr)#0 ^codeptr = $E8; codeptr++ // INX break is $9A - puts("SHL") + //puts("SHL") // // Call into VM // @@ -1070,7 +1070,7 @@ def compiler(defptr)#0 ^codeptr = $C0; codeptr++ // NATV CODE break is $9C - puts("SHR") + //puts("SHR") // // Call into VM // @@ -1080,7 +1080,7 @@ def compiler(defptr)#0 ^codeptr = $C0; codeptr++ // NATV CODE break is $9E - puts("IDXW") + //puts("IDXW") ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0; codeptr++ // ESTKL ^codeptr = $0A; codeptr++ // ASL @@ -1103,7 +1103,7 @@ def compiler(defptr)#0 is $A0 i++ dest = i + *(bytecode+i) - puts("BRGT "); puti(dest) + //puts("BRGT "); puti(dest) i++ ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+1; codeptr++ // ESTKL+1 @@ -1131,7 +1131,7 @@ def compiler(defptr)#0 is $A2 i++ dest = i + *(bytecode+i) - puts("BRLT "); puti(dest) + //puts("BRLT "); puti(dest) i++ ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0; codeptr++ // ESTKL @@ -1159,7 +1159,7 @@ def compiler(defptr)#0 is $A4 i++ dest = i + *(bytecode+i) - puts("INCBRLE "); puti(dest) + //puts("INCBRLE "); puti(dest) i++ // // INCR @@ -1199,7 +1199,7 @@ def compiler(defptr)#0 is $A6 i++ dest = i + *(bytecode+i) - puts("ADDBRLE "); puti(dest) + //puts("ADDBRLE "); puti(dest) i++ // // ADD @@ -1247,7 +1247,7 @@ def compiler(defptr)#0 is $A8 i++ dest = i + *(bytecode+i) - puts("DECBRGE "); puti(dest) + //puts("DECBRGE "); puti(dest) i++ // // DECR @@ -1289,7 +1289,7 @@ def compiler(defptr)#0 is $AA i++ dest = i + *(bytecode+i) - puts("SUBBRGE "); puti(dest) + //puts("SUBBRGE "); puti(dest) i++ // // SUB @@ -1338,7 +1338,7 @@ def compiler(defptr)#0 i++ dest = i + *(bytecode+i) i++ - puts("BRAND "); puti(dest) + //puts("BRAND "); puti(dest) ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0; codeptr++ // ESTKL ^codeptr = $15; codeptr++ // ORA zp,X @@ -1357,7 +1357,7 @@ def compiler(defptr)#0 i++ dest = i + *(bytecode+i) i++ - puts("BROR "); puti(dest) + //puts("BROR "); puti(dest) ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0; codeptr++ // ESTKL ^codeptr = $15; codeptr++ // ORA zp,X @@ -1375,7 +1375,7 @@ def compiler(defptr)#0 // ADDLB,ADDLW,ADDAB,ADDAW,IDXLB,IDXLW,IDXAB,IDXAW ; B0 B2 B4 B6 B8 BA BC BE is $B0 i++ - puts("ADDLB "); puti(^(bytecode+i)) + //puts("ADDLB "); puti(^(bytecode+i)) ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = ^(bytecode+i); codeptr++ ^codeptr = $B1; codeptr++ // LDA (zp),Y @@ -1392,7 +1392,7 @@ def compiler(defptr)#0 break is $B2 i++ - puts("ADDLW "); puti(^(bytecode+i)) + //puts("ADDLW "); puti(^(bytecode+i)) ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = ^(bytecode+i); codeptr++ ^codeptr = $B1; codeptr++ // LDA (zp),Y @@ -1412,7 +1412,7 @@ def compiler(defptr)#0 break is $B4 i++ - puts("ADDAB $"); puth(*(bytecode+i)) + //puts("ADDAB $"); puth(*(bytecode+i)) ^codeptr = $AD; codeptr++ // LDA abs *codeptr = *(bytecode+i); codeptr = codeptr + 2 ^codeptr = $18; codeptr++ // CLC @@ -1428,7 +1428,7 @@ def compiler(defptr)#0 break is $B6 i++ - puts("ADDAW $"); puth(*(bytecode+i)) + //puts("ADDAW $"); puth(*(bytecode+i)) ^codeptr = $AD; codeptr++ // LDA abs *codeptr = *(bytecode+i); codeptr = codeptr + 2 ^codeptr = $18; codeptr++ // CLC @@ -1446,7 +1446,7 @@ def compiler(defptr)#0 break is $B8 i++ - puts("IDXLB "); puti(^(bytecode+i)) + //puts("IDXLB "); puti(^(bytecode+i)) ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = ^(bytecode+i); codeptr++ ^codeptr = $B1; codeptr++ // LDA (zp),Y @@ -1470,7 +1470,7 @@ def compiler(defptr)#0 break is $BA i++ - puts("IDXLW "); puti(^(bytecode+i)) + //puts("IDXLW "); puti(^(bytecode+i)) ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = ^(bytecode+i); codeptr++ ^codeptr = $B1; codeptr++ // LDA (zp),Y @@ -1498,7 +1498,7 @@ def compiler(defptr)#0 break is $BC i++ - puts("IDXAB $"); puth(*(bytecode+i)) + //puts("IDXAB $"); puth(*(bytecode+i)) ^codeptr = $AD; codeptr++ // LDA abs *codeptr = *(bytecode+i); codeptr = codeptr + 2 ^codeptr = $A0; codeptr++ // LDY #imm @@ -1521,7 +1521,7 @@ def compiler(defptr)#0 break is $BE i++ - puts("IDXAW $"); puth(*(bytecode+i)) + //puts("IDXAW $"); puth(*(bytecode+i)) ^codeptr = $AD; codeptr++ // LDA abs *codeptr = *(bytecode+i); codeptr = codeptr + 2 ^codeptr = $0A; codeptr++ // ASL @@ -1548,10 +1548,10 @@ def compiler(defptr)#0 is $FF // NOPed out earlier by SELect break otherwise - putc('$'); puth(^(bytecode+i)) + //putc('$'); puth(^(bytecode+i)) wend fin - putln + //putln i++ if i >= defptr->bytecodesize // @@ -1564,11 +1564,11 @@ def compiler(defptr)#0 // Free working bufffers // heaprelease(addrxlate) - puts("Done compiling: $"); puth(defptr=>interpaddr); putln - getc + //puts("Done compiling: $"); puth(defptr=>interpaddr); putln + //getc return fin - getc + //getc loop // // If we got here. we ran out of code buffer space. Overwrite interpreter @@ -1579,8 +1579,8 @@ def compiler(defptr)#0 // Free working bufffers // heaprelease(addrxlate) - puts("Ran out of code buffer\n") - getc + //puts("Ran out of code buffer\n") + //getc end // // Install JIT compiler diff --git a/src/libsrc/apple/jitune.pla b/src/libsrc/apple/jitune.pla new file mode 100644 index 0000000..9ca8fc6 --- /dev/null +++ b/src/libsrc/apple/jitune.pla @@ -0,0 +1,38 @@ +// +// PLASMA JIT bytecode compiler +// +include "inc/cmdsys.plh" +include "inc/args.plh" +const jitcount = syserr+1 +const jitsize = jitcount+1 +const jitwarmup = jitsize+1 + +word arg + +def atoi(strptr) + word num + num = 0 + + if ^strptr < '0' or ^strptr > '9' + repeat + num = num * 10 + ^strptr - '0' + strptr++ + until ^strptr < '0' or ^strptr > '9' + fin + return num +end + +arg = argNext(argFirst) +if ^arg + cmdsys.jitcount = atoi(arg) + arg = argNext(arg) + if ^arg + cmdsys:warmup = atoi(arg) + arg = argNext(arg) + if ^arg + cmdsys.jitsize = atoi(arg) + fin + fin +else + puts("Usage: JITUNE CALLCOUNT [WARMUP [MAXSIZE]]\n") +fin diff --git a/src/vmsrc/apple/cmdjit.pla b/src/vmsrc/apple/cmdjit.pla index 0cd4799..1fa7cb0 100755 --- a/src/vmsrc/apple/cmdjit.pla +++ b/src/vmsrc/apple/cmdjit.pla @@ -39,9 +39,9 @@ end // // JIT compiler constants // -const jitcount = $01//$10 const jitcomp = $03E2 const jitcodeptr = $03E4 +const jitwarming = $03E6 const jitcode = $BF00 // // Pedefined functions. @@ -60,6 +60,9 @@ word syspath word syscmdln word = @execmod, @open, @close, @read, @write byte perr +byte jitcount = $10 +byte jitsize = $FF +word jitwarmup = $0100 // // Working input buffer overlayed with strings table // @@ -140,7 +143,7 @@ word sysmodsym = @exports // word systemflags = 0 word heap -word xheap = $0800 +word xheap = $0C00//$0800 Skip text page2 for double lores word lastsym = symtbl // // Utility functions @@ -988,12 +991,12 @@ def allocxheap(size)#1 xheap = xaddr + size fin fin - if systemflags & restxt2 - if uword_isle(xaddr, $0C00) and uword_isgt(xheap, $0800) - xaddr = $0C00 - xheap = xaddr + size - fin - fin + //if systemflags & restxt2 + // if uword_isle(xaddr, $0C00) and uword_isgt(xheap, $0800) + // xaddr = $0C00 + // xheap = xaddr + size + // fin + //fin if systemflags & resxhgr1 if uword_isle(xaddr, $4000) and uword_isgt(xheap, $2000) xaddr = $4000 @@ -1067,9 +1070,9 @@ def adddef(isfirst, addr, deflast)#1 if not isfirst preventry = defentry - t_defentry defsize = addr - preventry=>bytecodeaddr - if *jitcomp and defsize < 256 + if *jitcomp and defsize <= jitsize preventry=>interpaddr = $03D6 // JSR $03D6 (JIT INTERP) - preventry->callcount = jitcount // Set count + preventry->callcount = jitcount // Set JIT countdown preventry->bytecodesize = defsize // Set size fin fin @@ -1186,9 +1189,13 @@ def loadmod(mod)#1 codefix = defaddr - bytecode defofst = defaddr - defofst // + // Reser JIT warmup count + // + *jitwarming = jitwarmup + // // Run through the DeFinition Dictionary. // - deffirst = 1 + deffirst = 1 while ^rld == $02 // // This is a bytcode def entry - add it to the def directory. diff --git a/src/vmsrc/apple/plvmjit02.s b/src/vmsrc/apple/plvmjit02.s index 56b5899..b4589fd 100755 --- a/src/vmsrc/apple/plvmjit02.s +++ b/src/vmsrc/apple/plvmjit02.s @@ -53,6 +53,8 @@ OPPAGE = OPIDX+1 STRBUF = $0280 INTERP = $03D0 JITCOMP = $03E2 +JITCODE = $03E4 +JITWARM = $03E6 ;****************************** ;* * ;* INTERPRETER INITIALIZATION * @@ -439,13 +441,21 @@ JITINTRPX PHP PLA SBC #$00 STA TMPH - LDY #$05 ; DEC JIT COUNT - LDA (TMP),Y + LDY #$05 + LDA JITWARM+1 ; CHECK WARMING + ORA JITWARM + BEQ ++ + LDA JITWARM + BNE + + DEC JITWARM+1 ++ DEC JITWARM + JMP +++ +++ LDA (TMP),Y ; DEC JIT COUNT SEC SBC #$01 STA (TMP),Y BEQ RUNJIT - DEY ++++ DEY - LDA (TMP),Y STA IPH DEY From cdb0dac92f76f85abec5179cc80048edd3b7b6c3 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Thu, 22 Mar 2018 12:23:25 -0700 Subject: [PATCH 080/147] Fix SEL and SUBI --- src/inc/cmdsys.plh | 3 + src/libsrc/apple/jit.pla | 1958 +++++++++++++++++++---------------- src/libsrc/apple/jitune.pla | 52 +- src/makefile | 7 +- src/mkrel | 1 + src/vmsrc/apple/cmd.pla | 11 +- src/vmsrc/apple/cmdjit.pla | 12 +- src/vmsrc/apple/sossys.pla | 4 + 8 files changed, 1112 insertions(+), 936 deletions(-) diff --git a/src/inc/cmdsys.plh b/src/inc/cmdsys.plh index 1dd3ae8..b744f1b 100644 --- a/src/inc/cmdsys.plh +++ b/src/inc/cmdsys.plh @@ -51,6 +51,9 @@ import cmdsys word sysread word syswrite byte syserr + byte jitcount + byte jitsize + word jitwarmup byte refcons // Apple /// specific byte devcons // Apple /// specific byte cmdparser diff --git a/src/libsrc/apple/jit.pla b/src/libsrc/apple/jit.pla index 5b0b02c..cf101a4 100644 --- a/src/libsrc/apple/jit.pla +++ b/src/libsrc/apple/jit.pla @@ -32,19 +32,18 @@ const interpentry = $03DC // JIT compiler entry // def compiler(defptr)#0 - word codeptr, addrxlate, bytecode, i, case, dest - byte j + word codeptr, isdata, addrxlate, bytecode, i, case, dest, VX + byte opcode, j - //puts("JIT compiler invoked!\n") - - addrxlate = heapalloc(512 + defptr->bytecodesize) // 256 * sizeof(word) address xlate - if not addrxlate + //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 @@ -55,12 +54,145 @@ def compiler(defptr)#0 *$0042 = bytecode call($C311, 0, 0, 0, $00) // CALL XMOVE with carry clear (AUX->MAIN) //^$C053 // MIX TEXT - ////puts("Addr Xlate: $"); puth(addrxlate); putln - ////puts("Bytecode: $"); puth(bytecode); putln + //puts("Addr Xlate: $"); puth(addrxlate); putln + //puts("Bytecode: $"); puth(bytecode); putln + // + // Find all branch targets and optimization fences. Tag the opcode with the LSB set + // + // All PLASMA ops are even (LSB clear), so this will flag when to fence optimizations + // During compiling. + // + isdata = addrxlate // Use this buffer + i = 0 + while i <= defptr->bytecodesize + if not isdata->[i] + when (^(bytecode+i) & $FE) + // + // Double byte operands + // + is $26 // LA + is $2C // CW + is $54 // CALL + is $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 $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 + // + // Multi-byte operands + // + is $2E // CS + i = i + ^(bytecode+i+1) + 1 + break + // + // Branches + // + is $22 // BREQ + is $24 // BENE + is $4C // BRFLS + is $4E // BRTRU + is $50 // BRNCH + 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 + // + // VM calls + // + is $58 // ENTER, two byte operands + ^(bytecode+i) = ^(bytecode+i) | 1 + i = i + 2 + break + is $5A // LEAVE, one byte operand + ^(bytecode+i) = ^(bytecode+i) | 1 + i++ + break + is $86 // MULL + is $88 // DIV + is $8A // MOD + is $9A // SHL + is $9C // SHR + // + // External control + // + is $54 // CALL + is $5C // RET + ^(bytecode+i) = ^(bytecode+i) | 1 + break + // + // SELect/caseblock + // + is $52 // SEL + i++ + case = i + *(bytecode+i) + i++ + isdata->[case] = 1 // Flag as data + j = ^(bytecode+case) + case++ + repeat + isdata->[case] = 1 // Flag as data + case++ + isdata->[case] = 1 // Flag as data + case++ + dest = case + *(bytecode+case) + ^(bytecode+dest) = ^(bytecode+dest) | 1 // Flag as branch dest + isdata->[case] = 1 // Flag as data + case++ + isdata->[case] = 1 // Flag as data + case++ + 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 + VX = 0 // Virtual X register i = 0 while isule(codeptr, codemax) // @@ -80,52 +212,59 @@ def compiler(defptr)#0 addrxlate=>[i] = codeptr //putc('$'); puth(codeptr); putc(':') //putc('['); puti(i); //puts("] ") - if ^(bytecode+i) < $20 + opcode = ^(bytecode+i) + if opcode & 1 + // + // Optimization fence + // + opcode = opcode & $FE + fin + if opcode < $20 // CN,CN,CN,CN,CN,CN,CN,CN ; 00 02 04 06 08 0A 0C 0E // CN,CN,CN,CN,CN,CN,CN,CN ; 10 12 14 16 18 1A 1C 1E //puts("CN $"); putb(^(bytecode+i)/2) - ^codeptr = $CA; codeptr++ // DEX - ^codeptr = $A9; codeptr++ // LDA #imm + ^codeptr = $CA; codeptr++ // DEX + ^codeptr = $A9; codeptr++ // LDA #imm ^codeptr = ^(bytecode+i)/2; codeptr++ - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $A9; codeptr++ // LDA #imm - ^codeptr = $00; codeptr++ // $00 - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $A9; codeptr++ // LDA #imm + ^codeptr = $00; codeptr++ // $00 + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH else - when ^(bytecode+i) + when opcode // MINUS1,BREQ,BRNE,LA,LLA,CB,CW,CS ; 20 22 24 26 28 2A 2C 2E is $20 //puts("MINUS_ONE") - ^codeptr = $CA; codeptr++ // DEX - ^codeptr = $A9; codeptr++ // LDA #imm - ^codeptr = $FF; codeptr++ // $FF - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $CA; codeptr++ // DEX + ^codeptr = $A9; codeptr++ // LDA #imm + ^codeptr = $FF; codeptr++ // $FF + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH break is $22 i++ dest = i + *(bytecode+i) i++ //puts("BREQ "); puti(dest) - ^codeptr = $E8; codeptr++ // INX - ^codeptr = $E8; codeptr++ // INX - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0-2; codeptr++ // ESTKL-2 - ^codeptr = $D5; codeptr++ // CMP zp,X - ^codeptr = $D0-1; codeptr++ // ESTKL-1 - ^codeptr = $D0; codeptr++ // BNE rel - ^codeptr = $09; codeptr++ // +9 - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $C0-2; codeptr++ // ESTKH-2 - ^codeptr = $D5; codeptr++ // CMP zp,X - ^codeptr = $C0-1; codeptr++ // ESTKH-1 - ^codeptr = $D0; codeptr++ // BNE rel - ^codeptr = $03; codeptr++ // +3 - ^codeptr = $4C; codeptr++ // JMP abs + ^codeptr = $E8; codeptr++ // INX + ^codeptr = $E8; codeptr++ // INX + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0-2+VX; codeptr++ // ESTKL-2 + ^codeptr = $D5; codeptr++ // CMP zp,X + ^codeptr = $D0-1+VX; codeptr++ // ESTKL-1 + ^codeptr = $D0; codeptr++ // BNE rel + ^codeptr = $09; codeptr++ // +9 + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $C0-2+VX; codeptr++ // ESTKH-2 + ^codeptr = $D5; codeptr++ // CMP zp,X + ^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 + ^codeptr = $D0; codeptr++ // BNE rel + ^codeptr = $03; codeptr++ // +3 + ^codeptr = $4C; codeptr++ // JMP abs *codeptr = addrxlate=>[dest] if not (*codeptr & $8000) // Unresolved address list addrxlate=>[dest] = codeptr - *jitcodeptr @@ -137,21 +276,21 @@ def compiler(defptr)#0 dest = i + *(bytecode+i) i++ //puts("BRNE "); puti(dest) - ^codeptr = $E8; codeptr++ // INX - ^codeptr = $E8; codeptr++ // INX - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0-2; codeptr++ // ESTKL-2 - ^codeptr = $D5; codeptr++ // CMP zp,X - ^codeptr = $D0-1; codeptr++ // ESTKL-1 - ^codeptr = $D0; codeptr++ // BNE rel - ^codeptr = $06; codeptr++ // +6 - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $C0-2; codeptr++ // ESTKH-2 - ^codeptr = $D5; codeptr++ // CMP zp,X - ^codeptr = $C0-1; codeptr++ // ESTKH-1 - ^codeptr = $F0; codeptr++ // BEQ rel - ^codeptr = $03; codeptr++ // +3 - ^codeptr = $4C; codeptr++ // JMP abs + ^codeptr = $E8; codeptr++ // INX + ^codeptr = $E8; codeptr++ // INX + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0-2+VX; codeptr++ // ESTKL-2 + ^codeptr = $D5; codeptr++ // CMP zp,X + ^codeptr = $D0-1+VX; codeptr++ // ESTKL-1 + ^codeptr = $D0; codeptr++ // BNE rel + ^codeptr = $06; codeptr++ // +6 + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $C0-2+VX; codeptr++ // ESTKH-2 + ^codeptr = $D5; codeptr++ // CMP zp,X + ^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 + ^codeptr = $F0; codeptr++ // BEQ rel + ^codeptr = $03; codeptr++ // +3 + ^codeptr = $4C; codeptr++ // JMP abs *codeptr = addrxlate=>[dest] if not (*codeptr & $8000) // Unresolved address list addrxlate=>[dest] = codeptr - *jitcodeptr @@ -161,61 +300,61 @@ def compiler(defptr)#0 is $26 i++ //puts("LA $"); puth(*(bytecode+i)) - ^codeptr = $CA; codeptr++ // DEX - ^codeptr = $A9; codeptr++ // LDA #imm + ^codeptr = $CA; codeptr++ // DEX + ^codeptr = $A9; codeptr++ // LDA #imm ^codeptr = ^(bytecode+i); codeptr++ i++ - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $A9; codeptr++ // LDA #imm + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $A9; codeptr++ // LDA #imm ^codeptr = ^(bytecode+i); codeptr++ - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH break is $28 i++ //puts("LLA "); puti(^(bytecode+i)) - ^codeptr = $CA; codeptr++ // DEX - ^codeptr = $A9; codeptr++ // LDA #imm + ^codeptr = $CA; codeptr++ // DEX + ^codeptr = $A9; codeptr++ // LDA #imm ^codeptr = ^(bytecode+i); codeptr++ - ^codeptr = $18; codeptr++ // CLC - ^codeptr = $65; codeptr++ // ADC zp - ^codeptr = $E0; codeptr++ // IFPL - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $A9; codeptr++ // LDA #imm - ^codeptr = $00; codeptr++ // $00 - ^codeptr = $65; codeptr++ // ADC zp - ^codeptr = $E1; codeptr++ // IFPH - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $18; codeptr++ // CLC + ^codeptr = $65; codeptr++ // ADC zp + ^codeptr = $E0; codeptr++ // IFPL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $A9; codeptr++ // LDA #imm + ^codeptr = $00; codeptr++ // $00 + ^codeptr = $65; codeptr++ // ADC zp + ^codeptr = $E1; codeptr++ // IFPH + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH break is $2A i++ //puts("CB $"); putb(^(bytecode+i)) - ^codeptr = $CA; codeptr++ // DEX - ^codeptr = $A9; codeptr++ // LDA #imm + ^codeptr = $CA; codeptr++ // DEX + ^codeptr = $A9; codeptr++ // LDA #imm ^codeptr = ^(bytecode+i); codeptr++ - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $A9; codeptr++ // LDA #imm - ^codeptr = $00; codeptr++ // $00 - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $A9; codeptr++ // LDA #imm + ^codeptr = $00; codeptr++ // $00 + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH break is $2C i++ //puts("CW $"); puth(*(bytecode+i)) - ^codeptr = $CA; codeptr++ // DEX - ^codeptr = $A9; codeptr++ // LDA #imm + ^codeptr = $CA; codeptr++ // DEX + ^codeptr = $A9; codeptr++ // LDA #imm ^codeptr = ^(bytecode+i); codeptr++ i++ - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $A9; codeptr++ // LDA #imm + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $A9; codeptr++ // LDA #imm ^codeptr = ^(bytecode+i); codeptr++ - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH break is $2E i++ @@ -223,21 +362,21 @@ def compiler(defptr)#0 dest = i + j + 1 //puts("CS "); //puts(bytecode+i); //puts("-->"); puti(dest) if isule(codeptr + 12 + j, codemax) - ^codeptr = $CA; codeptr++ // DEX - ^codeptr = $A9; codeptr++ // LDA #imm + ^codeptr = $CA; codeptr++ // DEX + ^codeptr = $A9; codeptr++ // LDA #imm ^codeptr = codeptr+10; codeptr++ - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $A9; codeptr++ // LDA #imm + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $A9; codeptr++ // LDA #imm ^codeptr = (codeptr+6)>>8; codeptr++ - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0; codeptr++ // ESTKH - ^codeptr = $4C; codeptr++ // JMP abs + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH + ^codeptr = $4C; codeptr++ // JMP abs *codeptr = addrxlate=>[dest] if not (*codeptr & $8000) // Unresolved address list addrxlate=>[dest] = codeptr - *jitcodeptr fin - codeptr = codeptr + 2 + codeptr = codeptr + 2 strcpy(codeptr, bytecode+i) codeptr = codeptr + j + 1 i = i + j @@ -257,15 +396,15 @@ def compiler(defptr)#0 break is $34 //puts("DUP") - ^codeptr = $CA; codeptr++ // DEX - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+1; codeptr++ // ESTKL+1 - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $C0+1; codeptr++ // ESTKH+1 - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $CA; codeptr++ // DEX + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH break is $36 //puts("DIVMOD") @@ -276,217 +415,217 @@ def compiler(defptr)#0 is $38 i++ //puts("ADDI $"); putb(^(bytecode+i)) - ^codeptr = $A9; codeptr++ // LDA #imm + ^codeptr = $A9; codeptr++ // LDA #imm ^codeptr = ^(bytecode+i); codeptr++ - ^codeptr = $18; codeptr++ // CLC - ^codeptr = $75; codeptr++ // ADC zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $90; codeptr++ // BCC rel - ^codeptr = $02; codeptr++ // +2 - ^codeptr = $F6; codeptr++ // INC zp,X - ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $18; codeptr++ // CLC + ^codeptr = $75; codeptr++ // ADC zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $90; codeptr++ // BCC rel + ^codeptr = $02; codeptr++ // +2 + ^codeptr = $F6; codeptr++ // INC zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH break is $3A i++ //puts("SUBI $"); putb(^(bytecode+i)) - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $18; codeptr++ // SEC - ^codeptr = $E9; codeptr++ // SBC #imm + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $38; codeptr++ // SEC + ^codeptr = $E9; codeptr++ // SBC #imm ^codeptr = ^(bytecode+i); codeptr++ - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $B0; codeptr++ // BCS rel - ^codeptr = $02; codeptr++ // +2 - ^codeptr = $D6; codeptr++ // DEC zp,X - ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $B0; codeptr++ // BCS rel + ^codeptr = $02; codeptr++ // +2 + ^codeptr = $D6; codeptr++ // DEC zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH break is $3C i++ //puts("ANDI $"); putb(^(bytecode+i)) - ^codeptr = $A9; codeptr++ // LDA #imm + ^codeptr = $A9; codeptr++ // LDA #imm ^codeptr = ^(bytecode+i); codeptr++ - ^codeptr = $35; codeptr++ // AND zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $A9; codeptr++ // LDA #imm - ^codeptr = $00; codeptr++ // $00 - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $35; codeptr++ // AND zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $A9; codeptr++ // LDA #imm + ^codeptr = $00; codeptr++ // $00 + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH break is $3E i++ //puts("ORI $"); putb(^(bytecode+i)) - ^codeptr = $A9; codeptr++ // LDA #imm + ^codeptr = $A9; codeptr++ // LDA #imm ^codeptr = ^(bytecode+i); codeptr++ - ^codeptr = $15; codeptr++ // ORA zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $15; codeptr++ // ORA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL break // ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E is $40 //puts("ISEQ") - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = $00; codeptr++ // $00 - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+1; codeptr++ // ESTKL+1 - ^codeptr = $D5; codeptr++ // CMP zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $D0; codeptr++ // BNE rel - ^codeptr = $07; codeptr++ // +7 - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $C0+1; codeptr++ // ESTKH+1 - ^codeptr = $D5; codeptr++ // CMP zp,X - ^codeptr = $C0; codeptr++ // ESTKH - ^codeptr = $D0; codeptr++ // BNE rel - ^codeptr = $01; codeptr++ // +1 - ^codeptr = $88; codeptr++ // DEY - ^codeptr = $94; codeptr++ // STY zp,X - ^codeptr = $D0+1; codeptr++ // ESTKL+1 - ^codeptr = $94; codeptr++ // STY zp,X - ^codeptr = $C0+1; codeptr++ // ESTKH+1 - ^codeptr = $E8; codeptr++ // INX + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $00; codeptr++ // $00 + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + ^codeptr = $D5; codeptr++ // CMP zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $D0; codeptr++ // BNE rel + ^codeptr = $07; codeptr++ // +7 + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + ^codeptr = $D5; codeptr++ // CMP zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH + ^codeptr = $D0; codeptr++ // BNE rel + ^codeptr = $01; codeptr++ // +1 + ^codeptr = $88; codeptr++ // DEY + ^codeptr = $94; codeptr++ // STY zp,X + ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + ^codeptr = $94; codeptr++ // STY zp,X + ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + ^codeptr = $E8; codeptr++ // INX break is $42 //puts("ISNE") - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = $FF; codeptr++ // $FF - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+1; codeptr++ // ESTKL+1 - ^codeptr = $D5; codeptr++ // CMP zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $D0; codeptr++ // BNE rel - ^codeptr = $07; codeptr++ // +7 - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $C0+1; codeptr++ // ESTKH+1 - ^codeptr = $D5; codeptr++ // CMP zp,X - ^codeptr = $C0; codeptr++ // ESTKH - ^codeptr = $D0; codeptr++ // BNE rel - ^codeptr = $01; codeptr++ // +1 - ^codeptr = $C8; codeptr++ // INY - ^codeptr = $94; codeptr++ // STY zp,X - ^codeptr = $D0+1; codeptr++ // ESTKL+1 - ^codeptr = $94; codeptr++ // STY zp,X - ^codeptr = $C0+1; codeptr++ // ESTKH+1 - ^codeptr = $E8; codeptr++ // INX + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $FF; codeptr++ // $FF + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + ^codeptr = $D5; codeptr++ // CMP zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $D0; codeptr++ // BNE rel + ^codeptr = $07; codeptr++ // +7 + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + ^codeptr = $D5; codeptr++ // CMP zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH + ^codeptr = $D0; codeptr++ // BNE rel + ^codeptr = $01; codeptr++ // +1 + ^codeptr = $C8; codeptr++ // INY + ^codeptr = $94; codeptr++ // STY zp,X + ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + ^codeptr = $94; codeptr++ // STY zp,X + ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + ^codeptr = $E8; codeptr++ // INX break is $44 //puts("ISGT") - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = $FF; codeptr++ // $FF - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $D5; codeptr++ // CMP zp,X - ^codeptr = $D0+1; codeptr++ // ESTKL+1 - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $C0; codeptr++ // ESTKH - ^codeptr = $F5; codeptr++ // SBC zp,X - ^codeptr = $C0+1; codeptr++ // ESTKH+1 - ^codeptr = $50; codeptr++ // BVC rel - ^codeptr = $02; codeptr++ // +2 - ^codeptr = $49; codeptr++ // EOR #imm - ^codeptr = $80; codeptr++ // $80 - ^codeptr = $30; codeptr++ // BMI rel - ^codeptr = $01; codeptr++ // +1 - ^codeptr = $C8; codeptr++ // INY - ^codeptr = $94; codeptr++ // STY zp,X - ^codeptr = $D0+1; codeptr++ // ESTKL+1 - ^codeptr = $94; codeptr++ // STY zp,X - ^codeptr = $C0+1; codeptr++ // ESTKH+1 - ^codeptr = $E8; codeptr++ // INX + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $FF; codeptr++ // $FF + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $D5; codeptr++ // CMP zp,X + ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH + ^codeptr = $F5; codeptr++ // SBC zp,X + ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + ^codeptr = $50; codeptr++ // BVC rel + ^codeptr = $02; codeptr++ // +2 + ^codeptr = $49; codeptr++ // EOR #imm + ^codeptr = $80; codeptr++ // $80 + ^codeptr = $30; codeptr++ // BMI rel + ^codeptr = $01; codeptr++ // +1 + ^codeptr = $C8; codeptr++ // INY + ^codeptr = $94; codeptr++ // STY zp,X + ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + ^codeptr = $94; codeptr++ // STY zp,X + ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + ^codeptr = $E8; codeptr++ // INX break is $46 //puts("ISLT") - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = $FF; codeptr++ // $FF - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+1; codeptr++ // ESTKL+1 - ^codeptr = $D5; codeptr++ // CMP zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $C0+1; codeptr++ // ESTKH+1 - ^codeptr = $F5; codeptr++ // SBC zp,X - ^codeptr = $C0; codeptr++ // ESTKH - ^codeptr = $50; codeptr++ // BVC rel - ^codeptr = $02; codeptr++ // +2 - ^codeptr = $49; codeptr++ // EOR #imm - ^codeptr = $80; codeptr++ // $80 - ^codeptr = $30; codeptr++ // BMI rel - ^codeptr = $01; codeptr++ // +1 - ^codeptr = $C8; codeptr++ // INY - ^codeptr = $94; codeptr++ // STY zp,X - ^codeptr = $D0+1; codeptr++ // ESTKL+1 - ^codeptr = $94; codeptr++ // STY zp,X - ^codeptr = $C0+1; codeptr++ // ESTKH+1 - ^codeptr = $E8; codeptr++ // INX + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $FF; codeptr++ // $FF + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + ^codeptr = $D5; codeptr++ // CMP zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + ^codeptr = $F5; codeptr++ // SBC zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH + ^codeptr = $50; codeptr++ // BVC rel + ^codeptr = $02; codeptr++ // +2 + ^codeptr = $49; codeptr++ // EOR #imm + ^codeptr = $80; codeptr++ // $80 + ^codeptr = $30; codeptr++ // BMI rel + ^codeptr = $01; codeptr++ // +1 + ^codeptr = $C8; codeptr++ // INY + ^codeptr = $94; codeptr++ // STY zp,X + ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + ^codeptr = $94; codeptr++ // STY zp,X + ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + ^codeptr = $E8; codeptr++ // INX break is $48 //puts("ISGE") - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = $FF; codeptr++ // $FF - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+1; codeptr++ // ESTKL+1 - ^codeptr = $D5; codeptr++ // CMP zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $C0+1; codeptr++ // ESTKH+1 - ^codeptr = $F5; codeptr++ // SBC zp,X - ^codeptr = $C0; codeptr++ // ESTKH - ^codeptr = $50; codeptr++ // BVC rel - ^codeptr = $02; codeptr++ // +2 - ^codeptr = $49; codeptr++ // EOR #imm - ^codeptr = $80; codeptr++ // $80 - ^codeptr = $10; codeptr++ // BPL rel - ^codeptr = $01; codeptr++ // +1 - ^codeptr = $C8; codeptr++ // INY - ^codeptr = $94; codeptr++ // STY zp,X - ^codeptr = $D0+1; codeptr++ // ESTKL+1 - ^codeptr = $94; codeptr++ // STY zp,X - ^codeptr = $C0+1; codeptr++ // ESTKH+1 - ^codeptr = $E8; codeptr++ // INX + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $FF; codeptr++ // $FF + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + ^codeptr = $D5; codeptr++ // CMP zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + ^codeptr = $F5; codeptr++ // SBC zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH + ^codeptr = $50; codeptr++ // BVC rel + ^codeptr = $02; codeptr++ // +2 + ^codeptr = $49; codeptr++ // EOR #imm + ^codeptr = $80; codeptr++ // $80 + ^codeptr = $10; codeptr++ // BPL rel + ^codeptr = $01; codeptr++ // +1 + ^codeptr = $C8; codeptr++ // INY + ^codeptr = $94; codeptr++ // STY zp,X + ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + ^codeptr = $94; codeptr++ // STY zp,X + ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + ^codeptr = $E8; codeptr++ // INX break is $4A //puts("ISLE") - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = $FF; codeptr++ // $FF - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $D5; codeptr++ // CMP zp,X - ^codeptr = $D0+1; codeptr++ // ESTKL+1 - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $C0; codeptr++ // ESTKH - ^codeptr = $F5; codeptr++ // SBC zp,X - ^codeptr = $C0+1; codeptr++ // ESTKH+1 - ^codeptr = $50; codeptr++ // BVC rel - ^codeptr = $02; codeptr++ // +2 - ^codeptr = $49; codeptr++ // EOR #imm - ^codeptr = $80; codeptr++ // $80 - ^codeptr = $10; codeptr++ // BPL rel - ^codeptr = $01; codeptr++ // +1 - ^codeptr = $C8; codeptr++ // INY - ^codeptr = $94; codeptr++ // STY zp,X - ^codeptr = $D0+1; codeptr++ // ESTKL+1 - ^codeptr = $94; codeptr++ // STY zp,X - ^codeptr = $C0+1; codeptr++ // ESTKH+1 - ^codeptr = $E8; codeptr++ // INX + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $FF; codeptr++ // $FF + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $D5; codeptr++ // CMP zp,X + ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH + ^codeptr = $F5; codeptr++ // SBC zp,X + ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + ^codeptr = $50; codeptr++ // BVC rel + ^codeptr = $02; codeptr++ // +2 + ^codeptr = $49; codeptr++ // EOR #imm + ^codeptr = $80; codeptr++ // $80 + ^codeptr = $10; codeptr++ // BPL rel + ^codeptr = $01; codeptr++ // +1 + ^codeptr = $C8; codeptr++ // INY + ^codeptr = $94; codeptr++ // STY zp,X + ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + ^codeptr = $94; codeptr++ // STY zp,X + ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + ^codeptr = $E8; codeptr++ // INX break is $4C i++ dest = i + *(bytecode+i) i++ //puts("BRFLS "); puti(dest) - ^codeptr = $E8; codeptr++ // INX - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0-1; codeptr++ // ESTKL-1 - ^codeptr = $15; codeptr++ // ORA zp,X - ^codeptr = $C0-1; codeptr++ // ESTKH-1 - ^codeptr = $D0; codeptr++ // BNE rel - ^codeptr = $03; codeptr++ // +3 - ^codeptr = $4C; codeptr++ // JMP abs + ^codeptr = $E8; codeptr++ // INX + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0-1+VX; codeptr++ // ESTKL-1 + ^codeptr = $15; codeptr++ // ORA zp,X + ^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 + ^codeptr = $D0; codeptr++ // BNE rel + ^codeptr = $03; codeptr++ // +3 + ^codeptr = $4C; codeptr++ // JMP abs *codeptr = addrxlate=>[dest] if not (*codeptr & $8000) // Unresolved address list addrxlate=>[dest] = codeptr - *jitcodeptr @@ -498,14 +637,14 @@ def compiler(defptr)#0 dest = i + *(bytecode+i) i++ //puts("BRTRU "); puti(dest) - ^codeptr = $E8; codeptr++ // INX - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0-1; codeptr++ // ESTKL-1 - ^codeptr = $15; codeptr++ // ORA zp,X - ^codeptr = $C0-1; codeptr++ // ESTKH-1 - ^codeptr = $F0; codeptr++ // BEQ rel - ^codeptr = $03; codeptr++ // +3 - ^codeptr = $4C; codeptr++ // JMP abs + ^codeptr = $E8; codeptr++ // INX + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0-1+VX; codeptr++ // ESTKL-1 + ^codeptr = $15; codeptr++ // ORA zp,X + ^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 + ^codeptr = $F0; codeptr++ // BEQ rel + ^codeptr = $03; codeptr++ // +3 + ^codeptr = $4C; codeptr++ // JMP abs *codeptr = addrxlate=>[dest] if not (*codeptr & $8000) // Unresolved address list addrxlate=>[dest] = codeptr - *jitcodeptr @@ -533,13 +672,13 @@ def compiler(defptr)#0 j = ^(bytecode+case) dest = codeptr + 8 + case * 11) if isule(dest, codemax) - ^(bytecode+case) = $FF // Flag as NOP + ^(bytecode+case) = $FE // Flag as NOP case++ - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $B4; codeptr++ // LDY zp,X - ^codeptr = $C0; codeptr++ // ESTKH - ^codeptr = $E8; codeptr++ // INX + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $B4; codeptr++ // LDY zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH + ^codeptr = $E8; codeptr++ // INX repeat //puts(" $"); puth(*(bytecode+case)) ^codeptr = $C9; codeptr++ // CMP #imm @@ -550,16 +689,17 @@ def compiler(defptr)#0 ^codeptr = ^(bytecode+case+1); codeptr++ ^codeptr = $D0; codeptr++ // BNE rel ^codeptr = $03; codeptr++ // +3 - *(bytecode+case) = $FFFF + *(bytecode+case) = $FEFE case = case + 2 - //puts("-->"); puti(case + *(bytecode+case)); putln + dest = case + *(bytecode+case) + //puts("-->"); puti(dest); putln ^codeptr = $4C; codeptr++ // JMP abs - *codeptr = addrxlate=>[case] + *codeptr = addrxlate=>[dest] if not (*codeptr & $8000) // Unresolved address list - addrxlate=>[case] = codeptr - *jitcodeptr + addrxlate=>[dest] = codeptr - *jitcodeptr fin codeptr = codeptr + 2 - *(bytecode+case) = $FFFF + *(bytecode+case) = $FEFE case = case + 2 j-- until not j @@ -588,15 +728,19 @@ def compiler(defptr)#0 // // Pull address off stack // - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $85; codeptr++ // STA zp - ^codeptr = $E7; codeptr++ // $E7:TMPL - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $C0; codeptr++ // ESTKH - ^codeptr = $85; codeptr++ // STA zp - ^codeptr = $E8; codeptr++ // $E8:TMPH - ^codeptr = $E8; codeptr++ // INX + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $85; codeptr++ // STA zp + ^codeptr = $E7; codeptr++ // $E7:TMPL + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH + ^codeptr = $85; codeptr++ // STA zp + ^codeptr = $E8; codeptr++ // $E8:TMPH + ^codeptr = $E8; codeptr++ // INX + // + // Resolve VX + // + // // Call through TMP // @@ -610,9 +754,9 @@ def compiler(defptr)#0 // // Call into VM // - ^codeptr = $20; codeptr++ // JSR INTERP + ^codeptr = $20; codeptr++ // JSR INTERP *codeptr = $3D0; codeptr = codeptr + 2 - ^codeptr = $58; codeptr++ // ENTER CODE + ^codeptr = $58; codeptr++ // ENTER CODE ^codeptr = ^(bytecode+i); codeptr++ // ENTER FRAME SIZE i++ ^codeptr = ^(bytecode+i); codeptr++ // ENTER ARG COUNT @@ -624,9 +768,9 @@ def compiler(defptr)#0 // // Call into VM // - ^codeptr = $20; codeptr++ // JSR INTERP + ^codeptr = $20; codeptr++ // JSR INTERP *codeptr = $3D0; codeptr = codeptr + 2 - ^codeptr = $5A; codeptr++ // LEAVE CODE + ^codeptr = $5A; codeptr++ // LEAVE CODE ^codeptr = ^(bytecode+i); codeptr++ // LEAVE OPERAND break is $5C @@ -636,468 +780,468 @@ def compiler(defptr)#0 is $5E i++ //puts("CFFB $FF"); putb(^(bytecode+i)) - ^codeptr = $CA; codeptr++ // DEX - ^codeptr = $A9; codeptr++ // LDA #imm + ^codeptr = $CA; codeptr++ // DEX + ^codeptr = $A9; codeptr++ // LDA #imm ^codeptr = ^(bytecode+i); codeptr++ - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $A9; codeptr++ // LDA #imm - ^codeptr = $FF; codeptr++ // $FF - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $A9; codeptr++ // LDA #imm + ^codeptr = $FF; codeptr++ // $FF + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH break // LB,LW,LLB,LLW,LAB,LAW,DLB,DLW ; 60 62 64 66 68 6A 6C 6E is $60 //puts("LB") - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0-1; codeptr++ // ESTKH-1 - ^codeptr = $A1; codeptr++ // LDA (zp,X) - ^codeptr = $C0-1; codeptr++ // ESTKH-1 - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $A9; codeptr++ // LDA #imm - ^codeptr = $00; codeptr++ // $00 - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 + ^codeptr = $A1; codeptr++ // LDA (zp,X) + ^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $A9; codeptr++ // LDA #imm + ^codeptr = $00; codeptr++ // $00 + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH break is $62 //puts("LW") - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0-1; codeptr++ // ESTKH-1 - ^codeptr = $A1; codeptr++ // LDA (zp,X) - ^codeptr = $C0-1; codeptr++ // ESTKH-1 - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $F6; codeptr++ // INC zp,X - ^codeptr = $C0-1; codeptr++ // ESTKH-1 - ^codeptr = $D0; codeptr++ // BNE rel - ^codeptr = $02; codeptr++ // +2 - ^codeptr = $F6; codeptr++ // INC zp,X - ^codeptr = $C0; codeptr++ // ESTKH - ^codeptr = $A1; codeptr++ // LDA (zp,X) - ^codeptr = $C0-1; codeptr++ // ESTKH-1 - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 + ^codeptr = $A1; codeptr++ // LDA (zp,X) + ^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $F6; codeptr++ // INC zp,X + ^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 + ^codeptr = $D0; codeptr++ // BNE rel + ^codeptr = $02; codeptr++ // +2 + ^codeptr = $F6; codeptr++ // INC zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH + ^codeptr = $A1; codeptr++ // LDA (zp,X) + ^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH break is $64 i++ //puts("LLB "); puti(^(bytecode+i)) - ^codeptr = $CA; codeptr++ // DEX - ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $CA; codeptr++ // DEX + ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = ^(bytecode+i); codeptr++ - ^codeptr = $B1; codeptr++ // LDA (zp),Y - ^codeptr = $E0; codeptr++ // IFP - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $A9; codeptr++ // LDA #imm - ^codeptr = $00; codeptr++ // $00 - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $B1; codeptr++ // LDA (zp),Y + ^codeptr = $E0; codeptr++ // IFP + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $A9; codeptr++ // LDA #imm + ^codeptr = $00; codeptr++ // $00 + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH break is $66 i++ //puts("LLW "); puti(^(bytecode+i)) - ^codeptr = $CA; codeptr++ // DEX - ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $CA; codeptr++ // DEX + ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = ^(bytecode+i); codeptr++ - ^codeptr = $B1; codeptr++ // LDA (zp),Y - ^codeptr = $E0; codeptr++ // IFP - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $C8; codeptr++ // INY - ^codeptr = $B1; codeptr++ // LDA (zp),Y - ^codeptr = $E0; codeptr++ // IFP - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $B1; codeptr++ // LDA (zp),Y + ^codeptr = $E0; codeptr++ // IFP + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $C8; codeptr++ // INY + ^codeptr = $B1; codeptr++ // LDA (zp),Y + ^codeptr = $E0; codeptr++ // IFP + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH break is $68 i++ //puts("LAB $"); puth(*(bytecode+i)) - ^codeptr = $CA; codeptr++ // DEX - ^codeptr = $AD; codeptr++ // LDA abs + ^codeptr = $CA; codeptr++ // DEX + ^codeptr = $AD; codeptr++ // LDA abs *codeptr = *(bytecode+i); codeptr = codeptr + 2 - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $A9; codeptr++ // LDA #imm - ^codeptr = $00; codeptr++ // $00 - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $A9; codeptr++ // LDA #imm + ^codeptr = $00; codeptr++ // $00 + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH i++ break is $6A i++ //puts("LAW $"); puth(*(bytecode+i)) - ^codeptr = $CA; codeptr++ // DEX - ^codeptr = $AD; codeptr++ // LDA abs + ^codeptr = $CA; codeptr++ // DEX + ^codeptr = $AD; codeptr++ // LDA abs *codeptr = *(bytecode+i); codeptr = codeptr + 2 - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $AD; codeptr++ // LDA abs + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $AD; codeptr++ // LDA abs *codeptr = *(bytecode+i)+1; codeptr = codeptr + 2 - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH i++ break is $6C i++ //puts("DLB "); puti(^(bytecode+i)) - ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = ^(bytecode+i); codeptr++ - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $91; codeptr++ // STA (zp),Y - ^codeptr = $E0; codeptr++ // IFP + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $91; codeptr++ // STA (zp),Y + ^codeptr = $E0; codeptr++ // IFP break is $6E i++ //puts("DLW "); puti(^(bytecode+i)) - ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = ^(bytecode+i); codeptr++ - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $91; codeptr++ // STA (zp),Y - ^codeptr = $E0; codeptr++ // IFP - ^codeptr = $C8; codeptr++ // INY - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $C0; codeptr++ // ESTKH - ^codeptr = $91; codeptr++ // STA (zp),Y - ^codeptr = $E0; codeptr++ // IFP + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $91; codeptr++ // STA (zp),Y + ^codeptr = $E0; codeptr++ // IFP + ^codeptr = $C8; codeptr++ // INY + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH + ^codeptr = $91; codeptr++ // STA (zp),Y + ^codeptr = $E0; codeptr++ // IFP break // SB,SW,SLB,SLW,SAB,SAW,DAB,DAW ; 70 72 74 76 78 7A 7C 7E is $70 //puts("SB") - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0-1; codeptr++ // ESTKH-1 - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+1; codeptr++ // ESTKL+1 - ^codeptr = $81; codeptr++ // STA (zp,X) - ^codeptr = $C0-1; codeptr++ // ESTKH-1 - ^codeptr = $E8; codeptr++ // INX - ^codeptr = $E8; codeptr++ // INX + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + ^codeptr = $81; codeptr++ // STA (zp,X) + ^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 + ^codeptr = $E8; codeptr++ // INX + ^codeptr = $E8; codeptr++ // INX break is $72 //puts("SW") - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0-1; codeptr++ // ESTKH-1 - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+1; codeptr++ // ESTKL+1 - ^codeptr = $81; codeptr++ // STA (zp,X) - ^codeptr = $C0-1; codeptr++ // ESTKH-1 - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $C0+1; codeptr++ // ESTKH+1 - ^codeptr = $F6; codeptr++ // INC zp,X - ^codeptr = $C0-1; codeptr++ // ESTKH-1 - ^codeptr = $D0; codeptr++ // BNE rel - ^codeptr = $02; codeptr++ // +2 - ^codeptr = $F6; codeptr++ // INC zp,X - ^codeptr = $C0; codeptr++ // ESTKH - ^codeptr = $81; codeptr++ // STA (zp,X) - ^codeptr = $C0-1; codeptr++ // ESTKH-1 - ^codeptr = $E8; codeptr++ // INX - ^codeptr = $E8; codeptr++ // INX + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + ^codeptr = $81; codeptr++ // STA (zp,X) + ^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + ^codeptr = $F6; codeptr++ // INC zp,X + ^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 + ^codeptr = $D0; codeptr++ // BNE rel + ^codeptr = $02; codeptr++ // +2 + ^codeptr = $F6; codeptr++ // INC zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH + ^codeptr = $81; codeptr++ // STA (zp,X) + ^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 + ^codeptr = $E8; codeptr++ // INX + ^codeptr = $E8; codeptr++ // INX break is $74 i++ //puts("SLB "); puti(^(bytecode+i)) - ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = ^(bytecode+i); codeptr++ - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $91; codeptr++ // STA (zp),Y - ^codeptr = $E0; codeptr++ // IFP - ^codeptr = $E8; codeptr++ // INX + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $91; codeptr++ // STA (zp),Y + ^codeptr = $E0; codeptr++ // IFP + ^codeptr = $E8; codeptr++ // INX break is $76 i++ //puts("SLW "); puti(^(bytecode+i)) - ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = ^(bytecode+i); codeptr++ - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $91; codeptr++ // STA (zp),Y - ^codeptr = $E0; codeptr++ // IFP - ^codeptr = $C8; codeptr++ // INY - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $C0; codeptr++ // ESTKH - ^codeptr = $91; codeptr++ // STA (zp),Y - ^codeptr = $E0; codeptr++ // IFP - ^codeptr = $E8; codeptr++ // INX + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $91; codeptr++ // STA (zp),Y + ^codeptr = $E0; codeptr++ // IFP + ^codeptr = $C8; codeptr++ // INY + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH + ^codeptr = $91; codeptr++ // STA (zp),Y + ^codeptr = $E0; codeptr++ // IFP + ^codeptr = $E8; codeptr++ // INX break is $78 i++ //puts("SAB $"); puth(*(bytecode+i)) - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $8D; codeptr++ // STA abs + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $8D; codeptr++ // STA abs *codeptr = *(bytecode+i); codeptr = codeptr + 2 - ^codeptr = $E8; codeptr++ // INX + ^codeptr = $E8; codeptr++ // INX i++ break is $7A i++ //puts("SAW $"); puth(*(bytecode+i)) - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $8D; codeptr++ // STA abs + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $8D; codeptr++ // STA abs *codeptr = *(bytecode+i); codeptr = codeptr + 2 - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $C0; codeptr++ // ESTKH - ^codeptr = $8D; codeptr++ // STA abs + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH + ^codeptr = $8D; codeptr++ // STA abs *codeptr = *(bytecode+i)+1; codeptr = codeptr + 2 - ^codeptr = $E8; codeptr++ // INX + ^codeptr = $E8; codeptr++ // INX i++ break is $7C i++ //puts("DAB $"); puth(*(bytecode+i)) - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $8D; codeptr++ // STA abs + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $8D; codeptr++ // STA abs *codeptr = *(bytecode+i); codeptr = codeptr + 2 i++ break is $7E i++ //puts("DAW $"); puth(*(bytecode+i)) - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $8D; codeptr++ // STA abs + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $8D; codeptr++ // STA abs *codeptr = *(bytecode+i); codeptr = codeptr + 2 - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $C0; codeptr++ // ESTKH - ^codeptr = $8D; codeptr++ // STA abs + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH + ^codeptr = $8D; codeptr++ // STA abs *codeptr = *(bytecode+i)+1; codeptr = codeptr + 2 i++ break // LNOT,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 80 82 84 86 88 8A 8C 8E is $80 //puts("NOT") - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $15; codeptr++ // ORA zp,X - ^codeptr = $C0; codeptr++ // ESTKH - ^codeptr = $F0; codeptr++ // BEQ rel - ^codeptr = $02; codeptr++ // +2 - ^codeptr = $A9; codeptr++ // LDA #imm - ^codeptr = $FF; codeptr++ // $FF - ^codeptr = $49; codeptr++ // EOR #imm - ^codeptr = $FF; codeptr++ // $FF - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $15; codeptr++ // ORA zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH + ^codeptr = $F0; codeptr++ // BEQ rel + ^codeptr = $02; codeptr++ // +2 + ^codeptr = $A9; codeptr++ // LDA #imm + ^codeptr = $FF; codeptr++ // $FF + ^codeptr = $49; codeptr++ // EOR #imm + ^codeptr = $FF; codeptr++ // $FF + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH break is $82 //puts("ADD") - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $18; codeptr++ // CLC - ^codeptr = $75; codeptr++ // ADC zp,X - ^codeptr = $D0+1; codeptr++ // ESTKL+1 - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+1; codeptr++ // ESTKL+1 - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $C0; codeptr++ // ESTKH - ^codeptr = $75; codeptr++ // ADC zp,X - ^codeptr = $C0+1; codeptr++ // ESTKH+1 - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0+1; codeptr++ // ESTKH+1 - ^codeptr = $E8; codeptr++ // INX + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $18; codeptr++ // CLC + ^codeptr = $75; codeptr++ // ADC zp,X + ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH + ^codeptr = $75; codeptr++ // ADC zp,X + ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + ^codeptr = $E8; codeptr++ // INX break is $84 //puts("SUB") - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+1; codeptr++ // ESTKL+1 - ^codeptr = $38; codeptr++ // SEC - ^codeptr = $F5; codeptr++ // SBC zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+1; codeptr++ // ESTKL+1 - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $C0+1; codeptr++ // ESTKH+1 - ^codeptr = $F5; codeptr++ // SBC zp,X - ^codeptr = $C0; codeptr++ // ESTKH - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0+1; codeptr++ // ESTKH+1 - ^codeptr = $E8; codeptr++ // INX + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + ^codeptr = $38; codeptr++ // SEC + ^codeptr = $F5; codeptr++ // SBC zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + ^codeptr = $F5; codeptr++ // SBC zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + ^codeptr = $E8; codeptr++ // INX break is $86 //puts("MUL") // // Call into VM // - ^codeptr = $20; codeptr++ // JSR INTERP + ^codeptr = $20; codeptr++ // JSR INTERP *codeptr = $3D0; codeptr = codeptr + 2 - ^codeptr = $86; codeptr++ // MUL CODE - ^codeptr = $C0; codeptr++ // NATV CODE + ^codeptr = $86; codeptr++ // MUL CODE + ^codeptr = $C0; codeptr++ // NATV CODE break is $88 //puts("DIV") // // Call into VM // - ^codeptr = $20; codeptr++ // JSR INTERP + ^codeptr = $20; codeptr++ // JSR INTERP *codeptr = $3D0; codeptr = codeptr + 2 - ^codeptr = $88; codeptr++ // DIV CODE - ^codeptr = $C0; codeptr++ // NATV CODE + ^codeptr = $88; codeptr++ // DIV CODE + ^codeptr = $C0; codeptr++ // NATV CODE break is $8A //puts("MOD") // // Call into VM // - ^codeptr = $20; codeptr++ // JSR INTERP + ^codeptr = $20; codeptr++ // JSR INTERP *codeptr = $3D0; codeptr = codeptr + 2 - ^codeptr = $8A; codeptr++ // MOD CODE - ^codeptr = $C0; codeptr++ // NATV CODE + ^codeptr = $8A; codeptr++ // MOD CODE + ^codeptr = $C0; codeptr++ // NATV CODE break is $8C //puts("INCR") - ^codeptr = $F6; codeptr++ // INC zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $D0; codeptr++ // BNE rel - ^codeptr = $02; codeptr++ // +2 - ^codeptr = $F6; codeptr++ // INC zp,X - ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $F6; codeptr++ // INC zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $D0; codeptr++ // BNE rel + ^codeptr = $02; codeptr++ // +2 + ^codeptr = $F6; codeptr++ // INC zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH break is $8E //puts("DECR") - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $D0; codeptr++ // BNE rel - ^codeptr = $02; codeptr++ // +2 - ^codeptr = $D6; codeptr++ // DEC zp,X - ^codeptr = $C0; codeptr++ // ESTKH - ^codeptr = $D6; codeptr++ // DEC zp,X - ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $D0; codeptr++ // BNE rel + ^codeptr = $02; codeptr++ // +2 + ^codeptr = $D6; codeptr++ // DEC zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH + ^codeptr = $D6; codeptr++ // DEC zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL break // NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 90 92 94 96 98 9A 9C 9E is $90 //puts("NEG") - ^codeptr = $A9; codeptr++ // LDA #imm - ^codeptr = $00; codeptr++ // $00 - ^codeptr = $38; codeptr++ // SEC - ^codeptr = $F5; codeptr++ // SBC zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $A9; codeptr++ // LDA #imm - ^codeptr = $00; codeptr++ // $00 - ^codeptr = $F5; codeptr++ // SBC zp,X - ^codeptr = $C0; codeptr++ // ESTKH - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $A9; codeptr++ // LDA #imm + ^codeptr = $00; codeptr++ // $00 + ^codeptr = $38; codeptr++ // SEC + ^codeptr = $F5; codeptr++ // SBC zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $A9; codeptr++ // LDA #imm + ^codeptr = $00; codeptr++ // $00 + ^codeptr = $F5; codeptr++ // SBC zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH break is $92 //puts("COMP") - ^codeptr = $A9; codeptr++ // LDA #imm - ^codeptr = $FF; codeptr++ // $FF - ^codeptr = $55; codeptr++ // EOR zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $A9; codeptr++ // LDA #imm - ^codeptr = $FF; codeptr++ // $FF - ^codeptr = $55; codeptr++ // EOR zp,X - ^codeptr = $C0; codeptr++ // ESTKH - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $A9; codeptr++ // LDA #imm + ^codeptr = $FF; codeptr++ // $FF + ^codeptr = $55; codeptr++ // EOR zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $A9; codeptr++ // LDA #imm + ^codeptr = $FF; codeptr++ // $FF + ^codeptr = $55; codeptr++ // EOR zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH break is $94 //puts("AND") - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $35; codeptr++ // AND zp,X - ^codeptr = $D0+1; codeptr++ // ESTKL+1 - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+1; codeptr++ // ESTKL+1 - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $C0; codeptr++ // ESTKH - ^codeptr = $35; codeptr++ // AND zp,X - ^codeptr = $C0+1; codeptr++ // ESTKH+1 - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0+1; codeptr++ // ESTKH+1 - ^codeptr = $E8; codeptr++ // INX + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $35; codeptr++ // AND zp,X + ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH + ^codeptr = $35; codeptr++ // AND zp,X + ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + ^codeptr = $E8; codeptr++ // INX break is $96 //puts("OR") - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $15; codeptr++ // ORA zp,X - ^codeptr = $D0+1; codeptr++ // ESTKL+1 - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+1; codeptr++ // ESTKL+1 - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $C0; codeptr++ // ESTKH - ^codeptr = $15; codeptr++ // ORA zp,X - ^codeptr = $C0+1; codeptr++ // ESTKH+1 - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0+1; codeptr++ // ESTKH+1 - ^codeptr = $E8; codeptr++ // INX + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $15; codeptr++ // ORA zp,X + ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH + ^codeptr = $15; codeptr++ // ORA zp,X + ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + ^codeptr = $E8; codeptr++ // INX break is $98 //puts("XOR") - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $55; codeptr++ // EOR zp,X - ^codeptr = $D0+1; codeptr++ // ESTKL+1 - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+1; codeptr++ // ESTKL+1 - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $C0; codeptr++ // ESTKH - ^codeptr = $55; codeptr++ // EOR zp,X - ^codeptr = $C0+1; codeptr++ // ESTKH+1 - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0+1; codeptr++ // ESTKH+1 - ^codeptr = $E8; codeptr++ // INX + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $55; codeptr++ // EOR zp,X + ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH + ^codeptr = $55; codeptr++ // EOR zp,X + ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + ^codeptr = $E8; codeptr++ // INX break is $9A //puts("SHL") // // Call into VM // - ^codeptr = $20; codeptr++ // JSR INTERP + ^codeptr = $20; codeptr++ // JSR INTERP *codeptr = $3D0; codeptr = codeptr + 2 - ^codeptr = $9A; codeptr++ // SHL CODE - ^codeptr = $C0; codeptr++ // NATV CODE + ^codeptr = $9A; codeptr++ // SHL CODE + ^codeptr = $C0; codeptr++ // NATV CODE break is $9C //puts("SHR") // // Call into VM // - ^codeptr = $20; codeptr++ // JSR INTERP + ^codeptr = $20; codeptr++ // JSR INTERP *codeptr = $3D0; codeptr = codeptr + 2 - ^codeptr = $9C; codeptr++ // SHR CODE - ^codeptr = $C0; codeptr++ // NATV CODE + ^codeptr = $9C; codeptr++ // SHR CODE + ^codeptr = $C0; codeptr++ // NATV CODE break is $9E //puts("IDXW") - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $0A; codeptr++ // ASL - ^codeptr = $36; codeptr++ // ROL zp,X - ^codeptr = $C0; codeptr++ // ESTKH - ^codeptr = $18; codeptr++ // CLC - ^codeptr = $75; codeptr++ // ADC zp,X - ^codeptr = $D0+1; codeptr++ // ESTKL+1 - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+1; codeptr++ // ESTKL+1 - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $C0; codeptr++ // ESTKH - ^codeptr = $75; codeptr++ // ADC zp,X - ^codeptr = $C0+1; codeptr++ // ESTKH+1 - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0+1; codeptr++ // ESTKH+1 - ^codeptr = $E8; codeptr++ // INX + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $0A; codeptr++ // ASL + ^codeptr = $36; codeptr++ // ROL zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH + ^codeptr = $18; codeptr++ // CLC + ^codeptr = $75; codeptr++ // ADC zp,X + ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH + ^codeptr = $75; codeptr++ // ADC zp,X + ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + ^codeptr = $E8; codeptr++ // INX break // BRGT,BRLT,INCBRLE,ADDBRLE,DECBRGE,SUBBRGE,BRAND,BROR ; A0 A2 A4 A6 A8 AA AC AE is $A0 @@ -1105,23 +1249,23 @@ def compiler(defptr)#0 dest = i + *(bytecode+i) //puts("BRGT "); puti(dest) i++ - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+1; codeptr++ // ESTKL+1 - ^codeptr = $D5; codeptr++ // CMP zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $C0+1; codeptr++ // ESTKH+1 - ^codeptr = $F5; codeptr++ // SBC zp,X - ^codeptr = $C0; codeptr++ // ESTKH - ^codeptr = $50; codeptr++ // BVC rel - ^codeptr = $02; codeptr++ // +2 - ^codeptr = $49; codeptr++ // EOR #imm - ^codeptr = $80; codeptr++ // $80 - ^codeptr = $10; codeptr++ // BPL rel - ^codeptr = $05; codeptr++ // +5 - ^codeptr = $E8; codeptr++ // INX - ^codeptr = $E8; codeptr++ // INX - ^codeptr = $4C; codeptr++ // JMP abs + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + ^codeptr = $D5; codeptr++ // CMP zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + ^codeptr = $F5; codeptr++ // SBC zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH + ^codeptr = $50; codeptr++ // BVC rel + ^codeptr = $02; codeptr++ // +2 + ^codeptr = $49; codeptr++ // EOR #imm + ^codeptr = $80; codeptr++ // $80 + ^codeptr = $10; codeptr++ // BPL rel + ^codeptr = $05; codeptr++ // +5 + ^codeptr = $E8; codeptr++ // INX + ^codeptr = $E8; codeptr++ // INX + ^codeptr = $4C; codeptr++ // JMP abs *codeptr = addrxlate=>[dest] if not (*codeptr & $8000) // Unresolved address list addrxlate=>[dest] = codeptr - *jitcodeptr @@ -1133,23 +1277,23 @@ def compiler(defptr)#0 dest = i + *(bytecode+i) //puts("BRLT "); puti(dest) i++ - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $D5; codeptr++ // CMP zp,X - ^codeptr = $D0+1; codeptr++ // ESTKL+1 - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $C0; codeptr++ // ESTKH - ^codeptr = $F5; codeptr++ // SBC zp,X - ^codeptr = $C0+1; codeptr++ // ESTKH+1 - ^codeptr = $50; codeptr++ // BVC rel - ^codeptr = $02; codeptr++ // +2 - ^codeptr = $49; codeptr++ // EOR #imm - ^codeptr = $80; codeptr++ // $80 - ^codeptr = $10; codeptr++ // BPL rel - ^codeptr = $05; codeptr++ // +5 - ^codeptr = $E8; codeptr++ // INX - ^codeptr = $E8; codeptr++ // INX - ^codeptr = $4C; codeptr++ // JMP abs + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $D5; codeptr++ // CMP zp,X + ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH + ^codeptr = $F5; codeptr++ // SBC zp,X + ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + ^codeptr = $50; codeptr++ // BVC rel + ^codeptr = $02; codeptr++ // +2 + ^codeptr = $49; codeptr++ // EOR #imm + ^codeptr = $80; codeptr++ // $80 + ^codeptr = $10; codeptr++ // BPL rel + ^codeptr = $05; codeptr++ // +5 + ^codeptr = $E8; codeptr++ // INX + ^codeptr = $E8; codeptr++ // INX + ^codeptr = $4C; codeptr++ // JMP abs *codeptr = addrxlate=>[dest] if not (*codeptr & $8000) // Unresolved address list addrxlate=>[dest] = codeptr - *jitcodeptr @@ -1164,37 +1308,37 @@ def compiler(defptr)#0 // // INCR // - ^codeptr = $F6; codeptr++ // INC zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $D0; codeptr++ // BNE rel - ^codeptr = $02; codeptr++ // +2 - ^codeptr = $F6; codeptr++ // INC zp,X - ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $F6; codeptr++ // INC zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $D0; codeptr++ // BNE rel + ^codeptr = $02; codeptr++ // +2 + ^codeptr = $F6; codeptr++ // INC zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH // // BRLE // - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+1; codeptr++ // ESTKL+1 - ^codeptr = $D5; codeptr++ // CMP zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $C0+1; codeptr++ // ESTKH+1 - ^codeptr = $F5; codeptr++ // SBC zp,X - ^codeptr = $C0; codeptr++ // ESTKH - ^codeptr = $50; codeptr++ // BVC rel - ^codeptr = $02; codeptr++ // +2 - ^codeptr = $49; codeptr++ // EOR #imm - ^codeptr = $80; codeptr++ // $80 - ^codeptr = $30; codeptr++ // BMI rel - ^codeptr = $03; codeptr++ // +3 - ^codeptr = $4C; codeptr++ // JMP abs + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + ^codeptr = $D5; codeptr++ // CMP zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + ^codeptr = $F5; codeptr++ // SBC zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH + ^codeptr = $50; codeptr++ // BVC rel + ^codeptr = $02; codeptr++ // +2 + ^codeptr = $49; codeptr++ // EOR #imm + ^codeptr = $80; codeptr++ // $80 + ^codeptr = $30; codeptr++ // BMI rel + ^codeptr = $03; codeptr++ // +3 + ^codeptr = $4C; codeptr++ // JMP abs *codeptr = addrxlate=>[dest] if not (*codeptr & $8000) // Unresolved address list addrxlate=>[dest] = codeptr - *jitcodeptr fin codeptr = codeptr + 2 - ^codeptr = $E8; codeptr++ // INX - ^codeptr = $E8; codeptr++ // INX + ^codeptr = $E8; codeptr++ // INX + ^codeptr = $E8; codeptr++ // INX break is $A6 i++ @@ -1204,45 +1348,45 @@ def compiler(defptr)#0 // // ADD // - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $18; codeptr++ // CLC - ^codeptr = $75; codeptr++ // ADC zp,X - ^codeptr = $D0+1; codeptr++ // ESTKL+1 - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+1; codeptr++ // ESTKL+1 - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $C0; codeptr++ // ESTKH - ^codeptr = $75; codeptr++ // ADC zp,X - ^codeptr = $C0+1; codeptr++ // ESTKH+1 - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0+1; codeptr++ // ESTKH+1 - ^codeptr = $E8; codeptr++ // INX + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $18; codeptr++ // CLC + ^codeptr = $75; codeptr++ // ADC zp,X + ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH + ^codeptr = $75; codeptr++ // ADC zp,X + ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + ^codeptr = $E8; codeptr++ // INX // // BRLE // - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+1; codeptr++ // ESTKL+1 - ^codeptr = $D5; codeptr++ // CMP zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $C0+1; codeptr++ // ESTKH+1 - ^codeptr = $F5; codeptr++ // SBC zp,X - ^codeptr = $C0; codeptr++ // ESTKH - ^codeptr = $50; codeptr++ // BVC rel - ^codeptr = $02; codeptr++ // +2 - ^codeptr = $49; codeptr++ // EOR #imm - ^codeptr = $80; codeptr++ // $80 - ^codeptr = $30; codeptr++ // BMI rel - ^codeptr = $03; codeptr++ // +3 - ^codeptr = $4C; codeptr++ // JMP abs + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + ^codeptr = $D5; codeptr++ // CMP zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + ^codeptr = $F5; codeptr++ // SBC zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH + ^codeptr = $50; codeptr++ // BVC rel + ^codeptr = $02; codeptr++ // +2 + ^codeptr = $49; codeptr++ // EOR #imm + ^codeptr = $80; codeptr++ // $80 + ^codeptr = $30; codeptr++ // BMI rel + ^codeptr = $03; codeptr++ // +3 + ^codeptr = $4C; codeptr++ // JMP abs *codeptr = addrxlate=>[dest] if not (*codeptr & $8000) // Unresolved address list addrxlate=>[dest] = codeptr - *jitcodeptr fin codeptr = codeptr + 2 - ^codeptr = $E8; codeptr++ // INX - ^codeptr = $E8; codeptr++ // INX + ^codeptr = $E8; codeptr++ // INX + ^codeptr = $E8; codeptr++ // INX break is $A8 i++ @@ -1252,39 +1396,39 @@ def compiler(defptr)#0 // // DECR // - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $D0; codeptr++ // BNE rel - ^codeptr = $02; codeptr++ // +2 - ^codeptr = $D6; codeptr++ // DEC zp,X - ^codeptr = $C0; codeptr++ // ESTKH - ^codeptr = $D6; codeptr++ // DEC zp,X - ^codeptr = $D0; codeptr++ // ESTKL + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $D0; codeptr++ // BNE rel + ^codeptr = $02; codeptr++ // +2 + ^codeptr = $D6; codeptr++ // DEC zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH + ^codeptr = $D6; codeptr++ // DEC zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL // // BRGE // - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $D5; codeptr++ // CMP zp,X - ^codeptr = $D0+1; codeptr++ // ESTKL+1 - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $C0; codeptr++ // ESTKH - ^codeptr = $F5; codeptr++ // SBC zp,X - ^codeptr = $C0+1; codeptr++ // ESTKH+1 - ^codeptr = $50; codeptr++ // BVC rel - ^codeptr = $02; codeptr++ // +2 - ^codeptr = $49; codeptr++ // EOR #imm - ^codeptr = $80; codeptr++ // $80 - ^codeptr = $30; codeptr++ // BMI rel - ^codeptr = $03; codeptr++ // +3 - ^codeptr = $4C; codeptr++ // JMP abs + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $D5; codeptr++ // CMP zp,X + ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH + ^codeptr = $F5; codeptr++ // SBC zp,X + ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + ^codeptr = $50; codeptr++ // BVC rel + ^codeptr = $02; codeptr++ // +2 + ^codeptr = $49; codeptr++ // EOR #imm + ^codeptr = $80; codeptr++ // $80 + ^codeptr = $30; codeptr++ // BMI rel + ^codeptr = $03; codeptr++ // +3 + ^codeptr = $4C; codeptr++ // JMP abs *codeptr = addrxlate=>[dest] if not (*codeptr & $8000) // Unresolved address list addrxlate=>[dest] = codeptr - *jitcodeptr fin codeptr = codeptr + 2 - ^codeptr = $E8; codeptr++ // INX - ^codeptr = $E8; codeptr++ // INX + ^codeptr = $E8; codeptr++ // INX + ^codeptr = $E8; codeptr++ // INX break is $AA i++ @@ -1294,258 +1438,258 @@ def compiler(defptr)#0 // // SUB // - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+1; codeptr++ // ESTKL+1 - ^codeptr = $38; codeptr++ // SEC - ^codeptr = $F5; codeptr++ // SBC zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+1; codeptr++ // ESTKL+1 - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $C0+1; codeptr++ // ESTKH+1 - ^codeptr = $F5; codeptr++ // SBC zp,X - ^codeptr = $C0; codeptr++ // ESTKH - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0+1; codeptr++ // ESTKH+1 - ^codeptr = $E8; codeptr++ // INX + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + ^codeptr = $38; codeptr++ // SEC + ^codeptr = $F5; codeptr++ // SBC zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + ^codeptr = $F5; codeptr++ // SBC zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + ^codeptr = $E8; codeptr++ // INX // // BRGE // - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $D5; codeptr++ // CMP zp,X - ^codeptr = $D0+1; codeptr++ // ESTKL+1 - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $C0; codeptr++ // ESTKH - ^codeptr = $F5; codeptr++ // SBC zp,X - ^codeptr = $C0+1; codeptr++ // ESTKH+1 - ^codeptr = $50; codeptr++ // BVC rel - ^codeptr = $02; codeptr++ // +2 - ^codeptr = $49; codeptr++ // EOR #imm - ^codeptr = $80; codeptr++ // $80 - ^codeptr = $30; codeptr++ // BMI rel - ^codeptr = $03; codeptr++ // +3 - ^codeptr = $4C; codeptr++ // JMP abs + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $D5; codeptr++ // CMP zp,X + ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH + ^codeptr = $F5; codeptr++ // SBC zp,X + ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + ^codeptr = $50; codeptr++ // BVC rel + ^codeptr = $02; codeptr++ // +2 + ^codeptr = $49; codeptr++ // EOR #imm + ^codeptr = $80; codeptr++ // $80 + ^codeptr = $30; codeptr++ // BMI rel + ^codeptr = $03; codeptr++ // +3 + ^codeptr = $4C; codeptr++ // JMP abs *codeptr = addrxlate=>[dest] if not (*codeptr & $8000) // Unresolved address list addrxlate=>[dest] = codeptr - *jitcodeptr fin codeptr = codeptr + 2 - ^codeptr = $E8; codeptr++ // INX - ^codeptr = $E8; codeptr++ // INX + ^codeptr = $E8; codeptr++ // INX + ^codeptr = $E8; codeptr++ // INX break is $AC i++ dest = i + *(bytecode+i) i++ //puts("BRAND "); puti(dest) - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $15; codeptr++ // ORA zp,X - ^codeptr = $C0; codeptr++ // ESTKH - ^codeptr = $D0; codeptr++ // BNE rel - ^codeptr = $03; codeptr++ // +3 - ^codeptr = $4C; codeptr++ // JMP abs + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $15; codeptr++ // ORA zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH + ^codeptr = $D0; codeptr++ // BNE rel + ^codeptr = $03; codeptr++ // +3 + ^codeptr = $4C; codeptr++ // JMP abs *codeptr = addrxlate=>[dest] if not (*codeptr & $8000) // Unresolved address list addrxlate=>[dest] = codeptr - *jitcodeptr fin codeptr = codeptr + 2 - ^codeptr = $E8; codeptr++ // INX + ^codeptr = $E8; codeptr++ // INX break is $AE i++ dest = i + *(bytecode+i) i++ //puts("BROR "); puti(dest) - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $15; codeptr++ // ORA zp,X - ^codeptr = $C0; codeptr++ // ESTKH - ^codeptr = $F0; codeptr++ // BEQ rel - ^codeptr = $03; codeptr++ // +3 - ^codeptr = $4C; codeptr++ // JMP abs + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $15; codeptr++ // ORA zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH + ^codeptr = $F0; codeptr++ // BEQ rel + ^codeptr = $03; codeptr++ // +3 + ^codeptr = $4C; codeptr++ // JMP abs *codeptr = addrxlate=>[dest] if not (*codeptr & $8000) // Unresolved address list addrxlate=>[dest] = codeptr - *jitcodeptr fin codeptr = codeptr + 2 - ^codeptr = $E8; codeptr++ // INX + ^codeptr = $E8; codeptr++ // INX break // ADDLB,ADDLW,ADDAB,ADDAW,IDXLB,IDXLW,IDXAB,IDXAW ; B0 B2 B4 B6 B8 BA BC BE is $B0 i++ //puts("ADDLB "); puti(^(bytecode+i)) - ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = ^(bytecode+i); codeptr++ - ^codeptr = $B1; codeptr++ // LDA (zp),Y - ^codeptr = $E0; codeptr++ // IFP - ^codeptr = $18; codeptr++ // CLC - ^codeptr = $75; codeptr++ // ADC zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $90; codeptr++ // BCC rel - ^codeptr = $02; codeptr++ // +2 - ^codeptr = $F6; codeptr++ // INC zp,X - ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $B1; codeptr++ // LDA (zp),Y + ^codeptr = $E0; codeptr++ // IFP + ^codeptr = $18; codeptr++ // CLC + ^codeptr = $75; codeptr++ // ADC zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $90; codeptr++ // BCC rel + ^codeptr = $02; codeptr++ // +2 + ^codeptr = $F6; codeptr++ // INC zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH break is $B2 i++ //puts("ADDLW "); puti(^(bytecode+i)) - ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = ^(bytecode+i); codeptr++ - ^codeptr = $B1; codeptr++ // LDA (zp),Y - ^codeptr = $E0; codeptr++ // IFP - ^codeptr = $18; codeptr++ // CLC - ^codeptr = $75; codeptr++ // ADC zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $C8; codeptr++ // INY - ^codeptr = $B1; codeptr++ // LDA (zp),Y - ^codeptr = $E0; codeptr++ // IFP - ^codeptr = $75; codeptr++ // ADC zp,X - ^codeptr = $C0; codeptr++ // ESTKH - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $B1; codeptr++ // LDA (zp),Y + ^codeptr = $E0; codeptr++ // IFP + ^codeptr = $18; codeptr++ // CLC + ^codeptr = $75; codeptr++ // ADC zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $C8; codeptr++ // INY + ^codeptr = $B1; codeptr++ // LDA (zp),Y + ^codeptr = $E0; codeptr++ // IFP + ^codeptr = $75; codeptr++ // ADC zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH break is $B4 i++ //puts("ADDAB $"); puth(*(bytecode+i)) - ^codeptr = $AD; codeptr++ // LDA abs + ^codeptr = $AD; codeptr++ // LDA abs *codeptr = *(bytecode+i); codeptr = codeptr + 2 - ^codeptr = $18; codeptr++ // CLC - ^codeptr = $75; codeptr++ // ADC zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $90; codeptr++ // BCC rel - ^codeptr = $02; codeptr++ // +2 - ^codeptr = $F6; codeptr++ // INC zp,X - ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $18; codeptr++ // CLC + ^codeptr = $75; codeptr++ // ADC zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $90; codeptr++ // BCC rel + ^codeptr = $02; codeptr++ // +2 + ^codeptr = $F6; codeptr++ // INC zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH i++ break is $B6 i++ //puts("ADDAW $"); puth(*(bytecode+i)) - ^codeptr = $AD; codeptr++ // LDA abs + ^codeptr = $AD; codeptr++ // LDA abs *codeptr = *(bytecode+i); codeptr = codeptr + 2 - ^codeptr = $18; codeptr++ // CLC - ^codeptr = $75; codeptr++ // ADC zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $AD; codeptr++ // LDA abs + ^codeptr = $18; codeptr++ // CLC + ^codeptr = $75; codeptr++ // ADC zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $AD; codeptr++ // LDA abs *codeptr = *(bytecode+i)+1; codeptr = codeptr + 2 - ^codeptr = $75; codeptr++ // ADC zp,X - ^codeptr = $C0; codeptr++ // ESTKH - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $75; codeptr++ // ADC zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH i++ break is $B8 i++ //puts("IDXLB "); puti(^(bytecode+i)) - ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = ^(bytecode+i); codeptr++ - ^codeptr = $B1; codeptr++ // LDA (zp),Y - ^codeptr = $E0; codeptr++ // IFP - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = $00; codeptr++ // $00 - ^codeptr = $0A; codeptr++ // ASL - ^codeptr = $90; codeptr++ // BCC rel - ^codeptr = $02; codeptr++ // +2 - ^codeptr = $C8; codeptr++ // INY - ^codeptr = $18; codeptr++ // CLC - ^codeptr = $75; codeptr++ // ADC zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $98; codeptr++ // TYA - ^codeptr = $75; codeptr++ // ADC zp,X - ^codeptr = $C0; codeptr++ // ESTKH - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $B1; codeptr++ // LDA (zp),Y + ^codeptr = $E0; codeptr++ // IFP + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $00; codeptr++ // $00 + ^codeptr = $0A; codeptr++ // ASL + ^codeptr = $90; codeptr++ // BCC rel + ^codeptr = $02; codeptr++ // +2 + ^codeptr = $C8; codeptr++ // INY + ^codeptr = $18; codeptr++ // CLC + ^codeptr = $75; codeptr++ // ADC zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $98; codeptr++ // TYA + ^codeptr = $75; codeptr++ // ADC zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH break is $BA i++ //puts("IDXLW "); puti(^(bytecode+i)) - ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = ^(bytecode+i); codeptr++ - ^codeptr = $B1; codeptr++ // LDA (zp),Y - ^codeptr = $E0; codeptr++ // IFP - ^codeptr = $0A; codeptr++ // ASL - ^codeptr = $85; codeptr++ // STA zp - ^codeptr = $E7; codeptr++ // $E7:TMPL - ^codeptr = $C8; codeptr++ // INY - ^codeptr = $B1; codeptr++ // LDA (zp),Y - ^codeptr = $E0; codeptr++ // IFP - ^codeptr = $2A; codeptr++ // ROL - ^codeptr = $A8; codeptr++ // TAY - ^codeptr = $A5; codeptr++ // LDA zp - ^codeptr = $E7; codeptr++ // $E7:TMPL - ^codeptr = $18; codeptr++ // CLC - ^codeptr = $75; codeptr++ // ADC zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $98; codeptr++ // TYA - ^codeptr = $75; codeptr++ // ADC zp,X - ^codeptr = $C0; codeptr++ // ESTKH - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $B1; codeptr++ // LDA (zp),Y + ^codeptr = $E0; codeptr++ // IFP + ^codeptr = $0A; codeptr++ // ASL + ^codeptr = $85; codeptr++ // STA zp + ^codeptr = $E7; codeptr++ // $E7:TMPL + ^codeptr = $C8; codeptr++ // INY + ^codeptr = $B1; codeptr++ // LDA (zp),Y + ^codeptr = $E0; codeptr++ // IFP + ^codeptr = $2A; codeptr++ // ROL + ^codeptr = $A8; codeptr++ // TAY + ^codeptr = $A5; codeptr++ // LDA zp + ^codeptr = $E7; codeptr++ // $E7:TMPL + ^codeptr = $18; codeptr++ // CLC + ^codeptr = $75; codeptr++ // ADC zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $98; codeptr++ // TYA + ^codeptr = $75; codeptr++ // ADC zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH break is $BC i++ //puts("IDXAB $"); puth(*(bytecode+i)) - ^codeptr = $AD; codeptr++ // LDA abs + ^codeptr = $AD; codeptr++ // LDA abs *codeptr = *(bytecode+i); codeptr = codeptr + 2 - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = $00; codeptr++ // $00 - ^codeptr = $0A; codeptr++ // ASL - ^codeptr = $90; codeptr++ // BCC rel - ^codeptr = $02; codeptr++ // +2 - ^codeptr = $C8; codeptr++ // INY - ^codeptr = $18; codeptr++ // CLC - ^codeptr = $75; codeptr++ // ADC zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $98; codeptr++ // TYA - ^codeptr = $75; codeptr++ // ADC zp,X - ^codeptr = $C0; codeptr++ // ESTKH - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $00; codeptr++ // $00 + ^codeptr = $0A; codeptr++ // ASL + ^codeptr = $90; codeptr++ // BCC rel + ^codeptr = $02; codeptr++ // +2 + ^codeptr = $C8; codeptr++ // INY + ^codeptr = $18; codeptr++ // CLC + ^codeptr = $75; codeptr++ // ADC zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $98; codeptr++ // TYA + ^codeptr = $75; codeptr++ // ADC zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH i++ break is $BE i++ //puts("IDXAW $"); puth(*(bytecode+i)) - ^codeptr = $AD; codeptr++ // LDA abs + ^codeptr = $AD; codeptr++ // LDA abs *codeptr = *(bytecode+i); codeptr = codeptr + 2 - ^codeptr = $0A; codeptr++ // ASL - ^codeptr = $85; codeptr++ // STA zp - ^codeptr = $E7; codeptr++ // $E7:TMPL - ^codeptr = $AD; codeptr++ // LDA abs + ^codeptr = $0A; codeptr++ // ASL + ^codeptr = $85; codeptr++ // STA zp + ^codeptr = $E7; codeptr++ // $E7:TMPL + ^codeptr = $AD; codeptr++ // LDA abs *codeptr = *(bytecode+i)+1; codeptr = codeptr + 2 - ^codeptr = $2A; codeptr++ // ROL - ^codeptr = $A8; codeptr++ // TAY - ^codeptr = $A5; codeptr++ // LDA zp - ^codeptr = $E7; codeptr++ // $E7:TMPL - ^codeptr = $18; codeptr++ // CLC - ^codeptr = $75; codeptr++ // ADC zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0; codeptr++ // ESTKL - ^codeptr = $98; codeptr++ // TYA - ^codeptr = $75; codeptr++ // ADC zp,X - ^codeptr = $C0; codeptr++ // ESTKH - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0; codeptr++ // ESTKH + ^codeptr = $2A; codeptr++ // ROL + ^codeptr = $A8; codeptr++ // TAY + ^codeptr = $A5; codeptr++ // LDA zp + ^codeptr = $E7; codeptr++ // $E7:TMPL + ^codeptr = $18; codeptr++ // CLC + ^codeptr = $75; codeptr++ // ADC zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $98; codeptr++ // TYA + ^codeptr = $75; codeptr++ // ADC zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH i++ break - is $FF // NOPed out earlier by SELect + is $FE // NOPed out earlier by SELect break otherwise //putc('$'); puth(^(bytecode+i)) @@ -1563,7 +1707,7 @@ def compiler(defptr)#0 // // Free working bufffers // - heaprelease(addrxlate) + //heaprelease(addrxlate) //puts("Done compiling: $"); puth(defptr=>interpaddr); putln //getc return @@ -1578,7 +1722,7 @@ def compiler(defptr)#0 // // Free working bufffers // - heaprelease(addrxlate) + //heaprelease(addrxlate) //puts("Ran out of code buffer\n") //getc end diff --git a/src/libsrc/apple/jitune.pla b/src/libsrc/apple/jitune.pla index 9ca8fc6..910e64e 100644 --- a/src/libsrc/apple/jitune.pla +++ b/src/libsrc/apple/jitune.pla @@ -1,38 +1,50 @@ // -// PLASMA JIT bytecode compiler +// PLASMA JIT bytecode compiler tuner // include "inc/cmdsys.plh" include "inc/args.plh" -const jitcount = syserr+1 -const jitsize = jitcount+1 -const jitwarmup = jitsize+1 -word arg +var arg, val def atoi(strptr) - word num - num = 0 + var num, len - if ^strptr < '0' or ^strptr > '9' - repeat - num = num * 10 + ^strptr - '0' - strptr++ - until ^strptr < '0' or ^strptr > '9' - fin + num = 0 + len = ^strptr + strptr++ + while len and ^strptr >= '0' and ^strptr <= '9' + num = num * 10 + ^strptr - '0' + strptr++ + len-- + loop return num end arg = argNext(argFirst) if ^arg - cmdsys.jitcount = atoi(arg) - arg = argNext(arg) - if ^arg - cmdsys:warmup = atoi(arg) + if arg->1 >= '0' and arg->1 <= '9' + cmdsys:jitwarmup = atoi(arg) arg = argNext(arg) if ^arg - cmdsys.jitsize = atoi(arg) + val = atoi(arg) + if val > 255 + val = 255 + fin + cmdsys.jitcount = val + arg = argNext(arg) + if ^arg + val = atoi(arg) + if val > 255 + val = 255 + fin + cmdsys.jitsize = val + fin fin + else + puts("Usage: JITUNE WARMUP [CALLCOUNT [MAXSIZE]]\n") fin -else - puts("Usage: JITUNE CALLCOUNT [WARMUP [MAXSIZE]]\n") fin +puts("JIT Warm Up: "); puti(cmdsys:jitwarmup); putln +puts("JIT Call Count: "); puti(cmdsys.jitcount); putln +puts("JIT Max Size: "); puti(cmdsys.jitsize); putln +done diff --git a/src/makefile b/src/makefile index 48a8ba8..3c2fd58 100755 --- a/src/makefile +++ b/src/makefile @@ -14,6 +14,7 @@ PLVMZP_C64 = vmsrc/c64/plvmzp.inc PLVMC64 = rel/c64/PLASMA ED = rel/ED\#FE1000 JIT = rel/apple/JIT\#FE1000 +JITUNE = rel/apple/JITUNE\#FE1000 SOS = rel/apple/SOS\#FE1000 ROD = rel/ROD\#FE1000 SIEVE = rel/SIEVE\#FE1000 @@ -79,7 +80,7 @@ TXTTYPE = .TXT #SYSTYPE = \#FF2000 #TXTTYPE = \#040000 -apple: $(PLVMZP_APL) $(PLASM) $(PLVM) $(PLVM01) $(PLVM02) $(PLVMJIT) $(PLVM802) $(PLVM03) $(CMD) $(CMDJIT) $(JIT) $(SOSCMD) $(PLASMAPLASM) $(CODEOPT) $(ARGS) $(MEMMGR) $(MEMTEST) $(FIBER) $(FIBERTEST) $(LONGJMP) $(ED) $(MON) $(SOS) $(ROD) $(SIEVE) $(UTHERNET2) $(UTHERNET) $(ETHERIP) $(INET) $(DHCP) $(HTTPD) $(ROGUE) $(ROGUEMAP) $(ROGUECOMBAT) $(GRAFIX) $(GFXDEMO) $(DGR) $(DGRTEST) $(FILEIO_APL) $(CONIO_APL) $(JOYBUZZ) $(PORTIO) $(SPIPORT) $(SDFAT) $(FATCAT) $(FATGET) $(FATPUT) $(FATWDSK) $(FATRDSK) $(SANE) $(FPSTR) $(FPU) $(SANITY) $(RPNCALC) $(SNDSEQ) $(PLAYSEQ) +apple: $(PLVMZP_APL) $(PLASM) $(PLVM) $(PLVM01) $(PLVM02) $(PLVMJIT) $(PLVM802) $(PLVM03) $(CMD) $(CMDJIT) $(JIT) $(JITUNE) $(SOSCMD) $(PLASMAPLASM) $(CODEOPT) $(ARGS) $(MEMMGR) $(MEMTEST) $(FIBER) $(FIBERTEST) $(LONGJMP) $(ED) $(MON) $(SOS) $(ROD) $(SIEVE) $(UTHERNET2) $(UTHERNET) $(ETHERIP) $(INET) $(DHCP) $(HTTPD) $(ROGUE) $(ROGUEMAP) $(ROGUECOMBAT) $(GRAFIX) $(GFXDEMO) $(DGR) $(DGRTEST) $(FILEIO_APL) $(CONIO_APL) $(JOYBUZZ) $(PORTIO) $(SPIPORT) $(SDFAT) $(FATCAT) $(FATGET) $(FATPUT) $(FATWDSK) $(FATRDSK) $(SANE) $(FPSTR) $(FPU) $(SANITY) $(RPNCALC) $(SNDSEQ) $(PLAYSEQ) -rm vmsrc/plvmzp.inc c64: $(PLVMZP_C64) $(PLASM) $(PLVM) $(PLVMC64) @@ -369,4 +370,8 @@ $(JIT): libsrc/apple/jit.pla $(PLVMJIT) $(PLASM) ./$(PLASM) -AMO < libsrc/apple/jit.pla > libsrc/apple/jit.a acme --setpc 4094 -o $(JIT) libsrc/apple/jit.a +$(JITUNE): libsrc/apple/jitune.pla $(PLVMJIT) $(PLASM) + ./$(PLASM) -AMO < libsrc/apple/jitune.pla > libsrc/apple/jitune.a + acme --setpc 4094 -o $(JITUNE) libsrc/apple/jitune.a + diff --git a/src/mkrel b/src/mkrel index 311722b..395ca51 100755 --- a/src/mkrel +++ b/src/mkrel @@ -33,6 +33,7 @@ cp rel/apple/UTHERNET2#FE1000 prodos/sys/UTHERNET2.REL cp rel/apple/SOS#FE1000 prodos/sys/SOS.REL cp rel/apple/GRAFIX#FE1000 prodos/sys/GRAFIX.REL cp rel/apple/JIT#FE1000 prodos/sys/JIT.REL +cp rel/apple/JITUNE#FE1000 prodos/sys/JITUNE.REL cp ../sysfiles/FP6502.CODE#060000 prodos/sys/FP6502.CODE.BIN cp ../sysfiles/ELEMS.CODE#060000 prodos/sys/ELEMS.CODE.BIN diff --git a/src/vmsrc/apple/cmd.pla b/src/vmsrc/apple/cmd.pla index da0a26e..b3c766c 100755 --- a/src/vmsrc/apple/cmd.pla +++ b/src/vmsrc/apple/cmd.pla @@ -43,6 +43,9 @@ word syspath word syscmdln word = @execmod, @open, @close, @read, @write byte perr +byte jitcount = $10 +byte jitsize = $FF +word jitwarmup = $0100 // // Working input buffer overlayed with strings table // @@ -917,9 +920,10 @@ def availheap()#1 return @fp - heap end def allocheap(size)#1 - word addr - addr = heap - heap = heap + size + word oldheap, addr + oldheap = heap + addr = heap + heap = heap + size if systemflags & reshgr1 if uword_islt(addr, $4000) and uword_isgt(heap, $2000) addr = $4000 @@ -933,6 +937,7 @@ def allocheap(size)#1 fin fin if uword_isge(heap, @addr) + heap = oldheap return 0 fin return addr diff --git a/src/vmsrc/apple/cmdjit.pla b/src/vmsrc/apple/cmdjit.pla index 1fa7cb0..ac54e91 100755 --- a/src/vmsrc/apple/cmdjit.pla +++ b/src/vmsrc/apple/cmdjit.pla @@ -60,9 +60,9 @@ word syspath word syscmdln word = @execmod, @open, @close, @read, @write byte perr -byte jitcount = $10 +byte jitcount = $01 byte jitsize = $FF -word jitwarmup = $0100 +word jitwarmup = $0000 // // Working input buffer overlayed with strings table // @@ -941,9 +941,10 @@ def availheap()#1 return @fp - heap end def allocheap(size)#1 - word addr - addr = heap - heap = heap + size + word oldheap, addr + oldheap = heap + addr = heap + heap = heap + size if systemflags & reshgr1 if uword_islt(addr, $4000) and uword_isgt(heap, $2000) addr = $4000 @@ -957,6 +958,7 @@ def allocheap(size)#1 fin fin if uword_isge(heap, @addr) + heap = oldheap return 0 fin return addr diff --git a/src/vmsrc/apple/sossys.pla b/src/vmsrc/apple/sossys.pla index 4dc0ee9..6ee789b 100755 --- a/src/vmsrc/apple/sossys.pla +++ b/src/vmsrc/apple/sossys.pla @@ -34,6 +34,9 @@ word syspath word cmdlnptr word = @execmod, @open, @close, @read, @write byte perr +byte jitcount = $10 +byte jitsize = $FF +word jitwarmup = $0100 byte refcons = 0 byte devcons = 0 word cmdparser @@ -940,6 +943,7 @@ def allocheap(size)#1 addr = heap heap = heap + size if uword_isge(heap, @addr) + heap = addr return 0 fin return addr From 7b201b4392b5943cfc070478b9e680332ce42080 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Thu, 22 Mar 2018 16:11:06 -0700 Subject: [PATCH 081/147] Optimizing JIT WIP --- src/libsrc/apple/jit.pla | 1344 +++++++++++++++++++++++++++----------- 1 file changed, 960 insertions(+), 384 deletions(-) diff --git a/src/libsrc/apple/jit.pla b/src/libsrc/apple/jit.pla index cf101a4..d0470a5 100644 --- a/src/libsrc/apple/jit.pla +++ b/src/libsrc/apple/jit.pla @@ -33,9 +33,9 @@ const interpentry = $03DC // def compiler(defptr)#0 word codeptr, isdata, addrxlate, bytecode, i, case, dest, VX - byte opcode, j + byte opcode, j, A_IS_TOSL - //puts("JIT compiler invoked for :$"); puth(defptr=>bytecodeaddr); putln + puts("JIT compiler invoked for :$"); puth(defptr=>bytecodeaddr); putln if isult(heapavail, 512 + defptr->bytecodesize) // 256 * sizeof(word) address xlate // // Not enough heap available @@ -54,8 +54,8 @@ def compiler(defptr)#0 *$0042 = bytecode call($C311, 0, 0, 0, $00) // CALL XMOVE with carry clear (AUX->MAIN) //^$C053 // MIX TEXT - //puts("Addr Xlate: $"); puth(addrxlate); putln - //puts("Bytecode: $"); puth(bytecode); putln + 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 // @@ -72,7 +72,6 @@ def compiler(defptr)#0 // is $26 // LA is $2C // CW - is $54 // CALL is $68 // LAB is $6A // LAW is $78 // SAB @@ -115,11 +114,12 @@ def compiler(defptr)#0 // // Branches // + is $50 // BRNCH + ^(bytecode+i) = ^(bytecode+i) | 1 is $22 // BREQ is $24 // BENE is $4C // BRFLS is $4E // BRTRU - is $50 // BRNCH is $A0 // BRGT is $A2 // BRLT is $A4 // INCBRLE @@ -139,6 +139,7 @@ def compiler(defptr)#0 // // VM calls // + is $54 // CALL is $58 // ENTER, two byte operands ^(bytecode+i) = ^(bytecode+i) | 1 i = i + 2 @@ -155,7 +156,6 @@ def compiler(defptr)#0 // // External control // - is $54 // CALL is $5C // RET ^(bytecode+i) = ^(bytecode+i) | 1 break @@ -194,6 +194,13 @@ def compiler(defptr)#0 codeptr = *jitcodeptr VX = 0 // Virtual X register i = 0 + // + // First optimization is to keep zero in Y register at all times + // + if ^bytecode <> $58 // ENTER will set Y to zero + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $00; codeptr++ // $00 + fin while isule(codeptr, codemax) // // Update bytecode->native code address translation @@ -210,50 +217,78 @@ def compiler(defptr)#0 until not case fin addrxlate=>[i] = codeptr - //putc('$'); puth(codeptr); putc(':') - //putc('['); puti(i); //puts("] ") + putc('$'); puth(codeptr); putc(':') + putc('['); puti(i); puts("] ") opcode = ^(bytecode+i) if opcode & 1 // // Optimization fence // + if A_IS_TOSL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + A_IS_TOSL = FALSE + fin + while VX > 0 + ^codeptr = $E8; codeptr++ // INX + VX-- + loop + while VX < 0 + ^codeptr = $CA; codeptr++ // DEX + VX++ + loop opcode = opcode & $FE fin if opcode < $20 // CN,CN,CN,CN,CN,CN,CN,CN ; 00 02 04 06 08 0A 0C 0E // CN,CN,CN,CN,CN,CN,CN,CN ; 10 12 14 16 18 1A 1C 1E - //puts("CN $"); putb(^(bytecode+i)/2) - ^codeptr = $CA; codeptr++ // DEX + puts("CN $"); putb(^(bytecode+i)/2) + VX-- //^codeptr = $CA; codeptr++ // DEX ^codeptr = $A9; codeptr++ // LDA #imm ^codeptr = ^(bytecode+i)/2; codeptr++ - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL - ^codeptr = $A9; codeptr++ // LDA #imm - ^codeptr = $00; codeptr++ // $00 - ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $94; codeptr++ // STY zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $D0+VX; codeptr++ // ESTKL + A_IS_TOSL = TRUE else when opcode // MINUS1,BREQ,BRNE,LA,LLA,CB,CW,CS ; 20 22 24 26 28 2A 2C 2E is $20 - //puts("MINUS_ONE") - ^codeptr = $CA; codeptr++ // DEX + puts("MINUS_ONE") + if A_IS_TOSL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin + VX-- //^codeptr = $CA; codeptr++ // DEX ^codeptr = $A9; codeptr++ // LDA #imm ^codeptr = $FF; codeptr++ // $FF ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL - ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $D0+VX; codeptr++ // ESTKL + A_IS_TOSL = TRUE break is $22 i++ dest = i + *(bytecode+i) i++ - //puts("BREQ "); puti(dest) - ^codeptr = $E8; codeptr++ // INX - ^codeptr = $E8; codeptr++ // INX - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0-2+VX; codeptr++ // ESTKL-2 + puts("BREQ "); puti(dest) + //^codeptr = $E8; codeptr++ // INX + //^codeptr = $E8; codeptr++ // INX + VX = VX + 2 + while VX > 0 + ^codeptr = $E8; codeptr++ // INX + VX-- + loop + while VX < 0 + ^codeptr = $CA; codeptr++ // DEX + VX++ + loop + if not A_IS_TOSL + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0-2+VX; codeptr++ // ESTKL-2 + fin ^codeptr = $D5; codeptr++ // CMP zp,X ^codeptr = $D0-1+VX; codeptr++ // ESTKL-1 ^codeptr = $D0; codeptr++ // BNE rel @@ -269,17 +304,29 @@ def compiler(defptr)#0 if not (*codeptr & $8000) // Unresolved address list addrxlate=>[dest] = codeptr - *jitcodeptr fin - codeptr = codeptr + 2 + codeptr = codeptr + 2 + A_IS_TOSL = FALSE break is $24 i++ dest = i + *(bytecode+i) i++ - //puts("BRNE "); puti(dest) - ^codeptr = $E8; codeptr++ // INX - ^codeptr = $E8; codeptr++ // INX - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0-2+VX; codeptr++ // ESTKL-2 + puts("BRNE "); puti(dest) + //^codeptr = $E8; codeptr++ // INX + //^codeptr = $E8; codeptr++ // INX + VX = VX + 2 + while VX > 0 + ^codeptr = $E8; codeptr++ // INX + VX-- + loop + while VX < 0 + ^codeptr = $CA; codeptr++ // DEX + VX++ + loop + if not A_IS_TOSL + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0-2+VX; codeptr++ // ESTKL-2 + fin ^codeptr = $D5; codeptr++ // CMP zp,X ^codeptr = $D0-1+VX; codeptr++ // ESTKL-1 ^codeptr = $D0; codeptr++ // BNE rel @@ -295,26 +342,36 @@ def compiler(defptr)#0 if not (*codeptr & $8000) // Unresolved address list addrxlate=>[dest] = codeptr - *jitcodeptr fin - codeptr = codeptr + 2 + codeptr = codeptr + 2 + A_IS_TOSL = FALSE break is $26 i++ - //puts("LA $"); puth(*(bytecode+i)) - ^codeptr = $CA; codeptr++ // DEX + puts("LA $"); puth(*(bytecode+i)) + if A_IS_TOSL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin + VX-- //^codeptr = $CA; codeptr++ // DEX ^codeptr = $A9; codeptr++ // LDA #imm - ^codeptr = ^(bytecode+i); codeptr++ - i++ - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL - ^codeptr = $A9; codeptr++ // LDA #imm - ^codeptr = ^(bytecode+i); codeptr++ + ^codeptr = ^(bytecode+i+1); codeptr++ ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH + ^codeptr = $A9; codeptr++ // LDA #imm + ^codeptr = ^(bytecode+i); codeptr++ + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $D0+VX; codeptr++ // ESTKL + A_IS_TOSL = TRUE + i++ break is $28 i++ - //puts("LLA "); puti(^(bytecode+i)) - ^codeptr = $CA; codeptr++ // DEX + puts("LLA "); puti(^(bytecode+i)) + if A_IS_TOSL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin + VX-- //^codeptr = $CA; codeptr++ // DEX ^codeptr = $A9; codeptr++ // LDA #imm ^codeptr = ^(bytecode+i); codeptr++ ^codeptr = $18; codeptr++ // CLC @@ -322,47 +379,59 @@ def compiler(defptr)#0 ^codeptr = $E0; codeptr++ // IFPL ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL - ^codeptr = $A9; codeptr++ // LDA #imm - ^codeptr = $00; codeptr++ // $00 + ^codeptr = $98; codeptr++ // TYA -> LDA #$00 ^codeptr = $65; codeptr++ // ADC zp ^codeptr = $E1; codeptr++ // IFPH ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH + A_IS_TOSL = FALSE break is $2A i++ - //puts("CB $"); putb(^(bytecode+i)) - ^codeptr = $CA; codeptr++ // DEX + puts("CB $"); putb(^(bytecode+i)) + if A_IS_TOSL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin + VX-- //^codeptr = $CA; codeptr++ // DEX ^codeptr = $A9; codeptr++ // LDA #imm ^codeptr = ^(bytecode+i); codeptr++ - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL - ^codeptr = $A9; codeptr++ // LDA #imm - ^codeptr = $00; codeptr++ // $00 - ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $94; codeptr++ // STY zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $D0+VX; codeptr++ // ESTKL + A_IS_TOSL = TRUE break is $2C i++ - //puts("CW $"); puth(*(bytecode+i)) - ^codeptr = $CA; codeptr++ // DEX + puts("CW $"); puth(*(bytecode+i)) + if A_IS_TOSL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin + VX-- //^codeptr = $CA; codeptr++ // DEX ^codeptr = $A9; codeptr++ // LDA #imm - ^codeptr = ^(bytecode+i); codeptr++ - i++ - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL - ^codeptr = $A9; codeptr++ // LDA #imm - ^codeptr = ^(bytecode+i); codeptr++ + ^codeptr = ^(bytecode+i+1); codeptr++ ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH + ^codeptr = $A9; codeptr++ // LDA #imm + ^codeptr = ^(bytecode+i); codeptr++ + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $D0+VX; codeptr++ // ESTKL + A_IS_TOSL = TRUE + i++ break is $2E i++ j = ^(bytecode+i) dest = i + j + 1 - //puts("CS "); //puts(bytecode+i); //puts("-->"); puti(dest) + puts("CS "); puts(bytecode+i); puts("-->"); puti(dest) if isule(codeptr + 12 + j, codemax) - ^codeptr = $CA; codeptr++ // DEX + if A_IS_TOSL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin + VX-- //^codeptr = $CA; codeptr++ // DEX ^codeptr = $A9; codeptr++ // LDA #imm ^codeptr = codeptr+10; codeptr++ ^codeptr = $95; codeptr++ // STA zp,X @@ -383,142 +452,179 @@ def compiler(defptr)#0 else codeptr = codeptr + 12 + j // Flag buffer overflow fin + A_IS_TOSL = FALSE break // DROP,DROP2,DUP,DIVMOD,ADDI,SUBI,ANDI,ORI ; 30 32 34 36 38 3A 3C 3E is $30 - //puts("DROP") - ^codeptr = $E8; codeptr++ // INX + puts("DROP") + VX++ //^codeptr = $E8; codeptr++ // INX + A_IS_TOSL = FALSE break is $32 - //puts("DROP2") - ^codeptr = $E8; codeptr++ // INX - ^codeptr = $E8; codeptr++ // INX + puts("DROP2") + //^codeptr = $E8; codeptr++ // INX + //^codeptr = $E8; codeptr++ // INX + VX = VX + 2 + A_IS_TOSL = FALSE break is $34 - //puts("DUP") - ^codeptr = $CA; codeptr++ // DEX - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + puts("DUP") + if A_IS_TOSL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin + VX-- //^codeptr = $CA; codeptr++ // DEX ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $D0+VX; codeptr++ // ESTKL + A_IS_TOSL = TRUE break is $36 - //puts("DIVMOD") + puts("DIVMOD") // // Should never happen // break is $38 i++ - //puts("ADDI $"); putb(^(bytecode+i)) - ^codeptr = $A9; codeptr++ // LDA #imm - ^codeptr = ^(bytecode+i); codeptr++ + puts("ADDI $"); putb(^(bytecode+i)) + if not A_IS_TOSL + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin ^codeptr = $18; codeptr++ // CLC - ^codeptr = $75; codeptr++ // ADC zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $69; codeptr++ // ADC #imm + ^codeptr = ^(bytecode+i); codeptr++ ^codeptr = $90; codeptr++ // BCC rel ^codeptr = $02; codeptr++ // +2 ^codeptr = $F6; codeptr++ // INC zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $D0+VX; codeptr++ // ESTKL + A_IS_TOSL = TRUE break is $3A i++ - //puts("SUBI $"); putb(^(bytecode+i)) - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + puts("SUBI $"); putb(^(bytecode+i)) + if not A_IS_TOSL + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin ^codeptr = $38; codeptr++ // SEC ^codeptr = $E9; codeptr++ // SBC #imm ^codeptr = ^(bytecode+i); codeptr++ - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL ^codeptr = $B0; codeptr++ // BCS rel ^codeptr = $02; codeptr++ // +2 ^codeptr = $D6; codeptr++ // DEC zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $D0+VX; codeptr++ // ESTKL + A_IS_TOSL = TRUE break is $3C i++ - //puts("ANDI $"); putb(^(bytecode+i)) - ^codeptr = $A9; codeptr++ // LDA #imm + puts("ANDI $"); putb(^(bytecode+i)) + if not A_IS_TOSL + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin + ^codeptr = $29; codeptr++ // AND #imm ^codeptr = ^(bytecode+i); codeptr++ - ^codeptr = $35; codeptr++ // AND zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL - ^codeptr = $A9; codeptr++ // LDA #imm - ^codeptr = $00; codeptr++ // $00 - ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $94; codeptr++ // STY zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $D0+VX; codeptr++ // ESTKL + A_IS_TOSL = TRUE break is $3E i++ - //puts("ORI $"); putb(^(bytecode+i)) - ^codeptr = $A9; codeptr++ // LDA #imm + puts("ORI $"); putb(^(bytecode+i)) + if not A_IS_TOSL + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin + ^codeptr = $09; codeptr++ // ORA #imm ^codeptr = ^(bytecode+i); codeptr++ - ^codeptr = $15; codeptr++ // ORA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $D0+VX; codeptr++ // ESTKL + A_IS_TOSL = TRUE break // ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E is $40 - //puts("ISEQ") - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = $00; codeptr++ // $00 - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + puts("ISEQ") + if not A_IS_TOSL + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin ^codeptr = $D5; codeptr++ // CMP zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 ^codeptr = $D0; codeptr++ // BNE rel ^codeptr = $07; codeptr++ // +7 ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - ^codeptr = $D5; codeptr++ // CMP zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH + ^codeptr = $D5; codeptr++ // CMP zp,X + ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 ^codeptr = $D0; codeptr++ // BNE rel ^codeptr = $01; codeptr++ // +1 ^codeptr = $88; codeptr++ // DEY - ^codeptr = $94; codeptr++ // STY zp,X - ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + ^codeptr = $98; codeptr++ // TYA ^codeptr = $94; codeptr++ // STY zp,X ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - ^codeptr = $E8; codeptr++ // INX + // + // Reload zero into Y + // + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $00; codeptr++ // $00 + VX++ //^codeptr = $E8; codeptr++ // INX + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $D0+VX; codeptr++ // ESTKL + A_IS_TOSL = TRUE break is $42 - //puts("ISNE") + puts("ISNE") + if not A_IS_TOSL + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = $FF; codeptr++ // $FF - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 ^codeptr = $D5; codeptr++ // CMP zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 ^codeptr = $D0; codeptr++ // BNE rel ^codeptr = $07; codeptr++ // +7 ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - ^codeptr = $D5; codeptr++ // CMP zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH + ^codeptr = $D5; codeptr++ // CMP zp,X + ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 ^codeptr = $D0; codeptr++ // BNE rel ^codeptr = $01; codeptr++ // +1 ^codeptr = $C8; codeptr++ // INY - ^codeptr = $94; codeptr++ // STY zp,X - ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + ^codeptr = $98; codeptr++ // TYA ^codeptr = $94; codeptr++ // STY zp,X ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - ^codeptr = $E8; codeptr++ // INX + // + // Reload zero into Y + // + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $00; codeptr++ // $00 + VX++ //^codeptr = $E8; codeptr++ // INX + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $D0+VX; codeptr++ // ESTKL + A_IS_TOSL = TRUE break is $44 - //puts("ISGT") + puts("ISGT") + if not A_IS_TOSL + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = $FF; codeptr++ // $FF - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL ^codeptr = $D5; codeptr++ // CMP zp,X ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 ^codeptr = $B5; codeptr++ // LDA zp,X @@ -532,14 +638,25 @@ def compiler(defptr)#0 ^codeptr = $30; codeptr++ // BMI rel ^codeptr = $01; codeptr++ // +1 ^codeptr = $C8; codeptr++ // INY - ^codeptr = $94; codeptr++ // STY zp,X - ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + ^codeptr = $98; codeptr++ // TYA ^codeptr = $94; codeptr++ // STY zp,X ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - ^codeptr = $E8; codeptr++ // INX + // + // Reload zero into Y + // + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $00; codeptr++ // $00 + VX++ //^codeptr = $E8; codeptr++ // INX + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $D0+VX; codeptr++ // ESTKL + A_IS_TOSL = TRUE break is $46 - //puts("ISLT") + puts("ISLT") + if A_IS_TOSL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = $FF; codeptr++ // $FF ^codeptr = $B5; codeptr++ // LDA zp,X @@ -557,14 +674,25 @@ def compiler(defptr)#0 ^codeptr = $30; codeptr++ // BMI rel ^codeptr = $01; codeptr++ // +1 ^codeptr = $C8; codeptr++ // INY - ^codeptr = $94; codeptr++ // STY zp,X - ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + ^codeptr = $98; codeptr++ // TYA ^codeptr = $94; codeptr++ // STY zp,X ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - ^codeptr = $E8; codeptr++ // INX + // + // Reload zero into Y + // + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $00; codeptr++ // $00 + VX++ //^codeptr = $E8; codeptr++ // INX + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $D0+VX; codeptr++ // ESTKL + A_IS_TOSL = TRUE break is $48 - //puts("ISGE") + puts("ISGE") + if A_IS_TOSL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = $FF; codeptr++ // $FF ^codeptr = $B5; codeptr++ // LDA zp,X @@ -582,18 +710,27 @@ def compiler(defptr)#0 ^codeptr = $10; codeptr++ // BPL rel ^codeptr = $01; codeptr++ // +1 ^codeptr = $C8; codeptr++ // INY - ^codeptr = $94; codeptr++ // STY zp,X - ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + ^codeptr = $98; codeptr++ // TYA ^codeptr = $94; codeptr++ // STY zp,X ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - ^codeptr = $E8; codeptr++ // INX + // + // Reload zero into Y + // + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $00; codeptr++ // $00 + VX++ //^codeptr = $E8; codeptr++ // INX + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $D0+VX; codeptr++ // ESTKL + A_IS_TOSL = TRUE break is $4A - //puts("ISLE") + puts("ISLE") + if A_IS_TOSL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = $FF; codeptr++ // $FF - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL ^codeptr = $D5; codeptr++ // CMP zp,X ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 ^codeptr = $B5; codeptr++ // LDA zp,X @@ -607,20 +744,37 @@ def compiler(defptr)#0 ^codeptr = $10; codeptr++ // BPL rel ^codeptr = $01; codeptr++ // +1 ^codeptr = $C8; codeptr++ // INY - ^codeptr = $94; codeptr++ // STY zp,X - ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + ^codeptr = $98; codeptr++ // TYA ^codeptr = $94; codeptr++ // STY zp,X ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - ^codeptr = $E8; codeptr++ // INX + // + // Reload zero into Y + // + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $00; codeptr++ // $00 + VX++ //^codeptr = $E8; codeptr++ // INX + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $D0+VX; codeptr++ // ESTKL + A_IS_TOSL = TRUE break is $4C i++ dest = i + *(bytecode+i) i++ - //puts("BRFLS "); puti(dest) - ^codeptr = $E8; codeptr++ // INX - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0-1+VX; codeptr++ // ESTKL-1 + puts("BRFLS "); puti(dest) + VX++ //^codeptr = $E8; codeptr++ // INX + while VX > 0 + ^codeptr = $E8; codeptr++ // INX + VX-- + loop + while VX < 0 + ^codeptr = $CA; codeptr++ // DEX + VX++ + loop + if not A_IS_TOSL + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0-1+VX; codeptr++ // ESTKL-1 + fin ^codeptr = $15; codeptr++ // ORA zp,X ^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 ^codeptr = $D0; codeptr++ // BNE rel @@ -630,16 +784,27 @@ def compiler(defptr)#0 if not (*codeptr & $8000) // Unresolved address list addrxlate=>[dest] = codeptr - *jitcodeptr fin - codeptr = codeptr + 2 + codeptr = codeptr + 2 + A_IS_TOSL = FALSE break is $4E i++ dest = i + *(bytecode+i) i++ - //puts("BRTRU "); puti(dest) - ^codeptr = $E8; codeptr++ // INX - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0-1+VX; codeptr++ // ESTKL-1 + puts("BRTRU "); puti(dest) + VX++ //^codeptr = $E8; codeptr++ // INX + while VX > 0 + ^codeptr = $E8; codeptr++ // INX + VX-- + loop + while VX < 0 + ^codeptr = $CA; codeptr++ // DEX + VX++ + loop + if not A_IS_TOSL + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0-1+VX; codeptr++ // ESTKL-1 + fin ^codeptr = $15; codeptr++ // ORA zp,X ^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 ^codeptr = $F0; codeptr++ // BEQ rel @@ -649,50 +814,67 @@ def compiler(defptr)#0 if not (*codeptr & $8000) // Unresolved address list addrxlate=>[dest] = codeptr - *jitcodeptr fin - codeptr = codeptr + 2 + codeptr = codeptr + 2 + A_IS_TOSL = FALSE break // BRNCH,SEL,CALL,ICAL,ENTER,LEAVE,RET,CFFB ; 50 52 54 56 58 5A 5C 5E is $50 i++ dest = i + *(bytecode+i) i++ - //puts("BRNCH "); puti(dest) + puts("BRNCH "); puti(dest) ^codeptr = $4C; codeptr++ // JMP abs *codeptr = addrxlate=>[dest] if not (*codeptr & $8000) // Unresolved address list addrxlate=>[dest] = codeptr - *jitcodeptr fin codeptr = codeptr + 2 + A_IS_TOSL = FALSE break is $52 i++ case = i + *(bytecode+i) i++ - //puts("SEL "); puti(case); putln + puts("SEL "); puti(case); putln j = ^(bytecode+case) dest = codeptr + 8 + case * 11) if isule(dest, codemax) ^(bytecode+case) = $FE // Flag as NOP case++ - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + if not A_IS_TOSL + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin ^codeptr = $B4; codeptr++ // LDY zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH - ^codeptr = $E8; codeptr++ // INX + VX++ //^codeptr = $E8; codeptr++ // INX + while VX > 0 + ^codeptr = $E8; codeptr++ // INX + VX-- + loop + while VX < 0 + ^codeptr = $CA; codeptr++ // DEX + VX++ + loop repeat - //puts(" $"); puth(*(bytecode+case)) + puts(" $"); puth(*(bytecode+case)) ^codeptr = $C9; codeptr++ // CMP #imm ^codeptr = ^(bytecode+case); codeptr++ ^codeptr = $D0; codeptr++ // BNE rel - ^codeptr = $07; codeptr++ // +7 + ^codeptr = $09; codeptr++ // +9 ^codeptr = $C0; codeptr++ // CPY #imm ^codeptr = ^(bytecode+case+1); codeptr++ ^codeptr = $D0; codeptr++ // BNE rel - ^codeptr = $03; codeptr++ // +3 + ^codeptr = $05; codeptr++ // +5 *(bytecode+case) = $FEFE case = case + 2 dest = case + *(bytecode+case) - //puts("-->"); puti(dest); putln + puts("-->"); puti(dest); putln + // + // Reload zero into Y + // + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $00; codeptr++ // $00 ^codeptr = $4C; codeptr++ // JMP abs *codeptr = addrxlate=>[dest] if not (*codeptr & $8000) // Unresolved address list @@ -703,6 +885,11 @@ def compiler(defptr)#0 case = case + 2 j-- until not j + // + // Reload zero into Y + // + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $00; codeptr++ // $00 ^codeptr = $4C; codeptr++ // JMP abs *codeptr = addrxlate=>[case] if not (*codeptr & $8000) // Unresolved address list @@ -712,45 +899,64 @@ def compiler(defptr)#0 else codeptr = dest fin + A_IS_TOSL = FALSE break is $54 i++ - //puts("CALL $"); puth(*(bytecode+i)) + puts("CALL $"); puth(*(bytecode+i)) // // Call address // ^codeptr = $20; codeptr++ // JSR abs *codeptr = *(bytecode+i); codeptr = codeptr + 2 + // + // Reload zero into Y + // + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $00; codeptr++ // $00 + A_IS_TOSL = FALSE i++ break is $56 - //puts("ICAL") + puts("ICAL") // // Pull address off stack // - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + if not A_IS_TOSL + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin ^codeptr = $85; codeptr++ // STA zp ^codeptr = $E7; codeptr++ // $E7:TMPL ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH ^codeptr = $85; codeptr++ // STA zp ^codeptr = $E8; codeptr++ // $E8:TMPH - ^codeptr = $E8; codeptr++ // INX - // - // Resolve VX - // - + VX++ //^codeptr = $E8; codeptr++ // INX + while VX > 0 + ^codeptr = $E8; codeptr++ // INX + VX-- + loop + while VX < 0 + ^codeptr = $CA; codeptr++ // DEX + VX++ + loop // // Call through TMP // ^codeptr = $20; codeptr++ // JSR abs ^codeptr = $E6; codeptr++ // JMPTMP + // + // Reload zero into Y + // + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $00; codeptr++ // $00 + A_IS_TOSL = FALSE break is $58 i++ - //puts("ENTER "); puti(^(bytecode+i)); putc(',');puti(^(bytecode+i+1)) + puts("ENTER "); puti(^(bytecode+i)); putc(',');puti(^(bytecode+i+1)) // // Call into VM // @@ -761,10 +967,16 @@ def compiler(defptr)#0 i++ ^codeptr = ^(bytecode+i); codeptr++ // ENTER ARG COUNT ^codeptr = $C0; codeptr++ // NATV CODE + // + // Reload zero into Y + // + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $00; codeptr++ // $00 + A_IS_TOSL = FALSE break is $5A i++ - //puts("LEAVE "); puti(^(bytecode+i)) + puts("LEAVE "); puti(^(bytecode+i)) // // Call into VM // @@ -772,44 +984,54 @@ def compiler(defptr)#0 *codeptr = $3D0; codeptr = codeptr + 2 ^codeptr = $5A; codeptr++ // LEAVE CODE ^codeptr = ^(bytecode+i); codeptr++ // LEAVE OPERAND + A_IS_TOSL = FALSE break is $5C - //puts("RET") + puts("RET") ^codeptr = $60; codeptr++ // RTS + A_IS_TOSL = FALSE break is $5E i++ - //puts("CFFB $FF"); putb(^(bytecode+i)) - ^codeptr = $CA; codeptr++ // DEX - ^codeptr = $A9; codeptr++ // LDA #imm - ^codeptr = ^(bytecode+i); codeptr++ - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + puts("CFFB $FF"); putb(^(bytecode+i)) + if A_IS_TOSL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin + VX-- //^codeptr = $CA; codeptr++ // DEX ^codeptr = $A9; codeptr++ // LDA #imm ^codeptr = $FF; codeptr++ // $FF ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH + ^codeptr = $A9; codeptr++ // LDA #imm + ^codeptr = ^(bytecode+i); codeptr++ + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $D0+VX; codeptr++ // ESTKL + A_IS_TOSL = TRUE break // LB,LW,LLB,LLW,LAB,LAW,DLB,DLW ; 60 62 64 66 68 6A 6C 6E is $60 - //puts("LB") - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + puts("LB") + if not A_IS_TOSL + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 ^codeptr = $A1; codeptr++ // LDA (zp,X) ^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL - ^codeptr = $A9; codeptr++ // LDA #imm - ^codeptr = $00; codeptr++ // $00 - ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $94; codeptr++ // STY zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $D0+VX; codeptr++ // ESTKL + A_IS_TOSL = TRUE break is $62 - //puts("LW") - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + puts("LW") + if not A_IS_TOSL + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 ^codeptr = $A1; codeptr++ // LDA (zp,X) @@ -826,28 +1048,47 @@ def compiler(defptr)#0 ^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH + A_IS_TOSL = FALSE break is $64 i++ - //puts("LLB "); puti(^(bytecode+i)) - ^codeptr = $CA; codeptr++ // DEX - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = ^(bytecode+i); codeptr++ + puts("LLB "); puti(^(bytecode+i)) + if A_IS_TOSL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin + VX-- //^codeptr = $CA; codeptr++ // DEX + if ^(bytecode+i) <> 0 + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = ^(bytecode+i); codeptr++ + fin ^codeptr = $B1; codeptr++ // LDA (zp),Y ^codeptr = $E0; codeptr++ // IFP - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL - ^codeptr = $A9; codeptr++ // LDA #imm - ^codeptr = $00; codeptr++ // $00 - ^codeptr = $95; codeptr++ // STA zp,X + // + // Reload zero into Y + // + if ^(bytecode+i) <> 0 + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $00; codeptr++ // $00 + fin + ^codeptr = $94; codeptr++ // STY zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $D0+VX; codeptr++ // ESTKL + A_IS_TOSL = TRUE break is $66 i++ - //puts("LLW "); puti(^(bytecode+i)) - ^codeptr = $CA; codeptr++ // DEX - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = ^(bytecode+i); codeptr++ + puts("LLW "); puti(^(bytecode+i)) + if A_IS_TOSL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin + VX-- //^codeptr = $CA; codeptr++ // DEX + if ^(bytecode+i) <> 0 + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = ^(bytecode+i); codeptr++ + fin ^codeptr = $B1; codeptr++ // LDA (zp),Y ^codeptr = $E0; codeptr++ // IFP ^codeptr = $95; codeptr++ // STA zp,X @@ -857,52 +1098,86 @@ def compiler(defptr)#0 ^codeptr = $E0; codeptr++ // IFP ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH + // + // Reload zero into Y + // + if ^(bytecode+i) <> 0 + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $00; codeptr++ // $00 + else + ^codeptr = $88; codeptr++ // DEY + fin + A_IS_TOSL = FALSE break is $68 i++ - //puts("LAB $"); puth(*(bytecode+i)) - ^codeptr = $CA; codeptr++ // DEX + puts("LAB $"); puth(*(bytecode+i)) + if A_IS_TOSL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin + VX-- //^codeptr = $CA; codeptr++ // DEX ^codeptr = $AD; codeptr++ // LDA abs *codeptr = *(bytecode+i); codeptr = codeptr + 2 - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL - ^codeptr = $A9; codeptr++ // LDA #imm - ^codeptr = $00; codeptr++ // $00 - ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $94; codeptr++ // STY zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $D0+VX; codeptr++ // ESTKL + A_IS_TOSL = TRUE i++ break is $6A i++ - //puts("LAW $"); puth(*(bytecode+i)) - ^codeptr = $CA; codeptr++ // DEX - ^codeptr = $AD; codeptr++ // LDA abs - *codeptr = *(bytecode+i); codeptr = codeptr + 2 - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + puts("LAW $"); puth(*(bytecode+i)) + if A_IS_TOSL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin + VX-- //^codeptr = $CA; codeptr++ // DEX ^codeptr = $AD; codeptr++ // LDA abs *codeptr = *(bytecode+i)+1; codeptr = codeptr + 2 ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH + ^codeptr = $AD; codeptr++ // LDA abs + *codeptr = *(bytecode+i); codeptr = codeptr + 2 + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $D0+VX; codeptr++ // ESTKL + A_IS_TOSL = TRUE i++ break is $6C i++ - //puts("DLB "); puti(^(bytecode+i)) - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = ^(bytecode+i); codeptr++ - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + puts("DLB "); puti(^(bytecode+i)) + if ^(bytecode+i) <> 0 + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = ^(bytecode+i); codeptr++ + fin + if not A_IS_TOSL + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin ^codeptr = $91; codeptr++ // STA (zp),Y ^codeptr = $E0; codeptr++ // IFP + // + // Reload zero into Y + // + if ^(bytecode+i) <> 0 + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $00; codeptr++ // $00 + fin + A_IS_TOSL = FALSE break is $6E i++ - //puts("DLW "); puti(^(bytecode+i)) - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = ^(bytecode+i); codeptr++ - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + puts("DLW "); puti(^(bytecode+i)) + if ^(bytecode+i) <> 0 + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = ^(bytecode+i); codeptr++ + fin + if not A_IS_TOSL + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin ^codeptr = $91; codeptr++ // STA (zp),Y ^codeptr = $E0; codeptr++ // IFP ^codeptr = $C8; codeptr++ // INY @@ -910,25 +1185,41 @@ def compiler(defptr)#0 ^codeptr = $C0+VX; codeptr++ // ESTKH ^codeptr = $91; codeptr++ // STA (zp),Y ^codeptr = $E0; codeptr++ // IFP + // + // Reload zero into Y + // + if ^(bytecode+i) <> 0 + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $00; codeptr++ // $00 + else + ^codeptr = $88; codeptr++ // DEY + fin + A_IS_TOSL = FALSE break // SB,SW,SLB,SLW,SAB,SAW,DAB,DAW ; 70 72 74 76 78 7A 7C 7E is $70 - //puts("SB") - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + puts("SB") + if not A_IS_TOSL + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 ^codeptr = $81; codeptr++ // STA (zp,X) ^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 - ^codeptr = $E8; codeptr++ // INX - ^codeptr = $E8; codeptr++ // INX + //^codeptr = $E8; codeptr++ // INX + //^codeptr = $E8; codeptr++ // INX + VX = VX + 2 + A_IS_TOSL = FALSE break is $72 - //puts("SW") - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + puts("SW") + if not A_IS_TOSL + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 ^codeptr = $B5; codeptr++ // LDA zp,X @@ -945,27 +1236,45 @@ def compiler(defptr)#0 ^codeptr = $C0+VX; codeptr++ // ESTKH ^codeptr = $81; codeptr++ // STA (zp,X) ^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 - ^codeptr = $E8; codeptr++ // INX - ^codeptr = $E8; codeptr++ // INX + //^codeptr = $E8; codeptr++ // INX + //^codeptr = $E8; codeptr++ // INX + VX = VX + 2 + A_IS_TOSL = FALSE break is $74 i++ - //puts("SLB "); puti(^(bytecode+i)) - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = ^(bytecode+i); codeptr++ - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + puts("SLB "); puti(^(bytecode+i)) + if ^(bytecode+i) <> 0 + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = ^(bytecode+i); codeptr++ + fin + if not A_IS_TOSL + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin ^codeptr = $91; codeptr++ // STA (zp),Y ^codeptr = $E0; codeptr++ // IFP - ^codeptr = $E8; codeptr++ // INX + // + // Reload zero into Y + // + if ^(bytecode+i) <> 0 + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $00; codeptr++ // $00 + fin + VX++ //^codeptr = $E8; codeptr++ // INX + A_IS_TOSL = FALSE break is $76 i++ - //puts("SLW "); puti(^(bytecode+i)) - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = ^(bytecode+i); codeptr++ - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + puts("SLW "); puti(^(bytecode+i)) + if ^(bytecode+i) <> 0 + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = ^(bytecode+i); codeptr++ + fin + if not A_IS_TOSL + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin ^codeptr = $91; codeptr++ // STA (zp),Y ^codeptr = $E0; codeptr++ // IFP ^codeptr = $C8; codeptr++ // INY @@ -973,59 +1282,85 @@ def compiler(defptr)#0 ^codeptr = $C0+VX; codeptr++ // ESTKH ^codeptr = $91; codeptr++ // STA (zp),Y ^codeptr = $E0; codeptr++ // IFP - ^codeptr = $E8; codeptr++ // INX + // + // Reload zero into Y + // + if ^(bytecode+i) <> 0 + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $00; codeptr++ // $00 + else + ^codeptr = $88; codeptr++ // DEY + fin + VX++ //^codeptr = $E8; codeptr++ // INX + A_IS_TOSL = FALSE break is $78 i++ - //puts("SAB $"); puth(*(bytecode+i)) - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + puts("SAB $"); puth(*(bytecode+i)) + if not A_IS_TOSL + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin ^codeptr = $8D; codeptr++ // STA abs *codeptr = *(bytecode+i); codeptr = codeptr + 2 - ^codeptr = $E8; codeptr++ // INX + VX++ //^codeptr = $E8; codeptr++ // INX + A_IS_TOSL = FALSE i++ break is $7A i++ - //puts("SAW $"); puth(*(bytecode+i)) - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + puts("SAW $"); puth(*(bytecode+i)) + if not A_IS_TOSL + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin ^codeptr = $8D; codeptr++ // STA abs *codeptr = *(bytecode+i); codeptr = codeptr + 2 ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH ^codeptr = $8D; codeptr++ // STA abs *codeptr = *(bytecode+i)+1; codeptr = codeptr + 2 - ^codeptr = $E8; codeptr++ // INX + VX++ //^codeptr = $E8; codeptr++ // INX + A_IS_TOSL = FALSE i++ break is $7C i++ - //puts("DAB $"); puth(*(bytecode+i)) - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL - ^codeptr = $8D; codeptr++ // STA abs + puts("DAB $"); puth(*(bytecode+i)) + if not A_IS_TOSL + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin + ^codeptr = $8D; codeptr++ // STA abs *codeptr = *(bytecode+i); codeptr = codeptr + 2 + A_IS_TOSL = TRUE i++ break is $7E i++ - //puts("DAW $"); puth(*(bytecode+i)) - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL - ^codeptr = $8D; codeptr++ // STA abs - *codeptr = *(bytecode+i); codeptr = codeptr + 2 + puts("DAW $"); puth(*(bytecode+i)) + if A_IS_TOSL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH ^codeptr = $8D; codeptr++ // STA abs *codeptr = *(bytecode+i)+1; codeptr = codeptr + 2 + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $8D; codeptr++ // STA abs + *codeptr = *(bytecode+i); codeptr = codeptr + 2 + A_IS_TOSL = TRUE i++ break // LNOT,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 80 82 84 86 88 8A 8C 8E is $80 - //puts("NOT") - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + puts("NOT") + if not A_IS_TOSL + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin ^codeptr = $15; codeptr++ // ORA zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH ^codeptr = $F0; codeptr++ // BEQ rel @@ -1035,14 +1370,17 @@ def compiler(defptr)#0 ^codeptr = $49; codeptr++ // EOR #imm ^codeptr = $FF; codeptr++ // $FF ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL - ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $D0+VX; codeptr++ // ESTKL + A_IS_TOSL = TRUE break is $82 - //puts("ADD") - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + puts("ADD") + if not A_IS_TOSL + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin ^codeptr = $18; codeptr++ // CLC ^codeptr = $75; codeptr++ // ADC zp,X ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 @@ -1054,10 +1392,15 @@ def compiler(defptr)#0 ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - ^codeptr = $E8; codeptr++ // INX + VX++ //^codeptr = $E8; codeptr++ // INX + A_IS_TOSL = FALSE break is $84 - //puts("SUB") + puts("SUB") + if A_IS_TOSL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 ^codeptr = $38; codeptr++ // SEC @@ -1071,10 +1414,11 @@ def compiler(defptr)#0 ^codeptr = $C0+VX; codeptr++ // ESTKH ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - ^codeptr = $E8; codeptr++ // INX + VX++ //^codeptr = $E8; codeptr++ // INX + A_IS_TOSL = FALSE break is $86 - //puts("MUL") + puts("MUL") // // Call into VM // @@ -1082,9 +1426,15 @@ def compiler(defptr)#0 *codeptr = $3D0; codeptr = codeptr + 2 ^codeptr = $86; codeptr++ // MUL CODE ^codeptr = $C0; codeptr++ // NATV CODE + // + // Reload zero into Y + // + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $00; codeptr++ // $00 + A_IS_TOSL = FALSE break is $88 - //puts("DIV") + puts("DIV") // // Call into VM // @@ -1092,9 +1442,15 @@ def compiler(defptr)#0 *codeptr = $3D0; codeptr = codeptr + 2 ^codeptr = $88; codeptr++ // DIV CODE ^codeptr = $C0; codeptr++ // NATV CODE + // + // Reload zero into Y + // + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $00; codeptr++ // $00 + A_IS_TOSL = FALSE break is $8A - //puts("MOD") + puts("MOD") // // Call into VM // @@ -1102,63 +1458,88 @@ def compiler(defptr)#0 *codeptr = $3D0; codeptr = codeptr + 2 ^codeptr = $8A; codeptr++ // MOD CODE ^codeptr = $C0; codeptr++ // NATV CODE + // + // Reload zero into Y + // + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $00; codeptr++ // $00 + A_IS_TOSL = FALSE break is $8C - //puts("INCR") + puts("INCR") + if A_IS_TOSL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin ^codeptr = $F6; codeptr++ // INC zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL ^codeptr = $D0; codeptr++ // BNE rel ^codeptr = $02; codeptr++ // +2 ^codeptr = $F6; codeptr++ // INC zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH + A_IS_TOSL = FALSE break is $8E - //puts("DECR") - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + puts("DECR") + if not A_IS_TOSL + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + else + ^codeptr = $C9; codeptr++ // CMP #imm + ^codeptr = $00; codeptr++ // $00 + fin ^codeptr = $D0; codeptr++ // BNE rel ^codeptr = $02; codeptr++ // +2 ^codeptr = $D6; codeptr++ // DEC zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH ^codeptr = $D6; codeptr++ // DEC zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL + A_IS_TOSL = FALSE break // NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 90 92 94 96 98 9A 9C 9E is $90 - //puts("NEG") - ^codeptr = $A9; codeptr++ // LDA #imm - ^codeptr = $00; codeptr++ // $00 + puts("NEG") + if A_IS_TOSL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin + ^codeptr = $98; codeptr++ // TYA -> LDA #$00 ^codeptr = $38; codeptr++ // SEC ^codeptr = $F5; codeptr++ // SBC zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL - ^codeptr = $A9; codeptr++ // LDA #imm - ^codeptr = $00; codeptr++ // $00 + ^codeptr = $98; codeptr++ // TYA -> LDA #00 ^codeptr = $F5; codeptr++ // SBC zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH + A_IS_TOSL = FALSE break is $92 - //puts("COMP") - ^codeptr = $A9; codeptr++ // LDA #imm + puts("COMP") + if not A_IS_TOSL + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin + ^codeptr = $49; codeptr++ // EOR #imm ^codeptr = $FF; codeptr++ // $FF - ^codeptr = $55; codeptr++ // EOR zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL - ^codeptr = $A9; codeptr++ // LDA #imm - ^codeptr = $FF; codeptr++ // $FF - ^codeptr = $55; codeptr++ // EOR zp,X + ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH + ^codeptr = $49; codeptr++ // EOR #imm + ^codeptr = $FF; codeptr++ // $FF ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH + A_IS_TOSL = FALSE break is $94 - //puts("AND") - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + puts("AND") + if not A_IS_TOSL + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin ^codeptr = $35; codeptr++ // AND zp,X ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 ^codeptr = $95; codeptr++ // STA zp,X @@ -1169,12 +1550,15 @@ def compiler(defptr)#0 ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - ^codeptr = $E8; codeptr++ // INX + VX++ //^codeptr = $E8; codeptr++ // INX + A_IS_TOSL = FALSE break is $96 - //puts("OR") - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + puts("OR") + if not A_IS_TOSL + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin ^codeptr = $15; codeptr++ // ORA zp,X ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 ^codeptr = $95; codeptr++ // STA zp,X @@ -1185,12 +1569,15 @@ def compiler(defptr)#0 ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - ^codeptr = $E8; codeptr++ // INX + VX++ //^codeptr = $E8; codeptr++ // INX + A_IS_TOSL = FALSE break is $98 - //puts("XOR") - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + puts("XOR") + if not A_IS_TOSL + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin ^codeptr = $55; codeptr++ // EOR zp,X ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 ^codeptr = $95; codeptr++ // STA zp,X @@ -1201,10 +1588,11 @@ def compiler(defptr)#0 ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - ^codeptr = $E8; codeptr++ // INX + VX++ //^codeptr = $E8; codeptr++ // INX + A_IS_TOSL = FALSE break is $9A - //puts("SHL") + puts("SHL") // // Call into VM // @@ -1212,9 +1600,15 @@ def compiler(defptr)#0 *codeptr = $3D0; codeptr = codeptr + 2 ^codeptr = $9A; codeptr++ // SHL CODE ^codeptr = $C0; codeptr++ // NATV CODE + // + // Reload zero into Y + // + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $00; codeptr++ // $00 + A_IS_TOSL = FALSE break is $9C - //puts("SHR") + puts("SHR") // // Call into VM // @@ -1222,11 +1616,19 @@ def compiler(defptr)#0 *codeptr = $3D0; codeptr = codeptr + 2 ^codeptr = $9C; codeptr++ // SHR CODE ^codeptr = $C0; codeptr++ // NATV CODE + // + // Reload zero into Y + // + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $00; codeptr++ // $00 + A_IS_TOSL = FALSE break is $9E - //puts("IDXW") - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + puts("IDXW") + if not A_IS_TOSL + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin ^codeptr = $0A; codeptr++ // ASL ^codeptr = $36; codeptr++ // ROL zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH @@ -1241,14 +1643,27 @@ def compiler(defptr)#0 ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - ^codeptr = $E8; codeptr++ // INX + VX++ //^codeptr = $E8; codeptr++ // INX + A_IS_TOSL = FALSE break // BRGT,BRLT,INCBRLE,ADDBRLE,DECBRGE,SUBBRGE,BRAND,BROR ; A0 A2 A4 A6 A8 AA AC AE is $A0 i++ dest = i + *(bytecode+i) - //puts("BRGT "); puti(dest) + puts("BRGT "); puti(dest) i++ + while VX > 0 + ^codeptr = $E8; codeptr++ // INX + VX-- + loop + while VX < 0 + ^codeptr = $CA; codeptr++ // DEX + VX++ + loop + if A_IS_TOSL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 ^codeptr = $D5; codeptr++ // CMP zp,X @@ -1270,15 +1685,26 @@ def compiler(defptr)#0 if not (*codeptr & $8000) // Unresolved address list addrxlate=>[dest] = codeptr - *jitcodeptr fin - codeptr = codeptr + 2 + codeptr = codeptr + 2 + A_IS_TOSL = FALSE break is $A2 i++ dest = i + *(bytecode+i) - //puts("BRLT "); puti(dest) + puts("BRLT "); puti(dest) i++ - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + while VX > 0 + ^codeptr = $E8; codeptr++ // INX + VX-- + loop + while VX < 0 + ^codeptr = $CA; codeptr++ // DEX + VX++ + loop + if not A_IS_TOSL + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin ^codeptr = $D5; codeptr++ // CMP zp,X ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 ^codeptr = $B5; codeptr++ // LDA zp,X @@ -1298,16 +1724,21 @@ def compiler(defptr)#0 if not (*codeptr & $8000) // Unresolved address list addrxlate=>[dest] = codeptr - *jitcodeptr fin - codeptr = codeptr + 2 + codeptr = codeptr + 2 + A_IS_TOSL = FALSE break is $A4 i++ dest = i + *(bytecode+i) - //puts("INCBRLE "); puti(dest) + puts("INCBRLE "); puti(dest) i++ // // INCR // + if A_IS_TOSL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin ^codeptr = $F6; codeptr++ // INC zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL ^codeptr = $D0; codeptr++ // BNE rel @@ -1317,6 +1748,14 @@ def compiler(defptr)#0 // // BRLE // + while VX > 0 + ^codeptr = $E8; codeptr++ // INX + VX-- + loop + while VX < 0 + ^codeptr = $CA; codeptr++ // DEX + VX++ + loop ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 ^codeptr = $D5; codeptr++ // CMP zp,X @@ -1339,17 +1778,20 @@ def compiler(defptr)#0 codeptr = codeptr + 2 ^codeptr = $E8; codeptr++ // INX ^codeptr = $E8; codeptr++ // INX + A_IS_TOSL = FALSE break is $A6 i++ dest = i + *(bytecode+i) - //puts("ADDBRLE "); puti(dest) + puts("ADDBRLE "); puti(dest) i++ // // ADD // - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + if not A_IS_TOSL + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin ^codeptr = $18; codeptr++ // CLC ^codeptr = $75; codeptr++ // ADC zp,X ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 @@ -1361,10 +1803,18 @@ def compiler(defptr)#0 ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - ^codeptr = $E8; codeptr++ // INX + VX++ //^codeptr = $E8; codeptr++ // INX // // BRLE // + while VX > 0 + ^codeptr = $E8; codeptr++ // INX + VX-- + loop + while VX < 0 + ^codeptr = $CA; codeptr++ // DEX + VX++ + loop ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 ^codeptr = $D5; codeptr++ // CMP zp,X @@ -1387,17 +1837,23 @@ def compiler(defptr)#0 codeptr = codeptr + 2 ^codeptr = $E8; codeptr++ // INX ^codeptr = $E8; codeptr++ // INX + A_IS_TOSL = FALSE break is $A8 i++ dest = i + *(bytecode+i) - //puts("DECBRGE "); puti(dest) + puts("DECBRGE "); puti(dest) i++ // // DECR // - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + if not A_IS_TOSL + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + else + ^codeptr = $C9; codeptr++ // CMP #imm + ^codeptr = $00; codeptr++ // $00 + fin ^codeptr = $D0; codeptr++ // BNE rel ^codeptr = $02; codeptr++ // +2 ^codeptr = $D6; codeptr++ // DEC zp,X @@ -1407,6 +1863,14 @@ def compiler(defptr)#0 // // BRGE // + while VX > 0 + ^codeptr = $E8; codeptr++ // INX + VX-- + loop + while VX < 0 + ^codeptr = $CA; codeptr++ // DEX + VX++ + loop ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL ^codeptr = $D5; codeptr++ // CMP zp,X @@ -1429,15 +1893,20 @@ def compiler(defptr)#0 codeptr = codeptr + 2 ^codeptr = $E8; codeptr++ // INX ^codeptr = $E8; codeptr++ // INX + A_IS_TOSL = FALSE break is $AA i++ dest = i + *(bytecode+i) - //puts("SUBBRGE "); puti(dest) + puts("SUBBRGE "); puti(dest) i++ // // SUB // + if A_IS_TOSL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 ^codeptr = $38; codeptr++ // SEC @@ -1451,10 +1920,18 @@ def compiler(defptr)#0 ^codeptr = $C0+VX; codeptr++ // ESTKH ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - ^codeptr = $E8; codeptr++ // INX + VX++ //^codeptr = $E8; codeptr++ // INX // // BRGE // + while VX > 0 + ^codeptr = $E8; codeptr++ // INX + VX-- + loop + while VX < 0 + ^codeptr = $CA; codeptr++ // DEX + VX++ + loop ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL ^codeptr = $D5; codeptr++ // CMP zp,X @@ -1477,14 +1954,25 @@ def compiler(defptr)#0 codeptr = codeptr + 2 ^codeptr = $E8; codeptr++ // INX ^codeptr = $E8; codeptr++ // INX + A_IS_TOSL = FALSE break is $AC i++ dest = i + *(bytecode+i) i++ - //puts("BRAND "); puti(dest) - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + puts("BRAND "); puti(dest) + while VX > 0 + ^codeptr = $E8; codeptr++ // INX + VX-- + loop + while VX < 0 + ^codeptr = $CA; codeptr++ // DEX + VX++ + loop + if not A_IS_TOSL + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin ^codeptr = $15; codeptr++ // ORA zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH ^codeptr = $D0; codeptr++ // BNE rel @@ -1496,14 +1984,25 @@ def compiler(defptr)#0 fin codeptr = codeptr + 2 ^codeptr = $E8; codeptr++ // INX + A_IS_TOSL = FALSE break is $AE i++ dest = i + *(bytecode+i) i++ - //puts("BROR "); puti(dest) - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + puts("BROR "); puti(dest) + while VX > 0 + ^codeptr = $E8; codeptr++ // INX + VX-- + loop + while VX < 0 + ^codeptr = $CA; codeptr++ // DEX + VX++ + loop + if not A_IS_TOSL + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin ^codeptr = $15; codeptr++ // ORA zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH ^codeptr = $F0; codeptr++ // BEQ rel @@ -1515,88 +2014,129 @@ def compiler(defptr)#0 fin codeptr = codeptr + 2 ^codeptr = $E8; codeptr++ // INX + A_IS_TOSL = FALSE break // ADDLB,ADDLW,ADDAB,ADDAW,IDXLB,IDXLW,IDXAB,IDXAW ; B0 B2 B4 B6 B8 BA BC BE is $B0 i++ - //puts("ADDLB "); puti(^(bytecode+i)) - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = ^(bytecode+i); codeptr++ - ^codeptr = $B1; codeptr++ // LDA (zp),Y - ^codeptr = $E0; codeptr++ // IFP + puts("ADDLB "); puti(^(bytecode+i)) + if not A_IS_TOSL + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin + if ^(bytecode+i) <> 0 + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = ^(bytecode+i); codeptr++ + fin ^codeptr = $18; codeptr++ // CLC - ^codeptr = $75; codeptr++ // ADC zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $71; codeptr++ // ADC (zp),Y + ^codeptr = $E0; codeptr++ // IFP ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL ^codeptr = $90; codeptr++ // BCC rel ^codeptr = $02; codeptr++ // +2 ^codeptr = $F6; codeptr++ // INC zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH + // + // Reload zero into Y + // + if ^(bytecode+i) <> 0 + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $00; codeptr++ // $00 + fin + A_IS_TOSL = TRUE break is $B2 i++ - //puts("ADDLW "); puti(^(bytecode+i)) - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = ^(bytecode+i); codeptr++ - ^codeptr = $B1; codeptr++ // LDA (zp),Y - ^codeptr = $E0; codeptr++ // IFP + puts("ADDLW "); puti(^(bytecode+i)) + if not A_IS_TOSL + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin + if ^(bytecode+i) <> 0 + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = ^(bytecode+i); codeptr++ + fin ^codeptr = $18; codeptr++ // CLC - ^codeptr = $75; codeptr++ // ADC zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL - ^codeptr = $C8; codeptr++ // INY - ^codeptr = $B1; codeptr++ // LDA (zp),Y + ^codeptr = $71; codeptr++ // ADC (zp),Y ^codeptr = $E0; codeptr++ // IFP - ^codeptr = $75; codeptr++ // ADC zp,X + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH + ^codeptr = $C8; codeptr++ // INY + ^codeptr = $71; codeptr++ // ADC (zp),Y + ^codeptr = $E0; codeptr++ // IFP ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH + // + // Reload zero into Y + // + if ^(bytecode+i) <> 0 + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $00; codeptr++ // $00 + else + ^codeptr = $88; codeptr++ // DEY + fin + A_IS_TOSL = FALSE break is $B4 i++ - //puts("ADDAB $"); puth(*(bytecode+i)) - ^codeptr = $AD; codeptr++ // LDA abs - *codeptr = *(bytecode+i); codeptr = codeptr + 2 + puts("ADDAB $"); puth(*(bytecode+i)) + if not A_IS_TOSL + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin ^codeptr = $18; codeptr++ // CLC - ^codeptr = $75; codeptr++ // ADC zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $6D; codeptr++ // ADC abs + *codeptr = *(bytecode+i); codeptr = codeptr + 2 ^codeptr = $90; codeptr++ // BCC rel ^codeptr = $02; codeptr++ // +2 ^codeptr = $F6; codeptr++ // INC zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $D0+VX; codeptr++ // ESTKL + A_IS_TOSL = TRUE i++ break is $B6 i++ - //puts("ADDAW $"); puth(*(bytecode+i)) - ^codeptr = $AD; codeptr++ // LDA abs - *codeptr = *(bytecode+i); codeptr = codeptr + 2 + puts("ADDAW $"); puth(*(bytecode+i)) + if not A_IS_TOSL + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin ^codeptr = $18; codeptr++ // CLC - ^codeptr = $75; codeptr++ // ADC zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $6D; codeptr++ // ADC abs + *codeptr = *(bytecode+i); codeptr = codeptr + 2 ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL - ^codeptr = $AD; codeptr++ // LDA abs + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH + ^codeptr = $6D; codeptr++ // ADC abs *codeptr = *(bytecode+i)+1; codeptr = codeptr + 2 - ^codeptr = $75; codeptr++ // ADC zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH + A_IS_TOSL = FALSE i++ break is $B8 i++ - //puts("IDXLB "); puti(^(bytecode+i)) - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = ^(bytecode+i); codeptr++ + puts("IDXLB "); puti(^(bytecode+i)) + if A_IS_TOSL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin + if ^(bytecode+i) <> 0 + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = ^(bytecode+i); codeptr++ + fin ^codeptr = $B1; codeptr++ // LDA (zp),Y ^codeptr = $E0; codeptr++ // IFP - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = $00; codeptr++ // $00 + if ^(bytecode+i) <> 0 + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $00; codeptr++ // $00 + fin ^codeptr = $0A; codeptr++ // ASL ^codeptr = $90; codeptr++ // BCC rel ^codeptr = $02; codeptr++ // +2 @@ -1611,12 +2151,24 @@ def compiler(defptr)#0 ^codeptr = $C0+VX; codeptr++ // ESTKH ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH + // + // Reload zero into Y + // + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $00; codeptr++ // $00 + A_IS_TOSL = FALSE break is $BA i++ - //puts("IDXLW "); puti(^(bytecode+i)) - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = ^(bytecode+i); codeptr++ + puts("IDXLW "); puti(^(bytecode+i)) + if A_IS_TOSL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin + if ^(bytecode+i) <> 0 + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = ^(bytecode+i); codeptr++ + fin ^codeptr = $B1; codeptr++ // LDA (zp),Y ^codeptr = $E0; codeptr++ // IFP ^codeptr = $0A; codeptr++ // ASL @@ -1639,14 +2191,22 @@ def compiler(defptr)#0 ^codeptr = $C0+VX; codeptr++ // ESTKH ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH + // + // Reload zero into Y + // + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $00; codeptr++ // $00 + A_IS_TOSL = FALSE break is $BC i++ - //puts("IDXAB $"); puth(*(bytecode+i)) + puts("IDXAB $"); puth(*(bytecode+i)) + if A_IS_TOSL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin ^codeptr = $AD; codeptr++ // LDA abs *codeptr = *(bytecode+i); codeptr = codeptr + 2 - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = $00; codeptr++ // $00 ^codeptr = $0A; codeptr++ // ASL ^codeptr = $90; codeptr++ // BCC rel ^codeptr = $02; codeptr++ // +2 @@ -1661,11 +2221,21 @@ def compiler(defptr)#0 ^codeptr = $C0+VX; codeptr++ // ESTKH ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH + // + // Reload zero into Y + // + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $00; codeptr++ // $00 + A_IS_TOSL = FALSE i++ break is $BE i++ - //puts("IDXAW $"); puth(*(bytecode+i)) + puts("IDXAW $"); puth(*(bytecode+i)) + if A_IS_TOSL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin ^codeptr = $AD; codeptr++ // LDA abs *codeptr = *(bytecode+i); codeptr = codeptr + 2 ^codeptr = $0A; codeptr++ // ASL @@ -1687,6 +2257,12 @@ def compiler(defptr)#0 ^codeptr = $C0+VX; codeptr++ // ESTKH ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH + // + // Reload zero into Y + // + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $00; codeptr++ // $00 + A_IS_TOSL = FALSE i++ break is $FE // NOPed out earlier by SELect @@ -1695,7 +2271,7 @@ def compiler(defptr)#0 //putc('$'); puth(^(bytecode+i)) wend fin - //putln + putln i++ if i >= defptr->bytecodesize // @@ -1708,11 +2284,11 @@ def compiler(defptr)#0 // Free working bufffers // //heaprelease(addrxlate) - //puts("Done compiling: $"); puth(defptr=>interpaddr); putln - //getc + puts("Done compiling: $"); puth(defptr=>interpaddr); putln + getc return fin - //getc + getc loop // // If we got here. we ran out of code buffer space. Overwrite interpreter @@ -1723,7 +2299,7 @@ def compiler(defptr)#0 // Free working bufffers // //heaprelease(addrxlate) - //puts("Ran out of code buffer\n") + puts("Ran out of code buffer\n") //getc end // From a7ecdc7edca2e202f841300290228c598a918cf6 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Thu, 22 Mar 2018 16:38:05 -0700 Subject: [PATCH 082/147] Save a few bytes so we can test JIT --- src/libsrc/apple/jit.pla | 247 ++++++++++++------------------------- src/vmsrc/apple/cmdjit.pla | 18 +-- 2 files changed, 86 insertions(+), 179 deletions(-) diff --git a/src/libsrc/apple/jit.pla b/src/libsrc/apple/jit.pla index d0470a5..bb066e4 100644 --- a/src/libsrc/apple/jit.pla +++ b/src/libsrc/apple/jit.pla @@ -29,6 +29,20 @@ const codemax = $BEF0 // const interpentry = $03DC // +// 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 @@ -229,14 +243,7 @@ def compiler(defptr)#0 ^codeptr = $D0+VX; codeptr++ // ESTKL A_IS_TOSL = FALSE fin - while VX > 0 - ^codeptr = $E8; codeptr++ // INX - VX-- - loop - while VX < 0 - ^codeptr = $CA; codeptr++ // DEX - VX++ - loop + codeptr, VX = resolveX(codeptr, VX) opcode = opcode & $FE fin if opcode < $20 @@ -276,15 +283,7 @@ def compiler(defptr)#0 puts("BREQ "); puti(dest) //^codeptr = $E8; codeptr++ // INX //^codeptr = $E8; codeptr++ // INX - VX = VX + 2 - while VX > 0 - ^codeptr = $E8; codeptr++ // INX - VX-- - loop - while VX < 0 - ^codeptr = $CA; codeptr++ // DEX - VX++ - loop + codeptr, VX = resolveX(codeptr, VX + 2) if not A_IS_TOSL ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0-2+VX; codeptr++ // ESTKL-2 @@ -314,15 +313,7 @@ def compiler(defptr)#0 puts("BRNE "); puti(dest) //^codeptr = $E8; codeptr++ // INX //^codeptr = $E8; codeptr++ // INX - VX = VX + 2 - while VX > 0 - ^codeptr = $E8; codeptr++ // INX - VX-- - loop - while VX < 0 - ^codeptr = $CA; codeptr++ // DEX - VX++ - loop + codeptr, VX = resolveX(codeptr, VX + 2) if not A_IS_TOSL ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0-2+VX; codeptr++ // ESTKL-2 @@ -762,15 +753,8 @@ def compiler(defptr)#0 dest = i + *(bytecode+i) i++ puts("BRFLS "); puti(dest) - VX++ //^codeptr = $E8; codeptr++ // INX - while VX > 0 - ^codeptr = $E8; codeptr++ // INX - VX-- - loop - while VX < 0 - ^codeptr = $CA; codeptr++ // DEX - VX++ - loop + //VX++ //^codeptr = $E8; codeptr++ // INX + codeptr, VX = resolveX(codeptr, VX + 1) if not A_IS_TOSL ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0-1+VX; codeptr++ // ESTKL-1 @@ -792,15 +776,8 @@ def compiler(defptr)#0 dest = i + *(bytecode+i) i++ puts("BRTRU "); puti(dest) - VX++ //^codeptr = $E8; codeptr++ // INX - while VX > 0 - ^codeptr = $E8; codeptr++ // INX - VX-- - loop - while VX < 0 - ^codeptr = $CA; codeptr++ // DEX - VX++ - loop + //VX++ //^codeptr = $E8; codeptr++ // INX + codeptr, VX = resolveX(codeptr, VX + 1) if not A_IS_TOSL ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0-1+VX; codeptr++ // ESTKL-1 @@ -847,15 +824,8 @@ def compiler(defptr)#0 fin ^codeptr = $B4; codeptr++ // LDY zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH - VX++ //^codeptr = $E8; codeptr++ // INX - while VX > 0 - ^codeptr = $E8; codeptr++ // INX - VX-- - loop - while VX < 0 - ^codeptr = $CA; codeptr++ // DEX - VX++ - loop + //VX++ //^codeptr = $E8; codeptr++ // INX + codeptr, VX = resolveX(codeptr, VX + 1) repeat puts(" $"); puth(*(bytecode+case)) ^codeptr = $C9; codeptr++ // CMP #imm @@ -932,15 +902,8 @@ def compiler(defptr)#0 ^codeptr = $C0+VX; codeptr++ // ESTKH ^codeptr = $85; codeptr++ // STA zp ^codeptr = $E8; codeptr++ // $E8:TMPH - VX++ //^codeptr = $E8; codeptr++ // INX - while VX > 0 - ^codeptr = $E8; codeptr++ // INX - VX-- - loop - while VX < 0 - ^codeptr = $CA; codeptr++ // DEX - VX++ - loop + //VX++ //^codeptr = $E8; codeptr++ // INX + codeptr, VX = resolveX(codeptr, VX + 1) // // Call through TMP // @@ -1148,14 +1111,14 @@ def compiler(defptr)#0 is $6C i++ puts("DLB "); puti(^(bytecode+i)) - if ^(bytecode+i) <> 0 - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = ^(bytecode+i); codeptr++ - fin if not A_IS_TOSL ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL fin + if ^(bytecode+i) <> 0 + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = ^(bytecode+i); codeptr++ + fin ^codeptr = $91; codeptr++ // STA (zp),Y ^codeptr = $E0; codeptr++ // IFP // @@ -1170,14 +1133,14 @@ def compiler(defptr)#0 is $6E i++ puts("DLW "); puti(^(bytecode+i)) - if ^(bytecode+i) <> 0 - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = ^(bytecode+i); codeptr++ - fin if not A_IS_TOSL ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL fin + if ^(bytecode+i) <> 0 + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = ^(bytecode+i); codeptr++ + fin ^codeptr = $91; codeptr++ // STA (zp),Y ^codeptr = $E0; codeptr++ // IFP ^codeptr = $C8; codeptr++ // INY @@ -1244,14 +1207,14 @@ def compiler(defptr)#0 is $74 i++ puts("SLB "); puti(^(bytecode+i)) - if ^(bytecode+i) <> 0 - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = ^(bytecode+i); codeptr++ - fin if not A_IS_TOSL ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL fin + if ^(bytecode+i) <> 0 + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = ^(bytecode+i); codeptr++ + fin ^codeptr = $91; codeptr++ // STA (zp),Y ^codeptr = $E0; codeptr++ // IFP // @@ -1267,14 +1230,14 @@ def compiler(defptr)#0 is $76 i++ puts("SLW "); puti(^(bytecode+i)) - if ^(bytecode+i) <> 0 - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = ^(bytecode+i); codeptr++ - fin if not A_IS_TOSL ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL fin + if ^(bytecode+i) <> 0 + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = ^(bytecode+i); codeptr++ + fin ^codeptr = $91; codeptr++ // STA (zp),Y ^codeptr = $E0; codeptr++ // IFP ^codeptr = $C8; codeptr++ // INY @@ -1652,14 +1615,7 @@ def compiler(defptr)#0 dest = i + *(bytecode+i) puts("BRGT "); puti(dest) i++ - while VX > 0 - ^codeptr = $E8; codeptr++ // INX - VX-- - loop - while VX < 0 - ^codeptr = $CA; codeptr++ // DEX - VX++ - loop + codeptr, VX = resolveX(codeptr, VX) if A_IS_TOSL ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL @@ -1685,7 +1641,7 @@ def compiler(defptr)#0 if not (*codeptr & $8000) // Unresolved address list addrxlate=>[dest] = codeptr - *jitcodeptr fin - codeptr = codeptr + 2 + codeptr = codeptr + 2 A_IS_TOSL = FALSE break is $A2 @@ -1693,14 +1649,7 @@ def compiler(defptr)#0 dest = i + *(bytecode+i) puts("BRLT "); puti(dest) i++ - while VX > 0 - ^codeptr = $E8; codeptr++ // INX - VX-- - loop - while VX < 0 - ^codeptr = $CA; codeptr++ // DEX - VX++ - loop + codeptr, VX = resolveX(codeptr, VX) if not A_IS_TOSL ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL @@ -1724,7 +1673,7 @@ def compiler(defptr)#0 if not (*codeptr & $8000) // Unresolved address list addrxlate=>[dest] = codeptr - *jitcodeptr fin - codeptr = codeptr + 2 + codeptr = codeptr + 2 A_IS_TOSL = FALSE break is $A4 @@ -1748,14 +1697,7 @@ def compiler(defptr)#0 // // BRLE // - while VX > 0 - ^codeptr = $E8; codeptr++ // INX - VX-- - loop - while VX < 0 - ^codeptr = $CA; codeptr++ // DEX - VX++ - loop + codeptr, VX = resolveX(codeptr, VX) ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 ^codeptr = $D5; codeptr++ // CMP zp,X @@ -1775,9 +1717,9 @@ def compiler(defptr)#0 if not (*codeptr & $8000) // Unresolved address list addrxlate=>[dest] = codeptr - *jitcodeptr fin - codeptr = codeptr + 2 - ^codeptr = $E8; codeptr++ // INX - ^codeptr = $E8; codeptr++ // INX + codeptr = codeptr + 2 + ^codeptr = $E8; codeptr++ // INX + ^codeptr = $E8; codeptr++ // INX A_IS_TOSL = FALSE break is $A6 @@ -1803,18 +1745,11 @@ def compiler(defptr)#0 ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - VX++ //^codeptr = $E8; codeptr++ // INX + //VX++ //^codeptr = $E8; codeptr++ // INX // // BRLE // - while VX > 0 - ^codeptr = $E8; codeptr++ // INX - VX-- - loop - while VX < 0 - ^codeptr = $CA; codeptr++ // DEX - VX++ - loop + codeptr, VX = resolveX(codeptr, VX + 1) ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 ^codeptr = $D5; codeptr++ // CMP zp,X @@ -1834,9 +1769,9 @@ def compiler(defptr)#0 if not (*codeptr & $8000) // Unresolved address list addrxlate=>[dest] = codeptr - *jitcodeptr fin - codeptr = codeptr + 2 - ^codeptr = $E8; codeptr++ // INX - ^codeptr = $E8; codeptr++ // INX + codeptr = codeptr + 2 + ^codeptr = $E8; codeptr++ // INX + ^codeptr = $E8; codeptr++ // INX A_IS_TOSL = FALSE break is $A8 @@ -1863,14 +1798,7 @@ def compiler(defptr)#0 // // BRGE // - while VX > 0 - ^codeptr = $E8; codeptr++ // INX - VX-- - loop - while VX < 0 - ^codeptr = $CA; codeptr++ // DEX - VX++ - loop + codeptr, VX = resolveX(codeptr, VX) ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL ^codeptr = $D5; codeptr++ // CMP zp,X @@ -1890,9 +1818,9 @@ def compiler(defptr)#0 if not (*codeptr & $8000) // Unresolved address list addrxlate=>[dest] = codeptr - *jitcodeptr fin - codeptr = codeptr + 2 - ^codeptr = $E8; codeptr++ // INX - ^codeptr = $E8; codeptr++ // INX + codeptr = codeptr + 2 + ^codeptr = $E8; codeptr++ // INX + ^codeptr = $E8; codeptr++ // INX A_IS_TOSL = FALSE break is $AA @@ -1920,18 +1848,11 @@ def compiler(defptr)#0 ^codeptr = $C0+VX; codeptr++ // ESTKH ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - VX++ //^codeptr = $E8; codeptr++ // INX + //VX++ //^codeptr = $E8; codeptr++ // INX // // BRGE // - while VX > 0 - ^codeptr = $E8; codeptr++ // INX - VX-- - loop - while VX < 0 - ^codeptr = $CA; codeptr++ // DEX - VX++ - loop + codeptr, VX = resolveX(codeptr, VX + 1) ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL ^codeptr = $D5; codeptr++ // CMP zp,X @@ -1951,9 +1872,9 @@ def compiler(defptr)#0 if not (*codeptr & $8000) // Unresolved address list addrxlate=>[dest] = codeptr - *jitcodeptr fin - codeptr = codeptr + 2 - ^codeptr = $E8; codeptr++ // INX - ^codeptr = $E8; codeptr++ // INX + codeptr = codeptr + 2 + ^codeptr = $E8; codeptr++ // INX + ^codeptr = $E8; codeptr++ // INX A_IS_TOSL = FALSE break is $AC @@ -1961,14 +1882,7 @@ def compiler(defptr)#0 dest = i + *(bytecode+i) i++ puts("BRAND "); puti(dest) - while VX > 0 - ^codeptr = $E8; codeptr++ // INX - VX-- - loop - while VX < 0 - ^codeptr = $CA; codeptr++ // DEX - VX++ - loop + codeptr, VX = resolveX(codeptr, VX) if not A_IS_TOSL ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL @@ -1982,8 +1896,8 @@ def compiler(defptr)#0 if not (*codeptr & $8000) // Unresolved address list addrxlate=>[dest] = codeptr - *jitcodeptr fin - codeptr = codeptr + 2 - ^codeptr = $E8; codeptr++ // INX + codeptr = codeptr + 2 + ^codeptr = $E8; codeptr++ // INX A_IS_TOSL = FALSE break is $AE @@ -1991,14 +1905,7 @@ def compiler(defptr)#0 dest = i + *(bytecode+i) i++ puts("BROR "); puti(dest) - while VX > 0 - ^codeptr = $E8; codeptr++ // INX - VX-- - loop - while VX < 0 - ^codeptr = $CA; codeptr++ // DEX - VX++ - loop + codeptr, VX = resolveX(codeptr, VX) if not A_IS_TOSL ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL @@ -2012,8 +1919,8 @@ def compiler(defptr)#0 if not (*codeptr & $8000) // Unresolved address list addrxlate=>[dest] = codeptr - *jitcodeptr fin - codeptr = codeptr + 2 - ^codeptr = $E8; codeptr++ // INX + codeptr = codeptr + 2 + ^codeptr = $E8; codeptr++ // INX A_IS_TOSL = FALSE break // ADDLB,ADDLW,ADDAB,ADDAW,IDXLB,IDXLW,IDXAB,IDXAW ; B0 B2 B4 B6 B8 BA BC BE @@ -2154,8 +2061,8 @@ def compiler(defptr)#0 // // Reload zero into Y // - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = $00; codeptr++ // $00 + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $00; codeptr++ // $00 A_IS_TOSL = FALSE break is $BA @@ -2194,8 +2101,8 @@ def compiler(defptr)#0 // // Reload zero into Y // - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = $00; codeptr++ // $00 + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $00; codeptr++ // $00 A_IS_TOSL = FALSE break is $BC @@ -2224,8 +2131,8 @@ def compiler(defptr)#0 // // Reload zero into Y // - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = $00; codeptr++ // $00 + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $00; codeptr++ // $00 A_IS_TOSL = FALSE i++ break @@ -2260,8 +2167,8 @@ def compiler(defptr)#0 // // Reload zero into Y // - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = $00; codeptr++ // $00 + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $00; codeptr++ // $00 A_IS_TOSL = FALSE i++ break diff --git a/src/vmsrc/apple/cmdjit.pla b/src/vmsrc/apple/cmdjit.pla index ac54e91..686a32f 100755 --- a/src/vmsrc/apple/cmdjit.pla +++ b/src/vmsrc/apple/cmdjit.pla @@ -150,13 +150,13 @@ word lastsym = symtbl // //asm equates included from cmdstub.s // -asm saveX#0 - STX XREG+1 -end -asm restoreX#0 -XREG LDX #$00 - RTS -end +//asm saveX#0 +// STX XREG+1 +//end +//asm restoreX#0 +//XREG LDX #$00 +// RTS +//end // CALL PRODOS // SYSCALL(CMD, PARAMS) // @@ -1512,12 +1512,12 @@ while 1 execsys(getlnbuf) break is '+' - saveX + //saveX execmod(striptrail(getlnbuf)) // // Clean up // - restoreX + //restoreX resetmemfiles break otherwise From 9be1bd5eb89bb828088e86ba7901cd0241be2ce9 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Thu, 22 Mar 2018 16:50:18 -0700 Subject: [PATCH 083/147] Change sense of test to take advantage of Y=0 --- src/libsrc/apple/jit.pla | 32 +++++++++++--------------------- 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/src/libsrc/apple/jit.pla b/src/libsrc/apple/jit.pla index bb066e4..267bf44 100644 --- a/src/libsrc/apple/jit.pla +++ b/src/libsrc/apple/jit.pla @@ -582,19 +582,17 @@ def compiler(defptr)#0 ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL fin - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = $FF; codeptr++ // $FF ^codeptr = $D5; codeptr++ // CMP zp,X ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 ^codeptr = $D0; codeptr++ // BNE rel - ^codeptr = $07; codeptr++ // +7 + ^codeptr = $06; codeptr++ // +6 ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH ^codeptr = $D5; codeptr++ // CMP zp,X ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - ^codeptr = $D0; codeptr++ // BNE rel + ^codeptr = $F0; codeptr++ // BEQ rel ^codeptr = $01; codeptr++ // +1 - ^codeptr = $C8; codeptr++ // INY + ^codeptr = $88; codeptr++ // DEY ^codeptr = $98; codeptr++ // TYA ^codeptr = $94; codeptr++ // STY zp,X ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 @@ -614,8 +612,6 @@ def compiler(defptr)#0 ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL fin - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = $FF; codeptr++ // $FF ^codeptr = $D5; codeptr++ // CMP zp,X ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 ^codeptr = $B5; codeptr++ // LDA zp,X @@ -626,9 +622,9 @@ def compiler(defptr)#0 ^codeptr = $02; codeptr++ // +2 ^codeptr = $49; codeptr++ // EOR #imm ^codeptr = $80; codeptr++ // $80 - ^codeptr = $30; codeptr++ // BMI rel + ^codeptr = $10; codeptr++ // BPL rel ^codeptr = $01; codeptr++ // +1 - ^codeptr = $C8; codeptr++ // INY + ^codeptr = $88; codeptr++ // DEY ^codeptr = $98; codeptr++ // TYA ^codeptr = $94; codeptr++ // STY zp,X ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 @@ -648,8 +644,6 @@ def compiler(defptr)#0 ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL fin - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = $FF; codeptr++ // $FF ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 ^codeptr = $D5; codeptr++ // CMP zp,X @@ -662,9 +656,9 @@ def compiler(defptr)#0 ^codeptr = $02; codeptr++ // +2 ^codeptr = $49; codeptr++ // EOR #imm ^codeptr = $80; codeptr++ // $80 - ^codeptr = $30; codeptr++ // BMI rel + ^codeptr = $10; codeptr++ // BPL rel ^codeptr = $01; codeptr++ // +1 - ^codeptr = $C8; codeptr++ // INY + ^codeptr = $88; codeptr++ // DEY ^codeptr = $98; codeptr++ // TYA ^codeptr = $94; codeptr++ // STY zp,X ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 @@ -684,8 +678,6 @@ def compiler(defptr)#0 ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL fin - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = $FF; codeptr++ // $FF ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 ^codeptr = $D5; codeptr++ // CMP zp,X @@ -698,9 +690,9 @@ def compiler(defptr)#0 ^codeptr = $02; codeptr++ // +2 ^codeptr = $49; codeptr++ // EOR #imm ^codeptr = $80; codeptr++ // $80 - ^codeptr = $10; codeptr++ // BPL rel + ^codeptr = $30; codeptr++ // BMI rel ^codeptr = $01; codeptr++ // +1 - ^codeptr = $C8; codeptr++ // INY + ^codeptr = $88; codeptr++ // DEY ^codeptr = $98; codeptr++ // TYA ^codeptr = $94; codeptr++ // STY zp,X ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 @@ -720,8 +712,6 @@ def compiler(defptr)#0 ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL fin - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = $FF; codeptr++ // $FF ^codeptr = $D5; codeptr++ // CMP zp,X ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 ^codeptr = $B5; codeptr++ // LDA zp,X @@ -732,9 +722,9 @@ def compiler(defptr)#0 ^codeptr = $02; codeptr++ // +2 ^codeptr = $49; codeptr++ // EOR #imm ^codeptr = $80; codeptr++ // $80 - ^codeptr = $10; codeptr++ // BPL rel + ^codeptr = $30; codeptr++ // BMI rel ^codeptr = $01; codeptr++ // +1 - ^codeptr = $C8; codeptr++ // INY + ^codeptr = $88; codeptr++ // DEY ^codeptr = $98; codeptr++ // TYA ^codeptr = $94; codeptr++ // STY zp,X ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 From 56f6d783e29092c32f65d857e032ce9f93e33246 Mon Sep 17 00:00:00 2001 From: Dave Schmenk Date: Thu, 22 Mar 2018 21:53:49 -0700 Subject: [PATCH 084/147] JIT optimizations fixes --- src/libsrc/apple/jit.pla | 375 ++++++++++++++++----------------------- 1 file changed, 157 insertions(+), 218 deletions(-) diff --git a/src/libsrc/apple/jit.pla b/src/libsrc/apple/jit.pla index 267bf44..c2d15b1 100644 --- a/src/libsrc/apple/jit.pla +++ b/src/libsrc/apple/jit.pla @@ -49,7 +49,7 @@ def compiler(defptr)#0 word codeptr, isdata, addrxlate, bytecode, i, case, dest, VX byte opcode, j, A_IS_TOSL - puts("JIT compiler invoked for :$"); puth(defptr=>bytecodeaddr); putln + //puts("JIT compiler invoked for :$"); puth(defptr=>bytecodeaddr); putln if isult(heapavail, 512 + defptr->bytecodesize) // 256 * sizeof(word) address xlate // // Not enough heap available @@ -68,8 +68,8 @@ def compiler(defptr)#0 *$0042 = bytecode call($C311, 0, 0, 0, $00) // CALL XMOVE with carry clear (AUX->MAIN) //^$C053 // MIX TEXT - puts("Addr Xlate: $"); puth(addrxlate); putln - puts("Bytecode: $"); puth(bytecode); putln + //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 // @@ -211,9 +211,9 @@ def compiler(defptr)#0 // // First optimization is to keep zero in Y register at all times // - if ^bytecode <> $58 // ENTER will set Y to zero - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = $00; codeptr++ // $00 + if ^bytecode & $FE <> $58 // ENTER will set Y to zero + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $00; codeptr++ // $00 fin while isule(codeptr, codemax) // @@ -231,8 +231,8 @@ def compiler(defptr)#0 until not case fin addrxlate=>[i] = codeptr - putc('$'); puth(codeptr); putc(':') - putc('['); puti(i); puts("] ") + //putc('$'); puth(codeptr); putc(':') + //putc('['); puti(i); //puts("] ") opcode = ^(bytecode+i) if opcode & 1 // @@ -249,10 +249,18 @@ def compiler(defptr)#0 if opcode < $20 // CN,CN,CN,CN,CN,CN,CN,CN ; 00 02 04 06 08 0A 0C 0E // CN,CN,CN,CN,CN,CN,CN,CN ; 10 12 14 16 18 1A 1C 1E - puts("CN $"); putb(^(bytecode+i)/2) + //puts("CN $"); putb(^(bytecode+i)/2) + if A_IS_TOSL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin VX-- //^codeptr = $CA; codeptr++ // DEX - ^codeptr = $A9; codeptr++ // LDA #imm - ^codeptr = ^(bytecode+i)/2; codeptr++ + if ^(bytecode+i) == 0 + ^codeptr = $98; codeptr++ // TYA -> LDA #$00 + else + ^codeptr = $A9; codeptr++ // LDA #imm + ^codeptr = ^(bytecode+i)/2; codeptr++ + fin ^codeptr = $94; codeptr++ // STY zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH //^codeptr = $95; codeptr++ // STA zp,X @@ -262,7 +270,7 @@ def compiler(defptr)#0 when opcode // MINUS1,BREQ,BRNE,LA,LLA,CB,CW,CS ; 20 22 24 26 28 2A 2C 2E is $20 - puts("MINUS_ONE") + //puts("MINUS_ONE") if A_IS_TOSL ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL @@ -280,7 +288,7 @@ def compiler(defptr)#0 i++ dest = i + *(bytecode+i) i++ - puts("BREQ "); puti(dest) + //puts("BREQ "); puti(dest) //^codeptr = $E8; codeptr++ // INX //^codeptr = $E8; codeptr++ // INX codeptr, VX = resolveX(codeptr, VX + 2) @@ -310,7 +318,7 @@ def compiler(defptr)#0 i++ dest = i + *(bytecode+i) i++ - puts("BRNE "); puti(dest) + //puts("BRNE "); puti(dest) //^codeptr = $E8; codeptr++ // INX //^codeptr = $E8; codeptr++ // INX codeptr, VX = resolveX(codeptr, VX + 2) @@ -338,7 +346,7 @@ def compiler(defptr)#0 break is $26 i++ - puts("LA $"); puth(*(bytecode+i)) + //puts("LA $"); puth(*(bytecode+i)) if A_IS_TOSL ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL @@ -357,14 +365,18 @@ def compiler(defptr)#0 break is $28 i++ - puts("LLA "); puti(^(bytecode+i)) + //puts("LLA "); puti(^(bytecode+i)) if A_IS_TOSL ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL fin VX-- //^codeptr = $CA; codeptr++ // DEX - ^codeptr = $A9; codeptr++ // LDA #imm - ^codeptr = ^(bytecode+i); codeptr++ + if ^(bytecode+i) == 0 + ^codeptr = $98; codeptr++ // TYA -> LDA #$00 + else + ^codeptr = $A9; codeptr++ // LDA #imm + ^codeptr = ^(bytecode+i); codeptr++ + fin ^codeptr = $18; codeptr++ // CLC ^codeptr = $65; codeptr++ // ADC zp ^codeptr = $E0; codeptr++ // IFPL @@ -379,7 +391,7 @@ def compiler(defptr)#0 break is $2A i++ - puts("CB $"); putb(^(bytecode+i)) + //puts("CB $"); putb(^(bytecode+i)) if A_IS_TOSL ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL @@ -395,7 +407,7 @@ def compiler(defptr)#0 break is $2C i++ - puts("CW $"); puth(*(bytecode+i)) + //puts("CW $"); puth(*(bytecode+i)) if A_IS_TOSL ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL @@ -405,8 +417,12 @@ def compiler(defptr)#0 ^codeptr = ^(bytecode+i+1); codeptr++ ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH - ^codeptr = $A9; codeptr++ // LDA #imm - ^codeptr = ^(bytecode+i); codeptr++ + if ^(bytecode+i) == 0 + ^codeptr = $98; codeptr++ // TYA -> LDA #$00 + else + ^codeptr = $A9; codeptr++ // LDA #imm + ^codeptr = ^(bytecode+i); codeptr++ + fin //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL A_IS_TOSL = TRUE @@ -416,7 +432,7 @@ def compiler(defptr)#0 i++ j = ^(bytecode+i) dest = i + j + 1 - puts("CS "); puts(bytecode+i); puts("-->"); puti(dest) + //puts("CS "); //puts(bytecode+i); //puts("-->"); puti(dest) if isule(codeptr + 12 + j, codemax) if A_IS_TOSL ^codeptr = $95; codeptr++ // STA zp,X @@ -447,19 +463,19 @@ def compiler(defptr)#0 break // DROP,DROP2,DUP,DIVMOD,ADDI,SUBI,ANDI,ORI ; 30 32 34 36 38 3A 3C 3E is $30 - puts("DROP") + //puts("DROP") VX++ //^codeptr = $E8; codeptr++ // INX A_IS_TOSL = FALSE break is $32 - puts("DROP2") + //puts("DROP2") //^codeptr = $E8; codeptr++ // INX //^codeptr = $E8; codeptr++ // INX VX = VX + 2 A_IS_TOSL = FALSE break is $34 - puts("DUP") + //puts("DUP") if A_IS_TOSL ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL @@ -476,14 +492,14 @@ def compiler(defptr)#0 A_IS_TOSL = TRUE break is $36 - puts("DIVMOD") + //puts("DIVMOD") // // Should never happen // break is $38 i++ - puts("ADDI $"); putb(^(bytecode+i)) + //puts("ADDI $"); putb(^(bytecode+i)) if not A_IS_TOSL ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL @@ -501,7 +517,7 @@ def compiler(defptr)#0 break is $3A i++ - puts("SUBI $"); putb(^(bytecode+i)) + //puts("SUBI $"); putb(^(bytecode+i)) if not A_IS_TOSL ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL @@ -519,7 +535,7 @@ def compiler(defptr)#0 break is $3C i++ - puts("ANDI $"); putb(^(bytecode+i)) + //puts("ANDI $"); putb(^(bytecode+i)) if not A_IS_TOSL ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL @@ -534,7 +550,7 @@ def compiler(defptr)#0 break is $3E i++ - puts("ORI $"); putb(^(bytecode+i)) + //puts("ORI $"); putb(^(bytecode+i)) if not A_IS_TOSL ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL @@ -547,7 +563,7 @@ def compiler(defptr)#0 break // ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E is $40 - puts("ISEQ") + //puts("ISEQ") if not A_IS_TOSL ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL @@ -566,9 +582,6 @@ def compiler(defptr)#0 ^codeptr = $98; codeptr++ // TYA ^codeptr = $94; codeptr++ // STY zp,X ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - // - // Reload zero into Y - // ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = $00; codeptr++ // $00 VX++ //^codeptr = $E8; codeptr++ // INX @@ -577,7 +590,7 @@ def compiler(defptr)#0 A_IS_TOSL = TRUE break is $42 - puts("ISNE") + //puts("ISNE") if not A_IS_TOSL ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL @@ -596,9 +609,6 @@ def compiler(defptr)#0 ^codeptr = $98; codeptr++ // TYA ^codeptr = $94; codeptr++ // STY zp,X ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - // - // Reload zero into Y - // ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = $00; codeptr++ // $00 VX++ //^codeptr = $E8; codeptr++ // INX @@ -607,7 +617,7 @@ def compiler(defptr)#0 A_IS_TOSL = TRUE break is $44 - puts("ISGT") + //puts("ISGT") if not A_IS_TOSL ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL @@ -628,9 +638,6 @@ def compiler(defptr)#0 ^codeptr = $98; codeptr++ // TYA ^codeptr = $94; codeptr++ // STY zp,X ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - // - // Reload zero into Y - // ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = $00; codeptr++ // $00 VX++ //^codeptr = $E8; codeptr++ // INX @@ -639,7 +646,7 @@ def compiler(defptr)#0 A_IS_TOSL = TRUE break is $46 - puts("ISLT") + //puts("ISLT") if A_IS_TOSL ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL @@ -662,9 +669,6 @@ def compiler(defptr)#0 ^codeptr = $98; codeptr++ // TYA ^codeptr = $94; codeptr++ // STY zp,X ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - // - // Reload zero into Y - // ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = $00; codeptr++ // $00 VX++ //^codeptr = $E8; codeptr++ // INX @@ -673,7 +677,7 @@ def compiler(defptr)#0 A_IS_TOSL = TRUE break is $48 - puts("ISGE") + //puts("ISGE") if A_IS_TOSL ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL @@ -696,9 +700,6 @@ def compiler(defptr)#0 ^codeptr = $98; codeptr++ // TYA ^codeptr = $94; codeptr++ // STY zp,X ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - // - // Reload zero into Y - // ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = $00; codeptr++ // $00 VX++ //^codeptr = $E8; codeptr++ // INX @@ -707,7 +708,7 @@ def compiler(defptr)#0 A_IS_TOSL = TRUE break is $4A - puts("ISLE") + //puts("ISLE") if A_IS_TOSL ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL @@ -728,9 +729,6 @@ def compiler(defptr)#0 ^codeptr = $98; codeptr++ // TYA ^codeptr = $94; codeptr++ // STY zp,X ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - // - // Reload zero into Y - // ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = $00; codeptr++ // $00 VX++ //^codeptr = $E8; codeptr++ // INX @@ -742,7 +740,7 @@ def compiler(defptr)#0 i++ dest = i + *(bytecode+i) i++ - puts("BRFLS "); puti(dest) + //puts("BRFLS "); puti(dest) //VX++ //^codeptr = $E8; codeptr++ // INX codeptr, VX = resolveX(codeptr, VX + 1) if not A_IS_TOSL @@ -765,7 +763,7 @@ def compiler(defptr)#0 i++ dest = i + *(bytecode+i) i++ - puts("BRTRU "); puti(dest) + //puts("BRTRU "); puti(dest) //VX++ //^codeptr = $E8; codeptr++ // INX codeptr, VX = resolveX(codeptr, VX + 1) if not A_IS_TOSL @@ -789,7 +787,7 @@ def compiler(defptr)#0 i++ dest = i + *(bytecode+i) i++ - puts("BRNCH "); puti(dest) + //puts("BRNCH "); puti(dest) ^codeptr = $4C; codeptr++ // JMP abs *codeptr = addrxlate=>[dest] if not (*codeptr & $8000) // Unresolved address list @@ -802,7 +800,7 @@ def compiler(defptr)#0 i++ case = i + *(bytecode+i) i++ - puts("SEL "); puti(case); putln + //puts("SEL "); puti(case); putln j = ^(bytecode+case) dest = codeptr + 8 + case * 11) if isule(dest, codemax) @@ -817,7 +815,7 @@ def compiler(defptr)#0 //VX++ //^codeptr = $E8; codeptr++ // INX codeptr, VX = resolveX(codeptr, VX + 1) repeat - puts(" $"); puth(*(bytecode+case)) + //puts(" $"); puth(*(bytecode+case)) ^codeptr = $C9; codeptr++ // CMP #imm ^codeptr = ^(bytecode+case); codeptr++ ^codeptr = $D0; codeptr++ // BNE rel @@ -829,10 +827,7 @@ def compiler(defptr)#0 *(bytecode+case) = $FEFE case = case + 2 dest = case + *(bytecode+case) - puts("-->"); puti(dest); putln - // - // Reload zero into Y - // + //puts("-->"); puti(dest); putln ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = $00; codeptr++ // $00 ^codeptr = $4C; codeptr++ // JMP abs @@ -845,9 +840,6 @@ def compiler(defptr)#0 case = case + 2 j-- until not j - // - // Reload zero into Y - // ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = $00; codeptr++ // $00 ^codeptr = $4C; codeptr++ // JMP abs @@ -863,22 +855,19 @@ def compiler(defptr)#0 break is $54 i++ - puts("CALL $"); puth(*(bytecode+i)) + //puts("CALL $"); puth(*(bytecode+i)) // // Call address // ^codeptr = $20; codeptr++ // JSR abs *codeptr = *(bytecode+i); codeptr = codeptr + 2 - // - // Reload zero into Y - // ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = $00; codeptr++ // $00 A_IS_TOSL = FALSE i++ break is $56 - puts("ICAL") + //puts("ICAL") // // Pull address off stack // @@ -900,16 +889,13 @@ def compiler(defptr)#0 ^codeptr = $20; codeptr++ // JSR abs ^codeptr = $E6; codeptr++ // JMPTMP - // - // Reload zero into Y - // ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = $00; codeptr++ // $00 A_IS_TOSL = FALSE break is $58 i++ - puts("ENTER "); puti(^(bytecode+i)); putc(',');puti(^(bytecode+i+1)) + //puts("ENTER "); puti(^(bytecode+i)); putc(',');puti(^(bytecode+i+1)) // // Call into VM // @@ -920,16 +906,13 @@ def compiler(defptr)#0 i++ ^codeptr = ^(bytecode+i); codeptr++ // ENTER ARG COUNT ^codeptr = $C0; codeptr++ // NATV CODE - // - // Reload zero into Y - // ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = $00; codeptr++ // $00 A_IS_TOSL = FALSE break is $5A i++ - puts("LEAVE "); puti(^(bytecode+i)) + //puts("LEAVE "); puti(^(bytecode+i)) // // Call into VM // @@ -940,13 +923,13 @@ def compiler(defptr)#0 A_IS_TOSL = FALSE break is $5C - puts("RET") + //puts("RET") ^codeptr = $60; codeptr++ // RTS A_IS_TOSL = FALSE break is $5E i++ - puts("CFFB $FF"); putb(^(bytecode+i)) + //puts("CFFB $FF"); putb(^(bytecode+i)) if A_IS_TOSL ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL @@ -964,7 +947,7 @@ def compiler(defptr)#0 break // LB,LW,LLB,LLW,LAB,LAW,DLB,DLW ; 60 62 64 66 68 6A 6C 6E is $60 - puts("LB") + //puts("LB") if not A_IS_TOSL ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL @@ -980,7 +963,7 @@ def compiler(defptr)#0 A_IS_TOSL = TRUE break is $62 - puts("LW") + //puts("LW") if not A_IS_TOSL ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL @@ -1005,7 +988,7 @@ def compiler(defptr)#0 break is $64 i++ - puts("LLB "); puti(^(bytecode+i)) + //puts("LLB "); puti(^(bytecode+i)) if A_IS_TOSL ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL @@ -1017,9 +1000,6 @@ def compiler(defptr)#0 fin ^codeptr = $B1; codeptr++ // LDA (zp),Y ^codeptr = $E0; codeptr++ // IFP - // - // Reload zero into Y - // if ^(bytecode+i) <> 0 ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = $00; codeptr++ // $00 @@ -1032,7 +1012,7 @@ def compiler(defptr)#0 break is $66 i++ - puts("LLW "); puti(^(bytecode+i)) + //puts("LLW "); puti(^(bytecode+i)) if A_IS_TOSL ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL @@ -1051,9 +1031,6 @@ def compiler(defptr)#0 ^codeptr = $E0; codeptr++ // IFP ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH - // - // Reload zero into Y - // if ^(bytecode+i) <> 0 ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = $00; codeptr++ // $00 @@ -1064,7 +1041,7 @@ def compiler(defptr)#0 break is $68 i++ - puts("LAB $"); puth(*(bytecode+i)) + //puts("LAB $"); puth(*(bytecode+i)) if A_IS_TOSL ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL @@ -1081,7 +1058,7 @@ def compiler(defptr)#0 break is $6A i++ - puts("LAW $"); puth(*(bytecode+i)) + //puts("LAW $"); puth(*(bytecode+i)) if A_IS_TOSL ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL @@ -1100,7 +1077,7 @@ def compiler(defptr)#0 break is $6C i++ - puts("DLB "); puti(^(bytecode+i)) + //puts("DLB "); puti(^(bytecode+i)) if not A_IS_TOSL ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL @@ -1111,9 +1088,6 @@ def compiler(defptr)#0 fin ^codeptr = $91; codeptr++ // STA (zp),Y ^codeptr = $E0; codeptr++ // IFP - // - // Reload zero into Y - // if ^(bytecode+i) <> 0 ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = $00; codeptr++ // $00 @@ -1122,7 +1096,7 @@ def compiler(defptr)#0 break is $6E i++ - puts("DLW "); puti(^(bytecode+i)) + //puts("DLW "); puti(^(bytecode+i)) if not A_IS_TOSL ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL @@ -1138,9 +1112,6 @@ def compiler(defptr)#0 ^codeptr = $C0+VX; codeptr++ // ESTKH ^codeptr = $91; codeptr++ // STA (zp),Y ^codeptr = $E0; codeptr++ // IFP - // - // Reload zero into Y - // if ^(bytecode+i) <> 0 ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = $00; codeptr++ // $00 @@ -1151,7 +1122,7 @@ def compiler(defptr)#0 break // SB,SW,SLB,SLW,SAB,SAW,DAB,DAW ; 70 72 74 76 78 7A 7C 7E is $70 - puts("SB") + //puts("SB") if not A_IS_TOSL ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL @@ -1168,7 +1139,7 @@ def compiler(defptr)#0 A_IS_TOSL = FALSE break is $72 - puts("SW") + //puts("SW") if not A_IS_TOSL ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL @@ -1196,7 +1167,7 @@ def compiler(defptr)#0 break is $74 i++ - puts("SLB "); puti(^(bytecode+i)) + //puts("SLB "); puti(^(bytecode+i)) if not A_IS_TOSL ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL @@ -1207,9 +1178,6 @@ def compiler(defptr)#0 fin ^codeptr = $91; codeptr++ // STA (zp),Y ^codeptr = $E0; codeptr++ // IFP - // - // Reload zero into Y - // if ^(bytecode+i) <> 0 ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = $00; codeptr++ // $00 @@ -1219,7 +1187,7 @@ def compiler(defptr)#0 break is $76 i++ - puts("SLW "); puti(^(bytecode+i)) + //puts("SLW "); puti(^(bytecode+i)) if not A_IS_TOSL ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL @@ -1235,9 +1203,6 @@ def compiler(defptr)#0 ^codeptr = $C0+VX; codeptr++ // ESTKH ^codeptr = $91; codeptr++ // STA (zp),Y ^codeptr = $E0; codeptr++ // IFP - // - // Reload zero into Y - // if ^(bytecode+i) <> 0 ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = $00; codeptr++ // $00 @@ -1249,7 +1214,7 @@ def compiler(defptr)#0 break is $78 i++ - puts("SAB $"); puth(*(bytecode+i)) + //puts("SAB $"); puth(*(bytecode+i)) if not A_IS_TOSL ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL @@ -1262,7 +1227,7 @@ def compiler(defptr)#0 break is $7A i++ - puts("SAW $"); puth(*(bytecode+i)) + //puts("SAW $"); puth(*(bytecode+i)) if not A_IS_TOSL ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL @@ -1279,7 +1244,7 @@ def compiler(defptr)#0 break is $7C i++ - puts("DAB $"); puth(*(bytecode+i)) + //puts("DAB $"); puth(*(bytecode+i)) if not A_IS_TOSL ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL @@ -1291,7 +1256,7 @@ def compiler(defptr)#0 break is $7E i++ - puts("DAW $"); puth(*(bytecode+i)) + //puts("DAW $"); puth(*(bytecode+i)) if A_IS_TOSL ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL @@ -1309,7 +1274,7 @@ def compiler(defptr)#0 break // LNOT,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 80 82 84 86 88 8A 8C 8E is $80 - puts("NOT") + //puts("NOT") if not A_IS_TOSL ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL @@ -1329,7 +1294,7 @@ def compiler(defptr)#0 A_IS_TOSL = TRUE break is $82 - puts("ADD") + //puts("ADD") if not A_IS_TOSL ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL @@ -1349,7 +1314,7 @@ def compiler(defptr)#0 A_IS_TOSL = FALSE break is $84 - puts("SUB") + //puts("SUB") if A_IS_TOSL ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL @@ -1371,7 +1336,7 @@ def compiler(defptr)#0 A_IS_TOSL = FALSE break is $86 - puts("MUL") + //puts("MUL") // // Call into VM // @@ -1379,15 +1344,12 @@ def compiler(defptr)#0 *codeptr = $3D0; codeptr = codeptr + 2 ^codeptr = $86; codeptr++ // MUL CODE ^codeptr = $C0; codeptr++ // NATV CODE - // - // Reload zero into Y - // ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = $00; codeptr++ // $00 A_IS_TOSL = FALSE break is $88 - puts("DIV") + //puts("DIV") // // Call into VM // @@ -1395,15 +1357,12 @@ def compiler(defptr)#0 *codeptr = $3D0; codeptr = codeptr + 2 ^codeptr = $88; codeptr++ // DIV CODE ^codeptr = $C0; codeptr++ // NATV CODE - // - // Reload zero into Y - // ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = $00; codeptr++ // $00 A_IS_TOSL = FALSE break is $8A - puts("MOD") + //puts("MOD") // // Call into VM // @@ -1411,15 +1370,12 @@ def compiler(defptr)#0 *codeptr = $3D0; codeptr = codeptr + 2 ^codeptr = $8A; codeptr++ // MOD CODE ^codeptr = $C0; codeptr++ // NATV CODE - // - // Reload zero into Y - // ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = $00; codeptr++ // $00 A_IS_TOSL = FALSE break is $8C - puts("INCR") + //puts("INCR") if A_IS_TOSL ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL @@ -1433,13 +1389,15 @@ def compiler(defptr)#0 A_IS_TOSL = FALSE break is $8E - puts("DECR") + //puts("DECR") if not A_IS_TOSL ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL else - ^codeptr = $C9; codeptr++ // CMP #imm - ^codeptr = $00; codeptr++ // $00 + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $C9; codeptr++ // CMP #imm + ^codeptr = $00; codeptr++ // $00 fin ^codeptr = $D0; codeptr++ // BNE rel ^codeptr = $02; codeptr++ // +2 @@ -1451,7 +1409,7 @@ def compiler(defptr)#0 break // NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 90 92 94 96 98 9A 9C 9E is $90 - puts("NEG") + //puts("NEG") if A_IS_TOSL ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL @@ -1470,7 +1428,7 @@ def compiler(defptr)#0 A_IS_TOSL = FALSE break is $92 - puts("COMP") + //puts("COMP") if not A_IS_TOSL ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL @@ -1488,7 +1446,7 @@ def compiler(defptr)#0 A_IS_TOSL = FALSE break is $94 - puts("AND") + //puts("AND") if not A_IS_TOSL ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL @@ -1507,7 +1465,7 @@ def compiler(defptr)#0 A_IS_TOSL = FALSE break is $96 - puts("OR") + //puts("OR") if not A_IS_TOSL ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL @@ -1526,7 +1484,7 @@ def compiler(defptr)#0 A_IS_TOSL = FALSE break is $98 - puts("XOR") + //puts("XOR") if not A_IS_TOSL ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL @@ -1545,7 +1503,7 @@ def compiler(defptr)#0 A_IS_TOSL = FALSE break is $9A - puts("SHL") + //puts("SHL") // // Call into VM // @@ -1553,15 +1511,12 @@ def compiler(defptr)#0 *codeptr = $3D0; codeptr = codeptr + 2 ^codeptr = $9A; codeptr++ // SHL CODE ^codeptr = $C0; codeptr++ // NATV CODE - // - // Reload zero into Y - // ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = $00; codeptr++ // $00 A_IS_TOSL = FALSE break is $9C - puts("SHR") + //puts("SHR") // // Call into VM // @@ -1569,15 +1524,12 @@ def compiler(defptr)#0 *codeptr = $3D0; codeptr = codeptr + 2 ^codeptr = $9C; codeptr++ // SHR CODE ^codeptr = $C0; codeptr++ // NATV CODE - // - // Reload zero into Y - // ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = $00; codeptr++ // $00 A_IS_TOSL = FALSE break is $9E - puts("IDXW") + //puts("IDXW") if not A_IS_TOSL ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL @@ -1603,7 +1555,7 @@ def compiler(defptr)#0 is $A0 i++ dest = i + *(bytecode+i) - puts("BRGT "); puti(dest) + //puts("BRGT "); puti(dest) i++ codeptr, VX = resolveX(codeptr, VX) if A_IS_TOSL @@ -1631,18 +1583,21 @@ def compiler(defptr)#0 if not (*codeptr & $8000) // Unresolved address list addrxlate=>[dest] = codeptr - *jitcodeptr fin - codeptr = codeptr + 2 + codeptr = codeptr + 2 A_IS_TOSL = FALSE break is $A2 i++ dest = i + *(bytecode+i) - puts("BRLT "); puti(dest) + //puts("BRLT "); puti(dest) i++ codeptr, VX = resolveX(codeptr, VX) if not A_IS_TOSL ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL + else + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL fin ^codeptr = $D5; codeptr++ // CMP zp,X ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 @@ -1663,13 +1618,13 @@ def compiler(defptr)#0 if not (*codeptr & $8000) // Unresolved address list addrxlate=>[dest] = codeptr - *jitcodeptr fin - codeptr = codeptr + 2 + codeptr = codeptr + 2 A_IS_TOSL = FALSE break is $A4 i++ dest = i + *(bytecode+i) - puts("INCBRLE "); puti(dest) + //puts("INCBRLE "); puti(dest) i++ // // INCR @@ -1707,15 +1662,15 @@ def compiler(defptr)#0 if not (*codeptr & $8000) // Unresolved address list addrxlate=>[dest] = codeptr - *jitcodeptr fin - codeptr = codeptr + 2 - ^codeptr = $E8; codeptr++ // INX - ^codeptr = $E8; codeptr++ // INX + codeptr = codeptr + 2 + ^codeptr = $E8; codeptr++ // INX + ^codeptr = $E8; codeptr++ // INX A_IS_TOSL = FALSE break is $A6 i++ dest = i + *(bytecode+i) - puts("ADDBRLE "); puti(dest) + //puts("ADDBRLE "); puti(dest) i++ // // ADD @@ -1759,15 +1714,15 @@ def compiler(defptr)#0 if not (*codeptr & $8000) // Unresolved address list addrxlate=>[dest] = codeptr - *jitcodeptr fin - codeptr = codeptr + 2 - ^codeptr = $E8; codeptr++ // INX - ^codeptr = $E8; codeptr++ // INX + codeptr = codeptr + 2 + ^codeptr = $E8; codeptr++ // INX + ^codeptr = $E8; codeptr++ // INX A_IS_TOSL = FALSE break is $A8 i++ dest = i + *(bytecode+i) - puts("DECBRGE "); puti(dest) + //puts("DECBRGE "); puti(dest) i++ // // DECR @@ -1776,8 +1731,10 @@ def compiler(defptr)#0 ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL else - ^codeptr = $C9; codeptr++ // CMP #imm - ^codeptr = $00; codeptr++ // $00 + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $C9; codeptr++ // CMP #imm + ^codeptr = $00; codeptr++ // $00 fin ^codeptr = $D0; codeptr++ // BNE rel ^codeptr = $02; codeptr++ // +2 @@ -1808,15 +1765,15 @@ def compiler(defptr)#0 if not (*codeptr & $8000) // Unresolved address list addrxlate=>[dest] = codeptr - *jitcodeptr fin - codeptr = codeptr + 2 - ^codeptr = $E8; codeptr++ // INX - ^codeptr = $E8; codeptr++ // INX + codeptr = codeptr + 2 + ^codeptr = $E8; codeptr++ // INX + ^codeptr = $E8; codeptr++ // INX A_IS_TOSL = FALSE break is $AA i++ dest = i + *(bytecode+i) - puts("SUBBRGE "); puti(dest) + //puts("SUBBRGE "); puti(dest) i++ // // SUB @@ -1862,16 +1819,16 @@ def compiler(defptr)#0 if not (*codeptr & $8000) // Unresolved address list addrxlate=>[dest] = codeptr - *jitcodeptr fin - codeptr = codeptr + 2 - ^codeptr = $E8; codeptr++ // INX - ^codeptr = $E8; codeptr++ // INX + codeptr = codeptr + 2 + ^codeptr = $E8; codeptr++ // INX + ^codeptr = $E8; codeptr++ // INX A_IS_TOSL = FALSE break is $AC i++ dest = i + *(bytecode+i) i++ - puts("BRAND "); puti(dest) + //puts("BRAND "); puti(dest) codeptr, VX = resolveX(codeptr, VX) if not A_IS_TOSL ^codeptr = $B5; codeptr++ // LDA zp,X @@ -1886,15 +1843,15 @@ def compiler(defptr)#0 if not (*codeptr & $8000) // Unresolved address list addrxlate=>[dest] = codeptr - *jitcodeptr fin - codeptr = codeptr + 2 - ^codeptr = $E8; codeptr++ // INX + codeptr = codeptr + 2 + ^codeptr = $E8; codeptr++ // INX A_IS_TOSL = FALSE break is $AE i++ dest = i + *(bytecode+i) i++ - puts("BROR "); puti(dest) + //puts("BROR "); puti(dest) codeptr, VX = resolveX(codeptr, VX) if not A_IS_TOSL ^codeptr = $B5; codeptr++ // LDA zp,X @@ -1909,14 +1866,14 @@ def compiler(defptr)#0 if not (*codeptr & $8000) // Unresolved address list addrxlate=>[dest] = codeptr - *jitcodeptr fin - codeptr = codeptr + 2 - ^codeptr = $E8; codeptr++ // INX + codeptr = codeptr + 2 + ^codeptr = $E8; codeptr++ // INX A_IS_TOSL = FALSE break // ADDLB,ADDLW,ADDAB,ADDAW,IDXLB,IDXLW,IDXAB,IDXAW ; B0 B2 B4 B6 B8 BA BC BE is $B0 i++ - puts("ADDLB "); puti(^(bytecode+i)) + //puts("ADDLB "); puti(^(bytecode+i)) if not A_IS_TOSL ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL @@ -1928,24 +1885,21 @@ def compiler(defptr)#0 ^codeptr = $18; codeptr++ // CLC ^codeptr = $71; codeptr++ // ADC (zp),Y ^codeptr = $E0; codeptr++ // IFP - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL ^codeptr = $90; codeptr++ // BCC rel ^codeptr = $02; codeptr++ // +2 ^codeptr = $F6; codeptr++ // INC zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH - // - // Reload zero into Y - // if ^(bytecode+i) <> 0 ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = $00; codeptr++ // $00 fin + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $D0+VX; codeptr++ // ESTKL A_IS_TOSL = TRUE break is $B2 i++ - puts("ADDLW "); puti(^(bytecode+i)) + //puts("ADDLW "); puti(^(bytecode+i)) if not A_IS_TOSL ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL @@ -1966,9 +1920,6 @@ def compiler(defptr)#0 ^codeptr = $E0; codeptr++ // IFP ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH - // - // Reload zero into Y - // if ^(bytecode+i) <> 0 ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = $00; codeptr++ // $00 @@ -1979,7 +1930,7 @@ def compiler(defptr)#0 break is $B4 i++ - puts("ADDAB $"); puth(*(bytecode+i)) + //puts("ADDAB $"); puth(*(bytecode+i)) if not A_IS_TOSL ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL @@ -1998,7 +1949,7 @@ def compiler(defptr)#0 break is $B6 i++ - puts("ADDAW $"); puth(*(bytecode+i)) + //puts("ADDAW $"); puth(*(bytecode+i)) if not A_IS_TOSL ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL @@ -2019,7 +1970,7 @@ def compiler(defptr)#0 break is $B8 i++ - puts("IDXLB "); puti(^(bytecode+i)) + //puts("IDXLB "); puti(^(bytecode+i)) if A_IS_TOSL ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL @@ -2048,16 +1999,13 @@ def compiler(defptr)#0 ^codeptr = $C0+VX; codeptr++ // ESTKH ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH - // - // Reload zero into Y - // - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = $00; codeptr++ // $00 + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $00; codeptr++ // $00 A_IS_TOSL = FALSE break is $BA i++ - puts("IDXLW "); puti(^(bytecode+i)) + //puts("IDXLW "); puti(^(bytecode+i)) if A_IS_TOSL ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL @@ -2088,16 +2036,13 @@ def compiler(defptr)#0 ^codeptr = $C0+VX; codeptr++ // ESTKH ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH - // - // Reload zero into Y - // - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = $00; codeptr++ // $00 + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $00; codeptr++ // $00 A_IS_TOSL = FALSE break is $BC i++ - puts("IDXAB $"); puth(*(bytecode+i)) + //puts("IDXAB $"); puth(*(bytecode+i)) if A_IS_TOSL ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL @@ -2118,17 +2063,14 @@ def compiler(defptr)#0 ^codeptr = $C0+VX; codeptr++ // ESTKH ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH - // - // Reload zero into Y - // - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = $00; codeptr++ // $00 + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $00; codeptr++ // $00 A_IS_TOSL = FALSE i++ break is $BE i++ - puts("IDXAW $"); puth(*(bytecode+i)) + //puts("IDXAW $"); puth(*(bytecode+i)) if A_IS_TOSL ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL @@ -2154,11 +2096,8 @@ def compiler(defptr)#0 ^codeptr = $C0+VX; codeptr++ // ESTKH ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH - // - // Reload zero into Y - // - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = $00; codeptr++ // $00 + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $00; codeptr++ // $00 A_IS_TOSL = FALSE i++ break @@ -2168,7 +2107,7 @@ def compiler(defptr)#0 //putc('$'); puth(^(bytecode+i)) wend fin - putln + //putln i++ if i >= defptr->bytecodesize // @@ -2181,11 +2120,11 @@ def compiler(defptr)#0 // Free working bufffers // //heaprelease(addrxlate) - puts("Done compiling: $"); puth(defptr=>interpaddr); putln - getc + //puts("Done compiling: $"); puth(defptr=>interpaddr); putln + //getc return fin - getc + //getc loop // // If we got here. we ran out of code buffer space. Overwrite interpreter @@ -2196,7 +2135,7 @@ def compiler(defptr)#0 // Free working bufffers // //heaprelease(addrxlate) - puts("Ran out of code buffer\n") + //puts("Ran out of code buffer\n") //getc end // From 72a7996871fd9258048806dead889a80092b845b Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Fri, 23 Mar 2018 11:26:25 -0700 Subject: [PATCH 085/147] Fix optimization fences and BROR/BRAND/DUP/DLW --- src/libsrc/apple/jit.pla | 350 ++++++++++++++++++--------------------- 1 file changed, 164 insertions(+), 186 deletions(-) diff --git a/src/libsrc/apple/jit.pla b/src/libsrc/apple/jit.pla index c2d15b1..8075677 100644 --- a/src/libsrc/apple/jit.pla +++ b/src/libsrc/apple/jit.pla @@ -82,10 +82,18 @@ def compiler(defptr)#0 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 @@ -106,6 +114,7 @@ def compiler(defptr)#0 is $3A // SUBI is $3C // ANDI is $3E // ORI + is $5A // LEAVE is $5E // CFFB is $64 // LLB is $66 // LLW @@ -120,16 +129,9 @@ def compiler(defptr)#0 i++ break // - // Multi-byte operands - // - is $2E // CS - i = i + ^(bytecode+i+1) + 1 - break - // // Branches // is $50 // BRNCH - ^(bytecode+i) = ^(bytecode+i) | 1 is $22 // BREQ is $24 // BENE is $4C // BRFLS @@ -151,29 +153,6 @@ def compiler(defptr)#0 i++ break // - // VM calls - // - is $54 // CALL - is $58 // ENTER, two byte operands - ^(bytecode+i) = ^(bytecode+i) | 1 - i = i + 2 - break - is $5A // LEAVE, one byte operand - ^(bytecode+i) = ^(bytecode+i) | 1 - i++ - break - is $86 // MULL - is $88 // DIV - is $8A // MOD - is $9A // SHL - is $9C // SHR - // - // External control - // - is $5C // RET - ^(bytecode+i) = ^(bytecode+i) | 1 - break - // // SELect/caseblock // is $52 // SEL @@ -205,17 +184,44 @@ def compiler(defptr)#0 // // Compile the bytecodes // - codeptr = *jitcodeptr - VX = 0 // Virtual X register - i = 0 + codeptr = *jitcodeptr + VX = 0 // Virtual X register + A_IS_TOSL = FALSE + i = 0 + if ^bytecode == $58 + //puts("ENTER "); puti(^(bytecode+1)); //putc(',');puti(^(bytecode+2)) + // + // Call into VM + // + ^codeptr = $20; codeptr++ // JSR INTERP + *codeptr = $3D0; codeptr = codeptr + 2 + ^codeptr = $58; codeptr++ // ENTER CODE + ^codeptr = ^(bytecode+1); codeptr++ // ENTER FRAME SIZE + ^codeptr = ^(bytecode+2); codeptr++ // ENTER ARG COUNT + ^codeptr = $C0; codeptr++ // NATV CODE + i = 3 + fin // // First optimization is to keep zero in Y register at all times // - if ^bytecode & $FE <> $58 // ENTER will set Y to zero - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = $00; codeptr++ // $00 - fin + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $00; codeptr++ // $00 while isule(codeptr, codemax) + //putc('$'); puth(codeptr); //putc(':') + //putc('['); puti(i); //puts("] ") + opcode = ^(bytecode+i) + if opcode & 1 + // + // Optimization fence + // + if A_IS_TOSL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + A_IS_TOSL = FALSE + fin + codeptr, VX = resolveX(codeptr, VX) + opcode = opcode & $FE + fin // // Update bytecode->native code address translation // @@ -231,21 +237,6 @@ def compiler(defptr)#0 until not case fin addrxlate=>[i] = codeptr - //putc('$'); puth(codeptr); putc(':') - //putc('['); puti(i); //puts("] ") - opcode = ^(bytecode+i) - if opcode & 1 - // - // Optimization fence - // - if A_IS_TOSL - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL - A_IS_TOSL = FALSE - fin - codeptr, VX = resolveX(codeptr, VX) - opcode = opcode & $FE - fin if opcode < $20 // CN,CN,CN,CN,CN,CN,CN,CN ; 00 02 04 06 08 0A 0C 0E // CN,CN,CN,CN,CN,CN,CN,CN ; 10 12 14 16 18 1A 1C 1E @@ -479,14 +470,19 @@ def compiler(defptr)#0 if A_IS_TOSL ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL + else + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL fin VX-- //^codeptr = $CA; codeptr++ // DEX - ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $B4; codeptr++ // LDY zp,X ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $94; codeptr++ // STY zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $00; codeptr++ // $00 + //^codeptr = $B5; codeptr++ // LDA zp,X + //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL A_IS_TOSL = TRUE @@ -788,6 +784,11 @@ def compiler(defptr)#0 dest = i + *(bytecode+i) i++ //puts("BRNCH "); puti(dest) + codeptr, VX = resolveX(codeptr, VX) + if A_IS_TOSL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin ^codeptr = $4C; codeptr++ // JMP abs *codeptr = addrxlate=>[dest] if not (*codeptr & $8000) // Unresolved address list @@ -859,6 +860,11 @@ def compiler(defptr)#0 // // Call address // + if A_IS_TOSL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin + codeptr, VX = resolveX(codeptr, VX) ^codeptr = $20; codeptr++ // JSR abs *codeptr = *(bytecode+i); codeptr = codeptr + 2 ^codeptr = $A0; codeptr++ // LDY #imm @@ -893,29 +899,17 @@ def compiler(defptr)#0 ^codeptr = $00; codeptr++ // $00 A_IS_TOSL = FALSE break - is $58 - i++ - //puts("ENTER "); puti(^(bytecode+i)); putc(',');puti(^(bytecode+i+1)) - // - // Call into VM - // - ^codeptr = $20; codeptr++ // JSR INTERP - *codeptr = $3D0; codeptr = codeptr + 2 - ^codeptr = $58; codeptr++ // ENTER CODE - ^codeptr = ^(bytecode+i); codeptr++ // ENTER FRAME SIZE - i++ - ^codeptr = ^(bytecode+i); codeptr++ // ENTER ARG COUNT - ^codeptr = $C0; codeptr++ // NATV CODE - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = $00; codeptr++ // $00 - A_IS_TOSL = FALSE - break is $5A i++ //puts("LEAVE "); puti(^(bytecode+i)) // // Call into VM // + if A_IS_TOSL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin + codeptr, VX = resolveX(codeptr, VX) ^codeptr = $20; codeptr++ // JSR INTERP *codeptr = $3D0; codeptr = codeptr + 2 ^codeptr = $5A; codeptr++ // LEAVE CODE @@ -924,6 +918,11 @@ def compiler(defptr)#0 break is $5C //puts("RET") + if A_IS_TOSL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin + codeptr, VX = resolveX(codeptr, VX) ^codeptr = $60; codeptr++ // RTS A_IS_TOSL = FALSE break @@ -1092,33 +1091,35 @@ def compiler(defptr)#0 ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = $00; codeptr++ // $00 fin - A_IS_TOSL = FALSE + A_IS_TOSL = TRUE break is $6E i++ //puts("DLW "); puti(^(bytecode+i)) - if not A_IS_TOSL - ^codeptr = $B5; codeptr++ // LDA zp,X + if A_IS_TOSL + ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL fin if ^(bytecode+i) <> 0 ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = ^(bytecode+i); codeptr++ + ^codeptr = ^(bytecode+i)+1; codeptr++ + else + ^codeptr = $C8; codeptr++ // INY fin - ^codeptr = $91; codeptr++ // STA (zp),Y - ^codeptr = $E0; codeptr++ // IFP - ^codeptr = $C8; codeptr++ // INY ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH ^codeptr = $91; codeptr++ // STA (zp),Y ^codeptr = $E0; codeptr++ // IFP + ^codeptr = $88; codeptr++ // DEY + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $91; codeptr++ // STA (zp),Y + ^codeptr = $E0; codeptr++ // IFP if ^(bytecode+i) <> 0 ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = $00; codeptr++ // $00 - else - ^codeptr = $88; codeptr++ // DEY fin - A_IS_TOSL = FALSE + A_IS_TOSL = TRUE break // SB,SW,SLB,SLW,SAB,SAW,DAB,DAW ; 70 72 74 76 78 7A 7C 7E is $70 @@ -1257,18 +1258,18 @@ def compiler(defptr)#0 is $7E i++ //puts("DAW $"); puth(*(bytecode+i)) - if A_IS_TOSL - ^codeptr = $95; codeptr++ // STA zp,X + if not A_IS_TOSL + ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL fin - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH - ^codeptr = $8D; codeptr++ // STA abs - *codeptr = *(bytecode+i)+1; codeptr = codeptr + 2 - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL ^codeptr = $8D; codeptr++ // STA abs *codeptr = *(bytecode+i); codeptr = codeptr + 2 + ^codeptr = $B4; codeptr++ // LDY zp,X + ^codeptr = $C0+VX; codeptr++ // ESTKH + ^codeptr = $8C; codeptr++ // STY abs + *codeptr = *(bytecode+i)+1; codeptr = codeptr + 2 + ^codeptr = $A0; codeptr++ // LDY #imm + ^codeptr = $00; codeptr++ // $00 A_IS_TOSL = TRUE i++ break @@ -1335,77 +1336,73 @@ def compiler(defptr)#0 VX++ //^codeptr = $E8; codeptr++ // INX A_IS_TOSL = FALSE break - is $86 - //puts("MUL") + 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_TOSL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + fin + codeptr, VX = resolveX(codeptr, VX) ^codeptr = $20; codeptr++ // JSR INTERP *codeptr = $3D0; codeptr = codeptr + 2 - ^codeptr = $86; codeptr++ // MUL CODE + ^codeptr = opcode; codeptr++ // OPCODE ^codeptr = $C0; codeptr++ // NATV CODE ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = $00; codeptr++ // $00 A_IS_TOSL = FALSE break - is $88 - //puts("DIV") - // - // Call into VM - // - ^codeptr = $20; codeptr++ // JSR INTERP - *codeptr = $3D0; codeptr = codeptr + 2 - ^codeptr = $88; codeptr++ // DIV CODE - ^codeptr = $C0; codeptr++ // NATV CODE - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = $00; codeptr++ // $00 - A_IS_TOSL = FALSE - break - is $8A - //puts("MOD") - // - // Call into VM - // - ^codeptr = $20; codeptr++ // JSR INTERP - *codeptr = $3D0; codeptr = codeptr + 2 - ^codeptr = $8A; codeptr++ // MOD CODE - ^codeptr = $C0; codeptr++ // NATV CODE - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = $00; codeptr++ // $00 - A_IS_TOSL = FALSE - break - is $8C + is $8C //puts("INCR") - if A_IS_TOSL - ^codeptr = $95; codeptr++ // STA zp,X + if not A_IS_TOSL + ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL fin - ^codeptr = $F6; codeptr++ // INC zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL - ^codeptr = $D0; codeptr++ // BNE rel - ^codeptr = $02; codeptr++ // +2 + ^codeptr = $18; codeptr++ // CLC + ^codeptr = $69; codeptr++ // ADC #imm + ^codeptr = $01; codeptr++ // $01 + ^codeptr = $90; codeptr++ // BCC rel + ^codeptr = $02; codeptr++ // +2 ^codeptr = $F6; codeptr++ // INC zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH - A_IS_TOSL = FALSE + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $D0+VX; codeptr++ // ESTKL + A_IS_TOSL = TRUE break is $8E //puts("DECR") if not A_IS_TOSL ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL - else - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL - ^codeptr = $C9; codeptr++ // CMP #imm - ^codeptr = $00; codeptr++ // $00 fin - ^codeptr = $D0; codeptr++ // BNE rel - ^codeptr = $02; codeptr++ // +2 + ^codeptr = $38; codeptr++ // SEC + ^codeptr = $E9; codeptr++ // SBC #imm + ^codeptr = $01; codeptr++ // $01 + ^codeptr = $B0; codeptr++ // BCS rel + ^codeptr = $02; codeptr++ // +2 ^codeptr = $D6; codeptr++ // DEC zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH - ^codeptr = $D6; codeptr++ // DEC zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL - A_IS_TOSL = FALSE + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $D0+VX; codeptr++ // ESTKL + A_IS_TOSL = TRUE break // NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 90 92 94 96 98 9A 9C 9E is $90 @@ -1502,32 +1499,6 @@ def compiler(defptr)#0 VX++ //^codeptr = $E8; codeptr++ // INX A_IS_TOSL = FALSE break - is $9A - //puts("SHL") - // - // Call into VM - // - ^codeptr = $20; codeptr++ // JSR INTERP - *codeptr = $3D0; codeptr = codeptr + 2 - ^codeptr = $9A; codeptr++ // SHL CODE - ^codeptr = $C0; codeptr++ // NATV CODE - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = $00; codeptr++ // $00 - A_IS_TOSL = FALSE - break - is $9C - //puts("SHR") - // - // Call into VM - // - ^codeptr = $20; codeptr++ // JSR INTERP - *codeptr = $3D0; codeptr = codeptr + 2 - ^codeptr = $9C; codeptr++ // SHR CODE - ^codeptr = $C0; codeptr++ // NATV CODE - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = $00; codeptr++ // $00 - A_IS_TOSL = FALSE - break is $9E //puts("IDXW") if not A_IS_TOSL @@ -1629,14 +1600,17 @@ def compiler(defptr)#0 // // INCR // - if A_IS_TOSL - ^codeptr = $95; codeptr++ // STA zp,X + if not A_IS_TOSL + ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL fin - ^codeptr = $F6; codeptr++ // INC zp,X + ^codeptr = $18; codeptr++ // CLC + ^codeptr = $69; codeptr++ // ADC #imm + ^codeptr = $01; codeptr++ // $01 + ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL - ^codeptr = $D0; codeptr++ // BNE rel - ^codeptr = $02; codeptr++ // +2 + ^codeptr = $90; codeptr++ // BCC rel + ^codeptr = $02; codeptr++ // +2 ^codeptr = $F6; codeptr++ // INC zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH // @@ -1730,24 +1704,22 @@ def compiler(defptr)#0 if not A_IS_TOSL ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL - else - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL - ^codeptr = $C9; codeptr++ // CMP #imm - ^codeptr = $00; codeptr++ // $00 fin - ^codeptr = $D0; codeptr++ // BNE rel - ^codeptr = $02; codeptr++ // +2 + ^codeptr = $38; codeptr++ // SEC + ^codeptr = $E9; codeptr++ // SBC #imm + ^codeptr = $01; codeptr++ // $01 + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + ^codeptr = $B0; codeptr++ // BCS rel + ^codeptr = $02; codeptr++ // +2 ^codeptr = $D6; codeptr++ // DEC zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH - ^codeptr = $D6; codeptr++ // DEC zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL // // BRGE // codeptr, VX = resolveX(codeptr, VX) - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + //^codeptr = $B5; codeptr++ // LDA zp,X + //^codeptr = $D0+VX; codeptr++ // ESTKL ^codeptr = $D5; codeptr++ // CMP zp,X ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 ^codeptr = $B5; codeptr++ // LDA zp,X @@ -1830,7 +1802,10 @@ def compiler(defptr)#0 i++ //puts("BRAND "); puti(dest) codeptr, VX = resolveX(codeptr, VX) - if not A_IS_TOSL + if A_IS_TOSL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + else ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL fin @@ -1844,7 +1819,7 @@ def compiler(defptr)#0 addrxlate=>[dest] = codeptr - *jitcodeptr fin codeptr = codeptr + 2 - ^codeptr = $E8; codeptr++ // INX + ^codeptr = $E8; codeptr++ // INX VX++ ??? A_IS_TOSL = FALSE break is $AE @@ -1853,7 +1828,10 @@ def compiler(defptr)#0 i++ //puts("BROR "); puti(dest) codeptr, VX = resolveX(codeptr, VX) - if not A_IS_TOSL + if A_IS_TOSL + ^codeptr = $95; codeptr++ // STA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL + else ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL fin @@ -1867,7 +1845,7 @@ def compiler(defptr)#0 addrxlate=>[dest] = codeptr - *jitcodeptr fin codeptr = codeptr + 2 - ^codeptr = $E8; codeptr++ // INX + ^codeptr = $E8; codeptr++ // INX // VX++ ??? A_IS_TOSL = FALSE break // ADDLB,ADDLW,ADDAB,ADDAW,IDXLB,IDXLW,IDXAB,IDXAW ; B0 B2 B4 B6 B8 BA BC BE @@ -2120,8 +2098,8 @@ def compiler(defptr)#0 // Free working bufffers // //heaprelease(addrxlate) - //puts("Done compiling: $"); puth(defptr=>interpaddr); putln - //getc + puts("Done compiling: $"); puth(defptr=>interpaddr); putln + getc return fin //getc From 36c2506a241b9ef277ecf3adea5ad6e07f36f61d Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Fri, 23 Mar 2018 11:33:01 -0700 Subject: [PATCH 086/147] Move max code buffer down a smidge --- src/libsrc/apple/jit.pla | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libsrc/apple/jit.pla b/src/libsrc/apple/jit.pla index 8075677..3627f7e 100644 --- a/src/libsrc/apple/jit.pla +++ b/src/libsrc/apple/jit.pla @@ -23,7 +23,7 @@ end const jitcount = $10 const jitcomp = $03E2 const jitcodeptr = $03E4 -const codemax = $BEF0 +const codemax = $BEE0 // // AUX bytecode interpreter entrypoint // @@ -2098,8 +2098,8 @@ def compiler(defptr)#0 // Free working bufffers // //heaprelease(addrxlate) - puts("Done compiling: $"); puth(defptr=>interpaddr); putln - getc + //puts("Done compiling: $"); puth(defptr=>interpaddr); putln + //getc return fin //getc From 3c72bb9df3ceba67008e7d68795ea0c3f2ac51b5 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Fri, 23 Mar 2018 12:31:17 -0700 Subject: [PATCH 087/147] Better TOSL cache checks --- src/libsrc/apple/jit.pla | 131 ++++++++++++++++++++------------------- 1 file changed, 68 insertions(+), 63 deletions(-) diff --git a/src/libsrc/apple/jit.pla b/src/libsrc/apple/jit.pla index 3627f7e..7d60480 100644 --- a/src/libsrc/apple/jit.pla +++ b/src/libsrc/apple/jit.pla @@ -29,6 +29,11 @@ const codemax = $BEE0 // const interpentry = $03DC // +// TOS caching values +// +const TOSL_DIRTY = 1 +const TOSL_CLEAN = 2 +// // Resolve virtual X with real X // def resolveX(codeptr, VX)#2 @@ -214,7 +219,7 @@ def compiler(defptr)#0 // // Optimization fence // - if A_IS_TOSL + if A_IS_TOSL & TOSL_DIRTY ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL A_IS_TOSL = FALSE @@ -241,7 +246,7 @@ def compiler(defptr)#0 // CN,CN,CN,CN,CN,CN,CN,CN ; 00 02 04 06 08 0A 0C 0E // CN,CN,CN,CN,CN,CN,CN,CN ; 10 12 14 16 18 1A 1C 1E //puts("CN $"); putb(^(bytecode+i)/2) - if A_IS_TOSL + if A_IS_TOSL & TOSL_DIRTY ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL fin @@ -256,13 +261,13 @@ def compiler(defptr)#0 ^codeptr = $C0+VX; codeptr++ // ESTKH //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL - A_IS_TOSL = TRUE + A_IS_TOSL = TOSL_DIRTY else when opcode // MINUS1,BREQ,BRNE,LA,LLA,CB,CW,CS ; 20 22 24 26 28 2A 2C 2E is $20 //puts("MINUS_ONE") - if A_IS_TOSL + if A_IS_TOSL & TOSL_DIRTY ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL fin @@ -273,7 +278,7 @@ def compiler(defptr)#0 ^codeptr = $C0+VX; codeptr++ // ESTKH //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL - A_IS_TOSL = TRUE + A_IS_TOSL = TOSL_DIRTY break is $22 i++ @@ -338,7 +343,7 @@ def compiler(defptr)#0 is $26 i++ //puts("LA $"); puth(*(bytecode+i)) - if A_IS_TOSL + if A_IS_TOSL & TOSL_DIRTY ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL fin @@ -351,13 +356,13 @@ def compiler(defptr)#0 ^codeptr = ^(bytecode+i); codeptr++ //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL - A_IS_TOSL = TRUE + A_IS_TOSL = TOSL_DIRTY i++ break is $28 i++ //puts("LLA "); puti(^(bytecode+i)) - if A_IS_TOSL + if A_IS_TOSL & TOSL_DIRTY ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL fin @@ -383,7 +388,7 @@ def compiler(defptr)#0 is $2A i++ //puts("CB $"); putb(^(bytecode+i)) - if A_IS_TOSL + if A_IS_TOSL & TOSL_DIRTY ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL fin @@ -394,12 +399,12 @@ def compiler(defptr)#0 ^codeptr = $C0+VX; codeptr++ // ESTKH //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL - A_IS_TOSL = TRUE + A_IS_TOSL = TOSL_DIRTY break is $2C i++ //puts("CW $"); puth(*(bytecode+i)) - if A_IS_TOSL + if A_IS_TOSL & TOSL_DIRTY ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL fin @@ -416,7 +421,7 @@ def compiler(defptr)#0 fin //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL - A_IS_TOSL = TRUE + A_IS_TOSL = TOSL_DIRTY i++ break is $2E @@ -425,7 +430,7 @@ def compiler(defptr)#0 dest = i + j + 1 //puts("CS "); //puts(bytecode+i); //puts("-->"); puti(dest) if isule(codeptr + 12 + j, codemax) - if A_IS_TOSL + if A_IS_TOSL & TOSL_DIRTY ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL fin @@ -467,7 +472,7 @@ def compiler(defptr)#0 break is $34 //puts("DUP") - if A_IS_TOSL + if A_IS_TOSL & TOSL_DIRTY ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL else @@ -485,7 +490,7 @@ def compiler(defptr)#0 //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL - A_IS_TOSL = TRUE + A_IS_TOSL = TOSL_DIRTY break is $36 //puts("DIVMOD") @@ -509,7 +514,7 @@ def compiler(defptr)#0 ^codeptr = $C0+VX; codeptr++ // ESTKH //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL - A_IS_TOSL = TRUE + A_IS_TOSL = TOSL_DIRTY break is $3A i++ @@ -527,7 +532,7 @@ def compiler(defptr)#0 ^codeptr = $C0+VX; codeptr++ // ESTKH //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL - A_IS_TOSL = TRUE + A_IS_TOSL = TOSL_DIRTY break is $3C i++ @@ -542,7 +547,7 @@ def compiler(defptr)#0 ^codeptr = $C0+VX; codeptr++ // ESTKH //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL - A_IS_TOSL = TRUE + A_IS_TOSL = TOSL_DIRTY break is $3E i++ @@ -555,7 +560,7 @@ def compiler(defptr)#0 ^codeptr = ^(bytecode+i); codeptr++ //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL - A_IS_TOSL = TRUE + A_IS_TOSL = TOSL_DIRTY break // ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E is $40 @@ -583,7 +588,7 @@ def compiler(defptr)#0 VX++ //^codeptr = $E8; codeptr++ // INX //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL - A_IS_TOSL = TRUE + A_IS_TOSL = TOSL_DIRTY break is $42 //puts("ISNE") @@ -610,7 +615,7 @@ def compiler(defptr)#0 VX++ //^codeptr = $E8; codeptr++ // INX //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL - A_IS_TOSL = TRUE + A_IS_TOSL = TOSL_DIRTY break is $44 //puts("ISGT") @@ -639,11 +644,11 @@ def compiler(defptr)#0 VX++ //^codeptr = $E8; codeptr++ // INX //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL - A_IS_TOSL = TRUE + A_IS_TOSL = TOSL_DIRTY break is $46 //puts("ISLT") - if A_IS_TOSL + if A_IS_TOSL & TOSL_DIRTY ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL fin @@ -670,11 +675,11 @@ def compiler(defptr)#0 VX++ //^codeptr = $E8; codeptr++ // INX //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL - A_IS_TOSL = TRUE + A_IS_TOSL = TOSL_DIRTY break is $48 //puts("ISGE") - if A_IS_TOSL + if A_IS_TOSL & TOSL_DIRTY ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL fin @@ -701,11 +706,11 @@ def compiler(defptr)#0 VX++ //^codeptr = $E8; codeptr++ // INX //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL - A_IS_TOSL = TRUE + A_IS_TOSL = TOSL_DIRTY break is $4A //puts("ISLE") - if A_IS_TOSL + if A_IS_TOSL & TOSL_DIRTY ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL fin @@ -730,7 +735,7 @@ def compiler(defptr)#0 VX++ //^codeptr = $E8; codeptr++ // INX //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL - A_IS_TOSL = TRUE + A_IS_TOSL = TOSL_DIRTY break is $4C i++ @@ -785,7 +790,7 @@ def compiler(defptr)#0 i++ //puts("BRNCH "); puti(dest) codeptr, VX = resolveX(codeptr, VX) - if A_IS_TOSL + if A_IS_TOSL & TOSL_DIRTY ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL fin @@ -860,7 +865,7 @@ def compiler(defptr)#0 // // Call address // - if A_IS_TOSL + if A_IS_TOSL & TOSL_DIRTY ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL fin @@ -905,7 +910,7 @@ def compiler(defptr)#0 // // Call into VM // - if A_IS_TOSL + if A_IS_TOSL & TOSL_DIRTY ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL fin @@ -918,7 +923,7 @@ def compiler(defptr)#0 break is $5C //puts("RET") - if A_IS_TOSL + if A_IS_TOSL & TOSL_DIRTY ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL fin @@ -929,7 +934,7 @@ def compiler(defptr)#0 is $5E i++ //puts("CFFB $FF"); putb(^(bytecode+i)) - if A_IS_TOSL + if A_IS_TOSL & TOSL_DIRTY ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL fin @@ -942,7 +947,7 @@ def compiler(defptr)#0 ^codeptr = ^(bytecode+i); codeptr++ //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL - A_IS_TOSL = TRUE + A_IS_TOSL = TOSL_DIRTY break // LB,LW,LLB,LLW,LAB,LAW,DLB,DLW ; 60 62 64 66 68 6A 6C 6E is $60 @@ -959,7 +964,7 @@ def compiler(defptr)#0 ^codeptr = $C0+VX; codeptr++ // ESTKH //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL - A_IS_TOSL = TRUE + A_IS_TOSL = TOSL_DIRTY break is $62 //puts("LW") @@ -988,7 +993,7 @@ def compiler(defptr)#0 is $64 i++ //puts("LLB "); puti(^(bytecode+i)) - if A_IS_TOSL + if A_IS_TOSL & TOSL_DIRTY ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL fin @@ -1007,12 +1012,12 @@ def compiler(defptr)#0 ^codeptr = $C0+VX; codeptr++ // ESTKH //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL - A_IS_TOSL = TRUE + A_IS_TOSL = TOSL_DIRTY break is $66 i++ //puts("LLW "); puti(^(bytecode+i)) - if A_IS_TOSL + if A_IS_TOSL & TOSL_DIRTY ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL fin @@ -1041,7 +1046,7 @@ def compiler(defptr)#0 is $68 i++ //puts("LAB $"); puth(*(bytecode+i)) - if A_IS_TOSL + if A_IS_TOSL & TOSL_DIRTY ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL fin @@ -1052,13 +1057,13 @@ def compiler(defptr)#0 ^codeptr = $C0+VX; codeptr++ // ESTKH //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL - A_IS_TOSL = TRUE + A_IS_TOSL = TOSL_DIRTY i++ break is $6A i++ //puts("LAW $"); puth(*(bytecode+i)) - if A_IS_TOSL + if A_IS_TOSL & TOSL_DIRTY ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL fin @@ -1071,7 +1076,7 @@ def compiler(defptr)#0 *codeptr = *(bytecode+i); codeptr = codeptr + 2 //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL - A_IS_TOSL = TRUE + A_IS_TOSL = TOSL_DIRTY i++ break is $6C @@ -1080,6 +1085,7 @@ def compiler(defptr)#0 if not A_IS_TOSL ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL + A_IS_TOSL = TOSL_CLEAN fin if ^(bytecode+i) <> 0 ^codeptr = $A0; codeptr++ // LDY #imm @@ -1091,12 +1097,11 @@ def compiler(defptr)#0 ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = $00; codeptr++ // $00 fin - A_IS_TOSL = TRUE break is $6E i++ //puts("DLW "); puti(^(bytecode+i)) - if A_IS_TOSL + if A_IS_TOSL & TOSL_DIRTY ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL fin @@ -1119,7 +1124,7 @@ def compiler(defptr)#0 ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = $00; codeptr++ // $00 fin - A_IS_TOSL = TRUE + A_IS_TOSL = TOSL_CLEAN break // SB,SW,SLB,SLW,SAB,SAW,DAB,DAW ; 70 72 74 76 78 7A 7C 7E is $70 @@ -1249,10 +1254,10 @@ def compiler(defptr)#0 if not A_IS_TOSL ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL + A_IS_TOSL = TOSL_CLEAN fin ^codeptr = $8D; codeptr++ // STA abs *codeptr = *(bytecode+i); codeptr = codeptr + 2 - A_IS_TOSL = TRUE i++ break is $7E @@ -1270,7 +1275,7 @@ def compiler(defptr)#0 *codeptr = *(bytecode+i)+1; codeptr = codeptr + 2 ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = $00; codeptr++ // $00 - A_IS_TOSL = TRUE + A_IS_TOSL = TOSL_CLEAN i++ break // LNOT,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 80 82 84 86 88 8A 8C 8E @@ -1292,7 +1297,7 @@ def compiler(defptr)#0 ^codeptr = $C0+VX; codeptr++ // ESTKH //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL - A_IS_TOSL = TRUE + A_IS_TOSL = TOSL_DIRTY break is $82 //puts("ADD") @@ -1316,7 +1321,7 @@ def compiler(defptr)#0 break is $84 //puts("SUB") - if A_IS_TOSL + if A_IS_TOSL & TOSL_DIRTY ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL fin @@ -1357,7 +1362,7 @@ def compiler(defptr)#0 // // Call into VM // - if A_IS_TOSL + if A_IS_TOSL & TOSL_DIRTY ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL fin @@ -1385,7 +1390,7 @@ def compiler(defptr)#0 ^codeptr = $C0+VX; codeptr++ // ESTKH //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL - A_IS_TOSL = TRUE + A_IS_TOSL = TOSL_DIRTY break is $8E //puts("DECR") @@ -1402,12 +1407,12 @@ def compiler(defptr)#0 ^codeptr = $C0+VX; codeptr++ // ESTKH //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL - A_IS_TOSL = TRUE + A_IS_TOSL = TOSL_DIRTY break // NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 90 92 94 96 98 9A 9C 9E is $90 //puts("NEG") - if A_IS_TOSL + if A_IS_TOSL & TOSL_DIRTY ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL fin @@ -1529,7 +1534,7 @@ def compiler(defptr)#0 //puts("BRGT "); puti(dest) i++ codeptr, VX = resolveX(codeptr, VX) - if A_IS_TOSL + if A_IS_TOSL & TOSL_DIRTY ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL fin @@ -1750,7 +1755,7 @@ def compiler(defptr)#0 // // SUB // - if A_IS_TOSL + if A_IS_TOSL & TOSL_DIRTY ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL fin @@ -1802,7 +1807,7 @@ def compiler(defptr)#0 i++ //puts("BRAND "); puti(dest) codeptr, VX = resolveX(codeptr, VX) - if A_IS_TOSL + if A_IS_TOSL & TOSL_DIRTY ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL else @@ -1828,7 +1833,7 @@ def compiler(defptr)#0 i++ //puts("BROR "); puti(dest) codeptr, VX = resolveX(codeptr, VX) - if A_IS_TOSL + if A_IS_TOSL & TOSL_DIRTY ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL else @@ -1873,7 +1878,7 @@ def compiler(defptr)#0 fin //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL - A_IS_TOSL = TRUE + A_IS_TOSL = TOSL_DIRTY break is $B2 i++ @@ -1922,7 +1927,7 @@ def compiler(defptr)#0 ^codeptr = $C0+VX; codeptr++ // ESTKH //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL - A_IS_TOSL = TRUE + A_IS_TOSL = TOSL_DIRTY i++ break is $B6 @@ -1949,7 +1954,7 @@ def compiler(defptr)#0 is $B8 i++ //puts("IDXLB "); puti(^(bytecode+i)) - if A_IS_TOSL + if A_IS_TOSL & TOSL_DIRTY ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL fin @@ -1984,7 +1989,7 @@ def compiler(defptr)#0 is $BA i++ //puts("IDXLW "); puti(^(bytecode+i)) - if A_IS_TOSL + if A_IS_TOSL & TOSL_DIRTY ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL fin @@ -2021,7 +2026,7 @@ def compiler(defptr)#0 is $BC i++ //puts("IDXAB $"); puth(*(bytecode+i)) - if A_IS_TOSL + if A_IS_TOSL & TOSL_DIRTY ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL fin @@ -2049,7 +2054,7 @@ def compiler(defptr)#0 is $BE i++ //puts("IDXAW $"); puth(*(bytecode+i)) - if A_IS_TOSL + if A_IS_TOSL & TOSL_DIRTY ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL fin From 8b1ca4bf1ed2bce97730610aefe5c1129cda2646 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Fri, 23 Mar 2018 16:05:39 -0700 Subject: [PATCH 088/147] Fix DLW TOSL_DIRTY --- src/libsrc/apple/jit.pla | 2 +- src/toolsrc/codegen.pla | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/libsrc/apple/jit.pla b/src/libsrc/apple/jit.pla index 7d60480..034aaee 100644 --- a/src/libsrc/apple/jit.pla +++ b/src/libsrc/apple/jit.pla @@ -1266,6 +1266,7 @@ def compiler(defptr)#0 if not A_IS_TOSL ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL + A_IS_TOSL = TOSL_CLEAN fin ^codeptr = $8D; codeptr++ // STA abs *codeptr = *(bytecode+i); codeptr = codeptr + 2 @@ -1275,7 +1276,6 @@ def compiler(defptr)#0 *codeptr = *(bytecode+i)+1; codeptr = codeptr + 2 ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = $00; codeptr++ // $00 - A_IS_TOSL = TOSL_CLEAN i++ break // LNOT,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 80 82 84 86 88 8A 8C 8E diff --git a/src/toolsrc/codegen.pla b/src/toolsrc/codegen.pla index adceeea..c06d89f 100644 --- a/src/toolsrc/codegen.pla +++ b/src/toolsrc/codegen.pla @@ -435,6 +435,9 @@ def idmatch(nameptr, len, idptr, idcnt) //for i = 1 to len // if nameptr->[i - 1] <> idptr->idname.[i]; break; fin //next + puts(@idptr->idname);putln + puti(i); putln + puti(len); putln if i > len; return idptr; fin fin idptr = idptr + idptr->idname + t_id From efd1ff58e3d72d544c2b36eb06f6f1187d8dcd5d Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Fri, 23 Mar 2018 17:13:42 -0700 Subject: [PATCH 089/147] Fix ISLE --- src/libsrc/apple/jit.pla | 6 +++--- src/toolsrc/codegen.pla | 3 --- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/libsrc/apple/jit.pla b/src/libsrc/apple/jit.pla index 034aaee..951b492 100644 --- a/src/libsrc/apple/jit.pla +++ b/src/libsrc/apple/jit.pla @@ -710,9 +710,9 @@ def compiler(defptr)#0 break is $4A //puts("ISLE") - if A_IS_TOSL & TOSL_DIRTY - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + if not A_IS_TOSL + ^codeptr = $B5; codeptr++ // LDA zp,X + ^codeptr = $D0+VX; codeptr++ // ESTKL fin ^codeptr = $D5; codeptr++ // CMP zp,X ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 diff --git a/src/toolsrc/codegen.pla b/src/toolsrc/codegen.pla index c06d89f..adceeea 100644 --- a/src/toolsrc/codegen.pla +++ b/src/toolsrc/codegen.pla @@ -435,9 +435,6 @@ def idmatch(nameptr, len, idptr, idcnt) //for i = 1 to len // if nameptr->[i - 1] <> idptr->idname.[i]; break; fin //next - puts(@idptr->idname);putln - puti(i); putln - puti(len); putln if i > len; return idptr; fin fin idptr = idptr + idptr->idname + t_id From 27a2d8d0b7eead036761aa6ee17bba9331f9e0c4 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Sat, 24 Mar 2018 10:02:14 -0700 Subject: [PATCH 090/147] Start more efficient coding for writing native code to buffer --- src/libsrc/apple/jit.pla | 302 +++++++++++++++++++++--------------- src/vmsrc/apple/plvmjit02.s | 23 ++- 2 files changed, 185 insertions(+), 140 deletions(-) diff --git a/src/libsrc/apple/jit.pla b/src/libsrc/apple/jit.pla index 951b492..a110bbc 100644 --- a/src/libsrc/apple/jit.pla +++ b/src/libsrc/apple/jit.pla @@ -198,37 +198,48 @@ def compiler(defptr)#0 // // Call into VM // - ^codeptr = $20; codeptr++ // JSR INTERP - *codeptr = $3D0; codeptr = codeptr + 2 - ^codeptr = $58; codeptr++ // ENTER CODE - ^codeptr = ^(bytecode+1); codeptr++ // ENTER FRAME SIZE - ^codeptr = ^(bytecode+2); codeptr++ // ENTER ARG COUNT - ^codeptr = $C0; codeptr++ // NATV CODE + 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 // // First optimization is to keep zero in Y register at all times // - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = $00; codeptr++ // $00 + *codeptr = $00A0; codeptr = codeptr + 2 // LDY #$00 while isule(codeptr, codemax) //putc('$'); puth(codeptr); //putc(':') //putc('['); puti(i); //puts("] ") opcode = ^(bytecode+i) if opcode & 1 // - // Optimization fence + // Optimization fence. Sync A and X registers // if A_IS_TOSL & TOSL_DIRTY - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D095+(VX<<8) // STA ESTKL,X + codeptr = codeptr + 2 A_IS_TOSL = FALSE fin codeptr, VX = resolveX(codeptr, VX) opcode = opcode & $FE fin // - // Update bytecode->native code address translation + // 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] // @@ -241,46 +252,57 @@ def compiler(defptr)#0 dest = case + *jitcodeptr until not case fin + // + // Update address translate buffer with bytecode->native address + // addrxlate=>[i] = codeptr - if opcode < $20 - // CN,CN,CN,CN,CN,CN,CN,CN ; 00 02 04 06 08 0A 0C 0E - // CN,CN,CN,CN,CN,CN,CN,CN ; 10 12 14 16 18 1A 1C 1E + // + // Compile this bad boy... + // + if opcode < $20 // CONSTANT NYBBLE + // CN,CN,CN,CN,CN,CN,CN,CN ; 00 02 04 06 08 0A 0C 0E + // CN,CN,CN,CN,CN,CN,CN,CN ; 10 12 14 16 18 1A 1C 1E //puts("CN $"); putb(^(bytecode+i)/2) if A_IS_TOSL & TOSL_DIRTY - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D095+(VX<<8) // STA ESTKL,X + codeptr = codeptr + 2 fin - VX-- //^codeptr = $CA; codeptr++ // DEX + VX-- // DEX if ^(bytecode+i) == 0 - ^codeptr = $98; codeptr++ // TYA -> LDA #$00 + ^codeptr = $98; codeptr++ // TYA -> LDA #$00 else - ^codeptr = $A9; codeptr++ // LDA #imm - ^codeptr = ^(bytecode+i)/2; codeptr++ + *codeptr = $A9+(^(bytecode+i)/2<<8) // LDA #(CN/2) + //^codeptr = $A9; codeptr++ // LDA #imm + //^codeptr = $CN/2; codeptr++ // CN/2 + codeptr = codeptr + 2 fin - ^codeptr = $94; codeptr++ // STY zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $C094+(VX<<8) // STY ESTKH,X + //^codeptr = $94; codeptr++ // STY zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr = codeptr + 2 A_IS_TOSL = TOSL_DIRTY else when opcode - // MINUS1,BREQ,BRNE,LA,LLA,CB,CW,CS ; 20 22 24 26 28 2A 2C 2E - is $20 + // MINUS1,BREQ,BRNE,LA,LLA,CB,CW,CS ; 20 22 24 26 28 2A 2C 2E + is $20 // MINUS ONE //puts("MINUS_ONE") if A_IS_TOSL & TOSL_DIRTY - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D095+(VX<<8) // STA ESTKL,X + codeptr = codeptr + 2 fin - VX-- //^codeptr = $CA; codeptr++ // DEX - ^codeptr = $A9; codeptr++ // LDA #imm - ^codeptr = $FF; codeptr++ // $FF - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH + VX-- // DEX + codeptr=>0 = $FFA9 // LDA #$FF + //^codeptr = $A9; codeptr++ // LDA #imm + //^codeptr = $FF; codeptr++ // $FF + codeptr=>2 = $C095+(VX<<8) // STA ESTKH,X + codeptr = codeptr + 4 + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL A_IS_TOSL = TOSL_DIRTY break - is $22 + is $22 // BREQ i++ dest = i + *(bytecode+i) i++ @@ -289,28 +311,40 @@ def compiler(defptr)#0 //^codeptr = $E8; codeptr++ // INX codeptr, VX = resolveX(codeptr, VX + 2) if not A_IS_TOSL - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0-2+VX; codeptr++ // ESTKL-2 + *codeptr = ($D0B5-$0200)+(VX<<8) // LDA ESTKL-2,X + codeptr = codeptr + 2 + //^codeptr = $B5; codeptr++ // LDA zp,X + //^codeptr = $D0-2+VX; codeptr++ // ESTKL-2 fin - ^codeptr = $D5; codeptr++ // CMP zp,X - ^codeptr = $D0-1+VX; codeptr++ // ESTKL-1 - ^codeptr = $D0; codeptr++ // BNE rel - ^codeptr = $09; codeptr++ // +9 - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $C0-2+VX; codeptr++ // ESTKH-2 - ^codeptr = $D5; codeptr++ // CMP zp,X - ^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 - ^codeptr = $D0; codeptr++ // BNE rel - ^codeptr = $03; codeptr++ // +3 - ^codeptr = $4C; codeptr++ // JMP abs - *codeptr = addrxlate=>[dest] - if not (*codeptr & $8000) // Unresolved address list - addrxlate=>[dest] = codeptr - *jitcodeptr + codeptr=>0 = ($D0D5-$0100)+(VX<<8) // CMP ESTKL-1,X + //^codeptr = $D5; codeptr++ // CMP zp,X + //^codeptr = $D0-1+VX; codeptr++ // ESTKL-1 + codeptr=>2 = $09D0 // BNE +9 + //^codeptr = $D0; codeptr++ // BNE rel + //^codeptr = $09; codeptr++ // +9 + codeptr=>4 = ($C0B5-$0200)+(VX<<8) // LDA ESTKH-2,X + //^codeptr = $B5; codeptr++ // LDA zp,X + //^codeptr = $C0-2+VX; codeptr++ // ESTKH-2 + codeptr=>6 = ($C0D5-$0100)+(VX<<8) // CMP ESTKH-1,X + //^codeptr = $D5; codeptr++ // CMP zp,X + //^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 + codeptr=>8 = $03D0 // BNE +3 + //^codeptr = $D0; codeptr++ // BNE rel + //^codeptr = $03; codeptr++ // +3 + codeptr->10 = $4C // JMP abs + //^codeptr = $4C; codeptr++ // JMP abs + codeptr=>11 = addrxlate=>[dest] + //*codeptr = addrxlate=>[dest] + if not (codeptr->12 & $80) // Unresolved address list + //if not (*codeptr & $8000) // Unresolved address list + addrxlate=>[dest] = codeptr + 11 - *jitcodeptr + //addrxlate=>[dest] = codeptr - *jitcodeptr fin - codeptr = codeptr + 2 + codeptr = codeptr + 13 + //codeptr = codeptr + 2 A_IS_TOSL = FALSE break - is $24 + is $24 // BRNE i++ dest = i + *(bytecode+i) i++ @@ -319,33 +353,45 @@ def compiler(defptr)#0 //^codeptr = $E8; codeptr++ // INX codeptr, VX = resolveX(codeptr, VX + 2) if not A_IS_TOSL - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0-2+VX; codeptr++ // ESTKL-2 + *codeptr = ($D0B5-$0200)+(VX<<8) // LDA ESTKL-2,X + codeptr = codeptr + 2 + //^codeptr = $B5; codeptr++ // LDA zp,X + //^codeptr = $D0-2+VX; codeptr++ // ESTKL-2 fin - ^codeptr = $D5; codeptr++ // CMP zp,X - ^codeptr = $D0-1+VX; codeptr++ // ESTKL-1 - ^codeptr = $D0; codeptr++ // BNE rel - ^codeptr = $06; codeptr++ // +6 - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $C0-2+VX; codeptr++ // ESTKH-2 - ^codeptr = $D5; codeptr++ // CMP zp,X - ^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 - ^codeptr = $F0; codeptr++ // BEQ rel - ^codeptr = $03; codeptr++ // +3 - ^codeptr = $4C; codeptr++ // JMP abs - *codeptr = addrxlate=>[dest] - if not (*codeptr & $8000) // Unresolved address list - addrxlate=>[dest] = codeptr - *jitcodeptr + codeptr=>0 = ($D0D5-$0100)+(VX<<8) // CMP ESTKL-1,X + //^codeptr = $D5; codeptr++ // CMP zp,X + //^codeptr = $D0-1+VX; codeptr++ // ESTKL-1 + codeptr=>2 = $06D0 // BNE +6 + //^codeptr = $D0; codeptr++ // BNE rel + //^codeptr = $06; codeptr++ // +6 + codeptr=>4 = ($C0B5-$0200)+(VX<<8) // LDA ESTKH-2,X + //^codeptr = $B5; codeptr++ // LDA zp,X + //^codeptr = $C0-2+VX; codeptr++ // ESTKH-2 + codeptr=>6 = ($C0D5-$0100)+(VX<<8) // CMP ESTKH-1,X + //^codeptr = $D5; codeptr++ // CMP zp,X + //^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 + codeptr=>8 = $03F0 // BEQ +3 + //^codeptr = $F0; codeptr++ // BEQ rel + //^codeptr = $03; codeptr++ // +3 + codeptr->10 = $4C // JMP abs + //^codeptr = $4C; codeptr++ // JMP abs + codeptr=>11 = addrxlate=>[dest] + //*codeptr = addrxlate=>[dest] + if not (codeptr->12 & $80) // Unresolved address list + //if not (*codeptr & $8000) // Unresolved address list + addrxlate=>[dest] = codeptr + 11 - *jitcodeptr + //addrxlate=>[dest] = codeptr - *jitcodeptr fin - codeptr = codeptr + 2 + codeptr = codeptr + 13 + //codeptr = codeptr + 2 A_IS_TOSL = FALSE break is $26 i++ //puts("LA $"); puth(*(bytecode+i)) if A_IS_TOSL & TOSL_DIRTY - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D095+(VX<<8) // STA ESTKL,X + codeptr = codeptr + 2 fin VX-- //^codeptr = $CA; codeptr++ // DEX ^codeptr = $A9; codeptr++ // LDA #imm @@ -363,8 +409,8 @@ def compiler(defptr)#0 i++ //puts("LLA "); puti(^(bytecode+i)) if A_IS_TOSL & TOSL_DIRTY - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D095+(VX<<8) // STA ESTKL,X + codeptr = codeptr + 2 fin VX-- //^codeptr = $CA; codeptr++ // DEX if ^(bytecode+i) == 0 @@ -389,8 +435,8 @@ def compiler(defptr)#0 i++ //puts("CB $"); putb(^(bytecode+i)) if A_IS_TOSL & TOSL_DIRTY - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D095+(VX<<8) // STA ESTKL,X + codeptr = codeptr + 2 fin VX-- //^codeptr = $CA; codeptr++ // DEX ^codeptr = $A9; codeptr++ // LDA #imm @@ -405,8 +451,8 @@ def compiler(defptr)#0 i++ //puts("CW $"); puth(*(bytecode+i)) if A_IS_TOSL & TOSL_DIRTY - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D095+(VX<<8) // STA ESTKL,X + codeptr = codeptr + 2 fin VX-- //^codeptr = $CA; codeptr++ // DEX ^codeptr = $A9; codeptr++ // LDA #imm @@ -431,8 +477,8 @@ def compiler(defptr)#0 //puts("CS "); //puts(bytecode+i); //puts("-->"); puti(dest) if isule(codeptr + 12 + j, codemax) if A_IS_TOSL & TOSL_DIRTY - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D095+(VX<<8) // STA ESTKL,X + codeptr = codeptr + 2 fin VX-- //^codeptr = $CA; codeptr++ // DEX ^codeptr = $A9; codeptr++ // LDA #imm @@ -473,8 +519,8 @@ def compiler(defptr)#0 is $34 //puts("DUP") if A_IS_TOSL & TOSL_DIRTY - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D095+(VX<<8) // STA ESTKL,X + codeptr = codeptr + 2 else ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL @@ -649,8 +695,8 @@ def compiler(defptr)#0 is $46 //puts("ISLT") if A_IS_TOSL & TOSL_DIRTY - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D095+(VX<<8) // STA ESTKL,X + codeptr = codeptr + 2 fin ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 @@ -680,8 +726,8 @@ def compiler(defptr)#0 is $48 //puts("ISGE") if A_IS_TOSL & TOSL_DIRTY - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D095+(VX<<8) // STA ESTKL,X + codeptr = codeptr + 2 fin ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 @@ -791,8 +837,8 @@ def compiler(defptr)#0 //puts("BRNCH "); puti(dest) codeptr, VX = resolveX(codeptr, VX) if A_IS_TOSL & TOSL_DIRTY - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D095+(VX<<8) // STA ESTKL,X + codeptr = codeptr + 2 fin ^codeptr = $4C; codeptr++ // JMP abs *codeptr = addrxlate=>[dest] @@ -866,8 +912,8 @@ def compiler(defptr)#0 // Call address // if A_IS_TOSL & TOSL_DIRTY - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D095+(VX<<8) // STA ESTKL,X + codeptr = codeptr + 2 fin codeptr, VX = resolveX(codeptr, VX) ^codeptr = $20; codeptr++ // JSR abs @@ -911,8 +957,8 @@ def compiler(defptr)#0 // Call into VM // if A_IS_TOSL & TOSL_DIRTY - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D095+(VX<<8) // STA ESTKL,X + codeptr = codeptr + 2 fin codeptr, VX = resolveX(codeptr, VX) ^codeptr = $20; codeptr++ // JSR INTERP @@ -924,8 +970,8 @@ def compiler(defptr)#0 is $5C //puts("RET") if A_IS_TOSL & TOSL_DIRTY - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D095+(VX<<8) // STA ESTKL,X + codeptr = codeptr + 2 fin codeptr, VX = resolveX(codeptr, VX) ^codeptr = $60; codeptr++ // RTS @@ -935,8 +981,8 @@ def compiler(defptr)#0 i++ //puts("CFFB $FF"); putb(^(bytecode+i)) if A_IS_TOSL & TOSL_DIRTY - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D095+(VX<<8) // STA ESTKL,X + codeptr = codeptr + 2 fin VX-- //^codeptr = $CA; codeptr++ // DEX ^codeptr = $A9; codeptr++ // LDA #imm @@ -994,8 +1040,8 @@ def compiler(defptr)#0 i++ //puts("LLB "); puti(^(bytecode+i)) if A_IS_TOSL & TOSL_DIRTY - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D095+(VX<<8) // STA ESTKL,X + codeptr = codeptr + 2 fin VX-- //^codeptr = $CA; codeptr++ // DEX if ^(bytecode+i) <> 0 @@ -1018,8 +1064,8 @@ def compiler(defptr)#0 i++ //puts("LLW "); puti(^(bytecode+i)) if A_IS_TOSL & TOSL_DIRTY - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D095+(VX<<8) // STA ESTKL,X + codeptr = codeptr + 2 fin VX-- //^codeptr = $CA; codeptr++ // DEX if ^(bytecode+i) <> 0 @@ -1047,8 +1093,8 @@ def compiler(defptr)#0 i++ //puts("LAB $"); puth(*(bytecode+i)) if A_IS_TOSL & TOSL_DIRTY - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D095+(VX<<8) // STA ESTKL,X + codeptr = codeptr + 2 fin VX-- //^codeptr = $CA; codeptr++ // DEX ^codeptr = $AD; codeptr++ // LDA abs @@ -1064,8 +1110,8 @@ def compiler(defptr)#0 i++ //puts("LAW $"); puth(*(bytecode+i)) if A_IS_TOSL & TOSL_DIRTY - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D095+(VX<<8) // STA ESTKL,X + codeptr = codeptr + 2 fin VX-- //^codeptr = $CA; codeptr++ // DEX ^codeptr = $AD; codeptr++ // LDA abs @@ -1102,8 +1148,8 @@ def compiler(defptr)#0 i++ //puts("DLW "); puti(^(bytecode+i)) if A_IS_TOSL & TOSL_DIRTY - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D095+(VX<<8) // STA ESTKL,X + codeptr = codeptr + 2 fin if ^(bytecode+i) <> 0 ^codeptr = $A0; codeptr++ // LDY #imm @@ -1322,8 +1368,8 @@ def compiler(defptr)#0 is $84 //puts("SUB") if A_IS_TOSL & TOSL_DIRTY - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D095+(VX<<8) // STA ESTKL,X + codeptr = codeptr + 2 fin ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 @@ -1363,8 +1409,8 @@ def compiler(defptr)#0 // Call into VM // if A_IS_TOSL & TOSL_DIRTY - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D095+(VX<<8) // STA ESTKL,X + codeptr = codeptr + 2 fin codeptr, VX = resolveX(codeptr, VX) ^codeptr = $20; codeptr++ // JSR INTERP @@ -1413,8 +1459,8 @@ def compiler(defptr)#0 is $90 //puts("NEG") if A_IS_TOSL & TOSL_DIRTY - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D095+(VX<<8) // STA ESTKL,X + codeptr = codeptr + 2 fin ^codeptr = $98; codeptr++ // TYA -> LDA #$00 ^codeptr = $38; codeptr++ // SEC @@ -1535,8 +1581,8 @@ def compiler(defptr)#0 i++ codeptr, VX = resolveX(codeptr, VX) if A_IS_TOSL & TOSL_DIRTY - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D095+(VX<<8) // STA ESTKL,X + codeptr = codeptr + 2 fin ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 @@ -1756,8 +1802,8 @@ def compiler(defptr)#0 // SUB // if A_IS_TOSL & TOSL_DIRTY - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D095+(VX<<8) // STA ESTKL,X + codeptr = codeptr + 2 fin ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 @@ -1808,8 +1854,8 @@ def compiler(defptr)#0 //puts("BRAND "); puti(dest) codeptr, VX = resolveX(codeptr, VX) if A_IS_TOSL & TOSL_DIRTY - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D095+(VX<<8) // STA ESTKL,X + codeptr = codeptr + 2 else ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL @@ -1834,8 +1880,8 @@ def compiler(defptr)#0 //puts("BROR "); puti(dest) codeptr, VX = resolveX(codeptr, VX) if A_IS_TOSL & TOSL_DIRTY - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D095+(VX<<8) // STA ESTKL,X + codeptr = codeptr + 2 else ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL @@ -1955,8 +2001,8 @@ def compiler(defptr)#0 i++ //puts("IDXLB "); puti(^(bytecode+i)) if A_IS_TOSL & TOSL_DIRTY - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D095+(VX<<8) // STA ESTKL,X + codeptr = codeptr + 2 fin if ^(bytecode+i) <> 0 ^codeptr = $A0; codeptr++ // LDY #imm @@ -1990,8 +2036,8 @@ def compiler(defptr)#0 i++ //puts("IDXLW "); puti(^(bytecode+i)) if A_IS_TOSL & TOSL_DIRTY - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D095+(VX<<8) // STA ESTKL,X + codeptr = codeptr + 2 fin if ^(bytecode+i) <> 0 ^codeptr = $A0; codeptr++ // LDY #imm @@ -2027,8 +2073,8 @@ def compiler(defptr)#0 i++ //puts("IDXAB $"); puth(*(bytecode+i)) if A_IS_TOSL & TOSL_DIRTY - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D095+(VX<<8) // STA ESTKL,X + codeptr = codeptr + 2 fin ^codeptr = $AD; codeptr++ // LDA abs *codeptr = *(bytecode+i); codeptr = codeptr + 2 @@ -2055,8 +2101,8 @@ def compiler(defptr)#0 i++ //puts("IDXAW $"); puth(*(bytecode+i)) if A_IS_TOSL & TOSL_DIRTY - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D095+(VX<<8) // STA ESTKL,X + codeptr = codeptr + 2 fin ^codeptr = $AD; codeptr++ // LDA abs *codeptr = *(bytecode+i); codeptr = codeptr + 2 diff --git a/src/vmsrc/apple/plvmjit02.s b/src/vmsrc/apple/plvmjit02.s index b4589fd..d7dc43e 100755 --- a/src/vmsrc/apple/plvmjit02.s +++ b/src/vmsrc/apple/plvmjit02.s @@ -444,19 +444,13 @@ JITINTRPX PHP LDY #$05 LDA JITWARM+1 ; CHECK WARMING ORA JITWARM - BEQ ++ - LDA JITWARM + BEQ DECCALL +DECWARM LDA JITWARM ; DEC WARMING COUNT BNE + DEC JITWARM+1 + DEC JITWARM - JMP +++ -++ LDA (TMP),Y ; DEC JIT COUNT - SEC - SBC #$01 - STA (TMP),Y - BEQ RUNJIT -+++ DEY -- LDA (TMP),Y +NOJIT DEY ; INTERP BYTECODE AS USUAL + LDA (TMP),Y STA IPH DEY LDA (TMP),Y @@ -466,6 +460,11 @@ JITINTRPX PHP STA OPPAGE STA ALTRDON JMP FETCHOP +DECCALL LDA (TMP),Y ; DEC JIT COUNT + SEC + SBC #$01 + STA (TMP),Y + BNE NOJIT RUNJIT LDA JITCOMP STA SRCL LDA JITCOMP+1 @@ -478,7 +477,7 @@ RUNJIT LDA JITCOMP STA IPL DEX ; ADD PARAMETER TO DEF ENTRY LDA TMPL - PHA + PHA ; AND SAVE IT FOR LATER STA ESTKL,X LDA TMPH PHA @@ -492,7 +491,7 @@ RUNJIT LDA JITCOMP STA TMPH PLA STA TMPL - JMP JMPTMP ; RE-CALL ORIGINAL ROUTINE + JMP JMPTMP ; RE-CALL ORIGINAL DEF ENTRY ;* ;* ADD TOS TO TOS-1 ;* From 8adc03d640bec39de39a5d0b7e607b3e001074af Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Sat, 24 Mar 2018 15:47:05 -0700 Subject: [PATCH 091/147] Rework ops $20-$2E --- src/libsrc/apple/jit.pla | 162 ++++++++++++++++++++------------------- 1 file changed, 85 insertions(+), 77 deletions(-) diff --git a/src/libsrc/apple/jit.pla b/src/libsrc/apple/jit.pla index a110bbc..8657c13 100644 --- a/src/libsrc/apple/jit.pla +++ b/src/libsrc/apple/jit.pla @@ -295,7 +295,7 @@ def compiler(defptr)#0 //^codeptr = $A9; codeptr++ // LDA #imm //^codeptr = $FF; codeptr++ // $FF codeptr=>2 = $C095+(VX<<8) // STA ESTKH,X - codeptr = codeptr + 4 + codeptr = codeptr + 4 //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $C0+VX; codeptr++ // ESTKH //^codeptr = $95; codeptr++ // STA zp,X @@ -307,9 +307,9 @@ def compiler(defptr)#0 dest = i + *(bytecode+i) i++ //puts("BREQ "); puti(dest) - //^codeptr = $E8; codeptr++ // INX - //^codeptr = $E8; codeptr++ // INX 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 @@ -349,9 +349,9 @@ def compiler(defptr)#0 dest = i + *(bytecode+i) i++ //puts("BRNE "); puti(dest) - //^codeptr = $E8; codeptr++ // INX - //^codeptr = $E8; codeptr++ // INX 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 @@ -386,52 +386,72 @@ def compiler(defptr)#0 //codeptr = codeptr + 2 A_IS_TOSL = FALSE break - is $26 + is $26 // LA + is $2C // CW i++ - //puts("LA $"); puth(*(bytecode+i)) + //puts("LA/CW $"); puth(*(bytecode+i)) if A_IS_TOSL & TOSL_DIRTY *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin - VX-- //^codeptr = $CA; codeptr++ // DEX - ^codeptr = $A9; codeptr++ // LDA #imm - ^codeptr = ^(bytecode+i+1); codeptr++ - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH - ^codeptr = $A9; codeptr++ // LDA #imm - ^codeptr = ^(bytecode+i); codeptr++ + VX-- // DEX + codeptr=>0 = $A9+(^(bytecode+i+1)<<8) // LDA #2 = $C095+(VX<<8) // STA ESTKH,X + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH + if ^(bytecode+i) == 0 + codeptr->4 = $98 // TYA -> LDA #$00 + codeptr = codeptr + 5 + //^codeptr = $98; codeptr++ // TYA -> LDA #$00 + else + codeptr=>4 = $A9+(^(bytecode+i)<<8) // LDA #>VAL + codeptr = codeptr + 6 + //^codeptr = $A9; codeptr++ // LDA #imm + //^codeptr = ^(bytecode+i); codeptr++ + fin //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL A_IS_TOSL = TOSL_DIRTY i++ break - is $28 + is $28 // LLA i++ //puts("LLA "); puti(^(bytecode+i)) if A_IS_TOSL & TOSL_DIRTY *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin - VX-- //^codeptr = $CA; codeptr++ // DEX + VX-- // DEX if ^(bytecode+i) == 0 - ^codeptr = $98; codeptr++ // TYA -> LDA #$00 + ^codeptr = $98; codeptr++ // TYA -> LDA #$00 else - ^codeptr = $A9; codeptr++ // LDA #imm - ^codeptr = ^(bytecode+i); codeptr++ + codeptr=>4 = $A9+(^(bytecode+i)<<8) // LDA #imm + codeptr = codeptr + 2 + //^codeptr = $A9; codeptr++ // LDA #imm + //^codeptr = ^(bytecode+i); codeptr++ fin - ^codeptr = $18; codeptr++ // CLC - ^codeptr = $65; codeptr++ // ADC zp - ^codeptr = $E0; codeptr++ // IFPL - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL - ^codeptr = $98; codeptr++ // TYA -> LDA #$00 - ^codeptr = $65; codeptr++ // ADC zp - ^codeptr = $E1; codeptr++ // IFPH - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH - A_IS_TOSL = FALSE + codeptr->0 = $18 // CLC + //^codeptr = $18; codeptr++ // CLC + codeptr=>1 = $E065 // ADC IFPL + //^codeptr = $65; codeptr++ // ADC zp + //^codeptr = $E0; codeptr++ // IFPL + codeptr=>3 = $D095+(VX<<8) // STA ESTKL,X + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $D0+VX; codeptr++ // ESTKL + codeptr->5 = $98 // TYA -> LDA #$00 + //^codeptr = $98; codeptr++ // TYA -> LDA #$00 + codeptr=>6 = $E165 // ADC IFPH + //^codeptr = $65; codeptr++ // ADC zp + //^codeptr = $E1; codeptr++ // IFPH + codeptr=>8 = $C095+(VX<<8) // STA ESTKH,X + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr = codeptr + 10 + A_IS_TOSL = FALSE break - is $2A + is $2A // CB i++ //puts("CB $"); putb(^(bytecode+i)) if A_IS_TOSL & TOSL_DIRTY @@ -439,38 +459,18 @@ def compiler(defptr)#0 codeptr = codeptr + 2 fin VX-- //^codeptr = $CA; codeptr++ // DEX - ^codeptr = $A9; codeptr++ // LDA #imm - ^codeptr = ^(bytecode+i); codeptr++ - ^codeptr = $94; codeptr++ // STY zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr=>0 = $A9+(^(bytecode+i)<<8) // LDA #imm + //^codeptr = $A9; codeptr++ // LDA #imm + //^codeptr = ^(bytecode+i); codeptr++ + codeptr=>2 = $C094+(VX<<8) // STY ESTKH,X + //^codeptr = $94; codeptr++ // STY zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL + codeptr = codeptr + 4 A_IS_TOSL = TOSL_DIRTY break - is $2C - i++ - //puts("CW $"); puth(*(bytecode+i)) - if A_IS_TOSL & TOSL_DIRTY - *codeptr = $D095+(VX<<8) // STA ESTKL,X - codeptr = codeptr + 2 - fin - VX-- //^codeptr = $CA; codeptr++ // DEX - ^codeptr = $A9; codeptr++ // LDA #imm - ^codeptr = ^(bytecode+i+1); codeptr++ - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH - if ^(bytecode+i) == 0 - ^codeptr = $98; codeptr++ // TYA -> LDA #$00 - else - ^codeptr = $A9; codeptr++ // LDA #imm - ^codeptr = ^(bytecode+i); codeptr++ - fin - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $D0+VX; codeptr++ // ESTKL - A_IS_TOSL = TOSL_DIRTY - i++ - break - is $2E + is $2E // CS i++ j = ^(bytecode+i) dest = i + j + 1 @@ -481,26 +481,34 @@ def compiler(defptr)#0 codeptr = codeptr + 2 fin VX-- //^codeptr = $CA; codeptr++ // DEX - ^codeptr = $A9; codeptr++ // LDA #imm - ^codeptr = codeptr+10; codeptr++ - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL - ^codeptr = $A9; codeptr++ // LDA #imm - ^codeptr = (codeptr+6)>>8; codeptr++ - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH - ^codeptr = $4C; codeptr++ // JMP abs - *codeptr = addrxlate=>[dest] - if not (*codeptr & $8000) // Unresolved address list - addrxlate=>[dest] = codeptr - *jitcodeptr + codeptr=>0 = $A9+((codeptr+11)<<8) // LDA #imm + //^codeptr = $A9; codeptr++ // LDA #imm + //^codeptr = codeptr+10; codeptr++ + codeptr=>2 = $D095+(VX<<8) // STA ESTKL,X + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $D0+VX; codeptr++ // ESTKL + codeptr=>4 = $A9+((codeptr+11)&$FF00) // LDA #imm + //^codeptr = $A9; codeptr++ // LDA #imm + //^codeptr = (codeptr+6)>>8; codeptr++ + codeptr=>6 = $C095+(VX<<8) // STA ESTKH,X + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr->8 = $4C // JMP abs + //^codeptr = $4C; codeptr++ // JMP abs + codeptr=>9 = addrxlate=>[dest] + //*codeptr = addrxlate=>[dest] + if not (codeptr->10 & $80) // Unresolved address list + //if not (*codeptr & $8000) // Unresolved address list + addrxlate=>[dest] = codeptr + 9 - *jitcodeptr + //addrxlate=>[dest] = codeptr - *jitcodeptr fin - codeptr = codeptr + 2 - strcpy(codeptr, bytecode+i) - codeptr = codeptr + j + 1 - i = i + j - else - codeptr = codeptr + 12 + j // Flag buffer overflow + //codeptr = codeptr + 2 + strcpy(codeptr + 11, bytecode + i) + //strcpy(codeptr + 2, bytecode+i) + //codeptr = codeptr + j + 1 + i = i + j fin + codeptr = codeptr + 12 + j A_IS_TOSL = FALSE break // DROP,DROP2,DUP,DIVMOD,ADDI,SUBI,ANDI,ORI ; 30 32 34 36 38 3A 3C 3E From 1bf3c7043fcf0276f76b2190eeb3b02ce528828d Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Sat, 24 Mar 2018 16:37:47 -0700 Subject: [PATCH 092/147] Fix LLA --- src/libsrc/apple/jit.pla | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libsrc/apple/jit.pla b/src/libsrc/apple/jit.pla index 8657c13..8e17312 100644 --- a/src/libsrc/apple/jit.pla +++ b/src/libsrc/apple/jit.pla @@ -427,8 +427,8 @@ def compiler(defptr)#0 if ^(bytecode+i) == 0 ^codeptr = $98; codeptr++ // TYA -> LDA #$00 else - codeptr=>4 = $A9+(^(bytecode+i)<<8) // LDA #imm - codeptr = codeptr + 2 + *codeptr = $A9+(^(bytecode+i)<<8) // LDA #imm + codeptr = codeptr + 2 //^codeptr = $A9; codeptr++ // LDA #imm //^codeptr = ^(bytecode+i); codeptr++ fin @@ -449,7 +449,7 @@ def compiler(defptr)#0 //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $C0+VX; codeptr++ // ESTKH codeptr = codeptr + 10 - A_IS_TOSL = FALSE + A_IS_TOSL = FALSE break is $2A // CB i++ @@ -468,7 +468,7 @@ def compiler(defptr)#0 //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL codeptr = codeptr + 4 - A_IS_TOSL = TOSL_DIRTY + A_IS_TOSL = TOSL_DIRTY break is $2E // CS i++ From 6cfb957df4b2ccfd52ffa79c9db9e064a1be247b Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Sat, 24 Mar 2018 17:04:21 -0700 Subject: [PATCH 093/147] Rework ops $30-$3E --- src/libsrc/apple/jit.pla | 117 ++++++++++++++++++++++----------------- 1 file changed, 67 insertions(+), 50 deletions(-) diff --git a/src/libsrc/apple/jit.pla b/src/libsrc/apple/jit.pla index 8e17312..d02f4bb 100644 --- a/src/libsrc/apple/jit.pla +++ b/src/libsrc/apple/jit.pla @@ -512,16 +512,12 @@ def compiler(defptr)#0 A_IS_TOSL = FALSE break // DROP,DROP2,DUP,DIVMOD,ADDI,SUBI,ANDI,ORI ; 30 32 34 36 38 3A 3C 3E - is $30 - //puts("DROP") - VX++ //^codeptr = $E8; codeptr++ // INX - A_IS_TOSL = FALSE - break - is $32 + is $32 // DROP2 //puts("DROP2") - //^codeptr = $E8; codeptr++ // INX - //^codeptr = $E8; codeptr++ // INX - VX = VX + 2 + VX++ // INX + is $30 // DROP + //puts("DROP") + VX++ // INX A_IS_TOSL = FALSE break is $34 @@ -529,91 +525,112 @@ def compiler(defptr)#0 if A_IS_TOSL & TOSL_DIRTY *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 - else - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + elsif not A_IS_TOSL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 + //^codeptr = $B5; codeptr++ // LDA zp,X + //^codeptr = $D0+VX; codeptr++ // ESTKL fin - VX-- //^codeptr = $CA; codeptr++ // DEX - ^codeptr = $B4; codeptr++ // LDY zp,X - ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - ^codeptr = $94; codeptr++ // STY zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = $00; codeptr++ // $00 + VX-- // DEX + codeptr=>0 = ($C0B4+$0100)+(VX<<8) // LDY ESTKH+1,X + //^codeptr = $B4; codeptr++ // LDY zp,X + //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + codeptr=>2 = $C094+(VX<<8) // STY ESTKH,X + //^codeptr = $94; codeptr++ // STY zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr=>4 = $00A0 // LDY #$00 + //^codeptr = $A0; codeptr++ // LDY #imm + //^codeptr = $00; codeptr++ // $00 //^codeptr = $B5; codeptr++ // LDA zp,X //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL - A_IS_TOSL = TOSL_DIRTY + codeptr = codeptr + 6 + A_IS_TOSL = TOSL_DIRTY break - is $36 + //is $36 //puts("DIVMOD") // // Should never happen // - break + //break is $38 i++ //puts("ADDI $"); putb(^(bytecode+i)) if not A_IS_TOSL - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 fin - ^codeptr = $18; codeptr++ // CLC - ^codeptr = $69; codeptr++ // ADC #imm - ^codeptr = ^(bytecode+i); codeptr++ - ^codeptr = $90; codeptr++ // BCC rel - ^codeptr = $02; codeptr++ // +2 - ^codeptr = $F6; codeptr++ // INC zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr->0 = $18 // CLC + //^codeptr = $18; codeptr++ // CLC + codeptr=>1 = $69+(^(bytecode+i)<<8) // ADC #imm + //^codeptr = $69; codeptr++ // ADC #imm + //^codeptr = ^(bytecode+i); codeptr++ + codeptr=>3 = $0290 // BCC +2 + //^codeptr = $90; codeptr++ // BCC rel + //^codeptr = $02; codeptr++ // +2 + codeptr=>5 = $C0F6+(VX<<8) // INC ESTKH,X + //^codeptr = $F6; codeptr++ // INC zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL + codeptr = codeptr + 7 A_IS_TOSL = TOSL_DIRTY break is $3A i++ //puts("SUBI $"); putb(^(bytecode+i)) if not A_IS_TOSL - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 fin - ^codeptr = $38; codeptr++ // SEC - ^codeptr = $E9; codeptr++ // SBC #imm - ^codeptr = ^(bytecode+i); codeptr++ - ^codeptr = $B0; codeptr++ // BCS rel - ^codeptr = $02; codeptr++ // +2 - ^codeptr = $D6; codeptr++ // DEC zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr->0 = $18 // CLC + //^codeptr = $38; codeptr++ // SEC + codeptr=>1 = $E9+(^(bytecode+i)<<8) // SBC #imm + //^codeptr = $E9; codeptr++ // SBC #imm + //^codeptr = ^(bytecode+i); codeptr++ + codeptr=>3 = $02B0 // BCS +2 + //^codeptr = $B0; codeptr++ // BCS rel + //^codeptr = $02; codeptr++ // +2 + codeptr=>5 = $C0D6+(VX<<8) // INC ESTKH,X + //^codeptr = $D6; codeptr++ // DEC zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL + codeptr = codeptr + 7 A_IS_TOSL = TOSL_DIRTY break is $3C i++ //puts("ANDI $"); putb(^(bytecode+i)) if not A_IS_TOSL - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 fin - ^codeptr = $29; codeptr++ // AND #imm - ^codeptr = ^(bytecode+i); codeptr++ - ^codeptr = $94; codeptr++ // STY zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr=>0 = $29+(^(bytecode+i)<<8) // AND #imm + //^codeptr = $29; codeptr++ // AND #imm + //^codeptr = ^(bytecode+i); codeptr++ + codeptr=>2 = $C094+(VX<<8) // STY ESTKH,X + //^codeptr = $94; codeptr++ // STY zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL + codeptr = codeptr + 4 A_IS_TOSL = TOSL_DIRTY break is $3E i++ //puts("ORI $"); putb(^(bytecode+i)) if not A_IS_TOSL - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 fin - ^codeptr = $09; codeptr++ // ORA #imm - ^codeptr = ^(bytecode+i); codeptr++ + codeptr=>0 = $09+(^(bytecode+i)<<8) // ORA #imm + //^codeptr = $09; codeptr++ // ORA #imm + //^codeptr = ^(bytecode+i); codeptr++ //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL + codeptr = codeptr + 2 A_IS_TOSL = TOSL_DIRTY break // ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E From 2c9373c962ad3f976604fd8ae861784bfc8b3103 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Sat, 24 Mar 2018 17:17:06 -0700 Subject: [PATCH 094/147] WIP opcodes $40-$4E --- src/libsrc/apple/jit.pla | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/libsrc/apple/jit.pla b/src/libsrc/apple/jit.pla index d02f4bb..4f5c27f 100644 --- a/src/libsrc/apple/jit.pla +++ b/src/libsrc/apple/jit.pla @@ -584,7 +584,7 @@ def compiler(defptr)#0 *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - codeptr->0 = $18 // CLC + codeptr->0 = $38 // SEC //^codeptr = $38; codeptr++ // SEC codeptr=>1 = $E9+(^(bytecode+i)<<8) // SBC #imm //^codeptr = $E9; codeptr++ // SBC #imm @@ -637,8 +637,8 @@ def compiler(defptr)#0 is $40 //puts("ISEQ") if not A_IS_TOSL - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 fin ^codeptr = $D5; codeptr++ // CMP zp,X ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 @@ -656,7 +656,7 @@ def compiler(defptr)#0 ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = $00; codeptr++ // $00 - VX++ //^codeptr = $E8; codeptr++ // INX + VX++ // INX //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL A_IS_TOSL = TOSL_DIRTY @@ -664,8 +664,8 @@ def compiler(defptr)#0 is $42 //puts("ISNE") if not A_IS_TOSL - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 fin ^codeptr = $D5; codeptr++ // CMP zp,X ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 @@ -683,7 +683,7 @@ def compiler(defptr)#0 ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = $00; codeptr++ // $00 - VX++ //^codeptr = $E8; codeptr++ // INX + VX++ // INX //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL A_IS_TOSL = TOSL_DIRTY @@ -691,8 +691,8 @@ def compiler(defptr)#0 is $44 //puts("ISGT") if not A_IS_TOSL - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 fin ^codeptr = $D5; codeptr++ // CMP zp,X ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 @@ -712,7 +712,7 @@ def compiler(defptr)#0 ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = $00; codeptr++ // $00 - VX++ //^codeptr = $E8; codeptr++ // INX + VX++ // INX //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL A_IS_TOSL = TOSL_DIRTY @@ -743,7 +743,7 @@ def compiler(defptr)#0 ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = $00; codeptr++ // $00 - VX++ //^codeptr = $E8; codeptr++ // INX + VX++ // INX //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL A_IS_TOSL = TOSL_DIRTY @@ -774,7 +774,7 @@ def compiler(defptr)#0 ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = $00; codeptr++ // $00 - VX++ //^codeptr = $E8; codeptr++ // INX + VX++ // INX //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL A_IS_TOSL = TOSL_DIRTY @@ -782,8 +782,8 @@ def compiler(defptr)#0 is $4A //puts("ISLE") if not A_IS_TOSL - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 fin ^codeptr = $D5; codeptr++ // CMP zp,X ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 @@ -803,7 +803,7 @@ def compiler(defptr)#0 ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = $00; codeptr++ // $00 - VX++ //^codeptr = $E8; codeptr++ // INX + VX++ // INX //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL A_IS_TOSL = TOSL_DIRTY @@ -816,8 +816,8 @@ def compiler(defptr)#0 //VX++ //^codeptr = $E8; codeptr++ // INX codeptr, VX = resolveX(codeptr, VX + 1) if not A_IS_TOSL - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0-1+VX; codeptr++ // ESTKL-1 + *codeptr = ($D0B5-$0100)+(VX<<8) // LDA ESTKL-1,X + codeptr = codeptr + 2 fin ^codeptr = $15; codeptr++ // ORA zp,X ^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 @@ -839,8 +839,8 @@ def compiler(defptr)#0 //VX++ //^codeptr = $E8; codeptr++ // INX codeptr, VX = resolveX(codeptr, VX + 1) if not A_IS_TOSL - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0-1+VX; codeptr++ // ESTKL-1 + *codeptr = ($D0B5-$0100)+(VX<<8) // LDA ESTKL-1,X + codeptr = codeptr + 2 fin ^codeptr = $15; codeptr++ // ORA zp,X ^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 From 23779176d281c698b6aba52aaf99225eaa102e6f Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Sat, 24 Mar 2018 21:37:52 -0700 Subject: [PATCH 095/147] Update ops $40-$4E --- src/libsrc/apple/jit.pla | 348 ++++++++++++++++++++++++--------------- 1 file changed, 211 insertions(+), 137 deletions(-) diff --git a/src/libsrc/apple/jit.pla b/src/libsrc/apple/jit.pla index 4f5c27f..129abf3 100644 --- a/src/libsrc/apple/jit.pla +++ b/src/libsrc/apple/jit.pla @@ -520,7 +520,7 @@ def compiler(defptr)#0 VX++ // INX A_IS_TOSL = FALSE break - is $34 + is $34 // DUP //puts("DUP") if A_IS_TOSL & TOSL_DIRTY *codeptr = $D095+(VX<<8) // STA ESTKL,X @@ -554,7 +554,7 @@ def compiler(defptr)#0 // Should never happen // //break - is $38 + is $38 // ADDI i++ //puts("ADDI $"); putb(^(bytecode+i)) if not A_IS_TOSL @@ -577,7 +577,7 @@ def compiler(defptr)#0 codeptr = codeptr + 7 A_IS_TOSL = TOSL_DIRTY break - is $3A + is $3A // SUBI i++ //puts("SUBI $"); putb(^(bytecode+i)) if not A_IS_TOSL @@ -600,7 +600,7 @@ def compiler(defptr)#0 codeptr = codeptr + 7 A_IS_TOSL = TOSL_DIRTY break - is $3C + is $3C // ANDI i++ //puts("ANDI $"); putb(^(bytecode+i)) if not A_IS_TOSL @@ -618,7 +618,7 @@ def compiler(defptr)#0 codeptr = codeptr + 4 A_IS_TOSL = TOSL_DIRTY break - is $3E + is $3E // ORI i++ //puts("ORI $"); putb(^(bytecode+i)) if not A_IS_TOSL @@ -634,87 +634,115 @@ def compiler(defptr)#0 A_IS_TOSL = TOSL_DIRTY break // ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E - is $40 + is $40 // ISEQ //puts("ISEQ") if not A_IS_TOSL *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - ^codeptr = $D5; codeptr++ // CMP zp,X - ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - ^codeptr = $D0; codeptr++ // BNE rel - ^codeptr = $07; codeptr++ // +7 - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH - ^codeptr = $D5; codeptr++ // CMP zp,X - ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - ^codeptr = $D0; codeptr++ // BNE rel - ^codeptr = $01; codeptr++ // +1 - ^codeptr = $88; codeptr++ // DEY - ^codeptr = $98; codeptr++ // TYA - ^codeptr = $94; codeptr++ // STY zp,X - ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = $00; codeptr++ // $00 + codeptr=>0 = ($D0D5+$0100)+(VX<<8) // CMP ESTKL+1,X + //^codeptr = $D5; codeptr++ // CMP zp,X + //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + codeptr=>2 = $07D0 // BNE +7 + //^codeptr = $D0; codeptr++ // BNE rel + //^codeptr = $07; codeptr++ // +7 + codeptr=>4 = $C0B5+(VX<<8) // LDA ESTKH,X + //^codeptr = $B5; codeptr++ // LDA zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr=>6 = ($C0D5+$0100)+(VX<<8) // CMP ESTKH+1 + //^codeptr = $D5; codeptr++ // CMP zp,X + //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + codeptr=>8 = $01D0 // BNE +1 + //^codeptr = $D0; codeptr++ // BNE rel + //^codeptr = $01; codeptr++ // +1 + codeptr=>10 = $9888 // DEY TYA + //^codeptr = $88; codeptr++ // DEY + //^codeptr = $98; codeptr++ // TYA + codeptr=>12 = ($C094+$0100)+(VX<<8) // STY ESTKH+1,X + //^codeptr = $94; codeptr++ // STY zp,X + //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + codeptr=>14 = $00A0 // LDY #$00 + //^codeptr = $A0; codeptr++ // LDY #imm + //^codeptr = $00; codeptr++ // $00 VX++ // INX //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL + codeptr = codeptr + 16 A_IS_TOSL = TOSL_DIRTY break - is $42 + is $42 // ISNE //puts("ISNE") if not A_IS_TOSL *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - ^codeptr = $D5; codeptr++ // CMP zp,X - ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - ^codeptr = $D0; codeptr++ // BNE rel - ^codeptr = $06; codeptr++ // +6 - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH - ^codeptr = $D5; codeptr++ // CMP zp,X - ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - ^codeptr = $F0; codeptr++ // BEQ rel - ^codeptr = $01; codeptr++ // +1 - ^codeptr = $88; codeptr++ // DEY - ^codeptr = $98; codeptr++ // TYA - ^codeptr = $94; codeptr++ // STY zp,X - ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = $00; codeptr++ // $00 + codeptr=>0 = ($D0D5+$0100)+(VX<<8) // CMP ESTKL+1,X + //^codeptr = $D5; codeptr++ // CMP zp,X + //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + codeptr=>2 = $06D0 // BNE +6 + //^codeptr = $D0; codeptr++ // BNE rel + //^codeptr = $06; codeptr++ // +6 + codeptr=>4 = $C0B5+(VX<<8) // LDA ESTKH,X + //^codeptr = $B5; codeptr++ // LDA zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr=>6 = ($C0D5+$0100)+(VX<<8) // CMP ESTKH+1 + //^codeptr = $D5; codeptr++ // CMP zp,X + //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + codeptr=>8 = $01F0 // BEQ +1 + //^codeptr = $F0; codeptr++ // BEQ rel + //^codeptr = $01; codeptr++ // +1 + codeptr=>10 = $9888 // DEY TYA + //^codeptr = $88; codeptr++ // DEY + //^codeptr = $98; codeptr++ // TYA + codeptr=>12 = ($C094+$0100)+(VX<<8) // STY ESTKH+1,X + //^codeptr = $94; codeptr++ // STY zp,X + //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + codeptr=>14 = $00A0 // LDY #$00 + //^codeptr = $A0; codeptr++ // LDY #imm + //^codeptr = $00; codeptr++ // $00 VX++ // INX //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL + codeptr = codeptr + 16 A_IS_TOSL = TOSL_DIRTY break - is $44 + is $44 // ISGT //puts("ISGT") if not A_IS_TOSL *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - ^codeptr = $D5; codeptr++ // CMP zp,X - ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH - ^codeptr = $F5; codeptr++ // SBC zp,X - ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - ^codeptr = $50; codeptr++ // BVC rel - ^codeptr = $02; codeptr++ // +2 - ^codeptr = $49; codeptr++ // EOR #imm - ^codeptr = $80; codeptr++ // $80 - ^codeptr = $10; codeptr++ // BPL rel - ^codeptr = $01; codeptr++ // +1 - ^codeptr = $88; codeptr++ // DEY - ^codeptr = $98; codeptr++ // TYA - ^codeptr = $94; codeptr++ // STY zp,X - ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = $00; codeptr++ // $00 + codeptr=>0 = ($D0D5+$0100)+(VX<<8) // CMP ESTKL+1,X + //^codeptr = $D5; codeptr++ // CMP zp,X + //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + codeptr=>2 = $C0B5+(VX<<8) // LDA ESTKH,X + //^codeptr = $B5; codeptr++ // LDA zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr=>4 = ($C0F5+$0100)+(VX<<8) // SBC ESTKH+1 + //^codeptr = $F5; codeptr++ // SBC zp,X + //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + codeptr=>6 = $0250 // BVC +2 + //^codeptr = $50; codeptr++ // BVC rel + //^codeptr = $02; codeptr++ // +2 + codeptr=>8 = $8049 // EOR #$80 + //^codeptr = $49; codeptr++ // EOR #imm + //^codeptr = $80; codeptr++ // $80 + codeptr=>10 = $0110 // BPL +1 + //^codeptr = $10; codeptr++ // BPL rel + //^codeptr = $01; codeptr++ // +1 + codeptr=>12 = $9888 // DEY TYA + //^codeptr = $88; codeptr++ // DEY + //^codeptr = $98; codeptr++ // TYA + codeptr=>14 = ($C094+$0100)+(VX<<8) // STY ESTKH+1,X + //^codeptr = $94; codeptr++ // STY zp,X + //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + codeptr=>16 = $00A0 // LDY #$00 + //^codeptr = $A0; codeptr++ // LDY #imm + //^codeptr = $00; codeptr++ // $00 VX++ // INX //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL + codeptr = codeptr + 18 A_IS_TOSL = TOSL_DIRTY break is $46 @@ -723,29 +751,40 @@ def compiler(defptr)#0 *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - ^codeptr = $D5; codeptr++ // CMP zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - ^codeptr = $F5; codeptr++ // SBC zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH - ^codeptr = $50; codeptr++ // BVC rel - ^codeptr = $02; codeptr++ // +2 - ^codeptr = $49; codeptr++ // EOR #imm - ^codeptr = $80; codeptr++ // $80 - ^codeptr = $10; codeptr++ // BPL rel - ^codeptr = $01; codeptr++ // +1 - ^codeptr = $88; codeptr++ // DEY - ^codeptr = $98; codeptr++ // TYA - ^codeptr = $94; codeptr++ // STY zp,X - ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = $00; codeptr++ // $00 + codeptr=>0 = ($D0B5+$0100)+(VX<<8) // LDA ESTKL+1,X + //^codeptr = $B5; codeptr++ // LDA zp,X + //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + codeptr=>2 = $D0D5+(VX<<8) // CMP ESTKL,X + //^codeptr = $D5; codeptr++ // CMP zp,X + //^codeptr = $D0+VX; codeptr++ // ESTKL + codeptr=>4 = ($C0B5+$0100)+(VX<<8) // LDA ESTKH+1,X + //^codeptr = $B5; codeptr++ // LDA zp,X + //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + codeptr=>6 = $C0F5+(VX<<8) // SBC ESTKH + //^codeptr = $F5; codeptr++ // SBC zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr=>8 = $0250 // BVC +2 + //^codeptr = $50; codeptr++ // BVC rel + //^codeptr = $02; codeptr++ // +2 + codeptr=>10 = $8049 // EOR #$80 + //^codeptr = $49; codeptr++ // EOR #imm + //^codeptr = $80; codeptr++ // $80 + codeptr=>12 = $0110 // BPL +1 + //^codeptr = $10; codeptr++ // BPL rel + //^codeptr = $01; codeptr++ // +1 + codeptr=>14 = $9888 // DEY TYA + //^codeptr = $88; codeptr++ // DEY + //^codeptr = $98; codeptr++ // TYA + codeptr=>16 = ($C094+$0100)+(VX<<8) // STY ESTKH+1,X + //^codeptr = $94; codeptr++ // STY zp,X + //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + codeptr=>18 = $00A0 // LDY #$00 + //^codeptr = $A0; codeptr++ // LDY #imm + //^codeptr = $00; codeptr++ // $00 VX++ // INX //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL + codeptr = codeptr + 20 A_IS_TOSL = TOSL_DIRTY break is $48 @@ -754,61 +793,82 @@ def compiler(defptr)#0 *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - ^codeptr = $D5; codeptr++ // CMP zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - ^codeptr = $F5; codeptr++ // SBC zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH - ^codeptr = $50; codeptr++ // BVC rel - ^codeptr = $02; codeptr++ // +2 - ^codeptr = $49; codeptr++ // EOR #imm - ^codeptr = $80; codeptr++ // $80 - ^codeptr = $30; codeptr++ // BMI rel - ^codeptr = $01; codeptr++ // +1 - ^codeptr = $88; codeptr++ // DEY - ^codeptr = $98; codeptr++ // TYA - ^codeptr = $94; codeptr++ // STY zp,X - ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = $00; codeptr++ // $00 + codeptr=>0 = ($D0B5+$0100)+(VX<<8) // LDA ESTKL+1,X + //^codeptr = $B5; codeptr++ // LDA zp,X + //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + codeptr=>2 = $D0D5+(VX<<8) // CMP ESTKL,X + //^codeptr = $D5; codeptr++ // CMP zp,X + //^codeptr = $D0+VX; codeptr++ // ESTKL + codeptr=>4 = ($C0B5+$0100)+(VX<<8) // LDA ESTKH+1,X + //^codeptr = $B5; codeptr++ // LDA zp,X + //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + codeptr=>6 = $C0F5+(VX<<8) // SBC ESTKH + //^codeptr = $F5; codeptr++ // SBC zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr=>8 = $0250 // BVC +2 + //^codeptr = $50; codeptr++ // BVC rel + //^codeptr = $02; codeptr++ // +2 + codeptr=>10 = $8049 // EOR #$80 + //^codeptr = $49; codeptr++ // EOR #imm + //^codeptr = $80; codeptr++ // $80 + codeptr=>12 = $0130 // BMI +1 + //^codeptr = $30; codeptr++ // BMI rel + //^codeptr = $01; codeptr++ // +1 + codeptr=>14 = $9888 // DEY TYA + //^codeptr = $88; codeptr++ // DEY + //^codeptr = $98; codeptr++ // TYA + codeptr=>16 = ($C094+$0100)+(VX<<8) // STY ESTKH+1,X + //^codeptr = $94; codeptr++ // STY zp,X + //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + codeptr=>18 = $00A0 // LDY #$00 + //^codeptr = $A0; codeptr++ // LDY #imm + //^codeptr = $00; codeptr++ // $00 VX++ // INX //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL + codeptr = codeptr + 20 A_IS_TOSL = TOSL_DIRTY break - is $4A + is $4A // ISLE //puts("ISLE") if not A_IS_TOSL *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - ^codeptr = $D5; codeptr++ // CMP zp,X - ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH - ^codeptr = $F5; codeptr++ // SBC zp,X - ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - ^codeptr = $50; codeptr++ // BVC rel - ^codeptr = $02; codeptr++ // +2 - ^codeptr = $49; codeptr++ // EOR #imm - ^codeptr = $80; codeptr++ // $80 - ^codeptr = $30; codeptr++ // BMI rel - ^codeptr = $01; codeptr++ // +1 - ^codeptr = $88; codeptr++ // DEY - ^codeptr = $98; codeptr++ // TYA - ^codeptr = $94; codeptr++ // STY zp,X - ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = $00; codeptr++ // $00 + codeptr=>0 = ($D0D5+$0100)+(VX<<8) // CMP ESTKL+1,X + //^codeptr = $D5; codeptr++ // CMP zp,X + //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + codeptr=>2 = $C0B5+(VX<<8) // LDA ESTKH,X + //^codeptr = $B5; codeptr++ // LDA zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr=>4 = ($C0F5+$0100)+(VX<<8) // SBC ESTKH+1 + //^codeptr = $F5; codeptr++ // SBC zp,X + //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + codeptr=>6 = $0250 // BVC +2 + //^codeptr = $50; codeptr++ // BVC rel + //^codeptr = $02; codeptr++ // +2 + codeptr=>8 = $8049 // EOR #$80 + //^codeptr = $49; codeptr++ // EOR #imm + //^codeptr = $80; codeptr++ // $80 + codeptr=>10 = $0130 // BMI +1 + //^codeptr = $30; codeptr++ // BMI rel + //^codeptr = $01; codeptr++ // +1 + codeptr=>12 = $9888 // DEY TYA + //^codeptr = $88; codeptr++ // DEY + //^codeptr = $98; codeptr++ // TYA + codeptr=>14 = ($C094+$0100)+(VX<<8) // STY ESTKH+1,X + //^codeptr = $94; codeptr++ // STY zp,X + //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + codeptr=>16 = $00A0 // LDY #$00 + //^codeptr = $A0; codeptr++ // LDY #imm + //^codeptr = $00; codeptr++ // $00 VX++ // INX //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL + codeptr = codeptr + 18 A_IS_TOSL = TOSL_DIRTY break - is $4C + is $4C // BRFLS i++ dest = i + *(bytecode+i) i++ @@ -819,19 +879,26 @@ def compiler(defptr)#0 *codeptr = ($D0B5-$0100)+(VX<<8) // LDA ESTKL-1,X codeptr = codeptr + 2 fin - ^codeptr = $15; codeptr++ // ORA zp,X - ^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 - ^codeptr = $D0; codeptr++ // BNE rel - ^codeptr = $03; codeptr++ // +3 - ^codeptr = $4C; codeptr++ // JMP abs - *codeptr = addrxlate=>[dest] - if not (*codeptr & $8000) // Unresolved address list - addrxlate=>[dest] = codeptr - *jitcodeptr + codeptr=>0 = ($C015-$0100)+(VX<<8) // ORA ESTKH-1,X + //^codeptr = $15; codeptr++ // ORA zp,X + //^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 + codeptr=>2 = $03D0 // BNE +3 + //^codeptr = $D0; codeptr++ // BNE rel + //^codeptr = $03; codeptr++ // +3 + codeptr->4 = $4C // JMP abs + //^codeptr = $4C; codeptr++ // JMP abs + codeptr=>5 = addrxlate=>[dest] + //*codeptr = addrxlate=>[dest] + if not (codeptr->6 & $80) // Unresolved address list + //if not (*codeptr & $8000) // Unresolved address list + addrxlate=>[dest] = codeptr + 5 - *jitcodeptr + //addrxlate=>[dest] = codeptr - *jitcodeptr fin - codeptr = codeptr + 2 + codeptr = codeptr + 7 + //codeptr = codeptr + 2 A_IS_TOSL = FALSE break - is $4E + is $4E // BRTRU i++ dest = i + *(bytecode+i) i++ @@ -842,16 +909,23 @@ def compiler(defptr)#0 *codeptr = ($D0B5-$0100)+(VX<<8) // LDA ESTKL-1,X codeptr = codeptr + 2 fin - ^codeptr = $15; codeptr++ // ORA zp,X - ^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 - ^codeptr = $F0; codeptr++ // BEQ rel - ^codeptr = $03; codeptr++ // +3 - ^codeptr = $4C; codeptr++ // JMP abs - *codeptr = addrxlate=>[dest] - if not (*codeptr & $8000) // Unresolved address list - addrxlate=>[dest] = codeptr - *jitcodeptr + codeptr=>0 = ($C015-$0100)+(VX<<8) // ORA ESTKH-1,X + //^codeptr = $15; codeptr++ // ORA zp,X + //^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 + codeptr=>2 = $03F0 // BEQ +3 + //^codeptr = $F0; codeptr++ // BEQ rel + //^codeptr = $03; codeptr++ // +3 + codeptr->4 = $4C // JMP abs + //^codeptr = $4C; codeptr++ // JMP abs + codeptr=>5 = addrxlate=>[dest] + //*codeptr = addrxlate=>[dest] + if not (codeptr->6 & $80) // Unresolved address list + //if not (*codeptr & $8000) // Unresolved address list + addrxlate=>[dest] = codeptr + 5 - *jitcodeptr + //addrxlate=>[dest] = codeptr - *jitcodeptr fin - codeptr = codeptr + 2 + codeptr = codeptr + 7 + //codeptr = codeptr + 2 A_IS_TOSL = FALSE break // BRNCH,SEL,CALL,ICAL,ENTER,LEAVE,RET,CFFB ; 50 52 54 56 58 5A 5C 5E From 08e41bf4724b9ac68d0ef0193d35fc77c3048b09 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Sun, 25 Mar 2018 13:53:53 -0700 Subject: [PATCH 096/147] Update ops $50-$5E --- src/libsrc/apple/jit.pla | 287 ++++++++++++++++++++++----------------- 1 file changed, 165 insertions(+), 122 deletions(-) diff --git a/src/libsrc/apple/jit.pla b/src/libsrc/apple/jit.pla index 129abf3..1206d26 100644 --- a/src/libsrc/apple/jit.pla +++ b/src/libsrc/apple/jit.pla @@ -894,7 +894,7 @@ def compiler(defptr)#0 addrxlate=>[dest] = codeptr + 5 - *jitcodeptr //addrxlate=>[dest] = codeptr - *jitcodeptr fin - codeptr = codeptr + 7 + codeptr = codeptr + 7 //codeptr = codeptr + 2 A_IS_TOSL = FALSE break @@ -924,7 +924,7 @@ def compiler(defptr)#0 addrxlate=>[dest] = codeptr + 5 - *jitcodeptr //addrxlate=>[dest] = codeptr - *jitcodeptr fin - codeptr = codeptr + 7 + codeptr = codeptr + 7 //codeptr = codeptr + 2 A_IS_TOSL = FALSE break @@ -939,12 +939,17 @@ def compiler(defptr)#0 *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin - ^codeptr = $4C; codeptr++ // JMP abs - *codeptr = addrxlate=>[dest] - if not (*codeptr & $8000) // Unresolved address list - addrxlate=>[dest] = codeptr - *jitcodeptr + codeptr->0 = $4C // JMP abs + //^codeptr = $4C; codeptr++ // JMP abs + codeptr=>1 = addrxlate=>[dest] + //*codeptr = addrxlate=>[dest] + if not (codeptr->2 & $80) // Unresolved address list + //if not (*codeptr & $8000) // Unresolved address list + addrxlate=>[dest] = codeptr + 1 - *jitcodeptr + //addrxlate=>[dest] = codeptr - *jitcodeptr fin - codeptr = codeptr + 2 + codeptr = codeptr + 3 + //codeptr = codeptr + 2 A_IS_TOSL = FALSE break is $52 @@ -958,47 +963,64 @@ def compiler(defptr)#0 ^(bytecode+case) = $FE // Flag as NOP case++ if not A_IS_TOSL - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 fin - ^codeptr = $B4; codeptr++ // LDY zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH - //VX++ //^codeptr = $E8; codeptr++ // INX - codeptr, VX = resolveX(codeptr, VX + 1) + codeptr=>0 = $C0B4+(VX<<8) // LDY ESTKH,X + //^codeptr = $B4; codeptr++ // LDY zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr = codeptr + 2 + codeptr, VX = resolveX(codeptr, VX + 1) // INX repeat //puts(" $"); puth(*(bytecode+case)) - ^codeptr = $C9; codeptr++ // CMP #imm - ^codeptr = ^(bytecode+case); codeptr++ - ^codeptr = $D0; codeptr++ // BNE rel - ^codeptr = $09; codeptr++ // +9 - ^codeptr = $C0; codeptr++ // CPY #imm - ^codeptr = ^(bytecode+case+1); codeptr++ - ^codeptr = $D0; codeptr++ // BNE rel - ^codeptr = $05; codeptr++ // +5 + codeptr=>0 = $C9+(^(bytecode+case)<<8) // CMP #imm + //^codeptr = $C9; codeptr++ // CMP #imm + //^codeptr = ^(bytecode+case); codeptr++ + codeptr=>2 = $09D0 // BNE +9 + //^codeptr = $D0; codeptr++ // BNE rel + //^codeptr = $09; codeptr++ // +9 + codeptr=>4 = $C0+(^(bytecode+case+1)<<8) // CPY #imm + //^codeptr = $C0; codeptr++ // CPY #imm + //^codeptr = ^(bytecode+case+1); codeptr++ + codeptr=>6 = $05D0 // BNE +5 + //^codeptr = $D0; codeptr++ // BNE rel + //^codeptr = $05; codeptr++ // +5 *(bytecode+case) = $FEFE case = case + 2 dest = case + *(bytecode+case) //puts("-->"); puti(dest); putln - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = $00; codeptr++ // $00 - ^codeptr = $4C; codeptr++ // JMP abs - *codeptr = addrxlate=>[dest] - if not (*codeptr & $8000) // Unresolved address list - addrxlate=>[dest] = codeptr - *jitcodeptr + codeptr=>8 = $00A0 // LDY #$00 + //^codeptr = $A0; codeptr++ // LDY #imm + //^codeptr = $00; codeptr++ // $00 + codeptr->10 = $4C // JMP abs + //^codeptr = $4C; codeptr++ // JMP abs + codeptr=>11 = addrxlate=>[dest] + //*codeptr = addrxlate=>[dest] + if not (codeptr->12 & $80) // Unresolved address list + //if not (*codeptr & $8000) // Unresolved address list + addrxlate=>[dest] = codeptr + 11 - *jitcodeptr + //addrxlate=>[dest] = codeptr - *jitcodeptr fin - codeptr = codeptr + 2 + codeptr = codeptr + 13 + //codeptr = codeptr + 2 *(bytecode+case) = $FEFE case = case + 2 j-- until not j - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = $00; codeptr++ // $00 - ^codeptr = $4C; codeptr++ // JMP abs - *codeptr = addrxlate=>[case] - if not (*codeptr & $8000) // Unresolved address list - addrxlate=>[case] = codeptr - *jitcodeptr + codeptr=>0 = $00A0 // LDY #$00 + //^codeptr = $A0; codeptr++ // LDY #imm + //^codeptr = $00; codeptr++ // $00 + codeptr->1 = $4C // JMP abs + //^codeptr = $4C; codeptr++ // JMP abs + codeptr=>2 = addrxlate=>[case] + //*codeptr = addrxlate=>[case] + if not (codeptr->3 & $80) // Unresolved address list + //if not (*codeptr & $8000) // Unresolved address list + addrxlate=>[case] = codeptr + 2- *jitcodeptr + //addrxlate=>[case] = codeptr - *jitcodeptr fin - codeptr = codeptr + 2 + codeptr = codeptr + 4 + //codeptr = codeptr + 2 else codeptr = dest fin @@ -1015,10 +1037,14 @@ def compiler(defptr)#0 codeptr = codeptr + 2 fin codeptr, VX = resolveX(codeptr, VX) - ^codeptr = $20; codeptr++ // JSR abs - *codeptr = *(bytecode+i); codeptr = codeptr + 2 - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = $00; codeptr++ // $00 + codeptr->0 = $20 // JSR abs + //^codeptr = $20; codeptr++ // JSR abs + codeptr=>1 = *(bytecode+i) + //*codeptr = *(bytecode+i); codeptr = codeptr + 2 + codeptr=>3 = $00A0 // LDY #$00 + //^codeptr = $A0; codeptr++ // LDY #imm + //^codeptr = $00; codeptr++ // $00 + codeptr = codeptr + 5 A_IS_TOSL = FALSE i++ break @@ -1028,25 +1054,33 @@ def compiler(defptr)#0 // Pull address off stack // if not A_IS_TOSL - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 fin - ^codeptr = $85; codeptr++ // STA zp - ^codeptr = $E7; codeptr++ // $E7:TMPL - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH - ^codeptr = $85; codeptr++ // STA zp - ^codeptr = $E8; codeptr++ // $E8:TMPH - //VX++ //^codeptr = $E8; codeptr++ // INX - codeptr, VX = resolveX(codeptr, VX + 1) + codeptr=>0 = $E785 // STA $E7:TMPL + //^codeptr = $85; codeptr++ // STA zp + //^codeptr = $E7; codeptr++ // $E7:TMPL + codeptr=>2 = $C0B5+(VX<<8) // LDA ESTKH,X + //^codeptr = $B5; codeptr++ // LDA zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr=>4 = $E885 // STA $E8:TMPH + //^codeptr = $85; codeptr++ // STA zp + //^codeptr = $E8; codeptr++ // $E8:TMPH + //^codeptr = $E8; codeptr++ // INX + codeptr = codeptr + 6 // // Call through TMP // - ^codeptr = $20; codeptr++ // JSR abs - ^codeptr = $E6; codeptr++ // JMPTMP - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = $00; codeptr++ // $00 + codeptr, VX = resolveX(codeptr, VX + 1) // INX + codeptr->0 = $20 // JSR abs + //^codeptr = $20; codeptr++ // JSR abs + codeptr=>1 = $00E6 // JMPTMP + //^codeptr = $E6; codeptr++ // JMPTMP + codeptr=>3 = $00A0 // LDY #$00 + //^codeptr = $A0; codeptr++ // LDY #imm + //^codeptr = $00; codeptr++ // $00 + codeptr = codeptr + 5 A_IS_TOSL = FALSE break is $5A @@ -1060,10 +1094,14 @@ def compiler(defptr)#0 codeptr = codeptr + 2 fin codeptr, VX = resolveX(codeptr, VX) - ^codeptr = $20; codeptr++ // JSR INTERP - *codeptr = $3D0; codeptr = codeptr + 2 - ^codeptr = $5A; codeptr++ // LEAVE CODE - ^codeptr = ^(bytecode+i); codeptr++ // LEAVE OPERAND + codeptr->0 = $20 // JSR abs + //^codeptr = $20; codeptr++ // JSR INTERP + codeptr=>1 = $03D0 // INTERP + //*codeptr = $3D0; codeptr = codeptr + 2 + codeptr=>3 = $5A + (^(bytecode+i)<<8) // LEAVE CODE AND OPERAND + //^codeptr = $5A; codeptr++ // LEAVE CODE + //^codeptr = ^(bytecode+i); codeptr++ // LEAVE OPERAND + codeptr = codeptr + 5 A_IS_TOSL = FALSE break is $5C @@ -1073,7 +1111,8 @@ def compiler(defptr)#0 codeptr = codeptr + 2 fin codeptr, VX = resolveX(codeptr, VX) - ^codeptr = $60; codeptr++ // RTS + ^codeptr = $60 //RTS + codeptr++ A_IS_TOSL = FALSE break is $5E @@ -1083,23 +1122,27 @@ def compiler(defptr)#0 *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin - VX-- //^codeptr = $CA; codeptr++ // DEX - ^codeptr = $A9; codeptr++ // LDA #imm - ^codeptr = $FF; codeptr++ // $FF - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH - ^codeptr = $A9; codeptr++ // LDA #imm - ^codeptr = ^(bytecode+i); codeptr++ + VX-- // DEX + codeptr=>0 = $FFA9 // LDA #$FF + //^codeptr = $A9; codeptr++ // LDA #imm + //^codeptr = $FF; codeptr++ // $FF + codeptr=>2 = $C095+(VX<<8) // STA ESTKH,X + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr=>4 = $A9 + (^(bytecode+i)<<8) // LDA #imm + //^codeptr = $A9; codeptr++ // LDA #imm + //^codeptr = ^(bytecode+i); codeptr++ //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL + codeptr = codeptr + 6 A_IS_TOSL = TOSL_DIRTY break // LB,LW,LLB,LLW,LAB,LAW,DLB,DLW ; 60 62 64 66 68 6A 6C 6E is $60 //puts("LB") if not A_IS_TOSL - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 fin ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 @@ -1114,8 +1157,8 @@ def compiler(defptr)#0 is $62 //puts("LW") if not A_IS_TOSL - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 fin ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 @@ -1228,8 +1271,8 @@ def compiler(defptr)#0 i++ //puts("DLB "); puti(^(bytecode+i)) if not A_IS_TOSL - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 A_IS_TOSL = TOSL_CLEAN fin if ^(bytecode+i) <> 0 @@ -1275,8 +1318,8 @@ def compiler(defptr)#0 is $70 //puts("SB") if not A_IS_TOSL - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 fin ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 @@ -1292,8 +1335,8 @@ def compiler(defptr)#0 is $72 //puts("SW") if not A_IS_TOSL - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 fin ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 @@ -1320,8 +1363,8 @@ def compiler(defptr)#0 i++ //puts("SLB "); puti(^(bytecode+i)) if not A_IS_TOSL - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 fin if ^(bytecode+i) <> 0 ^codeptr = $A0; codeptr++ // LDY #imm @@ -1340,8 +1383,8 @@ def compiler(defptr)#0 i++ //puts("SLW "); puti(^(bytecode+i)) if not A_IS_TOSL - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 fin if ^(bytecode+i) <> 0 ^codeptr = $A0; codeptr++ // LDY #imm @@ -1367,8 +1410,8 @@ def compiler(defptr)#0 i++ //puts("SAB $"); puth(*(bytecode+i)) if not A_IS_TOSL - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 fin ^codeptr = $8D; codeptr++ // STA abs *codeptr = *(bytecode+i); codeptr = codeptr + 2 @@ -1380,8 +1423,8 @@ def compiler(defptr)#0 i++ //puts("SAW $"); puth(*(bytecode+i)) if not A_IS_TOSL - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 fin ^codeptr = $8D; codeptr++ // STA abs *codeptr = *(bytecode+i); codeptr = codeptr + 2 @@ -1397,8 +1440,8 @@ def compiler(defptr)#0 i++ //puts("DAB $"); puth(*(bytecode+i)) if not A_IS_TOSL - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 A_IS_TOSL = TOSL_CLEAN fin ^codeptr = $8D; codeptr++ // STA abs @@ -1409,8 +1452,8 @@ def compiler(defptr)#0 i++ //puts("DAW $"); puth(*(bytecode+i)) if not A_IS_TOSL - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 A_IS_TOSL = TOSL_CLEAN fin ^codeptr = $8D; codeptr++ // STA abs @@ -1427,8 +1470,8 @@ def compiler(defptr)#0 is $80 //puts("NOT") if not A_IS_TOSL - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 fin ^codeptr = $15; codeptr++ // ORA zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH @@ -1447,8 +1490,8 @@ def compiler(defptr)#0 is $82 //puts("ADD") if not A_IS_TOSL - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 fin ^codeptr = $18; codeptr++ // CLC ^codeptr = $75; codeptr++ // ADC zp,X @@ -1523,8 +1566,8 @@ def compiler(defptr)#0 is $8C //puts("INCR") if not A_IS_TOSL - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 fin ^codeptr = $18; codeptr++ // CLC ^codeptr = $69; codeptr++ // ADC #imm @@ -1540,8 +1583,8 @@ def compiler(defptr)#0 is $8E //puts("DECR") if not A_IS_TOSL - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 fin ^codeptr = $38; codeptr++ // SEC ^codeptr = $E9; codeptr++ // SBC #imm @@ -1577,8 +1620,8 @@ def compiler(defptr)#0 is $92 //puts("COMP") if not A_IS_TOSL - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 fin ^codeptr = $49; codeptr++ // EOR #imm ^codeptr = $FF; codeptr++ // $FF @@ -1595,8 +1638,8 @@ def compiler(defptr)#0 is $94 //puts("AND") if not A_IS_TOSL - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 fin ^codeptr = $35; codeptr++ // AND zp,X ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 @@ -1614,8 +1657,8 @@ def compiler(defptr)#0 is $96 //puts("OR") if not A_IS_TOSL - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 fin ^codeptr = $15; codeptr++ // ORA zp,X ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 @@ -1633,8 +1676,8 @@ def compiler(defptr)#0 is $98 //puts("XOR") if not A_IS_TOSL - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 fin ^codeptr = $55; codeptr++ // EOR zp,X ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 @@ -1652,8 +1695,8 @@ def compiler(defptr)#0 is $9E //puts("IDXW") if not A_IS_TOSL - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 fin ^codeptr = $0A; codeptr++ // ASL ^codeptr = $36; codeptr++ // ROL zp,X @@ -1714,8 +1757,8 @@ def compiler(defptr)#0 i++ codeptr, VX = resolveX(codeptr, VX) if not A_IS_TOSL - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 else ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL @@ -1751,8 +1794,8 @@ def compiler(defptr)#0 // INCR // if not A_IS_TOSL - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 fin ^codeptr = $18; codeptr++ // CLC ^codeptr = $69; codeptr++ // ADC #imm @@ -1800,8 +1843,8 @@ def compiler(defptr)#0 // ADD // if not A_IS_TOSL - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 fin ^codeptr = $18; codeptr++ // CLC ^codeptr = $75; codeptr++ // ADC zp,X @@ -1852,8 +1895,8 @@ def compiler(defptr)#0 // DECR // if not A_IS_TOSL - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 fin ^codeptr = $38; codeptr++ // SEC ^codeptr = $E9; codeptr++ // SBC #imm @@ -2003,8 +2046,8 @@ def compiler(defptr)#0 i++ //puts("ADDLB "); puti(^(bytecode+i)) if not A_IS_TOSL - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 fin if ^(bytecode+i) <> 0 ^codeptr = $A0; codeptr++ // LDY #imm @@ -2029,8 +2072,8 @@ def compiler(defptr)#0 i++ //puts("ADDLW "); puti(^(bytecode+i)) if not A_IS_TOSL - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 fin if ^(bytecode+i) <> 0 ^codeptr = $A0; codeptr++ // LDY #imm @@ -2060,8 +2103,8 @@ def compiler(defptr)#0 i++ //puts("ADDAB $"); puth(*(bytecode+i)) if not A_IS_TOSL - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 fin ^codeptr = $18; codeptr++ // CLC ^codeptr = $6D; codeptr++ // ADC abs @@ -2079,8 +2122,8 @@ def compiler(defptr)#0 i++ //puts("ADDAW $"); puth(*(bytecode+i)) if not A_IS_TOSL - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 fin ^codeptr = $18; codeptr++ // CLC ^codeptr = $6D; codeptr++ // ADC abs From 8f5d4647bf23b9523fac7055f993b1020c08507d Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Sun, 25 Mar 2018 17:31:07 -0700 Subject: [PATCH 097/147] Update ops $60-$6E --- src/libsrc/apple/jit.pla | 244 ++++++++++++++++++++++++--------------- 1 file changed, 151 insertions(+), 93 deletions(-) diff --git a/src/libsrc/apple/jit.pla b/src/libsrc/apple/jit.pla index 1206d26..1f77f1b 100644 --- a/src/libsrc/apple/jit.pla +++ b/src/libsrc/apple/jit.pla @@ -511,7 +511,7 @@ def compiler(defptr)#0 codeptr = codeptr + 12 + j A_IS_TOSL = FALSE break - // DROP,DROP2,DUP,DIVMOD,ADDI,SUBI,ANDI,ORI ; 30 32 34 36 38 3A 3C 3E + // DROP,DROP2,DUP,DIVMOD,ADDI,SUBI,ANDI,ORI ; 30 32 34 36 38 3A 3C 3E is $32 // DROP2 //puts("DROP2") VX++ // INX @@ -633,7 +633,7 @@ def compiler(defptr)#0 codeptr = codeptr + 2 A_IS_TOSL = TOSL_DIRTY break - // ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E + // ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E is $40 // ISEQ //puts("ISEQ") if not A_IS_TOSL @@ -928,8 +928,8 @@ def compiler(defptr)#0 //codeptr = codeptr + 2 A_IS_TOSL = FALSE break - // BRNCH,SEL,CALL,ICAL,ENTER,LEAVE,RET,CFFB ; 50 52 54 56 58 5A 5C 5E - is $50 + // BRNCH,SEL,CALL,ICAL,ENTER,LEAVE,RET,CFFB ; 50 52 54 56 58 5A 5C 5E + is $50 // BRNCH i++ dest = i + *(bytecode+i) i++ @@ -952,7 +952,7 @@ def compiler(defptr)#0 //codeptr = codeptr + 2 A_IS_TOSL = FALSE break - is $52 + is $52 // SEL i++ case = i + *(bytecode+i) i++ @@ -1026,7 +1026,7 @@ def compiler(defptr)#0 fin A_IS_TOSL = FALSE break - is $54 + is $54 // CALL i++ //puts("CALL $"); puth(*(bytecode+i)) // @@ -1048,7 +1048,7 @@ def compiler(defptr)#0 A_IS_TOSL = FALSE i++ break - is $56 + is $56 // ICAL //puts("ICAL") // // Pull address off stack @@ -1083,7 +1083,7 @@ def compiler(defptr)#0 codeptr = codeptr + 5 A_IS_TOSL = FALSE break - is $5A + is $5A // LEAVE i++ //puts("LEAVE "); puti(^(bytecode+i)) // @@ -1104,7 +1104,7 @@ def compiler(defptr)#0 codeptr = codeptr + 5 A_IS_TOSL = FALSE break - is $5C + is $5C // RET //puts("RET") if A_IS_TOSL & TOSL_DIRTY *codeptr = $D095+(VX<<8) // STA ESTKL,X @@ -1115,7 +1115,7 @@ def compiler(defptr)#0 codeptr++ A_IS_TOSL = FALSE break - is $5E + is $5E // CFFB i++ //puts("CFFB $FF"); putb(^(bytecode+i)) if A_IS_TOSL & TOSL_DIRTY @@ -1129,7 +1129,7 @@ def compiler(defptr)#0 codeptr=>2 = $C095+(VX<<8) // STA ESTKH,X //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $C0+VX; codeptr++ // ESTKH - codeptr=>4 = $A9 + (^(bytecode+i)<<8) // LDA #imm + codeptr=>4 = $A9+(^(bytecode+i)<<8) // LDA #imm //^codeptr = $A9; codeptr++ // LDA #imm //^codeptr = ^(bytecode+i); codeptr++ //^codeptr = $95; codeptr++ // STA zp,X @@ -1137,97 +1137,129 @@ def compiler(defptr)#0 codeptr = codeptr + 6 A_IS_TOSL = TOSL_DIRTY break - // LB,LW,LLB,LLW,LAB,LAW,DLB,DLW ; 60 62 64 66 68 6A 6C 6E - is $60 + // LB,LW,LLB,LLW,LAB,LAW,DLB,DLW ; 60 62 64 66 68 6A 6C 6E + is $60 // LB //puts("LB") if not A_IS_TOSL *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 - ^codeptr = $A1; codeptr++ // LDA (zp,X) - ^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 - ^codeptr = $94; codeptr++ // STY zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr=>0 = ($C095-$0100)+(VX<<8) // STA ESTKH-1,X + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 + codeptr=>2 = ($C0A1-$0100)+(VX<<8) // LDA (ESTKH-1,X) + //^codeptr = $A1; codeptr++ // LDA (zp,X) + //^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 + codeptr=>4 = $C094+(VX<<8) // STY ESTKH,X + //^codeptr = $94; codeptr++ // STY zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL + codeptr = codeptr + 6 A_IS_TOSL = TOSL_DIRTY break - is $62 + is $62 // LW //puts("LW") if not A_IS_TOSL *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 - ^codeptr = $A1; codeptr++ // LDA (zp,X) - ^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL - ^codeptr = $F6; codeptr++ // INC zp,X - ^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 - ^codeptr = $D0; codeptr++ // BNE rel - ^codeptr = $02; codeptr++ // +2 - ^codeptr = $F6; codeptr++ // INC zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH - ^codeptr = $A1; codeptr++ // LDA (zp,X) - ^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr=>0 = ($C095-$0100)+(VX<<8) // STA ESTKH-1,X + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 + codeptr=>2 = ($C0A1-$0100)+(VX<<8) // LDA (ESTKH-1,X) + //^codeptr = $A1; codeptr++ // LDA (zp,X) + //^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 + codeptr=>4 = $D095+(VX<<8) // STA ESTKL,X + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $D0+VX; codeptr++ // ESTKL + codeptr=>6 = ($C0F6-$0100)+(VX<<8) // INC ESTKH-1,X + //^codeptr = $F6; codeptr++ // INC zp,X + //^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 + codeptr=>8 = $02D0 // BNE +2 + //^codeptr = $D0; codeptr++ // BNE rel + //^codeptr = $02; codeptr++ // +2 + codeptr=>10 = $C0F6+(VX<<8) // INC ESTKH,X + //^codeptr = $F6; codeptr++ // INC zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr=>12 = ($C0A1-$0100)+(VX<<8) // LDA (ESTKH-1,X) + //^codeptr = $A1; codeptr++ // LDA (zp,X) + //^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 + codeptr=>14 = $C095+(VX<<8) // STA ESTKH,X + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr = codeptr + 16 A_IS_TOSL = FALSE break - is $64 + is $64 // LLB i++ //puts("LLB "); puti(^(bytecode+i)) if A_IS_TOSL & TOSL_DIRTY *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin - VX-- //^codeptr = $CA; codeptr++ // DEX + VX-- // DEX if ^(bytecode+i) <> 0 - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = ^(bytecode+i); codeptr++ + *codeptr = $A0+(^(bytecode+i)<<8) // LDY #imm + codeptr = codeptr + 2 + //^codeptr = $A0; codeptr++ // LDY #imm + //^codeptr = ^(bytecode+i); codeptr++ fin - ^codeptr = $B1; codeptr++ // LDA (zp),Y - ^codeptr = $E0; codeptr++ // IFP + *codeptr = $E0B1 // LDA (IFP),Y + codeptr = codeptr + 2 + //^codeptr = $B1; codeptr++ // LDA (zp),Y + //^codeptr = $E0; codeptr++ // IFP if ^(bytecode+i) <> 0 - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = $00; codeptr++ // $00 + *codeptr = $00A0 // LDY #$00 + codeptr = codeptr + 2 + //^codeptr = $A0; codeptr++ // LDY #imm + //^codeptr = $00; codeptr++ // $00 fin - ^codeptr = $94; codeptr++ // STY zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH + *codeptr = $C094+(VX<<8) // STY ESTKH,X + //^codeptr = $94; codeptr++ // STY zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL + codeptr = codeptr + 2 A_IS_TOSL = TOSL_DIRTY break - is $66 + is $66 // LLW i++ //puts("LLW "); puti(^(bytecode+i)) if A_IS_TOSL & TOSL_DIRTY *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin - VX-- //^codeptr = $CA; codeptr++ // DEX + VX-- // DEX if ^(bytecode+i) <> 0 - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = ^(bytecode+i); codeptr++ + *codeptr = $A0+(^(bytecode+i)<<8) // LDY #imm + codeptr = codeptr + 2 + //^codeptr = $A0; codeptr++ // LDY #imm + //^codeptr = ^(bytecode+i); codeptr++ fin - ^codeptr = $B1; codeptr++ // LDA (zp),Y - ^codeptr = $E0; codeptr++ // IFP - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL - ^codeptr = $C8; codeptr++ // INY - ^codeptr = $B1; codeptr++ // LDA (zp),Y - ^codeptr = $E0; codeptr++ // IFP - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr=>0 = $E0B1 // LDA (IFP),Y + //^codeptr = $B1; codeptr++ // LDA (zp),Y + //^codeptr = $E0; codeptr++ // IFP + codeptr=>2 = $D095+(VX<<8) // STA ESTKL,X + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $D0+VX; codeptr++ // ESTKL + codeptr->4 = $C8 // INY + //^codeptr = $C8; codeptr++ // INY + codeptr=>5 = $E0B1 // LDA (IFP),Y + //^codeptr = $B1; codeptr++ // LDA (zp),Y + //^codeptr = $E0; codeptr++ // IFP + codeptr=>7 = $C095+(VX<<8) // STA ESTKH,X + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH if ^(bytecode+i) <> 0 - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = $00; codeptr++ // $00 + codeptr=>9 = $00A0 // LDY #$00 + codeptr = codeptr + 11 + //^codeptr = $A0; codeptr++ // LDY #imm + //^codeptr = $00; codeptr++ // $00 else - ^codeptr = $88; codeptr++ // DEY + codeptr->9 = $88 // DEY + codeptr = codeptr + 10 + //^codeptr = $88; codeptr++ // DEY fin A_IS_TOSL = FALSE break @@ -1238,13 +1270,17 @@ def compiler(defptr)#0 *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin - VX-- //^codeptr = $CA; codeptr++ // DEX - ^codeptr = $AD; codeptr++ // LDA abs - *codeptr = *(bytecode+i); codeptr = codeptr + 2 - ^codeptr = $94; codeptr++ // STY zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH + VX-- // DEX + codeptr->0 = $AD // LDA abs + //^codeptr = $AD; codeptr++ // LDA abs + codeptr=>1 = *(bytecode+i) + //*codeptr = *(bytecode+i); codeptr = codeptr + 2 + codeptr=>3 = $C094+(VX<<8) // STY ESTKH,X + //^codeptr = $94; codeptr++ // STY zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL + codeptr = codeptr + 5 A_IS_TOSL = TOSL_DIRTY i++ break @@ -1255,15 +1291,21 @@ def compiler(defptr)#0 *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin - VX-- //^codeptr = $CA; codeptr++ // DEX - ^codeptr = $AD; codeptr++ // LDA abs - *codeptr = *(bytecode+i)+1; codeptr = codeptr + 2 - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH - ^codeptr = $AD; codeptr++ // LDA abs - *codeptr = *(bytecode+i); codeptr = codeptr + 2 + VX-- // DEX + codeptr->0 = $AD // LDA abs + //^codeptr = $AD; codeptr++ // LDA abs + codeptr=>1 = *(bytecode+i)+1 + //*codeptr = *(bytecode+i)+1; codeptr = codeptr + 2 + codeptr=>3 = $C095+(VX<<8) // STA ESTKH,X + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr->5 = $AD // LDA abs + //^codeptr = $AD; codeptr++ // LDA abs + codeptr=>6 = *(bytecode+i) + //*codeptr = *(bytecode+i); codeptr = codeptr + 2 //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL + codeptr = codeptr + 8 A_IS_TOSL = TOSL_DIRTY i++ break @@ -1276,14 +1318,20 @@ def compiler(defptr)#0 A_IS_TOSL = TOSL_CLEAN fin if ^(bytecode+i) <> 0 - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = ^(bytecode+i); codeptr++ + *codeptr = $A0+(^(bytecode+i)<<8) // LDY #imm + codeptr = codeptr + 2 + //^codeptr = $A0; codeptr++ // LDY #imm + //^codeptr = ^(bytecode+i); codeptr++ fin - ^codeptr = $91; codeptr++ // STA (zp),Y - ^codeptr = $E0; codeptr++ // IFP + *codeptr = $E091 // STA (IFP),Y + codeptr = codeptr + 2 + //^codeptr = $91; codeptr++ // STA (zp),Y + //^codeptr = $E0; codeptr++ // IFP if ^(bytecode+i) <> 0 - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = $00; codeptr++ // $00 + *codeptr = $00A0 // LDY #$00 + codeptr = codeptr + 2 + //^codeptr = $A0; codeptr++ // LDY #imm + //^codeptr = $00; codeptr++ // $00 fin break is $6E @@ -1294,23 +1342,33 @@ def compiler(defptr)#0 codeptr = codeptr + 2 fin if ^(bytecode+i) <> 0 - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = ^(bytecode+i)+1; codeptr++ + *codeptr = $A0+((^(bytecode+i)+1)<<8) // LDY #imm + codeptr = codeptr + 2 + //^codeptr = $A0; codeptr++ // LDY #imm + //^codeptr = ^(bytecode+i)+1; codeptr++ else ^codeptr = $C8; codeptr++ // INY fin - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH - ^codeptr = $91; codeptr++ // STA (zp),Y - ^codeptr = $E0; codeptr++ // IFP - ^codeptr = $88; codeptr++ // DEY - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL - ^codeptr = $91; codeptr++ // STA (zp),Y - ^codeptr = $E0; codeptr++ // IFP + codeptr=>0 = $C0B5+(VX<<8) // LDA ESTKH,X + //^codeptr = $B5; codeptr++ // LDA zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr=>2 = $E091 // STA (IFP),Y + //^codeptr = $91; codeptr++ // STA (zp),Y + //^codeptr = $E0; codeptr++ // IFP + codeptr->4 = $88 // DEY + //^codeptr = $88; codeptr++ // DEY + codeptr=>5 = $D0B5+(VX<<8) // LDA ESTKL,X + //^codeptr = $B5; codeptr++ // LDA zp,X + //^codeptr = $D0+VX; codeptr++ // ESTKL + codeptr=>7 = $E091 // STA (IFP),Y + //^codeptr = $91; codeptr++ // STA (zp),Y + //^codeptr = $E0; codeptr++ // IFP + codeptr = codeptr + 9 if ^(bytecode+i) <> 0 - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = $00; codeptr++ // $00 + *codeptr = $00A0 // LDY #$00 + codeptr = codeptr + 2 + //^codeptr = $A0; codeptr++ // LDY #imm + //^codeptr = $00; codeptr++ // $00 fin A_IS_TOSL = TOSL_CLEAN break From 26a03d8e0b84482d0125ea12781472634879515f Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Sun, 25 Mar 2018 20:20:19 -0700 Subject: [PATCH 098/147] Update ops $70-$7E --- src/libsrc/apple/jit.pla | 192 ++++++++++++++++++++++++--------------- 1 file changed, 120 insertions(+), 72 deletions(-) diff --git a/src/libsrc/apple/jit.pla b/src/libsrc/apple/jit.pla index 1f77f1b..36fd32d 100644 --- a/src/libsrc/apple/jit.pla +++ b/src/libsrc/apple/jit.pla @@ -1263,7 +1263,7 @@ def compiler(defptr)#0 fin A_IS_TOSL = FALSE break - is $68 + is $68 // LAB i++ //puts("LAB $"); puth(*(bytecode+i)) if A_IS_TOSL & TOSL_DIRTY @@ -1284,7 +1284,7 @@ def compiler(defptr)#0 A_IS_TOSL = TOSL_DIRTY i++ break - is $6A + is $6A // LAW i++ //puts("LAW $"); puth(*(bytecode+i)) if A_IS_TOSL & TOSL_DIRTY @@ -1309,7 +1309,7 @@ def compiler(defptr)#0 A_IS_TOSL = TOSL_DIRTY i++ break - is $6C + is $6C // DLB i++ //puts("DLB "); puti(^(bytecode+i)) if not A_IS_TOSL @@ -1334,7 +1334,7 @@ def compiler(defptr)#0 //^codeptr = $00; codeptr++ // $00 fin break - is $6E + is $6E // DLW i++ //puts("DLW "); puti(^(bytecode+i)) if A_IS_TOSL & TOSL_DIRTY @@ -1373,51 +1373,64 @@ def compiler(defptr)#0 A_IS_TOSL = TOSL_CLEAN break // SB,SW,SLB,SLW,SAB,SAW,DAB,DAW ; 70 72 74 76 78 7A 7C 7E - is $70 + is $70 // SB //puts("SB") if not A_IS_TOSL *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - ^codeptr = $81; codeptr++ // STA (zp,X) - ^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 + codeptr=>0 = ($C095-$0100)+(VX<<8) // STA ESTKH-1,X + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 + codeptr=>2 = ($D0B5+$0100)+(VX<<8) // LDA ESTKL+1,X + //^codeptr = $B5; codeptr++ // LDA zp,X + //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + codeptr=>4 = ($C081-$0100)+(VX<<8) // STA (ESTKH-1,X) + //^codeptr = $81; codeptr++ // STA (zp,X) + //^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 //^codeptr = $E8; codeptr++ // INX //^codeptr = $E8; codeptr++ // INX + codeptr = codeptr + 6 VX = VX + 2 A_IS_TOSL = FALSE break - is $72 + is $72 // SW //puts("SW") if not A_IS_TOSL *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - ^codeptr = $81; codeptr++ // STA (zp,X) - ^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - ^codeptr = $F6; codeptr++ // INC zp,X - ^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 - ^codeptr = $D0; codeptr++ // BNE rel - ^codeptr = $02; codeptr++ // +2 - ^codeptr = $F6; codeptr++ // INC zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH - ^codeptr = $81; codeptr++ // STA (zp,X) - ^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 + codeptr=>0 = ($C095-$0100)+(VX<<8) // STA ESTKH-1,X + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 + codeptr=>2 = ($D0B5+$0100)+(VX<<8) // LDA ESTKL+1,X + //^codeptr = $B5; codeptr++ // LDA zp,X + //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + codeptr=>4 = ($C081-$0100)+(VX<<8) // STA (ESTKH-1,X) + //^codeptr = $81; codeptr++ // STA (zp,X) + //^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 + codeptr=>6 = ($C0B5+$0100)+(VX<<8) // LDA ESTKH+1,X + //^codeptr = $B5; codeptr++ // LDA zp,X + //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + codeptr=>8 = ($C0F6-$0100)+(VX<<8) // INC ESTKH-1,X + //^codeptr = $F6; codeptr++ // INC zp,X + //^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 + codeptr=>10 = $02D0 // BNE +2 + //^codeptr = $D0; codeptr++ // BNE rel + //^codeptr = $02; codeptr++ // +2 + codeptr=>12 = $C0F6+(VX<<8) // INC ESTKH,X + //^codeptr = $F6; codeptr++ // INC zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr=>14 = ($C081-$0100)+(VX<<8) // STA (ESTKH-1,X) + //^codeptr = $81; codeptr++ // STA (zp,X) + //^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 //^codeptr = $E8; codeptr++ // INX //^codeptr = $E8; codeptr++ // INX + codeptr = codeptr + 16 VX = VX + 2 A_IS_TOSL = FALSE break - is $74 + is $74 // SLB i++ //puts("SLB "); puti(^(bytecode+i)) if not A_IS_TOSL @@ -1425,19 +1438,25 @@ def compiler(defptr)#0 codeptr = codeptr + 2 fin if ^(bytecode+i) <> 0 - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = ^(bytecode+i); codeptr++ + *codeptr = $A0+(^(bytecode+i)<<8) // LDY #imm + codeptr = codeptr + 2 + //^codeptr = $A0; codeptr++ // LDY #imm + //^codeptr = ^(bytecode+i); codeptr++ fin - ^codeptr = $91; codeptr++ // STA (zp),Y - ^codeptr = $E0; codeptr++ // IFP + *codeptr = $E091 // STA (IFP),Y + codeptr = codeptr + 2 + //^codeptr = $91; codeptr++ // STA (zp),Y + //^codeptr = $E0; codeptr++ // IFP if ^(bytecode+i) <> 0 - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = $00; codeptr++ // $00 + *codeptr = $00A0 // LDY #$00 + codeptr = codeptr + 2 + //^codeptr = $A0; codeptr++ // LDY #imm + //^codeptr = $00; codeptr++ // $00 fin VX++ //^codeptr = $E8; codeptr++ // INX A_IS_TOSL = FALSE break - is $76 + is $76 // SLW i++ //puts("SLW "); puti(^(bytecode+i)) if not A_IS_TOSL @@ -1445,56 +1464,75 @@ def compiler(defptr)#0 codeptr = codeptr + 2 fin if ^(bytecode+i) <> 0 - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = ^(bytecode+i); codeptr++ + *codeptr = $A0+(^(bytecode+i)<<8) // LDY #imm + codeptr = codeptr + 2 + //^codeptr = $A0; codeptr++ // LDY #imm + //^codeptr = ^(bytecode+i); codeptr++ fin - ^codeptr = $91; codeptr++ // STA (zp),Y - ^codeptr = $E0; codeptr++ // IFP - ^codeptr = $C8; codeptr++ // INY - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH - ^codeptr = $91; codeptr++ // STA (zp),Y - ^codeptr = $E0; codeptr++ // IFP + codeptr=>0 = $E091 // STA (IFP),Y + //^codeptr = $91; codeptr++ // STA (zp),Y + //^codeptr = $E0; codeptr++ // IFP + codeptr->2 = $C8 // INY + //^codeptr = $C8; codeptr++ // INY + codeptr=>3 = $C0B5+(VX<<8) // LDA ESTKH,X + //^codeptr = $B5; codeptr++ // LDA zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr=>5 = $E091 // STA (IFP),Y + //^codeptr = $91; codeptr++ // STA (zp),Y + //^codeptr = $E0; codeptr++ // IFP if ^(bytecode+i) <> 0 - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = $00; codeptr++ // $00 + codeptr=>7 = $00A0 // LDY #$00 + codeptr = codeptr + 9 + //^codeptr = $A0; codeptr++ // LDY #imm + //^codeptr = $00; codeptr++ // $00 else - ^codeptr = $88; codeptr++ // DEY + codeptr->7 = $88 // DEY + codeptr = codeptr + 8 + //^codeptr = $88; codeptr++ // DEY fin - VX++ //^codeptr = $E8; codeptr++ // INX + VX++ // INX A_IS_TOSL = FALSE break - is $78 + is $78 // SAB i++ //puts("SAB $"); puth(*(bytecode+i)) if not A_IS_TOSL *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - ^codeptr = $8D; codeptr++ // STA abs - *codeptr = *(bytecode+i); codeptr = codeptr + 2 - VX++ //^codeptr = $E8; codeptr++ // INX + codeptr->0 = $8D // STA abs + codeptr=>1 = *(bytecode+i) + //^codeptr = $8D; codeptr++ // STA abs + //*codeptr = *(bytecode+i); codeptr = codeptr + 2 + VX++ // INX + codeptr = codeptr + 3 A_IS_TOSL = FALSE i++ break - is $7A + is $7A // SAW i++ //puts("SAW $"); puth(*(bytecode+i)) if not A_IS_TOSL *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - ^codeptr = $8D; codeptr++ // STA abs - *codeptr = *(bytecode+i); codeptr = codeptr + 2 - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH - ^codeptr = $8D; codeptr++ // STA abs - *codeptr = *(bytecode+i)+1; codeptr = codeptr + 2 + codeptr->0 = $8D // STA abs + codeptr=>1 = *(bytecode+i) + //^codeptr = $8D; codeptr++ // STA abs + //*codeptr = *(bytecode+i); codeptr = codeptr + 2 + codeptr=>3 = $C0B5+(VX<<8) // LDA ESTKH,X + //^codeptr = $B5; codeptr++ // LDA zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr->5 = $8D // STA abs + codeptr=>6 = *(bytecode+i)+1 + //^codeptr = $8D; codeptr++ // STA abs + //*codeptr = *(bytecode+i)+1; codeptr = codeptr + 2 VX++ //^codeptr = $E8; codeptr++ // INX + codeptr = codeptr + 8 A_IS_TOSL = FALSE i++ break - is $7C + is $7C // DAB i++ //puts("DAB $"); puth(*(bytecode+i)) if not A_IS_TOSL @@ -1502,11 +1540,14 @@ def compiler(defptr)#0 codeptr = codeptr + 2 A_IS_TOSL = TOSL_CLEAN fin - ^codeptr = $8D; codeptr++ // STA abs - *codeptr = *(bytecode+i); codeptr = codeptr + 2 + codeptr->0 = $8D // STA abs + codeptr=>1 = *(bytecode+i) + //^codeptr = $8D; codeptr++ // STA abs + //*codeptr = *(bytecode+i); codeptr = codeptr + 2 + codeptr = codeptr + 3 i++ break - is $7E + is $7E // DAW i++ //puts("DAW $"); puth(*(bytecode+i)) if not A_IS_TOSL @@ -1514,14 +1555,21 @@ def compiler(defptr)#0 codeptr = codeptr + 2 A_IS_TOSL = TOSL_CLEAN fin - ^codeptr = $8D; codeptr++ // STA abs - *codeptr = *(bytecode+i); codeptr = codeptr + 2 - ^codeptr = $B4; codeptr++ // LDY zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH - ^codeptr = $8C; codeptr++ // STY abs - *codeptr = *(bytecode+i)+1; codeptr = codeptr + 2 - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = $00; codeptr++ // $00 + codeptr->0 = $8D // STA abs + codeptr=>1 = *(bytecode+i) + //^codeptr = $8D; codeptr++ // STA abs + //*codeptr = *(bytecode+i); codeptr = codeptr + 2 + codeptr=>3 = $C0B4+(VX<<8) // LDY ESTKH,X + //^codeptr = $B4; codeptr++ // LDY zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr->5 = $8C // STY abs + codeptr=>7 = *(bytecode+i)+1 + //^codeptr = $8C; codeptr++ // STY abs + //*codeptr = *(bytecode+i)+1; codeptr = codeptr + 2 + codeptr=>9 = $00A0 // LDY #$00 + //^codeptr = $A0; codeptr++ // LDY #imm + //^codeptr = $00; codeptr++ // $00 + codeptr = codeptr + 11 i++ break // LNOT,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 80 82 84 86 88 8A 8C 8E From 9922127a41e6afeee691b8fcf568c742179377a9 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Sun, 25 Mar 2018 23:03:29 -0700 Subject: [PATCH 099/147] Updates ops $80-$8E --- src/libsrc/apple/jit.pla | 164 ++++++++++++++++++++++++--------------- 1 file changed, 100 insertions(+), 64 deletions(-) diff --git a/src/libsrc/apple/jit.pla b/src/libsrc/apple/jit.pla index 36fd32d..bee2bd4 100644 --- a/src/libsrc/apple/jit.pla +++ b/src/libsrc/apple/jit.pla @@ -1563,54 +1563,67 @@ def compiler(defptr)#0 //^codeptr = $B4; codeptr++ // LDY zp,X //^codeptr = $C0+VX; codeptr++ // ESTKH codeptr->5 = $8C // STY abs - codeptr=>7 = *(bytecode+i)+1 + codeptr=>6 = *(bytecode+i)+1 //^codeptr = $8C; codeptr++ // STY abs //*codeptr = *(bytecode+i)+1; codeptr = codeptr + 2 - codeptr=>9 = $00A0 // LDY #$00 + codeptr=>8 = $00A0 // LDY #$00 //^codeptr = $A0; codeptr++ // LDY #imm //^codeptr = $00; codeptr++ // $00 - codeptr = codeptr + 11 + codeptr = codeptr + 10 i++ break // LNOT,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 80 82 84 86 88 8A 8C 8E - is $80 + is $80 // NOT //puts("NOT") if not A_IS_TOSL *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - ^codeptr = $15; codeptr++ // ORA zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH - ^codeptr = $F0; codeptr++ // BEQ rel - ^codeptr = $02; codeptr++ // +2 - ^codeptr = $A9; codeptr++ // LDA #imm - ^codeptr = $FF; codeptr++ // $FF - ^codeptr = $49; codeptr++ // EOR #imm - ^codeptr = $FF; codeptr++ // $FF - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr=>0 = $C015+(VX<<8) // ORA ESTKH,X + //^codeptr = $15; codeptr++ // ORA zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr=>2 = $02F0 // BEQ +2 + //^codeptr = $F0; codeptr++ // BEQ rel + //^codeptr = $02; codeptr++ // +2 + codeptr=>4 = $FFA9 // LDA #$FF + //^codeptr = $A9; codeptr++ // LDA #imm + //^codeptr = $FF; codeptr++ // $FF + codeptr=>6 = $FF49 // EOR #$FF + //^codeptr = $49; codeptr++ // EOR #imm + //^codeptr = $FF; codeptr++ // $FF + codeptr=>8 = $C095+(VX<<8) // STA ESTKH,X + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL + codeptr = codeptr + 10 A_IS_TOSL = TOSL_DIRTY break - is $82 + is $82 // ADD //puts("ADD") if not A_IS_TOSL *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - ^codeptr = $18; codeptr++ // CLC - ^codeptr = $75; codeptr++ // ADC zp,X - ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH - ^codeptr = $75; codeptr++ // ADC zp,X - ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - VX++ //^codeptr = $E8; codeptr++ // INX + codeptr->0 = $18 // CLC + //^codeptr = $18; codeptr++ // CLC + codeptr=>1 = ($D075+$0100)+(VX<<8) // ADC ESTKL+1,X + //^codeptr = $75; codeptr++ // ADC zp,X + //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + codeptr=>3 = ($D095+$0100)+(VX<<8) // STA ESTKL+1,X + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + codeptr=>5 = $C085+(VX<<8) // LDA ESTKH,X + //^codeptr = $B5; codeptr++ // LDA zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr=>7 = ($C075+$0100)+(VX<<8) // ADC ESTKH+1,X + //^codeptr = $75; codeptr++ // ADC zp,X + //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + codeptr=>9 = ($C095+$0100)+(VX<<8) // STA ESTKH+1,X + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + VX++ // INX + codeptr = codeptr + 11 A_IS_TOSL = FALSE break is $84 @@ -1619,20 +1632,28 @@ def compiler(defptr)#0 *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - ^codeptr = $38; codeptr++ // SEC - ^codeptr = $F5; codeptr++ // SBC zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - ^codeptr = $F5; codeptr++ // SBC zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - VX++ //^codeptr = $E8; codeptr++ // INX + codeptr=>0 = ($D085+$0100)+(VX<<8) // LDA ESTKL+1,X + //^codeptr = $B5; codeptr++ // LDA zp,X + //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + codeptr->2 = $38 // SEC + //^codeptr = $38; codeptr++ // SEC + codeptr=>3 = $D0F5+(VX<<8) // SBC ESTKL,X + //^codeptr = $F5; codeptr++ // SBC zp,X + //^codeptr = $D0+VX; codeptr++ // ESTKL + codeptr=>5 = ($D095+$0100)+(VX<<8) // STA ESTKL+1,X + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + codeptr=>7 = ($C085+$0100)+(VX<<8) // LDA ESTKH+1,X + //^codeptr = $B5; codeptr++ // LDA zp,X + //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + codeptr=>9 = $C0F5+(VX<<8) // SBC ESTKH,X + //^codeptr = $F5; codeptr++ // SBC zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr=>11 = ($C095+$0100)+(VX<<8) // STA ESTKH+1,X + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + VX++ // INX + codeptr = codeptr + 13 A_IS_TOSL = FALSE break is $86 // MUL @@ -1661,46 +1682,61 @@ def compiler(defptr)#0 codeptr = codeptr + 2 fin codeptr, VX = resolveX(codeptr, VX) - ^codeptr = $20; codeptr++ // JSR INTERP - *codeptr = $3D0; codeptr = codeptr + 2 - ^codeptr = opcode; codeptr++ // OPCODE - ^codeptr = $C0; codeptr++ // NATV CODE - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = $00; codeptr++ // $00 + codeptr->0 = $20 // JSR INTERP + codeptr=>1 = $3D0 // INTERP + //^codeptr = $20; codeptr++ // JSR INTERP + //*codeptr = $3D0; codeptr = codeptr + 2 + codeptr=>3 = $C000+opcode // OPCODE; NATV CODE + //^codeptr = opcode; codeptr++ // OPCODE + //^codeptr = $C0; codeptr++ // NATV CODE + codeptr=>5 = $00A0 // LDY #$00 + //^codeptr = $A0; codeptr++ // LDY #imm + //^codeptr = $00; codeptr++ // $00 + codeptr = codeptr + 7 A_IS_TOSL = FALSE - break - is $8C + break + is $8C // INCR //puts("INCR") if not A_IS_TOSL *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - ^codeptr = $18; codeptr++ // CLC - ^codeptr = $69; codeptr++ // ADC #imm - ^codeptr = $01; codeptr++ // $01 - ^codeptr = $90; codeptr++ // BCC rel - ^codeptr = $02; codeptr++ // +2 - ^codeptr = $F6; codeptr++ // INC zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr->0 = $18 // CLC + //^codeptr = $18; codeptr++ // CLC + codeptr=>1 = $0169 // ADC #$01 + //^codeptr = $69; codeptr++ // ADC #imm + //^codeptr = $01; codeptr++ // $01 + codeptr=>3 = $0290 // BCC +2 + //^codeptr = $90; codeptr++ // BCC rel + //^codeptr = $02; codeptr++ // +2 + codeptr=>5 = $C0F6+(VX<<8) // INC ESTKH,X + //^codeptr = $F6; codeptr++ // INC zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL + codeptr = codeptr + 7 A_IS_TOSL = TOSL_DIRTY break - is $8E + is $8E // DECR //puts("DECR") if not A_IS_TOSL *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - ^codeptr = $38; codeptr++ // SEC - ^codeptr = $E9; codeptr++ // SBC #imm - ^codeptr = $01; codeptr++ // $01 - ^codeptr = $B0; codeptr++ // BCS rel - ^codeptr = $02; codeptr++ // +2 - ^codeptr = $D6; codeptr++ // DEC zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr->0 = $38 // SEC + //^codeptr = $38; codeptr++ // SEC + codeptr=>1 = $01E9 // SBC #$01 + //^codeptr = $E9; codeptr++ // SBC #imm + //^codeptr = $01; codeptr++ // $01 + codeptr=>3 = $02B0 // BCS +2 + //^codeptr = $B0; codeptr++ // BCS rel + //^codeptr = $02; codeptr++ // +2 + codeptr=>5 = $C0D6+(VX<<8) // DEC ESTKH,X + //^codeptr = $D6; codeptr++ // DEC zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL + codeptr = codeptr + 7 A_IS_TOSL = TOSL_DIRTY break // NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 90 92 94 96 98 9A 9C 9E From 4717e01862063a2df915198d2371c487552bad05 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Mon, 26 Mar 2018 06:58:44 -0700 Subject: [PATCH 100/147] Fix SUB typo --- src/libsrc/apple/jit.pla | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libsrc/apple/jit.pla b/src/libsrc/apple/jit.pla index bee2bd4..ca07d25 100644 --- a/src/libsrc/apple/jit.pla +++ b/src/libsrc/apple/jit.pla @@ -1632,7 +1632,7 @@ def compiler(defptr)#0 *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin - codeptr=>0 = ($D085+$0100)+(VX<<8) // LDA ESTKL+1,X + codeptr=>0 = ($D0B5+$0100)+(VX<<8) // LDA ESTKL+1,X //^codeptr = $B5; codeptr++ // LDA zp,X //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 codeptr->2 = $38 // SEC @@ -1643,7 +1643,7 @@ def compiler(defptr)#0 codeptr=>5 = ($D095+$0100)+(VX<<8) // STA ESTKL+1,X //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - codeptr=>7 = ($C085+$0100)+(VX<<8) // LDA ESTKH+1,X + codeptr=>7 = ($C0B5+$0100)+(VX<<8) // LDA ESTKH+1,X //^codeptr = $B5; codeptr++ // LDA zp,X //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 codeptr=>9 = $C0F5+(VX<<8) // SBC ESTKH,X From 15c779d63b91ea4b05f835aa7386bff2c684ecb9 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Mon, 26 Mar 2018 11:04:45 -0700 Subject: [PATCH 101/147] Update ops $90-$9E --- src/libsrc/apple/jit.pla | 382 +++++++++++++++++++++------------------ 1 file changed, 210 insertions(+), 172 deletions(-) diff --git a/src/libsrc/apple/jit.pla b/src/libsrc/apple/jit.pla index ca07d25..b99b141 100644 --- a/src/libsrc/apple/jit.pla +++ b/src/libsrc/apple/jit.pla @@ -191,7 +191,7 @@ def compiler(defptr)#0 // codeptr = *jitcodeptr VX = 0 // Virtual X register - A_IS_TOSL = FALSE + A_IS_TOSL = FALSE i = 0 if ^bytecode == $58 //puts("ENTER "); puti(^(bytecode+1)); //putc(',');puti(^(bytecode+2)) @@ -221,7 +221,7 @@ def compiler(defptr)#0 if A_IS_TOSL & TOSL_DIRTY *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 - A_IS_TOSL = FALSE + A_IS_TOSL = FALSE fin codeptr, VX = resolveX(codeptr, VX) opcode = opcode & $FE @@ -300,7 +300,7 @@ def compiler(defptr)#0 //^codeptr = $C0+VX; codeptr++ // ESTKH //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL - A_IS_TOSL = TOSL_DIRTY + A_IS_TOSL = TOSL_DIRTY break is $22 // BREQ i++ @@ -413,7 +413,7 @@ def compiler(defptr)#0 fin //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL - A_IS_TOSL = TOSL_DIRTY + A_IS_TOSL = TOSL_DIRTY i++ break is $28 // LLA @@ -518,18 +518,18 @@ def compiler(defptr)#0 is $30 // DROP //puts("DROP") VX++ // INX - A_IS_TOSL = FALSE + A_IS_TOSL = FALSE break is $34 // DUP //puts("DUP") - if A_IS_TOSL & TOSL_DIRTY - *codeptr = $D095+(VX<<8) // STA ESTKL,X - codeptr = codeptr + 2 - elsif not A_IS_TOSL + if not A_IS_TOSL *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 //^codeptr = $B5; codeptr++ // LDA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL + elsif A_IS_TOSL & TOSL_DIRTY + *codeptr = $D095+(VX<<8) // STA ESTKL,X + codeptr = codeptr + 2 fin VX-- // DEX codeptr=>0 = ($C0B4+$0100)+(VX<<8) // LDY ESTKH+1,X @@ -575,7 +575,7 @@ def compiler(defptr)#0 //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL codeptr = codeptr + 7 - A_IS_TOSL = TOSL_DIRTY + A_IS_TOSL = TOSL_DIRTY break is $3A // SUBI i++ @@ -598,7 +598,7 @@ def compiler(defptr)#0 //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL codeptr = codeptr + 7 - A_IS_TOSL = TOSL_DIRTY + A_IS_TOSL = TOSL_DIRTY break is $3C // ANDI i++ @@ -616,7 +616,7 @@ def compiler(defptr)#0 //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL codeptr = codeptr + 4 - A_IS_TOSL = TOSL_DIRTY + A_IS_TOSL = TOSL_DIRTY break is $3E // ORI i++ @@ -631,7 +631,7 @@ def compiler(defptr)#0 //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL codeptr = codeptr + 2 - A_IS_TOSL = TOSL_DIRTY + A_IS_TOSL = TOSL_DIRTY break // ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E is $40 // ISEQ @@ -667,8 +667,8 @@ def compiler(defptr)#0 VX++ // INX //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL - codeptr = codeptr + 16 - A_IS_TOSL = TOSL_DIRTY + codeptr = codeptr + 16 + A_IS_TOSL = TOSL_DIRTY break is $42 // ISNE //puts("ISNE") @@ -703,8 +703,8 @@ def compiler(defptr)#0 VX++ // INX //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL - codeptr = codeptr + 16 - A_IS_TOSL = TOSL_DIRTY + codeptr = codeptr + 16 + A_IS_TOSL = TOSL_DIRTY break is $44 // ISGT //puts("ISGT") @@ -742,8 +742,8 @@ def compiler(defptr)#0 VX++ // INX //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL - codeptr = codeptr + 18 - A_IS_TOSL = TOSL_DIRTY + codeptr = codeptr + 18 + A_IS_TOSL = TOSL_DIRTY break is $46 //puts("ISLT") @@ -784,8 +784,8 @@ def compiler(defptr)#0 VX++ // INX //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL - codeptr = codeptr + 20 - A_IS_TOSL = TOSL_DIRTY + codeptr = codeptr + 20 + A_IS_TOSL = TOSL_DIRTY break is $48 //puts("ISGE") @@ -826,8 +826,8 @@ def compiler(defptr)#0 VX++ // INX //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL - codeptr = codeptr + 20 - A_IS_TOSL = TOSL_DIRTY + codeptr = codeptr + 20 + A_IS_TOSL = TOSL_DIRTY break is $4A // ISLE //puts("ISLE") @@ -865,16 +865,15 @@ def compiler(defptr)#0 VX++ // INX //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL - codeptr = codeptr + 18 - A_IS_TOSL = TOSL_DIRTY + codeptr = codeptr + 18 + A_IS_TOSL = TOSL_DIRTY break is $4C // BRFLS i++ dest = i + *(bytecode+i) i++ //puts("BRFLS "); puti(dest) - //VX++ //^codeptr = $E8; codeptr++ // INX - codeptr, VX = resolveX(codeptr, VX + 1) + codeptr, VX = resolveX(codeptr, VX + 1) //VX++ // INX if not A_IS_TOSL *codeptr = ($D0B5-$0100)+(VX<<8) // LDA ESTKL-1,X codeptr = codeptr + 2 @@ -903,8 +902,7 @@ def compiler(defptr)#0 dest = i + *(bytecode+i) i++ //puts("BRTRU "); puti(dest) - //VX++ //^codeptr = $E8; codeptr++ // INX - codeptr, VX = resolveX(codeptr, VX + 1) + codeptr, VX = resolveX(codeptr, VX + 1) //VX++ // INX if not A_IS_TOSL *codeptr = ($D0B5-$0100)+(VX<<8) // LDA ESTKL-1,X codeptr = codeptr + 2 @@ -1044,8 +1042,8 @@ def compiler(defptr)#0 codeptr=>3 = $00A0 // LDY #$00 //^codeptr = $A0; codeptr++ // LDY #imm //^codeptr = $00; codeptr++ // $00 - codeptr = codeptr + 5 - A_IS_TOSL = FALSE + codeptr = codeptr + 5 + A_IS_TOSL = FALSE i++ break is $56 // ICAL @@ -1080,8 +1078,8 @@ def compiler(defptr)#0 codeptr=>3 = $00A0 // LDY #$00 //^codeptr = $A0; codeptr++ // LDY #imm //^codeptr = $00; codeptr++ // $00 - codeptr = codeptr + 5 - A_IS_TOSL = FALSE + codeptr = codeptr + 5 + A_IS_TOSL = FALSE break is $5A // LEAVE i++ @@ -1101,8 +1099,8 @@ def compiler(defptr)#0 codeptr=>3 = $5A + (^(bytecode+i)<<8) // LEAVE CODE AND OPERAND //^codeptr = $5A; codeptr++ // LEAVE CODE //^codeptr = ^(bytecode+i); codeptr++ // LEAVE OPERAND - codeptr = codeptr + 5 - A_IS_TOSL = FALSE + codeptr = codeptr + 5 + A_IS_TOSL = FALSE break is $5C // RET //puts("RET") @@ -1113,7 +1111,7 @@ def compiler(defptr)#0 codeptr, VX = resolveX(codeptr, VX) ^codeptr = $60 //RTS codeptr++ - A_IS_TOSL = FALSE + A_IS_TOSL = FALSE break is $5E // CFFB i++ @@ -1134,8 +1132,8 @@ def compiler(defptr)#0 //^codeptr = ^(bytecode+i); codeptr++ //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL - codeptr = codeptr + 6 - A_IS_TOSL = TOSL_DIRTY + codeptr = codeptr + 6 + A_IS_TOSL = TOSL_DIRTY break // LB,LW,LLB,LLW,LAB,LAW,DLB,DLW ; 60 62 64 66 68 6A 6C 6E is $60 // LB @@ -1155,8 +1153,8 @@ def compiler(defptr)#0 //^codeptr = $C0+VX; codeptr++ // ESTKH //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL - codeptr = codeptr + 6 - A_IS_TOSL = TOSL_DIRTY + codeptr = codeptr + 6 + A_IS_TOSL = TOSL_DIRTY break is $62 // LW //puts("LW") @@ -1188,8 +1186,8 @@ def compiler(defptr)#0 codeptr=>14 = $C095+(VX<<8) // STA ESTKH,X //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $C0+VX; codeptr++ // ESTKH - codeptr = codeptr + 16 - A_IS_TOSL = FALSE + codeptr = codeptr + 16 + A_IS_TOSL = FALSE break is $64 // LLB i++ @@ -1220,7 +1218,7 @@ def compiler(defptr)#0 //^codeptr = $C0+VX; codeptr++ // ESTKH //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL - codeptr = codeptr + 2 + codeptr = codeptr + 2 A_IS_TOSL = TOSL_DIRTY break is $66 // LLW @@ -1315,7 +1313,7 @@ def compiler(defptr)#0 if not A_IS_TOSL *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 - A_IS_TOSL = TOSL_CLEAN + A_IS_TOSL = TOSL_CLEAN fin if ^(bytecode+i) <> 0 *codeptr = $A0+(^(bytecode+i)<<8) // LDY #imm @@ -1370,7 +1368,7 @@ def compiler(defptr)#0 //^codeptr = $A0; codeptr++ // LDY #imm //^codeptr = $00; codeptr++ // $00 fin - A_IS_TOSL = TOSL_CLEAN + A_IS_TOSL = TOSL_CLEAN break // SB,SW,SLB,SLW,SAB,SAW,DAB,DAW ; 70 72 74 76 78 7A 7C 7E is $70 // SB @@ -1390,9 +1388,9 @@ def compiler(defptr)#0 //^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 //^codeptr = $E8; codeptr++ // INX //^codeptr = $E8; codeptr++ // INX + VX = VX + 2 // INX INX codeptr = codeptr + 6 - VX = VX + 2 - A_IS_TOSL = FALSE + A_IS_TOSL = FALSE break is $72 // SW //puts("SW") @@ -1426,9 +1424,9 @@ def compiler(defptr)#0 //^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 //^codeptr = $E8; codeptr++ // INX //^codeptr = $E8; codeptr++ // INX + VX = VX + 2 // INX INX codeptr = codeptr + 16 - VX = VX + 2 - A_IS_TOSL = FALSE + A_IS_TOSL = FALSE break is $74 // SLB i++ @@ -1453,8 +1451,8 @@ def compiler(defptr)#0 //^codeptr = $A0; codeptr++ // LDY #imm //^codeptr = $00; codeptr++ // $00 fin - VX++ //^codeptr = $E8; codeptr++ // INX - A_IS_TOSL = FALSE + VX++ // INX + A_IS_TOSL = FALSE break is $76 // SLW i++ @@ -1491,7 +1489,7 @@ def compiler(defptr)#0 //^codeptr = $88; codeptr++ // DEY fin VX++ // INX - A_IS_TOSL = FALSE + A_IS_TOSL = FALSE break is $78 // SAB i++ @@ -1506,7 +1504,7 @@ def compiler(defptr)#0 //*codeptr = *(bytecode+i); codeptr = codeptr + 2 VX++ // INX codeptr = codeptr + 3 - A_IS_TOSL = FALSE + A_IS_TOSL = FALSE i++ break is $7A // SAW @@ -1527,9 +1525,9 @@ def compiler(defptr)#0 codeptr=>6 = *(bytecode+i)+1 //^codeptr = $8D; codeptr++ // STA abs //*codeptr = *(bytecode+i)+1; codeptr = codeptr + 2 - VX++ //^codeptr = $E8; codeptr++ // INX + VX++ // INX codeptr = codeptr + 8 - A_IS_TOSL = FALSE + A_IS_TOSL = FALSE i++ break is $7C // DAB @@ -1538,7 +1536,7 @@ def compiler(defptr)#0 if not A_IS_TOSL *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 - A_IS_TOSL = TOSL_CLEAN + A_IS_TOSL = TOSL_CLEAN fin codeptr->0 = $8D // STA abs codeptr=>1 = *(bytecode+i) @@ -1553,7 +1551,7 @@ def compiler(defptr)#0 if not A_IS_TOSL *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 - A_IS_TOSL = TOSL_CLEAN + A_IS_TOSL = TOSL_CLEAN fin codeptr->0 = $8D // STA abs codeptr=>1 = *(bytecode+i) @@ -1597,7 +1595,7 @@ def compiler(defptr)#0 //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL codeptr = codeptr + 10 - A_IS_TOSL = TOSL_DIRTY + A_IS_TOSL = TOSL_DIRTY break is $82 // ADD //puts("ADD") @@ -1613,7 +1611,7 @@ def compiler(defptr)#0 codeptr=>3 = ($D095+$0100)+(VX<<8) // STA ESTKL+1,X //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - codeptr=>5 = $C085+(VX<<8) // LDA ESTKH,X + codeptr=>5 = $C0B5+(VX<<8) // LDA ESTKH,X //^codeptr = $B5; codeptr++ // LDA zp,X //^codeptr = $C0+VX; codeptr++ // ESTKH codeptr=>7 = ($C075+$0100)+(VX<<8) // ADC ESTKH+1,X @@ -1624,9 +1622,9 @@ def compiler(defptr)#0 //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 VX++ // INX codeptr = codeptr + 11 - A_IS_TOSL = FALSE + A_IS_TOSL = FALSE break - is $84 + is $84 // SUB //puts("SUB") if A_IS_TOSL & TOSL_DIRTY *codeptr = $D095+(VX<<8) // STA ESTKL,X @@ -1654,7 +1652,7 @@ def compiler(defptr)#0 //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 VX++ // INX codeptr = codeptr + 13 - A_IS_TOSL = FALSE + A_IS_TOSL = FALSE break is $86 // MUL is $88 // DIV @@ -1693,7 +1691,7 @@ def compiler(defptr)#0 //^codeptr = $A0; codeptr++ // LDY #imm //^codeptr = $00; codeptr++ // $00 codeptr = codeptr + 7 - A_IS_TOSL = FALSE + A_IS_TOSL = FALSE break is $8C // INCR //puts("INCR") @@ -1715,7 +1713,7 @@ def compiler(defptr)#0 //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL codeptr = codeptr + 7 - A_IS_TOSL = TOSL_DIRTY + A_IS_TOSL = TOSL_DIRTY break is $8E // DECR //puts("DECR") @@ -1737,127 +1735,167 @@ def compiler(defptr)#0 //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL codeptr = codeptr + 7 - A_IS_TOSL = TOSL_DIRTY + A_IS_TOSL = TOSL_DIRTY break // NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 90 92 94 96 98 9A 9C 9E - is $90 + is $90 // NEG //puts("NEG") if A_IS_TOSL & TOSL_DIRTY *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin - ^codeptr = $98; codeptr++ // TYA -> LDA #$00 - ^codeptr = $38; codeptr++ // SEC - ^codeptr = $F5; codeptr++ // SBC zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL - ^codeptr = $98; codeptr++ // TYA -> LDA #00 - ^codeptr = $F5; codeptr++ // SBC zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH - A_IS_TOSL = FALSE + codeptr=>0 = $3898 // TYA -> LDA #$00; SEC + //^codeptr = $98; codeptr++ // TYA -> LDA #$00 + //^codeptr = $38; codeptr++ // SEC + codeptr=>2 = $D0F5+(VX<<8) // SBC ESTKL,X + //^codeptr = $F5; codeptr++ // SBC zp,X + //^codeptr = $D0+VX; codeptr++ // ESTKL + codeptr=>4 = $D095+(VX<<8) // STA ESTKL,X + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $D0+VX; codeptr++ // ESTKL + codeptr->6 = $98 // TYA -> LDA #00 + //^codeptr = $98; codeptr++ // TYA -> LDA #00 + codeptr=>7 = $C0F5+(VX<<8) // SBC ESTKH,X + //^codeptr = $F5; codeptr++ // SBC zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr=>9 = $C095+(VX<<8) // STA ESTKH,X + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr = codeptr + 11 + A_IS_TOSL = FALSE break - is $92 + is $92 // COMP //puts("COMP") if not A_IS_TOSL *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - ^codeptr = $49; codeptr++ // EOR #imm - ^codeptr = $FF; codeptr++ // $FF - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH - ^codeptr = $49; codeptr++ // EOR #imm - ^codeptr = $FF; codeptr++ // $FF - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH - A_IS_TOSL = FALSE + codeptr=>0 = $FF49 // EOR #$FF + //^codeptr = $49; codeptr++ // EOR #imm + //^codeptr = $FF; codeptr++ // $FF + codeptr=>2 = $D095+(VX<<8) // STA ESTKL,X + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $D0+VX; codeptr++ // ESTKL + codeptr=>4 = $C0B5+(VX<<8) // LDA ESTKH,X + //^codeptr = $B5; codeptr++ // LDA zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr=>6 = $FF49 // EOR #$FF + //^codeptr = $49; codeptr++ // EOR #imm + //^codeptr = $FF; codeptr++ // $FF + codeptr=>8 = $C095+(VX<<8) // STA ESTKH,X + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr = codeptr + 10 + A_IS_TOSL = FALSE break - is $94 + is $94 // AND //puts("AND") if not A_IS_TOSL *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - ^codeptr = $35; codeptr++ // AND zp,X - ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH - ^codeptr = $35; codeptr++ // AND zp,X - ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - VX++ //^codeptr = $E8; codeptr++ // INX - A_IS_TOSL = FALSE + codeptr=>0 = ($D035+$0100)+(VX<<8) // AND ESTKL+1,X + //^codeptr = $35; codeptr++ // AND zp,X + //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + codeptr=>2 = ($D095+$0100)+(VX<<8) // STA ESTKL+1,X + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + codeptr=>4 = $C0B5+(VX<<8) // LDA ESTKH,X + //^codeptr = $B5; codeptr++ // LDA zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr=>6 = ($C035+$0100)+(VX<<8) // AND ESTKH+1,X + //^codeptr = $35; codeptr++ // AND zp,X + //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + codeptr=>8 = ($C095+$0100)+(VX<<8) // STA ESTKH+1,X + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + VX++ // INX + codeptr = codeptr + 10 + A_IS_TOSL = FALSE break - is $96 + is $96 // OR //puts("OR") if not A_IS_TOSL *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - ^codeptr = $15; codeptr++ // ORA zp,X - ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH - ^codeptr = $15; codeptr++ // ORA zp,X - ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - VX++ //^codeptr = $E8; codeptr++ // INX - A_IS_TOSL = FALSE + codeptr=>0 = ($D015+$0100)+(VX<<8) // ORA ESTKL+1,X + //^codeptr = $15; codeptr++ // ORA zp,X + //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + codeptr=>2 = ($D095+$0100)+(VX<<8) // STA ESTKL+1,X + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + codeptr=>4 = $C0B5+(VX<<8) // LDA ESTKH,X + //^codeptr = $B5; codeptr++ // LDA zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr=>6 = ($C015+$0100)+(VX<<8) // ORA ESTKH+1,X + //^codeptr = $15; codeptr++ // ORA zp,X + //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + codeptr=>8 = ($C095+$0100)+(VX<<8) // STA ESTKH+1,X + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + VX++ // INX + codeptr = codeptr + 10 + A_IS_TOSL = FALSE break - is $98 + is $98 // XOR //puts("XOR") if not A_IS_TOSL *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - ^codeptr = $55; codeptr++ // EOR zp,X - ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH - ^codeptr = $55; codeptr++ // EOR zp,X - ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - VX++ //^codeptr = $E8; codeptr++ // INX - A_IS_TOSL = FALSE + codeptr=>0 = ($D055+$0100)+(VX<<8) // EOR ESTKL+1,X + //^codeptr = $55; codeptr++ // EOR zp,X + //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + codeptr=>2 = ($D095+$0100)+(VX<<8) // STA ESTKL+1,X + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + codeptr=>4 = $C0B5+(VX<<8) // LDA ESTKH,X + //^codeptr = $B5; codeptr++ // LDA zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr=>6 = ($C055+$0100)+(VX<<8) // EOR ESTKH+1,X + //^codeptr = $55; codeptr++ // EOR zp,X + //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + codeptr=>8 = ($C095+$0100)+(VX<<8) // STA ESTKH+1,X + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + VX++ // INX + codeptr = codeptr + 10 + A_IS_TOSL = FALSE break - is $9E + is $9E // IDXW //puts("IDXW") if not A_IS_TOSL *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - ^codeptr = $0A; codeptr++ // ASL - ^codeptr = $36; codeptr++ // ROL zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH - ^codeptr = $18; codeptr++ // CLC - ^codeptr = $75; codeptr++ // ADC zp,X - ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH - ^codeptr = $75; codeptr++ // ADC zp,X - ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - VX++ //^codeptr = $E8; codeptr++ // INX - A_IS_TOSL = FALSE + codeptr->0 = $0A // ASL + //^codeptr = $0A; codeptr++ // ASL + codeptr=>1 = $C036+(VX<<8) // ROL ESTKH,X + //^codeptr = $36; codeptr++ // ROL zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr->3 = $18 // CLC + //^codeptr = $18; codeptr++ // CLC + codeptr=>4 = ($D075+$0100)+(VX<<8) // ADC ESTKL+1,X + //^codeptr = $75; codeptr++ // ADC zp,X + //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + codeptr=>6 = ($D095+$0100)+(VX<<8) // STA ESTKL+1,X + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + codeptr=>8 = $C0B5+(VX<<8) // LDA ESTKH,X + //^codeptr = $B5; codeptr++ // LDA zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr=>10 = ($C075+$0100)+(VX<<8) // ADC ESTKH+1,X + //^codeptr = $75; codeptr++ // ADC zp,X + //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + codeptr=>12 = ($C095+$0100)+(VX<<8) // STA ESTKH+1,X + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + VX++ // INX + codeptr = codeptr + 14 + A_IS_TOSL = FALSE break - // BRGT,BRLT,INCBRLE,ADDBRLE,DECBRGE,SUBBRGE,BRAND,BROR ; A0 A2 A4 A6 A8 AA AC AE + // BRGT,BRLT,INCBRLE,ADDBRLE,DECBRGE,SUBBRGE,BRAND,BROR ; A0 A2 A4 A6 A8 AA AC AE is $A0 i++ dest = i + *(bytecode+i) @@ -1890,7 +1928,7 @@ def compiler(defptr)#0 addrxlate=>[dest] = codeptr - *jitcodeptr fin codeptr = codeptr + 2 - A_IS_TOSL = FALSE + A_IS_TOSL = FALSE break is $A2 i++ @@ -1901,7 +1939,7 @@ def compiler(defptr)#0 if not A_IS_TOSL *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 - else + elsif A_IS_TOSL & TOSL_DIRTY ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL fin @@ -1925,7 +1963,7 @@ def compiler(defptr)#0 addrxlate=>[dest] = codeptr - *jitcodeptr fin codeptr = codeptr + 2 - A_IS_TOSL = FALSE + A_IS_TOSL = FALSE break is $A4 i++ @@ -1974,7 +2012,7 @@ def compiler(defptr)#0 codeptr = codeptr + 2 ^codeptr = $E8; codeptr++ // INX ^codeptr = $E8; codeptr++ // INX - A_IS_TOSL = FALSE + A_IS_TOSL = FALSE break is $A6 i++ @@ -2026,7 +2064,7 @@ def compiler(defptr)#0 codeptr = codeptr + 2 ^codeptr = $E8; codeptr++ // INX ^codeptr = $E8; codeptr++ // INX - A_IS_TOSL = FALSE + A_IS_TOSL = FALSE break is $A8 i++ @@ -2075,7 +2113,7 @@ def compiler(defptr)#0 codeptr = codeptr + 2 ^codeptr = $E8; codeptr++ // INX ^codeptr = $E8; codeptr++ // INX - A_IS_TOSL = FALSE + A_IS_TOSL = FALSE break is $AA i++ @@ -2129,7 +2167,7 @@ def compiler(defptr)#0 codeptr = codeptr + 2 ^codeptr = $E8; codeptr++ // INX ^codeptr = $E8; codeptr++ // INX - A_IS_TOSL = FALSE + A_IS_TOSL = FALSE break is $AC i++ @@ -2137,12 +2175,12 @@ def compiler(defptr)#0 i++ //puts("BRAND "); puti(dest) codeptr, VX = resolveX(codeptr, VX) - if A_IS_TOSL & TOSL_DIRTY - *codeptr = $D095+(VX<<8) // STA ESTKL,X - codeptr = codeptr + 2 - else + if not A_IS_TOSL ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL + elsif A_IS_TOSL & TOSL_DIRTY + *codeptr = $D095+(VX<<8) // STA ESTKL,X + codeptr = codeptr + 2 fin ^codeptr = $15; codeptr++ // ORA zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH @@ -2155,7 +2193,7 @@ def compiler(defptr)#0 fin codeptr = codeptr + 2 ^codeptr = $E8; codeptr++ // INX VX++ ??? - A_IS_TOSL = FALSE + A_IS_TOSL = FALSE break is $AE i++ @@ -2163,12 +2201,12 @@ def compiler(defptr)#0 i++ //puts("BROR "); puti(dest) codeptr, VX = resolveX(codeptr, VX) - if A_IS_TOSL & TOSL_DIRTY - *codeptr = $D095+(VX<<8) // STA ESTKL,X - codeptr = codeptr + 2 - else + if not A_IS_TOSL ^codeptr = $B5; codeptr++ // LDA zp,X ^codeptr = $D0+VX; codeptr++ // ESTKL + elsif A_IS_TOSL & TOSL_DIRTY + *codeptr = $D095+(VX<<8) // STA ESTKL,X + codeptr = codeptr + 2 fin ^codeptr = $15; codeptr++ // ORA zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH @@ -2181,7 +2219,7 @@ def compiler(defptr)#0 fin codeptr = codeptr + 2 ^codeptr = $E8; codeptr++ // INX // VX++ ??? - A_IS_TOSL = FALSE + A_IS_TOSL = FALSE break // ADDLB,ADDLW,ADDAB,ADDAW,IDXLB,IDXLW,IDXAB,IDXAW ; B0 B2 B4 B6 B8 BA BC BE is $B0 @@ -2208,7 +2246,7 @@ def compiler(defptr)#0 fin //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL - A_IS_TOSL = TOSL_DIRTY + A_IS_TOSL = TOSL_DIRTY break is $B2 i++ @@ -2239,7 +2277,7 @@ def compiler(defptr)#0 else ^codeptr = $88; codeptr++ // DEY fin - A_IS_TOSL = FALSE + A_IS_TOSL = FALSE break is $B4 i++ @@ -2257,7 +2295,7 @@ def compiler(defptr)#0 ^codeptr = $C0+VX; codeptr++ // ESTKH //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL - A_IS_TOSL = TOSL_DIRTY + A_IS_TOSL = TOSL_DIRTY i++ break is $B6 @@ -2278,7 +2316,7 @@ def compiler(defptr)#0 *codeptr = *(bytecode+i)+1; codeptr = codeptr + 2 ^codeptr = $95; codeptr++ // STA zp,X ^codeptr = $C0+VX; codeptr++ // ESTKH - A_IS_TOSL = FALSE + A_IS_TOSL = FALSE i++ break is $B8 @@ -2314,7 +2352,7 @@ def compiler(defptr)#0 ^codeptr = $C0+VX; codeptr++ // ESTKH ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = $00; codeptr++ // $00 - A_IS_TOSL = FALSE + A_IS_TOSL = FALSE break is $BA i++ @@ -2351,7 +2389,7 @@ def compiler(defptr)#0 ^codeptr = $C0+VX; codeptr++ // ESTKH ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = $00; codeptr++ // $00 - A_IS_TOSL = FALSE + A_IS_TOSL = FALSE break is $BC i++ @@ -2378,7 +2416,7 @@ def compiler(defptr)#0 ^codeptr = $C0+VX; codeptr++ // ESTKH ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = $00; codeptr++ // $00 - A_IS_TOSL = FALSE + A_IS_TOSL = FALSE i++ break is $BE @@ -2411,7 +2449,7 @@ def compiler(defptr)#0 ^codeptr = $C0+VX; codeptr++ // ESTKH ^codeptr = $A0; codeptr++ // LDY #imm ^codeptr = $00; codeptr++ // $00 - A_IS_TOSL = FALSE + A_IS_TOSL = FALSE i++ break is $FE // NOPed out earlier by SELect From 818a2b14eaff8fc467aa86aeda73f92e2590bdf8 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Mon, 26 Mar 2018 16:51:09 -0700 Subject: [PATCH 102/147] Update ops $A0-$AE --- src/libsrc/apple/jit.pla | 525 ++++++++++++++++++++++++--------------- 1 file changed, 319 insertions(+), 206 deletions(-) diff --git a/src/libsrc/apple/jit.pla b/src/libsrc/apple/jit.pla index b99b141..2d8b8db 100644 --- a/src/libsrc/apple/jit.pla +++ b/src/libsrc/apple/jit.pla @@ -1896,7 +1896,7 @@ def compiler(defptr)#0 A_IS_TOSL = FALSE break // BRGT,BRLT,INCBRLE,ADDBRLE,DECBRGE,SUBBRGE,BRAND,BROR ; A0 A2 A4 A6 A8 AA AC AE - is $A0 + is $A0 // BRGT - FOR/NEXT SPECIFIC TEST & BRANCH i++ dest = i + *(bytecode+i) //puts("BRGT "); puti(dest) @@ -1906,31 +1906,44 @@ def compiler(defptr)#0 *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - ^codeptr = $D5; codeptr++ // CMP zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - ^codeptr = $F5; codeptr++ // SBC zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH - ^codeptr = $50; codeptr++ // BVC rel - ^codeptr = $02; codeptr++ // +2 - ^codeptr = $49; codeptr++ // EOR #imm - ^codeptr = $80; codeptr++ // $80 - ^codeptr = $10; codeptr++ // BPL rel - ^codeptr = $05; codeptr++ // +5 - ^codeptr = $E8; codeptr++ // INX - ^codeptr = $E8; codeptr++ // INX - ^codeptr = $4C; codeptr++ // JMP abs - *codeptr = addrxlate=>[dest] - if not (*codeptr & $8000) // Unresolved address list - addrxlate=>[dest] = codeptr - *jitcodeptr + codeptr=>0 = ($D0B5+$0100)+(VX<<8) // LDA ESTKL+1,X + //^codeptr = $B5; codeptr++ // LDA zp,X + //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + codeptr=>2 = $D0D5+(VX<<8) // CMP ESTKL,X + //^codeptr = $D5; codeptr++ // CMP zp,X + //^codeptr = $D0+VX; codeptr++ // ESTKL + codeptr=>4 = ($C0B5+$0100)+(VX<<8) // LDA ESTKH+1,X + //^codeptr = $B5; codeptr++ // LDA zp,X + //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + codeptr=>6 = $C0F5+(VX<<8) // SBC ESTKH + //^codeptr = $F5; codeptr++ // SBC zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr=>8 = $0250 // BVC +2 + //^codeptr = $50; codeptr++ // BVC rel + //^codeptr = $02; codeptr++ // +2 + codeptr=>10 = $8049 // EOR #$80 + //^codeptr = $49; codeptr++ // EOR #imm + //^codeptr = $80; codeptr++ // $80 + codeptr=>12 = $0510 // BPL +5 + //^codeptr = $10; codeptr++ // BPL rel + //^codeptr = $05; codeptr++ // +5 + codeptr=>14 = $E8E8 // INX; INX + //^codeptr = $E8; codeptr++ // INX + //^codeptr = $E8; codeptr++ // INX + codeptr->16 = $4C // JMP abs + //^codeptr = $4C; codeptr++ // JMP abs + codeptr=>17 = addrxlate=>[dest] + //*codeptr = addrxlate=>[dest] + if not (codeptr->18 & $80) // Unresolved address list + //if not (*codeptr & $8000) // Unresolved address list + addrxlate=>[dest] = codeptr + 17 - *jitcodeptr + //addrxlate=>[dest] = codeptr - *jitcodeptr fin - codeptr = codeptr + 2 - A_IS_TOSL = FALSE + codeptr = codeptr + 19 + //codeptr = codeptr + 2 + A_IS_TOSL = FALSE break - is $A2 + is $A2 // BRLT - FOR/NEXT SPECIFIC TEST & BRANCH i++ dest = i + *(bytecode+i) //puts("BRLT "); puti(dest) @@ -1940,32 +1953,46 @@ def compiler(defptr)#0 *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 elsif A_IS_TOSL & TOSL_DIRTY - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D095+(VX<<8) // STA ESTKL,X + codeptr = codeptr + 2 + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $D0+VX; codeptr++ // ESTKL fin - ^codeptr = $D5; codeptr++ // CMP zp,X - ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH - ^codeptr = $F5; codeptr++ // SBC zp,X - ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - ^codeptr = $50; codeptr++ // BVC rel - ^codeptr = $02; codeptr++ // +2 - ^codeptr = $49; codeptr++ // EOR #imm - ^codeptr = $80; codeptr++ // $80 - ^codeptr = $10; codeptr++ // BPL rel - ^codeptr = $05; codeptr++ // +5 - ^codeptr = $E8; codeptr++ // INX - ^codeptr = $E8; codeptr++ // INX - ^codeptr = $4C; codeptr++ // JMP abs - *codeptr = addrxlate=>[dest] - if not (*codeptr & $8000) // Unresolved address list - addrxlate=>[dest] = codeptr - *jitcodeptr + codeptr=>0 = ($D0D5+$0100)+(VX<<8) // CMP ESTKL+1,X + //^codeptr = $D5; codeptr++ // CMP zp,X + //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + codeptr=>2 = $C0B5+(VX<<8) // LDA ESTKH,X + //^codeptr = $B5; codeptr++ // LDA zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr=>4 = ($C0F5+$0100)+(VX<<8) // SBC ESTKH+1 + //^codeptr = $F5; codeptr++ // SBC zp,X + //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + codeptr=>6 = $0250 // BVC +2 + //^codeptr = $50; codeptr++ // BVC rel + //^codeptr = $02; codeptr++ // +2 + codeptr=>8 = $8049 // EOR #$80 + //^codeptr = $49; codeptr++ // EOR #imm + //^codeptr = $80; codeptr++ // $80 + codeptr=>10 = $0510 // BPL +5 + //^codeptr = $10; codeptr++ // BPL rel + //^codeptr = $05; codeptr++ // +5 + codeptr=>12 = $E8E8 // INX; INX + //^codeptr = $E8; codeptr++ // INX + //^codeptr = $E8; codeptr++ // INX + codeptr->14 = $4C // JMP abs + //^codeptr = $4C; codeptr++ // JMP abs + codeptr=>15 = addrxlate=>[dest] + //*codeptr = addrxlate=>[dest] + if not (codeptr->16 & $80) // Unresolved address list + //if not (*codeptr & $8000) // Unresolved address list + addrxlate=>[dest] = codeptr + 15 - *jitcodeptr + //addrxlate=>[dest] = codeptr - *jitcodeptr fin - codeptr = codeptr + 2 - A_IS_TOSL = FALSE + codeptr = codeptr + 17 + //codeptr = codeptr + 2 + A_IS_TOSL = FALSE break - is $A4 + is $A4 // INCBRLE - FOR/NEXT SPECIFIC INC & TEST & BRANCH i++ dest = i + *(bytecode+i) //puts("INCBRLE "); puti(dest) @@ -1977,44 +2004,62 @@ def compiler(defptr)#0 *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - ^codeptr = $18; codeptr++ // CLC - ^codeptr = $69; codeptr++ // ADC #imm - ^codeptr = $01; codeptr++ // $01 - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL - ^codeptr = $90; codeptr++ // BCC rel - ^codeptr = $02; codeptr++ // +2 - ^codeptr = $F6; codeptr++ // INC zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr->0 = $18 // CLC + //^codeptr = $18; codeptr++ // CLC + codeptr=>1 = $0169 // ADC #$01 + //^codeptr = $69; codeptr++ // ADC #imm + //^codeptr = $01; codeptr++ // $01 + codeptr=>3 = $D095+(VX<<8) // STA ESTKL,X + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $D0+VX; codeptr++ // ESTKL + codeptr=>5 = $0290 // BCC +2 + //^codeptr = $90; codeptr++ // BCC rel + //^codeptr = $02; codeptr++ // +2 + codeptr=>7 = $C0F6+(VX<<8) // INC ESTKH,X + //^codeptr = $F6; codeptr++ // INC zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr, VX = resolveX(codeptr + 9, VX) // // BRLE // - codeptr, VX = resolveX(codeptr, VX) - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - ^codeptr = $D5; codeptr++ // CMP zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - ^codeptr = $F5; codeptr++ // SBC zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH - ^codeptr = $50; codeptr++ // BVC rel - ^codeptr = $02; codeptr++ // +2 - ^codeptr = $49; codeptr++ // EOR #imm - ^codeptr = $80; codeptr++ // $80 - ^codeptr = $30; codeptr++ // BMI rel - ^codeptr = $03; codeptr++ // +3 - ^codeptr = $4C; codeptr++ // JMP abs - *codeptr = addrxlate=>[dest] - if not (*codeptr & $8000) // Unresolved address list - addrxlate=>[dest] = codeptr - *jitcodeptr + codeptr=>0 = ($D0B5+$0100)+(VX<<8) // LDA ESTKL+1,X + //^codeptr = $B5; codeptr++ // LDA zp,X + //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + codeptr=>2 = $D0D5+(VX<<8) // CMP ESTKL,X + //^codeptr = $D5; codeptr++ // CMP zp,X + //^codeptr = $D0+VX; codeptr++ // ESTKL + codeptr=>4 = ($C0B5+$0100)+(VX<<8) // LDA ESTKH+1,X + //^codeptr = $B5; codeptr++ // LDA zp,X + //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + codeptr=>6 = $C0F5+(VX<<8) // SBC ESTKH + //^codeptr = $F5; codeptr++ // SBC zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr=>8 = $0250 // BVC +2 + //^codeptr = $50; codeptr++ // BVC rel + //^codeptr = $02; codeptr++ // +2 + codeptr=>10 = $8049 // EOR #$80 + //^codeptr = $49; codeptr++ // EOR #imm + //^codeptr = $80; codeptr++ // $80 + codeptr=>12 = $0330 // BMI +3 + //^codeptr = $30; codeptr++ // BMI rel + //^codeptr = $03; codeptr++ // +3 + codeptr->14 = $4C // JMP abs + //^codeptr = $4C; codeptr++ // JMP abs + codeptr=>15 = addrxlate=>[dest] + //*codeptr = addrxlate=>[dest] + if not (codeptr->16 & $80) // Unresolved address list + //if not (*codeptr & $8000) // Unresolved address list + addrxlate=>[dest] = codeptr + 15 - *jitcodeptr + //addrxlate=>[dest] = codeptr - *jitcodeptr fin - codeptr = codeptr + 2 - ^codeptr = $E8; codeptr++ // INX - ^codeptr = $E8; codeptr++ // INX + //codeptr = codeptr + 2 + codeptr=>17 = $E8E8 // INX; INX + //^codeptr = $E8; codeptr++ // INX + //^codeptr = $E8; codeptr++ // INX + codeptr = codeptr + 19 A_IS_TOSL = FALSE break - is $A6 + is $A6 // ADDBRLE - FOR/NEXT SPECIFIC ADD & TEST & BRANCH i++ dest = i + *(bytecode+i) //puts("ADDBRLE "); puti(dest) @@ -2026,47 +2071,65 @@ def compiler(defptr)#0 *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - ^codeptr = $18; codeptr++ // CLC - ^codeptr = $75; codeptr++ // ADC zp,X - ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH - ^codeptr = $75; codeptr++ // ADC zp,X - ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - //VX++ //^codeptr = $E8; codeptr++ // INX + codeptr->0 = $18 // CLC + //^codeptr = $18; codeptr++ // CLC + codeptr=>1 = ($D075+$0100)+(VX<<8) // ADC ESTKL+1,X + //^codeptr = $75; codeptr++ // ADC zp,X + //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + codeptr=>3 = ($D095+$0100)+(VX<<8) // STA ESTKL+1,X + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + codeptr=>5 = $C0B5+(VX<<8) // LDA ESTKH,X + //^codeptr = $B5; codeptr++ // LDA zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr=>7 = ($C075+$0100)+(VX<<8) // ADC ESTKH+1,X + //^codeptr = $75; codeptr++ // ADC zp,X + //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + codeptr=>9 = ($C095+$0100)+(VX<<8) // STA ESTKH+1,X + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + codeptr, VX = resolveX(codeptr + 11, VX + 1) //VX++ // INX // // BRLE // - codeptr, VX = resolveX(codeptr, VX + 1) - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - ^codeptr = $D5; codeptr++ // CMP zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - ^codeptr = $F5; codeptr++ // SBC zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH - ^codeptr = $50; codeptr++ // BVC rel - ^codeptr = $02; codeptr++ // +2 - ^codeptr = $49; codeptr++ // EOR #imm - ^codeptr = $80; codeptr++ // $80 - ^codeptr = $30; codeptr++ // BMI rel - ^codeptr = $03; codeptr++ // +3 - ^codeptr = $4C; codeptr++ // JMP abs - *codeptr = addrxlate=>[dest] - if not (*codeptr & $8000) // Unresolved address list - addrxlate=>[dest] = codeptr - *jitcodeptr + codeptr=>0 = ($D0B5+$0100)+(VX<<8) // LDA ESTKL+1,X + //^codeptr = $B5; codeptr++ // LDA zp,X + //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + codeptr=>2 = $D0D5+(VX<<8) // CMP ESTKL,X + //^codeptr = $D5; codeptr++ // CMP zp,X + //^codeptr = $D0+VX; codeptr++ // ESTKL + codeptr=>4 = ($C0B5+$0100)+(VX<<8) // LDA ESTKH+1,X + //^codeptr = $B5; codeptr++ // LDA zp,X + //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + codeptr=>6 = $C0F5+(VX<<8) // SBC ESTKH + //^codeptr = $F5; codeptr++ // SBC zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr=>8 = $0250 // BVC +2 + //^codeptr = $50; codeptr++ // BVC rel + //^codeptr = $02; codeptr++ // +2 + codeptr=>10 = $8049 // EOR #$80 + //^codeptr = $49; codeptr++ // EOR #imm + //^codeptr = $80; codeptr++ // $80 + codeptr=>12 = $0330 // BMI +3 + //^codeptr = $30; codeptr++ // BMI rel + //^codeptr = $03; codeptr++ // +3 + codeptr->14 = $4C // JMP abs + //^codeptr = $4C; codeptr++ // JMP abs + codeptr=>15 = addrxlate=>[dest] + //*codeptr = addrxlate=>[dest] + if not (codeptr->16 & $80) // Unresolved address list + //if not (*codeptr & $8000) // Unresolved address list + addrxlate=>[dest] = codeptr + 15 - *jitcodeptr + //addrxlate=>[dest] = codeptr - *jitcodeptr fin - codeptr = codeptr + 2 - ^codeptr = $E8; codeptr++ // INX - ^codeptr = $E8; codeptr++ // INX + //codeptr = codeptr + 2 + codeptr=>17 = $E8E8 // INX; INX + //^codeptr = $E8; codeptr++ // INX + //^codeptr = $E8; codeptr++ // INX + codeptr = codeptr + 19 A_IS_TOSL = FALSE break - is $A8 + is $A8 // DECBRGR - FOR/NEXT SPECIFIC DEC & TEST & BRANCH i++ dest = i + *(bytecode+i) //puts("DECBRGE "); puti(dest) @@ -2078,44 +2141,61 @@ def compiler(defptr)#0 *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - ^codeptr = $38; codeptr++ // SEC - ^codeptr = $E9; codeptr++ // SBC #imm - ^codeptr = $01; codeptr++ // $01 - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL - ^codeptr = $B0; codeptr++ // BCS rel - ^codeptr = $02; codeptr++ // +2 - ^codeptr = $D6; codeptr++ // DEC zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr->0 = $38 // SEC + //^codeptr = $38; codeptr++ // SEC + codeptr=>1 = $01E9 // SBC #$01 + //^codeptr = $E9; codeptr++ // SBC #imm + //^codeptr = $01; codeptr++ // $01 + codeptr=>3 = $D095+(VX<<8) // STA ESTKL,X + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $D0+VX; codeptr++ // ESTKL + codeptr=>5 = $02B0 // BCS +2 + //^codeptr = $B0; codeptr++ // BCS rel + //^codeptr = $02; codeptr++ // +2 + codeptr=>7 = $C0D6+(VX<<8) // DEC ESTKH,X + //^codeptr = $D6; codeptr++ // DEC zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr, VX = resolveX(codeptr + 9, VX) // // BRGE // - codeptr, VX = resolveX(codeptr, VX) //^codeptr = $B5; codeptr++ // LDA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL - ^codeptr = $D5; codeptr++ // CMP zp,X - ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH - ^codeptr = $F5; codeptr++ // SBC zp,X - ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - ^codeptr = $50; codeptr++ // BVC rel - ^codeptr = $02; codeptr++ // +2 - ^codeptr = $49; codeptr++ // EOR #imm - ^codeptr = $80; codeptr++ // $80 - ^codeptr = $30; codeptr++ // BMI rel - ^codeptr = $03; codeptr++ // +3 - ^codeptr = $4C; codeptr++ // JMP abs - *codeptr = addrxlate=>[dest] - if not (*codeptr & $8000) // Unresolved address list - addrxlate=>[dest] = codeptr - *jitcodeptr + codeptr=>0 = ($D0D5+$0100)+(VX<<8) // CMP ESTKL+1,X + //^codeptr = $D5; codeptr++ // CMP zp,X + //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + codeptr=>2 = $C0B5+(VX<<8) // LDA ESTKH,X + //^codeptr = $B5; codeptr++ // LDA zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr=>4 = ($C0F5+$0100)+(VX<<8) // SBC ESTKH+1,X + //^codeptr = $F5; codeptr++ // SBC zp,X + //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + codeptr=>6 = $0250 // BVC +2 + //^codeptr = $50; codeptr++ // BVC rel + //^codeptr = $02; codeptr++ // +2 + codeptr=>8 = $8049 // EOR #$80 + //^codeptr = $49; codeptr++ // EOR #imm + //^codeptr = $80; codeptr++ // $80 + codeptr=>10 = $0330 // BMI +3 + //^codeptr = $30; codeptr++ // BMI rel + //^codeptr = $03; codeptr++ // +3 + codeptr->12 = $4C // JMP abs + //^codeptr = $4C; codeptr++ // JMP abs + codeptr=>13 = addrxlate=>[dest] + //*codeptr = addrxlate=>[dest] + if not (codeptr->14 & $80) // Unresolved address list + //if not (*codeptr & $8000) // Unresolved address list + addrxlate=>[dest] = codeptr + 13 - *jitcodeptr + //addrxlate=>[dest] = codeptr - *jitcodeptr fin - codeptr = codeptr + 2 - ^codeptr = $E8; codeptr++ // INX - ^codeptr = $E8; codeptr++ // INX + //codeptr = codeptr + 2 + codeptr=>15 = $E8E8 // INX; INX + //^codeptr = $E8; codeptr++ // INX + //^codeptr = $E8; codeptr++ // INX + codeptr = codeptr + 17 A_IS_TOSL = FALSE break - is $AA + is $AA // SUBBRGE - FOR/NEXT SPECIFIC SUB & TEST & BRANCH i++ dest = i + *(bytecode+i) //puts("SUBBRGE "); puti(dest) @@ -2127,98 +2207,131 @@ def compiler(defptr)#0 *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - ^codeptr = $38; codeptr++ // SEC - ^codeptr = $F5; codeptr++ // SBC zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - ^codeptr = $F5; codeptr++ // SBC zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - //VX++ //^codeptr = $E8; codeptr++ // INX + codeptr=>0 = ($D0B5+$0100)+(VX<<8) // LDA ESTKL+1,X + //^codeptr = $B5; codeptr++ // LDA zp,X + //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + codeptr->2 = $38 // SEC + //^codeptr = $38; codeptr++ // SEC + codeptr=>3 = $D0F5+(VX<<8) // SBC ESTKL,X + //^codeptr = $F5; codeptr++ // SBC zp,X + //^codeptr = $D0+VX; codeptr++ // ESTKL + codeptr=>5 = ($D095+$0100)+(VX<<8) // STA ESTKL+1,X + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + codeptr=>7 = ($C0B5+$0100)+(VX<<8) // LDA ESTKH+1,X + //^codeptr = $B5; codeptr++ // LDA zp,X + //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + codeptr=>9 = $C0F5+(VX<<8) // SBC ESTKH,X + //^codeptr = $F5; codeptr++ // SBC zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr=>11 = ($C095+$0100)+(VX<<8) // STA ESTKH+1,X + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + codeptr, VX = resolveX(codeptr + 13, VX + 1) //VX++ // INX // // BRGE // - codeptr, VX = resolveX(codeptr, VX + 1) - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL - ^codeptr = $D5; codeptr++ // CMP zp,X - ^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH - ^codeptr = $F5; codeptr++ // SBC zp,X - ^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - ^codeptr = $50; codeptr++ // BVC rel - ^codeptr = $02; codeptr++ // +2 - ^codeptr = $49; codeptr++ // EOR #imm - ^codeptr = $80; codeptr++ // $80 - ^codeptr = $30; codeptr++ // BMI rel - ^codeptr = $03; codeptr++ // +3 - ^codeptr = $4C; codeptr++ // JMP abs - *codeptr = addrxlate=>[dest] - if not (*codeptr & $8000) // Unresolved address list - addrxlate=>[dest] = codeptr - *jitcodeptr + codeptr=>0 = $D0B5+(VX<<8) // LDA ESTKL,X + //^codeptr = $B5; codeptr++ // LDA zp,X + //^codeptr = $D0+VX; codeptr++ // ESTKL + codeptr=>2 = ($D0D5+$0100)+(VX<<8) // CMP ESTKL+1,X + //^codeptr = $D5; codeptr++ // CMP zp,X + //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 + codeptr=>4 = $C0B5+(VX<<8) // LDA ESTKH,X + //^codeptr = $B5; codeptr++ // LDA zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr=>6 = ($C0F5+$0100)+(VX<<8) // SBC ESTKH+1,X + //^codeptr = $F5; codeptr++ // SBC zp,X + //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 + codeptr=>8 = $0250 // BVC +2 + //^codeptr = $50; codeptr++ // BVC rel + //^codeptr = $02; codeptr++ // +2 + codeptr=>10 = $8049 // EOR #$80 + //^codeptr = $49; codeptr++ // EOR #imm + //^codeptr = $80; codeptr++ // $80 + codeptr=>12 = $0330 // BMI +3 + //^codeptr = $30; codeptr++ // BMI rel + //^codeptr = $03; codeptr++ // +3 + codeptr->14 = $4C // JMP abs + //^codeptr = $4C; codeptr++ // JMP abs + codeptr=>15 = addrxlate=>[dest] + //*codeptr = addrxlate=>[dest] + if not (codeptr->16 & $80) // Unresolved address list + //if not (*codeptr & $8000) // Unresolved address list + addrxlate=>[dest] = codeptr + 15 - *jitcodeptr + //addrxlate=>[dest] = codeptr - *jitcodeptr fin - codeptr = codeptr + 2 - ^codeptr = $E8; codeptr++ // INX - ^codeptr = $E8; codeptr++ // INX + //codeptr = codeptr + 2 + codeptr=>17 = $E8E8 // INX; INX + //^codeptr = $E8; codeptr++ // INX + //^codeptr = $E8; codeptr++ // INX + codeptr = codeptr + 19 A_IS_TOSL = FALSE break - is $AC + is $AC // BRAND - LOGICAL AND SPECIFIC BRANCH i++ dest = i + *(bytecode+i) i++ //puts("BRAND "); puti(dest) codeptr, VX = resolveX(codeptr, VX) if not A_IS_TOSL - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 elsif A_IS_TOSL & TOSL_DIRTY *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin - ^codeptr = $15; codeptr++ // ORA zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH - ^codeptr = $D0; codeptr++ // BNE rel - ^codeptr = $03; codeptr++ // +3 - ^codeptr = $4C; codeptr++ // JMP abs - *codeptr = addrxlate=>[dest] - if not (*codeptr & $8000) // Unresolved address list - addrxlate=>[dest] = codeptr - *jitcodeptr + codeptr=>0 = $C015+(VX<<8) // ORA ESTKH,X + //^codeptr = $15; codeptr++ // ORA zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr=>2 = $03D0 // BNE +3 + //^codeptr = $D0; codeptr++ // BNE rel + //^codeptr = $03; codeptr++ // +3 + codeptr->4 = $4C // JMP abs + //^codeptr = $4C; codeptr++ // JMP abs + codeptr=>5 = addrxlate=>[dest] + //*codeptr = addrxlate=>[dest] + if not (codeptr->6 & $80) // Unresolved address list + //if not (*codeptr & $8000) // Unresolved address list + addrxlate=>[dest] = codeptr + 5 - *jitcodeptr + //addrxlate=>[dest] = codeptr - *jitcodeptr fin - codeptr = codeptr + 2 - ^codeptr = $E8; codeptr++ // INX VX++ ??? + //codeptr = codeptr + 2 + VX++ // INX + codeptr = codeptr + 7 A_IS_TOSL = FALSE break - is $AE + is $AE // BROR - LOGICAL OR SPECIFIC BRANCH i++ dest = i + *(bytecode+i) i++ //puts("BROR "); puti(dest) codeptr, VX = resolveX(codeptr, VX) if not A_IS_TOSL - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 elsif A_IS_TOSL & TOSL_DIRTY *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin - ^codeptr = $15; codeptr++ // ORA zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH - ^codeptr = $F0; codeptr++ // BEQ rel - ^codeptr = $03; codeptr++ // +3 - ^codeptr = $4C; codeptr++ // JMP abs - *codeptr = addrxlate=>[dest] - if not (*codeptr & $8000) // Unresolved address list - addrxlate=>[dest] = codeptr - *jitcodeptr + codeptr=>0 = $C015+(VX<<8) // ORA ESTKH,X + //^codeptr = $15; codeptr++ // ORA zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr=>2 = $03F0 // BEQ +3 + //^codeptr = $F0; codeptr++ // BEQ rel + //^codeptr = $03; codeptr++ // +3 + codeptr->4 = $4C // JMP abs + //^codeptr = $4C; codeptr++ // JMP abs + codeptr=>5 = addrxlate=>[dest] + //*codeptr = addrxlate=>[dest] + if not (codeptr->6 & $80) // Unresolved address list + //if not (*codeptr & $8000) // Unresolved address list + addrxlate=>[dest] = codeptr + 5 - *jitcodeptr + //addrxlate=>[dest] = codeptr - *jitcodeptr fin - codeptr = codeptr + 2 - ^codeptr = $E8; codeptr++ // INX // VX++ ??? + //codeptr = codeptr + 2 + VX++ // INX + codeptr = codeptr + 7 A_IS_TOSL = FALSE break // ADDLB,ADDLW,ADDAB,ADDAW,IDXLB,IDXLW,IDXAB,IDXAW ; B0 B2 B4 B6 B8 BA BC BE From 169d3477541271cfd2829d27984ba852428126f2 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Tue, 27 Mar 2018 10:12:13 -0700 Subject: [PATCH 103/147] Make sure A_IS_TOSL is cleared at opt fence --- src/libsrc/apple/jit.pla | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libsrc/apple/jit.pla b/src/libsrc/apple/jit.pla index 2d8b8db..35ab257 100644 --- a/src/libsrc/apple/jit.pla +++ b/src/libsrc/apple/jit.pla @@ -191,7 +191,7 @@ def compiler(defptr)#0 // codeptr = *jitcodeptr VX = 0 // Virtual X register - A_IS_TOSL = FALSE + A_IS_TOSL = FALSE i = 0 if ^bytecode == $58 //puts("ENTER "); puti(^(bytecode+1)); //putc(',');puti(^(bytecode+2)) @@ -221,8 +221,8 @@ def compiler(defptr)#0 if A_IS_TOSL & TOSL_DIRTY *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 - A_IS_TOSL = FALSE fin + A_IS_TOSL = FALSE codeptr, VX = resolveX(codeptr, VX) opcode = opcode & $FE fin From 1e05ab789e38ad632b47e320ecd5795ca4a45c57 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Tue, 27 Mar 2018 14:02:09 -0700 Subject: [PATCH 104/147] Finished updating ops $B0-$BE --- src/libsrc/apple/jit.pla | 402 +++++++++++++++++++++++---------------- 1 file changed, 238 insertions(+), 164 deletions(-) diff --git a/src/libsrc/apple/jit.pla b/src/libsrc/apple/jit.pla index 35ab257..02f0e23 100644 --- a/src/libsrc/apple/jit.pla +++ b/src/libsrc/apple/jit.pla @@ -194,7 +194,7 @@ def compiler(defptr)#0 A_IS_TOSL = FALSE i = 0 if ^bytecode == $58 - //puts("ENTER "); puti(^(bytecode+1)); //putc(',');puti(^(bytecode+2)) + //putc('$'); puth(codeptr);//puts(":[0] ENTER "); puti(^(bytecode+1)); putc(',');puti(^(bytecode+2)); putln // // Call into VM // @@ -211,7 +211,7 @@ def compiler(defptr)#0 // *codeptr = $00A0; codeptr = codeptr + 2 // LDY #$00 while isule(codeptr, codemax) - //putc('$'); puth(codeptr); //putc(':') + //putc('$'); puth(codeptr); putc(':') //putc('['); puti(i); //puts("] ") opcode = ^(bytecode+i) if opcode & 1 @@ -260,8 +260,6 @@ def compiler(defptr)#0 // Compile this bad boy... // if opcode < $20 // CONSTANT NYBBLE - // CN,CN,CN,CN,CN,CN,CN,CN ; 00 02 04 06 08 0A 0C 0E - // CN,CN,CN,CN,CN,CN,CN,CN ; 10 12 14 16 18 1A 1C 1E //puts("CN $"); putb(^(bytecode+i)/2) if A_IS_TOSL & TOSL_DIRTY *codeptr = $D095+(VX<<8) // STA ESTKL,X @@ -283,7 +281,6 @@ def compiler(defptr)#0 A_IS_TOSL = TOSL_DIRTY else when opcode - // MINUS1,BREQ,BRNE,LA,LLA,CB,CW,CS ; 20 22 24 26 28 2A 2C 2E is $20 // MINUS ONE //puts("MINUS_ONE") if A_IS_TOSL & TOSL_DIRTY @@ -511,7 +508,6 @@ def compiler(defptr)#0 codeptr = codeptr + 12 + j A_IS_TOSL = FALSE break - // DROP,DROP2,DUP,DIVMOD,ADDI,SUBI,ANDI,ORI ; 30 32 34 36 38 3A 3C 3E is $32 // DROP2 //puts("DROP2") VX++ // INX @@ -633,7 +629,6 @@ def compiler(defptr)#0 codeptr = codeptr + 2 A_IS_TOSL = TOSL_DIRTY break - // ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E is $40 // ISEQ //puts("ISEQ") if not A_IS_TOSL @@ -926,7 +921,6 @@ def compiler(defptr)#0 //codeptr = codeptr + 2 A_IS_TOSL = FALSE break - // BRNCH,SEL,CALL,ICAL,ENTER,LEAVE,RET,CFFB ; 50 52 54 56 58 5A 5C 5E is $50 // BRNCH i++ dest = i + *(bytecode+i) @@ -1135,7 +1129,6 @@ def compiler(defptr)#0 codeptr = codeptr + 6 A_IS_TOSL = TOSL_DIRTY break - // LB,LW,LLB,LLW,LAB,LAW,DLB,DLW ; 60 62 64 66 68 6A 6C 6E is $60 // LB //puts("LB") if not A_IS_TOSL @@ -1370,7 +1363,6 @@ def compiler(defptr)#0 fin A_IS_TOSL = TOSL_CLEAN break - // SB,SW,SLB,SLW,SAB,SAW,DAB,DAW ; 70 72 74 76 78 7A 7C 7E is $70 // SB //puts("SB") if not A_IS_TOSL @@ -1570,7 +1562,6 @@ def compiler(defptr)#0 codeptr = codeptr + 10 i++ break - // LNOT,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 80 82 84 86 88 8A 8C 8E is $80 // NOT //puts("NOT") if not A_IS_TOSL @@ -1662,15 +1653,15 @@ def compiler(defptr)#0 //puts("MUL,DIV,MOD,SHL,SHR") // when opcode // is $86 - // puts("MUL") + // //puts("MUL") // is $88 - // puts("DIV") + // //puts("DIV") // is $8A - // puts("MOD") + // //puts("MOD") // is $9A - // puts("SHL") + // //puts("SHL") // is $9C - // puts("SHR") + // //puts("SHR") // wend // // Call into VM @@ -1737,7 +1728,6 @@ def compiler(defptr)#0 codeptr = codeptr + 7 A_IS_TOSL = TOSL_DIRTY break - // NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 90 92 94 96 98 9A 9C 9E is $90 // NEG //puts("NEG") if A_IS_TOSL & TOSL_DIRTY @@ -1895,7 +1885,6 @@ def compiler(defptr)#0 codeptr = codeptr + 14 A_IS_TOSL = FALSE break - // BRGT,BRLT,INCBRLE,ADDBRLE,DECBRGE,SUBBRGE,BRAND,BROR ; A0 A2 A4 A6 A8 AA AC AE is $A0 // BRGT - FOR/NEXT SPECIFIC TEST & BRANCH i++ dest = i + *(bytecode+i) @@ -2334,8 +2323,7 @@ def compiler(defptr)#0 codeptr = codeptr + 7 A_IS_TOSL = FALSE break - // ADDLB,ADDLW,ADDAB,ADDAW,IDXLB,IDXLW,IDXAB,IDXAW ; B0 B2 B4 B6 B8 BA BC BE - is $B0 + is $B0 // ADDLB i++ //puts("ADDLB "); puti(^(bytecode+i)) if not A_IS_TOSL @@ -2343,25 +2331,32 @@ def compiler(defptr)#0 codeptr = codeptr + 2 fin if ^(bytecode+i) <> 0 - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = ^(bytecode+i); codeptr++ + *codeptr = $A0+(^(bytecode+i)<<8) // LDY #imm + codeptr = codeptr + 2 fin - ^codeptr = $18; codeptr++ // CLC - ^codeptr = $71; codeptr++ // ADC (zp),Y - ^codeptr = $E0; codeptr++ // IFP - ^codeptr = $90; codeptr++ // BCC rel - ^codeptr = $02; codeptr++ // +2 - ^codeptr = $F6; codeptr++ // INC zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr->0 = $18 // CLC + //^codeptr = $18; codeptr++ // CLC + codeptr=>1 = $E071 // ADC (IFP),Y + //^codeptr = $71; codeptr++ // ADC (zp),Y + //^codeptr = $E0; codeptr++ // IFP + codeptr=>3 = $0290 // BCC +2 + //^codeptr = $90; codeptr++ // BCC rel + //^codeptr = $02; codeptr++ // +2 + codeptr=>5 = $C0F6+(VX<<8) // INC ESTKH,X + //^codeptr = $F6; codeptr++ // INC zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr = codeptr + 7 if ^(bytecode+i) <> 0 - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = $00; codeptr++ // $00 + *codeptr = $00A0 // LDY #$00 + codeptr = codeptr + 2 + //^codeptr = $A0; codeptr++ // LDY #imm + //^codeptr = $00; codeptr++ // $00 fin //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL A_IS_TOSL = TOSL_DIRTY break - is $B2 + is $B2 // ADDLW i++ //puts("ADDLW "); puti(^(bytecode+i)) if not A_IS_TOSL @@ -2369,70 +2364,94 @@ def compiler(defptr)#0 codeptr = codeptr + 2 fin if ^(bytecode+i) <> 0 - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = ^(bytecode+i); codeptr++ + *codeptr = $A0+(^(bytecode+i)<<8) // LDY #imm + codeptr = codeptr + 2 fin - ^codeptr = $18; codeptr++ // CLC - ^codeptr = $71; codeptr++ // ADC (zp),Y - ^codeptr = $E0; codeptr++ // IFP - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH - ^codeptr = $C8; codeptr++ // INY - ^codeptr = $71; codeptr++ // ADC (zp),Y - ^codeptr = $E0; codeptr++ // IFP - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr->0 = $18 // CLC + //^codeptr = $18; codeptr++ // CLC + codeptr=>1 = $E071 // ADC (IFP),Y + //^codeptr = $71; codeptr++ // ADC (zp),Y + //^codeptr = $E0; codeptr++ // IFP + codeptr=>3 = $D095+(VX<<8) // STA ESTKL,X + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $D0+VX; codeptr++ // ESTKL + codeptr=>5 = $C0B5+(VX<<8) // LDA ESTKH,X + //^codeptr = $B5; codeptr++ // LDA zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr->7 = $C8 // INY + //^codeptr = $C8; codeptr++ // INY + codeptr=>8 = $E071 // ADC (IFP),Y + //^codeptr = $71; codeptr++ // ADC (zp),Y + //^codeptr = $E0; codeptr++ // IFP + codeptr=>10 = $C095+(VX<<8) // STA ESTKH,X + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH if ^(bytecode+i) <> 0 - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = $00; codeptr++ // $00 + codeptr=>12 = $00A0 // LDY #$00 + codeptr = codeptr + 14 + //^codeptr = $A0; codeptr++ // LDY #imm + //^codeptr = $00; codeptr++ // $00 else - ^codeptr = $88; codeptr++ // DEY + codeptr->12 = $88 // DEY + codeptr = codeptr + 13 + //^codeptr = $88; codeptr++ // DEY fin - A_IS_TOSL = FALSE + A_IS_TOSL = FALSE break - is $B4 + is $B4 // ADDAB i++ //puts("ADDAB $"); puth(*(bytecode+i)) if not A_IS_TOSL *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - ^codeptr = $18; codeptr++ // CLC - ^codeptr = $6D; codeptr++ // ADC abs - *codeptr = *(bytecode+i); codeptr = codeptr + 2 - ^codeptr = $90; codeptr++ // BCC rel - ^codeptr = $02; codeptr++ // +2 - ^codeptr = $F6; codeptr++ // INC zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr=>0 = $6D18 // CLC; ADC abs + //^codeptr = $18; codeptr++ // CLC + //^codeptr = $6D; codeptr++ // ADC abs + codeptr=>2 = *(bytecode+i) + //*codeptr = *(bytecode+i); codeptr = codeptr + 2 + codeptr=>4 = $0290 // BCC +2 + //^codeptr = $90; codeptr++ // BCC rel + //^codeptr = $02; codeptr++ // +2 + codeptr=>6 = $C0F6+(VX<<8) // INC ESTKH,X + //^codeptr = $F6; codeptr++ // INC zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH //^codeptr = $95; codeptr++ // STA zp,X //^codeptr = $D0+VX; codeptr++ // ESTKL + codeptr = codeptr + 8 A_IS_TOSL = TOSL_DIRTY i++ break - is $B6 + is $B6 // ADDAW i++ //puts("ADDAW $"); puth(*(bytecode+i)) if not A_IS_TOSL *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - ^codeptr = $18; codeptr++ // CLC - ^codeptr = $6D; codeptr++ // ADC abs - *codeptr = *(bytecode+i); codeptr = codeptr + 2 - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL - ^codeptr = $B5; codeptr++ // LDA zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH - ^codeptr = $6D; codeptr++ // ADC abs - *codeptr = *(bytecode+i)+1; codeptr = codeptr + 2 - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr=>0 = $6D18 // CLC; ADC abs + //^codeptr = $18; codeptr++ // CLC + //^codeptr = $6D; codeptr++ // ADC abs + codeptr=>2 = *(bytecode+i) + //*codeptr = *(bytecode+i); codeptr = codeptr + 2 + codeptr=>4 = $D095+(VX<<8) // STA ESTKL,X + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $D0+VX; codeptr++ // ESTKL + codeptr=>6 = $C0B5+(VX<<8) // LDA ESTKH,X + //^codeptr = $B5; codeptr++ // LDA zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr->8 = $6D // ADC abs + //^codeptr = $6D; codeptr++ // ADC abs + codeptr=>9 = *(bytecode+i)+1 + //*codeptr = *(bytecode+i)+1; codeptr = codeptr + 2 + codeptr=>11 = $C095+(VX<<8) // STA ESTKH,X + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr = codeptr + 13 A_IS_TOSL = FALSE i++ break - is $B8 + is $B8 // IDXLB i++ //puts("IDXLB "); puti(^(bytecode+i)) if A_IS_TOSL & TOSL_DIRTY @@ -2440,34 +2459,46 @@ def compiler(defptr)#0 codeptr = codeptr + 2 fin if ^(bytecode+i) <> 0 - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = ^(bytecode+i); codeptr++ + *codeptr = $A0+(^(bytecode+i)<<8) // LDY #imm + codeptr = codeptr + 2 fin - ^codeptr = $B1; codeptr++ // LDA (zp),Y - ^codeptr = $E0; codeptr++ // IFP + *codeptr = $E0B1 // LDA (IFP),Y + codeptr = codeptr + 2 + //^codeptr = $B1; codeptr++ // LDA (zp),Y + //^codeptr = $E0; codeptr++ // IFP if ^(bytecode+i) <> 0 - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = $00; codeptr++ // $00 + *codeptr = $00A0 // LDY #$00 + codeptr = codeptr + 2 fin - ^codeptr = $0A; codeptr++ // ASL - ^codeptr = $90; codeptr++ // BCC rel - ^codeptr = $02; codeptr++ // +2 - ^codeptr = $C8; codeptr++ // INY - ^codeptr = $18; codeptr++ // CLC - ^codeptr = $75; codeptr++ // ADC zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL - ^codeptr = $98; codeptr++ // TYA - ^codeptr = $75; codeptr++ // ADC zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = $00; codeptr++ // $00 - A_IS_TOSL = FALSE + codeptr->0 = $0A // ASL + //^codeptr = $0A; codeptr++ // ASL + codeptr=>1 = $0290 // BCC +2 + //^codeptr = $90; codeptr++ // BCC rel + //^codeptr = $02; codeptr++ // +2 + codeptr=>3 = $18C8 // INY; CLC + //^codeptr = $C8; codeptr++ // INY + //^codeptr = $18; codeptr++ // CLC + codeptr=>5 = $D075+(VX<<8) // ADC ESTKL,X + //^codeptr = $75; codeptr++ // ADC zp,X + //^codeptr = $D0+VX; codeptr++ // ESTKL + codeptr=>7 = $D095+(VX<<8) // STA ESTKL,X + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $D0+VX; codeptr++ // ESTKL + codeptr->9 = $98 // TYA + //^codeptr = $98; codeptr++ // TYA + codeptr=>10 = $C075+(VX<<8) // ADC ESTKH,X + //^codeptr = $75; codeptr++ // ADC zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr=>12 = $C095+(VX<<8) // STA ESTKH,X + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr=>14 = $00A0 // LDY #$00 + //^codeptr = $A0; codeptr++ // LDY #imm + //^codeptr = $00; codeptr++ // $00 + codeptr = codeptr + 16 + A_IS_TOSL = FALSE break - is $BA + is $BA // IDXLW i++ //puts("IDXLW "); puti(^(bytecode+i)) if A_IS_TOSL & TOSL_DIRTY @@ -2475,60 +2506,87 @@ def compiler(defptr)#0 codeptr = codeptr + 2 fin if ^(bytecode+i) <> 0 - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = ^(bytecode+i); codeptr++ + *codeptr = $A0+(^(bytecode+i)<<8) // LDY #imm + codeptr = codeptr + 2 fin - ^codeptr = $B1; codeptr++ // LDA (zp),Y - ^codeptr = $E0; codeptr++ // IFP - ^codeptr = $0A; codeptr++ // ASL - ^codeptr = $85; codeptr++ // STA zp - ^codeptr = $E7; codeptr++ // $E7:TMPL - ^codeptr = $C8; codeptr++ // INY - ^codeptr = $B1; codeptr++ // LDA (zp),Y - ^codeptr = $E0; codeptr++ // IFP - ^codeptr = $2A; codeptr++ // ROL - ^codeptr = $A8; codeptr++ // TAY - ^codeptr = $A5; codeptr++ // LDA zp - ^codeptr = $E7; codeptr++ // $E7:TMPL - ^codeptr = $18; codeptr++ // CLC - ^codeptr = $75; codeptr++ // ADC zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL - ^codeptr = $98; codeptr++ // TYA - ^codeptr = $75; codeptr++ // ADC zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = $00; codeptr++ // $00 + codeptr=>0 = $E0B1 // LDA (IFP),Y + //^codeptr = $B1; codeptr++ // LDA (zp),Y + //^codeptr = $E0; codeptr++ // IFP + codeptr->2 = $0A // ASL + //^codeptr = $0A; codeptr++ // ASL + codeptr=>3 = $E785 // STA $E7:TMPL + //^codeptr = $85; codeptr++ // STA zp + //^codeptr = $E7; codeptr++ // $E7:TMPL + codeptr->5 = $C8 // INY + //^codeptr = $C8; codeptr++ // INY + codeptr=>6 = $E0B1 // LDA (IFP),Y + //^codeptr = $B1; codeptr++ // LDA (zp),Y + //^codeptr = $E0; codeptr++ // IFP + codeptr=>8 = $A82A // ROL; TAY + //^codeptr = $2A; codeptr++ // ROL + //^codeptr = $A8; codeptr++ // TAY + codeptr=>10 = $E7A5 // LDA $E7:TMPL + //^codeptr = $A5; codeptr++ // LDA zp + //^codeptr = $E7; codeptr++ // $E7:TMPL + codeptr->12 = $18 // CLC + //^codeptr = $18; codeptr++ // CLC + codeptr=>13 = $D075+(VX<<8) // ADC ESTKL,X + //^codeptr = $75; codeptr++ // ADC zp,X + //^codeptr = $D0+VX; codeptr++ // ESTKL + codeptr=>15 = $D095+(VX<<8) // STA ESTKL,X + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $D0+VX; codeptr++ // ESTKL + codeptr->17 = $98 // TAY + //^codeptr = $98; codeptr++ // TYA + codeptr=>18 = $C075+(VX<<8) // ADC ESTKLH,X + //^codeptr = $75; codeptr++ // ADC zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr=>20 = $C095+(VX<<8) // STA ESTKLH,X + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr=>22 = $00A0 // LDY #$00 + //^codeptr = $A0; codeptr++ // LDY #imm + //^codeptr = $00; codeptr++ // $00 + codeptr = codeptr + 24 A_IS_TOSL = FALSE break - is $BC + is $BC // IDXAB i++ //puts("IDXAB $"); puth(*(bytecode+i)) if A_IS_TOSL & TOSL_DIRTY *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin - ^codeptr = $AD; codeptr++ // LDA abs - *codeptr = *(bytecode+i); codeptr = codeptr + 2 - ^codeptr = $0A; codeptr++ // ASL - ^codeptr = $90; codeptr++ // BCC rel - ^codeptr = $02; codeptr++ // +2 - ^codeptr = $C8; codeptr++ // INY - ^codeptr = $18; codeptr++ // CLC - ^codeptr = $75; codeptr++ // ADC zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL - ^codeptr = $98; codeptr++ // TYA - ^codeptr = $75; codeptr++ // ADC zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = $00; codeptr++ // $00 + codeptr->0 = $AD // LDA abs + //^codeptr = $AD; codeptr++ // LDA abs + codeptr=>1 = *(bytecode+i) + //*codeptr = *(bytecode+i); codeptr = codeptr + 2 + codeptr->3 = $0A // ASL + //^codeptr = $0A; codeptr++ // ASL + codeptr=>4 = $0290 // BCC +2 + //^codeptr = $90; codeptr++ // BCC rel + //^codeptr = $02; codeptr++ // +2 + codeptr=>6 = $18C8 // INY; CLC + //^codeptr = $C8; codeptr++ // INY + //^codeptr = $18; codeptr++ // CLC + codeptr=>8 = $D075+(VX<<8) // ADC ESTKL,X + //^codeptr = $75; codeptr++ // ADC zp,X + //^codeptr = $D0+VX; codeptr++ // ESTKL + codeptr=>10 = $D095+(VX<<8) // STA ESTKL,X + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $D0+VX; codeptr++ // ESTKL + codeptr->12 = $98 // TYA + //^codeptr = $98; codeptr++ // TYA + codeptr=>13 = $C075+(VX<<8) // ADC ESTKH,X + //^codeptr = $75; codeptr++ // ADC zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr=>15 = $C095+(VX<<8) // STA ESTKLH,X + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr=>17 = $00A0 // LDY #$00 + //^codeptr = $A0; codeptr++ // LDY #imm + //^codeptr = $00; codeptr++ // $00 + codeptr = codeptr + 19 A_IS_TOSL = FALSE i++ break @@ -2539,29 +2597,45 @@ def compiler(defptr)#0 *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin - ^codeptr = $AD; codeptr++ // LDA abs - *codeptr = *(bytecode+i); codeptr = codeptr + 2 - ^codeptr = $0A; codeptr++ // ASL - ^codeptr = $85; codeptr++ // STA zp - ^codeptr = $E7; codeptr++ // $E7:TMPL - ^codeptr = $AD; codeptr++ // LDA abs - *codeptr = *(bytecode+i)+1; codeptr = codeptr + 2 - ^codeptr = $2A; codeptr++ // ROL - ^codeptr = $A8; codeptr++ // TAY - ^codeptr = $A5; codeptr++ // LDA zp - ^codeptr = $E7; codeptr++ // $E7:TMPL - ^codeptr = $18; codeptr++ // CLC - ^codeptr = $75; codeptr++ // ADC zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $D0+VX; codeptr++ // ESTKL - ^codeptr = $98; codeptr++ // TYA - ^codeptr = $75; codeptr++ // ADC zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH - ^codeptr = $95; codeptr++ // STA zp,X - ^codeptr = $C0+VX; codeptr++ // ESTKH - ^codeptr = $A0; codeptr++ // LDY #imm - ^codeptr = $00; codeptr++ // $00 + codeptr->0 = $AD // LDA abs + //^codeptr = $AD; codeptr++ // LDA abs + codeptr=>1 = *(bytecode+i) + //*codeptr = *(bytecode+i); codeptr = codeptr + 2 + codeptr->3 = $0A // ASL + //^codeptr = $0A; codeptr++ // ASL + codeptr=>4 = $E785 // STA $E7:TMPL + //^codeptr = $85; codeptr++ // STA zp + //^codeptr = $E7; codeptr++ // $E7:TMPL + codeptr->6 = $AD // LDA abs + //^codeptr = $AD; codeptr++ // LDA abs + codeptr=>7 = *(bytecode+i)+1 + //*codeptr = *(bytecode+i)+1; codeptr = codeptr + 2 + codeptr=>9 = $A82A // ROL; TAY + //^codeptr = $2A; codeptr++ // ROL + //^codeptr = $A8; codeptr++ // TAY + codeptr=>11 = $E7A5 // LDA $E7:TMPL + //^codeptr = $A5; codeptr++ // LDA zp + //^codeptr = $E7; codeptr++ // $E7:TMPL + codeptr->13 = $18 // CLC + //^codeptr = $18; codeptr++ // CLC + codeptr=>14 = $D075+(VX<<8) // ADC ESTKL,X + //^codeptr = $75; codeptr++ // ADC zp,X + //^codeptr = $D0+VX; codeptr++ // ESTKL + codeptr=>16 = $D095+(VX<<8) // STA ESTKL,X + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $D0+VX; codeptr++ // ESTKL + codeptr->18 = $98 // TYA + //^codeptr = $98; codeptr++ // TYA + codeptr=>19 = $C075+(VX<<8) // ADC ESTKH,X + //^codeptr = $75; codeptr++ // ADC zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr=>21 = $C095+(VX<<8) // STA ESTKLH,X + //^codeptr = $95; codeptr++ // STA zp,X + //^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr=>23 = $00A0 // LDY #$00 + //^codeptr = $A0; codeptr++ // LDY #imm + //^codeptr = $00; codeptr++ // $00 + codeptr = codeptr + 25 A_IS_TOSL = FALSE i++ break @@ -2588,7 +2662,7 @@ def compiler(defptr)#0 //getc return fin - //getc + //if opcode == $B6; getc; fin loop // // If we got here. we ran out of code buffer space. Overwrite interpreter From 369e9731f4d7564e466697ad94a606acc8503bdc Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Tue, 27 Mar 2018 19:21:27 -0700 Subject: [PATCH 105/147] Source cleanup --- src/libsrc/apple/jit.pla | 2211 ++++++++++++-------------------------- 1 file changed, 659 insertions(+), 1552 deletions(-) diff --git a/src/libsrc/apple/jit.pla b/src/libsrc/apple/jit.pla index 02f0e23..c4a6388 100644 --- a/src/libsrc/apple/jit.pla +++ b/src/libsrc/apple/jit.pla @@ -260,25 +260,21 @@ def compiler(defptr)#0 // Compile this bad boy... // if opcode < $20 // CONSTANT NYBBLE - //puts("CN $"); putb(^(bytecode+i)/2) + //puts("CN $"); putb(opcode/2) if A_IS_TOSL & TOSL_DIRTY - *codeptr = $D095+(VX<<8) // STA ESTKL,X + *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin - VX-- // DEX - if ^(bytecode+i) == 0 - ^codeptr = $98; codeptr++ // TYA -> LDA #$00 + VX-- // DEX + if opcode == 0 + ^codeptr = $98; codeptr++ // TYA -> LDA #$00 else - *codeptr = $A9+(^(bytecode+i)/2<<8) // LDA #(CN/2) - //^codeptr = $A9; codeptr++ // LDA #imm - //^codeptr = $CN/2; codeptr++ // CN/2 + *codeptr = $A9+(opcode/2<<8) // LDA #(CN/2) codeptr = codeptr + 2 fin - *codeptr = $C094+(VX<<8) // STY ESTKH,X - //^codeptr = $94; codeptr++ // STY zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH + *codeptr = $C094+(VX<<8) // STY ESTKH,X codeptr = codeptr + 2 - A_IS_TOSL = TOSL_DIRTY + A_IS_TOSL = TOSL_DIRTY // STA ESTKL,X else when opcode is $20 // MINUS ONE @@ -288,57 +284,32 @@ def compiler(defptr)#0 codeptr = codeptr + 2 fin VX-- // DEX - codeptr=>0 = $FFA9 // LDA #$FF - //^codeptr = $A9; codeptr++ // LDA #imm - //^codeptr = $FF; codeptr++ // $FF - codeptr=>2 = $C095+(VX<<8) // STA ESTKH,X + codeptr=>0 = $FFA9 // LDA #$FF + codeptr=>2 = $C095+(VX<<8) // STA ESTKH,X codeptr = codeptr + 4 - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $D0+VX; codeptr++ // ESTKL - A_IS_TOSL = TOSL_DIRTY + A_IS_TOSL = TOSL_DIRTY // STA ESTKL,X break is $22 // BREQ i++ dest = i + *(bytecode+i) i++ //puts("BREQ "); puti(dest) - codeptr, VX = resolveX(codeptr, VX + 2) - // INX - // INX + codeptr, VX = resolveX(codeptr, VX + 2) // INX; INX if not A_IS_TOSL - *codeptr = ($D0B5-$0200)+(VX<<8) // LDA ESTKL-2,X + *codeptr = $D0B5-$0200//+(VX<<8) // LDA ESTKL-2,X codeptr = codeptr + 2 - //^codeptr = $B5; codeptr++ // LDA zp,X - //^codeptr = $D0-2+VX; codeptr++ // ESTKL-2 fin - codeptr=>0 = ($D0D5-$0100)+(VX<<8) // CMP ESTKL-1,X - //^codeptr = $D5; codeptr++ // CMP zp,X - //^codeptr = $D0-1+VX; codeptr++ // ESTKL-1 - codeptr=>2 = $09D0 // BNE +9 - //^codeptr = $D0; codeptr++ // BNE rel - //^codeptr = $09; codeptr++ // +9 - codeptr=>4 = ($C0B5-$0200)+(VX<<8) // LDA ESTKH-2,X - //^codeptr = $B5; codeptr++ // LDA zp,X - //^codeptr = $C0-2+VX; codeptr++ // ESTKH-2 - codeptr=>6 = ($C0D5-$0100)+(VX<<8) // CMP ESTKH-1,X - //^codeptr = $D5; codeptr++ // CMP zp,X - //^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 - codeptr=>8 = $03D0 // BNE +3 - //^codeptr = $D0; codeptr++ // BNE rel - //^codeptr = $03; codeptr++ // +3 - codeptr->10 = $4C // JMP abs - //^codeptr = $4C; codeptr++ // JMP abs + codeptr=>0 = $D0D5-$0100//+(VX<<8) // CMP ESTKL-1,X + codeptr=>2 = $09D0 // BNE +9 + codeptr=>4 = $C0B5-$0200//+(VX<<8) // LDA ESTKH-2,X + codeptr=>6 = $C0D5-$0100//+(VX<<8) // CMP ESTKH-1,X + codeptr=>8 = $03D0 // BNE +3 + codeptr->10 = $4C // JMP abs codeptr=>11 = addrxlate=>[dest] - //*codeptr = addrxlate=>[dest] if not (codeptr->12 & $80) // Unresolved address list - //if not (*codeptr & $8000) // Unresolved address list addrxlate=>[dest] = codeptr + 11 - *jitcodeptr - //addrxlate=>[dest] = codeptr - *jitcodeptr fin codeptr = codeptr + 13 - //codeptr = codeptr + 2 A_IS_TOSL = FALSE break is $24 // BRNE @@ -346,105 +317,67 @@ def compiler(defptr)#0 dest = i + *(bytecode+i) i++ //puts("BRNE "); puti(dest) - codeptr, VX = resolveX(codeptr, VX + 2) - // INX - // INX + codeptr, VX = resolveX(codeptr, VX + 2) // INX; INX if not A_IS_TOSL - *codeptr = ($D0B5-$0200)+(VX<<8) // LDA ESTKL-2,X + *codeptr = $D0B5-$0200//+(VX<<8) // LDA ESTKL-2,X codeptr = codeptr + 2 - //^codeptr = $B5; codeptr++ // LDA zp,X - //^codeptr = $D0-2+VX; codeptr++ // ESTKL-2 fin - codeptr=>0 = ($D0D5-$0100)+(VX<<8) // CMP ESTKL-1,X - //^codeptr = $D5; codeptr++ // CMP zp,X - //^codeptr = $D0-1+VX; codeptr++ // ESTKL-1 - codeptr=>2 = $06D0 // BNE +6 - //^codeptr = $D0; codeptr++ // BNE rel - //^codeptr = $06; codeptr++ // +6 - codeptr=>4 = ($C0B5-$0200)+(VX<<8) // LDA ESTKH-2,X - //^codeptr = $B5; codeptr++ // LDA zp,X - //^codeptr = $C0-2+VX; codeptr++ // ESTKH-2 - codeptr=>6 = ($C0D5-$0100)+(VX<<8) // CMP ESTKH-1,X - //^codeptr = $D5; codeptr++ // CMP zp,X - //^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 - codeptr=>8 = $03F0 // BEQ +3 - //^codeptr = $F0; codeptr++ // BEQ rel - //^codeptr = $03; codeptr++ // +3 - codeptr->10 = $4C // JMP abs - //^codeptr = $4C; codeptr++ // JMP abs + codeptr=>0 = $D0D5-$0100//+(VX<<8) // CMP ESTKL-1,X + codeptr=>2 = $06D0 // BNE +6 + codeptr=>4 = $C0B5-$0200//+(VX<<8) // LDA ESTKH-2,X + codeptr=>6 = $C0D5-$0100//+(VX<<8) // CMP ESTKH-1,X + codeptr=>8 = $03F0 // BEQ +3 + codeptr->10 = $4C // JMP abs codeptr=>11 = addrxlate=>[dest] - //*codeptr = addrxlate=>[dest] if not (codeptr->12 & $80) // Unresolved address list - //if not (*codeptr & $8000) // Unresolved address list addrxlate=>[dest] = codeptr + 11 - *jitcodeptr - //addrxlate=>[dest] = codeptr - *jitcodeptr fin codeptr = codeptr + 13 - //codeptr = codeptr + 2 A_IS_TOSL = FALSE break is $26 // LA is $2C // CW i++ - //puts("LA/CW $"); puth(*(bytecode+i)) + dest = *(bytecode+i) + //puts("LA/CW $"); puth(dest) if A_IS_TOSL & TOSL_DIRTY - *codeptr = $D095+(VX<<8) // STA ESTKL,X + *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin - VX-- // DEX - codeptr=>0 = $A9+(^(bytecode+i+1)<<8) // LDA #2 = $C095+(VX<<8) // STA ESTKH,X - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH - if ^(bytecode+i) == 0 - codeptr->4 = $98 // TYA -> LDA #$00 + VX-- // DEX + codeptr=>0 = $A9+(dest&$FF00) // LDA #2 = $C095+(VX<<8) // STA ESTKH,X + if dest & $00FF == 0 + codeptr->4 = $98 // TYA -> LDA #$00 codeptr = codeptr + 5 - //^codeptr = $98; codeptr++ // TYA -> LDA #$00 else - codeptr=>4 = $A9+(^(bytecode+i)<<8) // LDA #>VAL + codeptr=>4 = $A9+(dest<<8) // LDA #>VAL codeptr = codeptr + 6 - //^codeptr = $A9; codeptr++ // LDA #imm - //^codeptr = ^(bytecode+i); codeptr++ fin - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $D0+VX; codeptr++ // ESTKL - A_IS_TOSL = TOSL_DIRTY + A_IS_TOSL = TOSL_DIRTY // STA ESTKL,X i++ break is $28 // LLA i++ + j = ^(bytecode+i) //puts("LLA "); puti(^(bytecode+i)) if A_IS_TOSL & TOSL_DIRTY - *codeptr = $D095+(VX<<8) // STA ESTKL,X + *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin - VX-- // DEX - if ^(bytecode+i) == 0 - ^codeptr = $98; codeptr++ // TYA -> LDA #$00 + VX-- // DEX + if j + *codeptr = $A9+(j<<8) // LDA #imm + codeptr = codeptr + 2 else - *codeptr = $A9+(^(bytecode+i)<<8) // LDA #imm - codeptr = codeptr + 2 - //^codeptr = $A9; codeptr++ // LDA #imm - //^codeptr = ^(bytecode+i); codeptr++ + ^codeptr = $98; codeptr++ // TYA -> LDA #$00 fin - codeptr->0 = $18 // CLC - //^codeptr = $18; codeptr++ // CLC - codeptr=>1 = $E065 // ADC IFPL - //^codeptr = $65; codeptr++ // ADC zp - //^codeptr = $E0; codeptr++ // IFPL - codeptr=>3 = $D095+(VX<<8) // STA ESTKL,X - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $D0+VX; codeptr++ // ESTKL - codeptr->5 = $98 // TYA -> LDA #$00 - //^codeptr = $98; codeptr++ // TYA -> LDA #$00 - codeptr=>6 = $E165 // ADC IFPH - //^codeptr = $65; codeptr++ // ADC zp - //^codeptr = $E1; codeptr++ // IFPH - codeptr=>8 = $C095+(VX<<8) // STA ESTKH,X - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr->0 = $18 // CLC + codeptr=>1 = $E065 // ADC IFPL + codeptr=>3 = $D095+(VX<<8) // STA ESTKL,X + codeptr->5 = $98 // TYA -> LDA #$00 + codeptr=>6 = $E165 // ADC IFPH + codeptr=>8 = $C095+(VX<<8) // STA ESTKH,X codeptr = codeptr + 10 A_IS_TOSL = FALSE break @@ -452,97 +385,63 @@ def compiler(defptr)#0 i++ //puts("CB $"); putb(^(bytecode+i)) if A_IS_TOSL & TOSL_DIRTY - *codeptr = $D095+(VX<<8) // STA ESTKL,X + *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin - VX-- //^codeptr = $CA; codeptr++ // DEX + VX-- // DEX codeptr=>0 = $A9+(^(bytecode+i)<<8) // LDA #imm - //^codeptr = $A9; codeptr++ // LDA #imm - //^codeptr = ^(bytecode+i); codeptr++ - codeptr=>2 = $C094+(VX<<8) // STY ESTKH,X - //^codeptr = $94; codeptr++ // STY zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $D0+VX; codeptr++ // ESTKL + codeptr=>2 = $C094+(VX<<8) // STY ESTKH,X codeptr = codeptr + 4 - A_IS_TOSL = TOSL_DIRTY + A_IS_TOSL = TOSL_DIRTY // STA ESTKL,X break is $2E // CS i++ j = ^(bytecode+i) dest = i + j + 1 //puts("CS "); //puts(bytecode+i); //puts("-->"); puti(dest) - if isule(codeptr + 12 + j, codemax) + if isule(codeptr + 10 + j, codemax) if A_IS_TOSL & TOSL_DIRTY - *codeptr = $D095+(VX<<8) // STA ESTKL,X + *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin - VX-- //^codeptr = $CA; codeptr++ // DEX - codeptr=>0 = $A9+((codeptr+11)<<8) // LDA #imm - //^codeptr = $A9; codeptr++ // LDA #imm - //^codeptr = codeptr+10; codeptr++ - codeptr=>2 = $D095+(VX<<8) // STA ESTKL,X - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $D0+VX; codeptr++ // ESTKL - codeptr=>4 = $A9+((codeptr+11)&$FF00) // LDA #imm - //^codeptr = $A9; codeptr++ // LDA #imm - //^codeptr = (codeptr+6)>>8; codeptr++ - codeptr=>6 = $C095+(VX<<8) // STA ESTKH,X - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH - codeptr->8 = $4C // JMP abs - //^codeptr = $4C; codeptr++ // JMP abs - codeptr=>9 = addrxlate=>[dest] - //*codeptr = addrxlate=>[dest] - if not (codeptr->10 & $80) // Unresolved address list - //if not (*codeptr & $8000) // Unresolved address list - addrxlate=>[dest] = codeptr + 9 - *jitcodeptr - //addrxlate=>[dest] = codeptr - *jitcodeptr + 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 + codeptr=>7 = addrxlate=>[dest] + if not (codeptr->8 & $80) // Unresolved address list + addrxlate=>[dest] = codeptr + 7 - *jitcodeptr fin - //codeptr = codeptr + 2 - strcpy(codeptr + 11, bytecode + i) - //strcpy(codeptr + 2, bytecode+i) - //codeptr = codeptr + j + 1 + strcpy(codeptr + 9, bytecode + i) i = i + j fin - codeptr = codeptr + 12 + j - A_IS_TOSL = FALSE + codeptr = codeptr + 10 + j + A_IS_TOSL = TOSL_DIRTY // STA ESTKL,X break is $32 // DROP2 //puts("DROP2") - VX++ // INX + VX++ // INX is $30 // DROP //puts("DROP") - VX++ // INX + 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 = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 - //^codeptr = $B5; codeptr++ // LDA zp,X - //^codeptr = $D0+VX; codeptr++ // ESTKL elsif A_IS_TOSL & TOSL_DIRTY - *codeptr = $D095+(VX<<8) // STA ESTKL,X + *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin - VX-- // DEX - codeptr=>0 = ($C0B4+$0100)+(VX<<8) // LDY ESTKH+1,X - //^codeptr = $B4; codeptr++ // LDY zp,X - //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - codeptr=>2 = $C094+(VX<<8) // STY ESTKH,X - //^codeptr = $94; codeptr++ // STY zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH - codeptr=>4 = $00A0 // LDY #$00 - //^codeptr = $A0; codeptr++ // LDY #imm - //^codeptr = $00; codeptr++ // $00 - //^codeptr = $B5; codeptr++ // LDA zp,X - //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $D0+VX; codeptr++ // ESTKL + VX-- // DEX + codeptr=>0 = $C0B4+$0100+(VX<<8) // LDY ESTKH+1,X + codeptr=>2 = $C094+(VX<<8) // STY ESTKH,X + codeptr=>4 = $00A0 // LDY #$00 codeptr = codeptr + 6 - A_IS_TOSL = TOSL_DIRTY + A_IS_TOSL = TOSL_DIRTY // STA ESTKL,X break //is $36 //puts("DIVMOD") @@ -554,342 +453,185 @@ def compiler(defptr)#0 i++ //puts("ADDI $"); putb(^(bytecode+i)) if not A_IS_TOSL - *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - codeptr->0 = $18 // CLC - //^codeptr = $18; codeptr++ // CLC + codeptr->0 = $18 // CLC codeptr=>1 = $69+(^(bytecode+i)<<8) // ADC #imm - //^codeptr = $69; codeptr++ // ADC #imm - //^codeptr = ^(bytecode+i); codeptr++ - codeptr=>3 = $0290 // BCC +2 - //^codeptr = $90; codeptr++ // BCC rel - //^codeptr = $02; codeptr++ // +2 - codeptr=>5 = $C0F6+(VX<<8) // INC ESTKH,X - //^codeptr = $F6; codeptr++ // INC zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $D0+VX; codeptr++ // ESTKL + codeptr=>3 = $0290 // BCC +2 + codeptr=>5 = $C0F6+(VX<<8) // INC ESTKH,X codeptr = codeptr + 7 - A_IS_TOSL = TOSL_DIRTY + A_IS_TOSL = TOSL_DIRTY // STA ESTKL,X break is $3A // SUBI i++ //puts("SUBI $"); putb(^(bytecode+i)) if not A_IS_TOSL - *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - codeptr->0 = $38 // SEC - //^codeptr = $38; codeptr++ // SEC + codeptr->0 = $38 // SEC codeptr=>1 = $E9+(^(bytecode+i)<<8) // SBC #imm - //^codeptr = $E9; codeptr++ // SBC #imm - //^codeptr = ^(bytecode+i); codeptr++ - codeptr=>3 = $02B0 // BCS +2 - //^codeptr = $B0; codeptr++ // BCS rel - //^codeptr = $02; codeptr++ // +2 - codeptr=>5 = $C0D6+(VX<<8) // INC ESTKH,X - //^codeptr = $D6; codeptr++ // DEC zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $D0+VX; codeptr++ // ESTKL + codeptr=>3 = $02B0 // BCS +2 + codeptr=>5 = $C0D6+(VX<<8) // INC ESTKH,X codeptr = codeptr + 7 - A_IS_TOSL = TOSL_DIRTY + A_IS_TOSL = TOSL_DIRTY // STA ESTKL,X break is $3C // ANDI i++ //puts("ANDI $"); putb(^(bytecode+i)) if not A_IS_TOSL - *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin codeptr=>0 = $29+(^(bytecode+i)<<8) // AND #imm - //^codeptr = $29; codeptr++ // AND #imm - //^codeptr = ^(bytecode+i); codeptr++ - codeptr=>2 = $C094+(VX<<8) // STY ESTKH,X - //^codeptr = $94; codeptr++ // STY zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $D0+VX; codeptr++ // ESTKL + codeptr=>2 = $C094+(VX<<8) // STY ESTKH,X codeptr = codeptr + 4 - A_IS_TOSL = TOSL_DIRTY + A_IS_TOSL = TOSL_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 = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin codeptr=>0 = $09+(^(bytecode+i)<<8) // ORA #imm - //^codeptr = $09; codeptr++ // ORA #imm - //^codeptr = ^(bytecode+i); codeptr++ - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $D0+VX; codeptr++ // ESTKL codeptr = codeptr + 2 - A_IS_TOSL = TOSL_DIRTY + A_IS_TOSL = TOSL_DIRTY // STA ESTKL,X break is $40 // ISEQ //puts("ISEQ") if not A_IS_TOSL - *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - codeptr=>0 = ($D0D5+$0100)+(VX<<8) // CMP ESTKL+1,X - //^codeptr = $D5; codeptr++ // CMP zp,X - //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - codeptr=>2 = $07D0 // BNE +7 - //^codeptr = $D0; codeptr++ // BNE rel - //^codeptr = $07; codeptr++ // +7 - codeptr=>4 = $C0B5+(VX<<8) // LDA ESTKH,X - //^codeptr = $B5; codeptr++ // LDA zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH - codeptr=>6 = ($C0D5+$0100)+(VX<<8) // CMP ESTKH+1 - //^codeptr = $D5; codeptr++ // CMP zp,X - //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - codeptr=>8 = $01D0 // BNE +1 - //^codeptr = $D0; codeptr++ // BNE rel - //^codeptr = $01; codeptr++ // +1 - codeptr=>10 = $9888 // DEY TYA - //^codeptr = $88; codeptr++ // DEY - //^codeptr = $98; codeptr++ // TYA - codeptr=>12 = ($C094+$0100)+(VX<<8) // STY ESTKH+1,X - //^codeptr = $94; codeptr++ // STY zp,X - //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - codeptr=>14 = $00A0 // LDY #$00 - //^codeptr = $A0; codeptr++ // LDY #imm - //^codeptr = $00; codeptr++ // $00 - VX++ // INX - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $D0+VX; codeptr++ // ESTKL + codeptr=>0 = $D0D5+$0100+(VX<<8) // CMP ESTKL+1,X + codeptr=>2 = $07D0 // BNE +7 + codeptr=>4 = $C0B5+(VX<<8) // LDA ESTKH,X + codeptr=>6 = $C0D5+$0100+(VX<<8) // CMP ESTKH+1 + codeptr=>8 = $01D0 // BNE +1 + codeptr=>10 = $9888 // DEY; TYA + codeptr=>12 = $C094+$0100+(VX<<8) // STY ESTKH+1,X + codeptr=>14 = $00A0 // LDY #$00 + VX++ // INX codeptr = codeptr + 16 - A_IS_TOSL = TOSL_DIRTY + A_IS_TOSL = TOSL_DIRTY // STA ESTKL,X break is $42 // ISNE //puts("ISNE") if not A_IS_TOSL - *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - codeptr=>0 = ($D0D5+$0100)+(VX<<8) // CMP ESTKL+1,X - //^codeptr = $D5; codeptr++ // CMP zp,X - //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - codeptr=>2 = $06D0 // BNE +6 - //^codeptr = $D0; codeptr++ // BNE rel - //^codeptr = $06; codeptr++ // +6 - codeptr=>4 = $C0B5+(VX<<8) // LDA ESTKH,X - //^codeptr = $B5; codeptr++ // LDA zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH - codeptr=>6 = ($C0D5+$0100)+(VX<<8) // CMP ESTKH+1 - //^codeptr = $D5; codeptr++ // CMP zp,X - //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - codeptr=>8 = $01F0 // BEQ +1 - //^codeptr = $F0; codeptr++ // BEQ rel - //^codeptr = $01; codeptr++ // +1 - codeptr=>10 = $9888 // DEY TYA - //^codeptr = $88; codeptr++ // DEY - //^codeptr = $98; codeptr++ // TYA - codeptr=>12 = ($C094+$0100)+(VX<<8) // STY ESTKH+1,X - //^codeptr = $94; codeptr++ // STY zp,X - //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - codeptr=>14 = $00A0 // LDY #$00 - //^codeptr = $A0; codeptr++ // LDY #imm - //^codeptr = $00; codeptr++ // $00 - VX++ // INX - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $D0+VX; codeptr++ // ESTKL + codeptr=>0 = $D0D5+$0100+(VX<<8) // CMP ESTKL+1,X + codeptr=>2 = $06D0 // BNE +6 + codeptr=>4 = $C0B5+(VX<<8) // LDA ESTKH,X + codeptr=>6 = $C0D5+$0100+(VX<<8) // CMP ESTKH+1 + codeptr=>8 = $01F0 // BEQ +1 + codeptr=>10 = $9888 // DEY; TYA + codeptr=>12 = $C094+$0100+(VX<<8) // STY ESTKH+1,X + codeptr=>14 = $00A0 // LDY #$00 + VX++ // INX codeptr = codeptr + 16 - A_IS_TOSL = TOSL_DIRTY + A_IS_TOSL = TOSL_DIRTY // STA ESTKL,X break is $44 // ISGT //puts("ISGT") if not A_IS_TOSL - *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - codeptr=>0 = ($D0D5+$0100)+(VX<<8) // CMP ESTKL+1,X - //^codeptr = $D5; codeptr++ // CMP zp,X - //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - codeptr=>2 = $C0B5+(VX<<8) // LDA ESTKH,X - //^codeptr = $B5; codeptr++ // LDA zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH - codeptr=>4 = ($C0F5+$0100)+(VX<<8) // SBC ESTKH+1 - //^codeptr = $F5; codeptr++ // SBC zp,X - //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - codeptr=>6 = $0250 // BVC +2 - //^codeptr = $50; codeptr++ // BVC rel - //^codeptr = $02; codeptr++ // +2 - codeptr=>8 = $8049 // EOR #$80 - //^codeptr = $49; codeptr++ // EOR #imm - //^codeptr = $80; codeptr++ // $80 - codeptr=>10 = $0110 // BPL +1 - //^codeptr = $10; codeptr++ // BPL rel - //^codeptr = $01; codeptr++ // +1 - codeptr=>12 = $9888 // DEY TYA - //^codeptr = $88; codeptr++ // DEY - //^codeptr = $98; codeptr++ // TYA - codeptr=>14 = ($C094+$0100)+(VX<<8) // STY ESTKH+1,X - //^codeptr = $94; codeptr++ // STY zp,X - //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - codeptr=>16 = $00A0 // LDY #$00 - //^codeptr = $A0; codeptr++ // LDY #imm - //^codeptr = $00; codeptr++ // $00 - VX++ // INX - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $D0+VX; codeptr++ // ESTKL + codeptr=>0 = $D0D5+$0100+(VX<<8) // CMP ESTKL+1,X + codeptr=>2 = $C0B5+(VX<<8) // LDA ESTKH,X + codeptr=>4 = $C0F5+$0100+(VX<<8) // SBC ESTKH+1 + codeptr=>6 = $0250 // BVC +2 + codeptr=>8 = $8049 // EOR #$80 + codeptr=>10 = $0110 // BPL +1 + codeptr=>12 = $9888 // DEY TYA + codeptr=>14 = $C094+$0100+(VX<<8) // STY ESTKH+1,X + codeptr=>16 = $00A0 // LDY #$00 + VX++ // INX codeptr = codeptr + 18 - A_IS_TOSL = TOSL_DIRTY + A_IS_TOSL = TOSL_DIRTY // STA ESTKL,X break is $46 //puts("ISLT") if A_IS_TOSL & TOSL_DIRTY - *codeptr = $D095+(VX<<8) // STA ESTKL,X + *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin - codeptr=>0 = ($D0B5+$0100)+(VX<<8) // LDA ESTKL+1,X - //^codeptr = $B5; codeptr++ // LDA zp,X - //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - codeptr=>2 = $D0D5+(VX<<8) // CMP ESTKL,X - //^codeptr = $D5; codeptr++ // CMP zp,X - //^codeptr = $D0+VX; codeptr++ // ESTKL - codeptr=>4 = ($C0B5+$0100)+(VX<<8) // LDA ESTKH+1,X - //^codeptr = $B5; codeptr++ // LDA zp,X - //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - codeptr=>6 = $C0F5+(VX<<8) // SBC ESTKH - //^codeptr = $F5; codeptr++ // SBC zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH - codeptr=>8 = $0250 // BVC +2 - //^codeptr = $50; codeptr++ // BVC rel - //^codeptr = $02; codeptr++ // +2 - codeptr=>10 = $8049 // EOR #$80 - //^codeptr = $49; codeptr++ // EOR #imm - //^codeptr = $80; codeptr++ // $80 - codeptr=>12 = $0110 // BPL +1 - //^codeptr = $10; codeptr++ // BPL rel - //^codeptr = $01; codeptr++ // +1 - codeptr=>14 = $9888 // DEY TYA - //^codeptr = $88; codeptr++ // DEY - //^codeptr = $98; codeptr++ // TYA - codeptr=>16 = ($C094+$0100)+(VX<<8) // STY ESTKH+1,X - //^codeptr = $94; codeptr++ // STY zp,X - //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - codeptr=>18 = $00A0 // LDY #$00 - //^codeptr = $A0; codeptr++ // LDY #imm - //^codeptr = $00; codeptr++ // $00 - VX++ // INX - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $D0+VX; codeptr++ // ESTKL + codeptr=>0 = $D0B5+$0100+(VX<<8) // LDA ESTKL+1,X + codeptr=>2 = $D0D5+(VX<<8) // CMP ESTKL,X + codeptr=>4 = $C0B5+$0100+(VX<<8) // LDA ESTKH+1,X + codeptr=>6 = $C0F5+(VX<<8) // SBC ESTKH + codeptr=>8 = $0250 // BVC +2 + codeptr=>10 = $8049 // EOR #$80 + codeptr=>12 = $0110 // BPL +1 + codeptr=>14 = $9888 // DEY; TYA + codeptr=>16 = $C094+$0100+(VX<<8) // STY ESTKH+1,X + codeptr=>18 = $00A0 // LDY #$00 + VX++ // INX codeptr = codeptr + 20 - A_IS_TOSL = TOSL_DIRTY + A_IS_TOSL = TOSL_DIRTY // STA ESTKL,X break is $48 //puts("ISGE") if A_IS_TOSL & TOSL_DIRTY - *codeptr = $D095+(VX<<8) // STA ESTKL,X + *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin - codeptr=>0 = ($D0B5+$0100)+(VX<<8) // LDA ESTKL+1,X - //^codeptr = $B5; codeptr++ // LDA zp,X - //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - codeptr=>2 = $D0D5+(VX<<8) // CMP ESTKL,X - //^codeptr = $D5; codeptr++ // CMP zp,X - //^codeptr = $D0+VX; codeptr++ // ESTKL - codeptr=>4 = ($C0B5+$0100)+(VX<<8) // LDA ESTKH+1,X - //^codeptr = $B5; codeptr++ // LDA zp,X - //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - codeptr=>6 = $C0F5+(VX<<8) // SBC ESTKH - //^codeptr = $F5; codeptr++ // SBC zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH - codeptr=>8 = $0250 // BVC +2 - //^codeptr = $50; codeptr++ // BVC rel - //^codeptr = $02; codeptr++ // +2 - codeptr=>10 = $8049 // EOR #$80 - //^codeptr = $49; codeptr++ // EOR #imm - //^codeptr = $80; codeptr++ // $80 - codeptr=>12 = $0130 // BMI +1 - //^codeptr = $30; codeptr++ // BMI rel - //^codeptr = $01; codeptr++ // +1 - codeptr=>14 = $9888 // DEY TYA - //^codeptr = $88; codeptr++ // DEY - //^codeptr = $98; codeptr++ // TYA - codeptr=>16 = ($C094+$0100)+(VX<<8) // STY ESTKH+1,X - //^codeptr = $94; codeptr++ // STY zp,X - //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - codeptr=>18 = $00A0 // LDY #$00 - //^codeptr = $A0; codeptr++ // LDY #imm - //^codeptr = $00; codeptr++ // $00 - VX++ // INX - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $D0+VX; codeptr++ // ESTKL + codeptr=>0 = $D0B5+$0100+(VX<<8) // LDA ESTKL+1,X + codeptr=>2 = $D0D5+(VX<<8) // CMP ESTKL,X + codeptr=>4 = $C0B5+$0100+(VX<<8) // LDA ESTKH+1,X + codeptr=>6 = $C0F5+(VX<<8) // SBC ESTKH + codeptr=>8 = $0250 // BVC +2 + codeptr=>10 = $8049 // EOR #$80 + codeptr=>12 = $0130 // BMI +1 + codeptr=>14 = $9888 // DEY; TYA + codeptr=>16 = $C094+$0100+(VX<<8) // STY ESTKH+1,X + codeptr=>18 = $00A0 // LDY #$00 + VX++ // INX codeptr = codeptr + 20 - A_IS_TOSL = TOSL_DIRTY + A_IS_TOSL = TOSL_DIRTY // STA ESTKL,X break is $4A // ISLE //puts("ISLE") if not A_IS_TOSL - *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - codeptr=>0 = ($D0D5+$0100)+(VX<<8) // CMP ESTKL+1,X - //^codeptr = $D5; codeptr++ // CMP zp,X - //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - codeptr=>2 = $C0B5+(VX<<8) // LDA ESTKH,X - //^codeptr = $B5; codeptr++ // LDA zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH - codeptr=>4 = ($C0F5+$0100)+(VX<<8) // SBC ESTKH+1 - //^codeptr = $F5; codeptr++ // SBC zp,X - //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - codeptr=>6 = $0250 // BVC +2 - //^codeptr = $50; codeptr++ // BVC rel - //^codeptr = $02; codeptr++ // +2 - codeptr=>8 = $8049 // EOR #$80 - //^codeptr = $49; codeptr++ // EOR #imm - //^codeptr = $80; codeptr++ // $80 - codeptr=>10 = $0130 // BMI +1 - //^codeptr = $30; codeptr++ // BMI rel - //^codeptr = $01; codeptr++ // +1 - codeptr=>12 = $9888 // DEY TYA - //^codeptr = $88; codeptr++ // DEY - //^codeptr = $98; codeptr++ // TYA - codeptr=>14 = ($C094+$0100)+(VX<<8) // STY ESTKH+1,X - //^codeptr = $94; codeptr++ // STY zp,X - //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - codeptr=>16 = $00A0 // LDY #$00 - //^codeptr = $A0; codeptr++ // LDY #imm - //^codeptr = $00; codeptr++ // $00 - VX++ // INX - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $D0+VX; codeptr++ // ESTKL + codeptr=>0 = $D0D5+$0100+(VX<<8) // CMP ESTKL+1,X + codeptr=>2 = $C0B5+(VX<<8) // LDA ESTKH,X + codeptr=>4 = $C0F5+$0100+(VX<<8) // SBC ESTKH+1 + codeptr=>6 = $0250 // BVC +2 + codeptr=>8 = $8049 // EOR #$80 + codeptr=>10 = $0130 // BMI +1 + codeptr=>12 = $9888 // DEY; TYA + codeptr=>14 = $C094+$0100+(VX<<8) // STY ESTKH+1,X + codeptr=>16 = $00A0 // LDY #$00 + VX++ // INX codeptr = codeptr + 18 - A_IS_TOSL = TOSL_DIRTY + A_IS_TOSL = TOSL_DIRTY // STA ESTKL,X break is $4C // BRFLS i++ dest = i + *(bytecode+i) i++ //puts("BRFLS "); puti(dest) - codeptr, VX = resolveX(codeptr, VX + 1) //VX++ // INX + codeptr, VX = resolveX(codeptr, VX + 1) // INX if not A_IS_TOSL - *codeptr = ($D0B5-$0100)+(VX<<8) // LDA ESTKL-1,X + *codeptr = $D0B5-$0100//+(VX<<8) // LDA ESTKL-1,X codeptr = codeptr + 2 fin - codeptr=>0 = ($C015-$0100)+(VX<<8) // ORA ESTKH-1,X - //^codeptr = $15; codeptr++ // ORA zp,X - //^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 - codeptr=>2 = $03D0 // BNE +3 - //^codeptr = $D0; codeptr++ // BNE rel - //^codeptr = $03; codeptr++ // +3 - codeptr->4 = $4C // JMP abs - //^codeptr = $4C; codeptr++ // JMP abs + codeptr=>0 = $C015-$0100//+(VX<<8) // ORA ESTKH-1,X + codeptr=>2 = $03D0 // BNE +3 + codeptr->4 = $4C // JMP abs codeptr=>5 = addrxlate=>[dest] - //*codeptr = addrxlate=>[dest] if not (codeptr->6 & $80) // Unresolved address list - //if not (*codeptr & $8000) // Unresolved address list addrxlate=>[dest] = codeptr + 5 - *jitcodeptr - //addrxlate=>[dest] = codeptr - *jitcodeptr fin codeptr = codeptr + 7 - //codeptr = codeptr + 2 A_IS_TOSL = FALSE break is $4E // BRTRU @@ -897,28 +639,19 @@ def compiler(defptr)#0 dest = i + *(bytecode+i) i++ //puts("BRTRU "); puti(dest) - codeptr, VX = resolveX(codeptr, VX + 1) //VX++ // INX + codeptr, VX = resolveX(codeptr, VX + 1) // INX if not A_IS_TOSL - *codeptr = ($D0B5-$0100)+(VX<<8) // LDA ESTKL-1,X + *codeptr = $D0B5-$0100//+(VX<<8) // LDA ESTKL-1,X codeptr = codeptr + 2 fin - codeptr=>0 = ($C015-$0100)+(VX<<8) // ORA ESTKH-1,X - //^codeptr = $15; codeptr++ // ORA zp,X - //^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 - codeptr=>2 = $03F0 // BEQ +3 - //^codeptr = $F0; codeptr++ // BEQ rel - //^codeptr = $03; codeptr++ // +3 - codeptr->4 = $4C // JMP abs - //^codeptr = $4C; codeptr++ // JMP abs + codeptr=>0 = $C015-$0100//+(VX<<8) // ORA ESTKH-1,X + codeptr=>2 = $03F0 // BEQ +3 + codeptr->4 = $4C // JMP abs codeptr=>5 = addrxlate=>[dest] - //*codeptr = addrxlate=>[dest] if not (codeptr->6 & $80) // Unresolved address list - //if not (*codeptr & $8000) // Unresolved address list addrxlate=>[dest] = codeptr + 5 - *jitcodeptr - //addrxlate=>[dest] = codeptr - *jitcodeptr fin codeptr = codeptr + 7 - //codeptr = codeptr + 2 A_IS_TOSL = FALSE break is $50 // BRNCH @@ -928,20 +661,15 @@ def compiler(defptr)#0 //puts("BRNCH "); puti(dest) codeptr, VX = resolveX(codeptr, VX) if A_IS_TOSL & TOSL_DIRTY - *codeptr = $D095+(VX<<8) // STA ESTKL,X + *codeptr = $D095//+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin - codeptr->0 = $4C // JMP abs - //^codeptr = $4C; codeptr++ // JMP abs + codeptr->0 = $4C // JMP abs codeptr=>1 = addrxlate=>[dest] - //*codeptr = addrxlate=>[dest] if not (codeptr->2 & $80) // Unresolved address list - //if not (*codeptr & $8000) // Unresolved address list addrxlate=>[dest] = codeptr + 1 - *jitcodeptr - //addrxlate=>[dest] = codeptr - *jitcodeptr fin codeptr = codeptr + 3 - //codeptr = codeptr + 2 A_IS_TOSL = FALSE break is $52 // SEL @@ -950,69 +678,45 @@ def compiler(defptr)#0 i++ //puts("SEL "); puti(case); putln j = ^(bytecode+case) - dest = codeptr + 8 + case * 11) + 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 = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - codeptr=>0 = $C0B4+(VX<<8) // LDY ESTKH,X - //^codeptr = $B4; codeptr++ // LDY zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH - codeptr = codeptr + 2 - codeptr, VX = resolveX(codeptr, VX + 1) // INX + codeptr=>0 = $C0B4+(VX<<8) // LDY ESTKH,X + codeptr, VX = resolveX(codeptr + 2, VX + 1) // INX repeat - //puts(" $"); puth(*(bytecode+case)) - codeptr=>0 = $C9+(^(bytecode+case)<<8) // CMP #imm - //^codeptr = $C9; codeptr++ // CMP #imm - //^codeptr = ^(bytecode+case); codeptr++ - codeptr=>2 = $09D0 // BNE +9 - //^codeptr = $D0; codeptr++ // BNE rel - //^codeptr = $09; codeptr++ // +9 - codeptr=>4 = $C0+(^(bytecode+case+1)<<8) // CPY #imm - //^codeptr = $C0; codeptr++ // CPY #imm - //^codeptr = ^(bytecode+case+1); codeptr++ - codeptr=>6 = $05D0 // BNE +5 - //^codeptr = $D0; codeptr++ // BNE rel - //^codeptr = $05; codeptr++ // +5 + dest = case + *(bytecode+case) + //puts(" $"); puth(dest) + codeptr=>0 = $C9+(dest<<8) // CMP #imm + codeptr=>2 = $09D0 // BNE +9 + codeptr=>4 = $C0+(dest&$FF00) // CPY #imm + codeptr=>6 = $05D0 // BNE +5 *(bytecode+case) = $FEFE case = case + 2 dest = case + *(bytecode+case) //puts("-->"); puti(dest); putln - codeptr=>8 = $00A0 // LDY #$00 - //^codeptr = $A0; codeptr++ // LDY #imm - //^codeptr = $00; codeptr++ // $00 - codeptr->10 = $4C // JMP abs - //^codeptr = $4C; codeptr++ // JMP abs + codeptr=>8 = $00A0 // LDY #$00 + codeptr->10 = $4C // JMP abs codeptr=>11 = addrxlate=>[dest] - //*codeptr = addrxlate=>[dest] if not (codeptr->12 & $80) // Unresolved address list - //if not (*codeptr & $8000) // Unresolved address list addrxlate=>[dest] = codeptr + 11 - *jitcodeptr - //addrxlate=>[dest] = codeptr - *jitcodeptr fin codeptr = codeptr + 13 - //codeptr = codeptr + 2 *(bytecode+case) = $FEFE case = case + 2 j-- until not j - codeptr=>0 = $00A0 // LDY #$00 - //^codeptr = $A0; codeptr++ // LDY #imm - //^codeptr = $00; codeptr++ // $00 - codeptr->1 = $4C // JMP abs - //^codeptr = $4C; codeptr++ // JMP abs + codeptr=>0 = $00A0 // LDY #$00 + codeptr->1 = $4C // JMP abs codeptr=>2 = addrxlate=>[case] - //*codeptr = addrxlate=>[case] if not (codeptr->3 & $80) // Unresolved address list - //if not (*codeptr & $8000) // Unresolved address list - addrxlate=>[case] = codeptr + 2- *jitcodeptr - //addrxlate=>[case] = codeptr - *jitcodeptr + addrxlate=>[case] = codeptr + 2 - *jitcodeptr fin codeptr = codeptr + 4 - //codeptr = codeptr + 2 else codeptr = dest fin @@ -1024,18 +728,14 @@ def compiler(defptr)#0 // // Call address // + codeptr, VX = resolveX(codeptr, VX) if A_IS_TOSL & TOSL_DIRTY - *codeptr = $D095+(VX<<8) // STA ESTKL,X + *codeptr = $D095//+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin - codeptr, VX = resolveX(codeptr, VX) - codeptr->0 = $20 // JSR abs - //^codeptr = $20; codeptr++ // JSR abs + codeptr->0 = $20 // JSR abs codeptr=>1 = *(bytecode+i) - //*codeptr = *(bytecode+i); codeptr = codeptr + 2 - codeptr=>3 = $00A0 // LDY #$00 - //^codeptr = $A0; codeptr++ // LDY #imm - //^codeptr = $00; codeptr++ // $00 + codeptr=>3 = $00A0 // LDY #$00 codeptr = codeptr + 5 A_IS_TOSL = FALSE i++ @@ -1046,32 +746,19 @@ def compiler(defptr)#0 // Pull address off stack // if not A_IS_TOSL - *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - codeptr=>0 = $E785 // STA $E7:TMPL - //^codeptr = $85; codeptr++ // STA zp - //^codeptr = $E7; codeptr++ // $E7:TMPL - codeptr=>2 = $C0B5+(VX<<8) // LDA ESTKH,X - //^codeptr = $B5; codeptr++ // LDA zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH - codeptr=>4 = $E885 // STA $E8:TMPH - //^codeptr = $85; codeptr++ // STA zp - //^codeptr = $E8; codeptr++ // $E8:TMPH - //^codeptr = $E8; codeptr++ // INX - codeptr = codeptr + 6 + 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, VX = resolveX(codeptr, VX + 1) // INX - codeptr->0 = $20 // JSR abs - //^codeptr = $20; codeptr++ // JSR abs - codeptr=>1 = $00E6 // JMPTMP - //^codeptr = $E6; codeptr++ // JMPTMP - codeptr=>3 = $00A0 // LDY #$00 - //^codeptr = $A0; codeptr++ // LDY #imm - //^codeptr = $00; codeptr++ // $00 + codeptr->0 = $20 // JSR abs + codeptr=>1 = $00E6 // $E6:JMPTMP + codeptr=>3 = $00A0 // LDY #$00 codeptr = codeptr + 5 A_IS_TOSL = FALSE break @@ -1081,178 +768,120 @@ def compiler(defptr)#0 // // Call into VM // + codeptr, VX = resolveX(codeptr, VX) if A_IS_TOSL & TOSL_DIRTY - *codeptr = $D095+(VX<<8) // STA ESTKL,X + *codeptr = $D095//+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin - codeptr, VX = resolveX(codeptr, VX) - codeptr->0 = $20 // JSR abs - //^codeptr = $20; codeptr++ // JSR INTERP - codeptr=>1 = $03D0 // INTERP - //*codeptr = $3D0; codeptr = codeptr + 2 + codeptr->0 = $20 // JSR abs + codeptr=>1 = $03D0 // INTERP codeptr=>3 = $5A + (^(bytecode+i)<<8) // LEAVE CODE AND OPERAND - //^codeptr = $5A; codeptr++ // LEAVE CODE - //^codeptr = ^(bytecode+i); codeptr++ // LEAVE OPERAND codeptr = codeptr + 5 A_IS_TOSL = FALSE break is $5C // RET //puts("RET") + codeptr, VX = resolveX(codeptr, VX) if A_IS_TOSL & TOSL_DIRTY - *codeptr = $D095+(VX<<8) // STA ESTKL,X + *codeptr = $D095//+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin - codeptr, VX = resolveX(codeptr, VX) - ^codeptr = $60 //RTS + ^codeptr = $60 // RTS codeptr++ - A_IS_TOSL = FALSE + A_IS_TOSL = FALSE break is $5E // CFFB i++ //puts("CFFB $FF"); putb(^(bytecode+i)) if A_IS_TOSL & TOSL_DIRTY - *codeptr = $D095+(VX<<8) // STA ESTKL,X + *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin - VX-- // DEX - codeptr=>0 = $FFA9 // LDA #$FF - //^codeptr = $A9; codeptr++ // LDA #imm - //^codeptr = $FF; codeptr++ // $FF - codeptr=>2 = $C095+(VX<<8) // STA ESTKH,X - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH + VX-- // DEX + codeptr=>0 = $FFA9 // LDA #$FF + codeptr=>2 = $C095+(VX<<8) // STA ESTKH,X codeptr=>4 = $A9+(^(bytecode+i)<<8) // LDA #imm - //^codeptr = $A9; codeptr++ // LDA #imm - //^codeptr = ^(bytecode+i); codeptr++ - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $D0+VX; codeptr++ // ESTKL codeptr = codeptr + 6 - A_IS_TOSL = TOSL_DIRTY + A_IS_TOSL = TOSL_DIRTY // STA ESTKL,X break is $60 // LB //puts("LB") if not A_IS_TOSL - *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - codeptr=>0 = ($C095-$0100)+(VX<<8) // STA ESTKH-1,X - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 - codeptr=>2 = ($C0A1-$0100)+(VX<<8) // LDA (ESTKH-1,X) - //^codeptr = $A1; codeptr++ // LDA (zp,X) - //^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 - codeptr=>4 = $C094+(VX<<8) // STY ESTKH,X - //^codeptr = $94; codeptr++ // STY zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $D0+VX; codeptr++ // ESTKL + 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 = TOSL_DIRTY + A_IS_TOSL = TOSL_DIRTY // STA ESTKL,X break is $62 // LW //puts("LW") if not A_IS_TOSL - *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - codeptr=>0 = ($C095-$0100)+(VX<<8) // STA ESTKH-1,X - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 - codeptr=>2 = ($C0A1-$0100)+(VX<<8) // LDA (ESTKH-1,X) - //^codeptr = $A1; codeptr++ // LDA (zp,X) - //^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 - codeptr=>4 = $D095+(VX<<8) // STA ESTKL,X - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $D0+VX; codeptr++ // ESTKL - codeptr=>6 = ($C0F6-$0100)+(VX<<8) // INC ESTKH-1,X - //^codeptr = $F6; codeptr++ // INC zp,X - //^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 - codeptr=>8 = $02D0 // BNE +2 - //^codeptr = $D0; codeptr++ // BNE rel - //^codeptr = $02; codeptr++ // +2 - codeptr=>10 = $C0F6+(VX<<8) // INC ESTKH,X - //^codeptr = $F6; codeptr++ // INC zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH - codeptr=>12 = ($C0A1-$0100)+(VX<<8) // LDA (ESTKH-1,X) - //^codeptr = $A1; codeptr++ // LDA (zp,X) - //^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 - codeptr=>14 = $C095+(VX<<8) // STA ESTKH,X - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH + 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++ - //puts("LLB "); puti(^(bytecode+i)) + j = ^(bytecode+i) + //puts("LLB "); puti(j) if A_IS_TOSL & TOSL_DIRTY - *codeptr = $D095+(VX<<8) // STA ESTKL,X + *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin - VX-- // DEX - if ^(bytecode+i) <> 0 - *codeptr = $A0+(^(bytecode+i)<<8) // LDY #imm + VX-- // DEX + if j + *codeptr = $A0+(j<<8) // LDY #imm codeptr = codeptr + 2 - //^codeptr = $A0; codeptr++ // LDY #imm - //^codeptr = ^(bytecode+i); codeptr++ fin - *codeptr = $E0B1 // LDA (IFP),Y + *codeptr = $E0B1 // LDA (IFP),Y codeptr = codeptr + 2 - //^codeptr = $B1; codeptr++ // LDA (zp),Y - //^codeptr = $E0; codeptr++ // IFP - if ^(bytecode+i) <> 0 - *codeptr = $00A0 // LDY #$00 + if j + *codeptr = $00A0 // LDY #$00 codeptr = codeptr + 2 - //^codeptr = $A0; codeptr++ // LDY #imm - //^codeptr = $00; codeptr++ // $00 fin - *codeptr = $C094+(VX<<8) // STY ESTKH,X - //^codeptr = $94; codeptr++ // STY zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $D0+VX; codeptr++ // ESTKL + *codeptr = $C094+(VX<<8) // STY ESTKH,X codeptr = codeptr + 2 - A_IS_TOSL = TOSL_DIRTY + A_IS_TOSL = TOSL_DIRTY // STA ESTKL,X break is $66 // LLW i++ - //puts("LLW "); puti(^(bytecode+i)) + j = ^(bytecode+i) + //puts("LLW "); puti(j) if A_IS_TOSL & TOSL_DIRTY - *codeptr = $D095+(VX<<8) // STA ESTKL,X + *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin - VX-- // DEX - if ^(bytecode+i) <> 0 - *codeptr = $A0+(^(bytecode+i)<<8) // LDY #imm + VX-- // DEX + if j + *codeptr = $A0+((j+1)<<8) // LDY #imm codeptr = codeptr + 2 - //^codeptr = $A0; codeptr++ // LDY #imm - //^codeptr = ^(bytecode+i); codeptr++ - fin - codeptr=>0 = $E0B1 // LDA (IFP),Y - //^codeptr = $B1; codeptr++ // LDA (zp),Y - //^codeptr = $E0; codeptr++ // IFP - codeptr=>2 = $D095+(VX<<8) // STA ESTKL,X - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $D0+VX; codeptr++ // ESTKL - codeptr->4 = $C8 // INY - //^codeptr = $C8; codeptr++ // INY - codeptr=>5 = $E0B1 // LDA (IFP),Y - //^codeptr = $B1; codeptr++ // LDA (zp),Y - //^codeptr = $E0; codeptr++ // IFP - codeptr=>7 = $C095+(VX<<8) // STA ESTKH,X - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH - if ^(bytecode+i) <> 0 - codeptr=>9 = $00A0 // LDY #$00 - codeptr = codeptr + 11 - //^codeptr = $A0; codeptr++ // LDY #imm - //^codeptr = $00; codeptr++ // $00 else - codeptr->9 = $88 // DEY - codeptr = codeptr + 10 - //^codeptr = $88; codeptr++ // DEY + ^codeptr = $C8; codeptr++ // INY fin - A_IS_TOSL = FALSE + 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 + if j + *codeptr = $00A0 // LDY #$00 + codeptr = codeptr + 2 + else + fin + A_IS_TOSL = TOSL_DIRTY // STA ESTKL,X break is $68 // LAB i++ @@ -1261,227 +890,155 @@ def compiler(defptr)#0 *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin - VX-- // DEX - codeptr->0 = $AD // LDA abs - //^codeptr = $AD; codeptr++ // LDA abs + VX-- // DEX + codeptr->0 = $AD // LDA abs codeptr=>1 = *(bytecode+i) - //*codeptr = *(bytecode+i); codeptr = codeptr + 2 - codeptr=>3 = $C094+(VX<<8) // STY ESTKH,X - //^codeptr = $94; codeptr++ // STY zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $D0+VX; codeptr++ // ESTKL - codeptr = codeptr + 5 - A_IS_TOSL = TOSL_DIRTY + codeptr=>3 = $C094+(VX<<8) // STY ESTKH,X + codeptr = codeptr + 5 + A_IS_TOSL = TOSL_DIRTY // STA ESTKL,X i++ break is $6A // LAW i++ - //puts("LAW $"); puth(*(bytecode+i)) + dest = *(bytecode+i) + //puts("LAW $"); puth(dest) if A_IS_TOSL & TOSL_DIRTY *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin - VX-- // DEX - codeptr->0 = $AD // LDA abs - //^codeptr = $AD; codeptr++ // LDA abs - codeptr=>1 = *(bytecode+i)+1 - //*codeptr = *(bytecode+i)+1; codeptr = codeptr + 2 - codeptr=>3 = $C095+(VX<<8) // STA ESTKH,X - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH - codeptr->5 = $AD // LDA abs - //^codeptr = $AD; codeptr++ // LDA abs - codeptr=>6 = *(bytecode+i) - //*codeptr = *(bytecode+i); codeptr = codeptr + 2 - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $D0+VX; codeptr++ // ESTKL - codeptr = codeptr + 8 - A_IS_TOSL = TOSL_DIRTY + VX-- // DEX + codeptr->0 = $AD // LDA abs + codeptr=>1 = dest+1 + codeptr=>3 = $C095+(VX<<8) // STA ESTKH,X + codeptr->5 = $AD // LDA abs + codeptr=>6 = dest + codeptr = codeptr + 8 + A_IS_TOSL = TOSL_DIRTY // STA ESTKL,X i++ break is $6C // DLB i++ - //puts("DLB "); puti(^(bytecode+i)) + j = ^(bytecode+i) + //puts("DLB "); puti(j) if not A_IS_TOSL *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 A_IS_TOSL = TOSL_CLEAN fin - if ^(bytecode+i) <> 0 - *codeptr = $A0+(^(bytecode+i)<<8) // LDY #imm + if j + *codeptr = $A0+(j<<8) // LDY #imm codeptr = codeptr + 2 - //^codeptr = $A0; codeptr++ // LDY #imm - //^codeptr = ^(bytecode+i); codeptr++ fin - *codeptr = $E091 // STA (IFP),Y + *codeptr = $E091 // STA (IFP),Y codeptr = codeptr + 2 - //^codeptr = $91; codeptr++ // STA (zp),Y - //^codeptr = $E0; codeptr++ // IFP - if ^(bytecode+i) <> 0 - *codeptr = $00A0 // LDY #$00 + if j + *codeptr = $00A0 // LDY #$00 codeptr = codeptr + 2 - //^codeptr = $A0; codeptr++ // LDY #imm - //^codeptr = $00; codeptr++ // $00 fin break is $6E // DLW i++ - //puts("DLW "); puti(^(bytecode+i)) + j = ^(bytecode+i) + //puts("DLW "); puti(j) if A_IS_TOSL & TOSL_DIRTY - *codeptr = $D095+(VX<<8) // STA ESTKL,X + *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin - if ^(bytecode+i) <> 0 - *codeptr = $A0+((^(bytecode+i)+1)<<8) // LDY #imm + if j + *codeptr = $A0+((j+1)<<8) // LDY #imm codeptr = codeptr + 2 - //^codeptr = $A0; codeptr++ // LDY #imm - //^codeptr = ^(bytecode+i)+1; codeptr++ else - ^codeptr = $C8; codeptr++ // INY + ^codeptr = $C8; codeptr++ // INY fin - codeptr=>0 = $C0B5+(VX<<8) // LDA ESTKH,X - //^codeptr = $B5; codeptr++ // LDA zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH - codeptr=>2 = $E091 // STA (IFP),Y - //^codeptr = $91; codeptr++ // STA (zp),Y - //^codeptr = $E0; codeptr++ // IFP - codeptr->4 = $88 // DEY - //^codeptr = $88; codeptr++ // DEY - codeptr=>5 = $D0B5+(VX<<8) // LDA ESTKL,X - //^codeptr = $B5; codeptr++ // LDA zp,X - //^codeptr = $D0+VX; codeptr++ // ESTKL - codeptr=>7 = $E091 // STA (IFP),Y - //^codeptr = $91; codeptr++ // STA (zp),Y - //^codeptr = $E0; codeptr++ // IFP + 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 - if ^(bytecode+i) <> 0 - *codeptr = $00A0 // LDY #$00 + if j + *codeptr = $00A0 // LDY #$00 codeptr = codeptr + 2 - //^codeptr = $A0; codeptr++ // LDY #imm - //^codeptr = $00; codeptr++ // $00 fin - A_IS_TOSL = TOSL_CLEAN + A_IS_TOSL = TOSL_CLEAN break is $70 // SB //puts("SB") if not A_IS_TOSL - *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - codeptr=>0 = ($C095-$0100)+(VX<<8) // STA ESTKH-1,X - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 - codeptr=>2 = ($D0B5+$0100)+(VX<<8) // LDA ESTKL+1,X - //^codeptr = $B5; codeptr++ // LDA zp,X - //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - codeptr=>4 = ($C081-$0100)+(VX<<8) // STA (ESTKH-1,X) - //^codeptr = $81; codeptr++ // STA (zp,X) - //^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 - //^codeptr = $E8; codeptr++ // INX - //^codeptr = $E8; codeptr++ // INX - VX = VX + 2 // INX INX + 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) + VX = VX + 2 // INX; INX codeptr = codeptr + 6 A_IS_TOSL = FALSE break is $72 // SW //puts("SW") if not A_IS_TOSL - *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - codeptr=>0 = ($C095-$0100)+(VX<<8) // STA ESTKH-1,X - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 - codeptr=>2 = ($D0B5+$0100)+(VX<<8) // LDA ESTKL+1,X - //^codeptr = $B5; codeptr++ // LDA zp,X - //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - codeptr=>4 = ($C081-$0100)+(VX<<8) // STA (ESTKH-1,X) - //^codeptr = $81; codeptr++ // STA (zp,X) - //^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 - codeptr=>6 = ($C0B5+$0100)+(VX<<8) // LDA ESTKH+1,X - //^codeptr = $B5; codeptr++ // LDA zp,X - //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - codeptr=>8 = ($C0F6-$0100)+(VX<<8) // INC ESTKH-1,X - //^codeptr = $F6; codeptr++ // INC zp,X - //^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 - codeptr=>10 = $02D0 // BNE +2 - //^codeptr = $D0; codeptr++ // BNE rel - //^codeptr = $02; codeptr++ // +2 - codeptr=>12 = $C0F6+(VX<<8) // INC ESTKH,X - //^codeptr = $F6; codeptr++ // INC zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH - codeptr=>14 = ($C081-$0100)+(VX<<8) // STA (ESTKH-1,X) - //^codeptr = $81; codeptr++ // STA (zp,X) - //^codeptr = $C0-1+VX; codeptr++ // ESTKH-1 - //^codeptr = $E8; codeptr++ // INX - //^codeptr = $E8; codeptr++ // INX - VX = VX + 2 // INX INX + codeptr=>0 = $C095-$0100+(VX<<8) // STA ESTKH-1,X + codeptr=>2 = $D0B5+$0100+(VX<<8) // LDA ESTKL+1,X + codeptr=>4 = $C081-$0100+(VX<<8) // STA (ESTKH-1,X) + codeptr=>6 = $C0B5+$0100+(VX<<8) // LDA ESTKH+1,X + codeptr=>8 = $C0F6-$0100+(VX<<8) // INC ESTKH-1,X + codeptr=>10 = $02D0 // BNE +2 + codeptr=>12 = $C0F6+(VX<<8) // INC ESTKH,X + codeptr=>14 = $C081-$0100+(VX<<8) // STA (ESTKH-1,X) + VX = VX + 2 // INX; INX codeptr = codeptr + 16 A_IS_TOSL = FALSE break is $74 // SLB i++ - //puts("SLB "); puti(^(bytecode+i)) + j = ^(bytecode+i) + //puts("SLB "); puti(j) if not A_IS_TOSL *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - if ^(bytecode+i) <> 0 - *codeptr = $A0+(^(bytecode+i)<<8) // LDY #imm + if j + *codeptr = $A0+(j<<8) // LDY #imm codeptr = codeptr + 2 - //^codeptr = $A0; codeptr++ // LDY #imm - //^codeptr = ^(bytecode+i); codeptr++ fin - *codeptr = $E091 // STA (IFP),Y + *codeptr = $E091 // STA (IFP),Y codeptr = codeptr + 2 - //^codeptr = $91; codeptr++ // STA (zp),Y - //^codeptr = $E0; codeptr++ // IFP - if ^(bytecode+i) <> 0 - *codeptr = $00A0 // LDY #$00 + if j + *codeptr = $00A0 // LDY #$00 codeptr = codeptr + 2 - //^codeptr = $A0; codeptr++ // LDY #imm - //^codeptr = $00; codeptr++ // $00 fin - VX++ // INX - A_IS_TOSL = FALSE + VX++ // INX + A_IS_TOSL = FALSE break is $76 // SLW i++ - //puts("SLW "); puti(^(bytecode+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 ^(bytecode+i) <> 0 - *codeptr = $A0+(^(bytecode+i)<<8) // LDY #imm + if j + *codeptr = $A0+(j<<8) // LDY #imm codeptr = codeptr + 2 - //^codeptr = $A0; codeptr++ // LDY #imm - //^codeptr = ^(bytecode+i); codeptr++ fin - codeptr=>0 = $E091 // STA (IFP),Y - //^codeptr = $91; codeptr++ // STA (zp),Y - //^codeptr = $E0; codeptr++ // IFP - codeptr->2 = $C8 // INY - //^codeptr = $C8; codeptr++ // INY - codeptr=>3 = $C0B5+(VX<<8) // LDA ESTKH,X - //^codeptr = $B5; codeptr++ // LDA zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH - codeptr=>5 = $E091 // STA (IFP),Y - //^codeptr = $91; codeptr++ // STA (zp),Y - //^codeptr = $E0; codeptr++ // IFP - if ^(bytecode+i) <> 0 - codeptr=>7 = $00A0 // LDY #$00 + codeptr=>0 = $E091 // STA (IFP),Y + codeptr->2 = $C8 // INY + codeptr=>3 = $C0B5+(VX<<8) // LDA ESTKH,X + codeptr=>5 = $E091 // STA (IFP),Y + if j + codeptr=>7 = $00A0 // LDY #$00 codeptr = codeptr + 9 - //^codeptr = $A0; codeptr++ // LDY #imm - //^codeptr = $00; codeptr++ // $00 else - codeptr->7 = $88 // DEY + codeptr->7 = $88 // DEY codeptr = codeptr + 8 - //^codeptr = $88; codeptr++ // DEY fin - VX++ // INX - A_IS_TOSL = FALSE + VX++ // INX + A_IS_TOSL = FALSE break is $78 // SAB i++ @@ -1490,34 +1047,27 @@ def compiler(defptr)#0 *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - codeptr->0 = $8D // STA abs + codeptr->0 = $8D // STA abs codeptr=>1 = *(bytecode+i) - //^codeptr = $8D; codeptr++ // STA abs - //*codeptr = *(bytecode+i); codeptr = codeptr + 2 - VX++ // INX + VX++ // INX codeptr = codeptr + 3 A_IS_TOSL = FALSE i++ break is $7A // SAW i++ - //puts("SAW $"); puth(*(bytecode+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 = *(bytecode+i) - //^codeptr = $8D; codeptr++ // STA abs - //*codeptr = *(bytecode+i); codeptr = codeptr + 2 - codeptr=>3 = $C0B5+(VX<<8) // LDA ESTKH,X - //^codeptr = $B5; codeptr++ // LDA zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH - codeptr->5 = $8D // STA abs - codeptr=>6 = *(bytecode+i)+1 - //^codeptr = $8D; codeptr++ // STA abs - //*codeptr = *(bytecode+i)+1; codeptr = codeptr + 2 - VX++ // INX + codeptr->0 = $8D // STA abs + codeptr=>1 = dest + codeptr=>3 = $C0B5+(VX<<8) // LDA ESTKH,X + codeptr->5 = $8D // STA abs + codeptr=>6 = dest+1 + VX++ // INX codeptr = codeptr + 8 A_IS_TOSL = FALSE i++ @@ -1526,39 +1076,30 @@ def compiler(defptr)#0 i++ //puts("DAB $"); puth(*(bytecode+i)) if not A_IS_TOSL - *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X - codeptr = codeptr + 2 - A_IS_TOSL = TOSL_CLEAN + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 + A_IS_TOSL = TOSL_CLEAN fin - codeptr->0 = $8D // STA abs + codeptr->0 = $8D // STA abs codeptr=>1 = *(bytecode+i) - //^codeptr = $8D; codeptr++ // STA abs - //*codeptr = *(bytecode+i); codeptr = codeptr + 2 codeptr = codeptr + 3 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 = TOSL_CLEAN + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 + A_IS_TOSL = TOSL_CLEAN fin - codeptr->0 = $8D // STA abs - codeptr=>1 = *(bytecode+i) - //^codeptr = $8D; codeptr++ // STA abs - //*codeptr = *(bytecode+i); codeptr = codeptr + 2 - codeptr=>3 = $C0B4+(VX<<8) // LDY ESTKH,X - //^codeptr = $B4; codeptr++ // LDY zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH - codeptr->5 = $8C // STY abs - codeptr=>6 = *(bytecode+i)+1 - //^codeptr = $8C; codeptr++ // STY abs - //*codeptr = *(bytecode+i)+1; codeptr = codeptr + 2 - codeptr=>8 = $00A0 // LDY #$00 - //^codeptr = $A0; codeptr++ // LDY #imm - //^codeptr = $00; codeptr++ // $00 + codeptr->0 = $8D // STA abs + codeptr=>1 = dest + codeptr=>3 = $C0B4+(VX<<8) // LDY ESTKH,X + codeptr->5 = $8C // STY abs + codeptr=>6 = dest+1 + codeptr=>8 = $00A0 // LDY #$00 codeptr = codeptr + 10 i++ break @@ -1568,82 +1109,46 @@ def compiler(defptr)#0 *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - codeptr=>0 = $C015+(VX<<8) // ORA ESTKH,X - //^codeptr = $15; codeptr++ // ORA zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH - codeptr=>2 = $02F0 // BEQ +2 - //^codeptr = $F0; codeptr++ // BEQ rel - //^codeptr = $02; codeptr++ // +2 - codeptr=>4 = $FFA9 // LDA #$FF - //^codeptr = $A9; codeptr++ // LDA #imm - //^codeptr = $FF; codeptr++ // $FF - codeptr=>6 = $FF49 // EOR #$FF - //^codeptr = $49; codeptr++ // EOR #imm - //^codeptr = $FF; codeptr++ // $FF - codeptr=>8 = $C095+(VX<<8) // STA ESTKH,X - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $D0+VX; codeptr++ // ESTKL + 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 = TOSL_DIRTY + A_IS_TOSL = TOSL_DIRTY // STA ESTKL,X break is $82 // ADD //puts("ADD") if not A_IS_TOSL - *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - codeptr->0 = $18 // CLC - //^codeptr = $18; codeptr++ // CLC - codeptr=>1 = ($D075+$0100)+(VX<<8) // ADC ESTKL+1,X - //^codeptr = $75; codeptr++ // ADC zp,X - //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - codeptr=>3 = ($D095+$0100)+(VX<<8) // STA ESTKL+1,X - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - codeptr=>5 = $C0B5+(VX<<8) // LDA ESTKH,X - //^codeptr = $B5; codeptr++ // LDA zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH - codeptr=>7 = ($C075+$0100)+(VX<<8) // ADC ESTKH+1,X - //^codeptr = $75; codeptr++ // ADC zp,X - //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - codeptr=>9 = ($C095+$0100)+(VX<<8) // STA ESTKH+1,X - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - VX++ // INX + 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 + VX++ // INX codeptr = codeptr + 11 A_IS_TOSL = FALSE break is $84 // SUB //puts("SUB") if A_IS_TOSL & TOSL_DIRTY - *codeptr = $D095+(VX<<8) // STA ESTKL,X + *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin - codeptr=>0 = ($D0B5+$0100)+(VX<<8) // LDA ESTKL+1,X - //^codeptr = $B5; codeptr++ // LDA zp,X - //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - codeptr->2 = $38 // SEC - //^codeptr = $38; codeptr++ // SEC - codeptr=>3 = $D0F5+(VX<<8) // SBC ESTKL,X - //^codeptr = $F5; codeptr++ // SBC zp,X - //^codeptr = $D0+VX; codeptr++ // ESTKL - codeptr=>5 = ($D095+$0100)+(VX<<8) // STA ESTKL+1,X - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - codeptr=>7 = ($C0B5+$0100)+(VX<<8) // LDA ESTKH+1,X - //^codeptr = $B5; codeptr++ // LDA zp,X - //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - codeptr=>9 = $C0F5+(VX<<8) // SBC ESTKH,X - //^codeptr = $F5; codeptr++ // SBC zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH - codeptr=>11 = ($C095+$0100)+(VX<<8) // STA ESTKH+1,X - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - VX++ // INX + 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 + VX++ // INX codeptr = codeptr + 13 - A_IS_TOSL = FALSE + A_IS_TOSL = FALSE break is $86 // MUL is $88 // DIV @@ -1666,21 +1171,15 @@ def compiler(defptr)#0 // // Call into VM // + codeptr, VX = resolveX(codeptr, VX) if A_IS_TOSL & TOSL_DIRTY - *codeptr = $D095+(VX<<8) // STA ESTKL,X + *codeptr = $D095//+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin - codeptr, VX = resolveX(codeptr, VX) - codeptr->0 = $20 // JSR INTERP - codeptr=>1 = $3D0 // INTERP - //^codeptr = $20; codeptr++ // JSR INTERP - //*codeptr = $3D0; codeptr = codeptr + 2 - codeptr=>3 = $C000+opcode // OPCODE; NATV CODE - //^codeptr = opcode; codeptr++ // OPCODE - //^codeptr = $C0; codeptr++ // NATV CODE - codeptr=>5 = $00A0 // LDY #$00 - //^codeptr = $A0; codeptr++ // LDY #imm - //^codeptr = $00; codeptr++ // $00 + codeptr->0 = $20 // JSR INTERP + codeptr=>1 = $3D0 // INTERP + codeptr=>3 = $C000+opcode // OPCODE; NATV CODE + codeptr=>5 = $00A0 // LDY #$00 codeptr = codeptr + 7 A_IS_TOSL = FALSE break @@ -1690,21 +1189,12 @@ def compiler(defptr)#0 *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - codeptr->0 = $18 // CLC - //^codeptr = $18; codeptr++ // CLC - codeptr=>1 = $0169 // ADC #$01 - //^codeptr = $69; codeptr++ // ADC #imm - //^codeptr = $01; codeptr++ // $01 - codeptr=>3 = $0290 // BCC +2 - //^codeptr = $90; codeptr++ // BCC rel - //^codeptr = $02; codeptr++ // +2 - codeptr=>5 = $C0F6+(VX<<8) // INC ESTKH,X - //^codeptr = $F6; codeptr++ // INC zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $D0+VX; codeptr++ // ESTKL + codeptr->0 = $18 // CLC + codeptr=>1 = $0169 // ADC #$01 + codeptr=>3 = $0290 // BCC +2 + codeptr=>5 = $C0F6+(VX<<8) // INC ESTKH,X codeptr = codeptr + 7 - A_IS_TOSL = TOSL_DIRTY + A_IS_TOSL = TOSL_DIRTY // STA ESTKL,X break is $8E // DECR //puts("DECR") @@ -1712,21 +1202,12 @@ def compiler(defptr)#0 *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - codeptr->0 = $38 // SEC - //^codeptr = $38; codeptr++ // SEC - codeptr=>1 = $01E9 // SBC #$01 - //^codeptr = $E9; codeptr++ // SBC #imm - //^codeptr = $01; codeptr++ // $01 - codeptr=>3 = $02B0 // BCS +2 - //^codeptr = $B0; codeptr++ // BCS rel - //^codeptr = $02; codeptr++ // +2 - codeptr=>5 = $C0D6+(VX<<8) // DEC ESTKH,X - //^codeptr = $D6; codeptr++ // DEC zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $D0+VX; codeptr++ // ESTKL + codeptr->0 = $38 // SEC + codeptr=>1 = $01E9 // SBC #$01 + codeptr=>3 = $02B0 // BCS +2 + codeptr=>5 = $C0D6+(VX<<8) // DEC ESTKH,X codeptr = codeptr + 7 - A_IS_TOSL = TOSL_DIRTY + A_IS_TOSL = TOSL_DIRTY // STA ESTKL,X break is $90 // NEG //puts("NEG") @@ -1734,23 +1215,12 @@ def compiler(defptr)#0 *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin - codeptr=>0 = $3898 // TYA -> LDA #$00; SEC - //^codeptr = $98; codeptr++ // TYA -> LDA #$00 - //^codeptr = $38; codeptr++ // SEC - codeptr=>2 = $D0F5+(VX<<8) // SBC ESTKL,X - //^codeptr = $F5; codeptr++ // SBC zp,X - //^codeptr = $D0+VX; codeptr++ // ESTKL - codeptr=>4 = $D095+(VX<<8) // STA ESTKL,X - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $D0+VX; codeptr++ // ESTKL - codeptr->6 = $98 // TYA -> LDA #00 - //^codeptr = $98; codeptr++ // TYA -> LDA #00 - codeptr=>7 = $C0F5+(VX<<8) // SBC ESTKH,X - //^codeptr = $F5; codeptr++ // SBC zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH - codeptr=>9 = $C095+(VX<<8) // STA ESTKH,X - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH + 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 @@ -1760,128 +1230,74 @@ def compiler(defptr)#0 *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - codeptr=>0 = $FF49 // EOR #$FF - //^codeptr = $49; codeptr++ // EOR #imm - //^codeptr = $FF; codeptr++ // $FF - codeptr=>2 = $D095+(VX<<8) // STA ESTKL,X - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $D0+VX; codeptr++ // ESTKL - codeptr=>4 = $C0B5+(VX<<8) // LDA ESTKH,X - //^codeptr = $B5; codeptr++ // LDA zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH - codeptr=>6 = $FF49 // EOR #$FF - //^codeptr = $49; codeptr++ // EOR #imm - //^codeptr = $FF; codeptr++ // $FF - codeptr=>8 = $C095+(VX<<8) // STA ESTKH,X - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr=>0 = $FF49 // EOR #$FF + codeptr=>2 = $D095+(VX<<8) // STA ESTKL,X + codeptr=>4 = $C0B5+(VX<<8) // LDA ESTKH,X + codeptr=>6 = $FF49 // EOR #$FF + codeptr=>8 = $C095+(VX<<8) // STA ESTKH,X codeptr = codeptr + 10 A_IS_TOSL = FALSE break is $94 // AND //puts("AND") if not A_IS_TOSL - *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - codeptr=>0 = ($D035+$0100)+(VX<<8) // AND ESTKL+1,X - //^codeptr = $35; codeptr++ // AND zp,X - //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - codeptr=>2 = ($D095+$0100)+(VX<<8) // STA ESTKL+1,X - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - codeptr=>4 = $C0B5+(VX<<8) // LDA ESTKH,X - //^codeptr = $B5; codeptr++ // LDA zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH - codeptr=>6 = ($C035+$0100)+(VX<<8) // AND ESTKH+1,X - //^codeptr = $35; codeptr++ // AND zp,X - //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - codeptr=>8 = ($C095+$0100)+(VX<<8) // STA ESTKH+1,X - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - VX++ // INX - codeptr = codeptr + 10 - A_IS_TOSL = FALSE + codeptr=>0 = $D035+$0100+(VX<<8) // AND ESTKL+1,X + codeptr=>2 = $D095+$0100+(VX<<8) // STA ESTKL+1,X + codeptr=>4 = $C0B5+(VX<<8) // LDA ESTKH,X + codeptr=>6 = $C035+$0100+(VX<<8) // AND ESTKH+1,X + codeptr=>8 = $C095+$0100+(VX<<8) // STA ESTKH+1,X + VX++ // INX + codeptr = codeptr + 10 + A_IS_TOSL = FALSE break is $96 // OR //puts("OR") if not A_IS_TOSL - *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - codeptr=>0 = ($D015+$0100)+(VX<<8) // ORA ESTKL+1,X - //^codeptr = $15; codeptr++ // ORA zp,X - //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - codeptr=>2 = ($D095+$0100)+(VX<<8) // STA ESTKL+1,X - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - codeptr=>4 = $C0B5+(VX<<8) // LDA ESTKH,X - //^codeptr = $B5; codeptr++ // LDA zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH - codeptr=>6 = ($C015+$0100)+(VX<<8) // ORA ESTKH+1,X - //^codeptr = $15; codeptr++ // ORA zp,X - //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - codeptr=>8 = ($C095+$0100)+(VX<<8) // STA ESTKH+1,X - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - VX++ // INX - codeptr = codeptr + 10 - A_IS_TOSL = FALSE + codeptr=>0 = $D015+$0100+(VX<<8) // ORA ESTKL+1,X + codeptr=>2 = $D095+$0100+(VX<<8) // STA ESTKL+1,X + codeptr=>4 = $C0B5+(VX<<8) // LDA ESTKH,X + codeptr=>6 = $C015+$0100+(VX<<8) // ORA ESTKH+1,X + codeptr=>8 = $C095+$0100+(VX<<8) // STA ESTKH+1,X + VX++ // INX + codeptr = codeptr + 10 + A_IS_TOSL = FALSE break is $98 // XOR //puts("XOR") if not A_IS_TOSL - *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - codeptr=>0 = ($D055+$0100)+(VX<<8) // EOR ESTKL+1,X - //^codeptr = $55; codeptr++ // EOR zp,X - //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - codeptr=>2 = ($D095+$0100)+(VX<<8) // STA ESTKL+1,X - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - codeptr=>4 = $C0B5+(VX<<8) // LDA ESTKH,X - //^codeptr = $B5; codeptr++ // LDA zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH - codeptr=>6 = ($C055+$0100)+(VX<<8) // EOR ESTKH+1,X - //^codeptr = $55; codeptr++ // EOR zp,X - //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - codeptr=>8 = ($C095+$0100)+(VX<<8) // STA ESTKH+1,X - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - VX++ // INX - codeptr = codeptr + 10 - A_IS_TOSL = FALSE + codeptr=>0 = $D055+$0100+(VX<<8) // EOR ESTKL+1,X + codeptr=>2 = $D095+$0100+(VX<<8) // STA ESTKL+1,X + codeptr=>4 = $C0B5+(VX<<8) // LDA ESTKH,X + codeptr=>6 = $C055+$0100+(VX<<8) // EOR ESTKH+1,X + codeptr=>8 = $C095+$0100+(VX<<8) // STA ESTKH+1,X + VX++ // INX + codeptr = codeptr + 10 + A_IS_TOSL = FALSE break is $9E // IDXW //puts("IDXW") if not A_IS_TOSL - *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - codeptr->0 = $0A // ASL - //^codeptr = $0A; codeptr++ // ASL - codeptr=>1 = $C036+(VX<<8) // ROL ESTKH,X - //^codeptr = $36; codeptr++ // ROL zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH - codeptr->3 = $18 // CLC - //^codeptr = $18; codeptr++ // CLC - codeptr=>4 = ($D075+$0100)+(VX<<8) // ADC ESTKL+1,X - //^codeptr = $75; codeptr++ // ADC zp,X - //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - codeptr=>6 = ($D095+$0100)+(VX<<8) // STA ESTKL+1,X - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - codeptr=>8 = $C0B5+(VX<<8) // LDA ESTKH,X - //^codeptr = $B5; codeptr++ // LDA zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH - codeptr=>10 = ($C075+$0100)+(VX<<8) // ADC ESTKH+1,X - //^codeptr = $75; codeptr++ // ADC zp,X - //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - codeptr=>12 = ($C095+$0100)+(VX<<8) // STA ESTKH+1,X - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - VX++ // INX + 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 + VX++ // INX codeptr = codeptr + 14 A_IS_TOSL = FALSE break @@ -1892,44 +1308,23 @@ def compiler(defptr)#0 i++ codeptr, VX = resolveX(codeptr, VX) if A_IS_TOSL & TOSL_DIRTY - *codeptr = $D095+(VX<<8) // STA ESTKL,X + *codeptr = $D095//+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin - codeptr=>0 = ($D0B5+$0100)+(VX<<8) // LDA ESTKL+1,X - //^codeptr = $B5; codeptr++ // LDA zp,X - //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - codeptr=>2 = $D0D5+(VX<<8) // CMP ESTKL,X - //^codeptr = $D5; codeptr++ // CMP zp,X - //^codeptr = $D0+VX; codeptr++ // ESTKL - codeptr=>4 = ($C0B5+$0100)+(VX<<8) // LDA ESTKH+1,X - //^codeptr = $B5; codeptr++ // LDA zp,X - //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - codeptr=>6 = $C0F5+(VX<<8) // SBC ESTKH - //^codeptr = $F5; codeptr++ // SBC zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH - codeptr=>8 = $0250 // BVC +2 - //^codeptr = $50; codeptr++ // BVC rel - //^codeptr = $02; codeptr++ // +2 - codeptr=>10 = $8049 // EOR #$80 - //^codeptr = $49; codeptr++ // EOR #imm - //^codeptr = $80; codeptr++ // $80 - codeptr=>12 = $0510 // BPL +5 - //^codeptr = $10; codeptr++ // BPL rel - //^codeptr = $05; codeptr++ // +5 - codeptr=>14 = $E8E8 // INX; INX - //^codeptr = $E8; codeptr++ // INX - //^codeptr = $E8; codeptr++ // INX - codeptr->16 = $4C // JMP abs - //^codeptr = $4C; codeptr++ // JMP abs + 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] - //*codeptr = addrxlate=>[dest] if not (codeptr->18 & $80) // Unresolved address list - //if not (*codeptr & $8000) // Unresolved address list addrxlate=>[dest] = codeptr + 17 - *jitcodeptr - //addrxlate=>[dest] = codeptr - *jitcodeptr fin codeptr = codeptr + 19 - //codeptr = codeptr + 2 A_IS_TOSL = FALSE break is $A2 // BRLT - FOR/NEXT SPECIFIC TEST & BRANCH @@ -1939,46 +1334,25 @@ def compiler(defptr)#0 i++ codeptr, VX = resolveX(codeptr, VX) if not A_IS_TOSL - *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + *codeptr = $D0B5//+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 elsif A_IS_TOSL & TOSL_DIRTY - *codeptr = $D095+(VX<<8) // STA ESTKL,X + *codeptr = $D095//+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $D0+VX; codeptr++ // ESTKL fin - codeptr=>0 = ($D0D5+$0100)+(VX<<8) // CMP ESTKL+1,X - //^codeptr = $D5; codeptr++ // CMP zp,X - //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - codeptr=>2 = $C0B5+(VX<<8) // LDA ESTKH,X - //^codeptr = $B5; codeptr++ // LDA zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH - codeptr=>4 = ($C0F5+$0100)+(VX<<8) // SBC ESTKH+1 - //^codeptr = $F5; codeptr++ // SBC zp,X - //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - codeptr=>6 = $0250 // BVC +2 - //^codeptr = $50; codeptr++ // BVC rel - //^codeptr = $02; codeptr++ // +2 - codeptr=>8 = $8049 // EOR #$80 - //^codeptr = $49; codeptr++ // EOR #imm - //^codeptr = $80; codeptr++ // $80 - codeptr=>10 = $0510 // BPL +5 - //^codeptr = $10; codeptr++ // BPL rel - //^codeptr = $05; codeptr++ // +5 - codeptr=>12 = $E8E8 // INX; INX - //^codeptr = $E8; codeptr++ // INX - //^codeptr = $E8; codeptr++ // INX - codeptr->14 = $4C // JMP abs - //^codeptr = $4C; codeptr++ // JMP abs + 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] - //*codeptr = addrxlate=>[dest] if not (codeptr->16 & $80) // Unresolved address list - //if not (*codeptr & $8000) // Unresolved address list addrxlate=>[dest] = codeptr + 15 - *jitcodeptr - //addrxlate=>[dest] = codeptr - *jitcodeptr fin codeptr = codeptr + 17 - //codeptr = codeptr + 2 A_IS_TOSL = FALSE break is $A4 // INCBRLE - FOR/NEXT SPECIFIC INC & TEST & BRANCH @@ -1993,60 +1367,30 @@ def compiler(defptr)#0 *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - codeptr->0 = $18 // CLC - //^codeptr = $18; codeptr++ // CLC - codeptr=>1 = $0169 // ADC #$01 - //^codeptr = $69; codeptr++ // ADC #imm - //^codeptr = $01; codeptr++ // $01 - codeptr=>3 = $D095+(VX<<8) // STA ESTKL,X - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $D0+VX; codeptr++ // ESTKL - codeptr=>5 = $0290 // BCC +2 - //^codeptr = $90; codeptr++ // BCC rel - //^codeptr = $02; codeptr++ // +2 - codeptr=>7 = $C0F6+(VX<<8) // INC ESTKH,X - //^codeptr = $F6; codeptr++ // INC zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr->0 = $18 // CLC + codeptr=>1 = $0169 // ADC #$01 + codeptr=>3 = $D095+(VX<<8) // STA ESTKL,X + codeptr=>5 = $0290 // BCC +2 + codeptr=>7 = $C0F6+(VX<<8) // INC ESTKH,X codeptr, VX = resolveX(codeptr + 9, VX) // // BRLE // - codeptr=>0 = ($D0B5+$0100)+(VX<<8) // LDA ESTKL+1,X - //^codeptr = $B5; codeptr++ // LDA zp,X - //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - codeptr=>2 = $D0D5+(VX<<8) // CMP ESTKL,X - //^codeptr = $D5; codeptr++ // CMP zp,X - //^codeptr = $D0+VX; codeptr++ // ESTKL - codeptr=>4 = ($C0B5+$0100)+(VX<<8) // LDA ESTKH+1,X - //^codeptr = $B5; codeptr++ // LDA zp,X - //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - codeptr=>6 = $C0F5+(VX<<8) // SBC ESTKH - //^codeptr = $F5; codeptr++ // SBC zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH - codeptr=>8 = $0250 // BVC +2 - //^codeptr = $50; codeptr++ // BVC rel - //^codeptr = $02; codeptr++ // +2 - codeptr=>10 = $8049 // EOR #$80 - //^codeptr = $49; codeptr++ // EOR #imm - //^codeptr = $80; codeptr++ // $80 - codeptr=>12 = $0330 // BMI +3 - //^codeptr = $30; codeptr++ // BMI rel - //^codeptr = $03; codeptr++ // +3 - codeptr->14 = $4C // JMP abs - //^codeptr = $4C; codeptr++ // JMP abs + 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] - //*codeptr = addrxlate=>[dest] if not (codeptr->16 & $80) // Unresolved address list - //if not (*codeptr & $8000) // Unresolved address list addrxlate=>[dest] = codeptr + 15 - *jitcodeptr - //addrxlate=>[dest] = codeptr - *jitcodeptr fin - //codeptr = codeptr + 2 - codeptr=>17 = $E8E8 // INX; INX - //^codeptr = $E8; codeptr++ // INX - //^codeptr = $E8; codeptr++ // INX - codeptr = codeptr + 19 - A_IS_TOSL = FALSE + codeptr=>17 = $E8E8 // INX; INX + codeptr = codeptr + 19 + A_IS_TOSL = FALSE break is $A6 // ADDBRLE - FOR/NEXT SPECIFIC ADD & TEST & BRANCH i++ @@ -2057,66 +1401,34 @@ def compiler(defptr)#0 // ADD // if not A_IS_TOSL - *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - codeptr->0 = $18 // CLC - //^codeptr = $18; codeptr++ // CLC - codeptr=>1 = ($D075+$0100)+(VX<<8) // ADC ESTKL+1,X - //^codeptr = $75; codeptr++ // ADC zp,X - //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - codeptr=>3 = ($D095+$0100)+(VX<<8) // STA ESTKL+1,X - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - codeptr=>5 = $C0B5+(VX<<8) // LDA ESTKH,X - //^codeptr = $B5; codeptr++ // LDA zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH - codeptr=>7 = ($C075+$0100)+(VX<<8) // ADC ESTKH+1,X - //^codeptr = $75; codeptr++ // ADC zp,X - //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - codeptr=>9 = ($C095+$0100)+(VX<<8) // STA ESTKH+1,X - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - codeptr, VX = resolveX(codeptr + 11, VX + 1) //VX++ // INX + codeptr->0 = $18 // CLC + codeptr=>1 = $D075+$0100+(VX<<8) // ADC ESTKL+1,X + codeptr=>3 = $D095+$0100+(VX<<8) // STA ESTKL+1,X + codeptr=>5 = $C0B5+(VX<<8) // LDA ESTKH,X + codeptr=>7 = $C075+$0100+(VX<<8) // ADC ESTKH+1,X + codeptr=>9 = $C095+$0100+(VX<<8) // STA ESTKH+1,X + codeptr, VX = resolveX(codeptr + 11, VX + 1) // INX // // BRLE // - codeptr=>0 = ($D0B5+$0100)+(VX<<8) // LDA ESTKL+1,X - //^codeptr = $B5; codeptr++ // LDA zp,X - //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - codeptr=>2 = $D0D5+(VX<<8) // CMP ESTKL,X - //^codeptr = $D5; codeptr++ // CMP zp,X - //^codeptr = $D0+VX; codeptr++ // ESTKL - codeptr=>4 = ($C0B5+$0100)+(VX<<8) // LDA ESTKH+1,X - //^codeptr = $B5; codeptr++ // LDA zp,X - //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - codeptr=>6 = $C0F5+(VX<<8) // SBC ESTKH - //^codeptr = $F5; codeptr++ // SBC zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH - codeptr=>8 = $0250 // BVC +2 - //^codeptr = $50; codeptr++ // BVC rel - //^codeptr = $02; codeptr++ // +2 - codeptr=>10 = $8049 // EOR #$80 - //^codeptr = $49; codeptr++ // EOR #imm - //^codeptr = $80; codeptr++ // $80 - codeptr=>12 = $0330 // BMI +3 - //^codeptr = $30; codeptr++ // BMI rel - //^codeptr = $03; codeptr++ // +3 - codeptr->14 = $4C // JMP abs - //^codeptr = $4C; codeptr++ // JMP abs + 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] - //*codeptr = addrxlate=>[dest] if not (codeptr->16 & $80) // Unresolved address list - //if not (*codeptr & $8000) // Unresolved address list addrxlate=>[dest] = codeptr + 15 - *jitcodeptr - //addrxlate=>[dest] = codeptr - *jitcodeptr fin - //codeptr = codeptr + 2 - codeptr=>17 = $E8E8 // INX; INX - //^codeptr = $E8; codeptr++ // INX - //^codeptr = $E8; codeptr++ // INX - codeptr = codeptr + 19 - A_IS_TOSL = FALSE + codeptr=>17 = $E8E8 // INX; INX + codeptr = codeptr + 19 + A_IS_TOSL = FALSE break is $A8 // DECBRGR - FOR/NEXT SPECIFIC DEC & TEST & BRANCH i++ @@ -2130,59 +1442,29 @@ def compiler(defptr)#0 *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - codeptr->0 = $38 // SEC - //^codeptr = $38; codeptr++ // SEC - codeptr=>1 = $01E9 // SBC #$01 - //^codeptr = $E9; codeptr++ // SBC #imm - //^codeptr = $01; codeptr++ // $01 - codeptr=>3 = $D095+(VX<<8) // STA ESTKL,X - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $D0+VX; codeptr++ // ESTKL - codeptr=>5 = $02B0 // BCS +2 - //^codeptr = $B0; codeptr++ // BCS rel - //^codeptr = $02; codeptr++ // +2 - codeptr=>7 = $C0D6+(VX<<8) // DEC ESTKH,X - //^codeptr = $D6; codeptr++ // DEC zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr->0 = $38 // SEC + codeptr=>1 = $01E9 // SBC #$01 + codeptr=>3 = $D095+(VX<<8) // STA ESTKL,X + codeptr=>5 = $02B0 // BCS +2 + codeptr=>7 = $C0D6+(VX<<8) // DEC ESTKH,X codeptr, VX = resolveX(codeptr + 9, VX) // // BRGE // - //^codeptr = $B5; codeptr++ // LDA zp,X - //^codeptr = $D0+VX; codeptr++ // ESTKL - codeptr=>0 = ($D0D5+$0100)+(VX<<8) // CMP ESTKL+1,X - //^codeptr = $D5; codeptr++ // CMP zp,X - //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - codeptr=>2 = $C0B5+(VX<<8) // LDA ESTKH,X - //^codeptr = $B5; codeptr++ // LDA zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH - codeptr=>4 = ($C0F5+$0100)+(VX<<8) // SBC ESTKH+1,X - //^codeptr = $F5; codeptr++ // SBC zp,X - //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - codeptr=>6 = $0250 // BVC +2 - //^codeptr = $50; codeptr++ // BVC rel - //^codeptr = $02; codeptr++ // +2 - codeptr=>8 = $8049 // EOR #$80 - //^codeptr = $49; codeptr++ // EOR #imm - //^codeptr = $80; codeptr++ // $80 - codeptr=>10 = $0330 // BMI +3 - //^codeptr = $30; codeptr++ // BMI rel - //^codeptr = $03; codeptr++ // +3 - codeptr->12 = $4C // JMP abs - //^codeptr = $4C; codeptr++ // JMP abs + 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] - //*codeptr = addrxlate=>[dest] if not (codeptr->14 & $80) // Unresolved address list - //if not (*codeptr & $8000) // Unresolved address list addrxlate=>[dest] = codeptr + 13 - *jitcodeptr - //addrxlate=>[dest] = codeptr - *jitcodeptr fin - //codeptr = codeptr + 2 - codeptr=>15 = $E8E8 // INX; INX - //^codeptr = $E8; codeptr++ // INX - //^codeptr = $E8; codeptr++ // INX - codeptr = codeptr + 17 - A_IS_TOSL = FALSE + codeptr=>15 = $E8E8 // INX; INX + codeptr = codeptr + 17 + A_IS_TOSL = FALSE break is $AA // SUBBRGE - FOR/NEXT SPECIFIC SUB & TEST & BRANCH i++ @@ -2193,69 +1475,35 @@ def compiler(defptr)#0 // SUB // if A_IS_TOSL & TOSL_DIRTY - *codeptr = $D095+(VX<<8) // STA ESTKL,X + *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin - codeptr=>0 = ($D0B5+$0100)+(VX<<8) // LDA ESTKL+1,X - //^codeptr = $B5; codeptr++ // LDA zp,X - //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - codeptr->2 = $38 // SEC - //^codeptr = $38; codeptr++ // SEC - codeptr=>3 = $D0F5+(VX<<8) // SBC ESTKL,X - //^codeptr = $F5; codeptr++ // SBC zp,X - //^codeptr = $D0+VX; codeptr++ // ESTKL - codeptr=>5 = ($D095+$0100)+(VX<<8) // STA ESTKL+1,X - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - codeptr=>7 = ($C0B5+$0100)+(VX<<8) // LDA ESTKH+1,X - //^codeptr = $B5; codeptr++ // LDA zp,X - //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - codeptr=>9 = $C0F5+(VX<<8) // SBC ESTKH,X - //^codeptr = $F5; codeptr++ // SBC zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH - codeptr=>11 = ($C095+$0100)+(VX<<8) // STA ESTKH+1,X - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - codeptr, VX = resolveX(codeptr + 13, VX + 1) //VX++ // INX + codeptr=>0 = $D0B5+$0100+(VX<<8) // LDA ESTKL+1,X + codeptr->2 = $38 // SEC + codeptr=>3 = $D0F5+(VX<<8) // SBC ESTKL,X + codeptr=>5 = $D095+$0100+(VX<<8) // STA ESTKL+1,X + codeptr=>7 = $C0B5+$0100+(VX<<8) // LDA ESTKH+1,X + codeptr=>9 = $C0F5+(VX<<8) // SBC ESTKH,X + codeptr=>11 = $C095+$0100+(VX<<8) // STA ESTKH+1,X + codeptr, VX = resolveX(codeptr + 13, VX + 1) // INX // // BRGE // - codeptr=>0 = $D0B5+(VX<<8) // LDA ESTKL,X - //^codeptr = $B5; codeptr++ // LDA zp,X - //^codeptr = $D0+VX; codeptr++ // ESTKL - codeptr=>2 = ($D0D5+$0100)+(VX<<8) // CMP ESTKL+1,X - //^codeptr = $D5; codeptr++ // CMP zp,X - //^codeptr = $D0+1+VX; codeptr++ // ESTKL+1 - codeptr=>4 = $C0B5+(VX<<8) // LDA ESTKH,X - //^codeptr = $B5; codeptr++ // LDA zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH - codeptr=>6 = ($C0F5+$0100)+(VX<<8) // SBC ESTKH+1,X - //^codeptr = $F5; codeptr++ // SBC zp,X - //^codeptr = $C0+1+VX; codeptr++ // ESTKH+1 - codeptr=>8 = $0250 // BVC +2 - //^codeptr = $50; codeptr++ // BVC rel - //^codeptr = $02; codeptr++ // +2 - codeptr=>10 = $8049 // EOR #$80 - //^codeptr = $49; codeptr++ // EOR #imm - //^codeptr = $80; codeptr++ // $80 - codeptr=>12 = $0330 // BMI +3 - //^codeptr = $30; codeptr++ // BMI rel - //^codeptr = $03; codeptr++ // +3 - codeptr->14 = $4C // JMP abs - //^codeptr = $4C; codeptr++ // JMP abs + codeptr=>0 = $D0B5//+(VX<<8) // LDA ESTKL,X + codeptr=>2 = $D0D5+$0100//+(VX<<8) // CMP ESTKL+1,X + codeptr=>4 = $C0B5//+(VX<<8) // LDA ESTKH,X + codeptr=>6 = $C0F5+$0100//+(VX<<8) // SBC ESTKH+1,X + codeptr=>8 = $0250 // BVC +2 + codeptr=>10 = $8049 // EOR #$80 + codeptr=>12 = $0330 // BMI +3 + codeptr->14 = $4C // JMP abs codeptr=>15 = addrxlate=>[dest] - //*codeptr = addrxlate=>[dest] if not (codeptr->16 & $80) // Unresolved address list - //if not (*codeptr & $8000) // Unresolved address list addrxlate=>[dest] = codeptr + 15 - *jitcodeptr - //addrxlate=>[dest] = codeptr - *jitcodeptr fin - //codeptr = codeptr + 2 - codeptr=>17 = $E8E8 // INX; INX - //^codeptr = $E8; codeptr++ // INX - //^codeptr = $E8; codeptr++ // INX - codeptr = codeptr + 19 - A_IS_TOSL = FALSE + codeptr=>17 = $E8E8 // INX; INX + codeptr = codeptr + 19 + A_IS_TOSL = FALSE break is $AC // BRAND - LOGICAL AND SPECIFIC BRANCH i++ @@ -2264,31 +1512,22 @@ def compiler(defptr)#0 //puts("BRAND "); puti(dest) codeptr, VX = resolveX(codeptr, VX) if not A_IS_TOSL - *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + *codeptr = $D0B5//+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 elsif A_IS_TOSL & TOSL_DIRTY - *codeptr = $D095+(VX<<8) // STA ESTKL,X + *codeptr = $D095//+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin - codeptr=>0 = $C015+(VX<<8) // ORA ESTKH,X - //^codeptr = $15; codeptr++ // ORA zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH - codeptr=>2 = $03D0 // BNE +3 - //^codeptr = $D0; codeptr++ // BNE rel - //^codeptr = $03; codeptr++ // +3 - codeptr->4 = $4C // JMP abs - //^codeptr = $4C; codeptr++ // JMP abs + codeptr=>0 = $C015//+(VX<<8) // ORA ESTKH,X + codeptr=>2 = $03D0 // BNE +3 + codeptr->4 = $4C // JMP abs codeptr=>5 = addrxlate=>[dest] - //*codeptr = addrxlate=>[dest] if not (codeptr->6 & $80) // Unresolved address list - //if not (*codeptr & $8000) // Unresolved address list addrxlate=>[dest] = codeptr + 5 - *jitcodeptr - //addrxlate=>[dest] = codeptr - *jitcodeptr fin - //codeptr = codeptr + 2 - VX++ // INX - codeptr = codeptr + 7 - A_IS_TOSL = FALSE + VX++ // INX + codeptr = codeptr + 7 + A_IS_TOSL = FALSE break is $AE // BROR - LOGICAL OR SPECIFIC BRANCH i++ @@ -2297,104 +1536,71 @@ def compiler(defptr)#0 //puts("BROR "); puti(dest) codeptr, VX = resolveX(codeptr, VX) if not A_IS_TOSL - *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + *codeptr = $D0B5//+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 elsif A_IS_TOSL & TOSL_DIRTY - *codeptr = $D095+(VX<<8) // STA ESTKL,X + *codeptr = $D095//+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin - codeptr=>0 = $C015+(VX<<8) // ORA ESTKH,X - //^codeptr = $15; codeptr++ // ORA zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH - codeptr=>2 = $03F0 // BEQ +3 - //^codeptr = $F0; codeptr++ // BEQ rel - //^codeptr = $03; codeptr++ // +3 - codeptr->4 = $4C // JMP abs - //^codeptr = $4C; codeptr++ // JMP abs + codeptr=>0 = $C015//+(VX<<8) // ORA ESTKH,X + codeptr=>2 = $03F0 // BEQ +3 + codeptr->4 = $4C // JMP abs codeptr=>5 = addrxlate=>[dest] - //*codeptr = addrxlate=>[dest] if not (codeptr->6 & $80) // Unresolved address list - //if not (*codeptr & $8000) // Unresolved address list addrxlate=>[dest] = codeptr + 5 - *jitcodeptr - //addrxlate=>[dest] = codeptr - *jitcodeptr fin - //codeptr = codeptr + 2 - VX++ // INX - codeptr = codeptr + 7 - A_IS_TOSL = FALSE + VX++ // INX + codeptr = codeptr + 7 + A_IS_TOSL = FALSE break is $B0 // ADDLB i++ - //puts("ADDLB "); puti(^(bytecode+i)) + j = ^(bytecode+i) + //puts("ADDLB "); puti(j) if not A_IS_TOSL *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - if ^(bytecode+i) <> 0 - *codeptr = $A0+(^(bytecode+i)<<8) // LDY #imm + if j + *codeptr = $A0+(j<<8) // LDY #imm codeptr = codeptr + 2 fin - codeptr->0 = $18 // CLC - //^codeptr = $18; codeptr++ // CLC - codeptr=>1 = $E071 // ADC (IFP),Y - //^codeptr = $71; codeptr++ // ADC (zp),Y - //^codeptr = $E0; codeptr++ // IFP - codeptr=>3 = $0290 // BCC +2 - //^codeptr = $90; codeptr++ // BCC rel - //^codeptr = $02; codeptr++ // +2 - codeptr=>5 = $C0F6+(VX<<8) // INC ESTKH,X - //^codeptr = $F6; codeptr++ // INC zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH + codeptr->0 = $18 // CLC + codeptr=>1 = $E071 // ADC (IFP),Y + codeptr=>3 = $0290 // BCC +2 + codeptr=>5 = $C0F6+(VX<<8) // INC ESTKH,X codeptr = codeptr + 7 - if ^(bytecode+i) <> 0 - *codeptr = $00A0 // LDY #$00 + if j + *codeptr = $00A0 // LDY #$00 codeptr = codeptr + 2 - //^codeptr = $A0; codeptr++ // LDY #imm - //^codeptr = $00; codeptr++ // $00 fin - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $D0+VX; codeptr++ // ESTKL - A_IS_TOSL = TOSL_DIRTY + A_IS_TOSL = TOSL_DIRTY // STA ESTKL,X break is $B2 // ADDLW i++ - //puts("ADDLW "); puti(^(bytecode+i)) + j = ^(bytecode+i) + //puts("ADDLW "); puti(j) if not A_IS_TOSL *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - if ^(bytecode+i) <> 0 - *codeptr = $A0+(^(bytecode+i)<<8) // LDY #imm + if j + *codeptr = $A0+(j<<8) // LDY #imm codeptr = codeptr + 2 fin - codeptr->0 = $18 // CLC - //^codeptr = $18; codeptr++ // CLC - codeptr=>1 = $E071 // ADC (IFP),Y - //^codeptr = $71; codeptr++ // ADC (zp),Y - //^codeptr = $E0; codeptr++ // IFP - codeptr=>3 = $D095+(VX<<8) // STA ESTKL,X - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $D0+VX; codeptr++ // ESTKL - codeptr=>5 = $C0B5+(VX<<8) // LDA ESTKH,X - //^codeptr = $B5; codeptr++ // LDA zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH - codeptr->7 = $C8 // INY - //^codeptr = $C8; codeptr++ // INY - codeptr=>8 = $E071 // ADC (IFP),Y - //^codeptr = $71; codeptr++ // ADC (zp),Y - //^codeptr = $E0; codeptr++ // IFP - codeptr=>10 = $C095+(VX<<8) // STA ESTKH,X - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH - if ^(bytecode+i) <> 0 - codeptr=>12 = $00A0 // LDY #$00 + codeptr->0 = $18 // CLC + codeptr=>1 = $E071 // ADC (IFP),Y + codeptr=>3 = $D095+(VX<<8) // STA ESTKL,X + codeptr=>5 = $C0B5+(VX<<8) // LDA ESTKH,X + codeptr->7 = $C8 // INY + codeptr=>8 = $E071 // ADC (IFP),Y + codeptr=>10 = $C095+(VX<<8) // STA ESTKH,X + if j + codeptr=>12 = $00A0 // LDY #$00 codeptr = codeptr + 14 - //^codeptr = $A0; codeptr++ // LDY #imm - //^codeptr = $00; codeptr++ // $00 else - codeptr->12 = $88 // DEY + codeptr->12 = $88 // DEY codeptr = codeptr + 13 - //^codeptr = $88; codeptr++ // DEY fin A_IS_TOSL = FALSE break @@ -2405,150 +1611,91 @@ def compiler(defptr)#0 *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - codeptr=>0 = $6D18 // CLC; ADC abs - //^codeptr = $18; codeptr++ // CLC - //^codeptr = $6D; codeptr++ // ADC abs + codeptr=>0 = $6D18 // CLC; ADC abs codeptr=>2 = *(bytecode+i) - //*codeptr = *(bytecode+i); codeptr = codeptr + 2 - codeptr=>4 = $0290 // BCC +2 - //^codeptr = $90; codeptr++ // BCC rel - //^codeptr = $02; codeptr++ // +2 - codeptr=>6 = $C0F6+(VX<<8) // INC ESTKH,X - //^codeptr = $F6; codeptr++ // INC zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $D0+VX; codeptr++ // ESTKL - codeptr = codeptr + 8 - A_IS_TOSL = TOSL_DIRTY + codeptr=>4 = $0290 // BCC +2 + codeptr=>6 = $C0F6+(VX<<8) // INC ESTKH,X + codeptr = codeptr + 8 + A_IS_TOSL = TOSL_DIRTY // STA ESTKL,X i++ break is $B6 // ADDAW i++ - //puts("ADDAW $"); puth(*(bytecode+i)) + dest = *(bytecode+i) + i++ + //puts("ADDAW $"); puth(dest) if not A_IS_TOSL *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - codeptr=>0 = $6D18 // CLC; ADC abs - //^codeptr = $18; codeptr++ // CLC - //^codeptr = $6D; codeptr++ // ADC abs - codeptr=>2 = *(bytecode+i) - //*codeptr = *(bytecode+i); codeptr = codeptr + 2 - codeptr=>4 = $D095+(VX<<8) // STA ESTKL,X - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $D0+VX; codeptr++ // ESTKL - codeptr=>6 = $C0B5+(VX<<8) // LDA ESTKH,X - //^codeptr = $B5; codeptr++ // LDA zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH - codeptr->8 = $6D // ADC abs - //^codeptr = $6D; codeptr++ // ADC abs - codeptr=>9 = *(bytecode+i)+1 - //*codeptr = *(bytecode+i)+1; codeptr = codeptr + 2 - codeptr=>11 = $C095+(VX<<8) // STA ESTKH,X - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH - codeptr = codeptr + 13 - A_IS_TOSL = FALSE - i++ + codeptr=>0 = $6D18 // CLC; ADC abs + codeptr=>2 = dest + codeptr=>4 = $D095+(VX<<8) // STA ESTKL,X + codeptr=>6 = $C0B5+(VX<<8) // LDA ESTKH,X + codeptr->8 = $6D // ADC abs + codeptr=>9 = dest+1 + codeptr=>11 = $C095+(VX<<8) // STA ESTKH,X + codeptr = codeptr + 13 + A_IS_TOSL = FALSE break is $B8 // IDXLB i++ - //puts("IDXLB "); puti(^(bytecode+i)) + j = ^(bytecode+i) + //puts("IDXLB "); puti(j) if A_IS_TOSL & TOSL_DIRTY *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin - if ^(bytecode+i) <> 0 - *codeptr = $A0+(^(bytecode+i)<<8) // LDY #imm + if j + *codeptr = $A0+(j<<8) // LDY #imm codeptr = codeptr + 2 fin - *codeptr = $E0B1 // LDA (IFP),Y + *codeptr = $E0B1 // LDA (IFP),Y codeptr = codeptr + 2 - //^codeptr = $B1; codeptr++ // LDA (zp),Y - //^codeptr = $E0; codeptr++ // IFP - if ^(bytecode+i) <> 0 - *codeptr = $00A0 // LDY #$00 + if j + *codeptr = $00A0 // LDY #$00 codeptr = codeptr + 2 fin - codeptr->0 = $0A // ASL - //^codeptr = $0A; codeptr++ // ASL - codeptr=>1 = $0290 // BCC +2 - //^codeptr = $90; codeptr++ // BCC rel - //^codeptr = $02; codeptr++ // +2 - codeptr=>3 = $18C8 // INY; CLC - //^codeptr = $C8; codeptr++ // INY - //^codeptr = $18; codeptr++ // CLC - codeptr=>5 = $D075+(VX<<8) // ADC ESTKL,X - //^codeptr = $75; codeptr++ // ADC zp,X - //^codeptr = $D0+VX; codeptr++ // ESTKL - codeptr=>7 = $D095+(VX<<8) // STA ESTKL,X - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $D0+VX; codeptr++ // ESTKL - codeptr->9 = $98 // TYA - //^codeptr = $98; codeptr++ // TYA - codeptr=>10 = $C075+(VX<<8) // ADC ESTKH,X - //^codeptr = $75; codeptr++ // ADC zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH - codeptr=>12 = $C095+(VX<<8) // STA ESTKH,X - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH - codeptr=>14 = $00A0 // LDY #$00 - //^codeptr = $A0; codeptr++ // LDY #imm - //^codeptr = $00; codeptr++ // $00 + 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=>14 = $00A0 // LDY #$00 codeptr = codeptr + 16 A_IS_TOSL = FALSE break is $BA // IDXLW i++ - //puts("IDXLW "); puti(^(bytecode+i)) + j = ^(bytecode+i) + //puts("IDXLW "); puti(j) if A_IS_TOSL & TOSL_DIRTY *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin - if ^(bytecode+i) <> 0 - *codeptr = $A0+(^(bytecode+i)<<8) // LDY #imm + if j + *codeptr = $A0+(j<<8) // LDY #imm codeptr = codeptr + 2 fin - codeptr=>0 = $E0B1 // LDA (IFP),Y - //^codeptr = $B1; codeptr++ // LDA (zp),Y - //^codeptr = $E0; codeptr++ // IFP - codeptr->2 = $0A // ASL - //^codeptr = $0A; codeptr++ // ASL - codeptr=>3 = $E785 // STA $E7:TMPL - //^codeptr = $85; codeptr++ // STA zp - //^codeptr = $E7; codeptr++ // $E7:TMPL - codeptr->5 = $C8 // INY - //^codeptr = $C8; codeptr++ // INY - codeptr=>6 = $E0B1 // LDA (IFP),Y - //^codeptr = $B1; codeptr++ // LDA (zp),Y - //^codeptr = $E0; codeptr++ // IFP - codeptr=>8 = $A82A // ROL; TAY - //^codeptr = $2A; codeptr++ // ROL - //^codeptr = $A8; codeptr++ // TAY - codeptr=>10 = $E7A5 // LDA $E7:TMPL - //^codeptr = $A5; codeptr++ // LDA zp - //^codeptr = $E7; codeptr++ // $E7:TMPL - codeptr->12 = $18 // CLC - //^codeptr = $18; codeptr++ // CLC - codeptr=>13 = $D075+(VX<<8) // ADC ESTKL,X - //^codeptr = $75; codeptr++ // ADC zp,X - //^codeptr = $D0+VX; codeptr++ // ESTKL - codeptr=>15 = $D095+(VX<<8) // STA ESTKL,X - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $D0+VX; codeptr++ // ESTKL - codeptr->17 = $98 // TAY - //^codeptr = $98; codeptr++ // TYA - codeptr=>18 = $C075+(VX<<8) // ADC ESTKLH,X - //^codeptr = $75; codeptr++ // ADC zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH - codeptr=>20 = $C095+(VX<<8) // STA ESTKLH,X - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH - codeptr=>22 = $00A0 // LDY #$00 - //^codeptr = $A0; codeptr++ // LDY #imm - //^codeptr = $00; codeptr++ // $00 - codeptr = codeptr + 24 - A_IS_TOSL = FALSE + 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 // TAY + codeptr=>18 = $C075+(VX<<8) // ADC ESTKLH,X + codeptr=>20 = $C095+(VX<<8) // STA ESTKLH,X + codeptr=>22 = $00A0 // LDY #$00 + codeptr = codeptr + 24 + A_IS_TOSL = FALSE break is $BC // IDXAB i++ @@ -2557,87 +1704,47 @@ def compiler(defptr)#0 *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin - codeptr->0 = $AD // LDA abs - //^codeptr = $AD; codeptr++ // LDA abs + codeptr->0 = $AD // LDA abs codeptr=>1 = *(bytecode+i) - //*codeptr = *(bytecode+i); codeptr = codeptr + 2 - codeptr->3 = $0A // ASL - //^codeptr = $0A; codeptr++ // ASL - codeptr=>4 = $0290 // BCC +2 - //^codeptr = $90; codeptr++ // BCC rel - //^codeptr = $02; codeptr++ // +2 - codeptr=>6 = $18C8 // INY; CLC - //^codeptr = $C8; codeptr++ // INY - //^codeptr = $18; codeptr++ // CLC - codeptr=>8 = $D075+(VX<<8) // ADC ESTKL,X - //^codeptr = $75; codeptr++ // ADC zp,X - //^codeptr = $D0+VX; codeptr++ // ESTKL - codeptr=>10 = $D095+(VX<<8) // STA ESTKL,X - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $D0+VX; codeptr++ // ESTKL - codeptr->12 = $98 // TYA - //^codeptr = $98; codeptr++ // TYA - codeptr=>13 = $C075+(VX<<8) // ADC ESTKH,X - //^codeptr = $75; codeptr++ // ADC zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH - codeptr=>15 = $C095+(VX<<8) // STA ESTKLH,X - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH - codeptr=>17 = $00A0 // LDY #$00 - //^codeptr = $A0; codeptr++ // LDY #imm - //^codeptr = $00; codeptr++ // $00 - codeptr = codeptr + 19 - A_IS_TOSL = FALSE + 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=>17 = $00A0 // LDY #$00 + codeptr = codeptr + 19 + A_IS_TOSL = FALSE i++ break is $BE i++ - //puts("IDXAW $"); puth(*(bytecode+i)) + dest = *(bytecode+i) + i++ + //puts("IDXAW $"); puth(dest) if A_IS_TOSL & TOSL_DIRTY *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin - codeptr->0 = $AD // LDA abs - //^codeptr = $AD; codeptr++ // LDA abs - codeptr=>1 = *(bytecode+i) - //*codeptr = *(bytecode+i); codeptr = codeptr + 2 - codeptr->3 = $0A // ASL - //^codeptr = $0A; codeptr++ // ASL - codeptr=>4 = $E785 // STA $E7:TMPL - //^codeptr = $85; codeptr++ // STA zp - //^codeptr = $E7; codeptr++ // $E7:TMPL - codeptr->6 = $AD // LDA abs - //^codeptr = $AD; codeptr++ // LDA abs - codeptr=>7 = *(bytecode+i)+1 - //*codeptr = *(bytecode+i)+1; codeptr = codeptr + 2 - codeptr=>9 = $A82A // ROL; TAY - //^codeptr = $2A; codeptr++ // ROL - //^codeptr = $A8; codeptr++ // TAY - codeptr=>11 = $E7A5 // LDA $E7:TMPL - //^codeptr = $A5; codeptr++ // LDA zp - //^codeptr = $E7; codeptr++ // $E7:TMPL - codeptr->13 = $18 // CLC - //^codeptr = $18; codeptr++ // CLC - codeptr=>14 = $D075+(VX<<8) // ADC ESTKL,X - //^codeptr = $75; codeptr++ // ADC zp,X - //^codeptr = $D0+VX; codeptr++ // ESTKL - codeptr=>16 = $D095+(VX<<8) // STA ESTKL,X - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $D0+VX; codeptr++ // ESTKL - codeptr->18 = $98 // TYA - //^codeptr = $98; codeptr++ // TYA - codeptr=>19 = $C075+(VX<<8) // ADC ESTKH,X - //^codeptr = $75; codeptr++ // ADC zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH - codeptr=>21 = $C095+(VX<<8) // STA ESTKLH,X - //^codeptr = $95; codeptr++ // STA zp,X - //^codeptr = $C0+VX; codeptr++ // ESTKH - codeptr=>23 = $00A0 // LDY #$00 - //^codeptr = $A0; codeptr++ // LDY #imm - //^codeptr = $00; codeptr++ // $00 - codeptr = codeptr + 25 - A_IS_TOSL = FALSE - i++ + 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=>23 = $00A0 // LDY #$00 + codeptr = codeptr + 25 + A_IS_TOSL = FALSE break is $FE // NOPed out earlier by SELect break From 7cd9c00706a5124f1171f1c799c71033101e973a Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Tue, 27 Mar 2018 20:00:49 -0700 Subject: [PATCH 106/147] Fix SELect default branch --- src/libsrc/apple/jit.pla | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/src/libsrc/apple/jit.pla b/src/libsrc/apple/jit.pla index c4a6388..6e54212 100644 --- a/src/libsrc/apple/jit.pla +++ b/src/libsrc/apple/jit.pla @@ -84,7 +84,7 @@ def compiler(defptr)#0 isdata = addrxlate // Use this buffer i = 0 while i <= defptr->bytecodesize - if not isdata->[i] + if not ^(isdata+i) when (^(bytecode+i) & $FE) // // Multi-byte operands @@ -164,20 +164,16 @@ def compiler(defptr)#0 i++ case = i + *(bytecode+i) i++ - isdata->[case] = 1 // Flag as data + ^(isdata+case) = TRUE // Flag as data j = ^(bytecode+case) case++ repeat - isdata->[case] = 1 // Flag as data - case++ - isdata->[case] = 1 // Flag as data - case++ - dest = case + *(bytecode+case) + *(isdata+case) = TRUE // Flag as data + case = case + 2 + dest = case + *(bytecode+case) ^(bytecode+dest) = ^(bytecode+dest) | 1 // Flag as branch dest - isdata->[case] = 1 // Flag as data - case++ - isdata->[case] = 1 // Flag as data - case++ + *(isdata+case) = TRUE // Flag as data + case = case + 2 j-- until not j break @@ -203,8 +199,8 @@ def compiler(defptr)#0 codeptr->3 = $58 // ENTER CODE codeptr=>4 = *(bytecode+1) // ENTER FRAME SIZE & ARG COUNT codeptr->6 = $C0 // NATV CODE - codeptr = codeptr + 7 - i = 3 + codeptr = codeptr + 7 + i = 3 fin // // First optimization is to keep zero in Y register at all times @@ -624,8 +620,8 @@ def compiler(defptr)#0 *codeptr = $D0B5-$0100//+(VX<<8) // LDA ESTKL-1,X codeptr = codeptr + 2 fin - codeptr=>0 = $C015-$0100//+(VX<<8) // ORA ESTKH-1,X - codeptr=>2 = $03D0 // BNE +3 + codeptr=>0 = $C015-$0100//+(VX<<8) // ORA ESTKH-1,X + codeptr=>2 = $03D0 // BNE +3 codeptr->4 = $4C // JMP abs codeptr=>5 = addrxlate=>[dest] if not (codeptr->6 & $80) // Unresolved address list @@ -711,12 +707,12 @@ def compiler(defptr)#0 j-- until not j codeptr=>0 = $00A0 // LDY #$00 - codeptr->1 = $4C // JMP abs - codeptr=>2 = addrxlate=>[case] - if not (codeptr->3 & $80) // Unresolved address list - addrxlate=>[case] = codeptr + 2 - *jitcodeptr + codeptr->2 = $4C // JMP abs + codeptr=>3 = addrxlate=>[case] + if not (codeptr->4 & $80) // Unresolved address list + addrxlate=>[case] = codeptr + 3 - *jitcodeptr fin - codeptr = codeptr + 4 + codeptr = codeptr + 5 else codeptr = dest fin From 5e049ebe8e63d84f470c50d3addc9dfb6cfac806 Mon Sep 17 00:00:00 2001 From: Dave Schmenk Date: Tue, 27 Mar 2018 22:13:58 -0700 Subject: [PATCH 107/147] Fix CS destination jump --- src/libsrc/apple/jit.pla | 16 +++++++--------- src/toolsrc/lex.pla | 2 +- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/libsrc/apple/jit.pla b/src/libsrc/apple/jit.pla index 6e54212..49000b2 100644 --- a/src/libsrc/apple/jit.pla +++ b/src/libsrc/apple/jit.pla @@ -90,7 +90,7 @@ def compiler(defptr)#0 // Multi-byte operands // is $2E // CS - i = i + ^(bytecode+i+1) + 1 + i = i + ^(bytecode+i+1)// + 1 break // // Double byte operands @@ -393,9 +393,9 @@ def compiler(defptr)#0 is $2E // CS i++ j = ^(bytecode+i) - dest = i + j + 1 + dest = codeptr + 10 + j //puts("CS "); //puts(bytecode+i); //puts("-->"); puti(dest) - if isule(codeptr + 10 + j, codemax) + if isule(dest, codemax) if A_IS_TOSL & TOSL_DIRTY *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 @@ -405,14 +405,12 @@ def compiler(defptr)#0 codeptr=>2 = $C095+(VX<<8) // STA ESTKH,X codeptr=>4 = $A9+((codeptr+9)<<8) // LDA #6 = $4C // JMP abs - codeptr=>7 = addrxlate=>[dest] - if not (codeptr->8 & $80) // Unresolved address list - addrxlate=>[dest] = codeptr + 7 - *jitcodeptr - fin + dest = codeptr + 10 + j + codeptr=>7 = dest strcpy(codeptr + 9, bytecode + i) i = i + j fin - codeptr = codeptr + 10 + j + codeptr = dest A_IS_TOSL = TOSL_DIRTY // STA ESTKL,X break is $32 // DROP2 @@ -421,7 +419,7 @@ def compiler(defptr)#0 is $30 // DROP //puts("DROP") VX++ // INX - A_IS_TOSL = FALSE + A_IS_TOSL = FALSE break is $34 // DUP //puts("DUP") diff --git a/src/toolsrc/lex.pla b/src/toolsrc/lex.pla index 6d8f062..934c351 100644 --- a/src/toolsrc/lex.pla +++ b/src/toolsrc/lex.pla @@ -325,7 +325,7 @@ def nextln scanptr++ scan else - if token <> EOL_TKN and token <> EOF_TKN; puti(token&$7F); puts("Extraneous characters\n"); exit_err(0); fin + if token <> EOL_TKN and token <> EOF_TKN; putc(token&$7F); puts("Extraneous characters\n"); exit_err(0); fin scanptr = inbuff ^instr = fileio:read(refnum, inbuff, 127) if ^instr From b72e592c9a0ee6491d903a7af23fecbdb9ae5844 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Wed, 28 Mar 2018 11:51:04 -0700 Subject: [PATCH 108/147] Fix SEL tests --- src/libsrc/apple/jit.pla | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libsrc/apple/jit.pla b/src/libsrc/apple/jit.pla index 49000b2..43db616 100644 --- a/src/libsrc/apple/jit.pla +++ b/src/libsrc/apple/jit.pla @@ -265,7 +265,7 @@ def compiler(defptr)#0 if opcode == 0 ^codeptr = $98; codeptr++ // TYA -> LDA #$00 else - *codeptr = $A9+(opcode/2<<8) // LDA #(CN/2) + *codeptr = $A9+(opcode/2<<8) // LDA #(CN/2) codeptr = codeptr + 2 fin *codeptr = $C094+(VX<<8) // STY ESTKH,X @@ -279,7 +279,7 @@ def compiler(defptr)#0 *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin - VX-- // DEX + VX-- // DEX codeptr=>0 = $FFA9 // LDA #$FF codeptr=>2 = $C095+(VX<<8) // STA ESTKH,X codeptr = codeptr + 4 @@ -467,7 +467,7 @@ def compiler(defptr)#0 codeptr->0 = $38 // SEC codeptr=>1 = $E9+(^(bytecode+i)<<8) // SBC #imm codeptr=>3 = $02B0 // BCS +2 - codeptr=>5 = $C0D6+(VX<<8) // INC ESTKH,X + codeptr=>5 = $C0D6+(VX<<8) // DEC ESTKH,X codeptr = codeptr + 7 A_IS_TOSL = TOSL_DIRTY // STA ESTKL,X break @@ -683,7 +683,7 @@ def compiler(defptr)#0 codeptr=>0 = $C0B4+(VX<<8) // LDY ESTKH,X codeptr, VX = resolveX(codeptr + 2, VX + 1) // INX repeat - dest = case + *(bytecode+case) + dest = *(bytecode+case) //puts(" $"); puth(dest) codeptr=>0 = $C9+(dest<<8) // CMP #imm codeptr=>2 = $09D0 // BNE +9 @@ -1684,7 +1684,7 @@ def compiler(defptr)#0 codeptr->12 = $18 // CLC codeptr=>13 = $D075+(VX<<8) // ADC ESTKL,X codeptr=>15 = $D095+(VX<<8) // STA ESTKL,X - codeptr->17 = $98 // TAY + codeptr->17 = $98 // TYA codeptr=>18 = $C075+(VX<<8) // ADC ESTKLH,X codeptr=>20 = $C095+(VX<<8) // STA ESTKLH,X codeptr=>22 = $00A0 // LDY #$00 @@ -1743,7 +1743,7 @@ def compiler(defptr)#0 is $FE // NOPed out earlier by SELect break otherwise - //putc('$'); puth(^(bytecode+i)) + //puts("???: $"); puth(^(bytecode+i)); putln wend fin //putln From 208be4da1f78502467518cf5acd8e2e703d07662 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Wed, 28 Mar 2018 16:30:18 -0700 Subject: [PATCH 109/147] Update images --- PLASMA-BLD2.PO | Bin 143360 -> 143360 bytes PLASMA-SYS2.PO | Bin 143360 -> 143360 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/PLASMA-BLD2.PO b/PLASMA-BLD2.PO index ea8b416694ec3562122d0c2878813b1b2c28cb3a..475a5c65369caf23022826ed343a0d773ec553e3 100644 GIT binary patch delta 18022 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 delta 17992 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 E17_m_s{jB1 diff --git a/PLASMA-SYS2.PO b/PLASMA-SYS2.PO index 40de120950301a21ba70e23073c634dbf0dc9a6d..4ed1ed63ae5b191c5e21ad21fc0345f43c9cc024 100644 GIT binary patch delta 20419 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 delta 11645 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 From 3968f826258b42b576912fcd0234b4d192dd746b Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Wed, 28 Mar 2018 17:02:26 -0700 Subject: [PATCH 110/147] Lose the JIT warmup count --- src/inc/cmdsys.plh | 1 - src/libsrc/apple/jitune.pla | 17 ++++++----------- src/vmsrc/apple/cmd.pla | 1 - src/vmsrc/apple/cmdjit.pla | 11 ++--------- src/vmsrc/apple/plvmjit02.s | 20 ++++++-------------- src/vmsrc/apple/sossys.pla | 1 - 6 files changed, 14 insertions(+), 37 deletions(-) diff --git a/src/inc/cmdsys.plh b/src/inc/cmdsys.plh index b744f1b..a65a01c 100644 --- a/src/inc/cmdsys.plh +++ b/src/inc/cmdsys.plh @@ -53,7 +53,6 @@ import cmdsys byte syserr byte jitcount byte jitsize - word jitwarmup byte refcons // Apple /// specific byte devcons // Apple /// specific byte cmdparser diff --git a/src/libsrc/apple/jitune.pla b/src/libsrc/apple/jitune.pla index 910e64e..4a4356b 100644 --- a/src/libsrc/apple/jitune.pla +++ b/src/libsrc/apple/jitune.pla @@ -23,28 +23,23 @@ end arg = argNext(argFirst) if ^arg if arg->1 >= '0' and arg->1 <= '9' - cmdsys:jitwarmup = atoi(arg) + val = atoi(arg) + if val > 255 + val = 255 + fin + cmdsys.jitcount = val arg = argNext(arg) if ^arg val = atoi(arg) if val > 255 val = 255 fin - cmdsys.jitcount = val - arg = argNext(arg) - if ^arg - val = atoi(arg) - if val > 255 - val = 255 - fin - cmdsys.jitsize = val - fin + cmdsys.jitsize = val fin else puts("Usage: JITUNE WARMUP [CALLCOUNT [MAXSIZE]]\n") fin fin -puts("JIT Warm Up: "); puti(cmdsys:jitwarmup); putln puts("JIT Call Count: "); puti(cmdsys.jitcount); putln puts("JIT Max Size: "); puti(cmdsys.jitsize); putln done diff --git a/src/vmsrc/apple/cmd.pla b/src/vmsrc/apple/cmd.pla index b3c766c..bf6ed89 100755 --- a/src/vmsrc/apple/cmd.pla +++ b/src/vmsrc/apple/cmd.pla @@ -45,7 +45,6 @@ word = @execmod, @open, @close, @read, @write byte perr byte jitcount = $10 byte jitsize = $FF -word jitwarmup = $0100 // // Working input buffer overlayed with strings table // diff --git a/src/vmsrc/apple/cmdjit.pla b/src/vmsrc/apple/cmdjit.pla index 686a32f..a2a4206 100755 --- a/src/vmsrc/apple/cmdjit.pla +++ b/src/vmsrc/apple/cmdjit.pla @@ -41,8 +41,6 @@ end // const jitcomp = $03E2 const jitcodeptr = $03E4 -const jitwarming = $03E6 -const jitcode = $BF00 // // Pedefined functions. // @@ -60,9 +58,8 @@ word syspath word syscmdln word = @execmod, @open, @close, @read, @write byte perr -byte jitcount = $01 -byte jitsize = $FF -word jitwarmup = $0000 +byte jitcount = 45 +byte jitsize = 128 // // Working input buffer overlayed with strings table // @@ -1191,10 +1188,6 @@ def loadmod(mod)#1 codefix = defaddr - bytecode defofst = defaddr - defofst // - // Reser JIT warmup count - // - *jitwarming = jitwarmup - // // Run through the DeFinition Dictionary. // deffirst = 1 diff --git a/src/vmsrc/apple/plvmjit02.s b/src/vmsrc/apple/plvmjit02.s index d7dc43e..cf16ce5 100755 --- a/src/vmsrc/apple/plvmjit02.s +++ b/src/vmsrc/apple/plvmjit02.s @@ -54,7 +54,6 @@ STRBUF = $0280 INTERP = $03D0 JITCOMP = $03E2 JITCODE = $03E4 -JITWARM = $03E6 ;****************************** ;* * ;* INTERPRETER INITIALIZATION * @@ -442,14 +441,12 @@ JITINTRPX PHP SBC #$00 STA TMPH LDY #$05 - LDA JITWARM+1 ; CHECK WARMING - ORA JITWARM - BEQ DECCALL -DECWARM LDA JITWARM ; DEC WARMING COUNT - BNE + - DEC JITWARM+1 -+ DEC JITWARM -NOJIT DEY ; INTERP BYTECODE AS USUAL + LDA (TMP),Y ; DEC JIT COUNT + SEC + SBC #$01 + STA (TMP),Y + BEQ RUNJIT + DEY ; INTERP BYTECODE AS USUAL LDA (TMP),Y STA IPH DEY @@ -460,11 +457,6 @@ NOJIT DEY ; INTERP BYTECODE AS USUAL STA OPPAGE STA ALTRDON JMP FETCHOP -DECCALL LDA (TMP),Y ; DEC JIT COUNT - SEC - SBC #$01 - STA (TMP),Y - BNE NOJIT RUNJIT LDA JITCOMP STA SRCL LDA JITCOMP+1 diff --git a/src/vmsrc/apple/sossys.pla b/src/vmsrc/apple/sossys.pla index 6ee789b..d408a4a 100755 --- a/src/vmsrc/apple/sossys.pla +++ b/src/vmsrc/apple/sossys.pla @@ -36,7 +36,6 @@ word = @execmod, @open, @close, @read, @write byte perr byte jitcount = $10 byte jitsize = $FF -word jitwarmup = $0100 byte refcons = 0 byte devcons = 0 word cmdparser From 148031d192f4b5d0b64f5c7b481d898ad2b26e77 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Thu, 29 Mar 2018 07:58:31 -0700 Subject: [PATCH 111/147] Make SIEVE JITable --- src/samplesrc/sieve.pla | 44 +++++++++++++++++++++----------------- src/vmsrc/apple/cmdjit.pla | 2 +- 2 files changed, 25 insertions(+), 21 deletions(-) diff --git a/src/samplesrc/sieve.pla b/src/samplesrc/sieve.pla index eed1c77..77beecc 100644 --- a/src/samplesrc/sieve.pla +++ b/src/samplesrc/sieve.pla @@ -11,26 +11,30 @@ def beep#0 putc(7) end -beep -//for iter = 1 to 10 - flag = heapalloc(sizepl) - memset(flag, TRUE, sizepl) - count = 0 - for i = 0 to size - if flag->[i] - prime = i + i + 3 - k = i + prime - while k <= size - flag->[k] = FALSE - k = k + prime - loop - count = count + 1 - puti(prime) - putln - fin - next -//next -beep +def sieve#0 + beep + //for iter = 1 to 10 + flag = heapalloc(sizepl) + memset(flag, TRUE, sizepl) + count = 0 + for i = 0 to size + if flag->[i] + prime = i + i + 3 + k = i + prime + while k <= size + flag->[k] = FALSE + k = k + prime + loop + count = count + 1 + puti(prime) + putln + fin + next + //next + beep +end + +sieve puti(count) puts(" primes.\n") done diff --git a/src/vmsrc/apple/cmdjit.pla b/src/vmsrc/apple/cmdjit.pla index a2a4206..de20090 100755 --- a/src/vmsrc/apple/cmdjit.pla +++ b/src/vmsrc/apple/cmdjit.pla @@ -59,7 +59,7 @@ word syscmdln word = @execmod, @open, @close, @read, @write byte perr byte jitcount = 45 -byte jitsize = 128 +byte jitsize = 255 // // Working input buffer overlayed with strings table // From b5885dfe8fa071662a5a5bceb60c1516b082bb42 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Thu, 29 Mar 2018 12:19:49 -0700 Subject: [PATCH 112/147] Better tracking of Y register WIP --- src/libsrc/apple/jit.pla | 414 ++++++++++++++++++++++----------------- 1 file changed, 230 insertions(+), 184 deletions(-) diff --git a/src/libsrc/apple/jit.pla b/src/libsrc/apple/jit.pla index 43db616..c39875c 100644 --- a/src/libsrc/apple/jit.pla +++ b/src/libsrc/apple/jit.pla @@ -31,8 +31,12 @@ const interpentry = $03DC // // TOS caching values // -const TOSL_DIRTY = 1 -const TOSL_CLEAN = 2 +const TOS_DIRTY = 1 +const TOS_CLEAN = 2 +// +// Y unknown value +// +const UNKNOWN = -1 // // Resolve virtual X with real X // @@ -51,7 +55,7 @@ end // JIT compiler entry // def compiler(defptr)#0 - word codeptr, isdata, addrxlate, bytecode, i, case, dest, VX + 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 @@ -186,8 +190,9 @@ def compiler(defptr)#0 // Compile the bytecodes // codeptr = *jitcodeptr - VX = 0 // Virtual X register 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 @@ -202,10 +207,6 @@ def compiler(defptr)#0 codeptr = codeptr + 7 i = 3 fin - // - // First optimization is to keep zero in Y register at all times - // - *codeptr = $00A0; codeptr = codeptr + 2 // LDY #$00 while isule(codeptr, codemax) //putc('$'); puth(codeptr); putc(':') //putc('['); puti(i); //puts("] ") @@ -214,13 +215,14 @@ def compiler(defptr)#0 // // Optimization fence. Sync A and X registers // - if A_IS_TOSL & TOSL_DIRTY - *codeptr = $D095+(VX<<8) // STA ESTKL,X + 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 - codeptr, VX = resolveX(codeptr, VX) - opcode = opcode & $FE + opcode = opcode & $FE fin // // Update bytecode->native code address translation. @@ -257,10 +259,15 @@ def compiler(defptr)#0 // if opcode < $20 // CONSTANT NYBBLE //puts("CN $"); putb(opcode/2) - if A_IS_TOSL & TOSL_DIRTY + 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 VX-- // DEX if opcode == 0 ^codeptr = $98; codeptr++ // TYA -> LDA #$00 @@ -270,12 +277,12 @@ def compiler(defptr)#0 fin *codeptr = $C094+(VX<<8) // STY ESTKH,X codeptr = codeptr + 2 - A_IS_TOSL = TOSL_DIRTY // STA ESTKL,X + A_IS_TOSL = TOS_DIRTY // STA ESTKL,X else when opcode is $20 // MINUS ONE //puts("MINUS_ONE") - if A_IS_TOSL & TOSL_DIRTY + if A_IS_TOSL & TOS_DIRTY *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin @@ -283,7 +290,7 @@ def compiler(defptr)#0 codeptr=>0 = $FFA9 // LDA #$FF codeptr=>2 = $C095+(VX<<8) // STA ESTKH,X codeptr = codeptr + 4 - A_IS_TOSL = TOSL_DIRTY // STA ESTKL,X + A_IS_TOSL = TOS_DIRTY // STA ESTKL,X break is $22 // BREQ i++ @@ -336,31 +343,41 @@ def compiler(defptr)#0 i++ dest = *(bytecode+i) //puts("LA/CW $"); puth(dest) - if A_IS_TOSL & TOSL_DIRTY - *codeptr = $D095+(VX<<8) // STA ESTKL,X + 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 + if VY <> 0 + *codeptr = $00A0 // LDY #$00 + codeptr = codeptr + 2 + VY = 0 + fin + VX-- // DEX + codeptr=>0 = $A9+(dest&$FF00) // LDA #2 = $C095+(VX<<8) // STA ESTKH,X if dest & $00FF == 0 - codeptr->4 = $98 // TYA -> LDA #$00 + codeptr->4 = $98 // TYA -> LDA #$00 codeptr = codeptr + 5 else codeptr=>4 = $A9+(dest<<8) // LDA #>VAL codeptr = codeptr + 6 fin - A_IS_TOSL = TOSL_DIRTY // STA ESTKL,X + 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 & TOSL_DIRTY + 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 VX-- // DEX if j *codeptr = $A9+(j<<8) // LDA #imm @@ -380,15 +397,20 @@ def compiler(defptr)#0 is $2A // CB i++ //puts("CB $"); putb(^(bytecode+i)) - if A_IS_TOSL & TOSL_DIRTY + 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 VX-- // DEX codeptr=>0 = $A9+(^(bytecode+i)<<8) // LDA #imm codeptr=>2 = $C094+(VX<<8) // STY ESTKH,X codeptr = codeptr + 4 - A_IS_TOSL = TOSL_DIRTY // STA ESTKL,X + A_IS_TOSL = TOS_DIRTY // STA ESTKL,X break is $2E // CS i++ @@ -396,7 +418,7 @@ def compiler(defptr)#0 dest = codeptr + 10 + j //puts("CS "); //puts(bytecode+i); //puts("-->"); puti(dest) if isule(dest, codemax) - if A_IS_TOSL & TOSL_DIRTY + if A_IS_TOSL & TOS_DIRTY *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin @@ -411,7 +433,7 @@ def compiler(defptr)#0 i = i + j fin codeptr = dest - A_IS_TOSL = TOSL_DIRTY // STA ESTKL,X + A_IS_TOSL = TOS_DIRTY // STA ESTKL,X break is $32 // DROP2 //puts("DROP2") @@ -426,16 +448,16 @@ def compiler(defptr)#0 if not A_IS_TOSL *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 - elsif A_IS_TOSL & TOSL_DIRTY + elsif A_IS_TOSL & TOS_DIRTY *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin VX-- // DEX codeptr=>0 = $C0B4+$0100+(VX<<8) // LDY ESTKH+1,X codeptr=>2 = $C094+(VX<<8) // STY ESTKH,X - codeptr=>4 = $00A0 // LDY #$00 - codeptr = codeptr + 6 - A_IS_TOSL = TOSL_DIRTY // STA ESTKL,X + codeptr = codeptr + 4 + VY = UNKNOWN + A_IS_TOSL = TOS_DIRTY // STA ESTKL,X break //is $36 //puts("DIVMOD") @@ -455,7 +477,7 @@ def compiler(defptr)#0 codeptr=>3 = $0290 // BCC +2 codeptr=>5 = $C0F6+(VX<<8) // INC ESTKH,X codeptr = codeptr + 7 - A_IS_TOSL = TOSL_DIRTY // STA ESTKL,X + A_IS_TOSL = TOS_DIRTY // STA ESTKL,X break is $3A // SUBI i++ @@ -469,11 +491,16 @@ def compiler(defptr)#0 codeptr=>3 = $02B0 // BCS +2 codeptr=>5 = $C0D6+(VX<<8) // DEC ESTKH,X codeptr = codeptr + 7 - A_IS_TOSL = TOSL_DIRTY // STA ESTKL,X + 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 @@ -481,7 +508,7 @@ def compiler(defptr)#0 codeptr=>0 = $29+(^(bytecode+i)<<8) // AND #imm codeptr=>2 = $C094+(VX<<8) // STY ESTKH,X codeptr = codeptr + 4 - A_IS_TOSL = TOSL_DIRTY // STA ESTKL,X + A_IS_TOSL = TOS_DIRTY // STA ESTKL,X break is $3E // ORI i++ @@ -490,12 +517,16 @@ def compiler(defptr)#0 *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - codeptr=>0 = $09+(^(bytecode+i)<<8) // ORA #imm - codeptr = codeptr + 2 - A_IS_TOSL = TOSL_DIRTY // STA ESTKL,X + *codeptr = $09+(^(bytecode+i)<<8) // ORA #imm + codeptr = codeptr + 2 + A_IS_TOSL = TOS_DIRTY // STA ESTKL,X break is $40 // ISEQ //puts("ISEQ") + if VY <> 0 + *codeptr = $00A0 // LDY #$00 + codeptr = codeptr + 2 + fin if not A_IS_TOSL *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 @@ -507,13 +538,17 @@ def compiler(defptr)#0 codeptr=>8 = $01D0 // BNE +1 codeptr=>10 = $9888 // DEY; TYA codeptr=>12 = $C094+$0100+(VX<<8) // STY ESTKH+1,X - codeptr=>14 = $00A0 // LDY #$00 + codeptr = codeptr + 14 VX++ // INX - codeptr = codeptr + 16 - A_IS_TOSL = TOSL_DIRTY // STA ESTKL,X + VY = UNKNOWN + A_IS_TOSL = TOS_DIRTY // STA ESTKL,X break is $42 // ISNE //puts("ISNE") + if VY <> 0 + *codeptr = $00A0 // LDY #$00 + codeptr = codeptr + 2 + fin if not A_IS_TOSL *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 @@ -525,13 +560,17 @@ def compiler(defptr)#0 codeptr=>8 = $01F0 // BEQ +1 codeptr=>10 = $9888 // DEY; TYA codeptr=>12 = $C094+$0100+(VX<<8) // STY ESTKH+1,X - codeptr=>14 = $00A0 // LDY #$00 + codeptr = codeptr + 14 VX++ // INX - codeptr = codeptr + 16 - A_IS_TOSL = TOSL_DIRTY // STA ESTKL,X + VY = UNKNOWN + A_IS_TOSL = TOS_DIRTY // STA ESTKL,X break is $44 // ISGT //puts("ISGT") + if VY <> 0 + *codeptr = $00A0 // LDY #$00 + codeptr = codeptr + 2 + fin if not A_IS_TOSL *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 @@ -544,17 +583,21 @@ def compiler(defptr)#0 codeptr=>10 = $0110 // BPL +1 codeptr=>12 = $9888 // DEY TYA codeptr=>14 = $C094+$0100+(VX<<8) // STY ESTKH+1,X - codeptr=>16 = $00A0 // LDY #$00 + codeptr = codeptr + 16 VX++ // INX - codeptr = codeptr + 18 - A_IS_TOSL = TOSL_DIRTY // STA ESTKL,X + VY = UNKNOWN + A_IS_TOSL = TOS_DIRTY // STA ESTKL,X break is $46 //puts("ISLT") - if A_IS_TOSL & TOSL_DIRTY + 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 @@ -564,17 +607,21 @@ def compiler(defptr)#0 codeptr=>12 = $0110 // BPL +1 codeptr=>14 = $9888 // DEY; TYA codeptr=>16 = $C094+$0100+(VX<<8) // STY ESTKH+1,X - codeptr=>18 = $00A0 // LDY #$00 + codeptr = codeptr + 18 VX++ // INX - codeptr = codeptr + 20 - A_IS_TOSL = TOSL_DIRTY // STA ESTKL,X + VY = UNKNOWN + A_IS_TOSL = TOS_DIRTY // STA ESTKL,X break is $48 //puts("ISGE") - if A_IS_TOSL & TOSL_DIRTY + 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 @@ -584,13 +631,17 @@ def compiler(defptr)#0 codeptr=>12 = $0130 // BMI +1 codeptr=>14 = $9888 // DEY; TYA codeptr=>16 = $C094+$0100+(VX<<8) // STY ESTKH+1,X - codeptr=>18 = $00A0 // LDY #$00 + codeptr = codeptr + 18 VX++ // INX - codeptr = codeptr + 20 - A_IS_TOSL = TOSL_DIRTY // STA ESTKL,X + VY = UNKNOWN + A_IS_TOSL = TOS_DIRTY // STA ESTKL,X break is $4A // ISLE //puts("ISLE") + if VY <> 0 + *codeptr = $00A0 // LDY #$00 + codeptr = codeptr + 2 + fin if not A_IS_TOSL *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 @@ -603,10 +654,10 @@ def compiler(defptr)#0 codeptr=>10 = $0130 // BMI +1 codeptr=>12 = $9888 // DEY; TYA codeptr=>14 = $C094+$0100+(VX<<8) // STY ESTKH+1,X - codeptr=>16 = $00A0 // LDY #$00 + codeptr = codeptr + 16 VX++ // INX - codeptr = codeptr + 18 - A_IS_TOSL = TOSL_DIRTY // STA ESTKL,X + VY = UNKNOWN + A_IS_TOSL = TOS_DIRTY // STA ESTKL,X break is $4C // BRFLS i++ @@ -626,6 +677,7 @@ def compiler(defptr)#0 addrxlate=>[dest] = codeptr + 5 - *jitcodeptr fin codeptr = codeptr + 7 + VY = UNKNOWN A_IS_TOSL = FALSE break is $4E // BRTRU @@ -654,7 +706,7 @@ def compiler(defptr)#0 i++ //puts("BRNCH "); puti(dest) codeptr, VX = resolveX(codeptr, VX) - if A_IS_TOSL & TOSL_DIRTY + if A_IS_TOSL & TOS_DIRTY *codeptr = $D095//+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin @@ -685,35 +737,34 @@ def compiler(defptr)#0 repeat dest = *(bytecode+case) //puts(" $"); puth(dest) - codeptr=>0 = $C9+(dest<<8) // CMP #imm - codeptr=>2 = $09D0 // BNE +9 - codeptr=>4 = $C0+(dest&$FF00) // CPY #imm - codeptr=>6 = $05D0 // BNE +5 + 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 = $00A0 // LDY #$00 - codeptr->10 = $4C // JMP abs - codeptr=>11 = addrxlate=>[dest] - if not (codeptr->12 & $80) // Unresolved address list - addrxlate=>[dest] = codeptr + 11 - *jitcodeptr + 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 + 13 + codeptr = codeptr + 11 *(bytecode+case) = $FEFE case = case + 2 j-- until not j - codeptr=>0 = $00A0 // LDY #$00 - codeptr->2 = $4C // JMP abs - codeptr=>3 = addrxlate=>[case] - if not (codeptr->4 & $80) // Unresolved address list - addrxlate=>[case] = codeptr + 3 - *jitcodeptr + 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 + 5 + codeptr = codeptr + 3 else codeptr = dest fin + VY = UNKNOWN A_IS_TOSL = FALSE break is $54 // CALL @@ -723,14 +774,14 @@ def compiler(defptr)#0 // Call address // codeptr, VX = resolveX(codeptr, VX) - if A_IS_TOSL & TOSL_DIRTY + 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=>3 = $00A0 // LDY #$00 - codeptr = codeptr + 5 + codeptr = codeptr + 3 + VY = UNKNOWN A_IS_TOSL = FALSE i++ break @@ -752,8 +803,8 @@ def compiler(defptr)#0 // codeptr->0 = $20 // JSR abs codeptr=>1 = $00E6 // $E6:JMPTMP - codeptr=>3 = $00A0 // LDY #$00 - codeptr = codeptr + 5 + codeptr = codeptr + 3 + VY = UNKNOWN A_IS_TOSL = FALSE break is $5A // LEAVE @@ -763,7 +814,7 @@ def compiler(defptr)#0 // Call into VM // codeptr, VX = resolveX(codeptr, VX) - if A_IS_TOSL & TOSL_DIRTY + if A_IS_TOSL & TOS_DIRTY *codeptr = $D095//+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin @@ -771,23 +822,24 @@ def compiler(defptr)#0 codeptr=>1 = $03D0 // INTERP codeptr=>3 = $5A + (^(bytecode+i)<<8) // LEAVE CODE AND OPERAND codeptr = codeptr + 5 + VY = UNKNOWN A_IS_TOSL = FALSE break is $5C // RET //puts("RET") codeptr, VX = resolveX(codeptr, VX) - if A_IS_TOSL & TOSL_DIRTY + if A_IS_TOSL & TOS_DIRTY *codeptr = $D095//+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin - ^codeptr = $60 // RTS - codeptr++ + ^codeptr = $60; codeptr++ // RTS + VY = UNKNOWN A_IS_TOSL = FALSE break is $5E // CFFB i++ //puts("CFFB $FF"); putb(^(bytecode+i)) - if A_IS_TOSL & TOSL_DIRTY + if A_IS_TOSL & TOS_DIRTY *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin @@ -796,10 +848,15 @@ def compiler(defptr)#0 codeptr=>2 = $C095+(VX<<8) // STA ESTKH,X codeptr=>4 = $A9+(^(bytecode+i)<<8) // LDA #imm codeptr = codeptr + 6 - A_IS_TOSL = TOSL_DIRTY // STA ESTKL,X + A_IS_TOSL = TOS_DIRTY // STA ESTKL,X break is $60 // LB //puts("LB") + if VY <> 0 + *codeptr = $00A0 // LDY #$00 + codeptr = codeptr + 2 + VY = 0 + fin if not A_IS_TOSL *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 @@ -808,7 +865,7 @@ def compiler(defptr)#0 codeptr=>2 = $C0A1-$0100+(VX<<8) // LDA (ESTKH-1,X) codeptr=>4 = $C094+(VX<<8) // STY ESTKH,X codeptr = codeptr + 6 - A_IS_TOSL = TOSL_DIRTY // STA ESTKL,X + A_IS_TOSL = TOS_DIRTY // STA ESTKL,X break is $62 // LW //puts("LW") @@ -831,72 +888,75 @@ def compiler(defptr)#0 i++ j = ^(bytecode+i) //puts("LLB "); puti(j) - if A_IS_TOSL & TOSL_DIRTY + if A_IS_TOSL & TOS_DIRTY *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin VX-- // DEX - if j - *codeptr = $A0+(j<<8) // LDY #imm + if VY <> j + *codeptr = $A0+(j<<8) // LDY #imm codeptr = codeptr + 2 + VY = j fin *codeptr = $E0B1 // LDA (IFP),Y codeptr = codeptr + 2 - if j + 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 = TOSL_DIRTY // STA ESTKL,X + A_IS_TOSL = TOS_DIRTY // STA ESTKL,X break is $66 // LLW i++ j = ^(bytecode+i) //puts("LLW "); puti(j) - if A_IS_TOSL & TOSL_DIRTY + if A_IS_TOSL & TOS_DIRTY *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin - VX-- // DEX - if j + if VY <> j *codeptr = $A0+((j+1)<<8) // LDY #imm codeptr = codeptr + 2 else ^codeptr = $C8; codeptr++ // INY fin + VX-- // DEX 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 - if j - *codeptr = $00A0 // LDY #$00 - codeptr = codeptr + 2 - else - fin - A_IS_TOSL = TOSL_DIRTY // STA ESTKL,X + VY = j + A_IS_TOSL = TOS_DIRTY // STA ESTKL,X break is $68 // LAB i++ //puts("LAB $"); puth(*(bytecode+i)) - if A_IS_TOSL & TOSL_DIRTY + 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 VX-- // DEX codeptr->0 = $AD // LDA abs codeptr=>1 = *(bytecode+i) codeptr=>3 = $C094+(VX<<8) // STY ESTKH,X codeptr = codeptr + 5 - A_IS_TOSL = TOSL_DIRTY // STA ESTKL,X + A_IS_TOSL = TOS_DIRTY // STA ESTKL,X i++ break is $6A // LAW i++ dest = *(bytecode+i) //puts("LAW $"); puth(dest) - if A_IS_TOSL & TOSL_DIRTY + if A_IS_TOSL & TOS_DIRTY *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin @@ -907,7 +967,7 @@ def compiler(defptr)#0 codeptr->5 = $AD // LDA abs codeptr=>6 = dest codeptr = codeptr + 8 - A_IS_TOSL = TOSL_DIRTY // STA ESTKL,X + A_IS_TOSL = TOS_DIRTY // STA ESTKL,X i++ break is $6C // DLB @@ -917,28 +977,25 @@ def compiler(defptr)#0 if not A_IS_TOSL *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 - A_IS_TOSL = TOSL_CLEAN + A_IS_TOSL = TOS_CLEAN fin - if j + if VY <> j *codeptr = $A0+(j<<8) // LDY #imm codeptr = codeptr + 2 + VY = j fin *codeptr = $E091 // STA (IFP),Y codeptr = codeptr + 2 - if j - *codeptr = $00A0 // LDY #$00 - codeptr = codeptr + 2 - fin break is $6E // DLW i++ j = ^(bytecode+i) //puts("DLW "); puti(j) - if A_IS_TOSL & TOSL_DIRTY + if A_IS_TOSL & TOS_DIRTY *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin - if j + if VY <> j *codeptr = $A0+((j+1)<<8) // LDY #imm codeptr = codeptr + 2 else @@ -950,11 +1007,8 @@ def compiler(defptr)#0 codeptr=>5 = $D0B5+(VX<<8) // LDA ESTKL,X codeptr=>7 = $E091 // STA (IFP),Y codeptr = codeptr + 9 - if j - *codeptr = $00A0 // LDY #$00 - codeptr = codeptr + 2 - fin - A_IS_TOSL = TOSL_CLEAN + VY = j + A_IS_TOSL = TOS_CLEAN break is $70 // SB //puts("SB") @@ -965,8 +1019,8 @@ def compiler(defptr)#0 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) - VX = VX + 2 // INX; INX codeptr = codeptr + 6 + VX = VX + 2 // INX; INX A_IS_TOSL = FALSE break is $72 // SW @@ -983,9 +1037,9 @@ def compiler(defptr)#0 codeptr=>10 = $02D0 // BNE +2 codeptr=>12 = $C0F6+(VX<<8) // INC ESTKH,X codeptr=>14 = $C081-$0100+(VX<<8) // STA (ESTKH-1,X) + codeptr = codeptr + 16 VX = VX + 2 // INX; INX - codeptr = codeptr + 16 - A_IS_TOSL = FALSE + A_IS_TOSL = FALSE break is $74 // SLB i++ @@ -995,16 +1049,13 @@ def compiler(defptr)#0 *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - if j + if VY <> j *codeptr = $A0+(j<<8) // LDY #imm codeptr = codeptr + 2 + VY = j fin *codeptr = $E091 // STA (IFP),Y codeptr = codeptr + 2 - if j - *codeptr = $00A0 // LDY #$00 - codeptr = codeptr + 2 - fin VX++ // INX A_IS_TOSL = FALSE break @@ -1016,7 +1067,7 @@ def compiler(defptr)#0 *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - if j + if VY <> j *codeptr = $A0+(j<<8) // LDY #imm codeptr = codeptr + 2 fin @@ -1024,15 +1075,10 @@ def compiler(defptr)#0 codeptr->2 = $C8 // INY codeptr=>3 = $C0B5+(VX<<8) // LDA ESTKH,X codeptr=>5 = $E091 // STA (IFP),Y - if j - codeptr=>7 = $00A0 // LDY #$00 - codeptr = codeptr + 9 - else - codeptr->7 = $88 // DEY - codeptr = codeptr + 8 - fin + codeptr = codeptr + 7 VX++ // INX - A_IS_TOSL = FALSE + VY = j + 1 + A_IS_TOSL = FALSE break is $78 // SAB i++ @@ -1043,8 +1089,8 @@ def compiler(defptr)#0 fin codeptr->0 = $8D // STA abs codeptr=>1 = *(bytecode+i) - VX++ // INX codeptr = codeptr + 3 + VX++ // INX A_IS_TOSL = FALSE i++ break @@ -1061,8 +1107,8 @@ def compiler(defptr)#0 codeptr=>3 = $C0B5+(VX<<8) // LDA ESTKH,X codeptr->5 = $8D // STA abs codeptr=>6 = dest+1 - VX++ // INX codeptr = codeptr + 8 + VX++ // INX A_IS_TOSL = FALSE i++ break @@ -1072,9 +1118,9 @@ def compiler(defptr)#0 if not A_IS_TOSL *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 - A_IS_TOSL = TOSL_CLEAN + A_IS_TOSL = TOS_CLEAN fin - codeptr->0 = $8D // STA abs + codeptr->0 = $8D // STA abs codeptr=>1 = *(bytecode+i) codeptr = codeptr + 3 i++ @@ -1086,15 +1132,15 @@ def compiler(defptr)#0 if not A_IS_TOSL *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 - A_IS_TOSL = TOSL_CLEAN + 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 codeptr=>6 = dest+1 - codeptr=>8 = $00A0 // LDY #$00 - codeptr = codeptr + 10 + codeptr = codeptr + 8 + VY = UNKNOWN i++ break is $80 // NOT @@ -1109,7 +1155,7 @@ def compiler(defptr)#0 codeptr=>6 = $FF49 // EOR #$FF codeptr=>8 = $C095+(VX<<8) // STA ESTKH,X codeptr = codeptr + 10 - A_IS_TOSL = TOSL_DIRTY // STA ESTKL,X + A_IS_TOSL = TOS_DIRTY // STA ESTKL,X break is $82 // ADD //puts("ADD") @@ -1129,7 +1175,7 @@ def compiler(defptr)#0 break is $84 // SUB //puts("SUB") - if A_IS_TOSL & TOSL_DIRTY + if A_IS_TOSL & TOS_DIRTY *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin @@ -1166,15 +1212,15 @@ def compiler(defptr)#0 // Call into VM // codeptr, VX = resolveX(codeptr, VX) - if A_IS_TOSL & TOSL_DIRTY + 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=>5 = $00A0 // LDY #$00 - codeptr = codeptr + 7 + codeptr = codeptr + 5 + VY = UNKNOWN A_IS_TOSL = FALSE break is $8C // INCR @@ -1188,7 +1234,7 @@ def compiler(defptr)#0 codeptr=>3 = $0290 // BCC +2 codeptr=>5 = $C0F6+(VX<<8) // INC ESTKH,X codeptr = codeptr + 7 - A_IS_TOSL = TOSL_DIRTY // STA ESTKL,X + A_IS_TOSL = TOS_DIRTY // STA ESTKL,X break is $8E // DECR //puts("DECR") @@ -1201,14 +1247,19 @@ def compiler(defptr)#0 codeptr=>3 = $02B0 // BCS +2 codeptr=>5 = $C0D6+(VX<<8) // DEC ESTKH,X codeptr = codeptr + 7 - A_IS_TOSL = TOSL_DIRTY // STA ESTKL,X + A_IS_TOSL = TOS_DIRTY // STA ESTKL,X break is $90 // NEG //puts("NEG") - if A_IS_TOSL & TOSL_DIRTY + 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 @@ -1301,7 +1352,7 @@ def compiler(defptr)#0 //puts("BRGT "); puti(dest) i++ codeptr, VX = resolveX(codeptr, VX) - if A_IS_TOSL & TOSL_DIRTY + if A_IS_TOSL & TOS_DIRTY *codeptr = $D095//+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin @@ -1330,7 +1381,7 @@ def compiler(defptr)#0 if not A_IS_TOSL *codeptr = $D0B5//+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 - elsif A_IS_TOSL & TOSL_DIRTY + elsif A_IS_TOSL & TOS_DIRTY *codeptr = $D095//+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin @@ -1468,7 +1519,7 @@ def compiler(defptr)#0 // // SUB // - if A_IS_TOSL & TOSL_DIRTY + if A_IS_TOSL & TOS_DIRTY *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin @@ -1508,7 +1559,7 @@ def compiler(defptr)#0 if not A_IS_TOSL *codeptr = $D0B5//+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 - elsif A_IS_TOSL & TOSL_DIRTY + elsif A_IS_TOSL & TOS_DIRTY *codeptr = $D095//+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin @@ -1532,7 +1583,7 @@ def compiler(defptr)#0 if not A_IS_TOSL *codeptr = $D0B5//+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 - elsif A_IS_TOSL & TOSL_DIRTY + elsif A_IS_TOSL & TOS_DIRTY *codeptr = $D095//+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin @@ -1555,20 +1606,17 @@ def compiler(defptr)#0 *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - if j + if VY <> j *codeptr = $A0+(j<<8) // LDY #imm codeptr = codeptr + 2 + VY = j fin codeptr->0 = $18 // CLC codeptr=>1 = $E071 // ADC (IFP),Y codeptr=>3 = $0290 // BCC +2 codeptr=>5 = $C0F6+(VX<<8) // INC ESTKH,X codeptr = codeptr + 7 - if j - *codeptr = $00A0 // LDY #$00 - codeptr = codeptr + 2 - fin - A_IS_TOSL = TOSL_DIRTY // STA ESTKL,X + A_IS_TOSL = TOS_DIRTY // STA ESTKL,X break is $B2 // ADDLW i++ @@ -1578,7 +1626,7 @@ def compiler(defptr)#0 *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - if j + if VY <> j *codeptr = $A0+(j<<8) // LDY #imm codeptr = codeptr + 2 fin @@ -1589,13 +1637,7 @@ def compiler(defptr)#0 codeptr->7 = $C8 // INY codeptr=>8 = $E071 // ADC (IFP),Y codeptr=>10 = $C095+(VX<<8) // STA ESTKH,X - if j - codeptr=>12 = $00A0 // LDY #$00 - codeptr = codeptr + 14 - else - codeptr->12 = $88 // DEY - codeptr = codeptr + 13 - fin + VY = j + 1 A_IS_TOSL = FALSE break is $B4 // ADDAB @@ -1610,7 +1652,7 @@ def compiler(defptr)#0 codeptr=>4 = $0290 // BCC +2 codeptr=>6 = $C0F6+(VX<<8) // INC ESTKH,X codeptr = codeptr + 8 - A_IS_TOSL = TOSL_DIRTY // STA ESTKL,X + A_IS_TOSL = TOS_DIRTY // STA ESTKL,X i++ break is $B6 // ADDAW @@ -1636,11 +1678,11 @@ def compiler(defptr)#0 i++ j = ^(bytecode+i) //puts("IDXLB "); puti(j) - if A_IS_TOSL & TOSL_DIRTY + if A_IS_TOSL & TOS_DIRTY *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin - if j + if VY <> j *codeptr = $A0+(j<<8) // LDY #imm codeptr = codeptr + 2 fin @@ -1658,19 +1700,19 @@ def compiler(defptr)#0 codeptr->9 = $98 // TYA codeptr=>10 = $C075+(VX<<8) // ADC ESTKH,X codeptr=>12 = $C095+(VX<<8) // STA ESTKH,X - codeptr=>14 = $00A0 // LDY #$00 - codeptr = codeptr + 16 + 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 & TOSL_DIRTY + if A_IS_TOSL & TOS_DIRTY *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin - if j + if VY <> j *codeptr = $A0+(j<<8) // LDY #imm codeptr = codeptr + 2 fin @@ -1687,17 +1729,21 @@ def compiler(defptr)#0 codeptr->17 = $98 // TYA codeptr=>18 = $C075+(VX<<8) // ADC ESTKLH,X codeptr=>20 = $C095+(VX<<8) // STA ESTKLH,X - codeptr=>22 = $00A0 // LDY #$00 - codeptr = codeptr + 24 + codeptr = codeptr + 22 + VY = UNKNOWN A_IS_TOSL = FALSE break is $BC // IDXAB i++ //puts("IDXAB $"); puth(*(bytecode+i)) - if A_IS_TOSL & TOSL_DIRTY + 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 @@ -1708,8 +1754,8 @@ def compiler(defptr)#0 codeptr->12 = $98 // TYA codeptr=>13 = $C075+(VX<<8) // ADC ESTKH,X codeptr=>15 = $C095+(VX<<8) // STA ESTKLH,X - codeptr=>17 = $00A0 // LDY #$00 - codeptr = codeptr + 19 + codeptr = codeptr + 17 + VY = UNKNOWN A_IS_TOSL = FALSE i++ break @@ -1718,7 +1764,7 @@ def compiler(defptr)#0 dest = *(bytecode+i) i++ //puts("IDXAW $"); puth(dest) - if A_IS_TOSL & TOSL_DIRTY + if A_IS_TOSL & TOS_DIRTY *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin @@ -1736,8 +1782,8 @@ def compiler(defptr)#0 codeptr->18 = $98 // TYA codeptr=>19 = $C075+(VX<<8) // ADC ESTKH,X codeptr=>21 = $C095+(VX<<8) // STA ESTKLH,X - codeptr=>23 = $00A0 // LDY #$00 - codeptr = codeptr + 25 + codeptr = codeptr + 23 + VY = UNKNOWN A_IS_TOSL = FALSE break is $FE // NOPed out earlier by SELect From f7b1d6c3fbc0f68b7b69787dc8b5a2d927463f47 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Thu, 29 Mar 2018 17:14:27 -0700 Subject: [PATCH 113/147] Tracking Y register WIP --- src/libsrc/apple/jit.pla | 144 +++++++++++++++++---------------------- 1 file changed, 61 insertions(+), 83 deletions(-) diff --git a/src/libsrc/apple/jit.pla b/src/libsrc/apple/jit.pla index c39875c..aa1e6d7 100644 --- a/src/libsrc/apple/jit.pla +++ b/src/libsrc/apple/jit.pla @@ -263,20 +263,20 @@ def compiler(defptr)#0 *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 - VX-- // DEX + *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 - *codeptr = $C094+(VX<<8) // STY ESTKH,X - codeptr = codeptr + 2 A_IS_TOSL = TOS_DIRTY // STA ESTKL,X else when opcode @@ -344,25 +344,15 @@ def compiler(defptr)#0 dest = *(bytecode+i) //puts("LA/CW $"); puth(dest) if A_IS_TOSL & TOS_DIRTY - *codeptr = $D095+(VX<<8) // STA ESTKL,X + *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin - if VY <> 0 - *codeptr = $00A0 // LDY #$00 - codeptr = codeptr + 2 - VY = 0 - fin - VX-- // DEX - codeptr=>0 = $A9+(dest&$FF00) // LDA #2 = $C095+(VX<<8) // STA ESTKH,X - if dest & $00FF == 0 - codeptr->4 = $98 // TYA -> LDA #$00 - codeptr = codeptr + 5 - else - codeptr=>4 = $A9+(dest<<8) // LDA #>VAL - codeptr = codeptr + 6 - fin - A_IS_TOSL = TOS_DIRTY // STA ESTKL,X + 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 @@ -370,29 +360,19 @@ def compiler(defptr)#0 j = ^(bytecode+i) //puts("LLA "); puti(^(bytecode+i)) if A_IS_TOSL & TOS_DIRTY - *codeptr = $D095+(VX<<8) // STA ESTKL,X + *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin - if VY <> 0 - *codeptr = $00A0 // LDY #$00 - codeptr = codeptr + 2 - VY = 0 - fin - VX-- // DEX - if j - *codeptr = $A9+(j<<8) // LDA #imm - codeptr = codeptr + 2 - else - ^codeptr = $98; codeptr++ // TYA -> LDA #$00 - fin - codeptr->0 = $18 // CLC - codeptr=>1 = $E065 // ADC IFPL - codeptr=>3 = $D095+(VX<<8) // STA ESTKL,X - codeptr->5 = $98 // TYA -> LDA #$00 - codeptr=>6 = $E165 // ADC IFPH - codeptr=>8 = $C095+(VX<<8) // STA ESTKH,X - codeptr = codeptr + 10 - A_IS_TOSL = FALSE + VX-- // DEX + codeptr=>0 = $A9+(j<<8) // LDA #imm + codeptr->2 = $18 // CLC + codeptr=>3 = $E065 // ADC IFPL + codeptr=>5 = $D095+(VX<<8) // STA ESTKL,X + codeptr=>7 = $00A9 // LDA #$00 + codeptr=>9 = $E165 // ADC IFPH + codeptr=>11 = $C095+(VX<<8) // STA ESTKH,X + codeptr = codeptr + 13 + A_IS_TOSL = FALSE break is $2A // CB i++ @@ -401,14 +381,14 @@ def compiler(defptr)#0 *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 - VX-- // DEX - codeptr=>0 = $A9+(^(bytecode+i)<<8) // LDA #imm - codeptr=>2 = $C094+(VX<<8) // STY ESTKH,X + codeptr=>0 = $C094+(VX<<8) // STY ESTKH,X + codeptr=>2 = $A9+(^(bytecode+i)<<8) // LDA #imm codeptr = codeptr + 4 A_IS_TOSL = TOS_DIRTY // STA ESTKL,X break @@ -433,31 +413,31 @@ def compiler(defptr)#0 i = i + j fin codeptr = dest - A_IS_TOSL = TOS_DIRTY // STA ESTKL,X + A_IS_TOSL = TOS_DIRTY // STA ESTKL,X break is $32 // DROP2 //puts("DROP2") - VX++ // INX + VX++ // INX is $30 // DROP //puts("DROP") - VX++ // INX + 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 = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 elsif A_IS_TOSL & TOS_DIRTY - *codeptr = $D095+(VX<<8) // STA ESTKL,X + *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin - VX-- // DEX - codeptr=>0 = $C0B4+$0100+(VX<<8) // LDY ESTKH+1,X - codeptr=>2 = $C094+(VX<<8) // STY ESTKH,X + 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 + A_IS_TOSL = TOS_DIRTY // STA ESTKL,X break //is $36 //puts("DIVMOD") @@ -514,7 +494,7 @@ def compiler(defptr)#0 i++ //puts("ORI $"); putb(^(bytecode+i)) if not A_IS_TOSL - *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin *codeptr = $09+(^(bytecode+i)<<8) // ORA #imm @@ -677,7 +657,6 @@ def compiler(defptr)#0 addrxlate=>[dest] = codeptr + 5 - *jitcodeptr fin codeptr = codeptr + 7 - VY = UNKNOWN A_IS_TOSL = FALSE break is $4E // BRTRU @@ -822,7 +801,6 @@ def compiler(defptr)#0 codeptr=>1 = $03D0 // INTERP codeptr=>3 = $5A + (^(bytecode+i)<<8) // LEAVE CODE AND OPERAND codeptr = codeptr + 5 - VY = UNKNOWN A_IS_TOSL = FALSE break is $5C // RET @@ -833,7 +811,6 @@ def compiler(defptr)#0 codeptr = codeptr + 2 fin ^codeptr = $60; codeptr++ // RTS - VY = UNKNOWN A_IS_TOSL = FALSE break is $5E // CFFB @@ -917,19 +894,19 @@ def compiler(defptr)#0 *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 - VX-- // DEX 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 - VY = j A_IS_TOSL = TOS_DIRTY // STA ESTKL,X break is $68 // LAB @@ -939,15 +916,15 @@ def compiler(defptr)#0 *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 - VX-- // DEX - codeptr->0 = $AD // LDA abs - codeptr=>1 = *(bytecode+i) - codeptr=>3 = $C094+(VX<<8) // STY ESTKH,X + codeptr=>0 = $C094+(VX<<8) // STY ESTKH,X + codeptr->2 = $AD // LDA abs + codeptr=>3 = *(bytecode+i) codeptr = codeptr + 5 A_IS_TOSL = TOS_DIRTY // STA ESTKL,X i++ @@ -975,9 +952,9 @@ def compiler(defptr)#0 j = ^(bytecode+i) //puts("DLB "); puti(j) if not A_IS_TOSL - *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X - codeptr = codeptr + 2 - A_IS_TOSL = TOS_CLEAN + *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 @@ -998,6 +975,7 @@ def compiler(defptr)#0 if VY <> j *codeptr = $A0+((j+1)<<8) // LDY #imm codeptr = codeptr + 2 + VY = j else ^codeptr = $C8; codeptr++ // INY fin @@ -1007,7 +985,6 @@ def compiler(defptr)#0 codeptr=>5 = $D0B5+(VX<<8) // LDA ESTKL,X codeptr=>7 = $E091 // STA (IFP),Y codeptr = codeptr + 9 - VY = j A_IS_TOSL = TOS_CLEAN break is $70 // SB @@ -1105,7 +1082,7 @@ def compiler(defptr)#0 codeptr->0 = $8D // STA abs codeptr=>1 = dest codeptr=>3 = $C0B5+(VX<<8) // LDA ESTKH,X - codeptr->5 = $8D // STA abs + codeptr->5 = $8D // STA abs+1 codeptr=>6 = dest+1 codeptr = codeptr + 8 VX++ // INX @@ -1137,7 +1114,7 @@ def compiler(defptr)#0 codeptr->0 = $8D // STA abs codeptr=>1 = dest codeptr=>3 = $C0B4+(VX<<8) // LDY ESTKH,X - codeptr->5 = $8C // STY abs + codeptr->5 = $8C // STY abs+1 codeptr=>6 = dest+1 codeptr = codeptr + 8 VY = UNKNOWN @@ -1169,8 +1146,8 @@ def compiler(defptr)#0 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 - VX++ // INX codeptr = codeptr + 11 + VX++ // INX A_IS_TOSL = FALSE break is $84 // SUB @@ -1186,8 +1163,8 @@ def compiler(defptr)#0 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 - VX++ // INX codeptr = codeptr + 13 + VX++ // INX A_IS_TOSL = FALSE break is $86 // MUL @@ -1294,8 +1271,8 @@ def compiler(defptr)#0 codeptr=>4 = $C0B5+(VX<<8) // LDA ESTKH,X codeptr=>6 = $C035+$0100+(VX<<8) // AND ESTKH+1,X codeptr=>8 = $C095+$0100+(VX<<8) // STA ESTKH+1,X - VX++ // INX codeptr = codeptr + 10 + VX++ // INX A_IS_TOSL = FALSE break is $96 // OR @@ -1309,8 +1286,8 @@ def compiler(defptr)#0 codeptr=>4 = $C0B5+(VX<<8) // LDA ESTKH,X codeptr=>6 = $C015+$0100+(VX<<8) // ORA ESTKH+1,X codeptr=>8 = $C095+$0100+(VX<<8) // STA ESTKH+1,X - VX++ // INX codeptr = codeptr + 10 + VX++ // INX A_IS_TOSL = FALSE break is $98 // XOR @@ -1324,8 +1301,8 @@ def compiler(defptr)#0 codeptr=>4 = $C0B5+(VX<<8) // LDA ESTKH,X codeptr=>6 = $C055+$0100+(VX<<8) // EOR ESTKH+1,X codeptr=>8 = $C095+$0100+(VX<<8) // STA ESTKH+1,X - VX++ // INX codeptr = codeptr + 10 + VX++ // INX A_IS_TOSL = FALSE break is $9E // IDXW @@ -1342,8 +1319,8 @@ def compiler(defptr)#0 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 - VX++ // INX codeptr = codeptr + 14 + VX++ // INX A_IS_TOSL = FALSE break is $A0 // BRGT - FOR/NEXT SPECIFIC TEST & BRANCH @@ -1433,7 +1410,7 @@ def compiler(defptr)#0 if not (codeptr->16 & $80) // Unresolved address list addrxlate=>[dest] = codeptr + 15 - *jitcodeptr fin - codeptr=>17 = $E8E8 // INX; INX + codeptr=>17 = $E8E8 //VX=VX+2 // INX; INX codeptr = codeptr + 19 A_IS_TOSL = FALSE break @@ -1471,7 +1448,7 @@ def compiler(defptr)#0 if not (codeptr->16 & $80) // Unresolved address list addrxlate=>[dest] = codeptr + 15 - *jitcodeptr fin - codeptr=>17 = $E8E8 // INX; INX + codeptr=>17 = $E8E8 //VX=VX+2 // INX; INX codeptr = codeptr + 19 A_IS_TOSL = FALSE break @@ -1507,7 +1484,7 @@ def compiler(defptr)#0 if not (codeptr->14 & $80) // Unresolved address list addrxlate=>[dest] = codeptr + 13 - *jitcodeptr fin - codeptr=>15 = $E8E8 // INX; INX + codeptr=>15 = $E8E8 //VX=VX+2 // INX; INX codeptr = codeptr + 17 A_IS_TOSL = FALSE break @@ -1546,7 +1523,7 @@ def compiler(defptr)#0 if not (codeptr->16 & $80) // Unresolved address list addrxlate=>[dest] = codeptr + 15 - *jitcodeptr fin - codeptr=>17 = $E8E8 // INX; INX + codeptr=>17 = $E8E8 //VX=VX+2 // INX; INX codeptr = codeptr + 19 A_IS_TOSL = FALSE break @@ -1570,8 +1547,8 @@ def compiler(defptr)#0 if not (codeptr->6 & $80) // Unresolved address list addrxlate=>[dest] = codeptr + 5 - *jitcodeptr fin - VX++ // INX codeptr = codeptr + 7 + VX++ // INX A_IS_TOSL = FALSE break is $AE // BROR - LOGICAL OR SPECIFIC BRANCH @@ -1594,8 +1571,8 @@ def compiler(defptr)#0 if not (codeptr->6 & $80) // Unresolved address list addrxlate=>[dest] = codeptr + 5 - *jitcodeptr fin - VX++ // INX codeptr = codeptr + 7 + VX++ // INX A_IS_TOSL = FALSE break is $B0 // ADDLB @@ -1637,6 +1614,7 @@ def compiler(defptr)#0 codeptr->7 = $C8 // INY codeptr=>8 = $E071 // ADC (IFP),Y codeptr=>10 = $C095+(VX<<8) // STA ESTKH,X + codeptr = codeptr + 12 VY = j + 1 A_IS_TOSL = FALSE break @@ -1805,8 +1783,8 @@ def compiler(defptr)#0 // Free working bufffers // //heaprelease(addrxlate) - //puts("Done compiling: $"); puth(defptr=>interpaddr); putln - //getc + puts("Done compiling: $"); puth(defptr=>interpaddr); putln + getc return fin //if opcode == $B6; getc; fin From 3fe85c58353deb5396042f822914a944f9dc2bea Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Thu, 29 Mar 2018 20:00:06 -0700 Subject: [PATCH 114/147] Make sure to always allocate data on heap - it can get overwritten by JIT --- src/libsrc/apple/jit.pla | 4 ++-- src/libsrc/sane.pla | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/libsrc/apple/jit.pla b/src/libsrc/apple/jit.pla index aa1e6d7..bc25216 100644 --- a/src/libsrc/apple/jit.pla +++ b/src/libsrc/apple/jit.pla @@ -1783,8 +1783,8 @@ def compiler(defptr)#0 // Free working bufffers // //heaprelease(addrxlate) - puts("Done compiling: $"); puth(defptr=>interpaddr); putln - getc + //puts("Done compiling: $"); puth(defptr=>interpaddr); putln + //getc return fin //if opcode == $B6; getc; fin diff --git a/src/libsrc/sane.pla b/src/libsrc/sane.pla index ea79ca3..dae40f7 100644 --- a/src/libsrc/sane.pla +++ b/src/libsrc/sane.pla @@ -734,19 +734,21 @@ def loadcode(codefile) ref = fileio:open(strcat(strcpy(@filepath, cmdsys:syspath), codefile)) //puts("ref = "); prbyte(ref); puts(" perr = "); prbyte(perr); putln if ref - pcode = heapmark + pcode = heapalloc(512) fileio:read(ref, pcode, 512) //puts("Read header bytes: "); puti(seglen) //if seglen == 0; puts(" perr = "); prbyte(perr); fin //getc; putln //dumpheader(pcode) //putname(pcode + segname + 8); putc('='); prword(pcode); putln + heaprelease(pcode + (pcode + t_diskinfo)=>codeaddr) // REserve heap to end of buffer seglen = fileio:read(ref, pcode, (pcode + t_diskinfo)=>codeaddr) //puts("Read segment bytes: "); puti(seglen); putln fileio:close(ref) if !fp6502 and (MACHID & $F0 == $B0) // 128K Apple //e or //c seglen = fixup(AUXADDR, pcode + seglen - 2) - pcode auxmove(AUXADDR, pcode, seglen) + heaprelease(pcode) pcode = AUXADDR else heaprelease(fixup(pcode, pcode + seglen - 2)) // Set heap to beginning of relocation list From 43a03d288299b34893a9c4f104c8afdd5f1e3b30 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Thu, 29 Mar 2018 21:07:08 -0700 Subject: [PATCH 115/147] Make sure all buffers on heap are allocated --- src/toolsrc/codegen.pla | 29 +++++++++++++++++------------ src/toolsrc/plasm.pla | 2 +- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/src/toolsrc/codegen.pla b/src/toolsrc/codegen.pla index adceeea..6f4cd5f 100644 --- a/src/toolsrc/codegen.pla +++ b/src/toolsrc/codegen.pla @@ -587,13 +587,15 @@ def save_idlocal#0 savelocals = locals savesize = framesize savelast = lastlocal - memcpy(heapmark, idlocal_tbl, lastlocal - idlocal_tbl) + savetbl = heapalloc(lastlocal - idlocal_tbl) + memcpy(savetbl, idlocal_tbl, lastlocal - idlocal_tbl) end def restore_idlocal#0 locals = savelocals framesize = savesize lastlocal = savelast - memcpy(idlocal_tbl, heapmark, lastlocal - idlocal_tbl) + memcpy(idlocal_tbl, savetbl, lastlocal - idlocal_tbl) + heaprelease(savetbl) end // // Module dependency list @@ -904,10 +906,11 @@ end // Build External Symbol Directory on heap // def buildESD(modfix)#2 - word modofst, esd, idptr, idcnt, len + word modofst, esdtbl, esd, idptr, idcnt, len byte symnum - symnum, esd, idptr, idcnt = 0, heapmark, idglobal_tbl, globals + symnum, esdtbl, idptr, idcnt = 0, heapalloc(heapavail - 256), idglobal_tbl, globals + esd = esdtbl while idcnt if idptr=>idtype & EXPORT_TYPE esd = esd + stodci(@idptr->idname, esd) @@ -926,26 +929,27 @@ def buildESD(modfix)#2 idcnt-- loop ^esd = 0 - len = esd - heapmark + 1 - esd = heapalloc(len) - return esd, len + len = esd - esdtbl + 1 + heaprelease(esdtbl + len) + return esdtbl, len end // // Write ReLocation Directory // def writeRLD(refnum, modofst)#0 - word rld, rldlen, fixups, updtptr, idptr, idcnt, tag + word rldtbl, rld, rldlen, fixups, updtptr, idptr, idcnt, tag byte type - rld = heapmark + rldtbl = heapalloc(heapavail - 256) + rld = rldtbl rldlen = 0 for fixups = fixup_cnt-1 downto 0 tag = fixup_tag=>[fixups] type = tag_type->[tag] if not (type & RELATIVE_FIXUP) if rldlen == 64 // Write out blocks of entries - fileio:write(refnum, heapmark, rld - heapmark) - rld = heapmark + fileio:write(refnum, rldtbl, rld - rldtbl) + rld = rldtbl rldlen = 0 fin if type & EXTERN_FIXUP @@ -967,7 +971,8 @@ def writeRLD(refnum, modofst)#0 fin next ^rld = 0 - fileio:write(refnum, heapmark, rld - heapmark + 1) + fileio:write(refnum, rldtbl, rld - rldtbl + 1) + heaprelease(rldtbl) end // // Write Extended REL file diff --git a/src/toolsrc/plasm.pla b/src/toolsrc/plasm.pla index 9320212..e129806 100644 --- a/src/toolsrc/plasm.pla +++ b/src/toolsrc/plasm.pla @@ -245,7 +245,7 @@ word fixup_tag, fixup_addr word tag_addr, tag_type word idglobal_tbl, idlocal_tbl word pending_seq -word globals, lastglobal, lastglobalsize, lastlocal, savelast +word globals, lastglobal, lastglobalsize, lastlocal, savelast, savetbl word dfd_num, tag_num, fixup_num, globalbufsz, localbufsz, codebufsz word datasize, framesize, savesize byte locals, savelocals From f11a1470f08e1dc4dd3629307a9dcbcae3303ede Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Thu, 29 Mar 2018 21:44:40 -0700 Subject: [PATCH 116/147] Allocate seq buffer on heap and keep ints disabled durin aux memory move --- src/libsrc/apple/jit.pla | 2 +- src/samplesrc/playseq.pla | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/libsrc/apple/jit.pla b/src/libsrc/apple/jit.pla index bc25216..3d91ba2 100644 --- a/src/libsrc/apple/jit.pla +++ b/src/libsrc/apple/jit.pla @@ -75,7 +75,7 @@ def compiler(defptr)#0 *$003C = defptr=>bytecodeaddr *$003E = *$003C + defptr->bytecodesize *$0042 = bytecode - call($C311, 0, 0, 0, $00) // CALL XMOVE with carry clear (AUX->MAIN) + 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 diff --git a/src/samplesrc/playseq.pla b/src/samplesrc/playseq.pla index 087dad9..2671eb8 100644 --- a/src/samplesrc/playseq.pla +++ b/src/samplesrc/playseq.pla @@ -6,8 +6,8 @@ include "inc/sndseq.plh" // // These are utility sequences/routines needed to test the music sequencer code. // -word arg -word ref +word arg, seq, len +byte ref // // Sample background process to show it's working // @@ -19,9 +19,11 @@ arg = argNext(argFirst) if ^arg ref = fileio:open(arg) if ref - fileio:read(ref, heapmark(), heapavail()) + seq = heapalloc(heapavail - 256) + len = fileio:read(ref, seq, heapmark - seq) fileio:close(ref) - musicPlay(heapmark(), TRUE) + heaprelease(seq + len) + musicPlay(seq, TRUE) musicGetKey(8, @backgroundProc) // Yield every 8/16 second musicStop else From cccfdbb9a75e044fed96fff35e4d85d7865415e7 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Fri, 30 Mar 2018 09:52:35 -0700 Subject: [PATCH 117/147] Combine similar opcodes to shring module size to ~8K (keep clean version) --- src/libsrc/apple/cleanjit.pla | 1814 +++++++++++++++++++++++++++++++++ src/libsrc/apple/jit.pla | 827 ++++++--------- 2 files changed, 2120 insertions(+), 521 deletions(-) create mode 100644 src/libsrc/apple/cleanjit.pla diff --git a/src/libsrc/apple/cleanjit.pla b/src/libsrc/apple/cleanjit.pla new file mode 100644 index 0000000..3d91ba2 --- /dev/null +++ b/src/libsrc/apple/cleanjit.pla @@ -0,0 +1,1814 @@ +// +// PLASMA JIT bytecode compiler +// +include "inc/cmdsys.plh" +// +// Module don't free memory +// +const modkeep = $2000 +const modinitkeep = $4000 +// +// Indirect interpreter DEFinition entrypoint +// +struc t_defentry + byte interpjsr + word interpaddr + word bytecodeaddr + byte callcount + byte bytecodesize +end +// +// JIT compiler constants +// +const jitcount = $10 +const jitcomp = $03E2 +const jitcodeptr = $03E4 +const codemax = $BEE0 +// +// AUX bytecode interpreter entrypoint +// +const interpentry = $03DC +// +// TOS caching values +// +const TOS_DIRTY = 1 +const TOS_CLEAN = 2 +// +// Y unknown value +// +const UNKNOWN = -1 +// +// Resolve virtual X with real X +// +def resolveX(codeptr, VX)#2 + while VX > 0 + ^codeptr = $E8; codeptr++ // INX + VX-- + loop + while VX < 0 + ^codeptr = $CA; codeptr++ // DEX + VX++ + loop + return codeptr, 0 +end +// +// JIT compiler entry +// +def compiler(defptr)#0 + word codeptr, isdata, addrxlate, bytecode, i, case, dest, VX, VY + byte opcode, j, A_IS_TOSL + + //puts("JIT compiler invoked for :$"); puth(defptr=>bytecodeaddr); putln + if isult(heapavail, 512 + defptr->bytecodesize) // 256 * sizeof(word) address xlate + // + // Not enough heap available + // + defptr=>interpaddr = interpentry + return + fin + addrxlate = heapmark + memset(addrxlate, 0, 512) // Clear xlate buffer + // + // Copy bytecode def from AUX to heap for compiling + // + bytecode = addrxlate + 512 // def bytecode + *$003C = defptr=>bytecodeaddr + *$003E = *$003C + defptr->bytecodesize + *$0042 = bytecode + call($C311, 0, 0, 0, $04) // CALL XMOVE with carry clear (AUX->MAIN) and ints disabled + //^$C053 // MIX TEXT + //puts("Addr Xlate: $"); puth(addrxlate); putln + //puts("Bytecode: $"); puth(bytecode); putln + // + // Find all branch targets and optimization fences. Tag the opcode with the LSB set + // + // All PLASMA ops are even (LSB clear), so this will flag when to fence optimizations + // During compiling. + // + isdata = addrxlate // Use this buffer + i = 0 + while i <= defptr->bytecodesize + if not ^(isdata+i) + when (^(bytecode+i) & $FE) + // + // 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 + i++ + dest = i + *(bytecode+i) + i++ + //puts("BREQ "); puti(dest) + codeptr, VX = resolveX(codeptr, VX + 2) // INX; INX + if not A_IS_TOSL + *codeptr = $D0B5-$0200//+(VX<<8) // LDA ESTKL-2,X + codeptr = codeptr + 2 + fin + codeptr=>0 = $D0D5-$0100//+(VX<<8) // CMP ESTKL-1,X + codeptr=>2 = $09D0 // BNE +9 + codeptr=>4 = $C0B5-$0200//+(VX<<8) // LDA ESTKH-2,X + codeptr=>6 = $C0D5-$0100//+(VX<<8) // CMP ESTKH-1,X + codeptr=>8 = $03D0 // BNE +3 + codeptr->10 = $4C // JMP abs + codeptr=>11 = addrxlate=>[dest] + if not (codeptr->12 & $80) // Unresolved address list + addrxlate=>[dest] = codeptr + 11 - *jitcodeptr + fin + codeptr = codeptr + 13 + A_IS_TOSL = FALSE + break + is $24 // BRNE + i++ + dest = i + *(bytecode+i) + i++ + //puts("BRNE "); puti(dest) + codeptr, VX = resolveX(codeptr, VX + 2) // INX; INX + if not A_IS_TOSL + *codeptr = $D0B5-$0200//+(VX<<8) // LDA ESTKL-2,X + codeptr = codeptr + 2 + fin + codeptr=>0 = $D0D5-$0100//+(VX<<8) // CMP ESTKL-1,X + codeptr=>2 = $06D0 // BNE +6 + codeptr=>4 = $C0B5-$0200//+(VX<<8) // LDA ESTKH-2,X + codeptr=>6 = $C0D5-$0100//+(VX<<8) // CMP ESTKH-1,X + codeptr=>8 = $03F0 // BEQ +3 + codeptr->10 = $4C // JMP abs + codeptr=>11 = addrxlate=>[dest] + if not (codeptr->12 & $80) // Unresolved address list + addrxlate=>[dest] = codeptr + 11 - *jitcodeptr + fin + codeptr = codeptr + 13 + A_IS_TOSL = FALSE + break + is $26 // LA + is $2C // CW + 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 + codeptr=>0 = $A9+(j<<8) // LDA #imm + codeptr->2 = $18 // CLC + codeptr=>3 = $E065 // ADC IFPL + codeptr=>5 = $D095+(VX<<8) // STA ESTKL,X + codeptr=>7 = $00A9 // LDA #$00 + codeptr=>9 = $E165 // ADC IFPH + codeptr=>11 = $C095+(VX<<8) // STA ESTKH,X + codeptr = codeptr + 13 + A_IS_TOSL = FALSE + break + is $2A // CB + i++ + //puts("CB $"); putb(^(bytecode+i)) + if A_IS_TOSL & TOS_DIRTY + *codeptr = $D095+(VX<<8) // STA ESTKL,X + codeptr = codeptr + 2 + fin + VX-- // DEX + if VY <> 0 + *codeptr = $00A0 // LDY #$00 + codeptr = codeptr + 2 + VY = 0 + fin + codeptr=>0 = $C094+(VX<<8) // STY ESTKH,X + codeptr=>2 = $A9+(^(bytecode+i)<<8) // LDA #imm + codeptr = codeptr + 4 + A_IS_TOSL = TOS_DIRTY // STA ESTKL,X + break + is $2E // CS + i++ + j = ^(bytecode+i) + dest = codeptr + 10 + j + //puts("CS "); //puts(bytecode+i); //puts("-->"); puti(dest) + if isule(dest, codemax) + if A_IS_TOSL & TOS_DIRTY + *codeptr = $D095+(VX<<8) // STA ESTKL,X + codeptr = codeptr + 2 + fin + VX-- // DEX + codeptr=>0 = $A9+((codeptr+9)&$FF00) // LDA #>STRING + codeptr=>2 = $C095+(VX<<8) // STA ESTKH,X + codeptr=>4 = $A9+((codeptr+9)<<8) // LDA #6 = $4C // JMP abs + dest = codeptr + 10 + j + codeptr=>7 = dest + strcpy(codeptr + 9, bytecode + i) + i = i + j + fin + codeptr = dest + A_IS_TOSL = TOS_DIRTY // STA ESTKL,X + break + is $32 // DROP2 + //puts("DROP2") + VX++ // INX + is $30 // DROP + //puts("DROP") + VX++ // INX + A_IS_TOSL = FALSE + break + is $34 // DUP + //puts("DUP") + if not A_IS_TOSL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 + elsif A_IS_TOSL & TOS_DIRTY + *codeptr = $D095+(VX<<8) // STA ESTKL,X + codeptr = codeptr + 2 + fin + codeptr=>0 = $C0B4+(VX<<8) // LDY ESTKH,X + VX-- // DEX + codeptr=>2 = $C094+(VX<<8) // STY ESTKH,X + codeptr = codeptr + 4 + VY = UNKNOWN + A_IS_TOSL = TOS_DIRTY // STA ESTKL,X + break + //is $36 + //puts("DIVMOD") + // + // Should never happen + // + //break + is $38 // ADDI + i++ + //puts("ADDI $"); putb(^(bytecode+i)) + if not A_IS_TOSL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 + fin + codeptr->0 = $18 // CLC + codeptr=>1 = $69+(^(bytecode+i)<<8) // ADC #imm + codeptr=>3 = $0290 // BCC +2 + codeptr=>5 = $C0F6+(VX<<8) // INC ESTKH,X + codeptr = codeptr + 7 + A_IS_TOSL = TOS_DIRTY // STA ESTKL,X + break + is $3A // SUBI + i++ + //puts("SUBI $"); putb(^(bytecode+i)) + if not A_IS_TOSL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 + fin + codeptr->0 = $38 // SEC + codeptr=>1 = $E9+(^(bytecode+i)<<8) // SBC #imm + codeptr=>3 = $02B0 // BCS +2 + codeptr=>5 = $C0D6+(VX<<8) // DEC ESTKH,X + codeptr = codeptr + 7 + A_IS_TOSL = TOS_DIRTY // STA ESTKL,X + break + is $3C // ANDI + i++ + //puts("ANDI $"); putb(^(bytecode+i)) + if VY <> 0 + *codeptr = $00A0 // LDY #$00 + codeptr = codeptr + 2 + VY = 0 + fin + if not A_IS_TOSL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 + fin + codeptr=>0 = $29+(^(bytecode+i)<<8) // AND #imm + codeptr=>2 = $C094+(VX<<8) // STY ESTKH,X + codeptr = codeptr + 4 + A_IS_TOSL = TOS_DIRTY // STA ESTKL,X + break + is $3E // ORI + i++ + //puts("ORI $"); putb(^(bytecode+i)) + if not A_IS_TOSL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 + fin + *codeptr = $09+(^(bytecode+i)<<8) // ORA #imm + codeptr = codeptr + 2 + A_IS_TOSL = TOS_DIRTY // STA ESTKL,X + break + is $40 // ISEQ + //puts("ISEQ") + if VY <> 0 + *codeptr = $00A0 // LDY #$00 + codeptr = codeptr + 2 + fin + if not A_IS_TOSL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 + fin + codeptr=>0 = $D0D5+$0100+(VX<<8) // CMP ESTKL+1,X + codeptr=>2 = $07D0 // BNE +7 + codeptr=>4 = $C0B5+(VX<<8) // LDA ESTKH,X + codeptr=>6 = $C0D5+$0100+(VX<<8) // CMP ESTKH+1 + codeptr=>8 = $01D0 // BNE +1 + codeptr=>10 = $9888 // DEY; TYA + codeptr=>12 = $C094+$0100+(VX<<8) // STY ESTKH+1,X + codeptr = codeptr + 14 + VX++ // INX + VY = UNKNOWN + A_IS_TOSL = TOS_DIRTY // STA ESTKL,X + break + is $42 // ISNE + //puts("ISNE") + if VY <> 0 + *codeptr = $00A0 // LDY #$00 + codeptr = codeptr + 2 + fin + if not A_IS_TOSL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 + fin + codeptr=>0 = $D0D5+$0100+(VX<<8) // CMP ESTKL+1,X + codeptr=>2 = $06D0 // BNE +6 + codeptr=>4 = $C0B5+(VX<<8) // LDA ESTKH,X + codeptr=>6 = $C0D5+$0100+(VX<<8) // CMP ESTKH+1 + codeptr=>8 = $01F0 // BEQ +1 + codeptr=>10 = $9888 // DEY; TYA + codeptr=>12 = $C094+$0100+(VX<<8) // STY ESTKH+1,X + codeptr = codeptr + 14 + VX++ // INX + VY = UNKNOWN + A_IS_TOSL = TOS_DIRTY // STA ESTKL,X + break + is $44 // ISGT + //puts("ISGT") + if VY <> 0 + *codeptr = $00A0 // LDY #$00 + codeptr = codeptr + 2 + fin + if not A_IS_TOSL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 + fin + codeptr=>0 = $D0D5+$0100+(VX<<8) // CMP ESTKL+1,X + codeptr=>2 = $C0B5+(VX<<8) // LDA ESTKH,X + codeptr=>4 = $C0F5+$0100+(VX<<8) // SBC ESTKH+1 + codeptr=>6 = $0250 // BVC +2 + codeptr=>8 = $8049 // EOR #$80 + codeptr=>10 = $0110 // BPL +1 + codeptr=>12 = $9888 // DEY TYA + codeptr=>14 = $C094+$0100+(VX<<8) // STY ESTKH+1,X + codeptr = codeptr + 16 + VX++ // INX + VY = UNKNOWN + A_IS_TOSL = TOS_DIRTY // STA ESTKL,X + break + is $46 + //puts("ISLT") + if A_IS_TOSL & TOS_DIRTY + *codeptr = $D095+(VX<<8) // STA ESTKL,X + codeptr = codeptr + 2 + fin + if VY <> 0 + *codeptr = $00A0 // LDY #$00 + codeptr = codeptr + 2 + fin + codeptr=>0 = $D0B5+$0100+(VX<<8) // LDA ESTKL+1,X + codeptr=>2 = $D0D5+(VX<<8) // CMP ESTKL,X + codeptr=>4 = $C0B5+$0100+(VX<<8) // LDA ESTKH+1,X + codeptr=>6 = $C0F5+(VX<<8) // SBC ESTKH + codeptr=>8 = $0250 // BVC +2 + codeptr=>10 = $8049 // EOR #$80 + codeptr=>12 = $0110 // BPL +1 + codeptr=>14 = $9888 // DEY; TYA + codeptr=>16 = $C094+$0100+(VX<<8) // STY ESTKH+1,X + codeptr = codeptr + 18 + VX++ // INX + VY = UNKNOWN + A_IS_TOSL = TOS_DIRTY // STA ESTKL,X + break + is $48 + //puts("ISGE") + if A_IS_TOSL & TOS_DIRTY + *codeptr = $D095+(VX<<8) // STA ESTKL,X + codeptr = codeptr + 2 + fin + if VY <> 0 + *codeptr = $00A0 // LDY #$00 + codeptr = codeptr + 2 + fin + codeptr=>0 = $D0B5+$0100+(VX<<8) // LDA ESTKL+1,X + codeptr=>2 = $D0D5+(VX<<8) // CMP ESTKL,X + codeptr=>4 = $C0B5+$0100+(VX<<8) // LDA ESTKH+1,X + codeptr=>6 = $C0F5+(VX<<8) // SBC ESTKH + codeptr=>8 = $0250 // BVC +2 + codeptr=>10 = $8049 // EOR #$80 + codeptr=>12 = $0130 // BMI +1 + codeptr=>14 = $9888 // DEY; TYA + codeptr=>16 = $C094+$0100+(VX<<8) // STY ESTKH+1,X + codeptr = codeptr + 18 + VX++ // INX + VY = UNKNOWN + A_IS_TOSL = TOS_DIRTY // STA ESTKL,X + break + is $4A // ISLE + //puts("ISLE") + if VY <> 0 + *codeptr = $00A0 // LDY #$00 + codeptr = codeptr + 2 + fin + if not A_IS_TOSL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 + fin + codeptr=>0 = $D0D5+$0100+(VX<<8) // CMP ESTKL+1,X + codeptr=>2 = $C0B5+(VX<<8) // LDA ESTKH,X + codeptr=>4 = $C0F5+$0100+(VX<<8) // SBC ESTKH+1 + codeptr=>6 = $0250 // BVC +2 + codeptr=>8 = $8049 // EOR #$80 + codeptr=>10 = $0130 // BMI +1 + codeptr=>12 = $9888 // DEY; TYA + codeptr=>14 = $C094+$0100+(VX<<8) // STY ESTKH+1,X + codeptr = codeptr + 16 + VX++ // INX + VY = UNKNOWN + A_IS_TOSL = TOS_DIRTY // STA ESTKL,X + break + is $4C // BRFLS + i++ + dest = i + *(bytecode+i) + i++ + //puts("BRFLS "); puti(dest) + codeptr, VX = resolveX(codeptr, VX + 1) // INX + if not A_IS_TOSL + *codeptr = $D0B5-$0100//+(VX<<8) // LDA ESTKL-1,X + codeptr = codeptr + 2 + fin + codeptr=>0 = $C015-$0100//+(VX<<8) // ORA ESTKH-1,X + codeptr=>2 = $03D0 // BNE +3 + codeptr->4 = $4C // JMP abs + codeptr=>5 = addrxlate=>[dest] + if not (codeptr->6 & $80) // Unresolved address list + addrxlate=>[dest] = codeptr + 5 - *jitcodeptr + fin + codeptr = codeptr + 7 + A_IS_TOSL = FALSE + break + is $4E // BRTRU + i++ + dest = i + *(bytecode+i) + i++ + //puts("BRTRU "); puti(dest) + codeptr, VX = resolveX(codeptr, VX + 1) // INX + if not A_IS_TOSL + *codeptr = $D0B5-$0100//+(VX<<8) // LDA ESTKL-1,X + codeptr = codeptr + 2 + fin + codeptr=>0 = $C015-$0100//+(VX<<8) // ORA ESTKH-1,X + codeptr=>2 = $03F0 // BEQ +3 + codeptr->4 = $4C // JMP abs + codeptr=>5 = addrxlate=>[dest] + if not (codeptr->6 & $80) // Unresolved address list + addrxlate=>[dest] = codeptr + 5 - *jitcodeptr + fin + codeptr = codeptr + 7 + A_IS_TOSL = FALSE + break + is $50 // BRNCH + i++ + dest = i + *(bytecode+i) + i++ + //puts("BRNCH "); puti(dest) + codeptr, VX = resolveX(codeptr, VX) + if A_IS_TOSL & TOS_DIRTY + *codeptr = $D095//+(VX<<8) // STA ESTKL,X + codeptr = codeptr + 2 + fin + codeptr->0 = $4C // JMP abs + codeptr=>1 = addrxlate=>[dest] + if not (codeptr->2 & $80) // Unresolved address list + addrxlate=>[dest] = codeptr + 1 - *jitcodeptr + fin + codeptr = codeptr + 3 + A_IS_TOSL = FALSE + break + is $52 // SEL + i++ + case = i + *(bytecode+i) + i++ + //puts("SEL "); puti(case); putln + j = ^(bytecode+case) + dest = codeptr + 9 + case * 11) + if isule(dest, codemax) + ^(bytecode+case) = $FE // Flag as NOP + case++ + if not A_IS_TOSL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 + fin + codeptr=>0 = $C0B4+(VX<<8) // LDY ESTKH,X + codeptr, VX = resolveX(codeptr + 2, VX + 1) // INX + repeat + dest = *(bytecode+case) + //puts(" $"); puth(dest) + codeptr=>0 = $C9+(dest<<8) // CMP #imm + codeptr=>2 = $07D0 // BNE +7 + codeptr=>4 = $C0+(dest&$FF00) // CPY #imm + codeptr=>6 = $03D0 // BNE +3 + *(bytecode+case) = $FEFE + case = case + 2 + dest = case + *(bytecode+case) + //puts("-->"); puti(dest); putln + codeptr->8 = $4C // JMP abs + codeptr=>9 = addrxlate=>[dest] + if not (codeptr->10 & $80) // Unresolved address list + addrxlate=>[dest] = codeptr + 9 - *jitcodeptr + fin + codeptr = codeptr + 11 + *(bytecode+case) = $FEFE + case = case + 2 + j-- + until not j + codeptr->0 = $4C // JMP abs + codeptr=>1 = addrxlate=>[case] + if not (codeptr->2 & $80) // Unresolved address list + addrxlate=>[case] = codeptr + 1 - *jitcodeptr + fin + codeptr = codeptr + 3 + else + codeptr = dest + fin + VY = UNKNOWN + A_IS_TOSL = FALSE + break + is $54 // CALL + 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 $5E // CFFB + i++ + //puts("CFFB $FF"); putb(^(bytecode+i)) + if A_IS_TOSL & TOS_DIRTY + *codeptr = $D095+(VX<<8) // STA ESTKL,X + codeptr = codeptr + 2 + fin + VX-- // DEX + codeptr=>0 = $FFA9 // LDA #$FF + codeptr=>2 = $C095+(VX<<8) // STA ESTKH,X + codeptr=>4 = $A9+(^(bytecode+i)<<8) // LDA #imm + codeptr = codeptr + 6 + A_IS_TOSL = TOS_DIRTY // STA ESTKL,X + break + is $60 // LB + //puts("LB") + if VY <> 0 + *codeptr = $00A0 // LDY #$00 + codeptr = codeptr + 2 + VY = 0 + fin + if not A_IS_TOSL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 + fin + codeptr=>0 = $C095-$0100+(VX<<8) // STA ESTKH-1,X + codeptr=>2 = $C0A1-$0100+(VX<<8) // LDA (ESTKH-1,X) + codeptr=>4 = $C094+(VX<<8) // STY ESTKH,X + codeptr = codeptr + 6 + A_IS_TOSL = TOS_DIRTY // STA ESTKL,X + break + is $62 // LW + //puts("LW") + if not A_IS_TOSL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 + fin + codeptr=>0 = $C095-$0100+(VX<<8) // STA ESTKH-1,X + codeptr=>2 = $C0A1-$0100+(VX<<8) // LDA (ESTKH-1,X) + codeptr=>4 = $D095+(VX<<8) // STA ESTKL,X + codeptr=>6 = $C0F6-$0100+(VX<<8) // INC ESTKH-1,X + codeptr=>8 = $02D0 // BNE +2 + codeptr=>10 = $C0F6+(VX<<8) // INC ESTKH,X + codeptr=>12 = $C0A1-$0100+(VX<<8) // LDA (ESTKH-1,X) + codeptr=>14 = $C095+(VX<<8) // STA ESTKH,X + codeptr = codeptr + 16 + A_IS_TOSL = FALSE + break + is $64 // LLB + i++ + j = ^(bytecode+i) + //puts("LLB "); puti(j) + if A_IS_TOSL & TOS_DIRTY + *codeptr = $D095+(VX<<8) // STA ESTKL,X + codeptr = codeptr + 2 + fin + VX-- // DEX + if VY <> j + *codeptr = $A0+(j<<8) // LDY #imm + codeptr = codeptr + 2 + VY = j + fin + *codeptr = $E0B1 // LDA (IFP),Y + codeptr = codeptr + 2 + if VY + *codeptr = $00A0 // LDY #$00 + codeptr = codeptr + 2 + VY = 0 + fin + *codeptr = $C094+(VX<<8) // STY ESTKH,X + codeptr = codeptr + 2 + A_IS_TOSL = TOS_DIRTY // STA ESTKL,X + break + is $66 // LLW + i++ + j = ^(bytecode+i) + //puts("LLW "); puti(j) + if A_IS_TOSL & TOS_DIRTY + *codeptr = $D095+(VX<<8) // STA ESTKL,X + codeptr = codeptr + 2 + fin + VX-- // DEX + if VY <> j + *codeptr = $A0+((j+1)<<8) // LDY #imm + codeptr = codeptr + 2 + VY = j + else + ^codeptr = $C8; codeptr++ // INY + fin + codeptr=>0 = $E0B1 // LDA (IFP),Y + codeptr=>2 = $C095+(VX<<8) // STA ESTKH,X + codeptr->4 = $88 // DEY + codeptr=>5 = $E0B1 // LDA (IFP),Y + codeptr = codeptr + 7 + A_IS_TOSL = TOS_DIRTY // STA ESTKL,X + break + is $68 // LAB + i++ + //puts("LAB $"); puth(*(bytecode+i)) + if A_IS_TOSL & TOS_DIRTY + *codeptr = $D095+(VX<<8) // STA ESTKL,X + codeptr = codeptr + 2 + fin + VX-- // DEX + if VY <> 0 + *codeptr = $00A0 // LDY #$00 + codeptr = codeptr + 2 + VY = 0 + fin + codeptr=>0 = $C094+(VX<<8) // STY ESTKH,X + codeptr->2 = $AD // LDA abs + codeptr=>3 = *(bytecode+i) + codeptr = codeptr + 5 + A_IS_TOSL = TOS_DIRTY // STA ESTKL,X + i++ + break + is $6A // LAW + i++ + dest = *(bytecode+i) + //puts("LAW $"); puth(dest) + if A_IS_TOSL & TOS_DIRTY + *codeptr = $D095+(VX<<8) // STA ESTKL,X + codeptr = codeptr + 2 + fin + VX-- // DEX + codeptr->0 = $AD // LDA abs + codeptr=>1 = dest+1 + codeptr=>3 = $C095+(VX<<8) // STA ESTKH,X + codeptr->5 = $AD // LDA abs + codeptr=>6 = dest + codeptr = codeptr + 8 + A_IS_TOSL = TOS_DIRTY // STA ESTKL,X + i++ + break + is $6C // DLB + i++ + j = ^(bytecode+i) + //puts("DLB "); puti(j) + if not A_IS_TOSL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 + A_IS_TOSL = TOS_CLEAN + fin + if VY <> j + *codeptr = $A0+(j<<8) // LDY #imm + codeptr = codeptr + 2 + VY = j + fin + *codeptr = $E091 // STA (IFP),Y + codeptr = codeptr + 2 + break + is $6E // DLW + i++ + j = ^(bytecode+i) + //puts("DLW "); puti(j) + if A_IS_TOSL & TOS_DIRTY + *codeptr = $D095+(VX<<8) // STA ESTKL,X + codeptr = codeptr + 2 + fin + if VY <> j + *codeptr = $A0+((j+1)<<8) // LDY #imm + codeptr = codeptr + 2 + VY = j + else + ^codeptr = $C8; codeptr++ // INY + fin + codeptr=>0 = $C0B5+(VX<<8) // LDA ESTKH,X + codeptr=>2 = $E091 // STA (IFP),Y + codeptr->4 = $88 // DEY + codeptr=>5 = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr=>7 = $E091 // STA (IFP),Y + codeptr = codeptr + 9 + A_IS_TOSL = TOS_CLEAN + break + is $70 // SB + //puts("SB") + if not A_IS_TOSL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 + fin + codeptr=>0 = $C095-$0100+(VX<<8) // STA ESTKH-1,X + codeptr=>2 = $D0B5+$0100+(VX<<8) // LDA ESTKL+1,X + codeptr=>4 = $C081-$0100+(VX<<8) // STA (ESTKH-1,X) + codeptr = codeptr + 6 + VX = VX + 2 // INX; INX + A_IS_TOSL = FALSE + break + is $72 // SW + //puts("SW") + if not A_IS_TOSL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 + fin + codeptr=>0 = $C095-$0100+(VX<<8) // STA ESTKH-1,X + codeptr=>2 = $D0B5+$0100+(VX<<8) // LDA ESTKL+1,X + codeptr=>4 = $C081-$0100+(VX<<8) // STA (ESTKH-1,X) + codeptr=>6 = $C0B5+$0100+(VX<<8) // LDA ESTKH+1,X + codeptr=>8 = $C0F6-$0100+(VX<<8) // INC ESTKH-1,X + codeptr=>10 = $02D0 // BNE +2 + codeptr=>12 = $C0F6+(VX<<8) // INC ESTKH,X + codeptr=>14 = $C081-$0100+(VX<<8) // STA (ESTKH-1,X) + codeptr = codeptr + 16 + VX = VX + 2 // INX; INX + A_IS_TOSL = FALSE + break + is $74 // SLB + i++ + j = ^(bytecode+i) + //puts("SLB "); puti(j) + if not A_IS_TOSL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 + fin + if VY <> j + *codeptr = $A0+(j<<8) // LDY #imm + codeptr = codeptr + 2 + VY = j + fin + *codeptr = $E091 // STA (IFP),Y + codeptr = codeptr + 2 + VX++ // INX + A_IS_TOSL = FALSE + break + is $76 // SLW + i++ + j = ^(bytecode+i) + //puts("SLW "); puti(j) + if not A_IS_TOSL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 + fin + if VY <> j + *codeptr = $A0+(j<<8) // LDY #imm + codeptr = codeptr + 2 + fin + codeptr=>0 = $E091 // STA (IFP),Y + codeptr->2 = $C8 // INY + codeptr=>3 = $C0B5+(VX<<8) // LDA ESTKH,X + codeptr=>5 = $E091 // STA (IFP),Y + codeptr = codeptr + 7 + VX++ // INX + VY = j + 1 + A_IS_TOSL = FALSE + break + is $78 // SAB + i++ + //puts("SAB $"); puth(*(bytecode+i)) + if not A_IS_TOSL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 + fin + codeptr->0 = $8D // STA abs + codeptr=>1 = *(bytecode+i) + codeptr = codeptr + 3 + VX++ // INX + A_IS_TOSL = FALSE + 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 $7C // DAB + i++ + //puts("DAB $"); puth(*(bytecode+i)) + if not A_IS_TOSL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 + A_IS_TOSL = TOS_CLEAN + fin + codeptr->0 = $8D // STA abs + codeptr=>1 = *(bytecode+i) + codeptr = codeptr + 3 + 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 $8C // INCR + //puts("INCR") + if not A_IS_TOSL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 + fin + codeptr->0 = $18 // CLC + codeptr=>1 = $0169 // ADC #$01 + codeptr=>3 = $0290 // BCC +2 + codeptr=>5 = $C0F6+(VX<<8) // INC ESTKH,X + codeptr = codeptr + 7 + A_IS_TOSL = TOS_DIRTY // STA ESTKL,X + break + is $8E // DECR + //puts("DECR") + if not A_IS_TOSL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 + fin + codeptr->0 = $38 // SEC + codeptr=>1 = $01E9 // SBC #$01 + codeptr=>3 = $02B0 // BCS +2 + codeptr=>5 = $C0D6+(VX<<8) // DEC ESTKH,X + codeptr = codeptr + 7 + A_IS_TOSL = TOS_DIRTY // STA ESTKL,X + break + is $90 // NEG + //puts("NEG") + if A_IS_TOSL & TOS_DIRTY + *codeptr = $D095+(VX<<8) // STA ESTKL,X + codeptr = codeptr + 2 + fin + if VY <> 0 + *codeptr = $00A0 // LDY #$00 + codeptr = codeptr + 2 + VY = 0 + fin + codeptr=>0 = $3898 // TYA -> LDA #$00; SEC + codeptr=>2 = $D0F5+(VX<<8) // SBC ESTKL,X + codeptr=>4 = $D095+(VX<<8) // STA ESTKL,X + codeptr->6 = $98 // TYA -> LDA #00 + codeptr=>7 = $C0F5+(VX<<8) // SBC ESTKH,X + codeptr=>9 = $C095+(VX<<8) // STA ESTKH,X + codeptr = codeptr + 11 + A_IS_TOSL = FALSE + break + is $92 // COMP + //puts("COMP") + if not A_IS_TOSL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 + fin + codeptr=>0 = $FF49 // EOR #$FF + codeptr=>2 = $D095+(VX<<8) // STA ESTKL,X + codeptr=>4 = $C0B5+(VX<<8) // LDA ESTKH,X + codeptr=>6 = $FF49 // EOR #$FF + codeptr=>8 = $C095+(VX<<8) // STA ESTKH,X + codeptr = codeptr + 10 + A_IS_TOSL = FALSE + break + is $94 // AND + //puts("AND") + if not A_IS_TOSL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 + fin + codeptr=>0 = $D035+$0100+(VX<<8) // AND ESTKL+1,X + codeptr=>2 = $D095+$0100+(VX<<8) // STA ESTKL+1,X + codeptr=>4 = $C0B5+(VX<<8) // LDA ESTKH,X + codeptr=>6 = $C035+$0100+(VX<<8) // AND ESTKH+1,X + codeptr=>8 = $C095+$0100+(VX<<8) // STA ESTKH+1,X + codeptr = codeptr + 10 + VX++ // INX + A_IS_TOSL = FALSE + break + is $96 // OR + //puts("OR") + if not A_IS_TOSL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 + fin + codeptr=>0 = $D015+$0100+(VX<<8) // ORA ESTKL+1,X + codeptr=>2 = $D095+$0100+(VX<<8) // STA ESTKL+1,X + codeptr=>4 = $C0B5+(VX<<8) // LDA ESTKH,X + codeptr=>6 = $C015+$0100+(VX<<8) // ORA ESTKH+1,X + codeptr=>8 = $C095+$0100+(VX<<8) // STA ESTKH+1,X + codeptr = codeptr + 10 + VX++ // INX + A_IS_TOSL = FALSE + break + is $98 // XOR + //puts("XOR") + if not A_IS_TOSL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 + fin + codeptr=>0 = $D055+$0100+(VX<<8) // EOR ESTKL+1,X + codeptr=>2 = $D095+$0100+(VX<<8) // STA ESTKL+1,X + codeptr=>4 = $C0B5+(VX<<8) // LDA ESTKH,X + codeptr=>6 = $C055+$0100+(VX<<8) // EOR ESTKH+1,X + codeptr=>8 = $C095+$0100+(VX<<8) // STA ESTKH+1,X + codeptr = codeptr + 10 + VX++ // INX + A_IS_TOSL = FALSE + break + is $9E // IDXW + //puts("IDXW") + if not A_IS_TOSL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 + fin + codeptr->0 = $0A // ASL + codeptr=>1 = $C036+(VX<<8) // ROL ESTKH,X + codeptr->3 = $18 // CLC + codeptr=>4 = $D075+$0100+(VX<<8) // ADC ESTKL+1,X + codeptr=>6 = $D095+$0100+(VX<<8) // STA ESTKL+1,X + codeptr=>8 = $C0B5+(VX<<8) // LDA ESTKH,X + codeptr=>10 = $C075+$0100+(VX<<8) // ADC ESTKH+1,X + codeptr=>12 = $C095+$0100+(VX<<8) // STA ESTKH+1,X + codeptr = codeptr + 14 + VX++ // INX + A_IS_TOSL = FALSE + break + is $A0 // BRGT - FOR/NEXT SPECIFIC TEST & BRANCH + i++ + dest = i + *(bytecode+i) + //puts("BRGT "); puti(dest) + i++ + codeptr, VX = resolveX(codeptr, VX) + if A_IS_TOSL & TOS_DIRTY + *codeptr = $D095//+(VX<<8) // STA ESTKL,X + codeptr = codeptr + 2 + fin + codeptr=>0 = $D0B5+$0100//+(VX<<8) // LDA ESTKL+1,X + codeptr=>2 = $D0D5//+(VX<<8) // CMP ESTKL,X + codeptr=>4 = $C0B5+$0100//+(VX<<8) // LDA ESTKH+1,X + codeptr=>6 = $C0F5//+(VX<<8) // SBC ESTKH + codeptr=>8 = $0250 // BVC +2 + codeptr=>10 = $8049 // EOR #$80 + codeptr=>12 = $0510 // BPL +5 + codeptr=>14 = $E8E8 // INX; INX + codeptr->16 = $4C // JMP abs + codeptr=>17 = addrxlate=>[dest] + if not (codeptr->18 & $80) // Unresolved address list + addrxlate=>[dest] = codeptr + 17 - *jitcodeptr + fin + codeptr = codeptr + 19 + A_IS_TOSL = FALSE + break + is $A2 // BRLT - FOR/NEXT SPECIFIC TEST & BRANCH + i++ + dest = i + *(bytecode+i) + //puts("BRLT "); puti(dest) + i++ + codeptr, VX = resolveX(codeptr, VX) + if not A_IS_TOSL + *codeptr = $D0B5//+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 + elsif A_IS_TOSL & TOS_DIRTY + *codeptr = $D095//+(VX<<8) // STA ESTKL,X + codeptr = codeptr + 2 + fin + codeptr=>0 = $D0D5+$0100//+(VX<<8) // CMP ESTKL+1,X + codeptr=>2 = $C0B5//+(VX<<8) // LDA ESTKH,X + codeptr=>4 = $C0F5+$0100//+(VX<<8) // SBC ESTKH+1 + codeptr=>6 = $0250 // BVC +2 + codeptr=>8 = $8049 // EOR #$80 + codeptr=>10 = $0510 // BPL +5 + codeptr=>12 = $E8E8 // INX; INX + codeptr->14 = $4C // JMP abs + codeptr=>15 = addrxlate=>[dest] + if not (codeptr->16 & $80) // Unresolved address list + addrxlate=>[dest] = codeptr + 15 - *jitcodeptr + fin + codeptr = codeptr + 17 + A_IS_TOSL = FALSE + break + is $A4 // INCBRLE - FOR/NEXT SPECIFIC INC & TEST & BRANCH + i++ + dest = i + *(bytecode+i) + //puts("INCBRLE "); puti(dest) + i++ + // + // INCR + // + if not A_IS_TOSL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 + fin + codeptr->0 = $18 // CLC + codeptr=>1 = $0169 // ADC #$01 + codeptr=>3 = $D095+(VX<<8) // STA ESTKL,X + codeptr=>5 = $0290 // BCC +2 + codeptr=>7 = $C0F6+(VX<<8) // INC ESTKH,X + codeptr, VX = resolveX(codeptr + 9, VX) + // + // BRLE + // + codeptr=>0 = $D0B5+$0100//+(VX<<8) // LDA ESTKL+1,X + codeptr=>2 = $D0D5//+(VX<<8) // CMP ESTKL,X + codeptr=>4 = $C0B5+$0100//+(VX<<8) // LDA ESTKH+1,X + codeptr=>6 = $C0F5//+(VX<<8) // SBC ESTKH + codeptr=>8 = $0250 // BVC +2 + codeptr=>10 = $8049 // EOR #$80 + codeptr=>12 = $0330 // BMI +3 + codeptr->14 = $4C // JMP abs + codeptr=>15 = addrxlate=>[dest] + if not (codeptr->16 & $80) // Unresolved address list + addrxlate=>[dest] = codeptr + 15 - *jitcodeptr + fin + codeptr=>17 = $E8E8 //VX=VX+2 // INX; INX + codeptr = codeptr + 19 + A_IS_TOSL = FALSE + break + is $A6 // ADDBRLE - FOR/NEXT SPECIFIC ADD & TEST & BRANCH + i++ + dest = i + *(bytecode+i) + //puts("ADDBRLE "); puti(dest) + i++ + // + // ADD + // + if not A_IS_TOSL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 + fin + codeptr->0 = $18 // CLC + codeptr=>1 = $D075+$0100+(VX<<8) // ADC ESTKL+1,X + codeptr=>3 = $D095+$0100+(VX<<8) // STA ESTKL+1,X + codeptr=>5 = $C0B5+(VX<<8) // LDA ESTKH,X + codeptr=>7 = $C075+$0100+(VX<<8) // ADC ESTKH+1,X + codeptr=>9 = $C095+$0100+(VX<<8) // STA ESTKH+1,X + codeptr, VX = resolveX(codeptr + 11, VX + 1) // INX + // + // BRLE + // + codeptr=>0 = $D0B5+$0100//+(VX<<8) // LDA ESTKL+1,X + codeptr=>2 = $D0D5+(VX<<8) // CMP ESTKL,X + codeptr=>4 = $C0B5+$0100//+(VX<<8) // LDA ESTKH+1,X + codeptr=>6 = $C0F5+(VX<<8) // SBC ESTKH + codeptr=>8 = $0250 // BVC +2 + codeptr=>10 = $8049 // EOR #$80 + codeptr=>12 = $0330 // BMI +3 + codeptr->14 = $4C // JMP abs + codeptr=>15 = addrxlate=>[dest] + if not (codeptr->16 & $80) // Unresolved address list + addrxlate=>[dest] = codeptr + 15 - *jitcodeptr + fin + codeptr=>17 = $E8E8 //VX=VX+2 // INX; INX + codeptr = codeptr + 19 + A_IS_TOSL = FALSE + break + is $A8 // DECBRGR - FOR/NEXT SPECIFIC DEC & TEST & BRANCH + i++ + dest = i + *(bytecode+i) + //puts("DECBRGE "); puti(dest) + i++ + // + // DECR + // + if not A_IS_TOSL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 + fin + codeptr->0 = $38 // SEC + codeptr=>1 = $01E9 // SBC #$01 + codeptr=>3 = $D095+(VX<<8) // STA ESTKL,X + codeptr=>5 = $02B0 // BCS +2 + codeptr=>7 = $C0D6+(VX<<8) // DEC ESTKH,X + codeptr, VX = resolveX(codeptr + 9, VX) + // + // BRGE + // + codeptr=>0 = $D0D5+$0100//+(VX<<8) // CMP ESTKL+1,X + codeptr=>2 = $C0B5//+(VX<<8) // LDA ESTKH,X + codeptr=>4 = $C0F5+$0100//+(VX<<8) // SBC ESTKH+1,X + codeptr=>6 = $0250 // BVC +2 + codeptr=>8 = $8049 // EOR #$80 + codeptr=>10 = $0330 // BMI +3 + codeptr->12 = $4C // JMP abs + codeptr=>13 = addrxlate=>[dest] + if not (codeptr->14 & $80) // Unresolved address list + addrxlate=>[dest] = codeptr + 13 - *jitcodeptr + fin + codeptr=>15 = $E8E8 //VX=VX+2 // INX; INX + codeptr = codeptr + 17 + A_IS_TOSL = FALSE + break + is $AA // SUBBRGE - FOR/NEXT SPECIFIC SUB & TEST & BRANCH + i++ + dest = i + *(bytecode+i) + //puts("SUBBRGE "); puti(dest) + i++ + // + // SUB + // + if A_IS_TOSL & TOS_DIRTY + *codeptr = $D095+(VX<<8) // STA ESTKL,X + codeptr = codeptr + 2 + fin + codeptr=>0 = $D0B5+$0100+(VX<<8) // LDA ESTKL+1,X + codeptr->2 = $38 // SEC + codeptr=>3 = $D0F5+(VX<<8) // SBC ESTKL,X + codeptr=>5 = $D095+$0100+(VX<<8) // STA ESTKL+1,X + codeptr=>7 = $C0B5+$0100+(VX<<8) // LDA ESTKH+1,X + codeptr=>9 = $C0F5+(VX<<8) // SBC ESTKH,X + codeptr=>11 = $C095+$0100+(VX<<8) // STA ESTKH+1,X + codeptr, VX = resolveX(codeptr + 13, VX + 1) // INX + // + // BRGE + // + codeptr=>0 = $D0B5//+(VX<<8) // LDA ESTKL,X + codeptr=>2 = $D0D5+$0100//+(VX<<8) // CMP ESTKL+1,X + codeptr=>4 = $C0B5//+(VX<<8) // LDA ESTKH,X + codeptr=>6 = $C0F5+$0100//+(VX<<8) // SBC ESTKH+1,X + codeptr=>8 = $0250 // BVC +2 + codeptr=>10 = $8049 // EOR #$80 + codeptr=>12 = $0330 // BMI +3 + codeptr->14 = $4C // JMP abs + codeptr=>15 = addrxlate=>[dest] + if not (codeptr->16 & $80) // Unresolved address list + addrxlate=>[dest] = codeptr + 15 - *jitcodeptr + fin + codeptr=>17 = $E8E8 //VX=VX+2 // INX; INX + codeptr = codeptr + 19 + A_IS_TOSL = FALSE + break + is $AC // BRAND - LOGICAL AND SPECIFIC BRANCH + i++ + dest = i + *(bytecode+i) + i++ + //puts("BRAND "); puti(dest) + codeptr, VX = resolveX(codeptr, VX) + if not A_IS_TOSL + *codeptr = $D0B5//+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 + elsif A_IS_TOSL & TOS_DIRTY + *codeptr = $D095//+(VX<<8) // STA ESTKL,X + codeptr = codeptr + 2 + fin + codeptr=>0 = $C015//+(VX<<8) // ORA ESTKH,X + codeptr=>2 = $03D0 // BNE +3 + codeptr->4 = $4C // JMP abs + codeptr=>5 = addrxlate=>[dest] + if not (codeptr->6 & $80) // Unresolved address list + addrxlate=>[dest] = codeptr + 5 - *jitcodeptr + fin + codeptr = codeptr + 7 + VX++ // INX + A_IS_TOSL = FALSE + break + is $AE // BROR - LOGICAL OR SPECIFIC BRANCH + i++ + dest = i + *(bytecode+i) + i++ + //puts("BROR "); puti(dest) + codeptr, VX = resolveX(codeptr, VX) + if not A_IS_TOSL + *codeptr = $D0B5//+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 + elsif A_IS_TOSL & TOS_DIRTY + *codeptr = $D095//+(VX<<8) // STA ESTKL,X + codeptr = codeptr + 2 + fin + codeptr=>0 = $C015//+(VX<<8) // ORA ESTKH,X + codeptr=>2 = $03F0 // BEQ +3 + codeptr->4 = $4C // JMP abs + codeptr=>5 = addrxlate=>[dest] + if not (codeptr->6 & $80) // Unresolved address list + addrxlate=>[dest] = codeptr + 5 - *jitcodeptr + fin + codeptr = codeptr + 7 + VX++ // INX + A_IS_TOSL = FALSE + break + is $B0 // ADDLB + i++ + j = ^(bytecode+i) + //puts("ADDLB "); puti(j) + if not A_IS_TOSL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 + fin + if VY <> j + *codeptr = $A0+(j<<8) // LDY #imm + codeptr = codeptr + 2 + VY = j + fin + codeptr->0 = $18 // CLC + codeptr=>1 = $E071 // ADC (IFP),Y + codeptr=>3 = $0290 // BCC +2 + codeptr=>5 = $C0F6+(VX<<8) // INC ESTKH,X + codeptr = codeptr + 7 + A_IS_TOSL = TOS_DIRTY // STA ESTKL,X + break + is $B2 // ADDLW + i++ + j = ^(bytecode+i) + //puts("ADDLW "); puti(j) + if not A_IS_TOSL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 + fin + if VY <> j + *codeptr = $A0+(j<<8) // LDY #imm + codeptr = codeptr + 2 + fin + codeptr->0 = $18 // CLC + codeptr=>1 = $E071 // ADC (IFP),Y + codeptr=>3 = $D095+(VX<<8) // STA ESTKL,X + codeptr=>5 = $C0B5+(VX<<8) // LDA ESTKH,X + codeptr->7 = $C8 // INY + codeptr=>8 = $E071 // ADC (IFP),Y + codeptr=>10 = $C095+(VX<<8) // STA ESTKH,X + codeptr = codeptr + 12 + VY = j + 1 + A_IS_TOSL = FALSE + break + is $B4 // ADDAB + i++ + //puts("ADDAB $"); puth(*(bytecode+i)) + if not A_IS_TOSL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 + fin + codeptr=>0 = $6D18 // CLC; ADC abs + codeptr=>2 = *(bytecode+i) + codeptr=>4 = $0290 // BCC +2 + codeptr=>6 = $C0F6+(VX<<8) // INC ESTKH,X + codeptr = codeptr + 8 + A_IS_TOSL = TOS_DIRTY // STA ESTKL,X + i++ + break + is $B6 // ADDAW + i++ + dest = *(bytecode+i) + i++ + //puts("ADDAW $"); puth(dest) + if not A_IS_TOSL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 + fin + codeptr=>0 = $6D18 // CLC; ADC abs + codeptr=>2 = dest + codeptr=>4 = $D095+(VX<<8) // STA ESTKL,X + codeptr=>6 = $C0B5+(VX<<8) // LDA ESTKH,X + codeptr->8 = $6D // ADC abs + codeptr=>9 = dest+1 + codeptr=>11 = $C095+(VX<<8) // STA ESTKH,X + codeptr = codeptr + 13 + A_IS_TOSL = FALSE + break + is $B8 // IDXLB + i++ + j = ^(bytecode+i) + //puts("IDXLB "); puti(j) + if A_IS_TOSL & TOS_DIRTY + *codeptr = $D095+(VX<<8) // STA ESTKL,X + codeptr = codeptr + 2 + fin + if VY <> j + *codeptr = $A0+(j<<8) // LDY #imm + codeptr = codeptr + 2 + fin + *codeptr = $E0B1 // LDA (IFP),Y + codeptr = codeptr + 2 + if j + *codeptr = $00A0 // LDY #$00 + codeptr = codeptr + 2 + fin + codeptr->0 = $0A // ASL + codeptr=>1 = $0290 // BCC +2 + codeptr=>3 = $18C8 // INY; CLC + codeptr=>5 = $D075+(VX<<8) // ADC ESTKL,X + codeptr=>7 = $D095+(VX<<8) // STA ESTKL,X + codeptr->9 = $98 // TYA + codeptr=>10 = $C075+(VX<<8) // ADC ESTKH,X + codeptr=>12 = $C095+(VX<<8) // STA ESTKH,X + codeptr = codeptr + 14 + VY = UNKNOWN + A_IS_TOSL = FALSE + break + is $BA // IDXLW + i++ + j = ^(bytecode+i) + //puts("IDXLW "); puti(j) + if A_IS_TOSL & TOS_DIRTY + *codeptr = $D095+(VX<<8) // STA ESTKL,X + codeptr = codeptr + 2 + fin + if VY <> j + *codeptr = $A0+(j<<8) // LDY #imm + codeptr = codeptr + 2 + fin + codeptr=>0 = $E0B1 // LDA (IFP),Y + codeptr->2 = $0A // ASL + codeptr=>3 = $E785 // STA $E7:TMPL + codeptr->5 = $C8 // INY + codeptr=>6 = $E0B1 // LDA (IFP),Y + codeptr=>8 = $A82A // ROL; TAY + codeptr=>10 = $E7A5 // LDA $E7:TMPL + codeptr->12 = $18 // CLC + codeptr=>13 = $D075+(VX<<8) // ADC ESTKL,X + codeptr=>15 = $D095+(VX<<8) // STA ESTKL,X + codeptr->17 = $98 // TYA + codeptr=>18 = $C075+(VX<<8) // ADC ESTKLH,X + codeptr=>20 = $C095+(VX<<8) // STA ESTKLH,X + codeptr = codeptr + 22 + VY = UNKNOWN + A_IS_TOSL = FALSE + break + is $BC // IDXAB + 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 +// +// Install JIT compiler +// +if *jitcomp + puts("JIT compiler already installed!\n") + return 0 +fin +puts("Installing JIT compiler\n") +*jitcomp = @compiler +return modkeep +done diff --git a/src/libsrc/apple/jit.pla b/src/libsrc/apple/jit.pla index 3d91ba2..55a4027 100644 --- a/src/libsrc/apple/jit.pla +++ b/src/libsrc/apple/jit.pla @@ -293,43 +293,27 @@ def compiler(defptr)#0 A_IS_TOSL = TOS_DIRTY // STA ESTKL,X break is $22 // BREQ - i++ - dest = i + *(bytecode+i) - i++ - //puts("BREQ "); puti(dest) - codeptr, VX = resolveX(codeptr, VX + 2) // INX; INX - if not A_IS_TOSL - *codeptr = $D0B5-$0200//+(VX<<8) // LDA ESTKL-2,X - codeptr = codeptr + 2 - fin - codeptr=>0 = $D0D5-$0100//+(VX<<8) // CMP ESTKL-1,X - codeptr=>2 = $09D0 // BNE +9 - codeptr=>4 = $C0B5-$0200//+(VX<<8) // LDA ESTKH-2,X - codeptr=>6 = $C0D5-$0100//+(VX<<8) // CMP ESTKH-1,X - codeptr=>8 = $03D0 // BNE +3 - codeptr->10 = $4C // JMP abs - codeptr=>11 = addrxlate=>[dest] - if not (codeptr->12 & $80) // Unresolved address list - addrxlate=>[dest] = codeptr + 11 - *jitcodeptr - fin - codeptr = codeptr + 13 - A_IS_TOSL = FALSE - break is $24 // BRNE i++ dest = i + *(bytecode+i) i++ - //puts("BRNE "); puti(dest) codeptr, VX = resolveX(codeptr, VX + 2) // INX; INX if not A_IS_TOSL *codeptr = $D0B5-$0200//+(VX<<8) // LDA ESTKL-2,X codeptr = codeptr + 2 fin + 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=>2 = $06D0 // BNE +6 codeptr=>4 = $C0B5-$0200//+(VX<<8) // LDA ESTKH-2,X codeptr=>6 = $C0D5-$0100//+(VX<<8) // CMP ESTKH-1,X - codeptr=>8 = $03F0 // BEQ +3 codeptr->10 = $4C // JMP abs codeptr=>11 = addrxlate=>[dest] if not (codeptr->12 & $80) // Unresolved address list @@ -375,22 +359,31 @@ def compiler(defptr)#0 A_IS_TOSL = FALSE break is $2A // CB + is $5E // CFFB i++ - //puts("CB $"); putb(^(bytecode+i)) if A_IS_TOSL & TOS_DIRTY *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin VX-- // DEX - if VY <> 0 - *codeptr = $00A0 // LDY #$00 - codeptr = codeptr + 2 - VY = 0 + 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=>0 = $C094+(VX<<8) // STY ESTKH,X - codeptr=>2 = $A9+(^(bytecode+i)<<8) // LDA #imm - codeptr = codeptr + 4 - A_IS_TOSL = TOS_DIRTY // STA ESTKL,X + *codeptr = $A9+(^(bytecode+i)<<8) // LDA #imm + codeptr = codeptr + 2 + A_IS_TOSL = TOS_DIRTY // STA ESTKL,X break is $2E // CS i++ @@ -447,31 +440,43 @@ def compiler(defptr)#0 //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 = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - codeptr->0 = $18 // CLC - codeptr=>1 = $69+(^(bytecode+i)<<8) // ADC #imm - codeptr=>3 = $0290 // BCC +2 - codeptr=>5 = $C0F6+(VX<<8) // INC ESTKH,X + codeptr->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 + 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 = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - codeptr->0 = $38 // SEC - codeptr=>1 = $E9+(^(bytecode+i)<<8) // SBC #imm - codeptr=>3 = $02B0 // BCS +2 - codeptr=>5 = $C0D6+(VX<<8) // DEC ESTKH,X + codeptr->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 + A_IS_TOSL = TOS_DIRTY // STA ESTKL,X break is $3C // ANDI i++ @@ -502,29 +507,7 @@ def compiler(defptr)#0 A_IS_TOSL = TOS_DIRTY // STA ESTKL,X break is $40 // ISEQ - //puts("ISEQ") - if VY <> 0 - *codeptr = $00A0 // LDY #$00 - codeptr = codeptr + 2 - fin - if not A_IS_TOSL - *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X - codeptr = codeptr + 2 - fin - codeptr=>0 = $D0D5+$0100+(VX<<8) // CMP ESTKL+1,X - codeptr=>2 = $07D0 // BNE +7 - codeptr=>4 = $C0B5+(VX<<8) // LDA ESTKH,X - codeptr=>6 = $C0D5+$0100+(VX<<8) // CMP ESTKH+1 - codeptr=>8 = $01D0 // BNE +1 - codeptr=>10 = $9888 // DEY; TYA - codeptr=>12 = $C094+$0100+(VX<<8) // STY ESTKH+1,X - codeptr = codeptr + 14 - VX++ // INX - VY = UNKNOWN - A_IS_TOSL = TOS_DIRTY // STA ESTKL,X - break is $42 // ISNE - //puts("ISNE") if VY <> 0 *codeptr = $00A0 // LDY #$00 codeptr = codeptr + 2 @@ -533,11 +516,18 @@ def compiler(defptr)#0 *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=>2 = $06D0 // BNE +6 codeptr=>4 = $C0B5+(VX<<8) // LDA ESTKH,X codeptr=>6 = $C0D5+$0100+(VX<<8) // CMP ESTKH+1 - codeptr=>8 = $01F0 // BEQ +1 codeptr=>10 = $9888 // DEY; TYA codeptr=>12 = $C094+$0100+(VX<<8) // STY ESTKH+1,X codeptr = codeptr + 14 @@ -546,7 +536,7 @@ def compiler(defptr)#0 A_IS_TOSL = TOS_DIRTY // STA ESTKL,X break is $44 // ISGT - //puts("ISGT") + is $4A // ISLE if VY <> 0 *codeptr = $00A0 // LDY #$00 codeptr = codeptr + 2 @@ -560,7 +550,13 @@ def compiler(defptr)#0 codeptr=>4 = $C0F5+$0100+(VX<<8) // SBC ESTKH+1 codeptr=>6 = $0250 // BVC +2 codeptr=>8 = $8049 // EOR #$80 - codeptr=>10 = $0110 // BPL +1 + 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 @@ -568,8 +564,8 @@ def compiler(defptr)#0 VY = UNKNOWN A_IS_TOSL = TOS_DIRTY // STA ESTKL,X break - is $46 - //puts("ISLT") + is $46 // ISLT + is $48 // ISGE if A_IS_TOSL & TOS_DIRTY *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 @@ -584,7 +580,13 @@ def compiler(defptr)#0 codeptr=>6 = $C0F5+(VX<<8) // SBC ESTKH codeptr=>8 = $0250 // BVC +2 codeptr=>10 = $8049 // EOR #$80 - codeptr=>12 = $0110 // BPL +1 + 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 @@ -592,85 +594,24 @@ def compiler(defptr)#0 VY = UNKNOWN A_IS_TOSL = TOS_DIRTY // STA ESTKL,X break - is $48 - //puts("ISGE") - if A_IS_TOSL & TOS_DIRTY - *codeptr = $D095+(VX<<8) // STA ESTKL,X - codeptr = codeptr + 2 - fin - if VY <> 0 - *codeptr = $00A0 // LDY #$00 - codeptr = codeptr + 2 - fin - codeptr=>0 = $D0B5+$0100+(VX<<8) // LDA ESTKL+1,X - codeptr=>2 = $D0D5+(VX<<8) // CMP ESTKL,X - codeptr=>4 = $C0B5+$0100+(VX<<8) // LDA ESTKH+1,X - codeptr=>6 = $C0F5+(VX<<8) // SBC ESTKH - codeptr=>8 = $0250 // BVC +2 - codeptr=>10 = $8049 // EOR #$80 - codeptr=>12 = $0130 // BMI +1 - codeptr=>14 = $9888 // DEY; TYA - codeptr=>16 = $C094+$0100+(VX<<8) // STY ESTKH+1,X - codeptr = codeptr + 18 - VX++ // INX - VY = UNKNOWN - A_IS_TOSL = TOS_DIRTY // STA ESTKL,X - break - is $4A // ISLE - //puts("ISLE") - if VY <> 0 - *codeptr = $00A0 // LDY #$00 - codeptr = codeptr + 2 - fin - if not A_IS_TOSL - *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X - codeptr = codeptr + 2 - fin - codeptr=>0 = $D0D5+$0100+(VX<<8) // CMP ESTKL+1,X - codeptr=>2 = $C0B5+(VX<<8) // LDA ESTKH,X - codeptr=>4 = $C0F5+$0100+(VX<<8) // SBC ESTKH+1 - codeptr=>6 = $0250 // BVC +2 - codeptr=>8 = $8049 // EOR #$80 - codeptr=>10 = $0130 // BMI +1 - codeptr=>12 = $9888 // DEY; TYA - codeptr=>14 = $C094+$0100+(VX<<8) // STY ESTKH+1,X - codeptr = codeptr + 16 - VX++ // INX - VY = UNKNOWN - A_IS_TOSL = TOS_DIRTY // STA ESTKL,X - break is $4C // BRFLS - i++ - dest = i + *(bytecode+i) - i++ - //puts("BRFLS "); puti(dest) - codeptr, VX = resolveX(codeptr, VX + 1) // INX - if not A_IS_TOSL - *codeptr = $D0B5-$0100//+(VX<<8) // LDA ESTKL-1,X - codeptr = codeptr + 2 - fin - codeptr=>0 = $C015-$0100//+(VX<<8) // ORA ESTKH-1,X - codeptr=>2 = $03D0 // BNE +3 - codeptr->4 = $4C // JMP abs - codeptr=>5 = addrxlate=>[dest] - if not (codeptr->6 & $80) // Unresolved address list - addrxlate=>[dest] = codeptr + 5 - *jitcodeptr - fin - codeptr = codeptr + 7 - A_IS_TOSL = FALSE - break is $4E // BRTRU i++ dest = i + *(bytecode+i) i++ - //puts("BRTRU "); puti(dest) codeptr, VX = resolveX(codeptr, VX + 1) // INX if not A_IS_TOSL *codeptr = $D0B5-$0100//+(VX<<8) // LDA ESTKL-1,X codeptr = codeptr + 2 fin codeptr=>0 = $C015-$0100//+(VX<<8) // ORA ESTKH-1,X - codeptr=>2 = $03F0 // BEQ +3 + 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 @@ -813,20 +754,6 @@ def compiler(defptr)#0 ^codeptr = $60; codeptr++ // RTS A_IS_TOSL = FALSE break - is $5E // CFFB - i++ - //puts("CFFB $FF"); putb(^(bytecode+i)) - if A_IS_TOSL & TOS_DIRTY - *codeptr = $D095+(VX<<8) // STA ESTKL,X - codeptr = codeptr + 2 - fin - VX-- // DEX - codeptr=>0 = $FFA9 // LDA #$FF - codeptr=>2 = $C095+(VX<<8) // STA ESTKH,X - codeptr=>4 = $A9+(^(bytecode+i)<<8) // LDA #imm - codeptr = codeptr + 6 - A_IS_TOSL = TOS_DIRTY // STA ESTKL,X - break is $60 // LB //puts("LB") if VY <> 0 @@ -866,25 +793,25 @@ def compiler(defptr)#0 j = ^(bytecode+i) //puts("LLB "); puti(j) if A_IS_TOSL & TOS_DIRTY - *codeptr = $D095+(VX<<8) // STA ESTKL,X + *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin - VX-- // DEX + VX-- // DEX if VY <> j - *codeptr = $A0+(j<<8) // LDY #imm + *codeptr = $A0+(j<<8) // LDY #imm codeptr = codeptr + 2 VY = j fin - *codeptr = $E0B1 // LDA (IFP),Y + *codeptr = $E0B1 // LDA (IFP),Y codeptr = codeptr + 2 if VY - *codeptr = $00A0 // LDY #$00 + *codeptr = $00A0 // LDY #$00 codeptr = codeptr + 2 VY = 0 fin - *codeptr = $C094+(VX<<8) // STY ESTKH,X + *codeptr = $C094+(VX<<8) // STY ESTKH,X codeptr = codeptr + 2 - A_IS_TOSL = TOS_DIRTY // STA ESTKL,X + A_IS_TOSL = TOS_DIRTY // STA ESTKL,X break is $66 // LLW i++ @@ -910,59 +837,104 @@ def compiler(defptr)#0 A_IS_TOSL = TOS_DIRTY // STA ESTKL,X break is $68 // LAB - i++ - //puts("LAB $"); puth(*(bytecode+i)) - if A_IS_TOSL & TOS_DIRTY - *codeptr = $D095+(VX<<8) // STA ESTKL,X - codeptr = codeptr + 2 - fin - VX-- // DEX - if VY <> 0 - *codeptr = $00A0 // LDY #$00 - codeptr = codeptr + 2 - VY = 0 - fin - codeptr=>0 = $C094+(VX<<8) // STY ESTKH,X - codeptr->2 = $AD // LDA abs - codeptr=>3 = *(bytecode+i) - codeptr = codeptr + 5 - A_IS_TOSL = TOS_DIRTY // STA ESTKL,X - i++ - break is $6A // LAW i++ dest = *(bytecode+i) - //puts("LAW $"); puth(dest) + 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+1 - codeptr=>3 = $C095+(VX<<8) // STA ESTKH,X - codeptr->5 = $AD // LDA abs - codeptr=>6 = dest - codeptr = codeptr + 8 + codeptr=>1 = dest + codeptr = codeptr + 3 A_IS_TOSL = TOS_DIRTY // STA ESTKL,X - i++ + 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) - //puts("DLB "); puti(j) if not A_IS_TOSL *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 A_IS_TOSL = TOS_CLEAN fin - if VY <> j + 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++ @@ -987,88 +959,24 @@ def compiler(defptr)#0 codeptr = codeptr + 9 A_IS_TOSL = TOS_CLEAN break - is $70 // SB - //puts("SB") - if not A_IS_TOSL - *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X - codeptr = codeptr + 2 - fin - codeptr=>0 = $C095-$0100+(VX<<8) // STA ESTKH-1,X - codeptr=>2 = $D0B5+$0100+(VX<<8) // LDA ESTKL+1,X - codeptr=>4 = $C081-$0100+(VX<<8) // STA (ESTKH-1,X) - codeptr = codeptr + 6 - VX = VX + 2 // INX; INX - A_IS_TOSL = FALSE - break - is $72 // SW - //puts("SW") - if not A_IS_TOSL - *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X - codeptr = codeptr + 2 - fin - codeptr=>0 = $C095-$0100+(VX<<8) // STA ESTKH-1,X - codeptr=>2 = $D0B5+$0100+(VX<<8) // LDA ESTKL+1,X - codeptr=>4 = $C081-$0100+(VX<<8) // STA (ESTKH-1,X) - codeptr=>6 = $C0B5+$0100+(VX<<8) // LDA ESTKH+1,X - codeptr=>8 = $C0F6-$0100+(VX<<8) // INC ESTKH-1,X - codeptr=>10 = $02D0 // BNE +2 - codeptr=>12 = $C0F6+(VX<<8) // INC ESTKH,X - codeptr=>14 = $C081-$0100+(VX<<8) // STA (ESTKH-1,X) - codeptr = codeptr + 16 - VX = VX + 2 // INX; INX - A_IS_TOSL = FALSE - break - is $74 // SLB - i++ - j = ^(bytecode+i) - //puts("SLB "); puti(j) - if not A_IS_TOSL - *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X - codeptr = codeptr + 2 - fin - if VY <> j - *codeptr = $A0+(j<<8) // LDY #imm - codeptr = codeptr + 2 - VY = j - fin - *codeptr = $E091 // STA (IFP),Y - codeptr = codeptr + 2 - VX++ // INX - A_IS_TOSL = FALSE - break - is $76 // SLW - i++ - j = ^(bytecode+i) - //puts("SLW "); puti(j) - if not A_IS_TOSL - *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X - codeptr = codeptr + 2 - fin - if VY <> j - *codeptr = $A0+(j<<8) // LDY #imm - codeptr = codeptr + 2 - fin - codeptr=>0 = $E091 // STA (IFP),Y - codeptr->2 = $C8 // INY - codeptr=>3 = $C0B5+(VX<<8) // LDA ESTKH,X - codeptr=>5 = $E091 // STA (IFP),Y - codeptr = codeptr + 7 - VX++ // INX - VY = j + 1 - A_IS_TOSL = FALSE - break is $78 // SAB + is $7C // DAB i++ - //puts("SAB $"); 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 = *(bytecode+i) codeptr = codeptr + 3 - VX++ // INX - A_IS_TOSL = FALSE + 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 @@ -1089,19 +997,6 @@ def compiler(defptr)#0 A_IS_TOSL = FALSE i++ break - is $7C // DAB - i++ - //puts("DAB $"); puth(*(bytecode+i)) - if not A_IS_TOSL - *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X - codeptr = codeptr + 2 - A_IS_TOSL = TOS_CLEAN - fin - codeptr->0 = $8D // STA abs - codeptr=>1 = *(bytecode+i) - codeptr = codeptr + 3 - i++ - break is $7E // DAW i++ dest = *(bytecode+i) @@ -1200,32 +1095,6 @@ def compiler(defptr)#0 VY = UNKNOWN A_IS_TOSL = FALSE break - is $8C // INCR - //puts("INCR") - if not A_IS_TOSL - *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X - codeptr = codeptr + 2 - fin - codeptr->0 = $18 // CLC - codeptr=>1 = $0169 // ADC #$01 - codeptr=>3 = $0290 // BCC +2 - codeptr=>5 = $C0F6+(VX<<8) // INC ESTKH,X - codeptr = codeptr + 7 - A_IS_TOSL = TOS_DIRTY // STA ESTKL,X - break - is $8E // DECR - //puts("DECR") - if not A_IS_TOSL - *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X - codeptr = codeptr + 2 - fin - codeptr->0 = $38 // SEC - codeptr=>1 = $01E9 // SBC #$01 - codeptr=>3 = $02B0 // BCS +2 - codeptr=>5 = $C0D6+(VX<<8) // DEC ESTKH,X - codeptr = codeptr + 7 - A_IS_TOSL = TOS_DIRTY // STA ESTKL,X - break is $90 // NEG //puts("NEG") if A_IS_TOSL & TOS_DIRTY @@ -1261,45 +1130,31 @@ def compiler(defptr)#0 A_IS_TOSL = FALSE break is $94 // AND - //puts("AND") - if not A_IS_TOSL - *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X - codeptr = codeptr + 2 - fin - codeptr=>0 = $D035+$0100+(VX<<8) // AND ESTKL+1,X - codeptr=>2 = $D095+$0100+(VX<<8) // STA ESTKL+1,X - codeptr=>4 = $C0B5+(VX<<8) // LDA ESTKH,X - codeptr=>6 = $C035+$0100+(VX<<8) // AND ESTKH+1,X - codeptr=>8 = $C095+$0100+(VX<<8) // STA ESTKH+1,X - codeptr = codeptr + 10 - VX++ // INX - A_IS_TOSL = FALSE - break is $96 // OR - //puts("OR") - if not A_IS_TOSL - *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X - codeptr = codeptr + 2 - fin - codeptr=>0 = $D015+$0100+(VX<<8) // ORA ESTKL+1,X - codeptr=>2 = $D095+$0100+(VX<<8) // STA ESTKL+1,X - codeptr=>4 = $C0B5+(VX<<8) // LDA ESTKH,X - codeptr=>6 = $C015+$0100+(VX<<8) // ORA ESTKH+1,X - codeptr=>8 = $C095+$0100+(VX<<8) // STA ESTKH+1,X - codeptr = codeptr + 10 - VX++ // INX - A_IS_TOSL = FALSE - break is $98 // XOR - //puts("XOR") + 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 = $D055+$0100+(VX<<8) // EOR ESTKL+1,X + 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 = $C055+$0100+(VX<<8) // EOR ESTKH+1,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 @@ -1378,61 +1233,38 @@ def compiler(defptr)#0 A_IS_TOSL = FALSE break is $A4 // INCBRLE - FOR/NEXT SPECIFIC INC & TEST & BRANCH - i++ - dest = i + *(bytecode+i) - //puts("INCBRLE "); puti(dest) - i++ - // - // INCR - // - if not A_IS_TOSL - *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X - codeptr = codeptr + 2 - fin - codeptr->0 = $18 // CLC - codeptr=>1 = $0169 // ADC #$01 - codeptr=>3 = $D095+(VX<<8) // STA ESTKL,X - codeptr=>5 = $0290 // BCC +2 - codeptr=>7 = $C0F6+(VX<<8) // INC ESTKH,X - codeptr, VX = resolveX(codeptr + 9, VX) - // - // BRLE - // - codeptr=>0 = $D0B5+$0100//+(VX<<8) // LDA ESTKL+1,X - codeptr=>2 = $D0D5//+(VX<<8) // CMP ESTKL,X - codeptr=>4 = $C0B5+$0100//+(VX<<8) // LDA ESTKH+1,X - codeptr=>6 = $C0F5//+(VX<<8) // SBC ESTKH - codeptr=>8 = $0250 // BVC +2 - codeptr=>10 = $8049 // EOR #$80 - codeptr=>12 = $0330 // BMI +3 - codeptr->14 = $4C // JMP abs - codeptr=>15 = addrxlate=>[dest] - if not (codeptr->16 & $80) // Unresolved address list - addrxlate=>[dest] = codeptr + 15 - *jitcodeptr - fin - codeptr=>17 = $E8E8 //VX=VX+2 // INX; INX - codeptr = codeptr + 19 - A_IS_TOSL = FALSE - break is $A6 // ADDBRLE - FOR/NEXT SPECIFIC ADD & TEST & BRANCH i++ dest = i + *(bytecode+i) - //puts("ADDBRLE "); puti(dest) i++ - // - // ADD - // if not A_IS_TOSL - *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - codeptr->0 = $18 // CLC - codeptr=>1 = $D075+$0100+(VX<<8) // ADC ESTKL+1,X - codeptr=>3 = $D095+$0100+(VX<<8) // STA ESTKL+1,X - codeptr=>5 = $C0B5+(VX<<8) // LDA ESTKH,X - codeptr=>7 = $C075+$0100+(VX<<8) // ADC ESTKH+1,X - codeptr=>9 = $C095+$0100+(VX<<8) // STA ESTKH+1,X - codeptr, VX = resolveX(codeptr + 11, VX + 1) // INX + 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 // @@ -1448,28 +1280,54 @@ def compiler(defptr)#0 if not (codeptr->16 & $80) // Unresolved address list addrxlate=>[dest] = codeptr + 15 - *jitcodeptr fin - codeptr=>17 = $E8E8 //VX=VX+2 // INX; INX - codeptr = codeptr + 19 + 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) - //puts("DECBRGE "); puti(dest) i++ - // - // DECR - // - if not A_IS_TOSL - *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + if A_IS_TOSL & TOS_DIRTY + *codeptr = $D095+(VX<<8) // STA 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) + 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 // @@ -1484,78 +1342,15 @@ def compiler(defptr)#0 if not (codeptr->14 & $80) // Unresolved address list addrxlate=>[dest] = codeptr + 13 - *jitcodeptr fin - codeptr=>15 = $E8E8 //VX=VX+2 // INX; INX - codeptr = codeptr + 17 - A_IS_TOSL = FALSE - break - is $AA // SUBBRGE - FOR/NEXT SPECIFIC SUB & TEST & BRANCH - i++ - dest = i + *(bytecode+i) - //puts("SUBBRGE "); puti(dest) - i++ - // - // SUB - // - if A_IS_TOSL & TOS_DIRTY - *codeptr = $D095+(VX<<8) // STA ESTKL,X - codeptr = codeptr + 2 - fin - codeptr=>0 = $D0B5+$0100+(VX<<8) // LDA ESTKL+1,X - codeptr->2 = $38 // SEC - codeptr=>3 = $D0F5+(VX<<8) // SBC ESTKL,X - codeptr=>5 = $D095+$0100+(VX<<8) // STA ESTKL+1,X - codeptr=>7 = $C0B5+$0100+(VX<<8) // LDA ESTKH+1,X - codeptr=>9 = $C0F5+(VX<<8) // SBC ESTKH,X - codeptr=>11 = $C095+$0100+(VX<<8) // STA ESTKH+1,X - codeptr, VX = resolveX(codeptr + 13, VX + 1) // INX - // - // BRGE - // - codeptr=>0 = $D0B5//+(VX<<8) // LDA ESTKL,X - codeptr=>2 = $D0D5+$0100//+(VX<<8) // CMP ESTKL+1,X - codeptr=>4 = $C0B5//+(VX<<8) // LDA ESTKH,X - codeptr=>6 = $C0F5+$0100//+(VX<<8) // SBC ESTKH+1,X - codeptr=>8 = $0250 // BVC +2 - codeptr=>10 = $8049 // EOR #$80 - codeptr=>12 = $0330 // BMI +3 - codeptr->14 = $4C // JMP abs - codeptr=>15 = addrxlate=>[dest] - if not (codeptr->16 & $80) // Unresolved address list - addrxlate=>[dest] = codeptr + 15 - *jitcodeptr - fin - codeptr=>17 = $E8E8 //VX=VX+2 // INX; INX - codeptr = codeptr + 19 + codeptr = codeptr + 15 + VX = VX + 2 // INX; INX A_IS_TOSL = FALSE break is $AC // BRAND - LOGICAL AND SPECIFIC BRANCH - i++ - dest = i + *(bytecode+i) - i++ - //puts("BRAND "); puti(dest) - codeptr, VX = resolveX(codeptr, VX) - if not A_IS_TOSL - *codeptr = $D0B5//+(VX<<8) // LDA ESTKL,X - codeptr = codeptr + 2 - elsif A_IS_TOSL & TOS_DIRTY - *codeptr = $D095//+(VX<<8) // STA ESTKL,X - codeptr = codeptr + 2 - fin - codeptr=>0 = $C015//+(VX<<8) // ORA ESTKH,X - codeptr=>2 = $03D0 // BNE +3 - codeptr->4 = $4C // JMP abs - codeptr=>5 = addrxlate=>[dest] - if not (codeptr->6 & $80) // Unresolved address list - addrxlate=>[dest] = codeptr + 5 - *jitcodeptr - fin - codeptr = codeptr + 7 - VX++ // INX - A_IS_TOSL = FALSE - break is $AE // BROR - LOGICAL OR SPECIFIC BRANCH i++ dest = i + *(bytecode+i) i++ - //puts("BROR "); puti(dest) codeptr, VX = resolveX(codeptr, VX) if not A_IS_TOSL *codeptr = $D0B5//+(VX<<8) // LDA ESTKL,X @@ -1565,7 +1360,13 @@ def compiler(defptr)#0 codeptr = codeptr + 2 fin codeptr=>0 = $C015//+(VX<<8) // ORA ESTKH,X - codeptr=>2 = $03F0 // BEQ +3 + 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 @@ -1576,81 +1377,65 @@ def compiler(defptr)#0 A_IS_TOSL = FALSE break is $B0 // ADDLB - i++ - j = ^(bytecode+i) - //puts("ADDLB "); puti(j) - if not A_IS_TOSL - *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X - codeptr = codeptr + 2 - fin - if VY <> j - *codeptr = $A0+(j<<8) // LDY #imm - codeptr = codeptr + 2 - VY = j - fin - codeptr->0 = $18 // CLC - codeptr=>1 = $E071 // ADC (IFP),Y - codeptr=>3 = $0290 // BCC +2 - codeptr=>5 = $C0F6+(VX<<8) // INC ESTKH,X - codeptr = codeptr + 7 - A_IS_TOSL = TOS_DIRTY // STA ESTKL,X - break is $B2 // ADDLW i++ j = ^(bytecode+i) - //puts("ADDLW "); puti(j) if not A_IS_TOSL - *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - if VY <> j - *codeptr = $A0+(j<<8) // LDY #imm + if VY <> j + *codeptr = $A0+(j<<8) // LDY #imm codeptr = codeptr + 2 fin - codeptr->0 = $18 // CLC - codeptr=>1 = $E071 // ADC (IFP),Y - codeptr=>3 = $D095+(VX<<8) // STA ESTKL,X - codeptr=>5 = $C0B5+(VX<<8) // LDA ESTKH,X - codeptr->7 = $C8 // INY - codeptr=>8 = $E071 // ADC (IFP),Y - codeptr=>10 = $C095+(VX<<8) // STA ESTKH,X - codeptr = codeptr + 12 - VY = j + 1 - A_IS_TOSL = FALSE + 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 - i++ - //puts("ADDAB $"); puth(*(bytecode+i)) - if not A_IS_TOSL - *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X - codeptr = codeptr + 2 - fin - codeptr=>0 = $6D18 // CLC; ADC abs - codeptr=>2 = *(bytecode+i) - codeptr=>4 = $0290 // BCC +2 - codeptr=>6 = $C0F6+(VX<<8) // INC ESTKH,X - codeptr = codeptr + 8 - A_IS_TOSL = TOS_DIRTY // STA ESTKL,X - i++ - break is $B6 // ADDAW i++ dest = *(bytecode+i) i++ - //puts("ADDAW $"); puth(dest) if not A_IS_TOSL - *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - codeptr=>0 = $6D18 // CLC; ADC abs - codeptr=>2 = dest - codeptr=>4 = $D095+(VX<<8) // STA ESTKL,X - codeptr=>6 = $C0B5+(VX<<8) // LDA ESTKH,X - codeptr->8 = $6D // ADC abs - codeptr=>9 = dest+1 - codeptr=>11 = $C095+(VX<<8) // STA ESTKH,X - codeptr = codeptr + 13 - A_IS_TOSL = FALSE + 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++ From 51ba2df6184304638462fa7457890f1d04b4c21c Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Fri, 30 Mar 2018 13:12:39 -0700 Subject: [PATCH 118/147] Move JIT compiler to top of AUX memory --- src/vmsrc/apple/cmd.pla | 35 +++--------------- src/vmsrc/apple/cmdjit.pla | 73 ++++++++++---------------------------- 2 files changed, 23 insertions(+), 85 deletions(-) diff --git a/src/vmsrc/apple/cmd.pla b/src/vmsrc/apple/cmd.pla index bf6ed89..3d8b6a2 100755 --- a/src/vmsrc/apple/cmd.pla +++ b/src/vmsrc/apple/cmd.pla @@ -325,36 +325,6 @@ REVCPYLP LDA (SRC),Y BNE REVCPYLP CPYMEX RTS end -// -// COPY FROM MAIN MEM TO AUX MEM. -// -// MEMXCPY(DST, SRC, SIZE) -// -asm memxcpy(dst,src,size)#0 - LDA ESTKL+1,X - STA $3C - CLC - ADC ESTKL,X - STA $3E - LDA ESTKH+1,X - STA $3D - ADC ESTKH,X - STA $3F - LDA ESTKL+2,X - STA $42 - LDA ESTKH+2,X - STA $43 - STX ESP - BIT ROMEN - SEC - JSR $C311 - BIT LCRDEN+LCBNK2 - LDX ESP - INX - INX - INX - RTS -end asm crout()#0 LDA #$8D BNE ++ @@ -1234,7 +1204,10 @@ def loadmod(mod)#1 // // Move bytecode to AUX bank. // - memxcpy(defaddr, bytecode, modsize - (bytecode - modaddr)) + *$003C = bytecode + *$003E = modaddr + modsize + *$0042 = defaddr + call($C311, 0, 0, 0, $05) // CALL XMOVE with carry set (MAIN->AUX) and ints disabled fin fin if perr diff --git a/src/vmsrc/apple/cmdjit.pla b/src/vmsrc/apple/cmdjit.pla index de20090..923112d 100755 --- a/src/vmsrc/apple/cmdjit.pla +++ b/src/vmsrc/apple/cmdjit.pla @@ -49,14 +49,14 @@ predef crout()#0, cout(c)#0, prstr(s)#0, prbyte(b)#0, prword(w)#0, print(i)#0, c predef markheap()#1, allocheap(size)#1, allocalignheap(size, pow2, freeaddr)#1, releaseheap(newheap)#1, availheap()#1 predef memset(addr,value,size)#0, memcpy(dst,src,size)#0, strcpy(dst,src)#1, strcat(dst,src)#1 predef uword_isgt(a,b)#1, uword_isge(a,b)#1, uword_islt(a,b)#1, uword_isle(a,b)#1, sext(a)#1, divmod(a,b)#2 -predef execmod(modfile)#1, open(path)#1, close(refnum)#1, read(refnum, buff, len)#1, write(refnum, buff, len)#1 +predef execmod(modfile)#1, open(path)#1, close(refnum)#1, read(refnum, buf, len)#1 // // Exported CMDSYS table // word version = $0200 // 02.00 Dev word syspath word syscmdln -word = @execmod, @open, @close, @read, @write +word = @execmod, @open, @close, @read, 0 // Mark write() as NULL byte perr byte jitcount = 45 byte jitsize = 255 @@ -140,7 +140,8 @@ word sysmodsym = @exports // word systemflags = 0 word heap -word xheap = $0C00//$0800 Skip text page2 for double lores +word xheap = $A000 // Set load address for JIT compiler +word xheaptop = $C000 word lastsym = symtbl // // Utility functions @@ -344,36 +345,6 @@ REVCPYLP LDA (SRC),Y BNE REVCPYLP CPYMEX RTS end -// -// COPY FROM MAIN MEM TO AUX MEM. -// -// MEMXCPY(DST, SRC, SIZE) -// -asm memxcpy(dst,src,size)#0 - LDA ESTKL+1,X - STA $3C - CLC - ADC ESTKL,X - STA $3E - LDA ESTKH+1,X - STA $3D - ADC ESTKH,X - STA $3F - LDA ESTKL+2,X - STA $42 - LDA ESTKH+2,X - STA $43 - STX ESP - BIT ROMEN - SEC - JSR $C311 - BIT LCRDEN+LCBNK2 - LDX ESP - INX - INX - INX - RTS -end asm crout()#0 LDA #$8D BNE ++ @@ -908,18 +879,7 @@ def close(refnum)#1 perr = syscall($CC, @params) return perr end -def read(refnum, buff, len)#1 - byte params[8] - - params.0 = 4 - params.1 = refnum - params:2 = buff - params:4 = len - params:6 = 0 - perr = syscall($CA, @params) - return params:6 -end -def write(refnum, buf, len)#1 +def read(refnum, buf, len)#1 byte params[8] params.0 = 4 @@ -927,7 +887,7 @@ def write(refnum, buf, len)#1 params:2 = buf params:4 = len params:6 = 0 - perr = syscall($CB, @params) + perr = syscall($CA, @params) return params:6 end // @@ -990,12 +950,12 @@ def allocxheap(size)#1 xheap = xaddr + size fin fin - //if systemflags & restxt2 - // if uword_isle(xaddr, $0C00) and uword_isgt(xheap, $0800) - // xaddr = $0C00 - // xheap = xaddr + size - // fin - //fin + if systemflags & restxt2 + if uword_isle(xaddr, $0C00) and uword_isgt(xheap, $0800) + xaddr = $0C00 + xheap = xaddr + size + fin + fin if systemflags & resxhgr1 if uword_isle(xaddr, $4000) and uword_isgt(xheap, $2000) xaddr = $4000 @@ -1008,7 +968,7 @@ def allocxheap(size)#1 xheap = xaddr + size fin fin - if uword_isge(xheap, $BF00) + if uword_isge(xheap, xheaptop) return 0 fin return xaddr @@ -1233,7 +1193,10 @@ def loadmod(mod)#1 // // Move bytecode to AUX bank. // - memxcpy(defaddr, bytecode, modsize - (bytecode - modaddr)) + *$003C = bytecode + *$003E = modaddr + modsize + *$0042 = defaddr + call($C311, 0, 0, 0, $05) // CALL XMOVE with carry set (MAIN->AUX) and ints disabled fin if perr return -perr @@ -1464,6 +1427,8 @@ strcat(strcpy(@sysmods, $280), "SYS/")) // This is the path to CMD syspath = @sysmods // Update external interface table syscmdln = @cmdln loadmod(@jitmod) +xheap = $0800 // Reset heap to point at low memory +xheaptop = $A000 // Top where JIT loaded // // Try to load autorun. // From 53a992debb9f83a6860adab8eb612a829fdc8384 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Fri, 30 Mar 2018 13:23:52 -0700 Subject: [PATCH 119/147] Update images --- PLASMA-BLD2.PO | Bin 143360 -> 143360 bytes PLASMA-SYS2.PO | Bin 143360 -> 143360 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/PLASMA-BLD2.PO b/PLASMA-BLD2.PO index 475a5c65369caf23022826ed343a0d773ec553e3..8a4638906b5ba879aa9072a1548fbd408888518c 100644 GIT binary patch delta 18398 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 delta 18829 zcmb8$4O~=J!uauXFP8y%b7pu)kr5DZLHqHg>Aw@=@hbI&>V+;h)4 z_uO;u;EMMmSG*UweQ)^aVd5Wi#Io#UbC&qKFaoN`oiwAOa)#3-y8b(PzladmN1vYU z;eUm@6tkj=McGjnV`mw7cz(oRG*#(*SW*9`Y>E3I`fn4}1w#B9zd)SxaP-$%>SObV zs-x9)1>arq@VnoiujK5vav1v@K0NQsV1ar;tlW4_Zt%bAdB^H`E1<>9Q*)JTF?NI3h*9xy;qPF8}9#ioR~j&-qolwZzoerd!#k#I#r!#xA;W^c5c6 z+7(AK(VF5+BbQf|v5j6MU6uQ&ZTh-hKaX8-)UwcXlw%#Wc;2WV%_XtvwX9Yo&Bl*IMop=RGCX=h!UC+ zj7!%0)W>?Bu~eJrofAoO=^R&WKV8_eqlDcivrc2@d0(xsj^SIqO~#bS7_q*(udv(M zre}%F3PsKn*+kFliH`9Jdwyt((~x~{6wm4X=Z+zly}7%T?)~g7y<#*~=2>RM&`7go zBZcCY_m1<04r#9m?Yc)+A|gx|D>@>nalTMOBf?D27&SAptr44(MYBm)A2&79{JJK; z_axu_d1rk@S9#7}2=-Mh> zTg<4_bglYCC;jHtoMYrw<9T;oOy>~I2#oD4%I2z99NEIDiab?#nylwn|JW&~0+s95 zh*UjI>(+J->eJQrZAaJb?o95rb+j|h*L^Xz9kn=1>7Np{k&(ur>c^mxn+@jMHgNFJ zB`b5KF}~zzGV&5=Hz6<{Ze(E*?Iqh|4=war5^||Lop#9M}Ak zlT_u**(*3wQ3}WIPHKD7BHK7@MMsQ~0j)z5Zp{%c7y|X-btVQn2hmmawzfkSu99og zxc<*ccQpm?RFsR8-nO_lr?+U;1=NRm>2Zr^H!;EURAo?{iAnYJxZ!g)r_1S6QROry z6aQi zuqsR$ti%TwhAGJxomPB|(LA(`t}*x7GkVIOOzu|=u!0KxX5Z6hD*FT_-UBZZzi>msna<3wtW`br0qpMBiml))7-Y7 zPqpo!h5KQ?DCN_UA?&3_M%Bou^~$J_kzL8PTo2Z3%D}pP7G_}~+P2BtXDIlH49d8j z@>Uay+kPsz!{XU*B-6jfVcT|v4j#E``D-$?{9Q}i(ctTvGH8&oO%#)9q$W=@XP2eP z7$!YE?>Q7q4_8us@d+ffFMZqM*=s3@+@UVtYw_&jCVMc{ht5*^klAI2Y55_Gz0;Ux zoi?Li1v?1_B-z{cTIN#B(swLmZ96Q>YI{!Bi8R8pKsM$!yn;4)gR<*Z8@ztW~QT4HP@hV}jMh^+k zR?C_#4~mvZR&To^8@*=FPRkB+Lo;`->Hw9omuAZ~Ciz3v%n=z5526>hXhdbp~cWq;~9_VyN%Hl~c17?wD+B!RQN~h}6PK8p=FRYKRvno_`QBI30JCXBOJ?{p8h*5?Q zde_o@3z2o_Du{G_k;6xEuIwqcV_e5`gVnK0n(vUc!JeJHQg{wo+uIIV`D(BiPTAH+ zMl{$*Ph;7ji^$vL*2*!3Ug4Y`N-68fQ+0ZtQREpM$}_(wkA8ZdS>y>9Tq_=V{OW5u zos&a*6jpU~AGtz~29dD3=g0(3)v$NIw`FU}Y+iP#S7ouivf47g?qs`-hnhpyoJ_N8 zTKv+(R!(*45o^<7pH)6(aNh4&S1o

      U3yLN35~|B83ca{w2cx0y~JdV^+^GYfpXT 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 F{U3TA3>N?Z From 630ccd88fa1673a90df0275ec749826c49a0d2ea Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Sat, 31 Mar 2018 15:13:13 -0700 Subject: [PATCH 120/147] Improve LLA opts a little --- src/libsrc/apple/cleanjit.pla | 33 ++++++++++++++++++++----------- src/libsrc/apple/jit.pla | 37 +++++++++++++++++++++++------------ 2 files changed, 46 insertions(+), 24 deletions(-) diff --git a/src/libsrc/apple/cleanjit.pla b/src/libsrc/apple/cleanjit.pla index 3d91ba2..8a86ff2 100644 --- a/src/libsrc/apple/cleanjit.pla +++ b/src/libsrc/apple/cleanjit.pla @@ -360,19 +360,30 @@ def compiler(defptr)#0 j = ^(bytecode+i) //puts("LLA "); puti(^(bytecode+i)) if A_IS_TOSL & TOS_DIRTY - *codeptr = $D095+(VX<<8) // STA ESTKL,X + *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin - VX-- // DEX - codeptr=>0 = $A9+(j<<8) // LDA #imm - codeptr->2 = $18 // CLC - codeptr=>3 = $E065 // ADC IFPL - codeptr=>5 = $D095+(VX<<8) // STA ESTKL,X - codeptr=>7 = $00A9 // LDA #$00 - codeptr=>9 = $E165 // ADC IFPH - codeptr=>11 = $C095+(VX<<8) // STA ESTKH,X - codeptr = codeptr + 13 - A_IS_TOSL = FALSE + VX-- // DEX + if VY == j + ^codeptr = $98; codeptr++ // TYA -> LDA #imm + else + *codeptr = $A9+(j<<8) // LDA #imm + codeptr = codeptr + 2 + fin + codeptr->0 = $18 // CLC + codeptr=>1 = $E065 // ADC IFPL + codeptr=>3 = $D095+(VX<<8) // STA ESTKL,X + if VY == 0 + codeptr->5 = $98 // TYA -> LDA #00 + codeptr = codeptr + 6 + else + codeptr=>5 = $00A9 // LDA #$00 + codeptr = codeptr + 7 + fin + codeptr=>0 = $E165 // ADC IFPH + codeptr=>2 = $C095+(VX<<8) // STA ESTKH,X + codeptr = codeptr + 4 + A_IS_TOSL = FALSE break is $2A // CB i++ diff --git a/src/libsrc/apple/jit.pla b/src/libsrc/apple/jit.pla index 55a4027..dde73e7 100644 --- a/src/libsrc/apple/jit.pla +++ b/src/libsrc/apple/jit.pla @@ -344,19 +344,30 @@ def compiler(defptr)#0 j = ^(bytecode+i) //puts("LLA "); puti(^(bytecode+i)) if A_IS_TOSL & TOS_DIRTY - *codeptr = $D095+(VX<<8) // STA ESTKL,X + *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin - VX-- // DEX - codeptr=>0 = $A9+(j<<8) // LDA #imm - codeptr->2 = $18 // CLC - codeptr=>3 = $E065 // ADC IFPL - codeptr=>5 = $D095+(VX<<8) // STA ESTKL,X - codeptr=>7 = $00A9 // LDA #$00 - codeptr=>9 = $E165 // ADC IFPH - codeptr=>11 = $C095+(VX<<8) // STA ESTKH,X - codeptr = codeptr + 13 - A_IS_TOSL = FALSE + 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 @@ -1590,10 +1601,10 @@ end // Install JIT compiler // if *jitcomp - puts("JIT compiler already installed!\n") + //puts("JIT compiler already installed!\n") return 0 fin -puts("Installing JIT compiler\n") +puts("JITC installed\n") *jitcomp = @compiler return modkeep done From 46b9f073d5c11414e3bd712d5fd072126a037a61 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Sat, 31 Mar 2018 17:15:18 -0700 Subject: [PATCH 121/147] New JIT defaults --- src/vmsrc/apple/cmdjit.pla | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vmsrc/apple/cmdjit.pla b/src/vmsrc/apple/cmdjit.pla index 923112d..74ff408 100755 --- a/src/vmsrc/apple/cmdjit.pla +++ b/src/vmsrc/apple/cmdjit.pla @@ -58,8 +58,8 @@ word syspath word syscmdln word = @execmod, @open, @close, @read, 0 // Mark write() as NULL byte perr -byte jitcount = 45 -byte jitsize = 255 +byte jitcount = 44 +byte jitsize = 96 // // Working input buffer overlayed with strings table // From 46b24b077aca99608a0058c634086096f2f5243a Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Sun, 1 Apr 2018 15:29:57 -0700 Subject: [PATCH 122/147] 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 From 574911e389ff9da5db79e4d8c2c6fc5b900b074c Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Sun, 1 Apr 2018 18:53:56 -0700 Subject: [PATCH 123/147] Apple /// JIT WIP --- src/inc/cmdsys.plh | 3 +- src/toolsrc/parse.c | 13 +++-- src/toolsrc/parse.pla | 117 +++++++++++++++++++------------------ src/vmsrc/apple/plvm03.s | 61 +++++++++++++++++++ src/vmsrc/apple/soscmd.pla | 77 ++++++++++++++++++++++++ src/vmsrc/apple/sossys.pla | 5 +- 6 files changed, 212 insertions(+), 64 deletions(-) diff --git a/src/inc/cmdsys.plh b/src/inc/cmdsys.plh index a65a01c..7b311df 100644 --- a/src/inc/cmdsys.plh +++ b/src/inc/cmdsys.plh @@ -55,7 +55,8 @@ import cmdsys byte jitsize byte refcons // Apple /// specific byte devcons // Apple /// specific - byte cmdparser + word jitc + word cmdparser end // // CMD exported functions diff --git a/src/toolsrc/parse.c b/src/toolsrc/parse.c index d43ba50..1301921 100755 --- a/src/toolsrc/parse.c +++ b/src/toolsrc/parse.c @@ -1540,11 +1540,16 @@ int parse_defs(void) char c, *idstr; int idlen, func_tag, cfnparms, cfnvals, type = GLOBAL_TYPE, pretype; static char bytecode = 0; - if (scantoken == EXPORT_TOKEN) + + switch (scantoken) { - if (scan() != DEF_TOKEN && scantoken != ASM_TOKEN) - parse_error("Bad export definition"); - type = EXPORT_TYPE; + case CONST_TOKEN: + case STRUC_TOKEN: + return parse_vars(GLOBAL_TYPE); + case EXPORT_TOKEN: + if (scan() != DEF_TOKEN && scantoken != ASM_TOKEN) + parse_error("Bad export definition"); + type = EXPORT_TYPE; } if (scantoken == DEF_TOKEN) { diff --git a/src/toolsrc/parse.pla b/src/toolsrc/parse.pla index 6080e97..79d0cee 100644 --- a/src/toolsrc/parse.pla +++ b/src/toolsrc/parse.pla @@ -1220,65 +1220,68 @@ def parse_defs word type, idstr, func_tag, idptr type = FUNC_TYPE - if token == EXPORT_TKN - if scan <> DEF_TKN; exit_err(ERR_INVAL|ERR_STATE); fin - type = type | EXPORT_TYPE - fin - if token == DEF_TKN - if scan <> ID_TKN; exit_err(ERR_INVAL|ERR_ID); fin - lambda_cnt = 0 - cfnparms = 0 - infuncvals = 1 - infunc = TRUE - idstr = tknptr - idlen = tknlen - init_idlocal - if scan == OPEN_PAREN_TKN - repeat - if scan == ID_TKN - cfnparms++ - new_idlocal(tknptr, tknlen, WORD_TYPE, 2) - scan - fin - until token <> COMMA_TKN - if token <> CLOSE_PAREN_TKN; exit_err(ERR_MISS|ERR_CLOSE|ERR_SYNTAX); fin + when token + is CONST_TKN + is STRUC_TKN + return parse_vars(GLOBAL_TYPE) + is EXPORT_TKN + if scan <> DEF_TKN; exit_err(ERR_INVAL|ERR_STATE); fin + type = type | EXPORT_TYPE + is DEF_TKN + if scan <> ID_TKN; exit_err(ERR_INVAL|ERR_ID); fin + lambda_cnt = 0 + cfnparms = 0 + infuncvals = 1 + infunc = TRUE + idstr = tknptr + idlen = tknlen + init_idlocal + if scan == OPEN_PAREN_TKN + repeat + if scan == ID_TKN + cfnparms++ + new_idlocal(tknptr, tknlen, WORD_TYPE, 2) + scan + fin + until token <> COMMA_TKN + if token <> CLOSE_PAREN_TKN; exit_err(ERR_MISS|ERR_CLOSE|ERR_SYNTAX); fin + scan + fin + if token == POUND_TKN + if not parse_const(@infuncvals); exit_err(ERR_INVAL|ERR_CONST); fin + scan + fin + idptr = lookup_idglobal(idstr, idlen) + if idptr + if not idptr=>idtype & PREDEF_TYPE; exit_err(ERR_DUP|ERR_ID); fin + if idptr->funcparms <> cfnparms or idptr->funcvals <> infuncvals; exit_err(ERR_DUP|ERR_CODE|ERR_ID); fin + func_tag = idptr=>idval + idptr=>idtype = idptr=>idtype | type + else + func_tag = new_tag(WORD_FIXUP) + new_idfunc(idstr, idlen, type, func_tag, cfnparms, infuncvals) + fin + emit_tag(func_tag) + new_dfd(func_tag) + while parse_vars(LOCAL_TYPE); nextln; loop + emit_enter(cfnparms) + prevstmnt = 0 + while parse_stmnt; nextln; loop + infunc = FALSE + if token <> END_TKN; exit_err(ERR_MISS|ERR_CLOSE|ERR_STATE); fin scan - fin - if token == POUND_TKN - if not parse_const(@infuncvals); exit_err(ERR_INVAL|ERR_CONST); fin - scan - fin - idptr = lookup_idglobal(idstr, idlen) - if idptr - if not idptr=>idtype & PREDEF_TYPE; exit_err(ERR_DUP|ERR_ID); fin - if idptr->funcparms <> cfnparms or idptr->funcvals <> infuncvals; exit_err(ERR_DUP|ERR_CODE|ERR_ID); fin - func_tag = idptr=>idval - idptr=>idtype = idptr=>idtype | type - else - func_tag = new_tag(WORD_FIXUP) - new_idfunc(idstr, idlen, type, func_tag, cfnparms, infuncvals) - fin - emit_tag(func_tag) - new_dfd(func_tag) - while parse_vars(LOCAL_TYPE); nextln; loop - emit_enter(cfnparms) - prevstmnt = 0 - while parse_stmnt; nextln; loop - infunc = FALSE - if token <> END_TKN; exit_err(ERR_MISS|ERR_CLOSE|ERR_STATE); fin - scan - if prevstmnt <> RETURN_TKN - if infuncvals; parse_warn("No return values"); fin - for cfnvals = infuncvals - 1 downto 0 - emit_const(0) + if prevstmnt <> RETURN_TKN + if infuncvals; parse_warn("No return values"); fin + for cfnvals = infuncvals - 1 downto 0 + emit_const(0) + next + emit_leave + fin + for cfnvals = 0 to lambda_cnt-1 + emit_lambdafunc(lambda_tag[cfnvals], lambda_cparms[cfnvals], lambda_seq[cfnvals]) + new_dfd(lambda_tag[cfnvals]) next - emit_leave - fin - for cfnvals = 0 to lambda_cnt-1 - emit_lambdafunc(lambda_tag[cfnvals], lambda_cparms[cfnvals], lambda_seq[cfnvals]) - new_dfd(lambda_tag[cfnvals]) - next - fin + wend return token == EOL_TKN ?? TRUE :: FALSE end def parse_module#0 diff --git a/src/vmsrc/apple/plvm03.s b/src/vmsrc/apple/plvm03.s index 6f92cb1..a49a5e7 100755 --- a/src/vmsrc/apple/plvm03.s +++ b/src/vmsrc/apple/plvm03.s @@ -150,6 +150,7 @@ OPTBL !WORD CN,CN,CN,CN,CN,CN,CN,CN ; 00 02 !WORD NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 90 92 94 96 98 9A 9C 9E !WORD BRGT,BRLT,INCBRLE,ADDBRLE,DECBRGE,SUBBRGE,BRAND,BROR ; A0 A2 A4 A6 A8 AA AC AE !WORD ADDLB,ADDLW,ADDAB,ADDAW,IDXLB,IDXLW,IDXAB,IDXAW ; B0 B2 B4 B6 B8 BA BC BE + !WORD NATV ; C0 ;* ;* SYSTEM INTERPRETER ENTRYPOINT ;* @@ -182,6 +183,55 @@ XINTERP PLA DEY JMP FETCHOP ;* +;* JIT PROFILING ENTRY INTO INTERPRETER +;* +JITINTRP PLA + SEC + SBC #$02 ; POINT TO DEF ENTRY + STA TMPL + PLA + SBC #$00 + STA TMPH + LDY #$05 + LDA (TMP),Y ; DEC JIT COUNT + SEC + SBC #$01 + STA (TMP),Y + BEQ RUNJIT + DEY ; INTERP BYTECODE AS USUAL + LDA (TMP),Y + STA IPH + DEY + LDA (TMP),Y + STA IPL + LDY #$00 + JMP FETCHOP +RUNJIT LDA JITCOMP + STA SRCL + LDA JITCOMP+1 + STA SRCH + DEY ; LDY #$04 + LDA (SRC),Y + STA IPH + DEY + LDA (SRC),Y + STA IPL + DEX ; ADD PARAMETER TO DEF ENTRY + LDA TMPL + PHA ; AND SAVE IT FOR LATER + STA ESTKL,X + LDA TMPH + PHA + STA ESTKH,X + LDY #$00 + JSR FETCHOP ; CALL JIT COMPILER + PLA + STA TMPH + PLA + STA TMPL + JMP JMPTMP ; RE-CALL ORIGINAL DEF ENTRY +JITCOMP !WORD 0 +;* ;* INTERNAL DIVIDE ALGORITHM ;* _NEG LDA #$00 @@ -1369,6 +1419,17 @@ LEAVE INY ;+INC_IP PLA STA IFPH RET RTS +;* +;* RETURN TO NATIVE CODE +;* +NATV TYA ; FLATTEN IP + SEC + ADC IPL + STA TMPL + LDA #$00 + ADC IPH + STA TMPH + JMP JMPTMP SOSCMD = * !SOURCE "vmsrc/apple/sossys.a" } diff --git a/src/vmsrc/apple/soscmd.pla b/src/vmsrc/apple/soscmd.pla index 69a1c5c..0700d98 100755 --- a/src/vmsrc/apple/soscmd.pla +++ b/src/vmsrc/apple/soscmd.pla @@ -1,5 +1,78 @@ include "inc/cmdsys.plh" // +// JIT compiler values +// +// +// Indirect interpreter DEFinition entrypoint +// +struc t_defentry + byte interpjsr + word interpaddr + word bytecodeaddr + byte bytecodexbyte + byte callcount + byte bytecodesize +end +// +// JIT compiler constants +// +const jitcomp = $03E2 +const codemax = $A000 +// +// AUX bytecode interpreter entrypoint +// +word jitcodeptr +word codeptr +word interpentry +// +// COPY FROM EXT MEM TO MAIN MEM. +// +// XMEMCPY(DST, XSRC, SIZE) +// +asm defcpy(dst,defentry)#0 + !SOURCE "vmsrc/plvmzp.inc" +XPAGE = $1600 +SRCX = XPAGE+SRCH +DSTX = XPAGE+DSTH + +//asm memxcpy(dst,src,size)#0 + LDA ESTKL,X + ORA ESTKH,X + BEQ CPYXMEX + LDY #$00 + STY DSTL + LDA ESTKH+2,X + CLC + ADC #$60 + STA DSTH + LDA ESTKL+2,X + CLC + ADC #$7F + STA DSTX + LDA ESTKL+1,X + STA SRCL + LDA ESTKH+1,X + STA SRCH + INC ESTKH,X +CPYXLP LDA (SRC),Y + STA (DST),Y + INY + BNE + + INC DSTH + INC SRCH ++ DEC ESTKL,X + BNE CPYXLP + DEC ESTKH,X + BNE CPYXLP + LDA #$00 + STA DSTX +CPYXMEX INX + INX + INX + RTS +end +include "libsrc/jitcore.pla" +// // SOS routines // FILE I/O // @@ -240,4 +313,8 @@ end // Save pointer to command line handler // cmdsys:cmdparser = @shell +// +// Install JIT compiler +// +cmdsys:jitc = @compiler done diff --git a/src/vmsrc/apple/sossys.pla b/src/vmsrc/apple/sossys.pla index d408a4a..1d4ac94 100755 --- a/src/vmsrc/apple/sossys.pla +++ b/src/vmsrc/apple/sossys.pla @@ -34,10 +34,11 @@ word syspath word cmdlnptr word = @execmod, @open, @close, @read, @write byte perr -byte jitcount = $10 -byte jitsize = $FF +byte jitcount = 45 +byte jitsize = 96 byte refcons = 0 byte devcons = 0 +word jitcomp = 0 word cmdparser // // String pool. From d4f15e3a90629958743a39523a2c0621a2592f24 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Mon, 2 Apr 2018 08:47:16 -0700 Subject: [PATCH 124/147] Apple /// JITC --- src/vmsrc/apple/plvm03.s | 28 +++++++++---------- src/vmsrc/apple/soscmd.pla | 35 ++++++++++++------------ src/vmsrc/apple/sossys.pla | 55 +++++++++++++++++++++++++++++--------- 3 files changed, 74 insertions(+), 44 deletions(-) diff --git a/src/vmsrc/apple/plvm03.s b/src/vmsrc/apple/plvm03.s index a49a5e7..144e399 100755 --- a/src/vmsrc/apple/plvm03.s +++ b/src/vmsrc/apple/plvm03.s @@ -31,6 +31,8 @@ JMPTMPX = XPAGE+JMPTMP TMPX = XPAGE+TMPH SRCX = XPAGE+SRCH DSTX = XPAGE+DSTH +JITCOMP = $B7F0 ; JIT VARS AT THE END OF INTER +JITCODE = $B7F2 ;* ;* SOS ;* @@ -49,10 +51,6 @@ SEGSTART = $2000 !WORD SEGSTART !WORD SEGEND-SEGSTART -; +SOS $40, SEGREQ ; ALLOCATE SEG 1 AND MAP IT -; BNE FAIL ; PRHEX -; LDA #$00 -; STA MEMBANK LDY #$0F ; INSTALL PAGE 0 FETCHOP ROUTINE LDA #$00 - LDX PAGE0,Y @@ -65,15 +63,8 @@ SEGSTART = $2000 STA TMPX ; CLEAR ALL EXTENDED POINTERS STA SRCX STA DSTX - STA PPX ; INIT FRAME & POOL POINTERS + STA PPX STA IFPX - LDA #$00 - STA PPL - STA IFPL - LDA #$A0 - STA PPH - STA IFPH - !IF 1 { LDA #VMCORE @@ -91,7 +82,16 @@ SEGSTART = $2000 LDA DSTH CMP #$B8 BNE - -} + LDA #$00 ; INIT JIT, FRAME & POOL POINTERS + STA JITCOMP + STA JITCOMP+1 + STA JITCODE + STA PPL + STA IFPL + LDA #$90 ; RESERVE 4K FOR JITCODE + STA JITCODE+1 + STA PPH + STA IFPH LDX #$FF ; INIT STACK POINTER TXS LDX #ESTKSZ/2 ; INIT EVAL STACK INDEX @@ -230,7 +230,6 @@ RUNJIT LDA JITCOMP PLA STA TMPL JMP JMPTMP ; RE-CALL ORIGINAL DEF ENTRY -JITCOMP !WORD 0 ;* ;* INTERNAL DIVIDE ALGORITHM ;* @@ -1432,5 +1431,6 @@ NATV TYA ; FLATTEN IP JMP JMPTMP SOSCMD = * !SOURCE "vmsrc/apple/sossys.a" + } SEGEND = * diff --git a/src/vmsrc/apple/soscmd.pla b/src/vmsrc/apple/soscmd.pla index 0700d98..e0b5dac 100755 --- a/src/vmsrc/apple/soscmd.pla +++ b/src/vmsrc/apple/soscmd.pla @@ -14,46 +14,39 @@ struc t_defentry byte bytecodesize end // -// JIT compiler constants +// JIT compiler values // -const jitcomp = $03E2 +const jitcomp = $B7F0 +const jitcodeptr = $B7F2 const codemax = $A000 +word interpentry // // AUX bytecode interpreter entrypoint // -word jitcodeptr -word codeptr -word interpentry // // COPY FROM EXT MEM TO MAIN MEM. // // XMEMCPY(DST, XSRC, SIZE) // -asm defcpy(dst,defentry)#0 +asm xmemcpy(dst, src, srcx, size)#0 !SOURCE "vmsrc/plvmzp.inc" XPAGE = $1600 SRCX = XPAGE+SRCH DSTX = XPAGE+DSTH -//asm memxcpy(dst,src,size)#0 LDA ESTKL,X ORA ESTKH,X BEQ CPYXMEX - LDY #$00 + LDA ESTKL+3,X STY DSTL - LDA ESTKH+2,X - CLC - ADC #$60 + LDA ESTKH+3,X STA DSTH LDA ESTKL+2,X - CLC - ADC #$7F - STA DSTX - LDA ESTKL+1,X STA SRCL - LDA ESTKH+1,X + LDA ESTKH+2,X STA SRCH - INC ESTKH,X + LDA ESTKL+1,X + STA SRCX CPYXLP LDA (SRC),Y STA (DST),Y INY @@ -65,12 +58,16 @@ CPYXLP LDA (SRC),Y DEC ESTKH,X BNE CPYXLP LDA #$00 - STA DSTX + STA SRCX CPYXMEX INX + INX INX INX RTS end +def defcpy(dst, defentry)#0 + xmemcpy(dst, defentry=>bytecodeaddr, defentry->bytecodexbyte, defentry->bytecodesize) +end include "libsrc/jitcore.pla" // // SOS routines @@ -316,5 +313,7 @@ cmdsys:cmdparser = @shell // // Install JIT compiler // +puts("JITC 1.0\n") cmdsys:jitc = @compiler +interpentry = compiler:interpaddr done diff --git a/src/vmsrc/apple/sossys.pla b/src/vmsrc/apple/sossys.pla index 1d4ac94..10d338f 100755 --- a/src/vmsrc/apple/sossys.pla +++ b/src/vmsrc/apple/sossys.pla @@ -17,6 +17,17 @@ const resxhgr2 = $0080 const modkeep = $2000 const modinitkeep = $4000 // +// Indirect interpreter DEFinition entrypoint +// +struc t_defentry + byte interpjsr + word interpaddr + word bytecodeaddr + byte bytecodexbyte + byte callcount + byte bytecodesize +end +// // Pedefined functions. // predef syscall(cmd,params)#1, call(addr,areg,xreg,yreg,status)#1 @@ -449,6 +460,14 @@ asm interp()#1 STA ESTKH,X RTS end +asm jitinterp()#1 + DEX + LDA #JITINTRP + STA ESTKH,X + RTS +end // // A DCI string is one that has the high bit set for every character except the last. // More efficient than C or Pascal strings. @@ -662,7 +681,7 @@ end // if deftbl=>3 == addr // return deftbl // fin -// deftbl = deftbl + 6 +// deftbl = deftbl + t_defentry // loop // return 0 //end @@ -689,7 +708,7 @@ asm lookupdef(addr, deftbl)#1 LDA SRCH STA ESTKH,X RTS -+ LDA #$06 ++ LDA #$08 ; T_DEFENTRY CLC ADC SRCL STA SRCL @@ -1014,18 +1033,28 @@ def lookupextern(esd, index)#1 fin return 0 end -def adddef(ext, addr, deflast)#1 - word defentry +def adddef(isfirst, ext, addr, deflast)#1 + word preventry, defentry, defsize defentry = *deflast - *deflast = defentry + 6 - defentry->0 = $20 - defentry=>1 = interp - defentry=>3 = addr - defentry=>5 = ext // ext is byte, so this nulls out next entry + *deflast = defentry + t_defentry + if not isfirst + preventry = defentry - t_defentry + defsize = addr - preventry=>bytecodeaddr + if *jitcomp and defsize <= jitsize + preventry=>interpaddr = jitinterp // JSR JITINTRP + preventry->callcount = jitcount // Set JIT countdown + preventry->bytecodesize = defsize // Set size + fin + fin + defentry->interpjsr = $20 + defentry=>interpaddr = interp + defentry=>bytecodeaddr = addr + defentry->bytecodexbyte = ext + defentry->t_defentry = 0 return defentry end def loadmod(mod)#1 - word refnum, rdlen, modsize, bytecode, codefix, defofst, defcnt, init, fixup + word refnum[], deffirst, rdlen, modsize, bytecode, codefix, defofst, defcnt, init, fixup word addr, defaddr, modaddr, modfix, modofst, modend word deftbl, deflast, codeseg word moddep, rld, esd, sym @@ -1149,11 +1178,13 @@ def loadmod(mod)#1 // // Run through the DeFinition Dictionary. // + deffirst = 1 while ^rld == $02 // // This is a bytcode def entry - add it to the def directory. // - adddef(defext, rld=>1 + defofst, @deflast) + adddef(deffirst, defext, rld=>1 + defofst, @deflast) + deffirst = 0 rld = rld + 4 loop // @@ -1231,7 +1262,7 @@ def loadmod(mod)#1 // fixup = 0 if init - fixup = adddef(defext, init + defofst, @deflast)() + fixup = adddef(deffirst, defext, init + defofst, @deflast)() if fixup < 0 perr = -fixup fin From 77ca9b2813057fe0b1ea7717a2485341da162883 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Mon, 2 Apr 2018 09:17:18 -0700 Subject: [PATCH 125/147] Re-org some JIT <-> CMDSYS <-> VM connections --- src/inc/cmdsys.plh | 3 +-- src/libsrc/apple/jit.pla | 2 ++ src/vmsrc/apple/cmdjit.pla | 6 +++--- src/vmsrc/apple/soscmd.pla | 6 ++++-- src/vmsrc/apple/sossys.pla | 7 +++---- 5 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/inc/cmdsys.plh b/src/inc/cmdsys.plh index 7b311df..e476d19 100644 --- a/src/inc/cmdsys.plh +++ b/src/inc/cmdsys.plh @@ -55,8 +55,7 @@ import cmdsys byte jitsize byte refcons // Apple /// specific byte devcons // Apple /// specific - word jitc - word cmdparser + word cmdparser // Apple /// specific end // // CMD exported functions diff --git a/src/libsrc/apple/jit.pla b/src/libsrc/apple/jit.pla index 6191d58..42e0898 100644 --- a/src/libsrc/apple/jit.pla +++ b/src/libsrc/apple/jit.pla @@ -46,5 +46,7 @@ if *jitcomp fin puts("JITC 1.0\n") *jitcomp = @compiler +cmdsys.jitcount = 44 +cmdsys.jitsize = 96 return modkeep done diff --git a/src/vmsrc/apple/cmdjit.pla b/src/vmsrc/apple/cmdjit.pla index 74ff408..8e1ca57 100755 --- a/src/vmsrc/apple/cmdjit.pla +++ b/src/vmsrc/apple/cmdjit.pla @@ -58,8 +58,8 @@ word syspath word syscmdln word = @execmod, @open, @close, @read, 0 // Mark write() as NULL byte perr -byte jitcount = 44 -byte jitsize = 96 +byte jitcount = 0 +byte jitsize = 0 // // Working input buffer overlayed with strings table // @@ -1029,7 +1029,7 @@ def adddef(isfirst, addr, deflast)#1 if not isfirst preventry = defentry - t_defentry defsize = addr - preventry=>bytecodeaddr - if *jitcomp and defsize <= jitsize + if defsize <= jitsize // and *jitcomp preventry=>interpaddr = $03D6 // JSR $03D6 (JIT INTERP) preventry->callcount = jitcount // Set JIT countdown preventry->bytecodesize = defsize // Set size diff --git a/src/vmsrc/apple/soscmd.pla b/src/vmsrc/apple/soscmd.pla index e0b5dac..dc3bcca 100755 --- a/src/vmsrc/apple/soscmd.pla +++ b/src/vmsrc/apple/soscmd.pla @@ -314,6 +314,8 @@ cmdsys:cmdparser = @shell // Install JIT compiler // puts("JITC 1.0\n") -cmdsys:jitc = @compiler -interpentry = compiler:interpaddr +interpentry = compiler:interpaddr +*jitcomp = @compiler +cmdsys.jitcount = 44 +cmdsys.jitsize = 96 done diff --git a/src/vmsrc/apple/sossys.pla b/src/vmsrc/apple/sossys.pla index 10d338f..077efc6 100755 --- a/src/vmsrc/apple/sossys.pla +++ b/src/vmsrc/apple/sossys.pla @@ -45,11 +45,10 @@ word syspath word cmdlnptr word = @execmod, @open, @close, @read, @write byte perr -byte jitcount = 45 -byte jitsize = 96 +byte jitcount = 0 +byte jitsize = 0 byte refcons = 0 byte devcons = 0 -word jitcomp = 0 word cmdparser // // String pool. @@ -1040,7 +1039,7 @@ def adddef(isfirst, ext, addr, deflast)#1 if not isfirst preventry = defentry - t_defentry defsize = addr - preventry=>bytecodeaddr - if *jitcomp and defsize <= jitsize + if defsize <= jitsize // and *jitcomp preventry=>interpaddr = jitinterp // JSR JITINTRP preventry->callcount = jitcount // Set JIT countdown preventry->bytecodesize = defsize // Set size From e5e43f58b757b2cc0960ba14f0626b8e151e8bbb Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Mon, 2 Apr 2018 10:02:17 -0700 Subject: [PATCH 126/147] Save/Restore JIT code ptr --- src/vmsrc/apple/sossys.pla | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/vmsrc/apple/sossys.pla b/src/vmsrc/apple/sossys.pla index 077efc6..3042737 100755 --- a/src/vmsrc/apple/sossys.pla +++ b/src/vmsrc/apple/sossys.pla @@ -28,6 +28,12 @@ struc t_defentry byte bytecodesize end // +// JIT compiler values +// +const jitcomp = $B7F0 +const jitcodeptr = $B7F2 +const codemax = $A000 +// // Pedefined functions. // predef syscall(cmd,params)#1, call(addr,areg,xreg,yreg,status)#1 @@ -1270,16 +1276,18 @@ def loadmod(mod)#1 end def execmod(modfile)#1 byte moddci[17] - word saveheap, savesym, saveflags + word saveheap, savesym, saveflags, savejit perr = 1 if stodci(modfile, @moddci) - saveheap = heap - savesym = lastsym - saveflags = systemflags + saveheap = heap + savesym = lastsym + saveflags = systemflags + savejit = *jitcodeptr if loadmod(@moddci) < modkeep - lastsym = savesym - heap = saveheap + lastsym = savesym + heap = saveheap + *jitcodeptr = savejit while modid modid-- seg_release(modseg[modid]) From 58eb6151768abe99d5d7b5df1025bb04b491b9e6 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Mon, 2 Apr 2018 10:17:33 -0700 Subject: [PATCH 127/147] Remove JITC puts from JIT module --- PLASMA-BLD2.PO | Bin 143360 -> 143360 bytes PLASMA-DEM2.PO | Bin 143360 -> 143360 bytes PLASMA-SYS2.PO | Bin 143360 -> 143360 bytes src/libsrc/apple/jit.pla | 4 +--- src/vmsrc/apple/cmdjit.pla | 2 +- src/vmsrc/apple/soscmd.pla | 1 - src/vmsrc/apple/sossys.pla | 2 +- 7 files changed, 3 insertions(+), 6 deletions(-) diff --git a/PLASMA-BLD2.PO b/PLASMA-BLD2.PO index 8a4638906b5ba879aa9072a1548fbd408888518c..416b2581ebc825583c11a28adbc2bac4ffb36bac 100644 GIT binary patch delta 3435 zcmZXW4OElY8OQIvybuJV3_%GXL{UBr5R_`2n#2G}h)qaHq7`SI5u!$;U{I@`tufo` zK5BPPmP-6s)y6KmuEj3#fQNH*o1U%bY-_ttXE$q|R#&U7R%@|}CGP(w0`X1G`Q<)& z?*Bf|`#ksNCfhHiZ@-lOwv6+X)teeLCbNw^enr!Xh`f|Zel#ULql8=`F@q6VgU({p zSZ&p2gPK=zV+lvBsY2N_t=d+v9##=<9Aq|5D4VF&*J)z${OeLhp7Df|HB=~)>9mU* zG)B{K$~=-nDpQ0qNu$PK7#88l@)2!T{J9efsBF|(rYBUu6_PaaVLBhplUQg)qs?Y+ z7|MxolgSuzPa@2EM&DFF)G~e?D<=%%m@Af*x6n4D#+Zb=k@ zliDn|m~;y@)%7N0U2K23S4jprm?aEX6_**+=6GK2Fp-hN7NM*nE{h)~4{G85NeYOl zR;ZI%%uV%bL;Y|OH_14%vqUJXuBrs zOu_}K`lvWkI_5l0$ohQ#L^YXOxDHQ`Yk)m9U89;x(FDFtMmu ziiw9b{7G7RB<<7y6;CReGPSg74AINad| z=$ewU7A!Ee)Gb`HWJt+rAZtjfwZLF%(k(FZU#eI@P77JflQNbek3?5xut@r{`;?nr z`_xRFjBjap#UPuw#<{Vzebf4lV(H`8ime+RQg}O^+Z_Hc+Z%G}CA@H(RW>g^QkDjLCi) zoRt$aFxK+DxYW$TOL=MD1InKJe#{pxFE0kqQ z<}(K&(Qyv4A(Hu3Kh0UW+PP+}Yu)FL)8W40eNk-~c!b-T)EM z15Sc-;5xVq#Pf)^a31k^i(yOw6+jMV0tHY59e4& zKZkE8@c8l81?L`29)x`eb_n)cuzwGZfj)2oyaV0^AAqyqJhWG#{S5Xk*!{|4?*PU@ zj8uirs)$dlD)wf>&INg(06wW|jJE`1sS5jF0cRDc0Z+j>7n4eiYSm<~4!#AjjjCdw zL&bSlZYg0R!Tb^8!DwP$9ge;y9eIsrV$%lQiXK2 z!`@+cx!POHW7cN7(ubKDMlTe;h@@^MIh(K@?(E!H4j zMPT!BS|Z||?ylXj3!}{8a@ac^<$N|7{{$m(*KO)_wwhh`t^8!*{83uk6Q&Uw{DQGP z`{FmyZ5Hfiqkg^rz`@sohhF~;oZrxJI4!F;t&a}SjL?zazVW*^-|9a4c7QIY6477( z_V;(+d;cGhoufS`so3IIo|XjW^wG@T>C5Q*H2;G$Xa9BX!+-zh{6`l)zWCoump{33 z^?#pU`|SFS&#~rH8d^bT1b@b|zqs|~?K@xH{ks3&H}@Y5Jp6Vris@T4yi+o{SCYrB zQTixA3)rJWRsA$n$XKY0vJA$hris$|KYV`5?xoS#tE-d^g!a;Eo1UD*Ht delta 3354 zcmZvd3w%@69mmf(xlPif!9FN7eLzPGZPQX(P$-W!q-j!uNfVM3TSTyh0+pxb;b35h z4&)`0MhH3tO<7bF#&TVQZlZt>hN!SHVdxl+DU+>CWIS4E>+dF}Ey?ovd~^Qye}4CW z&i{WNckM;#+KbYI`P@*IUSrp4?1dJih6q1SN;qQY$m7|vge-E21PymxOp-%R7`pKs z7w(8lU?ktJv)PS?@^ApIjEG1KyZ3#_OgfXG?2%~@YGO>3%xbC9YK+<*nT{lpEm?xh z5gt{BQAb$KmDRdJt=Uu_oI6)TWaQ=e$Z&a+>~>2#V&(ZaJakF?z3#ksPbJ&zKnX36!Kv6e$~ulG{wdq6h!FR*@nS zKb<_8Ems69FBpiXHCO1&7P}*??0TI@$Yyz@4y(hFyii@ji%GbHB#lT$MGigCWUlJ1 z3TAi$iNr=FlG~dqA;S3FNg^kTq{wi}Njjs^+#8Vl0^vr7wocC;!XCi1YHhkHVIg-8 zby*g@RVwv06*^N-Jnl=#3Pg^`QHO_eHEArNfZPR=PhPb~%JM5J`z#r9h@~8{MeV#i zn?W~K7oHkq3MwKKS#Om&VLA9Z$sVycn~5Z`GM=(d>doa)m^^aHP^AqokkBsABFAzR zLJ5S^0<%BXN0gIqvluL9t8fe^2{KNB+}?^Pft;in%~h3?O+sQJ*?lNzZA3xkL>b(V zj<5>h;-TCAe{>d`-P%W%0NHmD%Pl7=i*c%Hnx!zD3YUb*S)(SGVyM#fB!CxRC1DQ(^Lt| z7!(N=P9<^VTJpWSLQYaEts1?drboyPMY#1*qvqKva6k5_2$zGB%)0j|vjjQc^)_QH zt{=8U7xf>OFkZ5yoi;bc^07<0DKA}hn|hlWOY9#Mcy}=W20^o}o%$CE#`_(Vr!RI> zxiT$1W6h-$B{1+|cW-40kahD!sv|GYH2dlq;8y3t(@= z&5cZLRTZH__miv;nWjW#s?wS&Y_+!DXhkH3G)p4umZGs%+6o=vF;U<95pGoUmeZQ6 z`pk`R4?uPxYSbLPrMhQGVYS9!)V8QmQ-w3rCtN8v9^tk|jhZ&uTw7i}ZCW@aHvzJW zNST|m54}xHq$(JWf_75>3JKRDIfQknZ>QXd;*q1^zDxacI+;7S@u30rE0;B7&RRHo zNnO*@h9*TOehrIeyW8fb^T!)Ym^+@8H`hye$)l9<(gj#=$!f$IT{3oDD9&1mxJ9xP z;WxEYUn(|AsTv(!)HjGR?@=b2SgsAu!}}5EJ4ab!g}!oTDlDGJJdf;Eak-onanfJNacazkqFCH{2YCl-Dt|> zu@hMXAzeugq>h)Lyg>_B{$ll-Cmm~@Pd)w1b?cwmuyNDoEzfR!Zkwyw{rvVFo}Dke z_^Vwn?cVe9E8dp9zxKWAq3NvKJ@3>q)aW?hc1NJaOiNQD8jKgUMhD zs0KCQ5l{~rz(TMJtN~AfbzmcKfn8t^XaR4410Vq20Y|}k&<1XSgbBo%Ie|EwSuk?J za4-st1sb3O4+1lo3TnY@Fc-`ROTlLF9C!ij0bcMX@Pk9(FgOA}2A_g2!3FR&xB{+D za9}nt?gCayoKg@65XP`X?`vUB5$_6{Hplw5Y4Zd5jJ7F_5k^)j7R})vf zx}P%%?Ep2_UkPUh$OPGN=A*L^ZLxZYa}0drV3(=~yQICG(R^lWY?{zYg~|<=Q%r^W_wbLs7%(Y z@Z=QHVeIT*gLh28RD=&7E(ephkg@Y$1)biJ%x9!b^|!xY{Q4i4{`t+fm;d$Mm4E-I z?dpHOzxKoR|J}HG>vns`ox7b~-Gnj`7bBLqDZ9Nx!lWK<82h5tLKRkCk$#h7J diff --git a/PLASMA-DEM2.PO b/PLASMA-DEM2.PO index 0c09af3fa0f8abf96c48814460b09ab979b0bcf1..2c4c1b3a82b93422f7c28fcb24a0eef7dfcce932 100644 GIT binary patch delta 1811 zcmZvcTTmNi6vxl^WkUjlWLu!2w54DOi3Cz8f)ueOmjwbFlIGTcC^w5Vf<>i@v>MXV z7EzIORlHU0cA6QTamFEI`{Fp$@zED&v|5Lk&h*6xeX%;zGB)*OL%5`5a`K%$`^!1s z_djQM`j&F~mhu}D6aLlWcJo{vq(2%35CAG&>fm-NOhIdJ^Y}QgFO4M*A@&!6)8)z> z2}?Q@ZaDp3hb;{OXj-<+_H!4vnkk%OHNh>pe2>e%o(v$-huHClt9o2*er_Gq^lzEX z;Bj}^Ed1K`5^sXC5ytW|5AmDV?)N!(Z#to7VT*L}0r_R6z|0o)CNUlSV928=8#Pp> z1U0)IK`B92HZ%Y^wpN5qDy0BzTWiqHIbG=@iGx@qoN+WooX}Y!&e3{hPOd6Xtzoxq z&o3z4p)J~3yleNKlD(y6kLb$v6$ay@m8Pm{^S+we{dJGkH$2{Wpy`R`C-L7u5^+AX zbdI3{qb`!fmbNOxtuh9!o40g(xx;IFu;3o9WbB~@s=Pjn$LHZX%_%m^1}dm7+if9ZN`02(kHasXUUg6K?{KaYqDHK+k zzmAjg2PD^O=UUs^9UYy#6Q%i=h{ghurP*EX!yd2CA2@=+dn8T^9%uwIyleBc$qo8; zpU=JF8A5LNQw76I6CQgDHuJ6pi@Ra!^RzN5n7(zcm zVnu|;D51({ho2ic7J7aZqjyOxi>PA_7#%x4{^Cn7Pn?jVSDVN|<)YO}O3CQ8J}bE- zS1mKixt`cAgWn6{s+E6;?3Kya5WY{A63diA@3+fDM`Fc<=1rY?{f+Q+&;+zE(N@rg zwLq7(@uBcVCe^ot8GXw(RJ2-rwv>31IEf3`x9b^wTYx0imVQwug?=A}{yszK6z29z ztw?422r)0SLFi=P7N8Q-c{q#R?(Ix*7m@q!p>!t1j(8kCZk0=1+NvsQlTXAJN}~e0 z2_o7V*?S)>qJN)=9gG;DvJXH0Bz4)7CHwTV&r|*&BX&{Q7vg2c{ zix73RG%X2p1_NClw}5HKQfTEtFu;BjCd*ySnww9dFzDwp>6BKaJ4m!JE7u+r`A|Bu z;z8K&|AT$+4g>_gDNShMfNWTz)=NQudzeqdz%sH#5s97pj|>tsUNV;I)R#_^4%X^cvjAasZ%$mw~KW5~@jn#>k9AJ=Y^1U)-%NswdnB(I>Tc$u|i`HIq&t1$F8 zk*A9CrhyIv*jWlLDQ{w>r@9WCIEaS7qm^u=lHDQr0f$H~^o-hAp%x-GHWiPUp{D`8 zh!ICzsz75Mc4>OT)@^4YRs}Rx1FK^7P!?Sa5N$?l0f=pZ@+h8s)QfWgj4?m3u^_JX zqCWuTvF*6F3+&N7=tsaAI{=Q@aj9&wQtF@lL}KZ-8K#0{v|W#F*Et<+Zqeh$Ei8OW zCFtOys^bhrm4gav&(Nr{1{k=Y*TP%~>kWEEo(pxVgi4hb7DV0@T_Bv1wFYq^MoU+X zbV1(DEwF*ofUwWBS@Bc~NqjY-v|=^R6%uz4MrX4-(78+EHH3+8B~<6UuR0k$*+NWn zW{%v@#T#(hRa=+Bts_~w`o^^>r-d-sGDc#~l?LC~R;Mm^UBKIy+-6oAtOv3;T}|@ZabRt4>*IKzKZ#Kf_Ia#kOj8Y)s)nV_ ze0zuYp-#cqY~QhSXxF2|yZ1b{H}d$t{Ra*nI{d_wN1l56 znP;CnivRwG$VHJ8<9bQ|x%J)yp(-`U=}JB?9>1?OC0At>#qg&_3?twW_#R$pT-+!y z6OaQsOS+)sWD(YI5B3V`eq*NYRi%zVRWhs39aumruY(ybF4xl8HE*AC8ne!6vtosX z#P}nlJ|0I3C{iYjzuhFd7skdhbeGKjafK#+zF{K?k9)D@-WsKb-^0#LB z3reS7MNc8}S5&@9O|QN2X6%IY*4rm%-g);u4E#mpTP5;OH0#v+XFfRl;T<cgXB7 Xn+>{s1t4v@UYQuWenubfAiw?#2@Y&< diff --git a/PLASMA-SYS2.PO b/PLASMA-SYS2.PO index 64d76181c2e5c66bd05f82088eb7fb19acbdc37d..ae737c2fb856c5444d399e6c2af52570557231f5 100644 GIT binary patch delta 2881 zcmZWq3sh6*9shs-+=QC|;U+u;K}C7fsOVak_1GN|0%CbY5;mo-6_vZ{@G)$oWzHCD z?L$sa(@dk*wez;;?%3lwcp6vQt>d({x<2SosjV=(f{O0ZiMn+%A2<8w#y|+)Iro0A z-}n1JzyG&=fZsmAAH9#u%PFfVhp49G!2kvU%5%*^4qOCbM=o#h*}0{UJ^K}8x4}0Km(vtmqO~P4a1%K53JMrc-f372`Hzb zAk8rDRoFCk(x0ucyo^~>K}DaQvLJO;>ekfo$xlCV`s>Wt?Jo|pFQvKoHe!>`G#fJnR z)A>dcE=S+pL~|gidTT<_EHvH(vOT$}c zLB7gRx9pMSKY8@A0PDKNu&wpH6|9J9*m%55sATelNT0Ao1y8Z|+I&AG@{Uo|RN*+UuH z&BxN^Ra7mskr|Puyh6$yoSj9Q{B8F%60cu*ylY^GIvxx-5X>C z%ovq=Pr1AbyTchR^=*>+?gXhh750XRVxeC7JzZP9Fv=DhprI+C>_?PeWXP>*7Jo{~ za)-$;Go4&WE03@JSxb1u!gSIR)U4aEk>)`bz@v&rx`w8oZ+hZM*XAuxwf$o2FSoh3 zdv*j&H-@MC1mrro3U-I-pMGZ7v(G*M!tVA?md*@QNR0#_x{+`$+j}$p2q}t6KGj}WqoNy)zVRaC@08gXSL&;LCKq2RcjlooaD1l zs5qU~#KLl->uboh-4v*Su`E*YO^`;ghFW(x)zlDtO;_d`i=~^ixNh0PhQ`K-cFJD~ zwr;}Bnp9m^Te-MqEGfSs*fSGg`8Bqhn$YFC*WAh=1%BH2z>}?M_PTm!bXNY8=n5w& zm+L649kYOJ{TE$@L4B+Zd5-dm(kRy{|0d66g*-Pt$MYSv_Zl0 z55{L>Gk{s(V0iZN&p+zzBl$}?6pQmK^nP*n%dgJ$_5bBO2^wblqi{}n3%*c}`GP&Jlt-tC z{9A?B?{`MRnsb(YY9z9ty(&4)zN99IvkpZj>fsr(mY5smObxB z4yl}+3*m`0`_{=~K;QcT$E?23zVgt&qd&tZp7YXZIW`d9J+kvZ-4&>WgJ!8ZYqf%)7B}LAn#)+y^7jzuMS_kPP@06B=ORFh&TR2Glfa- zqkNtr|J}`z|J}NM=PoUdFnNF(rCMal>kOH1!_!l#4i8HEP~Js_muWa36>JS-EY!;{ zFm6fcS`;>f9?!8ts>IQy%$e{$6-8ik!?#z7XL?u@TM0;w4kovfI32GaC(cE-rIEsh bghXSKU^3I@$lg@s{dyY6lbKP@N5lUC;xg^k delta 2849 zcmZWr4Oo-c6+Y+YhY)@Y{~#bS1Q3jfK5Efn1tCB*KqO&Pq#G(kK~PMUt=NjOt#vJH zjcG~i@6)gJ+v6jh)>zXY=h}&#T3zkHzs@OQbzQfiUFT}6e(WTH5a4^BFZbr$_rB-e zbI*Oxx4BogxmR{*vN&amL7!(V$;&h@F`Bd`00T0RLy-cesuMz!;U>T)bx?@iAWql2 zkqdODVPqU3k0@ZhIwshMWYA4a;P;GEfe1iKJkcS8u;>u`NpX7XRIlr4vj!;#?t=`r z2Ez>XoN<1Hsre-ZWTMfq$h`6*Bar{0M<@Y=liu_2ql>1{ zRFrCmP#}~N>@JR`QycUAKmdY)j^sw*XjsgGvL*8?Dl3QRT7?RtYaHWMT~M5F7y?l% z{EYT`S3H_7rBF9tTRw~vmJ)3DSeUV(FmL#PLHGrQB*7h$)}W!B2?|j`YN1ZA)s^}9 zgykTCxdEfSCi`cLdvPlv9D0#`{!DZnv^aw}5ysEB# zbwlHtwN2|RPp;q4{7Z6m2OaXAxFIq#(JVVGuWpFULA?gd%&ahlJ9^*2SjT~#*cmW0 zp(e8YyYY_RJ(%d&xC;~5y?Do34x`1{jDXHvxD6LMa(3erj8Oe=V|rG`{+cMo&MjtU z$%r+xY}TZy?WI;^(Y$uvtniFvODq}t$rfPI)ZTEs;lu=2?jGzCW4J@Yp_LlX3iffh zgZk6o!tNo{gbrLv{gw_)A2J>5K+Ry^g>T~lsoy}b>x%;z%Dk30sk!DqO!c31;8UfX>?*=yvTo ziVLyzvp&sLkr~=7l`-{wB7Hh!Dk&kAE7mqP)iu;wl*<|{waaRrQr4|`a{aP~hT58m zA@1C-%8b={Ep=;Fj+o&dPSq<~`a~K~R^fpC+^{ptdYNNrL z8w1vMdUwQvH8c*a`{Ka%+oX8gwIs3aQIgmSN`UhhdW;IOYw!EG9PJ7g%=NLbU$ty} z`k76wo2^@(eeU_KFKqj@GwiE76I)f#2k8~2Vr_Y;)-;`VNsrJ5flwDZ`Z^{T6!|Fy z!Cs@woi+Ay7aA(OJl@C@J}6rGBai!YPVekUMfCWue@8CVsWu@j4kEBG)73Ey$#A?ApC&?>-kkjz1#bj0(ywu}dt)huB_>3WDB6 zUXBy^dXmp0M_ptfL0&`hd7LCOm{j_MkB)hbG?AY~V*L9*eEi8D$wXqTAu*<5^gefz?--K{`Eh;`RBj>P3G^B@1iZA!C?LyWU~Id-~Q*j|K9r_jZkF!F_b&Z z0>1y@#|IA|31s^Lxud~5vXbz$U73{7aLT5Ov0%e9iw=)pxMM_P7 zf37~BFs8PIRT8Bcs@sb7L7-oDl(J;f)xs+hKl9*+h?R+z@igBTg1qL}V VnhEVOOy&rPVfVRk1)s{~{|6Ti+k5~3 diff --git a/src/libsrc/apple/jit.pla b/src/libsrc/apple/jit.pla index 42e0898..8b813b2 100644 --- a/src/libsrc/apple/jit.pla +++ b/src/libsrc/apple/jit.pla @@ -41,11 +41,9 @@ include "libsrc/jitcore.pla" // Install JIT compiler // if *jitcomp - //puts("JIT compiler already installed!\n") return 0 fin -puts("JITC 1.0\n") -*jitcomp = @compiler +*jitcomp = @compiler cmdsys.jitcount = 44 cmdsys.jitsize = 96 return modkeep diff --git a/src/vmsrc/apple/cmdjit.pla b/src/vmsrc/apple/cmdjit.pla index 8e1ca57..88ed673 100755 --- a/src/vmsrc/apple/cmdjit.pla +++ b/src/vmsrc/apple/cmdjit.pla @@ -1411,7 +1411,7 @@ heap = *freemem // // Print PLASMA version // -prstr("PLASMA 2.0 Dev\n")//; prbyte(version.1); cout('.'); prbyte(version.0); crout +prstr("PLASMA JITC 2.0 Dev\n")//; prbyte(version.1); cout('.'); prbyte(version.0); crout // // Init symbol table. // diff --git a/src/vmsrc/apple/soscmd.pla b/src/vmsrc/apple/soscmd.pla index dc3bcca..7f445ed 100755 --- a/src/vmsrc/apple/soscmd.pla +++ b/src/vmsrc/apple/soscmd.pla @@ -313,7 +313,6 @@ cmdsys:cmdparser = @shell // // Install JIT compiler // -puts("JITC 1.0\n") interpentry = compiler:interpaddr *jitcomp = @compiler cmdsys.jitcount = 44 diff --git a/src/vmsrc/apple/sossys.pla b/src/vmsrc/apple/sossys.pla index 3042737..3ead0ed 100755 --- a/src/vmsrc/apple/sossys.pla +++ b/src/vmsrc/apple/sossys.pla @@ -1321,7 +1321,7 @@ cmdlnptr = @cmdln // Print PLASMA version // init_cons -prstr("PLASMA 2.0 Dev\n")//; putb(version.1); putc('.'); putb(version.0); putln +prstr("PLASMA JITC 2.0 Dev\n")//; putb(version.1); putc('.'); putb(version.0); putln prstr("MEM:$"); prword(availheap); crout // // Exec command line parser From d0215eb7e158d966f6b6e678a195d48dd6bb5412 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Mon, 2 Apr 2018 12:36:44 -0700 Subject: [PATCH 128/147] Allocate proper size for defentries --- src/vmsrc/apple/plvm03.s | 10 ++++++++-- src/vmsrc/apple/soscmd.pla | 2 +- src/vmsrc/apple/sossys.pla | 6 +++--- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/vmsrc/apple/plvm03.s b/src/vmsrc/apple/plvm03.s index 144e399..1363f81 100755 --- a/src/vmsrc/apple/plvm03.s +++ b/src/vmsrc/apple/plvm03.s @@ -192,7 +192,7 @@ JITINTRP PLA PLA SBC #$00 STA TMPH - LDY #$05 + LDY #$06 LDA (TMP),Y ; DEC JIT COUNT SEC SBC #$01 @@ -200,6 +200,9 @@ JITINTRP PLA BEQ RUNJIT DEY ; INTERP BYTECODE AS USUAL LDA (TMP),Y + STA IPX + DEY + LDA (TMP),Y STA IPH DEY LDA (TMP),Y @@ -210,7 +213,10 @@ RUNJIT LDA JITCOMP STA SRCL LDA JITCOMP+1 STA SRCH - DEY ; LDY #$04 + DEY ; LDY #$05 + LDA (SRC),Y + STA IPX + DEY LDA (SRC),Y STA IPH DEY diff --git a/src/vmsrc/apple/soscmd.pla b/src/vmsrc/apple/soscmd.pla index 7f445ed..14827bb 100755 --- a/src/vmsrc/apple/soscmd.pla +++ b/src/vmsrc/apple/soscmd.pla @@ -316,5 +316,5 @@ cmdsys:cmdparser = @shell interpentry = compiler:interpaddr *jitcomp = @compiler cmdsys.jitcount = 44 -cmdsys.jitsize = 96 +//cmdsys.jitsize = 96 done diff --git a/src/vmsrc/apple/sossys.pla b/src/vmsrc/apple/sossys.pla index 3ead0ed..03739ec 100755 --- a/src/vmsrc/apple/sossys.pla +++ b/src/vmsrc/apple/sossys.pla @@ -457,7 +457,7 @@ end // // Addresses of internal routines. // -asm interp()#1 +asm xinterp()#1 DEX LDA #interpjsr = $20 - defentry=>interpaddr = interp + defentry=>interpaddr = xinterp defentry=>bytecodeaddr = addr defentry->bytecodexbyte = ext defentry->t_defentry = 0 @@ -1120,7 +1120,7 @@ def loadmod(mod)#1 // // Init def table. // - deftbl = allocheap(defcnt * 6 + 1) + deftbl = allocheap(defcnt * t_defentry + 1) deflast = deftbl ^deflast = 0 if !refnum From 9e4f9936afd21de90b7fa7958ef20a44f87d2427 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Mon, 2 Apr 2018 13:51:04 -0700 Subject: [PATCH 129/147] Cleanup --- src/libsrc/apple/jit.pla | 5 +++-- src/libsrc/jitcore.pla | 46 +++++++++++++++++++------------------- src/makefile | 4 ++-- src/vmsrc/apple/soscmd.pla | 19 ++++++++-------- 4 files changed, 37 insertions(+), 37 deletions(-) diff --git a/src/libsrc/apple/jit.pla b/src/libsrc/apple/jit.pla index 8b813b2..1cd6406 100644 --- a/src/libsrc/apple/jit.pla +++ b/src/libsrc/apple/jit.pla @@ -24,9 +24,10 @@ const jitcomp = $03E2 const jitcodeptr = $03E4 const codemax = $BEE0 // -// AUX bytecode interpreter entrypoint +// Bytecode interpreter entrypoints // -const interpentry = $03DC +const indirectentry = $03DC +const directentry = $03D0 // // // diff --git a/src/libsrc/jitcore.pla b/src/libsrc/jitcore.pla index 49983ac..3a9d381 100644 --- a/src/libsrc/jitcore.pla +++ b/src/libsrc/jitcore.pla @@ -27,13 +27,14 @@ end 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 + //puts("Not enough free heap\n") + defptr=>interpaddr = indirectentry return fin addrxlate = heapmark @@ -166,7 +167,7 @@ def compiler(defptr)#0 // Call into VM // codeptr->0 = $20 // JSR INTERP - codeptr=>1 = $3D0 + codeptr=>1 = directentry codeptr->3 = $58 // ENTER CODE codeptr=>4 = *(bytecode+1) // ENTER FRAME SIZE & ARG COUNT codeptr->6 = $C0 // NATV CODE @@ -428,7 +429,7 @@ def compiler(defptr)#0 *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - codeptr->0 = $18 // CLC + codeptr->0 = $18 // CLC codeptr=>1 = $69+(j<<8) // ADC #imm codeptr=>3 = $0290 // BCC +2 codeptr=>5 = $C0F6+(VX<<8) // INC ESTKH,X @@ -448,7 +449,7 @@ def compiler(defptr)#0 *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - codeptr->0 = $38 // SEC + codeptr->0 = $38 // SEC codeptr=>1 = $E9+(j<<8) // SBC #imm codeptr=>3 = $02B0 // BCS +2 codeptr=>5 = $C0D6+(VX<<8) // DEC ESTKH,X @@ -505,7 +506,7 @@ def compiler(defptr)#0 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=>10 = $9888 // DEY; TYA codeptr=>12 = $C094+$0100+(VX<<8) // STY ESTKH+1,X codeptr = codeptr + 14 VX++ // INX @@ -534,7 +535,7 @@ def compiler(defptr)#0 //puts("ISLE") codeptr=>10 = $0130 // BMI +1 fin - codeptr=>12 = $9888 // DEY TYA + codeptr=>12 = $9888 // DEY TYA codeptr=>14 = $C094+$0100+(VX<<8) // STY ESTKH+1,X codeptr = codeptr + 16 VX++ // INX @@ -564,7 +565,7 @@ def compiler(defptr)#0 //puts("ISGE") codeptr=>12 = $0130 // BMI +1 fin - codeptr=>14 = $9888 // DEY; TYA + codeptr=>14 = $9888 // DEY; TYA codeptr=>16 = $C094+$0100+(VX<<8) // STY ESTKH+1,X codeptr = codeptr + 18 VX++ // INX @@ -716,7 +717,7 @@ def compiler(defptr)#0 codeptr = codeptr + 2 fin codeptr->0 = $20 // JSR abs - codeptr=>1 = $03D0 // INTERP + codeptr=>1 = directentry // INTERP codeptr=>3 = $5A + (^(bytecode+i)<<8) // LEAVE CODE AND OPERAND codeptr = codeptr + 5 A_IS_TOSL = FALSE @@ -877,7 +878,7 @@ def compiler(defptr)#0 codeptr = codeptr + 2 A_IS_TOSL = TOS_CLEAN fin - if VY <> j + if VY <> j *codeptr = $A0+(j<<8) // LDY #imm codeptr = codeptr + 2 VY = j @@ -900,7 +901,7 @@ def compiler(defptr)#0 *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - if VY <> j + if VY <> j *codeptr = $A0+(j<<8) // LDY #imm codeptr = codeptr + 2 fin @@ -1066,7 +1067,7 @@ def compiler(defptr)#0 codeptr = codeptr + 2 fin codeptr->0 = $20 // JSR INTERP - codeptr=>1 = $3D0 // INTERP + codeptr=>1 = directentry // INTERP codeptr=>3 = $C000+opcode // OPCODE; NATV CODE codeptr = codeptr + 5 VY = UNKNOWN @@ -1181,7 +1182,7 @@ def compiler(defptr)#0 codeptr = codeptr + 19 A_IS_TOSL = FALSE break - is $A2 // BRLT - FOR/NEXT SPECIFIC TEST & BRANCH + is $A2 // BRLT - FOR/NEXT SPECIFIC TEST & BRANCH i++ dest = i + *(bytecode+i) //puts("BRLT "); puti(dest) @@ -1361,11 +1362,11 @@ def compiler(defptr)#0 *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - if VY <> j + if VY <> j *codeptr = $A0+(j<<8) // LDY #imm codeptr = codeptr + 2 fin - codeptr->0 = $18 // CLC + codeptr->0 = $18 // CLC codeptr=>1 = $E071 // ADC (IFP),Y if opcode == $B0 //puts("ADDLB "); puti(j) @@ -1395,7 +1396,7 @@ def compiler(defptr)#0 *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - codeptr=>0 = $6D18 // CLC; ADC abs + codeptr=>0 = $6D18 // CLC; ADC abs codeptr=>2 = dest if opcode == $B4 //puts("ADDAB $"); puth(dest) @@ -1407,7 +1408,7 @@ def compiler(defptr)#0 //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->8 = $6D // ADC abs codeptr=>9 = dest+1 codeptr=>11 = $C095+(VX<<8) // STA ESTKH,X codeptr = codeptr + 13 @@ -1422,13 +1423,13 @@ def compiler(defptr)#0 *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin - if VY <> j + if VY <> j *codeptr = $A0+(j<<8) // LDY #imm codeptr = codeptr + 2 fin *codeptr = $E0B1 // LDA (IFP),Y codeptr = codeptr + 2 - if j + if j *codeptr = $00A0 // LDY #$00 codeptr = codeptr + 2 fin @@ -1452,7 +1453,7 @@ def compiler(defptr)#0 *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin - if VY <> j + if VY <> j *codeptr = $A0+(j<<8) // LDY #imm codeptr = codeptr + 2 fin @@ -1512,7 +1513,7 @@ def compiler(defptr)#0 codeptr=>1 = dest codeptr->3 = $0A // ASL codeptr=>4 = $E785 // STA $E7:TMPL - codeptr->6 = $AD // LDA abs + codeptr->6 = $AD // LDA abs codeptr=>7 = dest+1 codeptr=>9 = $A82A // ROL; TAY codeptr=>11 = $E7A5 // LDA $E7:TMPL @@ -1549,13 +1550,12 @@ def compiler(defptr)#0 //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 + defptr=>interpaddr = indirectentry // // Free working bufffers // diff --git a/src/makefile b/src/makefile index 3c2fd58..de1131e 100755 --- a/src/makefile +++ b/src/makefile @@ -157,7 +157,7 @@ $(CMDJIT): vmsrc/apple/cmdjit.pla vmsrc/apple/cmdjitstub.s $(PLVMJIT) $(PLASM) ./$(PLASM) -AOW < vmsrc/apple/cmdjit.pla > vmsrc/apple/cmdjit.a acme --setpc 8192 -o $(CMDJIT) vmsrc/apple/cmdjitstub.s -$(SOSCMD): vmsrc/apple/soscmd.pla $(PLVM03) $(PLASM) +$(SOSCMD): vmsrc/apple/soscmd.pla libsrc/jitcore.pla $(PLVM03) $(PLASM) ./$(PLASM) -AMOW < vmsrc/apple/soscmd.pla > vmsrc/apple/soscmd.a acme --setpc 4094 -o $(SOSCMD) vmsrc/apple/soscmd.a @@ -366,7 +366,7 @@ $(SOS): libsrc/apple/sos.pla $(PLVM03) $(PLASM) ./$(PLASM) -AMO < libsrc/apple/sos.pla > libsrc/apple/sos.a acme --setpc 4094 -o $(SOS) libsrc/apple/sos.a -$(JIT): libsrc/apple/jit.pla $(PLVMJIT) $(PLASM) +$(JIT): libsrc/apple/jit.pla libsrc/jitcore.pla $(PLVMJIT) $(PLASM) ./$(PLASM) -AMO < libsrc/apple/jit.pla > libsrc/apple/jit.a acme --setpc 4094 -o $(JIT) libsrc/apple/jit.a diff --git a/src/vmsrc/apple/soscmd.pla b/src/vmsrc/apple/soscmd.pla index 14827bb..619e0ca 100755 --- a/src/vmsrc/apple/soscmd.pla +++ b/src/vmsrc/apple/soscmd.pla @@ -16,13 +16,11 @@ end // // JIT compiler values // -const jitcomp = $B7F0 -const jitcodeptr = $B7F2 -const codemax = $A000 -word interpentry -// -// AUX bytecode interpreter entrypoint -// +const jitcomp = $B7F0 +const jitcodeptr = $B7F2 +const codemax = $A000 +const directentry = $A0C2 // Right afer opcode table +const indirectentry = $A0D5 // Yikes! Grabbed from plvm03.sym // // COPY FROM EXT MEM TO MAIN MEM. // @@ -38,7 +36,7 @@ DSTX = XPAGE+DSTH ORA ESTKH,X BEQ CPYXMEX LDA ESTKL+3,X - STY DSTL + STA DSTL LDA ESTKH+3,X STA DSTH LDA ESTKL+2,X @@ -47,6 +45,8 @@ DSTX = XPAGE+DSTH STA SRCH LDA ESTKL+1,X STA SRCX + INC ESTKH,X + LDY #$00 CPYXLP LDA (SRC),Y STA (DST),Y INY @@ -313,8 +313,7 @@ cmdsys:cmdparser = @shell // // Install JIT compiler // -interpentry = compiler:interpaddr *jitcomp = @compiler cmdsys.jitcount = 44 -//cmdsys.jitsize = 96 +cmdsys.jitsize = 96 done From 347aa5329db9d9841a51400daf4ec5f28507f35d Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Mon, 2 Apr 2018 15:41:41 -0700 Subject: [PATCH 130/147] Leave buffer for maxcode and assembly defcpy --- src/vmsrc/apple/soscmd.pla | 61 +++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 33 deletions(-) diff --git a/src/vmsrc/apple/soscmd.pla b/src/vmsrc/apple/soscmd.pla index 619e0ca..7c8e9dd 100755 --- a/src/vmsrc/apple/soscmd.pla +++ b/src/vmsrc/apple/soscmd.pla @@ -18,56 +18,51 @@ end // const jitcomp = $B7F0 const jitcodeptr = $B7F2 -const codemax = $A000 +const codemax = $9FE0 const directentry = $A0C2 // Right afer opcode table const indirectentry = $A0D5 // Yikes! Grabbed from plvm03.sym // // COPY FROM EXT MEM TO MAIN MEM. // -// XMEMCPY(DST, XSRC, SIZE) -// -asm xmemcpy(dst, src, srcx, size)#0 +asm defcpy(dst, defentry)#0 !SOURCE "vmsrc/plvmzp.inc" XPAGE = $1600 SRCX = XPAGE+SRCH DSTX = XPAGE+DSTH - LDA ESTKL,X - ORA ESTKH,X - BEQ CPYXMEX - LDA ESTKL+3,X - STA DSTL - LDA ESTKH+3,X - STA DSTH - LDA ESTKL+2,X - STA SRCL - LDA ESTKH+2,X - STA SRCH LDA ESTKL+1,X + STA DSTL + LDA ESTKH+1,X + STA DSTH + LDA ESTKL,X + STA TMPL + LDA ESTKH,X + STA TMPH + LDY #$05 + LDA (TMP),Y STA SRCX - INC ESTKH,X - LDY #$00 -CPYXLP LDA (SRC),Y + DEY + LDA (TMP),Y + STA SRCH + DEY + LDA (TMP),Y + STA SRCL + LDY #$07 + LDA (TMP),Y + TAY + DEY + BEQ + +- LDA (SRC),Y STA (DST),Y - INY - BNE + - INC DSTH - INC SRCH -+ DEC ESTKL,X - BNE CPYXLP - DEC ESTKH,X - BNE CPYXLP - LDA #$00 - STA SRCX -CPYXMEX INX - INX + DEY + BNE - ++ LDA (SRC),Y + STA (DST),Y + STY SRCX INX INX RTS end -def defcpy(dst, defentry)#0 - xmemcpy(dst, defentry=>bytecodeaddr, defentry->bytecodexbyte, defentry->bytecodesize) -end include "libsrc/jitcore.pla" // // SOS routines From 763cbd69868a7576a3537d987bc5fb34f3c38400 Mon Sep 17 00:00:00 2001 From: Dave Schmenk Date: Mon, 2 Apr 2018 21:46:53 -0700 Subject: [PATCH 131/147] Full 4K JIT codebuffer --- src/vmsrc/apple/cmdjitstub.s | 92 ++++++++++++++++++------------------ src/vmsrc/apple/plvmjit02.s | 2 +- 2 files changed, 47 insertions(+), 47 deletions(-) diff --git a/src/vmsrc/apple/cmdjitstub.s b/src/vmsrc/apple/cmdjitstub.s index ab4e8f9..8e926dd 100644 --- a/src/vmsrc/apple/cmdjitstub.s +++ b/src/vmsrc/apple/cmdjitstub.s @@ -1,55 +1,55 @@ -INTERP = $03D0 -LCRDEN = $C080 -LCWTEN = $C081 +INTERP = $03D0 +LCRDEN = $C080 +LCWTEN = $C081 ROMEN = $C082 -LCRWEN = $C083 -LCBNK2 = $00 -LCBNK1 = $08 -JITCOMP = $03E2 -JITCODE = $03E4 - !SOURCE "vmsrc/plvmzp.inc" +LCRWEN = $C083 +LCBNK2 = $00 +LCBNK1 = $08 +JITCOMP = $03E2 +JITCODE = $03E4 +!SOURCE "vmsrc/plvmzp.inc" ;* ;* MOVE CMD DOWN TO $1000-$2000 ;* - LDA #<_CMDBEGIN - STA SRCL - LDA #>_CMDBEGIN - STA SRCH - LDY #$00 - STY DSTL - LDX #$10 - STX DSTH -- LDA (SRC),Y - STA (DST),Y - INY - BNE - - INC SRCH - INC DSTH - DEX ; STOP WHEN DST=$2000 REACHED - BNE - - LDA #<_CMDEND - STA SRCL - LDA #>_CMDEND - STA SRCH + LDA #<_CMDBEGIN + STA SRCL + LDA #>_CMDBEGIN + STA SRCH + LDY #$00 + STY DSTL + LDX #$10 + STX DSTH +- LDA (SRC),Y + STA (DST),Y + INY + BNE - + INC SRCH + INC DSTH + DEX ; STOP WHEN DST=$2000 REACHED + BNE - + LDA #<_CMDEND + STA SRCL + LDA #>_CMDEND + STA SRCH ; ; INIT VM ENVIRONMENT STACK POINTERS ; - STY PPL - STY IFPL ; INIT FRAME POINTER - STY JITCOMP - STY JITCOMP+1 - STY JITCODE - LDA #$B0 - STA PPH - STA IFPH - STA JITCODE+1 - LDX #$FE ; INIT STACK POINTER (YES, $FE. SEE GETS) - TXS - LDX #ESTKSZ/2 ; INIT EVAL STACK INDEX + STY JITCOMP + STY JITCOMP+1 + STY PPL + STY IFPL ; INIT FRAME POINTER + STY JITCODE + LDA #$AF + STA PPH + STA IFPH + STA JITCODE+1 + LDX #$FE ; INIT STACK POINTER (YES, $FE. SEE GETS) + TXS + LDX #ESTKSZ/2 ; INIT EVAL STACK INDEX - JMP $1000 -_CMDBEGIN = * - !PSEUDOPC $1000 { - !SOURCE "vmsrc/apple/cmdjit.a" -_CMDEND = * + JMP $1000 +_CMDBEGIN = * +!PSEUDOPC $1000 { +!SOURCE "vmsrc/apple/cmdjit.a" +_CMDEND = * } diff --git a/src/vmsrc/apple/plvmjit02.s b/src/vmsrc/apple/plvmjit02.s index cf16ce5..979ef67 100755 --- a/src/vmsrc/apple/plvmjit02.s +++ b/src/vmsrc/apple/plvmjit02.s @@ -339,7 +339,7 @@ CMDENTRY = * STA $01FF ; CLEAR CMDLINE BUFF STA PPL ; INIT FRAME POINTER STA IFPL - LDA #$B0 ; FRAME POINTER AT $B000, BELOW JIT BUFFER + LDA #$AF ; FRAME POINTER AT $AF00, BELOW JIT BUFFER STA PPH STA IFPH LDX #$FE ; INIT STACK POINTER (YES, $FE. SEE GETS) From 3e0d81d09d853e90a7b17c15ebb22daf491a41e4 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Tue, 3 Apr 2018 10:10:41 -0700 Subject: [PATCH 132/147] Put buffer at beginning of SBANK --- src/inc/cmdsys.plh | 1 - src/vmsrc/apple/plvm03.s | 35 +++++++++++++---------------------- src/vmsrc/apple/soscmd.pla | 16 ++++++++++------ src/vmsrc/apple/sossys.pla | 22 +++++++++++++--------- 4 files changed, 36 insertions(+), 38 deletions(-) diff --git a/src/inc/cmdsys.plh b/src/inc/cmdsys.plh index e476d19..d258e54 100644 --- a/src/inc/cmdsys.plh +++ b/src/inc/cmdsys.plh @@ -55,7 +55,6 @@ import cmdsys byte jitsize byte refcons // Apple /// specific byte devcons // Apple /// specific - word cmdparser // Apple /// specific end // // CMD exported functions diff --git a/src/vmsrc/apple/plvm03.s b/src/vmsrc/apple/plvm03.s index 1363f81..84aeab9 100755 --- a/src/vmsrc/apple/plvm03.s +++ b/src/vmsrc/apple/plvm03.s @@ -31,8 +31,6 @@ JMPTMPX = XPAGE+JMPTMP TMPX = XPAGE+TMPH SRCX = XPAGE+SRCH DSTX = XPAGE+DSTH -JITCOMP = $B7F0 ; JIT VARS AT THE END OF INTER -JITCODE = $B7F2 ;* ;* SOS ;* @@ -134,6 +132,10 @@ PAGE0 = * } VMCORE = * !PSEUDOPC $A000 { +TEMPBUF !FILL $F0 +CMDPARS !WORD 0 ; $A0F0 +JITCOMP !WORD 0 ; $A0F2 +JITCODE !WORD 0 ; $A0F4 ;* ;* OPCODE TABLE ;* @@ -171,7 +173,7 @@ XINTERP PLA STA TMPL PLA STA TMPH - LDY #$03 +- LDY #$03 LDA (TMP),Y STA IPX DEY @@ -186,34 +188,20 @@ XINTERP PLA ;* JIT PROFILING ENTRY INTO INTERPRETER ;* JITINTRP PLA - SEC - SBC #$02 ; POINT TO DEF ENTRY STA TMPL PLA - SBC #$00 STA TMPH - LDY #$06 + LDY #$04 LDA (TMP),Y ; DEC JIT COUNT SEC SBC #$01 STA (TMP),Y - BEQ RUNJIT - DEY ; INTERP BYTECODE AS USUAL - LDA (TMP),Y - STA IPX - DEY - LDA (TMP),Y - STA IPH - DEY - LDA (TMP),Y - STA IPL - LDY #$00 - JMP FETCHOP -RUNJIT LDA JITCOMP + BNE - ; INTERP BYTECODE + LDA JITCOMP ; CALL JIT COMPILER STA SRCL LDA JITCOMP+1 STA SRCH - DEY ; LDY #$05 + INY ; LDY #$05 LDA (SRC),Y STA IPX DEY @@ -224,9 +212,12 @@ RUNJIT LDA JITCOMP STA IPL DEX ; ADD PARAMETER TO DEF ENTRY LDA TMPL + SEC + SBC #$02 ; POINT TO DEF ENTRY PHA ; AND SAVE IT FOR LATER STA ESTKL,X LDA TMPH + SBC #$00 PHA STA ESTKH,X LDY #$00 @@ -1357,7 +1348,7 @@ CALL INY ;+INC_IP INY ;+INC_IP LDA (IP),Y STA CALLADR+2 - TYA +_CALL TYA SEC ADC IPL PHA diff --git a/src/vmsrc/apple/soscmd.pla b/src/vmsrc/apple/soscmd.pla index 7c8e9dd..883b8b8 100755 --- a/src/vmsrc/apple/soscmd.pla +++ b/src/vmsrc/apple/soscmd.pla @@ -1,5 +1,9 @@ include "inc/cmdsys.plh" // +// Temp buff addresses +// +const cmdparser = $A0F0 +// // JIT compiler values // // @@ -16,11 +20,11 @@ end // // JIT compiler values // -const jitcomp = $B7F0 -const jitcodeptr = $B7F2 -const codemax = $9FE0 -const directentry = $A0C2 // Right afer opcode table -const indirectentry = $A0D5 // Yikes! Grabbed from plvm03.sym +const jitcomp = $A0F2 +const jitcodeptr = $A0F4 +const codemax = $A000 +const directentry = $A1C2 // Right afer opcode table +const indirectentry = $A1F0 // Yikes! Grabbed from plvm03.sym // // COPY FROM EXT MEM TO MAIN MEM. // @@ -304,7 +308,7 @@ end // // Save pointer to command line handler // -cmdsys:cmdparser = @shell +*cmdparser = @shell // // Install JIT compiler // diff --git a/src/vmsrc/apple/sossys.pla b/src/vmsrc/apple/sossys.pla index 03739ec..02d7aaf 100755 --- a/src/vmsrc/apple/sossys.pla +++ b/src/vmsrc/apple/sossys.pla @@ -17,6 +17,11 @@ const resxhgr2 = $0080 const modkeep = $2000 const modinitkeep = $4000 // +// Temp buff addresses +// +const instr = $A020 +const cmdparser = $A0F0 +// // Indirect interpreter DEFinition entrypoint // struc t_defentry @@ -30,8 +35,8 @@ end // // JIT compiler values // -const jitcomp = $B7F0 -const jitcodeptr = $B7F2 +const jitcomp = $A0F2 +const jitcodeptr = $A0F4 const codemax = $A000 // // Pedefined functions. @@ -55,7 +60,6 @@ byte jitcount = 0 byte jitsize = 0 byte refcons = 0 byte devcons = 0 -word cmdparser // // String pool. // @@ -940,12 +944,12 @@ def print(i)#0 end def rdstr(prompt)#1 cout(prompt) - ^heap = read(refcons, heap + 1, 128) - if heap->[^heap] == $0D - ^heap-- + ^instr = read(refcons, instr+1, 128) + if instr->[^instr] == $0D + ^instr-- fin crout - return heap + return instr end def prbyte(v)#0 cout(hexchar[(v >> 4) & $0F]) @@ -1045,7 +1049,7 @@ def adddef(isfirst, ext, addr, deflast)#1 if not isfirst preventry = defentry - t_defentry defsize = addr - preventry=>bytecodeaddr - if defsize <= jitsize // and *jitcomp + if defsize <= jitsize preventry=>interpaddr = jitinterp // JSR JITINTRP preventry->callcount = jitcount // Set JIT countdown preventry->bytecodesize = defsize // Set size @@ -1337,7 +1341,7 @@ fin // Call cmd line parser // repeat - execmod(cmdparser()) + execmod((*cmdparser)()) write(refcons, @textmode, 3) cmdln = 0 until 0 From 9a82e3b5fb7297657242119c85ea42cb6cea1fa7 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Tue, 3 Apr 2018 13:56:55 -0700 Subject: [PATCH 133/147] Looking for one more JITC bug --- src/libsrc/jitcore.pla | 227 ++++++++++++++++++------------------- src/vmsrc/apple/plvm03.s | 3 + src/vmsrc/apple/soscmd.pla | 21 ++-- src/vmsrc/apple/sossys.pla | 33 ++---- 4 files changed, 131 insertions(+), 153 deletions(-) diff --git a/src/libsrc/jitcore.pla b/src/libsrc/jitcore.pla index 3a9d381..7624607 100644 --- a/src/libsrc/jitcore.pla +++ b/src/libsrc/jitcore.pla @@ -109,7 +109,7 @@ def compiler(defptr)#0 // is $50 // BRNCH is $22 // BREQ - is $24 // BENE + is $24 // BRNE is $4C // BRFLS is $4E // BRTRU is $A0 // BRGT @@ -293,6 +293,7 @@ def compiler(defptr)#0 is $2C // CW i++ dest = *(bytecode+i) + i++ //puts("LA/CW $"); puth(dest) if A_IS_TOSL & TOS_DIRTY *codeptr = $D095+(VX<<8) // STA ESTKL,X @@ -304,7 +305,6 @@ def compiler(defptr)#0 codeptr=>4 = $A9+(dest<<8) // LDA #>VAL codeptr = codeptr + 6 A_IS_TOSL = TOS_DIRTY // STA ESTKL,X - i++ break is $28 // LLA i++ @@ -420,7 +420,7 @@ def compiler(defptr)#0 i++ j = ^(bytecode+i) //puts("ADDI $"); putb(^(bytecode+i)) - is $8C // INCR + is $8C // INCR if opcode == $8C //puts("INCR") j = 1 @@ -778,17 +778,16 @@ def compiler(defptr)#0 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 + if j <> 0 *codeptr = $00A0 // LDY #$00 codeptr = codeptr + 2 - VY = 0 fin *codeptr = $C094+(VX<<8) // STY ESTKH,X codeptr = codeptr + 2 + VY = 0 A_IS_TOSL = TOS_DIRTY // STA ESTKL,X break is $66 // LLW @@ -820,60 +819,36 @@ def compiler(defptr)#0 dest = *(bytecode+i) i++ if A_IS_TOSL & TOS_DIRTY - *codeptr = $D095+(VX<<8) // STA ESTKL,X + *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 fin - VX-- // DEX + VX-- // DEX if opcode == $68 //puts("LAB $"); puth(*(bytecode+i)) if VY <> 0 - *codeptr = $00A0 // LDY #$00 + *codeptr = $00A0 // LDY #$00 codeptr = codeptr + 2 VY = 0 fin - codeptr=>0 = $C094+(VX<<8) // STY ESTKH,X - codeptr = codeptr + 2 + *codeptr = $C094+(VX<<8) // STY ESTKH,X + codeptr = codeptr + 2 else //puts("LAW $"); puth(dest) - codeptr->0 = $AD // LDA abs + codeptr->0 = $AD // LDA abs codeptr=>1 = dest+1 - codeptr=>3 = $C095+(VX<<8) // STA ESTKH,X + codeptr=>3 = $C095+(VX<<8) // STA ESTKH,X codeptr = codeptr + 5 fin - codeptr->0 = $AD // LDA abs + 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 + A_IS_TOSL = TOS_DIRTY // STA ESTKL,X break is $6C // DLB - is $74 // SLB i++ j = ^(bytecode+i) - if not A_IS_TOSL + //puts("DLB "); puti(j) + if not A_IS_TOSL *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 A_IS_TOSL = TOS_CLEAN @@ -883,36 +858,8 @@ def compiler(defptr)#0 codeptr = codeptr + 2 VY = j fin - *codeptr = $E091 // STA (IFP),Y + *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++ @@ -937,61 +884,105 @@ def compiler(defptr)#0 codeptr = codeptr + 9 A_IS_TOSL = TOS_CLEAN break - is $78 // SAB - is $7C // DAB - i++ + is $70 // SB + is $72 // SW if not A_IS_TOSL - *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + *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)) + 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 - i++ + VX = VX + 2 // INX; INX + A_IS_TOSL = FALSE break + is $74 // SLB + is $76 // SLW + i++ + j = ^(bytecode+i) + if not A_IS_TOSL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 + fin + if VY <> j + *codeptr = $A0+(j<<8) // LDY #imm + codeptr = codeptr + 2 + VY = j + fin + codeptr=>0 = $E091 // STA (IFP),Y + if opcode == $74 + //puts("SLB "); puti(j) + codeptr = codeptr + 2 + else + //puts("SLW "); puti(j) + codeptr->2 = $C8 // INY + codeptr=>3 = $C0B5+(VX<<8) // LDA ESTKH,X + codeptr=>5 = $E091 // STA (IFP),Y + codeptr = codeptr + 7 + VY++ + fin + VX++ // INX + A_IS_TOSL = FALSE + break + is $78 // SAB is $7A // SAW i++ dest = *(bytecode+i) + i++ //puts("SAW $"); puth(dest) if not A_IS_TOSL - *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin - codeptr->0 = $8D // STA abs + 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++ + if opcode == $78 + //puts("SAB $"); puth(*(bytecode+i)) + codeptr = codeptr + 3 + else + codeptr=>3 = $C0B5+(VX<<8) // LDA ESTKH,X + codeptr->5 = $8D // STA abs+1 + codeptr=>6 = dest+1 + codeptr = codeptr + 8 + fin + VX++ // INX + A_IS_TOSL = FALSE break + is $7C // DAB is $7E // DAW i++ dest = *(bytecode+i) + i++ //puts("DAW $"); puth(*(bytecode+i)) if not A_IS_TOSL - *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 A_IS_TOSL = TOS_CLEAN fin - codeptr->0 = $8D // STA abs + 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++ + if opcode == $7C + //puts("DAB $"); puth(*(bytecode+i)) + codeptr = codeptr + 3 + else + codeptr=>3 = $C0B4+(VX<<8) // LDY ESTKH,X + codeptr->5 = $8C // STY abs+1 + codeptr=>6 = dest+1 + codeptr = codeptr + 8 + VY = UNKNOWN + fin break is $80 // NOT //puts("NOT") @@ -1067,7 +1058,7 @@ def compiler(defptr)#0 codeptr = codeptr + 2 fin codeptr->0 = $20 // JSR INTERP - codeptr=>1 = directentry // INTERP + codeptr=>1 = directentry // INTERP codeptr=>3 = $C000+opcode // OPCODE; NATV CODE codeptr = codeptr + 5 VY = UNKNOWN @@ -1159,8 +1150,8 @@ def compiler(defptr)#0 is $A0 // BRGT - FOR/NEXT SPECIFIC TEST & BRANCH i++ dest = i + *(bytecode+i) - //puts("BRGT "); puti(dest) i++ + //puts("BRGT "); puti(dest) codeptr, VX = resolveX(codeptr, VX) if A_IS_TOSL & TOS_DIRTY *codeptr = $D095//+(VX<<8) // STA ESTKL,X @@ -1185,8 +1176,8 @@ def compiler(defptr)#0 is $A2 // BRLT - FOR/NEXT SPECIFIC TEST & BRANCH i++ dest = i + *(bytecode+i) - //puts("BRLT "); puti(dest) i++ + //puts("BRLT "); puti(dest) codeptr, VX = resolveX(codeptr, VX) if not A_IS_TOSL *codeptr = $D0B5//+(VX<<8) // LDA ESTKL,X @@ -1247,9 +1238,9 @@ def compiler(defptr)#0 // BRLE // codeptr=>0 = $D0B5+$0100//+(VX<<8) // LDA ESTKL+1,X - codeptr=>2 = $D0D5+(VX<<8) // CMP ESTKL,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=>6 = $C0F5//+(VX<<8) // SBC ESTKH codeptr=>8 = $0250 // BVC +2 codeptr=>10 = $8049 // EOR #$80 codeptr=>12 = $0330 // BMI +3 @@ -1365,6 +1356,7 @@ def compiler(defptr)#0 if VY <> j *codeptr = $A0+(j<<8) // LDY #imm codeptr = codeptr + 2 + VY = j fin codeptr->0 = $18 // CLC codeptr=>1 = $E071 // ADC (IFP),Y @@ -1373,8 +1365,7 @@ def compiler(defptr)#0 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 + A_IS_TOSL = TOS_DIRTY // STA ESTKL,X else //puts("ADDLW "); puti(j) codeptr=>3 = $D095+(VX<<8) // STA ESTKL,X @@ -1383,8 +1374,8 @@ def compiler(defptr)#0 codeptr=>8 = $E071 // ADC (IFP),Y codeptr=>10 = $C095+(VX<<8) // STA ESTKH,X codeptr = codeptr + 12 - VY = j + 1 - A_IS_TOSL = FALSE + VY++ + A_IS_TOSL = FALSE fin break is $B4 // ADDAB @@ -1429,7 +1420,7 @@ def compiler(defptr)#0 fin *codeptr = $E0B1 // LDA (IFP),Y codeptr = codeptr + 2 - if j + if j <> 0 *codeptr = $00A0 // LDY #$00 codeptr = codeptr + 2 fin @@ -1468,8 +1459,8 @@ def compiler(defptr)#0 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=>18 = $C075+(VX<<8) // ADC ESTKH,X + codeptr=>20 = $C095+(VX<<8) // STA ESTKH,X codeptr = codeptr + 22 VY = UNKNOWN A_IS_TOSL = FALSE @@ -1494,13 +1485,13 @@ def compiler(defptr)#0 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=>15 = $C095+(VX<<8) // STA ESTKH,X codeptr = codeptr + 17 VY = UNKNOWN A_IS_TOSL = FALSE i++ break - is $BE + is $BE // IDXAW i++ dest = *(bytecode+i) i++ @@ -1513,7 +1504,7 @@ def compiler(defptr)#0 codeptr=>1 = dest codeptr->3 = $0A // ASL codeptr=>4 = $E785 // STA $E7:TMPL - codeptr->6 = $AD // LDA abs + codeptr->6 = $AD // LDA abs+1 codeptr=>7 = dest+1 codeptr=>9 = $A82A // ROL; TAY codeptr=>11 = $E7A5 // LDA $E7:TMPL @@ -1522,7 +1513,7 @@ def compiler(defptr)#0 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=>21 = $C095+(VX<<8) // STA ESTKH,X codeptr = codeptr + 23 VY = UNKNOWN A_IS_TOSL = FALSE diff --git a/src/vmsrc/apple/plvm03.s b/src/vmsrc/apple/plvm03.s index 84aeab9..3059570 100755 --- a/src/vmsrc/apple/plvm03.s +++ b/src/vmsrc/apple/plvm03.s @@ -136,6 +136,9 @@ TEMPBUF !FILL $F0 CMDPARS !WORD 0 ; $A0F0 JITCOMP !WORD 0 ; $A0F2 JITCODE !WORD 0 ; $A0F4 +SENTRY !WORD INTERP ; $A0F6 +XENTRY !WORD XINTERP ; $A0F8 +JENTRY !WORD JITINTRP ; $A0FA ;* ;* OPCODE TABLE ;* diff --git a/src/vmsrc/apple/soscmd.pla b/src/vmsrc/apple/soscmd.pla index 883b8b8..f370a2b 100755 --- a/src/vmsrc/apple/soscmd.pla +++ b/src/vmsrc/apple/soscmd.pla @@ -1,9 +1,5 @@ include "inc/cmdsys.plh" // -// Temp buff addresses -// -const cmdparser = $A0F0 -// // JIT compiler values // // @@ -18,13 +14,16 @@ struc t_defentry byte bytecodesize end // -// JIT compiler values +// Private addresses // -const jitcomp = $A0F2 -const jitcodeptr = $A0F4 -const codemax = $A000 -const directentry = $A1C2 // Right afer opcode table -const indirectentry = $A1F0 // Yikes! Grabbed from plvm03.sym +const codemax = $A000 +const cmdparser = $A0F0 +const jitcomp = $A0F2 +const jitcodeptr = $A0F4 +const sinterp = $A0F6 +const xinterp = $A0F8 +const jitinterp = $A0FA +word directentry, indirectentry // // COPY FROM EXT MEM TO MAIN MEM. // @@ -312,6 +311,8 @@ end // // Install JIT compiler // +directentry = *sinterp +indirectentry = *xinterp *jitcomp = @compiler cmdsys.jitcount = 44 cmdsys.jitsize = 96 diff --git a/src/vmsrc/apple/sossys.pla b/src/vmsrc/apple/sossys.pla index 02d7aaf..29408a7 100755 --- a/src/vmsrc/apple/sossys.pla +++ b/src/vmsrc/apple/sossys.pla @@ -17,10 +17,12 @@ const resxhgr2 = $0080 const modkeep = $2000 const modinitkeep = $4000 // -// Temp buff addresses +// Private addresses // const instr = $A020 const cmdparser = $A0F0 +const xinterp = $A0F8 +const jitinterp = $A0FA // // Indirect interpreter DEFinition entrypoint // @@ -459,25 +461,6 @@ asm sext(a)#1 RTS end // -// Addresses of internal routines. -// -asm xinterp()#1 - DEX - LDA #XINTERP - STA ESTKH,X - RTS -end -asm jitinterp()#1 - DEX - LDA #JITINTRP - STA ESTKH,X - RTS -end -// // A DCI string is one that has the high bit set for every character except the last. // More efficient than C or Pascal strings. // @@ -1050,13 +1033,13 @@ def adddef(isfirst, ext, addr, deflast)#1 preventry = defentry - t_defentry defsize = addr - preventry=>bytecodeaddr if defsize <= jitsize - preventry=>interpaddr = jitinterp // JSR JITINTRP - preventry->callcount = jitcount // Set JIT countdown - preventry->bytecodesize = defsize // Set size + preventry=>interpaddr = *jitinterp // JSR JITINTRP + preventry->callcount = jitcount // Set JIT countdown + preventry->bytecodesize = defsize // Set size fin fin - defentry->interpjsr = $20 - defentry=>interpaddr = xinterp + defentry->interpjsr = $20 // JSR + defentry=>interpaddr = *xinterp // XINTERP defentry=>bytecodeaddr = addr defentry->bytecodexbyte = ext defentry->t_defentry = 0 From 8b649b0d48493d8f150cf4c2549c5403b97b55af Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Wed, 4 Apr 2018 13:25:13 -0700 Subject: [PATCH 134/147] fix opcode skip for CS in branch detection --- PLASMA-BLD2.PO | Bin 143360 -> 143360 bytes PLASMA-SYS2.PO | Bin 143360 -> 143360 bytes src/libsrc/apple/jit.pla | 2 +- src/libsrc/jitcore.pla | 9 +++++---- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/PLASMA-BLD2.PO b/PLASMA-BLD2.PO index 416b2581ebc825583c11a28adbc2bac4ffb36bac..1f04c2fbd28c019570349a41d9108a9f63f5d7dc 100644 GIT binary patch delta 4644 zcmb7I4Qx}_6+V8x_Iq*uj1wFaXvhdSFE7Li;Xk4f;}{ZToQG}FkRLE+X`xHOayxD7 zsyR+0RCO%HLj^6jV@kHo-KNK`Yv|TM->A9Uv;EO=an(X+H(6#ry8Hogaq{ zEz;-roqNwY_nhzEcWq_hrZR9-IWdpb+R01~L$#;9#oMljDD!tuA(_6JPtVR>I<1Os zks$kYR=#M`h(y{NcgW)oxpbdfgt8K16k<7n2d4(su3gjF;$7dKjbsio(tKl1;ONxA z`K@aM3qsytc1<=59sEwo32ZWz7fvd5-&T`5XXLnPN;~t=M{s>s1)_V8Q3F->Ogx-wiO=EM$pd6+;(*Hlojg&?Q1uBUF+R?I-DJ)S~?oYS@Gc1z}kTB_qctY z?5gY&Dxp19If0{71Jw!QiBgS*d@3x-32c(5lvaoKp}2*R-wn z1||e9L*R?)!#aLyNADM?2SXDBA4cHExhpnpnR14&XLS{cziLAgP8qWY@eB>M2Q&>j~gfKUE{_b`%jOF<-mS>FmVi@(pAjcwOfw6m0W@fPrV=*`4$gm_I){@MWRt!VS1T8QY8M_x` zW*TJ}jTvKMK8%GKqplc6T_&c%Xf<{>WM*7443{vLmv!dD=oChuy|x%eZEr;M_u|7 z>ZxfD_I~UL+O05xR$EEwbbA?OzPn$RYO1P4;5~zIWi~>J;2u-k%pv0 zLFz9+7;>ux;lZ(x37Nl;DGEyt#-*VLc^-Z>mCl!wtDaX`J0X`ymE+Vi$q6-0ZbXTT zh9`TWtaMd5zQT3Fs+Ndv4)M}hM72c1L+m-O=vV<3A%0h3rw!k$hnlIMRD-kG8g{O- zh9#B4aMYH?x%P?$=9s#gRW*c%q#>XWf`9a^vFlM@GE6(Osh`U*F%Vj z_V66OBF^EdmGiEgXG%Mq(NZKc5(W$S80J*1OmbOQ;484wv$a3I?aTdJpV}2$>5SPr zBuOhNAeY<}d}`~qFExpw01v5b#&iV>|8 z%Q(oTG_CJ@BEBp3HL(zst%9=J^hpAyx2Z!DfrmdzIe&=FiRsnYO1v0he6m5lk?B{+ z5HWM0o_FqYL89NPJ0rYQUhsr1JAMy83Tf(I|d^-g`ODN~I5;m7l%@H<; zSONPkO`Pa5V55Ze`CR(&Fg~I{MAGW4Bm0|u6Nj-CT~gXVdkh)H_w!ZeidAM?(UMl# z?0aZZGHDPQ8UNs&iY;|sFS$>y{k%zS+5eR*o-HbKSh5v{wP|a7)x3_#d_%+POe1?> zM{yd%c=CD%qx^s&#wb)6@D&ieF%#1(MGw*;2lY!BP^B<>b2a-+)YxS_JeuO+NEf$8 zH5WKHGuez;O@llIm!xjBPvu;QAmm6ZkxqdOb;2>KKTx=Adt4~-lEk@`**7IU`+6zA zcEbU;kh7J`sjm}!o!~14_X*x8xLAQxx zVLq+w+W_gB@!eVJtiT%x0iD+XzPFG-98!jB zkoTg9GV!j6t3y>0>&fC0Bk&U+l>pyLMJKxR!_`R9N0Y znjMkiwxS*>WFsjCTrVMMUMWdY;053aa0YlCxW+M^;?iO}NqxWx;0|CaBWXFX8@L6K zgQV>Me&9%n86*{!Q}Uk{CGi&vC2j*(f!_j`fOmnnfHy3ZJPV&!@%*mEkQ}xs$tdtR zcrTu9K%>Q!bXnrYq!W%0!O@1Nf?x&^@L3)u?g0M)ZUR?<%XySMoo7m(%rhpA!F~p| zFHcT31B(C^m<3n?2Ha8P#3u?R{-99u_u!Yn-v&Pi{xk3q{PIrjRg8%}Ft&lOQsm@9 zpcZECO6WEl>qi03|>kfPZo%J~N{zGbR6OW{E$8 z{}K2IxDI>(yo0&(W;t;d{HMTcz$?H}jK6GV@x)6oMt~QAB(MhpupGX%@STh2OtYM{f#-u8!9O)YeiJ2cn&jj~lOcK5q$G~OehK)FNlFfz zHYtf`U_6G&Zj+MSh-Vv~9z2)gxd6|32%2r8L@8k4$(WM(fKlRoM#*0>IdKvE9Po4C NG{%0+l;roB;Xfiv_ly7l delta 4107 zcmZu!OOG5^6|NqaGZRAbh%p$)5{HSS?#WbUdd81LBaCyq>UQ_FtLm2P-sK)dC_~uyVUDPI+i-OUi12V&0F<;|D5;U)wM6Z=>5}kUk-Es^7S(( zE8fdvVIyI;@=fBg%prV+_x^X(Tlq)t zldnX12lM>kTd)3Y^{lUL@7s~i6jNbZ8}V;?J@3!Gvtoyj4mu%0ajZtNIHmX+6hElx zdcxZ$U!<5Dds^`p6#v!rxOabvMfaCtxTG@4WNc#h{1~RPuBpe%iZ3KOo7_pc@J`ns zLvhgw{^;rb-#+_1;q~iZJb0Ua{PVYe`PPG9{p7*n&O29*e)G=$$|pa&vVNA0+uqB0 zGE3jcw^SB6K>a&lW3ke~GkTa$xel(NMtmUG*L5|k)TYZlB}jw+{NcqvK-GmN_8QrkRleNL~h|Y2%Ir8 zxrA&%x9Dm#yf!2#Oy!)anMg`$2=0o;dH-rZU`0siF|3w_k>m!6ps6sFXq~HUQoBT) zMHyK`s7+GFIH$2Lwlg`mAxjhze(iRdS(SveKUIm`W&p4Gr1O&Tu#khz?o+5wwURX@FS+X@k<4QK=G)lwog5jtV zS38D;ke1635f?I*ndPcj_id{!velWhXc9G<+GK%b_fb`F1hg3GnWVUM77-Mq)pwBh zftrj;%Whjuu8v8n6Llw!^!u*DHFu7Y2%Mb;neW}|q5^=N=;kIdvraMqkcz1oaE2`` zE>X>Vw$)S@x|~eImSH&-NFh?kd^6Q$5|acjt}O(u$H;%3&@qUXGl+DWgHr|F&Gfzj zqG%7KZY(GUKo^z)XTh;f02Kq!*g#p-1QaM_T<6NBg8&Mq?KXfKFC3QyfEC3^*+LXJ z;S!%1WZ;^xT@!8{-uv*{AH&s(&v^k0!W@c6dd`OX7Wj&oV@h>gCTPAy)m=>EGD&DA z3!`)v(x|j7rL1c^qtWuCQYH2kl|eF#ETp($gcB2-AL?vnW-ui{(#o;4A%e*BMD`u5 zQ&GhG0?gz(7(KS`hs8cN@gR+~3WKaA-6_$J7$cZHifM@!5wXi4mj$<>$Rf$u zL$*mc6$`4kz*@60gV^xd4kHH8faE9^=F#vvI;@#e?$D?=Bp&PxcdrM*Xkq0KYGFSA zA+VfDivsWiQo+71VmA+4b{%6>0VIb}J0i@&;EIt9qBIV3!7SV0P1L^jP#)lqQpVZ= z<%E%G5dwutIOn$ozvU)}W+Q*|#&DNFVssZk;PDL+>h*db^j4nw&wu0MH!<%2+YDL; zBbBL!y>beK@7YT9hwNteGOJ&DQo1q|O&) zs`~hpx!NN!j4s=}w9y~}Ib3Rap-^f5$xbE`&l<4y+eFzOYH$ShP&8)~h**h_@OV+Xk>Nrq@W6E#v=&Vhjm~CC24n8~``4%ri#`I() zFbI5?a2%HwZ5+Bq%Tnuujdj=5_IcAq!Yp`w$jKxf&HoRo( zkq)s!j?wh!{=GV+nQ@UN#6e(}4x&n-Hu8rcT05>gK zu}NJP6_VO$&)^yff^3L~IVvJ#>E;<`Z7w3&3OZ8vMW3q8TD?A?{ui0bu(&`~P_&8A zu^C=Z?{t8mFzwv7e7z41j8M=BS0z4bF=GrxF)4YRn%fksDyD@l8Ny@j1J-WA&I>tH zx-^*JBE_h_jf-J|R>#}OZ93e05`hsDvrGJSxsEHQ_%7odGzjesL%OjMAZRmK-{)H+ zY6hohJdsv%9eMB_d9`$ecX_Iz#UpqFx8`7(-`OIa3 z3#de!z(+_h?>w`QjbojgA;vgAIpCm>B<@XE%RDo<;JD)1Eoj#BrPZqQaBZ`|-@A5K YgmltDr@AKK#eH<|!^geDudO`&Kj=8IY5)KL diff --git a/PLASMA-SYS2.PO b/PLASMA-SYS2.PO index ae737c2fb856c5444d399e6c2af52570557231f5..4aef3648c557b965bf423b8794513468e426b55f 100644 GIT binary patch delta 1942 zcmZvddr(w$6vxl`?IMqbWnE-ph1!%wWJP00!@=^&@*0HOf?=iM8m^h<18KE%lr=-G zwE;y=gUhlKPai<8wvCfh$@I|5Y8q>5#zGB2Uh>X=-0AM#c({0H?!CYJ+w(c+d%nNB zzgyVqQ`qX$oGuo>tB#*~oD-)B1FJYf7<@fC6XYe#*b}_EHG$^aBJ&;5!P^I0&HsoR zitP(xb3?J%ej=su?EqJ%2)F|vq`WeH{v$Jbh)7Jt4rlZY3B);0zde8fC(+rJ;duphFhvTh4UsL^q~iAEy78ihNNd^B&V$$H|=kpd{0=` zv1Ov}$B+sxQ2l2O#jPz)NcM@h%SLnx9;{!p-fz8; zHZ@>m@M!qn@$e|1<)<-H#AyQrX+@_oo(=oE9u#!rG-k6S{;o9%rTfj8L*-{s!UFu= zwi55Lgnl`LA?%t&SU1sGT#Gu=pXIrSe&jfd#cZ>mkSzBcZe-oQt`{wq9-PDNEY1C( zq9cuX6fG3egx?cu#7M`~X57W16`--@1yA%pFW4y8gz}xo>}dVJ^=5Shkkg7P`uRLA zW(K)KX2*QderelG(6*^zS=%hQ)ixUz-POQfcVpm2+dRl=kA=?mIJnh5A9~ssLQ+Qp zRCYWE4>}e@%Dttq>)vwMc`p$HI+LKTGX*~GOatsphm@`iNbKUErAr5@?rcczc@Ylx zybL#c)<8t>tFZ6xI!NtZ50$-n`{Bv^1}MJ&I{5d!0X}_Opsa5z-0Is78~XD>-(LVD z{YDt*-witl-hpicd*RQ4eel~rAuJg@03QqSTbaVo5MC(JyHcDBi_|u`?nS>bjZQ~ZGNP72kxJD zAP7tsgTa)e0Fy2RO!fR(9ttLf5=?bUC}~oKnZ8j$$#wqxRpluC47cEM8H@Y$5{7dN iJid6*t6bk7eix4u_9CYQePNTw9;UY=Yrw?TAz{A-2t()wR~*7=l`7IQ($}P}eQMet9C^^$ zR#%&-?-`_AospTHlHp3(-pi5m++!vlMmN7n!!5a2KQ}8qDND8Psn|Gp!?47y0P8cz zs4R5~pUDJjXDEbdkEx{X@nIB5#Nsfv89*i#!k|rj0tfl5m8SI^BM+JMZ6S#+%) zgX!yX6w;nD3}KNWRAoUqSq zEJ^AT64N`M<1W_ZM}~S#lW7B@3zZ^pIkeV~7PVm%wX~zZhq+V7^t7x2Bm8(9wSgvs zj8E^Tgm*lW9@e7i((KIF@m@E}>_wKQTDJLbbTDu}*p#r3`h<|<3! z<8YZOnlK!HrVCB@F3T75Dsoac<8tOHrjMKP2<{@Za$-v?_y&&C$`%ZxuPkWfs^sPt ztfRpe{N6_@E#1!*%Jea3F3{mq7;d|5#UjSLCX+=6aW%#4r$xPJqr-QNU?fdbe*pe=^J0UZ{D1fRtn2T%OPR30)85+g7oof=o|N}ffIk#!BNVw;YKW@ zGd3)aZS)7@tw1mq%fYx?0miG`b2$i%$-!X!Ef~yyhR!nn9SUX$1G7h%t>7$f!!OQZ lh&sXTV>myD|1@zIe7y6TvWw9hwzyqyns#JXtn*>Y{{fKdPA&id diff --git a/src/libsrc/apple/jit.pla b/src/libsrc/apple/jit.pla index 1cd6406..e22301b 100644 --- a/src/libsrc/apple/jit.pla +++ b/src/libsrc/apple/jit.pla @@ -29,7 +29,7 @@ const codemax = $BEE0 const indirectentry = $03DC const directentry = $03D0 // -// +// Copy bytecode DEF to main memory // def defcpy(dst, defptr)#0 *$003C = defptr=>bytecodeaddr diff --git a/src/libsrc/jitcore.pla b/src/libsrc/jitcore.pla index 7624607..ff34c7b 100644 --- a/src/libsrc/jitcore.pla +++ b/src/libsrc/jitcore.pla @@ -56,12 +56,13 @@ def compiler(defptr)#0 i = 0 while i <= defptr->bytecodesize if not ^(isdata+i) - when (^(bytecode+i) & $FE) + when ^(bytecode+i) & $FE // // Multi-byte operands // is $2E // CS - i = i + ^(bytecode+i+1)// + 1 + i++ + i = i + ^(bytecode+i) break // // Double byte operands @@ -824,7 +825,7 @@ def compiler(defptr)#0 fin VX-- // DEX if opcode == $68 - //puts("LAB $"); puth(*(bytecode+i)) + //puts("LAB $"); puth(dest) if VY <> 0 *codeptr = $00A0 // LDY #$00 codeptr = codeptr + 2 @@ -834,7 +835,7 @@ def compiler(defptr)#0 codeptr = codeptr + 2 else //puts("LAW $"); puth(dest) - codeptr->0 = $AD // LDA abs + codeptr->0 = $AD // LDA abs+1 codeptr=>1 = dest+1 codeptr=>3 = $C095+(VX<<8) // STA ESTKH,X codeptr = codeptr + 5 From 87a0b24d7a6ce8c32bd162aaa3f2394c98c21f06 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Wed, 4 Apr 2018 17:44:52 -0700 Subject: [PATCH 135/147] image update --- PLASMA-BLD2.PO | Bin 143360 -> 143360 bytes PLASMA-SYS2.PO | Bin 143360 -> 143360 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/PLASMA-BLD2.PO b/PLASMA-BLD2.PO index 1f04c2fbd28c019570349a41d9108a9f63f5d7dc..500cddb78409886c3c8d2c5662f338127583c843 100644 GIT binary patch delta 1151 zcmZva&ui0Q7{{MCeYzI5ickhM6E^L}#=5l%DpHt`C25zDym?Kc=onT(@a|tQ#G5jP z#mf#ob~iWH`)>XXo`k_pgL?1}*z`@hX!E=a1i}lS_xmH?ozvpZY4KxE@| zeoA5mavJnF2L{!P~+KvOfc+{ba{COhNh-uSmKE+%kRc z#Q%6>)G0m!2HzOb>Rki2oOL@G10PH9>u87n2RXbB6k#+Du1WBmDmFXHJUWW`io@-A zWmnz-EqN8ER~@S0jO+9ErWgOwgvFKwUlQ|!i_UC4JEI0H3-`IVCF%}0lfrOQ&M44G zUt(ABx)d7RPW9sbahQVN(**3PpdNB7w4eS%aa($=(2&Dj{b6Pe4VZ~%e^F4#lC;Z6-n=GJbPTH?c=s;xB#t~DB;#wGV?l}$L6k{Csp$_{YQS7T=JrvwBJu6ei zUr>hERRWGwaCxG<)M`PShS@R!Te>lqE095L_*DOb!#Va{`+UX{q)qXNWNX3&E8uSO z!W-j8@djw{Q6ozIQ^2;n?t~NIEeXCIukimIN2h@ziYLL_68uROTU})wUB!IG?&TDBa=IsUa~$8Gw}Ny0sAUwMBI*?yZ=z!mR>6~5Ei!y|96ec3f3K7|C#rjK&as6gfgLnxbHPvHX zB`-*?GQ(pA28bbtq)bpm5*d_T+=Cd9z`sleRt5uhuzG~Xd6*iNTwRc~F);iqVi00* zS3uMF21%m;$m&D}b=MFN*C5XTnC^d58Q2)kaG+_lIxL0e_{75)j@NbzFf%nU(sTBA zaRnL2wgl(~1|_&rU>hf|$JD6o77z-vA4LD##lXeDDFD|9W^Dd@SpE=tc&T{$xrQKV z{dbaqnc*rks?O;FZH(gP8_)tHkwMJMGbGdx>{PH3|L!s{GJIe}(>$+@5yPkAKK_30 zUcQJxyARaa3W-*DG);elMW=3mePhBU68JT4G-`nhS08yMZE*H34xUp9l0iRsC| zX|ovh7+bgN&tkkNn`q7?*f@!ap>Y#4!^GRH(i5H7gd1777#iES7$$z_l5RBQW@u#P zVQ8!b;>AGx0*G6L85*~XGBietF*JsVGc>LO;yDrwjS`X!jVmP?CT^6MZag8+F!2Hq yU)`R#gK;k7wq1-e0j6lVOEVOd)`2O;2;%R5+>D$InP}maxS5e@J>xPSCKUj4*X<1e delta 1012 zcmZvbO=uHQ5XWaWo0x2BNgGVs28}eqYK0n$u@F26W}9xP$(j#5>LLyF+KYIy&yVKf zp`o-Z0Rw{6o|<5gsNkhRK@d^ILl4D*;>8~Hpa-E3-)70zOBaS2hWDHK&%C#byY|Ih zdu3J>?*^v^R#Y)=1|>0I25*`fx7Ey4Bi4W8xLgf~t_?A_IRX{ z&ViBo2q#{v_lQ3|t)35uCMPZ>qq0%X_JnDG(N?KO$CYv~7?@VG&Hjd`uRsEas|7ZK z>VDn7#qTSqB;-s7O5cG6zF4|RU0p)&)F!tK4LorrlT9?FHcHSPK=_3mTw21ONxiel zL@a)}y|k~4yl-A>>zeev14xgWOl6d0OEUe*$di1}NFKR;>l#b()1OEuqG|a`yVzfF z!0&!;fbs$4SXxyKB~6qHD8jh4o2>2U(bDhS_6u_WgDw$X>&`XY@GW3Yd?sB_%wf*X z`~{jSK~6H_2l~e~te~P39d8TY>H0$ybfJh7n6I5J;-{lpSQsG70+5OY3fop+;iAn= z1PRDJ2?~ECA35U$V(9~Nli6ctKbYNd19^S~$W;%Jlo!Ybv*HjC&oGdu!%!&uedMhl v3Llt#uHATnkFZ8x;xRSM{avTB##?7EX40ISI?)01+`hCb3T0gH6N3K%01oo$ From 6c6dca33480d2702986f49ce3d4ce7c1a7472d62 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Wed, 4 Apr 2018 20:19:35 -0700 Subject: [PATCH 136/147] re-arrange a few things --- src/libsrc/jitcore.pla | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/src/libsrc/jitcore.pla b/src/libsrc/jitcore.pla index ff34c7b..dad5198 100644 --- a/src/libsrc/jitcore.pla +++ b/src/libsrc/jitcore.pla @@ -25,7 +25,7 @@ end // JIT compiler entry // def compiler(defptr)#0 - word codeptr, isdata, addrxlate, bytecode, i, case, dest, VX, VY + 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 @@ -38,7 +38,6 @@ def compiler(defptr)#0 return fin addrxlate = heapmark - memset(addrxlate, 0, 512) // Clear xlate buffer // // Copy bytecode def from AUX to heap for compiling // @@ -52,19 +51,13 @@ def compiler(defptr)#0 // All PLASMA ops are even (LSB clear), so this will flag when to fence optimizations // During compiling. // - isdata = addrxlate // Use this buffer + //isdata = addrxlate // Use this buffer + memset(isdata, 0, 256) // Clear isdata buffer i = 0 while i <= defptr->bytecodesize if not ^(isdata+i) when ^(bytecode+i) & $FE // - // Multi-byte operands - // - is $2E // CS - i++ - i = i + ^(bytecode+i) - break - // // Double byte operands // is $26 // LA @@ -81,7 +74,13 @@ def compiler(defptr)#0 is $B6 // ADDAW is $BC // IDXAB is $BE // IDXAW - i++ + i = i + 2 + break + // + // Multi-byte operands + // + is $2E // CS + i = i + ^(bytecode+i+1) // // Single byte operands // @@ -122,12 +121,9 @@ def compiler(defptr)#0 is $AC // BRAND is $AE // BROR i++ - // - // Flag branch destination - // dest = i + *(bytecode+i) - ^(bytecode+dest) = ^(bytecode+dest) | 1 i++ + ^(bytecode+dest) = ^(bytecode+dest) | 1 // Flag as branch dest break // // SELect/caseblock @@ -153,10 +149,10 @@ def compiler(defptr)#0 fin i++ loop - memset(isdata, 0, 256) // Clear part of xlate buffer used for isdata // // Compile the bytecodes // + memset(addrxlate, 0, 512) // Clear xlate buffer codeptr = *jitcodeptr A_IS_TOSL = FALSE VY = UNKNOWN // Virtual Y register From 558290100cc3722207269b3e1103eebcb70f837e Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Thu, 5 Apr 2018 11:20:43 -0700 Subject: [PATCH 137/147] Clear MSB for DLB/DAB --- src/libsrc/jitcore.pla | 37 +++++++++++++++++++++++-------------- src/samplesrc/rogue.map.pla | 4 ++-- src/vmsrc/apple/plvm01.s | 4 ++++ src/vmsrc/apple/plvm02.s | 35 +++++++++++++++++++++++++++++++++++ src/vmsrc/apple/plvm03.s | 4 ++++ src/vmsrc/apple/plvm802.s | 4 ++++ src/vmsrc/apple/plvmjit02.s | 35 +++++++++++++++++++++++++++++++++++ 7 files changed, 107 insertions(+), 16 deletions(-) diff --git a/src/libsrc/jitcore.pla b/src/libsrc/jitcore.pla index dad5198..43b7d50 100644 --- a/src/libsrc/jitcore.pla +++ b/src/libsrc/jitcore.pla @@ -312,21 +312,16 @@ def compiler(defptr)#0 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 + codeptr=>0 = $A9+(j<<8) // LDA #imm + codeptr->2 = $18 // CLC + codeptr=>3 = $E065 // ADC IFPL + codeptr=>5 = $D095+(VX<<8) // STA ESTKL,X if VY == 0 - codeptr->5 = $98 // TYA -> LDA #00 - codeptr = codeptr + 6 + codeptr->7 = $98 // TYA -> LDA #00 + codeptr = codeptr + 8 else - codeptr=>5 = $00A9 // LDA #$00 - codeptr = codeptr + 7 + codeptr=>7 = $00A9 // LDA #$00 + codeptr = codeptr + 9 fin codeptr=>0 = $E165 // ADC IFPH codeptr=>2 = $C095+(VX<<8) // STA ESTKH,X @@ -857,7 +852,14 @@ def compiler(defptr)#0 fin *codeptr = $E091 // STA (IFP),Y codeptr = codeptr + 2 - break + if VY <> 0 + *codeptr = $00A0 // LDY #$00 + codeptr = codeptr + 2 + VY = 0 + fin + *codeptr = $C094+(VX<<8) // STY ESTKH,X + codeptr = codeptr + 2 + break is $6E // DLW i++ j = ^(bytecode+i) @@ -973,6 +975,13 @@ def compiler(defptr)#0 if opcode == $7C //puts("DAB $"); puth(*(bytecode+i)) codeptr = codeptr + 3 + if VY <> 0 + *codeptr = $00A0 // LDY #$00 + codeptr = codeptr + 2 + VY = 0 + fin + *codeptr = $C094+(VX<<8) // STY ESTKH,X + codeptr = codeptr + 2 else codeptr=>3 = $C0B4+(VX<<8) // LDY ESTKH,X codeptr->5 = $8C // STY abs+1 diff --git a/src/samplesrc/rogue.map.pla b/src/samplesrc/rogue.map.pla index 3190296..0ddf1a9 100644 --- a/src/samplesrc/rogue.map.pla +++ b/src/samplesrc/rogue.map.pla @@ -260,8 +260,8 @@ end // export def drawmap(xorg, yorg, viewfield, viewdir, lightdist, viewdist) - byte o, l, dist, tile, adjtile, occluded, darkness - word ymap, xmap, imap + byte l, dist, tile, adjtile, occluded, darkness + word ymap, xmap, imap, o byte yscr, xscr if viewdist > beamdepth diff --git a/src/vmsrc/apple/plvm01.s b/src/vmsrc/apple/plvm01.s index 4e73678..e9e14d3 100644 --- a/src/vmsrc/apple/plvm01.s +++ b/src/vmsrc/apple/plvm01.s @@ -658,6 +658,8 @@ DLB INY ;+INC_IP TAY LDA ESTKL,X STA (IFP),Y + LDA #$00 + STA ESTKH,X LDY IPY JMP NEXTOP DLW INY ;+INC_IP @@ -718,6 +720,8 @@ DAB INY ;+INC_IP STA ESTKH-1,X LDA ESTKL,X STA (ESTKH-2,X) + LDA #$00 + STA ESTKH,X JMP NEXTOP DAW INY ;+INC_IP LDA (IP),Y diff --git a/src/vmsrc/apple/plvm02.s b/src/vmsrc/apple/plvm02.s index 758ff06..abb60cb 100755 --- a/src/vmsrc/apple/plvm02.s +++ b/src/vmsrc/apple/plvm02.s @@ -1448,6 +1448,8 @@ DLB INY ;+INC_IP TAY LDA ESTKL,X STA (IFP),Y + LDA #$00 + STA ESTKH,X LDY IPY JMP NEXTOP DLW INY ;+INC_IP @@ -1509,6 +1511,8 @@ DAB INY ;+INC_IP STA ESTKH-1,X LDA ESTKL,X STA (ESTKH-2,X) + LDA #$00 + STA ESTKH,X JMP NEXTOP DAW INY ;+INC_IP LDA (IP),Y @@ -2262,6 +2266,37 @@ CDAW INY ;+INC_IP LDY IPY JMP NEXTOP CDAWEND +; + LDA #DAB + LDY #(CDABEND-CDAB) + JSR OPCPY +CDAB INY ;+INC_IP + LDA (IP),Y + STA ESTKH-2,X + INY ;+INC_IP + LDA (IP),Y + STA ESTKH-1,X + LDA ESTKL,X + STA (ESTKH-2,X) + STZ ESTKH,X + JMP NEXTOP +CDABEND +; + LDA #DLB + LDY #(CDLBEND-CDLB) + JSR OPCPY +CDLB INY ;+INC_IP + LDA (IP),Y + STY IPY + TAY + LDA ESTKL,X + STA (IFP),Y + STZ ESTKH,X + LDY IPY + JMP NEXTOP +CDLBEND ; LDA #ISFLS diff --git a/src/vmsrc/apple/plvm03.s b/src/vmsrc/apple/plvm03.s index 3059570..a62f8a0 100755 --- a/src/vmsrc/apple/plvm03.s +++ b/src/vmsrc/apple/plvm03.s @@ -984,6 +984,8 @@ DLB INY ;+INC_IP TAY LDA ESTKL,X STA (IFP),Y + LDA #$00 + STA ESTKH,X LDY IPY JMP NEXTOP DLW INY ;+INC_IP @@ -1044,6 +1046,8 @@ DAB INY ;+INC_IP STA ESTKH-1,X LDA ESTKL,X STA (ESTKH-2,X) + LDA #$00 + STA ESTKH,X JMP NEXTOP DAW INY ;+INC_IP LDA (IP),Y diff --git a/src/vmsrc/apple/plvm802.s b/src/vmsrc/apple/plvm802.s index 9f8b860..3dc02a5 100644 --- a/src/vmsrc/apple/plvm802.s +++ b/src/vmsrc/apple/plvm802.s @@ -1262,6 +1262,8 @@ DLB INY ;+INC_IP LDA TOS,S STA (IFP),Y +ACCMEM16 ; 16 BIT A/M + AND #$00FF + STA TOS,S TXY JMP NEXTOP DLW INY ;+INC_IP @@ -1304,6 +1306,8 @@ DAB INY ;+INC_IP LDA TOS,S STA (TMP) +ACCMEM16 ; 16 BIT A/M + AND #$00FF + STA TOS,S INY ;+INC_IP JMP NEXTOP DAW INY ;+INC_IP diff --git a/src/vmsrc/apple/plvmjit02.s b/src/vmsrc/apple/plvmjit02.s index 979ef67..7a0bac2 100755 --- a/src/vmsrc/apple/plvmjit02.s +++ b/src/vmsrc/apple/plvmjit02.s @@ -1511,6 +1511,8 @@ DLB INY ;+INC_IP TAY LDA ESTKL,X STA (IFP),Y + LDA #$00 + STA ESTKH,X LDY IPY JMP NEXTOP DLW INY ;+INC_IP @@ -1572,6 +1574,8 @@ DAB INY ;+INC_IP STA ESTKH-1,X LDA ESTKL,X STA (ESTKH-2,X) + LDA #$00 + STA ESTKH,X JMP NEXTOP DAW INY ;+INC_IP LDA (IP),Y @@ -2304,6 +2308,37 @@ CDAW INY ;+INC_IP LDY IPY JMP NEXTOP CDAWEND +; + LDA #DAB + LDY #(CDABEND-CDAB) + JSR OPCPY +CDAB INY ;+INC_IP + LDA (IP),Y + STA ESTKH-2,X + INY ;+INC_IP + LDA (IP),Y + STA ESTKH-1,X + LDA ESTKL,X + STA (ESTKH-2,X) + STZ ESTKH,X + JMP NEXTOP +CDABEND +; + LDA #DLB + LDY #(CDLBEND-CDLB) + JSR OPCPY +CDLB INY ;+INC_IP + LDA (IP),Y + STY IPY + TAY + LDA ESTKL,X + STA (IFP),Y + STZ ESTKH,X + LDY IPY + JMP NEXTOP +CDLBEND ; LDA #ISFLS From e3606f3f64ffc53a33fa694e2b2b7bf2c13237cf Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Thu, 5 Apr 2018 11:51:53 -0700 Subject: [PATCH 138/147] Fix byte variable used in negative FOR/NEXT --- src/samplesrc/rogue.map.pla | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/samplesrc/rogue.map.pla b/src/samplesrc/rogue.map.pla index b068fe1..e110ff4 100644 --- a/src/samplesrc/rogue.map.pla +++ b/src/samplesrc/rogue.map.pla @@ -260,8 +260,8 @@ end // export def drawmap(xorg, yorg, viewfield, viewdir, lightdist, viewdist) - byte o, l, dist, tile, adjtile, occluded, darkness - word ymap, xmap, imap + byte l, dist, tile, adjtile, occluded, darkness + word ymap, xmap, imap, o byte yscr, xscr if viewdist > beamdepth From f35f0b3bbaba79f0e573f58d5c7f765e45442e46 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Fri, 6 Apr 2018 08:05:23 -0700 Subject: [PATCH 139/147] Fix OBO in branch calc loop and free up bytes to re-enable LLA opt --- PLASMA-SOS2.PO | Bin 143360 -> 143360 bytes src/libsrc/jitcore.pla | 67 +++++++++++++++++++++-------------------- 2 files changed, 34 insertions(+), 33 deletions(-) diff --git a/PLASMA-SOS2.PO b/PLASMA-SOS2.PO index 4c07b34050b41a6c362c7496dcc8b3238f895ce1..785a5504afb08463e4dad1f94e60b865c31aab0c 100644 GIT binary patch delta 11623 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 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 @@ -37,14 +39,12 @@ def compiler(defptr)#0 defptr=>interpaddr = indirectentry return fin - addrxlate = heapmark // // 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 // @@ -54,8 +54,9 @@ def compiler(defptr)#0 //isdata = addrxlate // Use this buffer memset(isdata, 0, 256) // Clear isdata buffer i = 0 - while i <= defptr->bytecodesize + 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 @@ -153,6 +154,7 @@ def compiler(defptr)#0 // Compile the bytecodes // memset(addrxlate, 0, 512) // Clear xlate buffer + //puts("Bytecode: $"); puth(bytecode); putln; getc codeptr = *jitcodeptr A_IS_TOSL = FALSE VY = UNKNOWN // Virtual Y register @@ -288,9 +290,8 @@ def compiler(defptr)#0 break is $26 // LA is $2C // CW - i++ - dest = *(bytecode+i) - i++ + dest = *(bytecode+i+1) + i = i + 2 //puts("LA/CW $"); puth(dest) if A_IS_TOSL & TOS_DIRTY *codeptr = $D095+(VX<<8) // STA ESTKL,X @@ -312,16 +313,22 @@ def compiler(defptr)#0 codeptr = codeptr + 2 fin VX-- // DEX - codeptr=>0 = $A9+(j<<8) // LDA #imm - codeptr->2 = $18 // CLC - codeptr=>3 = $E065 // ADC IFPL - codeptr=>5 = $D095+(VX<<8) // STA ESTKL,X - if VY == 0 - codeptr->7 = $98 // TYA -> LDA #00 - codeptr = codeptr + 8 + if VY == j + ^codeptr = $98; codeptr++ // TYA -> LDA #imm + else - codeptr=>7 = $00A9 // LDA #$00 - codeptr = codeptr + 9 + *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 @@ -658,7 +665,6 @@ def compiler(defptr)#0 A_IS_TOSL = FALSE break is $54 // CALL - i++ //puts("CALL $"); puth(*(bytecode+i)) // // Call address @@ -669,11 +675,11 @@ def compiler(defptr)#0 codeptr = codeptr + 2 fin codeptr->0 = $20 // JSR abs - codeptr=>1 = *(bytecode+i) + codeptr=>1 = *(bytecode+i+1) codeptr = codeptr + 3 VY = UNKNOWN A_IS_TOSL = FALSE - i++ + i = i + 2 break is $56 // ICAL //puts("ICAL") @@ -807,9 +813,8 @@ def compiler(defptr)#0 break is $68 // LAB is $6A // LAW - i++ - dest = *(bytecode+i) - i++ + dest = *(bytecode+i+1) + i = i + 2 if A_IS_TOSL & TOS_DIRTY *codeptr = $D095+(VX<<8) // STA ESTKL,X codeptr = codeptr + 2 @@ -937,9 +942,8 @@ def compiler(defptr)#0 break is $78 // SAB is $7A // SAW - i++ - dest = *(bytecode+i) - i++ + dest = *(bytecode+i+1) + i = i + 2 //puts("SAW $"); puth(dest) if not A_IS_TOSL *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X @@ -961,9 +965,8 @@ def compiler(defptr)#0 break is $7C // DAB is $7E // DAW - i++ - dest = *(bytecode+i) - i++ + dest = *(bytecode+i+1) + i = i + 2 //puts("DAW $"); puth(*(bytecode+i)) if not A_IS_TOSL *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X @@ -1386,9 +1389,8 @@ def compiler(defptr)#0 break is $B4 // ADDAB is $B6 // ADDAW - i++ - dest = *(bytecode+i) - i++ + dest = *(bytecode+i+1) + i = i + 2 if not A_IS_TOSL *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 @@ -1498,9 +1500,8 @@ def compiler(defptr)#0 i++ break is $BE // IDXAW - i++ - dest = *(bytecode+i) - i++ + dest = *(bytecode+i+1) + i = i + 2 //puts("IDXAW $"); puth(dest) if A_IS_TOSL & TOS_DIRTY *codeptr = $D095+(VX<<8) // STA ESTKL,X From 625ce2704e2aacd49cd707ba96bf4b85cfb21d26 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Fri, 6 Apr 2018 08:25:42 -0700 Subject: [PATCH 140/147] Sync cleanjit with jitcore --- src/libsrc/apple/cleanjit.pla | 96 +++++++++++++++++++---------------- src/libsrc/jitcore.pla | 14 ++--- 2 files changed, 58 insertions(+), 52 deletions(-) diff --git a/src/libsrc/apple/cleanjit.pla b/src/libsrc/apple/cleanjit.pla index 8a86ff2..d8a6cb3 100644 --- a/src/libsrc/apple/cleanjit.pla +++ b/src/libsrc/apple/cleanjit.pla @@ -87,16 +87,10 @@ def compiler(defptr)#0 // isdata = addrxlate // Use this buffer i = 0 - while i <= defptr->bytecodesize + 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 @@ -113,7 +107,13 @@ def compiler(defptr)#0 is $B6 // ADDAW is $BC // IDXAB is $BE // IDXAW - i++ + i = i + 2 + break + // + // Multi-byte operands + // + is $2E // CS + i = i + ^(bytecode+i+1) // // Single byte operands // @@ -340,8 +340,8 @@ def compiler(defptr)#0 break is $26 // LA is $2C // CW - i++ - dest = *(bytecode+i) + dest = *(bytecode+i+1) + i = i + 2 //puts("LA/CW $"); puth(dest) if A_IS_TOSL & TOS_DIRTY *codeptr = $D095+(VX<<8) // STA ESTKL,X @@ -353,7 +353,6 @@ def compiler(defptr)#0 codeptr=>4 = $A9+(dest<<8) // LDA #>VAL codeptr = codeptr + 6 A_IS_TOSL = TOS_DIRTY // STA ESTKL,X - i++ break is $28 // LLA i++ @@ -758,7 +757,6 @@ def compiler(defptr)#0 A_IS_TOSL = FALSE break is $54 // CALL - i++ //puts("CALL $"); puth(*(bytecode+i)) // // Call address @@ -769,11 +767,11 @@ def compiler(defptr)#0 codeptr = codeptr + 2 fin codeptr->0 = $20 // JSR abs - codeptr=>1 = *(bytecode+i) + codeptr=>1 = *(bytecode+i+1) codeptr = codeptr + 3 VY = UNKNOWN A_IS_TOSL = FALSE - i++ + i = i + 2 break is $56 // ICAL //puts("ICAL") @@ -941,8 +939,8 @@ def compiler(defptr)#0 i++ break is $6A // LAW - i++ - dest = *(bytecode+i) + dest = *(bytecode+i+1) + i = i + 2 //puts("LAW $"); puth(dest) if A_IS_TOSL & TOS_DIRTY *codeptr = $D095+(VX<<8) // STA ESTKL,X @@ -956,7 +954,6 @@ def compiler(defptr)#0 codeptr=>6 = dest codeptr = codeptr + 8 A_IS_TOSL = TOS_DIRTY // STA ESTKL,X - i++ break is $6C // DLB i++ @@ -968,11 +965,18 @@ def compiler(defptr)#0 A_IS_TOSL = TOS_CLEAN fin if VY <> j - *codeptr = $A0+(j<<8) // LDY #imm + *codeptr = $A0+(j<<8) // LDY #imm codeptr = codeptr + 2 VY = j fin - *codeptr = $E091 // STA (IFP),Y + *codeptr = $E091 // STA (IFP),Y + codeptr = codeptr + 2 + if VY <> 0 + *codeptr = $00A0 // LDY #$00 + codeptr = codeptr + 2 + VY = 0 + fin + *codeptr = $C094+(VX<<8) // STY ESTKH,X codeptr = codeptr + 2 break is $6E // DLW @@ -1069,22 +1073,22 @@ def compiler(defptr)#0 A_IS_TOSL = FALSE break is $78 // SAB - i++ + dest = *(bytecode+i+1) + i = i + 2 //puts("SAB $"); puth(*(bytecode+i)) if not A_IS_TOSL *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin codeptr->0 = $8D // STA abs - codeptr=>1 = *(bytecode+i) + codeptr=>1 = dest codeptr = codeptr + 3 VX++ // INX A_IS_TOSL = FALSE - i++ break is $7A // SAW - i++ - dest = *(bytecode+i) + dest = *(bytecode+i+1) + i = i + 2 //puts("SAW $"); puth(dest) if not A_IS_TOSL *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X @@ -1098,24 +1102,29 @@ def compiler(defptr)#0 codeptr = codeptr + 8 VX++ // INX A_IS_TOSL = FALSE - i++ break is $7C // DAB - i++ + dest = *(bytecode+i+1) + i = i + 2 //puts("DAB $"); puth(*(bytecode+i)) if not A_IS_TOSL *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 A_IS_TOSL = TOS_CLEAN fin + if VY <> 0 + *codeptr = $00A0 // LDY #$00 + codeptr = codeptr + 2 + VY = 0 + fin codeptr->0 = $8D // STA abs - codeptr=>1 = *(bytecode+i) - codeptr = codeptr + 3 - i++ + codeptr=>1 = dest + codeptr=>3 = $C094+(VX<<8) // STY ESTKH,X + codeptr = codeptr + 5 break is $7E // DAW - i++ - dest = *(bytecode+i) + dest = *(bytecode+i+1) + i = i + 2 //puts("DAW $"); puth(*(bytecode+i)) if not A_IS_TOSL *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X @@ -1129,7 +1138,6 @@ def compiler(defptr)#0 codeptr=>6 = dest+1 codeptr = codeptr + 8 VY = UNKNOWN - i++ break is $80 // NOT //puts("NOT") @@ -1630,24 +1638,23 @@ def compiler(defptr)#0 A_IS_TOSL = FALSE break is $B4 // ADDAB - i++ + dest = *(bytecode+i+1) + i = i + 2 //puts("ADDAB $"); puth(*(bytecode+i)) if not A_IS_TOSL *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X codeptr = codeptr + 2 fin codeptr=>0 = $6D18 // CLC; ADC abs - codeptr=>2 = *(bytecode+i) + codeptr=>2 = dest codeptr=>4 = $0290 // BCC +2 codeptr=>6 = $C0F6+(VX<<8) // INC ESTKH,X codeptr = codeptr + 8 A_IS_TOSL = TOS_DIRTY // STA ESTKL,X - i++ break is $B6 // ADDAW - i++ - dest = *(bytecode+i) - i++ + dest = *(bytecode+i+1) + i = i + 2 //puts("ADDAW $"); puth(dest) if not A_IS_TOSL *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X @@ -1723,7 +1730,8 @@ def compiler(defptr)#0 A_IS_TOSL = FALSE break is $BC // IDXAB - i++ + dest = *(bytecode+i+1) + i = i + 2 //puts("IDXAB $"); puth(*(bytecode+i)) if A_IS_TOSL & TOS_DIRTY *codeptr = $D095+(VX<<8) // STA ESTKL,X @@ -1734,7 +1742,7 @@ def compiler(defptr)#0 codeptr = codeptr + 2 fin codeptr->0 = $AD // LDA abs - codeptr=>1 = *(bytecode+i) + codeptr=>1 = dest codeptr->3 = $0A // ASL codeptr=>4 = $0290 // BCC +2 codeptr=>6 = $18C8 // INY; CLC @@ -1746,12 +1754,10 @@ def compiler(defptr)#0 codeptr = codeptr + 17 VY = UNKNOWN A_IS_TOSL = FALSE - i++ break - is $BE - i++ - dest = *(bytecode+i) - i++ + is $BE // IDXAW + dest = *(bytecode+i+1) + i = i + 2 //puts("IDXAW $"); puth(dest) if A_IS_TOSL & TOS_DIRTY *codeptr = $D095+(VX<<8) // STA ESTKL,X diff --git a/src/libsrc/jitcore.pla b/src/libsrc/jitcore.pla index 752caeb..ccfc336 100644 --- a/src/libsrc/jitcore.pla +++ b/src/libsrc/jitcore.pla @@ -851,18 +851,18 @@ def compiler(defptr)#0 A_IS_TOSL = TOS_CLEAN fin if VY <> j - *codeptr = $A0+(j<<8) // LDY #imm + *codeptr = $A0+(j<<8) // LDY #imm codeptr = codeptr + 2 VY = j fin - *codeptr = $E091 // STA (IFP),Y + *codeptr = $E091 // STA (IFP),Y codeptr = codeptr + 2 if VY <> 0 - *codeptr = $00A0 // LDY #$00 + *codeptr = $00A0 // LDY #$00 codeptr = codeptr + 2 VY = 0 fin - *codeptr = $C094+(VX<<8) // STY ESTKH,X + *codeptr = $C094+(VX<<8) // STY ESTKH,X codeptr = codeptr + 2 break is $6E // DLW @@ -1474,7 +1474,8 @@ def compiler(defptr)#0 A_IS_TOSL = FALSE break is $BC // IDXAB - i++ + dest = *(bytecode+i+1) + i = i + 2 //puts("IDXAB $"); puth(*(bytecode+i)) if A_IS_TOSL & TOS_DIRTY *codeptr = $D095+(VX<<8) // STA ESTKL,X @@ -1485,7 +1486,7 @@ def compiler(defptr)#0 codeptr = codeptr + 2 fin codeptr->0 = $AD // LDA abs - codeptr=>1 = *(bytecode+i) + codeptr=>1 = dest codeptr->3 = $0A // ASL codeptr=>4 = $0290 // BCC +2 codeptr=>6 = $18C8 // INY; CLC @@ -1497,7 +1498,6 @@ def compiler(defptr)#0 codeptr = codeptr + 17 VY = UNKNOWN A_IS_TOSL = FALSE - i++ break is $BE // IDXAW dest = *(bytecode+i+1) From 2a015d98cf55fccbba1e7af2a97ca9c30364aa5a Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Fri, 6 Apr 2018 09:13:55 -0700 Subject: [PATCH 141/147] Update images --- PLASMA-SOS2.PO | Bin 143360 -> 143360 bytes PLASMA-SYS2.PO | Bin 143360 -> 143360 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/PLASMA-SOS2.PO b/PLASMA-SOS2.PO index 785a5504afb08463e4dad1f94e60b865c31aab0c..2f0823094c040e046fe7b7b897c6a71be136e058 100644 GIT binary patch delta 9560 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 S^01#XiyJAro;o0>wf_r-;vSFy delta 9168 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 LZ#Sc$TORyB%Gi Date: Fri, 6 Apr 2018 12:42:48 -0700 Subject: [PATCH 142/147] 65802 requires 128K and JITC --- src/vmsrc/apple/plvm03.s | 2 +- src/vmsrc/apple/plvm802.s | 196 ++++++++++++++++++++++++++++++------ src/vmsrc/apple/plvmjit02.s | 2 +- 3 files changed, 168 insertions(+), 32 deletions(-) diff --git a/src/vmsrc/apple/plvm03.s b/src/vmsrc/apple/plvm03.s index a62f8a0..920c57b 100755 --- a/src/vmsrc/apple/plvm03.s +++ b/src/vmsrc/apple/plvm03.s @@ -229,7 +229,7 @@ JITINTRP PLA STA TMPH PLA STA TMPL - JMP JMPTMP ; RE-CALL ORIGINAL DEF ENTRY + JMP (TMP) ; RE-CALL ORIGINAL DEF ENTRY ;* ;* INTERNAL DIVIDE ALGORITHM ;* diff --git a/src/vmsrc/apple/plvm802.s b/src/vmsrc/apple/plvm802.s index 3dc02a5..ee1d012 100644 --- a/src/vmsrc/apple/plvm802.s +++ b/src/vmsrc/apple/plvm802.s @@ -65,6 +65,8 @@ OPPAGE = OPIDX+1 ; STRBUF = $0280 INTERP = $03D0 +JITCOMP = $03E2 +JITCODE = $03E4 ;* ;* HARDWARE STACK OFFSETS ;* @@ -88,18 +90,35 @@ NOS = $03 ; TOS-1 ;****************************** * = $2000 ;* -;* CHECK CPU TYPE +;* MUST HAVE 128K FOR JIT ;* - CLC - XCE ; SWITCH TO NATIVE MODE - BCS ++ ; NOPE, NOT 65802/65816 ++ LDA MACHID + AND #$30 + CMP #$30 + BEQ ++ LDY #$00 -- LDA BADCPU,Y +- LDA NEEDAUX,Y BEQ + ORA #$80 JSR $FDED INY BNE - + LDY #ANYKEY-BADCPU + BNE +++ +NEEDAUX !TEXT "128K MEMORY REQUIRED.", 13, 0 +;* +;* CHECK CPU TYPE +;* +++ CLC + XCE ; SWITCH TO NATIVE MODE + BCS ++ + LDY #$00 ; NOPE, NOT 65802/65816 +- LDA BADCPU,Y + BEQ + + ORA #$80 + JSR $FDED + INY ++++ BNE - + LDA $C000 BPL - LDA $C010 @@ -112,7 +131,7 @@ BYEPARMS !BYTE 4 !BYTE 0 !WORD 0 BADCPU !TEXT "65C802/65C816 CPU REQUIRED.", 13 - !TEXT "PRESS ANY KEY...", 0 +ANYKEY !TEXT "PRESS ANY KEY...", 0 ++ XCE ; SWITCH BACK TO EMULATED MODE ;* @@ -193,7 +212,7 @@ RAMDONE ;CLI UNTIL I KNOW WHAT TO DO WITH THE UNENHANCED IIE JSR PRODOS ; GET PREFIX !BYTE $C7 !WORD GETPFXPARMS - LDY STRBUF ; APPEND "CMD" + LDY STRBUF ; APPEND "CMDJIT" LDA #"/" CMP STRBUF,Y BEQ + @@ -208,6 +227,15 @@ RAMDONE ;CLI UNTIL I KNOW WHAT TO DO WITH THE UNENHANCED IIE LDA #"D" INY STA STRBUF,Y + LDA #"J" + INY + STA STRBUF,Y + LDA #"I" + INY + STA STRBUF,Y + LDA #"T" + INY + STA STRBUF,Y STY STRBUF BIT LCRWEN+LCBNK2 ; COPY TO LC FOR BYE BIT LCRWEN+LCBNK2 @@ -243,30 +271,30 @@ OPTBL !WORD CN,CN,CN,CN,CN,CN,CN,CN ; 00 02 !WORD NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 90 92 94 96 98 9A 9C 9E !WORD BRGT,BRLT,INCBRLE,ADDBRLE,DECBRGE,SUBBRGE,BRAND,BROR ; A0 A2 A4 A6 A8 AA AC AE !WORD ADDLB,ADDLW,ADDAB,ADDAW,IDXLB,IDXLW,IDXAB,IDXAW ; B0 B2 B4 B6 B8 BA BC BE + !WORD NATV ; C0 ;* ;* ENTER INTO BYTECODE INTERPRETER - IMMEDIATELY SWITCH TO NATIVE ;* !AS -IINTRP PHP +DINTRP PHP PLA STA PSR SEI CLC ; SWITCH TO NATIVE MODE XCE +ACCMEM16 ; 16 BIT A/M - LDY #$01 - LDA (TOS,S),Y - DEY - STA IP PLA + INC + STA IP STX ESP TSX STX HWSP LDX #>OPTBL !IF DEBUG { - BRA SETDBG + JMP SETDBG } ELSE { STX OPPAGE + LDY #$00 JMP FETCHOP } !AS @@ -330,9 +358,6 @@ CMDENTRY = * !IF DEBUG { LDA #20 ; SET TEXT WINDOW ABOVE DEBUG OUTPUT STA $23 -; LDA $BF98 ; FORCE 64K -; AND #$CF -; STA $BF98 } ; ; INSTALL PAGE 0 FETCHOP ROUTINE @@ -379,11 +404,11 @@ CMDENTRY = * ; ; INIT VM ENVIRONMENT STACK POINTERS ; -; LDA #$00 +; LDA #$00 STA $01FF ; CLEAR CMDLINE BUFF STA PPL ; INIT FRAME POINTER STA IFPL - LDA #$BF + LDA #$AF ; FRAME POINTER AT $AF00, BELOW JIT BUFFER STA PPH STA IFPH LDX #$FE ; INIT STACK POINTER (YES, $FE. SEE GETS) @@ -394,7 +419,7 @@ CMDENTRY = * ; LDA STRBUF SEC - SBC #$03 + SBC #$06 STA STRBUF JMP $2000 ; JUMP TO LOADED SYSTEM COMMAND ; @@ -441,8 +466,8 @@ PAGE3 = * !PSEUDOPC $03D0 { BIT LCRDEN+LCBNK2 ; $03D0 - DIRECT INTERP ENTRY JMP DINTRP - BIT LCRDEN+LCBNK2 ; $03D6 - INDIRECT INTERP ENTRY - JMP IINTRP + BIT LCRDEN+LCBNK2 ; $03D6 - JIT INDIRECT INTERPX ENTRY + JMP JITINTRPX BIT LCRDEN+LCBNK2 ; $03DC - INDIRECT INTERPX ENTRY JMP IINTRPX } @@ -476,28 +501,85 @@ OPXTBL !WORD CN,CN,CN,CN,CN,CN,CN,CN ; 00 02 !WORD NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 90 92 94 96 98 9A 9C 9E !WORD BRGT,BRLT,INCBRLE,ADDBRLE,DECBRGE,SUBBRGE,BRAND,BROR ; A0 A2 A4 A6 A8 AA AC AE !WORD ADDLBX,ADDLWX,ADDABX,ADDAWX,IDXLBX,IDXLWX,IDXABX,IDXAWX ; B0 B2 B4 B6 B8 BA BC BE - !AS -DINTRP PHP + !WORD NATV ; C0 +;* +;* JIT PROFILING ENTRY INTO INTERPRETER +;* +JITINTRPX PHP PLA STA PSR SEI + PLA + SEC + SBC #$02 ; POINT TO DEF ENTRY + STA TMPL + PLA + SBC #$00 + STA TMPH + LDY #$05 + LDA (TMP),Y ; DEC JIT COUNT + DEC + STA (TMP),Y + BEQ RUNJIT CLC ; SWITCH TO NATIVE MODE XCE +ACCMEM16 ; 16 BIT A/M - PLA - INC + LDY #$3 ; INTERP BYTECODE AS USUAL + LDA (TMP),Y STA IP STX ESP TSX STX HWSP - LDX #>OPTBL + STX ALTRDON + LDX #>OPXTBL !IF DEBUG { - JMP SETDBG -} ELSE { +SETDBG LDY LCRWEN+LCBNK2 + LDY LCRWEN+LCBNK2 + STX DBG_OP+2 + LDY LCRDEN+LCBNK2 + LDX #>DBGTBL +} STX OPPAGE LDY #$00 JMP FETCHOP +; + !AS +RUNJIT DEX ; ADD PARAMETER TO DEF ENTRY + LDA TMPL + PHA ; AND SAVE IT FOR LATER + STA ESTKL,X + LDA TMPH + PHA + STA ESTKH,X + CLC ; SWITCH TO NATIVE MODE + XCE + +ACCMEM16 ; 16 BIT A/M + LDA JITCOMP + STA SRC + LDY #$03 + LDA (SRC),Y + STA IP + STX ESP + TSX + STX HWSP + STX ALTRDON + LDX #>OPXTBL +!IF DEBUG { +SETDBG LDY LCRWEN+LCBNK2 + LDY LCRWEN+LCBNK2 + STX DBG_OP+2 + LDY LCRDEN+LCBNK2 + LDX #>DBGTBL } + STX OPPAGE + LDY #$00 + JSR FETCHOP ; CALL JIT COMPILER + !AS + PLA + STA TMPH + PLA + STA TMPL + JMP (TMP) ; RE-CALL ORIGINAL DEF ENTRY ;********************************************************************* ;* ;* CODE BELOW HERE DEFAULTS TO NATIVE 16 BIT A/M, 8 BIT X,Y @@ -1823,7 +1905,7 @@ LEAVEX INY ;+INC_IP BEQ + LDX #$80+'L' STX $7D0+30 -- LDX $C000 +- LDX $C000 BPL - LDX $C010 + @@ -1882,7 +1964,7 @@ RET SEC ; SWITCH TO EMULATION MODE BEQ + LDX #$80+'X' STX $7D0+30 -- LDX $C000 +- LDX $C000 BPL - LDX $C010 + @@ -1892,6 +1974,59 @@ RET SEC ; SWITCH TO EMULATION MODE PHA PLP RTS +;* +;* RETURN TO NATIVE CODE +;* +NATV TYA ; FLATTEN IP + SEC + ADC IP + STA IP + SEC ; SWITCH TO EMULATION MODE + XCE + !AS + ;+ACCMEM8 ; 8 BIT A/M + TSC ; MOVE HW EVAL STACK TO ZP EVAL STACK + EOR #$FF + SEC + ADC HWSP ; STACK DEPTH = (HWSP - SP)/2 + LSR +!IF DEBUG { + PHA + CLC + ADC #$80+'0' + STA $7D0+31 + PLA +} + EOR #$FF + SEC + ADC ESP ; ESP - STACK DEPTH + TAX + CPX ESP + BEQ ++ + TAY +- PLA + STA ESTKL,X + PLA + STA ESTKH,X + INX + CPX ESP + BNE - +!IF DEBUG { + TSX + CPX HWSP + BEQ + + LDX #$80+'V' + STX $7D0+30 +- LDX $C000 + BPL - + LDX $C010 ++ +} + TYX +++ LDA PSR + PHA + PLP + JMP (IP) !IF DEBUG { ;***************** ;* * @@ -1911,6 +2046,7 @@ DBGTBL !WORD STEP,STEP,STEP,STEP,STEP,STEP,STEP,STEP ; 00 02 04 06 08 !WORD STEP,STEP,STEP,STEP,STEP,STEP,STEP,STEP ; 90 92 94 96 98 9A 9C 9E !WORD STEP,STEP,STEP,STEP,STEP,STEP,STEP,STEP ; A0 A2 A4 A6 A8 AA AC AE !WORD STEP,STEP,STEP,STEP,STEP,STEP,STEP,STEP ; B0 B2 B4 B6 B8 BA BC BE + !WORD STEP ; C0 ;* ;* DEBUG PRINT ROUTINES ;* diff --git a/src/vmsrc/apple/plvmjit02.s b/src/vmsrc/apple/plvmjit02.s index 7a0bac2..e00b664 100755 --- a/src/vmsrc/apple/plvmjit02.s +++ b/src/vmsrc/apple/plvmjit02.s @@ -483,7 +483,7 @@ RUNJIT LDA JITCOMP STA TMPH PLA STA TMPL - JMP JMPTMP ; RE-CALL ORIGINAL DEF ENTRY + JMP (TMP) ; RE-CALL ORIGINAL DEF ENTRY ;* ;* ADD TOS TO TOS-1 ;* From 11dc4abcdab1bfaa331f705ac59175e43419b764 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Fri, 6 Apr 2018 12:45:34 -0700 Subject: [PATCH 143/147] 65802 JITC placeholders --- src/libsrc/apple/jit16.pla | 51 ++ src/libsrc/jit16core.pla | 1563 ++++++++++++++++++++++++++++++++++++ 2 files changed, 1614 insertions(+) create mode 100644 src/libsrc/apple/jit16.pla create mode 100644 src/libsrc/jit16core.pla diff --git a/src/libsrc/apple/jit16.pla b/src/libsrc/apple/jit16.pla new file mode 100644 index 0000000..e22301b --- /dev/null +++ b/src/libsrc/apple/jit16.pla @@ -0,0 +1,51 @@ +// +// PLASMA JIT bytecode compiler +// +include "inc/cmdsys.plh" +// +// Module don't free memory +// +const modkeep = $2000 +const modinitkeep = $4000 +// +// Indirect interpreter DEFinition entrypoint +// +struc t_defentry + byte interpjsr + word interpaddr + word bytecodeaddr + byte callcount + byte bytecodesize +end +// +// JIT compiler constants +// +const jitcomp = $03E2 +const jitcodeptr = $03E4 +const codemax = $BEE0 +// +// Bytecode interpreter entrypoints +// +const indirectentry = $03DC +const directentry = $03D0 +// +// Copy bytecode DEF to main memory +// +def defcpy(dst, defptr)#0 + *$003C = defptr=>bytecodeaddr + *$003E = *$003C + defptr->bytecodesize + *$0042 = dst + call($C311, 0, 0, 0, $04) // CALL XMOVE with carry clear (AUX->MAIN) and ints disabled +end +include "libsrc/jitcore.pla" +// +// Install JIT compiler +// +if *jitcomp + return 0 +fin +*jitcomp = @compiler +cmdsys.jitcount = 44 +cmdsys.jitsize = 96 +return modkeep +done diff --git a/src/libsrc/jit16core.pla b/src/libsrc/jit16core.pla new file mode 100644 index 0000000..ccfc336 --- /dev/null +++ b/src/libsrc/jit16core.pla @@ -0,0 +1,1563 @@ +// +// 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 + 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_TOSL = FALSE + VY = UNKNOWN // Virtual Y register + VX = 0 // Virtual X register + i = 0 + if ^bytecode == $58 + //putc('$'); puth(codeptr);//puts(":[0] ENTER "); puti(^(bytecode+1)); putc(',');puti(^(bytecode+2)); putln + // + // Call into VM + // + codeptr->0 = $20 // JSR INTERP + codeptr=>1 = directentry + codeptr->3 = $58 // ENTER CODE + codeptr=>4 = *(bytecode+1) // ENTER FRAME SIZE & ARG COUNT + codeptr->6 = $C0 // NATV CODE + codeptr = codeptr + 7 + i = 3 + fin + while isule(codeptr, codemax) + //putc('$'); puth(codeptr); putc(':') + //putc('['); puti(i); //puts("] ") + opcode = ^(bytecode+i) + if opcode & 1 + // + // Optimization fence. Sync A and X registers + // + codeptr, VX = resolveX(codeptr, VX) + if A_IS_TOSL & TOS_DIRTY + *codeptr = $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 + dest = *(bytecode+i+1) + i = i + 2 + //puts("LA/CW $"); puth(dest) + if A_IS_TOSL & TOS_DIRTY + *codeptr = $D095+(VX<<8) // STA ESTKL,X + codeptr = codeptr + 2 + fin + VX-- // DEX + codeptr=>0 = $A9+(dest&$FF00) // LDA #2 = $C095+(VX<<8) // STA ESTKH,X + codeptr=>4 = $A9+(dest<<8) // LDA #>VAL + codeptr = codeptr + 6 + A_IS_TOSL = TOS_DIRTY // STA ESTKL,X + break + is $28 // LLA + i++ + j = ^(bytecode+i) + //puts("LLA "); puti(^(bytecode+i)) + if A_IS_TOSL & TOS_DIRTY + *codeptr = $D095+(VX<<8) // STA ESTKL,X + codeptr = codeptr + 2 + fin + VX-- // DEX + if VY == j + ^codeptr = $98; codeptr++ // TYA -> LDA #imm + + else + *codeptr = $A9+(j<<8) // LDA #imm + codeptr = codeptr + 2 + fin + codeptr->0 = $18 // CLC + codeptr=>1 = $E065 // ADC IFPL + codeptr=>3 = $D095+(VX<<8) // STA ESTKL,X + if VY == 0 + codeptr->5 = $98 // TYA -> LDA #00 + codeptr = codeptr + 6 + else + codeptr=>5 = $00A9 // LDA #$00 + codeptr = codeptr + 7 + fin + codeptr=>0 = $E165 // ADC IFPH + codeptr=>2 = $C095+(VX<<8) // STA ESTKH,X + codeptr = codeptr + 4 + A_IS_TOSL = FALSE + break + is $2A // CB + 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 + //puts("CALL $"); puth(*(bytecode+i)) + // + // Call address + // + codeptr, VX = resolveX(codeptr, VX) + if A_IS_TOSL & TOS_DIRTY + *codeptr = $D095//+(VX<<8) // STA ESTKL,X + codeptr = codeptr + 2 + fin + codeptr->0 = $20 // JSR abs + codeptr=>1 = *(bytecode+i+1) + codeptr = codeptr + 3 + VY = UNKNOWN + A_IS_TOSL = FALSE + i = i + 2 + break + is $56 // ICAL + //puts("ICAL") + // + // Pull address off stack + // + if not A_IS_TOSL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 + fin + codeptr=>0 = $E785 // STA $E7:TMPL + codeptr=>2 = $C0B5+(VX<<8) // LDA ESTKH,X + codeptr=>4 = $E885 // STA $E8:TMPH + codeptr, VX = resolveX(codeptr + 6, VX + 1) // INX + // + // Call through TMP + // + codeptr->0 = $20 // JSR abs + codeptr=>1 = $00E6 // $E6:JMPTMP + codeptr = codeptr + 3 + VY = UNKNOWN + A_IS_TOSL = FALSE + break + is $5A // LEAVE + i++ + //puts("LEAVE "); puti(^(bytecode+i)) + // + // Call into VM + // + codeptr, VX = resolveX(codeptr, VX) + if A_IS_TOSL & TOS_DIRTY + *codeptr = $D095//+(VX<<8) // STA ESTKL,X + codeptr = codeptr + 2 + fin + codeptr->0 = $20 // JSR abs + codeptr=>1 = directentry // INTERP + codeptr=>3 = $5A + (^(bytecode+i)<<8) // LEAVE CODE AND OPERAND + codeptr = codeptr + 5 + A_IS_TOSL = FALSE + break + is $5C // RET + //puts("RET") + codeptr, VX = resolveX(codeptr, VX) + if A_IS_TOSL & TOS_DIRTY + *codeptr = $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 + fin + *codeptr = $E0B1 // LDA (IFP),Y + codeptr = codeptr + 2 + if j <> 0 + *codeptr = $00A0 // LDY #$00 + codeptr = codeptr + 2 + fin + *codeptr = $C094+(VX<<8) // STY ESTKH,X + codeptr = codeptr + 2 + VY = 0 + A_IS_TOSL = TOS_DIRTY // STA ESTKL,X + break + is $66 // LLW + i++ + j = ^(bytecode+i) + //puts("LLW "); puti(j) + if A_IS_TOSL & TOS_DIRTY + *codeptr = $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 + dest = *(bytecode+i+1) + i = i + 2 + 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(dest) + if VY <> 0 + *codeptr = $00A0 // LDY #$00 + codeptr = codeptr + 2 + VY = 0 + fin + *codeptr = $C094+(VX<<8) // STY ESTKH,X + codeptr = codeptr + 2 + else + //puts("LAW $"); puth(dest) + codeptr->0 = $AD // LDA abs+1 + codeptr=>1 = dest+1 + codeptr=>3 = $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 $6C // DLB + i++ + j = ^(bytecode+i) + //puts("DLB "); puti(j) + if not A_IS_TOSL + *codeptr = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 + A_IS_TOSL = TOS_CLEAN + fin + if VY <> j + *codeptr = $A0+(j<<8) // LDY #imm + codeptr = codeptr + 2 + VY = j + fin + *codeptr = $E091 // STA (IFP),Y + codeptr = codeptr + 2 + if VY <> 0 + *codeptr = $00A0 // LDY #$00 + codeptr = codeptr + 2 + VY = 0 + fin + *codeptr = $C094+(VX<<8) // STY ESTKH,X + codeptr = codeptr + 2 + break + is $6E // DLW + i++ + j = ^(bytecode+i) + //puts("DLW "); puti(j) + if A_IS_TOSL & TOS_DIRTY + *codeptr = $D095+(VX<<8) // STA ESTKL,X + codeptr = codeptr + 2 + fin + if VY <> j + *codeptr = $A0+((j+1)<<8) // LDY #imm + codeptr = codeptr + 2 + VY = j + else + ^codeptr = $C8; codeptr++ // INY + fin + codeptr=>0 = $C0B5+(VX<<8) // LDA ESTKH,X + codeptr=>2 = $E091 // STA (IFP),Y + codeptr->4 = $88 // DEY + codeptr=>5 = $D0B5+(VX<<8) // LDA ESTKL,X + codeptr=>7 = $E091 // STA (IFP),Y + codeptr = codeptr + 9 + A_IS_TOSL = TOS_CLEAN + break + is $70 // SB + 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 $74 // SLB + is $76 // SLW + 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 + VY = j + fin + codeptr=>0 = $E091 // STA (IFP),Y + if opcode == $74 + //puts("SLB "); puti(j) + codeptr = codeptr + 2 + else + //puts("SLW "); puti(j) + codeptr->2 = $C8 // INY + codeptr=>3 = $C0B5+(VX<<8) // LDA ESTKH,X + codeptr=>5 = $E091 // STA (IFP),Y + codeptr = codeptr + 7 + VY++ + fin + VX++ // INX + A_IS_TOSL = FALSE + break + is $78 // SAB + is $7A // SAW + dest = *(bytecode+i+1) + i = i + 2 + //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 + if opcode == $78 + //puts("SAB $"); puth(*(bytecode+i)) + codeptr = codeptr + 3 + else + codeptr=>3 = $C0B5+(VX<<8) // LDA ESTKH,X + codeptr->5 = $8D // STA abs+1 + codeptr=>6 = dest+1 + codeptr = codeptr + 8 + fin + VX++ // INX + A_IS_TOSL = FALSE + break + is $7C // DAB + is $7E // DAW + dest = *(bytecode+i+1) + i = i + 2 + //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 + if opcode == $7C + //puts("DAB $"); puth(*(bytecode+i)) + codeptr = codeptr + 3 + if VY <> 0 + *codeptr = $00A0 // LDY #$00 + codeptr = codeptr + 2 + VY = 0 + fin + *codeptr = $C094+(VX<<8) // STY ESTKH,X + codeptr = codeptr + 2 + else + codeptr=>3 = $C0B4+(VX<<8) // LDY ESTKH,X + codeptr->5 = $8C // STY abs+1 + codeptr=>6 = dest+1 + codeptr = codeptr + 8 + VY = UNKNOWN + fin + break + is $80 // NOT + //puts("NOT") + if not A_IS_TOSL + *codeptr = $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 = directentry // INTERP + codeptr=>3 = $C000+opcode // OPCODE; NATV CODE + codeptr = codeptr + 5 + VY = UNKNOWN + A_IS_TOSL = FALSE + break + is $90 // NEG + //puts("NEG") + if A_IS_TOSL & TOS_DIRTY + *codeptr = $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) + i++ + //puts("BRGT "); 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 = $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) + i++ + //puts("BRLT "); puti(dest) + codeptr, VX = resolveX(codeptr, VX) + if not A_IS_TOSL + *codeptr = $D0B5//+(VX<<8) // LDA ESTKL,X + codeptr = codeptr + 2 + elsif A_IS_TOSL & TOS_DIRTY + *codeptr = $D095//+(VX<<8) // STA ESTKL,X + codeptr = codeptr + 2 + fin + codeptr=>0 = $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 + VY = j + 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 + 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++ + A_IS_TOSL = FALSE + fin + break + is $B4 // ADDAB + is $B6 // ADDAW + dest = *(bytecode+i+1) + i = i + 2 + if not A_IS_TOSL + *codeptr = $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 <> 0 + *codeptr = $00A0 // LDY #$00 + codeptr = codeptr + 2 + fin + codeptr->0 = $0A // ASL + codeptr=>1 = $0290 // BCC +2 + codeptr=>3 = $18C8 // INY; CLC + codeptr=>5 = $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 ESTKH,X + codeptr=>20 = $C095+(VX<<8) // STA ESTKH,X + codeptr = codeptr + 22 + VY = UNKNOWN + A_IS_TOSL = FALSE + break + is $BC // IDXAB + dest = *(bytecode+i+1) + i = i + 2 + //puts("IDXAB $"); puth(*(bytecode+i)) + if A_IS_TOSL & TOS_DIRTY + *codeptr = $D095+(VX<<8) // STA ESTKL,X + codeptr = codeptr + 2 + fin + if VY <> 0 + *codeptr = $00A0 // LDY #$00 + codeptr = codeptr + 2 + fin + codeptr->0 = $AD // LDA abs + codeptr=>1 = dest + codeptr->3 = $0A // ASL + codeptr=>4 = $0290 // BCC +2 + codeptr=>6 = $18C8 // INY; CLC + codeptr=>8 = $D075+(VX<<8) // ADC ESTKL,X + codeptr=>10 = $D095+(VX<<8) // STA ESTKL,X + codeptr->12 = $98 // TYA + codeptr=>13 = $C075+(VX<<8) // ADC ESTKH,X + codeptr=>15 = $C095+(VX<<8) // STA ESTKH,X + codeptr = codeptr + 17 + VY = UNKNOWN + A_IS_TOSL = FALSE + break + is $BE // IDXAW + dest = *(bytecode+i+1) + i = i + 2 + //puts("IDXAW $"); puth(dest) + if A_IS_TOSL & TOS_DIRTY + *codeptr = $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+1 + 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 ESTKH,X + codeptr = codeptr + 23 + VY = UNKNOWN + A_IS_TOSL = FALSE + break + is $FE // NOPed out earlier by SELect + break + otherwise + //puts("???: $"); puth(^(bytecode+i)); putln + wend + fin + //putln + i++ + if i >= defptr->bytecodesize + // + // Done compiling. Update DEF entry with JMP to compiled code + // + defptr->interpjsr = $4C // JMP + defptr=>interpaddr = *jitcodeptr + *jitcodeptr = codeptr + // + // 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 From fd641bef8f814fea91bba7fea2fe533e3529a462 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Fri, 6 Apr 2018 14:22:39 -0700 Subject: [PATCH 144/147] JIT specific module loading --- src/makefile | 7 ++++++- src/mkrel | 1 + src/vmsrc/apple/cmdjit.pla | 9 +++------ src/vmsrc/apple/plvm802.s | 14 ++++++++++++++ src/vmsrc/apple/plvmjit02.s | 10 ++++++++++ 5 files changed, 34 insertions(+), 7 deletions(-) diff --git a/src/makefile b/src/makefile index de1131e..e308491 100755 --- a/src/makefile +++ b/src/makefile @@ -14,6 +14,7 @@ PLVMZP_C64 = vmsrc/c64/plvmzp.inc PLVMC64 = rel/c64/PLASMA ED = rel/ED\#FE1000 JIT = rel/apple/JIT\#FE1000 +JIT16 = rel/apple/JIT16\#FE1000 JITUNE = rel/apple/JITUNE\#FE1000 SOS = rel/apple/SOS\#FE1000 ROD = rel/ROD\#FE1000 @@ -80,7 +81,7 @@ TXTTYPE = .TXT #SYSTYPE = \#FF2000 #TXTTYPE = \#040000 -apple: $(PLVMZP_APL) $(PLASM) $(PLVM) $(PLVM01) $(PLVM02) $(PLVMJIT) $(PLVM802) $(PLVM03) $(CMD) $(CMDJIT) $(JIT) $(JITUNE) $(SOSCMD) $(PLASMAPLASM) $(CODEOPT) $(ARGS) $(MEMMGR) $(MEMTEST) $(FIBER) $(FIBERTEST) $(LONGJMP) $(ED) $(MON) $(SOS) $(ROD) $(SIEVE) $(UTHERNET2) $(UTHERNET) $(ETHERIP) $(INET) $(DHCP) $(HTTPD) $(ROGUE) $(ROGUEMAP) $(ROGUECOMBAT) $(GRAFIX) $(GFXDEMO) $(DGR) $(DGRTEST) $(FILEIO_APL) $(CONIO_APL) $(JOYBUZZ) $(PORTIO) $(SPIPORT) $(SDFAT) $(FATCAT) $(FATGET) $(FATPUT) $(FATWDSK) $(FATRDSK) $(SANE) $(FPSTR) $(FPU) $(SANITY) $(RPNCALC) $(SNDSEQ) $(PLAYSEQ) +apple: $(PLVMZP_APL) $(PLASM) $(PLVM) $(PLVM01) $(PLVM02) $(PLVMJIT) $(PLVM802) $(PLVM03) $(CMD) $(CMDJIT) $(JIT) $(JIT16) $(JITUNE) $(SOSCMD) $(PLASMAPLASM) $(CODEOPT) $(ARGS) $(MEMMGR) $(MEMTEST) $(FIBER) $(FIBERTEST) $(LONGJMP) $(ED) $(MON) $(SOS) $(ROD) $(SIEVE) $(UTHERNET2) $(UTHERNET) $(ETHERIP) $(INET) $(DHCP) $(HTTPD) $(ROGUE) $(ROGUEMAP) $(ROGUECOMBAT) $(GRAFIX) $(GFXDEMO) $(DGR) $(DGRTEST) $(FILEIO_APL) $(CONIO_APL) $(JOYBUZZ) $(PORTIO) $(SPIPORT) $(SDFAT) $(FATCAT) $(FATGET) $(FATPUT) $(FATWDSK) $(FATRDSK) $(SANE) $(FPSTR) $(FPU) $(SANITY) $(RPNCALC) $(SNDSEQ) $(PLAYSEQ) -rm vmsrc/plvmzp.inc c64: $(PLVMZP_C64) $(PLASM) $(PLVM) $(PLVMC64) @@ -370,6 +371,10 @@ $(JIT): libsrc/apple/jit.pla libsrc/jitcore.pla $(PLVMJIT) $(PLASM) ./$(PLASM) -AMO < libsrc/apple/jit.pla > libsrc/apple/jit.a acme --setpc 4094 -o $(JIT) libsrc/apple/jit.a +$(JIT16): libsrc/apple/jit16.pla libsrc/jit16core.pla $(PLVMJIT) $(PLASM) + ./$(PLASM) -AMO < libsrc/apple/jit16.pla > libsrc/apple/jit16.a + acme --setpc 4094 -o $(JIT16) libsrc/apple/jit16.a + $(JITUNE): libsrc/apple/jitune.pla $(PLVMJIT) $(PLASM) ./$(PLASM) -AMO < libsrc/apple/jitune.pla > libsrc/apple/jitune.a acme --setpc 4094 -o $(JITUNE) libsrc/apple/jitune.a diff --git a/src/mkrel b/src/mkrel index 395ca51..bde649c 100755 --- a/src/mkrel +++ b/src/mkrel @@ -33,6 +33,7 @@ cp rel/apple/UTHERNET2#FE1000 prodos/sys/UTHERNET2.REL cp rel/apple/SOS#FE1000 prodos/sys/SOS.REL cp rel/apple/GRAFIX#FE1000 prodos/sys/GRAFIX.REL cp rel/apple/JIT#FE1000 prodos/sys/JIT.REL +cp rel/apple/JIT16#FE1000 prodos/sys/JIT16.REL cp rel/apple/JITUNE#FE1000 prodos/sys/JITUNE.REL cp ../sysfiles/FP6502.CODE#060000 prodos/sys/FP6502.CODE.BIN cp ../sysfiles/ELEMS.CODE#060000 prodos/sys/ELEMS.CODE.BIN diff --git a/src/vmsrc/apple/cmdjit.pla b/src/vmsrc/apple/cmdjit.pla index 88ed673..184a2c1 100755 --- a/src/vmsrc/apple/cmdjit.pla +++ b/src/vmsrc/apple/cmdjit.pla @@ -41,6 +41,7 @@ end // const jitcomp = $03E2 const jitcodeptr = $03E4 +const jitmod = $02E0 // // Pedefined functions. // @@ -65,10 +66,6 @@ byte jitsize = 0 // byte cmdln = "" // -// DCI version of JIT -// -byte jitmod = 'J'|$80, 'I'|$80, 'T' -// // Name for auto-run file (must follow cmdln) // byte autorun = "AUTORUN" @@ -1023,7 +1020,7 @@ end // def adddef(isfirst, addr, deflast)#1 word preventry, defentry, defsize - + defentry = *deflast *deflast = defentry + t_defentry if not isfirst @@ -1426,7 +1423,7 @@ loop strcat(strcpy(@sysmods, $280), "SYS/")) // This is the path to CMD syspath = @sysmods // Update external interface table syscmdln = @cmdln -loadmod(@jitmod) +loadmod(jitmod) xheap = $0800 // Reset heap to point at low memory xheaptop = $A000 // Top where JIT loaded // diff --git a/src/vmsrc/apple/plvm802.s b/src/vmsrc/apple/plvm802.s index ee1d012..26906da 100644 --- a/src/vmsrc/apple/plvm802.s +++ b/src/vmsrc/apple/plvm802.s @@ -64,6 +64,7 @@ OPPAGE = OPIDX+1 ; BUFFER ADDRESSES ; STRBUF = $0280 +JITMOD = $02E0 INTERP = $03D0 JITCOMP = $03E2 JITCODE = $03E4 @@ -342,6 +343,19 @@ BYE LDY DEFCMD ; STY $01FF CMDENTRY = * ; +; SET DCI STRING FOR JIT MODULE +; + LDA #'J'|$80 + STA JITMOD+0 + LDA #'I'|$80 + STA JITMOD+1 + LDA #'T'|$80 + STA JITMOD+2 + LDA #'1'|$80 + STA JITMOD+3 + LDA #'6' + STA JITMOD+4 +; ; DEACTIVATE 80 COL CARDS ; BIT ROMEN diff --git a/src/vmsrc/apple/plvmjit02.s b/src/vmsrc/apple/plvmjit02.s index e00b664..f0d57f8 100755 --- a/src/vmsrc/apple/plvmjit02.s +++ b/src/vmsrc/apple/plvmjit02.s @@ -51,6 +51,7 @@ IPH = IPL+1 OPIDX = FETCHOP+6 OPPAGE = OPIDX+1 STRBUF = $0280 +JITMOD = $02E0 INTERP = $03D0 JITCOMP = $03E2 JITCODE = $03E4 @@ -277,6 +278,15 @@ BYE LDY DEFCMD ; STY $01FF CMDENTRY = * ; +; SET DCI STRING FOR JIT MODULE +; + LDA #'J'|$80 + STA JITMOD+0 + LDA #'I'|$80 + STA JITMOD+1 + LDA #'T' + STA JITMOD+2 +; ; DEACTIVATE 80 COL CARDS ; BIT ROMEN From dad0f4b4d5649625857844a43101269a67cf617f Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Fri, 6 Apr 2018 17:53:51 -0700 Subject: [PATCH 145/147] Add NO-JITC flag to module SYSFLAGS --- src/inc/cmdsys.plh | 1 + src/vmsrc/apple/cmd.pla | 4 +++- src/vmsrc/apple/cmdjit.pla | 20 ++++++++++++-------- src/vmsrc/apple/sossys.pla | 12 ++++++++---- 4 files changed, 24 insertions(+), 13 deletions(-) diff --git a/src/inc/cmdsys.plh b/src/inc/cmdsys.plh index d258e54..b225302 100644 --- a/src/inc/cmdsys.plh +++ b/src/inc/cmdsys.plh @@ -33,6 +33,7 @@ import cmdsys const reshgr2 = $0020 const resxhgr1 = $0040 const resxhgr2 = $0080 + const nojitc = $0100 // // Module don't free memory // diff --git a/src/vmsrc/apple/cmd.pla b/src/vmsrc/apple/cmd.pla index 3d8b6a2..300a185 100755 --- a/src/vmsrc/apple/cmd.pla +++ b/src/vmsrc/apple/cmd.pla @@ -1024,7 +1024,7 @@ def loadmod(mod)#1 word addr, defaddr, modaddr, modfix, modofst, modend word deftbl, deflast word moddep, rld, esd, sym - byte refnum, defbank, str[16], filename[64] + byte refnum, defbank, filename[64], str[] byte header[128] // // Read the RELocatable module header (first 128 bytes) @@ -1209,6 +1209,8 @@ def loadmod(mod)#1 *$0042 = defaddr call($C311, 0, 0, 0, $05) // CALL XMOVE with carry set (MAIN->AUX) and ints disabled fin + else + perr = $46 fin if perr return -perr diff --git a/src/vmsrc/apple/cmdjit.pla b/src/vmsrc/apple/cmdjit.pla index 184a2c1..442bf2d 100755 --- a/src/vmsrc/apple/cmdjit.pla +++ b/src/vmsrc/apple/cmdjit.pla @@ -16,6 +16,7 @@ const reshgr1 = $0010 const reshgr2 = $0020 const resxhgr1 = $0040 const resxhgr2 = $0080 +const nojitc = $0100 // // Module don't free memory // @@ -1044,7 +1045,7 @@ def loadmod(mod)#1 word addr, defaddr, modaddr, modfix, modofst, modend word deftbl, deflast word moddep, rld, esd, sym - byte refnum[], deffirst, str[16], filename[64] + byte refnum[], deffirst, skipjit, filename[64], str[] byte header[128] // // Read the RELocatable module header (first 128 bytes) @@ -1074,11 +1075,12 @@ def loadmod(mod)#1 // // This is an EXTended RELocatable (data+bytecode) module. // - systemflags = header:4 | systemflags - defofst = header:6 - defcnt = header:8 - init = header:10 - moddep = @header.12 + systemflags = header.4 | systemflags + skipjit = header.5 & (nojitc >> 8) + defofst = header:6 + defcnt = header:8 + init = header:10 + moddep = @header.12 // // Load module dependencies. // @@ -1153,8 +1155,8 @@ def loadmod(mod)#1 // This is a bytcode def entry - add it to the def directory. // adddef(deffirst, rld=>1 + defofst, @deflast) - deffirst = 0 - rld = rld + 4 + deffirst = skipjit // Calculate JIT potential or not + rld = rld + 4 loop // // Run through the Re-Location Dictionary. @@ -1194,6 +1196,8 @@ def loadmod(mod)#1 *$003E = modaddr + modsize *$0042 = defaddr call($C311, 0, 0, 0, $05) // CALL XMOVE with carry set (MAIN->AUX) and ints disabled + else + perr = $46 fin if perr return -perr diff --git a/src/vmsrc/apple/sossys.pla b/src/vmsrc/apple/sossys.pla index 29408a7..98e60cb 100755 --- a/src/vmsrc/apple/sossys.pla +++ b/src/vmsrc/apple/sossys.pla @@ -11,6 +11,7 @@ const reshgr1 = $0010 const reshgr2 = $0020 const resxhgr1 = $0040 const resxhgr2 = $0080 +const nojitc = $0100 // // Module don't free memory // @@ -1050,7 +1051,7 @@ def loadmod(mod)#1 word addr, defaddr, modaddr, modfix, modofst, modend word deftbl, deflast, codeseg word moddep, rld, esd, sym - byte lerr, defext, fileinfo[], str[16], filename[33] + byte lerr, defext, skipjit, fileinfo[], str[16], filename[33] byte header[128] lerr = 0 // @@ -1084,7 +1085,8 @@ def loadmod(mod)#1 // // This is an EXTended RELocatable (data+bytecode) module. // - systemflags = header:4 | systemflags + systemflags = header.4 | systemflags + skipjit = header.5 & (nojitc >> 8) defofst = header:6 defcnt = header:8 init = header:10 @@ -1176,8 +1178,8 @@ def loadmod(mod)#1 // This is a bytcode def entry - add it to the def directory. // adddef(deffirst, defext, rld=>1 + defofst, @deflast) - deffirst = 0 - rld = rld + 4 + deffirst = skipjit // Calculate JIT potential or not + rld = rld + 4 loop // // Run through the Re-Location Dictionary. @@ -1241,6 +1243,8 @@ def loadmod(mod)#1 // memxcpy(codeseg, bytecode, modsize - (bytecode - modaddr)) fin + else + lerr = $46 fin if lerr return -lerr From 2241c0c65ff737a728af9c590ac031d2c5e5d092 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Sat, 7 Apr 2018 09:33:22 -0700 Subject: [PATCH 146/147] Somehow this got lost in the merge --- PLASMA-SYS2.PO | Bin 0 -> 143360 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100755 PLASMA-SYS2.PO diff --git a/PLASMA-SYS2.PO b/PLASMA-SYS2.PO new file mode 100755 index 0000000000000000000000000000000000000000..6300c41694495fb600b567132a211860c7c1a5a7 GIT binary patch literal 143360 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 literal 0 HcmV?d00001 From 61eaeef9c1e1d22b784993801e8adfb508a6f9c4 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Sat, 7 Apr 2018 10:48:11 -0700 Subject: [PATCH 147/147] Disable JITC on certain modules. --- src/libsrc/apple/conio.pla | 1 + src/libsrc/apple/fileio.pla | 1 + src/libsrc/args.pla | 1 + src/mkrel | 2 +- src/toolsrc/ed.pla | 18 +++++++++--------- 5 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/libsrc/apple/conio.pla b/src/libsrc/apple/conio.pla index f851d58..5469998 100644 --- a/src/libsrc/apple/conio.pla +++ b/src/libsrc/apple/conio.pla @@ -1,4 +1,5 @@ include "inc/cmdsys.plh" +sysflags nojitc // Keep tone() from compiling and sounding different // // Handy constants. // diff --git a/src/libsrc/apple/fileio.pla b/src/libsrc/apple/fileio.pla index db299a2..3036f5c 100644 --- a/src/libsrc/apple/fileio.pla +++ b/src/libsrc/apple/fileio.pla @@ -1,4 +1,5 @@ include "inc/cmdsys.plh" +sysflags nojitc // It's file I/O. No need to hurry up and wait. // // CFFA1 addresses. // diff --git a/src/libsrc/args.pla b/src/libsrc/args.pla index 7945de0..bc3ec66 100644 --- a/src/libsrc/args.pla +++ b/src/libsrc/args.pla @@ -1,4 +1,5 @@ include "inc/cmdsys.plh" +sysflags nojitc // No need to speed this up def argDelim(str) byte n diff --git a/src/mkrel b/src/mkrel index bde649c..fc9a31c 100755 --- a/src/mkrel +++ b/src/mkrel @@ -1,7 +1,7 @@ cp rel/apple/CMD#061000 prodos/CMD.BIN cp rel/apple/CMDJIT#061000 prodos/CMDJIT.BIN cp rel/apple/PLASMA.SYSTEM#FF2000 prodos/PLASMA.SYSTEM.SYS -cp rel/apple/PLASMAJIT.SYSTEM#FF2000 prodos/PLAJIT.SYSTEM.SYS +cp rel/apple/PLASMAJIT.SYSTEM#FF2000 prodos/PLIJIT.SYSTEM.SYS cp rel/apple/PLASMA16.SYSTEM#FF2000 prodos/PLASMA16.SYSTEM.SYS cp rel/apple/SOS.INTERP#050000 prodos/SOS.INTERP.\$05 cp rel/apple/SOS.CMD#FE1000 prodos/SOS.CMD.REL diff --git a/src/toolsrc/ed.pla b/src/toolsrc/ed.pla index 86f0844..79c0214 100755 --- a/src/toolsrc/ed.pla +++ b/src/toolsrc/ed.pla @@ -7,6 +7,7 @@ include "inc/cmdsys.plh" include "inc/args.plh" include "inc/fileio.plh" +sysflags nojitc // Keep JITC from compiling and pausing while editing // // Hardware constants // @@ -169,8 +170,8 @@ def sizemask(size) return 0 end def strpoolalloc(size) - byte szmask, i - word mapmask, addr + byte szmask + word mapmask, addr, i szmask = sizemask(size) for i = strplmapsize - 1 downto 0 @@ -357,14 +358,13 @@ def writetxt(filename)#0 // // Remove blank lines at end of text. // - while numlines > 1 and strlinbuf=>[numlines - 1] == @nullstr; numlines = numlines - 1; loop + while numlines > 1 and strlinbuf=>[numlines - 1] == @nullstr; numlines--; loop // // Write all the text line to the file. // for i = 0 to numlines - 1 cpyln(strlinbuf=>[i], @txtbuf) - txtbuf = txtbuf + 1 - txtbuf[txtbuf] = $0D + txtbuf++; txtbuf[txtbuf] = $0D // Add CR to end of line fileio:write(refnum, @txtbuf + 1, txtbuf) if !(i & $0F); putc('.'); fin next @@ -503,7 +503,7 @@ end def pgup#0 byte i - for i = pgjmp downto 0 + for i = 0 to pgjmp cursup next end @@ -523,7 +523,7 @@ end def pgdown#0 byte i - for i = pgjmp downto 0 + for i = 0 to pgjmp cursdown next end @@ -543,7 +543,7 @@ end def pgleft#0 byte i - for i = 7 downto 0 + for i = 0 to 7 cursleft next end @@ -563,7 +563,7 @@ end def pgright#0 byte i - for i = 7 downto 0 + for i = 0 to 7 cursright next end

      8jtmr_Bu<2f#92eb2$x|DDlruoa%@4I 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 C4<;D^ delta 12713 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 diff --git a/PLASMA-SYS2.PO b/PLASMA-SYS2.PO index fc312ff0d8f594df3f4ff64832ce993a6faec9dd..0fc1d67ba334362f955e998095035c95ad68093c 100644 GIT binary patch delta 21719 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 delta 21393 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 diff --git a/src/toolsrc/codegen.c b/src/toolsrc/codegen.c index 1b4b3c1..4255bba 100755 --- a/src/toolsrc/codegen.c +++ b/src/toolsrc/codegen.c @@ -1518,7 +1518,7 @@ int crunch_seq(t_opseq **seq, int pass) op->code = IDXLB_CODE; freeops = 1; } - if ((pass > 0) && (freeops == 0)) + else if (pass > 0) crunched = try_dupify(op); break; // LLB_CODE case LLW_CODE: @@ -1546,7 +1546,7 @@ int crunch_seq(t_opseq **seq, int pass) op->code = IDXLW_CODE; freeops = 1; } - if ((pass > 0) && (freeops == 0)) + else if (pass > 0) crunched = try_dupify(op); break; // LLW_CODE case LAB_CODE: @@ -1560,8 +1560,7 @@ int crunch_seq(t_opseq **seq, int pass) op->code = IDXAB_CODE; freeops = 1; } - if ((pass > 0) && (freeops == 0) && - (op->type || !is_hardware_address(op->offsz))) + else if ((pass > 0) && (op->type || !is_hardware_address(op->offsz))) crunched = try_dupify(op); break; // LAB_CODE case LAW_CODE: @@ -1589,8 +1588,7 @@ int crunch_seq(t_opseq **seq, int pass) op->code = IDXAW_CODE; freeops = 1; } - if ((pass > 0) && (freeops == 0) && - (op->type || !is_hardware_address(op->offsz))) + else if ((pass > 0) && (op->type || !is_hardware_address(op->offsz))) crunched = try_dupify(op); break; // LAW_CODE case LOGIC_NOT_CODE: From b145f82a9d396e9bab697739f7b674534368635f Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Wed, 14 Mar 2018 17:22:12 -0700 Subject: [PATCH 034/147] Faster ADDx ops --- src/vmsrc/apple/plvm01.s | 68 +++---- src/vmsrc/apple/plvm02.s | 386 ++++++++++++++++++++++++++++---------- src/vmsrc/apple/plvm802.s | 288 ++++++++++++++++++---------- 3 files changed, 505 insertions(+), 237 deletions(-) diff --git a/src/vmsrc/apple/plvm01.s b/src/vmsrc/apple/plvm01.s index bf71e31..9a9db1f 100644 --- a/src/vmsrc/apple/plvm01.s +++ b/src/vmsrc/apple/plvm01.s @@ -501,7 +501,7 @@ LLA INY ;+INC_IP ;* ;* LOAD VALUE FROM LOCAL FRAME OFFSET ;* -LLB INY ;+INC_IP +_LLB INY ;+INC_IP LDA (IP),Y STY IPY TAY @@ -511,8 +511,8 @@ LLB INY ;+INC_IP LDA #$00 STA ESTKH,X LDY IPY - JMP NEXTOP -LLW INY ;+INC_IP + RTS +_LLW INY ;+INC_IP LDA (IP),Y STY IPY TAY @@ -523,41 +523,29 @@ LLW INY ;+INC_IP LDA (IFP),Y STA ESTKH,X LDY IPY + RTS +LLB JSR _LLB + JMP NEXTOP +LLW JSR _LLW JMP NEXTOP ;* ;* ADD VALUE FROM LOCAL FRAME OFFSET ;* -ADDLB LDA #$60 ; RTS - STA NEXTOP - JSR LLB - LDA #$C8 ; INY - STA NEXTOP +ADDLB JSR _LLB JMP ADD -ADDLW LDA #$60 ; RTS - STA NEXTOP - JSR LLW - LDA #$C8 ; INY - STA NEXTOP +ADDLW JSR _LLW JMP ADD ;* ;* INDEX VALUE FROM LOCAL FRAME OFFSET ;* -IDXLB LDA #$60 ; RTS - STA NEXTOP - JSR LLB - LDA #$C8 ; INY - STA NEXTOP +IDXLB JSR _LLB JMP IDXW -IDXLW LDA #$60 ; RTS - STA NEXTOP - JSR LLW - LDA #$C8 ; INY - STA NEXTOP +IDXLW JSR _LLW JMP IDXW ;* ;* LOAD VALUE FROM ABSOLUTE ADDRESS ;* -LAB INY ;+INC_IP +_LAB INY ;+INC_IP LDA (IP),Y STA ESTKH-2,X INY ;+INC_IP @@ -568,8 +556,8 @@ LAB INY ;+INC_IP STA ESTKL,X LDA #$00 STA ESTKH,X - JMP NEXTOP -LAW INY ;+INC_IP + RTS +_LAW INY ;+INC_IP LDA (IP),Y STA TMPL INY ;+INC_IP @@ -584,36 +572,24 @@ LAW INY ;+INC_IP LDA (TMP),Y STA ESTKH,X LDY IPY + RTS +LAB JSR _LAB + JMP NEXTOP +LAW JSR _LAW JMP NEXTOP ;* ;* ADD VALUE FROM ABSOLUTE ADDRESS ;* -ADDAB LDA #$60 ; RTS - STA NEXTOP - JSR LAB - LDA #$C8 ; INY - STA NEXTOP +ADDAB JSR _LAB JMP ADD -ADDAW LDA #$60 ; RTS - STA NEXTOP - JSR LAW - LDA #$C8 ; INY - STA NEXTOP +ADDAW JSR _LAW JMP ADD ;* ;* INDEX VALUE FROM ABSOLUTE ADDRESS ;* -IDXAB LDA #$60 ; RTS - STA NEXTOP - JSR LAB - LDA #$C8 ; INY - STA NEXTOP +IDXAB JSR _LAB JMP IDXW -IDXAW LDA #$60 ; RTS - STA NEXTOP - JSR LAW - LDA #$C8 ; INY - STA NEXTOP +IDXAW JSR _LAW JMP IDXW ;* ;* STORE VALUE TO ADDRESS diff --git a/src/vmsrc/apple/plvm02.s b/src/vmsrc/apple/plvm02.s index 29cd6be..33ed7ff 100755 --- a/src/vmsrc/apple/plvm02.s +++ b/src/vmsrc/apple/plvm02.s @@ -1017,57 +1017,143 @@ LLWX INY ;+INC_IP ;* ;* ADD VALUE FROM LOCAL FRAME OFFSET ;* -ADDLB LDA #$60 ; RTS - STA NEXTOP - JSR LLB - LDA #$C8 ; INY - STA NEXTOP - JMP ADD -ADDLBX LDA #$60 ; RTS - STA NEXTOP - JSR LLBX - LDA #$C8 ; INY - STA NEXTOP - JMP ADD -ADDLW LDA #$60 ; RTS - STA NEXTOP - JSR LLW - LDA #$C8 ; INY - STA NEXTOP - JMP ADD -ADDLWX LDA #$60 ; RTS - STA NEXTOP - JSR LLWX - LDA #$C8 ; INY - STA NEXTOP - JMP ADD +ADDLB INY ;+INC_IP + LDA (IP),Y + STY IPY + TAY + LDA (IFP),Y + CLC + ADC ESTKL,X + STA ESTKL,X + BCC + + INC ESTKH,X ++ LDY IPY + JMP NEXTOP +ADDLBX INY ;+INC_IP + LDA (IP),Y + STY IPY + TAY + STA ALTRDOFF + LDA (IFP),Y + CLC + ADC ESTKL,X + STA ESTKL,X + BCC + + INC ESTKH,X ++ STA ALTRDON + LDY IPY + JMP NEXTOP +ADDLW INY ;+INC_IP + LDA (IP),Y + STY IPY + TAY + LDA (IFP),Y + CLC + ADC ESTKL,X + STA ESTKL,X + INY + LDA (IFP),Y + ADC ESTKH,X + STA ESTKH,X + LDY IPY + JMP NEXTOP +ADDLWX INY ;+INC_IP + LDA (IP),Y + STY IPY + TAY + STA ALTRDOFF + LDA (IFP),Y + CLC + ADC ESTKL,X + STA ESTKL,X + INY + LDA (IFP),Y + ADC ESTKH,X + STA ESTKH,X + STA ALTRDON + LDY IPY + JMP NEXTOP ;* ;* INDEX VALUE FROM LOCAL FRAME OFFSET ;* -IDXLB LDA #$60 ; RTS - STA NEXTOP - JSR LLB - LDA #$C8 ; INY - STA NEXTOP - JMP IDXW -IDXLBX LDA #$60 ; RTS - STA NEXTOP - JSR LLBX - LDA #$C8 ; INY - STA NEXTOP - JMP IDXW -IDXLW LDA #$60 ; RTS - STA NEXTOP - JSR LLW - LDA #$C8 ; INY - STA NEXTOP - JMP IDXW -IDXLWX LDA #$60 ; RTS - STA NEXTOP - JSR LLWX - LDA #$C8 ; INY - STA NEXTOP - JMP IDXW +IDXLB INY ;+INC_IP + LDA (IP),Y + STY IPY + TAY + LDA (IFP),Y + LDY #$00 + ASL + BCC + + INY + CLC ++ ADC ESTKL,X + STA ESTKL,X + TYA + ADC ESTKH,X + STA ESTKH,X + LDY IPY + JMP NEXTOP +IDXLBX INY ;+INC_IP + LDA (IP),Y + STY IPY + TAY + STA ALTRDOFF + LDA (IFP),Y + LDY #$00 + ASL + BCC + + INY + CLC ++ ADC ESTKL,X + STA ESTKL,X + TYA + ADC ESTKH,X + STA ESTKH,X + STA ALTRDON + LDY IPY + JMP NEXTOP +IDXLW INY ;+INC_IP + LDA (IP),Y + STY IPY + TAY + STA TMPL + LDA (IFP),Y + ASL + STA TMPL + INY + LDA (IFP),Y + ROL + STA TMPH + LDA TMPL + CLC + ADC ESTKL,X + STA ESTKL,X + LDA TMPH + ADC ESTKH,X + STA ESTKH,X + LDY IPY + JMP NEXTOP +IDXLWX INY ;+INC_IP + LDA (IP),Y + STY IPY + TAY + STA ALTRDOFF + LDA (IFP),Y + ASL + STA TMPL + INY + LDA (IFP),Y + ROL + STA TMPH + LDA TMPL + CLC + ADC ESTKL,X + STA ESTKL,X + LDA TMPH + ADC ESTKH,X + STA ESTKH,X + LDY IPY + JMP NEXTOP ;* ;* LOAD VALUE FROM ABSOLUTE ADDRESS ;* @@ -1134,56 +1220,166 @@ LAWX INY ;+INC_IP ;* ;* ADD VALUE FROM ABSOLUTE ADDRESS ;* -ADDAB LDA #$60 ; RTS - STA NEXTOP - JSR LAB - LDA #$C8 ; INY - STA NEXTOP - JMP ADD -ADDABX LDA #$60 ; RTS - STA NEXTOP - JSR LABX - LDA #$C8 ; INY - STA NEXTOP - JMP ADD -ADDAW LDA #$60 ; RTS - STA NEXTOP - JSR LAW - LDA #$C8 ; INY - STA NEXTOP - JMP ADD -ADDAWX LDA #$60 ; RTS - STA NEXTOP - JSR LAWX - LDA #$C8 ; INY - STA NEXTOP - JMP ADD +ADDAB INY ;+INC_IP + LDA (IP),Y + STA ESTKH-2,X + INY ;+INC_IP + LDA (IP),Y + STA ESTKH-1,X + LDA (ESTKH-2,X) + CLC + ADC ESTKL,X + STA ESTKL,X + BCC + + INC ESTKH,X ++ JMP NEXTOP +ADDABX INY ;+INC_IP + LDA (IP),Y + STA ESTKH-2,X + INY ;+INC_IP + LDA (IP),Y + STA ESTKH-1,X + STA ALTRDOFF + LDA (ESTKH-2,X) + CLC + ADC ESTKL,X + STA ESTKL,X + BCC + + INC ESTKH,X ++ STA ALTRDON + JMP NEXTOP +ADDAW INY ;+INC_IP + LDA (IP),Y + STA TMPL + INY ;+INC_IP + LDA (IP),Y + STA TMPH + STY IPY + LDY #$00 + LDA (TMP),Y + CLC + ADC ESTKL,X + STA ESTKL,X + INY + LDA (TMP),Y + ADC ESTKH,X + STA ESTKH,X + LDY IPY + JMP NEXTOP +ADDAWX INY ;+INC_IP + LDA (IP),Y + STA TMPL + INY ;+INC_IP + LDA (IP),Y + STA TMPH + STY IPY + STA ALTRDOFF + LDY #$00 + LDA (TMP),Y + CLC + ADC ESTKL,X + STA ESTKL,X + INY + LDA (TMP),Y + ADC ESTKH,X + STA ESTKH,X + STA ALTRDON + LDY IPY + JMP NEXTOP ;* ;* INDEX VALUE FROM ABSOLUTE ADDRESS ;* -IDXAB LDA #$60 ; RTS - STA NEXTOP - JSR LAB - LDA #$C8 ; INY - STA NEXTOP - JMP IDXW -IDXABX LDA #$60 ; RTS - STA NEXTOP - JSR LABX - LDA #$C8 ; INY - STA NEXTOP - JMP IDXW -IDXAW LDA #$60 ; RTS - STA NEXTOP - JSR LAW - LDA #$C8 ; INY - STA NEXTOP - JMP IDXW -IDXAWX LDA #$60 ; RTS - STA NEXTOP - JSR LAWX - LDA #$C8 ; INY - STA NEXTOP +IDXAB INY ;+INC_IP + LDA (IP),Y + STA ESTKH-2,X + INY ;+INC_IP + LDA (IP),Y + STA ESTKH-1,X + LDA (ESTKH-2,X) + STY IPY + LDY #$00 + ASL + BCC + + INY + CLC ++ ADC ESTKL,X + STA ESTKL,X + TYA + ADC ESTKH,X + STA ESTKH,X + LDY IPY + JMP NEXTOP +IDXABX INY ;+INC_IP + LDA (IP),Y + STA ESTKH-2,X + INY ;+INC_IP + LDA (IP),Y + STA ESTKH-1,X + STA ALTRDOFF + LDA (ESTKH-2,X) + STY IPY + LDY #$00 + ASL + BCC + + INY + CLC ++ ADC ESTKL,X + STA ESTKL,X + TYA + ADC ESTKH,X + STA ESTKH,X + LDY IPY + STA ALTRDON + JMP NEXTOP +IDXAW INY ;+INC_IP + LDA (IP),Y + STA SRCL + INY ;+INC_IP + LDA (IP),Y + STA SRCH + STY IPY + LDY #$00 + LDA (SRC),Y + ASL + STA TMPL + INY + LDA (SRC),Y + ROL + STA TMPH + LDA TMPL + CLC + ADC ESTKL,X + STA ESTKL,X + LDA TMPH + ADC ESTKH,X + STA ESTKH,X + LDY IPY + JMP NEXTOP +IDXAWX INY ;+INC_IP + LDA (IP),Y + STA SRCL + INY ;+INC_IP + LDA (IP),Y + STA SRCH + STY IPY + STA ALTRDOFF + LDY #$00 + LDA (SRC),Y + ASL + STA TMPL + INY + LDA (SRC),Y + ROL + STA TMPH + LDA TMPL + CLC + ADC ESTKL,X + STA ESTKL,X + LDA TMPH + ADC ESTKH,X + STA ESTKH,X + STA ALTRDON + LDY IPY JMP IDXW ;* ;* STORE VALUE TO ADDRESS diff --git a/src/vmsrc/apple/plvm802.s b/src/vmsrc/apple/plvm802.s index 8bf8ac8..947b10f 100644 --- a/src/vmsrc/apple/plvm802.s +++ b/src/vmsrc/apple/plvm802.s @@ -963,57 +963,105 @@ LLWX INY ;+INC_IP ;* ;* ADD VALUE FROM LOCAL FRAME OFFSET ;* -ADDLB LDX #$60 ; RTS - STX NEXTOP - JSR LLB - LDX #$C8 ; INY - STX NEXTOP - JMP ADD -ADDLBX LDX #$60 ; RTS - STX NEXTOP - JSR LLBX - LDX #$C8 ; INY - STX NEXTOP - JMP ADD -ADDLW LDX #$60 ; RTS - STX NEXTOP - JSR LLW - LDX #$C8 ; INY - STX NEXTOP - JMP ADD -ADDLWX LDX #$60 ; RTS - STX NEXTOP - JSR LLWX - LDX #$C8 ; INY - STX NEXTOP - JMP ADD +ADDLB INY ;+INC_IP + TYX + LDA (IP),Y + TAY + LDA (IFP),Y + AND #$00FF + TXY + CLC + ADC TOS,S + STA TOS,S + JMP NEXTOP +ADDLBX INY ;+INC_IP + TYX + LDA (IP),Y + TAY + STX ALTRDOFF + LDA (IFP),Y + STX ALTRDON + AND #$00FF + TXY + CLC + ADC TOS,S + STA TOS,S + JMP NEXTOP +ADDLW INY ;+INC_IP + TYX + LDA (IP),Y + TAY + LDA (IFP),Y + TXY + CLC + ADC TOS,S + STA TOS,S + JMP NEXTOP +ADDLWX INY ;+INC_IP + TYX + LDA (IP),Y + TAY + STX ALTRDOFF + LDA (IFP),Y + STX ALTRDON + TXY + CLC + ADC TOS,S + STA TOS,S + JMP NEXTOP ;* ;* INDEX VALUE FROM LOCAL FRAME OFFSET ;* -IDXLB LDX #$60 ; RTS - STX NEXTOP - JSR LLB - LDX #$C8 ; INY - STX NEXTOP - JMP IDXW -IDXLBX LDX #$60 ; RTS - STX NEXTOP - JSR LLBX - LDX #$C8 ; INY - STX NEXTOP - JMP IDXW -IDXLW LDX #$60 ; RTS - STX NEXTOP - JSR LLW - LDX #$C8 ; INY - STX NEXTOP - JMP IDXW -IDXLWX LDX #$60 ; RTS - STX NEXTOP - JSR LLWX - LDX #$C8 ; INY - STX NEXTOP - JMP IDXW +IDXLB INY ;+INC_IP + TYX + LDA (IP),Y + TAY + LDA (IFP),Y + AND #$00FF + TXY + ASL + CLC + ADC TOS,S + STA TOS,S + JMP NEXTOP +IDXLBX INY ;+INC_IP + TYX + LDA (IP),Y + TAY + STX ALTRDOFF + LDA (IFP),Y + STX ALTRDON + AND #$00FF + TXY + ASL + CLC + ADC TOS,S + STA TOS,S + JMP NEXTOP +IDXLW INY ;+INC_IP + TYX + LDA (IP),Y + TAY + LDA (IFP),Y + TXY + ASL + CLC + ADC TOS,S + STA TOS,S + JMP NEXTOP +IDXLWX INY ;+INC_IP + TYX + LDA (IP),Y + TAY + STX ALTRDOFF + LDA (IFP),Y + STX ALTRDON + TXY + ASL + CLC + ADC TOS,S + STA TOS,S + JMP NEXTOP ;* ;* LOAD VALUE FROM ABSOLUTE ADDRESS ;* @@ -1058,57 +1106,105 @@ LAWX INY ;+INC_IP ;* ;* ADD VALUE FROM ABSOLUTE ADDRESS ;* -ADDAB LDX #$60 ; RTS - STX NEXTOP - JSR LAB - LDX #$C8 ; INY - STX NEXTOP - JMP ADD -ADDABX LDX #$60 ; RTS - STX NEXTOP - JSR LABX - LDX #$C8 ; INY - STX NEXTOP - JMP ADD -ADDAW LDX #$60 ; RTS - STX NEXTOP - JSR LAW - LDX #$C8 ; INY - STX NEXTOP - JMP ADD -ADDAWX LDX #$60 ; RTS - STX NEXTOP - JSR LAWX - LDX #$C8 ; INY - STX NEXTOP - JMP ADD +ADDAB INY ;+INC_IP + LDA (IP),Y + STA TMP + TYA ; QUICKY CLEAR OUT MSB + +ACCMEM8 ; 8 BIT A/M + LDA (TMP) + +ACCMEM16 ; 16 BIT A/M + INY ;+INC_IP + CLC + ADC TOS,S + STA TOS,S + JMP NEXTOP +ADDABX INY ;+INC_IP + LDA (IP),Y + STA TMP + TYA ; QUICKY CLEAR OUT MSB + STX ALTRDOFF + +ACCMEM8 ; 8 BIT A/M + LDA (TMP) + +ACCMEM16 ; 16 BIT A/M + STX ALTRDON + INY ;+INC_IP + CLC + ADC TOS,S + STA TOS,S + JMP NEXTOP +ADDAW INY ;+INC_IP + LDA (IP),Y + STA TMP + LDA (TMP) + INY ;+INC_IP + CLC + ADC TOS,S + STA TOS,S + JMP NEXTOP +ADDAWX INY ;+INC_IP + LDA (IP),Y + STA TMP + STX ALTRDOFF + LDA (TMP) + STX ALTRDON + INY ;+INC_IP + CLC + ADC TOS,S + STA TOS,S + JMP NEXTOP ;* ;* INDEX VALUE FROM ABSOLUTE ADDRESS ;* -IDXAB LDX #$60 ; RTS - STX NEXTOP - JSR LAB - LDX #$C8 ; INY - STX NEXTOP - JMP IDXW -IDXABX LDX #$60 ; RTS - STX NEXTOP - JSR LABX - LDX #$C8 ; INY - STX NEXTOP - JMP IDXW -IDXAW LDX #$60 ; RTS - STX NEXTOP - JSR LAW - LDX #$C8 ; INY - STX NEXTOP - JMP IDXW -IDXAWX LDX #$60 ; RTS - STX NEXTOP - JSR LAWX - LDX #$C8 ; INY - STX NEXTOP - JMP IDXW +IDXAB INY ;+INC_IP + LDA (IP),Y + STA TMP + TYA ; QUICKY CLEAR OUT MSB + +ACCMEM8 ; 8 BIT A/M + LDA (TMP) + +ACCMEM16 ; 16 BIT A/M + INY ;+INC_IP + ASL + CLC + ADC TOS,S + STA TOS,S + JMP NEXTOP +IDXABX INY ;+INC_IP + LDA (IP),Y + STA TMP + TYA ; QUICKY CLEAR OUT MSB + STX ALTRDOFF + +ACCMEM8 ; 8 BIT A/M + LDA (TMP) + +ACCMEM16 ; 16 BIT A/M + STX ALTRDON + INY ;+INC_IP + ASL + CLC + ADC TOS,S + STA TOS,S + JMP NEXTOP +IDXAW INY ;+INC_IP + LDA (IP),Y + STA TMP + LDA (TMP) + INY ;+INC_IP + ASL + CLC + ADC TOS,S + STA TOS,S + JMP NEXTOP +IDXAWX INY ;+INC_IP + LDA (IP),Y + STA TMP + STX ALTRDOFF + LDA (TMP) + STX ALTRDON + INY ;+INC_IP + ASL + CLC + ADC TOS,S + STA TOS,S + JMP NEXTOP ;* ;* STORE VALUE TO ADDRESS ;* From 53c832da58c9ae14f3e4d9f68534fc5e0653ad7a Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Wed, 14 Mar 2018 18:43:21 -0700 Subject: [PATCH 035/147] Fix ADDx ops --- src/vmsrc/apple/plvm02.s | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/vmsrc/apple/plvm02.s b/src/vmsrc/apple/plvm02.s index 33ed7ff..7765974 100755 --- a/src/vmsrc/apple/plvm02.s +++ b/src/vmsrc/apple/plvm02.s @@ -1152,6 +1152,7 @@ IDXLWX INY ;+INC_IP LDA TMPH ADC ESTKH,X STA ESTKH,X + STA ALTRDON LDY IPY JMP NEXTOP ;* @@ -1250,37 +1251,37 @@ ADDABX INY ;+INC_IP JMP NEXTOP ADDAW INY ;+INC_IP LDA (IP),Y - STA TMPL + STA SRCL INY ;+INC_IP LDA (IP),Y - STA TMPH + STA SRCH STY IPY LDY #$00 - LDA (TMP),Y + LDA (SRC),Y CLC ADC ESTKL,X STA ESTKL,X INY - LDA (TMP),Y + LDA (SRC),Y ADC ESTKH,X STA ESTKH,X LDY IPY JMP NEXTOP ADDAWX INY ;+INC_IP LDA (IP),Y - STA TMPL + STA SRCL INY ;+INC_IP LDA (IP),Y - STA TMPH + STA SRCH STY IPY STA ALTRDOFF LDY #$00 - LDA (TMP),Y + LDA (SRC),Y CLC ADC ESTKL,X STA ESTKL,X INY - LDA (TMP),Y + LDA (SRC),Y ADC ESTKH,X STA ESTKH,X STA ALTRDON @@ -1380,7 +1381,7 @@ IDXAWX INY ;+INC_IP STA ESTKH,X STA ALTRDON LDY IPY - JMP IDXW + JMP NEXTOP ;* ;* STORE VALUE TO ADDRESS ;* From 934b04ae56d1bc51c633b69227e8691e355a885f Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Wed, 14 Mar 2018 19:19:01 -0700 Subject: [PATCH 036/147] Update images --- PLASMA-SOS2.PO | Bin 143360 -> 143360 bytes PLASMA-SYS2.PO | Bin 143360 -> 143360 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/PLASMA-SOS2.PO b/PLASMA-SOS2.PO index 3f44ddeb59790353ee3bac095af342c8ae5b084a..5508da09f0927d49cb439098800bcf21db2d36e8 100644 GIT binary patch delta 36 rcmZp8z|ru4V}mmbuZxP5fHK2l28KKpGoj`Hmi7P^#_a(tOdGTT$Xf~G delta 36 rcmZp8z|ru4V}mmbuagR!s4~N228KKpNuK5ami7P^#_a(tOdGTT#Ip&m diff --git a/PLASMA-SYS2.PO b/PLASMA-SYS2.PO index 0fc1d67ba334362f955e998095035c95ad68093c..6c699f789590e3c9273513cb954a448e61fe0af6 100644 GIT binary patch delta 1879 zcma)6e@t6d7=8CaN>?`5)n>L7OLfx(LP#}px1!fSUO;9jBaf=HiST(Gpn16CE>mMv2d?W&9$xPp4+NjhW$Sm zHWh&yzj=KdUn*67H#l8x{l$7i?`gI-g*;(L% z5}6}+iB=X`Hd-uIO109i3@E#l{mL~tA%71e(107T0X3lkd<6@`8(To!5BR@(l%#6PURUeF!%Ci>=&dn1O< zkRx=MUkD7(*WKV!sGSdF5%z*?ZixtbBb@<9HnH5a#I5Xeahk(?Fgb6qvpY|7P66d} z1#B^IL}QCl@d{gfB$m_}iRUwszbZ@3F%=Zl#&(tgeWj1-p{Yy`sT7uQx~VLRN~Bnu zigwwG`sQ7nSC#AxdR5t0G6hs%WlhG2DQi5F%8Dl-R2esSuLN1%`8_1Jth!e)E8XO; zPWw6?a!j9|`D8jS{AnEH?ZiJ)a);-mR$=JDk{6@ai?xnW2g||phg)i^Zk@$C`&#` zq&DnnbVHYpHSRGRnVFBw#;Q>_a_K3S{T(l+#U?3Pnj+b$N!WTVV-`?zsJ<2ziEXnR zM3Y!4?hr#LjQ&Fg{5#U%eYhQW;R+nZSMdb7NuHEj#YJ(Qv`czTdK%Wl_fRi-96gH~ z&>nOM4Iv-;$@#?z@Q~#*d<2hU86U$l_*LABk4OQj7y4jS(nAC_$a(n$*a5E5YrhD_ ze4vJ3gNc_&9ho5ikZsh2UaFAZl6s|P`0mG@&>ukgUG6KxUhpYkN1H(h+3i1A5LiWcBl!z+(UhX*o|0*%JT;Aqrjgw7 z%dm6PS@1l&thU(T6^k!+&JxV1Cqe2sg;UqLlrNUMrj@?fs;ac=vXRxYkL8k7I2Xt$ zXJF@rv)~yTw^KDvzc`Kkg>kTxADsmH(sx!!1qaHy1T7zM R_D_Hh{aU^sjLw2r{s)9`2fY9Q delta 1926 zcma)*Z%h+s9LJyMs1~JzwzPt_ltUY$H>6!gGIbe@sf)t`hu)S-%z}!pV&KKb5@5?< zPDtFwrgT`hC9YOyXyzt=L??3;oo)&%P5^%UT8+LKp++W^!!mm2)6ZkJgP{!9XS&UGpO$vszf zUOk-caTxYe_M@x6JsMf%{?#3~gl(-}K0MyKjSnAgEhm-#MDklDPN_w>GS(&>7dnN0 zVM{^KSf^}|7yHv{Go77ltmU*A_vaHuS?YukPOmFX|2>M z1*J>Uh~%$Kq3O5`qPbCT)Dqnk{YE}3e}{(9A$%I&K@=Xu6WD(;rLqT7f5C3^5^5d+ zK8eOifVamFk^nPe5~@djREDePAK)Uw=os$9)5wTL`~dfyv`i&5hAW!mG>gK6&2i7z z=wqtaP^E_a8d81J8lOt4PbJkiJv!L+puJytM2`0lwe$YZm+qR&;J{C2DAQ1$hN?BB z`qX_?pGvAvCDk`Q+RL{`dT+cRiFxh=Qv08=byB5L&u!Zyit2Fr|8Oi@+2I;0YUgVQ zJaG`d8xn#^G*M~?l;FIgxkF+wjcER?Oo!qr%v_b%;Zg=4kNoSKAw8+2M^Rg;fw_g& zgvT@45DJNh~AkGNK0TJhUZN6I!lN0S{Ls218PiR;Y@Hj)GDtJVFH9lOtjWCVKg{$sp_< zI6OI*AtfXS^`xivM(rhXV#Ff{9mx-(hr%Lpi?~D7AuD=_7UMp0Jwy~kX?PW0hc^d4 zJ_EDp6v-|XO1mVNv`xB$@8QqHPO%8>LD$8YxE~!uf#EZ7ExAOG;JI#CK+PiplEz4c zCix71V6k?f9dnw50qShx#UO!?_D5&g&a-f0xYDC zjKI267ojBwa6!9o0lf!Q7&dv5K+Zx^a$RZeoFhO9UvYS93~v7i D#s$Zn From 3d84a2192c9cadd67cad01de218b59e63bdd9bb5 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Wed, 14 Mar 2018 21:34:55 -0700 Subject: [PATCH 037/147] BREQ and BRNE ops --- src/toolsrc/codegen.c | 46 +++++++++++++++++++++++++++++++++++++++ src/toolsrc/codegen.h | 10 +++++---- src/vmsrc/apple/plvm01.s | 20 ++++++++++++++++- src/vmsrc/apple/plvm02.s | 22 +++++++++++++++++-- src/vmsrc/apple/plvm03.s | 23 ++++++++++++++++---- src/vmsrc/apple/plvm802.s | 16 ++++++++++++-- src/vmsrc/c64/plvmc64.s | 20 ++++++++++++++++- 7 files changed, 143 insertions(+), 14 deletions(-) diff --git a/src/toolsrc/codegen.c b/src/toolsrc/codegen.c index 4255bba..e4419d2 100755 --- a/src/toolsrc/codegen.c +++ b/src/toolsrc/codegen.c @@ -867,6 +867,16 @@ void emit_caseblock(int casecnt, int *caseof, int *casetag) printf("\t%s\t_B%03d-*\n", DW, casetag[i]); } } +void emit_breq(int tag) +{ + printf("\t%s\t$22\t\t\t; BREQ\t_B%03d\n", DB, tag); + printf("\t%s\t_B%03d-*\n", DW, tag); +} +void emit_brne(int tag) +{ + printf("\t%s\t$24\t\t\t; BRNE\t_B%03d\n", DB, tag); + printf("\t%s\t_B%03d-*\n", DW, tag); +} void emit_brfls(int tag) { printf("\t%s\t$4C\t\t\t; BRFLS\t_B%03d\n", DB, tag); @@ -1606,6 +1616,36 @@ int crunch_seq(t_opseq **seq, int pass) break; } break; // LOGIC_NOT_CODE + case EQ_CODE: + switch (opnext->code) + { + case BRFALSE_CODE: + op->code = BRNE_CODE; + op->tag = opnext->tag; + freeops = 1; + break; + case BRTRUE_CODE: + op->code = BREQ_CODE; + op->tag = opnext->tag; + freeops = 1; + break; + } + break; // EQ_CODE + case NE_CODE: + switch (opnext->code) + { + case BRFALSE_CODE: + op->code = BREQ_CODE; + op->tag = opnext->tag; + freeops = 1; + break; + case BRTRUE_CODE: + op->code = BRNE_CODE; + op->tag = opnext->tag; + freeops = 1; + break; + } + break; // NE_CODE case SLB_CODE: if ((opnext->code == LLB_CODE) && (op->offsz == opnext->offsz)) { @@ -1924,6 +1964,12 @@ int emit_pending_seq() case BROR_CODE: emit_bror(op->tag); break; + case BREQ_CODE: + emit_breq(op->tag); + break; + case BRNE_CODE: + emit_brne(op->tag); + break; case BRFALSE_CODE: emit_brfls(op->tag); break; diff --git a/src/toolsrc/codegen.h b/src/toolsrc/codegen.h index 2ea225b..6288330 100755 --- a/src/toolsrc/codegen.h +++ b/src/toolsrc/codegen.h @@ -64,10 +64,12 @@ typedef struct _opseq { #define BRNCH_CODE 0x0320 #define BRFALSE_CODE 0x0321 #define BRTRUE_CODE 0x0322 -#define BRAND_CODE 0x323 -#define BROR_CODE 0x324 -#define CODETAG_CODE 0x0325 -#define NOP_CODE 0x0326 +#define BREQ_CODE 0x0323 +#define BRNE_CODE 0x0324 +#define BRAND_CODE 0x325 +#define BROR_CODE 0x326 +#define CODETAG_CODE 0x0327 +#define NOP_CODE 0x0328 #define ADDLB_CODE 0x0330 #define ADDLW_CODE 0x0331 #define ADDAB_CODE 0x0332 diff --git a/src/vmsrc/apple/plvm01.s b/src/vmsrc/apple/plvm01.s index 9a9db1f..cf9c67d 100644 --- a/src/vmsrc/apple/plvm01.s +++ b/src/vmsrc/apple/plvm01.s @@ -111,7 +111,7 @@ COMP LDA #$FF !ALIGN 255,0 OPTBL !WORD CN,CN,CN,CN,CN,CN,CN,CN ; 00 02 04 06 08 0A 0C 0E !WORD CN,CN,CN,CN,CN,CN,CN,CN ; 10 12 14 16 18 1A 1C 1E - !WORD MINUS1,NEXTOP,NEXTOP,LA,LLA,CB,CW,CS ; 20 22 24 26 28 2A 2C 2E + !WORD MINUS1,BREQ,BRNE,LA,LLA,CB,CW,CS ; 20 22 24 26 28 2A 2C 2E !WORD DROP,DROP2,DUP,DIVMOD,ADDI,SUBI,ANDI,ORI ; 30 32 34 36 38 3A 3C 3E !WORD ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E !WORD BRNCH,SEL,CALL,ICAL,ENTER,LEAVE,RET,CFFB ; 50 52 54 56 58 5A 5C 5E @@ -853,6 +853,24 @@ BROR LDA ESTKL,X BNE BRNCH INX ; DROP LEFT HALF OF OR BNE NOBRNCH +BREQ INX + INX + LDA ESTKL-2,X + CMP ESTKL-1,X + BNE NOBRNCH + LDA ESTKH-2,X + CMP ESTKH-1,X + BEQ BRNCH + BNE NOBRNCH +BRNE INX + INX + LDA ESTKL-2,X + CMP ESTKL-1,X + BNE BRNCH + LDA ESTKH-2,X + CMP ESTKH-1,X + BNE BRNCH + BEQ NOBRNCH BRTRU INX LDA ESTKH-1,X ORA ESTKL-1,X diff --git a/src/vmsrc/apple/plvm02.s b/src/vmsrc/apple/plvm02.s index 7765974..e26c33b 100755 --- a/src/vmsrc/apple/plvm02.s +++ b/src/vmsrc/apple/plvm02.s @@ -195,7 +195,7 @@ VMCORE = * !ALIGN 255,0 OPTBL !WORD CN,CN,CN,CN,CN,CN,CN,CN ; 00 02 04 06 08 0A 0C 0E !WORD CN,CN,CN,CN,CN,CN,CN,CN ; 10 12 14 16 18 1A 1C 1E - !WORD MINUS1,NEXTOP,NEXTOP,LA,LLA,CB,CW,CS ; 20 22 24 26 28 2A 2C 2E + !WORD MINUS1,BREQ,BRNE,LA,LLA,CB,CW,CS ; 20 22 24 26 28 2A 2C 2E !WORD DROP,DROP2,DUP,DIVMOD,ADDI,SUBI,ANDI,ORI ; 30 32 34 36 38 3A 3C 3E !WORD ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E !WORD BRNCH,SEL,CALL,ICAL,ENTER,LEAVE,RET,CFFB ; 50 52 54 56 58 5A 5C 5E @@ -396,7 +396,7 @@ LCDEFCMD = *-28 ; DEFCMD IN LC MEMORY !ALIGN 255,0 OPXTBL !WORD CN,CN,CN,CN,CN,CN,CN,CN ; 00 02 04 06 08 0A 0C 0E !WORD CN,CN,CN,CN,CN,CN,CN,CN ; 10 12 14 16 18 1A 1C 1E - !WORD MINUS1,NEXTOP,NEXTOP,LA,LLA,CB,CW,CSX ; 20 22 24 26 28 2A 2C 2E + !WORD MINUS1,BREQ,BRNE,LA,LLA,CB,CW,CSX ; 20 22 24 26 28 2A 2C 2E !WORD DROP,DROP2,DUP,DIVMOD,ADDI,SUBI,ANDI,ORI ; 30 32 34 36 38 3A 3C 3E !WORD ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E !WORD BRNCH,SEL,CALLX,ICALX,ENTER,LEAVEX,RETX,CFFB ; 50 52 54 56 58 5A 5C 5E @@ -1645,6 +1645,24 @@ BROR LDA ESTKL,X BNE BRNCH INX ; DROP LEFT HALF OF OR BNE NOBRNCH +BREQ INX + INX + LDA ESTKL-2,X + CMP ESTKL-1,X + BNE NOBRNCH + LDA ESTKH-2,X + CMP ESTKH-1,X + BEQ BRNCH + BNE NOBRNCH +BRNE INX + INX + LDA ESTKL-2,X + CMP ESTKL-1,X + BNE BRNCH + LDA ESTKH-2,X + CMP ESTKH-1,X + BNE BRNCH + BEQ NOBRNCH BRTRU INX LDA ESTKH-1,X ORA ESTKL-1,X diff --git a/src/vmsrc/apple/plvm03.s b/src/vmsrc/apple/plvm03.s index 0343c1a..b319393 100755 --- a/src/vmsrc/apple/plvm03.s +++ b/src/vmsrc/apple/plvm03.s @@ -140,7 +140,7 @@ VMCORE = * !ALIGN 255,0 OPTBL !WORD CN,CN,CN,CN,CN,CN,CN,CN ; 00 02 04 06 08 0A 0C 0E !WORD CN,CN,CN,CN,CN,CN,CN,CN ; 10 12 14 16 18 1A 1C 1E - !WORD MINUS1,NEXTOP,NEXTOP,LA,LLA,CB,CW,CS ; 20 22 24 26 28 2A 2C 2E + !WORD MINUS1,BREQ,BRNE,LA,LLA,CB,CW,CS ; 20 22 24 26 28 2A 2C 2E !WORD DROP,DROP2,DUP,DIVMOD,ADDI,SUBI,ANDI,ORI ; 30 32 34 36 38 3A 3C 3E !WORD ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E !WORD BRNCH,SEL,CALL,ICAL,ENTER,LEAVE,RET,CFFB ; 50 52 54 56 58 5A 5C 5E @@ -1021,9 +1021,24 @@ BROR LDA ESTKL,X BNE BRNCH INX ; DROP LEFT HALF OF OR BNE NOBRNCH -;* -;* BRANCHES -;* +BREQ INX + INX + LDA ESTKL-2,X + CMP ESTKL-1,X + BNE NOBRNCH + LDA ESTKH-2,X + CMP ESTKH-1,X + BEQ BRNCH + BNE NOBRNCH +BRNE INX + INX + LDA ESTKL-2,X + CMP ESTKL-1,X + BNE BRNCH + LDA ESTKH-2,X + CMP ESTKH-1,X + BNE BRNCH + BEQ NOBRNCH BRTRU INX LDA ESTKH-1,X ORA ESTKL-1,X diff --git a/src/vmsrc/apple/plvm802.s b/src/vmsrc/apple/plvm802.s index 947b10f..9351938 100644 --- a/src/vmsrc/apple/plvm802.s +++ b/src/vmsrc/apple/plvm802.s @@ -233,7 +233,7 @@ VMCORE = * !ALIGN 255,0 OPTBL !WORD CN,CN,CN,CN,CN,CN,CN,CN ; 00 02 04 06 08 0A 0C 0E !WORD CN,CN,CN,CN,CN,CN,CN,CN ; 10 12 14 16 18 1A 1C 1E - !WORD MINUS1,NEXTOP,NEXTOP,LA,LLA,CB,CW,CS ; 20 22 24 26 28 2A 2C 2E + !WORD MINUS1,BREQ,BRNE,LA,LLA,CB,CW,CS ; 20 22 24 26 28 2A 2C 2E !WORD DROP,DROP2,DUP,DIVMOD,ADDI,SUBI,ANDI,ORI ; 30 32 34 36 38 3A 3C 3E !WORD ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E !WORD BRNCH,SEL,CALL,ICAL,ENTER,LEAVE,RET,CFFB ; 50 52 54 56 58 5A 5C 5E @@ -466,7 +466,7 @@ LCDEFCMD = *-28 ; DEFCMD IN LC MEMORY !ALIGN 255,0 OPXTBL !WORD CN,CN,CN,CN,CN,CN,CN,CN ; 00 02 04 06 08 0A 0C 0E !WORD CN,CN,CN,CN,CN,CN,CN,CN ; 10 12 14 16 18 1A 1C 1E - !WORD MINUS1,NEXTOP,NEXTOP,LA,LLA,CB,CW,CSX ; 20 22 24 26 28 2A 2C 2E + !WORD MINUS1,BREQ,BRNE,LA,LLA,CB,CW,CSX ; 20 22 24 26 28 2A 2C 2E !WORD DROP,DROP2,DUP,DIVMOD,ADDI,SUBI,ANDI,ORI ; 30 32 34 36 38 3A 3C 3E !WORD ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E !WORD BRNCH,SEL,CALLX,ICALX,ENTER,LEAVEX,RETX,CFFB ; 50 52 54 56 58 5A 5C 5E @@ -1408,6 +1408,18 @@ BROR LDA TOS,S BNE BRNCH PLA ; DROP LEFT HALF OF OR BRA NOBRNCH +BREQ PLA + CMP TOS,S + BNE + + PLA + BRA BRNCH +BRNE PLA + CMP TOS,S + BEQ + + PLA + BRA BRNCH ++ PLA + BRA NOBRNCH BRTRU PLA BNE BRNCH NOBRNCH INY ;+INC_IP diff --git a/src/vmsrc/c64/plvmc64.s b/src/vmsrc/c64/plvmc64.s index cb61aad..0c8d6e1 100644 --- a/src/vmsrc/c64/plvmc64.s +++ b/src/vmsrc/c64/plvmc64.s @@ -111,7 +111,7 @@ COMP LDA #$FF !ALIGN 255,0 OPTBL !WORD CN,CN,CN,CN,CN,CN,CN,CN ; 00 02 04 06 08 0A 0C 0E !WORD CN,CN,CN,CN,CN,CN,CN,CN ; 10 12 14 16 18 1A 1C 1E - !WORD MINUS1,NEXTOP,NEXTOP,LA,LLA,CB,CW,CS ; 20 22 24 26 28 2A 2C 2E + !WORD MINUS1,BREQ,BRNE,LA,LLA,CB,CW,CS ; 20 22 24 26 28 2A 2C 2E !WORD DROP,DROP2,DUP,DIVMOD,ADDI,SUBI,ANDI,ORI ; 30 32 34 36 38 3A 3C 3E !WORD ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E !WORD BRNCH,SEL,CALL,ICAL,ENTER,LEAVE,RET,CFFB ; 50 52 54 56 58 5A 5C 5E @@ -889,6 +889,24 @@ BROR LDA ESTKL,X BNE BRNCH INX ; DROP LEFT HALF OF OR BNE NOBRNCH +BREQ INX + INX + LDA ESTKL-2,X + CMP ESTKL-1,X + BNE NOBRNCH + LDA ESTKH-2,X + CMP ESTKH-1,X + BEQ BRNCH + BNE NOBRNCH +BRNE INX + INX + LDA ESTKL-2,X + CMP ESTKL-1,X + BNE BRNCH + LDA ESTKH-2,X + CMP ESTKH-1,X + BNE BRNCH + BEQ NOBRNCH BRTRU INX LDA ESTKH-1,X ORA ESTKL-1,X From c07bc8172cc41937f7f7d14455fdedc072707067 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Thu, 15 Mar 2018 07:59:16 -0700 Subject: [PATCH 038/147] Shrink a few bytes to fit --- src/vmsrc/apple/plvm03.s | 18 ++++++------------ src/vmsrc/apple/soscmd.pla | 8 +++++--- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/src/vmsrc/apple/plvm03.s b/src/vmsrc/apple/plvm03.s index b319393..fd1a9fd 100755 --- a/src/vmsrc/apple/plvm03.s +++ b/src/vmsrc/apple/plvm03.s @@ -634,12 +634,9 @@ LW LDA ESTKL,X LDA (ESTKH-1,X) STA ESTKL,X INC ESTKH-1,X - BEQ + - LDA (ESTKH-1,X) - STA ESTKH,X - JMP NEXTOP -+ INC ESTKH,X - LDA (ESTKH-1,X) + BNE + + INC ESTKH,X ++ LDA (ESTKH-1,X) STA ESTKH,X JMP NEXTOP ;* @@ -771,12 +768,9 @@ SW LDA ESTKL,X STA (ESTKH-1,X) LDA ESTKH+1,X INC ESTKH-1,X - BEQ + - STA (ESTKH-1,X) - INX - JMP DROP -+ INC ESTKH,X - STA (ESTKH-1,X) + BNE + + INC ESTKH,X ++ STA (ESTKH-1,X) ;* ;* DROP TOS, TOS-1 ;* diff --git a/src/vmsrc/apple/soscmd.pla b/src/vmsrc/apple/soscmd.pla index 7b89fc1..b5bf840 100755 --- a/src/vmsrc/apple/soscmd.pla +++ b/src/vmsrc/apple/soscmd.pla @@ -938,12 +938,14 @@ def init_cons()#0 dev_control(devcons, $02, @nlmode) end def cout(ch)#0 + byte nc + + nc = 1 if ch == $0D ch = $0A0D - write(refcons, @ch, 2) - else - write(refcons, @ch, 1) + nc = 2 fin + write(refcons, @ch, nc) end def crout()#0 cout($0D) From b8714745dd480a2e1f89cda2883ebcf9e6a8c41d Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Thu, 15 Mar 2018 11:16:58 -0700 Subject: [PATCH 039/147] Add BRGT/BRLT FOR/NEXT optimization --- PLASMA-BLD2.PO | Bin 143360 -> 143360 bytes PLASMA-DEM2.PO | Bin 143360 -> 143360 bytes PLASMA-SOS2.PO | Bin 143360 -> 143360 bytes PLASMA-SYS2.PO | Bin 143360 -> 143360 bytes src/toolsrc/codegen.c | 16 +++++++++++++++- src/toolsrc/codegen.h | 12 ++++++++---- src/toolsrc/codeopt.pla | 10 ++++++++++ src/toolsrc/codeseq.plh | 2 ++ src/toolsrc/parse.c | 5 ++--- src/toolsrc/parse.pla | 4 +--- 10 files changed, 38 insertions(+), 11 deletions(-) diff --git a/PLASMA-BLD2.PO b/PLASMA-BLD2.PO index 096af24cd1813318120332a509063e3da91f1486..26f70593374db6bf555d6855d58746002867d7d2 100644 GIT binary patch delta 14637 zcmb8$30zd=!uav$IUE*QhXL7P5J$uj5z$-`P;u)5PB@yP8PPa#$TSs zU7~H^+r`7GDXW2O6wuQlIJO#7i-Wp^E5k8$Q-nGJ0r^wPc9kKea#v zh(N`c{&L2(zKm^(B4fF=Y}k;JVXYa5ix^Sgxn0JyS7+=t%4V|`U&=;}RU%USme?-i zz`&$-jlU^SZ~PT)=vqFeO+geji^dNQXjjzM!1#XAldg0u#72iY#8HR!6=CXO0jQZnXpR`nPe`}&8bO;=x? zvHQpo6N-nIwq{k2bD7!gFZ1kw$yhwHTp!;{b*detD#ix3YwEz@c3r*Wrr)fu~vu#Rh!PpJJwpg0%Y?jp~YC-uH!g@uXaYsX9+IE=*jNw<9+XT4T9#FQUal!f!Itkz@t>oH&OiZC~vX)?*u zh7K3Il$Iu2rd>)=p-fPujhNatF{+}+%=N`M6x-PN3Uz`%Zr&Afdd`NsFJ@BilNYmG z5##nJ#LTn#SneN|i&H4Wed?9;{WXwud;>nHx_veJLqpgb?_IXXx-f+U(Iikp)h_PW9Rz}MY zJFHH!cH+({cC7qf<^{}Zu4yQ`5UcfN!WE86sDbL$&oxwN)im1Wo9mT1(03Q2Pg0nziSp9Fe)* zD=Ion2vQux*X)e0{vg`6I<;0U%b{(=JRe=Nn;0!!k$KYh){vj47+0%SKyS{W!0%UgH79Vi=Ac}A-Y zmD3{z3r7$gmK~z5FqpN^LS=8cUyBZt1thSB$v(W@8zyf^dq&iT=%W!*zEwV%#7%4{vt7`T8#`4|TeUWl$$LRr<1GA4BYmOM}=N!@BDlL;UwCpH3 zF0*5|IiKh;OZ_M6D=l3!LPWNz+8nV&_g9Fwp3pW%$@C6O#HFl9qhy8bsP!<=nbWjN zgG?PArf`z%JWSD)6$=4us)q$^Plink)@|6dx2RyWRNEF`j(Uh zddiRgTgo10Eizh~LMvNRb~kJNIX3reoAc;@%Q@Jr-9yTPUs~$S*Xww@ZOWl7XMFA4 z-}X$Kc7CSUuC=5bXx4&_(ln*E<+#wyUFwy#Ic=i)s8PuX^7W2&gorSU;Z0q|k){kW z>0(cj-8@*7Hun(q&E3UY%?09z=6uo9J5b!`Efmjsg*f0HBwo=L8|83$PJ7!ZyBhR0 z>>p9vxo)}E+ch;tj?FkNM9tgAK9vh*)Eqa~&pU3+k17immK?S;B(wa@ykDCWBYOlA zem_HdHb&kTO>W!kIg_meMD@z&xz9^TZb_o^jYtQ#bzDYPup9KB7cG+XovGyCXaM}Td6?x>Ow zVOx-E>)A_B4mV{RWnFDQ1gP1fmi$I_VbZ|(jB*)x|+V}&D@IGf4rjOEs;FIl~3 zt&@Z!G(Vj-`H%H%pPRKa39?&mqqkXX^gbarc%KoQy`PKcy_>~0?>=$VE9!#n!DWkm z{U0P-8!U08DsO?6b%EA>`o%ekHrOtg^bGf8qHSw3ocb)ubqISnV+_D>h> zmqeK|EUY!5sNk8vgmwr*HZhu_+cd$~&VC~JnE0dlkeI;`Ph+U>@op5$w6RID%W!(` zytEbcaT;n99C5Z6;@Z}wccAYom^`Y(H+w=9y;DnlOJ}_~USt_;fA-e)CCS*Rg*l{E zOL&0AS*mPd+L2_L>>@ngMr-5jLE8eC)&+?=RjCUkVWl(F-;1|PUlk#uJ`sG^ z;BT0=Em@kRudV5MW^P5+01@I0%`$RTWnudCvn|YFT{?^`AV-|T$e_^ovW0a2b0N3;3VFr+S6|ha3(@{alhMQ5S ztS#lU&3V72t;&CGt9G49ntI#&>XM%jBS){p|-)qCa6IB$|NT-xP|G`7Wh~&y`uftMHUhBNxDqUrj0>t^Q=LFM^dgW zJ-_UC-|SzcuZ`Q8n6`b1+)Gv`UCMY16C}v4D#c~zyuRKtuz@Ne$)%F+_T|6V+@(!s z{ibt86_m@Cm5&;F(Y^!yN*4Q;oI$?@{6%}algtgJ^4K<&m$#{$YRfpeq%%*M_N~9a zwV;~s^qL&{HFEzU6h7x$qa$+8cSd{Q?5~Vgm-c9e?A~*A(p62=8?>T*IeNxRJ< z2Z3)|xZ0fKkt&=)Oi;QmM1L`h;u3CJT-?z_iq-?C5*n}aUHX~7A3f7H! zPnJK-hDsZkDLc8CuWhH9^)`AZt@>-DWpzfF&{sljn!Z+2^huWGusE`93lfDh#gSG* zThoaBuQTkS*5S3L_?93Kq<{x`l-7$Uyo&gb*WV%4M_oqCLuQ-Tkx~-p>-qLoIV|ir zbK6|Cf9Cxxi6Tq&S4P@l$+I;l=xO%p(I#s`wXluL5BGbAAyIOPFID#~Mg0%9*lD^X* zL0Jca>$HnqWm?-Q?CX2WWD2tWAkr&x1mAT`5^)QK{rCIC%0C*!4Sy~bX%`+4b(%Fx zj&?1~5w^rZwL$u9^WDE@=?_z9x=?I9jHsui(zg&^Eo!+f9xN)!_9xX>%d2LZU2j!| zWhqrU(s>HgEN-&?n_(wmjU};uWnmfmriB~c(mK_ymi^o7t8TL1d%mX-gQ^x)=4Z2z|*OGxzkhCYVifU63Ag+?=X!%bf=UQicv}*HlLbd!Q{T!5L;vZY`;UBdpD-1tX*B$vRuMHJjjdC(|GKmR z7MbOu#lo3n-K6)hn(-v}9p47h-MUfn-MB7Yb4;DlfBwpAR-6f<&Y-vWQg@~3-DPOo zU3%7ptGY}3#=>%Z(Bw$kp5RRKU$f?A&05?=TMWKoUr@9q*w?zEvLRl3G?P0^*rT~) zJZRF>FVPpB??$8denr}ZP)T&Thwosr4Riu$7lr8e-$}i5bLV^-ZGBAt;NZV^`#-6F zm}_)~=KV4qw|_yK$A1PelQG`Nz#Xe)YE01zg!1Ohf-3l0nn=p7sD`bsgX2*aK`I z7yEnWXRq~;Z##X=e7|sUfkINSzF7S2_iu~!S~i+{v?L5;!qwNQdb9k6obf%=FMpuC zbY{IdR%8Y0n_2yC;_CqN_^w^_@y#dJ*)n~d&F2PbS6xivH70%W_%_M@!l!zz-2_uG zL=&~m^Tnd(Rbo%`TCum;&4=;@;%xI8F_c^3=X~K5nqCpAXL_7%o8IKBo~D~R=}l|7 zQPTk1ZzIZn^)=o%=D{t4u2uJt{aiP9ve`O`IwgJfNuyrcMsvTG4v1qvS6`?2AJHKy z3+B=lH)ed^t}j}z#At7^173B1>hhvZ1x@*J?N`*J#UfWN!b(ogAVfctV&kIDK0cvYt=(zK_BG!*yQjf%WE&BJ;HG6U-HZ z9%vV~{@S9RvU1cKlOvc1Udu384EiYi#)oshR1~wnHeT@@6|=w8zv^hWCiUm)qZwLG zuIv`PE@9&zJVmrAxh(s+snutVWuNI|pmM)S=L40f2(x)j3?;XKlDXni>HiqTR<`9p z=q)(!wXICJbk=$;XZdb*&cCAdCg~G_*69s-BqOS|4F7i6*B0M%E1?5VGk+p2te3PU zyeeu6V)#a_D8{;3)D*>3@({L+G2f`o?j=VLHb;wUyRkr-Z8vhRUQacoHB}jFM?b5! zIorAQ?Dc#lnI{wE^;%M%JRxJX3wg3!YFb%uxiF$MStyfw3+46!LJ`{My=9?mWr9%F zp&8~xq4dQlOvVhb7g6@%C{BSt^(i4qLPS%UXrG7DudUhX24Gw72k zl;_Z~t56O?%Oc!ODCfWvT3L?QF+P_I!WwMHySame63~klBPdTO#rTsBD(E8=I}$mc zo-dS-i-mG*I9ESHDF5I~C;sT6#O@k@jod0-!$X9d+n9SM7U5y6!sFP0t#}ph;TXQf zIsA%0p>z=LV1ywGM#LcPk5n*3U@f75r;H%Miz2$4F-m~gnKA~kziBhwqYWs;AS{bi`!9$ zxmbt?u@oMx!dg5LDm?o`Rrl+J58(rx!f$AX3={4UL?Z<~kn7^5KMF7c*I^=VL=|RW z7VgC}*oqx^3;)FX_z!-h!fGHyf_ZpCaY!2MVn!T2{2ScMB{hKv;M2pAB9 zA`HU_+yN)Esu#>+U2FL1%dOOSz?3L_E>!jo(; zcsd!9+!l^=(HHr|4>d%(hZC+LJe}}N!gms$P55rY^9U~_yqNI)gqITb5MDu8BfOgM zz{xfx1a{MVFvDq79MAGxce@`bK&B6VYJb` zgzy7+2+PobRd|&1Ye@e$!cP)@inOl~-jCNfKEm;bgg?d?_zJ;B#y{35+3}Mz{y#1}wuie2OMy#R~T*Jd4+H8e2LF&&7@%Jqd9g-Gy;XT#UkBFcuRr9kVb8 z_quplhLuLs5cR@xt?u_;All@sXZ4IsYDU z|H4V)e<%JTWP-^Plo0Ojn80MlEeXQ2Bq7{W4^M*0{Wx*1&AdE^-Pnu6_zWlT6&b!E z;SYp=g-8^h4v8j@Au-CGlE@7P-H;8QyzXM~)r7kO)u_Wf)Z;Py9b2&%uj6ncM+74j5ilSIaY%#-8OQ{WbN4kULNP|71Y}T0DWL(1;hX2mA0Q-oiieA-=?^6vqDy zf$wnv%?L=PD-j7J62SKe?yks2AN0c@3_&TZ7>7x?1vQwCS(t-)ScGM0z#~|T&8dw4 zvjn!|1sud1cpD$!BOJ$euDE~@qXH* zdd`>v+~-L51INE{{sQ4<$aH!L!3aepqR|m4Fr_p8UDAaoE8XPIA)*)hpdSWeFp4k? ze}NTaQGuzb!ELw$d<*8DgLznpC0LG?cm$7Q6B@A-2k}O_i%kK6&u|i7aSlobR}KSW5Qk1ELjxXl@$xr3gXgdxZ{ZVsgYR$- zft@K7Rj9=*EW~0g$7(!*4R{)xu?=718+?cF@f(_7($yo@(+7$3NJ`3RrkA_6UR zF=CO7Y~*4Pif|n!pc1#^PRz%>ScS*&ckIM&?893)f{$<#|He-^4_8QcKDVJWvd|Nw zFdjGIcFe_mEW{E#fQR703arC+yom46gqUo454@! zUfhpW*n`73hEw)Kw1jb-8+*pPU*n}O}iI?yS4(2lc9})Nh-{W^QL+QmT zKn&uLh&1p;hr18*F&bqUkBOL!n_$OZQHwgv!97@r#dx5X@GS2Y=~>;2PeHvH|7}Em zh*S6p=kX_G9^Hy4bVE<{Mj=L_6y=zNYTSyMaAGc&;2~_l(|8`c@Dg6j6Q09)QSNtL z9K45PIF2vz4Zg=u_!Z4ido#X>Kpaw#fou%J2$Z56lVQgKEJXuW;|Vn4CA@`C;QE}G z5q;=Rl;V2a0KPwR*J2hH;9ji2qgaa#*p7eTb^H@YaT4F*d;EeX1YW}v5HUzY9)_U! z8peMdfg3ObPAtO1cpT4QKij*ovKa z6>qqBIgHQoCC;J=vOg6g7M;)qJ9he$2ipDPRxTFJMl6O;cfgANAV#(#aB23 z*Dt)B#|5YZm|!prU`sYYb!QXqi98HIK8kT2Y?z42s6;jHz+AYn1P|h2EXOK5fsJUy zR_qwS`0pg}G7jM=j^R_B#Mk&47a#`mxJ3tqBM~V`$1seSXK)rj;Afo2pJ;~6=SGE&NI){o$U-mlMLvdN1WGUl zW8oUlO9gH~HKt)E?#4X0@kqY#yppea_UEU1UdvB&ze(I%IEv4365o>MY<@@2MZ!UY z*(oD(u<&FLR^2@b_eNh7q8KCbm%)txbtD=$xTE_9BC0SIf5mj-?;!qe!t=2ZOVB|4 zs=;aQM+vXNdOStkrol1pXL;YoxgEsq#9r(p?f~Zw6Ml#A5yBr4K90`^GybOte1jix z9v8r`WZnF0Bu`{PjN4d1w-PoLnA~RGyYk+hxL$<&5zZ%Eh@lux+_eRf?o!^Z9FN8I zsK6BBrgE;D_gf1x+_w`~rytBJFnJy>P~FRkSjq9D1%aM51p)5A5q^>ip5}ck@6YqT zi}yXGdld)q262bUe~SFy5dN+}^_(jR@B|jB?vO&^2`f}Rk%a-C!d)+y$)U2rpezX+ z7OMYKiFku5254bcnbKz^fBoiXrj;2%{OPSCkb`o5_pbjS-x0t|OSH8@k5lzHwJJlK zVwF83wtKV0ey?4;>~)CU+G?xJk~P`^tL)<%(7_Q}Sw4p!v{Qm&&Jzx`(y~DR33R<9 zbcX5(t)HPd!>teSuL3G9i}d)VZR2O^@#ReczU<5N*O_|qY%)^b^45rCe?&=;5d2Ln zy)|A2XmhTUSt0-Omr$m;ualhyJ=by+B&IY|+LQi6GW!l2t~|S_<&a-k&v%4ARW6mV z%k7@FE7~THNcotSKVD{PA>;W0{t!JpQGTPX8qe#+ozN49z)ed!r?>D?(dacv{e+k#LNjO6A!xFAtEo(kZ`va6 zZfX>Zn}!NcQ;}HHlr6R;H!TqNG%phGH?I)gysN};?_z#s!;ee6)*NmA_40Xnmv+qr z`KsKdou43!2I)UwuHVA2gB3p8vp_;lz_D&TQCGHT9J(rSv3T~6M_~L=Q9o$@nTV4hm0pK%~(9jZnq6<%f=a}idgY;YKM&d zL(@7GeoCk+{6%FbtQp(xKpg583O^{M!=W~XCih)&^~I5zC>%O=*zmD7yQ;MMujMHb zF8&#Hak8d!q1hcznmlG~^@Y-N(szUuk+MTZTi7L~O&vAdY8`tatKkqC`vkkDT~lA0 zvFpeYwZn#wIiJ<=G1ctWv6?6TAmgx+HL8Ex&S{901~ERgLs9#OcWCOZQ^NlqYfuBF z$()qep&M*T9V!+rQb&xg8eYRmMg^PFV5DNpFR9q287(&J#4&ZYlF`*e133-xRIH}s z;5%_?#d$(IzqX#9}s;TOs-3~3@poJ#D_Mw>3p zSUi5%h#{(J+iG1%;jit`D_hScXZOE&1VxLq@zuk|4%)lrVObW zIsSY$hF&=tdtK7dmu4&+VVlq{pD^?lq2gqChf1EPN$Y*l42u@&myf-wYC>IITV}&R z&N!^Y8Kaw|w!7KBI_90h+B6}4j(3QxF+X3Uj43N?6SHV@b9vgi}oZVOezy-`YwQ(@({SW!0U9#lp5zsL1?a1o`&{WKAff%P|AD>)js13&5aZ#Mg*>uaf0$J0v z`dpERJhtFb{+@jPxQ|^D(|k$HnoDBVUJ|qJl9=@!Vsg?g8#+X#TQ**Zp{&l9{*?9c zmPus;M8k)14Ts_uxFbZvy12#7IigW(*bui}o9d*!jG|$q3O5?2Zi#RjX0JQi)ZIU& z`~A|XHHt;`HDjey)LXh$TAOL(%e1LxQL3)%l|EVhPYZ9n&QqS=%rG|WTepb^_G%KYlJYn47OM{FAJOM z)|^`Pzx6An%qy!&uM4dW3!$4=r#Urk<=p*o^wXVbPJ_K~rrnuV7gif-uvL@MX}B!B zzS63%mvThGvwl$*SsSJ~+0pPq+>C>9_9rqM4b>$SkC^A;8nzRokJe-teSjuA$w0U# zU$<#;h+M6|qDePfy+h=**O&M;?$Gs<3~KN}*`W!1KKLu9ce?JoxT zj=Xu>>!GsAAb->+M#&pvD}*zQM(Y+~SZ1Vb2cl#zxl<2|mKCHJ9xcoHnj0;z$=)Cu zBUGnEOm!O@w#02Q)?aTLs8v5meoG}e{~Imum$kY#MrO$h{jnHX)9ddA&Ir4?&>iMB zP_!8PzCykX&aeifm{>~t2vJ&Rs?~&Wi-!HCdP_cs$?qgT4ymj@rOQ}pk=N+mV&%y2 zM8k~tO*Q|}=f=v#N%KN1Z_GJhBFCb+`_)&yWm1(@&+IHG6y_Aq{YXVE4(?f0Zz-&z z>$({Xc4q?dmuc*B8AXIhIiFi?WM?NbhG-4#5@>+N@` ziiEe-WG97*UfG(sKc)MYi27Nr5rZqOT=rgVpL>FsaloWiS;GR2Xd59q<%{yOh2qt- zxx#v`hsbIfBr03F3vWwT@p?;zINmZ)6#M&&h5o_fX}=J!`v-_u^ywx!T%OUNG0DQX zN_9yH_P+g0ajDIve`S*6^NtJAu-8;xKYv!k$EHPhd~6!nxjI}}N*HD&vpia9eM7%0 zUUm;-<9+)4{&;zhiTw6sC6jFZ#f)jD8PiQvC_h2wWU9F6zyW7#)P^cd;oz~hYUT)gQJGtFNq3lSf&O%o%os3Tu-WjD$sMM- zHQQCf&~EFBz}CM^GY*>U=eT|_l^eBzvDSFu5JoB~lVx(;-TwE*68{@woqvzm;y)x_ z){B#6kA~Bw=DLX5P$4*;BhDS-kS-OrH}tfQR;N^rYl#z&4HVaF6s;gXZnMVq%c4$M zP_8zdA@)P1qnKd!wWW4@nMxFhx8GXY(-tb$yzO^LLzVSO{k3FSoDxXm4B=cOs(YnuC`Ua&*+|4Qe<)I)BYCmr2ld8g#T&rl>ala)xTbB^1mhy_=PLn z5njD8(Cp!|p|uh9DjjrP;IYFtNz9 zlKsV`^CzOQ0)vm*M5y6ma56rKjL=jIRtM(D6P4CvQDn5|mFvDVnb5hpgwzJEf6gS! zRC}WSXu3?-_oc~D4+Tzggl!I8>zNSKAYF8w1DXShkNXU3x;b#5S1Ya8|3QJG&KJwd+NfQz)VMnmoC>P+l-t%?Zqj|) zT6~Z8zm}hwt<}ZWTBL9l2v^~Z6DC(N#ZgTm|Z! zOoh+R$tWv>-6+Zeq0CccpTfTAkLGQ%&SB zhd~=webOIjAS25;D@oc8H8*g8g_YJW?Q*LN+C?Yfz$~J922#fkY^WOE6`ajRb%D7u ze8y3eD^$!mY6_euI7*WAM{{Ia6opD?SE%vr3Po|M+3CyUe%P^E_g*-D!?&sgPE~s@ zdxT=<9yd8-=YDH)gmOyTefor4*|l_a+9gF-1zmQ@fmF`6HtKqDajediw$^Dl9yqHy zSMW5u^t3!#mc$C+J9X;BYQ?b;+b1b>o5k%bnaB$l3b zEmfu2rMf9N=4|gtIz#n4lcs(AOLE2+ChI&w<3_ncY@LF+_0mF_7_Ft+rPUjk`ldpe)w^SRTP9H)+bLnLD-rxQbG1mi zQ%wBz9&z7qO=A3+#Uk4tKzCJIy9bl1w%b{$YQM;45SGQ9(`n|y8oVF}FOfOImOyG@DP={W)=69i7rP7& zL-lulbv{p~YA>Pg2y~>OvaY1IvnE_D!8@^SIaFya3zR3EmA5NQMSWap%~I=qm%$b4 z?xf1lZZ)F@gR_%UyDPY7N2PT-H{fnY!!mU#7#6{49AQ>2py3W4s*_~>MX9cD*9K&vdBXbg*(mmtZG(n{7-TH39M4R7uG?lEiP0v-en4= z=ulD3og!RD)dJ_6DMK}r@sivr?V2ep*w*@e7MUBrJlmPJCB>bl_H(0b^4pK;uUKT# z*nWOT97DHAIO4ckEYDU6?hZ_D*7^Z0pp+ zjk-qbIbCIZ5#iQrvihBXRBpktieFJ28e?I3wr!@gTSnNX=~s7^>9mu@TeTs0*PdUc zmTD0UE_G&67v&5L$_q{Qkef%Tkk*Q;zM}-LkapEpwPvUVSENqCayx?coVL=%PfCsu zd*SfbCOGZ4?GG%{Jv8cKHF$*N;A&1psK#Y*s>QZC)4ED)X&@;nqZvGlTn1IT)&u=J za7SDU(qi9j4Siy}Y!b#q{zC(`;4lc8$kXMA$p?eABu+ z(2x2{-DMY9r61|et!JRI3@?+(VAMd~LQfoO@hr|5%Kwdw%9=pC3NOoMWbo?ww-J z7wQL;j?+}#Odnb^`Ngmbk4OLKWf{zg&>_VOd}+{1CIRBDV+Kvk9%RjfVQk_Fev!Qyc9 z>SS+D;g;5#Ouwg8+EaInhKhK8*Q<=TZ4?ca@%7w$En_RK_4-exa`aV|JWtJVm@2e6 z4ikG9sdPinr>j;IOYJta+ns-Y_myqCBiileS%Lq@>rG|ybGb}+^^`SHPZZ5?ni^vG z@l-$6Q>NLTwtN1?ZP1( z#~H+=2`vkysDd3%(4QKQ3tHbyp)JG{IESh%q1_BETWBR%j!ui_@sc6Pgd7qBvh@Z{h7OLi-UF1w#8f%!NYRhbM}JmQze&!L3|-7RPXF zDaXTWIE2%s1E_TwH9*&%LTf-?xzMI#F>2XgKTv3e!-ZxULAsHggdevgrr|=tE5Ed!C(ddkLBq0s?=!P=%K?R0l6l|D) zNs+?ibr84?voHs@V?G|iqgaFIu>)`8T^zt+9KlyOfm8SyEeMGc-Ut|xh&1G)5ZzFY zeyE7@2=532SHOl^T!X2Yjt0!e&6tCExEo9GAeLh#n(?EvAp^Na;p<{F`nnp^yya~7MmGEl9j}u-)_({U+2|vU4W~0&T*+yVH5j)uV8s5O0#2qyn zykGPEjWN`B!WiQHmH6M$g77%ujY20RA{+TAL|2rcH!j0KjKFAAqYm|OV0s+=-$0-d zH^GHlFc-JS3E#Z981J2g@4~%oKM-f~`Uo$Bj+I!2$M6LE*OLAz!W#&0ChZ==d$Eu0 z!)zZR{3X7@NyM4x|11+10$htbu?hR|JJREYcO<4`CAQ;hge5S4QG;#Rk00=2qVR<$ zCHiuc61}677`Ujx1YCn_aVxx7fF&M2R^m~tNfN%TN!i|=gm>Xfw$qZceO;1cyhX`0 zEymzV%ug1+*OFs=Zzae2-e>@HP(M1AKC_`TiKm|r%4D6T$kB5)>ScrSE2rID)%~+3Tuo=(cMZAnx@dozbeSCn=@FkAn zB>szY2+QC?hVCdsZ(N3f@C@c-7)HU0v6zT@G~fo@1Q+Ju4%~;u(6JJ$u?ElLIlP2d zu^0Pr5TD=(j^Z2qjNdZo{}uv!76{toHYB3Ena0C8~dAJkz zU@4lQV-?op8EnCe*qurLzfIs>ypPXu6vy!ce#9?e9q5h9qMujX z_X^yF`>_}gVmVge5j=`@c*euW^Vp78u?u^!AOFH(9KqN41}E?{&fpvj*-T3$WD8$v zcBrpB+u*&7?E$F35Da7A=r zcOTmavg5sn`2L6keag3HHh4qL!WUsS_@d1r-p*!PhV2w{wl|Zo8F?r`F}k4?z0emG z7-FXXN0I3YGL0j`jw?}zYfz7C;Y1_;41O2$-i~{*7(VD&iPdPvlXx00;3d3_op=}f zaTv$(o!LWk63}wEt04+T#3L0MFe4w`P>KPlzz___C|EHTwU~mxz?93_Ko9iBWf*{w zaN#Aq>fvKI-opntj#KcXQyzsuJi6g_+>7N{jrDj2+wnT~U@!LJ06s)iKF2^jQjm>8 zbVna}`tdOkf5tpKgctA%cH*D-3|}Cm3;lL1`jr*bFIlPR2;GcLOU*I@?LU;iy zEX1P#Wd-#AR07w-joYvg_u(Ntjc4&Pc4Hq7;B%aYETl`&2O}^B6EFog;xAZ>XYekL z;9KxghF2@%K2t>hClE--V2s0+sKa%bg=Rd7op>9^5nIfS34Jgcc3h2FxDyXxH8x@g z4&zgNi_`cWEr{?~Sn(nbJ<%V7Fd8;oi|Lq+TW~LyVg;VYCTz#6cn=@qbNq;3a1Ie& z8B0ij8O10?Z+J%XQH`mXjz-*#hwwO_#mjgNZ{RJwgLm;B4&rm1#&586V{BkN9Jm2) zcyJHy$6_o;b2s|`Edqyd6yM+{{02Wlx(jb4l92&3x}yeD(1=@c2NqxnmO;mAG-Exs zU>mmMP3*-19O_R0e?s63{2SlmB!0p#I0HXIN|;9IjbWIG$(V{6aN!org$E08FBYQ- z593ihfpypj9_zi&sl?l{1FvH@_F_K{;Y;xB?>&x_IE5DE^Ok|H235>jX|iwa9B};I=C%|2JQHbxwow8SFZ-$4BY~-UDJG@7od$0WYH>9j zXuvGYg%8W{S3HLG*n<7|1Yh7dzQ-9vm2-1LAw1pqSOy(`#ozEWw%}###(unyqd1O} z_z|)<3lJnC3ppr5e+Hic0Ij~?5Dq+P~)S>}5U^eDp z0q({k_^=9(VH2LmTiAz#_!P(S9ezT@Wy~O?ARiVFAKfto!(hV{IB^r^;vOu*ay*VT zSck268L#3)9KmsXhn#*K9DUFa12Gs?7!BUt_D+OnDj(Bu9cJS%xTBx&J=D+OT}gNq z9>bGZkFD5=UD$)Y*pH8J4FAC?oIwk;{)~D=A`uxdBM*iB>3<7>o*0A?xE#Es=$(kG zFda9-g#WHNe-|-6mfrI!Q-{B{S0Sr_`qccoMM#cd8Kbt@i`k)^wFa*O< zjXGR|DQLhAaN|~Z@h~>v1?F)R}fc?38=?3%p}c?gA#pS!uMeb9wct_AcJ=+;ceKCUD$)Y z*guH=KSZL#gA%<*i8zk$@IC%Z{BOi-6)YSP1>WKIrd0@EW<{3QOgIk~bSJK~BHmlh zcVG7PCvFgiVI*;vvu_+>JK-w{PbNGS(<lfeYzso`zvw3d)R2H z$o3@-Hh5D9Ga?5IpLuYoFK=*&w}5c*;B0RR-+lNVz;^}TRiqn*D^N|`xWU=JndEOI zeA8fq&owy2w}|Z}Y(L2Ma<<zAD8I~3N*_D@G>($%L4y`Vft(vjK@kcUe2p?_nwyX7J=9wk1a>TLzr(F|)U<>Ij<8gH&Q|G5$jKoeJRgx6jG)+pzonUj@di?c>aKAV z=o5VvU%j^m4^$l{CbzJ2O>mQ3fz9O?@4c&ab8U^(;&|(OUi*SIZi}|d{Zg*dKbat} zl0(&3fj(&>|GMBCed$ErecYpOo+wKaR*Ed~SiZQvbD+eUqw`8$+&wi>#(O^Z+h+a2 zPLps1($2O#;xx<(yk<c8FjpEj`8^nUMRbt86 zO0n{6H?i^TeDRl-1>(JyWunmkkQnN}i}!Et;T=s|sX?{pLi*t{eg2hlz5I*by;km& zFX`Xc%F2Or_~#Y%HFjayLS0ou*9pt^)*$0Ry?t%0+`#)k2L6!<@1+L58^h`?k5H+G zt7J~@)BgFqjl5cHWFh~&->Gc~lo8G7SYGShs?xp@aPX5I!~FxCF%wwvpuCR6YDrAVCpy+Ay3)*)t| zbBcB6W{BLD1~F4#dbLc89ZjaCyxz&14pXVswyWhGlVAGT5nE?0_{=z0@LGa-l9p@~ z8o!ropYdDyK9TA>EYiG(L%1Y`aT!BtIIDe}#_zZ-f~!k}@Vy(E>H7eYQJKE@s7&v0 S{(3ZOThk;tRj!>Z5Bv`Ud|kKz diff --git a/PLASMA-DEM2.PO b/PLASMA-DEM2.PO index ea761b476dafcf6bfaa8afb585b789bc8c99d6c2..a0aa4a2ad9cc94275a9fb7f12d21c307d9e6d240 100644 GIT binary patch delta 7801 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 Y%0c8qDTg1tF<2^+zdMKT7%VUU2RhIFGXMYp diff --git a/PLASMA-SOS2.PO b/PLASMA-SOS2.PO index 5508da09f0927d49cb439098800bcf21db2d36e8..db90822c518fd1dbf1d0c462b5d89e541e4cd834 100644 GIT binary patch delta 148 zcmZp8z|ru4V?z*&s#dUnu%5STke{m$0|@YlG3YQbgfTd&u!<@(JZ1nhCYQ6!V`P{t z#;U-QuOiO1*^2c9+hhecE*AFx|Nn0m;Q1iCXbF?HsJMirl(dYjoV<&xo4bdnm$#3v wpMOALP;f|SSa?KaRCG*iTzo=eQgX^>LAI-mi&h9Na`0HR%c<$qvQvy{0Ns5mga7~l delta 8216 zcmaKx4}4QqmdEdVd40{lrZ0b5N+}Sr#PBR_z|ld}TAYFogqnefrGpr2d6rJ6)*3c=5IMy{}Dt}kov`x}d+A^3$(UGu#RuBmaIH>I6jL@nxL${2evr6}OleFTxJN@u| z_uPBWIrrRq-~IDK!#R1wIeFhAZYr5uOs@UAsvtUYmys0b>V)gbpGjQsujXE2M1N+A zkt@y}FYK9}($8yBN2p!;NR%eBJ%V~@q9>JjXM;j82h0a0U@=$%mVt60ftBFb;4!cY ztO4sm19%EN4K{)%&~N8nR1fbxqF9X1$lu7k9)x)PzrttmV*_b5>$gnfg7v`Pl86U z5j+P+o8YJ!@)ociyad`n2y}ryum`*bqTnDn24dh8@O*^FS#Swl2HydqCcad)&Z|)q zuNGv231AYq4w%3+Pyl9vTfnX0b}$DNg9V@je(dmbKja6114y6-)PZ_6oqq^kun{za zE#O~4JB-6H-UT@VUInj%gWxUjF6xh?{(Z4JHB!RD-%S;#-%d^?D(102{$`;9tNNupRV)SHVH>4v4|#WSY+V3FLF& z&)@?18yE&(fv>@LK&HV;0!j}aX+QvaFdj?+CNK?52Nqxj_kjn21gbT}SF6!^U69>i zJ@A63K@;$U9iR<_!7k7TUITA{1K@4oIf_RNd;m^^GvE{OColxQ18h2m4CvB{FEd@| zodo$hkPD`PJWvScfMReru!4KRB2We%0af7FU=^qbYtu3RPr~WObjG&{1)IS(@Dd1s zE)W4xa1@*dpMt-DD}WU+dLRp25AwmyU>2AIioxB$3T$98SPmWnD?qJ)`CkLU1D*oU zfM-E7XaQ{?47$Ny5Cw06qu>Pi5PSj#z!10$z7en~X&GOd79$2Sz<7`YCTodrD(dnf z-vn;);4vE%gHlvFw3B_0XgOb%R_3eKYJ97aU#~U#o&tWz1E{;AWqleQ>$_Pu*>}4x z-B+ZO`O0-V?^+%4H6!iRVXh&c)^Xl5NYCmrd>5eerB3GkJMsoS=N+fV3$G_Wk5SM0 zrs`9@A~MtU8Q!0wVm2rO3&1bHeV`OP036_9Ab}e27+4K{1De1Kzz<#oJ3uG=?$uBB zegyeE7z8N>Y}r6#!2C~uaGinpOa|6B%^>qlHyC|)7&u=M(w`aRzJ-u&2AQ`MI=?h9 zUJ3duAy*qF`W`h*^41~03akSjls{?Ed!I(S(ZG3|Q1$}wgDqe?Xa(&c1iB13RCYn= zGi=^k%gmVc_TiI@g;Wwdb@DDjP7WS;*D5H<2WLKrORCLZmojyH?C|@G1mhkpA7woI zId%mhw+Xo<({S+Ep%2b1Ci8@6gf3xN$kw)MC+dEy+pA;s%k}H^@9D4T>A6pcJdu!6 zmLU?Ul}H&|ni3a9#>q;=B@^E^vvxx2rwgb|L8ZthD~g;c*Hn6FEz2Z5j9I_+18a^I znRU~JGOjd}6_rj74Wx*N%v`bo)|@J)L#~8MW~q`DWeF9Db)mwkNUBl~N*XbOl_%qI zdSt}K5f?9>h_`5wxH5S>9yd#Vc zQkI$wSiz9E`?+K8P5Eerbr^H4`2;_x=d5b%c#Rdm6JzXshDZG#JQBjr52Bxc^K0dkLs#r7@HsHBo%0j>M>V3 znV3q|@WLE)DkRpaggX_2Od~j-T!I+&#NARWU8#_C>Pj`MT?#ayf`u9uX<~FtO}J*n z#@_1#W4%ooYg>6uh)#3^FYG&GUX-QDYEQhI)>I;n*klCL^CLxGCf-2fm>%{BZmnQCCb%;M({`92bCje>1C5#@zTiRreuj|Rc57fda2Pk#~I<3|0Z$Ngo* z{nhK-lLb?6-0MGd)T?KS-aSP=I>;OMDAhkIGwu%p&jr z3Lb-!6X^z|&mavV?L^%k$nQfwh4d2A%P6}F*(_6eZLTVryArJ>+Uq2f>-yCa>I!5&)CmQ9i9O&Pm2t-@R zZh14IN^dDT2AeKr1_!pa5A2q2B@CPd&v)?6v5r*O5_0&D2M?#k>~fWGvj6?#_see+ zaBe%9O&V?wSM=@On>4D77B-6%&25R@*2y$o9BE1KByU<<{27`XCI&{f1qADt!KMbz z!7)bWWq}O#zcw<`c%_=O`U}$MO^QUPH8g%Mq!>4}T=+b4Ku`=qI&$Ij7?*KkXsX|r zKF#yRKl|g`hFVFWp><#Dq1NjId4X42e;SwPPdwaw*{5K@xg^17na;>`vvCwlD|kdLw`9I zV=qVJS~2!?^mNQRQ~EOtP}IMBc*AGmBfHNv$NKSzwtto=YO@F`TfvdzOW^b=8H|^*$S#(z`Y^xA%9Ur+QmLhTff_qv79&u7)c@S9^aI%I}A>|Ew?Od!CNCRzxiF% zainvlKX<}>#g496>Tce+qszZ~LS9mRPiVqa#$Dv1d~#fKaK&+{hzqxybn&oRp43W{xH>6a;_E8w!ev@&khmn$ zJ0h9&gL`4zExi{~t^akMTN_>ndydwO-rn*PVcvdGg+QQUPUeV zvF`_hK5rQ97Xpa)IX&4gdUbQrtD9Qlof@$*-ZL6ZI(3qUt7PJm2Q3BePb%V6i$%Eb zBzmJROQULr6p_dMk9cscljB;)$A^iyw8W_w=a`kr!Ah6dI!TKWtI(GjsNFTAFgG6H z*eI~1@^Y|5MND4@?TfqXF9(q|F(FZAf34d>3%~2GzY-K1oJ34>GL;ZnGqHO7vfeL}aP4EiIX2XfC16j1_I_wp0+&V<=-1USKHETf2iQOJt^l zbx^msQ!4G>?E1bfGS8}p-EuqD|%>NDO%Vc7$F1yRm;L^vBAEn z8$vA@Z9_$nacF3%mku0Z)`_IDCR|mEwlTz=5Y%p(QM-uk zKSr*tO33O8Ok!t37Fo6e@55+L#u87$g(zd;BoR7oNG-AW=dfQ5qL*$V92QJbmqol2Gi3J2?RWOr zPxeTBSr#eFqH`q2(3RKlBG1yHGfI4|{gy6?SJz3b#3Rr;_~*qGq%)VNrQwLXA{8G~ux531Ja$DrjNy5UfbZMk2mtd}jmC0efl}M&UKk4^4 zYgN$^sPDEAv}UsR^x<8X6YO_F**VEH(_DZ!S(nLnctrAOM4ngMr}WksT~mlOrB-4~ zbhIb54~YzX8~r5yU1JE_L(5+%`rB`S#`+=;f~ z5lK{|P-DH15Oc0MQ!-0(P8?xHc~0f>u&870D|eY53`1sX(busaqd;B1JY110He_m? z`BLt3g1{VXO(yI;*hw=bHQh|nTeiqLfmGy6W_7uwX3bOV>-#K{nYM4Xog0CM_2)#& zmU1MyWVWx`>C(9jH7J}xsIg$M8i-^lmqeJz@bcc#$J!9TPExXx(LQ^pWT+c;7C~nm z)_Fwoh^{z zk#Z3f53)GUUf)^ij1Pb_KIL-zQ@wZ>bdq4rq20r;28qrssqyII?}nrk=+e-Youe=G zO!`aBbTMmIAyHRMH>O)dD%W0LBaQj6D;C~igA7}T>?oZte{a}DF2bKF;@vcGTf1>X*;tf&^GDs zXrggG_J#^J-ed}~eLCX75m_dqQzT;u{qfTN_g7$oO`gU~3w{u8qKUXx1)H!Nk7nXG zGn_(|UDl;^u3UN?3$6_8Sgvs>?&-@T#(CBoiIhQ)3O!C1EJ|w@sa);}Yp^zx%hq9U z*=4a^7_ssA4qYBjoEZcsgftEtUwr=>k5KLVcIB&W);Wt8&N15RR{X?>*{!@7#9=As zV~Q&OMny~jG1Y`kwP8^%YOys~ut8$wBY^MyR+W0f?+&vUDjSIPl=_SCO5h7I?p<2_~5Z>r@XG5eI3#{^N2!*(F(F+1< zk*9BjEdxts;oOC@a}loH&}(OV5u=B$5okHASEws{Rm8rnOZ-_Ot`f){-DBHLL|fra zH0J<#jSB9{#edphAyI|wJ`1*(WaetG1(KadTWj%t7mB3vd`MG&K7>+8nErwy>t9D8 zicGOpLCx$Qs$D|F#f3TX7Llb#)}MCfbBmWQE{Hc!K*S}5a$;Yz$CiubQJ6*St7y#j z+avZs#A2@xV@7NWlF#0mhQ3+o!k$czoBGGY`6+W3EsA%!^6@aHg?87bB>A#?7f@aM zl#@L)j6dx}M%-uL+JiC0_)_oaj&1NNS+<8!4lx0dy>XHKz9sjUE-m}zvImww=y<67 z;ffW~Bb6(wepUVJnn!CNt9#tJ%C)+FjeG67_4xVV6cfnT1%7kalivovWq$HMG>hu* diff --git a/PLASMA-SYS2.PO b/PLASMA-SYS2.PO index 6c699f789590e3c9273513cb954a448e61fe0af6..5f51cf2e9d66ec678057d080ae6f33ad7aa2b252 100644 GIT binary patch delta 15757 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

    Q>@wO&DQ2`#dD=WSfUp|#miFb=m zk*2)Xc)vB4;#cMvFYoWQ#+1G5dSz_P1T6(`9XIrkP};hgHltYhlu4&qWi?Lm4(s%Y zwCk{R4#x+FL+b|Qko4{mC!Ro=?-*81#6(It4yF2U!-PW}=NSiY z*b&#MB7DhR?Ql#2aS}Vs#V*cIlnq$L;ZoxX2iv=QW7;R4*5W}7oH(Zq?ig`6T#+O6 zcEuU3=X+jy<1t-Y5|4NpiVepTTVlNq8RiT}2MKa|IJri8oP@KeIB5KKZ|+t_B1sg# z>ju^hh{!t10@dJ*jLH5^i=4UYIfEmYZQ*tzZ}dp+2eZ1ArEBlrlnAP0s5yQ*?kq;J zOXzZ(dvTmgeYmvQlp^j|tI^1l;EtXxs>?=sbIkO};6N-GE?W?)EY!Xw(#?bP zixV7`h89Q<>hrgtG*ssE*2lKG%9m=y)H~OG9BXN{g^mqBJLL`{KoQ85vFwfy^922;~{lQ0^;^ z&BKG;Iv10aM>TRl+)t}PL{limCgr7-hp)n@KshO#()IL; z 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 diff --git a/PLASMA-BLD2.PO b/PLASMA-BLD2.PO index bb1d25479ab4c0e69fae7455f9a2bd7d08c0b334..7b53330ce41ba27925f59677379ee91d540970e1 100644 GIT binary patch delta 27353 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 BKidER delta 27224 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 YFEq9ke6M||-I1^Bx9R#F{q)@b2aAmQ<^TWy diff --git a/PLASMA-DEM1.PO b/PLASMA-DEM1.PO deleted file mode 100644 index 62ca12c48ea175ca4584b8b441a33af9119cebcc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 143360 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 M%z(_m|8oZZ2ejohxBvhE diff --git a/PLASMA-DEM2.PO b/PLASMA-DEM2.PO index 62ca12c48ea175ca4584b8b441a33af9119cebcc..c70d666efe9ca0a0ed2a26089652de429f59c1c4 100644 GIT binary patch delta 18976 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 diff --git a/PLASMA-SOS2.PO b/PLASMA-SOS2.PO index 6c8829017667c9ea27ad2b6614ef7ec6a885cb46..2c2e83a565287622418e55bb3e080a469720313c 100644 GIT binary patch delta 3922 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 delta 3170 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