Skip to content

Commit

Permalink
Refactoring, COMMAND_FDS_BLOCK_CRC_ERROR message
Browse files Browse the repository at this point in the history
ClusterM committed Apr 23, 2021
1 parent f45d5cb commit ffcabaa
Showing 6 changed files with 788 additions and 571 deletions.
544 changes: 363 additions & 181 deletions STM32/.cproject

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions STM32/Core/Inc/comm.h
Original file line number Diff line number Diff line change
@@ -49,6 +49,8 @@
#define COMMAND_FDS_WRITE_DONE 54
#define COMMAND_SET_FLASH_BUFFER_SIZE 55
#define COMMAND_SET_VALUE_DONE 56
#define COMMAND_FDS_DISK_WRITE_PROTECTED 57
#define COMMAND_FDS_BLOCK_CRC_ERROR 58

#define COMMAND_BOOTLOADER 0xFE
#define COMMAND_DEBUG 0xFF
4 changes: 4 additions & 0 deletions STM32/Core/Inc/dumper.h
Original file line number Diff line number Diff line change
@@ -21,6 +21,10 @@
#define FDS_CONTROL_TRANSFER_ON 0b01000000
#define FDS_CONTROL_IRQ_ON 0b10000000

#define FDS_DRIVE_STATUS_DISK_NOT_INSERTED 0b00000001
#define FDS_DRIVE_STATUS_DISK_NOT_READY 0b00000010
#define FDS_DRIVE_STATUS_DISK_WRITE_PROTECTED 0b00000100

