From 4785b281a64db992c47721a217f2f0f8d7938255 Mon Sep 17 00:00:00 2001 From: Steve Sims Date: Fri, 15 Dec 2023 18:47:54 +0000 Subject: [PATCH] read colours reads colours, either from the palette, or one of the active colours this is done using `VDU 23, 0, &94, colour`. values will be returned using the `PACKET_SCRPIXEL` response packet, and therefore MOS will interpret these exactly the same as reading a screen pixel via `VDU 23, 0, &84`. values will therefore be exposed in MOS in the exact same `scrpixel` and `scrpixelIndex` sysvar bytes when using this command, colours 0-63 will be interpreted as palette colours, 128 will return the currently selected text foreground colour, 129 the text background colour, 130 graphics foreground, and 131 graphics background. any other colour values will be ignored --- video/agon.h | 1 + video/vdu_stream_processor.h | 1 + video/vdu_sys.h | 44 ++++++++++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+) diff --git a/video/agon.h b/video/agon.h index b17231b..76c48e8 100644 --- a/video/agon.h +++ b/video/agon.h @@ -45,6 +45,7 @@ #define VDP_RTC 0x87 // RTC #define VDP_KEYSTATE 0x88 // Keyboard repeat rate and LED status #define VDP_MOUSE 0x89 // Mouse data +#define VDP_READ_COLOUR 0x94 // Read colour #define VDP_BUFFERED 0xA0 // Buffered commands #define VDP_UPDATER 0xA1 // Update VDP #define VDP_LOGICALCOORDS 0xC0 // Switch BBC Micro style logical coords on and off diff --git a/video/vdu_stream_processor.h b/video/vdu_stream_processor.h index 6c29656..a75c497 100644 --- a/video/vdu_stream_processor.h +++ b/video/vdu_stream_processor.h @@ -41,6 +41,7 @@ class VDUStreamProcessor { void sendCursorPosition(); void sendScreenChar(uint16_t x, uint16_t y); void sendScreenPixel(uint16_t x, uint16_t y); + void sendColour(uint8_t colour); void sendTime(); void vdu_sys_video_time(); void sendKeyboardState(); diff --git a/video/vdu_sys.h b/video/vdu_sys.h index fa126f1..72f4eeb 100644 --- a/video/vdu_sys.h +++ b/video/vdu_sys.h @@ -147,6 +147,12 @@ void VDUStreamProcessor::vdu_sys_video() { case VDP_MOUSE: { // VDU 23, 0, &89, command, vdu_sys_mouse(); } break; + case VDP_READ_COLOUR: { // VDU 23, 0, &94, index + auto index = readByte_t(); // Read colour from palette + if (index >= 0) { + sendColour(index); + } + } break; case VDP_BUFFERED: { // VDU 23, 0, &A0, bufferId; command, vdu_sys_buffered(); } break; @@ -238,6 +244,44 @@ void VDUStreamProcessor::sendScreenPixel(uint16_t x, uint16_t y) { send_packet(PACKET_SCRPIXEL, sizeof packet, packet); } +// VDU 23, 0, &94, index: Send a colour back to MOS +// +void VDUStreamProcessor::sendColour(uint8_t colour) { + RGB888 pixel; + if (colour < 64) { + // Colour is a palette lookup + uint8_t c = palette[colour % getVGAColourDepth()]; + pixel = colourLookup[c]; + } else { + // Colour may be an active colour lookup + switch (colour) { + case 128: // text foreground + pixel = tfg; + break; + case 129: // text background + pixel = tbg; + break; + case 130: // graphics foreground + pixel = gfg; + break; + case 131: // graphics background + pixel = gbg; + break; + default: + // Unrecognised colour - no response + return; + } + } + + uint8_t packet[] = { + pixel.R, // Send the colour components + pixel.G, + pixel.B, + colour, + }; + send_packet(PACKET_SCRPIXEL, sizeof packet, packet); +} + // VDU 23, 0, &87, 0: Send TIME information (from ESP32 RTC) // void VDUStreamProcessor::sendTime() {