preliminary MSU-1 audio support
This commit is contained in:
parent
6c27daa30b
commit
e2e628d6fb
@ -27,7 +27,7 @@ void clock_init() {
|
||||
-> FPGA freq = 11289473.7Hz
|
||||
First, disable and disconnect PLL0.
|
||||
*/
|
||||
clock_disconnect();
|
||||
// clock_disconnect();
|
||||
|
||||
/* PLL is disabled and disconnected. setup PCLK NOW as it cannot be changed
|
||||
reliably with PLL0 connected.
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
#define _CONFIG_H
|
||||
|
||||
// #define DEBUG_SD
|
||||
// #define DEBUG_IRQ
|
||||
|
||||
#define VER "0.0.1(NSFW)"
|
||||
#define IN_AHBRAM __attribute__ ((section(".ahbram")))
|
||||
@ -38,7 +39,7 @@
|
||||
#define CONFIG_UART_BAUDRATE 921600
|
||||
#define CONFIG_UART_DEADLOCKABLE
|
||||
|
||||
#define SSP_CLK_DIVISOR_FAST 4
|
||||
#define SSP_CLK_DIVISOR_FAST 2
|
||||
#define SSP_CLK_DIVISOR_SLOW 250
|
||||
|
||||
#define SSP_CLK_DIVISOR_FPGA_FAST 6
|
||||
|
||||
@ -62,7 +62,10 @@ void disk_init(void);
|
||||
/* Will be set to DISK_ERROR if any access on the card fails */
|
||||
enum diskstates { DISK_CHANGED = 0, DISK_REMOVED, DISK_OK, DISK_ERROR };
|
||||
|
||||
extern int sd_offload, ff_sd_offload, newcard;
|
||||
extern int sd_offload, ff_sd_offload, sd_offload_tgt, newcard;
|
||||
extern int sd_offload_partial;
|
||||
extern uint16_t sd_offload_partial_start;
|
||||
extern uint16_t sd_offload_partial_end;
|
||||
extern volatile enum diskstates disk_state;
|
||||
|
||||
/* Disk type - part of the external API except for ATA2! */
|
||||
|
||||
51
src/ff.c
51
src/ff.c
@ -87,7 +87,8 @@
|
||||
|
||||
#include "ff.h" /* FatFs configurations and declarations */
|
||||
#include "diskio.h" /* Declarations of low level disk I/O functions */
|
||||
|
||||
#include "config.h"
|
||||
#include "uart.h"
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
@ -2013,7 +2014,6 @@ FRESULT f_open (
|
||||
BYTE *dir;
|
||||
DEF_NAMEBUF;
|
||||
|
||||
|
||||
fp->fs = 0; /* Clear file object */
|
||||
|
||||
#if !_FS_READONLY
|
||||
@ -2186,8 +2186,8 @@ FRESULT f_read (
|
||||
if (fp->fs->wflag && fp->fs->winsect - sect < cc)
|
||||
mem_cpy(rbuff + ((fp->fs->winsect - sect) * SS(fp->fs)), fp->fs->win, SS(fp->fs));
|
||||
#else
|
||||
if ((fp->flag & FA__DIRTY) && fp->dsect - sect < cc)
|
||||
mem_cpy(rbuff + ((fp->dsect - sect) * SS(fp->fs)), fp->buf, SS(fp->fs));
|
||||
if ((fp->flag & FA__DIRTY) && fp->dsect - sect < cc){
|
||||
mem_cpy(rbuff + ((fp->dsect - sect) * SS(fp->fs)), fp->buf, SS(fp->fs)); uart_putc('Y');}
|
||||
#endif
|
||||
#endif
|
||||
rcnt = SS(fp->fs) * cc; /* Number of bytes transferred */
|
||||
@ -2196,27 +2196,45 @@ FRESULT f_read (
|
||||
#if !_FS_TINY
|
||||
#if !_FS_READONLY
|
||||
if (fp->flag & FA__DIRTY) { /* Write sector I/O buffer if needed */
|
||||
printf("DIRTY!?!\n");
|
||||
if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK)
|
||||
ABORT(fp->fs, FR_DISK_ERR);
|
||||
fp->flag &= ~FA__DIRTY;
|
||||
}
|
||||
#endif
|
||||
if (fp->dsect != sect) { /* Fill sector buffer with file data */
|
||||
if (disk_read(fp->fs->drv, fp->buf, sect, 1) != RES_OK)
|
||||
ABORT(fp->fs, FR_DISK_ERR);
|
||||
if(!ff_sd_offload) {
|
||||
if (disk_read(fp->fs->drv, fp->buf, sect, 1) != RES_OK)
|
||||
ABORT(fp->fs, FR_DISK_ERR);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
fp->dsect = sect;
|
||||
}
|
||||
rcnt = SS(fp->fs) - (fp->fptr % SS(fp->fs)); /* Get partial sector data from sector buffer */
|
||||
if (rcnt > btr) rcnt = btr;
|
||||
if(!ff_sd_offload) {
|
||||
#if _FS_TINY
|
||||
if (move_window(fp->fs, fp->dsect)) /* Move sector window */
|
||||
ABORT(fp->fs, FR_DISK_ERR);
|
||||
mem_cpy(rbuff, &fp->fs->win[fp->fptr % SS(fp->fs)], rcnt); /* Pick partial sector */
|
||||
if (move_window(fp->fs, fp->dsect)) /* Move sector window */
|
||||
ABORT(fp->fs, FR_DISK_ERR);
|
||||
mem_cpy(rbuff, &fp->fs->win[fp->fptr % SS(fp->fs)], rcnt); /* Pick partial sector */
|
||||
#else
|
||||
mem_cpy(rbuff, &fp->buf[fp->fptr % SS(fp->fs)], rcnt); /* Pick partial sector */
|
||||
mem_cpy(rbuff, &fp->buf[fp->fptr % SS(fp->fs)], rcnt); /* Pick partial sector */
|
||||
// printf("final mem_cpy, rcnt=%d, rbuff-buff=%d\n", rcnt, (void*)rbuff-buff);
|
||||
} else {
|
||||
sd_offload_partial_start = fp->fptr % SS(fp->fs);
|
||||
sd_offload_partial_end = sd_offload_partial_start + rcnt;
|
||||
// printf("partial dma. sect=%08lx start=%d end=%d\n", fp->dsect, sd_offload_partial_start, sd_offload_partial_end);
|
||||
/* set start + end */
|
||||
sd_offload = 1;
|
||||
sd_offload_partial = 1;
|
||||
if(disk_read(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK) {
|
||||
sd_offload = 0;
|
||||
ABORT(fp->fs, FR_DISK_ERR);
|
||||
}
|
||||
sd_offload = 0;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
ff_sd_offload = 0;
|
||||
LEAVE_FF(fp->fs, FR_OK);
|
||||
@ -2356,6 +2374,7 @@ FRESULT f_sync (
|
||||
res = validate(fp->fs, fp->id); /* Check validity of the object */
|
||||
if (res == FR_OK) {
|
||||
if (fp->flag & FA__WRITTEN) { /* Has the file been written? */
|
||||
printf("DIRTY?!?!?!\n");
|
||||
#if !_FS_TINY /* Write-back dirty buffer */
|
||||
if (fp->flag & FA__DIRTY) {
|
||||
if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK)
|
||||
@ -2696,8 +2715,14 @@ FRESULT f_lseek (
|
||||
fp->flag &= ~FA__DIRTY;
|
||||
}
|
||||
#endif
|
||||
if (disk_read(fp->fs->drv, fp->buf, nsect, 1) != RES_OK)
|
||||
ABORT(fp->fs, FR_DISK_ERR);
|
||||
if(!ff_sd_offload) {
|
||||
sd_offload_partial=0;
|
||||
if (disk_read(fp->fs->drv, fp->buf, nsect, 1) != RES_OK)
|
||||
ABORT(fp->fs, FR_DISK_ERR);
|
||||
} else {
|
||||
sd_offload_partial=1;
|
||||
sd_offload_partial_start = fp->fptr % SS(fp->fs);
|
||||
}
|
||||
#endif
|
||||
fp->dsect = nsect;
|
||||
}
|
||||
@ -2708,7 +2733,7 @@ FRESULT f_lseek (
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
ff_sd_offload = 0;
|
||||
LEAVE_FF(fp->fs, res);
|
||||
}
|
||||
|
||||
|
||||
181
src/fpga_spi.c
181
src/fpga_spi.c
@ -29,20 +29,50 @@
|
||||
|
||||
cmd param function
|
||||
=============================================
|
||||
00 bbhhll set address to 0xbbhhll
|
||||
01 bbhhll set SNES input address mask to 0xbbhhll
|
||||
02 bbhhll set SRAM address mask to 0xbbhhll
|
||||
0t bbhhll set address to 0xbbhhll
|
||||
t = target
|
||||
target: 0 = RAM
|
||||
1 = MSU Audio buffer
|
||||
2 = MSU Data buffer
|
||||
targets 1 & 2 only require 2 address bytes to
|
||||
be written.
|
||||
|
||||
10 bbhhll set SNES input address mask to 0xbbhhll
|
||||
20 bbhhll set SRAM address mask to 0xbbhhll
|
||||
|
||||
3m - set mapper to m
|
||||
0=HiROM, 1=LoROM, 2=ExHiROM, 6=SF96, 7=Menu
|
||||
40 - trigger SD DMA (512b from SD to memory)
|
||||
80 - read with increment
|
||||
81 - read w/o increment
|
||||
90 {xx}* write xx with increment
|
||||
91 {xx}* write xx w/o increment
|
||||
Eu - set memory unit (u=0: "ROM"; u=1: SRAM)
|
||||
|
||||
4s - trigger SD DMA (512b from SD to memory)
|
||||
s: Bit 2 = partial, Bit 1:0 = target
|
||||
target: see above
|
||||
|
||||
60 sssseeee set SD DMA partial transfer start+end
|
||||
ssss = start offset (msb first)
|
||||
eeee = end offset (msb first)
|
||||
|
||||
80 - read with increment (RAM only)
|
||||
81 - read w/o increment (RAM only)
|
||||
|
||||
90 {xx}* write xx with increment (RAM only)
|
||||
91 {xx}* write xx w/o increment (RAM only)
|
||||
|
||||
E0 ssrr set MSU-1 status register (=FPGA status byte 2)
|
||||
ss = bits to set in status register (1=set)
|
||||
rr = bits to reset in status register (1=reset)
|
||||
|
||||
E1 - pause DAC
|
||||
E2 - resume/play DAC
|
||||
E3 - reset DAC playback pointer (0)
|
||||
|
||||
F0 - receive test token (to see if FPGA is alive)
|
||||
F1 - receive status
|
||||
|
||||
|
||||
F2 - get MSU data address (32bit, MSB first)
|
||||
F3 - get MSU audio track no. (16bit, MSB first)
|
||||
F4 - get MSU volume (8bit)
|
||||
|
||||
FF {xx]* echo (returns the sent data in the next byte)
|
||||
*/
|
||||
|
||||
#include <arm/NXP/LPC17xx/LPC17xx.h>
|
||||
@ -58,6 +88,22 @@ void fpga_spi_init(void) {
|
||||
spi_init(SPI_SPEED_FPGA_FAST);
|
||||
}
|
||||
|
||||
void set_msu_addr(uint32_t address) {
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0x02);
|
||||
FPGA_TX_BYTE((address>>8)&0xff);
|
||||
FPGA_TX_BYTE((address)&0xff);
|
||||
FPGA_DESELECT();
|
||||
}
|
||||
|
||||
void set_dac_addr(uint32_t address) {
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0x01);
|
||||
FPGA_TX_BYTE((address>>8)&0xff);
|
||||
FPGA_TX_BYTE((address)&0xff);
|
||||
FPGA_DESELECT();
|
||||
}
|
||||
|
||||
void set_mcu_addr(uint32_t address) {
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0x00);
|
||||
@ -69,7 +115,7 @@ void set_mcu_addr(uint32_t address) {
|
||||
|
||||
void set_saveram_mask(uint32_t mask) {
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0x02);
|
||||
FPGA_TX_BYTE(0x20);
|
||||
FPGA_TX_BYTE((mask>>16)&0xff);
|
||||
FPGA_TX_BYTE((mask>>8)&0xff);
|
||||
FPGA_TX_BYTE((mask)&0xff);
|
||||
@ -78,7 +124,7 @@ void set_saveram_mask(uint32_t mask) {
|
||||
|
||||
void set_rom_mask(uint32_t mask) {
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0x01);
|
||||
FPGA_TX_BYTE(0x10);
|
||||
FPGA_TX_BYTE((mask>>16)&0xff);
|
||||
FPGA_TX_BYTE((mask>>8)&0xff);
|
||||
FPGA_TX_BYTE((mask)&0xff);
|
||||
@ -100,25 +146,116 @@ uint8_t fpga_test() {
|
||||
return result;
|
||||
}
|
||||
|
||||
uint8_t fpga_status() {
|
||||
uint16_t fpga_status() {
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0xF1); /* STATUS */
|
||||
FPGA_TX_BYTE(0x00); /* dummy */
|
||||
uint16_t result = (FPGA_RX_BYTE()) << 8;
|
||||
result |= FPGA_RX_BYTE();
|
||||
FPGA_DESELECT();
|
||||
return result;
|
||||
}
|
||||
|
||||
void fpga_set_sddma_range(uint16_t start, uint16_t end) {
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0x60); /* DMA_RANGE */
|
||||
FPGA_TX_BYTE(start>>8);
|
||||
FPGA_TX_BYTE(start&0xff);
|
||||
FPGA_TX_BYTE(end>>8);
|
||||
FPGA_TX_BYTE(end&0xff);
|
||||
//if(tgt==1 && (test=FPGA_RX_BYTE()) != 0x41) printf("!!!!!!!!!!!!!!! -%02x- \n", test);
|
||||
FPGA_DESELECT();
|
||||
}
|
||||
|
||||
void fpga_sddma(uint8_t tgt, uint8_t partial) {
|
||||
uint32_t test = 0;
|
||||
uint8_t status = 0;
|
||||
BITBAND(SD_CLKREG->FIODIR, SD_CLKPIN) = 0;
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0x40 | (tgt & 0x3) | ((partial & 1) << 2) ); /* DO DMA */
|
||||
FPGA_TX_BYTE(0x00); /* dummy for falling DMA_EN edge */
|
||||
//if(tgt==1 && (test=FPGA_RX_BYTE()) != 0x41) printf("!!!!!!!!!!!!!!! -%02x- \n", test);
|
||||
FPGA_DESELECT();
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0xF1); /* STATUS */
|
||||
FPGA_TX_BYTE(0x00); /* dummy */
|
||||
while((status=FPGA_RX_BYTE()) & 0x80) {
|
||||
FPGA_RX_BYTE(); /* eat the 2nd status byte */
|
||||
test++;
|
||||
}
|
||||
FPGA_DESELECT();
|
||||
if(test<10)printf("loopy: %ld %02x\n", test, status);
|
||||
BITBAND(SD_CLKREG->FIODIR, SD_CLKPIN) = 1;
|
||||
}
|
||||
|
||||
void set_dac_vol(uint8_t volume) {
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0x50);
|
||||
FPGA_TX_BYTE(volume);
|
||||
FPGA_TX_BYTE(0x00); /* latch rise */
|
||||
FPGA_TX_BYTE(0x00); /* latch fall */
|
||||
FPGA_DESELECT();
|
||||
}
|
||||
|
||||
void dac_play() {
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0xe2);
|
||||
FPGA_TX_BYTE(0x00); /* latch reset */
|
||||
FPGA_DESELECT();
|
||||
}
|
||||
|
||||
void dac_pause() {
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0xe1);
|
||||
FPGA_TX_BYTE(0x00); /* latch reset */
|
||||
FPGA_DESELECT();
|
||||
}
|
||||
|
||||
void dac_reset() {
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0xe3);
|
||||
FPGA_TX_BYTE(0x00); /* latch reset */
|
||||
FPGA_DESELECT();
|
||||
}
|
||||
|
||||
void set_msu_status(uint8_t set, uint8_t reset) {
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0xe0);
|
||||
FPGA_TX_BYTE(set);
|
||||
FPGA_TX_BYTE(reset);
|
||||
FPGA_TX_BYTE(0x00); /* latch reset */
|
||||
FPGA_TX_BYTE(0x00); /* latch reset */
|
||||
FPGA_DESELECT();
|
||||
}
|
||||
|
||||
uint8_t get_msu_volume() {
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0xF4); /* MSU_VOLUME */
|
||||
FPGA_TX_BYTE(0x00); /* dummy */
|
||||
uint8_t result = FPGA_RX_BYTE();
|
||||
FPGA_DESELECT();
|
||||
return result;
|
||||
}
|
||||
|
||||
void fpga_sd2ram() {
|
||||
BITBAND(SD_CLKREG->FIODIR, SD_CLKPIN) = 0;
|
||||
uint16_t get_msu_track() {
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0x40); /* DO DMA */
|
||||
FPGA_TX_BYTE(0x00); /* dummy for falling DMA_EN edge */
|
||||
FPGA_DESELECT();
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0xF1); /* STATUS */
|
||||
FPGA_TX_BYTE(0xF3); /* MSU_TRACK */
|
||||
FPGA_TX_BYTE(0x00); /* dummy */
|
||||
while(FPGA_RX_BYTE() & 0x80);
|
||||
uint16_t result = (FPGA_RX_BYTE()) << 8;
|
||||
result |= FPGA_RX_BYTE();
|
||||
FPGA_DESELECT();
|
||||
BITBAND(SD_CLKREG->FIODIR, SD_CLKPIN) = 1;
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32_t get_msu_offset() {
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0xF2); /* MSU_OFFSET */
|
||||
FPGA_TX_BYTE(0x00); /* dummy */
|
||||
uint32_t result = (FPGA_RX_BYTE()) << 24;
|
||||
result |= (FPGA_RX_BYTE()) << 16;
|
||||
result |= (FPGA_RX_BYTE()) << 8;
|
||||
result |= (FPGA_RX_BYTE());
|
||||
FPGA_DESELECT();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/* sd2snes - SD card based universal cartridge for the SNES
|
||||
Copyright (C) 2009-2010 Maximilian Rehkopf <otakon@gmx.net>
|
||||
AVR firmware portion
|
||||
uC firmware portion
|
||||
|
||||
Inspired by and based on code from sd2iec, written by Ingo Korb et al.
|
||||
See sdcard.c|h, config.h.
|
||||
@ -34,7 +34,9 @@
|
||||
#define FPGA_SS_REG LPC_GPIO0
|
||||
|
||||
#define FPGA_SELECT() do {FPGA_TX_SYNC(); BITBAND(FPGA_SS_REG->FIOCLR, FPGA_SS_BIT) = 1;} while (0)
|
||||
#define FPGA_SELECT_ASYNC() do {BITBAND(FPGA_SS_REG->FIOCLR, FPGA_SS_BIT) = 1;} while (0)
|
||||
#define FPGA_DESELECT() do {FPGA_TX_SYNC(); BITBAND(FPGA_SS_REG->FIOSET, FPGA_SS_BIT) = 1;} while (0)
|
||||
#define FPGA_DESELECT_ASYNC() do {BITBAND(FPGA_SS_REG->FIOSET, FPGA_SS_BIT) = 1;} while (0)
|
||||
|
||||
#define FPGA_TX_SYNC() spi_tx_sync()
|
||||
#define FPGA_TX_BYTE(x) spi_tx_byte(x)
|
||||
@ -48,14 +50,24 @@
|
||||
|
||||
void fpga_spi_init(void);
|
||||
uint8_t fpga_test(void);
|
||||
uint8_t fpga_status(void);
|
||||
uint16_t fpga_status(void);
|
||||
void spi_fpga(void);
|
||||
void spi_sd(void);
|
||||
void spi_none(void);
|
||||
void set_mcu_addr(uint32_t);
|
||||
void set_dac_addr(uint32_t);
|
||||
void set_dac_vol(uint8_t);
|
||||
void dac_play(void);
|
||||
void dac_pause(void);
|
||||
void dac_reset(void);
|
||||
void set_msu_addr(uint32_t);
|
||||
void set_msu_status(uint8_t set, uint8_t reset);
|
||||
void set_saveram_mask(uint32_t);
|
||||
void set_rom_mask(uint32_t);
|
||||
void set_mapper(uint8_t val);
|
||||
void fpga_sd2ram(void);
|
||||
|
||||
void fpga_sddma(uint8_t tgt, uint8_t partial);
|
||||
void fpga_set_sddma_range(uint16_t start, uint16_t end);
|
||||
uint8_t get_msu_volume(void);
|
||||
uint16_t get_msu_track(void);
|
||||
uint32_t get_msu_offset(void);
|
||||
#endif
|
||||
|
||||
171
src/main.c
171
src/main.c
@ -30,7 +30,11 @@
|
||||
|
||||
int i;
|
||||
|
||||
int sd_offload = 0, ff_sd_offload = 0;
|
||||
int sd_offload = 0, ff_sd_offload = 0, sd_offload_tgt = 0;
|
||||
int sd_offload_partial = 0;
|
||||
uint16_t sd_offload_partial_start = 0;
|
||||
uint16_t sd_offload_partial_end = 0;
|
||||
|
||||
/* FIXME HACK */
|
||||
volatile enum diskstates disk_state;
|
||||
extern volatile tick_t ticks;
|
||||
@ -44,9 +48,8 @@ int main(void) {
|
||||
/* connect UART3 on P0[25:26] + SSP0 on P0[15:18] SSP1 on P0[6:9] + MAT3.0 on P0[10] */
|
||||
LPC_PINCON->PINSEL1 = BV(18) | BV(19) | BV(20) | BV(21) /* UART3 */
|
||||
| BV(3) | BV(5); /* SSP0 (FPGA) except SS */
|
||||
LPC_PINCON->PINSEL0 = BV(31) /* SSP0 */
|
||||
LPC_PINCON->PINSEL0 = BV(31); /* SSP0 */
|
||||
/* | BV(13) | BV(15) | BV(17) | BV(19) SSP1 (SD) */
|
||||
| BV(20) | BV(21); /* MAT3.0 (FPGA clock) */
|
||||
|
||||
/* pull-down CIC data lines */
|
||||
LPC_PINCON->PINMODE3 = BV(18) | BV(19) | BV(20) | BV(21);
|
||||
@ -62,6 +65,7 @@ int main(void) {
|
||||
led_init();
|
||||
/* do this last because the peripheral init()s change PCLK dividers */
|
||||
clock_init();
|
||||
LPC_PINCON->PINSEL0 |= BV(20) | BV(21); /* MAT3.0 (FPGA clock) */
|
||||
led_pwm();
|
||||
sdn_init();
|
||||
fpga_spi_init();
|
||||
@ -76,7 +80,6 @@ led_pwm();
|
||||
LPC_TIM3->MR0=1;
|
||||
LPC_TIM3->TCR=1;
|
||||
fpga_init();
|
||||
// fpga_pgm((uint8_t*)"/main.bit.rle");
|
||||
fpga_rompgm();
|
||||
restart:
|
||||
if(disk_state == DISK_CHANGED) {
|
||||
@ -121,7 +124,7 @@ restart:
|
||||
snes_bootprint(" Loading ... \0");
|
||||
if(get_cic_state() == CIC_PAIR) {
|
||||
printf("PAIR MODE ENGAGED!\n");
|
||||
cic_pair(CIC_PAL, CIC_PAL);
|
||||
cic_pair(CIC_NTSC, CIC_NTSC);
|
||||
}
|
||||
rdyled(1);
|
||||
readled(0);
|
||||
@ -176,6 +179,7 @@ restart:
|
||||
load_sram((uint8_t*)"/sd2snes/sd2snes.dir", SRAM_DIR_ADDR);
|
||||
}
|
||||
/* load menu */
|
||||
fpga_pgm((uint8_t*)"/main.bit.rle");
|
||||
uart_putc('(');
|
||||
load_rom((uint8_t*)"/sd2snes/menu.bin", SRAM_MENU_ADDR);
|
||||
/* force memory size + mapper */
|
||||
@ -222,7 +226,7 @@ restart:
|
||||
}
|
||||
set_mcu_ovr(0);
|
||||
snes_reset(1);
|
||||
delay_ms(1);
|
||||
delay_ms(10);
|
||||
snes_reset(0);
|
||||
break;
|
||||
case SNES_CMD_SETRTC:
|
||||
@ -234,8 +238,161 @@ restart:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
printf("cmd was %x, going to snes main loop\n", cmd);
|
||||
|
||||
/* MSU1 STUFF, GET ME OUTTA HERE */
|
||||
FIL durr;
|
||||
f_open(&durr, "/SF96SOE.smc", FA_READ);
|
||||
ff_sd_offload=1;
|
||||
sd_offload_tgt=2;
|
||||
f_lseek(&durr, 79L);
|
||||
set_msu_addr(0);
|
||||
UINT bytes_read = 1024;
|
||||
UINT bytes_read2 = 1;
|
||||
uint16_t volume=0;
|
||||
set_dac_vol(0x00);
|
||||
spi_set_speed(SSP_CLK_DIVISOR_FAST);
|
||||
while(fpga_status() & 0x4000);
|
||||
uint16_t fpga_status_prev = fpga_status();
|
||||
uint16_t fpga_status_now = fpga_status();
|
||||
uint16_t dac_addr = 0;
|
||||
uint16_t msu_addr = 0;
|
||||
uint8_t msu_repeat = 0;
|
||||
uint16_t msu_track = 0;
|
||||
uint32_t msu_offset = 0;
|
||||
uint8_t msu_volume = 0;
|
||||
uint8_t msu_volupdate = 0;
|
||||
uint8_t msu_volupdate_cnt = 0;
|
||||
set_dac_addr(dac_addr);
|
||||
dac_pause();
|
||||
dac_reset();
|
||||
/* audio_start, data_start, volume_start, audio_ctrl[1:0], ctrl_start */
|
||||
while(1){
|
||||
fpga_status_now = fpga_status();
|
||||
if(fpga_status_now & 0x0020) {
|
||||
char suffix[11];
|
||||
|
||||
/* get trackno */
|
||||
msu_track = get_msu_track();
|
||||
printf("Audio requested! Track=%d\n", msu_track);
|
||||
|
||||
/* open file */
|
||||
f_close(&file_handle);
|
||||
snprintf(suffix, sizeof(suffix), "-%d.wav", msu_track);
|
||||
strcpy((char*)file_buf, (char*)file_lfn);
|
||||
strcpy(strrchr((char*)file_buf, (int)'.'), suffix);
|
||||
f_open(&file_handle, (const TCHAR*)file_buf, FA_READ);
|
||||
ff_sd_offload=1;
|
||||
sd_offload_tgt=1;
|
||||
f_lseek(&file_handle, 44L);
|
||||
ff_sd_offload=1;
|
||||
sd_offload_tgt=1;
|
||||
set_dac_addr(0);
|
||||
dac_pause();
|
||||
dac_reset();
|
||||
f_read(&file_handle, file_buf, 2048, &bytes_read);
|
||||
|
||||
/* clear busy bit */
|
||||
set_msu_status(0x00, 0x20); /* set no bits, reset bit 5 */
|
||||
}
|
||||
|
||||
if(fpga_status_now & 0x0010) {
|
||||
msu_offset=get_msu_offset();
|
||||
printf("Data requested! Offset=%08lx\n", msu_offset);
|
||||
// get address
|
||||
// open file + fill buffer
|
||||
// clear busy bit
|
||||
set_msu_status(0x00, 0x10);
|
||||
}
|
||||
|
||||
if(fpga_status_now & 0x0001) {
|
||||
if(fpga_status_now & 0x0004) {
|
||||
msu_repeat = 1;
|
||||
set_msu_status(0x04, 0x01); /* set bit 2, reset bit 0 */
|
||||
printf("Repeat set!\n");
|
||||
} else {
|
||||
msu_repeat = 0;
|
||||
set_msu_status(0x00, 0x05); /* set no bits, reset bit 0+2 */
|
||||
printf("Repeat clear!\n");
|
||||
}
|
||||
|
||||
if(fpga_status_now & 0x0002) {
|
||||
printf("PLAY!\n");
|
||||
set_msu_status(0x02, 0x01); /* set bit 0, reset bit 1 */
|
||||
dac_play();
|
||||
} else {
|
||||
printf("PAUSE!\n");
|
||||
set_msu_status(0x00, 0x03); /* set no bits, reset bit 1+0 */
|
||||
dac_pause();
|
||||
}
|
||||
}
|
||||
|
||||
/* Audio buffer refill */
|
||||
if((fpga_status_now & 0x4000) != (fpga_status_prev & 0x4000)) {
|
||||
if(fpga_status_now & 0x4000) {
|
||||
dac_addr = 0x0;
|
||||
} else {
|
||||
dac_addr = 0x400;
|
||||
}
|
||||
set_dac_addr(dac_addr);
|
||||
sd_offload_tgt=1;
|
||||
ff_sd_offload=1;
|
||||
f_read(&file_handle, file_buf, 1024, &bytes_read);
|
||||
}
|
||||
|
||||
/* volume update */
|
||||
if(msu_volupdate && !(msu_volupdate_cnt++ & 0x1)) {
|
||||
if(volume < msu_volume) {
|
||||
volume++;
|
||||
} else if(volume > msu_volume) {
|
||||
volume--;
|
||||
} else {
|
||||
msu_volupdate = 0;
|
||||
}
|
||||
printf("should not see me!\n");
|
||||
set_dac_vol(volume);
|
||||
}
|
||||
|
||||
/* Data buffer refill */
|
||||
if((fpga_status_now & 0x2000) != (fpga_status_prev & 0x2000)) {
|
||||
printf("data\n");
|
||||
if(fpga_status_now & 0x2000) {
|
||||
msu_addr = 0x0;
|
||||
} else {
|
||||
msu_addr = 0x2000;
|
||||
}
|
||||
set_msu_addr(msu_addr);
|
||||
sd_offload_tgt=2;
|
||||
ff_sd_offload=1;
|
||||
f_read(&durr, file_buf, 8192, &bytes_read2);
|
||||
}
|
||||
fpga_status_prev = fpga_status_now;
|
||||
|
||||
/* handle loop / end */
|
||||
if(bytes_read<1024) {
|
||||
ff_sd_offload=0;
|
||||
sd_offload=0;
|
||||
if(msu_repeat) {
|
||||
printf("loop\n");
|
||||
ff_sd_offload=1;
|
||||
sd_offload_tgt=1;
|
||||
f_lseek(&file_handle, 44L);
|
||||
ff_sd_offload=1;
|
||||
sd_offload_tgt=1;
|
||||
f_read(&file_handle, file_buf, 1024 - bytes_read, &bytes_read);
|
||||
} else {
|
||||
set_msu_status(0x00, 0x02); /* clear play bit */
|
||||
}
|
||||
bytes_read=1024;
|
||||
}
|
||||
if(!bytes_read2) {
|
||||
f_lseek(&durr, 0L);
|
||||
uart_putc('*');
|
||||
}
|
||||
}
|
||||
|
||||
/* END OF MSU1 STUFF */
|
||||
|
||||
cmd=0;
|
||||
uint8_t snes_reset_prev=0, snes_reset_now=0, snes_reset_state=0;
|
||||
uint16_t reset_count=0;
|
||||
|
||||
@ -186,6 +186,7 @@ printf("%s\n", filename);
|
||||
// FPGA_TX_BYTE(0x91); /* write w/ increment */
|
||||
for(;;) {
|
||||
ff_sd_offload=1;
|
||||
sd_offload_tgt=0;
|
||||
tickstmp=getticks();
|
||||
bytes_read = file_read();
|
||||
ticks_read+=getticks()-tickstmp;
|
||||
|
||||
@ -348,7 +348,7 @@ int send_command_fast(uint8_t* cmd, uint8_t* rsp, uint8_t* buf){
|
||||
do {
|
||||
if(dat) {
|
||||
if(!(BITBAND(SD_DAT0REG->FIOPIN, SD_DAT0PIN))) {
|
||||
DBG_SD printf("data start during response\n");
|
||||
printf("data start during response\n");
|
||||
j=datcnt;
|
||||
state=CMD_RSPDAT;
|
||||
break;
|
||||
@ -401,6 +401,7 @@ int send_command_fast(uint8_t* cmd, uint8_t* rsp, uint8_t* buf){
|
||||
}
|
||||
|
||||
if(dat && state != CMD_DAT) { /* response ended before data */
|
||||
BITBAND(SD_CMDREG->FIODIR, SD_CMDPIN) = 1;
|
||||
state=CMD_DAT;
|
||||
j=datcnt;
|
||||
datshift=8;
|
||||
@ -410,7 +411,13 @@ int send_command_fast(uint8_t* cmd, uint8_t* rsp, uint8_t* buf){
|
||||
}
|
||||
wiggle_fast_neg1(); /* eat the start bit */
|
||||
if(sd_offload) {
|
||||
fpga_sd2ram();
|
||||
if(sd_offload_partial) {
|
||||
fpga_set_sddma_range(sd_offload_partial_start, sd_offload_partial_end);
|
||||
fpga_sddma(sd_offload_tgt, 1);
|
||||
sd_offload_partial=0;
|
||||
} else {
|
||||
fpga_sddma(sd_offload_tgt, 0);
|
||||
}
|
||||
state=CMD_RSP;
|
||||
return rsplen;
|
||||
}
|
||||
@ -460,6 +467,7 @@ int send_command_fast(uint8_t* cmd, uint8_t* rsp, uint8_t* buf){
|
||||
}
|
||||
rsp-=rsplen;
|
||||
DBG_SD printf("send_command_fast: CMD%d response: %02x%02x%02x%02x%02x%02x\n", cmdno, rsp[0], rsp[1], rsp[2], rsp[3], rsp[4], rsp[5]);
|
||||
BITBAND(SD_CMDREG->FIODIR, SD_CMDPIN) = 1;
|
||||
return rsplen;
|
||||
}
|
||||
|
||||
@ -528,7 +536,13 @@ void stream_datablock(uint8_t *buf) {
|
||||
}
|
||||
wiggle_fast_neg1(); /* eat the start bit */
|
||||
if(sd_offload) {
|
||||
fpga_sd2ram();
|
||||
if(sd_offload_partial) {
|
||||
fpga_set_sddma_range(sd_offload_partial_start, sd_offload_partial_end);
|
||||
fpga_sddma(sd_offload_tgt, 1);
|
||||
sd_offload_partial=0;
|
||||
} else {
|
||||
fpga_sddma(sd_offload_tgt, 0);
|
||||
}
|
||||
} else {
|
||||
while(1) {
|
||||
datdata = SD_DAT << 4;
|
||||
@ -677,6 +691,7 @@ void read_block(uint32_t address, uint8_t *buf) {
|
||||
last_block=address;
|
||||
} else {
|
||||
if(during_blocktrans) {
|
||||
// uart_putc('_');
|
||||
//printf("nonseq read (%lx -> %lx), restarting transmission\n", last_block, address);
|
||||
/* send STOP_TRANSMISSION to end an open READ/WRITE_MULTIPLE_BLOCK */
|
||||
cmd_fast(STOP_TRANSMISSION, 0, 0x61, NULL, rsp);
|
||||
|
||||
@ -47,7 +47,7 @@ void timer_init(void) {
|
||||
BITBAND(LPC_SC->PCLKSEL1, 26) = 1;
|
||||
BITBAND(LPC_SC->PCLKSEL1, PCLK_TIMER3) = 1;
|
||||
/* enable SysTick */
|
||||
SysTick_Config(SysTick->CALIB & SysTick_CALIB_TENMS_Msk);
|
||||
SysTick_Config((SysTick->CALIB & SysTick_CALIB_TENMS_Msk));
|
||||
}
|
||||
|
||||
void delay_us(unsigned int time) {
|
||||
|
||||
@ -111,7 +111,6 @@ static volatile unsigned int read_idx,write_idx;
|
||||
|
||||
void UART_HANDLER(void) {
|
||||
int iir = UART_REGS->IIR;
|
||||
|
||||
if (!(iir & 1)) {
|
||||
/* Interrupt is pending */
|
||||
switch (iir & 14) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user