#define FDS_READ_GAP_BEFORE_FIRST_BLOCK 486974
#define FDS_WRITE_GAP_BEFORE_FIRST_BLOCK 580000
#define FDS_READ_GAP_BETWEEN_BLOCKS 9026
1 change: 0 additions & 1 deletion STM32/Core/Src/comm.c
Original file line number Diff line number Diff line change
@@ -28,7 +28,6 @@ static void comm_flush(void)
if (HAL_GetTick() >= start_time + SEND_TIMEOUT) // timeout
break;
res = CDC_Transmit_FS((uint8_t*) send_buffer, send_buffer_pos);
//HAL_Delay(1);
} while (res != USBD_OK);
send_buffer_pos = 0;
}
148 changes: 89 additions & 59 deletions STM32/Core/Src/dumper.c
Original file line number Diff line number Diff line change
@@ -260,9 +260,9 @@ static uint8_t transfer_fds_byte(uint8_t *output, uint8_t input, uint8_t *end_of
else
dummy = PRG(FDS_DATA_READ);
PRG(FDS_DATA_WRITE) = input; // clear interrupt
uint8_t status = PRG(FDS_DISK_STATUS);
uint8_t disk_status = PRG(FDS_DISK_STATUS);
if (end_of_head)
*end_of_head |= (status >> 6) & 1;
*end_of_head |= (disk_status >> 6) & 1;
start_time = HAL_GetTick();
while (IRQ_FIRED)
{
@@ -278,11 +278,13 @@ static uint8_t transfer_fds_byte(uint8_t *output, uint8_t input, uint8_t *end_of
return 1;
}

static uint8_t read_fds_block_send(uint16_t length, uint8_t send, uint8_t *crc_ok, uint8_t *end_of_head, uint16_t *file_size, uint32_t gap_delay)
static uint8_t read_fds_block_send(uint16_t length, uint8_t send, uint16_t *file_size, uint32_t gap_delay)
{
uint8_t data;
uint8_t status;
uint8_t disk_status;
uint32_t b;
uint8_t crc_ok = 1;
uint8_t end_of_head = 0;

delay_clock(gap_delay);
if (send)
@@ -294,7 +296,7 @@ static uint8_t read_fds_block_send(uint16_t length, uint8_t send, uint8_t *crc_o
PRG(FDS_CONTROL) = FDS_CONTROL_READ | FDS_CONTROL_MOTOR_ON | FDS_CONTROL_TRANSFER_ON | FDS_CONTROL_IRQ_ON;
for (b = 0; b < length; b++)
{
if (!transfer_fds_byte(&data, 0, end_of_head))
if (!transfer_fds_byte(&data, 0, &end_of_head))
return 0;
// parse file size if need
if (file_size)
@@ -307,18 +309,33 @@ static uint8_t read_fds_block_send(uint16_t length, uint8_t send, uint8_t *crc_o
if (send)
comm_send_byte(data);
}
if (!transfer_fds_byte(0, 0, end_of_head))
if (!transfer_fds_byte(0, 0, &end_of_head))
return 0;
PRG(FDS_CONTROL) = FDS_CONTROL_READ | FDS_CONTROL_MOTOR_ON | FDS_CONTROL_TRANSFER_ON | FDS_CONTROL_IRQ_ON | FDS_CONTROL_CRC; // enable CRC control
if (!transfer_fds_byte(0, 0, end_of_head))
if (!transfer_fds_byte(0, 0, &end_of_head))
return 0;
status = PRG(FDS_DISK_STATUS);
*crc_ok &= ((status >> 4) & 1) ^ 1;
*end_of_head |= (status >> 6) & 1;
disk_status = PRG(FDS_DISK_STATUS);
crc_ok &= ((disk_status >> 4) & 1) ^ 1;
end_of_head |= (disk_status >> 6) & 1;
if (send)
{
comm_send_byte(*crc_ok); // CRC check result
comm_send_byte(*end_of_head); // end of head meet?
comm_send_byte(crc_ok); // CRC check result
comm_send_byte(end_of_head); // end of head meet?
}
if (!crc_ok || end_of_head)
{
// invalid data or end of disk, abort transfer
PRG(FDS_CONTROL) = FDS_CONTROL_READ | FDS_CONTROL_MOTOR_OFF; // reset, stop
HAL_Delay(50);
if (send)
comm_start(COMMAND_FDS_READ_RESULT_END, 0);
else {
if (!crc_ok)
comm_start(COMMAND_FDS_BLOCK_CRC_ERROR, 0);
else
comm_start(COMMAND_FDS_END_OF_HEAD, 0);
}
return 0;
}
PRG(FDS_CONTROL) = FDS_CONTROL_READ | FDS_CONTROL_MOTOR_ON; // motor on without transfer

@@ -371,8 +388,8 @@ static uint8_t write_fds_block(uint8_t *data, uint16_t length, uint32_t gap_dela
start_time = HAL_GetTick();
while (1)
{
uint8_t status = PRG(FDS_DRIVE_STATUS);
if (!(status & 2))
uint8_t drive_status = PRG(FDS_DRIVE_STATUS);
if (!(drive_status & FDS_DRIVE_STATUS_DISK_NOT_READY))
break; // ready
// timeout 1 sec
if (HAL_GetTick() - start_time >= 1000)
@@ -388,32 +405,39 @@ static uint8_t write_fds_block(uint8_t *data, uint16_t length, uint32_t gap_dela
return 1; // success
}

void fds_transfer(uint8_t block_read_start, uint8_t block_read_count, uint8_t block_write_count, uint8_t *block_write_ids, uint16_t *write_lengths, uint8_t *write_data)
uint8_t fds_transfer_real(uint8_t block_read_start, uint8_t block_read_count, uint8_t block_write_count, uint8_t *block_write_ids, uint16_t *write_lengths, uint8_t *write_data)
{
uint8_t crc_ok = 1;
uint8_t end_of_head = 0;
uint8_t current_block = 0;
uint8_t current_writing_block = 0;
uint32_t start_time;
uint8_t drive_status;
uint8_t blocks_writed = 0;

led_magenta();
PRG(FDS_IRQ_CONTROL) = 0x00; // disable timer IRQ
PRG(FDS_MASTER_IO) = 0x01; // enable disk registers
PRG(FDS_CONTROL) = FDS_CONTROL_READ | FDS_CONTROL_MOTOR_OFF; // reset
if (PRG(FDS_DRIVE_STATUS) & 1)
drive_status = PRG(FDS_DRIVE_STATUS);
// is disk inserted?
if (drive_status & FDS_DRIVE_STATUS_DISK_NOT_INSERTED)
{
comm_start(COMMAND_FDS_DISK_NOT_INSERTED, 0);
return;
return 0;
}
// is it write protected while we are writing?
if (block_write_count && (drive_status & FDS_DRIVE_STATUS_DISK_WRITE_PROTECTED))
{
comm_start(COMMAND_FDS_DISK_WRITE_PROTECTED, 0);
return 0;
}
// battery test
PRG(FDS_CONTROL) = FDS_CONTROL_READ | FDS_CONTROL_MOTOR_ON; // monor on, unreset
HAL_Delay(100);
if ((PRG(FDS_EXT_READ) & 0x80) == 0)
if (!(PRG(FDS_EXT_READ) & 0x80))
{
// battery low
PRG(FDS_CONTROL) = FDS_CONTROL_READ | FDS_CONTROL_MOTOR_OFF; // reset, stop
comm_start(COMMAND_FDS_BATTERY_LOW, 0);
return;
return 0;
}
// waiting until drive is rewinded
start_time = HAL_GetTick();
@@ -424,9 +448,9 @@ void fds_transfer(uint8_t block_read_start, uint8_t block_read_count, uint8_t bl
{
PRG(FDS_CONTROL) = FDS_CONTROL_READ | FDS_CONTROL_MOTOR_OFF; // reset, stop
comm_start(COMMAND_FDS_TIMEOUT, 0);
return;
return 0;
}
} while (!(PRG(FDS_DRIVE_STATUS) & 2));
} while (!(PRG(FDS_DRIVE_STATUS) & FDS_DRIVE_STATUS_DISK_NOT_READY));
start_time = HAL_GetTick();
do
{
@@ -435,105 +459,111 @@ void fds_transfer(uint8_t block_read_start, uint8_t block_read_count, uint8_t bl
{
PRG(FDS_CONTROL) = FDS_CONTROL_READ | FDS_CONTROL_MOTOR_OFF; // reset, stop
comm_start(COMMAND_FDS_TIMEOUT, 0);
return;
return 0;
}
} while (PRG(FDS_DRIVE_STATUS) & 2);
} while (PRG(FDS_DRIVE_STATUS) & FDS_DRIVE_STATUS_DISK_NOT_READY);

led_cyan();

// disk info block
if (block_write_count && (current_block == block_write_ids[current_writing_block]))
if (block_write_count && (current_block == block_write_ids[blocks_writed]))
{
// gap delay while writing = ~28300 bits = (~28300 / 8)bits * ~165cycles = ~583687.5
uint16_t write_length = write_lengths[current_writing_block];
uint16_t write_length = write_lengths[blocks_writed];
if (!write_fds_block(write_data, write_length, FDS_WRITE_GAP_BEFORE_FIRST_BLOCK))
return;
return 0;
write_data += write_length;
current_writing_block++;
blocks_writed++;
block_write_count--;
} else
{
// gap delay while reading = ~486974 cycles
if (!read_fds_block_send(56, (current_block >= block_read_start) && block_read_count, &crc_ok, &end_of_head, 0, FDS_READ_GAP_BEFORE_FIRST_BLOCK))
return;
if (!read_fds_block_send(56, (current_block >= block_read_start) && block_read_count, 0, FDS_READ_GAP_BEFORE_FIRST_BLOCK))
return 0;
}
if ((current_block >= block_read_start) && block_read_count)
block_read_count--;
current_block++;

if (crc_ok && !end_of_head && (block_read_count || block_write_count))
if (block_read_count || block_write_count)
{
// file amount block
if (block_write_count && (current_block == block_write_ids[current_writing_block]))
if (block_write_count && (current_block == block_write_ids[blocks_writed]))
{
uint16_t write_length = write_lengths[current_writing_block];
uint16_t write_length = write_lengths[blocks_writed];
if (!write_fds_block(write_data, write_length, FDS_WRITE_GAP_BETWEEN_BLOCKS))
return;
return 0;
write_data += write_length;
current_writing_block++;
blocks_writed++;
block_write_count--;
} else
{
if (!read_fds_block_send(2, (current_block >= block_read_start) && block_read_count, &crc_ok, &end_of_head, 0, FDS_READ_GAP_BETWEEN_BLOCKS))
return;
if (!read_fds_block_send(2, (current_block >= block_read_start) && block_read_count, 0, FDS_READ_GAP_BETWEEN_BLOCKS))
return 0;
}
if ((current_block >= block_read_start) && block_read_count)
block_read_count--;
current_block++;
}

while (crc_ok && !end_of_head && (block_read_count || block_write_count))
while (block_read_count || block_write_count)
{
// file header block
uint16_t file_size = 0; // size of the next file
if (block_write_count && (current_block == block_write_ids[current_writing_block]))
if (block_write_count && (current_block == block_write_ids[blocks_writed]))
{
uint16_t write_length = write_lengths[current_writing_block];
uint16_t write_length = write_lengths[blocks_writed];
if (!write_fds_block(write_data, write_length, FDS_WRITE_GAP_BETWEEN_BLOCKS))
return;
return 0;
write_data += write_length;
current_writing_block++;
blocks_writed++;
block_write_count--;
} else
{
if (!read_fds_block_send(16, (current_block >= block_read_start) && block_read_count, &crc_ok, &end_of_head, &file_size, FDS_READ_GAP_BETWEEN_BLOCKS))
return;
if (!read_fds_block_send(16, (current_block >= block_read_start) && block_read_count, &file_size, FDS_READ_GAP_BETWEEN_BLOCKS))
return 0;
}
if ((current_block >= block_read_start) && block_read_count)
block_read_count--;
current_block++;

if (crc_ok && !end_of_head && (block_read_count || block_write_count))
if (block_read_count || block_write_count)
{
// file data block
if (block_write_count && (current_block == block_write_ids[current_writing_block]))
if (block_write_count && (current_block == block_write_ids[blocks_writed]))
{
uint16_t write_length = write_lengths[current_writing_block];
uint16_t write_length = write_lengths[blocks_writed];
if (!write_fds_block(write_data, write_length, FDS_WRITE_GAP_BETWEEN_BLOCKS))
return;
return 0;
write_data += write_length;
current_writing_block++;
blocks_writed++;
block_write_count--;
} else
{
if (!read_fds_block_send(file_size + 1, (current_block >= block_read_start) && block_read_count, &crc_ok, &end_of_head, 0, FDS_READ_GAP_BETWEEN_BLOCKS))
return;
if (!read_fds_block_send(file_size + 1, (current_block >= block_read_start) && block_read_count, 0, FDS_READ_GAP_BETWEEN_BLOCKS))
return 0;
}
if ((current_block >= block_read_start) && block_read_count)
block_read_count--;
current_block++;
}
}

PRG(FDS_CONTROL) = FDS_CONTROL_READ | FDS_CONTROL_MOTOR_OFF; // reset, stop
return 1;
}

HAL_Delay(50);
if (current_writing_block && !block_write_count && !block_read_count)
void fds_transfer(uint8_t block_read_start, uint8_t block_read_count, uint8_t block_write_count, uint8_t *block_write_ids, uint16_t *write_lengths, uint8_t *write_data)
{
uint8_t ok = fds_transfer_real(block_read_start, block_read_count, block_write_count, block_write_ids, write_lengths, write_data);
PRG(FDS_CONTROL) = FDS_CONTROL_READ | FDS_CONTROL_MOTOR_OFF; // reset, stop
if (ok)
{
comm_start(COMMAND_FDS_WRITE_DONE, 0);
return;
HAL_Delay(50);
if (block_write_count && !block_read_count)
comm_start(COMMAND_FDS_WRITE_DONE, 0);
else
comm_start(COMMAND_FDS_READ_RESULT_END, 0);
}
comm_start(COMMAND_FDS_READ_RESULT_END, 0);
}

void get_mirroring()
660 changes: 330 additions & 330 deletions STM32/FamicomDumper.ioc

Large diffs are not rendered by default.

0 comments on commit ffcabaa

Please sign in to comment.