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

Compare commits

..

No commits in common. "edb27714880586d9817db783c2dec677f5dd89f8" and "2af959a13dc543d0fc6efec7962e478a5f8e63d1" have entirely different histories.

15 changed files with 78 additions and 172 deletions

View File

@ -9,12 +9,59 @@ CONFIGURATION
ACIA_CTL: IO port for the ACIA's control registers ACIA_CTL: IO port for the ACIA's control registers
ACIA_IO: IO port for the ACIA's data registers ACIA_IO: IO port for the ACIA's data registers
ACIA_MEM: Address in memory that can be used variables shared
with ACIA's native words. 8 bytes used.
) )
0x20 CONSTANT ACIABUFSZ 0x20 CONSTANT ACIABUFSZ
( Points to ACIA buf )
(sysv) ACIA(
( Points to ACIA buf end )
(sysv) ACIA)
( Read buf pointer. Pre-inc )
(sysv) ACIAR>
( Write buf pointer. Post-inc )
(sysv) ACIAW>
( This means that if W> == R>, buffer is full.
If R>+1 == W>, buffer is empty. )
(entry) ~ACIA
AF PUSHqq,
HL PUSHqq,
DE PUSHqq,
( Read our character from ACIA into our BUFIDX )
ACIA_CTL INAn,
0x01 ANDn, ( is ACIA rcv buf full? )
JRZ, L2 FWR ( end, no, wrong interrupt cause. )
ACIAW> @ LDHL(nn),
( is it == to ACIAR>? )
DE ACIAR> @ LDdd(nn),
( carry cleared from ANDn above )
DE SBCHLss,
JRZ, L3 FWR ( end, buffer full )
( buffer not full, let's write )
ACIA_IO INAn,
(HL) A LDrr,
( advance W> )
HL INCss,
DE ACIAR) @ LDdd(nn),
DE SUBHLss,
JRNZ, L4 FWR ( skip )
( end of buffer reached )
ACIA( @ LDHL(nn),
L4 FSET ( skip )
ACIAW> @ LD(nn)HL,
L3 FSET L2 FSET ( end )
DE POPqq,
HL POPqq,
AF POPqq,
EI,
RETI,
: ACIA$ : ACIA$
H@ DUP DUP ACIA( ! ACIAR> ! H@ DUP DUP ACIA( ! ACIAR> !
1 + ACIAW> ! ( write index starts one position later ) 1 + ACIAW> ! ( write index starts one position later )
@ -29,9 +76,9 @@ ACIA_MEM: Address in memory that can be used variables shared
0b10010110 ACIA_CTL PC! 0b10010110 ACIA_CTL PC!
( setup interrupt ) ( setup interrupt )
( 4e == INTJUMP ) ( 51 == INTJUMP )
0xc3 0x4e RAM+ C! ( JP upcode ) 0xc3 0x51 RAM+ C! ( JP upcode )
['] ~ACIA 0x4f RAM+ ! ['] ~ACIA 0x52 RAM+ !
(im1) (im1)
; ;
@ -39,15 +86,14 @@ ACIA_MEM: Address in memory that can be used variables shared
( As long as R> == W>-1, it means that buffer is empty ) ( As long as R> == W>-1, it means that buffer is empty )
BEGIN ACIAR> @ 1 + ACIAW> @ = NOT UNTIL BEGIN ACIAR> @ 1 + ACIAW> @ = NOT UNTIL
( inc then fetch )
1 ACIAR> +!
ACIAR> @ C@ ACIAR> @ C@
1 ACIAR> +!
; ;
: EMIT : EMIT
( As long at CTL bit 1 is low, we are transmitting. wait ) ( As long at CTL bit 1 is low, we are transmitting. wait )
BEGIN ACIA_CTL PC@ 0x02 AND UNTIL BEGIN ACIA_CTL PC@ 0x02 AND UNTIL
( The way is clear, go! ) ( The way is clear, go! )
ACIA_IO PC! ACIA_IO SWAP PC!
; ;

View File

@ -1,55 +0,0 @@
( Save ACIA conf )
ACIA_CTL
: ACIA_CTL [ LITN ] ;
ACIA_IO
: ACIA_IO [ LITN ] ;
( 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. )
(entry) ~ACIA
AF PUSHqq,
HL PUSHqq,
DE PUSHqq,
( Read our character from ACIA into our BUFIDX )
ACIA_CTL INAn,
0x01 ANDn, ( is ACIA rcv buf full? )
JRZ, L2 FWR ( end, no, wrong interrupt cause. )
ACIAW> LDHL(nn),
( is it == to ACIAR>? )
DE ACIAR> LDdd(nn),
( carry cleared from ANDn above )
DE SBCHLss,
JRZ, L3 FWR ( end, buffer full )
DE ADDHLss, ( restore ACIAW> )
( buffer not full, let's write )
ACIA_IO INAn,
(HL) A LDrr,
( advance W> )
HL INCss,
ACIAW> LD(nn)HL,
DE ACIA) @ LDdd(nn),
DE SUBHLss,
JRNZ, L4 FWR ( skip )
( end of buffer reached )
ACIA( @ LDHL(nn),
ACIAW> LD(nn)HL,
L4 FSET ( skip )
L3 FSET L2 FSET ( end )
DE POPqq,
HL POPqq,
AF POPqq,
EI,
RETI,

View File

@ -4,12 +4,10 @@ FORTHSRCS = core.fs print.fs str.fs parse.fs readln.fs fmt.fs z80a.fs
FORTHSRC_PATHS = ${FORTHSRCS:%=../forth/%} forth/run.fs FORTHSRC_PATHS = ${FORTHSRCS:%=../forth/%} forth/run.fs
OBJS = emul.o libz80/libz80.o OBJS = emul.o libz80/libz80.o
SLATEST = ../tools/slatest SLATEST = ../tools/slatest
STRIPFC = ../tools/stripfc
.PHONY: all .PHONY: all
all: $(TARGETS) all: $(TARGETS)
$(STRIPFC):
$(SLATEST): $(SLATEST):
$(MAKE) -C ../tools $(MAKE) -C ../tools
@ -29,10 +27,8 @@ forth/stage1: forth/stage.c $(OBJS) forth/forth0-bin.h
forth/stage1dbg: forth/stage.c $(OBJS) forth/forth0-bin.h forth/stage1dbg: forth/stage.c $(OBJS) forth/forth0-bin.h
$(CC) -DDEBUG forth/stage.c $(OBJS) -o $@ $(CC) -DDEBUG forth/stage.c $(OBJS) -o $@
# We don't really need to use stripfc, but we do it anyway to test that we
# don't mistakenly break our code with that tool. It's easier to debug here.
forth/core.bin: $(FORTHSRC_PATHS) forth/stage1 forth/core.bin: $(FORTHSRC_PATHS) forth/stage1
cat $(FORTHSRC_PATHS) ./forth/stop.fs | $(STRIPFC) | ./forth/stage1 | tee $@ > /dev/null cat $(FORTHSRC_PATHS) ./forth/stop.fs | ./forth/stage1 | tee $@ > /dev/null
forth/forth1.bin: forth/core.bin $(SLATEST) forth/forth1.bin: forth/core.bin $(SLATEST)
cat forth/boot.bin forth/z80c.bin forth/core.bin > $@ cat forth/boot.bin forth/z80c.bin forth/core.bin > $@

View File

@ -115,12 +115,7 @@ 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 one of those slots for an interrupt, write a jump to the appropriate offset in
that RAM location. that RAM location.
SYSTEM SCRATCHPAD is reserved for temporary system storage or can be reserved SYSTEM SCRATCHPAD is reserved for temporary system storage.
by low-level drivers. These are the current usages of this space throughout the
project:
* 0x51-0x53: (c<) pointer during in-memory initialization (see below)
* 0x53-0x5b: ACIA buffer pointers in RC2014 recipes.
*** Initialization sequence *** Initialization sequence

View File

@ -80,7 +80,7 @@
(parseb) IF EXIT THEN (parseb) IF EXIT THEN
(parsed) IF EXIT THEN (parsed) IF EXIT THEN
( nothing works ) ( nothing works )
LIT< (wnf) (find) DROP EXECUTE ABORT" unknown word! "
; ;
' (parse) (parse*) ! ' (parse) (parse*) !

View File

@ -28,8 +28,3 @@
: (uflw) ABORT" stack underflow" ; : (uflw) ABORT" stack underflow" ;
: (wnf) ABORT" word not found" ; : (wnf) ABORT" word not found" ;
: BS 8 EMIT ;
: LF 10 EMIT ;
: CR 13 EMIT ;
: SPC 32 EMIT ;

View File

@ -1,4 +1,4 @@
( requires core, parse, print ) ( requires core, parse )
( Managing variables in a core module is tricky. Sure, we ( Managing variables in a core module is tricky. Sure, we
have (sysv), but here we need to allocate a big buffer, and have (sysv), but here we need to allocate a big buffer, and
@ -76,5 +76,5 @@
( not EOL? good, inc and return ) ( not EOL? good, inc and return )
DUP IF 1 IN> +! EXIT THEN ( c ) DUP IF 1 IN> +! EXIT THEN ( c )
( EOL ? readline. we still return typed char though ) ( EOL ? readline. we still return typed char though )
(rdln) ( c ) (rdln) (<c) ( c )
; ;

View File

@ -5,3 +5,8 @@
1 + 1 +
AGAIN AGAIN
; ;
: BS 8 EMIT ;
: LF 10 EMIT ;
: CR 13 EMIT ;
: SPC 32 EMIT ;

View File

@ -1,33 +1,25 @@
TARGET = os.bin TARGET = os.bin
BASEDIR = ../.. BASEDIR = ../..
FDIR = $(BASEDIR)/forth FDIR = $(BASEDIR)/emul/forth
EDIR = $(BASEDIR)/emul/forth STAGE1 = $(FDIR)/stage1
STAGE2 = $(EDIR)/stage2 FORTH0 = $(FDIR)/forth0.bin
EMUL = $(BASEDIR)/emul/hw/rc2014/classic EMUL = $(BASEDIR)/emul/hw/rc2014/classic
PATHS = pre.fs \ SRCS = core.fs str.fs parse.fs readln.fs fmt.fs
$(FDIR)/core.fs \ PATHS = conf.fs \
$(FDIR)/str.fs \ ${SRCS:%=$(BASEDIR)/forth/%} \
$(FDIR)/parse.fs \
$(BASEDIR)/drv/acia.fs \ $(BASEDIR)/drv/acia.fs \
$(FDIR)/print.fs \ run.fs \
$(FDIR)/readln.fs \ $(FDIR)/stop.fs
$(FDIR)/fmt.fs \
run.fs
SLATEST = $(BASEDIR)/tools/slatest SLATEST = $(BASEDIR)/tools/slatest
STRIPFC = $(BASEDIR)/tools/stripfc
.PHONY: all .PHONY: all
all: $(TARGET) all: $(TARGET)
$(TARGET): boot.bin z80c.bin $(SLATEST) $(PATHS) $(TARGET): dict.bin $(FORTH0) $(SLATEST)
cat boot.bin z80c.bin > $@ cat $(FORTH0) dict.bin > $@
$(SLATEST) $@ $(SLATEST) $@
cat $(PATHS) | $(STRIPFC) >> $@
z80c.bin: boot.bin dict.bin: conf.fs
cat conf.fs $(FDIR)/z80c.fs $(BASEDIR)/drv/acia.z80 $(FDIR)/icore.fs | $(STAGE2) | tee $@ > /dev/null cat $(PATHS) | $(STAGE1) > $@
boot.bin: conf.fs
cat conf.fs $(FDIR)/boot.fs | $(STAGE2) | tee $@ > /dev/null
$(SLATEST): $(SLATEST):
$(MAKE) -C $(BASEDIR)/tools $(MAKE) -C $(BASEDIR)/tools

View File

@ -2,5 +2,4 @@
0xf000 CONSTANT RS_ADDR 0xf000 CONSTANT RS_ADDR
0x80 CONSTANT ACIA_CTL 0x80 CONSTANT ACIA_CTL
0x81 CONSTANT ACIA_IO 0x81 CONSTANT ACIA_IO
RAMSTART 0x53 + CONSTANT ACIA_MEM

View File

@ -1 +0,0 @@
96 RAM+ HERE !

View File

@ -1,9 +1 @@
: INIT : INIT 5 5 PC! BYE ACIA$ INTERPRET ;
ACIA$
(c<$)
." Collapse OS" LF
( 0c == CINPTR )
['] (c<) 0x0c RAM+ !
;
INIT

1
tools/.gitignore vendored
View File

@ -5,4 +5,3 @@
/ttysafe /ttysafe
/pingpong /pingpong
/slatest /slatest
/stripfc

View File

@ -5,9 +5,8 @@ FONTCOMPILE_TGT = fontcompile
TTYSAFE_TGT = ttysafe TTYSAFE_TGT = ttysafe
PINGPONG_TGT = pingpong PINGPONG_TGT = pingpong
SLATEST_TGT = slatest SLATEST_TGT = slatest
STRIPFC_TGT = stripfc
TARGETS = $(MEMDUMP_TGT) $(BLKDUMP_TGT) $(UPLOAD_TGT) $(FONTCOMPILE_TGT) \ TARGETS = $(MEMDUMP_TGT) $(BLKDUMP_TGT) $(UPLOAD_TGT) $(FONTCOMPILE_TGT) \
$(TTYSAFE_TGT) $(PINGPONG_TGT) $(SLATEST_TGT) $(STRIPFC_TGT) $(TTYSAFE_TGT) $(PINGPONG_TGT) $(SLATEST_TGT)
OBJS = common.o OBJS = common.o
all: $(TARGETS) all: $(TARGETS)
@ -23,7 +22,6 @@ $(FONTCOMPILE_TGT): $(FONTCOMPILE_TGT).c
$(TTYSAFE_TGT): $(TTYSAFE_TGT).c $(TTYSAFE_TGT): $(TTYSAFE_TGT).c
$(PINGPONG_TGT): $(PINGPONG_TGT).c $(PINGPONG_TGT): $(PINGPONG_TGT).c
$(SLATEST_TGT): $(SLATEST_TGT).c $(SLATEST_TGT): $(SLATEST_TGT).c
$(STRIPFC_TGT): $(STRIPFC_TGT).c
$(TARGETS): $(OBJS) $(TARGETS): $(OBJS)
$(CC) $(CFLAGS) $@.c $(OBJS) -o $@ $(CC) $(CFLAGS) $@.c $(OBJS) -o $@

View File

@ -1,55 +0,0 @@
#include <stdio.h>
/* read stdin and strip Forth-style comments before spitting in stdout. This
also deduplicate spaces and newlines.
THIS PARSING IS IMPERFECT. Only a Forth interpreter can reliably detect
comments. For example, a naive parser misinterprets the "(" word definition as
a comment.
We work around this by considering as a comment opener only "(" chars preceeded
by more than once space or by a newline. Hackish, but works.
*/
int main()
{
int spccnt = 0;
int incomment = 0;
int c;
c = getchar();
while ( c != EOF ) {
if (c == '\n') {
// We still spit newlines whenever we see them, Forth interpreter
// doesn't like when they're not there...
putchar(c);
spccnt += 2;
} else if (c == ' ') {
spccnt++;
} else {
if (incomment) {
if ((c == ')') && spccnt) {
incomment = 0;
}
} else {
if ((c == '(') && (spccnt > 1)) {
putchar(' ');
spccnt = 0;
int next = getchar();
if (next <= ' ') {
incomment = 1;
continue;
}
putchar(c);
c = next;
}
if (spccnt) {
putchar(' ');
}
putchar(c);
}
spccnt = 0;
}
c = getchar();
}
return 0;
}