diff --git a/include/debug.h b/include/debug.h index ac888f7ce..ad8963798 100644 --- a/include/debug.h +++ b/include/debug.h @@ -24,17 +24,17 @@ #ifdef ESP_PLATFORM // Use FujiNet debug serial output #include "../lib/hardware/fnUART.h" - #define Serial fnUartDebug + #define Serial fnDebugConsole #if defined(PINMAP_RS232_S3) /*|| defined(PINMAP_ESP32S3_XDRIVE)*/ #define Debug_print(...) printf( __VA_ARGS__ ) #define Debug_printf(...) printf( __VA_ARGS__ ) #define Debug_println(...) do { printf(__VA_ARGS__); printf("\n"); } while (0) #define Debug_printv(format, ...) {printf( ANSI_YELLOW "[%s:%u] %s(): " ANSI_GREEN_BOLD format ANSI_RESET "\r\n", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__);} #else - #define Debug_print(...) fnUartDebug.print( __VA_ARGS__ ) - #define Debug_printf(...) fnUartDebug.printf( __VA_ARGS__ ) - #define Debug_println(...) fnUartDebug.println( __VA_ARGS__ ) - #define Debug_printv(format, ...) {fnUartDebug.printf( ANSI_YELLOW "[%s:%u] %s(): " ANSI_GREEN_BOLD format ANSI_RESET "\r\n", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__);} + #define Debug_print(...) fnDebugConsole.print( __VA_ARGS__ ) + #define Debug_printf(...) fnDebugConsole.printf( __VA_ARGS__ ) + #define Debug_println(...) fnDebugConsole.println( __VA_ARGS__ ) + #define Debug_printv(format, ...) {fnDebugConsole.printf( ANSI_YELLOW "[%s:%u] %s(): " ANSI_GREEN_BOLD format ANSI_RESET "\r\n", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__);} #endif // PINMAP_RS232_S3 #define HEAP_CHECK(x) Debug_printf("HEAP CHECK %s " x "\r\n", heap_caps_check_integrity_all(true) ? "PASSED":"FAILED") @@ -55,7 +55,7 @@ #ifdef ESP_PLATFORM // Use FujiNet debug serial output #include "../lib/hardware/fnUART.h" - #define Serial fnUartDebug + #define Serial fnDebugConsole #endif #define Debug_print(...) diff --git a/lib/bus/adamnet/adamnet.cpp b/lib/bus/adamnet/adamnet.cpp index f7d082df0..9eac6280e 100755 --- a/lib/bus/adamnet/adamnet.cpp +++ b/lib/bus/adamnet/adamnet.cpp @@ -78,24 +78,24 @@ uint8_t adamnet_checksum(uint8_t *buf, unsigned short len) void virtualDevice::adamnet_send(uint8_t b) { // Write the byte - fnUartBUS.write(b); - fnUartBUS.flush(); + SYSTEM_BUS.write(b); + SYSTEM_BUS.flush(); } void virtualDevice::adamnet_send_buffer(uint8_t *buf, unsigned short len) { - fnUartBUS.write(buf, len); - fnUartBUS.flush(); + SYSTEM_BUS.write(buf, len); + SYSTEM_BUS.flush(); } uint8_t virtualDevice::adamnet_recv() { uint8_t b; - while (fnUartBUS.available() <= 0) + while (SYSTEM_BUS.available() <= 0) fnSystem.yield(); - b = fnUartBUS.read(); + b = SYSTEM_BUS.read(); return b; } @@ -108,7 +108,7 @@ bool virtualDevice::adamnet_recv_timeout(uint8_t *b, uint64_t dur) start = current = esp_timer_get_time(); elapsed = 0; - while (fnUartBUS.available() <= 0) + while (SYSTEM_BUS.available() <= 0) { current = esp_timer_get_time(); elapsed = current - start; @@ -116,9 +116,9 @@ bool virtualDevice::adamnet_recv_timeout(uint8_t *b, uint64_t dur) break; } - if (fnUartBUS.available() > 0) + if (SYSTEM_BUS.available() > 0) { - *b = (uint8_t)fnUartBUS.read(); + *b = (uint8_t)SYSTEM_BUS.read(); timeout = false; } // else // Debug_printf("duration: %llu\n", elapsed); @@ -143,7 +143,7 @@ void virtualDevice::adamnet_send_length(uint16_t l) unsigned short virtualDevice::adamnet_recv_buffer(uint8_t *buf, unsigned short len) { - return fnUartBUS.readBytes(buf, len); + return SYSTEM_BUS.read(buf, len); } uint32_t virtualDevice::adamnet_recv_blockno() @@ -168,7 +168,7 @@ void virtualDevice::adamnet_response_ack(bool doNotWaitForIdle) { SYSTEM_BUS.wait_for_idle(); } - + if (t < 300) { adamnet_send(0x90 | _devnum); @@ -183,7 +183,7 @@ void virtualDevice::adamnet_response_nack(bool doNotWaitForIdle) { SYSTEM_BUS.wait_for_idle(); } - + if (t < 300) { adamnet_send(0xC0 | _devnum); @@ -203,12 +203,12 @@ void systemBus::wait_for_idle() do { // Wait for serial line to quiet down. - while (fnUartBUS.available() > 0) - fnUartBUS.read(); + while (_port.available() > 0) + _port.read(); start = current = esp_timer_get_time(); - while ((fnUartBUS.available() <= 0) && (isIdle == false)) + while ((_port.available() <= 0) && (isIdle == false)) { current = esp_timer_get_time(); dur = current - start; @@ -221,7 +221,7 @@ void systemBus::wait_for_idle() void virtualDevice::adamnet_process(uint8_t b) { - fnUartDebug.printf("adamnet_process() not implemented yet for this device. Cmd received: %02x\n", b); + fnDebugConsole.printf("adamnet_process() not implemented yet for this device. Cmd received: %02x\n", b); } void virtualDevice::adamnet_control_status() @@ -262,14 +262,14 @@ void virtualDevice::adamnet_idle() //void virtualDevice::adamnet_status() //{ -// fnUartDebug.printf("adamnet_status() not implemented yet for this device.\n"); +// fnDebugConsole.printf("adamnet_status() not implemented yet for this device.\n"); //} void systemBus::_adamnet_process_cmd() { uint8_t b; - b = fnUartBUS.read(); + b = _port.read(); start_time = esp_timer_get_time(); uint8_t d = b & 0x0F; @@ -311,7 +311,7 @@ void systemBus::service() _adamnet_process_queue(); // Process anything waiting. - if (fnUartBUS.available() > 0) + if (_port.available() > 0) _adamnet_process_cmd(); } @@ -332,7 +332,7 @@ void systemBus::setup() gpio_isr_handler_add((gpio_num_t)PIN_ADAMNET_RESET, adamnet_reset_isr_handler, (void *)PIN_CARD_DETECT_FIX); // Set up UART - fnUartBUS.begin(ADAMNET_BAUDRATE); + _port.begin(ADAMNET_BAUDRATE); } void systemBus::shutdown() diff --git a/lib/bus/adamnet/adamnet.h b/lib/bus/adamnet/adamnet.h index 9fc4e432c..3276da431 100755 --- a/lib/bus/adamnet/adamnet.h +++ b/lib/bus/adamnet/adamnet.h @@ -5,6 +5,7 @@ * AdamNet Routines */ +#include "fnUART.h" #include #include @@ -178,7 +179,7 @@ class virtualDevice * @brief Do any tasks that can only be done when the bus is quiet */ virtual void adamnet_idle(); - + /** * @brief send current status of device */ @@ -193,7 +194,7 @@ class virtualDevice * @brief send status response */ virtual void adamnet_response_status(); - + /** * @brief command frame, used by network protocol, ultimately */ @@ -232,7 +233,7 @@ class virtualDevice */ uint8_t id() { return _devnum; } - + }; /** @@ -246,6 +247,8 @@ class systemBus adamFuji *_fujiDev = nullptr; adamPrinter *_printerDev = nullptr; + UARTManager _port = UARTManager(FN_UART_BUS); + void _adamnet_process_cmd(); void _adamnet_process_queue(); @@ -279,6 +282,18 @@ class systemBus bool shuttingDown = false; // TRUE if we are in shutdown process bool getShuttingDown() { return shuttingDown; }; + + // Everybody thinks "oh I know how a serial port works, I'll just + // access it directly and bypass the bus!" ಠ_ಠ + size_t read(void *buffer, size_t length) { return _port.readBytes(buffer, length); } + size_t read() { return _port.read(); } + size_t write(const void *buffer, size_t length) { return _port.write(buffer, length); } + size_t write(int n) { return _port.write(n); } + size_t available() { return _port.available(); } + void flush() { _port.flush(); } + size_t print(int n, int base = 10) { return _port.print(n, base); } + size_t print(const char *str) { return _port.print(str); } + size_t print(const std::string &str) { return _port.print(str); } }; extern systemBus SYSTEM_BUS; diff --git a/lib/bus/rs232/rs232.cpp b/lib/bus/rs232/rs232.cpp index 1741ef261..7243cddc4 100755 --- a/lib/bus/rs232/rs232.cpp +++ b/lib/bus/rs232/rs232.cpp @@ -68,11 +68,11 @@ void virtualDevice::bus_to_computer(uint8_t *buf, uint16_t len, bool err) rs232_complete(); // Write data frame - fnUartBUS.write(buf, len); + SYSTEM_BUS.write(buf, len); // Write checksum - fnUartBUS.write(rs232_checksum(buf, len)); + SYSTEM_BUS.write(rs232_checksum(buf, len)); - fnUartBUS.flush(); + SYSTEM_BUS.flush(); } /* @@ -87,13 +87,13 @@ uint8_t virtualDevice::bus_to_peripheral(uint8_t *buf, unsigned short len) Debug_printf("<-RS232 read %hu bytes\n", len); __BEGIN_IGNORE_UNUSEDVARS - size_t l = fnUartBUS.readBytes(buf, len); + size_t l = SYSTEM_BUS.read(buf, len); __END_IGNORE_UNUSEDVARS // Wait for checksum - while (fnUartBUS.available() <= 0) + while (SYSTEM_BUS.available() <= 0) fnSystem.yield(); - uint8_t ck_rcv = fnUartBUS.read(); + uint8_t ck_rcv = SYSTEM_BUS.read(); uint8_t ck_tst = rs232_checksum(buf, len); @@ -120,17 +120,17 @@ uint8_t virtualDevice::bus_to_peripheral(uint8_t *buf, unsigned short len) // RS232 NAK void virtualDevice::rs232_nak() { - fnUartBUS.write('N'); - fnUartBUS.flush(); + SYSTEM_BUS.write('N'); + SYSTEM_BUS.flush(); Debug_println("NAK!"); } // RS232 ACK void virtualDevice::rs232_ack() { - fnUartBUS.write('A'); + SYSTEM_BUS.write('A'); fnSystem.delay_microseconds(DELAY_T5); //? - fnUartBUS.flush(); + SYSTEM_BUS.flush(); Debug_println("ACK!"); } @@ -138,7 +138,7 @@ void virtualDevice::rs232_ack() void virtualDevice::rs232_complete() { fnSystem.delay_microseconds(DELAY_T5); - fnUartBUS.write('C'); + SYSTEM_BUS.write('C'); Debug_println("COMPLETE!"); } @@ -146,7 +146,7 @@ void virtualDevice::rs232_complete() void virtualDevice::rs232_error() { fnSystem.delay_microseconds(DELAY_T5); - fnUartBUS.write('E'); + SYSTEM_BUS.write('E'); Debug_println("ERROR!"); } @@ -166,14 +166,14 @@ void systemBus::_rs232_process_cmd() { _modemDev->modemActive = false; Debug_println("Modem was active - resetting RS232 baud"); - fnUartBUS.set_baudrate(_rs232Baud); + _port.set_baudrate(_rs232Baud); } // Read CMD frame cmdFrame_t tempFrame; memset(&tempFrame, 0, sizeof(tempFrame)); - if (fnUartBUS.readBytes((uint8_t *)&tempFrame, sizeof(tempFrame)) != sizeof(tempFrame)) + if (_port.readBytes((uint8_t *)&tempFrame, sizeof(tempFrame)) != sizeof(tempFrame)) { Debug_println("Timeout waiting for data after CMD pin asserted"); return; @@ -281,7 +281,7 @@ void systemBus::service() // Neither CMD nor active modem, so throw out any stray input data { //Debug_println("RS232 Srvc Flush"); - fnUartBUS.flush_input(); + _port.flush_input(); } // Handle interrupts from network protocols @@ -298,7 +298,7 @@ void systemBus::setup() Debug_printf("RS232 SETUP: Baud rate: %u\n",Config.get_rs232_baud()); // Set up UART - fnUartBUS.begin(Config.get_rs232_baud()); + _port.begin(Config.get_rs232_baud()); // // INT PIN // fnSystem.set_pin_mode(PIN_RS232_RI, gpio_mode_t::GPIO_MODE_OUTPUT_OD, SystemManager::pull_updown_t::PULL_UP); @@ -326,7 +326,7 @@ void systemBus::setup() qRs232Messages = xQueueCreate(4, sizeof(rs232_message_t)); Debug_println("RS232 Setup Flush"); - fnUartBUS.flush_input(); + _port.flush_input(); } // Add device to RS232 bus @@ -421,7 +421,7 @@ void systemBus::toggleBaudrate() // Debug_printf("Toggling baudrate from %d to %d\n", _rs232Baud, baudrate); _rs232Baud = baudrate; - fnUartBUS.set_baudrate(_rs232Baud); + _port.set_baudrate(_rs232Baud); } int systemBus::getBaudrate() @@ -439,7 +439,7 @@ void systemBus::setBaudrate(int baud) Debug_printf("Changing baudrate from %d to %d\n", _rs232Baud, baud); _rs232Baud = baud; - fnUartBUS.set_baudrate(baud); + _port.set_baudrate(baud); } // Set HRS232 index. Sets high speed RS232 baud and also returns that value. diff --git a/lib/bus/rs232/rs232.h b/lib/bus/rs232/rs232.h index 7e94e3430..0d8e038e8 100755 --- a/lib/bus/rs232/rs232.h +++ b/lib/bus/rs232/rs232.h @@ -1,6 +1,7 @@ #ifndef RS232_H #define RS232_H +#include "fnUART.h" #include #include @@ -216,6 +217,8 @@ class systemBus bool useUltraHigh = false; // Use fujinet derived clock. + UARTManager _port = UARTManager(FN_UART_BUS); + void _rs232_process_cmd(); /* void _rs232_process_queue(); */ @@ -250,6 +253,18 @@ class systemBus bool shuttingDown = false; // TRUE if we are in shutdown process bool getShuttingDown() { return shuttingDown; }; + + // Everybody thinks "oh I know how a serial port works, I'll just + // access it directly and bypass the bus!" ಠ_ಠ + size_t read(void *buffer, size_t length) { return _port.readBytes(buffer, length); } + size_t read() { return _port.read(); } + size_t write(const void *buffer, size_t length) { return _port.write(buffer, length); } + size_t write(int n) { return _port.write(n); } + size_t available() { return _port.available(); } + void flush() { _port.flush(); } + size_t print(int n, int base = 10) { return _port.print(n, base); } + size_t print(const char *str) { return _port.print(str); } + size_t print(const std::string &str) { return _port.print(str); } }; extern systemBus SYSTEM_BUS; diff --git a/lib/bus/sio/sio.cpp b/lib/bus/sio/sio.cpp index de9a020f7..c69129b9d 100755 --- a/lib/bus/sio/sio.cpp +++ b/lib/bus/sio/sio.cpp @@ -58,20 +58,11 @@ void virtualDevice::bus_to_computer(uint8_t *buf, uint16_t len, bool err) sio_complete(); // Write data frame -#ifdef ESP_PLATFORM - UARTManager *uart = SYSTEM_BUS.uart; - uart->write(buf, len); - // Write checksum - uart->write(sio_checksum(buf, len)); - - uart->flush(); -#else - fnSioCom.write(buf, len); + SYSTEM_BUS.write(buf, len); // Write checksum - fnSioCom.write(sio_checksum(buf, len)); + SYSTEM_BUS.write(sio_checksum(buf, len)); - fnSioCom.flush(); -#endif + SYSTEM_BUS.flush(); } // TODO apc: change return type to indicate valid/invalid checksum @@ -86,30 +77,21 @@ uint8_t virtualDevice::bus_to_peripheral(uint8_t *buf, unsigned short len) // Retrieve data frame from computer Debug_printf("<-SIO read %hu bytes\n", len); -#ifdef ESP_PLATFORM - UARTManager *uart = SYSTEM_BUS.uart; - - __BEGIN_IGNORE_UNUSEDVARS - size_t l = uart->readBytes(buf, len); - __END_IGNORE_UNUSEDVARS - - // Wait for checksum - while (uart->available() <= 0) - fnSystem.yield(); - uint8_t ck_rcv = uart->read(); -#else - if (fnSioCom.get_sio_mode() == SioCom::sio_mode::NETSIO) +#ifndef ESP_PLATFORM + if (SYSTEM_BUS.get_sio_mode() == SioCom::sio_mode::NETSIO) { - fnSioCom.netsio_write_size(len); // set hint for NetSIO + SYSTEM_BUS.netsio_write_size(len); // set hint for NetSIO } +#endif /* ! ESP_PLATFORM */ - size_t l = fnSioCom.readBytes(buf, len); + __BEGIN_IGNORE_UNUSEDVARS + size_t l = SYSTEM_BUS.read(buf, len); + __END_IGNORE_UNUSEDVARS // Wait for checksum - while (0 == fnSioCom.available()) + while (SYSTEM_BUS.available() <= 0) fnSystem.yield(); - uint8_t ck_rcv = fnSioCom.read(); -#endif + uint8_t ck_rcv = SYSTEM_BUS.read(); uint8_t ck_tst = sio_checksum(buf, len); @@ -137,13 +119,9 @@ uint8_t virtualDevice::bus_to_peripheral(uint8_t *buf, unsigned short len) // SIO NAK void virtualDevice::sio_nak() { -#ifdef ESP_PLATFORM - UARTManager *uart = SYSTEM_BUS.uart; - uart->write('N'); - uart->flush(); -#else - fnSioCom.write('N'); - fnSioCom.flush(); + SYSTEM_BUS.write('N'); + SYSTEM_BUS.flush(); +#ifndef ESP_PLATFORM SYSTEM_BUS.set_command_processed(true); #endif Debug_println("NAK!"); @@ -152,15 +130,10 @@ void virtualDevice::sio_nak() // SIO ACK void virtualDevice::sio_ack() { -#ifdef ESP_PLATFORM - UARTManager *uart = SYSTEM_BUS.uart; - uart->write('A'); + SYSTEM_BUS.write('A'); fnSystem.delay_microseconds(DELAY_T5); //? - uart->flush(); -#else - fnSioCom.write('A'); - fnSystem.delay_microseconds(DELAY_T5); //? - fnSioCom.flush(); + SYSTEM_BUS.flush(); +#ifndef ESP_PLATFORM SYSTEM_BUS.set_command_processed(true); #endif Debug_println("ACK!"); @@ -170,9 +143,9 @@ void virtualDevice::sio_ack() #ifndef ESP_PLATFORM void virtualDevice::sio_late_ack() { - if (fnSioCom.get_sio_mode() == SioCom::sio_mode::NETSIO) + if (SYSTEM_BUS.get_sio_mode() == SioCom::sio_mode::NETSIO) { - fnSioCom.netsio_late_sync('A'); + SYSTEM_BUS.netsio_late_sync('A'); SYSTEM_BUS.set_command_processed(true); Debug_println("ACK+!"); } @@ -187,11 +160,7 @@ void virtualDevice::sio_late_ack() void virtualDevice::sio_complete() { fnSystem.delay_microseconds(DELAY_T5); -#ifdef ESP_PLATFORM - SYSTEM_BUS.uart->write('C'); -#else - fnSioCom.write('C'); -#endif + SYSTEM_BUS.write('C'); Debug_println("COMPLETE!"); } @@ -199,11 +168,7 @@ void virtualDevice::sio_complete() void virtualDevice::sio_error() { fnSystem.delay_microseconds(DELAY_T5); -#ifdef ESP_PLATFORM - SYSTEM_BUS.uart->write('E'); -#else - fnSioCom.write('E'); -#endif + SYSTEM_BUS.write('E'); Debug_println("ERROR!"); } @@ -231,11 +196,7 @@ void systemBus::_sio_process_cmd() { _modemDev->modemActive = false; Debug_println("Modem was active - resetting SIO baud"); -#ifdef ESP_PLATFORM - SYSTEM_BUS.uart->set_baudrate(_sioBaud); -#else - fnSioCom.set_baudrate(_sioBaud); -#endif + SYSTEM_BUS.setBaudrate(_sioBaud); } // Read CMD frame @@ -243,19 +204,11 @@ void systemBus::_sio_process_cmd() tempFrame.commanddata = 0; tempFrame.checksum = 0; -#ifdef ESP_PLATFORM - if (SYSTEM_BUS.uart->readBytes((uint8_t *)&tempFrame, sizeof(tempFrame)) != sizeof(tempFrame)) + if (SYSTEM_BUS.read((uint8_t *)&tempFrame, sizeof(tempFrame)) != sizeof(tempFrame)) { // Debug_println("Timeout waiting for data after CMD pin asserted"); return; } -#else - if (fnSioCom.readBytes((uint8_t *)&tempFrame, sizeof(tempFrame)) != sizeof(tempFrame)) - { - Debug_println("Timeout waiting for data after CMD pin asserted"); - return; - } -#endif // Turn on the SIO indicator LED fnLedManager.set(eLed::LED_BUS, true); @@ -269,7 +222,7 @@ void systemBus::_sio_process_cmd() fnSystem.yield(); #else int i = 0; - while (fnSioCom.command_asserted()) + while (_port.command_asserted()) { fnSystem.delay_microseconds(500); if (++i == 100) @@ -279,12 +232,12 @@ void systemBus::_sio_process_cmd() } } - int bytes_pending = fnSioCom.available(); + int bytes_pending = _port.available(); if (bytes_pending > 0) { Debug_printf("!!! Extra bytes pending (%d)\n", bytes_pending); // TODO use last 5 received bytes as command frame - // fnSioCom.flush_input(); + // _port.flush_input(); } #endif @@ -413,7 +366,7 @@ void systemBus::service() #ifdef ESP_PLATFORM if (fnSystem.digital_read(PIN_CMD) == DIGI_LOW) #else - if (fnSioCom.command_asserted()) + if (_port.command_asserted()) #endif { Debug_println("CMD Asserted, stopping UDP Stream"); @@ -447,7 +400,7 @@ void systemBus::service() #ifdef ESP_PLATFORM if (fnSystem.digital_read(PIN_MTR) == DIGI_HIGH) // TODO: use cassette helper function for consistency? #else - if (fnSioCom.motor_asserted()) + if (_port.motor_asserted()) #endif { if (_fujiDev->cassette()->is_active() == false) // keep this logic because motor line mode @@ -481,7 +434,7 @@ void systemBus::service() #ifdef ESP_PLATFORM if (fnSystem.digital_read(PIN_CMD) == DIGI_LOW) #else - if (fnSioCom.command_asserted()) + if (_port.command_asserted()) #endif { #ifndef ESP_PLATFORM @@ -506,10 +459,10 @@ void systemBus::service() { // flush UART input #ifdef ESP_PLATFORM - SYSTEM_BUS.uart->flush_input(); + SYSTEM_BUS.discardInput(); #else - if (fnSioCom.get_sio_mode() == SioCom::sio_mode::SERIAL) - fnSioCom.flush_input(); + if (_port.get_sio_mode() == SioCom::sio_mode::SERIAL) + _port.flush_input(); #endif } @@ -523,7 +476,7 @@ void systemBus::service() // loop until all SIO "events" are processed // true = SIO port needs handling // false = no SIO "event" ocurred within interval - } while (fnSioCom.poll(1)); + } while (_port.poll(1)); #endif } @@ -534,7 +487,7 @@ void systemBus::setup() #ifdef ESP_PLATFORM // Set up UART - SYSTEM_BUS.uart->begin(_sioBaud); + _port.begin(_sioBaud); // INT PIN fnSystem.set_pin_mode(PIN_INT, gpio_mode_t::GPIO_MODE_OUTPUT_OD, SystemManager::pull_updown_t::PULL_UP); @@ -565,21 +518,21 @@ void systemBus::setup() else setHighSpeedIndex(_sioHighSpeedIndex); - SYSTEM_BUS.uart->flush_input(); + _port.flush_input(); #else // Setup SIO ports: serial UART and NetSIO - fnSioCom.set_serial_port(Config.get_serial_port().c_str(), Config.get_serial_command(), Config.get_serial_proceed()); // UART - fnSioCom.set_netsio_host(Config.get_boip_host().c_str(), Config.get_boip_port()); // NetSIO - fnSioCom.set_sio_mode(Config.get_boip_enabled() ? SioCom::sio_mode::NETSIO : SioCom::sio_mode::SERIAL); - fnSioCom.begin(_sioBaud); + _port.set_serial_port(Config.get_serial_port().c_str(), Config.get_serial_command(), Config.get_serial_proceed()); // UART + _port.set_netsio_host(Config.get_boip_host().c_str(), Config.get_boip_port()); // NetSIO + _port.set_sio_mode(Config.get_boip_enabled() ? SioCom::sio_mode::NETSIO : SioCom::sio_mode::SERIAL); + _port.begin(_sioBaud); - fnSioCom.set_interrupt(false); - fnSioCom.set_proceed(false); + _port.set_interrupt(false); + _port.set_proceed(false); // Set the initial HSIO index setHighSpeedIndex(Config.get_general_hsioindex()); - fnSioCom.flush_input(); + _port.flush_input(); #endif } @@ -669,7 +622,7 @@ void systemBus::shutdown() } Debug_printf("All devices shut down.\n"); #ifndef ESP_PLATFORM - fnSioCom.end(); + _port.end(); #endif } @@ -682,15 +635,13 @@ void systemBus::toggleBaudrate() // Debug_printf("Toggling baudrate from %d to %d\n", _sioBaud, baudrate); _sioBaud = baudrate; -#ifdef ESP_PLATFORM - SYSTEM_BUS.uart->set_baudrate(_sioBaud); -#else - fnSioCom.flush_input(); - fnSioCom.flush(); +#ifndef ESP_PLATFORM + _port.flush_input(); + _port.flush(); // hmm, calling flush() may not be enough to empty TX buffer fnSystem.delay_microseconds(2000); - fnSioCom.set_baudrate(_sioBaud); #endif + _port.set_baudrate(_sioBaud); } int systemBus::getBaudrate() @@ -708,11 +659,7 @@ void systemBus::setBaudrate(int baud) Debug_printf("Changing baudrate from %d to %d\n", _sioBaud, baud); _sioBaud = baud; -#ifdef ESP_PLATFORM - SYSTEM_BUS.uart->set_baudrate(baud); -#else - fnSioCom.set_baudrate(baud); -#endif + _port.set_baudrate(baud); } // Set HSIO index. Sets high speed SIO baud and also returns that value. @@ -736,28 +683,28 @@ int systemBus::setHighSpeedIndex(int hsio_index) return _sioBaudHigh; } - switch (hsio_index) + switch (hsio_index) { - case 0: - case 1: - case 2: - case 3: - case 4: - // compensate for late pokey sampling, add 3 cycles to byte time - _sioBaudHigh = (SIO_ATARI_PAL_FREQUENCY * 10) / (10 * (2 * (hsio_index + 7)) + 3); + case 0: + case 1: + case 2: + case 3: + case 4: + // compensate for late pokey sampling, add 3 cycles to byte time + _sioBaudHigh = (SIO_ATARI_PAL_FREQUENCY * 10) / (10 * (2 * (hsio_index + 7)) + 3); break; - case 8: - _sioBaudHigh = 57600; + case 8: + _sioBaudHigh = 57600; break; - case 16: - _sioBaudHigh = 38400; + case 16: + _sioBaudHigh = 38400; break; - case 40: - _sioBaudHigh = SIO_STANDARD_BAUDRATE; // 19200 + case 40: + _sioBaudHigh = SIO_STANDARD_BAUDRATE; // 19200 break; - default: - _sioBaudHigh = SIO_ATARI_PAL_FREQUENCY / (2 * (hsio_index + 7)); - } + default: + _sioBaudHigh = SIO_ATARI_PAL_FREQUENCY / (2 * (hsio_index + 7)); + } _sioHighSpeedIndex = hsio_index; @@ -788,9 +735,9 @@ void systemBus::set_command_processed(bool processed) // Empty acknowledgment message for NetSIO hub void systemBus::sio_empty_ack() { - if (fnSioCom.get_sio_mode() == SioCom::sio_mode::NETSIO) + if (_port.get_sio_mode() == SioCom::sio_mode::NETSIO) { - fnSioCom.netsio_empty_sync(); + _port.netsio_empty_sync(); } } #endif @@ -881,10 +828,8 @@ void systemBus::setUltraHigh(bool _enable, int _ultraHighBaud) #ifdef ESP_PLATFORM ledc_channel_config(&ledc_channel_sio_ckin); ledc_timer_config(&ledc_timer); - SYSTEM_BUS.uart->set_baudrate(_sioBaudUltraHigh); -#else - fnSioCom.set_baudrate(_sioBaudUltraHigh); #endif + _port.set_baudrate(_sioBaudUltraHigh); } else { @@ -893,10 +838,17 @@ void systemBus::setUltraHigh(bool _enable, int _ultraHighBaud) #ifdef ESP_PLATFORM ledc_stop(LEDC_ESP32XX_HIGH_SPEED, LEDC_CHANNEL_1, 0); ledc_stop(LEDC_SPEED_MODE_MAX, LEDC_CHANNEL_1, 0); - SYSTEM_BUS.uart->set_baudrate(SIO_STANDARD_BAUDRATE); -#else - fnSioCom.set_baudrate(SIO_STANDARD_BAUDRATE); #endif + _port.set_baudrate(SIO_STANDARD_BAUDRATE); } } + +bool systemBus::motor_asserted() +{ +#ifdef ESP_PLATFORM + return (bool)fnSystem.digital_read(PIN_MTR); +#else + return _port.motor_asserted(); +#endif +} #endif /* BUILD_ATARI */ diff --git a/lib/bus/sio/sio.h b/lib/bus/sio/sio.h index 0cdc71f1e..aa66996a8 100755 --- a/lib/bus/sio/sio.h +++ b/lib/bus/sio/sio.h @@ -168,7 +168,7 @@ class virtualDevice #ifdef ESP_PLATFORM inline void sio_late_ack() { sio_ack(); }; #else - void sio_late_ack(); + void sio_late_ack(); #endif /** @@ -196,7 +196,7 @@ class virtualDevice /** * @brief Return the two aux bytes in cmdFrame as a single 16-bit value, commonly used, for example to retrieve * a sector number, for disk, or a number of bytes waiting for the sioNetwork device. - * + * * @return 16-bit value of DAUX1/DAUX2 in cmdFrame. */ unsigned short sio_get_aux(); @@ -208,7 +208,7 @@ class virtualDevice virtual void sio_status() = 0; /** - * @brief All SIO devices repeatedly call this routine to fan out to other methods for each command. + * @brief All SIO devices repeatedly call this routine to fan out to other methods for each command. * This is typcially implemented as a switch() statement. */ virtual void sio_process(uint32_t commanddata, uint8_t checksum) = 0; @@ -282,6 +282,12 @@ class systemBus bool useUltraHigh = false; // Use fujinet derived clock. +#ifdef ESP_PLATFORM + MODEM_UART_T _port = MODEM_UART_T(FN_UART_BUS); +#else + MODEM_UART_T _port; +#endif + #ifndef ESP_PLATFORM bool _command_processed = false; #endif @@ -332,9 +338,39 @@ class systemBus QueueHandle_t qSioMessages = nullptr; #endif - MODEM_UART_T* uart; // UART manager to use. - void set_uart(MODEM_UART_T* _uart) { uart = _uart; } + // Everybody thinks "oh I know how a serial port works, I'll just + // access it directly and bypass the bus!" ಠ_ಠ + size_t read(void *buffer, size_t length) { return _port.readBytes((uint8_t *) buffer, length); } + size_t read() { return _port.read(); } + size_t write(const void *buffer, size_t length) { return _port.write((uint8_t *) buffer, length); } + size_t write(int n) { return _port.write(n); } + size_t available() { return _port.available(); } + void flush() { _port.flush(); } + void discardInput() { _port.flush_input(); } + size_t print(int n, int base = 10) { return _port.print(n, base); } + size_t print(const char *str) { return _port.print(str); } + size_t print(const std::string &str) { return _port.print(str); } +#ifndef ESP_PLATFORM + // specific to NetSioPort + void set_netsio_host(const char *host, int port) { _port.set_netsio_host(host, port); } + const char* get_netsio_host(int &port) { return _port.get_netsio_host(port); } + void netsio_late_sync(uint8_t c) { _port.netsio_late_sync(c); } + void netsio_empty_sync() { _port.netsio_empty_sync(); } + void netsio_write_size(int write_size) { _port.netsio_write_size(write_size); } + + // get/set SIO mode + SioCom::sio_mode get_sio_mode() { return _port.get_sio_mode(); } + void set_sio_mode(SioCom::sio_mode mode) { _port.set_sio_mode(mode); } + void reset_sio_port(SioCom::sio_mode mode) { _port.reset_sio_port(mode); } + + void set_proceed(bool level) { _port.set_proceed(level); } + bool poll(int ms) { return _port.poll(ms); } + bool command_asserted() { return _port.command_asserted(); } + void bus_idle(uint16_t ms) { _port.bus_idle(ms); } +#endif /* ESP_PLATFORM */ + + bool motor_asserted(); }; extern systemBus SYSTEM_BUS; diff --git a/lib/bus/sio/siocom/fnSioCom.cpp b/lib/bus/sio/siocom/fnSioCom.cpp index f2918ec69..4f165bbde 100644 --- a/lib/bus/sio/siocom/fnSioCom.cpp +++ b/lib/bus/sio/siocom/fnSioCom.cpp @@ -13,8 +13,6 @@ * or network SIO (NetSio = SIO over UDP) for use with Altirra Atari Emulator */ -SioCom fnSioCom; - SioCom::SioCom() : _sio_mode(sio_mode::SERIAL), _sioPort(&_serialSio) {} void SioCom::begin(int baud) @@ -25,9 +23,9 @@ void SioCom::begin(int baud) _sioPort->begin(get_baudrate()); } -void SioCom::end() -{ - _sioPort->end(); +void SioCom::end() +{ + _sioPort->end(); } /* @@ -37,25 +35,25 @@ void SioCom::end() */ bool SioCom::poll(int ms) { - return _sioPort->poll(ms); + return _sioPort->poll(ms); } -void SioCom::set_baudrate(uint32_t baud) -{ - _sioPort->set_baudrate(baud); +void SioCom::set_baudrate(uint32_t baud) +{ + _sioPort->set_baudrate(baud); } uint32_t SioCom::get_baudrate() { - return _sioPort->get_baudrate(); + return _sioPort->get_baudrate(); } -bool SioCom::command_asserted() +bool SioCom::command_asserted() { return _sioPort->command_asserted(); } -bool SioCom::motor_asserted() +bool SioCom::motor_asserted() { return _sioPort->motor_asserted(); } @@ -70,12 +68,12 @@ void SioCom::set_interrupt(bool level) _sioPort->set_interrupt(level); } -int SioCom::available() +int SioCom::available() { return _sioPort->available(); } -void SioCom::flush() +void SioCom::flush() { _sioPort->flush(); } @@ -110,7 +108,7 @@ ssize_t SioCom::write(uint8_t b) } // write buffer -ssize_t SioCom::write(const uint8_t *buffer, size_t size) +ssize_t SioCom::write(const uint8_t *buffer, size_t size) { return _sioPort->write(buffer, size); } @@ -208,12 +206,12 @@ const char* SioCom::get_serial_port(int &command_pin, int &proceed_pin) }; // specific to NetSioPort -void SioCom::set_netsio_host(const char *host, int port) +void SioCom::set_netsio_host(const char *host, int port) { _netSio.set_host(host, port); } -const char* SioCom::get_netsio_host(int &port) +const char* SioCom::get_netsio_host(int &port) { return _netSio.get_host(port); } @@ -257,4 +255,4 @@ void SioCom::reset_sio_port(sio_mode mode) #endif // BUILD_ATARI -#endif // !ESP_PLATFORM \ No newline at end of file +#endif // !ESP_PLATFORM diff --git a/lib/bus/sio/siocom/fnSioCom.h b/lib/bus/sio/siocom/fnSioCom.h index d8ea5192b..5ba6849f0 100644 --- a/lib/bus/sio/siocom/fnSioCom.h +++ b/lib/bus/sio/siocom/fnSioCom.h @@ -93,6 +93,4 @@ class SioCom void reset_sio_port(sio_mode mode); }; -extern SioCom fnSioCom; - #endif // SIOCOM_H diff --git a/lib/device/adamnet/fuji.cpp b/lib/device/adamnet/fuji.cpp index 02230d8b3..6ed3cf083 100755 --- a/lib/device/adamnet/fuji.cpp +++ b/lib/device/adamnet/fuji.cpp @@ -367,8 +367,8 @@ void adamFuji::adamnet_copy_file() ck = adamnet_recv(); SYSTEM_BUS.wait_for_idle(); - fnUartBUS.write(0x9f); // ACK. - fnUartBUS.flush(); + SYSTEM_BUS.write(0x9f); // ACK. + SYSTEM_BUS.flush(); dataBuf = (char *)malloc(COPY_SIZE); @@ -1415,7 +1415,7 @@ void adamFuji::adamnet_get_time() struct tm *now = localtime(&tt); - /* + /* NWD order has changed to match apple format Previously: response[0] = now->tm_mday; @@ -1426,15 +1426,15 @@ void adamFuji::adamnet_get_time() response[5] = now->tm_sec; */ - response[0] = (now->tm_year) / 100 + 19; - response[1] = now->tm_year % 100; - response[2] = now->tm_mon + 1; - response[3] = now->tm_mday; - response[4] = now->tm_hour; - response[5] = now->tm_min; - response[6] = now->tm_sec; + response[0] = (now->tm_year) / 100 + 19; + response[1] = now->tm_year % 100; + response[2] = now->tm_mon + 1; + response[3] = now->tm_mday; + response[4] = now->tm_hour; + response[5] = now->tm_min; + response[6] = now->tm_sec; - response_len = 7; + response_len = 7; Debug_printf("Sending %02X %02X %02X %02X %02X %02X %02X\n", response[0], response[1], response[2], response[3], response[4], response[5], response[6]); } diff --git a/lib/device/adamnet/modem.cpp b/lib/device/adamnet/modem.cpp index e0c1d7894..d49076795 100755 --- a/lib/device/adamnet/modem.cpp +++ b/lib/device/adamnet/modem.cpp @@ -41,7 +41,7 @@ static void _telnet_event_handler(telnet_t *telnet, telnet_event_t *ev, void *us switch (ev->type) { case TELNET_EV_DATA: - if (ev->data.size && fnUartBUS.write((uint8_t *)ev->data.buffer, ev->data.size) != ev->data.size) + if (ev->data.size && SYSTEM_BUS.write((uint8_t *)ev->data.buffer, ev->data.size) != ev->data.size) Debug_printf("_telnet_event_handler(%d) - Could not write complete buffer to SIO.\n", ev->type); break; case TELNET_EV_SEND: @@ -128,8 +128,8 @@ void adamModem::at_connect_resultCode(int modemBaud) resultCode = 1; break; } - fnUartBUS.print(resultCode); - fnUartBUS.write(ASCII_CR); + SYSTEM_BUS.print(resultCode); + SYSTEM_BUS.write(ASCII_CR); } /** @@ -138,9 +138,9 @@ void adamModem::at_connect_resultCode(int modemBaud) */ void adamModem::at_cmd_resultCode(int resultCode) { - fnUartBUS.print(resultCode); - fnUartBUS.write(ASCII_CR); - fnUartBUS.write(ASCII_LF); + SYSTEM_BUS.print(resultCode); + SYSTEM_BUS.write(ASCII_CR); + SYSTEM_BUS.write(ASCII_LF); } /** @@ -153,14 +153,14 @@ void adamModem::at_cmd_println() if (cmdAtascii == true) { - fnUartBUS.write(ATASCII_EOL); + SYSTEM_BUS.write(ATASCII_EOL); } else { - fnUartBUS.write(ASCII_CR); - fnUartBUS.write(ASCII_LF); + SYSTEM_BUS.write(ASCII_CR); + SYSTEM_BUS.write(ASCII_LF); } - fnUartBUS.flush(); + SYSTEM_BUS.flush(); } void adamModem::at_cmd_println(const char *s, bool addEol) @@ -168,20 +168,20 @@ void adamModem::at_cmd_println(const char *s, bool addEol) if (cmdOutput == false) return; - fnUartBUS.print(s); + SYSTEM_BUS.print(s); if (addEol) { if (cmdAtascii == true) { - fnUartBUS.write(ATASCII_EOL); + SYSTEM_BUS.write(ATASCII_EOL); } else { - fnUartBUS.write(ASCII_CR); - fnUartBUS.write(ASCII_LF); + SYSTEM_BUS.write(ASCII_CR); + SYSTEM_BUS.write(ASCII_LF); } } - fnUartBUS.flush(); + SYSTEM_BUS.flush(); } void adamModem::at_cmd_println(int i, bool addEol) @@ -189,20 +189,20 @@ void adamModem::at_cmd_println(int i, bool addEol) if (cmdOutput == false) return; - fnUartBUS.print(i); + SYSTEM_BUS.print(i); if (addEol) { if (cmdAtascii == true) { - fnUartBUS.write(ATASCII_EOL); + SYSTEM_BUS.write(ATASCII_EOL); } else { - fnUartBUS.write(ASCII_CR); - fnUartBUS.write(ASCII_LF); + SYSTEM_BUS.write(ASCII_CR); + SYSTEM_BUS.write(ASCII_LF); } } - fnUartBUS.flush(); + SYSTEM_BUS.flush(); } void adamModem::at_cmd_println(std::string s, bool addEol) @@ -210,20 +210,20 @@ void adamModem::at_cmd_println(std::string s, bool addEol) if (cmdOutput == false) return; - fnUartBUS.print(s); + SYSTEM_BUS.print(s); if (addEol) { if (cmdAtascii == true) { - fnUartBUS.write(ATASCII_EOL); + SYSTEM_BUS.write(ATASCII_EOL); } else { - fnUartBUS.write(ASCII_CR); - fnUartBUS.write(ASCII_LF); + SYSTEM_BUS.write(ASCII_CR); + SYSTEM_BUS.write(ASCII_LF); } } - fnUartBUS.flush(); + SYSTEM_BUS.flush(); } void adamModem::at_handle_wificonnect() @@ -489,7 +489,7 @@ void adamModem::at_handle_answer() CRX = true; cmdMode = false; - fnUartBUS.flush(); + SYSTEM_BUS.flush(); answerHack = false; } } @@ -1030,11 +1030,11 @@ void adamModem::sio_handle_modem() // In command mode - don't exchange with TCP but gather characters to a string //if (SIO_UART.available() /*|| blockWritePending == true */ ) - if (fnUartBUS.available() > 0) + if (SYSTEM_BUS.available() > 0) { // get char from Atari SIO //char chr = SIO_UART.read(); - char chr = fnUartBUS.read(); + char chr = SYSTEM_BUS.read(); // Return, enter, new line, carriage return.. anything goes to end the command if ((chr == ASCII_LF) || (chr == ASCII_CR) || (chr == ATASCII_EOL)) @@ -1059,9 +1059,9 @@ void adamModem::sio_handle_modem() // Clear with a space if (commandEcho == true) { - fnUartBUS.write(ASCII_BACKSPACE); - fnUartBUS.write(' '); - fnUartBUS.write(ASCII_BACKSPACE); + SYSTEM_BUS.write(ASCII_BACKSPACE); + SYSTEM_BUS.write(' '); + SYSTEM_BUS.write(ASCII_BACKSPACE); } } } @@ -1074,7 +1074,7 @@ void adamModem::sio_handle_modem() { cmd.erase(len - 1); if (commandEcho == true) - fnUartBUS.write(ATASCII_BACKSPACE); + SYSTEM_BUS.write(ATASCII_BACKSPACE); } } // Take into account arrow key movement and clear screen @@ -1082,7 +1082,7 @@ void adamModem::sio_handle_modem() ((chr >= ATASCII_CURSOR_UP) && (chr <= ATASCII_CURSOR_RIGHT))) { if (commandEcho == true) - fnUartBUS.write(chr); + SYSTEM_BUS.write(chr); } else { @@ -1092,7 +1092,7 @@ void adamModem::sio_handle_modem() cmd += chr; } if (commandEcho == true) - fnUartBUS.write(chr); + SYSTEM_BUS.write(chr); } } } @@ -1124,7 +1124,7 @@ void adamModem::sio_handle_modem() } //int sioBytesAvail = SIO_UART.available(); - int sioBytesAvail = std::min(0, fnUartBUS.available()); + int sioBytesAvail = std::min((size_t) 0, SYSTEM_BUS.available()); // send from Atari to Fujinet if (sioBytesAvail && tcpClient.connected()) @@ -1139,8 +1139,8 @@ void adamModem::sio_handle_modem() // Read from serial, the amount available up to // maximum size of the buffer - int sioBytesRead = fnUartBUS.readBytes(&txBuf[0], //SIO_UART.readBytes(&txBuf[0], - (sioBytesAvail > TX_BUF_SIZE) ? TX_BUF_SIZE : sioBytesAvail); + int sioBytesRead = SYSTEM_BUS.read(&txBuf[0], //SIO_UART.readBytes(&txBuf[0], + (sioBytesAvail > TX_BUF_SIZE) ? TX_BUF_SIZE : sioBytesAvail); // Disconnect if going to AT mode with "+++" sequence for (int i = 0; i < (int)sioBytesRead; i++) @@ -1189,8 +1189,8 @@ void adamModem::sio_handle_modem() } else { - fnUartBUS.write(buf, bytesRead); - fnUartBUS.flush(); + SYSTEM_BUS.write(buf, bytesRead); + SYSTEM_BUS.flush(); } // And dump to sniffer, if enabled. @@ -1208,7 +1208,7 @@ void adamModem::sio_handle_modem() Debug_println("Going back to command mode"); at_cmd_println("OK"); - + cmdMode = true; plusCount = 0; diff --git a/lib/device/rs232/modem.cpp b/lib/device/rs232/modem.cpp index e351bd7b1..759b200ac 100755 --- a/lib/device/rs232/modem.cpp +++ b/lib/device/rs232/modem.cpp @@ -60,7 +60,7 @@ static void _telnet_event_handler(telnet_t *telnet, telnet_event_t *ev, void *us switch (ev->type) { case TELNET_EV_DATA: - if (ev->data.size && fnUartBUS.write((uint8_t *)ev->data.buffer, ev->data.size) != ev->data.size) + if (ev->data.size && SYSTEM_BUS.write((uint8_t *)ev->data.buffer, ev->data.size) != ev->data.size) Debug_printf("_telnet_event_handler(%d) - Could not write complete buffer to RS232.\n", ev->type); break; case TELNET_EV_SEND: @@ -570,7 +570,7 @@ void rs232Modem::rs232_stream() bus_to_computer((uint8_t *)response, sizeof(response), false); - fnUartBUS.set_baudrate(modemBaud); + SYSTEM_BUS.setBaudrate(modemBaud); modemActive = true; Debug_printf("Modem streaming at %u baud\n", modemBaud); } @@ -664,8 +664,8 @@ void rs232Modem::at_connect_resultCode(int modemBaud) resultCode = 1; break; } - fnUartBUS.print(resultCode); - fnUartBUS.write(ASCII_CR); + SYSTEM_BUS.print(resultCode); + SYSTEM_BUS.write(ASCII_CR); } /** @@ -674,9 +674,9 @@ void rs232Modem::at_connect_resultCode(int modemBaud) */ void rs232Modem::at_cmd_resultCode(int resultCode) { - fnUartBUS.print(resultCode); - fnUartBUS.write(ASCII_CR); - fnUartBUS.write(ASCII_LF); + SYSTEM_BUS.print(resultCode); + SYSTEM_BUS.write(ASCII_CR); + SYSTEM_BUS.write(ASCII_LF); } /** @@ -689,14 +689,14 @@ void rs232Modem::at_cmd_println() if (cmdAtascii == true) { - fnUartBUS.write(ATASCII_EOL); + SYSTEM_BUS.write(ATASCII_EOL); } else { - fnUartBUS.write(ASCII_CR); - fnUartBUS.write(ASCII_LF); + SYSTEM_BUS.write(ASCII_CR); + SYSTEM_BUS.write(ASCII_LF); } - fnUartBUS.flush(); + SYSTEM_BUS.flush(); } void rs232Modem::at_cmd_println(const char *s, bool addEol) @@ -704,20 +704,20 @@ void rs232Modem::at_cmd_println(const char *s, bool addEol) if (cmdOutput == false) return; - fnUartBUS.print(s); + SYSTEM_BUS.print(s); if (addEol) { if (cmdAtascii == true) { - fnUartBUS.write(ATASCII_EOL); + SYSTEM_BUS.write(ATASCII_EOL); } else { - fnUartBUS.write(ASCII_CR); - fnUartBUS.write(ASCII_LF); + SYSTEM_BUS.write(ASCII_CR); + SYSTEM_BUS.write(ASCII_LF); } } - fnUartBUS.flush(); + SYSTEM_BUS.flush(); } void rs232Modem::at_cmd_println(int i, bool addEol) @@ -725,20 +725,20 @@ void rs232Modem::at_cmd_println(int i, bool addEol) if (cmdOutput == false) return; - fnUartBUS.print(i); + SYSTEM_BUS.print(i); if (addEol) { if (cmdAtascii == true) { - fnUartBUS.write(ATASCII_EOL); + SYSTEM_BUS.write(ATASCII_EOL); } else { - fnUartBUS.write(ASCII_CR); - fnUartBUS.write(ASCII_LF); + SYSTEM_BUS.write(ASCII_CR); + SYSTEM_BUS.write(ASCII_LF); } } - fnUartBUS.flush(); + SYSTEM_BUS.flush(); } void rs232Modem::at_cmd_println(std::string s, bool addEol) @@ -746,20 +746,20 @@ void rs232Modem::at_cmd_println(std::string s, bool addEol) if (cmdOutput == false) return; - fnUartBUS.print(s); + SYSTEM_BUS.print(s); if (addEol) { if (cmdAtascii == true) { - fnUartBUS.write(ATASCII_EOL); + SYSTEM_BUS.write(ATASCII_EOL); } else { - fnUartBUS.write(ASCII_CR); - fnUartBUS.write(ASCII_LF); + SYSTEM_BUS.write(ASCII_CR); + SYSTEM_BUS.write(ASCII_LF); } } - fnUartBUS.flush(); + SYSTEM_BUS.flush(); } void rs232Modem::at_handle_wificonnect() @@ -1025,7 +1025,7 @@ void rs232Modem::at_handle_answer() CRX = true; cmdMode = false; - fnUartBUS.flush(); + SYSTEM_BUS.flush(); answerHack = false; } } @@ -1569,11 +1569,11 @@ void rs232Modem::rs232_handle_modem() // In command mode - don't exchange with TCP but gather characters to a string //if (RS232_UART.available() /*|| blockWritePending == true */ ) - if (fnUartBUS.available() > 0) + if (SYSTEM_BUS.available() > 0) { // get char from Atari RS232 //char chr = RS232_UART.read(); - char chr = fnUartBUS.read(); + char chr = SYSTEM_BUS.read(); // Return, enter, new line, carriage return.. anything goes to end the command if ((chr == ASCII_LF) || (chr == ASCII_CR) || (chr == ATASCII_EOL)) @@ -1598,9 +1598,9 @@ void rs232Modem::rs232_handle_modem() // Clear with a space if (commandEcho == true) { - fnUartBUS.write(ASCII_BACKSPACE); - fnUartBUS.write(' '); - fnUartBUS.write(ASCII_BACKSPACE); + SYSTEM_BUS.write(ASCII_BACKSPACE); + SYSTEM_BUS.write(' '); + SYSTEM_BUS.write(ASCII_BACKSPACE); } } } @@ -1613,7 +1613,7 @@ void rs232Modem::rs232_handle_modem() { cmd.erase(len - 1); if (commandEcho == true) - fnUartBUS.write(ATASCII_BACKSPACE); + SYSTEM_BUS.write(ATASCII_BACKSPACE); } } // Take into account arrow key movement and clear screen @@ -1621,7 +1621,7 @@ void rs232Modem::rs232_handle_modem() ((chr >= ATASCII_CURSOR_UP) && (chr <= ATASCII_CURSOR_RIGHT))) { if (commandEcho == true) - fnUartBUS.write(chr); + SYSTEM_BUS.write(chr); } else { @@ -1631,7 +1631,7 @@ void rs232Modem::rs232_handle_modem() cmd += chr; } if (commandEcho == true) - fnUartBUS.write(chr); + SYSTEM_BUS.write(chr); } } } @@ -1662,8 +1662,8 @@ void rs232Modem::rs232_handle_modem() } } - int rs232BytesAvail = fnUartBUS.available(); - //int rs232BytesAvail = std::min(0, fnUartBUS.available()); + int rs232BytesAvail = SYSTEM_BUS.available(); + //int rs232BytesAvail = std::min(0, SYSTEM_BUS.available()); // send from Atari to Fujinet if (rs232BytesAvail && tcpClient.connected()) @@ -1678,7 +1678,7 @@ void rs232Modem::rs232_handle_modem() // Read from serial, the amount available up to // maximum size of the buffer - int rs232BytesRead = fnUartBUS.readBytes(&txBuf[0], //RS232_UART.readBytes(&txBuf[0], + int rs232BytesRead = SYSTEM_BUS.read(&txBuf[0], //RS232_UART.readBytes(&txBuf[0], (rs232BytesAvail > TX_BUF_SIZE) ? TX_BUF_SIZE : rs232BytesAvail); // Disconnect if going to AT mode with "+++" sequence @@ -1728,8 +1728,8 @@ void rs232Modem::rs232_handle_modem() } else { - fnUartBUS.write(buf, bytesRead); - fnUartBUS.flush(); + SYSTEM_BUS.write(buf, bytesRead); + SYSTEM_BUS.flush(); } // And dump to sniffer, if enabled. diff --git a/lib/device/sio/cassette.cpp b/lib/device/sio/cassette.cpp index 55b72c3b2..f2e3bbcc5 100755 --- a/lib/device/sio/cassette.cpp +++ b/lib/device/sio/cassette.cpp @@ -12,17 +12,10 @@ #include "led.h" -// TODO: merge/fix this at global level -#ifdef ESP_PLATFORM -#define FN_BUS_LINK fnUartBUS -#else -#define FN_BUS_LINK fnSioCom -#endif - /** thinking about state machine * boolean states: * file mounted or not - * motor activated or not + * motor activated or not * (play/record button?) * state variables: * baud rate @@ -197,7 +190,7 @@ void sioCassette::mount_cassette_file(fnFile *f, size_t fz) // There is no facility to specify an output file for writing to C: or CSAVE // so instead of using the file mounted in slot 8 by CONFIG, create an output file with some serial number // files are created with the cassette is enabled. - + } _mounted = true; @@ -208,12 +201,14 @@ void sioCassette::sio_enable_cassette() cassetteActive = true; if (cassetteMode == cassette_mode_t::playback) - FN_BUS_LINK.set_baudrate(CASSETTE_BAUDRATE); + SYSTEM_BUS.setBaudrate(CASSETTE_BAUDRATE); if (cassetteMode == cassette_mode_t::record && tape_offset == 0) { open_cassette_file(&fnSDFAT); // hardcode SD card? - FN_BUS_LINK.end(); +#ifdef UNUSED + SYSTEM_BUS.end(); +#endif /* UNUSED */ #ifdef ESP_PLATFORM fnSystem.set_pin_mode(UART2_RX, gpio_mode_t::GPIO_MODE_INPUT, SystemManager::pull_updown_t::PULL_NONE, GPIO_INTR_ANYEDGE); @@ -269,12 +264,14 @@ void sioCassette::sio_disable_cassette() { cassetteActive = false; if (cassetteMode == cassette_mode_t::playback) - FN_BUS_LINK.set_baudrate(SIO_STANDARD_BAUDRATE); + SYSTEM_BUS.setBaudrate(SIO_STANDARD_BAUDRATE); else { close_cassette_file(); //TODO: gpio_isr_handler_remove((gpio_num_t)UART2_RX); - FN_BUS_LINK.begin(SIO_STANDARD_BAUDRATE); +#ifdef UNUSED + SYSTEM_BUS.begin(SIO_STANDARD_BAUDRATE); +#endif /* UNUSED */ } Debug_println("Cassette Mode disabled"); } @@ -342,7 +339,7 @@ size_t sioCassette::send_tape_block(size_t offset) unsigned char *p = atari_sector_buffer + BLOCK_LEN - 1; unsigned char i, r; - // if (offset < FileInfo.vDisk->size) { //data record + // if (offset < FileInfo.vDisk->size) { //data record if (offset < filesize) { //data record #ifdef DEBUG @@ -384,10 +381,10 @@ size_t sioCassette::send_tape_block(size_t offset) atari_sector_buffer[0] = 0x55; //sync marker atari_sector_buffer[1] = 0x55; // USART_Send_Buffer(atari_sector_buffer, BLOCK_LEN + 3); - FN_BUS_LINK.write(atari_sector_buffer, BLOCK_LEN + 3); + SYSTEM_BUS.write(atari_sector_buffer, BLOCK_LEN + 3); //USART_Transmit_Byte(get_checksum(atari_sector_buffer, BLOCK_LEN + 3)); - FN_BUS_LINK.write(sio_checksum(atari_sector_buffer, BLOCK_LEN + 3)); - FN_BUS_LINK.flush(); // wait for all data to be sent just like a tape + SYSTEM_BUS.write(sio_checksum(atari_sector_buffer, BLOCK_LEN + 3)); + SYSTEM_BUS.flush(); // wait for all data to be sent just like a tape // _delay_ms(300); //PRG(0-N) + PRWT(0.25s) delay fnSystem.delay(300); return (offset); @@ -461,7 +458,7 @@ size_t sioCassette::send_FUJI_tape_block(size_t offset) if (tape_flags.turbo) //ignore baud hdr continue; baud = hdr->irg_length; - FN_BUS_LINK.set_baudrate(baud); + SYSTEM_BUS.setBaudrate(baud); } offset += sizeof(struct tape_FUJI_hdr) + len; } @@ -481,13 +478,13 @@ size_t sioCassette::send_FUJI_tape_block(size_t offset) fnSystem.delay_microseconds(999); // shave off a usec for the MOTOR pin check #else int step; - // FN_BUS_LINK is fnSioCom - if (FN_BUS_LINK.get_sio_mode() == SioCom::sio_mode::NETSIO) + // SYSTEM_BUS is fnSioCom + if (SYSTEM_BUS.get_sio_mode() == SioCom::sio_mode::NETSIO) step = gap > 1000 ? 1000 : gap; // step is 1000 ms (NetSIO) else step = gap > 20 ? 20 : gap; // step is 20 ms (SerialSIO) gap -= step; - FN_BUS_LINK.bus_idle(step); // idle bus (i.e. delay for SerialSIO, BUS_IDLE message for NetSIO) + SYSTEM_BUS.bus_idle(step); // idle bus (i.e. delay for SerialSIO, BUS_IDLE message for NetSIO) #endif if (has_pulldown() && !motor_line() && gap > 1000) { @@ -526,8 +523,8 @@ size_t sioCassette::send_FUJI_tape_block(size_t offset) Debug_printf("Sending %u bytes\r\n", buflen); for (int i = 0; i < buflen; i++) Debug_printf("%02x ", atari_sector_buffer[i]); - FN_BUS_LINK.write(atari_sector_buffer, buflen); - FN_BUS_LINK.flush(); // wait for all data to be sent just like a tape + SYSTEM_BUS.write(atari_sector_buffer, buflen); + SYSTEM_BUS.flush(); // wait for all data to be sent just like a tape Debug_printf("\r\n"); if (first && atari_sector_buffer[2] == 0xfe) diff --git a/lib/device/sio/cassette.h b/lib/device/sio/cassette.h index 37c67d807..36f9de3bb 100755 --- a/lib/device/sio/cassette.h +++ b/lib/device/sio/cassette.h @@ -83,11 +83,7 @@ class sioCassette : public virtualDevice uint8_t decode_fsk(); // helper function to read motor pin -#ifdef ESP_PLATFORM - bool motor_line() { return (bool)fnSystem.digital_read(PIN_MTR); } -#else - bool motor_line() { return fnSioCom.motor_asserted(); } -#endif + bool motor_line() { return SYSTEM_BUS.motor_asserted(); } // have to populate virtual functions to complete class void sio_status() override{}; // $53, 'S', Status @@ -143,4 +139,4 @@ class sioCassette : public virtualDevice size_t receive_FUJI_tape_block(size_t offset); }; -#endif \ No newline at end of file +#endif diff --git a/lib/device/sio/fuji.cpp b/lib/device/sio/fuji.cpp index 8b60a4429..e2d33870f 100644 --- a/lib/device/sio/fuji.cpp +++ b/lib/device/sio/fuji.cpp @@ -319,7 +319,7 @@ void sioFuji::sio_net_get_wifi_enabled() // Set SIO baudrate void sioFuji::sio_set_baudrate() { - + int br = 0; switch(cmdFrame.aux1) { @@ -356,18 +356,15 @@ void sioFuji::sio_set_baudrate() sio_error(); return; } - + // send complete with current baudrate sio_complete(); -#ifdef ESP_PLATFORM - SYSTEM_BUS.uart->flush(); - SYSTEM_BUS.uart->set_baudrate(br); -#else - fnSioCom.flush(); + SYSTEM_BUS.flush(); +#ifndef ESP_PLATFORM fnSystem.delay_microseconds(2000); - fnSioCom.set_baudrate(br); #endif + SYSTEM_BUS.setBaudrate(br); } // Mount Server @@ -652,9 +649,9 @@ void sioFuji::sio_copy_file() do { #ifndef ESP_PLATFORM - if (fnSioCom.get_sio_mode() == SioCom::sio_mode::NETSIO && fnSystem.millis() - poll_ts > 1000) + if (SYSTEM_BUS.get_sio_mode() == SioCom::sio_mode::NETSIO && fnSystem.millis() - poll_ts > 1000) { - fnSioCom.poll(1); + SYSTEM_BUS.poll(1); poll_ts = fnSystem.millis(); } #endif @@ -961,8 +958,8 @@ void sioFuji::sio_read_app_key() fclose(fIn); #ifdef DEBUG - std::string msg = util_hexdump(response_data.data(), appkey_size); - Debug_printf("\n%s\n", msg.c_str()); + std::string msg = util_hexdump(response_data.data(), appkey_size); + Debug_printf("\n%s\n", msg.c_str()); #endif bus_to_computer(response_data.data(), response_data.size(), false); @@ -1210,23 +1207,23 @@ void _set_additional_direntry_details(fsdir_entry_t *f, uint8_t *dest, uint8_t m /* * Read directory entries in block mode - * + * * Input parameters: * aux1: Number of 256-byte pages to return (determines maximum response size) * aux2: Lower 6 bits define the number of entries per page group - * + * * Response format: * Overall response header: * Byte 0 : 'M' (Magic number byte 1) * Byte 1 : 'F' (Magic number byte 2) * Byte 2 : Header size (4) * Byte 3 : Number of page groups that follow - * + * * Followed by one or more complete PageGroups, padded to aux1 * 256 bytes. * Each PageGroup must fit entirely within the response - partial groups are not allowed. * If a PageGroup would exceed the remaining space, the directory position is rewound * and that group is not included. - * + * * PageGroup structure: * Byte 0 : Flags * - Bit 7: Last group (1=yes, 0=no) @@ -1245,7 +1242,7 @@ void _set_additional_direntry_details(fsdir_entry_t *f, uint8_t *dest, uint8_t m * - Bytes 4-6: File size (24-bit little-endian, 0 for directories) * - Byte 7 : Media type (0-255, with 0=unknown) * - Bytes 8+ : Null-terminated filename - * + * * The last PageGroup in the response will have its last_group flag set if: * a) There are no more directory entries to process, or * b) The next PageGroup would exceed the maximum response size @@ -1266,7 +1263,7 @@ void sioFuji::sio_read_directory_block() uint16_t starting_pos = _fnHosts[_current_open_directory_slot].dir_tell(); #endif /* WE_NEED_TO_REWIND */ // Debug_printf("Starting directory position: %d\n", starting_pos); - + std::vector page_groups; size_t total_size = 0; bool is_last_entry = false; @@ -1275,17 +1272,17 @@ void sioFuji::sio_read_directory_block() // Create a new page group DirectoryPageGroup group; uint16_t group_start_pos = _fnHosts[_current_open_directory_slot].dir_tell(); - + // Calculate group index (0-based) group.index = group_start_pos / group_size; - - // Debug_printf("Starting new group at directory position: %d (index=%d)\n", + + // Debug_printf("Starting new group at directory position: %d (index=%d)\n", // group_start_pos, group.index); - + // Fill the group with entries for (int i = 0; i < group_size && !is_last_entry; i++) { fsdir_entry_t *f = _fnHosts[_current_open_directory_slot].dir_nextfile(); - + if (f == nullptr) { // Debug_println("Reached end of directory"); is_last_entry = true; @@ -1293,9 +1290,9 @@ void sioFuji::sio_read_directory_block() break; } - // Debug_printf("Adding entry %d: \"%s\" (size=%lu)\n", + // Debug_printf("Adding entry %d: \"%s\" (size=%lu)\n", // i, f->filename, f->size); - + if (!group.add_entry(f)) { // Debug_println("Failed to add entry to group"); break; @@ -1315,7 +1312,7 @@ void sioFuji::sio_read_directory_block() size_t new_total = total_size + group.data.size(); // Debug_printf("Group stats: entries=%d, size=%d, new_total=%d/%d\n", // group.entry_count, group.data.size(), new_total, max_block_size); - + if (new_total > max_block_size) { // Debug_printf("Group would exceed max_block_size (%d > %d), rewinding to pos %d\n", // new_total, max_block_size, group_start_pos); @@ -1323,11 +1320,11 @@ void sioFuji::sio_read_directory_block() _fnHosts[_current_open_directory_slot].dir_seek(group_start_pos); break; } - + // Add group to our collection total_size = new_total; page_groups.push_back(std::move(group)); - // Debug_printf("Added group %d, total_size now %d\n", + // Debug_printf("Added group %d, total_size now %d\n", // page_groups.size(), total_size); } @@ -1376,7 +1373,7 @@ void sioFuji::sio_read_directory_entry() sio_error(); return; } - + // detect block mode in request if ((cmdFrame.aux2 & 0xC0) == 0xC0) { sio_read_directory_block(); diff --git a/lib/device/sio/modem.cpp b/lib/device/sio/modem.cpp index 69a91a3f8..c4ece2949 100755 --- a/lib/device/sio/modem.cpp +++ b/lib/device/sio/modem.cpp @@ -60,7 +60,7 @@ static void _telnet_event_handler(telnet_t *telnet, telnet_event_t *ev, void *us switch (ev->type) { case TELNET_EV_DATA: - if (ev->data.size && SYSTEM_BUS.uart->write((uint8_t *)ev->data.buffer, ev->data.size) != ev->data.size) + if (ev->data.size && SYSTEM_BUS.write((uint8_t *)ev->data.buffer, ev->data.size) != ev->data.size) Debug_printf("_telnet_event_handler(%d) - Could not write complete buffer to SIO.\n", ev->type); break; case TELNET_EV_SEND: @@ -193,7 +193,7 @@ void modem::sio_poll_1() Send back SIO command for booting. This is a 12 uint8_t + chk block that is meant to be written to the SIO parameter block starting at DDEVIC ($0300). - The boot block MUST start at $0500. There are both BASIC-based and cart-based + The boot block MUST start at $0500. There are both BASIC-based and cart-based loaders that use JSR $0506 to run the loader. */ @@ -427,7 +427,7 @@ void modem::sio_control() tcpClient.stop(); // Hang up if DTR drops. CRX = false; cmdMode = true; - + if (listenPort > 0) { // tcpServer.stop(); @@ -571,9 +571,9 @@ void modem::sio_stream() } bus_to_computer((uint8_t *)response, sizeof(response), false); - + fnSystem.delay_microseconds(DELAY_FIRMWARE_DELIVERY); // macOS workaround (flush on uart was not working) - SYSTEM_BUS.uart->set_baudrate(modemBaud); + SYSTEM_BUS.setBaudrate(modemBaud); modemActive = true; Debug_printf("Modem streaming at %u baud\n", modemBaud); } @@ -680,8 +680,8 @@ void modem::at_connect_resultCode(int modemBaud) resultCode = 1; break; } - SYSTEM_BUS.uart->print(resultCode); - SYSTEM_BUS.uart->write(ASCII_CR); + SYSTEM_BUS.print(resultCode); + SYSTEM_BUS.write(ASCII_CR); } /** @@ -690,9 +690,9 @@ void modem::at_connect_resultCode(int modemBaud) */ void modem::at_cmd_resultCode(int resultCode) { - SYSTEM_BUS.uart->print(resultCode); - SYSTEM_BUS.uart->write(ASCII_CR); - SYSTEM_BUS.uart->write(ASCII_LF); + SYSTEM_BUS.print(resultCode); + SYSTEM_BUS.write(ASCII_CR); + SYSTEM_BUS.write(ASCII_LF); } /** @@ -707,14 +707,14 @@ void modem::at_cmd_println() if (cmdAtascii == true) { - SYSTEM_BUS.uart->write(ATASCII_EOL); + SYSTEM_BUS.write(ATASCII_EOL); } else { - SYSTEM_BUS.uart->write(ASCII_CR); - SYSTEM_BUS.uart->write(ASCII_LF); + SYSTEM_BUS.write(ASCII_CR); + SYSTEM_BUS.write(ASCII_LF); } - SYSTEM_BUS.uart->flush(); + SYSTEM_BUS.flush(); fnLedManager.set(LED_BT,false); } @@ -726,20 +726,20 @@ void modem::at_cmd_println(const char *s, bool addEol) fnLedManager.set(LED_BT,true); - SYSTEM_BUS.uart->print(s); + SYSTEM_BUS.print(s); if (addEol) { if (cmdAtascii == true) { - SYSTEM_BUS.uart->write(ATASCII_EOL); + SYSTEM_BUS.write(ATASCII_EOL); } else { - SYSTEM_BUS.uart->write(ASCII_CR); - SYSTEM_BUS.uart->write(ASCII_LF); + SYSTEM_BUS.write(ASCII_CR); + SYSTEM_BUS.write(ASCII_LF); } } - SYSTEM_BUS.uart->flush(); + SYSTEM_BUS.flush(); fnLedManager.set(LED_BT,false); } @@ -751,20 +751,20 @@ void modem::at_cmd_println(int i, bool addEol) fnLedManager.set(LED_BT,true); - SYSTEM_BUS.uart->print(i); + SYSTEM_BUS.print(i); if (addEol) { if (cmdAtascii == true) { - SYSTEM_BUS.uart->write(ATASCII_EOL); + SYSTEM_BUS.write(ATASCII_EOL); } else { - SYSTEM_BUS.uart->write(ASCII_CR); - SYSTEM_BUS.uart->write(ASCII_LF); + SYSTEM_BUS.write(ASCII_CR); + SYSTEM_BUS.write(ASCII_LF); } } - SYSTEM_BUS.uart->flush(); + SYSTEM_BUS.flush(); fnLedManager.set(LED_BT,false); } @@ -776,20 +776,20 @@ void modem::at_cmd_println(std::string s, bool addEol) fnLedManager.set(LED_BT,true); - SYSTEM_BUS.uart->print(s); + SYSTEM_BUS.print(s); if (addEol) { if (cmdAtascii == true) { - SYSTEM_BUS.uart->write(ATASCII_EOL); + SYSTEM_BUS.write(ATASCII_EOL); } else { - SYSTEM_BUS.uart->write(ASCII_CR); - SYSTEM_BUS.uart->write(ASCII_LF); + SYSTEM_BUS.write(ASCII_CR); + SYSTEM_BUS.write(ASCII_LF); } } - SYSTEM_BUS.uart->flush(); + SYSTEM_BUS.flush(); fnLedManager.set(LED_BT,false); } @@ -1066,7 +1066,7 @@ void modem::at_handle_answer() CRX = true; cmdMode = false; - SYSTEM_BUS.uart->flush(); + SYSTEM_BUS.flush(); answerHack = false; } } @@ -1635,11 +1635,11 @@ void modem::sio_handle_modem() // In command mode - don't exchange with TCP but gather characters to a string //if (SIO_UART.available() /*|| blockWritePending == true */ ) - if (SYSTEM_BUS.uart->available() > 0) + if (SYSTEM_BUS.available() > 0) { // get char from Atari SIO //char chr = SIO_UART.read(); - int intchr = SYSTEM_BUS.uart->read(); + int intchr = SYSTEM_BUS.read(); if (intchr < 0) { // read error or timeout @@ -1670,9 +1670,9 @@ void modem::sio_handle_modem() // Clear with a space if (commandEcho == true) { - SYSTEM_BUS.uart->write(ASCII_BACKSPACE); - SYSTEM_BUS.uart->write(' '); - SYSTEM_BUS.uart->write(ASCII_BACKSPACE); + SYSTEM_BUS.write(ASCII_BACKSPACE); + SYSTEM_BUS.write(' '); + SYSTEM_BUS.write(ASCII_BACKSPACE); } } } @@ -1685,7 +1685,7 @@ void modem::sio_handle_modem() { cmd.erase(len - 1); if (commandEcho == true) - SYSTEM_BUS.uart->write(ATASCII_BACKSPACE); + SYSTEM_BUS.write(ATASCII_BACKSPACE); } } // Take into account arrow key movement and clear screen @@ -1693,7 +1693,7 @@ void modem::sio_handle_modem() ((chr >= ATASCII_CURSOR_UP) && (chr <= ATASCII_CURSOR_RIGHT))) { if (commandEcho == true) - SYSTEM_BUS.uart->write(chr); + SYSTEM_BUS.write(chr); } else { @@ -1703,7 +1703,7 @@ void modem::sio_handle_modem() cmd += chr; } if (commandEcho == true) - SYSTEM_BUS.uart->write(chr); + SYSTEM_BUS.write(chr); } } } @@ -1735,14 +1735,14 @@ void modem::sio_handle_modem() } } - int sioBytesAvail = SYSTEM_BUS.uart->available(); - //int sioBytesAvail = std::min(0, SYSTEM_BUS.uart->available()); + int sioBytesAvail = SYSTEM_BUS.available(); + //int sioBytesAvail = std::min(0, SYSTEM_BUS.available()); // send from Atari to Fujinet if (sioBytesAvail && tcpClient.connected()) { fnLedManager.set(eLed::LED_BT,true); - + // In telnet in worst case we have to escape every uint8_t // so leave half of the buffer always free //int max_buf_size; @@ -1753,8 +1753,8 @@ void modem::sio_handle_modem() // Read from serial, the amount available up to // maximum size of the buffer - int sioBytesRead = SYSTEM_BUS.uart->readBytes(&txBuf[0], //SIO_UART.readBytes(&txBuf[0], - (sioBytesAvail > TX_BUF_SIZE) ? TX_BUF_SIZE : sioBytesAvail); + int sioBytesRead = SYSTEM_BUS.read(&txBuf[0], //SIO_UART.readBytes(&txBuf[0], + (sioBytesAvail > TX_BUF_SIZE) ? TX_BUF_SIZE : sioBytesAvail); // Disconnect if going to AT mode with "+++" sequence for (int i = 0; i < (int)sioBytesRead; i++) @@ -1808,12 +1808,12 @@ void modem::sio_handle_modem() } else { - SYSTEM_BUS.uart->write(buf, bytesRead); - SYSTEM_BUS.uart->flush(); + SYSTEM_BUS.write(buf, bytesRead); + SYSTEM_BUS.flush(); } fnLedManager.set(eLed::LED_BT,false); - + // And dump to sniffer, if enabled. modemSniffer->dumpInput(buf, bytesRead); _lasttime = fnSystem.millis(); @@ -1829,7 +1829,7 @@ void modem::sio_handle_modem() Debug_println("Going back to command mode"); at_cmd_println("OK"); - + cmdMode = true; plusCount = 0; diff --git a/lib/device/sio/network.cpp b/lib/device/sio/network.cpp index 0cf160227..cc18eb51d 100755 --- a/lib/device/sio/network.cpp +++ b/lib/device/sio/network.cpp @@ -579,7 +579,7 @@ void sioNetwork::sio_set_prefix() { prefix.clear(); } - else + else { // Append trailing slash if not found if (prefixSpec_str.back() != '/') @@ -997,7 +997,7 @@ bool sioNetwork::instantiate_protocol() { protocolParser = new ProtocolParser(); } - + protocol = protocolParser->createProtocol(urlParser->scheme, receiveBuffer, transmitBuffer, specialBuffer, &login, &password); if (protocol == nullptr) @@ -1154,7 +1154,7 @@ void sioNetwork::sio_assert_interrupt() if (ms - lastInterruptMs >= timerRate) { interruptProceed = !interruptProceed; - fnSioCom.set_proceed(interruptProceed); + SYSTEM_BUS.set_proceed(interruptProceed); lastInterruptMs = ms; } #endif @@ -1166,11 +1166,11 @@ void sioNetwork::sio_assert_interrupt() */ void sioNetwork::sio_clear_interrupt() { - if (interruptProceed) + if (interruptProceed) { // Debug_println("clear interrupt"); interruptProceed = false; - fnSioCom.set_proceed(interruptProceed); + SYSTEM_BUS.set_proceed(interruptProceed); lastInterruptMs = fnSystem.millis(); } } diff --git a/lib/device/sio/pclink.cpp b/lib/device/sio/pclink.cpp index 72ec73742..303016bf2 100644 --- a/lib/device/sio/pclink.cpp +++ b/lib/device/sio/pclink.cpp @@ -5,9 +5,9 @@ * * based on sio2bsd.c version 1.22 * adapted for FujiNet - * + * */ - + #include #include #include @@ -50,118 +50,118 @@ # define SIOTRACE # ifdef SIOTRACE -static int log_flag = 0; /* enable more SIO messages, if 1 */ +static int log_flag = 0; /* enable more SIO messages, if 1 */ # endif # define SDX_MAXLEN 16777215L /* SDX required attribute mask */ -# define RA_PROTECT 0x01 -# define RA_HIDDEN 0x02 -# define RA_ARCHIVED 0x04 -# define RA_SUBDIR 0x08 -# define RA_NO_PROTECT 0x10 -# define RA_NO_HIDDEN 0x20 -# define RA_NO_ARCHIVED 0x40 -# define RA_NO_SUBDIR 0x80 +# define RA_PROTECT 0x01 +# define RA_HIDDEN 0x02 +# define RA_ARCHIVED 0x04 +# define RA_SUBDIR 0x08 +# define RA_NO_PROTECT 0x10 +# define RA_NO_HIDDEN 0x20 +# define RA_NO_ARCHIVED 0x40 +# define RA_NO_SUBDIR 0x80 /* SDX set attribute mask */ -# define SA_PROTECT 0x01 -# define SA_UNPROTECT 0x10 -# define SA_HIDE 0x02 -# define SA_UNHIDE 0x20 -# define SA_ARCHIVE 0x04 -# define SA_UNARCHIVE 0x40 -# define SA_SUBDIR 0x08 /* illegal mode */ -# define SA_UNSUBDIR 0x80 /* illegal mode */ +# define SA_PROTECT 0x01 +# define SA_UNPROTECT 0x10 +# define SA_HIDE 0x02 +# define SA_UNHIDE 0x20 +# define SA_ARCHIVE 0x04 +# define SA_UNARCHIVE 0x40 +# define SA_SUBDIR 0x08 /* illegal mode */ +# define SA_UNSUBDIR 0x80 /* illegal mode */ -# define DEVICE_LABEL ".PCLINK.VOLUME.LABEL" +# define DEVICE_LABEL ".PCLINK.VOLUME.LABEL" -# define PCL_MAX_FNO 0x14 +# define PCL_MAX_FNO 0x14 static const char *fun[] = { - "FREAD", "FWRITE", "FSEEK", "FTELL", "FLEN", "(none)", "FNEXT", "FCLOSE", - "INIT", "FOPEN", "FFIRST", "RENAME", "REMOVE", "CHMOD", "MKDIR", "RMDIR", - "CHDIR", "GETCWD", "SETBOOT", "DFREE", "CHVOL" + "FREAD", "FWRITE", "FSEEK", "FTELL", "FLEN", "(none)", "FNEXT", "FCLOSE", + "INIT", "FOPEN", "FFIRST", "RENAME", "REMOVE", "CHMOD", "MKDIR", "RMDIR", + "CHDIR", "GETCWD", "SETBOOT", "DFREE", "CHVOL" }; /* Atari SIO status block */ typedef struct { - uchar stat; - uchar err; - uchar tmot; - uchar none; + uchar stat; + uchar err; + uchar tmot; + uchar none; } STATUS; -typedef struct /* PCLink parameter buffer */ +typedef struct /* PCLink parameter buffer */ { - uchar fno; /* function number */ - uchar handle; /* file handle */ - uchar f1,f2,f3,f4; /* general-purpose bytes */ - uchar f5,f6; /* more general-purpose bytes */ - uchar fmode; /* fmode */ - uchar fatr1; /* fatr1 */ - uchar fatr2; /* fatr2 */ - uchar name[12]; /* name */ - uchar names[12]; /* names */ - uchar path[65]; /* path */ + uchar fno; /* function number */ + uchar handle; /* file handle */ + uchar f1,f2,f3,f4; /* general-purpose bytes */ + uchar f5,f6; /* more general-purpose bytes */ + uchar fmode; /* fmode */ + uchar fatr1; /* fatr1 */ + uchar fatr2; /* fatr2 */ + uchar name[12]; /* name */ + uchar names[12]; /* names */ + uchar path[65]; /* path */ } PARBUF; typedef struct { - STATUS status; /* the 4-byte status block */ - int on; /* PCLink mount flag */ - char dirname[1024]; /* PCLink root directory path */ - uchar cwd[65]; /* PCLink current working dir, relative to the above */ - PARBUF parbuf; /* PCLink parameter buffer */ + STATUS status; /* the 4-byte status block */ + int on; /* PCLink mount flag */ + char dirname[1024]; /* PCLink root directory path */ + uchar cwd[65]; /* PCLink current working dir, relative to the above */ + PARBUF parbuf; /* PCLink parameter buffer */ } DEVICE; typedef struct { - uchar status; - uchar map_l, map_h; - uchar len_l, len_m, len_h; - char fname[11]; - uchar stamp[6]; + uchar status; + uchar map_l, map_h; + uchar len_l, len_m, len_h; + char fname[11]; + uchar stamp[6]; } DIRENTRY; static struct { - union - { - FILE *file; - DIR *dir; - } fps; - - DIRENTRY *dir_cache; /* used only for directories */ - - uchar devno; - uchar cunit; - uchar fpmode; - uchar fatr1; - uchar fatr2; - uchar t1,t2,t3; - uchar d1,d2,d3; - struct stat fpstat; - char fpname[12]; - long fppos; - long fpread; - int eof; - char pathname[1024]; + union + { + FILE *file; + DIR *dir; + } fps; + + DIRENTRY *dir_cache; /* used only for directories */ + + uchar devno; + uchar cunit; + uchar fpmode; + uchar fatr1; + uchar fatr2; + uchar t1,t2,t3; + uchar d1,d2,d3; + struct stat fpstat; + char fpname[12]; + long fppos; + long fpread; + int eof; + char pathname[1024]; } iodesc[16]; static struct { - uchar handle; - uchar dirbuf[23]; + uchar handle; + uchar dirbuf[23]; } pcl_dbf; //static ulong upper_dir = UPPER_DIR; static ulong upper_dir = 0; -static DEVICE device[16]; /* one PCLINK device with 16 units */ +static DEVICE device[16]; /* one PCLINK device with 16 units */ # define COM_COMD 0 # define COM_DATA 1 @@ -175,43 +175,43 @@ static void pclink_write(uint8_t *buf, int len); static uchar calc_checksum(uchar *buf, int how_much) { - uchar cksum = 0; - ushort nck; - int i; - - for (i = 0; i < how_much; i++) - { - nck = cksum + buf[i]; - cksum = (nck > 0x00ff) ? (nck + 1) : nck; - cksum &= 0x00ff; - } - - return cksum; + uchar cksum = 0; + ushort nck; + int i; + + for (i = 0; i < how_much; i++) + { + nck = cksum + buf[i]; + cksum = (nck > 0x00ff) ? (nck + 1) : nck; + cksum &= 0x00ff; + } + + return cksum; } static void unix_time_2_sdx(time_t *todp, uchar *ob) { - struct tm *t; - uchar yy; + struct tm *t; + uchar yy; - memset(ob, 0, 6); + memset(ob, 0, 6); - if (*todp == 0) - return; + if (*todp == 0) + return; - t = localtime(todp); + t = localtime(todp); - yy = t->tm_year; - while (yy >= 100) - yy-=100; + yy = t->tm_year; + while (yy >= 100) + yy-=100; - ob[0] = t->tm_mday; - ob[1] = t->tm_mon + 1; - ob[2] = yy; - ob[3] = t->tm_hour; - ob[4] = t->tm_min; - ob[5] = t->tm_sec; + ob[0] = t->tm_mday; + ob[1] = t->tm_mon + 1; + ob[2] = yy; + ob[3] = t->tm_hour; + ob[4] = t->tm_min; + ob[5] = t->tm_sec; } static long @@ -219,685 +219,685 @@ dos_2_allowed(uchar c) { //# ifndef __CYGWIN__ #if 1 - if (upper_dir) - return (isupper(c) || isdigit(c) || (c == '_') || (c == '@')); + if (upper_dir) + return (isupper(c) || isdigit(c) || (c == '_') || (c == '@')); - return (islower(c) || isdigit(c) || (c == '_') || (c == '@')); + return (islower(c) || isdigit(c) || (c == '_') || (c == '@')); # else - return (isalpha(c) || isdigit(c) || (c == '_') || (c == '@')); + return (isalpha(c) || isdigit(c) || (c == '_') || (c == '@')); # endif } static long dos_2_term(uchar c) { - return ((c == 0) || (c == 0x20)); + return ((c == 0) || (c == 0x20)); } static long validate_fn(uchar *name, int len) { - int x; - - for (x = 0; x < len; x++) - { - if (dos_2_term(name[x])) - return (x != 0); - if (name[x] == '.') - return 1; - if (!dos_2_allowed(name[x])) - return 0; - } - - return 1; + int x; + + for (x = 0; x < len; x++) + { + if (dos_2_term(name[x])) + return (x != 0); + if (name[x] == '.') + return 1; + if (!dos_2_allowed(name[x])) + return 0; + } + + return 1; } static void ugefina(char *src, char *out) { - char *dot; - ushort i; - - memset(out, 0x20, 8+3); - - dot = strchr(src, '.'); - - if (dot) - { - i = 1; - while (dot[i] && (i < 4)) - { - out[i+7] = toupper((uchar)dot[i]); - i++; - } - } - - i = 0; - while ((src[i] != '.') && !dos_2_term(src[i]) && (i < 8)) - { - out[i] = toupper((uchar)src[i]); - i++; - } + char *dot; + ushort i; + + memset(out, 0x20, 8+3); + + dot = strchr(src, '.'); + + if (dot) + { + i = 1; + while (dot[i] && (i < 4)) + { + out[i+7] = toupper((uchar)dot[i]); + i++; + } + } + + i = 0; + while ((src[i] != '.') && !dos_2_term(src[i]) && (i < 8)) + { + out[i] = toupper((uchar)src[i]); + i++; + } } static void uexpand(uchar *rawname, char *name83) { - ushort x, y; - uchar t; - - name83[0] = 0; - - for (x = 0; x < 8; x++) - { - t = rawname[x]; - if (t && (t != 0x20)) - name83[x] = upper_dir ? toupper(t) : tolower(t); - else - break; - } - - y = 8; - - if (rawname[y] && (rawname[y] != 0x20)) - { - name83[x] = '.'; - x++; - - while ((y < 11) && rawname[y] && (rawname[y] != 0x20)) - { - name83[x] = upper_dir ? toupper(rawname[y]) : tolower(rawname[y]); - x++; - y++; - } - } - - name83[x] = 0; + ushort x, y; + uchar t; + + name83[0] = 0; + + for (x = 0; x < 8; x++) + { + t = rawname[x]; + if (t && (t != 0x20)) + name83[x] = upper_dir ? toupper(t) : tolower(t); + else + break; + } + + y = 8; + + if (rawname[y] && (rawname[y] != 0x20)) + { + name83[x] = '.'; + x++; + + while ((y < 11) && rawname[y] && (rawname[y] != 0x20)) + { + name83[x] = upper_dir ? toupper(rawname[y]) : tolower(rawname[y]); + x++; + y++; + } + } + + name83[x] = 0; } static int match_dos_names(char *name, char *mask, uchar fatr1, struct stat *sb) { - ushort i; - - if (log_flag) - { - Debug_printf("match: %c%c%c%c%c%c%c%c%c%c%c with %c%c%c%c%c%c%c%c%c%c%c: ", - name[0], name[1], name[2], name[3], name[4], name[5], name[6], name[7], \ - name[8], name[9], name[10], \ - mask[0], mask[1], mask[2], mask[3], mask[4], mask[5], mask[6], mask[7], \ - mask[8], mask[9], mask[10]); - } - - for (i = 0; i < 11; i++) - { - if (mask[i] != '?') - if (toupper((uchar)name[i]) != toupper((uchar)mask[i])) - { - if (log_flag) - Debug_printf("no match\n"); - return 1; - } - } - - /* There are no such attributes in Unix */ - fatr1 &= ~(RA_NO_HIDDEN|RA_NO_ARCHIVED); - - /* Now check the attributes */ - if (fatr1 & (RA_HIDDEN | RA_ARCHIVED)) - { - if (log_flag) - Debug_printf("atr mismatch: not HIDDEN or ARCHIVED\n"); - return 1; - } - - if (fatr1 & RA_PROTECT) - { - if (sb->st_mode & (S_IWUSR|S_IWGRP)) - { - if (log_flag) - Debug_printf("atr mismatch: not PROTECTED\n"); - - return 1; - } - } - - if (fatr1 & RA_NO_PROTECT) - { - if ((sb->st_mode & (S_IWUSR|S_IWGRP)) == 0) - { - if (log_flag) - Debug_printf("atr mismatch: not UNPROTECTED\n"); - - return 1; - } - } - - if (fatr1 & RA_SUBDIR) - { - if (!S_ISDIR(sb->st_mode)) - { - if (log_flag) - Debug_printf("atr mismatch: not SUBDIR\n"); - - return 1; - } - } - - if (fatr1 & RA_NO_SUBDIR) - { - if (S_ISDIR(sb->st_mode)) - { - if (log_flag) - Debug_printf("atr mismatch: not FILE\n"); - - return 1; - } - } - - if (log_flag) - Debug_printf("match\n"); - - return 0; + ushort i; + + if (log_flag) + { + Debug_printf("match: %c%c%c%c%c%c%c%c%c%c%c with %c%c%c%c%c%c%c%c%c%c%c: ", + name[0], name[1], name[2], name[3], name[4], name[5], name[6], name[7], \ + name[8], name[9], name[10], \ + mask[0], mask[1], mask[2], mask[3], mask[4], mask[5], mask[6], mask[7], \ + mask[8], mask[9], mask[10]); + } + + for (i = 0; i < 11; i++) + { + if (mask[i] != '?') + if (toupper((uchar)name[i]) != toupper((uchar)mask[i])) + { + if (log_flag) + Debug_printf("no match\n"); + return 1; + } + } + + /* There are no such attributes in Unix */ + fatr1 &= ~(RA_NO_HIDDEN|RA_NO_ARCHIVED); + + /* Now check the attributes */ + if (fatr1 & (RA_HIDDEN | RA_ARCHIVED)) + { + if (log_flag) + Debug_printf("atr mismatch: not HIDDEN or ARCHIVED\n"); + return 1; + } + + if (fatr1 & RA_PROTECT) + { + if (sb->st_mode & (S_IWUSR|S_IWGRP)) + { + if (log_flag) + Debug_printf("atr mismatch: not PROTECTED\n"); + + return 1; + } + } + + if (fatr1 & RA_NO_PROTECT) + { + if ((sb->st_mode & (S_IWUSR|S_IWGRP)) == 0) + { + if (log_flag) + Debug_printf("atr mismatch: not UNPROTECTED\n"); + + return 1; + } + } + + if (fatr1 & RA_SUBDIR) + { + if (!S_ISDIR(sb->st_mode)) + { + if (log_flag) + Debug_printf("atr mismatch: not SUBDIR\n"); + + return 1; + } + } + + if (fatr1 & RA_NO_SUBDIR) + { + if (S_ISDIR(sb->st_mode)) + { + if (log_flag) + Debug_printf("atr mismatch: not FILE\n"); + + return 1; + } + } + + if (log_flag) + Debug_printf("match\n"); + + return 0; } static int validate_dos_name(char *fname) { - char *dot = strchr(fname, '.'); - long valid_fn, valid_xx; - - if ((dot == NULL) && (strlen(fname) > 8)) - return 1; - if (dot) - { - long dd = strlen(dot); - - if (dd > 4) - return 1; - if ((dot - fname) > 8) - return 1; - if ((dot == fname) && (dd == 1)) - return 1; - if ((dd == 2) && (dot[1] == '.')) - return 1; - if ((dd == 3) && ((dot[1] == '.') || (dot[2] == '.'))) - return 1; - if ((dd == 4) && ((dot[1] == '.') || (dot[2] == '.') || (dot[3] == '.'))) - return 1; - } - - valid_fn = validate_fn((uchar *)fname, 8); - if (dot != NULL) - valid_xx = validate_fn((uchar *)(dot + 1), 3); - else - valid_xx = 1; - - if (!valid_fn || !valid_xx) - return 1; - - return 0; + char *dot = strchr(fname, '.'); + long valid_fn, valid_xx; + + if ((dot == NULL) && (strlen(fname) > 8)) + return 1; + if (dot) + { + long dd = strlen(dot); + + if (dd > 4) + return 1; + if ((dot - fname) > 8) + return 1; + if ((dot == fname) && (dd == 1)) + return 1; + if ((dd == 2) && (dot[1] == '.')) + return 1; + if ((dd == 3) && ((dot[1] == '.') || (dot[2] == '.'))) + return 1; + if ((dd == 4) && ((dot[1] == '.') || (dot[2] == '.') || (dot[3] == '.'))) + return 1; + } + + valid_fn = validate_fn((uchar *)fname, 8); + if (dot != NULL) + valid_xx = validate_fn((uchar *)(dot + 1), 3); + else + valid_xx = 1; + + if (!valid_fn || !valid_xx) + return 1; + + return 0; } static int check_dos_name(char *newpath, struct dirent *dp, struct stat *sb) { - char temp_fspec[1024], fname[256]; + char temp_fspec[1024], fname[256]; - strcpy(fname, dp->d_name); + strcpy(fname, dp->d_name); - if (log_flag) - Debug_printf("%s: got fname '%s'\n", __func__, fname); + if (log_flag) + Debug_printf("%s: got fname '%s'\n", __func__, fname); - if (validate_dos_name(fname)) - return 1; + if (validate_dos_name(fname)) + return 1; - /* stat() the file (fetches the length) */ - sprintf(temp_fspec, "%s/%s", newpath, fname); + /* stat() the file (fetches the length) */ + sprintf(temp_fspec, "%s/%s", newpath, fname); - if (log_flag) - Debug_printf("%s: stat '%s'\n", __func__, temp_fspec); + if (log_flag) + Debug_printf("%s: stat '%s'\n", __func__, temp_fspec); - if (stat(temp_fspec, sb)) - { - Debug_printf("cannot stat '%s'\n", temp_fspec); - return 1; - } + if (stat(temp_fspec, sb)) + { + Debug_printf("cannot stat '%s'\n", temp_fspec); + return 1; + } - if (!S_ISREG(sb->st_mode) && !S_ISDIR(sb->st_mode)) - { - Debug_printf("'%s' is not regular file nor directory\n", temp_fspec); - return 1; - } + if (!S_ISREG(sb->st_mode) && !S_ISDIR(sb->st_mode)) + { + Debug_printf("'%s' is not regular file nor directory\n", temp_fspec); + return 1; + } - /*if (sb->st_uid != our_uid) - { - Debug_printf("'%s' wrong uid\n", temp_fspec); - return 1; - }*/ + /*if (sb->st_uid != our_uid) + { + Debug_printf("'%s' wrong uid\n", temp_fspec); + return 1; + }*/ - if ((sb->st_mode & S_IRUSR) == 0) - { - Debug_printf("'%s' is unreadable\n", temp_fspec); - return 1; - } + if ((sb->st_mode & S_IRUSR) == 0) + { + Debug_printf("'%s' is unreadable\n", temp_fspec); + return 1; + } - if (S_ISDIR(sb->st_mode) && ((sb->st_mode & S_IXUSR) == 0)) - { - Debug_printf("dir '%s' is unbrowseable\n", temp_fspec); - return 1; - } + if (S_ISDIR(sb->st_mode) && ((sb->st_mode & S_IXUSR) == 0)) + { + Debug_printf("dir '%s' is unbrowseable\n", temp_fspec); + return 1; + } - return 0; + return 0; } static void fps_close(int i) { - if (iodesc[i].fps.file != NULL) - { - if (iodesc[i].fpmode & 0x10) - closedir(iodesc[i].fps.dir); - else - fclose(iodesc[i].fps.file); - } - - if (iodesc[i].dir_cache != NULL) - { - free(iodesc[i].dir_cache); - iodesc[i].dir_cache = NULL; - } - - iodesc[i].fps.file = NULL; - - iodesc[i].devno = 0; - iodesc[i].cunit = 0; - iodesc[i].fpmode = 0; - iodesc[i].fatr1 = 0; - iodesc[i].fatr2 = 0; - iodesc[i].t1 = 0; - iodesc[i].t2 = 0; - iodesc[i].t3 = 0; - iodesc[i].d1 = 0; - iodesc[i].d2 = 0; - iodesc[i].d3 = 0; - iodesc[i].fpname[0] = 0; - iodesc[i].fppos = 0; - iodesc[i].fpread = 0; - iodesc[i].eof = 0; - iodesc[i].pathname[0] = 0; - memset(&iodesc[i].fpstat, 0, sizeof(struct stat)); + if (iodesc[i].fps.file != NULL) + { + if (iodesc[i].fpmode & 0x10) + closedir(iodesc[i].fps.dir); + else + fclose(iodesc[i].fps.file); + } + + if (iodesc[i].dir_cache != NULL) + { + free(iodesc[i].dir_cache); + iodesc[i].dir_cache = NULL; + } + + iodesc[i].fps.file = NULL; + + iodesc[i].devno = 0; + iodesc[i].cunit = 0; + iodesc[i].fpmode = 0; + iodesc[i].fatr1 = 0; + iodesc[i].fatr2 = 0; + iodesc[i].t1 = 0; + iodesc[i].t2 = 0; + iodesc[i].t3 = 0; + iodesc[i].d1 = 0; + iodesc[i].d2 = 0; + iodesc[i].d3 = 0; + iodesc[i].fpname[0] = 0; + iodesc[i].fppos = 0; + iodesc[i].fpread = 0; + iodesc[i].eof = 0; + iodesc[i].pathname[0] = 0; + memset(&iodesc[i].fpstat, 0, sizeof(struct stat)); } static ulong get_file_len(uchar handle) { - ulong filelen; - struct dirent *dp; - struct stat sb; - - if (iodesc[handle].fpmode & 0x10) /* directory */ - { - rewinddir(iodesc[handle].fps.dir); - filelen = sizeof(DIRENTRY); - - while ((dp = readdir(iodesc[handle].fps.dir)) != NULL) - { - if (check_dos_name(iodesc[handle].pathname, dp, &sb)) - continue; - filelen += sizeof(DIRENTRY); - } - rewinddir(iodesc[handle].fps.dir); - } - else - filelen = iodesc[handle].fpstat.st_size; - - if (filelen > SDX_MAXLEN) - filelen = SDX_MAXLEN; - - return filelen; + ulong filelen; + struct dirent *dp; + struct stat sb; + + if (iodesc[handle].fpmode & 0x10) /* directory */ + { + rewinddir(iodesc[handle].fps.dir); + filelen = sizeof(DIRENTRY); + + while ((dp = readdir(iodesc[handle].fps.dir)) != NULL) + { + if (check_dos_name(iodesc[handle].pathname, dp, &sb)) + continue; + filelen += sizeof(DIRENTRY); + } + rewinddir(iodesc[handle].fps.dir); + } + else + filelen = iodesc[handle].fpstat.st_size; + + if (filelen > SDX_MAXLEN) + filelen = SDX_MAXLEN; + + return filelen; } static DIRENTRY * cache_dir(uchar handle) { - char *bs, *cwd; - uchar dirnode = 0x00; - ushort node; - ulong dlen, flen, sl, dirlen = iodesc[handle].fpstat.st_size; - DIRENTRY *dbuf, *dir; - struct dirent *dp; - struct stat sb; - - if (iodesc[handle].dir_cache != NULL) - { - Debug_printf("Internal error: dir_cache should be NULL!\n"); - //sig(0); - } + char *bs, *cwd; + uchar dirnode = 0x00; + ushort node; + ulong dlen, flen, sl, dirlen = iodesc[handle].fpstat.st_size; + DIRENTRY *dbuf, *dir; + struct dirent *dp; + struct stat sb; + + if (iodesc[handle].dir_cache != NULL) + { + Debug_printf("Internal error: dir_cache should be NULL!\n"); + //sig(0); + } - dir = dbuf = (DIRENTRY*)malloc(dirlen + sizeof(DIRENTRY)); - memset(dbuf, 0, dirlen + sizeof(DIRENTRY)); + dir = dbuf = (DIRENTRY*)malloc(dirlen + sizeof(DIRENTRY)); + memset(dbuf, 0, dirlen + sizeof(DIRENTRY)); - dir->status = 0x28; - dir->map_l = 0x00; /* low 11 bits: file number, high 5 bits: dir number */ - dir->map_h = dirnode; - dir->len_l = dirlen & 0x000000ffL; - dir->len_m = (dirlen & 0x0000ff00L) >> 8; - dir->len_h = (dirlen & 0x00ff0000L) >> 16; + dir->status = 0x28; + dir->map_l = 0x00; /* low 11 bits: file number, high 5 bits: dir number */ + dir->map_h = dirnode; + dir->len_l = dirlen & 0x000000ffL; + dir->len_m = (dirlen & 0x0000ff00L) >> 8; + dir->len_h = (dirlen & 0x00ff0000L) >> 16; - memset(dir->fname, 0x20, 11); + memset(dir->fname, 0x20, 11); - sl = strlen(device[iodesc[handle].cunit].dirname); + sl = strlen(device[iodesc[handle].cunit].dirname); - cwd = iodesc[handle].pathname + sl; + cwd = iodesc[handle].pathname + sl; - bs = strrchr(cwd, '/'); + bs = strrchr(cwd, '/'); - if (bs == NULL) - memcpy(dir->fname, "MAIN", 4); - else - { - char *cp = cwd; + if (bs == NULL) + memcpy(dir->fname, "MAIN", 4); + else + { + char *cp = cwd; - ugefina(bs+1, (char *)dir->fname); + ugefina(bs+1, (char *)dir->fname); - node = 0; + node = 0; - while (cp <= bs) - { - if (*cp == '/') - dirnode++; - cp++; - } + while (cp <= bs) + { + if (*cp == '/') + dirnode++; + cp++; + } - dir->map_h = (dirnode & 0x1f) << 3; - } + dir->map_h = (dirnode & 0x1f) << 3; + } - unix_time_2_sdx(&iodesc[handle].fpstat.st_mtime, dir->stamp); + unix_time_2_sdx(&iodesc[handle].fpstat.st_mtime, dir->stamp); - dir++; - flen = sizeof(DIRENTRY); + dir++; + flen = sizeof(DIRENTRY); - node = 1; + node = 1; - while ((dp = readdir(iodesc[handle].fps.dir)) != NULL) - { - ushort map; + while ((dp = readdir(iodesc[handle].fps.dir)) != NULL) + { + ushort map; - if (check_dos_name(iodesc[handle].pathname, dp, &sb)) - continue; + if (check_dos_name(iodesc[handle].pathname, dp, &sb)) + continue; - dlen = sb.st_size; - if (dlen > SDX_MAXLEN) - dlen = SDX_MAXLEN; + dlen = sb.st_size; + if (dlen > SDX_MAXLEN) + dlen = SDX_MAXLEN; - dir->status = (sb.st_mode & (S_IWUSR|S_IWGRP)) ? 0x08 : 0x09; + dir->status = (sb.st_mode & (S_IWUSR|S_IWGRP)) ? 0x08 : 0x09; - if (S_ISDIR(sb.st_mode)) - { - dir->status |= 0x20; /* directory */ - dlen = sizeof(DIRENTRY); - } + if (S_ISDIR(sb.st_mode)) + { + dir->status |= 0x20; /* directory */ + dlen = sizeof(DIRENTRY); + } - map = dirnode << 11; - map |= (node & 0x07ff); + map = dirnode << 11; + map |= (node & 0x07ff); - dir->map_l = map & 0x00ff; - dir->map_h = ((map & 0xff00) >> 8); - dir->len_l = dlen & 0x000000ffL; - dir->len_m = (dlen & 0x0000ff00L) >> 8; - dir->len_h = (dlen & 0x00ff0000L) >> 16; + dir->map_l = map & 0x00ff; + dir->map_h = ((map & 0xff00) >> 8); + dir->len_l = dlen & 0x000000ffL; + dir->len_m = (dlen & 0x0000ff00L) >> 8; + dir->len_h = (dlen & 0x00ff0000L) >> 16; - ugefina(dp->d_name, (char *)dir->fname); + ugefina(dp->d_name, (char *)dir->fname); - unix_time_2_sdx(&sb.st_mtime, dir->stamp); + unix_time_2_sdx(&sb.st_mtime, dir->stamp); - node++; - dir++; - flen += sizeof(DIRENTRY); + node++; + dir++; + flen += sizeof(DIRENTRY); - if (flen >= dirlen) - break; - } + if (flen >= dirlen) + break; + } - return dbuf; + return dbuf; } static ulong dir_read(uchar *mem, ulong blk_size, uchar handle, int *eof_sig) { - uchar *db = (uchar *)iodesc[handle].dir_cache; - ulong dirlen = iodesc[handle].fpstat.st_size, newblk; + uchar *db = (uchar *)iodesc[handle].dir_cache; + ulong dirlen = iodesc[handle].fpstat.st_size, newblk; - eof_sig[0] = 0; + eof_sig[0] = 0; - newblk = dirlen - iodesc[handle].fppos; + newblk = dirlen - iodesc[handle].fppos; - if (newblk < blk_size) - { - blk_size = newblk; - eof_sig[0] = 1; - } + if (newblk < blk_size) + { + blk_size = newblk; + eof_sig[0] = 1; + } - if (blk_size) - memcpy(mem, db+iodesc[handle].fppos, blk_size); + if (blk_size) + memcpy(mem, db+iodesc[handle].fppos, blk_size); - return blk_size; + return blk_size; } static void do_pclink_init(int server_cold_start) { - uchar handle; - - if (server_cold_start == 0) - Debug_printf("closing all files\n"); - - for (handle = 0; handle < 16; handle++) - { - if (server_cold_start) - iodesc[handle].fps.file = NULL; - fps_close(handle); - memset(&device[handle].parbuf, 0, sizeof(PARBUF)); - } - - if (server_cold_start) - { - int unit; - - for (unit = 0; unit < 16; unit++) - { - device[unit].status.stat = 0; - device[unit].status.err = 1; - device[unit].status.tmot = 0; - device[unit].status.none = SIO_DEVICEID_PCLINK; - } - } + uchar handle; + + if (server_cold_start == 0) + Debug_printf("closing all files\n"); + + for (handle = 0; handle < 16; handle++) + { + if (server_cold_start) + iodesc[handle].fps.file = NULL; + fps_close(handle); + memset(&device[handle].parbuf, 0, sizeof(PARBUF)); + } + + if (server_cold_start) + { + int unit; + + for (unit = 0; unit < 16; unit++) + { + device[unit].status.stat = 0; + device[unit].status.err = 1; + device[unit].status.tmot = 0; + device[unit].status.none = SIO_DEVICEID_PCLINK; + } + } } static void set_status_size(uchar devno, uchar cunit, ushort size) { - device[cunit].status.tmot = (size & 0x00ff); - device[cunit].status.none = (size & 0xff00) >> 8; + device[cunit].status.tmot = (size & 0x00ff); + device[cunit].status.none = (size & 0xff00) >> 8; } #ifdef ESP_PLATFORM static int validate_user_path(char *defwd, char *newpath) { - char *d; - struct stat st; - - d = strstr(newpath, defwd); - if (d == NULL || d != newpath) - return 0; - d = newpath + strlen(defwd); - if (*d != '\0' && *d != '/') - return 0; - - if (stat(newpath, &st) < 0) - return 0; - if (!S_ISDIR(st.st_mode)) - return 0; - - return 1; + char *d; + struct stat st; + + d = strstr(newpath, defwd); + if (d == NULL || d != newpath) + return 0; + d = newpath + strlen(defwd); + if (*d != '\0' && *d != '/') + return 0; + + if (stat(newpath, &st) < 0) + return 0; + if (!S_ISDIR(st.st_mode)) + return 0; + + return 1; } #else static int validate_user_path(char *defwd, char *newpath) { - char *d, oldwd[1024], newwd[1024]; + char *d, oldwd[1024], newwd[1024]; - (void)getcwd(oldwd, sizeof(oldwd)); - if (chdir(newpath) < 0) - return 0; - (void)getcwd(newwd, sizeof(newwd)); - (void)chdir(oldwd); + (void)getcwd(oldwd, sizeof(oldwd)); + if (chdir(newpath) < 0) + return 0; + (void)getcwd(newwd, sizeof(newwd)); + (void)chdir(oldwd); - d = strstr(newwd, defwd); + d = strstr(newwd, defwd); - if (d == NULL) - return 0; - if (d != newwd) - return 0; + if (d == NULL) + return 0; + if (d != newwd) + return 0; - return 1; + return 1; } static int abs_path(const char *path, char *abspath, int size) { - char oldwd[1024]; + char oldwd[1024]; char *cwd; - if (getcwd(oldwd, sizeof(oldwd)) == NULL) + if (getcwd(oldwd, sizeof(oldwd)) == NULL) return 0; - if (chdir(path) < 0) - return 0; - cwd = getcwd(abspath, size); - if (chdir(oldwd) < 0 || cwd == NULL) + if (chdir(path) < 0) + return 0; + cwd = getcwd(abspath, size); + if (chdir(oldwd) < 0 || cwd == NULL) return 0; - return 1; + return 1; } #endif static int ispathsep(uchar c) { - return ((c == '>') || (c == '\\')); + return ((c == '>') || (c == '\\')); } static void path_copy(uchar *dst, uchar *src) { - uchar a; - - while (*src) - { - a = *src; - if (ispathsep(a)) - { - while (ispathsep(*src)) - src++; - src--; - } - *dst = a; - src++; - dst++; - } - - *dst = 0; + uchar a; + + while (*src) + { + a = *src; + if (ispathsep(a)) + { + while (ispathsep(*src)) + src++; + src--; + } + *dst = a; + src++; + dst++; + } + + *dst = 0; } static void path2unix(uchar *out, uchar *path) { - int i, y = 0; + int i, y = 0; - for (i = 0; path[i] && (i < 64); i++) - { - char a; - - a = upper_dir ? toupper(path[i]) : tolower(path[i]); - - if (ispathsep(a)) - a = '/'; - else if (a == '<') - { - a = '.'; - out[y++] = '.'; - } - out[y++] = a; - } + for (i = 0; path[i] && (i < 64); i++) + { + char a; + + a = upper_dir ? toupper(path[i]) : tolower(path[i]); + + if (ispathsep(a)) + a = '/'; + else if (a == '<') + { + a = '.'; + out[y++] = '.'; + } + out[y++] = a; + } - if (y && (out[y-1] != '/')) - out[y++] = '/'; + if (y && (out[y-1] != '/')) + out[y++] = '/'; - out[y] = 0; + out[y] = 0; } static void create_user_path(uchar devno, uchar cunit, char *newpath) { - long sl, cwdo = 0; - uchar lpath[128], upath[128]; - - strcpy(newpath, device[cunit].dirname); - - /* this is user-requested new path */ - path_copy(lpath, device[cunit].parbuf.path); - path2unix(upath, lpath); - - if (upath[0] != '/') - { - sl = strlen(newpath); - if (sl && (newpath[sl-1] != '/')) - strcat(newpath, "/"); - if (device[cunit].cwd[0] == '/') - cwdo++; - strcat(newpath, (char *)device[cunit].cwd + cwdo); - sl = strlen(newpath); - if (sl && (newpath[sl-1] != '/')) - strcat(newpath, "/"); - } - strcat(newpath, (char *)upath); - sl = strlen(newpath); - // resolve ".." and "." - strcpy(newpath, util_get_canonical_path(std::string(newpath)).c_str()); - sl = strlen(newpath); - if (sl && (newpath[sl-1] == '/')) - newpath[sl-1] = 0; + long sl, cwdo = 0; + uchar lpath[128], upath[128]; + + strcpy(newpath, device[cunit].dirname); + + /* this is user-requested new path */ + path_copy(lpath, device[cunit].parbuf.path); + path2unix(upath, lpath); + + if (upath[0] != '/') + { + sl = strlen(newpath); + if (sl && (newpath[sl-1] != '/')) + strcat(newpath, "/"); + if (device[cunit].cwd[0] == '/') + cwdo++; + strcat(newpath, (char *)device[cunit].cwd + cwdo); + sl = strlen(newpath); + if (sl && (newpath[sl-1] != '/')) + strcat(newpath, "/"); + } + strcat(newpath, (char *)upath); + sl = strlen(newpath); + // resolve ".." and "." + strcpy(newpath, util_get_canonical_path(std::string(newpath)).c_str()); + sl = strlen(newpath); + if (sl && (newpath[sl-1] == '/')) + newpath[sl-1] = 0; } static time_t timestamp2mtime(uchar *stamp) { - struct tm sdx_tm; + struct tm sdx_tm; - memset(&sdx_tm, 0, sizeof(struct tm)); + memset(&sdx_tm, 0, sizeof(struct tm)); - sdx_tm.tm_sec = stamp[5]; - sdx_tm.tm_min = stamp[4]; - sdx_tm.tm_hour = stamp[3]; - sdx_tm.tm_mday = stamp[0]; - sdx_tm.tm_mon = stamp[1]; - sdx_tm.tm_year = stamp[2]; + sdx_tm.tm_sec = stamp[5]; + sdx_tm.tm_min = stamp[4]; + sdx_tm.tm_hour = stamp[3]; + sdx_tm.tm_mday = stamp[0]; + sdx_tm.tm_mon = stamp[1]; + sdx_tm.tm_year = stamp[2]; - if ((sdx_tm.tm_mday == 0) || (sdx_tm.tm_mon == 0)) - return 0; + if ((sdx_tm.tm_mday == 0) || (sdx_tm.tm_mon == 0)) + return 0; - if (sdx_tm.tm_mon) - sdx_tm.tm_mon--; + if (sdx_tm.tm_mon) + sdx_tm.tm_mon--; - if (sdx_tm.tm_year < 80) - sdx_tm.tm_year += 2000; - else - sdx_tm.tm_year += 1900; + if (sdx_tm.tm_year < 80) + sdx_tm.tm_year += 2000; + else + sdx_tm.tm_year += 1900; - sdx_tm.tm_year -= 1900; + sdx_tm.tm_year -= 1900; - return mktime(&sdx_tm); + return mktime(&sdx_tm); } /* Command: DDEVIC+DUNIT-1 = $6f, DAUX1 = parbuf size, DAUX2 = %vvvvuuuu @@ -907,48 +907,48 @@ timestamp2mtime(uchar *stamp) static void do_pclink(uchar devno, uchar ccom, uchar caux1, uchar caux2) { - uchar ck, sck, fno, ob[7], handle; - ushort cunit = caux2 & 0x0f, parsize; - ulong faux; - struct stat sb; - struct dirent *dp; - static uchar old_ccom = 0; - - if (caux2 & 0xf0) /* protocol version number must be 0 */ - { - pclink_ack(devno, cunit, 'N'); - return; - } + uchar ck, sck, fno, ob[7], handle; + ushort cunit = caux2 & 0x0f, parsize; + ulong faux; + struct stat sb; + struct dirent *dp; + static uchar old_ccom = 0; + + if (caux2 & 0xf0) /* protocol version number must be 0 */ + { + pclink_ack(devno, cunit, 'N'); + return; + } - parsize = caux1 ? caux1 : 256; + parsize = caux1 ? caux1 : 256; - if (parsize > (ushort)sizeof(PARBUF)) /* and not more than fits in parbuf */ - { - pclink_ack(devno, cunit, 'N'); - return; - } + if (parsize > (ushort)sizeof(PARBUF)) /* and not more than fits in parbuf */ + { + pclink_ack(devno, cunit, 'N'); + return; + } - if (ccom == 'P') - { - PARBUF pbuf; + if (ccom == 'P') + { + PARBUF pbuf; - pclink_ack(devno, cunit, 'a'); /* ack the command (late_ack) */ + pclink_ack(devno, cunit, 'a'); /* ack the command (late_ack) */ - memset(&pbuf, 0, sizeof(PARBUF)); - sck = pclink_read((uchar *)&pbuf, (int)parsize); // read data + checksum byte - ck = calc_checksum((uchar *)&pbuf, (int)parsize); // calculate checksum from data + memset(&pbuf, 0, sizeof(PARBUF)); + sck = pclink_read((uchar *)&pbuf, (int)parsize); // read data + checksum byte + ck = calc_checksum((uchar *)&pbuf, (int)parsize); // calculate checksum from data - device[cunit].status.stat &= ~0x02; + device[cunit].status.stat &= ~0x02; - pclink_ack(devno, cunit, 'A'); /* ack the received block */ + pclink_ack(devno, cunit, 'A'); /* ack the received block */ - if (ck != sck) - { - device[cunit].status.stat |= 0x02; - Debug_printf("PARBLK CRC error, Atari: $%02x, PC: $%02x\n", sck, ck); - device[cunit].status.err = 143; - goto complete; - } + if (ck != sck) + { + device[cunit].status.stat |= 0x02; + Debug_printf("PARBLK CRC error, Atari: $%02x, PC: $%02x\n", sck, ck); + device[cunit].status.err = 143; + goto complete; + } Debug_printf("PARBLK size %d, dump: ", (int)parsize); { @@ -964,1527 +964,1527 @@ do_pclink(uchar devno, uchar ccom, uchar caux1, uchar caux2) #endif } - device[cunit].status.stat &= ~0x04; + device[cunit].status.stat &= ~0x04; # if 0 - /* True if Atari didn't catch the ACK above and retried the command */ - if (pbuf.fno > PCL_MAX_FNO) - { - device[cunit].status.stat |= 0x04; - Debug_printf("PARBLK error, invalid fno $%02x\n", pbuf.fno); - device[cunit].status.err = 144; - goto complete; - } + /* True if Atari didn't catch the ACK above and retried the command */ + if (pbuf.fno > PCL_MAX_FNO) + { + device[cunit].status.stat |= 0x04; + Debug_printf("PARBLK error, invalid fno $%02x\n", pbuf.fno); + device[cunit].status.err = 144; + goto complete; + } # endif - if (memcmp(&pbuf, &device[cunit].parbuf, sizeof(PARBUF)) == 0) - { - /* this is a retry of P-block. Most commands don't like that */ - if ((pbuf.fno != 0x00) && (pbuf.fno != 0x01) && (pbuf.fno != 0x03) \ - && (pbuf.fno != 0x04) && (pbuf.fno != 0x06) && \ - (pbuf.fno != 0x11) && (pbuf.fno != 0x13)) - { - Debug_printf("PARBLK retry, ignored\n"); - goto complete; - } - } - - memcpy(&device[cunit].parbuf, &pbuf, sizeof(PARBUF)); - } - -// device[cunit].status.err = 1; -// set_status_size(devno, cunit, 0); - - fno = device[cunit].parbuf.fno; - faux = device[cunit].parbuf.f1 + device[cunit].parbuf.f2 * 256 + \ - device[cunit].parbuf.f3 * 65536; - - if (fno < (PCL_MAX_FNO+1)) - Debug_printf("%s (fno $%02x):\n", fun[fno], fno); - - handle = device[cunit].parbuf.handle; - - if (fno == 0x00) /* FREAD */ - { - uchar *mem; - ulong blk_size = (faux & 0x0000FFFFL), buffer; - - if (ccom == 'P') - { - if ((handle > 15) || (iodesc[handle].fps.file == NULL)) - { - Debug_printf("bad handle %d\n", handle); - device[cunit].status.err = 134; /* bad file handle */ - goto complete; - } - - if (blk_size == 0) - { - Debug_printf("bad size $0000 (0)\n"); - device[cunit].status.err = 176; - set_status_size(devno, cunit, 0); - goto complete; - } - - device[cunit].status.err = 1; - iodesc[handle].eof = 0; - - buffer = iodesc[handle].fpstat.st_size - iodesc[handle].fppos; - - if (buffer < blk_size) - { - blk_size = buffer; - device[cunit].parbuf.f1 = (buffer & 0x00ff); - device[cunit].parbuf.f2 = (buffer & 0xff00) >> 8; - iodesc[handle].eof = 1; - if (blk_size == 0) - device[cunit].status.err = 136; - } - - Debug_printf("size $%04lx (%ld), buffer $%04lx (%ld)\n", blk_size, blk_size, buffer, buffer); - - set_status_size(devno, cunit, (ushort)blk_size); - goto complete; - } - - if ((ccom == 'R') && (old_ccom == 'R')) - { - pclink_ack(devno, cunit, 'N'); - Debug_printf("serial communication error, abort\n"); - fps_close(handle); - return; - } - - pclink_ack(devno, cunit, 'A'); /* ack the command */ - - Debug_printf("handle %d\n", handle); - - //mem = (uchar*)malloc(blk_size + 1); - mem = (uchar*)malloc(blk_size); - - if (device[cunit].status.err == 1) - { - iodesc[handle].fpread = blk_size; - - if (iodesc[handle].fpmode & 0x10) - { - ulong rdata; - int eof_sig; - - rdata = dir_read(mem, blk_size, handle, &eof_sig); - - if (rdata != blk_size) - { - Debug_printf("FREAD: cannot read %ld bytes from dir\n", blk_size); - if (eof_sig) - { - iodesc[handle].fpread = rdata; - device[cunit].status.err = 136; - } - else - { - iodesc[handle].fpread = 0; - device[cunit].status.err = 255; - } - } - } - else - { - if (fseek(iodesc[handle].fps.file, iodesc[handle].fppos, SEEK_SET)) - { - Debug_printf("FREAD: cannot seek to $%04lx (%ld)\n", iodesc[handle].fppos, iodesc[handle].fppos); - device[cunit].status.err = 166; - } - else - { - long fdata = fread(mem, sizeof(char), blk_size, iodesc[handle].fps.file); - - if ((ulong)fdata != blk_size) - { - Debug_printf("FREAD: cannot read %ld bytes from file\n", blk_size); - if (feof(iodesc[handle].fps.file)) - { - iodesc[handle].fpread = fdata; - device[cunit].status.err = 136; - } - else - { - iodesc[handle].fpread = 0; - device[cunit].status.err = 255; - } - } - } - } - } - - iodesc[handle].fppos += iodesc[handle].fpread; - - if (device[cunit].status.err == 1) - { - if (iodesc[handle].eof) - device[cunit].status.err = 136; - else if (iodesc[handle].fppos == iodesc[handle].fpstat.st_size) - device[cunit].status.err = 3; - } - - set_status_size(devno, cunit, iodesc[handle].fpread); - - Debug_printf("FREAD: send $%04lx (%ld), status $%02x\n", blk_size, blk_size, device[cunit].status.err); - - //sck = calc_checksum(mem, blk_size); - //mem[blk_size] = sck; - pclink_ack(devno, cunit, 'C'); - //com_write(mem, blk_size + 1); - pclink_write(mem, blk_size); // write data + checksum byte - - free(mem); - - goto exit; - } - - if (fno == 0x01) /* FWRITE */ - { - uchar *mem; - ulong blk_size = (faux & 0x0000FFFFL); - - if (ccom == 'P') - { - if ((handle > 15) || (iodesc[handle].fps.file == NULL)) - { - Debug_printf("bad handle %d\n", handle); - device[cunit].status.err = 134; /* bad file handle */ - goto complete; - } - - if (blk_size == 0) - { - Debug_printf("bad size $0000 (0)\n"); - device[cunit].status.err = 176; - set_status_size(devno, cunit, 0); - goto complete; - } - - device[cunit].status.err = 1; - - Debug_printf("size $%04lx (%ld)\n", blk_size, blk_size); - set_status_size(devno, cunit, (ushort)blk_size); - goto complete; - } - - if ((ccom == 'R') && (old_ccom == 'R')) - { - pclink_ack(devno, cunit, 'N'); - Debug_printf("serial communication error, abort\n"); - return; - } - - pclink_ack(devno, cunit, 'a'); /* ack the command (late_ack) */ - - Debug_printf("handle %d\n", handle); - - if ((iodesc[handle].fpmode & 0x10) == 0) - { - if (fseek(iodesc[handle].fps.file, iodesc[handle].fppos, SEEK_SET)) - { - Debug_printf("FWRITE: cannot seek to $%06lx (%ld)\n", iodesc[handle].fppos, iodesc[handle].fppos); - device[cunit].status.err = 166; - } - } - - //mem = (uchar*)malloc(blk_size + 1); - mem = (uchar*)malloc(blk_size); - - sck = pclink_read(mem, blk_size); // read data + checksum byte - ck = calc_checksum(mem, blk_size); // calculate checksum from data - - pclink_ack(devno, cunit, 'A'); /* ack the block of data */ - - if (ck != sck) - { - Debug_printf("FWRITE: block CRC mismatch (sent $%02x, calculated $%02x)\n", sck, ck); - device[cunit].status.err = 143; - free(mem); - goto complete; - } - - if (device[cunit].status.err == 1) - { - long rdata; - - iodesc[handle].fpread = blk_size; - - if (iodesc[handle].fpmode & 0x10) - { - /* ignore raw dir writes */ - } - else - { - rdata = fwrite(mem, sizeof(char), blk_size, iodesc[handle].fps.file); - - if ((ulong)rdata != blk_size) - { - Debug_printf("FWRITE: cannot write %ld bytes to file\n", blk_size); - iodesc[handle].fpread = rdata; - device[cunit].status.err = 255; - } - } - } - - iodesc[handle].fppos += iodesc[handle].fpread; - - set_status_size(devno, cunit, iodesc[handle].fpread); - - Debug_printf("FWRITE: received $%04lx (%ld), status $%02x\n", blk_size, blk_size, device[cunit].status.err); - - free(mem); - goto complete; - } - - if (fno == 0x02) /* FSEEK */ - { - ulong newpos = faux; - - if ((handle > 15) || (iodesc[handle].fps.file == NULL)) - { - Debug_printf("bad handle %d\n", handle); - device[cunit].status.err = 134; /* bad file handle */ - goto complete; - } - - if (ccom == 'R') - { - pclink_ack(devno, cunit, 'A'); /* ack the command */ - Debug_printf("bad exec\n"); - device[cunit].status.err = 176; - goto complete; - } - - device[cunit].status.err = 1; - - Debug_printf("handle %d, newpos $%06lx (%ld)\n", handle, newpos, newpos); - - if (iodesc[handle].fpmode & 0x08) - iodesc[handle].fppos = newpos; - else - { - if ((off_t)newpos <= iodesc[handle].fpstat.st_size) - iodesc[handle].fppos = newpos; - else - device[cunit].status.err = 166; - } - - goto complete; - } - - if ((fno == 0x03) || (fno == 0x04)) /* FTELL/FLEN */ - { - ulong outval = 0; - //uchar out[4]; - uchar out[3]; - - if (ccom == 'P') - { - if ((handle > 15) || (iodesc[handle].fps.file == NULL)) - { - Debug_printf("bad handle %d\n", handle); - device[cunit].status.err = 134; /* bad file handle */ - goto complete; - } - - device[cunit].status.err = 1; - - Debug_printf("device $%02x\n", cunit); - goto complete; - } - - pclink_ack(devno, cunit, 'A'); /* ack the command */ - - if (fno == 0x03) - outval = iodesc[handle].fppos; - else - outval = iodesc[handle].fpstat.st_size; - - Debug_printf("handle %d, send $%06lx (%ld)\n", handle, outval, outval); - - out[0] = (uchar)(outval & 0x000000ffL); - out[1] = (uchar)((outval & 0x0000ff00L) >> 8); - out[2] = (uchar)((outval & 0x00ff0000L) >> 16); - - //out[3] = calc_checksum(out, sizeof(out)-1); - pclink_ack(devno, cunit, 'C'); - //com_write(out, sizeof(out)); - pclink_write(out, sizeof(out)); // write data + checksum byte - - goto exit; - } - - if (fno == 0x06) /* FNEXT */ - { - if (ccom == 'P') - { - device[cunit].status.err = 1; - - Debug_printf("device $%02x\n", cunit); - goto complete; - } - - if ((ccom == 'R') && (old_ccom == 'R')) - { - pclink_ack(devno, cunit, 'N'); - Debug_printf("serial communication error, abort\n"); - return; - } - - pclink_ack(devno, cunit, 'A'); /* ack the command */ - - memset(pcl_dbf.dirbuf, 0, sizeof(pcl_dbf.dirbuf)); - - if ((handle > 15) || (iodesc[handle].fps.file == NULL)) - { - Debug_printf("bad handle %d\n", handle); - device[cunit].status.err = 134; /* bad file handle */ - } - else - { - int eof_flg, match = 0; - - Debug_printf("handle %d\n", handle); - - do - { - struct stat ts; - - memset(&ts, 0, sizeof(ts)); - memset(pcl_dbf.dirbuf, 0, sizeof(pcl_dbf.dirbuf)); - iodesc[handle].fppos += dir_read(pcl_dbf.dirbuf, sizeof(pcl_dbf.dirbuf), handle, &eof_flg); - - if (!eof_flg) - { - /* fake stat to satisfy match_dos_names() */ - if ((pcl_dbf.dirbuf[0] & 0x01) == 0) - ts.st_mode |= (S_IWUSR|S_IWGRP); - if (pcl_dbf.dirbuf[0] & 0x20) - ts.st_mode |= S_IFDIR; - else - ts.st_mode |= S_IFREG; - - match = !match_dos_names((char *)pcl_dbf.dirbuf+6, iodesc[handle].fpname, iodesc[handle].fatr1, &ts); - } - - } while (!eof_flg && !match); - - if (eof_flg) - { - Debug_printf("FNEXT: EOF\n"); - device[cunit].status.err = 136; - } - else if (iodesc[handle].fppos == iodesc[handle].fpstat.st_size) - device[cunit].status.err = 3; - } - - /* avoid the 4th execution stage */ - pcl_dbf.handle = device[cunit].status.err; - - Debug_printf("FNEXT: status %d, send $%02x $%02x%02x $%02x%02x%02x %c%c%c%c%c%c%c%c%c%c%c %02d-%02d-%02d %02d:%02d:%02d\n", \ - pcl_dbf.handle, - pcl_dbf.dirbuf[0], - pcl_dbf.dirbuf[2], pcl_dbf.dirbuf[1], - pcl_dbf.dirbuf[5], pcl_dbf.dirbuf[4], pcl_dbf.dirbuf[3], - pcl_dbf.dirbuf[6], pcl_dbf.dirbuf[7], pcl_dbf.dirbuf[8], pcl_dbf.dirbuf[9], - pcl_dbf.dirbuf[10], pcl_dbf.dirbuf[11], pcl_dbf.dirbuf[12], pcl_dbf.dirbuf[13], - pcl_dbf.dirbuf[14], pcl_dbf.dirbuf[15], pcl_dbf.dirbuf[16], - pcl_dbf.dirbuf[17], pcl_dbf.dirbuf[18], pcl_dbf.dirbuf[19], - pcl_dbf.dirbuf[20], pcl_dbf.dirbuf[21], pcl_dbf.dirbuf[22]); - - //sck = calc_checksum((uchar *)&pcl_dbf, sizeof(pcl_dbf)); - pclink_ack(devno, cunit, 'C'); - //com_write((uchar *)&pcl_dbf, sizeof(pcl_dbf)); - //com_write(&sck, 1); - pclink_write((uchar *)&pcl_dbf, sizeof(pcl_dbf)); // write data + checksum byte - - goto exit; - } - - if (fno == 0x07) /* FCLOSE */ - { - uchar fpmode; - time_t mtime; - char pathname[1024]; - - if (ccom == 'R') - { - pclink_ack(devno, cunit, 'A'); /* ack the command */ - device[cunit].status.err = 176; - Debug_printf("bad exec\n"); - goto complete; - } - - if ((handle > 15) || (iodesc[handle].fps.file == NULL)) - { - Debug_printf("bad handle %d\n", handle); - device[cunit].status.err = 134; /* bad file handle */ - goto complete; - } - - Debug_printf("handle %d\n", handle); - - device[cunit].status.err = 1; - - fpmode = iodesc[handle].fpmode; - mtime = iodesc[handle].fpstat.st_mtime; + if (memcmp(&pbuf, &device[cunit].parbuf, sizeof(PARBUF)) == 0) + { + /* this is a retry of P-block. Most commands don't like that */ + if ((pbuf.fno != 0x00) && (pbuf.fno != 0x01) && (pbuf.fno != 0x03) \ + && (pbuf.fno != 0x04) && (pbuf.fno != 0x06) && \ + (pbuf.fno != 0x11) && (pbuf.fno != 0x13)) + { + Debug_printf("PARBLK retry, ignored\n"); + goto complete; + } + } + + memcpy(&device[cunit].parbuf, &pbuf, sizeof(PARBUF)); + } + +// device[cunit].status.err = 1; +// set_status_size(devno, cunit, 0); + + fno = device[cunit].parbuf.fno; + faux = device[cunit].parbuf.f1 + device[cunit].parbuf.f2 * 256 + \ + device[cunit].parbuf.f3 * 65536; + + if (fno < (PCL_MAX_FNO+1)) + Debug_printf("%s (fno $%02x):\n", fun[fno], fno); + + handle = device[cunit].parbuf.handle; + + if (fno == 0x00) /* FREAD */ + { + uchar *mem; + ulong blk_size = (faux & 0x0000FFFFL), buffer; + + if (ccom == 'P') + { + if ((handle > 15) || (iodesc[handle].fps.file == NULL)) + { + Debug_printf("bad handle %d\n", handle); + device[cunit].status.err = 134; /* bad file handle */ + goto complete; + } + + if (blk_size == 0) + { + Debug_printf("bad size $0000 (0)\n"); + device[cunit].status.err = 176; + set_status_size(devno, cunit, 0); + goto complete; + } + + device[cunit].status.err = 1; + iodesc[handle].eof = 0; + + buffer = iodesc[handle].fpstat.st_size - iodesc[handle].fppos; + + if (buffer < blk_size) + { + blk_size = buffer; + device[cunit].parbuf.f1 = (buffer & 0x00ff); + device[cunit].parbuf.f2 = (buffer & 0xff00) >> 8; + iodesc[handle].eof = 1; + if (blk_size == 0) + device[cunit].status.err = 136; + } + + Debug_printf("size $%04lx (%ld), buffer $%04lx (%ld)\n", blk_size, blk_size, buffer, buffer); + + set_status_size(devno, cunit, (ushort)blk_size); + goto complete; + } + + if ((ccom == 'R') && (old_ccom == 'R')) + { + pclink_ack(devno, cunit, 'N'); + Debug_printf("serial communication error, abort\n"); + fps_close(handle); + return; + } + + pclink_ack(devno, cunit, 'A'); /* ack the command */ + + Debug_printf("handle %d\n", handle); + + //mem = (uchar*)malloc(blk_size + 1); + mem = (uchar*)malloc(blk_size); + + if (device[cunit].status.err == 1) + { + iodesc[handle].fpread = blk_size; + + if (iodesc[handle].fpmode & 0x10) + { + ulong rdata; + int eof_sig; + + rdata = dir_read(mem, blk_size, handle, &eof_sig); + + if (rdata != blk_size) + { + Debug_printf("FREAD: cannot read %ld bytes from dir\n", blk_size); + if (eof_sig) + { + iodesc[handle].fpread = rdata; + device[cunit].status.err = 136; + } + else + { + iodesc[handle].fpread = 0; + device[cunit].status.err = 255; + } + } + } + else + { + if (fseek(iodesc[handle].fps.file, iodesc[handle].fppos, SEEK_SET)) + { + Debug_printf("FREAD: cannot seek to $%04lx (%ld)\n", iodesc[handle].fppos, iodesc[handle].fppos); + device[cunit].status.err = 166; + } + else + { + long fdata = fread(mem, sizeof(char), blk_size, iodesc[handle].fps.file); + + if ((ulong)fdata != blk_size) + { + Debug_printf("FREAD: cannot read %ld bytes from file\n", blk_size); + if (feof(iodesc[handle].fps.file)) + { + iodesc[handle].fpread = fdata; + device[cunit].status.err = 136; + } + else + { + iodesc[handle].fpread = 0; + device[cunit].status.err = 255; + } + } + } + } + } + + iodesc[handle].fppos += iodesc[handle].fpread; + + if (device[cunit].status.err == 1) + { + if (iodesc[handle].eof) + device[cunit].status.err = 136; + else if (iodesc[handle].fppos == iodesc[handle].fpstat.st_size) + device[cunit].status.err = 3; + } + + set_status_size(devno, cunit, iodesc[handle].fpread); + + Debug_printf("FREAD: send $%04lx (%ld), status $%02x\n", blk_size, blk_size, device[cunit].status.err); + + //sck = calc_checksum(mem, blk_size); + //mem[blk_size] = sck; + pclink_ack(devno, cunit, 'C'); + //com_write(mem, blk_size + 1); + pclink_write(mem, blk_size); // write data + checksum byte + + free(mem); + + goto exit; + } + + if (fno == 0x01) /* FWRITE */ + { + uchar *mem; + ulong blk_size = (faux & 0x0000FFFFL); + + if (ccom == 'P') + { + if ((handle > 15) || (iodesc[handle].fps.file == NULL)) + { + Debug_printf("bad handle %d\n", handle); + device[cunit].status.err = 134; /* bad file handle */ + goto complete; + } + + if (blk_size == 0) + { + Debug_printf("bad size $0000 (0)\n"); + device[cunit].status.err = 176; + set_status_size(devno, cunit, 0); + goto complete; + } + + device[cunit].status.err = 1; + + Debug_printf("size $%04lx (%ld)\n", blk_size, blk_size); + set_status_size(devno, cunit, (ushort)blk_size); + goto complete; + } + + if ((ccom == 'R') && (old_ccom == 'R')) + { + pclink_ack(devno, cunit, 'N'); + Debug_printf("serial communication error, abort\n"); + return; + } + + pclink_ack(devno, cunit, 'a'); /* ack the command (late_ack) */ + + Debug_printf("handle %d\n", handle); + + if ((iodesc[handle].fpmode & 0x10) == 0) + { + if (fseek(iodesc[handle].fps.file, iodesc[handle].fppos, SEEK_SET)) + { + Debug_printf("FWRITE: cannot seek to $%06lx (%ld)\n", iodesc[handle].fppos, iodesc[handle].fppos); + device[cunit].status.err = 166; + } + } + + //mem = (uchar*)malloc(blk_size + 1); + mem = (uchar*)malloc(blk_size); + + sck = pclink_read(mem, blk_size); // read data + checksum byte + ck = calc_checksum(mem, blk_size); // calculate checksum from data + + pclink_ack(devno, cunit, 'A'); /* ack the block of data */ + + if (ck != sck) + { + Debug_printf("FWRITE: block CRC mismatch (sent $%02x, calculated $%02x)\n", sck, ck); + device[cunit].status.err = 143; + free(mem); + goto complete; + } + + if (device[cunit].status.err == 1) + { + long rdata; + + iodesc[handle].fpread = blk_size; + + if (iodesc[handle].fpmode & 0x10) + { + /* ignore raw dir writes */ + } + else + { + rdata = fwrite(mem, sizeof(char), blk_size, iodesc[handle].fps.file); + + if ((ulong)rdata != blk_size) + { + Debug_printf("FWRITE: cannot write %ld bytes to file\n", blk_size); + iodesc[handle].fpread = rdata; + device[cunit].status.err = 255; + } + } + } + + iodesc[handle].fppos += iodesc[handle].fpread; + + set_status_size(devno, cunit, iodesc[handle].fpread); + + Debug_printf("FWRITE: received $%04lx (%ld), status $%02x\n", blk_size, blk_size, device[cunit].status.err); + + free(mem); + goto complete; + } + + if (fno == 0x02) /* FSEEK */ + { + ulong newpos = faux; + + if ((handle > 15) || (iodesc[handle].fps.file == NULL)) + { + Debug_printf("bad handle %d\n", handle); + device[cunit].status.err = 134; /* bad file handle */ + goto complete; + } + + if (ccom == 'R') + { + pclink_ack(devno, cunit, 'A'); /* ack the command */ + Debug_printf("bad exec\n"); + device[cunit].status.err = 176; + goto complete; + } + + device[cunit].status.err = 1; + + Debug_printf("handle %d, newpos $%06lx (%ld)\n", handle, newpos, newpos); + + if (iodesc[handle].fpmode & 0x08) + iodesc[handle].fppos = newpos; + else + { + if ((off_t)newpos <= iodesc[handle].fpstat.st_size) + iodesc[handle].fppos = newpos; + else + device[cunit].status.err = 166; + } + + goto complete; + } + + if ((fno == 0x03) || (fno == 0x04)) /* FTELL/FLEN */ + { + ulong outval = 0; + //uchar out[4]; + uchar out[3]; + + if (ccom == 'P') + { + if ((handle > 15) || (iodesc[handle].fps.file == NULL)) + { + Debug_printf("bad handle %d\n", handle); + device[cunit].status.err = 134; /* bad file handle */ + goto complete; + } + + device[cunit].status.err = 1; + + Debug_printf("device $%02x\n", cunit); + goto complete; + } + + pclink_ack(devno, cunit, 'A'); /* ack the command */ + + if (fno == 0x03) + outval = iodesc[handle].fppos; + else + outval = iodesc[handle].fpstat.st_size; + + Debug_printf("handle %d, send $%06lx (%ld)\n", handle, outval, outval); + + out[0] = (uchar)(outval & 0x000000ffL); + out[1] = (uchar)((outval & 0x0000ff00L) >> 8); + out[2] = (uchar)((outval & 0x00ff0000L) >> 16); + + //out[3] = calc_checksum(out, sizeof(out)-1); + pclink_ack(devno, cunit, 'C'); + //com_write(out, sizeof(out)); + pclink_write(out, sizeof(out)); // write data + checksum byte + + goto exit; + } + + if (fno == 0x06) /* FNEXT */ + { + if (ccom == 'P') + { + device[cunit].status.err = 1; + + Debug_printf("device $%02x\n", cunit); + goto complete; + } + + if ((ccom == 'R') && (old_ccom == 'R')) + { + pclink_ack(devno, cunit, 'N'); + Debug_printf("serial communication error, abort\n"); + return; + } + + pclink_ack(devno, cunit, 'A'); /* ack the command */ + + memset(pcl_dbf.dirbuf, 0, sizeof(pcl_dbf.dirbuf)); + + if ((handle > 15) || (iodesc[handle].fps.file == NULL)) + { + Debug_printf("bad handle %d\n", handle); + device[cunit].status.err = 134; /* bad file handle */ + } + else + { + int eof_flg, match = 0; + + Debug_printf("handle %d\n", handle); + + do + { + struct stat ts; + + memset(&ts, 0, sizeof(ts)); + memset(pcl_dbf.dirbuf, 0, sizeof(pcl_dbf.dirbuf)); + iodesc[handle].fppos += dir_read(pcl_dbf.dirbuf, sizeof(pcl_dbf.dirbuf), handle, &eof_flg); + + if (!eof_flg) + { + /* fake stat to satisfy match_dos_names() */ + if ((pcl_dbf.dirbuf[0] & 0x01) == 0) + ts.st_mode |= (S_IWUSR|S_IWGRP); + if (pcl_dbf.dirbuf[0] & 0x20) + ts.st_mode |= S_IFDIR; + else + ts.st_mode |= S_IFREG; + + match = !match_dos_names((char *)pcl_dbf.dirbuf+6, iodesc[handle].fpname, iodesc[handle].fatr1, &ts); + } + + } while (!eof_flg && !match); + + if (eof_flg) + { + Debug_printf("FNEXT: EOF\n"); + device[cunit].status.err = 136; + } + else if (iodesc[handle].fppos == iodesc[handle].fpstat.st_size) + device[cunit].status.err = 3; + } + + /* avoid the 4th execution stage */ + pcl_dbf.handle = device[cunit].status.err; + + Debug_printf("FNEXT: status %d, send $%02x $%02x%02x $%02x%02x%02x %c%c%c%c%c%c%c%c%c%c%c %02d-%02d-%02d %02d:%02d:%02d\n", \ + pcl_dbf.handle, + pcl_dbf.dirbuf[0], + pcl_dbf.dirbuf[2], pcl_dbf.dirbuf[1], + pcl_dbf.dirbuf[5], pcl_dbf.dirbuf[4], pcl_dbf.dirbuf[3], + pcl_dbf.dirbuf[6], pcl_dbf.dirbuf[7], pcl_dbf.dirbuf[8], pcl_dbf.dirbuf[9], + pcl_dbf.dirbuf[10], pcl_dbf.dirbuf[11], pcl_dbf.dirbuf[12], pcl_dbf.dirbuf[13], + pcl_dbf.dirbuf[14], pcl_dbf.dirbuf[15], pcl_dbf.dirbuf[16], + pcl_dbf.dirbuf[17], pcl_dbf.dirbuf[18], pcl_dbf.dirbuf[19], + pcl_dbf.dirbuf[20], pcl_dbf.dirbuf[21], pcl_dbf.dirbuf[22]); + + //sck = calc_checksum((uchar *)&pcl_dbf, sizeof(pcl_dbf)); + pclink_ack(devno, cunit, 'C'); + //com_write((uchar *)&pcl_dbf, sizeof(pcl_dbf)); + //com_write(&sck, 1); + pclink_write((uchar *)&pcl_dbf, sizeof(pcl_dbf)); // write data + checksum byte + + goto exit; + } + + if (fno == 0x07) /* FCLOSE */ + { + uchar fpmode; + time_t mtime; + char pathname[1024]; + + if (ccom == 'R') + { + pclink_ack(devno, cunit, 'A'); /* ack the command */ + device[cunit].status.err = 176; + Debug_printf("bad exec\n"); + goto complete; + } + + if ((handle > 15) || (iodesc[handle].fps.file == NULL)) + { + Debug_printf("bad handle %d\n", handle); + device[cunit].status.err = 134; /* bad file handle */ + goto complete; + } + + Debug_printf("handle %d\n", handle); + + device[cunit].status.err = 1; + + fpmode = iodesc[handle].fpmode; + mtime = iodesc[handle].fpstat.st_mtime; # if 0 - Debug_printf("FCLOSE: mtime $%08x\n", mtime); + Debug_printf("FCLOSE: mtime $%08x\n", mtime); # endif - strcpy(pathname, iodesc[handle].pathname); + strcpy(pathname, iodesc[handle].pathname); - fps_close(handle); /* this clears out iodesc[handle] */ + fps_close(handle); /* this clears out iodesc[handle] */ - if (mtime && (fpmode & 0x08)) - { + if (mtime && (fpmode & 0x08)) + { utimbuf ub; ub.actime = mtime; ub.modtime = mtime; # if 0 - Debug_printf("FCLOSE: setting timestamp in '%s'\n", pathname); + Debug_printf("FCLOSE: setting timestamp in '%s'\n", pathname); # endif utime(pathname,&ub); - } - goto complete; - } - - if (fno == 0x08) /* INIT */ - { - if (ccom == 'R') - { - pclink_ack(devno, cunit, 'A'); /* ack the command */ - device[cunit].status.err = 176; - Debug_printf("INIT: bad exec\n"); - goto complete; - } - - do_pclink_init(0); - - device[cunit].parbuf.handle = 0xff; - device[cunit].status.none = SIO_DEVICEID_PCLINK; - device[cunit].status.err = 1; - goto complete; - } - - if ((fno == 0x09) || (fno == 0x0a)) /* FOPEN/FFIRST */ - { - if (ccom == 'P') - { - Debug_printf("mode: $%02x, atr1: $%02x, atr2: $%02x, path: '%s', name: '%s'\n", \ - device[cunit].parbuf.fmode, device[cunit].parbuf.fatr1, \ - device[cunit].parbuf.fatr2, device[cunit].parbuf.path, \ - device[cunit].parbuf.name); + } + goto complete; + } + + if (fno == 0x08) /* INIT */ + { + if (ccom == 'R') + { + pclink_ack(devno, cunit, 'A'); /* ack the command */ + device[cunit].status.err = 176; + Debug_printf("INIT: bad exec\n"); + goto complete; + } + + do_pclink_init(0); + + device[cunit].parbuf.handle = 0xff; + device[cunit].status.none = SIO_DEVICEID_PCLINK; + device[cunit].status.err = 1; + goto complete; + } + + if ((fno == 0x09) || (fno == 0x0a)) /* FOPEN/FFIRST */ + { + if (ccom == 'P') + { + Debug_printf("mode: $%02x, atr1: $%02x, atr2: $%02x, path: '%s', name: '%s'\n", \ + device[cunit].parbuf.fmode, device[cunit].parbuf.fatr1, \ + device[cunit].parbuf.fatr2, device[cunit].parbuf.path, \ + device[cunit].parbuf.name); # if 0 - Debug_printf("date: %02d-%02d-%02d time: %02d:%02d:%02d\n", \ - device[cunit].parbuf.f1, device[cunit].parbuf.f2, \ - device[cunit].parbuf.f3, device[cunit].parbuf.f4, \ - device[cunit].parbuf.f5, device[cunit].parbuf.f6); + Debug_printf("date: %02d-%02d-%02d time: %02d:%02d:%02d\n", \ + device[cunit].parbuf.f1, device[cunit].parbuf.f2, \ + device[cunit].parbuf.f3, device[cunit].parbuf.f4, \ + device[cunit].parbuf.f5, device[cunit].parbuf.f6); # endif - device[cunit].status.err = 1; - - if (fno == 0x0a) - device[cunit].parbuf.fmode |= 0x10; - goto complete; - } - else /* ccom not 'P', execution stage */ - { - DIR *dh; - uchar i; - long sl; - struct stat tempstat; - char newpath[1024], raw_name[12]; - - if ((ccom == 'R') && (old_ccom == 'R')) - { - pclink_ack(devno, cunit, 'N'); - Debug_printf("serial communication error, abort\n"); - fps_close(handle); - return; - } - - pclink_ack(devno, cunit, 'A'); /* ack the command */ - - memset(raw_name, 0, sizeof(raw_name)); - memcpy(raw_name, device[cunit].parbuf.name, 8+3); - - if (((device[cunit].parbuf.fmode & 0x0c) == 0) || \ - ((device[cunit].parbuf.fmode & 0x18) == 0x18)) - { - Debug_printf("unsupported fmode ($%02x)\n", device[cunit].parbuf.fmode); - device[cunit].status.err = 146; - goto complete_fopen; - } - - create_user_path(devno, cunit, newpath); - - if (!validate_user_path(device[cunit].dirname, newpath)) - { - Debug_printf("invalid path '%s'\n", newpath); - device[cunit].status.err = 150; - goto complete_fopen; - } - - Debug_printf("local path '%s'\n", newpath); - - for (i = 0; i < 16; i++) - { + device[cunit].status.err = 1; + + if (fno == 0x0a) + device[cunit].parbuf.fmode |= 0x10; + goto complete; + } + else /* ccom not 'P', execution stage */ + { + DIR *dh; + uchar i; + long sl; + struct stat tempstat; + char newpath[1024], raw_name[12]; + + if ((ccom == 'R') && (old_ccom == 'R')) + { + pclink_ack(devno, cunit, 'N'); + Debug_printf("serial communication error, abort\n"); + fps_close(handle); + return; + } + + pclink_ack(devno, cunit, 'A'); /* ack the command */ + + memset(raw_name, 0, sizeof(raw_name)); + memcpy(raw_name, device[cunit].parbuf.name, 8+3); + + if (((device[cunit].parbuf.fmode & 0x0c) == 0) || \ + ((device[cunit].parbuf.fmode & 0x18) == 0x18)) + { + Debug_printf("unsupported fmode ($%02x)\n", device[cunit].parbuf.fmode); + device[cunit].status.err = 146; + goto complete_fopen; + } + + create_user_path(devno, cunit, newpath); + + if (!validate_user_path(device[cunit].dirname, newpath)) + { + Debug_printf("invalid path '%s'\n", newpath); + device[cunit].status.err = 150; + goto complete_fopen; + } + + Debug_printf("local path '%s'\n", newpath); + + for (i = 0; i < 16; i++) + { # if 0 - Debug_printf("FOPEN: find handle: %d is $%08lx\n", i, (ulong)iodesc[i].fps.file); + Debug_printf("FOPEN: find handle: %d is $%08lx\n", i, (ulong)iodesc[i].fps.file); # endif - if (iodesc[i].fps.file == NULL) + if (iodesc[i].fps.file == NULL) # if 1 - break; + break; # else - { - Debug_printf("FOPEN: find handle: found %d\n", i); - break; - } + { + Debug_printf("FOPEN: find handle: found %d\n", i); + break; + } # endif - } - if (i > 15) - { - Debug_printf("FOPEN: too many channels open\n"); - device[cunit].status.err = 161; - goto complete_fopen; - } - - if (stat(newpath, &tempstat) < 0) - { - Debug_printf("FOPEN: cannot stat '%s'\n", newpath); - device[cunit].status.err = 150; - goto complete_fopen; - } - - dh = opendir(newpath); - - if (device[cunit].parbuf.fmode & 0x10) - { - iodesc[i].fps.dir = dh; - memcpy(&sb, &tempstat, sizeof(sb)); - } - else - { - while ((dp = readdir(dh)) != NULL) - { - if (check_dos_name(newpath, dp, &sb)) - continue; - - /* convert 8+3 to NNNNNNNNXXX */ - ugefina(dp->d_name, raw_name); - - /* match */ - if (match_dos_names(raw_name, \ - (char *)device[cunit].parbuf.name, \ - device[cunit].parbuf.fatr1, &sb) == 0) - break; - } - - sl = strlen(newpath); - if (sl && (newpath[sl-1] != '/')) - strcat(newpath, "/"); - - if (dp) - { - strcat(newpath, dp->d_name); - ugefina(dp->d_name, raw_name); - if ((device[cunit].parbuf.fmode & 0x0c) == 0x08) - sb.st_mtime = timestamp2mtime(&device[cunit].parbuf.f1); - } - else - { - if ((device[cunit].parbuf.fmode & 0x0c) == 0x04) - { - Debug_printf("FOPEN: file not found\n"); - device[cunit].status.err = 170; - closedir(dh); - dp = NULL; - goto complete_fopen; - } - else - { - char name83[12]; - - Debug_printf("FOPEN: creating file\n"); - - uexpand(device[cunit].parbuf.name, name83); - - if (validate_dos_name(name83)) - { - Debug_printf("FOPEN: bad filename '%s'\n", name83); - device[cunit].status.err = 165; /* bad filename */ - goto complete_fopen; - } - - strcat(newpath, name83); - ugefina(name83, raw_name); - - memset(&sb, 0, sizeof(struct stat)); - sb.st_mode = S_IFREG|S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP; - - sb.st_mtime = timestamp2mtime(&device[cunit].parbuf.f1); - } - } - - Debug_printf("FOPEN: full local path '%s'\n", newpath); - - if (stat(newpath, &tempstat) < 0) - { - if ((device[cunit].parbuf.fmode & 0x0c) == 0x04) - { - Debug_printf("FOPEN: cannot stat '%s'\n", newpath); - device[cunit].status.err = 170; - goto complete_fopen; - } - } - else - { - if (device[cunit].parbuf.fmode & 0x08) - { - if ((tempstat.st_mode & (S_IWUSR|S_IWGRP)) == 0) - { - Debug_printf("FOPEN: '%s' is read-only\n", newpath); - device[cunit].status.err = 151; - goto complete_fopen; - } - } + } + if (i > 15) + { + Debug_printf("FOPEN: too many channels open\n"); + device[cunit].status.err = 161; + goto complete_fopen; + } + + if (stat(newpath, &tempstat) < 0) + { + Debug_printf("FOPEN: cannot stat '%s'\n", newpath); + device[cunit].status.err = 150; + goto complete_fopen; + } + + dh = opendir(newpath); + + if (device[cunit].parbuf.fmode & 0x10) + { + iodesc[i].fps.dir = dh; + memcpy(&sb, &tempstat, sizeof(sb)); + } + else + { + while ((dp = readdir(dh)) != NULL) + { + if (check_dos_name(newpath, dp, &sb)) + continue; + + /* convert 8+3 to NNNNNNNNXXX */ + ugefina(dp->d_name, raw_name); + + /* match */ + if (match_dos_names(raw_name, \ + (char *)device[cunit].parbuf.name, \ + device[cunit].parbuf.fatr1, &sb) == 0) + break; + } + + sl = strlen(newpath); + if (sl && (newpath[sl-1] != '/')) + strcat(newpath, "/"); + + if (dp) + { + strcat(newpath, dp->d_name); + ugefina(dp->d_name, raw_name); + if ((device[cunit].parbuf.fmode & 0x0c) == 0x08) + sb.st_mtime = timestamp2mtime(&device[cunit].parbuf.f1); + } + else + { + if ((device[cunit].parbuf.fmode & 0x0c) == 0x04) + { + Debug_printf("FOPEN: file not found\n"); + device[cunit].status.err = 170; + closedir(dh); + dp = NULL; + goto complete_fopen; + } + else + { + char name83[12]; + + Debug_printf("FOPEN: creating file\n"); + + uexpand(device[cunit].parbuf.name, name83); + + if (validate_dos_name(name83)) + { + Debug_printf("FOPEN: bad filename '%s'\n", name83); + device[cunit].status.err = 165; /* bad filename */ + goto complete_fopen; + } + + strcat(newpath, name83); + ugefina(name83, raw_name); + + memset(&sb, 0, sizeof(struct stat)); + sb.st_mode = S_IFREG|S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP; + + sb.st_mtime = timestamp2mtime(&device[cunit].parbuf.f1); + } + } + + Debug_printf("FOPEN: full local path '%s'\n", newpath); + + if (stat(newpath, &tempstat) < 0) + { + if ((device[cunit].parbuf.fmode & 0x0c) == 0x04) + { + Debug_printf("FOPEN: cannot stat '%s'\n", newpath); + device[cunit].status.err = 170; + goto complete_fopen; + } + } + else + { + if (device[cunit].parbuf.fmode & 0x08) + { + if ((tempstat.st_mode & (S_IWUSR|S_IWGRP)) == 0) + { + Debug_printf("FOPEN: '%s' is read-only\n", newpath); + device[cunit].status.err = 151; + goto complete_fopen; + } + } # if 0 - if ((device[cunit].parbuf.fmode & 0x0d) == 0x08) - { - if (!S_ISDIR(tempstat.st_mode)) - { - Debug_printf("FOPEN: delete '%s'\n", newpath); - if (unlink(newpath)) - { - Debug_printf("FOPEN: cannot delete '%s'\n", newpath); - device[cunit].status.err = 255; - } - } - } + if ((device[cunit].parbuf.fmode & 0x0d) == 0x08) + { + if (!S_ISDIR(tempstat.st_mode)) + { + Debug_printf("FOPEN: delete '%s'\n", newpath); + if (unlink(newpath)) + { + Debug_printf("FOPEN: cannot delete '%s'\n", newpath); + device[cunit].status.err = 255; + } + } + } # endif - } - - if ((device[cunit].parbuf.fmode & 0x0d) == 0x04) - iodesc[i].fps.file = fopen(newpath, "r"); - else if ((device[cunit].parbuf.fmode & 0x0d) == 0x08) - { - iodesc[i].fps.file = fopen(newpath, "w"); - if (iodesc[i].fps.file) - sb.st_size = 0; - } - else if ((device[cunit].parbuf.fmode & 0x0d) == 0x09) - { - iodesc[i].fps.file = fopen(newpath, "r+"); - if (iodesc[i].fps.file) - fseek(iodesc[i].fps.file, sb.st_size, SEEK_SET); - } - else if ((device[cunit].parbuf.fmode & 0x0d) == 0x0c) - iodesc[i].fps.file = fopen(newpath, "r+"); - - closedir(dh); - dp = NULL; - } - - if (iodesc[i].fps.file == NULL) - { - Debug_printf("FOPEN: cannot open '%s', %s (%d)\n", newpath, strerror(errno), errno); - if (device[cunit].parbuf.fmode & 0x04) - device[cunit].status.err = 170; - else - device[cunit].status.err = 151; - goto complete_fopen; - } + } + + if ((device[cunit].parbuf.fmode & 0x0d) == 0x04) + iodesc[i].fps.file = fopen(newpath, "r"); + else if ((device[cunit].parbuf.fmode & 0x0d) == 0x08) + { + iodesc[i].fps.file = fopen(newpath, "w"); + if (iodesc[i].fps.file) + sb.st_size = 0; + } + else if ((device[cunit].parbuf.fmode & 0x0d) == 0x09) + { + iodesc[i].fps.file = fopen(newpath, "r+"); + if (iodesc[i].fps.file) + fseek(iodesc[i].fps.file, sb.st_size, SEEK_SET); + } + else if ((device[cunit].parbuf.fmode & 0x0d) == 0x0c) + iodesc[i].fps.file = fopen(newpath, "r+"); + + closedir(dh); + dp = NULL; + } + + if (iodesc[i].fps.file == NULL) + { + Debug_printf("FOPEN: cannot open '%s', %s (%d)\n", newpath, strerror(errno), errno); + if (device[cunit].parbuf.fmode & 0x04) + device[cunit].status.err = 170; + else + device[cunit].status.err = 151; + goto complete_fopen; + } # if 0 - Debug_printf("FOPEN: handle %d is $%08lx\n", i, (ulong)iodesc[i].fps.file); + Debug_printf("FOPEN: handle %d is $%08lx\n", i, (ulong)iodesc[i].fps.file); # endif - handle = device[cunit].parbuf.handle = i; - - iodesc[handle].devno = devno; - iodesc[handle].cunit = cunit; - iodesc[handle].fpmode = device[cunit].parbuf.fmode; - iodesc[handle].fatr1 = device[cunit].parbuf.fatr1; - iodesc[handle].fatr2 = device[cunit].parbuf.fatr2; - iodesc[handle].t1 = device[cunit].parbuf.f1; - iodesc[handle].t2 = device[cunit].parbuf.f2; - iodesc[handle].t3 = device[cunit].parbuf.f3; - iodesc[handle].d1 = device[cunit].parbuf.f4; - iodesc[handle].d2 = device[cunit].parbuf.f5; - iodesc[handle].d3 = device[cunit].parbuf.f6; - iodesc[handle].fppos = 0L; - strcpy(iodesc[handle].pathname, newpath); - memcpy((void *)&iodesc[handle].fpstat, (void *)&sb, sizeof(struct stat)); - if (iodesc[handle].fpmode & 0x10) - memcpy(iodesc[handle].fpname, device[cunit].parbuf.name, sizeof(iodesc[i].fpname)); - else - memcpy(iodesc[handle].fpname, raw_name, sizeof(iodesc[handle].fpname)); - - iodesc[handle].fpstat.st_size = get_file_len(handle); - - if ((iodesc[handle].fpmode & 0x1d) == 0x09) - iodesc[handle].fppos = iodesc[handle].fpstat.st_size; - - memset(pcl_dbf.dirbuf, 0, sizeof(pcl_dbf.dirbuf)); - - if ((handle > 15) || (iodesc[handle].fps.file == NULL)) - { - Debug_printf("FOPEN: bad handle %d\n", handle); - device[cunit].status.err = 134; /* bad file handle */ - pcl_dbf.handle = 134; - } - else - { - pcl_dbf.handle = handle; - - unix_time_2_sdx(&iodesc[handle].fpstat.st_mtime, ob); + handle = device[cunit].parbuf.handle = i; + + iodesc[handle].devno = devno; + iodesc[handle].cunit = cunit; + iodesc[handle].fpmode = device[cunit].parbuf.fmode; + iodesc[handle].fatr1 = device[cunit].parbuf.fatr1; + iodesc[handle].fatr2 = device[cunit].parbuf.fatr2; + iodesc[handle].t1 = device[cunit].parbuf.f1; + iodesc[handle].t2 = device[cunit].parbuf.f2; + iodesc[handle].t3 = device[cunit].parbuf.f3; + iodesc[handle].d1 = device[cunit].parbuf.f4; + iodesc[handle].d2 = device[cunit].parbuf.f5; + iodesc[handle].d3 = device[cunit].parbuf.f6; + iodesc[handle].fppos = 0L; + strcpy(iodesc[handle].pathname, newpath); + memcpy((void *)&iodesc[handle].fpstat, (void *)&sb, sizeof(struct stat)); + if (iodesc[handle].fpmode & 0x10) + memcpy(iodesc[handle].fpname, device[cunit].parbuf.name, sizeof(iodesc[i].fpname)); + else + memcpy(iodesc[handle].fpname, raw_name, sizeof(iodesc[handle].fpname)); + + iodesc[handle].fpstat.st_size = get_file_len(handle); + + if ((iodesc[handle].fpmode & 0x1d) == 0x09) + iodesc[handle].fppos = iodesc[handle].fpstat.st_size; + + memset(pcl_dbf.dirbuf, 0, sizeof(pcl_dbf.dirbuf)); + + if ((handle > 15) || (iodesc[handle].fps.file == NULL)) + { + Debug_printf("FOPEN: bad handle %d\n", handle); + device[cunit].status.err = 134; /* bad file handle */ + pcl_dbf.handle = 134; + } + else + { + pcl_dbf.handle = handle; + + unix_time_2_sdx(&iodesc[handle].fpstat.st_mtime, ob); # if 0 - Debug_printf("FOPEN: time %02d-%02d-%02d %02d:%02d.%02d\n", ob[0], ob[1], ob[2], ob[3], ob[4], ob[5]); + Debug_printf("FOPEN: time %02d-%02d-%02d %02d:%02d.%02d\n", ob[0], ob[1], ob[2], ob[3], ob[4], ob[5]); # endif - Debug_printf("FOPEN: %s handle %d\n", (iodesc[handle].fpmode & 0x08) ? "write" : "read", handle); - - memset(pcl_dbf.dirbuf, 0, sizeof(pcl_dbf.dirbuf)); - - if (iodesc[handle].fpmode & 0x10) - { - int eof_sig; - - iodesc[handle].dir_cache = cache_dir(handle); - iodesc[handle].fppos += dir_read(pcl_dbf.dirbuf, sizeof(pcl_dbf.dirbuf), handle, &eof_sig); - - if (eof_sig) - { - Debug_printf("FOPEN: dir EOF?\n"); - device[cunit].status.err = 136; - } - else if (iodesc[handle].fppos == iodesc[handle].fpstat.st_size) - device[cunit].status.err = 3; - } - else - { - int x; - ulong dlen = iodesc[handle].fpstat.st_size; - - memset(pcl_dbf.dirbuf+6, 0x20, 11); - pcl_dbf.dirbuf[3] = (uchar)(dlen & 0x000000ffL); - pcl_dbf.dirbuf[4] = (uchar)((dlen & 0x0000ff00L) >> 8); - pcl_dbf.dirbuf[5] = (uchar)((dlen & 0x00ff0000L) >> 16); - memcpy(pcl_dbf.dirbuf+17, ob, 6); - - pcl_dbf.dirbuf[0] = 0x08; - - if ((iodesc[handle].fpstat.st_mode & (S_IWUSR|S_IWGRP)) == 0) - pcl_dbf.dirbuf[0] |= 0x01; /* protected */ - if (S_ISDIR(iodesc[handle].fpstat.st_mode)) - pcl_dbf.dirbuf[0] |= 0x20; /* directory */ - - x = 0; - while (iodesc[handle].fpname[x] && (x < 11)) - { - pcl_dbf.dirbuf[6+x] = iodesc[handle].fpname[x]; - x++; - } - } - - Debug_printf("FOPEN: send $%02x $%02x%02x $%02x%02x%02x %c%c%c%c%c%c%c%c%c%c%c %02d-%02d-%02d %02d:%02d:%02d\n", \ - pcl_dbf.dirbuf[0], - pcl_dbf.dirbuf[2], pcl_dbf.dirbuf[1], - pcl_dbf.dirbuf[5], pcl_dbf.dirbuf[4], pcl_dbf.dirbuf[3], - pcl_dbf.dirbuf[6], pcl_dbf.dirbuf[7], pcl_dbf.dirbuf[8], pcl_dbf.dirbuf[9], - pcl_dbf.dirbuf[10], pcl_dbf.dirbuf[11], pcl_dbf.dirbuf[12], pcl_dbf.dirbuf[13], - pcl_dbf.dirbuf[14], pcl_dbf.dirbuf[15], pcl_dbf.dirbuf[16], - pcl_dbf.dirbuf[17], pcl_dbf.dirbuf[18], pcl_dbf.dirbuf[19], - pcl_dbf.dirbuf[20], pcl_dbf.dirbuf[21], pcl_dbf.dirbuf[22]); - } + Debug_printf("FOPEN: %s handle %d\n", (iodesc[handle].fpmode & 0x08) ? "write" : "read", handle); + + memset(pcl_dbf.dirbuf, 0, sizeof(pcl_dbf.dirbuf)); + + if (iodesc[handle].fpmode & 0x10) + { + int eof_sig; + + iodesc[handle].dir_cache = cache_dir(handle); + iodesc[handle].fppos += dir_read(pcl_dbf.dirbuf, sizeof(pcl_dbf.dirbuf), handle, &eof_sig); + + if (eof_sig) + { + Debug_printf("FOPEN: dir EOF?\n"); + device[cunit].status.err = 136; + } + else if (iodesc[handle].fppos == iodesc[handle].fpstat.st_size) + device[cunit].status.err = 3; + } + else + { + int x; + ulong dlen = iodesc[handle].fpstat.st_size; + + memset(pcl_dbf.dirbuf+6, 0x20, 11); + pcl_dbf.dirbuf[3] = (uchar)(dlen & 0x000000ffL); + pcl_dbf.dirbuf[4] = (uchar)((dlen & 0x0000ff00L) >> 8); + pcl_dbf.dirbuf[5] = (uchar)((dlen & 0x00ff0000L) >> 16); + memcpy(pcl_dbf.dirbuf+17, ob, 6); + + pcl_dbf.dirbuf[0] = 0x08; + + if ((iodesc[handle].fpstat.st_mode & (S_IWUSR|S_IWGRP)) == 0) + pcl_dbf.dirbuf[0] |= 0x01; /* protected */ + if (S_ISDIR(iodesc[handle].fpstat.st_mode)) + pcl_dbf.dirbuf[0] |= 0x20; /* directory */ + + x = 0; + while (iodesc[handle].fpname[x] && (x < 11)) + { + pcl_dbf.dirbuf[6+x] = iodesc[handle].fpname[x]; + x++; + } + } + + Debug_printf("FOPEN: send $%02x $%02x%02x $%02x%02x%02x %c%c%c%c%c%c%c%c%c%c%c %02d-%02d-%02d %02d:%02d:%02d\n", \ + pcl_dbf.dirbuf[0], + pcl_dbf.dirbuf[2], pcl_dbf.dirbuf[1], + pcl_dbf.dirbuf[5], pcl_dbf.dirbuf[4], pcl_dbf.dirbuf[3], + pcl_dbf.dirbuf[6], pcl_dbf.dirbuf[7], pcl_dbf.dirbuf[8], pcl_dbf.dirbuf[9], + pcl_dbf.dirbuf[10], pcl_dbf.dirbuf[11], pcl_dbf.dirbuf[12], pcl_dbf.dirbuf[13], + pcl_dbf.dirbuf[14], pcl_dbf.dirbuf[15], pcl_dbf.dirbuf[16], + pcl_dbf.dirbuf[17], pcl_dbf.dirbuf[18], pcl_dbf.dirbuf[19], + pcl_dbf.dirbuf[20], pcl_dbf.dirbuf[21], pcl_dbf.dirbuf[22]); + } complete_fopen: - //sck = calc_checksum((uchar *)&pcl_dbf, sizeof(pcl_dbf)); - pclink_ack(devno, cunit, 'C'); - //com_write((uchar *)&pcl_dbf, sizeof(pcl_dbf)); - //com_write(&sck, 1); - pclink_write((uchar *)&pcl_dbf, sizeof(pcl_dbf)); // write data + checksum byte - - goto exit; - } - } - - if (fno == 0x0b) /* RENAME/RENDIR */ - { - char newpath[1024]; - DIR *renamedir; - ulong fcnt = 0; - - if (ccom == 'R') - { - pclink_ack(devno, cunit, 'A'); /* ack the command */ - device[cunit].status.err = 176; - Debug_printf("bad exec\n"); - goto complete; - } - - create_user_path(devno, cunit, newpath); - - if (!validate_user_path(device[cunit].dirname, newpath)) - { - Debug_printf("invalid path '%s'\n", newpath); - device[cunit].status.err = 150; - goto complete; - } - - renamedir = opendir(newpath); - - if (renamedir == NULL) - { - Debug_printf("cannot open dir '%s'\n", newpath); - device[cunit].status.err = 255; - goto complete; - } - - Debug_printf("local path '%s', fatr1 $%02x\n", newpath, \ - device[cunit].parbuf.fatr1 | RA_NO_PROTECT); - - device[cunit].status.err = 1; - - while ((dp = readdir(renamedir)) != NULL) - { - char raw_name[12]; - - if (check_dos_name(newpath, dp, &sb)) - continue; - - /* convert 8+3 to NNNNNNNNXXX */ - ugefina(dp->d_name, raw_name); - - /* match */ - if (match_dos_names(raw_name, (char *)device[cunit].parbuf.name, \ - device[cunit].parbuf.fatr1 | RA_NO_PROTECT, &sb) == 0) - { - char xpath[1024], xpath2[1024], newname[16]; - uchar names[12]; - struct stat dummy; - ushort x; - - fcnt++; - - strcpy(xpath, newpath); - strcat(xpath, "/"); - strcat(xpath, dp->d_name); - - memcpy(names, device[cunit].parbuf.names, 12); - - for (x = 0; x < 12; x++) - { - if (names[x] == '?') - names[x] = raw_name[x]; - } - - uexpand(names, newname); - - strcpy(xpath2, newpath); - strcat(xpath2, "/"); - strcat(xpath2, newname); - - Debug_printf("RENAME: renaming '%s' -> '%s'\n", dp->d_name, newname); - - if (stat(xpath2, &dummy) == 0) - { - Debug_printf("RENAME: '%s' already exists\n", xpath2); - device[cunit].status.err = 151; - break; - } - - if (rename(xpath, xpath2)) - { - Debug_printf("RENAME: %s\n", strerror(errno)); - device[cunit].status.err = 255; - } - } - } - - closedir(renamedir); - - if ((fcnt == 0) && (device[cunit].status.err == 1)) - device[cunit].status.err = 170; - goto complete; - } - - if (fno == 0x0c) /* REMOVE */ - { - char newpath[1024]; - DIR *deldir; - ulong delcnt = 0; - - if (ccom == 'R') - { - pclink_ack(devno, cunit, 'A'); /* ack the command */ - device[cunit].status.err = 176; - Debug_printf("bad exec\n"); - goto complete; - } - - create_user_path(devno, cunit, newpath); - - if (!validate_user_path(device[cunit].dirname, newpath)) - { - Debug_printf("invalid path '%s'\n", newpath); - device[cunit].status.err = 150; - goto complete; - } - - Debug_printf("local path '%s'\n", newpath); - - deldir = opendir(newpath); - - if (deldir == NULL) - { - Debug_printf("cannot open dir '%s'\n", newpath); - device[cunit].status.err = 255; - goto complete; - } - - device[cunit].status.err = 1; - - while ((dp = readdir(deldir)) != NULL) - { - char raw_name[12]; - - if (check_dos_name(newpath, dp, &sb)) - continue; - - /* convert 8+3 to NNNNNNNNXXX */ - ugefina(dp->d_name, raw_name); - - /* match */ - if (match_dos_names(raw_name, (char *)device[cunit].parbuf.name, \ - RA_NO_PROTECT | RA_NO_SUBDIR | RA_NO_HIDDEN, &sb) == 0) - { - char xpath[1024]; - - strcpy(xpath, newpath); - strcat(xpath, "/"); - strcat(xpath, dp->d_name); - - if (!S_ISDIR(sb.st_mode)) - { - Debug_printf("REMOVE: delete '%s'\n", xpath); - if (unlink(xpath)) - { - Debug_printf("REMOVE: cannot delete '%s'\n", xpath); - device[cunit].status.err = 255; - } - delcnt++; - } - } - } - closedir(deldir); - if (delcnt == 0) - device[cunit].status.err = 170; - goto complete; - } - - if (fno == 0x0d) /* CHMOD */ - { - char newpath[1024]; - DIR *chmdir; - ulong fcnt = 0; - uchar fatr2 = device[cunit].parbuf.fatr2; - - if (ccom == 'R') - { - pclink_ack(devno, cunit, 'A'); /* ack the command */ - device[cunit].status.err = 176; - Debug_printf("bad exec\n"); - goto complete; - } - - if (fatr2 & (SA_SUBDIR | SA_UNSUBDIR)) - { - Debug_printf("illegal fatr2 $%02x\n", fatr2); - device[cunit].status.err = 146; - goto complete; - } - - create_user_path(devno, cunit, newpath); - - if (!validate_user_path(device[cunit].dirname, newpath)) - { - Debug_printf("invalid path '%s'\n", newpath); - device[cunit].status.err = 150; - goto complete; - } - - Debug_printf("local path '%s', fatr1 $%02x fatr2 $%02x\n", newpath, \ - device[cunit].parbuf.fatr1, fatr2); - - chmdir = opendir(newpath); - - if (chmdir == NULL) - { - Debug_printf("CHMOD: cannot open dir '%s'\n", newpath); - device[cunit].status.err = 255; - goto complete; - } - - - device[cunit].status.err = 1; - - while ((dp = readdir(chmdir)) != NULL) - { - char raw_name[12]; - - if (check_dos_name(newpath, dp, &sb)) - continue; - - /* convert 8+3 to NNNNNNNNXXX */ - ugefina(dp->d_name, raw_name); - - /* match */ - if (match_dos_names(raw_name, (char *)device[cunit].parbuf.name, \ - device[cunit].parbuf.fatr1, &sb) == 0) - { - char xpath[1024]; - mode_t newmode = sb.st_mode; - - strcpy(xpath, newpath); - strcat(xpath, "/"); - strcat(xpath, dp->d_name); - Debug_printf("CHMOD: change atrs in '%s'\n", xpath); - - /* On Unix, ignore Hidden and Archive bits */ - if (fatr2 & SA_UNPROTECT) - newmode |= S_IWUSR; - if (fatr2 & SA_PROTECT) - newmode &= ~S_IWUSR; - // TODO - chmod is not available on platformio + //sck = calc_checksum((uchar *)&pcl_dbf, sizeof(pcl_dbf)); + pclink_ack(devno, cunit, 'C'); + //com_write((uchar *)&pcl_dbf, sizeof(pcl_dbf)); + //com_write(&sck, 1); + pclink_write((uchar *)&pcl_dbf, sizeof(pcl_dbf)); // write data + checksum byte + + goto exit; + } + } + + if (fno == 0x0b) /* RENAME/RENDIR */ + { + char newpath[1024]; + DIR *renamedir; + ulong fcnt = 0; + + if (ccom == 'R') + { + pclink_ack(devno, cunit, 'A'); /* ack the command */ + device[cunit].status.err = 176; + Debug_printf("bad exec\n"); + goto complete; + } + + create_user_path(devno, cunit, newpath); + + if (!validate_user_path(device[cunit].dirname, newpath)) + { + Debug_printf("invalid path '%s'\n", newpath); + device[cunit].status.err = 150; + goto complete; + } + + renamedir = opendir(newpath); + + if (renamedir == NULL) + { + Debug_printf("cannot open dir '%s'\n", newpath); + device[cunit].status.err = 255; + goto complete; + } + + Debug_printf("local path '%s', fatr1 $%02x\n", newpath, \ + device[cunit].parbuf.fatr1 | RA_NO_PROTECT); + + device[cunit].status.err = 1; + + while ((dp = readdir(renamedir)) != NULL) + { + char raw_name[12]; + + if (check_dos_name(newpath, dp, &sb)) + continue; + + /* convert 8+3 to NNNNNNNNXXX */ + ugefina(dp->d_name, raw_name); + + /* match */ + if (match_dos_names(raw_name, (char *)device[cunit].parbuf.name, \ + device[cunit].parbuf.fatr1 | RA_NO_PROTECT, &sb) == 0) + { + char xpath[1024], xpath2[1024], newname[16]; + uchar names[12]; + struct stat dummy; + ushort x; + + fcnt++; + + strcpy(xpath, newpath); + strcat(xpath, "/"); + strcat(xpath, dp->d_name); + + memcpy(names, device[cunit].parbuf.names, 12); + + for (x = 0; x < 12; x++) + { + if (names[x] == '?') + names[x] = raw_name[x]; + } + + uexpand(names, newname); + + strcpy(xpath2, newpath); + strcat(xpath2, "/"); + strcat(xpath2, newname); + + Debug_printf("RENAME: renaming '%s' -> '%s'\n", dp->d_name, newname); + + if (stat(xpath2, &dummy) == 0) + { + Debug_printf("RENAME: '%s' already exists\n", xpath2); + device[cunit].status.err = 151; + break; + } + + if (rename(xpath, xpath2)) + { + Debug_printf("RENAME: %s\n", strerror(errno)); + device[cunit].status.err = 255; + } + } + } + + closedir(renamedir); + + if ((fcnt == 0) && (device[cunit].status.err == 1)) + device[cunit].status.err = 170; + goto complete; + } + + if (fno == 0x0c) /* REMOVE */ + { + char newpath[1024]; + DIR *deldir; + ulong delcnt = 0; + + if (ccom == 'R') + { + pclink_ack(devno, cunit, 'A'); /* ack the command */ + device[cunit].status.err = 176; + Debug_printf("bad exec\n"); + goto complete; + } + + create_user_path(devno, cunit, newpath); + + if (!validate_user_path(device[cunit].dirname, newpath)) + { + Debug_printf("invalid path '%s'\n", newpath); + device[cunit].status.err = 150; + goto complete; + } + + Debug_printf("local path '%s'\n", newpath); + + deldir = opendir(newpath); + + if (deldir == NULL) + { + Debug_printf("cannot open dir '%s'\n", newpath); + device[cunit].status.err = 255; + goto complete; + } + + device[cunit].status.err = 1; + + while ((dp = readdir(deldir)) != NULL) + { + char raw_name[12]; + + if (check_dos_name(newpath, dp, &sb)) + continue; + + /* convert 8+3 to NNNNNNNNXXX */ + ugefina(dp->d_name, raw_name); + + /* match */ + if (match_dos_names(raw_name, (char *)device[cunit].parbuf.name, \ + RA_NO_PROTECT | RA_NO_SUBDIR | RA_NO_HIDDEN, &sb) == 0) + { + char xpath[1024]; + + strcpy(xpath, newpath); + strcat(xpath, "/"); + strcat(xpath, dp->d_name); + + if (!S_ISDIR(sb.st_mode)) + { + Debug_printf("REMOVE: delete '%s'\n", xpath); + if (unlink(xpath)) + { + Debug_printf("REMOVE: cannot delete '%s'\n", xpath); + device[cunit].status.err = 255; + } + delcnt++; + } + } + } + closedir(deldir); + if (delcnt == 0) + device[cunit].status.err = 170; + goto complete; + } + + if (fno == 0x0d) /* CHMOD */ + { + char newpath[1024]; + DIR *chmdir; + ulong fcnt = 0; + uchar fatr2 = device[cunit].parbuf.fatr2; + + if (ccom == 'R') + { + pclink_ack(devno, cunit, 'A'); /* ack the command */ + device[cunit].status.err = 176; + Debug_printf("bad exec\n"); + goto complete; + } + + if (fatr2 & (SA_SUBDIR | SA_UNSUBDIR)) + { + Debug_printf("illegal fatr2 $%02x\n", fatr2); + device[cunit].status.err = 146; + goto complete; + } + + create_user_path(devno, cunit, newpath); + + if (!validate_user_path(device[cunit].dirname, newpath)) + { + Debug_printf("invalid path '%s'\n", newpath); + device[cunit].status.err = 150; + goto complete; + } + + Debug_printf("local path '%s', fatr1 $%02x fatr2 $%02x\n", newpath, \ + device[cunit].parbuf.fatr1, fatr2); + + chmdir = opendir(newpath); + + if (chmdir == NULL) + { + Debug_printf("CHMOD: cannot open dir '%s'\n", newpath); + device[cunit].status.err = 255; + goto complete; + } + + + device[cunit].status.err = 1; + + while ((dp = readdir(chmdir)) != NULL) + { + char raw_name[12]; + + if (check_dos_name(newpath, dp, &sb)) + continue; + + /* convert 8+3 to NNNNNNNNXXX */ + ugefina(dp->d_name, raw_name); + + /* match */ + if (match_dos_names(raw_name, (char *)device[cunit].parbuf.name, \ + device[cunit].parbuf.fatr1, &sb) == 0) + { + char xpath[1024]; + mode_t newmode = sb.st_mode; + + strcpy(xpath, newpath); + strcat(xpath, "/"); + strcat(xpath, dp->d_name); + Debug_printf("CHMOD: change atrs in '%s'\n", xpath); + + /* On Unix, ignore Hidden and Archive bits */ + if (fatr2 & SA_UNPROTECT) + newmode |= S_IWUSR; + if (fatr2 & SA_PROTECT) + newmode &= ~S_IWUSR; + // TODO - chmod is not available on platformio #ifndef ESP_PLATFORM - if (chmod(xpath, newmode)) - { - Debug_printf("CHMOD: failed on '%s'\n", xpath); - device[cunit].status.err |= 255; - } + if (chmod(xpath, newmode)) + { + Debug_printf("CHMOD: failed on '%s'\n", xpath); + device[cunit].status.err |= 255; + } #endif - fcnt++; - } - } - closedir(chmdir); - if (fcnt == 0) - device[cunit].status.err = 170; - goto complete; - } - - if (fno == 0x0e) /* MKDIR - warning, fatr2 is bogus */ - { - char newpath[1024], fname[12]; - uchar dt[6]; - struct stat dummy; - - if (ccom == 'R') - { - pclink_ack(devno, cunit, 'A'); /* ack the command */ - device[cunit].status.err = 176; - Debug_printf("bad exec\n"); - goto complete; - } - - create_user_path(devno, cunit, newpath); - - if (!validate_user_path(device[cunit].dirname, newpath)) - { - Debug_printf("invalid path '%s'\n", newpath); - device[cunit].status.err = 150; - goto complete; - } - - uexpand(device[cunit].parbuf.name, fname); - - if (validate_dos_name(fname)) - { - Debug_printf("bad dir name '%s'\n", fname); - device[cunit].status.err = 165; - goto complete; - } - - strcat(newpath, "/"); - strcat(newpath, fname); - - memcpy(dt, &device[cunit].parbuf.f1, sizeof(dt)); - - Debug_printf("making dir '%s', time %2d-%02d-%02d %2d:%02d:%02d\n", newpath, \ - dt[0], dt[1], dt[2], dt[3], dt[4], dt[5]); - - if (stat(newpath, &dummy) == 0) - { - Debug_printf("MKDIR: '%s' already exists\n", newpath); - device[cunit].status.err = 151; - goto complete; - } - - if (mkdir(newpath, S_IRWXU|S_IRWXG|S_IRWXO)) - { - Debug_printf("MKDIR: cannot make dir '%s'\n", newpath); - device[cunit].status.err = 255; - } - else - { - time_t mtime = timestamp2mtime(dt); - - device[cunit].status.err = 1; - - if (mtime) - { + fcnt++; + } + } + closedir(chmdir); + if (fcnt == 0) + device[cunit].status.err = 170; + goto complete; + } + + if (fno == 0x0e) /* MKDIR - warning, fatr2 is bogus */ + { + char newpath[1024], fname[12]; + uchar dt[6]; + struct stat dummy; + + if (ccom == 'R') + { + pclink_ack(devno, cunit, 'A'); /* ack the command */ + device[cunit].status.err = 176; + Debug_printf("bad exec\n"); + goto complete; + } + + create_user_path(devno, cunit, newpath); + + if (!validate_user_path(device[cunit].dirname, newpath)) + { + Debug_printf("invalid path '%s'\n", newpath); + device[cunit].status.err = 150; + goto complete; + } + + uexpand(device[cunit].parbuf.name, fname); + + if (validate_dos_name(fname)) + { + Debug_printf("bad dir name '%s'\n", fname); + device[cunit].status.err = 165; + goto complete; + } + + strcat(newpath, "/"); + strcat(newpath, fname); + + memcpy(dt, &device[cunit].parbuf.f1, sizeof(dt)); + + Debug_printf("making dir '%s', time %2d-%02d-%02d %2d:%02d:%02d\n", newpath, \ + dt[0], dt[1], dt[2], dt[3], dt[4], dt[5]); + + if (stat(newpath, &dummy) == 0) + { + Debug_printf("MKDIR: '%s' already exists\n", newpath); + device[cunit].status.err = 151; + goto complete; + } + + if (mkdir(newpath, S_IRWXU|S_IRWXG|S_IRWXO)) + { + Debug_printf("MKDIR: cannot make dir '%s'\n", newpath); + device[cunit].status.err = 255; + } + else + { + time_t mtime = timestamp2mtime(dt); + + device[cunit].status.err = 1; + + if (mtime) + { utimbuf ub; ub.actime = mtime; ub.modtime = mtime; # if 0 - Debug_printf("MKDIR: setting timestamp in '%s'\n", newpath); + Debug_printf("MKDIR: setting timestamp in '%s'\n", newpath); # endif utime(newpath, &ub); - } - } - goto complete; - } - - if (fno == 0x0f) /* RMDIR */ - { - char newpath[1024], fname[12]; - - if (ccom == 'R') - { - pclink_ack(devno, cunit, 'A'); /* ack the command */ - device[cunit].status.err = 176; - Debug_printf("bad exec\n"); - goto complete; - } - - create_user_path(devno, cunit, newpath); - - if (!validate_user_path(device[cunit].dirname, newpath)) - { - Debug_printf("invalid path '%s'\n", newpath); - device[cunit].status.err = 150; - goto complete; - } - - uexpand(device[cunit].parbuf.name, fname); - - if (validate_dos_name(fname)) - { - Debug_printf("bad dir name '%s'\n", fname); - device[cunit].status.err = 165; - goto complete; - } - - strcat(newpath, "/"); - strcat(newpath, fname); - - if (stat(newpath, &sb) < 0) - { - Debug_printf("cannot stat '%s'\n", newpath); - device[cunit].status.err = 170; - goto complete; - } - - /*if (sb.st_uid != our_uid) - { - Debug_printf("'%s' wrong uid\n", newpath); - device[cunit].status.err = 170; - goto complete; - }*/ - - if (!S_ISDIR(sb.st_mode)) - { - Debug_printf("'%s' is not a directory\n", newpath); - device[cunit].status.err = 170; - goto complete; - } - - if ((sb.st_mode & (S_IWUSR|S_IWGRP)) == 0) - { - Debug_printf("dir '%s' is write-protected\n", newpath); - device[cunit].status.err = 170; - goto complete; - } - - Debug_printf("delete dir '%s'\n", newpath); - - device[cunit].status.err = 1; - - if (rmdir(newpath)) - { - Debug_printf("RMDIR: cannot del '%s', %s (%d)\n", newpath, strerror(errno), errno); - if (errno == ENOTEMPTY) - device[cunit].status.err = 167; - else - device[cunit].status.err = 255; - } - goto complete; - } - - if (fno == 0x10) /* CHDIR */ - { - ulong i; - char newpath[1024]; - - if (ccom == 'R') - { - pclink_ack(devno, cunit, 'A'); /* ack the command */ - device[cunit].status.err = 176; - Debug_printf("bad exec\n"); - goto complete; - } - - Debug_printf("req. path '%s'\n", device[cunit].parbuf.path); - - create_user_path(devno, cunit, newpath); - Debug_printf("newpath '%s'\n", newpath); - - if (!validate_user_path(device[cunit].dirname, newpath)) - { - Debug_printf("invalid path '%s'\n", newpath); - device[cunit].status.err = 150; - goto complete; - } - - // chdir and getcwd not implemented on platformio (as of July 2023) - // https://github.com/espressif/esp-idf/issues/8540 - - /* validate_user_path() guarantees that .dirname is part of newwd */ - i = strlen(device[cunit].dirname); - strcpy((char *)device[cunit].cwd, newpath + i); - Debug_printf("new current dir '%s'\n", (char *)device[cunit].cwd); - - device[cunit].status.err = 1; - - goto complete; - } - - if (fno == 0x11) /* GETCWD */ - { - int i; - uchar tempcwd[65]; - - device[cunit].status.err = 1; - - if (ccom == 'P') - { - Debug_printf("device $%02x\n", cunit); - goto complete; - } - - pclink_ack(devno, cunit, 'A'); /* ack the command */ - - tempcwd[0] = 0; - - for (i = 0; device[cunit].cwd[i] && (i < 64); i++) - { - uchar a; - - a = toupper(device[cunit].cwd[i]); - if (a == '/') - a = '>'; - tempcwd[i] = a; - } - - tempcwd[i] = 0; - - Debug_printf("send '%s'\n", tempcwd); - - //sck = calc_checksum(tempcwd, sizeof(tempcwd)-1); - pclink_ack(devno, cunit, 'C'); - //com_write(tempcwd, sizeof(tempcwd)-1); - //com_write(&sck, sizeof(sck)); - pclink_write(tempcwd, sizeof(tempcwd)-1); // write data + checksum byte - - goto exit; - } - - if (fno == 0x13) /* DFREE */ - { - FILE *vf; - int x; - uchar c = 0, volname[8]; - char lpath[1024]; - static uchar dfree[64] = - { - 0x21, /* data format version */ - 0x00, 0x00, /* main directory ptr */ - 0xff, 0xff, /* total sectors */ - 0xff, 0xff, /* free sectors */ - 0x00, /* bitmap length */ - 0x00, 0x00, /* bitmap begin */ - 0x00, 0x00, /* filef */ - 0x00, 0x00, /* dirf */ - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* volume name */ - 0x00, /* number of tracks */ - 0x01, /* bytes per sector, encoded */ - 0x80, /* version number */ - 0x00, 0x02, /* real bps */ - 0x00, 0x00, /* fmapen */ - 0x01, /* sectors per cluster */ - 0x00, 0x00, /* nr seq and rnd */ - 0x00, 0x00, /* bootp */ - 0x00, /* lock */ - - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0, - 0,0,0,0,0, - //0 /* CRC */ - }; - - device[cunit].status.err = 1; - - if (ccom == 'P') - { - Debug_printf("device $%02x\n", cunit); - goto complete; - } - - pclink_ack(devno, cunit, 'A'); /* ack the command */ - - memset(dfree + 0x0e, 0x020, 8); - - strcpy(lpath, (char *)device[cunit].dirname); - strcat(lpath, "/"); - strcat(lpath, DEVICE_LABEL); - - Debug_printf("reading '%s'\n", lpath); - - vf = fopen(lpath, "r"); - - if (vf) - { - int r; - uchar a; - - r = fread(volname, sizeof (uchar), 8, vf); - - fclose(vf); - - for (x = 0; x < r; x++) - { - a = volname[x]; - if (a == 0x9b) - break; - dfree[14+x] = a; - } - } - else - { - uchar a; - int o; - for (o = strlen(device[cunit].dirname); o > 0; o--) - { - a = device[cunit].dirname[o-1]; - if (a == '/') - break; - } - for (x = 0; x < 8; x++) - { - a = device[cunit].dirname[o+x]; - if (a == '\0') - break; - dfree[14+x] = a; - } - } - - x = 0; - while (x < 8) - { - c |= dfree[14+x]; - x++; - } - - if (c == 0x20) - { - memcpy(dfree + 14, "PCLink ", 8); - dfree[21] = cunit + 0x40; - } - - Debug_printf("DFREE: send info (%d bytes)\n", (int)sizeof(dfree)-1); - - //dfree[64] = calc_checksum(dfree, sizeof(dfree)-1); - pclink_ack(devno, cunit, 'C'); - //com_write(dfree, sizeof(dfree)); - pclink_write(dfree, sizeof(dfree)); // write data + checksum byte - - goto exit; - } - - if (fno == 0x14) /* CHVOL */ - { - FILE *vf; - ulong nl; - char lpath[1024]; - - device[cunit].status.err = 1; - - if (ccom == 'R') - { - pclink_ack(devno, cunit, 'A'); /* ack the command */ - device[cunit].status.err = 176; - Debug_printf("bad exec\n"); - goto complete; - } - - nl = strlen((char *)device[cunit].parbuf.name); - - if (nl == 0) - { - Debug_printf("invalid name\n"); - device[cunit].status.err = 156; - goto complete; - } - - strcpy(lpath, device[cunit].dirname); - strcat(lpath, "/"); - strcat(lpath, DEVICE_LABEL); - - Debug_printf("writing '%s'\n", lpath); - - vf = fopen(lpath, "w"); - - if (vf) - { - int x; - uchar a; - - for (x = 0; x < 8; x++) - { - a = device[cunit].parbuf.name[x]; - if (!a || (a == 0x9b)) - a = 0x20; - (void)fwrite(&a, sizeof(uchar), 1, vf); - } - fclose(vf); - } - else - { - Debug_printf("CHVOL: %s\n", strerror(errno)); - device[cunit].status.err = 255; - } - goto complete; - } - - Debug_printf("fno $%02x: not implemented\n", fno); - device[cunit].status.err = 146; + } + } + goto complete; + } + + if (fno == 0x0f) /* RMDIR */ + { + char newpath[1024], fname[12]; + + if (ccom == 'R') + { + pclink_ack(devno, cunit, 'A'); /* ack the command */ + device[cunit].status.err = 176; + Debug_printf("bad exec\n"); + goto complete; + } + + create_user_path(devno, cunit, newpath); + + if (!validate_user_path(device[cunit].dirname, newpath)) + { + Debug_printf("invalid path '%s'\n", newpath); + device[cunit].status.err = 150; + goto complete; + } + + uexpand(device[cunit].parbuf.name, fname); + + if (validate_dos_name(fname)) + { + Debug_printf("bad dir name '%s'\n", fname); + device[cunit].status.err = 165; + goto complete; + } + + strcat(newpath, "/"); + strcat(newpath, fname); + + if (stat(newpath, &sb) < 0) + { + Debug_printf("cannot stat '%s'\n", newpath); + device[cunit].status.err = 170; + goto complete; + } + + /*if (sb.st_uid != our_uid) + { + Debug_printf("'%s' wrong uid\n", newpath); + device[cunit].status.err = 170; + goto complete; + }*/ + + if (!S_ISDIR(sb.st_mode)) + { + Debug_printf("'%s' is not a directory\n", newpath); + device[cunit].status.err = 170; + goto complete; + } + + if ((sb.st_mode & (S_IWUSR|S_IWGRP)) == 0) + { + Debug_printf("dir '%s' is write-protected\n", newpath); + device[cunit].status.err = 170; + goto complete; + } + + Debug_printf("delete dir '%s'\n", newpath); + + device[cunit].status.err = 1; + + if (rmdir(newpath)) + { + Debug_printf("RMDIR: cannot del '%s', %s (%d)\n", newpath, strerror(errno), errno); + if (errno == ENOTEMPTY) + device[cunit].status.err = 167; + else + device[cunit].status.err = 255; + } + goto complete; + } + + if (fno == 0x10) /* CHDIR */ + { + ulong i; + char newpath[1024]; + + if (ccom == 'R') + { + pclink_ack(devno, cunit, 'A'); /* ack the command */ + device[cunit].status.err = 176; + Debug_printf("bad exec\n"); + goto complete; + } + + Debug_printf("req. path '%s'\n", device[cunit].parbuf.path); + + create_user_path(devno, cunit, newpath); + Debug_printf("newpath '%s'\n", newpath); + + if (!validate_user_path(device[cunit].dirname, newpath)) + { + Debug_printf("invalid path '%s'\n", newpath); + device[cunit].status.err = 150; + goto complete; + } + + // chdir and getcwd not implemented on platformio (as of July 2023) + // https://github.com/espressif/esp-idf/issues/8540 + + /* validate_user_path() guarantees that .dirname is part of newwd */ + i = strlen(device[cunit].dirname); + strcpy((char *)device[cunit].cwd, newpath + i); + Debug_printf("new current dir '%s'\n", (char *)device[cunit].cwd); + + device[cunit].status.err = 1; + + goto complete; + } + + if (fno == 0x11) /* GETCWD */ + { + int i; + uchar tempcwd[65]; + + device[cunit].status.err = 1; + + if (ccom == 'P') + { + Debug_printf("device $%02x\n", cunit); + goto complete; + } + + pclink_ack(devno, cunit, 'A'); /* ack the command */ + + tempcwd[0] = 0; + + for (i = 0; device[cunit].cwd[i] && (i < 64); i++) + { + uchar a; + + a = toupper(device[cunit].cwd[i]); + if (a == '/') + a = '>'; + tempcwd[i] = a; + } + + tempcwd[i] = 0; + + Debug_printf("send '%s'\n", tempcwd); + + //sck = calc_checksum(tempcwd, sizeof(tempcwd)-1); + pclink_ack(devno, cunit, 'C'); + //com_write(tempcwd, sizeof(tempcwd)-1); + //com_write(&sck, sizeof(sck)); + pclink_write(tempcwd, sizeof(tempcwd)-1); // write data + checksum byte + + goto exit; + } + + if (fno == 0x13) /* DFREE */ + { + FILE *vf; + int x; + uchar c = 0, volname[8]; + char lpath[1024]; + static uchar dfree[64] = + { + 0x21, /* data format version */ + 0x00, 0x00, /* main directory ptr */ + 0xff, 0xff, /* total sectors */ + 0xff, 0xff, /* free sectors */ + 0x00, /* bitmap length */ + 0x00, 0x00, /* bitmap begin */ + 0x00, 0x00, /* filef */ + 0x00, 0x00, /* dirf */ + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* volume name */ + 0x00, /* number of tracks */ + 0x01, /* bytes per sector, encoded */ + 0x80, /* version number */ + 0x00, 0x02, /* real bps */ + 0x00, 0x00, /* fmapen */ + 0x01, /* sectors per cluster */ + 0x00, 0x00, /* nr seq and rnd */ + 0x00, 0x00, /* bootp */ + 0x00, /* lock */ + + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0, + //0 /* CRC */ + }; + + device[cunit].status.err = 1; + + if (ccom == 'P') + { + Debug_printf("device $%02x\n", cunit); + goto complete; + } + + pclink_ack(devno, cunit, 'A'); /* ack the command */ + + memset(dfree + 0x0e, 0x020, 8); + + strcpy(lpath, (char *)device[cunit].dirname); + strcat(lpath, "/"); + strcat(lpath, DEVICE_LABEL); + + Debug_printf("reading '%s'\n", lpath); + + vf = fopen(lpath, "r"); + + if (vf) + { + int r; + uchar a; + + r = fread(volname, sizeof (uchar), 8, vf); + + fclose(vf); + + for (x = 0; x < r; x++) + { + a = volname[x]; + if (a == 0x9b) + break; + dfree[14+x] = a; + } + } + else + { + uchar a; + int o; + for (o = strlen(device[cunit].dirname); o > 0; o--) + { + a = device[cunit].dirname[o-1]; + if (a == '/') + break; + } + for (x = 0; x < 8; x++) + { + a = device[cunit].dirname[o+x]; + if (a == '\0') + break; + dfree[14+x] = a; + } + } + + x = 0; + while (x < 8) + { + c |= dfree[14+x]; + x++; + } + + if (c == 0x20) + { + memcpy(dfree + 14, "PCLink ", 8); + dfree[21] = cunit + 0x40; + } + + Debug_printf("DFREE: send info (%d bytes)\n", (int)sizeof(dfree)-1); + + //dfree[64] = calc_checksum(dfree, sizeof(dfree)-1); + pclink_ack(devno, cunit, 'C'); + //com_write(dfree, sizeof(dfree)); + pclink_write(dfree, sizeof(dfree)); // write data + checksum byte + + goto exit; + } + + if (fno == 0x14) /* CHVOL */ + { + FILE *vf; + ulong nl; + char lpath[1024]; + + device[cunit].status.err = 1; + + if (ccom == 'R') + { + pclink_ack(devno, cunit, 'A'); /* ack the command */ + device[cunit].status.err = 176; + Debug_printf("bad exec\n"); + goto complete; + } + + nl = strlen((char *)device[cunit].parbuf.name); + + if (nl == 0) + { + Debug_printf("invalid name\n"); + device[cunit].status.err = 156; + goto complete; + } + + strcpy(lpath, device[cunit].dirname); + strcat(lpath, "/"); + strcat(lpath, DEVICE_LABEL); + + Debug_printf("writing '%s'\n", lpath); + + vf = fopen(lpath, "w"); + + if (vf) + { + int x; + uchar a; + + for (x = 0; x < 8; x++) + { + a = device[cunit].parbuf.name[x]; + if (!a || (a == 0x9b)) + a = 0x20; + (void)fwrite(&a, sizeof(uchar), 1, vf); + } + fclose(vf); + } + else + { + Debug_printf("CHVOL: %s\n", strerror(errno)); + device[cunit].status.err = 255; + } + goto complete; + } + + Debug_printf("fno $%02x: not implemented\n", fno); + device[cunit].status.err = 146; complete: - pclink_ack(devno, cunit, 'C'); + pclink_ack(devno, cunit, 'C'); exit: - old_ccom = ccom; + old_ccom = ccom; - return; + return; } /* @@ -2496,30 +2496,21 @@ pclink_read(uint8_t *buf, int len) // Retrieve data frame from computer Debug_printf("<-SIO read (PCLINK) %hu bytes\n", len); -#ifdef ESP_PLATFORM - UARTManager *uart = SYSTEM_BUS.uart; - - __BEGIN_IGNORE_UNUSEDVARS - size_t l = uart->readBytes(buf, len); - __END_IGNORE_UNUSEDVARS - - // Wait for checksum - while (uart->available() <= 0) - fnSystem.yield(); - uint8_t ck_rcv = uart->read(); -#else - if (fnSioCom.get_sio_mode() == SioCom::sio_mode::NETSIO) +#ifndef ESP_PLATFORM + if (SYSTEM_BUS.get_sio_mode() == SioCom::sio_mode::NETSIO) { - fnSioCom.netsio_write_size(len); // set hint for NetSIO + SYSTEM_BUS.netsio_write_size(len); // set hint for NetSIO } +#endif - size_t l = fnSioCom.readBytes(buf, len); + __BEGIN_IGNORE_UNUSEDVARS + size_t l = SYSTEM_BUS.read(buf, len); + __END_IGNORE_UNUSEDVARS // Wait for checksum - while (0 == fnSioCom.available()) + while (SYSTEM_BUS.available() <= 0) fnSystem.yield(); - uint8_t ck_rcv = fnSioCom.read(); -#endif + uint8_t ck_rcv = SYSTEM_BUS.read(); #ifdef VERBOSE_SIO Debug_printf("RECV <%u> BYTES, checksum: %hu\n\t", (unsigned int)l, ck_rcv); @@ -2547,31 +2538,22 @@ pclink_write(uint8_t *buf, int len) #endif // Write data frame -#ifdef ESP_PLATFORM - UARTManager *uart = SYSTEM_BUS.uart; - uart->write(buf, len); - // Write checksum - uart->write(sio_checksum(buf, len)); - - uart->flush(); -#else - fnSioCom.write(buf, len); + SYSTEM_BUS.write(buf, len); // Write checksum - fnSioCom.write(sio_checksum(buf, len)); + SYSTEM_BUS.write(sio_checksum(buf, len)); - fnSioCom.flush(); -#endif + SYSTEM_BUS.flush(); } static void get_device_status(ushort devno, ushort d, uchar *st) { - //setup_status(d); - st[0] = device[d].status.stat; - st[1] = device[d].status.err; - st[2] = device[d].status.tmot; - st[3] = device[d].status.none; + //setup_status(d); + st[0] = device[d].status.stat; + st[1] = device[d].status.err; + st[2] = device[d].status.tmot; + st[3] = device[d].status.none; } static void @@ -2582,23 +2564,23 @@ pclink_ack(ushort devno, ushort d, uchar what) // call one of sio_ack/sio_nak/sio_complete/sio_error pcLink.send_ack_byte(what); - device[d].status.stat &= ~(0x01|0x04); + device[d].status.stat &= ~(0x01|0x04); - switch (what) - { + switch (what) + { case 'E': - device[d].status.stat |= 0x04; /* last operation failed */ + device[d].status.stat |= 0x04; /* last operation failed */ break; case 'N': device[d].status.stat |= 0x01; break; - } + } fnSystem.delay_microseconds(DELAY_T4); # ifdef SIOTRACE - if (log_flag) - Debug_printf("<- ACK '%c'\n", what); + if (log_flag) + Debug_printf("<- ACK '%c'\n", what); # endif } @@ -2610,9 +2592,9 @@ sioPCLink::sioPCLink() // public wrapper around sio_ack(), sio_nak(), etc... void sioPCLink::send_ack_byte(uint8_t what) { - switch (what) - { - case 'a': + switch (what) + { + case 'a': #ifndef ESP_PLATFORM sio_late_ack(); break; @@ -2629,7 +2611,7 @@ void sioPCLink::send_ack_byte(uint8_t what) case 'E': sio_error(); break; - } + } } void sioPCLink::mount(int no, const char* path) @@ -2673,8 +2655,8 @@ void sioPCLink::unmount(int no) void sioPCLink::sio_status() { // # ifdef SIOTRACE -// if (log_flag) - Debug_printf("STATUS: %02x %02x %02x %02x\n", status[0], status[1], status[2], status[3]); +// if (log_flag) + Debug_printf("STATUS: %02x %02x %02x %02x\n", status[0], status[1], status[2], status[3]); // # endif bus_to_computer(status, sizeof(status), false); } @@ -2685,15 +2667,15 @@ void sioPCLink::sio_process(uint32_t commanddata, uint8_t checksum) cmdFrame.commanddata = commanddata; cmdFrame.checksum = checksum; - uchar cunit = cmdFrame.aux2 & 0x0f; /* PCLink ignores DUNIT */ + uchar cunit = cmdFrame.aux2 & 0x0f; /* PCLink ignores DUNIT */ uchar cdev = SIO_DEVICEID_PCLINK; uchar devno = cdev >> 4; // ??? magical 6 if (!Config.get_pclink_enabled()) - { + { Debug_println("PCLink disabled, ignoring"); - return; - } + return; + } Debug_println("PCLink sio_process()"); @@ -2710,13 +2692,13 @@ void sioPCLink::sio_process(uint32_t commanddata, uint8_t checksum) Debug_println("EXEC"); do_pclink(devno, cmdFrame.comnd, cmdFrame.aux1, cmdFrame.aux2); break; - case 'S': /* status */ + case 'S': /* status */ Debug_println("STATUS"); pclink_ack(devno, cunit, 'A'); get_device_status(devno, cunit, status); sio_status(); break; - case '?': /* send hi-speed index */ + case '?': /* send hi-speed index */ Debug_println("HIGH SPEED INDEX"); pclink_ack(devno, cunit, 'A'); sio_high_speed(); diff --git a/lib/device/sio/siocpm.cpp b/lib/device/sio/siocpm.cpp index 304e0a19f..57e936b3c 100755 --- a/lib/device/sio/siocpm.cpp +++ b/lib/device/sio/siocpm.cpp @@ -57,7 +57,7 @@ void sioCPM::sio_handle_cpm() void sioCPM::init_cpm(int baud) { - FN_CPM_LINK.set_baudrate(baud); + SYSTEM_BUS.setBaudrate(baud); Status = Debug = 0; Break = Step = -1; RAM = (uint8_t *)malloc(MEMSIZE); @@ -89,4 +89,4 @@ void sioCPM::sio_process(uint32_t commanddata, uint8_t checksum) } } -#endif /* BUILD_ATARI */ \ No newline at end of file +#endif /* BUILD_ATARI */ diff --git a/lib/device/sio/udpstream.cpp b/lib/device/sio/udpstream.cpp index 5204e6383..12e6f28c6 100755 --- a/lib/device/sio/udpstream.cpp +++ b/lib/device/sio/udpstream.cpp @@ -8,14 +8,6 @@ #include "fnSystem.h" #include "utils.h" -// TODO: merge/fix this at global level -#ifdef ESP_PLATFORM -#include "fnUART.h" -#define FN_BUS_LINK fnUartBUS -#else -#define FN_BUS_LINK fnSioCom -#endif - void sioUDPStream::sio_enable_udpstream() { if (udpstream_port == MIDI_PORT) @@ -47,7 +39,7 @@ void sioUDPStream::sio_enable_udpstream() #endif // Change baud rate - FN_BUS_LINK.set_baudrate(MIDI_BAUDRATE); + SYSTEM_BUS.setBaudrate(MIDI_BAUDRATE); } // Open the UDP connection @@ -81,7 +73,7 @@ void sioUDPStream::sio_disable_udpstream() #ifdef ESP_PLATFORM ledc_stop(LEDC_ESP32XX_HIGH_SPEED, LEDC_CHANNEL_1, 0); #endif - FN_BUS_LINK.set_baudrate(SIO_STANDARD_BAUDRATE); + SYSTEM_BUS.setBaudrate(SIO_STANDARD_BAUDRATE); } #ifdef ESP_PLATFORM // Reset CKI pin back to output open drain high @@ -101,7 +93,7 @@ void sioUDPStream::sio_handle_udpstream() { udpStream.read(buf_net, UDPSTREAM_BUFFER_SIZE); // Send to Atari UART - FN_BUS_LINK.write(buf_net, packetSize); + SYSTEM_BUS.write(buf_net, packetSize); #ifdef ESP_PLATFORM if (udpstreamIsServer) { @@ -128,7 +120,7 @@ void sioUDPStream::sio_handle_udpstream() #endif // Read the data until there's a pause in the incoming stream - if (FN_BUS_LINK.available() > 0) + if (SYSTEM_BUS.available() > 0) { while (true) { @@ -136,24 +128,24 @@ void sioUDPStream::sio_handle_udpstream() #ifdef ESP_PLATFORM if (fnSystem.digital_read(PIN_CMD) == DIGI_LOW) #else - if (FN_BUS_LINK.command_asserted()) + if (SYSTEM_BUS.command_asserted()) #endif { Debug_println("CMD Asserted in LOOP, stopping UDPStream"); sio_disable_udpstream(); return; } - if (FN_BUS_LINK.available() > 0) + if (SYSTEM_BUS.available() > 0) { // Collect bytes read in our buffer - buf_stream[buf_stream_index] = (unsigned char)FN_BUS_LINK.read(); // TODO apc: check for error first + buf_stream[buf_stream_index] = (unsigned char)SYSTEM_BUS.read(); // TODO apc: check for error first if (buf_stream_index < UDPSTREAM_BUFFER_SIZE - 1) buf_stream_index++; } else { fnSystem.delay_microseconds(UDPSTREAM_PACKET_TIMEOUT); - if (FN_BUS_LINK.available() <= 0) + if (SYSTEM_BUS.available() <= 0) break; } } diff --git a/lib/hardware/fnUART.cpp b/lib/hardware/fnUART.cpp index 1c82b5bf7..ebaf53f88 100644 --- a/lib/hardware/fnUART.cpp +++ b/lib/hardware/fnUART.cpp @@ -22,12 +22,7 @@ #define MAX_WRITE_BUFFER_TICKS 1000 // Serial "debug port" -UARTManager fnUartDebug(FN_UART_DEBUG); - -// Serial "bus port" (CoCo uses fnDwCom - configurable serial or TCP (Becker) drivewire port) -#ifndef BUILD_COCO -UARTManager fnUartBUS(FN_UART_BUS); -#endif +UARTManager fnDebugConsole(FN_UART_DEBUG); // Constructor UARTManager::UARTManager(uart_port_t uart_num) : _uart_num(uart_num), _uart_q(NULL) {} @@ -259,7 +254,7 @@ int UARTManager::read(void) /* Since the underlying Stream calls this Read() multiple times to get more than one * character for ReadBytes(), we override with a single call to uart_read_bytes */ -size_t UARTManager::readBytes(uint8_t *buffer, size_t length) +size_t UARTManager::readBytes(void *buffer, size_t length) { int result = uart_read_bytes(_uart_num, buffer, length, MAX_READ_WAIT_TICKS); #ifdef DEBUG @@ -285,7 +280,7 @@ size_t UARTManager::write(uint8_t c) return z; } -size_t UARTManager::write(const uint8_t *buffer, size_t size) +size_t UARTManager::write(const void *buffer, size_t size) { int z = uart_write_bytes(_uart_num, (const char *)buffer, size); // uart_wait_tx_done(_uart_num, MAX_WRITE_BUFFER_TICKS); diff --git a/lib/hardware/fnUART.h b/lib/hardware/fnUART.h index def83928d..90d70090e 100644 --- a/lib/hardware/fnUART.h +++ b/lib/hardware/fnUART.h @@ -71,11 +71,11 @@ class UARTManager void flush_input(); int read(); - size_t readBytes(uint8_t *buffer, size_t length); + size_t readBytes(void *buffer, size_t length); size_t readBytes(char *buffer, size_t length) { return readBytes((uint8_t *)buffer, length); }; size_t write(uint8_t); - size_t write(const uint8_t *buffer, size_t size); + size_t write(const void *buffer, size_t size); size_t write(const char *s); size_t write(unsigned long n) { return write((uint8_t)n); }; @@ -158,11 +158,7 @@ class UARTManager #ifdef ESP_PLATFORM // Serial "debug port" for FN-ESP (not available on FN-PC) - extern UARTManager fnUartDebug; - // Serial "bus port" (CoCo uses fnDwCom - configurable serial or TCP (Becker) drivewire port) - #ifndef BUILD_COCO - extern UARTManager fnUartBUS; - #endif + extern UARTManager fnDebugConsole; #endif #endif //FNUART_H diff --git a/lib/http/httpService.cpp b/lib/http/httpService.cpp index 4b580be56..8b282e8c2 100644 --- a/lib/http/httpService.cpp +++ b/lib/http/httpService.cpp @@ -687,7 +687,7 @@ esp_err_t fnHttpService::get_handler_mount(httpd_req_t *req) #ifdef BUILD_APPLE DEVICE_TYPE *disk_dev = theFuji.get_disk_dev(ds); #else - DEVICE_TYPE *disk_dev = &disk->disk_dev; + DEVICE_TYPE *disk_dev = &disk->disk_dev; #endif disk->fileh = host->fnfile_open(qp.query_parsed["filename"].c_str(), (char *)qp.query_parsed["filename"].c_str(), qp.query_parsed["filename"].length() + 1, flag); @@ -837,7 +837,7 @@ esp_err_t fnHttpService::get_handler_term(httpd_req_t *req) if (ws_pkt.len) { - buf = (uint8_t *)calloc(sizeof(uint8_t), ws_pkt.len + 1); + buf = (uint8_t *)calloc(ws_pkt.len + 1, sizeof(uint8_t)); if (buf == NULL) return ESP_ERR_NO_MEM; else @@ -886,7 +886,7 @@ esp_err_t fnHttpService::get_handler_kybd(httpd_req_t *req) if (ws_pkt.len) { - buf = (uint8_t *)calloc(sizeof(uint8_t), ws_pkt.len + 1); + buf = (uint8_t *)calloc(ws_pkt.len + 1, sizeof(uint8_t)); if (buf == NULL) return ESP_ERR_NO_MEM; else diff --git a/lib/http/httpServiceConfigurator.cpp b/lib/http/httpServiceConfigurator.cpp index 669395ddd..912d9153f 100644 --- a/lib/http/httpServiceConfigurator.cpp +++ b/lib/http/httpServiceConfigurator.cpp @@ -544,6 +544,7 @@ void fnHttpServiceConfigurator::config_serial(std::string port, std::string baud { Config.save(); +#ifdef UNUSED #if defined(BUILD_ATARI) if (fnSioCom.get_sio_mode() == SioCom::sio_mode::SERIAL) { @@ -570,6 +571,7 @@ void fnHttpServiceConfigurator::config_serial(std::string port, std::string baud fnDwCom.begin(Config.get_serial_baud()); } #endif +#endif /* UNUSED */ } } #elif defined(BUILD_RS232) @@ -614,7 +616,7 @@ void fnHttpServiceConfigurator::config_boip(std::string enable_boip, std::string // Update settings (on ESP reboot is needed) #ifndef ESP_PLATFORM #if defined(BUILD_ATARI) - fnSioCom.set_netsio_host(Config.get_boip_host().c_str(), Config.get_boip_port()); + SYSTEM_BUS.set_netsio_host(Config.get_boip_host().c_str(), Config.get_boip_port()); #elif defined(BUILD_COCO) fnDwCom.set_becker_host(Config.get_boip_host().c_str(), Config.get_boip_port()); #endif @@ -628,7 +630,7 @@ void fnHttpServiceConfigurator::config_boip(std::string enable_boip, std::string // Apply settings (on ESP reboot is needed) #ifndef ESP_PLATFORM #if defined(BUILD_ATARI) - fnSioCom.reset_sio_port(Config.get_boip_enabled() ? SioCom::sio_mode::NETSIO : SioCom::sio_mode::SERIAL); + SYSTEM_BUS.reset_sio_port(Config.get_boip_enabled() ? SioCom::sio_mode::NETSIO : SioCom::sio_mode::SERIAL); #elif defined(BUILD_COCO) fnDwCom.reset_drivewire_port(Config.get_boip_enabled() ? DwCom::dw_mode::BECKER : DwCom::dw_mode::SERIAL); #endif diff --git a/lib/runcpm/abstraction_fujinet.h b/lib/runcpm/abstraction_fujinet.h index 3575c5b3f..f98e50033 100644 --- a/lib/runcpm/abstraction_fujinet.h +++ b/lib/runcpm/abstraction_fujinet.h @@ -24,31 +24,25 @@ #include "fuji.h" -#ifdef ESP_PLATFORM -#define FN_CPM_LINK fnUartBUS -#else -#define FN_CPM_LINK fnSioCom -#endif - #define HostOS 0x07 // FUJINET typedef struct { - uint8_t dr; - uint8_t fn[8]; - uint8_t tp[3]; - uint8_t ex, s1, s2, rc; - uint8_t al[16]; - uint8_t cr, r0, r1, r2; + uint8_t dr; + uint8_t fn[8]; + uint8_t tp[3]; + uint8_t ex, s1, s2, rc; + uint8_t al[16]; + uint8_t cr, r0, r1, r2; } CPM_FCB; typedef struct { - uint8_t dr; - uint8_t fn[8]; - uint8_t tp[3]; - uint8_t ex, s1, s2, rc; - uint8_t al[16]; + uint8_t dr; + uint8_t fn[8]; + uint8_t tp[3]; + uint8_t ex, s1, s2, rc; + uint8_t al[16]; } CPM_DIRENTRY; int dirPos; @@ -62,10 +56,10 @@ unsigned short portActive = 0; char *full_path(char *fn) { - memset(full_filename, 0, sizeof(full_filename)); - strcpy(full_filename, "/CPM/"); - strcat(full_filename, fn); - return full_filename; + memset(full_filename, 0, sizeof(full_filename)); + strcpy(full_filename, "/CPM/"); + strcat(full_filename, fn); + return full_filename; } @@ -77,32 +71,32 @@ void _HardwareOut(const uint32 Port, const uint32 Value) { } uint32 _HardwareIn(const uint32 Port) { - return 0; + return 0; } /* Memory abstraction functions */ /*===============================================================================*/ bool _RamLoad(char *fn, uint16_t address) { - FILE *f = fnSDFAT.file_open(full_path(fn), "r"); - bool result = false; - uint8_t b; - - if (f) - { - while (!feof(f)) - { - if (fread(&b, sizeof(uint8_t), 1, f) == 1) - { - _RamWrite(address++, b); - result = true; - } - else - result = false; - } - fclose(f); - } - return (result); + FILE *f = fnSDFAT.file_open(full_path(fn), "r"); + bool result = false; + uint8_t b; + + if (f) + { + while (!feof(f)) + { + if (fread(&b, sizeof(uint8_t), 1, f) == 1) + { + _RamWrite(address++, b); + result = true; + } + else + result = false; + } + fclose(f); + } + return (result); } /* filesystem (disk) abstraction fuctions */ @@ -112,260 +106,260 @@ FILE *userdir; bool _sys_exists(uint8* filename) { - return fnSDFAT.exists(full_path((char *)filename)); + return fnSDFAT.exists(full_path((char *)filename)); } int _sys_fputc(uint8_t ch, FILE *f) { - return fputc(ch, f); + return fputc(ch, f); } void _sys_fflush(FILE *f) { - fflush(f); + fflush(f); } void _sys_fclose(FILE *f) { - fclose(f); + fclose(f); } int _sys_select(uint8_t *disk) { - return fnSDFAT.exists(full_path((char *)disk)); + return fnSDFAT.exists(full_path((char *)disk)); } long _sys_filesize(uint8_t *fn) { - unsigned long fs = -1; - FILE *fp = fnSDFAT.file_open(full_path((char *)fn), "r"); + unsigned long fs = -1; + FILE *fp = fnSDFAT.file_open(full_path((char *)fn), "r"); - if (fp) - { - fseek(fp, 0L, SEEK_END); - fs = ftell(fp); - } + if (fp) + { + fseek(fp, 0L, SEEK_END); + fs = ftell(fp); + } - fclose(fp); - return fs; + fclose(fp); + return fs; } int _sys_openfile(uint8_t *fn) { - FILE *fp = fnSDFAT.file_open(full_path((char *)fn), "r"); - if (fp) - { - fclose(fp); - return 1; - } - else - return 0; + FILE *fp = fnSDFAT.file_open(full_path((char *)fn), "r"); + if (fp) + { + fclose(fp); + return 1; + } + else + return 0; } int _sys_makefile(uint8_t *fn) { - FILE *fp = fnSDFAT.file_open(full_path((char *)fn), "w"); - if (fp) - { - fclose(fp); - return true; - } - else - return false; + FILE *fp = fnSDFAT.file_open(full_path((char *)fn), "w"); + if (fp) + { + fclose(fp); + return true; + } + else + return false; } int _sys_deletefile(uint8_t *fn) { - return fnSDFAT.remove(full_path((char *)fn)); + return fnSDFAT.remove(full_path((char *)fn)); } int _sys_renamefile(uint8_t *fn, uint8_t *newname) { - std::string from, to; + std::string from, to; - from = std::string(full_path((char *)fn)); - to = std::string(full_path((char *)newname)); + from = std::string(full_path((char *)fn)); + to = std::string(full_path((char *)newname)); - return fnSDFAT.rename(from.c_str(), to.c_str()); + return fnSDFAT.rename(from.c_str(), to.c_str()); } void _sys_logbuffer(uint8_t *buffer) { - // not implemented at present. + // not implemented at present. } bool _sys_extendfile(char *fn, unsigned long fpos) { - FILE *fp = fnSDFAT.file_open(full_path((char *)fn), "a"); + FILE *fp = fnSDFAT.file_open(full_path((char *)fn), "a"); - if (!fp) - return false; + if (!fp) + return false; - long origSize = fnSDFAT.filesize(full_path(fn)); + long origSize = fnSDFAT.filesize(full_path(fn)); - // This was patterned after the arduino abstraction, and I do not like how this works. + // This was patterned after the arduino abstraction, and I do not like how this works. - if (fpos > origSize) - { - for (long i = 0; i < (origSize - fpos); ++i) - { - if (fwrite("\0", sizeof(uint8_t), 1, fp) != 1) - { - fclose(fp); - return false; - } - } - } - fclose(fp); - return true; + if (fpos > origSize) + { + for (long i = 0; i < (origSize - fpos); ++i) + { + if (fwrite("\0", sizeof(uint8_t), 1, fp) != 1) + { + fclose(fp); + return false; + } + } + } + fclose(fp); + return true; } uint8_t _sys_readseq(uint8_t *fn, long fpos) { - uint8_t result = 0xff; - FILE *f; - uint8_t bytesread; - uint8_t dmabuf[BlkSZ]; - int seekErr; - - f = fnSDFAT.file_open(full_path((char *)fn), "r"); - if (!f) - { - result = 0x10; - return result; - } - seekErr = fseek(f, fpos, SEEK_SET); - if (f) - { - if (fpos > 0 && seekErr != 0) - { - // EOF - result = 0x01; - } - else - { - // set DMA buffer to EOF - memset(dmabuf, 0x1a, BlkSZ); - bytesread = fread(&dmabuf[0], BlkSZ, sizeof(uint8_t), f); - if (bytesread) - memcpy((uint8_t *)&RAM[dmaAddr], dmabuf, BlkSZ); - result = bytesread ? 0x00 : 0x01; - } - } - else - { - result = 0x10; - } - fclose(f); - return (result); + uint8_t result = 0xff; + FILE *f; + uint8_t bytesread; + uint8_t dmabuf[BlkSZ]; + int seekErr; + + f = fnSDFAT.file_open(full_path((char *)fn), "r"); + if (!f) + { + result = 0x10; + return result; + } + seekErr = fseek(f, fpos, SEEK_SET); + if (f) + { + if (fpos > 0 && seekErr != 0) + { + // EOF + result = 0x01; + } + else + { + // set DMA buffer to EOF + memset(dmabuf, 0x1a, BlkSZ); + bytesread = fread(&dmabuf[0], BlkSZ, sizeof(uint8_t), f); + if (bytesread) + memcpy((uint8_t *)&RAM[dmaAddr], dmabuf, BlkSZ); + result = bytesread ? 0x00 : 0x01; + } + } + else + { + result = 0x10; + } + fclose(f); + return (result); } uint8_t _sys_writeseq(uint8_t *fn, long fpos) { - uint8_t result = 0xff; - FILE *f; - - if (_sys_extendfile((char *)fn, fpos)) - f = fnSDFAT.file_open(full_path((char *)fn), "r+"); - else - return result; - - if (f) - { - if (fseek(f, fpos, SEEK_SET) == 0) - { - if (fwrite(_RamSysAddr(dmaAddr), BlkSZ, sizeof(uint8_t), f)) - result = 0x00; - } - else - { - result = 0x01; - } - } - else - { - result = 0x10; - } - fclose(f); - return (result); + uint8_t result = 0xff; + FILE *f; + + if (_sys_extendfile((char *)fn, fpos)) + f = fnSDFAT.file_open(full_path((char *)fn), "r+"); + else + return result; + + if (f) + { + if (fseek(f, fpos, SEEK_SET) == 0) + { + if (fwrite(_RamSysAddr(dmaAddr), BlkSZ, sizeof(uint8_t), f)) + result = 0x00; + } + else + { + result = 0x01; + } + } + else + { + result = 0x10; + } + fclose(f); + return (result); } uint8_t _sys_readrand(uint8_t *fn, long fpos) { - uint8 result = 0xff; - FILE *f; - uint8 bytesread; - uint8 dmabuf[BlkSZ]; - long extSize; - - f = fnSDFAT.file_open(full_path((char *)fn), "r+"); - if (f) - { - if (fseek(f, fpos, SEEK_SET) == 0) - { - memset(dmabuf, 0x1A, BlkSZ); - bytesread = fread(&dmabuf[0], BlkSZ, sizeof(uint8_t), f); - if (bytesread) - memcpy((uint8_t *)&RAM[dmaAddr], dmabuf, BlkSZ); - result = bytesread ? 0x00 : 0x01; - } - else - { - if (fpos >= 65536L * BlkSZ) - { - result = 0x06; // seek past 8MB (largest file size in CP/M) - } - else - { - extSize = _sys_filesize((uint8_t *)full_path((char *)fn)); - - // round file size up to next full logical extent - extSize = ExtSZ * ((extSize / ExtSZ) + ((extSize % ExtSZ) ? 1 : 0)); - if (fpos < extSize) - result = 0x01; // reading unwritten data - else - result = 0x04; // seek to unwritten extent - } - } - } - else - { - result = 0x10; - } - fclose(f); - return (result); + uint8 result = 0xff; + FILE *f; + uint8 bytesread; + uint8 dmabuf[BlkSZ]; + long extSize; + + f = fnSDFAT.file_open(full_path((char *)fn), "r+"); + if (f) + { + if (fseek(f, fpos, SEEK_SET) == 0) + { + memset(dmabuf, 0x1A, BlkSZ); + bytesread = fread(&dmabuf[0], BlkSZ, sizeof(uint8_t), f); + if (bytesread) + memcpy((uint8_t *)&RAM[dmaAddr], dmabuf, BlkSZ); + result = bytesread ? 0x00 : 0x01; + } + else + { + if (fpos >= 65536L * BlkSZ) + { + result = 0x06; // seek past 8MB (largest file size in CP/M) + } + else + { + extSize = _sys_filesize((uint8_t *)full_path((char *)fn)); + + // round file size up to next full logical extent + extSize = ExtSZ * ((extSize / ExtSZ) + ((extSize % ExtSZ) ? 1 : 0)); + if (fpos < extSize) + result = 0x01; // reading unwritten data + else + result = 0x04; // seek to unwritten extent + } + } + } + else + { + result = 0x10; + } + fclose(f); + return (result); } uint8_t _sys_writerand(uint8_t *fn, long fpos) { - uint8 result = 0xff; - FILE *f; - - if (_sys_extendfile((char *)fn, fpos)) - { - f = fnSDFAT.file_open(full_path((char *)fn), "r+"); - } - else - return result; - - if (f) - { - if (fseek(f, fpos, SEEK_SET) == 0) - { - if (fwrite(_RamSysAddr(dmaAddr), BlkSZ, sizeof(uint8_t), f)) - result = 0x00; - } - else - { - result = 0x06; - } - } - else - { - result = 0x10; - } - fclose(f); - return (result); + uint8 result = 0xff; + FILE *f; + + if (_sys_extendfile((char *)fn, fpos)) + { + f = fnSDFAT.file_open(full_path((char *)fn), "r+"); + } + else + return result; + + if (f) + { + if (fseek(f, fpos, SEEK_SET) == 0) + { + if (fwrite(_RamSysAddr(dmaAddr), BlkSZ, sizeof(uint8_t), f)) + result = 0x00; + } + else + { + result = 0x06; + } + } + else + { + result = 0x10; + } + fclose(f); + return (result); } uint8_t findNextDirName[17]; @@ -376,135 +370,135 @@ uint16_t firstFreeAllocBlock; uint8_t _findnext(uint8_t isdir) { - uint8 result = 0xff; - bool isfile; - uint32 bytes; - fsdir_entry *entry; - - if (allExtents && fileRecords) - { - _mockupDirEntry(); - result = 0; - } - else - { - while ((entry = fnSDFAT.dir_read())) - { - strcpy((char *)findNextDirName, entry->filename); // careful watch for string overflow! - isfile = !entry->isDir; - bytes = entry->size; - if (!isfile) - continue; - _HostnameToFCBname(findNextDirName, fcbname); - if (match(fcbname, pattern)) - { - if (isdir) - { - // account for host files that aren't multiples of the block size - // by rounding their bytes up to the next multiple of blocks - if (bytes & (BlkSZ - 1)) - { - bytes = (bytes & ~(BlkSZ - 1)) + BlkSZ; - } - fileRecords = bytes / BlkSZ; - fileExtents = fileRecords / BlkEX + ((fileRecords & (BlkEX - 1)) ? 1 : 0); - fileExtentsUsed = 0; - firstFreeAllocBlock = firstBlockAfterDir; - _mockupDirEntry(); - } - else - { - fileRecords = 0; - fileExtents = 0; - fileExtentsUsed = 0; - firstFreeAllocBlock = firstBlockAfterDir; - } - _RamWrite(tmpFCB, filename[0] - '@'); - _HostnameToFCB(tmpFCB, findNextDirName); - result = 0x00; - break; - } - } - } - return (result); + uint8 result = 0xff; + bool isfile; + uint32 bytes; + fsdir_entry *entry; + + if (allExtents && fileRecords) + { + _mockupDirEntry(); + result = 0; + } + else + { + while ((entry = fnSDFAT.dir_read())) + { + strcpy((char *)findNextDirName, entry->filename); // careful watch for string overflow! + isfile = !entry->isDir; + bytes = entry->size; + if (!isfile) + continue; + _HostnameToFCBname(findNextDirName, fcbname); + if (match(fcbname, pattern)) + { + if (isdir) + { + // account for host files that aren't multiples of the block size + // by rounding their bytes up to the next multiple of blocks + if (bytes & (BlkSZ - 1)) + { + bytes = (bytes & ~(BlkSZ - 1)) + BlkSZ; + } + fileRecords = bytes / BlkSZ; + fileExtents = fileRecords / BlkEX + ((fileRecords & (BlkEX - 1)) ? 1 : 0); + fileExtentsUsed = 0; + firstFreeAllocBlock = firstBlockAfterDir; + _mockupDirEntry(); + } + else + { + fileRecords = 0; + fileExtents = 0; + fileExtentsUsed = 0; + firstFreeAllocBlock = firstBlockAfterDir; + } + _RamWrite(tmpFCB, filename[0] - '@'); + _HostnameToFCB(tmpFCB, findNextDirName); + result = 0x00; + break; + } + } + } + return (result); } uint8_t _findfirst(uint8_t isdir) { - uint8 path[4] = {'?', FOLDERCHAR, '?', 0}; - path[0] = filename[0]; - path[2] = filename[2]; - fnSDFAT.dir_close(); - fnSDFAT.dir_open(full_path((char *)path), "*", 0); - _HostnameToFCBname(filename, pattern); - fileRecords = 0; - fileExtents = 0; - fileExtentsUsed = 0; - return (_findnext(isdir)); + uint8 path[4] = {'?', FOLDERCHAR, '?', 0}; + path[0] = filename[0]; + path[2] = filename[2]; + fnSDFAT.dir_close(); + fnSDFAT.dir_open(full_path((char *)path), "*", 0); + _HostnameToFCBname(filename, pattern); + fileRecords = 0; + fileExtents = 0; + fileExtentsUsed = 0; + return (_findnext(isdir)); } uint8_t _findnextallusers(uint8_t isdir) { - return _findnext(isdir); + return _findnext(isdir); } uint8_t _findfirstallusers(uint8_t isdir) { - dirPos = 0; - strcpy((char *)pattern, "???????????"); - fileRecords = 0; - fileExtents = 0; - fileExtentsUsed = 0; - return (_findnextallusers(isdir)); + dirPos = 0; + strcpy((char *)pattern, "???????????"); + fileRecords = 0; + fileExtents = 0; + fileExtentsUsed = 0; + return (_findnextallusers(isdir)); } uint8_t _Truncate(char *fn, uint8_t rc) { - // Implement some other way. - return 0; + // Implement some other way. + return 0; } void _MakeUserDir() { - uint8 dFolder = cDrive + 'A'; - uint8 uFolder = toupper(tohex(userCode)); + uint8 dFolder = cDrive + 'A'; + uint8 uFolder = toupper(tohex(userCode)); - uint8 path[4] = {dFolder, FOLDERCHAR, uFolder, 0}; + uint8 path[4] = {dFolder, FOLDERCHAR, uFolder, 0}; - if (fnSDFAT.exists(full_path((char *)path))) - { - return; - } + if (fnSDFAT.exists(full_path((char *)path))) + { + return; + } - fnSDFAT.create_path(full_path((char *)path)); + fnSDFAT.create_path(full_path((char *)path)); } uint8_t _sys_makedisk(uint8_t drive) { - uint8 result = 0; - if (drive < 1 || drive > 16) - { - result = 0xff; - } - else - { - uint8 dFolder = drive + '@'; - uint8 disk[2] = {dFolder, 0}; - - if (fnSDFAT.exists(full_path((char *)disk))) - return 0; - - if (!fnSDFAT.create_path(full_path((char *)disk))) - { - result = 0xfe; - } - else - { - uint8 path[4] = {dFolder, FOLDERCHAR, '0', 0}; - fnSDFAT.create_path(full_path((char *)path)); - } - } - return (result); + uint8 result = 0; + if (drive < 1 || drive > 16) + { + result = 0xff; + } + else + { + uint8 dFolder = drive + '@'; + uint8 disk[2] = {dFolder, 0}; + + if (fnSDFAT.exists(full_path((char *)disk))) + return 0; + + if (!fnSDFAT.create_path(full_path((char *)disk))) + { + result = 0xfe; + } + else + { + uint8 path[4] = {dFolder, FOLDERCHAR, '0', 0}; + fnSDFAT.create_path(full_path((char *)path)); + } + } + return (result); } /* Console abstraction functions */ @@ -512,47 +506,47 @@ uint8_t _sys_makedisk(uint8_t drive) int _kbhit(void) { - return FN_CPM_LINK.available(); + return SYSTEM_BUS.available(); } uint8_t _getch(void) { - if (teeMode == true) - { - while (FN_CPM_LINK.available() > 0) - { - if (client.available()) - { - uint8_t ch; - client.read(&ch, 1); - return ch & 0x7F; - } - } - return FN_CPM_LINK.read() & 0x7F; - } - else - { - while (FN_CPM_LINK.available() <= 0) - { - } - return FN_CPM_LINK.read() & 0x7f; - } + if (teeMode == true) + { + while (SYSTEM_BUS.available() > 0) + { + if (client.available()) + { + uint8_t ch; + client.read(&ch, 1); + return ch & 0x7F; + } + } + return SYSTEM_BUS.read() & 0x7F; + } + else + { + while (SYSTEM_BUS.available() <= 0) + { + } + return SYSTEM_BUS.read() & 0x7f; + } } uint8_t _getche(void) { - uint8_t ch = _getch() & 0x7f; - FN_CPM_LINK.write(ch); - if (teeMode == true) - client.write(ch); - return ch; + uint8_t ch = _getch() & 0x7f; + SYSTEM_BUS.write(ch); + if (teeMode == true) + client.write(ch); + return ch; } void _putch(uint8_t ch) { - FN_CPM_LINK.write(ch & 0x7f); - if (teeMode == true) - client.write(ch); + SYSTEM_BUS.write(ch & 0x7f); + if (teeMode == true) + client.write(ch); } void _clrscr(void) @@ -561,141 +555,141 @@ void _clrscr(void) uint8_t bdos_networkConfig(uint16_t addr) { - // Response to SIO_FUJICMD_GET_ADAPTERCONFIG - struct - { - char ssid[32]; - char hostname[64]; - unsigned char localIP[4]; - unsigned char gateway[4]; - unsigned char netmask[4]; - unsigned char dnsIP[4]; - unsigned char macAddress[6]; - unsigned char bssid[6]; - char fn_version[15]; - } cfg; - - memset(&cfg, 0, sizeof(cfg)); - - strlcpy(cfg.fn_version, fnSystem.get_fujinet_version(true), sizeof(cfg.fn_version)); - - if (!fnWiFi.connected()) - { - strlcpy(cfg.ssid, "NOT CONNECTED", sizeof(cfg.ssid)); - } - else - { - strlcpy(cfg.hostname, fnSystem.Net.get_hostname().c_str(), sizeof(cfg.hostname)); - strlcpy(cfg.ssid, fnWiFi.get_current_ssid().c_str(), sizeof(cfg.ssid)); - fnWiFi.get_current_bssid(cfg.bssid); - fnSystem.Net.get_ip4_info(cfg.localIP, cfg.netmask, cfg.gateway); - fnSystem.Net.get_ip4_dns_info(cfg.dnsIP); - } - - fnWiFi.get_mac(cfg.macAddress); - - // Transfer to Z80 RAM. - memset(&RAM[addr], 0, sizeof(cfg)); - memcpy(&RAM[addr], &cfg, sizeof(cfg)); - - return 0; + // Response to SIO_FUJICMD_GET_ADAPTERCONFIG + struct + { + char ssid[32]; + char hostname[64]; + unsigned char localIP[4]; + unsigned char gateway[4]; + unsigned char netmask[4]; + unsigned char dnsIP[4]; + unsigned char macAddress[6]; + unsigned char bssid[6]; + char fn_version[15]; + } cfg; + + memset(&cfg, 0, sizeof(cfg)); + + strlcpy(cfg.fn_version, fnSystem.get_fujinet_version(true), sizeof(cfg.fn_version)); + + if (!fnWiFi.connected()) + { + strlcpy(cfg.ssid, "NOT CONNECTED", sizeof(cfg.ssid)); + } + else + { + strlcpy(cfg.hostname, fnSystem.Net.get_hostname().c_str(), sizeof(cfg.hostname)); + strlcpy(cfg.ssid, fnWiFi.get_current_ssid().c_str(), sizeof(cfg.ssid)); + fnWiFi.get_current_bssid(cfg.bssid); + fnSystem.Net.get_ip4_info(cfg.localIP, cfg.netmask, cfg.gateway); + fnSystem.Net.get_ip4_dns_info(cfg.dnsIP); + } + + fnWiFi.get_mac(cfg.macAddress); + + // Transfer to Z80 RAM. + memset(&RAM[addr], 0, sizeof(cfg)); + memcpy(&RAM[addr], &cfg, sizeof(cfg)); + + return 0; } uint8_t bdos_readHostSlots(uint16_t addr) { - char hostSlots[8][32]; - memset(hostSlots, 0, sizeof(hostSlots)); + char hostSlots[8][32]; + memset(hostSlots, 0, sizeof(hostSlots)); - for (int i = 0; i < 8; i++) - strlcpy(hostSlots[i], theFuji.get_hosts(i)->get_hostname(), 32); + for (int i = 0; i < 8; i++) + strlcpy(hostSlots[i], theFuji.get_hosts(i)->get_hostname(), 32); - memset(&RAM[addr], 0, sizeof(hostSlots)); - memcpy(&RAM[addr], &hostSlots, sizeof(hostSlots)); - return 0; + memset(&RAM[addr], 0, sizeof(hostSlots)); + memcpy(&RAM[addr], &hostSlots, sizeof(hostSlots)); + return 0; } uint8_t bdos_readDeviceSlots(uint16_t addr) { - struct disk_slot - { - uint8_t hostSlot; - uint8_t mode; - char filename[MAX_DISPLAY_FILENAME_LEN]; - }; - disk_slot diskSlots[MAX_DISK_DEVICES]; + struct disk_slot + { + uint8_t hostSlot; + uint8_t mode; + char filename[MAX_DISPLAY_FILENAME_LEN]; + }; + disk_slot diskSlots[MAX_DISK_DEVICES]; - // Load the data from our current device array - for (int i = 0; i < MAX_DISK_DEVICES; i++) - { - diskSlots[i].mode = theFuji.get_disks(i)->access_mode; - diskSlots[i].hostSlot = theFuji.get_disks(i)->host_slot; - strlcpy(diskSlots[i].filename, theFuji.get_disks(i)->filename, MAX_DISPLAY_FILENAME_LEN); - } + // Load the data from our current device array + for (int i = 0; i < MAX_DISK_DEVICES; i++) + { + diskSlots[i].mode = theFuji.get_disks(i)->access_mode; + diskSlots[i].hostSlot = theFuji.get_disks(i)->host_slot; + strlcpy(diskSlots[i].filename, theFuji.get_disks(i)->filename, MAX_DISPLAY_FILENAME_LEN); + } - // Transfer to Z80 RAM. - memset(&RAM[addr], 0, sizeof(diskSlots)); - memcpy(&RAM[addr], &diskSlots, sizeof(diskSlots)); + // Transfer to Z80 RAM. + memset(&RAM[addr], 0, sizeof(diskSlots)); + memcpy(&RAM[addr], &diskSlots, sizeof(diskSlots)); - return 0; + return 0; } uint8_t bios_tcpListen(uint16_t port) { - Debug_printf("Do we get here?\r\n"); + Debug_printf("Do we get here?\r\n"); - if (client.connected()) - client.stop(); + if (client.connected()) + client.stop(); - if (server != nullptr && port != portActive) - { - server->stop(); - delete server; - } + if (server != nullptr && port != portActive) + { + server->stop(); + delete server; + } - server = new fnTcpServer(port,1); + server = new fnTcpServer(port,1); - int res = server->begin(port); - if (res == 0) - { - Debug_printf("bios_tcpListen - failed to open port %u\nError (%d): %s\r\n", port, errno, strerror(errno)); - return true; - } - else - { - Debug_printf("bios_tcpListen - Now listening on port %u\r\n", port); - return false; - } + int res = server->begin(port); + if (res == 0) + { + Debug_printf("bios_tcpListen - failed to open port %u\nError (%d): %s\r\n", port, errno, strerror(errno)); + return true; + } + else + { + Debug_printf("bios_tcpListen - Now listening on port %u\r\n", port); + return false; + } } uint8_t bios_tcpAvailable(void) { - if (server == nullptr) - return 0; + if (server == nullptr) + return 0; - return server->hasClient(); + return server->hasClient(); } uint8_t bios_tcpTeeAccept(void) { - if (server == nullptr) - return false; + if (server == nullptr) + return false; - if (server->hasClient()) - client = server->accept(); + if (server->hasClient()) + client = server->accept(); - teeMode = true; + teeMode = true; - return client.connected(); + return client.connected(); } uint8_t bios_tcpDrop(void) { - if (server == nullptr) - return false; + if (server == nullptr) + return false; - client.stop(); + client.stop(); - return true; + return true; } #endif /* ABSTRACTION_FUJINET_H */ diff --git a/src/main.cpp b/src/main.cpp index 9443e9d63..f3344edc2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -273,11 +273,6 @@ void main_setup(int argc, char *argv[]) SYSTEM_BUS.addDevice(ptr, SIO_DEVICEID_PRINTER + fnPrinters.get_port(0)); // P: sioR = new modem(ptrfs, Config.get_modem_sniffer_enabled()); // Config/User selected sniffer enable -#ifdef ESP_PLATFORM - SYSTEM_BUS.set_uart(&fnUartBUS); -#else - SYSTEM_BUS.set_uart(&fnSioCom); -#endif SYSTEM_BUS.addDevice(sioR, SIO_DEVICEID_RS232); // R: