This commit is contained in:
Polprzewodnikowy 2021-08-23 23:35:08 +02:00
parent b1826a9167
commit d550d9c184
37 changed files with 5 additions and 1056 deletions

8
.gitmodules vendored
View File

@ -1,8 +1,8 @@
[submodule "sw/cic"]
path = sw/cic
url = https://github.com/ManCloud/UltraCIC-III.git
ignore = dirty
[submodule "fw/picorv32"]
path = fw/picorv32
url = https://github.com/cliffordwolf/picorv32.git
ignore = dirty
[submodule "sw/cic"]
path = sw/cic
url = https://github.com/ManCloud/UltraCIC-III.git
ignore = dirty

View File

@ -304,5 +304,4 @@ set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top
# ------------------------
set_global_assignment -name QIP_FILE rtl/intel/gpio/intel_gpio_ddro.qip
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
set_global_assignment -name SLD_FILE db/stp_auto_stripped.stp
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top

View File

View File

View File

@ -1,17 +0,0 @@
#ifndef ERRORS_H__
#define ERRORS_H__
typedef enum menu_load_error_e {
E_MENU_OK,
E_MENU_ERROR_NOT_SC64,
E_MENU_ERROR_NO_CARD,
E_MENU_ERROR_NO_FILESYSTEM,
E_MENU_ERROR_NO_FILE,
E_MENU_ERROR_READ_ERROR,
E_MENU_ERROR_OTHER_ERROR,
E_MENU_END,
} menu_load_error_t;
#endif

View File

@ -1,2 +0,0 @@
/lib
/output

View File

@ -1,37 +0,0 @@
SRC_DIRS = src
INC_DIRS = inc
OUTPUT_DIR = lib
BUILD_DIR = output/$(LIB_BUILD_DIR)
SRC_FILES = boot.c control.c gpio.c helpers.c init.c io_dma.c save.c sd.c usb.c
CFLAGS += -ffunction-sections -fdata-sections -Os -Wall -MMD -MP $(patsubst %, -I%, $(INC_DIRS))
OBJS = $(addprefix $(BUILD_DIR)/, $(notdir $(SRC_FILES:.c=.o)))
DEPS = $(OBJS:.o=.d)
VPATH = $(SRC_DIRS)
all: create_build_dirs $(OUTPUT_DIR)/$(LIB_NAME).a
create_build_dirs: $(OUTPUT_DIR) $(BUILD_DIR)
$(OUTPUT_DIR):
mkdir -p ./$(OUTPUT_DIR)
$(BUILD_DIR):
mkdir -p ./$(BUILD_DIR)
$(BUILD_DIR)/%.o: %.c
$(COMPILE.c) $(OUTPUT_OPTION) $<
$(OUTPUT_DIR)/$(LIB_NAME).a: $(OBJS)
$(AR) -rcs -o $@ $(OBJS)
clean:
rm -rf ./$(BUILD_DIR) 2> /dev/null
rm -rf ./$(OUTPUT_DIR) 2> /dev/null
.PHONY: all clean create_build_dirs
-include $(DEPS)

View File

@ -1,11 +0,0 @@
TOOLCHAIN = $(N64_INST)/bin/mips64-elf-
CC = $(TOOLCHAIN)gcc
AR = $(TOOLCHAIN)ar
LIB_NAME = libsc64_libdragon
LIB_BUILD_DIR = libdragon
CFLAGS += -march=vr4300 -mtune=vr4300 -DLIBDRAGON
include Makefile.common

View File

@ -1,9 +0,0 @@
include $(ROOT)/usr/include/make/PRdefs
LIB_NAME = libsc64_libultra
LIB_BUILD_DIR = libultra
CFLAGS += -I$(ROOT)/usr/include/nustd -DLIBULTRA
include Makefile.common

View File

@ -1,11 +0,0 @@
#!/bin/bash
build_in_docker() {
docker run -t \
--mount type=bind,src=`realpath $(pwd)`,target="/src" \
$1 /bin/bash -c "cd /src && make -f $2 all"
}
build_in_docker "anacierdem/libdragon:6.0.2" "Makefile.libdragon"
build_in_docker "polprzewodnikowy/n64sdkmod:latest" "Makefile.libultra"

View File

@ -1,31 +0,0 @@
#ifndef SC64_BOOT_H__
#define SC64_BOOT_H__
#include <stdbool.h>
#include <stdint.h>
typedef union sc64_boot_config_s {
uint32_t _packed_value;
struct {
uint16_t _padding: 16;
bool skip_menu: 1;
bool cic_seed_override: 1;
bool tv_type_override: 1;
bool ddipl_override: 1;
bool rom_loaded: 1;
uint8_t tv_type: 2;
uint8_t os_version: 1;
uint8_t cic_seed: 8;
};
} sc64_boot_config_t;
void sc64_boot_config_set(sc64_boot_config_t *boot_config);
void sc64_boot_config_get(sc64_boot_config_t *boot_config);
void sc64_boot_skip_bootloader(bool is_enabled);
#endif

