zasm emul: bring back kernel/user distinction

It was a bad idea to remove it. Now that I'm introducing the concept of
a per-app glue file, it becomes much easier to build emulated zasm as a
userspace app.
This commit is contained in:
Virgil Dupras 2019-05-19 12:57:59 -04:00
parent 7fad3b0c90
commit bc1496a7e3
9 changed files with 148 additions and 76 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/kernel/user.h

62
apps/zasm/glue.asm Normal file
View File

@ -0,0 +1,62 @@
; zasm
;
; Reads input from specified blkdev ID, assemble the binary in two passes and
; spit the result in another specified blkdev ID.
;
; We don't buffer the whole source in memory, so we need our input blkdev to
; support Seek so we can read the file a second time. So, for input, we need
; GetC and Seek.
;
; For output, we only need PutC. Output doesn't start until the second pass.
;
; The goal of the second pass is to assign values to all symbols so that we
; can have forward references (instructions referencing a label that happens
; later).
;
; Labels and constants are both treated the same way, that is, they can be
; forward-referenced in instructions. ".equ" directives, however, are evaluated
; during the first pass so forward references are not allowed.
;
; *** Requirements ***
; blockdev
; strncmp
; addDE
; addHL
; upcase
; unsetZ
; intoDE
; intoHL
; writeHLinDE
; findchar
; parseHex
; parseHexPair
; blkSel
; fsFindFN
; fsOpen
; fsGetC
; fsSeek
; fsTell
; FS_HANDLE_SIZE
; *** Variables ***
#include "user.h"
.org USER_CODE
jp zasmMain
#include "zasm/util.asm"
.equ IO_RAMSTART USER_RAMSTART
#include "zasm/io.asm"
.equ TOK_RAMSTART IO_RAMEND
#include "zasm/tok.asm"
#include "zasm/parse.asm"
#include "zasm/expr.asm"
#include "zasm/instr.asm"
.equ DIREC_RAMSTART TOK_RAMEND
#include "zasm/directive.asm"
.equ SYM_RAMSTART DIREC_RAMEND
#include "zasm/symbol.asm"
.equ ZASM_RAMSTART SYM_RAMEND
#include "zasm/main.asm"

View File

@ -1,44 +1,3 @@
; zasm
;
; Reads input from specified blkdev ID, assemble the binary in two passes and
; spit the result in another specified blkdev ID.
;
; We don't buffer the whole source in memory, so we need our input blkdev to
; support Seek so we can read the file a second time. So, for input, we need
; GetC and Seek.
;
; For output, we only need PutC. Output doesn't start until the second pass.
;
; The goal of the second pass is to assign values to all symbols so that we
; can have forward references (instructions referencing a label that happens
; later).
;
; Labels and constants are both treated the same way, that is, they can be
; forward-referenced in instructions. ".equ" directives, however, are evaluated
; during the first pass so forward references are not allowed.
;
; *** Requirements ***
; blockdev
; strncmp
; addDE
; addHL
; upcase
; unsetZ
; intoDE
; intoHL
; writeHLinDE
; findchar
; parseHex
; parseHexPair
; blkSel
; fsFindFN
; fsOpen
; fsGetC
; fsSeek
; fsTell
; ZASM_RAMSTART (where we put our variables in RAM)
; FS_HANDLE_SIZE
; *** Variables *** ; *** Variables ***
; A bool flag indicating that we're on first pass. When we are, we don't care ; A bool flag indicating that we're on first pass. When we are, we don't care
@ -54,19 +13,6 @@
.equ ZASM_CTX_PC ZASM_LOCAL_PASS+1 .equ ZASM_CTX_PC ZASM_LOCAL_PASS+1
.equ ZASM_RAMEND ZASM_CTX_PC+2 .equ ZASM_RAMEND ZASM_CTX_PC+2
#include "zasm/util.asm"
.equ IO_RAMSTART ZASM_RAMEND
#include "zasm/io.asm"
.equ TOK_RAMSTART IO_RAMEND
#include "zasm/tok.asm"
#include "zasm/parse.asm"
#include "zasm/expr.asm"
#include "zasm/instr.asm"
.equ DIREC_RAMSTART TOK_RAMEND
#include "zasm/directive.asm"
.equ SYM_RAMSTART DIREC_RAMEND
#include "zasm/symbol.asm"
; Read file through blockdev ID in H and outputs its upcodes through blockdev ; Read file through blockdev ID in H and outputs its upcodes through blockdev
; ID in L. ; ID in L.
zasmMain: zasmMain:

7
kernel/user.h.example Normal file
View File

@ -0,0 +1,7 @@
; Example include file for userspace program
; All userspace programs include this file in they main source file so that
; they know a couple of vital things about the system such as where user memory
; starts. This is an example file with required constants.
.equ USER_CODE 0x4800 ; Where in memory user code is loaded
.equ USER_RAMSTART 0x8800 ; Where in memory user memory begins

View File

@ -11,14 +11,19 @@ all: $(TARGETS)
shell/kernel.h: shell/shell_.asm shell/kernel.h: shell/shell_.asm
zasm/kernel.h: zasm/glue.asm zasm/kernel.h: zasm/glue.asm
$(KERNEL_HEADERS): $(KERNEL_HEADERS):
scas -o - -I $(KERNEL) -I $(APPS) $< | ./bin2c.sh KERNEL | tee $@ > /dev/null scas -o - -I $(KERNEL) $< | ./bin2c.sh KERNEL | tee $@ > /dev/null
zasm/user.h: $(APPS)/zasm/glue.asm
$(USER_HEADERS):
scas -o - -I $(APPS) $< | ./bin2c.sh USERSPACE | tee $@ > /dev/null
zasm/includes.cfs: $(CFSPACK) zasm/includes.cfs: $(CFSPACK)
rm -rf zasm/includes rm -rf zasm/includes
cp -r $(KERNEL) zasm/includes cp -r $(KERNEL) zasm/includes
cp -r $(APPS)/zasm zasm/includes/zasm cp -r $(APPS)/zasm zasm/includes/zasm
find zasm/includes -name *.md -delete find zasm/includes -name *.md -o -name *.example -delete
find zasm/includes -type f -exec sed -i -e 's/;.*//g' {} \; find zasm/includes -type f -exec sed -i -e 's/;.*//g' {} \;
cp user.h zasm/includes
$(CFSPACK) zasm/includes > $@ $(CFSPACK) zasm/includes > $@
rm -rf zasm/includes rm -rf zasm/includes
@ -26,7 +31,7 @@ zasm/includes.h: zasm/includes.cfs
./bin2c.sh FSDEV < $< | tee $@ > /dev/null ./bin2c.sh FSDEV < $< | tee $@ > /dev/null
shell/shell: shell/shell.c libz80/libz80.o shell/kernel.h $(CFSPACK) shell/shell: shell/shell.c libz80/libz80.o shell/kernel.h $(CFSPACK)
zasm/zasm: zasm/zasm.c libz80/libz80.o zasm/kernel.h zasm/includes.h zasm/zasm: zasm/zasm.c libz80/libz80.o zasm/kernel.h zasm/user.h zasm/includes.h
runbin/runbin: runbin/runbin.c libz80/libz80.o runbin/runbin: runbin/runbin.c libz80/libz80.o
$(TARGETS): $(TARGETS):
cc $< libz80/libz80.o -o $@ cc $< libz80/libz80.o -o $@

22
tools/emul/user.h Normal file
View File

@ -0,0 +1,22 @@
.equ USER_CODE 0x4800
.equ USER_RAMSTART 0x5800
.equ FS_HANDLE_SIZE 8
; *** JUMP TABLE ***
.equ strncmp 0x03
.equ addDE 0x06
.equ addHL 0x09
.equ upcase 0x0c
.equ unsetZ 0x0f
.equ intoDE 0x12
.equ intoHL 0x15
.equ writeHLinDE 0x18
.equ findchar 0x1b
.equ parseHex 0x1e
.equ parseHexPair 0x21
.equ blkSel 0x24
.equ fsFindFN 0x27
.equ fsOpen 0x2a
.equ fsGetC 0x2d
.equ fsSeek 0x30
.equ fsTell 0x33

View File

