From 884e509d67a5afc6636dcca0fe917970cdeefb6c Mon Sep 17 00:00:00 2001 From: Raimon Zamora Date: Thu, 7 Aug 2025 10:35:49 +0200 Subject: [PATCH] - [NEW] [zx_disk] READ DATA command (0x06) --- zx_disk.cpp | 159 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 156 insertions(+), 3 deletions(-) diff --git a/zx_disk.cpp b/zx_disk.cpp index a8d3064..b0e5d4d 100644 --- a/zx_disk.cpp +++ b/zx_disk.cpp @@ -18,6 +18,7 @@ #define ZX_FDC_COMMAND_SENSE_INTERRUPT_STATUS 0x08 #define ZX_FDC_COMMAND_SEEK 0x0F #define ZX_FDC_COMMAND_READ_ID 0x0A +#define ZX_FDC_COMMAND_READ_DATA 0x06 #define ZX_FDC_MAIN_DRIVE0_BUSY 1 #define ZX_FDC_MAIN_DRIVE1_BUSY 2 @@ -71,6 +72,12 @@ namespace zx_disk uint8_t current_drive = 0; uint8_t current_track = 0; uint8_t current_sector = 0; + uint8_t current_byte = 0; + + uint16_t bytes_to_read = 0; + uint8_t eot = 0; + uint8_t st1 = 0; + uint8_t st2 = 0; int zx_fdc_main_status_port_in(int port); int zx_fdc_data_port_in(int port); @@ -158,7 +165,7 @@ namespace zx_disk int zx_fdc_main_status_port_in(int port) { - printf("FDC port 0x2ffd IN\n"); + if (mode != ZX_FDC_MODE_EXECUTION) printf("FDC port 0x2ffd IN\n"); return main_status_register(); } @@ -184,10 +191,11 @@ namespace zx_disk uint8_t process_command_sense_interrupt_status(uint8_t command); uint8_t process_command_seek(uint8_t command); uint8_t process_command_read_id(uint8_t command); + uint8_t process_command_read_data(uint8_t command); int zx_fdc_data_port_in(int port) { - printf("FDC port 0x3ffd IN\n"); + if (mode != ZX_FDC_MODE_EXECUTION) printf("FDC port 0x3ffd IN\n"); if (mode == ZX_FDC_MODE_COMMAND) { printf("IGNORED!\n"); return 0; @@ -240,6 +248,9 @@ namespace zx_disk case ZX_FDC_COMMAND_READ_ID: process_current_command = process_command_read_id; break; + case ZX_FDC_COMMAND_READ_DATA: + process_current_command = process_command_read_data; + break; default: { process_current_command = process_command_unknown; @@ -422,7 +433,7 @@ namespace zx_disk case 3: { call_count++; - const uint8_t val = current_track+1; + const uint8_t val = current_track; printf("--> (returning 0x%02x)\n", val); return val; } @@ -454,4 +465,146 @@ namespace zx_disk } return 0; } + + // =================================================================== + // FDC COMMAND: READ DATA (0x06) + // =================================================================== + uint8_t process_command_read_data(uint8_t command) + { + switch (mode) + { + case ZX_FDC_MODE_COMMAND: + switch (call_count) + { + case 1: + call_count++; + current_head = (command & 0x4)>>2; + current_drive = command & 0x3; + break; + case 2: + call_count++; + current_track = command; + break; + case 3: + call_count++; + current_head = command; + break; + case 4: + call_count++; + current_sector = command-1; + break; + case 5: + call_count++; + bytes_to_read = command; + break; + case 6: + call_count++; + eot = command; + break; + case 7: + call_count++; + // GPL; + break; + case 8: + call_count++; + if ( (bytes_to_read==0) && (command != 0xff) ) bytes_to_read = command; + bytes_to_read = bytes_to_read << 8; + current_byte = 0; + call_count = 0; + mode = ZX_FDC_MODE_EXECUTION; + break; + } + break; + + case ZX_FDC_MODE_EXECUTION: + { + const uint8_t val = disk.tracks[current_track].sectors[current_sector].data[current_byte]; + bytes_to_read--; + if (bytes_to_read==0) { + st1 = disk.tracks[current_track].sectors[current_sector].st1; + st2 = disk.tracks[current_track].sectors[current_sector].st2; + if (current_sector+1 == disk.tracks[current_track].num_sectors) { + current_track++; + current_sector = 0; + } else { + current_sector++; + } + current_byte = 0; + mode = ZX_FDC_MODE_RESULT; + } else { + current_byte++; + if (current_byte == disk.tracks[current_track].sectors[current_sector].data_length) { + current_byte = 0; + current_sector++; + // [TODO] Detectar si s'ha acabat la pista + } + } + return val; + 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 = st1; + printf("--> (returning 0x%02x)\n", val); + return val; + } + case 2: + { + call_count++; + const uint8_t val = st2; + printf("--> (returning 0x%02x)\n", val); + return val; + } + case 3: + { + call_count++; + const uint8_t val = current_track; + 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; + } + } + break; + } + } + return 0; + } + }