From 7c45727eb0297599cc6fd4bc8ccae741e4635513 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Thu, 18 Dec 2014 12:20:20 -0800 Subject: [PATCH] Apple /// support for ROGUE! Bring A1 and A3 AUTORUN inline with A2 --- src/samplesrc/rogue.map.pla | 135 +++++++++++++++++++++++++++++++++++- src/samplesrc/rogue.pla | 53 +++----------- src/vmsrc/a1cmd.pla | 44 +++++++----- src/vmsrc/cmd.pla | 2 + src/vmsrc/soscmd.pla | 85 +++++++++++++---------- 5 files changed, 222 insertions(+), 97 deletions(-) diff --git a/src/samplesrc/rogue.map.pla b/src/samplesrc/rogue.map.pla index 3371f5a..75abdfc 100644 --- a/src/samplesrc/rogue.map.pla +++ b/src/samplesrc/rogue.map.pla @@ -3,8 +3,8 @@ // import STDLIB - predef syscall, call, memset, getc, putc, puts, putln - predef memset, memcpy + predef syscall, call, getc, putc, puts, putln + predef memset, memcpy, modaddr predef heapmark, heapallocallign, heapalloc, heaprelease, heapavail byte MACHID end @@ -12,6 +12,8 @@ end const modkeep = $2000 const modinitkeep = $4000 +byte stdlib[] = "STDLIB" + const FALSE = 0 const TRUE = not FALSE @@ -173,6 +175,107 @@ word = $450, $4D0, $550, $5D0, $650, $6D0, $750, @linebuffer // $7D0 word = @linebuffer, @linebuffer, @linebuffer, @linebuffer, @linebuffer word = @linebuffer, @linebuffer, @linebuffer, @linebuffer, @linebuffer +// +// Machine specific routines +// + +export word rnd +export word getkb +export word tone +export word home +export word gotoxy + +byte noapple1 = "APPLE 1 NOT SUPPORTED." +byte apple2 = "Apple II " +byte apple3 = "Apple /// " + +const SPEAKER = $C030 + +const a2rndnum = $4E // ZP location of RND +const a2rndl = $4E +const a2rndh = $4F + +word a3rndnum = 12345 +byte devcons + +def a3rnd + a3rndnum = (a3rndnum << 1) + a3rndnum + 123 + return *a3rndnum & $7FFF +end + +def a2rnd + *a2rndnum = (*a2rndnum << 1) + *a2rndnum + 123 + return *a2rndnum & $7FFF +end + +def a2getkb + return getc() +end + +def a3tone(duration, pitch) +end + +def a2tone(duration, delay) + byte i + + while duration + ^SPEAKER + for i = 0 to delay + next + duration = duration - 1 + loop +end + +// +// Apple /// console routines +// + +def dev_status(devnum, code, list) + byte params[5] + + params.0 = 3 + params.1 = devnum + params.2 = code + params:3 = list + return syscall($82, @params) +end +def a3keypressed + byte count + dev_status(devcons, 5, @count) + return count +end + +def a3getkb + while not a3keypressed + a3rndnum = a3rndnum + 123 + loop + return getc() +end + +def a3home + return putc(28) +end + +def a3gotoxy(ch, cv) + putc(24) + putc(ch) + putc(25) + return putc(cv) +end + +// +// Apple ][ console routines +// + +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 + // // Load map // @@ -255,7 +358,7 @@ export def drawmap(xorg, yorg, viewfield, viewdir, lightdist, viewdist) // // Clear screen // - call($FC58, 0, 0, 0, 0) + home() // // Draw background map if in light // @@ -737,4 +840,30 @@ export def drawvisentity(xofst, yofst, tile) fin end +// +// Set machine specific routines +// + +when MACHID & $C8 + is $08 // Apple 1 + puts(@noapple1) + return -1 + is $C0 // Apple /// + puts(@apple3) + rnd = @a3rnd + getkb = @a3getkb + home = @a3home + gotoxy = @a3gotoxy + tone = @a3tone + devcons = modaddr(@stdlib).5 // devcons variable from STDLIB + break + otherwise // Apple ][ + puts(@apple2) + rnd = @a2rnd + getkb = @a2getkb + home = @a2home + gotoxy = @a2gotoxy + tone = @a2tone +wend + done \ No newline at end of file diff --git a/src/samplesrc/rogue.pla b/src/samplesrc/rogue.pla index ac23e06..28710f6 100755 --- a/src/samplesrc/rogue.pla +++ b/src/samplesrc/rogue.pla @@ -33,14 +33,12 @@ import ROGUEMAP const MAP_TILE = $7F predef loadmap, getmaptile, setmaptile, updtmaptile, lighttorches, drawmap, drawvisentity + word rnd, getkb, home, gotoxy, tone end const FALSE = 0 const TRUE = not FALSE - -const SPEAKER = $C030 - const maxlight = 10 const maxview = 20 @@ -154,24 +152,6 @@ byte youdiedstr = "You perished inside the catacombs :-(" // Utility functions // -const rndnum = $4E // ZP location of RND -const rndl = $4E -const rndh = $4F - -def rnd - *rndnum = (*rndnum << 1) + *rndnum + 123 - return *rndnum & $7FFF -end - -def home - return call($FC58, 0, 0, 0, 0) -end - -def gotoxy(ch, cv) - ^$24 = ch + ^$20 - return call($FB5B, cv + ^$22, 0, 0, 0) -end - def toupper(c) if c >= 'a' and c <= 'z' c = c - $20 @@ -186,17 +166,6 @@ def abs(i) return i end -def tone(duration, delay) - byte i - - while duration - ^SPEAKER - for i = 0 to delay - next - duration = duration - 1 - loop -end - def ouch tone(128,5) end @@ -289,7 +258,7 @@ def fight(enemy) gotoxy(21, 3) puts(@lifestr); puti(enemy->life) gotoxy(12, 8); puts(@fightstr) - if toupper(getc()) == 'R' + if toupper(getkb()) == 'R' if player.energy > RUN_ENERGY moveplayer(1) fin @@ -298,12 +267,12 @@ def fight(enemy) // // Turn player in random direction // - player.angle = rnd & 7 + player.angle = rnd() & 7 // // Calculate attack (with a little random variation) // - p_atck = player.skill + player.energy / 10 - enemy->power / 25 + (rnd & 7) - e_atck = enemy->power - player.skill / 5 - player.energy / 20 + (rnd & 7) + p_atck = player.skill + player.energy / 10 - enemy->power / 25 + (rnd() & 7) + e_atck = enemy->power - player.skill / 5 - player.energy / 20 + (rnd() & 7) if enemy->life > p_atck enemy->life = enemy->life - p_atck else @@ -543,10 +512,10 @@ def play return FALSE fin gotoxy(xcentr, ycentr) - when toupper(getc) + when toupper(getkb()) is 'I' if totaldarkness - player.angle = rnd & 7 + player.angle = rnd() & 7 else player.angle = 0 fin @@ -554,7 +523,7 @@ def play break is 'J' if totaldarkness - player.angle = rnd & 7 + player.angle = rnd() & 7 else player.angle = 6 fin @@ -562,7 +531,7 @@ def play break is 'K' if totaldarkness - player.angle = rnd & 7 + player.angle = rnd() & 7 else player.angle = 2 fin @@ -570,7 +539,7 @@ def play break is 'M' if totaldarkness - player.angle = rnd & 7 + player.angle = rnd() & 7 else player.angle = 4 fin @@ -672,7 +641,7 @@ def play clearstatus gotoxy(0, statusline) puts(@quitstr) - if toupper(getc) == 'Y' + if toupper(getkb()) == 'Y' player.health = 0 return FALSE fin diff --git a/src/vmsrc/a1cmd.pla b/src/vmsrc/a1cmd.pla index dc47944..6202135 100644 --- a/src/vmsrc/a1cmd.pla +++ b/src/vmsrc/a1cmd.pla @@ -43,13 +43,27 @@ word version = $0010 // 00.10 word systemflags = 0 word heap word symtbl, lastsym -byte perr -word cmdptr +byte perr, refauto +// +// String pool. +// +byte autorun[] = "AUTORUN" +byte verstr[] = "\nPLASMA " +byte freestr[] = "MEM FREE:$" +byte errorstr[] = "ERR:$" +byte prompt[] = "PLASMA" +byte okstr[] = "OK" +byte huhstr[] = "?\n" +byte hexchar[] = '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' // // Exported Machine ID. // 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 stdlibstr[] = "STDLIB" @@ -75,6 +89,7 @@ byte uislestr[] = "ISULE" byte loadstr[] = "MODLOAD" byte execstr[] = "MODEXEC" byte modadrstr[] = "MODADDR" +byte argstr[] = "ARGS" word exports[] = @sysstr, @syscall word = @callstr, @call word = @putcstr, @cout @@ -96,20 +111,10 @@ word = @loadstr, @loadmod word = @execstr, @execmod word = @modadrstr, @lookupstrmod word = @machidstr, @machid +word = @argstr, @cmdptr word = 0 word stdlibsym = @exports // -// String pool. -// -byte autorun[] = "AUTORUN" -byte verstr[] = "\nPLASMA " -byte freestr[] = "MEM FREE:$" -byte errorstr[] = "ERR:$" -byte prompt[] = "PLASMA" -byte okstr[] = "OK" -byte huhstr[] = "?\n" -byte hexchar[] = '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' -// // CALL CFFA1 API ENTRYPOINT // SYSCALL(CMD) // @@ -990,9 +995,14 @@ while *stdlibsym stdlibsym = stdlibsym + 4 loop // -// Try to run autorun module. +// Try to load autorun. // -execmod(@autorun) +cmdptr = heap +memset(cmdptr, 64, 0) +readfile(@autorun, cmdptr + 1) +while ^(cmdptr + ^cmdptr + 1) >= ' ' + ^cmdptr = ^cmdptr + 1 +loop perr = 0 // // Print some startup info. @@ -1009,8 +1019,6 @@ crout // Handle commands. // while 1 - prstr(@prompt) - cmdptr = rdstr($BA) if ^cmdptr when toupper(parsecmd(cmdptr)) is 'Q' @@ -1033,5 +1041,7 @@ while 1 fin crout() fin + prstr(@prompt) + cmdptr = rdstr($BA) loop done diff --git a/src/vmsrc/cmd.pla b/src/vmsrc/cmd.pla index 8765599..5a8f988 100644 --- a/src/vmsrc/cmd.pla +++ b/src/vmsrc/cmd.pla @@ -65,6 +65,7 @@ byte uislestr = "ISULE" byte loadstr = "MODLOAD" byte execstr = "MODEXEC" byte modadrstr = "MODADDR" +byte argstr = "ARGS" word exports = @sysstr, @syscall word = @callstr, @call word = @putcstr, @cout @@ -86,6 +87,7 @@ word = @loadstr, @loadmod word = @execstr, @execmod word = @modadrstr, @lookupstrmod word = @machidstr, MACHID +word = @argstr, $01FF word = 0 word stdlibsym = @exports // diff --git a/src/vmsrc/soscmd.pla b/src/vmsrc/soscmd.pla index c5319e9..4597672 100644 --- a/src/vmsrc/soscmd.pla +++ b/src/vmsrc/soscmd.pla @@ -14,8 +14,8 @@ const resxhgr2 = $0080 // // Module don't free memory // -const modkeep = $1000 -const modinitkeep = $2000 +const modkeep = $2000 +const modinitkeep = $4000 // // SOS flags // @@ -43,12 +43,29 @@ byte modid = 0 byte modseg[15] word symtbl, lastsym byte perr, terr, lerr -word cmdptr +// +// String pool. +// +byte console[] = ".CONSOLE" +byte autorun[] = "AUTORUN" +byte verstr[] = "PLASMA " +byte freestr[] = "MEM FREE:$" +byte errorstr[] = "ERR:$" +byte okstr[] = "OK" +byte huhstr[] = "?\n" +byte devtovol[] = " => /" +byte prefix[64] = "" +byte textmode[] = 16, 0, 15 +byte hexchar[] = '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' // // Exported Machine ID. // byte machid = $F2 // Apple ///, 80 columns // +// Command line pointer +// +word cmdptr = @autorun +// // Standard Library exported functions. // byte stdlibstr[] = "STDLIB" @@ -74,6 +91,7 @@ byte uislestr[] = "ISULE" byte loadstr[] = "MODLOAD" byte execstr[] = "MODEXEC" byte modadrstr[] = "MODADDR" +byte argstr[] = "ARGS" word exports[] = @sysstr, @syscall word = @callstr, @call word = @putcstr, @cout @@ -95,23 +113,10 @@ word = @loadstr, @loadmod word = @execstr, @execmod word = @modadrstr, @lookupstrmod word = @machidstr, @machid +word = @argstr, @cmdptr word = 0 word stdlibsym = @exports // -// String pool. -// -byte console[] = ".CONSOLE" -byte autorun[] = "AUTORUN" -byte verstr[] = "PLASMA " -byte freestr[] = "MEM FREE:$" -byte errorstr[] = "ERR:$" -byte okstr[] = "OK" -byte huhstr[] = "?\n" -byte devtovol[] = " => /" -byte prefix[128] = "" -byte textmode[] = 16, 0, 15 -byte hexchar[] = '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' -// // CALL SOS // SYSCALL(CMD, PARAMS) // @@ -787,7 +792,7 @@ end def cin byte ch read(refcons, @ch, 1) - return ch + return ch & $7F end def prstr(str) write(refcons, str + 1, ^str) @@ -1104,7 +1109,7 @@ def loadmod(mod) if init fixup = adddef(defext, init - defofst + defaddr, @deflast)() fin - return fixup | (systemflags & modkeep) + return fixup end // // Command mode @@ -1210,7 +1215,7 @@ def striptrail(strptr) byte i for i = 1 to ^strptr - if (strptr)[i] == ' ' + if (strptr)[i] <= ' ' ^strptr = i - 1 return fin @@ -1239,15 +1244,15 @@ def execmod(modfile) savesym = lastsym saveflags = systemflags perr = loadmod(@moddci) - if perr >= modkeep - perr = perr & ~modkeep - else + if perr < modkeep lastsym = savesym heap = saveheap while modid modid = modid - 1 seg_release(modseg[modid]) loop + else + perr = perr & ~modkeep fin systemflags = saveflags fin @@ -1270,27 +1275,35 @@ while *stdlibsym stdlibsym = stdlibsym + 4 loop // -// Try to run autorun module. +// Try to load autorun. // -execmod(@autorun) +cmdptr = heap +^cmdptr = 0 +terr = open(@autorun, O_READ) +if terr > 0 + ^cmdptr = read(terr, cmdptr + 1, 64) + close(terr) +fin perr = 0 // // Print some startup info. // -prstr(@verstr) -prbyte(version.1) -cout('.') -prbyte(version.0) -crout -prstr(@freestr) -prword(availheap) -crout +if not ^cmdptr + prstr(@verstr) + prbyte(version.1) + cout('.') + prbyte(version.0) + crout + prstr(@freestr) + prword(availheap) + crout +else + getpfx(@prefix) +fin // // Handle commands. // while 1 - prstr(getpfx(@prefix)) - cmdptr = rdstr($BA) if ^cmdptr when toupper(parsecmd(cmdptr)) is 'Q' @@ -1321,5 +1334,7 @@ while 1 fin crout() fin + prstr(getpfx(@prefix)) + cmdptr = rdstr($BA) loop done