Compare commits
52 Commits
80d730318a
...
63dec372ce
Author | SHA1 | Date | |
---|---|---|---|
|
63dec372ce | ||
|
177e70580f | ||
|
8c4c879a65 | ||
|
212126d6d2 | ||
|
b5d42924ba | ||
|
5227777b34 | ||
|
2e23b84fc1 | ||
|
75a1b2d504 | ||
|
322be4d576 | ||
|
0f2d14ad8a | ||
|
fd597d29d2 | ||
|
ee3407bf1c | ||
|
ed3bee787d | ||
|
863540f7c6 | ||
|
bd38d80f9c | ||
|
f2817870aa | ||
|
7ceff6144c | ||
|
b6c039589f | ||
|
aad713c477 | ||
|
fdea069544 | ||
|
ebc70be8e8 | ||
|
852c775b5b | ||
|
f9a8e6f180 | ||
|
1597f1e131 | ||
|
db9885b8cf | ||
|
175b4bc497 | ||
|
ca60685067 | ||
|
0163af470a | ||
|
43eabf566b | ||
|
faa2576f83 | ||
|
87b51a6261 | ||
|
bf289b0a67 | ||
|
3fbae082f4 | ||
|
a5269a1c7c | ||
|
eec9549bde | ||
|
b606dbf9af | ||
|
a8e8204eba | ||
|
8a58449776 | ||
|
303b34b483 | ||
|
0703da928e | ||
|
b0258f5bba | ||
|
5446afd87d | ||
|
9d4d9de511 | ||
|
e6bac985fa | ||
|
68262f925b | ||
|
640e3321fc | ||
|
4143e2a699 | ||
|
179c66be8a | ||
|
74896051bb | ||
|
b17bd4dca0 | ||
|
40a756cf1c | ||
|
51997533ff |
7
blk/001
7
blk/001
@ -5,12 +5,11 @@ MASTER INDEX
|
||||
120 Linker 140 Addressed devices
|
||||
150 Extra words
|
||||
200 Z80 assembler 260 Cross compilation
|
||||
280 Z80 boot code 390 Cross-compiled core
|
||||
439 XPACKed core
|
||||
280 Z80 boot code 350 Core words
|
||||
490 TRS-80 Recipe 520 Fonts
|
||||
550 TI-84+ Recipe 580 RC2014 Recipe
|
||||
|
||||
|
||||
620 Sega Master System Recipe
|
||||
650 AVR assembler
|
||||
|
||||
|
||||
|
||||
|
2
blk/037
2
blk/037
@ -10,7 +10,7 @@ Entry management
|
||||
, n -- Write n in HERE and advance it.
|
||||
ALLOT n -- Move HERE by n bytes
|
||||
C, b -- Write byte b in HERE and advance it.
|
||||
FIND w -- a f Like '?, but for w.
|
||||
EMPTY -- Rewind HERE and CURRENT where they were at
|
||||
system initialization.
|
||||
|
||||
(cont.)
|
||||
|
3
blk/043
3
blk/043
@ -12,4 +12,5 @@ have to consume it to avoid PSP leak.
|
||||
] -- End interpretative mode.
|
||||
ABORT -- Resets PS and RS and returns to interpreter.
|
||||
ABORT" x" -- *I* Compiles a ." followed by a ABORT.
|
||||
EXECUTE a -- Execute wordref at addr a
|
||||
ERR a -- Prints a and ABORT. Defined early and used by
|
||||
drivers. (cont.)
|
||||
|
1
blk/044
1
blk/044
@ -1,3 +1,4 @@
|
||||
EXECUTE a -- Execute wordref at addr a
|
||||
INTERPRET -- Get a line from stdin, compile it in tmp memory,
|
||||
then execute the compiled contents.
|
||||
LEAVE -- In a DO..LOOP, exit at the next LOOP call.
|
||||
|
4
blk/056
4
blk/056
@ -6,7 +6,9 @@ Logic
|
||||
>< n l h -- f Push true if l < n < h
|
||||
=><= n l h -- f Push true if l <= n <= h
|
||||
CMP n1 n2 -- n Compare n1 and n2 and set n to -1, 0, or 1.
|
||||
n=0: a1=a2. n=1: a1>a2. n=-1: a1<a2.
|
||||
n=0: a1=a2. n=1: a1>a2. n=-1: a1<a2.
|
||||
MIN a b -- n Returns the lowest of a and b
|
||||
MAX a b -- n Returns the highest of a and b
|
||||
NOT f -- f Push the logical opposite of f
|
||||
|
||||
|
||||
|
31
blk/081
31
blk/081
@ -1,17 +1,16 @@
|
||||
RAMSTART FUTURE USES +55 (key) override
|
||||
+02 CURRENT +57 readln's variables
|
||||
+04 HERE +59 blk's variables
|
||||
+06 C<? +5b z80a's variables
|
||||
+08 C<* override +5d adev's variables
|
||||
+0a NLPTR +5f FUTURE USES
|
||||
+0c C<* +70 DRIVERS
|
||||
+0e WORDBUF +80 RAMEND
|
||||
+2e BOOT C< PTR
|
||||
+30 FUTURE USES
|
||||
+4e INTJUMP
|
||||
+51 CURRENTPTR
|
||||
+53 (emit) override
|
||||
|
||||
|
||||
|
||||
RAMSTART FUTURE USES +3c BLK(*
|
||||
+02 CURRENT +3e FUTURE USES
|
||||
+04 HERE
|
||||
+06 C<? +51 CURRENTPTR
|
||||
+08 C<* override +53 (emit) override
|
||||
+0a NLPTR +55 (key) override
|
||||
+0c C<* +57 FUTURE USES
|
||||
+0e WORDBUF
|
||||
+2e BOOT C< PTR +5d adev's variables
|
||||
+30 IN> +5f FUTURE USES
|
||||
+32 IN(* +70 DRIVERS
|
||||
+34 BLK@* +80 RAMEND
|
||||
+36 BLK!*
|
||||
+38 BLK>
|
||||
+3a BLKDTY
|
||||
(cont.)
|
||||
|
4
blk/082
4
blk/082
@ -9,8 +9,8 @@ PARSEPTR holds routine address called on (parse)
|
||||
C<* holds routine address called on C<. If the C<* override
|
||||
at 0x08 is nonzero, this routine is called instead.
|
||||
|
||||
IN> is the current position in IN(, which is the input buffer.
|
||||
|
||||
|
||||
|
||||
IN(* is a pointer to the input buffer, allocated at runtime.
|
||||
|
||||
(cont.)
|
||||
|
10
blk/083
10
blk/083
@ -7,10 +7,10 @@ WORDBUF is the buffer used by WORD
|
||||
BOOT C< PTR is used when Forth boots from in-memory
|
||||
source. See "Initialization sequence" below.
|
||||
|
||||
INTJUMP All RST offsets (well, not *all* at this moment, I
|
||||
still have to free those slots...) in boot binaries are made to
|
||||
jump to this address. If you use one of those slots for an
|
||||
interrupt, write a jump to the appropriate offset in that RAM
|
||||
location.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
(cont.)
|
||||
|
7
blk/084
7
blk/084
@ -7,10 +7,9 @@ for example), it can point elsewhere.
|
||||
NLPTR points to an alternative routine for NL (by default,
|
||||
CRLF).
|
||||
|
||||
BLK* see B416.
|
||||
|
||||
FUTURE USES section is unused for now.
|
||||
|
||||
DRIVERS section is reserved for recipe-specific
|
||||
drivers. Here is a list of known usages:
|
||||
|
||||
* 0x70-0x78: ACIA buffer pointers in RC2014 recipes.
|
||||
DRIVERS section is reserved for recipe-specific drivers.
|
||||
|
||||
|
23
blk/090
23
blk/090
@ -1,15 +1,10 @@
|
||||
4. Call INTERPRET
|
||||
4. Call INTERPRET which interprets boot source code until
|
||||
ASCII EOT (4) is met. This usually init drivers.
|
||||
5. Initialize rdln buffer, _sys entry (for EMPTY), prints
|
||||
"CollapseOS" and then calls (main).
|
||||
6. (main) interprets from rdln input (usually from KEY) until
|
||||
EOT is met, then calls BYE.
|
||||
|
||||
In other words, BOOT interprets bytes directly following
|
||||
CURRENT as Forth source code. This code will typically
|
||||
initialize all subsystems and then call RDLN$. As soon as
|
||||
this is called, INTERPRET will begin reading from RDLN< which
|
||||
reads from KEY.
|
||||
|
||||
In the "/emul" binaries, "HERE" is readjusted to "CURRENT @" so
|
||||
that we don't have to relocate compiled dicts. Note that in
|
||||
this context, the initialization code is fighting for space
|
||||
with HERE: New entries to the dict will overwrite that code!
|
||||
Also, because we're barebone, we can't have comments. This can
|
||||
lead to peculiar code in this area where we try to "waste"
|
||||
space in initialization code.
|
||||
In RAM-only environment, we will typically have a
|
||||
"CURRENT @ HERE !" line during init to have HERE begin at the
|
||||
end of the binary instead of RAMEND.
|
||||
|
9
blk/131
9
blk/131
@ -1,9 +0,0 @@
|
||||
( Relink a regular Forth full interpreter. )
|
||||
: RLCORE
|
||||
LIT< [ (find) DROP ( target )
|
||||
DUP 3 - @ ( t prevoff )
|
||||
( subtract [ name length )
|
||||
1- ( t o )
|
||||
RLDICT
|
||||
;
|
||||
|
2
blk/156
2
blk/156
@ -1,4 +1,4 @@
|
||||
: EMPTY
|
||||
LIT< _sys (find) NOT IF ABORT THEN
|
||||
LIT< _sys FIND NOT IF ABORT THEN
|
||||
DUP HERE ! CURRENT ! ;
|
||||
|
||||
|
6
blk/204
6
blk/204
@ -8,3 +8,9 @@ byte that is taken care of. We still need to adjust by another
|
||||
byte before writing the offset.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
(cont.)
|
||||
|
16
blk/205
Normal file
16
blk/205
Normal file
@ -0,0 +1,16 @@
|
||||
Structured flow
|
||||
|
||||
z80a also has words that behave similarly to IF..THEN and
|
||||
BEGIN..UNTIL.
|
||||
|
||||
On the IF side, we have IFZ, IFNZ, IFC, IFNC, and THEN,. When
|
||||
the opposite condition is met, a relative jump is made to
|
||||
THEN,'s PC. For example, if you have IFZ, a jump is made when
|
||||
Z is unset.
|
||||
|
||||
On the BEGIN,..AGAIN, side, it's a bit different. You start
|
||||
with your BEGIN, instruction, and then later you issue a
|
||||
JRxx, instr followed by AGAIN,. Exactly like you would do
|
||||
with a label.
|
||||
|
||||
(cont.)
|
3
blk/206
Normal file
3
blk/206
Normal file
@ -0,0 +1,3 @@
|
||||
On top of that, you have the very nice BREAK, instruction,
|
||||
which must also be preceeded by a JRxx, and will jump to the
|
||||
PC following the next AGAIN,
|
2
blk/209
2
blk/209
@ -8,4 +8,4 @@ JP [nn, (HL), (IX), (IY)]
|
||||
JR [, Z, NZ, C, NC]
|
||||
|
||||
DI EI EXDEHL EXX HALT
|
||||
NOP RET SCF
|
||||
NOP RET RETI RETN SCF
|
||||
|
9
blk/213
9
blk/213
@ -1,9 +1,6 @@
|
||||
: Z80AMEM+ 0x5b RAM+ @ + ;
|
||||
: ORG 0 Z80AMEM+ ;
|
||||
: BIN( 2 Z80AMEM+ ;
|
||||
: L1 4 Z80AMEM+ ; : L2 6 Z80AMEM+ ;
|
||||
: L3 8 Z80AMEM+ ; : L4 10 Z80AMEM+ ;
|
||||
: Z80A$ H@ 0x5b RAM+ ! 12 ALLOT 0 BIN( ! ;
|
||||
VARIABLE ORG
|
||||
VARIABLE BIN( 0 BIN( !
|
||||
VARIABLE L1 VARIABLE L2 VARIABLE L3 VARIABLE L4
|
||||
: A 7 ; : B 0 ; : C 1 ; : D 2 ;
|
||||
: E 3 ; : H 4 ; : L 5 ; : (HL) 6 ;
|
||||
: BC 0 ; : DE 1 ; : HL 2 ; : AF 3 ; : SP AF ;
|
||||
|
3
blk/224
3
blk/224
@ -5,4 +5,5 @@
|
||||
0xed5e OP2 IM2,
|
||||
0xeda0 OP2 LDI, 0xedb0 OP2 LDIR,
|
||||
0xeda8 OP2 LDD, 0xedb8 OP2 LDDR,
|
||||
0xed44 OP2 NEG, 0xed4d OP2 RETI,
|
||||
0xed44 OP2 NEG,
|
||||
0xed4d OP2 RETI, 0xed45 OP2 RETN,
|
||||
|
9
blk/246
9
blk/246
@ -1,13 +1,16 @@
|
||||
( Place BEGIN, where you want to jump back and AGAIN after
|
||||
a relative jump operator. Just like BSET and BWR. )
|
||||
: BEGIN, PC ;
|
||||
: AGAIN, PC - 1- A, ;
|
||||
|
||||
: BSET PC SWAP ! ;
|
||||
: BWR @ AGAIN, ;
|
||||
( same as BSET, but we need to write a placeholder )
|
||||
: FJR, PC 0 A, ;
|
||||
: IFZ, JRNZ, FJR, ;
|
||||
: IFNZ, JRZ, FJR, ;
|
||||
: IFC, JRNC, FJR, ;
|
||||
: IFNC, JRC, FJR, ;
|
||||
: THEN,
|
||||
DUP PC ( l l pc )
|
||||
-^ 1- ( l off )
|
||||
( warning: l is a PC offset, not a mem addr! )
|
||||
SWAP ORG @ + BIN( @ - ( off addr )
|
||||
C! ;
|
||||
|
13
blk/247
13
blk/247
@ -1,9 +1,8 @@
|
||||
: THEN,
|
||||
DUP PC ( l l pc )
|
||||
-^ 1- ( l off )
|
||||
( warning: l is a PC offset, not a mem addr! )
|
||||
SWAP ORG @ + BIN( @ - ( off addr )
|
||||
C!
|
||||
;
|
||||
: FWR BSET 0 A, ;
|
||||
: FSET @ THEN, ;
|
||||
: BREAK, FJR, 0x8000 OR ;
|
||||
: BREAK?, DUP 0x8000 AND IF
|
||||
0x7fff AND 1 ALLOT THEN, -1 ALLOT
|
||||
THEN ;
|
||||
: AGAIN, BREAK?, PC - 1- A, ;
|
||||
: BWR @ AGAIN, ;
|
||||
|
5
blk/263
5
blk/263
@ -1,16 +1,15 @@
|
||||
VARIABLE XCURRENT
|
||||
|
||||
: XCON XCURRENT CURRENT* ! ;
|
||||
: XCOFF 0x02 RAM+ CURRENT* ! ;
|
||||
|
||||
: (xentry) XCON (entry) XCOFF ;
|
||||
: XCREATE (xentry) 11 C, ;
|
||||
: XCODE XCON CODE XCOFF ;
|
||||
: XIMM XCON IMMEDIATE XCOFF ;
|
||||
: _xapply ( a -- a-off )
|
||||
DUP ORG @ > IF ORG @ - BIN( @ + THEN ;
|
||||
: X' XCON ' XCOFF ;
|
||||
: X['] XCON ' _xapply LITA XCOFF ;
|
||||
: XCOMPILE
|
||||
XCON ' _xapply LITA
|
||||
LIT< , (find) DROP _xapply , XCOFF ;
|
||||
LIT< , FIND DROP _xapply , XCOFF ;
|
||||
: X[COMPILE] XCON ' _xapply , XCOFF ;
|
||||
|
6
blk/283
6
blk/283
@ -8,8 +8,8 @@ EXDEHL, JP(HL), NOP, ( 17, nativeWord )
|
||||
0 JPnn, ( 1a, next ) 0 JPnn, ( 1d, chkPS )
|
||||
NOP, NOP, ( 20, numberWord ) NOP, NOP, ( 22, litWord )
|
||||
NOP, NOP, ( 24, addrWord ) NOP, NOP, ( 26, unused )
|
||||
RAMSTART 0x4e + JPnn, ( 28, RST 28 )
|
||||
0 JPnn, ( RST 28 )
|
||||
0 JPnn, ( 2b, doesWord ) NOP, NOP, ( 2e, unused )
|
||||
RAMSTART 0x4e + JPnn, ( RST 30 )
|
||||
0 JPnn, ( RST 30 )
|
||||
0 JPnn, ( 33, execute ) NOP, NOP, ( unused )
|
||||
RAMSTART 0x4e + JPnn, ( RST 38 )
|
||||
0 JPnn, ( RST 38 )
|
||||
|
2
blk/291
2
blk/291
@ -13,4 +13,4 @@ PC ORG @ 4 + ! ( find )
|
||||
NEG,
|
||||
A DECr,
|
||||
( special case. zero len? we never find anything. )
|
||||
JRZ, L1 FWR ( fail-B296 ) ( cont. )
|
||||
IFNZ, ( fail-B296 ) ( cont. )
|
||||
|
29
blk/293
29
blk/293
@ -1,16 +1,15 @@
|
||||
JRNZ, L2 FWR ( loopend )
|
||||
( match, let's compare the string then )
|
||||
DE DECss, ( Skip prev field. One less because we )
|
||||
DE DECss, ( pre-decrement )
|
||||
B C LDrr, ( loop C times )
|
||||
BEGIN, ( loop )
|
||||
( pre-decrement for easier Z matching )
|
||||
DE DECss,
|
||||
HL DECss,
|
||||
LDA(DE),
|
||||
(HL) CPr,
|
||||
JRNZ, L3 FWR ( loopend )
|
||||
DJNZ, AGAIN, ( loop )
|
||||
L2 FSET L3 FSET ( loopend )
|
||||
|
||||
IFZ,
|
||||
( match, let's compare the string then )
|
||||
DE DECss, ( Skip prev field. One less because we )
|
||||
DE DECss, ( pre-decrement )
|
||||
B C LDrr, ( loop C times )
|
||||
BEGIN,
|
||||
( pre-decrement for easier Z matching )
|
||||
DE DECss,
|
||||
HL DECss,
|
||||
LDA(DE),
|
||||
(HL) CPr,
|
||||
JRNZ, BREAK,
|
||||
DJNZ, AGAIN,
|
||||
THEN,
|
||||
( cont. )
|
||||
|
2
blk/296
2
blk/296
@ -1,4 +1,4 @@
|
||||
L1 FSET ( fail )
|
||||
THEN, ( zero length check, B291 )
|
||||
A XORr,
|
||||
A INCr,
|
||||
L2 FSET ( end )
|
||||
|
8
blk/328
8
blk/328
@ -2,15 +2,13 @@ CODE S=
|
||||
DE POPqq,
|
||||
HL POPqq,
|
||||
chkPS,
|
||||
BEGIN, ( loop )
|
||||
BEGIN,
|
||||
LDA(DE),
|
||||
(HL) CPr,
|
||||
JRNZ, L1 FWR ( not equal? break early to "end".
|
||||
NZ is set. )
|
||||
JRNZ, BREAK, ( not equal? break early. NZ is set. )
|
||||
A ORr, ( if our char is null, stop )
|
||||
HL INCss,
|
||||
DE INCss,
|
||||
JRNZ, AGAIN, ( loop )
|
||||
L1 FSET ( end )
|
||||
JRNZ, AGAIN,
|
||||
PUSHZ,
|
||||
;CODE
|
||||
|
16
blk/350
Normal file
16
blk/350
Normal file
@ -0,0 +1,16 @@
|
||||
Core words
|
||||
|
||||
This section contains arch-independent core words of Collapse
|
||||
OS. Those words are written in a way that make them entirely
|
||||
cross-compilable (see B260). When building Collapse OS, these
|
||||
words come right after the boot binary (B280).
|
||||
|
||||
Because this unit is designed to be cross-compiled, things are
|
||||
a little weird. It is compiling in the context of a full
|
||||
Forth interpreter with all bells and whistles (and z80
|
||||
assembler), but it has to obey strict rules:
|
||||
|
||||
1. Although it cannot compile a word that isn't defined yet,
|
||||
it can still execute an immediate from the host system.
|
||||
|
||||
(cont.)
|
16
blk/351
Normal file
16
blk/351
Normal file
@ -0,0 +1,16 @@
|
||||
2. Immediate words that have been cross compiled *cannot* be
|
||||
used. Only immediates from the host system can be used.
|
||||
3. If an immediate word compiles words, it can only be words
|
||||
that are part of the stable ABI.
|
||||
|
||||
All of this is because when cross compiling, all atom ref-
|
||||
erences are offsetted to the target system and are thus
|
||||
unusable directly. For the same reason, any reference to a word
|
||||
in the host system will obviously be wrong in the target
|
||||
system. More details in B260.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
(cont.)
|
9
blk/352
Normal file
9
blk/352
Normal file
@ -0,0 +1,9 @@
|
||||
This unit is loaded in two "low" and "high" parts. The low part
|
||||
is the biggest chunk and has the most definitions. The high
|
||||
part is the "sensitive" chunk and contains "LITN", ":" and ";"
|
||||
definitions which, once defined, kind of make any more defs
|
||||
impossible.
|
||||
|
||||
The gap between these 2 parts is the ideal place to put device
|
||||
driver code. Load the low part with "353 LOAD", the high part
|
||||
with "380 LOAD"
|
13
blk/353
Normal file
13
blk/353
Normal file
@ -0,0 +1,13 @@
|
||||
: RAM+ [ RAMSTART LITN ] + ;
|
||||
: BIN+ [ BIN( @ LITN ] + ;
|
||||
: HERE 0x04 RAM+ ;
|
||||
: CURRENT* 0x51 RAM+ ;
|
||||
: CURRENT CURRENT* @ ;
|
||||
: H@ HERE @ ;
|
||||
: FIND ( w -- a f ) CURRENT @ SWAP _find ;
|
||||
: QUIT
|
||||
(resRS)
|
||||
0 0x08 RAM+ ! ( 08 == C<* override )
|
||||
LIT< (main) FIND DROP EXECUTE
|
||||
;
|
||||
1 25 LOADR+ ( xcomp core low )
|
12
blk/354
Normal file
12
blk/354
Normal file
@ -0,0 +1,12 @@
|
||||
: ABORT (resSP) QUIT ;
|
||||
: ERR LIT< (print) FIND IF EXECUTE THEN ABORT ;
|
||||
: = CMP NOT ; : < CMP -1 = ; : > CMP 1 = ;
|
||||
: 0< 32767 > ; : >= < NOT ; : <= > NOT ; : 0>= 0< NOT ;
|
||||
: >< ( n l h -- f ) 2 PICK > ( n l f ) ROT ROT > AND ;
|
||||
: =><= 2 PICK >= ( n l f ) ROT ROT >= AND ;
|
||||
: MIN ( n n - n ) 2DUP > IF SWAP THEN DROP ;
|
||||
: MAX ( n n - n ) 2DUP < IF SWAP THEN DROP ;
|
||||
: C@+ ( a -- a+1 c ) DUP C@ SWAP 1+ SWAP ;
|
||||
: C!+ ( c a -- a+1 ) SWAP OVER C! 1+ ;
|
||||
: C@- ( a -- a-1 c ) DUP C@ SWAP 1- SWAP ;
|
||||
: C!- ( c a -- a-1 ) SWAP OVER C! 1- ;
|
11
blk/356
Normal file
11
blk/356
Normal file
@ -0,0 +1,11 @@
|
||||
( parsed is tight, all comments ahead. We read the first char
|
||||
outside of the loop because it *has* to be nonzero, which
|
||||
means _pdacc *has* to return 0.
|
||||
|
||||
Then, we check for '-'. If we get it, we advance by one,
|
||||
recurse and invert result.
|
||||
|
||||
We loop until _pdacc is nonzero, which means either WS or
|
||||
non-digit. 1 means WS, which means parsing was a success.
|
||||
-1 means non-digit, which means we have a non-decimal. )
|
||||
|
16
blk/357
Normal file
16
blk/357
Normal file
@ -0,0 +1,16 @@
|
||||
: (parsed) ( a -- n f )
|
||||
DUP C@ ( a c )
|
||||
DUP '-' = IF
|
||||
DROP 1+ ( a+1 ) (parsed) 0 ROT ( f 0 n )
|
||||
- SWAP EXIT ( 0-n f )
|
||||
THEN
|
||||
0 SWAP _pdacc ( a r f )
|
||||
DUP IF 2DROP 0 EXIT THEN
|
||||
BEGIN ( a r 0 )
|
||||
DROP SWAP 1+ ( r a+1 )
|
||||
DUP C@ ( r a c )
|
||||
ROT SWAP ( a r c )
|
||||
_pdacc ( a r f )
|
||||
DUP UNTIL
|
||||
1 = ( a r f )
|
||||
ROT DROP ( r f ) ;
|
11
blk/358
Normal file
11
blk/358
Normal file
@ -0,0 +1,11 @@
|
||||
( strings being sent to parse routines are always null
|
||||
terminated )
|
||||
|
||||
: (parsec) ( a -- n f )
|
||||
( apostrophe is ASCII 39 )
|
||||
DUP C@ 39 = OVER 2+ C@ 39 = AND ( a f )
|
||||
NOT IF 0 EXIT THEN ( a 0 )
|
||||
( surrounded by apos, good, return )
|
||||
1+ C@ 1 ( n 1 )
|
||||
;
|
||||
|
8
blk/359
Normal file
8
blk/359
Normal file
@ -0,0 +1,8 @@
|
||||
( returns negative value on error )
|
||||
: _ ( c -- n )
|
||||
DUP '0' '9' =><= IF '0' - EXIT THEN
|
||||
DUP 'a' 'f' =><= IF 0x57 ( 'a' - 10 ) - EXIT THEN
|
||||
DROP -1 ( bad )
|
||||
;
|
||||
|
||||
|
15
blk/360
Normal file
15
blk/360
Normal file
@ -0,0 +1,15 @@
|
||||
: (parseh) ( a -- n f )
|
||||
( '0': ASCII 0x30 'x': 0x78 0x7830: 30768 )
|
||||
DUP @ 30768 = NOT IF 0 EXIT THEN ( a 0 )
|
||||
( We have "0x" prefix )
|
||||
2+
|
||||
0 ( a r )
|
||||
BEGIN
|
||||
SWAP C@+ ( r a+1 c )
|
||||
DUP NOT IF 2DROP 1 EXIT THEN ( r, 1 )
|
||||
_ ( r a n )
|
||||
DUP 0< IF ROT 2DROP 0 EXIT THEN ( a 0 )
|
||||
ROT 16 * + ( a r*16+n )
|
||||
AGAIN
|
||||
;
|
||||
|
@ -4,5 +4,5 @@
|
||||
(parseb) IF EXIT THEN
|
||||
(parsed) IF EXIT THEN
|
||||
( nothing works )
|
||||
LIT< (wnf) (find) IF EXECUTE ELSE ABORT THEN
|
||||
LIT< (wnf) FIND IF EXECUTE ELSE ABORT THEN
|
||||
;
|
@ -4,8 +4,8 @@
|
||||
DUP NOT IF DROP 0x0c RAM+ @ THEN ( 0c == C<* )
|
||||
EXECUTE
|
||||
;
|
||||
: , HERE @ ! HERE @ 2+ HERE ! ;
|
||||
: C, HERE @ C! HERE @ 1+ HERE ! ;
|
||||
: , H@ ! H@ 2+ HERE ! ;
|
||||
: C, H@ C! H@ 1+ HERE ! ;
|
||||
: BIT@ ( bit addr -- f ) C@ SWAP RSHIFT 0x01 AND ;
|
||||
: BIT! ( f bit addr -- )
|
||||
SWAP 0x01 SWAP LSHIFT ROT ( addr mask f )
|
@ -1,5 +1,6 @@
|
||||
: WS? 33 < ;
|
||||
: EOT? 4 = ; ( 4 == ASCII EOT, CTRL+D )
|
||||
: EOT, 4 C, ;
|
||||
|
||||
: TOWORD
|
||||
0 ( dummy ) BEGIN
|
10
blk/368
Normal file
10
blk/368
Normal file
@ -0,0 +1,10 @@
|
||||
: [entry] ( w -- )
|
||||
H@ SWAP SCPY ( h )
|
||||
H@ SWAP - ( sz )
|
||||
( write prev value )
|
||||
H@ CURRENT @ - ,
|
||||
C, ( write size )
|
||||
H@ CURRENT !
|
||||
;
|
||||
|
||||
: (entry) WORD [entry] ;
|
@ -1,16 +1,15 @@
|
||||
( Words here until the end of the low part, unlike words
|
||||
preceeding them, aren't immediately needed for boot. But its
|
||||
better to have as many words as possible in the xcomp part. )
|
||||
: H@ HERE @ ;
|
||||
: IMMEDIATE
|
||||
CURRENT @ 1-
|
||||
DUP C@ 128 OR SWAP C!
|
||||
;
|
||||
DUP C@ 128 OR SWAP C! ;
|
||||
: IMMED? 1- C@ 0x80 AND ;
|
||||
: +! SWAP OVER @ + SWAP ! ;
|
||||
: -^ SWAP - ;
|
||||
: / /MOD SWAP DROP ;
|
||||
: MOD /MOD DROP ;
|
||||
|
||||
: ALLOT HERE +! ;
|
||||
: CREATE (entry) 11 ( 11 == cellWord ) C, ;
|
||||
: VARIABLE CREATE 2 ALLOT ;
|
||||
: LEAVE R> R> DROP I 1- >R >R ;
|
@ -1,7 +1,7 @@
|
||||
: '? WORD (find) ;
|
||||
: '? WORD FIND ;
|
||||
: '
|
||||
'? (?br) [ 4 , ] EXIT
|
||||
LIT< (wnf) (find) DROP EXECUTE
|
||||
LIT< (wnf) FIND DROP EXECUTE
|
||||
;
|
||||
: ROLL
|
||||
DUP NOT IF EXIT THEN
|
@ -11,4 +11,5 @@
|
||||
( We're done. Because we've popped RS, we'll exit parent
|
||||
definition )
|
||||
;
|
||||
: CONSTANT CREATE , DOES> @ ;
|
||||
|
5
blk/374
Normal file
5
blk/374
Normal file
@ -0,0 +1,5 @@
|
||||
: [IF]
|
||||
IF EXIT THEN
|
||||
LIT< [THEN] BEGIN DUP WORD S= UNTIL DROP ;
|
||||
: [THEN] ;
|
||||
|
@ -1,13 +1,12 @@
|
||||
: BLKMEM+ 0x59 RAM+ @ + ;
|
||||
( n -- Fetches block n and write it to BLK( )
|
||||
: BLK@* 0 BLKMEM+ ;
|
||||
: BLK@* 0x34 RAM+ ;
|
||||
( n -- Write back BLK( to storage at block n )
|
||||
: BLK!* 2 BLKMEM+ ;
|
||||
: BLK!* 0x36 RAM+ ;
|
||||
( Current blk pointer in ( )
|
||||
: BLK> 4 BLKMEM+ ;
|
||||
: BLK> 0x38 RAM+ ;
|
||||
( Whether buffer is dirty )
|
||||
: BLKDTY 6 BLKMEM+ ;
|
||||
: BLK( 8 BLKMEM+ ;
|
||||
: BLKDTY 0x3a RAM+ ;
|
||||
: BLK( 0x3c RAM+ @ ;
|
||||
: BLK) BLK( 1024 + ;
|
||||
|
||||
|
11
blk/377
Normal file
11
blk/377
Normal file
@ -0,0 +1,11 @@
|
||||
: BLK$
|
||||
H@ 0x3c ( BLK(* ) RAM+ !
|
||||
1024 ALLOT
|
||||
( LOAD detects end of block with ASCII EOT. This is why
|
||||
we write it there. )
|
||||
EOT,
|
||||
0 BLKDTY !
|
||||
-1 BLK> !
|
||||
;
|
||||
|
||||
|
@ -1,14 +1,15 @@
|
||||
: EMIT
|
||||
( 0x53==(emit) override )
|
||||
0x53 RAM+ @ DUP IF EXECUTE ELSE DROP (emit) THEN ;
|
||||
|
||||
: (print)
|
||||
BEGIN
|
||||
C@+ ( a+1 c )
|
||||
( exit if null or 0xd )
|
||||
DUP 0xd = OVER NOT OR IF 2DROP EXIT THEN
|
||||
EMIT ( a )
|
||||
AGAIN
|
||||
;
|
||||
|
||||
|
||||
AGAIN ;
|
||||
: BS 8 EMIT ; : LF 10 EMIT ; : CR 13 EMIT ;
|
||||
: CRLF CR LF ; : SPC 32 EMIT ;
|
||||
: NL 0x0a RAM+ @ ( NLPTR ) DUP IF EXECUTE ELSE DROP CRLF THEN ;
|
||||
: (uflw) LIT" stack underflow" ERR ;
|
||||
: (wnf) (print) SPC LIT" word not found" ERR ;
|
7
blk/382
Normal file
7
blk/382
Normal file
@ -0,0 +1,7 @@
|
||||
: ,"
|
||||
BEGIN
|
||||
C< DUP 34 ( ASCII " ) = IF DROP EXIT THEN C,
|
||||
AGAIN ;
|
||||
: LIT" 34 , ( litWord ) ," 0 C, ; IMMEDIATE
|
||||
: ." [COMPILE] LIT" COMPILE (print) ; IMMEDIATE
|
||||
: ABORT" [COMPILE] ." COMPILE ABORT ; IMMEDIATE
|
@ -1,10 +1,9 @@
|
||||
: RDLNMEM+ 0x57 RAM+ @ + ;
|
||||
( current position in INBUF )
|
||||
: IN> 0 RDLNMEM+ ;
|
||||
: IN> 0x30 RAM+ ;
|
||||
( points to INBUF )
|
||||
: IN( 2 RDLNMEM+ ;
|
||||
: IN( 0x32 RAM+ @ ;
|
||||
( points to INBUF's end )
|
||||
: IN) 0x40 ( buffer size ) 2+ RDLNMEM+ ;
|
||||
: IN) 0x40 ( buffer size ) IN( + ;
|
||||
|
||||
( flush input buffer )
|
||||
( set IN> to IN( and set IN> @ to null )
|
@ -1,10 +1,10 @@
|
||||
( handle backspace: go back one char in IN>, if possible, then
|
||||
emit SPC + BS )
|
||||
emit BS + SPC + BS )
|
||||
: (inbs)
|
||||
( already at IN( ? )
|
||||
IN> @ IN( = IF EXIT THEN
|
||||
IN> @ 1- IN> !
|
||||
SPC BS
|
||||
BS SPC BS
|
||||
;
|
||||
|
||||
: KEY
|
@ -1,16 +1,16 @@
|
||||
: (rdlnc) ( -- f )
|
||||
: (rdlnc) ( -- c )
|
||||
( buffer overflow? same as if we typed a newline )
|
||||
IN> @ IN) = IF 0x0a ELSE KEY THEN ( c )
|
||||
IN> @ IN) = IF 0x0a ELSE KEY THEN ( c )
|
||||
DUP 0x7f = IF DROP 0x8 THEN ( del? same as backspace )
|
||||
DUP 0x0a = IF DROP 0xd THEN ( lf? same as cr )
|
||||
( echo back )
|
||||
DUP EMIT ( c )
|
||||
( bacspace? handle and exit )
|
||||
DUP 0x8 = IF (inbs) EXIT THEN
|
||||
( echo back )
|
||||
DUP EMIT ( c )
|
||||
( write and advance )
|
||||
DUP ( keep as result ) ( c c )
|
||||
DUP ( keep as result ) ( c c )
|
||||
( We take advantage of the fact that c's MSB is always zero and
|
||||
thus ! automatically null-terminates our string )
|
||||
IN> @ ! 1 IN> +! ( c )
|
||||
IN> @ ! 1 IN> +! ( c )
|
||||
( if newline, replace with zero to indicate EOL )
|
||||
DUP 0xd = IF DROP 0 THEN ;
|
23
blk/390
23
blk/390
@ -1,14 +1,11 @@
|
||||
Cross-compiled core
|
||||
( Initializes the readln subsystem )
|
||||
: RDLN$
|
||||
H@ 0x32 ( IN(* ) RAM+ !
|
||||
( plus 2 for extra bytes after buffer: 1 for
|
||||
the last typed 0x0a and one for the following NULL. )
|
||||
IN) IN( - ALLOT
|
||||
(infl)
|
||||
['] RDLN< 0x0c RAM+ !
|
||||
1 0x06 RAM+ ! ( 06 == C<? )
|
||||
;
|
||||
|
||||
This units contains core Collapse OS that are cross-compiled.
|
||||
During building, these come right after the boot binary (B280).
|
||||
|
||||
Because this unit is designed to be cross-compiled, things are
|
||||
a little weird. It is compiling in the context of a full
|
||||
Forth interpreter with all bells and whistles (and z80
|
||||
assembler), but it has to obey strict rules:
|
||||
|
||||
1. It cannot compile a word from higher layers. Immediates are
|
||||
fine.
|
||||
|
||||
(cont.)
|
||||
|
27
blk/391
27
blk/391
@ -1,16 +1,13 @@
|
||||
2. Immediate words that have been cross compiled *cannot* be
|
||||
used. Only immediates from the host system can be used.
|
||||
3. If an immediate word compiles words, it can only be words
|
||||
that are part of the stable ABI.
|
||||
: .2 DUP 10 < IF SPC THEN . ;
|
||||
: EOL? ( c -- f ) DUP 0xd = SWAP NOT OR ;
|
||||
: LIST
|
||||
BLK@
|
||||
16 0 DO
|
||||
I 1+ .2 SPC
|
||||
64 I * BLK( + DUP 64 + SWAP DO
|
||||
I C@ DUP EOL? IF DROP LEAVE ELSE EMIT THEN
|
||||
LOOP
|
||||
NL
|
||||
LOOP
|
||||
;
|
||||
|
||||
All of this is because when cross compiling, all atom ref-
|
||||
erences are offsetted to the target system and are thus
|
||||
unusable directly. For the same reason, any reference to a word
|
||||
in the host system will obviously be wrong in the target
|
||||
system. More details in B260.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
(cont.)
|
||||
|
24
blk/392
24
blk/392
@ -1,9 +1,15 @@
|
||||
This unit is loaded in two "low" and "high" parts. The low part
|
||||
is the biggest chunk and has the most definitions. The high
|
||||
part is the "sensitive" chunk and contains "LITN", ":" and ";"
|
||||
definitions which, once defined, kind of make any more defs
|
||||
impossible.
|
||||
|
||||
The gap between these 2 parts is the ideal place to put device
|
||||
driver code. Load the low part with "393 LOAD", the high part
|
||||
with "415 LOAD"
|
||||
: INTERPRET
|
||||
BEGIN
|
||||
WORD DUP C@ EOT? IF DROP EXIT THEN
|
||||
FIND NOT IF (parse) ELSE EXECUTE THEN
|
||||
C<? NOT IF SPC LIT< ok (print) NL THEN
|
||||
AGAIN ;
|
||||
( Read from BOOT C< PTR and inc it. )
|
||||
: (boot<)
|
||||
( 2e == BOOT C< PTR )
|
||||
0x2e ( BOOT C< PTR ) RAM+ @ DUP C@ ( a c )
|
||||
SWAP 1 + 0x2e RAM+ ! ( c ) ;
|
||||
( pre-comment for tight LOAD: The 0x08==I check after INTERPRET
|
||||
is to check whether we're restoring to "_", the word above.
|
||||
if yes, then we're in a nested load. Also, the 1 in 0x06 is
|
||||
to avoid tons of "ok" displays. )
|
||||
|
31
blk/393
31
blk/393
@ -1,15 +1,16 @@
|
||||
: RAM+ [ RAMSTART LITN ] + ;
|
||||
: BIN+ [ BIN( @ LITN ] + ;
|
||||
: HERE 0x04 RAM+ ;
|
||||
: CURRENT* 0x51 RAM+ ;
|
||||
: CURRENT CURRENT* @ ;
|
||||
|
||||
( w -- a f )
|
||||
: (find) CURRENT @ SWAP _find ;
|
||||
|
||||
: QUIT
|
||||
(resRS)
|
||||
0 0x08 RAM+ ! ( 08 == C<* override )
|
||||
LIT< INTERPRET (find) DROP EXECUTE
|
||||
;
|
||||
1 25 LOADR+ ( xcomp core low )
|
||||
: LOAD
|
||||
BLK> @ >R ( save restorable variables to RSP )
|
||||
0x08 RAM+ @ >R ( 08 == C<* override )
|
||||
0x06 RAM+ @ >R ( C<? )
|
||||
0x2e RAM+ @ >R ( boot ptr )
|
||||
BLK@
|
||||
BLK( 0x2e RAM+ ! ( Point to beginning of BLK )
|
||||
['] (boot<) 0x08 RAM+ !
|
||||
1 0x06 RAM+ ! ( 06 == C<? )
|
||||
INTERPRET
|
||||
R> 0x2e RAM+ ! R> 0x06 RAM+ !
|
||||
I 0x08 RAM+ @ = IF ( nested load )
|
||||
R> DROP ( C<* ) R> BLK@
|
||||
ELSE ( not nested )
|
||||
R> 0x08 RAM+ ! R> DROP ( BLK> )
|
||||
THEN ;
|
||||
|
18
blk/394
18
blk/394
@ -1,14 +1,4 @@
|
||||
: ABORT (resSP) QUIT ;
|
||||
: = CMP NOT ; : < CMP -1 = ; : > CMP 1 = ;
|
||||
: 0< 32767 > ; : >= < NOT ; : <= > NOT ; : 0>= 0< NOT ;
|
||||
( n l h -- f )
|
||||
: >< 2 PICK > ( n l f ) ROT ROT > AND ;
|
||||
: =><= 2 PICK >= ( n l f ) ROT ROT >= AND ;
|
||||
( a -- a+1 c )
|
||||
: C@+ DUP C@ SWAP 1+ SWAP ;
|
||||
( c a -- a+1 )
|
||||
: C!+ SWAP OVER C! 1+ ;
|
||||
( a -- a-1 c )
|
||||
: C@- DUP C@ SWAP 1- SWAP ;
|
||||
( c a -- a-1 )
|
||||
: C!- SWAP OVER C! 1- ;
|
||||
: LOAD+ BLK> @ + LOAD ;
|
||||
( b1 b2 -- )
|
||||
: LOADR 1+ SWAP DO I DUP . NL LOAD LOOP ;
|
||||
: LOADR+ BLK> @ + SWAP BLK> @ + SWAP LOADR ;
|
||||
|
25
blk/396
25
blk/396
@ -1,11 +1,14 @@
|
||||
( parsed is tight, all comments ahead. We read the first char
|
||||
outside of the loop because it *has* to be nonzero, which
|
||||
means _pdacc *has* to return 0.
|
||||
|
||||
Then, we check for '-'. If we get it, we advance by one,
|
||||
recurse and invert result.
|
||||
|
||||
We loop until _pdacc is nonzero, which means either WS or
|
||||
non-digit. 1 means WS, which means parsing was a success.
|
||||
-1 means non-digit, which means we have a non-decimal. )
|
||||
|
||||
: (main) INTERPRET BYE ;
|
||||
: BOOT
|
||||
0x02 RAM+ CURRENT* !
|
||||
CURRENT @ 0x2e RAM+ ! ( 2e == BOOT C< PTR )
|
||||
0 0x08 RAM+ ! ( 08 == C<* override )
|
||||
0 0x53 RAM+ ! ( 53 == (emit) override )
|
||||
0 0x55 RAM+ ! ( 55 == (key) override )
|
||||
0 0x0a RAM+ ! ( NLPTR )
|
||||
( 0c == C<* )
|
||||
['] (boot<) 0x0c RAM+ !
|
||||
( boot< always has a char waiting. 06 == C<?* )
|
||||
1 0x06 RAM+ ! INTERPRET
|
||||
RDLN$ LIT< _sys [entry]
|
||||
LIT< CollapseOS (print) NL (main) ;
|
||||
|
31
blk/397
31
blk/397
@ -1,16 +1,15 @@
|
||||
: (parsed) ( a -- n f )
|
||||
DUP C@ ( a c )
|
||||
DUP '-' = IF
|
||||
DROP 1+ ( a+1 ) (parsed) 0 ROT ( f 0 n )
|
||||
- SWAP EXIT ( 0-n f )
|
||||
THEN
|
||||
0 SWAP _pdacc ( a r f )
|
||||
DUP IF 2DROP 0 EXIT THEN
|
||||
BEGIN ( a r 0 )
|
||||
DROP SWAP 1+ ( r a+1 )
|
||||
DUP C@ ( r a c )
|
||||
ROT SWAP ( a r c )
|
||||
_pdacc ( a r f )
|
||||
DUP UNTIL
|
||||
1 = ( a r f )
|
||||
ROT DROP ( r f ) ;
|
||||
( Now we have "as late as possible" stuff )
|
||||
: DO COMPILE 2>R H@ ; IMMEDIATE
|
||||
: LOOP COMPILE (loop) H@ - , ; IMMEDIATE
|
||||
( LEAVE is implemented in low xcomp )
|
||||
: LITN 32 , , ( 32 == NUMBER ) ;
|
||||
( gets its name at the very end. can't comment afterwards )
|
||||
: _ BEGIN LIT< ) WORD S= UNTIL ; IMMEDIATE
|
||||
: _ ( : will get its name almost at the very end )
|
||||
(entry)
|
||||
[ 14 ( == compiledWord ) LITN ] C,
|
||||
BEGIN
|
||||
WORD FIND
|
||||
IF ( is word ) DUP IMMED? IF EXECUTE ELSE , THEN
|
||||
ELSE ( maybe number ) (parse) LITN THEN
|
||||
AGAIN ;
|
||||
|
23
blk/398
23
blk/398
@ -1,11 +1,14 @@
|
||||
( strings being sent to parse routines are always null
|
||||
terminated )
|
||||
|
||||
: (parsec) ( a -- n f )
|
||||
( apostrophe is ASCII 39 )
|
||||
DUP C@ 39 = OVER 2+ C@ 39 = AND ( a f )
|
||||
NOT IF 0 EXIT THEN ( a 0 )
|
||||
( surrounded by apos, good, return )
|
||||
1+ C@ 1 ( n 1 )
|
||||
;
|
||||
: IF ( -- a | a: br cell addr )
|
||||
COMPILE (?br) H@ 2 ALLOT ( br cell allot )
|
||||
; IMMEDIATE
|
||||
: THEN ( a -- | a: br cell addr )
|
||||
DUP H@ -^ SWAP ( a-H a ) !
|
||||
; IMMEDIATE
|
||||
: ELSE ( a1 -- a2 | a1: IF cell a2: ELSE cell )
|
||||
COMPILE (br)
|
||||
2 ALLOT
|
||||
DUP H@ -^ SWAP ( a-H a )
|
||||
!
|
||||
H@ 2- ( push a. -2 for allot offset )
|
||||
; IMMEDIATE
|
||||
|
||||
|
17
blk/399
17
blk/399
@ -1,8 +1,9 @@
|
||||
( returns negative value on error )
|
||||
: _ ( c -- n )
|
||||
DUP '0' '9' =><= IF '0' - EXIT THEN
|
||||
DUP 'a' 'f' =><= IF 0x57 ( 'a' - 10 ) - EXIT THEN
|
||||
DROP -1 ( bad )
|
||||
;
|
||||
|
||||
|
||||
: BEGIN H@ ; IMMEDIATE
|
||||
: AGAIN COMPILE (br) H@ - , ; IMMEDIATE
|
||||
: UNTIL COMPILE (?br) H@ - , ; IMMEDIATE
|
||||
: [ INTERPRET ; IMMEDIATE
|
||||
: ] R> DROP ;
|
||||
: LIT< WORD 34 , SCPY 0 C, ; IMMEDIATE
|
||||
: LITA 36 , , ;
|
||||
: COMPILE ' LITA ['] , , ; IMMEDIATE
|
||||
: [COMPILE] ' , ; IMMEDIATE
|
||||
|
26
blk/400
26
blk/400
@ -1,15 +1,11 @@
|
||||
: (parseh) ( a -- n f )
|
||||
( '0': ASCII 0x30 'x': 0x78 0x7830: 30768 )
|
||||
DUP @ 30768 = NOT IF 0 EXIT THEN ( a 0 )
|
||||
( We have "0x" prefix )
|
||||
2+
|
||||
0 ( a r )
|
||||
BEGIN
|
||||
SWAP C@+ ( r a+1 c )
|
||||
DUP NOT IF 2DROP 1 EXIT THEN ( r, 1 )
|
||||
_ ( r a n )
|
||||
DUP 0< IF ROT 2DROP 0 EXIT THEN ( a 0 )
|
||||
ROT 16 * + ( a r*16+n )
|
||||
AGAIN
|
||||
;
|
||||
|
||||
( ';' can't have its name right away because, when created, it
|
||||
is not an IMMEDIATE yet and will not be treated properly by
|
||||
xcomp. )
|
||||
: _
|
||||
['] EXIT ,
|
||||
R> DROP ( exit : )
|
||||
; IMMEDIATE
|
||||
: ['] ' LITA ; IMMEDIATE
|
||||
';' X' _ 4 - C! ( give ; its name )
|
||||
':' X' _ 4 - C! ( give : its name )
|
||||
'(' X' _ 4 - C!
|
||||
|
11
blk/408
11
blk/408
@ -1,11 +0,0 @@
|
||||
: [entry]
|
||||
HERE @ ( w h )
|
||||
SWAP SCPY ( h )
|
||||
HERE @ SWAP - ( sz )
|
||||
( write prev value )
|
||||
HERE @ CURRENT @ - ,
|
||||
C, ( write size )
|
||||
HERE @ CURRENT !
|
||||
;
|
||||
|
||||
: (entry) WORD [entry] ;
|
7
blk/409
7
blk/409
@ -1,7 +0,0 @@
|
||||
: INTERPRET
|
||||
BEGIN
|
||||
WORD DUP C@ EOT? IF DROP EXIT THEN
|
||||
(find)
|
||||
NOT IF (parse) ELSE EXECUTE THEN
|
||||
C<? NOT IF LIT< (ok) (find) IF EXECUTE THEN THEN
|
||||
AGAIN ;
|
11
blk/410
11
blk/410
@ -1,11 +0,0 @@
|
||||
( system c< simply reads source from binary, starting at
|
||||
LATEST. Convenient way to bootstrap a new system. )
|
||||
: (boot<)
|
||||
( 2e == BOOT C< PTR )
|
||||
0x2e RAM+ @ ( a )
|
||||
DUP C@ ( a c )
|
||||
SWAP 1 + ( c a+1 )
|
||||
0x2e RAM+ ! ( c )
|
||||
;
|
||||
|
||||
|
13
blk/411
13
blk/411
@ -1,13 +0,0 @@
|
||||
: BOOT
|
||||
0x02 RAM+ CURRENT* !
|
||||
CURRENT @ 0x2e RAM+ ! ( 2e == BOOT C< PTR )
|
||||
0 0x08 RAM+ ! ( 08 == C<* override )
|
||||
0 0x53 RAM+ ! ( 53 == (emit) override )
|
||||
0 0x55 RAM+ ! ( 55 == (key) override )
|
||||
0 0x0a RAM+ ! ( NLPTR )
|
||||
( 0c == C<* )
|
||||
['] (boot<) 0x0c RAM+ !
|
||||
( boot< always has a char waiting. 06 == C<?* )
|
||||
1 0x06 RAM+ !
|
||||
INTERPRET BYE ;
|
||||
|
12
blk/417
12
blk/417
@ -1,12 +0,0 @@
|
||||
: BLK$
|
||||
H@ 0x59 RAM+ !
|
||||
( 1024 for the block, 8 for variables )
|
||||
1032 ALLOT
|
||||
( LOAD detects end of block with ASCII EOT. This is why
|
||||
we write it there. EOT == 0x04 )
|
||||
4 C,
|
||||
0 BLKDTY !
|
||||
-1 BLK> !
|
||||
;
|
||||
|
||||
|
15
blk/422
15
blk/422
@ -1,15 +0,0 @@
|
||||
: ,"
|
||||
BEGIN
|
||||
C<
|
||||
( 34 is ASCII for " )
|
||||
DUP 34 = IF DROP EXIT THEN C,
|
||||
AGAIN ;
|
||||
|
||||
: ."
|
||||
34 , ( 34 == litWord ) ," 0 C,
|
||||
COMPILE (print)
|
||||
; IMMEDIATE
|
||||
: ABORT" [COMPILE] ." COMPILE ABORT ; IMMEDIATE
|
||||
: BS 8 EMIT ; : LF 10 EMIT ; : CR 13 EMIT ;
|
||||
: CRLF CR LF ; : SPC 32 EMIT ;
|
||||
: NL 0x0a RAM+ @ ( NLPTR ) DUP IF EXECUTE ELSE DROP CRLF THEN ;
|
12
blk/430
12
blk/430
@ -1,12 +0,0 @@
|
||||
( Initializes the readln subsystem )
|
||||
: RDLN$
|
||||
( 57 == rdln's memory )
|
||||
H@ 0x57 RAM+ !
|
||||
( plus 2 for extra bytes after buffer: 1 for
|
||||
the last typed 0x0a and one for the following NULL. )
|
||||
IN) IN> - 2+ ALLOT
|
||||
(infl)
|
||||
['] RDLN< 0x0c RAM+ !
|
||||
1 0x06 RAM+ ! ( 06 == C<? )
|
||||
;
|
||||
|
13
blk/431
13
blk/431
@ -1,13 +0,0 @@
|
||||
: .2 DUP 10 < IF SPC THEN . ;
|
||||
: EOL? ( c -- f ) DUP 0xd = SWAP NOT OR ;
|
||||
: LIST
|
||||
BLK@
|
||||
16 0 DO
|
||||
I 1+ .2 SPC
|
||||
64 I * BLK( + DUP 64 + SWAP DO
|
||||
I C@ DUP EOL? IF DROP LEAVE ELSE EMIT THEN
|
||||
LOOP
|
||||
NL
|
||||
LOOP
|
||||
;
|
||||
|
4
blk/432
4
blk/432
@ -1,4 +0,0 @@
|
||||
( pre-comment for tight LOAD: The 0x08==I check after INTERPRET
|
||||
is to check whether we're restoring to "_", the word above.
|
||||
if yes, then we're in a nested load. Also, the 1 in 0x06 is
|
||||
to avoid tons of "ok" displays. )
|
16
blk/433
16
blk/433
@ -1,16 +0,0 @@
|
||||
: LOAD
|
||||
BLK> @ >R ( save restorable variables to RSP )
|
||||
0x08 RAM+ @ >R ( 08 == C<* override )
|
||||
0x06 RAM+ @ >R ( C<? )
|
||||
0x2e RAM+ @ >R ( boot ptr )
|
||||
BLK@
|
||||
BLK( 0x2e RAM+ ! ( Point to beginning of BLK )
|
||||
['] (boot<) 0x08 RAM+ !
|
||||
1 0x06 RAM+ ! ( 06 == C<? )
|
||||
INTERPRET
|
||||
R> 0x2e RAM+ ! R> 0x06 RAM+ !
|
||||
I 0x08 RAM+ @ = IF ( nested load )
|
||||
R> DROP ( C<* ) R> BLK@
|
||||
ELSE ( not nested )
|
||||
R> 0x08 RAM+ ! R> DROP ( BLK> )
|
||||
THEN ;
|
4
blk/434
4
blk/434
@ -1,4 +0,0 @@
|
||||
: LOAD+ BLK> @ + LOAD ;
|
||||
( b1 b2 -- )
|
||||
: LOADR 1+ SWAP DO I DUP . NL LOAD LOOP ;
|
||||
: LOADR+ BLK> @ + SWAP BLK> @ + SWAP LOADR ;
|
14
blk/435
14
blk/435
@ -1,14 +0,0 @@
|
||||
( LITN has to be defined after the last immediate usage of
|
||||
it to avoid bootstrapping issues )
|
||||
: LITN 32 , , ( 32 == NUMBER ) ;
|
||||
|
||||
: IMMED? 1- C@ 0x80 AND ;
|
||||
|
||||
( ';' can't have its name right away because, when created, it
|
||||
is not an IMMEDIATE yet and will not be treated properly by
|
||||
xcomp. )
|
||||
: _
|
||||
['] EXIT ,
|
||||
R> DROP ( exit : )
|
||||
; IMMEDIATE
|
||||
|
16
blk/436
16
blk/436
@ -1,16 +0,0 @@
|
||||
XCURRENT @ ( to PSP )
|
||||
: :
|
||||
(entry)
|
||||
( We cannot use LITN as IMMEDIATE because of bootstrapping
|
||||
issues. Same thing for ",".
|
||||
32 == NUMBER 14 == compiledWord )
|
||||
[ 32 H@ ! 2 ALLOT 14 H@ ! 2 ALLOT ] C,
|
||||
BEGIN
|
||||
WORD
|
||||
(find)
|
||||
( is word )
|
||||
IF DUP IMMED? IF EXECUTE ELSE , THEN
|
||||
( maybe number )
|
||||
ELSE (parse) LITN THEN
|
||||
AGAIN ;
|
||||
( from PSP ) ';' SWAP 4 - C!
|
14
blk/439
14
blk/439
@ -1,14 +0,0 @@
|
||||
XPACKed core
|
||||
|
||||
Most of Collapse OS' core words are cross compiled (B390).
|
||||
However, some of them are too dynamically referenced to be
|
||||
cross-compiled without great pain, so we XPACK (B267) them,
|
||||
that is, we put them in source form in the target's
|
||||
initialization section (see B89).
|
||||
|
||||
These words will be compiled into RAM at initialization, which
|
||||
is a bit wasteful both in RAM and in boot time, so we will
|
||||
typically relink (B120) that newly compiled binary and append
|
||||
it to our existing binary for optimal resource usage.
|
||||
|
||||
Load range: 440-446
|
10
blk/440
10
blk/440
@ -1,10 +0,0 @@
|
||||
: [ INTERPRET ; IMMEDIATE
|
||||
: ] R> DROP ;
|
||||
: LIT< WORD 34 , SCPY 0 C, ; IMMEDIATE
|
||||
: LITA 36 , , ;
|
||||
: ['] ' LITA ; IMMEDIATE
|
||||
: COMPILE ' LITA ['] , , ; IMMEDIATE
|
||||
: [COMPILE] ' , ; IMMEDIATE
|
||||
: BEGIN H@ ; IMMEDIATE
|
||||
: AGAIN COMPILE (br) H@ - , ; IMMEDIATE
|
||||
: UNTIL COMPILE (?br) H@ - , ; IMMEDIATE
|
13
blk/441
13
blk/441
@ -1,13 +0,0 @@
|
||||
: _ BEGIN LIT< ) WORD S= UNTIL ; IMMEDIATE
|
||||
40 CURRENT @ 4 - C!
|
||||
( Hello, hello, krkrkrkr... do you hear me?
|
||||
Ah, voice at last! Some lines above need comments
|
||||
BTW: Forth lines limited to 64 cols because of default
|
||||
input buffer size in Collapse OS
|
||||
|
||||
40 is ASCII for '('. We do this to simplify XPACK's task of
|
||||
not mistakenly consider '(' definition as a comment.
|
||||
LIT<: 34 == litWord
|
||||
LITA: 36 == addrWord
|
||||
COMPILE: Tough one. Get addr of caller word (example above
|
||||
(br)) and then call LITA on it. )
|
11
blk/442
11
blk/442
@ -1,11 +0,0 @@
|
||||
: IF ( -- a | a: br cell addr )
|
||||
COMPILE (?br)
|
||||
H@ ( push a )
|
||||
2 ALLOT ( br cell allot )
|
||||
; IMMEDIATE
|
||||
|
||||
: THEN ( a -- | a: br cell addr )
|
||||
DUP H@ -^ SWAP ( a-H a )
|
||||
!
|
||||
; IMMEDIATE
|
||||
|
12
blk/443
12
blk/443
@ -1,12 +0,0 @@
|
||||
: ELSE ( a1 -- a2 | a1: IF cell a2: ELSE cell )
|
||||
COMPILE (br)
|
||||
2 ALLOT
|
||||
DUP H@ -^ SWAP ( a-H a )
|
||||
!
|
||||
H@ 2- ( push a. -2 for allot offset )
|
||||
; IMMEDIATE
|
||||
|
||||
: [IF]
|
||||
IF EXIT THEN
|
||||
LIT< [THEN] BEGIN DUP WORD S= UNTIL DROP ;
|
||||
: [THEN] ;
|
8
blk/445
8
blk/445
@ -1,8 +0,0 @@
|
||||
: VARIABLE CREATE 2 ALLOT ;
|
||||
: CONSTANT CREATE , DOES> @ ;
|
||||
|
||||
( In addition to pushing H@ this compiles 2>R so that loop
|
||||
variables are sent to PS at runtime )
|
||||
: DO COMPILE 2>R H@ ; IMMEDIATE
|
||||
: LOOP COMPILE (loop) H@ - , ; IMMEDIATE
|
||||
( LEAVE is implemented in xcomp )
|
3
blk/446
3
blk/446
@ -1,3 +0,0 @@
|
||||
: (ok) SPC ." ok" NL ;
|
||||
: (uflw) ABORT" stack underflow" ;
|
||||
: (wnf) (print) SPC ABORT" word not found" ;
|
3
blk/490
3
blk/490
@ -4,8 +4,7 @@ Support code for the TRS-80 recipe. Contains drivers for the
|
||||
keyboard, video and floppy. At the moment, they are thin layer
|
||||
over the drivers provided by TRSDOS' SVC.
|
||||
|
||||
Load the Z80 words with "492 LOAD" and the high level part
|
||||
with "498 LOAD".
|
||||
Load with "492 LOAD".
|
||||
|
||||
There is also the RECV program at B502 and the XCOMP unit at
|
||||
B504
|
||||
|
2
blk/499
2
blk/499
@ -1,4 +1,4 @@
|
||||
: _err ABORT" FDerr" ;
|
||||
: _err LIT" FDerr" ERR ;
|
||||
: _cylsec ( sec -- cs, return sector/cylinder for given secid )
|
||||
( 4 256b sectors per block, 10 sec per cyl, 40 cyl max )
|
||||
10 /MOD ( sec cyl )
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user