// ================================
// 8x8 led control by software spi
//		(c) 2021	1YEN Toru
//
//
//		2021/10/16	ver.1.02
//			can use fontjp unit
//
//		2021/10/02	ver.1.00
//
// ================================
asm		"mcoc_irom.mif"
#asm		"mcoc_irom.mem"
#asm		"mcoc_irom.dat2",bit16,list
incl	"mcoc115.incl"
# ================================
# string macros
def		prog_name,"flash_mesg"
def		prog_vers,"1.02"
def		s,"#"							// simulation="" / real fpga="#"
def		f,""							// fontjp unit: not use="" / use="#"
# 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_spc,0x20					// space ' ' code
equ		chr_cma,0x2c					// comma ',' code
equ		spi_ss,0x80						// spi: ss pin
equ		spi_sck,0x40					// spi: sck pin
equ		spi_mosi,0x20					// spi: mosi pin
equ		spi_miso,0x20					// spi: miso pin (not used in max7219)
equ		led_nop,0x00					// 8x8: nop
equ		led_dgt0,0x01					// 8x8: Digit0
equ		led_dgt1,0x02					// 8x8: Digit1
equ		led_dgt2,0x03					// 8x8: Digit2
equ		led_dgt3,0x04					// 8x8: Digit3
equ		led_dgt4,0x05					// 8x8: Digit4
equ		led_dgt5,0x06					// 8x8: Digit5
equ		led_dgt6,0x07					// 8x8: Digit6
equ		led_dgt7,0x08					// 8x8: Digit7
equ		led_decmd,0x09					// 8x8: decode mode
equ		led_inten,0x0a					// 8x8: intensity
equ		led_scan,0x0b					// 8x8: scan limit
equ		led_shut,0x0c					// 8x8: shutdown
equ		led_test,0x0f					// 8x8: display test
# variables
equ		va,ramtop
equ		spi_adr_dat,va					// address & data word for max7219
equ		va,va+2
equ		itvl_ms,va						// <interval_ms>
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
# ================================
# user macros
macro	spi_ss_0
// ss=0
ldbiu	r0,spi_ss
stw		[r6],r0
endm

macro	spi_ss_1
// ss=1
ldbiu	r0,spi_ss
stw		[r7],r0
endm

macro	spi_sck_0
// sck=0
ldbiu	r0,spi_sck
stw		[r6],r0
endm

macro	spi_sck_1
// sck=1
ldbiu	r0,spi_sck
stw		[r7],r0
endm

macro	spi_mosi_o
// mosi
ldbiu	r0,spi_mosi
lsfti	r1,1
bcs		pcnt+4
stw		[r6],r0							// clear
bra		pcnt+2
stw		[r7],r0							// set
endm

macro	spi_miso_i
// miso
ldw		r0,[r5]
andi	r0,spi_miso
beq		pcnt+2
ori		r1,1
endm
# ================================

// ================================
// 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

// port setting
ldbiu	r0,spi_ss
ldwi	r7,porset
stw		[r7],r0
ldwi	r7,pordir
ldw		r0,[r7]
andi	r0,~(spi_ss|spi_sck|spi_mosi)
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

// init max7219
ldwi	r1,(led_decmd<<8)+0x00			// no decode mode
jalwr7	spi_transfer
ldwi	r1,(led_inten<<8)+0x00			// minimum intensity
jalwr7	spi_transfer
ldwi	r1,(led_scan<<8)+0x07			// full scan mode
jalwr7	spi_transfer
ldwi	r1,(led_shut<<8)+0x00			// shutdown mode set
jalwr7	spi_transfer
tst_skip:

// fontjp setting
ldbiu	r0,fnjp_rot_1
ldwi	r7,fnjpctl
stw		[r7],r0

// send RDY
ldwi	r1,lab_str_msg_rdy
jalwr7	print

