// ================================
// weather clock
//		(c) 2022	1YEN Toru
//
//
//		2022/09/24	ver.1.00
//
// ================================
romsiz	8*1024
asm		"mcoc_irom_8k.mif"
#asm		"mcoc_irom.mem"
#asm		"mcoc_irom.dat2",bit16,list
incl	"mcoc115.incl"
incl	"mcvm_lib_wire_h.incl"
# ================================
# string macros
def		prog_name,"weather_clock"
def		prog_vers,"1.00"
def		s,"#"							// simulation="" / real fpga="#"
def		r,"#"							// ole: rotate="" / normal="#"
def		d,"#"							// show debug="" / not="#"
# http macros
# url: https://weather.yahoo.co.jp/weather/28/6310/28207.html
def		esp_ctyp,"SSL"					// TCP or SSL
def		esp_port,"443"					// 80 or 443
def		esp_http,"https://"				// http or https
def		esp_serv,"weather.yahoo.co.jp"
def		esp_path,"/weather/28/6310/28207.html"
# constants
equ		max_lbuf,128					// size of lbuf
equ		baud,9600						// baud rate
equ		uart_baud,fcpu/baud-1			// uartbaud setting
equ		baud_esp,115200					// esp32: baud rate
equ		uart_baud_esp,fcpu/baud_esp-1	// esp32: uartbaud setting
equ		stws_baud,fcpu/400000-1			// i2c: clock speed
$(s)// ********************************
$(s)equ		stws_baud,fcpu/400000/3-1	// i2c: clock speed for sim
$(s)// ********************************
equ		i2c_ssd1306,0x3c				// i2c: ssd1306 slave address
equ		chr_tab,0x09					// tab code
equ		chr_lf,0x0a						// lf code
equ		chr_cr,0x0d						// cr code
equ		chr_spc,0x20					// space ' ' code
equ		chr_cma,0x2c					// comma ',' code
equ		chr_mns,0x2d					// minus '-' code
equ		chr_cln,0x3a					// colon ':' code
equ		chr_lt,0x3c						// less '<' code
equ		chr_gt,0x3e						// greater '>' code
equ		wck_msec_scr,75					// wck: scroll interval [ms]
equ		wck_getw_minute,10				// wck: get weather info at minute
# oled driver ssd1306 i/o registers
equ		ole_siz_h,128					// ole: screen size
equ		ole_siz_v,64
equ		ole_reg_ctrl_c,0x00				// ole: ctr: co=0, d/c#=0 (command)
equ		ole_reg_ctrl_d,0x40				// ole: ctr: co=0, d/c#=1 (data)
equ		ole_reg_ctrl_cc,0x80			// ole: ctr: co=1, d/c#=0 (command)
equ		ole_reg_ctrl_cd,0xc0			// ole: ctr: co=1, d/c#=1 (data)
equ		ole_reg_madr_mod,0x20			// ole: reg: memory addressing mode
equ		ole_reg_col_adr,0x21			// ole: reg: column address
equ		ole_reg_pag_adr,0x22			// ole: reg: page address
equ		ole_reg_disp_lin,0x40			// ole: reg: display start line
equ		ole_reg_cont_ctrl,0x81			// ole: reg: contrast control
equ		ole_reg_chg_pump,0x8d			// ole: reg: charge pump setting
equ		ole_reg_seg_remap,0xa0			// ole: reg: segment re-map
equ		ole_reg_ent_disp,0xa4			// ole: reg: entire display on
equ		ole_reg_nor_disp,0xa6			// ole: reg: normal display
equ		ole_reg_inv_disp,0xa7			// ole: reg: inverse display
equ		ole_reg_mux_rat,0xa8			// ole: reg: multiplex ratio
equ		ole_reg_disp_off,0xae			// ole: reg: display off
equ		ole_reg_disp_on,0xaf			// ole: reg: display on
equ		ole_reg_scan_dir,0xc0			// ole: reg: com output scan dir
equ		ole_reg_disp_ofst,0xd3			// ole: reg: display offset
equ		ole_reg_clk_div,0xd5			// ole: reg: display clock divide
equ		ole_reg_com_cnfg,0xda			// ole: reg: com pins h/w config
# variables
equ		va,ramtop
equ		esp_ewr_idx,va					// esp32: response list code (0~)
equ		va,va+2
equ		path_ptr,va						// path: write pointer to lbuf
equ		va,va+2
equ		wck_msec_prev,va				// wck: previously scroll time [ms]
equ		va,va+4
equ		wck_scroll,va					// wck: scroll position
equ		va,va+2
equ		wck_upd_sntp,va					// wck: ole: update sntp time
equ		va,va+2
equ		wck_upd_getw,va					// wck: ole: update weather info.
equ		va,va+2
equ		wck_upd_rtc_part,va				// wck: ole: update rtc part
equ		va,va+2
equ		wck_upd_wth_part,va				// wck: ole: update weather part
equ		va,va+2
equ		wck_upd_oled01,va				// wck: ole: update oled line 0,1
equ		va,va+2
equ		wck_upd_oled23,va				// wck: ole: update oled line 2,3
equ		va,va+2
equ		rtc_leap,va						// rtc: leap year(true) or not
equ		va,va+2
equ		rtc_year,va						// rtc: year counter
equ		va,va+2
equ		rtc_month,va					// rtc: month counter
equ		va,va+2
equ		rtc_day,va						// rtc: day counter
equ		va,va+2
equ		rtc_week,va						// rtc: day of week Mon(0)..Sun(6)
equ		va,va+2
equ		rtc_hour,va						// rtc: hour counter
equ		va,va+2
equ		rtc_minute,va					// rtc: minute counter
equ		va,va+2
equ		rtc_second,va					// rtc: second counter
equ		va,va+2
equ		rtc_evt_day,va					// rtc: day changed
equ		va,va+2
equ		rtc_evt_hou,va					// rtc: hour changed
equ		va,va+2
equ		rtc_evt_min,va					// rtc: minute changed
equ		va,va+2
equ		rtc_evt_sec,va					// rtc: second changed
equ		va,va+2
equ		gwi_rtncod,va					// gwi: return code
equ		va,va+2
equ		gwi_stat,va						// gwi: state code
equ		va,va+2
equ		gwi_nclm,va						// gwi: column number
equ		va,va+2
equ		gwi_nclm_cur,va					// gwi: current column number
equ		va,va+2
equ		gwi_time,va						// gwi: time (not used)
equ		va,va+2
equ		gwi_temp,va						// gwi: temperature [degC]
equ		va,va+2
equ		gwi_humi,va						// gwi: humidity [%RH]
equ		va,va+2
equ		gwi_rain,va						// gwi: rainfall [mm/h]
equ		va,va+2
equ		hgl_html_siz,va					// hgl: html size
equ		va,va+2
equ		hgl_chr_fifo,va					// hgl: character fifo
equ		va,va+2
equ		hgl_chr,va						// hgl: character code
equ		va,va+2
equ		hgl_dlm,va						// hgl: delimiter code
equ		va,va+2
equ		hgl_cnt,va						// hgl: string length
equ		va,va+2
equ		ole_baikaku,va					// ole: draw BAIKAKU character
equ		va,va+2
$(s)// ********************************
$(s)equ		sim_ptr,va					// sim: read pointer
$(s)equ		va,va+2
$(s)// ********************************
equ		static_va,va
# array variables
equ		lbuf,va							// receive data buffer
equ		va,va+max_lbuf
equ		esp_lbuf,va						// esp32: line buffer
equ		va,va+max_lbuf
equ		i2c_buf,va						// i2c: buffer for i2c frame
equ		va,va+2*64
equ		gwi_area,va						// gwi: area
equ		va,va+max_lbuf
equ		gwi_weather,va					// gwi: weather
equ		va,va+max_lbuf
equ		wck_lin0,va						// wck: display buffer line 0
equ		va,va+(16+2)*2
equ		wck_lin1,va						// wck: display buffer line 1
equ		va,va+(16+2)*2
equ		wck_lin2,va						// wck: display buffer line 2
equ		va,va+(16+2)*2
equ		wck_lin2d,va					// wck: display buffer line 2'
equ		va,va+(16+2)*2
equ		wck_lin3,va						// wck: display buffer line 3
equ		va,va+(16+2)*2
equ		array_va,va
# ================================


// ================================
// setup
// ================================

// set sp to the bottom of ram area
ldwi	r7,idrgramt						// idrg: ram top addr.
ldw		r7,[r7]
ldwi	r6,idrgrams						// idrg: ram size
ldw		r6,[r6]
add		r7,r6
movtc	sp,r7

// clear variables
ldwi	r7,ramtop
ldwi	r1,static_va
ldbiu	r0,0
st_clrvar:
stw		[r7],r0
addi	r7,2
cmp		r7,r1
blo		st_clrvar

// initialize
ldbiu	r0,true
$(s)// ********************************
$(s)ldbiu	r0,false
$(s)// ********************************
ldwi	r7,wck_upd_sntp
stw		[r7],r0
ldwi	r7,wck_upd_getw
stw		[r7],r0
ldbiu	r0,0
ldwi	r7,gwi_area
stw		[r7],r0
ldwi	r7,gwi_weather
stw		[r7],r0

// uart setting: RXE, TXE, baud rate
ldwi	r7,uartbaud
ldwi	r0,uart_baud
stw		[r7],r0
ldwi	r7,uartctl
ldbiu	r0,uart_rxe|uart_txe
stw		[r7],r0

// uart#1 setting: RXE, TXE, baud rate, RTSE
ldwi	r7,uartbaud1
ldwi	r0,uart_baud_esp
stw		[r7],r0
ldwi	r7,uartctl1
ldbiu	r0,uart_rxe|uart_txe
stw		[r7],r0
ldwi	r7,uartflow1
ldbiu	r0,uart_rtse
stw		[r7],r0
// check uart#1 unit
ldwi	r7,uartbaud1
ldw		r0,[r7]
mov		r0,r0
bne		uar1_found
// ERROR: uart#1 unit not found
ldwi	r1,lab_str_err_nouar1
jmpr7	error_halt
uar1_found:

// stwser setting
ldwi	r0,stws_baud
ldwi	r7,stwmbaud
stw		[r7],r0
// check stwser unit
ldw		r1,[r7]
cmp		r0,r1
beq		stw_found
// ERROR: stwser unit not found
ldwi	r1,lab_str_err_nostws
jmpr7	error_halt
stw_found:

// fontjp setting
ldwi	r7,fnjpctl
ldbiu	r0,fnjp_rot_1
stw		[r7],r0
// check fontjp unit
ldw		r1,[r7]
cmp		r0,r1
beq		fjp_found
// ERROR: fontjp unit not found
ldwi	r1,lab_str_err_nofnjp
jmpr7	error_halt
fjp_found:

// check unisji unit
ldwi	r7,unsjctl
ldw		r0,[r7]
andi	r0,unsj_unsj
bne		unsj_found
// ERROR: unisji unit not found
ldwi	r1,lab_str_err_nounsj
jmpr7	error_halt
unsj_found:

// tim162 setting
// interrupt every 1s for real time clock
ldwi	r7,timpsc0
ldwi	r0,fcpu/1000-1
$(s)// ********************************
$(s)ldwi	r0,100-1
$(s)// ********************************
stw		[r7],r0
ldwi	r7,timprd0
ldwi	r0,1000-1
$(s)// ********************************
$(s)ldwi	r0,100-1
$(s)// ********************************
stw		[r7],r0
ldwi	r7,timctl0
ldbiu	r0,timr_cnte
stw		[r7],r0
ldwi	r7,timflg0
ldbiu	r0,timr_ovff|timr_ovfe
stw		[r7],r0

// interrupt setting
ldc		iv,lab_timr_isr
seie

$(s)// ********************************
$(s)// setup dummy slave
$(s)ldbiu	r0,i2c_ssd1306
$(s)ldwi	r7,stwsadr
$(s)stw		[r7],r0
$(s)ldbiu	r0,0
$(s)bra		pcnt+6
$(s)// ********************************
// oled display init
jalwr7	ole_init
mov		r0,r0
beq		ole_init_done
// ERROR: oled display could not init.
ldwi	r1,lab_str_err_oled
jalwr7	print
ole_init_done:
// clear oled display
ldwi	r1,lab_str_wck_clear
ldbiu	r2,0
$(s)// ********************************
$(s)bra		pcnt+6
$(s)// ********************************
jalwr7	ole_kprint
ldwi	r1,lab_str_wck_clear
ldbiu	r2,1
$(s)// ********************************
$(s)bra		pcnt+6
$(s)// ********************************
jalwr7	ole_kprint
ldwi	r1,lab_str_wck_clear
ldbiu	r2,2
$(s)// ********************************
$(s)bra		pcnt+6
$(s)// ********************************
jalwr7	ole_kprint
ldwi	r1,lab_str_wck_clear
ldbiu	r2,3
$(s)// ********************************
$(s)bra		pcnt+6
$(s)// ********************************
jalwr7	ole_kprint

// in preparation message
ldwi	r1,lab_str_wck_prep2
ldbiu	r2,2
$(s)// ********************************
$(s)bra		pcnt+6
$(s)// ********************************
jalwr7	ole_kprint
ldwi	r1,lab_str_wck_prep3
ldbiu	r2,3
$(s)// ********************************
$(s)bra		pcnt+6
$(s)// ********************************
jalwr7	ole_kprint

// esp32
ldwi	r1,lab_str_msg_esp_init
jalwr7	print
// at+rst (reset)
ldwi	r1,lab_str_atc_rst
ldwi	r2,lab_str_res_rst
jalwr7	esp_cast_at
mov		r0,r0
beq		eit_pass
// esp32 init error
ldwi	r1,lab_str_err_esp_init
jalwr7	print
bra		eit_end

