|
|
@@ -13,16 +13,21 @@ |
|
|
|
#include <termios.h> |
|
|
|
#include "../../emul.h" |
|
|
|
#include "acia.h" |
|
|
|
#include "sio.h" |
|
|
|
#include "sdc.h" |
|
|
|
|
|
|
|
#define RAMSTART 0x8000 |
|
|
|
#define ACIA_CTL_PORT 0x80 |
|
|
|
#define ACIA_DATA_PORT 0x81 |
|
|
|
#define SIO_ACTL_PORT 0x80 |
|
|
|
#define SIO_ADATA_PORT 0x81 |
|
|
|
#define SDC_CTL 0x05 |
|
|
|
#define SDC_SPI 0x04 |
|
|
|
#define MAX_ROMSIZE 0x2000 |
|
|
|
|
|
|
|
bool use_sio = false; |
|
|
|
static ACIA acia; |
|
|
|
static SIO sio; |
|
|
|
static SDC sdc; |
|
|
|
|
|
|
|
static uint8_t iord_acia_ctl() |
|
|
@@ -45,6 +50,26 @@ static void iowr_acia_data(uint8_t val) |
|
|
|
acia_data_wr(&acia, val); |
|
|
|
} |
|
|
|
|
|
|
|
static uint8_t iord_sio_ctl() |
|
|
|
{ |
|
|
|
return sio_actl_rd(&sio); |
|
|
|
} |
|
|
|
|
|
|
|
static uint8_t iord_sio_data() |
|
|
|
{ |
|
|
|
return sio_adata_rd(&sio); |
|
|
|
} |
|
|
|
|
|
|
|
static void iowr_sio_ctl(uint8_t val) |
|
|
|
{ |
|
|
|
sio_actl_wr(&sio, val); |
|
|
|
} |
|
|
|
|
|
|
|
static void iowr_sio_data(uint8_t val) |
|
|
|
{ |
|
|
|
sio_adata_wr(&sio, val); |
|
|
|
} |
|
|
|
|
|
|
|
static uint8_t iord_sdc_spi() |
|
|
|
{ |
|
|
|
return sdc_spi_rd(&sdc); |
|
|
@@ -67,13 +92,65 @@ static void iowr_sdc_ctl(uint8_t val) |
|
|
|
sdc_ctl_wr(&sdc, val); |
|
|
|
} |
|
|
|
|
|
|
|
static bool has_irq() |
|
|
|
{ |
|
|
|
return use_sio ? sio_has_irq(&sio) : acia_has_irq(&acia); |
|
|
|
} |
|
|
|
|
|
|
|
static bool hastx() |
|
|
|
{ |
|
|
|
return use_sio ? sio_hastx(&sio) : acia_hastx(&acia); |
|
|
|
} |
|
|
|
|
|
|
|
static bool hasrx() |
|
|
|
{ |
|
|
|
return use_sio ? sio_hasrx(&sio) : acia_hasrx(&acia); |
|
|
|
} |
|
|
|
|
|
|
|
static uint8_t _read() |
|
|
|
{ |
|
|
|
return use_sio ? sio_read(&sio) : acia_read(&acia); |
|
|
|
} |
|
|
|
|
|
|
|
static void _write(uint8_t val) |
|
|
|
{ |
|
|
|
if (use_sio) { sio_write(&sio, val); } else { acia_write(&acia, val); } |
|
|
|
} |
|
|
|
|
|
|
|
static void usage() |
|
|
|
{ |
|
|
|
fprintf(stderr, "Usage: ./classic [-s] [-c sdcard.img] /path/to/rom\n"); |
|
|
|
} |
|
|
|
|
|
|
|
int main(int argc, char *argv[]) |
|
|
|
{ |
|
|
|
FILE *fp = NULL; |
|
|
|
int ch; |
|
|
|
|
|
|
|
if (argc < 2) { |
|
|
|
fprintf(stderr, "Usage: ./classic /path/to/rom [sdcard.img]\n"); |
|
|
|
usage(); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
FILE *fp = fopen(argv[1], "r"); |
|
|
|
acia_init(&acia); |
|
|
|
sio_init(&sio); |
|
|
|
sdc_init(&sdc); |
|
|
|
|
|
|
|
while ((ch = getopt(argc, argv, "sc:")) != -1) { |
|
|
|
switch (ch) { |
|
|
|
case 's': |
|
|
|
use_sio = true; |
|
|
|
break; |
|
|
|
case 'c': |
|
|
|
fprintf(stderr, "Setting up SD card image with %s\n", optarg); |
|
|
|
sdc.fp = fopen(optarg, "r+"); |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
if (optind != argc-1) { |
|
|
|
usage(); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
fp = fopen(argv[optind], "r"); |
|
|
|
if (fp == NULL) { |
|
|
|
fprintf(stderr, "Can't open %s\n", argv[1]); |
|
|
|
return 1; |
|
|
@@ -106,16 +183,17 @@ int main(int argc, char *argv[]) |
|
|
|
tcsetattr(0, TCSADRAIN, &term); |
|
|
|
} |
|
|
|
|
|
|
|
acia_init(&acia); |
|
|
|
sdc_init(&sdc); |
|
|
|
if (argc == 3) { |
|
|
|
fprintf(stderr, "Setting up SD card image\n"); |
|
|
|
sdc.fp = fopen(argv[2], "r+"); |
|
|
|
if (use_sio) { |
|
|
|
m->iord[SIO_ACTL_PORT] = iord_sio_ctl; |
|
|
|
m->iord[SIO_ADATA_PORT] = iord_sio_data; |
|
|
|
m->iowr[SIO_ACTL_PORT] = iowr_sio_ctl; |
|
|
|
m->iowr[SIO_ADATA_PORT] = iowr_sio_data; |
|
|
|
} else { |
|
|
|
m->iord[ACIA_CTL_PORT] = iord_acia_ctl; |
|
|
|
m->iord[ACIA_DATA_PORT] = iord_acia_data; |
|
|
|
m->iowr[ACIA_CTL_PORT] = iowr_acia_ctl; |
|
|
|
m->iowr[ACIA_DATA_PORT] = iowr_acia_data; |
|
|
|
} |
|
|
|
m->iord[ACIA_CTL_PORT] = iord_acia_ctl; |
|
|
|
m->iord[ACIA_DATA_PORT] = iord_acia_data; |
|
|
|
m->iowr[ACIA_CTL_PORT] = iowr_acia_ctl; |
|
|
|
m->iowr[ACIA_DATA_PORT] = iowr_acia_data; |
|
|
|
m->iord[SDC_SPI] = iord_sdc_spi; |
|
|
|
m->iowr[SDC_SPI] = iowr_sdc_spi; |
|
|
|
m->iord[SDC_CTL] = iord_sdc_ctl; |
|
|
@@ -124,12 +202,12 @@ int main(int argc, char *argv[]) |
|
|
|
char tosend = 0; |
|
|
|
while (emul_step()) { |
|
|
|
// Do we have an interrupt? |
|
|
|
if (acia_has_irq(&acia)) { |
|
|
|
if (has_irq()) { |
|
|
|
Z80INT(&m->cpu, 0); |
|
|
|
} |
|
|
|
// Is the RC2014 transmitting? |
|
|
|
if (acia_hastx(&acia)) { |
|
|
|
putchar(acia_read(&acia)); |
|
|
|
if (hastx()) { |
|
|
|
putchar(_read()); |
|
|
|
fflush(stdout); |
|
|
|
} |
|
|
|
// Do we have something to send? |
|
|
@@ -150,8 +228,8 @@ int main(int argc, char *argv[]) |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
if (tosend && !acia_hasrx(&acia)) { |
|
|
|
acia_write(&acia, tosend); |
|
|
|
if (tosend && !hasrx()) { |
|
|
|
_write(tosend); |
|
|
|
tosend = 0; |
|
|
|
} |
|
|
|
} |
|
|
|