// ================================
// RAM marching test for Nihonium (NH=1)
//		(c) 2023	1YEN Toru
//
//
//		2023/12/16	ver.1.02
//			add: byte and word marching
//				"marchb" and "marchw" command, "marchl" command also
//
//		2023/11/18	ver.1.00
//
// ================================
asm		"mcoc_irom.mem"
#asm		"mcoc_irom.dat2",bit16,list
incl	"mcoc115.incl"
# ================================
# string macros
def		prog_name,"test_march_nh"
def		prog_vers,"1.02"
def		s,"#"							// simulation="" / real fpga="#"
# constants
equ		max_lbuf,64						// size of lbuf
equ		baud,9600						// baud rate
equ		uart_baud,fcpu/baud-1			// uartbaud setting
equ		chr_lf,0x0a						// lf code
equ		chr_cr,0x0d						// cr code
equ		chr_cma,0x2c					// comma ',' code
equ		chr_mns,0x2d					// minus '-' code
equ		mrch_byte0,0x00					// mrch: byte data
equ		mrch_byte1,0xff
equ		mrch_word0,0x0000				// mrch: word data
equ		mrch_word1,0xffff
equ		mrch_long0,0x0000_0000			// mrch: long data
equ		mrch_long1,0xffff_ffff
# variables
equ		va,ramtop
equ		mrch_time,va					// marching test time [us]
equ		va,va+4
equ		mrch_start,va					// marching start address
equ		mrch_err_adr,va					// marching error address
equ		va,va+4
equ		mrch_end,va						// marching end address
equ		mrch_err_dat,va					// marching error data
equ		va,va+4
equ		mrch_step,va					// marching address step
equ		va,va+2
equ		mrch_err,va						// marching error flag
equ		va,va+2
equ		static_va,va
# array variables
equ		lbuf,va							// receive data buffer
equ		va,va+max_lbuf
equ		array_va,va
# ================================


// ================================
// setup
// ================================

// ================================		// general 8 bit Tennessine codes
// 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

// check cpu core
ldch	sr,(sreg_nh)>>8
movfc	r0,sr
ldch	sr,0x00
cendw	r0
andi	r0,(sreg_nh)>>8
bne		target_cpu_ok
// ERROR: not target CPU=Nihonium, halt
ldc		sp,iome_botm
ldbiu	r1,chr_mns
jalwr7	print_chr
$(s)// ********************************
$(s)ldwi	r0,simfail
$(s)ldwi	r7,simfnsh
$(s)stw		[r7],r0
$(s)// ********************************
pause
// ================================		// target cpu codes from here
target_cpu_ok:


// stop if cpu2 for dual core cpu edition
movfc	r0,sr
lsri	r0,sreg_b_id0
andi	r0,sreg_id_2>>sreg_b_id0
beq		pcnt+2
pause

// set sp to iomem16 unit
ldc		sp,iome_botm

// 32 bit mode
sesr	sreg_b_nh

// 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

// port setting
ldbiu	r0,led_builtin_r|led_builtin_g|led_builtin_b
ldwi	r7,porset
stw		[r7],r0
ldwi	r7,pordir
ldw		r0,[r7]
andi	r0,~(led_builtin_r|led_builtin_g|led_builtin_b)
stw		[r7],r0

// send RDY
ldwi	r1,lab_str_msg_rdy
jalwr7	print

