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

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;