@@ -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 | |||||
these constants to be set: | |||||
(B200) and cross compilation setup (B260). It requires some | |||||
constants to be set. See B420 for details. | |||||
SYSVARS: This is where system variables are placed. HERE is | |||||
then placed at SYSVARS+0x80 (ref B80). | |||||
RESERVED REGISTERS: At all times, IX points to RSP TOS and IY | |||||
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". | |||||
RS_ADDR: to be set to the bottom address of the Return Stack. | |||||
PS_ADDR: top address of the Parameter stack (PS grows down- | |||||
wards). Allow space for stack underflow protection (B76). | |||||
(cont.) | |||||
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. (cont.) |
@@ -1,14 +1,3 @@ | |||||
RESERVED REGISTERS: At all times, IX points to RSP TOS and IY | |||||
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". | |||||
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. | |||||
The boot binary is loaded in 2 parts. The first part, "decla- | The boot binary is loaded in 2 parts. The first part, "decla- | ||||
rations", are loaded after xcomp, before xcomp overrides, with | rations", are loaded after xcomp, before xcomp overrides, with | ||||
"282 LOAD". The rest, after xcomp overrides, with "283 335 | "282 LOAD". The rest, after xcomp overrides, with "283 335 | ||||
@@ -1,13 +1,14 @@ | |||||
PC ORG @ 1 + ! ( main ) | PC ORG @ 1 + ! ( main ) | ||||
( STACK OVERFLOW PROTECTION: See B76 ) | ( STACK OVERFLOW PROTECTION: See B76 ) | ||||
SP PS_ADDR LDdn, IX RS_ADDR LDdn, | SP PS_ADDR LDdn, IX RS_ADDR LDdn, | ||||
( HERE begins at RAMEND ) | |||||
HL SYSVARS 0x80 + LDdn, | |||||
SYSVARS 0x04 + LD(n)HL, ( RAM+04 == HERE ) | |||||
( LATEST is a label to the latest entry of the dict. It is | ( LATEST is a label to the latest entry of the dict. It is | ||||
written at offset 0x08 by the process or person building | written at offset 0x08 by the process or person building | ||||
Forth. ) | Forth. ) | ||||
BIN( @ 0x08 + LDHL(n), | BIN( @ 0x08 + LDHL(n), | ||||
SYSVARS 0x02 ( CURRENT ) + LD(n)HL, | SYSVARS 0x02 ( CURRENT ) + LD(n)HL, | ||||
HERESTART [IF] | |||||
HL HERESTART LDdn, | |||||
[THEN] | |||||
SYSVARS 0x04 + LD(n)HL, ( RAM+04 == HERE ) | |||||
DE BIN( @ 0x04 ( BOOT ) + LDdd(n), | DE BIN( @ 0x04 ( BOOT ) + LDdd(n), | ||||
JR, L1 FWR ( execute, B301 ) | JR, L1 FWR ( execute, B301 ) |
@@ -1,7 +1,10 @@ | |||||
anatomy. First, we have constants. Some of them are device- | anatomy. First, we have constants. Some of them are device- | ||||
specific, but some of them are always there. SYSVARS is the | specific, but some of them are always there. SYSVARS is the | ||||
address at which the RAM starts on the system. System variables | address at which the RAM starts on the system. System variables | ||||
will go there and HERE will go after it. | |||||
will go there and use 0x80 bytes. See B80. | |||||
HERESTART determines where... HERE is at startup. 0 means | |||||
"same as CURRENT". | |||||
RS_ADDR is where RSP starts and PS_ADDR is where PSP starts. | RS_ADDR is where RSP starts and PS_ADDR is where PSP starts. | ||||
RSP and PSP are designed to be contiguous. RSP goes up and PSP | RSP and PSP are designed to be contiguous. RSP goes up and PSP | ||||
@@ -10,7 +13,4 @@ goes down. If they meet, we know we have a stack overflow. | |||||
Then, we load the assembler and cross compilation unit, which | Then, we load the assembler and cross compilation unit, which | ||||
will be needed for the task ahead. | will be needed for the task ahead. | ||||
Then, it's a matter of adding layer after layer. For most | |||||
system, all those layers except the drivers will be added the | |||||
same way. Drivers are a bit tricker and machine specific. I | |||||
can't help you there, you'll have to use your wits. (cont.) | |||||
(cont.) |
@@ -1,3 +1,8 @@ | |||||
Then, it's a matter of adding layer after layer. For most | |||||
system, all those layers except the drivers will be added the | |||||
same way. Drivers are a bit tricker and machine specific. I | |||||
can't help you there, you'll have to use your wits. | |||||
After we've loaded the high part of the core words, we're at | After we've loaded the high part of the core words, we're at | ||||
the "wrapping up" part. We add what we call a "hook word" (an | the "wrapping up" part. We add what we call a "hook word" (an | ||||
empty word with a single letter name) which doesn't cost us | empty word with a single letter name) which doesn't cost us | ||||
@@ -7,9 +12,5 @@ CURRENT, which PC yields. That is why we write it to the | |||||
LATEST field of the stable ABI: This value will be used at | LATEST field of the stable ABI: This value will be used at | ||||
boot. | boot. | ||||
After the last word of the dictionary comes the "source init" | |||||
part. The boot sequence is designed to interpret whatever comes | |||||
after LATEST as Forth source, and this, until it reads ASCII | |||||
EOT character (4). This is generally used for driver init. | |||||
Good luck! | |||||
(cont.) |
@@ -0,0 +1,6 @@ | |||||
After the last word of the dictionary comes the "source init" | |||||
part. The boot sequence is designed to interpret whatever comes | |||||
after LATEST as Forth source, and this, until it reads ASCII | |||||
EOT character (4). This is generally used for driver init. | |||||
Good luck! |
@@ -1,5 +1,6 @@ | |||||
0x8000 CONSTANT SYSVARS | |||||
0xff00 CONSTANT RS_ADDR 0xfffa CONSTANT PS_ADDR | 0xff00 CONSTANT RS_ADDR 0xfffa CONSTANT PS_ADDR | ||||
RS_ADDR 0x80 - CONSTANT SYSVARS | |||||
0x8000 CONSTANT HERESTART | |||||
4 CONSTANT SDC_SPI | 4 CONSTANT SDC_SPI | ||||
5 CONSTANT SDC_CSLOW 6 CONSTANT SDC_CSHIGH | 5 CONSTANT SDC_CSLOW 6 CONSTANT SDC_CSHIGH | ||||
582 LOAD ( acia decl ) | 582 LOAD ( acia decl ) | ||||
@@ -242,15 +242,6 @@ static void native(NativeWord func) { | |||||
vm.nativew[vm.nativew_count++] = func; | vm.nativew[vm.nativew_count++] = func; | ||||
} | } | ||||
/* INITIAL BOOTSTRAP PLAN | |||||
For the initial bootstrap of the C VM, we treat every native word as a stable | |||||
word, giving it exactly the same memory offset as we have in the z80 forth.bin. | |||||
This will greatly simplify the initial bootstrap because we'll be able to | |||||
directly plug the "core words" part of forth.bin into our C VM and run it. | |||||
Once we have that, we can de-stabilize the native words that aren't part of the | |||||
stable ABI and bootstrap ourselves from ourselves. Good plan, right? | |||||
*/ | |||||
VM* VM_init() { | VM* VM_init() { | ||||
fprintf(stderr, "Using blkfs %s\n", BLKFS_PATH); | fprintf(stderr, "Using blkfs %s\n", BLKFS_PATH); | ||||
blkfp = fopen(BLKFS_PATH, "r+"); | blkfp = fopen(BLKFS_PATH, "r+"); | ||||
@@ -3,7 +3,7 @@ | |||||
#define SP_ADDR 0xffff | #define SP_ADDR 0xffff | ||||
#define RS_ADDR 0xff00 | #define RS_ADDR 0xff00 | ||||
#define SYSVARS 0xe800 | |||||
#define SYSVARS RS_ADDR-0x80 | |||||
typedef uint8_t byte; | typedef uint8_t byte; | ||||
typedef uint16_t word; | typedef uint16_t word; | ||||
@@ -1,6 +1,7 @@ | |||||
0xe800 CONSTANT SYSVARS | |||||
0xff00 CONSTANT RS_ADDR | 0xff00 CONSTANT RS_ADDR | ||||
0xfffa CONSTANT PS_ADDR | 0xfffa CONSTANT PS_ADDR | ||||
RS_ADDR 0x80 - CONSTANT SYSVARS | |||||
0 CONSTANT HERESTART | |||||
: CODE ( natidx -- ) (entry) 0 C, C, ; | : CODE ( natidx -- ) (entry) 0 C, C, ; | ||||
VARIABLE ORG | VARIABLE ORG | ||||
CREATE BIN( 0 , | CREATE BIN( 0 , | ||||
@@ -95,7 +96,6 @@ ORG @ 0xce + HERE ! | |||||
(entry) _ | (entry) _ | ||||
( Update LATEST ) | ( Update LATEST ) | ||||
PC ORG @ 8 + ! | PC ORG @ 8 + ! | ||||
," CURRENT @ HERE ! " | |||||
," BLK$ " | ," BLK$ " | ||||
," ' EFS@ BLK@* ! " | ," ' EFS@ BLK@* ! " | ||||
," ' EFS! BLK!* ! " | ," ' EFS! BLK!* ! " | ||||
@@ -1,6 +1,7 @@ | |||||
0xe800 CONSTANT SYSVARS | |||||
0xff00 CONSTANT RS_ADDR | 0xff00 CONSTANT RS_ADDR | ||||
0xfffa CONSTANT PS_ADDR | 0xfffa CONSTANT PS_ADDR | ||||
RS_ADDR 0x80 - CONSTANT SYSVARS | |||||
0 CONSTANT HERESTART | |||||
212 LOAD ( z80 assembler ) | 212 LOAD ( z80 assembler ) | ||||
262 LOAD ( xcomp ) | 262 LOAD ( xcomp ) | ||||
282 LOAD ( boot.z80.decl ) | 282 LOAD ( boot.z80.decl ) | ||||
@@ -26,7 +27,6 @@ | |||||
(entry) _ | (entry) _ | ||||
( Update LATEST ) | ( Update LATEST ) | ||||
PC ORG @ 8 + ! | PC ORG @ 8 + ! | ||||
," CURRENT @ HERE ! " | |||||
," BLK$ " | ," BLK$ " | ||||
," ' EFS@ BLK@* ! " | ," ' EFS@ BLK@* ! " | ||||
," ' EFS! BLK!* ! " | ," ' EFS! BLK!* ! " | ||||
@@ -1,8 +1,9 @@ | |||||
( 8K of onboard RAM ) | ( 8K of onboard RAM ) | ||||
0xc000 CONSTANT SYSVARS | |||||
0xdd00 CONSTANT RS_ADDR | 0xdd00 CONSTANT RS_ADDR | ||||
( Memory register at the end of RAM. Must not overwrite ) | ( Memory register at the end of RAM. Must not overwrite ) | ||||
0xddca CONSTANT PS_ADDR | 0xddca CONSTANT PS_ADDR | ||||
RS_ADDR 0x80 - CONSTANT SYSVARS | |||||
0xc000 CONSTANT HERESTART | |||||
SYSVARS 0x70 + CONSTANT VDP_MEM | SYSVARS 0x70 + CONSTANT VDP_MEM | ||||
0xbf CONSTANT VDP_CTLPORT | 0xbf CONSTANT VDP_CTLPORT | ||||
0xbe CONSTANT VDP_DATAPORT | 0xbe CONSTANT VDP_DATAPORT | ||||
@@ -1,6 +1,7 @@ | |||||
0x8000 CONSTANT SYSVARS | |||||
0xbf00 CONSTANT RS_ADDR | 0xbf00 CONSTANT RS_ADDR | ||||
0xbffa CONSTANT PS_ADDR | 0xbffa CONSTANT PS_ADDR | ||||
RS_ADDR 0x80 - CONSTANT SYSVARS | |||||
0x8000 CONSTANT HERESTART | |||||
SYSVARS 0x70 + CONSTANT LCD_MEM | SYSVARS 0x70 + CONSTANT LCD_MEM | ||||
SYSVARS 0x72 + CONSTANT KBD_MEM | SYSVARS 0x72 + CONSTANT KBD_MEM | ||||
0x01 CONSTANT KBD_PORT | 0x01 CONSTANT KBD_PORT | ||||
@@ -1,6 +1,7 @@ | |||||
0xff00 CONSTANT RS_ADDR | 0xff00 CONSTANT RS_ADDR | ||||
0xfffa CONSTANT PS_ADDR | 0xfffa CONSTANT PS_ADDR | ||||
RS_ADDR 0x80 - CONSTANT SYSVARS | RS_ADDR 0x80 - CONSTANT SYSVARS | ||||
0 CONSTANT HERESTART | |||||
212 LOAD ( z80 assembler ) | 212 LOAD ( z80 assembler ) | ||||
262 LOAD ( xcomp ) | 262 LOAD ( xcomp ) | ||||
282 LOAD ( boot.z80.decl ) | 282 LOAD ( boot.z80.decl ) | ||||
@@ -13,7 +14,6 @@ RS_ADDR 0x80 - CONSTANT SYSVARS | |||||
(entry) _ | (entry) _ | ||||
( Update LATEST ) | ( Update LATEST ) | ||||
PC ORG @ 8 + ! | PC ORG @ 8 + ! | ||||
," CURRENT @ HERE ! " | |||||
( 0x0a == NLPTR. TRS-80 wants CR-only newlines ) | ( 0x0a == NLPTR. TRS-80 wants CR-only newlines ) | ||||
," ' CR 0x0a RAM+ ! BLK$ FD$ " EOT, | ," ' CR 0x0a RAM+ ! BLK$ FD$ " EOT, | ||||
ORG @ 256 /MOD 2 PC! 2 PC! | ORG @ 256 /MOD 2 PC! 2 PC! | ||||
@@ -1,5 +1,6 @@ | |||||
0xff00 CONSTANT RS_ADDR 0xfffa CONSTANT PS_ADDR | 0xff00 CONSTANT RS_ADDR 0xfffa CONSTANT PS_ADDR | ||||
RS_ADDR 0x80 - CONSTANT SYSVARS | RS_ADDR 0x80 - CONSTANT SYSVARS | ||||
0 CONSTANT HERESTART | |||||
212 LOAD ( z80 assembler ) | 212 LOAD ( z80 assembler ) | ||||
262 LOAD ( xcomp ) | 262 LOAD ( xcomp ) | ||||
282 LOAD ( boot.z80.decl ) | 282 LOAD ( boot.z80.decl ) | ||||
@@ -37,6 +38,6 @@ CODE (key) | |||||
(entry) _ | (entry) _ | ||||
( Update LATEST ) | ( Update LATEST ) | ||||
PC ORG @ 8 + ! | PC ORG @ 8 + ! | ||||
," CURRENT @ HERE ! BLK$ FD$ ' FD@ BLK@* ! ' FD! BLK!* ! " EOT, | |||||
," BLK$ FD$ ' FD@ BLK@* ! ' FD! BLK!* ! " EOT, | |||||
ORG @ 256 /MOD 2 PC! 2 PC! | ORG @ 256 /MOD 2 PC! 2 PC! | ||||
H@ 256 /MOD 2 PC! 2 PC! | H@ 256 /MOD 2 PC! 2 PC! |