View File

@ -1,20 +0,0 @@
#ifndef SC64_CONTROL_H__
#define SC64_CONTROL_H__
#include <stdbool.h>
#include <stdint.h>
void sc64_control_sdram_writable(bool is_enabled);
void sc64_control_embedded_flash_access(bool is_enabled);
uint32_t sc64_control_version_get(void);
void sc64_control_ddipl_access(bool is_enabled);
void sc64_control_ddipl_address_set(uint32_t address);
uint32_t sc64_control_ddipl_address_get(void);
#endif

View File

@ -1,26 +0,0 @@
#ifndef SC64_GPIO_H__
#define SC64_GPIO_H__
#include <stdint.h>
typedef enum sc64_gpio_mode_e {
MODE_INPUT,
MODE_OUTPUT,
MODE_OPEN_DRAIN,
} sc64_gpio_mode_t;
void sc64_gpio_init(void);
void sc64_gpio_mode_set(uint8_t num, sc64_gpio_mode_t mode);
void sc64_gpio_output_write(uint8_t value);
void sc64_gpio_output_set(uint8_t mask);
void sc64_gpio_output_clear(uint8_t mask);
uint8_t sc64_gpio_input_get(void);
#endif

View File

@ -1,15 +0,0 @@
#ifndef SC64_HELPERS_H__
#define SC64_HELPERS_H__
#include <stdbool.h>
#include <stdint.h>
void sc64_helpers_reg_write(volatile uint32_t *pi_address, uint32_t mask, bool mask_mode);
void sc64_helpers_reg_set(volatile uint32_t *pi_address, uint32_t mask);
void sc64_helpers_reg_clear(volatile uint32_t *pi_address, uint32_t mask);
#endif

View File

@ -1,8 +0,0 @@
#ifndef SC64_INIT_H__
#define SC64_INIT_H__
void sc64_init(void);
#endif

View File

@ -1,18 +0,0 @@
#ifndef SC64_IO_DMA_H__
#define SC64_IO_DMA_H__
#include <stdint.h>
#include <stdlib.h>
void sc64_io_dma_init(void);
void sc64_io_write(volatile uint32_t *pi_address, uint32_t value);
uint32_t sc64_io_read(volatile uint32_t *pi_address);
void sc64_dma_write(void *ram_address, volatile uint32_t *pi_address, size_t length);
void sc64_dma_read(void *ram_address, volatile uint32_t *pi_address, size_t length);
#endif

View File

@ -1,15 +0,0 @@
#ifndef LIBSC64_H__
#define LIBSC64_H__
#include "boot.h"
#include "control.h"
#include "gpio.h"
#include "io_dma.h"
#include "init.h"
#include "save.h"
#include "sd.h"
#include "usb.h"
#endif

View File

