@@ -13,20 +13,20 @@ $(BLKPACK): | |||
$(BLKUNPACK): $(BLKPACK) | |||
stage: stage.c $(OBJS) | |||
$(CC) stage.c -DFBIN_PATH=\"`pwd`/forth.bin\" -DBLKFS_PATH=\"`pwd`/blkfs\" $(OBJS) -o $@ | |||
$(CC) stage.c $(OBJS) -o $@ | |||
blkfs: $(BLKPACK) | |||
$(BLKPACK) ../blk > $@ | |||
forth: forth.c $(OBJS) | |||
$(CC) forth.c -DFBIN_PATH=\"`pwd`/forth.bin\" -DBLKFS_PATH=\"`pwd`/blkfs\" $(OBJS) -lncurses -o $@ | |||
$(CC) forth.c $(OBJS) -lncurses -o $@ | |||
libz80/libz80.o: libz80/z80.c | |||
$(MAKE) -C libz80/codegen opcodes | |||
$(CC) -Wall -ansi -g -c -o libz80/libz80.o libz80/z80.c | |||
emul.o: emul.c | |||
$(CC) -c -o emul.o emul.c | |||
$(CC) -DFBIN_PATH=\"`pwd`/forth.bin\" -DBLKFS_PATH=\"`pwd`/blkfs\" -c -o emul.o emul.c | |||
.PHONY: updatebootstrap | |||
@@ -1,13 +1,26 @@ | |||
/* Common code between shell, zasm and runbin. | |||
/* Common code between forth and stage binaries. | |||
They all run on the same kind of virtual machine: A z80 CPU, 64K of RAM/ROM. | |||
*/ | |||
#include <string.h> | |||
#include "emul.h" | |||
// Port for block reads. Write 2 bytes, MSB first, on that port and then | |||
// read 1024 bytes from the DATA port. | |||
#define BLK_PORT 0x03 | |||
#define BLKDATA_PORT 0x04 | |||
#ifndef BLKFS_PATH | |||
#error BLKFS_PATH needed | |||
#endif | |||
#ifndef FBIN_PATH | |||
#error FBIN_PATH needed | |||
#endif | |||
static Machine m; | |||
static ushort traceval = 0; | |||
static uint16_t blkid = 0; | |||
static FILE *blkfp; | |||
static uint8_t io_read(int unused, uint16_t addr) | |||
{ | |||
@@ -32,6 +45,23 @@ static void io_write(int unused, uint16_t addr, uint8_t val) | |||
} | |||
} | |||
static void iowr_blk(uint8_t val) | |||
{ | |||
blkid <<= 8; | |||
blkid |= val; | |||
fseek(blkfp, blkid*1024, SEEK_SET); | |||
} | |||
static uint8_t iord_blkdata() | |||
{ | |||
return getc(blkfp); | |||
} | |||
static void iowr_blkdata(uint8_t val) | |||
{ | |||
putc(val, blkfp); | |||
} | |||
static uint8_t mem_read(int unused, uint16_t addr) | |||
{ | |||
return m.mem[addr]; | |||
@@ -50,7 +80,26 @@ static void mem_write(int unused, uint16_t addr, uint8_t val) | |||
Machine* emul_init() | |||
{ | |||
fprintf(stderr, "Using blkfs %s\n", BLKFS_PATH); | |||
blkfp = fopen(BLKFS_PATH, "r+"); | |||
if (!blkfp) { | |||
fprintf(stderr, "Can't open\n"); | |||
return NULL; | |||
} | |||
// initialize memory | |||
memset(m.mem, 0, 0x10000); | |||
FILE *bfp = fopen(FBIN_PATH, "r"); | |||
if (!bfp) { | |||
fprintf(stderr, "Can't open forth.bin\n"); | |||
return NULL; | |||
} | |||
int i = 0; | |||
int c = getc(bfp); | |||
while (c != EOF) { | |||
m.mem[i++] = c; | |||
c = getc(bfp); | |||
} | |||
fclose(bfp); | |||
m.ramstart = 0; | |||
m.minsp = 0xffff; | |||
m.maxix = 0; | |||
@@ -63,9 +112,16 @@ Machine* emul_init() | |||
m.cpu.memWrite = mem_write; | |||
m.cpu.ioRead = io_read; | |||
m.cpu.ioWrite = io_write; | |||
m.iowr[BLK_PORT] = iowr_blk; | |||
m.iord[BLKDATA_PORT] = iord_blkdata; | |||
m.iowr[BLKDATA_PORT] = iowr_blkdata; | |||
return &m; | |||
} | |||
void emul_deinit() | |||
{ | |||
fclose(blkfp); | |||
} | |||
bool emul_step() | |||
{ | |||
@@ -29,6 +29,7 @@ typedef enum { | |||
} Tristate; | |||
Machine* emul_init(); | |||
void emul_deinit(); | |||
bool emul_step(); | |||
bool emul_steps(unsigned int steps); | |||
void emul_loop(); | |||
@@ -4,12 +4,6 @@ | |||
#include <curses.h> | |||
#include <termios.h> | |||
#include "emul.h" | |||
#ifndef FBIN_PATH | |||
#error FBIN_PATH needed | |||
#endif | |||
#ifndef BLKFS_PATH | |||
#error BLKFS_PATH needed | |||
#endif | |||
// in sync with glue.asm | |||
#define RAMSTART 0x900 | |||
@@ -23,9 +17,7 @@ | |||
#define BLKDATA_PORT 0x04 | |||
static FILE *fp; | |||
static FILE *blkfp; | |||
static int retcode = 0; | |||
static uint16_t blkid = 0; | |||
static uint8_t iord_stdio() | |||
{ | |||
@@ -57,63 +49,20 @@ static void iowr_ret(uint8_t val) | |||
retcode = val; | |||
} | |||
static void iowr_blk(uint8_t val) | |||
{ | |||
blkid <<= 8; | |||
blkid |= val; | |||
fseek(blkfp, blkid*1024, SEEK_SET); | |||
} | |||
static uint8_t iord_blkdata() | |||
{ | |||
uint8_t res = 0; | |||
int c = getc(blkfp); | |||
if (c != EOF) { | |||
res = c; | |||
} | |||
return res; | |||
} | |||
static void iowr_blkdata(uint8_t val) | |||
{ | |||
putc(val, blkfp); | |||
} | |||
int run() | |||
{ | |||
fprintf(stderr, "Using blkfs %s\n", BLKFS_PATH); | |||
blkfp = fopen(BLKFS_PATH, "r+"); | |||
if (!blkfp) { | |||
fprintf(stderr, "Can't open\n"); | |||
Machine *m = emul_init(); | |||
if (m == NULL) { | |||
return 1; | |||
} | |||
Machine *m = emul_init(); | |||
m->ramstart = RAMSTART; | |||
m->iord[STDIO_PORT] = iord_stdio; | |||
m->iowr[STDIO_PORT] = iowr_stdio; | |||
m->iowr[RET_PORT] = iowr_ret; | |||
m->iowr[BLK_PORT] = iowr_blk; | |||
m->iord[BLKDATA_PORT] = iord_blkdata; | |||
m->iowr[BLKDATA_PORT] = iowr_blkdata; | |||
// initialize memory | |||
FILE *bfp = fopen(FBIN_PATH, "r"); | |||
if (!bfp) { | |||
fprintf(stderr, "Can't open forth.bin\n"); | |||
return 1; | |||
} | |||
int i = 0; | |||
int c = getc(bfp); | |||
while (c != EOF) { | |||
m->mem[i++] = c; | |||
c = getc(bfp); | |||
} | |||
fclose(bfp); | |||
// Run! | |||
while (emul_step()); | |||
if (blkfp != NULL) { | |||
fclose(blkfp); | |||
} | |||
emul_deinit(); | |||
return retcode; | |||
} | |||
@@ -2,12 +2,6 @@ | |||
#include <stdio.h> | |||
#include <unistd.h> | |||
#include "emul.h" | |||
#ifndef FBIN_PATH | |||
#error FBIN_PATH needed | |||
#endif | |||
#ifndef BLKFS_PATH | |||
#error BLKFS_PATH needed | |||
#endif | |||
/* Staging binaries | |||
@@ -29,10 +23,6 @@ trouble of compiling defs to binary. | |||
// 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 | |||
// Port for block reads. Write 2 bytes, MSB first, on that port and then | |||
// read 1024 bytes from the DATA port. | |||
#define BLK_PORT 0x03 | |||
#define BLKDATA_PORT 0x04 | |||
static int running; | |||
// We support double-pokes, that is, a first poke to tell where to start the | |||
@@ -40,8 +30,6 @@ static int running; | |||
// then ending HERE and we start at sizeof(KERNEL). | |||
static uint16_t start_here = 0; | |||
static uint16_t end_here = 0; | |||
static uint16_t blkid = 0; | |||
static FILE *blkfp; | |||
static uint8_t iord_stdio() | |||
{ | |||
@@ -65,46 +53,16 @@ static void iowr_here(uint8_t val) | |||
end_here |= val; | |||
} | |||
static void iowr_blk(uint8_t val) | |||
{ | |||
blkid <<= 8; | |||
blkid |= val; | |||
fseek(blkfp, blkid*1024, SEEK_SET); | |||
} | |||
static uint8_t iord_blkdata() | |||
{ | |||
return getc(blkfp); | |||
} | |||
int main(int argc, char *argv[]) | |||
{ | |||
fprintf(stderr, "Using blkfs %s\n", BLKFS_PATH); | |||
blkfp = fopen(BLKFS_PATH, "r+"); | |||
if (!blkfp) { | |||
fprintf(stderr, "Can't open\n"); | |||
Machine *m = emul_init(); | |||
if (m == NULL) { | |||
return 1; | |||
} | |||
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; | |||
m->iowr[BLK_PORT] = iowr_blk; | |||
m->iord[BLKDATA_PORT] = iord_blkdata; | |||
// initialize memory | |||
FILE *bfp = fopen(FBIN_PATH, "r"); | |||
if (!bfp) { | |||
fprintf(stderr, "Can't open forth.bin\n"); | |||
return 1; | |||
} | |||
int i = 0; | |||
int c = getc(bfp); | |||
while (c != EOF) { | |||
m->mem[i++] = c; | |||
c = getc(bfp); | |||
} | |||
fclose(bfp); | |||
// Run! | |||
running = 1; | |||
@@ -114,6 +72,7 @@ int main(int argc, char *argv[]) | |||
for (int i=start_here; i<end_here; i++) { | |||
putchar(m->mem[i]); | |||
} | |||
emul_deinit(); | |||
emul_printdebug(); | |||
return 0; | |||
} | |||