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
//
const _VERSION_ = $0100
const FALSE = 0
const TRUE = not FALSE
const NULL = 0
const _SYSVER_ = $0100 // Version built against
const FALSE = 0
const TRUE = not FALSE
const NULL = 0
//
// Machine ID values
//
const MACHID_CLOCK = $01
const MACHID_80COL = $02
const MACHID_MEM = $03
const MACHID_48K = $10
const MACHID_64K = $20
const MACHID_128K = $30
const MACHID_MODEL = $C8
@ -24,10 +23,6 @@ import cmdsys
const MACHID_I = $08
byte MACHID
//
// System path
//
byte syspath
//
// System flags: memory allocator screen holes.
//
const restxt1 = $0001
@ -44,12 +39,23 @@ import cmdsys
const modkeep = $2000
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
//
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 heapmark()#1, heapallocalign(size, pow2, freeaddr)#1, heapalloc(size)#1, heaprelease(newheap)#1, heapavail()#1
predef memset(addr,value,size)#0, memcpy(dst,src,size)#0
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 modload(mod)#1, modexec(modfile)#1, modaddr(str)#1
predef heapmark()#1, heapallocalign(size, pow2, freeaddr)#1
predef heapalloc(size)#1, heaprelease(newheap)#1, heapavail()#1
predef memset(addr,value,size)#0, memcpy(dst,src,size)#0, strcpy(dst,src)#1, strcat(dst,src)#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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -16,7 +16,8 @@ end
// External interface to SANE libraries
//
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
//
@ -720,16 +721,6 @@ end
// loop
// loop
//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
//
@ -740,7 +731,7 @@ def loadcode(codefile)
//puts(codefile); puts(":\n")
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
if ref
pcode = heapmark

View File

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

View File

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

View File

@ -297,7 +297,7 @@ iB = 4
iC = -1
zero = 0
puts("SANE sanity test...\n")
sane.initFP()
sane:initFP()
sane:saveZP()
sane:op2FP(FFINT|FOZ2X, @xT, @iA) // Convert int A 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.
//
predef puth(h)#0
export word print[] = @puti, @puth, @putln, @puts, @putc
predef puthex(h)#0
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 loadstr[] = "testlib loaded!"
//
// Define functions.
//
def puth(h)#0
def puthex(h)#0
putc('$')
putc(valstr[(h >> 12) & $0F])
putc(valstr[(h >> 8) & $0F])

View File