@ -1,178 +0,0 @@
#ifndef SC64_REGISTERS_H__
#define SC64_REGISTERS_H__
#include <stdint.h>
// Bank definitions
#define SC64_BANK_SDRAM (1)
#define SC64_BANK_EEPROM (3)
// Cart Interface Registers
typedef struct sc64_cart_registers {
volatile uint32_t SCR; // Cart status and control
volatile uint32_t BOOT; // Boot behavior control
volatile uint32_t VERSION; // Cart firmware version
volatile uint32_t GPIO; // GPIO control
volatile uint32_t USB_SCR; // USB interface status and control
volatile uint32_t USB_DMA_ADDR; // USB address for DMA to PC
volatile uint32_t USB_DMA_LEN; // USB transfer length for DMA to PC
volatile uint32_t DDIPL_ADDR; // 64 Disk Drive IPL location in SDRAM
volatile uint32_t SAVE_ADDR; // SRAM/FlashRAM save emulation location in SDRAM
volatile uint32_t _unused[1015];
volatile uint32_t USB_FIFO[1024]; // USB data from PC read FIFO memory
} sc64_cart_registers_t;
#define SC64_CART_BASE (0x1E000000)
#define SC64_CART ((volatile sc64_cart_registers_t *) SC64_CART_BASE)
// SCR
#define SC64_CART_SCR_SKIP_BOOTLOADER (1 << 10)
#define SC64_CART_SCR_SD_ENABLE (1 << 9)
#define SC64_CART_SCR_FLASHRAM_ENABLE (1 << 8)
#define SC64_CART_SCR_SRAM_768K_MODE (1 << 7)
#define SC64_CART_SCR_SRAM_ENABLE (1 << 6)
#define SC64_CART_SCR_EEPROM_PI_ENABLE (1 << 5)
#define SC64_CART_SCR_EEPROM_16K_MODE (1 << 4)
#define SC64_CART_SCR_EEPROM_ENABLE (1 << 3)
#define SC64_CART_SCR_DDIPL_ENABLE (1 << 2)
#define SC64_CART_SCR_SDRAM_WRITABLE (1 << 1)
#define SC64_CART_SCR_ROM_SWITCH (1 << 0)
// GPIO
#define SC64_CART_GPIO_OFFSET_OUTPUT (0)
#define SC64_CART_GPIO_OFFSET_INPUT (8)
#define SC64_CART_GPIO_OFFSET_DIR (16)
#define SC64_CART_GPIO_OFFSET_OPEN_DRAIN (24)
// USB_SCR
#define SC64_CART_USB_SCR_FIFO_ITEMS(s) (((s) >> 3) & 0x7FF)
#define SC64_CART_USB_SCR_READY (1 << 1)
#define SC64_CART_USB_SCR_DMA_BUSY (1 << 0)
#define SC64_CART_USB_SCR_FIFO_FLUSH (1 << 2)
#define SC64_CART_USB_SCR_DMA_START (1 << 0)
// USB_DMA_ADDR
#define SC64_CART_USB_DMA_ADDR(a) ((SC64_BANK_SDRAM << 28) | ((a) & 0x3FFFFFC))
// USB_DMA_LEN
#define SC64_CART_USB_DMA_LEN(l) (((l) - 1) & 0xFFFFF)
// SD Card Interface Registers
typedef struct sc64_sd_registers_s {
volatile uint32_t SCR; // Clock control and bus width selection
volatile uint32_t ARG; // SD command argument
volatile uint32_t CMD; // SD command index and flags
volatile uint32_t RSP; // SD command response
volatile uint32_t DAT; // SD data path control
volatile uint32_t DMA_SCR; // DMA status and configuration
volatile uint32_t DMA_ADDR; // DMA current address
volatile uint32_t DMA_LEN; // DMA remaining length
volatile uint32_t _unused[120];
volatile uint32_t FIFO[128]; // SD data path FIFO buffer
} sc64_sd_registers_t;
#define SC64_SD_BASE (0x1E010000)
#define SC64_SD ((volatile sc64_sd_registers_t *) SC64_SD_BASE)
// SCR
#define SC64_SD_SCR_DAT_WIDTH (1 << 2)
#define SC64_SD_SCR_CLK_MASK (0x3 << 0)
#define SC64_SD_SCR_CLK_STOP (0 << 0)
#define SC64_SD_SCR_CLK_400_KHZ (1 << 0)
#define SC64_SD_SCR_CLK_25_MHZ (2 << 0)
#define SC64_SD_SCR_CLK_50_MHZ (3 << 0)
// CMD
#define SC64_SD_CMD_RESPONSE_CRC_ERROR (1 << 8)
#define SC64_SD_CMD_TIMEOUT (1 << 7)
#define SC64_SD_CMD_BUSY (1 << 6)
#define SC64_SD_CMD_INDEX_GET(cmd) ((cmd) & 0x3F)
#define SC64_SD_CMD_SKIP_RESPONSE (1 << 8)
#define SC64_SD_CMD_LONG_RESPONSE (1 << 7)
#define SC64_SD_CMD_START (1 << 6)
#define SC64_SD_CMD_INDEX(i) ((i) & 0x3F)
// DAT
#define SC64_SD_DAT_WRITE_OK (1 << 28)
#define SC64_SD_DAT_WRITE_ERROR (1 << 27)
#define SC64_SD_DAT_WRITE_BUSY (1 << 26)
#define SC64_SD_DAT_TX_FIFO_ITEMS_GET(dat) (((dat) >> 17) & 0x1FF)
#define SC64_SD_DAT_TX_FIFO_BYTES_GET(dat) (SC64_SD_DAT_TX_FIFO_ITEMS_GET(dat) * 4)
#define SC64_SD_DAT_TX_FIFO_FULL (1 << 16)
#define SC64_SD_DAT_TX_FIFO_EMPTY (1 << 15)
#define SC64_SD_DAT_TX_FIFO_UNDERRUN (1 << 14)
#define SC64_SD_DAT_RX_FIFO_ITEMS_GET(dat) (((dat) >> 5) & 0x1FF)
#define SC64_SD_DAT_RX_FIFO_BYTES_GET(dat) (SC64_SD_DAT_RX_FIFO_ITEMS_GET(dat) * 4)
#define SC64_SD_DAT_RX_FIFO_FULL (1 << 4)
#define SC64_SD_DAT_RX_FIFO_EMPTY (1 << 3)
#define SC64_SD_DAT_RX_FIFO_OVERRUN (1 << 2)
#define SC64_SD_DAT_CRC_ERROR (1 << 1)
#define SC64_SD_DAT_BUSY (1 << 0)
#define SC64_SD_DAT_TX_FIFO_FLUSH (1 << 19)
#define SC64_SD_DAT_RX_FIFO_FLUSH (1 << 18)
#define SC64_SD_DAT_NUM_BLOCKS(nb) ((((nb) - 1) & 0xFF) << 10)
#define SC64_SD_DAT_BLOCK_SIZE(bs) (((((bs) / 4) - 1) & 0x7F) << 3)
#define SC64_SD_DAT_DIRECTION (1 << 2)
#define SC64_SD_DAT_STOP (1 << 1)
#define SC64_SD_DAT_START (1 << 0)
#define SC64_SD_DAT_FIFO_SIZE_BYTES (1024)
#define SC64_SD_DAT_NUM_BLOCKS_MAX (256)
#define SC64_SD_DAT_BLOCK_SIZE_MAX (512)
// DMA_SCR
#define SC64_SD_DMA_SCR_BUSY (1 << 0)
#define SC64_SD_DMA_SCR_DIRECTION (1 << 2)
#define SC64_SD_DMA_SCR_STOP (1 << 1)
#define SC64_SD_DMA_SCR_START (1 << 0)
// DMA_ADDR
#define SC64_SD_DMA_ADDR_GET(addr) ((addr) & 0x3FFFFFC)
#define SC64_SD_DMA_BANK_GET(addr) (((addr) >> 28) & 0xF)
#define SC64_SD_DMA_BANK_ADDR(b, a) ((((b) & 0xF) << 28) | ((a) & 0x3FFFFFC))
// DMA_LEN
#define SC64_SD_DMA_LEN_GET(len) (((len) & 0x7FFF) * 4)
#define SC64_SD_DMA_LEN(l) ((((l) / 4) - 1) & 0x7FFF)
#define SC64_SD_DMA_LEN_MAX (0x20000)
// EEPROM Block RAM
#define SC64_EEPROM_BASE (0x1E030000)
#define SC64_EEPROM ((volatile uint8_t *) SC64_EEPROM_BASE)
#define SC64_EEPROM_SIZE ((16 * 1024) / 8)
#endif

