Version 0.1

This commit is contained in:
nihirash 2019-06-25 22:27:29 +03:00
commit e5b6f1e91e
16 changed files with 2217 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
*.tap
ugoph.bin
.vscode

7
Makefile Normal file
View File

@ -0,0 +1,7 @@
all: ugoph.tap
ugoph.tap: *.asm *.pg
sjasmplus main.asm
clean:
rm *.tap

71
esxdos.asm Normal file
View File

@ -0,0 +1,71 @@
; API methods
ESX_GETSETDRV = #89
ESX_FOPEN = #9A
ESX_FCLOSE = #9B
ESX_FSYNC = #9C
ESX_FREAD = #9D
ESX_FWRITE = #9E
; File modes
FMODE_READ = #01
FMODE_WRITE = #06
FMODE_CREATE = #0E
; Returns:
; A - current drive
getDefaultDrive:
ld a, 0
rst #8
defb ESX_GETSETDRV
ret
; Opens file on default drive
; B - File mode
; HL - File name
; Returns:
; A - file stream id
fopen:
push bc
push hl
call getDefaultDrive
pop ix
pop bc
rst #8
defb ESX_FOPEN
ret
; A - file stream id
fclose:
rst #8
defb ESX_FCLOSE
ret
; A - file stream id
; BC - length
; HL - buffer
; Returns
; BC - length(how much was actually read)
fread:
push hl
pop ix
rst #8
defb ESX_FREAD
ret
; A - file stream id
; BC - length
; HL - buffer
; Returns:
; BC - actually written bytes
fwrite:
push hl
pop ix
rst #8
defb ESX_FWRITE
ret
; A - file stream id
fsync:
rst #8
defb ESX_FSYNC
ret

BIN
font.bin Normal file

Binary file not shown.

217
gopher.asm Normal file
View File

@ -0,0 +1,217 @@
; hl - server
; de - path
; bc - port
openPage:
push hl
push de
push bc
ex hl, de
ld de, hist
ld bc, 147
ldir
ld hl, page_buffer
xor a
ld (hl), a
ld de, page_buffer + 1
ld bc, 32767
ldir
pop bc
pop de
pop hl
call makeRequest
ld hl, page_buffer
call loadData
xor a
ld (show_offset), a
ld a, 1
ld (cursor_pos), a
ret
; HL - domain stringZ
; DE - path stringZ
; BC - port stringZ
makeRequest:
push de
push bc
push HL
ld hl, downloading_msg
call showTypePrint
ld hl, cmd_open1 ; Open TCP connection
call uartWriteStringZ
pop hl
call uartWriteStringZ
ld hl, cmd_open2
call uartWriteStringZ
pop hl
call uartWriteStringZ
ld hl, cmd_open3
call okErrCmd
cp 1
jp nz, reqErr
ld hl, cmd_send ; Send request
call uartWriteStringZ
pop hl
push hl
call getStringLength ; Calculate addr length
push bc
pop hl
inc hl ; CR
inc hl ; LF
call B2D16 ; To string
ld hl, B2DBUF
call SkipWhitespace
call uartWriteStringZ
ld hl, crlf
call okErrCmd
cp 1
jp nz, reqErr
wPrmt:
call uartReadBlocking
call pushRing
ld hl, send_prompt
call searchRing
cp 1
jr nz, wPrmt
pop hl
call uartWriteStringZ
ld hl, crlf
call uartWriteStringZ
ld a, 1
ld (connectionOpen), a
ret
reqErr
ld hl, connectionError
call putStringZ
xor a
ld (connectionOpen), a
ret
; Load data to ram via gopher
; HL - data pointer
; In data_recv downloaded volume
loadData:
ld (data_pointer), hl
ld hl, 0
ld (data_recv), hl
lpLoop:
call getPacket
ld a, (connectionOpen)
and a
jp z, ldEnd
ld bc, (bytes_avail)
ld de, (data_pointer)
ld hl, output_buffer
ldir
ld hl, (data_pointer)
ld de, (bytes_avail)
push de
add hl, de
ld (data_pointer), hl
pop de
ld hl, (data_recv)
add hl, de
ld (data_recv), hl
jp lpLoop
ldEnd
xor a
ld (data_pointer), a
ret
; Download file via gopher
; HL - filename
downloadData:
ld b, FMODE_CREATE
call fopen
ld (fstream), a
dwnLp:
call getPacket
ld a, (connectionOpen)
and a
jp z, dwnEnd
ld bc, (bytes_avail)
ld hl, output_buffer
ld a, (fstream)
call fwrite
ld a, (fstream)
call fsync
jp dwnLp
dwnEnd:
ld a, (fstream)
call fclose
ret
openURI:
call cleanIBuff
ld b, 19
ld c, 0
call gotoXY
ld hl, cleanLine
call printZ64
ld b, 19
ld c, 0
call gotoXY
ld hl, hostTxt
call printZ64
call input
ld b, 19
ld c, 0
call gotoXY
ld hl, cleanLine
call printZ64
ld hl, iBuff
ld a, (hl)
and a
ret z
ld de, d_host
ld bc, 65
ldir
ld hl, d_host
ld de, d_path
ld bc, d_port
call openPage
jp showPage
ret
data_pointer defw #4000
data_recv defw 0
fstream defb 0
closed_callback
xor a
ld (connectionOpen), a
ret
hostTxt db 'Enter host: ', 0
d_path db '/'
defs 69
d_host defs 70
d_port db '70'
defs 5
hist ds 147
connectionOpen db 0
downloading_msg db 'Downloading...', 0
connectionError db 'Cant open TCP connection', 0

