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

Files at this revision

API Documentation at this revision

Comitter:
davervw
Date:
Wed Apr 15 05:33:58 2020 +0000
Parent:
6:65f96b9dd1d3
Child:
8:d356d6930bdb
Commit message:
Banking ROM/RAM/IO/CHARSET implemented

Changed in this revision

emuc64.cpp Show annotated file Show diff for this revision Revisions of this file
emuc64.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
diff -r 65f96b9dd1d3 -r dce21deeac6c emuc64.cpp
--- 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)
diff -r 65f96b9dd1d3 -r dce21deeac6c emuc64.h
--- a/emuc64.h	Mon Apr 13 07:24:08 2020 +0000
+++ b/emuc64.h	Wed Apr 15 05:33:58 2020 +0000
@@ -33,6 +33,6 @@
 
 #pragma once
 
-extern void C64_Init(const char* basic_file, const char* kernal_file);
+extern void C64_Init(const char* basic_file, const char* chargen_file, const char* kernal_file);
 extern char* StartupPRG;
 extern void keyboard_task(void const *); // enhancement for ARM MBED USBHOST
\ No newline at end of file
diff -r 65f96b9dd1d3 -r dce21deeac6c main.cpp
--- a/main.cpp	Mon Apr 13 07:24:08 2020 +0000
+++ b/main.cpp	Wed Apr 15 05:33:58 2020 +0000
@@ -49,7 +49,7 @@
 {
     printf("\n");
     printf("C64-stm429_discovery\n");
-	printf("C64 Emu6502 (for STM32F429 Discovery), version 1.01\n");
+	printf("C64 Emu6502 (for STM32F429 Discovery), version 1.2\n");
 	printf("Copyright (c) 2020 by David R. Van Wagner\n");
 	printf("Open Source - MIT License\n");
 	printf("github.com/davervw\n");
@@ -60,7 +60,7 @@
 	printf("   STM32F429 BSP\n");
 	printf("\n");
 	//StartupPRG = "/local/guess2.prg";
-	C64_Init("/local/basic", "/local/kernal");
+	C64_Init("/local/basic", "/local/chargen", "/local/kernal");
 
     Thread keyboardTask(keyboard_task, NULL, osPriorityNormal, 1024 * 4);
     Thread executeTask(execute_task, NULL, osPriorityNormal, 1024 * 4);