1
0
mirror of https://github.com/hsoft/collapseos.git synced 2024-11-27 16:28:06 +11:00

Move apps/zasm/emul to tools/emul

This commit is contained in:
Virgil Dupras 2019-05-09 14:09:40 -04:00
parent 193e6e066c
commit 7f27d63c19
14 changed files with 169 additions and 145 deletions

View File

@ -1,4 +0,0 @@
libz80
kernel.h
zasm.h
zasm

View File

@ -1,12 +0,0 @@
zasm: zasm.c libz80/libz80.o kernel.h zasm.h
cc $< libz80/libz80.o -o $@
libz80/libz80.o: libz80/z80.c
make -C libz80/codegen opcodes
gcc -Wall -ansi -g -c -o libz80/libz80.o libz80/z80.c
kernel.h: glue.asm
scas -o - -I ../../../parts/z80 $< | ./bin2c.sh KERNEL | tee $@ > /dev/null
zasm.h: $(addprefix ../, main.asm instr.asm directive.asm tok.asm parse.asm literal.asm util.asm)
scas -o - -I.. $< | ./bin2c.sh ZASM | tee $@ > /dev/null

View File

@ -1,5 +0,0 @@
#!/bin/sh
echo "unsigned char $1[] = { "
xxd -i -
echo " };"

View File

@ -1,28 +0,0 @@
#include "user.inc"
; Glue code for the emulated environment
ZASM_INPUT .equ 0xa000
ZASM_OUTPUT .equ 0xd000
jr init ; 2 bytes
; *** JUMP TABLE ***
jp strncmp
jp addDE
jp upcase
jp unsetZ
jp intoDE
init:
di
ld hl, RAMEND
ld sp, hl
ld hl, ZASM_INPUT
ld de, ZASM_OUTPUT
call USER_CODE
; signal the emulator we're done
; BC contains the number of written bytes
ld a, c
ld c, b
out (c), a
halt
#include "core.asm"

View File

@ -1,81 +0,0 @@
#include <stdint.h>
#include <stdio.h>
#include "libz80/z80.h"
#include "kernel.h"
#include "zasm.h"
/* zasm is a "pure memory" application. It starts up being told memory location
* to read and memory location to write.
*
* This program works be writing stdin in a specific location in memory, run
* zasm in a special wrapper, wait until we receive the stop signal, then
* spit the contents of the dest memory to stdout.
*/
// in sync with glue.asm
#define READFROM 0xa000
#define WRITETO 0xd000
#define ZASM_CODE_OFFSET 0x8000
static Z80Context cpu;
static uint8_t mem[0xffff];
static int running;
// Number of bytes written to WRITETO
// We receive that result from an OUT (C), A call. C contains LSB, A is MSB.
static uint16_t written;
static uint8_t io_read(int unused, uint16_t addr)
{
return 0;
}
static void io_write(int unused, uint16_t addr, uint8_t val)
{
written = ((addr & 0xff) << 8) + (val & 0xff);
running = 0;
}
static uint8_t mem_read(int unused, uint16_t addr)
{
return mem[addr];
}
static void mem_write(int unused, uint16_t addr, uint8_t val)
{
mem[addr] = val;
}
int main()
{
// initialize memory
for (int i=0; i<sizeof(KERNEL); i++) {
mem[i] = KERNEL[i];
}
for (int i=0; i<sizeof(ZASM); i++) {
mem[i+ZASM_CODE_OFFSET] = ZASM[i];
}
int ptr = READFROM;
int c = getchar();
while (c != EOF) {
mem[ptr] = c;
ptr++;
c = getchar();
}
// Run!
running = 1;
Z80RESET(&cpu);
cpu.ioRead = io_read;
cpu.ioWrite = io_write;
cpu.memRead = mem_read;
cpu.memWrite = mem_write;
while (running) {
Z80Execute(&cpu);
}
for (int i=0; i<written; i++) {
putchar(mem[WRITETO+i]);
}
return 0;
}

View File

@ -1,8 +1,11 @@
#include "user.inc" ; *** Requirements ***
; JUMP_STRNCMP
; JUMP_ADDDE
; JUMP_UPCASE
; JUMP_UNSETZ
; JUMP_INTODE
; *** Code *** ; *** Code ***
.org USER_CODE
; Parse asm file in (HL) and outputs its upcodes in (DE). Returns the number ; Parse asm file in (HL) and outputs its upcodes in (DE). Returns the number
; of bytes written in C. ; of bytes written in C.
main: main:

6
apps/zasm/tests/Makefile Normal file
View File

@ -0,0 +1,6 @@
EMULDIR = ../../../tools/emul
.PHONY: run
run:
make -C $(EMULDIR) zasm
./runtests.sh

View File

