diff --git a/PLASMA-BLD1.PO b/PLASMA-BLD1.PO index 3ced536..bb1d254 100644 Binary files a/PLASMA-BLD1.PO and b/PLASMA-BLD1.PO differ diff --git a/PLASMA-DEM1.PO b/PLASMA-DEM1.PO index 58fa81e..62ca12c 100644 Binary files a/PLASMA-DEM1.PO and b/PLASMA-DEM1.PO differ diff --git a/PLASMA-SOS1.PO b/PLASMA-SOS1.PO index 1db9bc3..6c88290 100644 Binary files a/PLASMA-SOS1.PO and b/PLASMA-SOS1.PO differ diff --git a/PLASMA-SYS1.PO b/PLASMA-SYS1.PO index 06d0147..0437ae0 100644 Binary files a/PLASMA-SYS1.PO and b/PLASMA-SYS1.PO differ diff --git a/PLASMA.D64 b/PLASMA.D64 new file mode 100644 index 0000000..36f4096 Binary files /dev/null and b/PLASMA.D64 differ diff --git a/doc/Version 1.0.md b/doc/Version 1.0.md index 86ee8da..a24595c 100644 --- a/doc/Version 1.0.md +++ b/doc/Version 1.0.md @@ -4,7 +4,7 @@ Welcome to PLASMA: the Grand Unifying Platform for the Apple 1, ][, and ///. Download the four disk images (three if you don't plan to boot an Apple ///): -[PLASMA 1.0 System](https://github.com/dschmenk/PLASMA/blob/master/PLASMA-SYS1.PO?raw=true) +[PLASMA 1.0 System and ProDOS Boot](https://github.com/dschmenk/PLASMA/blob/master/PLASMA-SYS1.PO?raw=true) [PLASMA 1.0 Build Tools](https://github.com/dschmenk/PLASMA/blob/master/PLASMA-BLD1.PO?raw=true) diff --git a/src/FIRE.PLA#040000 b/src/FIRE.PLA#040000 deleted file mode 100755 index 1dc87c4..0000000 --- a/src/FIRE.PLA#040000 +++ /dev/null @@ -1 +0,0 @@ -CONST FALSE = 0 CONST TRUE = NOT FALSE CONST SHOWLORES = $C056 CONST KEYBOARD = $C000 CONST KEYSTROBE = $C010 CONST EMPTY = 0 CONST TREE = 4 CONST FIRE = 13 CONST FORESTSIZE = 42*42 BYTE HELLOMSG[] = "PRESS ANY KEY TO BEGIN..." BYTE EXITMSG[] = "PRESS ANY KEY TO EXIT." BYTE GOODBYE[] = "THAT'S ALL FOLKS!" BYTE TREES1[FORESTSIZE] BYTE TREES2[FORESTSIZE] WORD RNDNUM DEF TEXTMODE CALL($FB39, 0, 0, 0, 0) END DEF HOME CALL($FC58, 0, 0, 0, 0) END DEF GOTOXY(X, Y) ^($24) = X CALL($FB5B, Y, 0, 0, 0) END DEF GRMODE CALL($FB40, 0, 0, 0, 0) ^SHOWLORES END DEF RANDOMIZE(SEED) RNDNUM = (SEED >> 8) + (SEED << 8) + SEED END DEF RND RNDNUM = (RNDNUM << 8) + RNDNUM + 12345 RETURN RNDNUM & $7FFF END DEF BYFIRE(TREEPTR) IF ^(TREEPTR - 43) == FIRE RETURN TRUE ELSIF ^(TREEPTR - 42) == FIRE RETURN TRUE ELSIF ^(TREEPTR - 41) == FIRE RETURN TRUE ELSIF ^(TREEPTR - 1) == FIRE RETURN TRUE ELSIF ^(TREEPTR + 1) == FIRE RETURN TRUE ELSIF ^(TREEPTR + 41) == FIRE RETURN TRUE ELSIF ^(TREEPTR + 42) == FIRE RETURN TRUE ELSIF ^(TREEPTR + 43) == FIRE RETURN TRUE FIN RETURN FALSE END DEF FORESTFIRE WORD NEWTREES, OLDTREES, NEWTREE, OLDTREE, YROW BYTE X, Y MEMSET(@TREES1, FORESTSIZE, EMPTY) MEMSET(@TREES2, FORESTSIZE, EMPTY) OLDTREES = @TREES1 NEWTREES = @TREES2 FOR Y = 1 TO 40 YROW = Y * 42 FOR X = 1 TO 40 IF RND < 8000 ^(OLDTREES + X + YROW) = TREE FIN NEXT NEXT WHILE ^$C000 < 128 FOR Y = 1 TO 40 YROW = Y * 42 FOR X = 1 TO 40 OLDTREE = OLDTREES + X + YROW NEWTREE = NEWTREES + X + YROW WHEN ^OLDTREE IS EMPTY IF RND < 5000 ^NEWTREE = TREE ELSE ^NEWTREE = EMPTY FIN BREAK IS TREE IF RND < 5 OR BYFIRE(OLDTREE) ^NEWTREE = FIRE ELSE ^NEWTREE = TREE FIN BREAK IS FIRE ^NEWTREE = EMPTY WEND CALL($F864, ^NEWTREE, 0, 0, 0) CALL($F800, Y - 1, 0, X - 1, 0) NEXT NEXT YROW = NEWTREES NEWTREES = OLDTREES OLDTREES = YROW LOOP ^$C010 END PRSTR(@HELLOMSG) WHILE ^$C000 < 128 RNDNUM = RNDNUM + 1 LOOP RANDOMIZE(RNDNUM) ^$C010 GRMODE HOME GOTOXY(10,22) PRSTR(@EXITMSG) FORESTFIRE TEXTMODE HOME PRSTR(@GOODBYE) DONE \ No newline at end of file diff --git a/src/inc/grafix.plh b/src/inc/grafix.plh new file mode 100644 index 0000000..1dd05a8 --- /dev/null +++ b/src/inc/grafix.plh @@ -0,0 +1,14 @@ +import grafix + predef pencolor(clr)#0 + predef fillcolor(clr)#0 + predef fillscreen()#0 + predef penmove(x, y)#0 + predef plot(x, y)#0 + predef line(x1, y1, x2, y2)#0 + predef lineto(x, y)#0 + predef rect(x1, y1, x2, y2)#0 + predef fillrect(x1, y1, x2, y2)#0 + predef bitblt(blk, pitch, x, y, width, height)#0 + predef drawmode(mode)#0 + predef setmode(mode)#0 +end diff --git a/src/inc/joybuzz.plh b/src/inc/joybuzz.plh new file mode 100644 index 0000000..9bdc6d2 --- /dev/null +++ b/src/inc/joybuzz.plh @@ -0,0 +1,4 @@ +import joybuzz + const MAX_JOY = 79 + predef joypos(buzz)#4 +end diff --git a/src/libsrc/conio.pla b/src/libsrc/apple/conio.pla similarity index 100% rename from src/libsrc/conio.pla rename to src/libsrc/apple/conio.pla diff --git a/src/libsrc/dgr.pla b/src/libsrc/apple/dgr.pla similarity index 96% rename from src/libsrc/dgr.pla rename to src/libsrc/apple/dgr.pla index 001cf97..d76d49e 100755 --- a/src/libsrc/dgr.pla +++ b/src/libsrc/apple/dgr.pla @@ -506,7 +506,7 @@ asm _dgrFillTile RTS end // -// Wait for VLB - Doens't work on //c +// Wait for VLB - Shouldn't work on //c, but seems to. // asm vlbWait#0 - LDA $C019 @@ -525,7 +525,6 @@ export def dgrMode#1 ^showpage1 ^ena80 = 0 ^show80 = 0 -// ^mapaux = 0 ^an3on return 1 end @@ -578,16 +577,11 @@ export def dgrLine(buff, x1, y1, x2, y2)#0 fin dx2 = dx << 1 dy2 = dy << 1 - if dx >= dy - // Horizontal line + if dx >= dy // Horizontal line if sx < 0 - pp = x1 - x1 = x2 - x2 = pp - pp = y1 - y1 = y2 - y2 = pp - sy = -sy + x1, x2 = x2, x1 + y1, y2 = y2, y1 + sy = -sy fin dd2 = dx2 - dy2 err = dx - dy2 @@ -600,7 +594,7 @@ export def dgrLine(buff, x1, y1, x2, y2)#0 sx = 1 dy-- err = err + dd2 - else + else sx++ err = err - dy2 fin @@ -608,16 +602,11 @@ export def dgrLine(buff, x1, y1, x2, y2)#0 if y2 == y1 dgrHLin(buff, x1, x2, y1) fin - else - // Vertical line + else // Vertical line if sy < 0 - pp = x1 - x1 = x2 - x2 = pp - pp = y1 - y1 = y2 - y2 = pp - sx = -sx + x1, x2 = x2, x1 + y1, y2 = y2, y1 + sx = -sx fin dd2 = dy2 - dx2 err = dy - dx2 @@ -630,7 +619,7 @@ export def dgrLine(buff, x1, y1, x2, y2)#0 sy = 1 dx-- err = err + dd2 - else + else sy++ err = err - dx2 fin diff --git a/src/libsrc/fileio.pla b/src/libsrc/apple/fileio.pla similarity index 100% rename from src/libsrc/fileio.pla rename to src/libsrc/apple/fileio.pla diff --git a/src/libsrc/apple/grafix.pla b/src/libsrc/apple/grafix.pla new file mode 100644 index 0000000..6a610ab --- /dev/null +++ b/src/libsrc/apple/grafix.pla @@ -0,0 +1,174 @@ +include "inc/cmdsys.plh" + +byte gfxref, gfxseg +byte params[8], cmd[16] + +export def pencolor(clr)#0 + params:4 = 2 + cmd.0 = 19 // Pen color + cmd.1 = clr + syscall($CB, @params) +end + +export def fillcolor(clr)#0 + params:4 = 2 + cmd.0 = 20 // Fill color + cmd.1 = clr + syscall($CB, @params) +end + +export def fillscreen()#0 + params:4 = 1 + cmd.9 = 28 // Clear viewport + syscall($CB, @params) +end + +export def penmove(x, y)#0 + params:4 = 5 + cmd.0 = 26 // Move pen + cmd:1 = x + cmd:3 = y + syscall($CB, @params) +end + +export def plot(x, y)#0 + params:4 = 5 + cmd.0 = 25 // Plot + cmd:1 = x + cmd:3 = y + syscall($CB, @params) +end + +export def line(x1, y1, x2, y2)#0 + params:4 = 10 + cmd.0 = 26 // Move pen + cmd:1 = x1 + cmd:3 = y1 + cmd.5 = 24 // Line + cmd:6 = x2 + cmd:8 = y2 + syscall($CB, @params) +end + +export def lineto(x, y)#0 + params:4 = 5 + cmd.0 = 24 // Line + cmd:1 = x + cmd:3 = y + syscall($CB, @params) +end + +export def rect(x1, y1, x2, y2)#0 + params:4 = 10 + cmd.0 = 26 // Move pen + cmd:1 = x1 + cmd:3 = y1 + cmd.5 = 24 // Line + cmd:6 = x2 + cmd:8 = y1 + syscall($CB, @params) + params:4 = 15 + cmd.0 = 24 // Line + cmd:1 = x2 + cmd:3 = y2 + cmd.5 = 24 // Line + cmd:6 = x1 + cmd:8 = y2 + cmd.10 = 24 // Line + cmd:11 = x1 + cmd:13 = y1 + syscall($CB, @params) +end + +export def fillrect(x1, y1, x2, y2)#0 + params:4 = 11 + cmd.0 = 2 // Set viewport + cmd:1 = x1 + cmd:3 = x2 + cmd:5 = y1 + cmd:7 = y2 + cmd.9 = 28 // Clear viewport + cmd.10 = 1 // Reset viewport + syscall($CB, @params) +end + +export def bitblt(bits, pitch, x, y, width, height)#0 + params:4 = 14 + cmd.0 = 4 // Draw block + cmd:1 = bits + cmd.3 = ^$FFED & $8F + cmd:4 = pitch + cmd:6 = x + cmd:8 = y + cmd:10 = width + cmd:12 = height + syscall($CB, @params) +end + +export def drawmode(mode)#0 + params:4 = 2 + cmd.0 = 21 // Transfer mode + cmd.1 = mode + syscall($CB, @params) +end + +export def setmode(mode)#0 + if mode < 0 + // + // Free driver + // + params.0 = 1 + params.1 = gfxref + syscall($CC, @params) + gfxref = 0 + // + // Deaalocate bank 0 + // + params.0 = 1 + params.1 = gfxseg + syscall($45, @params) + ^$1907 = $00 // Unset graphics pages allocated + fin + if not gfxref + return + fin + params.0 = 3 + params.1 = gfxref + params:2 = @cmd + params:4 = 8 + cmd.0 = 16 // Set mode + cmd.1 = mode + cmd.2 = 19 // Pen color + cmd.3 = 0 + cmd.4 = 1 // Reset viewport + cmd.5 = 28 // Clear viewport + cmd.7 = 15 // Turn on screen + syscall($CB, @params) +end + +if MACHID <> $F2 + puts("Apple /// only.\n") + return -1 +fin +// +// Allocate bank 0 +// +params.0 = 4 +params:1 = $2000 +params:3 = $9F00 +params.5 = $10 +params.6 = $00 +syscall($40, @params) +gfxseg = params.6 +^$1907 = $80 // Set graphics pages allocated +// +// Open graphics driver +// +params.0 = 4 +params:1 = ".GRAFIX" +params.3 = 0 +params:4 = 0 +params.6 = 0 +syscall($C8, @params) +gfxref = params.3 +done diff --git a/src/libsrc/apple/joybuzz.pla b/src/libsrc/apple/joybuzz.pla new file mode 100644 index 0000000..2c831ec --- /dev/null +++ b/src/libsrc/apple/joybuzz.pla @@ -0,0 +1,60 @@ +asm asmdefs + !SOURCE "vmsrc/plvmzp.inc" +SPEAKER = $C030 +GCSTRB = $C070 +GC0 = $C064 +GC1 = $C065 +GCPB1 = $C061 +GCPB2 = $C062 +GCMAX = 79 ; MAX VALUE FOR GAME CONTROLLER +end +// +// Read both game controllers in parallel +// +export asm joypos(buzz)#4 + LDY ESTKL,X ; BUZZ TONE + STY TMPH + DEX + DEX + DEX + LDA #$00 + STA ESTKL+2,X + STA ESTKH+2,X + STA ESTKL+3,X + STA ESTKH+3,X + LDA #GCMAX + SEC + BIT GCSTRB +BUZZ DEY + BNE BUZZDLY + BIT SPEAKER + LDY TMPH ; BUZZ TONE +GC0READ BIT GC0 + BPL GC0DLY + INC ESTKL+3,X +GC1READ BIT GC1 + BPL GC1DLY + INC ESTKL+2,X +JOYLP SBC #$01 + BNE BUZZ + TAY ; LDY #$00 + BIT GCPB1 ; READ GC BUTTONS + BPL + + DEY ++ STY ESTKL+1,X + STY ESTKH+1,X + TAY ; LDY #$00 + BIT GCPB2 + BPL + + DEY ++ STY ESTKL,X + STY ESTKH,X + RTS +GC0DLY NOP ; TIMING + BPL GC1READ +GC1DLY NOP ; TIMING + BPL JOYLP +BUZZDLY BNE + ; TIMING ++ BNE GC0READ +end +done diff --git a/src/libsrc/portio.pla b/src/libsrc/apple/portio.pla similarity index 100% rename from src/libsrc/portio.pla rename to src/libsrc/apple/portio.pla diff --git a/src/libsrc/sdfat.pla b/src/libsrc/apple/sdfat.pla similarity index 100% rename from src/libsrc/sdfat.pla rename to src/libsrc/apple/sdfat.pla diff --git a/src/libsrc/sndseq.pla b/src/libsrc/apple/sndseq.pla similarity index 92% rename from src/libsrc/sndseq.pla rename to src/libsrc/apple/sndseq.pla index 1989cd0..152d951 100755 --- a/src/libsrc/sndseq.pla +++ b/src/libsrc/apple/sndseq.pla @@ -67,12 +67,14 @@ predef musicStop#0 predef spkrSequence(yield, func)#0 predef a2spkrTone(pitch, duration)#0 predef a2spkrPWM(sample, speed, len)#0 +predef a2keypressed // // Static sequencer values // export word musicSequence = @spkrSequence export word spkrTone = @a2spkrTone export word spkrPWM = @a2spkrPWM +word keypressed = @a2keypressed word instr[] // Overlay with other variables word seqTrack, seqEvent, seqTime, eventTime, updateTime @@ -211,6 +213,31 @@ asm psgWrite(pVIA, reg, val)#0 INX RTS end +asm viaCheck(pVIA)#1 + PHP + SEI + LDA ESTKL,X + STA TMPL + LDA ESTKH,X + STA TMPH + STX ESP + LDX #$80 + LDY #$04 + SEC +- LDA (TMP),Y + BMI + + DEX + BNE - + TXA ; TIMEOUT + BEQ ++ ++ SBC (TMP),Y +++ LDX ESP + STA ESTKL,X + LDA #$00 + STA ESTKH,X + PLP + RTS +end // // Apple II speaker tone generator routines // @@ -328,6 +355,30 @@ asm a2spkrPWM(sample, speed, len)#0 INX RTS end +asm a2keypressed + INC $004E ; rndseed + BNE + + INC $004F ++ DEX + LDY #$00 + BIT $C000 + BPL + + DEY ++ STY ESTKL,X + STY ESTKH,X + RTS +end +def a3keypressed + byte count + byte params[5] + + params.0 = 3 + params.1 = cmdsys.devcons + params.2 = 5 + params:3 = @count + syscall($82, @params) + return count +end def a3spkrTone(pitch, duration)#0 byte env @@ -348,14 +399,16 @@ end // Search slots for MockingBoard // def mbTicklePSG(pVIA) - pVIA->IER = $7F // Mask all interrupts - pVIA->ACR = $00 // Stop T1 countdown - pVIA->DDRB = $FF // Output enable port A and B - pVIA->DDRA = $FF - pVIA->IORA = $00 // Reset MockingBoard - if pVIA->IORA == $00 + //puts("VIA address: $"); puth(pVIA); puts(" Timer Diff = "); puti(viaCheck(pVIA)); putln + if viaCheck(pVIA) == 8 and viaCheck(pVIA) == 8 // Check twice + pVIA->IER = $7F // Mask all interrupts + //pVIA->ACR = $00 // Stop T1 countdown + pVIA->DDRB = $FF // Output enable port A and B + pVIA->DDRA = $FF + pVIA->IORA = $00 // Reset MockingBoard + //if pVIA->IORA == $00 pVIA->IORA = $04 // Inactive MockingBoard control lines - if pVIA->IORA == $04 + //if pVIA->IORA == $04 // // At least we know we have some sort of R/W in the ROM // address space. Most likely a MockingBoard or John Bell @@ -366,7 +419,7 @@ def mbTicklePSG(pVIA) //if mbReadP(pVIA, 2) == $7E and mbReadP(pVIA, 3) == $0A return pVIA //fin - fin + //fin fin return 0 end @@ -591,8 +644,7 @@ def mbSequence(yield, func)#0 // seqTime++ while !(mbVIA1->IFR & $40) // Wait for T1 interrupt - if ^$C000 > 127; quit = TRUE; break; fin - *rndseed++ + if a2keypressed(); quit = TRUE; break; fin loop mbVIA1->IFR = $40 // Clear interrupt if yieldTime <= seqTime; func()#0; yieldTime = seqTime + yield; fin @@ -607,7 +659,7 @@ def mbSequence(yield, func)#0 psgWrite(mbVIA2, BENVAMP, $00) psgWrite(mbVIA2, CENVAMP, $00) fin - mbVIA1->ACR = $00 // Stop T1 countdown + //mbVIA1->ACR = $00 // Stop T1 countdown mbVIA1->IER = $7F // Mask all interrupts mbVIA1->IFR = $40 // Clear interrupt setStatusReg(status) @@ -703,7 +755,6 @@ def spkrSequence(yield, func)#0 if notes1[i] spkrTone(periods1[i], arpeggioDuration[numNotes])#0 fin - *rndseed++ next seqTime++ else @@ -713,13 +764,12 @@ def spkrSequence(yield, func)#0 period = periods1[i] break; fin - *rndseed++ next duration = eventTime - seqTime seqTime = duration + seqTime spkrTone(period, DUR16TH * duration)#0 fin - if ^$C000 > 127; return; fin + if keypressed(); return; fin if yieldTime <= seqTime; func()#0; yieldTime = seqTime + yield; fin until FALSE end @@ -737,9 +787,8 @@ def noSequence(yield, func)#0 repeat seqTime++ if seqTime < 0; seqTime = 1; fin // Capture wrap-around - *rndseed++ - a2spkrTone(0, DUR16TH) // Waste 16th of a second playing silence - if ^$C000 > 127; return; fin + spkrTone(0, DUR16TH) // Waste 16th of a second playing silence + if keypressed(); return; fin if yield == seqTime; func()#0; seqTime = 0; fin until FALSE end @@ -782,31 +831,32 @@ end // Play until keystroke // export def musicGetKey(yield, backgroundProc)#1 - while ^$C000 < 128 + while not keypressed() musicSequence(yield, backgroundProc)#0 // Call background proc every half second loop - ^$C010 - return ^$C000 + return getc end when MACHID & MACHID_MODEL is MACHID_III - spkrTone = @a3spkrTone - spkrPWM = @a3spkrPWM + spkrTone = @a3spkrTone + spkrPWM = @a3spkrPWM + keypressed = @a3keypressed break is MACHID_I puts("Sound unsupported.\n") return -1 break otherwise - puts("MockingBoard Slot:\n") - puts("ENTER = None\n") - puts("0 = Scan\n") - puts("1-7 = Slot #\n") - instr = gets('>'|$80) - if ^instr - mbSlot = mbSearch(^(instr + 1) - '0') - fin + //puts("MockingBoard Slot:\n") + //puts("ENTER = None\n") + //puts("0 = Scan\n") + //puts("1-7 = Slot #\n") + //instr = gets('>'|$80) + //if ^instr + // mbSlot = mbSearch(^(instr + 1) - '0') + //fin + mbSlot = mbSearch(0) break wend if mbSlot < 0 diff --git a/src/libsrc/sos.pla b/src/libsrc/apple/sos.pla similarity index 100% rename from src/libsrc/sos.pla rename to src/libsrc/apple/sos.pla diff --git a/src/libsrc/spiport.pla b/src/libsrc/apple/spiport.pla similarity index 100% rename from src/libsrc/spiport.pla rename to src/libsrc/apple/spiport.pla diff --git a/src/libsrc/uthernet.pla b/src/libsrc/apple/uthernet.pla similarity index 100% rename from src/libsrc/uthernet.pla rename to src/libsrc/apple/uthernet.pla diff --git a/src/libsrc/uthernet2.pla b/src/libsrc/apple/uthernet2.pla similarity index 100% rename from src/libsrc/uthernet2.pla rename to src/libsrc/apple/uthernet2.pla diff --git a/src/libsrc/c64/conio.pla b/src/libsrc/c64/conio.pla new file mode 100644 index 0000000..9bffc75 --- /dev/null +++ b/src/libsrc/c64/conio.pla @@ -0,0 +1,195 @@ +include "inc/cmdsys.plh" +// +// Handy constants. +// +const FULLMODE = 0 +const MIXMODE = 1 +// +// External interface. +// +struc t_conio + word keypressed + word getkey + word echo + word home + word gotoxy + word viewport + word texttype + word textmode + word grmode + word grcolor + word grplot + word tone + word rnd +end +// +// Predefined functions. +// +predef a2keypressed,a2home,a12echo(state),a2gotoxy(x,y),a2viewport(left, top, width, height),a2texttype(type) +predef a2textmode(cols),a2grmode(mix),a2grcolor(color),a2grplot(x,y),a2tone(duration, delay),a2rnd +// +// Exported function table. +// +word conio[] +// +// Function pointers. +// +word = @a2keypressed +word = @getc +word = @a12echo +word = @a2home +word = @a2gotoxy +word = @a2viewport +word = @a2texttype +word = @a2textmode +word = @a2grmode +word = @a2grcolor +word = @a2grplot +word = @a2tone +word = @a2rnd +// +// Screen row address arrays. +// +word txt1scrn[] = $0400,$0480,$0500,$0580,$0600,$0680,$0700,$0780 +word = $0428,$04A8,$0528,$05A8,$0628,$06A8,$0728,$07A8 +word = $0450,$04D0,$0550,$05D0,$0650,$06D0,$0750,$07D0 +word txt2scrn[] = $0800,$0880,$0900,$0980,$0A00,$0A80,$0B00,$0B80 +word = $0828,$08A8,$0928,$09A8,$0A28,$0AA8,$0B28,$0BA8 +word = $0850,$08D0,$0950,$09D0,$0A50,$0AD0,$0B50,$0BD0 +// +// Text screen parameters. +// +//byte textcols = 40 +//byte curshpos = 0 +//byte cursvpos = 0 +// +// Apple 3 console codes. +// +byte textbwmode[] = 2, 16, 0 +byte textclrmode[] = 2, 16, 1 +byte grcharset[] = 1, 0, $7F, $7F, $7F, $7F, $00, $00, $00, $00 +// +// Random number for Apple 1 and III. +// +word randnum = 12345 +// +// Native routines. +// +asm equates + !SOURCE "vmsrc/plvmzp.inc" +end +// +// def grscrn(rowaddrs) +// +asm a2grscrn(rowaddrs) +GRSCRN = $26 +GRSCRNL = GRSCRN +GRSCRNH = GRSCRNL+1 + LDA ESTKL,X + STA GRSCRNL + LDA ESTKH,X + STA GRSCRNH + RTS +end +// +// def grcolor(color) +// +asm a2grcolor(color) +GRCLR = $30 + LDA #$0F + AND ESTKL,X + STA GRCLR + ASL + ASL + ASL + ASL + ORA GRCLR + STA GRCLR + RTS +end +// +// def grplot(x, y) +// +asm a2grplot(x, y) + STY IPY + LDA ESTKL,X + AND #$FE + CMP ESTKL,X + TAY + LDA (GRSCRN),Y + STA DSTL + INY + LDA (GRSCRN),Y + STA DSTH + LDY ESTKL+1,X + LDA (DST),Y + EOR GRCLR + STA TMPL + LDA #$FF + ADC #$00 + EOR #$F0 + AND TMPL + EOR GRCLR + STA (DST),Y + LDY IPY + INX + RTS +end +// +// Commodore 64 routines. +// +def a2keypressed + return ^keyboard >= 128 +end +def a2home + return call($FC58, 0, 0, 0, 0) // home() +end +def a2gotoxy(x, y) + ^$24 = x + ^$20 + return call($FB5B, y + ^$22, 0, 0, 0) +end +def a2viewport(left, top, width, height) + if !width or !height + left = 0 + top = 0 + width = 40 + height = 24 + fin + ^$20 = left + ^$21 = width + ^$22 = top + ^$23 = height + top - 1 + return a2gotoxy(0, 0) +end +def a2texttype(type) + ^$32 = type + return 0 +end +def a2textmode(columns) + call($FB39, 0, 0, 0, 0) // textmode() + return a2home +end +def a2grmode(mix) + call($FB2F, 0, 0, 0, 0) // initmode() + call($FB40, 0, 0, 0, 0) // grmode() + if !mix + ^showfull + fin + a2home + return a2grscrn(@txt1scrn) // point to lo-res screen +end +def a2tone(duration, delay) + byte i + + while duration + ^speaker // toggle speaker + for i = delay downto 0; next + duration-- + loop + return 0 +end +def a2rnd + *a2rndnum = (*a2rndnum << 1) + *a2rndnum + 123 + return *a2rndnum & $7FFF +end +done diff --git a/src/libsrc/c64/fileio.pla b/src/libsrc/c64/fileio.pla new file mode 100644 index 0000000..ed8491d --- /dev/null +++ b/src/libsrc/c64/fileio.pla @@ -0,0 +1,77 @@ +include "inc/cmdsys.plh" +// +// External interface +// +struc t_fileio + word getpfx + word setpfx + word getfileinfo + word geteof + word iobufalloc + word open + word close + word read + word write + word create + word destroy + word newline + word readblock + word writeblock +end +predef a2getpfx(path), a23setpfx(path), a2getfileinfo(path, fileinfo), a23geteof(refnum), a2iobufs(iobufs), a2open(path), a2close(refnum) +predef a23read(refnum, buf, len), a2write(refnum, buf, len), a2create(path, type, aux), a23destroy(path) +predef a2newline(refnum, emask, nlchar), a2readblock(unit, buf, block), a2writeblock(unit, buf, block) +// +// Exported function table. +// +word fileio[] +word = @a2getpfx, @a23setpfx, @a2getfileinfo, @a23geteof, @a2iobufs, @a2open, @a2close +word = @a23read, @a2write, @a2create, @a23destroy +word = @a2newline, @a2readblock, @a2writeblock +// +// SOS/ProDOS error code +// +export byte perr +def a2getpfx(path) + return path +end +def a23setpfx(path) + return path +end +def a2getfileinfo(path, fileinfo) + return perr +end +def a23geteof(refnum) + return 0 +end +def a2iobufs(iobufs) + return 0 +end +def a2open(path) + return 0 +end +def a2close(refnum) + return perr +end +def a23read(refnum, buf, len) + return len +end +def a2write(refnum, buf, len) + return len +end +def a2create(path, type, aux) + return perr +end +def a23destroy(path) + return perr +end +def a2newline(refnum, emask, nlchar) + return perr +end +def a2readblock(unit, buf, block) + return 0 +end +def, a2writeblock(unit, buf, block) + return 0 +end +done diff --git a/src/libsrc/tone.pla b/src/libsrc/tone.pla deleted file mode 100644 index 7440fa5..0000000 --- a/src/libsrc/tone.pla +++ /dev/null @@ -1,116 +0,0 @@ -export asm tone(pitch, duration) -!SOURCE "vmsrc/plvmzp.inc" - DEX - LDA ESTKL+1,X - STA ESTKL,X - LDA ESTKH+1,X - STA ESTKH,X - LDA #$00 - STA ESTKL+1,X - STA ESTKH+1,X -end -export asm tone2(pitch1, pitch2, duration)#0 - STX ESP - LDY ESTKH,X - LDA ESTKL,X - BEQ + - INY -+ STA DSTL - STY DSTH - LDY ESTKL+1,X - STY TMPL - LDA ESTKL+2,X - TAX - LDA #$00 - CPX TMPL - BNE + - TAX -+ STX TMPH - PHP - SEI -- CLC --- DEY - BNE + - LDY TMPL - BEQ ++ ; SILENCE - STA $C030 - BNE +++ -+ NOP - NOP -++ NOP - NOP - NOP -+++ DEX - BNE + - LDX TMPH - BEQ ++ ; SILENCE - STA $C030 - BNE +++ -+ NOP - NOP -++ NOP - NOP - NOP -+++ ADC #$01 - BNE -- - DEC DSTL - BNE - - DEC DSTH - BNE - - PLP - LDX ESP - INX - INX - INX - RTS -end -export asm tonePWM(sample, speed, len)#0 - STX ESP - LDY ESTKH,X - LDA ESTKL,X - BEQ + - INY -+ STY DSTH - STA DSTL - LDA ESTKL+2,X - STA SRCL - LDA ESTKH+2,X - STA SRCH - LDY ESTKL+1,X - INY - STY TMPL - LDY #$00 - PHP - SEI -- LDA (SRC),Y - SEC --- LDX TMPL ---- DEX - BNE --- - SBC #$01 - BCS -- - LDA $C030 - INY - BNE + - INC SRCH -+ DEC DSTL - BNE - - DEC DSTH - BNE - - PLP - LDX ESP - INX - INX - INX - RTS -++ -end -def toneTest#0 - byte t - for t = 2 to 128 - tone2(t, t >> 1, 10) - tone(t, 50) - next -end -toneTest() -done diff --git a/src/makefile b/src/makefile index 392864a..d77eab5 100755 --- a/src/makefile +++ b/src/makefile @@ -1,62 +1,64 @@ .SUFFIXES = -AFLAGS = -o $@ -PLVM = plvm -PLVM01 = A1PLASMA\#060280 -PLVM02 = PLASMA.SYSTEM\#FF2000 -PLVM802 = PLASMA16.SYSTEM\#FF2000 -PLVM03 = SOS.INTERP\#050000 -CMD = CMD\#061000 -ED = ED\#FE1000 -SB = SB\#FF2000 -SOS = SOS\#FE1000 -ROD = ROD\#FE1000 -SIEVE = SIEVE\#FE1000 -ARGS = ARGS\#FE1000 -SPIPORT = SPIPORT\#FE1000 -SDFAT = SDFAT\#FE1000 -FATCAT = FATCAT\#FE1000 -FATGET = FATGET\#FE1000 -FATPUT = FATPUT\#FE1000 -FATWDSK = FATWRITEDSK\#FE1000 -FATRDSK = FATREADDSK\#FE1000 -FILEIO = FILEIO\#FE1000 -CONIO = CONIO\#FE1000 -SANE = SANE\#FE1000 -FPSTR = FPSTR\#FE1000 -FPU = FPU\#FE1000 -SNDSEQ = SNDSEQ\#FE1000 -PLAYSEQ = PLAYSEQ\#FE1000 -SANITY = SANITY\#FE1000 -RPNCALC = RPNCALC\#FE1000 -WIZNET = WIZNET\#FE1000 -UTHERNET2= UTHERNET2\#FE1000 -UTHERNET= UTHERNET\#FE1000 -ETHERIP = ETHERIP\#FE1000 -INET = INET\#FE1000 -DHCP = DHCP\#FE1000 -HTTPD = HTTPD\#FE1000 -DGR = DGR\#FE1000 -TONE = TONE\#FE1000 -PORTIO = PORTIO\#FE1000 -ROGUE = ROGUE\#FE1000 -ROGUEMAP= ROGUEMAP\#FE1000 -ROGUECOMBAT= ROGUECOMBAT\#FE1000 -HELLO = HELLO\#FE1000 -MON = MON\#FE1000 -DGRTEST = DGRTEST\#FE1000 -TEST = TEST\#FE1000 -TESTLIB = TESTLIB\#FE1000 -PROFILE = PROFILE\#FE1000 -MEMMGR = MEMMGR\#FE1000 -MEMTEST = MEMTEST\#FE1000 -FIBERTEST = FIBERTEST\#FE1000 -FIBER = FIBER\#FE1000 -LONGJMP = LONGJMP\#FE1000 -PLASM = plasm -PLASMAPLASM = PLASM\#FE1000 -CODEOPT = CODEOPT\#FE1000 -INCS = toolsrc/plasm.h toolsrc/tokens.h toolsrc/symbols.h toolsrc/lex.h toolsrc/parse.h toolsrc/codegen.h -OBJS = toolsrc/plasm.c toolsrc/parse.c toolsrc/lex.c toolsrc/codegen.c +AFLAGS = -o $@ +PLVM = plvm +PLVMZP_APL = vmsrc/apple/plvmzp.inc +PLVM01 = rel/apple/A1PLASMA\#060280 +PLVM02 = rel/apple/PLASMA.SYSTEM\#FF2000 +PLVM802 = rel/apple/PLASMA16.SYSTEM\#FF2000 +PLVM03 = rel/apple/SOS.INTERP\#050000 +CMD = rel/apple/CMD\#061000 +PLVMZP_C64 = vmsrc/c64/plvmzp.inc +PLVMC64 = rel/c64/PLASMA +ED = rel/ED\#FE1000 +SOS = rel/apple/SOS\#FE1000 +ROD = rel/ROD\#FE1000 +SIEVE = rel/SIEVE\#FE1000 +ARGS = rel/ARGS\#FE1000 +SPIPORT = rel/apple/SPIPORT\#FE1000 +SDFAT = rel/apple/SDFAT\#FE1000 +FATCAT = rel/apple/FATCAT\#FE1000 +FATGET = rel/apple/FATGET\#FE1000 +FATPUT = rel/apple/FATPUT\#FE1000 +FATWDSK = rel/apple/FATWRITEDSK\#FE1000 +FATRDSK = rel/apple/FATREADDSK\#FE1000 +FILEIO_APL = rel/apple/FILEIO\#FE1000 +CONIO_APL = rel/apple/CONIO\#FE1000 +SANE = rel/SANE\#FE1000 +FPSTR = rel/FPSTR\#FE1000 +FPU = rel/FPU\#FE1000 +SNDSEQ = rel/apple/SNDSEQ\#FE1000 +PLAYSEQ = rel/apple/PLAYSEQ\#FE1000 +SANITY = rel/SANITY\#FE1000 +RPNCALC = rel/RPNCALC\#FE1000 +UTHERNET2 = rel/apple/UTHERNET2\#FE1000 +UTHERNET = rel/apple/UTHERNET\#FE1000 +ETHERIP = rel/ETHERIP\#FE1000 +INET = rel/INET\#FE1000 +DHCP = rel/DHCP\#FE1000 +HTTPD = rel/HTTPD\#FE1000 +DGR = rel/apple/DGR\#FE1000 +GRAFIX = rel/apple/GRAFIX\#FE1000 +GFXDEMO = rel/apple/GFXDEMO\#FE1000 +JOYBUZZ = rel/apple/JOYBUZZ\#FE1000 +PORTIO = rel/apple/PORTIO\#FE1000 +ROGUE = rel/ROGUE\#FE1000 +ROGUEMAP = rel/ROGUEMAP\#FE1000 +ROGUECOMBAT= rel/ROGUECOMBAT\#FE1000 +MON = rel/apple/MON\#FE1000 +DGRTEST = rel/apple/DGRTEST\#FE1000 +MEMMGR = rel/MEMMGR\#FE1000 +MEMTEST = rel/MEMTEST\#FE1000 +FIBERTEST = rel/FIBERTEST\#FE1000 +FIBER = rel/FIBER\#FE1000 +LONGJMP = rel/LONGJMP\#FE1000 +HELLO = HELLO\#FE1000 +TEST = TEST\#FE1000 +TESTLIB = TESTLIB\#FE1000 +PLASM = plasm +PLASMAPLASM = rel/PLASM\#FE1000 +CODEOPT = rel/CODEOPT\#FE1000 +INCS = toolsrc/plasm.h toolsrc/tokens.h toolsrc/symbols.h toolsrc/lex.h toolsrc/parse.h toolsrc/codegen.h +OBJS = toolsrc/plasm.c toolsrc/parse.c toolsrc/lex.c toolsrc/codegen.c # # Image filetypes for Virtual ][ # @@ -73,13 +75,30 @@ TXTTYPE = .TXT #SYSTYPE = \#FF2000 #TXTTYPE = \#040000 -all: $(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) $(TONE) $(DGR) $(DGRTEST) $(FILEIO) $(CONIO) $(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) $(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) + -rm vmsrc/plvmzp.inc + +all: apple c64 clean: -rm *FE1000 *FF2000 $(PLASM) $(PLVM) $(PLVM01) $(PLVM02) $(PLVM03) - -rm toolsrc/*.o toolsrc/*~ toolsrc/*.a - -rm vmsrc/*.o vmsrc/*~ vmsrc/*.a vmsrc/*.sym + -rm rel/* + -rm rel/apple/* + -rm rel/c64/* -rm samplesrc/*.o samplesrc/*~ samplesrc/*.a + -rm toolsrc/*.o toolsrc/*~ toolsrc/*.a + -rm toolsrc/apple/*.o toolsrc/apple/*~ toolsrc/apple/*.a + -rm toolsrc/c64/*.o toolsrc/c64/*~ toolsrc/c64/*.a + -rm vmsrc/*.o vmsrc/*~ vmsrc/*.a vmsrc/*.sym + -rm vmsrc/apple/*.o vmsrc/apple/*~ vmsrc/apple/*.a vmsrc/apple/*.sym + -rm vmsrc/c64/*.o vmsrc/c64/*~ vmsrc/c64/*.a vmsrc/c64/*.sym + -rm libsrc/*.o libsrc/*~ libsrc/*.a + -rm libsrc/apple/*.o libsrc/apple/*~ libsrc/apple/*.a + -rm libsrc/c64/*.o libsrc/c64/*~ libsrc/c64/*.a + -rm libsrc/*.o libsrc/*~ libsrc/*.a # # PLASMA compiler: plasm @@ -101,27 +120,47 @@ $(CODEOPT): toolsrc/codeopt.pla toolsrc/codeseq.plh $(PLVM): vmsrc/plvm.c cc vmsrc/plvm.c -o $(PLVM) -vmsrc/a1cmd.a: vmsrc/a1cmd.pla $(PLASM) - ./$(PLASM) -AOW < vmsrc/a1cmd.pla > vmsrc/a1cmd.a +$(PLVMZP_APL): FORCE + -mkdir rel + -mkdir rel/apple + -rm vmsrc/plvmzp.inc + -ln -s apple/plvmzp.inc vmsrc/plvmzp.inc -$(PLVM01): vmsrc/plvm01.s vmsrc/a1cmd.a - acme -o $(PLVM01) -l vmsrc/plvm01.sym vmsrc/plvm01.s +$(PLVMZP_C64): FORCE + -mkdir rel + -mkdir rel/c64 + -rm vmsrc/plvmzp.inc + -ln -s c64/plvmzp.inc vmsrc/plvmzp.inc -$(CMD): vmsrc/cmd.pla vmsrc/cmdstub.s $(PLVM02) $(PLASM) - ./$(PLASM) -AOW < vmsrc/cmd.pla > vmsrc/cmd.a - acme --setpc 8192 -o $(CMD) vmsrc/cmdstub.s +FORCE: -$(PLVM02): vmsrc/plvm02.s - acme -o $(PLVM02) -l vmsrc/plvm02.sym vmsrc/plvm02.s +vmsrc/c64/cmd.a: vmsrc/c64/cmd.pla $(PLASM) + ./$(PLASM) -AOW < vmsrc/c64/cmd.pla > vmsrc/c64/cmd.a -$(PLVM802): vmsrc/plvm802.s - acme -o $(PLVM802) -l vmsrc/plvm802.sym vmsrc/plvm802.s +$(PLVMC64): vmsrc/c64/plvmc64.s vmsrc/c64/cmd.a + acme -f cbm -o $(PLVMC64) -l vmsrc/c64/plvmc64.sym vmsrc/c64/plvmc64.s -vmsrc/soscmd.a: vmsrc/soscmd.pla $(PLASM) - ./$(PLASM) -AOW < vmsrc/soscmd.pla > vmsrc/soscmd.a +vmsrc/apple/a1cmd.a: vmsrc/apple/a1cmd.pla $(PLASM) + ./$(PLASM) -AOW < vmsrc/apple/a1cmd.pla > vmsrc/apple/a1cmd.a -$(PLVM03): vmsrc/plvm03.s vmsrc/soscmd.a - acme -o $(PLVM03) -l vmsrc/plvm03.sym vmsrc/plvm03.s +$(PLVM01): vmsrc/apple/plvm01.s vmsrc/apple/a1cmd.a + acme -o $(PLVM01) -l vmsrc/apple/plvm01.sym vmsrc/apple/plvm01.s + +$(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 + +$(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 + +$(PLVM03): vmsrc/apple/plvm03.s vmsrc/apple/soscmd.a + acme -o $(PLVM03) -l vmsrc/apple/plvm03.sym vmsrc/apple/plvm03.s # # Sample code @@ -137,10 +176,6 @@ $(ED): toolsrc/ed.pla $(PLVM02) $(PLASM) toolsrc/ed.pla ./$(PLASM) -AMOW < toolsrc/ed.pla > toolsrc/ed.a acme --setpc 4094 -o $(ED) toolsrc/ed.a -$(SB): toolsrc/sb.pla $(PLVM02) $(PLASM) toolsrc/sb.pla - ./$(PLASM) -AOW < toolsrc/sb.pla > toolsrc/sb.a - acme --setpc 8192 -o $(SB) toolsrc/sb.a - $(ARGS): libsrc/args.pla $(PLVM02) $(PLASM) ./$(PLASM) -AMOW < libsrc/args.pla > libsrc/args.a acme --setpc 4094 -o $(ARGS) libsrc/args.a @@ -161,26 +196,26 @@ $(FIBERTEST): samplesrc/fibertest.pla $(PLVM02) $(PLASM) ./$(PLASM) -AMOW < samplesrc/fibertest.pla > samplesrc/fibertest.a acme --setpc 4094 -o $(FIBERTEST) samplesrc/fibertest.a -$(SNDSEQ): libsrc/sndseq.pla $(PLVM02) $(PLASM) - ./$(PLASM) -AMOW < libsrc/sndseq.pla > libsrc/sndseq.a - acme --setpc 4094 -o $(SNDSEQ) libsrc/sndseq.a - -$(PLAYSEQ): samplesrc/playseq.pla $(PLVM02) $(PLASM) - ./$(PLASM) -AMOW < samplesrc/playseq.pla > samplesrc/playseq.a - acme --setpc 4094 -o $(PLAYSEQ) samplesrc/playseq.a - $(LONGJMP): libsrc/longjmp.pla $(PLVM02) $(PLASM) ./$(PLASM) -AMOW < libsrc/longjmp.pla > libsrc/longjmp.a acme --setpc 4094 -o $(LONGJMP) libsrc/longjmp.a -$(MON): samplesrc/mon.pla $(PLVM02) $(PLASM) - ./$(PLASM) -AMOW < samplesrc/mon.pla > samplesrc/mon.a - acme --setpc 4094 -o $(MON) samplesrc/mon.a +$(ROGUE): samplesrc/rogue.pla $(PLVM02) $(PLASM) + ./$(PLASM) -AMOW < samplesrc/rogue.pla > samplesrc/rogue.a + acme --setpc 4094 -o $(ROGUE) samplesrc/rogue.a -$(SOS): libsrc/sos.pla $(PLVM02) $(PLASM) - ./$(PLASM) -AMO < libsrc/sos.pla > libsrc/sos.a - acme --setpc 4094 -o $(SOS) libsrc/sos.a +$(ROGUECOMBAT): samplesrc/rogue.combat.pla $(PLVM02) $(PLASM) + ./$(PLASM) -AMOW < samplesrc/rogue.combat.pla > samplesrc/rogue.combat.a + acme --setpc 4094 -o $(ROGUECOMBAT) samplesrc/rogue.combat.a +$(ROGUEMAP): samplesrc/rogue.map.pla $(PLVM02) $(PLASM) + ./$(PLASM) -AMOW < samplesrc/rogue.map.pla > samplesrc/rogue.map.a + acme --setpc 4094 -o $(ROGUEMAP) samplesrc/rogue.map.a + +hello: samplesrc/hello.pla $(PLVM) $(PLASM) + ./$(PLASM) -AMOW < samplesrc/hello.pla > samplesrc/hello.a + acme --setpc 4094 -o $(HELLO) samplesrc/hello.a + ./$(PLVM) HELLO $(ROD): samplesrc/rod.pla $(PLVM02) $(PLASM) ./$(PLASM) -AMO < samplesrc/rod.pla > samplesrc/rod.a acme --setpc 4094 -o $(ROD) samplesrc/rod.a @@ -189,38 +224,6 @@ $(SIEVE): samplesrc/sieve.pla $(PLVM02) $(PLASM) ./$(PLASM) -AMW < samplesrc/sieve.pla > samplesrc/sieve.a acme --setpc 4094 -o $(SIEVE) samplesrc/sieve.a -$(UTHERNET): libsrc/uthernet.pla $(PLVM02) $(PLASM) - ./$(PLASM) -AMOW < libsrc/uthernet.pla > libsrc/uthernet.a - acme --setpc 4094 -o $(UTHERNET) libsrc/uthernet.a - -$(UTHERNET2): libsrc/uthernet2.pla $(PLVM02) $(PLASM) - ./$(PLASM) -AMOW < libsrc/uthernet2.pla > libsrc/uthernet2.a - acme --setpc 4094 -o $(UTHERNET2) libsrc/uthernet2.a - -$(ETHERIP): libsrc/etherip.pla $(PLVM02) $(PLASM) - ./$(PLASM) -AMOW < libsrc/etherip.pla > libsrc/etherip.a - acme --setpc 4094 -o $(ETHERIP) libsrc/etherip.a - -$(INET): libsrc/inet.pla $(PLVM02) $(PLASM) - ./$(PLASM) -AMOW < libsrc/inet.pla > libsrc/inet.a - acme --setpc 4094 -o $(INET) libsrc/inet.a - -$(DHCP): libsrc/dhcp.pla $(PLVM02) $(PLASM) - ./$(PLASM) -AMOW < libsrc/dhcp.pla > libsrc/dhcp.a - acme --setpc 4094 -o $(DHCP) libsrc/dhcp.a - -$(HTTPD): samplesrc/httpd.pla $(PLVM02) $(PLASM) - ./$(PLASM) -AMOW < samplesrc/httpd.pla > samplesrc/httpd.a - acme --setpc 4094 -o $(HTTPD) samplesrc/httpd.a - -$(FILEIO): libsrc/fileio.pla $(PLVM02) $(PLASM) - ./$(PLASM) -AMOW < libsrc/fileio.pla > libsrc/fileio.a - acme --setpc 4094 -o $(FILEIO) libsrc/fileio.a - -$(CONIO): libsrc/conio.pla $(PLVM02) $(PLASM) - ./$(PLASM) -AMOW < libsrc/conio.pla > libsrc/conio.a - acme --setpc 4094 -o $(CONIO) libsrc/conio.a - $(SANE): libsrc/sane.pla $(PLVM02) $(PLASM) ./$(PLASM) -AMOW < libsrc/sane.pla > libsrc/sane.a acme --setpc 4094 -o $(SANE) libsrc/sane.a @@ -237,13 +240,65 @@ $(SANITY): samplesrc/sanity.pla $(PLVM02) $(PLASM) ./$(PLASM) -AMOW < samplesrc/sanity.pla > samplesrc/sanity.a acme --setpc 4094 -o $(SANITY) samplesrc/sanity.a -$(RPNCALC): samplesrc/rpncalc.pla libsrc/fpu.pla inc/fpu.plh libsrc/fpstr.pla inc/fpstr.plh libsrc/conio.pla inc/conio.plh $(PLVM02) $(PLASM) +$(RPNCALC): samplesrc/rpncalc.pla libsrc/fpu.pla inc/fpu.plh libsrc/fpstr.pla inc/fpstr.plh inc/conio.plh $(PLVM02) $(PLASM) ./$(PLASM) -AMOW < samplesrc/rpncalc.pla > samplesrc/rpncalc.a acme --setpc 4094 -o $(RPNCALC) samplesrc/rpncalc.a -$(TONE): libsrc/tone.pla $(PLVM02) $(PLASM) - ./$(PLASM) -AMOW < libsrc/tone.pla > libsrc/tone.a - acme --setpc 4094 -o $(TONE) libsrc/tone.a +$(ETHERIP): libsrc/etherip.pla $(PLVM02) $(PLASM) + ./$(PLASM) -AMOW < libsrc/etherip.pla > libsrc/etherip.a + acme --setpc 4094 -o $(ETHERIP) libsrc/etherip.a + +$(INET): libsrc/inet.pla $(PLVM02) $(PLASM) + ./$(PLASM) -AMOW < libsrc/inet.pla > libsrc/inet.a + acme --setpc 4094 -o $(INET) libsrc/inet.a + +$(DHCP): libsrc/dhcp.pla $(PLVM02) $(PLASM) + ./$(PLASM) -AMOW < libsrc/dhcp.pla > libsrc/dhcp.a + acme --setpc 4094 -o $(DHCP) libsrc/dhcp.a + +$(HTTPD): samplesrc/httpd.pla $(PLVM02) $(PLASM) + ./$(PLASM) -AMOW < samplesrc/httpd.pla > samplesrc/httpd.a + acme --setpc 4094 -o $(HTTPD) samplesrc/httpd.a + +$(UTHERNET): libsrc/apple/uthernet.pla $(PLVM02) $(PLASM) + ./$(PLASM) -AMOW < libsrc/apple/uthernet.pla > libsrc/apple/uthernet.a + acme --setpc 4094 -o $(UTHERNET) libsrc/apple/uthernet.a + +$(UTHERNET2): libsrc/apple/uthernet2.pla $(PLVM02) $(PLASM) + ./$(PLASM) -AMOW < libsrc/apple/uthernet2.pla > libsrc/apple/uthernet2.a + acme --setpc 4094 -o $(UTHERNET2) libsrc/apple/uthernet2.a + +$(FILEIO_APL): libsrc/apple/fileio.pla $(PLVM02) $(PLASM) + ./$(PLASM) -AMOW < libsrc/apple/fileio.pla > libsrc/apple/fileio.a + acme --setpc 4094 -o $(FILEIO_APL) libsrc/apple/fileio.a + +$(CONIO_APL): libsrc/apple/conio.pla $(PLVM02) $(PLASM) + ./$(PLASM) -AMOW < libsrc/apple/conio.pla > libsrc/apple/conio.a + acme --setpc 4094 -o $(CONIO_APL) libsrc/apple/conio.a + +$(FILEIO_C64): libsrc/c64/fileio.pla $(PLVM02) $(PLASM) + ./$(PLASM) -AMOW < libsrc/c64/fileio.pla > libsrc/c64/fileio.a + acme --setpc 4094 -o $(FILEIO_C64) libsrc/c64/fileio.a + +$(CONIO_C64): libsrc/c64/conio.pla $(PLVM02) $(PLASM) + ./$(PLASM) -AMOW < libsrc/c64/conio.pla > libsrc/c64/conio.a + acme --setpc 4094 -o $(CONIO_C64) libsrc/c64/conio.a + +$(SNDSEQ): libsrc/apple/sndseq.pla $(PLVM02) $(PLASM) + ./$(PLASM) -AMOW < libsrc/apple/sndseq.pla > libsrc/apple/sndseq.a + acme --setpc 4094 -o $(SNDSEQ) libsrc/apple/sndseq.a + +$(PLAYSEQ): samplesrc/playseq.pla $(PLVM02) $(PLASM) + ./$(PLASM) -AMOW < samplesrc/playseq.pla > samplesrc/playseq.a + acme --setpc 4094 -o $(PLAYSEQ) samplesrc/playseq.a + +$(GRAFIX): libsrc/apple/grafix.pla $(PLVM02) $(PLASM) + ./$(PLASM) -AMOW < libsrc/apple/grafix.pla > libsrc/apple/grafix.a + acme --setpc 4094 -o $(GRAFIX) libsrc/apple/grafix.a + +$(GFXDEMO): samplesrc/gfxdemo.pla $(PLVM02) $(PLASM) + ./$(PLASM) -AMOW < samplesrc/gfxdemo.pla > samplesrc/gfxdemo.a + acme --setpc 4094 -o $(GFXDEMO) samplesrc/gfxdemo.a $(FATCAT): samplesrc/fatcat.pla $(PLVM02) $(PLASM) ./$(PLASM) -AMOW < samplesrc/fatcat.pla > samplesrc/fatcat.a @@ -265,39 +320,35 @@ $(FATRDSK): samplesrc/fatreaddsk.pla $(PLVM02) $(PLASM) ./$(PLASM) -AMOW < samplesrc/fatreaddsk.pla > samplesrc/fatreaddsk.a acme --setpc 4094 -o $(FATRDSK) samplesrc/fatreaddsk.a -$(SDFAT): libsrc/sdfat.pla $(PLVM02) $(PLASM) - ./$(PLASM) -AMOW < libsrc/sdfat.pla > libsrc/sdfat.a - acme --setpc 4094 -o $(SDFAT) libsrc/sdfat.a +$(SDFAT): libsrc/apple/sdfat.pla $(PLVM02) $(PLASM) + ./$(PLASM) -AMOW < libsrc/apple/sdfat.pla > libsrc/apple/sdfat.a + acme --setpc 4094 -o $(SDFAT) libsrc/apple/sdfat.a -$(SPIPORT): libsrc/spiport.pla $(PLVM02) $(PLASM) - ./$(PLASM) -AMOW < libsrc/spiport.pla > libsrc/spiport.a - acme --setpc 4094 -o $(SPIPORT) libsrc/spiport.a +$(SPIPORT): libsrc/apple/spiport.pla $(PLVM02) $(PLASM) + ./$(PLASM) -AMOW < libsrc/apple/spiport.pla > libsrc/apple/spiport.a + acme --setpc 4094 -o $(SPIPORT) libsrc/apple/spiport.a -$(PORTIO): libsrc/portio.pla $(PLVM02) $(PLASM) - ./$(PLASM) -AMOW < libsrc/portio.pla > libsrc/portio.a - acme --setpc 4094 -o $(PORTIO) libsrc/portio.a +$(JOYBUZZ): libsrc/apple/joybuzz.pla $(PLVM02) $(PLASM) + ./$(PLASM) -AMOW < libsrc/apple/joybuzz.pla > libsrc/apple/joybuzz.a + acme --setpc 4094 -o $(JOYBUZZ) libsrc/apple/joybuzz.a -$(DGR): libsrc/dgr.pla $(PLVM02) $(PLASM) - ./$(PLASM) -AMOW < libsrc/dgr.pla > libsrc/dgr.a - acme --setpc 4094 -o $(DGR) libsrc/dgr.a +$(PORTIO): libsrc/apple/portio.pla $(PLVM02) $(PLASM) + ./$(PLASM) -AMOW < libsrc/apple/portio.pla > libsrc/apple/portio.a + acme --setpc 4094 -o $(PORTIO) libsrc/apple/portio.a + +$(DGR): libsrc/apple/dgr.pla $(PLVM02) $(PLASM) + ./$(PLASM) -AMOW < libsrc/apple/dgr.pla > libsrc/apple/dgr.a + acme --setpc 4094 -o $(DGR) libsrc/apple/dgr.a $(DGRTEST): samplesrc/dgrtest.pla $(PLVM02) $(PLASM) ./$(PLASM) -AMOW < samplesrc/dgrtest.pla > samplesrc/dgrtest.a acme --setpc 4094 -o $(DGRTEST) samplesrc/dgrtest.a -$(ROGUE): samplesrc/rogue.pla $(PLVM02) $(PLASM) - ./$(PLASM) -AMOW < samplesrc/rogue.pla > samplesrc/rogue.a - acme --setpc 4094 -o $(ROGUE) samplesrc/rogue.a +$(MON): samplesrc/mon.pla $(PLVM02) $(PLASM) + ./$(PLASM) -AMOW < samplesrc/mon.pla > samplesrc/mon.a + acme --setpc 4094 -o $(MON) samplesrc/mon.a -$(ROGUECOMBAT): samplesrc/rogue.combat.pla $(PLVM02) $(PLASM) - ./$(PLASM) -AMOW < samplesrc/rogue.combat.pla > samplesrc/rogue.combat.a - acme --setpc 4094 -o $(ROGUECOMBAT) samplesrc/rogue.combat.a +$(SOS): libsrc/apple/sos.pla $(PLVM02) $(PLASM) + ./$(PLASM) -AMO < libsrc/apple/sos.pla > libsrc/apple/sos.a + acme --setpc 4094 -o $(SOS) libsrc/apple/sos.a -$(ROGUEMAP): samplesrc/rogue.map.pla $(PLVM02) $(PLASM) - ./$(PLASM) -AMOW < samplesrc/rogue.map.pla > samplesrc/rogue.map.a - acme --setpc 4094 -o $(ROGUEMAP) samplesrc/rogue.map.a - -hello: samplesrc/hello.pla $(PLVM) $(PLASM) - ./$(PLASM) -AMOW < samplesrc/hello.pla > samplesrc/hello.a - acme --setpc 4094 -o $(HELLO) samplesrc/hello.a - ./$(PLVM) HELLO diff --git a/src/mkrel b/src/mkrel index 8aabd61..687e882 100755 --- a/src/mkrel +++ b/src/mkrel @@ -1,68 +1,74 @@ -cp CMD#061000 prodos/CMD.BIN -cp PLASMA.SYSTEM#FF2000 prodos/PLASMA.SYSTEM.SYS -cp PLASMA16.SYSTEM#FF2000 prodos/PLASMA16.SYSTEM.SYS -cp SOS.INTERP#050000 prodos/SOS.INTERP.\$05 +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 ../doc/Editor.md prodos/EDITOR.README.TXT rm -rf prodos/sys mkdir prodos/sys -cp ARGS#FE1000 prodos/sys/ARGS.REL -cp CONIO#FE1000 prodos/sys/CONIO.REL -cp DGR#FE1000 prodos/sys/DGR.REL -cp DHCP#FE1000 prodos/sys/DHCP.REL -cp ED#FE1000 prodos/sys/ED.REL -cp ETHERIP#FE1000 prodos/sys/ETHERIP.REL -cp FIBER#FE1000 prodos/sys/FIBER.REL -cp FILEIO#FE1000 prodos/sys/FILEIO.REL -cp FPSTR#FE1000 prodos/sys/FPSTR.REL -cp FPU#FE1000 prodos/sys/FPU.REL -cp INET#FE1000 prodos/sys/INET.REL -cp LONGJMP#FE1000 prodos/sys/LONGJMP.REL -cp MEMMGR#FE1000 prodos/sys/MEMMGR.REL -cp PORTIO#FE1000 prodos/sys/PORTIO.REL -cp SANE#FE1000 prodos/sys/SANE.REL -cp SDFAT#FE1000 prodos/sys/SDFAT.REL -cp SPIPORT#FE1000 prodos/sys/SPIPORT.REL -cp SNDSEQ#FE1000 prodos/sys/SNDSEQ.REL -cp UTHERNET#FE1000 prodos/sys/UTHERNET.REL -cp UTHERNET2#FE1000 prodos/sys/UTHERNET2.REL -cp SOS#FE1000 prodos/sys/SOS.REL +cp rel/ARGS#FE1000 prodos/sys/ARGS.REL +cp rel/apple/CONIO#FE1000 prodos/sys/CONIO.REL +cp rel/apple/DGR#FE1000 prodos/sys/DGR.REL +cp rel/DHCP#FE1000 prodos/sys/DHCP.REL +cp rel/ED#FE1000 prodos/sys/ED.REL +cp rel/ETHERIP#FE1000 prodos/sys/ETHERIP.REL +cp rel/FIBER#FE1000 prodos/sys/FIBER.REL +cp rel/apple/FILEIO#FE1000 prodos/sys/FILEIO.REL +cp rel/FPSTR#FE1000 prodos/sys/FPSTR.REL +cp rel/FPU#FE1000 prodos/sys/FPU.REL +cp rel/INET#FE1000 prodos/sys/INET.REL +cp rel/LONGJMP#FE1000 prodos/sys/LONGJMP.REL +cp rel/MEMMGR#FE1000 prodos/sys/MEMMGR.REL +cp rel/apple/PORTIO#FE1000 prodos/sys/PORTIO.REL +cp rel/apple/JOYBUZZ#FE1000 prodos/sys/JOYBUZZ.REL +cp rel/SANE#FE1000 prodos/sys/SANE.REL +cp rel/apple/SDFAT#FE1000 prodos/sys/SDFAT.REL +cp rel/apple/SPIPORT#FE1000 prodos/sys/SPIPORT.REL +cp rel/apple/SNDSEQ#FE1000 prodos/sys/SNDSEQ.REL +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 ../sysfiles/FP6502.CODE#060000 prodos/sys/FP6502.CODE.BIN cp ../sysfiles/ELEMS.CODE#060000 prodos/sys/ELEMS.CODE.BIN rm -rf prodos/demos mkdir prodos/demos -cp DGRTEST#FE1000 prodos/demos/DGRTEST.REL -cp RPNCALC#FE1000 prodos/demos/RPNCALC.REL -cp ROD#FE1000 prodos/demos/ROD.REL +cp rel/apple/DGRTEST#FE1000 prodos/demos/DGRTEST.REL +cp rel/RPNCALC#FE1000 prodos/demos/RPNCALC.REL +cp rel/ROD#FE1000 prodos/demos/ROD.REL mkdir prodos/demos/rogue -cp ROGUE#FE1000 prodos/demos/rogue/ROGUE.REL -cp ROGUECOMBAT#FE1000 prodos/demos/rogue/ROGUECOMBAT.REL -cp ROGUEMAP#FE1000 prodos/demos/rogue/ROGUEMAP.REL +cp rel/ROGUE#FE1000 prodos/demos/rogue/ROGUE.REL +cp rel/ROGUECOMBAT#FE1000 prodos/demos/rogue/ROGUECOMBAT.REL +cp rel/ROGUEMAP#FE1000 prodos/demos/rogue/ROGUEMAP.REL cp samplesrc/LEVEL0#040000 prodos/demos/rogue/LEVEL0.TXT cp samplesrc/LEVEL1#040000 prodos/demos/rogue/LEVEL1.TXT mkdir prodos/demos/sdutils -cp FATCAT#FE1000 prodos/demos/sdutils/FATCAT.REL -cp FATGET#FE1000 prodos/demos/sdutils/FATGET.REL -cp FATPUT#FE1000 prodos/demos/sdutils/FATPUT.REL -cp FATREADDSK#FE1000 prodos/demos/sdutils/FATREADDSK.REL -cp FATWRITEDSK#FE1000 prodos/demos/sdutils/FATWRITEDSK.REL +cp rel/apple/FATCAT#FE1000 prodos/demos/sdutils/FATCAT.REL +cp rel/apple/FATGET#FE1000 prodos/demos/sdutils/FATGET.REL +cp rel/apple/FATPUT#FE1000 prodos/demos/sdutils/FATPUT.REL +cp rel/apple/FATREADDSK#FE1000 prodos/demos/sdutils/FATREADDSK.REL +cp rel/apple/FATWRITEDSK#FE1000 prodos/demos/sdutils/FATWRITEDSK.REL + +mkdir prodos/demos/apple3 +cp rel/apple/GFXDEMO#FE1000 prodos/demos/apple3/GFXDEMO.REL +cp samplesrc/APPLE3.PIX#060000 prodos/demos/apple3/APPLE3.PIX.BIN mkdir prodos/demos/net -cp HTTPD#FE1000 prodos/demos/net/HTTPD.REL +cp rel/HTTPD#FE1000 prodos/demos/net/HTTPD.REL cp samplesrc/index.html prodos/demos/net/INDEX.HTML.TXT mkdir prodos/demos/music -cp PLAYSEQ#FE1000 prodos/demos/music/PLAYSEQ.REL +cp rel/apple/PLAYSEQ#FE1000 prodos/demos/music/PLAYSEQ.REL cp mockingboard/ultima3.seq prodos/demos/music/ULTIMA3.SEQ.BIN cp mockingboard/startrek.seq prodos/demos/music/STARTREK.SEQ.BIN rm -rf prodos/bld mkdir prodos/bld -cp PLASM#FE1000 prodos/bld/PLASM.REL -cp CODEOPT#FE1000 prodos/bld/CODEOPT.REL +cp rel/PLASM#FE1000 prodos/bld/PLASM.REL +cp rel/CODEOPT#FE1000 prodos/bld/CODEOPT.REL cp samplesrc/dgrtest.pla prodos/bld/DGRTEST.PLA.TXT cp samplesrc/hello.pla prodos/bld/HELLO.PLA.TXT cp samplesrc/hgr1test.pla prodos/bld/HGR1TEST.PLA.TXT @@ -80,6 +86,7 @@ cp samplesrc/fatcat.pla prodos/bld/FATCAT.PLA.TXT cp samplesrc/rogue.pla prodos/bld/ROGUE.PLA.TXT cp samplesrc/rogue.map.pla prodos/bld/ROGUE.MAP.PLA.TXT cp samplesrc/rogue.combat.pla prodos/bld/ROGUE.COMBAT.PLA.TXT +cp samplesrc/gfxdemo.pla prodos/bld/GFXDEMO.PLA.TXT mkdir prodos/bld/inc cp inc/args.plh prodos/bld/inc/ARGS.PLH.TXT @@ -94,9 +101,11 @@ cp inc/inet.plh prodos/bld/inc/INET.PLH.TXT cp inc/longjmp.plh prodos/bld/inc/LONGJMP.PLH.TXT cp inc/memmgr.plh prodos/bld/inc/MEMMGR.PLH.TXT cp inc/sane.plh prodos/bld/inc/SANE.PLH.TXT +cp inc/joybuzz.plh prodos/bld/inc/JOYBUZZ.PLH.TXT cp inc/portio.plh prodos/bld/inc/PORTIO.PLH.TXT cp inc/sdfat.plh prodos/bld/inc/SDFAT.PLH.TXT cp inc/sndseq.plh prodos/bld/inc/SNDSEQ.PLH.TXT cp inc/spiport.plh prodos/bld/inc/SPIPORT.PLH.TXT cp inc/testlib.plh prodos/bld/inc/TESTLIB.PLH.TXT -cp vmsrc/plvmzp.inc prodos/bld/inc/PLVMZP.INC.TXT +cp inc/grafix.plh prodos/bld/inc/GRAFIX.PLH.TXT +cp vmsrc/apple/plvmzp.inc prodos/bld/inc/PLVMZP.INC.TXT diff --git a/src/samplesrc/APPLE3.PIX#060000 b/src/samplesrc/APPLE3.PIX#060000 new file mode 100644 index 0000000..23fee28 Binary files /dev/null and b/src/samplesrc/APPLE3.PIX#060000 differ diff --git a/src/samplesrc/examples/ex.1.pla b/src/samplesrc/examples/ex.1.pla new file mode 100644 index 0000000..a92a665 --- /dev/null +++ b/src/samplesrc/examples/ex.1.pla @@ -0,0 +1,14 @@ +// +// THE SIMPLE "HELLO, WORLD." PROGRAM! +// +// THIS IS A COMMENT, EVEYTHING IS +// IGNORED FOR THE REST OF THE LINE +// FOLLOWING "//" +// +// TO RUN, PRESS 'ESC', THEN "X" FROM +// COMMAND MODE. PRESS ANY KEY ONCE IT +// HAS SUCCESSFULLY COMPILED AND TOLD +// YOU HOW BIG THE RESULTANT PROGRAM IS. +// + +PUTS("HELLO, WORLD.") diff --git a/src/samplesrc/examples/ex.10.pla b/src/samplesrc/examples/ex.10.pla new file mode 100644 index 0000000..4d19745 --- /dev/null +++ b/src/samplesrc/examples/ex.10.pla @@ -0,0 +1,292 @@ +// RADAR SCOPE +// +// HERE IS ANOTHER LO-RES DEMO WITH +// A LITTLE MORE ON THE ALGORITHMIC +// SIDE OF THINGS. ON A IIGS, YOU WILL +// NEED TO ENABLE THE ALTERNATE DISPLAY +// OPTION IN THE CONTROL PANEL (ROM 01 +// ONLY). THIS PROGRAM COPIES THE PAGE1 +// LORES GRAPHICS TO THE PAGE2 FOR A +// FLICKER-FREE DISPLAY. +// +// NOTICE HOW SOME OF THE FUNCTIONS +// RETURN A VALUE THAT ISN'T USED. THIS +// IS CALLED "CASCADING THE RETURN". +// IN PLASMA, ALL FUNCTION DEFINITIONS +// RETURN A VALUE, EVEN IF IT ISN'T +// EXPLICITY SHOWN. A VALUE OF ZERO +// WILL BE SILENTLY ADDED IF NONE IS +// SPECIFIED. BY RETURNING A VALUE OF +// A FUNCTION OR SOFTSWITCH REFERENCE AT +// THE END OF THE DEFINTION IS A SLIGHT +// OPTIMIZATION IN THAT PLASMA WILL +// JUST PASS THE LAST VALUE BACK TO THE +// CALLER, WITHOUT DROPPING THE VALUE +// ON THE STACK AND PUSHING A ZERO BACK +// ON. +// + +CONST SHOWGR = $C050 +CONST SHOWFULL = $C052 +CONST SHOWPG1 = $C054 +CONST SHOWPG2 = $C055 +CONST SHOWLORES = $C056 +CONST RADIUS = 19 +CONST XORG = 19 +CONST YORG = 23 + +BYTE[RADIUS] OCTANT +BYTE NUMPOINTS + +DEF TEXTMODE + ^SHOWPG1 + RETURN CALL($FB39, 0, 0, 0, 0) +END + +DEF CPYBUF + RETURN MEMCPY($0800, $0400, 1024) +END + +DEF GRMODE + CALL($F832, 0, 0, 0, 0) + ^SHOWGR + ^SHOWFULL + CPYBUF + ^SHOWPG2 + RETURN ^SHOWLORES +END + +DEF COLOR(CLR) + RETURN CALL($F864, CLR, 0, 0, 0) +END + +DEF HLIN(LEFT, RIGHT, VERT) + ^$2C = RIGHT + RETURN CALL($F819, VERT, 0, LEFT, 0) +END + +DEF VLIN(TOP, BOTTOM, HORZ) + ^$2D = BOTTOM + RETURN CALL($F828, TOP, 0, HORZ, 0) +END + +// +// MODIFIED BRESENHAM TO DRAW SYMETRICAL +// SPANS FROM BOTH ENDS (DOUBLE SPEED) +// +DEF LINE(X1, Y1, X2, Y2) + BYTE DX, DY, DX2, DY2, PP, S + WORD SX, SY, ERR, DD2 + + IF X1 < X2 + SX = 1 + DX = X2 - X1 + ELSE + SX = -1 + DX = X1 - X2 + FIN + IF Y1 < Y2 + SY = 1 + DY = Y2 - Y1 + ELSE + SY = -1 + DY = Y1 - Y2 + FIN + DX2 = DX << 1 + DY2 = DY << 1 + IF DX >= DY + // + // HORIZONTAL LINE + // + IF SX < 0 + PP = X1 + X1 = X2 + X2 = PP + PP = Y1 + Y1 = Y2 + Y2 = PP + SY = -SY + FIN + DD2 = DX2 - DY2 + ERR = DX - DY2 + DY = (DY + 1) >> 1 + SX = 1 + WHILE DY + IF ERR < 0 + // + // DRAW TOP AND BOTTOM SPANS AT + // SAME TIME + // + IF Y2 - Y1 == SY + // + // THIS FIXES ANY OFF-BY-ONE + // PIXELS ON LAST REMAINING + // ADJACENT SPANS + // + HLIN(X1, X1 + SX - 1, Y1) + HLIN(X1 + SX, X2, Y2) + ELSE + HLIN(X1, X1 + SX - 1, Y1) + HLIN(X2 - SX + 1, X2, Y2) + FIN + X1 = X1 + SX + X2 = X2 - SX + Y1 = Y1 + SY + Y2 = Y2 - SY + DY = DY - 1 + SX = 1 + ERR = ERR + DD2 + ELSE + SX = SX + 1 + ERR = ERR - DY2 + FIN + LOOP + IF Y2 == Y1 + HLIN(X1, X2, Y2) + FIN + ELSE + // + // VERTICAL LINE + // + IF SY < 0 + PP = X1 + X1 = X2 + X2 = PP + PP = Y1 + Y1 = Y2 + Y2 = PP + SX = -SX + FIN + DD2 = DY2 - DX2 + ERR = DY - DX2 + DX = (DX + 1) >> 1 + SY = 1 + WHILE DX + IF ERR < 0 + // + // DRAW RIGHT AND LEFT SPANS + // AT THE SAME TIME + // + IF X2 - X1 == SX + // + // THIS FIXES ANY OFF-BY-ONE + // PIXELS ON LAST REMAINING + // ADJACENT SPANS + // + VLIN(Y1, Y1 + SY - 1, X1) + VLIN(Y1 + SY, Y2, X2) + ELSE + VLIN(Y1, Y1 + SY - 1, X1) + VLIN(Y2 - SY + 1, Y2, X2) + FIN + X1 = X1 + SX + X2 = X2 - SX + Y1 = Y1 + SY + Y2 = Y2 - SY + DX = DX - 1 + SY = 1 + ERR = ERR + DD2 + ELSE + SY = SY + 1 + ERR = ERR - DX2 + FIN + LOOP + IF X2 == X1 + VLIN(Y1, Y2, X2) + FIN + FIN +END + +DEF RADAR(C) + BYTE I + + FOR I = 1 TO NUMPOINTS + COLOR(C) + LINE(XORG, YORG, XORG + I, YORG - OCTANT[I]) + CPYBUF + COLOR(0) + LINE(XORG, YORG, XORG + I, YORG - OCTANT[I]) + NEXT + FOR I = NUMPOINTS - 1 DOWNTO 0 + COLOR(C) + LINE(XORG, YORG, XORG + OCTANT[I], YORG - I) + CPYBUF + COLOR(0) + LINE(XORG, YORG, XORG + OCTANT[I], YORG - I) + NEXT + FOR I = 1 TO NUMPOINTS + COLOR(C) + LINE(XORG, YORG, XORG + OCTANT[I], YORG + I) + CPYBUF + COLOR(0) + LINE(XORG, YORG, XORG + OCTANT[I], YORG + I) + NEXT + FOR I = NUMPOINTS - 1 DOWNTO 0 + COLOR(C) + LINE(XORG, YORG, XORG + I, YORG + OCTANT[I]) + CPYBUF + COLOR(0) + LINE(XORG, YORG, XORG + I, YORG + OCTANT[I]) + NEXT + FOR I = 1 TO NUMPOINTS + COLOR(C) + LINE(XORG, YORG, XORG - I, YORG + OCTANT[I]) + CPYBUF + COLOR(0) + LINE(XORG, YORG, XORG - I, YORG + OCTANT[I]) + NEXT + FOR I = NUMPOINTS - 1 DOWNTO 0 + COLOR(C) + LINE(XORG, YORG, XORG - OCTANT[I], YORG + I) + CPYBUF + COLOR(0) + LINE(XORG, YORG, XORG - OCTANT[I], YORG + I) + NEXT + FOR I = 1 TO NUMPOINTS + COLOR(C) + LINE(XORG, YORG, XORG - OCTANT[I], YORG - I) + CPYBUF + COLOR(0) + LINE(XORG, YORG, XORG - OCTANT[I], YORG - I) + NEXT + FOR I = NUMPOINTS - 1 DOWNTO 0 + COLOR(C) + LINE(XORG, YORG, XORG - I, YORG - OCTANT[I]) + CPYBUF + COLOR(0) + LINE(XORG, YORG, XORG - I, YORG - OCTANT[I]) + NEXT +END + +// +// USE BRESENHAM CIRCLE ALG TO CALC +// FIRST OCTANT +// +DEF CIRCALC + BYTE X, Y + WORD ERR + + X = 0 + Y = RADIUS + ERR = 3 - (RADIUS << 1) + WHILE X <= Y + IF ERR <= 0 + ERR = ERR + (X << 2) + 6 + ELSE + ERR = ERR + ((X - Y) << 2) + 10 + Y = Y - 1 + FIN + OCTANT[X] = Y + X = X + 1 + LOOP + NUMPOINTS = X - 1 +END + +CIRCALC +GRMODE +REPEAT + RADAR(15) +UNTIL ^$C000 > 127 +^$C010 +TEXTMODE +DONE diff --git a/src/samplesrc/examples/ex.11.pla b/src/samplesrc/examples/ex.11.pla new file mode 100644 index 0000000..fbf2637 --- /dev/null +++ b/src/samplesrc/examples/ex.11.pla @@ -0,0 +1,245 @@ +CONST FALSE = 0 +CONST TRUE = 1 +// +// HERE IS AN INTERACTIVE EXAMPLE. +// +// SET AUTOPLAY TO FALSE TO USE THE +// PADDLE CONTROL AND PLAY YOURSELF. +// + +BYTE AUTOPLAY = TRUE + +// +// THE BUILT-IN FUNCTION CALL() +// RETURNS A STRUCTURE THAT CAN BE +// USED TO READ THE REGISTER RESULTS. +// CHECK OUT THE PADDLE() FUNCTION. +// +STRUC S_CALL + BYTE AREG + BYTE XREG + BYTE YREG + BYTE FLAGS +END + +CONST SHOWLORES = $C056 +CONST KEYBOARD = $C000 +CONST KEYSTROBE = $C010 +CONST SPEAKER = $C030 +BYTE PDLPOS, PDLSIZE, PDLMID, MISS +BYTE XSCRN, YSCRN +BYTE[3] SCORE +WORD XBALL, YBALL, XSPEED, YSPEED +PREDEF INCSCORE + +DEF BEEP(TONE, DURATION) + BYTE I, J + + FOR J = DURATION DOWNTO 0 + FOR I = TONE DOWNTO 0 + NEXT + ^SPEAKER + NEXT +END + +DEF KEYPRESSED + RETURN ^KEYBOARD > 127 +END + +DEF GETKEY + BYTE KEY + + REPEAT + KEY = ^KEYBOARD + UNTIL KEY > 127 + ^KEYSTROBE + RETURN KEY +END + +DEF TEXTMODE + CALL($FB39, 0, 0, 0, 0) + RETURN HOME +END + +DEF PUTSXY(X, Y, STRPTR) + GOTOXY(X, Y) + RETURN PUTS(STRPTR) +END + +DEF GRMODE + CALL($FB40, 0, 0, 0, 0) + ^SHOWLORES + RETURN HOME +END + +DEF COLOR(CLR) + RETURN CALL($F864, CLR, 0, 0, 0) +END + +DEF PLOT(X, Y) + RETURN CALL($F800, Y, 0, X, 0) +END + +DEF HLIN(LEFT, RIGHT, VERT) + ^($2C) = RIGHT + RETURN CALL($F819, VERT, 0, LEFT, 0) +END + +DEF VLIN(TOP, BOTTOM, HORZ) + ^($2D) = BOTTOM + RETURN CALL($F828, TOP, 0, HORZ, 0) +END + +DEF PADDLE(NUM) + RETURN CALL($FB1E, 0, NUM, 0, 0)->YREG +END + +DEF BUTTON(NUM) + RETURN ^($C060 + NUM) > 127 +END + +DEF UPDTPDL + IF AUTOPLAY + IF PDLPOS + PDLMID > XSCRN + IF PDLPOS > 0 + PDLPOS = PDLPOS - 1 + FIN + ELSIF PDLPOS + PDLMID + 1 < XSCRN + IF PDLPOS + PDLSIZE < 39 + PDLPOS = PDLPOS + 1 + FIN + FIN + ELSE + PDLPOS = PADDLE(0) / 5 + FIN + IF PDLPOS + PDLSIZE > 39 + PDLPOS = 39 - PDLSIZE + FIN + IF PDLPOS + COLOR(0) + HLIN(0, PDLPOS - 1, 39) + FIN + COLOR(1) + HLIN(PDLPOS, PDLPOS + PDLSIZE, 39) + IF PDLPOS + PDLSIZE < 38 + COLOR(0) + HLIN(PDLPOS + PDLSIZE + 1, 39, 39) + FIN +END + +DEF UPDTBALL + BYTE XNEW, YNEW + + // + // UPDATE HORIZONTAL POSITION + // + XBALL = XBALL + XSPEED + IF XBALL > 623 + XBALL = 623 + XSPEED = -XSPEED + BEEP(4, 10) + ELSIF XBALL < 16 + XBALL = 16 + XSPEED = -XSPEED + BEEP(4, 10) + FIN + XNEW = XBALL >> 4 + // + // UPDATE VERTICAL POSITION + // + YBALL = YBALL + YSPEED + IF YBALL > 623 + // + // CHECK FOR PADDLE HIT + // + IF XNEW >= PDLPOS AND XNEW <= PDLPOS + PDLSIZE + YBALL = 623 + YSPEED = -YSPEED - 2 + XSPEED = XSPEED + (XNEW - (PDLPOS + PDLMID - 1)) + IF XSPEED == 0 + IF PDLPOS + PDLMID > 19 + XSPEED = 1 + ELSE + XSPEED = -1 + FIN + FIN + INCSCORE + BEEP(4, 10) + ELSE + MISS = 1 + BEEP(14, 40) + FIN + ELSIF YBALL < 16 + YBALL = 16 + YSPEED = -YSPEED + BEEP(4, 10) + FIN + YNEW = YBALL >> 4 + // + // UPDATE ON-SCREEN BALL + // + IF XNEW <> XSCRN OR YNEW <> YSCRN + COLOR(8) + PLOT(XNEW, YNEW) + COLOR(0) + PLOT(XSCRN, YSCRN) + XSCRN = XNEW + YSCRN = YNEW + FIN +END + +DEF PUTSCORE + PUTC(SCORE[2]) + PUTC(SCORE[1]) + PUTC(SCORE[0]) +END + +DEF INCSCORE + SCORE[0] = SCORE[0] + 1 + IF SCORE[0] > '9' + SCORE[0] = '0' + SCORE[1] = SCORE[1] + 1 + IF SCORE[1] > '9' + SCORE[1] = '0' + SCORE[2] = SCORE[2] + 1 + FIN + FIN + GOTOXY(17, 2) + PUTSCORE +END + +DEF INITSCORE + SCORE[0] = '0' + SCORE[1] = '0' + SCORE[2] = '0' + GOTOXY(17, 2) + PUTSCORE +END + +PUTS("1=HARD 2=MED 3=EASY ?") +PDLSIZE = (GETKEY - $B0) * 3 +PDLMID = PDLSIZE >> 1 +GRMODE +COLOR(15) +HLIN(0, 39, 0) +VLIN(1, 38, 0) +VLIN(1, 38, 39) +XBALL = PADDLE(0) + 16 +YBALL = PADDLE(1) + 16 +XSCRN = XBALL >> 4 +YSCRN = YBALL >> 4 +XSPEED = 1 +YSPEED = 1 +MISS = 0 +INITSCORE +REPEAT + UPDTPDL + UPDTBALL +UNTIL KEYPRESSED OR MISS +TEXTMODE +HOME +PUTS("YOUR SCORE WAS ") +PUTSCORE +PUTC($0D) +PUTS("THAT'S ALL FOLKS!") +DONE diff --git a/src/samplesrc/examples/ex.12.pla b/src/samplesrc/examples/ex.12.pla new file mode 100644 index 0000000..59c6bba --- /dev/null +++ b/src/samplesrc/examples/ex.12.pla @@ -0,0 +1,189 @@ +// +// This is a simple combat simulator +// +// Many of the different structure, +// address, an pointer operations are +// demonstrated. A few of the many +// flow control constructs are shown, +// including loops, tests, and function +// calls. +// +// A note about in-line strings. When a +// string is encountered in-line, space +// is allocated on the fly for the string +// in memory. PLASMA doesn't have garbage +// collection, so that memory adds up +// until the function exits (or the +// proram ends in the main function). +// If you use strings inside a loop, you +// may overflow memory. Try moving the +// string outside the loop, or into +// initialized memory. +// +const rndnum = $4E // ZP location of RND +const rndl = $4E +const rndh = $4F + +struc t_player + byte name[32] + word morality + byte health + byte stamina + byte strength + byte skill +end + +byte[32] player = "Player" +word = 0 // morality +byte = 0 // health +byte = 10 // stamina +byte = 50 // strength +byte = 20 // skill + +struc t_actor + byte kind + byte life + byte power + word ethics + word next_actor +end + +byte preacher = "Preacher", 200 +byte zombie = "Zombie", 0 +byte cowboy = "Cowboy", 129 +byte clerk = "Clerk", 128 +byte merchant = "Merchant", 192 +byte rustler = "Rustler", 60 +byte traveler = "Traveler", 132 +byte rogue = "Rogue", 30 + +// +// Notice how the array is initialized +// with the addresses of prior records. +// +word actors = @preacher, @zombie, @cowboy +word = @clerk, @merchant, @rustler +word = @traveler, @rogue, 0 + +byte fightstr = "F)ight or R)un?" +byte whostr = "Whom do you want to fight (0=quit)?" +byte numactors +word choice + +def rnd + *rndnum = (*rndnum << 1) + *rndnum + 251 + return *rndnum & $7FFF +end + +// +// Apple //e and //c computers can input +// lower-case, so convert all input into +// upper-case for easier testing. +// +def toupper(c) + if c >= 'a' and c <= 'z' + c = c - ('a' - 'A') + fin + return c +end + +def putstats(other) + home() + gotoxy(0, 0) + puts(@player.name) + if player.health == 0 + puts(" Died!") + fin + gotoxy(1, 1) + puts("Morality:"); puti(player:morality) + gotoxy(1, 2) + puts("Skill :"); puti(player.skill) + gotoxy(1, 3) + puts("Stamina :"); puti(player.stamina) + gotoxy(1, 4) + puts("Strength:"); puti(player.strength) + gotoxy(1, 5) + puts("Health :"); puti(player.health) + + gotoxy(20, 0) + puts(actors[other->kind]) + if other->life == 0 + puts("Died!") + fin + gotoxy(21, 1) + puts("Ethics :"); puti(other=>ethics) + gotoxy(21, 2) + puts("Power :"); puti(other->power) + gotoxy(21, 3) + puts("Life :"); puti(other->life) +end + +def fight(who) + byte[t_actor] enemy + byte quit + word p_atck, e_atck + + enemy.kind = who + enemy:ethics = ^(actors[who] + ^(actors[who]) + 1) - 128 + enemy.power = 64 + (rnd & 191) + enemy.life = 128 + (rnd & 127) + + quit = 0 + repeat + putstats(@enemy) + gotoxy(12, 8); puts(@fightstr) + if toupper(getc()) == 'F' + p_atck = player.skill * player.strength / enemy.power + p_atck = p_atck + (rnd() & 15) + if enemy.life > p_atck + enemy.life = enemy.life - p_atck + else + player:morality = player:morality - enemy:ethics + enemy.life = 0 + p_atck = player.skill + enemy.power / 10 + if p_atck > 255 // Limit skill + p_atck = 255 + fin + player.skill = p_atck + quit = 1 + fin + e_atck = enemy.power / player.stamina + e_atck = e_atck + (rnd() & 15) + if player.health > e_atck + player.health = player.health - e_atck + else + player.health = 0 + quit = 1 + fin + else + quit = 1 + fin + until quit + putstats(@enemy) +end + +// +// This is the main loop. Know when to +// walk away, know when to run. +// +home() +repeat + player.health = 192 + (rnd & 63) + numactors = 0 + repeat + gotoxy(10, 10 + numactors) + puti(numactors + 1); putc(' ') + puts(actors[numactors]) + numactors = numactors + 1 + until not actors[numactors] + gotoxy(2, 11 + numactors) + puts(@whostr) + choice = getc() - '0' + if choice > 0 and choice <= numactors + fight(choice - 1) + elsif choice == 0 + player.health = 0 + fin +until player.health == 0 +gotoxy(0, 21); puts("That's all, folks!") +done diff --git a/src/samplesrc/examples/ex.13.pla b/src/samplesrc/examples/ex.13.pla new file mode 100644 index 0000000..9af1caa --- /dev/null +++ b/src/samplesrc/examples/ex.13.pla @@ -0,0 +1,59 @@ +// +// SIEVE OF ERATOSTHENESE +// +// PRIME NUMBER FINDER SHOWING OFF SOME +// OF PLASMA'S BIT MANIPULATION +// OPERATIONS. +// +// THE APPLE ][ CANNOT DISPLAY THE +// TWO SYMBOLS USED FOR BIT COMPLIMENT +// AND INCLUSIVE OR: THE TILDE AND THE +// BAR. SO ALIASES FOR THESE OPERATORS +// ARE: +// +// ~ : BITWISE COMPLIMENT (CTRL-Y) +// | : BITWISE INCLUSIVE OR (CTRL-B) +// +// ON THE APPLE ][, THESE SHOW UP AS AN +// INVERTED ^ AND AN INVERTED \. +// +// IN THIS EXAMPLE, AN ARRAY IS USED TO +// HOLD THE FLAGS USED TO IDENTIFY NON- +// PRIME VALUES. THIS IS MORE MEMORY +// EFFICIENT THAN USING A WHOLE BYTE FOR +// EACH FLAG, BUT REQUIRES BITWISE TESTS +// FOR ONE OF THE EIGHT FLAGS IN EACH +// BYTE. SHIFTING RIGHT IS A FAST WAY +// TO DIVIDE BY POWERS OF TWO: +// X >> 3 IS THE SAME AS X / 8 +// SHIFTING LEFT IS A FAST WAY TO +// MULTIPLY BY POWERS OF TWO: +// X << 2 IS THE SAME AS X * 4 +// + +CONST FALSE = 0 +CONST TRUE = NOT FALSE +CONST IMAX = 8192 +CONST IMAXM1 = IMAX-1 +CONST SIZEF = IMAX/8 +CONST CR = $0D + +BYTE[SIZEF] FLAGS +WORD PRIME, I, K, COUNT = 0 + +MEMSET(@FLAGS, 0, SIZEF) +FOR I = 0 TO IMAXM1 + IF NOT (FLAGS[I >> 3] & (1 << (I&7))) + PRIME = I + I + 3 + FOR K = PRIME + I TO IMAXM1 STEP PRIME + FLAGS[K >> 3] = FLAGS[K >> 3] | (1 << (K&7)) + NEXT + COUNT = COUNT + 1 + PUTI(PRIME) + PUTC(CR) + FIN +NEXT +PUTI(COUNT) +PUTS(" PRIMES BETWEEN 0 AND ") +PUTI(IMAX << 1) +DONE diff --git a/src/samplesrc/examples/ex.14.pla b/src/samplesrc/examples/ex.14.pla new file mode 100644 index 0000000..30db369 --- /dev/null +++ b/src/samplesrc/examples/ex.14.pla @@ -0,0 +1,111 @@ +// PRODOS +// +// I HOPE YOUR INTRODUCTION TO PLASMA +// HAS INSPIRED YOU TO PLAY AROUND WITH +// PROGRAMMING YOUR APPLE II. +// +// THIS NEXT EXAMPLE SHOWS HOW TO CALL +// PRODOS TO DISPLAY A CATALOG. YOU MAY +// WANT TO CONSULT THE PRODOS TECH REF +// TO UNDERSTAND ALL THE PARAMETERS AND +// STRUCTURE OFFSETS. +// + +BYTE PERR = 0 +BYTE[512] DATABUFF + +DEF GETPFX(PATH) + BYTE[3] PARAMS + + ^PATH = 0 + PARAMS.0 = 1 + PARAMS:1 = PATH + PERR = SYSCALL($C7, @PARAMS) + RETURN PATH +END + +DEF OPEN(PATH, IOBUFF) + BYTE[6] PARAMS + + PARAMS.0 = 3 + PARAMS:1 = PATH + PARAMS:3 = IOBUFF + PARAMS.5 = 0 + SYSCALL($C8, @PARAMS) + RETURN PARAMS.5 +END + +DEF READ(REFNUM, BUFF, LEN) + BYTE[8] PARAMS + + PARAMS.0 = 4 + PARAMS.1 = REFNUM + PARAMS:2 = BUFF + PARAMS:4 = LEN + PARAMS:6 = 0 + PERR = SYSCALL($CA, @PARAMS) + RETURN PARAMS:6 +END + +DEF CLOSE(REFNUM) + BYTE[2] PARAMS + + PARAMS.0 = 1 + PARAMS.1 = REFNUM + PERR = SYSCALL($CC, @PARAMS) + RETURN PERR +END + +DEF CATALOG + BYTE[64] PATH + BYTE REFNUM + BYTE FIRSTBLK + BYTE ENTRYLEN, ENTRIESBLK + BYTE I, TYPE, LEN + WORD ENTRY, FILECNT + + GETPFX(@PATH) + PUTS(@PATH) + PUTC($0D) + REFNUM = OPEN(@PATH, $0800) // SAFE IO BUFFER LOCATION + IF PERR; RETURN PERR; FIN + FIRSTBLK = 1 // FIRST BLOCK IS TREATED SPECIAL + REPEAT + IF READ(REFNUM, @DATABUFF, 512) == 512 + ENTRY = @DATABUFF.$04 + 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 + PUTS(ENTRY) + IF ENTRY->$10 == $D0 // IS IT A DIRECTORY? + PUTC('/') + LEN = LEN + 1 + ELSIF ENTRY->$10 == $FF // IS IT A SYSTEM FILE? + PUTC('*') + LEN = LEN + 1 + FIN + FOR LEN = 19 - LEN DOWNTO 0 + PUTC(' ') + NEXT + FILECNT = FILECNT - 1 + FIN + ENTRY = ENTRY + ENTRYLEN + NEXT + FIRSTBLK = 0 // DONE WITH FIRST BLOCK + ELSE + FILECNT = 0 + FIN + UNTIL FILECNT == 0 + RETURN CLOSE(REFNUM) +END + +CATALOG() +DONE diff --git a/src/samplesrc/examples/ex.15.pla b/src/samplesrc/examples/ex.15.pla new file mode 100644 index 0000000..09e5fd7 --- /dev/null +++ b/src/samplesrc/examples/ex.15.pla @@ -0,0 +1,30 @@ +// +// THIS EXAMPLE SHOWS HOW TO CALL +// MACHINE CODE INSIDE YOUR PLASMA +// CODE. THIS MACHINE CODE IS EMBEDDED +// INSIDE THE DATA AND MUST BE POSITION +// INDEPENDENT. FUNCTIONS ARE EXPECTED +// TO RETURN A VALUE ON THE PLASMA +// EVALUATION STACK, INDEXED BY THE +// X-REGISTER. IT MUST BE CONSISTENT: +// INX FOR EVERY ARGUMENT, DEX FOR THE +// RETURN VALUE. THE ACTUAL VALUES ARE +// LOCATED IN ZERO PAGE: +// +// $C0,X = EVAL STACK LO BYTE +// $D0,X = EVAL STACK HI BYTE +// +// IF THE RETURN VALUE IS TO BE IGNORED, +// YOU CAN SKIP THE ACTUAL SETTING OF THE +// EVAL STACK AND JUST UPDATE THE X-REG. +// +BYTE CLICK = $AD, $30, $C0 // LDA $C030 +BYTE = $CA // DEX +BYTE = $60 // RTS + +BYTE I + +FOR I=0 TO 200 + (@CLICK)() +NEXT +DONE diff --git a/src/samplesrc/examples/ex.16.pla b/src/samplesrc/examples/ex.16.pla new file mode 100644 index 0000000..f68c927 --- /dev/null +++ b/src/samplesrc/examples/ex.16.pla @@ -0,0 +1,159 @@ +// +// Check github for fully commented code +// +const MAX_FIBERS = 3 +const MAX_FIBER = MAX_FIBERS-1 +const FIBER_UNAVAIL = 0 +const FIBER_FREE = 1 +const FIBER_HALT = 2 +const FIBER_RUN = 3 +byte fbrState[MAX_FIBERS] +word fbrVMState[MAX_FIBERS] +byte fbrNext[MAX_FIBERS] = 0 +byte fbrRunning = 0 +struc t_vm + byte estklo[$10] + byte estkhi[$10] + byte esp + word ifp + word pp + byte hwsp + byte fill[9] + byte drop + byte nextop[$10] + byte frame[$40] + byte hwstk[$80] +end +word fbrPool[t_vm*MAX_FIBERS] + +byte fbrSwap = $B5 +byte = $C0,$85,$06,$B5,$D0,$85,$07,$E8 +byte = $B5,$C0,$85,$08,$B5,$D0,$85,$09 +byte = $86,$E0,$BA,$86,$E5,$A0,$26,$B9 +byte = $C0,$00,$91,$08,$B1,$06,$99,$C0 +byte = $00,$88,$10,$F3,$8A,$A8,$B9,$00 +byte = $01,$91,$08,$C8,$D0,$F8,$A4,$E5 +byte = $B1,$06,$99,$00,$01,$C8,$D0,$F8 +byte = $A6,$E5,$9A,$A6,$E0,$60 + +byte fbrLoad = $B5,$C0 +byte = $85,$06,$B5,$D0,$85,$07,$A0,$26 +byte = $B1,$06,$99,$C0,$00,$88,$10,$F8 +byte = $A4,$E5,$B1,$06,$99,$00,$01,$C8 +byte = $D0,$F8,$A6,$E5,$9A,$A6,$E0,$60 + +def fbrInit + byte i + word pool + + pool = @fbrPool + t_vm + for i = MAX_FIBER downto 1 + fbrState[i] = FIBER_FREE + fbrVMState[i] = pool + pool = pool + t_vm + next + fbrState = FIBER_RUN + fbrVMState = @fbrPool +end +def fbrStop(fid) + byte i + + if fid + fbrState[fid] = FIBER_FREE + i = 0 + while fbrNext[i] <> fid + i = fbrNext[i] + loop + fbrNext[i] = fbrNext[fid] + if fid == fbrRunning + fbrRunning = fbrNext[fbrRunning] + return (@fbrLoad)(fbrVMState[fbrRunning]) + fin + fin +end +def fbrExit + fbrStop(fbrRunning) +end +def fbrStart(defaddr, param) + byte i + word vmstate + + for i = MAX_FIBER downto 1 + if fbrState[i] == FIBER_FREE + fbrState[i] = FIBER_RUN + vmstate = fbrVMState[i] + vmstate=>ifp = vmstate + hwstk + vmstate=>pp = vmstate + hwstk + vmstate->esp = $0E + vmstate->estklo.$0F = i + vmstate->estkhi.$0F = 0 + vmstate->estklo.$0E = param.0 // param lo byte + vmstate->estkhi.$0E = param.1 // param hi byte + vmstate->hwsp = $FB + vmstate=>$FE = @fbrExit - 1 + vmstate=>$FC = defaddr - 1 + fbrNext[i] = fbrNext[fbrRunning] + fbrNext[fbrRunning] = i + return i + fin + next +end +def fbrYield + byte prev + + if fbrNext[fbrRunning] <> fbrRunning + prev = fbrRunning + fbrRunning = fbrNext[fbrRunning] + return (@fbrSwap)(fbrVMState[prev], fbrVMState[fbrRunning]) + fin +end +def fbrHalt + byte i + + if fbrRunning + i = 0 + while fbrNext[i] <> fbrRunning + i = fbrNext[i] + loop + fbrState[fbrRunning] = FIBER_HALT + fbrNext[i] = fbrNext[fbrRunning] + i = fbrRunning + fbrRunning = fbrNext[fbrRunning] + return (@fbrSwap)(fbrVMState[i], fbrVMState[fbrRunning]) + fin +end +def fbrResume(fid) + if fbrState[fid] == FIBER_HALT + fbrState[fid] = FIBER_RUN + fbrNext[fid] = fbrNext[fbrRunning] + fbrNext[fbrRunning] = fid + fin +end +// +// Test Fibers +// +def fbrTest(fid, param) + byte x + word i + + i = 1 + x = fid * 8 + while 1 + gotoxy(x, fid) + puts(param) + x = x + i + if x < 1 or x > 32 + i = -i + fin + fbrYield + loop +end + +fbrInit +fbrStart(@fbrTest, " World ") +fbrStart(@fbrTest, " Hello ") +while ^$C000 < 128 + fbrYield +loop +^$C010 +done diff --git a/src/samplesrc/examples/ex.17.pla b/src/samplesrc/examples/ex.17.pla new file mode 100644 index 0000000..a640382 --- /dev/null +++ b/src/samplesrc/examples/ex.17.pla @@ -0,0 +1,55 @@ +// +// GAME PORT I/O LIBRARY +// BASED ON THE WIRING LIBRARY +// +CONST ANN0 = $C058 +CONST ANN1 = $C05A +CONST ANN2 = $C05C +CONST ANN3 = $C05E +CONST OFF = 0 +CONST ON = 1 +CONST STROBE = $C040 +CONST FLAG0 = $C060 +CONST FLAG1 = $C061 +CONST FLAG2 = $C062 +CONST FLAG3 = $C063 +CONST PREAD = $FB1E +CONST WAIT = $FCA8 + +DEF DIGITALREAD(PIN) + RETURN FLAG0[PIN&3] > 127 +END + +DEF PORTREAD + RETURN (^FLAG0>>7)&1|(^FLAG1>>6)&2|(^FLAG2>>5)&4|(^FLAG3>>4)&8 +END + +DEF DIGITALWRITE(PIN, VAL) + RETURN ^ANN0[((PIN&3)<<1)+VAL&1] +END + +DEF PORTWRITE(VAL) + ^ANN0[VAL&1] + ^ANN1[(VAL>>1)&1] + ^ANN2[(VAL>>2)&1] + RETURN ^ANN3[(VAL>>3)&1] +END + +DEF ANALOGREAD(PIN) + RETURN CALL(PREAD,0,PIN&3,0,0).2 +END + +DEF DELAY(TIME) + RETURN CALL(WAIT,TIME,0,0,0) +END + +// +// OUTPUT THE ANALOG INPUT TO +// THE DIGITAL PORT +// +WHILE ^$C000 < 128 + PORTWRITE((255 - ANALOGREAD(2)) / 16) +LOOP +^$C010 + +DONE diff --git a/src/samplesrc/examples/ex.2.pla b/src/samplesrc/examples/ex.2.pla new file mode 100644 index 0000000..1d04962 --- /dev/null +++ b/src/samplesrc/examples/ex.2.pla @@ -0,0 +1,92 @@ +// +// PLASMA UNDERSTANDS TWO TYPES OF DATA: +// BYTES (UNSIGNED 8 BIT VALUES), AND +// WORDS (SIGNED 16 BIT VALUES). FROM +// THESE TWO TYPES, EVERYTHING MUST BE +// BUILT. BUT, PLASMA HELPS OUT WITH +// DEFINING DATA, INCLUDING ARRAYS, +// STRUCTURES, STRINGS, AND POINTERS. +// YOU'VE ALREADY SEEN A STRING IN THE +// FIRST EXAMPLE. HERE ARE SOME MORE... +// + +BYTE[16] FILENAME // RESERVES 16 BYTES + +// +// THE FOLLOWING RESERVES A MINUMUM +// AMOUNT OF SPACE FOR A STRING, PLUS +// IT INITIALIZES IT WITH A VALUE. +// + +BYTE[32] PREFIX = "/EXAMPLES" + +// +// ARRAY DEFINITIONS WITH NO SIZE DON'T +// RESERVE ANY SPACE, BUT ARE USEFUL FOR +// LABELS. ARRAY DEFINITIONS WITHOUT A +// NAMED VARIABLE JUST INITIALIZE THE +// MEMORY WITH VALUES. +// + +BYTE[] ALIAS // ALIAS HAS SAME +WORD MYVAR = 1 // ADDRESS AS MYVAR +WORD = 2, 3, 4// BUT DIFFERENT TYPE + +// +// PLASMA ALLOWS FLEXIBLE ARRAY SYNTAX, +// MORE TRADITIONAL ARRAYS LOOK LIKE: +// + +WORD MYARRAY[2] // PICK ONE STYLE AND + // STICK WITH IT + +// +// PLASMA ALSO HELPS OUT WITH CONSTANTS +// THAT CAN BE GIVEN A NAME TO MAKE THE +// CODE MORE READABLE. +// + +CONST SPEAKER = $C030 // HEX VALUES START WITH '$' + +// +// OF COURSE PLASMA HAS LOOPING +// CONSTRUCTS INCLUDING FOR/NEXT, +// REPEAT/UNTIL, WHILE/LOOP. +// +// THE FOR/NEXT IS THE MOST FLEXIBLE, +// TAKING THE EXPANDED FORM OF: +// +// FOR VAR = LO TO HI STEP INC +// +// FOR VAR = HI DOWNTO LO STEP DEC +// + +FOR MYVAR = 0 TO 1000 + ^SPEAKER // ACCESS SPEAKER TO MAKE NOISE +NEXT + +// +// HERE IS THE SAME THING USING A WHILE +// LOOP AND THE INCREMENT STATEMENT. THE +// TONE IS SLIGHTLY LOWER THAN ABOVE DUE +// TO THE 'WHILE' EXECUTING SLIGHTLY +// SLOWER THAN THE 'FOR' LOOP. +// + +MYVAR = 0 +WHILE MYVAR <= 1000 + ^SPEAKER + MYVAR++ // INCREMENT VARIABLE +LOOP + +// +// AND TO BE THOROUGH, PLASMA PROGRAMS +// SHOULD END WITH A "DONE" SO THE +// COMPILER KNOWS WHEN TO STOP. ANYTHING +// FOLLOWING "DONE" IS IGNORED. +// + +DONE + +THIS CAN BE HANDY TO HAVE ARBITRARY TEXT +FOLLOWING THE PROGRAM CODE. diff --git a/src/samplesrc/examples/ex.3.pla b/src/samplesrc/examples/ex.3.pla new file mode 100644 index 0000000..92fdd21 --- /dev/null +++ b/src/samplesrc/examples/ex.3.pla @@ -0,0 +1,83 @@ +// +// THE PLASMA SANDBOX CAN'T LOAD +// MODULES LIKE THE FULL VERSION, BUT +// IT HAS SOME BUILT-IN FUNCTIONS THAT +// ALLOW EXTENSIVE ACCESS TO THE APPLE'S +// HARDWARE AND SOFTWARE ENVIRONMENT. +// OTHERS ARE JUST CONVENIENT OR ADD +// PERFORMANCE WHERE PLASMA MAY BE TOO +// SLOW +// + +CONST TEXTSCREEN = $0400 +CONST SCREENSIZE = 1024 + +BYTE[SCREENSIZE] SAVETXT +BYTE I +WORD NAME + +// +// BUILT-IN FUNTIONS: +// +// SYSCALL(CMD,PARAMS) : CALL PRODOS +// CALL(ADDR,AREG,XREG,YREG,PSP) : CALL 6502 ROUTINE WITH REG VALUES +// MEMSET(DSTADDR, VALUE, SIZE) : FILL DSTADDR TO DSTADDR + SIZE WITH VALUE +// MEMCPY(DSTADDR, SRCADDR, SIZE) : COPY SRCADDR TO DSTADDR, SIZE BYTES +// PUTC(CHAR) : PRINT CHAR +// GETC() : READ CHAR FROM KEYBOARD +// PUTI(NUM) : PRINT INTEGER NUMBER +// PUTS(ADDR) : PRINT STRING AT ADDR +// GETS(CHAR) : READ STRING FROM KEYBOARD, PROMPTING WITH CHAR +// HOME() : CLEAR SCREEN AND HOME CURSOR +// GOTOXY(X,Y) : SET CURSOR TO X,Y +// + +// +// SAVE THE TEXT SCREEN IN A BIG (1024) ARRAY +// +MEMCPY(@SAVETXT, TEXTSCREEN, SCREENSIZE) // SAVE TEXT SCREEN + +// +// CLEAR SCREEN, HOME CURSOR. FOR +// FUNCTIONS WITHOUT PARAMETERS, THE +// "()" ARE OPTIONAL, BUT HELP CLARIFY +// THE FUNCTION CALL IS NOT A VARIABLE +// REFERENCE: HOME VS HOME() +// +HOME() + +FOR I = 0 TO 23 + // + // MOVE CURSOR TO POSITION X, Y + // + GOTOXY(I, I) + // + // OUTPUT A CHARACTER AND A SPACE + // + PUTC('A' + I) + PUTC(' ') + // + // OUTPUT AN INTEGER + // + PUTI(I) +NEXT + +// +// NOTICE THE '@' IN SOME OF THE FUNCTION +// ARGUMENTS? DID YOU NOTICE THE '^' IN +// THE PREVIOUS EXAMPLE? ALL WILL BE +// EXPLAINED IN EX.4.PLA! +// + +GOTOXY(10, 5) +PUTS("WHAT IS YOUR NAME") +NAME = GETS($BF) // GETS NEEDS PROMPT CHAR: '?' + 128 +GOTOXY(12, 7) +PUTS("NICE TO MEET YOU, ") +PUTS(NAME) +GOTOXY(16, 10) +PUTS("PRESS ANY KEY TO EXIT.") +GETC() +GOTOXY(0, 5) +MEMCPY(TEXTSCREEN, @SAVETXT, SCREENSIZE) +DONE diff --git a/src/samplesrc/examples/ex.4.pla b/src/samplesrc/examples/ex.4.pla new file mode 100644 index 0000000..8653393 --- /dev/null +++ b/src/samplesrc/examples/ex.4.pla @@ -0,0 +1,75 @@ +// +// IN PLASMA, ANY VALUE CAN BE USED +// AS A CHARACTER, INTEGER, ADDRESS, +// OFFSET, ETC. JUST LIKE IN ASSEMBLY +// LANGUAGE, THERE ARE NO RESTRICTIONS. +// WITH GREAT FLEXIBILITY COMES GREAT +// RESPONSIBILITY. IN THE FIRST EXAMPLE, +// YOU SAW WHERE A STRING WAS PRINTED. +// THE LINE LOOKED LIKE: PUTS(@HELLO) +// HOWEVER, THE STRING NAME WAS JUST +// "HELLO", WITHOUT THE '@'. SO WHAT +// DOES THAT '@' DO? IT IS THE +// ADDRESS-OF OPERATOR. IT TAKES THE +// ADDRESS WHERE THE VARIABLE IS STORED +// FOR ITS VALUE, NOT THE VALUE OF THE +// VARIABLE. WHEN OUTPUTTING THE STRING, +// THE ADDRESS OF THE STRING IS PASSED +// IN, NOT THE ENTIRE STRING. THIS IS +// MUCH MORE EFFICIENT. WHEN AN ADDRESS +// IS PASSED AROUND, IT IS REFERED TO +// AS A "POINTER". IT "POINTS" TO +// SOMETHING. +// +// THE COROLLARY TO THE ADDRESS-OF +// OPERATOR IS THE POINTER-TO OPERATOR. +// NOW, IN PLASMA, A POINTER IS JUST AN +// ADDRESS, THERE IS NO IDEA OF WHAT IT +// POINTS TO. PLASMA ONLY KNOWS ABOUT +// BYTES AND WORDS, SO THERE ARE TWO +// POINTER-TO OPERATORS: +// +// ^ POINTER-TO-BYTE +// * POINTER-TO-WORD +// +// NOW THE '*' OPERATOR LOOKS JUST LIKE +// THE MULTIPLICATION OPERATOR, BUT IT +// BEHAVES DIFFERENTLY DEPENDING ON +// WHERE IT IS PLACED. THESE OPERATORS +// ARE PRE-OPS; THEY COME BEFORE THE +// OPERAND. +// +// NOTE THAT ADDRESSES, THUS POINTERS, +// ARE 16 BIT VALUES ON THE APPLE II. +// IF YOU ARE GOING TO SAVE AN ADDRESS +// IN A VARIABLE, IT MUST BE A WORD +// VARIABLE TO HOLD THE FULL PRECISION. +// +// HERE IS AN EXAMPLE TO PLAY WITH: +// + +BYTE MYBYTE = 26 +WORD MYWORD = 75 +WORD MYPTR + +MYPTR = @MYBYTE +PUTI(^MYPTR) + +PUTC($8D) // THIS IS A CARRIAGE-RETURN CHARACTER + +MYPTR = @MYWORD +PUTI(*MYPTR) + +DONE // EVERYTHING AFTER "DONE" IS IGNORED + +TRY PLAYING AROUND WITH THE CODE. GO +AHEAD. YOU CAN'T REALLY BREAK THE +COMPUTER. IF IT LOCKS UP AND CTRL-RESET +DOESN'T GET YOU BACK TO THE EDITOR, JUST +REBOOT THE MACHINE. + +HOPEFULLY YOU SEE THAT THE VARIABLE +NAMES IN PLASMA ARE JUST LABELS APPLIED +TO ADDRESSES. SPACE IS SET ASIDE +DEPENDING ON THE SIZE OF THE VARIABLE,IF +ITS AN ARRAY, AND IF IT IS INITIALIZED. diff --git a/src/samplesrc/examples/ex.5.pla b/src/samplesrc/examples/ex.5.pla new file mode 100644 index 0000000..f1ae353 --- /dev/null +++ b/src/samplesrc/examples/ex.5.pla @@ -0,0 +1,40 @@ +// +// YOU'VE ALREADY SEEN SOME OF THE +// BUILT-IN FUNCTIONS IN PLASMA, NOW +// IT IS TIME TO DEFINE OUR OWN. THE +// REAL POWER OF PLASMA COMES FROM +// FUNCTION DEFINITIONS THAT USE LOCAL +// VARIABLES, AND THE ABILITY FOR +// RECURSION - FUNCTIONS THAT CAN CALL +// THEMSELVES. THE APPLE II DOES LIMIT +// THESE ABILITIES SOMEWHAT, BUT SOME +// COMPLEX ALGORITHMS WORK JUST FINE +// WITH THESE LIMITATION (INCLUDING +// THE PLASMA COMPILER, ITSELF). +// +// A FUNCTION DEFINITION HAS OPTIONAL +// ARGUMENTS, OPTIONAL LOCAL VARIABLES, +// AND AN OPTIONAL RETURN VALUE. +// +DEF ADD(A, B) + WORD C + + C = A + B + RETURN C +END + +PUTI(ADD(1, 2)) +DONE + +IN THE ABOVE EXAMPLE, THE RETURN COULD +BE SIMPLIFIED TO "RETURN A + B" BUT +I WAS TRYING TO SHOW HOW TO USE LOCAL +VARIABLES. ARRAYS CAN ALSO BE PLACED +IN THE LOCAL VARIABLES, BUT NOTE THAT +THE MAXIMUM SIZE OF LOCAL VARIABLES HAS +TO BE 255 BYTES OR LESS, PER DEFINITION. + +ALSO, DUE TO THE NATURE OF THE 6502 CALL +STACK, ONLY A CALL DEPTH OF ABOUT 96 IS +AVAILABLE. AFTER THAT, THE STACK +OVERFLOWS AND UNEXPECTED THINGS HAPPEN. diff --git a/src/samplesrc/examples/ex.6.pla b/src/samplesrc/examples/ex.6.pla new file mode 100644 index 0000000..f53e026 --- /dev/null +++ b/src/samplesrc/examples/ex.6.pla @@ -0,0 +1,68 @@ +// +// INSTEAD OF USING HARD-TO-REMEMBER +// NUMBERS, PLASMA ALLOWS YOU TO +// REPLACE THOSE WITH SYMBOLIC VALUES +// +CONST CR = $8D +CONST MALE = 0 +CONST FEMALE = 1 + +// +// STRUCTURES ARE SYNTACTICAL CANDY +// FOR CREATING OFFSETS. IN THE FOLLOWING +// EXAMPLE, MYSTRUC IS A CONSTANT VALUE +// OF THE SIZE OF THE STRUCTURE. THE +// ELEMENTS WILL BE CONSTANTS REPRESENTING +// THE OFFSETS INTO THE STRUCTURE. +// +STRUC MYSTRUC + BYTE[32] FIRST + BYTE[32] LAST + BYTE AGE + WORD SEX +END + +BYTE MALESTR = "MALE" +BYTE FEMALESTR = "FEMALE" + +// +// INITIALIZE A SAMPLE RECORD. +// +BYTE[] RECORD +BYTE[32] = "STEVE" +BYTE[32] = "WOZNIAK" +BYTE = 61 +WORD = @MALESTR + +// +// HERE IS A NEW WAY TO USE POINTERS: AS +// A POINTER TO A STRUCTURE. AGAIN, +// SINCE POINTERS DON'T KNOW WHAT THEY +// POINT TO, THERE ARE TWO OPERATORS TO +// POINT TO A BYTE, OR POINT TO A WORD. +// '->' POINTS TO A BYTE USING A POINTER +// AND AN OFFSET. '=>' POINTS TO A WORD +// USING A POINTER AND AN OFFSET. IN +// THE FOLLOWING EXAMPLE, THE OFFSETS +// COME FROM THE 'MYSTRUC' DEFINITION. +// +DEF PUTREC(RECPTR) + PUTS(@RECPTR->FIRST) // ADDRESS OF FIRST NAME + PUTC(CR) + PUTS(@RECPTR->LAST) // ADDRESS OF LAST NAME + PUTC(CR) + PUTI(RECPTR->AGE) // AGE (BYTE) + PUTC(CR) + PUTS(RECPTR=>SEX) // POINTER TO STRING (WORD) +END + +PUTS("STRUCTURE SIZE:") +PUTI(MYSTRUC) // THIS IS JUST THE SIZE OF THE STRUCTURE +PUTC(CR) + +// +// PASS THE ADDRESS OF A SAMPLE RECORD +// TO BE PRINTED OUT. +// +PUTREC(@RECORD) +DONE diff --git a/src/samplesrc/examples/ex.7.pla b/src/samplesrc/examples/ex.7.pla new file mode 100644 index 0000000..99f8a14 --- /dev/null +++ b/src/samplesrc/examples/ex.7.pla @@ -0,0 +1,65 @@ +// +// RETURNING BACK TO ARRAYS AND STRINGS. +// SINGLE DIMENSION ARRAYS CAN BE +// ACCESSED WITH INDICES, USING THE TYPE +// THE ARRAY WAS DEFINED WITH. NOTICE +// THAT WITH INITIALIZED ARRAYS, THE "[]" +// IS OPTIONAL. ONLY IF A MINIMUM SIZE +// IS SPECIFIED (OR THERE ARE NO +// INITIALIZERS) ARE THE "[]" REQUIRED. +// +BYTE[] ASTRING = "PLASMA IS COOL!" +// +// MULTI-DIMENSIONAL ARRAYS ARE DEFINED +// AS POINTERS TO ARRAYS. THIS HAS THE +// BENEFIT OF CREATING SPARSE ARRAYS AND +// NON-CONTIGUOUS ARRAYS. THE APPLE II +// SCREEN MEMORY, FOR INSTANCE, WORKS +// WELL AS AN ARRAY OF POINTERS TO BYTES. +// +// BECAUSE POINTERS ARE 16 BITS, THE +// MULTI-DIMENSIONAL ARRAY IS DEFINED AS +// 'WORDS'. BUT HOW TO REPRESENT BYTE +// ARRAYS VS WORD ARRAYS? AGAIN, THERE +// ARE TWO SIZE OPERATORS THAT DEFINE +// BYTE ARRAYS AND WORD ARRAYS. '.' SETS +// THE ARRAY TYPE TO 'BYTE' AND ':' SETS +// THE ARRAY TYPE TO 'WORD'. +// +// +// '.' AND ':' CAN ALSO HAVE CONSTANTS +// FOLLOWING THEM, TO ACCESS FIXED +// OFFSETS FROM THE ARRAY, FOR STRUCTURE +// ELEMENT ACCESS. CHECK OUT THE ACCESS +// TO THE STRING LENGTH, IN BYTE OFFSET +// 0 (ASSIGNED TO CONSTANT STRLEN). +// +CONST STRLEN = 0 + +WORD[] TEXTSCREEN +WORD = $400, $480, $500, $580, $600, $680, $700, $780 +WORD = $428, $4A8, $528, $5A8, $628, $6A8, $728, $7A8 +WORD = $450, $4D0, $550, $5D0, $650, $6D0, $750, $7D0 +// +// STRINGS IN PLASMA ARE PRODOS +// COMPATIBLE "PASCAL" STRINGS. STRINGS +// WITH THE LENGTH ENCODED IN THE FIRST +// BYTE, FOLLOWED BY THE CHARACTERS. +// +WORD P +BYTE I + +HOME() +FOR I = 1 TO ASTRING.STRLEN // THE LENGTH OF THE STRING + TEXTSCREEN.[I, I] = ASTRING[I] | $80 +NEXT +GOTOXY(0, ASTRING.STRLEN+2) +PUTS("THE STRING LENGTH IS:") +PUTI(ASTRING.STRLEN) +DONE + +NOTE THAT THE HIGH BIT IS SET WHEN +WRITING CHARACTERS TO THE SCREEN. PLASMA +AND PRODOS USE 0..128 FOR ASCII VALUES, +BUT THE APPLE II SCREEN USES 128..255 FOR +NORMAL CHARACTERS. diff --git a/src/samplesrc/examples/ex.8.pla b/src/samplesrc/examples/ex.8.pla new file mode 100644 index 0000000..cd77544 --- /dev/null +++ b/src/samplesrc/examples/ex.8.pla @@ -0,0 +1,71 @@ +// +// PLASMA DOESN'T REQUIRE UPPER CASE. +// HOWEVER, DUE TO THE NATURE OF THE +// APPLE ][ AND ][+, UPPER CASE WILL +// LOOK BEST ON ALL APPLE II COMPUTERS. +// IF YOU PRINT LOWER CASE TEXT ON AN +// APPLE ][ OR ][+ USING PUTS, IT WILL +// BE AUTOMATICALLY SHIFTED TO UPPER +// CASE. +// +// Here is the PLASMA version of +// Rod's Colors from the DOS System +// Master disk using the built-in call +// function to call ROM routines: +// +const showlores = $C056 +const keyboard = $C000 +const keystrobe = $C010 +byte i, j, k, w, fmi, fmk, color + +def textmode + call($FB39, 0, 0, 0, 0) + return home +end + +def grmode + call($FB40, 0, 0, 0, 0) + ^showlores + return home +end + +def colors + while 1 + for w = 3 to 50 + for i = 1 to 19 + for j = 0 to 19 + k = i + j + color = (j * 3) / (i + 3) + i * w / 12 + fmi = 40 - i + fmk = 40 - k + call($F864, color, 0, 0, 0) //grcolor(color); + call($F800, k, 0, i, 0) //grplot(i, k); + call($F800, i, 0, k, 0) //grplot(k, i); + call($F800, fmk, 0, fmi, 0) //grplot(fmi, fmk); + call($F800, fmi, 0, fmk, 0) //grplot(fmk, fmi); + call($F800, fmi, 0, k, 0) //grplot(k, fmi); + call($F800, k, 0, fmi, 0) //grplot(fmi, k); + call($F800, fmk, 0, i, 0) //grplot(i, fmk); + call($F800, i, 0, fmk, 0) //grplot(fmk, i); + if ^keyboard >= 128 + return ^keystrobe + fin + next + next + next + loop +end + + +grmode +gotoxy(10,2) // X,Y offsets from the text window +puts("Press any key to exit.") +colors +textmode +puts("That's all, folks!") +done + +This program skips the optional "()" on +parameter-less functions. You decide if +this is a style you prefer. Regardless, +be consistent in your source code. diff --git a/src/samplesrc/examples/ex.9.pla b/src/samplesrc/examples/ex.9.pla new file mode 100644 index 0000000..7ed08c2 --- /dev/null +++ b/src/samplesrc/examples/ex.9.pla @@ -0,0 +1,126 @@ +// +// THIS IS A FOREST FIRE SIMULATION. +// +// WRITTEN IS A SLIGHTLY DIFFERENT STYLE. +// +CONST FALSE = 0 +CONST TRUE = NOT FALSE +CONST SHOWLORES = $C056 +CONST KEYBOARD = $C000 +CONST KEYSTROBE = $C010 +CONST EMPTY = 0 +CONST TREE = 4 +CONST FIRE = 13 +CONST FORESTSIZE = 42*42 +CONST RNDNUM = $4E +CONST RNDL = $4E +CONST RNDH = $4F +BYTE TREES1[FORESTSIZE] // ALT ARRAY SIZE SPECIFIER +BYTE TREES2[FORESTSIZE] + +DEF TEXTMODE + CALL($FB39, 0, 0, 0, 0) + RETURN HOME +END + +DEF GRMODE + CALL($FB40, 0, 0, 0, 0) + ^SHOWLORES + RETURN HOME +END + +// +// RANDOM NUMBERS +// +DEF RND + *RNDNUM = (*RNDNUM << 1) + *RNDNUM + 251 + RETURN *RNDNUM & $7FFF +END + +// +// CHECK IF A FIRE IS BURNING AROUND TREE +// +DEF BYFIRE(TREEPTR) + IF ^(TREEPTR - 43) == FIRE + RETURN TRUE + ELSIF ^(TREEPTR - 42) == FIRE + RETURN TRUE + ELSIF ^(TREEPTR - 41) == FIRE + RETURN TRUE + ELSIF ^(TREEPTR - 1) == FIRE + RETURN TRUE + ELSIF ^(TREEPTR + 1) == FIRE + RETURN TRUE + ELSIF ^(TREEPTR + 41) == FIRE + RETURN TRUE + ELSIF ^(TREEPTR + 42) == FIRE + RETURN TRUE + ELSIF ^(TREEPTR + 43) == FIRE + RETURN TRUE + FIN + RETURN FALSE +END + +DEF FORESTFIRE + WORD NEWTREES, OLDTREES, NEWTREE, OLDTREE, YROW + BYTE X, Y + + MEMSET(@TREES1, EMPTY, FORESTSIZE) + MEMSET(@TREES2, EMPTY, FORESTSIZE) + OLDTREES = @TREES1 + NEWTREES = @TREES2 + + FOR Y = 1 TO 40 + YROW = Y * 42 + FOR X = 1 TO 40 + IF RND < 8000 + ^(OLDTREES + X + YROW) = TREE + FIN + NEXT + NEXT + WHILE ^KEYBOARD < 128 + FOR Y = 1 TO 40 + YROW = Y * 42 + FOR X = 1 TO 40 + OLDTREE = OLDTREES + X + YROW + NEWTREE = NEWTREES + X + YROW + WHEN ^OLDTREE + IS EMPTY + IF RND < 5000 + ^NEWTREE = TREE + ELSE + ^NEWTREE = EMPTY + FIN + BREAK + IS TREE + IF RND < 5 OR BYFIRE(OLDTREE) + ^NEWTREE = FIRE + ELSE + ^NEWTREE = TREE + FIN + BREAK + IS FIRE + ^NEWTREE = EMPTY + WEND + CALL($F864, ^NEWTREE, 0, 0, 0) + CALL($F800, Y - 1, 0, X - 1, 0) + NEXT + NEXT + YROW = NEWTREES + NEWTREES = OLDTREES + OLDTREES = YROW + LOOP + RETURN ^KEYSTROBE +END + +PUTS("PRESS ANY KEY TO BEGIN...") +GETC +GRMODE +HOME +GOTOXY(10,2) +PUTS("PRESS ANY KEY TO EXIT.") +FORESTFIRE +TEXTMODE +HOME +PUTS("THAT'S ALL FOLKS!") +DONE diff --git a/src/samplesrc/gfxdemo.pla b/src/samplesrc/gfxdemo.pla new file mode 100644 index 0000000..ab08e08 --- /dev/null +++ b/src/samplesrc/gfxdemo.pla @@ -0,0 +1,41 @@ +include "inc/cmdsys.plh" +include "inc/args.plh" +include "inc/fileio.plh" +include "inc/grafix.plh" + +var arg +byte ref + +def showimage#0 + var row, x + byte scanline[140] + + for row = 0 to 191 + // + // Read one scanline at a time, scale it, and draw it + // + fileio:read(ref, @scanline, 140) + for x = 139 downto 0 + //scanline[x] = scanline[x] >> 4 + pencolor(scanline[x] >> 4) + plot(x, row) + next + next +end + +arg = argNext(argFirst) +if ^arg + ref = fileio:open(arg) + if ref + setmode(3) // 140 x 192 full color (or greyscale) + showimage + fileio:close(ref) + getc + setmode(-1) + else + puts("Unable to open "); puts(arg); putln + fin +else + puts("Usage: gfxdemo \n") +fin +done diff --git a/src/samplesrc/httpd.pla b/src/samplesrc/httpd.pla index ab73a90..067dcc6 100644 --- a/src/samplesrc/httpd.pla +++ b/src/samplesrc/httpd.pla @@ -11,13 +11,13 @@ include "inc/cmdsys.plh" include "inc/inet.plh" include "inc/fileio.plh" +include "inc/conio.plh" word socketHTTP -byte[65] prefix -word filebuff, iobuff -byte fileInfo[12] = 0 // used for get_file_info() -byte hello = "Apple II Web Server - 12 Nov 15\n" -byte defhtml = "INDEX.HTML" +byte[65] prefix +word filebuff +byte[15] fileInfo = 0 // used for get_file_info() +byte defhtml = "INDEX.HTML" byte[200] okhdr // combined response header // // HTTP response codes @@ -78,7 +78,7 @@ def strcat2(dst, src1, src2) return dst end def itos(dst, i) - if i < 0; ^dst = '-'; i = -i; dst = dst + 1; fin + if i < 0; ^dst = '-'; i = -i; dst++; fin if i < 10 ^dst = i + '0' else @@ -141,7 +141,6 @@ def servHTTP(remip, remport, lclport, data, len, param) // Get file info // //puts("getting file info "); // debug - fileio:getfileinfo(@filename) refnum = fileio:open(@filename) // try to open this file with ProDOS if refnum // file was opened OK filelen = fileio:geteof(refnum) // get length of file for Content-Length @@ -152,7 +151,8 @@ def servHTTP(remip, remport, lclport, data, len, param) // // Content type header // - if fileInfo.4 == $03 OR fileInfo.4 == $04 + fileio:getfileinfo(@filename, @fileInfo) + if fileInfo.1 == $03 OR fileInfo.1 == $04 // // this a text file // @@ -181,8 +181,8 @@ def servHTTP(remip, remport, lclport, data, len, param) else // file couldn't be opened, so return 404 on this puts("404 Not Found");putln // debug iNet:sendTCP(socketHTTP, @httpNOTFOUND + 1, httpNOTFOUND) - fin // if refnum - break // return + fin // refnum + break fin next else @@ -196,7 +196,7 @@ end if !iNet:initIP() return -1 fin -puts(@hello) +puts("PLASMA Web Server, Version 1.0\n") fileio:getpfx(@prefix) // // Alloc aligned file/io buffers @@ -213,7 +213,6 @@ repeat socketHTTP = iNet:listenTCP(80, @servHTTP, 0) fin iNet:serviceIP() -until ^$C000 > 127 -^$C010 +until conio:keypressed() done diff --git a/src/samplesrc/index.html b/src/samplesrc/index.html index 5b16ba7..29f2954 100755 --- a/src/samplesrc/index.html +++ b/src/samplesrc/index.html @@ -1,5 +1,11 @@ -Hello from the Apple II! +

Hello from PLASMA!

+ +

Useful links:

+
PLASMA Language +
Facebook Apple II Enthusiasts +
comp.sys.apple2 + - \ No newline at end of file + diff --git a/src/samplesrc/playseq.pla b/src/samplesrc/playseq.pla index f3af6c6..087dad9 100644 --- a/src/samplesrc/playseq.pla +++ b/src/samplesrc/playseq.pla @@ -12,7 +12,7 @@ word ref // Sample background process to show it's working // def backgroundProc#0 - ^$0400++ + putc('.') end arg = argNext(argFirst) diff --git a/src/vmsrc/a1cmd.pla b/src/vmsrc/apple/a1cmd.pla similarity index 100% rename from src/vmsrc/a1cmd.pla rename to src/vmsrc/apple/a1cmd.pla diff --git a/src/vmsrc/cmd.pla b/src/vmsrc/apple/cmd.pla similarity index 99% rename from src/vmsrc/cmd.pla rename to src/vmsrc/apple/cmd.pla index feff331..68309fb 100755 --- a/src/vmsrc/cmd.pla +++ b/src/vmsrc/apple/cmd.pla @@ -38,7 +38,7 @@ predef execmod(modfile)#1 // // Exported CMDSYS table // -word version = $0100 // 01.00 +word version = $0101 // 01.01 word syspath word syscmdln word = @execmod diff --git a/src/vmsrc/cmdstub.s b/src/vmsrc/apple/cmdstub.s similarity index 96% rename from src/vmsrc/cmdstub.s rename to src/vmsrc/apple/cmdstub.s index bd8db37..deae3cc 100644 --- a/src/vmsrc/cmdstub.s +++ b/src/vmsrc/apple/cmdstub.s @@ -43,6 +43,6 @@ LCBNK1 = $08 JMP $1000 _CMDBEGIN = * !PSEUDOPC $1000 { - !SOURCE "vmsrc/cmd.a" + !SOURCE "vmsrc/apple/cmd.a" _CMDEND = * } diff --git a/src/vmsrc/plvm01.s b/src/vmsrc/apple/plvm01.s similarity index 99% rename from src/vmsrc/plvm01.s rename to src/vmsrc/apple/plvm01.s index 0ca40ec..b391d3c 100644 --- a/src/vmsrc/plvm01.s +++ b/src/vmsrc/apple/plvm01.s @@ -64,7 +64,7 @@ MUL STY IPY LDA #$00 STA ESTKL+1,X ; PRODL ; STA ESTKH+1,X ; PRODH -MULLP LSR TMPH ; MULTPLRH +_MULLP LSR TMPH ; MULTPLRH ROR TMPL ; MULTPLRL BCS + STA ESTKH+1,X ; PRODH @@ -76,7 +76,7 @@ MULLP LSR TMPH ; MULTPLRH + ASL ESTKL,X ; MULTPLNDL ROL ESTKH,X ; MULTPLNDH DEY - BNE MULLP + BNE _MULLP STA ESTKH+1,X ; PRODH LDY IPY JMP DROP @@ -902,7 +902,7 @@ LEAVE INY ;+INC_IP RTS + INC IFPH RET RTS -A1CMD !SOURCE "vmsrc/a1cmd.a" +A1CMD !SOURCE "vmsrc/apple/a1cmd.a" SEGEND = * VMINIT LDY #$10 ; INSTALL PAGE 0 FETCHOP ROUTINE - LDA PAGE0-1,Y diff --git a/src/vmsrc/plvm02.s b/src/vmsrc/apple/plvm02.s similarity index 99% rename from src/vmsrc/plvm02.s rename to src/vmsrc/apple/plvm02.s index 160f3e2..77d2d58 100755 --- a/src/vmsrc/plvm02.s +++ b/src/vmsrc/apple/plvm02.s @@ -457,7 +457,7 @@ MUL STY IPY LDA #$00 STA ESTKL+1,X ; PRODL ; STA ESTKH+1,X ; PRODH -MULLP LSR TMPH ; MULTPLRH +_MULLP LSR TMPH ; MULTPLRH ROR TMPL ; MULTPLRL BCS + STA ESTKH+1,X ; PRODH @@ -469,7 +469,7 @@ MULLP LSR TMPH ; MULTPLRH + ASL ESTKL,X ; MULTPLNDL ROL ESTKH,X ; MULTPLNDH DEY - BNE MULLP + BNE _MULLP STA ESTKH+1,X ; PRODH LDY IPY JMP DROP @@ -1161,7 +1161,7 @@ SAW INY ;+INC_IP LDY IPY BMI + JMP DROP - JMP FIXDROP ++ JMP FIXDROP ;* ;* STORE VALUE TO ABSOLUTE ADDRESS WITHOUT POPPING STACK ;* @@ -1884,7 +1884,7 @@ OPCPY STA DST INC SRC BNE + INC SRC+1 -+ ++ DEY - LDA (SRC),Y STA (DST),Y DEY diff --git a/src/vmsrc/plvm03.s b/src/vmsrc/apple/plvm03.s similarity index 99% rename from src/vmsrc/plvm03.s rename to src/vmsrc/apple/plvm03.s index bf81b6f..40e8e64 100755 --- a/src/vmsrc/plvm03.s +++ b/src/vmsrc/apple/plvm03.s @@ -135,6 +135,18 @@ PAGE0 = * VMCORE = * !PSEUDOPC $A000 { ;* +;* 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 +;* ;* SYSTEM INTERPRETER ENTRYPOINT ;* INTERP PLA @@ -220,33 +232,6 @@ _DIVEX INX LDY IPY RTS ;* -;* INCREMENT TOS -;* -INCR INC ESTKL,X - BNE + - INC ESTKH,X -+ JMP NEXTOP -;* -;* DECREMENT TOS -;* -DECR LDA ESTKL,X - BNE + - DEC ESTKH,X -+ DEC ESTKL,X - JMP NEXTOP -;* -;* 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 -;* ;* MUL TOS-1 BY TOS ;* MUL STY IPY @@ -260,7 +245,7 @@ MUL STY IPY LDA #$00 STA ESTKL+1,X ; PRODL ; STA ESTKH+1,X ; PRODH -MULLP LSR TMPH ; MULTPLRH +_MULLP LSR TMPH ; MULTPLRH ROR TMPL ; MULTPLRL BCS + STA ESTKH+1,X ; PRODH @@ -272,7 +257,7 @@ MULLP LSR TMPH ; MULTPLRH + ASL ESTKL,X ; MULTPLNDL ROL ESTKH,X ; MULTPLNDH DEY - BNE MULLP + BNE _MULLP STA ESTKH+1,X ; PRODH LDY IPY JMP DROP @@ -315,6 +300,21 @@ DIVMOD JSR _DIV BMI NEG JMP NEXTOP ;* +;* INCREMENT TOS +;* +INCR INC ESTKL,X + BNE + + INC ESTKH,X ++ JMP NEXTOP +;* +;* DECREMENT TOS +;* +DECR LDA ESTKL,X + BNE + + DEC ESTKH,X ++ DEC ESTKL,X + JMP NEXTOP +;* ;* ADD TOS TO TOS-1 ;* ADD LDA ESTKL,X @@ -1084,6 +1084,6 @@ LEAVE INY ;+INC_IP STA IFPH RET RTS SOSCMD = * - !SOURCE "vmsrc/soscmd.a" + !SOURCE "vmsrc/apple/soscmd.a" } SEGEND = * diff --git a/src/vmsrc/plvm802.s b/src/vmsrc/apple/plvm802.s similarity index 99% rename from src/vmsrc/plvm802.s rename to src/vmsrc/apple/plvm802.s index 179ac0a..5335412 100644 --- a/src/vmsrc/plvm802.s +++ b/src/vmsrc/apple/plvm802.s @@ -529,12 +529,12 @@ MUL LDX #$10 EOR #$FFFF STA TMP LDA #$0000 -MULLP ASL +_MULLP ASL ASL TMP ; MULTPLR BCS + ADC TOS,S ; MULTPLD + DEX - BNE MULLP + BNE _MULLP STA NOS,S ; PROD JMP DROP ;* @@ -1006,7 +1006,6 @@ SLB INY ;+INC_IP TXY BMI + JMP NEXTOP -+ JMP FIXNEXT SLW INY ;+INC_IP LDA (IP),Y TYX @@ -1051,7 +1050,6 @@ SAB INY ;+INC_IP INY BMI + JMP NEXTOP -+ JMP FIXNEXT SAW INY ;+INC_IP LDA (IP),Y STA TMP diff --git a/src/vmsrc/plvmzp.inc b/src/vmsrc/apple/plvmzp.inc similarity index 100% rename from src/vmsrc/plvmzp.inc rename to src/vmsrc/apple/plvmzp.inc diff --git a/src/vmsrc/soscmd.pla b/src/vmsrc/apple/soscmd.pla similarity index 100% rename from src/vmsrc/soscmd.pla rename to src/vmsrc/apple/soscmd.pla diff --git a/src/vmsrc/c64/cmd.pla b/src/vmsrc/c64/cmd.pla new file mode 100755 index 0000000..d457d4f --- /dev/null +++ b/src/vmsrc/c64/cmd.pla @@ -0,0 +1,1131 @@ +const RELADDR = $1000 +const freemem = $0100 +//const inbuff = $0200 +// +// 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 = $1000 +const modinitkeep = $2000 +// +// Pedefined functions. +// +predef syscall(cmd,null)#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 +predef sext(a)#1, divmod(a,b)#2, execmod(modfile)#1 +// +// Exported CMDSYS table +// +word version = $0100 // 01.00 +word syspath +word syscmdln +word = @execmod +word systemflags = 0 +word heap +word symtbl, lastsym +byte perr, refauto +// +// String pool. +// +byte inbuff[128] +byte autorun[] = "AUTORUN" +byte verstr[] = "\nPLASMA " +byte hexchar[] = '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' +// +// Exported Machine ID. +// +byte machid = $08 // Apple 1 (NA in ProDOS Tech Ref) +// +// Command line pointer +// +word cmdptr = @hexchar // make it point to a zero +// +// Standard Library exported functions. +// +byte syslibstr[] = "CMDSYS" +byte machidstr[] = "MACHID" +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 sysstr[] = "SYSCALL" +byte callstr[] = "CALL" +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" +word exports[] = @syslibstr, @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 syslibsym = @exports +// +// Utility functions +// +asm saveX#0 + STX XREG+1 +end +asm restoreX#0 +XREG LDX #$00 + RTS +end +// +// CALL API ENTRYPOINT +// SYSCALL(CMD, 0) +// +asm syscall(cmd, null)#1 + LDA ESTKL,X + STX ESP + TAX + JSR $900C + LDX ESP + INX + 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,sstatus)#1 + PHP + LDA ESTKL+4,X + STA CALL6502+1 + LDA ESTKH+4,X + STA CALL6502+2 + 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 + PLP +CALL6502 JSR $FFFF + 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 +REGVALS !FILL 4 +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 +// +// 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 DINTERP + !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 #IINTERP + 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 +// +// Module symbols are entered into the symbol table +// pre-pended with a '#' to differentiate them +// from normal symbols. +// +// +// 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->0 == $20 +// if deftbl=>3 == addr +// return deftbl +// fin +// deftbl = deftbl + 5 +// 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 #$05 + 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 +// +// CONSOLE I/O +// +asm cout(c)#0 + LDA ESTKL,X + INX + JMP $FFD2 +end +asm cin()#1 + DEX + STX ESP + JSR $FFCF + AND #$7F + LDX ESP + STA ESTKL,X + LDA #$00 + STA ESTKH,X + RTS +end +def crout()#0 + cout($0D) +end +def prstr(str)#0 + byte i + for i = 1 to ^str + cout(^(str + i)) + next +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 + byte ch + inbuff.0 = 0 + cout(prompt) + for inbuff = 0 to 127 + ch = cin + 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]) + cout(hexchar[v & $0F]) +end +def prword(v)#0 + prbyte(v >> 8) + prbyte(v) +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 +// +// C64 FILE I/O +// +def finddirentry(filename)#1 + return 0 +end +def readfile(filename, buffer)#1 + return 0 +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 + ^lastsym = ^sym + lastsym = lastsym + 1 + sym = sym + 1 + loop + lastsym->0 = ^sym + lastsym=>1 = addr + lastsym = lastsym + 3 + ^lastsym = 0 +end +// +// Module routines. +// +def lookupextern(esd, index)#1 + word sym, addr + byte str[16] + while ^esd + sym = esd + esd = sym + dcitos(sym, @str) + if esd->0 & $10 and esd->1 == index + addr = lookuptbl(sym, symtbl) + if !addr + perr = $81 + cout('?') + prstr(@str) + crout + fin + return addr + fin + esd = esd + 3 + loop + return 0 +end +def adddef(addr, deflast)#1 + word defentry + defentry = *deflast + *deflast = defentry + 5 + defentry->0 = $20 + defentry=>1 = interp + defentry=>3 = addr + defentry->5 = 0 // null out next entry + return defentry +end +def loadmod(mod)#1 + word rdlen, modsize, bytecode, defofst, defcnt, init, fixup + word addr, modaddr, modfix, modofst, modend + word deftbl, deflast + word moddep, rld, esd, sym + byte type, str[17], filename[17] + byte header[128] + // + // Read the RELocatable module header (first 128 bytes) + // + dcitos(mod, @filename) + rdlen = finddirentry(@filename)=>$15 + if perr + return -perr + fin + if rdlen > 0 + readfile(@filename, heap) + memcpy(@header, heap, 128) + modsize = header:0 + moddep = @header.1 + defofst = modsize + RELADDR + init = 0 + if rdlen > 4 and heap=>2 == $6502 // magic number + // + // This is an EXTended RELocatable (data+bytecode) module. + // + defofst = header:6 + defcnt = header:8 + init = header:10 + moddep = @header.12 + // + // Load module dependencies. + // + while ^moddep + if !lookuptbl(moddep, symtbl) + if loadmod(moddep) < 0 + return -perr + fin + fin + moddep = moddep + dcitos(moddep, @str) + loop + // + // Init def table. + // + deftbl = allocheap(defcnt * 5 + 1) + deflast = deftbl + ^deflast = 0 + // + // Re-read file + // + readfile(@filename, heap) + fin + // + // Alloc heap space for relocated module (data + bytecode). + // + moddep = moddep + 1 - @header + heap + modfix = moddep - (heap + 2) // Adjust to skip header + modsize = modsize - modfix + rdlen = rdlen - modfix - 2 + modaddr = allocheap(modsize) + memcpy(modaddr, moddep, rdlen) + // + // 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 + defofst = bytecode - defofst + 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 + // + // Run through the DeFinition Dictionary. + // + while ^rld == $02 + // + // This is a bytcode def entry - add it to the def directory. + // + adddef(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 + defofst, 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 + defofst, deftbl) + fin + addsym(sym, addr) + fin + esd = esd + 3 + loop + fin + if perr + return -perr + fin + // + // Free up the end-of-module in main memory. + // + releaseheap(modend) + // + // Call init routine if it exists. + // + fixup = 0 + if init + init = init - defofst + bytecode + fixup = adddef(init, @deflast)() + if fixup < 0 + perr = -fixup + fin + if !(systemflags & modinitkeep) + releaseheap(init) + fin + fin + return fixup | (systemflags & modkeep) +end +// +// Command mode +// +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)#0 + byte i + + for i = 1 to ^strptr + if (strptr)[i] == ' ' + ^strptr = i - 1 + return + fin + next +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 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 + fin + ^lastsym = 0 + systemflags = saveflags + fin + return -perr +end +// +// Get heap start. +// +heap = *freemem +// +// Print PLASMA version +// +prstr("\nPRELIM PLASMA "); prbyte(version.1); cout('.'); prbyte(version.0); crout +// +// Init symbol table. +// +symtbl = allocheap($200) +lastsym = symtbl +^lastsym = 0 +while *syslibsym + stodci(syslibsym=>0, heap) + addsym(heap, syslibsym=>2) + syslibsym = syslibsym + 4 +loop +// +// Try to load autorun. +// +cmdptr = heap +memset(cmdptr, 0, 128) +readfile(@autorun, cmdptr + 1) +while ^(cmdptr + ^cmdptr + 1) >= ' ' + ^cmdptr++ +loop +perr = 0 +// +// Print some startup info. +// +if not ^cmdptr + prstr("MEM FREE:$") + prword(availheap) + crout +fin +// +// Handle commands. +// +while 1 + if ^cmdptr + when toupper(parsecmd(cmdptr)) + is 'C' + break + is '+' + execmod(cmdptr) + break + otherwise + cout('?') + wend + if perr + prstr("ERR:$") + prbyte(perr) + perr = 0 + else + prstr("OK") + fin + crout + fin + prstr("C64 PLASMA") + cmdptr = rdstr(':') +loop +done diff --git a/src/vmsrc/c64/plvmc64.s b/src/vmsrc/c64/plvmc64.s new file mode 100644 index 0000000..bfaa45c --- /dev/null +++ b/src/vmsrc/c64/plvmc64.s @@ -0,0 +1,935 @@ +;********************************************************** +;* +;* COMMODORE 64 PLASMA INTERPETER +;* +;* SYSTEM ROUTINES AND LOCATIONS +;* +;********************************************************** +;* +;* VM ZERO PAGE LOCATIONS +;* + !SOURCE "vmsrc/plvmzp.inc" +DVSIGN = TMP+2 +DROP = $7F +NEXTOP = $80 +FETCHOP = NEXTOP+1 +IP = FETCHOP+1 +IPL = IP +IPH = IPL+1 +OPIDX = FETCHOP+6 +OPPAGE = OPIDX+1 +;* +;* INTERPRETER HEADER+INITIALIZATION +;* + *= $1000 +SEGBEGIN JMP VMINIT +;* +;* SYSTEM INTERPRETER ENTRYPOINT +;* +INTERP PLA + CLC + ADC #$01 + STA IPL + PLA + ADC #$00 + STA IPH + LDY #$00 + JMP FETCHOP +;* +;* ENTER INTO USER BYTECODE INTERPRETER +;* +IINTERP PLA + STA TMPL + PLA + STA TMPH + LDY #$02 + LDA (TMP),Y + STA IPH + DEY + LDA (TMP),Y + STA IPL + DEY + JMP FETCHOP +;* +;* 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 +;* +;* INCREMENT TOS +;* +INCR INC ESTKL,X + BNE + + INC ESTKH,X ++ JMP NEXTOP +;* +;* DECREMENT TOS +;* +DECR LDA ESTKL,X + BNE + + DEC ESTKH,X ++ DEC ESTKL,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 +;* +;* 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 +;* +;* 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 + LDA DVSIGN ; REMAINDER IS SIGN OF DIVIDEND + BMI NEG + JMP NEXTOP +;* +;* NEGATE TOS +;* +NEG JSR _NEG + JMP NEXTOP +;* +;* 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 + LDA ESTKH,X + AND #$80 + STA DVSIGN + BPL + + JSR _NEG + INC DVSIGN ++ LDA ESTKH+1,X + BPL + + INX + JSR _NEG + DEX + INC DVSIGN + BNE _DIV1 ++ ORA ESTKL+1,X ; DVDNDL + BEQ _DIVEX +_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 +;* +;* 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 +;* +;* 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 +;* +;* 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 + 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 + STA ESTKL,X + STA ESTKH,X + JMP NEXTOP +;* +;* CONSTANT +;* +ZERO DEX ++ LDA #$00 + STA ESTKL,X + STA ESTKH,X + JMP NEXTOP +CFFB LDA #$FF + !BYTE $2C ; BIT $00A9 - effectively skips LDA #$00, no harm in reading this address +CB LDA #$00 + DEX + 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 +;* +;* 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 +;* +;* 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 +;* +;* 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 +;* +;* 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) + 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 FIXDROP + JMP DROP +;* +;* 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 +; +ISGT LDA ESTKL,X + CMP ESTKL+1,X + LDA ESTKH,X + SBC ESTKH+1,X + BVS + + BMI ISTRU + BPL 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 + + BMI ISTRU + BPL ISFLS ++ BMI ISFLS + BPL ISTRU +;* +;* BRANCHES +;* +BRTRU INX + LDA ESTKH-1,X + ORA ESTKL-1,X + BNE BRNCH +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 + 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 +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 +BRGT INX + LDA ESTKL-1,X + CMP ESTKL,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 + LDA ESTKH,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 +;* +;* INDIRECT CALL TO ADDRESS (NATIVE CODE) +;* +ICAL LDA ESTKL,X + STA TMPL + LDA ESTKH,X + STA TMPH + INX + BNE _CALL +;* +;* CALL INTO ABSOLUTE ADDRESS (NATIVE CODE) +;* +CALL INY ;+INC_IP + LDA (IP),Y + STA TMPL + INY ;+INC_IP + LDA (IP),Y + STA TMPH +_CALL TYA + CLC + ADC IPL + PHA + LDA IPH + ADC #$00 + PHA + JSR JMPTMP + PLA + STA IPH + PLA + STA IPL + LDY #$01 + JMP FETCHOP +;* +;* ENTER FUNCTION WITH FRAME SIZE AND PARAM COUNT +;* +ENTER INY + LDA (IP),Y + EOR #$FF + SEC + ADC IFPL + STA IFPL + BCS + + DEC 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 +;* +LEAVE INY ;+INC_IP + LDA (IP),Y + CLC + ADC IFPL + STA IFPL + BCS + + RTS ++ INC IFPH +RET RTS +CMD !SOURCE "vmsrc/c64/cmd.a" +SEGEND = * +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 TO $D000 + LDA #$D0 + STA IFPH + LDA #SEGEND + 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 { +;* +;* INTERP BYTECODE INNER LOOP +;* + INX ; DROP + INY ; NEXTOP + LDA $FFFF,Y ; FETCHOP @ $F3, IP MAPS OVER $FFFF @ $F4 + STA OPIDX + JMP (OPTBL) +} diff --git a/src/vmsrc/c64/plvmzp.inc b/src/vmsrc/c64/plvmzp.inc new file mode 100755 index 0000000..148b288 --- /dev/null +++ b/src/vmsrc/c64/plvmzp.inc @@ -0,0 +1,29 @@ +;********************************************************** +;* +;* VM ZERO PAGE LOCATIONS +;* +;********************************************************** +SRC = $4C +SRCL = SRC +SRCH = SRC+1 +DST = SRC+2 +DSTL = DST +DSTH = DST+1 +ESGUARD = $4E +ESTKSZ = $20 +ESTK = $50 +ESTKH = ESTK +ESTKL = ESTK+ESTKSZ/2 +VMZP = ESTK+ESTKSZ +IFP = VMZP +IFPL = IFP +IFPH = IFP+1 +PP = IFP+2 +PPL = PP +PPH = PP+1 +IPY = PP+2 +ESP = IPY+1 +JMPTMP = ESP+1 +TMP = JMPTMP+1 +TMPL = TMP +TMPH = TMP+1