pico6502 Guide Technique

English

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 R/W̄ (Read/Not-Write) au lieu de signaux /RD et /WR separes.

Generation d'horloge biphasee
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 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.

Le mecanisme 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 SYNC et R/W̄ tout en se coordonnant avec les SM d'adresse et de donnees via les drapeaux IRQ.

Types de cycles bus 6502
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 :
  • Signal R/W̄ unique — remplace les signaux /RD et /WR separes du Z80. Les SM m6502_fetch et m6502_read mettent R/W̄ a l'etat haut ; m6502_write le met a l'etat bas.
  • Signal SYNC — le 6502 active SYNC lors des recuperations d'opcode pour les distinguer des lectures ordinaires. La SM m6502_fetch met SYNC a l'etat haut ; m6502_read et m6502_write le 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_data attend sur wait 0 gpio CLK2 pour temporiser la capture de donnees.
  • Etats d'attente bases sur RDY — au lieu du signal /WAIT du Z80, le 6502 utilise RDY. Lorsque RDY est bas pendant un cycle de lecture, le processeur se met en pause. Les SM de fetch et de lecture verifient RDY via jmp pin apres 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.

Machines d'etat de surveillance de signaux
Trois SM dediees surveillent les signaux d'entree asynchrones du 6502 :
  • m6502_irq (PIO 1 SM 2) — surveille la broche /IRQ. Lorsque /IRQ passe 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 /NMI et 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 broche SO (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.
Les trois SM utilisent le meme motif : 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 :
  1. Creer une fonction handler avec la signature MemoryFunc. Le handler recoit read=true pour les cycles de lecture du 6502 (RNW=1) et read=false pour les cycles d'ecriture (RNW=0).
  2. Creer une fonction d'initialisation avec la signature VirtualFunc. Dans la passe de configuration (pass=1), installer votre handler dans cpu->_6502PSRAM->memioPtr[addr] pour chaque adresse occupee par votre peripherique.
  3. Enregistrer le nom du pilote et la fonction d'initialisation dans la table virtualFuncMap[] dans M6502CPU.c.
  4. Ajouter une entree de type FUNC dans le tableau memory du config.json pour la plage d'adresses.
  5. Ajouter une entree de pilote dans le config.json avec 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 (pas BaseZ80).
  • L'entree add-auto-load-safe-path dans ~/.gdbinit doit referencer BaseM6502.

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
  • 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.
Responsabilite du constructeur
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.