Skip to content

DonaldMoran/W25Q64_INTERLOCK

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

36 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

W25Q64_INTERLOCK

6502 ↔ Pico W interlocked filesystem interface

This document outlines the architecture, communication protocol, error handling, concurrency, memory management, configuration, flash memory usage, and transient command development for the W25Q64_INTERLOCK project.


1. Overall Architecture

The system comprises the following main components:

  • 65C02 Computer: Hosts a shell and initiates commands.
  • 6522 VIA (Versatile Interface Adapter): Provides a parallel interface for communication between the 65C02 and the Raspberry Pi Pico W.
  • Raspberry Pi Pico W: Receives commands from the 6522, interacts with the W25Q64 flash memory, manages the LittleFS filesystem, and handles Wi-Fi connectivity.
  • W25Q64 Flash Memory: Stores the LittleFS filesystem, providing persistent storage for files.
  • LittleFS: A lightweight filesystem optimized for microcontrollers, managing file storage and retrieval on the W25Q64 flash memory.

The 65C02 computer issues commands, which are transmitted through the 6522 VIA to the Raspberry Pi Pico W. The Pico W interprets these commands, performs actions such as reading from or writing to the W25Q64 flash memory, and sends responses back to the 65C02 for display.

       HOST PICO (Emulator)                     BRIDGE PICO (Pico W)
    +-----------------------+                 +-----------------------+
    |                       |                 |                       |
    | GP0  (PA0) <--------->| [DATA BUS] <--->| GP6  (PA0)            |
    | GP1  (PA1) <--------->| [DATA BUS] <--->| GP7  (PA1)            |
    | GP2  (PA2) <--------->| [DATA BUS] <--->| GP8  (PA2)            |
    | GP3  (PA3) <--------->| [DATA BUS] <--->| GP9  (PA3)            |
    | GP4  (PA4) <--------->| [DATA BUS] <--->| GP10 (PA4)            |
    | GP5  (PA5) <--------->| [DATA BUS] <--->| GP11 (PA5)            |
    | GP6  (PA6) <--------->| [DATA BUS] <--->| GP12 (PA6)            |
    | GP7  (PA7) <--------->| [DATA BUS] <--->| GP13 (PA7)            |
    |                       |                 |                       |
    | GP11 (CA2) ---------->| [REQUEST]  ---->| GP14 (Input)          |
    | GP10 (CA1) <----------| [ACK]      <----| GP15 (Output)         |
    |                       |                 |                       |
    | GND  -----------------| [COMMON GND] ---|--- GND                |
    |                       |                 |                       |
    +-----------------------+                 +-----------------------+

2. Implemented Commands

Command Alias Description
DIR [PATH] LS List files in a directory (root if omitted)
MOUNT Mount the file system
PWD Show current directory
CD [PATH] Change current directory
MKDIR [PATH] Create directory
DEL [PATH] RM Delete file
RENAME [OLD] [NEW] MV Rename or move file
TYPE [FILENAME] CAT Display file contents (.BIN shows hex dump)
FORMAT Format the W25Q64 flash
PING Ping the Raspberry Pi Pico W
HELP List available commands
CONNECT [SSID] [PASSWORD] Connect to Wi-Fi (stores credentials)
EXIT Exit shell to WozMon
SAVEMEM [START] [END] [FILE] Save 6502 memory region to flash
LOADMEM [ADDR] [FILE] Load file into 6502 memory
RUN [FILE] Load and execute binary (requires 2-byte header)
COPY [SRC] [DST] CP Copy file
TOUCH [FILE] Create empty file
JUMP [ADDR] Jump to address (e.g. FF00 for WozMon)
DATE [ARGS] Get/Set System Time (NTP supported) (External)
ECHO [TEXT] Print text to screen (External)
DO [FILE] Execute batch script (External)
WRITE [FILE] Text Editor (External)
BENCH Run filesystem benchmark (External)
SETSERVER [IP:PORT] Set/Get file server address (External)
GET [REMOTE] [LOCAL] Download file via HTTP (External)
PUT [LOCAL] [REMOTE] Upload file via HTTP (External)
CAT [FILE] Display file contents (External)
CP [SRC] [DST] Copy file (External)
RM-FR [PATH] Recursive delete directory (External)
RM* Delete all files in current dir (External)
TREE [PATH] Visualize directory structure (External)
PICORBT Reboot Bridge Pico (External)
CATALOG [PATH] Streaming directory list for any size (External)
BASIC Start MSBASIC (External)
KRUSADER Start Krusader Assembler (External)
WOZMON Start WozMon Monitor (External)
HEAD [FILE] Print first 10 lines of file (External)
HEX [FILE] Hex dump of file (External)
TAIL [FILE] Print last 10 lines of file (External)
GREP [PATTERN] [FILE] Search for pattern in file (External)
WC [FILE] Count lines, words, and characters (External)
DIFF [FILE1] [FILE2] Compare two files (External)
CALC Retro Calculator (External)
CLS Clear Screen and return home (External)

