From f0d6b8e7d13d59bdd1fd30907aee818af11ff327 Mon Sep 17 00:00:00 2001 From: Nihirash Date: Sat, 24 Oct 2020 21:06:24 +0300 Subject: [PATCH] History refactoring. It fixes bug and adds multilevel history --- Makefile | 2 +- README.md | 8 +++- docs/index.gph | 2 +- drivers/esxdos.asm | 3 +- drivers/wifi.asm | 8 ++-- engine/engine.asm | 4 +- engine/fetcher.asm | 62 +++++++----------------------- engine/history.asm | 41 -------------------- engine/history/controller.asm | 72 +++++++++++++++++++++++++++++++++++ engine/history/index.asm | 1 + engine/history/model.asm | 30 +++++++++++++++ engine/media-processor.asm | 10 ++--- engine/resident-parts.asm | 14 +------ engine/urlencoder.asm | 28 ++++---------- main.asm | 41 ++++++++++---------- render/gopher-page.asm | 32 +++++----------- render/index.asm | 6 +-- render/ui.asm | 5 +-- 18 files changed, 177 insertions(+), 192 deletions(-) delete mode 100644 engine/history.asm create mode 100644 engine/history/controller.asm create mode 100644 engine/history/index.asm create mode 100644 engine/history/model.asm diff --git a/Makefile b/Makefile index 8162265..7e9fc81 100644 --- a/Makefile +++ b/Makefile @@ -8,4 +8,4 @@ cspect/test.nex: pages main.asm engine/*.* drivers/*.* render/*.* utils/*.* cp browser.nex cspect/ test: cspect/test.nex - cd cspect && mono CSpect.exe -w4 -nextrom -map=test.map -brk -tv -mmc=./../ -zxnext browser.nex + cd cspect && mono CSpect.exe -w5 -nextrom -map=test.map -brk -tv -mmc=./../ -zxnext browser.nex diff --git a/README.md b/README.md index 6247b71..1ddfc18 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ To compile project all you need is [sjasmplus](https://github.com/z00m128/sjasmp You may use or not use GNU Make. But for just build enought only sjasmplus: `sjasmplus --zxnext=cspect main.asm` -If you want run it in emulator - use CSpect with configured REAL ESP-module! Buildin ESP-emulator doesn't support all necessary commands. But if you want run it in CSpect with buildin emulator there is some hack: +If you want run it in emulator - use CSpect with configured REAL ESP-module! Buildin ESP-emulator doesn't support all necessary commands. But if you want run it in CSpect with buildin emulator there is some hack(but it will work very bad): * Found in `drivers` directory file `wifi.asm`. @@ -35,6 +35,8 @@ And this I've tried organize code for eaiser location all parts and wish you won't have issues with it. If there are some issues with it - feel free write me about it. +To bundle browser include `browser.nex` file and `docs/` directory in single package(should be placed in same directory). + ## Usage Before usage you should have already configured wifi chip(via wifi.bas/wifi2.bas located at demos/esp in Next distro). @@ -60,7 +62,9 @@ Sometimes it's crashes. I didn't found reason - if you find it - please let me k Still not possible download files. Sorry. ## Development plan - +- [X] Publish first version and get first happy users +- [X] Fix history bugs +- [X] Make history multilevel - [ ] Add file downloads using proxy server - [ ] Add mouse support - [ ] Automatic change song to next(if it goes as next link on page) diff --git a/docs/index.gph b/docs/index.gph index 4814728..90e0eba 100644 --- a/docs/index.gph +++ b/docs/index.gph @@ -9,7 +9,7 @@ i Arrow Right or P - page down - - - i Arrow Left or O - page up - - - i Enter - visit link - - - i N - enter new domain - - - -i B - history back(currently work only on one level) - - - +i B - history back(currently work only few levels) - - - i H - return to this page - - - i - - - iIf you like my software - support it via PayPal donation: - - - diff --git a/drivers/esxdos.asm b/drivers/esxdos.asm index cef5cf3..2cb56dd 100644 --- a/drivers/esxdos.asm +++ b/drivers/esxdos.asm @@ -26,11 +26,10 @@ loadBuffer: ld b, Dos.FMODE_READ: call Dos.fopen push af ld hl, buffer, bc, #ffff - buffer : call Dos.fread - ld hl, buffer : add hl, bc : xor a : ld (hl), a + ld hl, buffer : add hl, bc : xor a : ld (hl), a : inc hl : ld (hl), a pop af call Dos.fclose ei - xor a : ld (Render.cursor_position), a, (Render.page_offset), a ret ; Returns: diff --git a/drivers/wifi.asm b/drivers/wifi.asm index 1c813f9..268f854 100644 --- a/drivers/wifi.asm +++ b/drivers/wifi.asm @@ -1,5 +1,4 @@ MODULE Wifi -inited db 0 bytes_avail dw 0 buffer_pointer dw 0 closed db 1 @@ -8,12 +7,13 @@ init: call Uart.init EspCmdOkErr "ATE0" jr c, .initError - EspCmdOkErr "AT+CIPCLOSE" ; Close if there some connection was. Don't care about result EspCmdOkErr "AT+CIPSERVER=0" - EspCmdOkErr "AT+CIPDINFO=0" ; Disable additional info - jr c, .initError + EspCmdOkErr "AT+CIPCLOSE" ; Close if there some connection was. Don't care about result EspCmdOkErr "AT+CIPMUX=0" ; Single connection mode jr c, .initError + + EspCmdOkErr "AT+CIPDINFO=0" ; Disable additional info + jr c, .initError or a ret .initError diff --git a/engine/engine.asm b/engine/engine.asm index 837001e..9d24909 100644 --- a/engine/engine.asm +++ b/engine/engine.asm @@ -1,4 +1,4 @@ + include "history/index.asm" include "urlencoder.asm" include "fetcher.asm" - include "media-processor.asm" - include "history.asm" \ No newline at end of file + include "media-processor.asm" \ No newline at end of file diff --git a/engine/fetcher.asm b/engine/fetcher.asm index 6f73e74..181b562 100644 --- a/engine/fetcher.asm +++ b/engine/fetcher.asm @@ -1,57 +1,25 @@ MODULE Fetcher -; HL - pointer to gopher page line -; C flag - is error happens -fetch: - call History.save -.skipHistory - push hl - ld hl, .msg : call DialogBox.msgNoWait - pop hl - push hl - ld a, (hl) : call Render.getIcon - ld (MediaProcessor.media_type), a - pop hl : push hl - call UrlEncoder.isFile - pop hl - jp c, fetchFromFS - push hl - call UrlEncoder.isValidGopherRow - pop hl - jr c, fetchFromNet - scf - ret -.msg db "Loading resource! Please wait! It will be here soon!", 0 ; HL - pointer to gopher page line fetchFromNet: - ld a, 9, bc, #ff : cpir - ld de, requestBuffer + ld hl, historyBlock.locator, de, requestBuffer .copyRequest ld a, (hl) - cp 9 - jr z, .urlCopied + and a : jr z, .urlCopied ld (de), a inc hl, de - ; TODO add search request support jp .copyRequest .urlCopied xor a : ld (de), a .getDomainAndHost - ld a, 9, bc, #ff : cpir - push hl ; domain - ld a, 9, bc, #ff : cpir - ; hl - host - pop de ; de - port - ex hl, de + ld hl, historyBlock.host, de, historyBlock.port call Wifi.openTCP jr c, .error - ld hl, buffer, de, buffer + 1, bc, #ffff - buffer - 1, (hl), a - ldir - ld a, (Render.isInputRequest) : and a : jr z, .performRequest + ld a, (historyBlock.mediaType) : cp Font.INPUT : jr nz, .performRequest ld a, 0, bc, #ff, hl, requestBuffer : cpir : dec hl ld a, 9, (hl), a : inc hl - ld de, DialogBox.inputBuffer + ld de, historyBlock.search .loadSearchRequest ld a, (de) : ld (hl), a : and a : jr z, .performRequest inc hl, de @@ -64,25 +32,21 @@ fetchFromNet: call Wifi.getPacket ld a, (Wifi.closed) : and a : jr nz, .closedCallback jr .loadPackets -.error - scf +.error + ld hl, .err : call DialogBox.msgBox + jp History.back ret .closedCallback - - or a - ret + jp MediaProcessor.processResource +.err db "Document fetch error! Check your connection or hostname!", 0 -; HL - pointer to gopher page line fetchFromFS: + xor a : ld hl, buffer, de, buffer + 1, bc, #ffff - buffer - 1, (hl), a : ldir + call UrlEncoder.extractPath loadFile - xor a : ld (de), a - - ld hl, buffer, de, buffer + 1, bc, #ffff - buffer - 1, (hl), a - ldir ld hl, nameBuffer : call Dos.loadBuffer - or a - ret + jp MediaProcessor.processResource requestBuffer ds #ff ENDMODULE \ No newline at end of file diff --git a/engine/history.asm b/engine/history.asm deleted file mode 100644 index 30c55c7..0000000 --- a/engine/history.asm +++ /dev/null @@ -1,41 +0,0 @@ - MODULE History -back: - ld hl, prev - ld a, (History.input), (Render.isInputRequest), a - call Fetcher.fetch.skipHistory - ld hl, prev, de, row, bc, #ff : ldir - ld hl, (History.position), (Render.position), hl - jp MediaProcessor.processResource - -home: - ld hl, homePage : call Fetcher.fetch - jp MediaProcessor.processResource - -refresh: - ld a, (History.input), (Render.isInputRequest), a - ld hl, row : call Fetcher.fetch.skipHistory - jp MediaProcessor.processResource - -save: - push bc - push hl - push de - - push hl - ld hl, (Render.position), (History.position), hl, hl, 0, (Render.position), hl - ld a, (Render.isInputRequest), (History.input), a - ld hl, row, de, prev, bc, #ff : ldir - pop hl - ld de, row -.loop - ld a, (hl) : ldi - cp 13 : jr z, .exit - cp 10 : jr z, .exit - jr .loop -.exit - pop de - pop hl - pop bc - ret - - ENDMODULE diff --git a/engine/history/controller.asm b/engine/history/controller.asm new file mode 100644 index 0000000..c90c4df --- /dev/null +++ b/engine/history/controller.asm @@ -0,0 +1,72 @@ + MODULE History + +back: + ld a, (depth) : cp 1 : ret z + ld hl, historyBlock + HistoryRecord, de, historyBlock, bc, (total - 1) * HistoryRecord : ldir ; Move history up + ld hl, depth : dec (hl) +; Loads current resource +load: + ld hl, .msg : call DialogBox.msgNoWait + xor a : ld hl, buffer, de, buffer + 1, bc, #ffff - buffer - 1, (hl), a : ldir + + ld a, (historyBlock.isFile) : and a : jp nz, Fetcher.fetchFromFS + jp Fetcher.fetchFromNet + +.msg db "Loading resource! Please wait! It will be here soon!", 0 + +home: + ld hl, homePage +; HL - gopher row +navigate: + ld de, hl + call UrlEncoder.isValidGopherRow + jr nc, load ; Not valid - reload last + ld hl, de + push hl + + push hl + ld hl, HistoryEnd - HistoryRecord, de, HistoryEnd, bc, HistoryRecord * total : lddr + pop hl + + ; Fill record + ld de, hl + call UrlEncoder.isFile + ex hl, de + ld de, historyBlock + ld (de), a : inc de + ld a, (hl) : push hl, de : call Render.getIcon : pop de, hl + ld (de), a : inc de + ld a, 9, bc, #ff : cpir +.locatorCopy + ld a, (hl) : cp 9 : jr z, 1f + ld (de), a : inc hl, de + jr .locatorCopy +1 + inc hl : xor a : ld (de), a + ld de, historyBlock.host +.hostCopy + ld a, (hl) : cp 9 : jr z, 1f + ld (de), a : inc hl, de + jr .hostCopy +1 + inc hl : xor a : ld (de), a + ld de, historyBlock.port +.portCopy + ld a, (hl) + cp 9 : jr z, 1f + cp 13 : jr z, 1f + cp 10 : jr z, 1f + cp 0 : jr z, 1f + ld (de), a : inc hl, de + jr .portCopy +1 xor a : ld (de), a + ld hl, DialogBox.inputBuffer, de, historyBlock.search, bc, #ff : ldir + ld de, (Render.position), (historyBlock.position + HistoryRecord), de + ld de, 0, (historyBlock.position), de + pop hl + ld a, (depth) : cp total : jr nc, 1f + inc a : ld (depth), a +1 + jp load + + ENDMODULE diff --git a/engine/history/index.asm b/engine/history/index.asm new file mode 100644 index 0000000..e46d3a5 --- /dev/null +++ b/engine/history/index.asm @@ -0,0 +1 @@ + include "controller.asm" \ No newline at end of file diff --git a/engine/history/model.asm b/engine/history/model.asm new file mode 100644 index 0000000..40f5600 --- /dev/null +++ b/engine/history/model.asm @@ -0,0 +1,30 @@ +; This shit brokes adressing!!!! +; +; STRUCT HistoryRecord +;isFile BYTE +;mediaType BYTE +;locator BLOCK #ff +;host BLOCK 64 ; If you'll use longer host name - you're "сам себе злобный буратино"(you're your only enemy) +;port BLOCK 6 ; can be up to 65535 +;search BLOCK #FF +;position WORD #00 +; ENDS + + +total equ 5 +depth db 0 + +historyBlock: +.isFile db 0 +.mediaType db 0 +.locator ds #ff +.host ds 64 +.port ds 6 +.search ds #ff +.position dw #00 + +HistoryRecord EQU $ - historyBlock + dup total + ds HistoryRecord + edup +HistoryEnd equ $ - 1 diff --git a/engine/media-processor.asm b/engine/media-processor.asm index 438e4d0..19b9d70 100644 --- a/engine/media-processor.asm +++ b/engine/media-processor.asm @@ -1,11 +1,7 @@ MODULE MediaProcessor - -media_type db 2 ; Same as icon - processResource: call UrlEncoder.extractHostName - - ld a, (media_type) + ld a, (historyBlock.mediaType) cp Font.LINK : jr z, processPage cp Font.INPUT : jr z, processPage cp Font.MUSIC : jr z, processPT @@ -17,7 +13,7 @@ processText: processPT: call VortexProcessor.play - jp History.refresh + jp History.back processPage: call Render.renderGopherScreen @@ -25,6 +21,6 @@ processPage: processImage: call ScreenViewer.display - jp History.refresh + jp History.back ENDMODULE \ No newline at end of file diff --git a/engine/resident-parts.asm b/engine/resident-parts.asm index 4b0eefa..b873d8d 100644 --- a/engine/resident-parts.asm +++ b/engine/resident-parts.asm @@ -1,14 +1,4 @@ -nameBuffer db "index.gph", 0 - ds #7f - ($ - nameBuffer), 0 +nameBuffer ds #ff, 0 db 0 -hostName ds 48 - - MODULE History -row db "1Starting page", 09, "index.gph", 09, "file", 09, "70", 13, 10 - ds #ff - ($ - row) -prev db "1Starting page", 09, "index.gph", 09, "file", 09, "70", 13, 10 - ds #ff - ($ - prev) -position dw 0 -input db 0 - ENDMODULE \ No newline at end of file +hostName ds 64 diff --git a/engine/urlencoder.asm b/engine/urlencoder.asm index 52a884a..54bfdf6 100644 --- a/engine/urlencoder.asm +++ b/engine/urlencoder.asm @@ -18,10 +18,10 @@ isFile: ld a, (hl) : cp "l" : jr nz, .notFile : inc hl ld a, (hl) : cp "e" : jr nz, .notFile : inc hl ld a, (hl) : cp 9 : jr nz, .notFile : inc hl - scf + ld a, 1 ret .notFile - or a + xor a ret ; Is enough fields to encode @@ -46,26 +46,12 @@ isValidGopherRow: scf ret -; HL - pointer to gopher page line extractPath: - ld a, 9, bc, #ff : cpir - ld de, nameBuffer -.loop - ld a, (hl) : cp 9 : ret z : and a : ret z - ld (de), a : inc hl, de - jr .loop + ld hl, historyBlock.locator, de, nameBuffer, bc, #ff : ldir + ret extractHostName: - xor a - ld hl, hostName, de, hostName + 1, bc, 47, (hl), a : ldir - - ld hl, History.row - ld a, 9, bc, #ff : cpir - ld bc, #ff : cpir - ld de, hostName -.loop - ld a, (hl) : cp 9 : ret z : and a : ret z : cp 13 : ret z - ld (de), a : inc hl, de - jr .loop - + ld hl, historyBlock.host, de, hostName, bc, 64 : ldir + ret + ENDMODULE \ No newline at end of file diff --git a/main.asm b/main.asm index 0daf935..42d8dfd 100644 --- a/main.asm +++ b/main.asm @@ -4,56 +4,57 @@ ;DEFINE WIFI_DEBUG ;DEFINE EMU + SLOT0_PAGE = 16 SLOT1_PAGE = 17 ;; 0x0000 - 0x2000 - MMU 0 e, SLOT0_PAGE + MMU 0 1, SLOT0_PAGE ORG #38 push af, bc, de, hl, ix call Keyboard.update pop ix, hl, de, bc, af ei ret - include "drivers/utils.asm" - include "drivers/keyboard.asm" - include "drivers/tile-driver.asm" - include "engine/engine.asm" - include "utils/limitedstring.asm" - include "player/index.asm" - include "screen-viewer/index.asm" - include "drivers/uart.asm" - include "drivers/wifi.asm" - DISPLAY "Page 16 memory left: ", #2000 - $ - - MMU 1 e, SLOT1_PAGE - ORG #2000 -; Currently unused + + include "drivers/utils.asm" + include "drivers/keyboard.asm" + include "drivers/tile-driver.asm" + include "engine/engine.asm" + include "utils/limitedstring.asm" + include "player/index.asm" + include "screen-viewer/index.asm" + include "drivers/uart.asm" + include "drivers/wifi.asm" + ; Render + include "render/index.asm" + ; History data placed here + include "engine/history/model.asm" + DISPLAY "History ends: ", $ ORG #8000 Start: nextreg 7, 3 + ld sp, stack nextreg Slot_0_Reg, SLOT0_PAGE nextreg Slot_1_Reg, SLOT1_PAGE call TextMode.init call Wifi.init - ld hl, homePage : call Fetcher.fetch : jp MediaProcessor.processResource + jp History.home include "engine/resident-parts.asm" - -homePage db "1 ",9, "docs/index.gph", 9, "file", 9, " ",13,10,0 +homePage db "1Home page",9, "docs/index.gph", 9, "file", 9, "70",13,10,0 ds 255 stack = $ - 1 include "drivers/esxdos.asm" - include "render/index.asm" include "utils/comparebuff.asm" buffer: DISPLAY "Page buffer ", $ - ds 32, 0 + ds 32,0 SAVENEX OPEN "browser.nex", Start, stack, 0 , 2 SAVENEX CORE 3,0,0 : SAVENEX CFG 0 diff --git a/render/gopher-page.asm b/render/gopher-page.asm index f1fee47..7623583 100644 --- a/render/gopher-page.asm +++ b/render/gopher-page.asm @@ -1,8 +1,4 @@ - -isInputRequest db 0 - renderGopherScreen: - xor a : ld (isInputRequest), a call prepareScreen ld b, PER_PAGE .loop @@ -60,27 +56,19 @@ workLoop: navigate: ld a, (page_offset), b, a, a, (cursor_position) : add b : ld b, a : call Render.findLine ld a, (hl) - cp '1' : jp z, .page - cp '0' : jp z, .page - cp '9' : jp z, .fetch + cp '1' : jp z, .load + cp '0' : jp z, .load + cp '9' : jp z, .load cp '7' : jp z, .input jp workLoop -.page - call Fetcher.fetch - jr .f2 -.fetch - ld de, (Render.position), (History.position), de - call Fetcher.fetch.skipHistory -.f2 - jp nc, MediaProcessor.processResource - ld hl, loadingErrorMsg : call DialogBox.msgBox - jp History.back +.load + jp History.navigate .input push hl call DialogBox.inputBox - ld a, 1 : ld (isInputRequest), a pop hl - jr .page + ld a, (DialogBox.inputBuffer) : and a : jp z, workLoop + jr .load cursorDown: call hideCursor @@ -108,11 +96,9 @@ pageUp: call renderGopherScreen jp workLoop .skip - xor a : ld (cursor_position), a : call showCursor : jp workLoop + xor a : ld (cursor_position), a : call renderGopherScreen : jp workLoop pageDn: xor a : ld (cursor_position), a ld a, (page_offset) : add PER_PAGE : ld (page_offset), a - jr pageUp.exit - -loadingErrorMsg db "Document fetch error! Check your connection or hostname!", 0 \ No newline at end of file + jr pageUp.exit \ No newline at end of file diff --git a/render/index.asm b/render/index.asm index b815123..db8bd91 100644 --- a/render/index.asm +++ b/render/index.asm @@ -7,9 +7,9 @@ WAIT_FRAMES = 3 include "gopher-page.asm" include "plaintext.asm" -position: -cursor_position db 0 -page_offset db 0 +position EQU historyBlock.position +cursor_position EQU position + 1 +page_offset EQU position ENDMODULE include "dialogbox.asm" \ No newline at end of file diff --git a/render/ui.asm b/render/ui.asm index e76c955..7975a7a 100644 --- a/render/ui.asm +++ b/render/ui.asm @@ -55,10 +55,7 @@ inputNavigate: ld a, '0' : ld (de), a : inc de ld a, 13 : ld (de), a : inc de ld a, 10 : ld (de), a : inc de - ld hl, navRow : call Fetcher.fetch - jp nc, MediaProcessor.processResource - ld hl, loadingErrorMsg : call DialogBox.msgBox - jp History.back + ld hl, navRow : call History.navigate navRow db "1 ", 9, "/", 9 domain ds 64