SAROO/Firm_Saturn/sci_shell.c
2023-04-19 22:33:28 +08:00

383 lines
6.8 KiB
C

#include "main.h"
#include "smpc.h"
/**********************************************************/
int gets_from_stm32 = 0;
static char hbuf[128];
static int hblen = 0;
#define PROMPT "SS"
int gets(char *buf, int len)
{
int n, ch, esc;
if(gets_from_stm32){
while(1){
n = *(volatile u8*)0x22820000;
if(n)
break;
}
strcpy(buf, (u8*)0x22820010);
buf[n] = 0;
return n;
}
printk(PROMPT "> ");
n = 0;
esc = 0;
while(1){
while((ch=sci_getc(1000))<0);
if(ch==0x0d || ch==0x0a){
break;
}
if(esc==0 && ch==0x1b){
esc = 1;
continue;
}
if(esc==1){
if(ch==0x5b){
esc = 2;
}else{
printk("<ESC1 %02x>", ch);
esc = 0;
}
continue;
}
if(esc==2){
esc = 0;
if(ch==0x41 || ch==0x43){
// UP:0x41 RIGHT:0x43
if(hblen){
int sn = n;
n = hblen;
memcpy(buf, hbuf, hblen);
printk("\r" PROMPT "> %s", hbuf);
while(hblen<sn){
printk(" ");
hblen += 1;
}
if(ch==0x43){
break;
}
}
}else{
printk("<ESC2 %02x>", ch);
}
}else if(ch==0x08){
if(n){
n -= 1;
printk("\b \b");
}
}else if(ch>=0x20){
printk("%c", ch);
buf[n] = ch;
n++;
if(n==len)
break;
}else{
printk("{%02x}", ch);
}
}
if(n){
memcpy(hbuf, buf, n);
hbuf[n] = 0;
hblen = n;
}
printk("\r\n");
buf[n] = 0;
return n;
}
static int arg_base = 16;
int str2hex(char *str, int *hex)
{
int n, p, ch, base;
base = arg_base;
n = 0;
p = 0;
hex[0] = 0;
while(1){
ch = *str++;
if(ch==' '){
if(p){
n++;
hex[n] = 0;
p = 0;
}
continue;
}else if((ch=='0' && *str=='x')){
str += 1;
base = 16;
}else if((ch>='0' && ch<='9')){
ch -= '0';
}else if((base==16 && ch>='a' && ch<='f')){
ch = ch-'a'+10;
}else if((base==16 && ch>='A' && ch<='F')){
ch = ch-'A'+10;
}else{
if(p)
n++;
return n;
}
hex[n] = hex[n]*base + ch;
p++;
}
}
/**********************************************************/
static int dump_width = 2;
static int dump_addr = 0x00200000;
void dump(int argc, int *args, int width)
{
int i, c, p, addr, len;
u32 d;
u8 sbuf[16];
addr = (argc>=1)? args[0] : dump_addr;
len = (argc>=2)? args[1] : 256;
if(width==0)
width = dump_width;
c = 0;
p = 0;
while(1){
if((p%16)==0 || p>=len){
if(c){
printk(" ");
for(i=0; i<c; i++){
if(sbuf[i]>0x20 && sbuf[i]<0x80){
printk("%c", sbuf[i]);
}else{
printk(".");
}
}
c = 0;
}
if(p>=len){
printk("\n");
}else{
printk("\n%08x: ", addr);
}
}else if((p%8)==0){
printk("- ");
}
if(p>=len)
break;
if(width==1){
d = *(u8*)(addr);
sbuf[c++] = d;
printk("%02x ", d);
}else if(width==2){
d = *(u16*)(addr);
sbuf[c++] = d>>8; // big endian
sbuf[c++] = d;
printk("%04x ", d);
}else{
d = *(u32*)(addr);
sbuf[c++] = d>>24; // big endian
sbuf[c++] = d>>16;
sbuf[c++] = d>>8;
sbuf[c++] = d;
printk("%08x ", d);
}
p += width;
addr += width;
}
dump_width = width;
dump_addr = addr;
}
void mem_dump(char *str, void *vaddr, int size)
{
u8 *addr = (u8*)vaddr;
int i, j, c;
if(str){
printk("%s:\n", str);
}
for(i=0; i<size; i+=16){
printk("%04x: ", i);
for(j=0; j<16; j++){
printk("%02x ", addr[j]);
}
printk(" ");
for(j=0; j<16; j++){
c = addr[j];
if(c>0x20 && c<0x80){
printk("%c", c);
}else{
printk(".");
}
}
printk("\n");
addr += 16;
}
}
/**********************************************************/
#define CMD_START if(0){}
#define CMD(x) else if(strcmp(cmd, #x)==0)
void sci_shell(void)
{
char cmd[128];
u32 argc, arg[4];
while(1){
gets(cmd, 128);
char *sp = strchr(cmd, ' ');
if(sp){
*sp = 0;
sp += 1;
argc = str2hex(sp, arg);
}else{
argc = 0;
}
CMD_START
CMD(base16) { arg_base = 16; }
CMD(base10) { arg_base = 10; }
CMD(rb){ printk("%08x: %02x\n", arg[0], *(u8*)arg[0]); }
CMD(rw){ printk("%08x: %04x\n", arg[0], *(u16*)arg[0]); }
CMD(rd){ printk("%08x: %08x\n", arg[0], *(u32*)arg[0]); }
CMD(wb){ printk("%08x= %02x\n", arg[0], (u8)arg[1]); *(u8*)arg[0] = arg[1]; }
CMD(ww){ printk("%08x= %04x\n", arg[0], (u16)arg[1]); *(u16*)arg[0] = arg[1]; }
CMD(wd){ printk("%08x= %08x\n", arg[0], (u32)arg[1]); *(u32*)arg[0] = arg[1]; }
CMD(db){ dump(argc, arg, 1); }
CMD(dw){ dump(argc, arg, 2); }
CMD(dd){ dump(argc, arg, 4); }
CMD(d) { dump(argc, arg, 0); }
CMD(go){ void (*go)(void) = (void(*)(void))arg[0]; go(); }
CMD(t) { cd_cmd(); }
CMD(f) { cdc_file_test(); }
CMD(m) { bios_run_cd_player(); } /* 运行系统CD播放器 */
CMD(n) { bios_cd_cmd(); } /* 启动游戏 */
CMD(menu) { menu_init(); }
CMD(wtt) {
// 测试延时计数. 大概9000000是1秒.
int cnt = arg[0];
reset_timer();
while(cnt){
cnt -= 1;
}
int tm = get_timer();
printk("counter: %d timer: %d\n", arg[0], tm);
}
CMD(mmt) {
int mem_test(int size);
mem_test(0x100000);
}
CMD(b) {
u32 addr = 0, mask = 0;
install_ubr_isr();
if(argc>0) addr = arg[0];
if(argc>1) mask = arg[1];
set_break_pc(addr, mask);
}
CMD(br) {
u32 addr = 0, mask = 0;
install_ubr_isr();
if(argc>0) addr = arg[0];
if(argc>1) mask = arg[1];
set_break_rw(addr, mask, BRK_READ);
}
CMD(bw) {
u32 addr = 0, mask = 0;
install_ubr_isr();
if(argc>0) addr = arg[0];
if(argc>1) mask = arg[1];
set_break_rw(addr, mask, BRK_WRITE);
}
CMD(bb) {
u32 addr = 0;
if(argc>0) addr = arg[0];
if(addr){
game_break_pc = addr;
}
}
CMD(c) {
/* 打开系统光驱 */
smpc_cmd(CDOFF);
printk("CDOFF ...\n");
printk("CDOFF ...\n");
smpc_cmd(CDON);
printk("CDON ...\n");
printk("CDON ...\n");
REG16(0x25897004) = 0x0000;
}
CMD(s) {
/* 关闭系统光驱, 打开sarooo */
smpc_cmd(CDOFF);
printk("CDOFF ...\n");
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并运行. 如果指定了地址, 则只下载. */
int xm_len, xm_addr;
xm_addr = (argc>0)? arg[0] : 0x06004000;
xm_len = tiny_xmodem_recv(xm_addr);
printk(" \n");
printk(" \n");
printk("Download to %08x, size %08x\n", xm_addr, xm_len);
if(argc==0){
u32 *xbuf = (u32*)xm_addr;
int offset = 0;
if(xbuf[0]==0x53454741 && xbuf[1]==0x20534547)
offset = 0x0f00;
printk("Jump to %08x ...\n", xm_addr);
void (*go)(void) = (void(*)(void))(xm_addr+offset);
go();
}
}
}
}
/**********************************************************/