mirror of
https://github.com/Polprzewodnikowy/SummerCart64.git
synced 2024-12-27 05:21:55 +01:00
64dd from sd card working
This commit is contained in:
parent
60592dca3a
commit
f701df4fbb
@ -34,7 +34,7 @@
|
||||
/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define FF_USE_FASTSEEK 1
|
||||
#define FF_USE_FASTSEEK 0
|
||||
/* This option switches fast seek function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
@ -224,7 +224,7 @@
|
||||
/ System Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FF_FS_TINY 0
|
||||
#define FF_FS_TINY 1
|
||||
/* This option switches tiny buffer configuration. (0:Normal or 1:Tiny)
|
||||
/ At the tiny configuration, size of file object (FIL) is shrinked FF_MAX_SS bytes.
|
||||
/ Instead of private sector buffer eliminated from the file object, common sector
|
||||
|
@ -19,6 +19,7 @@ typedef enum {
|
||||
SC64_CMD_SD_SECTOR_SET = 'I',
|
||||
SC64_CMD_SD_WRITE = 'S',
|
||||
SC64_CMD_SD_READ = 's',
|
||||
SC64_CMD_DD_SD_DISK_INFO = 'D',
|
||||
} cmd_id_t;
|
||||
|
||||
typedef enum {
|
||||
@ -199,3 +200,11 @@ bool sc64_sd_read_sectors (uint32_t *address, uint32_t sector, uint32_t count) {
|
||||
}
|
||||
return sc64_execute_cmd(SC64_CMD_SD_READ, read_args, NULL);
|
||||
}
|
||||
|
||||
bool sc64_dd_set_sd_disk_info (uint32_t *address, uint32_t count) {
|
||||
uint32_t args[2] = { (uint32_t) (address), count };
|
||||
if (sc64_execute_cmd(SC64_CMD_DD_SD_DISK_INFO, args, NULL)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -29,6 +29,8 @@ typedef enum {
|
||||
CFG_ID_DD_DISK_STATE,
|
||||
CFG_ID_BUTTON_STATE,
|
||||
CFG_ID_BUTTON_MODE,
|
||||
CFG_ID_ROM_EXTENDED_ENABLE,
|
||||
CFG_ID_DD_SD_MODE,
|
||||
} cfg_id_t;
|
||||
|
||||
typedef enum {
|
||||
@ -109,6 +111,7 @@ bool sc64_sd_card_get_status (void);
|
||||
bool sc64_sd_card_get_info (uint32_t *address);
|
||||
bool sc64_sd_write_sectors (uint32_t *address, uint32_t sector, uint32_t count);
|
||||
bool sc64_sd_read_sectors (uint32_t *address, uint32_t sector, uint32_t count);
|
||||
bool sc64_dd_set_sd_disk_info (uint32_t *address, uint32_t count);
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -13,6 +13,8 @@ bool test_check (void) {
|
||||
}
|
||||
|
||||
void test_execute (void) {
|
||||
uint8_t card_info[32] __attribute__((aligned(8)));
|
||||
|
||||
display_init(NULL);
|
||||
|
||||
display_printf("SC64 Test suite\n\n");
|
||||
@ -27,18 +29,25 @@ void test_execute (void) {
|
||||
while (1);
|
||||
}
|
||||
|
||||
uint8_t card_info[32] __attribute__((aligned(8)));
|
||||
|
||||
pi_dma_read((io32_t *) (SC64_BUFFERS->BUFFER), card_info, sizeof(card_info));
|
||||
|
||||
display_printf("CSD: 0x");
|
||||
display_printf("SD Card registers:\n CSD: 0x");
|
||||
for (int i = 0; i < 16; i++) {
|
||||
display_printf("%02X", card_info[i]);
|
||||
}
|
||||
display_printf("\nCID: 0x");
|
||||
display_printf("\n CID: 0x");
|
||||
for (int i = 16; i < 32; i++) {
|
||||
display_printf("%02X", card_info[i]);
|
||||
}
|
||||
display_printf("\n ");
|
||||
for (int i = 16; i < 32; i++) {
|
||||
display_printf("%c ", card_info[i] >= ' ' ? card_info[i] : 0xFF);
|
||||
}
|
||||
|
||||
if (sc64_sd_card_deinit()) {
|
||||
display_printf("SD card deinit error!\n");
|
||||
while (1);
|
||||
}
|
||||
|
||||
while (1);
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include <stdint.h>
|
||||
#include "button.h"
|
||||
#include "dd.h"
|
||||
#include "fpga.h"
|
||||
#include "usb.h"
|
||||
|
||||
@ -66,7 +67,7 @@ void button_process (void) {
|
||||
break;
|
||||
|
||||
case BUTTON_MODE_DD_DISK_SWAP:
|
||||
// TODO: implement 64DD disk swapping
|
||||
dd_handle_button();
|
||||
p.trigger = false;
|
||||
break;
|
||||
|
||||
|
@ -25,6 +25,7 @@ typedef enum {
|
||||
CFG_ID_BUTTON_STATE,
|
||||
CFG_ID_BUTTON_MODE,
|
||||
CFG_ID_ROM_EXTENDED_ENABLE,
|
||||
CFG_ID_DD_SD_MODE,
|
||||
} cfg_id_t;
|
||||
|
||||
typedef enum {
|
||||
@ -106,6 +107,12 @@ static bool cfg_translate_address (uint32_t *address, uint32_t length, bool with
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (*address >= 0x1FFE2000 && *address < 0x1FFE2800) {
|
||||
if ((*address + length) <= 0x1FFE2800) {
|
||||
*address = *address - 0x1FFE2000 + 0x05002000;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -220,6 +227,9 @@ bool cfg_query (uint32_t *args) {
|
||||
case CFG_ID_ROM_EXTENDED_ENABLE:
|
||||
args[1] = (scr & CFG_SCR_ROM_EXTENDED_ENABLED);
|
||||
break;
|
||||
case CFG_ID_DD_SD_MODE:
|
||||
args[1] = dd_get_sd_mode();
|
||||
break;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
@ -285,6 +295,9 @@ bool cfg_update (uint32_t *args) {
|
||||
case CFG_ID_ROM_EXTENDED_ENABLE:
|
||||
cfg_change_scr_bits(CFG_SCR_ROM_EXTENDED_ENABLED, args[1]);
|
||||
break;
|
||||
case CFG_ID_DD_SD_MODE:
|
||||
dd_set_sd_mode(args[1]);
|
||||
break;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
@ -457,6 +470,14 @@ void cfg_process (void) {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'D':
|
||||
if (cfg_translate_address(&args[0], args[1], false)) {
|
||||
cfg_set_error(CFG_ERROR_BAD_ADDRESS);
|
||||
return;
|
||||
}
|
||||
dd_set_sd_disk_info(args[0], args[1]);
|
||||
break;
|
||||
|
||||
default:
|
||||
cfg_set_error(CFG_ERROR_UNKNOWN_CMD);
|
||||
|
@ -3,13 +3,17 @@
|
||||
#include "fpga.h"
|
||||
#include "hw.h"
|
||||
#include "rtc.h"
|
||||
#include "sd.h"
|
||||
#include "usb.h"
|
||||
|
||||
|
||||
#define DD_SECTOR_MAX_SIZE (232)
|
||||
#define DD_BLOCK_DATA_SECTORS_NUM (85)
|
||||
#define DD_BLOCK_BUFFER_ADDRESS (0x03BC0000UL - (DD_SECTOR_MAX_SIZE * DD_BLOCK_DATA_SECTORS_NUM))
|
||||
#define DD_BLOCK_BUFFER_SIZE (ALIGN(DD_SECTOR_MAX_SIZE * DD_BLOCK_DATA_SECTORS_NUM, SD_SECTOR_SIZE) + SD_SECTOR_SIZE)
|
||||
#define DD_BLOCK_BUFFER_ADDRESS (0x03BC0000UL - DD_BLOCK_BUFFER_SIZE)
|
||||
#define DD_SECTOR_BUFFER_ADDRESS (0x05002800UL)
|
||||
#define DD_SD_SECTOR_TABLE_SIZE (DD_BLOCK_BUFFER_SIZE / SD_SECTOR_SIZE)
|
||||
#define DD_SD_MAX_DISKS (4)
|
||||
|
||||
#define DD_DRIVE_ID_RETAIL (0x0003)
|
||||
#define DD_DRIVE_ID_DEVELOPMENT (0x0004)
|
||||
@ -47,8 +51,7 @@ enum state {
|
||||
STATE_NEXT_BLOCK,
|
||||
};
|
||||
|
||||
|
||||
typedef union sector_info {
|
||||
typedef union {
|
||||
uint32_t full;
|
||||
struct {
|
||||
uint8_t sector_num;
|
||||
@ -58,6 +61,11 @@ typedef union sector_info {
|
||||
};
|
||||
} sector_info_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t thb_table_address;
|
||||
uint32_t sector_table_address;
|
||||
} sd_disk_info_t;
|
||||
|
||||
struct process {
|
||||
enum state state;
|
||||
rtc_time_t time;
|
||||
@ -73,7 +81,12 @@ struct process {
|
||||
sector_info_t sector_info;
|
||||
bool block_ready;
|
||||
bool block_valid;
|
||||
uint32_t block_offset;
|
||||
dd_drive_type_t drive_type;
|
||||
bool sd_mode;
|
||||
uint8_t sd_current_disk;
|
||||
sd_disk_info_t sd_disk_info[DD_SD_MAX_DISKS];
|
||||
uint32_t sd_sector_table[DD_SD_SECTOR_TABLE_SIZE];
|
||||
};
|
||||
|
||||
|
||||
@ -87,28 +100,88 @@ static uint16_t dd_track_head_block (void) {
|
||||
return (track | head | block);
|
||||
}
|
||||
|
||||
static uint32_t dd_fill_sd_sector_table (uint32_t index) {
|
||||
uint32_t tmp;
|
||||
sd_disk_info_t info = p.sd_disk_info[p.sd_current_disk];
|
||||
uint32_t thb_entry_address = (info.thb_table_address + (index * sizeof(uint32_t)));
|
||||
fpga_mem_read(thb_entry_address, sizeof(uint32_t), (uint8_t *) (&tmp));
|
||||
uint32_t start_offset = SWAP32(tmp);
|
||||
if (start_offset == 0xFFFFFFFF) {
|
||||
return 0;
|
||||
}
|
||||
p.block_offset = (start_offset % SD_SECTOR_SIZE);
|
||||
uint32_t block_length = ((p.sector_info.sector_size + 1) * DD_BLOCK_DATA_SECTORS_NUM);
|
||||
uint32_t end_offset = ((start_offset + block_length) - 1); // CHECK THIS
|
||||
uint32_t starting_sector = (start_offset / SD_SECTOR_SIZE);
|
||||
uint32_t sectors = (1 + ((end_offset / SD_SECTOR_SIZE) - starting_sector));
|
||||
for (int i = 0; i < sectors; i++) {
|
||||
uint32_t sector_entry_address = info.sector_table_address + ((starting_sector + i) * sizeof(uint32_t));
|
||||
fpga_mem_read(sector_entry_address, sizeof(uint32_t), (uint8_t *) (&tmp));
|
||||
p.sd_sector_table[i] = SWAP32(tmp);
|
||||
}
|
||||
return sectors;
|
||||
}
|
||||
|
||||
static bool dd_block_read_request (void) {
|
||||
usb_tx_info_t packet_info;
|
||||
usb_create_packet(&packet_info, PACKET_CMD_DD_REQUEST);
|
||||
packet_info.data_length = 12;
|
||||
packet_info.data[0] = 1;
|
||||
packet_info.data[1] = DD_BLOCK_BUFFER_ADDRESS;
|
||||
packet_info.data[2] = dd_track_head_block();
|
||||
p.block_ready = false;
|
||||
return usb_enqueue_packet(&packet_info);
|
||||
uint16_t index = dd_track_head_block();
|
||||
uint32_t buffer_address = DD_BLOCK_BUFFER_ADDRESS;
|
||||
|
||||
if (p.sd_mode) {
|
||||
dd_set_block_ready(false);
|
||||
uint32_t sectors = dd_fill_sd_sector_table(index);
|
||||
if (sectors > 0) {
|
||||
for (int i = 0; i < sectors; i++) {
|
||||
if (sd_read_sectors(buffer_address, p.sd_sector_table[i], 1)) {
|
||||
return true;
|
||||
}
|
||||
buffer_address += SD_SECTOR_SIZE;
|
||||
}
|
||||
dd_set_block_ready(true);
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
usb_tx_info_t packet_info;
|
||||
usb_create_packet(&packet_info, PACKET_CMD_DD_REQUEST);
|
||||
packet_info.data_length = 12;
|
||||
packet_info.data[0] = 1;
|
||||
packet_info.data[1] = buffer_address;
|
||||
packet_info.data[2] = index;
|
||||
p.block_ready = false;
|
||||
p.block_offset = 0;
|
||||
return usb_enqueue_packet(&packet_info);
|
||||
}
|
||||
}
|
||||
|
||||
static bool dd_block_write_request (void) {
|
||||
usb_tx_info_t packet_info;
|
||||
usb_create_packet(&packet_info, PACKET_CMD_DD_REQUEST);
|
||||
packet_info.data_length = 12;
|
||||
packet_info.data[0] = 2;
|
||||
packet_info.data[1] = DD_BLOCK_BUFFER_ADDRESS;
|
||||
packet_info.data[2] = dd_track_head_block();
|
||||
packet_info.dma_length = (p.sector_info.sector_size + 1) * DD_BLOCK_DATA_SECTORS_NUM;
|
||||
packet_info.dma_address = DD_BLOCK_BUFFER_ADDRESS;
|
||||
p.block_ready = false;
|
||||
return usb_enqueue_packet(&packet_info);
|
||||
uint32_t index = dd_track_head_block();
|
||||
uint32_t buffer_address = DD_BLOCK_BUFFER_ADDRESS;
|
||||
|
||||
if (p.sd_mode) {
|
||||
dd_set_block_ready(false);
|
||||
uint32_t sectors = dd_fill_sd_sector_table(index);
|
||||
if (sectors > 0) {
|
||||
for (int i = 0; i < sectors; i++) {
|
||||
if (sd_write_sectors(buffer_address, p.sd_sector_table[i], 1)) {
|
||||
return true;
|
||||
}
|
||||
buffer_address += SD_SECTOR_SIZE;
|
||||
}
|
||||
dd_set_block_ready(true);
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
usb_tx_info_t packet_info;
|
||||
usb_create_packet(&packet_info, PACKET_CMD_DD_REQUEST);
|
||||
packet_info.data_length = 12;
|
||||
packet_info.data[0] = 2;
|
||||
packet_info.data[1] = buffer_address;
|
||||
packet_info.data[2] = index;
|
||||
packet_info.dma_length = (p.sector_info.sector_size + 1) * DD_BLOCK_DATA_SECTORS_NUM;
|
||||
packet_info.dma_address = buffer_address;
|
||||
p.block_ready = false;
|
||||
p.block_offset = 0;
|
||||
return usb_enqueue_packet(&packet_info);
|
||||
}
|
||||
}
|
||||
|
||||
static void dd_set_cmd_response_ready (void) {
|
||||
@ -168,6 +241,29 @@ void dd_set_disk_state (dd_disk_state_t state) {
|
||||
fpga_reg_set(REG_DD_SCR, scr);
|
||||
}
|
||||
|
||||
bool dd_get_sd_mode (void) {
|
||||
return p.sd_mode;
|
||||
}
|
||||
|
||||
void dd_set_sd_mode (bool value) {
|
||||
p.sd_mode = value;
|
||||
}
|
||||
|
||||
void dd_set_sd_disk_info (uint32_t address, uint32_t length) {
|
||||
uint32_t tmp[2];
|
||||
p.sd_current_disk = 0;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
fpga_mem_read(address, sizeof(tmp), (uint8_t *) (tmp));
|
||||
p.sd_disk_info[i].thb_table_address = SWAP32(tmp[0]);
|
||||
p.sd_disk_info[i].sector_table_address = SWAP32(tmp[1]);
|
||||
address += sizeof(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
void dd_handle_button (void) {
|
||||
// TODO: disk swap
|
||||
}
|
||||
|
||||
void dd_init (void) {
|
||||
fpga_reg_set(REG_DD_SCR, 0);
|
||||
fpga_reg_set(REG_DD_HEAD_TRACK, 0);
|
||||
@ -178,6 +274,8 @@ void dd_init (void) {
|
||||
p.disk_spinning = false;
|
||||
p.bm_running = false;
|
||||
p.drive_type = DD_DRIVE_TYPE_RETAIL;
|
||||
p.sd_mode = false;
|
||||
p.sd_current_disk = 0;
|
||||
}
|
||||
|
||||
void dd_process (void) {
|
||||
@ -365,7 +463,7 @@ void dd_process (void) {
|
||||
|
||||
case STATE_SECTOR_READ:
|
||||
fpga_mem_copy(
|
||||
DD_BLOCK_BUFFER_ADDRESS + (p.current_sector * (p.sector_info.sector_size + 1)),
|
||||
DD_BLOCK_BUFFER_ADDRESS + p.block_offset + (p.current_sector * (p.sector_info.sector_size + 1)),
|
||||
DD_SECTOR_BUFFER_ADDRESS,
|
||||
p.sector_info.sector_size + 1
|
||||
);
|
||||
@ -377,7 +475,7 @@ void dd_process (void) {
|
||||
case STATE_SECTOR_WRITE:
|
||||
fpga_mem_copy(
|
||||
DD_SECTOR_BUFFER_ADDRESS,
|
||||
DD_BLOCK_BUFFER_ADDRESS + (p.current_sector * (p.sector_info.sector_size + 1)),
|
||||
DD_BLOCK_BUFFER_ADDRESS + p.block_offset + (p.current_sector * (p.sector_info.sector_size + 1)),
|
||||
p.sector_info.sector_size + 1
|
||||
);
|
||||
p.current_sector += 1;
|
||||
|
@ -17,11 +17,15 @@ typedef enum {
|
||||
} dd_disk_state_t;
|
||||
|
||||
|
||||
void dd_set_block_ready (bool valid);
|
||||
dd_drive_type_t dd_get_drive_type (void);
|
||||
void dd_set_drive_type (dd_drive_type_t type);
|
||||
dd_disk_state_t dd_get_disk_state (void);
|
||||
void dd_set_disk_state (dd_disk_state_t state);
|
||||
void dd_set_block_ready (bool valid);
|
||||
bool dd_get_sd_mode (void);
|
||||
void dd_set_sd_mode (bool value);
|
||||
void dd_set_sd_disk_info (uint32_t address, uint32_t length);
|
||||
void dd_handle_button (void);
|
||||
void dd_init (void);
|
||||
void dd_process (void);
|
||||
|
||||
|
@ -55,6 +55,7 @@ typedef enum {
|
||||
} fpga_reg_t;
|
||||
|
||||
|
||||
#define ALIGN(value, align) (((value) + ((typeof(value))(align) - 1)) & ~((typeof(value))(align) - 1))
|
||||
#define SWAP16(x) ((((x) & 0xFF) << 8) | (((x) & 0xFF00) >> 8))
|
||||
#define SWAP32(x) (((x) & 0xFF) << 24 | ((x) & 0xFF00) << 8 | ((x) & 0xFF0000) >> 8 | ((x) & 0xFF000000) >> 24)
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
#include "sd.h"
|
||||
|
||||
|
||||
#define SD_BUFFER_ADDRESS (0x05000000UL)
|
||||
#define SD_INIT_BUFFER_ADDRESS (0x05002800UL)
|
||||
|
||||
#define CMD6_ARG_CHECK_HS (0x00FFFFF1UL)
|
||||
#define CMD6_ARG_SWITCH_HS (0x80FFFFF1UL)
|
||||
@ -28,7 +28,10 @@
|
||||
#define R7_SUPPLY_VOLTAGE_27_36_V (1 << 8)
|
||||
#define R7_CHECK_PATTERN (0xAA << 0)
|
||||
|
||||
#define SD_BLOCK_SIZE (512)
|
||||
#define SWITCH_FUNCTION_CURRENT_LIMIT (SD_INIT_BUFFER_ADDRESS + 0)
|
||||
#define SWITCH_FUNCTION_GROUP_1 (SD_INIT_BUFFER_ADDRESS + 12)
|
||||
#define SWITCH_FUNCTION_GROUP_1_HS (1 << 1)
|
||||
|
||||
#define DAT_BLOCK_MAX_COUNT (256)
|
||||
|
||||
|
||||
@ -166,7 +169,7 @@ static bool sd_acmd (uint8_t acmd, uint32_t arg, rsp_type_t rsp_type, void *rsp)
|
||||
}
|
||||
|
||||
static void sd_dat_prepare (uint32_t address, uint32_t count, dat_mode_t mode) {
|
||||
uint32_t length = (count * SD_BLOCK_SIZE);
|
||||
uint32_t length = (count * SD_SECTOR_SIZE);
|
||||
uint32_t sd_dat = (((count - 1) << SD_DAT_BLOCKS_BIT) | SD_DAT_FIFO_FLUSH);
|
||||
uint32_t sd_dma_scr = DMA_SCR_START;
|
||||
|
||||
@ -209,7 +212,7 @@ static bool sd_dat_wait (uint16_t timeout) {
|
||||
bool sd_card_init (void) {
|
||||
uint32_t arg;
|
||||
uint32_t rsp;
|
||||
uint16_t sd_function;
|
||||
uint16_t tmp;
|
||||
|
||||
if (p.card_initialized) {
|
||||
return false;
|
||||
@ -289,7 +292,7 @@ bool sd_card_init (void) {
|
||||
return true;
|
||||
}
|
||||
|
||||
sd_dat_prepare(SD_BUFFER_ADDRESS, 1, DAT_READ);
|
||||
sd_dat_prepare(SD_INIT_BUFFER_ADDRESS, 1, DAT_READ);
|
||||
if (sd_cmd(6, CMD6_ARG_CHECK_HS, RSP_R1, NULL)) {
|
||||
sd_dat_abort();
|
||||
sd_card_deinit();
|
||||
@ -300,9 +303,14 @@ bool sd_card_init (void) {
|
||||
sd_card_deinit();
|
||||
return true;
|
||||
}
|
||||
fpga_mem_read(SD_BUFFER_ADDRESS + 12, 2, (uint8_t *) (&sd_function));
|
||||
if (SWAP16(sd_function) & (1 << 1)) {
|
||||
sd_dat_prepare(SD_BUFFER_ADDRESS, 1, DAT_READ);
|
||||
fpga_mem_read(SWITCH_FUNCTION_CURRENT_LIMIT, 2, (uint8_t *) (&tmp));
|
||||
if (SWAP16(tmp) == 0) {
|
||||
sd_card_deinit();
|
||||
return true;
|
||||
}
|
||||
fpga_mem_read(SWITCH_FUNCTION_GROUP_1, 2, (uint8_t *) (&tmp));
|
||||
if (SWAP16(tmp) & SWITCH_FUNCTION_GROUP_1_HS) {
|
||||
sd_dat_prepare(SD_INIT_BUFFER_ADDRESS, 1, DAT_READ);
|
||||
if (sd_cmd(6, CMD6_ARG_SWITCH_HS, RSP_R1, NULL)) {
|
||||
sd_dat_abort();
|
||||
sd_card_deinit();
|
||||
@ -313,8 +321,8 @@ bool sd_card_init (void) {
|
||||
sd_card_deinit();
|
||||
return true;
|
||||
}
|
||||
fpga_mem_read(SD_BUFFER_ADDRESS + 12, 2, (uint8_t *) (&sd_function));
|
||||
if (SWAP16(sd_function) & (1 << 1)) {
|
||||
fpga_mem_read(SWITCH_FUNCTION_GROUP_1, 2, (uint8_t *) (&tmp));
|
||||
if (SWAP16(tmp) & SWITCH_FUNCTION_GROUP_1_HS) {
|
||||
sd_set_clock(CLOCK_50MHZ);
|
||||
}
|
||||
}
|
||||
@ -352,7 +360,7 @@ bool sd_write_sectors (uint32_t address, uint32_t sector, uint32_t count) {
|
||||
}
|
||||
|
||||
if (!p.card_type_block) {
|
||||
sector *= SD_BLOCK_SIZE;
|
||||
sector *= SD_SECTOR_SIZE;
|
||||
}
|
||||
|
||||
while (count > 0) {
|
||||
@ -365,14 +373,14 @@ bool sd_write_sectors (uint32_t address, uint32_t sector, uint32_t count) {
|
||||
return true;
|
||||
}
|
||||
sd_dat_prepare(address, blocks, DAT_WRITE);
|
||||
bool error = sd_dat_wait(1000);
|
||||
sd_cmd(12, 0, RSP_R1b, NULL);
|
||||
if (error) {
|
||||
if (sd_dat_wait(1000)) {
|
||||
sd_dat_abort();
|
||||
sd_cmd(12, 0, RSP_R1b, NULL);
|
||||
return true;
|
||||
}
|
||||
address += (blocks * SD_BLOCK_SIZE);
|
||||
sector += (blocks * (p.card_type_block ? 1 : SD_BLOCK_SIZE));
|
||||
sd_cmd(12, 0, RSP_R1b, NULL);
|
||||
address += (blocks * SD_SECTOR_SIZE);
|
||||
sector += (blocks * (p.card_type_block ? 1 : SD_SECTOR_SIZE));
|
||||
count -= blocks;
|
||||
}
|
||||
|
||||
@ -385,7 +393,7 @@ bool sd_read_sectors (uint32_t address, uint32_t sector, uint32_t count) {
|
||||
}
|
||||
|
||||
if (!p.card_type_block) {
|
||||
sector *= SD_BLOCK_SIZE;
|
||||
sector *= SD_SECTOR_SIZE;
|
||||
}
|
||||
|
||||
while (count > 0) {
|
||||
@ -406,8 +414,8 @@ bool sd_read_sectors (uint32_t address, uint32_t sector, uint32_t count) {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
address += (blocks * SD_BLOCK_SIZE);
|
||||
sector += (blocks * (p.card_type_block ? 1 : SD_BLOCK_SIZE));
|
||||
address += (blocks * SD_SECTOR_SIZE);
|
||||
sector += (blocks * (p.card_type_block ? 1 : SD_SECTOR_SIZE));
|
||||
count -= blocks;
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,9 @@
|
||||
#include <stdbool.h>
|
||||
|
||||
|
||||
#define SD_SECTOR_SIZE (512)
|
||||
|
||||
|
||||
bool sd_card_init (void);
|
||||
void sd_card_deinit (void);
|
||||
bool sd_card_get_status (void);
|
||||
|
@ -185,6 +185,9 @@ class DD64Image:
|
||||
self.__file.close()
|
||||
self.__drive_type = None
|
||||
|
||||
def get_block_info_table(self) -> list[tuple[int, int]]:
|
||||
return self.__block_info_table
|
||||
|
||||
def get_drive_type(self) -> str:
|
||||
return self.__drive_type
|
||||
|
||||
@ -222,6 +225,12 @@ if __name__ == '__main__':
|
||||
print(dd.read_block(track, head, block)[:4])
|
||||
except BadBlockError:
|
||||
print(f'Bad ID block [track: {track}, head: {head}, block: {block}]')
|
||||
if (len(sys.argv) >= 3):
|
||||
with open(sys.argv[2], 'wb+') as f:
|
||||
block_info_table = dd.get_block_info_table()
|
||||
for block in block_info_table:
|
||||
offset = 0xFFFFFFFF if block == None else block[0]
|
||||
f.write(offset.to_bytes(4, byteorder='big'))
|
||||
dd.unload()
|
||||
else:
|
||||
print(f'[{sys.argv[0]}]: Expected disk image path as first argument')
|
||||
|
@ -238,6 +238,7 @@ class SC64:
|
||||
BUTTON_STATE = 12
|
||||
BUTTON_MODE = 13
|
||||
ROM_EXTENDED_ENABLE = 14
|
||||
DD_SD_MODE = 15
|
||||
|
||||
class __UpdateError(IntEnum):
|
||||
OK = 0
|
||||
@ -364,6 +365,7 @@ class SC64:
|
||||
self.__set_config(self.__CfgId.DD_DISK_STATE, self.__DDDiskState.EJECTED)
|
||||
self.__set_config(self.__CfgId.BUTTON_MODE, self.__ButtonMode.NONE)
|
||||
self.__set_config(self.__CfgId.ROM_EXTENDED_ENABLE, False)
|
||||
self.__set_config(self.__CfgId.DD_SD_MODE, False)
|
||||
self.set_cic_parameters()
|
||||
|
||||
def get_state(self):
|
||||
@ -383,6 +385,7 @@ class SC64:
|
||||
'button_state': bool(self.__get_config(self.__CfgId.BUTTON_STATE)),
|
||||
'button_mode': self.__ButtonMode(self.__get_config(self.__CfgId.BUTTON_MODE)),
|
||||
'rom_extended_enable': bool(self.__get_config(self.__CfgId.ROM_EXTENDED_ENABLE)),
|
||||
'dd_sd_mode': bool(self.__get_config(self.__CfgId.DD_SD_MODE)),
|
||||
}
|
||||
|
||||
def download_memory(self) -> bytes:
|
||||
@ -564,6 +567,7 @@ class SC64:
|
||||
break
|
||||
if (dd):
|
||||
self.__set_config(self.__CfgId.DD_MODE, self.__DDMode.FULL)
|
||||
self.__set_config(self.__CfgId.DD_SD_MODE, False)
|
||||
self.__set_config(self.__CfgId.DD_DRIVE_TYPE, {
|
||||
'retail': self.__DDDriveType.RETAIL,
|
||||
'development': self.__DDDriveType.DEVELOPMENT
|
||||
|
Loading…
Reference in New Issue
Block a user