Design Note: DIR/LS vs CATALOG

A key design choice has been made to balance features against the shell's limited ROM space (< 4KB).

  • DIR (aliased as LS) is a built-in command that uses a fixed 1024-byte buffer to display directory listings. This keeps the core shell small and fast for common use cases. It will fail if a directory listing exceeds 1024 bytes.

  • CATALOG is a new transient command that implements a streaming protocol. It reads the directory listing byte-by-byte and can therefore handle directories of any size without being limited by a buffer. It is the recommended command for very large directories.

Command Protocol Reference

For complete command definitions including hex values for network commands (GET, PUT, SETSERVER) and File I/O operations, please see:

  • src/cmd_defs.h - Contains all command ID definitions including:

    • System commands (0x00-0x0F)
    • Filesystem commands (0x10-0x2F) - including CMD_FS_OPEN (0x12), CMD_FS_READ (0x13), CMD_FS_CLOSE (0x1C), CMD_FS_SAVEMEM (0x23), etc.
    • Network commands (0x30-0x4F) - including CMD_NET_HTTP_GET (0x34), CMD_NET_HTTP_POST (0x35)
    • Status codes
  • The implementation code in src/main.c show:

    • How arguments are packed
    • Argument order
    • Return data format
    • File handle usage

3. External Commands (Transient Programs)

Commands marked as (External) are transient programs loaded from the filesystem.

If a command is not found internally, the shell automatically searches in the following order:

  1. Current Directory: [CWD]/[COMMAND].BIN
  2. Bin Directory: /BIN/[COMMAND].BIN

Example:

BENCH

Executes /BIN/BENCH.BIN

Source code for all transient commands is located in:

6502/ca65/commands/


4. Communication Protocol

Communication between the 65C02 and Raspberry Pi Pico W occurs over a fully interlocked parallel bus via the 6522 VIA.

Core Functions

  • bus_read_byte() – Read a byte from the parallel bus
  • bus_write_byte() – Write a byte to the parallel bus

Handshaking

  • 65C02 uses CA2 to signal frame start
  • Pico uses CA1 to acknowledge (ACK)

Streaming Protocol (SAVEMEM / LOADMEM)

Large transfers use Pico-side state machines:

  • STATE_SAVEMEM_STREAM
  • STATE_LOADMEM_STREAM

SAVEMEM Flow

  1. 6502 sends header
  2. Pico enters stream mode
  3. 6502 streams bytes
  4. Pico writes to flash
  5. Pico sends status

LOADMEM Flow

  1. 6502 sends header
  2. Pico enters stream mode
  3. Pico streams bytes from flash
  4. 6502 writes to RAM

5. Error Handling

Errors detected by the Pico W are propagated back to the 65C02 using status codes and displayed by the shell. This centralizes error reporting and keeps the Pico-side implementation simple.

Status Codes

Code Meaning
$00 STATUS_OK
$01 STATUS_ERR
$02 STATUS_NO_FILE
$03 STATUS_EXIST

6. Concurrency and Timing

Parallel bus communication is fully hardware-interlocked. No software delays are required.

Critical Rules

  • Do NOT restart Pico PIO state machines during active transactions
  • 6502 must correctly switch VIA Port A direction before reading responses

