mirror of
https://github.com/dschmenk/PLASMA.git
synced 2025-02-20 17:29:11 +00:00
Change comment symbol to '//' and allow multiple statements per line
with ';'
This commit is contained in:
parent
b3e335eeb5
commit
f8b694d1ca
@ -6,9 +6,9 @@ import stdlib
|
||||
predef isugt, isuge, isult, isule
|
||||
predef modload, modexec, modaddr
|
||||
word MACHID, sysvars
|
||||
;
|
||||
; System flags: memory allocator screen holes.
|
||||
;
|
||||
//
|
||||
// System flags: memory allocator screen holes.
|
||||
//
|
||||
const restxt1 = $0001
|
||||
const restxt2 = $0002
|
||||
const reshgr1 = $0004
|
||||
|
@ -2,16 +2,16 @@ import STDLIB
|
||||
predef syscall, call, memset, getc, putc, puts, modaddr
|
||||
byte MACHID
|
||||
end
|
||||
;
|
||||
; Handy constants.
|
||||
;
|
||||
//
|
||||
// Handy constants.
|
||||
//
|
||||
const FALSE = 0
|
||||
const TRUE = !FALSE
|
||||
const FULLMODE = 0
|
||||
const MIXMODE = 1
|
||||
;
|
||||
; Apple II hardware constants.
|
||||
;
|
||||
//
|
||||
// Apple II hardware constants.
|
||||
//
|
||||
const speaker = $C030
|
||||
const showgraphics = $C050
|
||||
const showtext = $C051
|
||||
@ -27,45 +27,45 @@ const hgr1 = $2000
|
||||
const hgr2 = $4000
|
||||
const page1 = 0
|
||||
const page2 = 1
|
||||
;
|
||||
; Predefined functions.
|
||||
;
|
||||
//
|
||||
// Predefined functions.
|
||||
//
|
||||
predef a2reset,a2keypressed,a2home,a2gotoxy,a2viewport,a2texttype
|
||||
predef a2textmode,a2writeint,a2writeln
|
||||
predef a2grmode,grcolor,grplot
|
||||
;
|
||||
; String pool.
|
||||
;
|
||||
//
|
||||
// String pool.
|
||||
//
|
||||
byte stdlib[] = "STDLIB"
|
||||
;
|
||||
; Screen row address arrays.
|
||||
;
|
||||
//
|
||||
// Screen row address arrays.
|
||||
//
|
||||
word txt1scrn[] = $0400,$0480,$0500,$0580,$0600,$0680,$0700,$0780
|
||||
word = $0428,$04A8,$0528,$05A8,$0628,$06A8,$0728,$07A8
|
||||
word = $0450,$04D0,$0550,$05D0,$0650,$06D0,$0750,$07D0
|
||||
word txt2scrn[] = $0800,$0880,$0900,$0980,$0A00,$0A80,$0B00,$0B80
|
||||
word = $0828,$08A8,$0928,$09A8,$0A28,$0AA8,$0B28,$0BA8
|
||||
word = $0850,$08D0,$0950,$09D0,$0A50,$0AD0,$0B50,$0BD0
|
||||
;
|
||||
; Text screen parameters.
|
||||
;
|
||||
//
|
||||
// Text screen parameters.
|
||||
//
|
||||
byte textcols = 40
|
||||
byte curshpos = 0
|
||||
byte cursvpos = 0
|
||||
;
|
||||
; Apple 3 console codes.
|
||||
;
|
||||
//
|
||||
// Apple 3 console codes.
|
||||
//
|
||||
byte textbwmode[] = 2, 16, 0
|
||||
byte textclrmode[] = 2, 16, 1
|
||||
byte grcharset[] = 1, 0, $7F, $7F, $7F, $7F, $00, $00, $00, $00
|
||||
byte devcons
|
||||
;
|
||||
; Exported function table.
|
||||
;
|
||||
//
|
||||
// Exported function table.
|
||||
//
|
||||
export word conio[]
|
||||
;
|
||||
; Function pointers.
|
||||
;
|
||||
//
|
||||
// Function pointers.
|
||||
//
|
||||
word = @a2reset
|
||||
word = @a2keypressed
|
||||
word = @a2home
|
||||
@ -76,15 +76,15 @@ word = @a2textmode
|
||||
word = @a2grmode
|
||||
word = @grcolor
|
||||
word = @grplot
|
||||
;
|
||||
; Native routines.
|
||||
;
|
||||
//
|
||||
// Native routines.
|
||||
//
|
||||
asm equates
|
||||
!SOURCE "vmsrc/plvmzp.inc"
|
||||
end
|
||||
;
|
||||
; def grscrn(rowaddrs)
|
||||
;
|
||||
//
|
||||
// def grscrn(rowaddrs)
|
||||
//
|
||||
asm grscrn
|
||||
GRSCRN = $26
|
||||
GRSCRNL = GRSCRN
|
||||
@ -95,9 +95,9 @@ GRSCRNH = GRSCRNL+1
|
||||
STA GRSCRNH
|
||||
RTS
|
||||
end
|
||||
;
|
||||
; def grcolor(color)
|
||||
;
|
||||
//
|
||||
// def grcolor(color)
|
||||
//
|
||||
asm grcolor
|
||||
GRCLR = $30
|
||||
LDA #$0F
|
||||
@ -111,9 +111,9 @@ GRCLR = $30
|
||||
STA GRCLR
|
||||
RTS
|
||||
end
|
||||
;
|
||||
; def grplot(x, y)
|
||||
;
|
||||
//
|
||||
// def grplot(x, y)
|
||||
//
|
||||
asm grplot
|
||||
STY IPY
|
||||
LDA ESTKL,X
|
||||
@ -142,9 +142,9 @@ asm grplot
|
||||
INX
|
||||
RTS
|
||||
end
|
||||
;
|
||||
; Apple 1 routines.
|
||||
;
|
||||
//
|
||||
// Apple 1 routines.
|
||||
//
|
||||
def a1keypressed
|
||||
return ^$D011 >= 128
|
||||
end
|
||||
@ -164,18 +164,18 @@ end
|
||||
def a1textmode(columns)
|
||||
end
|
||||
def a1grmode(mix)
|
||||
return 0 ; not supported
|
||||
return 0 // not supported
|
||||
end
|
||||
;
|
||||
; Apple II routines.
|
||||
;
|
||||
//
|
||||
// Apple II routines.
|
||||
//
|
||||
def a2keypressed
|
||||
return ^keyboard >= 128
|
||||
end
|
||||
def a2home
|
||||
curshpos = 0
|
||||
cursypos = 0
|
||||
return call($FC58, 0, 0, 0, 0) ;home()
|
||||
return call($FC58, 0, 0, 0, 0) // home()
|
||||
end
|
||||
def a2gotoxy(x, y)
|
||||
curshpos = x
|
||||
@ -202,21 +202,21 @@ def a2writeln(string, start, fill)
|
||||
|
||||
end
|
||||
def a2textmode(columns)
|
||||
call($FB39, 0, 0, 0, 0) ;textmode()
|
||||
call($FB39, 0, 0, 0, 0) // textmode()
|
||||
return a2home
|
||||
end
|
||||
def a2grmode(mix)
|
||||
call($FB2F, 0, 0, 0, 0) ;initmode()
|
||||
call($FB40, 0, 0, 0, 0) ;grmode()
|
||||
call($FB2F, 0, 0, 0, 0) // initmode()
|
||||
call($FB40, 0, 0, 0, 0) // grmode()
|
||||
if !mix
|
||||
^showfull
|
||||
fin
|
||||
a2home
|
||||
return grscrn(@txt1scrn) ; point to lo-res screen
|
||||
return grscrn(@txt1scrn) // point to lo-res screen
|
||||
end
|
||||
;
|
||||
; Apple III routines.
|
||||
;
|
||||
//
|
||||
// Apple III routines.
|
||||
//
|
||||
def dev_control(devnum, code, list)
|
||||
byte params[5]
|
||||
|
||||
@ -255,15 +255,15 @@ def a3gotoxy(x, y)
|
||||
end
|
||||
def a3viewport(left, top, width, height)
|
||||
if !width or !height
|
||||
;
|
||||
; Reset the full-screen viewport
|
||||
;
|
||||
//
|
||||
// Reset the full-screen viewport
|
||||
//
|
||||
left = 0
|
||||
top = 0
|
||||
width = textwidth
|
||||
height = 24
|
||||
fin
|
||||
putc(1) ; Reset viewport
|
||||
putc(1) // Reset viewport
|
||||
putc(26)
|
||||
putc(left)
|
||||
putc(top)
|
||||
@ -297,16 +297,16 @@ def a3grmode(mix)
|
||||
dev_control(devcons, 17, @grcharset)
|
||||
a3viewport(0, 20, 40, 4)
|
||||
for i = 0 to mix
|
||||
memset(txt1scrn[i], 40, $0000) ; text screen
|
||||
memset(txt2scrn[i], 40, $0000) ; color screen
|
||||
memset(txt1scrn[i], 40, $0000) // text screen
|
||||
memset(txt2scrn[i], 40, $0000) // color screen
|
||||
next
|
||||
return grscrn(@txt2scrn) ; point to color screen
|
||||
return grscrn(@txt2scrn) // point to color screen
|
||||
end
|
||||
;
|
||||
; Machine specific initialization.
|
||||
;
|
||||
//
|
||||
// Machine specific initialization.
|
||||
//
|
||||
when MACHID & $C8
|
||||
is $08 ; Apple 1
|
||||
is $08 // Apple 1
|
||||
conio:reset = @a1reset
|
||||
conio:keypressed = @a1keypressed
|
||||
conio:home = @a1home
|
||||
@ -315,7 +315,7 @@ when MACHID & $C8
|
||||
conio:texttype = @a1texttype
|
||||
conio:textmode = @a1textmode
|
||||
conio:grmixmode = @a1grmixmode
|
||||
is $C0 ; Apple ///
|
||||
is $C0 // Apple ///
|
||||
conio:reset = @a3reset
|
||||
conio:keypressed = @a3keypressed
|
||||
conio:home = @a3home
|
||||
@ -324,6 +324,6 @@ when MACHID & $C8
|
||||
conio:texttype = @a3texttype
|
||||
conio:textmode = @a3textmode
|
||||
conio:grmixmode = @a3grmixmode
|
||||
devcons = modaddr(@stdlib).5 ; devcons variable from STDLIB
|
||||
otherwise ; Apple ][
|
||||
devcons = modaddr(@stdlib).5 // devcons variable from STDLIB
|
||||
otherwise // Apple ][
|
||||
wend
|
||||
|
@ -1,8 +1,8 @@
|
||||
import STDLIB
|
||||
predef memset
|
||||
;
|
||||
; System flags: memory allocator screen holes.
|
||||
;
|
||||
//
|
||||
// System flags: memory allocator screen holes.
|
||||
//
|
||||
const restxt1 = $0001
|
||||
const restxt2 = $0002
|
||||
const reshgr1 = $0004
|
||||
@ -11,9 +11,9 @@ import STDLIB
|
||||
const resxhgr2 = $0020
|
||||
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
|
||||
^$C052
|
||||
^$C057
|
||||
|
@ -4,11 +4,11 @@ end
|
||||
import HGR1
|
||||
end
|
||||
|
||||
const view_height = 64 ; scan count of ground view
|
||||
const fix_bits = 8 ; number of fixed point bits
|
||||
;
|
||||
; Hardware addresses
|
||||
;
|
||||
const view_height = 64 // scan count of ground view
|
||||
const fix_bits = 8 // number of fixed point bits
|
||||
//
|
||||
// Hardware addresses
|
||||
//
|
||||
const speaker=$C030
|
||||
const showgraphics=$C050
|
||||
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 = $03D0,$07D0,$0BD0,$0FD0,$13D0,$17D0,$1BD0,$1FD0
|
||||
word hcolor[] = $0000,$552A,$2A55,$7F7F,$8080,$D5AA,$AAD5,$FFFF
|
||||
;
|
||||
; def draw_scan(d8p8, scanptr)
|
||||
;
|
||||
//
|
||||
// def draw_scan(d8p8, scanptr)
|
||||
//
|
||||
asm draw_scan
|
||||
!SOURCE "vmsrc/plvmzp.inc"
|
||||
WFIXL = $80
|
||||
|
@ -1,16 +1,16 @@
|
||||
;
|
||||
; Include all imported modules and their data/functions.
|
||||
;
|
||||
//
|
||||
// Include all imported modules and their data/functions.
|
||||
//
|
||||
include(stdlib.plh)
|
||||
;
|
||||
; Profile commands.
|
||||
;
|
||||
//
|
||||
// Profile commands.
|
||||
//
|
||||
const stop = 0
|
||||
const start = 1
|
||||
const dump = 2
|
||||
;
|
||||
; Declare all global variables for this module.
|
||||
;
|
||||
//
|
||||
// Declare all global variables for this module.
|
||||
//
|
||||
byte profstr[] = "PLASMA Profiler\n"
|
||||
byte optstr[] = "Module to profile"
|
||||
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'
|
||||
word cmdstr
|
||||
byte opstats[260]
|
||||
;
|
||||
; Define functions.
|
||||
;
|
||||
//
|
||||
// Define functions.
|
||||
//
|
||||
asm equate
|
||||
!SOURCE "vmsrc/plvmzp.inc"
|
||||
end
|
||||
|
@ -2,16 +2,16 @@ import STDLIB
|
||||
predef syscall, call, memset, getc, putc, puts, modaddr
|
||||
byte MACHID
|
||||
end
|
||||
;
|
||||
; Handy constants.
|
||||
;
|
||||
//
|
||||
// Handy constants.
|
||||
//
|
||||
const FALSE=0
|
||||
const TRUE=!FALSE
|
||||
const FULLMODE=0
|
||||
const MIXMODE=1
|
||||
;
|
||||
; Apple II hardware constants.
|
||||
;
|
||||
//
|
||||
// Apple II hardware constants.
|
||||
//
|
||||
const speaker = $C030
|
||||
const showgraphics = $C050
|
||||
const showtext = $C051
|
||||
@ -27,50 +27,50 @@ const hgr1 = $2000
|
||||
const hgr2 = $4000
|
||||
const page1 = 0
|
||||
const page2 = 1
|
||||
;
|
||||
; Predefined functions.
|
||||
;
|
||||
//
|
||||
// Predefined functions.
|
||||
//
|
||||
predef a2keypressed, a2gotoxy, a2grmode, a2textmode
|
||||
;
|
||||
; String data.
|
||||
;
|
||||
//
|
||||
// String data.
|
||||
//
|
||||
byte a1err[] = "Apple 1 not supported.\n"
|
||||
byte a3err[] = "Apple 3 version mismatch.\n"
|
||||
byte exitmsg[] = "Press any key to exit.\n"
|
||||
byte goodbye[] = "That's all, folks!\n"
|
||||
byte stdlib[] = "STDLIB"
|
||||
;
|
||||
; Screen row address arrays.
|
||||
;
|
||||
//
|
||||
// Screen row address arrays.
|
||||
//
|
||||
word txt1scrn[] = $0400,$0480,$0500,$0580,$0600,$0680,$0700,$0780
|
||||
word = $0428,$04A8,$0528,$05A8,$0628,$06A8,$0728,$07A8
|
||||
word = $0450,$04D0,$0550,$05D0,$0650,$06D0,$0750,$07D0
|
||||
word txt2scrn[] = $0800,$0880,$0900,$0980,$0A00,$0A80,$0B00,$0B80
|
||||
word = $0828,$08A8,$0928,$09A8,$0A28,$0AA8,$0B28,$0BA8
|
||||
word = $0850,$08D0,$0950,$09D0,$0A50,$0AD0,$0B50,$0BD0
|
||||
;
|
||||
; Apple 3 console codes.
|
||||
;
|
||||
//
|
||||
// Apple 3 console codes.
|
||||
//
|
||||
byte textbwmode[] = 2, 16, 0
|
||||
byte textclrmode[] = 2, 16, 1
|
||||
byte grcharset[] = 1, 0, $7F, $7F, $7F, $7F, $00, $00, $00, $00
|
||||
byte devcons
|
||||
;
|
||||
; Function pointers.
|
||||
;
|
||||
//
|
||||
// Function pointers.
|
||||
//
|
||||
word keypressed = @a2keypressed
|
||||
word gotoxy = @a2gotoxy
|
||||
word grmode = @a2grmode
|
||||
word textmode = @a2textmode
|
||||
;
|
||||
; Common routines.
|
||||
;
|
||||
//
|
||||
// Common routines.
|
||||
//
|
||||
asm equates
|
||||
!SOURCE "vmsrc/plvmzp.inc"
|
||||
end
|
||||
;
|
||||
; def grscrn(rowaddrs)
|
||||
;
|
||||
//
|
||||
// def grscrn(rowaddrs)
|
||||
//
|
||||
asm grscrn
|
||||
GRSCRN = $26
|
||||
GRSCRNL = GRSCRN
|
||||
@ -81,9 +81,9 @@ GRSCRNH = GRSCRNL+1
|
||||
STA GRSCRNH
|
||||
RTS
|
||||
end
|
||||
;
|
||||
; def grcolor(color)
|
||||
;
|
||||
//
|
||||
// def grcolor(color)
|
||||
//
|
||||
asm grcolor
|
||||
GRCLR = $30
|
||||
LDA #$0F
|
||||
@ -97,9 +97,9 @@ GRCLR = $30
|
||||
STA GRCLR
|
||||
RTS
|
||||
end
|
||||
;
|
||||
; def grplot(x, y)
|
||||
;
|
||||
//
|
||||
// def grplot(x, y)
|
||||
//
|
||||
asm grplot
|
||||
STY IPY
|
||||
LDA ESTKL,X
|
||||
@ -128,9 +128,9 @@ asm grplot
|
||||
INX
|
||||
RTS
|
||||
end
|
||||
;
|
||||
; Apple II routines.
|
||||
;
|
||||
//
|
||||
// Apple II routines.
|
||||
//
|
||||
def a2keypressed
|
||||
if ^keyboard >= 128
|
||||
return ^keystrobe
|
||||
@ -142,21 +142,21 @@ def a2gotoxy(x, y)
|
||||
return call($FB5B, y + ^$22, 0, 0, 0)
|
||||
end
|
||||
def a2grmode(mix)
|
||||
call($FB2F, 0, 0, 0, 0) ;initmode()
|
||||
call($FB40, 0, 0, 0, 0) ;grmode()
|
||||
call($FB2F, 0, 0, 0, 0) // initmode()
|
||||
call($FB40, 0, 0, 0, 0) // grmode()
|
||||
if !mix
|
||||
^showfull
|
||||
fin
|
||||
call($FC58, 0, 0, 0, 0) ;home()
|
||||
return grscrn(@txt1scrn) ; point to lo-res screen
|
||||
call($FC58, 0, 0, 0, 0) // home()
|
||||
return grscrn(@txt1scrn) // point to lo-res screen
|
||||
end
|
||||
def a2textmode
|
||||
call($FB39, 0, 0, 0, 0) ;textmode()
|
||||
return call($FC58, 0, 0, 0, 0) ;home()
|
||||
call($FB39, 0, 0, 0, 0) // textmode()
|
||||
return call($FC58, 0, 0, 0, 0) // home()
|
||||
end
|
||||
;
|
||||
; Apple III routines.
|
||||
;
|
||||
//
|
||||
// Apple III routines.
|
||||
//
|
||||
def dev_control(devnum, code, list)
|
||||
byte params[5]
|
||||
|
||||
@ -190,7 +190,7 @@ def a3gotoxy(x, y)
|
||||
return putc(y)
|
||||
end
|
||||
def a3viewport(left, top, width, height)
|
||||
putc(1) ; Reset viewport
|
||||
putc(1) // Reset viewport
|
||||
putc(26)
|
||||
putc(left)
|
||||
putc(top)
|
||||
@ -212,19 +212,19 @@ def a3grmode(mix)
|
||||
dev_control(devcons, 17, @grcharset)
|
||||
a3viewport(0, 20, 40, 4)
|
||||
for i = 0 to mix
|
||||
memset(txt1scrn[i], 40, $0000) ; text screen
|
||||
memset(txt2scrn[i], 40, $0000) ; color screen
|
||||
memset(txt1scrn[i], 40, $0000) // text screen
|
||||
memset(txt2scrn[i], 40, $0000) // color screen
|
||||
next
|
||||
return grscrn(@txt2scrn) ; point to color screen
|
||||
return grscrn(@txt2scrn) // point to color screen
|
||||
end
|
||||
def a3textmode
|
||||
puts(@textbwmode)
|
||||
a3viewport(0, 0, 40, 24)
|
||||
return putc(28)
|
||||
end
|
||||
;
|
||||
; Rod's Colors.
|
||||
;
|
||||
//
|
||||
// Rod's Colors.
|
||||
//
|
||||
def rod
|
||||
byte i, j, k, w, fmi, fmk, color
|
||||
while TRUE
|
||||
@ -252,25 +252,25 @@ def rod
|
||||
next
|
||||
loop
|
||||
end
|
||||
;
|
||||
; Machine specific initialization.
|
||||
;
|
||||
//
|
||||
// Machine specific initialization.
|
||||
//
|
||||
when MACHID & $C8
|
||||
is $08 ; Apple 1
|
||||
is $08 // Apple 1
|
||||
puts(@a1err)
|
||||
return
|
||||
is $C0 ; Apple ///
|
||||
is $C0 // Apple ///
|
||||
keypressed = @a3keypressed
|
||||
gotoxy = @a3gotoxy
|
||||
grmode = @a3grmode
|
||||
textmode = @a3textmode
|
||||
if modaddr(@stdlib):0 == $0010
|
||||
devcons = modaddr(@stdlib).5 ; devcons variable from STDLIB
|
||||
devcons = modaddr(@stdlib).5 // devcons variable from STDLIB
|
||||
else
|
||||
puts(@a3err)
|
||||
return
|
||||
fin
|
||||
otherwise ; Apple ][
|
||||
otherwise // Apple ][
|
||||
wend
|
||||
grmode(MIXMODE)
|
||||
gotoxy(11, 1)
|
||||
|
@ -18,10 +18,7 @@ def beep
|
||||
end
|
||||
|
||||
def puti(i)
|
||||
if i < 0
|
||||
putc('-')
|
||||
i = -i
|
||||
fin
|
||||
if i < 0; putc('-'); i = -i; fin
|
||||
if i < 10
|
||||
putc(i + '0')
|
||||
else
|
||||
|
@ -1,14 +1,11 @@
|
||||
;
|
||||
; Include all imported modules and their data/functions.
|
||||
;
|
||||
|
||||
//
|
||||
// Include all imported modules and their data/functions.
|
||||
//
|
||||
include(stdlib.plh)
|
||||
include(testlib.plh)
|
||||
|
||||
;
|
||||
; Declare all global variables for this module.
|
||||
;
|
||||
|
||||
//
|
||||
// Declare all global variables for this module.
|
||||
//
|
||||
byte hello[] = "Hello, Apple "
|
||||
byte a1[] = "1"
|
||||
byte a2[] = "]["
|
||||
@ -19,11 +16,9 @@ byte a3[] = "///"
|
||||
word struct[] = 1, 10, 100, 1000, 10000
|
||||
word ptr
|
||||
byte spaces[] = " "
|
||||
|
||||
;
|
||||
; Define functions.
|
||||
;
|
||||
|
||||
//
|
||||
// Define functions.
|
||||
//
|
||||
def tens(start)
|
||||
word i
|
||||
i = start
|
||||
@ -35,7 +30,6 @@ def tens(start)
|
||||
i = i / 10
|
||||
until i == 0
|
||||
end
|
||||
|
||||
def ascii
|
||||
byte i
|
||||
i = 32
|
||||
@ -44,7 +38,6 @@ def ascii
|
||||
i = i + 1
|
||||
loop
|
||||
end
|
||||
|
||||
def nums(range)
|
||||
word i
|
||||
for i = range downto -range step range/10
|
||||
@ -52,7 +45,6 @@ def nums(range)
|
||||
putln
|
||||
next
|
||||
end
|
||||
|
||||
export def main(range)
|
||||
nums(*range)
|
||||
tens(*range*10)
|
||||
@ -83,8 +75,7 @@ export def main(range)
|
||||
wend
|
||||
putln
|
||||
end
|
||||
|
||||
ptr=@struct
|
||||
ptr = @struct
|
||||
main(@struct:6)
|
||||
puti((ptr):6)
|
||||
putln
|
||||
|
@ -1,22 +1,17 @@
|
||||
;
|
||||
; Include all imported modules and their data/functions.
|
||||
;
|
||||
|
||||
//
|
||||
// Include all imported modules and their data/functions.
|
||||
//
|
||||
include(stdlib.plh)
|
||||
|
||||
;
|
||||
; Module data.
|
||||
;
|
||||
|
||||
//
|
||||
// Module data.
|
||||
//
|
||||
predef puti, puth, putln
|
||||
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 loadstr[] = "testlib loaded!"
|
||||
|
||||
;
|
||||
; Define functions.
|
||||
;
|
||||
|
||||
//
|
||||
// Define functions.
|
||||
//
|
||||
def puth(h)
|
||||
putc('$')
|
||||
putc(valstr[(h >> 12) & $0F])
|
||||
@ -24,12 +19,8 @@ def puth(h)
|
||||
putc(valstr[(h >> 4) & $0F])
|
||||
putc(valstr[ h & $0F])
|
||||
end
|
||||
|
||||
export def puti(i)
|
||||
if i < 0
|
||||
putc('-')
|
||||
i = -i
|
||||
fin
|
||||
if i < 0; putc('-'); i = -i; fin
|
||||
if i < 10
|
||||
putc(i + '0')
|
||||
else
|
||||
@ -37,7 +28,6 @@ export def puti(i)
|
||||
putc(i % 10 + '0')
|
||||
fin
|
||||
end
|
||||
|
||||
puts(@loadstr)
|
||||
putln
|
||||
done
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include "tokens.h"
|
||||
#include "symbols.h"
|
||||
|
||||
char *statement, *scanpos, *tokenstr;
|
||||
char *statement, *tokenstr, *scanpos = "";
|
||||
t_token scantoken, prevtoken;
|
||||
int tokenlen;
|
||||
long constval;
|
||||
@ -22,28 +22,28 @@ t_token keywords[] = {
|
||||
ENDCASE_TOKEN, 'W', 'E', 'N', 'D',
|
||||
FOR_TOKEN, 'F', 'O', 'R',
|
||||
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',
|
||||
NEXT_TOKEN, 'N', 'E', 'X', 'T',
|
||||
REPEAT_TOKEN, 'R', 'E', 'P', 'E', 'A', 'T',
|
||||
UNTIL_TOKEN, 'U', 'N', 'T', 'I', 'L',
|
||||
BREAK_TOKEN, 'B', 'R', 'E', 'A', 'K',
|
||||
UNTIL_TOKEN, 'U', 'N', 'T', 'I', 'L',
|
||||
BREAK_TOKEN, 'B', 'R', 'E', 'A', 'K',
|
||||
ASM_TOKEN, 'A', 'S', 'M',
|
||||
DEF_TOKEN, 'D', 'E', 'F',
|
||||
EXPORT_TOKEN, 'E', 'X', 'P', 'O', 'R', 'T',
|
||||
IMPORT_TOKEN, 'I', 'M', 'P', 'O', 'R', 'T',
|
||||
EXPORT_TOKEN, 'E', 'X', 'P', 'O', 'R', 'T',
|
||||
IMPORT_TOKEN, 'I', 'M', 'P', 'O', 'R', 'T',
|
||||
RETURN_TOKEN, 'R', 'E', 'T', 'U', 'R', 'N',
|
||||
END_TOKEN, 'E', 'N', 'D',
|
||||
EXIT_TOKEN, 'E', 'X', 'I', 'T',
|
||||
DONE_TOKEN, 'D', 'O', 'N', 'E',
|
||||
LOGIC_NOT_TOKEN, 'N', 'O', 'T',
|
||||
LOGIC_AND_TOKEN, 'A', 'N', 'D',
|
||||
LOGIC_OR_TOKEN, 'O', 'R',
|
||||
LOGIC_OR_TOKEN, 'O', 'R',
|
||||
BYTE_TOKEN, 'B', 'Y', 'T', 'E',
|
||||
WORD_TOKEN, 'W', 'O', 'R', 'D',
|
||||
CONST_TOKEN, 'C', 'O', 'N', 'S', 'T',
|
||||
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
|
||||
};
|
||||
|
||||
@ -333,6 +333,15 @@ t_token scan(void)
|
||||
scanpos++;
|
||||
}
|
||||
break;
|
||||
case '/':
|
||||
if (scanpos[1] == '/')
|
||||
scantoken = EOL_TOKEN;
|
||||
else
|
||||
{
|
||||
scantoken = DIV_TOKEN;
|
||||
scanpos++;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
* Simple single character tokens.
|
||||
@ -363,12 +372,21 @@ int scan_lookahead(void)
|
||||
char inputline[512];
|
||||
int next_line(void)
|
||||
{
|
||||
gets(inputline);
|
||||
lineno++;
|
||||
statement = inputline;
|
||||
scanpos = inputline;
|
||||
scantoken = EOL_TOKEN;
|
||||
scan();
|
||||
printf("; %03d: %s\n", lineno, inputline);
|
||||
if (*scanpos == ';')
|
||||
{
|
||||
statement = ++scanpos;
|
||||
scantoken = EOL_TOKEN;
|
||||
scan();
|
||||
}
|
||||
else
|
||||
{
|
||||
gets(inputline);
|
||||
lineno++;
|
||||
statement = inputline;
|
||||
scanpos = inputline;
|
||||
scantoken = EOL_TOKEN;
|
||||
scan();
|
||||
printf("; %03d: %s\n", lineno, inputline);
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
const MODADDR = $1000
|
||||
const inbuff = $200
|
||||
const freemem = $0006
|
||||
;
|
||||
; CFFA1 addresses.
|
||||
;
|
||||
//
|
||||
// CFFA1 addresses.
|
||||
//
|
||||
const CFFADest = $00
|
||||
const CFFAFileName = $02
|
||||
const CFFAOldName = $04
|
||||
@ -11,31 +11,31 @@ const CFFAFileType = $06
|
||||
const CFFAAuxType = $07
|
||||
const CFFAFileSize = $09
|
||||
const CFFAEntryPtr = $0B
|
||||
;
|
||||
; Pedefined functions.
|
||||
;
|
||||
//
|
||||
// Pedefined functions.
|
||||
//
|
||||
predef crout, cout, prstr, cin, rdstr
|
||||
predef syscall, call
|
||||
predef markheap, allocheap, allocalignheap, releaseheap, availheap
|
||||
predef memset, memcpy
|
||||
predef uword_isgt, uword_isge, uword_islt, uword_isle
|
||||
predef loadmod, execmod, lookupstrmod
|
||||
;
|
||||
; System variables.
|
||||
;
|
||||
word version = $0010 ; 00.10
|
||||
//
|
||||
// System variables.
|
||||
//
|
||||
word version = $0010 // 00.10
|
||||
word systemflags = 0
|
||||
word heap
|
||||
word symtbl, lastsym
|
||||
byte perr
|
||||
word cmdptr
|
||||
;
|
||||
; Exported Machine ID.
|
||||
;
|
||||
byte machid = $08 ; Apple 1 (NA in ProDOS Tech Ref)
|
||||
;
|
||||
; Standard Library exported functions.
|
||||
;
|
||||
//
|
||||
// Exported Machine ID.
|
||||
//
|
||||
byte machid = $08 // Apple 1 (NA in ProDOS Tech Ref)
|
||||
//
|
||||
// Standard Library exported functions.
|
||||
//
|
||||
byte stdlibstr[] = "STDLIB"
|
||||
byte machidstr[] = "MACHID"
|
||||
byte putcstr[] = "PUTC"
|
||||
@ -82,9 +82,9 @@ word = @modadrstr, @lookupstrmod
|
||||
word = @machidstr, @machid
|
||||
word = 0
|
||||
word stdlibsym = @exports
|
||||
;
|
||||
; String pool.
|
||||
;
|
||||
//
|
||||
// String pool.
|
||||
//
|
||||
byte autorun[] = "AUTORUN"
|
||||
byte verstr[] = "\nPLASMA "
|
||||
byte freestr[] = "MEM FREE:$"
|
||||
@ -93,10 +93,10 @@ byte prompt[] = "PLASMA"
|
||||
byte okstr[] = "OK"
|
||||
byte huhstr[] = "?\n"
|
||||
byte hexchar[] = '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
|
||||
;
|
||||
; CALL CFFA1 API ENTRYPOINT
|
||||
; SYSCALL(CMD)
|
||||
;
|
||||
//
|
||||
// CALL CFFA1 API ENTRYPOINT
|
||||
// SYSCALL(CMD)
|
||||
//
|
||||
asm syscall
|
||||
LDA ESTKL,X
|
||||
STX ESP
|
||||
@ -108,10 +108,10 @@ asm syscall
|
||||
STY ESTKH,X
|
||||
RTS
|
||||
end
|
||||
;
|
||||
; CALL 6502 ROUTINE
|
||||
; CALL(AREG, XREG, YREG, STATUS, ADDR)
|
||||
;
|
||||
//
|
||||
// CALL 6502 ROUTINE
|
||||
// CALL(AREG, XREG, YREG, STATUS, ADDR)
|
||||
//
|
||||
asm call
|
||||
REGVALS = SRC
|
||||
PHP
|
||||
@ -150,17 +150,17 @@ REGVALS = SRC
|
||||
RTS
|
||||
JMPTMP JMP (TMP)
|
||||
end
|
||||
;
|
||||
; QUIT TO MONITOR
|
||||
;
|
||||
//
|
||||
// QUIT TO MONITOR
|
||||
//
|
||||
asm quit
|
||||
JMP $9000
|
||||
end
|
||||
;
|
||||
; SET MEMORY TO VALUE
|
||||
; MEMSET(ADDR, SIZE, VALUE)
|
||||
; With optimizations from Peter Ferrie
|
||||
;
|
||||
//
|
||||
// SET MEMORY TO VALUE
|
||||
// MEMSET(ADDR, SIZE, VALUE)
|
||||
// With optimizations from Peter Ferrie
|
||||
//
|
||||
asm memset
|
||||
LDY #$00
|
||||
LDA ESTKL+2,X
|
||||
@ -187,10 +187,10 @@ SETMEX INX
|
||||
INX
|
||||
RTS
|
||||
end
|
||||
;
|
||||
; COPY MEMORY
|
||||
; MEMCPY(DSTADDR, SRCADDR, SIZE)
|
||||
;
|
||||
//
|
||||
// COPY MEMORY
|
||||
// MEMCPY(DSTADDR, SRCADDR, SIZE)
|
||||
//
|
||||
asm memcpy
|
||||
INX
|
||||
INX
|
||||
@ -260,9 +260,9 @@ REVCPYLP LDA (SRC),Y
|
||||
BNE REVCPYLP
|
||||
CPYMEX RTS
|
||||
end
|
||||
;
|
||||
; Unsigned word comparisons.
|
||||
;
|
||||
//
|
||||
// Unsigned word comparisons.
|
||||
//
|
||||
asm uword_isge
|
||||
LDY #$00
|
||||
LDA ESTKL+1,X
|
||||
@ -313,9 +313,9 @@ asm uword_islt
|
||||
INX
|
||||
RTS
|
||||
end
|
||||
;
|
||||
; Addresses of internal routines.
|
||||
;
|
||||
//
|
||||
// Addresses of internal routines.
|
||||
//
|
||||
asm interp
|
||||
DEX
|
||||
LDA #<IINTERP
|
||||
@ -324,21 +324,21 @@ asm interp
|
||||
STA ESTKH,X
|
||||
RTS
|
||||
end
|
||||
;
|
||||
; A DCI string is one that has the high bit set for every character except the last.
|
||||
; More efficient than C or Pascal strings.
|
||||
;
|
||||
;def dcitos(dci, str)
|
||||
; byte len, c
|
||||
; len = 0
|
||||
; repeat
|
||||
; c = (dci).[len]
|
||||
; len = len + 1
|
||||
; (str).[len] = c & $7F
|
||||
; until !(c & $80)
|
||||
; ^str = len
|
||||
; return len
|
||||
;end
|
||||
//
|
||||
// A DCI string is one that has the high bit set for every character except the last.
|
||||
// More efficient than C or Pascal strings.
|
||||
//
|
||||
//def dcitos(dci, str)
|
||||
// byte len, c
|
||||
// len = 0
|
||||
// repeat
|
||||
// c = (dci).[len]
|
||||
// len = len + 1
|
||||
// (str).[len] = c & $7F
|
||||
// until !(c & $80)
|
||||
// ^str = len
|
||||
// return len
|
||||
//end
|
||||
asm dcitos
|
||||
LDA ESTKL,X
|
||||
STA DSTL
|
||||
@ -363,22 +363,22 @@ asm dcitos
|
||||
STY ESTKH,X
|
||||
RTS
|
||||
end
|
||||
;def stodci(str, dci)
|
||||
; byte len, c
|
||||
; len = ^str
|
||||
; if len == 0
|
||||
; return
|
||||
; fin
|
||||
; c = toupper((str).[len]) & $7F
|
||||
; len = len - 1
|
||||
; (dci).[len] = c
|
||||
; while len
|
||||
; c = toupper((str).[len]) | $80
|
||||
; len = len - 1
|
||||
; (dci).[len] = c
|
||||
; loop
|
||||
; return ^str
|
||||
;end
|
||||
//def stodci(str, dci)
|
||||
// byte len, c
|
||||
// len = ^str
|
||||
// if len == 0
|
||||
// return
|
||||
// fin
|
||||
// c = toupper((str).[len]) & $7F
|
||||
// len = len - 1
|
||||
// (dci).[len] = c
|
||||
// while len
|
||||
// c = toupper((str).[len]) | $80
|
||||
// len = len - 1
|
||||
// (dci).[len] = c
|
||||
// loop
|
||||
// return ^str
|
||||
//end
|
||||
asm stodci
|
||||
LDA ESTKL,X
|
||||
STA DSTL
|
||||
@ -418,22 +418,22 @@ TOUPR AND #$7F
|
||||
+ STA ESTKL,X
|
||||
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
|
||||
//
|
||||
// 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
|
||||
LDA ESTKL+1,X
|
||||
STA SRCL
|
||||
@ -455,26 +455,26 @@ asm modtosym
|
||||
BCS -
|
||||
RTS
|
||||
end
|
||||
;
|
||||
; Lookup routines.
|
||||
;
|
||||
;def lookuptbl(dci, tbl)
|
||||
; word match
|
||||
; while ^tbl
|
||||
; match = dci
|
||||
; while ^tbl == ^match
|
||||
; if !(^tbl & $80)
|
||||
; return (tbl):1
|
||||
; fin
|
||||
; tbl = tbl + 1
|
||||
; match = match + 1
|
||||
; loop
|
||||
; while (^tbl & $80)
|
||||
; tbl = tbl + 1
|
||||
; loop
|
||||
; tbl = tbl + 3
|
||||
; loop
|
||||
; return 0
|
||||
//
|
||||
// Lookup routines.
|
||||
//
|
||||
//def lookuptbl(dci, tbl)
|
||||
// word match
|
||||
// while ^tbl
|
||||
// match = dci
|
||||
// while ^tbl == ^match
|
||||
// if !(^tbl & $80)
|
||||
// return (tbl):1
|
||||
// fin
|
||||
// tbl = tbl + 1
|
||||
// match = match + 1
|
||||
// loop
|
||||
// while (^tbl & $80)
|
||||
// tbl = tbl + 1
|
||||
// loop
|
||||
// tbl = tbl + 3
|
||||
// loop
|
||||
// return 0
|
||||
asm lookuptbl
|
||||
LDA ESTKL,X
|
||||
STA DSTL
|
||||
@ -516,9 +516,9 @@ asm lookuptbl
|
||||
INC DSTH
|
||||
BCS -
|
||||
end
|
||||
;
|
||||
; CONSOLE I/O
|
||||
;
|
||||
//
|
||||
// CONSOLE I/O
|
||||
//
|
||||
asm cout
|
||||
LDA ESTKL,X
|
||||
JSR TOUPR
|
||||
@ -555,19 +555,19 @@ def rdstr(prompt)
|
||||
repeat
|
||||
ch = cin
|
||||
when ch
|
||||
is $15 ; right arrow
|
||||
is $15 // right arrow
|
||||
if inbuff.0 < maxlen
|
||||
inbuff.0 = inbuff.0 + 1
|
||||
ch = inbuff[inbuff.0]
|
||||
cout(ch)
|
||||
fin
|
||||
is $08 ; left arrow
|
||||
is $08 // left arrow
|
||||
if inbuff.0
|
||||
cout('\\')
|
||||
cout(inbuff[inbuff.0])
|
||||
inbuff.0 = inbuff.0 - 1
|
||||
fin
|
||||
is $04 ; ctrl-d
|
||||
is $04 // ctrl-d
|
||||
if inbuff.0
|
||||
cout('#')
|
||||
cout(inbuff[inbuff.0])
|
||||
@ -575,14 +575,14 @@ def rdstr(prompt)
|
||||
maxlen = maxlen - 1
|
||||
inbuff.0 = inbuff.0 - 1
|
||||
fin
|
||||
is $0C ; ctrl-l
|
||||
is $0C // ctrl-l
|
||||
crout
|
||||
prstr(inbuff)
|
||||
is $0D ; return
|
||||
is $18 ; ctrl-x
|
||||
is $0D // return
|
||||
is $18 // ctrl-x
|
||||
crout
|
||||
inbuff.0 = 0
|
||||
is $9B ; escape
|
||||
is $9B // escape
|
||||
inbuff.0 = 0
|
||||
ch = $0D
|
||||
otherwise
|
||||
@ -607,18 +607,18 @@ def prword(v)
|
||||
prbyte(v >> 8)
|
||||
return prbyte(v)
|
||||
end
|
||||
;
|
||||
; CFFA1 routines
|
||||
; FILE I/O
|
||||
;
|
||||
;def opendir
|
||||
; perr = syscall($10)
|
||||
; return perr
|
||||
;end
|
||||
;def readdir
|
||||
; perr = syscall($12)
|
||||
; return *CFFAEntryPtr
|
||||
;end
|
||||
//
|
||||
// CFFA1 routines
|
||||
// FILE I/O
|
||||
//
|
||||
//def opendir
|
||||
// perr = syscall($10)
|
||||
// return perr
|
||||
//end
|
||||
//def readdir
|
||||
// perr = syscall($12)
|
||||
// return *CFFAEntryPtr
|
||||
//end
|
||||
def finddirentry(filename)
|
||||
*CFFAFileName = filename
|
||||
perr = syscall($14)
|
||||
@ -630,9 +630,9 @@ def readfile(filename, buffer)
|
||||
perr = syscall($22)
|
||||
return perr
|
||||
end
|
||||
;
|
||||
; Heap routines.
|
||||
;
|
||||
//
|
||||
// Heap routines.
|
||||
//
|
||||
def availheap
|
||||
byte fp
|
||||
return @fp - heap
|
||||
@ -660,15 +660,15 @@ def allocalignheap(size, pow2, freeaddr)
|
||||
return addr
|
||||
end
|
||||
def markheap
|
||||
return heap;
|
||||
return heap
|
||||
end
|
||||
def releaseheap(newheap)
|
||||
heap = newheap;
|
||||
return @newheap - heap;
|
||||
heap = newheap
|
||||
return @newheap - heap
|
||||
end
|
||||
;
|
||||
; Symbol table routines.
|
||||
;
|
||||
//
|
||||
// Symbol table routines.
|
||||
//
|
||||
def lookupsym(sym)
|
||||
return lookuptbl(sym, symtbl)
|
||||
end
|
||||
@ -683,9 +683,9 @@ def addsym(sym, addr)
|
||||
lastsym = lastsym + 3
|
||||
^lastsym = 0
|
||||
end
|
||||
;
|
||||
; Module routines.
|
||||
;
|
||||
//
|
||||
// Module routines.
|
||||
//
|
||||
def lookupmod(mod)
|
||||
byte dci[17]
|
||||
return lookuptbl(modtosym(mod, @dci), symtbl)
|
||||
@ -726,7 +726,7 @@ def adddef(addr, deflast)
|
||||
defentry->0 = $20
|
||||
defentry=>1 = interp
|
||||
defentry=>3 = addr
|
||||
defentry->5 = 0 ; null out next entry
|
||||
defentry->5 = 0 // null out next entry
|
||||
return defentry
|
||||
end
|
||||
def lookupdef(addr, deftbl)
|
||||
@ -745,9 +745,9 @@ def loadmod(mod)
|
||||
word moddep, rld, esd, sym
|
||||
byte str[17], filename[17]
|
||||
byte header[128]
|
||||
;
|
||||
; Read the RELocatable module header (first 128 bytes)
|
||||
;
|
||||
//
|
||||
// Read the RELocatable module header (first 128 bytes)
|
||||
//
|
||||
dcitos(mod, @filename)
|
||||
rdlen = finddirentry(@filename)=>$15
|
||||
if perr
|
||||
@ -760,17 +760,17 @@ def loadmod(mod)
|
||||
moddep = @header.1
|
||||
defofst = modsize
|
||||
init = 0
|
||||
if rdlen > 4 and heap=>2 == $DA7E ; DAVE = magic number :-)
|
||||
;
|
||||
; This is an EXTended RELocatable (data+bytecode) module.
|
||||
;
|
||||
if rdlen > 4 and heap=>2 == $DA7E // DAVE = magic number :-)
|
||||
//
|
||||
// This is an EXTended RELocatable (data+bytecode) module.
|
||||
//
|
||||
defofst = header:6
|
||||
defcnt = header:8
|
||||
init = header:10
|
||||
moddep = @header.12
|
||||
;
|
||||
; Load module dependencies.
|
||||
;
|
||||
//
|
||||
// Load module dependencies.
|
||||
//
|
||||
while ^moddep
|
||||
if !lookupmod(moddep)
|
||||
if loadmod(moddep) < 0
|
||||
@ -779,94 +779,94 @@ def loadmod(mod)
|
||||
fin
|
||||
moddep = moddep + dcitos(moddep, @str)
|
||||
loop
|
||||
;
|
||||
; Init def table.
|
||||
;
|
||||
//
|
||||
// Init def table.
|
||||
//
|
||||
deftbl = allocheap(defcnt * 5 + 1)
|
||||
deflast = deftbl
|
||||
^deflast = 0
|
||||
;
|
||||
; Re-read file
|
||||
;
|
||||
//
|
||||
// Re-read file
|
||||
//
|
||||
readfile(@filename, heap)
|
||||
fin
|
||||
;
|
||||
; Alloc heap space for relocated module (data + bytecode).
|
||||
;
|
||||
//
|
||||
// Alloc heap space for relocated module (data + bytecode).
|
||||
//
|
||||
moddep = moddep + 1 - @header + heap
|
||||
modfix = moddep - (heap + 2) ; Adjust to skip header
|
||||
modfix = moddep - (heap + 2) // Adjust to skip header
|
||||
modsize = modsize - modfix
|
||||
rdlen = rdlen - modfix - 2
|
||||
modaddr = allocheap(modsize)
|
||||
memcpy(modaddr, moddep, rdlen)
|
||||
;
|
||||
; Add module to symbol table.
|
||||
;
|
||||
//
|
||||
// Add module to symbol table.
|
||||
//
|
||||
addmod(mod, modaddr)
|
||||
;
|
||||
; Apply all fixups and symbol import/export.
|
||||
;
|
||||
//
|
||||
// Apply all fixups and symbol import/export.
|
||||
//
|
||||
modfix = modaddr - modfix
|
||||
bytecode = defofst + modfix - MODADDR
|
||||
modend = modaddr + modsize
|
||||
rld = modend ; Re-Locatable Directory
|
||||
esd = rld ; Extern+Entry Symbol Directory
|
||||
while ^esd ; Scan to end of ESD
|
||||
rld = modend // Re-Locatable Directory
|
||||
esd = rld // Extern+Entry Symbol Directory
|
||||
while ^esd // Scan to end of ESD
|
||||
esd = esd + 4
|
||||
loop
|
||||
esd = esd + 1
|
||||
;
|
||||
; Run through the Re-Location Dictionary.
|
||||
;
|
||||
//
|
||||
// Run through the Re-Location Dictionary.
|
||||
//
|
||||
while ^rld
|
||||
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)
|
||||
else
|
||||
addr = rld=>1 + modfix
|
||||
if uword_isge(addr, modaddr) ; Skip fixups to header
|
||||
if ^rld & $80 ; WORD sized fixup.
|
||||
if uword_isge(addr, modaddr) // Skip fixups to header
|
||||
if ^rld & $80 // WORD sized fixup.
|
||||
fixup = *addr
|
||||
else ; BYTE sized fixup.
|
||||
else // BYTE sized fixup.
|
||||
fixup = ^addr
|
||||
fin
|
||||
if ^rld & $10 ; EXTERN reference.
|
||||
if ^rld & $10 // EXTERN reference.
|
||||
fixup = fixup + lookupextern(esd, rld->3)
|
||||
else ; INTERN fixup.
|
||||
else // INTERN fixup.
|
||||
fixup = fixup + modfix - MODADDR
|
||||
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)
|
||||
fin
|
||||
fin
|
||||
if ^rld & $80 ; WORD sized fixup.
|
||||
if ^rld & $80 // WORD sized fixup.
|
||||
*addr = fixup
|
||||
else ; BYTE sized fixup.
|
||||
else // BYTE sized fixup.
|
||||
^addr = fixup
|
||||
fin
|
||||
fin
|
||||
fin
|
||||
rld = rld + 4
|
||||
loop
|
||||
;
|
||||
; Run through the External/Entry Symbol Directory.
|
||||
;
|
||||
//
|
||||
// Run through the External/Entry Symbol Directory.
|
||||
//
|
||||
while ^esd
|
||||
sym = esd
|
||||
esd = esd + dcitos(esd, @str)
|
||||
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
|
||||
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)
|
||||
fin
|
||||
addsym(sym, addr)
|
||||
@ -877,24 +877,24 @@ def loadmod(mod)
|
||||
if perr
|
||||
return -perr
|
||||
fin
|
||||
;
|
||||
; Call init routine if it exists.
|
||||
;
|
||||
//
|
||||
// Call init routine if it exists.
|
||||
//
|
||||
if init
|
||||
fixup = adddef(init - defofst + bytecode, @deflast)()
|
||||
modend = init - defofst + bytecode
|
||||
else
|
||||
fixup = 0
|
||||
fin
|
||||
;
|
||||
; Free up the end-of-module in main memory.
|
||||
;
|
||||
//
|
||||
// Free up the end-of-module in main memory.
|
||||
//
|
||||
releaseheap(modend)
|
||||
return fixup
|
||||
end
|
||||
;
|
||||
; Command mode
|
||||
;
|
||||
//
|
||||
// Command mode
|
||||
//
|
||||
def stripchars(strptr)
|
||||
while ^strptr and ^(strptr + 1) <> ' '
|
||||
memcpy(strptr + 1, strptr + 2, ^strptr)
|
||||
@ -949,13 +949,13 @@ def execmod(modfile)
|
||||
heap = saveheap
|
||||
fin
|
||||
end
|
||||
;
|
||||
; Get heap start.
|
||||
;
|
||||
//
|
||||
// Get heap start.
|
||||
//
|
||||
heap = *freemem
|
||||
;
|
||||
; Init symbol table.
|
||||
;
|
||||
//
|
||||
// Init symbol table.
|
||||
//
|
||||
symtbl = allocheap($200)
|
||||
lastsym = symtbl
|
||||
^lastsym = 0
|
||||
@ -966,14 +966,14 @@ while *stdlibsym
|
||||
addsym(heap, stdlibsym=>2)
|
||||
stdlibsym = stdlibsym + 4
|
||||
loop
|
||||
;
|
||||
; Try to run autorun module.
|
||||
;
|
||||
//
|
||||
// Try to run autorun module.
|
||||
//
|
||||
execmod(@autorun)
|
||||
perr = 0
|
||||
;
|
||||
; Print some startup info.
|
||||
;
|
||||
//
|
||||
// Print some startup info.
|
||||
//
|
||||
prstr(@verstr)
|
||||
prbyte(version.1)
|
||||
cout('.')
|
||||
@ -982,9 +982,9 @@ crout
|
||||
prstr(@freestr)
|
||||
prword(availheap)
|
||||
crout
|
||||
;
|
||||
; Handle commands.
|
||||
;
|
||||
//
|
||||
// Handle commands.
|
||||
//
|
||||
while 1
|
||||
prstr(@prompt)
|
||||
cmdptr = rdstr($BA)
|
||||
|
@ -4,37 +4,37 @@ const databuff = $2000
|
||||
const MODADDR = $1000
|
||||
const symtbl = $0C00
|
||||
const freemem = $0006
|
||||
;
|
||||
; System flags: memory allocator screen holes.
|
||||
;
|
||||
//
|
||||
// System flags: memory allocator screen holes.
|
||||
//
|
||||
const restxt1 = $0001
|
||||
const restxt2 = $0002
|
||||
const reshgr1 = $0004
|
||||
const reshgr2 = $0008
|
||||
const resxhgr1 = $0010
|
||||
const resxhgr2 = $0020
|
||||
;
|
||||
; Pedefined functions.
|
||||
;
|
||||
//
|
||||
// Pedefined functions.
|
||||
//
|
||||
predef syscall, call
|
||||
predef crout, cout, prstr, cin, rdstr
|
||||
predef markheap, allocheap, allocalignheap, releaseheap, availheap
|
||||
predef memset, memcpy
|
||||
predef uword_isgt, uword_isge, uword_islt, uword_isle
|
||||
predef loadmod, execmod, lookupstrmod
|
||||
;
|
||||
; System variable.
|
||||
;
|
||||
word version = $0010 ; 00.10
|
||||
//
|
||||
// System variable.
|
||||
//
|
||||
word version = $0010 // 00.10
|
||||
word systemflags = 0
|
||||
word heap
|
||||
word xheap = $0800
|
||||
word lastsym = symtbl
|
||||
byte perr
|
||||
word cmdptr
|
||||
;
|
||||
; Standard Library exported functions.
|
||||
;
|
||||
//
|
||||
// Standard Library exported functions.
|
||||
//
|
||||
byte stdlibstr[] = "STDLIB"
|
||||
byte machidstr[] = "MACHID"
|
||||
byte sysstr[] = "SYSCALL"
|
||||
@ -81,9 +81,9 @@ word = @modadrstr, @lookupstrmod
|
||||
word = @machidstr, MACHID
|
||||
word = 0
|
||||
word stdlibsym = @exports
|
||||
;
|
||||
; String pool.
|
||||
;
|
||||
//
|
||||
// String pool.
|
||||
//
|
||||
byte autorun[] = "AUTORUN"
|
||||
byte verstr[] = "PLASMA "
|
||||
byte freestr[] = "MEM FREE:$"
|
||||
@ -91,14 +91,14 @@ byte errorstr[] = "ERR:$"
|
||||
byte okstr[] = "OK"
|
||||
byte huhstr[] = "?\n"
|
||||
byte prefix[32] = ""
|
||||
;
|
||||
; Utility functions
|
||||
;
|
||||
;asm equates included from cmdstub.s
|
||||
;
|
||||
; CALL PRODOS
|
||||
; SYSCALL(CMD, PARAMS)
|
||||
;
|
||||
//
|
||||
// Utility functions
|
||||
//
|
||||
//asm equates included from cmdstub.s
|
||||
//
|
||||
// CALL PRODOS
|
||||
// SYSCALL(CMD, PARAMS)
|
||||
//
|
||||
asm syscall
|
||||
LDA ESTKL,X
|
||||
LDY ESTKH,X
|
||||
@ -115,10 +115,10 @@ PARAMS: !WORD 0000
|
||||
STY ESTKH,X
|
||||
RTS
|
||||
end
|
||||
;
|
||||
; CALL 6502 ROUTINE
|
||||
; CALL(ADDR, AREG, XREG, YREG, STATUS)
|
||||
;
|
||||
//
|
||||
// CALL 6502 ROUTINE
|
||||
// CALL(ADDR, AREG, XREG, YREG, STATUS)
|
||||
//
|
||||
asm call
|
||||
REGVALS = SRC
|
||||
PHP
|
||||
@ -159,9 +159,9 @@ REGVALS = SRC
|
||||
RTS
|
||||
JMPTMP JMP (TMP)
|
||||
end
|
||||
;
|
||||
; CALL LOADED SYSTEM PROGRAM
|
||||
;
|
||||
//
|
||||
// CALL LOADED SYSTEM PROGRAM
|
||||
//
|
||||
asm exec
|
||||
LDX #$00
|
||||
STX IFPL
|
||||
@ -173,19 +173,19 @@ asm exec
|
||||
BIT ROMEN
|
||||
JMP $2000
|
||||
end
|
||||
;
|
||||
; EXIT
|
||||
;
|
||||
//
|
||||
// EXIT
|
||||
//
|
||||
asm reboot
|
||||
BIT ROMEN
|
||||
DEC $03F4 ; INVALIDATE POWER-UP BYTE
|
||||
JMP ($FFFC) ; RESET
|
||||
end
|
||||
;
|
||||
; SET MEMORY TO VALUE
|
||||
; MEMSET(ADDR, SIZE, VALUE)
|
||||
; With optimizations from Peter Ferrie
|
||||
;
|
||||
//
|
||||
// SET MEMORY TO VALUE
|
||||
// MEMSET(ADDR, SIZE, VALUE)
|
||||
// With optimizations from Peter Ferrie
|
||||
//
|
||||
asm memset
|
||||
LDY #$00
|
||||
LDA ESTKL+2,X
|
||||
@ -212,10 +212,10 @@ SETMEX INX
|
||||
INX
|
||||
RTS
|
||||
end
|
||||
;
|
||||
; COPY MEMORY
|
||||
; MEMCPY(DSTADDR, SRCADDR, SIZE)
|
||||
;
|
||||
//
|
||||
// COPY MEMORY
|
||||
// MEMCPY(DSTADDR, SRCADDR, SIZE)
|
||||
//
|
||||
asm memcpy
|
||||
INX
|
||||
INX
|
||||
@ -285,11 +285,11 @@ REVCPYLP LDA (SRC),Y
|
||||
BNE REVCPYLP
|
||||
CPYMEX RTS
|
||||
end
|
||||
;
|
||||
; COPY FROM MAIN MEM TO AUX MEM.
|
||||
;
|
||||
; MEMXCPY(DST, SRC, SIZE)
|
||||
;
|
||||
//
|
||||
// COPY FROM MAIN MEM TO AUX MEM.
|
||||
//
|
||||
// MEMXCPY(DST, SRC, SIZE)
|
||||
//
|
||||
asm memxcpy
|
||||
LDA ESTKL+1,X
|
||||
STA $3C
|
||||
@ -320,10 +320,10 @@ asm crout
|
||||
STA ESTKL,X
|
||||
; FALL THROUGH TO COUT
|
||||
end
|
||||
;
|
||||
; CHAR OUT
|
||||
; COUT(CHAR)
|
||||
;
|
||||
//
|
||||
// CHAR OUT
|
||||
// COUT(CHAR)
|
||||
//
|
||||
asm cout
|
||||
LDA ESTKL,X
|
||||
BIT $BF98
|
||||
@ -335,10 +335,10 @@ asm cout
|
||||
BIT LCRDEN+LCBNK2
|
||||
RTS
|
||||
end
|
||||
;
|
||||
; CHAR IN
|
||||
; RDKEY()
|
||||
;
|
||||
//
|
||||
// CHAR IN
|
||||
// RDKEY()
|
||||
//
|
||||
asm cin
|
||||
BIT ROMEN
|
||||
JSR $FD0C
|
||||
@ -349,10 +349,10 @@ asm cin
|
||||
STY ESTKH,X
|
||||
RTS
|
||||
end
|
||||
;
|
||||
; PRINT STRING
|
||||
; PRSTR(STR)
|
||||
;
|
||||
//
|
||||
// PRINT STRING
|
||||
// PRSTR(STR)
|
||||
//
|
||||
asm prstr
|
||||
LDY #$00
|
||||
LDA ESTKL,X
|
||||
@ -375,9 +375,9 @@ asm prstr
|
||||
BIT LCRDEN+LCBNK2
|
||||
++ RTS
|
||||
end
|
||||
;
|
||||
; PRINT BYTE
|
||||
;
|
||||
//
|
||||
// PRINT BYTE
|
||||
//
|
||||
asm prbyte
|
||||
LDA ESTKL,X
|
||||
STX ESP
|
||||
@ -387,9 +387,9 @@ asm prbyte
|
||||
BIT LCRDEN+LCBNK2
|
||||
RTS
|
||||
end
|
||||
;
|
||||
; PRINT WORD
|
||||
;
|
||||
//
|
||||
// PRINT WORD
|
||||
//
|
||||
asm prword
|
||||
STX ESP
|
||||
TXA
|
||||
@ -402,10 +402,10 @@ asm prword
|
||||
BIT LCRDEN+LCBNK2
|
||||
RTS
|
||||
end
|
||||
;
|
||||
; READ STRING
|
||||
; STR = RDSTR(PROMPTCHAR)
|
||||
;
|
||||
//
|
||||
// READ STRING
|
||||
// STR = RDSTR(PROMPTCHAR)
|
||||
//
|
||||
asm rdstr
|
||||
LDA ESTKL,X
|
||||
STA $33
|
||||
@ -476,23 +476,23 @@ asm uword_islt
|
||||
INX
|
||||
RTS
|
||||
end
|
||||
;
|
||||
; Utility routines.
|
||||
;
|
||||
; A DCI string is one that has the high bit set for every character except the last.
|
||||
; More efficient than C or Pascal strings.
|
||||
;
|
||||
;def dcitos(dci, str)
|
||||
; byte len, c
|
||||
; len = 0
|
||||
; repeat
|
||||
; c = (dci).[len]
|
||||
; len = len + 1
|
||||
; (str).[len] = c & $7F
|
||||
; until !(c & $80)
|
||||
; ^str = len
|
||||
; return len
|
||||
;end
|
||||
//
|
||||
// Utility routines.
|
||||
//
|
||||
// A DCI string is one that has the high bit set for every character except the last.
|
||||
// More efficient than C or Pascal strings.
|
||||
//
|
||||
//def dcitos(dci, str)
|
||||
// byte len, c
|
||||
// len = 0
|
||||
// repeat
|
||||
// c = (dci).[len]
|
||||
// len = len + 1
|
||||
// (str).[len] = c & $7F
|
||||
// until !(c & $80)
|
||||
// ^str = len
|
||||
// return len
|
||||
//end
|
||||
asm dcitos
|
||||
LDA ESTKL,X
|
||||
STA DSTL
|
||||
@ -517,22 +517,22 @@ asm dcitos
|
||||
STY ESTKH,X
|
||||
RTS
|
||||
end
|
||||
;def stodci(str, dci)
|
||||
; byte len, c
|
||||
; len = ^str
|
||||
; if len == 0
|
||||
; return
|
||||
; fin
|
||||
; c = toupper((str).[len]) & $7F
|
||||
; len = len - 1
|
||||
; (dci).[len] = c
|
||||
; while len
|
||||
; c = toupper((str).[len]) | $80
|
||||
; len = len - 1
|
||||
; (dci).[len] = c
|
||||
; loop
|
||||
; return ^str
|
||||
;end
|
||||
//def stodci(str, dci)
|
||||
// byte len, c
|
||||
// len = ^str
|
||||
// if len == 0
|
||||
// return
|
||||
// fin
|
||||
// c = toupper((str).[len]) & $7F
|
||||
// len = len - 1
|
||||
// (dci).[len] = c
|
||||
// while len
|
||||
// c = toupper((str).[len]) | $80
|
||||
// len = len - 1
|
||||
// (dci).[len] = c
|
||||
// loop
|
||||
// return ^str
|
||||
//end
|
||||
asm stodci
|
||||
LDA ESTKL,X
|
||||
STA DSTL
|
||||
@ -572,22 +572,22 @@ TOUPR AND #$7F
|
||||
+ STA ESTKL,X
|
||||
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
|
||||
//
|
||||
// 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
|
||||
LDA ESTKL+1,X
|
||||
STA SRCL
|
||||
@ -609,26 +609,26 @@ asm modtosym
|
||||
BCS -
|
||||
RTS
|
||||
end
|
||||
;
|
||||
; Lookup routines.
|
||||
;
|
||||
;def lookuptbl(dci, tbl)
|
||||
; word match
|
||||
; while ^tbl
|
||||
; match = dci
|
||||
; while ^tbl == ^match
|
||||
; if !(^tbl & $80)
|
||||
; return (tbl):1
|
||||
; fin
|
||||
; tbl = tbl + 1
|
||||
; match = match + 1
|
||||
; loop
|
||||
; while (^tbl & $80)
|
||||
; tbl = tbl + 1
|
||||
; loop
|
||||
; tbl = tbl + 3
|
||||
; loop
|
||||
; return 0
|
||||
//
|
||||
// Lookup routines.
|
||||
//
|
||||
//def lookuptbl(dci, tbl)
|
||||
// word match
|
||||
// while ^tbl
|
||||
// match = dci
|
||||
// while ^tbl == ^match
|
||||
// if !(^tbl & $80)
|
||||
// return (tbl):1
|
||||
// fin
|
||||
// tbl = tbl + 1
|
||||
// match = match + 1
|
||||
// loop
|
||||
// while (^tbl & $80)
|
||||
// tbl = tbl + 1
|
||||
// loop
|
||||
// tbl = tbl + 3
|
||||
// loop
|
||||
// return 0
|
||||
asm lookuptbl
|
||||
LDA ESTKL,X
|
||||
STA DSTL
|
||||
@ -670,9 +670,9 @@ asm lookuptbl
|
||||
INC DSTH
|
||||
BCS -
|
||||
end
|
||||
;
|
||||
; ProDOS routines
|
||||
;
|
||||
//
|
||||
// ProDOS routines
|
||||
//
|
||||
def getpfx(path)
|
||||
byte params[3]
|
||||
|
||||
@ -719,9 +719,9 @@ def read(refnum, buff, len)
|
||||
perr = syscall($CA, @params)
|
||||
return params:6
|
||||
end
|
||||
;
|
||||
; Heap routines.
|
||||
;
|
||||
//
|
||||
// Heap routines.
|
||||
//
|
||||
def availheap
|
||||
byte fp
|
||||
return @fp - heap
|
||||
@ -761,11 +761,11 @@ def allocalignheap(size, pow2, freeaddr)
|
||||
return addr
|
||||
end
|
||||
def markheap
|
||||
return heap;
|
||||
return heap//
|
||||
end
|
||||
def releaseheap(newheap)
|
||||
heap = newheap;
|
||||
return @newheap - heap;
|
||||
heap = newheap//
|
||||
return @newheap - heap//
|
||||
end
|
||||
def allocxheap(size)
|
||||
word xaddr
|
||||
@ -800,9 +800,9 @@ def allocxheap(size)
|
||||
fin
|
||||
return xaddr
|
||||
end
|
||||
;
|
||||
; Symbol table routines.
|
||||
;
|
||||
//
|
||||
// Symbol table routines.
|
||||
//
|
||||
def lookupsym(sym)
|
||||
return lookuptbl(sym, symtbl)
|
||||
end
|
||||
@ -817,9 +817,9 @@ def addsym(sym, addr)
|
||||
lastsym = lastsym + 3
|
||||
^lastsym = 0
|
||||
end
|
||||
;
|
||||
; Module routines.
|
||||
;
|
||||
//
|
||||
// Module routines.
|
||||
//
|
||||
def lookupmod(mod)
|
||||
byte dci[17]
|
||||
return lookuptbl(modtosym(mod, @dci), symtbl)
|
||||
@ -858,13 +858,13 @@ def adddef(bank, addr, deflast)
|
||||
defentry = *deflast
|
||||
*deflast = defentry + 5
|
||||
if bank
|
||||
defentry=>1 = $03DC ; JSR $03DC (AUX MEM INTERP)
|
||||
defentry=>1 = $03DC // JSR $03DC (AUX MEM INTERP)
|
||||
else
|
||||
defentry=>1 = $03D6 ; JSR $03D6 (MAIN MEM INTERP)
|
||||
defentry=>1 = $03D6 // JSR $03D6 (MAIN MEM INTERP)
|
||||
fin
|
||||
defentry->0 = $20
|
||||
defentry=>3 = addr
|
||||
defentry->5 = 0 ; NULL out next entry
|
||||
defentry->5 = 0 // NULL out next entry
|
||||
return defentry
|
||||
end
|
||||
def lookupdef(addr, deftbl)
|
||||
@ -883,9 +883,9 @@ def loadmod(mod)
|
||||
word moddep, rld, esd, sym
|
||||
byte defbank, str[16], filename[64]
|
||||
byte header[128]
|
||||
;
|
||||
; Read the RELocatable module header (first 128 bytes)
|
||||
;
|
||||
//
|
||||
// Read the RELocatable module header (first 128 bytes)
|
||||
//
|
||||
dcitos(mod, @filename)
|
||||
refnum = open(@filename, iobuffer)
|
||||
if refnum > 0
|
||||
@ -894,18 +894,18 @@ def loadmod(mod)
|
||||
moddep = @header.1
|
||||
defofst = modsize
|
||||
init = 0
|
||||
if rdlen > 4 and header:2 == $DA7E ; DAVE = magic number :-)
|
||||
;
|
||||
; This is an EXTended RELocatable (data+bytecode) module.
|
||||
;
|
||||
if rdlen > 4 and header:2 == $DA7E // DAVE = magic number :-)
|
||||
//
|
||||
// This is an EXTended RELocatable (data+bytecode) module.
|
||||
//
|
||||
systemflags = header:4 | systemflags
|
||||
defofst = header:6
|
||||
defcnt = header:8
|
||||
init = header:10
|
||||
moddep = @header.12
|
||||
;
|
||||
; Load module dependencies.
|
||||
;
|
||||
//
|
||||
// Load module dependencies.
|
||||
//
|
||||
while ^moddep
|
||||
if !lookupmod(moddep)
|
||||
close(refnum)
|
||||
@ -916,57 +916,57 @@ def loadmod(mod)
|
||||
fin
|
||||
moddep = moddep + dcitos(moddep, @str)
|
||||
loop
|
||||
;
|
||||
; Init def table.
|
||||
;
|
||||
//
|
||||
// Init def table.
|
||||
//
|
||||
deftbl = allocheap(defcnt * 5 + 1)
|
||||
deflast = deftbl
|
||||
^deflast = 0
|
||||
if !refnum
|
||||
;
|
||||
; Reset read pointer.
|
||||
;
|
||||
//
|
||||
// Reset read pointer.
|
||||
//
|
||||
refnum = open(@filename, iobuffer)
|
||||
rdlen = read(refnum, @header, 128)
|
||||
fin
|
||||
fin
|
||||
;
|
||||
; Alloc heap space for relocated module (data + bytecode).
|
||||
;
|
||||
//
|
||||
// Alloc heap space for relocated module (data + bytecode).
|
||||
//
|
||||
moddep = moddep + 1
|
||||
modfix = moddep - @header.2 ; Adjust to skip header
|
||||
modfix = moddep - @header.2 // Adjust to skip header
|
||||
modsize = modsize - modfix
|
||||
rdlen = rdlen - modfix - 2
|
||||
modaddr = allocheap(modsize)
|
||||
memcpy(modaddr, moddep, rdlen)
|
||||
;
|
||||
; Read in remainder of module into memory for fixups.
|
||||
;
|
||||
addr = modaddr;
|
||||
//
|
||||
// Read in remainder of module into memory for fixups.
|
||||
//
|
||||
addr = modaddr//
|
||||
repeat
|
||||
addr = addr + rdlen
|
||||
rdlen = read(refnum, addr, 4096)
|
||||
until rdlen <= 0
|
||||
close(refnum)
|
||||
;
|
||||
; Add module to symbol table.
|
||||
;
|
||||
//
|
||||
// Add module to symbol table.
|
||||
//
|
||||
addmod(mod, modaddr)
|
||||
;
|
||||
; Apply all fixups and symbol import/export.
|
||||
;
|
||||
//
|
||||
// Apply all fixups and symbol import/export.
|
||||
//
|
||||
modfix = modaddr - modfix
|
||||
bytecode = defofst + modfix - MODADDR
|
||||
modend = modaddr + modsize
|
||||
rld = modend ; Re-Locatable Directory
|
||||
esd = rld ; Extern+Entry Symbol Directory
|
||||
while ^esd ; Scan to end of ESD
|
||||
rld = modend // Re-Locatable Directory
|
||||
esd = rld // Extern+Entry Symbol Directory
|
||||
while ^esd // Scan to end of ESD
|
||||
esd = esd + 4
|
||||
loop
|
||||
esd = esd + 1
|
||||
;
|
||||
; Locate bytecode defs in appropriate bank.
|
||||
;
|
||||
//
|
||||
// Locate bytecode defs in appropriate bank.
|
||||
//
|
||||
if ^MACHID & $30 == $30
|
||||
defbank = 1
|
||||
defaddr = allocxheap(rld - bytecode)
|
||||
@ -975,58 +975,58 @@ def loadmod(mod)
|
||||
defbank = 0
|
||||
defaddr = bytecode
|
||||
fin
|
||||
;
|
||||
; Run through the Re-Location Dictionary.
|
||||
;
|
||||
//
|
||||
// Run through the Re-Location Dictionary.
|
||||
//
|
||||
while ^rld
|
||||
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)
|
||||
else
|
||||
addr = rld=>1 + modfix
|
||||
if uword_isge(addr, modaddr) ; Skip fixups to header
|
||||
if ^rld & $80 ; WORD sized fixup.
|
||||
if uword_isge(addr, modaddr) // Skip fixups to header
|
||||
if ^rld & $80 // WORD sized fixup.
|
||||
fixup = *addr
|
||||
else ; BYTE sized fixup.
|
||||
else // BYTE sized fixup.
|
||||
fixup = ^addr
|
||||
fin
|
||||
if ^rld & $10 ; EXTERN reference.
|
||||
if ^rld & $10 // EXTERN reference.
|
||||
fixup = fixup + lookupextern(esd, rld->3)
|
||||
else ; INTERN fixup.
|
||||
else // INTERN fixup.
|
||||
fixup = fixup + modfix - MODADDR
|
||||
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)
|
||||
fin
|
||||
fin
|
||||
if ^rld & $80 ; WORD sized fixup.
|
||||
if ^rld & $80 // WORD sized fixup.
|
||||
*addr = fixup
|
||||
else ; BYTE sized fixup.
|
||||
else // BYTE sized fixup.
|
||||
^addr = fixup
|
||||
fin
|
||||
fin
|
||||
fin
|
||||
rld = rld + 4
|
||||
loop
|
||||
;
|
||||
; Run through the External/Entry Symbol Directory.
|
||||
;
|
||||
//
|
||||
// Run through the External/Entry Symbol Directory.
|
||||
//
|
||||
while ^esd
|
||||
sym = esd
|
||||
esd = esd + dcitos(esd, @str)
|
||||
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
|
||||
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)
|
||||
fin
|
||||
addsym(sym, addr)
|
||||
@ -1034,18 +1034,18 @@ def loadmod(mod)
|
||||
esd = esd + 3
|
||||
loop
|
||||
if defbank
|
||||
;
|
||||
; Move bytecode to AUX bank.
|
||||
;
|
||||
//
|
||||
// Move bytecode to AUX bank.
|
||||
//
|
||||
memxcpy(defaddr, bytecode, modsize - (bytecode - modaddr))
|
||||
fin
|
||||
fin
|
||||
if perr
|
||||
return -perr
|
||||
fin
|
||||
;
|
||||
; Call init routine if it exists.
|
||||
;
|
||||
//
|
||||
// Call init routine if it exists.
|
||||
//
|
||||
if init
|
||||
fixup = adddef(defbank, init - defofst + defaddr, @deflast)()
|
||||
if defbank
|
||||
@ -1056,15 +1056,15 @@ def loadmod(mod)
|
||||
else
|
||||
fixup = 0
|
||||
fin
|
||||
;
|
||||
; Free up the end-of-module in main memory.
|
||||
;
|
||||
//
|
||||
// Free up the end-of-module in main memory.
|
||||
//
|
||||
releaseheap(modend)
|
||||
return fixup
|
||||
end
|
||||
;
|
||||
; Command mode
|
||||
;
|
||||
//
|
||||
// Command mode
|
||||
//
|
||||
def volumes
|
||||
byte params[4]
|
||||
word strbuf
|
||||
@ -1120,7 +1120,7 @@ def catalog(optpath)
|
||||
len = type & $0F
|
||||
^entry = len
|
||||
prstr(entry)
|
||||
if type & $F0 == $D0 ; Is it a directory?
|
||||
if type & $F0 == $D0 // Is it a directory?
|
||||
cout('/')
|
||||
len = len + 1
|
||||
elsif entry->$10 == $FF
|
||||
@ -1186,14 +1186,14 @@ def parsecmd(strptr)
|
||||
return cmd
|
||||
end
|
||||
def resetmemfiles
|
||||
;
|
||||
; Close all files
|
||||
;
|
||||
//
|
||||
// Close all files
|
||||
//
|
||||
^$BFD8 = 0
|
||||
close(0)
|
||||
;
|
||||
; Set memory bitmap
|
||||
;
|
||||
//
|
||||
// Set memory bitmap
|
||||
//
|
||||
memset($BF58, 24, 0)
|
||||
^$BF58 = $CF
|
||||
^$BF6F = $01
|
||||
@ -1240,13 +1240,13 @@ def execmod(modfile)
|
||||
heap = saveheap
|
||||
fin
|
||||
end
|
||||
;
|
||||
; Get heap start.
|
||||
;
|
||||
//
|
||||
// Get heap start.
|
||||
//
|
||||
heap = *freemem
|
||||
;
|
||||
; Init symbol table.
|
||||
;
|
||||
//
|
||||
// Init symbol table.
|
||||
//
|
||||
stodci(@stdlibstr, heap)
|
||||
addmod(heap, @version)
|
||||
while *stdlibsym
|
||||
@ -1254,15 +1254,15 @@ while *stdlibsym
|
||||
addsym(heap, stdlibsym=>2)
|
||||
stdlibsym = stdlibsym + 4
|
||||
loop
|
||||
;
|
||||
; Try to run autorun module.
|
||||
;
|
||||
//
|
||||
// Try to run autorun module.
|
||||
//
|
||||
resetmemfiles()
|
||||
execmod(@autorun)
|
||||
perr = 0
|
||||
;
|
||||
; Print some startup info.
|
||||
;
|
||||
//
|
||||
// Print some startup info.
|
||||
//
|
||||
prstr(@verstr)
|
||||
prbyte(version.1)
|
||||
cout('.')
|
||||
|
@ -1,24 +1,24 @@
|
||||
const membank = $FFEF
|
||||
const MODADDR = $1000
|
||||
;
|
||||
; SOS flags
|
||||
;
|
||||
//
|
||||
// SOS flags
|
||||
//
|
||||
const O_READ = 1
|
||||
const O_WRITE = 2
|
||||
const O_READ_WRITE = 3
|
||||
;
|
||||
; Pedefined functions.
|
||||
;
|
||||
//
|
||||
// Pedefined functions.
|
||||
//
|
||||
predef crout, cout, prstr, cin, rdstr
|
||||
predef syscall, call
|
||||
predef markheap, allocheap, allocalignheap, releaseheap, availheap
|
||||
predef memset, memcpy
|
||||
predef uword_isgt, uword_isge, uword_islt, uword_isle
|
||||
predef loadmod, execmod, lookupstrmod
|
||||
;
|
||||
; System variables.
|
||||
;
|
||||
word version = $0010 ; 00.10
|
||||
//
|
||||
// System variables.
|
||||
//
|
||||
word version = $0010 // 00.10
|
||||
word systemflags = 0
|
||||
byte refcons = 0
|
||||
byte devcons = 0
|
||||
@ -28,13 +28,13 @@ byte modseg[15]
|
||||
word symtbl, lastsym
|
||||
byte perr, terr, lerr
|
||||
word cmdptr
|
||||
;
|
||||
; Exported Machine ID.
|
||||
;
|
||||
byte machid = $F2 ; Apple ///, 80 columns
|
||||
;
|
||||
; Standard Library exported functions.
|
||||
;
|
||||
//
|
||||
// Exported Machine ID.
|
||||
//
|
||||
byte machid = $F2 // Apple ///, 80 columns
|
||||
//
|
||||
// Standard Library exported functions.
|
||||
//
|
||||
byte stdlibstr[] = "STDLIB"
|
||||
byte machidstr[] = "MACHID"
|
||||
byte sysstr[] = "SYSCALL"
|
||||
@ -81,9 +81,9 @@ word = @modadrstr, @lookupstrmod
|
||||
word = @machidstr, @machid
|
||||
word = 0
|
||||
word stdlibsym = @exports
|
||||
;
|
||||
; String pool.
|
||||
;
|
||||
//
|
||||
// String pool.
|
||||
//
|
||||
byte console[] = ".CONSOLE"
|
||||
byte autorun[] = "AUTORUN"
|
||||
byte verstr[] = "PLASMA "
|
||||
@ -95,10 +95,10 @@ byte devtovol[] = " => /"
|
||||
byte prefix[128] = ""
|
||||
byte textmode[] = 16, 0, 15
|
||||
byte hexchar[] = '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
|
||||
;
|
||||
; CALL SOS
|
||||
; SYSCALL(CMD, PARAMS)
|
||||
;
|
||||
//
|
||||
// CALL SOS
|
||||
// SYSCALL(CMD, PARAMS)
|
||||
//
|
||||
asm syscall
|
||||
LDA ESTKL,X
|
||||
LDY ESTKH,X
|
||||
@ -115,10 +115,10 @@ PARAMS !WORD 0000
|
||||
STY ESTKH,X
|
||||
RTS
|
||||
end
|
||||
;
|
||||
; CALL 6502 ROUTINE
|
||||
; CALL(AREG, XREG, YREG, STATUS, ADDR)
|
||||
;
|
||||
//
|
||||
// CALL 6502 ROUTINE
|
||||
// CALL(AREG, XREG, YREG, STATUS, ADDR)
|
||||
//
|
||||
asm call
|
||||
REGVALS = SRC
|
||||
PHP
|
||||
@ -157,11 +157,11 @@ REGVALS = SRC
|
||||
RTS
|
||||
JMPTMP JMP (TMP)
|
||||
end
|
||||
;
|
||||
; SET MEMORY TO VALUE
|
||||
; MEMSET(ADDR, SIZE, VALUE)
|
||||
; With optimizations from Peter Ferrie
|
||||
;
|
||||
//
|
||||
// SET MEMORY TO VALUE
|
||||
// MEMSET(ADDR, SIZE, VALUE)
|
||||
// With optimizations from Peter Ferrie
|
||||
//
|
||||
asm memset
|
||||
LDY #$00
|
||||
LDA ESTKL+2,X
|
||||
@ -188,10 +188,10 @@ SETMEX INX
|
||||
INX
|
||||
RTS
|
||||
end
|
||||
;
|
||||
; COPY MEMORY
|
||||
; MEMCPY(DSTADDR, SRCADDR, SIZE)
|
||||
;
|
||||
//
|
||||
// COPY MEMORY
|
||||
// MEMCPY(DSTADDR, SRCADDR, SIZE)
|
||||
//
|
||||
asm memcpy
|
||||
INX
|
||||
INX
|
||||
@ -261,11 +261,11 @@ REVCPYLP LDA (SRC),Y
|
||||
BNE REVCPYLP
|
||||
CPYMEX RTS
|
||||
end
|
||||
;
|
||||
; COPY FROM MAIN MEM TO EXT MEM.
|
||||
;
|
||||
; MEMXCPY(DSTSEG, SRC, SIZE)
|
||||
;
|
||||
//
|
||||
// COPY FROM MAIN MEM TO EXT MEM.
|
||||
//
|
||||
// MEMXCPY(DSTSEG, SRC, SIZE)
|
||||
//
|
||||
asm memxcpy
|
||||
LDA ESTKL,X
|
||||
ORA ESTKH,X
|
||||
@ -301,11 +301,11 @@ CPYXMEX INX
|
||||
INX
|
||||
RTS
|
||||
end
|
||||
;
|
||||
; POKE BYTE VAL INTO EXT MEM.
|
||||
;
|
||||
; XPOKEB(SEG, DST, BYTEVAL)
|
||||
;
|
||||
//
|
||||
// POKE BYTE VAL INTO EXT MEM.
|
||||
//
|
||||
// XPOKEB(SEG, DST, BYTEVAL)
|
||||
//
|
||||
asm xpokeb
|
||||
LDA ESTKL+1,X
|
||||
STA DSTL
|
||||
@ -325,9 +325,9 @@ asm xpokeb
|
||||
INX
|
||||
RTS
|
||||
end
|
||||
;
|
||||
; Unsigned word comparisons.
|
||||
;
|
||||
//
|
||||
// Unsigned word comparisons.
|
||||
//
|
||||
asm uword_isge
|
||||
LDY #$00
|
||||
LDA ESTKL+1,X
|
||||
@ -378,9 +378,9 @@ asm uword_islt
|
||||
INX
|
||||
RTS
|
||||
end
|
||||
;
|
||||
; Addresses of internal routines.
|
||||
;
|
||||
//
|
||||
// Addresses of internal routines.
|
||||
//
|
||||
asm interp
|
||||
DEX
|
||||
LDA #<XINTERP
|
||||
@ -389,21 +389,21 @@ asm interp
|
||||
STA ESTKH,X
|
||||
RTS
|
||||
end
|
||||
;
|
||||
; A DCI string is one that has the high bit set for every character except the last.
|
||||
; More efficient than C or Pascal strings.
|
||||
;
|
||||
;def dcitos(dci, str)
|
||||
; byte len, c
|
||||
; len = 0
|
||||
; repeat
|
||||
; c = (dci).[len]
|
||||
; len = len + 1
|
||||
; (str).[len] = c & $7F
|
||||
; until !(c & $80)
|
||||
; ^str = len
|
||||
; return len
|
||||
;end
|
||||
//
|
||||
// A DCI string is one that has the high bit set for every character except the last.
|
||||
// More efficient than C or Pascal strings.
|
||||
//
|
||||
//def dcitos(dci, str)
|
||||
// byte len, c
|
||||
// len = 0
|
||||
// repeat
|
||||
// c = (dci).[len]
|
||||
// len = len + 1
|
||||
// (str).[len] = c & $7F
|
||||
// until !(c & $80)
|
||||
// ^str = len
|
||||
// return len
|
||||
//end
|
||||
asm dcitos
|
||||
LDA ESTKL,X
|
||||
STA DSTL
|
||||
@ -428,22 +428,22 @@ asm dcitos
|
||||
STY ESTKH,X
|
||||
RTS
|
||||
end
|
||||
;def stodci(str, dci)
|
||||
; byte len, c
|
||||
; len = ^str
|
||||
; if len == 0
|
||||
; return
|
||||
; fin
|
||||
; c = toupper((str).[len]) & $7F
|
||||
; len = len - 1
|
||||
; (dci).[len] = c
|
||||
; while len
|
||||
; c = toupper((str).[len]) | $80
|
||||
; len = len - 1
|
||||
; (dci).[len] = c
|
||||
; loop
|
||||
; return ^str
|
||||
;end
|
||||
//def stodci(str, dci)
|
||||
// byte len, c
|
||||
// len = ^str
|
||||
// if len == 0
|
||||
// return
|
||||
// fin
|
||||
// c = toupper((str).[len]) & $7F
|
||||
// len = len - 1
|
||||
// (dci).[len] = c
|
||||
// while len
|
||||
// c = toupper((str).[len]) | $80
|
||||
// len = len - 1
|
||||
// (dci).[len] = c
|
||||
// loop
|
||||
// return ^str
|
||||
//end
|
||||
asm stodci
|
||||
LDA ESTKL,X
|
||||
STA DSTL
|
||||
@ -483,22 +483,22 @@ TOUPR AND #$7F
|
||||
+ STA ESTKL,X
|
||||
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
|
||||
//
|
||||
// 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
|
||||
LDA ESTKL+1,X
|
||||
STA SRCL
|
||||
@ -520,26 +520,26 @@ asm modtosym
|
||||
BCS -
|
||||
RTS
|
||||
end
|
||||
;
|
||||
; Lookup routines.
|
||||
;
|
||||
;def lookuptbl(dci, tbl)
|
||||
; word match
|
||||
; while ^tbl
|
||||
; match = dci
|
||||
; while ^tbl == ^match
|
||||
; if !(^tbl & $80)
|
||||
; return (tbl):1
|
||||
; fin
|
||||
; tbl = tbl + 1
|
||||
; match = match + 1
|
||||
; loop
|
||||
; while (^tbl & $80)
|
||||
; tbl = tbl + 1
|
||||
; loop
|
||||
; tbl = tbl + 3
|
||||
; loop
|
||||
; return 0
|
||||
//
|
||||
// Lookup routines.
|
||||
//
|
||||
//def lookuptbl(dci, tbl)
|
||||
// word match
|
||||
// while ^tbl
|
||||
// match = dci
|
||||
// while ^tbl == ^match
|
||||
// if !(^tbl & $80)
|
||||
// return (tbl):1
|
||||
// fin
|
||||
// tbl = tbl + 1
|
||||
// match = match + 1
|
||||
// loop
|
||||
// while (^tbl & $80)
|
||||
// tbl = tbl + 1
|
||||
// loop
|
||||
// tbl = tbl + 3
|
||||
// loop
|
||||
// return 0
|
||||
asm lookuptbl
|
||||
LDY #$00
|
||||
STY DSTL
|
||||
@ -588,10 +588,10 @@ asm lookuptbl
|
||||
INC DSTH
|
||||
BCS -
|
||||
end
|
||||
;
|
||||
; SOS routines
|
||||
; FILE I/O
|
||||
;
|
||||
//
|
||||
// SOS routines
|
||||
// FILE I/O
|
||||
//
|
||||
def getpfx(path)
|
||||
byte params[4]
|
||||
|
||||
@ -663,9 +663,9 @@ def write(refnum, buff, len)
|
||||
perr = syscall($CB, @params)
|
||||
return perr
|
||||
end
|
||||
;
|
||||
; DEVICE I/O
|
||||
;
|
||||
//
|
||||
// DEVICE I/O
|
||||
//
|
||||
def dev_control(devnum, code, list)
|
||||
byte params[5]
|
||||
|
||||
@ -696,9 +696,9 @@ def dev_info(devnum, name, list, listlen)
|
||||
perr = syscall($85, @params)
|
||||
return perr
|
||||
end
|
||||
;
|
||||
; MEMORY CALLS
|
||||
;
|
||||
//
|
||||
// MEMORY CALLS
|
||||
//
|
||||
def seg_request(base, limit, id)
|
||||
byte params[7]
|
||||
|
||||
@ -733,9 +733,9 @@ def seg_release(segnum)
|
||||
perr = syscall($45, @params)
|
||||
return perr
|
||||
end
|
||||
;
|
||||
; Other SOS calls.
|
||||
;
|
||||
//
|
||||
// Other SOS calls.
|
||||
//
|
||||
def quit
|
||||
byte params[1]
|
||||
|
||||
@ -744,9 +744,9 @@ def quit
|
||||
perr = syscall($65, @params)
|
||||
end
|
||||
|
||||
;
|
||||
; CONSOLE I/O
|
||||
;
|
||||
//
|
||||
// CONSOLE I/O
|
||||
//
|
||||
def init_cons
|
||||
byte nlmode[2]
|
||||
if !refcons
|
||||
@ -797,9 +797,9 @@ def prword(v)
|
||||
prbyte(v >> 8)
|
||||
return prbyte(v)
|
||||
end
|
||||
;
|
||||
; Heap routines.
|
||||
;
|
||||
//
|
||||
// Heap routines.
|
||||
//
|
||||
def availheap
|
||||
byte fp
|
||||
return @fp - heap
|
||||
@ -827,15 +827,15 @@ def allocalignheap(size, pow2, freeaddr)
|
||||
return addr
|
||||
end
|
||||
def markheap
|
||||
return heap;
|
||||
return heap//
|
||||
end
|
||||
def releaseheap(newheap)
|
||||
heap = newheap;
|
||||
return @newheap - heap;
|
||||
heap = newheap//
|
||||
return @newheap - heap//
|
||||
end
|
||||
;
|
||||
; Symbol table routines.
|
||||
;
|
||||
//
|
||||
// Symbol table routines.
|
||||
//
|
||||
def lookupsym(sym)
|
||||
return lookuptbl(sym, symtbl)
|
||||
end
|
||||
@ -851,9 +851,9 @@ def addsym(sym, addr)
|
||||
xpokeb(symtbl.0, lastsym + 3, 0)
|
||||
lastsym = lastsym + 3
|
||||
end
|
||||
;
|
||||
; Module routines.
|
||||
;
|
||||
//
|
||||
// Module routines.
|
||||
//
|
||||
def lookupmod(mod)
|
||||
byte dci[17]
|
||||
return lookuptbl(modtosym(mod, @dci), symtbl)
|
||||
@ -894,7 +894,7 @@ def adddef(ext, addr, deflast)
|
||||
defentry->0 = $20
|
||||
defentry=>1 = interp
|
||||
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
|
||||
end
|
||||
def lookupdef(addr, deftbl)
|
||||
@ -914,9 +914,9 @@ def loadmod(mod)
|
||||
byte defext, str[16], filename[33]
|
||||
byte header[128]
|
||||
lerr = 0
|
||||
;
|
||||
; Read the RELocatable module header (first 128 bytes)
|
||||
;
|
||||
//
|
||||
// Read the RELocatable module header (first 128 bytes)
|
||||
//
|
||||
dcitos(mod, @filename)
|
||||
refnum = open(@filename, O_READ)
|
||||
if refnum > 0
|
||||
@ -925,18 +925,18 @@ def loadmod(mod)
|
||||
moddep = @header.1
|
||||
defofst = modsize
|
||||
init = 0
|
||||
if rdlen > 4 and header:2 == $DA7E ; DAVE = magic number :-)
|
||||
;
|
||||
; This is an EXTended RELocatable (data+bytecode) module.
|
||||
;
|
||||
if rdlen > 4 and header:2 == $DA7E // DAVE = magic number :-)
|
||||
//
|
||||
// This is an EXTended RELocatable (data+bytecode) module.
|
||||
//
|
||||
systemflags = header:4 | systemflags
|
||||
defofst = header:6
|
||||
defcnt = header:8
|
||||
init = header:10
|
||||
moddep = @header.12
|
||||
;
|
||||
; Load module dependencies.
|
||||
;
|
||||
//
|
||||
// Load module dependencies.
|
||||
//
|
||||
while ^moddep
|
||||
if !lookupmod(moddep)
|
||||
close(refnum)
|
||||
@ -947,57 +947,57 @@ def loadmod(mod)
|
||||
fin
|
||||
moddep = moddep + dcitos(moddep, @str)
|
||||
loop
|
||||
;
|
||||
; Init def table.
|
||||
;
|
||||
//
|
||||
// Init def table.
|
||||
//
|
||||
deftbl = allocheap(defcnt * 6 + 1)
|
||||
deflast = deftbl
|
||||
^deflast = 0
|
||||
if !refnum
|
||||
;
|
||||
; Reset read pointer.
|
||||
;
|
||||
//
|
||||
// Reset read pointer.
|
||||
//
|
||||
refnum = open(@filename, O_READ)
|
||||
rdlen = read(refnum, @header, 128)
|
||||
fin
|
||||
fin
|
||||
;
|
||||
; Alloc heap space for relocated module (data + bytecode).
|
||||
;
|
||||
//
|
||||
// Alloc heap space for relocated module (data + bytecode).
|
||||
//
|
||||
moddep = moddep + 1
|
||||
modfix = moddep - @header.2 ; Adjust to skip header
|
||||
modfix = moddep - @header.2 // Adjust to skip header
|
||||
modsize = modsize - modfix
|
||||
rdlen = rdlen - modfix - 2
|
||||
modaddr = allocheap(modsize)
|
||||
memcpy(modaddr, moddep, rdlen)
|
||||
;
|
||||
; Read in remainder of module into memory for fixups.
|
||||
;
|
||||
addr = modaddr;
|
||||
//
|
||||
// Read in remainder of module into memory for fixups.
|
||||
//
|
||||
addr = modaddr//
|
||||
repeat
|
||||
addr = addr + rdlen
|
||||
rdlen = read(refnum, addr, 4096)
|
||||
until rdlen <= 0
|
||||
close(refnum)
|
||||
;
|
||||
; Add module to symbol table.
|
||||
;
|
||||
//
|
||||
// Add module to symbol table.
|
||||
//
|
||||
addmod(mod, modaddr)
|
||||
;
|
||||
; Apply all fixups and symbol import/export.
|
||||
;
|
||||
//
|
||||
// Apply all fixups and symbol import/export.
|
||||
//
|
||||
modfix = modaddr - modfix
|
||||
bytecode = defofst + modfix - MODADDR
|
||||
modend = modaddr + modsize
|
||||
rld = modend ; Re-Locatable Directory
|
||||
esd = rld ; Extern+Entry Symbol Directory
|
||||
while ^esd ; Scan to end of ESD
|
||||
rld = modend // Re-Locatable Directory
|
||||
esd = rld // Extern+Entry Symbol Directory
|
||||
while ^esd // Scan to end of ESD
|
||||
esd = esd + 4
|
||||
loop
|
||||
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)
|
||||
if perr
|
||||
return -perr
|
||||
@ -1005,58 +1005,58 @@ def loadmod(mod)
|
||||
modid = modid + 1
|
||||
defext = (codeseg.0 | $80) - 1
|
||||
defaddr = (codeseg & $FF00) + $6000
|
||||
;
|
||||
; Run through the Re-Location Dictionary.
|
||||
;
|
||||
//
|
||||
// Run through the Re-Location Dictionary.
|
||||
//
|
||||
while ^rld
|
||||
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)
|
||||
else
|
||||
addr = rld=>1 + modfix
|
||||
if uword_isge(addr, modaddr) ; Skip fixups to header
|
||||
if ^rld & $80 ; WORD sized fixup.
|
||||
if uword_isge(addr, modaddr) // Skip fixups to header
|
||||
if ^rld & $80 // WORD sized fixup.
|
||||
fixup = *addr
|
||||
else ; BYTE sized fixup.
|
||||
else // BYTE sized fixup.
|
||||
fixup = ^addr
|
||||
fin
|
||||
if ^rld & $10 ; EXTERN reference.
|
||||
if ^rld & $10 // EXTERN reference.
|
||||
fixup = fixup + lookupextern(esd, rld->3)
|
||||
else ; INTERN fixup.
|
||||
else // INTERN fixup.
|
||||
fixup = fixup + modfix - MODADDR
|
||||
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)
|
||||
fin
|
||||
fin
|
||||
if ^rld & $80 ; WORD sized fixup.
|
||||
if ^rld & $80 // WORD sized fixup.
|
||||
*addr = fixup
|
||||
else ; BYTE sized fixup.
|
||||
else // BYTE sized fixup.
|
||||
^addr = fixup
|
||||
fin
|
||||
fin
|
||||
fin
|
||||
rld = rld + 4
|
||||
loop
|
||||
;
|
||||
; Run through the External/Entry Symbol Directory.
|
||||
;
|
||||
//
|
||||
// Run through the External/Entry Symbol Directory.
|
||||
//
|
||||
while ^esd
|
||||
sym = esd
|
||||
esd = esd + dcitos(esd, @str)
|
||||
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
|
||||
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)
|
||||
fin
|
||||
addsym(sym, addr)
|
||||
@ -1064,14 +1064,14 @@ def loadmod(mod)
|
||||
esd = esd + 3
|
||||
loop
|
||||
if defext
|
||||
;
|
||||
; Copy bytecode to code segment.
|
||||
;
|
||||
//
|
||||
// Copy bytecode to code segment.
|
||||
//
|
||||
memxcpy(codeseg, bytecode, modsize - (bytecode - modaddr))
|
||||
fin
|
||||
;
|
||||
; Free up end-of-module main memory.
|
||||
;
|
||||
//
|
||||
// Free up end-of-module main memory.
|
||||
//
|
||||
releaseheap(bytecode)
|
||||
else
|
||||
return -perr
|
||||
@ -1079,9 +1079,9 @@ def loadmod(mod)
|
||||
if lerr
|
||||
return -lerr
|
||||
fin
|
||||
;
|
||||
; Call init routine if it exists.
|
||||
;
|
||||
//
|
||||
// Call init routine if it exists.
|
||||
//
|
||||
if init
|
||||
fixup = adddef(defext, init - defofst + defaddr, @deflast)()
|
||||
else
|
||||
@ -1089,9 +1089,9 @@ def loadmod(mod)
|
||||
fin
|
||||
return fixup
|
||||
end
|
||||
;
|
||||
; Command mode
|
||||
;
|
||||
//
|
||||
// Command mode
|
||||
//
|
||||
def volumes
|
||||
byte info[11]
|
||||
byte devname[17]
|
||||
@ -1147,7 +1147,7 @@ def catalog(optpath)
|
||||
len = type & $0F
|
||||
^entry = len
|
||||
prstr(entry)
|
||||
if type & $F0 == $D0 ; Is it a directory?
|
||||
if type & $F0 == $D0 // Is it a directory?
|
||||
cout('/')
|
||||
len = len + 1
|
||||
elsif entry->$10 == $FF
|
||||
@ -1231,13 +1231,13 @@ def execmod(modfile)
|
||||
loop
|
||||
fin
|
||||
end
|
||||
;
|
||||
; Init console.
|
||||
;
|
||||
//
|
||||
// Init console.
|
||||
//
|
||||
init_cons
|
||||
;
|
||||
; Init 2K symbol table.
|
||||
;
|
||||
//
|
||||
// Init 2K symbol table.
|
||||
//
|
||||
seg_find($00, @symtbl, @lastsym, $08, $11)
|
||||
lastsym = symtbl & $FF00
|
||||
xpokeb(symtbl.0, lastsym, 0)
|
||||
@ -1248,14 +1248,14 @@ while *stdlibsym
|
||||
addsym(heap, stdlibsym=>2)
|
||||
stdlibsym = stdlibsym + 4
|
||||
loop
|
||||
;
|
||||
; Try to run autorun module.
|
||||
;
|
||||
//
|
||||
// Try to run autorun module.
|
||||
//
|
||||
execmod(@autorun)
|
||||
perr = 0
|
||||
;
|
||||
; Print some startup info.
|
||||
;
|
||||
//
|
||||
// Print some startup info.
|
||||
//
|
||||
prstr(@verstr)
|
||||
prbyte(version.1)
|
||||
cout('.')
|
||||
@ -1264,9 +1264,9 @@ crout
|
||||
prstr(@freestr)
|
||||
prword(availheap)
|
||||
crout
|
||||
;
|
||||
; Handle commands.
|
||||
;
|
||||
//
|
||||
// Handle commands.
|
||||
//
|
||||
while 1
|
||||
prstr(getpfx(@prefix))
|
||||
cmdptr = rdstr($BA)
|
||||
|
Loading…
x
Reference in New Issue
Block a user