eit_pass:
// at+uart_cur (uart config, use CTS)
ldwi	r1,lab_str_atc_uart_cur
ldwi	r2,lab_str_res_atc
jalwr7	esp_cast_at
// at+sntpconfig (sntp config)
ldwi	r1,lab_str_atc_cipsntpcfg
ldwi	r2,lab_str_res_atc
jalwr7	esp_cast_at
// at+cipmux (single connection mode)
ldwi	r1,lab_str_atc_cipmux
ldwi	r2,lab_str_res_atc
jalwr7	esp_cast_at
// at+cipmode (pass through mode)
ldwi	r1,lab_str_atc_cipmode
ldwi	r2,lab_str_res_atc
jalwr7	esp_cast_at
// at+gmr (at-firmware version)
ldwi	r1,lab_str_atc_gmr
ldwi	r2,lab_str_res_atc
jalwr7	esp_cast_at
// at+cipsta? (query ip address)
ldwi	r1,lab_str_atc_cipstaq
ldwi	r2,lab_str_res_atc
jalwr7	esp_cast_at
// esp32 init done
ldwi	r1,lab_str_msg_esp_init_done
jalwr7	print
eit_end:

// send RDY
ldwi	r1,lab_str_msg_rdy
jalwr7	print

$(s)// ********************************
$(s)// for simulation
$(s)// cancel time out
$(s)ldwi	r7,simctrl
$(s)ldbiu	r0,simc_noto
$(s)stw		[r7],r0
$(s)// update display (weather) test
$(s)ldwi	r1,gwi_area
$(s)ldwi	r2,lab_sim_udw_area
$(s)jalwr7	strcpy
$(s)ldwi	r1,gwi_weather
$(s)ldwi	r2,lab_sim_udw_fore
$(s)jalwr7	strcpy
$(s)ldwi	r7,gwi_temp
$(s)ldwi	r0,-19
$(s)stw		[r7],r0
$(s)ldwi	r7,gwi_humi
$(s)ldwi	r0,100
$(s)stw		[r7],r0
$(s)ldwi	r7,gwi_rain
$(s)ldwi	r0,999
$(s)stw		[r7],r0
$(s)ldwi	r7,lbuf
$(s)ldbiu	r0,0
$(s)stw		[r7],r0
$(s)ldbiu	r0,true
$(s)ldwi	r7,wck_upd_wth_part
$(s)stw		[r7],r0
$(s)jalwr7	sim_cmnd
$(s)bra		sim_udw_next
$(s)sim_udw_area:
$(s)dats	"伊丹市の天気\0"
$(s)sim_udw_fore:
$(s)dats	"強い雨\0"
$(s)sim_udw_next:
$(s)ldbiu	r0,0
#8$(s)// update display (clock) test
#8$(s)ldwi	r1,esp_lbuf
#8$(s)ldwi	r2,lab_sim_str_updy
#8$(s)jalwr7	strcpy
#8$(s)ldwi	r7,lbuf
#8$(s)ldbiu	r0,0
#8$(s)stw		[r7],r0
#8$(s)ldbiu	r0,true
#8$(s)ldwi	r7,wck_upd_sntp
#8$(s)stw		[r7],r0
#8$(s)ldwi	r7,wck_upd_rtc_part
#8$(s)stw		[r7],r0
#8$(s)jalwr7	sim_cmnd
#8$(s)ldbiu	r0,0
#8$(s)bra		sim_updy_next
#8$(s)sim_str_updy:
#8$(s)dats	"+CIPSNTPTIME:Tue Feb 29 08:10:32 2000\0"
#8$(s)sim_updy_next:
#7$(s)// "sntp" command test
#7$(s)ldwi	r1,lbuf
#7$(s)ldwi	r2,lab_str_cmd_sntp
#7$(s)jalwr7	strcpy
#7$(s)ldwi	r1,esp_lbuf
#7$(s)ldwi	r2,lab_sim_str_sntp
#7$(s)pushw	r1
#7$(s)jalwr7	strcpy
#7$(s)popw	r1
#7$(s)jalwr7	print
#7$(s)ldwi	r7,princhr
#7$(s)ldbiu	r0,chr_lf
#7$(s)stw		[r7],r0
#7$(s)jalwr7	sim_cmnd
#7$(s)ldbiu	r0,0
#7$(s)bra		sim_sntp_next
#7$(s)sim_str_sntp:
#7$(s)dats	"+CIPSNTPTIME:Wed Aug 24 19:02:13 2022\0"
#7$(s)sim_sntp_next:
#6$(s)// "getw" command test
#6$(s)ldwi	r7,sim_ptr
#6$(s)ldwi	r0,lab_sim_html_dat
#6$(s)stw		[r7],r0
#6$(s)ldwi	r1,lbuf
#6$(s)ldwi	r2,lab_str_cmd_getw
#6$(s)jalwr7	strcpy
#6$(s)jalwr7	sim_cmnd
#5$(s)// utf2sjis test
#5$(s)ldwi	r1,lbuf
#5$(s)ldwi	r2,lab_sim_unsj_utf
#5$(s)jalwr7	strcpy
#5$(s)ldwi	r1,lbuf
#5$(s)jalwr7	utf2sjis
#5$(s)ldwi	r1,lbuf
#5$(s)jalwr7	print
#5$(s)ldbiu	r0,chr_lf
#5$(s)ldwi	r7,princhr
#5$(s)stw		[r7],r0
#5$(s)bra		sim_unsj_next
#5$(s)sim_unsj_utf:
#5$(s)datb	0x2d, 0xe6,0x99,0x82, 0xe5,0x88,0xbb, 0xc3,0x97, 0x34, 0x41, 0xe2,0x92,0xb6, 0x00
#5$(s)sim_unsj_next:
#5$(s)ldbiu	r0,0
#3$(s)// rtc test
#3$(s)ldwi	r7,lab_sim_rtc_tab
#3$(s)ldwi	r5,prindec
#3$(s)sim_rtc_loop:
#3$(s)ldw		r6,[r7]
#3$(s)mov		r6,r6
#3$(s)beq		sim_rtc_body
#3$(s)addi	r7,2
#3$(s)ldw		r0,[r7]
#3$(s)addi	r7,2
#3$(s)stw		[r6],r0
#3$(s)stw		[r5],r0
#3$(s)bra		sim_rtc_loop
#3$(s)sim_rtc_body:
#3$(s)// emulate interrupt
#3$(s)ldwi	r0,lab_sim_rtc_rti
#3$(s)pushw	r0
#3$(s)pushc	sr
#3$(s)jmpr7	timr_isr
#3$(s)sim_rtc_rti:
#3$(s)ldwi	r7,lab_sim_rtc_tab
#3$(s)ldwi	r5,prindec
#3$(s)sim_rtc_loop2:
#3$(s)ldw		r6,[r7]
#3$(s)mov		r6,r6
#3$(s)beq		sim_rtc_break
#3$(s)addi	r7,4
#3$(s)ldw		r0,[r6]
#3$(s)stw		[r5],r0
#3$(s)bra		sim_rtc_loop2
#3$(s)sim_rtc_break:
#3$(s)bra		sim_rtc_next
#3$(s)sim_rtc_tab:
#3$(s)datw	rtc_leap,1
#3$(s)datw	rtc_year,2000
#3$(s)datw	rtc_month,6
#3$(s)datw	rtc_day,30
#3$(s)datw	rtc_week,5
#3$(s)datw	rtc_hour,23
#3$(s)datw	rtc_minute,59
#3$(s)datw	rtc_second,59
#3$(s)datw	0,0
#3$(s)sim_rtc_next:
#2$(s)// leap year test
#2$(s)ldwi	r1,2000
#2$(s)ldwi	r6,prindec
#2$(s)sim_lpyr_loop:
#2$(s)pushw	r1
#2$(s)jalwr7	is_leap
#2$(s)popw	r1
#2$(s)mov		r0,r0
#2$(s)beq		pcnt+2
#2$(s)stw		[r6],r1					// show leap year
#2$(s)addi	r1,1
#2$(s)ldwi	r0,2410
#2$(s)cmp		r1,r0
#2$(s)blo		sim_lpyr_loop
#1$(s)// command test
#1$(s)ldwi	r6,lab_sim_str_cmnd
#1$(s)sim_cmnd_loop2:
#1$(s)ldwi	r7,lbuf
#1$(s)sim_cmnd_loop:
#1$(s)ldb		r0,[r6]
#1$(s)addi	r6,1
#1$(s)stb		[r7],r0
#1$(s)addi	r7,1
#1$(s)mov		r0,r0
#1$(s)bne		sim_cmnd_loop
#1$(s)pushw	r6
#1$(s)jalwr7	sim_cmnd
#1$(s)// skip nil, check end mark (*)
#1$(s)popw	r6
#1$(s)ldb		r0,[r6]
#1$(s)addi	r6,1
#1$(s)cmpi	r0,0
#1$(s)beq		pcnt-8
#1$(s)subi	r6,1
#1$(s)cmpi	r0,0x2a						// asterisk(*)
#1$(s)bne		sim_cmnd_loop2
#1$(s)bra		sim_cmnd_end
#1$(s)sim_str_cmnd:
#1$(s)dats	"who\0"
#1$(s)dats	"help\0"
#1$(s)dats	"*"							// end mark
#1$(s)sim_cmnd_end:
#1$(s)ldbiu	r0,0
$(s)// simulation finish
$(s)mov		r0,r0
$(s)beq		pcnt+6
$(s)ldwi	r0,simfail
$(s)bra		pcnt+4
$(s)ldwi	r0,simpass
$(s)ldwi	r7,simfnsh
$(s)stw		[r7],r0
$(s)bra		pcnt-2
$(s)// ********************************


// ================================
// loop
// ================================
loop:

// ================================
// serial monitor handling
// check uartctl.RAVL
ldwi	r7,uartctl
ldw		r0,[r7]
andi	r0,uart_ravl
beq		no_data
jalwr7	get_line
$(s)// ********************************
$(s)sim_cmnd:
$(s)// ********************************

// check "sntp" command
ldwi	r1,lbuf
ldwi	r2,lab_str_cmd_sntp
jalwr7	strcmp
mov		r0,r0
bne		sntp_notid
// ================================
// sntp
jalwr7	rtc_sntp_time
ldwi	r7,wck_scroll
ldbiu	r0,ole_siz_v-1
stw		[r7],r0
// response
ldwi	r1,lab_str_msg_sntp
jalwr7	print
pushw	r1
ldwi	r7,rtc_year
ldw		r1,[r7]
jalwr7	print_dec
popw	r1
jalwr7	print
pushw	r1
ldwi	r7,rtc_month
ldw		r1,[r7]
jalwr7	print_dec2
popw	r1
jalwr7	print
pushw	r1
ldwi	r7,rtc_day
ldw		r1,[r7]
jalwr7	print_dec2
popw	r1
jalwr7	print
pushw	r1
ldwi	r7,rtc_week
ldw		r1,[r7]
lsfti	r1,2
ldwi	r7,lab_str_rtc_week_jp
add		r1,r7
jalwr7	print
popw	r1
jalwr7	print
pushw	r1
ldwi	r7,rtc_hour
ldw		r1,[r7]
jalwr7	print_dec2
popw	r1
jalwr7	print
pushw	r1
ldwi	r7,rtc_minute
ldw		r1,[r7]
jalwr7	print_dec2
popw	r1
jalwr7	print
pushw	r1
ldwi	r7,rtc_second
ldw		r1,[r7]
jalwr7	print_dec2
popw	r1
jalwr7	print
bra		no_data
sntp_notid:

// check "getw" command
ldwi	r1,lbuf
ldwi	r2,lab_str_cmd_getw
jalwr7	strcmp
mov		r0,r0
bne		getw_notid
// ================================
// getw
jalwr7	get_weather_info
mov		r0,r0
beq		getw_noerr
// ERROR:
pushw	r0
ldwi	r1,lab_str_err_gwi_getw
jalwr7	print
popw	r0
pushw	r1
mov		r1,r0
jalwr7	print_dec
popw	r1
jalwr7	print
bra		no_data
getw_noerr:
ldwi	r7,wck_scroll
ldbiu	r0,ole_siz_h/2
stw		[r7],r0
ldwi	r7,wck_upd_wth_part
ldbiu	r0,true
stw		[r7],r0
// response
ldwi	r1,lab_str_msg_getw
jalwr7	print
pushw	r1
// area
ldwi	r1,gwi_area
jalwr7	print
popw	r1
jalwr7	print
pushw	r1
// weather
ldwi	r1,gwi_weather
jalwr7	print
popw	r1
jalwr7	print
pushw	r1
// temperature
ldwi	r7,gwi_temp
ldw		r1,[r7]
jalwr7	print_dec
popw	r1
jalwr7	print
pushw	r1
// humidity
ldwi	r7,gwi_humi
ldw		r1,[r7]
jalwr7	print_dec
popw	r1
jalwr7	print
pushw	r1
// rainfall
ldwi	r7,gwi_rain
ldw		r1,[r7]
jalwr7	print_dec
popw	r1
jalwr7	print
bra		no_data
getw_notid:

// check "path" command
ldwi	r1,lbuf
ldwi	r2,lab_str_cmd_path
jalwr7	strcmp
mov		r0,r0
bne		path_notid
// ================================
// path
jalwr7	esp_passthru
// response
ldwi	r1,lab_str_msg_path
jalwr7	print
bra		no_data
path_notid:

// check "who" command
ldwi	r1,lbuf
ldwi	r2,lab_str_cmd_who
jalwr7	strcmp
mov		r0,r0
bne		who_notid
// ================================
// who
// response
ldwi	r1,lab_str_msg_who
jalwr7	print
bra		no_data
who_notid:

// check "help" command
ldwi	r1,lbuf
ldwi	r2,lab_str_cmd_help
jalwr7	strcmp
mov		r0,r0
bne		help_notid
// ================================
// help
// response
ldwi	r1,lab_str_msg_help
jalwr7	print_lst
bra		no_data
help_notid:

// ================================
// ignore empty line
ldwi	r1,lbuf
ldb		r0,[r1]
mov		r0,r0
beq		no_data
// ================================
// ERROR: unsupported command
ldwi	r1,lab_str_err_unspt
jalwr7	print
pushw	r1
ldwi	r1,lbuf
jalwr7	print
popw	r1
jalwr7	print
bra		no_data

// ERROR: syntax
err_syntx:
ldwi	r1,lab_str_err_syntx
jalwr7	print
bra		no_data

no_data:
// end of command interpretation


// ================================
// update event
clie
// second event
ldwi	r7,rtc_evt_sec
ldw		r0,[r7]
mov		r0,r0
beq		uev_not_sec
// set update rtc
ldbiu	r0,true
ldwi	r7,wck_upd_rtc_part
stw		[r7],r0
uev_not_sec:
// minute event
ldwi	r7,rtc_evt_min
ldw		r0,[r7]
mov		r0,r0
beq		uev_not_min
ldwi	r7,rtc_minute
ldw		r0,[r7]
cmpi	r0,wck_getw_minute
bne		uev_not_min
// set update sntp & getw
ldbiu	r0,true
ldwi	r7,wck_upd_sntp
stw		[r7],r0
ldwi	r7,wck_upd_getw
stw		[r7],r0
uev_not_min:
// clear event flag
ldbiu	r0,false
ldwi	r7,rtc_evt_sec
stw		[r7],r0
ldwi	r7,rtc_evt_min
stw		[r7],r0
ldwi	r7,rtc_evt_hou
stw		[r7],r0
ldwi	r7,rtc_evt_day
stw		[r7],r0
seie
// end of update event


// ================================
// weather info
ldwi	r7,wck_upd_getw
ldw		r0,[r7]
mov		r0,r0
beq		wth_next
// get weather information
jalwr7	get_weather_info
ldwi	r7,wck_upd_wth_part
ldbiu	r0,true
stw		[r7],r0
// clear flag
ldbiu	r0,false
ldwi	r7,wck_upd_getw
stw		[r7],r0
wth_next:
// end of weather info


// ================================
// update display contents, real time clock
ldwi	r7,wck_upd_rtc_part
ldw		r0,[r7]
mov		r0,r0
beq		udcr_next
clie
// line 0: time
ldwi	r1,wck_lin0
ldwi	r2,lab_str_wck_clear
jalwr7	strcpy
ldwi	r1,wck_lin0
ldwi	r2,lab_str_wck_time
jalwr7	strcpy
pushw	r2
// hour
ldwi	r7,rtc_hour
ldw		r2,[r7]
jalwr7	strcpy_dec2
popw	r2
jalwr7	strcpy
pushw	r2
// minute
ldwi	r7,rtc_minute
ldw		r2,[r7]
jalwr7	strcpy_dec2
popw	r2
jalwr7	strcpy
pushw	r2
// second
ldwi	r7,rtc_second
ldw		r2,[r7]
jalwr7	strcpy_dec2
popw	r2
// truncate
ldbiu	r0,chr_spc
stb		[r1],r0
ldwi	r1,wck_lin0
ldbiu	r2,8
jalwr7	strtrunc
$(s)// ********************************
$(s)ldwi	r7,princhr
$(s)ldbiu	r0,chr_lt
$(s)stw		[r7],r0
$(s)ldwi	r1,wck_lin0
$(s)jalwr7	print
$(s)ldwi	r7,princhr
$(s)ldbiu	r0,chr_gt
$(s)stw		[r7],r0
$(s)ldbiu	r0,chr_lf
$(s)stw		[r7],r0
$(s)// ********************************
// line 1: date
ldwi	r1,wck_lin1
ldwi	r2,lab_str_wck_clear
jalwr7	strcpy
ldwi	r1,wck_lin1
ldwi	r2,lab_str_wck_date
jalwr7	strcpy
pushw	r2
// year
ldwi	r7,rtc_year
ldw		r2,[r7]
jalwr7	strcpy_dec
popw	r2
jalwr7	strcpy
pushw	r2
// month
ldwi	r7,rtc_month
ldw		r2,[r7]
jalwr7	strcpy_dec2
popw	r2
jalwr7	strcpy
pushw	r2
// day
ldwi	r7,rtc_day
ldw		r2,[r7]
jalwr7	strcpy_dec2
popw	r2
jalwr7	strcpy
pushw	r2
// week of day
ldwi	r7,rtc_week
ldw		r2,[r7]
lsfti	r2,2
ldwi	r0,lab_str_rtc_week_jp
add		r2,r0
jalwr7	strcpy
popw	r2
jalwr7	strcpy
// truncate
ldbiu	r0,chr_spc
stb		[r1],r0
ldwi	r1,wck_lin1
ldbiu	r2,16
jalwr7	strtrunc
seie
$(s)// ********************************
$(s)ldwi	r7,princhr
$(s)ldbiu	r0,chr_lt
$(s)stw		[r7],r0
$(s)ldwi	r1,wck_lin1
$(s)jalwr7	print
$(s)ldwi	r7,princhr
$(s)ldbiu	r0,chr_gt
$(s)stw		[r7],r0
$(s)ldbiu	r0,chr_lf
$(s)stw		[r7],r0
$(s)// ********************************
// clear flag
ldwi	r7,wck_upd_rtc_part
ldbiu	r0,false
stw		[r7],r0
// set flag
ldwi	r7,wck_upd_oled01
ldbiu	r0,true
stw		[r7],r0
udcr_next:
// end of update display contents, real time clock


// ================================
// update display contents, weather
ldwi	r7,wck_upd_wth_part
ldw		r0,[r7]
mov		r0,r0
beq		udcw_next
// line 2: area
ldwi	r1,wck_lin2
ldwi	r2,lab_str_wck_clear
jalwr7	strcpy
// area
ldwi	r1,wck_lin2
ldwi	r2,gwi_area
mov		r7,r2
addi	r7,32
ldbiu	r0,0
stb		[r7],r0
jalwr7	strcpy
// truncate
ldbiu	r0,chr_spc
stb		[r1],r0
ldwi	r1,wck_lin2
ldbiu	r2,16
jalwr7	strtrunc
$(s)// ********************************
$(s)ldwi	r7,princhr
$(s)ldbiu	r0,chr_lt
$(s)stw		[r7],r0
$(s)ldwi	r1,wck_lin2
$(s)jalwr7	print
$(s)ldwi	r7,princhr
$(s)ldbiu	r0,chr_gt
$(s)stw		[r7],r0
$(s)ldbiu	r0,chr_lf
$(s)stw		[r7],r0
$(s)// ********************************
// line 2d: forcast
ldwi	r1,wck_lin2d
ldwi	r2,lab_str_wck_clear
jalwr7	strcpy
// forecast
ldwi	r1,wck_lin2d
ldwi	r2,gwi_weather
ldbiu	r0,0
mov		r7,r2
addi	r7,32
stb		[r7],r0
jalwr7	strcpy
// truncate
ldbiu	r0,chr_spc
stb		[r1],r0
ldwi	r1,wck_lin2d
ldbiu	r2,4
jalwr7	strtrunc
$(s)// ********************************
$(s)ldwi	r7,princhr
$(s)ldbiu	r0,chr_lt
$(s)stw		[r7],r0
$(s)ldwi	r1,wck_lin2d
$(s)jalwr7	print
$(s)ldwi	r7,princhr
$(s)ldbiu	r0,chr_gt
$(s)stw		[r7],r0
$(s)ldbiu	r0,chr_lf
$(s)stw		[r7],r0
$(s)// ********************************
// line 3: temp, humid, rainfall
ldwi	r1,wck_lin3
ldwi	r2,lab_str_wck_clear
jalwr7	strcpy
ldwi	r1,wck_lin3
ldwi	r2,lab_str_wck_temp
jalwr7	strcpy
pushw	r2
// temperature
ldwi	r7,gwi_temp
ldw		r2,[r7]
mov		r2,r2
bpl		udcw_temp_plus
ldbiu	r0,chr_mns
stb		[r1],r0
addi	r1,1
neg		r2
udcw_temp_plus:
jalwr7	strcpy_dec
popw	r2
jalwr7	strcpy
pushw	r2
// humidity
ldwi	r7,gwi_humi
ldw		r2,[r7]
jalwr7	strcpy_dec
popw	r2
jalwr7	strcpy
pushw	r2
// rainfall
ldwi	r7,gwi_rain
ldw		r2,[r7]
jalwr7	strcpy_dec
popw	r2
jalwr7	strcpy
// truncate
ldbiu	r0,chr_spc
stb		[r1],r0
ldwi	r1,wck_lin3
ldbiu	r2,16
jalwr7	strtrunc
$(s)// ********************************
$(s)ldwi	r7,princhr
$(s)ldbiu	r0,chr_lt
$(s)stw		[r7],r0
$(s)ldwi	r1,wck_lin3
$(s)jalwr7	print
$(s)ldwi	r7,princhr
$(s)ldbiu	r0,chr_gt
$(s)stw		[r7],r0
$(s)ldbiu	r0,chr_lf
$(s)stw		[r7],r0
$(s)// ********************************
// clear flag
ldwi	r7,wck_upd_wth_part
ldbiu	r0,false
stw		[r7],r0
// set flag
ldwi	r7,wck_upd_oled23
ldbiu	r0,true
stw		[r7],r0
udcw_next:
// end of update display contents, update weather


// ================================
// update oled display
ldwi	r7,wck_upd_oled01
ldw		r0,[r7]
mov		r0,r0
beq		uole_next1
// draw line 0,1
ldwi	r7,ole_baikaku
ldbiu	r0,true
stw		[r7],r0
ldwi	r1,wck_lin0
ldbiu	r2,0
jalwr7	ole_kprint
ldwi	r7,ole_baikaku
ldbiu	r0,false
stw		[r7],r0
ldwi	r1,wck_lin1
ldbiu	r2,1
jalwr7	ole_kprint
// clear flag
ldwi	r7,wck_upd_oled01
ldbiu	r0,false
stw		[r7],r0
uole_next1:
ldwi	r7,wck_upd_oled23
ldw		r0,[r7]
mov		r0,r0
beq		uole_next2
// draw line 2,3
ldwi	r1,wck_lin2
ldbiu	r2,2
jalwr7	ole_kprint
ldwi	r1,wck_lin2d
ldbiu	r2,2
ldbiu	r3,8
ldwi	r7,ole_baikaku
ldbiu	r0,true
stw		[r7],r0
jalwr7	ole_kprint+2
ldwi	r7,ole_baikaku
ldbiu	r0,false
stw		[r7],r0
ldwi	r1,wck_lin3
ldbiu	r2,3
jalwr7	ole_kprint
// clear flag
ldwi	r7,wck_upd_oled23
ldbiu	r0,false
stw		[r7],r0
uole_next2:
// end of update oled display


// ================================
// sntp time
ldwi	r7,wck_upd_sntp
ldw		r0,[r7]
mov		r0,r0
beq		snt_next
jalwr7	rtc_sntp_time
// clear flag
ldbiu	r0,false
ldwi	r7,wck_upd_sntp
stw		[r7],r0
snt_next:
// end of sntp time


// ================================
// update scroll position
ldwi	r7,wck_msec_prev
ldw		r1,[r7]
addi	r7,2
ldw		r0,[r7]
ldwi	r7,sytmmilh
ldw		r3,[r7]
addi	r7,2
ldw		r2,[r7]
mov		r5,r3
mov		r4,r2
sub		r2,r0
sbb		r3,r1
ldbiu	r1,0
ldwi	r0,wck_msec_scr
cmp		r2,r0
cmb		r3,r1
blo		usp_next
// update wck_msec_prev
ldwi	r7,wck_msec_prev
stw		[r7],r5
addi	r7,2
stw		[r7],r4
// update scroll
ldwi	r7,wck_scroll
ldw		r0,[r7]
addi	r0,1
cmpi	r0,ole_siz_v*6/4
blo		pcnt+2
ldbiu	r0,0
stw		[r7],r0
// clip scroll
mov		r1,r0
cmpi	r1,ole_siz_v
blo		pcnt+2
ldbiu	r1,0
jalwr7	ole_set_offset
usp_next:
// end of update scroll position


// ================================
// redirect uart#1 (esp32) to uart#0 (serial monitor)
// check RAVL1
ldwi	r7,uartctl1
ldw		r0,[r7]
andi	r0,uart_ravl
beq		rdir_not_ravl
// get line (redirect)
jalwr7	esp_get_line
$(d)// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
$(d)bra		rdir_not_ravl
$(d)// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
ldwi	r1,lab_str_msg_esp_rdir
jalwr7	print
pushw	r1
ldwi	r1,esp_lbuf
jalwr7	print
popw	r1
jalwr7	print
rdir_not_ravl:
// end of redirection


// ================================
// end of loop
$(s)// ********************************
$(s)rtnw
$(s)// ********************************
bra		loop


// ================================
// ERROR: halted
error_halt:
jalwr7	print
$(s)// ********************************
$(s)ldwi	r0,simfail
$(s)ldwi	r7,simfnsh
$(s)stw		[r7],r0
$(s)// ********************************
pause
bra		pcnt-4