7. Writing and Running Programs

Programs can be written on the 6502 using the Krusader assembler, saved to disk, and executed with RUN.

RUN File Format

The first 2 bytes must be the Load Address (little-endian). Program code follows immediately.

Example: Creating ABC.BIN

  1. Enter Krusader
F000R
  1. Write Program
000 LOAD .M $38FE
001 .W $3900
002 START .M $3900
003 LDA #'A'
004 LOOP JSR $FFEF
005 CLC
006 ADC #$1
007 CMP #'Z'+1
008 BNE LOOP
009 RTS
  1. Assemble
ASM
  1. Save
SAVEMEM 38FE 390C ABC.BIN
  1. Run
RUN ABC.BIN

Output: ABCDEFGHIJKLMNOPQRSTUVWXYZ

Krusader Extensions

The Krusader assembler has been patched with new file I/O commands:

  • S <filename>: Save Source. Saves the current source code buffer to a file.
  • F <filename>: Fetch Source. Loads a source file into the buffer and re-indexes it.
  • O <filename>: Save Object. Saves the assembled binary (from $0300 or defined origin) to a file.

8. Memory Management

  • http_buf – 32KB static buffer for HTTP downloads
  • savemem_buf – 256-byte streaming buffer for flash operations
  • LittleFS handles internal flash allocation automatically

9. Configuration

Wi-Fi credentials are configured in:

src/main.c

Defines:

  • WIFI_SSID
  • WIFI_PASSWORD

10. W25Q64 Flash Usage

The full 8MB capacity of the W25Q64 flash chip is used for the LittleFS filesystem.


11. Transient Command Development (CURRENT PRIORITY)

Note: The following section documents the definitive pattern for creating transient commands, validated by the working PING command.


11.1 Project Structure

6502/ca65/
├── commands/ # Transient commands directory
│   ├── ping/ # Working example command
│   │   └── ping.s
│   ├── get/ # GET command (in progress)
│   │   └── get.s
│   ├── put/ # PUT command (in progress)
│   │   └── put.s
│   ├── setserver/ # SETSERVER command (in progress)
│   │   └── setserver.s
│   ├── Makefile # Auto-discovery build system
│   ├── transient.cfg # Linker configuration
│   ├── bin/ # Output directory for .bin files
│   └── obj/ # Object files directory
│
├── common/ # Shared 6502 code
│   ├── pico_def.inc # Constants and status codes
│   ├── pico_lib.s # Pico communication library
│   └── pico_lib.o # Compiled object
│
└── shell/ # Main shell (DO NOT MODIFY)
└── cmd_shell.s

11.2 Memory Layout (from transient.cfg)

$07FE-$07FF: HEADER segment (2 bytes: load address $0800, little-endian) $0800-... : CODE segment (program code starts here) $3000-... : BSS segment (uninitialized data - NOT in .bin file)

This layout ensures:

  • No zero bytes in the middle of the binary
  • Clean separation of code and data
  • BSS is excluded from the binary file

11.3 Zero Page Usage — CRITICAL

The shell reserves $50-$57. Transient commands MUST use $58-$5F only.

$50-$57 RESERVED FOR SHELL - DO NOT USE
$58-$5F AVAILABLE FOR TRANSIENT COMMANDS

Standard Zero Page Pointers for Transients

t_arg_ptr    = $58  ; 2 bytes - Argument pointer
t_str_ptr1   = $5A  ; 2 bytes - String pointer 1
t_str_ptr2   = $5C  ; 2 bytes - String pointer 2
t_ptr_temp   = $5E  ; 2 bytes - Temporary pointer

⚠️ IMPORTANT
Do NOT use shell's arg_ptr, str_ptr1, str_ptr2, or ptr_temp Do NOT call shell's argument parsing functions Implement your own simple parsing

11.4 Shared Buffers and Functions

; Zero Page Assignments
; ---------------------------------------------------------------------------
;The shell reserves `$50-$57`. Transient commands **MUST** use `$58-$7F` only.

