1
0
mirror of https://github.com/dschmenk/PLASMA.git synced 2024-06-17 01:29:31 +00:00

Sometimes a small change has large repercussions

This commit is contained in:
David Schmenk 2018-01-13 11:53:21 -08:00
parent f48d6c5336
commit 87f9be31d8
33 changed files with 520 additions and 611 deletions

View File

@ -2,17 +2,16 @@ import cmdsys
// //
// Useful values for everyone // Useful values for everyone
// //
const _VERSION_ = $0100 const _SYSVER_ = $0100 // Version built against
const FALSE = 0 const FALSE = 0
const TRUE = not FALSE const TRUE = not FALSE
const NULL = 0 const NULL = 0
// //
// Machine ID values // Machine ID values
// //
const MACHID_CLOCK = $01 const MACHID_CLOCK = $01
const MACHID_80COL = $02 const MACHID_80COL = $02
const MACHID_MEM = $03 const MACHID_MEM = $03
const MACHID_48K = $10
const MACHID_64K = $20 const MACHID_64K = $20
const MACHID_128K = $30 const MACHID_128K = $30
const MACHID_MODEL = $C8 const MACHID_MODEL = $C8
@ -24,10 +23,6 @@ import cmdsys
const MACHID_I = $08 const MACHID_I = $08
byte MACHID byte MACHID
// //
// System path
//
byte syspath
//
// System flags: memory allocator screen holes. // System flags: memory allocator screen holes.
// //
const restxt1 = $0001 const restxt1 = $0001
@ -44,12 +39,23 @@ import cmdsys
const modkeep = $2000 const modkeep = $2000
const modinitkeep = $4000 const modinitkeep = $4000
// //
// CMD exported interface table
//
struc t_cmdsys
word sysver
word syspath
word cmdline
word modexec
byte refcons
byte devcons
end
//
// CMD exported functions // CMD exported functions
// //
predef putc(c)#0, putln()#0, puts(s)#0, puti(i)#0, getc()#1, gets(p)#1, toupper(c)#1 predef putc(c)#0, putln()#0, puts(s)#0, puti(i)#0, getc()#1, gets(p)#1, putb(b)#0, puth(h)#0
predef call(addr,areg,xreg,yreg,status)#1, syscall(cmd,params)#1 predef call(addr,areg,xreg,yreg,status)#1, syscall(cmd,params)#1
predef heapmark()#1, heapallocalign(size, pow2, freeaddr)#1, heapalloc(size)#1, heaprelease(newheap)#1, heapavail()#1 predef heapmark()#1, heapallocalign(size, pow2, freeaddr)#1
predef memset(addr,value,size)#0, memcpy(dst,src,size)#0 predef heapalloc(size)#1, heaprelease(newheap)#1, heapavail()#1
predef sext(a)#1, divmod(a,b)#2, isugt(a,b)#1, isuge(a,b)#1, isult(a,b)#1, isule(a,b)#1 predef memset(addr,value,size)#0, memcpy(dst,src,size)#0, strcpy(dst,src)#1, strcat(dst,src)#1
predef modload(mod)#1, modexec(modfile)#1, modaddr(str)#1 predef toupper(c)#1, sext(a)#1, divmod(a,b)#2, isugt(a,b)#1, isuge(a,b)#1, isult(a,b)#1, isule(a,b)#1
end end

View File

@ -1,17 +1,16 @@
import conio import conio
const NORMAL = $FF const NORMAL = $FF
const INVERSE = $3F const INVERSE = $3F
const FLASH = $7F const FLASH = $7F
struc t_conio struc t_conio
word keypressed word keypressed
word home word home
word gotoxy word gotoxy
word viewport word viewport
word texttype word texttype
word textmode word textmode
word grmode word grmode
word grcolor word grcolor
word grplot word grplot
end end
word conio
end end

View File

@ -49,7 +49,6 @@ import fileio
word readblock word readblock
word writeblock word writeblock
end end
word fileio
// //
// Globally accessible error code // Globally accessible error code
// //

View File

@ -112,5 +112,4 @@ struc t_fpu
word randNum word randNum
end end
const dropX = shiftDown // Alias dropX and shiftDown const dropX = shiftDown // Alias dropX and shiftDown
word fpu
end end

View File

@ -1,7 +1,7 @@
// //
// iNet API // iNet API
// //
import inet import iNet
struc t_inet struc t_inet
word initIP word initIP
word serviceIP word serviceIP
@ -19,5 +19,4 @@ struc t_inet
word setCallback word setCallback
word setParam word setParam
end end
word iNet
end end

View File

@ -1,4 +1,4 @@
import longjmp import longjmp
const t_longjmp = $0140 const t_except = $0140
predef setjmp(env), longjmp(env, retval) predef except(env), throw(env, retval)
end end

View File

@ -142,5 +142,4 @@ struc t_sane
word saveZP word saveZP
word restoreZP word restoreZP
end end
word sane
end end

View File

@ -17,7 +17,7 @@ import sdFAT
// //
// Interface // Interface
// //
struc t_fatio struc t_sdFAT
word getDir word getDir
word setDir word setDir
word newDir word newDir
@ -41,5 +41,4 @@ import sdFAT
word isDir word isDir
word isFile word isFile
end end
word sdFAT // sdFAT interface
end end

View File

@ -1,13 +1,12 @@
include "inc/cmdsys.plh" include "inc/cmdsys.plh"
const cmdline = $01FF
def argDelim(str) def argDelim(str)
byte n byte n
// Strip leading spaces // Skip leading spaces
while ^str and ^(str + 1) == ' ' while ^str and ^(str + 1) == ' '
memcpy(str + 1, str + 2, ^str - 1) ^(str + 1) = ^str - 1
^str-- str++
loop loop
// Scan to trailing spaces (if any) // Scan to trailing spaces (if any)
for n = 1 to ^str for n = 1 to ^str
@ -26,9 +25,8 @@ export def argNext(str)
end end
export def argFirst export def argFirst
// NULL terminate command line ^(cmdsys:cmdline + ^cmdsys:cmdline + 1) = NULL
^(cmdline + ^cmdline + 1) = 0 return argDelim(cmdsys:cmdline)
return argDelim(cmdline)
end end
done done

View File

@ -44,7 +44,7 @@ predef a2textmode(cols),a2grmode(mix),a2grcolor(color),a2grplot(x,y)
// //
// Exported function table. // Exported function table.
// //
export word conio[] word conio[]
// //
// Function pointers. // Function pointers.
// //
@ -78,7 +78,6 @@ word = $0850,$08D0,$0950,$09D0,$0A50,$0AD0,$0B50,$0BD0
byte textbwmode[] = 2, 16, 0 byte textbwmode[] = 2, 16, 0
byte textclrmode[] = 2, 16, 1 byte textclrmode[] = 2, 16, 1
byte grcharset[] = 1, 0, $7F, $7F, $7F, $7F, $00, $00, $00, $00 byte grcharset[] = 1, 0, $7F, $7F, $7F, $7F, $00, $00, $00, $00
byte devcons
// //
// Native routines. // Native routines.
// //
@ -247,7 +246,7 @@ def dev_status(devnum, code, list)
end end
def a3keypressed def a3keypressed
byte count byte count
dev_status(devcons, 5, @count) dev_status(cmdsys.devcons, 5, @count)
return count return count
end end
def a3home def a3home
@ -307,7 +306,7 @@ def a3grmode(mix)
mix = 23 mix = 23
fin fin
puts(@textclrmode) puts(@textclrmode)
dev_control(devcons, 17, @grcharset) dev_control(cmdsys.devcons, 17, @grcharset)
a3viewport(0, 20, 40, 4) a3viewport(0, 20, 40, 4)
for i = 0 to mix for i = 0 to mix
memset(txt1scrn[i], 40, $0000) // text screen memset(txt1scrn[i], 40, $0000) // text screen
@ -318,8 +317,8 @@ end
// //
// Machine specific initialization. // Machine specific initialization.
// //
when MACHID & $C8 when MACHID & MACHID_MODEL
is $08 // Apple 1 is MACHID_I
conio:keypressed = @a1keypressed conio:keypressed = @a1keypressed
conio:home = @a1home conio:home = @a1home
conio:gotoxy = @a1gotoxy conio:gotoxy = @a1gotoxy
@ -328,7 +327,7 @@ when MACHID & $C8
conio:textmode = @a1textmode conio:textmode = @a1textmode
conio:grmode = @a1grmode conio:grmode = @a1grmode
break break
is $C0 // Apple /// is MACHID_III
conio:keypressed = @a3keypressed conio:keypressed = @a3keypressed
conio:home = @a3home conio:home = @a3home
conio:gotoxy = @a3gotoxy conio:gotoxy = @a3gotoxy
@ -336,8 +335,7 @@ when MACHID & $C8
conio:texttype = @a3texttype conio:texttype = @a3texttype
conio:textmode = @a3textmode conio:textmode = @a3textmode
conio:grmode = @a3grmode conio:grmode = @a3grmode
devcons = modaddr("CMDSYS").5 // devcons variable from STDLIB
break break
otherwise // Apple ][ //otherwise // MACHID_II
wend wend
done done

View File

@ -653,16 +653,16 @@ fin
// //
// Assembly fixups // Assembly fixups
// //
*(@_dgrPlotPix):1 = @_dgrSetPix _dgrPlotPix:1 = @_dgrSetPix
*(@_dgrHLinPix):1 = @_dgrSetPix _dgrHLinPix:1 = @_dgrSetPix
*(@_dgrVLinPix):1 = @_dgrSetPix _dgrVLinPix:1 = @_dgrSetPix
*(@_dgrBLTPix):1 = @_dgrSetPix _dgrBLTPix:1 = @_dgrSetPix
*(@_dgrTileTile):1 = @dgrTile _dgrTileTile:1 = @dgrTile
*(@_dgrFillTile):1 = @dgrTile _dgrFillTile:1 = @dgrTile
*(@_dgrSetEvnEvn):1 = @evnclr _dgrSetEvnEvn:1 = @evnclr
*(@_dgrSetEvnOdd):1 = @oddclr _dgrSetEvnOdd:1 = @oddclr
*(@_dgrSetOddEvn):1 = @evnclr _dgrSetOddEvn:1 = @evnclr
*(@_dgrSetOddOdd):1 = @oddclr _dgrSetOddOdd:1 = @oddclr
// Put read AUX mem routine in scary location // Put read AUX mem routine in scary location
memcpy($0100, @auxRead, 9) memcpy($0100, @auxRead, 9)
done done

View File

@ -44,9 +44,10 @@ predef a23newline(refnum, emask, nlchar), a2readblock(unit, buf, block), a2write
// //
// Exported function table. // Exported function table.
// //
export word fileio[] = @a2getpfx, @a23setpfx, @a2getfileinfo, @a23geteof, @a2openbuf, @a2open, @a23close word fileio[]
word = @a23read, @a2write, @a2create, @a23destroy word = @a2getpfx, @a23setpfx, @a2getfileinfo, @a23geteof, @a2openbuf, @a2open, @a23close
word = @a23newline, @a2readblock, @a2writeblock word = @a23read, @a2write, @a2create, @a23destroy
word = @a23newline, @a2readblock, @a2writeblock
// //
// SOS/ProDOS error code // SOS/ProDOS error code
// //

View File

@ -22,7 +22,8 @@ predef compXY, annuityXY, randNum(pSeed)
// //
// FP6502 functions // FP6502 functions
// //
export word fpu = @reset //export word fpu = @reset
word fpu = @reset
word = @setEnv, @getEnv, @testExcept, @setExcept, @enterProc, @exitProc word = @setEnv, @getEnv, @testExcept, @setExcept, @enterProc, @exitProc
word = @constPi, @constE word = @constPi, @constE
word = @pushInt, @pushSgl, @pushDbl, @pushExt, @pushStr word = @pushInt, @pushSgl, @pushDbl, @pushExt, @pushStr

View File

@ -4,7 +4,7 @@ end
// //
// Save environment (PLASMA ZP and stack) for below and return 0 // Save environment (PLASMA ZP and stack) for below and return 0
// //
export asm setjmp(env) export asm except(env)
LDA ESTKL,X LDA ESTKL,X
STA SRC STA SRC
LDA ESTKH,X LDA ESTKH,X
@ -33,7 +33,7 @@ end
// //
// Restore environment saved above and return retval // Restore environment saved above and return retval
// //
export asm longjmp(env, retval) export asm throw(env, retval)
LDA ESTKL,X LDA ESTKL,X
STA SRC STA SRC
LDA ESTKH,X LDA ESTKH,X

