/* * ===================================================================================== * * ________ .__ __ ________ ____ ________ * \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/ * / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \ * / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \ * \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ / * \__> \/ \/ \/ \/ \/ * * www.optixx.org * * * Version: 1.0 * Created: 07/21/2009 03:32:16 PM * Author: david@optixx.org * * ===================================================================================== */ #include #include #include #include #include #include #include #include #include "pwm.h" #include "debug.h" #include "info.h" #include "sram.h" #include "util.h" #include "uart.h" #include "dump.h" #include "irq.h" #include "config.h" #include "crc.h" #include "command.h" #include "shared_memory.h" uint8_t command_buf[RECEIVE_BUF_LEN]; uint8_t recv_buf[RECEIVE_BUF_LEN]; volatile uint8_t recv_counter = 0; volatile uint8_t cr = 0; uint8_t *token_ptr; uint8_t *get_token(void) { uint8_t *p = token_ptr; while (*p == ' ') p++; if (*p == '\0') return NULL; token_ptr = p; do { token_ptr++; if (*token_ptr == ' ' || *token_ptr == '\n' || *token_ptr == '\r') { *token_ptr++ = '\0'; break; } } while (*token_ptr != ' ' && *token_ptr != '\n' && *token_ptr != '\r'); return p; } uint8_t get_dec(uint32_t *decval) { const uint8_t *t; t = get_token(); if (t != NULL) { int x = util_sscandec(t); if (x < 0) return 0; *decval = x; return 1; } return 0; } uint8_t parse_hex(const uint8_t *s, uint32_t *hexval) { uint32_t x = util_sscanhex(s); *hexval = (uint32_t) x; return 1; } uint8_t get_hex(uint32_t *hexval) { const uint8_t *t; t = get_token(); if (t != NULL) return parse_hex(t, hexval); return 0; } uint8_t get_hex_arg2(uint32_t *hexval1, uint32_t *hexval2) { return get_hex(hexval1) && get_hex(hexval2); } uint8_t get_hex_arg3(uint32_t *hexval1, uint32_t *hexval2, uint32_t *hexval3) { return get_hex(hexval1) && get_hex(hexval2) && get_hex(hexval3); } static uint8_t get_int32(uint32_t *val) { if (!get_hex(val)){ info_P(PSTR("Invalid argument!\n")); return 0; } else { return 1; } } static uint8_t get_int8(uint8_t *val) { uint32_t ret; if (!get_hex(&ret) ||ret > 0xff){ info_P(PSTR("Invalid argument!\n")); return 0; }else{ *val = (uint8_t)ret; return 1; } } static int get_bool(void) { const uint8_t *t; t = get_token(); if (t != NULL) { int result = util_sscanbool(t); if (result >= 0) return result; } info_P(PSTR("Invalid argument (should be 0 or 1)!\n")); return -1; } void prompt(void){ uart_putc('\r'); uart_putc('\n'); uart_putc('>'); } ISR(USART0_RX_vect) // Interrupt for UART Byte received { UCSR0B &= (255 - (1< 0) { recv_counter--; } else { recv_counter++; } } UCSR0B |= (1< \n")); }else if (strcmp_P((char*)t, (PGM_P)cmdlist[CMD_CRC]) == 0) { if (get_hex_arg2(&arg1,&arg2)){ crc = crc_check_bulk_memory(arg1,arg2,0x8000); info_P(PSTR("0x%06lx - 0x%06lx crc=0x%04x\n"),arg1,arg2,crc); } else info_P(PSTR("CRC \n")); }else if (strcmp_P((char*)t, (PGM_P)cmdlist[CMD_EXIT]) == 0) { leave_application(); }else if (strcmp_P((char*)t, (PGM_P)cmdlist[CMD_RESET]) == 0) { send_reset(); }else if (strcmp_P((char*)t, (PGM_P)cmdlist[CMD_IRQ]) == 0) { info_P(PSTR("Send IRQ\n")); snes_irq_on(); snes_irq_lo(); _delay_us(20); snes_irq_hi(); snes_irq_off(); }else if (strcmp_P((char*)t, (PGM_P)cmdlist[CMD_AVR]) == 0) { info_P(PSTR("Activate AVR bus\n")); avr_bus_active(); snes_irq_lo(); snes_irq_off(); }else if (strcmp_P((char*)t, (PGM_P)cmdlist[CMD_SNES]) == 0) { info_P(PSTR("Activate SNES bus\n")); snes_irq_lo(); snes_irq_off(); snes_wr_disable(); snes_bus_active(); }else if (strcmp_P((char*)t, (PGM_P)cmdlist[CMD_LOROM]) == 0) { info_P(PSTR("Set LOROM\n")); snes_lorom(); snes_wr_disable(); }else if (strcmp_P((char*)t, (PGM_P)cmdlist[CMD_HIROM]) == 0) { info_P(PSTR("Set HIROM\n")); snes_hirom(); snes_wr_disable(); }else if (strcmp_P((char*)t, (PGM_P)cmdlist[CMD_WR]) == 0) { arg1 = get_bool(); if(arg1==1){ info_P(PSTR("Set WR enable")); snes_wr_enable(); }else if (arg1==0){ info_P(PSTR("Set WR disable")); snes_wr_disable(); } }else if (strcmp_P((char*)t, (PGM_P)cmdlist[CMD_SHMWR]) == 0) { if (get_hex_arg2(&arg1,&arg2)) shared_memory_write((uint8_t)arg1, (uint8_t)arg1); else info_P(PSTR("SHMWR \n")); }else if (strcmp_P((char*)t, (PGM_P)cmdlist[CMD_SHMSAVE]) == 0) { shared_memory_scratchpad_region_tx_save(); shared_memory_scratchpad_region_rx_save(); info_P(PSTR("Save scratchpad\n")); }else if (strcmp_P((char*)t, (PGM_P)cmdlist[CMD_SHMRESTORE]) == 0) { shared_memory_scratchpad_region_tx_restore(); shared_memory_scratchpad_region_rx_restore(); info_P(PSTR("Restore scratchpad\n")); }else if (strcmp_P((char*)t, (PGM_P)cmdlist[CMD_LOADER]) == 0) { boot_startup_rom(500); }else if (strcmp_P((char*)t, (PGM_P)cmdlist[CMD_RECONNECT]) == 0) { usb_connect(); }else if (strcmp_P((char*)t, (PGM_P)cmdlist[CMD_STATUS]) == 0) { transaction_status(); }else if (strcmp_P((char*)t, (PGM_P)cmdlist[CMD_HELP]) == 0) { shell_help(); } prompt(); /* dias set irq vector set reset vector dump cart header */ }