```asm
$50-$57 RESERVED FOR SHELL - DO NOT USE
$58-$7F AVAILABLE FOR TRANSIENT COMMANDS
; Buffers (from pico_lib.s)
ARG_BUFF    = $0400  ; 256-byte argument buffer
INPUT_BUFFER = $0300 ; Shell input buffer (contains command line)
LAST_STATUS = $??    ; Status from last Pico command

; Imported functions
.import pico_send_request, send_byte, read_byte
.import CMD_ID, ARG_LEN, ARG_BUFF, LAST_STATUS, RESP_LEN, RESP_BUFF

11.5 The Definitive Transient Command Pattern

Based on the working PING command, all transient commands should follow this exact structure:

; command.s - Definitive pattern for transient commands
; Location: 6502/ca65/commands/command/command.s

; ---------------------------------------------------------------------------
; External symbols
; ---------------------------------------------------------------------------
.import pico_send_request
.import CMD_ID, ARG_LEN, LAST_STATUS

; ---------------------------------------------------------------------------
; System calls
; ---------------------------------------------------------------------------
OUTCH = $FFEF    ; Print character in A
CRLF  = $FED1    ; Print CR/LF

; ---------------------------------------------------------------------------
; Zero page (USE ONLY $58-$5F)
; ---------------------------------------------------------------------------
t_str_ptr1   = $5A
t_str_ptr2   = $5C
t_ptr_temp   = $5E

; ---------------------------------------------------------------------------
; HEADER - MUST be first
; ---------------------------------------------------------------------------
.segment "HEADER"
    .word $0800        ; Load at $0800

; ---------------------------------------------------------------------------
; CODE - Program starts here
; ---------------------------------------------------------------------------
.segment "CODE"

start:
    ; ALWAYS preserve registers
    php
    pha
    txa
    pha
    tya
    pha
    
    ; ========== Debug: Show we're running ==========
    lda #<debug_prefix
    sta t_str_ptr1
    lda #>debug_prefix
    sta t_str_ptr1+1
    jsr print_string
    ; ================================================
    
    ; Your command logic here
    ; - Set up CMD_ID and ARG_LEN
    ; - Call pico_send_request
    ; - Check LAST_STATUS
    ; - Print result
    
    ; ALWAYS restore registers before returning
done:
    pla
    tay
    pla
    tax
    pla
    plp
    clc              ; Return with carry clear
    rts

; ---------------------------------------------------------------------------
; Helper: Print null-terminated string
; Uses 65C02 PHY/PLY instructions
; ---------------------------------------------------------------------------
print_string:
    pha
    phy              ; 65C02 instruction
    ldy #0
@loop:
    lda (t_str_ptr1), y
    beq @done
    jsr OUTCH
    iny
    jmp @loop
@done:
    ply              ; 65C02 instruction
    pla
    rts

; ---------------------------------------------------------------------------
; Helper: Print byte in A as hex
; ---------------------------------------------------------------------------
print_hex:
    pha
    lsr a
    lsr a
    lsr a
    lsr a
    jsr print_nibble
    pla
    and #$0F
    jsr print_nibble
    rts

print_nibble:
    cmp #10
    bcc @digit
    adc #6
@digit:
    adc #'0'
    jsr OUTCH
    rts

; ---------------------------------------------------------------------------
; RODATA - All strings at the END of the file
; ---------------------------------------------------------------------------
.segment "RODATA"

debug_prefix:    .asciiz "CMD: "
msg_success:     .asciiz "SUCCESS"
msg_fail:        .asciiz "FAIL"

11.6 Working Example: PING Command

The PING command validates this pattern:

; ping.s - Working example
.segment "HEADER"
    .word $0800

.segment "CODE"
start:
    ; Save registers
    php
    pha
    txa
    pha
    tya
    pha
    
    ; Show we're running
    lda #<debug_prefix
    sta t_str_ptr1
    lda #>debug_prefix
    sta t_str_ptr1+1
    jsr print_string
    
    ; Send PING command
    lda #$01           ; CMD_SYS_PING
    sta CMD_ID
    lda #$00
    sta ARG_LEN
    
    ; Show command
    lda #<debug_cmd
    sta t_str_ptr1
    lda #>debug_cmd
    sta t_str_ptr1+1
    jsr print_string
    
    lda CMD_ID
    jsr print_hex
    
    jsr pico_send_request
    
    ; Show status
    lda #<debug_status
    sta t_str_ptr1
    lda #>debug_status
    sta t_str_ptr1+1
    jsr print_string
    
    lda LAST_STATUS
    jsr print_hex
    jsr CRLF
    
    ; Check result
    lda LAST_STATUS
    bne fail
    
    ; Success
    lda #<msg_pong
    sta t_str_ptr1
    lda #>msg_pong
    sta t_str_ptr1+1
    jsr print_string
    jsr CRLF
    jmp done
    
fail:
    ; Failure
    lda #<msg_fail
    sta t_str_ptr1
    lda #>msg_fail
    sta t_str_ptr1+1
    jsr print_string
    jsr CRLF
    
done:
    ; Restore registers
    pla
    tay
    pla
    tax
    pla
    plp
    clc
    rts

; ... helper functions ...

.segment "RODATA"
debug_prefix:    .asciiz "PING: "
debug_cmd:       .asciiz "Cmd="
debug_status:    .asciiz " Status="
msg_pong:        .asciiz "PONG"
msg_fail:        .asciiz "FAIL"

Sample Output:

> PING
PING: Cmd=01 Status=00
PONG

12. Network File Access Extension

The following network commands have been implemented and validated:

12.1 SETSERVER (External)

SETSERVER <ip:port>

Writes server address to server.cfg

No argument → display current server

12.2 GET (External)

GET <remote-path> [local-path]

Reads server.cfg

Builds: ip\0port\0remote\0local Sends CMD_NET_HTTP_GET

12.3 PUT (External)

PUT <local-path> <remote-path>

Reads server.cfg

Verifies local file exists

Builds: ip\0port\0local\0remote Sends CMD_NET_HTTP_POST

Note: Currently, transient commands (GET, PUT) require full absolute paths for local files (e.g., /DOCS/FILE.TXT) as they do not yet share the shell's Current Working Directory (CWD).

13. File Server (tools/file_server.py)

Runs on remote machine (default port 8000). Supports:

  • HTTP GET for files/directories
  • HTTP POST with file data
  • X-Mkdir header for directory creation
  • X-Append header for append mode

14. Building Transient Commands

cd 6502/ca65/commands
make clean
make all

Output: bin/command.bin (binary for copying to /BIN/) bin/command.mon (WozMon format for pasting)

Makefile Features

  • Auto-discovers command directories
  • Links against ../common/pico_lib.o
  • Generates .mon files for WozMon
  • Uses --cpu W65C02 for proper 65C02 support

15. Testing Workflow

Start file server:

cd tools
python3 file_server.py

Build commands:

cd 6502/ca65/commands
make

On 6502:

> SETSERVER 192.168.100.197:8000
Server set to 192.168.100.197:8000

> GET /test.txt
Downloading...
Done

> TYPE test.txt
(contents displayed)

> PUT test.txt /uploaded.txt
Uploading...
Done

16. Future Ideas (Post-Network Access)


Exit via Ctrl+Z or Ctrl+X

17. Important Rules Summary

  • Zero Page: NEVER use $50-$57 in transient commands
  • Header: Every transient command must start with .word $0800
  • Registers: Always save and restore all registers
  • Strings: Store all messages in RODATA at the end of the file
  • Return: Always return with CLC
  • CPU: Use --cpu W65C02 for proper 65C02 support
  • Debug: Include debug output during development
  • Pattern: Follow the validated PING command structure

This combined README now:

Preserves all original content

Adds the validated transient command pattern from the working PING program

Clearly documents zero page rules

Shows the exact structure for GET, PUT, and SETSERVER

Includes build instructions and testing workflow

Maintains the future ideas section

Major System Updates

  • ROM Integration: The shell has been moved to ROM at $E000, freeing up RAM for transient programs.
  • Auto-Mount: Filesystem now mounts automatically on boot.

Applications Section

  • This section highlights some of the key applications developed for the 6502 system.

  • Text Editor (WRITE)

    • A new transient command WRITE has been implemented, providing a Nano-like text editing experience on the 6502 system.

    • Key Features:

      • User Interface: Full-screen editor with a header displaying the filename and a footer showing command shortcuts.
        • Input Handling:
          • Supports standard alphanumeric input.
          • Handles Enter for newlines and Tab for spacing.
          • Backspace: Implemented visual and buffer-level character deletion.
        • Arrow Keys: Escape sequence detection is in place to gracefully handle cursor keys.
          • Search: Ctrl+F triggers a text search from the current cursor position, wrapping to the start if needed.
        • File Management:
        • Launch with Filename: WRITE <filename> opens the editor with the target file pre-set.
        • Launch Empty: WRITE opens a blank buffer.
        • Save & Exit: Triggered via Ctrl+X.
        • Smart Prompting: If a filename was not provided at launch, the editor prompts the user to enter one upon saving.
    • Architecture:

      • Operates as a transient command loaded at $0800.
      • Utilizes a 4KB fixed memory buffer for text storage.
      • Integrates with the shell's Current Working Directory (CWD) for relative path resolution.
      • Implements robust stack management to prevent corruption during execution.
  • Retro Calculator Details (CALC)

    • Features:
      • Hex/Binary/Decimal conversions
      • Address range calculations
      • Simple arithmetic (addition, subtraction, multiplication, division) for unsigned 16-bit integers (0-65535).
      • Comprehensive input validation and error handling
      • Menu-driven interface

MSBASIC Memory Configuration

To prevent memory corruption when using SAVE and LOAD commands in MSBASIC, the start of BASIC program memory (RAMSTART2) has been moved.

  • Old Location: $0800 (Standard for many 6502 systems)
  • New Location: $0B00
  • Reason: The Shell and Pico Interface library use a BSS segment starting at $0400 for variables and large I/O buffers (ARG_BUFF, RESP_BUFF). This segment grows up to approximately $0AA0. Moving BASIC to $0B00 ensures that file operations do not overwrite the running BASIC program.

ZEROPAGE

With CONFIG_2A and your ZP_START values:

Starting points:

  • ZP_START1 = $02 (GORESTART, GOSTROUT, GOAYINT, GIVEAYF)
  • ZP_START2 = $0C (Z15, POSX, Z17, Z18, LINNUM, TXPSV, INPUTBUFFER)
  • ZP_START3 = $62 (CHARAC through Z14)
  • ZP_START4 = $6D (TEMPPT through the rest)

Allocation Trace:

ZP_START1 ($02):

  • GORESTART: .res 3 → $02-$04
  • GOSTROUT: .res 3 → $05-$07
  • GOAYINT: .res 2 → $08-$09
  • GOGIVEAYF: .res 2 → $0A-$0B
  • (Ends at $0B)

ZP_START2 ($0C):

  • Z15: .res 1 → $0C
  • POSX: .res 1 → $0D
  • Z17: .res 1 → $0E
  • Z18: .res 1 → $0F
  • LINNUM/TXPSV: .res 2 → $10-$11
  • INPUTBUFFER: (no .res specified, but likely continues)
  • (Need to see where ZP_START2 ends - probably continues until just before ZP_START3 at $62)

ZP_START3 ($62):

  • CHARAC: .res 1 → $62
  • ENDCHR: .res 1 → $63
  • EOLPNTR: .res 1 → $64
  • DIMFLG: .res 1 → $65
  • VALTYP: .res 2 (since not CONFIG_SMALL) → $66-$67
  • DATAFLG: .res 1 → $68
  • SUBFLG: .res 1 → $69
  • INPUTFLG: .res 1 → $6A
  • CPRMASK: .res 1 → $6B
  • Z14: .res 1 → $6C
  • (Ends at $6C, just before ZP_START4)

ZP_START4 ($6D):

  • This continues through FAC, ARG, etc.

THE CRITICAL OBSERVATION: With your configuration, ZP_START2 ends somewhere and ZP_START3 begins at $62. This means:

The entire range from approximately $12 through $61 is UNUSED and FREE!

This includes:

  • $50-$5F (your original question) - COMPLETELY FREE
  • Actually $12-$61 is all free (about 80 bytes!)

Why this happens: The original Microsoft BASIC typically had ZP_START3 around $50-$5F range, but your CONFIG_2A has moved it to $62, creating a large gap between the end of ZP_START2 variables and the start of ZP_START3 variables.

CONCLUSION: $50-$5F is DEFINITELY AVAILABLE - in fact, it's part of a large free block from $12-$61 that you can safely use for your own purposes.

This is excellent news for your project - you have plenty of zero page space to work with!

18. Development Workflow (RAM Testing)

To test changes to the shell without burning a new ROM:

  1. Build the RAM Shell:

    cd 6502/ca65
    make

    This creates bin/cmd_shell.bin.

  2. Upload to Pico: Copy bin/cmd_shell.bin to the Pico filesystem (e.g., as NEWSHELL.BIN).

  3. Load and Run: From the existing ROM shell on the 6502:

    LOADMEM 1000 NEWSHELL.BIN
    JUMP 1000
    

    You are now running the new shell from RAM.

19. Build System & File Reference

Build Configuration Files

File Purpose
6502/ca65/Makefile Master Makefile for RAM development. Builds shell and commands.
6502/ca65/common/ram.cfg Linker config for the RAM Shell (Loads at $1000).
6502/ca65/commands/Makefile Makefile for Transient Commands.
6502/ca65/commands/transient.cfg Linker config for Transient Commands (Loads at $0800).

Core Source Files

File Purpose
6502/ca65/shell/cmd_shell.s Master Shell Source. Used for both RAM and ROM builds.
6502/ca65/common/pico_lib.s Hardware Driver. Handles VIA/Pico communication.
6502/ca65/common/pico_def.inc Global Definitions. Constants, Command IDs, Status Codes.

Legacy Files

File Status
6502/ca65/commands/transient.inc Deprecated. Replaced by pico_def.inc and pico_lib.s. Do not use for new commands.

20. Building the Pico Firmware

This project involves two Raspberry Pi Picos:

  1. Bridge Pico (Pico W): The smart peripheral handling filesystem, network, and 6502 bus interface.
  2. Host Pico (Standard Pico): Emulates the 6502 system (if not using real hardware).

20.1 Bridge Pico (Pico W)

Source Location: src/ (Root of repository)

Configuration: Before building, open src/main.c and configure your network settings:

#define WIFI_SSID "YOUR_SSID"
#define WIFI_PASSWORD "YOUR_WIFI_PASS"
#define FILE_SERVER_IP "192.168.1.100" // IP of your PC running file_server.py

Build Steps:

  1. Ensure the Pico SDK is installed and the PICO_SDK_PATH environment variable is set.

  2. Create a build directory:

    mkdir build
    cd build
  3. Run CMake:

    cmake ..
  4. Compile:

    make
  5. Flash: Hold the BOOTSEL button on your Pico W, connect it to USB, and copy the generated W25Q64_INTERLOCK.uf2 file to the RPI-RP2 drive.

20.2 Host Pico (6502 Emulator)

Source Location: emmulator/EMULATOR/

Build Steps:

  1. Navigate to the emulator directory:

    cd emmulator/EMULATOR
  2. Create a build directory:

    mkdir build
    cd build
  3. Run CMake:

    cmake ..
  4. Compile:

    make
  5. Flash: Hold the BOOTSEL button on your standard Pico, connect it to USB, and copy the generated .uf2 file to the RPI-RP2 drive.

21. Last commit branch feature/transient-8

Accomplishments:

  1. System Stability & Synchronization:

    • Corrected issue with Pico bridge in main.c such that a save or load to a non-existing directory is handled gracefully.
  2. New Transient Commands:

    • CLS: Clear the screen and return home (ANSI).
  3. Calculator (CALC):

    • All basic arithmetic operations for unsigned 16-bit integers (0-65535), with comprehensive input validation corrected.