diff --git a/PLASMA/src/cmd.pla b/PLASMA/src/cmd.pla new file mode 100644 index 00000000..92894936 --- /dev/null +++ b/PLASMA/src/cmd.pla @@ -0,0 +1,500 @@ +const iobuffer = $0800 +const databuff = $0C00 +const autorun = $01FF +byte version[] = "PLASMA VM VERSION 0.9" +byte errorstr[] = "ERROR: $" +byte okstr[] = "OK" +byte prefix[32] = "" +byte perr +word cmdptr + +; +; Utility functions +; +; CALL PRODOS +; SYSCALL(CMD, PARAMS) +; +asm prodos + LDA ESTKL,X + LDY ESTKH,X + STA PARAMS + STY PARAMS+1 + INX + LDA ESTKL,X + STA CMD + STX ESP + JSR $BF00 +CMD: !BYTE 00 +PARAMS: !WORD 0000 + BIT LCBNK2 + LDX ESP + STA ESTKL,X + LDY #$00 + STY ESTKH,X + RTS +end +; +; CALL LOADED SYSTEM PROGRAM +; +asm exec + LDX #$FF + TXS + BIT ROMEN + JMP $2000 +end +; +; SET MEMORY TO 0 +; MEMCLR(ADDR, SIZE) +; +asm memclr + LDY #$00 + LDA ESTKL+1,X + STA DSTL + LDA ESTKH+1,X + STA DSTH + INC ESTKL,X + INC ESTKH,X + TYA +SETMLP DEC ESTKL,X + BNE + + DEC ESTKH,X + BEQ ++ ++ STA (DST),Y + INY + BNE SETMLP + INC DSTH + BNE SETMLP ++ INX + INX + RTS +end +; +; COPY MEMORY +; MEMCPY(DSTADDR, SRCADDR, SIZE) +; +asm memcpy + LDY #$00 + LDA ESTKL,X + BNE + + LDA ESTKH,X + BEQ MEMEXIT ++ LDA ESTKL+2,X + STA DSTL + LDA ESTKH+2,X + STA DSTH + LDA ESTKL+1,X + STA SRCL + LDA ESTKH+1,X + STA SRCH + CMP DSTH + BCC REVCPY + BNE FORCPY + LDA SRCL + CMP DSTL + BCS FORCPY +REVCPY ; REVERSE DIRECTION COPY +; CLC + LDA ESTKL,X + ADC DSTL + STA DSTL + LDA ESTKH,X + ADC DSTH + STA DSTH + CLC + LDA ESTKL,X + ADC SRCL + STA SRCL + LDA ESTKH,X + ADC SRCH + STA SRCH + INC ESTKH,X +REVCPYLP + LDA DSTL + BNE + + DEC DSTH ++ DEC DSTL + LDA SRCL + BNE + + DEC SRCH ++ DEC SRCL + LDA (SRC),Y + STA (DST),Y + DEC ESTKL,X + BNE REVCPYLP + DEC ESTKH,X + BNE REVCPYLP + BEQ MEMEXIT +FORCPY INC ESTKH,X +FORCPYLP + LDA (SRC),Y + STA (DST),Y + INC DSTL + BNE + + INC DSTH ++ INC SRCL + BNE + + INC SRCH ++ DEC ESTKL,X + BNE FORCPYLP + DEC ESTKH,X + BNE FORCPYLP +MEMEXIT INX + INX + INX + RTS +end +; +; CHAR OUT +; COUT(CHAR) +; +asm cout + LDA ESTKL,X + INX + ORA #$80 + BIT ROMIN + JSR $FDED + BIT LCBNK2 + RTS +end +; +; CHAR IN +; RDKEY() +; +asm cin + BIT ROMIN + STX ESP + JSR $FD0C + LDX ESP + BIT LCBNK2 + DEX + STA ESTKL,X + LDY #$00 + STY ESTKH,X + RTS +end +; +; PRINT STRING +; PRSTR(STR) +; +asm prstr + LDY #$00 + LDA ESTKL,X + STA SRCL + LDA ESTKH,X + STA SRCH + BIT ROMIN + LDA (SRC),Y + STA ESTKL,X + BEQ + +- INY + LDA (SRC),Y + ORA #$80 + JSR $FDED + TYA + CMP ESTKL,X + BNE - ++ INX + BIT LCBNK2 + RTS +end +; +; PRINT BYTE +; +asm prbyte + LDA ESTKL,X + INX + STX ESP + BIT ROMIN + JSR $FDDA + BIT LCBNK2 + LDX ESP + RTS +end +; +; READ STRING +; STR = RDSTR(PROMPTCHAR) +; +asm rdstr + LDA ESTKL,X + STA $33 + STX ESP + BIT ROMIN + JSR $FD6A + BIT LCBNK2 + STX $01FF +- LDA $01FF,X + AND #$7F + STA $01FF,X + DEX + BPL - + LDX ESP + LDA #$FF + STA ESTKL,X + LDA #$01 + STA ESTKH,X + RTS +end +asm toupper + LDA ESTKL,X + CMP #'a' + BCC + + CMP #'z'+1 + BCS + + SEC + SBC #$20 + STA ESTKL,X ++ RTS +end +; +; EXIT +; +asm reboot + BIT ROMIN + LDA #$00 + STA $3F4 ; INVALIDATE POWER-UP BYTE + JMP ($FFFC) ; RESET +end +def crout + cout($0D) +end +; +; ProDOS routines +; +def getpfx(path) + byte params[3] + + ^path = 0 + params.0 = 1 + params:1 = path + perr = prodos($C7, @params) + return path +end +def setpfx(path) + byte params[3] + + params.0 = 1 + params:1 = path + perr = prodos($C6, @params) + return path +end +def online + byte params[4] + + params.0 = 2 + params.1 = 0 + params:2 = $2000 + perr = prodos($C5, @params) + return $2000 +end +def open(path, buff) + byte params[6] + + params.0 = 3 + params:1 = path + params:3 = buff + params.5 = 0 + perr = prodos($C8, @params) + return params.5 +end +def close(refnum) + byte params[2] + + params.0 = 1 + params.1 = refnum + perr = prodos($CC, @params) + return perr +end +def read(refnum, buff, len) + byte params[8] + + params.0 = 4 + params.1 = refnum + params:2 = buff + params:4 = len + params:6 = 0 + perr = prodos($CA, @params) + return params:6 +end +; +; Command mode +; +def volumes + word strbuf + byte i + + strbuf = online() + for i = 0 to 15 + ^strbuf = ^strbuf & $0F + if ^strbuf + cout('/') + prstr(strbuf) + crout() + fin + strbuf = strbuf + 16 + next +end +def catalog(optpath) + byte path[64] + byte refnum + byte firstblk + byte entrylen, entriesblk + byte i, type, len + word entry, filecnt + + if ^optpath + memcpy(optpath, @path, ^optpath + 1) + else + getpfx(@path) + prstr(@path) + crout() + fin + refnum = open(@path, iobuffer); + if perr + return perr + 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 <> 0 + len = type & $0F + ^entry = len + prstr(entry) + if type & $F0 == $D0 ; Is it a directory? + cout('/') + len = len + 1 + elsif (entry).$10 == $FF + cout('*') + len = len + 1 + fin + for len = 19 - len downto 0 + cout(' ') + next + filecnt = filecnt - 1 + fin + entry = entry + entrylen + next + firstblk = 0 + else + filecnt = 0 + fin + until filecnt == 0 + close(refnum) + crout() + return 0 +end +def stripchars(strptr) + while ^strptr and ^(strptr + 1) <> ' ' + memcpy(strptr + 2, strptr + 1, ^strptr) + ^strptr = ^strptr - 1 + loop + return ^strptr +end +def stripspaces(strptr) + while ^strptr and ^(strptr + ^strptr) <= ' ' + ^strptr = ^strptr - 1 + loop + while ^strptr and ^(strptr + 1) <= ' ' + memcpy(strptr + 2, strptr + 1, ^strptr) + ^strptr = ^strptr - 1 + loop +end +def striptrail(strptr) + byte i + + for i = 1 to ^strptr + if (strptr)[i] == ' ' + ^strptr = i - 1 + return + fin + next +end +def parsecmd(strptr) + byte cmd + + cmd = 0 + stripspaces(strptr) + if ^strptr + cmd = ^(strptr + 1) + memcpy(strptr + 2, strptr + 1, ^strptr) + ^strptr = ^strptr - 1 + fin + stripspaces(strptr) + return cmd +end +def resetmemfiles + ; + ; Close all files + ; + ^$BFD8 = 0 + close(0) + ; + ; Set memory bitmap + ; + memclr($BF58, 24) + ^$BF58 = $CF + ^$BF6F = $01 +end +def execsys(sysfile) + byte refnum + word len + + if ^sysfile + memcpy(sysfile, $280, ^sysfile + 1) + striptrail(sysfile) + refnum = open(sysfile, iobuffer) + if refnum + len = read(refnum, $2000, $FFFF) + resetmemfiles() + if len + memcpy($280, sysfile, ^$280 + 1) + if stripchars(sysfile) and ^$2000 == $4C and *$2003 == $EEEE + stripspaces(sysfile) + if ^$2006 <= ^sysfile + memcpy(sysfile, $2006, ^sysfile + 1) + fin + fin + striptrail($280) + exec() + fin + fin + fin +end + +resetmemfiles() +execsys(autorun) +prstr(@version) +crout(); +while 1 + prstr(getpfx(@prefix)) + cmdptr = rdstr($BA) + when toupper(parsecmd(cmdptr)) + is 'Q' + reboot() + is 'C' + catalog(cmdptr) + is 'P' + setpfx(cmdptr) + is 'V' + volumes(); + is '-' + execsys(cmdptr) + perr = $46 + wend + if perr + prstr(@errorstr) + prbyte(perr) + else + prstr(@okstr) + fin + crout() +loop +done \ No newline at end of file diff --git a/PLASMA/src/codegen.c b/PLASMA/src/codegen.c index 13ad12df..e0fe4d15 100755 --- a/PLASMA/src/codegen.c +++ b/PLASMA/src/codegen.c @@ -236,12 +236,22 @@ int fixup_new(int tag, int type, int size) /* * Emit assembly code. */ -#define BYTECODE_SEG 2 +#define BYTECODE_SEG 8 +#define INIT 16 static int outflags = 0; static char *DB = ".BYTE"; static char *DW = ".WORD"; static char *DS = ".RES"; static char LBL = ':'; +char *supper(char *s) +{ + static char su[80]; + int i; + for (i = 0; s[i]; i++) + su[i] = toupper(s[i]); + su[i] = '\0'; + return su; +} char *tag_string(int tag, int type) { static char str[16]; @@ -260,6 +270,17 @@ char *tag_string(int tag, int type) sprintf(str, "_%c%03d", t, tag); return str; } +void emit_dci(char *str, int len) +{ + if (len--) + { + printf("\t; DCI STRING: %s\n", supper(str)); + printf("\t%s\t$%02X", DB, toupper(*str++) | (len ? 0x80 : 0x00)); + while (len--) + printf(",$%02X", toupper(*str++) | (len ? 0x80 : 0x00)); + printf("\n"); + } +} void emit_flags(int flags) { outflags = flags; @@ -277,35 +298,83 @@ void emit_header(void) printf("; ACME COMPATIBLE OUTPUT\n"); else printf("; CA65 COMPATIBLE OUTPUT\n"); - printf("_SEGBEGIN%c\n", LBL); - printf("\t%s\t_SEGEND-_SEGBEGIN\t; LENGTH OF HEADER + CODE/DATA + BYTECODE SEGMENT\n", DW); - printf("\t%s\t$DA7E\t\t\t; MAGIC #\n", DW); - printf("\t%s\t_SUBSEG\t\t\t; BYTECODE SUB-SEGMENT\n", DW); + if (outflags & MODULE) + { + printf("_SEGBEGIN%c\n", LBL); + printf("\t%s\t_SEGEND-_SEGBEGIN\t; LENGTH OF HEADER + CODE/DATA + BYTECODE SEGMENT\n", DW); + printf("\t%s\t$DA7E\t\t\t; MAGIC #\n", DW); + printf("\t%s\t_SUBSEG\t\t\t; BYTECODE SUB-SEGMENT\n", DW); + printf("\t%s\t_INIT\t\t\t; MODULE INITIALIZATION ROUTINE\n", DW); + } +} +void emit_rld(void) +{ + int i; + + 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)) + { + printf("\t%s\t$02\t\t\t; CODE TABLE FIXUP\n", DB); + printf("\t%s\t_C%03d\t\t\n", DW, idglobal_tag[i]); + printf("\t%s\t$00\n", DB); + } + /* + * Now emit the fixup table. + */ + for (i = 0; i < fixups; i++) + { + if (fixup_type[i] & EXTERN_TYPE) + { + printf("\t%s\t$%02X\t\t\t; EXTERNAL FIXUP\n", DB, 0x11 + fixup_size[i]); + printf("\t%s\t_F%03d\t\t\n", DW, i); + printf("\t%s\t%d\t\t\t; ESD INDEX\n", DB, fixup_tag[i]); + } + else + { + printf("\t%s\t$%02X\t\t\t; INTERNAL FIXUP\n", DB, 0x01 + fixup_size[i]); + printf("\t%s\t_F%03d\t\t\n", DW, i); + printf("\t%s\t$00\n", DB); + } + } + printf("\t%s\t$00\t\t\t; END OF RLD\n", DB); +} +void emit_esd(void) +{ + int i; + + printf(";\n; EXTERNAL/ENTRY SYMBOL DICTIONARY\n;\n"); + for (i = 0; i < globals; i++) + { + if (idglobal_type[i] & EXTERN_TYPE) + { + emit_dci(&idglobal_name[i][1], idglobal_name[i][0]); + printf("\t%s\t$10\t\t\t; EXTERNAL SYMBOL FLAG\n", DB); + printf("\t%s\t%d\t\t\t; ESD INDEX\n", DW, idglobal_tag[i]); + } + else if (idglobal_type[i] & EXPORT_TYPE) + { + emit_dci(&idglobal_name[i][1], idglobal_name[i][0]); + printf("\t%s\t$08\t\t\t; ENTRY SYMBOL FLAG\n", DB); + printf("\t%s\t%s\t\t\n", DW, tag_string(idglobal_tag[i], idglobal_type[i])); + } + } + printf("\t%s\t$00\t\t\t; END OF ESD\n", DB); } void emit_trailer(void) { if (!(outflags & BYTECODE_SEG)) emit_bytecode_seg(); - printf("_SEGEND%c\n", LBL); -} -char *supper(char *s) -{ - static char su[80]; - int i; - for (i = 0; s[i]; i++) - su[i] = toupper(s[i]); - su[i] = '\0'; - return su; -} -void emit_dci(char *str, int len) -{ - if (len--) + if (!(outflags & INIT)) + printf("_INIT\t=\t0\n"); + if (outflags & MODULE) { - printf("\t; DCI STRING: %s\n", supper(str)); - printf("\t%s\t$%02X", DB, toupper(*str++) | (len ? 0x80 : 0x00)); - while (len--) - printf(",$%02X", toupper(*str++) | (len ? 0x80 : 0x00)); - printf("\n"); + printf("_SEGEND%c\n", LBL); + emit_rld(); + emit_esd(); } } void emit_moddep(char *name, int len) @@ -317,7 +386,7 @@ void emit_moddep(char *name, int len) } void emit_bytecode_seg(void) { - if (!(outflags & BYTECODE_SEG)) + if ((outflags & MODULE) && !(outflags & BYTECODE_SEG)) printf("_SUBSEG%c\t\t\t\t; BYTECODE STARTS\n", LBL); outflags |= BYTECODE_SEG; } @@ -411,6 +480,19 @@ int emit_data(int vartype, int consttype, long constval, int constsize) } return (datasize); } +void emit_def(char *name, int is_bytecode) +{ + if (!(outflags & MODULE)) + { + printf("%s%c\n", name, LBL); + if (is_bytecode) + { + printf("\tJSR $03D0\n"); + printf("\t%s\t$00\n", DB); + printf("\t%s\t*+2\n", DW); + } + } +} void emit_codetag(int tag) { printf("_B%03d%c\n", tag, LBL); @@ -492,6 +574,20 @@ void emit_saw(int tag, int type) printf("\t%s\t$7A\t\t\t; SAW\t%s\n", DB, taglbl); printf("_F%03d%c\t%s\t%s\t\t\n", fixup, LBL, DW, type & EXTERN_TYPE ? "0" : taglbl); } +void emit_sab_ofst(int tag, int offset, int type) +{ + int fixup = fixup_new(tag, type, FIXUP_WORD); + char *taglbl = tag_string(tag, type); + printf("\t%s\t$78\t\t\t; SAB\t%s\n", DB, taglbl); + printf("_F%03d%c\t%s\t%s+%d\t\t\n", fixup, LBL, DW, type & EXTERN_TYPE ? "0" : taglbl, offset); +} +void emit_saw_ofst(int tag, int offset, int type) +{ + int fixup = fixup_new(tag, type, FIXUP_WORD); + char *taglbl = tag_string(tag, type); + printf("\t%s\t$7A\t\t\t; SAW\t%s\n", DB, taglbl); + printf("_F%03d%c\t%s\t%s+%d\t\t\n", fixup, LBL, DW, type & EXTERN_TYPE ? "0" : taglbl, offset); +} void emit_dab(int tag, int type) { int fixup = fixup_new(tag, type, FIXUP_WORD); @@ -589,9 +685,6 @@ void emit_ret(void) { printf("\t%s\t$5C\t\t\t; RET\n", DB); } -void emit_def(int defopt) -{ -} void emit_enter(int framesize, int cparams) { if (framesize > 2) @@ -599,6 +692,8 @@ void emit_enter(int framesize, int cparams) } void emit_start(void) { + printf("_INIT%c\n", LBL); + outflags |= INIT; } void emit_dup(void) { @@ -716,60 +811,3 @@ int emit_op(t_token op) } return (1); } -void emit_rld(void) -{ - int i; - - 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)) - { - printf("\t%s\t$02\t\t\t; CODE TABLE FIXUP\n", DB); - printf("\t%s\t_C%03d\t\t\n", DW, idglobal_tag[i]); - printf("\t%s\t$00\n", DB); - } - /* - * Now emit the fixup table. - */ - for (i = 0; i < fixups; i++) - { - if (fixup_type[i] & EXTERN_TYPE) - { - printf("\t%s\t$%02X\t\t\t; EXTERNAL FIXUP\n", DB, 0x11 + fixup_size[i]); - printf("\t%s\t_F%03d\t\t\n", DW, i); - printf("\t%s\t%d\t\t\t; ESD INDEX\n", DB, fixup_tag[i]); - } - else - { - printf("\t%s\t$%02X\t\t\t; INTERNAL FIXUP\n", DB, 0x01 + fixup_size[i]); - printf("\t%s\t_F%03d\t\t\n", DW, i); - printf("\t%s\t$00\n", DB); - } - } - printf("\t%s\t$00\t\t\t; END OF RLD\n", DB); -} -void emit_esd(void) -{ - int i; - - printf(";\n; EXTERNAL/ENTRY SYMBOL DICTIONARY\n;\n"); - for (i = 0; i < globals; i++) - { - if (idglobal_type[i] & EXTERN_TYPE) - { - emit_dci(&idglobal_name[i][1], idglobal_name[i][0]); - printf("\t%s\t$10\t\t\t; EXTERNAL SYMBOL FLAG\n", DB); - printf("\t%s\t%d\t\t\t; ESD INDEX\n", DW, idglobal_tag[i]); - } - else if (idglobal_type[i] & EXPORT_TYPE) - { - emit_dci(&idglobal_name[i][1], idglobal_name[i][0]); - printf("\t%s\t$08\t\t\t; ENTRY SYMBOL FLAG\n", DB); - printf("\t%s\t%s\t\t\n", DW, tag_string(idglobal_tag[i], idglobal_type[i])); - } - } - printf("\t%s\t$00\t\t\t; END OF ESD\n", DB); -} \ No newline at end of file diff --git a/PLASMA/src/codegen.h b/PLASMA/src/codegen.h index 667edee8..9ef4297f 100755 --- a/PLASMA/src/codegen.h +++ b/PLASMA/src/codegen.h @@ -1,4 +1,5 @@ #define ACME 1 +#define MODULE 2 void emit_flags(int flags); void emit_header(void); void emit_trailer(void); @@ -10,6 +11,7 @@ void emit_idlocal(char *name, int value); void emit_idglobal(int value, int size, char *name); void emit_idfunc(int tag, int type, char *name); void emit_idconst(char *name, int value); +void emit_def(char *name, int is_bytecode); int emit_data(int vartype, int consttype, long constval, int constsize); void emit_codetag(int tag); void emit_const(int cval); @@ -27,6 +29,8 @@ void emit_dlb(int index); void emit_dlw(int index); void emit_sab(int tag, int type); void emit_saw(int tag, int type); +void emit_sab_ofst(int tag, int offset, int type); +void emit_saw_ofst(int tag, int ofset, int type); void emit_dab(int tag, int type); void emit_daw(int tag, int type); void emit_call(int tag, int type); @@ -51,7 +55,6 @@ void emit_pull(void); void emit_drop(void); void emit_leave(int framesize); void emit_ret(void); -void emit_def(int defopt); void emit_enter(int framesize, int cparams); void emit_start(void); void emit_rld(void); diff --git a/PLASMA/src/loadcmd.s b/PLASMA/src/loadcmd.s new file mode 100644 index 00000000..7f95ead9 --- /dev/null +++ b/PLASMA/src/loadcmd.s @@ -0,0 +1,62 @@ +SRC = TMP +SRCL = SRC +SRCH = SRC+1 +DST = SRC+2 +DSTL = DST +DSTH = DST+1 +ESP = DST+2 + !PSEUDOPC $1000 { +;* +;* CLEAR COMMAND LINE LENGTH BYTE IF CALLED FROM 'BYE' +;* + LDY #$00 + LDX #$FE ; LEAVE ROOM FOR COMMAND LINE LENGTH BYTE + TXS + BVS + + STY $01FF ; CLEAR AUTORUN COMMAND WHEN CALLED FROM 'BYE' +;* +;* MOVE REST OF CMD FROM LANGUAGE CARD +;* ++ STY $06 + STY $08 + LDA #$D2 + STA $07 + LDA #$11 + STA $09 + BIT LCRDEN+LCBNK2 +- LDA ($06),Y + STA ($08),Y + INY + BNE - + INC $07 + INC $09 + LDA $07 + CMP #$E0 + BNE - +;* +;* DEACTIVATE 80 COL CARDS +;* + BIT ROMEN + LDY #4 +- LDA DISABLE80,Y + JSR $FDED + DEY + BPL - + BIT $C054 ; SET TEXT MODE + BIT $C051 + BIT $C058 + JSR $FC58 ; HOME +;* +;* JUMP TO INTERPRETER +;* + BIT LCRDEN+LCBNK2 + LDX #$00 + LDA #$BF + STX IFPL + STA IFPH + JSR INTERP + !BYTE 0 + !WORD START +DISABLE80 !BYTE 21, 13, '1', 26, 13 + !SOURCE "cmd.a" +} \ No newline at end of file diff --git a/PLASMA/src/makefile b/PLASMA/src/makefile index dc7d868f..af6aac25 100755 --- a/PLASMA/src/makefile +++ b/PLASMA/src/makefile @@ -32,15 +32,15 @@ $(PLVM): plvm.c cc plvm.c -o $(PLVM) TESTLIB: testlib.pla $(PLVM) $(PLASM) - ./$(PLASM) -A < testlib.pla > testlib.a + ./$(PLASM) -AM < testlib.pla > testlib.a acme --setpc 4096 -o TESTLIB testlib.a test: test.pla TESTLIB $(PLVM) $(PLASM) - ./$(PLASM) -A < test.pla > test.a + ./$(PLASM) -AM < test.pla > test.a acme --setpc 4096 -o TEST.BIN test.a ./$(PLVM) TEST.BIN MAIN debug: test.pla TESTLIB $(PLVM) $(PLASM) - ./$(PLASM) -A < test.pla > test.a + ./$(PLASM) -AM < test.pla > test.a acme --setpc 4096 -o TEST.BIN test.a ./$(PLVM) -s TEST.BIN MAIN diff --git a/PLASMA/src/parse.c b/PLASMA/src/parse.c index e49d90de..ca908b63 100755 --- a/PLASMA/src/parse.c +++ b/PLASMA/src/parse.c @@ -863,32 +863,54 @@ int parse_stmnt(void) case ID_TOKEN: idptr = tokenstr; type = id_type(tokenstr, tokenlen); - if (type & (VAR_TYPE | FUNC_TYPE)) + addr = id_tag(tokenstr, tokenlen); + if (type & VAR_TYPE) { - addr = id_tag(tokenstr, tokenlen); - if (scan() == SET_TOKEN) + int elem_type = type; + long elem_offset = 0; + if (scan() == DOT_TOKEN || scantoken == COLON_TOKEN) { - if (type & VAR_TYPE) - { - if (!parse_expr()) - { - parse_error("Bad expression"); - return (0); - } - if (type & LOCAL_TYPE) - (type & BYTE_TYPE) ? emit_slb(addr) : emit_slw(addr); - else - (type & BYTE_TYPE) ? emit_sab(addr, type) : emit_saw(addr, type); - break; - } + /* + * Structure member offset + */ + int elem_size; + elem_type = (scantoken == DOT_TOKEN) ? BYTE_TYPE : WORD_TYPE; + if (!parse_constval(&elem_offset, &elem_size)) + scantoken = ID_TOKEN; + else + scan(); + printf("Structure offset = %d\n", elem_offset); } - else if ((scantoken == EOL_TOKEN) && (type & FUNC_TYPE)) + if (scantoken == SET_TOKEN) + { + if (!parse_expr()) + { + parse_error("Bad expression"); + return (0); + } + if (type & LOCAL_TYPE) + (elem_type & BYTE_TYPE) ? emit_slb(addr + elem_offset) : emit_slw(addr + elem_offset); + else if (elem_offset) + (elem_type & BYTE_TYPE) ? emit_sab_ofst(addr, elem_offset, type) : emit_saw_ofst(addr, elem_offset, type); + else + (elem_type & BYTE_TYPE) ? emit_sab(addr, type) : emit_saw(addr, type); + break; + } + } + else if (type & FUNC_TYPE) + { + if (scan() == EOL_TOKEN) { emit_call(addr, type); emit_drop(); break; } } + else + { + parse_error("Syntax error"); + return (0); + } tokenstr = idptr; default: scan_rewind(tokenstr); @@ -1160,6 +1182,7 @@ int parse_defs(void) c = tokenstr[tokenlen]; tokenstr[tokenlen] = '\0'; emit_idfunc(func_tag, type, tokenstr); + emit_def(tokenstr, 1); tokenstr[tokenlen] = c; idlocal_reset(); if (scan() == OPEN_PAREN_TOKEN) @@ -1230,6 +1253,7 @@ int parse_defs(void) c = tokenstr[tokenlen]; tokenstr[tokenlen] = '\0'; emit_idfunc(func_tag, type, tokenstr); + emit_def(tokenstr, 0); tokenstr[tokenlen] = c; if (scan() == OPEN_PAREN_TOKEN) { @@ -1250,7 +1274,6 @@ int parse_defs(void) } scan(); } - emit_def(1); do { if (scantoken == EOL_TOKEN || scantoken == COMMENT_TOKEN) @@ -1288,7 +1311,5 @@ int parse_module(void) } } emit_trailer(); - emit_rld(); - emit_esd(); return (0); } diff --git a/PLASMA/src/plasm.c b/PLASMA/src/plasm.c index de5e0e01..24164569 100755 --- a/PLASMA/src/plasm.c +++ b/PLASMA/src/plasm.c @@ -6,12 +6,30 @@ int main(int argc, char **argv) { - - if (argc > 1 && argv[1][0] == '-' && argv[1][1] == 'A') - emit_flags(ACME); - if (parse_module()) - { - fprintf(stderr, "Compilation complete.\n"); + int j, i, flags = 0; + for (i = 1; i < argc; i++) + { + if (argv[i][0] == '-') + { + j = 1; + while (argv[i][j]) + { + switch(argv[i][j++]) + { + case 'A': + flags |= ACME; + break; + case 'M': + flags |= MODULE; + break; + } + } } - return (0); + } + emit_flags(flags); + if (parse_module()) + { + fprintf(stderr, "Compilation complete.\n"); + } + return (0); } diff --git a/PLASMA/src/plvm.c b/PLASMA/src/plvm.c index d8f0c700..99994db8 100755 --- a/PLASMA/src/plvm.c +++ b/PLASMA/src/plvm.c @@ -45,6 +45,10 @@ byte symtbl[SYMTBLSZ]; byte *lastsym = symtbl; byte modtbl[MODTBLSZ]; byte *lastmod = modtbl; +/* + * Predef. + */ +void interp(code *ip); /* * Utility routines. * @@ -269,7 +273,7 @@ int extern_lookup(byte *esd, int index) } int load_mod(byte *mod) { - int len, size, end, magic, bytecode, fixup, addr, modaddr = mark_heap(); + int len, size, end, magic, bytecode, fixup, addr, init = 0, modaddr = mark_heap(); byte *moddep, *rld, *esd, *cdd, *sym; byte header[128]; char filename[32], string[17]; @@ -286,7 +290,8 @@ int load_mod(byte *mod) * This is a relocatable bytecode module. */ bytecode = header[4] | (header[5] << 8); - moddep = header + 6; + init = header[6] | (header[7] << 8); + moddep = header + 8; if (*moddep) { /* @@ -329,6 +334,7 @@ int load_mod(byte *mod) printf("Module code+data size: %d\n", len); printf("Module magic: $%04X\n", magic); printf("Module bytecode: $%04X\n", bytecode); + printf("Module init: $%04X\n", init); } /* * Print out the Re-Location Dictionary. @@ -415,6 +421,14 @@ int load_mod(byte *mod) * Reserve heap space for relocated module. */ alloc_heap(end - modaddr); + /* + * Call init routine. + */ + if (init) + { + interp(mem_data + init + modaddr - MOD_ADDR); + POP; + } return (fd > 0); } void interp(code *ip); diff --git a/PLASMA/src/plvm02.s b/PLASMA/src/plvm02.s index 82b95981..5603aa6d 100644 --- a/PLASMA/src/plvm02.s +++ b/PLASMA/src/plvm02.s @@ -72,12 +72,97 @@ DVSIGN = TMPX CLD BIT LCRWEN+LCBNK2 BIT LCRWEN+LCBNK2 +;* +;* INSTALL PAGE 3 VECTORS +;* LDY #$10 - LDA PAGE3,Y STA $03D0,Y DEY BPL - +;* +;* MOVE VM INTO LANGUAGE CARD +;* + LDA #VMCORE + STA $07 + LDA #$00 + STA $08 + LDA #$D0 + STA $09 + LDY #$00 +- LDA ($06),Y ; COPY VM+CMD INTO LANGUAGE CARD + STA ($08),Y + INY + BNE - + INC $07 + INC $09 + LDA $09 + CMP #$E0 + BNE - +;* +;* INIT STACKS, FRAMES, AND HEAPS +;* + LDX #$FE + TXS + LDX #$00 + STX $01FF LDX #ESTKSZ/2 +;* +;* LOOK FOR STARTUP FILE +;* + JSR PRODOS ; OPEN AUTORUN + !BYTE $C8 + !WORD OPENPARMS + BCC + + JMP EXIT ++ LDA REFNUM + STA NLPARMS+1 + JSR PRODOS + !BYTE $C9 + !WORD NLPARMS + BCC + + JMP EXIT ++ LDA REFNUM + STA READPARMS+1 + JSR PRODOS + !BYTE $CA + !WORD READPARMS + BCC + + JMP EXIT ++ LDX READPARMS+6 + STX $01FF +EXIT JSR PRODOS + !BYTE $CC + !WORD CLOSEPARMS + LDY #$00 + STY $06 + LDA #$D1 + STA $07 +- LDA ($06),Y ; LOAD FIRST PAGE OF CMD INTO PLACE + STA $1000,Y + INY + BNE - + LDA #$7F + ADC #$01 ; SET V FLAG + JMP $1007 ; CALL CMD +AUTORUN !BYTE 7,"AUTORUN" +OPENPARMS !BYTE 3 + !WORD AUTORUN + !WORD $0800 +REFNUM !BYTE 0 +NLPARMS !BYTE 3 + !BYTE 0 + !BYTE $7F + !BYTE $0D +READPARMS !BYTE 4 + !BYTE 0 + !WORD $0200 + !WORD $0080 + !WORD 0 +CLOSEPARMS !BYTE 1 + !BYTE 0 PAGE3 = * !PSEUDOPC $03D0 { ;* @@ -90,7 +175,7 @@ CALLADR JSR $0000 BIT LCRDEN+LCBNK2 RTS } -PLASMA = * +VMCORE = * !PSEUDOPC $D000 { ;* ;* OPCODE TABLE @@ -104,6 +189,22 @@ OPTBL !WORD ZERO,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 00 02 04 06 08 0A 0C 0E !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 ;* +;* OPXCODE TABLE +;* +OPXTBL !WORD ZEROX,ADDX,SUBX,MULX,DIVX,MODX,INCRX,DECRX ; 00 02 04 06 08 0A 0C 0E + !WORD NEGX,COMPX,BANDX,IORX,XORX,SHLX,SHRX,IDXWX ; 10 12 14 16 18 1A 1C 1E + !WORD LNOTX,LORX,LANDX,LAX,LLAX,CBX,CWX,SWAPX ; 20 22 24 26 28 2A 2C 2E + !WORD DROPX,DUPX,PUSHX,PULLX,BRLTX,BRGTX,BREQX,BRNEX ; 30 32 34 36 38 3A 3C 3E + !WORD ISEQX,ISNEX,ISGTX,ISLTX,ISGEX,ISLEX,BRFLSX,BRTRUX; 40 42 44 46 48 4A 4C 4E + !WORD BRNCHX,IBRNCHX,CALLX,ICALX,ENTERX,LEAVEX,RETX,NEXTOPX; 50 52 54 56 58 5A 5C 5E + !WORD LBX,LWX,LLBX,LLWX,LABX,LAWX,DLBX,DLWX ; 60 62 64 66 68 6A 6C 6E + !WORD SBX,SWX,SLBX,SLWX,SABX,SAWX,DABX,DAWX ; 70 72 74 76 78 7A 7C 7E +;* +;* COMMAND PROCESSING +;* + !SOURCE loadcmd.s +; !BINARY CMDLINE.BIN +;* ;* ENTER INTO BYTECODE INTERPRETER ;* INTERP PLA @@ -145,24 +246,10 @@ NEXTOPX CLI FETCHOPX SEI STA ALTRDON LDA (IP),Y + ORA #$80 ; SELECT OPX OPCODES STA *+5 JMP (OPXTBL) ;* -;* ALIGN TO NEXT PAGE -;* - !ALIGN 255, 0 -;* -;* OPXCODE TABLE -;* -OPXTBL !WORD ZEROX,ADDX,SUBX,MULX,DIVX,MODX,INCRX,DECRX ; 00 02 04 06 08 0A 0C 0E - !WORD NEGX,COMPX,BANDX,IORX,XORX,SHLX,SHRX,IDXWX ; 10 12 14 16 18 1A 1C 1E - !WORD LNOTX,LORX,LANDX,LAX,LLAX,CBX,CWX,SWAPX ; 20 22 24 26 28 2A 2C 2E - !WORD DROPX,DUPX,PUSHX,PULLX,BRLTX,BRGTX,BREQX,BRNEX ; 30 32 34 36 38 3A 3C 3E - !WORD ISEQX,ISNEX,ISGTX,ISLTX,ISGEX,ISLEX,BRFLSX,BRTRUX; 40 42 44 46 48 4A 4C 4E - !WORD BRNCHX,IBRNCHX,CALLX,ICALX,ENTERX,LEAVEX,RETX,NEXTOPX; 50 52 54 56 58 5A 5C 5E - !WORD LBX,LWX,LLBX,LLWX,LABX,LAWX,DLBX,DLWX ; 60 62 64 66 68 6A 6C 6E - !WORD SBX,SWX,SLBX,SLWX,SABX,SAWX,DABX,DAWX ; 70 72 74 76 78 7A 7C 7E -;* ;* ADD TOS TO TOS-1 ;* ADD LDA ESTKL,X diff --git a/PLASMA/src/samplib.s b/PLASMA/src/samplib.s index 210ed6a8..8f837e96 100755 --- a/PLASMA/src/samplib.s +++ b/PLASMA/src/samplib.s @@ -13,6 +13,7 @@ _SEGBEGIN ; !WORD $DA7E ; MAGIC # !WORD _SUBSEG ; BYTECODE SUB-SEGMENT + !WORD _INIT ; BYTECODE INIT ROUTINE ; ; MODULE DEPENDENCY LIST ; NOTE: DCI = PSUEDO OP FOR ASCII STRING WITH HI BIT SET EXCEPT LAST CHAR @@ -59,6 +60,8 @@ FIXUP7 !WORD $0000 !BYTE $54 ; CALL INCNT FIXUP8 !WORD $0000 !BYTE $5A ; LEAVE +_INIT + !BYTE $5C ; RET ; ; END OF CODE/DATA + BYTECODE SEGMENT ; diff --git a/PLASMA/src/test.pla b/PLASMA/src/test.pla index 454a3d11..2d78516f 100755 --- a/PLASMA/src/test.pla +++ b/PLASMA/src/test.pla @@ -49,4 +49,5 @@ export def indirect mainptr() end +ascii done diff --git a/PLASMA/src/testlib.pla b/PLASMA/src/testlib.pla index 4e4dda9b..737ecaef 100755 --- a/PLASMA/src/testlib.pla +++ b/PLASMA/src/testlib.pla @@ -4,6 +4,7 @@ import stdlib predef cls, gotoxy, puts, putc end +byte loadstr[] = "testlib loaded!\n" ; ; Define functions. ; @@ -20,4 +21,5 @@ export def puti(i) fin end +puts(@loadstr); done