Diagnostic Mode

MODE=DIAG allows testing the card addressing via the PicoPal chip.
This commit is contained in:
David Kuder 2023-01-08 00:37:25 -05:00
parent f2b9d0ff8a
commit 1407b3a20f
9 changed files with 111 additions and 9 deletions

View File

@ -27,6 +27,8 @@ target_sources(v2-analog-${PICO_BOARD} PUBLIC
common/abus.c
common/config.c
common/main.c
diag/businterface.c
diag/diag.c
vga/vgamain.c
vga/businterface.c
vga/vgabuf.c

View File

@ -41,7 +41,7 @@ write_cycle:
read_cycle:
; the current time is P0+88ns (P0 + 16ns + 2 clocks (input synchronizers) + 7 instructions)
set PINS, 0b111 ; ensure AddrLo transceiver is disabled and delay for ~DEVSEL to become valid (P0+63ns+buffer delay)
set PINS, 0b111 [1] ; ensure AddrLo transceiver is disabled and delay for ~DEVSEL to become valid (P0+63ns+buffer delay)
in PINS, 10 ; read R/W, ~DEVSEL, and dontcare[7:0], then autopush
irq set READ_DATA_TRIGGER_IRQ ; trigger the data read state machine to put data on the data bus
@ -80,7 +80,7 @@ wait_loop:
set PINS, 0b01 ; enable Data tranceiver with output direction
mov OSR, ~NULL
out PINDIRS, 8 [31] ; set data pins as outputs
out PINDIRS, 8 [30] ; set data pins as outputs
pull noblock ; pull value from the FIFO as late as possible
out PINS, 8

View File

@ -13,7 +13,9 @@ uint8_t wifi_psk[32];
void parse_config(uint8_t *buffer) {
if(!memcmp("MODE=", buffer, 5)) {
if(!strcmp("VGA", buffer+5)) {
if(!strcmp("DIAG", buffer+5)) {
v2mode = MODE_DIAG;
} else if(!strcmp("VGA", buffer+5)) {
v2mode = MODE_VGACARD;
} else if(!strcmp("Z80", buffer+5)) {
v2mode = MODE_APPLICARD;
@ -40,10 +42,16 @@ void parse_config(uint8_t *buffer) {
} else if(!strcmp("CDC_HOST", buffer+4)) {
usbmux = USB_HOST_CDC;
}
} else if(!memcmp("WIFI=", buffer, 5)) {
if(!strcmp("CLIENT", buffer+5)) {
wifimode = WIFI_CLIENT;
} else if(!strcmp("AP", buffer+5)) {
wifimode = WIFI_AP;
}
} else if(!memcmp("SSID=", buffer, 5)) {
// TODO: Set lwip WIFI SSID
strncpy(wifi_ssid, buffer+5, 25);
} else if(!memcmp("PSK=", buffer, 4)) {
// TODO: Set lwip WIFI PSK
strncpy(wifi_psk, buffer+5, 26);
}
}
@ -58,6 +66,10 @@ void default_config() {
void write_config() {
uint8_t config_temp[32];
if(v2mode == MODE_DIAG) return;
if(v2mode == MODE_REBOOT) return;
int file = pico_open("config", LFS_O_WRONLY | LFS_O_CREAT);
if(file < 0)
return;
@ -178,5 +190,7 @@ void config_handler() {
if(!strcmp("WRITE_CONFIG", (uint8_t*)config_memory)) {
write_config();
} else if(!strcmp("REBOOT", (uint8_t*)config_memory)) {
v2mode = MODE_REBOOT;
} else parse_config((uint8_t*)config_memory);
}

View File

@ -19,6 +19,7 @@
typedef enum {
MODE_REBOOT = 0,
MODE_DIAG,
MODE_VGACARD,
MODE_APPLICARD,
MODE_SERIAL,

View File

@ -4,10 +4,6 @@
#include "common/abus.h"
#include "common/config.h"
#include "common/modes.h"
#include "vga/businterface.h"
#include "z80/businterface.h"
#include "serial/businterface.h"
#include "parallel/businterface.h"
#include "pico_hal.h"
#ifdef RASPBERRYPI_PICO_W
@ -19,6 +15,11 @@ volatile uint8_t core1_running = 0;
static void core1_loop() {
for(;;) {
switch(v2mode) {
case MODE_DIAG:
core1_running = 1;
diag_businterface();
core1_running = 0;
break;
case MODE_VGACARD:
core1_running = 1;
vga_businterface();

View File

@ -1,7 +1,17 @@
void vgamain();
void vga_businterface();
void z80main();
void z80_businterface();
void serialmain();
void serial_businterface();
void parallelmain();
void parallel_businterface();
void diag_businterface();
void diagmain();
void flash_reboot() __attribute__ ((noreturn));

View File

@ -0,0 +1,43 @@
#include <string.h>
#include <hardware/pio.h>
#include "common/config.h"
#include "common/buffers.h"
#include "abus.pio.h"
#include "diag/businterface.h"
static inline void __time_critical_func(shadow_memory)(uint32_t address, uint32_t value) {
// Shadow parts of the Apple's memory by observing the bus write cycles
if(CARD_SELECT) {
if((value & (1u << CONFIG_PIN_APPLEBUS_RW-CONFIG_PIN_APPLEBUS_DATA_BASE)) == 0) {
apple_memory[address] = value;
}
// Config memory in card slot-rom address space
if(CARD_IOSEL) {
if((value & (1u << CONFIG_PIN_APPLEBUS_RW-CONFIG_PIN_APPLEBUS_DATA_BASE)) == 0) {
config_memory[address & 0x1F] = value;
if((address & 0xFF) == 0xFF)
config_handler();
}
}
}
}
void __time_critical_func(diag_businterface)() {
while(v2mode == MODE_DIAG) {
uint32_t value = pio_sm_get_blocking(CONFIG_ABUS_PIO, ABUS_MAIN_SM);
uint32_t dout;
uint32_t address = (value >> 10) & 0xffff;
if((value & (1u << CONFIG_PIN_APPLEBUS_RW-CONFIG_PIN_APPLEBUS_DATA_BASE)) != 0) {
if(CARD_SELECT) {
dout = apple_memory[address];
// device read access
pio_sm_put_blocking(CONFIG_ABUS_PIO, ABUS_DEVICE_READ_SM, dout);
}
}
shadow_memory(address, value);
}
}

View File

@ -0,0 +1,3 @@
#pragma once
void diag_businterface();

View File

@ -0,0 +1,28 @@
#include <pico/stdlib.h>
#include <pico/multicore.h>
#include "common/config.h"
#include "common/buffers.h"
#include "diag/businterface.h"
void diagmain() {
memset((uint8_t*)(apple_memory+0xC080), 0xC0, 0x10);
memset((uint8_t*)(apple_memory+0xC090), 0xC1, 0x10);
memset((uint8_t*)(apple_memory+0xC0A0), 0xC2, 0x10);
memset((uint8_t*)(apple_memory+0xC0B0), 0xC3, 0x10);
memset((uint8_t*)(apple_memory+0xC0C0), 0xC4, 0x10);
memset((uint8_t*)(apple_memory+0xC0D0), 0xC5, 0x10);
memset((uint8_t*)(apple_memory+0xC0E0), 0xC6, 0x10);
memset((uint8_t*)(apple_memory+0xC0F0), 0xC7, 0x10);
memset((uint8_t*)(apple_memory+0xC100), 0xC1, 0x100);
memset((uint8_t*)(apple_memory+0xC200), 0xC2, 0x100);
memset((uint8_t*)(apple_memory+0xC300), 0xC3, 0x100);
memset((uint8_t*)(apple_memory+0xC400), 0xC4, 0x100);
memset((uint8_t*)(apple_memory+0xC500), 0xC5, 0x100);
memset((uint8_t*)(apple_memory+0xC600), 0xC6, 0x100);
memset((uint8_t*)(apple_memory+0xC700), 0xC7, 0x100);
memset((uint8_t*)(apple_memory+0xC800), 0xC8, 0x800);
while(v2mode == MODE_DIAG) {
}
}