$(s)// ********************************
$(s)// for simulation
$(s)// local loop back: mosi -> miso
$(s)ldwi	r7,porsel
$(s)ldbiu	r0,spi_miso
$(s)stw		[r7],r0
$(s)// flash message
$(s)ldwi	r1,lab_tst_string
$(s)ldbiu	r2,8
$(s)jalwr7	flash_mesg
$(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)tst_string:
$(s)$(f)dats	"Ab7\0"
$(s)dats	"Ваa4\0"
$(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

// check "fmsg" command
ldwi	r1,lbuf
ldwi	r2,lab_str_cmd_fmsg
ldbiu	r5,5
jalwr7	strncmp
mov		r0,r0
bne		fmsg_notid
// ================================
// fmsg,<interval_ms>,<message>
ldwi	r1,lbuf
// <reg_addr_hex>
addi	r1,5
jalwr7	atoi
ldwi	r7,itvl_ms
stw		[r7],r0
// check ','
ldb		r0,[r1]
cmpi	r0,chr_cma
bne		err_syntx
// <message>
addi	r1,1
ldwi	r2,itvl_ms
ldw		r2,[r2]

// flash message
jalwr7	flash_mesg
// response
ldwi	r1,lab_str_msg_fmsg
jalwr7	print
bra		no_data
fmsg_notid:

// check "wr" command
ldwi	r1,lbuf
ldwi	r2,lab_str_cmd_wrad
ldbiu	r5,3
jalwr7	strncmp
mov		r0,r0
bne		wrad_notid
// ================================
// wr,<adr_dat_hex4>
ldwi	r1,lbuf
// <adr_dat_hex4>
addi	r1,3
jalwr7	xtoi
ldwi	r7,spi_adr_dat
stw		[r7],r0
// write to max7219
ldwi	r1,spi_adr_dat
ldw		r1,[r1]
jalwr7	spi_transfer
// response
ldwi	r1,lab_str_msg_wrad
jalwr7	print
pushw	r1
ldwi	r1,spi_adr_dat
ldw		r1,[r1]
jalwr7	print_hex
popw	r1
jalwr7	print
bra		no_data
wrad_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 loop
bra		loop


// ================================
// software spi transfer ; disturbed r0,r5~r7
//	mode 0, MSB first, 16 bit
//	parameter:	r1=16 bits data to send
//	return:		r1=received 16 bits data
// ================================
spi_transfer:
ldwi	r7,porset
ldwi	r6,porclr
ldwi	r5,porind						// porind is better than porin.
// spi 16 bits transfer
spi_ss_0
rept	16
// spi bit $(reptr)
spi_mosi_o
spi_sck_1
spi_miso_i
spi_sck_0
endr
spi_ss_1
$(s)// ********************************
$(s)ldwi	r7,prinhex
$(s)stw		[r7],r1
$(s)// ********************************
rtnw

// ================================
// show character ; disturbed r0,r1,r5~r7
//	r1: ascii / s-jis character code
// ================================
show_chr:
// font data address
$(f)subi	r1,chr_spc
$(f)lsfti	r1,3
$(f)ldwi	r7,lab_font_8x8
$(f)add		r7,r1
$(f)bra		shc_skip1
ldwi	r7,fnjpcod
stw		[r7],r1
ldwi	r7,fnjpdata
shc_skip1:
// loop
ldbiu	r0,led_dgt0
shc_loop:
ldb		r1,[r7]
pushw	r0
lsfti	r0,8
add		r1,r0
$(s)// ********************************
$(s)// print font data for simulation
$(s)ldwi	r6,princhr
$(s)lsfti	r1,8
$(s)rept	8
$(s)lsfti	r1,1
$(s)ldbiu	r0,chr_spc
$(s)bcc		pcnt+2
$(s)addi	r0,chr_spc
$(s)stw		[r6],r0
$(s)stw		[r6],r0
$(s)endr
$(s)ldbiu	r0,chr_lf
$(s)stw		[r6],r0
$(s)bra		shc_skip2
$(s)// ********************************
// send 1 line
pushw	r7
jalwr7	spi_transfer
popw	r7
shc_skip2:
// end of loop
addi	r7,1
popw	r0
addi	r0,1
cmpi	r0,led_dgt7+1
blo		shc_loop
// shutdown mode clear
ldwi	r1,(led_shut<<8)+0x01
jalwr7	spi_transfer
rtnw

// ================================
// flash message ; disturbed r0,r1,r5~r7
//	r1: pointer to string
//	r2: flash interval [ms]
// ================================
flash_mesg:
ldb		r0,[r1]
mov		r0,r0
beq		fmg_return
addi	r1,1
pushw	r1
// ascii / s-jis code check
$(f)cmpi	r0,chr_spc
$(f)bhs		pcnt+2
$(f)ldbiu	r0,chr_spc
$(f)bra		fmg_not_sjis
mov		r1,r0
lsfti	r1,8
ldwi	r7,fnjpcod
stw		[r7],r1
ldwi	r7,fnjpctl
ldw		r7,[r7]
andi	r7,fnjp_sjs1
beq		fmg_not_sjis
popw	r7
ldb		r0,[r7]
addi	r7,1
add		r0,r1
pushw	r7
fmg_not_sjis:
// show character
mov		r1,r0
jalwr7	show_chr
// set offset of sytmmil
ldwi	r7,sytmctl
ldw		r0,[r7]
andi	r0,~sytm_mloe
stw		[r7],r0
ori		r0,sytm_mloe
stw		[r7],r0
// wait "on" time
mov		r1,r2
mov		r0,r2
lsfti	r0,-3
sub		r1,r0
ldwi	r7,sytmmill
ldw		r0,[r7]
cmp		r0,r1
blo		pcnt-6
// clear 8x8 led
ldwi	r1,(led_shut<<8)+0x00			// shutdown mode set
jalwr7	spi_transfer
// wait "off" time
ldwi	r7,sytmmill
ldw		r0,[r7]
cmp		r0,r2
blo		pcnt-6
// end of loop
popw	r1
bra		flash_mesg
fmg_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
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_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		pcnt+6
$(s)lsfti	r1,-8
$(s)stb		[r7],r1
$(s)bra		pcnt+2
$(s)stw		[r7],r1
$(s)rtnw
$(s)// ********************************
ldwi	r7,uarttdat
ldwi	r6,uartctl
ldwi	r5,lab_ph_hexdig
ph_loop:
// print nibble
mov		r0,r1
mov		r4,r5
lsfti	r0,-12
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
lsfti	r1,4
subi	r3,1
bne		ph_loop
rtnw

ph_hexdig:
dats	"0123456789abcdef"

// ================================
// 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

// ================================
// 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

// ================================
// 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+ fmsg,<interval_ms>,<message>\r\n"
dats	"OK+ wr,<adr_dat_hex4>\r\n"
dats	"OK+ who\r\n"
dats	"OK: help\r\n\0\0"
str_msg_fmsg:
dats	"OK: fmsg done\r\n\0"
str_msg_wrad:
dats	"OK: wr=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_fmsg:
dats	"fmsg,\0"
str_cmd_wrad:
dats	"wr,\0"
str_cmd_who:
dats	"who\0"
str_cmd_help:
dats	"help\0"

$(f)// ================================
$(f)// 8x8 font data
$(f)# rotate 90 degree
$(f)font_8x8:
$(f)datb	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00		// ' '
$(f)datb	0x00,0x00,0x00,0x6F,0x6F,0x00,0x00,0x00		// '!'
$(f)datb	0x04,0x03,0x03,0x00,0x04,0x03,0x03,0x00		// '"'
$(f)datb	0x22,0x7F,0x22,0x22,0x22,0x7F,0x22,0x00		// '#'
$(f)datb	0x24,0x2A,0x7F,0x2A,0x7F,0x2A,0x12,0x00		// '$'
$(f)datb	0x42,0x25,0x12,0x08,0x24,0x52,0x21,0x00		// '%'
$(f)datb	0x20,0x56,0x49,0x49,0x36,0x50,0x08,0x00		// '&'
$(f)datb	0x00,0x00,0x04,0x03,0x03,0x00,0x00,0x00		// '''
$(f)datb	0x00,0x00,0x00,0x00,0x1C,0x3E,0x41,0x00		// '('
$(f)datb	0x00,0x41,0x3E,0x1C,0x00,0x00,0x00,0x00		// ')'
$(f)datb	0x08,0x2A,0x1C,0x7F,0x1C,0x2A,0x08,0x00		// '*'
$(f)datb	0x08,0x08,0x08,0x7F,0x08,0x08,0x08,0x00		// '+'
$(f)datb	0x00,0x00,0x40,0x30,0x30,0x00,0x00,0x00		// ','
$(f)datb	0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x00		// '-'
$(f)datb	0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00		// '.'
$(f)datb	0x40,0x20,0x10,0x08,0x04,0x02,0x01,0x00		// '/'
$(f)datb	0x00,0x3E,0x51,0x49,0x45,0x7F,0x3E,0x00		// '0'
$(f)datb	0x00,0x00,0x44,0x7E,0x7F,0x40,0x00,0x00		// '1'
$(f)datb	0x00,0x42,0x61,0x71,0x59,0x4F,0x46,0x00		// '2'
$(f)datb	0x00,0x22,0x41,0x49,0x49,0x7F,0x36,0x00		// '3'
$(f)datb	0x00,0x18,0x14,0x12,0x7F,0x7F,0x10,0x00		// '4'
$(f)datb	0x00,0x2F,0x4A,0x4A,0x4A,0x7A,0x32,0x00		// '5'
$(f)datb	0x00,0x3E,0x49,0x49,0x49,0x7B,0x32,0x00		// '6'
$(f)datb	0x00,0x41,0x61,0x31,0x19,0x0F,0x07,0x00		// '7'
$(f)datb	0x00,0x36,0x49,0x49,0x49,0x7F,0x36,0x00		// '8'
$(f)datb	0x00,0x06,0x49,0x69,0x39,0x1F,0x06,0x00		// '9'
$(f)datb	0x00,0x00,0x00,0x36,0x36,0x00,0x00,0x00		// ':'
$(f)datb	0x00,0x00,0x40,0x36,0x36,0x00,0x00,0x00		// ';'
$(f)datb	0x00,0x08,0x1C,0x36,0x63,0x41,0x00,0x00		// '<'
$(f)datb	0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x00		// '='
$(f)datb	0x00,0x00,0x41,0x63,0x36,0x1C,0x08,0x00		// '>'
$(f)datb	0x00,0x06,0x07,0x51,0x59,0x0F,0x06,0x00		// '?'
$(f)datb	0x1C,0x22,0x49,0x55,0x5D,0x22,0x1C,0x00		// '@'
$(f)datb	0x78,0x7C,0x16,0x13,0x12,0x14,0x78,0x00		// 'A'
$(f)datb	0x7F,0x7F,0x49,0x49,0x49,0x49,0x36,0x00		// 'B'
$(f)datb	0x3E,0x7F,0x41,0x41,0x41,0x41,0x22,0x00		// 'C'
$(f)datb	0x7F,0x7F,0x41,0x41,0x41,0x22,0x1C,0x00		// 'D'
$(f)datb	0x7F,0x7F,0x49,0x49,0x49,0x49,0x41,0x00		// 'E'
$(f)datb	0x7F,0x7F,0x09,0x09,0x09,0x09,0x01,0x00		// 'F'
$(f)datb	0x3E,0x7F,0x41,0x41,0x41,0x31,0x72,0x00		// 'G'
$(f)datb	0x7F,0x7F,0x08,0x08,0x08,0x08,0x7F,0x00		// 'H'
$(f)datb	0x00,0x00,0x41,0x7F,0x7F,0x41,0x00,0x00		// 'I'
$(f)datb	0x00,0x30,0x70,0x41,0x7F,0x3F,0x01,0x00		// 'J'
$(f)datb	0x00,0x7F,0x7F,0x1C,0x36,0x63,0x41,0x00		// 'K'
$(f)datb	0x00,0x7F,0x7F,0x40,0x40,0x60,0x70,0x00		// 'L'
$(f)datb	0x7F,0x7F,0x06,0x0C,0x06,0x7F,0x7F,0x00		// 'M'
$(f)datb	0x7F,0x7F,0x06,0x0C,0x18,0x30,0x7F,0x00		// 'N'
$(f)datb	0x3E,0x7F,0x41,0x41,0x41,0x41,0x3E,0x00		// 'O'
$(f)datb	0x7F,0x7F,0x09,0x09,0x09,0x09,0x06,0x00		// 'P'
$(f)datb	0x3E,0x7F,0x41,0x49,0x51,0x3F,0x5E,0x00		// 'Q'
$(f)datb	0x7F,0x7F,0x09,0x19,0x39,0x69,0x46,0x00		// 'R'
$(f)datb	0x26,0x6F,0x49,0x49,0x49,0x7B,0x32,0x00		// 'S'
$(f)datb	0x00,0x01,0x01,0x7F,0x7F,0x01,0x01,0x00		// 'T'
$(f)datb	0x3F,0x7F,0x40,0x40,0x40,0x7F,0x3F,0x00		// 'U'
$(f)datb	0x07,0x1F,0x38,0x60,0x38,0x1F,0x07,0x00		// 'V'
$(f)datb	0x1F,0x7F,0x30,0x3C,0x30,0x7F,0x1F,0x00		// 'W'
$(f)datb	0x63,0x77,0x3A,0x1C,0x2E,0x77,0x63,0x00		// 'X'
$(f)datb	0x00,0x07,0x0F,0x7C,0x78,0x0C,0x07,0x00		// 'Y'
$(f)datb	0x61,0x71,0x59,0x4D,0x47,0x43,0x41,0x00		// 'Z'
$(f)datb	0x00,0x00,0x7F,0x7F,0x41,0x41,0x00,0x00		// '['
$(f)datb	0x00,0x27,0x2C,0x78,0x7C,0x2F,0x27,0x00		// '\'
$(f)datb	0x00,0x00,0x41,0x41,0x7F,0x7F,0x00,0x00		// ']'
$(f)datb	0x00,0x04,0x06,0x03,0x03,0x06,0x04,0x00		// '^'
$(f)datb	0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00		// '_'
$(f)datb	0x00,0x00,0x00,0x03,0x03,0x04,0x00,0x00		// '`'
$(f)datb	0x00,0x38,0x44,0x44,0x3C,0x40,0x00,0x00		// 'a'
$(f)datb	0x00,0x7E,0x48,0x44,0x24,0x18,0x00,0x00		// 'b'
$(f)datb	0x00,0x38,0x44,0x44,0x44,0x44,0x00,0x00		// 'c'
$(f)datb	0x00,0x38,0x44,0x44,0x48,0x3E,0x40,0x00		// 'd'
$(f)datb	0x00,0x38,0x54,0x54,0x54,0x58,0x00,0x00		// 'e'
$(f)datb	0x00,0x10,0x7C,0x12,0x12,0x14,0x00,0x00		// 'f'
$(f)datb	0x00,0x30,0x4C,0x4A,0x4A,0x34,0x02,0x00		// 'g'
$(f)datb	0x00,0x7E,0x10,0x08,0x08,0x70,0x00,0x00		// 'h'
$(f)datb	0x00,0x00,0x00,0x7A,0x7A,0x00,0x00,0x00		// 'i'
$(f)datb	0x00,0x20,0x40,0x40,0x7A,0x3A,0x00,0x00		// 'j'
$(f)datb	0x00,0x7E,0x10,0x28,0x24,0x40,0x00,0x00		// 'k'
$(f)datb	0x00,0x00,0x02,0x3E,0x7C,0x40,0x00,0x00		// 'l'
$(f)datb	0x00,0x78,0x04,0x04,0x78,0x04,0x78,0x00		// 'm'
$(f)datb	0x00,0x7C,0x08,0x04,0x04,0x78,0x00,0x00		// 'n'
$(f)datb	0x00,0x38,0x44,0x44,0x44,0x38,0x00,0x00		// 'o'
$(f)datb	0x00,0x7C,0x12,0x12,0x12,0x0C,0x00,0x00		// 'p'
$(f)datb	0x00,0x0C,0x12,0x12,0x12,0x7C,0x00,0x00		// 'q'
$(f)datb	0x00,0x7C,0x08,0x04,0x04,0x08,0x00,0x00		// 'r'
$(f)datb	0x00,0x48,0x54,0x54,0x54,0x24,0x00,0x00		// 's'
$(f)datb	0x00,0x00,0x08,0x3E,0x48,0x48,0x00,0x00		// 't'
$(f)datb	0x00,0x3C,0x40,0x40,0x40,0x7C,0x00,0x00		// 'u'
$(f)datb	0x00,0x0C,0x30,0x40,0x30,0x0C,0x00,0x00		// 'v'
$(f)datb	0x00,0x3C,0x40,0x3C,0x40,0x40,0x3C,0x00		// 'w'
$(f)datb	0x00,0x44,0x28,0x10,0x28,0x44,0x00,0x00		// 'x'
$(f)datb	0x00,0x4C,0x50,0x50,0x50,0x3C,0x00,0x00		// 'y'
$(f)datb	0x00,0x44,0x64,0x54,0x4C,0x44,0x00,0x00		// 'z'
$(f)datb	0x00,0x00,0x08,0x3E,0x63,0x41,0x00,0x00		// '{'
$(f)datb	0x00,0x00,0x00,0x7F,0x7F,0x00,0x00,0x00		// '|'
$(f)datb	0x00,0x00,0x41,0x63,0x3E,0x08,0x00,0x00		// '}'
$(f)datb	0x00,0x0C,0x02,0x04,0x04,0x08,0x06,0x00		// '~'