176
http.asm Normal file
View File

@ -0,0 +1,176 @@
; Some parts taken from ZiFi sources
; Performs HTTP-get request
; First packet will be in var 'output_buffer'
; received packet size in var 'bytes_avail'
;
; HL - url includes http:// header
httpGet ld de,cmd_conn2site_adr
pu1 ld a,(hl) ; http://
inc hl
cp "/"
jr nz,pu1
inc hl ; /
ld bc,"//"
ld (host_url+1),hl
call find_copy_char
inc hl
ld (file_url+1),hl
create_link1 ld hl,create_link_suffix
ld bc,7
ldir
ld hl,modem_command
ld (hl),"G"
inc hl
ld (hl),"E"
inc hl
ld (hl),"T"
inc hl
ld (hl)," "
inc hl
ld (hl),"/"
inc hl
ex hl,de
file_url ld hl,0
ld bc,#0d0a
call find_copy_char
ld hl,http_part1
ld bc,http_part2-http_part1
ldir
host_url ld hl,0
ld bc,"//"
call find_copy_char
ld a,13
ld (de),a
inc de
ld a,10
ld (de),a
inc de
ld hl,http_part2
ld bc,http_part3-http_part2
ldir
ex de,hl
ld de,modem_command
or a
sbc hl,de
ld de,url_len
ld bc,-1000
call Num1
cp "0"
jr z,1f
ld (de),a
inc de
1 ld bc,-100
call Num1
ld (de),a
inc de
1 ld c,-10
call Num1
ld (de),a
inc de
1 ld c,-1
call Num1
ld (de),a
inc de
ld a,#0d
ld (de),a
inc de
ld a,#0a
ld (de),a
inc de
xor a
ld (de),a
jr firstPacket
Num1: ld a,'0'-1
Num2: inc a
add hl,bc
jr c,Num2
sbc hl,bc
ret
find_copy_char ld a,(hl)
cp c
ret z
cp b
ret z
ld (de),a
inc hl
inc de
jr find_copy_char
firstPacket:
call performRequest
skipHeaders:
ld de, output_buffer
ld bc, 0
shLp:
ld a, (de)
push de
push bc
call pushRing
ld hl, headers_end
call searchRing
pop bc
pop de
inc de
inc bc
cp 1
jr nz, shLp
ld hl, (bytes_avail)
sbc hl, bc
ld (bytes_avail), hl
push hl
pop bc
push de
ld de, output_buffer
pop hl
ldir
ret
performRequest:
ld hl, cmd_conn2site
call okErrCmd
cp 1
jr z, zg_ok
ld hl, cmd_close
call okErrCmd
jr performRequest
zg_ok:
ld hl, cmd_cipsend
call okErrCmd
guLp:
call uartReadBlocking
call pushRing
ld hl, send_prompt
call searchRing
cp 1
jr nz, guLp
ld hl, modem_command
call okErrCmd
jp getPacket
create_link_suffix
db #22,",80",13,10,0
display $
modem_command ds 256+128
display $
http_part1 db " HTTP/1.0",13,10 ;size=123
db "Host: "
http_part2 db "User-Agent: ZX Uno(Z80 CPU)",13,10 ; show off ;)
db "Accept: */*",13,10
db "Connection: close",13,10,13,10
http_part3
cmd_conn2site defb "AT+CIPSTART=", 0x22,"TCP",0x22,",",0x22
cmd_conn2site_adr ds #40
headers_end defb 13,10,13,10,0
cmd_cipsend defb "AT+CIPSEND="
url_len defs 6
defb 0

13
index.pg Normal file
View File

@ -0,0 +1,13 @@
iWecome to uGophy - ZX-Uno's gopher client! fake (NULL) 0
i(c) 2019 Alexander Sharikhin aka Nihirash fake (NULL) 0
iVersion 0.1 - First public release fake (NULL) 0
i fake (NULL) 0
iNavigation keys: fake (NULL) 0
i Q - Up fake (NULL) 0
i A - Down fake (NULL) 0
i B - History back fake (NULL) 0
i O - Enter server name to browse(using port 70) fake (NULL) 0
i Enter - visit page/download file fake (NULL) 0
i fake (NULL) 0
iYou may visit: fake (NULL) 0
1Nihirash.net - there you can download my software / nihirash.net 70

99
keyboard.asm Normal file
View File

@ -0,0 +1,99 @@
CURKEY = 23560
; Returns in A key code or zero if key wans't pressed
inkey:
ld hl, CURKEY
ld a, (hl)
push af
xor a
ld (hl), a
pop af
ret
findZero:
ld a, (hl)
or a
ret z
inc hl
jp findZero
input:
ld b, 20
ld c, 0
call gotoXY
ld hl, cleanLine
call printZ64
ld hl, iBuff
call findZero
iLp:
halt
push hl
ld b, 20
ld c, 0
call gotoXY
ld hl, iBuff
call printZ64
ld a, '_'
call putC
ld a, ' '
call putC
call inkey
cp 0
jr z, iNth
cp 12
jr z, iBS
cp 13
jr z, iRet
pop hl
ld (hl), A
push hl
ld de, iBuff + 62
sub hl, de
ld a, h
or l
jr z, iCr
pop hl
inc hl
jr iLp
iBS: pop hl
push hl
ld de, iBuff
sub hl, de
ld a, h
or l
pop hl
jr z, iLp
dec hl
ld (hl), 0
jr iLp
iCr pop hl
xor a
ld (hl), a
push hl
iNth pop hl
jr iLp
cleanIBuff:
ld bc, 64
ld hl, iBuff
ld de, iBuff + 1
ld (hl), 0
ldir
ret
iRet:
ld b, 20
ld c, 0
call gotoXY
ld hl, cleanLine
call printZ64
ret
iBuff defs 65

