- [NEW] [zx_disk] READ DATA command (0x06)
This commit is contained in:
159
zx_disk.cpp
159
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user