mirror of
https://github.com/hsoft/collapseos.git
synced 2024-11-02 16:10:55 +11:00
Compare commits
No commits in common. "d6516e2122335d411e27ae8bf6237dca118d5df6" and "ca7c21d49f318b053259780dafe0a62bf6f1ed36" have entirely different histories.
d6516e2122
...
ca7c21d49f
2
emul/.gitignore
vendored
2
emul/.gitignore
vendored
@ -1,8 +1,6 @@
|
|||||||
/shell/shell
|
/shell/shell
|
||||||
/forth/stage1
|
/forth/stage1
|
||||||
/forth/stage1dbg
|
/forth/stage1dbg
|
||||||
/forth/stage2
|
|
||||||
/forth/stage2dbg
|
|
||||||
/forth/forth
|
/forth/forth
|
||||||
/zasm/zasm
|
/zasm/zasm
|
||||||
/zasm/avra
|
/zasm/avra
|
||||||
|
@ -27,8 +27,8 @@ shell/shell-bin.h: shell/shell.bin
|
|||||||
shell/shell: shell/shell.c $(SHELLOBJS) shell/shell-bin.h
|
shell/shell: shell/shell.c $(SHELLOBJS) shell/shell-bin.h
|
||||||
$(CC) shell/shell.c $(SHELLOBJS) -o $@
|
$(CC) shell/shell.c $(SHELLOBJS) -o $@
|
||||||
|
|
||||||
forth/forth0.bin: forth/stage0.asm $(ZASMBIN)
|
forth/forth0.bin: forth/glue0.asm $(ZASMBIN)
|
||||||
$(ZASMBIN) $(KERNEL) ../forth forth/stagec.asm < forth/stage0.asm | tee $@ > /dev/null
|
$(ZASMBIN) $(KERNEL) ../forth < forth/glue0.asm | tee $@ > /dev/null
|
||||||
|
|
||||||
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
|
||||||
@ -39,30 +39,16 @@ 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 $@
|
||||||
|
|
||||||
# z80c.bin is not in the prerequisites because its a bootstrap binary that
|
forth/core.bin: $(FORTHSRC_PATHS) forth/stage1
|
||||||
# should be updated manually through make fbootstrap.
|
cat $(FORTHSRC_PATHS) | ./forth/stage1 | tee $@ > /dev/null
|
||||||
forth/forth1.bin: forth/stage1.asm forth/forth0.bin $(ZASMBIN)
|
|
||||||
$(ZASMBIN) $(KERNEL) ../forth forth/z80c.bin forth/stagec.asm < forth/stage1.asm | tee $@ > /dev/null
|
forth/forth1.bin: forth/glue1.asm forth/core.bin $(ZASMBIN)
|
||||||
|
$(ZASMBIN) $(KERNEL) ../forth forth/core.bin < forth/glue1.asm | tee $@ > /dev/null
|
||||||
|
|
||||||
forth/forth1-bin.h: forth/forth1.bin
|
forth/forth1-bin.h: forth/forth1.bin
|
||||||
./bin2c.sh KERNEL < forth/forth1.bin | tee $@ > /dev/null
|
./bin2c.sh KERNEL < forth/forth1.bin | tee $@ > /dev/null
|
||||||
|
|
||||||
forth/stage2: forth/stage.c $(OBJS) forth/forth1-bin.h
|
forth/forth: forth/forth.c $(OBJS) forth/forth1-bin.h
|
||||||
$(CC) -DSTAGE2 forth/stage.c $(OBJS) -o $@
|
|
||||||
|
|
||||||
forth/stage2dbg: forth/stage.c $(OBJS) forth/forth1-bin.h
|
|
||||||
$(CC) -DSTAGE2 -DDEBUG forth/stage.c $(OBJS) -o $@
|
|
||||||
|
|
||||||
forth/core.bin: $(FORTHSRC_PATHS) forth/stage2
|
|
||||||
cat $(FORTHSRC_PATHS) | ./forth/stage2 | tee $@ > /dev/null
|
|
||||||
|
|
||||||
forth/forth2.bin: forth/stage2.asm forth/core.bin $(ZASMBIN)
|
|
||||||
$(ZASMBIN) $(KERNEL) ../forth forth/core.bin forth/z80c.bin forth/stagec.asm < forth/stage2.asm | tee $@ > /dev/null
|
|
||||||
|
|
||||||
forth/forth2-bin.h: forth/forth2.bin
|
|
||||||
./bin2c.sh KERNEL < forth/forth2.bin | tee $@ > /dev/null
|
|
||||||
|
|
||||||
forth/forth: forth/forth.c $(OBJS) forth/forth2-bin.h
|
|
||||||
$(CC) forth/forth.c $(OBJS) -o $@
|
$(CC) forth/forth.c $(OBJS) -o $@
|
||||||
|
|
||||||
zasm/kernel-bin.h: zasm/kernel.bin
|
zasm/kernel-bin.h: zasm/kernel.bin
|
||||||
@ -108,10 +94,6 @@ updatebootstrap: $(ZASMBIN)
|
|||||||
$(ZASMBIN) $(KERNEL) < zasm/glue.asm > zasm/kernel.bin
|
$(ZASMBIN) $(KERNEL) < zasm/glue.asm > zasm/kernel.bin
|
||||||
$(ZASMBIN) $(KERNEL) $(APPS) zasm/user.h < $(APPS)/zasm/glue.asm > zasm/zasm.bin
|
$(ZASMBIN) $(KERNEL) $(APPS) zasm/user.h < $(APPS)/zasm/glue.asm > zasm/zasm.bin
|
||||||
|
|
||||||
.PHONY: fbootstrap
|
|
||||||
fbootstrap: forth/stage1
|
|
||||||
cat $(FORTHSRC_PATHS) ../forth/z80c.fs ../forth/dummy.fs | ./forth/stage1 | tee forth/z80c.bin > /dev/null
|
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean:
|
clean:
|
||||||
rm -f $(TARGETS) $(SHELLTGTS) emul.o zasm/*-bin.h shell/*-bin.h
|
rm -f $(TARGETS) $(SHELLTGTS) emul.o zasm/*-bin.h shell/*-bin.h
|
||||||
|
@ -80,39 +80,6 @@ code of the program is the value of `A` when the program halts.
|
|||||||
|
|
||||||
This is used for unit tests.
|
This is used for unit tests.
|
||||||
|
|
||||||
## forth
|
|
||||||
|
|
||||||
Collapse OS' Forth interpreter, which will probably soon replace the whole OS.
|
|
||||||
|
|
||||||
At this point, it is not yet entirely self-hosting, but will be eventually.
|
|
||||||
Because of that aim, it currently builds in a particular manner.
|
|
||||||
|
|
||||||
There are 3 build stages.
|
|
||||||
|
|
||||||
**Stage 0**: This stage is created with zasm by assembling `forth/forth.asm`
|
|
||||||
through `stage0.asm`. This yields `forth0.bin`. We then wrap this binary with
|
|
||||||
`stage.c` to create the `stage1` binary, which allows us to get to the next
|
|
||||||
stage.
|
|
||||||
|
|
||||||
The long term goal is to gradually extract contents from `forth.asm` and have
|
|
||||||
nothing but Forth source files.
|
|
||||||
|
|
||||||
**Stage 1**: The `stage1` binary allows us to augment `forth0.bin` with
|
|
||||||
contents from `z80c.fs`, which compiles native words using Forth's Z80
|
|
||||||
assembler. This yields `z80c.bin`.
|
|
||||||
|
|
||||||
This is where there's a chiken-and-egg issue: Forth's assembler needs our full
|
|
||||||
Forth interpreter, but that interpreter needs native words from `z80c.fs`. This
|
|
||||||
is why `z80c.bin` is committed into the git repo and it's built automatically
|
|
||||||
with `make`. Updating `z80c.bin` is a specific make rule, `fbootstrap`.
|
|
||||||
|
|
||||||
Then, from there, we augment `forth0.bin` with `z80c.bin` and yield
|
|
||||||
`forth1.bin`, from which we create `stage2`.
|
|
||||||
|
|
||||||
**Stage 2**: From there, the way is clear to compile the dict of our full Forth
|
|
||||||
interpreter, which we do using `stage2` and produce `forth2.bin`, from which we
|
|
||||||
can create our final `forth` executable.
|
|
||||||
|
|
||||||
## Problems?
|
## Problems?
|
||||||
|
|
||||||
If the libz80-wrapped zasm executable works badly (hangs, spew garbage, etc.),
|
If the libz80-wrapped zasm executable works badly (hangs, spew garbage, etc.),
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
#include "../emul.h"
|
#include "../emul.h"
|
||||||
#include "forth2-bin.h"
|
#include "forth1-bin.h"
|
||||||
|
|
||||||
// in sync with glue.asm
|
// in sync with glue.asm
|
||||||
#define RAMSTART 0x900
|
#define RAMSTART 0x900
|
||||||
|
@ -1,8 +1,13 @@
|
|||||||
.equ RAMSTART 0xe800
|
.equ RAMSTART 0xe800
|
||||||
.equ HERE_INITIAL CODE_END ; override
|
.equ HERE_INITIAL CODE_END ; override
|
||||||
.equ LATEST CODE_END ; override
|
|
||||||
.equ STDIO_PORT 0x00
|
.equ STDIO_PORT 0x00
|
||||||
|
|
||||||
|
jp init
|
||||||
|
|
||||||
|
.equ GETC emulGetC
|
||||||
|
.equ PUTC emulPutC
|
||||||
|
.inc "forth.asm"
|
||||||
|
|
||||||
init:
|
init:
|
||||||
di
|
di
|
||||||
; setup stack
|
; setup stack
|
||||||
@ -20,5 +25,6 @@ emulPutC:
|
|||||||
out (STDIO_PORT), a
|
out (STDIO_PORT), a
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.equ GETC emulGetC
|
CODE_END:
|
||||||
.equ PUTC emulPutC
|
.out LATEST
|
||||||
|
.out $ ; should be the same as in glue1
|
31
emul/forth/glue1.asm
Normal file
31
emul/forth/glue1.asm
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
; Warning: The offsets of native dict entries must be exactly the same between
|
||||||
|
; glue0.asm and glue1.asm
|
||||||
|
.equ LATEST RAMSTART ; override
|
||||||
|
.equ STDIO_PORT 0x00
|
||||||
|
|
||||||
|
jp init
|
||||||
|
|
||||||
|
.equ GETC emulGetC
|
||||||
|
.equ PUTC emulPutC
|
||||||
|
.inc "forth.asm"
|
||||||
|
|
||||||
|
init:
|
||||||
|
di
|
||||||
|
; setup stack
|
||||||
|
ld sp, 0xffff
|
||||||
|
call forthMain
|
||||||
|
halt
|
||||||
|
|
||||||
|
emulGetC:
|
||||||
|
; Blocks until a char is returned
|
||||||
|
in a, (STDIO_PORT)
|
||||||
|
cp a ; ensure Z
|
||||||
|
ret
|
||||||
|
|
||||||
|
emulPutC:
|
||||||
|
out (STDIO_PORT), a
|
||||||
|
ret
|
||||||
|
|
||||||
|
.out $ ; should be the same as in glue0
|
||||||
|
.bin "core.bin"
|
||||||
|
RAMSTART:
|
@ -2,11 +2,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include "../emul.h"
|
#include "../emul.h"
|
||||||
#ifdef STAGE2
|
|
||||||
#include "forth1-bin.h"
|
|
||||||
#else
|
|
||||||
#include "forth0-bin.h"
|
#include "forth0-bin.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Staging binaries
|
/* Staging binaries
|
||||||
|
|
||||||
@ -36,11 +32,7 @@ trouble of compiling defs to binary.
|
|||||||
#define HERE_PORT 0x02
|
#define HERE_PORT 0x02
|
||||||
|
|
||||||
static int running;
|
static int running;
|
||||||
// We support double-pokes, that is, a first poke to tell where to start the
|
static uint16_t ending_here = 0;
|
||||||
// dump and a second one to tell where to stop. If there is only one poke, it's
|
|
||||||
// then ending HERE and we start at sizeof(KERNEL).
|
|
||||||
static uint16_t start_here = 0;
|
|
||||||
static uint16_t end_here = 0;
|
|
||||||
|
|
||||||
static uint8_t iord_stdio()
|
static uint8_t iord_stdio()
|
||||||
{
|
{
|
||||||
@ -62,10 +54,8 @@ static void iowr_stdio(uint8_t val)
|
|||||||
|
|
||||||
static void iowr_here(uint8_t val)
|
static void iowr_here(uint8_t val)
|
||||||
{
|
{
|
||||||
start_here <<=8;
|
ending_here <<= 8;
|
||||||
start_here |= (end_here >> 8);
|
ending_here |= val;
|
||||||
end_here <<= 8;
|
|
||||||
end_here |= val;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
@ -86,10 +76,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
|
||||||
if (start_here == 0) {
|
fprintf(stderr, "hey, %x\n", ending_here);
|
||||||
start_here = sizeof(KERNEL);
|
for (int i=sizeof(KERNEL); i<ending_here; i++) {
|
||||||
}
|
|
||||||
for (int i=start_here; i<end_here; i++) {
|
|
||||||
putchar(m->mem[i]);
|
putchar(m->mem[i]);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
jp init
|
|
||||||
|
|
||||||
.inc "stagec.asm"
|
|
||||||
.inc "forth.asm"
|
|
||||||
|
|
||||||
CODE_END:
|
|
||||||
.out $ ; should be the same as in stage{1,2}
|
|
@ -1,8 +0,0 @@
|
|||||||
jp init
|
|
||||||
|
|
||||||
.inc "stagec.asm"
|
|
||||||
.inc "forth.asm"
|
|
||||||
|
|
||||||
.out $ ; should be the same as in stage{0,2}
|
|
||||||
.bin "z80c.bin"
|
|
||||||
CODE_END:
|
|
@ -1,10 +0,0 @@
|
|||||||
jp init
|
|
||||||
|
|
||||||
.inc "stagec.asm"
|
|
||||||
.inc "forth.asm"
|
|
||||||
|
|
||||||
.out $ ; should be the same as in stage{0,1}
|
|
||||||
.bin "z80c.bin"
|
|
||||||
.bin "core.bin"
|
|
||||||
CODE_END:
|
|
||||||
|
|
Binary file not shown.
@ -1405,10 +1405,28 @@ SWAP:
|
|||||||
push hl
|
push hl
|
||||||
jp next
|
jp next
|
||||||
|
|
||||||
|
; ( a b c d -- c d a b )
|
||||||
|
.db "2SWAP"
|
||||||
|
.fill 2
|
||||||
|
.dw $-SWAP
|
||||||
|
.db 0
|
||||||
|
SWAP2:
|
||||||
|
.dw nativeWord
|
||||||
|
pop de ; D
|
||||||
|
pop hl ; C
|
||||||
|
pop bc ; B
|
||||||
|
call chkPS
|
||||||
|
|
||||||
|
ex (sp), hl ; A in HL
|
||||||
|
push de ; D
|
||||||
|
push hl ; A
|
||||||
|
push bc ; B
|
||||||
|
jp next
|
||||||
|
|
||||||
; ( a -- a a )
|
; ( a -- a a )
|
||||||
.db "DUP"
|
.db "DUP"
|
||||||
.fill 4
|
.fill 4
|
||||||
.dw $-SWAP
|
.dw $-SWAP2
|
||||||
.db 0
|
.db 0
|
||||||
DUP:
|
DUP:
|
||||||
.dw nativeWord
|
.dw nativeWord
|
||||||
@ -1418,10 +1436,26 @@ DUP:
|
|||||||
push hl
|
push hl
|
||||||
jp next
|
jp next
|
||||||
|
|
||||||
|
; ( a b -- a b a b )
|
||||||
|
.db "2DUP"
|
||||||
|
.fill 3
|
||||||
|
.dw $-DUP
|
||||||
|
.db 0
|
||||||
|
DUP2:
|
||||||
|
.dw nativeWord
|
||||||
|
pop hl ; B
|
||||||
|
pop de ; A
|
||||||
|
call chkPS
|
||||||
|
push de
|
||||||
|
push hl
|
||||||
|
push de
|
||||||
|
push hl
|
||||||
|
jp next
|
||||||
|
|
||||||
; ( a b -- a b a )
|
; ( a b -- a b a )
|
||||||
.db "OVER"
|
.db "OVER"
|
||||||
.fill 3
|
.fill 3
|
||||||
.dw $-DUP
|
.dw $-DUP2
|
||||||
.db 0
|
.db 0
|
||||||
OVER:
|
OVER:
|
||||||
.dw nativeWord
|
.dw nativeWord
|
||||||
@ -1433,9 +1467,45 @@ OVER:
|
|||||||
push de
|
push de
|
||||||
jp next
|
jp next
|
||||||
|
|
||||||
|
; ( a b c d -- a b c d a b )
|
||||||
|
.db "2OVER"
|
||||||
|
.fill 2
|
||||||
|
.dw $-OVER
|
||||||
|
.db 0
|
||||||
|
OVER2:
|
||||||
|
.dw nativeWord
|
||||||
|
pop hl ; D
|
||||||
|
pop de ; C
|
||||||
|
pop bc ; B
|
||||||
|
pop iy ; A
|
||||||
|
call chkPS
|
||||||
|
push iy ; A
|
||||||
|
push bc ; B
|
||||||
|
push de ; C
|
||||||
|
push hl ; D
|
||||||
|
push iy ; A
|
||||||
|
push bc ; B
|
||||||
|
jp next
|
||||||
|
|
||||||
|
; ( a b c -- b c a)
|
||||||
|
.db "ROT"
|
||||||
|
.fill 4
|
||||||
|
.dw $-OVER2
|
||||||
|
.db 0
|
||||||
|
ROT:
|
||||||
|
.dw nativeWord
|
||||||
|
pop hl ; C
|
||||||
|
pop de ; B
|
||||||
|
pop bc ; A
|
||||||
|
call chkPS
|
||||||
|
push de ; B
|
||||||
|
push hl ; C
|
||||||
|
push bc ; A
|
||||||
|
jp next
|
||||||
|
|
||||||
.db ">R"
|
.db ">R"
|
||||||
.fill 5
|
.fill 5
|
||||||
.dw $-OVER
|
.dw $-ROT
|
||||||
.db 0
|
.db 0
|
||||||
P2R:
|
P2R:
|
||||||
.dw nativeWord
|
.dw nativeWord
|
||||||
|
@ -1,5 +1,11 @@
|
|||||||
( Z80 assembler )
|
( Z80 assembler )
|
||||||
|
|
||||||
|
: CODE
|
||||||
|
( same as CREATE, but with ROUTINE V )
|
||||||
|
(entry)
|
||||||
|
ROUTINE V [LITN] ,
|
||||||
|
;
|
||||||
|
|
||||||
( Splits word into msb/lsb, lsb being on TOS )
|
( Splits word into msb/lsb, lsb being on TOS )
|
||||||
: SPLITB
|
: SPLITB
|
||||||
DUP 0x100 /
|
DUP 0x100 /
|
||||||
@ -22,11 +28,6 @@
|
|||||||
3 CONSTANT AF
|
3 CONSTANT AF
|
||||||
3 CONSTANT SP
|
3 CONSTANT SP
|
||||||
|
|
||||||
( As a general rule, IX and IY are equivalent to spitting an
|
|
||||||
extra 0xdd / 0xfd and then spit the equivalent of HL )
|
|
||||||
: IX 0xdd A, HL ;
|
|
||||||
: IY 0xfd A, HL ;
|
|
||||||
|
|
||||||
( -- )
|
( -- )
|
||||||
: OP1 CREATE C, DOES> C@ A, ;
|
: OP1 CREATE C, DOES> C@ A, ;
|
||||||
0xc9 OP1 RET,
|
0xc9 OP1 RET,
|
||||||
@ -129,12 +130,3 @@
|
|||||||
( Specials )
|
( Specials )
|
||||||
: JRe, 0x18 A, 2 - A, ;
|
: JRe, 0x18 A, 2 - A, ;
|
||||||
: JPNEXT, ROUTINE N [LITN] JPnn, ;
|
: JPNEXT, ROUTINE N [LITN] JPnn, ;
|
||||||
|
|
||||||
: CODE
|
|
||||||
( same as CREATE, but with ROUTINE V )
|
|
||||||
(entry)
|
|
||||||
ROUTINE V [LITN] ,
|
|
||||||
;
|
|
||||||
|
|
||||||
: ;CODE JPNEXT, ;
|
|
||||||
|
|
||||||
|
@ -1,73 +0,0 @@
|
|||||||
( Core words in z80. This requires a full Forth interpreter
|
|
||||||
to run, but is also necessary for core.fs. This means that
|
|
||||||
it needs to be compiled from a prior bootstrapped binary.
|
|
||||||
|
|
||||||
This stage is tricky due to the fact that references in
|
|
||||||
Forth are all absolute, except for prev word refs. This
|
|
||||||
means that there are severe limitations to the kind of code
|
|
||||||
you can put here.
|
|
||||||
|
|
||||||
You shouldn't define any word with reference to other words.
|
|
||||||
This means no regular definition. You can, however, execute
|
|
||||||
any word from our high level Forth, as long as it doesn't
|
|
||||||
spit word references.
|
|
||||||
|
|
||||||
ROUTINE stuff is fine. It's not supposed to change.
|
|
||||||
|
|
||||||
These restrictions are temporary, I'll figure something out
|
|
||||||
so that we can end up fully bootstrap Forth from within
|
|
||||||
itself.
|
|
||||||
)
|
|
||||||
|
|
||||||
( a b c -- b c a )
|
|
||||||
CODE ROT
|
|
||||||
HL POPqq, ( C )
|
|
||||||
DE POPqq, ( B )
|
|
||||||
BC POPqq, ( A )
|
|
||||||
ROUTINE P CALLnn,
|
|
||||||
DE PUSHqq, ( B )
|
|
||||||
HL PUSHqq, ( C )
|
|
||||||
BC PUSHqq, ( A )
|
|
||||||
;CODE
|
|
||||||
|
|
||||||
( a b -- a b a b )
|
|
||||||
CODE 2DUP
|
|
||||||
HL POPqq, ( B )
|
|
||||||
DE POPqq, ( A )
|
|
||||||
ROUTINE P CALLnn,
|
|
||||||
DE PUSHqq, ( A )
|
|
||||||
HL PUSHqq, ( B )
|
|
||||||
DE PUSHqq, ( A )
|
|
||||||
HL PUSHqq, ( B )
|
|
||||||
;CODE
|
|
||||||
|
|
||||||
( a b c d -- a b c d a b )
|
|
||||||
|
|
||||||
CODE 2OVER
|
|
||||||
HL POPqq, ( D )
|
|
||||||
DE POPqq, ( C )
|
|
||||||
BC POPqq, ( B )
|
|
||||||
IY POPqq, ( A )
|
|
||||||
ROUTINE P CALLnn,
|
|
||||||
IY PUSHqq, ( A )
|
|
||||||
BC PUSHqq, ( B )
|
|
||||||
DE PUSHqq, ( C )
|
|
||||||
HL PUSHqq, ( D )
|
|
||||||
IY PUSHqq, ( A )
|
|
||||||
BC PUSHqq, ( B )
|
|
||||||
;CODE
|
|
||||||
|
|
||||||
( a b c d -- c d a b )
|
|
||||||
|
|
||||||
CODE 2SWAP
|
|
||||||
HL POPqq, ( D )
|
|
||||||
DE POPqq, ( C )
|
|
||||||
BC POPqq, ( B )
|
|
||||||
IY POPqq, ( A )
|
|
||||||
ROUTINE P CALLnn,
|
|
||||||
DE PUSHqq, ( C )
|
|
||||||
HL PUSHqq, ( D )
|
|
||||||
IY PUSHqq, ( A )
|
|
||||||
BC PUSHqq, ( B )
|
|
||||||
;CODE
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user