C64 emulation on STM32F429 Discovery board with builtin LCD and USB keyboard support (OTG). More info at davevw.com and/or github.com/davervw
Dependencies: LCD_DISCO_F429ZI BSP_DISCO_F429ZI USBHOST
Diff: emu6502.cpp
- Revision:
- 4:8476be802690
- Parent:
- 0:90de1cbc8a5f
- Child:
- 9:a0c6747e539f
--- a/emu6502.cpp Fri Apr 10 04:32:54 2020 +0000 +++ b/emu6502.cpp Mon Apr 13 05:36:43 2020 +0000 @@ -1,9 +1,10 @@ -// emu6502.c - Emu6502 - MOS6502 Emulator +// emu6502.cpp - Emu6502 - MOS6502 Emulator // //////////////////////////////////////////////////////////////////////////////// // -// c-simple-emu-cbm (C Portable Version) -// C64/6502 Emulator for Microsoft Windows Console +// C64-stm429_discovery +// C64/6502 Emulator targeting STM32F429 LCD/USBHOST +// [ported from c-simple-emu-cbm (C Portable Version - for console)] // // MIT License // @@ -11,7 +12,6 @@ // davevw.com // // Permission is hereby granted, free of charge, to any person obtaining a copy -// // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell @@ -36,9 +36,6 @@ #include <mbed.h> #include "emu6502.h" -// global references -extern Serial pc; - // globals byte A = 0; byte X = 0; @@ -98,9 +95,9 @@ static void BRK(byte *p_bytes) { ++PC; - PHP(); Push(HI(PC)); Push(LO(PC)); + PHP(); B = true; PC = (ushort)(GetMemory(0xFFFE) + (GetMemory(0xFFFF) << 8)); *p_bytes = 0; @@ -186,7 +183,7 @@ } } -static void ADC(byte value) +static void ADDC(byte value) { int result; if (D) @@ -491,8 +488,8 @@ static void RTI(ushort *p_addr, byte *p_bytes) { PLP(); + byte lo = Pop(); byte hi = Pop(); - byte lo = Pop(); *p_bytes = 0; // make sure caller does not increase addr by one *p_addr = (ushort)((hi << 8) | lo); } @@ -660,39 +657,55 @@ bool conditional; byte bytes; + Timer timer; + const double interrupt_time = 1.0 / 60.0 ; // 60 times per second + timer.start(); + double timer_then = timer.read(); + PC = addr; while (true) { while (true) { - bytes = 1; - //bool breakpoint = false; - //if (Breakpoints.Contains(PC)) - // breakpoint = true; - bool breakpoint = (addr == 0xFD88); - if (trace || breakpoint || step) + if (!I && (timer.read()-timer_then) >= interrupt_time) // IRQ + { + timer_then = timer.read(); // reset timer + Push(HI(PC)); + Push(LO(PC)); + PHP(); + I = true; + PC = (GetMemory(0xfffe) | (GetMemory(0xffff) << 8)); + } + else { - ushort addr2; - char line[27]; - char dis[13]; - DisassembleLong(PC, &conditional, &bytes, &addr2, dis, sizeof(dis), line, sizeof(line)); - char state[33]; - GetDisplayState(state, sizeof(state)); - char full_line[80]; - snprintf(full_line, sizeof(full_line), "%-30s%s\n", line, state); -#ifdef WIN32 - OutputDebugStringA(full_line); -#else - pc.printf("%s", full_line); -#endif - if (step) - step = step; // user can put debug breakpoint here to allow stepping - if (breakpoint) - breakpoint = breakpoint; // user can put debug breakpoint here to allow break + bytes = 1; + bool breakpoint = false; + //if (Breakpoints.Contains(PC)) + // breakpoint = true; + if (trace || breakpoint || step) + { + ushort addr2; + char line[27]; + char dis[13]; + DisassembleLong(PC, &conditional, &bytes, &addr2, dis, sizeof(dis), line, sizeof(line)); + char state[33]; + GetDisplayState(state, sizeof(state)); + char full_line[80]; + snprintf(full_line, sizeof(full_line), "%-30s%s\n", line, state); + #ifdef WIN32 + OutputDebugStringA(full_line); + #else + printf("%s", full_line); + #endif + if (step) + step = step; // user can put debug breakpoint here to allow stepping + if (breakpoint) + breakpoint = breakpoint; // user can put debug breakpoint here to allow break + } + if (ExecutePatch != 0 && !ExecutePatch()) // allow execute to be overriden at a specific address + break; } - if (ExecutePatch != 0 && !ExecutePatch()) // allow execute to be overriden at a specific address - break; } switch (GetMemory(PC)) @@ -758,23 +771,23 @@ case 0x5E: SetABSX(LSR(GetABSX(PC, &bytes)), PC, &bytes); break; case 0x60: RTS(&PC, &bytes); break; - case 0x61: ADC(GetIndX(PC, &bytes)); break; - case 0x65: ADC(GetZP(PC, &bytes)); break; + case 0x61: ADDC(GetIndX(PC, &bytes)); break; + case 0x65: ADDC(GetZP(PC, &bytes)); break; case 0x66: SetZP(ROR(GetZP(PC, &bytes)), PC, &bytes); break; case 0x68: PLA(); break; - case 0x69: ADC(GetIM(PC, &bytes)); break; + case 0x69: ADDC(GetIM(PC, &bytes)); break; case 0x6A: SetA(ROR(A)); break; case 0x6C: JMPIND(&PC, &bytes); break; - case 0x6D: ADC(GetABS(PC, &bytes)); break; + case 0x6D: ADDC(GetABS(PC, &bytes)); break; case 0x6E: SetABS(ROR(GetABS(PC, &bytes)), PC, &bytes); break; case 0x70: BVS(&PC, &conditional, &bytes); break; - case 0x71: ADC(GetIndY(PC, &bytes)); break; - case 0x75: ADC(GetZPX(PC, &bytes)); break; + case 0x71: ADDC(GetIndY(PC, &bytes)); break; + case 0x75: ADDC(GetZPX(PC, &bytes)); break; case 0x76: SetZPX(ROR(GetZPX(PC, &bytes)), PC, &bytes); break; case 0x78: SEI(); break; - case 0x79: ADC(GetABSY(PC, &bytes)); break; - case 0x7D: ADC(GetABSX(PC, &bytes)); break; + case 0x79: ADDC(GetABSY(PC, &bytes)); break; + case 0x7D: ADDC(GetABSX(PC, &bytes)); break; case 0x7E: SetABSX(ROR(GetABSX(PC, &bytes)), PC, &bytes); break; case 0x81: SetIndX(A, PC, &bytes); break;