// ================================
// tim162 interrupt service routine
//	general register bank #2 is reserved for isr.
// ================================
timr_isr:
ldcl	sr,sreg_bk_2
#$(d)// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#$(d)ldbiu	r1,0a_
#$(d)jalwr7	print_chr
#$(d)// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// clear interrupt flag
ldwi	r7,timflg0
ldbiu	r0,timr_ovff|timr_ovfe
stw		[r7],r0
// update rtc
ldwi	r7,rtc_evt_sec
ldbiu	r0,true
stw		[r7],r0
ldwi	r7,rtc_second
ldw		r0,[r7]
addi	r0,1
stw		[r7],r0
cmpi	r0,60
blo		tisr_rtc_done
// carry second -> minute
ldbiu	r0,0
stw		[r7],r0
ldwi	r7,rtc_evt_min
ldbiu	r0,true
stw		[r7],r0
ldwi	r7,rtc_minute
ldw		r0,[r7]
addi	r0,1
stw		[r7],r0
cmpi	r0,60
blo		tisr_rtc_done
// carry minute -> hour
ldbiu	r0,0
stw		[r7],r0
ldwi	r7,rtc_evt_hou
ldbiu	r0,true
stw		[r7],r0
ldwi	r7,rtc_hour
ldw		r0,[r7]
addi	r0,1
stw		[r7],r0
cmpi	r0,24
blo		tisr_rtc_done
// carry hour -> day
ldbiu	r0,0
stw		[r7],r0
ldwi	r7,rtc_evt_day
ldbiu	r0,true
stw		[r7],r0
ldwi	r7,rtc_week
ldw		r0,[r7]
addi	r0,1
cmpi	r0,7
blo		pcnt+2
ldbiu	r0,0
stw		[r7],r0
ldwi	r7,rtc_day
ldw		r0,[r7]
addi	r0,1
stw		[r7],r0
// days in the month
ldwi	r7,rtc_month
ldw		r1,[r7]
ldwi	r7,lab_tisr_rtc_dinm-1
add		r7,r1
ldb		r1,[r7]
cmpi	r1,28
bne		tisr_rtc_notfeb
// leap year?
ldwi	r7,rtc_leap
ldw		r2,[r7]
add		r1,r2
tisr_rtc_notfeb:
addi	r1,1
cmp		r0,r1
blo		tisr_rtc_done
// carry day -> month
ldwi	r7,rtc_day
ldbiu	r0,1
stw		[r7],r0
ldwi	r7,rtc_month
ldw		r0,[r7]
addi	r0,1
stw		[r7],r0
cmpi	r0,12+1
blo		tisr_rtc_done
// carry month -> year
ldbiu	r0,1
stw		[r7],r0
ldwi	r7,rtc_year
ldw		r0,[r7]
addi	r0,1
stw		[r7],r0
// judge leap year
mov		r1,r0
jalwr7	is_leap
ldwi	r7,rtc_leap
stw		[r7],r0
// update rtc done
tisr_rtc_done:
rti

// days in the month
tisr_rtc_dinm:
datb	31,28,31,30, 31,30,31,31, 30,31,30,31

// ================================
// is r1 leap year ; disturbed r1,Sr[DR]
//	return: r0=true / false
// ================================
is_leap:
pushw	r1
andi	r1,4-1
popw	r1
ldbiu	r0,false
bne		isl_return
lsfti	r1,-2
ldbiu	r0,100/4
sesr	sreg_b_dr
divu	r1,r0
cmpi	r0,0
ldbiu	r0,true
bne		isl_return
// %100==0
andi	r1,4-1
beq		isl_return
ldbiu	r0,false						// %100==0 && %400!=0
isl_return:
rtnw


// ================================
// get weather information
// ================================
get_weather_info:
ldwi	r7,gwi_rtncod
ldbiu	r0,0
stw		[r7],r0
// show status
ldwi	r7,wck_scroll
ldbiu	r1,ole_siz_v/2
stw		[r7],r1
jalwr7	ole_set_offset
ldwi	r1,lab_str_wck_weather
ldbiu	r2,2
$(s)// ********************************
$(s)bra		pcnt+6
$(s)// ********************************
jalwr7	ole_kprint
ldwi	r1,lab_str_wck_clear
ldbiu	r2,3
$(s)// ********************************
$(s)bra		pcnt+6
$(s)// ********************************
jalwr7	ole_kprint
// ================================
// http connect
// at+cipstart (http connect)
ldwi	r1,lab_str_atc_cipstart
ldwi	r2,lab_str_res_start
jalwr7	esp_cast_at
$(s)// ********************************
$(s)cmp		r0,r0
$(s)bra		pcnt+2
$(s)// ********************************
cmpi	r0,2
beq		gwi_connected
// ERROR: not "CONNECT" response
gwi_loop1:
cmpi	r0,2
blo		gwi_break1
ldwi	r1,lab_str_res_start
jalwr7	esp_wait_response
bra		gwi_loop1
gwi_break1:
// message
ldwi	r1,lab_str_err_esp_start
jalwr7	print
// return code
ldwi	r7,gwi_rtncod
ldbiu	r0,255
stw		[r7],r0
bra		gwi_return

gwi_connected:
// discard "OK" message
ldwi	r1,lab_str_res_start
jalwr7	esp_wait_response

// ================================
// enter pass through mode
// at+cipsend (enter pass through mode)
ldwi	r1,lab_str_atc_cipsend
ldwi	r2,lab_str_res_atc
jalwr7	esp_cast_at
mov		r0,r0
beq		gwi_enter_path
// ERROR:
ldwi	r1,lab_str_err_esp_path
jalwr7	print
ldwi	r7,gwi_rtncod
ldbiu	r0,255
stw		[r7],r0
bra		gwi_return

gwi_enter_path:
$(s)// ********************************
$(s)bra		gwi_break2
$(s)// ********************************
// clear receiving data (wrap return ">" and greeting if received)
ldwi	r1,500
jalwr7	delay
gwi_loop2:
// check RAVL1
ldwi	r7,uartctl1
ldw		r0,[r7]
andi	r0,uart_ravl
beq		gwi_break2
// receive and discard a byte
ldwi	r7,uartrdat1
ldw		r0,[r7]
bra		gwi_loop2
gwi_break2:

// ================================
// http session
// send http-get
ldwi	r1,lab_str_http_get
jalwr7	esp_print

// http header: "HTTP/1.1 200 OK"
jalwr7	esp_get_line
ldwi	r1,esp_lbuf
ldwi	r2,lab_str_http_res_head
jalwr7	strfcmp
mov		r0,r0
beq		gwi_head_endif
// ERROR: illegal response header
ldwi	r7,gwi_rtncod
ldbiu	r0,255
stw		[r7],r0
ldwi	r1,lab_str_err_gwi_head
jalwr7	print

gwi_head_endif:

// response header
ldwi	r7,hgl_html_siz
ldbiu	r0,0
stw		[r7],r0
gwi_loop3:
jalwr7	esp_get_line
ldwi	r1,esp_lbuf
ldb		r0,[r1]
mov		r0,r0
beq		gwi_empty_line
// check Transfer-Encoding
ldwi	r1,esp_lbuf
ldwi	r2,lab_str_http_tranenc
jalwr7	strfcmp
mov		r0,r0
bne		gwi_tranenc_endif
// "Transfer-Encoding:"
ldwi	r0,1
ldwi	r7,hgl_html_siz
stw		[r7],r0
gwi_tranenc_endif:
bra		gwi_loop3
gwi_empty_line:

// check "Transfer-Encoding:"
ldwi	r7,hgl_html_siz
ldw		r0,[r7]
mov		r0,r0
bne		gwi_siz_endif
// ERROR: illegal header
ldwi	r7,gwi_rtncod
ldbiu	r0,255
stw		[r7],r0
bra		gwi_exit
gwi_siz_endif:

// current column number
ldwi	r7,rtc_hour
ldw		r0,[r7]							// 0<=r0<=23
ldbiu	r1,3
divu	r0,r1							// 0<=r0<=7
addi	r0,2							// 2<=r0<=9
ldwi	r7,gwi_nclm_cur
stw		[r7],r0

// start analyze html
ldbiu	r0,0
ldwi	r7,gwi_stat
stw		[r7],r0
ldwi	r7,hgl_chr_fifo
stw		[r7],r0
#	html_get_line;
jalwr7	html_get_line
#	while (!EOF)
#	{
gwi_while4:
$(d)// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
$(d)pushc	sr
$(d)ldcl	sr,sreg_bk_1
$(d)ldbiu	r1,0ag
$(d)jalwr7	print_chr
$(d)ldwi	r1,esp_lbuf
$(d)jalwr7	print
$(d)ldbiu	r1,chr_cr
$(d)jalwr7	print_chr
$(d)ldbiu	r1,chr_lf
$(d)jalwr7	print_chr
$(d)popc	sr
$(d)// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
mov		r0,r0
bne		gwi_break4
// analyze
#	if (stat=0)
ldwi	r7,gwi_stat
ldw		r0,[r7]
cmpi	r0,0
bne		gwi_stat0_else
#	{
// area
#	strcmp	cmp=$(html_get_line),"<title>",left;
ldwi	r1,esp_lbuf
ldwi	r2,lab_str_html_tag_title
jalwr7	strfcmp
#	if (cmp=0)
mov		r0,r0
bne		gwi_ttl_endif
#	{
// search except tag
#	repeat
#	{
gwi_lt_repeat:
#	html_get_line;
jalwr7	html_get_line
#	if (status)
#	{
#	break;
#	}
mov		r0,r0
bne		gwi_lt_break
#	strcmp	cmp=$(html_get_line),"<",left;
ldwi	r1,esp_lbuf
ldb		r0,[r1]
#	} until (cmp!=0);
cmpi	r0,chr_lt
beq		gwi_lt_repeat
gwi_lt_break:
// area string
ldwi	r1,gwi_area
ldwi	r2,esp_lbuf
jalwr7	strcpy
ldwi	r1,gwi_area
jalwr7	utf2sjis
// delete after "の天気"
ldwi	r1,gwi_area
ldwi	r2,lab_str_html_notenki
jalwr7	strstr
mov		r0,r0
beq		gwi_noten_endif
#subi	r0,1							// "の天気"以降を消す時
addi	r0,5							// "の天気"まで残して、その後ろを消す
add		r1,r0
ldbiu	r0,0
stb		[r1],r0
gwi_noten_endif:
#	stat=stat + 1;
ldwi	r7,gwi_stat
ldw		r0,[r7]
addi	r0,1
stw		[r7],r0
#	}
gwi_ttl_endif:
bra		gwi_stat_endif
#	}
gwi_stat0_else:
#	elif (stat=1)
cmpi	r0,1
bne		gwi_stat1_else
#	{
// search "<tbody>"
#	strcmp	cmp=$(html_get_line),"<tbody>",left;
ldwi	r1,esp_lbuf
ldwi	r2,lab_str_html_tag_tbody
jalwr7	strfcmp
#	if (cmp=0)
mov		r0,r0
bne		gwi_tbody_endif
#	{
#	stat=stat + 1;
ldwi	r7,gwi_stat
ldw		r0,[r7]
addi	r0,1
stw		[r7],r0
#	nclm=0;
ldwi	r7,gwi_nclm
ldbiu	r0,0
stw		[r7],r0
#	}
gwi_tbody_endif:
bra		gwi_stat_endif
#	}
gwi_stat1_else:
#	elif (2<=stat & stat<=6)
cmpi	r0,2
blo		gwi_stat26_else
cmpi	r0,6+1
bhs		gwi_stat26_else
#	{
// table body
#	strcmp	cmp=$(html_get_line),"<td",left;
ldwi	r1,esp_lbuf
ldwi	r2,lab_str_html_tag_td
jalwr7	strfcmp
#	if (cmp=0)
mov		r0,r0
bne		gwi_td_endif
#	{
#	nclm=nclm + 1;
ldwi	r7,gwi_nclm
ldw		r0,[r7]
addi	r0,1
stw		[r7],r0
#	repeat
#	{
gwi_td_repeat:
#	html_get_line;
jalwr7	html_get_line
#	if (status)
#	{
#	break;
#	}
mov		r0,r0
bne		gwi_td_break
#	strcmp	cmp=$(html_get_line),"<",left;
#	} until (cmp!=0);
ldwi	r1,esp_lbuf
ldb		r0,[r1]
cmpi	r0,chr_lt
beq		gwi_td_repeat
gwi_td_break:
#	if (nclm=nclm_cur)
ldwi	r7,gwi_nclm
ldw		r0,[r7]
ldwi	r7,gwi_nclm_cur
ldw		r1,[r7]
cmp		r0,r1
bne		gwi_cur_endif
#	{
#	strcat	info,$(html_get_line)",";
// weather informations
ldwi	r7,gwi_stat
ldw		r0,[r7]
cmpi	r0,2
bne		gwi_stat2_else
// stat=2 (time)
ldwi	r1,esp_lbuf
jalwr7	atoi
ldwi	r7,gwi_time
stw		[r7],r0
bra		gwi_stat6_else

gwi_stat2_else:
cmpi	r0,3
bne		gwi_stat3_else
// stat=3 (weather)
ldwi	r1,gwi_weather
ldwi	r2,esp_lbuf
pushw	r1
jalwr7	strcpy
popw	r1
jalwr7	utf2sjis
bra		gwi_stat6_else

gwi_stat3_else:
cmpi	r0,4
bne		gwi_stat4_else
// stat=4 (temperature)
ldwi	r1,esp_lbuf
ldb		r0,[r1]
cmpi	r0,chr_mns
bne		gwi_temp_else
// temp<0
addi	r1,1
jalwr7	atoi
neg		r0
bra		gwi_temp_endif
gwi_temp_else:
// temp>=0
jalwr7	atoi
gwi_temp_endif:
ldwi	r7,gwi_temp
stw		[r7],r0
bra		gwi_stat6_else

