浏览代码

emul/z80: add SD card support to SMS

It works (in emulation, but soon on real hardware!), but the LIST
command is awkward due to tight screen estate...
master
Virgil Dupras 3 年前
父节点
当前提交
6947fea2a8
共有 8 个文件被更改,包括 64 次插入13 次删除
  1. +2
    -2
      blk/001
  2. +1
    -1
      blk/418
  3. +0
    -0
      blk/419
  4. +1
    -1
      emul/z80/Makefile
  5. +2
    -0
      emul/z80/README.md
  6. +4
    -0
      emul/z80/rc2014.c
  7. +53
    -8
      emul/z80/sms.c
  8. +1
    -1
      recipes/rc2014/sdcard.md

+ 2
- 2
blk/001 查看文件

@@ -6,6 +6,6 @@ MASTER INDEX
160 AVR SPI programmer
170-259 unused 260 Cross compilation
280 Z80 boot code 350 Core words
410 PS/2 keyboard subsystem 420 SD Card subsystem
440 8086 boot code
410 PS/2 keyboard subsystem 418 Z80 SPI Relay driver
420 SD Card subsystem 440 8086 boot code
470-519 unused 520 Fonts

recipes/rc2014/blk/615 → blk/418 查看文件

@@ -7,4 +7,4 @@ to SPI_CTL, we expect a bitmask of the device to select, with
returns 0 if the device is ready or 1 if it's still running an
exchange. Writing to SPI_DATA initiates an exchange.

Provides the SPI relay protocol. Load driver with "596 LOAD".
Provides the SPI relay protocol. Load driver with "419 LOAD".

recipes/rc2014/blk/616 → blk/419 查看文件


+ 1
- 1
emul/z80/Makefile 查看文件

@@ -1,7 +1,7 @@
TARGETS = forth rc2014 sms ti84
OBJS = emul.o z80.o
RC2014_OBJS = $(OBJS) sio.o acia.o sdc.o
SMS_OBJS = $(OBJS) sms_vdp.o sms_ports.o sms_pad.o ps2_kbd.o
SMS_OBJS = $(OBJS) sms_vdp.o sms_ports.o sms_pad.o ps2_kbd.o sdc.o
TI84_OBJS = $(OBJS) t6a04.o ti84_kbd.o
CDIR = ../../cvm
STAGE = $(CDIR)/stage


+ 2
- 0
emul/z80/README.md 查看文件

@@ -61,6 +61,8 @@ pad are:
If your ROM is configured with PS/2 keyboard input, run this emulator with the
`-k` flag to replace SMS pad emulation with keyboard emulation.

The `-c` option connects a SD card in the same way as the RC2014 emulator.

In both cases (pad or keyboard), only port A emulation is supported.

Press ESC to quit.


+ 4
- 0
emul/z80/rc2014.c 查看文件

@@ -143,6 +143,10 @@ int main(int argc, char *argv[])
case 'c':
fprintf(stderr, "Setting up SD card image with %s\n", optarg);
sdc.fp = fopen(optarg, "r+");
if (sdc.fp == NULL) {
fprintf(stderr, "Can't open file\n");
return 1;
}
break;
}
}


+ 53
- 8
emul/z80/sms.c 查看文件

@@ -12,6 +12,7 @@
#include "sms_ports.h"
#include "sms_pad.h"
#include "ps2_kbd.h"
#include "sdc.h"

#define RAMSTART 0xc000
#define VDP_CMD_PORT 0xbf
@@ -19,6 +20,8 @@
#define PORTS_CTL_PORT 0x3f
#define PORTS_IO1_PORT 0xdc
#define PORTS_IO2_PORT 0xdd
#define SDC_CTL 0x05
#define SDC_SPI 0x04
#define MAX_ROMSIZE 0x8000

static xcb_connection_t *conn;
@@ -39,6 +42,7 @@ static Ports ports;
static Pad pad;
static Kbd kbd;
static bool use_kbd = false;
static SDC sdc;

static uint8_t iord_vdp_cmd()
{
@@ -86,6 +90,28 @@ static void iowr_ports_ctl(uint8_t val)
ports_ctl_wr(&ports, val);
}