View File

@ -16,7 +16,8 @@ end
// External interface to SANE libraries // External interface to SANE libraries
// //
predef fpInit(), fpDefaultHalt(pstatus), uninit0(), uninit1(op, dst), uninit2(op, dst, src), uninit3(op, dst, src, src2) predef fpInit(), fpDefaultHalt(pstatus), uninit0(), uninit1(op, dst), uninit2(op, dst, src), uninit3(op, dst, src, src2)
export word sane = @fpInit, @fpDefaultHalt, @uninit0, @uninit1, @uninit2, @uninit3, @uninit1, @uninit2, @uninit3, @uninit0, @uninit0 //export word sane = @fpInit, @fpDefaultHalt, @uninit0, @uninit1, @uninit2, @uninit3, @uninit1, @uninit2, @uninit3, @uninit0, @uninit0
word sane = @fpInit, @fpDefaultHalt, @uninit0, @uninit1, @uninit2, @uninit3, @uninit1, @uninit2, @uninit3, @uninit0, @uninit0
// //
// Pointer to FP6502 entry // Pointer to FP6502 entry
// //
@ -720,16 +721,6 @@ end
// loop // loop
// loop // loop
//end //end
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
// //
// Load Pascal CODE file // Load Pascal CODE file
// //
@ -740,7 +731,7 @@ def loadcode(codefile)
//puts(codefile); puts(":\n") //puts(codefile); puts(":\n")
pcode = 0 pcode = 0
ref = fileio:open(strcat(strcpy(@filepath, @syspath), codefile)) ref = fileio:open(strcat(strcpy(@filepath, cmdsys:syspath), codefile))
//puts("ref = "); prbyte(ref); puts(" perr = "); prbyte(perr); putln //puts("ref = "); prbyte(ref); puts(" perr = "); prbyte(perr); putln
if ref if ref
pcode = heapmark pcode = heapmark

View File

@ -77,7 +77,7 @@ end
// //
// String functions // String functions
// //
def strcat(dst, src1, src2) def strcat2(dst, src1, src2)
memcpy(dst + 1, src1 + 1, ^src1) memcpy(dst + 1, src1 + 1, ^src1)
memcpy(dst + 1 + ^src1, src2 + 1, ^src2) memcpy(dst + 1 + ^src1, src2 + 1, ^src2)
^dst = ^src1 + ^src2 ^dst = ^src1 + ^src2
@ -141,7 +141,7 @@ def servHTTP(remip, remport, lclport, data, len, param)
url = url + 1 url = url + 1
fin fin
fin fin
strcat(@filename, @prefix, url) strcat2(@filename, @prefix, url)
puts("GET:"); puts(@filename);putln puts("GET:"); puts(@filename);putln
// //
// Get file info // Get file info
@ -152,9 +152,9 @@ def servHTTP(remip, remport, lclport, data, len, param)
if refnum // file was opened OK if refnum // file was opened OK
filelen = fileio:geteof(refnum) // get length of file for Content-Length filelen = fileio:geteof(refnum) // get length of file for Content-Length
lenstr = itos(@lenstr + 1, filelen) - (@lenstr + 1) lenstr = itos(@lenstr + 1, filelen) - (@lenstr + 1)
strcat(@okhdr, @httpOK, @httpContentLen) strcat2(@okhdr, @httpOK, @httpContentLen)
strcat(@okhdr, @okhdr, @lenstr) strcat2(@okhdr, @okhdr, @lenstr)
strcat(@okhdr, @okhdr, "\n\r") strcat2(@okhdr, @okhdr, "\n\r")
// //
// Content type header // Content type header
// //
@ -163,23 +163,23 @@ def servHTTP(remip, remport, lclport, data, len, param)
// this a text file // this a text file
// //
//puts(@mimeTextHtml) // debug //puts(@mimeTextHtml) // debug
strcat(@okhdr, @okhdr, @httpContentType) strcat2(@okhdr, @okhdr, @httpContentType)
strcat(@okhdr, @okhdr, @mimeTextHtml) strcat2(@okhdr, @okhdr, @mimeTextHtml)
else else
// //
// send as binary attachment // send as binary attachment
// //
//puts(@mimeOctetStream) // debug //puts(@mimeOctetStream) // debug
strcat(@okhdr, @okhdr, @httpContentType) strcat2(@okhdr, @okhdr, @httpContentType)
strcat(@okhdr, @okhdr, @mimeOctetStream) strcat2(@okhdr, @okhdr, @mimeOctetStream)
strcat(@okhdr, @okhdr, "\n\r") strcat2(@okhdr, @okhdr, "\n\r")
// //
// and send filename too // and send filename too
// //
strcat(@okhdr, @okhdr, @httpContentAttach) strcat2(@okhdr, @okhdr, @httpContentAttach)
// todo: get the base filename... // todo: get the base filename...
fin fin
strcat(@okhdr, @okhdr, @httpEnd) strcat2(@okhdr, @okhdr, @httpEnd)
//dumpchars(@okhdr + 1, okhdr) // debug //dumpchars(@okhdr + 1, okhdr) // debug
iNet:sendTCP(socketHTTP, @okhdr + 1, okhdr) // send HTTP response header to client iNet:sendTCP(socketHTTP, @okhdr + 1, okhdr) // send HTTP response header to client
sendFile(refnum, socketHTTP, filelen) // send file data to client sendFile(refnum, socketHTTP, filelen) // send file data to client

View File

@ -3,13 +3,6 @@ include "inc/memmgr.plh"
word a, b, c, d, e, memptr word a, b, c, d, e, memptr
word memfre, memlrgst word memfre, memlrgst
def putb(hexb)
return call($FDDA, hexb, 0, 0, 0)
end
def puth(hex)
return call($F941, hex >> 8, hex, 0, 0)
end
sbrk($3000) // Set small pool size sbrk($3000) // Set small pool size
memfre=hmemFre(@memlrgst);puth(memfre); putc(' '); puth(memlrgst); putln memfre=hmemFre(@memlrgst);puth(memfre); putc(' '); puth(memlrgst); putln

View File

@ -3,17 +3,15 @@ include "inc/cmdsys.plh"
const modkeep = $2000 const modkeep = $2000
const modinitkeep = $4000 const modinitkeep = $4000
byte cmdsys = "cmdsys"
byte[] initstr byte[] initstr
byte = " ( )\n" byte = " ( )\n"
byte = " )\\ ) ( /( (\n" byte = " )\\ ) ( /( (\n"
byte = "(()/( )\\()) )\\ ) ( (\n" byte = " (()/( )\\()) )\\ ) ( (\n"
byte = " /(_))((_)\\ (()/( )\\ )\\\n" byte = " /(_))((_)\\ (()/( )\\ )\\\n"
byte = "(_)) ((_) /(_))_ _ ((_)((_)\n" byte = "(_)) ((_) /(_))_ _ ((_)((_)\n"
byte = "| _ \\ / _ \\(_)) __|| | | || __|\n" byte = "| _ \\ / _ \\(_)) __| | | | || __|\n"
byte = "| / | (_) | | (_ || |_| || _|\n" byte = "| / | (_) | || (_ | |_| || _|\n"
byte = "|_|_\\ \\___/ \\___| \\___/ |___|\n" byte = "|_|_\\\\___/ \\___| \\___/ |___|\n"
byte = "\n" byte = "\n"
byte = " By Resman\n" byte = " By Resman\n"
byte = " Artwork by Seth Sternberger\n" byte = " Artwork by Seth Sternberger\n"
@ -40,7 +38,6 @@ const a2rndh = $4F
word iobuff word iobuff
word a3rndnum = 12345 word a3rndnum = 12345
byte devcons
def a3rnd def a3rnd
a3rndnum = (a3rndnum << 1) + a3rndnum + 123 a3rndnum = (a3rndnum << 1) + a3rndnum + 123
@ -182,7 +179,7 @@ def dev_status(devnum, code, list)
end end
def a3keypressed def a3keypressed
byte count byte count
dev_status(devcons, 5, @count) dev_status(cmdsys.devcons, 5, @count)
return count return count
end end
@ -233,7 +230,6 @@ when MACHID & $C8
home = @a3home home = @a3home
gotoxy = @a3gotoxy gotoxy = @a3gotoxy
tone = @a3tone tone = @a3tone
devcons = modaddr(@cmdsys).5 // devcons variable from cmdsys
open = @a3open open = @a3open
read = @a3read read = @a3read
close = @a3close close = @a3close

View File

@ -297,7 +297,7 @@ iB = 4
iC = -1 iC = -1
zero = 0 zero = 0
puts("SANE sanity test...\n") puts("SANE sanity test...\n")
sane.initFP() sane:initFP()
sane:saveZP() sane:saveZP()
sane:op2FP(FFINT|FOZ2X, @xT, @iA) // Convert int A to ext T sane:op2FP(FFINT|FOZ2X, @xT, @iA) // Convert int A to ext T
sane:op2FP(FFINT|FOADD, @xT, @iB) // Add int B to ext T sane:op2FP(FFINT|FOADD, @xT, @iB) // Add int B to ext T

View File

@ -5,14 +5,14 @@ include "inc/cmdsys.plh"
// //
// Module data. // Module data.
// //
predef puth(h)#0 predef puthex(h)#0
export word print[] = @puti, @puth, @putln, @puts, @putc export word print[] = @puti, @puthex, @putln, @puts, @putc
byte valstr[] = '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' byte valstr[] = '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
byte loadstr[] = "testlib loaded!" byte loadstr[] = "testlib loaded!"
// //
// Define functions. // Define functions.
// //
def puth(h)#0 def puthex(h)#0
putc('$') putc('$')
putc(valstr[(h >> 12) & $0F]) putc(valstr[(h >> 12) & $0F])
putc(valstr[(h >> 8) & $0F]) putc(valstr[(h >> 8) & $0F])

View File