@ -449,7 +449,10 @@ void emit_moddep(char *name, int len)
if (outflags & MODULE)
{
if (name)
{
emit_dci(name, len);
idglobal_add(name, len, EXTERN_TYPE | WORD_TYPE, 2); // Add to symbol table
}
else
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)
return crunched;
switch (op->code)
{
case CONST_CODE:
@ -1005,19 +1007,16 @@ int try_dupify(t_opseq *op)
case GADDR_CODE:
case LAB_CODE:
case LAW_CODE:
if ((op->tag != opn->tag) || (op->offsz != opn->offsz) ||
(op->type != opn->type))
if ((op->tag != opn->tag) || (op->offsz != opn->offsz) /*|| (op->type != opn->type)*/)
return crunched;
break;
default:
return crunched;
}
opn->code = DUP_CODE;
crunched = 1;
crunched = 1;
}
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
//
def new_tag(type)
@ -564,10 +539,11 @@ end
//
// Module dependency list
//
def new_moddep(strptr, strlen)#0
if strlen > 15; strlen = 15; fin
memcpy(@moddep_tbl[moddep_cnt*16] + 1, strptr, strlen)
moddep_tbl[moddep_cnt*16] = strlen
def new_moddep(nameptr, len)#0
if len > 15; len = 15; fin
new_iddata(nameptr, len, EXTERN_TYPE|WORD_TYPE, 2)
memcpy(@moddep_tbl[moddep_cnt*16] + 1, nameptr, len)
moddep_tbl[moddep_cnt*16] = len
moddep_cnt++
if moddep_cnt > 8; parse_warn("Module dependency overflow"); fin
end

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -91,12 +91,10 @@ byte uisltstr[] = "ISULT"
byte uislestr[] = "ISULE"
byte sextstr[] = "SEXT"
byte divmodstr[] = "DIVMOD"
byte loadstr[] = "MODLOAD"
byte execstr[] = "MODEXEC"
byte modadrstr[] = "MODADDR"
byte argstr[] = "ARGS"
byte syspath[] = "" // Set to NULL
word exports[] = @sysstr, @syscall
word exports[] = @syslibstr, @version
word = @sysstr, @syscall
word = @callstr, @call
word = @putcstr, @cout
word = @putlnstr, @crout
@ -118,9 +116,6 @@ word = @uisltstr, @uword_islt
word = @uislestr, @uword_isle
word = @sextstr, @sext
word = @divmodstr, @divmod
word = @loadstr, @loadmod
word = @execstr, @execmod
word = @modadrstr, @lookupstrmod
word = @machidstr, @machid
word = @syspathstr,@syspath
word = @argstr, @cmdptr
@ -498,38 +493,6 @@ end
// 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.
//
@ -635,47 +598,53 @@ def rdstr(prompt)#1
cout(prompt)
repeat
ch = cin
when ch
is $15 // right arrow
if inbuff.0 < maxlen
inbuff.0 = inbuff.0 + 1
ch = inbuff[inbuff.0]
cout(ch)
fin
is $08 // left arrow
if inbuff.0
cout('\\')
cout(inbuff[inbuff.0])
inbuff.0 = inbuff.0 - 1
fin
is $04 // ctrl-d
if inbuff.0
cout('#')
cout(inbuff[inbuff.0])
memcpy(inbuff + inbuff.0, inbuff + inbuff.0 + 1, maxlen - inbuff.0)
maxlen = maxlen - 1
inbuff.0 = inbuff.0 - 1
fin
is $0C // ctrl-l
crout
prstr(inbuff)
is $0D // return
is $18 // ctrl-x
crout
inbuff.0 = 0
is $9B // escape
inbuff.0 = 0
ch = $0D
otherwise
if ch >= ' '
cout(ch)
inbuff.0 = inbuff.0 + 1
inbuff[inbuff.0] = ch
if inbuff.0 > maxlen
maxlen = inbuff.0
fin
fin
wend
when ch
is $15 // right arrow
if ^inbuff < maxlen //inbuff.0 < maxlen
inbuff.0 = inbuff.0 + 1
ch = inbuff[inbuff.0]
cout(ch)
fin
break
is $08 // left arrow
if inbuff.0
cout('\\')
cout(inbuff[inbuff.0])
inbuff.0 = inbuff.0 - 1
fin
break
is $04 // ctrl-d
if inbuff.0
cout('#')
cout(inbuff[inbuff.0])
memcpy(inbuff + inbuff.0, inbuff + inbuff.0 + 1, maxlen - inbuff.0)
maxlen = maxlen - 1
inbuff.0 = inbuff.0 - 1
fin
break
is $0C // ctrl-l
crout
prstr(inbuff)
break
is $0D // return
is $18 // ctrl-x
crout
inbuff.0 = 0
break
is $9B // escape
inbuff.0 = 0
ch = $0D
break
otherwise
if ch >= ' '
cout(ch)
inbuff.0 = inbuff.0 + 1
inbuff[inbuff.0] = ch
if inbuff.0 > maxlen
maxlen = inbuff.0
fin
fin
wend
until ch == $0D or inbuff.0 == $7F
cout($0D)
return inbuff
@ -764,19 +733,6 @@ end
//
// 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
word sym, addr
byte str[16]
@ -850,7 +806,7 @@ def loadmod(mod)#1
// Load module dependencies.
//
while ^moddep
if !lookupmod(moddep)
if !lookuptbl(moddep, symtbl)
if loadmod(moddep) < 0
return -perr
fin
@ -880,7 +836,7 @@ def loadmod(mod)#1
//
// Add module to symbol table.
//
addmod(mod, modaddr)
addsym(mod, modaddr)
//
// Apply all fixups and symbol import/export.
//
@ -1054,8 +1010,6 @@ prstr(@verstr); prbyte(version.1); cout('.'); prbyte(version.0); crout
symtbl = allocheap($200)
lastsym = symtbl
^lastsym = 0
stodci(@syslibstr, heap)
addmod(heap, @version)
while *syslibsym
stodci(syslibsym=>0, heap)
addsym(heap, syslibsym=>2)

View File

