pico6502 Guide Technique
Remarque : Le projet pico6502 est en phase de developpement initial. Le materiel, l'interface bus PIO, le modele memoire et le systeme de compilation sont entierement implementes et fonctionnels. Les pilotes de persona machine en sont a un stade precoce. Ce guide decrit l'architecture technique telle qu'elle existe aujourd'hui.
Vue d'ensemble
L'architecture technique du pico6502 est identique a celle du picoZ80 a tous egards, sauf l'interface bus CPU. Le meme processeur double coeur RP2350B, le meme modele memoire PSRAM, la meme disposition Flash, le meme coprocesseur ESP32 et le meme framework de pilotes sont partages entre les deux produits. Ce guide se concentre sur les differences specifiques au 6502 et renvoie au Guide technique du picoZ80 pour les sujets entierement partages.
Architecture materielle
Schema fonctionnel
┌─────────────────────────────────────────────────────────────────────────┐ │ pico6502 Board (v2.2) │ │ │ │ ┌───────────────┐ PIO 0: A0–A15, D0–D7 ┌───────────────────┐ │ │ │ │◄──────────────────────────►│ DIP-40 Interface │ │ │ │ RP2350B │ PIO 1: cycle/ctrl/irq │ (6502 socket) │ │ │ │ (300 MHz) │◄──────────────────────────►│ A0–A15, D0–D7 │ │ │ │ │ PIO 2: PHI1/PHI2 clock ──►│ PHI0/RNW/SYNC │ │ │ │ Core 0 │ │ IRQ/NMI/RDY/SO │ │ │ │ (USB/IO/ESP) │ └───────────────────┘ │ │ │ │◄──QSPI──►[ 8MB PSRAM ] │ │ │ Core 1 │◄──SPI───►[ 16MB Flash ] │ │ │ (6502 loop) │ │ │ │ │◄──FSPI──►┌───────────┐ │ │ │ │◄──UART──►│ ESP32 │◄──SPI──►[ SD Card ] │ │ └───────────────┘ │ (WiFi) │──────────[ Web Server ] │ │ └───────────┘ │ │ [ USB Hub ]──USB──►[ RP2350 USB Bridge ] │ └─────────────────────────────────────────────────────────────────────────┘
Composants principaux
| Composant | Reference | Specification |
|---|---|---|
| Processeur principal | RP2350B | Double Cortex-M33, jusqu’a 300 MHz, 512 Ko SRAM, 48 GPIO |
| PSRAM | SPI PSRAM | 8 Mo, interface QSPI, jusqu’a 133 MHz |
| Flash | SPI NOR Flash | 16 Mo, XIP (execution sur place) |
| Coprocesseur | ESP32-S3 | WiFi, carte SD, serveur web, UART 460,8 kbaud vers le RP2350 |
| Carte SD | FAT32 | Images ROM, images disque, config.json, fichiers web |
| Interface bus | Reseau de resistances | Resistances serie pour la translation de niveau 5 V / 3,3 V |
| Alimentation | TLV62590BV | Buck synchrone, 5 V (broche VCC) vers 3,3 V, alimentation complete de la carte |
| USB | Hub integre | Pont USB de stockage de masse RP2350 pour le flashage firmware |
Affectation des GPIO
Les affectations GPIO ci-dessous sont indicatives de la disposition typique de la carte pico6502 v2.2. Le schema KiCad (
kicad/PICO6502/PICO6502_Schematic.pdf) est la source de reference.
| GPIO | Signal | Direction | Notes |
|---|---|---|---|
| 0–15 | A0–A15 | Sortie | Bus d’adresses 6502 — pilote par PIO 0 m6502_addr |
| 16–23 | D0–D7 | Bidir | Bus de donnees 6502 — pilote/echantillonne par PIO 0 m6502_data |
| 24 | PHI0 | Entree | Entree d’horloge externe vers PIO 2 |
| 25 | PHI1 | Sortie | Sortie d’horloge phase 1 — generee par PIO 2 |
| 26 | PHI2 | Sortie | Sortie d’horloge phase 2 — generee par PIO 2 |
| 27 | RNW | Entree | Read/Not-Write — echantillonne par PIO 1 |
| 28 | SYNC | Sortie | Indicateur de recuperation d’opcode — pilote par PIO 1 |
| 29 | IRQ | Entree | Interruption masquable (actif bas) — surveille par PIO 1 |
| 30 | NMI | Entree | Interruption non masquable (actif bas) — surveille par PIO 1 |
| 31 | RDY | Entree | Signal Ready — echantillonne par PIO 1 |
| 32 | SO | Entree | Set Overflow — surveille par PIO 1 |
| 33 | RESET | Bidir | Reset systeme (actif bas) |
| 34–39 | Flash | — | Flash SPI NOR (XIP) |
| 40–45 | PSRAM | — | PSRAM QSPI |
| 46–47 | ESP32 FSPI | — | SCLK, CS vers l’ESP32 |
| 48–49 | ESP32 UART | — | TX/RX 460,8 kbaud vers l’ESP32 |
Architecture firmware
Disposition de la memoire Flash
Identique a la disposition du picoZ80 :
| Partition | Plage d’adresses | Taille | Contenu |
|---|---|---|---|
| Bootloader | 0x10000000–0x1001FFFF |
128 Ko | Pont USB, mise a jour firmware, selecteur de partition |
| App Slot 1 | 0x10020000–0x1051FFFF |
5 Mo | Firmware principal 6502 (partition 1) |
| App Slot 2 | 0x10520000–0x10A1FFFF |
5 Mo | Firmware principal 6502 (partition 2) |
| App Config 1 | 0x10A20000–0x10C9FFFF |
2,5 Mo | Images ROM + JSON de configuration minifie (slot 1) |
| App Config 2 | 0x10CA0000–0x10F1FFFF |
2,5 Mo | Images ROM + JSON de configuration minifie (slot 2) |
| General Config | 0x10F20000–0x10FFEFFF |
892 Ko | Parametres principaux, espace de travail |
| Partition Table | 0x10FFF000–0x11000000 |
4 Ko | Slot actif, checksums, metadonnees |
Conception double coeur
| Coeur | Responsabilites |
|---|---|
| Core 0 | Pont USB de stockage de masse ; gestion des partitions firmware ; relais d’E/S fichiers vers l’ESP32 ; dispatch des commandes UART ESP32 ; service de la file inter-coeurs |
| Core 1 | Boucle principale d’emulation bus 6502 — traite les FIFO PIO pour chaque cycle bus, resout les adresses par rapport a la carte memoire, dispatche vers les handlers PSRAM / PHYSICAL / FUNC, appelle les callbacks de poll des pilotes |
Interface bus PIO
L'interface bus 6502 est implementee dans
M6502.pio a travers les trois blocs PIO du RP2350. La difference cle par rapport a l'interface Z80 est le schema d'horloge biphasee non chevauchante du 6502 : PHI0 est une entree d'horloge externe ; PIO 2 genere PHI1 et PHI2 a partir de celle-ci. Cela garantit un timing bus 6502 correct independamment de la planification du Core 1.
Programmes PIO
| Bloc PIO | Programme | Machines d’etat | Fonction |
|---|---|---|---|
| PIO 0 | m6502_addr |
SM 0 | Produit l’adresse 16 bits A0-A15 ; signale IRQ 0 (debut de cycle) |
| PIO 0 | m6502_data |
SM 1 | Pilote ou echantillonne D0-D7 ; signale IRQ 1 (phase donnees) ; controle tri-state via RNW |
| PIO 1 | m6502_cycle |
SM 0 | Sequenceur de cycle bus de niveau superieur ; IRQ 7 = sortie de boucle d’execution |
| PIO 1 | m6502_fetch |
SM 1 | Cycle de recuperation d’opcode (SYNC actif, PHI2 haut, RNW=1) |
| PIO 1 | m6502_read |
SM 1 | Cycle de lecture memoire |
| PIO 1 | m6502_write |
SM 2 | Cycle d’ecriture memoire |
| PIO 1 | m6502_irq |
SM 2 | Surveille la broche IRQ ; signale PIO IRQ 5 lors de l’assertion |
| PIO 1 | m6502_nmi |
SM 3 | Surveille la broche NMI ; signale PIO IRQ 4 lors de l’assertion |
| PIO 1 | m6502_so |
SM 3 | Surveille la broche SO (Set Overflow) ; signale PIO IRQ 6 |
| PIO 2 | m6502_clock_6502 |
SM 0 | Genere les horloges biphasees PHI1 / PHI2 a partir de l’entree PHI0 externe |
Conventions de signaux IRQ
| Drapeau IRQ PIO | Signal | Declenche par | Consomme par |
|---|---|---|---|
| IRQ 0 | Debut de cycle | m6502_addr — adresse valide sur PHI1 |
Boucle de dispatch Core 1 |
| IRQ 1 | Phase donnees | m6502_data — bus de donnees actif |
Boucle de dispatch Core 1 |
| IRQ 4 | NMI | m6502_nmi — broche NMI basse |
Handler NMI Core 1 |
| IRQ 5 | IRQ | m6502_irq — broche IRQ basse |
Handler IRQ Core 1 |
| IRQ 6 | SO | m6502_so — broche SO haute |
Handler SO Core 1 |
| IRQ 7 | Sortie de boucle | Requete logicielle | m6502_cycle — sort de la boucle d’execution |
Generation d'horloge PHI1 / PHI2
Le 6502 necessite deux phases d'horloge non chevauchantes. PIO 2 execute le programme
m6502_clock_6502 qui accepte une entree PHI0 externe sur un GPIO dedie et genere PHI1 et PHI2 avec le timing de non-chevauchement correct. Dedier un bloc PIO entier a la generation d'horloge signifie que le timing bus du 6502 n'est jamais affecte par l'activite du Core 1 ou les blocages FIFO.
Etats d'attente et RDY
Le signal
RDY du 6502 peut etre utilise pour inserer des etats d'attente — maintenir RDY a l'etat bas pendant un cycle de lecture met le processeur en pause jusqu'a ce que RDY repasse a l'etat haut. Le pico6502 peut activer RDY par programmation depuis le Core 1 pour inserer des etats d'attente lors de l'acces a des peripheriques virtuels plus lents (ex. emulation de lecteur de disquettes). Le parametre tcycwait dans l'entree JSON de la carte memoire specifie le nombre d'etats d'attente a inserer pour une region memoire donnee.
Architecture PIO — Comment les cycles bus 6502 sont recrees
Le sous-systeme E/S programmable (PIO) du RP2350 recree un timing bus 6502 precis au cycle pres en utilisant 10 machines d'etat reparties sur les trois blocs PIO. L'architecture differe du PIO du picoZ80 de deux manieres fondamentales : le 6502 utilise un schema d'horloge biphasee non chevauchante (PHI1/PHI2) au lieu d'une horloge unique, et il utilise un signal unique
Generation d'horloge biphasee
R/W̄ (Read/Not-Write) au lieu de signaux /RD et /WR separes.
Le 6502 necessite deux horloges non chevauchantes — PHI1 et PHI2. Un signal PHI0 externe fournit la reference ; PIO 2 genere PHI1 et PHI2 a partir de celui-ci. La machine d'etat
m6502_clock_6502 (PIO 2 SM 0) implemente ceci :
PHI0 (input): ──┐ ┌──┐ ┌──
│ │ │ │
└────────┘ └────────┘
PHI1 (output): ┌──────┐ ┌──────┐
│ │ │ │
───┘ └──────────────┘ └───
PHI2 (output): ───┐ ┌──────┐ ┌──
│ │ │ │
└──────────────┘ └──────────────┘
↑ ↑ ↑
│ │ │
PHI0 tombe PHI0 monte PHI0 tombe
→ bref ecart → bref ecart → bref ecart
La SM utilise
Le mecanisme jmp pin pour detecter les fronts de PHI0 et set pins pour piloter PHI1 et PHI2 avec les ecarts de non-chevauchement corrects. L'annotation de delai [1] sur la premiere instruction set pins cree la periode de non-chevauchement — les deux horloges sont basses pendant un bref intervalle lors des transitions. Dedier un bloc PIO entier a la generation d'horloge garantit que le timing bus du 6502 n'est jamais affecte par les blocages FIFO ou la latence du Core 1.
out exec, 32
Comme le picoZ80, le pico6502 utilise l'injection dynamique d'instructions via
out exec — mais avec une difference cle : la SM de cycle du 6502 utilise out exec, 32 (instructions 32 bits) au lieu du out exec, 16 du Z80. Cela fournit l'encodage complet d'instruction PIO 32 bits incluant les bits de side-set, les valeurs de delai et les operandes etendus.
La SM m6502_cycle (PIO 1 SM 0) orchestre tous les cycles bus :
// Programme SM m6502_cycle (PIO 1 SM 0) : // // start_cycle: // wait 0 gpio CLK2 ; Synchronisation sur front descendant PHI2 (debut nouveau cycle) // irq set 0 ; Signale "pret pour nouveau cycle" // wait 0 irq 0 ; Attend que le code C charge l'adresse et efface IRQ 0 // cycle_exec: // out exec, 32 ; Tire l'instruction 32 bits du FIFO, l'execute // jmp cycle_exec ; Repete // cycle_end: // irq set 7 ; Signale fin de boucle d'execution // cycle_exec2: // out exec, 32 ; Continue a executer les instructions injectees // jmp cycle_exec2 ; Boucle jusqu'a JMP start_cycle
Le code C pre-calcule les sequences d'instructions 32 bits pour chaque type de cycle (fetch, read, write) et les pousse dans le FIFO. La SM de cycle tire et execute chaque instruction tour a tour, controlant les signaux
Types de cycles bus 6502
SYNC et R/W̄ tout en se coordonnant avec les SM d'adresse et de donnees via les drapeaux IRQ.
Le 6502 a trois types de cycles bus, tous controles par l'etat de
R/W̄ et SYNC :
Opcode Fetch (m6502_fetch):
PHI1: ┌──────┐ ┌──
│ │ │
───┘ └──────────────┘
PHI2: ───┐ ┌──────┐
│ │ │
└──────────────┘ └───
A0–A15: ══╤═══ PC address ══════════╗ (valide sur front montant PHI1)
R/W̄: ──┤── haut (lecture) ──────╢
SYNC: ──┤── haut (fetch) ────────╢ (SYNC haut = recuperation d'opcode)
D0–D7: ══════════════════╤════════╗ (echantillonne sur front descendant PHI2)
opcode
Memory Read (m6502_read):
Meme timing que fetch, mais SYNC = bas.
Memory Write (m6502_write):
PHI1: ┌──────┐ ┌──
│ │ │
───┘ └──────────────┘
PHI2: ───┐ ┌──────┐
│ │ │
└──────────────┘ └───
A0–A15: ══╤═══ adresse ═════════════╗ (valide sur front montant PHI1)
R/W̄: ──┤── bas (ecriture) ──────╢ (R/W̄ bas = ecriture)
SYNC: ──┤── bas ─────────────────╢
D0–D7: ══════════════╤═══ donnees ╗ (pilote pendant PHI2 haut)
Differences cles par rapport a l'implementation PIO du Z80 :
Machines d'etat de surveillance de signaux
- Signal R/W̄ unique — remplace les signaux
/RDet/WRsepares du Z80. Les SMm6502_fetchetm6502_readmettentR/W̄a l'etat haut ;m6502_writele met a l'etat bas. - Signal SYNC — le 6502 active
SYNClors des recuperations d'opcode pour les distinguer des lectures ordinaires. La SMm6502_fetchmetSYNCa l'etat haut ;m6502_readetm6502_writele laissent a l'etat bas. - Echantillonnage de donnees base sur PHI2 — le bus de donnees est echantillonne sur le front descendant de PHI2 (fin du cycle), pas sur un front d'horloge T-state specifique comme le Z80. La SM
m6502_dataattend surwait 0 gpio CLK2pour temporiser la capture de donnees. - Etats d'attente bases sur RDY — au lieu du signal
/WAITdu Z80, le 6502 utiliseRDY. LorsqueRDYest bas pendant un cycle de lecture, le processeur se met en pause. Les SM de fetch et de lecture verifient RDY viajmp pinapres chaque front montant de PHI2. - Pas de cycle de rafraichissement — le 6502 n'a pas de cycle de rafraichissement DRAM, donc les cycles de fetch sont plus simples (pas de phase de rafraichissement T3-T4).
- Pas de cycles specifiques aux E/S — le 6502 n'a pas d'instructions
IN/OUT. Tout acces aux peripheriques se fait via des lectures et ecritures mappees en memoire.
Trois SM dediees surveillent les signaux d'entree asynchrones du 6502 :
m6502_irq(PIO 1 SM 2) — surveille la broche/IRQ. Lorsque/IRQpasse a l'etat bas, elle active PIO IRQ 5 et le maintient jusqu'a ce que la broche revienne a l'etat haut, puis efface le drapeau. Le Core 1 verifie IRQ 5 pour decider s'il faut injecter une sequence de recuperation de vecteur d'interruption.m6502_nmi(PIO 1 SM 3) — surveille/NMIet active/desactive PIO IRQ 4. Le handler NMI dans le Core 1 pousse la sequence de cycle bus appropriee pour vectoriser via$FFFA/$FFFB.m6502_so(PIO 1 SM 3) — surveille la brocheSO(Set Overflow) et active/desactive PIO IRQ 6. Ceci est utilise par certains systemes 6502 (notamment le lecteur de disque Commodore) pour signaler des evenements de donnees pretes.
jmp pin pour detecter la broche passant a l'etat actif, irq set pour signaler le Core 1, puis jmp pin en boucle pour detecter la broche revenant a l'etat inactif, suivi de irq clear. Ceci convertit les evenements de front asynchrones en drapeaux IRQ synchrones que le Core 1 peut interroger efficacement dans la boucle principale.
Modele memoire
Le modele memoire du pico6502 est structurellement identique au modele du picoZ80 avec une difference critique : le 6502 n'a pas d'espace d'adressage E/S separe. Il n'y a pas de tableau
ioPtr[] dans t_6502PSRAM et pas de section JSON iomap. Tous les registres de peripheriques sont mappes dans l'espace d'adressage memoire de 64 Ko en utilisant des blocs de type FUNC.
Niveau 1 — SRAM du RP2350 (table de dispatch rapide)
128 entrees 32 bits dans
_membankPtr[], une par bloc de 512 octets de l'espace d'adressage de 64 Ko. Chaque entree encode le type de bloc, le numero de banque PSRAM et l'adresse de base du bloc dans un seul mot 32 bits pour un dispatch O(1) a chaque cycle bus :
// Encodage membankPtr 32 bits // Bits 31–24 : constante MEMBANK_TYPE_xxx // Bits 23–16 : numero de banque PSRAM (0–63) // Bits 15–0 : adresse de base du bloc >> 9 (c.-a-d. 7 bits superieurs de l'adresse 16 bits) #define MEMBANK_ENCODE(type, bank, base) (((type) << 24) | ((bank) << 16) | ((base) >> 9))
Niveau 2 — PSRAM (8 Mo)
Les 8 Mo de PSRAM sont divises entre la zone RAM/ROM et les tables de pointeurs de fonctions :
typedef struct {
uint8_t RAM[MAX_MEMORY_BANKS * MEMORY_PAGE_SIZE]; // 64 banques x 64 Ko = 4 Mo zone RAM/ROM
MemoryFunc memPtr[MEMORY_PAGE_SIZE]; // 64K redirection lecture par octet (type PTR)
MemoryFunc memioPtr[MEMORY_PAGE_SIZE]; // 64K tableau handlers mappes memoire (type FUNC)
// Note : pas de ioPtr[] — le 6502 n'a pas d'espace E/S separe
} t_6502PSRAM;
Niveau 3 — Flash (16 Mo)
La Flash de 16 Mo contient le bootloader, deux emplacements firmware application de 5 Mo, deux emplacements de configuration pour les images ROM et le JSON minifie, la configuration generale et la table de partitions. Voir le tableau de disposition de la memoire Flash dans la section Architecture firmware ci-dessus.
Types de blocs memoire
| Constante | Valeur | Comportement |
|---|---|---|
MEMBANK_TYPE_PHYSICAL |
0 | Pass-through vers le materiel reel de l’hote — le RP2350 libere le bus |
MEMBANK_TYPE_PHYSICAL_VRAM |
1 | RAM video de l’hote avec etats d’attente configurables |
MEMBANK_TYPE_RAM |
2 | Lecture/ecriture — sauvegardee dans une banque PSRAM |
MEMBANK_TYPE_ROM |
3 | Lecture seule — sauvegardee dans une banque PSRAM ; les ecritures sont silencieusement ignorees |
MEMBANK_TYPE_VRAM |
4 | Miroir RAM video PSRAM avec etats d’attente |
MEMBANK_TYPE_FUNC |
5 | Peripherique virtuel — handler memioPtr[addr] appele a chaque acces |
MEMBANK_TYPE_PTR |
6 | Redirection par octet — handler memPtr[addr] utilise pour les lectures |
Reference de configuration
Le pico6502 utilise le meme mecanisme de configuration JSON que le picoZ80. Les cles de niveau superieur sont
"esp32" et "rp2350". La section specifique au CPU utilise la cle "6502" (au lieu de "z80"). Parce que le 6502 n'a pas d'espace E/S, il n'y a pas de tableau "io" — seulement un tableau "memory".
esp32.core
| Cle | Type | Description |
|---|---|---|
device |
string | Type de CPU. Doit etre "6502" pour le pico6502. |
mode |
integer | Mode de demarrage par defaut : 0 = client (station), 1 = Point d’Acces. |
esp32.wifi
| Cle | Type | Description |
|---|---|---|
override |
0/1 | 1 = appliquer tous les parametres wifi de ce bloc ; 0 = utiliser les parametres NVS. |
wifimode |
string | "ap" ou "client". |
ssid |
string | Nom du reseau a creer (AP) ou rejoindre (client). |
password |
string | Mot de passe WiFi. |
ip |
string | Adresse IP fixe. |
netmask |
string | Masque de sous-reseau. |
gateway |
string | Passerelle par defaut. |
dhcp |
0/1 | Mode client uniquement. 1 = DHCP, 0 = IP fixe. |
webfs |
string | Repertoire racine du systeme de fichiers web sur la carte SD (par defaut "webfs"). |
persist |
0/1 | 1 = ecrire les parametres resolus dans le NVS a chaque demarrage. |
rp2350.core
| Cle | Type | Description |
|---|---|---|
cpufreq |
integer | Horloge systeme du RP2350 en Hz (ex. 300000000). |
psramfreq |
integer | Horloge SPI PSRAM en Hz (ex. 133000000). |
voltage |
float | Tension du coeur du RP2350 (ex. 1.10). |
rp2350.6502.memory[ ]
Definit la carte memoire du 6502. Tous les peripheriques doivent apparaitre ici sous forme d'entrees de type
FUNC — il n'y a pas de carte E/S separee.
| Cle | Type | Description |
|---|---|---|
enable |
0/1 | Si cette entree est active. |
addr |
hex string | Adresse de debut dans l’espace d’adressage du 6502 (ex. "0xE000"). |
size |
hex string | Taille de la region en octets (ex. "0x2000"). |
type |
string | PHYSICAL, PHYSICAL_VRAM, RAM, ROM, FUNC ou PTR. |
bank |
integer | Numero de banque PSRAM pour les types RAM/ROM (0-63). |
tcycwait |
integer | Etats d’attente a inserer (etirement RDY) pour cette region. |
task |
string | Tache/handler pilote nomme pour les blocs de type FUNC. |
file |
string | Chemin sur la carte SD vers une image ROM a charger au demarrage (type ROM). |
rp2350.6502.drivers[ ]
Les entrees de pilotes pour le 6502 sont plus simples que celles du Z80. Chaque entree active un pilote nomme (mis en correspondance avec la table
virtualFuncMap[] du firmware) et charge optionnellement des images ROM dans la PSRAM au demarrage.
| Cle | Type | Description |
|---|---|---|
enable |
0/1 | Si cette entree de pilote est active. |
name |
string | Nom du pilote — mis en correspondance sans distinction de casse avec virtualFuncMap[]. |
rom[] |
array | Images ROM a charger au demarrage. Chaque entree : enable, file, loadaddr[]. |
Entree rom[] :
| Cle | Type | Description |
|---|---|---|
enable |
0/1 | Si cette image ROM doit etre chargee. |
file |
string | Chemin sur la carte SD vers le binaire ROM. |
loadaddr[] |
array | Un ou plusieurs descripteurs d’adresse de chargement : enable, position, addr, bank, size. |
Framework de peripheriques virtuels
Le framework de peripheriques virtuels est structurellement identique au framework du picoZ80 decrit dans le Guide technique du picoZ80. La difference cle est que tous les peripheriques virtuels sont enregistres dans
memioPtr[] — il n'y a pas d'equivalent ioPtr[] pour le 6502.
Signatures des handlers
// Handler memoire / peripherique — installe dans memioPtr[addr] // Appele pour chaque acces a un bloc MEMBANK_TYPE_FUNC typedef uint8_t (*MemoryFunc)(M6502CPU *cpu, bool read, uint16_t addr, uint8_t data); // Fonction d'initialisation de pilote — enregistree dans virtualFuncMap[] // Appelee deux fois : pass=0 (validation), pass=1 (configuration) typedef int (*VirtualFunc)(M6502CPU *cpu, t_drvConfig *drvConfig, int pass);
Ecrire un pilote de peripherique
Pour ajouter un peripherique virtuel pour le pico6502 :
- Creer une fonction handler avec la signature
MemoryFunc. Le handler recoitread=truepour les cycles de lecture du 6502 (RNW=1) etread=falsepour les cycles d'ecriture (RNW=0). - Creer une fonction d'initialisation avec la signature
VirtualFunc. Dans la passe de configuration (pass=1), installer votre handler danscpu->_6502PSRAM->memioPtr[addr]pour chaque adresse occupee par votre peripherique. - Enregistrer le nom du pilote et la fonction d'initialisation dans la table
virtualFuncMap[]dansM6502CPU.c. - Ajouter une entree de type
FUNCdans le tableaumemoryduconfig.jsonpour la plage d'adresses. - Ajouter une entree de pilote dans le
config.jsonavec le champ"name"correspondant.
Voir le Guide du developpeur pico6502 pour un exemple complet incluant une implementation de peripherique VIA6522.
Coprocesseur ESP32
Le coprocesseur ESP32 est identique en fonction et en implementation a celui du picoZ80 — referez-vous au Guide technique du picoZ80 — Coprocesseur ESP32 pour la description complete de l'interface carte SD, la structure du serveur web et le protocole de commande RP2350-ESP32.
Carte SD
La carte SD est geree exclusivement par l'ESP32 via SPI. Le RP2350 demande des lectures et ecritures de fichiers en postant des messages dans la file inter-coeurs ; le Core 0 relaie ces requetes a l'ESP32 via UART et renvoie les resultats. La disposition du repertoire de la carte SD pour le pico6502 est identique a celle du picoZ80 :
webfs/ pour les fichiers web, ROM/ pour les images ROM, et config.json a la racine.
Serveur web
Le meme serveur web Bootstrap 4 a sept pages fonctionne sur l'ESP32. L'interface web detecte automatiquement le type d'appareil connecte via le champ
esp32.core.device dans le config.json et ajuste son theme CSS et ses libelles en consequence (la feuille de style p6502.css applique la palette de couleurs specifique au 6502).
Protocole de commande
Le protocole de commande RP2350-ESP32 est identique pour le picoZ80 et le pico6502. Les commandes sont echangees via une liaison UART a 460,8 kbaud (sauvegardee par FSPI a 50 MHz pour le transfert de donnees en masse). Le protocole est defini dans
ESP.c / ESP.h et est partage entre les deux variantes de firmware.
Debogage SWD — RP2350
La configuration du debogage SWD pour le pico6502 est identique a celle du picoZ80 — referez-vous au Guide technique du picoZ80 — Debogage SWD pour la description complete des connexions materielles, de la cible OpenOCD personnalisee
rp2350_tzpu.cfg et de l'initialisation GDB globale. Les differences par rapport au picoZ80 sont :
- L'ELF du firmware principal est
build/bin/model/BaseM6502/BaseM6502_0x10020000.elf(pasBaseZ80). - L'entree
add-auto-load-safe-pathdans~/.gdbinitdoit referencerBaseM6502.
Configuration OpenOCD
sudo cp rp2350_tzpu.cfg /usr/local/share/openocd/scripts/target/ openocd -f interface/cmsis-dap.cfg -f target/rp2350_tzpu.cfg -c "adapter speed 5000"
Configuration GDB
set history save on set history filename ~/.gdb_history set history size 65536 add-auto-load-safe-path build/bin/model/BaseM6502/.gdbinit:build/bin/model/Bootloader/.gdbinit
# Bootloader — Core 0 cd build/bin/model/Bootloader cp ../../../../.gdbinit.bootloader.3333 .gdbinit gdb-multiarch Bootloader.elf # Bootloader — Core 1 (terminal separe) cd build/bin/model/Bootloader cp ../../../../.gdbinit.bootloader.3334 .gdbinit gdb-multiarch Bootloader.elf
# Firmware principal — Core 0 cd build/bin/model/BaseM6502 cp ../../../../.gdbinit.3333 .gdbinit gdb-multiarch BaseM6502_0x10020000.elf # Firmware principal — Core 1 (terminal separe) cd build/bin/model/BaseM6502 cp ../../../../.gdbinit.3334 .gdbinit gdb-multiarch BaseM6502_0x10020000.elf
ESP32 — Debogage USB
Identique au picoZ80 — connectez l'USB au port USB ESP32 et utilisez l'interface USB-JTAG integree de l'ESP32-S3 (aucune sonde externe requise).
openocd -f board/esp32s3-builtin.cfg xtensa-esp32s3-elf-gdb esp32/build/main.elf (gdb) target extended-remote :3333
Systeme de compilation
Le systeme de compilation est identique a celui du picoZ80 — CMake avec Pico SDK 2.x ciblant le RP2350. Le pico6502 ne necessite pas la bibliotheque d'emulateur Zeta Z80. Referez-vous au Guide technique du picoZ80 — Systeme de compilation pour la description complete des prerequis, la configuration Docker pour ESP-IDF et le script de compilation. Les differences specifiques au pico6502 sont notees ci-dessous.
Cibles de compilation
| Cible | Sortie | Description |
|---|---|---|
BaseM6502 |
BaseM6502_0x10020000.uf2 |
Firmware principal 6502 — adresse de chargement Slot 1 |
BaseM6502 |
BaseM6502_0x10520000.uf2 |
Firmware principal 6502 — adresse de chargement Slot 2 |
Bootloader |
Bootloader.uf2 |
Bootloader partage (meme que picoZ80) |
| ESP32 | main.bin |
Firmware ESP32 (partage avec picoZ80) |
Commandes de compilation
# Configuration (une seule fois) — depuis la racine du projet
export PICO_PATH=/path/to/pico-sdk
./get_and_build_sdk.sh
# Compilation release standard
./build_tzpuPico.sh
# Compilation debug
./build_tzpuPico.sh DEBUG
# Compilation complete incluant le firmware ESP32
./build_tzpuPico.sh ALL
# ESP32 uniquement (en utilisant l'alias Docker idf54)
cd projects/tzpuPico/esp32
idf54 build
# Flasher le RP2350 via stockage de masse USB (mode BOOTSEL)
cp build/bin/model/Bootloader/Bootloader.uf2 /media/$USER/RPI-RP2/
cp build/bin/model/BaseM6502/BaseM6502_0x10020000.uf2 /media/$USER/RPI-RP2/
# Flasher l'ESP32 (initial, via esptool)
esptool.py --chip esp32s3 --port /dev/ttyUSB0 --baud 460800 \
write_flash 0x0 esp32/build/bootloader/bootloader.bin \
0x8000 esp32/build/partition_table/partition-table.bin \
0x10000 esp32/build/main.bin
Sites de reference
| Ressource | Lien |
|---|---|
| Page du projet pico6502 | /pico6502/ |
| Manuel d’utilisation du pico6502 | /pico6502-usermanual/ |
| Guide du developpeur pico6502 | /pico6502-developersguide/ |
| Guide technique du picoZ80 | /picoz80-technicalguide/ |
| Page du projet picoZ80 | /picoz80/ |
| Fiche technique du RP2350 | datasheets.raspberrypi.com |
| API Multicore du Pico SDK | raspberrypi.github.io/pico-sdk-doxygen |
| Fiche technique du MOS 6502 | archive.org |
| Documentation esptool | docs.espressif.com |
| Bibliotheque cJSON | github.com/DaveGamble/cJSON |
Avis reglementaire sans fil
Cet appareil incorpore un module sans fil ESP32-S3-PICO-1 qui emet dans la bande ISM 2,4 GHz, ce qui en fait un emetteur intentionnel au regard des reglementations de radiofrequences dans le monde entier (y compris FCC Part 15 Subpart C aux Etats-Unis et la Directive Equipements Radio 2014/53/EU dans l'Union europeenne).
Bien que le module ESP32-S3-PICO-1 lui-meme possede des certifications reglementaires prealables (FCC, CE et autres), ces certifications au niveau du module ne s'etendent pas automatiquement a un produit fini qui incorpore le module. L'exemption de module pre-certifie permet aux hobbyistes individuels de construire un nombre limite d'appareils pour un usage personnel, experimental ou educatif sans obtenir d'autorisation d'equipement separee.
Limitations importantes
Il est de la seule responsabilite du constructeur de s'assurer que tout appareil construit a partir de ces conceptions est conforme a toutes les reglementations de radiofrequences applicables dans sa juridiction. L'auteur fournit ces conceptions pour un usage personnel, educatif et de hobbyiste et ne garantit pas qu'un appareil construit a partir de celles-ci satisfait aux exigences reglementaires pour la distribution commerciale.
- Les appareils assembles ne doivent pas etre vendus, proposes a la vente, offerts ou distribues de quelque maniere que ce soit a des tiers, sauf si le produit fini a ete teste independamment et a obtenu sa propre autorisation d'equipement (ex. FCC ID, marquage CE avec evaluation d'un organisme notifie) dans la juridiction concernee.
- La construction de ce projet pour un usage personnel en quantites limitees est generalement autorisee en vertu des dispositions pour hobbyistes et usage experimental (ex. FCC § 15.23), a condition que l'appareil ne cause pas d'interferences nuisibles.
- Les exigences reglementaires varient selon les pays. Les constructeurs en dehors des Etats-Unis doivent consulter leur autorite nationale des radiofrequences pour les regles applicables.
Il est de la seule responsabilite du constructeur de s'assurer que tout appareil construit a partir de ces conceptions est conforme a toutes les reglementations de radiofrequences applicables dans sa juridiction. L'auteur fournit ces conceptions pour un usage personnel, educatif et de hobbyiste et ne garantit pas qu'un appareil construit a partir de celles-ci satisfait aux exigences reglementaires pour la distribution commerciale.