From cf32a423642f7d8033c7aece44214d36131adac8 Mon Sep 17 00:00:00 2001
From: David Schmenk <dschmenk@gmail.com>
Date: Wed, 10 Jan 2018 09:27:54 -0800
Subject: [PATCH 01/16] PLASMA 1.0 code complete (but not fully tested)

---
 src/toolsrc/ed.pla    |  2 +-
 src/toolsrc/plasm.pla |  1 +
 src/vmsrc/a1cmd.pla   | 14 +++++++--
 src/vmsrc/cmd.pla     | 70 ++++++++++++++++++++++++++++++-------------
 src/vmsrc/soscmd.pla  | 40 +++++++++++++++++++++++--
 5 files changed, 100 insertions(+), 27 deletions(-)

diff --git a/src/toolsrc/ed.pla b/src/toolsrc/ed.pla
index 233da1e..99fd323 100755
--- a/src/toolsrc/ed.pla
+++ b/src/toolsrc/ed.pla
@@ -1003,7 +1003,7 @@ def cmdmode#0
     word cmdptr
 
     clrscrn
-    puts("PLASMA ][ EDITOR VERSION 0.99\n")
+    puts("PLASMA Editor, Version 1.0\n")
     while not exit
         puts(@filename)
         cmdptr = gets($BA)
diff --git a/src/toolsrc/plasm.pla b/src/toolsrc/plasm.pla
index e8fbb9e..638811f 100644
--- a/src/toolsrc/plasm.pla
+++ b/src/toolsrc/plasm.pla
@@ -414,6 +414,7 @@ include "toolsrc/parse.pla"
 //
 // Look at command line arguments and compile module
 //
+puts("PLASMA Compiler, Version 1.0\n")
 arg = argNext(argFirst)
 if ^arg and ^(arg + 1) == '-'
     opt          = arg + 2
diff --git a/src/vmsrc/a1cmd.pla b/src/vmsrc/a1cmd.pla
index 6eb06cf..15063a1 100755
--- a/src/vmsrc/a1cmd.pla
+++ b/src/vmsrc/a1cmd.pla
@@ -34,12 +34,12 @@ predef syscall(cmd,null)#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 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, 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
 //
 // System variables.
 //
-word version     = $0099 // 00.99
+word version     = $0100 // 01.00
 word systemflags = 0
 word heap
 word symtbl, lastsym
@@ -88,6 +88,7 @@ byte uisgtstr[]   = "ISUGT"
 byte uisgestr[]   = "ISUGE"
 byte uisltstr[]   = "ISULT"
 byte uislestr[]   = "ISULE"
+byte sextstr[]    = "SEXT"
 byte divmodstr[]  = "DIVMOD"
 byte loadstr[]    = "MODLOAD"
 byte execstr[]    = "MODEXEC"
@@ -113,6 +114,7 @@ word              = @uisgtstr,  @uword_isgt
 word              = @uisgestr,  @uword_isge
 word              = @uisltstr,  @uword_islt
 word              = @uislestr,  @uword_isle
+word              = @sextstr,   @sext
 word              = @divmodstr, @divmod
 word              = @loadstr,   @loadmod
 word              = @execstr,   @execmod
@@ -375,6 +377,14 @@ _divmod DEX
     STA ESTKH,X
     RTS
 end
+asm sext(a)#1
+    LDY #$00
+    LDA ESTKL,X
+    BPL +
+    DEY
++   STY ESTKH,X
+    RTS
+end
 //
 // Addresses of internal routines.
 //
diff --git a/src/vmsrc/cmd.pla b/src/vmsrc/cmd.pla
index 583a8b9..8f580bf 100755
--- a/src/vmsrc/cmd.pla
+++ b/src/vmsrc/cmd.pla
@@ -28,12 +28,12 @@ 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 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 uword_isgt(a,b)#1, uword_isge(a,b)#1, uword_islt(a,b)#1, uword_isle(a,b)#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
 //
 // System variable.
 //
-word version     = $0099 // 00.99
+word version     = $0100 // 01.00
 word systemflags = 0
 word heap
 word xheap       = $0800
@@ -59,12 +59,14 @@ byte hpalignstr = "HEAPALLOCALIGN"
 byte hpallocstr = "HEAPALLOC"
 byte hprelstr   = "HEAPRELEASE"
 byte hpavlstr   = "HEAPAVAIL"
-byte memsetstr  = "MEMSET"
+word memsetstr  = "MEMSET"
 byte memcpystr  = "MEMCPY"
 byte uisgtstr   = "ISUGT"
 byte uisgestr   = "ISUGE"
 byte uisltstr   = "ISULT"
 byte uislestr   = "ISULE"
+byte syspath[] // overlay with exported strings
+byte sextstr    = "SEXT"
 byte divmodstr  = "DIVMOD"
 byte loadstr    = "MODLOAD"
 byte execstr    = "MODEXEC"
@@ -92,6 +94,7 @@ word            = @uisgtstr,  @uword_isgt
 word            = @uisgestr,  @uword_isge
 word            = @uisltstr,  @uword_islt
 word            = @uislestr,  @uword_isle
+word            = @sextstr,   @sext
 word            = @divmodstr, @divmod
 word            = @loadstr,   @loadmod
 word            = @execstr,   @execmod
@@ -534,6 +537,14 @@ _divmod DEX
         STA     ESTKH,X
         RTS
 end
+asm sext(a)#1
+        LDY     #$00
+        LDA     ESTKL,X
+        BPL     +
+        DEY
++       STY     ESTKH,X
+        RTS
+end
 //
 // Utility routines.
 //
@@ -757,12 +768,12 @@ def setpfx(path)#1
     perr     = syscall($C6, @params)
     return path
 end
-def open(path, buff)#1
+def open(path)#1
     byte params[6]
 
     params.0 = 3
     params:1 = path
-    params:3 = buff
+    params:3 = iobuffer
     params.5 = 0
     perr     = syscall($C8, @params)
     return params.5
@@ -882,6 +893,19 @@ def addsym(sym, addr)#0
     ^lastsym    = 0
 end
 //
+// String routines.
+//
+def strcpy(dst, src)#1
+    memcpy(dst+1, src+1, ^src)
+    ^dst = ^src
+    return dst
+end
+def strcat(dst, src)#1
+    memcpy(dst + ^dst + 1, src + 1, ^src)
+    ^dst = ^dst + ^src
+    return dst
+end
+//
 // Module routines.
 //
 def lookupmod(mod)#1
@@ -939,18 +963,24 @@ def lookupdef(addr, deftbl)#1
     return 0
 end
 def loadmod(mod)#1
-    word refnum, rdlen, modsize, bytecode, codefix, defofst, defcnt, init, fixup
+    word rdlen, modsize, bytecode, codefix, defofst, defcnt, init, fixup
     word addr, defaddr, modaddr, modfix, modofst, modend
     word deftbl, deflast
     word moddep, rld, esd, sym
-    byte defbank, str[16], filename[64]
+    byte refnum, defbank, str[16], filename[64]
     byte header[128]
     //
     // Read the RELocatable module header (first 128 bytes)
     //
     dcitos(mod, @filename)
-    refnum = open(@filename, iobuffer)
-    if refnum > 0
+    refnum = open(@filename)
+    if !refnum
+        //
+        // Try system path
+        //
+        refnum = open(strcpy(@filename,strcat(strcpy(@header, @syspath), @filename)))
+    fin
+    if refnum
         rdlen   = read(refnum, @header, 128)
         modsize = header:0
         moddep  = @header.1
@@ -988,7 +1018,7 @@ def loadmod(mod)#1
                 //
                 // Reset read pointer.
                 //
-                refnum = open(@filename, iobuffer)
+                refnum = open(@filename)
                 rdlen  = read(refnum, @header, 128)
             fin
         fin
@@ -1181,7 +1211,7 @@ def catalog(optpath)#1
         prstr(@path)
         crout()
     fin
-    refnum = open(@path, iobuffer)
+    refnum = open(@path)
     if perr
         return perr
     fin
@@ -1287,7 +1317,7 @@ def execsys(sysfile)#0
     if ^sysfile
         memcpy($280, sysfile, ^sysfile + 1)
         striptrail(sysfile)
-        refnum = open(sysfile, iobuffer)
+        refnum = open(sysfile)
         if refnum
             len = read(refnum, databuff, $FFFF)
             resetmemfiles()
@@ -1340,9 +1370,13 @@ while *syslibsym
     syslibsym = syslibsym + 4
 loop
 //
+// Set system path
+//
+strcat(getpfx(@syspath), "SYS/"))
+//
 // Try to load autorun.
 //
-autorun = open(@autorun, iobuffer)
+autorun = open(@autorun)
 if autorun > 0
     cmdln = read(autorun, @syslibstr, 128)
     close(autorun)
@@ -1350,14 +1384,8 @@ else
     //
     // Print some startup info.
     //
-    prstr("PLASMA ")
-    prbyte(version.1)
-    cout('.')
-    prbyte(version.0)
-    crout
-    prstr("MEM FREE:$")
-    prword(availheap)
-    crout
+    prstr("PLASMA "); prbyte(version.1); cout('.'); prbyte(version.0); crout
+    prstr("MEM FREE:$"); prword(availheap); crout
 fin
 perr = 0
 while 1