gwi_stat4_else:
cmpi	r0,5
bne		gwi_stat5_else
// stat=5 (humidity)
ldwi	r1,esp_lbuf
jalwr7	atoi
ldwi	r7,gwi_humi
stw		[r7],r0
bra		gwi_stat6_else

gwi_stat5_else:
cmpi	r0,6
bne		gwi_stat6_else
// stat=6 (rainfall)
ldwi	r1,esp_lbuf
jalwr7	atoi
ldwi	r7,gwi_rain
stw		[r7],r0
bra		gwi_stat6_else

gwi_stat6_else:
#	}
gwi_cur_endif:
#	if (nclm>=9)
ldwi	r7,gwi_nclm
ldw		r0,[r7]
cmpi	r0,9
blo		gwi_nclm_endif
#	{
#	stat=stat + 1;
ldwi	r7,gwi_stat
ldw		r0,[r7]
addi	r0,1
stw		[r7],r0
#	nclm=0;
ldwi	r7,gwi_nclm
ldbiu	r0,0
stw		[r7],r0
#	}
gwi_nclm_endif:
#	if (stat=2 & nclm=1)
ldwi	r7,gwi_stat
ldw		r0,[r7]
cmpi	r0,2
bne		gwi_stcl_endif
ldwi	r7,gwi_nclm
ldw		r0,[r7]
cmpi	r0,1
bne		gwi_stcl_endif
#	{
// if 1st element is not "時刻", that table is not the one. re-try.
#	strcmp	cmp=$(html_get_line),$(stru8c), left;
ldwi	r1,esp_lbuf
ldwi	r2,lab_str_html_jikoku
jalwr7	strfcmp
#	if (cmp!=0)
mov		r0,r0
beq		gwi_jik_endif
#	{
#	stat=stat - 1;
ldwi	r7,gwi_stat
ldw		r0,[r7]
subi	r0,1
stw		[r7],r0
#	nclm=0;
ldwi	r7,gwi_nclm
ldbiu	r0,0
stw		[r7],r0
#	}
gwi_jik_endif:
#	}
gwi_stcl_endif:
#	}
gwi_td_endif:
bra		gwi_stat_endif
#	}
gwi_stat26_else:
#	elif (stat=7)
cmpi	r0,7
bne		gwi_stat_endif
#	{
// discard to EOF
#	var		chr;
#
#	fgetb	fin,chr;
#	while (status=0)
#	{
#	fputb	fout,chr;
#	hgl_html_siz=hgl_html_siz + 1;
#	// continue
#	fgetb	fin,chr;
#	}
gwi_while5:
jalwr7	html_get_byte
ldwi	r7,hgl_html_siz
ldw		r0,[r7]
cmpi	r0,1
bhs		gwi_while5
#	break;
bra		gwi_break4
#	}
gwi_stat_endif:
#
// continue
#	html_get_line;
jalwr7	html_get_line
#	}
bra		gwi_while4
gwi_break4:
// discard until empty line, omitted

// ================================
// exit pass through mode
gwi_exit:
ldwi	r1,500
jalwr7	delay
ldwi	r1,lab_str_cmd_exit_send
jalwr7	esp_print
ldwi	r1,1000
jalwr7	delay

// close connection
// at+cipclose (close connection)
ldwi	r1,lab_str_atc_cipclose
ldwi	r2,lab_str_res_atc
jalwr7	esp_cast_at

gwi_return:
// return code
ldwi	r7,gwi_rtncod
ldw		r0,[r7]
rtnw


// ================================
// html get line
//	return: r0=0(no error) / 255(EOF)
// ================================
html_get_line:
ldwi	r7,hgl_html_siz
ldw		r0,[r7]
cmpi	r0,1
bhs		hgl_eof_endif
// ERROR: html EOF
ldwi	r7,esp_lbuf
ldbiu	r0,0
stb		[r7],r0
ldbiu	r0,255
bra		hgl_return
hgl_eof_endif:
#	var		hgl_html_siz;
#	var		hgl_chr_fifo;
#	procedure	html_get_line
#	{
#	var		hgl_chr;
#	var		hgl_dlm;
#	var		hgl_cnt;
ldbiu	r0,0
ldwi	r7,hgl_chr
stw		[r7],r0
ldwi	r7,hgl_dlm
stw		[r7],r0
ldwi	r7,hgl_cnt
stw		[r7],r0
// get 1st character
#	if (hgl_chr_fifo)
ldwi	r7,hgl_chr_fifo
ldw		r0,[r7]
mov		r0,r0
beq		hgl_fifo_else
#	{
#	hgl_chr=hgl_chr_fifo;
ldwi	r7,hgl_chr
stw		[r7],r0
#	hgl_chr_fifo=0;
ldwi	r7,hgl_chr_fifo
ldbiu	r1,0
stw		[r7],r1
bra		hgl_fifo_endif
#	}
#	else
#	{
hgl_fifo_else:
#	fgetb	fin,hgl_chr;
#	hgl_html_siz=hgl_html_siz + 1;
jalwr7	html_get_byte
ldwi	r7,hgl_chr
stw		[r7],r0
#	}
hgl_fifo_endif:

// skip space
#	while (hgl_chr=chr_spc | hgl_chr=chr_tab |
#	hgl_chr=chr_cr | hgl_chr=chr_lf)
hgl_while1:
ldwi	r7,hgl_chr
ldw		r0,[r7]
cmpi	r0,chr_spc
beq		hgl_true1
cmpi	r0,chr_tab
beq		hgl_true1
cmpi	r0,chr_cr
beq		hgl_true1
cmpi	r0,chr_lf
beq		hgl_true1
bra		hgl_break1
#	{
hgl_true1:
#	fgetb	fin,hgl_chr;
#	hgl_html_siz=hgl_html_siz + 1;
jalwr7	html_get_byte
ldwi	r7,hgl_chr
stw		[r7],r0
bra		hgl_while1
#	}
hgl_break1:

// determine the delimiter
#	if (hgl_chr=chr_lt)
ldwi	r7,hgl_chr
ldw		r0,[r7]
cmpi	r0,chr_lt
bne		pcnt+4
#	{
#	hgl_dlm=chr_gt;
ldbiu	r0,chr_gt
bra		pcnt+2
#	}
#	else
#	{
#	hgl_dlm=chr_lt;
ldbiu	r0,chr_lt
#	}
ldwi	r7,hgl_dlm
stw		[r7],r0

// get until delimiter
ldwi	r6,esp_lbuf
#	while (true)
hgl_while2:
#	{
#	chrcat	html_get_line,hgl_chr, binary;
ldwi	r7,hgl_chr
ldw		r0,[r7]
stb		[r6],r0
addi	r6,1
#	hgl_cnt=hgl_cnt + 1;
ldwi	r7,hgl_cnt
ldw		r0,[r7]
addi	r0,1
stw		[r7],r0
#	if (hgl_cnt>=hgl_max_lin)
cmpi	r0,max_lbuf-1
blo		hgl_max_endif
#	{
// skip to delimiter
#	repeat
ldwi	r7,hgl_dlm
ldw		r1,[r7]
hgl_repeat:
#	{
#	fgetb	fin,hgl_chr;
#	hgl_html_siz=hgl_html_siz + 1;
jalwr7	html_get_byte
ldwi	r7,hgl_chr
stw		[r7],r0
#	} until (hgl_chr=hgl_dlm);
cmp		r0,r1
bne		hgl_repeat
#	if (hgl_dlm=chr_lt)
cmpi	r1,chr_lt
bne		pcnt+4
#	{
#	hgl_chr_fifo=chr_lt;
ldbiu	r0,chr_lt
bra		pcnt+2
#	}
#	else
#	{
#	hgl_chr_fifo=0;
ldbiu	r0,0
#	}
ldwi	r7,hgl_chr_fifo
stw		[r7],r0
#	break;
bra		hgl_break2
#	}
hgl_max_endif:

// continue
#	hgl_chr_fifo=hgl_chr;
ldwi	r7,hgl_chr
ldw		r0,[r7]
ldwi	r7,hgl_chr_fifo
stw		[r7],r0
#	fgetb	fin,hgl_chr;
#	hgl_html_siz=hgl_html_siz + 1;
jalwr7	html_get_byte
ldwi	r7,hgl_chr
stw		[r7],r0

// break if over run the html size
#	if (status)
ldwi	r7,hgl_html_siz
ldw		r0,[r7]
cmpi	r0,1
bhs		hgl_siz_endif
#	{
#	hgl_chr_fifo=0;
ldwi	r7,hgl_chr_fifo
ldbiu	r0,0
stw		[r7],r0
#	break;
bra		hgl_break2
#	}
hgl_siz_endif:

// found delimiter
#	if (hgl_chr=hgl_dlm)
ldwi	r7,hgl_chr
ldw		r0,[r7]
ldwi	r7,hgl_dlm
ldw		r1,[r7]
cmp		r0,r1
bne		hgl_dlm_endif
#	{
#	if (hgl_chr=chr_lt)
cmpi	r0,chr_lt
bne		hgl_gt_else
#	{
#	hgl_chr_fifo=chr_lt;
ldwi	r7,hgl_chr_fifo
stw		[r7],r0
bra		hgl_gt_endif
#	}
#	else
#	{
hgl_gt_else:
#	chrcat	html_get_line,hgl_chr, binary;
stb		[r6],r0
addi	r6,1
#	hgl_chr_fifo=0;
ldwi	r7,hgl_chr_fifo
ldbiu	r0,0
stw		[r7],r0
#	}
hgl_gt_endif:
#	break;
bra		hgl_break2
#	}
hgl_dlm_endif:

// replace newline codes with a space
#	if (hgl_chr=chr_cr | hgl_chr=chr_lf)
ldwi	r7,hgl_chr
ldw		r0,[r7]
cmpi	r0,chr_cr
beq		hgl_nl_then
cmpi	r0,chr_lf
beq		hgl_nl_then
bra		hgl_nl_endif
#	{
hgl_nl_then:
#	hgl_chr=chr_spc;
ldbiu	r0,chr_spc
stw		[r7],r0
#	}
hgl_nl_endif:
bra		hgl_while2
#	}
hgl_break2:
#	}
// terminate string by nil
ldbiu	r0,0
stb		[r6],r0
hgl_return:
$(s)// ********************************
$(s)pushc	sr
$(s)ldcl	sr,sreg_bk_1
$(s)ldwi	r1,esp_lbuf
$(s)jalwr7	print
$(s)ldwi	r7,princhr
$(s)ldbiu	r0,chr_lf
$(s)stw		[r7],r0
$(s)popc	sr
$(s)// ********************************
rtnw

// ================================
// html get byte ; disturbed r1,r2,r7
//	return: r0=byte code
// ================================
html_get_byte:
// check html size
ldwi	r7,hgl_html_siz
ldw		r0,[r7]
cmpi	r0,0
beq		hgc_return						// EOF
cmpi	r0,1+1
bhs		hgc_endif
// end of chunk, get new chunk size
jalwr7	html_get_siz
$(d)// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
$(d)pushc	sr
$(d)ldcl	sr,sreg_bk_1
$(d)ldbiu	r1,0ac
$(d)jalwr7	print_chr
$(d)ldwi	r1,lbuf
$(d)jalwr7	print
$(d)ldbiu	r1,chr_cr
$(d)jalwr7	print_chr
$(d)ldbiu	r1,chr_lf
$(d)jalwr7	print_chr
$(d)popc	sr
$(d)// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
ldwi	r1,lbuf
jalwr7	xtoi
ldwi	r7,hgl_html_siz
stw		[r7],r0
// check end of html
cmpi	r0,0
beq		hgc_return
addi	r0,1							// chunk size must be <0xffff
stw		[r7],r0
hgc_endif:
$(s)// ********************************
$(s)ldwi	r7,sim_ptr
$(s)ldw		r0,[r7]
$(s)addi	r0,1
$(s)stw		[r7],r0
$(s)subi	r0,1
$(s)ldb		r0,[r0]
$(s)pushw	r0
$(s)// html_siz--
$(s)ldwi	r7,hgl_html_siz
$(s)ldw		r0,[r7]
$(s)subi	r0,1
$(s)stw		[r7],r0
$(s)popw	r0
$(s)bra		hgc_return
$(s)// ********************************
// polling until RAVL=1
ldwi	r7,uartctl1
ldw		r0,[r7]
andi	r0,uart_ravl
beq		pcnt-6
// get byte
ldwi	r7,hgl_html_siz
ldw		r0,[r7]
subi	r0,1
stw		[r7],r0
ldwi	r7,uartrdat1
ldw		r0,[r7]
hgc_return:
rtnw

// ================================
// html get chunk size ; disturbed r7
//	return: r0=chunk size
// ================================
html_get_siz:
pushw	r6
ldwi	r6,lbuf
hgs_loop:
$(s)// ********************************
$(s)ldwi	r7,sim_ptr
$(s)ldw		r0,[r7]
$(s)addi	r0,1
$(s)stw		[r7],r0
$(s)subi	r0,1
$(s)ldb		r0,[r0]
$(s)bra		sim_hgs_skip
$(s)// ********************************
// polling until RAVL=1
ldwi	r7,uartctl1
ldw		r0,[r7]
andi	r0,uart_ravl
beq		pcnt-6
// get byte
ldwi	r7,uartrdat1
ldw		r0,[r7]
$(s)// ********************************
$(s)sim_hgs_skip:
$(s)// ********************************
// until LF
cmpi	r0,chr_lf
beq		hgs_break
cmpi	r0,chr_cr
beq		hgs_loop
cmpi	r0,chr_spc
beq		hgs_loop
cmpi	r0,chr_tab
beq		hgs_loop
stb		[r6],r0
addi	r6,1
bra		hgs_loop
hgs_break:
ldbiu	r0,0
stb		[r6],r0
ldwi	r7,lbuf
cmp		r6,r7
beq		hgs_loop
popw	r6
rtnw


// ================================
// convert string r1, utf-8 to s-jis ; disturbed r0~r3,r7
// ================================
utf2sjis:
mov		r2,r1
u2s_loop:
// check code
ldb		r0,[r1]
addi	r1,1
mov		r3,r0
andi	r0,0xf0
cmpi	r0,0xe0
beq		u2s_utf_3
andi	r0,0xe0
cmpi	r0,0xc0
beq		u2s_utf_2
bra		u2s_utf_a

// utf-8 (2 bytes code)
u2s_utf_2:
andi	r3,0x1f
ldb		r0,[r1]
addi	r1,1
andi	r0,0x3f
lsfti	r3,6
or		r3,r0
bra		u2s_utf2sjis

// utf-8 (3 bytes code)
u2s_utf_3:
andi	r3,0x0f
ldb		r0,[r1]
addi	r1,1
andi	r0,0x3f
lsfti	r3,6
or		r3,r0
ldb		r0,[r1]
addi	r1,1
andi	r0,0x3f
lsfti	r3,6
or		r3,r0

u2s_utf2sjis:
// unicode to s-jis
ldwi	r7,unsjunic
stw		[r7],r3
ldwi	r7,unsjctl
ldw		r0,[r7]
andi	r0,unsj_bsy
bne		pcnt-6
ldwi	r7,unsjsjis
ldw		r0,[r7]
// conversion error?
mov		r0,r0
bne		pcnt+4
// ERROR: no corresponding s-jis code
ldwi	r0,0a■
// replace
mov		r3,r0
lsfti	r3,-8
andi	r0,0xff
stb		[r2],r3
addi	r2,1
stb		[r2],r0
addi	r2,1
or		r3,r0
bra		u2s_utf_endif

// ascii (7 bits code)
u2s_utf_a:
stb		[r2],r3
addi	r2,1
u2s_utf_endif:

// end of loop
mov		r3,r3
bne		u2s_loop

// terminate string by nil
ldbiu	r0,0
stb		[r2],r0
rtnw


// ================================
// rtc set sntp time ; disturbed r1~r3,r7
//	return: r0=0(no error) / 255(error)
// ================================
rtc_sntp_time:
// show status
ldwi	r7,wck_scroll
ldbiu	r1,0
stw		[r7],r1
jalwr7	ole_set_offset
ldwi	r1,lab_str_wck_sntp
ldbiu	r2,0
jalwr7	ole_kprint
ldwi	r1,lab_str_wck_clear
ldbiu	r2,1
$(s)// ********************************
$(s)bra		pcnt+6
$(s)// ********************************
jalwr7	ole_kprint
// sntp config
ldwi	r1,lab_str_atc_cipsntpcfg
ldwi	r2,lab_str_res_atc
jalwr7	esp_cast_at
// sntp time
ldwi	r1,lab_str_atc_sntptime
ldwi	r2,lab_str_res_sntp
jalwr7	esp_cast_at
$(s)// ********************************
$(s)ldbiu	r0,1
$(s)// ********************************
cmpi	r0,1
beq		rtsn_time
// ERROR:
ldiu	r0,255
bra		rtsn_return
rtsn_time:
// strcpy (lbuf,esp_lbuf)
ldwi	r1,lbuf
ldwi	r2,esp_lbuf
jalwr7	strcpy
// discard ok response
rtsn_dscd_ok:
ldwi	r1,lab_str_res_sntp
jalwr7	esp_wait_response
cmpi	r0,0
bne		rtsn_dscd_ok
// lbuf[]="+CIPSNTPTIME:www mmm dd HH:MM:SS yyyy"
// ________0123456789_123456789_123456789_123456789
ldbiu	r0,0
ldwi	r7,lbuf+16
stb		[r7],r0
ldwi	r7,lbuf+20
stb		[r7],r0

// interrupt disable
clie
// reset timer counter, clear OVFF flag
ldwi	r7,timcnt0
ldbiu	r0,0
stw		[r7],r0
ldwi	r7,timflg0
ldbiu	r0,timr_ovff|timr_ovfe
stw		[r7],r0

// yyyy
ldwi	r1,lbuf+33
jalwr7	atoi
ldwi	r7,rtc_year
stw		[r7],r0
mov		r1,r0
jalwr7	is_leap
ldwi	r7,rtc_leap
stw		[r7],r0
// mmm
ldwi	r1,lbuf+17
ldwi	r2,lab_str_rtc_month
ldbiu	r3,12+1
rtsn_loop:
pushwm	r1,r2,r3
jalwr7	strcmp
popwm	r3,r2,r1
addi	r2,4
subi	r3,1
bne		pcnt+2
ldbiu	r0,0							// ERROR: ignore, month=0
mov		r0,r0
bne		rtsn_loop
ldwi	r7,rtc_month
stw		[r7],r3
// dd
ldwi	r1,lbuf+21
jalwr7	atoi
ldwi	r7,rtc_day
stw		[r7],r0
// www
ldwi	r1,lbuf+13
ldwi	r2,lab_str_rtc_week
ldbiu	r3,0
rtsn_loop2:
pushwm	r1,r2,r3
jalwr7	strcmp
popwm	r3,r2,r1
addi	r2,4
addi	r3,1
cmpi	r3,7+1
blo		pcnt+4
ldbiu	r0,0							// ERROR: ignore
ldbiu	r3,0+1							// week=0
mov		r0,r0
bne		rtsn_loop2
subi	r3,1
ldwi	r7,rtc_week
stw		[r7],r3
// HH
ldwi	r1,lbuf+24
jalwr7	atoi
ldwi	r7,rtc_hour
stw		[r7],r0
// MM
ldwi	r1,lbuf+27
jalwr7	atoi
ldwi	r7,rtc_minute
stw		[r7],r0
// SS
ldwi	r1,lbuf+30
jalwr7	atoi
ldwi	r7,rtc_second
stw		[r7],r0

// interrupt enable
seie
// end of subroutine
ldbiu	r0,0
rtsn_return:
rtnw


// ================================
// oled set offset r1 ; disturbed r0,r1,r7
// ================================
ole_set_offset:
ldwi	r7,i2c_buf
// S [adr,w]
ldwi	r0,0x4100+(i2c_ssd1306<<1)
stw		[r7],r0
addi	r7,2
// [0x00]
ldwi	r0,0x4000+ole_reg_ctrl_c
stw		[r7],r0
addi	r7,2
// [DISP_OFST]
ldwi	r0,0x4000+ole_reg_disp_ofst
stw		[r7],r0
addi	r7,2
// [r1]
ldwi	r0,0x4000
add		r0,r1
stw		[r7],r0
addi	r7,2
// P
ldbiu	r0,0
stw		[r7],r0
addi	r7,2
// call mcvm_wire
ldwi	r1,i2c_buf
$(s)// ********************************
$(s)bra		pcnt+6
$(s)// ********************************
jalwr7	mcvm_wire
rtnw

// ================================
// oled kanji print r1 at line r2 ; disturbed r0~r3,r7
// ================================
ole_kprint:
ldbiu	r3,0
pushw	r1
cmpi	r2,ole_siz_v/16
blo		pcnt+2
ldbiu	r2,ole_siz_v/16-1
// set rect
ldwi	r7,i2c_buf
// S [adr,w]
ldwi	r0,0x4100+(i2c_ssd1306<<1)
stw		[r7],r0
addi	r7,2
// [0x00]
ldwi	r0,0x4000+ole_reg_ctrl_c
stw		[r7],r0
addi	r7,2
// [COL_ADR]
ldwi	r0,0x4000+ole_reg_col_adr
stw		[r7],r0
addi	r7,2
// [8*r3]
lsfti	r3,3
ldwi	r0,0x4000
add		r0,r3
stw		[r7],r0
addi	r7,2
// [127]
ldwi	r0,0x4000+ole_siz_h-1
stw		[r7],r0
addi	r7,2
// [PAG_ADR]
ldwi	r0,0x4000+ole_reg_pag_adr
stw		[r7],r0
addi	r7,2
// [2*r2]
ldwi	r0,0x4000
lsfti	r2,1
add		r0,r2
stw		[r7],r0
addi	r7,2
// [2*r2+1]
addi	r0,1
stw		[r7],r0
addi	r7,2
// P
ldbiu	r0,0
stw		[r7],r0
addi	r7,2
// call mcvm_wire
ldwi	r1,i2c_buf
$(s)// ********************************
$(s)bra		pcnt+6
$(s)// ********************************
jalwr7	mcvm_wire

// print
popw	r1
ole_prn_loop:
ldb		r0,[r1]
addi	r1,1
lsfti	r0,8
beq		ole_prn_break
// s-jis?
ldwi	r7,fnjpcod
stw		[r7],r0
ldwi	r7,fnjpctl
ldw		r2,[r7]
andi	r2,fnjp_sjs1
beq		pcnt+6
// yes, s-jis 2 bytes code
ldb		r2,[r1]
addi	r1,1
add		r0,r2
jalwr7	ole_kprint_chr
bra		ole_prn_loop

ole_prn_break:

ole_prn_return:
rtnw

// ================================
// oled kanji print 1 character r0 ; disturbed r0,r7
// ================================
ole_kprint_chr:
pushwm	r1,r2,r3,r4,r6
// font
ldwi	r7,fnjpcod
stw		[r7],r0
$(s)// ********************************
$(s)ldwi	r7,prinhex
$(s)stw		[r7],r0
$(s)// ********************************
// i2c frame
ldwi	r1,i2c_buf
ldwi	r0,0x4100+(i2c_ssd1306<<1)
stw		[r1],r0
addi	r1,2
ldwi	r0,0x4000+ole_reg_ctrl_d
stw		[r1],r0
addi	r1,2
// draw character
ldwi	r6,fnjpdbl
ldwi	r7,fnjpdata
ldbiu	r4,8
ole_prc_loop:
ldb		r0,[r7]
stw		[r6],r0
ldw		r0,[r6]
mov		r2,r0
andi	r0,0xff
lsfti	r2,-8
ldwi	r3,0x4000
add		r0,r3
add		r2,r3
stw		[r1],r0
addi	r1,2
stw		[r1],r2
addi	r1,2
// font width * 2 size
ldwi	r3,ole_baikaku
ldw		r3,[r3]
mov		r3,r3
beq		pcnt+8
stw		[r1],r0
addi	r1,2
stw		[r1],r2
addi	r1,2
addi	r7,1
// end of loop
subi	r4,1
bne		ole_prc_loop
// P
ldbiu	r0,0
stw		[r1],r0
// call mcvm_wire
ldwi	r1,i2c_buf
$(s)// ********************************
$(s)pushc	sr
$(s)ldcl	sr,sreg_bk_1
$(s)ldwi	r7,fnjpdata
$(s)ldwi	r6,princhr
$(s)ldbiu	r2,8
$(s)sim_ole_prc_loop2:
$(s)ldb		r0,[r7]
$(s)lsfti	r0,16-8						// 16=Mc
$(s)ldbiu	r1,8
$(s)sim_ole_prc_loop1:
$(s)lsfti	r0,1
$(s)bcc		pcnt+4
$(s)ldbiu	r3,0ax-0x20
$(s)bra		pcnt+2
$(s)ldbiu	r3,chr_spc
$(s)stw		[r6],r3
$(s)stw		[r6],r3
$(s)ldwi	r4,ole_baikaku
$(s)ldw		r4,[r4]
$(s)mov		r4,r4
$(s)beq		pcnt+4
$(s)stw		[r6],r3
$(s)stw		[r6],r3
$(s)subi	r1,1
$(s)bne		sim_ole_prc_loop1
$(s)ldbiu	r3,chr_lf
$(s)stw		[r6],r3
$(s)addi	r7,1
$(s)subi	r2,1
$(s)bne		sim_ole_prc_loop2
$(s)popc	sr
$(s)bra		ole_prc_return
$(s)// ********************************
jalwr7	mcvm_wire

ole_prc_return:
popwm	r6,r4,r3,r2,r1
rtnw

// ================================
// oled display (ssd1306) initialize
// ================================
ole_init:
// call mcvm_wire
ldwi	r1,lab_ole_init_reg
jalwr7	mcvm_wire
rtnw

// oled display (ssd1306) initialization i2c frame
ole_init_reg:
// [adr,w] [0x00]
datw	0x4100+(i2c_ssd1306<<1)
datw	0x4000+ole_reg_ctrl_c
// set mux ratio (0xa8, 0x3f)
datw	0x4000+ole_reg_mux_rat
datw	0x4000+0x3f
// set display offset (0xd3,0x00)
datw	0x4000+ole_reg_disp_ofst
datw	0x4000+0x00
// set display start line (0x40)
datw	0x4000+ole_reg_disp_lin+0x00
// set segment re-map (0xa0 / 0x0a1)
datw	0x4000+ole_reg_seg_remap
$(r)datw	0x4000+ole_reg_seg_remap+0x01
// set com output scan direction (0xc0 / 0xc8)
datw	0x4000+ole_reg_scan_dir
$(r)datw	0x4000+ole_reg_scan_dir+0x08
// set com pins hardware configuration (0xda,0x02)
datw	0x4000+ole_reg_com_cnfg
datw	0x4000+0x02
$(r)datw	0x4000+ole_reg_com_cnfg
$(r)datw	0x4000+0x22
// set contrast control (0x81,0x7f)
datw	0x4000+ole_reg_cont_ctrl
datw	0x4000+0x7f
// disable entire display on (0xa4)
datw	0x4000+ole_reg_ent_disp
// set normal display (0xa6)
datw	0x4000+ole_reg_nor_disp
// set osc frequency (0xd5,0x80)
datw	0x4000+ole_reg_clk_div
datw	0x4000+0x80
// enable charge pump regulator (0x8d,0x14)
datw	0x4000+ole_reg_chg_pump
datw	0x4000+0x14
// display on (0xaf)
datw	0x4000+ole_reg_disp_on
// vertical addressing mode
datw	0x4000+ole_reg_madr_mod
datw	0x4000+0x01
// P
datw	0x0000


// ================================
// esp32 access routines
// ================================
// ================================
// esp32 pass through command
// ================================
esp_passthru:
ldwi	r1,lab_str_msg_path_ent
jalwr7	print_lst
// initialize
ldwi	r7,path_ptr
ldbiu	r0,0
stw		[r7],r0
wpt_loop:
// handling uart#0 (serial monitor)
// check RAVL0
ldwi	r7,uartctl
ldw		r0,[r7]
andi	r0,uart_ravl
beq		wpt0_not_ravl
// receive a byte
ldwi	r7,uartrdat
ldw		r0,[r7]
ldwi	r7,path_ptr
ldw		r1,[r7]
ldwi	r7,lbuf
add		r7,r1
stb		[r7],r0
// update path_ptr
ldwi	r2,max_lbuf-2					// -2:=CR+LF
addi	r1,1
cmp		r1,r2
blo		pcnt+2
subi	r1,1
ldwi	r7,path_ptr
stw		[r7],r1
// check lf code
cmpi	r0,chr_lf
bne		wpt0_not_lf
// lbuf termination
ldwi	r7,lbuf
add		r7,r1
subi	r1,1
ldb		r0,[r7]
addi	r1,1
cmpi	r0,chr_cr
beq		pcnt+6
ldbiu	r0,chr_cr
stb		[r7],r0
addi	r7,1
ldbiu	r0,chr_lf
stb		[r7],r0
addi	r7,1
ldbiu	r0,0
stb		[r7],r0

// check "+++"
ldwi	r1,lbuf
ldwi	r2,lab_str_cmd_exit_send
jalwr7	strfcmp
mov		r0,r0
bne		wpt0_not_pls
// "+++"
ldwi	r7,lbuf+3
ldbiu	r0,0
stb		[r7],r0
// message
ldwi	r1,lab_str_msg_path_snd
jalwr7	print
wpt0_not_pls:

// check exit command "---"
ldwi	r1,lbuf
ldwi	r2,lab_str_cmd_exit_path
jalwr7	strfcmp
mov		r0,r0
bne		wpt0_not_exit
// "---"
bra		wpt_break

wpt0_not_exit:
// send data to esp32
ldwi	r1,lbuf
jalwr7	esp_print
// reset path_ptr
ldwi	r7,path_ptr
ldbiu	r0,0
stw		[r7],r0
wpt0_not_lf:
wpt0_not_ravl:

// handling uart#1 (esp32 communication)
// check TFUL0
ldwi	r7,uartctl
ldw		r0,[r7]
andi	r0,uart_tful
bne		wpt1_not_ravl
// check RAVL1
ldwi	r7,uartctl1
ldw		r0,[r7]
andi	r0,uart_ravl
beq		wpt1_not_ravl
// receive a byte
ldwi	r7,uartrdat1
ldw		r0,[r7]
// redirect data to uart#0
ldwi	r7,uarttdat
stw		[r7],r0
wpt1_not_ravl:

// end of loop
bra		wpt_loop
wpt_break:

rtnw

// ================================
// esp32 cast at-command and get response ; disturbed r1~r3,r5~r7
//	parameter: r1=at_cmnd, r2=response list
//	return: r0=response number (0~)
// ================================
esp_cast_at:
// send at-command
pushw	r2
jalwr7	esp_print
popw	r1
jalwr7	esp_wait_response
rtnw

// ================================
// esp32 wait response ; disturbed r1~r3,r5~r7
//	parameter: r1=response list
//	return: r0=response number (0~)
// ================================
esp_wait_response:
$(s)// ********************************
$(s)ldbiu	r0,0
$(s)rtnw
$(s)// ********************************
pushw	r1
ewr_loop:
popw	r3
pushw	r3
ldbiu	r0,0
ldwi	r7,esp_ewr_idx
stw		[r7],r0
pushw	r3
jalwr7	esp_get_line
popw	r3
ewr_loop2:
ldwi	r1,esp_lbuf
mov		r2,r3
pushw	r3
jalwr7	strfcmp
popw	r3
mov		r0,r0
beq		ewr_match
// next string in the list
// idx++
ldwi	r7,esp_ewr_idx
ldw		r0,[r7]
addi	r0,1
stw		[r7],r0
// search next string
ldb		r0,[r3]
addi	r3,1
mov		r0,r0
bne		pcnt-8
ldb		r0,[r3]
mov		r0,r0
bne		ewr_loop2
// not match
bra		ewr_loop

ewr_match:
popw	r0
ldwi	r7,esp_ewr_idx
ldw		r0,[r7]
rtnw

// ================================
// esp32 get line from uart ; disturbed r0,r5~r7
// ================================
esp_get_line:
ldwi	r7,uartrdat1
ldwi	r6,uartctl1
ldwi	r5,esp_lbuf
egl_loop:
$(s)// ********************************
$(s)ldwi	r7,sim_ptr
$(s)ldw		r0,[r7]
$(s)addi	r0,1
$(s)stw		[r7],r0
$(s)subi	r0,1
$(s)ldb		r0,[r0]
$(s)bra		sim_egl_skip1
$(s)// ********************************
// polling until RAVL=1
ldw		r0,[r6]
andi	r0,uart_ravl
beq		egl_loop
// get byte
ldw		r0,[r7]
$(s)// ********************************
$(s)sim_egl_skip1:
$(s)// ********************************
stb		[r5],r0
addi	r5,1
// LF code check
cmpi	r0,chr_lf
beq		egl_got
// size check
ldwi	r0,esp_lbuf+max_lbuf-1
cmp		r5,r0
blo		egl_loop
// string too long, discard until receiving a LF
egl_discard:
$(s)// ********************************
$(s)ldwi	r7,sim_ptr
$(s)ldw		r0,[r7]
$(s)addi	r0,1
$(s)stw		[r7],r0
$(s)subi	r0,1
$(s)ldb		r0,[r0]
$(s)bra		sim_egl_skip2
$(s)// ********************************
// polling until RAVL=1
ldw		r0,[r6]
andi	r0,uart_ravl
beq		egl_loop
// discard byte
ldw		r0,[r7]
$(s)// ********************************
$(s)sim_egl_skip2:
$(s)// ********************************
// LF code check
cmpi	r0,chr_lf
bne		egl_discard
// got line
egl_got:
// string terminate
ldbiu	r0,0
subi	r5,1
stb		[r5],r0
// check CR code
subi	r5,1
ldb		r0,[r5]
cmpi	r0,chr_cr
bne		egl_notcr
ldbiu	r0,0
stb		[r5],r0
egl_notcr:
$(d)// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
$(d)// print esp_lbuf
$(d)pushc	sr
$(d)ldcl	sr,sreg_bk_1
$(d)ldwi	r1,lab_str_msg_esp_rdir
$(d)jalwr7	print
$(d)pushw	r1
$(d)ldwi	r1,esp_lbuf
$(d)jalwr7	print
$(d)popw	r1
$(d)jalwr7	print
$(d)popc	sr
$(d)// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
rtnw

// ================================
// esp32 print r1 ; disturbed r0~r2,r6,r7
// ================================
esp_print:
$(s)// ********************************
$(s)jalwr7	print
$(s)rtnw
$(s)// ********************************
$(d)// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
$(d)// print to uart#0 (serial monitor)
$(d)pushc	sr
$(d)pushw	r1
$(d)ldcl	sr,sreg_bk_1
$(d)popw	r1
$(d)jalwr7	print
$(d)popc	sr
$(d)// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
ldwi	r7,uarttdat1
ldwi	r6,uartctl1
epr_loop:
// get 1 byte
ldb		r2,[r1]
addi	r1,1
mov		r2,r2
beq		epr_finish
// polling uartctl1.TFUL=0
epr_poll:
ldw		r0,[r6]
andi	r0,uart_tful
bne		epr_poll
// send data
stw		[r7],r2
bra		epr_loop
epr_finish:
rtnw


// ================================
// get line from uart ; disturbed r0,r5~r7
// ================================
get_line:
ldwi	r7,uartrdat
ldwi	r6,uartctl
ldwi	r5,lbuf
gl_loop:
// polling until RAVL=1
ldw		r0,[r6]
andi	r0,uart_ravl
beq		gl_loop
// get byte
ldw		r0,[r7]
stb		[r5],r0
addi	r5,1
// LF code check
cmpi	r0,chr_lf
beq		gl_got
// size check
ldwi	r0,lbuf+max_lbuf-1
cmp		r5,r0
blo		gl_loop
// got line
gl_got:
// string terminate
ldbiu	r0,0
subi	r5,1
stb		[r5],r0
// check CR code
subi	r5,1
ldb		r0,[r5]
cmpi	r0,chr_cr
bne		gl_notcr
ldbiu	r0,0
stb		[r5],r0
gl_notcr:
rtnw

// ================================
// print r1 ; disturbed r0~r2,r6,r7
// ================================
print:
ldwi	r7,uarttdat
ldwi	r6,uartctl
pr_loop:
// get 1 byte
ldb		r2,[r1]
addi	r1,1
mov		r2,r2
beq		pr_finish
$(s)// ********************************
$(s)ldwi	r7,princhr
$(s)stw		[r7],r2
$(s)bra		pr_loop
$(s)// ********************************
// polling uartctl.TFUL=0
pr_poll:
ldw		r0,[r6]
andi	r0,uart_tful
bne		pr_poll
// send data
stw		[r7],r2
bra		pr_loop
pr_finish:
rtnw

// ================================
// print_lst r1 ; disturbed r0~r2,r6,r7
// ================================
print_lst:
jalwr7	print
ldb		r0,[r1]
mov		r0,r0
bne		print_lst
rtnw

// ================================
// print_chr r1 ; disturbed r0,r7
// ================================
print_chr:
$(s)// ********************************
$(s)ldwi	r7,princhr
$(s)stw		[r7],r1
$(s)rtnw
$(s)// ********************************
// polling uartctl.TFUL=0
ldwi	r7,uartctl
pc_poll:
ldw		r0,[r7]
andi	r0,uart_tful
bne		pc_poll
// send data
ldwi	r7,uarttdat
stw		[r7],r1
rtnw

// ================================
// print decimal2 r1 ; disturbed r0~r4,r6,r7
// ================================
print_dec2:
mov		r1,r1
bne		pdc2_not_0
// 00
ldbiu	r1,0a0
jalwr7	print_chr
ldbiu	r1,0a0
jalwr7	print_chr
bra		pdc2_fin

pdc2_not_0:
// for each r0=10, 1
ldwi	r6,lab_pdc2_tab
ldbiu	r3,false						// omit leading zero flag
pdc2_loop:
ldw		r0,[r6]
mov		r0,r0
beq		pdc2_fin
// r2=r1/r0
ldbiu	r2,0
pdc2_div:
sub		r1,r0
blo		pcnt+4
addi	r2,1
bra		pdc2_div

// omit leading zero
mov		r3,r3
beq		pcnt+4
mov		r2,r2
beq		pdc2_omit
// print 1 digit
addi	r2,0a0
pushwm	r0,r1,r7
mov		r1,r2
jalwr7	print_chr
popwm	r7,r1,r0
ldbiu	r3,false
pdc2_omit:
// add back r1; loop
add		r1,r0
addi	r6,2
bra		pdc2_loop

pdc2_fin:
rtnw

pdc2_tab:
datw	10
datw	1
datw	0

// ================================
// print decimal r1 ; disturbed r0~r4,r6,r7
// ================================
print_dec:
#$(s)// ********************************
#$(s)ldwi	r7,prindec
#$(s)stw		[r7],r1
#$(s)rtnw
#$(s)// ********************************
mov		r1,r1
bne		pdc_not_0
// 0
ldbiu	r1,0a0
jalwr7	print_chr
bra		pdc_fin

pdc_not_0:
// for each r0=10000, ~, 10, 1
ldwi	r6,lab_pdc_tab
ldbiu	r3,true							// omit leading zero flag
pdc_loop:
ldw		r0,[r6]
mov		r0,r0
beq		pdc_fin
// r2=r1/r0
ldbiu	r2,0
pdc_div:
sub		r1,r0
blo		pcnt+4
addi	r2,1
bra		pdc_div

// omit leading zero
mov		r3,r3
beq		pcnt+4
mov		r2,r2
beq		pdc_omit
// print 1 digit
addi	r2,0a0
pushwm	r0,r1,r7
mov		r1,r2
jalwr7	print_chr
popwm	r7,r1,r0
ldbiu	r3,false
pdc_omit:
// add back r1; loop
add		r1,r0
addi	r6,2
bra		pdc_loop

pdc_fin:
rtnw

pdc_tab:
datw	10000
datw	1000
datw	100
datw	10
datw	1
datw	0

// ================================
// string compare: r0=strcmp (r1,r2) ; disturbed r1~r4
// ================================
strcmp:
ldb		r3,[r1]
addi	r1,1
ldb		r4,[r2]
addi	r2,1
mov		r0,r3
sub		r0,r4
bne		sc_finish
// check nil code
mov		r3,r3
beq		sc_finish
mov		r4,r4
bne		strcmp
sc_finish:
rtnw

// ================================
// string n compare: r0=strncmp (r1,r2,r5) ; disturbed r1~r5
// ================================
strncmp:
ldb		r3,[r1]
addi	r1,1
ldb		r4,[r2]
addi	r2,1
mov		r0,r3
sub		r0,r4
bne		snc_finish
// check n character
subi	r5,1
beq		snc_finish
// check nil code
mov		r3,r3
beq		snc_finish
mov		r4,r4
bne		strncmp
snc_finish:
rtnw

// ================================
// string forward match compare: r0=strfcmp (r1,r2) ; disturbed r1~r3
//	if left(r1,strlen(r2)) equal to r2 then match
//	if strlen(r1)<strlen(r2) then always mismatch
// ================================
strfcmp:
ldbiu	r0,0
sfc_loop:
ldb		r3,[r2]
addi	r2,1
mov		r3,r3
beq		sfc_return
ldb		r0,[r1]
addi	r1,1
sub		r0,r3
beq		sfc_loop
sfc_return:
rtnw

// ================================
// ascii to integer: r0=atoi (r1)>=0 ; disturbed r1~r3
// ================================
atoi:
ldbiu	r0,0
// r2=[r1]-'0'
ldb		r2,[r1]
subi	r2,0a0
blo		a2i_finish
cmpi	r2,10
bhs		a2i_finish
// r0=10*r0+r2
mov		r3,r0
lsfti	r3,3
add		r0,r0
add		r0,r3
add		r0,r2
// loop
addi	r1,1
bra		atoi+2
a2i_finish:
rtnw

// ================================
// hexadecimal to integer: r0=xtoi (r1) ; disturbed r1,r2
// ================================
xtoi:
ldbiu	r0,0
// r2=[r1]-'0'
ldb		r2,[r1]
subi	r2,0a0
blo		x2i_finish						// [r1]<'0'
cmpi	r2,10
blo		x2i_next						// [r1]<='9'
subi	r2,(0aA-0x20)-0a0-10
blo		x2i_finish						// [r1]<'A'
cmpi	r2,16
blo		x2i_next						// [r1]<='F'
subi	r2,0aa-(0aA-0x20)
blo		x2i_finish						// [r1]<'a'
cmpi	r2,16
bhs		x2i_finish						// [r1]>'f'
x2i_next:
// r0=16*r0+r2
lsfti	r0,4
add		r0,r2
// loop
addi	r1,1
bra		xtoi+2
x2i_finish:
rtnw

// ================================
// string copy: strcpy (r1,r2) ; disturbed r0~r2
//	return: r1 pointed to '\0' position
//			r2 pointed to '\0'+1 position
// ================================
strcpy:
ldb		r0,[r2]
addi	r2,1
stb		[r1],r0
addi	r1,1
mov		r0,r0
bne		strcpy
subi	r1,1
rtnw

// ================================
// string copy decimal r2 to r1 ; disturbed r0,r2~r4,r6,r7
//	'\0' is copied after copying decimal
//	return: r1=pointer to the last '\0'
// ================================
strcpy_dec:
mov		r2,r2
bne		cpd_not_0
// 0
ldbiu	r2,0a0
stb		[r1],r2
addi	r1,1
ldbiu	r0,0
bra		cpd_fin

cpd_not_0:
// for each r0=10000, ~, 10, 1
ldwi	r6,lab_cpd_tab
ldbiu	r3,true							// omit leading zero flag
cpd_loop:
ldw		r0,[r6]
mov		r0,r0
beq		cpd_fin
// r4=r2/r0
ldbiu	r4,0
cpd_div:
sub		r2,r0
blo		pcnt+4
addi	r4,1
bra		cpd_div

// omit leading zero
mov		r3,r3
beq		pcnt+4
mov		r4,r4
beq		cpd_omit
// copy 1 digit
addi	r4,0a0
stb		[r1],r4
addi	r1,1
ldbiu	r3,false
cpd_omit:
// add back r2; loop
add		r2,r0
addi	r6,2
bra		cpd_loop

cpd_fin:
stb		[r1],r0
rtnw

cpd_tab:
datw	10000
datw	1000
datw	100
datw	10
datw	1
datw	0

// ================================
// string copy decimal2 r2 to r1 ; disturbed r0,r2~r4,r6,r7
//	'\0' is copied after copying decimal
//	return: r1=pointer to the last '\0'
// ================================
strcpy_dec2:
mov		r2,r2
bne		cpd2_not_0
// 00
ldbiu	r2,0a0
stb		[r1],r2
addi	r1,1
stb		[r1],r2
addi	r1,1
ldbiu	r0,0
bra		cpd2_fin

cpd2_not_0:
// for each r0=10, 1
ldwi	r6,lab_cpd2_tab
ldbiu	r3,false						// omit leading zero flag
cpd2_loop:
ldw		r0,[r6]
mov		r0,r0
beq		cpd2_fin
// r4=r2/r0
ldbiu	r4,0
cpd2_div:
sub		r2,r0
blo		pcnt+4
addi	r4,1
bra		cpd2_div

// omit leading zero
mov		r3,r3
beq		pcnt+4
mov		r4,r4
beq		cpd2_omit
// copy 1 digit
addi	r4,0a0
stb		[r1],r4
addi	r1,1
ldbiu	r3,false
cpd2_omit:
// add back r2; loop
add		r2,r0
addi	r6,2
bra		cpd2_loop

cpd2_fin:
stb		[r1],r0
rtnw

cpd2_tab:
datw	10
datw	1
datw	0

// ================================
// string search: r0=strstr (r1,r2) ; disturbed r3,r4
//	search string r2 in string r1, and returns position r0(=1~)
//	if string r2 not found, returns r0=0
// ================================
strstr:
pushwm	r1,r2
ldbiu	r0,0
sst_loop:
ldb		r3,[r1]
addi	r1,1
ldb		r4,[r2]
addi	r2,1
mov		r4,r4
beq		sst_return
// compare
cmp		r3,r4
bne		sst_cmp_else

// match
mov		r0,r0
bne		pcnt+2
mov		r0,r1
bra		sst_cmp_endif

// not match
sst_cmp_else:
ldbiu	r0,0
popw	r2
pushw	r2
sst_cmp_endif:

// end of loop
mov		r3,r3
beq		sst_return
bra		sst_loop

sst_return:
popwm	r2,r1
mov		r0,r0
beq		pcnt+2
sub		r0,r1
rtnw

// ================================
// string truncate r1 to length r2(>0) ; disturbed r0,r2,r7
//	need fontjp unit to check s-jis code
//	return: r1=pointer to the last '\0'
// ================================
strtrunc:
subi	r2,1
bpl		trc_endif
ldbiu	r0,0
stb		[r1],r0
addi	r1,1
bra		trc_break
trc_endif:
ldb		r0,[r1]
addi	r1,1
// nil?
mov		r0,r0
beq		trc_break
# delete from here, if you do not need s-jis string
// s-jis?
lsfti	r0,8
ldwi	r7,fnjpcod
stw		[r7],r0
ldwi	r7,fnjpctl
ldw		r0,[r7]
andi	r0,fnjp_sjs1
beq		pcnt+2
addi	r1,1
# delete to here
bra		strtrunc
trc_break:
subi	r1,1
rtnw

// ================================
// delay r1 [ms] ; disturbed r0,r7,sytmctl[MLOE]
// ================================
delay:
$(s)// ********************************
$(s)ldbiu	r1,3
$(s)// ********************************
// sytmmil: set offset
ldwi	r7,sytmctl
ldw		r0,[r7]
andi	r0,~sytm_mloe
stw		[r7],r0
ori		r0,sytm_mloe
stw		[r7],r0
// wait r1 [ms]
ldwi	r7,sytmmill
dly_loop:
ldw		r0,[r7]
cmp		r0,r1
blo		dly_loop
rtnw


// ================================
// c string data
// ================================
str_msg_who:
dats	"OK: $(prog_name) ver.$(prog_vers)\r\n\0"
str_msg_rdy:
dats	"RDY\r\n\0"
str_msg_help:
dats	"OK+ sntp\r\n"
dats	"OK+ getw\r\n"
dats	"OK+ path\r\n"
dats	"OK+ who\r\n"
dats	"OK: help\r\n\0\0"
str_msg_getw:
dats	"OK: getw (\0),(\0),\0,\0,\0\r\n\0"
str_msg_sntp:
dats	"OK: sntp \0年\0月\0日(\0) \0:\0:\0\r\n\0"
str_msg_path_ent:
dats	"OK+ enter ESP32 pass through mode\r\n"
dats	"OK+ ---<return> to exit pass through mode\r\n\0\0"
str_msg_path_snd:
dats	"OK: exit AT+CIPSEND\r\n\0"
str_msg_path:
dats	"OK: exit ESP32 pass through mode\r\n\0"
str_msg_esp_init:
dats	"OK+ ESP32 init...\r\n\0"
str_msg_esp_init_done:
dats	"OK: ESP32 init done.\r\n\0"
str_msg_esp_rdir:
dats	"ESP32: \0\r\n\0"
str_err_unspt:
dats	"ERR: unsupported command: \0\r\n\0"
str_err_syntx:
dats	"ERR: syntax\r\n\0"
str_err_nouar1:
dats	"ERR: no UART#1 unit found, halted.\r\n\0"
str_err_nostws:
dats	"ERR: no STWSER unit found, halted.\r\n\0"
str_err_nofnjp:
dats	"ERR: no FONTJP unit found, halted.\r\n\0"
str_err_nounsj:
dats	"ERR: no UNISJI unit found, halted.\r\n\0"
str_err_oled:
dats	"ERR: could not init. OLED display, ignore.\r\n\0"
str_err_esp_init:
dats	"ERR: ESP32 init failed\r\n\0"
str_err_esp_start:
dats	"ERR: could not connect server\r\n\0"
str_err_esp_path:
dats	"ERR: could not enter pass through mode\r\n\0"
str_err_gwi_head:
dats	"ERR: illegal http response header\r\n\0"
str_err_gwi_getw:
dats	"ERR: getw failed. (\0)\r\n\0"
str_cmd_sntp:
dats	"sntp\0"
str_cmd_getw:
dats	"getw\0"
str_cmd_path:
dats	"path\0"
str_cmd_exit_send:
dats	"+++\0"
str_cmd_exit_path:
dats	"---\0"
str_cmd_who:
dats	"who\0"
str_cmd_help:
dats	"help\0"
str_wck_clear:
dats	"                                \0"	// 32 spaces
str_wck_time:
dats	"\0:\0:\0"
str_wck_date:
dats	"\0年\0月\0日(\0)\0"
str_wck_temp:
dats	"\0℃\0%降水量\0mm\0"
str_wck_sntp:
dats	"SNTP時刻合わせ中……    \0"
str_wck_weather:
dats	"気象情報取得中……       \0"
str_wck_prep2:
dats	"天気予報：           \0"
str_wck_prep3:
dats	"◆未取得◆ no data ◆ \0"

// ================================
// rtc
str_rtc_month:
dats	"Dec\0"
dats	"Nov\0"
dats	"Oct\0"
dats	"Sep\0"
dats	"Aug\0"
dats	"Jul\0"
dats	"Jun\0"
dats	"May\0"
dats	"Apr\0"
dats	"Mar\0"
dats	"Feb\0"
dats	"Jan\0"
str_rtc_week:
dats	"Mon\0"
dats	"Tue\0"
dats	"Wed\0"
dats	"Thu\0"
dats	"Fri\0"
dats	"Sat\0"
dats	"Sun\0"
str_rtc_week_jp:
dats	"月\0"
dats	"火\0"
dats	"水\0"
dats	"木\0"
dats	"金\0"
dats	"土\0"
dats	"日\0"

// ================================
// at-command
str_atc_rst:
dats	"AT+RST\r\n\0"
str_atc_gmr:
dats	"AT+GMR\r\n\0"
str_atc_uart_cur:
dats	"AT+UART_CUR=115200,8,1,0,2\r\n\0"
str_atc_cipsntpcfg:
dats	"AT+CIPSNTPCFG=1,9\r\n\0"
str_atc_cipmux:
dats	"AT+CIPMUX=0\r\n\0"
str_atc_cipstaq:
dats	"AT+CIPSTA?\r\n\0"
str_atc_sntpcfg:
dats	"AT+CIPSNTPCFG=1,9\r\n\0"
str_atc_sntptime:
dats	"AT+CIPSNTPTIME?\r\n\0"
str_atc_cipstart:
dats	"AT+CIPSTART=\"$(esp_ctyp)\",\"$(esp_serv)\",$(esp_port)\r\n\0"
str_atc_cipmode:
dats	"AT+CIPMODE=1\r\n\0"
str_atc_cipsend:
dats	"AT+CIPSEND\r\n\0"
str_atc_cipclose:
dats	"AT+CIPCLOSE\r\n\0"

// ================================
// at-command response list
str_res_rst:
dats	"WIFI GOT IP\0\0"
str_res_atc:
dats	"OK\0ERROR\0\0"
str_res_sntp:
dats	"OK\0+CIPSNTPTIME:\0\0"
str_res_start:
dats	"OK\0ERROR\0CONNECT\0CLOSE\0\0"

// ================================
// http command
str_http_get:
dats	"GET $(esp_http)$(esp_serv)$(esp_path) HTTP/1.1\r\n\r\n\0"
str_http_res_head:
dats	"HTTP/1.1 2\0"
str_http_tranenc:
dats	"Transfer-Encoding: chunked\0

// ================================
// html analyze
str_html_tag_title:
dats	"<title>\0"
str_html_tag_tbody:
dats	"<tbody>\0"
str_html_tag_td:
dats	"<td\0"
str_html_jikoku:						// utf-8 code of "時刻"
datb	0xe6,0x99,0x82, 0xe5,0x88,0xbb, 0x00
str_html_notenki:
dats	"の天気\0"

# ================================
incl	"mcvm_lib_wire_m.incl"

#6$(s)romsiz	16*1024
#6$(s)# ================================
#6$(s)sim_html_dat:
#6$(s)incl	"weather_clock_datb.incl"

