Compare commits

...

21 Commits

Author SHA1 Message Date
David Kuder 0a23cd3eff Hardware UART should only be enabled on AnalogGS or custom hardware 2023-04-17 00:48:40 -04:00
David Kuder ef562a65b8 Add missing includes 2023-04-17 00:32:44 -04:00
David Kuder 75b8799a4d Add 4ns VGA builds 2023-04-17 00:32:37 -04:00
David Kuder 912c4992bd Fix PICO_SDK_PATH environment variable in build.sh 2023-04-17 00:30:27 -04:00
David Kuder f2e41270f9 Bus timing tweaks for IIgs 2023-04-16 23:40:51 -04:00
David Kuder 9b8e49bc0f DPMS timeout tweaks for IIgs 2023-04-16 23:40:32 -04:00
David Kuder 03b23c10d0 ROM config window initialization 2023-04-16 23:38:28 -04:00
David Kuder 2ac788fbf2 UART initialization for Z80 mode 2023-04-16 23:37:40 -04:00
David Kuder d94cdbc9fd Fix config not being read 2023-04-16 23:25:38 -04:00
David Kuder 99f0b1483e Fix config tokens 2023-04-16 23:25:12 -04:00
David Kuder 14086c1a9e Config cleanup 2023-04-16 23:24:37 -04:00
David Kuder 5b008a72f0 Fix USB/UART abstraction backwards 2023-04-16 23:23:09 -04:00
David Kuder b7380a8022 RGB bit count for AnalogGS 2023-04-16 23:22:45 -04:00
David Kuder afac553ed6 Fix tbcolor/border on IIgs 2023-04-16 23:22:11 -04:00
David Kuder 0a2f2a6e46 Default colors for monochrome & classic 80-col modes. 2023-04-16 23:21:45 -04:00
David Kuder 80711a169a Fix test screen for AnalogGS 12-bit video 2023-04-16 23:20:58 -04:00
David Kuder 8acc28abb5 Fix SuperHiRes rendering for AnalogGS 2023-04-16 23:20:33 -04:00
David Kuder 77574312ea Update .gitignore 2023-04-16 23:20:05 -04:00
David Kuder 1bfe6296b6 Build strings for hardware type 2023-04-16 23:18:38 -04:00
David Kuder 55d2dfa988 Add UART library for Z80 mode 2023-04-16 23:17:13 -04:00
David Kuder d14f9c6a27 Add ANALOG_WIFI define 2023-04-16 23:16:50 -04:00
15 changed files with 181 additions and 104 deletions

1
.gitignore vendored
View File

@ -10,3 +10,4 @@ compile_commands.json
CTestTestfile.cmake
_deps
build/
tools/mksparse

View File

@ -52,6 +52,10 @@ if(${CMAKE_CURRENT_BINARY_DIR} MATCHES "-gs")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DANALOG_GS=1")
endif()
if(${CMAKE_CURRENT_BINARY_DIR} MATCHES "-wifi")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DANALOG_WIFI=1")
endif()
if(${CMAKE_CURRENT_BINARY_DIR} MATCHES "-4ns")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DCONFIG_SYSCLOCK=252 -DPICO_FLASH_SPI_CLKDIV=8 -DOVERCLOCKED=1")
if(${CMAKE_CURRENT_BINARY_DIR} MATCHES "-gs")
@ -134,6 +138,7 @@ if(${CMAKE_CURRENT_BINARY_DIR} MATCHES "-z80")
target_link_libraries(v2-analog${BINARY_TAGS} PUBLIC
tinyusb_device
tinyusb_board
hardware_uart
)
endif()

View File

