org 100h siob_data equ 083h siob_ctrl equ 082h lcd_data equ 0dbh lcd_ctrl equ 0dah celcius_offset equ 08ah pressure_offset equ 0cah humid_offset equ 09eh bdos equ 0005h conout equ 02h conin equ 01h printstr equ 09h start: call init_lcd call init_siob call lcd_delay ld a,celcius_offset ; write celcius label out (lcd_ctrl),a call lcd_delay ld hl,clabel call print_str_to_lcd ld a,pressure_offset ; write pressure label out (lcd_ctrl),a call lcd_delay ld hl,plabel call print_str_to_lcd ld a,humid_offset ; write humidity label out (lcd_ctrl),a call lcd_delay ld hl,hlabel call print_str_to_lcd main: call read_char_b call parse_char ld c,11 call bdos or a jr z,main ret init_siob: ld a,018h ; channel reset out (siob_ctrl),a ld a,04h out (siob_ctrl),a ; wr4 baud settings ld a,0c4h out (siob_ctrl),a ld a,03h out (siob_ctrl),a ; rx enable ld a,0c1h out (siob_ctrl),a ld a,05h out (siob_ctrl),a ; tx settings ld a,0eah out (siob_ctrl),a ret init_lcd: ld a,38h out (lcd_ctrl),a ; function 8 bit, 2 lines, 5x8 dot font call lcd_delay ld a,0ch out (lcd_ctrl),a ; display on, cursor off, no blink call lcd_delay ld a,01h out (lcd_ctrl),a ; clear display ret lcd_delay: ld bc,500 delay1: dec bc ld a,b or c jr nz,delay1 ret convert_to_hpa: ; shift the decimal point in (pressure) two places left 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 read_char_b: wait: in a,(siob_ctrl) bit 0,a jr z,wait in a,(siob_data) ret parse_char: ; char should be in register a cp a,25h ; percent sign (end of transmission) jr z,print_telem_to_lcd cp a,0dh ; carriage return jr z,null_term cp a,0ah ; new line jr z,parse_char_done cp a,054h ; T character jr z,set_char_idx_t ; point the char_idx to the temperature buffer cp a,050h ; P character jr z,set_char_idx_p ; point the char_idx to the pressure buffer cp a,048h ; H character 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),a ; deref that address and store char inc bc ld (char_idx),bc ; store incremented address in char_idx parse_char_done: ret store_full: pop af ret print_telem_to_lcd: call move_to_tempaddr ld hl,temperature call print_str_to_lcd call convert_to_hpa call move_to_presaddr ld hl,pressure call print_str_to_lcd call move_to_humidaddr ld hl,humidity call print_str_to_lcd ld a,1h ret null_term: ; null terminate end of parsed string in memory ld a,00h ld bc,(char_idx) ld (bc),a jr parse_char_done set_char_idx_t: ld bc,temperature ld (char_idx),bc xor a ; reset char_cnt to zero ld (char_cnt),a ret set_char_idx_p: ld bc,pressure ld (char_idx),bc xor a ; reset char_cnt to zero ld (char_cnt),a ret set_char_idx_h: ld bc,humidity ld (char_idx),bc xor a ; reset char_cnt to zero ld (char_cnt),a ret print_str_to_lcd: ; place memory address in hl first ld a,(hl) or a jr z,print_done out (lcd_data),a call lcd_delay inc hl jr print_str_to_lcd print_done: ret move_to_tempaddr: ld c,a ld a,85h out (lcd_ctrl),a ld a,c call lcd_delay ret move_to_presaddr: ld a,0c3h out (lcd_ctrl),a call lcd_delay ret move_to_humidaddr: ld a,99h out (lcd_ctrl),a call lcd_delay ret clabel: DB 'degree C',0 plabel: DB 'hPa',0 hlabel: DB '% RH',0 char_max equ 15 char_cnt DB 0 char_idx DW scratch scratch: DS 16 temperature: DS 16 humidity: DS 16 pressure: DS 16