~rabbits/uxn5

2a4f37bf22c840d824c5b7070dfc7cf82e582d1a — Devine Lu Linvega a month ago 6a8f6fb
Added drifblim interpreter
8 files changed, 734 insertions(+), 26 deletions(-)

M build.sh
A etc/drifloon.tal
M etc/format-js.tal
M etc/program.js
A etc/programs.js
M index.html
M src/emu.js
A src/programs.js
M build.sh => build.sh +5 -3
@@ 6,10 6,12 @@ TARGET="bin/output.rom"
rm -rf bin
mkdir bin

# Assembler
uxnasm etc/format-js.tal bin/format-js.rom
uxnasm etc/drifloon.tal bin/drifloon.rom

echo "Assembling unicycle.."
uxnasm $SOURCE $TARGET
echo "Assembling formatter.."
uxnasm etc/format-js.tal bin/format-js.rom

echo "Writing program.js.."
uxncli bin/format-js.rom $TARGET > etc/program.js
echo "Done."

A etc/drifloon.tal => etc/drifloon.tal +429 -0
@@ 0,0 1,429 @@
( uxncli drifloon.rom )

|10 @Console &vector $2 &read $1 &pad $5 &write $1 &err $1

|0100

	;on-console .Console/vector DEO2

BRK

@on-console ( -> )

	.Console/read DEI
	DUP [ LIT2 &buffer =source ] STA
	;&buffer LDA2k INC2 SWP2 STA2
	#0a NEQ ?&end
		assemble
		print-summary
		&end

BRK

@on-error ( id* name* -> )

	#0a19 DEO
	( print ) ;err pstr pstr #2019 DEO pstr ;dict/in pstr ;scope pstr ;dict/dot pstr
	( halt ) #010f DEO

BRK

(
@|generics )

@handle-source ( -- )

	;source
	&w
		LDAk handle-char
		INC2 LDAk ?&w
	POP2
JMP2r

@handle-char ( c -- )

	#20 GTHk NIP ?&append POP
	;token LDAk ?&run POP2

JMP2r
	&append ( c -- ) ;token DUP2 slen #001f LTH2 ?sput POP JMP2r
	&run ( t* -- ) DUP2 handle-token !sclr

@handle-token ( t* -- )

	LDAk LIT "( EQU ?&on-parens
	LDAk LIT ") EQU ?&on-parens
	[ LIT &sleep $1 ] ?&on-sleep

!parse
	&on-parens ( t* -- ) LDA LIT "( EQU ,&sleep STR JMP2r
	&on-sleep ( t* -- ) POP2 JMP2r

(
@|core )

@assemble ( -- )

	( pass1 )
	#0100 set-head
	;dict/reset ;scope scpy
	handle-source
	( pass2 )
	#0100 set-head
	;dict/reset ;scope scpy
	#00 ;write/skip STA
	handle-source

JMP2r

@parse ( t* -- )

	LDAk ,&rune STR
	( runes )
	;runes/err ;runes
	&l
		LDAk [ LIT &rune $1 ] NEQ ?&no-runic
			NIP2 INC2 LDA2 JMP2
			&no-runic
		#0003 ADD2 GTH2k ?&l
	POP2 POP2
	( non-runic )
	DUP2 is-hex ?lib/rawhex
	DUP2 is-opcode ?lib/opcode
	lib/litjsi

JMP2r

@lib
	&padabs INC2 get-hex write-pad !set-head
	&padrel INC2 get-hex !write-fill
	&toplab INC2 ;scope OVR2 SWP2 scpy !create-label
	&sublab INC2 make-sublabel !create-label
	&litrel #80 write
	&rawrel INC2 get-ref get-rel INC !write
	&litzep #80 write
	&rawzep INC2 get-ref LDA2 NIP !write
	&litabs #a0 write
	&rawabs INC2 get-ref LDA2 !write-short
	&litjci #20 write INC2 !write-call
	&litjmi #40 write INC2 !write-call
	&litjsi #60 write !write-call
	&lithex INC2 DUP2 slen NIP #02 SFT #a080 ROT [ JMP SWP POP ] write
	&rawhex !write-hex
	&rawstr INC2 !write-str
	&opcode find-opcode !write
	&ignore POP2 JMP2r

(
@|primitives )

@write-pad ( addr* -- dest* )

	;write/head LDA2
	LTH2k ?&no-pad
		SUB2k write-fill POP2 JMP2r
		&no-pad
	OVR2 #0100 LTH2 ?&no-err
		;token ;err/rewind !on-error
		&no-err
	POP2

JMP2r

@write-fill ( len* -- )

	#0000 EQU2k ?&skip
	&l
		#00 write
		INC2 GTH2k ?&l
	&skip
	POP2 POP2

JMP2r

@write-str ( str* -- )

	&w
		LDAk write
		INC2 LDAk ?&w
	POP2

JMP2r

@write-call ( str* -- )

	get-ref LDA2 ;write/head LDA2 INC2 INC2 SUB2

!write-short

@write-hex ( str* -- )

	DUP2 slen OVR2 get-hex SWP2 NIP
	DUP #02 EQU ?&byte
	DUP #04 EQU ?&short
	POP POP2
	;err/number !on-error
	&byte POP NIP2 NIP !write
	&short POP NIP2 ( fall through )