View File

@ -1,31 +0,0 @@
#ifndef SC64_SAVE_H__
#define SC64_SAVE_H__
#include <stdbool.h>
#include <stdint.h>
typedef enum sc64_save_type_e {
SC64_SAVE_DISABLED,
SC64_SAVE_EEPROM_4K,
SC64_SAVE_EEPROM_16K,
SC64_SAVE_SRAM_256K,
SC64_SAVE_SRAM_768K,
SC64_SAVE_FLASHRAM_1M,
} sc64_save_type_t;
void sc64_save_type_set(sc64_save_type_t save_type);
sc64_save_type_t sc64_save_type_get(void);
void sc64_save_address_set(uint32_t address);
uint32_t sc64_save_address_get(void);
void sc64_save_eeprom_pi_access(bool is_enabled);
void sc64_save_write(void *ram_address);
void sc64_save_read(void *ram_address);
#endif

View File

@ -1,34 +0,0 @@
#ifndef SC64_SD_H__
#define SC64_SD_H__
#include <stdbool.h>
#include <stdint.h>
void sc64_sd_access(bool is_enabled);
// typedef enum sc64_sd_err_e {
// E_OK,
// E_TIMEOUT,
// E_CRC_ERROR,
// E_BAD_INDEX,
// E_PAR_ERROR,
// E_FIFO_ERROR,
// E_WRITE_ERROR,
// E_NO_INIT,
// } sc64_sd_err_t;
// bool sc64_sd_init(void);
// void sc64_sd_deinit(void);
// bool sc64_sd_status_get(void);
// sc64_sd_err_t sc64_sd_sectors_read(uint32_t starting_sector, size_t count, uint8_t *buffer);
// sc64_sd_err_t sc64_sd_sectors_write(uint32_t starting_sector, size_t count, uint8_t *buffer);
// sc64_sd_err_t sc64_sd_sectors_read_dma(uint32_t starting_sector, size_t count, uint8_t bank, uint32_t address);
// // sc64_sd_err_t sc64_sd_sectors_write_dma(uint32_t starting_sector, size_t count, uint8_t bank, uint32_t address);
// sc64_sd_err_t sc64_sd_dat_busy_wait(void);
#endif

View File

@ -1,8 +0,0 @@
#ifndef SC64_USB_H__
#define SC64_USB_H__
#endif

View File

@ -1,17 +0,0 @@
#include "boot.h"
#include "helpers.h"
#include "io_dma.h"
#include "registers.h"
void sc64_boot_skip_bootloader(bool is_enabled) {
sc64_helpers_reg_write(&SC64_CART->SCR, SC64_CART_SCR_SKIP_BOOTLOADER, is_enabled);
}
void sc64_boot_config_set(sc64_boot_config_t *boot_config) {
sc64_io_write(&SC64_CART->BOOT, boot_config->_packed_value);
}
void sc64_boot_config_get(sc64_boot_config_t *boot_config) {
boot_config->_packed_value = sc64_io_read(&SC64_CART->BOOT);
}

View File