@ -25,32 +25,35 @@ const modinitkeep = $4000
// Pedefined functions.
//
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 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 loadmod(mod)#1, execmod(modfile)#1, lookupstrmod(str)#1
predef execmod(modfile)#1
//
// System variable.
// Exported CMDSYS table
//
word version = $0100 // 01.00
word systemflags = 0
word heap
word xheap = $0800
word lastsym = symtbl
byte perr
byte cmdln = "" // Overlay exported strings table
word version = $0100 // 01.00
word syspath
word = getlnbuf
word = @execmod
word = getlnbuf
//
// Working input buffer overlayed with strings table
//
byte cmdln = ""
//
// Standard Library exported functions.
//
byte syslibstr = "CMDSYS"
byte sysmodstr = "CMDSYS"
byte machidstr = "MACHID"
byte syspathstr = "SYSPATH"
byte sysstr = "SYSCALL"
byte callstr = "CALL"
byte putcstr = "PUTC"
byte putlnstr = "PUTLN"
byte putsstr = "PUTS"
byte putbstr = "PUTB"
byte putwstr = "PUTH"
byte putistr = "PUTI"
byte getcstr = "GETC"
byte getsstr = "GETS"
@ -66,20 +69,21 @@ byte uisgtstr = "ISUGT"
byte uisgestr = "ISUGE"
byte uisltstr = "ISULT"
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 divmodstr = "DIVMOD"
byte loadstr = "MODLOAD"
byte execstr = "MODEXEC"
byte modadrstr = "MODADDR"
byte argstr = "ARGS"
byte autorun = "AUTORUN"
byte prefix[] // overlay with exported symbols table
word exports = @sysstr, @syscall
word exports = @sysmodstr, @version
word = @sysstr, @syscall
word = @callstr, @call
word = @putcstr, @cout
word = @putlnstr, @crout
word = @putsstr, @prstr
word = @putbstr, @prbyte
word = @putwstr, @prword
word = @putistr, @print
word = @getcstr, @cin
word = @getsstr, @rdstr
@ -95,16 +99,21 @@ word = @uisgtstr, @uword_isgt
word = @uisgestr, @uword_isge
word = @uisltstr, @uword_islt
word = @uislestr, @uword_isle
word = @strcpystr, @strcpy
word = @strcatstr, @strcat
word = @sextstr, @sext
word = @divmodstr, @divmod
word = @loadstr, @loadmod
word = @execstr, @execmod
word = @modadrstr, @lookupstrmod
word = @machidstr, MACHID
word = @syspathstr,@syspath
word = @argstr, @cmdln
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
//
@ -635,43 +644,6 @@ TOUPR AND #$7F
RTS
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.
//
//def lookuptbl(dci, tbl)
@ -877,13 +849,13 @@ end
def addsym(sym, addr)#0
while ^sym & $80
^lastsym = ^sym
lastsym = lastsym + 1
sym = sym + 1
lastsym++
sym++
loop
lastsym->0 = ^sym
lastsym=>1 = addr
lastsym = lastsym + 3
^lastsym = 0
lastsym = lastsym + 3
^lastsym = 0
end
//
// String routines.
@ -901,19 +873,6 @@ end
//
// 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
word sym, addr
byte str[16]
@ -971,7 +930,7 @@ def loadmod(mod)#1
//
// Try system path
//
refnum = open(strcpy(@filename,strcat(strcpy(@header, @syspath), @filename)))
refnum = open(strcpy(@filename,strcat(strcpy(@header, @sysmods), @filename)))
fin
if refnum
rdlen = read(refnum, @header, 128)
@ -992,7 +951,7 @@ def loadmod(mod)#1
// Load module dependencies.
//
while ^moddep
if !lookupmod(moddep)
if !lookuptbl(moddep, symtbl)//lookupmod(moddep)
close(refnum)
refnum = 0
if loadmod(moddep) < 0
@ -1036,7 +995,7 @@ def loadmod(mod)#1
//
// Add module to symbol table.
//
addmod(mod, modaddr)
addsym(mod, modaddr)//addmod(mod, modaddr)
//
// Apply all fixups and symbol import/export.
//
@ -1272,7 +1231,7 @@ def striptrail(strptr)#1
for i = 1 to ^strptr
if ^(strptr + i) <= ' '
^strptr = i - 1
return strptr
break
fin
next
return strptr
@ -1359,23 +1318,22 @@ prstr("PLASMA Pre "); prbyte(version.1); cout('.'); prbyte(version.0); crout
//
// Init symbol table.
//
stodci(@syslibstr, heap)
addmod(heap, @version)
while *syslibsym
stodci(syslibsym=>0, heap)
addsym(heap, syslibsym=>2)
syslibsym = syslibsym + 4
while *sysmodsym
stodci(sysmodsym=>0, heap)
addsym(heap, sysmodsym=>2)
sysmodsym = sysmodsym + 4
loop
//
// 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.
//
autorun = open(@autorun)
if autorun > 0
cmdln = read(autorun, @syslibstr, 128)
cmdln = read(autorun, @sysmodstr, 128)
close(autorun)
else
//
@ -1396,6 +1354,14 @@ while 1
is 'P'
setpfx(@cmdln)
break
is '/'
repeat
prefix--
until prefix[prefix] == '/'
if prefix > 1
setpfx(@prefix)
fin
break
is 'V'
volumes()
break
@ -1424,6 +1390,6 @@ while 1
crout()
fin
prstr(getpfx(@prefix))
memcpy(@cmdln, rdstr($BA), 128)
strcpy(@cmdln, rdstr($BA))
loop
done

