1
0
mirror of https://github.com/hsoft/collapseos.git synced 2024-11-02 10:20:55 +11:00

Compare commits

..

No commits in common. "9ad7ee7a4b10e133ee6155e252b24480ca0b6565" and "73b6d9905efabec76c77e57573d3841bcdf3e5fd" have entirely different histories.

29 changed files with 156 additions and 135 deletions

22
blk/000
View File

@ -1,16 +1,16 @@
Collapse OS Collapse OS file system
This is the first block of Collapse OS' filesystem which cons- This is a Forth-style filesystems which is very simple. It is a
ists of contiguous blocks of 1024 bytes organized in 16 lines list of 1024 bytes block, organised in 16 lines of 64 columns
of 64 characters. You can display a block's content with the each. You refer to blocks by numbers. You show them with LIST.
"LIST" command. For example, "123 LIST" shows the contents of You interpret them with LOAD. For a convenient way to browse
the block 123. If a block contains source code, you can inter- blocks, see Block editor at B100.
pret it with "LOAD".
Conventions: When you see "(cont.)" at the bottom right of a Conventions: When you see "(cont.)" at the bottom right of a
block, it means that the next block continues the same kind of block, it means that the next block continues the same kind of
contents. Block numbers are abbreviated with prefix "B". "BX" contents. This of course only work for informational text.
means "block X".
The master index of this filesystem is at B1. The Block editor Block numbers are abbreviated with prefix "B". "BX" means
at B100 is a convenient way to navigate blocks. "block X".
The master index of this filesystem is at B1.

View File

@ -6,7 +6,7 @@ MASTER INDEX
150 Extra words 150 Extra words
200 Z80 assembler 260 Cross compilation 200 Z80 assembler 260 Cross compilation
280 Z80 boot code 350 ACIA driver 280 Z80 boot code 350 ACIA driver
370 SD Card driver 390 Cross-compiled core 370 SD Card driver 390 Inner core
420 Core words 480 AT28 Driver 420 Core words 480 AT28 Driver
490 TRS-80 Recipe 520 Fonts 490 TRS-80 Recipe 520 Fonts
550 TI-84+ Recipe 550 TI-84+ Recipe

View File

@ -1,6 +1,6 @@
STACK OVERFLOW PROTECTION: To avoid having to check for stack STACK OVERFLOW PROTECTION: To avoid having to check for stack
underflow after each pop operation (which can end up being underflow after each pop operation (which can end up being
prohibitive in terms of costs), PS_ADDR should be set to prohibitive in terms of costs), we give ourselves a nice 6
at least 6 bytes before its actual limit. 6 bytes because we bytes buffer. 6 bytes because we seldom have words requiring
seldom have words requiring more than 3 items from the stack. more than 3 items from the stack. Then, at each "exit" call we
Then, at each "exit" call we check for stack underflow. check for stack underflow.

View File

@ -1,4 +1,5 @@
RAMSTART FUTURE USES +55 (key) override (cont.)
RAMSTART INITIAL_SP +55 (key) override
+02 CURRENT +57 readln's variables +02 CURRENT +57 readln's variables
+04 HERE +59 blk's variables +04 HERE +59 blk's variables
+06 C<? +5b z80a's variables +06 C<? +5b z80a's variables
@ -12,5 +13,4 @@ RAMSTART FUTURE USES +55 (key) override
+53 (emit) override +53 (emit) override
(cont.) (cont.)

View File

@ -1,3 +1,6 @@
INITIAL_SP holds the initial Stack Pointer value so
that we know where to reset it on ABORT
CURRENT points to the last dict entry. CURRENT points to the last dict entry.
HERE points to current write offset. HERE points to current write offset.
@ -10,7 +13,4 @@ C<* holds routine address called on C<. If the C<* override
at 0x08 is nonzero, this routine is called instead. at 0x08 is nonzero, this routine is called instead.
(cont.) (cont.)

20
blk/280
View File

