pico6502 Guida per Sviluppatori
Nota: Il progetto pico6502 e in fase di sviluppo iniziale. Il framework driver e il modello di memoria sono completamente implementati e condividono la stessa architettura del picoZ80. Tuttavia, attualmente esiste solo una persona BBC Model B segnaposto — questa guida spiega come costruire su quella base per aggiungere i propri driver. Dove il pico6502 e architetturalmente identico al picoZ80, vengono forniti riferimenti incrociati alla Guida dello sviluppatore picoZ80.
Panoramica
Il firmware del pico6502 e strutturato in modo identico al firmware del picoZ80. Usa la stessa architettura dual-core RP2350B, lo stesso modello di memoria PSRAM, lo stesso sistema di configurazione JSON e lo stesso framework driver — le differenze principali sono:
- M6502CPU.c / M6502CPU.h sostituiscono Z80CPU.c / Z80CPU.h come file principali di dispatch e framework driver.
- Il 6502 non ha uno spazio di indirizzamento I/O separato — non c'e un array
ioPtr[]e nessuna sezione JSONiomap. Tutte le periferiche sono virtualizzate come blocchi tipoFUNCnella mappa di memoria da 64 KB. - L'interfaccia bus PIO (
M6502.pio) implementa il clock bifase PHI1/PHI2 anziche il modello a clock singolo dello Z80. - La directory target di compilazione e
BaseM6502anzicheBaseZ80. - La chiave della sezione CPU JSON e
"6502"anziche"z80".
Tutto il resto — il pattern di coda inter-core, i callback del ciclo di vita dei driver (
reset_ptr, poll_ptr, task_ptr), la tabella di registrazione virtualFuncMap[], le costanti tipo blocco memoria, la struct t_6502PSRAM, il protocollo del coprocessore ESP32 e il sistema di compilazione — e condiviso con il codebase del picoZ80.
Albero dei sorgenti
Tutto il codice sorgente si trova sotto
projects/tzpuPico/ nella radice del repository. Il layout seguente evidenzia i file specifici del pico6502:
tzpuPico/
├── CMakeLists.txt File di compilazione di livello superiore
├── src/
│ ├── CMakeLists.txt File di compilazione a livello sorgente — aggiungere nuovi file driver qui
│ ├── M6502CPU.c *** FILE CHIAVE: dispatch 6502, framework driver, virtualFuncMap
│ ├── M6502CPU.h (legacy — incluso via include/)
│ ├── M6502.c Inizializzazione PIO e punti di ingresso cicli bus
│ ├── M6502.pio Programmi PIO: clock, addr, data, cycle, fetch, read, write, irq, nmi, so
│ ├── Z80CPU.c / Z80CPU.h Controparte Z80 (non usata per le compilazioni pico6502)
│ ├── FSPI.c / FSPI.h Interfaccia Flash SPI (condivisa)
│ ├── ESP.c / ESP.h Livello comunicazione ESP32 (condiviso)
│ ├── psram.c / psram.h Allocazione e gestione PSRAM (condivisa)
│ ├── cJSON.c / cJSON.h Parser JSON per config.json (condiviso)
│ ├── include/
│ │ ├── M6502CPU.h *** FILE CHIAVE: tutte le definizioni tipo e macro 6502
│ │ ├── M6502.h Definizioni helper PIO
│ │ └── drivers/
│ │ └── BBC/
│ │ └── ModelB.h Header driver BBC Model B (segnaposto iniziale)
│ ├── drivers/
│ │ └── BBC/
│ │ └── ModelB.c *** DRIVER ESEMPIO/SEGNAPOSTO (persona BBC Model B)
│ └── model/
│ ├── BaseM6502/
│ │ ├── CMakeLists.txt Target compilazione per modello
│ │ ├── main.c Punto di ingresso (lancio Core 0 + Core 1)
│ │ ├── main_memmap_partition_1.ld Script linker per Slot 1
│ │ └── main_memmap_partition_2.ld Script linker per Slot 2
│ └── Bootloader/
│ ├── CMakeLists.txt
│ └── main.c Bootloader condiviso (stesso del picoZ80)
└── esp32/
├── CMakeLists.txt
└── main/
└── ... Firmware ESP32 (condiviso con picoZ80)
Differenze chiave dal picoZ80
Nessuno spazio I/O separato
La differenza architetturale piu importante e che il 6502 non ha istruzioni
IN/OUT e nessun segnale IORQ. Ogni periferica deve apparire da qualche parte nella mappa di memoria da 64 KB. Nel picoZ80, le periferiche virtuali possono essere registrate tramite memioPtr[] (mappate in memoria) o ioPtr[] (mappate in I/O). Nel pico6502 c'e solo memioPtr[] — ma poiche tutti gli accessi periferici passano attraverso il bus memoria, questo copre tutti i casi.
La struct
t_6502PSRAM quindi non ha un array ioPtr[]. La configurazione JSON non ha un array "io". Il loop di dispatch in M6502CPU.c controlla solo l'array _membankPtr[] e, per i blocchi MEMBANK_TYPE_FUNC, chiama l'handler memioPtr[] corrispondente.
Struct t_6502PSRAM
Equivalente a
t_Z80PSRAM nel picoZ80, ma senza l'array ioPtr[]:
// src/include/M6502CPU.h (semplificato)
typedef struct {
uint8_t RAM[MAX_MEMORY_BANKS * MEMORY_PAGE_SIZE]; // 64 banchi x 64 KB = 4 MB area RAM/ROM
MemoryFunc memPtr[MEMORY_PAGE_SIZE]; // 64K reindirizzamento lettura per byte (tipo PTR)
MemoryFunc memioPtr[MEMORY_PAGE_SIZE]; // 64K array handler mappati memoria (tipo FUNC)
// NOTA: nessun ioPtr[] — il 6502 non ha spazio I/O separato
} t_6502PSRAM;
Firma della funzione handler
// Handler chiamato per i blocchi MEMBANK_TYPE_FUNC ad ogni accesso typedef uint8_t (*MemoryFunc)(M6502CPU *cpu, bool read, uint16_t addr, uint8_t data); // Parametri: // cpu — puntatore alla struct M6502CPU (accesso PSRAM, stato, code tramite questo) // read — true per ciclo lettura 6502 (RNW=1), false per ciclo scrittura (RNW=0) // addr — indirizzo 16 bit che ha attivato questo handler // data — byte scritto (significativo solo quando read=false) // Ritorno: // byte da posizionare sul bus dati (significativo solo quando read=true)
Framework driver
Il framework driver in
M6502CPU.c e strutturalmente identico al framework driver del picoZ80. Fare riferimento alla sezione Guida dello sviluppatore picoZ80 — Framework driver per la descrizione completa della tabella di registrazione virtualFuncMap[], del flusso di inizializzazione a due passaggi e dei callback del ciclo di vita dei driver.
| picoZ80 | pico6502 | Note |
|---|---|---|
struct Z80CPU |
struct M6502CPU |
Stessi campi, stesso layout |
Z80CPU_getVirtualFunc() |
M6502CPU_getVirtualFunc() |
Stessa logica di ricerca |
Z80CPU_cpu() |
M6502CPU_cpu() |
Punto ingresso loop Core 1 |
Z80CPU_readMem() |
M6502CPU_readMem() |
Dispatch lettura memoria |
Z80CPU_writeMem() |
M6502CPU_writeMem() |
Dispatch scrittura memoria |
Z80CPU_readIO() |
— | Nessun equivalente — il 6502 non ha spazio I/O |
Z80CPU_writeIO() |
— | Nessun equivalente — il 6502 non ha spazio I/O |
cpu->_z80PSRAM |
cpu->_6502PSRAM |
Puntatore struct PSRAM |
Scrivere un nuovo driver
Il processo per scrivere un driver pico6502 e identico a quello del picoZ80 descritto nella Guida dello sviluppatore picoZ80 — Scrivere un nuovo driver. I sei passaggi sono gli stessi:
- Creare un file header in
src/include/drivers/<Family>/MyDriver.h - Creare un file di implementazione in
src/drivers/<Family>/MyDriver.c - Aggiungere il file sorgente a
src/CMakeLists.txt - Includere il driver in
M6502CPU.csotto una guardia#ifdef INCLUDE_<FAMILY>_DRIVERS - Registrare il driver in
virtualFuncMap[]inM6502CPU.c - Aggiungere una voce driver JSON in
config.json
La differenza chiave e che anziche un parametro
Z80CPU *cpu, tutte le funzioni ricevono un parametro M6502CPU *cpu, e si accede alla PSRAM tramite cpu->_6502PSRAM anziche cpu->_z80PSRAM. Non ci sono slot ioPtr[] da installare — tutte le periferiche virtuali sono registrate in memioPtr[].
Template driver minimo
Quanto segue mostra un driver periferica 6502 minimo — un 6522 VIA (Versatile Interface Adapter) virtualizzato all'indirizzo
0xC000–0xC00F:
// 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"
// --- Stato interno ---
typedef struct {
uint8_t regs[16]; // Registri interni VIA (ORB, ORA, DDRB, DDRA, T1CL, T1CH, ...)
bool irqPending;
} t_VIA6522State;
static t_VIA6522State ViaState = { .irqPending = false };
// --- Handler memoria (chiamato per ogni accesso a 0xC000–0xC00F) ---
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];
}
else
{
ViaState.regs[reg] = data;
return 0;
}
}
// --- Handler reset ---
static uint8_t VIA6522_Reset(M6502CPU *cpu)
{
memset(&ViaState.regs, 0, sizeof(ViaState.regs));
ViaState.irqPending = false;
return 0;
}
// --- Funzione init ---
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: Inizializzato a 0xC000–0xC00F\n");
return 1;
}
Pattern hook memoria
Poiche il 6502 non ha spazio I/O, tutti i pattern hook usano
memioPtr[]. I pattern sono gli stessi descritti nella Guida dello sviluppatore picoZ80 — Pattern hook memoria, con il pattern handler porta I/O sostituito da un handler mappato in memoria a qualsiasi intervallo di indirizzi.
Errori comuni
- Installare un handler in ioPtr anziche memioPtr. Il pico6502 non ha un array
ioPtr[]. Tutti gli handler periferiche vanno inmemioPtr[]. - Aspettarsi una chiamata dispatch I/O. Non esiste
M6502CPU_readIO()oM6502CPU_writeIO(). Se state portando un driver Z80, spostate tutti gli handler inmemioPtr[]. - Bloccare in un handler. Qualsiasi chiamata a
debugf,sleep_msofopenda un handler blocchera il Core 1 e corrompe il timing bus del 6502. - Nome virtualFuncMap non corrispondente. Il campo JSON
"name"e confrontato senza distinzione maiuscole/minuscole con la tabellavirtualFuncMap[]. - Dimenticare di impostare il tipo blocco a FUNC. Installare un handler in
memioPtr[]non ha effetto se le voci_membankPtr[]corrispondenti mostrano ancoraMEMBANK_TYPE_RAMoMEMBANK_TYPE_ROM.
Siti di riferimento
| Risorsa | Link |
|---|---|
| Pagina progetto pico6502 | /pico6502/ |
| Manuale utente pico6502 | /pico6502-usermanual/ |
| Guida tecnica pico6502 | /pico6502-technicalguide/ |
| Guida sviluppatore picoZ80 | /picoz80-developersguide/ |
| Pagina progetto picoZ80 | /picoz80/ |
| Scheda tecnica RP2350 | datasheets.raspberrypi.com |
| Scheda tecnica MOS 6502 | archive.org |
Avviso normativo wireless
Questo dispositivo incorpora un modulo wireless ESP32-S3-PICO-1 che trasmette nella banda ISM a 2,4 GHz, rendendolo un emettitore intenzionale secondo le normative sulle radiofrequenze a livello mondiale (incluso FCC Part 15 Subpart C negli Stati Uniti e la Direttiva Apparecchiature Radio 2014/53/EU nell'Unione Europea).
Sebbene il modulo ESP32-S3-PICO-1 stesso possieda certificazioni normative preesistenti (FCC, CE e altre), tali certificazioni a livello di modulo non si estendono automaticamente a un prodotto finito che incorpora il modulo. L'esenzione per moduli pre-certificati consente agli hobbisti individuali di costruire un numero limitato di dispositivi per uso personale, sperimentale o educativo senza ottenere un'autorizzazione separata per l'apparecchiatura.
Limitazioni importanti
E responsabilita esclusiva del costruttore assicurarsi che qualsiasi dispositivo costruito da questi design sia conforme a tutte le normative sulle radiofrequenze applicabili nella propria giurisdizione. L'autore fornisce questi design per uso personale, educativo e hobbistico e non garantisce che un dispositivo costruito da essi soddisfi i requisiti normativi per la distribuzione commerciale.
- I dispositivi assemblati non devono essere venduti, offerti in vendita, regalati o altrimenti distribuiti a terzi a meno che il prodotto finito non sia stato testato indipendentemente e abbia ottenuto la propria autorizzazione per l'apparecchiatura nella giurisdizione pertinente.
- La costruzione di questo progetto per uso personale in quantita limitate e generalmente consentita in base alle disposizioni per hobbisti e uso sperimentale (es. FCC § 15.23), a condizione che il dispositivo non causi interferenze dannose.
- I requisiti normativi variano da paese a paese. I costruttori al di fuori degli Stati Uniti dovrebbero consultare la propria autorita nazionale per le radiofrequenze per le regole applicabili.
E responsabilita esclusiva del costruttore assicurarsi che qualsiasi dispositivo costruito da questi design sia conforme a tutte le normative sulle radiofrequenze applicabili nella propria giurisdizione. L'autore fornisce questi design per uso personale, educativo e hobbistico e non garantisce che un dispositivo costruito da essi soddisfi i requisiti normativi per la distribuzione commerciale.