diff --git a/src/vmsrc/soscmd.pla b/src/vmsrc/soscmd.pla
index 82d9e2b..8240e1b 100755
--- a/src/vmsrc/soscmd.pla
+++ b/src/vmsrc/soscmd.pla
@@ -29,12 +29,12 @@ 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 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, 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
 //
 // System variables.
 //
-word version     = $0099 // 00.99
+word version     = $0100 // 01.00
 word systemflags = 0
 byte refcons     = 0
 byte devcons     = 0
@@ -83,6 +83,8 @@ byte uisgtstr[]   = "ISUGT"
 byte uisgestr[]   = "ISUGE"
 byte uisltstr[]   = "ISULT"
 byte uislestr[]   = "ISULE"
+byte syspath[] // overlay with exported strings
+byte sextstr[]    = "SEXT"
 byte divmodstr[]  = "DIVMOD"
 byte loadstr[]    = "MODLOAD"
 byte execstr[]    = "MODEXEC"
@@ -109,6 +111,7 @@ word              = @uisgtstr,  @uword_isgt
 word              = @uisgestr,  @uword_isge
 word              = @uisltstr,  @uword_islt
 word              = @uislestr,  @uword_isle
+word              = @sextstr,   @sext
 word              = @divmodstr, @divmod
 word              = @loadstr,   @loadmod
 word              = @execstr,   @execmod
@@ -436,6 +439,14 @@ _divmod DEX
         STA     ESTKH,X
         RTS
 end
+asm sext(a)#1
+        LDY     #$00
+        LDA     ESTKL,X
+        BPL     +
+        DEY
++       STY     ESTKH,X
+        RTS
+end
 //
 // Addresses of internal routines.
 //
@@ -913,6 +924,19 @@ def addsym(sym, addr)#0
     lastsym = lastsym + 3
 end
 //
+// String routines.
+//
+def strcpy(dst, src)#1
+    memcpy(dst+1, src+1, ^src)
+    ^dst = ^src
+    return dst
+end
+def strcat(dst, src)#1
+    memcpy(dst + ^dst + 1, src + 1, ^src)
+    ^dst = ^dst + ^src
+    return dst
+end
+//
 // Module routines.
 //
 def lookupmod(mod)#1
@@ -980,7 +1004,13 @@ def loadmod(mod)#1
     //
     dcitos(mod, @filename)
     refnum = open(@filename)
-    if refnum > 0
+    if !refnum
+        //
+        // Try system path
+        //
+        refnum = open(strcpy(@filename,strcat(strcpy(@header, @syspath), @filename)))
+    fin
+    if refnum
         rdlen   = read(refnum, @header, 128)
         modsize = header:0
         moddep  = @header.1
@@ -1325,6 +1355,10 @@ while *syslibsym
     syslibsym = syslibsym + 4
 loop
 //
+// Set system path
+//
+strcat(getpfx(@syspath), "SYS/"))
+//
 // Try to load autorun.
 //
 cmdptr  = heap

From 6213bbf3ef14d5003ddf27ceb4f4efb08878aeec Mon Sep 17 00:00:00 2001
From: David Schmenk <dschmenk@gmail.com>
Date: Wed, 10 Jan 2018 10:03:23 -0800
Subject: [PATCH 02/16] Allow SOS PLASMA to set system path

---
 src/vmsrc/a1cmd.pla  |  9 ++++-----
 src/vmsrc/cmd.pla    |  5 ++++-
 src/vmsrc/soscmd.pla | 17 ++++++++++-------
 3 files changed, 18 insertions(+), 13 deletions(-)

diff --git a/src/vmsrc/a1cmd.pla b/src/vmsrc/a1cmd.pla
index 15063a1..e9b011b 100755
--- a/src/vmsrc/a1cmd.pla
+++ b/src/vmsrc/a1cmd.pla
@@ -1038,6 +1038,10 @@ def execmod(modfile)#1
     return -perr
 end
 //
+// Print PLASMA version
+//
+prstr(@verstr); prbyte(version.1); cout('.'); prbyte(version.0); crout
+//
 // Get heap start.
 //
 heap = *freemem
@@ -1068,11 +1072,6 @@ perr = 0
 // Print some startup info.
 //
 if not ^cmdptr
-    prstr(@verstr)
-    prbyte(version.1)
-    cout('.')
-    prbyte(version.0)
-    crout
     prstr(@freestr)
     prword(availheap)
     crout
diff --git a/src/vmsrc/cmd.pla b/src/vmsrc/cmd.pla
index 8f580bf..25cfcb9 100755
--- a/src/vmsrc/cmd.pla
+++ b/src/vmsrc/cmd.pla
@@ -1356,6 +1356,10 @@ def execmod(modfile)#1
     return -perr
 end
 //
+// Print PLASMA version
+//
+prstr("PLASMA "); prbyte(version.1); cout('.'); prbyte(version.0); crout
+//
 // Get heap start.
 //
 heap = *freemem
@@ -1384,7 +1388,6 @@ else
     //
     // Print some startup info.
     //
-    prstr("PLASMA "); prbyte(version.1); cout('.'); prbyte(version.0); crout
     prstr("MEM FREE:$"); prword(availheap); crout
 fin
 perr = 0
diff --git a/src/vmsrc/soscmd.pla b/src/vmsrc/soscmd.pla
index 8240e1b..49823ce 100755
--- a/src/vmsrc/soscmd.pla
+++ b/src/vmsrc/soscmd.pla
@@ -1342,6 +1342,10 @@ end
 //
 init_cons
 //
+// Print PLASMA version
+//
+prstr("PLASMA "); prbyte(version.1); cout('.'); prbyte(version.0); crout
+//
 // Init 2K symbol table.
 //
 seg_find($00, @symtbl, @lastsym, $08, $11)
@@ -1355,9 +1359,9 @@ while *syslibsym
     syslibsym = syslibsym + 4
 loop
 //
-// Set system path
+// Clear system path
 //
-strcat(getpfx(@syspath), "SYS/"))
+syspath = 0
 //
 // Try to load autorun.
 //
@@ -1371,11 +1375,6 @@ else
     //
     // Print some startup info.
     //
-    prstr("PLASMA ")
-    prbyte(version.1)
-    cout('.')
-    prbyte(version.0)
-    crout
     prstr("MEM:$")
     prword(availheap)
     crout
@@ -1395,6 +1394,10 @@ while 1
             is 'P'
                 setpfx(cmdptr)
                 break
+            is 'S'
+                setpfx(cmdptr)
+                strcat(getpfx(@syspath), "SYS/"))
+                break
             is 'V'
                 volumes
                 break

From a58f3639a519c3124e9b9ad6d8f6f64a881313df Mon Sep 17 00:00:00 2001
From: David Schmenk <dschmenk@gmail.com>
Date: Wed, 10 Jan 2018 10:29:27 -0800
Subject: [PATCH 03/16] Print banner *after* setting heap address

---
 src/vmsrc/a1cmd.pla | 8 ++++----
 src/vmsrc/cmd.pla   | 8 ++++----
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/src/vmsrc/a1cmd.pla b/src/vmsrc/a1cmd.pla
index e9b011b..adad124 100755
--- a/src/vmsrc/a1cmd.pla
+++ b/src/vmsrc/a1cmd.pla
@@ -1038,14 +1038,14 @@ def execmod(modfile)#1
     return -perr
 end
 //
-// Print PLASMA version
-//
-prstr(@verstr); prbyte(version.1); cout('.'); prbyte(version.0); crout
-//
 // Get heap start.
 //
 heap = *freemem
 //
+// Print PLASMA version
+//
+prstr(@verstr); prbyte(version.1); cout('.'); prbyte(version.0); crout
+//
 // Init symbol table.
 //
 symtbl   = allocheap($200)
diff --git a/src/vmsrc/cmd.pla b/src/vmsrc/cmd.pla
index 25cfcb9..eb003d4 100755
--- a/src/vmsrc/cmd.pla
+++ b/src/vmsrc/cmd.pla
@@ -1356,14 +1356,14 @@ def execmod(modfile)#1
     return -perr
 end
 //
-// Print PLASMA version
-//
-prstr("PLASMA "); prbyte(version.1); cout('.'); prbyte(version.0); crout
-//
 // Get heap start.
 //
 heap = *freemem
 //
+// Print PLASMA version
+//
+prstr("PLASMA "); prbyte(version.1); cout('.'); prbyte(version.0); crout
+//
 // Init symbol table.
 //
 stodci(@syslibstr, heap)

From e778e018aa57f73bfee546b3bcf58f265e48f2ae Mon Sep 17 00:00:00 2001
From: David Schmenk <dschmenk@gmail.com>
Date: Wed, 10 Jan 2018 11:48:11 -0800
Subject: [PATCH 04/16] Export SYSPATH

---
 src/inc/cmdsys.plh   |  4 ++++
 src/libsrc/sane.pla  | 15 +++++++++++++--
 src/vmsrc/a1cmd.pla  |  3 +++
 src/vmsrc/cmd.pla    | 34 ++++++++++++++--------------------
 src/vmsrc/soscmd.pla |  2 ++
 5 files changed, 36 insertions(+), 22 deletions(-)

