mirror of
https://github.com/hsoft/collapseos.git
synced 2024-11-02 16:10:55 +11:00
Compare commits
No commits in common. "ca7c21d49f318b053259780dafe0a62bf6f1ed36" and "ffe61a12f8543cf4c2081dab219edee2b4827ae1" have entirely different histories.
ca7c21d49f
...
ffe61a12f8
@ -33,11 +33,11 @@ forth/forth0.bin: forth/glue0.asm $(ZASMBIN)
|
|||||||
forth/forth0-bin.h: forth/forth0.bin
|
forth/forth0-bin.h: forth/forth0.bin
|
||||||
./bin2c.sh KERNEL < forth/forth0.bin | tee $@ > /dev/null
|
./bin2c.sh KERNEL < forth/forth0.bin | tee $@ > /dev/null
|
||||||
|
|
||||||
forth/stage1: forth/stage.c $(OBJS) forth/forth0-bin.h
|
forth/stage1: forth/stage1.c $(OBJS) forth/forth0-bin.h
|
||||||
$(CC) forth/stage.c $(OBJS) -o $@
|
$(CC) forth/stage1.c $(OBJS) -o $@
|
||||||
|
|
||||||
forth/stage1dbg: forth/stage.c $(OBJS) forth/forth0-bin.h
|
forth/stage1dbg: forth/stage1.c $(OBJS) forth/forth0-bin.h
|
||||||
$(CC) -DDEBUG forth/stage.c $(OBJS) -o $@
|
$(CC) -DDEBUG forth/stage1.c $(OBJS) -o $@
|
||||||
|
|
||||||
forth/core.bin: $(FORTHSRC_PATHS) forth/stage1
|
forth/core.bin: $(FORTHSRC_PATHS) forth/stage1
|
||||||
cat $(FORTHSRC_PATHS) | ./forth/stage1 | tee $@ > /dev/null
|
cat $(FORTHSRC_PATHS) | ./forth/stage1 | tee $@ > /dev/null
|
||||||
|
@ -1,4 +1,13 @@
|
|||||||
|
; RAM disposition
|
||||||
|
;
|
||||||
|
; Because this glue code also serves stage0 which needs HERE to start right
|
||||||
|
; after the code, we have a peculiar RAM setup here: it lives at the very end
|
||||||
|
; of the address space, just under RS_ADDR at 0xf000
|
||||||
|
; Warning: The offsets of native dict entries must be exactly the same between
|
||||||
|
; glue0.asm and glue1.asm
|
||||||
.equ RAMSTART 0xe800
|
.equ RAMSTART 0xe800
|
||||||
|
.equ HERE 0xe700 ; override, in sync with stage1.c
|
||||||
|
.equ CURRENT 0xe702 ; override, in sync with stage1.c
|
||||||
.equ HERE_INITIAL CODE_END ; override
|
.equ HERE_INITIAL CODE_END ; override
|
||||||
.equ STDIO_PORT 0x00
|
.equ STDIO_PORT 0x00
|
||||||
|
|
||||||
|
@ -4,19 +4,20 @@
|
|||||||
#include "../emul.h"
|
#include "../emul.h"
|
||||||
#include "forth0-bin.h"
|
#include "forth0-bin.h"
|
||||||
|
|
||||||
/* Staging binaries
|
/* Stage 1
|
||||||
|
|
||||||
The role of a stage executable is to compile definitions in a dictionary and
|
The role of the stage 1 executable is to start from a bare Forth executable
|
||||||
then spit the difference between the starting binary and the new binary.
|
(stage 0) that will compile core non-native definitions into binary form and
|
||||||
|
append this to existing bootstrap binary to form our final Forth bin.
|
||||||
That binary can then be grafted to an exiting Forth binary to augment its
|
|
||||||
dictionary.
|
|
||||||
|
|
||||||
We could, if we wanted, run only with the bootstrap binary and compile core
|
We could, if we wanted, run only with the bootstrap binary and compile core
|
||||||
defs at runtime, but that would mean that those defs live in RAM. In may system,
|
defs at runtime, but that would mean that those defs live in RAM. In may system,
|
||||||
RAM is much more constrained than ROM, so it's worth it to give ourselves the
|
RAM is much more constrained than ROM, so it's worth it to give ourselves the
|
||||||
trouble of compiling defs to binary.
|
trouble of compiling defs to binary.
|
||||||
|
|
||||||
|
This stage 0 executable has to be layed out in a particular manner: HERE must
|
||||||
|
directly follow executable's last byte so that we don't waste spce and also
|
||||||
|
that wordref offsets correspond.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// When DEBUG is set, stage1 is a core-less forth that works interactively.
|
// When DEBUG is set, stage1 is a core-less forth that works interactively.
|
||||||
@ -27,12 +28,13 @@ trouble of compiling defs to binary.
|
|||||||
// in sync with glue.asm
|
// in sync with glue.asm
|
||||||
#define RAMSTART 0x900
|
#define RAMSTART 0x900
|
||||||
#define STDIO_PORT 0x00
|
#define STDIO_PORT 0x00
|
||||||
// To know which part of RAM to dump, we listen to port 2, which at the end of
|
// In sync with glue code. This way, we can know where HERE was when we stopped
|
||||||
// its compilation process, spits its HERE addr to port 2 (MSB first)
|
// running
|
||||||
#define HERE_PORT 0x02
|
#define HERE 0xe700
|
||||||
|
// We also need to know what CURRENT is so we can write our first two bytes
|
||||||
|
#define CURRENT 0xe702
|
||||||
|
|
||||||
static int running;
|
static int running;
|
||||||
static uint16_t ending_here = 0;
|
|
||||||
|
|
||||||
static uint8_t iord_stdio()
|
static uint8_t iord_stdio()
|
||||||
{
|
{
|
||||||
@ -52,19 +54,12 @@ static void iowr_stdio(uint8_t val)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void iowr_here(uint8_t val)
|
|
||||||
{
|
|
||||||
ending_here <<= 8;
|
|
||||||
ending_here |= val;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
Machine *m = emul_init();
|
Machine *m = emul_init();
|
||||||
m->ramstart = RAMSTART;
|
m->ramstart = RAMSTART;
|
||||||
m->iord[STDIO_PORT] = iord_stdio;
|
m->iord[STDIO_PORT] = iord_stdio;
|
||||||
m->iowr[STDIO_PORT] = iowr_stdio;
|
m->iowr[STDIO_PORT] = iowr_stdio;
|
||||||
m->iowr[HERE_PORT] = iowr_here;
|
|
||||||
// initialize memory
|
// initialize memory
|
||||||
for (int i=0; i<sizeof(KERNEL); i++) {
|
for (int i=0; i<sizeof(KERNEL); i++) {
|
||||||
m->mem[i] = KERNEL[i];
|
m->mem[i] = KERNEL[i];
|
||||||
@ -76,8 +71,8 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
#ifndef DEBUG
|
#ifndef DEBUG
|
||||||
// We're done, now let's spit dict data
|
// We're done, now let's spit dict data
|
||||||
fprintf(stderr, "hey, %x\n", ending_here);
|
uint16_t here = m->mem[HERE] + (m->mem[HERE+1] << 8);
|
||||||
for (int i=sizeof(KERNEL); i<ending_here; i++) {
|
for (int i=sizeof(KERNEL); i<here; i++) {
|
||||||
putchar(m->mem[i]);
|
putchar(m->mem[i]);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
@ -42,7 +42,7 @@
|
|||||||
; IMMEDIATE
|
; IMMEDIATE
|
||||||
|
|
||||||
: CREATE
|
: CREATE
|
||||||
(entry) ( empty header with name )
|
WORD (entry) ( empty header with name )
|
||||||
ROUTINE C [LITN] ( push cellWord addr )
|
ROUTINE C [LITN] ( push cellWord addr )
|
||||||
, ( write it )
|
, ( write it )
|
||||||
;
|
;
|
||||||
|
@ -1,11 +1,4 @@
|
|||||||
( When building a compiled dict, always include this unit at
|
( When building a compiled dict, always include this unit at
|
||||||
the end of it so that Forth knows how to hook LATEST into
|
the end of it so that Forth knows how to hook LATEST into
|
||||||
it )
|
it )
|
||||||
(entry) _______
|
WORD _______ (entry)
|
||||||
|
|
||||||
( After each dummy word like this, we poke IO port 2 with our
|
|
||||||
current HERE value. The staging executable needs it to know
|
|
||||||
what to dump. )
|
|
||||||
|
|
||||||
HERE @ 256 / 2 PC!
|
|
||||||
HERE @ 2 PC!
|
|
||||||
|
@ -883,6 +883,7 @@ ENDDEF:
|
|||||||
.db 1 ; IMMEDIATE
|
.db 1 ; IMMEDIATE
|
||||||
DEFINE:
|
DEFINE:
|
||||||
.dw compiledWord
|
.dw compiledWord
|
||||||
|
.dw WORD
|
||||||
.dw ENTRYHEAD
|
.dw ENTRYHEAD
|
||||||
.dw NUMBER
|
.dw NUMBER
|
||||||
.dw compiledWord
|
.dw compiledWord
|
||||||
@ -1237,12 +1238,6 @@ PARSEI:
|
|||||||
.dw $-PARSE
|
.dw $-PARSE
|
||||||
.db 0
|
.db 0
|
||||||
ENTRYHEAD:
|
ENTRYHEAD:
|
||||||
.dw compiledWord
|
|
||||||
.dw WORD
|
|
||||||
.dw .private
|
|
||||||
.dw EXIT
|
|
||||||
|
|
||||||
.private:
|
|
||||||
.dw nativeWord
|
.dw nativeWord
|
||||||
pop hl
|
pop hl
|
||||||
ld de, (HERE)
|
ld de, (HERE)
|
||||||
@ -1277,6 +1272,7 @@ ENTRYHEAD:
|
|||||||
.db 0
|
.db 0
|
||||||
SYSV:
|
SYSV:
|
||||||
.dw compiledWord
|
.dw compiledWord
|
||||||
|
.dw WORD
|
||||||
.dw ENTRYHEAD
|
.dw ENTRYHEAD
|
||||||
.dw NUMBER
|
.dw NUMBER
|
||||||
.dw sysvarWord
|
.dw sysvarWord
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
: CODE
|
: CODE
|
||||||
( same as CREATE, but with ROUTINE V )
|
( same as CREATE, but with ROUTINE V )
|
||||||
(entry)
|
WORD (entry)
|
||||||
ROUTINE V [LITN] ,
|
ROUTINE V [LITN] ,
|
||||||
;
|
;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user