@ -1,29 +0,0 @@
#include "control.h"
#include "helpers.h"
#include "io_dma.h"
#include "registers.h"
void sc64_control_sdram_writable(bool is_enabled) {
sc64_helpers_reg_write(&SC64_CART->SCR, SC64_CART_SCR_SDRAM_WRITABLE, is_enabled);
}
void sc64_control_embedded_flash_access(bool is_enabled) {
sc64_helpers_reg_write(&SC64_CART->SCR, SC64_CART_SCR_ROM_SWITCH, !is_enabled);
}
uint32_t sc64_control_version_get(void) {
return sc64_io_read(&SC64_CART->VERSION);
}
void sc64_control_ddipl_access(bool is_enabled) {
sc64_helpers_reg_write(&SC64_CART->SCR, SC64_CART_SCR_DDIPL_ENABLE, is_enabled);
}
void sc64_control_ddipl_address_set(uint32_t address) {
sc64_io_write(&SC64_CART->DDIPL_ADDR, address);
}
uint32_t sc64_control_ddipl_address_get(void) {
return sc64_io_read(&SC64_CART->DDIPL_ADDR);
}

View File

@ -1,63 +0,0 @@
#include "gpio.h"
#include "io_dma.h"
#include "registers.h"
static uint32_t gpio_state;
void sc64_gpio_init(void) {
gpio_state = 0;
sc64_io_write(&SC64_CART->GPIO, gpio_state);
}
void sc64_gpio_mode_set(uint8_t num, sc64_gpio_mode_t mode) {
if (num >= 8) {
return;
}
gpio_state &= ~(
((1 << num) << SC64_CART_GPIO_OFFSET_OPEN_DRAIN) |
((1 << num) << SC64_CART_GPIO_OFFSET_DIR)
);
switch (mode) {
case MODE_OUTPUT:
gpio_state |= ((1 << num) << SC64_CART_GPIO_OFFSET_DIR);
break;
case MODE_OPEN_DRAIN:
gpio_state |= (
((1 << num) << SC64_CART_GPIO_OFFSET_OPEN_DRAIN) |
((1 << num) << SC64_CART_GPIO_OFFSET_DIR)
);
break;
default:
break;
}
sc64_io_write(&SC64_CART->GPIO, gpio_state);
}
void sc64_gpio_output_write(uint8_t value) {
gpio_state &= ~(0xFF << SC64_CART_GPIO_OFFSET_OUTPUT);
gpio_state |= (value << SC64_CART_GPIO_OFFSET_OUTPUT);
sc64_io_write(&SC64_CART->GPIO, gpio_state);
}
void sc64_gpio_output_set(uint8_t mask) {
gpio_state |= (mask << SC64_CART_GPIO_OFFSET_OUTPUT);
sc64_io_write(&SC64_CART->GPIO, gpio_state);
}
void sc64_gpio_output_clear(uint8_t mask) {
gpio_state &= ~(mask << SC64_CART_GPIO_OFFSET_OUTPUT);
sc64_io_write(&SC64_CART->GPIO, gpio_state);
}
uint8_t sc64_gpio_input_get(void) {
return (uint8_t) ((sc64_io_read(&SC64_CART->GPIO) >> SC64_CART_GPIO_OFFSET_INPUT) & 0xFF);
}

View File

@ -1,24 +0,0 @@
#include "helpers.h"
#include "io_dma.h"
#include "registers.h"
void sc64_helpers_reg_write(volatile uint32_t *pi_address, uint32_t mask, bool mask_mode) {
uint32_t reg = sc64_io_read(pi_address);
if (mask_mode) {
reg |= mask;
} else {
reg &= ~mask;
}
sc64_io_write(pi_address, reg);
}
void sc64_helpers_reg_set(volatile uint32_t *pi_address, uint32_t mask) {
sc64_helpers_reg_write(pi_address, mask, true);
}
void sc64_helpers_reg_clear(volatile uint32_t *pi_address, uint32_t mask) {
sc64_helpers_reg_write(pi_address, mask, false);
}

View File

@ -1,8 +0,0 @@
#include "gpio.h"
#include "io_dma.h"
void sc64_init(void) {
sc64_io_dma_init();
sc64_gpio_init();
}

View File

