TriOS-alt/system/regnatix/basic.spin

1248 lines
77 KiB
Plaintext

{{
Modified Tiny Basic for use with Propeller Demo Board and Hydra.
Original Tiny Basic written by Tomas Rokicki & Radical Eye Software.
Copyright (c) 2008 Michael Green. See end of file for terms of use.
}}
'' Note: There are three places in the next 50 lines where there are
'' pairs of lines with one commented out. One is marked TV
'' and the other is marked VGA. All three places should have
'' the appropriate line commented out for the display being used.
'' The combination of Hydra and VGA is not supported because the
'' I/O pins used for the SD card and the VGA display conflict.
{{ ---------------------------------------------------------------------------------------------------------
Hive-Computer-Projekt
Name : FemtoBasic
Chip : Regnatix-Code
Version : 0.1
Dateien :
Beschreibung : Modifiziertes FemtoBasic für den Hive.
Eigenschaften :
Logbuch :
29.04.2009 - erste an ios angepasste version
- eeprom-zugriff deaktiviert
Notizen:
--------------------------------------------------------------------------------------------------------- }}
obj
ios : "ios.spin"
con
_CLKMODE = XTAL1 + PLL16X
_XINFREQ = 5_000_000
version = 3 ' Major version
release = 006 ' Minor release
testLevel = 0 ' Test change level
' progsize = 8192 ' Space reserved for program
progsize = $3FFF
_stack = 100 ' Roughly 4 nested expressions
_free = (progsize + 12) / 4
bspKey = $C8 ' PS/2 keyboard backspace key
breakKey = $CB ' PS/2 keyboard escape key
backspace = 8
fReturn = 13
fLinefeed = 10
fEof = $FF
maxstack = 20 ' Maximum stack depth
linelen = 256 ' Maximum input line length
quote = 34 ' Double quote
caseBit = !32 ' Uppercase/Lowercase bit
' userPtr = $7FEC ' Pointer to program memory
userPtr = $4000
var
long sp, tp, eop, nextlineloc, rv, curlineno, pauseTime
long vars[26], stack[maxstack], control[2]
long forStep[26], forLimit[26], forLoop[26]
long ioControl[2]
word outputs
byte tline[linelen], tailLine[linelen], inVars[26], fileOpened
dat
tok0 byte "IF", 0
tok1 byte "THEN", 0
tok2 byte "INPUT", 0 ' INPUT {"<prompt>";} <var> {,<var>}
tok3 byte "PRINT", 0 ' PRINT {USING "<format>";} ...
tok4 byte "GOTO", 0
tok5 byte "GOSUB", 0
tok6 byte "RETURN", 0
tok7 byte "REM", 0
tok8 byte "NEW", 0
tok9 byte "LIST", 0
tok10 byte "RUN", 0
tok11 byte "RND", 0
tok12 byte "OPEN", 0 ' OPEN " <file> ",<mode>
tok13 byte "READ", 0 ' READ <var> {,<var>}
tok14 byte "WRITE", 0 ' WRITE {USING "<format>";} ...
tok15 byte "CLOSE", 0 ' CLOSE
tok16 byte "DELETE", 0 ' DELETE " <file> "
tok17 byte "RENAME", 0 ' RENAME " <file> "," <file> "
tok18 byte "FILES", 0 ' FILES
tok19 byte "SAVE", 0 ' SAVE or SAVE [<expr>] or SAVE "<file>"
tok20 byte "LOAD", 0 ' LOAD or LOAD [<expr>] or LOAD "<file>"
tok21 byte "NOT" ,0 ' NOT <logical>
tok22 byte "AND" ,0 ' <logical> AND <logical>
tok23 byte "OR", 0 ' <logical> OR <logical>
tok24 byte "SHL", 0 ' <expr> SHL <expr>
tok25 byte "SHR", 0 ' <expr> SHR <expr>
tok26 byte "FOR", 0 ' FOR <var> = <expr> TO <expr>
tok27 byte "TO", 0
tok28 byte "STEP", 0 ' optional STEP <expr>
tok29 byte "NEXT", 0 ' NEXT <var>
tok30 byte "INA", 0 ' INA [ <expr> ]
tok31 byte "OUTA", 0 ' OUTA [ <expr> ] = <expr>
tok32 byte "PAUSE", 0 ' PAUSE <time ms> {,<time us>}
tok33 byte "USING", 0 ' PRINT USING "<format>"; ...
tok34 byte "ROL", 0 ' <expr> ROL <expr>
tok35 byte "ROR", 0 ' <expr> ROR <expr>
tok36 byte "SAR", 0 ' <expr> SAR <expr>
tok37 byte "REV", 0 ' <expr> REV <expr>
tok38 byte "BYTE", 0 ' BYTE [ <expr> ]
tok39 byte "WORD", 0 ' WORD [ <expr> ]
tok40 byte "LONG", 0 ' LONG [ <expr> ]
tok41 byte "CNT", 0
tok42 byte "PHSA", 0
tok43 byte "PHSB", 0
tok44 byte "FRQA", 0
tok45 byte "FRQB", 0
tok46 byte "CTRA", 0
tok47 byte "CTRB", 0
tok48 byte "DISPLAY", 0 ' DISPLAY <expr> {,<expr>}
tok49 byte "KEYCODE", 0 ' KEYCODE
tok50 byte "LET", 0
tok51 byte "STOP", 0
tok52 byte "END", 0
tok53 byte "EEPROM", 0 ' EEPROM[ <expr> ]
tok54 byte "FILE", 0 ' FILE
tok55 byte "MEM", 0 ' MEM
tok56 byte "SPIN", 0 ' SPIN [<expr>] or SPIN "<file>"
tok57 byte "COPY", 0 ' COPY [<expr>],"<file>" or COPY "<file>",[<expr>] or
' COPY [<expr>],<expr> where <expr> are different
tok58 byte "DUMP", 0 ' DUMP <expr>,<expr> or DUMP [<expr>],<expr>
toks word @tok0, @tok1, @tok2, @tok3, @tok4, @tok5, @tok6, @tok7
word @tok8, @tok9, @tok10, @tok11, @tok12, @tok13, @tok14, @tok15
word @tok16, @tok17, @tok18, @tok19, @tok20, @tok21, @tok22, @tok23
word @tok24, @tok25, @tok26, @tok27, @tok28, @tok29, @tok30, @tok31
word @tok32, @tok33, @tok34, @tok35, @tok36, @tok37, @tok38, @tok39
word @tok40, @tok41, @tok42, @tok43, @tok44, @tok45, @tok46, @tok47
word @tok48, @tok49, @tok50, @tok51, @tok52, @tok53, @tok54, @tok55
word @tok56, @tok57, @tok58
tokx word
syn byte "Syntax Error", 0
ln byte "Invalid Line Number", 0
ver byte "▶Hive: FemtoBasic • 18-09-2010-dr235",13,0
PUB main | err, s
ios.start
' code für test im ram, sollte bei bin-datei auskommentiert werden
' ios.startram
' clear the program space and variables, then read a line and interpret it.
pauseTime := 0
outputs := 0
fileOpened := 0
long[userPtr] := userPtr - progsize ' Allocate memory
waitcnt(clkfreq + cnt) ' wozu das?
ios.screeninit(@ver,1)
clearall
s := 0
curlineno := -1
repeat
err := \doline(s) ' eine kommandozeile verarbeiten
s := 0
if err ' fehler?
showError(err)
pri doline(s) | c ' Execute the string in s or wait for input
curlineno := -1
if ios.keystat > 0 ' Was the "break key" pressed?
if ios.key == ios#CHAR_ESC ' escape?
nextlineloc := eop-2 ' Stop the program
if nextlineloc < eop-2
curlineno := wordat(nextlineloc)
tp := nextlineloc + 2
nextlineloc := tp + strsize(tp) + 1
texec
else
pauseTime := 0
outputs := 0
if s
bytemove(tp:=@tline,s,strsize(s)+1)
else
putlinet(string("OK"))
getline
c := spaces
if "0" =< c and c =< "9"
insertline
nextlineloc := eop - 2
else
tokenize
if spaces
texec
PRI showError(err)
if curlineno => 0
ios.print(string("IN LINE "))
ios.printdec(curlineno)
ios.printchar(" ")
if err < 0
ios.print(string("SD card "))
ios.printdec(err)
ios.printnl
else
putlinet(err)
nextlineloc := eop - 2
PRI getline | i, c
i := 0
repeat
c := ios.keywait
if c == ios#CHAR_BS
if i > 0
ios.printctrl(ios#CHAR_TER_BS)
i--
elseif c == fReturn
ios.printchar(c)
tline[i] := 0
tp := @tline
return
elseif i < linelen-1
ios.printchar(c)
tline[i++] := c
pri putlinet(s) | c, ntoks
ntoks := (@tokx - @toks) / 2
repeat while c := byte[s++]
if c => 128
if (c -= 128) < ntoks
ios.print(@@toks[c])
if c <> 7 ' REM
ios.printchar(" ")
else
ios.printchar("{")
ios.printdec(c)
ios.printchar("}")
else
ios.printchar(c)
ios.printchar(fReturn)
pri spaces | c
repeat
c := byte[tp]
if c == 0 or c > " "
return c
tp++
pri skipspaces
if byte[tp]
tp++
return spaces
pri parseliteral | r, c
r := 0
repeat
c := byte[tp]
if c < "0" or c > "9"
return r
r := r * 10 + c - "0"
tp++
pri movprog(at, delta)
if eop + delta + 2 - long[userPtr] > progsize
abort string("NO MEMORY")
bytemove(at+delta, at, eop-at)
eop += delta
pri fixvar(c)
if c => "a"
c -= 32
return c - "A"
pri isvar(c)
c := fixvar(c)
return c => 0 and c < 26
pri tokenize | tok, c, at, put, state, i, j, ntoks
ntoks := (@tokx - @toks) / 2
at := tp
put := tp
state := 0
repeat while c := byte[at]
if c == quote
if state == "Q"
state := 0
elseif state == 0
state := "Q"
if state == 0
repeat i from 0 to ntoks-1
tok := @@toks[i]
j := 0
repeat while byte[tok] and ((byte[tok] ^ byte[j+at]) & caseBit) == 0
j++
tok++
if byte[tok] == 0 and not isvar(byte[j+at])
byte[put++] := 128 + i
at += j
if i == 7
state := "R"
else
repeat while byte[at] == " "
at++
state := "F"
quit
if state == "F"
state := 0
else
byte[put++] := byte[at++]
else
byte[put++] := byte[at++]
byte[put] := 0
pri wordat(loc)
return (byte[loc]<<8)+byte[loc+1]
pri findline(lineno) | at
at := long[userPtr]
repeat while wordat(at) < lineno
at += 3 + strsize(at+2)
return at
pri insertline | lineno, fc, loc, locat, newlen, oldlen
lineno := parseliteral
if lineno < 0 or lineno => 65535
abort @ln
tokenize
fc := spaces
loc := findline(lineno)
locat := wordat(loc)
newlen := 3 + strsize(tp)
if locat == lineno
oldlen := 3 + strsize(loc+2)
if fc == 0
movprog(loc+oldlen, -oldlen)
else
movprog(loc+oldlen, newlen-oldlen)
elseif fc
movprog(loc, newlen)
if fc
byte[loc] := lineno >> 8
byte[loc+1] := lineno
bytemove(loc+2, tp, newlen-2)
pri clearvars
bytefill(@vars, 0, 26)
pauseTime := 0
nextlineloc := long[userPtr]
sp := 0
pri newprog
byte[long[userPtr]][0] := 255
byte[long[userPtr]][1] := 255
byte[long[userPtr]][2] := 0
eop := long[userPtr] + 2
nextlineloc := eop - 2
sp := 0
pri clearall
newprog
clearvars
pri pushstack
if sp => constant(maxstack-1)
abort string("RECURSION ERROR")
stack[sp++] := nextlineloc
pri getAddress(delim) | t
if spaces <> "["
abort @syn
skipspaces
result := expr
if delim == "." and (result < 0 or result > 31)
abort string("Invalid pin number")
if delim == "." or delim == ","
if spaces == delim
if delim == "." ' Handle the form <expr>..<expr>
if byte[++tp] <> "."
abort @syn
result <<= 8
skipspaces
t := expr
if t < 0 or t > 31
abort string("Invalid pin number")
result |= t | $10000
else ' Handle the form <expr>,<expr>
if result & 1 or result < 0 or result > 31
abort string("Invalid pin number")
skipspaces
result := (result << 18) | (expr & $7FFFF)
elseif delim == ","
result := (result & $7FFFF)
if spaces <> "]"
abort @syn
tp++
pri factor | tok, t, i
tok := spaces
tp++
case tok
"(":
t := expr
if spaces <> ")"
abort @syn
tp++
return t
"a".."z","A".."Z":
return vars[fixvar(tok)]
158: ' INA [ <expr>{..<expr>} ]
t := getAddress(".")
if t > $FFFF
tok := t & $FF
t := (t >> 8) & $FF
repeat i from t to tok
outputs &= ! |< i
dira[t..tok]~
return ina[t..tok]
else
outputs &= ! |< t
dira[t]~
return ina[t]
166: ' BYTE [ <expr> ]
return byte[getAddress(" ")]
167: ' WORD [ <expr> ]
return word[getAddress(" ")]
168: ' LONG [ <expr> ]
return long[getAddress(" ")]
181: ' EEPROM [ <expr> ]
' code ausgefügt
return
182: ' FILE
return ios.sdgetc
183: ' MEM
return progsize - (eop - long[userPtr] )
169: ' CNT
return CNT
170: ' PHSA
return PHSA
171: ' PHSB
return PHSB
172: ' FRQA
return FRQA
173: ' FRQB
return FRQB
174: ' CTRA
return CTRA
175: ' CTRB
return CTRB
177: ' KEYCODE
return ios.keywait
139: ' RND <factor>
return (rv? >> 1) ** (factor << 1)
"-":
return - factor
"!":
return ! factor
"$", "%", quote, "0".."9":
--tp
return getAnyNumber
other:
abort(@syn)
pri shifts | tok, t
t := factor
tok := spaces
if tok == 152 ' SHL
tp++
return t << factor
elseif tok == 153 ' SHR
tp++
return t >> factor
elseif tok == 162 ' ROL
tp++
return t <- factor
elseif tok == 163 ' ROR
tp++
return t -> factor
elseif tok == 164 ' SAR
tp++
return t ~> factor
elseif tok == 165 ' REV
tp++
return t >< factor
else
return t
pri bitFactor | tok, t
t := shifts
repeat
tok := spaces
if tok == "&"
tp++
t &= shifts
else
return t
pri bitTerm | tok, t
t := bitFactor
repeat
tok := spaces
if tok == "|"
tp++
t |= bitFactor
elseif tok == "^"
tp++
t ^= bitFactor
else
return t
pri term | tok, t
t := bitTerm
repeat
tok := spaces
if tok == "*"
tp++
t *= bitTerm
elseif tok == "/"
if byte[++tp] == "/"
tp++
t //= bitTerm
else
t / =bitTerm
else
return t
pri arithExpr | tok, t
t := term
repeat
tok := spaces
if tok == "+"
tp++
t += term
elseif tok == "-"
tp++
t -= term
else
return t
pri compare | op, a, b, c
a := arithExpr
op := 0
spaces
repeat
c := byte[tp]
case c
"<": op |= 1
tp++
">": op |= 2
tp++
"=": op |= 4
tp++
other: quit
case op
0: return a
1: return a < arithExpr
2: return a > arithExpr
3: return a <> arithExpr
4: return a == arithExpr
5: return a =< arithExpr
6: return a => arithExpr
7: abort string("Invalid comparison")
pri logicNot | tok
tok := spaces
if tok == 149 ' NOT
tp++
return not compare
return compare
pri logicAnd | t, tok
t := logicNot
repeat
tok := spaces
if tok == 150 ' AND
tp++
t := t and logicNot
else
return t
pri expr | tok, t
t := logicAnd
repeat
tok := spaces
if tok == 151 ' OR
tp++
t := t or logicAnd
else
return t
pri specialExpr
if spaces <> "="
abort @syn
skipspaces
return expr
pri scanFilename(f) | c, chars
chars := 0
tp++ ' skip past initial quote
repeat while (c := byte[tp++]) <> quote
if chars++ < 31
byte[f++] := c
byte[f] := 0
pri texec | ht, nt, restart, thisLine, uS, a,b,c,d, f0,f1,f2,f3,f4,f5,f6,f7
uS := clkfreq / 1_000_000
thisLine := tp - 2
restart := 1
repeat while restart
restart := 0
ht := spaces
if ht == 0
return
nt := skipspaces
if isvar(ht) and nt == "="
tp++
vars[fixvar(ht)] := expr
elseif ht => 128
case ht
128: ' THEN
a := expr
if spaces <> 129
abort string("MISSING THEN")
skipspaces
if not a
return
restart := 1
130: ' INPUT {"<prompt>";} <var> {, <var>}
if nt == quote
c := byte[++tp]
repeat while c <> quote and c
ios.printchar(c)
c := byte[++tp]
if c <> quote
abort @syn
if skipspaces <> ";"
abort @syn
nt := skipspaces
if not isvar(nt)
abort @syn
b := 0
inVars[b++] := fixvar(nt)
repeat while skipspaces == ","
nt := skipspaces
if not isvar(nt) or b == 26
abort @syn
inVars[b++] := fixvar(nt)
getline
tokenize
repeat a from 1 to b
vars[inVars[a-1]] := expr
if a < b
if spaces == ","
skipspaces
131: ' PRINT
a := 0
repeat
nt := spaces
if nt == 0 or nt == ":"
quit
if nt == quote
tp++
repeat
c := byte[tp++]
if c == 0 or c == quote
quit
ios.printchar(c)
a++
else
d~
if (b := expr) < 0
-b
ios.printchar("-")
a++
c := 1_000_000_000
repeat 10
if b => c
ios.printchar(b / c + "0")
a++
b //= c
d~~
elseif d or c == 1
ios.printchar("0")
a++
c /= 10
nt := spaces
if nt == ";"
tp++
elseif nt == ","
ios.printchar(" ")
a++
repeat while a & 7
ios.printchar(" ")
a++
tp++
elseif nt == 0 or nt == ":"
ios.printchar(fReturn)
quit
else
abort @syn
132, 133: ' GOTO, GOSUB
a := expr
if a < 0 or a => 65535
abort @ln
b := findline(a)
if wordat(b) <> a
abort @ln
if ht == 133
pushstack
nextlineloc := b
134: ' RETURN
if sp == 0
abort string("INVALID RETURN")
nextlineloc := stack[--sp]
135: ' REM
repeat while skipspaces
136: ' NEW
clearall
137: ' LIST {<expr> {,<expr>}}
b := 0 ' Default line range
c := 65535
if spaces <> 0 ' At least one parameter
b := c := expr
if spaces == ","
skipspaces
c := expr
a := long[userPtr]
repeat while a+2 < eop
d := wordat(a)
if d => b and d =< c
ios.printdec(d)
ios.printchar(" ")
putlinet(a+2)
a += 3 + strsize(a+2)
138: ' RUN
clearvars
140: ' OPEN " <file> ", R/W/A
if spaces <> quote
abort @syn
scanFilename(@f0)
if spaces <> ","
abort @syn
case skipspaces
"A", "a": d := "a"
"W", "w": d := "w"
"R", "r": d := "r"
other: abort string("Invalid open file mode")
tp++
if ios.sdmount < 0
abort string("Can't mount SD card")
if ios.sdopen(d,@f0)
abort string("Can't open file")
fileOpened := true
141: ' READ <var> {, <var> }
if not isvar(nt)
abort @syn
d := 0
inVars[d++] := fixvar(nt)
repeat while skipspaces == ","
nt := skipspaces
if not isvar(nt) or d == 26
abort @syn
inVars[d++] := fixvar(nt)
a := 0
repeat
c := ios.sdgetc
if c < 0
abort string("Can't read file")
elseif c == fReturn or c == fEof
tline[a] := 0
tp := @tline
quit
elseif c == fLinefeed
next
elseif a < linelen-1
tline[a++] := c
tokenize
repeat a from 1 to d
vars[inVars[a-1]] := expr
if a < d
if spaces == ","
skipspaces
142: ' WRITE ...
d := 0 ' record column
repeat
nt := spaces
if nt == 0 or nt == ":"
quit
if nt == quote
tp++
repeat
c := byte[tp++]
if c == 0 or c == quote
quit
ios.sdputc(c)
d++
else
a := expr
if a < 0
-a
ios.sdputc("-")
b := 1_000_000_000
c := false
repeat 10
if a => b
ios.sdputc(a / b + "0")
a //= b
c := true
elseif c or b == 1
ios.sdputc("0")
b /= 10
nt := spaces
if nt == ";"
tp++
elseif nt == ","
ios.sdputc(" ")
d++
repeat while d & 7
ios.sdputc(" ")
d++
tp++
elseif nt == 0 or nt == ":"
ios.sdputc(fReturn)
ios.sdputc(fLinefeed)
quit
else
abort @syn
143: ' CLOSE
fileOpened := false
if ios.sdclose < 0
abort string("Error closing file")
ios.sdunmount
144: ' DELETE " <file> "
if spaces <> quote
abort @syn
scanFilename(@f0)
if ios.sdmount < 0
abort string("Can't mount SD card")
if ios.sdopen("d",@f0)
abort string("Can't delete file")
if ios.sdclose < 0
abort string("Error deleting file")
ios.sdunmount
145: ' RENAME " <file> "," <file> "
if spaces <> quote
abort @syn
scanFilename(@f0)
if spaces <> ","
abort @syn
if skipspaces <> quote
abort @syn
scanFilename(@f0)
abort string("Rename not implemented")
146: ' FILES
h_dir
147: ' SAVE or SAVE "<filename>"
if (nt := spaces) == quote
scanFilename(@f0)
if ios.sdmount < 0
abort string("Can't mount SD card")
if ios.sdopen("w",@f0)
abort string("Can't create file")
processSave
if ios.sdclose < 0
abort string("Error closing file")
ios.sdunmount
148: ' LOAD or LOAD "<filename>"
if (nt := spaces) == quote
scanFilename(@f0)
if ios.sdmount < 0
abort string("Can't mount SD card")
if ios.sdopen("r",@f0) ' Open requested file
abort string("Can't open file")
bytemove(@tailLine,tp,strsize(tp)+1)
newprog
processLoad
tp := @tailLine ' Scan command tail after load
if ios.sdclose < 0
abort string("Error closing file")
ios.sdunmount
154: ' FOR <var> = <expr> TO <expr> {STEP <expr>}
ht := spaces
if ht == 0
abort @syn
nt := skipspaces
if not isvar(ht) or nt <> "="
abort @syn
a := fixvar(ht)
skipspaces
vars[a] := expr
if spaces <> 155 ' TO ' Save FOR limit
abort @syn
skipspaces
forLimit[a] := expr
if spaces == 156 ' STEP ' Save step size
skipspaces
forStep[a] := expr
else
forStep[a] := 1 ' Default step is 1
if spaces
abort @syn
forLoop[a] := nextlineloc ' Save address of line
if forStep[a] < 0 ' following the FOR
b := vars[a] => forLimit[a]
else ' Initially past the limit?
b := vars[a] =< forLimit[a]
if not b ' Search for matching NEXT
repeat while nextlineloc < eop-2
curlineno := wordat(nextlineloc)
tp := nextlineloc + 2
nextlineloc := tp + strsize(tp) + 1
if spaces == 157 ' NEXT <var>
nt := skipspaces ' Variable has to agree
if not isvar(nt)
abort @syn
if fixvar(nt) == a ' If match, continue after
quit ' the matching NEXT
157: ' NEXT <var>
nt := spaces
if not isvar(nt)
abort @syn
a := fixvar(nt)
vars[a] += forStep[a] ' Increment or decrement the
if forStep[a] < 0 ' FOR variable and check for
b := vars[a] => forLimit[a]
else ' the limit value
b := vars[a] =< forLimit[a]
if b ' If continuing loop, go to
nextlineloc := forLoop[a] ' statement after FOR
tp++
159: ' OUTA [ <expr>{..<expr>} ] = <expr>
a := getAddress(".")
if a > $FFFF
b := a & $FF
a := (a >> 8) & $FF
outa[a..b] := specialExpr
dira[a..b]~~
repeat c from a to b
outputs |= |< c
else
outa[a] := specialExpr
dira[a]~~
outputs |= |< a
160: ' PAUSE <expr> {,<expr>}
if pauseTime == 0 ' If no active pause time, set it
spaces ' with a minimum time of 50us
pauseTime := expr * 1000
if spaces == "," ' First (or only) value is in ms
skipspaces
pauseTime += expr ' Second value is in us
pauseTime #>= 50
if pauseTime < 10_050 ' Normally pause at most 10ms at a time,
waitcnt(pauseTime * uS + cnt) ' but, if that would leave < 50us,
pauseTime := 0 ' pause the whole amount now
else
a := pauseTime <# 10_000
waitcnt(a * uS + cnt) ' Otherwise, pause at most 10ms and
nextlineloc := thisLine ' re-execute the PAUSE for the rest
pauseTime -= 10_000
166: ' BYTE [ <expr> ] = <expr>
a := getAddress(" ")
byte[a] := specialExpr
167: ' WORD [ <expr> ] = <expr>
a := getAddress(" ")
word[a] := specialExpr
168: ' LONG [ <expr> ] = <expr>
a := getAddress(" ")
long[a] := specialExpr
170: ' PHSA =
PHSA := specialExpr
171: ' PHSB =
PHSB := specialExpr
172: ' FRQA =
FRQA := specialExpr
173: ' FRQB =
FRQB := specialExpr
174: ' CTRA =
CTRA := specialExpr
175: ' CTRB =
CTRB := specialExpr
176: ' DISPLAY <expr> {,<expr>}
spaces
ios.printchar(expr)
repeat while spaces == ","
skipspaces
ios.printchar(expr)
178: ' LET <var> = <expr>
nt := spaces
if not isvar(nt)
abort @syn
tp++
vars[fixvar(nt)] := specialExpr
179: ' STOP
nextlineloc := eop-2
return
180: ' END
nextlineloc := eop-2
return
181: ' EEPROM [ <expr> ] = <expr>
' code ausgefügt
ios.print(@msg0)
182: ' FILE = <expr>
if ios.sdputc(specialExpr) < 0
abort string("SDCARD write error")
184: ' SPIN [{<expr>,}<expr>] or "<file>"
if spaces == quote
scanFilename(@f0)
ios.ldbin(@f0)
185: ' COPY [<expr>],"<file>" or COPY "<file>",[<expr>] or
' COPY [<expr>],[<expr>] where <expr> are different
' code ausgefügt
ios.print(@msg0)
186: ' DUMP <expr>,<expr> or DUMP [<expr>],<expr>
if spaces == "["
c := getAddress(",")
a := c & $F80000
b := c & $07FFFF
else
a := -1
b := expr
if spaces <> ","
abort @syn
skipspaces
dumpMemory(a,b,expr)
else
abort(@syn)
if spaces == ":"
restart := 1
tp++
PRI processLoad : c | a
repeat
a := 0
repeat
c := ios.sdgetc
if c == fReturn or c == fEof
tline[a] := 0
tp := @tline
quit
elseif c == fLinefeed
next
elseif c < 0
quit
elseif a < linelen-1
tline[a++] := c
if ios.sdeof and tline[0] == 0
quit
if c < 0
abort string("Error while loading file")
tp := @tline
a := spaces
if "0" =< a and a =< "9"
insertline
nextlineloc := eop - 2
else
if a <> 0
abort string("Missing line number in file")
PRI processSave | a, c, d, ntoks
ntoks := (@tokx - @toks) / 2
a := long[userPtr]
repeat while a+2 < eop
d := wordat(a)
ios.sddec(d)
ios.sdputc(" ")
d := a + 2
repeat while c := byte[d++]
if c => 128
if (c -= 128) < ntoks
ios.sdputstr(@@toks[c])
if c <> 7 ' REM
ios.sdputc(" ")
else
ios.sdputc("{")
ios.sddec(c)
ios.sdputc("}")
else
ios.sdputc(c)
ios.sdputc(fReturn)
ios.sdputc(fLinefeed)
a += 3 + strsize(a+2)
PRI getAnyNumber | c, t
case c := byte[tp]
quote:
if result := byte[++tp]
if byte[++tp] == quote
tp++
else
abort string("missing closing quote")
else
abort string("end of line in string")
"$":
c := byte[++tp]
if (t := hexDigit(c)) < 0
abort string("invalid hex character")
result := t
c := byte[++tp]
repeat until (t := hexDigit(c)) < 0
result := result << 4 | t
c := byte[++tp]
"%":
c := byte[++tp]
if not (c == "0" or c == "1")
abort string("invalid binary character")
result := c - "0"
c := byte[++tp]
repeat while c == "0" or c == "1"
result := result << 1 | (c - "0")
c := byte[++tp]
"0".."9":
result := c - "0"
c := byte[++tp]
repeat while c => "0" and c =< "9"
result := result * 10 + c - "0"
c := byte[++tp]
other:
abort string("invalid literal value")
PRI hexDigit(c)
'' Convert hexadecimal character to the corresponding value or -1 if invalid.
if c => "0" and c =< "9"
return c - "0"
if c => "A" and c =< "F"
return c - "A" + 10
if c => "a" and c =< "f"
return c - "a" + 10
return -1
PUB dumpMemory(pin,addr,size) | i, c, p, first, buf0, buf1, buf2
'' This routine dumps a portion of the RAM/ROM to the display (pin == -1).
'' If pin is not -1, it is an EEPROM address in the form required by the
'' I2C routines in i2cSpiInit. The specified address is or'd with this.
'' The format is 8 bytes wide with hexadecimal and ASCII.
addr &= $7FFFF
first := true
p := addr & $7FFF8
repeat while p < (addr + size)
if first
ios.printhex(addr,5)
first := false
else
ios.printhex(p,5)
ios.printchar(":")
repeat i from 0 to 7
byte[@buf0][i] := " "
if p => addr and p < (addr + size)
c := byte[p]
ios.printhex(c,2)
if c => " " and c =< "~"
byte[@buf0][i] := c
else
ios.printchar(" ")
ios.printchar(" ")
ios.printchar(" ")
p++
buf2 := 0
ios.printchar("|")
ios.print(@buf0)
ios.printchar("|")
ios.printchar(fReturn)
PUB h_dir | stradr,n,wflag,c,i,len,mflag 'hive: verzeichnis anzeigen
{{h_dir - anzeige verzeichnis}}
wflag := 1
mflag := 1
ios.sdmount 'medium mounten
ios.sddir 'kommando: verzeichnis öffnen
n := 1
c := 0 'spalten
i := 0 'dateizähler
repeat 'wiederhole bis verzeichnisende
stradr := ios.sdnext 'einen eintrag holen
if stradr <> 0 'ist eintrag gültig?
i++
len := strsize(stradr)
n++
ios.print(stradr)
if wflag == 1
c++
ios.printtab
if (wflag == 0 OR c == 3)
ios.printnl
c := 0
if mflag == 1 AND i == 20
ios.printnl
ios.print(@wait1)
if ios.keywait == "q"
return
ios.printnl
i := 0
while stradr <> 0 'wiederholen solange stradr <> 0
if wflag == 1
ios.printnl
ios.printdec(--n)
ios.print(string(" Datei(en)"))
ios.printnl
ios.sdunmount 'medium unmounten
DAT
wait1 byte "<WEITER? */q:>",0
msg0 byte "Funktion nicht implementiert!",0
{{
TERMS OF USE: MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
}}