36
main.asm Normal file
View File

@ -0,0 +1,36 @@
DEVICE ZXSPECTRUM48
org 24100
Start:
call renderHeader
call initWifi
jp showPage
wSec: ld b, 50
wsLp halt
djnz wsLp
include "screen64.asm"
include "keyboard.asm"
include "utils.asm"
include "wifi.asm"
include "gopher.asm"
include "render.asm"
include "textrender.asm"
include "uart.asm"
include "ring.asm"
include "esxdos.asm"
open_lbl db 'Opening connection to ', 0
path db '/'
defs 69
server db 'nihirash.net'
defs 58
port db '70'
defs 5
data_buff defs 255
page_buffer
incbin "index.pg"
db 0
eop equ $
SAVEBIN "ugoph.bin", Start, eop-Start

451
render.asm Normal file
View File

@ -0,0 +1,451 @@
showPage:
xor a
ld (show_offset), a
ld a, 1
ld (cursor_pos), a
call renderScreen
call showCursor
showLp:
call controls
dup 5
halt
edup
jr showLp
controls:
call inkey
cp 0
ret z
cp 'q'
jr z, pageCursorUp
cp 'a'
jr z, pageCursorDown
cp 13
jp z, selectItem
cp 'b'
jr z, historyBack
cp 'o'
jp z, openURI
ret
historyBack:
ld hl, server
ld de, path
ld bc, port
call openPage
jp showPage
pageCursorUp:
ld a, (cursor_pos)
dec a
cp 0
jp z, pageScrollUp
push af
call hideCursor
pop af
ld (cursor_pos), a
call showCursor
ret
pageCursorDown:
ld a, (cursor_pos)
inc a
cp 21
jp z, pageScrollDn
push af
call hideCursor
pop af
ld (cursor_pos), a
call showCursor
ret
pageScrollDn:
ld hl, (show_offset)
ld de, 20
add hl, de
ld (show_offset), hl
ld a, 1
ld (cursor_pos), a
call renderScreen
call showCursor
ret
pageScrollUp:
ld a, (show_offset)
and a
ret z
ld hl, (show_offset)
ld de, 20
sub hl, de
ld (show_offset), hl
ld a, 20
ld (cursor_pos), a
call renderScreen
call showCursor
ret
selectItem:
ld a, (cursor_pos)
dec a
ld b, a
ld a, (show_offset)
add b
ld b, a
call findLine
ld a, h
cp l
ret z
ld a, (hl)
cp '1'
jr z, downPg
cp '0'
jr z, downPg
cp '9'
jp z, downFl
ret
downPg:
push af
call extractInfo
ld hl, hist
ld de, path
ld bc, 147
ldir
ld hl, server_buffer
ld de, file_buffer
ld bc, port_buffer
call openPage
pop af
cp '1'
jp z,showPage
cp '0'
jp z, showText
ret
downFl:
call extractInfo
call cleanIBuff
ld hl, file_buffer
call findFnme
ld de, iBuff
ld bc, 65
ldir
call input
ld hl, server_buffer
ld de, file_buffer
ld bc, port_buffer
call makeRequest
ld hl, iBuff
call downloadData
call showCursor
ret
findFnme:
push hl
pop de
ffnmlp:
ld a, (hl)
cp 0
jr z, ffnmend
cp '/'
jr z, fslsh
inc hl
jp ffnmlp
fslsh:
inc hl
push hl
pop de
jp ffnmlp
ffnmend:
push de
pop hl
ret
showType:
ld a, (cursor_pos)
dec a
ld b, a
ld a, (show_offset)
add b
ld b, a
call findLine
ld a, h
cp l
jr z, showTypeUnknown
ld a, (hl)
cp 'i'
jr z, showTypeInfo
cp '9'
jr z, showTypeDown
cp '1'
jr z, showTypePage
cp '0'
jr z, showTypeText
jr showTypeUnknown
showTypeText:
ld hl, type_text
call showTypePrint
call showURI
ret
showTypeInfo:
ld hl, type_info
jp showTypePrint
showTypePage:
ld hl, type_page
call showTypePrint
call showURI
ret
showTypeDown:
ld hl, type_down
call showTypePrint
call showURI
ret
showURI:
call extractInfo
ld hl, server_buffer
call printZ64
ld hl, file_buffer
call printZ64
ret
showTypeUnknown:
ld hl, type_unkn
jp showTypePrint
showTypePrint:
push hl
ld b, 21
ld c, 0
call gotoXY
ld hl, cleanLine
call printZ64
ld b, 21
ld c, 0
call gotoXY
ld a, 3
ld (attr_screen), a
pop hl
call printZ64
ld a, #7
ld (attr_screen), a
ret
showCursor:
ld a, (cursor_pos)
ld c, 0
ld b, a
call bc_to_attr
ld (hl), #C
ld de, hl
inc de
ld bc, 31
ldir
call showType
ret
hideCursor:
ld a, (cursor_pos)
ld b, a
ld c, 0
call bc_to_attr
ld (hl), #07
ld de, hl
inc de
ld bc, 31
ldir
ret
renderHeader:
call clearScreen
ld a, #0F
ld (attr_screen), a
ld bc, 0
call gotoXY
ld hl, head
call printZ64
ld a, #07
ld (attr_screen), a
ret
renderScreen:
call renderHeader
ld b, 20
renderLp:
push bc
ld a, 20
sub b
ld b, a
ld a, (show_offset)
add b
ld b, a
call renderLine
pop bc
djnz renderLp
ret
; b - line number
renderLine:
call findLine
ld a, h
or l
ret z
ld a, (hl)
and a
ret z
inc hl
call printT64
call mvCR
ret
; B - line number
; HL - pointer to line(or zero if doesn't find it)
findLine:
ld hl, page_buffer
fndLnLp:
ld a, b
and a
ret z
ld a, (hl)
and a ; Buffer ends?
jr z, fndEnd
cp 10 ; New line?
jr z, fndLnNL
inc hl
jp fndLnLp
fndLnNL:
dec b
inc hl
jp fndLnLp
fndEnd:
ld hl, 0
ret
extractInfo:
ld a, (cursor_pos)
dec a
ld b, a
ld a, (show_offset)
add b
ld b, a
call findLine
ld a, h
cp l
ret z
call findNextBlock
inc hl
ld de, file_buffer
call extractCol
inc hl
ld de, server_buffer
call extractCol
inc hl
ld de, port_buffer
call extractCol
ret
extractCol:
ld a, (hl)
cp 0
jr z, endExtract
cp 09
jr z, endExtract
cp 13
jr z, endExtract
ld (de), a
inc de
inc hl
jr extractCol
endExtract:
xor a
ld (de), a
ret
findNextBlock:
ld a, (hl)
cp 09 ; TAB
ret z
cp 13 ; New line
ret z
cp 0 ; End buffer
ret z
inc hl
jp findNextBlock
show_offset db 0
display $
cursor_pos db 1
head db " UGophy - ZX-UNO Gopher client v. 0.1 (c) Alexander Sharikhin ",0
cleanLine db " ",0
type_text db "Text file: ", 0
type_info db "Information ", 0
type_page db "Page: ", 0
type_down db "File to download: ", 0
type_unkn db "Unknown type ", 0
display $
file_buffer defs 70 ; URI path
server_buffer defs 70 ; Host name
port_buffer defs 7 ; Port
end_inf_buff equ $

60
ring.asm Normal file
View File

@ -0,0 +1,60 @@
; Pushes A to ring buffer
pushRing
push af
ld b, 32
ld hl, ring_buffer + 1
ld de, ring_buffer
ringL
ld a, (hl)
ld (de), a
inc hl
inc de
djnz ringL
pop af
ld hl, ring_buffer + 31
ld (hl), a
ret
; HL - Compare string(null terminated)
; A - 0 NOT Found
; 1 Found
searchRing:
ld b, 0
push hl
serlp:
ld a, (hl)
inc hl
inc b
and a
jp nz, serlp
dec b
pop hl
push bc
push hl
SRWork:
pop hl
ld de, ring_buffer + 32
srcLp
dec de
djnz srcLp
pop bc
ringCmpLp
push bc
push af
ld a, (de)
ld b, a
pop af
ld a, (hl)
cp b
pop bc
ld a, 0
ret nz
inc de
inc hl
djnz ringCmpLp
ld a, 1
ret
ring_buffer dup 33
defb 0
edup

414
screen64.asm Normal file
View File

@ -0,0 +1,414 @@
clearScreen:
ld c, #fe
ld a, 0
out (c), a
ld hl, #4000
ld (hl), 0
ld de, #4001
ld bc, #17FF
ldir
ld hl, #5800
ld a, (attr_screen)
ld (hl), a
ld de, #5801
ld bc, #2FF
ldir
ld bc, 0
call gotoXY
ret
;
; Print just one symbol
; A - symbol
putC
cp 13
jr z, mvCR
or a
cp ' '
ret c
ld hl, single_symbol
ld (hl), a
ld hl, single_symbol_print
jp print64
mvCR
ld bc, (col_screen)
inc b
ld c, 0
ld a, 0
ld (half_tile_screen), a
call gotoXY
ret
; Set console coordinates
; b = row(0..23), c = column (0..63)
;
gotoXY:
ld a, 0
ld (half_tile_screen), a
ld (col_screen), bc
ld a, 22
cp b
jp s, scrl
ret
scrl
ld b, 22
ld (col_screen) ,bc
jp scroll_up8
; Print zero-terminated string
; HL - string pointer
putStringZ:
printZ64:
ld a,(hl)
and a
ret z
push hl
call putC
pop hl
inc hl
jr printZ64
printT64:
ld a, (hl)
and a
ret z
cp 09
ret z
push hl
call putC
pop hl
inc hl
jr printT64
printL64:
ld a, (hl)
and a
ret z
cp #0A
ret z
cp #0D
ret z
push hl
call putC
pop hl
inc hl
jr printL64
; Put string with coordinates
; b= row (0..23), c=col (0..63)
; hl - string pointer that's begins from symbol count
printAt64:
call gotoXY
; Put string
; hl - string pointer that's begins from symbol count
print64
ld a,(hl)
and a
ret z
push hl
call calc_addr_attr
ld a,(attr_screen)
ld (hl),a
pop hl
call calc_addr_scr
ld a,(half_tile_screen)
bit 0,a
ld a,(hl)
jp nz,print64_4
print64_3
push af
push hl
call calc_addr_attr
ld a,(attr_screen)
ld (hl),a
pop hl
inc hl
push hl
ld a,(hl)
sub 32
ld l,a
ld h,0
add hl,hl
ld c,l
ld b,h
add hl,hl
add hl,bc
ld bc,font64
add hl,bc
push de
ld b,6
xor a
ld (de),a
print64_1
inc d
ld a,(hl)
and #f0
ld (de),a
inc hl
djnz print64_1
inc d
xor a
ld (de),a
ld a,1
ld (half_tile_screen),a
pop de
pop hl
pop af
dec a
ret z
print64_4
push af
inc hl
push hl
ld a,(hl)
sub 32
ld l,a
ld h,0
add hl,hl
ld c,l
ld b,h
add hl,hl
add hl,bc
ld bc,font64
add hl,bc
push de
ld b,6
xor a
ld (de),a
print64_2
inc d
ld a,(hl)
and #0f
ld c,a
ld a,(de)
or c
ld (de),a
inc hl
djnz print64_2
inc d
xor a
ld (de),a
ld (half_tile_screen),a
pop de
call move_cr64
pop hl
pop af
dec a
jp nz,print64_3
ret
; move cursor
move_cr64
inc de
ld hl,col_screen
inc (hl)
ld a,(hl)
cp 32
ret c
xor a
ld (half_tile_screen),a
ld (hl),a
ld c,a
inc hl
inc (hl)
ld a,(hl)
ld b,a
cp 24
jp c,move_cr64_01
ld a,23
ld (hl),a
ld b,a
push bc
call scroll_up8
pop bc
move_cr64_01
call calc_addr_scr
ret
calc_addr_scr
ld a,b
ld d,a
rrca
rrca
rrca
and a,224
add a,c
ld e,a
ld a,d
and 24
or 64
ld d,a
ret
calc_addr_attr
ld bc,(col_screen)
bc_to_attr:
ld a,b
rrca
rrca
rrca
ld l,a
and 31
or 88
ld h,a
ld a,l
and 252
or c
ld l,a
ret
scroll_up8
ld hl,table_addr_scr
ld b,184
scroll_up8_01
push bc
ld e,(hl)
inc hl
ld d,(hl)
inc hl
push hl
ld bc,14
add hl,bc
ld c,(hl)
inc hl
ld b,(hl)
ld h,b
ld l,c
ld bc,32
ldir
pop hl
pop bc
djnz scroll_up8_01
ld b,8
scroll_up8_02
push bc
ld e,(hl)
inc hl
ld d,(hl)
inc hl
push hl
ld h,d
ld l,e
inc de
ld (hl),0
ld bc,31
ldir
pop hl
pop bc
djnz scroll_up8_02
ld de,#5800
ld hl,#5820
ld bc,736
ldir
ld a,(de)
ld hl,#5ae0
ld de,#5ae1
ld (hl),a
ld bc,31
ldir
ret
font64 incbin "font.bin"
table_addr_scr
defw #4000,#4100,#4200,#4300,#4400,#4500,#4600,#4700
defw #4020,#4120,#4220,#4320,#4420,#4520,#4620,#4720
defw #4040,#4140,#4240,#4340,#4440,#4540,#4640,#4740
defw #4060,#4160,#4260,#4360,#4460,#4560,#4660,#4760
defw #4080,#4180,#4280,#4380,#4480,#4580,#4680,#4780
defw #40a0,#41a0,#42a0,#43a0,#44a0,#45a0,#46a0,#47a0
defw #40c0,#41c0,#42c0,#43c0,#44c0,#45c0,#46c0,#47c0
defw #40e0,#41e0,#42e0,#43e0,#44e0,#45e0,#46e0,#47e0
defw #4800,#4900,#4a00,#4b00,#4c00,#4d00,#4e00,#4f00
defw #4820,#4920,#4a20,#4b20,#4c20,#4d20,#4e20,#4f20
defw #4840,#4940,#4a40,#4b40,#4c40,#4d40,#4e40,#4f40
defw #4860,#4960,#4a60,#4b60,#4c60,#4d60,#4e60,#4f60
defw #4880,#4980,#4a80,#4b80,#4c80,#4d80,#4e80,#4f80
defw #48a0,#49a0,#4aa0,#4ba0,#4ca0,#4da0,#4ea0,#4fa0
defw #48c0,#49c0,#4ac0,#4bc0,#4cc0,#4dc0,#4ec0,#4fc0
defw #48e0,#49e0,#4ae0,#4be0,#4ce0,#4de0,#4ee0,#4fe0
defw #5000,#5100,#5200,#5300,#5400,#5500,#5600,#5700
defw #5020,#5120,#5220,#5320,#5420,#5520,#5620,#5720
defw #5040,#5140,#5240,#5340,#5440,#5540,#5640,#5740
defw #5060,#5160,#5260,#5360,#5460,#5560,#5660,#5760
defw #5080,#5180,#5280,#5380,#5480,#5580,#5680,#5780
defw #50a0,#51a0,#52a0,#53a0,#54a0,#55a0,#56a0,#57a0
defw #50c0,#51c0,#52c0,#53c0,#54c0,#55c0,#56c0,#57c0
defw #50e0,#51e0,#52e0,#53e0,#54e0,#55e0,#56e0,#57e0
string_temp defb 0
dup 255
defb 32
edup
col_screen defb 0
row_screen defb 0
half_tile_screen defb 0
attr_screen defb 07
col_screen_temp defw 0
half_tile_screen_temp defb 0
single_symbol_print defb 1
single_symbol defb 0

78
textrender.asm Normal file
View File

@ -0,0 +1,78 @@
showText:
xor a
ld (show_offset), a
call renderTextScreen
showTxLp:
call txControls
dup 5
halt
edup
jp showTxLp
txControls:
call inkey
and a
ret z
cp 'q'
jp z, txUp
cp 'a'
jp z, txDn
cp 'b'
jp z, historyBack
cp 'o'
jp z, openURI
ret
txUp:
ld a, (show_offset)
and a
ret z
sub 20
ld (show_offset), a
call renderTextScreen
ret
txDn:
ld a, (show_offset)
add 20
ld (show_offset), a
call renderTextScreen
ret
renderTextScreen:
call renderHeader
ld b, 20
txRenderLp:
push bc
ld a, 20
sub b
ld b, a
ld a, (show_offset)
add b
ld b, a
call renderTextLine
pop bc
djnz txRenderLp
ret
renderTextLine:
call findLine
ld a, h
or l
ret z
ld a, (hl)
and a
ret z
call printL64
call mvCR
ret

194
uart.asm Normal file
View File

@ -0,0 +1,194 @@
UART_DATA_REG = #c6
UART_STAT_REG = #c7
UART_BYTE_RECIVED = #80
UART_BYTE_SENT = #40
ZXUNO_ADDR = #FC3B
ZXUNO_REG = #FD3B
; Enable UART
; Cleaning all flags by reading UART regs
; Wastes AF and BC
uartBegin:
ld bc, ZXUNO_ADDR
ld a, UART_STAT_REG
out (c), a
ld bc, ZXUNO_REG
in A, (c)
ld bc, ZXUNO_ADDR
ld a, UART_DATA_REG
out (c), a
ld bc, ZXUNO_REG
in A, (c)
ret
; Pushes to UART zero-terminated string
; HL - string poiner
uartWriteStringZ:
ld a, (hl)
and a
ret z
push hl
call uartWriteByte
pop hl
inc hl
jp uartWriteStringZ
; Blocking read one byte
uartReadBlocking:
call uartRead
push af
ld a, 1
cp b
jr z, urb
pop af
ret nz
jp uartReadBlocking
urb:
pop af
ret
; Write single byte to UART
; A - byte to write
; BC will be wasted
uartWriteByte:
push af
ld bc, ZXUNO_ADDR
ld a, UART_STAT_REG
out (c), a
waitWriteReady:
ld bc, ZXUNO_REG
in A, (c)
and UART_BYTE_RECIVED
jr nz, is_recvF
checkSent:
ld bc, ZXUNO_REG
in A, (c)
and UART_BYTE_SENT
jr nz, checkSent
ld bc, ZXUNO_ADDR
ld a, UART_DATA_REG
out (c), a
ld bc, ZXUNO_REG
pop af
out (c), a
ret
is_recvF:
push af
push hl
ld hl, is_recv
ld a, 1
ld (hl), a
pop hl
pop af
jr checkSent
; Is data avail in UART
; NZ - Data Presents
; Z - Data absent
uartAvail:
ld a, (is_recv)
and 1
ret nz
ld a, (poked_byte)
and 1
ret nz
call uartRead
push af
ld a, b
and 1
jr z, noneData
pop af
push af
ld hl, byte_buff
ld (hl), a
ld hl, poked_byte
ld a, 1
ld (hl), a
pop af
ld b, a
ld a, 1
or a
ld a, b
ret
noneData:
pop bc
xor a
ret
; Read byte from UART
; A: byte
; B:
; 1 - Was read
; 0 - Nothing to read
uartRead:
ld a, (poked_byte)
and 1
jr nz, retBuff
ld a, (is_recv)
and 1
jr nz, recvRet
ld bc, ZXUNO_ADDR
ld a, UART_STAT_REG
out (c), a
ld bc, ZXUNO_REG
in a, (c)
and UART_BYTE_RECIVED
jr nz, retReadByte
ld b, 0
ret
retReadByte:
ld a, 0
ld (poked_byte), a
ld (is_recv), a
ld bc, ZXUNO_ADDR
ld a, UART_DATA_REG
out (c), a
ld bc, ZXUNO_REG
in a, (c)
ld b, 1
ret
recvRet:
ld bc, ZXUNO_ADDR
ld a, UART_DATA_REG
out (c),a
ld bc, ZXUNO_REG
in a, (c)
ld hl, is_recv
ld (hl), 0
ld hl, poked_byte
ld (hl), 0
ld b, 1
ret
retBuff
ld a, 0
ld (poked_byte), a
ld a, (byte_buff)
ld b, 1
ret
poked_byte defb 0
byte_buff defb 0
is_recv defb 0

140
utils.asm Normal file
View File

@ -0,0 +1,140 @@
; HL - string
; Return: bc - len
getStringLength:
ld bc, 0
strLnLp
ld a, (hl)
and a
ret z
inc bc
inc hl
jr strLnLp
SkipWhitespace:
ld a, (hl)
cp ' '
ret nz
inc hl
jr SkipWhitespace
;;;;;;;;;;;;;;;;;;;;;;;;
; Binary to decimal stuff
; From https://www.msx.org/forum/development/msx-development/32-bit-long-ascii
; Combined routine for conversion of different sized binary numbers into
; directly printable ASCII(Z)-string
; Input value in registers, number size and -related to that- registers to fill
; is selected by calling the correct entry:
;
; entry inputregister(s) decimal value 0 to:
; B2D8 A 255 (3 digits)
; B2D16 HL 65535 5 "
; B2D24 E:HL 16777215 8 "
; B2D32 DE:HL 4294967295 10 "
; B2D48 BC:DE:HL 281474976710655 15 "
; B2D64 IX:BC:DE:HL 18446744073709551615 20 "
;
; The resulting string is placed into a small buffer attached to this routine,
; this buffer needs no initialization and can be modified as desired.
; The number is aligned to the right, and leading 0's are replaced with spaces.
; On exit HL points to the first digit, (B)C = number of decimals
; This way any re-alignment / postprocessing is made easy.
; Changes: AF,BC,DE,HL,IX
; P.S. some examples below
; by Alwin Henseler
B2D8: LD H,0
LD L,A
B2D16: LD E,0
B2D24: LD D,0
B2D32: LD BC,0
B2D48: LD IX,0 ; zero all non-used bits
B2D64: LD (B2DINV),HL
LD (B2DINV+2),DE
LD (B2DINV+4),BC
LD (B2DINV+6),IX ; place full 64-bit input value in buffer
LD HL,B2DBUF
LD DE,B2DBUF+1
LD (HL)," "
B2DFILC: EQU $-1 ; address of fill-character
LD BC,18
LDIR ; fill 1st 19 bytes of buffer with spaces
LD (B2DEND-1),BC ;set BCD value to "0" & place terminating 0
LD E,1 ; no. of bytes in BCD value
LD HL,B2DINV+8 ; (address MSB input)+1
LD BC,0x0909
XOR A
B2DSKP0: DEC B
JR Z,B2DSIZ ; all 0: continue with postprocessing
DEC HL
OR (HL) ; find first byte <>0
JR Z,B2DSKP0
B2DFND1: DEC C
RLA
JR NC,B2DFND1 ; determine no. of most significant 1-bit
RRA
LD D,A ; byte from binary input value
B2DLUS2: PUSH HL
PUSH BC
B2DLUS1: LD HL,B2DEND-1 ; address LSB of BCD value
LD B,E ; current length of BCD value in bytes
RL D ; highest bit from input value -> carry
B2DLUS0: LD A,(HL)
ADC A,A
DAA
LD (HL),A ; double 1 BCD byte from intermediate result
DEC HL
DJNZ B2DLUS0 ; and go on to double entire BCD value (+carry!)
JR NC,B2DNXT
INC E ; carry at MSB -> BCD value grew 1 byte larger
LD (HL),1 ; initialize new MSB of BCD value
B2DNXT: DEC C
JR NZ,B2DLUS1 ; repeat for remaining bits from 1 input byte
POP BC ; no. of remaining bytes in input value
LD C,8 ; reset bit-counter
POP HL ; pointer to byte from input value
DEC HL
LD D,(HL) ; get next group of 8 bits
DJNZ B2DLUS2 ; and repeat until last byte from input value
B2DSIZ: LD HL,B2DEND ; address of terminating 0
LD C,E ; size of BCD value in bytes
OR A
SBC HL,BC ; calculate address of MSB BCD
LD D,H
LD E,L
SBC HL,BC
EX DE,HL ; HL=address BCD value, DE=start of decimal value
LD B,C ; no. of bytes BCD
SLA C ; no. of bytes decimal (possibly 1 too high)
LD A,"0"
RLD ; shift bits 4-7 of (HL) into bit 0-3 of A
CP "0" ; (HL) was > 9h?
JR NZ,B2DEXPH ; if yes, start with recording high digit
DEC C ; correct number of decimals
INC DE ; correct start address
JR B2DEXPL ; continue with converting low digit
B2DEXP: RLD ; shift high digit (HL) into low digit of A
B2DEXPH: LD (DE),A ; record resulting ASCII-code
INC DE
B2DEXPL: RLD
LD (DE),A
INC DE
INC HL ; next BCD-byte
DJNZ B2DEXP ; and go on to convert each BCD-byte into 2 ASCII
SBC HL,BC ; return with HL pointing to 1st decimal
RET
AppendB2D:
; Append results of B2D to string at HL
ex de, hl ; Get destination into DE
ld hl, B2DBUF
call SkipWhitespace
ldir
ex de, hl ; Get destination into DE
ret
B2DINV: DS 8 ; space for 64-bit input value (LSB first)
B2DBUF: DS 20 ; space for 20 decimal digits
B2DEND: DB 0 ; space for terminating 0

258
wifi.asm Normal file
View File

@ -0,0 +1,258 @@
; Initialize WiFi chip and connect to WiFi
initWifi:
call loadWiFiConfig
ld hl, cmd_plus
call uartWriteStringZ
ld b,#ff
wlp:
push bc
ld b, #ff
djnz $
pop bc
djnz wlp
ld hl, cmd_rst
call uartWriteStringZ
rstLp:
call uartReadBlocking
call pushRing
ld hl, response_rdy
call searchRing
cp 1
jr nz, rstLp
ld hl, cmd_at ; Disable ECHO. BTW Basic UART test
call okErrCmd
and 1
jr z, errInit
ld hl, cmd_cwqap ; Lets disconnect from last AP
call okErrCmd
and 1
jr z, errInit
ld hl, cmd_cmux ; Single connection mode
call okErrCmd
and 1
jr z, errInit
ld hl, cmd_inf_off ; FTP enables this info? We doesn't need it :-)
call okErrCmd
and 1
jr z, errInit
ld hl, cmd_cwjap1 ; Access Point connection
call uartWriteStringZ
ld hl, ssid
call uartWriteStringZ
ld hl, cmd_cwjap2
call uartWriteStringZ
ld hl, pass
call uartWriteStringZ
ld hl, cmd_cwjap3
call okErrCmd
and 1
jr z, errInit
ld hl, log_ok
call putStringZ
ret
errInit
ld hl, log_err
call putStringZ
jr $
; Send AT-command and wait for result.
; HL - Z-terminated AT-command(with CR/LF)
; A:
; 1 - Success
; 0 - Failed
okErrCmd:
call uartWriteStringZ
okErrCmdLp:
call uartReadBlocking
call pushRing
ld hl, response_ok
call searchRing
cp 1
jr z, okErrOk
ld hl, response_err
call searchRing
cp 1
jr z, okErrErr
ld hl, response_fail
call searchRing
cp 1
jr z, okErrErr
jp okErrCmdLp
okErrOk
ld a, 1
ret
okErrErr
ld a, 0
ret
; Gets packet from network
; packet will be in var 'output_buffer'
; received packet size in var 'bytes_avail'
;
; If connection was closed it calls 'closed_callback'
getPacket
call uartReadBlocking
call pushRing
ld hl, closed
call searchRing
cp 1
jp z, closed_callback
ld hl, ipd
call searchRing
cp 1
jr nz, getPacket
call count_ipd_lenght
ld (bytes_avail), hl
push hl
pop bc
ld hl, output_buffer
readp:
push bc
push hl
call uartReadBlocking
pop hl
ld (hl), a
pop bc
dec bc
inc hl
ld a, b
or c
jr nz, readp
ld hl, (bytes_avail)
ret
count_ipd_lenght
ld hl,0 ; count lenght
cil1 push hl
call uartReadBlocking
push af
call pushRing
pop af
pop hl
cp ':'
ret z
sub 0x30
ld c,l
ld b,h
add hl,hl
add hl,hl
add hl,bc
add hl,hl
ld c,a
ld b,0
add hl,bc
jr cil1
; HL - z-string to hostname or ip
; DE - z-string to port
startTcp:
push de
push hl
ld hl, cmd_open1
call uartWriteStringZ
pop hl
call uartWriteStringZ
ld hl, cmd_open2
call uartWriteStringZ
pop de
call uartWriteStringZ
ld hl, cmd_open3
call okErrCmd
ret
; Returns:
; A: 1 - Success
; 0 - Failed
sendByte:
push af
ld hl, cmd_send_b
call okErrCmd
cp 1
jr nz, sbErr
sbLp
call uartReadBlocking
ld hl, send_prompt
call searchRing
cp 1
jr nz, sbLp
pop af
ld (sbyte_buff), a
call okErrCmd
ret
sbErr:
pop af
ld a, 0
ret
loadWiFiConfig:
ld b, FMODE_READ
ld hl, conf_file
call fopen
push af
ld hl, ssid
ld bc, 160
call fread
pop af
call fclose
ret
cmd_plus defb "+++", 0
cmd_rst defb "AT+RST",13, 10, 0
cmd_at defb "ATE0", 13, 10, 0 ; Disable echo - less to parse
cmd_mode defb "AT+CWMODE_DEF=1",13,10,0 ; Client mode
cmd_cmux defb "AT+CIPMUX=0",13,10,0 ; Single connection mode
cmd_cwqap defb "AT+CWQAP",13,10,0 ; Disconnect from AP
cmd_inf_off defb "AT+CIPDINFO=0",13,10,0 ; doesn't send me info about remote port and ip
cmd_cwjap1 defb "AT+CWJAP_CUR=", #22,0 ;Connect to AP. Send this -> SSID
cmd_cwjap2 defb #22,',',#22,0 ; -> This -> Password
cmd_cwjap3 defb #22, 13, 10, 0 ; -> And this
cmd_open1 defb "AT+CIPSTART=", #22, "TCP", #22, ",", #22, 0
cmd_open2 defb #22, ",", 0
cmd_open3 defb 13, 10, 0
cmd_send defb "AT+CIPSEND=", 0
cmd_close defb "AT+CIPCLOSE",13,10,0
cmd_send_b defb "AT+CIPSEND=1", 13, 10,0
closed defb "CLOSED", 13, 10, 0
ipd defb 13, 10, "+IPD,", 0
crlf defb 13,10, 0
response_rdy defb 'ready', 0
response_ok defb 'OK', 13, 10, 0 ; Sucessful operation
response_err defb 13,10,'ERROR',13,10,0 ; Failed operation
response_fail defb 13,10,'FAIL',13,10,0 ; Failed connection to WiFi. For us same as ERROR
log_err defb 'Failed connect to WiFi!',13, 0
log_ok defb 'WiFi connected!', 13, 0
ssid defs 80
pass defs 80
bytes_avail defw 0
sbyte_buff defb 0, 0
send_prompt defb ">",0
output_buffer defs 2048 ; buffer for downloading data
; WiFi configuration
conf_file defb "/sys/config/iw.cfg",0