@ -1,69 +0,0 @@
#include "io_dma.h"
#ifndef LIBDRAGON
#ifndef LIBULTRA
#error "Please specify used library with -DLIBDRAGON or -DLIBULTRA"
#endif
#endif
#ifdef LIBDRAGON
#include <libdragon.h>
#endif
#ifdef LIBULTRA
#include <ultra64.h>
static OSMesg pi_message;
static OSIoMesg pi_io_message;
static OSMesgQueue pi_message_queue;
#endif
void sc64_io_dma_init(void) {
#ifdef LIBULTRA
osCreateMesgQueue(&pi_message_queue, &pi_message, 1);
#endif
}
void sc64_io_write(volatile uint32_t *pi_address, uint32_t value) {
#ifdef LIBDRAGON
io_write((uint32_t) pi_address, value);
#elif LIBULTRA
osPiWriteIo((u32) pi_address, value);
#endif
}
uint32_t sc64_io_read(volatile uint32_t *pi_address) {
#ifdef LIBDRAGON
return io_read((uint32_t) pi_address);
#elif LIBULTRA
u32 value;
osPiReadIo((u32) pi_address, &value);
return value;
#endif
}
void sc64_dma_write(void *ram_address, volatile uint32_t *pi_address, size_t length) {
#ifdef LIBDRAGON
data_cache_hit_writeback_invalidate(ram_address, length);
dma_write(ram_address, (uint32_t) pi_address, length);
#elif LIBULTRA
osWritebackDCache(ram_address, length);
osPiStartDma(&pi_io_message, OS_MESG_PRI_NORMAL, OS_WRITE, (u32) pi_address, ram_address, length, &pi_message_queue);
osRecvMesg(&pi_message_queue, NULL, OS_MESG_BLOCK);
#endif
}
void sc64_dma_read(void *ram_address, volatile uint32_t *pi_address, size_t length) {
#ifdef LIBDRAGON
dma_read(ram_address, (uint32_t) pi_address, length);
data_cache_hit_writeback_invalidate(ram_address, length);
#elif LIBULTRA
osPiStartDma(&pi_io_message, OS_MESG_PRI_NORMAL, OS_READ, (u32) pi_address, ram_address, length, &pi_message_queue);
osRecvMesg(&pi_message_queue, NULL, OS_MESG_BLOCK);
osInvalDCache(ram_address, length);
#endif
}

View File

@ -1,157 +0,0 @@
#include "control.h"
#include "helpers.h"
#include "io_dma.h"
#include "registers.h"
#include "save.h"
static bool sc64_save_address_length_get(uint32_t *pi_address, size_t *length, bool *is_eeprom) {
sc64_save_type_t save_type = sc64_save_type_get();
*is_eeprom = false;
switch (save_type) {
case SC64_SAVE_EEPROM_4K:
*pi_address = SC64_EEPROM_BASE;
*length = 512;
*is_eeprom = true;
break;
case SC64_SAVE_EEPROM_16K:
*pi_address = SC64_EEPROM_BASE;
*length = 2048;
*is_eeprom = true;
break;
case SC64_SAVE_SRAM_256K:
*pi_address = sc64_save_address_get();
*length = (32 * 1024);
break;
case SC64_SAVE_SRAM_768K:
*pi_address = sc64_save_address_get();
*length = (96 * 1024);
break;
case SC64_SAVE_FLASHRAM_1M:
*pi_address = sc64_save_address_get();
*length = (128 * 1024);
break;
default:
return false;
}
return true;
}
void sc64_save_type_set(sc64_save_type_t save_type) {
uint32_t scr;
scr = sc64_io_read(&SC64_CART->SCR);
scr &= ~(
SC64_CART_SCR_FLASHRAM_ENABLE |
SC64_CART_SCR_SRAM_768K_MODE |
SC64_CART_SCR_SRAM_ENABLE |
SC64_CART_SCR_EEPROM_16K_MODE |
SC64_CART_SCR_EEPROM_ENABLE
);
switch (save_type)
{
case SC64_SAVE_EEPROM_4K:
scr |= SC64_CART_SCR_EEPROM_ENABLE;
break;
case SC64_SAVE_EEPROM_16K:
scr |= SC64_CART_SCR_EEPROM_ENABLE | SC64_CART_SCR_EEPROM_16K_MODE;
break;
case SC64_SAVE_SRAM_256K:
scr |= SC64_CART_SCR_SRAM_ENABLE;
break;
case SC64_SAVE_SRAM_768K:
scr |= SC64_CART_SCR_SRAM_ENABLE | SC64_CART_SCR_SRAM_768K_MODE;
break;
case SC64_SAVE_FLASHRAM_1M:
scr |= SC64_CART_SCR_FLASHRAM_ENABLE;
break;
default:
break;
}
sc64_io_write(&SC64_CART->SCR, scr);
}
sc64_save_type_t sc64_save_type_get(void) {
uint32_t scr;
scr = sc64_io_read(&SC64_CART->SCR);
if (scr & SC64_CART_SCR_FLASHRAM_ENABLE) {
return SC64_SAVE_FLASHRAM_1M;
} else if (scr & SC64_CART_SCR_SRAM_ENABLE) {
return (scr & SC64_CART_SCR_SRAM_768K_MODE) ? SC64_SAVE_SRAM_768K : SC64_SAVE_SRAM_256K;
} else if (scr & SC64_CART_SCR_EEPROM_ENABLE) {
return (scr & SC64_CART_SCR_EEPROM_16K_MODE) ? SC64_SAVE_EEPROM_16K : SC64_SAVE_EEPROM_4K;
}
return SC64_SAVE_DISABLED;
}
void sc64_save_address_set(uint32_t address) {
sc64_io_write(&SC64_CART->SAVE_ADDR, address);
}
uint32_t sc64_save_address_get(void) {
return sc64_io_read(&SC64_CART->SAVE_ADDR);
}
void sc64_save_eeprom_pi_access(bool is_enabled) {
sc64_helpers_reg_write(&SC64_CART->SCR, SC64_CART_SCR_EEPROM_PI_ENABLE, is_enabled);
}
void sc64_save_write(void *ram_address) {
uint32_t pi_address;
size_t length;
bool is_eeprom;
uint32_t scr;
bool eeprom_pi_access;
bool sdram_writable;
if (sc64_save_address_length_get(&pi_address, &length, &is_eeprom)) {
scr = sc64_io_read(&SC64_CART->SCR);
eeprom_pi_access = scr & SC64_CART_SCR_EEPROM_PI_ENABLE;
sdram_writable = scr & SC64_CART_SCR_SDRAM_WRITABLE;
if (is_eeprom && !eeprom_pi_access) {
sc64_save_eeprom_pi_access(true);
} else if (!sdram_writable) {
sc64_control_sdram_writable(true);
}
sc64_dma_write(ram_address, (volatile uint32_t *) pi_address, length);
if (is_eeprom && !eeprom_pi_access) {
sc64_save_eeprom_pi_access(false);
} else if (!sdram_writable) {
sc64_control_sdram_writable(false);
}
}
}
void sc64_save_read(void *ram_address) {
uint32_t pi_address;
size_t length;
bool is_eeprom;
bool eeprom_pi_access;
if (sc64_save_address_length_get(&pi_address, &length, &is_eeprom)) {
eeprom_pi_access = sc64_io_read(&SC64_CART->SCR) & SC64_CART_SCR_EEPROM_PI_ENABLE;
if (is_eeprom && !eeprom_pi_access) {
sc64_save_eeprom_pi_access(true);
}
sc64_dma_read(ram_address, (volatile uint32_t *) pi_address, length);
if (is_eeprom && !eeprom_pi_access) {
sc64_save_eeprom_pi_access(false);
}
}
}