@write-short ( short* -- )

	SWP write

@write ( byte -- )

	,&b STR
	[ LIT2 &head 0100 ] #0100 LTH2 ?&ignore
	[ LIT &skip 01 ] ?&pass1
	[ LIT2 &length $2 ] ,&head LDR2 LTH2 ?&ignore
	( pass2 ) ,&b LDR #18 DEO
	&ignore

!move-head

&pass1 ( -- )

	[ LIT &b $1 ] #00 EQU ?&no-record
		,&head LDR2 ;write/length STA2
		&no-record

!move-head

(
@|helpers )

@get-hex ( str* -- value* )

	DUP2 is-hex ?&valid
		;err/number !on-error
		&valid

!shex

@get-rel ( label* -- distance )

	;write/skip LDA ?&fill
	LDA2k ;write/head LDA2 SUB2 #0003 SUB2
	DUP2 #0080 ADD2 POP ?&fail
	NIP2 NIP

JMP2r
	&fail POP2 #0003 ADD2 ;err/distance !on-error
	&fill POP2 #ff JMP2r

@get-ref ( token* -- <label*> )

	;write/skip LDA #00 EQU ?&no-write
		POP2 ;&fill JMP2r
		&no-write
	LDAk LIT "& NEQ ?&no-sub
		INC2 make-sublabel
		&no-sub
	find-label
		INC2k ORA ?&found
			POP2 ;err/reference !on-error
			&found
	( count )
	INC2k INC2 LDAk INC ROT ROT STA

JMP2r
	&fill ffff "[empty] $1

@create-label ( name* -- )

	;write/skip LDA #00 EQU ?&skip
	( not hex ) DUP2 is-hex ?&invalid
	( not opc ) DUP2 is-opcode ?&invalid
	( not dup ) DUP2 find-label INC2 ORA ?&not-unique
	( save addr ) ;write/head LDA2 [ LIT2 &ptr =symbols ] STH2k STA2
	( move ) INC2r INC2r INC2r
	( save name ) DUP2 STH2kr scpy
	( move ) slen STH2r ADD2 INC2 ,&ptr STR2
	( stats ) [ LIT2 &count $2 ] INC2 ,&count STR2

JMP2r
	&invalid ;err/invalid !on-error
	&not-unique ;err/duplicate !on-error
	&skip POP2 JMP2r

@make-sublabel ( name* -- sublabel* )

	;scope ;sublabel STH2k scpy
	LIT "/ STH2kr sput
	STH2kr scat
	STH2r

JMP2r

@is-hex ( str* -- f )

	&w
		LDAk chex INC ?&valid
			POP2 #00 JMP2r &valid
		INC2 LDAk ?&w
	POP2
	#01

JMP2r

@is-opcode ( string* -- f )

	DUP2 ;opcodes/brk scmp3 ?find-opcode/on-brk

@find-opcode ( name* -- byte )

	STH2
	#2000
	&l
		#00 OVR #03 MUL ;opcodes ADD2 STH2kr scmp3 ?&on-found
		INC GTHk ?&l
	POP2 POP2r #00

JMP2r
	&on-found
		NIP ( LITk ) DUP #00 EQU #70 SFT ADD
		STH2r #0003 ADD2 find-modes ADD JMP2r
	&on-brk POP2 #01 JMP2r

@find-modes ( mode* -- byte )

	LITr 00
	&w
		LDAk #20
		OVR LIT "2 EQU ?&end DUP ADD
		OVR LIT "r EQU ?&end DUP ADD
		OVR LIT "k EQU ?&end DUP ADD
		OVR #21 LTH ?&end
			;token ;err/mode !on-error
		&end NIP STH ORAr
		INC2 LDAk ?&w
	POP2 STHr

JMP2r

@find-label ( name* -- <addr*> )

	STH2
	;symbols
	&w
		#0003 ADD2 DUP2 STH2kr scmp ?&found
		scap INC2 INC2k INC2 INC2 LDA ?&w
	POP2
	POP2r
	#ffff

JMP2r
	&found #0003 SUB2 POP2r JMP2r

@move-head ( -- )

	;write/head LDA2 INC2

@set-head ( v* -- )

	;write/head STA2

JMP2r

@print-summary ( -- )

	;symbols
	&w
		( ignore uppercased device labels )
		INC2k INC2 INC2 LDA DUP #40 GTH SWP #5b LTH AND ?&used
		INC2k INC2 LDA ?&used
			;dict/unused pstr
			#0003 ADD2 DUP2 pstr #0a19 DEO
			&used
		scap INC2 INC2k INC2 INC2 LDA ?&w
	POP2
	( result )
	;dict/assembled pstr ;write/length LDA2 #00ff SUB2 pdec ;dict/bytes pstr
	;create-label/count LDA2 pdec ;dict/labels pstr
	;dict/end pstr

JMP2r

(
@|stdlib )

