mirror of
https://github.com/libretro/oberon-risc-emu.git
synced 2024-12-04 07:00:52 +00:00
Add --boot-from-serial option
The emulator does not require a disk image when using this option. The firmware however will attempt to initialize the SD cards regardless of chosen boot method, so we still emulate a dummy SD card.
This commit is contained in:
parent
08248b93fa
commit
a0890e1b40
49
src/disk.c
49
src/disk.c
@ -32,6 +32,7 @@ struct Disk {
|
||||
static uint32_t disk_read(const struct RISC_SPI *spi);
|
||||
static void disk_write(const struct RISC_SPI *spi, uint32_t value);
|
||||
static void disk_run_command(struct Disk *disk);
|
||||
static void seek_sector(FILE *f, uint32_t secnum);
|
||||
static void read_sector(FILE *f, uint32_t buf[static 128]);
|
||||
static void write_sector(FILE *f, uint32_t buf[static 128]);
|
||||
|
||||
@ -45,15 +46,17 @@ struct RISC_SPI *disk_new(const char *filename) {
|
||||
|
||||
disk->state = diskCommand;
|
||||
|
||||
disk->file = fopen(filename, "rb+");
|
||||
if (disk->file == 0) {
|
||||
fprintf(stderr, "Can't open file \"%s\": %s\n", filename, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
if (filename) {
|
||||
disk->file = fopen(filename, "rb+");
|
||||
if (disk->file == 0) {
|
||||
fprintf(stderr, "Can't open file \"%s\": %s\n", filename, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Check for filesystem-only image, starting directly at sector 1 (DiskAdr 29)
|
||||
read_sector(disk->file, &disk->tx_buf[0]);
|
||||
disk->offset = (disk->tx_buf[0] == 0x9B1EA38D)? 0x80002 : 0;
|
||||
// Check for filesystem-only image, starting directly at sector 1 (DiskAdr 29)
|
||||
read_sector(disk->file, &disk->tx_buf[0]);
|
||||
disk->offset = (disk->tx_buf[0] == 0x9B1EA38D) ? 0x80002 : 0;
|
||||
}
|
||||
|
||||
return &disk->spi;
|
||||
}
|
||||
@ -130,14 +133,14 @@ static void disk_run_command(struct Disk *disk) {
|
||||
disk->state = diskRead;
|
||||
disk->tx_buf[0] = 0;
|
||||
disk->tx_buf[1] = 254;
|
||||
fseek(disk->file, (arg - disk->offset) * 512, SEEK_SET);
|
||||
seek_sector(disk->file, arg - disk->offset);
|
||||
read_sector(disk->file, &disk->tx_buf[2]);
|
||||
disk->tx_cnt = 2 + 128;
|
||||
break;
|
||||
}
|
||||
case 88: {
|
||||
disk->state = diskWrite;
|
||||
fseek(disk->file, (arg - disk->offset) * 512, SEEK_SET);
|
||||
seek_sector(disk->file, arg - disk->offset);
|
||||
disk->tx_buf[0] = 0;
|
||||
disk->tx_cnt = 1;
|
||||
break;
|
||||
@ -151,9 +154,17 @@ static void disk_run_command(struct Disk *disk) {
|
||||
disk->tx_idx = -1;
|
||||
}
|
||||
|
||||
static void seek_sector(FILE *f, uint32_t secnum) {
|
||||
if (f) {
|
||||
fseek(f, secnum * 512, SEEK_SET);
|
||||
}
|
||||
}
|
||||
|
||||
static void read_sector(FILE *f, uint32_t buf[static 128]) {
|
||||
uint8_t bytes[512] = { 0 };
|
||||
fread(bytes, 512, 1, f);
|
||||
if (f) {
|
||||
fread(bytes, 512, 1, f);
|
||||
}
|
||||
for (int i = 0; i < 128; i++) {
|
||||
buf[i] = (uint32_t)bytes[i*4+0]
|
||||
| ((uint32_t)bytes[i*4+1] << 8)
|
||||
@ -163,12 +174,14 @@ static void read_sector(FILE *f, uint32_t buf[static 128]) {
|
||||
}
|
||||
|
||||
static void write_sector(FILE *f, uint32_t buf[static 128]) {
|
||||
uint8_t bytes[512];
|
||||
for (int i = 0; i < 128; i++) {
|
||||
bytes[i*4+0] = (uint8_t)(buf[i] );
|
||||
bytes[i*4+1] = (uint8_t)(buf[i] >> 8);
|
||||
bytes[i*4+2] = (uint8_t)(buf[i] >> 16);
|
||||
bytes[i*4+3] = (uint8_t)(buf[i] >> 24);
|
||||
if (f) {
|
||||
uint8_t bytes[512];
|
||||
for (int i = 0; i < 128; i++) {
|
||||
bytes[i*4+0] = (uint8_t)(buf[i] );
|
||||
bytes[i*4+1] = (uint8_t)(buf[i] >> 8);
|
||||
bytes[i*4+2] = (uint8_t)(buf[i] >> 16);
|
||||
bytes[i*4+3] = (uint8_t)(buf[i] >> 24);
|
||||
}
|
||||
fwrite(bytes, 512, 1, f);
|
||||
}
|
||||
fwrite(bytes, 512, 1, f);
|
||||
}
|
||||
|
@ -39,6 +39,7 @@ struct RISC {
|
||||
uint32_t mouse;
|
||||
uint8_t key_buf[16];
|
||||
uint32_t key_cnt;
|
||||
uint32_t switches;
|
||||
|
||||
const struct RISC_LED *leds;
|
||||
const struct RISC_Serial *serial;
|
||||
@ -101,6 +102,10 @@ void risc_set_clipboard(struct RISC *risc, const struct RISC_Clipboard *clipboar
|
||||
risc->clipboard = clipboard;
|
||||
}
|
||||
|
||||
void risc_set_switches(struct RISC *risc, int switches) {
|
||||
risc->switches = switches;
|
||||
}
|
||||
|
||||
void risc_screen_size_hack(struct RISC *risc, int width, int height) {
|
||||
risc->fb_width = width / 32;
|
||||
risc->fb_height = height;
|
||||
@ -407,7 +412,7 @@ static uint32_t risc_load_io(struct RISC *risc, uint32_t address) {
|
||||
}
|
||||
case 4: {
|
||||
// Switches
|
||||
return 0;
|
||||
return risc->switches;
|
||||
}
|
||||
case 8: {
|
||||
// RS232 data
|
||||
|
@ -20,6 +20,7 @@ void risc_set_leds(struct RISC *risc, const struct RISC_LED *leds);
|
||||
void risc_set_serial(struct RISC *risc, const struct RISC_Serial *serial);
|
||||
void risc_set_spi(struct RISC *risc, int index, const struct RISC_SPI *spi);
|
||||
void risc_set_clipboard(struct RISC *risc, const struct RISC_Clipboard *clipboard);
|
||||
void risc_set_switches(struct RISC *risc, int switches);
|
||||
void risc_screen_size_hack(struct RISC *risc, int width, int height);
|
||||
|
||||
void risc_reset(struct RISC *risc);
|
||||
|
@ -62,13 +62,14 @@ struct KeyMapping key_map[] = {
|
||||
};
|
||||
|
||||
static struct option long_options[] = {
|
||||
{ "zoom", required_argument, NULL, 'z' },
|
||||
{ "fullscreen", no_argument, NULL, 'f' },
|
||||
{ "leds", no_argument, NULL, 'L' },
|
||||
{ "size", required_argument, NULL, 's' },
|
||||
{ "serial-in", required_argument, NULL, 'I' },
|
||||
{ "serial-out", required_argument, NULL, 'O' },
|
||||
{ NULL, no_argument, NULL, 0 }
|
||||
{ "zoom", required_argument, NULL, 'z' },
|
||||
{ "fullscreen", no_argument, NULL, 'f' },
|
||||
{ "leds", no_argument, NULL, 'L' },
|
||||
{ "size", required_argument, NULL, 's' },
|
||||
{ "serial-in", required_argument, NULL, 'I' },
|
||||
{ "serial-out", required_argument, NULL, 'O' },
|
||||
{ "boot-from-serial", no_argument, NULL, 'S' },
|
||||
{ NULL, no_argument, NULL, 0 }
|
||||
};
|
||||
|
||||
static void fail(int code, const char *fmt, ...) {
|
||||
@ -101,9 +102,10 @@ int main (int argc, char *argv[]) {
|
||||
};
|
||||
const char *serial_in = NULL;
|
||||
const char *serial_out = NULL;
|
||||
bool boot_from_serial = false;
|
||||
|
||||
int opt;
|
||||
while ((opt = getopt_long(argc, argv, "z:fLS:I:O:", long_options, NULL)) != -1) {
|
||||
while ((opt = getopt_long(argc, argv, "z:fLs:I:O:S", long_options, NULL)) != -1) {
|
||||
switch (opt) {
|
||||
case 'z': {
|
||||
double x = strtod(optarg, 0);
|
||||
@ -138,16 +140,25 @@ int main (int argc, char *argv[]) {
|
||||
serial_out = optarg;
|
||||
break;
|
||||
}
|
||||
case 'S': {
|
||||
boot_from_serial = true;
|
||||
risc_set_switches(risc, 1);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
usage();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (optind != argc - 1) {
|
||||
if (optind == argc - 1) {
|
||||
risc_set_spi(risc, 1, disk_new(argv[optind]));
|
||||
} else if (optind == argc && boot_from_serial) {
|
||||
/* Allow diskless boot */
|
||||
risc_set_spi(risc, 1, disk_new(NULL));
|
||||
} else {
|
||||
usage();
|
||||
}
|
||||
risc_set_spi(risc, 1, disk_new(argv[optind]));
|
||||
|
||||
if (serial_in || serial_out) {
|
||||
if (!serial_in) {
|
||||
|
Loading…
Reference in New Issue
Block a user