diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..142c793 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +*.exe +*.sld +*.labels +*.tmp +*.bak +*.lst +*.list +.tmp/ diff --git a/README.md b/README.md index a2fc821..b38212f 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,12 @@ ESPKit for Sprinter computer ============================ -Библиотеки и приложения для работы с картой Sprinter-WiFi на базе модуля ESP8266. +Библиотека и приложения для карты Sprinter-WiFi, ISA8-карты на модуле ESP8266 (ESP12-E,ESP12F). + +Исходные коды для [Sprinter DSS](sources/DSS) и для [MS-DOS](sources/DOS) + +[Sprinter-WiFi](https://github.com/romychs/SprinterESP) + +[Спринтер в Телеграм](https://t.me/zx_sprinter) + +[Спринтер в Web](https://www.sprinter.ru/) diff --git a/sources/espdef.h b/sources/DOS/espdef.h similarity index 100% rename from sources/espdef.h rename to sources/DOS/espdef.h diff --git a/sources/DOS/esplib.c b/sources/DOS/esplib.c new file mode 100644 index 0000000..9ca453b --- /dev/null +++ b/sources/DOS/esplib.c @@ -0,0 +1,339 @@ +/* +================================================== + Implementation of Sprinter-WiFi ISA Card Library + Author: Roman A. Boykov + License: BSD 3-Clause +================================================== +*/ + +#include +#include +#include +#include +#include "esplib.h" + +#ifdef ESTEX +#pragma nonrec +#define outb(port, b) mset(port, b); +#define inb(port) mget(port); +#else +#define outb(port, b) outp(port, b); +#define inb(port) inp(port); +#endif + +void util_delay(unsigned delay_ms) +{ +#ifdef ESTEX + if (delay_ms == 0) + { + delay_ms = 20; + } + unsigned ctr; + for (ctr = 0; ctr < delay_ms * 1000; ctr++) + { + } +#else + clock_t t; + t = clock() + delay_ms; + while (clock() < t) + { + } + + // delay(delay_ms); +#endif +} + +char save_mmu3 = 0; // Variable to save Sprinter memory mapping +char isa_slot = -1; // Variable to storeISA slot number where WiFi card found + +char isa_init() +{ + char wifi_found; + wifi_found = find_wifi(); + if (wifi_found) + { + isa_reset(); + return 1; + } + else + { + return 0; + } +} + +void isa_reset() +{ +#ifdef ESTEX + outp(port_isa, ISA_RESET | ISA_AEN); // RESET=1 AEN=1 + delay(20); + outp(port_isa, 0); // RESET=0 AEN=0 + delay(40); +#endif +} + +void isa_open() +{ +#ifdef ESTEX + save_mmu3 = inp(PORT_MMU3); + outp(PORT_SYSTEM, 0x11); + outp(PORT_MMU3, ((isa_slot & 0x01) << 1) | 0xd4); +#endif +} + +void isa_close() +{ +#ifdef ESTEX + outp(PORT_SYSTEM, 0x01); + // restore mmu3 (Close ISA ports memory mapping) + outp(PORT_MMU3, save_mmu3); +#endif +} + +char isa_get_slot() +{ + return isa_slot; +} + +char check_slot(char slot) +{ + char irr; + isa_slot = slot; + isa_open(); + irr = inb(REG_IIR); + isa_close(); + return irr & 0x3F; +} + +char find_wifi() +{ + // check isa slot 0 + char exists; + exists = check_slot(0); + if (exists) + { + return 1; + } + else + { +#ifdef ESTEX + return check_slot(1); +#else + return 0; +#endif + } +} + +// MODULE uart + +void uart_init() +{ + isa_open(); + // enable FIFO buffer, trigger to 14 byte + outb(REG_FCR, FCR_TR14 | FCR_FIFO); + // Disable interrupts + outb(REG_IER, 0x00); + // Set 8bit word and Divisor for speed + outb(REG_LCR, LCR_DLAB | LCR_WL8); // enable Baud rate latch + outb(REG_DLL, DIVISOR); + outb(REG_DLM, 0x00); + outb(REG_LCR, LCR_WL8); // 8bit word + isa_close(); +} + +char uart_read(reg) +unsigned reg; +{ + char res; + isa_open(); + res = inb(reg); + isa_close(); + return res; +} + +void uart_write(reg, value) unsigned reg; +char value; +{ + isa_open(); + outb(reg, value); + isa_close(); +} + +char uart_wait_tr() +{ + char res; + char loops = 100; + while (loops > 0) + { + res = uart_read(REG_LSR); + + if (res & LSR_THRE) + { + break; + } + + loops--; + util_delay(1); + } + return loops; +} + +char uart_tx_byte(byte) +char byte; +{ + char ready = uart_wait_tr(); + if (ready) + { + uart_write(REG_THR, byte); + } + return ready; +} + +char uart_tx_buffer(char *tbuff, int size) +{ + int ctr = size; + while (ctr--) + { + if (uart_wait_tr()) + { + uart_write(REG_THR, *tbuff++); + } + else + { + return RESULT_TX_TIMEOUT; + } + } + return RESULT_OK; +} + +char uart_tx_cmd(char *tx_buff, char *rs_buff, int size, int wait_ms) +{ + char resp = RESULT_OK; + char rcv, *buff; + char lstr[LSTR_SIZE]; + int lstrp = 0; + buff = rs_buff; + buff[size - 1] = 0; // mark last byte of buffer as end of string + size--; + uart_empty_rs(); + + if (uart_tx_buffer(tx_buff, strlen(tx_buff)) == RESULT_OK) + { + while (1) + { + if (uart_wait_rs(wait_ms)) + { + rcv = uart_read(REG_RBR); + if (size > 0 && rcv != CR) + { // ignore CR + *buff++ = rcv; + size--; + } + if (rcv == CR || rcv == LF) + { + + lstr[lstrp] = 0; + + if (strcmp(lstr, "OK") == 0) + { + break; + } + + if (strcmp(lstr, "ERROR") == 0) + { + resp = RESULT_ERROR; + break; + } + + if (strcmp(lstr, "FAIL") == 0) + { + resp = RESULT_FAIL; + break; + } + + lstrp = 0; + } + + if (lstrp < LSTR_SIZE && rcv != CR && rcv != LF) + { + lstr[lstrp++] = rcv; + } + } + else + { +#ifdef DEBUG + printf("No ansver to CMD, RCVR empty! %s\n", lstr); +#endif + return RESULT_RS_TIMEOUT; + } + } + if (uart_wait_rs(1)) + { + rcv = uart_read(REG_RBR); // read last LF + } + if (size > 0) + { + *buff = 0; // mark end of string + } +#ifdef DEBUG + printf(": '%s'\n", lstr); +#endif + } + else + { +#ifdef DEBUG + printf("Cmd transmit error, TR not ready!\n"); +#endif + return RESULT_TX_TIMEOUT; + } + return resp; +} + +void uart_empty_rs() +{ + uart_write(REG_FCR, FCR_TR14 | FCR_RESET_RX | FCR_FIFO); +} + +char uart_wait_rs(wait_ms) +int wait_ms; +{ + char res; + unsigned loops; + + if (wait_ms < 0) + { + loops = 1; + } + else + { + loops = wait_ms; + } + + while (loops > 0) + { + res = uart_read(REG_LSR) & LSR_DR; + if (res) + { + break; + } + loops--; + util_delay(1); + } + + return loops > 0; +} + +void esp_reset(char full) +{ + isa_open(); + if (full) + { + outb(REG_MCR, MCR_RST | MCR_RTS) // 0110b ESP -PGM=1, -RST=0, -RTS=0 + util_delay(20); + } + outb(REG_MCR, MCR_AFE | MCR_RTS) // 0x0202 -RST = 1 -RTS=0 AutoFlow enabled + isa_close(); + if (full) + { + util_delay(1000); + } +} diff --git a/sources/esplib.h b/sources/DOS/esplib.h similarity index 100% rename from sources/esplib.h rename to sources/DOS/esplib.h diff --git a/sources/wset.c b/sources/DOS/wset.c similarity index 100% rename from sources/wset.c rename to sources/DOS/wset.c diff --git a/sources/wset.h b/sources/DOS/wset.h similarity index 100% rename from sources/wset.h rename to sources/DOS/wset.h diff --git a/sources/wterm.c b/sources/DOS/wterm.c similarity index 100% rename from sources/wterm.c rename to sources/DOS/wterm.c diff --git a/sources/wterm.h b/sources/DOS/wterm.h similarity index 85% rename from sources/wterm.h rename to sources/DOS/wterm.h index d0b0079..42db213 100644 --- a/sources/wterm.h +++ b/sources/DOS/wterm.h @@ -12,6 +12,6 @@ #define MSG_START "Terminal for Sprinter WiFi Card (ESP8266)\nv1.0.0 by Romych (Boykov Roman)\n\n",0 #define MSG_NOT_FOUND "No Sprinter WiFi card found!\n" #define MSG_FOUND "Sprinter WiFi card found at slot: %d\n" -#define MSG_HLP "\nEnter ESP AT comand or QUIT to close terminal.\n" +#define MSG_HLP "\nEnter ESP AT command or QUIT to close terminal.\n" #endif \ No newline at end of file diff --git a/sources/wtime.c b/sources/DOS/wtime.c similarity index 100% rename from sources/wtime.c rename to sources/DOS/wtime.c diff --git a/sources/wtime.h b/sources/DOS/wtime.h similarity index 100% rename from sources/wtime.h rename to sources/DOS/wtime.h diff --git a/sources/DSS/.vscode/launch.json b/sources/DSS/.vscode/launch.json new file mode 100644 index 0000000..ba7da1c --- /dev/null +++ b/sources/DSS/.vscode/launch.json @@ -0,0 +1,173 @@ +{ + "version": "0.2.0", + "configurations": [ + // { + // "type": "dezog", + // "request": "launch", + // "name": "WSET Internal Simulator", + // "remoteType": "zsim", + // "zsim": { + // "visualMemory": true, + // "memoryModel": "CUSTOM", + // "customMemory": { + // "slots": [ + // { + // "name": "PAGE0", + // "range": ["0x0000","0x3FFF"], + // "banks": [{"index": [0, 255]}], + // "initialBank": 0 + // }, + // { + // "name": "PAGE1", + // "range": ["0x4000","0x7FFF"], + // "banks": [{"index": [0, 255]}], + // "initialBank": 1 + // }, + // { + // "name": "PAGE2", + // "range": ["0x8000","0xBFFF"], + // "banks": [{"index": [0, 255]}], + // "initialBank": 2 + // }, + // { + // "name": "PAGE3", + // "range": ["0xC000","0xFFFF"], + // "banks": [{"index": [0, 255]}], + // "initialBank": 3 + // } + // ], + // "ioMmu": [ + // "if (portAddress == 0x82) {", + // " bank = portValue;", + // " PAGE0 = bank;", + // "}", + // "if (portAddress == 0xA2) {", + // " bank = portValue;", + // " PAGE1 = bank;", + // "}", + // "if (portAddress == 0xC2) {", + // " bank = portValue;", + // " PAGE2 = bank;", + // "}", + // "if (portAddress == 0xE2) {", + // " bank = portValue;", + // " PAGE3 = bank;", + // "}" + // ] + // }, + // "customCode": { + // "debug": false, + // "jsPath": "sim/ports.js" + // }, + // }, + // "sjasmplus": [ + // { + // "path": "espset.sld" + // } + // ], + // "history": { + // "reverseDebugInstructionCount": 1000000, + // "spotCount": 10, + // "codeCoverageEnabled": true + // }, + // "startAutomatically": false, + // "commandsAfterLaunch": [], + // "rootFolder": "${workspaceFolder}", + // "topOfStack": "STACK_TOP", + // "loadObjs": [ + // { + // "path": "espset.exe", + // "start": "0x0000" + // } + // ], + // "execAddress": "0x8100", + // "smallValuesMaximum": 513, + // "tmpDir": ".tmp" + // }, + + { + "type": "dezog", + "request": "launch", + "name": "WTERM Internal Simulator", + "remoteType": "zsim", + "zsim": { + "visualMemory": true, + "memoryModel": "CUSTOM", + "customMemory": { + "slots": [ + { + "name": "PAGE0", + "range": ["0x0000","0x3FFF"], + "banks": [{"index": [0, 255]}], + "initialBank": 0 + }, + { + "name": "PAGE1", + "range": ["0x4000","0x7FFF"], + "banks": [{"index": [0, 255]}], + "initialBank": 1 + }, + { + "name": "PAGE2", + "range": ["0x8000","0xBFFF"], + "banks": [{"index": [0, 255]}], + "initialBank": 2 + }, + { + "name": "PAGE3", + "range": ["0xC000","0xFFFF"], + "banks": [{"index": [0, 255]}], + "initialBank": 3 + } + ], + "ioMmu": [ + "if (portAddress == 0x82) {", + " bank = portValue;", + " PAGE0 = bank;", + "}", + "if (portAddress == 0xA2) {", + " bank = portValue;", + " PAGE1 = bank;", + "}", + "if (portAddress == 0xC2) {", + " bank = portValue;", + " PAGE2 = bank;", + "}", + "if (portAddress == 0xE2) {", + " bank = portValue;", + " PAGE3 = bank;", + "}" + ] + }, + "customCode": { + "debug": false, + "jsPath": "sim/ports.js" + }, + }, + "sjasmplus": [ + { + "path": "wterm.sld" + } + ], + "history": { + "reverseDebugInstructionCount": 1000000, + "spotCount": 10, + "codeCoverageEnabled": true + }, + "startAutomatically": false, + "commandsAfterLaunch": [], + "rootFolder": "${workspaceFolder}", + "topOfStack": "STACK_TOP", + "loadObjs": [ + { + "path": "wterm.exe", + "start": "0x0000" + } + ], + "execAddress": "0x8100", + "smallValuesMaximum": 513, + "tmpDir": ".tmp" + } + + ] +} \ No newline at end of file diff --git a/sources/DSS/.vscode/tasks.json b/sources/DSS/.vscode/tasks.json new file mode 100644 index 0000000..5dee63b --- /dev/null +++ b/sources/DSS/.vscode/tasks.json @@ -0,0 +1,70 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "make ESPSET (sjasmplus)", + "type": "shell", + "command": "sjasmplus", + "args": [ + "--sld=espset.sld", + "--sym=espset.labels", + "--raw=espset.exe", + "--fullpath", + "espset.asm" + ], + "problemMatcher": { + "owner": "sjasmplus", + "fileLocation": "autoDetect", + "pattern": { + "regexp": "^(.*)\\((\\d+)\\):\\s+(warning|error):\\s+(.*)$", + "file": 1, + "line": 2, + "severity": 3, + "message": 4 + } + }, + "group": { + "kind": "build", + "isDefault": true + } + }, + + { + "label": "make WTERM (sjasmplus)", + "type": "shell", + "command": "sjasmplus", + "args": [ + "--sld=wterm.sld", + "--sym=wterm.labels", + "--raw=wterm.exe", + "--fullpath", + "wterm.asm" + ], + "problemMatcher": { + "owner": "sjasmplus", + "fileLocation": "autoDetect", + "pattern": { + "regexp": "^(.*)\\((\\d+)\\):\\s+(warning|error):\\s+(.*)$", + "file": 1, + "line": 2, + "severity": 3, + "message": 4 + } + }, + "group": { + "kind": "build", + "isDefault": true + } + }, + + { + "label": "start mame", + "type": "shell", + "command": "while true; do ./mame spectrum -window -debugger gdbstub -debug -debugger_port 12000 -verbose -resolution 512x384 ; sleep 2 ; done", + "options": { + "cwd": "${config:mame_dir}" + }, + "problemMatcher": [] + } + ] +} \ No newline at end of file diff --git a/sources/DSS/dss.asm b/sources/DSS/dss.asm new file mode 100644 index 0000000..9e08ce2 --- /dev/null +++ b/sources/DSS/dss.asm @@ -0,0 +1,367 @@ +; ====================================================== +; DSS Estex dumb for debug code in VSC with DEZOG plugin +; By Roman Boykov. Copyright (c) 2024 +; https://github.com/romychs +; ====================================================== + + ORG 0x0000 + +RESET: + JP NOT_IMPL + DS 5, 0xFF + +RST08: + JP NOT_IMPL + DS 5, 0xFF + + ORG 0x0010 +RST10: + JP DSS_HANDLER + DS 5, 0xFF + +RST18: + JP NOT_IMPL + DS 5, 0xFF + +RST20: + JP NOT_IMPL + DS 5, 0xFF + +RST28: + JP NOT_IMPL + DS 5, 0xFF + +RST30: + JP NOT_IMPL + DS 5, 0xFF + +RST38: + JP NOT_IMPL + DS 5, 0xFF + +DSS_HANDLER + + PUSH HL + PUSH BC + LD A, C + CP DSS_CURDISK + JP Z, _CURDISK + CP 0x0B + JP Z, _CREATE_FILE + CP 0x11 + JP Z, _OPEN_FILE + CP 0x12 + JP Z, _CLOSE_FILE + CP 0x13 + JP Z, _READ_FILE + CP 0x14 + JP Z, _WRITE_FILE + CP 0x19 + JP Z, _FIND_FIRST + CP 0x1D + JP Z, _CH_DIR + CP 0x1E + JP Z, _CURDIR + + CP DSS_WAITKEY + JP Z, _WAITKEY + + CP DSS_SCANKEY + JP Z, _SCANKEY + + CP DSS_ECHOKEY + JP Z, _ECHOKEY + + CP DSS_SETVMOD + JP Z, _SETVMOD + + + CP DSS_GETVMOD + JP Z, _GETVMOD + + CP low DSS_CLEAR + JP Z, _CLEAR + + CP DSS_PUTCHAR + JP Z, _PUTCHAR + + CP DSS_PCHARS + JP Z, _PCHARS + + CP 0x41 + JP Z, _EXIT + + POP BC + POP HL + + +NOT_IMPL + LD A,0x01 + SCF + RET + +_PUTCHAR + LD BC, 0x9000 + OUT (C),A + JR NORM_EXIT + + +_PCHARS + LD BC, 0x9000 + +NXT_PCHAR + LD A, (HL) + OUT (C),A + INC HL + OR A + JR NZ, NXT_PCHAR + +NORM_EXIT + AND A ; CF=0 + POP BC + POP HL + RET + +BAD_EXIT + SCF + POP BC + POP HL + RET + + +_CURDISK + LD A, 3 + JP NORM_EXIT + +; Входные значения: +; HL - указатель на файловую спецификацию +; A - атрибут файла +; Выходные значения: +; A — код ошибки, если CF=1 +; A - файловый манипулятор, если CF=0 +_CREATE_FILE + JP _OPEN_FILE + +; Входные значения: +; HL - указатель на файловую спецификацию +; A - режим доступа +; A=0 чтение/запись +; A=1 чтение +; A=2 запись +; Выходные значения: +; A - код ошибки, если CF=1 +; A - файловый манипулятор, если CF=0 +CUR_FILE_MAN + DB 0x4F + +CUR_DIR + DB "\\FOLDER",0 +CUR_DIR_END +CUR_DIR_SIZE EQU CUR_DIR_END-CUR_DIR + +_OPEN_FILE + LD HL, CUR_FILE_MAN + INC (HL) + LD A, (HL) + JP NORM_EXIT + +_CLOSE_FILE + JP NORM_EXIT + +CUR_F_PTR + DW ZIP_FILE + +REMAINS_IN_ZIP + DW 0 + +; Входные значения: +; A - файловый манипулятор +; HL - адрес в памяти +; DE - количество читаемых байт +; Выходные значения: +; A - код ошибки, если CF=1 +; DE - реальное количество прочитанных байт +; если CF=0: +; A = 0 прочитаны все байты +; A = 0FFh прочитано меньшее число байт +_READ_FILE + OR A + JP Z, BAD_EXIT + PUSH DE + POP BC ; BC - bytes to read + PUSH HL + + LD HL, (CUR_F_PTR) ; HL -> IN ZIP_FILE + LD DE, ZIP_FILE_END + EX HL, DE + SUB HL, DE ; HL = remain bytes + LD (REMAINS_IN_ZIP), HL + SBC HL, BC + LD A, 0 + JR NC, NO_OUT_OF_ZIP + DEC A + LD HL,(REMAINS_IN_ZIP) + LD BC, HL + +NO_OUT_OF_ZIP + LD HL, (CUR_F_PTR) + POP DE ; DE - Buffer to write + PUSH BC + LDIR + POP DE ; DE = bytes read, A = 0 or 0xFF + LD (CUR_F_PTR), HL + + JP NORM_EXIT + + +; Входные значения: +; A - файловый манипулятор +; HL - адрес в памяти +; DE - количество записываемых байт +; Выходные значения: +; A - код ошибки, если CF=1 +; DE - реальное количество записанных байт +_WRITE_FILE + + PUSH DE + POP BC + LD DE,UNZIP_FILE + + PUSH BC + LDIR + POP DE + JP NORM_EXIT + +; Входные значения: +; HL - указатель на файловую спецификацию +; Выходные значения: +; A - код ошибки, если CF=1 +_CH_DIR + JP NORM_EXIT + + +; 1Eh (30) CURDIR (Информация о текущем каталоге) +; Входные значения: +; HL - буфер в памяти 256 байт +; Выходные значения: +; A - код ошибки, если CF=1 +_CURDIR + PUSH DE + LD DE, CUR_DIR + EX HL,DE + LD BC, CUR_DIR_SIZE + LDIR + POP DE + JP NORM_EXIT + +_ECHOKEY + PUSH HL + LD HL,EC + LD C,DSS_PCHARS + RST DSS + POP HL + LD A,(EC) + JP NORM_EXIT + +EC DB "3",0 + +; Входные значения: +; HL - указатель на файловую спецификацию +; DE - рабочий буфер 44 байта, если B=0, иначе 256 байт +; A - атрибуты, используемые при поиске +; B = 0 - имя найденного файла в формате 11 байт "FilenameExt" +; B = 1 - имя найденного файла в формате DOS "filename.ext",0 +; C - 19h +; Выходные значения: +; A - код ошибки, если CF=1 +_FIND_FIRST + PUSH DE + LD HL, 33 ; offset of file name + ADD HL, DE + EX HL, DE + LD HL, ZIP_FILE_NAME + LD BC,9 + LDIR + POP DE + JP NORM_EXIT + + +_SCANKEY + XOR A + JP NORM_EXIT + + +; Выходные значения: +; A - код символа +; D - позиционный код +; Е - ASCII код +; C - режим клавиатуры: +_WAITKEY + XOR A + LD D, A + LD C, A + LD E,65 + LD A,65 + JP NORM_EXIT + + +CUR_VMOD + DB 1 + +; 50h (80) SETVMOD (Выбор режима экрана) +; Входные значения: +; A - режим экрана: +; 02h - текстовый 40x32x16 цветов; +; 03h - текстовый 80x32x16 цветов; +; 81h - графический 320x256x256 цветов; +; 82h - графический 640x256x16 цветов; +; B - страница экрана 0/1 +; C - 50h +; Выходные значения: +; A - код ошибки, если CF=1 +_SETVMOD + LD (CUR_VMOD),A + JP NORM_EXIT + +; 51h (81) GETVMOD (Получить текущий режим экрана) +; Входные значения: +; C - 51h +; Выходные значения: +; A - код ошибки, если CF=1 +; A - текущий режим экрана, если CF=0 +; B - страница экрана 0/1 +_GETVMOD + LD A,(CUR_VMOD) + JP NORM_EXIT + +; 56h (86) CLEAR (Очистка окна) +; Входные значения: +; D - строка левого верхнего угла окна +; E - столбец левого верхнего угла окна +; H - высота окна +; L - ширина окна +; B - атрибут заполнитель +; A - символ заполнитель +; C - 56h +; Выходные значения: +; нет +_CLEAR + JP NORM_EXIT + + +_EXIT +; LOGPOINT STOPPED! + + HALT + JP _EXIT + + +ZIP_FILE_NAME + DB "file.zip",0 +ZIP_FILE + DS 1024,0 +ZIP_FILE_END +UNZIP_FILE + DS 1024,0 + + ALIGN 16384, 0 \ No newline at end of file diff --git a/sources/DSS/dss.inc b/sources/DSS/dss.inc new file mode 100644 index 0000000..e3a0d9f --- /dev/null +++ b/sources/DSS/dss.inc @@ -0,0 +1,43 @@ +; ====================================================== +; Defines for DSS Estex for Sprinter computer +; By Roman Boykov. Copyright (c) 2024 +; https://github.com/romychs +; ====================================================== + +; DSS RST Entry +DSS EQU 0x10 + +; DSS Functions +DSS_CURDISK EQU 0x02 +DSS_CREATE_FILE EQU 0x0B +DSS_OPEN_FILE EQU 0x11 +DSS_CLOSE_FILE EQU 0x12 +DSS_READ_FILE EQU 0x13 +DSS_WRITE EQU 0x14 +DSS_MOVE_FP_CP EQU 0x0115 +DSS_FIND_FIRST EQU 0x0119 +DSS_FIND_NEXT EQU 0x011A +DSS_MKDIR EQU 0x1B +DSS_CHDIR EQU 0x1D +DSS_CURDIR EQU 0x1E +DSS_SCANKEY EQU 0x31 +DSS_ECHOKEY EQU 0x32 +DSS_EXIT EQU 0x41 +DSS_WAITKEY EQU 0x48 +DSS_SETVMOD EQU 0x50 +DSS_GETVMOD EQU 0x51 +DSS_CLEAR EQU 0x56 +DSS_PUTCHAR EQU 0x5B +DSS_PCHARS EQU 0x5C + + +DSS_VMOD_T40 EQU 0x02 ; text 40x32, 16 colors +DSS_VMOD_T80 EQU 0x03 ; text 80x32, 16 colors +DSS_VMOD_G320 EQU 0x81 ; graphics 320x256, 256 colors +DSS_VMOD_G640 EQU 0x82 ; graphics 640x256, 16 colors + + +; DSS Error codes +E_FILE_EXISTS EQU 7 +E_FILE_NOT_FOUND EQU 3 + diff --git a/sources/DSS/esplib.asm b/sources/DSS/esplib.asm new file mode 100644 index 0000000..c180bcf --- /dev/null +++ b/sources/DSS/esplib.asm @@ -0,0 +1,483 @@ +; ====================================================== +; Library for Sprinter-WiFi ESP ISA Card +; By Roman Boykov. Copyright (c) 2024 +; https://github.com/romychs +; License: BSD 3-Clause +; ====================================================== + +;ISA_BASE_A EQU 0xC000 ; Базовый адрес портов ISA в памяти +PORT_UART EQU 0x03E8 ; Базовый номер порта COM3 +PORT_UART_A EQU ISA_BASE_A + PORT_UART ; Порты чипа UART в памяти + +; UART TC16C550 Registers in memory +REG_RBR EQU PORT_UART_A +REG_THR EQU PORT_UART_A +REG_IER EQU PORT_UART_A + 1 +REG_IIR EQU PORT_UART_A + 2 +REG_FCR EQU PORT_UART_A + 2 +REG_LCR EQU PORT_UART_A + 3 +REG_MCR EQU PORT_UART_A + 4 +REG_LSR EQU PORT_UART_A + 5 +REG_MSR EQU PORT_UART_A + 6 +REG_SCR EQU PORT_UART_A + 7 +REG_DLL EQU PORT_UART_A +REG_DLM EQU PORT_UART_A + 1 +REG_AFR EQU PORT_UART_A + 2 + + + +; UART TC16C550 Register bits +MCR_DTR EQU 0x01 +MCR_RTS EQU 0x02 +MCR_RST EQU 0x04 +MCR_PGM EQU 0x08 +MCR_LOOP EQU 0x10 +MCR_AFE EQU 0x20 +LCR_WL8 EQU 0x03 ; 8 bits word len +LCR_SB2 EQU 0x04 ; 1.5 or 2 stp bits +LCR_DLAB EQU 0x80 ; Enable Divisor latch +FCR_FIFO EQU 0x01 ; Enable FIFO for rx and tx +FCR_RESET_RX EQU 0x02 ; Reset Rx FIFO +FCR_RESET_TX EQU 0x04 ; Reset Tx FIFO +FCR_DMA EQU 0x08 ; Set -RXRDY, -TXRDY to "1" +FCR_TR1 EQU 0x00 ; Trigger on 1 byte in fifo +FCR_TR4 EQU 0x40 ; Trigger on 4 bytes in fifo +FCR_TR8 EQU 0x80 ; Trigger on 8 bytes in fifo +FCR_TR14 EQU 0xC0 ; Trigger on 14 bytes in fifo +LSR_DR EQU 0x01 ; Data Ready +LSR_OE EQU 0x02 ; Overrun Error +LSR_PE EQU 0x04 ; Parity Error +LSR_FE EQU 0x08 ; Framing Error +LSR_BI EQU 0x10 ; Break Interrupt +LSR_THRE EQU 0x20 ; Transmitter Holding Register Empty +LSR_TEMT EQU 0x40 ; Transmitter empty +LSR_RCVE EQU 0x80 ; Error in receiver FIFO + +; Speed divider for UART +BAUD_RATE EQU 115200 ; Скорость соединения с ESP8266 +XIN_FREQ EQU 14745600 ; Частота генератора для TL16C550 +DIVISOR EQU XIN_FREQ / (BAUD_RATE * 16) ; Делитель частоты для передачи/приема данных + +RS_BUFF_SIZE EQU 2048 ; Receive buffer size +MAX_BUFF_SIZE EQU 16384 + +LSTR_SIZE EQU 20 ; Size of buffer for last response line +LF EQU 0x0A +CR EQU 0x0D + +; -- +RES_OK EQU 0 +RES_ERROR EQU 1 +RES_FAIL EQU 2 +RES_TX_TIMEOUT EQU 3 +RES_RS_TIMEOUT EQU 4 +RES_CONNECTED EQU 5 +RES_NOT_CONN EQU 6 +RES_ENABLED EQU 7 +RES_DISABLED EQU 8 + + + + MODULE WIFI + +; -- UART Registers offset + +_RBR EQU 0 +_THR EQU 0 +_IER EQU 1 +_IIR EQU 2 +_FCR EQU 2 +_LCR EQU 3 +_MCR EQU 4 +_LSR EQU 5 +_MSR EQU 6 +_SCR EQU 7 +_DLL EQU 0 +_DLM EQU 1 +_AFR EQU 2 + + +; ------------------------------------------------------ +; Find TL550C in ISA slot +; Out: CF=1 - Not found, CF=0 - ISA.ISA_SLOT found in slot +; ------------------------------------------------------ +UART_FIND + PUSH HL + XOR A + CALL UT_T_SLOT + JR Z, UF_T_FND + LD A,1 + CALL UT_T_SLOT + JR Z, UF_T_FND + SCF +UF_T_FND + POP HL + RET + +; Test slot, A - ISA Slot no. 0 or 1 +UT_T_SLOT + ; check IER hi bits, will be 0 + LD (ISA.ISA_SLOT), A + LD HL, REG_IER + CALL UART_READ + AND 0xF0 + RET NZ + + ; check SCR register + LD DE,0x5555 + CALL CHK_SCR + RET NZ + LD DE,0xAAAA + CALL CHK_SCR + RET + +CHK_SCR + LD HL, REG_SCR + CALL UART_WRITE + CALL UART_READ + CP D + RET + + + +; ------------------------------------------------------ +; Init UART device TL16C550 +; ------------------------------------------------------ +UART_INIT + PUSH AF, IX + + CALL ISA.ISA_OPEN + LD IX, PORT_UART_A + LD A, FCR_TR8 | FCR_FIFO ; Enable FIFO buffer, trigger to 14 byte + LD (IX+_FCR),A + XOR A + LD (IX+_IER), A ; Disable interrupts + + ; Set 8bit word and Divisor for speed + LD A, LCR_DLAB | LCR_WL8 + LD (IX+_LCR), A ; Enable Baud rate latch + LD A, DIVISOR + LD (IX+_DLL), A ; 8 - 115200 + XOR A + LD (IX+_DLM), A + LD A, LCR_WL8 ; 8bit word, disable latch + LD (IX+_LCR), A + CALL ISA.ISA_CLOSE + + POP IX,AF + RET + +; ------------------------------------------------------ +; Read TL16C550 register +; Inp: HL - register +; Out: A - value from register +; ------------------------------------------------------ +UART_READ + CALL ISA.ISA_OPEN + LD A, (HL) + CALL ISA.ISA_CLOSE + RET + +; ------------------------------------------------------ +; Write TL16C550 register +; Inp: HL - register, E - value +; ------------------------------------------------------ +UART_WRITE + CALL ISA.ISA_OPEN + LD (HL), E + CALL ISA.ISA_CLOSE + RET + +; ------------------------------------------------------ +; Wait for transmitter ready +; Out: CF=1 - tr not ready, CF=0 ready +; ------------------------------------------------------ +UART_WAIT_TR + CALL ISA.ISA_OPEN + CALL UART_WAIT_TR_INT + CALL ISA.ISA_CLOSE + RET + +; +; Wait, without open/close ISA +; +UART_WAIT_TR_INT + PUSH AF, BC, HL + LD BC, 500 + LD HL, REG_LSR +WAIT_TR_BZY + LD A,(HL) + AND A, LSR_THRE + JR NZ,WAIT_TR_RDY + CALL UTIL.DELAY_100uS ; ~11 bit tx delay + DEC BC + LD A, C + OR B + JR NZ,WAIT_TR_BZY + SCF +WAIT_TR_RDY + POP HL, BC, AF + RET + +; ------------------------------------------------------ +; Transmit byte +; Inp: E - byte +; Out: CF=1 - Not ready +; ------------------------------------------------------ +UART_TX_BYTE + CALL UART_WAIT_TR + JP C, UTB_NOT_R + LD HL, REG_THR + CALL UART_WRITE + XOR A +UTB_NOT_R + RET + +; ------------------------------------------------------ +; Transmit buffer +; Inp: HL -> buffer, BC - size +; Out: CF=0 - Ok, CF=1 - Timeout +; ------------------------------------------------------ +UART_TX_BUFFER + PUSH BC,DE,HL + LD DE, REG_THR + CALL ISA.ISA_OPEN +UTX_NEXT + ; buff not empty? + LD A, B + OR C + JR Z,UTX_EMP + ; check transmitter ready + CALL UART_WAIT_TR_INT + JR C, UTX_TXNR + ; transmitt byte + LD A,(HL) + INC HL + LD (DE),A + DEC BC + JR UTX_NEXT + ; CF=0 +UTX_EMP + AND A +UTX_TXNR + CALL ISA.ISA_CLOSE + POP HL,DE,BC + RET + +; ------------------------------------------------------ +; Transmit zero ended string +; Inp: HL -> buffer +; Out: CF=0 - Ok, CF=1 - Timeout +; ------------------------------------------------------ +UART_TX_STRING + PUSH DE,HL + LD DE, REG_THR + CALL ISA.ISA_OPEN +UTXS_NEXT + LD A,(HL) + AND A + JR Z,UTXS_END + ; check transmitter ready + CALL UART_WAIT_TR_INT + JR C, UTXS_TXNR + ; transmitt byte + LD A,(HL) + INC HL + LD (DE),A + JR UTXS_NEXT + ; CF=0 +UTXS_END + AND A +UTXS_TXNR + CALL ISA.ISA_CLOSE + POP HL,DE + RET + + + + +; ------------------------------------------------------ +; Empty receiver FIFO buffer +; ------------------------------------------------------ +UART_EMPTY_RS + PUSH DE, HL + LD E, FCR_TR8 | FCR_RESET_RX | FCR_FIFO + LD HL, REG_FCR + CALL UART_WRITE + POP HL, DE + RET + +; ------------------------------------------------------ +; Wait byte in receiver fifo +; Inp: BC - Wait ms +; Out: CF=1 - Timeout, FIFO is EMPTY +; ------------------------------------------------------ +UART_WAIT_RS1 + PUSH BC,HL +WAIT_MS+* LD BC,0x2000 + JR UVR_NEXT +UART_WAIT_RS + PUSH BC,HL +UVR_NEXT + LD HL, REG_LSR + CALL UART_READ + AND LSR_DR + JR NZ,UVR_OK + CALL UTIL.DELAY_1MS + DEC BC + LD A,B + OR C + JR NZ,UVR_NEXT +UVR_TO + IF TRACE + PUSH AF,BC,DE,HL + PRINTLN MSG_RCV_EMPTY + POP HL,DE,BC,AF + ENDIF + SCF +UVR_OK + POP HL,BC + RET + +; ------------------------------------------------------ +; Reset ESP module +; ------------------------------------------------------ +ESP_RESET + PUSH AF,HL + + CALL ISA.ISA_OPEN + + LD HL, REG_MCR + LD A, MCR_RST ;| MCR_RTS ; -OUT1=0 -> RESET ESP + LD (REG_MCR), A + CALL UTIL.DELAY_1MS + LD A, MCR_AFE | MCR_RTS ; 0x22 -OUT1=1 RTS=1 AutoFlow enabled + LD (HL), A + CALL ISA.ISA_CLOSE + + ; wait 2s for ESP firmware boot + LD HL,2000 + CALL UTIL.DELAY + + POP HL,AF + RET + + +; Receive block size +BSIZE DW 0 + +; Received message for OK result +MSG_OK DB "OK", 0 +; Received message for Error +MSG_ERROR DB "ERROR", 0 +; Received message for Failure +MSG_FAIL DB "FAIL", 0 + +; ------------------------------------------------------ +; UART TX Command +; Inp: HL - ptr to command, +; DE - ptr to receive buffer, +; BC - wait ms +; Out: CF=1 if Error +; ------------------------------------------------------ +UART_TX_CMD + PUSH BC, DE, HL + + LD A, low RS_BUFF_SIZE + LD (BSIZE), A + LD A, high RS_BUFF_SIZE + LD (BSIZE+1), A + + ;LD (RESBUF),DE + XOR A + LD (DE), A + + LD (WAIT_MS), BC + CALL UART_EMPTY_RS + + ; HL - Buffer, BC - Size + ;CALL UTIL.STRLEN + CALL UART_TX_STRING + JR NC, UTC_STRT_RX + ; error, transmit timeout + LD A, RES_TX_TIMEOUT + JR UTC_RET +UTC_STRT_RX + ; no transmit timeout, receive response + ; IX - pointer to begin of current line + LD IXH, D + LD IXL, E + LD BC,(BSIZE) +UTC_RCV_NXT + ; wait receiver ready + ;LD BC,(WAIT_MS) + CALL UART_WAIT_RS1 + JR NC, UTC_NO_RT + ; error, read timeout + LD A, RES_RS_TIMEOUT + JR UTC_RET + ; no receive timeout +UTC_NO_RT + + ; read symbol from tty + LD HL, REG_RBR + CALL UART_READ + CP CR + JP Z, UTC_RCV_NXT ; Skip CR + CP LF + JR Z, UTC_END ; LF - last symbol in responce + LD (DE),A + INC DE + DEC BC + LD A, B + OR C + JR NZ, UTC_RCV_NXT + +UTC_END + XOR A + LD (DE),A ; temporary mark end of string + PUSH DE ; store DE + POP IY + PUSH IX + POP DE ; DE - ptr to begin pf current line + + ; It is 'OK'? + LD HL, MSG_OK + CALL UTIL.STRCMP + JR NC, UTC_RET + ; It is 'ERROR'? + LD HL,MSG_ERROR + CALL UTIL.STRCMP + JR C, UTC_CP_FAIL + LD A, RES_ERROR + ; It is 'FAIL'? + JR UTC_RET +UTC_CP_FAIL + LD HL,MSG_FAIL + CALL UTIL.STRCMP + JR C, UTC_NOMSG + LD A, RES_FAIL + JR UTC_RET +UTC_NOMSG + ; no resp message, continue receive + PUSH IY + POP DE + LD A, LF + LD (DE),A ; change 0 - EOL to LF + INC DE + LD IXH,D ; store new start line ptr + LD IXL,E + JR UTC_RCV_NXT +UTC_RET + POP HL, DE, BC + RET + + IF TRACE +MSG_RCV_EMPTY + DB "Receiver is empty!",0 + ENDIF + +; Buffer to receive response from ESP +RS_BUFF DS RS_BUFF_SIZE, 0 + + ENDMODULE \ No newline at end of file diff --git a/sources/DSS/espset.asm b/sources/DSS/espset.asm new file mode 100644 index 0000000..0df9db9 --- /dev/null +++ b/sources/DSS/espset.asm @@ -0,0 +1,301 @@ +; ====================================================== +; ESPSET for Sprinter-WiFi for Sprinter computer +; By Roman Boykov. Copyright (c) 2024 +; https://github.com/romychs +; License: BSD 3-Clause +; ====================================================== + + +; Set to 1 to turn debug ON with DeZog VSCode plugin +; Set to 0 to compile .EXE +DEBUG EQU 0 + +; Set to 1 to output TRACE messages +TRACE EQU 1 + +; Version of EXE file, 1 for DSS 1.70+ +EXE_VERSION EQU 0 + +; Timeout to wait ESP response +DEFAULT_TIMEOUT EQU 2000 + + SLDOPT COMMENT WPMEM, LOGPOINT, ASSERTION + + DEVICE NOSLOT64K + + IF DEBUG == 1 + INCLUDE "dss.asm" + DB 0 + ALIGN 16384, 0 + DS 0x80, 0 + ENDIF + + INCLUDE "macro.inc" + INCLUDE "dss.inc" + INCLUDE "sprinter.inc" + + MODULE MAIN + + ORG 0x8080 + +; ------------------------------------------------------ +EXE_HEADER + DB "EXE" + DB EXE_VERSION ; EXE Version + DW 0x0080 ; Code offset + DW 0 + DW 0 ; Primary loader size + DW 0 ; Reserved + DW 0 + DW 0 + DW START ; Loading Address + DW START ; Entry Point + DW STACK_TOP ; Stack address + DS 106, 0 ; Reserved + + ORG 0x8100 +@STACK_TOP + +; ------------------------------------------------------ +START + + IF DEBUG == 1 + ; LD IX,CMD_LINE1 + LD SP, STACK_TOP + ENDIF + + + CALL ISA.ISA_RESET + + PRINTLN MSG_START + + CALL FIND_SWF + + ; Turn local echo Off + CALL INIT_ESP + + ; Display main menu to make selection +MENU_AGAIN + CALL SELECT_MAIN_MENU + + ; Do somethink with selected item + AND A + JR Z, MENU_EXIT + DEC A + JP Z, MENU_SELECT_WIFI + DEC A + JP Z, MENU_CONFIGURE_IP + DEC A + JP Z, MENU_DISPLAY_INFO + JP MENU_AGAIN + +MENU_EXIT + LD B,0 + JP EXIT + + +MENU_SELECT_WIFI +MENU_CONFIGURE_IP +MENU_DISPLAY_INFO + JP MENU_AGAIN + +NO_TL_FOUND + PRINTLN MSG_SWF_NOF + LD B,2 + JP EXIT + + +CHECK_ERROR + RET NC + ADD A,'0' + LD (COMM_ERROR_NO), A + PRINTLN MSG_COMM_ERROR + LD B,3 + POP HL ; ret addr reset + +EXIT + LD C,DSS_EXIT + RST DSS + +FIND_SWF + ; Find Sprinter-WiFi + CALL WIFI.UART_FIND + JP C, NO_TL_FOUND + LD A,(ISA.ISA_SLOT) + ADD A,'1' + LD (MSG_SLOT_NO),A + PRINTLN MSG_SWF_FOUND + LD C,DSS_PCHARS + RST DSS + RET + + + +; ------------------------------------------------------ +; Init basic parameters of ESP +; ------------------------------------------------------ +INIT_ESP + PUSH BC, DE + LD DE, WIFI.RS_BUFF + LD BC, DEFAULT_TIMEOUT + + TRACELN MSG_ECHO_OFF + SEND_CMD CMD_ECHO_OFF + + TRACELN MSG_STATIOJN_MODE + SEND_CMD CMD_STATION_MODE + + TRACELN MSG_NO_SLEEP + SEND_CMD CMD_NO_SLEEP + + TRACELN MSG_SET_UART + SEND_CMD CMD_SET_SPEED + + TRACELN MSG_SET_OPT + SEND_CMD CMD_CWLAP_OPT + POP DE,BC + RET + +; ------------------------------------------------------ +; Set DHCP mode +; Out: CF=1 if error +; ------------------------------------------------------ +SET_DHCP_MODE + PUSH BC,DE + LD DE, WIFI.RS_BUFF + LD BC, DEFAULT_TIMEOUT + TRACELN MSG_SET_DHCP + SEND_CMD CMD_SET_DHCP + POP DE,BC + RET + + + +; ------------------------------------------------------ +; Output main menu to select user action +; Ret: A = selected menu item +; ------------------------------------------------------ +SELECT_MAIN_MENU + PUSH BC + PRINTLN MSG_MAIN_MENU +SMM_L1 + PRINT MSG_ENT_NO + ; SCANF + LD C, DSS_ECHOKEY + RST DSS + SUB '0' + ; Test A in range [0..3] + AND A + JP M, SMM_L1 + CP 4 + JP P, SMM_L1 + POP BC + RET + +; ------------------------------------------------------ +; Messages DB "\r\n1 - Select WiFi Network\r\n" + DB "2 - Configure IP parameters\r\n" + DB "3 - Display info\r\n" + DB "0 - Exit",0 + +; ------------------------------------------------------ +MSG_START + DB "Setup for Sprinter-WiFi by Sprinter Team, ", __DATE__ ,"\r\n", 0 + +MSG_SWF_NOF + DB "Sprinter-WiFi not found!",0 + +MSG_SWF_FOUND + DB "Sprinter-WiFi found in ISA#" +MSG_SLOT_NO + DB "n slot.",0 + +MSG_COMM_ERROR + DB "Error communication with Sprinter-WiFi #" +COMM_ERROR_NO + DB "n!",0 + +MSG_MAIN_MENU + DB "\r\n1 - Select WiFi Network\r\n" + DB "2 - Configure IP parameters\r\n" + DB "3 - Display info\r\n" + DB "0 - Exit",0 + +MSG_ENT_NO + DB "\r\nEnter number 0..3: ",0 +; ------------------------------------------------------ +; Debug messages +; ------------------------------------------------------ + IF TRACE + +MSG_ECHO_OFF + DB "Echo off",0 + +MSG_STATIOJN_MODE + DB "Station mode",0 + +MSG_NO_SLEEP + DB "No sleep",0 + +MSG_SET_UART + DB "Setup uart",0 + +MSG_SET_OPT + DB "Set options",0 + +MSG_SET_DHCP + DB "Set DHCP mode",0 + + ENDIF + + +; ------------------------------------------------------ +; Commands +; ------------------------------------------------------ +CMD_SET_SPEED + DB "AT+UART_CUR=115200,8,1,0,3\r\n",0 +CMD_ECHO_OFF + DB "ATE0\r\n",0 +CMD_STATION_MODE + DB "AT+CWMODE=1\r\n",0 +CMD_NO_SLEEP + DB "AT+SLEEP=0\r\n",0 +CMD_CHECK_CONN_AP + DB "AT+CWJAP?\r\n",0 +CMD_CWLAP_OPT + DB "AT+CWLAPOPT=1,23\r\n",0 +CMD_GET_AP_LIST + DB "AT+CWLAP\r\n",0 +CMD_GET_DHCP + DB "AT+CWDHCP?\r\n",0 +CMD_SET_DHCP + DB "AT+CWDHCP=1,1\r\n",0 +CMD_GET_IP + DB "AT+CIPSTA?\r\n",0 +LINE_END + DB "\r\n",0 + + + + IF DEBUG == 1 +CMD_TEST1 DB "ATE0\r\n",0 +BUFF_TEST1 DS RS_BUFF_SIZE,0 + ENDIF + + ENDMODULE + + INCLUDE "util.asm" + INCLUDE "isa.asm" + INCLUDE "esplib.asm" + + END MAIN.START + + ; PUSH IX ; IX ptr to cmd line + ; POP HL + ; INC HL ; Skip size of Command line + ; LD DE,ZIP_FILE + ; CALL GET_CMD_PARAM + ; JR C,INVALID_CMDLINE + ; LD DE,FILES_TO_ZIP + ; CALL GET_CMD_PARAM + ; JR C,INVALID_CMDLINE diff --git a/sources/DSS/isa.asm b/sources/DSS/isa.asm new file mode 100644 index 0000000..b3928b3 --- /dev/null +++ b/sources/DSS/isa.asm @@ -0,0 +1,80 @@ +; ====================================================== +; ISA Library for Sprinter computer +; By Roman Boykov. Copyright (c) 2024 +; https://github.com/romychs +; License: BSD 3-Clause +; ====================================================== + +PORT_ISA EQU 0x9FBD +PORT_SYSTEM EQU 0x1FFD + +ISA_BASE_A EQU 0xC000 ; Базовый адрес портов ISA в памяти + +; --- PORT_ISA bits +ISA_A14 EQU 0x01 +ISA_A15 EQU 0x02 +ISA_A16 EQU 0x04 +ISA_A17 EQU 0x08 +ISA_A18 EQU 0x10 +ISA_A19 EQU 0x20 +ISA_AEN EQU 0x40 +ISA_RST EQU 0x80 + + MODULE ISA + +; ------------------------------------------------------ +; Reset ISA device +; ------------------------------------------------------ +ISA_RESET + LD BC, PORT_ISA + LD A,ISA_RST | ISA_AEN ; RESET=1 AEN=1 + OUT (C), A + CALL UTIL.DELAY_1MS + XOR A + OUT (C), A ; RESET=0 AEN=0 + LD HL,100 + CALL UTIL.DELAY + RET + +; ------------------------------------------------------ +; Open access to ISA ports as memory +; Inp: A = 0 - ISA slot 0, 1 - ISA SLOT 1 +; ------------------------------------------------------ +ISA_OPEN + PUSH AF,BC + LD BC, PAGE3 + IN A,(C) + LD (SAVE_MMU3), A + LD BC, PORT_SYSTEM + LD A, 0x11 + OUT (C), A +ISA_SLOT+* LD A,0x01 + SLA A + OR A, 0xD4 ; D4 - ISA1, D6 - ISA2 + LD BC, PAGE3 + OUT (C), A + LD BC, PORT_ISA + XOR A + OUT (C), A + POP BC,AF + RET + + +; ------------------------------------------------------ +; Close access to ISA ports +; ------------------------------------------------------ +ISA_CLOSE + PUSH AF,BC + LD A,0x01 + LD BC,PORT_SYSTEM + OUT (C),A + LD BC,PAGE3 + LD A,(SAVE_MMU3) + OUT (C),A + POP BC,AF + RET + +; To save memory page 3 +SAVE_MMU3 DB 0 + + ENDMODULE \ No newline at end of file diff --git a/sources/DSS/macro.inc b/sources/DSS/macro.inc new file mode 100644 index 0000000..6f39f20 --- /dev/null +++ b/sources/DSS/macro.inc @@ -0,0 +1,39 @@ +; ====================================================== +; Macros for Sprinter-WiFi utilities +; By Roman Boykov. Copyright (c) 2024 +; https://github.com/romychs +; License: BSD 3-Clause +; ====================================================== + + ; Transmit data|command via UART and check response + MACRO SEND_CMD data + LD HL, data + CALL WIFI.UART_TX_CMD + CALL CHECK_ERROR + ENDM + + ; Print data ASCIIZ string to screen + MACRO PRINT data + LD HL,data + LD C,DSS_PCHARS + RST DSS + ENDM + + ; Print data ASCIIZ string to screen and CR+LF + MACRO PRINTLN data + LD HL,data + LD C,DSS_PCHARS + RST DSS + LD C,DSS_PCHARS + LD HL, WCOMMON.LINE_END + RST DSS + ENDM + + ; Print data ASCIIZ string to screen if TRACE enabled + MACRO TRACELN data + IF TRACE == 1 + PUSH BC,DE + PRINTLN data + POP DE,BC + ENDIF + ENDM diff --git a/sources/DSS/sim/ports.js b/sources/DSS/sim/ports.js new file mode 100644 index 0000000..9287bb0 --- /dev/null +++ b/sources/DSS/sim/ports.js @@ -0,0 +1,44 @@ +port_p0 = 0; +port_p1 = 1; +port_p2 = 2; +port_p3 = 3; +message = ""; + +// This function is called when time (t-states) advances. +API.tick = () => { +} + +// This function is called when an 'out' is executed in Z80. +API.writePort = (port, value) => { + // Go through all ports + if (port == 0x9000) { + if (value != 0) { + message += String.fromCharCode(value); + } else { + API.log("> " + message); + message = ""; + } + } else if (port == 0x82) { + port_p0 = value; + } else if (port == 0xA2) { + port_p1 = value; + } else if (port == 0xC2) { + port_p2 = value; + } else if (port == 0xE2) { + port_p3 = value; + } +} + + +API.readPort = (port) => { + if (port == 0x82) { + return port_p0; + } else if (port == 0xA2) { + return port_p1; + } else if (port == 0xC2) { + return port_p2; + } else if (port == 0xE2) { + return port_p3; + } +} + diff --git a/sources/DSS/sprinter.inc b/sources/DSS/sprinter.inc new file mode 100644 index 0000000..1a2037c --- /dev/null +++ b/sources/DSS/sprinter.inc @@ -0,0 +1,32 @@ +; ====================================================== +; Defines for Sprinter computer hardware +; By Roman Boykov. Copyright (c) 2024 +; https://github.com/romychs +; ====================================================== + +; Memory pages +PAGE0_ADDR EQU 0x0000 +PAGE1_ADDR EQU 0x4000 +PAGE2_ADDR EQU 0x8000 +PAGE3_ADDR EQU 0xC000 + +; Sprinter ports to switch mem pages +PAGE0 EQU 0x82 +PAGE1 EQU 0xA2 +PAGE2 EQU 0xC2 +PAGE3 EQU 0xE2 + +; CTC Control register ports +CTC_CH0 EQU 0x10 +CTC_CH1 EQU 0x11 +CTC_CH2 EQU 0x12 +CTC_CH3 EQU 0x13 + +CTC_CR_VEC EQU 0x01 ; 1 - Vector, 0 - Control +CTC_CR_SWR EQU 0x02 ; 1 - Software Reset, 0 - Continued operation +CTC_CR_TCF EQU 0x04 ; 1 - TYime const follows +CTC_CR_TTR EQU 0x08 ; 1 - Time trigger +CTC_CT_TRE EQU 0x10 ; 1 - Trigger Edge +CTC_CT_PRE EQU 0x20 ; 1 - 256 Prescaler, 0 - 16 +CTC_CT_CTR EQU 0x40 ; 0 - Timer, 1 - Counter +CTC_CT_EI EQU 0x80 ; Interrupt 1 - enable, 0 - disable diff --git a/sources/DSS/util.asm b/sources/DSS/util.asm new file mode 100644 index 0000000..3c16254 --- /dev/null +++ b/sources/DSS/util.asm @@ -0,0 +1,184 @@ +; ====================================================== +; Utility code for Sprinter-WiFi utilities +; By Roman Boykov. Copyright (c) 2024 +; https://github.com/romychs +; License: BSD 3-Clause +; ====================================================== + + MODULE UTIL + +; ------------------------------------------------------ +; Small delay +; Inp: HL - number of cycles, if HL=0, then 2000 +; ------------------------------------------------------ +DELAY + PUSH AF,BC,HL + + LD A,H + OR L + JR NZ,DELAY_NXT + LD HL,20 + +DELAY_NXT + CALL DELAY_1MS_INT + DEC HL + LD A,H + OR L + JP NZ,DELAY_NXT + + POP HL,BC,AF + RET + + + +DELAY_1MS_INT + LD BC,400 +SBD_NXT + DEC BC + LD A, B + OR C + JR NZ, SBD_NXT + RET + + + + +DELAY_1MS + PUSH BC + CALL DELAY_1MS_INT + POP BC + RET + +DELAY_100uS + PUSH BC + LD BC,40 + CALL SBD_NXT + POP BC + RET + + +; ------------------------------------------------------ +; Calc length of zero ended string +; Inp: HL - pointer to string +; Out: BC - length of string +; ------------------------------------------------------ +STRLEN + PUSH DE,HL,HL + LD BC,MAX_BUFF_SIZE + XOR A + CPIR + POP DE + SUB HL,DE ; llength of zero ended string + LD BC,HL + LD A, B + OR C + JR Z, STRL_NCOR + DEC BC +STRL_NCOR + POP HL,DE + RET + +; ------------------------------------------------------ +; Compare zero-ended strings +; Inp: HL, DE - pointers to strinngs to compare +; Out: CF=0 - equal, CF=1 - not equal +; ------------------------------------------------------ +STRCMP + PUSH DE,HL +STC_NEXT + LD A, (DE) + CP (HL) + JR NZ, STC_NE + AND A + JR Z, STC_EQ + INC DE + INC HL + JR STC_NEXT +STC_NE + SCF +STC_EQ + POP HL,DE + RET + +; ------------------------------------------------------ +; Convert string to number +; Inp: DE - ptr to zero ended string +; Out: HL - Result +; ------------------------------------------------------ +ATOU + PUSH BC + LD HL,0x0000 +ATOU_L1 + LD A,(DE) + AND A + JR Z, ATOU_LE + SUB 0x30 + CP 10 + JR NC, ATOU_LE + INC DE + LD B,H + LD C,L + ADD HL,HL + ADD HL,HL + ADD HL,BC + ADD HL,HL + ADD A,L + LD L,A + JR NC,ATOU_L1 + INC H + JP ATOU_L1 +ATOU_LE + POP BC + RET + + +; ------------------------------------------------------ +; Find char in string +; Inp: HL - ptr to zero endeds string +; A - char to find +; Outp: CF=0, HL points to char if found +; CF=1 - Not found +; ------------------------------------------------------ +STRCHR + PUSH BC +STCH_NEXT + LD C,A + LD A,(HL) + AND A + JR Z, STCH_N_FOUND + CP C + JR Z, STCH_FOUND + INC HL + JR STCH_NEXT +STCH_N_FOUND + SCF +STCH_FOUND + POP BC + RET + +; ------------------------------------------------------ +; Convert Byte to hex +; Inp: C +; Out: (DE) +; ------------------------------------------------------ +HEXB + LD A,C + RRA + RRA + RRA + RRA + CALL CONV_NIBLE + LD A,C +CONV_NIBLE + AND 0x0f + ADD A,0x90 + DAA + ADC A,0x40 + DAA + LD (DE), A + INC DE + RET + + + + ENDMODULE \ No newline at end of file diff --git a/sources/DSS/wcommon.asm b/sources/DSS/wcommon.asm new file mode 100644 index 0000000..8ca9a50 --- /dev/null +++ b/sources/DSS/wcommon.asm @@ -0,0 +1,272 @@ +; ====================================================== +; Common code for Sprinter-WiFi utilities +; By Roman Boykov. Copyright (c) 2024 +; https://github.com/romychs +; License: BSD 3-Clause +; ====================================================== + + MODULE WCOMMON + +; ------------------------------------------------------ +; Ckeck for error (CF=1) print message and exit +; ------------------------------------------------------ + +CHECK_ERROR + RET NC + ADD A,'0' + LD (COMM_ERROR_NO), A + PRINTLN MSG_COMM_ERROR + CALL DUMP_UART_REGS + LD B,3 + POP HL ; ret addr reset + +EXIT + CALL REST_VMODE + LD C,DSS_EXIT + RST DSS + +; ------------------------------------------------------ +; Search Sprinter WiFi card +; ------------------------------------------------------ +FIND_SWF + ; Find Sprinter-WiFi + CALL WIFI.UART_FIND + JP C, NO_TL_FOUND + LD A,(ISA.ISA_SLOT) + ADD A,'1' + LD (MSG_SLOT_NO),A + PRINTLN MSG_SWF_FOUND + RET + +NO_TL_FOUND + POP BC + PRINTLN MSG_SWF_NOF + LD B,2 + JP EXIT + + + IF TRACE +; ------------------------------------------------------ +; Dump all UTL16C550 registers to screen for debug +; ------------------------------------------------------ +DUMP_UART_REGS + ; Dump, DLAB=0 registers + LD BC, 0x0800 + CALL DUMP_REGS + + ; Dump, DLAB=1 registers + LD HL, REG_LCR + LD E, LCR_DLAB | LCR_WL8 + CALL WIFI.UART_WRITE + + LD BC, 0x0210 + CALL DUMP_REGS + + LD HL, REG_LCR + LD E, LCR_WL8 + CALL WIFI.UART_WRITE + RET + +DUMP_REGS + LD HL, PORT_UART_A + +DR_NEXT + LD DE,MSG_DR_RN + CALL UTIL.HEXB + INC C + + CALL WIFI.UART_READ + PUSH BC + LD C,A + LD DE,MSG_DR_RV + CALL UTIL.HEXB + PUSH HL + + PRINTLN MSG_DR + + POP HL,BC + INC HL + DJNZ DR_NEXT + RET + ENDIF + + +; ------------------------------------------------------ +; Store old video mode, set 80x32 and clear +; ------------------------------------------------------ +INIT_VMODE + PUSH BC,DE,HL + ; Store previous vmode + LD C,DSS_GETVMOD + RST DSS + LD (SAVE_VMODE),A + CP DSS_VMOD_T80 + ; Set vmode 80x32 + JR Z, IVM_ALRDY_80 + LD C,DSS_SETVMOD + LD A,DSS_VMOD_T80 + RST DSS +IVM_ALRDY_80 + ; Clear screen + LD A,' ' + LD B,0x07 + LD C,DSS_CLEAR + LD HL,0x2050 + LD DE,0x0000 + RST DSS + + POP HL,DE,BC + RET + +; ------------------------------------------------------ +; Restore saved video mode +; ------------------------------------------------------ +REST_VMODE + PUSH BC + LD A,(SAVE_VMODE) + CP DSS_VMOD_T80 + JR Z, RVM_SAME + ; Restore mode + PRINTLN MSG_PRESS_AKEY + + LD C, DSS_WAITKEY + RST DSS + + LD C,DSS_SETVMOD + RST DSS +RVM_SAME + POP BC + RET + +; ------------------------------------------------------ +; Init basic parameters of ESP +; ------------------------------------------------------ +INIT_ESP + PUSH BC, DE + LD DE, WIFI.RS_BUFF + LD BC, DEFAULT_TIMEOUT + + TRACELN MSG_ECHO_OFF + SEND_CMD CMD_ECHO_OFF + + TRACELN MSG_STATIOJN_MODE + SEND_CMD CMD_STATION_MODE + + TRACELN MSG_NO_SLEEP + SEND_CMD CMD_NO_SLEEP + + TRACELN MSG_SET_UART + SEND_CMD CMD_SET_SPEED + + TRACELN MSG_SET_OPT + SEND_CMD CMD_CWLAP_OPT + POP DE,BC + RET + +; ------------------------------------------------------ +; Set DHCP mode +; Out: CF=1 if error +; ------------------------------------------------------ +SET_DHCP_MODE + PUSH BC,DE + LD DE, WIFI.RS_BUFF + LD BC, DEFAULT_TIMEOUT + TRACELN MSG_SET_DHCP + SEND_CMD CMD_SET_DHCP + POP DE,BC + RET + +; ------------------------------------------------------ +; Messages +; ------------------------------------------------------ +MSG_SWF_NOF + DB "Sprinter-WiFi not found!",0 + +MSG_SWF_FOUND + DB "Sprinter-WiFi found in ISA#" +MSG_SLOT_NO + DB "n slot.",0 + +MSG_COMM_ERROR + DB "Error communication with Sprinter-WiFi #" +COMM_ERROR_NO + DB "n!",0 + +MSG_PRESS_AKEY + DB "Press any key to continue...",0 + +MSG_ESP_RESET + DB "Reset ESP module.",0 + +MSG_UART_INIT + DB "Reset UART.",0 + +LINE_END + DB "\r\n",0 + +SAVE_VMODE + DB 0 + +; ------------------------------------------------------ +; Debug messages +; ------------------------------------------------------ + IF TRACE + +MSG_DR + DB "Reg[0x" +MSG_DR_RN + DB "vv]=0x" +MSG_DR_RV + DB "vv",0 + +MSG_ECHO_OFF + DB "Echo off",0 + +MSG_STATIOJN_MODE + DB "Station mode",0 + +MSG_NO_SLEEP + DB "No sleep",0 + +MSG_SET_UART + DB "Setup uart",0 + +MSG_SET_OPT + DB "Set options",0 + +MSG_SET_DHCP + DB "Set DHCP mode",0 + + ENDIF + +; ------------------------------------------------------ +; Commands +; ------------------------------------------------------ +CMD_QUIT + DB "QUIT\r",0 + +CMD_VERSION + DB "AT+GMR\r\n",0 +CMD_SET_SPEED + DB "AT+UART_CUR=115200,8,1,0,3\r\n",0 +CMD_ECHO_OFF + DB "ATE0\r\n",0 +CMD_STATION_MODE + DB "AT+CWMODE=1\r\n",0 +CMD_NO_SLEEP + DB "AT+SLEEP=0\r\n",0 +CMD_CHECK_CONN_AP + DB "AT+CWJAP?\r\n",0 +CMD_CWLAP_OPT + DB "AT+CWLAPOPT=1,23\r\n",0 +CMD_GET_AP_LIST + DB "AT+CWLAP\r\n",0 +CMD_GET_DHCP + DB "AT+CWDHCP?\r\n",0 +CMD_SET_DHCP + DB "AT+CWDHCP=1,1\r\n",0 +CMD_GET_IP + DB "AT+CIPSTA?\r\n",0 + + + ENDMODULE \ No newline at end of file diff --git a/sources/DSS/wterm.asm b/sources/DSS/wterm.asm new file mode 100644 index 0000000..6d3c2ca --- /dev/null +++ b/sources/DSS/wterm.asm @@ -0,0 +1,242 @@ +; ====================================================== +; WTERM terminal for Sprinter-WiFi ISA Card +; For Sprinter computer DSS +; By Roman Boykov. Copyright (c) 2024 +; https://github.com/romychs +; License: BSD 3-Clause +; ====================================================== + +; Set to 1 to turn debug ON with DeZog VSCode plugin +; Set to 0 to compile .EXE +DEBUG EQU 0 + +; Set to 1 to output TRACE messages +TRACE EQU 1 + +; Version of EXE file, 1 for DSS 1.70+ +EXE_VERSION EQU 0 + +; Timeout to wait ESP response +DEFAULT_TIMEOUT EQU 2000 + + SLDOPT COMMENT WPMEM, LOGPOINT, ASSERTION + + DEVICE NOSLOT64K + + IF DEBUG == 1 + INCLUDE "dss.asm" + DB 0 + ALIGN 16384, 0 + DS 0x80, 0 + ENDIF + + INCLUDE "macro.inc" + INCLUDE "dss.inc" + INCLUDE "sprinter.inc" + + MODULE MAIN + + ORG 0x8080 +; ------------------------------------------------------ +EXE_HEADER + DB "EXE" + DB EXE_VERSION ; EXE Version + DW 0x0080 ; Code offset + DW 0 + DW 0 ; Primary loader size + DW 0 ; Reserved + DW 0 + DW 0 + DW START ; Loading Address + DW START ; Entry Point + DW STACK_TOP ; Stack address + DS 106, 0 ; Reserved + + ORG 0x8100 +@STACK_TOP + +; ------------------------------------------------------ +START + + IF DEBUG == 1 + ; LD IX,CMD_LINE1 + LD SP, STACK_TOP + ENDIF + + CALL ISA.ISA_RESET + + CALL WCOMMON.INIT_VMODE + + PRINTLN MSG_START + + CALL WCOMMON.FIND_SWF + + PRINTLN WCOMMON.MSG_UART_INIT + CALL WIFI.UART_INIT + + PRINTLN WCOMMON.MSG_ESP_RESET + CALL WIFI.ESP_RESET + + CALL WCOMMON.INIT_ESP + + PRINTLN MSG_HLP + + CALL WIFI.UART_EMPTY_RS + + XOR A + LD (Q_POS),A + +MAIN_LOOP + ; handle key pressed + LD C,DSS_SCANKEY + RST DSS + JP Z,HANDLE_RECEIVE ; if no key pressed + + ; check for QUIT command + LD A,(Q_POS) + CP 4 + JP P,NO_QUIT + + LD IX, CMD_QUIT +Q_POS EQU $+2 + LD A,(IX+0x00) + ; compare current char with "QUIT" str + CP E + JR NZ,NO_QUIT + + LD HL,Q_POS + INC (HL) + LD A,(HL) + CP 5 + JP Z,OK_EXIT + JR OUT_CHAR + +NO_QUIT + XOR A + LD (Q_POS), A + +OUT_CHAR + LD A, E + CP CR + JR Z, PUT_CHAR + CP 0x20 + JP M, HANDLE_CR_LF + +PUT_CHAR + CALL PUT_A_CHAR + +HANDLE_CR_LF + CALL WIFI.UART_TX_BYTE + JP C,TX_WARN + LD A, E + CP CR + JR NZ,NO_TX_LF + LD E,LF + CALL WIFI.UART_TX_BYTE + JP C,TX_WARN + JR HANDLE_RECEIVE + +NO_TX_LF + CP LF + JR NZ,HANDLE_RECEIVE + LD E,CR + CALL WIFI.UART_TX_BYTE + JP C,TX_WARN + + ; check receiver and handle received bytes +HANDLE_RECEIVE + ; check receiver status + LD HL,REG_LCR + CALL WIFI.UART_READ + CP LSR_RCVE + JP NZ, RX_WARN + CP LSR_DR + JP Z, CHECK_FOR_END + ; rx queue is not empty, read + LD HL,REG_RBR + CALL WIFI.UART_READ + LD E,A + CP CR + JR NZ, CHK_1F + ; print CR+LF + CALL PUT_A_CHAR + LD A,LF + CALL PUT_A_CHAR + JP CHECK_FOR_END + +CHK_1F + CP 0x20 + CALL P, PUT_A_CHAR + +CHECK_FOR_END + LD A,(Q_POS) + CP 5 + JP Z, OK_EXIT + JP MAIN_LOOP + +RX_WARN + LD C,A + LD DE,MSG_LSR_VALUE + CALL UTIL.HEXB + PRINTLN MSG_RX_ERROR + JP MAIN_LOOP + +TX_WARN + PRINTLN MSG_TX_ERROR + JP MAIN_LOOP + +PUT_A_CHAR + PUSH BC,DE + LD C,DSS_PUTCHAR + RST DSS + POP DE,BC + RET + + +; ------------------------------------------------------ +; Do Some +; ------------------------------------------------------ + +OK_EXIT + LD B,0 + JP WCOMMON.EXIT + + +; ------------------------------------------------------ +; Custom messages +; ------------------------------------------------------ + +MSG_START + DB "Terminal for Sprinter-WiFi by Sprinter Team. v1.0.1, ", __DATE__, "\r\n", 0 +MSG_HLP + DB"\r\nEnter ESP AT command or QUIT to close terminal.",0 + +MSG_TX_ERROR + DB "Transmitter not ready",0 + +MSG_RX_ERROR + DB "Receiver error LSR: 0x" +MSG_LSR_VALUE + DB "xx",0 + +; TX_DATA +; DB " ",0 +; ------------------------------------------------------ +; Custom commands +; ------------------------------------------------------ +CMD_QUIT + DB "QUIT\r",0 + + IF DEBUG == 1 +CMD_TEST1 DB "ATE0\r\n",0 +BUFF_TEST1 DS RS_BUFF_SIZE,0 + ENDIF + + ENDMODULE + + INCLUDE "wcommon.asm" + INCLUDE "util.asm" + INCLUDE "isa.asm" + INCLUDE "esplib.asm" + + END MAIN.START diff --git a/sources/esplib.c b/sources/esplib.c deleted file mode 100644 index 108c63b..0000000 --- a/sources/esplib.c +++ /dev/null @@ -1,314 +0,0 @@ -/* -================================================== - Implementation of Sprinter-WiFi ISA Card Library - Author: Roman A. Boykov - License: BSD 3-Clause -================================================== -*/ - -#include -#include -#include -#include -#include "esplib.h" - -#ifdef ESTEX -#pragma nonrec -#define outb(port, b) mset(port, b); -#define inb(port) mget(port); -#else -#define outb(port, b) outp(port, b); -#define inb(port) inp(port); -#endif - - -void util_delay(unsigned delay_ms) -{ -#ifdef ESTEX - if (delay_ms==0) { - delay_ms = 20; - } - unsigned ctr; - for (ctr = 0; ctr < delay_ms*1000; ctr++) - { - } -#else - clock_t t; - t = clock() + delay_ms; - while (clock() < t) { - } - - //delay(delay_ms); -#endif -} - -char save_mmu3 = 0; // Variable to save Sprinter memory mapping -char isa_slot = -1; // Variable to storeISA slot number where WiFi card found - -char isa_init() -{ - char wifi_found; - wifi_found = find_wifi(); - if (wifi_found) { - isa_reset(); - return 1; - } else { - return 0; - } -} - - -void isa_reset() -{ -#ifdef ESTEX - outp(port_isa, ISA_RESET | ISA_AEN); // RESET=1 AEN=1 - delay(20); - outp(port_isa, 0); // RESET=0 AEN=0 - delay(40); -#endif -} - - -void isa_open() -{ -#ifdef ESTEX - save_mmu3 = inp(PORT_MMU3); - outp(PORT_SYSTEM, 0x11); - outp(PORT_MMU3, ((isa_slot & 0x01) << 1) | 0xd4); -#endif -} - -void isa_close() -{ -#ifdef ESTEX - outp(PORT_SYSTEM, 0x01); - // restore mmu3 (Close ISA ports memory mapping) - outp(PORT_MMU3, save_mmu3); -#endif -} - -char isa_get_slot() -{ - return isa_slot; -} - -char check_slot(char slot) -{ - char irr; - isa_slot = slot; - isa_open(); - irr = inb(REG_IIR); - isa_close(); - return irr & 0x3F; -} - - -char find_wifi() -{ - // check isa slot 0 - char exists; - exists = check_slot(0); - if (exists) { - return 1; - } else { -#ifdef ESTEX - return check_slot(1); -#else - return 0; -#endif - } -} - - -// MODULE uart - -void uart_init() -{ - isa_open(); - // enable FIFO buffer, trigger to 14 byte - outb(REG_FCR, FCR_TR14 | FCR_FIFO); - // Disable interrupts - outb(REG_IER, 0x00); - // Set 8bit word and Divisor for speed - outb(REG_LCR, LCR_DLAB | LCR_WL8); // enable Baud rate latch - outb(REG_DLL, DIVISOR); - outb(REG_DLM, 0x00); - outb(REG_LCR, LCR_WL8); // 8bit word - isa_close(); -} - -char uart_read(reg) -unsigned reg; -{ - char res; - isa_open(); - res = inb(reg); - isa_close(); - return res; -} - -void uart_write(reg, value) -unsigned reg; -char value; -{ - isa_open(); - outb(reg, value); - isa_close(); -} - -char uart_wait_tr() -{ - char res; - char loops = 100; - while (loops>0) - { - res = uart_read(REG_LSR); - - if (res & LSR_THRE) { - break; - } - - loops--; - util_delay(1); - } - return loops; -} - -char uart_tx_byte(byte) -char byte; -{ - char ready = uart_wait_tr(); - if (ready){ - uart_write(REG_THR, byte); - } - return ready; -} - -char uart_tx_buffer(char* tbuff, int size) -{ - int ctr = size; - while (ctr--) { - if (uart_wait_tr()) { - uart_write(REG_THR, *tbuff++); - } else { - return RESULT_TX_TIMEOUT; - } - } - return RESULT_OK; -} - -char uart_tx_cmd(char* tx_buff, char* rs_buff, int size, int wait_ms) -{ - char resp = RESULT_OK; - char rcv, *buff; - char lstr[LSTR_SIZE]; - int lstrp = 0; - buff = rs_buff; - buff[size-1] = 0; // mark last byte of buffer as end of string - size--; - uart_empty_rs(); - - if (uart_tx_buffer(tx_buff, strlen(tx_buff)) == RESULT_OK) { - while (1) { - if (uart_wait_rs(wait_ms)) { - rcv = uart_read(REG_RBR); - if (size > 0 && rcv != CR) { // ignore CR - *buff++ = rcv; - size--; - } - if (rcv == CR || rcv == LF) { - - lstr[lstrp] = 0; - - if (strcmp(lstr, "OK")==0) { - break; - } - - if (strcmp(lstr, "ERROR")==0) { - resp = RESULT_ERROR; - break; - } - - if (strcmp(lstr, "FAIL")==0) { - resp = RESULT_FAIL; - break; - } - - lstrp = 0; - } - - if (lstrp 0) { - *buff = 0; // mark end of string - } -#ifdef DEBUG - printf(": '%s'\n", lstr); -#endif - } else { -#ifdef DEBUG - printf("Cmd transmit error, TR not ready!\n"); -#endif - return RESULT_TX_TIMEOUT; - } - return resp; -} - - -void uart_empty_rs() -{ - uart_write(REG_FCR, FCR_TR14 | FCR_RESET_RX | FCR_FIFO); -} - -char uart_wait_rs(wait_ms) -int wait_ms; -{ - char res; - unsigned loops; - - if (wait_ms<0) { - loops = 1; - } else { - loops = wait_ms; - } - - while (loops>0) { - res = uart_read(REG_LSR) & LSR_DR; - if (res){ - break; - } - loops--; - util_delay(1); - } - - return loops>0; -} - - - -void esp_reset(char full) -{ - isa_open(); - if (full) { - outb(REG_MCR, MCR_RST | MCR_RTS) // 0110b ESP -PGM=1, -RST=0, -RTS=0 - util_delay(20); - } - outb(REG_MCR, MCR_AFE | MCR_RTS) // 0x0202 -RST = 1 -RTS=0 AutoFlow enabled - isa_close(); - if (full) { - util_delay(1000); - } -} -