@ -4,7 +4,7 @@ set -e
TMPFILE=$(mktemp) TMPFILE=$(mktemp)
SCAS=scas SCAS=scas
ZASM=../emul/zasm ZASM=../../../tools/emul/zasm
ASMFILE=../instr.asm ASMFILE=../instr.asm
cmpas() { cmpas() {

View File

@ -1,2 +1,4 @@
/shell /shell
/shell-kernel.h /zasm
/*-kernel.h
/*-user.h

View File

@ -1,10 +1,20 @@
TARGETS = shell zasm
KERNEL_HEADERS = shell-kernel.h zasm-kernel.h
.PHONY: all .PHONY: all
all: shell all: $(TARGETS)
shell-kernel.h: shell_.asm shell-kernel.h: shell_.asm
scas -o - -I ../../parts/z80 $< | ./bin2c.sh SHELL_KERNEL | tee $@ > /dev/null zasm-kernel.h: zasm_glue.asm
$(KERNEL_HEADERS):
scas -o - -I ../../parts/z80 $< | ./bin2c.sh KERNEL | tee $@ > /dev/null
zasm-user.h: zasm_user.asm
scas -o - -I ../../apps/zasm $< | ./bin2c.sh USERSPACE | tee $@ > /dev/null
shell: shell.c libz80/libz80.o shell-kernel.h shell: shell.c libz80/libz80.o shell-kernel.h
zasm: zasm.c libz80/libz80.o zasm-kernel.h zasm-user.h
$(TARGETS):
cc $< libz80/libz80.o -o $@ cc $< libz80/libz80.o -o $@
libz80/libz80.o: libz80/z80.c libz80/libz80.o: libz80/z80.c
@ -13,4 +23,4 @@ libz80/libz80.o: libz80/z80.c
.PHONY: clean .PHONY: clean
clean: clean:
rm shell shell-kernel.h rm -f $(TARGETS) $(KERNEL_HEADERS)

View File

@ -18,7 +18,6 @@
*/ */
// in sync with shell.asm // in sync with shell.asm
#define RAMSTART 0x4000
#define STDIO_PORT 0x00 #define STDIO_PORT 0x00
#define STDIN_ST_PORT 0x01 #define STDIN_ST_PORT 0x01
@ -79,8 +78,8 @@ int main()
// initialize memory // initialize memory
for (int i=0; i<sizeof(SHELL_KERNEL); i++) { for (int i=0; i<sizeof(KERNEL); i++) {
mem[i] = SHELL_KERNEL[i]; mem[i] = KERNEL[i];
} }
// Run! // Run!
running = 1; running = 1;

84
tools/emul/zasm.c Normal file
View File

@ -0,0 +1,84 @@
#include <stdint.h>
#include <stdio.h>
#include "libz80/z80.h"
#include "zasm-kernel.h"
#include "zasm-user.h"
/* zasm is a "pure memory" application. It starts up being told memory location
* to read and memory location to write.
*
*
* Memory layout:
*
* 0x0000 - 0x3fff: ROM code from zasm_glue.asm
* 0x4000 - 0xffff: Userspace
*
* I/O Ports:
*
* 0 - stdin / stdout
*/
// in sync with zasm_glue.asm
#define USER_CODE 0x4000
#define STDIO_PORT 0x00
static Z80Context cpu;
static uint8_t mem[0xffff];
static uint8_t io_read(int unused, uint16_t addr)
{
addr &= 0xff;
if (addr == STDIO_PORT) {
int c = getchar();
if (c == EOF) {
return 0;
}
return c;
} else {
fprintf(stderr, "Out of bounds I/O read: %d\n", addr);
return 0;
}
}
static void io_write(int unused, uint16_t addr, uint8_t val)
{
addr &= 0xff;
if (addr == STDIO_PORT) {
putchar(val);
} else {
fprintf(stderr, "Out of bounds I/O write: %d / %d\n", addr, val);
}
}
static uint8_t mem_read(int unused, uint16_t addr)
{
return mem[addr];
}
static void mem_write(int unused, uint16_t addr, uint8_t val)
{
mem[addr] = val;
}
int main()
{
// initialize memory
for (int i=0; i<sizeof(KERNEL); i++) {
mem[i] = KERNEL[i];
}
for (int i=0; i<sizeof(USERSPACE); i++) {
mem[i+USER_CODE] = USERSPACE[i];
}
Z80RESET(&cpu);
cpu.ioRead = io_read;
cpu.ioWrite = io_write;
cpu.memRead = mem_read;
cpu.memWrite = mem_write;
while (!cpu.halted) {
Z80Execute(&cpu);
}
fflush(stdout);
return 0;
}

51
tools/emul/zasm_glue.asm Normal file
View File

@ -0,0 +1,51 @@
; Glue code for the emulated environment
.equ USER_CODE 0x4000
.equ RAMEND 0xffff
.equ ZASM_INPUT 0xa000
.equ ZASM_OUTPUT 0xd000
.equ STDIO_PORT 0x00
jr init ; 2 bytes
; *** JUMP TABLE ***
jp strncmp
jp addDE
jp upcase
jp unsetZ
jp intoDE
init:
di
ld hl, RAMEND
ld sp, hl
ld hl, ZASM_INPUT
; yes, this means that input can't have null bytes
.inloop:
in a, (STDIO_PORT)
ld (hl), a ; before cond jr so we write a final \0
or a
jr z, .inloopend
inc hl
jr .inloop
.inloopend:
ld hl, ZASM_INPUT
ld de, ZASM_OUTPUT
call USER_CODE
; BC contains the number of written bytes
xor a
cp b
jr nz, .spit
cp c
jr z, .end ; no output
.spit:
ld hl, ZASM_OUTPUT
.outloop:
ld a, (hl)
out (STDIO_PORT), a
cpi ; a trick to inc HL and dec BC at the same time.
; P/V indicates whether BC reached 0
jp pe, .outloop ; BC is not zero, loop
.end:
; signal the emulator we're done
halt
#include "core.asm"

View File

@ -1,10 +1,9 @@
RAMSTART .equ 0x8000
RAMEND .equ 0xffff
USER_CODE .equ RAMSTART
; *** JUMP TABLE *** ; *** JUMP TABLE ***
JUMP_STRNCMP .equ 0x02 JUMP_STRNCMP .equ 0x02
JUMP_ADDDE .equ 0x05 JUMP_ADDDE .equ 0x05
JUMP_UPCASE .equ 0x08 JUMP_UPCASE .equ 0x08
JUMP_UNSETZ .equ 0x0b JUMP_UNSETZ .equ 0x0b
JUMP_INTODE .equ 0x0e JUMP_INTODE .equ 0x0e
.org 0x4000
#include "main.asm"