1
0
mirror of https://github.com/dschmenk/PLASMA.git synced 2025-02-22 00:29:01 +00:00

Change comment symbol to '//' and allow multiple statements per line

with ';'
This commit is contained in:
David Schmenk 2014-08-15 21:16:24 -07:00
parent b3e335eeb5
commit f8b694d1ca
13 changed files with 922 additions and 926 deletions

View File

@ -6,9 +6,9 @@ import stdlib
predef isugt, isuge, isult, isule predef isugt, isuge, isult, isule
predef modload, modexec, modaddr predef modload, modexec, modaddr
word MACHID, sysvars word MACHID, sysvars
; //
; System flags: memory allocator screen holes. // System flags: memory allocator screen holes.
; //
const restxt1 = $0001 const restxt1 = $0001
const restxt2 = $0002 const restxt2 = $0002
const reshgr1 = $0004 const reshgr1 = $0004

View File

@ -2,16 +2,16 @@ import STDLIB
predef syscall, call, memset, getc, putc, puts, modaddr predef syscall, call, memset, getc, putc, puts, modaddr
byte MACHID byte MACHID
end end
; //
; Handy constants. // Handy constants.
; //
const FALSE = 0 const FALSE = 0
const TRUE = !FALSE const TRUE = !FALSE
const FULLMODE = 0 const FULLMODE = 0
const MIXMODE = 1 const MIXMODE = 1
; //
; Apple II hardware constants. // Apple II hardware constants.
; //
const speaker = $C030 const speaker = $C030
const showgraphics = $C050 const showgraphics = $C050
const showtext = $C051 const showtext = $C051
@ -27,45 +27,45 @@ const hgr1 = $2000
const hgr2 = $4000 const hgr2 = $4000
const page1 = 0 const page1 = 0
const page2 = 1 const page2 = 1
; //
; Predefined functions. // Predefined functions.
; //
predef a2reset,a2keypressed,a2home,a2gotoxy,a2viewport,a2texttype predef a2reset,a2keypressed,a2home,a2gotoxy,a2viewport,a2texttype
predef a2textmode,a2writeint,a2writeln predef a2textmode,a2writeint,a2writeln
predef a2grmode,grcolor,grplot predef a2grmode,grcolor,grplot
; //
; String pool. // String pool.
; //
byte stdlib[] = "STDLIB" byte stdlib[] = "STDLIB"
; //
; Screen row address arrays. // Screen row address arrays.
; //
word txt1scrn[] = $0400,$0480,$0500,$0580,$0600,$0680,$0700,$0780 word txt1scrn[] = $0400,$0480,$0500,$0580,$0600,$0680,$0700,$0780
word = $0428,$04A8,$0528,$05A8,$0628,$06A8,$0728,$07A8 word = $0428,$04A8,$0528,$05A8,$0628,$06A8,$0728,$07A8
word = $0450,$04D0,$0550,$05D0,$0650,$06D0,$0750,$07D0 word = $0450,$04D0,$0550,$05D0,$0650,$06D0,$0750,$07D0
word txt2scrn[] = $0800,$0880,$0900,$0980,$0A00,$0A80,$0B00,$0B80 word txt2scrn[] = $0800,$0880,$0900,$0980,$0A00,$0A80,$0B00,$0B80
word = $0828,$08A8,$0928,$09A8,$0A28,$0AA8,$0B28,$0BA8 word = $0828,$08A8,$0928,$09A8,$0A28,$0AA8,$0B28,$0BA8
word = $0850,$08D0,$0950,$09D0,$0A50,$0AD0,$0B50,$0BD0 word = $0850,$08D0,$0950,$09D0,$0A50,$0AD0,$0B50,$0BD0
; //
; Text screen parameters. // Text screen parameters.
; //
byte textcols = 40 byte textcols = 40
byte curshpos = 0 byte curshpos = 0
byte cursvpos = 0 byte cursvpos = 0
; //
; Apple 3 console codes. // Apple 3 console codes.
; //
byte textbwmode[] = 2, 16, 0 byte textbwmode[] = 2, 16, 0
byte textclrmode[] = 2, 16, 1 byte textclrmode[] = 2, 16, 1
byte grcharset[] = 1, 0, $7F, $7F, $7F, $7F, $00, $00, $00, $00 byte grcharset[] = 1, 0, $7F, $7F, $7F, $7F, $00, $00, $00, $00
byte devcons byte devcons
; //
; Exported function table. // Exported function table.
; //
export word conio[] export word conio[]
; //
; Function pointers. // Function pointers.
; //
word = @a2reset word = @a2reset
word = @a2keypressed word = @a2keypressed
word = @a2home word = @a2home
@ -76,15 +76,15 @@ word = @a2textmode
word = @a2grmode word = @a2grmode
word = @grcolor word = @grcolor
word = @grplot word = @grplot
; //
; Native routines. // Native routines.
; //
asm equates asm equates
!SOURCE "vmsrc/plvmzp.inc" !SOURCE "vmsrc/plvmzp.inc"
end end
; //
; def grscrn(rowaddrs) // def grscrn(rowaddrs)
; //
asm grscrn asm grscrn
GRSCRN = $26 GRSCRN = $26
GRSCRNL = GRSCRN GRSCRNL = GRSCRN
@ -95,9 +95,9 @@ GRSCRNH = GRSCRNL+1
STA GRSCRNH STA GRSCRNH
RTS RTS
end end
; //
; def grcolor(color) // def grcolor(color)
; //
asm grcolor asm grcolor
GRCLR = $30 GRCLR = $30
LDA #$0F LDA #$0F
@ -111,9 +111,9 @@ GRCLR = $30
STA GRCLR STA GRCLR
RTS RTS
end end
; //
; def grplot(x, y) // def grplot(x, y)
; //
asm grplot asm grplot
STY IPY STY IPY
LDA ESTKL,X LDA ESTKL,X
@ -142,9 +142,9 @@ asm grplot
INX INX
RTS RTS
end end
; //
; Apple 1 routines. // Apple 1 routines.
; //
def a1keypressed def a1keypressed
return ^$D011 >= 128 return ^$D011 >= 128
end end
@ -164,18 +164,18 @@ end
def a1textmode(columns) def a1textmode(columns)
end end
def a1grmode(mix) def a1grmode(mix)
return 0 ; not supported return 0 // not supported
end end
; //
; Apple II routines. // Apple II routines.
; //
def a2keypressed def a2keypressed
return ^keyboard >= 128 return ^keyboard >= 128
end end
def a2home def a2home
curshpos = 0 curshpos = 0
cursypos = 0 cursypos = 0
return call($FC58, 0, 0, 0, 0) ;home() return call($FC58, 0, 0, 0, 0) // home()
end end
def a2gotoxy(x, y) def a2gotoxy(x, y)
curshpos = x curshpos = x
@ -202,21 +202,21 @@ def a2writeln(string, start, fill)
end end
def a2textmode(columns) def a2textmode(columns)
call($FB39, 0, 0, 0, 0) ;textmode() call($FB39, 0, 0, 0, 0) // textmode()
return a2home return a2home
end end
def a2grmode(mix) def a2grmode(mix)
call($FB2F, 0, 0, 0, 0) ;initmode() call($FB2F, 0, 0, 0, 0) // initmode()
call($FB40, 0, 0, 0, 0) ;grmode() call($FB40, 0, 0, 0, 0) // grmode()
if !mix if !mix
^showfull ^showfull
fin fin
a2home a2home
return grscrn(@txt1scrn) ; point to lo-res screen return grscrn(@txt1scrn) // point to lo-res screen
end end
; //
; Apple III routines. // Apple III routines.
; //
def dev_control(devnum, code, list) def dev_control(devnum, code, list)
byte params[5] byte params[5]
@ -255,15 +255,15 @@ def a3gotoxy(x, y)
end end
def a3viewport(left, top, width, height) def a3viewport(left, top, width, height)
if !width or !height if !width or !height
; //
; Reset the full-screen viewport // Reset the full-screen viewport
; //
left = 0 left = 0
top = 0 top = 0
width = textwidth width = textwidth
height = 24 height = 24
fin fin
putc(1) ; Reset viewport putc(1) // Reset viewport
putc(26) putc(26)
putc(left) putc(left)
putc(top) putc(top)
@ -297,16 +297,16 @@ def a3grmode(mix)
dev_control(devcons, 17, @grcharset) dev_control(devcons, 17, @grcharset)
a3viewport(0, 20, 40, 4) a3viewport(0, 20, 40, 4)
for i = 0 to mix for i = 0 to mix
memset(txt1scrn[i], 40, $0000) ; text screen memset(txt1scrn[i], 40, $0000) // text screen
memset(txt2scrn[i], 40, $0000) ; color screen memset(txt2scrn[i], 40, $0000) // color screen
next next
return grscrn(@txt2scrn) ; point to color screen return grscrn(@txt2scrn) // point to color screen
end end
; //
; Machine specific initialization. // Machine specific initialization.
; //
when MACHID & $C8 when MACHID & $C8
is $08 ; Apple 1 is $08 // Apple 1
conio:reset = @a1reset conio:reset = @a1reset
conio:keypressed = @a1keypressed conio:keypressed = @a1keypressed
conio:home = @a1home conio:home = @a1home
@ -315,7 +315,7 @@ when MACHID & $C8
conio:texttype = @a1texttype conio:texttype = @a1texttype
conio:textmode = @a1textmode conio:textmode = @a1textmode
conio:grmixmode = @a1grmixmode conio:grmixmode = @a1grmixmode
is $C0 ; Apple /// is $C0 // Apple ///
conio:reset = @a3reset conio:reset = @a3reset
conio:keypressed = @a3keypressed conio:keypressed = @a3keypressed
conio:home = @a3home conio:home = @a3home
@ -324,6 +324,6 @@ when MACHID & $C8
conio:texttype = @a3texttype conio:texttype = @a3texttype
conio:textmode = @a3textmode conio:textmode = @a3textmode
conio:grmixmode = @a3grmixmode conio:grmixmode = @a3grmixmode
devcons = modaddr(@stdlib).5 ; devcons variable from STDLIB devcons = modaddr(@stdlib).5 // devcons variable from STDLIB
otherwise ; Apple ][ otherwise // Apple ][
wend wend

View File

@ -1,8 +1,8 @@
import STDLIB import STDLIB
predef memset predef memset
; //
; System flags: memory allocator screen holes. // System flags: memory allocator screen holes.
; //
const restxt1 = $0001 const restxt1 = $0001
const restxt2 = $0002 const restxt2 = $0002
const reshgr1 = $0004 const reshgr1 = $0004
@ -11,9 +11,9 @@ import STDLIB
const resxhgr2 = $0020 const resxhgr2 = $0020
end end
sysflags reshgr1 ; Reserve HGR page 1 sysflags reshgr1 // Reserve HGR page 1
memset($2000, $2000, 0) ; Clear HGR page 1 memset($2000, $2000, 0) // Clear HGR page 1
^$C054 ^$C054
^$C052 ^$C052
^$C057 ^$C057

View File

@ -4,11 +4,11 @@ end
import HGR1 import HGR1
end end
const view_height = 64 ; scan count of ground view const view_height = 64 // scan count of ground view
const fix_bits = 8 ; number of fixed point bits const fix_bits = 8 // number of fixed point bits
; //
; Hardware addresses // Hardware addresses
; //
const speaker=$C030 const speaker=$C030
const showgraphics=$C050 const showgraphics=$C050
const showtext=$C051 const showtext=$C051
@ -50,9 +50,9 @@ word = $02D0,$06D0,$0AD0,$0ED0,$12D0,$16D0,$1AD0,$1ED0
word = $0350,$0750,$0B50,$0F50,$1350,$1750,$1B50,$1F50 word = $0350,$0750,$0B50,$0F50,$1350,$1750,$1B50,$1F50
word = $03D0,$07D0,$0BD0,$0FD0,$13D0,$17D0,$1BD0,$1FD0 word = $03D0,$07D0,$0BD0,$0FD0,$13D0,$17D0,$1BD0,$1FD0
word hcolor[] = $0000,$552A,$2A55,$7F7F,$8080,$D5AA,$AAD5,$FFFF word hcolor[] = $0000,$552A,$2A55,$7F7F,$8080,$D5AA,$AAD5,$FFFF
; //
; def draw_scan(d8p8, scanptr) // def draw_scan(d8p8, scanptr)
; //
asm draw_scan asm draw_scan
!SOURCE "vmsrc/plvmzp.inc" !SOURCE "vmsrc/plvmzp.inc"
WFIXL = $80 WFIXL = $80

View File

@ -1,16 +1,16 @@
; //
; Include all imported modules and their data/functions. // Include all imported modules and their data/functions.
; //
include(stdlib.plh) include(stdlib.plh)
; //
; Profile commands. // Profile commands.
; //
const stop = 0 const stop = 0
const start = 1 const start = 1
const dump = 2 const dump = 2
; //
; Declare all global variables for this module. // Declare all global variables for this module.
; //
byte profstr[] = "PLASMA Profiler\n" byte profstr[] = "PLASMA Profiler\n"
byte optstr[] = "Module to profile" byte optstr[] = "Module to profile"
byte ttlstr[] = "Total executed opcodes: $" byte ttlstr[] = "Total executed opcodes: $"
@ -18,9 +18,9 @@ byte hdrstr[] = " OP COUNT\n"
byte valstr[] = '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' byte valstr[] = '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
word cmdstr word cmdstr
byte opstats[260] byte opstats[260]
; //
; Define functions. // Define functions.
; //
asm equate asm equate
!SOURCE "vmsrc/plvmzp.inc" !SOURCE "vmsrc/plvmzp.inc"
end end

View File

@ -2,16 +2,16 @@ import STDLIB
predef syscall, call, memset, getc, putc, puts, modaddr predef syscall, call, memset, getc, putc, puts, modaddr
byte MACHID byte MACHID
end end
; //
; Handy constants. // Handy constants.
; //
const FALSE=0 const FALSE=0
const TRUE=!FALSE const TRUE=!FALSE
const FULLMODE=0 const FULLMODE=0
const MIXMODE=1 const MIXMODE=1
; //
; Apple II hardware constants. // Apple II hardware constants.
; //
const speaker = $C030 const speaker = $C030
const showgraphics = $C050 const showgraphics = $C050
const showtext = $C051 const showtext = $C051
@ -27,50 +27,50 @@ const hgr1 = $2000
const hgr2 = $4000 const hgr2 = $4000
const page1 = 0 const page1 = 0
const page2 = 1 const page2 = 1
; //
; Predefined functions. // Predefined functions.
; //
predef a2keypressed, a2gotoxy, a2grmode, a2textmode predef a2keypressed, a2gotoxy, a2grmode, a2textmode
; //
; String data. // String data.
; //
byte a1err[] = "Apple 1 not supported.\n" byte a1err[] = "Apple 1 not supported.\n"
byte a3err[] = "Apple 3 version mismatch.\n" byte a3err[] = "Apple 3 version mismatch.\n"
byte exitmsg[] = "Press any key to exit.\n" byte exitmsg[] = "Press any key to exit.\n"
byte goodbye[] = "That's all, folks!\n" byte goodbye[] = "That's all, folks!\n"
byte stdlib[] = "STDLIB" byte stdlib[] = "STDLIB"
; //
; Screen row address arrays. // Screen row address arrays.
; //
word txt1scrn[] = $0400,$0480,$0500,$0580,$0600,$0680,$0700,$0780 word txt1scrn[] = $0400,$0480,$0500,$0580,$0600,$0680,$0700,$0780
word = $0428,$04A8,$0528,$05A8,$0628,$06A8,$0728,$07A8 word = $0428,$04A8,$0528,$05A8,$0628,$06A8,$0728,$07A8
word = $0450,$04D0,$0550,$05D0,$0650,$06D0,$0750,$07D0 word = $0450,$04D0,$0550,$05D0,$0650,$06D0,$0750,$07D0
word txt2scrn[] = $0800,$0880,$0900,$0980,$0A00,$0A80,$0B00,$0B80 word txt2scrn[] = $0800,$0880,$0900,$0980,$0A00,$0A80,$0B00,$0B80
word = $0828,$08A8,$0928,$09A8,$0A28,$0AA8,$0B28,$0BA8 word = $0828,$08A8,$0928,$09A8,$0A28,$0AA8,$0B28,$0BA8
word = $0850,$08D0,$0950,$09D0,$0A50,$0AD0,$0B50,$0BD0 word = $0850,$08D0,$0950,$09D0,$0A50,$0AD0,$0B50,$0BD0
; //
; Apple 3 console codes. // Apple 3 console codes.
; //
byte textbwmode[] = 2, 16, 0 byte textbwmode[] = 2, 16, 0
byte textclrmode[] = 2, 16, 1 byte textclrmode[] = 2, 16, 1
byte grcharset[] = 1, 0, $7F, $7F, $7F, $7F, $00, $00, $00, $00 byte grcharset[] = 1, 0, $7F, $7F, $7F, $7F, $00, $00, $00, $00
byte devcons byte devcons
; //
; Function pointers. // Function pointers.
; //
word keypressed = @a2keypressed word keypressed = @a2keypressed
word gotoxy = @a2gotoxy word gotoxy = @a2gotoxy
word grmode = @a2grmode word grmode = @a2grmode
word textmode = @a2textmode word textmode = @a2textmode
; //
; Common routines. // Common routines.
; //
asm equates asm equates
!SOURCE "vmsrc/plvmzp.inc" !SOURCE "vmsrc/plvmzp.inc"
end end
; //
; def grscrn(rowaddrs) // def grscrn(rowaddrs)
; //
asm grscrn asm grscrn
GRSCRN = $26 GRSCRN = $26
GRSCRNL = GRSCRN GRSCRNL = GRSCRN
@ -81,9 +81,9 @@ GRSCRNH = GRSCRNL+1
STA GRSCRNH STA GRSCRNH
RTS RTS
end end
; //
; def grcolor(color) // def grcolor(color)
; //
asm grcolor asm grcolor
GRCLR = $30 GRCLR = $30
LDA #$0F LDA #$0F
@ -97,9 +97,9 @@ GRCLR = $30
STA GRCLR STA GRCLR
RTS RTS
end end
; //
; def grplot(x, y) // def grplot(x, y)
; //
asm grplot asm grplot
STY IPY STY IPY
LDA ESTKL,X LDA ESTKL,X
@ -128,9 +128,9 @@ asm grplot
INX INX
RTS RTS
end end
; //
; Apple II routines. // Apple II routines.
; //
def a2keypressed def a2keypressed
if ^keyboard >= 128 if ^keyboard >= 128
return ^keystrobe return ^keystrobe
@ -142,21 +142,21 @@ def a2gotoxy(x, y)
return call($FB5B, y + ^$22, 0, 0, 0) return call($FB5B, y + ^$22, 0, 0, 0)
end end
def a2grmode(mix) def a2grmode(mix)
call($FB2F, 0, 0, 0, 0) ;initmode() call($FB2F, 0, 0, 0, 0) // initmode()
call($FB40, 0, 0, 0, 0) ;grmode() call($FB40, 0, 0, 0, 0) // grmode()
if !mix if !mix
^showfull ^showfull
fin fin
call($FC58, 0, 0, 0, 0) ;home() call($FC58, 0, 0, 0, 0) // home()
return grscrn(@txt1scrn) ; point to lo-res screen return grscrn(@txt1scrn) // point to lo-res screen
end end
def a2textmode def a2textmode
call($FB39, 0, 0, 0, 0) ;textmode() call($FB39, 0, 0, 0, 0) // textmode()
return call($FC58, 0, 0, 0, 0) ;home() return call($FC58, 0, 0, 0, 0) // home()
end end
; //
; Apple III routines. // Apple III routines.
; //
def dev_control(devnum, code, list) def dev_control(devnum, code, list)
byte params[5] byte params[5]
@ -190,7 +190,7 @@ def a3gotoxy(x, y)
return putc(y) return putc(y)
end end
def a3viewport(left, top, width, height) def a3viewport(left, top, width, height)
putc(1) ; Reset viewport putc(1) // Reset viewport
putc(26) putc(26)
putc(left) putc(left)
putc(top) putc(top)
@ -212,19 +212,19 @@ def a3grmode(mix)
dev_control(devcons, 17, @grcharset) dev_control(devcons, 17, @grcharset)
a3viewport(0, 20, 40, 4) a3viewport(0, 20, 40, 4)
for i = 0 to mix for i = 0 to mix
memset(txt1scrn[i], 40, $0000) ; text screen memset(txt1scrn[i], 40, $0000) // text screen
memset(txt2scrn[i], 40, $0000) ; color screen memset(txt2scrn[i], 40, $0000) // color screen
next next
return grscrn(@txt2scrn) ; point to color screen return grscrn(@txt2scrn) // point to color screen
end end
def a3textmode def a3textmode
puts(@textbwmode) puts(@textbwmode)
a3viewport(0, 0, 40, 24) a3viewport(0, 0, 40, 24)
return putc(28) return putc(28)
end end
; //
; Rod's Colors. // Rod's Colors.
; //
def rod def rod
byte i, j, k, w, fmi, fmk, color byte i, j, k, w, fmi, fmk, color
while TRUE while TRUE
@ -252,25 +252,25 @@ def rod
next next
loop loop
end end
; //
; Machine specific initialization. // Machine specific initialization.
; //
when MACHID & $C8 when MACHID & $C8
is $08 ; Apple 1 is $08 // Apple 1
puts(@a1err) puts(@a1err)
return return
is $C0 ; Apple /// is $C0 // Apple ///
keypressed = @a3keypressed keypressed = @a3keypressed
gotoxy = @a3gotoxy gotoxy = @a3gotoxy
grmode = @a3grmode grmode = @a3grmode
textmode = @a3textmode textmode = @a3textmode
if modaddr(@stdlib):0 == $0010 if modaddr(@stdlib):0 == $0010
devcons = modaddr(@stdlib).5 ; devcons variable from STDLIB devcons = modaddr(@stdlib).5 // devcons variable from STDLIB
else else
puts(@a3err) puts(@a3err)
return return
fin fin
otherwise ; Apple ][ otherwise // Apple ][
wend wend
grmode(MIXMODE) grmode(MIXMODE)
gotoxy(11, 1) gotoxy(11, 1)

View File

@ -18,10 +18,7 @@ def beep
end end
def puti(i) def puti(i)
if i < 0 if i < 0; putc('-'); i = -i; fin
putc('-')
i = -i
fin
if i < 10 if i < 10
putc(i + '0') putc(i + '0')
else else

View File

@ -1,14 +1,11 @@
; //
; Include all imported modules and their data/functions. // Include all imported modules and their data/functions.
; //
include(stdlib.plh) include(stdlib.plh)
include(testlib.plh) include(testlib.plh)
//
; // Declare all global variables for this module.
; Declare all global variables for this module. //
;
byte hello[] = "Hello, Apple " byte hello[] = "Hello, Apple "
byte a1[] = "1" byte a1[] = "1"
byte a2[] = "][" byte a2[] = "]["
@ -19,11 +16,9 @@ byte a3[] = "///"
word struct[] = 1, 10, 100, 1000, 10000 word struct[] = 1, 10, 100, 1000, 10000
word ptr word ptr
byte spaces[] = " " byte spaces[] = " "
//
; // Define functions.
; Define functions. //
;
def tens(start) def tens(start)
word i word i
i = start i = start
@ -35,7 +30,6 @@ def tens(start)
i = i / 10 i = i / 10
until i == 0 until i == 0
end end
def ascii def ascii
byte i byte i
i = 32 i = 32
@ -44,7 +38,6 @@ def ascii
i = i + 1 i = i + 1
loop loop
end end
def nums(range) def nums(range)
word i word i
for i = range downto -range step range/10 for i = range downto -range step range/10
@ -52,7 +45,6 @@ def nums(range)
putln putln
next next
end end
export def main(range) export def main(range)
nums(*range) nums(*range)
tens(*range*10) tens(*range*10)
@ -83,8 +75,7 @@ export def main(range)
wend wend
putln putln
end end
ptr = @struct
ptr=@struct
main(@struct:6) main(@struct:6)
puti((ptr):6) puti((ptr):6)
putln putln

View File

@ -1,22 +1,17 @@
; //
; Include all imported modules and their data/functions. // Include all imported modules and their data/functions.
; //
include(stdlib.plh) include(stdlib.plh)
//
; // Module data.
; Module data. //
;
predef puti, puth, putln predef puti, puth, putln
export word print[] = @puti, @puth, @putln, @puts, @putc export word print[] = @puti, @puth, @putln, @puts, @putc
byte valstr[] = '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' byte valstr[] = '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
byte loadstr[] = "testlib loaded!" byte loadstr[] = "testlib loaded!"
//
; // Define functions.
; Define functions. //
;
def puth(h) def puth(h)
putc('$') putc('$')
putc(valstr[(h >> 12) & $0F]) putc(valstr[(h >> 12) & $0F])
@ -24,12 +19,8 @@ def puth(h)
putc(valstr[(h >> 4) & $0F]) putc(valstr[(h >> 4) & $0F])
putc(valstr[ h & $0F]) putc(valstr[ h & $0F])
end end
export def puti(i) export def puti(i)
if i < 0 if i < 0; putc('-'); i = -i; fin
putc('-')
i = -i
fin
if i < 10 if i < 10
putc(i + '0') putc(i + '0')
else else
@ -37,7 +28,6 @@ export def puti(i)
putc(i % 10 + '0') putc(i % 10 + '0')
fin fin
end end
puts(@loadstr) puts(@loadstr)
putln putln
done done

View File

@ -4,7 +4,7 @@
#include "tokens.h" #include "tokens.h"
#include "symbols.h" #include "symbols.h"
char *statement, *scanpos, *tokenstr; char *statement, *tokenstr, *scanpos = "";
t_token scantoken, prevtoken; t_token scantoken, prevtoken;
int tokenlen; int tokenlen;
long constval; long constval;
@ -22,28 +22,28 @@ t_token keywords[] = {
ENDCASE_TOKEN, 'W', 'E', 'N', 'D', ENDCASE_TOKEN, 'W', 'E', 'N', 'D',
FOR_TOKEN, 'F', 'O', 'R', FOR_TOKEN, 'F', 'O', 'R',
TO_TOKEN, 'T', 'O', TO_TOKEN, 'T', 'O',
DOWNTO_TOKEN, 'D', 'O', 'W', 'N', 'T', 'O', DOWNTO_TOKEN, 'D', 'O', 'W', 'N', 'T', 'O',
STEP_TOKEN, 'S', 'T', 'E', 'P', STEP_TOKEN, 'S', 'T', 'E', 'P',
NEXT_TOKEN, 'N', 'E', 'X', 'T', NEXT_TOKEN, 'N', 'E', 'X', 'T',
REPEAT_TOKEN, 'R', 'E', 'P', 'E', 'A', 'T', REPEAT_TOKEN, 'R', 'E', 'P', 'E', 'A', 'T',
UNTIL_TOKEN, 'U', 'N', 'T', 'I', 'L', UNTIL_TOKEN, 'U', 'N', 'T', 'I', 'L',
BREAK_TOKEN, 'B', 'R', 'E', 'A', 'K', BREAK_TOKEN, 'B', 'R', 'E', 'A', 'K',
ASM_TOKEN, 'A', 'S', 'M', ASM_TOKEN, 'A', 'S', 'M',
DEF_TOKEN, 'D', 'E', 'F', DEF_TOKEN, 'D', 'E', 'F',
EXPORT_TOKEN, 'E', 'X', 'P', 'O', 'R', 'T', EXPORT_TOKEN, 'E', 'X', 'P', 'O', 'R', 'T',
IMPORT_TOKEN, 'I', 'M', 'P', 'O', 'R', 'T', IMPORT_TOKEN, 'I', 'M', 'P', 'O', 'R', 'T',
RETURN_TOKEN, 'R', 'E', 'T', 'U', 'R', 'N', RETURN_TOKEN, 'R', 'E', 'T', 'U', 'R', 'N',
END_TOKEN, 'E', 'N', 'D', END_TOKEN, 'E', 'N', 'D',
EXIT_TOKEN, 'E', 'X', 'I', 'T', EXIT_TOKEN, 'E', 'X', 'I', 'T',
DONE_TOKEN, 'D', 'O', 'N', 'E', DONE_TOKEN, 'D', 'O', 'N', 'E',
LOGIC_NOT_TOKEN, 'N', 'O', 'T', LOGIC_NOT_TOKEN, 'N', 'O', 'T',
LOGIC_AND_TOKEN, 'A', 'N', 'D', LOGIC_AND_TOKEN, 'A', 'N', 'D',
LOGIC_OR_TOKEN, 'O', 'R', LOGIC_OR_TOKEN, 'O', 'R',
BYTE_TOKEN, 'B', 'Y', 'T', 'E', BYTE_TOKEN, 'B', 'Y', 'T', 'E',
WORD_TOKEN, 'W', 'O', 'R', 'D', WORD_TOKEN, 'W', 'O', 'R', 'D',
CONST_TOKEN, 'C', 'O', 'N', 'S', 'T', CONST_TOKEN, 'C', 'O', 'N', 'S', 'T',
PREDEF_TOKEN, 'P', 'R', 'E', 'D', 'E', 'F', PREDEF_TOKEN, 'P', 'R', 'E', 'D', 'E', 'F',
SYSFLAGS_TOKEN, 'S', 'Y', 'S', 'F', 'L', 'A', 'G', 'S', SYSFLAGS_TOKEN, 'S', 'Y', 'S', 'F', 'L', 'A', 'G', 'S',
EOL_TOKEN EOL_TOKEN
}; };
@ -333,6 +333,15 @@ t_token scan(void)
scanpos++; scanpos++;
} }
break; break;
case '/':
if (scanpos[1] == '/')
scantoken = EOL_TOKEN;
else
{
scantoken = DIV_TOKEN;
scanpos++;
}
break;
default: default:
/* /*
* Simple single character tokens. * Simple single character tokens.
@ -363,12 +372,21 @@ int scan_lookahead(void)
char inputline[512]; char inputline[512];
int next_line(void) int next_line(void)
{ {
gets(inputline); if (*scanpos == ';')
lineno++; {
statement = inputline; statement = ++scanpos;
scanpos = inputline; scantoken = EOL_TOKEN;
scantoken = EOL_TOKEN; scan();
scan(); }
printf("; %03d: %s\n", lineno, inputline); else
{
gets(inputline);
lineno++;
statement = inputline;
scanpos = inputline;
scantoken = EOL_TOKEN;
scan();
printf("; %03d: %s\n", lineno, inputline);
}
return (1); return (1);
} }

View File

@ -1,9 +1,9 @@
const MODADDR = $1000 const MODADDR = $1000
const inbuff = $200 const inbuff = $200
const freemem = $0006 const freemem = $0006
; //
; CFFA1 addresses. // CFFA1 addresses.
; //
const CFFADest = $00 const CFFADest = $00
const CFFAFileName = $02 const CFFAFileName = $02
const CFFAOldName = $04 const CFFAOldName = $04
@ -11,31 +11,31 @@ const CFFAFileType = $06
const CFFAAuxType = $07 const CFFAAuxType = $07
const CFFAFileSize = $09 const CFFAFileSize = $09
const CFFAEntryPtr = $0B const CFFAEntryPtr = $0B
; //
; Pedefined functions. // Pedefined functions.
; //
predef crout, cout, prstr, cin, rdstr predef crout, cout, prstr, cin, rdstr
predef syscall, call predef syscall, call
predef markheap, allocheap, allocalignheap, releaseheap, availheap predef markheap, allocheap, allocalignheap, releaseheap, availheap
predef memset, memcpy predef memset, memcpy
predef uword_isgt, uword_isge, uword_islt, uword_isle predef uword_isgt, uword_isge, uword_islt, uword_isle
predef loadmod, execmod, lookupstrmod predef loadmod, execmod, lookupstrmod
; //
; System variables. // System variables.
; //
word version = $0010 ; 00.10 word version = $0010 // 00.10
word systemflags = 0 word systemflags = 0
word heap word heap
word symtbl, lastsym word symtbl, lastsym
byte perr byte perr
word cmdptr word cmdptr
; //
; Exported Machine ID. // Exported Machine ID.
; //
byte machid = $08 ; Apple 1 (NA in ProDOS Tech Ref) byte machid = $08 // Apple 1 (NA in ProDOS Tech Ref)
; //
; Standard Library exported functions. // Standard Library exported functions.
; //
byte stdlibstr[] = "STDLIB" byte stdlibstr[] = "STDLIB"
byte machidstr[] = "MACHID" byte machidstr[] = "MACHID"
byte putcstr[] = "PUTC" byte putcstr[] = "PUTC"
@ -82,9 +82,9 @@ word = @modadrstr, @lookupstrmod
word = @machidstr, @machid word = @machidstr, @machid
word = 0 word = 0
word stdlibsym = @exports word stdlibsym = @exports
; //
; String pool. // String pool.
; //
byte autorun[] = "AUTORUN" byte autorun[] = "AUTORUN"
byte verstr[] = "\nPLASMA " byte verstr[] = "\nPLASMA "
byte freestr[] = "MEM FREE:$" byte freestr[] = "MEM FREE:$"
@ -93,10 +93,10 @@ byte prompt[] = "PLASMA"
byte okstr[] = "OK" byte okstr[] = "OK"
byte huhstr[] = "?\n" byte huhstr[] = "?\n"
byte hexchar[] = '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' byte hexchar[] = '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
; //
; CALL CFFA1 API ENTRYPOINT // CALL CFFA1 API ENTRYPOINT
; SYSCALL(CMD) // SYSCALL(CMD)
; //
asm syscall asm syscall
LDA ESTKL,X LDA ESTKL,X
STX ESP STX ESP
@ -108,10 +108,10 @@ asm syscall
STY ESTKH,X STY ESTKH,X
RTS RTS
end end
; //
; CALL 6502 ROUTINE // CALL 6502 ROUTINE
; CALL(AREG, XREG, YREG, STATUS, ADDR) // CALL(AREG, XREG, YREG, STATUS, ADDR)
; //
asm call asm call
REGVALS = SRC REGVALS = SRC
PHP PHP
@ -150,17 +150,17 @@ REGVALS = SRC
RTS RTS
JMPTMP JMP (TMP) JMPTMP JMP (TMP)
end end
; //
; QUIT TO MONITOR // QUIT TO MONITOR
; //
asm quit asm quit
JMP $9000 JMP $9000
end end
; //
; SET MEMORY TO VALUE // SET MEMORY TO VALUE
; MEMSET(ADDR, SIZE, VALUE) // MEMSET(ADDR, SIZE, VALUE)
; With optimizations from Peter Ferrie // With optimizations from Peter Ferrie
; //
asm memset asm memset
LDY #$00 LDY #$00
LDA ESTKL+2,X LDA ESTKL+2,X
@ -187,10 +187,10 @@ SETMEX INX
INX INX
RTS RTS
end end
; //
; COPY MEMORY // COPY MEMORY
; MEMCPY(DSTADDR, SRCADDR, SIZE) // MEMCPY(DSTADDR, SRCADDR, SIZE)
; //
asm memcpy asm memcpy
INX INX
INX INX
@ -260,9 +260,9 @@ REVCPYLP LDA (SRC),Y
BNE REVCPYLP BNE REVCPYLP
CPYMEX RTS CPYMEX RTS
end end
; //
; Unsigned word comparisons. // Unsigned word comparisons.
; //
asm uword_isge asm uword_isge
LDY #$00 LDY #$00
LDA ESTKL+1,X LDA ESTKL+1,X
@ -313,9 +313,9 @@ asm uword_islt
INX INX
RTS RTS
end end
; //
; Addresses of internal routines. // Addresses of internal routines.
; //
asm interp asm interp
DEX DEX
LDA #<IINTERP LDA #<IINTERP
@ -324,21 +324,21 @@ asm interp
STA ESTKH,X STA ESTKH,X
RTS RTS
end end
; //
; A DCI string is one that has the high bit set for every character except the last. // A DCI string is one that has the high bit set for every character except the last.
; More efficient than C or Pascal strings. // More efficient than C or Pascal strings.
; //
;def dcitos(dci, str) //def dcitos(dci, str)
; byte len, c // byte len, c
; len = 0 // len = 0
; repeat // repeat
; c = (dci).[len] // c = (dci).[len]
; len = len + 1 // len = len + 1
; (str).[len] = c & $7F // (str).[len] = c & $7F
; until !(c & $80) // until !(c & $80)
; ^str = len // ^str = len
; return len // return len
;end //end
asm dcitos asm dcitos
LDA ESTKL,X LDA ESTKL,X
STA DSTL STA DSTL
@ -363,22 +363,22 @@ asm dcitos
STY ESTKH,X STY ESTKH,X
RTS RTS
end end
;def stodci(str, dci) //def stodci(str, dci)
; byte len, c // byte len, c
; len = ^str // len = ^str
; if len == 0 // if len == 0
; return // return
; fin // fin
; c = toupper((str).[len]) & $7F // c = toupper((str).[len]) & $7F
; len = len - 1 // len = len - 1
; (dci).[len] = c // (dci).[len] = c
; while len // while len
; c = toupper((str).[len]) | $80 // c = toupper((str).[len]) | $80
; len = len - 1 // len = len - 1
; (dci).[len] = c // (dci).[len] = c
; loop // loop
; return ^str // return ^str
;end //end
asm stodci asm stodci
LDA ESTKL,X LDA ESTKL,X
STA DSTL STA DSTL
@ -418,22 +418,22 @@ TOUPR AND #$7F
+ STA ESTKL,X + STA ESTKL,X
RTS RTS
end end
; //
; Module symbols are entered into the symbol table // Module symbols are entered into the symbol table
; pre-pended with a '#' to differentiate them // pre-pended with a '#' to differentiate them
; from normal symbols. // from normal symbols.
; //
;def modtosym(mod, dci) //def modtosym(mod, dci)
; byte len, c // byte len, c
; (dci).0 = '#'|$80 // (dci).0 = '#'|$80
; len = 0 // len = 0
; repeat // repeat
; c = (mod).[len] // c = (mod).[len]
; len = len + 1 // len = len + 1
; (dci).[len] = c // (dci).[len] = c
; until !(c & $80) // until !(c & $80)
; return dci // return dci
;end //end
asm modtosym asm modtosym
LDA ESTKL+1,X LDA ESTKL+1,X
STA SRCL STA SRCL
@ -455,26 +455,26 @@ asm modtosym
BCS - BCS -
RTS RTS
end end
; //
; Lookup routines. // Lookup routines.
; //
;def lookuptbl(dci, tbl) //def lookuptbl(dci, tbl)
; word match // word match
; while ^tbl // while ^tbl
; match = dci // match = dci
; while ^tbl == ^match // while ^tbl == ^match
; if !(^tbl & $80) // if !(^tbl & $80)
; return (tbl):1 // return (tbl):1
; fin // fin
; tbl = tbl + 1 // tbl = tbl + 1
; match = match + 1 // match = match + 1
; loop // loop
; while (^tbl & $80) // while (^tbl & $80)
; tbl = tbl + 1 // tbl = tbl + 1
; loop // loop
; tbl = tbl + 3 // tbl = tbl + 3
; loop // loop
; return 0 // return 0
asm lookuptbl asm lookuptbl
LDA ESTKL,X LDA ESTKL,X
STA DSTL STA DSTL
@ -516,9 +516,9 @@ asm lookuptbl
INC DSTH INC DSTH
BCS - BCS -
end end
; //
; CONSOLE I/O // CONSOLE I/O
; //
asm cout asm cout
LDA ESTKL,X LDA ESTKL,X
JSR TOUPR JSR TOUPR
@ -555,19 +555,19 @@ def rdstr(prompt)
repeat repeat
ch = cin ch = cin
when ch when ch
is $15 ; right arrow is $15 // right arrow
if inbuff.0 < maxlen if inbuff.0 < maxlen
inbuff.0 = inbuff.0 + 1 inbuff.0 = inbuff.0 + 1
ch = inbuff[inbuff.0] ch = inbuff[inbuff.0]
cout(ch) cout(ch)
fin fin
is $08 ; left arrow is $08 // left arrow
if inbuff.0 if inbuff.0
cout('\\') cout('\\')
cout(inbuff[inbuff.0]) cout(inbuff[inbuff.0])
inbuff.0 = inbuff.0 - 1 inbuff.0 = inbuff.0 - 1
fin fin
is $04 ; ctrl-d is $04 // ctrl-d
if inbuff.0 if inbuff.0
cout('#') cout('#')
cout(inbuff[inbuff.0]) cout(inbuff[inbuff.0])
@ -575,14 +575,14 @@ def rdstr(prompt)
maxlen = maxlen - 1 maxlen = maxlen - 1
inbuff.0 = inbuff.0 - 1 inbuff.0 = inbuff.0 - 1
fin fin
is $0C ; ctrl-l is $0C // ctrl-l
crout crout
prstr(inbuff) prstr(inbuff)
is $0D ; return is $0D // return
is $18 ; ctrl-x is $18 // ctrl-x
crout crout
inbuff.0 = 0 inbuff.0 = 0
is $9B ; escape is $9B // escape
inbuff.0 = 0 inbuff.0 = 0
ch = $0D ch = $0D
otherwise otherwise
@ -607,18 +607,18 @@ def prword(v)
prbyte(v >> 8) prbyte(v >> 8)
return prbyte(v) return prbyte(v)
end end
; //
; CFFA1 routines // CFFA1 routines
; FILE I/O // FILE I/O
; //
;def opendir //def opendir
; perr = syscall($10) // perr = syscall($10)
; return perr // return perr
;end //end
;def readdir //def readdir
; perr = syscall($12) // perr = syscall($12)
; return *CFFAEntryPtr // return *CFFAEntryPtr
;end //end
def finddirentry(filename) def finddirentry(filename)
*CFFAFileName = filename *CFFAFileName = filename
perr = syscall($14) perr = syscall($14)
@ -630,9 +630,9 @@ def readfile(filename, buffer)
perr = syscall($22) perr = syscall($22)
return perr return perr
end end
; //
; Heap routines. // Heap routines.
; //
def availheap def availheap
byte fp byte fp
return @fp - heap return @fp - heap
@ -660,15 +660,15 @@ def allocalignheap(size, pow2, freeaddr)
return addr return addr
end end
def markheap def markheap
return heap; return heap
end end
def releaseheap(newheap) def releaseheap(newheap)
heap = newheap; heap = newheap
return @newheap - heap; return @newheap - heap
end end
; //
; Symbol table routines. // Symbol table routines.
; //
def lookupsym(sym) def lookupsym(sym)
return lookuptbl(sym, symtbl) return lookuptbl(sym, symtbl)
end end
@ -683,9 +683,9 @@ def addsym(sym, addr)
lastsym = lastsym + 3 lastsym = lastsym + 3
^lastsym = 0 ^lastsym = 0
end end
; //
; Module routines. // Module routines.
; //
def lookupmod(mod) def lookupmod(mod)
byte dci[17] byte dci[17]
return lookuptbl(modtosym(mod, @dci), symtbl) return lookuptbl(modtosym(mod, @dci), symtbl)
@ -726,7 +726,7 @@ def adddef(addr, deflast)
defentry->0 = $20 defentry->0 = $20
defentry=>1 = interp defentry=>1 = interp
defentry=>3 = addr defentry=>3 = addr
defentry->5 = 0 ; null out next entry defentry->5 = 0 // null out next entry
return defentry return defentry
end end
def lookupdef(addr, deftbl) def lookupdef(addr, deftbl)
@ -745,9 +745,9 @@ def loadmod(mod)
word moddep, rld, esd, sym word moddep, rld, esd, sym
byte str[17], filename[17] byte str[17], filename[17]
byte header[128] byte header[128]
; //
; Read the RELocatable module header (first 128 bytes) // Read the RELocatable module header (first 128 bytes)
; //
dcitos(mod, @filename) dcitos(mod, @filename)
rdlen = finddirentry(@filename)=>$15 rdlen = finddirentry(@filename)=>$15
if perr if perr
@ -760,17 +760,17 @@ def loadmod(mod)
moddep = @header.1 moddep = @header.1
defofst = modsize defofst = modsize
init = 0 init = 0
if rdlen > 4 and heap=>2 == $DA7E ; DAVE = magic number :-) if rdlen > 4 and heap=>2 == $DA7E // DAVE = magic number :-)
; //
; This is an EXTended RELocatable (data+bytecode) module. // This is an EXTended RELocatable (data+bytecode) module.
; //
defofst = header:6 defofst = header:6
defcnt = header:8 defcnt = header:8
init = header:10 init = header:10
moddep = @header.12 moddep = @header.12
; //
; Load module dependencies. // Load module dependencies.
; //
while ^moddep while ^moddep
if !lookupmod(moddep) if !lookupmod(moddep)
if loadmod(moddep) < 0 if loadmod(moddep) < 0
@ -779,94 +779,94 @@ def loadmod(mod)
fin fin
moddep = moddep + dcitos(moddep, @str) moddep = moddep + dcitos(moddep, @str)
loop loop
; //
; Init def table. // Init def table.
; //
deftbl = allocheap(defcnt * 5 + 1) deftbl = allocheap(defcnt * 5 + 1)
deflast = deftbl deflast = deftbl
^deflast = 0 ^deflast = 0
; //
; Re-read file // Re-read file
; //
readfile(@filename, heap) readfile(@filename, heap)
fin fin
; //
; Alloc heap space for relocated module (data + bytecode). // Alloc heap space for relocated module (data + bytecode).
; //
moddep = moddep + 1 - @header + heap moddep = moddep + 1 - @header + heap
modfix = moddep - (heap + 2) ; Adjust to skip header modfix = moddep - (heap + 2) // Adjust to skip header
modsize = modsize - modfix modsize = modsize - modfix
rdlen = rdlen - modfix - 2 rdlen = rdlen - modfix - 2
modaddr = allocheap(modsize) modaddr = allocheap(modsize)
memcpy(modaddr, moddep, rdlen) memcpy(modaddr, moddep, rdlen)
; //
; Add module to symbol table. // Add module to symbol table.
; //
addmod(mod, modaddr) addmod(mod, modaddr)
; //
; Apply all fixups and symbol import/export. // Apply all fixups and symbol import/export.
; //
modfix = modaddr - modfix modfix = modaddr - modfix
bytecode = defofst + modfix - MODADDR bytecode = defofst + modfix - MODADDR
modend = modaddr + modsize modend = modaddr + modsize
rld = modend ; Re-Locatable Directory rld = modend // Re-Locatable Directory
esd = rld ; Extern+Entry Symbol Directory esd = rld // Extern+Entry Symbol Directory
while ^esd ; Scan to end of ESD while ^esd // Scan to end of ESD
esd = esd + 4 esd = esd + 4
loop loop
esd = esd + 1 esd = esd + 1
; //
; Run through the Re-Location Dictionary. // Run through the Re-Location Dictionary.
; //
while ^rld while ^rld
if ^rld == $02 if ^rld == $02
; //
; This is a bytcode def entry - add it to the def directory. // This is a bytcode def entry - add it to the def directory.
; //
adddef(rld=>1 - defofst + bytecode, @deflast) adddef(rld=>1 - defofst + bytecode, @deflast)
else else
addr = rld=>1 + modfix addr = rld=>1 + modfix
if uword_isge(addr, modaddr) ; Skip fixups to header if uword_isge(addr, modaddr) // Skip fixups to header
if ^rld & $80 ; WORD sized fixup. if ^rld & $80 // WORD sized fixup.
fixup = *addr fixup = *addr
else ; BYTE sized fixup. else // BYTE sized fixup.
fixup = ^addr fixup = ^addr
fin fin
if ^rld & $10 ; EXTERN reference. if ^rld & $10 // EXTERN reference.
fixup = fixup + lookupextern(esd, rld->3) fixup = fixup + lookupextern(esd, rld->3)
else ; INTERN fixup. else // INTERN fixup.
fixup = fixup + modfix - MODADDR fixup = fixup + modfix - MODADDR
if uword_isge(fixup, bytecode) if uword_isge(fixup, bytecode)
; //
; Bytecode address - replace with call def directory. // Bytecode address - replace with call def directory.
; //
fixup = lookupdef(fixup - bytecode + bytecode, deftbl) fixup = lookupdef(fixup - bytecode + bytecode, deftbl)
fin fin
fin fin
if ^rld & $80 ; WORD sized fixup. if ^rld & $80 // WORD sized fixup.
*addr = fixup *addr = fixup
else ; BYTE sized fixup. else // BYTE sized fixup.
^addr = fixup ^addr = fixup
fin fin
fin fin
fin fin
rld = rld + 4 rld = rld + 4
loop loop
; //
; Run through the External/Entry Symbol Directory. // Run through the External/Entry Symbol Directory.
; //
while ^esd while ^esd
sym = esd sym = esd
esd = esd + dcitos(esd, @str) esd = esd + dcitos(esd, @str)
if ^esd & $08 if ^esd & $08
; //
; EXPORT symbol - add it to the global symbol table. // EXPORT symbol - add it to the global symbol table.
; //
addr = esd=>1 + modfix - MODADDR addr = esd=>1 + modfix - MODADDR
if uword_isge(addr, bytecode) if uword_isge(addr, bytecode)
; //
; Use the def directory address for bytecode. // Use the def directory address for bytecode.
; //
addr = lookupdef(addr - bytecode + bytecode, deftbl) addr = lookupdef(addr - bytecode + bytecode, deftbl)
fin fin
addsym(sym, addr) addsym(sym, addr)
@ -877,24 +877,24 @@ def loadmod(mod)
if perr if perr
return -perr return -perr
fin fin
; //
; Call init routine if it exists. // Call init routine if it exists.
; //
if init if init
fixup = adddef(init - defofst + bytecode, @deflast)() fixup = adddef(init - defofst + bytecode, @deflast)()
modend = init - defofst + bytecode modend = init - defofst + bytecode
else else
fixup = 0 fixup = 0
fin fin
; //
; Free up the end-of-module in main memory. // Free up the end-of-module in main memory.
; //
releaseheap(modend) releaseheap(modend)
return fixup return fixup
end end
; //
; Command mode // Command mode
; //
def stripchars(strptr) def stripchars(strptr)
while ^strptr and ^(strptr + 1) <> ' ' while ^strptr and ^(strptr + 1) <> ' '
memcpy(strptr + 1, strptr + 2, ^strptr) memcpy(strptr + 1, strptr + 2, ^strptr)
@ -949,13 +949,13 @@ def execmod(modfile)
heap = saveheap heap = saveheap
fin fin
end end
; //
; Get heap start. // Get heap start.
; //
heap = *freemem heap = *freemem
; //
; Init symbol table. // Init symbol table.
; //
symtbl = allocheap($200) symtbl = allocheap($200)
lastsym = symtbl lastsym = symtbl
^lastsym = 0 ^lastsym = 0
@ -966,14 +966,14 @@ while *stdlibsym
addsym(heap, stdlibsym=>2) addsym(heap, stdlibsym=>2)
stdlibsym = stdlibsym + 4 stdlibsym = stdlibsym + 4
loop loop
; //
; Try to run autorun module. // Try to run autorun module.
; //
execmod(@autorun) execmod(@autorun)
perr = 0 perr = 0
; //
; Print some startup info. // Print some startup info.
; //
prstr(@verstr) prstr(@verstr)
prbyte(version.1) prbyte(version.1)
cout('.') cout('.')
@ -982,9 +982,9 @@ crout
prstr(@freestr) prstr(@freestr)
prword(availheap) prword(availheap)
crout crout
; //
; Handle commands. // Handle commands.
; //
while 1 while 1
prstr(@prompt) prstr(@prompt)
cmdptr = rdstr($BA) cmdptr = rdstr($BA)

View File

@ -4,37 +4,37 @@ const databuff = $2000
const MODADDR = $1000 const MODADDR = $1000
const symtbl = $0C00 const symtbl = $0C00
const freemem = $0006 const freemem = $0006
; //
; System flags: memory allocator screen holes. // System flags: memory allocator screen holes.
; //
const restxt1 = $0001 const restxt1 = $0001
const restxt2 = $0002 const restxt2 = $0002
const reshgr1 = $0004 const reshgr1 = $0004
const reshgr2 = $0008 const reshgr2 = $0008
const resxhgr1 = $0010 const resxhgr1 = $0010
const resxhgr2 = $0020 const resxhgr2 = $0020
; //
; Pedefined functions. // Pedefined functions.
; //
predef syscall, call predef syscall, call
predef crout, cout, prstr, cin, rdstr predef crout, cout, prstr, cin, rdstr
predef markheap, allocheap, allocalignheap, releaseheap, availheap predef markheap, allocheap, allocalignheap, releaseheap, availheap
predef memset, memcpy predef memset, memcpy
predef uword_isgt, uword_isge, uword_islt, uword_isle predef uword_isgt, uword_isge, uword_islt, uword_isle
predef loadmod, execmod, lookupstrmod predef loadmod, execmod, lookupstrmod
; //
; System variable. // System variable.
; //
word version = $0010 ; 00.10 word version = $0010 // 00.10
word systemflags = 0 word systemflags = 0
word heap word heap
word xheap = $0800 word xheap = $0800
word lastsym = symtbl word lastsym = symtbl
byte perr byte perr
word cmdptr word cmdptr
; //
; Standard Library exported functions. // Standard Library exported functions.
; //
byte stdlibstr[] = "STDLIB" byte stdlibstr[] = "STDLIB"
byte machidstr[] = "MACHID" byte machidstr[] = "MACHID"
byte sysstr[] = "SYSCALL" byte sysstr[] = "SYSCALL"
@ -81,9 +81,9 @@ word = @modadrstr, @lookupstrmod
word = @machidstr, MACHID word = @machidstr, MACHID
word = 0 word = 0
word stdlibsym = @exports word stdlibsym = @exports
; //
; String pool. // String pool.
; //
byte autorun[] = "AUTORUN" byte autorun[] = "AUTORUN"
byte verstr[] = "PLASMA " byte verstr[] = "PLASMA "
byte freestr[] = "MEM FREE:$" byte freestr[] = "MEM FREE:$"
@ -91,14 +91,14 @@ byte errorstr[] = "ERR:$"
byte okstr[] = "OK" byte okstr[] = "OK"
byte huhstr[] = "?\n" byte huhstr[] = "?\n"
byte prefix[32] = "" byte prefix[32] = ""
; //
; Utility functions // Utility functions
; //
;asm equates included from cmdstub.s //asm equates included from cmdstub.s
; //
; CALL PRODOS // CALL PRODOS
; SYSCALL(CMD, PARAMS) // SYSCALL(CMD, PARAMS)
; //
asm syscall asm syscall
LDA ESTKL,X LDA ESTKL,X
LDY ESTKH,X LDY ESTKH,X
@ -115,10 +115,10 @@ PARAMS: !WORD 0000
STY ESTKH,X STY ESTKH,X
RTS RTS
end end
; //
; CALL 6502 ROUTINE // CALL 6502 ROUTINE
; CALL(ADDR, AREG, XREG, YREG, STATUS) // CALL(ADDR, AREG, XREG, YREG, STATUS)
; //
asm call asm call
REGVALS = SRC REGVALS = SRC
PHP PHP
@ -159,9 +159,9 @@ REGVALS = SRC
RTS RTS
JMPTMP JMP (TMP) JMPTMP JMP (TMP)
end end
; //
; CALL LOADED SYSTEM PROGRAM // CALL LOADED SYSTEM PROGRAM
; //
asm exec asm exec
LDX #$00 LDX #$00
STX IFPL STX IFPL
@ -173,19 +173,19 @@ asm exec
BIT ROMEN BIT ROMEN
JMP $2000 JMP $2000
end end
; //
; EXIT // EXIT
; //
asm reboot asm reboot
BIT ROMEN BIT ROMEN
DEC $03F4 ; INVALIDATE POWER-UP BYTE DEC $03F4 ; INVALIDATE POWER-UP BYTE
JMP ($FFFC) ; RESET JMP ($FFFC) ; RESET
end end
; //
; SET MEMORY TO VALUE // SET MEMORY TO VALUE
; MEMSET(ADDR, SIZE, VALUE) // MEMSET(ADDR, SIZE, VALUE)
; With optimizations from Peter Ferrie // With optimizations from Peter Ferrie
; //
asm memset asm memset
LDY #$00 LDY #$00
LDA ESTKL+2,X LDA ESTKL+2,X
@ -212,10 +212,10 @@ SETMEX INX
INX INX
RTS RTS
end end
; //
; COPY MEMORY // COPY MEMORY
; MEMCPY(DSTADDR, SRCADDR, SIZE) // MEMCPY(DSTADDR, SRCADDR, SIZE)
; //
asm memcpy asm memcpy
INX INX
INX INX
@ -285,11 +285,11 @@ REVCPYLP LDA (SRC),Y
BNE REVCPYLP BNE REVCPYLP
CPYMEX RTS CPYMEX RTS
end end
; //
; COPY FROM MAIN MEM TO AUX MEM. // COPY FROM MAIN MEM TO AUX MEM.
; //
; MEMXCPY(DST, SRC, SIZE) // MEMXCPY(DST, SRC, SIZE)
; //
asm memxcpy asm memxcpy
LDA ESTKL+1,X LDA ESTKL+1,X
STA $3C STA $3C
@ -320,10 +320,10 @@ asm crout
STA ESTKL,X STA ESTKL,X
; FALL THROUGH TO COUT ; FALL THROUGH TO COUT
end end
; //
; CHAR OUT // CHAR OUT
; COUT(CHAR) // COUT(CHAR)
; //
asm cout asm cout
LDA ESTKL,X LDA ESTKL,X
BIT $BF98 BIT $BF98
@ -335,10 +335,10 @@ asm cout
BIT LCRDEN+LCBNK2 BIT LCRDEN+LCBNK2
RTS RTS
end end
; //
; CHAR IN // CHAR IN
; RDKEY() // RDKEY()
; //
asm cin asm cin
BIT ROMEN BIT ROMEN
JSR $FD0C JSR $FD0C
@ -349,10 +349,10 @@ asm cin
STY ESTKH,X STY ESTKH,X
RTS RTS
end end
; //
; PRINT STRING // PRINT STRING
; PRSTR(STR) // PRSTR(STR)
; //
asm prstr asm prstr
LDY #$00 LDY #$00
LDA ESTKL,X LDA ESTKL,X
@ -375,9 +375,9 @@ asm prstr
BIT LCRDEN+LCBNK2 BIT LCRDEN+LCBNK2
++ RTS ++ RTS
end end
; //
; PRINT BYTE // PRINT BYTE
; //
asm prbyte asm prbyte
LDA ESTKL,X LDA ESTKL,X
STX ESP STX ESP
@ -387,9 +387,9 @@ asm prbyte
BIT LCRDEN+LCBNK2 BIT LCRDEN+LCBNK2
RTS RTS
end end
; //
; PRINT WORD // PRINT WORD
; //
asm prword asm prword
STX ESP STX ESP
TXA TXA
@ -402,10 +402,10 @@ asm prword
BIT LCRDEN+LCBNK2 BIT LCRDEN+LCBNK2
RTS RTS
end end
; //
; READ STRING // READ STRING
; STR = RDSTR(PROMPTCHAR) // STR = RDSTR(PROMPTCHAR)
; //
asm rdstr asm rdstr
LDA ESTKL,X LDA ESTKL,X
STA $33 STA $33
@ -476,23 +476,23 @@ asm uword_islt
INX INX
RTS RTS
end end
; //
; Utility routines. // Utility routines.
; //
; A DCI string is one that has the high bit set for every character except the last. // A DCI string is one that has the high bit set for every character except the last.
; More efficient than C or Pascal strings. // More efficient than C or Pascal strings.
; //
;def dcitos(dci, str) //def dcitos(dci, str)
; byte len, c // byte len, c
; len = 0 // len = 0
; repeat // repeat
; c = (dci).[len] // c = (dci).[len]
; len = len + 1 // len = len + 1
; (str).[len] = c & $7F // (str).[len] = c & $7F
; until !(c & $80) // until !(c & $80)
; ^str = len // ^str = len
; return len // return len
;end //end
asm dcitos asm dcitos
LDA ESTKL,X LDA ESTKL,X
STA DSTL STA DSTL
@ -517,22 +517,22 @@ asm dcitos
STY ESTKH,X STY ESTKH,X
RTS RTS
end end
;def stodci(str, dci) //def stodci(str, dci)
; byte len, c // byte len, c
; len = ^str // len = ^str
; if len == 0 // if len == 0
; return // return
; fin // fin
; c = toupper((str).[len]) & $7F // c = toupper((str).[len]) & $7F
; len = len - 1 // len = len - 1
; (dci).[len] = c // (dci).[len] = c
; while len // while len
; c = toupper((str).[len]) | $80 // c = toupper((str).[len]) | $80
; len = len - 1 // len = len - 1
; (dci).[len] = c // (dci).[len] = c
; loop // loop
; return ^str // return ^str
;end //end
asm stodci asm stodci
LDA ESTKL,X LDA ESTKL,X
STA DSTL STA DSTL
@ -572,22 +572,22 @@ TOUPR AND #$7F
+ STA ESTKL,X + STA ESTKL,X
RTS RTS
end end
; //
; Module symbols are entered into the symbol table // Module symbols are entered into the symbol table
; pre-pended with a '#' to differentiate them // pre-pended with a '#' to differentiate them
; from normal symbols. // from normal symbols.
; //
;def modtosym(mod, dci) //def modtosym(mod, dci)
; byte len, c // byte len, c
; (dci).0 = '#'|$80 // (dci).0 = '#'|$80
; len = 0 // len = 0
; repeat // repeat
; c = (mod).[len] // c = (mod).[len]
; len = len + 1 // len = len + 1
; (dci).[len] = c // (dci).[len] = c
; until !(c & $80) // until !(c & $80)
; return dci // return dci
;end //end
asm modtosym asm modtosym
LDA ESTKL+1,X LDA ESTKL+1,X
STA SRCL STA SRCL
@ -609,26 +609,26 @@ asm modtosym
BCS - BCS -
RTS RTS
end end
; //
; Lookup routines. // Lookup routines.
; //
;def lookuptbl(dci, tbl) //def lookuptbl(dci, tbl)
; word match // word match
; while ^tbl // while ^tbl
; match = dci // match = dci
; while ^tbl == ^match // while ^tbl == ^match
; if !(^tbl & $80) // if !(^tbl & $80)
; return (tbl):1 // return (tbl):1
; fin // fin
; tbl = tbl + 1 // tbl = tbl + 1
; match = match + 1 // match = match + 1
; loop // loop
; while (^tbl & $80) // while (^tbl & $80)
; tbl = tbl + 1 // tbl = tbl + 1
; loop // loop
; tbl = tbl + 3 // tbl = tbl + 3
; loop // loop
; return 0 // return 0
asm lookuptbl asm lookuptbl
LDA ESTKL,X LDA ESTKL,X
STA DSTL STA DSTL
@ -670,9 +670,9 @@ asm lookuptbl
INC DSTH INC DSTH
BCS - BCS -
end end
; //
; ProDOS routines // ProDOS routines
; //
def getpfx(path) def getpfx(path)
byte params[3] byte params[3]
@ -719,9 +719,9 @@ def read(refnum, buff, len)
perr = syscall($CA, @params) perr = syscall($CA, @params)
return params:6 return params:6
end end
; //
; Heap routines. // Heap routines.
; //
def availheap def availheap
byte fp byte fp
return @fp - heap return @fp - heap
@ -761,11 +761,11 @@ def allocalignheap(size, pow2, freeaddr)
return addr return addr
end end
def markheap def markheap
return heap; return heap//
end end
def releaseheap(newheap) def releaseheap(newheap)
heap = newheap; heap = newheap//
return @newheap - heap; return @newheap - heap//
end end
def allocxheap(size) def allocxheap(size)
word xaddr word xaddr
@ -800,9 +800,9 @@ def allocxheap(size)
fin fin
return xaddr return xaddr
end end
; //
; Symbol table routines. // Symbol table routines.
; //
def lookupsym(sym) def lookupsym(sym)
return lookuptbl(sym, symtbl) return lookuptbl(sym, symtbl)
end end
@ -817,9 +817,9 @@ def addsym(sym, addr)
lastsym = lastsym + 3 lastsym = lastsym + 3
^lastsym = 0 ^lastsym = 0
end end
; //
; Module routines. // Module routines.
; //
def lookupmod(mod) def lookupmod(mod)
byte dci[17] byte dci[17]
return lookuptbl(modtosym(mod, @dci), symtbl) return lookuptbl(modtosym(mod, @dci), symtbl)
@ -858,13 +858,13 @@ def adddef(bank, addr, deflast)
defentry = *deflast defentry = *deflast
*deflast = defentry + 5 *deflast = defentry + 5
if bank if bank
defentry=>1 = $03DC ; JSR $03DC (AUX MEM INTERP) defentry=>1 = $03DC // JSR $03DC (AUX MEM INTERP)
else else
defentry=>1 = $03D6 ; JSR $03D6 (MAIN MEM INTERP) defentry=>1 = $03D6 // JSR $03D6 (MAIN MEM INTERP)
fin fin
defentry->0 = $20 defentry->0 = $20
defentry=>3 = addr defentry=>3 = addr
defentry->5 = 0 ; NULL out next entry defentry->5 = 0 // NULL out next entry
return defentry return defentry
end end
def lookupdef(addr, deftbl) def lookupdef(addr, deftbl)
@ -883,9 +883,9 @@ def loadmod(mod)
word moddep, rld, esd, sym word moddep, rld, esd, sym
byte defbank, str[16], filename[64] byte defbank, str[16], filename[64]
byte header[128] byte header[128]
; //
; Read the RELocatable module header (first 128 bytes) // Read the RELocatable module header (first 128 bytes)
; //
dcitos(mod, @filename) dcitos(mod, @filename)
refnum = open(@filename, iobuffer) refnum = open(@filename, iobuffer)
if refnum > 0 if refnum > 0
@ -894,18 +894,18 @@ def loadmod(mod)
moddep = @header.1 moddep = @header.1
defofst = modsize defofst = modsize
init = 0 init = 0
if rdlen > 4 and header:2 == $DA7E ; DAVE = magic number :-) if rdlen > 4 and header:2 == $DA7E // DAVE = magic number :-)
; //
; This is an EXTended RELocatable (data+bytecode) module. // This is an EXTended RELocatable (data+bytecode) module.
; //
systemflags = header:4 | systemflags systemflags = header:4 | systemflags
defofst = header:6 defofst = header:6
defcnt = header:8 defcnt = header:8
init = header:10 init = header:10
moddep = @header.12 moddep = @header.12
; //
; Load module dependencies. // Load module dependencies.
; //
while ^moddep while ^moddep
if !lookupmod(moddep) if !lookupmod(moddep)
close(refnum) close(refnum)
@ -916,57 +916,57 @@ def loadmod(mod)
fin fin
moddep = moddep + dcitos(moddep, @str) moddep = moddep + dcitos(moddep, @str)
loop loop
; //
; Init def table. // Init def table.
; //
deftbl = allocheap(defcnt * 5 + 1) deftbl = allocheap(defcnt * 5 + 1)
deflast = deftbl deflast = deftbl
^deflast = 0 ^deflast = 0
if !refnum if !refnum
; //
; Reset read pointer. // Reset read pointer.
; //
refnum = open(@filename, iobuffer) refnum = open(@filename, iobuffer)
rdlen = read(refnum, @header, 128) rdlen = read(refnum, @header, 128)
fin fin
fin fin
; //
; Alloc heap space for relocated module (data + bytecode). // Alloc heap space for relocated module (data + bytecode).
; //
moddep = moddep + 1 moddep = moddep + 1
modfix = moddep - @header.2 ; Adjust to skip header modfix = moddep - @header.2 // Adjust to skip header
modsize = modsize - modfix modsize = modsize - modfix
rdlen = rdlen - modfix - 2 rdlen = rdlen - modfix - 2
modaddr = allocheap(modsize) modaddr = allocheap(modsize)
memcpy(modaddr, moddep, rdlen) memcpy(modaddr, moddep, rdlen)
; //
; Read in remainder of module into memory for fixups. // Read in remainder of module into memory for fixups.
; //
addr = modaddr; addr = modaddr//
repeat repeat
addr = addr + rdlen addr = addr + rdlen
rdlen = read(refnum, addr, 4096) rdlen = read(refnum, addr, 4096)
until rdlen <= 0 until rdlen <= 0
close(refnum) close(refnum)
; //
; Add module to symbol table. // Add module to symbol table.
; //
addmod(mod, modaddr) addmod(mod, modaddr)
; //
; Apply all fixups and symbol import/export. // Apply all fixups and symbol import/export.
; //
modfix = modaddr - modfix modfix = modaddr - modfix
bytecode = defofst + modfix - MODADDR bytecode = defofst + modfix - MODADDR
modend = modaddr + modsize modend = modaddr + modsize
rld = modend ; Re-Locatable Directory rld = modend // Re-Locatable Directory
esd = rld ; Extern+Entry Symbol Directory esd = rld // Extern+Entry Symbol Directory
while ^esd ; Scan to end of ESD while ^esd // Scan to end of ESD
esd = esd + 4 esd = esd + 4
loop loop
esd = esd + 1 esd = esd + 1
; //
; Locate bytecode defs in appropriate bank. // Locate bytecode defs in appropriate bank.
; //
if ^MACHID & $30 == $30 if ^MACHID & $30 == $30
defbank = 1 defbank = 1
defaddr = allocxheap(rld - bytecode) defaddr = allocxheap(rld - bytecode)
@ -975,58 +975,58 @@ def loadmod(mod)
defbank = 0 defbank = 0
defaddr = bytecode defaddr = bytecode
fin fin
; //
; Run through the Re-Location Dictionary. // Run through the Re-Location Dictionary.
; //
while ^rld while ^rld
if ^rld == $02 if ^rld == $02
; //
; This is a bytcode def entry - add it to the def directory. // This is a bytcode def entry - add it to the def directory.
; //
adddef(defbank, rld=>1 - defofst + defaddr, @deflast) adddef(defbank, rld=>1 - defofst + defaddr, @deflast)
else else
addr = rld=>1 + modfix addr = rld=>1 + modfix
if uword_isge(addr, modaddr) ; Skip fixups to header if uword_isge(addr, modaddr) // Skip fixups to header
if ^rld & $80 ; WORD sized fixup. if ^rld & $80 // WORD sized fixup.
fixup = *addr fixup = *addr
else ; BYTE sized fixup. else // BYTE sized fixup.
fixup = ^addr fixup = ^addr
fin fin
if ^rld & $10 ; EXTERN reference. if ^rld & $10 // EXTERN reference.
fixup = fixup + lookupextern(esd, rld->3) fixup = fixup + lookupextern(esd, rld->3)
else ; INTERN fixup. else // INTERN fixup.
fixup = fixup + modfix - MODADDR fixup = fixup + modfix - MODADDR
if uword_isge(fixup, bytecode) if uword_isge(fixup, bytecode)
; //
; Bytecode address - replace with call def directory. // Bytecode address - replace with call def directory.
; //
fixup = lookupdef(fixup - bytecode + defaddr, deftbl) fixup = lookupdef(fixup - bytecode + defaddr, deftbl)
fin fin
fin fin
if ^rld & $80 ; WORD sized fixup. if ^rld & $80 // WORD sized fixup.
*addr = fixup *addr = fixup
else ; BYTE sized fixup. else // BYTE sized fixup.
^addr = fixup ^addr = fixup
fin fin
fin fin
fin fin
rld = rld + 4 rld = rld + 4
loop loop
; //
; Run through the External/Entry Symbol Directory. // Run through the External/Entry Symbol Directory.
; //
while ^esd while ^esd
sym = esd sym = esd
esd = esd + dcitos(esd, @str) esd = esd + dcitos(esd, @str)
if ^esd & $08 if ^esd & $08
; //
; EXPORT symbol - add it to the global symbol table. // EXPORT symbol - add it to the global symbol table.
; //
addr = esd=>1 + modfix - MODADDR addr = esd=>1 + modfix - MODADDR
if uword_isge(addr, bytecode) if uword_isge(addr, bytecode)
; //
; Use the def directory address for bytecode. // Use the def directory address for bytecode.
; //
addr = lookupdef(addr - bytecode + defaddr, deftbl) addr = lookupdef(addr - bytecode + defaddr, deftbl)
fin fin
addsym(sym, addr) addsym(sym, addr)
@ -1034,18 +1034,18 @@ def loadmod(mod)
esd = esd + 3 esd = esd + 3
loop loop
if defbank if defbank
; //
; Move bytecode to AUX bank. // Move bytecode to AUX bank.
; //
memxcpy(defaddr, bytecode, modsize - (bytecode - modaddr)) memxcpy(defaddr, bytecode, modsize - (bytecode - modaddr))
fin fin
fin fin
if perr if perr
return -perr return -perr
fin fin
; //
; Call init routine if it exists. // Call init routine if it exists.
; //
if init if init
fixup = adddef(defbank, init - defofst + defaddr, @deflast)() fixup = adddef(defbank, init - defofst + defaddr, @deflast)()
if defbank if defbank
@ -1056,15 +1056,15 @@ def loadmod(mod)
else else
fixup = 0 fixup = 0
fin fin
; //
; Free up the end-of-module in main memory. // Free up the end-of-module in main memory.
; //
releaseheap(modend) releaseheap(modend)
return fixup return fixup
end end
; //
; Command mode // Command mode
; //
def volumes def volumes
byte params[4] byte params[4]
word strbuf word strbuf
@ -1120,7 +1120,7 @@ def catalog(optpath)
len = type & $0F len = type & $0F
^entry = len ^entry = len
prstr(entry) prstr(entry)
if type & $F0 == $D0 ; Is it a directory? if type & $F0 == $D0 // Is it a directory?
cout('/') cout('/')
len = len + 1 len = len + 1
elsif entry->$10 == $FF elsif entry->$10 == $FF
@ -1186,14 +1186,14 @@ def parsecmd(strptr)
return cmd return cmd
end end
def resetmemfiles def resetmemfiles
; //
; Close all files // Close all files
; //
^$BFD8 = 0 ^$BFD8 = 0
close(0) close(0)
; //
; Set memory bitmap // Set memory bitmap
; //
memset($BF58, 24, 0) memset($BF58, 24, 0)
^$BF58 = $CF ^$BF58 = $CF
^$BF6F = $01 ^$BF6F = $01
@ -1240,13 +1240,13 @@ def execmod(modfile)
heap = saveheap heap = saveheap
fin fin
end end
; //
; Get heap start. // Get heap start.
; //
heap = *freemem heap = *freemem
; //
; Init symbol table. // Init symbol table.
; //
stodci(@stdlibstr, heap) stodci(@stdlibstr, heap)
addmod(heap, @version) addmod(heap, @version)
while *stdlibsym while *stdlibsym
@ -1254,15 +1254,15 @@ while *stdlibsym
addsym(heap, stdlibsym=>2) addsym(heap, stdlibsym=>2)
stdlibsym = stdlibsym + 4 stdlibsym = stdlibsym + 4
loop loop
; //
; Try to run autorun module. // Try to run autorun module.
; //
resetmemfiles() resetmemfiles()
execmod(@autorun) execmod(@autorun)
perr = 0 perr = 0
; //
; Print some startup info. // Print some startup info.
; //
prstr(@verstr) prstr(@verstr)
prbyte(version.1) prbyte(version.1)
cout('.') cout('.')

View File

@ -1,24 +1,24 @@
const membank = $FFEF const membank = $FFEF
const MODADDR = $1000 const MODADDR = $1000
; //
; SOS flags // SOS flags
; //
const O_READ = 1 const O_READ = 1
const O_WRITE = 2 const O_WRITE = 2
const O_READ_WRITE = 3 const O_READ_WRITE = 3
; //
; Pedefined functions. // Pedefined functions.
; //
predef crout, cout, prstr, cin, rdstr predef crout, cout, prstr, cin, rdstr
predef syscall, call predef syscall, call
predef markheap, allocheap, allocalignheap, releaseheap, availheap predef markheap, allocheap, allocalignheap, releaseheap, availheap
predef memset, memcpy predef memset, memcpy
predef uword_isgt, uword_isge, uword_islt, uword_isle predef uword_isgt, uword_isge, uword_islt, uword_isle
predef loadmod, execmod, lookupstrmod predef loadmod, execmod, lookupstrmod
; //
; System variables. // System variables.
; //
word version = $0010 ; 00.10 word version = $0010 // 00.10
word systemflags = 0 word systemflags = 0
byte refcons = 0 byte refcons = 0
byte devcons = 0 byte devcons = 0
@ -28,13 +28,13 @@ byte modseg[15]
word symtbl, lastsym word symtbl, lastsym
byte perr, terr, lerr byte perr, terr, lerr
word cmdptr word cmdptr
; //
; Exported Machine ID. // Exported Machine ID.
; //
byte machid = $F2 ; Apple ///, 80 columns byte machid = $F2 // Apple ///, 80 columns
; //
; Standard Library exported functions. // Standard Library exported functions.
; //
byte stdlibstr[] = "STDLIB" byte stdlibstr[] = "STDLIB"
byte machidstr[] = "MACHID" byte machidstr[] = "MACHID"
byte sysstr[] = "SYSCALL" byte sysstr[] = "SYSCALL"
@ -81,9 +81,9 @@ word = @modadrstr, @lookupstrmod
word = @machidstr, @machid word = @machidstr, @machid
word = 0 word = 0
word stdlibsym = @exports word stdlibsym = @exports
; //
; String pool. // String pool.
; //
byte console[] = ".CONSOLE" byte console[] = ".CONSOLE"
byte autorun[] = "AUTORUN" byte autorun[] = "AUTORUN"
byte verstr[] = "PLASMA " byte verstr[] = "PLASMA "
@ -95,10 +95,10 @@ byte devtovol[] = " => /"
byte prefix[128] = "" byte prefix[128] = ""
byte textmode[] = 16, 0, 15 byte textmode[] = 16, 0, 15
byte hexchar[] = '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' byte hexchar[] = '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
; //
; CALL SOS // CALL SOS
; SYSCALL(CMD, PARAMS) // SYSCALL(CMD, PARAMS)
; //
asm syscall asm syscall
LDA ESTKL,X LDA ESTKL,X
LDY ESTKH,X LDY ESTKH,X
@ -115,10 +115,10 @@ PARAMS !WORD 0000
STY ESTKH,X STY ESTKH,X
RTS RTS
end end
; //
; CALL 6502 ROUTINE // CALL 6502 ROUTINE
; CALL(AREG, XREG, YREG, STATUS, ADDR) // CALL(AREG, XREG, YREG, STATUS, ADDR)
; //
asm call asm call
REGVALS = SRC REGVALS = SRC
PHP PHP
@ -157,11 +157,11 @@ REGVALS = SRC
RTS RTS
JMPTMP JMP (TMP) JMPTMP JMP (TMP)
end end
; //
; SET MEMORY TO VALUE // SET MEMORY TO VALUE
; MEMSET(ADDR, SIZE, VALUE) // MEMSET(ADDR, SIZE, VALUE)
; With optimizations from Peter Ferrie // With optimizations from Peter Ferrie
; //
asm memset asm memset
LDY #$00 LDY #$00
LDA ESTKL+2,X LDA ESTKL+2,X
@ -188,10 +188,10 @@ SETMEX INX
INX INX
RTS RTS
end end
; //
; COPY MEMORY // COPY MEMORY
; MEMCPY(DSTADDR, SRCADDR, SIZE) // MEMCPY(DSTADDR, SRCADDR, SIZE)
; //
asm memcpy asm memcpy
INX INX
INX INX
@ -261,11 +261,11 @@ REVCPYLP LDA (SRC),Y
BNE REVCPYLP BNE REVCPYLP
CPYMEX RTS CPYMEX RTS
end end
; //
; COPY FROM MAIN MEM TO EXT MEM. // COPY FROM MAIN MEM TO EXT MEM.
; //
; MEMXCPY(DSTSEG, SRC, SIZE) // MEMXCPY(DSTSEG, SRC, SIZE)
; //
asm memxcpy asm memxcpy
LDA ESTKL,X LDA ESTKL,X
ORA ESTKH,X ORA ESTKH,X
@ -301,11 +301,11 @@ CPYXMEX INX
INX INX
RTS RTS
end end
; //
; POKE BYTE VAL INTO EXT MEM. // POKE BYTE VAL INTO EXT MEM.
; //
; XPOKEB(SEG, DST, BYTEVAL) // XPOKEB(SEG, DST, BYTEVAL)
; //
asm xpokeb asm xpokeb
LDA ESTKL+1,X LDA ESTKL+1,X
STA DSTL STA DSTL
@ -325,9 +325,9 @@ asm xpokeb
INX INX
RTS RTS
end end
; //
; Unsigned word comparisons. // Unsigned word comparisons.
; //
asm uword_isge asm uword_isge
LDY #$00 LDY #$00
LDA ESTKL+1,X LDA ESTKL+1,X
@ -378,9 +378,9 @@ asm uword_islt
INX INX
RTS RTS
end end
; //
; Addresses of internal routines. // Addresses of internal routines.
; //
asm interp asm interp
DEX DEX
LDA #<XINTERP LDA #<XINTERP
@ -389,21 +389,21 @@ asm interp
STA ESTKH,X STA ESTKH,X
RTS RTS
end end
; //
; A DCI string is one that has the high bit set for every character except the last. // A DCI string is one that has the high bit set for every character except the last.
; More efficient than C or Pascal strings. // More efficient than C or Pascal strings.
; //
;def dcitos(dci, str) //def dcitos(dci, str)
; byte len, c // byte len, c
; len = 0 // len = 0
; repeat // repeat
; c = (dci).[len] // c = (dci).[len]
; len = len + 1 // len = len + 1
; (str).[len] = c & $7F // (str).[len] = c & $7F
; until !(c & $80) // until !(c & $80)
; ^str = len // ^str = len
; return len // return len
;end //end
asm dcitos asm dcitos
LDA ESTKL,X LDA ESTKL,X
STA DSTL STA DSTL
@ -428,22 +428,22 @@ asm dcitos
STY ESTKH,X STY ESTKH,X
RTS RTS
end end
;def stodci(str, dci) //def stodci(str, dci)
; byte len, c // byte len, c
; len = ^str // len = ^str
; if len == 0 // if len == 0
; return // return
; fin // fin
; c = toupper((str).[len]) & $7F // c = toupper((str).[len]) & $7F
; len = len - 1 // len = len - 1
; (dci).[len] = c // (dci).[len] = c
; while len // while len
; c = toupper((str).[len]) | $80 // c = toupper((str).[len]) | $80
; len = len - 1 // len = len - 1
; (dci).[len] = c // (dci).[len] = c
; loop // loop
; return ^str // return ^str
;end //end
asm stodci asm stodci
LDA ESTKL,X LDA ESTKL,X
STA DSTL STA DSTL
@ -483,22 +483,22 @@ TOUPR AND #$7F
+ STA ESTKL,X + STA ESTKL,X
RTS RTS
end end
; //
; Module symbols are entered into the symbol table // Module symbols are entered into the symbol table
; pre-pended with a '#' to differentiate them // pre-pended with a '#' to differentiate them
; from normal symbols. // from normal symbols.
; //
;def modtosym(mod, dci) //def modtosym(mod, dci)
; byte len, c // byte len, c
; (dci).0 = '#'|$80 // (dci).0 = '#'|$80
; len = 0 // len = 0
; repeat // repeat
; c = (mod).[len] // c = (mod).[len]
; len = len + 1 // len = len + 1
; (dci).[len] = c // (dci).[len] = c
; until !(c & $80) // until !(c & $80)
; return dci // return dci
;end //end
asm modtosym asm modtosym
LDA ESTKL+1,X LDA ESTKL+1,X
STA SRCL STA SRCL
@ -520,26 +520,26 @@ asm modtosym
BCS - BCS -
RTS RTS
end end
; //
; Lookup routines. // Lookup routines.
; //
;def lookuptbl(dci, tbl) //def lookuptbl(dci, tbl)
; word match // word match
; while ^tbl // while ^tbl
; match = dci // match = dci
; while ^tbl == ^match // while ^tbl == ^match
; if !(^tbl & $80) // if !(^tbl & $80)
; return (tbl):1 // return (tbl):1
; fin // fin
; tbl = tbl + 1 // tbl = tbl + 1
; match = match + 1 // match = match + 1
; loop // loop
; while (^tbl & $80) // while (^tbl & $80)
; tbl = tbl + 1 // tbl = tbl + 1
; loop // loop
; tbl = tbl + 3 // tbl = tbl + 3
; loop // loop
; return 0 // return 0
asm lookuptbl asm lookuptbl
LDY #$00 LDY #$00
STY DSTL STY DSTL
@ -588,10 +588,10 @@ asm lookuptbl
INC DSTH INC DSTH
BCS - BCS -
end end
; //
; SOS routines // SOS routines
; FILE I/O // FILE I/O
; //
def getpfx(path) def getpfx(path)
byte params[4] byte params[4]
@ -663,9 +663,9 @@ def write(refnum, buff, len)
perr = syscall($CB, @params) perr = syscall($CB, @params)
return perr return perr
end end
; //
; DEVICE I/O // DEVICE I/O
; //
def dev_control(devnum, code, list) def dev_control(devnum, code, list)
byte params[5] byte params[5]
@ -696,9 +696,9 @@ def dev_info(devnum, name, list, listlen)
perr = syscall($85, @params) perr = syscall($85, @params)
return perr return perr
end end
; //
; MEMORY CALLS // MEMORY CALLS
; //
def seg_request(base, limit, id) def seg_request(base, limit, id)
byte params[7] byte params[7]
@ -733,9 +733,9 @@ def seg_release(segnum)
perr = syscall($45, @params) perr = syscall($45, @params)
return perr return perr
end end
; //
; Other SOS calls. // Other SOS calls.
; //
def quit def quit
byte params[1] byte params[1]
@ -744,9 +744,9 @@ def quit
perr = syscall($65, @params) perr = syscall($65, @params)
end end
; //
; CONSOLE I/O // CONSOLE I/O
; //
def init_cons def init_cons
byte nlmode[2] byte nlmode[2]
if !refcons if !refcons
@ -797,9 +797,9 @@ def prword(v)
prbyte(v >> 8) prbyte(v >> 8)
return prbyte(v) return prbyte(v)
end end
; //
; Heap routines. // Heap routines.
; //
def availheap def availheap
byte fp byte fp
return @fp - heap return @fp - heap
@ -827,15 +827,15 @@ def allocalignheap(size, pow2, freeaddr)
return addr return addr
end end
def markheap def markheap
return heap; return heap//
end end
def releaseheap(newheap) def releaseheap(newheap)
heap = newheap; heap = newheap//
return @newheap - heap; return @newheap - heap//
end end
; //
; Symbol table routines. // Symbol table routines.
; //
def lookupsym(sym) def lookupsym(sym)
return lookuptbl(sym, symtbl) return lookuptbl(sym, symtbl)
end end
@ -851,9 +851,9 @@ def addsym(sym, addr)
xpokeb(symtbl.0, lastsym + 3, 0) xpokeb(symtbl.0, lastsym + 3, 0)
lastsym = lastsym + 3 lastsym = lastsym + 3
end end
; //
; Module routines. // Module routines.
; //
def lookupmod(mod) def lookupmod(mod)
byte dci[17] byte dci[17]
return lookuptbl(modtosym(mod, @dci), symtbl) return lookuptbl(modtosym(mod, @dci), symtbl)
@ -894,7 +894,7 @@ def adddef(ext, addr, deflast)
defentry->0 = $20 defentry->0 = $20
defentry=>1 = interp defentry=>1 = interp
defentry=>3 = addr defentry=>3 = addr
defentry=>5 = ext ; ext is byte, so this nulls out next entry defentry=>5 = ext // ext is byte, so this nulls out next entry
return defentry return defentry
end end
def lookupdef(addr, deftbl) def lookupdef(addr, deftbl)
@ -914,9 +914,9 @@ def loadmod(mod)
byte defext, str[16], filename[33] byte defext, str[16], filename[33]
byte header[128] byte header[128]
lerr = 0 lerr = 0
; //
; Read the RELocatable module header (first 128 bytes) // Read the RELocatable module header (first 128 bytes)
; //
dcitos(mod, @filename) dcitos(mod, @filename)
refnum = open(@filename, O_READ) refnum = open(@filename, O_READ)
if refnum > 0 if refnum > 0
@ -925,18 +925,18 @@ def loadmod(mod)
moddep = @header.1 moddep = @header.1
defofst = modsize defofst = modsize
init = 0 init = 0
if rdlen > 4 and header:2 == $DA7E ; DAVE = magic number :-) if rdlen > 4 and header:2 == $DA7E // DAVE = magic number :-)
; //
; This is an EXTended RELocatable (data+bytecode) module. // This is an EXTended RELocatable (data+bytecode) module.
; //
systemflags = header:4 | systemflags systemflags = header:4 | systemflags
defofst = header:6 defofst = header:6
defcnt = header:8 defcnt = header:8
init = header:10 init = header:10
moddep = @header.12 moddep = @header.12
; //
; Load module dependencies. // Load module dependencies.
; //
while ^moddep while ^moddep
if !lookupmod(moddep) if !lookupmod(moddep)
close(refnum) close(refnum)
@ -947,57 +947,57 @@ def loadmod(mod)
fin fin
moddep = moddep + dcitos(moddep, @str) moddep = moddep + dcitos(moddep, @str)
loop loop
; //
; Init def table. // Init def table.
; //
deftbl = allocheap(defcnt * 6 + 1) deftbl = allocheap(defcnt * 6 + 1)
deflast = deftbl deflast = deftbl
^deflast = 0 ^deflast = 0
if !refnum if !refnum
; //
; Reset read pointer. // Reset read pointer.
; //
refnum = open(@filename, O_READ) refnum = open(@filename, O_READ)
rdlen = read(refnum, @header, 128) rdlen = read(refnum, @header, 128)
fin fin
fin fin
; //
; Alloc heap space for relocated module (data + bytecode). // Alloc heap space for relocated module (data + bytecode).
; //
moddep = moddep + 1 moddep = moddep + 1
modfix = moddep - @header.2 ; Adjust to skip header modfix = moddep - @header.2 // Adjust to skip header
modsize = modsize - modfix modsize = modsize - modfix
rdlen = rdlen - modfix - 2 rdlen = rdlen - modfix - 2
modaddr = allocheap(modsize) modaddr = allocheap(modsize)
memcpy(modaddr, moddep, rdlen) memcpy(modaddr, moddep, rdlen)
; //
; Read in remainder of module into memory for fixups. // Read in remainder of module into memory for fixups.
; //
addr = modaddr; addr = modaddr//
repeat repeat
addr = addr + rdlen addr = addr + rdlen
rdlen = read(refnum, addr, 4096) rdlen = read(refnum, addr, 4096)
until rdlen <= 0 until rdlen <= 0
close(refnum) close(refnum)
; //
; Add module to symbol table. // Add module to symbol table.
; //
addmod(mod, modaddr) addmod(mod, modaddr)
; //
; Apply all fixups and symbol import/export. // Apply all fixups and symbol import/export.
; //
modfix = modaddr - modfix modfix = modaddr - modfix
bytecode = defofst + modfix - MODADDR bytecode = defofst + modfix - MODADDR
modend = modaddr + modsize modend = modaddr + modsize
rld = modend ; Re-Locatable Directory rld = modend // Re-Locatable Directory
esd = rld ; Extern+Entry Symbol Directory esd = rld // Extern+Entry Symbol Directory
while ^esd ; Scan to end of ESD while ^esd // Scan to end of ESD
esd = esd + 4 esd = esd + 4
loop loop
esd = esd + 1 esd = esd + 1
; //
; Locate bytecode defs in allocated segment. // Locate bytecode defs in allocated segment.
; //
modseg[modid] = seg_find($00, @codeseg, @defaddr, (rld - bytecode + 255) >> 8, modid + $12) modseg[modid] = seg_find($00, @codeseg, @defaddr, (rld - bytecode + 255) >> 8, modid + $12)
if perr if perr
return -perr return -perr
@ -1005,58 +1005,58 @@ def loadmod(mod)
modid = modid + 1 modid = modid + 1
defext = (codeseg.0 | $80) - 1 defext = (codeseg.0 | $80) - 1
defaddr = (codeseg & $FF00) + $6000 defaddr = (codeseg & $FF00) + $6000
; //
; Run through the Re-Location Dictionary. // Run through the Re-Location Dictionary.
; //
while ^rld while ^rld
if ^rld == $02 if ^rld == $02
; //
; This is a bytcode def entry - add it to the def directory. // This is a bytcode def entry - add it to the def directory.
; //
adddef(defext, rld=>1 - defofst + defaddr, @deflast) adddef(defext, rld=>1 - defofst + defaddr, @deflast)
else else
addr = rld=>1 + modfix addr = rld=>1 + modfix
if uword_isge(addr, modaddr) ; Skip fixups to header if uword_isge(addr, modaddr) // Skip fixups to header
if ^rld & $80 ; WORD sized fixup. if ^rld & $80 // WORD sized fixup.
fixup = *addr fixup = *addr
else ; BYTE sized fixup. else // BYTE sized fixup.
fixup = ^addr fixup = ^addr
fin fin
if ^rld & $10 ; EXTERN reference. if ^rld & $10 // EXTERN reference.
fixup = fixup + lookupextern(esd, rld->3) fixup = fixup + lookupextern(esd, rld->3)
else ; INTERN fixup. else // INTERN fixup.
fixup = fixup + modfix - MODADDR fixup = fixup + modfix - MODADDR
if uword_isge(fixup, bytecode) if uword_isge(fixup, bytecode)
; //
; Bytecode address - replace with call def directory. // Bytecode address - replace with call def directory.
; //
fixup = lookupdef(fixup - bytecode + defaddr, deftbl) fixup = lookupdef(fixup - bytecode + defaddr, deftbl)
fin fin
fin fin
if ^rld & $80 ; WORD sized fixup. if ^rld & $80 // WORD sized fixup.
*addr = fixup *addr = fixup
else ; BYTE sized fixup. else // BYTE sized fixup.
^addr = fixup ^addr = fixup
fin fin
fin fin
fin fin
rld = rld + 4 rld = rld + 4
loop loop
; //
; Run through the External/Entry Symbol Directory. // Run through the External/Entry Symbol Directory.
; //
while ^esd while ^esd
sym = esd sym = esd
esd = esd + dcitos(esd, @str) esd = esd + dcitos(esd, @str)
if ^esd & $08 if ^esd & $08
; //
; EXPORT symbol - add it to the global symbol table. // EXPORT symbol - add it to the global symbol table.
; //
addr = esd=>1 + modfix - MODADDR addr = esd=>1 + modfix - MODADDR
if uword_isge(addr, bytecode) if uword_isge(addr, bytecode)
; //
; Use the def directory address for bytecode. // Use the def directory address for bytecode.
; //
addr = lookupdef(addr - bytecode + defaddr, deftbl) addr = lookupdef(addr - bytecode + defaddr, deftbl)
fin fin
addsym(sym, addr) addsym(sym, addr)
@ -1064,14 +1064,14 @@ def loadmod(mod)
esd = esd + 3 esd = esd + 3
loop loop
if defext if defext
; //
; Copy bytecode to code segment. // Copy bytecode to code segment.
; //
memxcpy(codeseg, bytecode, modsize - (bytecode - modaddr)) memxcpy(codeseg, bytecode, modsize - (bytecode - modaddr))
fin fin
; //
; Free up end-of-module main memory. // Free up end-of-module main memory.
; //
releaseheap(bytecode) releaseheap(bytecode)
else else
return -perr return -perr
@ -1079,9 +1079,9 @@ def loadmod(mod)
if lerr if lerr
return -lerr return -lerr
fin fin
; //
; Call init routine if it exists. // Call init routine if it exists.
; //
if init if init
fixup = adddef(defext, init - defofst + defaddr, @deflast)() fixup = adddef(defext, init - defofst + defaddr, @deflast)()
else else
@ -1089,9 +1089,9 @@ def loadmod(mod)
fin fin
return fixup return fixup
end end
; //
; Command mode // Command mode
; //
def volumes def volumes
byte info[11] byte info[11]
byte devname[17] byte devname[17]
@ -1147,7 +1147,7 @@ def catalog(optpath)
len = type & $0F len = type & $0F
^entry = len ^entry = len
prstr(entry) prstr(entry)
if type & $F0 == $D0 ; Is it a directory? if type & $F0 == $D0 // Is it a directory?
cout('/') cout('/')
len = len + 1 len = len + 1
elsif entry->$10 == $FF elsif entry->$10 == $FF
@ -1231,13 +1231,13 @@ def execmod(modfile)
loop loop
fin fin
end end
; //
; Init console. // Init console.
; //
init_cons init_cons
; //
; Init 2K symbol table. // Init 2K symbol table.
; //
seg_find($00, @symtbl, @lastsym, $08, $11) seg_find($00, @symtbl, @lastsym, $08, $11)
lastsym = symtbl & $FF00 lastsym = symtbl & $FF00
xpokeb(symtbl.0, lastsym, 0) xpokeb(symtbl.0, lastsym, 0)
@ -1248,14 +1248,14 @@ while *stdlibsym
addsym(heap, stdlibsym=>2) addsym(heap, stdlibsym=>2)
stdlibsym = stdlibsym + 4 stdlibsym = stdlibsym + 4
loop loop
; //
; Try to run autorun module. // Try to run autorun module.
; //
execmod(@autorun) execmod(@autorun)
perr = 0 perr = 0
; //
; Print some startup info. // Print some startup info.
; //
prstr(@verstr) prstr(@verstr)
prbyte(version.1) prbyte(version.1)
cout('.') cout('.')
@ -1264,9 +1264,9 @@ crout
prstr(@freestr) prstr(@freestr)
prword(availheap) prword(availheap)
crout crout
; //
; Handle commands. // Handle commands.
; //
while 1 while 1
prstr(getpfx(@prefix)) prstr(getpfx(@prefix))
cmdptr = rdstr($BA) cmdptr = rdstr($BA)