@ -1,16 +1,16 @@
Z80 boot code Z80 boot code
This assembles the boot binary. It requires the Z80 assembler This assembles the boot binary. It requires the Z80 assembler
(B200) and cross compilation setup (B260). It also requires (B200) and cross compilation setup (B260).
these constants to be set:
RAMSTART: beginning address of RAM. This is where system On top of that, it requires RAMSTART to be defined as the
variables are placed. HERE is then placed at RAM+80 (ref B80). beginning address of RAM. This is where system variables are
placed. HERE is then placed at RAM+80 (ref B80).
RS_ADDR: to be set to the bottom address of the Return Stack. We also need RS_ADDR to be set to the bottom address of the
Return Stack.
PS_ADDR: top address of the Parameter stack (PS grows down- RESERVED REGISTERS: At all times, IX points to RSP TOS and IY
wards). Allow space for stack underflow protection (B76). is IP. SP points to PSP TOS, but you can still use the stack\
in native code. you just have to make sure you've restored it
before "next". (cont.)
(cont.)

15
blk/281
View File

@ -1,12 +1,7 @@
RESERVED REGISTERS: At all times, IX points to RSP TOS and IY (cont.) STABLE ABI: The boot binary starts with a list of
is IP. SP points to PSP TOS, but you can still use the stack\ references. The address of these references have to stay to
in native code. you just have to make sure you've restored it those addresses. The rest of the Collapse OS code depend on it.
before "next". In fact, up until 0x67, the (?br) wordref, pretty much
everything has to stay put.
STABLE ABI: The boot binary starts with a list of references.
The address of these references have to stay to those addr-
esses. The rest of the Collapse OS code depend on it. In fact,
up until 0x67, the (?br) wordref, pretty much everything has
to stay put.
To assemble, run "282 LOAD". To assemble, run "282 LOAD".

View File

@ -3,7 +3,8 @@ L1 BSET 'B' A, 'O' A, 'O' A, 'T' A, 0 A,
PC ORG @ 1 + ! ( main ) PC ORG @ 1 + ! ( main )
( STACK OVERFLOW PROTECTION: See B76 ) ( STACK OVERFLOW PROTECTION: See B76 )
SP PS_ADDR LDddnn, SP 0xfffa LDddnn,
RAMSTART SP LD(nn)dd, ( RAM+00 == INITIAL_SP )
IX RS_ADDR LDddnn, IX RS_ADDR LDddnn,
( HERE begins at RAMEND ) ( HERE begins at RAMEND )
HL RAMSTART 0x80 + LDddnn, HL RAMSTART 0x80 + LDddnn,

10
blk/299
View File

