mirror of
https://github.com/Polprzewodnikowy/SummerCart64.git
synced 2024-11-25 15:16:53 +01:00
dd write works
This commit is contained in:
parent
0bb73dac1c
commit
099d0bc91c
@ -29,7 +29,12 @@ module cpu_dd (
|
||||
bus.rdata = 32'd0;
|
||||
if (bus.ack) begin
|
||||
if (bus.address[8] == M_SECTOR_BUFFER[8]) begin
|
||||
bus.rdata = dd.sector_rdata;
|
||||
bus.rdata = {
|
||||
dd.sector_rdata[7:0],
|
||||
dd.sector_rdata[15:8],
|
||||
dd.sector_rdata[23:16],
|
||||
dd.sector_rdata[31:24]
|
||||
};
|
||||
end else begin
|
||||
case (bus.address[5:2])
|
||||
R_SCR: bus.rdata = {
|
||||
|
@ -48,6 +48,8 @@ class SC64:
|
||||
__DEBUG_ID_FSD_SECTOR = 0xF3
|
||||
__DEBUG_ID_DD_BLOCK = 0xF5
|
||||
|
||||
__DD_USER_SECTORS_IN_BLOCK = 85
|
||||
|
||||
|
||||
def __init__(self) -> None:
|
||||
self.__serial = None
|
||||
@ -381,7 +383,8 @@ class SC64:
|
||||
self.__fsd_file.write(data)
|
||||
|
||||
|
||||
def __dd_track_offset(self, head_track: int) -> int:
|
||||
def __dd_track_offset(self, head_track: int, sector_size: int) -> int:
|
||||
# shamelessly stolen from MAME implementation, to be rewritten
|
||||
head = (head_track & 0x1000) >> 9
|
||||
track = head_track & 0xFFF
|
||||
dd_zone = 0
|
||||
@ -412,43 +415,52 @@ class SC64:
|
||||
dd_zone = 0 + head
|
||||
tr_off = track
|
||||
|
||||
ddStartOffset = [0x0,0x5F15E0,0xB79D00,0x10801A0,0x1523720,0x1963D80,0x1D414C0,0x20BBCE0,
|
||||
0x23196E0,0x28A1E00,0x2DF5DC0,0x3299340,0x36D99A0,0x3AB70E0,0x3E31900,0x4149200]
|
||||
ddZoneSecSize = [232,216,208,192,176,160,144,128,
|
||||
216,208,192,176,160,144,128,112]
|
||||
ddStartOffset = [
|
||||
0x0000000,
|
||||
0x05F15E0,
|
||||
0x0B79D00,
|
||||
0x10801A0,
|
||||
0x1523720,
|
||||
0x1963D80,
|
||||
0x1D414C0,
|
||||
0x20BBCE0,
|
||||
0x23196E0,
|
||||
0x28A1E00,
|
||||
0x2DF5DC0,
|
||||
0x3299340,
|
||||
0x36D99A0,
|
||||
0x3AB70E0,
|
||||
0x3E31900,
|
||||
0x4149200
|
||||
]
|
||||
|
||||
return (dd_zone, ddStartOffset[dd_zone] + tr_off * ddZoneSecSize[dd_zone] * 85 * 2)
|
||||
return ddStartOffset[dd_zone] + tr_off * sector_size * self.__DD_USER_SECTORS_IN_BLOCK * 2
|
||||
|
||||
|
||||
# def __dd_zone_track_size(self, i) -> int:
|
||||
# # ddZoneTrackSize = [158,158,149,149,149,149,149,114,158,158,149,149,149,149,149,114]
|
||||
# ddZoneSecSize = [232,216,208,192,176,160,144,128,
|
||||
# 216,208,192,176,160,144,128,112]
|
||||
# return ddZoneSecSize[i]
|
||||
def __dd_calculate_file_offset(self, head_track: int, starting_block: int, sector_size: int) -> int:
|
||||
offset = self.__dd_track_offset(head_track, sector_size)
|
||||
offset += starting_block * self.__DD_USER_SECTORS_IN_BLOCK * sector_size
|
||||
return offset
|
||||
|
||||
|
||||
def __debug_process_dd_block(self, data: bytes) -> None:
|
||||
# scr = int.from_bytes(data[0:4], byteorder='big')
|
||||
current_sector = int.from_bytes(data[4:8], byteorder='little')
|
||||
head_track = int.from_bytes(data[8:12], byteorder='little')
|
||||
sector_num = int.from_bytes(data[12:16], byteorder='little')
|
||||
sector_size = int.from_bytes(data[16:20], byteorder='little')
|
||||
# sector_size_full = int.from_bytes(data[20:24], byteorder='little')
|
||||
# sectors_in_block = int.from_bytes(data[24:28], byteorder='little')
|
||||
# print(f"info: {hex(scr)}, {current_sector}, {head_track}, {sector_num}, {sector_size}, {sector_size_full}, {sectors_in_block}")
|
||||
transfer_mode = int.from_bytes(data[0:4], byteorder='little')
|
||||
head_track = int.from_bytes(data[4:6], byteorder='little')
|
||||
starting_block = int.from_bytes(data[6:7], byteorder='little')
|
||||
sector_size = int.from_bytes(data[7:8], byteorder='little')
|
||||
|
||||
if (self.__disk_file):
|
||||
(zone, track_offset) = self.__dd_track_offset(head_track)
|
||||
sector = 0
|
||||
sector += track_offset
|
||||
sector += (int(sector_num / 90) * 85 * (sector_size + 1)) # self.__dd_zone_track_size(zone)
|
||||
sector += ((current_sector) * (sector_size + 1))
|
||||
self.__disk_file.seek(sector)
|
||||
data_dd = self.__disk_file.read(0x100 * 85)
|
||||
if (current_sector == 0x00 or current_sector == 0x5A):
|
||||
print(f"getting sect {hex(sector)}, {hex(int.from_bytes(data_dd[0:4], byteorder='big'))}")
|
||||
self.__debug_write(self.__DEBUG_ID_DD_BLOCK, data_dd)
|
||||
file_offset = self.__dd_calculate_file_offset(head_track, starting_block, sector_size)
|
||||
self.__disk_file.seek(file_offset)
|
||||
if (transfer_mode):
|
||||
block_data = self.__disk_file.read(sector_size * self.__DD_USER_SECTORS_IN_BLOCK)
|
||||
self.__debug_write(self.__DEBUG_ID_DD_BLOCK, block_data)
|
||||
else:
|
||||
self.__debug_write(self.__DEBUG_ID_DD_BLOCK, bytes(0x100))
|
||||
block_data = self.__read_long(sector_size * self.__DD_USER_SECTORS_IN_BLOCK)
|
||||
self.__disk_file.write(block_data)
|
||||
else:
|
||||
if (transfer_mode):
|
||||
self.__debug_write(self.__DEBUG_ID_DD_BLOCK, bytes(4))
|
||||
|
||||
|
||||
def debug_loop(self, file: str = None, disk_file: str = None) -> None:
|
||||
|
@ -1,5 +1,4 @@
|
||||
#include "dd.h"
|
||||
#include "uart.h"
|
||||
#include "rtc.h"
|
||||
#include "usb.h"
|
||||
|
||||
@ -7,7 +6,10 @@
|
||||
#define DD_DRIVE_ID_RETAIL (0x0003)
|
||||
#define DD_DRIVE_ID_DEVELOPMENT (0x0004)
|
||||
#define DD_VERSION_RETAIL (0x0114)
|
||||
#define DD_TRACK_SEEK_TIME_TICKS (10000)
|
||||
#define DD_POWER_UP_DELAY_TICKS (320000000UL) // 3.2 s
|
||||
#define DD_TRACK_SEEK_TIME_TICKS (10000) // 0.1 ms
|
||||
#define DEFAULT_DD_BUFFER_OFFSET (0x03BD8000UL)
|
||||
#define USB_DEBUG_ID_DD_BLOCK (0xF5)
|
||||
|
||||
typedef enum {
|
||||
DD_CMD_SEEK_READ = 0x01,
|
||||
@ -44,6 +46,7 @@ struct process {
|
||||
enum state state;
|
||||
uint32_t track_seek_time;
|
||||
uint32_t next_seek_time;
|
||||
bool power_up_delay;
|
||||
bool deffered_cmd_ready;
|
||||
bool bm_running;
|
||||
bool transfer_mode;
|
||||
@ -52,37 +55,32 @@ struct process {
|
||||
uint8_t current_sector;
|
||||
bool is_dev_disk;
|
||||
rtc_time_t time;
|
||||
io32_t *buffer;
|
||||
};
|
||||
|
||||
static struct process p;
|
||||
|
||||
enum {
|
||||
READ_PHASE_IDLE,
|
||||
READ_PHASE_STARTED,
|
||||
READ_PHASE_WAIT,
|
||||
} read_phase = READ_PHASE_IDLE;
|
||||
|
||||
io32_t *sdram = (io32_t *) (SDRAM_BASE + (32 * 1024 * 1024));
|
||||
|
||||
static void dd_block_read (void) {
|
||||
read_phase = READ_PHASE_STARTED;
|
||||
|
||||
io32_t *dst = sdram;
|
||||
io32_t *dst = p.buffer;
|
||||
|
||||
const char *dma = "DMA@";
|
||||
const char *cmp = "CMPH";
|
||||
|
||||
if (usb_debug_tx_ready()) {
|
||||
*dst++ = *((uint32_t *) (dma));
|
||||
*dst++ = 0xF5 | (7 * 4) << 24;
|
||||
*dst++ = (uint32_t) DD->SCR;
|
||||
*dst++ = (uint32_t) p.current_sector;
|
||||
*dst++ = (uint32_t) DD->HEAD_TRACK;
|
||||
*dst++ = p.starting_block ? (DD->SECTORS_IN_BLOCK + 1) : 0;
|
||||
*dst++ = (uint32_t) DD->SECTOR_SIZE;
|
||||
*dst++ = (uint32_t) DD->SECTOR_SIZE_FULL;
|
||||
*dst++ = (uint32_t) DD->SECTORS_IN_BLOCK;
|
||||
*dst++ = (((2 * 4) << 24) | USB_DEBUG_ID_DD_BLOCK);
|
||||
*dst++ = p.transfer_mode;
|
||||
*dst++ = (((DD->SECTOR_SIZE + 1) << 24) | (p.starting_block << 16) | DD->HEAD_TRACK);
|
||||
*dst++ = *((uint32_t *) (cmp));
|
||||
usb_debug_tx_data((uint32_t) (sdram), 10 * 4);
|
||||
}
|
||||
|
||||
usb_debug_tx_data((uint32_t) (p.buffer), (5 * 4));
|
||||
}
|
||||
|
||||
static bool dd_block_read_done (void) {
|
||||
@ -91,7 +89,7 @@ static bool dd_block_read_done (void) {
|
||||
|
||||
if (read_phase == READ_PHASE_STARTED) {
|
||||
if (usb_debug_rx_ready(&type, &length)) {
|
||||
usb_debug_rx_data((uint32_t) (sdram), length);
|
||||
usb_debug_rx_data((uint32_t) (p.buffer), length);
|
||||
read_phase = READ_PHASE_WAIT;
|
||||
}
|
||||
return false;
|
||||
@ -107,39 +105,64 @@ static bool dd_block_read_done (void) {
|
||||
}
|
||||
|
||||
static void dd_sector_read (void) {
|
||||
io32_t *buf = DD->SEC_BUF;
|
||||
io32_t *dst = sdram;
|
||||
uint8_t sector_size = DD->SECTOR_SIZE + 1;
|
||||
io32_t *src = p.buffer;
|
||||
io32_t *dst = DD->SECTOR_BUFFER;
|
||||
|
||||
dst += ((sector_size * p.current_sector) / sizeof(io32_t));
|
||||
for (int i = 0; i < 0x100; i += 4) {
|
||||
*buf++ = *dst++;
|
||||
uint8_t sector_size = ((DD->SECTOR_SIZE + 1) / sizeof(io32_t));
|
||||
|
||||
src += (sector_size * p.current_sector);
|
||||
|
||||
for (int i = 0; i < sector_size; i++) {
|
||||
*dst++ = *src++;
|
||||
}
|
||||
}
|
||||
|
||||
static void dd_sector_write (void) {
|
||||
io32_t *src = DD->SECTOR_BUFFER;
|
||||
io32_t *dst = p.buffer + 4;
|
||||
|
||||
uint8_t sector_size = ((DD->SECTOR_SIZE + 1) / sizeof(io32_t));
|
||||
|
||||
dst += (sector_size * p.current_sector);
|
||||
|
||||
for (int i = 0; i < sector_size; i++) {
|
||||
*dst++ = *src++;
|
||||
}
|
||||
}
|
||||
|
||||
static void dd_block_write (void) {
|
||||
uart_print("Requesting block write 0x");
|
||||
uart_print_08hex(DD->HEAD_TRACK & DD_HEAD_TRACK_MASK);
|
||||
uart_print("\r\n");
|
||||
io32_t *dst = p.buffer;
|
||||
|
||||
const char *dma = "DMA@";
|
||||
const char *cmp = "CMPH";
|
||||
|
||||
uint32_t block_length = ((DD->SECTOR_SIZE + 1) * 85);
|
||||
|
||||
*dst++ = *((uint32_t *) (dma));
|
||||
*dst++ = (((2 * 4) << 24) | USB_DEBUG_ID_DD_BLOCK);
|
||||
*dst++ = p.transfer_mode;
|
||||
*dst++ = (((DD->SECTOR_SIZE + 1) << 24) | (p.starting_block << 16) | DD->HEAD_TRACK);
|
||||
dst += block_length / 4;
|
||||
*dst++ = *((uint32_t *) (cmp));
|
||||
usb_debug_tx_data((uint32_t) (p.buffer), ((5 * 4) + block_length));
|
||||
}
|
||||
|
||||
static bool dd_block_write_done (void) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static void dd_sector_write (void) {
|
||||
return usb_debug_tx_ready();
|
||||
}
|
||||
|
||||
|
||||
void dd_init (void) {
|
||||
DD->SCR = 0;
|
||||
DD->SCR = DD_SCR_DISK_INSERTED;
|
||||
DD->HEAD_TRACK = 0;
|
||||
DD->DRIVE_ID = DD_DRIVE_ID_RETAIL;
|
||||
p.state = STATE_IDLE;
|
||||
p.track_seek_time = DD_TRACK_SEEK_TIME_TICKS;
|
||||
p.power_up_delay = true;
|
||||
p.deffered_cmd_ready = false;
|
||||
p.bm_running = false;
|
||||
p.is_dev_disk = false;
|
||||
p.buffer = (io32_t *) (SDRAM_BASE + DEFAULT_DD_BUFFER_OFFSET);
|
||||
}
|
||||
|
||||
|
||||
@ -148,7 +171,9 @@ void process_dd (void) {
|
||||
|
||||
if (scr & DD_SCR_HARD_RESET) {
|
||||
DD->SCR &= ~(DD_SCR_DISK_CHANGED);
|
||||
DD->HEAD_TRACK = 0;
|
||||
p.state = STATE_IDLE;
|
||||
p.power_up_delay = true;
|
||||
p.deffered_cmd_ready = false;
|
||||
p.bm_running = false;
|
||||
}
|
||||
@ -167,7 +192,12 @@ void process_dd (void) {
|
||||
}
|
||||
} else if ((cmd == DD_CMD_SEEK_READ) || (cmd == DD_CMD_SEEK_WRITE)) {
|
||||
int track_distance = abs((DD->HEAD_TRACK & DD_TRACK_MASK) - (data & DD_TRACK_MASK));
|
||||
p.next_seek_time = track_distance * p.track_seek_time;
|
||||
if (p.power_up_delay) {
|
||||
p.power_up_delay = false;
|
||||
p.next_seek_time += DD_POWER_UP_DELAY_TICKS;
|
||||
} else {
|
||||
p.next_seek_time = (track_distance * p.track_seek_time);
|
||||
}
|
||||
p.deffered_cmd_ready = true;
|
||||
DD->HEAD_TRACK &= ~(DD_HEAD_TRACK_INDEX_LOCK);
|
||||
DD->SCR |= DD_SCR_SEEK_TIMER_RESET;
|
||||
|
@ -8,9 +8,6 @@
|
||||
#include <stdbool.h>
|
||||
|
||||
|
||||
#define CPU_FREQ (100000000UL)
|
||||
|
||||
|
||||
typedef volatile uint8_t io8_t;
|
||||
typedef volatile uint16_t io16_t;
|
||||
typedef volatile uint32_t io32_t;
|
||||
@ -209,7 +206,7 @@ typedef volatile struct dd_regs {
|
||||
io16_t __padding_3;
|
||||
io32_t SEEK_TIMER;
|
||||
io32_t __padding_4[58];
|
||||
io32_t SEC_BUF[64];
|
||||
io32_t SECTOR_BUFFER[64];
|
||||
} dd_regs_t;
|
||||
|
||||
#define DD_BASE (0xB0000000UL)
|
||||
|
Loading…
Reference in New Issue
Block a user