@ -1,7 +1,7 @@
#!/bin/bash
if [ -z ${PICO_SDK:+x} ]; then
echo You must set PICO_SDK to the path where you downloaded https://github.com/raspberrypi/pico-sdk.git
if [ -z ${PICO_SDK_PATH:+x} ]; then
echo You must set PICO_SDK_PATH to the path where you downloaded https://github.com/raspberrypi/pico-sdk.git
exit 1
fi
@ -15,7 +15,9 @@ build_firmware() {
build_firmware v2-analog-lc-4ns-z80
build_firmware v2-analog-lc-8ns-z80
build_firmware v2-analog-lc-4ns-vga
build_firmware v2-analog-lc-8ns-vga
build_firmware v2-analog-wifi-4ns-z80
build_firmware v2-analog-wifi-8ns-z80
build_firmware v2-analog-wifi-4ns-vga
build_firmware v2-analog-wifi-8ns-vga

View File

@ -33,7 +33,7 @@ next_bus_cycle:
write_cycle:
; the current time is P0+82ns (P0 + 10ns + 2 clocks (input synchronizers) + 16 instructions)
set PINS, 0b110 [31] ; enable Data tranceiver & wait until both ~DEVSEL and the written data are valid (P0+210ns)
set PINS, 0b110 [21] ; enable Data tranceiver & wait until both ~DEVSEL and the written data are valid (P0+170ns)
in PINS, 10 ; read R/W, ~DEVSEL, and Data[7:0], then autopush
wait 0 GPIO, PHI0_GPIO [7] ; wait for PHI0 to fall
jmp next_bus_cycle
@ -71,8 +71,8 @@ wait_loop:
;
; Phase 0 is typically 489 ns long.
; * Data from peripherals should be valid on the data bus by 45 nanoseconds before the end of phase 0
; * Data should be held for 40ns after phase 0 ends
; * Data bus should be tri-stated within 60ns after phase 0 ends
; * Data should be held for no more than 20ns after phase 0 ends
; * Data bus should be tri-stated within 30ns after phase 0 ends
irq set DATA_BUSY_IRQ
@ -85,7 +85,7 @@ wait_loop:
; the current time is P0+424ns (P0 + 10ns + 2 clocks (input synchronizers) + 101 instructions)
wait 0 GPIO, PHI0_GPIO [7] ; wait for PHI0 to fall then hold for 40ns (2 clocks (input synchronizers) + 7 instructions)
wait 0 GPIO, PHI0_GPIO [2] ; wait for PHI0 to fall then hold for 15ns (2 clocks (input synchronizers) + 7 instructions)
set PINS, 0b10 ; disable Data tranceiver to tri-state the data bus
mov OSR, NULL

View File

@ -2,3 +2,16 @@
#define BUILDID 0x0171
#define BUILDSTR " 3 Apr 2023 Build 0171"
#ifdef ANALOG_GS
#define HWSTRING " V2 Analog GS Rev1"
#define HWBYTE 'G'
#define HWREV '1'
#elif defined(ANALOG_WIFI)
#define HWSTRING " V2 Analog WiFi Rev1"
#define HWBYTE 'W'
#define HWREV '1'
#else
#define HWSTRING " V2 Analog LC Rev1"
#define HWBYTE 'L'
#define HWREV '1'
#endif

View File

@ -1,7 +1,7 @@
#define NEWCONFIG_MAGIC 0x0001434E // "NC\x01\x00"
#define NEWCONFIG_EOF_MARKER 0x00464F45 // "EOF\x00"
#define CFGTOKEN_REVISION 0x00015652 // "RV\xXX\x00"
#define CFGTOKEN_REVISION 0x00005652 // "RV\xXX\x00"
#define CFGTOKEN_MODE_VGA 0x0000564D // "MV\x00\x00" VGA
#define CFGTOKEN_MODE_PCPI 0x00005A4D // "MZ\x00\x00" PCPI Applicard
@ -38,8 +38,8 @@
#define CFGTOKEN_WIFI_IP 0x04004957 // "WI\x00\xSS" WiFi IP
#define CFGTOKEN_WIFI_NM 0x04004E57 // "WN\x00\xSS" WiFi Netmask
#define CFGTOKEN_JD_HOST 0x0000484A // "JH\x00\x01" JetDirect Hostname
#define CFGTOKEN_JD_PORT 0x0200444A // "JD\x00\x01" JetDirect Port
#define CFGTOKEN_JD_HOST 0x0000484A // "JH\x00\xSS" JetDirect Hostname
#define CFGTOKEN_JD_PORT 0x0200504A // "JP\x00\x02" JetDirect Port
#define CFGTOKEN_FONT_00 0x00004656 // "VF\xXX\x00" Custom default font

View File

@ -98,7 +98,7 @@ bool DELAYED_COPY_CODE(parse_config)(uint32_t address) {
case CFGTOKEN_BORDER:
terminal_border = (config[i] >> 16) & 0xF;
break;
#else
#elif defined(FUNCTION_Z80)
case CFGTOKEN_MUX_LOOP:
serialmux[(config[i] >> 16) & 1] = SERIAL_LOOP;
break;
@ -273,7 +273,7 @@ int DELAYED_COPY_CODE(make_config)(uint32_t rev) {
#endif
#ifdef FUNCTION_VGA
config_temp[i++] = CFGTOKEN_FONT_00 | ((romx_textbank & 0x2F) << 20);
config_temp[i++] = CFGTOKEN_FONT_00 | ((romx_textbank & 0x2F) << 16);
config_temp[i++] = CFGTOKEN_MONO_00 | ((mono_palette & 0xF) << 20);
config_temp[i++] = CFGTOKEN_TBCOLOR | ((terminal_tbcolor & 0xFF) << 16);
config_temp[i++] = CFGTOKEN_BORDER | ((terminal_border & 0xF) << 16);
@ -324,10 +324,9 @@ bool DELAYED_COPY_CODE(is_primary_config_newer)() {
uint8_t a=get_config_rev(FLASH_CONFIG_PRIMARY);
uint8_t b=get_config_rev(FLASH_CONFIG_SECONDARY);
return (a == ((b+1) & 0xff));
return ((int8_t)(a-b)) >= 0;
}
bool DELAYED_COPY_CODE(read_config)() {
if(is_config_valid(FLASH_CONFIG_ONETIME)) {
internal_flags &= ~IFLAGS_TEST;
@ -726,16 +725,10 @@ void DELAYED_COPY_CODE(config_handler)() {
case 'h':
// Identify Hardware Type
retval = REPLY_OK;
config_rpybuf[rs++] = 0x02; // V2 Retro Computing
#ifdef ANALOG_GS
// AnalogGS Rev 1
config_rpybuf[rs++] = 'G';
config_rpybuf[rs++] = '1';
#else
// Analog Rev 1
config_rpybuf[rs++] = 'A';
config_rpybuf[rs++] = '1';
#endif
config_rpybuf[rs++] = 0x02; // V2 Retro Computing
config_rpybuf[rs++] = 'A'; // V2 Analog
config_rpybuf[rs++] = HWBYTE; // 'G'S / 'W'ifi / 'L'C
config_rpybuf[rs++] = HWREV; // '1'
break;
case 'd':

View File

@ -1,15 +1,20 @@
#include <stdio.h>
#include <string.h>
#include <pico/stdlib.h>
#include <pico/multicore.h>
#include <hardware/pio.h>
#include "common/abus.h"
#include "common/config.h"
#include "common/build.h"
#include "common/modes.h"
#include "common/buffers.h"
#include "common/flash.h"
#include "common/dmacopy.h"
#ifdef FUNCTION_Z80
#include "z80/z80buf.h"
#include <hardware/uart.h>
#endif
#ifdef RASPBERRYPI_PICO_W
#include <pico/cyw43_arch.h>
#endif
@ -172,20 +177,53 @@ int main() {
memcpy32((void*)apple_memory+0xC000, (void *)FLASH_6502_BASE, FLASH_6502_SIZE);
// Initialize the config window in each rom slot
memcpy((uint8_t*)apple_memory+0xC1F0, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFFV2ANALOG", 16);
memcpy((uint8_t*)apple_memory+0xC2F0, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFFV2ANALOG", 16);
memcpy((uint8_t*)apple_memory+0xC3F0, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFFV2ANALOG", 16);
memcpy((uint8_t*)apple_memory+0xC4F0, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFFV2ANALOG", 16);
memcpy((uint8_t*)apple_memory+0xC5F0, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFFV2ANALOG", 16);
memcpy((uint8_t*)apple_memory+0xC6F0, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFFV2ANALOG", 16);
memcpy((uint8_t*)apple_memory+0xC7F0, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFFV2ANALOG", 16);
memcpy((uint8_t*)apple_memory+0xC1F0, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFFV2AxCx00", 16);
memcpy((uint8_t*)apple_memory+0xC2F0, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFFV2AxCx00", 16);
memcpy((uint8_t*)apple_memory+0xC3F0, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFFV2AxCx00", 16);
memcpy((uint8_t*)apple_memory+0xC4F0, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFFV2AxCx00", 16);
memcpy((uint8_t*)apple_memory+0xC5F0, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFFV2AxCx00", 16);
memcpy((uint8_t*)apple_memory+0xC6F0, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFFV2AxCx00", 16);
memcpy((uint8_t*)apple_memory+0xC7F0, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFFV2AxCx00", 16);
// Card Type identifiers
apple_memory[0xC1FB] = HWBYTE;
apple_memory[0xC2FB] = HWBYTE;
apple_memory[0xC3FB] = HWBYTE;
apple_memory[0xC4FB] = HWBYTE;
apple_memory[0xC5FB] = HWBYTE;
apple_memory[0xC6FB] = HWBYTE;
apple_memory[0xC7FB] = HWBYTE;
// Slot identifiers
apple_memory[0xC1FD] = '1';
apple_memory[0xC2FD] = '2';
apple_memory[0xC3FD] = '3';
apple_memory[0xC4FD] = '4';
apple_memory[0xC5FD] = '5';
apple_memory[0xC6FD] = '6';
apple_memory[0xC7FD] = '7';
// Finish copying remaining data and code to RAM from flash
dmacpy32(__ram_delayed_copy_start__, __ram_delayed_copy_end__, __ram_delayed_copy_source__);
// Sensible defaults if there is no config / fs
default_config();
// Load the config from flash, or defaults
read_config();
#if defined(FUNCTION_Z80) && defined(ANALOG_GS)
uart_init(uart0, sio[0].baudrate);
uart_init(uart1, sio[1].baudrate);
gpio_set_function(0, GPIO_FUNC_UART);
gpio_set_function(1, GPIO_FUNC_UART);
gpio_set_function(2, GPIO_FUNC_UART);
gpio_set_function(3, GPIO_FUNC_UART);
gpio_set_function(4, GPIO_FUNC_UART);
gpio_set_function(5, GPIO_FUNC_UART);
gpio_set_function(6, GPIO_FUNC_UART);
gpio_set_function(7, GPIO_FUNC_UART);
#endif
core0_loop();
return 0;

View File

@ -152,11 +152,11 @@ void DELAYED_COPY_CODE(render_loop)() {
} else {
if(busactive == 0) {
screentimeout++;
if(screentimeout == 5) {
if(screentimeout == 30) {
update_status_right("Going to sleep...");
}
} else {
if(screentimeout >= 5) {
if(screentimeout >= 30) {
// Clear the sleep mode message
memset(status_line, 0, sizeof(status_line));
status_timeout = 0;

View File

@ -48,20 +48,29 @@ static void DELAYED_COPY_CODE(render_shr_line)(uint16_t line) {
i = 0;
if(control & 0x80) { // 640 Pixels
while(i < 160) {
// Load in the next 2 pixels
// Load in the next 4 pixels
dots = (line_mem[i++] & 0xff);
color_a = ((dots >> 4) & 0xf);
color_b = ((dots >> 0) & 0xf);
color_a = ((dots >> 6) & 0x3);
color_b = ((dots >> 4) & 0x3);
// Consume 2 pixels
pixeldata = rgb444(shr_palette[color_a]) | THEN_EXTEND_1;
pixeldata |= (rgb444(shr_palette[color_b]) | THEN_EXTEND_1) << 16;
pixeldata = rgb444(shr_palette[color_a | 0x8]);
pixeldata |= (rgb444(shr_palette[color_b | 0xC])) << 16;
sl->data[sl_pos++] = pixeldata;
color_a = ((dots >> 2) & 0x3);
color_b = ((dots >> 0) & 0x3);
// Consume 2 pixels
pixeldata = rgb444(shr_palette[color_a | 0x0]);
pixeldata |= (rgb444(shr_palette[color_b | 0x4])) << 16;
sl->data[sl_pos++] = pixeldata;
}
} else if(control & 0x40) { // 320 Pixels w/ color fill
while(i < 160) {
// Load in the next 4 subpixels
// Load in the next 2 pixels
dots = (line_mem[i++] & 0xff);
// Consume 2 pixels

View File

@ -16,7 +16,7 @@ char __attribute__((section(".uninitialized_data."))) error_message[32*24+1];
void DELAYED_COPY_CODE(render_test_init)() {
memset(error_message, ' ', 32*24);
memcpy(error_message + 0, "HARDWARE: V2 Analog Rev1", 32);
memcpy(error_message + 0, "HARDWARE: " HWSTRING, 32);
memcpy(error_message + 32, "FIRMWARE: " BUILDSTR, 32);
memcpy(error_message + 128, " Copyright (C) 2022-2023 ", 32);
@ -63,32 +63,32 @@ void DELAYED_COPY_CODE(render_testpattern)() {
if((line == 0) || (line == VGA_HEIGHT-1) || (line == 36) || (line == VGA_HEIGHT-36-1)) {
for(; sl_pos < VGA_WIDTH/32; sl_pos++) {
sl->data[sl_pos] = _PIXPAIR(0x1ff | THEN_EXTEND_15, 0x1ff | THEN_EXTEND_15);
sl->data[sl_pos] = _PIXPAIR(_RGB(255, 255, 255) | THEN_EXTEND_15, _RGB(255, 255, 255) | THEN_EXTEND_15);
}
sl->length = sl_pos;
} else if(line == 1) {
for(uint i=0; i < VGA_WIDTH/4; i++, sl_pos++) {
sl->data[sl_pos] = _PIXPAIR(0x1ff, 0);
sl->data[sl_pos] = _PIXPAIR(_RGB(255, 255, 255), _RGB(0, 0, 0));
}
for(uint i=0; i < VGA_WIDTH/4; i++, sl_pos++) {
sl->data[sl_pos] = _PIXPAIR(0, 0x1ff);
sl->data[sl_pos] = _PIXPAIR(_RGB(0, 0, 0), _RGB(255, 255, 255));
}
sl->length = sl_pos;
sl->repeat_count = 16;
} else if(line == VGA_HEIGHT-36) {
for(uint i=0; i < VGA_WIDTH/4; i++, sl_pos++) {
sl->data[sl_pos] = _PIXPAIR(0x1ff, 0);
sl->data[sl_pos] = _PIXPAIR(_RGB(255, 255, 255), _RGB(0, 0, 0));
}
for(uint i=0; i < VGA_WIDTH/4; i++, sl_pos++) {
sl->data[sl_pos] = _PIXPAIR(0, 0x1ff);
sl->data[sl_pos] = _PIXPAIR(_RGB(0, 0, 0), _RGB(255, 255, 255));
}
sl->length = sl_pos;
sl->repeat_count = 34;
} else if((line >= 48) && (line < 48+128)) {
sl->data[sl_pos++] = _PIXPAIR(0x1ff, 0 | THEN_EXTEND_6); // 8px
sl->data[sl_pos++] = _PIXPAIR(0 | THEN_EXTEND_1, 0 | THEN_EXTEND_1); // 4px
sl->data[sl_pos++] = _PIXPAIR(_RGB(255, 255, 255), _RGB(0, 0, 0) | THEN_EXTEND_6); // 8px
sl->data[sl_pos++] = _PIXPAIR(_RGB(0, 0, 0) | THEN_EXTEND_1, _RGB(0, 0, 0) | THEN_EXTEND_1); // 4px
const uint z = (line - 48);
@ -96,18 +96,18 @@ void DELAYED_COPY_CODE(render_testpattern)() {
const uint g = z / 16;
for(uint b=0; b < 3; b++) {
for(uint r=0; r < 8; r++) {
const uint rgb = (r << 6) | (g << 3) | b;
sl->data[sl_pos++] = _PIXPAIR(0, rgb | THEN_EXTEND_6); // 8px
sl->data[sl_pos++] = _PIXPAIR(rgb | THEN_EXTEND_6, 0); // 8px
const uint32_t rgb = _RGB((r << 5), (g << 5), (b << 5));
sl->data[sl_pos++] = _PIXPAIR(_RGB(0, 0, 0), rgb | THEN_EXTEND_6); // 8px
sl->data[sl_pos++] = _PIXPAIR(rgb | THEN_EXTEND_6, _RGB(0, 0, 0)); // 8px
}
}
} else {
for(uint i=0; i < 12; i++) {
sl->data[sl_pos++] = _PIXPAIR(0 | THEN_EXTEND_15, 0 | THEN_EXTEND_15); // 384px
sl->data[sl_pos++] = _PIXPAIR(_RGB(0, 0, 0) | THEN_EXTEND_15, _RGB(0, 0, 0) | THEN_EXTEND_15); // 384px
}
}
sl->data[sl_pos++] = _PIXPAIR(0 | THEN_EXTEND_3, 0 | THEN_EXTEND_3); // 8px
sl->data[sl_pos++] = _PIXPAIR(_RGB(0, 0, 0) | THEN_EXTEND_3, _RGB(0, 0, 0) | THEN_EXTEND_3); // 8px
const uint w = (line - 48) << 1;
for(uint i=0; i < 32; i+=2) {
@ -115,21 +115,21 @@ void DELAYED_COPY_CODE(render_testpattern)() {
uint32_t bits_b = char_test_bits(error_message[(w & 0x3E0) | (i+1)], (w>>2) & 0x7);
uint32_t bits = (bits_a << 7) | bits_b;
for(uint j=0; j < 7; j++) {
uint32_t pixeldata = (bits & 0x2000) ? (0) : (0x1ff);
pixeldata |= (bits & 0x1000) ? ((0) << 16) : ((0x1ff) << 16);
uint32_t pixeldata = (bits & 0x2000) ? (_RGB(0, 0, 0)) : (_RGB(255, 255, 255));
pixeldata |= (bits & 0x1000) ? ((_RGB(0, 0, 0)) << 16) : ((_RGB(255, 255, 255)) << 16);
bits <<= 2;
sl->data[sl_pos++] = pixeldata;
}
}
sl->data[sl_pos++] = _PIXPAIR(0 | THEN_EXTEND_1, 0 | THEN_EXTEND_1); // 4px
sl->data[sl_pos++] = _PIXPAIR(0 | THEN_EXTEND_6, 0x1ff); // 8px
sl->data[sl_pos++] = _PIXPAIR(_RGB(0, 0, 0) | THEN_EXTEND_1, _RGB(0, 0, 0) | THEN_EXTEND_1); // 4px
sl->data[sl_pos++] = _PIXPAIR(_RGB(0, 0, 0) | THEN_EXTEND_6, _RGB(255, 255, 255)); // 8px
sl->repeat_count = 1;
sl->length = sl_pos;
} else if((line >= 176) && (line < 176+128)) {
sl->data[sl_pos++] = _PIXPAIR(0x1ff, 0 | THEN_EXTEND_6); // 8px
sl->data[sl_pos++] = _PIXPAIR(0 | THEN_EXTEND_1, 0 | THEN_EXTEND_1); // 4px
sl->data[sl_pos++] = _PIXPAIR(_RGB(255, 255, 255), _RGB(0, 0, 0) | THEN_EXTEND_6); // 8px
sl->data[sl_pos++] = _PIXPAIR(_RGB(0, 0, 0) | THEN_EXTEND_1, _RGB(0, 0, 0) | THEN_EXTEND_1); // 4px
const uint z = (line - 176);
const uint g = z / 16;
@ -138,13 +138,13 @@ void DELAYED_COPY_CODE(render_testpattern)() {
if((z & 0xf) < 14) {
uint b = 3;
for(uint r=0; r < 8; r++) {
const uint rgb = (r << 6) | (g << 3) | b;
sl->data[sl_pos++] = _PIXPAIR(0, rgb | THEN_EXTEND_6);
sl->data[sl_pos++] = _PIXPAIR(rgb | THEN_EXTEND_6, 0);
const uint32_t rgb = _RGB((r << 5), (g << 5), (b << 5));
sl->data[sl_pos++] = _PIXPAIR(_RGB(0, 0, 0), rgb | THEN_EXTEND_6);
sl->data[sl_pos++] = _PIXPAIR(rgb | THEN_EXTEND_6, _RGB(0, 0, 0));
}
} else {
for(uint i=0; i < 4; i++) {
sl->data[sl_pos++] = _PIXPAIR(0 | THEN_EXTEND_15, 0 | THEN_EXTEND_15);
sl->data[sl_pos++] = _PIXPAIR(_RGB(0, 0, 0) | THEN_EXTEND_15, _RGB(0, 0, 0) | THEN_EXTEND_15);
}
}
@ -159,17 +159,17 @@ void DELAYED_COPY_CODE(render_testpattern)() {
if((z & 0xf) < 14) {
uint b = 4;
for(uint r=0; r < 8; r++) {
const uint rgb = (r << 6) | (g << 3) | b;
sl->data[sl_pos++] = _PIXPAIR(0, rgb | THEN_EXTEND_6);
sl->data[sl_pos++] = _PIXPAIR(rgb | THEN_EXTEND_6, 0);
const uint32_t rgb = _RGB((r << 5), (g << 5), (b << 5));
sl->data[sl_pos++] = _PIXPAIR(_RGB(0, 0, 0), rgb | THEN_EXTEND_6);
sl->data[sl_pos++] = _PIXPAIR(rgb | THEN_EXTEND_6, _RGB(0, 0, 0));
}
} else {
for(uint i=0; i < 4; i++) {
sl->data[sl_pos++] = _PIXPAIR(0 | THEN_EXTEND_15, 0 | THEN_EXTEND_15);
sl->data[sl_pos++] = _PIXPAIR(_RGB(0, 0, 0) | THEN_EXTEND_15, _RGB(0, 0, 0) | THEN_EXTEND_15);
}
}
sl->data[sl_pos++] = _PIXPAIR(0 | THEN_EXTEND_3, 0 | THEN_EXTEND_3); // 8px
sl->data[sl_pos++] = _PIXPAIR(_RGB(0, 0, 0) | THEN_EXTEND_3, _RGB(0, 0, 0) | THEN_EXTEND_3); // 8px
const uint w = (line - 48) << 1;
for(uint i=0; i < 32; i+=2) {
@ -177,21 +177,21 @@ void DELAYED_COPY_CODE(render_testpattern)() {
uint32_t bits_b = char_test_bits(error_message[(w & 0x3E0) | (i+1)], (w>>2) & 0x7);
uint32_t bits = (bits_a << 7) | bits_b;
for(uint j=0; j < 7; j++) {
uint32_t pixeldata = (bits & 0x2000) ? (0) : (0x1ff);
pixeldata |= (bits & 0x1000) ? ((0) << 16) : ((0x1ff) << 16);
uint32_t pixeldata = (bits & 0x2000) ? (_RGB(0, 0, 0)) : (_RGB(255, 255, 255));
pixeldata |= (bits & 0x1000) ? ((_RGB(0, 0, 0)) << 16) : ((_RGB(255, 255, 255)) << 16);
bits <<= 2;
sl->data[sl_pos++] = pixeldata;
}
}
sl->data[sl_pos++] = _PIXPAIR(0 | THEN_EXTEND_1, 0 | THEN_EXTEND_1); // 4px
sl->data[sl_pos++] = _PIXPAIR(0 | THEN_EXTEND_6, 0x1ff); // 8px
sl->data[sl_pos++] = _PIXPAIR(_RGB(0, 0, 0) | THEN_EXTEND_1, _RGB(0, 0, 0) | THEN_EXTEND_1); // 4px
sl->data[sl_pos++] = _PIXPAIR(_RGB(0, 0, 0) | THEN_EXTEND_6, _RGB(255, 255, 255)); // 8px
sl->repeat_count = 1;
sl->length = sl_pos;
} else if((line >= 304) && (line < 304+128)) {
sl->data[sl_pos++] = _PIXPAIR(0x1ff, 0 | THEN_EXTEND_6); // 8px
sl->data[sl_pos++] = _PIXPAIR(0 | THEN_EXTEND_1, 0 | THEN_EXTEND_1); // 4px
sl->data[sl_pos++] = _PIXPAIR(_RGB(255, 255, 255), _RGB(0, 0, 0) | THEN_EXTEND_6); // 8px
sl->data[sl_pos++] = _PIXPAIR(_RGB(0, 0, 0) | THEN_EXTEND_1, _RGB(0, 0, 0) | THEN_EXTEND_1); // 4px
const uint z = (line - 304);
@ -199,18 +199,18 @@ void DELAYED_COPY_CODE(render_testpattern)() {
const uint g = z / 16;
for(uint b=5; b < 8; b++) {
for(uint r=0; r < 8; r++) {
const uint rgb = (r << 6) | (g << 3) | b;
sl->data[sl_pos++] = _PIXPAIR(0, rgb | THEN_EXTEND_6);
sl->data[sl_pos++] = _PIXPAIR(rgb | THEN_EXTEND_6, 0);
const uint32_t rgb = _RGB((r << 5), (g << 5), (b << 5));
sl->data[sl_pos++] = _PIXPAIR(_RGB(0, 0, 0), rgb | THEN_EXTEND_6);
sl->data[sl_pos++] = _PIXPAIR(rgb | THEN_EXTEND_6, _RGB(0, 0, 0));
}
}
} else {
for(uint i=0; i < 12; i++) {
sl->data[sl_pos++] = _PIXPAIR(0 | THEN_EXTEND_15, 0 | THEN_EXTEND_15); // 384px
sl->data[sl_pos++] = _PIXPAIR(_RGB(0, 0, 0) | THEN_EXTEND_15, _RGB(0, 0, 0) | THEN_EXTEND_15); // 384px
}
}
sl->data[sl_pos++] = _PIXPAIR(0 | THEN_EXTEND_3, 0 | THEN_EXTEND_3); // 8px
sl->data[sl_pos++] = _PIXPAIR(_RGB(0, 0, 0) | THEN_EXTEND_3, _RGB(0, 0, 0) | THEN_EXTEND_3); // 8px
const uint w = (line - 48) << 1;
for(uint i=0; i < 32; i+=2) {
@ -218,29 +218,29 @@ void DELAYED_COPY_CODE(render_testpattern)() {
uint32_t bits_b = char_test_bits(error_message[(w & 0x3E0) | (i+1)], (w>>2) & 0x7);
uint32_t bits = (bits_a << 7) | bits_b;
for(uint j=0; j < 7; j++) {
uint32_t pixeldata = (bits & 0x2000) ? (0) : (0x1ff);
pixeldata |= (bits & 0x1000) ? ((0) << 16) : ((0x1ff) << 16);
uint32_t pixeldata = (bits & 0x2000) ? (_RGB(0, 0, 0)) : (_RGB(255, 255, 255));
pixeldata |= (bits & 0x1000) ? ((_RGB(0, 0, 0)) << 16) : ((_RGB(255, 255, 255)) << 16);
bits <<= 2;
sl->data[sl_pos++] = pixeldata;
}
}
sl->data[sl_pos++] = _PIXPAIR(0 | THEN_EXTEND_1, 0 | THEN_EXTEND_1); // 4px
sl->data[sl_pos++] = _PIXPAIR(0 | THEN_EXTEND_6, 0x1ff); // 8px
sl->data[sl_pos++] = _PIXPAIR(_RGB(0, 0, 0) | THEN_EXTEND_1, _RGB(0, 0, 0) | THEN_EXTEND_1); // 4px
sl->data[sl_pos++] = _PIXPAIR(_RGB(0, 0, 0) | THEN_EXTEND_6, _RGB(255, 255, 255)); // 8px
sl->repeat_count = 1;
sl->length = sl_pos;
} else if(line < VGA_HEIGHT) {
// black w/ white border
sl->data[sl_pos++] = _PIXPAIR(0x1ff, 0 | THEN_EXTEND_6);
sl->data[sl_pos++] = _PIXPAIR(_RGB(255, 255, 255), _RGB(0, 0, 0) | THEN_EXTEND_6);
for(uint i=0; i < 39; i++) {
sl->data[sl_pos++] = _PIXPAIR(0 | THEN_EXTEND_7, 0 | THEN_EXTEND_7);
sl->data[sl_pos++] = _PIXPAIR(_RGB(0, 0, 0) | THEN_EXTEND_7, _RGB(0, 0, 0) | THEN_EXTEND_7);
}
sl->data[sl_pos++] = _PIXPAIR(0 | THEN_EXTEND_6, 0x1ff);
sl->data[sl_pos++] = _PIXPAIR(_RGB(0, 0, 0) | THEN_EXTEND_6, _RGB(255, 255, 255));
sl->length = sl_pos;
} else {
sl->data[sl_pos++] = _PIXPAIR(0, 0);
sl->data[sl_pos++] = _PIXPAIR(_RGB(0, 0, 0), _RGB(0, 0, 0));
sl->length = sl_pos;
}
@ -277,10 +277,10 @@ void DELAYED_COPY_CODE(render_status_line)() {
// Translate each pair of bits into a pair of pixels
for(int i=0; i < 7; i++) {
uint32_t pixeldata = (bits & 0x2000) ? (0x000) : (0x1ff);
uint32_t pixeldata = (bits & 0x2000) ? (_RGB(0, 0, 0)) : (_RGB(255, 255, 255));
pixeldata |= (bits & 0x1000) ?
((uint32_t)0x000) << 16 :
((uint32_t)0x1ff) << 16;
((uint32_t)_RGB(0, 0, 0)) << 16 :
((uint32_t)_RGB(255, 255, 255)) << 16;
bits <<= 2;
sl->data[sl_pos] = pixeldata;

View File

@ -10,8 +10,8 @@ uint8_t __attribute__((section(".uninitialized_data."))) terminal_character_rom[
volatile uint8_t terminal_row = 0;
volatile uint8_t terminal_col = 0;
volatile uint8_t terminal_tbcolor = 0xF6;
volatile uint8_t terminal_border = 0x6;
volatile uint8_t terminal_tbcolor = 0xF0;
volatile uint8_t terminal_border = 0x0;
volatile uint8_t romx_type = 0;
volatile uint8_t romx_unlocked = 0;

View File

@ -16,9 +16,9 @@ extern volatile uint8_t terminal_col;
#define apple_tbcolor apple_memory[0xC022]
#define apple_border apple_memory[0xC034]
#define APPLE_FORE ((terminal_tbcolor>>4) & 0xf)
#define APPLE_BACK (terminal_tbcolor & 0xf)
#define APPLE_BORDER (terminal_border & 0xf)
#define APPLE_FORE ((apple_tbcolor>>4) & 0xf)
#define APPLE_BACK (apple_tbcolor & 0xf)
#define APPLE_BORDER (apple_border & 0xf)
extern volatile uint32_t mono_palette;
extern volatile uint8_t terminal_tbcolor;

View File

@ -11,8 +11,10 @@
#ifdef ANALOG_GS
#include "vga12.pio.h"
#define RGB_PINCOUNT 12
#else
#include "vga9.pio.h"
#define RGB_PINCOUNT 9
#endif
#include "vgaout.h"
@ -110,18 +112,18 @@ static void DELAYED_COPY_CODE(vga_data_setup)(PIO pio, uint sm) {
sm_config_set_clkdiv(&c, CONFIG_SYSCLOCK / (2*PIXEL_FREQ));
// Map the state machine's OUT pin group to the data pins
sm_config_set_out_pins(&c, CONFIG_PIN_RGB_BASE, 9);
sm_config_set_set_pins(&c, CONFIG_PIN_RGB_BASE, 9);
sm_config_set_out_pins(&c, CONFIG_PIN_RGB_BASE, RGB_PINCOUNT);
sm_config_set_set_pins(&c, CONFIG_PIN_RGB_BASE, RGB_PINCOUNT);
// Enable autopull every 32 bits (2 x (9 data + 5 jump + 2 pad) bits)
// Enable autopull every 32 bits (2 x (RGB_PINCOUNT data + jump + pad) bits)
sm_config_set_out_shift(&c, true, true, 32);
// Set join the state machine FIFOs to double the TX fifo size
sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_TX);
// Configure the pins as outputs & connect to the PIO
pio_sm_set_consecutive_pindirs(pio, sm, CONFIG_PIN_RGB_BASE, 9, true);
for(int i=0; i < 9; i++) {
pio_sm_set_consecutive_pindirs(pio, sm, CONFIG_PIN_RGB_BASE, RGB_PINCOUNT, true);
for(int i=0; i < RGB_PINCOUNT; i++) {
pio_gpio_init(pio, CONFIG_PIN_RGB_BASE+i);
}

View File

@ -36,6 +36,7 @@ uint8_t DELAYED_COPY_CODE(zuart_read)(bool port) {
}
switch(serialmux[port]) {
default:
case SERIAL_LOOP:
break;
case SERIAL_USB:
@ -44,6 +45,7 @@ uint8_t DELAYED_COPY_CODE(zuart_read)(bool port) {
sio[port].datavalid = 1;
}
break;
#ifdef ANALOG_GS
case SERIAL_UART:
if(port) {
if(uart_is_readable(uart1)) {
@ -57,6 +59,7 @@ uint8_t DELAYED_COPY_CODE(zuart_read)(bool port) {
}
}
break;
#endif
}
return rv;
@ -87,6 +90,7 @@ uint8_t DELAYED_COPY_CODE(auart_status)(bool port) {
rv = sio[port].datavalid ? 0x08 : 0x00;
switch(serialmux[port]) {
default:
case SERIAL_LOOP:
rv |= ((sio[port].control[5] & 0x02) ? 0x40 : 0x00) |
((sio[port].control[5] & 0x80) ? 0x20 : 0x00) |
@ -97,6 +101,7 @@ uint8_t DELAYED_COPY_CODE(auart_status)(bool port) {
(tud_cdc_n_connected(port) ? 0x00 : 0x20) |
(tud_cdc_n_write_available(port) ? 0x10 : 0x00);
break;
#ifdef ANALOG_GS
case SERIAL_UART:
if(port) {
rv |= (uart_is_writable(uart1) ? 0x10 : 0x00);
@ -104,6 +109,7 @@ uint8_t DELAYED_COPY_CODE(auart_status)(bool port) {
rv |= (uart_is_writable(uart0) ? 0x10 : 0x00);
}
break;
#endif
}
return rv;
@ -130,6 +136,7 @@ uint8_t DELAYED_COPY_CODE(auart_command)(bool port, uint8_t value) {
uint8_t DELAYED_COPY_CODE(zuart_write)(bool port, uint8_t value) {
switch(serialmux[port]) {
default:
case SERIAL_LOOP:
if(sio[port].datavalid) {
sio[port].status[1] |= 0x20;
@ -137,12 +144,13 @@ uint8_t DELAYED_COPY_CODE(zuart_write)(bool port, uint8_t value) {
sio[port].datavalid = 1;
sio[port].data = value;
break;
case SERIAL_UART:
case SERIAL_USB:
if(tud_cdc_n_write_available(port)) {
tud_cdc_n_write_char(port, value);
}
break;
case SERIAL_USB:
#ifdef ANALOG_GS
case SERIAL_UART:
if(port) {
if(uart_is_writable(uart1)) {
uart_putc(uart1, value);
@ -153,6 +161,7 @@ uint8_t DELAYED_COPY_CODE(zuart_write)(bool port, uint8_t value) {
}
}
break;
#endif
}
return value;
}
@ -170,6 +179,7 @@ uint8_t DELAYED_COPY_CODE(zuart_status)(bool port) {
rv = sio[port].datavalid ? 0x01 : 0x00;
switch(serialmux[port]) {
default:
case SERIAL_LOOP:
rv |= ((sio[port].control[5] & 0x02) ? 0x20 : 0x00) |
((sio[port].control[5] & 0x80) ? 0x08 : 0x00) |
@ -180,6 +190,7 @@ uint8_t DELAYED_COPY_CODE(zuart_status)(bool port) {
(tud_cdc_n_connected(port) ? 0x08 : 0x00) |
(tud_cdc_n_write_available(port) ? 0x04 : 0x00);
break;
#ifdef ANALOG_GS
case SERIAL_UART:
if(port) {
rv |= 0x20 |
@ -189,6 +200,7 @@ uint8_t DELAYED_COPY_CODE(zuart_status)(bool port) {
(uart_is_writable(uart0) ? 0x00 : 0x04);
}
break;
#endif
}
break;
case 1:
@ -264,6 +276,7 @@ void DELAYED_COPY_CODE(cpu_out)(uint16_t address, uint8_t value) {
if((address & 0x02) == 0) {
divisor = value ? value : 256;
sio[address & 0x01].baudrate = 115200 / divisor;
#ifdef ANALOG_GS
if(serialmux[(address & 0x01)] == SERIAL_UART) {
if(address & 0x01) {
uart_set_baudrate(uart1, sio[1].baudrate);
@ -271,6 +284,7 @@ void DELAYED_COPY_CODE(cpu_out)(uint16_t address, uint8_t value) {
uart_set_baudrate(uart0, sio[0].baudrate);
}
}
#endif
}
} else if(value & 1) {
ctc[address & 0x03].control = value;