Cartridge support added

Check for cartridge, identify if it's RAM or FLASH, and allow for erasing/programming the flash chip.
This commit is contained in:
Peter Weingartner 2024-08-11 21:47:50 -04:00
parent e45ce4000d
commit 57c48f1ef9
4 changed files with 211 additions and 2 deletions

View file

@ -2,7 +2,7 @@
DEBUGGER=../module/Calypsi-remote-debug/src
UNIT := F256K
MEMORY := ROM
MEMORY := RAM
# Define OS-dependent variables
@ -51,7 +51,7 @@ else ifeq ($(UNIT),F256)
else ifeq ($(UNIT),F256K)
CPU=w65816
C_SRCS_DEBUGGER=$(DEBUGGER)/agent.c $(DEBUGGER)/c256-uart.c $(DEBUGGER)/low_level_WDC65816.s
SRCS_FOR_UNIT=C256/jumptable.s C256/io_stubs.c C256/extras.s C256/iecll.s C256/interrupts.s C256/f256-cstartup.s
SRCS_FOR_UNIT=cartridge.c C256/jumptable.s C256/io_stubs.c C256/extras.s C256/iecll.s C256/interrupts.s C256/f256-cstartup.s
CFLAGS_FOR_UNIT=-DMODEL=17 -DCPU=255 --code-model large --data-model large
ifeq ($(MEMORY),ROM)

129
src/cartridge.c Normal file
View file

@ -0,0 +1,129 @@
/**
* @file cartdridge.c
* @author your name (you@domain.com)
* @brief Support for the flash cartridge
* @version 0.1
* @date 2024-08-11
*
* @copyright Copyright (c) 2024
*
*/
#include <stdbool.h>
#include "cartridge.h"
#include "timers.h"
volatile uint8_t * cartridge = ((volatile uint8_t *)0xf40000);
static short cart_id_memo = CART_ID_UNDEF;
static bool cart_rw_match(uint8_t value) {
*cartridge = value;
uint8_t new_value = *cartridge;
return (new_value == value);
}
/**
* @brief Send a command to the flash chip
*
* @param command the number of the command
*/
static void cart_flash_command(uint8_t command) {
cartridge[0x5555] = 0xaa;
cartridge[0x2aaa] = 0x55;
cartridge[0x5555] = command;
}
/**
* @brief Send the command to enter system ID mode on the flash chip
*
*/
static void cart_flash_system_id_enter() {
// Attempt to enter software ID mode on the flash cartridge
cart_flash_command(0x90);
}
/**
* @brief Send the command to exit the system ID mode on the flash chip
*
*/
static void cart_flash_system_id_exit() {
// Attempt to exit software ID mode on the flash cartridge
cart_flash_command(0xf0);
}
/**
* @brief Return a code describing the cartridge
*
* @return short the code describing the cartridge (-1 for none found)
*/
short cart_id() {
if (cart_id_memo == CART_ID_UNDEF) {
// Start off assuming we don't have anything in the slot
cart_id_memo = -1;
// Check to see if there is RAM at the first byte of the cartridge
if (cart_rw_match(0x12) && cart_rw_match(0x23) && cart_rw_match(0x34)) {
cart_id_memo = CART_ID_RAM;
} else {
// Check to see if we have a flash chip
cart_flash_system_id_enter();
// Check for the manufacturer's ID we expect (BF for Microchip)
if (cartridge[0x0000] == 0xbf) {
// Yes... get the chip ID
uint8_t chip_id = cartridge[0x0001];
if ((chip_id == 0xd5) || (chip_id == 0xd6) || (chip_id == 0xd7)) {
cart_id_memo = CART_ID_FLASH;
}
}
// Leave system ID mode, regardless
cart_flash_system_id_exit();
}
}
return cart_id_memo;
}
/**
* @brief Erase the entire flash memory
*
*/
void cart_erase() {
if (cart_id() == CART_ID_FLASH) {
cart_flash_command(0x80);
cart_flash_command(0x10);
// Wait half a second
long target_jiffies = timers_jiffies() + 30;
while (timers_jiffies() < target_jiffies) ;
}
}
/**
* @brief Write a byte to the flash memory
*
* @param address the address to write to (in CPU address space)
* @param value the byte to write to the address
*/
void cart_write(uint32_t address, uint8_t value) {
uint32_t cart_base_address = (uint32_t)cartridge;
uint32_t cart_end_address = 0xf7ffff;
uint8_t current_value = 0;
if (cart_id() == CART_ID_FLASH) {
if ((cart_base_address <= address) && (cart_end_address >= address)) {
cart_flash_command(0xa0);
// Attempt to write the data
volatile uint8_t * dest = ((volatile uint8_t *)address);
*dest = value;
// Wait for the value to show up at the destination
long target_jiffies = timers_jiffies() + 5;
while (timers_jiffies() < target_jiffies) ;
}
}
}

43
src/cartridge.h Normal file
View file

@ -0,0 +1,43 @@
/**
* @file cartridge.h
* @author your name (you@domain.com)
* @brief Support for the flash cartridge
* @version 0.1
* @date 2024-08-11
*
* @copyright Copyright (c) 2024
*
*/
#ifndef __cartridge_h__
#define __cartridge_h__
#include <stdint.h>
#define CART_ID_UNDEF -2
#define CART_ID_NONE -1
#define CART_ID_RAM 0
#define CART_ID_FLASH 1
/**
* @brief Return a code describing the cartridge
*
* @return short the code describing the cartridge (-1 for none found)
*/
extern short cart_id();
/**
* @brief Erase the entire flash memory
*
*/
extern void cart_erase();
/**
* @brief Write a byte to the flash memory
*
* @param address the address to write to (in CPU address space)
* @param value the byte to write to the address
*/
extern void cart_write(uint32_t address, uint8_t value);
#endif

View file

@ -34,6 +34,7 @@
#include "dev/txt_c256.h"
#include "dev/txt_evid.h"
#elif MODEL == MODEL_FOENIX_F256 || MODEL == MODEL_FOENIX_F256K || MODEL == MODEL_FOENIX_F256K2
#include "cartridge.h"
#include "dev/txt_f256.h"
#include "dev/kbd_f256.h"
#include "dev/sdc_f256.h"
@ -481,6 +482,42 @@ int main(int argc, char * argv[]) {
test_sysinfo();
printf("Foenix Toolbox v%d.%04d.%04d\n", VER_MAJOR, VER_MINOR, VER_BUILD);
const char * test_data = "Hello, world!";
volatile uint8_t * cartridge = ((volatile uint8_t *)0xf40000);
short cartridge_id = cart_id();
switch(cartridge_id) {
case CART_ID_NONE:
printf("No cartridge detected.\n");
break;
case CART_ID_RAM:
printf("RAM cartridge detected.\n");
break;
case CART_ID_FLASH:
printf("FLASH cartridge detected.\n");
// printf("Attempting to erase the flash cartridge.\n");
// cart_erase();
// printf("Attempting to program the flash cartridge.\n");
// for (int i = 0; i < strlen(test_data); i++) {
// cart_write(0xf40000 + i, test_data[i]);
// }
// for (int j = 0; j < strlen(test_data); j++) {
// txt_put(0, cartridge[j]);
// }
// printf("\n");
break;
default:
printf("Unable to determine whether a cartridge is present.\n");
break;
}
test_kbd();
// printf("Initializing IEC\n");