static uint8_t iord_sdc_spi()
{
return sdc_spi_rd(&sdc);
}

static void iowr_sdc_spi(uint8_t val)
{
sdc_spi_wr(&sdc, val);
}

// in emulation, exchanges are always instantaneous, so we
// always report as ready.
static uint8_t iord_sdc_ctl()
{
return 0;
}

static void iowr_sdc_ctl(uint8_t val)
{
sdc_ctl_wr(&sdc, val);
}

void create_window()
{
uint32_t mask;
@@ -227,7 +253,7 @@ void event_loop()
if (vdp_changed) {
// To avoid overdrawing, we'll let the CPU run a bit to finish its
// drawing operation.
emul_steps(100);
emul_steps(10000);
draw_pixels();
}
// A low tech way of checking when the window was closed. The proper way
@@ -263,7 +289,7 @@ void event_loop()

static void usage()
{
fprintf(stderr, "Usage: ./sms [-k] /path/to/rom\n");
fprintf(stderr, "Usage: ./sms [-k] [-c sdcard.img] /path/to/rom\n");
}

int main(int argc, char *argv[])
@@ -272,12 +298,27 @@ int main(int argc, char *argv[])
usage();
return 1;
}
vdp_init(&vdp);
vdp_changed = false;
ports_init(&ports);
pad_init(&pad, &ports.THA);
kbd_init(&kbd, &ports.THA);
sdc_init(&sdc);

int ch;
while ((ch = getopt(argc, argv, "k")) != -1) {
while ((ch = getopt(argc, argv, "kc:")) != -1) {
switch (ch) {
case 'k':
use_kbd = true;
break;
case 'c':
fprintf(stderr, "Setting up SD card image with %s\n", optarg);
sdc.fp = fopen(optarg, "r+");
if (sdc.fp == NULL) {
fprintf(stderr, "Can't open file\n");
return 1;
}
break;
}
}
if (optind != argc-1) {
@@ -301,16 +342,12 @@ int main(int argc, char *argv[])
fprintf(stderr, "ROM image too large.\n");
return 1;
}
vdp_init(&vdp);
vdp_changed = false;
ports_init(&ports);
pad_init(&pad, &ports.THA);
kbd_init(&kbd, &ports.THA);
if (use_kbd) {
ports.portA_rd = iord_kbd;
} else {
ports.portA_rd = iord_pad;
}

m->iord[VDP_CMD_PORT] = iord_vdp_cmd;
m->iord[VDP_DATA_PORT] = iord_vdp_data;
m->iord[PORTS_IO1_PORT] = iord_ports_io1;
@@ -319,11 +356,19 @@ int main(int argc, char *argv[])
m->iowr[VDP_CMD_PORT] = iowr_vdp_cmd;
m->iowr[VDP_DATA_PORT] = iowr_vdp_data;
m->iowr[PORTS_CTL_PORT] = iowr_ports_ctl;
m->iord[SDC_SPI] = iord_sdc_spi;
m->iowr[SDC_SPI] = iowr_sdc_spi;
m->iord[SDC_CTL] = iord_sdc_ctl;
m->iowr[SDC_CTL] = iowr_sdc_ctl;

conn = xcb_connect(NULL, NULL);
screen = xcb_setup_roots_iterator(xcb_get_setup(conn)).data;
create_window();
draw_pixels();
event_loop();
emul_printdebug();
if (sdc.fp) {
fclose(sdc.fp);
}
return 0;
}

+ 1
- 1
recipes/rc2014/sdcard.md 查看文件

@@ -84,7 +84,7 @@ and `SPI_CTL`, which are respectively `4` and `5` in our relay design.
You also need to tell the SDC subsystem which SPI device to activate by defining
the `SDC_DEVID` (1, 2, 4, 8 for device 0, 1, 2 or 3)

You can then load the driver with `616 LOAD`. This driver provides
You can then load the driver with `419 LOAD`. This driver provides
`(spix)` and `(spie)` which are then used in the SDC driver.

The SDC driver is at B420. It gives you a load range. This means that what


正在加载...
取消
保存