#include #include #include #include #include #include #include #include #include #include void disasm_main(void) { extern void casio_syscall_test(void); // Setup Channel 0. SH7305_UBC.CRR0.PCB = 1; // Set PC break adter instruction break. SH7305_UBC.CRR0.BIE = 1; // Request a Break. SH7305_UBC.CBR0.MFE = 0; // Enable Match Flag. SH7305_UBC.CBR0.MFI = 0b000000; // Set UBC.CCMFR.MF0 = 1, when break occur. SH7305_UBC.CBR0.AIE = 0; // Disable ASID check. SH7305_UBC.CBR0.SZ = 0b010; // Disable Match condition. SH7305_UBC.CBR0.CD = 0; // Use Operand Bus for Operand Access. SH7305_UBC.CBR0.ID = 0b01; // Selecte instruction Fetch cycle. SH7305_UBC.CBR0.RW = 0b11; // Use Read or Write for match condition. SH7305_UBC.CBR0.CE = 0; // Disable Channel 0. // Set up target address. SH7305_UBC.CAR0 = (uint32_t)&casio_Bfile_ReadFile; // Tested programe address ! SH7305_UBC.CAMR0 = 0x00000000; // Address Mask. // Setup Control register. SH7305_UBC.CBCR.UBDE = 1; // Use DBR instead of VBR. //@note: // You *SHOULD* use `icbi` SH4 instruction // After channel enable, otherwise the calculator // will freeze. SH7305_UBC.CBR0.CE = 1; // Enable Channel 0 ! icbi((void*)0xa0000000); // Start disassembly // TODO: thread !! drivers_uninstall(0); char buffer[128]; int handle = casio_Bfile_OpenFile(u"\\\\fls0\\vhex.g1a", 1); earlyterm_write("handle -> %#x\n", handle); DBG_WAIT; DBG_WAIT; DBG_WAIT; casio_Bfile_ReadFile(handle, buffer, 128, 0); casio_Bfile_CloseFile(handle); drivers_install(0); } static void internal_GetKey(ubc_session_t *session, void (**menu)(ubc_session_t*)) { keyscan_t keylist[KEYBOARD_NB_KEYS]; int i; // Wipe key informations session->key.entry = 0; session->key.shift = 0; session->key.left = 0; session->key.right = 0; session->key.up = 0; session->key.down = 0; session->key.optn = 0; session->key.minus = 0; session->key.plus = 0; // Wait user interactions keyboard_wait_event(keylist); // Check all pressed keys i = -1; while (keylist[++i].keycode != KEY_UNUSED && i < KEYBOARD_NB_KEYS) { // Check key validity if (!(keylist[i].counter == 1 || (i == 0 && keylist[i].counter > 10 && (keylist[i].counter & 1) == 0))) continue; // Check special keys switch (keylist[i].keycode) { case KEY_EXE: session->key.entry = 1; break; case KEY_SHIFT: session->key.shift = 1; break; case KEY_ALPHA: session->key.alpha = 1; break; case KEY_OPTN: session->key.optn = 1; break; case KEY_LEFT: session->key.left = 1; break; case KEY_RIGHT: session->key.right = 1; break; case KEY_UP: session->key.up = 1; break; case KEY_DOWN: session->key.down = 1; break; case KEY_PLUS: session->key.plus = 1; break; case KEY_MINUS: session->key.minus = 1; break; case KEY_F1: *menu = &disasm_menu_disassembly; break; case KEY_F2: *menu = &disasm_menu_show_context; break; case KEY_MENU: casio_return_menu(0); break; } } } void ubc_handler(struct cpu_context *context, int channel) { extern struct earlyterm earlyterm; void (*menu)(ubc_session_t *session); ubc_session_t session; // Initialize new session. session.key.entry = 0; session.key.shift = 0; session.key.left = 0; session.key.right = 0; session.key.up = 0; session.key.minus = 0; session.key.plus = 0; session.key.optn = 0; session.channel = channel; session.context = context; session.menu.context.cursor = 0; // Initialize disassembly menu session.menu.disassembly.memory = (void *)(ptrdiff_t)context->spc; session.menu.disassembly.memory = &session.menu.disassembly.memory[-earlyterm.display.ws_row / 2]; session.menu.disassembly.print_offset.horizontal = -4; session.menu.disassembly.print_offset.vertical = 0; session.menu.disassembly.next_break = context->spc; session.menu.disassembly.next_instruction = 0x00000000; // Main loop. menu = &disasm_menu_disassembly; while (session.key.entry == 0 && session.key.optn == 0) { menu(&session); internal_GetKey(&session, &menu); } // Workaround for skip instruction if (session.key.optn == 1) { session.context->spc = session.menu.disassembly.next_break; } // Update UBC SH7305_UBC.CAR0 = session.menu.disassembly.next_break; // Update break address. SH7305_UBC.CAMR0 = 0x00000000; // Update break address. SH7305_UBC.CBR0.CE = 1; // Enable channel. icbi((void*)0xa0000000); }