@ -6,7 +6,25 @@
.equ FS_SEEK_PORT 0x03 .equ FS_SEEK_PORT 0x03
.equ STDERR_PORT 0x04 .equ STDERR_PORT 0x04
jp init jp init ; 3 bytes
; *** JUMP TABLE ***
jp strncmp
jp addDE
jp addHL
jp upcase
jp unsetZ
jp intoDE
jp intoHL
jp writeHLinDE
jp findchar
jp parseHex
jp parseHexPair
jp blkSel
jp fsFindFN
jp fsOpen
jp fsGetC
jp fsSeek
jp fsTell
#include "core.asm" #include "core.asm"
#include "parse.asm" #include "parse.asm"
@ -21,8 +39,7 @@ jp init
.equ FS_RAMSTART BLOCKDEV_RAMEND .equ FS_RAMSTART BLOCKDEV_RAMEND
.equ FS_HANDLE_COUNT 0 .equ FS_HANDLE_COUNT 0
#include "fs.asm" #include "fs.asm"
.equ ZASM_RAMSTART FS_RAMEND #include "user.h"
#include "zasm/main.asm"
init: init:
di di
@ -34,7 +51,7 @@ init:
call fsOn call fsOn
ld h, 0 ; input blkdev ld h, 0 ; input blkdev
ld l, 1 ; output blkdev ld l, 1 ; output blkdev
call zasmMain call USER_CODE
; signal the emulator we're done ; signal the emulator we're done
halt halt

View File

@ -2,6 +2,7 @@
#include <stdio.h> #include <stdio.h>
#include "../libz80/z80.h" #include "../libz80/z80.h"
#include "kernel.h" #include "kernel.h"
#include "user.h"
#include "includes.h" #include "includes.h"
/* zasm reads from a specified blkdev, assemble the file and writes the result /* zasm reads from a specified blkdev, assemble the file and writes the result
@ -25,6 +26,7 @@
*/ */
// in sync with zasm_glue.asm // in sync with zasm_glue.asm
#define USER_CODE 0x4800
#define STDIO_PORT 0x00 #define STDIO_PORT 0x00
#define STDIN_SEEK_PORT 0x01 #define STDIN_SEEK_PORT 0x01
#define FS_DATA_PORT 0x02 #define FS_DATA_PORT 0x02
@ -150,6 +152,9 @@ int main()
for (int i=0; i<sizeof(KERNEL); i++) { for (int i=0; i<sizeof(KERNEL); i++) {
mem[i] = KERNEL[i]; mem[i] = KERNEL[i];
} }
for (int i=0; i<sizeof(USERSPACE); i++) {
mem[i+USER_CODE] = USERSPACE[i];
}
for (int i=0; i<sizeof(FSDEV); i++) { for (int i=0; i<sizeof(FSDEV); i++) {
fsdev[i] = FSDEV[i]; fsdev[i] = FSDEV[i];
} }

View File

@ -1,21 +1,28 @@
.equ RAMSTART 0x4000 .equ USER_CODE 0x4800
.equ ZASM_FIRST_PASS RAMSTART .equ USER_RAMSTART 0x5800
.equ ZASM_LOCAL_PASS ZASM_FIRST_PASS+1 .equ FS_HANDLE_SIZE 8
.equ ZASM_CTX_PC ZASM_LOCAL_PASS+1
.equ ZASM_RAMEND ZASM_CTX_PC+2
#include "core.asm" ; *** JUMP TABLE ***
#include "parse.asm" .equ strncmp 0x03
.equ BLOCKDEV_RAMSTART ZASM_RAMEND .equ addDE 0x06
.equ BLOCKDEV_COUNT 0 .equ addHL 0x09
#include "blockdev.asm" .equ upcase 0x0c
.equ unsetZ 0x0f
.equ FS_RAMSTART BLOCKDEV_RAMEND .equ intoDE 0x12
.equ FS_HANDLE_COUNT 0 .equ intoHL 0x15
#include "fs.asm" .equ writeHLinDE 0x18
.equ findchar 0x1b
.equ parseHex 0x1e
.equ parseHexPair 0x21
.equ blkSel 0x24
.equ fsFindFN 0x27
.equ fsOpen 0x2a
.equ fsGetC 0x2d
.equ fsSeek 0x30
.equ fsTell 0x33
#include "zasm/util.asm" #include "zasm/util.asm"
.equ IO_RAMSTART ZASM_RAMEND .equ IO_RAMSTART USER_RAMSTART
#include "zasm/io.asm" #include "zasm/io.asm"
.equ SYM_RAMSTART IO_RAMEND .equ SYM_RAMSTART IO_RAMEND
#include "zasm/symbol.asm" #include "zasm/symbol.asm"