diff --git a/src/inc/cmdsys.plh b/src/inc/cmdsys.plh
index c490a8f..d7dfa02 100644
--- a/src/inc/cmdsys.plh
+++ b/src/inc/cmdsys.plh
@@ -23,6 +23,10 @@ import cmdsys
     const MACHID_I     = $08
     byte MACHID
     //
+    // System path
+    //
+    byte syspath
+    //
     // System flags: memory allocator screen holes.
     //
     const restxt1     = $0001
diff --git a/src/libsrc/sane.pla b/src/libsrc/sane.pla
index 51f3bee..c57c3f8 100644
--- a/src/libsrc/sane.pla
+++ b/src/libsrc/sane.pla
@@ -720,16 +720,27 @@ 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
 //
 def loadcode(codefile)
     byte ref
     word pcode, seglen
-
+    byte filepath[64]
+    
     //puts(codefile); puts(":\n")
     pcode = 0
-    ref   = fileio:open(codefile)
+    ref   = fileio:open(strcat(strcpy(@filepath, @syspath), codefile))
     //puts("ref = "); prbyte(ref); puts(" perr = "); prbyte(perr); putln
     if ref
         pcode = heapmark
diff --git a/src/vmsrc/a1cmd.pla b/src/vmsrc/a1cmd.pla
index adad124..f685ba7 100755
--- a/src/vmsrc/a1cmd.pla
+++ b/src/vmsrc/a1cmd.pla
@@ -68,6 +68,7 @@ word cmdptr       = @hexchar // make it point to a zero
 //
 byte syslibstr[]  = "CMDSYS"
 byte machidstr[]  = "MACHID"
+byte syspathstr[] = "SYSPATH"
 byte putcstr[]    = "PUTC"
 byte putlnstr[]   = "PUTLN"
 byte putsstr[]    = "PUTS"
@@ -94,6 +95,7 @@ byte loadstr[]    = "MODLOAD"
 byte execstr[]    = "MODEXEC"
 byte modadrstr[]  = "MODADDR"
 byte argstr[]     = "ARGS"
+byte syspath[]    = "" // Set to NULL
 word exports[]    = @sysstr,    @syscall
 word              = @callstr,   @call
 word              = @putcstr,   @cout
@@ -120,6 +122,7 @@ word              = @loadstr,   @loadmod
 word              = @execstr,   @execmod
 word              = @modadrstr, @lookupstrmod
 word              = @machidstr, @machid
+word              = @syspathstr,@syspath
 word              = @argstr,    @cmdptr
 word              = 0
 word syslibsym    = @exports
diff --git a/src/vmsrc/cmd.pla b/src/vmsrc/cmd.pla
index eb003d4..69a9946 100755
--- a/src/vmsrc/cmd.pla
+++ b/src/vmsrc/cmd.pla
@@ -45,6 +45,7 @@ byte cmdln       = "" // Overlay exported strings table
 //
 byte syslibstr  = "CMDSYS"
 byte machidstr  = "MACHID"
+byte syspathstr = "SYSPATH"
 byte sysstr     = "SYSCALL"
 byte callstr    = "CALL"
 byte putcstr    = "PUTC"
@@ -100,6 +101,7 @@ word            = @loadstr,   @loadmod
 word            = @execstr,   @execmod
 word            = @modadrstr, @lookupstrmod
 word            = @machidstr, MACHID
+word            = @syspathstr,@syspath
 word            = @argstr,    @cmdln
 word            = 0
 word syslibsym  = @exports
@@ -347,10 +349,9 @@ asm memxcpy(dst,src,size)#0
         RTS
 end
 asm crout()#0
-        DEX
         LDA     #$0D
         BNE     +
-    ; FALL THROUGH TO COUT
+        ; FALL THROUGH TO COUT
 end
 //
 // CHAR OUT
@@ -358,6 +359,7 @@ end
 //
 asm cout(c)#0
         LDA     ESTKL,X
+        INX
         BIT     $BF98
         BMI     +
         JSR     TOUPR
@@ -365,7 +367,6 @@ asm cout(c)#0
         BIT     ROMEN
         JSR     $FDED
         BIT     LCRDEN+LCBNK2
-        INX
         RTS
 end
 //
@@ -411,11 +412,20 @@ asm prstr(s)#0
         RTS
 end
 //
+// PRINT WORD
+//
+asm prword(w)#0
+        LDA     ESTKH,X
+        JSR     +
+        DEX
+        ; FALL THROUGH TO PRBYTE
+end
+//
 // PRINT BYTE
 //
 asm prbyte(b)#0
         LDA     ESTKL,X
-        STX     ESP
++       STX     ESP
         BIT     ROMEN
         JSR     $FDDA
         LDX     ESP
@@ -424,22 +434,6 @@ asm prbyte(b)#0
         RTS
 end
 //
-// PRINT WORD
-//
-asm prword(w)#0
-        STX     ESP
-        TXA
-        TAY
-        LDA     ESTKH,Y
-        LDX     ESTKL,Y
-        BIT     ROMEN
-        JSR     $F941
-        LDX     ESP
-        BIT     LCRDEN+LCBNK2
-        INX
-        RTS
-end
-//
 // READ STRING
 // STR = RDSTR(PROMPTCHAR)
 //
diff --git a/src/vmsrc/soscmd.pla b/src/vmsrc/soscmd.pla
index 49823ce..5e8a771 100755
--- a/src/vmsrc/soscmd.pla
+++ b/src/vmsrc/soscmd.pla
@@ -63,6 +63,7 @@ word cmdptr
 //
 byte syslibstr[]  = "CMDSYS"
 byte machidstr[]  = "MACHID"
+byte syspathstr[] = "SYSPATH"
 byte sysstr[]     = "SYSCALL"
 byte callstr[]    = "CALL"
 byte putcstr[]    = "PUTC"
@@ -117,6 +118,7 @@ word              = @loadstr,   @loadmod
 word              = @execstr,   @execmod
 word              = @modadrstr, @lookupstrmod
 word              = @machidstr, @machid
+word              = @syspathstr,@syspath
 word              = @argstr,    @cmdptr
 word              = 0
 word syslibsym    = @exports

From d7618a37083376a276ada778a36cc0791e17aa74 Mon Sep 17 00:00:00 2001
From: David Schmenk <dschmenk@gmail.com>
Date: Wed, 10 Jan 2018 12:29:52 -0800
Subject: [PATCH 05/16] get SYSPATH from CMD path

---
 src/vmsrc/cmd.pla  | 2 +-
 src/vmsrc/plvm02.s | 7 +++++++
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/src/vmsrc/cmd.pla b/src/vmsrc/cmd.pla
index 69a9946..926ca57 100755
--- a/src/vmsrc/cmd.pla
+++ b/src/vmsrc/cmd.pla
@@ -1370,7 +1370,7 @@ loop
 //
 // Set system path
 //
-strcat(getpfx(@syspath), "SYS/"))
+strcat(strcpy(@syspath, $280), "SYS/")) // This is the path to CMD
 //
 // Try to load autorun.
 //
diff --git a/src/vmsrc/plvm02.s b/src/vmsrc/plvm02.s
index 1463f9a..ead6b7c 100755
--- a/src/vmsrc/plvm02.s
+++ b/src/vmsrc/plvm02.s
@@ -336,6 +336,13 @@ CMDENTRY =      *
         !WORD   CLOSEPARMS
         BNE     FAIL
 ;
+; CHANGE CMD STRING TO SYSPATH STRING
+;
+        LDA     STRBUF
+        SEC
+        SBC     #$03
+        STA     STRBUF
+;
 ; INIT VM ENVIRONMENT STACK POINTERS
 ;
 ;        LDA #$00               ; INIT FRAME POINTER

From 9b42eae31b7777ef6f8a1b63f64d28b05c04b8c7 Mon Sep 17 00:00:00 2001
From: David Schmenk <dschmenk@gmail.com>
Date: Wed, 10 Jan 2018 12:53:47 -0800
Subject: [PATCH 06/16] Set verion to Pre 1.0 for developer release

---
 src/inc/cmdsys.plh | 3 ++-
 src/vmsrc/cmd.pla  | 2 +-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/inc/cmdsys.plh b/src/inc/cmdsys.plh
index d7dfa02..b6b33cd 100644
--- a/src/inc/cmdsys.plh
+++ b/src/inc/cmdsys.plh
@@ -2,6 +2,7 @@ import cmdsys
     //
     // Useful values for everyone
     //
+    const _VERSION_ = $0100
     const FALSE = 0
     const TRUE  = not FALSE
     const NULL  = 0
@@ -49,6 +50,6 @@ import cmdsys
     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 divmod(a,b)#2, isugt(a,b)#1, isuge(a,b)#1, isult(a,b)#1, isule(a,b)#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 modload(mod)#1, modexec(modfile)#1, modaddr(str)#1
 end
diff --git a/src/vmsrc/cmd.pla b/src/vmsrc/cmd.pla
index 926ca57..560270c 100755
--- a/src/vmsrc/cmd.pla
+++ b/src/vmsrc/cmd.pla
@@ -1356,7 +1356,7 @@ heap = *freemem
 //
 // Print PLASMA version
 //
-prstr("PLASMA "); prbyte(version.1); cout('.'); prbyte(version.0); crout
+prstr("PLASMA Pre "); prbyte(version.1); cout('.'); prbyte(version.0); crout
 //
 // Init symbol table.
 //