@ -1,10 +1,14 @@
PC ORG @ 0x1e + ! ( chkPS ) PC ORG @ 0x1e + ! ( chkPS )
HL PUSHqq, HL PUSHqq,
RAMSTART LDHL(nn), ( RAM+00 == INITIAL_SP )
( We have the return address for this very call on the stack ( We have the return address for this very call on the stack
and protected registers. 4 - is to compensate that. ) and protected registers. Let's compensate )
HL PS_ADDR 4 - LDddnn, HL DECss,
HL DECss,
HL DECss,
HL DECss,
SP SUBHLss, SP SUBHLss,
HL POPqq, HL POPqq,
CNC RETcc, ( PS_ADDR >= SP? good ) CNC RETcc, ( INITIAL_SP >= SP? good )
JR, L2 BWR ( abortUnderflow-B298 ) JR, L2 BWR ( abortUnderflow-B298 )

View File

@ -9,7 +9,7 @@ CODE PICK
B (HL) LDrr, B (HL) LDrr,
( check PS range before returning ) ( check PS range before returning )
EXDEHL, EXDEHL,
HL PS_ADDR LDddnn, RAMSTART LDHL(nn), ( RAM+00 == INITIAL_SP )
DE SUBHLss, DE SUBHLss,
CC L2 @ JPccnn, ( abortUnderflow-B298 ) CC L2 @ JPccnn, ( abortUnderflow-B298 )
BC PUSHqq, BC PUSHqq,

View File

@ -1,5 +1,5 @@
CODE S0 CODE S0
HL PS_ADDR LDddnn, RAMSTART LDHL(nn), ( RAM+00 == INITIAL_SP )
HL PUSHqq, HL PUSHqq,
;CODE ;CODE

View File

@ -3,7 +3,8 @@ CODE BYE
;CODE ;CODE
CODE (resSP) CODE (resSP)
SP PS_ADDR LDddnn, ( INITIAL_SP == RAM+0 )
SP RAMSTART LDdd(nn),
;CODE ;CODE
CODE (resRS) CODE (resRS)

View File

@ -1,9 +1,9 @@
ACIA driver ACIA driver
Manage I/O from an asynchronous communication interface adapter Manage I/O from an asynchronous communication interface adapter
(ACIA). provides "(emit)" to put c char on the ACIA as well as (ACIA). provides "EMIT" to put c char on the ACIA as well as
an input buffer from which a provided "(key)" reads. You have an input buffer. You have to call "~ACIA" on interrupt for
to call "~ACIA" on interrupt for this module to work well. this module to work well.
CONFIGURATION CONFIGURATION
@ -12,5 +12,4 @@ ACIA_IO: IO port for the ACIA's data registers
ACIA_MEM: Address in memory that can be used variables shared ACIA_MEM: Address in memory that can be used variables shared
with ACIA's native words. 8 bytes used. with ACIA's native words. 8 bytes used.
The whole driver is cross-compilable and is loaded with Load z80 words with "352 LOAD" and Forth words with "357 LOAD".
"352 LOAD"

View File

@ -1,8 +1,15 @@
( Save ACIA conf )
ACIA_CTL
: ACIA_CTL [ LITN ] ;
ACIA_IO
: ACIA_IO [ LITN ] ;
ACIA_MEM
: ACIA_MEM [ LITN ] ;
( Memory layout ( Memory layout
+0 ACIAR> +0 ACIAR>
+2 ACIAW> +2 ACIAW>
+4 ACIA( +4 ACIA(
+6 ACIA) ) +6 ACIA) )
1 6 LOADR+ 1 3 LOADR+

View File

@ -1,4 +1,4 @@
CREATE ~ACIA (entry) ~ACIA
AF PUSHqq, AF PUSHqq,
HL PUSHqq, HL PUSHqq,
DE PUSHqq, DE PUSHqq,

11
blk/356
View File

@ -1,11 +0,0 @@
( Points to ACIA buf )
: ACIA( [ ACIA_MEM 4 + LITN ] ;
( Points to ACIA buf end )
: ACIA) [ ACIA_MEM 6 + LITN ] ;
( Read buf pointer. Pre-inc )
: ACIAR> [ ACIA_MEM LITN ] ;
( Write buf pointer. Post-inc )
: ACIAW> [ ACIA_MEM 2 + LITN ] ;
( This means that if W> == R>, buffer is full.
If R>+1 == W>, buffer is empty. )

17
blk/357
View File

@ -1,16 +1 @@
: (key) 1 3 LOADR+
( inc then fetch )
ACIAR> @ 1+ DUP ACIA) @ = IF
DROP ACIA( @
THEN
( As long as R> == W>-1, it means that buffer is empty )
BEGIN DUP ACIAW> @ = NOT UNTIL
ACIAR> !
ACIAR> @ C@
;
: (emit)
( As long at CTL bit 1 is low, we are transmitting. wait )
BEGIN [ ACIA_CTL LITN ] PC@ 0x02 AND UNTIL
( The way is clear, go! )
[ ACIA_IO LITN ] PC!
;

27
blk/358
View File

@ -1,16 +1,13 @@
: ACIA$ 0x20 CONSTANT ACIABUFSZ
H@ DUP DUP ACIA( ! ACIAR> !
1+ ACIAW> ! ( write index starts one position later ) ( Points to ACIA buf )
0x20 ( buffer size ) ALLOT : ACIA( [ ACIA_MEM 4 + LITN ] ;
H@ ACIA) ! ( Points to ACIA buf end )
( setup ACIA : ACIA) [ ACIA_MEM 6 + LITN ] ;
CR7 (1) - Receive Interrupt enabled ( Read buf pointer. Pre-inc )
CR6:5 (00) - RTS low, transmit interrupt disabled. : ACIAR> [ ACIA_MEM LITN ] ;
CR4:2 (101) - 8 bits + 1 stop bit ( Write buf pointer. Post-inc )
CR1:0 (10) - Counter divide: 64 ) : ACIAW> [ ACIA_MEM 2 + LITN ] ;
0b10010110 [ ACIA_CTL LITN ] PC! ( This means that if W> == R>, buffer is full.
( setup interrupt ) If R>+1 == W>, buffer is empty. )
0xc3 0x4e RAM+ C! ( c3==JP, 4e==INTJUMP )
~ACIA 0x4f RAM+ !
(im1) ;

16
blk/359 Normal file
View File

@ -0,0 +1,16 @@
: (key)
( inc then fetch )
ACIAR> @ 1+ DUP ACIA) @ = IF
DROP ACIA( @
THEN
( As long as R> == W>-1, it means that buffer is empty )
BEGIN DUP ACIAW> @ = NOT UNTIL
ACIAR> !
ACIAR> @ C@
;
: (emit)
( As long at CTL bit 1 is low, we are transmitting. wait )
BEGIN ACIA_CTL PC@ 0x02 AND UNTIL
( The way is clear, go! )
ACIA_IO PC!
;

16
blk/360 Normal file
View File

@ -0,0 +1,16 @@
: ACIA$
H@ DUP DUP ACIA( ! ACIAR> !
1+ ACIAW> ! ( write index starts one position later )
ACIABUFSZ ALLOT
H@ ACIA) !
( setup ACIA
CR7 (1) - Receive Interrupt enabled
CR6:5 (00) - RTS low, transmit interrupt disabled.
CR4:2 (101) - 8 bits + 1 stop bit
CR1:0 (10) - Counter divide: 64 )
0b10010110 ACIA_CTL PC!
( setup interrupt )
0xc3 0x4e RAM+ C! ( c3==JP, 4e==INTJUMP )
['] ~ACIA 0x4f RAM+ !
(im1) ;

20
blk/390
View File

@ -1,14 +1,16 @@
Cross-compiled core Inner core
This units contains core Collapse OS that are cross-compiled. This unit represents core definitions that happen right after
During building, these come right after the boot binary (B280). native definitions. Before core.fs.
Because this unit is designed to be cross-compiled, things are Unlike core.fs and its followers, this unit isn't self-
a little weird. It is compiling in the context of a full sustained. Like native defs it uses the machinery of a full
Forth interpreter with all bells and whistles (and z80 Forth interpreter, notably for flow structures.
assembler), but it has to obey strict rules:
Because of that, it has to obey specific rules:
1. It cannot compile a word from higher layers. Using
immediates is fine though.
1. It cannot compile a word from higher layers. Immediates are
fine.
(cont.) (cont.)

28
blk/391
View File

@ -1,16 +1,16 @@
2. Immediate words that have been cross compiled *cannot* be 2. If it references a word from this unit or from native
used. Only immediates from the host system can be used. definitions, these need to be properly offsetted because
3. If an immediate word compiles words, it can only be words their offset at compile time are not the same as their
that are part of the stable ABI. runtime offsets.
3. Anything they refer to in the boot binary has to be properly
stabilized.
4. Make sure that the words you compile are not overridden by
the full interpreter.
5. When using words as immediates, make sure that they're not
defined in icore or, if they are, make sure that they are
*not* offsetted
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.
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 ";" (cont.)
definitions which, once defined, kind of make any more defs
impossible. (cont.)

12
blk/392
View File

@ -1,3 +1,15 @@
Those rules are mostly met by the "xcomp" unit, which is
expected to have been loaded prior to icore and redefines ":"
and other defining words. So, in other words, when compiling
icore, ":" doesn't means what you think it means, go look in
B260.
This 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 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 driver code. Load the low part with "393 LOAD", the high part
with "415 LOAD" with "415 LOAD"

14
blk/420
View File

@ -1,12 +1,12 @@
Core words Core words
These words follow cross-compiled words, but unlike them, these These words follow Inner core words, but unlike them, these are
are self-bootstrapping and don't depend on the Cross Compiler. self-bootstrapping and don't depend on the Cross Compiler. They
They will typically be included in source form right after a will typically be included in source form right after a stage1
stage1 binary which will interpret it on boot and bootstrap binary which will interpret it on boot and bootstrap itself to
itself to a full intepreter, which can then be relinked with a full intepreter, which can then be relinked with the
the Relinker. There is no loader for these libraries because Relinker. There is no loader for these libraries because you
you will typically XPACK (B267) them. will typically XPACK (B267) them.
422 core 438 print 422 core 438 print
442 fmt 447 readln 442 fmt 447 readln

Binary file not shown.

View File

@ -1,6 +1,5 @@
0xe800 CONSTANT RAMSTART 0xe800 CONSTANT RAMSTART
0xf000 CONSTANT RS_ADDR 0xf000 CONSTANT RS_ADDR
0xfffa CONSTANT PS_ADDR
212 LOAD ( z80 assembler ) 212 LOAD ( z80 assembler )
262 LOAD ( xcomp ) 262 LOAD ( xcomp )
: CODE XCODE ; : CODE XCODE ;

View File

@ -1,6 +1,5 @@
0x8000 CONSTANT RAMSTART 0x8000 CONSTANT RAMSTART
0xf000 CONSTANT RS_ADDR 0xf000 CONSTANT RS_ADDR
0xfffa CONSTANT PS_ADDR
0x80 CONSTANT ACIA_CTL 0x80 CONSTANT ACIA_CTL
0x81 CONSTANT ACIA_IO 0x81 CONSTANT ACIA_IO
4 CONSTANT SDC_SPI 4 CONSTANT SDC_SPI
@ -12,20 +11,21 @@ RAMSTART 0x70 + CONSTANT ACIA_MEM
: CODE XCODE ; : CODE XCODE ;
: IMMEDIATE XIMM ; : IMMEDIATE XIMM ;
: (entry) (xentry) ; : (entry) (xentry) ;
: CREATE XCREATE ;
: : [ ' X: , ] ; : : [ ' X: , ] ;
CURRENT @ XCURRENT ! CURRENT @ XCURRENT !
282 LOAD ( boot.z80 ) 282 LOAD ( boot.z80 )
393 LOAD ( icore low ) 352 LOAD ( acia.z80 )
352 LOAD ( acia )
372 LOAD ( sdc.z80 ) 372 LOAD ( sdc.z80 )
393 LOAD ( icore low )
415 LOAD ( icore high ) 415 LOAD ( icore high )
(entry) _ (entry) _
( Update LATEST ) ( Update LATEST )
PC ORG @ 8 + ! PC ORG @ 8 + !
422 452 XPACKR ( core print fmt readln ) 422 437 XPACKR ( core )
358 360 XPACKR ( acia.fs )
438 452 XPACKR ( print fmt readln )
123 132 XPACKR ( linker ) 123 132 XPACKR ( linker )
," : _ ACIA$ RDLN$ (ok) ; _ " ," : _ ACIA$ RDLN$ (ok) ; _ "
ORG @ 256 /MOD 2 PC! 2 PC! ORG @ 256 /MOD 2 PC! 2 PC!

View File

@ -1,6 +1,5 @@
0x8000 CONSTANT RAMSTART 0x8000 CONSTANT RAMSTART
0xb000 CONSTANT RS_ADDR 0xb000 CONSTANT RS_ADDR
0xbffa CONSTANT PS_ADDR
RAMSTART 0x70 + CONSTANT LCD_MEM RAMSTART 0x70 + CONSTANT LCD_MEM
RAMSTART 0x72 + CONSTANT KBD_MEM RAMSTART 0x72 + CONSTANT KBD_MEM
0x01 CONSTANT KBD_PORT 0x01 CONSTANT KBD_PORT

View File

@ -1,5 +1,4 @@
0xf000 CONSTANT RS_ADDR 0xf000 CONSTANT RS_ADDR
0xfffa CONSTANT PS_ADDR
RS_ADDR 0x80 - CONSTANT RAMSTART RS_ADDR 0x80 - CONSTANT RAMSTART
212 LOAD ( z80 assembler ) 212 LOAD ( z80 assembler )
262 LOAD ( xcomp ) 262 LOAD ( xcomp )