$(s)// ********************************
$(s)// for simulation
#0$(s)// cancel time out
#0$(s)ldwi	r7,simctrl
#0$(s)ldbiu	r0,simc_noto
#0$(s)stw		[r7],r0
$(s)// command test
$(s)ldwi	r6,lab_sim_str_cmnd
$(s)sim_cmnd_loop2:
$(s)ldwi	r7,lbuf
$(s)sim_cmnd_loop:
$(s)ldb		r0,[r6]
$(s)addi	r6,1
$(s)stb		[r7],r0
$(s)addi	r7,1
$(s)cmpi	r0,0
$(s)bne		sim_cmnd_loop
$(s)pushw	r6
$(s)jalwr7	sim_cmnd
$(s)// skip nil, check end mark (*)
$(s)popw	r6
$(s)sim_loop_1:
$(s)ldb		r0,[r6]
$(s)addi	r6,1
$(s)cmpi	r0,0
$(s)beq		sim_loop_1
$(s)subi	r6,1
$(s)cmpi	r0,0x2a						// asterisk(*)
$(s)bne		sim_cmnd_loop2
$(s)bra		sim_cmnd_end
$(s)sim_str_cmnd:
$(s)dats	"march,100000,100020,0\0"	// SRAM: caused error
$(s)dats	"marchl,100000,100020\0"	// SRAM: 32B
$(s)dats	"marchw,100000,100010\0"	// SRAM: 16B
$(s)dats	"marchb,100000,100008\0"	// SRAM: 8B
$(s)dats	"march,100000,180000,2000\0"	// SRAM: 512KB
$(s)dats	"who\0"
$(s)dats	"help\0"
$(s)dats	"*"							// end mark
$(s)dats	"march,080000,0a0000,0800\0"	// ERAM: 128KB
$(s)dats	"march,080000,080020\0"		// ERAM: 64B
$(s)dats	"march,080000,090000,0400\0"	// ERAM: 64KB
$(s)dats	"march,80000,800c0,6\0"		// ERAM: even/odd word address mix
$(s)dats	"march,88000,a8000,4000\0"	// ERAM: caused error
$(s)dats	"*"							// end mark
$(s)sim_cmnd_end:
$(s)ldbiu	r0,0
$(s)// simulation finish
$(s)cmpi	r0,0
$(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 "march" command
ldwi	r1,lbuf
ldwi	r2,lab_str_cmd_march
ldbiu	r5,5
jalwr7	strncmp
cmpi	r0,0
beq		march
bne		march_notid
// ================================
// march[bwl],<start_hex6>,<end_hex6>[,<step_hex4>]
march:
ldwi	r1,lbuf+5
// access size
ldb		r0,[r1]
cmpi	r0,chr_cma
bne		pcnt+4
ldbiu	r0,6*2
bra		mrch_endif
cmpi	r0,0ab
bne		mrch_else_b
	// byte size
	ldbiu	r0,6*0
	addi	r1,1
	bra		mrch_endif
mrch_else_b:
cmpi	r0,0aw
bne		mrch_else_w
	// word size
	ldbiu	r0,6*1
	addi	r1,1
	bra		mrch_endif
mrch_else_w:
cmpi	r0,0al
bne		mrch_else_l
	// long word size
	ldbiu	r0,6*2
	addi	r1,1
	bra		mrch_endif
mrch_else_l:
	// ERROR:
	bra		march_notid
mrch_endif:
pushw	r0
// check ','
ldb		r0,[r1]
cmpi	r0,chr_cma
bne		err_syntx
addi	r1,1
// <start_hex6>
jalwr7	xtoi
ldwi	r7,mrch_start
stl		[r7],r0
mov		r4,r0
// check ','
ldb		r0,[r1]
cmpi	r0,chr_cma
bne		err_syntx
addi	r1,1
// <end_hex6>
jalwr7	xtoi
ldwi	r7,mrch_end
stl		[r7],r0
mov		r5,r0
// check ','
ldb		r0,[r1]
cmpi	r0,chr_cma
block	ne
	// default
	ldbiu	r0,0
	ldwsp	r0,[r0]
	ldwi	r7,lab_mrch_table+4
	add		r7,r0
	ldw		r0,[r7]
elsb
	// <step_hex4>
	addi	r1,1
	jalwr7	xtoi
	cmpi	r0,0
	beq		err_syntx
endb
ldwi	r7,mrch_step
stw		[r7],r0
mov		r6,r0

// led=yellow
ldbiu	r0,(~(led_builtin_r|led_builtin_g))&led_builtin
ldwi	r7,porout
stw		[r7],r0
// start test
ldwi	r7,sytmctl
ldbiu	r0,sytm_mcoe
stw		[r7],r0
// marching test
ldbiu	r0,0
ldwsp	r0,[r0]
ldwi	r7,lab_mrch_table
add		r7,r0
ldw		r7,[r7]
jalw	r7
// store results
ldwi	r7,mrch_err
stw		[r7],r0
ldwi	r7,mrch_err_adr
stl		[r7],r4
ldwi	r7,mrch_err_dat
stl		[r7],r5
ldwi	r7,mrch_step
stw		[r7],r6
// end test
ldwi	r7,sytmmcrh
ldl		r1,[r7]
ldwi	r7,mrch_time
stl		[r7],r1
ldwi	r7,sytmctl
ldbiu	r1,0
stw		[r7],r1

// response
cmpi	r0,0
beq		march_ok
// ERROR:
pushw	r0
ldwi	r1,lab_str_err_march
jalwr7	print
// error code
popw	r0
pushw	r1
mov		r1,r0
jalwr7	print_hex
popw	r1
jalwr7	print
pushw	r1
// error address
ldwi	r7,mrch_err_adr
ldl		r1,[r7]
pushw	r1
lsri	r1,16
jalwr7	print_hex
popw	r1
jalwr7	print_hex
popw	r1
jalwr7	print
pushw	r1
// error data
ldwi	r7,mrch_err_dat
ldl		r1,[r7]
pushw	r1
lsri	r1,16
jalwr7	print_hex
popw	r1
jalwr7	print_hex
popw	r1
jalwr7	print
// led=red
ldbiu	r0,(~led_builtin_r)&led_builtin
ldwi	r7,porout
stw		[r7],r0
// discard access size
popw	r0
bra		no_data

march_ok:
ldwi	r1,lab_str_msg_march
jalwr7	print
pushw	r1
// access size
ldbiu	r0,2
ldwsp	r0,[r0]
ldwi	r1,lab_mrch_table+2
add		r1,r0
ldw		r1,[r1]
jalwr7	print
popw	r1
jalwr7	print
pushw	r1
// start address
ldwi	r7,mrch_start
ldl		r1,[r7]
pushw	r1
lsri	r1,16
jalwr7	print_hex
popw	r1
jalwr7	print_hex
popw	r1
jalwr7	print
pushw	r1
// end address
ldwi	r7,mrch_end
ldl		r1,[r7]
pushw	r1
lsri	r1,16
jalwr7	print_hex
popw	r1
jalwr7	print_hex
popw	r1
jalwr7	print
pushw	r1
// step
ldwi	r7,mrch_step
ldw		r1,[r7]
jalwr7	print_hex
popw	r1
jalwr7	print
pushw	r1
// test time
ldwi	r7,mrch_time
ldl		r1,[r7]
pushw	r1
lsri	r1,16
jalwr7	print_hex
popw	r1
jalwr7	print_hex
popw	r1
jalwr7	print
// led=green
ldbiu	r0,led_builtin_r|led_builtin_g|led_builtin_b
ldbiu	r0,(~led_builtin_g)&led_builtin
ldwi	r7,porout
stw		[r7],r0
// discard access size
popw	r0
bra		no_data

// table
mrch_table:
//		sub routine,	size string,		default step
datw	lab_marching_b,	lab_str_msg_byte,	1
datw	lab_marching_w,	lab_str_msg_word,	2
datw	lab_marching_l,	lab_str_msg_long,	4
march_notid:

// check "who" command
ldwi	r1,lbuf
ldwi	r2,lab_str_cmd_who
jalwr7	strcmp
cmpi	r0,0
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
cmpi	r0,0
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]
cmpi	r0,0
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

// end of command interpretation
no_data:


// ================================
// end of loop
$(s)// ********************************
$(s)ldwi	r1,lab_sim_str_delim
$(s)jalwr7	print
$(s)rtnw
$(s)sim_str_delim:
$(s)dats	"--------\r\n\0"
$(s)// ********************************
bra		loop


// ================================
// RAM marching test (long); disturbed r1~r3,r7
//	start:	r4
//	end:	r5-1
//	step:	r6
//	return:	r0=pass(0)/fail(1), r4=fail address, r5=fail data
// ================================
marching:
marching_l:
// initialize
ldli	r1,mrch_long1
ldli	r2,mrch_long0
// write all 0, upward
mov		r7,r4
mrch_loop_wr0:
stl		[r7],r2
add		r7,r6
cmp		r7,r5
blo		mrch_loop_wr0
// read 0, write 1, downward
ldbiu	r3,1
mov		r7,r5
mrch_loop_rd0wr1:
sub		r7,r6
ldl		r0,[r7]
stl		[r7],r1
cmp		r0,r2
bne		mrch_fail
cmp		r4,r7
blo		mrch_loop_rd0wr1
// read 1, write 0, upward
ldbiu	r3,2
mov		r7,r4
mrch_loop_rd1wr0:
ldl		r0,[r7]
stl		[r7],r2
add		r7,r6
cmp		r0,r1
bne		mrch_fail
cmp		r7,r5
blo		mrch_loop_rd1wr0
// read all 0, downward
ldbiu	r3,3
mov		r7,r5
mrch_loop_rd0:
sub		r7,r6
ldl		r0,[r7]
cmp		r0,r2
bne		mrch_fail
cmp		r4,r7
blo		mrch_loop_rd0
// test pass
ldbiu	r0,0
bra		mrch_return

// test fail
mrch_fail:
mov		r4,r7
mov		r5,r0
mov		r0,r3

// end of sub routine
mrch_return:
rtnw

// ================================
// RAM marching test (word); disturbed r1~r3,r7
//	start:	r4
//	end:	r5-1
//	step:	r6
//	return:	r0=pass(0)/fail(1), r4=fail address, r5=fail data
// ================================
marching_w:
// initialize
ldwi	r1,mrch_word1
ldwi	r2,mrch_word0
// write all 0, upward
mov		r7,r4
mrchw_loop_wr0:
stw		[r7],r2
add		r7,r6
cmp		r7,r5
blo		mrchw_loop_wr0
// read 0, write 1, downward
ldbiu	r3,1
mov		r7,r5
mrchw_loop_rd0wr1:
sub		r7,r6
ldw		r0,[r7]
stw		[r7],r1
cmp		r0,r2
bne		mrchw_fail
cmp		r4,r7
blo		mrchw_loop_rd0wr1
// read 1, write 0, upward
ldbiu	r3,2
mov		r7,r4
mrchw_loop_rd1wr0:
ldw		r0,[r7]
stw		[r7],r2
add		r7,r6
cmp		r0,r1
bne		mrchw_fail
cmp		r7,r5
blo		mrchw_loop_rd1wr0
// read all 0, downward
ldbiu	r3,3
mov		r7,r5
mrchw_loop_rd0:
sub		r7,r6
ldw		r0,[r7]
cmp		r0,r2
bne		mrchw_fail
cmp		r4,r7
blo		mrchw_loop_rd0
// test pass
ldbiu	r0,0
bra		mrchw_return

// test fail
mrchw_fail:
mov		r4,r7
mov		r5,r0
mov		r0,r3

// end of sub routine
mrchw_return:
rtnw