@pstr ( str* -- ) LDAk ?&w POP2 JMP2r &w LDAk #19 DEO INC2 LDAk ?&w POP2 JMP2r
@scap ( str* -- end* ) LDAk ?&w JMP2r &w INC2 LDAk ?&w JMP2r
@sput ( chr str* -- ) scap INC2k #00 ROT ROT STA STA JMP2r
@slen ( str* -- len* ) DUP2 scap SWP2 SUB2 JMP2r
@scat ( src* dst* -- ) scap
@scpy ( src* dst* -- ) OVR2 LDA ?&e POP2 POP2 JMP2r &e STH2 &w LDAk STH2kr STA INC2r INC2 LDAk ?&w POP2 #00 STH2r STA JMP2r
@sclr ( str* -- ) LDAk ?&w POP2 JMP2r &w STH2k #00 STH2r STA INC2 LDAk ?&w POP2 JMP2r
@skey ( key buf -- proc ) OVR #21 LTH ?&eval #00 SWP sput #00 JMP2r &eval POP2 #01 JMP2r
@scmp ( a* b* -- f ) STH2 &l LDAk LDAkr STHr ANDk #00 EQU ?&e NEQk ?&e POP2 INC2 INC2r !&l &e NIP2 POP2r EQU JMP2r
@scmp3 ( a* b* -- f ) LDA2k ROT2 LDA2k ROT2 EQU2 STH INC2 LDA2 SWP2 INC2 LDA2 EQU2 STHr AND JMP2r
@chex ( c -- val|ff ) LIT "0 SUB DUP #09 GTH [ JMP JMP2r ] #27 SUB DUP #0f GTH [ JMP JMP2r ] POP #ff JMP2r
@shex ( str* -- val* ) LIT2r 0000 &w LITr 40 SFT2r LITr 00 LDAk chex STH ADD2r INC2 LDAk ?&w POP2 STH2r JMP2r

@pdec ( short* -- )

	#00 ,&z STR
	#2710 pdec/parse
	#03e8 pdec/parse
	#0064 pdec/parse
	#000a pdec/parse
	NIP #30 ADD #19 DEO

JMP2r

&parse ( short* den* -- short* )

	DIV2k DUPk [ LIT &z $1 ] EQU ?&skip
	DUP #30 ADD #19 DEO #ff ,&z STR
	&skip POP MUL2 SUB2

JMP2r

(
@|assets )

@dict
	&assembled "Assembled 20 $1
	&reset "INIT $1
	&bytes 20 "bytes( $1
	&in ", 20 "in 20 $1
	&end ") &dot ". 0a $1
	&labels 20 "labels $1
	&unused "-- 20 "Unused 20 "label: 20 $1

@err "!! 20 "Error: 20 $1
	&duplicate "Duplicate  $1
	&number "Number $1
	&reference "Reference $1
	&distance "Distance $1
	&invalid "Invalid $1
	&mode "Mode $1
	&rewind "Rewind $1

@opcodes
	"LIT "INC "POP "NIP "SWP "ROT "DUP "OVR
	"EQU "NEQ "GTH "LTH "JMP "JCN "JSR "STH
	"LDZ "STZ "LDR "STR "LDA "STA "DEI "DEO
	"ADD "SUB "MUL "DIV "AND "ORA "EOR "SFT
	&brk "BRK

@runes
	"| =lib/padabs "$ =lib/padrel
	"@ =lib/toplab "& =lib/sublab
	", =lib/litrel "_ =lib/rawrel
	". =lib/litzep "- =lib/rawzep
	"; =lib/litabs "= =lib/rawabs
	"? =lib/litjci "! =lib/litjmi
	"[ =lib/ignore "] =lib/ignore
	"# =lib/lithex "" =lib/rawstr
	&err

(
@|memory )

@token $20
@scope $20
@sublabel $20
@source $4000
@symbols ( addr*, refs, name[], 00 )


M etc/format-js.tal => etc/format-js.tal +1 -1
@@ 78,5 78,5 @@ JMP2r

JMP2r

@header-txt "const 20 "program 20 "= 20 "new 20 "Uint8Array([ 0a 09 00
@header-txt "const 20 "assembler 20 "= 20 "new 20 "Uint8Array([ 0a 09 00
@footer-txt "0x00]) 00

