From 24b67e2e0c924bccc6a0bd950bb42fc5eb00983d Mon Sep 17 00:00:00 2001
From: Oliver Schmidt
Date: Tue, 2 Jan 2024 22:47:56 +0100
Subject: [PATCH] Make use A2Pico library.
---
RaspberryPiPico/CMakeLists.txt | 12 +-
RaspberryPiPico/board.c | 49 +++-----
RaspberryPiPico/bus.pio | 205 ---------------------------------
RaspberryPiPico/main.c | 8 +-
4 files changed, 23 insertions(+), 251 deletions(-)
delete mode 100644 RaspberryPiPico/bus.pio
diff --git a/RaspberryPiPico/CMakeLists.txt b/RaspberryPiPico/CMakeLists.txt
index 1364538..e946a83 100644
--- a/RaspberryPiPico/CMakeLists.txt
+++ b/RaspberryPiPico/CMakeLists.txt
@@ -1,18 +1,22 @@
set(PROJECT_NAME Apple2-IO-RPi)
cmake_minimum_required(VERSION 3.12)
-
include(pico_sdk_import.cmake)
+project(${PROJECT_NAME} C CXX ASM)
pico_sdk_init()
-project(${PROJECT_NAME} C CXX ASM)
add_executable(${PROJECT_NAME})
pico_add_extra_outputs(${PROJECT_NAME})
pico_enable_stdio_uart(${PROJECT_NAME} 0)
pico_enable_stdio_usb(${PROJECT_NAME} 1)
-pico_generate_pio_header(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR}/bus.pio)
+include(FetchContent)
+FetchContent_Declare(a2pico
+ GIT_REPOSITORY https://github.com/oliverschmidt/a2pico.git
+ GIT_TAG main
+ )
+FetchContent_MakeAvailable(a2pico)
target_sources(${PROJECT_NAME} PRIVATE
main.c
@@ -23,5 +27,5 @@ target_sources(${PROJECT_NAME} PRIVATE
target_link_libraries(${PROJECT_NAME} PRIVATE
pico_stdlib
pico_multicore
- hardware_pio
+ a2pico
)
diff --git a/RaspberryPiPico/board.c b/RaspberryPiPico/board.c
index cf62246..d6e440f 100644
--- a/RaspberryPiPico/board.c
+++ b/RaspberryPiPico/board.c
@@ -24,9 +24,9 @@ SOFTWARE.
*/
-#include "pico/multicore.h"
+#include
-#include "bus.pio.h"
+#include
#include "board.h"
@@ -35,57 +35,34 @@ extern const __attribute__((aligned(4))) uint8_t firmware[];
static uint32_t page;
void __time_critical_func(board)(void) {
- for (uint gpio = gpio_addr; gpio < gpio_addr + size_addr; gpio++) {
- gpio_init(gpio);
- gpio_set_pulls(gpio, false, false); // floating
- }
- for (uint gpio = gpio_data; gpio < gpio_data + size_data; gpio++) {
- pio_gpio_init(pio0, gpio);
- gpio_set_pulls(gpio, false, false); // floating
- }
-
- gpio_init(gpio_enbl);
- gpio_set_pulls(gpio_enbl, false, false); // floating
-
- uint offset;
-
- offset = pio_add_program(pio0, &enbl_program);
- enbl_program_init(offset);
-
- offset = pio_add_program(pio0, &write_program);
- write_program_init(offset);
-
- offset = pio_add_program(pio0, &read_program);
- read_program_init(offset);
-
- page = 0;
+ a2pico_init(pio0);
while (true) {
- uint32_t enbl = pio_sm_get_blocking(pio0, sm_enbl);
- uint32_t addr = enbl & 0x0FFF;
- uint32_t io = enbl & 0x0F00; // IOSTRB or IOSEL
- uint32_t strb = enbl & 0x0800; // IOSTRB
- uint32_t read = enbl & 0x1000; // R/W
+ uint32_t pico = a2pico_getaddr(pio0);
+ uint32_t addr = pico & 0x0FFF;
+ uint32_t io = pico & 0x0F00; // IOSTRB or IOSEL
+ uint32_t strb = pico & 0x0800; // IOSTRB
+ uint32_t read = pico & 0x1000; // R/W
if (read) {
if (!io) { // DEVSEL
switch (addr & 0x7) {
case 0x3:
- pio_sm_put(pio0, sm_read, !multicore_fifo_rvalid() << 7 |
- !multicore_fifo_wready() << 6);
+ a2pico_putdata(pio0, !multicore_fifo_rvalid() << 7 |
+ !multicore_fifo_wready() << 6);
break;
case 0x6:
- pio_sm_put(pio0, sm_read, sio_hw->fifo_rd);
+ a2pico_putdata(pio0, sio_hw->fifo_rd);
break;
}
} else {
if (!strb) {
- pio_sm_put(pio0, sm_read, firmware[page | addr]);
+ a2pico_putdata(pio0, firmware[page | addr]);
}
}
} else {
- uint32_t data = pio_sm_get_blocking(pio0, sm_write);
+ uint32_t data = a2pico_getdata(pio0);
if (!io) { // DEVSEL
switch (addr & 0x7) {
case 0x5:
diff --git a/RaspberryPiPico/bus.pio b/RaspberryPiPico/bus.pio
deleted file mode 100644
index 6dd012a..0000000
--- a/RaspberryPiPico/bus.pio
+++ /dev/null
@@ -1,205 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-
-/*
-
-MIT License
-
-Copyright (c) 2022 Oliver Schmidt (https://a2retro.de/)
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-
-*/
-
-///////////////////////////////////////////////////////////////////////////////
-
-.define public gpio_addr 2 // 12 pins
-.define public gpio_rw 14
-.define public gpio_data 15 // 8 pins
-.define public gpio_enbl 23 // DEVSEL | IOSEL | IOSTRB
-.define public gpio_irq 24
-.define public gpio_res 25
-
-.define public size_addr 13 // incl. R/W
-.define public size_data 8
-
-.define public sm_enbl 0
-.define public sm_read 1 // from Apple II perspective
-.define public sm_write 2 // from Apple II perspective
-
-.define irq_write 4
-
-/*
-
-Implementation of the Apple II peripheral bus protocol:
-
-- /DEVSEL, /IOSEL and /IOSTRB are supposed to combined to ENBL via an AND gate.
-
-- On the falling edge of ENBL, the lines A0-A11 and R/W are sampled and pushed
- into the 'enable' state machine RX FIFO.
-
-- In case of an Apple II write cycle, the lines D0-D7 are sampled ~300ns later
- and pushed into the 'write' state machine RX FIFO.
-
-- If a byte is pushed into the 'read' state machine TX FIFO, it is driven out
- to the lines D0-D7 until the rising edge of ENBL.
-
-*/
-
-///////////////////////////////////////////////////////////////////////////////
-
-.program enbl
-
-.wrap_target
-
-idle:
- wait 1 gpio gpio_enbl // wait for ENBL to rise
- wait 0 gpio gpio_enbl // wait for ENBL to fall
-
- in pins, size_addr // shift A0-A11 + R/W into ISR
-
- jmp pin idle // jump to 'idle' if R/W is high
-
- irq irq_write // set 'write' IRQ
-
-.wrap
-
-% c-sdk {
-static inline void enbl_program_init(uint offset) {
- pio_sm_config c = enbl_program_get_default_config(offset);
-
- // in_base: gpio_addr
- sm_config_set_in_pins(&c, gpio_addr);
-
- // shift_right: false
- // autopush: true
- // push_threshold: size_addr
- sm_config_set_in_shift(&c, false, true, size_addr);
-
- // pin: gpio_rw
- sm_config_set_jmp_pin(&c, gpio_rw);
-
- // state_machine: sm_enbl
- // initial_pc: offset
- pio_sm_init(pio0, sm_enbl, offset, &c);
-
- // state_machine: sm_enbl
- pio_sm_set_enabled(pio0, sm_enbl, true);
-}
-%}
-
-///////////////////////////////////////////////////////////////////////////////
-
-.program write
-
-.wrap_target
-
- wait 1 irq irq_write [31] // wait for 'write' IRQ to be set and clear it
- // [31 cycles to allow 6502 to set up D0-D7]
-
- in pins, size_data // shift D0-D7 into ISR
-
-.wrap
-
-% c-sdk {
-static inline void write_program_init(uint offset) {
- pio_sm_config c = write_program_get_default_config(offset);
-
- // in_base: gpio_data
- sm_config_set_in_pins(&c, gpio_data);
-
- // shift_right: false
- // autopush: true
- // push_threshold: size_data
- sm_config_set_in_shift(&c, false, true, size_data);
-
- // state_machine: sm_write
- // initial_pc: offset
- pio_sm_init(pio0, sm_write, offset, &c);
-
- // state_machine: sm_write
- pio_sm_set_enabled(pio0, sm_write, true);
-}
-%}
-
-///////////////////////////////////////////////////////////////////////////////
-
-.program read
-
-/*
-
-Both set and set-side are limited to 5 pins each. So both set and side-set are
-configured to set (the direction of) 4 pins. This approach allows to set the
-direction of D0-D7 in one operation.
-
-Note: The naive approach would have been
- mov osr, ~x // move 0xFFFFFFFF to OSR
- out pindirs, size_data // enable output of D0-D7
- [...]
- mov osr, x // move 0x00000000 to OSR
- out pindirs, size_data // disable output of D0-D7
-but this would have required two operations and destroyed OSR.
-
-*/
-
-.side_set (size_data / 2) opt pindirs
-
-.wrap_target
-
- pull block // pull data into OSR, block on empty FIFO
-
- out pins, size_data // shift OSR out to D0-D7
-
- set pindirs, 15 side 15 // enable output of D0-D7
-
- wait 1 gpio gpio_enbl // wait for ENBL to rise
-
- set pindirs, 0 side 0 // disable output of D0-D7
-
-.wrap
-
-% c-sdk {
-static inline void read_program_init(uint offset) {
- pio_sm_config c = read_program_get_default_config(offset);
-
- // out_base: gpio_data
- // out_count: size_data
- sm_config_set_out_pins(&c, gpio_data, size_data);
-
- // shift_right: true
- // autopull: false
- // pull_threshold: size_data
- sm_config_set_out_shift(&c, true, false, size_data);
-
- // set_base: gpio_data
- // set_count: size_data / 2
- sm_config_set_set_pins(&c, gpio_data, size_data / 2);
-
- // sideset_base: gpio_data + size_data / 2
- sm_config_set_sideset_pins(&c, gpio_data + size_data / 2);
-
- // state_machine: sm_read
- // initial_pc: offset
- pio_sm_init(pio0, sm_read, offset, &c);
-
- // state_machine: sm_read
- pio_sm_set_enabled(pio0, sm_read, true);
-}
-%}
-
-///////////////////////////////////////////////////////////////////////////////
diff --git a/RaspberryPiPico/main.c b/RaspberryPiPico/main.c
index 8d2545d..62fd90f 100644
--- a/RaspberryPiPico/main.c
+++ b/RaspberryPiPico/main.c
@@ -29,7 +29,6 @@ SOFTWARE.
#include
#include
-#include "bus.pio.h"
#include "board.h"
#ifdef TRACE
@@ -49,17 +48,14 @@ void uart_printf(uart_inst_t *uart, const char *format, ...) {
void main(void) {
multicore_launch_core1(board);
- gpio_init(gpio_irq);
- gpio_pull_up(gpio_irq);
-
stdio_init_all();
stdio_set_translate_crlf(&stdio_usb, false);
#ifdef TRACE
uart_init(uart0, 115200);
uart_set_translate_crlf(uart0, true);
- gpio_set_function(0, GPIO_FUNC_UART);
- gpio_set_function(1, GPIO_FUNC_UART);
+ gpio_set_function(PICO_DEFAULT_UART_TX_PIN, GPIO_FUNC_UART);
+ gpio_set_function(PICO_DEFAULT_UART_RX_PIN, GPIO_FUNC_UART);
#endif
while (true) {