1.Read pad by SMPC

2.Add key repeat mode
3.Add File R/W from SD
4.CDC bugfix
This commit is contained in:
tpu 2023-03-25 23:02:18 +08:00
parent 51621a8dbe
commit 415cd5bd5b
9 changed files with 281 additions and 78 deletions

View file

@ -358,35 +358,70 @@ void put_box(int x1, int y1, int x2, int y2, int c)
/******************************************************************************/
static u32 last_pdat = 0;
static u32 last_value;
static u32 curr_pdat = 0;
static int pdat_state = 0;
static int pdat_count = 0;
static int pdat_wait;
u32 conio_getc(void)
{
u32 pdat;
u32 pdat = pad_read();
while(1){
if(pdat_state==0){
pdat = pad_read();
switch(pdat_state){
case 0:
// 空闲检测
if(pdat != curr_pdat){
curr_pdat = pdat;
pdat_state = 1;
pdat_count = 0;
}
}else if(pdat_state<100){
pdat = pad_read();
break;
case 1:
// 等待稳定
if(pdat == curr_pdat){
pdat_state += 1;
pdat_count += 1;
if(pdat_count==2){
pdat_state = 2;
}
}else{
pdat_state = 0;
}
}else{
break;
case 2:
// 稳定状态
pdat = last_pdat ^ curr_pdat;
last_pdat = curr_pdat;
if(curr_pdat){
// 转入重复状态
pdat_state = 3;
pdat_count = 0;
pdat_wait = 500;
}else{
pdat_state = 0;
return (pdat<<16) | curr_pdat;
}
last_value = (pdat<<16) | curr_pdat;
//printk("key0: %08x\n", last_value);
return last_value;
case 3:
// 重复状态
if(pdat != curr_pdat){
pdat_state = 0;
}else{
pdat_count += 1;
if(pdat_count==pdat_wait){
pdat_wait = 30;
pdat_count = 0;
//printk("keyr: %08x\n", last_value);
return last_value;
}
}
break;
default:
break;
}
return 0;
}
@ -484,6 +519,8 @@ _restart:
#if 1
while(1){
ctrl = conio_getc();
if(ctrl==0)
continue;
retv = menu->handle(ctrl);
if(retv==MENU_EXIT)
break;

View file

@ -12,32 +12,63 @@
#include "smpc.h"
#include "vdp2.h"
/**********************************************************/
u32 BE32(void *ptr)
{
u8 *b = (u8*)ptr;
return (b[0]<<24) | (b[1]<<16) | (b[2]<<8) | b[3];
}
u32 LE32(void *ptr)
{
u8 *b = (u8*)ptr;
return (b[3]<<24) | (b[2]<<16) | (b[1]<<8) | b[0];
}
void LE32W(void *ptr, u32 val)
{
u8 *b = (u8*)ptr;
b[0] = (val>> 0)&0xff;
b[1] = (val>> 8)&0xff;
b[2] = (val>>16)&0xff;
b[3] = (val>>24)&0xff;
}
/**********************************************************/
void pad_init(void)
{
PDR1 = 0;
DDR1 = 0x60;
IOSEL = IOSEL1;
}
u32 pad_read(void)
{
u32 bits;
u32 bits = 0;
PDR1 = 0x60;
bits = (PDR1 & 0x8) << 9;
PDR1 = 0x40;
bits |= (PDR1 & 0xf) << 8;
PDR1 = 0x20;
bits |= (PDR1 & 0xf) << 4;
PDR1 = 0x00;
bits |= (PDR1 & 0xf);
while(SF&0x01);
SF = 0x01;
COMREG = 0x10;
while(SF&0x01);
return bits ^ 0x1FFF;
bits = (OREG2<<8) | (OREG3);
IREG0 = 0x40;
return bits ^ 0xFFFF;
}
void pad_init(void)
{
DDR1 = 0;
EXLE = 0;
IOSEL = 0;
IREG0 = 0x00;
IREG1 = 0x0a;
IREG2 = 0xf0;
}
/**********************************************************/
int smpc_cmd(int cmd)
@ -164,6 +195,52 @@ int sci_getc(int timeout)
}
/**********************************************************/
int read_file (char *name, int offset, int size, void *buf)
{
int retv;
LE32W((void*)0x22820000, offset);
LE32W((void*)0x22820004, size);
strcpy((void*)0x22820010, name);
SS_ARG = 0;
SS_CMD = SSCMD_FILERD;
while(SS_CMD);
retv = (signed short)SS_ARG;
if(retv<0)
return retv;
size = LE32((void*)0x22820004);
memcpy(buf, (void*)0x22820100, size);
return size;
}
int write_file(char *name, int offset, int size, void *buf)
{
int retv;
LE32W((void*)0x22820000, offset);
LE32W((void*)0x22820004, size);
strcpy((void*)0x22820010, name);
memcpy((void*)0x22820100, buf, size);
SS_ARG = 0;
SS_CMD = SSCMD_FILEWR;
while(SS_CMD);
retv = (signed short)SS_ARG;
if(retv<0)
return retv;
size = LE32((void*)0x22820004);
return size;
}
/**********************************************************/
@ -229,21 +306,6 @@ int mem_test(int size)
}
/**********************************************************/
u32 BE32(void *ptr)
{
u8 *b = (u8*)ptr;
return (b[0]<<24) | (b[1]<<16) | (b[2]<<8) | b[3];
}
u32 LE32(void *ptr)
{
u8 *b = (u8*)ptr;
return (b[3]<<24) | (b[2]<<16) | (b[1]<<8) | b[0];
}
/**********************************************************/
static int total_disc, total_page, page;
@ -311,15 +373,17 @@ static int sel_handle(int ctrl)
page_update(0);
}
}else if(BUTTON_DOWN(ctrl, PAD_LT)){
if(page>0){
page -= 1;
page_update(0);
if(page<0){
page = total_page-1;
}
page_update(0);
}else if(BUTTON_DOWN(ctrl, PAD_RT)){
if((page+1)<total_page){
page += 1;
page_update(0);
if(page>=total_page){
page = 0;
}
page_update(0);
}else if(BUTTON_DOWN(ctrl, PAD_A)){
int index = page*11 + menu->current;
@ -401,7 +465,7 @@ int main_handle(int ctrl)
menu_status(&main_menu, NULL);
return MENU_EXIT;
}else if(index==3){
menu_status(&main_menu, NULL);
menu_status(&main_menu, "TODO");
}else if(index==update_index){
menu_status(&main_menu, "升级中,请勿断电...");
SS_ARG = 0;
@ -436,7 +500,7 @@ void menu_init(void)
int i;
memset(&main_menu, 0, sizeof(main_menu));
strcpy(main_menu.title, "SAROO Boot Menu");
sprintf(main_menu.title, "SAROO Boot Menu V%02x0000", SS_VER&0xff);
for(i=0; i<4; i++){
add_menu_item(&main_menu, menu_str[i]);

View file

@ -18,8 +18,8 @@ typedef unsigned long long u64;
#define NULL ((void*)0)
#define SS_ID REG16(0x25897000)
#define SS_VER REG16(0x25897002)
#define SS_ID REG16(0x25807000)
#define SS_VER REG16(0x25807002)
#define SS_CTRL REG16(0x25897004)
#define SS_STAT REG16(0x25897008)
#define SS_TIMER REG32(0x2589700c)
@ -40,6 +40,8 @@ typedef unsigned long long u64;
#define SSCMD_LOADDISC 0x0003
#define SSCMD_CHECK 0x0004
#define SSCMD_UPDATE 0x0005
#define SSCMD_FILERD 0x0006
#define SSCMD_FILEWR 0x0007
/*****************************************************************************/
@ -67,19 +69,19 @@ void msleep(u32 ms);
/*****************************************************************************/
#define PAD_LT (1<<12)
#define PAD_RIGHT (1<<15)
#define PAD_LEFT (1<<14)
#define PAD_DOWN (1<<13)
#define PAD_UP (1<<12)
#define PAD_START (1<<11)
#define PAD_A (1<<10)
#define PAD_C (1<<9)
#define PAD_B (1<<8)
#define PAD_RIGHT (1<<7)
#define PAD_LEFT (1<<6)
#define PAD_DOWN (1<<5)
#define PAD_UP (1<<4)
#define PAD_RT (1<<3)
#define PAD_X (1<<2)
#define PAD_Y (1<<1)
#define PAD_Z (1<<0)
#define PAD_RT (1<<7)
#define PAD_X (1<<6)
#define PAD_Y (1<<5)
#define PAD_Z (1<<4)
#define PAD_LT (1<<3)
u32 pad_read(void);
@ -143,6 +145,9 @@ int str2hex(char *str, int *hex);
void dump(int argc, int *args, int width);
void mem_dump(char *str, void *addr, int size);
int read_file (char *name, int offset, int size, void *buf);
int write_file(char *name, int offset, int size, void *buf);
/*****************************************************************************/
@ -175,6 +180,8 @@ typedef struct {
u32 crc32(u8 *buf, int len, u32 crc);
u32 get_sr(void);
void set_sr(u32 sr);
void break_in_game(int break_pc, void *handle);
void break_in_game_next(int break_pc, void *handle);
void install_ubr_isr(void);
@ -192,7 +199,7 @@ void set_break_rw(u32 addr, u32 mask, int rw);
typedef struct menu_desc_t {
int num;
int current;
char title[32];
char title[64];
char items[11][64];
int (*handle)(int index);
}MENU_DESC;

View file

@ -331,6 +331,14 @@ void sci_shell(void)
printk("CDOFF ...\n");
REG16(0x25897004) = 0x8000;
}
CMD(frt){
int retv = read_file("/ramimage.bin", 0, 0, (void*)0x00280000);
printk("read /ramimage.bin to 0x00280000: %d\n", retv);
}
CMD(fwt){
int retv = write_file("/saturn_save.bin", 0, 0x10000, (void*)0x00180000);
printk("write 0x00180000 to /saturn_save.bin: %d\n", retv);
}
CMD(z) {
/* 下载到ram并运行. 如果指定了地址, 则只下载. */

View file

@ -126,6 +126,7 @@ static int sd_card_insert(void)
void SDIO_IRQHandler(void)
{
#if 1
u32 cmd, mask, stat;
stat = SDIO->STA;
@ -133,12 +134,16 @@ void SDIO_IRQHandler(void)
cmd = SDIO->CMD;
if(stat&SDMMC_STA_BUSYD0){
printk("SD_IRQ: cmd=%08x stat=%08x mask=%08x Busy!\n", cmd, stat, mask);
//printk("SD_IRQ: cmd=%08x stat=%08x mask=%08x Busy!\n", cmd, stat, mask);
SDIO->MASK = SDMMC_STA_BUSYD0END;
}else{
SDIO->MASK = 0;
osSemaphoreRelease(cmd_sem);
}
#else
SDIO->MASK = 0;
osSemaphoreRelease(cmd_sem);
#endif
}

View file

@ -1,5 +1,6 @@
#include "main.h"
#include "ff.h"
/******************************************************************************/
@ -278,6 +279,18 @@ void simple_shell(void)
void cdc_dump();
cdc_dump();
}
CMD(seram){
FIL fp;
int retv = f_open(&fp, "/exram.bin", FA_CREATE_ALWAYS|FA_WRITE);
if(retv==FR_OK){
u32 wsize = 0x00400000;
retv = f_write(&fp, (void*)0x61400000, 0x00400000, &wsize);
f_close(&fp);
printk("save to exram.bin: %d %d\n", retv, wsize);
}else{
printk("create exram.bin failed! %d\n", retv);
}
}
CMD(q){
break;

View file

@ -93,6 +93,15 @@
#define PLAYTYPE_DIR 3
#define SSCMD_PRINTF 0x0001
#define SSCMD_LISTDISC 0x0002
#define SSCMD_LOADDISC 0x0003
#define SSCMD_CHECK 0x0004
#define SSCMD_UPDATE 0x0005
#define SSCMD_FILERD 0x0006
#define SSCMD_FILEWR 0x0007
#define MSF_TO_FAD(m,s,f) ((m * 4500) + (s * 75) + f)
@ -201,6 +210,7 @@ typedef struct
u8 trans_block_end; // 分区中最后一个要传输的扇区+1
BLOCK *trans_block;
u16 trans_size;
u8 trans_finish;
u8 last_buffer;

View file

@ -130,10 +130,13 @@ void trans_start(void)
tcnt = 0;
min_num = 40960;
cdb.cdwnum = 0;
cdb.trans_finish = 0;
if(cdb.trans_type==TRANS_DATA || cdb.trans_type==TRANS_DATA_DEL){
PARTITION *pt = &cdb.part[cdb.trans_part_index];
BLOCK *bt = find_block(pt, cdb.trans_block_start);
//printk("trans_start: pt=%d start=%d size=%d\n",
// cdb.trans_part_index, cdb.trans_block_start, cdb.trans_block_end-cdb.trans_block_start);
//printk(" trans pt_%d: blks=%d bt=%08x size=%04x\n", cdb.trans_part_index, pt->numblocks, bt, bt->size);
cdb.trans_bk = cdb.trans_block_start;
@ -179,12 +182,16 @@ void trans_start(void)
void trans_handle(void)
{
tcnt += 1;
if(cdb.trans_finish==0){
// 中断在传输结束时会重复进入一次。这里做个判断,以免误加。
cdb.cdwnum += cdb.trans_size;
}
if(cdb.trans_type==TRANS_DATA || cdb.trans_type==TRANS_DATA_DEL){
if(cdb.trans_bk==cdb.trans_block_end){
//printk(" trans end!\n");
cdb.trans_finish = 1;
ST_CTRL &= ~STIRQ_DAT;
}else{
BLOCK *bt = cdb.trans_block->next;
@ -215,7 +222,7 @@ void trans_handle(void)
fill_fifo(dp, cdb.trans_size);
ST_STAT = STIRQ_DAT;
ST_CTRL |= STIRQ_DAT;
HIRQ = HIRQ_DRDY | HIRQ_SCDQ;
HIRQ = HIRQ_SCDQ;
}
}else{
ST_CTRL &= ~STIRQ_DAT;
@ -509,8 +516,12 @@ int end_trans(void)
ST_CTRL &= ~STIRQ_DAT;
ST_STAT = STIRQ_DAT;
//printk(" cdwnum=%08x FIFO_STAT=%08x min_num=%d\n", cdb.cdwnum, FIFO_STAT, min_num);
//printk("end_trans: cdwnum=%08x FIFO_STAT=%08x min_num=%d\n", cdb.cdwnum, FIFO_STAT, min_num);
fifo_remain = (FIFO_STAT&0x0fff)*2; // FIFO中还有多少字节未读
if(fifo_remain>=512){
//FIFO中的数据大于512字节不会产生中断。cdwnum会少记一次。
cdb.cdwnum += 0x800;
}
cdb.cdwnum -= fifo_remain;
// reset fifo
@ -528,7 +539,7 @@ int end_trans(void)
}
}
//printk("end_trans: cdwnum=%08x\n", cdb.cdwnum);
//printk(" : cdwnum=%08x\n", cdb.cdwnum);
if(cdb.cdwnum){
SSCR1 = (cdb.status<<8) | ((cdb.cdwnum>>17)&0xff);
SSCR2 = (cdb.cdwnum>>1)&0xffff;

View file

@ -295,6 +295,13 @@ _restart_nowait:
{
//printk("filter sector %08x...\n", fad);
retv = filter_sector(play_track, &wblk);
{
// "Final Fight Revenge" need this!
int i;
for(i=0; i<500000; i++){
NOTHING();
}
}
HIRQ = HIRQ_CSCT;
if(retv==0){
// 送到某个过滤器成功
@ -388,24 +395,24 @@ void ss_cmd_handle(void)
printk("scmd_task: %04x\n", SS_CMD);
switch(cmd){
case 0x0001:
case SSCMD_PRINTF:
// 输出信息
printk("%s", (char*)0x61820010);
SS_CMD = 0;
break;
case 0x0002:
case SSCMD_LISTDISC:
// 列出镜像信息
retv = list_disc(0);
SS_ARG = retv;
SS_CMD = 0;
break;
case 0x0003:
case SSCMD_LOADDISC:
// 装载镜像
retv = load_disc(SS_ARG);
SS_ARG = retv;
SS_CMD = 0;
break;
case 0x0004:
case SSCMD_CHECK:
{
// 检查是否有升级固件
int fpga = (fpga_update(1)==0)? 1: 0;
@ -414,7 +421,7 @@ void ss_cmd_handle(void)
SS_CMD = 0;
break;
}
case 0x0005:
case SSCMD_UPDATE:
{
// 固件升级
int fpga = (fpga_update(0)>=-1)? 0: 1;
@ -423,6 +430,47 @@ void ss_cmd_handle(void)
SS_CMD = 0;
break;
}
case SSCMD_FILERD:
{
FIL fp;
int offset = *(u32*)(0x61820000);
int size = *(u32*)(0x61820004);
char *name = (char*)(0x61820010);
int retv = f_open(&fp, name, FA_READ);
if(retv==FR_OK){
u32 rsize = 0;
f_lseek(&fp, offset);
if(size==0)
size = f_size(&fp);
retv = f_read(&fp, (void*)0x61820100, size, &rsize);
*(u32*)(0x61820004) = rsize;
f_close(&fp);
printk("\nSSCMD_FILERD: retv=%d rsize=%08x %s\n", retv, rsize, name);
}
SS_ARG = -retv;
SS_CMD = 0;
break;
}
case SSCMD_FILEWR:
{
FIL fp;
int offset = *(u32*)(0x61820000);
int size = *(u32*)(0x61820004);
char *name = (char*)(0x61820010);
int flags = (offset==0)? FA_CREATE_ALWAYS : FA_OPEN_ALWAYS;
int retv = f_open(&fp, name, flags|FA_WRITE);
if(retv==FR_OK){
u32 wsize = 0;
f_lseek(&fp, offset);
retv = f_write(&fp, (void*)0x61820100, size, &wsize);
*(u32*)(0x61820004) = wsize;
f_close(&fp);
printk("\nSSCMD_FILEWR: retv=%d wsize=%08x %s\n", retv, wsize, name);
}
SS_ARG = -retv;
SS_CMD = 0;
break;
}
default:
printk("[SS] unkonw cmd: %04x\n", cmd);
break;