// ================================
// RAM marching test (byte); disturbed r1~r3,r7
//	start:	r4
//	end:	r5-1
//	step:	r6
//	return:	r0=pass(0)/fail(1), r4=fail address, r5=fail data
// ================================
marching_b:
// initialize
ldwi	r1,mrch_byte1
ldwi	r2,mrch_byte0
// write all 0, upward
mov		r7,r4
mrchb_loop_wr0:
stb		[r7],r2
add		r7,r6
cmp		r7,r5
blo		mrchb_loop_wr0
// read 0, write 1, downward
ldbiu	r3,1
mov		r7,r5
mrchb_loop_rd0wr1:
sub		r7,r6
ldb		r0,[r7]
stb		[r7],r1
cmp		r0,r2
bne		mrchb_fail
cmp		r4,r7
blo		mrchb_loop_rd0wr1
// read 1, write 0, upward
ldbiu	r3,2
mov		r7,r4
mrchb_loop_rd1wr0:
ldb		r0,[r7]
stb		[r7],r2
add		r7,r6
cmp		r0,r1
bne		mrchb_fail
cmp		r7,r5
blo		mrchb_loop_rd1wr0
// read all 0, downward
ldbiu	r3,3
mov		r7,r5
mrchb_loop_rd0:
sub		r7,r6
ldb		r0,[r7]
cmp		r0,r2
bne		mrchb_fail
cmp		r4,r7
blo		mrchb_loop_rd0
// test pass
ldbiu	r0,0
bra		mrchb_return

// test fail
mrchb_fail:
mov		r4,r7
mov		r5,r0
mov		r0,r3

// end of sub routine
mrchb_return:
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
cmpi	r2,0
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]
cmpi	r0,0
bne		print_lst
rtnw

// ================================
// print_hex r1 ; disturbed r0~r7
//		print r1 as 4 digits hexadecimal number
// ================================
print_hex:
ldbiu	r3,4
$(s)// ********************************
$(s)ldwi	r7,princtl
$(s)ldbiu	r0,prin_nld
$(s)stw		[r7],r0
$(s)ldwi	r7,prinhex
$(s)cmpi	r3,4
$(s)beq		ph_else
$(s)cendw	r1
$(s)stb		[r7],r1
$(s)bra		ph_endif
$(s)ph_else:
$(s)stw		[r7],r1
$(s)ph_endif:
$(s)rtnw
$(s)// ********************************
ldwi	r7,uarttdat
ldwi	r6,uartctl
ldwi	r5,lab_ph_hexdig
ph_loop:
// print nibble
mov		r0,r1
mov		r4,r5
cendw	r0
lsri	r0,4
andi	r0,0x0f
add		r4,r0
ldb		r2,[r4]
// polling uartctl.TFUL=0
ph_poll:
ldw		r0,[r6]
andi	r0,uart_tful
bne		ph_poll
// send data
stw		[r7],r2
// loop
lsli	r1,4
subi	r3,1
bne		ph_loop
rtnw

ph_hexdig:
dats	"0123456789abcdef"

// ================================
// 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

// ================================
// 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
cmpi	r3,0
beq		sc_finish
cmpi	r4,0
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
cmpi	r3,0
beq		snc_finish
cmpi	r4,0
bne		strncmp
snc_finish:
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
lsli	r3,3
add		r0,r0
add		r0,r3
add		r0,r2
// end of 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
lsli	r0,4
add		r0,r2
// end of loop
addi	r1,1
bra		xtoi+2
x2i_finish:
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+ march[l],<start_hex6>,<end_hex6>[,<step_hex4>]\r\n"
dats	"OK+ marchw,<start_hex6>,<end_hex6>[,<step_hex4>]\r\n"
dats	"OK+ marchb,<start_hex6>,<end_hex6>[,<step_hex4>]\r\n"
dats	"OK+ who\r\n"
dats	"OK: help\r\n\0\0"
str_msg_march:
dats	"OK: \0 marching (0x\0~0x\0,0x\0, 0x\0[us])\r\n\0"
str_msg_byte:
dats	"byte\0"
str_msg_word:
dats	"word\0"
str_msg_long:
dats	"long\0"
str_err_march:
dats	"ERR: (\0) address 0x\0, data 0x\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_cmd_march:
dats	"march\0"
str_cmd_who:
dats	"who\0"
str_cmd_help:
dats	"help\0"