View File

@ -1,211 +0,0 @@
#include "helpers.h"
#include "registers.h"
#include "sd.h"
void sc64_sd_access(bool is_enabled) {
sc64_helpers_reg_write(&SC64_CART->SCR, SC64_CART_SCR_SD_ENABLE, is_enabled);
}
// #include "registers.h"
// #include "sd.h"
// #include "io_dma.h"
// #define CMD8_ARG_SUPPLY_VOLTAGE_27_36_V (1 << 8)
// #define CMD8_ARG_CHECK_PATTERN_AA (0xAA << 0)
// #define ACMD41_ARG_HCS (1 << 30)
// #define R3_CCS (1 << 30)
// #define R3_BUSY (1 << 31)
// #define R7_SUPPLY_VOLTAGE_27_36_V (1 << 8)
// #define R7_CHECK_PATTERN_AA (0xAA << 0)
// #define SD_BLOCK_SIZE (512)
// typedef enum sc64_sd_cmd_flags_e {
// NO_FLAGS = 0,
// ACMD = (1 << 0),
// SKIP_RESPONSE = (1 << 1),
// LONG_RESPONSE = (1 << 2),
// IGNORE_CRC = (1 << 3),
// IGNORE_INDEX = (1 << 4),
// } sc64_sd_cmd_flags_t;
// static bool sd_card_initialized = false;
// static bool sd_card_type_block = false;
// static bool sd_card_selected = false;
// static uint32_t sd_card_rca = 0;
// static uint8_t sd_buffer[64] __attribute__((aligned(16)));
// static void sc64_sd_clock_set(uint32_t clock) {
// uint32_t scr = sc64_io_read(&SC64_SD->SCR);
// sc64_io_write(&SC64_SD->SCR, (scr & (~SC64_SD_SCR_CLK_MASK)) | (clock & SC64_SD_SCR_CLK_MASK));
// }
// static void sc64_sd_dat_4bit_set(bool is_4bit) {
// uint32_t scr = sc64_io_read(&SC64_SD->SCR);
// scr &= ~SC64_SD_SCR_DAT_WIDTH;
// if (is_4bit) {
// scr |= SC64_SD_SCR_DAT_WIDTH;
// }
// sc64_io_write(&SC64_SD->SCR, scr);
// }
// static void sc64_sd_peripheral_reset(void) {
// while (sc64_io_read(&SC64_SD->CMD) & SC64_SD_CMD_BUSY);
// sc64_io_write(&SC64_SD->DMA_SCR, SC64_SD_DMA_SCR_STOP);
// sc64_io_write(&SC64_SD->DAT, SC64_SD_DAT_TX_FIFO_FLUSH | SC64_SD_DAT_RX_FIFO_FLUSH | SC64_SD_DAT_STOP);
// sc64_io_write(&SC64_SD->SCR, 0);
// }
// static void sc64_sd_peripheral_init(void) {
// sc64_control_sd_enable();
// sc64_sd_peripheral_reset();
// }
// static void sc64_sd_peripheral_deinit(void) {
// if (sc64_control_sd_is_enabled()) {
// sc64_sd_peripheral_reset();
// }
// sc64_control_sd_disable();
// }
// static bool sc64_sd_cmd_send(uint8_t index, uint32_t arg, sc64_sd_cmd_flags_t flags, uint32_t *response) {
// uint32_t reg;
// if (flags & ACMD) {
// if (!sc64_sd_cmd_send(55, sd_card_rca, NO_FLAGS, response)) {
// return false;
// }
// }
// sc64_io_write(&SC64_SD->ARG, arg);
// reg = SC64_SD_CMD_START | SC64_SD_CMD_INDEX(index);
// if (flags & SKIP_RESPONSE) {
// reg |= SC64_SD_CMD_SKIP_RESPONSE;
// }
// if (flags & LONG_RESPONSE) {
// reg |= SC64_SD_CMD_LONG_RESPONSE;
// }
// sc64_io_write(&SC64_SD->CMD, reg);
// do {
// reg = sc64_io_read(&SC64_SD->CMD);
// } while (reg & SC64_SD_CMD_BUSY);
// *response = sc64_io_read(&SC64_SD->RSP);
// return (
// (reg & SC64_SD_CMD_TIMEOUT) |
// ((!(flags & SKIP_RESPONSE)) && (
// ((!(flags & IGNORE_CRC)) && (reg & SC64_SD_CMD_RESPONSE_CRC_ERROR)) |
// ((!(flags & IGNORE_INDEX)) && (SC64_SD_CMD_INDEX_GET(reg) != index))
// ))
// );
// }
// bool sc64_sd_init(void) {
// bool success;
// uint32_t response;
// uint32_t argument;
// if (sd_card_initialized) {
// return true;
// }
// sc64_sd_peripheral_init();
// do {
// sc64_sd_cmd_send(0, 0, SKIP_RESPONSE, &response);
// argument = CMD8_ARG_SUPPLY_VOLTAGE_27_36_V | CMD8_ARG_CHECK_PATTERN_AA;
// success = sc64_sd_cmd_send(8, argument, NO_FLAGS, &response);
// if (success && (response != (R7_SUPPLY_VOLTAGE_27_36_V | R7_CHECK_PATTERN_AA))) {
// break;
// }
// argument = (success ? ACMD41_ARG_HCS : 0) | 0x00FF8000;
// for (int i = 0; i < 4000; i++) {
// success = sc64_sd_cmd_send(41, argument, ACMD | IGNORE_CRC | IGNORE_INDEX, &response);
// if (!success || (response & R3_BUSY)) {
// break;
// }
// }
// if (!success || ((response & 0x00FF8000) == 0)) {
// break;
// }
// sd_card_type_block = (response & R3_CCS) ? true : false;
// success = sc64_sd_cmd_send(2, 0, LONG_RESPONSE | IGNORE_INDEX, &response);
// if (!success) {
// break;
// }
// success = sc64_sd_cmd_send(3, 0, NO_FLAGS, &response);
// if (!success) {
// break;
// }
// sd_card_rca = response & 0xFFFF0000;
// success = sc64_sd_cmd_send(7, sd_card_rca, NO_FLAGS, &response);
// if (!success) {
// break;
// }
// sd_card_selected = true;
// success = sc64_sd_cmd_send(6, 2, ACMD, &response);
// if (!success) {
// break;
// }
// sc64_sd_clock_set(SC64_SD_SCR_CLK_25_MHZ);
// sc64_sd_dat_4bit_set(true);
// sc64_sd_dat_prepare(1, 64, DAT_DIR_RX);
// success = sc64_sd_cmd_send(6, 0x00000001, NO_FLAGS, &response);
// if (!success) {
// sc64_sd_dat_abort();
// break;
// }
// success = sc64_sd_dat_read(64, sd_buffer);
// if (!success) {
// break;
// }
// if (sd_buffer[13] & 0x02) {
// sc64_sd_dat_prepare(1, 64, DAT_DIR_RX);
// success = sc64_sd_cmd_send(6, 0x80000001, NO_FLAGS, &response);
// if (!success) {
// sc64_sd_dat_abort();
// break;
// }
// success = sc64_sd_dat_read(64, sd_buffer);
// if (!success) {
// break;
// }
// sc64_sd_clock_set(SC64_SD_SCR_CLK_50_MHZ);
// }
// sd_card_initialized = true;
// return true;
// } while(0);
// sc64_sd_deinit();
// return false;
// }

View File

@ -1 +0,0 @@
#include "usb.h"