pico6502 Guia del Desarrollador
Nota: El proyecto pico6502 esta en fase de desarrollo inicial. El framework de drivers y el modelo de memoria estan completamente implementados y comparten la misma arquitectura que el picoZ80. Sin embargo, actualmente solo existe una persona BBC Model B de relleno — esta guia explica como construir sobre esa base para agregar sus propios drivers. Donde el pico6502 es arquitectonicamente identico al picoZ80, se proporcionan referencias cruzadas a la Guia del desarrollador picoZ80.
Vision general
El firmware del pico6502 esta estructurado de manera identica al firmware del picoZ80. Usa la misma arquitectura de doble nucleo RP2350B, el mismo modelo de memoria PSRAM, el mismo sistema de configuracion JSON y el mismo framework de drivers — las diferencias principales son:
- M6502CPU.c / M6502CPU.h reemplazan a Z80CPU.c / Z80CPU.h como archivos principales de despacho y framework de drivers.
- El 6502 no tiene un espacio de direcciones I/O separado — no hay array
ioPtr[]ni seccion JSONiomap. Todos los perifericos se virtualizan como bloques tipoFUNCen el mapa de memoria de 64 KB. - La interfaz de bus PIO (
M6502.pio) implementa reloj bifasico PHI1/PHI2 en lugar del modelo de reloj unico del Z80. - El directorio objetivo de compilacion es
BaseM6502en lugar deBaseZ80. - La clave de seccion CPU JSON es
"6502"en lugar de"z80".
Todo lo demas — el patron de cola inter-nucleos, los callbacks del ciclo de vida de drivers (
reset_ptr, poll_ptr, task_ptr), la tabla de registro virtualFuncMap[], las constantes de tipo de bloque de memoria, la struct t_6502PSRAM, el protocolo del coprocesador ESP32 y el sistema de compilacion — se comparte con el codebase del picoZ80.
Arbol de codigo fuente
Todo el codigo fuente se encuentra bajo
projects/tzpuPico/ en la raiz del repositorio. El layout a continuacion resalta los archivos especificos del pico6502:
tzpuPico/
├── CMakeLists.txt Archivo de compilacion de nivel superior
├── src/
│ ├── CMakeLists.txt Archivo de compilacion a nivel fuente — agregar nuevos archivos de driver aqui
│ ├── M6502CPU.c *** ARCHIVO CLAVE: despacho 6502, framework drivers, virtualFuncMap
│ ├── M6502.pio Programas PIO: clock, addr, data, cycle, fetch, read, write, irq, nmi, so
│ ├── include/
│ │ ├── M6502CPU.h *** ARCHIVO CLAVE: todas las definiciones de tipo y macros 6502
│ │ └── drivers/
│ │ └── BBC/
│ │ └── ModelB.h Header del driver BBC Model B (relleno inicial)
│ ├── drivers/
│ │ └── BBC/
│ │ └── ModelB.c *** DRIVER EJEMPLO/RELLENO (persona BBC Model B)
│ └── model/
│ ├── BaseM6502/
│ │ ├── CMakeLists.txt Objetivos de compilacion por modelo
│ │ └── main.c Punto de entrada (lanzamiento Core 0 + Core 1)
│ └── Bootloader/
│ └── main.c Bootloader compartido (mismo del picoZ80)
└── esp32/
└── main/
└── ... Firmware ESP32 (compartido con picoZ80)
Diferencias clave con el picoZ80
Sin espacio de direcciones I/O separado
La diferencia arquitectonica mas importante es que el 6502 no tiene instrucciones
IN/OUT ni senal IORQ. Cada periferico debe aparecer en algun lugar del mapa de memoria de 64 KB. En el picoZ80, los perifericos virtuales pueden registrarse via memioPtr[] (mapeados en memoria) o ioPtr[] (mapeados en I/O). En el pico6502 solo existe memioPtr[].
Struct t_6502PSRAM
// src/include/M6502CPU.h (simplificado)
typedef struct {
uint8_t RAM[MAX_MEMORY_BANKS * MEMORY_PAGE_SIZE]; // 64 bancos x 64 KB = 4 MB area RAM/ROM
MemoryFunc memPtr[MEMORY_PAGE_SIZE]; // 64K redireccion lectura por byte (tipo PTR)
MemoryFunc memioPtr[MEMORY_PAGE_SIZE]; // 64K array handlers mapeados memoria (tipo FUNC)
// NOTA: sin ioPtr[] — el 6502 no tiene espacio I/O separado
} t_6502PSRAM;
Firma de la funcion handler
// Handler llamado para bloques MEMBANK_TYPE_FUNC en cada acceso typedef uint8_t (*MemoryFunc)(M6502CPU *cpu, bool read, uint16_t addr, uint8_t data); // Parametros: // cpu — puntero a la struct M6502CPU // read — true para ciclo lectura 6502 (RNW=1), false para ciclo escritura (RNW=0) // addr — direccion 16 bits que activo este handler // data — byte escrito (solo significativo cuando read=false) // Retorno: // byte a colocar en el bus de datos (solo significativo cuando read=true)
Framework de drivers
El framework de drivers en
M6502CPU.c es estructuralmente identico al del picoZ80. Consulte la seccion Guia del desarrollador picoZ80 — Framework de drivers para la descripcion completa.
| picoZ80 | pico6502 | Notas |
|---|---|---|
struct Z80CPU |
struct M6502CPU |
Mismos campos, mismo layout |
Z80CPU_getVirtualFunc() |
M6502CPU_getVirtualFunc() |
Misma logica de busqueda |
Z80CPU_cpu() |
M6502CPU_cpu() |
Punto de entrada del bucle Core 1 |
Z80CPU_readMem() |
M6502CPU_readMem() |
Despacho lectura memoria |
Z80CPU_writeMem() |
M6502CPU_writeMem() |
Despacho escritura memoria |
Z80CPU_readIO() |
— | Sin equivalente — el 6502 no tiene espacio I/O |
Z80CPU_writeIO() |
— | Sin equivalente — el 6502 no tiene espacio I/O |
cpu->_z80PSRAM |
cpu->_6502PSRAM |
Puntero a struct PSRAM |
Escribir un nuevo driver
El proceso para escribir un driver pico6502 es identico al del picoZ80 descrito en la Guia del desarrollador picoZ80 — Escribir un nuevo driver. Los seis pasos son los mismos:
- Crear un archivo header en
src/include/drivers/<Family>/MyDriver.h - Crear un archivo de implementacion en
src/drivers/<Family>/MyDriver.c - Agregar el archivo fuente a
src/CMakeLists.txt - Incluir el driver en
M6502CPU.cbajo una guardia#ifdef INCLUDE_<FAMILY>_DRIVERS - Registrar el driver en
virtualFuncMap[]enM6502CPU.c - Agregar una entrada de driver JSON en
config.json
La diferencia clave es que en lugar de un parametro
Z80CPU *cpu, todas las funciones reciben un parametro M6502CPU *cpu, y se accede a la PSRAM via cpu->_6502PSRAM en lugar de cpu->_z80PSRAM. No hay slots ioPtr[] para instalar — todos los perifericos virtuales se registran en memioPtr[].
Plantilla de driver minima
// src/include/drivers/BBC/VIA6522.h #ifndef VIA6522_H #define VIA6522_H #include "M6502CPU.h" int VIA6522_Init(M6502CPU *cpu, t_drvConfig *drvConfig, int pass); #endif
// src/drivers/BBC/VIA6522.c
#include "../../include/M6502CPU.h"
#include "../../include/drivers/BBC/VIA6522.h"
typedef struct {
uint8_t regs[16];
bool irqPending;
} t_VIA6522State;
static t_VIA6522State ViaState = { .irqPending = false };
static uint8_t VIA6522_Handler(M6502CPU *cpu, bool read, uint16_t addr, uint8_t data)
{
uint8_t reg = addr & 0x0F;
if(read) return ViaState.regs[reg];
ViaState.regs[reg] = data;
return 0;
}
static uint8_t VIA6522_Reset(M6502CPU *cpu)
{
memset(&ViaState.regs, 0, sizeof(ViaState.regs));
ViaState.irqPending = false;
return 0;
}
int VIA6522_Init(M6502CPU *cpu, t_drvConfig *drvConfig, int pass)
{
if(pass == 0) return (strcasecmp(drvConfig->name, "via6522") == 0) ? 1 : 0;
for(uint16_t addr = 0xC000; addr <= 0xC00F; addr++)
cpu->_6502PSRAM->memioPtr[addr] = VIA6522_Handler;
cpu->reset_ptr = VIA6522_Reset;
debugf("VIA6522: Inicializado en 0xC000–0xC00F\n");
return 1;
}
Registro en virtualFuncMap
static const t_VirtualFuncMap virtualFuncMap[] = {
{ "BBCModelB", BBCModelB_Init }, // entrada existente
{ "via6522", VIA6522_Init }, // su nuevo driver
{ NULL, NULL } // terminador
};
Patrones de hooks de memoria
Como el 6502 no tiene espacio I/O, todos los patrones de hooks usan
memioPtr[]. Los patrones son los mismos descritos en la Guia del desarrollador picoZ80 — Patrones de hooks de memoria.
Errores comunes
- Instalar un handler en ioPtr en lugar de memioPtr. El pico6502 no tiene array
ioPtr[]. Todos los handlers de perifericos van enmemioPtr[]. - Esperar una llamada de despacho I/O. No existe
M6502CPU_readIO()niM6502CPU_writeIO(). - Bloquear en un handler. Cualquier llamada a
debugf,sleep_msofopendesde un handler bloqueara el Core 1 y corrompera el timing de bus del 6502. - Nombre virtualFuncMap no coincidente. El campo JSON
"name"se compara sin distincion de mayusculas/minusculas con la tablavirtualFuncMap[]. - Olvidar establecer el tipo de bloque a FUNC. Instalar un handler en
memioPtr[]no tiene efecto si las entradas_membankPtr[]correspondientes aun muestranMEMBANK_TYPE_RAMoMEMBANK_TYPE_ROM.
Sitios de referencia
| Recurso | Enlace |
|---|---|
| Pagina del proyecto pico6502 | /pico6502/ |
| Manual de usuario pico6502 | /pico6502-usermanual/ |
| Guia tecnica pico6502 | /pico6502-technicalguide/ |
| Guia del desarrollador picoZ80 | /picoz80-developersguide/ |
| Pagina del proyecto picoZ80 | /picoz80/ |
| Hoja de datos RP2350 | datasheets.raspberrypi.com |
| Hoja de datos MOS 6502 | archive.org |
Aviso regulatorio inalambrico
Este dispositivo incorpora un modulo inalambrico ESP32-S3-PICO-1 que transmite en la banda ISM de 2,4 GHz, convirtiendolo en un emisor intencional segun las regulaciones de radiofrecuencia a nivel mundial.
Limitaciones importantes
Es responsabilidad exclusiva del constructor asegurarse de que cualquier dispositivo construido a partir de estos disenos cumpla con todas las regulaciones de radiofrecuencia aplicables en su jurisdiccion.
- Los dispositivos ensamblados no deben ser vendidos o distribuidos a terceros sin autorizacion de equipo propia.
- La construccion para uso personal en cantidades limitadas esta generalmente permitida bajo disposiciones para aficionados (ej. FCC § 15.23).
Es responsabilidad exclusiva del constructor asegurarse de que cualquier dispositivo construido a partir de estos disenos cumpla con todas las regulaciones de radiofrecuencia aplicables en su jurisdiccion.