diff --git a/video/agon_ps2.h b/video/agon_ps2.h index 6f19a7a..c8879c6 100644 --- a/video/agon_ps2.h +++ b/video/agon_ps2.h @@ -23,11 +23,17 @@ uint32_t mWheelAcc = MOUSE_DEFAULT_WHEELACC; // Mouse wheel acceleration // Forward declarations // -bool resetMousePositioner(uint16_t width, uint16_t height, fabgl::VGABaseController * display); +#ifdef USERSPACE +bool zdi_mode () { return false; } +void zdi_enter () {} +void zdi_process_cmd (uint8_t key) {} +#else +bool zdi_mode (); +void zdi_enter (); +void zdi_process_cmd (uint8_t key); +#endif -extern bool zdi_mode(); -extern void zdi_enter(); -extern void zdi_process_cmd(uint8_t key); +bool resetMousePositioner(uint16_t width, uint16_t height, fabgl::VGABaseController * display); extern bool consoleMode; extern HardwareSerial DBGSerial; diff --git a/video/context.h b/video/context.h index c8a5269..529394a 100644 --- a/video/context.h +++ b/video/context.h @@ -96,7 +96,6 @@ class Context { uint8_t linePatternLength = 8; // Dotted line pattern length std::vector charToBitmap = std::vector(256, 65535); // character to bitmap mapping bool plottingText = false; // Are we currently plotting text? - bool logicalCoords = true; // Use BBC BASIC logical coordinates Point origin; // Screen origin @@ -240,7 +239,7 @@ class Context { bool usingSystemFont(); char getScreenChar(uint8_t x, uint8_t y); char getScreenCharAt(uint16_t px, uint16_t py); - void mapCharToBitmap(char c, uint16_t bitmapId); + void mapCharToBitmap(uint8_t c, uint16_t bitmapId); void unmapBitmapFromChars(uint16_t bitmapId); void resetCharToBitmap(); diff --git a/video/context/fonts.h b/video/context/fonts.h index 265c29c..0f66f4b 100644 --- a/video/context/fonts.h +++ b/video/context/fonts.h @@ -195,7 +195,7 @@ char Context::getScreenCharAt(uint16_t px, uint16_t py) { return getScreenChar(toScreenCoordinates(px, py)); } -void Context::mapCharToBitmap(char c, uint16_t bitmapId) { +void Context::mapCharToBitmap(uint8_t c, uint16_t bitmapId) { auto bitmap = getBitmap(bitmapId); if (bitmap) { charToBitmap[c] = bitmapId; diff --git a/video/context/graphics.h b/video/context/graphics.h index af4bfbc..df59eb1 100644 --- a/video/context/graphics.h +++ b/video/context/graphics.h @@ -14,6 +14,7 @@ #include "buffers.h" #include "sprites.h" #include "types.h" +#include "mat.h" // Definitions for the functions we're implementing here #include "context.h" diff --git a/video/hexload.h b/video/hexload.h index a33bda6..0364e5c 100644 --- a/video/hexload.h +++ b/video/hexload.h @@ -2,14 +2,18 @@ #define HEXLOAD_H #include +#ifndef USERSPACE #include "CRC16.h" #include "CRC32.h" +#endif /* !USERSPACE */ extern void printFmt(const char *format, ...); extern HardwareSerial DBGSerial; +#ifndef USERSPACE CRC16 linecrc16(0x8005, 0x0, 0x0, false, false); CRC32 crc32,crc32tmp; +#endif /* !USERSPACE */ bool aborted; #define DEF_LOAD_ADDRESS 0x040000 @@ -57,6 +61,7 @@ void consumeHexMarker(void) { // Receive a single iHex Nibble from the external Debug serial interface uint8_t getIHexNibble(bool addcrc) { +#ifndef USERSPACE uint8_t nibble, input; input = toupper(serialRx_t()); if(addcrc) linecrc16.add(input); @@ -64,6 +69,7 @@ uint8_t getIHexNibble(bool addcrc) { else nibble = input - 'A' + 10; // illegal characters will be dealt with by checksum later return nibble; +#endif /* !USERSPACE */ } // Receive a byte from the external Debug serial interface as two iHex nibbles @@ -106,6 +112,10 @@ void serialTx(uint32_t crc) { } void VDUStreamProcessor::vdu_sys_hexload(void) { +#ifdef USERSPACE + // no hexload for emulators :) + return; +#else /* !USERSPACE */ uint32_t segment_address; uint32_t crc32target; uint8_t u,h,l,tmp; @@ -290,6 +300,7 @@ void VDUStreamProcessor::vdu_sys_hexload(void) { } if(rom_area) printFmt("\r\nHEX data overlapping ROM area, transfer unsuccessful\r\nERROR\r\n"); printFmt("VDP done\r\n"); +#endif /* !USERSPACE */ } -#endif // HEXLOAD_H \ No newline at end of file +#endif // HEXLOAD_H diff --git a/video/types.h b/video/types.h index 9ff5b4f..cee84a3 100644 --- a/video/types.h +++ b/video/types.h @@ -36,6 +36,7 @@ #include #include +#include #include #include @@ -114,6 +115,12 @@ class psram_allocator } }; +template +bool operator==(const psram_allocator&, const psram_allocator&) { return true; } + +template +bool operator!=(const psram_allocator&a, const psram_allocator&b) { return !(a == b); } + // Typically we do not need a deleter because the regular one can handle PSRAM deallocations just fine, // but for completeness, here it is. diff --git a/video/vdu_buffered.h b/video/vdu_buffered.h index 4334cc4..1fd06cd 100644 --- a/video/vdu_buffered.h +++ b/video/vdu_buffered.h @@ -253,7 +253,7 @@ void IRAM_ATTR VDUStreamProcessor::vdu_sys_buffered() { } auto matrixSize = getMatrixSize(bufferId); if (matrixSize.value != 0) { - float transform[matrixSize.size()] = {0.0f}; + float transform[matrixSize.size()]; if (getMatrixFromBuffer(bufferId, transform, matrixSize)) { force_debug_log("buffer contains a %d x %d matrix with contents:\n\r", matrixSize.rows, matrixSize.columns); for (int i = 0; i < matrixSize.rows; i++) { @@ -1580,7 +1580,8 @@ void VDUStreamProcessor::bufferAffineTransform(uint16_t bufferId, uint8_t comman MatrixSize size; size.rows = dimensions + 1; size.columns = size.rows; - float transform[size.size()] = {0.0f}; + float transform[size.size()]; + memset(transform, 0, sizeof(transform)); for (int i = 0; i < size.rows; i++) { transform[i * size.rows + i] = 1.0f; } @@ -1657,7 +1658,8 @@ void VDUStreamProcessor::bufferAffineTransform(uint16_t bufferId, uint8_t comman } break; case AFFINE_SCALE: { // scale by a given factor in each dimension - float scales[dimensions] = {0.0f}; + float scales[dimensions]; + memset(scales, 0, sizeof(scales)); if (!readFloatArguments(scales, dimensions, useBufferValue, useAdvancedOffsets, useMultiFormat)) { return; } @@ -1667,7 +1669,8 @@ void VDUStreamProcessor::bufferAffineTransform(uint16_t bufferId, uint8_t comman } break; case AFFINE_TRANSLATE: { // translate by a given amount - float translateXY[dimensions] = {0.0f}; + float translateXY[dimensions]; + memset(translateXY, 0, sizeof(translateXY)); if (!readFloatArguments(translateXY, dimensions, useBufferValue, useAdvancedOffsets, useMultiFormat)) { return; } @@ -1677,7 +1680,8 @@ void VDUStreamProcessor::bufferAffineTransform(uint16_t bufferId, uint8_t comman } break; case AFFINE_TRANSLATE_OS_COORDS: { // translate by a given amount of pixels where x and y match current coordinate system scaling - float translateXY[dimensions] = {0.0f}; + float translateXY[dimensions]; + memset(translateXY, 0, sizeof(translateXY)); if (!readFloatArguments(translateXY, dimensions, useBufferValue, useAdvancedOffsets, useMultiFormat)) { return; } @@ -1690,7 +1694,8 @@ void VDUStreamProcessor::bufferAffineTransform(uint16_t bufferId, uint8_t comman } break; case AFFINE_SHEAR: { // shear by a given amount - float shearXY[dimensions] = {0.0f}; + float shearXY[dimensions]; + memset(shearXY, 0, sizeof(shearXY)); if (!readFloatArguments(shearXY, dimensions, useBufferValue, useAdvancedOffsets, useMultiFormat)) { return; } @@ -1702,7 +1707,8 @@ void VDUStreamProcessor::bufferAffineTransform(uint16_t bufferId, uint8_t comman case AFFINE_SKEW_RAD: { // skew by a given amount (angle) bool conversion = op == AFFINE_SKEW ? DEG_TO_RAD : 1.0f; - float skewXY[dimensions] = {0.0f}; + float skewXY[dimensions]; + memset(skewXY, 0, sizeof(skewXY)); if (!readFloatArguments(skewXY, dimensions, useBufferValue, useAdvancedOffsets, useMultiFormat)) { return; } @@ -1744,10 +1750,11 @@ void VDUStreamProcessor::bufferAffineTransform(uint16_t bufferId, uint8_t comman if (!replace) { // we are combining - for now, only if the existing matrix is the same size // TODO consider handling different size matrices - could combine at larger size, and then truncate - float existing[size.size()] = {0.0f}; + float existing[size.size()]; + memset(existing, 0, sizeof(existing)); if (getMatrixFromBuffer(bufferId, existing, size, false)) { // combine the two matrices together - float newTransform[size.size()] = {0.0f}; + float newTransform[size.size()]; dspm_mult_f32(transform, existing, newTransform, size.rows, size.columns, size.columns); // copy data from matrix back to our working transform matrix memcpy(transform, newTransform, size.sizeBytes()); @@ -1775,7 +1782,8 @@ void VDUStreamProcessor::bufferMatrixManipulate(uint16_t bufferId, uint8_t comma const bool useAdvancedOffsets = command & MATRIX_OP_ADVANCED_OFFSETS; const bool useBufferValue = command & MATRIX_OP_BUFFER_VALUE; - float matrix[size.size()] = {0.0f}; + float matrix[size.size()]; + memset(matrix, 0, sizeof(matrix)); switch (op) { case MATRIX_SET: { @@ -1817,7 +1825,8 @@ void VDUStreamProcessor::bufferMatrixManipulate(uint16_t bufferId, uint8_t comma case MATRIX_DIAGONAL: { // diagonal matrix with given values auto argCount = fabgl::imin(size.rows, size.columns); - float args[argCount] = {0.0f}; + float args[argCount]; + memset(args, 0, sizeof(args)); if (!readFloatArguments(args, argCount, useBufferValue, useAdvancedOffsets, false)) { return; } @@ -1830,7 +1839,8 @@ void VDUStreamProcessor::bufferMatrixManipulate(uint16_t bufferId, uint8_t comma auto sourceId1 = readWord_t(); if (sourceId1 == -1) return; auto sourceId2 = readWord_t(); if (sourceId2 == -1) return; // Get the matrixes, for our target size, padding or truncating as necessary - float source[size.size()] = {0.0f}; + float source[size.size()]; + memset(source, 0, sizeof(source)); if (!getMatrixFromBuffer(sourceId1, matrix, size) || !getMatrixFromBuffer(sourceId2, source, size)) { debug_log("bufferMatrixManipulate: failed to read matrix from buffer %d or %d\n\r", sourceId1, sourceId2); return; @@ -1845,7 +1855,8 @@ void VDUStreamProcessor::bufferMatrixManipulate(uint16_t bufferId, uint8_t comma auto sourceId1 = readWord_t(); if (sourceId1 == -1) return; auto sourceId2 = readWord_t(); if (sourceId2 == -1) return; // Get the matrixes, for our target size, padding or truncating as necessary - float source[size.size()] = {0.0f}; + float source[size.size()]; + memset(source, 0, sizeof(source)); if (!getMatrixFromBuffer(sourceId1, matrix, size) || !getMatrixFromBuffer(sourceId2, source, size)) { debug_log("bufferMatrixManipulate: failed to read matrix from buffer %d or %d\n\r", sourceId1, sourceId2); return; @@ -1871,14 +1882,17 @@ void VDUStreamProcessor::bufferMatrixManipulate(uint16_t bufferId, uint8_t comma MatrixSize resultSize; resultSize.rows = dimensions; resultSize.columns = dimensions; - float source1[resultSize.size()] = {0.0f}; - float source2[resultSize.size()] = {0.0f}; + float source1[resultSize.size()]; + float source2[resultSize.size()]; + memset(source1, 0, sizeof(source1)); + memset(source2, 0, sizeof(source2)); if (!getMatrixFromBuffer(sourceId1, source1, resultSize) || !getMatrixFromBuffer(sourceId2, source2, resultSize)) { debug_log("bufferMatrixManipulate: failed to read matrix from buffer %d or %d\n\r", sourceId1, sourceId2); return; } // multiply values in source1 and source2 - float result[resultSize.size()] = {0.0f}; + float result[resultSize.size()]; + memset(result, 0, sizeof(result)); dspm_mult_f32(source1, source2, result, resultSize.rows, resultSize.columns, resultSize.columns); for (int row = 0; row < size.rows; row++) { for (int column = 0; column < size.columns; column++) { @@ -1913,7 +1927,8 @@ void VDUStreamProcessor::bufferMatrixManipulate(uint16_t bufferId, uint8_t comma debug_log("bufferMatrixManipulate: source matrix %d not found\n\r", sourceId); return; } - float source[sourceSize.size()] = {0.0f}; + float source[sourceSize.size()]; + memset(source, 0, sizeof(source)); if (!getMatrixFromBuffer(sourceId, source, sourceSize)) { debug_log("bufferMatrixManipulate: failed to read matrix from buffer %d\n\r", sourceId); return; @@ -1940,7 +1955,8 @@ void VDUStreamProcessor::bufferMatrixManipulate(uint16_t bufferId, uint8_t comma return; } // read source matrix - float source[sourceSize.size()] = {0.0f}; + float source[sourceSize.size()]; + memset(source, 0, sizeof(source)); if (!getMatrixFromBuffer(sourceId, source, sourceSize)) { debug_log("bufferMatrixManipulate: failed to read matrix from buffer %d\n\r", sourceId); return; @@ -2101,8 +2117,8 @@ void VDUStreamProcessor::bufferTransformBitmap(uint16_t bufferId, uint8_t option debug_log("bufferTransformBitmap: width %d, height %d, xOffset %d, yOffset %d\n\r", width, height, xOffset, yOffset); - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { // calculate the source pixel // NB we will need to adjust x,y here if we are auto-translating pos[0] = (float)x + xOffset; @@ -2114,7 +2130,7 @@ void VDUStreamProcessor::bufferTransformBitmap(uint16_t bufferId, uint8_t option } destination[(int)y * width + (int)x] = srcPixel; } - } + } // save new bitmap data to target buffer bufferClear(bufferId); diff --git a/video/vdu_sys.h b/video/vdu_sys.h index 5b0f963..54c5474 100644 --- a/video/vdu_sys.h +++ b/video/vdu_sys.h @@ -390,7 +390,7 @@ void VDUStreamProcessor::sendCursorPosition() { // void VDUStreamProcessor::sendScreenChar(char c) { uint8_t packet[] = { - c, + (uint8_t)c, }; send_packet(PACKET_SCRCHAR, sizeof packet, packet); } diff --git a/video/video.ino b/video/video.ino index 5fb7591..e13d1b4 100644 --- a/video/video.ino +++ b/video/video.ino @@ -45,14 +45,28 @@ // 12/09/2023: + Refactored // 17/09/2023: + Added ZDI mode -#include #include #include #include -#define DEBUG 0 // Serial Debug Mode: 1 = enable +// Serial Debug Mode: 1 = enable +// Always enabled on the emulator, to support --verbose mode +#ifdef USERSPACE +#undef DEBUG +# define DEBUG 1 +#else /* !USERSPACE */ +#undef DEBUG +# define DEBUG 0 +#endif /* USERSPACE */ + #define SERIALBAUDRATE 115200 +#ifdef USERSPACE +extern uint32_t startup_screen_mode; /* in rust_glue.cpp */ +#else /* !USERSPACE */ +#define startup_screen_mode 0 +#endif /* !USERSPACE */ + HardwareSerial DBGSerial(0); #include "agon.h" // Configuration file @@ -74,7 +88,9 @@ bool controlKeys = true; // Control keys enabled std::unique_ptr Terminal; // Used for Terminal emulation mode (for CP/M, etc) VDUStreamProcessor * processor; // VDU Stream Processor +#ifndef USERSPACE #include "zdi.h" // ZDI debugging console +#endif /* !USERSPACE */ TaskHandle_t Core0Task; // Core 0 task handle @@ -84,7 +100,7 @@ void setup() { disableCore1WDT(); delay(200); #endif DBGSerial.begin(SERIALBAUDRATE, SERIAL_8N1, 3, 1); - changeMode(0); + changeMode(startup_screen_mode); copy_font(); setupVDPProtocol(); processor = new VDUStreamProcessor(&VDPSerial); @@ -114,7 +130,18 @@ void loop() { } void processLoop(void * parameter) { +#ifdef USERSPACE + uint32_t count = 0; +#endif /* USERSPACE */ + while (true) { +#ifdef USERSPACE + if ((count & 0x7f) == 0) { + delay(1 /* -TM- ms */); + } + count++; +#endif /* USERSPACE */ + #ifdef VDP_USE_WDT esp_task_wdt_reset(); #endif @@ -203,6 +230,7 @@ void boot_screen() { // Debug printf to PC // +#ifndef USERSPACE void debug_log(const char *format, ...) { #if DEBUG == 1 va_list ap; @@ -218,6 +246,7 @@ void debug_log(const char *format, ...) { va_end(ap); #endif } +#endif void force_debug_log(const char *format, ...) { va_list ap; @@ -326,8 +355,8 @@ bool processTerminal() { if (seq[0] == 'F') { uint32_t fontnum = textToWord(seq + 1); if (fontnum >= 0) { - auto font = fonts[fontnum]; // get shared_ptr to font -- was fonts[bufferID] - if (font != nullptr && font->chptr == nullptr) { // check it's defined + auto font = fonts[fontnum]; // get shared_ptr to font -- was fonts[bufferID] + if (font != nullptr && font->chptr == nullptr) { // check it's defined Terminal->loadFont(font.get()); } }