View File

@ -40,17 +40,47 @@ word *esp = eval_stack + EVAL_STACKSZ;
#define SYMTBLSZ 1024
#define SYMSZ 16
#define MODTBLSZ 128
#define MODSZ 16
#define MODLSTSZ 32
byte symtbl[SYMTBLSZ];
byte *lastsym = symtbl;
byte modtbl[MODTBLSZ];
byte *lastmod = modtbl;
/*
* Predef.
*/
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.
*
@ -181,19 +211,6 @@ uword add_sym(byte *sym, int addr)
/*
* 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)
{
mem_data[lastdef] = bank ? 2 : 1;
@ -204,7 +221,7 @@ uword defcall_add(int bank, int addr)
uword def_lookup(byte *cdd, int defaddr)
{
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)
{
@ -263,7 +280,7 @@ int load_mod(byte *mod)
*/
while (*moddep)
{
if (lookup_mod(moddep) == 0)
if (lookup_sym(moddep) == 0)
{
if (fd)
{
@ -324,7 +341,7 @@ int load_mod(byte *mod)
/*
* Add module to symbol table.
*/
add_mod(mod, modaddr);
add_sym(mod, modaddr);
/*
* Print out the Re-Location Dictionary.
*/
@ -337,6 +354,7 @@ int load_mod(byte *mod)
if (show_state) printf("\tDEF CODE");
addr = rld[1] | (rld[2] << 8);
addr += modfix - MOD_ADDR;
rld[0] = 0; // Set call code to 0
rld[1] = addr;
rld[2] = addr >> 8;
end = rld - mem_data + 4;
@ -440,25 +458,29 @@ void call(uword pc)
char c, sz[64];
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++])
{
case 0: // NULL call
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
case 0: // BYTECODE in mem_data
interp(mem_data + (mem_data[pc] + (mem_data[pc + 1] << 8)));
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
c = POP;
if (c == 0x0D)
c = '\n';
putchar(c);
break;
case 4: // LIBRARY STDLIB::PUTS
case 4: // LIBRARY STDLIB::PUTNL
putchar('\n');
fflush(stdout);
break;
case 5: // LIBRARY STDLIB::PUTS
s = POP;
i = mem_data[s++];
while (i--)
@ -469,19 +491,14 @@ void call(uword pc)
putchar(c);
}
break;
case 5: // LIBRARY STDLIB::PUTSZ
s = POP;
while ((c = mem_data[s++]))
{
if (c == 0x0D)
c = '\n';
putchar(c);
}
case 6: // LIBRARY STDLIB::PUTI
i = POP;
printf("%d", i);
break;
case 6: // LIBRARY STDLIB::GETC
case 7: // LIBRARY STDLIB::GETC
PUSH(getchar());
break;
case 7: // LIBRARY STDLIB::GETS
case 8: // LIBRARY STDLIB::GETS
gets(sz);
for (i = 0; sz[i]; i++)
mem_data[0x200 + i] = sz[i];
@ -489,19 +506,8 @@ void call(uword pc)
mem_data[0x1FF] = i;
PUSH(i);
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:
printf("\nBad call code:$%02X\n", mem_data[pc - 1]);
printf("\nUnimplemented call code:$%02X\n", mem_data[pc - 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)
{
byte dci[32];
@ -904,17 +898,16 @@ int main(int argc, char **argv)
/*
* Add default library.
*/
stodci("CMDSYS", dci);
add_mod(dci, 0xFFFF);
for (i = 0; syslib_exp[i]; i++)
{
mem_data[i] = i + 3;
mem_data[i] = i;
stodci(syslib_exp[i], dci);
add_sym(dci, i);
add_sym(dci, i+1);
}
if (argc)
{
stodci(*argv, dci);
if (show_state) dump_sym();
load_mod(dci);
if (show_state) dump_sym();
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 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 loadmod(mod)#1, execmod(modfile)#1, lookupstrmod(str)#1
predef execmod(modfile)#1
//
// System variables.
//
word version = $0100 // 01.00
word systemflags = 0
word syspath
word cmdptr
word = @execmod
byte refcons = 0
byte devcons = 0
word heap = $2000
byte modid = 0
byte modseg[15]
word symtbl, lastsym
byte perr, terr, lerr
//
// 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
//
// Command line pointer
//
word cmdptr
//
// Standard Library exported functions.
//
byte syslibstr[] = "CMDSYS"
byte sysmodstr[] = "CMDSYS"
byte machidstr[] = "MACHID"
byte syspathstr[] = "SYSPATH"
byte sysstr[] = "SYSCALL"
byte callstr[] = "CALL"
byte putcstr[] = "PUTC"
@ -84,15 +76,15 @@ byte uisgtstr[] = "ISUGT"
byte uisgestr[] = "ISUGE"
byte uisltstr[] = "ISULT"
byte uislestr[] = "ISULE"
byte syspath[] // overlay with exported strings
byte sysmods[] // overlay with exported strings
byte sextstr[] = "SEXT"
byte divmodstr[] = "DIVMOD"
byte loadstr[] = "MODLOAD"
byte execstr[] = "MODEXEC"
byte modadrstr[] = "MODADDR"
byte argstr[] = "ARGS"
byte prefix[] // Overlay with exported symbols table
word exports[] = @sysstr, @syscall
word exports[] = @sysmodstr, @version
word = @sysstr, @syscall
word = @callstr, @call
word = @putcstr, @cout
word = @putlnstr, @crout
@ -114,14 +106,18 @@ word = @uisltstr, @uword_islt
word = @uislestr, @uword_isle
word = @sextstr, @sext
word = @divmodstr, @divmod
word = @loadstr, @loadmod
word = @execstr, @execmod
word = @modadrstr, @lookupstrmod
word = @machidstr, @machid
word = @syspathstr,@syspath
word = @argstr, @cmdptr
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
// SYSCALL(CMD, PARAMS)
@ -570,27 +566,27 @@ end
// 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
//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.
//
@ -941,19 +937,14 @@ end
//
// 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 lookupmod(mod)#1
// byte dci[17]
// return lookuptbl(modtosym(mod, @dci), symtbl)
//end
//def addmod(mod, addr)#0
// byte dci[17]
// addsym(modtosym(mod, @dci), addr)
//end
def lookupextern(esd, index)#1
word sym, addr
byte str[16]
@ -1010,7 +1001,7 @@ def loadmod(mod)#1
//
// Try system path
//
refnum = open(strcpy(@filename,strcat(strcpy(@header, @syspath), @filename)))
refnum = open(strcpy(@filename,strcat(strcpy(@header, @sysmods), @filename)))
fin
if refnum
rdlen = read(refnum, @header, 128)
@ -1031,7 +1022,7 @@ def loadmod(mod)#1
// Load module dependencies.
//
while ^moddep
if !lookupmod(moddep)
if !lookuptbl(moddep, symtbl)
if refnum
close(refnum)
refnum = 0
@ -1077,7 +1068,7 @@ def loadmod(mod)#1
//
// Add module to symbol table.
//
addmod(mod, modaddr)
addsym(mod, modaddr)
//
// Apply all fixups and symbol import/export.
//
@ -1292,15 +1283,16 @@ def stripspaces(strptr)#0
^strptr = ^strptr - 1
loop
end
def striptrail(strptr)#0
def striptrail(strptr)#1
byte i
for i = 1 to ^strptr
if (strptr)[i] <= ' '
^strptr = i - 1
return
break
fin
next
return strptr
end
def parsecmd(strptr)#1
byte cmd
@ -1353,17 +1345,16 @@ prstr("PLASMA "); prbyte(version.1); cout('.'); prbyte(version.0); crout
seg_find($00, @symtbl, @lastsym, $08, $11)
lastsym = symtbl & $FF00
xpokeb(symtbl.0, lastsym, 0)
stodci(@syslibstr, heap)
addmod(heap, @version)
while *syslibsym
stodci(syslibsym=>0, heap)
addsym(heap, syslibsym=>2)
syslibsym = syslibsym + 4
while *sysmodsym
stodci(sysmodsym=>0, heap)
addsym(heap, sysmodsym=>2)
sysmodsym = sysmodsym + 4
loop
//
// Clear system path
//
syspath = 0
sysmods = 0
syspath = @sysmods
//
// Try to load autorun.
//
@ -1398,13 +1389,13 @@ while 1
break
is 'S'
setpfx(cmdptr)
strcat(getpfx(@syspath), "SYS/"))
strcat(getpfx(@sysmods), "SYS/"))
break
is 'V'
volumes
break
is '+'
execmod(cmdptr)
execmod(striptrail(cmdptr))
write(refcons, @textmode, 3)
break
otherwise

View File

@ -38,7 +38,7 @@ pod=comment_doc
[keywords]
# 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]
# default extension used when saving files