Compare commits

...
5 Commits
Author SHA1 Message Date
maddiebaka 2a077bd1e7 Add activity spinner 2026-08-23 21:08:52 -04:00
maddiebaka cb936d97b8 Fix serial and keyboard input to be non-blocking 2026-08-23 20:36:30 -04:00
maddiebaka 0b4cb9f0b8 Add 'press Q to exit' function 2026-08-23 20:31:56 -04:00
maddiebaka 33fe56dade Add conversion to hPa 2026-08-23 20:26:52 -04:00
maddiebaka 014689916d Add character counting guard 2026-08-23 20:14:43 -04:00
+142 -37
View File
@@ -9,18 +9,29 @@ lcd_ctrl equ 0dah
celcius_offset equ 08ah celcius_offset equ 08ah
pressure_offset equ 0cah pressure_offset equ 0cah
humid_offset equ 09eh humid_offset equ 09eh
spinner_offset equ 0e7h ; line 4, column 20 on a 20x4 panel
bs_char equ 01h ; cgram slot holding our backslash
bs_cgram equ 048h ; set cgram address, slot 1 row 0
bdos equ 0005h bdos equ 0005h
conout equ 02h conout equ 02h
conin equ 01h conin equ 01h
dconio equ 06h
printstr equ 09h
char_idx equ 10h
start: start:
ld c,printstr ; tell the operator how to quit
ld de,quitmsg
call bdos
call init_lcd call init_lcd
call init_siob call init_siob
call lcd_delay call lcd_delay
call load_glyphs
ld a,celcius_offset ; write celcius label ld a,celcius_offset ; write celcius label
out (lcd_ctrl),a out (lcd_ctrl),a
call lcd_delay call lcd_delay
@@ -40,15 +51,23 @@ start:
call print_str_to_lcd call print_str_to_lcd
main: main:
call read_char_b call read_char_b ; never blocks now
jr nc,check_quit ; wire is idle, go look at the keyboard
ld hl,rx_seen
ld (hl),0ffh ; note traffic, a holds the char untouched
call parse_char call parse_char
;call lcd_delay jr main ; drain the sio while it still has data
;call print_char_to_lcd
ld c,11 check_quit:
call spin_tick ; keep the spinner turning while idle
ld c,dconio ; direct console i/o, no echo
ld e,0ffh ; ff polls, returning zero if no key
call bdos call bdos
or a cp a,051h ; Q
jr z,main ret z
ret cp a,071h ; q
ret z
jr main ; no key, or a key we ignore
init_siob: init_siob:
ld a,018h ; channel reset ld a,018h ; channel reset
@@ -83,6 +102,21 @@ init_lcd:
ret ret
load_glyphs: ; the a00 rom has yen at 5ch, so draw our own backslash
ld a,bs_cgram
out (lcd_ctrl),a
call lcd_delay
ld hl,glyph_bs
ld e,08h ; eight rows, and e survives lcd_delay
glyph_row:
ld a,(hl)
out (lcd_data),a ; cgram address auto increments
call lcd_delay
inc hl
dec e
jr nz,glyph_row
ret
lcd_delay: lcd_delay:
ld bc,500 ld bc,500
delay1: delay1:
@@ -92,17 +126,41 @@ delay1:
jr nz,delay1 jr nz,delay1
ret ret
convert_to_hpa: convert_to_hpa: ; shift the decimal point in (pressure) two places left
ld a,(pressure) ld hl,pressure
ld b,0 ; count of digits ahead of the point
find_point:
ld a,(hl)
or a
ret z ; no point in the string, leave it alone
cp a,2eh ; period
jr z,found_point
inc hl
inc b
jr find_point
found_point:
ld a,b
cp 3 ; need three whole digits to shift by two
ret c
dec hl ; step back over the ones digit
dec hl ; hl now holds the new tenths digit
ld a,(hl)
ld (hl),2eh ; drop the point in two places left
inc hl
ld (hl),a ; and the saved digit after it
inc hl
ld (hl),00h ; null terminate, discarding the rest
ret ret
read_char_b: read_char_b: ; carry set with the char in a, carry clear if nothing waiting
wait:
in a,(siob_ctrl) in a,(siob_ctrl)
bit 0,a bit 0,a
jr z,wait jr z,no_char
in a,(siob_data) in a,(siob_data)
scf ; flag a as a real character
ret
no_char:
or a ; clears carry, a holds status not data
ret ret
parse_char: ; char should be in register a parse_char: ; char should be in register a
@@ -119,20 +177,31 @@ parse_char: ; char should be in register a
cp a,048h ; H character cp a,048h ; H character
jr z,set_char_idx_h ; point the char_idx to the humidity buffer jr z,set_char_idx_h ; point the char_idx to the humidity buffer
push af
ld a,(char_cnt) ; get number stored in char_cnt
cp char_max ; compare it to maximum character count
jr nc,store_full ; if no carry, the buffer is full
inc a ; otherwise increment
ld (char_cnt),a ; and store back in char_cnt
pop af
ld bc,(char_idx) ; get address stored in char_idx ld bc,(char_idx) ; get address stored in char_idx
ld (bc),a ; deref that address and store char ld (bc),a ; deref that address and store char
inc bc inc bc
ld (char_idx),bc ; store incremented address in char_idx ld (char_idx),bc ; store incremented address in char_idx
;out (lcd_data),a
parse_char_done: parse_char_done:
ret ret
store_full:
pop af
ret
print_telem_to_lcd: print_telem_to_lcd:
call move_to_tempaddr call move_to_tempaddr
ld hl,temperature ld hl,temperature
call print_str_to_lcd call print_str_to_lcd
call convert_to_hpa
call move_to_presaddr call move_to_presaddr
ld hl,pressure ld hl,pressure
call print_str_to_lcd call print_str_to_lcd
@@ -142,7 +211,6 @@ print_telem_to_lcd:
call print_str_to_lcd call print_str_to_lcd
ld a,1h ld a,1h
out (0),a
ret ret
null_term: ; null terminate end of parsed string in memory null_term: ; null terminate end of parsed string in memory
@@ -155,36 +223,25 @@ null_term: ; null terminate end of parsed s
set_char_idx_t: set_char_idx_t:
ld bc,temperature ld bc,temperature
ld (char_idx),bc ld (char_idx),bc
xor a ; reset char_cnt to zero
ld (char_cnt),a
ret ret
set_char_idx_p: set_char_idx_p:
ld bc,pressure ld bc,pressure
ld (char_idx),bc ld (char_idx),bc
xor a ; reset char_cnt to zero
ld (char_cnt),a
ret ret
set_char_idx_h: set_char_idx_h:
ld bc,humidity ld bc,humidity
ld (char_idx),bc ld (char_idx),bc
xor a ; reset char_cnt to zero
ld (char_cnt),a
ret ret
print_char_to_lcd:
cp a,00h ; null byte
jr z,lcd_done
cp a,0dh ; carriage return
jr z,lcd_done
cp a,0ah ; new line
jr z,lcd_done
cp a,054h ; T character
call z,move_to_tempaddr
cp a,050h ; P character
call z,move_to_presaddr
cp a,048h ; H character
call z,move_to_humidaddr
out (lcd_data),a
lcd_done:
ret
print_str_to_lcd: ; place memory address in hl first print_str_to_lcd: ; place memory address in hl first
ld a,(hl) ld a,(hl)
or a or a
@@ -197,16 +254,49 @@ print_str_to_lcd: ; place memory address in hl f
print_done: print_done:
ret ret
spin_tick: ; count down, then step the spinner one frame
ld hl,(spin_cnt)
dec hl
ld (spin_cnt),hl
ld a,h ; dec hl leaves the flags alone
or l
ret nz ; not time yet
ld hl,spin_ticks ; reload, so the interval stays regular
ld (spin_cnt),hl
ld a,(rx_seen) ; did anything arrive this interval?
or a
ret z ; no, hold the frame and stop spinning
xor a
ld (rx_seen),a ; clear it for the next interval
ld a,(spin_idx)
inc a
and 03h ; four frames, then wrap
ld (spin_idx),a
ld hl,spinner
ld d,00h
ld e,a
add hl,de ; hl now points at the frame character
ld a,spinner_offset
out (lcd_ctrl),a ; park the cursor bottom right
call lcd_delay
ld a,(hl) ; fetch late, lcd_delay wrecks a and bc but not hl
out (lcd_data),a
call lcd_delay
ret
move_to_tempaddr: move_to_tempaddr:
ld c,a
ld a,85h ld a,85h
out (lcd_ctrl),a out (lcd_ctrl),a
ld a,c
call lcd_delay call lcd_delay
ret ret
move_to_presaddr: move_to_presaddr:
ld a,0c1h ld a,0c3h
out (lcd_ctrl),a out (lcd_ctrl),a
call lcd_delay call lcd_delay
ret ret
@@ -218,9 +308,24 @@ move_to_humidaddr:
ret ret
clabel: DB 'degree C',0 clabel: DB 'degree C',0
plabel: DB 'pascal',0 plabel: DB 'hPa',0
hlabel: DB '% RH',0 hlabel: DB '% RH',0
quitmsg: DB 'Press Q to quit',0dh,0ah,'$'
spinner: DB '-','/','|',bs_char
glyph_bs: DB 00h,10h,08h,04h,02h,01h,00h,00h
spin_ticks equ 3000 ; idle polls per frame, tune on real hardware
spin_idx DB 03h ; wraps to the first frame on the next tick
spin_cnt DW spin_ticks
rx_seen DB 00h ; set on every byte off the sio
char_max equ 15
char_cnt DB 0
char_idx DW scratch
scratch: DS 16
temperature: DS 16 temperature: DS 16
humidity: DS 16 humidity: DS 16
pressure: DS 16 pressure: DS 16