M etc/program.js => etc/program.js +1 -1
@@ 1,4 1,4 @@
const program = new Uint8Array([
const assembler = new Uint8Array([
	0xa0, 0x01, 0x12, 0x94, 0x80, 0x18, 0x17, 0x21, 
	0x94, 0x20, 0xff, 0xf7, 0x22, 0xa0, 0x01, 0x0f, 
	0x17, 0x00, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 

A etc/programs.js => etc/programs.js +19 -0
@@ 0,0 1,19 @@
const program_default = `@program

	;hello-word
	&while
		( send ) LDAk #18 DEO
		( loop ) INC2 LDAk ?&while
	POP2
	( halt ) #010f DEO

BRK

@hello-word "Hello 20 "World! 0a00`

const program = new Uint8Array([
	0xa0, 0x01, 0x12, 0x94, 0x80, 0x18, 0x17, 0x21, 
	0x94, 0x20, 0xff, 0xf7, 0x22, 0xa0, 0x01, 0x0f, 
	0x17, 0x00, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 
	0x57, 0x6f, 0x72, 0x6c, 0x64, 0x21, 0x0a, 0x00, 
	0x00, 0x00])

M index.html => index.html +53 -15
@@ 2,33 2,71 @@
<html>
<head>
	<meta charset="utf-8"/>
	<script src="etc/program.js"></script>
	<script src="src/programs.js"></script>
	<script src="src/emu.js"></script>
	<script src="src/uxn.js"></script>
</head>
<body>
	<input type="value" placeholder="Uxntal Interpreter" id="asm" autofocus/>
	<span id="res"></span>
	<textarea id="editor" spellcheck="false">Program</textarea>
	<div id='term'></div>
	<div id='stack'>
		<input type="button" id="run" value="Run">
		<span id='wst'>empty</span>
	</div>

	<script type="text/javascript">
		'use strict'

		let asm_el = document.getElementById("asm")
		let res = document.getElementById("res")
		let emulator = new Emu()
		let term_el = document.getElementById("term")
		term_el.innerHTML = "Ready."

		let editor_el = document.getElementById("editor")
		editor_el.value = hello_tal;

		let wst_el = document.getElementById("wst")
		wst_el.innerHTML = "--"

		emulator.console.display = res
		emulator.uxn.load(program).eval(0x0100)
		function assemble(query, program){
			let emulator = new Emu()
			let length = 0
			emulator.console.write = (char) => { program[length++] = char }
			emulator.console.error = (char) => { term_el.innerHTML += String.fromCharCode(char) }
			emulator.uxn.load(drifloon_rom).eval(0x0100)
			term_el.innerHTML = ""
			for (let i = 0; i < query.length; i++)
				emulator.console.input(query.charAt(i).charCodeAt(0))
			emulator.console.input(0x0a)
		}

		asm_el.addEventListener("keydown", function (event) {
			if (event.key === "Enter") {
				event.preventDefault();
				for (let i = 0; i < asm_el.value.length; i++) 
					emulator.console.input(asm_el.value.charAt(i).charCodeAt(0))
				emulator.console.input(0x0a)
				asm_el.value = ""
		/* assembler */
		let run_el = document.getElementById("run")		
		run_el.addEventListener("click", (event) => {
			let program = new Uint8Array(0x10000)
			assemble(editor_el.value.replace(/(\r\n|\n|\r|\t)/gm, " "), program)
			let emulator = new Emu()
			emulator.console.write = (char) => { term_el.innerHTML += String.fromCharCode(char) }
			emulator.uxn.load(program).eval(0x0100)
			/* draw stack */
			if(!emulator.uxn.wst.ptr())
				wst_el.innerHTML = "Stack: Empty"
			else {
				let i = 0;
				wst_el.innerHTML = "Stack: "
				for(i = 0; i< emulator.uxn.wst.ptr(); i++){
					wst_el.innerHTML += ('0' + (emulator.uxn.wst.get(i) & 0xFF).toString(16)).slice(-2) + " ";
				}
			}
			
		})
	</script>
	<style>
		body { max-width:600px; font-family:monospace; padding:30px }
		textarea { resize:none; width:100%; height:250px; border:2px solid #000; border-radius:0px; padding:10px; margin-bottom:0px; }
		textarea:focus { outline: none !important; border:2px solid black; }
		div#term { width:100%; background:#000; padding:12px; color:white; max-height:60px; overflow:scroll; white-space:pre }
		div#ctrl { margin-bottom:10px }
		div#stack { width:100%; background:#72dec2; padding:12px; margin-bottom:20px;font-weight:bold }
	</style>
	<noscript>This form requires Javascript.</noscript>
</body>
</html> 
\ No newline at end of file

M src/emu.js => src/emu.js +10 -6
@@ 4,14 4,15 @@ function Console(emu)
{
	this.buffer = ""
	this.display = null
	this.emit = null

	this.i = (char) => {
		console.log("i",char)
	this.write = (char) => {
		this.display.innerHTML += this.buffer
	}

	this.send = (char) => {
	this.error = (char) => {
		if(char == 0x0a) {
			this.display.innerHTML = this.buffer
			console.warn(this.buffer)
			this.buffer = ""
		}
		else{


@@ 82,10 83,13 @@ function Emu ()
			this.uxn.wst.addr = val ? val * 0x100 : 0x10000
		}
		else if(port == 0x18) {
			this.console.send(val)
			this.console.write(val)
		}
		else if(port == 0x19) {
			this.console.error(val)
		}
		else if(port == 0x0f) {
			console.warn("Program ended.")
			// console.warn("Program ended.")
		}
		else {
			console.log("Unknown deo", port, val)

A src/programs.js => src/programs.js +216 -0
@@ 0,0 1,216 @@
const hello_tal= `@program

	;hello-word
	&while
		( send ) LDAk #18 DEO
		( loop ) INC2 LDAk ?&while
	POP2

BRK

@hello-word "Hello 20 "World! 0a00`

const drifloon_rom = new Uint8Array([
	0xa0, 0x01, 0x07, 0x80, 0x10, 0x37, 0x00, 0x80, 
	0x12, 0x16, 0x06, 0xa0, 0x07, 0xaf, 0x15, 0xa0, 
	0x01, 0x0c, 0xb4, 0x21, 0x24, 0x35, 0x80, 0x0a, 
	0x09, 0x20, 0x00, 0x06, 0x60, 0x00, 0x85, 0x60, 
	0x03, 0xb9, 0x00, 0xa0, 0x0a, 0x19, 0x17, 0xa0, 
	0x06, 0x79, 0x60, 0x04, 0x10, 0x60, 0x04, 0x0d, 
	0xa0, 0x20, 0x19, 0x17, 0x60, 0x04, 0x06, 0xa0, 
	0x06, 0x55, 0x60, 0x04, 0x00, 0xa0, 0x07, 0x6f, 
	0x60, 0x03, 0xfa, 0xa0, 0x06, 0x5c, 0x60, 0x03, 
	0xf4, 0xa0, 0x01, 0x0f, 0x17, 0x00, 0xa0, 0x07, 
	0xaf, 0x94, 0x60, 0x00, 0x07, 0x21, 0x94, 0x20, 
	0xff, 0xf7, 0x22, 0x6c, 0x80, 0x20, 0x8a, 0x03, 
	0x20, 0x00, 0x0a, 0x02, 0xa0, 0x07, 0x4f, 0x94, 
	0x20, 0x00, 0x12, 0x22, 0x6c, 0xa0, 0x07, 0x4f, 
	0x26, 0x60, 0x03, 0xf0, 0xa0, 0x00, 0x1f, 0x2b, 
	0x20, 0x03, 0xde, 0x02, 0x6c, 0x26, 0x60, 0x00, 
	0x03, 0x40, 0x04, 0x02, 0x94, 0x80, 0x28, 0x08, 
	0x20, 0x00, 0x0f, 0x94, 0x80, 0x29, 0x08, 0x20, 
	0x00, 0x08, 0x80, 0x00, 0x20, 0x00, 0x0b, 0x40, 
	0x00, 0x35, 0x14, 0x80, 0x28, 0x08, 0x80, 0xf2, 
	0x13, 0x6c, 0x22, 0x6c, 0xa0, 0x01, 0x00, 0x60, 
	0x03, 0x2c, 0xa0, 0x06, 0x48, 0xa0, 0x07, 0x6f, 
	0x60, 0x03, 0xbb, 0x60, 0xff, 0x98, 0xa0, 0x01, 
	0x00, 0x60, 0x03, 0x1a, 0xa0, 0x06, 0x48, 0xa0, 
	0x07, 0x6f, 0x60, 0x03, 0xa9, 0x80, 0x00, 0xa0, 
	0x03, 0x13, 0x15, 0x60, 0xff, 0x80, 0x6c, 0x94, 
	0x80, 0x08, 0x13, 0xa0, 0x07, 0x4f, 0xa0, 0x07, 
	0x1f, 0x94, 0x80, 0x00, 0x09, 0x20, 0x00, 0x04, 
	0x23, 0x21, 0x34, 0x2c, 0xa0, 0x00, 0x03, 0x38, 
	0xaa, 0x20, 0xff, 0xed, 0x22, 0x22, 0x26, 0x60, 
	0x02, 0x28, 0x20, 0x00, 0x87, 0x26, 0x60, 0x02, 
	0x36, 0x20, 0x00, 0x87, 0x60, 0x00, 0x62, 0x6c, 
	0x21, 0x60, 0x01, 0x38, 0x60, 0x00, 0x84, 0x40, 
	0x02, 0xcc, 0x21, 0x60, 0x01, 0x2e, 0x40, 0x00, 
	0x9b, 0x21, 0xa0, 0x07, 0x6f, 0x27, 0x24, 0x60, 
	0x03, 0x54, 0x40, 0x01, 0x96, 0x21, 0x60, 0x01, 
	0xe3, 0x40, 0x01, 0x8f, 0x80, 0x80, 0x60, 0x00, 
	0xdc, 0x21, 0x60, 0x01, 0x4b, 0x60, 0x01, 0x1c, 
	0x01, 0x40, 0x00, 0xd1, 0x80, 0x80, 0x60, 0x00, 
	0xcc, 0x21, 0x60, 0x01, 0x3b, 0x34, 0x03, 0x40, 
	0x00, 0xc3, 0x80, 0xa0, 0x60, 0x00, 0xbe, 0x21, 
	0x60, 0x01, 0x2d, 0x34, 0x40, 0x00, 0xb2, 0x80, 
	0x20, 0x60, 0x00, 0xb1, 0x21, 0x40, 0x00, 0x73, 
	0x80, 0x40, 0x60, 0x00, 0xa8, 0x21, 0x40, 0x00, 
	0x6a, 0x80, 0x60, 0x60, 0x00, 0x9f, 0x40, 0x00, 
	0x62, 0x21, 0x26, 0x60, 0x02, 0xf6, 0x03, 0x80, 
	0x02, 0x1f, 0xa0, 0xa0, 0x80, 0x05, 0x0c, 0x04, 
	0x02, 0x60, 0x00, 0x89, 0x40, 0x00, 0x5a, 0x21, 
	0x40, 0x00, 0x3d, 0x60, 0x01, 0xb3, 0x40, 0x00, 
	0x7c, 0x22, 0x6c, 0xa0, 0x03, 0x09, 0x34, 0xab, 
	0x20, 0x00, 0x06, 0xb9, 0x60, 0x00, 0x15, 0x22, 
	0x6c, 0x27, 0xa0, 0x01, 0x00, 0x2b, 0x20, 0x00, 
	0x09, 0xa0, 0x07, 0x4f, 0xa0, 0x06, 0xb5, 0x40, 
	0xfe, 0x79, 0x22, 0x6c, 0xa0, 0x00, 0x00, 0xa8, 
	0x20, 0x00, 0x0a, 0x80, 0x00, 0x60, 0x00, 0x4d, 
	0x21, 0xaa, 0x20, 0xff, 0xf6, 0x22, 0x22, 0x6c, 
	0x94, 0x60, 0x00, 0x41, 0x21, 0x94, 0x20, 0xff, 
	0xf7, 0x22, 0x6c, 0x60, 0x00, 0xaa, 0x34, 0xa0, 
	0x03, 0x09, 0x34, 0x21, 0x21, 0x39, 0x40, 0x00, 
	0x28, 0x26, 0x60, 0x02, 0x87, 0x27, 0x60, 0x00, 
	0x5b, 0x24, 0x03, 0x06, 0x80, 0x02, 0x08, 0x20, 
	0x00, 0x0f, 0x06, 0x80, 0x04, 0x08, 0x20, 0x00, 
	0x0e, 0x02, 0x22, 0xa0, 0x06, 0x8e, 0x40, 0xfe, 
	0x2a, 0x02, 0x23, 0x03, 0x40, 0x00, 0x06, 0x02, 
	0x23, 0x04, 0x60, 0x00, 0x00, 0x80, 0x23, 0x13, 
	0xa0, 0x01, 0x00, 0xa0, 0x01, 0x00, 0x2b, 0x20, 
	0x00, 0x15, 0x80, 0x01, 0x20, 0x00, 0x13, 0xa0, 
	0x00, 0x00, 0x80, 0xec, 0x32, 0x2b, 0x20, 0x00, 
	0x06, 0x80, 0x07, 0x12, 0x80, 0x18, 0x17, 0x40, 
	0x01, 0xa7, 0x80, 0x00, 0x80, 0x00, 0x08, 0x20, 
	0x00, 0x07, 0x80, 0xd4, 0x32, 0xa0, 0x03, 0x18, 
	0x35, 0x40, 0x01, 0x95, 0x26, 0x60, 0x00, 0xda, 
	0x20, 0x00, 0x06, 0xa0, 0x06, 0x8e, 0x40, 0xfd, 
	0xda, 0x40, 0x02, 0x9e, 0xa0, 0x03, 0x13, 0x14, 
	0x20, 0x00, 0x21, 0xb4, 0xa0, 0x03, 0x09, 0x34, 
	0x39, 0xa0, 0x00, 0x03, 0x39, 0x26, 0xa0, 0x00, 
	0x80, 0x38, 0x02, 0x20, 0x00, 0x03, 0x23, 0x03, 
	0x6c, 0x22, 0xa0, 0x00, 0x03, 0x38, 0xa0, 0x06, 
	0x9f, 0x40, 0xfd, 0xaf, 0x22, 0x80, 0xff, 0x6c, 
	0xa0, 0x03, 0x13, 0x14, 0x80, 0x00, 0x08, 0x20, 
	0x00, 0x05, 0x22, 0xa0, 0x03, 0xa9, 0x6c, 0x94, 
	0x80, 0x26, 0x09, 0x20, 0x00, 0x04, 0x21, 0x60, 
	0x00, 0x72, 0x60, 0x01, 0x15, 0xa1, 0x1d, 0x20, 
	0x00, 0x07, 0x22, 0xa0, 0x06, 0x95, 0x40, 0xfd, 
	0x82, 0xa1, 0x21, 0x94, 0x01, 0x05, 0x05, 0x15, 
	0x6c, 0xff, 0xff, 0x5b, 0x65, 0x6d, 0x70, 0x74, 
	0x79, 0x5d, 0x00, 0xa0, 0x03, 0x13, 0x14, 0x80, 
	0x00, 0x08, 0x20, 0x00, 0x45, 0x26, 0x60, 0x00, 
	0x59, 0x20, 0x00, 0x32, 0x26, 0x60, 0x00, 0x67, 
	0x20, 0x00, 0x2b, 0x26, 0x60, 0x00, 0xdb, 0x21, 
	0x1d, 0x20, 0x00, 0x28, 0xa0, 0x03, 0x09, 0x34, 
	0xa0, 0x47, 0xaf, 0xaf, 0x35, 0x61, 0x61, 0x61, 
	0x26, 0xef, 0x60, 0x01, 0x89, 0x60, 0x01, 0x7c, 
	0x6f, 0x38, 0x21, 0x80, 0xeb, 0x33, 0xa0, 0x00, 
	0x00, 0x21, 0x80, 0xfa, 0x33, 0x6c, 0xa0, 0x06, 
	0xa8, 0x40, 0xfd, 0x27, 0xa0, 0x06, 0x84, 0x40, 
	0xfd, 0x21, 0x22, 0x6c, 0xa0, 0x07, 0x6f, 0xa0, 
	0x07, 0x8f, 0xaf, 0x60, 0x01, 0x60, 0x80, 0x2f, 
	0xef, 0x60, 0x01, 0x45, 0xef, 0x60, 0x01, 0x53, 
	0x6f, 0x6c, 0x94, 0x60, 0x01, 0xb6, 0x01, 0x20, 
	0x00, 0x04, 0x22, 0x80, 0x00, 0x6c, 0x21, 0x94, 
	0x20, 0xff, 0xef, 0x22, 0x80, 0x01, 0x6c, 0x26, 
	0xa0, 0x07, 0x1c, 0x60, 0x01, 0x8f, 0x20, 0x00, 
	0x32, 0x2f, 0xa0, 0x20, 0x00, 0x80, 0x00, 0x07, 
	0x80, 0x03, 0x1a, 0xa0, 0x06, 0xbc, 0x38, 0xef, 
	0x60, 0x01, 0x7a, 0x20, 0x00, 0x0a, 0x01, 0x8a, 
	0x20, 0xff, 0xea, 0x22, 0x62, 0x80, 0x00, 0x6c, 
	0x03, 0x06, 0x80, 0x00, 0x08, 0x80, 0x70, 0x1f, 
	0x18, 0x6f, 0xa0, 0x00, 0x03, 0x38, 0x60, 0x00, 
	0x06, 0x18, 0x6c, 0x22, 0x80, 0x01, 0x6c, 0xc0, 
	0x00, 0x94, 0x80, 0x20, 0x07, 0x80, 0x32, 0x08, 
	0x20, 0x00, 0x24, 0x06, 0x18, 0x07, 0x80, 0x72, 
	0x08, 0x20, 0x00, 0x1b, 0x06, 0x18, 0x07, 0x80, 
	0x6b, 0x08, 0x20, 0x00, 0x12, 0x06, 0x18, 0x07, 
	0x80, 0x21, 0x0b, 0x20, 0x00, 0x09, 0xa0, 0x07, 
	0x4f, 0xa0, 0x06, 0xb0, 0x40, 0xfc, 0x84, 0x03, 
	0x0f, 0x5d, 0x21, 0x94, 0x20, 0xff, 0xca, 0x22, 
	0x4f, 0x6c, 0x2f, 0xa0, 0x47, 0xaf, 0xa0, 0x00, 
	0x03, 0x38, 0x26, 0xef, 0x60, 0x00, 0xf5, 0x20, 
	0x00, 0x11, 0x60, 0x00, 0x91, 0x21, 0xa1, 0x21, 
	0x21, 0x14, 0x20, 0xff, 0xe9, 0x22, 0x62, 0xa0, 
	0xff, 0xff, 0x6c, 0xa0, 0x00, 0x03, 0x39, 0x62, 
	0x6c, 0xa0, 0x03, 0x09, 0x34, 0x21, 0xa0, 0x03, 
	0x09, 0x35, 0x6c, 0xa0, 0x47, 0xaf, 0xa1, 0x21, 
	0x21, 0x14, 0x06, 0x80, 0x40, 0x0a, 0x04, 0x80, 
	0x5b, 0x0b, 0x1c, 0x20, 0x00, 0x18, 0xa1, 0x21, 
	0x14, 0x20, 0x00, 0x12, 0xa0, 0x06, 0x67, 0x60, 
	0x00, 0x43, 0xa0, 0x00, 0x03, 0x38, 0x26, 0x60, 
	0x00, 0x3b, 0xa0, 0x0a, 0x19, 0x17, 0x60, 0x00, 
	0x45, 0x21, 0xa1, 0x21, 0x21, 0x14, 0x20, 0xff, 
	0xcd, 0x22, 0xa0, 0x06, 0x3d, 0x60, 0x00, 0x25, 
	0xa0, 0x03, 0x18, 0x34, 0xa0, 0x00, 0xff, 0x39, 
	0x60, 0x00, 0xdd, 0xa0, 0x06, 0x4d, 0x60, 0x00, 
	0x14, 0xa0, 0x03, 0xef, 0x34, 0x60, 0x00, 0xd0, 
	0xa0, 0x06, 0x5f, 0x60, 0x00, 0x07, 0xa0, 0x06, 
	0x5b, 0x60, 0x00, 0x01, 0x6c, 0x94, 0x20, 0x00, 
	0x02, 0x22, 0x6c, 0x94, 0x80, 0x19, 0x17, 0x21, 
	0x94, 0x20, 0xff, 0xf7, 0x22, 0x6c, 0x94, 0x20, 
	0x00, 0x01, 0x6c, 0x21, 0x94, 0x20, 0xff, 0xfb, 
	0x6c, 0x60, 0xff, 0xf2, 0xa1, 0x80, 0x00, 0x05, 
	0x05, 0x15, 0x15, 0x6c, 0x26, 0x60, 0xff, 0xe6, 
	0x24, 0x39, 0x6c, 0x60, 0xff, 0xe0, 0x27, 0x14, 
	0x20, 0x00, 0x03, 0x22, 0x22, 0x6c, 0x2f, 0x94, 
	0xef, 0x15, 0x61, 0x21, 0x94, 0x20, 0xff, 0xf7, 
	0x22, 0x80, 0x00, 0x6f, 0x15, 0x6c, 0x94, 0x20, 
	0x00, 0x02, 0x22, 0x6c, 0xaf, 0x80, 0x00, 0x6f, 
	0x15, 0x21, 0x94, 0x20, 0xff, 0xf6, 0x22, 0x6c, 
	0x07, 0x80, 0x21, 0x0b, 0x20, 0x00, 0x09, 0x80, 
	0x00, 0x04, 0x60, 0xff, 0xb4, 0x80, 0x00, 0x6c, 
	0x22, 0x80, 0x01, 0x6c, 0x2f, 0x94, 0xd4, 0x4f, 
	0x9c, 0x80, 0x00, 0x08, 0x20, 0x00, 0x0a, 0x89, 
	0x20, 0x00, 0x06, 0x22, 0x21, 0x61, 0x40, 0xff, 
	0xec, 0x23, 0x62, 0x08, 0x6c, 0xb4, 0x25, 0xb4, 
	0x25, 0x28, 0x0f, 0x21, 0x34, 0x24, 0x21, 0x34, 
	0x28, 0x4f, 0x1c, 0x6c, 0x80, 0x30, 0x19, 0x06, 
	0x80, 0x09, 0x0a, 0x0c, 0x6c, 0x80, 0x27, 0x19, 
	0x06, 0x80, 0x0f, 0x0a, 0x0c, 0x6c, 0x02, 0x80, 
	0xff, 0x6c, 0xe0, 0x00, 0x00, 0xc0, 0x40, 0x7f, 
	0xc0, 0x00, 0x94, 0x60, 0xff, 0xde, 0x0f, 0x78, 
	0x21, 0x94, 0x20, 0xff, 0xf0, 0x22, 0x6f, 0x6c, 
	0x80, 0x00, 0x80, 0x23, 0x13, 0xa0, 0x27, 0x10, 
	0x60, 0x00, 0x1a, 0xa0, 0x03, 0xe8, 0x60, 0x00, 
	0x14, 0xa0, 0x00, 0x64, 0x60, 0x00, 0x0e, 0xa0, 
	0x00, 0x0a, 0x60, 0x00, 0x08, 0x03, 0x80, 0x30, 
	0x18, 0x80, 0x19, 0x17, 0x6c, 0xbb, 0x86, 0x80, 
	0x00, 0x08, 0x20, 0x00, 0x0c, 0x06, 0x80, 0x30, 
	0x18, 0x80, 0x19, 0x17, 0x80, 0xff, 0x80, 0xef, 
	0x13, 0x02, 0x3a, 0x39, 0x6c, 0x41, 0x73, 0x73, 
	0x65, 0x6d, 0x62, 0x6c, 0x65, 0x64, 0x20, 0x00, 
	0x49, 0x4e, 0x49, 0x54, 0x00, 0x20, 0x62, 0x79, 
	0x74, 0x65, 0x73, 0x28, 0x00, 0x2c, 0x20, 0x69, 
	0x6e, 0x20, 0x00, 0x29, 0x2e, 0x0a, 0x00, 0x20, 
	0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x00, 0x2d, 
	0x2d, 0x20, 0x55, 0x6e, 0x75, 0x73, 0x65, 0x64, 
	0x20, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x3a, 0x20, 
	0x00, 0x21, 0x21, 0x20, 0x45, 0x72, 0x72, 0x6f, 
	0x72, 0x3a, 0x20, 0x00, 0x44, 0x75, 0x70, 0x6c, 
	0x69, 0x63, 0x61, 0x74, 0x65, 0x00, 0x4e, 0x75, 
	0x6d, 0x62, 0x65, 0x72, 0x00, 0x52, 0x65, 0x66, 
	0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x00, 0x44, 
	0x69, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x00, 
	0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x00, 
	0x4d, 0x6f, 0x64, 0x65, 0x00, 0x52, 0x65, 0x77, 
	0x69, 0x6e, 0x64, 0x00, 0x4c, 0x49, 0x54, 0x49, 
	0x4e, 0x43, 0x50, 0x4f, 0x50, 0x4e, 0x49, 0x50, 
	0x53, 0x57, 0x50, 0x52, 0x4f, 0x54, 0x44, 0x55, 
	0x50, 0x4f, 0x56, 0x52, 0x45, 0x51, 0x55, 0x4e, 
	0x45, 0x51, 0x47, 0x54, 0x48, 0x4c, 0x54, 0x48, 
	0x4a, 0x4d, 0x50, 0x4a, 0x43, 0x4e, 0x4a, 0x53, 
	0x52, 0x53, 0x54, 0x48, 0x4c, 0x44, 0x5a, 0x53, 
	0x54, 0x5a, 0x4c, 0x44, 0x52, 0x53, 0x54, 0x52, 
	0x4c, 0x44, 0x41, 0x53, 0x54, 0x41, 0x44, 0x45, 
	0x49, 0x44, 0x45, 0x4f, 0x41, 0x44, 0x44, 0x53, 
	0x55, 0x42, 0x4d, 0x55, 0x4c, 0x44, 0x49, 0x56, 
	0x41, 0x4e, 0x44, 0x4f, 0x52, 0x41, 0x45, 0x4f, 
	0x52, 0x53, 0x46, 0x54, 0x42, 0x52, 0x4b, 0x7c, 
	0x02, 0x00, 0x24, 0x02, 0x0a, 0x40, 0x02, 0x11, 
	0x26, 0x02, 0x1d, 0x2c, 0x02, 0x24, 0x5f, 0x02, 
	0x29, 0x2e, 0x02, 0x34, 0x2d, 0x02, 0x39, 0x3b, 
	0x02, 0x42, 0x3d, 0x02, 0x47, 0x3f, 0x02, 0x4f, 
	0x21, 0x02, 0x58, 0x5b, 0x02, 0x89, 0x5d, 0x02, 
	0x89, 0x23, 0x02, 0x69, 0x22, 0x02, 0x7f, 0x00, 
	0x00])