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

Compare commits

...

2 Commits

Author SHA1 Message Date
Virgil Dupras
ca7c21d49f forth: make "(entry)" call WORD itself
Otherwise, when a defining word would be called outside a definition
itself, it would get the name of the last parsed word, that is,
itself!

For example, dummy.fs, instead of creating a "_______" entry, created
a "(entry)" entry...
2020-03-22 22:27:54 -04:00
Virgil Dupras
5387e08437 forth: make bin staging process a bit less hackish
The goal being to add a new native code dict staging phase.
2020-03-22 21:46:43 -04:00
7 changed files with 39 additions and 32 deletions

View File

@ -33,11 +33,11 @@ forth/forth0.bin: forth/glue0.asm $(ZASMBIN)
forth/forth0-bin.h: forth/forth0.bin
./bin2c.sh KERNEL < forth/forth0.bin | tee $@ > /dev/null
forth/stage1: forth/stage1.c $(OBJS) forth/forth0-bin.h
$(CC) forth/stage1.c $(OBJS) -o $@
forth/stage1: forth/stage.c $(OBJS) forth/forth0-bin.h
$(CC) forth/stage.c $(OBJS) -o $@
forth/stage1dbg: forth/stage1.c $(OBJS) forth/forth0-bin.h
$(CC) -DDEBUG forth/stage1.c $(OBJS) -o $@
forth/stage1dbg: forth/stage.c $(OBJS) forth/forth0-bin.h
$(CC) -DDEBUG forth/stage.c $(OBJS) -o $@
forth/core.bin: $(FORTHSRC_PATHS) forth/stage1
cat $(FORTHSRC_PATHS) | ./forth/stage1 | tee $@ > /dev/null

View File

@ -1,13 +1,4 @@
; 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 HERE 0xe700 ; override, in sync with stage1.c
.equ CURRENT 0xe702 ; override, in sync with stage1.c
.equ HERE_INITIAL CODE_END ; override
.equ STDIO_PORT 0x00

View File

@ -4,20 +4,19 @@
#include "../emul.h"
#include "forth0-bin.h"
/* Stage 1
/* Staging binaries
The role of the stage 1 executable is to start from a bare Forth executable
(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.
The role of a stage executable is to compile definitions in a dictionary and
then spit the difference between the starting binary and the new binary.
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
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
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.
@ -28,13 +27,12 @@ that wordref offsets correspond.
// in sync with glue.asm
#define RAMSTART 0x900
#define STDIO_PORT 0x00
// In sync with glue code. This way, we can know where HERE was when we stopped
// running
#define HERE 0xe700
// We also need to know what CURRENT is so we can write our first two bytes
#define CURRENT 0xe702
// To know which part of RAM to dump, we listen to port 2, which at the end of
// its compilation process, spits its HERE addr to port 2 (MSB first)
#define HERE_PORT 0x02
static int running;
static uint16_t ending_here = 0;
static uint8_t iord_stdio()
{
@ -54,12 +52,19 @@ static void iowr_stdio(uint8_t val)
#endif
}
static void iowr_here(uint8_t val)
{
ending_here <<= 8;
ending_here |= val;
}
int main(int argc, char *argv[])
{
Machine *m = emul_init();
m->ramstart = RAMSTART;
m->iord[STDIO_PORT] = iord_stdio;
m->iowr[STDIO_PORT] = iowr_stdio;
m->iowr[HERE_PORT] = iowr_here;
// initialize memory
for (int i=0; i<sizeof(KERNEL); i++) {
m->mem[i] = KERNEL[i];
@ -71,8 +76,8 @@ int main(int argc, char *argv[])
#ifndef DEBUG
// We're done, now let's spit dict data
uint16_t here = m->mem[HERE] + (m->mem[HERE+1] << 8);
for (int i=sizeof(KERNEL); i<here; i++) {
fprintf(stderr, "hey, %x\n", ending_here);
for (int i=sizeof(KERNEL); i<ending_here; i++) {
putchar(m->mem[i]);
}
#endif

View File

@ -42,7 +42,7 @@
; IMMEDIATE
: CREATE
WORD (entry) ( empty header with name )
(entry) ( empty header with name )
ROUTINE C [LITN] ( push cellWord addr )
, ( write it )
;

View File

@ -1,4 +1,11 @@
( When building a compiled dict, always include this unit at
the end of it so that Forth knows how to hook LATEST into
it )
WORD _______ (entry)
(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!

View File

@ -883,7 +883,6 @@ ENDDEF:
.db 1 ; IMMEDIATE
DEFINE:
.dw compiledWord
.dw WORD
.dw ENTRYHEAD
.dw NUMBER
.dw compiledWord
@ -1238,6 +1237,12 @@ PARSEI:
.dw $-PARSE
.db 0
ENTRYHEAD:
.dw compiledWord
.dw WORD
.dw .private
.dw EXIT
.private:
.dw nativeWord
pop hl
ld de, (HERE)
@ -1272,7 +1277,6 @@ ENTRYHEAD:
.db 0
SYSV:
.dw compiledWord
.dw WORD
.dw ENTRYHEAD
.dw NUMBER
.dw sysvarWord

View File

@ -2,7 +2,7 @@
: CODE
( same as CREATE, but with ROUTINE V )
WORD (entry)
(entry)
ROUTINE V [LITN] ,
;