From d1893b69daabe851ad778f9b4e9061b46a5ca8e0 Mon Sep 17 00:00:00 2001
From: David Schmenk <dschmenk@gmail.com>
Date: Wed, 10 Jan 2018 13:29:45 -0800
Subject: [PATCH 07/16] Set SYSPATH for CMD

---
 src/vmsrc/plvm802.s | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/src/vmsrc/plvm802.s b/src/vmsrc/plvm802.s
index 6b5fe93..1b44a2b 100644
--- a/src/vmsrc/plvm802.s
+++ b/src/vmsrc/plvm802.s
@@ -423,6 +423,13 @@ CMDENTRY =      *
         !WORD   CLOSEPARMS
         BNE     FAIL
 ;
+; CHANGE CMD STRING TO SYSPATH STRING
+;
+        LDA     STRBUF
+        SEC
+        SBC     #$03
+        STA     STRBUF
+;
 ; INIT VM ENVIRONMENT STACK POINTERS
 ;
 ;        LDA #$00               ; INIT FRAME POINTER

From f2d759352708e6adb1a6282cf5c93b29ec38d778 Mon Sep 17 00:00:00 2001
From: David Schmenk <dschmenk@gmail.com>
Date: Wed, 10 Jan 2018 19:10:15 -0800
Subject: [PATCH 08/16] Apple ][/][+ and PLASMA16 acting wierd

---
 src/libsrc/conio.pla      | 28 ++++++++++++++--------------
 src/samplesrc/rpncalc.pla | 14 ++++++++++----
 src/vmsrc/cmd.pla         |  1 -
 src/vmsrc/plvm01.s        |  4 ++--
 src/vmsrc/plvm02.s        | 27 ++++++++++++++-------------
 src/vmsrc/plvm03.s        |  4 ++--
 src/vmsrc/plvm802.s       | 33 +++++++++++++++++----------------
 7 files changed, 59 insertions(+), 52 deletions(-)

diff --git a/src/libsrc/conio.pla b/src/libsrc/conio.pla
index fd22e1c..ba9aca9 100644
--- a/src/libsrc/conio.pla
+++ b/src/libsrc/conio.pla
@@ -50,9 +50,9 @@ word                = $0850,$08D0,$0950,$09D0,$0A50,$0AD0,$0B50,$0BD0
 //
 // Text screen parameters.
 //
-byte textcols = 40
-byte curshpos = 0
-byte cursvpos = 0
+//byte textcols = 40
+//byte curshpos = 0
+//byte cursvpos = 0
 //
 // Apple 3 console codes.
 //
@@ -153,8 +153,8 @@ def a1home
     return 0
 end
 def a1gotoxy(x, y)
-    curshpos = x
-    cursvpos = y
+    //curshpos = x
+    //cursvpos = y
     putln
     while x
         putc(' ')
@@ -181,13 +181,13 @@ def a2keypressed
     return ^keyboard >= 128
 end
 def a2home
-    curshpos = 0
-    cursvpos = 0
+    //curshpos = 0
+    //cursvpos = 0
     return call($FC58, 0, 0, 0, 0) // home()
 end
 def a2gotoxy(x, y)
-    curshpos = x
-    cursvpos = y
+    //curshpos = x
+    //cursvpos = y
     ^$24 = x + ^$20
     return call($FB5B, y + ^$22, 0, 0, 0)
 end
@@ -248,14 +248,14 @@ def a3keypressed
     return count
 end
 def a3home
-    curshpos = 0
-    cursvpos = 0
+    //curshpos = 0
+    //cursvpos = 0
     putc(28)
     return 0
 end
 def a3gotoxy(x, y)
-    curshpos = x
-    cursvpos = y
+    //curshpos = x
+    //cursvpos = y
     putc(24)
     putc(x)
     putc(25)
@@ -269,7 +269,7 @@ def a3viewport(left, top, width, height)
         //
         left   = 0
         top    = 0
-        width  = textcols
+        width  = 40//textcols
         height = 24
     fin
     putc(1) // Reset viewport
diff --git a/src/samplesrc/rpncalc.pla b/src/samplesrc/rpncalc.pla
index 5fc6e8a..f04398d 100644
--- a/src/samplesrc/rpncalc.pla
+++ b/src/samplesrc/rpncalc.pla
@@ -26,6 +26,10 @@ predef digitKey(pkey)#0, pointKey(pkey)#0, opKey(pkey)#0
 predef enterKey(pkey)#0, copyKey(pkey)#0, chsKey(pkey)#0, memKey(pkey)#0
 predef elemsKey(pkey)#0
 //
+// Run state
+//
+byte quit = FALSE
+//
 // Current input
 //
 byte inputStr[32] = ""
@@ -395,11 +399,13 @@ def cmdKey(pkey)#0
 //    cmdLine = gets(':'|$80)
     word d
 
-    showStatus("Press 1-9 for fix point digits:")
-    d = getc - '0'
+    showStatus("Press 1-9 for fix point digits(Q=Quit):")
+    d = toupper(getc) - '0'
     if d >= 1 and d <= 9
         displayFix = d
         displayInt = displayWidth - displayFix - 1
+    elsif d == 'Q' - '0'
+        quit = TRUE
     fin
     clearStatus
     //
@@ -417,7 +423,7 @@ def inputKey#0
     byte inkey
     word pkeys
 
-    while 1
+    while not quit
         pkeys = @keypad
         conio:gotoxy(18, 7)
         inkey = toupper(getc)
@@ -442,7 +448,7 @@ initInput
 showStack
 showMem
 showInput
-showStatus("Version 0.5")
+showStatus("Version 0.6")
 inputKey
 conio:gotoxy(0, 22)
 done
diff --git a/src/vmsrc/cmd.pla b/src/vmsrc/cmd.pla
index 560270c..592c75e 100755
--- a/src/vmsrc/cmd.pla
+++ b/src/vmsrc/cmd.pla
@@ -351,7 +351,6 @@ end
 asm crout()#0
         LDA     #$0D
         BNE     +
-        ; FALL THROUGH TO COUT
 end
 //
 // CHAR OUT
diff --git a/src/vmsrc/plvm01.s b/src/vmsrc/plvm01.s
index b6655cf..f587cd0 100644
--- a/src/vmsrc/plvm01.s
+++ b/src/vmsrc/plvm01.s
@@ -863,15 +863,15 @@ BRGT    INX
     CMP ESTKL,X
     LDA ESTKH-1,X
     SBC ESTKH,X
-    BMI BRNCH
     BPL NOBRNCH
+    BMI BRNCH
 BRLT    INX
     LDA ESTKL,X
     CMP ESTKL-1,X
     LDA ESTKH,X
     SBC ESTKH-1,X
-    BMI BRNCH
     BPL NOBRNCH
+    BMI BRNCH
 IBRNCH  LDA IPL
     CLC
     ADC ESTKL,X
diff --git a/src/vmsrc/plvm02.s b/src/vmsrc/plvm02.s
index ead6b7c..a14fd81 100755
--- a/src/vmsrc/plvm02.s
+++ b/src/vmsrc/plvm02.s
@@ -281,8 +281,8 @@ BYE     LDY     DEFCMD
         STA     STRBUF,Y
         DEY
         BPL     -
-        INY                     ; CLEAR CMDLINE BUFF
-        STY     $01FF
+;        INY                     ; CLEAR CMDLINE BUFF
+;        STY     $01FF
 CMDENTRY =      *
 ;
 ; DEACTIVATE 80 COL CARDS
@@ -336,17 +336,11 @@ CMDENTRY =      *
         !WORD   CLOSEPARMS
         BNE     FAIL
 ;
-; CHANGE CMD STRING TO SYSPATH STRING
-;
-        LDA     STRBUF
-        SEC
-        SBC     #$03
-        STA     STRBUF
-;
 ; INIT VM ENVIRONMENT STACK POINTERS
 ;
-;        LDA #$00               ; INIT FRAME POINTER
-        STA     PPL
+;       LDA     #$00
+        STA     $01FF           ; CLEAR CMDLINE BUFF
+        STA     PPL             ; INIT FRAME POINTER
         STA     IFPL
         LDA     #$BF
         STA     PPH
@@ -354,6 +348,13 @@ CMDENTRY =      *
         LDX     #$FE            ; INIT STACK POINTER (YES, $FE. SEE GETS)
         TXS
         LDX     #ESTKSZ/2       ; INIT EVAL STACK INDEX
+;
+; CHANGE CMD STRING TO SYSPATH STRING
+;
+        LDA     STRBUF
+        SEC
+        SBC     #$03
+        STA     STRBUF
         JMP     $2000           ; JUMP TO LOADED SYSTEM COMMAND
 ;
 ; PRINT FAIL MESSAGE, WAIT FOR KEYPRESS, AND REBOOT
@@ -1374,15 +1375,15 @@ BRGT    INX
         CMP     ESTKL,X
         LDA     ESTKH-1,X
         SBC     ESTKH,X
-        BMI     BRNCH
         BPL     NOBRNCH
+        BMI     BRNCH
 BRLT    INX
         LDA     ESTKL,X
         CMP     ESTKL-1,X
         LDA     ESTKH,X
         SBC     ESTKH-1,X
-        BMI     BRNCH
         BPL     NOBRNCH
+        BMI     BRNCH
 IBRNCH  LDA     IPL
         CLC
         ADC     ESTKL,X
diff --git a/src/vmsrc/plvm03.s b/src/vmsrc/plvm03.s
index 20d5927..68f4050 100755
--- a/src/vmsrc/plvm03.s
+++ b/src/vmsrc/plvm03.s
@@ -1020,15 +1020,15 @@ BRGT    INX
         CMP     ESTKL,X
         LDA     ESTKH-1,X
         SBC     ESTKH,X
-        BMI     BRNCH
         BPL     NOBRNCH
+        BMI     BRNCH
 BRLT    INX
         LDA     ESTKL,X
         CMP     ESTKL-1,X
         LDA     ESTKH,X
         SBC     ESTKH-1,X
-        BMI     BRNCH
         BPL     NOBRNCH
+        BMI     BRNCH
 IBRNCH  LDA     IPL
         CLC
         ADC     ESTKL,X
diff --git a/src/vmsrc/plvm802.s b/src/vmsrc/plvm802.s
index 1b44a2b..786565a 100644
--- a/src/vmsrc/plvm802.s
+++ b/src/vmsrc/plvm802.s
@@ -130,10 +130,10 @@ BADCPU  !TEXT   "65C802/65C816 CPU REQUIRED.", 13
 ;*
 ;* INITIALIZE STACK
 ;*
-INITSP  LDX     #$FE
-        TXS
-        LDX     #$00
-        STX     $01FF
+;INITSP  LDX     #$FE
+;        TXS
+;        LDX     #$00
+;        STX     $01FF
 ;*
 ;* DISCONNECT /RAM
 ;*
@@ -361,8 +361,8 @@ BYE     LDY     DEFCMD
         STA     STRBUF,Y
         DEY
         BPL     -
-        INY                     ; CLEAR CMDLINE BUFF
-        STY     $01FF
+;        INY                     ; CLEAR CMDLINE BUFF
+;        STY     $01FF
 CMDENTRY =      *
 ;
 ; DEACTIVATE 80 COL CARDS
@@ -423,17 +423,11 @@ CMDENTRY =      *
         !WORD   CLOSEPARMS
         BNE     FAIL
 ;
-; CHANGE CMD STRING TO SYSPATH STRING
-;
-        LDA     STRBUF
-        SEC
-        SBC     #$03
-        STA     STRBUF
-;
 ; INIT VM ENVIRONMENT STACK POINTERS
 ;
-;        LDA #$00               ; INIT FRAME POINTER
-        STA     PPL
+;        LDA     #$00
+        STA     $01FF           ; CLEAR CMDLINE BUFF
+        STA     PPL             ; INIT FRAME POINTER
         STA     IFPL
         LDA     #$BF
         STA     PPH
@@ -441,6 +435,13 @@ CMDENTRY =      *
         LDX     #$FE            ; INIT STACK POINTER (YES, $FE. SEE GETS)
         TXS
         LDX     #ESTKSZ/2       ; INIT EVAL STACK INDEX
+;
+; CHANGE CMD STRING TO SYSPATH STRING
+;
+        LDA     STRBUF
+        SEC
+        SBC     #$03
+        STA     STRBUF
         JMP     $2000           ; JUMP TO LOADED SYSTEM COMMAND
 ;
 ; PRINT FAIL MESSAGE, WAIT FOR KEYPRESS, AND REBOOT
@@ -1245,8 +1246,8 @@ BRGT    PLA
         SEC
         SBC     TOS,S
         BVS     +
-        BMI     BRNCH
         BPL     NOBRNCH
+        BMI     BRNCH
 +       BMI     NOBRNCH
         BPL     BRNCH
 BRLT    PLA

From 55c23805b4cc51424f2263283ec876d6c9d9f42a Mon Sep 17 00:00:00 2001
From: Dave Schmenk <dschmenk@gmail.com>
Date: Wed, 10 Jan 2018 21:02:43 -0800
Subject: [PATCH 09/16] Fix TOUPPER in COUT for Apple][

---
 src/vmsrc/cmd.pla | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/vmsrc/cmd.pla b/src/vmsrc/cmd.pla
index 592c75e..44b92e6 100755
--- a/src/vmsrc/cmd.pla
+++ b/src/vmsrc/cmd.pla
@@ -349,8 +349,8 @@ asm memxcpy(dst,src,size)#0
         RTS
 end
 asm crout()#0
-        LDA     #$0D
-        BNE     +
+        LDA     #$8D
+        BNE     ++
 end
 //
 // CHAR OUT
@@ -358,12 +358,12 @@ end
 //
 asm cout(c)#0
         LDA     ESTKL,X
-        INX
         BIT     $BF98
         BMI     +
         JSR     TOUPR
 +       ORA     #$80
-        BIT     ROMEN
+        INX
+++      BIT     ROMEN
         JSR     $FDED
         BIT     LCRDEN+LCBNK2
         RTS

From 80a7805be13144561bc4e4c928f14f64f7916f66 Mon Sep 17 00:00:00 2001
From: Dave Schmenk <dschmenk@gmail.com>
Date: Wed, 10 Jan 2018 22:02:55 -0800
Subject: [PATCH 10/16] Clean up

---
 src/vmsrc/plvm802.s | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/vmsrc/plvm802.s b/src/vmsrc/plvm802.s
index 786565a..d88823b 100644
--- a/src/vmsrc/plvm802.s
+++ b/src/vmsrc/plvm802.s
@@ -1575,7 +1575,7 @@ LEAVE   +ACCMEM8                ; 8 BIT A/M
         INX
 +       CPX     ESP
         BNE     -
- !IF    DEBUG {
+!IF     DEBUG {
         STX     TMPL
         TSX
         CPX     HWSP

From f48d6c53362b10b81d6bfa84603077b868e76133 Mon Sep 17 00:00:00 2001
From: Dave Schmenk <dschmenk@gmail.com>
Date: Thu, 11 Jan 2018 10:12:25 -0800
Subject: [PATCH 11/16] Make sure all module functin tables are at the
 beginning of the module

---
 src/inc/testlib.plh   |  2 +-
 src/libsrc/conio.pla  | 35 +++++++++++++++++++----------------
 src/libsrc/fileio.pla |  2 +-
 3 files changed, 21 insertions(+), 18 deletions(-)

diff --git a/src/inc/testlib.plh b/src/inc/testlib.plh
index 087b6f2..719f940 100644
--- a/src/inc/testlib.plh
+++ b/src/inc/testlib.plh
@@ -4,5 +4,5 @@ import testlib
   const hex = 2
   const newln = 4
   const str = 6
-  const char = 8
+  const chr = 8
 end
diff --git a/src/libsrc/conio.pla b/src/libsrc/conio.pla
index ba9aca9..dfcdcfb 100644
--- a/src/libsrc/conio.pla
+++ b/src/libsrc/conio.pla
@@ -22,6 +22,9 @@ const hgr1         = $2000
 const hgr2         = $4000
 const page1        = 0
 const page2        = 1
+//
+// External interface
+//
 struc t_conio
     word keypressed
     word home
@@ -39,6 +42,22 @@ end
 predef a2keypressed,a2home,a2gotoxy(x,y),a2viewport(left, top, width, height),a2texttype(type)
 predef a2textmode(cols),a2grmode(mix),a2grcolor(color),a2grplot(x,y)
 //
+// Exported function table.
+//
+export word conio[]
+//
+// Function pointers.
+//
+word = @a2keypressed
+word = @a2home
+word = @a2gotoxy
+word = @a2viewport
+word = @a2texttype
+word = @a2textmode
+word = @a2grmode
+word = @a2grcolor
+word = @a2grplot
+//
 // Screen row address arrays.
 //
 word txt1scrn[]     = $0400,$0480,$0500,$0580,$0600,$0680,$0700,$0780
@@ -61,22 +80,6 @@ byte textclrmode[]  = 2, 16, 1
 byte grcharset[]    = 1, 0, $7F, $7F, $7F, $7F, $00, $00, $00, $00
 byte devcons
 //
-// Exported function table.
-//
-export word conio[]
-//
-// Function pointers.
-//
-word = @a2keypressed
-word = @a2home
-word = @a2gotoxy
-word = @a2viewport
-word = @a2texttype
-word = @a2textmode
-word = @a2grmode
-word = @a2grcolor
-word = @a2grplot
-//
 // Native  routines.
 //
 asm equates
diff --git a/src/libsrc/fileio.pla b/src/libsrc/fileio.pla
index cb0fd72..2b48bfd 100644
--- a/src/libsrc/fileio.pla
+++ b/src/libsrc/fileio.pla
@@ -20,7 +20,7 @@ const O_READ_WRITE = 3
 //
 const sysbuf = $0800
 //
-// All our file I/O routines
+// External interface
 //
 struc t_fileio
     word getpfx

From 87f9be31d8d3c350f3d57507c8d4f8bff1e06b19 Mon Sep 17 00:00:00 2001
From: David Schmenk <dschmenk@gmail.com>
Date: Sat, 13 Jan 2018 11:53:21 -0800
Subject: [PATCH 12/16] Sometimes a small change has large repercussions

---
 src/inc/cmdsys.plh             |  34 +++++---
 src/inc/conio.plh              |  29 +++----
 src/inc/fileio.plh             |   1 -
 src/inc/fpu.plh                |   1 -
 src/inc/inet.plh               |   3 +-
 src/inc/longjmp.plh            |   4 +-
 src/inc/sane.plh               |   1 -
 src/inc/sdfat.plh              |   3 +-
 src/libsrc/args.pla            |  14 ++-
 src/libsrc/conio.pla           |  16 ++--
 src/libsrc/dgr.pla             |  20 ++---
 src/libsrc/fileio.pla          |   7 +-
 src/libsrc/fpu.pla             |   3 +-
 src/libsrc/longjmp.pla         |   4 +-
 src/libsrc/sane.pla            |  15 +---
 src/samplesrc/httpd.pla        |  24 +++---
 src/samplesrc/memtest.pla      |   7 --
 src/samplesrc/rogue.io.pla     |  18 ++--
 src/samplesrc/sanity.pla       |   2 +-
 src/samplesrc/testlib.pla      |   6 +-
 src/toolsrc/codegen.c          |  11 ++-
 src/toolsrc/codegen.pla        |  34 ++------
 src/toolsrc/ed.pla             |  20 ++---
 src/toolsrc/lex.c              |   1 +
 src/toolsrc/lex.pla            |   4 +-
 src/toolsrc/parse.c            | 118 ++++++++++++++++----------
 src/toolsrc/parse.pla          | 119 +++++++++++++++-----------
 src/toolsrc/plasm.pla          |  52 ++++++------
 src/vmsrc/a1cmd.pla            | 148 +++++++++++---------------------
 src/vmsrc/cmd.pla              | 150 +++++++++++++--------------------
 src/vmsrc/plvm.c               | 129 ++++++++++++++--------------
 src/vmsrc/soscmd.pla           | 131 ++++++++++++++--------------
 sysfiles/filetypes.plasma.conf |   2 +-
 33 files changed, 520 insertions(+), 611 deletions(-)

diff --git a/src/inc/cmdsys.plh b/src/inc/cmdsys.plh
index b6b33cd..a5bb328 100644
--- a/src/inc/cmdsys.plh
+++ b/src/inc/cmdsys.plh
@@ -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
diff --git a/src/inc/conio.plh b/src/inc/conio.plh
index 72eabc7..58c5590 100644
--- a/src/inc/conio.plh
+++ b/src/inc/conio.plh
@@ -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
diff --git a/src/inc/fileio.plh b/src/inc/fileio.plh
index e65c1f2..d759ecc 100644
--- a/src/inc/fileio.plh
+++ b/src/inc/fileio.plh
@@ -49,7 +49,6 @@ import fileio
         word readblock
         word writeblock
     end
-    word fileio
     //
     // Globally accessible error code
     //
diff --git a/src/inc/fpu.plh b/src/inc/fpu.plh
index 76a5572..90de2d0 100644
--- a/src/inc/fpu.plh
+++ b/src/inc/fpu.plh
@@ -112,5 +112,4 @@ struc t_fpu
     word randNum
 end
 const dropX = shiftDown // Alias dropX and shiftDown
-word fpu
 end
diff --git a/src/inc/inet.plh b/src/inc/inet.plh
index 2e68f3e..f631bc6 100644
--- a/src/inc/inet.plh
+++ b/src/inc/inet.plh
@@ -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
diff --git a/src/inc/longjmp.plh b/src/inc/longjmp.plh
index 330ff91..466bbae 100644
--- a/src/inc/longjmp.plh
+++ b/src/inc/longjmp.plh
@@ -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
diff --git a/src/inc/sane.plh b/src/inc/sane.plh
index 5637360..61f2334 100644
--- a/src/inc/sane.plh
+++ b/src/inc/sane.plh
@@ -142,5 +142,4 @@ struc t_sane
     word saveZP
     word restoreZP
 end
-word sane
 end
diff --git a/src/inc/sdfat.plh b/src/inc/sdfat.plh
index 0959ecc..b107e1f 100644
--- a/src/inc/sdfat.plh
+++ b/src/inc/sdfat.plh
@@ -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
diff --git a/src/libsrc/args.pla b/src/libsrc/args.pla
index f0a8e00..7945de0 100644
--- a/src/libsrc/args.pla
+++ b/src/libsrc/args.pla
@@ -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
\ No newline at end of file
+done
diff --git a/src/libsrc/conio.pla b/src/libsrc/conio.pla
index dfcdcfb..fa4769e 100644
--- a/src/libsrc/conio.pla
+++ b/src/libsrc/conio.pla
@@ -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
diff --git a/src/libsrc/dgr.pla b/src/libsrc/dgr.pla
index 079f009..f50924a 100755
--- a/src/libsrc/dgr.pla
+++ b/src/libsrc/dgr.pla
@@ -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
diff --git a/src/libsrc/fileio.pla b/src/libsrc/fileio.pla
index 2b48bfd..0c35c7f 100644
--- a/src/libsrc/fileio.pla
+++ b/src/libsrc/fileio.pla
@@ -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
 //
diff --git a/src/libsrc/fpu.pla b/src/libsrc/fpu.pla
index 7b78699..46410b2 100644
--- a/src/libsrc/fpu.pla
+++ b/src/libsrc/fpu.pla
@@ -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
diff --git a/src/libsrc/longjmp.pla b/src/libsrc/longjmp.pla
index 1f797c8..9a4df23 100644
--- a/src/libsrc/longjmp.pla
+++ b/src/libsrc/longjmp.pla
@@ -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
diff --git a/src/libsrc/sane.pla b/src/libsrc/sane.pla
index c57c3f8..c168a17 100644
--- a/src/libsrc/sane.pla
+++ b/src/libsrc/sane.pla
@@ -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
diff --git a/src/samplesrc/httpd.pla b/src/samplesrc/httpd.pla
index b76d63d..4e8c2ca 100644
--- a/src/samplesrc/httpd.pla
+++ b/src/samplesrc/httpd.pla
@@ -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
diff --git a/src/samplesrc/memtest.pla b/src/samplesrc/memtest.pla
index 87eafec..4f16ea1 100644
--- a/src/samplesrc/memtest.pla
+++ b/src/samplesrc/memtest.pla
@@ -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
diff --git a/src/samplesrc/rogue.io.pla b/src/samplesrc/rogue.io.pla
index 4a51aeb..8f8c882 100644
--- a/src/samplesrc/rogue.io.pla
+++ b/src/samplesrc/rogue.io.pla
@@ -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
diff --git a/src/samplesrc/sanity.pla b/src/samplesrc/sanity.pla
index 916acaa..8b3bff5 100644
--- a/src/samplesrc/sanity.pla
+++ b/src/samplesrc/sanity.pla
@@ -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
diff --git a/src/samplesrc/testlib.pla b/src/samplesrc/testlib.pla
index a40749c..55ce84d 100755
--- a/src/samplesrc/testlib.pla
+++ b/src/samplesrc/testlib.pla
@@ -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])
diff --git a/src/toolsrc/codegen.c b/src/toolsrc/codegen.c
index 96d7b49..f007f1d 100755
--- a/src/toolsrc/codegen.c
+++ b/src/toolsrc/codegen.c
@@ -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;
 }
 /*
diff --git a/src/toolsrc/codegen.pla b/src/toolsrc/codegen.pla
index 0b1a577..28b5312 100644
--- a/src/toolsrc/codegen.pla
+++ b/src/toolsrc/codegen.pla
@@ -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
diff --git a/src/toolsrc/ed.pla b/src/toolsrc/ed.pla
index 99fd323..c745d4c 100755
--- a/src/toolsrc/ed.pla
+++ b/src/toolsrc/ed.pla
@@ -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
diff --git a/src/toolsrc/lex.c b/src/toolsrc/lex.c
index ae018dd..cf7f09e 100755
--- a/src/toolsrc/lex.c
+++ b/src/toolsrc/lex.c
@@ -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',
diff --git a/src/toolsrc/lex.pla b/src/toolsrc/lex.pla
index 2a9cae9..233e5c4 100644
--- a/src/toolsrc/lex.pla
+++ b/src/toolsrc/lex.pla
@@ -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
diff --git a/src/toolsrc/parse.c b/src/toolsrc/parse.c
index 25680fb..588ce5d 100755
--- a/src/toolsrc/parse.c
+++ b/src/toolsrc/parse.c
@@ -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)
diff --git a/src/toolsrc/parse.pla b/src/toolsrc/parse.pla
index 67acf32..423ed19 100644
--- a/src/toolsrc/parse.pla
+++ b/src/toolsrc/parse.pla
@@ -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
diff --git a/src/toolsrc/plasm.pla b/src/toolsrc/plasm.pla
index 638811f..ce95bb4 100644
--- a/src/toolsrc/plasm.pla
+++ b/src/toolsrc/plasm.pla
@@ -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
             //
diff --git a/src/vmsrc/a1cmd.pla b/src/vmsrc/a1cmd.pla
index f685ba7..eed3cdf 100755
--- a/src/vmsrc/a1cmd.pla
+++ b/src/vmsrc/a1cmd.pla
@@ -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)
diff --git a/src/vmsrc/cmd.pla b/src/vmsrc/cmd.pla
index 44b92e6..b6e8677 100755
--- a/src/vmsrc/cmd.pla
+++ b/src/vmsrc/cmd.pla
@@ -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
diff --git a/src/vmsrc/plvm.c b/src/vmsrc/plvm.c
index 0184705..cca64ef 100755
--- a/src/vmsrc/plvm.c
+++ b/src/vmsrc/plvm.c
@@ -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--;
diff --git a/src/vmsrc/soscmd.pla b/src/vmsrc/soscmd.pla
index 5e8a771..f5b6c10 100755
--- a/src/vmsrc/soscmd.pla
+++ b/src/vmsrc/soscmd.pla
@@ -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
diff --git a/sysfiles/filetypes.plasma.conf b/sysfiles/filetypes.plasma.conf
index 02e222a..c7acaae 100755
--- a/sysfiles/filetypes.plasma.conf
+++ b/sysfiles/filetypes.plasma.conf
@@ -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

From 26005a06370e20a106c833fec85cc48264fecf0b Mon Sep 17 00:00:00 2001
From: David Schmenk <dschmenk@gmail.com>
Date: Sat, 13 Jan 2018 12:09:52 -0800
Subject: [PATCH 13/16] Save a byte

---
 src/vmsrc/cmd.pla | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/src/vmsrc/cmd.pla b/src/vmsrc/cmd.pla
index b6e8677..c9acb86 100755
--- a/src/vmsrc/cmd.pla
+++ b/src/vmsrc/cmd.pla
@@ -120,12 +120,11 @@ word lastsym     = symtbl
 //asm equates included from cmdstub.s
 //
 asm saveX#0
-        STX     XREG
+        STX     XREG+1
         RTS
-XREG    !BYTE   0
 end
 asm restoreX#0
-        LDX     XREG
+XREG    LDX     #$00
         RTS
 end
 // CALL PRODOS

From 4c49fb0c0ead21a4334b31f49a9b07d35289c746 Mon Sep 17 00:00:00 2001
From: David Schmenk <dschmenk@sbcglobal.net>
Date: Sat, 13 Jan 2018 15:51:48 -0800
Subject: [PATCH 14/16] Update README.md

---
 README.md | 26 ++++++++++++++++++++++----
 1 file changed, 22 insertions(+), 4 deletions(-)

diff --git a/README.md b/README.md
index 2a3bcb0..a8d6d9a 100755
--- a/README.md
+++ b/README.md
@@ -7,7 +7,7 @@ PLASMA: **P**roto **L**anguage **A**s**S**e**M**bler for **A**pple
 
 PLASMA is a medium level programming language targeting the 8-bit 6502 processor. Historically, there were simple languages developed in the early years of computers that improved on the tedium of assembly language programming while still being low level enough for system coding. Languages like B, FORTH, and PLASMA fall into this category.
 
-PLASMA is a combination of virtual machine and assembler/compiler matched closely to the 6502 architecture.  It is an attempt to satisfy a few challenges surrounding code size, efficient execution, small runtime and flexible code location.  By architecting a unique bytecode that maps nearly one-to-one to the higher-level representation, the compiler can be very simple and execute quickly on the Apple II for a self-hosted environment.  A modular approach provides for incremental development and code reuse. The syntax of the language is heavily influenced by assembly, Pascal, and C. The design philosophy was to be as simple as feasible while retaining flexibility and symantic clarity. You won't find any unnecessary or redundant syntax in PLASMA.
+PLASMA is a combination of operating environment, virtual machine, and assembler/compiler matched closely to the 6502 architecture.  It is an attempt to satisfy a few challenges surrounding code size, efficient execution, small runtime and flexible code location.  By architecting a unique bytecode that maps nearly one-to-one to the higher-level representation, the compiler can be very simple and execute quickly on the Apple II for a self-hosted environment.  A modular approach provides for incremental development and code reuse. The syntax of the language is heavily influenced by assembly, Pascal, and C. The design philosophy was to be as simple as feasible while retaining flexibility and symantic clarity. You won't find any unnecessary or redundant syntax in PLASMA.
 
 Different projects have led to the architecture of PLASMA, most notably Apple Pascal, FORTH, and my own Java VM for the 6502: VM02. Each has tried to map a generic VM to the 6502 with varying levels of success.  Apple Pascal, based on the USCD Pascal using the p-code interpreter, was a very powerful system and ran fast enough on the Apple II to be interactive but didn't win any speed contests. FORTH was the poster child for efficiency and obtuse syntax. Commonly referred to as a write only language, it was difficult to come up to speed as a developer, especially when using others' code. My own project in creating a Java VM for the Apple II uncovered the folly of shoehorning a large, 32-bit virtual memory environment into 8-bit, 64K hardware.
 
@@ -101,6 +101,8 @@ Different projects have led to the architecture of PLASMA, most notably Apple Pa
 
 # Build Environment
 
+## PLASMA Cross-Compiler
+
 The first step in writing PLASMA code is to get a build environment working. If you have Unix-like environment, then this is a fairly easy exercise. Windows users may want to install the [Cygwin](https://www.cygwin.com/) environment to replicate a Unix-like environment under Windows. When installing Cygwin, make sure **gcc-core**, **make**, and **git** are installed under the **Devel** packages. Mac OS X users may have to install the **Xcode** from the App Store.
 
 Launch the command-line/terminal application for your environment to download and build PLASMA. Create a source code directory and change the working directory to it, something like:
@@ -110,7 +112,7 @@ mkdir Src
 cd Src
 ```
 
-## acme Cross-Assembler
+### acme Cross-Assembler
 
 There are two source projects you need to download: the first is a nice cross-platform 6502 assembler called [acme](http://sourceforge.net/p/acme-crossass/code-0/6/tree/trunk/docs/QuickRef.txt). Download, build, and install the acme assembler by typing:
 
@@ -124,7 +126,7 @@ cd ../..
 
 Under Unix that `cp` command may have to be preceded by `sudo` to elevate the privileges to copy into `/usr/local/bin`.
 
-## PLASMA Source
+### PLASMA Source
 
 Now, to download PLASMA and build it, type:
 
@@ -134,7 +136,7 @@ cd PLASMA/src
 make
 ```
 
-### Portable VM
+#### Portable VM
 
 To see if everything built correctly, type:
 
@@ -166,6 +168,22 @@ to run the module. You will be rewarded with `Hello, world.` printed to the scre
 
 and you should see the same screenful of gibberish you saw from the portable VM, but on the Apple II this time. Both VMs are running the exact same module binaries. To view the source of these modules refer to `PLASMA/src/samplesrc/hello.pla`, `PLASMA/src/samplesrc/test.pla`, and `PLASMA/src/samplesrc/testlib.pla`. To get even more insight into the compiled source, view the corresponding `.a` files.
 
+## Target Compiler
+
+The PLASMA compiler is also self-hosted on the Apple II and III. The PLASMA system and development disks can be run on a real or emulated machine. It is recommended to copy the file to a hard disk, or similar mass storage device. Boot the PLASMA system and change prefix to the development disk/directory. The 'HELLO.PLA' source file should be there. To compile the module, type:
+
+```
++PLASMA HELLO.PLA
+```
+
+After the compiler loads (which can take some time on an un-accelerated machine), you will see the compiler banner message. The complilation process prints out a `.` once in awhile. When compilation is complete, the module will be written to disk, and the prompt will return. To execute the module, type:
+
+```
++HELLO
+```
+
+and just like with the cross-compiled module, you will get the `Hello, word.` message printed to the screen.
+
 # Tutorial
 
 During KansasFest 2015, I gave a PLASMA introduction using the Apple II PLASMA sandbox IDE. You can play along using your favorite Apple II emulator, or one that runs directly in your browser: [Apple II Emulator in Javascript](https://www.scullinsteel.com/apple/e). Download [SANDBOX.PO](https://github.com/dschmenk/PLASMA/blob/master/SANDBOX.PO?raw=true) and load it into Drive 1 of the emulator. Start the [KansasFest PLASMA Code-along video](https://www.youtube.com/watch?v=RrR79WVHwJo?t=11m24s) and follow along.

From 89fde24b862eca984225b02a6ba7c75a776e670a Mon Sep 17 00:00:00 2001
From: David Schmenk <dschmenk@sbcglobal.net>
Date: Sat, 13 Jan 2018 16:39:45 -0800
Subject: [PATCH 15/16] Update README.md

---
 README.md | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/README.md b/README.md
index a8d6d9a..3d5a9b9 100755
--- a/README.md
+++ b/README.md
@@ -168,12 +168,12 @@ to run the module. You will be rewarded with `Hello, world.` printed to the scre
 
 and you should see the same screenful of gibberish you saw from the portable VM, but on the Apple II this time. Both VMs are running the exact same module binaries. To view the source of these modules refer to `PLASMA/src/samplesrc/hello.pla`, `PLASMA/src/samplesrc/test.pla`, and `PLASMA/src/samplesrc/testlib.pla`. To get even more insight into the compiled source, view the corresponding `.a` files.
 
-## Target Compiler
+## Target Hosted Compiler
 
-The PLASMA compiler is also self-hosted on the Apple II and III. The PLASMA system and development disks can be run on a real or emulated machine. It is recommended to copy the file to a hard disk, or similar mass storage device. Boot the PLASMA system and change prefix to the development disk/directory. The 'HELLO.PLA' source file should be there. To compile the module, type:
+The PLASMA compiler is also self-hosted on the Apple II and III. The PLASMA system and development disks can be run on a real or emulated machine. It is recommended to copy the file to a hard disk, or similar mass storage device. Boot the PLASMA system and change the prefix to the development disk/directory. The 'HELLO.PLA' source file should be there. To compile the module, type:
 
 ```
-+PLASMA HELLO.PLA
++PLASM HELLO.PLA
 ```
 
 After the compiler loads (which can take some time on an un-accelerated machine), you will see the compiler banner message. The complilation process prints out a `.` once in awhile. When compilation is complete, the module will be written to disk, and the prompt will return. To execute the module, type:

From 5a0865b02ce7610d8610b69071d17dbbec838c66 Mon Sep 17 00:00:00 2001
From: David Schmenk <dschmenk@sbcglobal.net>
Date: Sat, 13 Jan 2018 17:00:54 -0800
Subject: [PATCH 16/16] Quickly add new PLASMA aliases and data initialization.

---
 README.md | 63 ++++++++++++++++++++++++++++++++++++-------------------
 1 file changed, 41 insertions(+), 22 deletions(-)

diff --git a/README.md b/README.md
index 3d5a9b9..06da45d 100755
--- a/README.md
+++ b/README.md
@@ -168,9 +168,9 @@ to run the module. You will be rewarded with `Hello, world.` printed to the scre
 
 and you should see the same screenful of gibberish you saw from the portable VM, but on the Apple II this time. Both VMs are running the exact same module binaries. To view the source of these modules refer to `PLASMA/src/samplesrc/hello.pla`, `PLASMA/src/samplesrc/test.pla`, and `PLASMA/src/samplesrc/testlib.pla`. To get even more insight into the compiled source, view the corresponding `.a` files.
 
-## Target Hosted Compiler
+## PLASMA Target Hosted Compiler
 
-The PLASMA compiler is also self-hosted on the Apple II and III. The PLASMA system and development disks can be run on a real or emulated machine. It is recommended to copy the file to a hard disk, or similar mass storage device. Boot the PLASMA system and change the prefix to the development disk/directory. The 'HELLO.PLA' source file should be there. To compile the module, type:
+The PLASMA compiler is also self-hosted on the Apple II and III. The PLASMA system and development disks can be run on a real or emulated machine. It is recommended to copy the files to a hard disk, or similar mass storage device. Boot the PLASMA system and change the prefix to the development disk/directory. The 'HELLO.PLA' source file should be there. To compile the module, type:
 
 ```
 +PLASM HELLO.PLA
@@ -196,11 +196,11 @@ Although the low-level PLASMA VM operations could easily by coded by hand, they
 
 ## PLASMA Modules
 
-PLASMA programs are built up around modules: small, self contained, dynamically loaded and linked software components that provide a well defined interface to other modules. The module format extends the .REL file type originally defined by the EDASM assembler from the DOS/ProDOS Toolkit from Apple Computer, Inc. PLASMA extends the file format through a backwards compatible extension that the PLASMA loader recognizes to locate the PLASMA bytecode and provide for advanced dynamic loading of module dependencies.
+PLASMA programs are built up around modules: small, self contained, dynamically loaded and linked software components that provide a well defined interface to other modules. The module format extends the .REL file type originally defined by the EDASM assembler from the DOS/ProDOS Toolkit from Apple Computer, Inc. PLASMA extends the file format through a backwards compatible extension that the PLASMA loader recognizes to locate the PLASMA bytecode and provide for advanced dynamic loading of module dependencies. Modules are first-class citizens in PLASMA: an imported module is assigned to a variable which can be accessed like any other.
 
 ## Data Types
 
-PLASMA only defines two data types: `byte` and `word`. All operations take place on word-sized quantities, with the exception of loads and stores to byte sized addresses. The interpretation of a value can be an integer, an address, or anything that fits in 16 bits. There are a number of address operators to identify how an address value is to be interpreted.
+PLASMA only defines two data types: `char`(or `byte`) and `var`(or `word`). All operations take place on word-sized quantities, with the exception of loads and stores to byte sized addresses. The interpretation of a value can be an integer, an address, or anything that fits in 16 bits. There are a number of address operators to identify how an address value is to be interpreted.
 
 ## Obligatory 'Hello World'
 
@@ -276,8 +276,8 @@ end
 
 import testlib
     predef puti
-    byte testdata, teststring
-    word testarray
+    char testdata, teststring
+    var testarray
 end
 ```
 
@@ -319,9 +319,9 @@ There is a shortcut for defining constant offsets into structures:
 
 ```
 struc t_entry
-  word id
-  byte[32] name
-  word next_entry
+  var id
+  char[32] name
+  var next_entry
 end
 ```
 
@@ -375,7 +375,7 @@ Strings are defined like Pascal strings, a length byte followed by the string ch
 //
 // An initialized string of 64 characters
 //
-byte[64] txtfile = "UNTITLED"
+char[64] txtfile = "UNTITLED"
 ```
 
 ### Function Definitions
@@ -464,7 +464,7 @@ Values can be treated as pointers by preceding them with a `^` for byte pointers
 
 ```
 char[] hellostr = "Hello"
-word srcstr, strlen
+var srcstr, strlen
 
 srcstr = @hellostr // srcstr points to address of hellostr
 strlen = ^srcstr // the first byte srcstr points to is the string length
@@ -474,8 +474,8 @@ Functions with parameters or expressions to be used as a function address to cal
 
 ```
 predef keyin2plus
-word keyin
-byte key
+var keyin
+char key
 
 keyin = @keyin2plus // address-of keyin2plus function
 key   = keyin()
@@ -607,14 +607,14 @@ Here is an example using the `import`s from the previous examples to export an i
 ```
 predef mydef(var)
 
-export word[10] myfuncs = @putc, @mydef, $0000
+export var[10] myfuncs = @putc, @mydef, $0000
 ```
 
 Exporting functions is simple:
 
 ```
 export def plot(x, y)
-    romcall(y, 0, x, 0, $F800)
+    call($F800, y, 0, x, 0)
 end
 ```
 
@@ -640,7 +640,7 @@ call(addr, aReg, xReg, yReg, statusReg) returns a pointer to a four-byte structu
 const xreg = 1
 const getlin = $FD6A
 
-numchars = call(getlin, 0, 0, 0, 0).xreg // return char count in X reg
+numchars = call(getlin, 0, 0, 0, 0)->xreg // return char count in X reg
 ```
 
 syscall(cmd, params) calls ProDOS, returning the status value.
@@ -662,14 +662,14 @@ putc(char), puts(string), home, gotoxy(x,y), getc() and gets() are other handy u
 
 ```
 putc('.')
-byte okstr[] = "OK"
+char okstr[] = "OK"
 puts(@okstr)
 ```
 
 memset(addr, val, len) will fill memory with a 16-bit value.  memcpy(dstaddr, srcaddr, len) will copy memory from one address to another, taking care to copy in the proper direction.
 
 ```
-byte nullstr[] = ""
+char nullstr[] = ""
 memset(strlinbuf, @nullstr, maxfill * 2) // fill line buff with pointer to null string
 memcpy(scrnptr, strptr + ofst + 1, numchars)
 ```
@@ -737,8 +737,8 @@ predef myfunc
 
 byte smallarray[4]
 byte initbarray[] = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
-byte string[64] = "Initialized string"
-word wlabel[]
+char string[64] = "Initialized string"
+var wlabel[]
 word = 1000, 2000, 3000, 4000 // Anonymous array
 word funclist = @myfunc, $0000
 ```
@@ -750,14 +750,33 @@ predef myfunc(var)#0
 
 byte[4] smallarray
 byte[] initbarray = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
-byte[64] string = "Initialized string"
-word[] wlabel
+char[64] string = "Initialized string"
+var[] wlabel
 word = 1000, 2000, 3000, 4000 // Anonymous array
 word funclist = @myfunc, $0000
 ```
 
 Arrays can be uninitialized and reserve a size, as in `smallarray` above.  Initialized arrays without a size specified in the definition will take up as much data as is present, as in `initbarray` above. Strings are special arrays that include a hidden length byte in the beginning (Pascal strings). When specified with a size, a minimum size is reserved for the string value. Labels can be defined as arrays without size or initializers; this can be useful when overlapping labels with other arrays or defining the actual array data as anonymous arrays in following lines as in `wlabel` and following lines. Addresses of other data (must be defined previously) or function definitions (pre-defined with predef), including imported references, can be initializers.
 
+The base array size can be used to initialize multiple variable of arbitrary size. Three, four byte values can be defined as such:
+
+```
+byte[4] a, b, c
+```
+
+All three variables will have 4 bytes reserved for them. If you combine a base size with an array size, you can define multiple large values. For instance,
+
+```
+byte[4] a[5]
+```
+
+will assign an array of five, four byte elements, for a total of 20 bytes. This may make more sense when we combine the alias for `byte`, `res` with structure definitions. An array of five structures would look like:
+
+```
+res[t_record] patient[20]
+```
+The result would be to reserve 20 patient records.
+
 #### Type Overrides
 
 Arrays are usually identified by the data type specifier, `byte` or `word` when the array is defined. However, this can be overridden with the type override specifiers: `:` and `.`. `:` overrides the type to be `word`, `.` overrides the type to be `byte`. An example of accessing a `word` array as `bytes`: