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:
parent
e45ce4000d
commit
57c48f1ef9
|
@ -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
129
src/cartridge.c
Normal 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
43
src/cartridge.h
Normal 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
|
|
@ -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");
|
||||
|
|
Loading…
Reference in a new issue