@ -449,7 +449,10 @@ void emit_moddep(char *name, int len)
if (outflags & MODULE) if (outflags & MODULE)
{ {
if (name) if (name)
{
emit_dci(name, len); emit_dci(name, len);
idglobal_add(name, len, EXTERN_TYPE | WORD_TYPE, 2); // Add to symbol table
}
else else
printf("\t%s\t$00\t\t\t; END OF MODULE DEPENDENCIES\n", DB); printf("\t%s\t$00\t\t\t; END OF MODULE DEPENDENCIES\n", DB);
} }
@ -989,7 +992,6 @@ int try_dupify(t_opseq *op)
{ {
if (op->code != opn->code) if (op->code != opn->code)
return crunched; return crunched;
switch (op->code) switch (op->code)
{ {
case CONST_CODE: case CONST_CODE:
@ -1005,19 +1007,16 @@ int try_dupify(t_opseq *op)
case GADDR_CODE: case GADDR_CODE:
case LAB_CODE: case LAB_CODE:
case LAW_CODE: case LAW_CODE:
if ((op->tag != opn->tag) || (op->offsz != opn->offsz) || if ((op->tag != opn->tag) || (op->offsz != opn->offsz) /*|| (op->type != opn->type)*/)
(op->type != opn->type))
return crunched; return crunched;
break; break;
default: default:
return crunched; return crunched;
} }
opn->code = DUP_CODE; opn->code = DUP_CODE;
crunched = 1; crunched = 1;
} }
return crunched; return crunched;
} }
/* /*

View File

@ -1,29 +1,4 @@
// //
// Symbol table
//
//def dumpsym(idptr, idcnt)#0
// while idcnt
// prword(idptr=>idval)
// cout(' ')
// prbyte(idptr->idtype)
// cout(' ')
// prstr(@idptr->idname)
// cout('=')
// if idptr->idtype & ADDR_TYPE
// if idptr=>idval & IS_CTAG
// prword((ctag_tbl=>[idptr=>idval & MASK_CTAG] & MASK_CTAG) + codebuff)
// else
// prword(idptr=>idval + codebuff)
// fin
// else
// prword(idptr=>idval)
// fin
// crout
// idptr = idptr + idptr->idname + t_id
// idcnt--
// loop
//end
//
// Address tags // Address tags
// //
def new_tag(type) def new_tag(type)
@ -564,10 +539,11 @@ end
// //
// Module dependency list // Module dependency list
// //
def new_moddep(strptr, strlen)#0 def new_moddep(nameptr, len)#0
if strlen > 15; strlen = 15; fin if len > 15; len = 15; fin
memcpy(@moddep_tbl[moddep_cnt*16] + 1, strptr, strlen) new_iddata(nameptr, len, EXTERN_TYPE|WORD_TYPE, 2)
moddep_tbl[moddep_cnt*16] = strlen memcpy(@moddep_tbl[moddep_cnt*16] + 1, nameptr, len)
moddep_tbl[moddep_cnt*16] = len
moddep_cnt++ moddep_cnt++
if moddep_cnt > 8; parse_warn("Module dependency overflow"); fin if moddep_cnt > 8; parse_warn("Module dependency overflow"); fin
end end

View File

@ -193,7 +193,7 @@ def strpoolalloc(size)
return 0 return 0
end end
def strcpy(dststr, srcstr)#0 def strstripcpy(dststr, srcstr)#0
byte strlen byte strlen
strlen = ^srcstr strlen = ^srcstr
@ -681,7 +681,7 @@ def joinline#0
byte joinstr[80], joinlen byte joinstr[80], joinlen
if cursrow < numlines - 1 if cursrow < numlines - 1
strcpy(@joinstr, strlinbuf=>[cursrow]) strstripcpy(@joinstr, strlinbuf=>[cursrow])
joinlen = joinstr + ^(strlinbuf=>[cursrow + 1]) joinlen = joinstr + ^(strlinbuf=>[cursrow + 1])
if joinlen < 80 if joinlen < 80
memcpy(@joinstr + joinstr + 1, strlinbuf=>[cursrow + 1] + 1, ^(strlinbuf=>[cursrow + 1])) memcpy(@joinstr + joinstr + 1, strlinbuf=>[cursrow + 1] + 1, ^(strlinbuf=>[cursrow + 1]))
@ -743,7 +743,7 @@ def editline(key)
if (editkey(key)) if (editkey(key))
flags = flags | changed flags = flags | changed
memset(@editstr, $A0A0, 80) memset(@editstr, $A0A0, 80)
strcpy(@editstr, strlinbuf=>[cursrow]) strstripcpy(@editstr, strlinbuf=>[cursrow])
undoline = strlinbuf=>[cursrow] undoline = strlinbuf=>[cursrow]
strlinbuf=>[cursrow] = @editstr strlinbuf=>[cursrow] = @editstr
repeat repeat
@ -802,7 +802,7 @@ def editline(key)
fin fin
elsif key == keyctrld elsif key == keyctrld
if curscol < editstr if curscol < editstr
strcpy(undoline, @editstr) strstripcpy(undoline, @editstr)
memcpy(@editstr[curscol + 1], @editstr[curscol + 2], editstr - curscol) memcpy(@editstr[curscol + 1], @editstr[curscol + 2], editstr - curscol)
editstr-- editstr--
cursoff cursoff
@ -810,7 +810,7 @@ def editline(key)
curson curson
fin fin
elsif key == keyctrlr elsif key == keyctrlr
strcpy(@editstr, undoline) strstripcpy(@editstr, undoline)
cursoff cursoff
drawrow(cursy, scrnleft, @editstr) drawrow(cursy, scrnleft, @editstr)
curson curson
@ -918,7 +918,7 @@ def prfiles(optpath)
word databuff, entry, filecnt word databuff, entry, filecnt
if ^optpath if ^optpath
strcpy(@path, optpath) strstripcpy(@path, optpath)
else else
fileio:getpfx(@path) fileio:getpfx(@path)
puts(@path) puts(@path)
@ -1016,7 +1016,7 @@ def cmdmode#0
if chkchng if chkchng
inittxtbuf inittxtbuf
numlines = 0 numlines = 0
strcpy(@filename, cmdptr) strstripcpy(@filename, cmdptr)
readtxt(@filename) readtxt(@filename)
if numlines == 0; numlines = 1; fin if numlines == 0; numlines = 1; fin
flags = flags & ~changed flags = flags & ~changed
@ -1024,7 +1024,7 @@ def cmdmode#0
break break
is 'W' is 'W'
if ^cmdptr if ^cmdptr
strcpy(@filename, cmdptr) strstripcpy(@filename, cmdptr)
fin fin
writetxt(@filename) writetxt(@filename)
//if flags & changed; fin //if flags & changed; fin
@ -1050,7 +1050,7 @@ def cmdmode#0
is 'N' is 'N'
if chkchng if chkchng
inittxtbuf inittxtbuf
strcpy(@filename, "UNTITLED") strstripcpy(@filename, "UNTITLED")
fin fin
break break
otherwise otherwise
@ -1078,7 +1078,7 @@ else
fin fin
inittxtbuf inittxtbuf
arg = argNext(argFirst) arg = argNext(argFirst)
if arg if ^arg
strcpy(@filename, arg) strcpy(@filename, arg)
puts(@filename) puts(@filename)
numlines = 0 numlines = 0

View File

@ -49,6 +49,7 @@ t_token keywords[] = {
LOGIC_OR_TOKEN, 'O', 'R', LOGIC_OR_TOKEN, 'O', 'R',
BYTE_TOKEN, 'B', 'Y', 'T', 'E', BYTE_TOKEN, 'B', 'Y', 'T', 'E',
BYTE_TOKEN, 'C', 'H', 'A', 'R', BYTE_TOKEN, 'C', 'H', 'A', 'R',
BYTE_TOKEN, 'R', 'E', 'S',
WORD_TOKEN, 'W', 'O', 'R', 'D', WORD_TOKEN, 'W', 'O', 'R', 'D',
WORD_TOKEN, 'V', 'A', 'R', WORD_TOKEN, 'V', 'A', 'R',
CONST_TOKEN, 'C', 'O', 'N', 'S', 'T', CONST_TOKEN, 'C', 'O', 'N', 'S', 'T',

View File

@ -316,7 +316,7 @@ end
// Get next line of input // Get next line of input
// //
def nextln def nextln
strconstptr = @strconst // Reset string constant buffer strconstptr = strconstbuff // Reset string constant buffer
if ^scanptr == ';' if ^scanptr == ';'
scanptr++ scanptr++
scan scan
@ -358,7 +358,7 @@ def nextln
lineno = srcline lineno = srcline
return nextln return nextln
else else
*instr = 0 *instr = NULL // NULL terminated 0 length string
token = EOF_TKN token = EOF_TKN
fin fin
fin fin

View File

@ -366,11 +366,11 @@ t_opseq *parse_value(t_opseq *codeseq, int rvalue, int *stackdepth)
} }
else if (scantoken == BPTR_TOKEN || scantoken == WPTR_TOKEN) else if (scantoken == BPTR_TOKEN || scantoken == WPTR_TOKEN)
{ {
deref++; if (type & BPTR_TYPE)
if (!type)
type |= scantoken == BPTR_TOKEN ? BPTR_TYPE : WPTR_TYPE;
else if (scantoken == BPTR_TOKEN)
parse_error("Byte value used as pointer"); parse_error("Byte value used as pointer");
else
type = scantoken == BPTR_TOKEN ? BPTR_TYPE : WPTR_TYPE;
deref++;
} }
else if (scantoken == NEG_TOKEN || scantoken == COMP_TOKEN || scantoken == LOGIC_NOT_TOKEN) else if (scantoken == NEG_TOKEN || scantoken == COMP_TOKEN || scantoken == LOGIC_NOT_TOKEN)
{ {
@ -396,28 +396,29 @@ t_opseq *parse_value(t_opseq *codeseq, int rvalue, int *stackdepth)
if (scantoken == INT_TOKEN || scantoken == CHAR_TOKEN) if (scantoken == INT_TOKEN || scantoken == CHAR_TOKEN)
{ {
value = constval; value = constval;
type |= CONST_TYPE;
valseq = gen_const(NULL, value); valseq = gen_const(NULL, value);
deref--;
} }
else if (scantoken == ID_TOKEN) else if (scantoken == ID_TOKEN)
{ {
if ((type |= id_type(tokenstr, tokenlen)) & CONST_TYPE) if ((type |= id_type(tokenstr, tokenlen)) & CONST_TYPE)
{ {
value = id_const(tokenstr, tokenlen); value = id_const(tokenstr, tokenlen);
valseq = gen_const(NULL, value); valseq = gen_const(NULL, value);
deref--;
} }
else //if (type & (VAR_TYPE | FUNC_TYPE)) else
{ {
value = id_tag(tokenstr, tokenlen); value = id_tag(tokenstr, tokenlen);
if (type & LOCAL_TYPE) if (type & LOCAL_TYPE)
valseq = gen_lcladr(NULL, value); valseq = gen_lcladr(NULL, value);
else else
valseq = gen_gbladr(NULL, value, type); valseq = gen_gbladr(NULL, value, type);
} if (type & FUNC_TYPE)
if (type & FUNC_TYPE) {
{ cfnparms = funcparms_cnt(type);
cfnparms = funcparms_cnt(type); cfnvals = funcvals_cnt(type);
cfnvals = funcvals_cnt(type); }
} }
} }
else if (scantoken == LAMBDA_TOKEN) else if (scantoken == LAMBDA_TOKEN)
@ -427,9 +428,9 @@ t_opseq *parse_value(t_opseq *codeseq, int rvalue, int *stackdepth)
release_seq(uopseq); release_seq(uopseq);
return (codeseq); return (codeseq);
} }
type |= CONST_TYPE; value = parse_lambda();
value = parse_lambda();
valseq = gen_gbladr(NULL, value, FUNC_TYPE); valseq = gen_gbladr(NULL, value, FUNC_TYPE);
deref--;
} }
else if (scantoken == OPEN_PAREN_TOKEN) else if (scantoken == OPEN_PAREN_TOKEN)
{ {
@ -437,6 +438,7 @@ t_opseq *parse_value(t_opseq *codeseq, int rvalue, int *stackdepth)
parse_error("Bad expression in parenthesis"); parse_error("Bad expression in parenthesis");
if (scantoken != CLOSE_PAREN_TOKEN) if (scantoken != CLOSE_PAREN_TOKEN)
parse_error("Missing closing parenthesis"); parse_error("Missing closing parenthesis");
deref--;
} }
else if (scantoken == DROP_TOKEN) else if (scantoken == DROP_TOKEN)
{ {
@ -482,18 +484,19 @@ t_opseq *parse_value(t_opseq *codeseq, int rvalue, int *stackdepth)
} }
else else
scan_rewind(tokenstr); scan_rewind(tokenstr);
if (type & (VAR_TYPE | PTR_TYPE)) if (type & WORD_TYPE)
{
valseq = gen_lw(valseq); valseq = gen_lw(valseq);
if (deref) else if (type & BYTE_TYPE)
deref--; parse_error("Using BYTE value as a pointer");
} else
deref++;
} }
valseq = gen_icall(valseq); valseq = gen_icall(valseq);
if (stackdepth) if (stackdepth)
*stackdepth += cfnvals - 1; *stackdepth += cfnvals - 1;
cfnparms = 0; cfnvals = 1; cfnparms = 0; cfnvals = 1;
type &= ~(FUNC_TYPE | VAR_TYPE); type &= PTR_TYPE;
deref--;
} }
else if (scantoken == OPEN_BRACKET_TOKEN) else if (scantoken == OPEN_BRACKET_TOKEN)
{ {
@ -506,24 +509,26 @@ t_opseq *parse_value(t_opseq *codeseq, int rvalue, int *stackdepth)
* Function address dereference * Function address dereference
*/ */
cfnparms = 0; cfnvals = 1; cfnparms = 0; cfnvals = 1;
type = BPTR_TYPE;
} }
while ((valseq = parse_expr(valseq, stackdepth)) && scantoken == COMMA_TOKEN) while ((valseq = parse_expr(valseq, stackdepth)) && scantoken == COMMA_TOKEN)
{ {
valseq = gen_idxw(valseq); valseq = gen_idxw(valseq);
valseq = gen_lw(valseq); valseq = gen_lw(valseq); // Multi-dimenstion arrays are array pointers to arrays
} }
if (scantoken != CLOSE_BRACKET_TOKEN) if (scantoken != CLOSE_BRACKET_TOKEN)
parse_error("Missing closing bracket"); parse_error("Missing closing bracket");
if (type & (WPTR_TYPE | WORD_TYPE)) if (type & WORD_TYPE)
{ {
valseq = gen_idxw(valseq); valseq = gen_idxw(valseq);
type = (type & PTR_TYPE) | WORD_TYPE;
} }
else else
{ {
valseq = gen_idxb(valseq); valseq = gen_idxb(valseq);
type = (type & PTR_TYPE) | BYTE_TYPE; if (!(type & BYTE_TYPE))
{
type = (type & PTR_TYPE) | BYTE_TYPE;
deref++;
}
} }
} }
else if (scantoken == PTRB_TOKEN || scantoken == PTRW_TOKEN) else if (scantoken == PTRB_TOKEN || scantoken == PTRW_TOKEN)
@ -542,16 +547,19 @@ t_opseq *parse_value(t_opseq *codeseq, int rvalue, int *stackdepth)
if (stackdepth) if (stackdepth)
*stackdepth += cfnvals - 1; *stackdepth += cfnvals - 1;
cfnparms = 0; cfnvals = 1; cfnparms = 0; cfnvals = 1;
type &= ~FUNC_TYPE;
} }
else if (type & (VAR_TYPE | PTR_TYPE)) else if (type & WORD_TYPE)
{ {
/* /*
* Pointer dereference * Pointer dereference
*/ */
valseq = gen_lw(valseq); valseq = gen_lw(valseq);
} }
type = (scantoken == PTRB_TOKEN) ? BPTR_TYPE : WPTR_TYPE; else if (type & BYTE_TYPE)
parse_error("Using BYTE value as a pointer");
else
deref++;
type = (type & PTR_TYPE) | (scantoken == PTRB_TOKEN) ? BYTE_TYPE : WORD_TYPE; // Type override
if (!parse_const(&const_offset)) if (!parse_const(&const_offset))
{ {
/* /*
@ -579,11 +587,10 @@ t_opseq *parse_value(t_opseq *codeseq, int rvalue, int *stackdepth)
* Function address dereference * Function address dereference
*/ */
cfnparms = 0; cfnvals = 1; cfnparms = 0; cfnvals = 1;
type = 0;
} }
type = (type & (VAR_TYPE | CONST_TYPE)) else if (!(type & VAR_TYPE))
? ((scantoken == DOT_TOKEN) ? BYTE_TYPE : WORD_TYPE) deref++;
: ((scantoken == DOT_TOKEN) ? BPTR_TYPE : WPTR_TYPE); type = (type & PTR_TYPE) | ((scantoken == DOT_TOKEN) ? BYTE_TYPE : WORD_TYPE); // Type override
if (!parse_const(&const_offset)) if (!parse_const(&const_offset))
{ {
/* /*
@ -603,12 +610,20 @@ t_opseq *parse_value(t_opseq *codeseq, int rvalue, int *stackdepth)
else else
break; break;
} }
/*
* Probably parsing RVALUE as LVALUE
*/
if (deref < 0)
{
release_seq(valseq);
release_seq(uopseq);
return (NULL);
}
/* /*
* Resolve outstanding dereference pointer loads * Resolve outstanding dereference pointer loads
*/ */
while (deref > rvalue) while (deref > rvalue)
{ {
deref--;
if (type & FUNC_TYPE) if (type & FUNC_TYPE)
{ {
if (cfnparms) if (cfnparms)
@ -619,8 +634,11 @@ t_opseq *parse_value(t_opseq *codeseq, int rvalue, int *stackdepth)
cfnparms = 0; cfnvals = 1; cfnparms = 0; cfnvals = 1;
type &= ~FUNC_TYPE; type &= ~FUNC_TYPE;
} }
else if (type & VAR_TYPE) else //if (type & VAR_TYPE)
valseq = gen_lw(valseq); valseq = gen_lw(valseq);
//else
// {fprintf(stderr,"deref=%d",deref);parse_error("What are we dereferencing #1?");}
deref--;
} }
if (deref) if (deref)
{ {
@ -638,6 +656,8 @@ t_opseq *parse_value(t_opseq *codeseq, int rvalue, int *stackdepth)
valseq = gen_lb(valseq); valseq = gen_lb(valseq);
else if (type & (WORD_TYPE | WPTR_TYPE)) else if (type & (WORD_TYPE | WPTR_TYPE))
valseq = gen_lw(valseq); valseq = gen_lw(valseq);
else
parse_error("What are we dereferencing?");
} }
/* /*
* Output pre-operations * Output pre-operations
@ -657,6 +677,8 @@ t_opseq *parse_value(t_opseq *codeseq, int rvalue, int *stackdepth)
release_seq(valseq); release_seq(valseq);
return (NULL); // Function or const cannot be LVALUE, must be RVALUE return (NULL); // Function or const cannot be LVALUE, must be RVALUE
} }
if (stackdepth)
*stackdepth--;
} }
return (cat_seq(codeseq, valseq)); return (cat_seq(codeseq, valseq));
} }
@ -1039,10 +1061,13 @@ int parse_stmnt(void)
{ {
if (!(seq = parse_expr(NULL, &cfnvals))) if (!(seq = parse_expr(NULL, &cfnvals)))
emit_const(0); emit_const(0);
else if (cfnvals > 1) else
{ {
parse_warn("Expression value overflow"); if (cfnvals > 1)
while (cfnvals-- > 1) seq = gen_drop(seq); {
parse_warn("Expression value overflow");
while (cfnvals-- > 1) seq = gen_drop(seq);
}
emit_seq(seq); emit_seq(seq);
} }
emit_ret(); emit_ret();
@ -1141,13 +1166,18 @@ int parse_var(int type, long basesize)
else else
parse_error("Bad variable initializer"); parse_error("Bad variable initializer");
} }
else if (idlen) else
id_add(idstr, idlen, type, size); {
if (idlen)
id_add(idstr, idlen, type, size);
else
emit_data(0, 0, 0, size);
}
return (1); return (1);
} }
int parse_struc(void) int parse_struc(void)
{ {
long size; long basesize, size;
int type, constsize, offset = 0; int type, constsize, offset = 0;
char *idstr, strucid[80]; char *idstr, strucid[80];
int idlen = 0, struclen = 0; int idlen = 0, struclen = 0;
@ -1163,18 +1193,19 @@ int parse_struc(void)
{ {
if (scantoken == EOL_TOKEN) if (scantoken == EOL_TOKEN)
continue; continue;
size = 1; basesize = 1;
type = scantoken == BYTE_TOKEN ? BYTE_TYPE : WORD_TYPE; type = scantoken == BYTE_TOKEN ? BYTE_TYPE : WORD_TYPE;
if (scan() == OPEN_BRACKET_TOKEN) if (scan() == OPEN_BRACKET_TOKEN)
{ {
size = 0; basesize = 0;
parse_constexpr(&size, &constsize); parse_constexpr(&basesize, &constsize);
if (scantoken != CLOSE_BRACKET_TOKEN) if (scantoken != CLOSE_BRACKET_TOKEN)
parse_error("Missing closing bracket"); parse_error("Missing closing bracket");
scan(); scan();
} }
do do
{ {
size = 1;
idlen = 0; idlen = 0;
if (scantoken == ID_TOKEN) if (scantoken == ID_TOKEN)
{ {
@ -1189,6 +1220,7 @@ int parse_struc(void)
scan(); scan();
} }
} }
size *= basesize;
if (type & WORD_TYPE) if (type & WORD_TYPE)
size *= 2; size *= 2;
if (idlen) if (idlen)

View File

@ -228,8 +228,8 @@ def parse_list#2
return listseq, listdepth return listseq, listdepth
end end
def parse_value(codeseq, rvalue)#2 def parse_value(codeseq, rvalue)#2
byte cfnparms, cfnvals, stackdepth, deref, operation byte cfnparms, cfnvals, stackdepth, operation
word type, optos, idptr, value, const_offset word deref, type, optos, idptr, value, const_offset
word uopseq, valseq, idxseq word uopseq, valseq, idxseq
deref = rvalue deref = rvalue
@ -256,12 +256,10 @@ def parse_value(codeseq, rvalue)#2
if not rvalue; exit_err(ERR_INVAL|ERR_SYNTAX); fin if not rvalue; exit_err(ERR_INVAL|ERR_SYNTAX); fin
break break
is BPTR_TKN is BPTR_TKN
deref++
type = type | BPTR_TYPE
break
is WPTR_TKN is WPTR_TKN
if type & BPTR_TYPE; exit_err(ERR_INVAL|ERR_SYNTAX); fin
type = token == BPTR_TKN ?? BPTR_TYPE :: WPTR_TYPE
deref++ deref++
type = type | WPTR_TYPE
break break
is AT_TKN is AT_TKN
if not deref; exit_err(ERR_INVAL|ERR_SYNTAX); fin if not deref; exit_err(ERR_INVAL|ERR_SYNTAX); fin
@ -278,24 +276,25 @@ def parse_value(codeseq, rvalue)#2
is ID_TKN is ID_TKN
idptr = lookup_id(tknptr, tknlen) idptr = lookup_id(tknptr, tknlen)
if not idptr; return codeseq, 0; fin if not idptr; return codeseq, 0; fin
if not idptr=>idtype; return codeseq, 0; fin if not idptr=>idtype; return codeseq, 0; fin // DEBUG
type = type | idptr=>idtype type = type | idptr=>idtype
value = idptr=>idval value = idptr=>idval
if type & CONST_TYPE if type & CONST_TYPE
valseq = gen_const(NULL, value) valseq = gen_const(NULL, value)
deref--
else else
valseq = type & LOCAL_TYPE ?? gen_oplcl(NULL, LADDR_CODE, value) :: gen_opglbl(NULL, GADDR_CODE, value, 0) valseq = type & LOCAL_TYPE ?? gen_oplcl(NULL, LADDR_CODE, value) :: gen_opglbl(NULL, GADDR_CODE, value, 0)
fin if type & FUNC_TYPE
if type & FUNC_TYPE cfnparms = idptr->funcparms
cfnparms = idptr->funcparms cfnvals = idptr->funcvals
cfnvals = idptr->funcvals fin
fin fin
break break
is INT_TKN is INT_TKN
is CHR_TKN is CHR_TKN
value = constval value = constval
type = type | CONST_TYPE
valseq = gen_const(NULL, value) valseq = gen_const(NULL, value)
deref--
break break
is STR_TKN is STR_TKN
codeseq = gen_str(codeseq, constval) codeseq = gen_str(codeseq, constval)
@ -305,6 +304,7 @@ def parse_value(codeseq, rvalue)#2
is OPEN_PAREN_TKN is OPEN_PAREN_TKN
valseq, stackdepth = parse_expr(NULL) valseq, stackdepth = parse_expr(NULL)
if token <> CLOSE_PAREN_TKN; exit_err(ERR_MISS|ERR_CLOSE|ERR_SYNTAX); fin if token <> CLOSE_PAREN_TKN; exit_err(ERR_MISS|ERR_CLOSE|ERR_SYNTAX); fin
deref--
break break
is DROP_TKN is DROP_TKN
if rvalue; exit_err(ERR_INVAL|ERR_STATE); fin if rvalue; exit_err(ERR_INVAL|ERR_STATE); fin
@ -313,9 +313,9 @@ def parse_value(codeseq, rvalue)#2
return codeseq, 0 // Special case return return codeseq, 0 // Special case return
is LAMBDA_TKN is LAMBDA_TKN
if not rvalue; return codeseq, 0; fin // Lambdas can't be LVALUES if not rvalue; return codeseq, 0; fin // Lambdas can't be LVALUES
type = type | CONST_TYPE
value = parse_lambda value = parse_lambda
valseq = gen_opglbl(NULL, GADDR_CODE, value, 0) valseq = gen_opglbl(NULL, GADDR_CODE, value, 0)
deref--
break break
otherwise otherwise
if uopseq; release_seq(uopseq); fin if uopseq; release_seq(uopseq); fin
@ -344,39 +344,44 @@ def parse_value(codeseq, rvalue)#2
else else
rewind(tknptr) rewind(tknptr)
fin fin
if type & (VAR_TYPE | PTR_TYPE) if type & WORD_TYPE
valseq = gen_op(valseq, LW_CODE) valseq = gen_op(valseq, LW_CODE)
if deref; deref--; fin elsif type & BYTE_TYPE
exit_err(ERR_INVAL|ERR_CODE)
else
deref++
fin fin
fin fin
valseq = gen_op(valseq, ICAL_CODE) valseq = gen_op(valseq, ICAL_CODE)
stackdepth = stackdepth + cfnvals - 1 stackdepth = stackdepth + cfnvals - 1
cfnparms = 0 cfnparms = 0
cfnvals = 1 cfnvals = 1
type = type & ~(FUNC_TYPE | VAR_TYPE) type = type & PTR_TYPE
deref--
break break
is OPEN_BRACKET_TKN is OPEN_BRACKET_TKN
// //
// Array of arrays // Array of arrays
// //
if type & FUNC_TYPE // Function address dereference if type & FUNC_TYPE // Function address dereference
cfnparms = 0 cfnparms = 0
cfnvals = 1 cfnvals = 1
type = BPTR_TYPE
fin fin
repeat repeat
valseq, drop = parse_expr(valseq) valseq, drop = parse_expr(valseq)
if token <> COMMA_TKN; break; fin if token <> COMMA_TKN; break; fin
valseq = gen_op(valseq, INDEXW_CODE) valseq = gen_op(valseq, INDEXW_CODE)
valseq = gen_op(valseq, LW_CODE) valseq = gen_op(valseq, LW_CODE) // Multi-dimenstion arrays are array pointers to arrays
until FALSE until FALSE
if token <> CLOSE_BRACKET_TKN; exit_err(ERR_MISS|ERR_CLOSE|ERR_SYNTAX); fin if token <> CLOSE_BRACKET_TKN; exit_err(ERR_MISS|ERR_CLOSE|ERR_SYNTAX); fin
if type & (WPTR_TYPE | WORD_TYPE) if type & WORD_TYPE
valseq = gen_op(valseq, INDEXW_CODE) valseq = gen_op(valseq, INDEXW_CODE)
type = (type & PTR_TYPE) | WORD_TYPE
else else
valseq = gen_op(valseq, INDEXB_CODE) valseq = gen_op(valseq, INDEXB_CODE)
type = (type & PTR_TYPE) | BYTE_TYPE if not (type & BYTE_TYPE)
type = (type & PTR_TYPE) | BYTE_TYPE
deref++
fin
fin fin
break break
is PTRB_TKN is PTRB_TKN
@ -390,11 +395,14 @@ def parse_value(codeseq, rvalue)#2
stackdepth = stackdepth + cfnvals - 1 stackdepth = stackdepth + cfnvals - 1
cfnparms = 0 cfnparms = 0
cfnvals = 1 cfnvals = 1
type = type & ~FUNC_TYPE elsif type & WORD_TYPE
elsif type & (VAR_TYPE | PTR_TYPE)
valseq = gen_op(valseq, LW_CODE) // Pointer dereference valseq = gen_op(valseq, LW_CODE) // Pointer dereference
elsif type & BYTE_TYPE
exit_err(ERR_INVAL|ERR_CODE)
else
deref++
fin fin
type = token == PTRB_TKN ?? BPTR_TYPE :: WPTR_TYPE type = (type & PTR_TYPE) | token == PTRB_TKN ?? BYTE_TYPE :: WORD_TYPE
if not parse_const(@const_offset) if not parse_const(@const_offset)
rewind(tknptr) // Setting type override for following operations rewind(tknptr) // Setting type override for following operations
elsif const_offset <> 0 elsif const_offset <> 0
@ -410,13 +418,10 @@ def parse_value(codeseq, rvalue)#2
if type & FUNC_TYPE // Function address dereference if type & FUNC_TYPE // Function address dereference
cfnparms = 0 cfnparms = 0
cfnvals = 1 cfnvals = 1
type = VAR_TYPE elsif not (type & VAR_TYPE)
fin deref++
if type & (VAR_TYPE | CONST_TYPE)
type = token == DOT_TKN ?? BYTE_TYPE :: WORD_TYPE
else
type = token == DOT_TKN ?? BPTR_TYPE :: WPTR_TYPE
fin fin
type = (type & VAR_TYPE) | (token == DOT_TKN ?? BYTE_TYPE :: WORD_TYPE)
if not parse_const(@const_offset) if not parse_const(@const_offset)
rewind(tknptr) // Setting type override for following operations rewind(tknptr) // Setting type override for following operations
elsif const_offset <> 0 elsif const_offset <> 0
@ -429,10 +434,17 @@ def parse_value(codeseq, rvalue)#2
wend wend
until not operation until not operation
// //
//Probably parsing RVALUE as LVALUE
//
if deref < 0
release_seq(valseq)
release_seq(uopseq)
return codeseq, 0
fin
//
// Resolve outstanding dereference pointer loads // Resolve outstanding dereference pointer loads
// //
while deref > rvalue while deref > rvalue
deref--
if type & FUNC_TYPE if type & FUNC_TYPE
if cfnparms; exit_err(ERR_MISS|ERR_ID); fin if cfnparms; exit_err(ERR_MISS|ERR_ID); fin
valseq = gen_op(valseq, ICAL_CODE) valseq = gen_op(valseq, ICAL_CODE)
@ -440,9 +452,10 @@ def parse_value(codeseq, rvalue)#2
cfnparms = 0 cfnparms = 0
cfnvals = 1 cfnvals = 1
type = type & ~FUNC_TYPE; type = type & ~FUNC_TYPE;
elsif type & VAR_TYPE else
valseq = gen_op(valseq, LW_CODE) valseq = gen_op(valseq, LW_CODE)
fin fin
deref--
loop loop
if deref if deref
if type & FUNC_TYPE if type & FUNC_TYPE
@ -454,6 +467,8 @@ def parse_value(codeseq, rvalue)#2
valseq = gen_op(valseq, LB_CODE) valseq = gen_op(valseq, LB_CODE)
elsif type & (WORD_TYPE | WPTR_TYPE) elsif type & (WORD_TYPE | WPTR_TYPE)
valseq = gen_op(valseq, LW_CODE) valseq = gen_op(valseq, LW_CODE)
else
exit_err(ERR_INVAL|ERR_CODE)
fin fin
fin fin
// //
@ -464,15 +479,15 @@ def parse_value(codeseq, rvalue)#2
// Wrap up LVALUE store // Wrap up LVALUE store
// //
if not rvalue if not rvalue
stackdepth--
if type & (BYTE_TYPE | BPTR_TYPE) if type & (BYTE_TYPE | BPTR_TYPE)
valseq = gen_op(valseq, SB_CODE) valseq = gen_op(valseq, SB_CODE)
elsif type & (WORD_TYPE | WPTR_TYPE) elsif type & (WORD_TYPE | WPTR_TYPE)
valseq = gen_op(valseq, SW_CODE) valseq = gen_op(valseq, SW_CODE)
else else
release_seq(valseq) release_seq(valseq)
return NULL, 0 // Function or const cannot be LVALUE, must be RVALUE return codeseq, 0 // Function or const cannot be LVALUE, must be RVALUE
fin fin
stackdepth--
fin fin
return cat_seq(codeseq, valseq), stackdepth return cat_seq(codeseq, valseq), stackdepth
end end
@ -836,9 +851,11 @@ def parse_stmnt
seq, cfnvals = parse_expr(NULL) seq, cfnvals = parse_expr(NULL)
if not seq if not seq
emit_const(0) emit_const(0)
elsif cfnvals > 1 else
exit_err(ERR_OVER|ERR_CLOSE|ERR_STATE) if cfnvals > 1
while cfnvals > 1;cfnvals--; seq = gen_op(seq, DROP_CODE); loop exit_err(ERR_OVER|ERR_CLOSE|ERR_STATE)
while cfnvals > 1;cfnvals--; seq = gen_op(seq, DROP_CODE); loop
fin
emit_seq(seq) emit_seq(seq)
fin fin
emit_code(RET_CODE) emit_code(RET_CODE)
@ -917,18 +934,22 @@ def parse_var(type, basesize)#0
arraysize = arraysize + emit_data(type, consttype, constval, constsize) arraysize = arraysize + emit_data(type, consttype, constval, constsize)
loop loop
size_iddata(PTR_TYPE, size, arraysize) size_iddata(PTR_TYPE, size, arraysize)
elsif idlen else
if infunc if idlen
new_idlocal(idptr, idlen, type, size) if infunc
else new_idlocal(idptr, idlen, type, size)
new_iddata(idptr, idlen, type, size) else
new_iddata(idptr, idlen, type, size)
fin
elsif not (type & (EXTERN_TYPE|LOCAL_TYPE))
emit_fill(size)
fin fin
fin fin
end end
def parse_struc#0 def parse_struc#0
byte strucid[16] byte strucid[16]
byte idlen, struclen, constsize, consttype byte idlen, struclen, constsize, consttype
word type, size, offset, idstr word type, basesize, size, offset, idstr
struclen = 0 struclen = 0
if scan == ID_TKN if scan == ID_TKN
@ -944,15 +965,16 @@ def parse_struc#0
offset = 0 offset = 0
while nextln == BYTE_TKN or token == WORD_TKN or token == EOL_TKN while nextln == BYTE_TKN or token == WORD_TKN or token == EOL_TKN
if token <> EOL_TKN if token <> EOL_TKN
size = 1 basesize = 1
type = token == BYTE_TKN ?? BYTE_TYPE :: WORD_TYPE type = token == BYTE_TKN ?? BYTE_TYPE :: WORD_TYPE
if scan == OPEN_BRACKET_TKN if scan == OPEN_BRACKET_TKN
size, constsize, consttype = parse_constexpr basesize, constsize, consttype = parse_constexpr
if token <> CLOSE_BRACKET_TKN; exit_err(ERR_MISS|ERR_CLOSE|ERR_SYNTAX); fin if token <> CLOSE_BRACKET_TKN; exit_err(ERR_MISS|ERR_CLOSE|ERR_SYNTAX); fin
scan scan
fin fin
repeat repeat
idlen = 0; size = 1
idlen = 0
if token == ID_TKN if token == ID_TKN
idstr = tknptr idstr = tknptr
idlen = tknlen idlen = tknlen
@ -962,6 +984,7 @@ def parse_struc#0
scan scan
fin fin
fin fin
size = size * basesize
if type & WORD_TYPE if type & WORD_TYPE
size = size * 2 size = size * 2
fin fin

View File

@ -151,6 +151,7 @@ byte = "END", END_TKN
byte = "AND", LOGIC_AND_TKN byte = "AND", LOGIC_AND_TKN
byte = "NOT", LOGIC_NOT_TKN byte = "NOT", LOGIC_NOT_TKN
byte = "VAR", WORD_TKN byte = "VAR", WORD_TKN
byte = "RES", BYTE_TKN
byte = "WORD", WORD_TKN byte = "WORD", WORD_TKN
byte = "CHAR", BYTE_TKN byte = "CHAR", BYTE_TKN
byte = "BYTE", BYTE_TKN byte = "BYTE", BYTE_TKN
@ -280,21 +281,21 @@ word srcline // Saved source line number
// //
// Scanner variables // Scanner variables
// //
const inbuff = $0200 word instr
const instr = $01FF word inbuff
word scanptr = inbuff word scanptr
byte token = EOL_TKN byte token = EOL_TKN
byte scanchr, tknlen byte scanchr, tknlen
word tknptr, parserrln word tknptr, parserrln
word constval word constval
word lineno word lineno
// //
// Parser variables // Parser variables
// //
const LVALUE = 0 const LVALUE = 0
const RVALUE = 1 const RVALUE = 1
const LAMBDANUM = 16 const LAMBDANUM = 16
byte[80] strconst word strconstbuff
word strconstptr word strconstptr
byte infunc, inlambda byte infunc, inlambda
byte stack_loop byte stack_loop
@ -347,14 +348,6 @@ def puth(hex)#0
putc('$') putc('$')
call($F941, hex >> 8, hex, 0, 0) call($F941, hex >> 8, hex, 0, 0)
end end
def strcpy(dst, src)
if ^src
memcpy(dst, src, ^src + 1)
else
^dst = 0
fin
return ^dst
end
def nametostr(namestr, len, strptr)#0 def nametostr(namestr, len, strptr)#0
^strptr = len ^strptr = len
memcpy(strptr + 1, namestr, len) memcpy(strptr + 1, namestr, len)
@ -393,7 +386,7 @@ def exit_err(err)#0
if err & ERR_SYNTAX; puts("syntax"); fin if err & ERR_SYNTAX; puts("syntax"); fin
putcurln putcurln
fileio:close(0) // Close all open files fileio:close(0) // Close all open files
longjmp(exit, TRUE) throw(exit, TRUE)
end end
// //
// Warning // Warning
@ -417,14 +410,14 @@ include "toolsrc/parse.pla"
puts("PLASMA Compiler, Version 1.0\n") puts("PLASMA Compiler, Version 1.0\n")
arg = argNext(argFirst) arg = argNext(argFirst)
if ^arg and ^(arg + 1) == '-' if ^arg and ^(arg + 1) == '-'
opt = arg + 2 opt = arg + 2
while TRUE while TRUE
if toupper(^opt) == 'O' if toupper(^opt) == 'O'
// //
// Load optimizer module here // Load optimizer module here
// //
if MACHID & $30 == $30 if MACHID & $30 == $30
if modexec("CODEOPT") >= 0 if cmdsys:modexec("CODEOPT") >= 0
outflags = outflags | OPTIMIZE outflags = outflags | OPTIMIZE
fin fin
fin fin
@ -448,10 +441,10 @@ if ^arg and ^(arg + 1) == '-'
loop loop
arg = argNext(arg) arg = argNext(arg)
fin fin
if arg if ^arg
strcpy(@srcfile, arg) strcpy(@srcfile, arg)
arg = argNext(arg) arg = argNext(arg)
if arg and ^arg if ^arg
strcpy(@relfile, arg) strcpy(@relfile, arg)
else else
strcpy(@relfile, @srcfile) strcpy(@relfile, @srcfile)
@ -474,12 +467,15 @@ if srcfile and relfile
srcref = fileio:open(@srcfile) srcref = fileio:open(@srcfile)
if srcref if srcref
fileio:newline(srcref, $7F, $0D) fileio:newline(srcref, $7F, $0D)
refnum = srcref refnum = srcref
parsefile = @srcfile parsefile = @srcfile
*instr = 0 strconstbuff = heapalloc(80)
scanptr = inbuff instr = cmdsys:cmdline
exit = heapalloc(t_longjmp) inbuff = instr + 1
if not setjmp(exit) scanptr = inbuff
*instr = NULL
exit = heapalloc(t_except)
if not except(exit)
// //
// Parse source code module // Parse source code module
// //

View File

@ -91,12 +91,10 @@ byte uisltstr[] = "ISULT"
byte uislestr[] = "ISULE" byte uislestr[] = "ISULE"
byte sextstr[] = "SEXT" byte sextstr[] = "SEXT"
byte divmodstr[] = "DIVMOD" byte divmodstr[] = "DIVMOD"
byte loadstr[] = "MODLOAD"
byte execstr[] = "MODEXEC"
byte modadrstr[] = "MODADDR"
byte argstr[] = "ARGS" byte argstr[] = "ARGS"
byte syspath[] = "" // Set to NULL byte syspath[] = "" // Set to NULL
word exports[] = @sysstr, @syscall word exports[] = @syslibstr, @version
word = @sysstr, @syscall
word = @callstr, @call word = @callstr, @call
word = @putcstr, @cout word = @putcstr, @cout
word = @putlnstr, @crout word = @putlnstr, @crout
@ -118,9 +116,6 @@ word = @uisltstr, @uword_islt
word = @uislestr, @uword_isle word = @uislestr, @uword_isle
word = @sextstr, @sext word = @sextstr, @sext
word = @divmodstr, @divmod word = @divmodstr, @divmod
word = @loadstr, @loadmod
word = @execstr, @execmod
word = @modadrstr, @lookupstrmod
word = @machidstr, @machid word = @machidstr, @machid
word = @syspathstr,@syspath word = @syspathstr,@syspath
word = @argstr, @cmdptr word = @argstr, @cmdptr
@ -498,38 +493,6 @@ end
// pre-pended with a '#' to differentiate them // pre-pended with a '#' to differentiate them
// from normal symbols. // from normal symbols.
// //
//def modtosym(mod, dci)
// byte len, c
// (dci).0 = '#'|$80
// len = 0
// repeat
// c = (mod).[len]
// len = len + 1
// (dci).[len] = c
// until !(c & $80)
// return dci
//end
asm modtosym(mod, dci)#1
LDA ESTKL+1,X
STA SRCL
LDA ESTKH+1,X
STA SRCH
LDA ESTKL,X
STA ESTKL+1,X
STA DSTL
LDA ESTKH,X
STA ESTKH+1,X
STA DSTH
INX
LDY #$00
LDA #'#'+$80
- STA (DST),Y
ASL
LDA (SRC),Y
INY
BCS -
RTS
end
// //
// Lookup routines. // Lookup routines.
// //
@ -635,47 +598,53 @@ def rdstr(prompt)#1
cout(prompt) cout(prompt)
repeat repeat
ch = cin ch = cin
when ch when ch
is $15 // right arrow is $15 // right arrow
if inbuff.0 < maxlen if ^inbuff < maxlen //inbuff.0 < maxlen
inbuff.0 = inbuff.0 + 1 inbuff.0 = inbuff.0 + 1
ch = inbuff[inbuff.0] ch = inbuff[inbuff.0]
cout(ch) cout(ch)
fin fin
is $08 // left arrow break
if inbuff.0 is $08 // left arrow
cout('\\') if inbuff.0
cout(inbuff[inbuff.0]) cout('\\')
inbuff.0 = inbuff.0 - 1 cout(inbuff[inbuff.0])
fin inbuff.0 = inbuff.0 - 1
is $04 // ctrl-d fin
if inbuff.0 break
cout('#') is $04 // ctrl-d
cout(inbuff[inbuff.0]) if inbuff.0
memcpy(inbuff + inbuff.0, inbuff + inbuff.0 + 1, maxlen - inbuff.0) cout('#')
maxlen = maxlen - 1 cout(inbuff[inbuff.0])
inbuff.0 = inbuff.0 - 1 memcpy(inbuff + inbuff.0, inbuff + inbuff.0 + 1, maxlen - inbuff.0)
fin maxlen = maxlen - 1
is $0C // ctrl-l inbuff.0 = inbuff.0 - 1
crout fin
prstr(inbuff) break
is $0D // return is $0C // ctrl-l
is $18 // ctrl-x crout
crout prstr(inbuff)
inbuff.0 = 0 break
is $9B // escape is $0D // return
inbuff.0 = 0 is $18 // ctrl-x
ch = $0D crout
otherwise inbuff.0 = 0
if ch >= ' ' break
cout(ch) is $9B // escape
inbuff.0 = inbuff.0 + 1 inbuff.0 = 0
inbuff[inbuff.0] = ch ch = $0D
if inbuff.0 > maxlen break
maxlen = inbuff.0 otherwise
fin if ch >= ' '
fin cout(ch)
wend inbuff.0 = inbuff.0 + 1
inbuff[inbuff.0] = ch
if inbuff.0 > maxlen
maxlen = inbuff.0
fin
fin
wend
until ch == $0D or inbuff.0 == $7F until ch == $0D or inbuff.0 == $7F
cout($0D) cout($0D)
return inbuff return inbuff
@ -764,19 +733,6 @@ end
// //
// Module routines. // Module routines.
// //
def lookupmod(mod)#1
byte dci[17]
return lookuptbl(modtosym(mod, @dci), symtbl)
end
def lookupstrmod(str)#1
byte mod[17]
stodci(str, @mod)
return lookupmod(@mod)
end
def addmod(mod, addr)#0
byte dci[17]
addsym(modtosym(mod, @dci), addr)
end
def lookupextern(esd, index)#1 def lookupextern(esd, index)#1
word sym, addr word sym, addr
byte str[16] byte str[16]
@ -850,7 +806,7 @@ def loadmod(mod)#1
// Load module dependencies. // Load module dependencies.
// //
while ^moddep while ^moddep
if !lookupmod(moddep) if !lookuptbl(moddep, symtbl)
if loadmod(moddep) < 0 if loadmod(moddep) < 0
return -perr return -perr
fin fin
@ -880,7 +836,7 @@ def loadmod(mod)#1
// //
// Add module to symbol table. // Add module to symbol table.
// //
addmod(mod, modaddr) addsym(mod, modaddr)
// //
// Apply all fixups and symbol import/export. // Apply all fixups and symbol import/export.
// //
@ -1054,8 +1010,6 @@ prstr(@verstr); prbyte(version.1); cout('.'); prbyte(version.0); crout
symtbl = allocheap($200) symtbl = allocheap($200)
lastsym = symtbl lastsym = symtbl
^lastsym = 0 ^lastsym = 0
stodci(@syslibstr, heap)
addmod(heap, @version)
while *syslibsym while *syslibsym
stodci(syslibsym=>0, heap) stodci(syslibsym=>0, heap)
addsym(heap, syslibsym=>2) addsym(heap, syslibsym=>2)

View File

@ -25,32 +25,35 @@ const modinitkeep = $4000
// Pedefined functions. // Pedefined functions.
// //
predef syscall(cmd,params)#1, call(addr,areg,xreg,yreg,status)#1 predef syscall(cmd,params)#1, call(addr,areg,xreg,yreg,status)#1
predef crout()#0, cout(c)#0, prstr(s)#0, print(i)#0, cin()#1, rdstr(p)#1, toupper(c)#1 predef crout()#0, cout(c)#0, prstr(s)#0, prbyte(b)#0, prword(w)#0, print(i)#0, cin()#1, rdstr(p)#1, toupper(c)#1
predef markheap()#1, allocheap(size)#1, allocalignheap(size, pow2, freeaddr)#1, releaseheap(newheap)#1, availheap()#1 predef markheap()#1, allocheap(size)#1, allocalignheap(size, pow2, freeaddr)#1, releaseheap(newheap)#1, availheap()#1
predef memset(addr,value,size)#0, memcpy(dst,src,size)#0 predef memset(addr,value,size)#0, memcpy(dst,src,size)#0, strcpy(dst,src)#1, strcat(dst,src)#1
predef uword_isgt(a,b)#1, uword_isge(a,b)#1, uword_islt(a,b)#1, uword_isle(a,b)#1, sext(a)#1, divmod(a,b)#2 predef uword_isgt(a,b)#1, uword_isge(a,b)#1, uword_islt(a,b)#1, uword_isle(a,b)#1, sext(a)#1, divmod(a,b)#2
predef loadmod(mod)#1, execmod(modfile)#1, lookupstrmod(str)#1 predef execmod(modfile)#1
// //
// System variable. // Exported CMDSYS table
// //
word version = $0100 // 01.00 word version = $0100 // 01.00
word systemflags = 0 word syspath
word heap word = getlnbuf
word xheap = $0800 word = @execmod
word lastsym = symtbl word = getlnbuf
byte perr //
byte cmdln = "" // Overlay exported strings table // Working input buffer overlayed with strings table
//
byte cmdln = ""
// //
// Standard Library exported functions. // Standard Library exported functions.
// //
byte syslibstr = "CMDSYS" byte sysmodstr = "CMDSYS"
byte machidstr = "MACHID" byte machidstr = "MACHID"
byte syspathstr = "SYSPATH"
byte sysstr = "SYSCALL" byte sysstr = "SYSCALL"
byte callstr = "CALL" byte callstr = "CALL"
byte putcstr = "PUTC" byte putcstr = "PUTC"
byte putlnstr = "PUTLN" byte putlnstr = "PUTLN"
byte putsstr = "PUTS" byte putsstr = "PUTS"
byte putbstr = "PUTB"
byte putwstr = "PUTH"
byte putistr = "PUTI" byte putistr = "PUTI"
byte getcstr = "GETC" byte getcstr = "GETC"
byte getsstr = "GETS" byte getsstr = "GETS"
@ -66,20 +69,21 @@ byte uisgtstr = "ISUGT"
byte uisgestr = "ISUGE" byte uisgestr = "ISUGE"
byte uisltstr = "ISULT" byte uisltstr = "ISULT"
byte uislestr = "ISULE" byte uislestr = "ISULE"
byte syspath[] // overlay with exported strings byte sysmods[] // overlay with exported strings
byte strcpystr = "STRCPY"
byte strcatstr = "STRCAT"
byte sextstr = "SEXT" byte sextstr = "SEXT"
byte divmodstr = "DIVMOD" byte divmodstr = "DIVMOD"
byte loadstr = "MODLOAD"
byte execstr = "MODEXEC"
byte modadrstr = "MODADDR"
byte argstr = "ARGS"
byte autorun = "AUTORUN" byte autorun = "AUTORUN"
byte prefix[] // overlay with exported symbols table byte prefix[] // overlay with exported symbols table
word exports = @sysstr, @syscall word exports = @sysmodstr, @version
word = @sysstr, @syscall
word = @callstr, @call word = @callstr, @call
word = @putcstr, @cout word = @putcstr, @cout
word = @putlnstr, @crout word = @putlnstr, @crout
word = @putsstr, @prstr word = @putsstr, @prstr
word = @putbstr, @prbyte
word = @putwstr, @prword
word = @putistr, @print word = @putistr, @print
word = @getcstr, @cin word = @getcstr, @cin
word = @getsstr, @rdstr word = @getsstr, @rdstr
@ -95,16 +99,21 @@ word = @uisgtstr, @uword_isgt
word = @uisgestr, @uword_isge word = @uisgestr, @uword_isge
word = @uisltstr, @uword_islt word = @uisltstr, @uword_islt
word = @uislestr, @uword_isle word = @uislestr, @uword_isle
word = @strcpystr, @strcpy
word = @strcatstr, @strcat
word = @sextstr, @sext word = @sextstr, @sext
word = @divmodstr, @divmod word = @divmodstr, @divmod
word = @loadstr, @loadmod
word = @execstr, @execmod
word = @modadrstr, @lookupstrmod
word = @machidstr, MACHID word = @machidstr, MACHID
word = @syspathstr,@syspath
word = @argstr, @cmdln
word = 0 word = 0
word syslibsym = @exports word sysmodsym = @exports
//
// System variable.
//
word systemflags = 0
byte perr
word heap
word xheap = $0800
word lastsym = symtbl
// //
// Utility functions // Utility functions
// //
@ -635,43 +644,6 @@ TOUPR AND #$7F
RTS RTS
end end
// //
// Module symbols are entered into the symbol table
// pre-pended with a '#' to differentiate them
// from normal symbols.
//
//def modtosym(mod, dci)
// byte len, c
// (dci).0 = '#'|$80
// len = 0
// repeat
// c = (mod).[len]
// len = len + 1
// (dci).[len] = c
// until !(c & $80)
// return dci
//end
asm modtosym(mod,dci)#1
LDA ESTKL+1,X
STA SRCL
LDA ESTKH+1,X
STA SRCH
LDA ESTKL,X
STA ESTKL+1,X
STA DSTL
LDA ESTKH,X
STA ESTKH+1,X
STA DSTH
INX
LDY #$00
LDA #'#'+$80
- STA (DST),Y
ASL
LDA (SRC),Y
INY
BCS -
RTS
end
//
// Lookup routines. // Lookup routines.
// //
//def lookuptbl(dci, tbl) //def lookuptbl(dci, tbl)
@ -877,13 +849,13 @@ end
def addsym(sym, addr)#0 def addsym(sym, addr)#0
while ^sym & $80 while ^sym & $80
^lastsym = ^sym ^lastsym = ^sym
lastsym = lastsym + 1 lastsym++
sym = sym + 1 sym++
loop loop
lastsym->0 = ^sym lastsym->0 = ^sym
lastsym=>1 = addr lastsym=>1 = addr
lastsym = lastsym + 3 lastsym = lastsym + 3
^lastsym = 0 ^lastsym = 0
end end
// //
// String routines. // String routines.
@ -901,19 +873,6 @@ end
// //
// Module routines. // Module routines.
// //
def lookupmod(mod)#1
byte dci[17]
return lookuptbl(modtosym(mod, @dci), symtbl)
end
def lookupstrmod(str)#1
byte mod[17]
stodci(str, @mod)
return lookupmod(@mod)
end
def addmod(mod, addr)#0
byte dci[17]
addsym(modtosym(mod, @dci), addr)
end
def lookupextern(esd, index)#1 def lookupextern(esd, index)#1
word sym, addr word sym, addr
byte str[16] byte str[16]
@ -971,7 +930,7 @@ def loadmod(mod)#1
// //
// Try system path // Try system path
// //
refnum = open(strcpy(@filename,strcat(strcpy(@header, @syspath), @filename))) refnum = open(strcpy(@filename,strcat(strcpy(@header, @sysmods), @filename)))
fin fin
if refnum if refnum
rdlen = read(refnum, @header, 128) rdlen = read(refnum, @header, 128)
@ -992,7 +951,7 @@ def loadmod(mod)#1
// Load module dependencies. // Load module dependencies.
// //
while ^moddep while ^moddep
if !lookupmod(moddep) if !lookuptbl(moddep, symtbl)//lookupmod(moddep)
close(refnum) close(refnum)
refnum = 0 refnum = 0
if loadmod(moddep) < 0 if loadmod(moddep) < 0
@ -1036,7 +995,7 @@ def loadmod(mod)#1
// //
// Add module to symbol table. // Add module to symbol table.
// //
addmod(mod, modaddr) addsym(mod, modaddr)//addmod(mod, modaddr)
// //
// Apply all fixups and symbol import/export. // Apply all fixups and symbol import/export.
// //
@ -1272,7 +1231,7 @@ def striptrail(strptr)#1
for i = 1 to ^strptr for i = 1 to ^strptr
if ^(strptr + i) <= ' ' if ^(strptr + i) <= ' '
^strptr = i - 1 ^strptr = i - 1
return strptr break
fin fin
next next
return strptr return strptr
@ -1359,23 +1318,22 @@ prstr("PLASMA Pre "); prbyte(version.1); cout('.'); prbyte(version.0); crout
// //
// Init symbol table. // Init symbol table.
// //
stodci(@syslibstr, heap) while *sysmodsym
addmod(heap, @version) stodci(sysmodsym=>0, heap)
while *syslibsym addsym(heap, sysmodsym=>2)
stodci(syslibsym=>0, heap) sysmodsym = sysmodsym + 4
addsym(heap, syslibsym=>2)
syslibsym = syslibsym + 4
loop loop
// //
// Set system path // Set system path
// //
strcat(strcpy(@syspath, $280), "SYS/")) // This is the path to CMD strcat(strcpy(@sysmods, $280), "SYS/")) // This is the path to CMD
syspath = @sysmods // Update external interface table
// //
// Try to load autorun. // Try to load autorun.
// //
autorun = open(@autorun) autorun = open(@autorun)
if autorun > 0 if autorun > 0
cmdln = read(autorun, @syslibstr, 128) cmdln = read(autorun, @sysmodstr, 128)
close(autorun) close(autorun)
else else
// //
@ -1396,6 +1354,14 @@ while 1
is 'P' is 'P'
setpfx(@cmdln) setpfx(@cmdln)
break break
is '/'
repeat
prefix--
until prefix[prefix] == '/'
if prefix > 1
setpfx(@prefix)
fin
break
is 'V' is 'V'
volumes() volumes()
break break
@ -1424,6 +1390,6 @@ while 1
crout() crout()
fin fin
prstr(getpfx(@prefix)) prstr(getpfx(@prefix))
memcpy(@cmdln, rdstr($BA), 128) strcpy(@cmdln, rdstr($BA))
loop loop
done done

View File

@ -40,17 +40,47 @@ word *esp = eval_stack + EVAL_STACKSZ;
#define SYMTBLSZ 1024 #define SYMTBLSZ 1024
#define SYMSZ 16 #define SYMSZ 16
#define MODTBLSZ 128
#define MODSZ 16
#define MODLSTSZ 32
byte symtbl[SYMTBLSZ]; byte symtbl[SYMTBLSZ];
byte *lastsym = symtbl; byte *lastsym = symtbl;
byte modtbl[MODTBLSZ];
byte *lastmod = modtbl;
/* /*
* Predef. * Predef.
*/ */
void interp(code *ip); void interp(code *ip);
/*
* CMDSYS exports
*/
char *syslib_exp[] = {
"CMDSYS",
"MACHID",
"PUTC",
"PUTLN",
"PUTS",
"PUTI",
"GETC",
"GETS",
"PUTB",
"PUTH",
"TOUPPER",
"CALL",
"SYSCALL",
"HEAPMARK",
"HEAPALLOCALLIGN",
"HEAPALLOC",
"HEAPRELEASE",
"HEAPAVAIL",
"MEMSET",
"MEMCPY",
"STRCPY",
"STRCAT",
"SEXT",
"DIVMOD",
"ISUGT",
"ISUGE",
"ISULT",
"ISULE",
0
};
/* /*
* Utility routines. * Utility routines.
* *
@ -181,19 +211,6 @@ uword add_sym(byte *sym, int addr)
/* /*
* Module routines. * Module routines.
*/ */
void dump_mod(void)
{
printf("\nSystem Module Table:\n");
dump_tbl(modtbl);
}
uword lookup_mod(byte *mod)
{
return lookup_tbl(mod, modtbl);
}
uword add_mod(byte *mod, int addr)
{
return add_tbl(mod, addr, &lastmod);
}
uword defcall_add(int bank, int addr) uword defcall_add(int bank, int addr)
{ {
mem_data[lastdef] = bank ? 2 : 1; mem_data[lastdef] = bank ? 2 : 1;
@ -204,7 +221,7 @@ uword defcall_add(int bank, int addr)
uword def_lookup(byte *cdd, int defaddr) uword def_lookup(byte *cdd, int defaddr)
{ {
int i, calldef = 0; int i, calldef = 0;
for (i = 0; cdd[i * 4] == 0x02; i++) for (i = 0; cdd[i * 4] == 0x00; i++)
{ {
if ((cdd[i * 4 + 1] | (cdd[i * 4 + 2] << 8)) == defaddr) if ((cdd[i * 4 + 1] | (cdd[i * 4 + 2] << 8)) == defaddr)
{ {
@ -263,7 +280,7 @@ int load_mod(byte *mod)
*/ */
while (*moddep) while (*moddep)
{ {
if (lookup_mod(moddep) == 0) if (lookup_sym(moddep) == 0)
{ {
if (fd) if (fd)
{ {
@ -324,7 +341,7 @@ int load_mod(byte *mod)
/* /*
* Add module to symbol table. * Add module to symbol table.
*/ */
add_mod(mod, modaddr); add_sym(mod, modaddr);
/* /*
* Print out the Re-Location Dictionary. * Print out the Re-Location Dictionary.
*/ */
@ -337,6 +354,7 @@ int load_mod(byte *mod)
if (show_state) printf("\tDEF CODE"); if (show_state) printf("\tDEF CODE");
addr = rld[1] | (rld[2] << 8); addr = rld[1] | (rld[2] << 8);
addr += modfix - MOD_ADDR; addr += modfix - MOD_ADDR;
rld[0] = 0; // Set call code to 0
rld[1] = addr; rld[1] = addr;
rld[2] = addr >> 8; rld[2] = addr >> 8;
end = rld - mem_data + 4; end = rld - mem_data + 4;
@ -440,25 +458,29 @@ void call(uword pc)
char c, sz[64]; char c, sz[64];
if (show_state) if (show_state)
printf("\nCall code:$%02X\n", mem_data[pc]); printf("\nCall: %s\n", mem_data[pc] ? syslib_exp[mem_data[pc] - 1] : "BYTECODE");
switch (mem_data[pc++]) switch (mem_data[pc++])
{ {
case 0: // NULL call case 0: // BYTECODE in mem_data
printf("NULL call code\n");
break;
case 1: // BYTECODE in mem_code
//interp(mem_code + (mem_data[pc] + (mem_data[pc + 1] << 8)));
break;
case 2: // BYTECODE in mem_data
interp(mem_data + (mem_data[pc] + (mem_data[pc + 1] << 8))); interp(mem_data + (mem_data[pc] + (mem_data[pc + 1] << 8)));
break; break;
case 1: // CMDSYS call
printf("CMD call code!\n");
break;
case 2: // MACHID
printf("MACHID call code!\n");
break;
case 3: // LIBRARY STDLIB::PUTC case 3: // LIBRARY STDLIB::PUTC
c = POP; c = POP;
if (c == 0x0D) if (c == 0x0D)
c = '\n'; c = '\n';
putchar(c); putchar(c);
break; break;
case 4: // LIBRARY STDLIB::PUTS case 4: // LIBRARY STDLIB::PUTNL
putchar('\n');
fflush(stdout);
break;
case 5: // LIBRARY STDLIB::PUTS
s = POP; s = POP;
i = mem_data[s++]; i = mem_data[s++];
while (i--) while (i--)
@ -469,19 +491,14 @@ void call(uword pc)
putchar(c); putchar(c);
} }
break; break;
case 5: // LIBRARY STDLIB::PUTSZ case 6: // LIBRARY STDLIB::PUTI
s = POP; i = POP;
while ((c = mem_data[s++])) printf("%d", i);
{
if (c == 0x0D)
c = '\n';
putchar(c);
}
break; break;
case 6: // LIBRARY STDLIB::GETC case 7: // LIBRARY STDLIB::GETC
PUSH(getchar()); PUSH(getchar());
break; break;
case 7: // LIBRARY STDLIB::GETS case 8: // LIBRARY STDLIB::GETS
gets(sz); gets(sz);
for (i = 0; sz[i]; i++) for (i = 0; sz[i]; i++)
mem_data[0x200 + i] = sz[i]; mem_data[0x200 + i] = sz[i];
@ -489,19 +506,8 @@ void call(uword pc)
mem_data[0x1FF] = i; mem_data[0x1FF] = i;
PUSH(i); PUSH(i);
break; break;
case 8: // LIBRARY STDLIB::PUTNL
putchar('\n');
fflush(stdout);
break;
case 9: // LIBRARY STDLIB::MACHID
PUSH(0x0000);
break;
case 10: // LIBRARY STDLIB::PUTI
i = POP;
printf("%d", i);
break;
default: default:
printf("\nBad call code:$%02X\n", mem_data[pc - 1]); printf("\nUnimplemented call code:$%02X\n", mem_data[pc - 1]);
exit(1); exit(1);
} }
} }
@ -875,18 +881,6 @@ void interp(code *ip)
} }
} }
char *syslib_exp[] = {
"PUTC",
"PUTS",
"PUTSZ",
"GETC",
"GETS",
"PUTLN",
"MACHID",
"PUTI",
0
};
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
byte dci[32]; byte dci[32];
@ -904,17 +898,16 @@ int main(int argc, char **argv)
/* /*
* Add default library. * Add default library.
*/ */
stodci("CMDSYS", dci);
add_mod(dci, 0xFFFF);
for (i = 0; syslib_exp[i]; i++) for (i = 0; syslib_exp[i]; i++)
{ {
mem_data[i] = i + 3; mem_data[i] = i;
stodci(syslib_exp[i], dci); stodci(syslib_exp[i], dci);
add_sym(dci, i); add_sym(dci, i+1);
} }
if (argc) if (argc)
{ {
stodci(*argv, dci); stodci(*argv, dci);
if (show_state) dump_sym();
load_mod(dci); load_mod(dci);
if (show_state) dump_sym(); if (show_state) dump_sym();
argc--; argc--;

View File

@ -30,19 +30,16 @@ predef crout()#0, cout(c)#0, prstr(s)#0, print(i)#0, cin()#1, rdstr(p)#1, touppe
predef markheap()#1, allocheap(size)#1, allocalignheap(size, pow2, freeaddr), releaseheap(newheap)#1, availheap()#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 memset(addr,value,size)#0, memcpy(dst,src,size)#0
predef uword_isgt(a,b)#1, uword_isge(a,b)#1, uword_islt(a,b)#1, uword_isle(a,b)#1, sext(a)#1, divmod(a,b)#2 predef uword_isgt(a,b)#1, uword_isge(a,b)#1, uword_islt(a,b)#1, uword_isle(a,b)#1, sext(a)#1, divmod(a,b)#2
predef loadmod(mod)#1, execmod(modfile)#1, lookupstrmod(str)#1 predef execmod(modfile)#1
// //
// System variables. // System variables.
// //
word version = $0100 // 01.00 word version = $0100 // 01.00
word systemflags = 0 word syspath
word cmdptr
word = @execmod
byte refcons = 0 byte refcons = 0
byte devcons = 0 byte devcons = 0
word heap = $2000
byte modid = 0
byte modseg[15]
word symtbl, lastsym
byte perr, terr, lerr
// //
// String pool. // String pool.
// //
@ -55,15 +52,10 @@ byte hexchar[] = '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E',
// //
byte machid = $F2 // Apple ///, 80 columns byte machid = $F2 // Apple ///, 80 columns
// //
// Command line pointer
//
word cmdptr
//
// Standard Library exported functions. // Standard Library exported functions.
// //
byte syslibstr[] = "CMDSYS" byte sysmodstr[] = "CMDSYS"
byte machidstr[] = "MACHID" byte machidstr[] = "MACHID"
byte syspathstr[] = "SYSPATH"
byte sysstr[] = "SYSCALL" byte sysstr[] = "SYSCALL"
byte callstr[] = "CALL" byte callstr[] = "CALL"
byte putcstr[] = "PUTC" byte putcstr[] = "PUTC"
@ -84,15 +76,15 @@ byte uisgtstr[] = "ISUGT"
byte uisgestr[] = "ISUGE" byte uisgestr[] = "ISUGE"
byte uisltstr[] = "ISULT" byte uisltstr[] = "ISULT"
byte uislestr[] = "ISULE" byte uislestr[] = "ISULE"
byte syspath[] // overlay with exported strings byte sysmods[] // overlay with exported strings
byte sextstr[] = "SEXT" byte sextstr[] = "SEXT"
byte divmodstr[] = "DIVMOD" byte divmodstr[] = "DIVMOD"
byte loadstr[] = "MODLOAD" byte loadstr[] = "MODLOAD"
byte execstr[] = "MODEXEC" byte execstr[] = "MODEXEC"
byte modadrstr[] = "MODADDR" byte modadrstr[] = "MODADDR"
byte argstr[] = "ARGS"
byte prefix[] // Overlay with exported symbols table byte prefix[] // Overlay with exported symbols table
word exports[] = @sysstr, @syscall word exports[] = @sysmodstr, @version
word = @sysstr, @syscall
word = @callstr, @call word = @callstr, @call
word = @putcstr, @cout word = @putcstr, @cout
word = @putlnstr, @crout word = @putlnstr, @crout
@ -114,14 +106,18 @@ word = @uisltstr, @uword_islt
word = @uislestr, @uword_isle word = @uislestr, @uword_isle
word = @sextstr, @sext word = @sextstr, @sext
word = @divmodstr, @divmod word = @divmodstr, @divmod
word = @loadstr, @loadmod
word = @execstr, @execmod
word = @modadrstr, @lookupstrmod
word = @machidstr, @machid word = @machidstr, @machid
word = @syspathstr,@syspath
word = @argstr, @cmdptr
word = 0 word = 0
word syslibsym = @exports word sysmodsym = @exports
//
// System variables.
//
word systemflags = 0
word heap = $2000
byte modid = 0
byte modseg[15]
word symtbl, lastsym
byte perr, terr, lerr
// //
// CALL SOS // CALL SOS
// SYSCALL(CMD, PARAMS) // SYSCALL(CMD, PARAMS)
@ -570,27 +566,27 @@ end
// until !(c & $80) // until !(c & $80)
// return dci // return dci
//end //end
asm modtosym(mod, dci)#1 //asm modtosym(mod, dci)#1
LDA ESTKL+1,X // LDA ESTKL+1,X
STA SRCL // STA SRCL
LDA ESTKH+1,X // LDA ESTKH+1,X
STA SRCH // STA SRCH
LDA ESTKL,X // LDA ESTKL,X
STA ESTKL+1,X // STA ESTKL+1,X
STA DSTL // STA DSTL
LDA ESTKH,X // LDA ESTKH,X
STA ESTKH+1,X // STA ESTKH+1,X
STA DSTH // STA DSTH
INX // INX
LDY #$00 // LDY #$00
LDA #'#'+$80 // LDA #'#'+$80
- STA (DST),Y //- STA (DST),Y
ASL // ASL
LDA (SRC),Y // LDA (SRC),Y
INY // INY
BCS - // BCS -
RTS // RTS
end //end
// //
// Lookup routines. // Lookup routines.
// //
@ -941,19 +937,14 @@ end
// //
// Module routines. // Module routines.
// //
def lookupmod(mod)#1 //def lookupmod(mod)#1
byte dci[17] // byte dci[17]
return lookuptbl(modtosym(mod, @dci), symtbl) // return lookuptbl(modtosym(mod, @dci), symtbl)
end //end
def lookupstrmod(str)#1 //def addmod(mod, addr)#0
byte mod[17] // byte dci[17]
stodci(str, @mod) // addsym(modtosym(mod, @dci), addr)
return lookupmod(@mod) //end
end
def addmod(mod, addr)#0
byte dci[17]
addsym(modtosym(mod, @dci), addr)
end
def lookupextern(esd, index)#1 def lookupextern(esd, index)#1
word sym, addr word sym, addr
byte str[16] byte str[16]
@ -1010,7 +1001,7 @@ def loadmod(mod)#1
// //
// Try system path // Try system path
// //
refnum = open(strcpy(@filename,strcat(strcpy(@header, @syspath), @filename))) refnum = open(strcpy(@filename,strcat(strcpy(@header, @sysmods), @filename)))
fin fin
if refnum if refnum
rdlen = read(refnum, @header, 128) rdlen = read(refnum, @header, 128)
@ -1031,7 +1022,7 @@ def loadmod(mod)#1
// Load module dependencies. // Load module dependencies.
// //
while ^moddep while ^moddep
if !lookupmod(moddep) if !lookuptbl(moddep, symtbl)
if refnum if refnum
close(refnum) close(refnum)
refnum = 0 refnum = 0
@ -1077,7 +1068,7 @@ def loadmod(mod)#1
// //
// Add module to symbol table. // Add module to symbol table.
// //
addmod(mod, modaddr) addsym(mod, modaddr)
// //
// Apply all fixups and symbol import/export. // Apply all fixups and symbol import/export.
// //
@ -1292,15 +1283,16 @@ def stripspaces(strptr)#0
^strptr = ^strptr - 1 ^strptr = ^strptr - 1
loop loop
end end
def striptrail(strptr)#0 def striptrail(strptr)#1
byte i byte i
for i = 1 to ^strptr for i = 1 to ^strptr
if (strptr)[i] <= ' ' if (strptr)[i] <= ' '
^strptr = i - 1 ^strptr = i - 1
return break
fin fin
next next
return strptr
end end
def parsecmd(strptr)#1 def parsecmd(strptr)#1
byte cmd byte cmd
@ -1353,17 +1345,16 @@ prstr("PLASMA "); prbyte(version.1); cout('.'); prbyte(version.0); crout
seg_find($00, @symtbl, @lastsym, $08, $11) seg_find($00, @symtbl, @lastsym, $08, $11)
lastsym = symtbl & $FF00 lastsym = symtbl & $FF00
xpokeb(symtbl.0, lastsym, 0) xpokeb(symtbl.0, lastsym, 0)
stodci(@syslibstr, heap) while *sysmodsym
addmod(heap, @version) stodci(sysmodsym=>0, heap)
while *syslibsym addsym(heap, sysmodsym=>2)
stodci(syslibsym=>0, heap) sysmodsym = sysmodsym + 4
addsym(heap, syslibsym=>2)
syslibsym = syslibsym + 4
loop loop
// //
// Clear system path // Clear system path
// //
syspath = 0 sysmods = 0
syspath = @sysmods
// //
// Try to load autorun. // Try to load autorun.
// //
@ -1398,13 +1389,13 @@ while 1
break break
is 'S' is 'S'
setpfx(cmdptr) setpfx(cmdptr)
strcat(getpfx(@syspath), "SYS/")) strcat(getpfx(@sysmods), "SYS/"))
break break
is 'V' is 'V'
volumes volumes
break break
is '+' is '+'
execmod(cmdptr) execmod(striptrail(cmdptr))
write(refcons, @textmode, 3) write(refcons, @textmode, 3)
break break
otherwise otherwise

View File

@ -38,7 +38,7 @@ pod=comment_doc
[keywords] [keywords]
# all items must be in one line # all items must be in one line
primary=done include import export struc const word byte var char and predef asm def end not or repeat until continue break for to downto next step when wend is otherwise if else elsif fin while loop return primary=done include import export struc const word byte var char res and predef asm def end not or repeat until continue break for to downto next step when wend is otherwise if else elsif fin while loop return
[settings] [settings]
# default extension used when saving files # default extension used when saving files