From 86408f5157fe60f6a1ee01d2b97c2cc75f19919b Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Sat, 24 Feb 2018 18:11:06 -0800 Subject: [PATCH] First Commodore 64 version! --- PLASMA.D64 | Bin 0 -> 174848 bytes src/makefile | 2 +- src/vmsrc/c64/cmd.pla | 140 +++++++++------------------------------- src/vmsrc/c64/plvmc64.s | 22 ++++--- 4 files changed, 46 insertions(+), 118 deletions(-) create mode 100644 PLASMA.D64 diff --git a/PLASMA.D64 b/PLASMA.D64 new file mode 100644 index 0000000000000000000000000000000000000000..36f4096c8766a518699243700aa6308b55320cf4 GIT binary patch literal 174848 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 vmsrc/c64/cmd.a $(PLVMC64): vmsrc/c64/plvmc64.s vmsrc/c64/cmd.a - acme -o $(PLVMC64) -l vmsrc/c64/plvmc64.sym vmsrc/c64/plvmc64.s + acme -f cbm -o $(PLVMC64) -l vmsrc/c64/plvmc64.sym vmsrc/c64/plvmc64.s vmsrc/apple/a1cmd.a: vmsrc/apple/a1cmd.pla $(PLASM) ./$(PLASM) -AOW < vmsrc/apple/a1cmd.pla > vmsrc/apple/a1cmd.a diff --git a/src/vmsrc/c64/cmd.pla b/src/vmsrc/c64/cmd.pla index 9688a77..d457d4f 100755 --- a/src/vmsrc/c64/cmd.pla +++ b/src/vmsrc/c64/cmd.pla @@ -1,6 +1,6 @@ const RELADDR = $1000 -const inbuff = $200 -const freemem = $0006 +const freemem = $0100 +//const inbuff = $0200 // // System flags: memory allocator screen holes. // @@ -18,16 +18,6 @@ const resxhgr2 = $0080 const modkeep = $1000 const modinitkeep = $2000 // -// CFFA1 addresses. -// -const CFFADest = $00 -const CFFAFileName = $02 -const CFFAOldName = $04 -const CFFAFileType = $06 -const CFFAAuxType = $07 -const CFFAFileSize = $09 -const CFFAEntryPtr = $0B -// // Pedefined functions. // predef syscall(cmd,null)#1, call(addr,areg,xreg,yreg,status)#1 @@ -51,13 +41,9 @@ byte perr, refauto // // String pool. // +byte inbuff[128] byte autorun[] = "AUTORUN" byte verstr[] = "\nPLASMA " -byte freestr[] = "MEM FREE:$" -byte errorstr[] = "ERR:$" -byte prompt[] = "PLASMA" -byte okstr[] = "OK" -byte huhstr[] = "?\n" byte hexchar[] = '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' // // Exported Machine ID. @@ -195,12 +181,6 @@ CALL6502 JSR $FFFF REGVALS !FILL 4 end // -// QUIT TO MONITOR -// -asm quit()#0 - JMP $9000 -end -// // SET MEMORY TO VALUE // MEMSET(ADDR, VALUE, SIZE) // With optimizations from Peter Ferrie @@ -725,16 +705,15 @@ end // asm cout(c)#0 LDA ESTKL,X - JSR TOUPR - ORA #$80 - JMP $FFEF + INX + JMP $FFD2 end asm cin()#1 DEX -- LDA $D011 - BPL - - LDA $D010 + STX ESP + JSR $FFCF AND #$7F + LDX ESP STA ESTKL,X LDA #$00 STA ESTKH,X @@ -755,62 +734,19 @@ def print(i)#0 cout(i % 10 + '0') end def rdstr(prompt)#1 - byte ch, maxlen - maxlen = 0 + byte ch inbuff.0 = 0 cout(prompt) - repeat + for inbuff = 0 to 127 ch = cin - when ch - is $15 // right arrow - if ^inbuff < maxlen //inbuff.0 < maxlen - inbuff.0++ - ch = inbuff[inbuff.0] - cout(ch) - fin - break - is $08 // left arrow - if inbuff.0 - cout('\\') - cout(inbuff[inbuff.0]) - inbuff.0-- - fin - break - is $04 // ctrl-d - if inbuff.0 - cout('#') - cout(inbuff[inbuff.0]) - memcpy(inbuff + inbuff.0, inbuff + inbuff.0 + 1, maxlen - inbuff.0) - maxlen-- - inbuff.0-- - fin - break - is $0C // ctrl-l - crout - prstr(inbuff) - break - is $0D // return - is $18 // ctrl-x - crout - inbuff.0 = 0 - break - is $9B // escape - inbuff.0 = 0 - ch = $0D - break - otherwise - if ch >= ' ' - cout(ch) - inbuff.0++ - inbuff[inbuff.0] = ch - if inbuff.0 > maxlen - maxlen = inbuff.0 - fin - fin - wend - until ch == $0D or inbuff.0 == $7F - cout($0D) - return inbuff + if ch == $0D + break + fin + inbuff.0++ + inbuff[inbuff.0] = ch + next + crout + return @inbuff end def prbyte(v)#0 cout(hexchar[(v >> 4) & $0F]) @@ -834,27 +770,13 @@ def strcat(dst, src)#1 return dst end // -// CFFA1 routines -// FILE I/O +// C64 FILE I/O // -//def opendir -// perr = syscall($10, 0) -// return perr -//end -//def readdir -// perr = syscall($12, 0) -// return *CFFAEntryPtr -//end def finddirentry(filename)#1 - *CFFAFileName = filename - perr = syscall($14, 0) - return *CFFAEntryPtr + return 0 end def readfile(filename, buffer)#1 - *CFFADest = buffer - *CFFAFileName = filename - perr = syscall($22, 0) - return perr + return 0 end // // Heap routines. @@ -1150,7 +1072,7 @@ heap = *freemem // // Print PLASMA version // -prstr(@verstr); prbyte(version.1); cout('.'); prbyte(version.0); crout +prstr("\nPRELIM PLASMA "); prbyte(version.1); cout('.'); prbyte(version.0); crout // // Init symbol table. // @@ -1176,7 +1098,7 @@ perr = 0 // Print some startup info. // if not ^cmdptr - prstr(@freestr) + prstr("MEM FREE:$") prword(availheap) crout fin @@ -1186,24 +1108,24 @@ fin while 1 if ^cmdptr when toupper(parsecmd(cmdptr)) - is 'Q' - quit + is 'C' + break is '+' execmod(cmdptr) break otherwise - prstr(@huhstr) + cout('?') wend if perr - prstr(@errorstr) + prstr("ERR:$") prbyte(perr) perr = 0 else - prstr(@okstr) + prstr("OK") fin - crout() + crout fin - prstr(@prompt) - cmdptr = rdstr($BA) + prstr("C64 PLASMA") + cmdptr = rdstr(':') loop done diff --git a/src/vmsrc/c64/plvmc64.s b/src/vmsrc/c64/plvmc64.s index ae2b0c7..bfaa45c 100644 --- a/src/vmsrc/c64/plvmc64.s +++ b/src/vmsrc/c64/plvmc64.s @@ -10,8 +10,8 @@ ;* !SOURCE "vmsrc/plvmzp.inc" DVSIGN = TMP+2 -DROP = $EF -NEXTOP = $F0 +DROP = $7F +NEXTOP = $80 FETCHOP = NEXTOP+1 IP = FETCHOP+1 IPL = IP @@ -21,7 +21,7 @@ OPPAGE = OPIDX+1 ;* ;* INTERPRETER HEADER+INITIALIZATION ;* - *= $0800 + *= $1000 SEGBEGIN JMP VMINIT ;* ;* SYSTEM INTERPRETER ENTRYPOINT @@ -900,21 +900,27 @@ LEAVE INY ;+INC_IP RET RTS CMD !SOURCE "vmsrc/c64/cmd.a" SEGEND = * -VMINIT LDY #$10 ; INSTALL PAGE 0 FETCHOP ROUTINE +VMINIT JSR $FFE7 ; CLOSE ALL CHANNELS + LDY #$10 ; INSTALL PAGE 0 FETCHOP ROUTINE - LDA PAGE0-1,Y STA DROP-1,Y DEY BNE - LDA #$4C ; SET JMPTMP OPCODE STA JMPTMP - STY IFPL ; INIT FRAME POINTER - LDA #$80 + STY IFPL ; INIT FRAME POINTER TO $D000 + LDA #$D0 STA IFPH LDA #SEGEND - STA SRCH + STA $0101 + LDX #$FF ; INIT STACK POINTER + TXS LDX #ESTKSZ/2 ; INIT EVAL STACK INDEX + LDA $01 + AND #$FE ; SWAP OUT BASIC ROM + STA $01 JMP CMD PAGE0 = * !PSEUDOPC DROP {