TriOS-alt/zubehör/PropForth/PropForthPart2.f

312 lines
10 KiB
FortranFixed
Raw Normal View History

2010-11-26 23:58:06 +01:00
FL
\ eeReadWord ( eeAddr -- n1 )
: eeReadWord mcwT0 2 eeReadPage if eeErr cr then mcwT0 w@ ;
\ eeWriteWord ( n1 eeAddr -- )
: eeWriteWord swap mcwT0 w! mcwT0 2 eeWritePage if eeErr cr then ;
\ eeReadByte ( eeAddr -- c1 )
: eeReadByte eeReadWord FF and ;
\ eeCopy ( addr1 addr2 u -- ) copy u bytes from addr1 to addr2, addr1 and addr2 must be on a 0x80 byte page boundary
\ clears the pad, so make sure no commands follow
\ and u must be a multiple of 0x80 and should not overlap
: eeCopy 7F invert and rot 7f invert and rot 7f invert and rot
0 do over i + dup . mcPad 80 eeReadPage if eeErr leave then
dup i + dup . mcPad 80 eeWritePage if eeErr leave then
i 3FF and 0= if cr then 80 +loop 2drop cogid cogPadclr ;
: _d1 cr over .word space dup .word _ecs bounds ;
: _d2 cr .word _ecs ;
: _d3 mcT 10 bounds do i c@ .byte space loop 2 spaces mcT 10 .str ;
\ dump ( adr cnt -- ) uses mcT
: dump _d1 do i _d2 i mcT 10 cmove _d3 10 +loop cr ;
\ rdump ( adr cnt -- ) uses mcwT1 - mcwT8
: rdump _d1 do i _d2 i mcT 10 eeReadPage if mcT 10 0 fill then _d3 10 +loop cr ;
\ adump ( adr cnt -- )
: adump cr over .word space dup .word _ecs bounds
do
cr i .word _ecs i 4 bounds
do i @ .long space loop
4 +loop cr ;
\ \ ( -- ) moves the parse pointer >in to the end of the line, tricky to redefine
\ CTL-E gets traslated to \ by fast_load
:  \
padsize mcw>in w! ; immediate exec
\ ' ( -- addr ) returns the execution token for the next name, if not found it returns 0
: ' parsebl if pad>in nextword find 0= if _udf cr drop 0 then else 0 then ;
\ cq ( -- addr ) returns the address of the counted string following this word and increments the IP past it
: cq r> dup c@++ + alignw >r ;
\ c" ( -- c-addr ) compiles the string delimited by ", runtime return the addr of the counted string ** valid only in that line
: c" compile?
if
cm_cq w, 1 mcw>in w+! 22 parse dup c, dup pad>in mswHere w@ rot cmove dup allot 1+ mcw>in w+! herewal
else
22 parse 1- pad>in 2dup c! swap 2+ mcw>in w+!
then ; immediate exec
\ the base address for the input buffer
wvariable fl_base
\ the number of buffered characters
wvariable fl_count
\ the old mswDictend
wvariable fl_top
\ the offset of the next byte in
wvariable fl_in
\ one fast load at a time
wvariable fl_lock
\ fl_buf ( -- t/f ) allocate all but 300 chars and load keys load true if successful
: fl_buf mswDictend w@ mswHere w@ - 300 - 0 fl_count w! lockdict fl_lock w@
if freedict cr 0 else -1 fl_lock w! freedict -1 then
\ ( u t/f -- ) true if successful so far
if
\ save the old mswDictend and initialize variables
mswDictend w@ dup fl_top w! swap - dup fl_base w! dup fl_in w! 1- mswDictend w!
0
begin dup mswKeyTO w@ 0
do
begin fkey?
if dup 5C = \ if a backslash, throw away keys
if drop begin keyto if D = else -1 then until else
\ drop all characters between { }
dup 7B = if drop begin keyto if 7D = else -1 then until else
\ translate CTL-E 05 to backspace 5C
dup 5 = if drop 5C then
fl_in w@ c! 1+ fl_in w@ 1+ dup fl_top w@ =
if _eoom clearkeys reset then fl_in w!
then
then 0
\ stay in begin until
else drop -1 then
\ no key, exit begin until
until
loop
swap over =
\ until count is the same
until
dup . ." chars" cr fl_count w! -1
else drop 0 then
;
\ fl_skeys ( n -- ) emit the keys in the fast buffer
: fl_skeys
fl_lock w@ fl_count w@ 0<> and
if
fl_base w@ fl_count w@ bounds
do
i dup c@ emit mswDictend w!
loop
fl_top w@ mswDictend w! 0 fl_count w! lockdict 0 fl_lock w! freedict
then
;
: loadee 2dup F andn bounds
do i mcT 10 eeReadPage drop mcT 10 bounds do i c@ emit loop 10 +loop
dup F andn rot + swap F and dup if bounds do i eeReadByte emit loop else 2drop then ;
: _caend c" cr " over cappend cogid over cappendnc c" 0 mcwEmitptr w! >cog" swap cappend ;
: FL fl_buf if c" fl_skeys" mcT ccopy mcT _caend mcT cogXO then ;
\ file area 8000 - FFFF
\ individual files start on 128 byte boundaries,
\ the first thing is the length as a 16 bit word, then a cstr which is the file name, and then the contents
\ of the file
8000 constant eeBot
10000 constant eeTop
\ f_fill ( c1 -- ) fill the eeprom file area with c1
: f_fill mcPad 80 rot fill eeTop eeBot
do i mcPad 80 eeWritePage if eeErr cr leave then 80 +loop
mcPad 80 bl fill ;
\ f_clear ( -- ) clear the eeprom file area, only writes the length word to FFFF
: f_clear eeTop eeBot do FFFF i eeWriteWord 80 +loop ;
: _fi mcNumpad dup w@ swap 2+ c@ + 2+ 1+ 80 u/mod swap if 1+ then 80 u* ;
\ list ( -- ) list the files names in the eeprom
: list eeTop eeBot
do
i mcNumpad numpadsize namemax 1+ 2+ min eeReadPage if eeErr leave then mcNumpad w@ FFFF =
if i . cr 80 leave else i . mcNumpad dup w@ . 2+ .cstr cr _fi then
+loop ;
\ f_find ( cstr -- n1 ) find the file, 0 if not found
: f_find 0 eeTop eeBot
do
i mcNumpad numpadsize namemax 1+ 2+ min eeReadPage if eeErr leave then mcNumpad w@ FFFF =
if nip 80 leave else over mcNumpad 2+ cstr= if drop i then _fi then
+loop ;
\ f_free ( -- n1 ) address of the first free file page, 0 if there are none
: f_free 0 eeTop eeBot
do
i mcNumpad 4 eeReadPage if eeErr leave then mcNumpad w@ FFFF =
if drop i 80 leave else _fi then
+loop ;
\ f_wfile ( -- ) write the file at fl_base for fl_count bytes, the format must be:
\ word length the number of bytes in the content
\ bytes cstr - filename
\ bytes file contents
: f_wfile f_free dup
if
dup fl_count w@ + eeTop <
if fl_base w@ fl_count w@ bounds
do dup
i fl_count w@ dup 80 min swap over - fl_count w! eeWritePage
if eeErr leave then
80 + 80 +loop drop
else drop _eoom then
else drop eeErr cr then ;
\ FW ( n1 -- ) like a fast load but write to the file area, first entry after a blank lines must be 3 periods followed by the filename
: FW fl_buf
if fl_count w@ 0
do
fl_base w@ c@ 2E =
if leave else fl_base w@ 1+ fl_base w! fl_count w@ 1- fl_count w! then
loop
fl_base w@ 3 + 20 bounds do i c@ bl <= lasti? or if i leave then loop fl_base w@ - dup
3 - fl_base w@ 2+ c!
fl_count w@ swap - dup fl_base w@ c! dup 8 rshift fl_base w@ 1+ c!
if f_wfile then
fl_top w@ mswDictend w! lockdict 0 fl_lock w! freedict
then ;
\ f_al ( addr1 -- n1 addr2) for file at addr1, get the length - n1, and the address of teh contents - addr2
: f_al dup eeReadWord over 2+ eeReadByte rot + 2+ 1+ ;
\ f_load ( cstr -- ) load the file name following from eeprom
: f_load f_find dup
if f_al 0 mcT c! mcT cappendnc mcT cappendnc c" loadee" mcT cappend mcT _caend mcT cogXO else drop then ;
\ load ( -- ) load the file name following from eeprom
: load parsenw dup if f_load else drop then ;
: version c" PropForth v2.5 2009OCT24 17:15 0" ;
\ free ( -- ) display free main bytes and current cog longs
: free mswDictend w@ mswHere w@ - . ." bytes free - " par mcwAhere w@ - . ." cog longs free" cr ;
\ saveforth( -- ) write the running image to eeprom
: saveforth
c" mswHere" find
if
version dup c@ + dup c@ 1+ swap c!
pfa>nfa mswHere w@ swap
\ 2e emit
begin dup w@ over eeWriteWord 2+ dup 7F and 0= until
do
ibound i - 80 min dup i dup rot
eeWritePage if leave then 2e emit
+loop
else drop then cr ;
\ _forget ( cstr -- ) wind the dictionary back to the word which follows - caution
: _forget dup
if
find if
pfa>nfa nfa>lfa dup mswHere w! w@ mswlastnfa w!
else .cstr ??? cr then
else drop then ;
\ forget ( -- ) wind the dictionary back to the word which follows - caution
: forget parsenw _forget ;
\ this constant is used at boot time to set the forth starting routine, if it is changed
\ it does not take effect until a reboot, a cog reset is not adequate
cm_fstart wconstant cm_fstart
\ fstart ( -- ) the start word
: fstart
cogid dup cogInbyte 10 lshift cm_entry 2 lshift or swap or resetDreg !
mcwInbyte m@ l>w swap
100 mcwInbyte w!
0 mcwEmitptr w!
fMask @ mcwDebugcmd w!
\ zero out cog data area
par @ 8 + F8 0 fill
\ initialize forth variables
hex
ca_varEnd mcwAhere w!
\ initiliaze the common variables
lockdict mswHere w@ 0=
if 0 fl_lock w! lastnfa nfa>pfa 2+ alignl 4+ mswHere w! 7FFF dup mswMemend w! mswDictend w! then
freedict rsTop 1- rsPtr !
FFFF = if 8 lshift cogid + vxcog w! else drop then
c" boot" mcT ccopy cogid mcT cappendn mcT find if execute else drop then
-1
begin
compile? 0= if ." Cog" cogid . ." ok" cr then
\ if the first time through set mcwDebugValue to -1 to let people know we are alive
if -1 mcwDebugvalue m! then
interpret
0 0 until ;
: boot6 cogid >cog cog+ ;
\ cog? ( -- ) display active forth cogs
: cog? ." Forth cogs: " ffcog w@ . 2D emit space lfcog w@ . cr ;
\ cog+ ( -- ) add a forth cog
: cog+ ffcog w@ 1- dup 0>= if dup ffcog w! cogreset else drop then cog? ;
\ cog- ( -- ) stop first forth cog, cannot be executed form the first forth cog
: cog- ffcog w@ dup cogid <> swap 1+ dup lfcog w@ <= rot and if dup 1- cogstop ffcog w! else drop then cog? ;
\ st? ( -- ) prints out the stack
: st? ." ST: " stPtr @ 2+ dup stTop < if stTop swap - 0 do stTop 2- i - @ .long space loop else drop then cr ;
\ sc ( -- ) clears the stack
: sc stTop stPtr @ - 3 - dup . ." items cleared" cr dup 0> if 0 do drop loop then ;
\ _pna ( addr -- ) print the address, contents and forth name
: _pna dup .word 3a emit w@ dup .word space pfa>nfa .strname space ;
\ pfa? ( addr -- t/f) true if addr is a pfa
: pfa? dup pfa>nfa dup c@ dup 80 and 0= swap namemax and 0<> rot nfa>pfa rot if w@ then rot = and ;
\ rs? ( -- ) prints out the return stack
: rs? ." RS: " rsTop rsPtr @ 1+ - 0 do rsTop 1- i - @ dup 2- w@ pfa? if 2- _pna else .long space then loop cr ;
\ lasm ( addr -- ) expects an address pointing to a structure in the following form
\ empty long, long upper address of the assembler routine, long lower address of the assembler routine
\ a series of longs which are the assembler codes
: lasm 4+ dup m@ swap 4+ swap over m@ dup mcwAhere w! do 4+ dup m@ a, loop drop ;
\ f_erase ( -- ) erase the word following from eeprom - DANGER - should be the last word only
\ or following words may get overwritten when a new file is written to eeprom
: f_erase parsenw dup if f_find dup if eeTop swap do FFFF i eeWriteWord 80 +loop else drop then else drop then ;
\ no more symbols available
\ mswlastnfa is generated by the forth spinmaker word