diff --git a/zx_disk.cpp b/zx_disk.cpp index 005f254..a8d3064 100644 --- a/zx_disk.cpp +++ b/zx_disk.cpp @@ -1,6 +1,7 @@ #include "zx_disk.h" #include "z80.h" #include +#include #define ZX_FDC_MODE_IDLE 0 #define ZX_FDC_MODE_COMMAND 1 @@ -16,6 +17,7 @@ #define ZX_FDC_COMMAND_RECALIBRATE 0x07 #define ZX_FDC_COMMAND_SENSE_INTERRUPT_STATUS 0x08 #define ZX_FDC_COMMAND_SEEK 0x0F +#define ZX_FDC_COMMAND_READ_ID 0x0A #define ZX_FDC_MAIN_DRIVE0_BUSY 1 #define ZX_FDC_MAIN_DRIVE1_BUSY 2 @@ -29,16 +31,46 @@ namespace zx_disk { + struct sector_t + { + uint8_t id { 0 }; + uint8_t size { 0 }; + uint8_t st1 { 0 }; + uint8_t st2 { 0 }; + uint16_t data_length{ 0 }; + uint8_t *data { nullptr }; + }; + + struct track_t + { + uint8_t size { 0 }; + uint8_t sector_size { 0 }; + uint8_t num_sectors { 0 }; + uint8_t filler_byte { 0x35 }; + sector_t *sectors { nullptr }; + }; + + struct disk_t + { + uint8_t num_tracks { 0 }; + uint8_t num_sides { 0 }; + track_t *tracks { nullptr }; + }; + + disk_t disk; + uint8_t mode = ZX_FDC_MODE_IDLE; uint8_t call_count = 0; //uint8_t data_direction = 0x00; // 0x40 uint8_t fdd0busy = 0; + bool command_success = false; uint8_t srt, hlt, hut, nd; bool seeking = false; uint8_t current_head = 0; uint8_t current_drive = 0; uint8_t current_track = 0; + uint8_t current_sector = 0; int zx_fdc_main_status_port_in(int port); int zx_fdc_data_port_in(int port); @@ -48,6 +80,7 @@ namespace zx_disk { z80::connect_port(0x2ffd, 0xf002, zx_fdc_main_status_port_in, nullptr); z80::connect_port(0x3ffd, 0xf002, zx_fdc_data_port_in, zx_fdc_data_port_out); + load("goldenaxe1.dsk"); } void reset() @@ -55,6 +88,63 @@ namespace zx_disk } + void load(const char *filename) + { + FILE *f = fopen(filename, "rb"); + if (!f) return; + fseek(f, 0, SEEK_END); + const int file_size = ftell(f); + fseek(f, 0, SEEK_SET); + uint8_t *buffer = (uint8_t*)malloc(file_size); + fread(buffer, file_size, 1, f); + fclose(f); + + if (disk.tracks) { + for (int i=0; i>2; + current_drive = command & 0x3; + call_count = 0; + current_sector = 0; + mode = ZX_FDC_MODE_RESULT; + break; + case ZX_FDC_MODE_RESULT: + { + switch (call_count) + { + case 0: + { + call_count++; + fdd0busy = 1; + const uint8_t val = ST0(); + fdd0busy = 0; + printf("--> (returning 0x%02x)\n", val); + return val; + } + case 1: + { + call_count++; + const uint8_t val = 0x00; // ST1 + printf("--> (returning 0x%02x)\n", val); + return val; + } + case 2: + { + call_count++; + const uint8_t val = 0x00; // ST2 + printf("--> (returning 0x%02x)\n", val); + return val; + } + case 3: + { + call_count++; + const uint8_t val = current_track+1; + printf("--> (returning 0x%02x)\n", val); + return val; + } + case 4: + { + call_count++; + const uint8_t val = current_head; + printf("--> (returning 0x%02x)\n", val); + return val; + } + case 5: + { + call_count++; + const uint8_t val = current_sector+1; + printf("--> (returning 0x%02x)\n", val); + return val; + } + case 6: + { + call_count = 0; + process_current_command = nullptr; + mode = ZX_FDC_MODE_IDLE; + const uint8_t val = disk.tracks[current_track].sectors[current_sector].size; + printf("--> (returning 0x%02x)\n", val); + return val; + } + } + } + } + return 0; + } } diff --git a/zx_disk.h b/zx_disk.h index f429639..6a29778 100644 --- a/zx_disk.h +++ b/zx_disk.h @@ -4,4 +4,5 @@ namespace zx_disk { void init(); void reset(); + void load(const char *filename); }