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:
7:dce21deeac6c
Parent:
6:65f96b9dd1d3
Child:
9:a0c6747e539f
--- a/emuc64.cpp	Mon Apr 13 07:24:08 2020 +0000
+++ b/emuc64.cpp	Wed Apr 15 05:33:58 2020 +0000
@@ -1010,9 +1010,10 @@
 
 static byte io[io_size];
 
-void C64_Init(const char* basic_file, const char* kernal_file)
+void C64_Init(const char* basic_file, const char* chargen_file, const char* kernal_file)
 {
 	//File_ReadAllBytes(basic_rom, sizeof(basic_rom), basic_file);
+	//File_ReadAllBytes(chargen_rom, sizeof(chargen_rom), chargen_file);
 	//File_ReadAllBytes(kernal_rom, sizeof(kernal_rom), kernal_file);
 
 	for (int i = 0; i < sizeof(ram); ++i)
@@ -1021,6 +1022,10 @@
 		color_nybles[i] = 0;
 	for (int i = 0; i < sizeof(io); ++i)
 		io[i] = 0;
+
+	// initialize DDR and memory mapping to defaults
+	ram[0] = 0xEF;
+	ram[1] = 0x07;
 }
 
 int C64ColorToLCDColor(byte value)
@@ -1090,32 +1095,45 @@
 
 byte GetMemory(ushort addr)
 {
-	if (addr < sizeof(ram) && (addr < basic_addr || (addr >= open_addr && addr < open_addr + open_size)))
+	if (addr <= sizeof(ram) - 1
+		  && (
+			  addr < basic_addr // always RAM
+			  || (addr >= open_addr && addr < open_addr + open_size) // always open RAM C000.CFFF
+			  || (((ram[1] & 3) != 3) && addr >= basic_addr && addr < basic_addr + sizeof(basic_rom)) // RAM banked instead of BASIC
+			  || (((ram[1] & 2) == 0) && addr >= kernal_addr && addr <= kernal_addr + sizeof(kernal_rom) - 1) // RAM banked instead of KERNAL
+			  || (((ram[1] & 3) == 0) && addr >= io_addr && addr < io_addr + io_size) // RAM banked instead of IO
+		  )
+		)
 		return ram[addr];
 	else if (addr >= basic_addr && addr < basic_addr + sizeof(basic_rom))
 		return basic_rom[addr - basic_addr];
-	else if (addr >= color_addr && addr < color_addr + sizeof(color_nybles))
-		return color_nybles[addr - color_addr];
-	else if (addr == 0xDC01)
+	else if (addr >= io_addr && addr < io_addr + io_size)
 	{
-		int value = 0;
-		
-		for (int i=0; i<9; ++i)
+		if ((ram[1] & 4) == 0)
+			return chargen_rom[addr - io_addr];
+		else if (addr >= color_addr && addr < color_addr + sizeof(color_nybles))
+			return color_nybles[addr - color_addr] | 0xF0;
+		else if (addr == 0xDC01)
 		{
-			if (scan_codes[i] < 64)
+			int value = 0;
+			
+			for (int i=0; i<9; ++i)
 			{
-				int col = scan_codes[i] / 8;
-				int row = scan_codes[i] % 8;
-				
-				if ((io[0xC00] & (1 << col)) == 0)
-					value |= (1 << row);
+				if (scan_codes[i] < 64)
+				{
+					int col = scan_codes[i] / 8;
+					int row = scan_codes[i] % 8;
+					
+					if ((io[0xC00] & (1 << col)) == 0)
+						value |= (1 << row);
+				}
 			}
+			
+			return ~value;
 		}
-		
-		return ~value;
+		else
+			return io[addr - io_addr];
 	}
-	else if (addr >= io_addr && addr < io_addr + io_size)
-		return io[addr - io_addr];
 	else if (addr >= kernal_addr && addr <= kernal_addr + sizeof(kernal_rom)-1)
 		return kernal_rom[addr - kernal_addr];
 	else
@@ -1124,7 +1142,13 @@
 
 void SetMemory(ushort addr, byte value)
 {
-	if (addr <= sizeof(ram)-1 && (addr < io_addr || (addr >= kernal_addr && addr <= kernal_addr + sizeof(kernal_rom)-1)))
+	if (addr <= sizeof(ram) - 1
+		&& (
+			addr < io_addr // RAM, including open RAM, and RAM under BASIC
+			|| (addr >= kernal_addr && addr <= kernal_addr + sizeof(kernal_rom) - 1) // RAM under KERNAL
+			|| (((ram[1] & 7) == 0) && addr >= io_addr && addr < io_addr + io_size) // RAM banked in instead of IO
+			)
+		)
 	{
 		ram[addr] = value;
 		if (addr >= 1024 && addr < 2024)