static void memory_error(_u32 address, BOOL read) { debug_abort_memory = TRUE; if (filter_mem) { if (debug_mask_memory_error_messages) return; if (read) system_debug_message("Memory Exception: Read from %06X", address); else system_debug_message("Memory Exception: Write to %06X", address); } }
void WrZ80(_u16 address, _u8 value) { if (address <= 0x0FFF) { ram[0x7000 + address] = value; return; } if (address == 0x8000) { #ifdef NEOPOP_DEBUG if (filter_sound) system_debug_message("z80 -> TLCS900h: Write ... %02X", value); #endif ram[0xBC] = value; return; } if (address == 0x4001) { Write_SoundChipTone(value); return; } if (address == 0x4000) { Write_SoundChipNoise(value); return; } if (address == 0xC000 && (statusIFF() <= (ram[0x71] & 0x7))) { interrupt(6); // Z80 Int. if (ram[0x007C] == 0x0C) DMA_update(0); else { if (ram[0x007D] == 0x0C) DMA_update(1); else { if (ram[0x007E] == 0x0C) DMA_update(2); else { if (ram[0x007F] == 0x0C) DMA_update(3); }}} } }
//----------------------------------------------------------------------------- // state_store() //----------------------------------------------------------------------------- void state_store(char* filename) { NEOPOPSTATE0050 state; int i,j; //Build a state description state.valid_state_id = 0x0050; memcpy(&state.header, rom_header, sizeof(RomHeader)); state.eepromStatusEnable = eepromStatusEnable; //TLCS-900h Registers state.pc = pc; state.sr = sr; state.f_dash = f_dash; for (i = 0; i < 4; i++) { state.gpr[i] = gpr[i]; for (j = 0; j < 4; j++) state.gprBank[i][j] = gprBank[i][j]; } //Z80 Registers memcpy(&state.Z80_regs, &Z80_regs, sizeof(Z80)); //Sound Chips memcpy(&state.toneChip, &toneChip, sizeof(SoundChip)); memcpy(&state.noiseChip, &noiseChip, sizeof(SoundChip)); //Memory memcpy(&state.ram, ram, 0xC000); //Timers state.timer_hint = timer_hint; for (i = 0; i < 4; i++) //Up-counters state.timer[i] = timer[i]; state.timer_clock0 = timer_clock0; state.timer_clock1 = timer_clock1; state.timer_clock2 = timer_clock2; state.timer_clock3 = timer_clock3; //DMA for (i = 0; i < 4; i++) { state.dmaS[i] = dmaS[i]; state.dmaD[i] = dmaD[i]; state.dmaC[i] = dmaC[i]; state.dmaM[i] = dmaM[i]; } #ifdef NEOPOP_DEBUG system_debug_message("Saving State ..."); #endif system_io_state_write(filename, (_u8*)&state, sizeof(NEOPOPSTATE0050)); }
_u8 RdZ80(_u16 address) { if (address <= 0xFFF) return ram[0x7000 + address]; if (address == 0x8000) { #ifdef NEOPOP_DEBUG if (filter_sound) system_debug_message("z80 <- TLCS900h: Read ... %02X", ram[0xBC]); #endif return ram[0xBC]; } return 0; }
void __cdecl instruction_error(char* vaMessage,...) { char message[1000]; va_list vl; va_start(vl, vaMessage); vsprintf(message, vaMessage, vl); va_end(vl); #ifdef NEOPOP_DEBUG system_debug_message(message); debug_abort_instruction = TRUE; #else system_message("[PC %06X] %s", pc, message); #endif }
//----------------------------------------------------------------------------- // state_restore() //----------------------------------------------------------------------------- void state_restore(char* filename) { _u16 version; if (system_io_state_read(filename, (_u8*)&version, sizeof(_u16))) { switch(version) { case 0x0050: read_state_0050(filename); break; default: system_message(system_get_string(IDS_BADSTATE)); return; } #ifdef NEOPOP_DEBUG system_debug_message("Restoring State ..."); system_debug_refresh(); #endif } }
void emulate_debug(BOOL dis_TLCS900h, BOOL dis_Z80) { _u32 storePC = pc; debug_abort_memory = FALSE; debug_abort_instruction = FALSE; system_debug_history_add(); //For the debugger if (dis_TLCS900h) { char* s; //Disassemble TLCS-900h _u32 oldpc = pc; s = disassemble(); system_debug_message(s); system_debug_message_associate_address(oldpc); free(s); pc = oldpc; } if (dis_Z80) { //Disassemble Z80 if (Z80ACTIVE) { char* s; _u16 pc = Z80_getReg(Z80_REG_PC); _u16 store_pc = pc; //Disassemble s = Z80_disassemble(&pc); system_debug_message(s); system_debug_message_associate_address(store_pc + 0x7000); free(s); } } debug_abort_memory = FALSE; debug_abort_instruction = FALSE; //================== // EMULATE //================== { //TLCS900h instruction updateTimers(TLCS900h_interpret()); //Z80 Instruction if (Z80ACTIVE) Z80EMULATE; } //Check register code error if (rErr != RERR_VALUE) instruction_error("Invalid register code used."); //Memory Exception if (debug_abort_memory && filter_mem) { _u32 oldpc = pc; char* s; debug_abort_memory = FALSE; //Try to disassemble the erroneous instruction pc = storePC; debug_mask_memory_error_messages = TRUE; s = disassemble(); debug_mask_memory_error_messages = FALSE; if (debug_abort_memory == FALSE) { system_debug_message("Stopped due to memory exception caused by"); system_debug_message(" %s", s); system_debug_message_associate_address(storePC); system_debug_message("\n"); } else { system_debug_message("Stopped due to memory exception caused at %06X", storePC); system_debug_message_associate_address(storePC); } free(s); pc = oldpc; system_debug_stop(); system_debug_refresh(); return; } //Unimplemented Instruction if (debug_abort_instruction) { _u32 oldpc = pc; char* s; debug_abort_memory = FALSE; //Try to disassemble the erroneous instruction pc = storePC; debug_mask_memory_error_messages = TRUE; s = disassemble(); debug_mask_memory_error_messages = FALSE; if (debug_abort_memory == FALSE) { system_debug_message("Stopped due to instruction"); system_debug_message(" %s", s); system_debug_message_associate_address(storePC); system_debug_message("\n"); } else { system_debug_message("Stopped due to instruction at %06X", storePC); system_debug_message_associate_address(storePC); } free(s); pc = oldpc; system_debug_stop(); system_debug_refresh(); return; } }