From 9b62da6567993734d02f619019f4da0fd9ca3a49 Mon Sep 17 00:00:00 2001 From: Seth Morabito Date: Thu, 15 Sep 2022 07:05:18 -0700 Subject: [PATCH] 3B2-700 Initial Public Release This commit introduces dozens of changes to make the 3B2-700 simulator fully functional and ready for wider use. In addition to 3B2-700 availability, this commit includes a tremendous amount of refactoring of the 3B2-400 and common code to make the project structure easier to maintain and reason about. One final important change: ROM files are no longer included in the source code. 3B2 ROM images must be obtained separately and loaded into the simulator before boot. Changes: - The 3b2 target has been aliased to 3b2-400 - The formerly named 3b2-600 project has become 3b2-700 - SCSI QIC tape support has been added to sim_scsi.c - Header files have been reworked to reduce complexity of includes - Common code has been consolidated - Timer code has been unified --- 3B2/3b2_cpu.c | 9009 +++++++++-------- 3B2/3b2_cpu.h | 1350 +-- 3B2/3b2_csr.h | 90 +- 3B2/3b2_ctc.c | 1656 ++- 3B2/3b2_ctc.h | 306 +- 3B2/3b2_defs.h | 330 +- 3B2/3b2_dmac.c | 949 +- 3B2/3b2_dmac.h | 173 +- 3B2/3b2_id.c | 1996 ++-- 3B2/3b2_id.h | 356 +- 3B2/3b2_if.c | 1285 +-- 3B2/3b2_if.h | 262 +- 3B2/3b2_io.c | 1558 ++- 3B2/3b2_io.h | 523 +- 3B2/3b2_iu.c | 2192 ++-- 3B2/3b2_iu.h | 448 +- 3B2/{3b2_rev2_mau.c => 3b2_mau.c} | 7192 +++++++------ 3B2/3b2_mau.h | 426 +- 3B2/3b2_mem.c | 670 +- 3B2/3b2_mem.h | 141 +- 3B2/3b2_mmu.h | 80 +- 3B2/3b2_ni.c | 2412 ++--- 3B2/3b2_ni.h | 424 +- 3B2/3b2_ports.c | 1827 ++-- 3B2/3b2_ports.h | 459 +- 3B2/3b2_rev2_csr.c | 368 +- 3B2/3b2_rev2_csr.h | 92 +- 3B2/3b2_rev2_defs.h | 264 +- 3B2/3b2_rev2_mau.h | 383 - 3B2/3b2_rev2_mmu.c | 1648 ++- 3B2/3b2_rev2_mmu.h | 741 +- 3B2/3b2_rev2_sys.c | 164 +- 3B2/3b2_rev2_timer.c | 401 - 3B2/3b2_rev2_timer.h | 72 - 3B2/3b2_rev3_csr.c | 592 +- 3B2/3b2_rev3_csr.h | 90 +- 3B2/3b2_rev3_defs.h | 290 +- 3B2/3b2_rev3_mau.c | 31 - 3B2/3b2_rev3_mau.h | 36 - 3B2/3b2_rev3_mmu.c | 2387 +++-- 3B2/3b2_rev3_mmu.h | 714 +- 3B2/3b2_rev3_sys.c | 160 +- 3B2/3b2_rev3_timer.h | 79 - 3B2/3b2_scsi.c | 2920 +++--- 3B2/3b2_scsi.h | 548 +- 3B2/3b2_stddev.c | 1358 ++- 3B2/3b2_stddev.h | 220 +- 3B2/3b2_sys.c | 352 +- 3B2/3b2_sys.h | 92 +- 3B2/{3b2_rev3_timer.c => 3b2_timer.c} | 1012 +- 3B2/3b2_timer.h | 120 +- 3B2/README.md | 264 +- 3B2/rom_rev2.bin | Bin 32768 -> 0 bytes 3B2/rom_rev2_bin.h | 2081 ---- 3B2/rom_rev2_demon.bin | Bin 65536 -> 0 bytes 3B2/rom_rev2_demon_bin.h | 4129 -------- 3B2/rom_rev3.bin | Bin 131072 -> 0 bytes 3B2/rom_rev3_bin.h | 8225 --------------- 3B2/tests/3b2_test.ini | 34 - 3B2/tests/rev2_diags.dsk | Bin 737280 -> 0 bytes .../{3B2.vcproj => 3B2-400.vcproj} | 82 +- .../{3B2-600.vcproj => 3B2-700.vcproj} | 66 +- Visual Studio Projects/Simh.sln | 4 +- makefile | 57 +- sim_BuildROMs.c | 3 - sim_scsi.c | 107 +- sim_scsi.h | 5 +- 67 files changed, 26013 insertions(+), 40292 deletions(-) rename 3B2/{3b2_rev2_mau.c => 3b2_mau.c} (91%) delete mode 100644 3B2/3b2_rev2_mau.h delete mode 100644 3B2/3b2_rev2_timer.c delete mode 100644 3B2/3b2_rev2_timer.h delete mode 100644 3B2/3b2_rev3_mau.c delete mode 100644 3B2/3b2_rev3_mau.h delete mode 100644 3B2/3b2_rev3_timer.h rename 3B2/{3b2_rev3_timer.c => 3b2_timer.c} (55%) delete mode 100644 3B2/rom_rev2.bin delete mode 100644 3B2/rom_rev2_bin.h delete mode 100644 3B2/rom_rev2_demon.bin delete mode 100644 3B2/rom_rev2_demon_bin.h delete mode 100644 3B2/rom_rev3.bin delete mode 100644 3B2/rom_rev3_bin.h delete mode 100644 3B2/tests/3b2_test.ini delete mode 100644 3B2/tests/rev2_diags.dsk rename Visual Studio Projects/{3B2.vcproj => 3B2-400.vcproj} (90%) rename Visual Studio Projects/{3B2-600.vcproj => 3B2-700.vcproj} (90%) diff --git a/3B2/3b2_cpu.c b/3B2/3b2_cpu.c index c7799d14..516e78cb 100644 --- a/3B2/3b2_cpu.c +++ b/3B2/3b2_cpu.c @@ -1,4131 +1,4878 @@ -/* 3b2_cpu.c: AT&T 3B2 CPU (WE32100 and WE32200) Implementation - - Copyright (c) 2017, Seth J. Morabito - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - - Except as contained in this notice, the name of the author shall - not be used in advertising or otherwise to promote the sale, use or - other dealings in this Software without prior written authorization - from the author. -*/ - -/* - * This is an implementation of the WE32100 and WE32200 CPUs, used in - * the Rev 2 (e.g. 3B2/400) and Rev 3 (e.g. 3B2/600G) AT&T 3B2 - * systems, respectively. - * - * The WE32000 series of microprocessors were a fully 32-bit general - * purpose CISC architecture purposely designed to run UNIX. - * - * The architecture is fully described in the following books: - * - * - "WE 32100 Microprocessor Information Manual" (AT&T, 1985) - * - "WE 32200 Microprocessor Information Manual" (AT&T, 1988) - * - */ - -#include "3b2_cpu.h" - -#if defined(REV3) -#include "rom_rev3_bin.h" -#include "3b2_if.h" -#define ROM_ARRAY BOOT_CODE_ARRAY -#define ROM_SIZE BOOT_CODE_SIZE -#else -#include "rom_rev2_bin.h" -#include "rom_rev2_demon_bin.h" -#include "3b2_id.h" -#define ROM_ARRAY BOOT_CODE_ARRAY_1 -#define ROM_SIZE BOOT_CODE_SIZE_1 -#define DEMON_ROM_ARRAY BOOT_CODE_ARRAY_2 -#define DEMON_ROM_SIZE BOOT_CODE_SIZE_2 -#endif /* defined(REV3) */ - -#include "3b2_csr.h" -#include "3b2_dmac.h" -#include "3b2_io.h" -#include "3b2_iu.h" -#include "3b2_mau.h" -#include "3b2_mem.h" -#include "3b2_mmu.h" -#include "3b2_stddev.h" -#include "3b2_timer.h" - -#define MAX_SUB_RETURN_SKIP 9 - -uint32 rom_size = 0; - -/* Static function declarations */ -static uint32 cpu_effective_address(operand * op); -static uint32 cpu_read_op(operand * op); -static void cpu_write_op(operand * op, t_uint64 val); -static void cpu_set_nz_flags(t_uint64 data, operand * op); -static SIM_INLINE void cpu_on_normal_exception(uint8 isc); -static SIM_INLINE void cpu_on_stack_exception(uint8 isc); -static SIM_INLINE void cpu_on_process_exception(uint8 isc); -static SIM_INLINE void cpu_on_reset_exception(uint8 isc); -static SIM_INLINE void cpu_perform_gate(uint32 index1, uint32 index2); -static SIM_INLINE void clear_instruction(instr *inst); -static SIM_INLINE int8 op_type(operand *op); -static SIM_INLINE t_bool op_signed(operand *op); -static SIM_INLINE uint32 sign_extend_b(uint8 val); -static SIM_INLINE uint32 sign_extend_h(uint16 val); -static SIM_INLINE t_bool cpu_z_flag(); -static SIM_INLINE t_bool cpu_n_flag(); -static SIM_INLINE t_bool cpu_c_flag(); -static SIM_INLINE t_bool cpu_v_flag(); -static SIM_INLINE void cpu_set_z_flag(t_bool val); -static SIM_INLINE void cpu_set_n_flag(t_bool val); -static SIM_INLINE void cpu_set_c_flag(t_bool val); -static SIM_INLINE void cpu_set_v_flag(t_bool val); -static SIM_INLINE void cpu_set_v_flag_op(t_uint64 val, operand *op); -static SIM_INLINE uint8 cpu_execution_level(); -static SIM_INLINE void cpu_push_word(uint32 val); -static SIM_INLINE uint32 cpu_pop_word(); -static SIM_INLINE void irq_push_word(uint32 val); -static SIM_INLINE uint32 irq_pop_word(); -static SIM_INLINE void cpu_context_switch_1(uint32 pcbp); -static SIM_INLINE void cpu_context_switch_2(uint32 pcbp); -static SIM_INLINE void cpu_context_switch_3(uint32 pcbp); -static SIM_INLINE t_bool op_is_psw(operand *op); -static SIM_INLINE void add(t_uint64 a, t_uint64 b, operand *dst); -static SIM_INLINE void sub(t_uint64 a, t_uint64 b, operand *dst); - -/* RO memory. */ -uint32 *ROM = NULL; - -/* Main memory. */ -uint32 *RAM = NULL; - -/* Save environment for setjmp/longjmp */ -jmp_buf save_env; -volatile uint32 abort_context; - -/* Pointer to the last decoded instruction */ -instr *cpu_instr; - -/* The instruction to use if there is no history storage */ -instr inst; - -/* Circular buffer of instructions */ -instr *INST = NULL; -uint32 cpu_hist_size = 0; -uint32 cpu_hist_p = 0; - -t_bool cpu_in_wait = FALSE; - -volatile size_t cpu_exception_stack_depth = 0; -volatile int32 stop_reason; -volatile uint32 abort_reason; - -/* Register data */ -uint32 R[NUM_REGISTERS]; - -/* Other global CPU state */ - -/* Interrupt request bitfield */ -/* Note: Only the lowest 8 bits are used by Rev 2, and only the lowest - 12 bits are used by Rev 3 */ -uint16 sbd_int_req = 0; /* Currently set interrupt sources */ -uint8 int_map[INT_MAP_LEN]; /* Map of interrupt sources to highest - priority IPL */ -t_bool cpu_nmi = FALSE; /* If set, there has been an NMI */ -int32 pc_incr = 0; /* Length (in bytes) of instruction - currently being executed */ -t_bool cpu_ex_halt = FALSE; /* Flag to halt on exceptions / traps */ -t_bool cpu_km = FALSE; /* If true, kernel mode has been forced - for memory access */ -CTAB sys_cmd[] = { - { "BOOT", &sys_boot, RU_BOOT, - "bo{ot} boot simulator\n", NULL, &run_cmd_message }, - { NULL } -}; - -BITFIELD psw_bits[] = { - BITFFMT(ET,2,%d), /* Exception Type */ - BIT(TM), /* Trace Mask */ - BITFFMT(ISC,4,%d), /* Internal State Code */ - BIT(I), /* Register Initial Context (I) */ - BIT(R), /* Register Initial Context (R) */ - BITFFMT(PM,2,%d), /* Previous Execution Level */ - BITFFMT(CM,2,%d), /* Current Execution Level */ - BITFFMT(IPL,4,%d), /* Interrupt Priority Level */ - BIT(TE), /* Trace Enable */ - BIT(C), /* Carry */ - BIT(V), /* Overflow */ - BIT(Z), /* Zero */ - BIT(N), /* Negative */ - BIT(OE), /* Enable Overflow Trap */ - BIT(CD), /* Cache Disable */ - BIT(QIE), /* Quick-Interrupt Enable */ - BIT(CFD), /* Cache Flush Disable */ -#if defined(REV3) - BIT(X), /* Extend Carry / Borrow */ - BIT(AR), /* Additional Register Save */ - BIT(EXUC), /* Exception/User Call Option */ - BIT(EA), /* Enable Arbitrary Alignment */ - BITNCF(2), /* Unused */ -#else - BITNCF(6), /* Unused */ -#endif - ENDBITS -}; - -BITFIELD sbd_int_req_bits[] = { -#if defined(REV3) - BIT(CLOK), /* UNIX Interval Timer */ - BIT(PWRD), /* Power Down Request */ - BIT(BUSO), /* UBUS or BUB Operational Interrupt */ - BIT(SBER), /* Single Bit Memory Error */ - BIT(MBER), /* Multiple Bit Memory Error */ - BIT(BRXF), /* UBUS, BUB, EIO Bus Received Fail */ - BIT(BTMO), /* UBUS Timer Timeout */ - BIT(UDMA), /* UART DMA Complete */ - BIT(UART), /* UART Interrupt */ - BIT(FDMA), /* Floppy DMA Complete */ - BIT(FLOP), /* Floppy Interrupt */ - BIT(PIR9), /* PIR 9 */ - BIT(PIR8), /* PIR 8 */ - BITNCF(3), /* Unused */ - ENDBITS -#else - BIT(SERR), /* System Error */ - BIT(CLOK), /* UNIX Interval Timer */ - BIT(DMAC), /* DMA Complete */ - BIT(UART), /* UART */ - BIT(DISK), /* Integrated Disk Drive (Winchester) */ - BIT(FLOP), /* Integrated Floppy Drive */ - BIT(PIR9), /* PIR 9 */ - BIT(PIR8), /* PIR 8 */ - BITNCF(8), /* Unused */ - ENDBITS -#endif -}; - -/* Registers. */ -REG cpu_reg[] = { - { HRDATAD (R0, R[0], 32, "General purpose register 0") }, - { HRDATAD (R1, R[1], 32, "General purpose register 1") }, - { HRDATAD (R2, R[2], 32, "General purpose register 2") }, - { HRDATAD (R3, R[3], 32, "General purpose register 3") }, - { HRDATAD (R4, R[4], 32, "General purpose register 4") }, - { HRDATAD (R5, R[5], 32, "General purpose register 5") }, - { HRDATAD (R6, R[6], 32, "General purpose register 6") }, - { HRDATAD (R7, R[7], 32, "General purpose register 7") }, - { HRDATAD (R8, R[8], 32, "General purpose register 8") }, - { HRDATAD (FP, R[NUM_FP], 32, "Frame Pointer") }, - { HRDATAD (AP, R[NUM_AP], 32, "Argument Pointer") }, - { HRDATADF (PSW, R[NUM_PSW], 32, "Processor Status Word", psw_bits) }, - { HRDATAD (SP, R[NUM_SP], 32, "Stack Pointer") }, - { HRDATAD (PCBP, R[NUM_PCBP], 32, "Process Control Block Pointer") }, - { HRDATAD (ISP, R[NUM_ISP], 32, "Interrupt Stack Pointer") }, - { HRDATAD (PC, R[NUM_PC], 32, "Program Counter") }, -#if defined(REV3) - { HRDATAD (R16, R[16], 32, "General purpose register 16")}, - { HRDATAD (R17, R[17], 32, "General purpose register 17")}, - { HRDATAD (R18, R[18], 32, "General purpose register 18")}, - { HRDATAD (R19, R[19], 32, "General purpose register 19")}, - { HRDATAD (R20, R[20], 32, "General purpose register 20")}, - { HRDATAD (R21, R[21], 32, "General purpose register 21")}, - { HRDATAD (R22, R[22], 32, "General purpose register 22")}, - { HRDATAD (R23, R[23], 32, "General purpose register 23")}, - { HRDATAD (R24, R[24], 32, "Privileged register 24")}, - { HRDATAD (R25, R[25], 32, "Privileged register 25")}, - { HRDATAD (R26, R[26], 32, "Privileged register 26")}, - { HRDATAD (R27, R[27], 32, "Privileged register 27")}, - { HRDATAD (R28, R[28], 32, "Privileged register 28")}, - { HRDATAD (R29, R[29], 32, "Privileged register 29")}, - { HRDATAD (R30, R[30], 32, "Privileged register 30")}, - { HRDATAD (R31, R[31], 32, "Privileged register 31")}, -#endif - { HRDATADF (SBD_INT, sbd_int_req, 16, "Interrupt Requests", sbd_int_req_bits) }, - { NULL } -}; - -static DEBTAB cpu_deb_tab[] = { - { "READ", READ_MSG, "Memory read activity" }, - { "WRITE", WRITE_MSG, "Memory write activity" }, - { "DECODE", DECODE_MSG, "Instruction decode" }, - { "EXECUTE", EXECUTE_MSG, "Instruction execute" }, - { "INIT", INIT_MSG, "Initialization" }, - { "IRQ", IRQ_MSG, "Interrupt Handling" }, - { "IO", IO_DBG, "I/O Dispatch" }, - { "CIO", CIO_DBG, "Common I/O Interface" }, - { "TRACE", TRACE_DBG, "Call Trace" }, - { "ERROR", ERR_MSG, "Error" }, - { NULL, 0, NULL } -}; - -UNIT cpu_unit = { - UDATA (NULL, UNIT_FIX|UNIT_BINK|UNIT_IDLE, DEFMEMSIZE) -}; - -/* - * The following commands deposit a small calibration program into - * mainstore at 0x2000000 and then set the program counter to the - * start address. Simulator calibration will execute this program to - * establish a baseline execution rate. - * - * Program: - * 84 01 46 MOVW &0x1,%r6 - * 84 46 47 MOVW %r6,%r7 - * 84 47 48 MOVW %r7,%r8 - * 90 48 INCW %r8 - * 28 48 TSTW %r8 - * 4f 0b BLEB 0xb - * e4 07 48 40 MODW3 &0x7,%r8,%r0 - * 84 40 47 MOVW %r0,%r7 - * 7b 0b BRB 0xb - * 8c 48 40 MNEGW %r8,%r0 - * a4 07 40 MODW2 &0x7,%r0 - * 84 40 47 MOVW %r0,%r7 - * e8 47 48 40 MULW3 %r7,%r8,%r0 - * 9c 07 40 ADDW2 &0x7,%r0 - * 84 40 46 MOVW %r0,%r6 - * 28 48 TSTW %r8 - * 4f 05 BLEB 0x5 - * a8 03 47 MULW2 &0x3,%r7 - * d0 01 46 46 LLSW3 &0x1,%r6,%r6 - * 28 46 TSTW %r6 - * 4f 09 BLEB 0x9 - * ec 46 47 40 DIVW3 %r6,%r7,%r0 - * 84 40 48 MOVW %r0,%r8 - * d4 01 47 47 LRSW3 &0x1,%r7,%r7 - * 3c 48 47 CMPW %r8,%r7 - * 4f 05 BLEB 0x5 - * bc 48 47 SUBW2 %r8,%r7 - * 7b bc BRB -0x44 - */ -static const char *att3b2_clock_precalibrate_commands[] = { - "-v 2000000 84014684", - "-v 2000004 46478447", - "-v 2000008 48904828", - "-v 200000c 484f0be4", - "-v 2000010 07484084", - "-v 2000014 40477b0b", - "-v 2000018 8c4840a4", - "-v 200001c 07408440", - "-v 2000020 47e84748", - "-v 2000024 409c0740", - "-v 2000028 84404628", - "-v 200002c 484f05a8", - "-v 2000030 0347d001", - "-v 2000034 46462846", - "-v 2000038 4f09ec46", - "-v 200003c 47408440", - "-v 2000040 48d40147", - "-v 2000044 473c4847", - "-v 2000048 4f05bc48", - "-v 200004c 477bbc00", - "PC 2000000", - NULL -}; - -CONST cio_device cio_entries[] = { - {0x0001, "SBD"}, /* System Board */ - {0x0002, "NI"}, /* Network Interface Card (ethernet) */ - {0x0003, "PORTS"}, /* Serial I/O Card */ - {0x0005, "CTC"}, /* Cartridge Tape Controller */ - {0x0100, "SCSI"}, /* SCSI disk and tape controller */ - {0} /* END */ -}; - -MTAB cpu_mod[] = { -#if defined(REV2) - { UNIT_MSIZE, (1u << 20), NULL, "1M", - &cpu_set_size, NULL, NULL, "Set Memory to 1M bytes" }, - { UNIT_MSIZE, (1u << 21), NULL, "2M", - &cpu_set_size, NULL, NULL, "Set Memory to 2M bytes" }, - { UNIT_MSIZE, (1u << 22), NULL, "4M", - &cpu_set_size, NULL, NULL, "Set Memory to 4M bytes" }, -#endif -#if defined(REV3) - { UNIT_MSIZE, (1u << 23), NULL, "8M", - &cpu_set_size, NULL, NULL, "Set Memory to 8M bytes" }, - { UNIT_MSIZE, (1u << 24), NULL, "16M", - &cpu_set_size, NULL, NULL, "Set Memory to 16M bytes" }, - { UNIT_MSIZE, (1u << 25), NULL, "32M", - &cpu_set_size, NULL, NULL, "Set Memory to 32M bytes" }, - { UNIT_MSIZE, (1u << 26), NULL, "64M", - &cpu_set_size, NULL, NULL, "Set Memory to 64M bytes" }, -#endif - { MTAB_XTD|MTAB_VDV|MTAB_NMO|MTAB_SHP, 0, "HISTORY", "HISTORY", - &cpu_set_hist, &cpu_show_hist, NULL, "Displays instruction history" }, - { MTAB_XTD|MTAB_VDV|MTAB_NMO|MTAB_SHP, 0, "VIRTUAL", NULL, - NULL, &cpu_show_virt, NULL, "Show translation for virtual address" }, - { MTAB_XTD|MTAB_VDV|MTAB_NMO|MTAB_SHP, 0, "STACK", NULL, - NULL, &cpu_show_stack, NULL, "Display the current stack with optional depth" }, - { MTAB_XTD|MTAB_VDV|MTAB_NMO, 0, "CIO", NULL, - NULL, &cpu_show_cio, NULL, "Display CIO configuration" }, - { MTAB_XTD|MTAB_VDV, 0, "IDLE", "IDLE", &sim_set_idle, &sim_show_idle }, - { MTAB_XTD|MTAB_VDV, 0, NULL, "NOIDLE", &sim_clr_idle, NULL }, - { UNIT_EXBRK, UNIT_EXBRK, "Break on exceptions", "EXBRK", - NULL, NULL, NULL, "Enable break on exceptions and traps" }, - { UNIT_EXBRK, 0, "No break on exceptions", "NOEXBRK", - NULL, NULL, NULL, "Disable break on exceptions and traps" }, - { UNIT_OPBRK, UNIT_OPBRK, "Break on invalid opcodes", "OPBRK", - NULL, NULL, NULL, "Enable break on invalid opcodes" }, - { UNIT_OPBRK, 0, "No break on invalid opcodes", "NOOPBRK", - NULL, NULL, NULL, "Disable break on invalid opcodes" }, - { 0 } -}; - -DEVICE cpu_dev = { - "CPU", /* Name */ - &cpu_unit, /* Units */ - cpu_reg, /* Registers */ - cpu_mod, /* Modifiers */ - 1, /* Number of Units */ - 16, /* Address radix */ - 32, /* Address width */ - 1, /* Addr increment */ - 16, /* Data radix */ - 8, /* Data width */ - &cpu_ex, /* Examine routine */ - &cpu_dep, /* Deposit routine */ - &cpu_reset, /* Reset routine */ - &cpu_boot, /* Boot routine */ - NULL, /* Attach routine */ - NULL, /* Detach routine */ - NULL, /* Context */ - DEV_DYNM|DEV_DEBUG, /* Flags */ - 0, /* Debug control flags */ - cpu_deb_tab, /* Debug flag names */ - &cpu_set_size, /* Memory size change */ - NULL, /* Logical names */ - &cpu_help, /* Help routine */ - NULL, /* Attach Help Routine */ - NULL, /* Help Context */ - &cpu_description /* Device Description */ -}; - -mnemonic hword_ops[HWORD_OP_COUNT] = { - {0x3009, 0, OP_NONE, NA, "MVERNO", -1, -1, -1, -1}, - {0x300d, 0, OP_NONE, NA, "ENBVJMP", -1, -1, -1, -1}, - {0x3013, 0, OP_NONE, NA, "DISVJMP", -1, -1, -1, -1}, - {0x3019, 0, OP_NONE, NA, "MOVBLW", -1, -1, -1, -1}, - {0x301f, 0, OP_NONE, NA, "STREND", -1, -1, -1, -1}, - {0x302f, 1, OP_DESC, WD, "INTACK", -1, -1, -1, -1}, - {0x3035, 0, OP_NONE, NA, "STRCPY", -1, -1, -1, -1}, - {0x3045, 0, OP_NONE, NA, "RETG", -1, -1, -1, -1}, - {0x3061, 0, OP_NONE, NA, "GATE", -1, -1, -1, -1}, - {0x30ac, 0, OP_NONE, NA, "CALLPS", -1, -1, -1, -1}, -#if defined(REV3) - {0x30c0, 0, OP_NONE, NA, "UCALLPS", -1, -1, -1, -1}, -#endif - {0x30c8, 0, OP_NONE, NA, "RETPS", -1, -1, -1, -1} -}; - -/* Lookup table of operand types. */ -mnemonic ops[256] = { - {0x00, 0, OP_NONE, NA, "halt", -1, -1, -1, -1}, - {0x01, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0x02, 2, OP_COPR, WD, "SPOPRD", 1, -1, -1, -1}, - {0x03, 3, OP_COPR, WD, "SPOPD2", 1, -1, -1, 2}, - {0x04, 2, OP_DESC, WD, "MOVAW", 0, -1, -1, 1}, - {0x05, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0x06, 2, OP_COPR, WD, "SPOPRT", 1, -1, -1, -1}, - {0x07, 3, OP_COPR, WD, "SPOPT2", 1, -1, -1, 2}, - {0x08, 0, OP_NONE, NA, "RET", -1, -1, -1, -1}, -#if defined(REV3) - {0x09, 3, OP_DESC, WD, "CASWI", 0, 1, -1, 2}, -#else - {0x09, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, -#endif - {0x0a, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0x0b, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0x0c, 2, OP_DESC, WD, "MOVTRW", 0, -1, -1, 1}, - {0x0d, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0x0e, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0x0f, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0x10, 1, OP_DESC, WD, "SAVE", 0, -1, -1, -1}, - {0x11, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0x12, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0x13, 2, OP_COPR, WD, "SPOPWD", -1, -1, -1, 1}, - {0x14, 1, OP_BYTE, NA, "EXTOP", -1, -1, -1, -1}, - {0x15, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0x16, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0x17, 2, OP_COPR, WD, "SPOPWT", -1, -1, -1, 1}, - {0x18, 1, OP_DESC, WD, "RESTORE", 0, -1, -1, -1}, - {0x19, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0x1a, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0x1b, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0x1c, 1, OP_DESC, WD, "SWAPWI", -1, -1, -1, 0}, /* 3-122 252 */ - {0x1d, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0x1e, 1, OP_DESC, HW, "SWAPHI", -1, -1, -1, 0}, /* 3-122 252 */ - {0x1f, 1, OP_DESC, BT, "SWAPBI", -1, -1, -1, 0}, /* 3-122 252 */ - {0x20, 1, OP_DESC, WD, "POPW", -1, -1, -1, 0}, - {0x21, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0x22, 2, OP_COPR, WD, "SPOPRS", 1, -1, -1, -1}, - {0x23, 3, OP_COPR, WD, "SPOPS2", 1, -1, -1, 2}, - {0x24, 1, OP_DESC, NA, "JMP", -1, -1, -1, 0}, - {0x25, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0x26, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0x27, 0, OP_NONE, NA, "CFLUSH", -1, -1, -1, -1}, - {0x28, 1, OP_DESC, WD, "TSTW", 0, -1, -1, -1}, - {0x29, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0x2a, 1, OP_DESC, HW, "TSTH", 0, -1, -1, -1}, - {0x2b, 1, OP_DESC, BT, "TSTB", 0, -1, -1, -1}, - {0x2c, 2, OP_DESC, WD, "CALL", 0, -1, -1, 1}, - {0x2d, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0x2e, 0, OP_NONE, NA, "BPT", -1, -1, -1, -1}, - {0x2f, 0, OP_NONE, NA, "WAIT", -1, -1, -1, -1}, - {0x30, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, /* Two-byte instructions */ - {0x31, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0x32, 1, OP_COPR, WD, "SPOP", -1, -1, -1, -1}, - {0x33, 2, OP_COPR, WD, "SPOPWS", -1, -1, -1, 1}, - {0x34, 1, OP_DESC, WD, "JSB", -1, -1, -1, 0}, - {0x35, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0x36, 1, OP_HALF, NA, "BSBH", -1, -1, -1, 0}, - {0x37, 1, OP_BYTE, NA, "BSBB", -1, -1, -1, 0}, - {0x38, 2, OP_DESC, WD, "BITW", 0, 1, -1, -1}, - {0x39, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0x3a, 2, OP_DESC, HW, "BITH", 0, 1, -1, -1}, - {0x3b, 2, OP_DESC, BT, "BITB", 0, 1, -1, -1}, - {0x3c, 2, OP_DESC, WD, "CMPW", 0, 1, -1, -1}, - {0x3d, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0x3e, 2, OP_DESC, HW, "CMPH", 0, 1, -1, -1}, - {0x3f, 2, OP_DESC, BT, "CMPB", 0, 1, -1, -1}, - {0x40, 0, OP_NONE, NA, "RGEQ", -1, -1, -1, -1}, - {0x41, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0x42, 1, OP_HALF, NA, "BGEH", -1, -1, -1, 0}, - {0x43, 1, OP_BYTE, NA, "BGEB", -1, -1, -1, 0}, - {0x44, 0, OP_NONE, NA, "RGTR", -1, -1, -1, -1}, - {0x45, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0x46, 1, OP_HALF, NA, "BGH", -1, -1, -1, 0}, - {0x47, 1, OP_BYTE, NA, "BGB", -1, -1, -1, 0}, - {0x48, 0, OP_NONE, NA, "RLSS", -1, -1, -1, 0}, - {0x49, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0x4a, 1, OP_HALF, NA, "BLH", -1, -1, -1, 0}, - {0x4b, 1, OP_BYTE, NA, "BLB", -1, -1, -1, 0}, - {0x4c, 0, OP_NONE, NA, "RLEQ", -1, -1, -1, -1}, - {0x4d, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0x4e, 1, OP_HALF, NA, "BLEH", -1, -1, -1, 0}, - {0x4f, 1, OP_BYTE, NA, "BLEB", -1, -1, -1, 0}, - {0x50, 0, OP_NONE, NA, "BGEQU", -1, -1, -1, 0}, /* aka BCC */ - {0x51, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0x52, 1, OP_HALF, NA, "BGEUH", -1, -1, -1, 0}, /* aka BCCH */ - {0x53, 1, OP_BYTE, NA, "BGEUB", -1, -1, -1, 0}, /* aka BCCB */ - {0x54, 0, OP_NONE, NA, "RGTRU", -1, -1, -1, -1}, - {0x55, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0x56, 1, OP_HALF, NA, "BGUH", -1, -1, -1, 0}, - {0x57, 1, OP_BYTE, NA, "BGUB", -1, -1, -1, 0}, - {0x58, 0, OP_NONE, NA, "RLSSU", -1, -1, -1, 0}, /* aka BCS */ - {0x59, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0x5a, 1, OP_HALF, NA, "BLUH", -1, -1, -1, 0}, /* aka BCSH */ - {0x5b, 1, OP_BYTE, NA, "BLUB", -1, -1, -1, 0}, /* aka BCSB */ - {0x5c, 0, OP_NONE, NA, "RLEQU", -1, -1, -1, -1}, - {0x5d, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0x5e, 1, OP_HALF, NA, "BLEUH", -1, -1, -1, 0}, - {0x5f, 1, OP_BYTE, NA, "BLEUB", -1, -1, -1, 0}, - {0x60, 0, OP_NONE, NA, "RVC", -1, -1, -1, -1}, - {0x61, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0x62, 1, OP_HALF, NA, "BVCH", -1, -1, -1, 0}, - {0x63, 1, OP_BYTE, NA, "BVCB", -1, -1, -1, 0}, - {0x64, 0, OP_NONE, NA, "RNEQU", -1, -1, -1, -1}, - {0x65, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0x66, 1, OP_HALF, NA, "BNEH", -1, -1, -1, 0}, /* duplicate of 76 */ - {0x67, 1, OP_BYTE, NA, "BNEB", -1, -1, -1, 0}, /* duplicate of 77*/ - {0x68, 0, OP_NONE, NA, "RVS", -1, -1, -1, -1}, - {0x69, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0x6a, 1, OP_HALF, NA, "BVSH", -1, -1, -1, 0}, - {0x6b, 1, OP_BYTE, NA, "BVSB", -1, -1, -1, 0}, - {0x6c, 0, OP_NONE, NA, "REQLU", -1, -1, -1, -1}, - {0x6d, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0x6e, 1, OP_HALF, NA, "BEH", -1, -1, -1, 0}, /* duplicate of 7e */ - {0x6f, 1, OP_BYTE, NA, "BEB", -1, -1, -1, 0}, /* duplicate of 7f */ - {0x70, 0, OP_NONE, NA, "NOP", -1, -1, -1, -1}, - {0x71, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0x72, 0, OP_NONE, NA, "NOP3", -1, -1, -1, -1}, - {0x73, 0, OP_NONE, NA, "NOP2", -1, -1, -1, -1}, - {0x74, 0, OP_NONE, NA, "RNEQ", -1, -1, -1, -1}, - {0x75, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0x76, 1, OP_HALF, NA, "BNEH", -1, -1, -1, 0}, /* duplicate of 66 */ - {0x77, 1, OP_BYTE, NA, "BNEB", -1, -1, -1, 0}, /* duplicate of 67 */ - {0x78, 0, OP_NONE, NA, "RSB", -1, -1, -1, -1}, - {0x79, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0x7a, 1, OP_HALF, NA, "BRH", -1, -1, -1, 0}, - {0x7b, 1, OP_BYTE, NA, "BRB", -1, -1, -1, 0}, - {0x7c, 0, OP_NONE, NA, "REQL", -1, -1, -1, -1}, - {0x7d, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0x7e, 1, OP_HALF, NA, "BEH", -1, -1, -1, 0}, /* duplicate of 6e */ - {0x7f, 1, OP_BYTE, NA, "BEB", -1, -1, -1, 0}, /* duplicate of 6f */ - {0x80, 1, OP_DESC, WD, "CLRW", -1, -1, -1, 0}, - {0x81, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0x82, 1, OP_DESC, HW, "CLRH", -1, -1, -1, 0}, - {0x83, 1, OP_DESC, BT, "CLRB", -1, -1, -1, 0}, - {0x84, 2, OP_DESC, WD, "MOVW", 0, -1, -1, 1}, - {0x85, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0x86, 2, OP_DESC, HW, "MOVH", 0, -1, -1, 1}, - {0x87, 2, OP_DESC, BT, "MOVB", 0, -1, -1, 1}, - {0x88, 2, OP_DESC, WD, "MCOMW", 0, -1, -1, 1}, - {0x89, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0x8a, 2, OP_DESC, HW, "MCOMH", 0, -1, -1, 1}, - {0x8b, 2, OP_DESC, BT, "MCOMB", 0, -1, -1, 1}, - {0x8c, 2, OP_DESC, WD, "MNEGW", 0, -1, -1, 1}, - {0x8d, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0x8e, 2, OP_DESC, HW, "MNEGH", 0, -1, -1, 1}, - {0x8f, 2, OP_DESC, BT, "MNEGB", 0, -1, -1, 1}, - {0x90, 1, OP_DESC, WD, "INCW", -1, -1, -1, 0}, - {0x91, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0x92, 1, OP_DESC, HW, "INCH", -1, -1, -1, 0}, - {0x93, 1, OP_DESC, BT, "INCB", -1, -1, -1, 0}, - {0x94, 1, OP_DESC, WD, "DECW", -1, -1, -1, 0}, - {0x95, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0x96, 1, OP_DESC, HW, "DECH", -1, -1, -1, 0}, - {0x97, 1, OP_DESC, BT, "DECB", -1, -1, -1, 0}, - {0x98, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0x99, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0x9a, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0x9b, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0x9c, 2, OP_DESC, WD, "ADDW2", 0, -1, -1, 1}, - {0x9d, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0x9e, 2, OP_DESC, HW, "ADDH2", 0, -1, -1, 1}, - {0x9f, 2, OP_DESC, BT, "ADDB2", 0, -1, -1, 1}, - {0xa0, 1, OP_DESC, WD, "PUSHW", 0, -1, -1, -1}, - {0xa1, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0xa2, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0xa3, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0xa4, 2, OP_DESC, WD, "MODW2", 0, -1, -1, 1}, - {0xa5, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0xa6, 2, OP_DESC, HW, "MODH2", 0, -1, -1, 1}, - {0xa7, 2, OP_DESC, BT, "MODB2", 0, -1, -1, 1}, - {0xa8, 2, OP_DESC, WD, "MULW2", 0, -1, -1, 1}, - {0xa9, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0xaa, 2, OP_DESC, HW, "MULH2", 0, -1, -1, 1}, - {0xab, 2, OP_DESC, BT, "MULB2", 0, -1, -1, 1}, - {0xac, 2, OP_DESC, WD, "DIVW2", 0, -1, -1, 1}, - {0xad, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0xae, 2, OP_DESC, HW, "DIVH2", 0, -1, -1, 1}, - {0xaf, 2, OP_DESC, BT, "DIVB2", 0, -1, -1, 1}, - {0xb0, 2, OP_DESC, WD, "ORW2", 0, -1, -1, 1}, - {0xb1, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0xb2, 2, OP_DESC, HW, "ORH2", 0, -1, -1, 1}, - {0xb3, 2, OP_DESC, BT, "ORB2", 0, -1, -1, 1}, - {0xb4, 2, OP_DESC, WD, "XORW2", 0, -1, -1, 1}, - {0xb5, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0xb6, 2, OP_DESC, HW, "XORH2", 0, -1, -1, 1}, - {0xb7, 2, OP_DESC, BT, "XORB2", 0, -1, -1, 1}, - {0xb8, 2, OP_DESC, WD, "ANDW2", 0, -1, -1, 1}, - {0xb9, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0xba, 2, OP_DESC, HW, "ANDH2", 0, -1, -1, 1}, - {0xbb, 2, OP_DESC, BT, "ANDB2", 0, -1, -1, 1}, - {0xbc, 2, OP_DESC, WD, "SUBW2", 0, -1, -1, 1}, - {0xbd, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0xbe, 2, OP_DESC, HW, "SUBH2", 0, -1, -1, 1}, - {0xbf, 2, OP_DESC, BT, "SUBB2", 0, -1, -1, 1}, - {0xc0, 3, OP_DESC, WD, "ALSW3", 0, 1, -1, 2}, - {0xc1, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0xc2, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0xc3, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0xc4, 3, OP_DESC, WD, "ARSW3", 0, 1, -1, 2}, - {0xc5, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0xc6, 3, OP_DESC, HW, "ARSH3", 0, 1, -1, 2}, - {0xc7, 3, OP_DESC, BT, "ARSB3", 0, 1, -1, 2}, - {0xc8, 4, OP_DESC, WD, "INSFW", 0, 1, 2, 3}, - {0xc9, -1, OP_DESC, NA, "???", -1, -1, -1, -1}, - {0xca, 4, OP_DESC, HW, "INSFH", 0, 1, 2, 3}, - {0xcb, 4, OP_DESC, BT, "INSFB", 0, 1, 2, 3}, - {0xcc, 4, OP_DESC, WD, "EXTFW", 0, 1, 2, 3}, - {0xcd, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0xce, 4, OP_DESC, HW, "EXTFH", 0, 1, 2, 3}, - {0xcf, 4, OP_DESC, BT, "EXTFB", 0, 1, 2, 3}, - {0xd0, 3, OP_DESC, WD, "LLSW3", 0, 1, -1, 2}, - {0xd1, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0xd2, 3, OP_DESC, HW, "LLSH3", 0, 1, -1, 2}, - {0xd3, 3, OP_DESC, BT, "LLSB3", 0, 1, -1, 2}, - {0xd4, 3, OP_DESC, WD, "LRSW3", 0, 1, -1, 2}, - {0xd5, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0xd6, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0xd7, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0xd8, 3, OP_DESC, WD, "ROTW", 0, 1, -1, 2}, /* 3-108 238 */ - {0xd9, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0xda, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0xdb, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0xdc, 3, OP_DESC, WD, "ADDW3", 0, 1, -1, 2}, - {0xdd, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0xde, 3, OP_DESC, HW, "ADDH3", 0, 1, -1, 2}, - {0xdf, 3, OP_DESC, BT, "ADDB3", 0, 1, -1, 2}, - {0xe0, 1, OP_DESC, WD, "PUSHAW", 0, -1, -1, -1}, - {0xe1, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0xe2, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0xe3, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0xe4, 3, OP_DESC, WD, "MODW3", 0, 1, -1, 2}, - {0xe5, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0xe6, 3, OP_DESC, HW, "MODH3", 0, 1, -1, 2}, - {0xe7, 3, OP_DESC, BT, "MODB3", 0, 1, -1, 2}, - {0xe8, 3, OP_DESC, WD, "MULW3", 0, 1, -1, 2}, - {0xe9, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0xea, 3, OP_DESC, HW, "MULH3", 0, 1, -1, 2}, - {0xeb, 3, OP_DESC, BT, "MULB3", 0, 1, -1, 2}, - {0xec, 3, OP_DESC, WD, "DIVW3", 0, 1, -1, 2}, - {0xed, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0xee, 3, OP_DESC, HW, "DIVH3", 0, 1, -1, 2}, - {0xef, 3, OP_DESC, BT, "DIVB3", 0, 1, -1, 2}, - {0xf0, 3, OP_DESC, WD, "ORW3", 0, 1, -1, 2}, - {0xf1, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0xf2, 3, OP_DESC, HW, "ORH3", 0, 1, -1, 2}, - {0xf3, 3, OP_DESC, BT, "ORB3", 0, 1, -1, 2}, - {0xf4, 3, OP_DESC, WD, "XORW3", 0, 1, -1, 2}, - {0xf5, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0xf6, 3, OP_DESC, HW, "XORH3", 0, 1, -1, 2}, - {0xf7, 3, OP_DESC, BT, "XORB3", 0, 1, -1, 2}, - {0xf8, 3, OP_DESC, WD, "ANDW3", 0, 1, -1, 2}, - {0xf9, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0xfa, 3, OP_DESC, HW, "ANDH3", 0, 1, -1, 2}, - {0xfb, 3, OP_DESC, BT, "ANDB3", 0, 1, -1, 2}, - {0xfc, 3, OP_DESC, WD, "SUBW3", 0, 1, -1, 2}, - {0xfd, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, - {0xfe, 3, OP_DESC, HW, "SUBH3", 0, 1, -1, 2}, - {0xff, 3, OP_DESC, BT, "SUBB3", 0, 1, -1, 2} -}; - -/* from MAME (src/devices/cpu/m68000/m68kcpu.c) */ -const uint8 shift_8_table[65] = -{ - 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff -}; -const uint16 shift_16_table[65] = -{ - 0x0000, 0x8000, 0xc000, 0xe000, 0xf000, 0xf800, 0xfc00, 0xfe00, 0xff00, - 0xff80, 0xffc0, 0xffe0, 0xfff0, 0xfff8, 0xfffc, 0xfffe, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff -}; -const uint32 shift_32_table[65] = -{ - 0x00000000, 0x80000000, 0xc0000000, 0xe0000000, 0xf0000000, 0xf8000000, - 0xfc000000, 0xfe000000, 0xff000000, 0xff800000, 0xffc00000, 0xffe00000, - 0xfff00000, 0xfff80000, 0xfffc0000, 0xfffe0000, 0xffff0000, 0xffff8000, - 0xffffc000, 0xffffe000, 0xfffff000, 0xfffff800, 0xfffffc00, 0xfffffe00, - 0xffffff00, 0xffffff80, 0xffffffc0, 0xffffffe0, 0xfffffff0, 0xfffffff8, - 0xfffffffc, 0xfffffffe, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff -}; - -t_stat cpu_show_stack(FILE *st, UNIT *uptr, int32 val, CONST void *desc) -{ - uint32 i, j; - uint32 addr, v, count; - uint8 tmp; - char *cptr = (char *) desc; - t_stat result; - - if (cptr) { - count = (size_t) get_uint(cptr, 10, 128, &result); - if ((result != SCPE_OK) || (count == 0)) { - return SCPE_ARG; - } - } else { - count = 8; - } - - for (i = 0; i < (count * 4); i += 4) { - v = 0; - addr = R[NUM_SP] - i; - - for (j = 0; j < 4; j++) { - result = examine(addr + j, &tmp); - if (result != SCPE_OK) { - return result; - } - v |= (uint32) tmp << ((3 - j) * 8); - } - - fprintf(st, " %08x: %08x\n", addr, v); - } - - return SCPE_OK; -} - -t_stat cpu_show_cio(FILE *st, UNIT *uptr, int32 val, CONST void *desc) -{ - uint32 i, j; - - fprintf(st, " SLOT DEVICE\n"); - fprintf(st, "---------------------\n"); - for (i = 0; i < CIO_SLOTS; i++) { - /* Find the matching entry for this slot */ - for (j = 0; cio_entries[j].id != 0; j++) { - if (cio_entries[j].id == cio[i].id) { - break; - } - } - - if (cio_entries[j].id == 0) { - fprintf(st, " %d\n", i); - } else { - fprintf(st, " %d %s\n", i, cio_entries[j].name); - } - } - - return SCPE_OK; -} - -t_stat cpu_load_rom(uint8 *arrayp, uint32 len) -{ - uint32 i, index, sc, mask, val; - - /* Update global state */ - rom_size = len; - - if (ROM != NULL) { - free(ROM); - } - ROM = (uint32 *) calloc((size_t)(len >> 2), sizeof(uint32)); - if (ROM == NULL) { - return SCPE_MEM; - } - - for (i = 0; i < len; i++) { - val = arrayp[i]; - sc = (~(i & 3) << 3) & 0x1f; - mask = 0xffu << sc; - index = i >> 2; - - ROM[index] = (ROM[index] & ~mask) | (val << sc); - } - - return SCPE_OK; -} - -#if defined(REV3) -t_stat sys_boot(int32 flag, CONST char *ptr) -{ - char gbuf[CBUFSIZE]; - - if ((ptr = get_sim_sw(ptr)) == NULL) { - return SCPE_INVSW; - } - - get_glyph(ptr, gbuf, 0); - if (gbuf[0] && strcmp(gbuf, "CPU")) { - return SCPE_ARG; - } - - return run_cmd(flag, "CPU"); -} -#else -t_stat sys_boot(int32 flag, CONST char *ptr) -{ - char gbuf[CBUFSIZE] = { 0 }; - int gnum = 0; - uint8 *srcp = ROM_ARRAY; - uint32 len = ROM_SIZE; - t_stat r; - - if ((ptr = get_sim_sw(ptr)) == NULL) { - return SCPE_INVSW; - } - - do { - ptr = get_glyph(ptr, gbuf, 0); - - if (gbuf[0] && (strcmp(gbuf, "CPU") && strcmp(gbuf, "DEMON"))) { - return SCPE_ARG; - } - - if (strcmp(gbuf, "DEMON") == 0) { - srcp = DEMON_ROM_ARRAY; - len = DEMON_ROM_SIZE; - } - } while (gbuf[0]); - - if ((r = cpu_load_rom(srcp, len)) != SCPE_OK) { - return r; - } - - return run_cmd(flag, "CPU"); -} -#endif /* Rev 2 boot */ - -t_stat cpu_boot(int32 unit_num, DEVICE *dptr) -{ - /* - * page 2-52 (pdf page 85) - * - * 1. Change to physical address mode - * 2. Fetch the word at physical address 0x80 and store it in - * the PCBP register. - * 3. Fetch the word at the PCB address and store it in the - * PSW. - * 4. Fetch the word at PCB address + 4 bytes and store it - * in the PC. - * 5. Fetch the word at PCB address + 8 bytes and store it - * in the SP. - * 6. Fetch the word at PCB address + 12 bytes and store it - * in the PCB, if bit I in PSW is set. - */ - - sim_debug(EXECUTE_MSG, &cpu_dev, - "CPU Boot/Reset Initiated. PC=%08x SP=%08x\n", - R[NUM_PC], R[NUM_SP]); - - mmu_disable(); - - R[NUM_PCBP] = pread_w(0x80); - R[NUM_PSW] = pread_w(R[NUM_PCBP]); - R[NUM_PC] = pread_w(R[NUM_PCBP] + 4); - R[NUM_SP] = pread_w(R[NUM_PCBP] + 8); - - if (R[NUM_PSW] & PSW_I_MASK) { - R[NUM_PSW] &= ~PSW_I_MASK; - R[NUM_PCBP] += 12; - } - - /* set ISC to External Reset */ - R[NUM_PSW] &= ~PSW_ISC_MASK; - R[NUM_PSW] |= 3 << PSW_ISC ; - - return SCPE_OK; -} - -t_stat cpu_ex(t_value *vptr, t_addr addr, UNIT *uptr, int32 sw) -{ - uint32 uaddr = (uint32) addr; - uint8 value; - t_stat succ; - - if (vptr == NULL) { - return SCPE_ARG; - } - - if (sw & EX_V_FLAG) { - succ = examine(uaddr, &value); - *vptr = value; - return succ; - } else { - if (addr_is_rom(uaddr) || addr_is_mem(uaddr)) { - *vptr = (uint32) pread_b(uaddr); - return SCPE_OK; - } else { - *vptr = 0; - return SCPE_NXM; - } - } -} - -t_stat cpu_dep(t_value val, t_addr addr, UNIT *uptr, int32 sw) -{ - uint32 uaddr = (uint32) addr; - - if (sw & EX_V_FLAG) { - return deposit(uaddr, (uint8) val); - } else { - if (addr_is_mem(uaddr)) { - pwrite_b(uaddr, (uint8) val); - return SCPE_OK; - } else { - return SCPE_NXM; - } - } -} - -/* - * Pre-populate the interrupt->IPL map "int_map" - */ -static void build_int_map() -{ - int i; - uint8 ipl; - - for (i = 0; i < INT_MAP_LEN; i++) { -#if defined(REV3) - if (i & (INT_PWRDWN|INT_BUS_OP|INT_SBERR| - INT_MBERR|INT_BUS_RXF|INT_BUS_TMO| - INT_CLOCK)) { - ipl = CPU_IPL_15; - } else if (i & (INT_UART|INT_UART_DMA)) { - ipl = CPU_IPL_13; - } else if (i & (INT_FLOPPY|INT_FLOPPY_DMA)) { - ipl = CPU_IPL_11; - } else if (i & INT_PIR9) { - ipl = CPU_IPL_9; - } else if (i & INT_PIR8) { - ipl = CPU_IPL_8; - } else { - ipl = 0; - } -#else - if (i & (INT_CLOCK|INT_SERR)) { - ipl = CPU_IPL_15; - } else if (i & (INT_UART|INT_DMA)) { - ipl = CPU_IPL_13; - } else if (i & (INT_DISK|INT_FLOPPY)) { - ipl = CPU_IPL_11; - } else if (i & INT_PIR9) { - ipl = CPU_IPL_9; - } else if (i & INT_PIR8) { - ipl = CPU_IPL_8; - } else { - ipl = 0; - } -#endif - - int_map[i] = ipl; - } - - sim_debug(EXECUTE_MSG, &cpu_dev, - "Built interrupt->IPL map of length %d\n", INT_MAP_LEN); -} - -t_stat cpu_reset(DEVICE *dptr) -{ - int i; - t_stat r; - - /* Link in our special "boot" command so we can boot with both - * "BO{OT}" and "BO{OT} CPU" */ - sim_vm_cmd = sys_cmd; - - /* Set up the pre-calibration routine */ - sim_clock_precalibrate_commands = att3b2_clock_precalibrate_commands; - - /* Populate the interrupt->IPL map */ - build_int_map(); - - if (!sim_is_running) { - /* Clear registers */ - for (i = 0; i < NUM_REGISTERS; i++) { - R[i] = 0; - } - - /* Allocate ROM if needed */ - if (ROM == NULL) { - if ((r = cpu_load_rom(ROM_ARRAY, ROM_SIZE)) != SCPE_OK) { - return r; - } - } - - /* Always re-allocate RAM */ - if (RAM != NULL) { - free(RAM); - } - RAM = (uint32 *) calloc((size_t)(MEM_SIZE >> 2), sizeof(uint32)); - if (RAM == NULL) { - return SCPE_MEM; - } - - sim_vm_is_subroutine_call = cpu_is_pc_a_subroutine_call; - } - - abort_context = C_NONE; - cpu_nmi = FALSE; - - cpu_hist_p = 0; - cpu_in_wait = FALSE; - - sim_brk_types = SWMASK('E'); - sim_brk_dflt = SWMASK('E'); - - return SCPE_OK; -} - -static const char *cpu_next_caveats = -"The NEXT command in this 3B2 architecture simulator currently will\n" -"enable stepping across subroutine calls which are initiated by the\n" -"JSB, CALL and CALLPS instructions.\n" -"This stepping works by dynamically establishing breakpoints at the\n" -"memory address immediately following the instruction which initiated\n" -"the subroutine call. These dynamic breakpoints are automatically\n" -"removed once the simulator returns to the sim> prompt for any reason.\n" -"If the called routine returns somewhere other than one of these\n" -"locations due to a trap, stack unwind or any other reason, instruction\n" -"execution will continue until some other reason causes execution to stop.\n"; - -t_bool cpu_is_pc_a_subroutine_call (t_addr **ret_addrs) -{ - static t_addr returns[MAX_SUB_RETURN_SKIP+1] = {0}; - static t_bool caveats_displayed = FALSE; - int i; - - if (!caveats_displayed) { - caveats_displayed = TRUE; - sim_printf ("%s", cpu_next_caveats); - } - - /* get data */ - if (SCPE_OK != get_aval (R[NUM_PC], &cpu_dev, &cpu_unit)) { - return FALSE; - } - - switch (sim_eval[0]) { - case JSB: - case CALL: - case CALLPS: - returns[0] = R[NUM_PC] + (unsigned int) (1 - fprint_sym(stdnul, R[NUM_PC], - sim_eval, &cpu_unit, - SWMASK ('M'))); - for (i=1; imnemonic); - - for (i = 0; i < mn->op_count; i++) { - - /* Special cases for non-descriptor opcodes */ - if (mn->mode == OP_BYTE) { - mode = 6; - reg = 15; - } else if (mn->mode == OP_HALF) { - mode = 5; - reg = 15; - } else if (mn->mode == OP_COPR) { - mode = 4; - reg = 15; - } else { - desc = (uint8) val[vp++]; - mode = (desc >> 4) & 0xf; - reg = desc & 0xf; - - /* Find the expanded data type, if any */ - if (mode == 14 && - (reg == 0 || reg == 2 || reg == 3 || - reg == 4 || reg == 6 || reg == 7)) { - etype = reg; - /* The real descriptor byte lies one ahead */ - desc = (uint8) val[vp++]; - mode = (desc >> 4) & 0xf; - reg = desc & 0xf; - } - } - - fputc(i ? ',' : ' ', of); - - switch (etype) { - case 0: - fprintf(of, "{uword}"); - break; - case 2: - fprintf(of, "{uhalf}"); - break; - case 3: - fprintf(of, "{ubyte}"); - break; - case 4: - fprintf(of, "{word}"); - break; - case 6: - fprintf(of, "{half}"); - break; - case 7: - fprintf(of, "{sbyte}"); - break; - default: - /* do nothing */ - break; - } - - switch(mode) { - case 0: /* Positive Literal */ - case 1: /* Positive Literal */ - case 2: /* Positive Literal */ - case 3: /* Positive Literal */ - case 15: /* Negative Literal */ - fprintf(of, "&%d", desc); - break; - case 4: /* Halfword Immediate, Register Mode */ - switch (reg) { - case 15: /* Word Immediate */ - OP_R_W(w, val, vp); - fprintf(of, "&0x%x", w); - break; - default: /* Register Mode */ - cpu_register_name(reg, reg_name, 8); - fprintf(of, "%s", reg_name); - break; - } - break; - case 5: /* Halfword Immediate, Register Deferred */ - switch (reg) { - case 15: - OP_R_H(w, val, vp); - fprintf(of, "&0x%x", w); - break; - default: - cpu_register_name(reg, reg_name, 8); - fprintf(of, "(%s)", reg_name); - break; - } - break; - case 6: /* Byte Immediate, FP Short Offset */ - switch (reg) { - case 15: - OP_R_B(w, val, vp); - fprintf(of, "&0x%x", w); - break; - default: - fprintf(of, "%d(%%fp)", (int8) reg); - break; - } - break; - case 7: /* Absolute, AP Short Offset */ - switch (reg) { - case 15: - OP_R_W(w, val, vp); - fprintf(of, "$0x%x", w); - break; - default: - fprintf(of, "%d(%%ap)", (int8) reg); - break; - } - break; - case 8: /* Word Displacement */ - OP_R_W(w, val, vp); - cpu_register_name(reg, reg_name, 8); - fprintf(of, "0x%x(%s)", w, reg_name); - break; - case 9: /* Word Displacement Deferred */ - OP_R_W(w, val, vp); - cpu_register_name(reg, reg_name, 8); - fprintf(of, "*0x%x(%s)", w, reg_name); - break; - case 10: /* Halfword Displacement */ - OP_R_H(w, val, vp); - cpu_register_name(reg, reg_name, 8); - fprintf(of, "0x%x(%s)", w, reg_name); - break; - case 11: /* Halfword Displacement Deferred */ - OP_R_H(w, val, vp); - cpu_register_name(reg, reg_name, 8); - fprintf(of, "*0x%x(%s)", w, reg_name); - break; - case 12: /* Byte Displacement */ - OP_R_B(w, val, vp); - cpu_register_name(reg, reg_name, 8); - fprintf(of, "%d(%s)", (int8) w, reg_name); - break; - case 13: /* Byte Displacement Deferred */ - OP_R_B(w, val, vp); - cpu_register_name(reg, reg_name, 8); - fprintf(of, "*%d(%s)", (int8) w, reg_name); - break; - case 14: - if (reg == 15) { - OP_R_W(w, val, vp); - fprintf(of, "*$0x%x", w); - } - break; - default: - fprintf(of, ""); - break; - } - } - - - return -(vp - 1); -} - -void fprint_sym_hist(FILE *st, instr *ip) -{ - int32 i; - - if (ip == NULL || ip->mn == NULL) { - fprintf(st, "???"); - return; - } - - fprintf(st, "%s", ip->mn->mnemonic); - - if (ip->mn->op_count > 0) { - fputc(' ', st); - } - - /* Show the operand mnemonics */ - for (i = 0; i < ip->mn->op_count; i++) { - cpu_show_operand(st, &ip->operands[i]); - if (i < ip->mn->op_count - 1) { - fputc(',', st); - } - } -} - -t_stat cpu_show_virt(FILE *of, UNIT *uptr, int32 val, CONST void *desc) -{ - uint32 va, pa; - t_stat r; - - const char *cptr = (const char *)desc; - if (cptr) { - va = (uint32) get_uint(cptr, 16, 0xffffffff, &r); - if (r == SCPE_OK) { - r = mmu_decode_va(va, 0, FALSE, &pa); - if (r == SCPE_OK) { - fprintf(of, "Virtual %08x = Physical %08x\n", va, pa); - return SCPE_OK; - } else { - fprintf(of, "Translation not possible for virtual address.\n"); - return SCPE_ARG; - } - } else { - fprintf(of, "Illegal address format.\n"); - return SCPE_ARG; - } - } - - fprintf(of, "Address argument required.\n"); - return SCPE_ARG; -} - -t_stat cpu_set_hist(UNIT *uptr, int32 val, CONST char *cptr, void *desc) -{ - uint32 i, size; - t_stat result; - - /* Clear the history buffer if no argument */ - if (cptr == NULL) { - for (i = 0; i < cpu_hist_size; i++) { - INST[i].valid = FALSE; - } - return SCPE_OK; - } - - /* Otherwise, get the new length */ - size = (uint32) get_uint(cptr, 10, MAX_HIST_SIZE, &result); - - /* If no length was provided, give up */ - if (result != SCPE_OK) { - return SCPE_ARG; - } - - /* Legnth 0 is a special flag that means disable the feature. */ - if (size == 0) { - if (INST != NULL) { - for (i = 0; i < cpu_hist_size; i++) { - INST[i].valid = FALSE; - } - } - cpu_hist_size = 0; - cpu_hist_p = 0; - return SCPE_OK; - } - - /* Reinitialize the new history ring bufer */ - cpu_hist_p = 0; - if (size > 0) { - if (INST != NULL) { - free(INST); - } - INST = (instr *)calloc(size, sizeof(instr)); - if (INST == NULL) { - return SCPE_MEM; - } - memset(INST, 0, sizeof(instr) * size); - cpu_hist_size = size; - } - - return SCPE_OK; -} - -t_stat cpu_show_hist(FILE *st, UNIT *uptr, int32 val, CONST void *desc) -{ - uint32 i; - size_t j, count; - char *cptr = (char *) desc; - t_stat result; - instr *ip; - - int32 di; - - if (cpu_hist_size == 0) { - return SCPE_NOFNC; - } - - /* 'count' is the number of history entries the user wants */ - - if (cptr) { - count = (size_t) get_uint(cptr, 10, cpu_hist_size, &result); - if ((result != SCPE_OK) || (count == 0)) { - return SCPE_ARG; - } - } else { - count = cpu_hist_size; - } - - /* Position for reading from ring buffer */ - di = (int32) (cpu_hist_p - count); - - if (di < 0) { - di = di + (int32) cpu_hist_size; - } - - fprintf(st, "PSW SP PC IR\n"); - - for (i = 0; i < count; i++) { - ip = &INST[(di++) % (int32) cpu_hist_size]; - if (ip->valid) { - /* Show the opcode mnemonic */ - fprintf(st, "%08x %08x %08x ", ip->psw, ip->sp, ip->pc); - /* Show the operand data */ - if (ip->mn == NULL || ip->mn->op_count < 0) { - fprintf(st, "???"); - } else { - fprint_sym_hist(st, ip); - if (ip->mn->op_count > 0 && ip->mn->mode == OP_DESC) { - fprintf(st, "\n "); - for (j = 0; j < (uint32) ip->mn->op_count; j++) { - fprintf(st, "%08x", ip->operands[j].data); - if (j < (uint32) ip->mn->op_count - 1) { - fputc(' ', st); - } - } - } - } - fputc('\n', st); - } - } - - - return SCPE_OK; -} - -void cpu_register_name(uint8 reg, char *buf, size_t len) { - switch(reg) { - case 9: - snprintf(buf, len, "%%fp"); - break; - case 10: - snprintf(buf, len, "%%ap"); - break; - case 11: - snprintf(buf, len, "%%psw"); - break; - case 12: - snprintf(buf, len, "%%sp"); - break; - case 13: - snprintf(buf, len, "%%pcbp"); - break; - case 14: - snprintf(buf, len, "%%isp"); - break; - case 15: - snprintf(buf, len, "%%pc"); - break; - default: - snprintf(buf, len, "%%r%d", reg); - break; - } -} - -void cpu_show_operand(FILE *st, operand *op) -{ - char reg_name[8]; - - if (op->etype != -1) { - switch(op->etype) { - case 0: - fprintf(st, "{uword}"); - break; - case 2: - fprintf(st, "{uhalf}"); - break; - case 3: - fprintf(st, "{ubyte}"); - break; - case 4: - fprintf(st, "{word}"); - break; - case 6: - fprintf(st, "{half}"); - break; - case 7: - fprintf(st, "{sbyte}"); - break; - } - } - - switch(op->mode) { - case 0: - case 1: - case 2: - case 3: - fprintf(st, "&0x%x", op->embedded.b); - break; - case 4: - if (op->reg == 15) { - fprintf(st, "&0x%x", op->embedded.w); - } else { - cpu_register_name(op->reg, reg_name, 8); - fprintf(st, "%s", reg_name); - } - break; - case 5: - if (op->reg == 15) { - fprintf(st, "&0x%x", op->embedded.w); - } else { - cpu_register_name(op->reg, reg_name, 8); - fprintf(st, "(%s)", reg_name); - } - break; - case 6: /* FP Short Offset */ - if (op->reg == 15) { - fprintf(st, "&0x%x", op->embedded.w); - } else { - fprintf(st, "%d(%%fp)", op->reg); - } - break; - case 7: /* AP Short Offset */ - if (op->reg == 15) { - fprintf(st, "$0x%x", op->embedded.w); - } else { - fprintf(st, "%d(%%ap)", op->embedded.w); - } - break; - case 8: - cpu_register_name(op->reg, reg_name, 8); - fprintf(st, "0x%x(%s)", (int32)op->embedded.w, reg_name); - break; - case 9: - cpu_register_name(op->reg, reg_name, 8); - fprintf(st, "*0x%x(%s)", (int32)op->embedded.w, reg_name); - break; - case 10: - cpu_register_name(op->reg, reg_name, 8); - fprintf(st, "0x%x(%s)", (int16)op->embedded.w, reg_name); - break; - case 11: - cpu_register_name(op->reg, reg_name, 8); - fprintf(st, "*0x%x(%s)", (int16)op->embedded.w, reg_name); - break; - case 12: - cpu_register_name(op->reg, reg_name, 8); - fprintf(st, "%d(%s)", (int8)op->embedded.w, reg_name); - break; - case 13: - cpu_register_name(op->reg, reg_name, 8); - fprintf(st, "*%d(%s)", (int8)op->embedded.w, reg_name); - break; - case 14: - if (op->reg == 15) { - fprintf(st, "*$0x%x", op->embedded.w); - } - break; - case 15: - fprintf(st, "&0x%x", (int32)op->embedded.w); - break; - } -} - -t_stat cpu_set_size(UNIT *uptr, int32 val, CONST char *cptr, void *desc) -{ - uint32 *nRAM = NULL; - uint32 uval = (uint32) val; - - if ((val <= 0) || (val > MAXMEMSIZE)) { - return SCPE_ARG; - } - - /* Do (re-)allocation for memory. */ - - nRAM = (uint32 *) calloc(uval >> 2, sizeof(uint32)); - - if (nRAM == NULL) { - return SCPE_MEM; - } - - free(RAM); - RAM = nRAM; - - MEM_SIZE = uval; - - memset(RAM, 0, (size_t)(MEM_SIZE >> 2)); - - return SCPE_OK; -} - -static SIM_INLINE void clear_instruction(instr *inst) -{ - uint8 i; - - inst->mn = NULL; - inst->psw = 0; - inst->sp = 0; - inst->pc = 0; - - for (i = 0; i < 4; i++) { - inst->operands[i].mode = 0; - inst->operands[i].reg = 0; - inst->operands[i].dtype = -1; - inst->operands[i].etype = -1; - inst->operands[i].embedded.w = 0; - inst->operands[i].data = 0; - } -} - -/* - * Decode a single descriptor-defined operand from the instruction - * stream. Returns the number of bytes consumed during decode.type - */ -static uint8 decode_operand(uint32 pa, instr *instr, uint8 op_number, int8 *etype) -{ - uint8 desc; - uint8 offset = 0; - operand *oper = &instr->operands[op_number]; - - /* Read in the descriptor byte */ - desc = read_b(pa + offset++, ACC_IF); - - oper->mode = (desc >> 4) & 0xf; - oper->reg = desc & 0xf; - oper->dtype = instr->mn->dtype; - oper->etype = *etype; - - switch (oper->mode) { - case 0: /* Positive Literal */ - case 1: /* Positive Literal */ - case 2: /* Positive Literal */ - case 3: /* Positive Literal */ - case 15: /* Negative literal */ - oper->embedded.b = desc; - oper->data = oper->embedded.b; - break; - case 4: /* Word Immediate, Register Mode */ - switch (oper->reg) { - case 15: /* Word Immediate */ - oper->embedded.w = (uint32) read_b(pa + offset++, ACC_IF); - oper->embedded.w |= ((uint32) read_b(pa + offset++, ACC_IF)) << 8u; - oper->embedded.w |= ((uint32) read_b(pa + offset++, ACC_IF)) << 16u; - oper->embedded.w |= ((uint32) read_b(pa + offset++, ACC_IF)) << 24u; - oper->data = oper->embedded.w; - break; - default: /* Register mode */ - oper->data = R[oper->reg]; - break; - } - break; - case 5: /* Halfword Immediate, Register Deferred Mode */ - switch (oper->reg) { - case 15: /* Halfword Immediate */ - oper->embedded.h = (uint16) read_b(pa + offset++, ACC_IF); - oper->embedded.h |= ((uint16) read_b(pa + offset++, ACC_IF)) << 8u; - oper->data = oper->embedded.h; - break; - case 11: /* INVALID */ - cpu_abort(NORMAL_EXCEPTION, INVALID_DESCRIPTOR); - return offset; - default: /* Register deferred mode */ - oper->data = R[oper->reg]; - break; - } - break; - case 6: /* Byte Immediate, FP Short Offset */ - switch (oper->reg) { - case 15: /* Byte Immediate */ - oper->embedded.b = read_b(pa + offset++, ACC_IF); - oper->data = oper->embedded.b; - break; - default: /* FP Short Offset */ - oper->embedded.b = oper->reg; - oper->data = oper->embedded.b; - break; - } - break; - case 7: /* Absolute, AP Short Offset */ - switch (oper->reg) { - case 15: /* Absolute */ - oper->embedded.w = (uint32) read_b(pa + offset++, ACC_IF); - oper->embedded.w |= ((uint32) read_b(pa + offset++, ACC_IF)) << 8u; - oper->embedded.w |= ((uint32) read_b(pa + offset++, ACC_IF)) << 16u; - oper->embedded.w |= ((uint32) read_b(pa + offset++, ACC_IF)) << 24u; - oper->data = oper->embedded.w; - break; - default: /* AP Short Offset */ - oper->embedded.b = oper->reg; - oper->data = oper->embedded.b; - break; - } - break; - case 8: /* Word Displacement */ - case 9: /* Word Displacement Deferred */ - oper->embedded.w = (uint32) read_b(pa + offset++, ACC_IF); - oper->embedded.w |= ((uint32) read_b(pa + offset++, ACC_IF)) << 8u; - oper->embedded.w |= ((uint32) read_b(pa + offset++, ACC_IF)) << 16u; - oper->embedded.w |= ((uint32) read_b(pa + offset++, ACC_IF)) << 24u; - oper->data = oper->embedded.w; - break; - case 10: /* Halfword Displacement */ - case 11: /* Halfword Displacement Deferred */ - oper->embedded.h = read_b(pa + offset++, ACC_IF); - oper->embedded.h |= ((uint16) read_b(pa + offset++, ACC_IF)) << 8u; - oper->data = oper->embedded.h; - break; - case 12: /* Byte Displacement */ - case 13: /* Byte Displacement Deferred */ - oper->embedded.b = read_b(pa + offset++, ACC_IF); - oper->data = oper->embedded.b; - break; - case 14: /* Absolute Deferred, Extended-Operand */ - switch (oper->reg) { - case 15: /* Absolute Deferred */ - oper->embedded.w = (uint32) read_b(pa + offset++, ACC_IF); - oper->embedded.w |= ((uint32) read_b(pa + offset++, ACC_IF)) << 8u; - oper->embedded.w |= ((uint32) read_b(pa + offset++, ACC_IF)) << 16u; - oper->embedded.w |= ((uint32) read_b(pa + offset++, ACC_IF)) << 24u; - break; - case 0: - case 2: - case 3: - case 4: - case 6: - case 7: /* Expanded Datatype */ - /* Recursively decode the remainder of the operand after - storing the expanded datatype */ - *etype = (int8) oper->reg; - oper->etype = *etype; - offset += decode_operand(pa + offset, instr, op_number, etype); - break; - default: - cpu_abort(NORMAL_EXCEPTION, RESERVED_DATATYPE); - break; - } - break; - default: - cpu_abort(NORMAL_EXCEPTION, INVALID_DESCRIPTOR); - } - - return offset; -} - -/* - * Decode the instruction currently being pointed at by the PC. - * This routine does the following: - * 1. Read the opcode. - * 2. Determine the number of operands to decode based on - * the opcode type. - * 3. Fetch each opcode from main memory. - * - * This routine is guaranteed not to change state. - * - * returns: a Normal Exception if an error occured, or 0 on success. - */ -uint8 decode_instruction(instr *instr) -{ - uint8 offset = 0; - uint8 b1, b2; - uint16 hword_op; - uint32 pa; - mnemonic *mn = NULL; - int i; - int8 etype = -1; /* Expanded datatype (if any) */ - - clear_instruction(instr); - - pa = R[NUM_PC]; - - /* Store off the PC and and PSW for history keeping */ - instr->psw = R[NUM_PSW]; - instr->sp = R[NUM_SP]; - instr->pc = pa; - - if (read_operand(pa + offset++, &b1) != SCPE_OK) { - /* We tried to read out of a page that doesn't exist. We - need to let the operating system handle it.*/ - cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT); - return offset; - } - - /* It should never, ever happen that operand fetch - would cause a page fault. */ - - if (b1 == 0x30) { - read_operand(pa + offset++, &b2); - hword_op = (uint16) ((uint16)b1 << 8) | (uint16) b2; - for (i = 0; i < HWORD_OP_COUNT; i++) { - if (hword_ops[i].opcode == hword_op) { - mn = &hword_ops[i]; - break; - } - } - } else { - mn = &ops[b1]; - } - - if (mn == NULL) { - cpu_abort(NORMAL_EXCEPTION, ILLEGAL_OPCODE); - return offset; - } - - instr->mn = mn; - - if (mn->op_count < 0) { - cpu_abort(NORMAL_EXCEPTION, ILLEGAL_OPCODE); - return offset; - } - - if (mn->op_count == 0) { - /* Nothing else to do, we're done decoding. */ - return offset; - } - - switch (mn->mode) { - case OP_NONE: - break; - case OP_BYTE: - instr->operands[0].embedded.b = read_b(pa + offset++, ACC_IF); - instr->operands[0].mode = 6; - instr->operands[0].reg = 15; - break; - case OP_HALF: - instr->operands[0].embedded.h = read_b(pa + offset++, ACC_IF); - instr->operands[0].embedded.h |= read_b(pa + offset++, ACC_IF) << 8; - instr->operands[0].mode = 5; - instr->operands[0].reg = 15; - break; - case OP_COPR: - instr->operands[0].embedded.w = (uint32) read_b(pa + offset++, ACC_IF); - instr->operands[0].embedded.w |= (uint32) read_b(pa + offset++, ACC_IF) << 8; - instr->operands[0].embedded.w |= (uint32) read_b(pa + offset++, ACC_IF) << 16; - instr->operands[0].embedded.w |= (uint32) read_b(pa + offset++, ACC_IF) << 24; - instr->operands[0].mode = 4; - instr->operands[0].reg = 15; - - /* Decode subsequent operands */ - for (i = 1; i < mn->op_count; i++) { - offset += decode_operand(pa + offset, instr, (uint8) i, &etype); - } - - break; - case OP_DESC: - for (i = 0; i < mn->op_count; i++) { - offset += decode_operand(pa + offset, instr, (uint8) i, &etype); - } - break; - } - - return offset; -} - -static SIM_INLINE void cpu_context_switch_3(uint32 new_pcbp) -{ - if (R[NUM_PSW] & PSW_R_MASK) { - - R[0] = R[NUM_PCBP] + 64; - R[2] = read_w(R[0], ACC_AF); - R[0] += 4; - - while (R[2] != 0) { - R[1] = read_w(R[0], ACC_AF); - R[0] += 4; - - /* Execute MOVBLW instruction inside this loop */ - while (R[2] != 0) { - write_w(R[1], read_w(R[0], ACC_AF)); - R[2]--; - R[0] += 4; - R[1] += 4; - } - - R[2] = read_w(R[0], ACC_AF); - R[0] += 4; - } - - R[0] = R[0] + 4; - } -} - -static SIM_INLINE void cpu_context_switch_2(uint32 new_pcbp) -{ - R[NUM_PCBP] = new_pcbp; - - /* Put new PSW, PC and SP values from PCB into registers */ - R[NUM_PSW] = read_w(R[NUM_PCBP], ACC_AF); - R[NUM_PSW] &= ~PSW_TM_MASK; /* Clear TM */ - R[NUM_PC] = read_w(R[NUM_PCBP] + 4, ACC_AF); - R[NUM_SP] = read_w(R[NUM_PCBP] + 8, ACC_AF); - - /* If i-bit is set, increment PCBP past initial context area */ - if (R[NUM_PSW] & PSW_I_MASK) { - R[NUM_PSW] &= ~PSW_I_MASK; - R[NUM_PCBP] += 12; - } -} - -static SIM_INLINE void cpu_context_switch_1(uint32 new_pcbp) -{ - /* Save the current PC in PCB */ - write_w(R[NUM_PCBP] + 4, R[NUM_PC]); - - /* Copy the 'R' flag from the new PSW to the old PSW */ - R[NUM_PSW] &= ~PSW_R_MASK; - R[NUM_PSW] |= (read_w(new_pcbp, ACC_AF) & PSW_R_MASK); - - /* Save current PSW and SP in PCB */ - write_w(R[NUM_PCBP], R[NUM_PSW]); - write_w(R[NUM_PCBP] + 8, R[NUM_SP]); - - /* If R is set, save current R0-R8/FP/AP in PCB */ - if (R[NUM_PSW] & PSW_R_MASK) { - write_w(R[NUM_PCBP] + 24, R[NUM_FP]); - write_w(R[NUM_PCBP] + 28, R[0]); - write_w(R[NUM_PCBP] + 32, R[1]); - write_w(R[NUM_PCBP] + 36, R[2]); - write_w(R[NUM_PCBP] + 40, R[3]); - write_w(R[NUM_PCBP] + 44, R[4]); - write_w(R[NUM_PCBP] + 48, R[5]); - write_w(R[NUM_PCBP] + 52, R[6]); - write_w(R[NUM_PCBP] + 56, R[7]); - write_w(R[NUM_PCBP] + 60, R[8]); - write_w(R[NUM_PCBP] + 20, R[NUM_AP]); - - R[NUM_FP] = R[NUM_PCBP] + 52; - } -} - -void cpu_on_interrupt(uint16 vec) -{ - uint32 new_pcbp, new_pcbp_ptr; - - sim_debug(IRQ_MSG, &cpu_dev, - "[%08x] [cpu_on_interrupt] vec=%02x (%d) sbd_int_req = %x, csr_data = %x\n", - R[NUM_PC], vec, vec, sbd_int_req, csr_data); - - /* - * "If a nonmaskable interrupt request is received, an auto-vector - * interrupt acknowledge cycle is performed (as if an autovector - * interrupt at level 0 was being acknowledged) and no - * Interrupt-ID is fetched. The value 0 is used as the ID." - */ - if (cpu_nmi) { - vec = 0; - } - - cpu_nmi = FALSE; - cpu_km = TRUE; - - if (R[NUM_PSW] & PSW_QIE_MASK) { - /* TODO: Maybe implement quick interrupts at some point, but - the 3B2 ROM and SVR3 don't appear to use them. */ - stop_reason = STOP_ERR; - return; - } - - new_pcbp_ptr = (uint32)0x8c + (4 * (uint32)vec); - new_pcbp = read_w(new_pcbp_ptr, ACC_AF); - - /* Save the old PCBP */ - irq_push_word(R[NUM_PCBP]); - - /* Set ISC, TM, and ET to 0, 0, 1 before saving */ - R[NUM_PSW] &= ~(PSW_ISC_MASK|PSW_TM_MASK|PSW_ET_MASK); - R[NUM_PSW] |= (1 << PSW_ET); - - /* Context switch */ - cpu_context_switch_1(new_pcbp); - cpu_context_switch_2(new_pcbp); - - /* Set ISC, TM, and ET to 7, 0, 3 in new PSW */ - R[NUM_PSW] &= ~(PSW_ISC_MASK|PSW_TM_MASK|PSW_ET_MASK); - R[NUM_PSW] |= (7 << PSW_ISC); - R[NUM_PSW] |= (3 << PSW_ET); - - cpu_context_switch_3(new_pcbp); - - cpu_km = FALSE; -} - -t_stat sim_instr(void) -{ - uint8 et, isc, trap; - - /* Temporary register used for overflow detection */ - t_uint64 result; - - /* Scratch space */ - uint32 a, b, c, d; - - /* Used for field calculation */ - uint32 width, offset; - uint32 mask; - - /* Generic index */ - uint32 i; - - /* Interrupt request IPL */ - uint8 ipl; - - /* Used by oprocessor instructions */ - uint32 coprocessor_word; - - operand *src1, *src2, *src3, *dst; - - stop_reason = 0; - - abort_reason = (uint32) setjmp(save_env); - - /* Exception handler. - * - * This gets a little messy because of exception contexts. If a - * normal-exception happens while we're handling a - * normal-exception, it needs to be treated as a stack-exception. - */ - if (abort_reason != 0) { - if (cpu_exception_stack_depth++ >= 10) { - return STOP_ESTK; - } - - if (cpu_unit.flags & UNIT_EXBRK) { - return STOP_EX; - } - - et = R[NUM_PSW] & PSW_ET_MASK; - isc = (R[NUM_PSW] & PSW_ISC_MASK) >> PSW_ISC; - - if (abort_reason == ABORT_EXC) { - switch(abort_context) { - case C_NORMAL_GATE_VECTOR: - cpu_on_normal_exception(N_GATE_VECTOR); - break; - case C_PROCESS_GATE_PCB: - cpu_on_process_exception(GATE_PCB_FAULT); - break; - case C_PROCESS_OLD_PCB: - cpu_on_process_exception(OLD_PCB_FAULT); - break; - case C_PROCESS_NEW_PCB: - cpu_on_process_exception(NEW_PCB_FAULT); - break; - case C_STACK_FAULT: - cpu_on_stack_exception(STACK_FAULT); - break; - case C_RESET_GATE_VECTOR: - cpu_on_reset_exception(GATE_VECTOR_FAULT); - break; - case C_RESET_SYSTEM_DATA: - cpu_on_reset_exception(SYSTEM_DATA_FAULT); - break; - case C_RESET_INT_STACK: - cpu_on_reset_exception(INTERRUPT_STACK_FAULT); - break; - default: - switch(et) { - case NORMAL_EXCEPTION: - cpu_on_normal_exception(isc); - break; - case STACK_EXCEPTION: - cpu_on_stack_exception(isc); - break; - case RESET_EXCEPTION: - cpu_on_reset_exception(isc); - break; - default: - stop_reason = STOP_EX; - break; - } - break; - } - } - /* Traps are handled at the end of instruction execution */ - } - - while (stop_reason == 0) { - trap = 0; - abort_context = C_NONE; - - if (sim_brk_summ && sim_brk_test(R[NUM_PC], SWMASK ('E'))) { - stop_reason = STOP_IBKPT; - break; - } - - if (cpu_exception_stack_depth > 0) { - cpu_exception_stack_depth--; - } - - AIO_CHECK_EVENT; - - if (sim_interval-- <= 0) { - if ((stop_reason = sim_process_event())) { - break; - } - } - - /* Process DMA requests */ - dmac_service_drqs(); - - /* - * Post-increment IU mode pointers (if needed). - * - * This is essentially a colossal hack. We never want to - * increment these pointers during an interlocked Read/Write - * operation, so we only increment after a CPU step has - * occured. - */ - if (iu_increment_a) { - increment_modep_a(); - } - if (iu_increment_b) { - increment_modep_b(); - } - - /* Interrupt Handling - * - * - NMI is always serviced first. - * - SBD interrupts are handled next in priority. - * - IO Bus boards are handled last. - */ - if (cpu_nmi) { - cpu_nmi = FALSE; - cpu_in_wait = FALSE; - cpu_on_interrupt(0); - } else if (sbd_int_req) { - ipl = int_map[sbd_int_req]; - if (PSW_CUR_IPL < ipl) { - /* For the system board, interrupt vector is always - equal to IPL */ - cpu_in_wait = FALSE; - cpu_on_interrupt(ipl); - } - } else if (cio_int_req) { - for (i = 0; i < CIO_SLOTS; i++) { - if ((cio_int_req & (1 << i)) && (PSW_CUR_IPL < cio[i].ipl)) { - cpu_in_wait = FALSE; - CIO_CLR_INT(i); - cpu_on_interrupt(cio[i].ivec); - break; - } - } - } - - if (cpu_in_wait) { - if (sim_idle_enab) { - sim_idle(TMR_CLK, TRUE); - } - continue; - } - - /* Reset the TM bits */ - /* TODO: Figure out why we were doing this! */ - /* R[NUM_PSW] |= PSW_TM_MASK; */ - - /* Record the instruction for history */ - if (cpu_hist_size > 0) { - cpu_instr = &INST[cpu_hist_p]; - cpu_hist_p = (cpu_hist_p + 1) % cpu_hist_size; - } else { - cpu_instr = &inst; - } - - /* Decode the instruction */ - pc_incr = decode_instruction(cpu_instr); - - /* Make sure to update the valid bit for history keeping (if - * enabled) */ - cpu_instr->valid = TRUE; - - /* - * Operate on the decoded instruction. - */ - - /* Special case for coprocessor instructions */ - if (cpu_instr->mn->mode == OP_COPR) { - coprocessor_word = cpu_instr->operands[0].embedded.w; - } - - /* Get the operands */ - if (cpu_instr->mn->src_op1 >= 0) { - src1 = &cpu_instr->operands[cpu_instr->mn->src_op1]; - } - - if (cpu_instr->mn->src_op2 >= 0) { - src2 = &cpu_instr->operands[cpu_instr->mn->src_op2]; - } - - if (cpu_instr->mn->src_op3 >= 0) { - src3 = &cpu_instr->operands[cpu_instr->mn->src_op3]; - } - - if (cpu_instr->mn->dst_op >= 0) { - dst = &cpu_instr->operands[cpu_instr->mn->dst_op]; - } - - switch (cpu_instr->mn->opcode) { - case ADDW2: - case ADDH2: - case ADDB2: - a = cpu_read_op(src1); - b = cpu_read_op(dst); - add(a, b, dst); - break; - case ADDW3: - case ADDH3: - case ADDB3: - a = cpu_read_op(src1); - b = cpu_read_op(src2); - add(a, b, dst); - break; - case ALSW3: - a = cpu_read_op(src2); - b = cpu_read_op(src1); - result = (t_uint64)a << (b & 0x1f); - cpu_write_op(dst, result); - cpu_set_nz_flags(result, dst); - cpu_set_c_flag(0); - cpu_set_v_flag_op(result, dst); - break; - case ANDW2: - case ANDH2: - case ANDB2: - a = cpu_read_op(src1); - b = cpu_read_op(dst); - c = a & b; - cpu_write_op(dst, c); - cpu_set_nz_flags(c, dst); - cpu_set_c_flag(0); - cpu_set_v_flag_op(c, dst); - break; - case ANDW3: - case ANDH3: - case ANDB3: - a = cpu_read_op(src1); - b = cpu_read_op(src2); - c = a & b; - cpu_write_op(dst, c); - cpu_set_nz_flags(c, dst); - cpu_set_c_flag(0); - cpu_set_v_flag_op(c, dst); - break; - case BEH: - case BEH_D: - if (cpu_z_flag() == 1) { - pc_incr = sign_extend_h(dst->embedded.h); - } - break; - case BEB: - case BEB_D: - if (cpu_z_flag() == 1) { - pc_incr = sign_extend_b(dst->embedded.b); - } - break; - case BGH: - if ((cpu_n_flag() | cpu_z_flag()) == 0) { - pc_incr = sign_extend_h(dst->embedded.h); - } - break; - case BGB: - if ((cpu_n_flag() | cpu_z_flag()) == 0) { - pc_incr = sign_extend_b(dst->embedded.b); - } - break; - case BGEH: - if ((cpu_n_flag() == 0) | (cpu_z_flag() == 1)) { - pc_incr = sign_extend_h(dst->embedded.h); - } - break; - case BGEB: - if ((cpu_n_flag() == 0) | (cpu_z_flag() == 1)) { - pc_incr = sign_extend_b(dst->embedded.b); - } - break; - case BGEUH: - if (cpu_c_flag() == 0) { - pc_incr = sign_extend_h(dst->embedded.h); - } - break; - case BGEUB: - if (cpu_c_flag() == 0) { - pc_incr = sign_extend_b(dst->embedded.b); - } - break; - case BGUH: - if ((cpu_c_flag() | cpu_z_flag()) == 0) { - pc_incr = sign_extend_h(dst->embedded.h); - } - break; - case BGUB: - if ((cpu_c_flag() | cpu_z_flag()) == 0) { - pc_incr = sign_extend_b(dst->embedded.b); - } - break; - case BITW: - case BITH: - case BITB: - a = cpu_read_op(src1); - b = cpu_read_op(src2); - c = a & b; - cpu_set_nz_flags(c, src1); - cpu_set_c_flag(0); - cpu_set_v_flag(0); - break; - case BLH: - if ((cpu_n_flag() == 1) && (cpu_z_flag() == 0)) { - pc_incr = sign_extend_h(dst->embedded.h); - } - break; - case BLB: - if ((cpu_n_flag() == 1) && (cpu_z_flag() == 0)) { - pc_incr = sign_extend_b(dst->embedded.b); - } - break; - case BLEH: - if ((cpu_n_flag() | cpu_z_flag()) == 1) { - pc_incr = sign_extend_h(dst->embedded.h); - } - break; - case BLEB: - if ((cpu_n_flag() | cpu_z_flag()) == 1) { - pc_incr = sign_extend_b(dst->embedded.b); - } - break; - case BLEUH: - if ((cpu_c_flag() | cpu_z_flag()) == 1) { - pc_incr = sign_extend_h(dst->embedded.h); - } - break; - case BLEUB: - if ((cpu_c_flag() | cpu_z_flag()) == 1) { - pc_incr = sign_extend_b(dst->embedded.b); - } - break; - case BLUH: - if (cpu_c_flag() == 1) { - pc_incr = sign_extend_h(dst->embedded.h); - } - break; - case BLUB: - if (cpu_c_flag() == 1) { - pc_incr = sign_extend_b(dst->embedded.b); - } - break; - case BNEH: - case BNEH_D: - if (cpu_z_flag() == 0) { - pc_incr = sign_extend_h(dst->embedded.h); - } - break; - case BNEB: - case BNEB_D: - if (cpu_z_flag() == 0) { - pc_incr = sign_extend_b(dst->embedded.b); - } - break; - case BPT: - case HALT: - trap = BREAKPOINT_TRAP; - stop_reason = STOP_IBKPT; - break; - case BRH: - pc_incr = sign_extend_h(dst->embedded.h); - break; - case BRB: - pc_incr = sign_extend_b(dst->embedded.b); - /* BRB is commonly used to halt the processor in a tight - * infinite loop. */ - if (pc_incr == 0) { - stop_reason = STOP_LOOP; - } - break; - case BSBH: - cpu_push_word(R[NUM_PC] + pc_incr); - pc_incr = sign_extend_h(dst->embedded.h); - break; - case BSBB: - cpu_push_word(R[NUM_PC] + pc_incr); - pc_incr = sign_extend_b(dst->embedded.b); - break; - case BVCH: - if (cpu_v_flag() == 0) { - pc_incr = sign_extend_h(dst->embedded.h); - } - break; - case BVCB: - if (cpu_v_flag() == 0) { - pc_incr = sign_extend_b(dst->embedded.b); - } - break; - case BVSH: - if (cpu_v_flag() == 1) { - pc_incr = sign_extend_h(dst->embedded.h); - } - break; - case BVSB: - if (cpu_v_flag() == 1) { - pc_incr = sign_extend_b(dst->embedded.b); - } - break; - case CALL: - a = cpu_effective_address(src1); - b = cpu_effective_address(dst); - write_w(R[NUM_SP] + 4, R[NUM_AP]); - write_w(R[NUM_SP], R[NUM_PC] + pc_incr); - R[NUM_SP] += 8; - R[NUM_PC] = b; - R[NUM_AP] = a; - pc_incr = 0; - break; -#if defined(REV3) - case CASWI: - a = cpu_read_op(src1); - b = cpu_read_op(src2); - c = cpu_read_op(dst); - result = c - b; - - if (result == 0) { - cpu_write_op(src2, c); - } else { - cpu_write_op(dst, a); - } - - cpu_set_n_flag((int32)result < 0); - cpu_set_z_flag(result == 0); - cpu_set_c_flag((uint32)b > (uint32)c); - cpu_set_v_flag_op(result, dst); - break; -#endif - case CFLUSH: - break; - case CALLPS: - if (cpu_execution_level() != EX_LVL_KERN) { - cpu_abort(NORMAL_EXCEPTION, PRIVILEGED_OPCODE); - break; - } - - a = R[0]; - - cpu_km = TRUE; - - abort_context = C_RESET_INT_STACK; - - irq_push_word(R[NUM_PCBP]); - - /* Set current PC to start of next instruction (always PC+2) */ - R[NUM_PC] += 2; - - /* Set old PSW ISC, TM, and ET to 0, 0, 1 */ - R[NUM_PSW] &= ~(PSW_ISC_MASK|PSW_TM_MASK|PSW_ET_MASK); - R[NUM_PSW] |= (1 << PSW_ET); - - cpu_context_switch_1(a); - cpu_context_switch_2(a); - - R[NUM_PSW] &= ~(PSW_ISC_MASK|PSW_TM_MASK|PSW_ET_MASK); - R[NUM_PSW] |= (7 << PSW_ISC); - R[NUM_PSW] |= (3 << PSW_ET); - - cpu_context_switch_3(a); - - abort_context = C_NONE; - - cpu_km = FALSE; - pc_incr = 0; - break; - case CLRW: - case CLRH: - case CLRB: - cpu_write_op(dst, 0); - cpu_set_n_flag(0); - cpu_set_z_flag(1); - cpu_set_c_flag(0); - cpu_set_v_flag(0); - break; - case CMPW: - case CMPH: - case CMPB: - a = cpu_read_op(src1); - b = cpu_read_op(src2); - - switch(op_type(src2)) { - case WD: - case UW: - cpu_set_n_flag((int32)b < (int32)a); - break; - case HW: - case UH: - cpu_set_n_flag((int16)b < (int16)a); - break; - case BT: - case SB: - cpu_set_n_flag((int8)b < (int8)a); - break; - default: - /* Unreachable */ - break; - } - - cpu_set_z_flag(b == a); - cpu_set_c_flag(b < a); - cpu_set_v_flag(0); - break; - case DECW: - case DECH: - case DECB: - a = cpu_read_op(dst); - sub(a, 1, dst); - break; - case DIVW2: - a = cpu_read_op(src1); - b = cpu_read_op(dst); - - if (a == 0) { - cpu_abort(NORMAL_EXCEPTION, INTEGER_ZERO_DIVIDE); - break; - } - - if (a == WORD_MASK && b == WD_MSB) { - cpu_set_v_flag(1); - } - - DIV(a, b, src1, dst, int32); - - cpu_write_op(dst, result); - cpu_set_nz_flags(result, dst); - cpu_set_c_flag(0); - break; - case DIVH2: - a = cpu_read_op(src1); - b = cpu_read_op(dst); - - if (a == 0) { - cpu_abort(NORMAL_EXCEPTION, INTEGER_ZERO_DIVIDE); - break; - } - - if (a == HALF_MASK && b == HW_MSB) { - cpu_set_v_flag(1); - } - - DIV(a, b, src1, dst, int16); - - cpu_write_op(dst, result); - cpu_set_nz_flags(result, dst); - cpu_set_c_flag(0); - break; - case DIVB2: - a = cpu_read_op(src1); - b = cpu_read_op(dst); - - if (a == 0) { - cpu_abort(NORMAL_EXCEPTION, INTEGER_ZERO_DIVIDE); - break; - } - - if (a == BYTE_MASK && b == BT_MSB) { - cpu_set_v_flag(1); - } - - result = (uint8)b / (uint8)a; - - cpu_write_op(dst, result); - cpu_set_nz_flags(result, dst); - cpu_set_c_flag(0); - break; - case DIVW3: - a = cpu_read_op(src1); - b = cpu_read_op(src2); - - if (a == 0) { - cpu_abort(NORMAL_EXCEPTION, INTEGER_ZERO_DIVIDE); - break; - } - - if (a == WORD_MASK && b == WD_MSB) { - cpu_set_v_flag(1); - } - - DIV(a, b, src1, src2, int32); - - cpu_write_op(dst, result); - cpu_set_nz_flags(result, dst); - cpu_set_c_flag(0); - break; - case DIVH3: - a = cpu_read_op(src1); - b = cpu_read_op(src2); - - if (a == 0) { - cpu_abort(NORMAL_EXCEPTION, INTEGER_ZERO_DIVIDE); - break; - } - - if (a == HALF_MASK && b == HW_MSB) { - cpu_set_v_flag(1); - } - - DIV(a, b, src1, src2, int16); - - cpu_write_op(dst, result); - cpu_set_nz_flags(result, dst); - cpu_set_c_flag(0); - break; - case DIVB3: - a = cpu_read_op(src1); - b = cpu_read_op(src2); - - if (a == 0) { - cpu_abort(NORMAL_EXCEPTION, INTEGER_ZERO_DIVIDE); - break; - } - - if (a == BYTE_MASK && b == BT_MSB) { - cpu_set_v_flag(1); - } - - result = (uint8)b / (uint8)a; - - cpu_write_op(dst, result); - cpu_set_nz_flags(result, dst); - cpu_set_c_flag(0); - break; - case MVERNO: - R[0] = CPU_VERSION; - break; - case ENBVJMP: - if (cpu_execution_level() != EX_LVL_KERN) { - cpu_abort(NORMAL_EXCEPTION, PRIVILEGED_OPCODE); - break; - } - mmu_enable(); - R[NUM_PC] = R[0]; - pc_incr = 0; - break; - case DISVJMP: - if (cpu_execution_level() != EX_LVL_KERN) { - cpu_abort(NORMAL_EXCEPTION, PRIVILEGED_OPCODE); - break; - } - mmu_disable(); - R[NUM_PC] = R[0]; - pc_incr = 0; - break; - case EXTFW: - case EXTFH: - case EXTFB: - width = (cpu_read_op(src1) & 0x1f) + 1; - offset = cpu_read_op(src2) & 0x1f; - if (width >= 32) { - mask = -1; - } else { - mask = (1ul << width) - 1; - } - mask = mask << offset; - - if (width + offset > 32) { - mask |= (1ul << ((width + offset) - 32)) - 1; - } - - a = cpu_read_op(src3); /* src */ - a &= mask; - a = a >> offset; - - cpu_write_op(dst, a); - cpu_set_nz_flags(a, dst); - cpu_set_c_flag(0); - cpu_set_v_flag_op(a, dst); - break; - case INCW: - case INCH: - case INCB: - a = cpu_read_op(dst); - add(a, 1, dst); - break; - case INSFW: - case INSFH: - case INSFB: - width = (cpu_read_op(src1) & 0x1f) + 1; - offset = cpu_read_op(src2) & 0x1f; - if (width >= 32) { - mask = -1; - } else { - mask = (1ul << width) - 1; - } - - a = cpu_read_op(src3) & mask; /* src */ - b = cpu_read_op(dst); /* dst */ - - b &= ~(mask << offset); - b |= (a << offset); - - cpu_write_op(dst, b); - cpu_set_nz_flags(b, dst); - cpu_set_c_flag(0); - cpu_set_v_flag_op(b, dst); - break; - case JMP: - R[NUM_PC] = cpu_effective_address(dst); - pc_incr = 0; - break; - case JSB: - cpu_push_word(R[NUM_PC] + pc_incr); - R[NUM_PC] = cpu_effective_address(dst); - pc_incr = 0; - break; - case LLSW3: - case LLSH3: - case LLSB3: - result = (t_uint64)cpu_read_op(src2) << (cpu_read_op(src1) & 0x1f); - cpu_write_op(dst, result); - cpu_set_nz_flags(result, dst); - cpu_set_c_flag(0); - cpu_set_v_flag_op(result, dst); - break; - case ARSW3: - case ARSH3: - case ARSB3: - a = cpu_read_op(src2); - b = cpu_read_op(src1) & 0x1f; - result = a >> b; - /* Ensure the MSB is copied appropriately */ - switch (op_type(src2)) { - case WD: - if (a & 0x80000000) { - result |= shift_32_table[b + 1]; - } - break; - case HW: - if (a & 0x8000) { - result |= shift_16_table[b + 1]; - } - break; - case BT: - if (a & 0x80) { - result |= shift_8_table[b + 1]; - } - break; - } - cpu_write_op(dst, result); - cpu_set_nz_flags(result, dst); - cpu_set_c_flag(0); - cpu_set_v_flag(0); - break; - case LRSW3: - a = (uint32) cpu_read_op(src2) >> (cpu_read_op(src1) & 0x1f); - cpu_write_op(dst, a); - cpu_set_nz_flags(a, dst); - cpu_set_c_flag(0); - cpu_set_v_flag_op(a, dst); - break; - case GATE: - cpu_km = TRUE; - if (R[NUM_SP] < read_w(R[NUM_PCBP] + 12, ACC_AF) || - R[NUM_SP] > read_w(R[NUM_PCBP] + 16, ACC_AF)) { - sim_debug(EXECUTE_MSG, &cpu_dev, - "[%08x] STACK OUT OF BOUNDS IN GATE. " - "SP=%08x, R[NUM_PCBP]+12=%08x, " - "R[NUM_PCBP]+16=%08x\n", - R[NUM_PC], - R[NUM_SP], - read_w(R[NUM_PCBP] + 12, ACC_AF), - read_w(R[NUM_PCBP] + 16, ACC_AF)); - cpu_abort(STACK_EXCEPTION, STACK_BOUND); - } - cpu_km = FALSE; - - abort_context = C_STACK_FAULT; - - /* Push PC+2 onto stack */ - write_w(R[NUM_SP], R[NUM_PC] + 2); - - /* Write 1, 0, 2 to ISC, TM, ET */ - R[NUM_PSW] &= ~(PSW_ISC_MASK|PSW_TM_MASK|PSW_ET_MASK); - R[NUM_PSW] |= (1 << PSW_ISC); - R[NUM_PSW] |= (2 << PSW_ET); - - /* Push PSW onto stack */ - write_w(R[NUM_SP] + 4, R[NUM_PSW]); - - abort_context = C_NONE; - - /* Perform gate entry-point 2 */ - cpu_perform_gate(R[0] & 0x7c, - R[1] & 0x7ff8); - - /* Finish push of PC and PSW */ - R[NUM_SP] += 8; - pc_incr = 0; - -#if defined(REV3) - /* - * NB: The WE32200 processor manual claims that this is - * not a privileged instruction, and that it can be run - * from any processor level. This is not true. Tests in - * the Rev 3 off-line processor diagnostics check to - * ensure that there is an exception raised when calling - * GATE in a non-privileged context. - */ - if (cpu_execution_level() != EX_LVL_KERN) { - cpu_abort(NORMAL_EXCEPTION, PRIVILEGED_OPCODE); - } -#endif - break; - case MCOMW: - case MCOMH: - case MCOMB: /* One's complement */ - a = ~(cpu_read_op(src1)); - cpu_write_op(dst, a); - cpu_set_nz_flags(a, dst); - cpu_set_c_flag(0); - cpu_set_v_flag_op(a, dst); - break; - case MNEGW: - case MNEGH: - case MNEGB: /* Two's complement */ - a = ~cpu_read_op(src1) + 1; - cpu_write_op(dst, a); - cpu_set_nz_flags(a, dst); - cpu_set_c_flag(0); - cpu_set_v_flag_op(a, dst); - break; - case MOVBLW: - while (R[2] != 0) { - a = read_w(R[0], ACC_AF); - write_w(R[1], a); - R[2]--; - R[0] += 4; - R[1] += 4; - } - break; - case STREND: - while (read_b(R[0], ACC_AF) != '\0') { - R[0]++; - } - break; - case SWAPWI: - case SWAPHI: - case SWAPBI: - a = cpu_read_op(dst); - cpu_write_op(dst, R[0]); - R[0] = a; - cpu_set_nz_flags(a, dst); - cpu_set_v_flag(0); - cpu_set_c_flag(0); - break; - case ROTW: - a = cpu_read_op(src1) & 0x1f; - b = (uint32) cpu_read_op(src2); - mask = (CHAR_BIT * sizeof(a) - 1); - d = (b >> a) | (b << ((~a + 1) & mask)); - cpu_write_op(dst, d); - cpu_set_nz_flags(d, dst); - cpu_set_v_flag(0); - cpu_set_c_flag(0); - break; - case MOVAW: - a = cpu_effective_address(src1); - cpu_write_op(dst, a); - cpu_set_nz_flags(a, dst); - cpu_set_v_flag(0); - cpu_set_c_flag(0); - break; - case MOVTRW: - a = cpu_effective_address(src1); - result = mmu_xlate_addr(a, ACC_MT); - cpu_write_op(dst, result); - cpu_set_nz_flags(result, dst); - cpu_set_v_flag(0); - cpu_set_c_flag(0); - break; - case MOVW: - case MOVH: - case MOVB: - a = cpu_read_op(src1); - cpu_write_op(dst, a); - - /* Flags are never set if the source or destination is the - PSW */ - if (!(op_is_psw(src1) || op_is_psw(dst))) { - cpu_set_nz_flags(a, dst); - cpu_set_c_flag(0); - cpu_set_v_flag_op(a, dst); - } - - /* However, if a move to PSW set the O bit, we have to - generate an overflow exception trap */ - if (op_is_psw(dst) && (R[NUM_PSW] & PSW_OE_MASK)) { - trap = INTEGER_OVERFLOW; - } - break; - case MODW2: - a = cpu_read_op(src1); - b = cpu_read_op(dst); - if (a == 0) { - cpu_abort(NORMAL_EXCEPTION, INTEGER_ZERO_DIVIDE); - break; - } - MOD(a, b, src1, dst, int32); - cpu_write_op(dst, result); - cpu_set_nz_flags(result, dst); - cpu_set_c_flag(0); - cpu_set_v_flag_op(result, dst); - break; - case MODH2: - a = cpu_read_op(src1); - b = cpu_read_op(dst); - if (a == 0) { - cpu_abort(NORMAL_EXCEPTION, INTEGER_ZERO_DIVIDE); - break; - } - MOD(a, b, src1, dst, int16); - cpu_write_op(dst, result); - cpu_set_nz_flags(result, dst); - cpu_set_c_flag(0); - cpu_set_v_flag_op(result, dst); - break; - case MODB2: - a = cpu_read_op(src1); - b = cpu_read_op(dst); - if (a == 0) { - cpu_abort(NORMAL_EXCEPTION, INTEGER_ZERO_DIVIDE); - break; - } - result = (uint8)b % (uint8)a; - cpu_write_op(dst, result); - cpu_set_nz_flags(result, dst); - cpu_set_c_flag(0); - cpu_set_v_flag_op(result, dst); - break; - break; - case MODW3: - a = cpu_read_op(src1); - b = cpu_read_op(src2); - if (a == 0) { - cpu_abort(NORMAL_EXCEPTION, INTEGER_ZERO_DIVIDE); - break; - } - MOD(a, b, src1, src2, int32); - cpu_write_op(dst, result); - cpu_set_nz_flags(result, dst); - cpu_set_c_flag(0); - cpu_set_v_flag_op(result, dst); - break; - case MODH3: - a = cpu_read_op(src1); - b = cpu_read_op(src2); - if (a == 0) { - cpu_abort(NORMAL_EXCEPTION, INTEGER_ZERO_DIVIDE); - break; - } - MOD(a, b, src1, src2, int16); - cpu_write_op(dst, result); - cpu_set_nz_flags(result, dst); - cpu_set_c_flag(0); - cpu_set_v_flag_op(result, dst); - break; - case MODB3: - a = cpu_read_op(src1); - b = cpu_read_op(src2); - if (a == 0) { - cpu_abort(NORMAL_EXCEPTION, INTEGER_ZERO_DIVIDE); - break; - } - result = (uint8)b % (uint8)a; - cpu_write_op(dst, result); - cpu_set_nz_flags(result, dst); - cpu_set_c_flag(0); - cpu_set_v_flag_op(result, dst); - break; - case MULW2: - result = (t_uint64)cpu_read_op(src1) * (t_uint64)cpu_read_op(dst); - cpu_write_op(dst, (uint32)(result & WORD_MASK)); - cpu_set_nz_flags((uint32)(result & WORD_MASK), dst); - cpu_set_c_flag(0); - cpu_set_v_flag_op(result, dst); - break; - case MULH2: - a = cpu_read_op(src1) * cpu_read_op(dst); - cpu_write_op(dst, a); - cpu_set_nz_flags(a, dst); - cpu_set_c_flag(0); - cpu_set_v_flag_op(result, dst); - break; - case MULB2: - a = cpu_read_op(src1) * cpu_read_op(dst); - cpu_write_op(dst, a); - cpu_set_nz_flags(a, dst); - cpu_set_c_flag(0); - cpu_set_v_flag_op(result, src1); - break; - case MULW3: - result = (t_uint64)cpu_read_op(src1) * (t_uint64)cpu_read_op(src2); - cpu_write_op(dst, (uint32)(result & WORD_MASK)); - cpu_set_nz_flags((uint32)(result & WORD_MASK), dst); - cpu_set_c_flag(0); - cpu_set_v_flag_op(result, dst); - break; - case MULH3: - a = cpu_read_op(src1) * cpu_read_op(src2); - cpu_write_op(dst, a); - cpu_set_nz_flags(a, dst); - cpu_set_c_flag(0); - cpu_set_v_flag_op(result, dst); - break; - case MULB3: - a = cpu_read_op(src1) * cpu_read_op(src2); - cpu_write_op(dst, a); - cpu_set_nz_flags(a, dst); - cpu_set_c_flag(0); - cpu_set_v_flag_op(result, dst); - break; - case NOP: - break; - case NOP2: - pc_incr += 1; - break; - case NOP3: - pc_incr += 2; - break; - case ORW2: - case ORH2: - case ORB2: - a = (cpu_read_op(src1) | cpu_read_op(dst)); - cpu_write_op(dst, a); - cpu_set_nz_flags(a, dst); - cpu_set_c_flag(0); - cpu_set_v_flag_op(a, dst); - break; - case ORW3: - case ORH3: - case ORB3: - a = (cpu_read_op(src1) | cpu_read_op(src2)); - cpu_write_op(dst, a); - cpu_set_nz_flags(a, dst); - cpu_set_c_flag(0); - cpu_set_v_flag_op(a, dst); - break; - case POPW: - /* N.B. "If dst is the stack pointer (%sp), the results - are indeterminate". The ordering here is important. If - we decrement SP before writing the results, we end up - in a weird, bad state. */ - a = read_w(R[NUM_SP] - 4, ACC_AF); - cpu_write_op(dst, a); - R[NUM_SP] -= 4; - cpu_set_nz_flags(a, dst); - cpu_set_c_flag(0); - cpu_set_v_flag(0); - break; - case PUSHAW: - a = cpu_effective_address(src1); - cpu_push_word(a); - cpu_set_nz_flags(a, src1); - cpu_set_c_flag(0); - cpu_set_v_flag(0); - break; - case PUSHW: - a = cpu_read_op(src1); - cpu_push_word(a); - cpu_set_nz_flags(a, src1); - cpu_set_c_flag(0); - cpu_set_v_flag(0); - break; - case RGEQ: - if (cpu_n_flag() == 0 || cpu_z_flag() == 1) { - R[NUM_PC] = cpu_pop_word(); - pc_incr = 0; - } - break; - case RGEQU: - if (cpu_c_flag() == 0) { - R[NUM_PC] = cpu_pop_word(); - pc_incr = 0; - } - break; - case RGTR: - if ((cpu_n_flag() | cpu_z_flag()) == 0) { - R[NUM_PC] = cpu_pop_word(); - pc_incr = 0; - } - break; - case RNEQ: - case RNEQU: - if (cpu_z_flag() == 0) { - R[NUM_PC] = cpu_pop_word(); - pc_incr = 0; - } - break; - case RET: - a = R[NUM_AP]; - b = read_w(R[NUM_SP] - 4, ACC_AF); - c = read_w(R[NUM_SP] - 8, ACC_AF); - R[NUM_AP] = b; - R[NUM_PC] = c; - R[NUM_SP] = a; - pc_incr = 0; - break; - case RETG: - abort_context = C_STACK_FAULT; - a = read_w(R[NUM_SP] - 4, ACC_AF); /* PSW */ - b = read_w(R[NUM_SP] - 8, ACC_AF); /* PC */ - abort_context = C_NONE; - if ((a & PSW_CM_MASK) < (R[NUM_PSW] & PSW_CM_MASK)) { - sim_debug(EXECUTE_MSG, &cpu_dev, - "[%08x] Illegal level change. New level=%d, Cur level=%d\n", - R[NUM_PC], - (a & PSW_CM_MASK) >> PSW_CM, - (R[NUM_PSW] & PSW_CM_MASK) >> PSW_CM); - cpu_abort(NORMAL_EXCEPTION, ILLEGAL_LEVEL_CHANGE); - break; - } - /* Clear some state and move it from the current PSW */ - a &= ~PSW_IPL_MASK; - a &= ~PSW_CFD_MASK; - a &= ~PSW_QIE_MASK; - a &= ~PSW_CD_MASK; - a &= ~PSW_R_MASK; - a &= ~PSW_ISC_MASK; - a &= ~PSW_TM_MASK; - a &= ~PSW_ET_MASK; - - a |= (R[NUM_PSW] & PSW_IPL_MASK); - a |= (R[NUM_PSW] & PSW_CFD_MASK); - a |= (R[NUM_PSW] & PSW_QIE_MASK); - a |= (R[NUM_PSW] & PSW_CD_MASK); - a |= (R[NUM_PSW] & PSW_R_MASK); - a |= (7 << PSW_ISC); - a |= (3 << PSW_ET); - - R[NUM_PSW] = a; - R[NUM_PC] = b; - - R[NUM_SP] -= 8; - pc_incr = 0; - break; - case RETPS: - if (cpu_execution_level() != EX_LVL_KERN) { - cpu_abort(NORMAL_EXCEPTION, PRIVILEGED_OPCODE); - break; - } - - /* Force kernel memory access */ - cpu_km = TRUE; - - abort_context = C_RESET_INT_STACK; - /* Restore process state */ - a = irq_pop_word(); /* New process PCBP */ - - abort_context = C_PROCESS_OLD_PCB; - b = read_w(a, ACC_AF); /* New PSW */ - - abort_context = C_PROCESS_NEW_PCB; - /* Copy the 'R' flag from the new PSW to the old PSW */ - R[NUM_PSW] &= ~PSW_R_MASK; - R[NUM_PSW] |= (b & PSW_R_MASK); - - /* a now holds the new PCBP */ - cpu_context_switch_2(a); - - /* Perform block moves, if any */ - cpu_context_switch_3(a); - - /* Restore registers if R bit is set */ - if (R[NUM_PSW] & PSW_R_MASK) { - R[NUM_FP] = read_w(a + 24, ACC_AF); - R[0] = read_w(a + 28, ACC_AF); - R[1] = read_w(a + 32, ACC_AF); - R[2] = read_w(a + 36, ACC_AF); - R[3] = read_w(a + 40, ACC_AF); - R[4] = read_w(a + 44, ACC_AF); - R[5] = read_w(a + 48, ACC_AF); - R[6] = read_w(a + 52, ACC_AF); - R[7] = read_w(a + 56, ACC_AF); - R[8] = read_w(a + 60, ACC_AF); - R[NUM_AP] = read_w(a + 20, ACC_AF); - } - - abort_context = C_NONE; - - /* Un-force kernel memory access */ - cpu_km = FALSE; - pc_incr = 0; - break; - case SPOP: - /* Memory fault is signaled when no support processor is - active */ - if (mau_broadcast(coprocessor_word, 0, 0) != SCPE_OK) { - cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT); - } - break; - case SPOPD2: - case SPOPS2: - case SPOPT2: - a = cpu_effective_address(src1); - b = cpu_effective_address(dst); - if (mau_broadcast(coprocessor_word, a, b) != SCPE_OK) { - cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT); - } - break; - case SPOPRD: - case SPOPRS: - case SPOPRT: - a = cpu_effective_address(src1); - if (mau_broadcast(coprocessor_word, a, 0) != SCPE_OK) { - cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT); - } - break; - case SPOPWD: - case SPOPWS: - case SPOPWT: - a = cpu_effective_address(dst); - if (mau_broadcast(coprocessor_word, 0, a) != SCPE_OK) { - cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT); - } - break; - case SUBW2: - case SUBH2: - case SUBB2: - a = cpu_read_op(dst); - b = cpu_read_op(src1); - sub(a, b, dst); - break; - case SUBW3: - case SUBH3: - case SUBB3: - a = cpu_read_op(src2); - b = cpu_read_op(src1); - sub(a, b, dst); - break; - case RESTORE: - a = R[NUM_FP] - 28; /* Old FP */ - b = read_w(a, ACC_AF); /* Old FP */ - c = R[NUM_FP] - 24; /* Old save point */ - - for (d = src1->reg; d < NUM_FP; d++) { - R[d] = read_w(c, ACC_AF); - c += 4; - } - - R[NUM_FP] = b; /* Restore FP */ - R[NUM_SP] = a; /* Restore SP */ - break; - case RLEQ: - if ((cpu_n_flag() | cpu_z_flag()) == 1) { - R[NUM_PC] = cpu_pop_word(); - pc_incr = 0; - } - break; - case RLEQU: - if ((cpu_c_flag() | cpu_z_flag()) == 1) { - R[NUM_PC] = cpu_pop_word(); - pc_incr = 0; - } - break; - case RLSS: - if ((cpu_n_flag() == 1) & (cpu_z_flag() == 0)) { - R[NUM_PC] = cpu_pop_word(); - pc_incr = 0; - } - break; - case REQL: - if (cpu_z_flag() == 1) { - R[NUM_PC] = cpu_pop_word(); - pc_incr = 0; - } - break; - case REQLU: - if (cpu_z_flag() == 1) { - R[NUM_PC] = cpu_pop_word(); - pc_incr = 0; - } - break; - case RSB: - R[NUM_PC] = cpu_pop_word(); - pc_incr = 0; - break; - case SAVE: - /* Save the FP register */ - write_w(R[NUM_SP], R[NUM_FP]); - - /* Save all the registers from the one identified by the - src operand up to FP (exclusive) */ - for (a = src1->reg, b = 4; a < NUM_FP; a++, b += 4) { - write_w(R[NUM_SP] + b, R[a]); - } - - R[NUM_SP] = R[NUM_SP] + 28; - R[NUM_FP] = R[NUM_SP]; - break; - case STRCPY: - /* The STRCPY instruction will always copy the NULL - * terminator of a string. However, copying the NULL - * terminator never increments the source or destination - * pointer! */ - while (1) { - a = read_b(R[0], ACC_AF); - write_b(R[1], (uint8) a); - if (a == '\0') { - break; - } - R[0]++; - R[1]++; - } - break; - case TSTW: - a = cpu_read_op(src1); - cpu_set_n_flag((int32)a < 0); - cpu_set_z_flag(a == 0); - cpu_set_c_flag(0); - cpu_set_v_flag(0); - break; - case TSTH: - a = cpu_read_op(src1); - cpu_set_n_flag((int16)a < 0); - cpu_set_z_flag(a == 0); - cpu_set_c_flag(0); - cpu_set_v_flag(0); - break; - case TSTB: - a = cpu_read_op(src1); - cpu_set_n_flag((int8)a < 0); - cpu_set_z_flag(a == 0); - cpu_set_c_flag(0); - cpu_set_v_flag(0); - break; - case WAIT: - if (cpu_execution_level() != EX_LVL_KERN) { - cpu_abort(NORMAL_EXCEPTION, PRIVILEGED_OPCODE); - break; - } - cpu_in_wait = TRUE; - break; - case XORW2: - case XORH2: - case XORB2: - a = (cpu_read_op(src1) ^ cpu_read_op(dst)); - cpu_write_op(dst, a); - cpu_set_nz_flags(a, dst); - cpu_set_c_flag(0); - cpu_set_v_flag_op(a, dst); - break; - case XORW3: - case XORH3: - case XORB3: - a = (cpu_read_op(src1) ^ cpu_read_op(src2)); - cpu_write_op(dst, a); - cpu_set_nz_flags(a, dst); - cpu_set_c_flag(0); - cpu_set_v_flag_op(a, dst); - break; - default: - if (cpu_unit.flags & UNIT_OPBRK) { - stop_reason = STOP_OPCODE; - } - sim_debug(EXECUTE_MSG, &cpu_dev, - "[%08x] Illegal Opcode 0x%x\n", - R[NUM_PC], inst.mn->opcode); - cpu_abort(NORMAL_EXCEPTION, ILLEGAL_OPCODE); - break; - }; - - /* Increment the PC appropriately */ - R[NUM_PC] += pc_incr; - - /* If TE and TM are both set, generate a trace trap */ - if ((R[NUM_PSW] & PSW_TE_MASK) && (R[NUM_PSW] & PSW_TM_MASK)) { - trap = TRACE_TRAP; - } - - /* Handle traps */ - if (trap) { - R[NUM_PSW] &= ~(PSW_ET_MASK); - R[NUM_PSW] &= ~(PSW_ISC_MASK); - R[NUM_PSW] |= NORMAL_EXCEPTION; - R[NUM_PSW] |= (uint32) (trap << PSW_ISC); - cpu_on_normal_exception(trap); - } - } - - return stop_reason; -} - -static SIM_INLINE void cpu_on_process_exception(uint8 isc) -{ - /* TODO: Handle */ - sim_debug(ERR_MSG, &cpu_dev, - "[%08x] CPU_ON_PROCESS_EXCEPTION not yet implemented.\n", - R[NUM_PC]); - stop_reason = STOP_EX; - return; -} - -static SIM_INLINE void cpu_on_reset_exception(uint8 isc) -{ - uint32 new_pcbp; - - sim_debug(EXECUTE_MSG, &cpu_dev, - "[%08x] [cpu_on_reset_exception %d] SP=%08x PCBP=%08x ISP=%08x\n", - R[NUM_PC], isc, R[NUM_SP], R[NUM_PCBP], R[NUM_ISP]); - - if (isc == EXTERNAL_RESET) { - R[NUM_PSW] &= ~(PSW_R_MASK); - } - - cpu_km = TRUE; - - mmu_disable(); - - abort_context = C_RESET_SYSTEM_DATA; - new_pcbp = read_w(0x80, ACC_AF); - - abort_context = C_RESET_NEW_PCB; - cpu_context_switch_2(new_pcbp); - - cpu_km = FALSE; - abort_context = C_NONE; -} - -static SIM_INLINE void cpu_on_stack_exception(uint8 isc) -{ - uint32 new_pcbp; - - sim_debug(EXECUTE_MSG, &cpu_dev, - "[%08x] [cpu_on_stack_exception %d] SP=%08x PCBP=%08x ISP=%08x\n", - R[NUM_PC], isc, R[NUM_SP], R[NUM_PCBP], R[NUM_ISP]); - - abort_context = C_RESET_SYSTEM_DATA; - cpu_km = TRUE; - new_pcbp = read_w(0x88, ACC_AF); - - abort_context = C_RESET_INT_STACK; - irq_push_word(R[NUM_PCBP]); - - abort_context = C_PROCESS_OLD_PCB; - R[NUM_PSW] &= ~(PSW_ET_MASK|PSW_ISC_MASK); - R[NUM_PSW] |= (2 << PSW_ET); - R[NUM_PSW] |= (uint32) (isc << PSW_ISC); - - cpu_context_switch_1(new_pcbp); - cpu_context_switch_2(new_pcbp); - - /* Set ISC, TM, and ET to 7, 0, 3 in new PSW */ - R[NUM_PSW] &= ~(PSW_ISC_MASK|PSW_TM_MASK|PSW_ET_MASK); - R[NUM_PSW] |= (7 << PSW_ISC); - R[NUM_PSW] |= (3 << PSW_ET); - - cpu_km = FALSE; - abort_context = C_NONE; -} - -static SIM_INLINE void cpu_on_normal_exception(uint8 isc) -{ - sim_debug(EXECUTE_MSG, &cpu_dev, - "[%08x] [cpu_on_normal_exception %d] %%sp=%08x abort_context=%d\n", - R[NUM_PC], isc, R[NUM_SP], abort_context); - - cpu_km = TRUE; - if (R[NUM_SP] < read_w(R[NUM_PCBP] + 12, ACC_AF) || - R[NUM_SP] > read_w(R[NUM_PCBP] + 16, ACC_AF)) { - sim_debug(EXECUTE_MSG, &cpu_dev, - "[%08x] STACK OUT OF BOUNDS IN EXCEPTION HANDLER. " - "SP=%08x, R[NUM_PCBP]+12=%08x, " - "R[NUM_PCBP]+16=%08x\n", - R[NUM_PC], - R[NUM_SP], - read_w(R[NUM_PCBP] + 12, ACC_AF), - read_w(R[NUM_PCBP] + 16, ACC_AF)); - cpu_abort(STACK_EXCEPTION, STACK_BOUND); - } - cpu_km = FALSE; - - /* Set context for STACK (FAULT) */ - abort_context = C_STACK_FAULT; - /* Save address of next instruction to stack */ - write_w(R[NUM_SP], R[NUM_PC]); - - /* Write 0, 3 to TM, ET fields of PSW */ - R[NUM_PSW] &= ~(PSW_TM_MASK|PSW_ET_MASK); - R[NUM_PSW] |= (3 << PSW_ET); - - /* Save PSW to stack */ - write_w(R[NUM_SP] + 4, R[NUM_PSW]); - - /* Set context for RESET (GATE VECTOR) */ - abort_context = C_RESET_GATE_VECTOR; - cpu_perform_gate(0, ((uint32) isc) << 3); - - /* Finish push of old PC and PSW */ - R[NUM_SP] += 8; - abort_context = C_NONE; -} - -static SIM_INLINE void cpu_perform_gate(uint32 index1, uint32 index2) -{ - uint32 gate_l2, new_psw; - - abort_context = C_NORMAL_GATE_VECTOR; - cpu_km = TRUE; - - gate_l2 = read_w(index1, ACC_AF) + index2; - - /* Get new PSW from second-level table */ - new_psw = read_w(gate_l2, ACC_AF); - - /* Clear state in PSW */ - new_psw &= ~(PSW_PM_MASK|PSW_IPL_MASK|PSW_R_MASK| - PSW_ISC_MASK|PSW_TM_MASK|PSW_ET_MASK); - - /* Set PM in new PSW */ - new_psw |= (R[NUM_PSW] & PSW_CM_MASK) >> 2; /* PM */ - new_psw |= (R[NUM_PSW] & PSW_IPL_MASK); /* IPL */ - new_psw |= (R[NUM_PSW] & PSW_R_MASK); /* R */ - - /* Set new PSW ISC, TM, and ET to 7, 1, 3 */ - new_psw |= (7 << PSW_ISC); /* ISC */ - new_psw |= (1 << PSW_TM); /* TM */ - new_psw |= (3 << PSW_ET); /* ET */ - - R[NUM_PC] = read_w(gate_l2 + 4, ACC_AF); - R[NUM_PSW] = new_psw; - - cpu_km = FALSE; - abort_context = C_NONE; -} - -/* - * TODO: Setting 'data' to the effective address is bogus. We're only - * doing it because we want to get the address when we trace the - * instructions using "SHOW CPU HISTORY". We should just put - * effective_address as a field in the operand struct and make - * cpu_show_hist smarter. - */ -static uint32 cpu_effective_address(operand *op) -{ - /* Register Deferred */ - if (op->mode == 5 && op->reg != 11) { - return R[op->reg]; - } - - /* Absolute */ - if (op->mode == 7 && op->reg == 15) { - return op->embedded.w; - } - - /* Absolute Deferred */ - if (op->mode == 14 && op->reg == 15) { - /* May cause exception */ - return read_w(op->embedded.w, ACC_AF); - } - - /* FP Short Offset */ - if (op->mode == 6 && op->reg != 15) { - return R[NUM_FP] + sign_extend_b(op->embedded.b); - } - - /* AP Short Offset */ - if (op->mode == 7 && op->reg != 15) { - return R[NUM_AP] + sign_extend_b(op->embedded.b); - } - - /* Word Displacement */ - if (op->mode == 8) { - return R[op->reg] + op->embedded.w; - } - - /* Word Displacement Deferred */ - if (op->mode == 9) { - return read_w(R[op->reg] + op->embedded.w, ACC_AF); - } - - /* Halfword Displacement */ - if (op->mode == 10) { - return R[op->reg] + sign_extend_h(op->embedded.h); - } - - /* Halfword Displacement Deferred */ - if (op->mode == 11) { - return read_w(R[op->reg] + sign_extend_h(op->embedded.h), ACC_AF); - } - - /* Byte Displacement */ - if (op->mode == 12) { - return R[op->reg] + sign_extend_b(op->embedded.b); - } - - /* Byte Displacement Deferred */ - if (op->mode == 13) { - return read_w(R[op->reg] + sign_extend_b(op->embedded.b), ACC_AF); - } - - if (cpu_unit.flags & UNIT_OPBRK) { - stop_reason = STOP_OPCODE; - } - - return 0; -} - -/* - * Read and Write routines for operands. - * - * The rules for dealing with the type (signed/unsigned, - * byte/halfword/word) of operands are fairly complex. - * - * 1. The expanded operand mode does not affect the treatment of - * Literal Mode operands. All literals are signed. - * - * 2. The expanded operand mode does not affect the length of - * Immediate Mode operands, but does affect whether they are signed - * or unsigned. - * - * 3. When using expanded-mode operands, the new type remains in - * effect for the operands that folow in the instruction unless - * another expanded operand mode overrides it. (This rule in - * particular is managed by decode_instruction()) - * - * 4. The expanded operand mode is illegal with coprocessor instructions - * and CALL, SAVE, RESTORE, SWAP INTERLOCKED, PUSAHW, PUSHAW, POPW, - * and JSB. (Illegal Operand Fault) - * - * 5. When writing a byte, the Negative (N) flag is set based on the - * high bit of the data type being written, regardless of the SIGN - * of the extended datatype. e.g.: {ubyte} and {sbyte} both check - * for bit 7, {uhalf} and {shalf} both check for bit 15, and - * {uword} and {sword} both check for bit 31. - * - * 6. For instructions with a signed destination, V is set if the sign - * bit of the output value is different from any truncated bit of - * the result. For instructions with an unsigned destination, V is - * set if any truncated bit is 1. - */ - - -/* - * Read the data referenced by an operand. Performs sign or zero - * extension as required by the read width and operand type, then - * returns the read value. - * - * "All operations are performed only on 32-bit quantities even though - * an instruction may specify a byte or halfword operand. The WE - * 32100 Microprocessor reads in the correct number of bits for the - * operand and extends the data automatically to 32 bits. It uses - * sign extension when reading signed data or halfwords and zero - * extension when reading unsigned data or bytes (or bit fields that - * contain less than 32 bits). The data type of the source operand - * determines how many bits are fetched and what type of extension is - * applied. Bytes are treated as unsigned, while halfwords and words - * are considered signed. The type of extension applied can be - * changed using the expanded-operand type mode as described in 3.4.5 - * Expanded-Operand Type Mode. For sign extension, the value of the - * MSB or sign bit of the data fills the high-order bits to form a - * 32-bit value. In zero extension, zeros fill the high order bits. - * The microprocessor automatically extends a byte or halfword to 32 - * bits before performing an operation. Figure 3-3 illustrates sign - * and zero extension. An arithmetic, logical, data transfer, or bit - * field operation always yields an intermediate result that is 32 - * bits in length. If the result is to be stored in a register, the - * processor writes all 32 bits to that register. The processor - * automatically strips any surplus high-order bits from a result - * when writing bytes or halfwords to memory." -- "WE 32100 - * Microprocessor Information Manual", Section 3.1.1 - * - */ -static uint32 cpu_read_op(operand * op) -{ - uint32 eff; - uint32 data; - - /* Register */ - if (op->mode == 4 && op->reg < 15) { - switch (op_type(op)) { - case WD: - case UW: - data = R[op->reg]; - break; - case HW: - data = sign_extend_h(R[op->reg] & HALF_MASK); - break; - case UH: - data = R[op->reg] & HALF_MASK; - break; - case BT: - data = R[op->reg] & BYTE_MASK; - break; - case SB: - data = sign_extend_b(R[op->reg] & BYTE_MASK); - break; - default: - stop_reason = STOP_ERR; - data = 0; - break; - } - - op->data = data; - return data; - } - - /* Literal */ - if (op->mode < 4 || op->mode == 15) { - /* Both positive and negative literals are _always_ treated as - signed bytes, and they are _always_ sign extended. They - simply ignore expanded datatypes. */ - data = sign_extend_b(op->embedded.b); - op->data = data; - return data; - } - - /* Immediate */ - if (op->reg == 15 && - (op->mode == 4 || op->mode == 5 || op->mode == 6)) { - switch (op->mode) { - case 4: /* Word Immediate */ - data = op->embedded.w; - op->data = data; - return data; - case 5: /* Halfword Immediate */ - data = sign_extend_h(op->embedded.h); - op->data = data; - return data; - case 6: /* Byte Immedaite */ - data = sign_extend_b(op->embedded.b); - op->data = data; - return data; - } - } - - /* At this point, we'll need to find an effective address */ - eff = cpu_effective_address(op); - - switch (op_type(op)) { - case WD: /* Signed Word */ - case UW: /* Unsigned Word */ - data = read_w(eff, ACC_OF); - op->data = data; - return data; - case HW: /* Signed Halfword */ - data = sign_extend_h(read_h(eff, ACC_OF)); - op->data = data; - return data; - case UH: /* Unsigned Halfword */ - data = read_h(eff, ACC_OF); - op->data = data; - return data; - case SB: /* Signed Byte */ - data = sign_extend_b(read_b(eff, ACC_OF)); - op->data = data; - return data; - case BT: /* Unsigned Byte */ - data = read_b(eff, ACC_OF); - op->data = data; - return data; - default: - stop_reason = STOP_ERR; - return 0; - } -} - - -static void cpu_write_op(operand * op, t_uint64 val) -{ - uint32 eff; - op->data = (uint32) val; - - /* Writing to a register. */ - if (op->mode == 4 && op->reg < 15) { - if ((op->reg == NUM_PSW || op->reg == NUM_PCBP || op->reg == NUM_ISP) && - cpu_execution_level() != EX_LVL_KERN) { - cpu_abort(NORMAL_EXCEPTION, PRIVILEGED_REGISTER); - return; - } - - /* Registers always get the full 32-bits written, EXCEPT for - * the PSW, which has some Read-Only fields. */ - if (op->reg == NUM_PSW) { - WRITE_PSW((uint32) val); - } else { - R[op->reg] = (uint32) val; - } - - return; - } - - /* Literal mode is not legal. */ - if (op->mode < 4 || op->mode == 15) { - cpu_abort(NORMAL_EXCEPTION, INVALID_DESCRIPTOR); - return; - } - - /* Immediate mode is not legal. */ - if (op->reg == 15 && - (op->mode == 4 || op->mode == 5 || op->mode == 6)) { - cpu_abort(NORMAL_EXCEPTION, INVALID_DESCRIPTOR); - return; - } - - eff = cpu_effective_address(op); - - switch (op_type(op)) { - case UW: - case WD: - write_w(eff, (uint32) val); - break; - case HW: - case UH: - write_h(eff, val & HALF_MASK); - break; - case SB: - case BT: - write_b(eff, val & BYTE_MASK); - break; - default: - stop_reason = STOP_ERR; - break; - } -} - -/* - * Returns the correct datatype for an operand -- either extended type - * or default type. - */ -static SIM_INLINE int8 op_type(operand *op) { - if (op->etype > -1) { - return op->etype; - } else { - return op->dtype; - } -} - -static SIM_INLINE t_bool op_signed(operand *op) { - return (op_type(op) == WD || op_type(op) == HW || op_type(op) == SB); -} - -static SIM_INLINE uint32 sign_extend_b(uint8 val) -{ - if (val & 0x80) - return ((uint32) val) | 0xffffff00; - return (uint32) val; -} - -static SIM_INLINE uint32 sign_extend_h(uint16 val) -{ - if (val & 0x8000) - return ((uint32) val) | 0xffff0000; - return (uint32) val; -} - -/* - * Returns the current CPU execution level. - */ -static SIM_INLINE uint8 cpu_execution_level() -{ - return (R[NUM_PSW] & PSW_CM_MASK) >> PSW_CM; -} - -static SIM_INLINE t_bool cpu_z_flag() -{ - return (R[NUM_PSW] & PSW_Z_MASK) != 0; -} - -static SIM_INLINE t_bool cpu_n_flag() -{ - return (R[NUM_PSW] & PSW_N_MASK) != 0; -} - -static SIM_INLINE t_bool cpu_c_flag() -{ - return (R[NUM_PSW] & PSW_C_MASK) != 0; -} - -static SIM_INLINE t_bool cpu_v_flag() -{ - return (R[NUM_PSW] & PSW_V_MASK) != 0; -} - -static SIM_INLINE void cpu_set_z_flag(t_bool val) -{ - if (val) { - R[NUM_PSW] |= PSW_Z_MASK; - } else { - R[NUM_PSW] &= ~PSW_Z_MASK; - } -} - -static SIM_INLINE void cpu_set_n_flag(t_bool val) -{ - if (val) { - R[NUM_PSW] |= PSW_N_MASK; - } else { - R[NUM_PSW] &= ~PSW_N_MASK; - } -} - -static SIM_INLINE void cpu_set_c_flag(t_bool val) -{ - if (val) { - R[NUM_PSW] |= PSW_C_MASK; - } else { - R[NUM_PSW] &= ~PSW_C_MASK; - } -} - -static SIM_INLINE void cpu_set_v_flag_op(t_uint64 val, operand *op) -{ - switch(op_type(op)) { - case WD: - case UW: - cpu_set_v_flag(0); - break; - case HW: - case UH: - cpu_set_v_flag(val > HALF_MASK); - break; - case BT: - case SB: - default: - cpu_set_v_flag(val > BYTE_MASK); - break; - } -} - -static SIM_INLINE void cpu_set_v_flag(t_bool val) -{ - if (val) { - R[NUM_PSW] |= PSW_V_MASK; - if (R[NUM_PSW] & PSW_OE_MASK) { - cpu_abort(NORMAL_EXCEPTION, INTEGER_OVERFLOW); - } - } else { - R[NUM_PSW] &= ~PSW_V_MASK; - } -} - -static void cpu_set_nz_flags(t_uint64 data, operand *dst) -{ - int8 type = op_type(dst); - - switch (type) { - case WD: - case UW: - cpu_set_n_flag(!!(WD_MSB & data)); - cpu_set_z_flag((data & WORD_MASK) == 0); - break; - case HW: - case UH: - cpu_set_n_flag(HW_MSB & data); - cpu_set_z_flag((data & HALF_MASK) == 0); - break; - case BT: - case SB: - cpu_set_n_flag(BT_MSB & data); - cpu_set_z_flag((data & BYTE_MASK) == 0); - break; - } -} - -static SIM_INLINE void cpu_push_word(uint32 val) -{ - write_w(R[NUM_SP], val); - R[NUM_SP] += 4; -} - -static SIM_INLINE uint32 cpu_pop_word() -{ - uint32 result; - /* We always read fromthe stack first BEFORE decrementing, - in case this causes a fault. */ - result = read_w(R[NUM_SP] - 4, ACC_AF); - R[NUM_SP] -= 4; - return result; -} - -static SIM_INLINE void irq_push_word(uint32 val) -{ - write_w(R[NUM_ISP], val); - R[NUM_ISP] += 4; -} - -static SIM_INLINE uint32 irq_pop_word() -{ - R[NUM_ISP] -= 4; - return read_w(R[NUM_ISP], ACC_AF); -} - -static SIM_INLINE t_bool op_is_psw(operand *op) -{ - return (op->mode == 4 && op->reg == NUM_PSW); -} - -static SIM_INLINE void sub(t_uint64 a, t_uint64 b, operand *dst) -{ - t_uint64 result; - - result = a - b; - - cpu_write_op(dst, result); - - cpu_set_nz_flags(result, dst); - cpu_set_c_flag((uint32)b > (uint32)a); - cpu_set_v_flag_op(result, dst); -} - -static SIM_INLINE void add(t_uint64 a, t_uint64 b, operand *dst) -{ - t_uint64 result; - - result = a + b; - - cpu_write_op(dst, result); - - cpu_set_nz_flags(result, dst); - - switch(op_type(dst)) { - case WD: - cpu_set_c_flag(result > WORD_MASK); - cpu_set_v_flag(((a ^ ~b) & (a ^ result)) & WD_MSB); - break; - case UW: - cpu_set_c_flag(result > WORD_MASK); - cpu_set_v_flag(result > WORD_MASK); - break; - case HW: - cpu_set_c_flag(result > HALF_MASK); - cpu_set_v_flag(((a ^ ~b) & (a ^ result)) & HW_MSB); - break; - case UH: - cpu_set_c_flag(result > HALF_MASK); - cpu_set_v_flag(result > HALF_MASK); - break; - case BT: - cpu_set_c_flag(result > BYTE_MASK); - cpu_set_v_flag(result > BYTE_MASK); - break; - case SB: - cpu_set_c_flag(result > BYTE_MASK); - cpu_set_v_flag(((a ^ ~b) & (a ^ result)) & BT_MSB); - break; - } -} - -/* - * Set PSW's ET and ISC fields, and store global exception or fault - * state appropriately. - */ -void cpu_abort(uint8 et, uint8 isc) -{ - /* We don't trap Integer Overflow if the OE bit is not set */ - if ((R[NUM_PSW] & PSW_OE_MASK) == 0 && isc == INTEGER_OVERFLOW) { - return; - } - - R[NUM_PSW] &= ~(PSW_ET_MASK); /* Clear ET */ - R[NUM_PSW] &= ~(PSW_ISC_MASK); /* Clear ISC */ - R[NUM_PSW] |= et; /* Set ET */ - R[NUM_PSW] |= (uint32) (isc << PSW_ISC); /* Set ISC */ - - longjmp(save_env, ABORT_EXC); -} - -CONST char *cpu_description(DEVICE *dptr) -{ -#if defined(REV3) - return "3B2/600G CPU (WE 32200)"; -#else - return "3B2/400 CPU (WE 32100)"; -#endif -} - -t_stat cpu_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr) -{ -#if defined(REV3) - fprintf(st, "3B2/600G CPU Help\n\n"); - fprintf(st, "The 3B2/600G CPU simulates a WE 32200 at 24 MHz.\n\n"); -#else - fprintf(st, "3B2/400 CPU Help\n\n"); - fprintf(st, "The 3B2/400 CPU simulates a WE 32100 at 10 MHz.\n\n"); -#endif - fprintf(st, "CPU options include the size of main memory.\n\n"); - if (dptr->modifiers) { - MTAB *mptr; - for (mptr = dptr->modifiers; mptr->mask != 0; mptr++) { - if (mptr->valid == &cpu_set_size) { - fprintf(st, " sim> SET CPU %3s set memory size = %sB\n", - mptr->mstring, mptr->mstring); - } - } - fprintf(st, "\n"); - } - fprintf(st, "The CPU also implements a command to display a virtual to physical address\n"); - fprintf(st, "translation:\n\n"); - fprintf(st, " sim> SHOW CPU VIRTUAL=n show translation for address n\n\n"); - fprintf(st, "The CPU attempts to detect when the simulator is idle. When idle, the\n"); - fprintf(st, "simulator does not use any resources on the host system. Idle detetion is\n"); - fprintf(st, "controlled by the SET CPU IDLE and SET CPU NOIDLE commands:\n\n"); - fprintf(st, " sim> SET CPU IDLE enable idle detection\n"); - fprintf(st, " sim> SET CPU NOIDLE disable idle detection\n\n"); - fprintf(st, "Idle detection is disabled by default.\n\n"); - fprintf(st, "The CPU can maintain a history of the most recently executed instructions.\n"); - fprintf(st, "This is controlled by the SET CPU HISTORY and SHOW CPU HISTORY commands:\n\n"); - - fprintf(st, " sim> SET CPU HISTORY clear history buffer\n"); - fprintf(st, " sim> SET CPU HISTORY=0 disable history\n"); - fprintf(st, " sim> SET CPU HISTORY=n enable history, length = n\n"); - fprintf(st, " sim> SHOW CPU HISTORY print CPU history\n"); - fprintf(st, " sim> SHOW CPU HISTORY=n print last n entries of CPU history\n\n"); -#if defined(REV3) - fprintf(st, "Additional documentation for the 3B2/600G Simulator is available on the web:\n\n"); -#else - fprintf(st, "Additional documentation for the 3B2/400 Simulator is available on the web:\n\n"); -#endif - fprintf(st, " https://loomcom.com/3b2/emulator.html\n\n"); - - return SCPE_OK; -} +/* 3b2_cpu.c: WE32100 and WE32200 CPU + + Copyright (c) 2017-2022, Seth J. Morabito + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + Except as contained in this notice, the name of the author shall + not be used in advertising or otherwise to promote the sale, use or + other dealings in this Software without prior written authorization + from the author. +*/ + +/* + * This is an implementation of the WE 32100 and WE 32200 CPUs, used + * in the Rev 2 (e.g. 3B2/400) and Rev 3 (e.g. 3B2/700) AT&T 3B2 + * computers, respectively. + * + * The WE 32K series of microprocessors were fully 32-bit, general + * purpose CISC architecture microprocessors with features designed to + * support UNIX as a primary operating system. In addition to the CPU, + * other members of the WE 32K chipset included: + * + * - WE 32101 and WE 32201 Memory Management Units + * - WE 32106 and WE 32206 Math Accelerator Units + * + * The architecture is fully described in the following books: + * + * - "WE 32100 Microprocessor Information Manual" (AT&T, 1985) + * - "WE 32200 Microprocessor Information Manual" (AT&T, 1988) + * + */ + +#include "3b2_cpu.h" + +#if defined(REV3) +#include "3b2_if.h" +#else +#include "3b2_id.h" +#endif /* defined(REV3) */ + +#include "3b2_csr.h" +#include "3b2_dmac.h" +#include "3b2_io.h" +#include "3b2_iu.h" +#include "3b2_mau.h" +#include "3b2_mem.h" +#include "3b2_mmu.h" +#include "3b2_stddev.h" +#include "3b2_timer.h" + +/* Up to 128KB ROM allowed */ +#define MAX_SUB_RETURN_SKIP 9 + +/* Kernel-privileged registers on write */ +#if defined(REV3) +#define PRIVREG(V) ((V) == NUM_PSW || (V) == NUM_PCBP || \ + (V) == NUM_ISP || (V) == NUM_PC || (V) >= 24) +#else +#define PRIVREG(V) ((V) == NUM_PSW || (V) == NUM_PCBP || \ + (V) == NUM_ISP || (V) == NUM_PC) +#endif + +/* Static function declarations */ +static uint32 cpu_effective_address(operand * op); +static uint32 cpu_read_op(operand * op); +static void cpu_write_op(operand * op, t_uint64 val); +static void cpu_set_nz_flags(t_uint64 data, operand * op); +static SIM_INLINE void cpu_on_normal_exception(uint8 isc); +static SIM_INLINE void cpu_on_stack_exception(uint8 isc); +static SIM_INLINE void cpu_on_process_exception(uint8 isc); +static SIM_INLINE void cpu_on_reset_exception(uint8 isc); +static SIM_INLINE void cpu_perform_gate(uint32 index1, uint32 index2); +static SIM_INLINE void clear_instruction(instr *inst); +static SIM_INLINE int8 op_type(operand *op); +static SIM_INLINE t_bool op_signed(operand *op); +static SIM_INLINE uint32 sign_extend_b(uint8 val); +static SIM_INLINE uint32 sign_extend_h(uint16 val); +static SIM_INLINE t_bool cpu_z_flag(); +static SIM_INLINE t_bool cpu_n_flag(); +static SIM_INLINE t_bool cpu_c_flag(); +static SIM_INLINE t_bool cpu_v_flag(); +static SIM_INLINE void cpu_set_z_flag(t_bool val); +static SIM_INLINE void cpu_set_n_flag(t_bool val); +static SIM_INLINE void cpu_set_c_flag(t_bool val); +static SIM_INLINE void cpu_set_v_flag(t_bool val); +static SIM_INLINE void cpu_set_v_flag_op(t_uint64 val, operand *op); +static SIM_INLINE uint8 cpu_execution_level(); +static SIM_INLINE void cpu_push_word(uint32 val); +static SIM_INLINE uint32 cpu_pop_word(); +static SIM_INLINE void irq_push_word(uint32 val); +static SIM_INLINE uint32 irq_pop_word(); +static SIM_INLINE void cpu_context_switch_1(uint32 pcbp); +static SIM_INLINE void cpu_context_switch_2(uint32 pcbp); +static SIM_INLINE void cpu_context_switch_3(uint32 pcbp); +static SIM_INLINE t_bool op_is_psw(operand *op); +static SIM_INLINE void add(t_uint64 a, t_uint64 b, operand *dst); +static SIM_INLINE void sub(t_uint64 a, t_uint64 b, operand *dst); +#if defined(REV3) +static SIM_INLINE uint8 add_bcd(uint8 a, uint8 b); +static SIM_INLINE uint8 sub_bcd(uint8 a, uint8 b); +#endif + +/* RO memory. */ +uint8 *ROM = NULL; + +/* Main memory. */ +uint8 *RAM = NULL; + +/* Save environment for setjmp/longjmp */ +jmp_buf save_env; +volatile uint32 abort_context; + +/* Pointer to the last decoded instruction */ +instr *cpu_instr; + +/* The instruction to use if there is no history storage */ +instr inst; + +/* Circular buffer of instructions */ +instr *INST = NULL; +uint32 cpu_hist_size = 0; +uint32 cpu_hist_p = 0; + +t_bool cpu_in_wait = FALSE; + +volatile size_t cpu_exception_stack_depth = 0; +volatile int32 stop_reason; +volatile uint32 abort_reason; + +/* Register data */ +uint32 R[NUM_REGISTERS]; + +/* Other global CPU state */ + +t_bool rom_loaded = FALSE; /* True if ROM has been loaded, false otherwise */ + +/* Interrupt request bitfield */ +/* Note: Only the lowest 8 bits are used by Rev 2, and only the lowest + 12 bits are used by Rev 3 */ +uint16 sbd_int_req = 0; /* Currently set interrupt sources */ +uint8 int_map[INT_MAP_LEN]; /* Map of interrupt sources to highest + priority IPL */ +t_bool cpu_nmi = FALSE; /* If set, there has been an NMI */ +int32 pc_incr = 0; /* Length (in bytes) of instruction + currently being executed */ +t_bool cpu_ex_halt = FALSE; /* Flag to halt on exceptions / traps */ +t_bool cpu_km = FALSE; /* If true, kernel mode has been forced + for memory access */ +uint16 cpu_int_ack; /* The most recently acknowledged + interrupt */ + +CTAB sys_cmd[] = { + { "BOOT", &sys_boot, RU_BOOT, + "bo{ot} boot simulator\n", NULL, &run_cmd_message }, + { NULL } +}; + +BITFIELD psw_bits[] = { + BITFFMT(ET,2,%d), /* Exception Type */ + BIT(TM), /* Trace Mask */ + BITFFMT(ISC,4,%d), /* Internal State Code */ + BIT(I), /* Register Initial Context (I) */ + BIT(R), /* Register Initial Context (R) */ + BITFFMT(PM,2,%d), /* Previous Execution Level */ + BITFFMT(CM,2,%d), /* Current Execution Level */ + BITFFMT(IPL,4,%d), /* Interrupt Priority Level */ + BIT(TE), /* Trace Enable */ + BIT(C), /* Carry */ + BIT(V), /* Overflow */ + BIT(Z), /* Zero */ + BIT(N), /* Negative */ + BIT(OE), /* Enable Overflow Trap */ + BIT(CD), /* Cache Disable */ + BIT(QIE), /* Quick-Interrupt Enable */ + BIT(CFD), /* Cache Flush Disable */ +#if defined(REV3) + BIT(X), /* Extend Carry / Borrow */ + BIT(AR), /* Additional Register Save */ + BIT(EXUC), /* Exception/User Call Option */ + BIT(EA), /* Enable Arbitrary Alignment */ + BITNCF(2), /* Unused */ +#else + BITNCF(6), /* Unused */ +#endif + ENDBITS +}; + +BITFIELD sbd_int_req_bits[] = { +#if defined(REV3) + BIT(CLOK), /* UNIX Interval Timer */ + BIT(PWRD), /* Power Down Request */ + BIT(BUSO), /* UBUS or BUB Operational Interrupt */ + BIT(SBER), /* Single Bit Memory Error */ + BIT(MBER), /* Multiple Bit Memory Error */ + BIT(BRXF), /* UBUS, BUB, EIO Bus Received Fail */ + BIT(BTMO), /* UBUS Timer Timeout */ + BIT(UDMA), /* UART DMA Complete */ + BIT(UART), /* UART Interrupt */ + BIT(FDMA), /* Floppy DMA Complete */ + BIT(FLOP), /* Floppy Interrupt */ + BIT(PIR9), /* PIR 9 */ + BIT(PIR8), /* PIR 8 */ + BITNCF(3), /* Unused */ + ENDBITS +#else + BIT(SERR), /* System Error */ + BIT(CLOK), /* UNIX Interval Timer */ + BIT(DMAC), /* DMA Complete */ + BIT(UART), /* UART */ + BIT(DISK), /* Integrated Disk Drive (Winchester) */ + BIT(FLOP), /* Integrated Floppy Drive */ + BIT(PIR9), /* PIR 9 */ + BIT(PIR8), /* PIR 8 */ + BITNCF(8), /* Unused */ + ENDBITS +#endif +}; + +/* Registers. */ +REG cpu_reg[] = { + { HRDATAD (R0, R[0], 32, "General purpose register 0") }, + { HRDATAD (R1, R[1], 32, "General purpose register 1") }, + { HRDATAD (R2, R[2], 32, "General purpose register 2") }, + { HRDATAD (R3, R[3], 32, "General purpose register 3") }, + { HRDATAD (R4, R[4], 32, "General purpose register 4") }, + { HRDATAD (R5, R[5], 32, "General purpose register 5") }, + { HRDATAD (R6, R[6], 32, "General purpose register 6") }, + { HRDATAD (R7, R[7], 32, "General purpose register 7") }, + { HRDATAD (R8, R[8], 32, "General purpose register 8") }, + { HRDATAD (FP, R[NUM_FP], 32, "Frame Pointer") }, + { HRDATAD (AP, R[NUM_AP], 32, "Argument Pointer") }, + { HRDATADF (PSW, R[NUM_PSW], 32, "Processor Status Word", psw_bits) }, + { HRDATAD (SP, R[NUM_SP], 32, "Stack Pointer") }, + { HRDATAD (PCBP, R[NUM_PCBP], 32, "Process Control Block Pointer") }, + { HRDATAD (ISP, R[NUM_ISP], 32, "Interrupt Stack Pointer") }, + { HRDATAD (PC, R[NUM_PC], 32, "Program Counter") }, +#if defined(REV3) + { HRDATAD (R16, R[16], 32, "General purpose register 16")}, + { HRDATAD (R17, R[17], 32, "General purpose register 17")}, + { HRDATAD (R18, R[18], 32, "General purpose register 18")}, + { HRDATAD (R19, R[19], 32, "General purpose register 19")}, + { HRDATAD (R20, R[20], 32, "General purpose register 20")}, + { HRDATAD (R21, R[21], 32, "General purpose register 21")}, + { HRDATAD (R22, R[22], 32, "General purpose register 22")}, + { HRDATAD (R23, R[23], 32, "General purpose register 23")}, + { HRDATAD (R24, R[24], 32, "Privileged register 24")}, + { HRDATAD (R25, R[25], 32, "Privileged register 25")}, + { HRDATAD (R26, R[26], 32, "Privileged register 26")}, + { HRDATAD (R27, R[27], 32, "Privileged register 27")}, + { HRDATAD (R28, R[28], 32, "Privileged register 28")}, + { HRDATAD (R29, R[29], 32, "Privileged register 29")}, + { HRDATAD (R30, R[30], 32, "Privileged register 30")}, + { HRDATAD (R31, R[31], 32, "Privileged register 31")}, +#endif + { HRDATADF (SBD_INT, sbd_int_req, 16, "Interrupt Requests", sbd_int_req_bits) }, + { NULL } +}; + +static DEBTAB cpu_deb_tab[] = { + { "READ", READ_MSG, "Memory read activity" }, + { "WRITE", WRITE_MSG, "Memory write activity" }, + { "DECODE", DECODE_MSG, "Instruction decode" }, + { "EXECUTE", EXECUTE_MSG, "Instruction execute" }, + { "INIT", INIT_MSG, "Initialization" }, + { "IRQ", IRQ_MSG, "Interrupt Handling" }, + { "IO", IO_DBG, "I/O Dispatch" }, + { "CIO", CIO_DBG, "Common I/O Interface" }, + { "TRACE", TRACE_DBG, "Call Trace" }, + { "ERROR", ERR_MSG, "Error" }, + { NULL, 0, NULL } +}; + +UNIT cpu_unit = { + UDATA (NULL, UNIT_FIX|UNIT_BINK|UNIT_IDLE, DEFMEMSIZE) +}; + +/* + * The following commands deposit a small calibration program into + * mainstore at 0x2000000 and then set the program counter to the + * start address. Simulator calibration will execute this program to + * establish a baseline execution rate. + * + * Program: + * 84 01 46 MOVW &0x1,%r6 + * 84 46 47 MOVW %r6,%r7 + * 84 47 48 MOVW %r7,%r8 + * 90 48 INCW %r8 + * 28 48 TSTW %r8 + * 4f 0b BLEB 0xb + * e4 07 48 40 MODW3 &0x7,%r8,%r0 + * 84 40 47 MOVW %r0,%r7 + * 7b 0b BRB 0xb + * 8c 48 40 MNEGW %r8,%r0 + * a4 07 40 MODW2 &0x7,%r0 + * 84 40 47 MOVW %r0,%r7 + * e8 47 48 40 MULW3 %r7,%r8,%r0 + * 9c 07 40 ADDW2 &0x7,%r0 + * 84 40 46 MOVW %r0,%r6 + * 28 48 TSTW %r8 + * 4f 05 BLEB 0x5 + * a8 03 47 MULW2 &0x3,%r7 + * d0 01 46 46 LLSW3 &0x1,%r6,%r6 + * 28 46 TSTW %r6 + * 4f 09 BLEB 0x9 + * ec 46 47 40 DIVW3 %r6,%r7,%r0 + * 84 40 48 MOVW %r0,%r8 + * d4 01 47 47 LRSW3 &0x1,%r7,%r7 + * 3c 48 47 CMPW %r8,%r7 + * 4f 05 BLEB 0x5 + * bc 48 47 SUBW2 %r8,%r7 + * 7b bc BRB -0x44 + */ +static const char *att3b2_clock_precalibrate_commands[] = { + "-v 2000000 84014684", + "-v 2000004 46478447", + "-v 2000008 48904828", + "-v 200000c 484f0be4", + "-v 2000010 07484084", + "-v 2000014 40477b0b", + "-v 2000018 8c4840a4", + "-v 200001c 07408440", + "-v 2000020 47e84748", + "-v 2000024 409c0740", + "-v 2000028 84404628", + "-v 200002c 484f05a8", + "-v 2000030 0347d001", + "-v 2000034 46462846", + "-v 2000038 4f09ec46", + "-v 200003c 47408440", + "-v 2000040 48d40147", + "-v 2000044 473c4847", + "-v 2000048 4f05bc48", + "-v 200004c 477bbc00", + "PC 2000000", + NULL +}; + +MTAB cpu_mod[] = { +#if defined(REV2) + { UNIT_MSIZE, (1u << 20), NULL, "1M", + &cpu_set_size, NULL, NULL, "Set Memory to 1M bytes" }, + { UNIT_MSIZE, (1u << 21), NULL, "2M", + &cpu_set_size, NULL, NULL, "Set Memory to 2M bytes" }, + { UNIT_MSIZE, (1u << 22), NULL, "4M", + &cpu_set_size, NULL, NULL, "Set Memory to 4M bytes" }, +#endif +#if defined(REV3) + { UNIT_MSIZE, (1u << 23), NULL, "8M", + &cpu_set_size, NULL, NULL, "Set Memory to 8M bytes" }, + { UNIT_MSIZE, (1u << 24), NULL, "16M", + &cpu_set_size, NULL, NULL, "Set Memory to 16M bytes" }, + { UNIT_MSIZE, (1u << 25), NULL, "32M", + &cpu_set_size, NULL, NULL, "Set Memory to 32M bytes" }, + { UNIT_MSIZE, (1u << 26), NULL, "64M", + &cpu_set_size, NULL, NULL, "Set Memory to 64M bytes" }, +#endif + { MTAB_XTD|MTAB_VDV|MTAB_NMO|MTAB_SHP, 0, "HISTORY", "HISTORY", + &cpu_set_hist, &cpu_show_hist, NULL, "Displays instruction history" }, + { MTAB_XTD|MTAB_VDV|MTAB_NMO|MTAB_SHP, 0, "VIRTUAL", NULL, + NULL, &cpu_show_virt, NULL, "Show translation for virtual address" }, + { MTAB_XTD|MTAB_VDV|MTAB_NMO|MTAB_SHP, 0, "STACK", NULL, + NULL, &cpu_show_stack, NULL, "Display the current stack with optional depth" }, + { MTAB_XTD|MTAB_VDV|MTAB_NMO, 0, "CIO", NULL, + NULL, &cpu_show_cio, NULL, "Display backplane configuration" }, + { MTAB_XTD|MTAB_VDV, 0, "IDLE", "IDLE", &sim_set_idle, &sim_show_idle }, + { MTAB_XTD|MTAB_VDV, 0, NULL, "NOIDLE", &sim_clr_idle, NULL }, + { UNIT_EXBRK, UNIT_EXBRK, "Break on exceptions", "EXBRK", + NULL, NULL, NULL, "Enable break on exceptions and traps" }, + { UNIT_EXBRK, 0, "No break on exceptions", "NOEXBRK", + NULL, NULL, NULL, "Disable break on exceptions and traps" }, + { UNIT_OPBRK, UNIT_OPBRK, "Break on invalid opcodes", "OPBRK", + NULL, NULL, NULL, "Enable break on invalid opcodes" }, + { UNIT_OPBRK, 0, "No break on invalid opcodes", "NOOPBRK", + NULL, NULL, NULL, "Disable break on invalid opcodes" }, + { 0 } +}; + +DEVICE cpu_dev = { + "CPU", /* Name */ + &cpu_unit, /* Units */ + cpu_reg, /* Registers */ + cpu_mod, /* Modifiers */ + 1, /* Number of Units */ + 16, /* Address radix */ + 32, /* Address width */ + 1, /* Addr increment */ + 16, /* Data radix */ + 8, /* Data width */ + &cpu_ex, /* Examine routine */ + &cpu_dep, /* Deposit routine */ + &cpu_reset, /* Reset routine */ + &cpu_boot, /* Boot routine */ + NULL, /* Attach routine */ + NULL, /* Detach routine */ + NULL, /* Context */ + DEV_DYNM|DEV_DEBUG, /* Flags */ + 0, /* Debug control flags */ + cpu_deb_tab, /* Debug flag names */ + &cpu_set_size, /* Memory size change */ + NULL, /* Logical names */ + &cpu_help, /* Help routine */ + NULL, /* Attach Help Routine */ + NULL, /* Help Context */ + &cpu_description /* Device Description */ +}; + +mnemonic hword_ops[HWORD_OP_COUNT] = { + {0x3009, 0, OP_NONE, NA, "MVERNO", -1, -1, -1, -1}, + {0x300d, 0, OP_NONE, NA, "ENBVJMP", -1, -1, -1, -1}, + {0x3013, 0, OP_NONE, NA, "DISVJMP", -1, -1, -1, -1}, + {0x3019, 0, OP_NONE, NA, "MOVBLW", -1, -1, -1, -1}, + {0x301f, 0, OP_NONE, NA, "STREND", -1, -1, -1, -1}, + {0x302f, 1, OP_DESC, WD, "INTACK", -1, -1, -1, -1}, + {0x3035, 0, OP_NONE, NA, "STRCPY", -1, -1, -1, -1}, + {0x3045, 0, OP_NONE, NA, "RETG", -1, -1, -1, -1}, + {0x3061, 0, OP_NONE, NA, "GATE", -1, -1, -1, -1}, + {0x30ac, 0, OP_NONE, NA, "CALLPS", -1, -1, -1, -1}, +#if defined(REV3) + {0x30c0, 0, OP_NONE, NA, "UCALLPS", -1, -1, -1, -1}, +#endif + {0x30c8, 0, OP_NONE, NA, "RETPS", -1, -1, -1, -1} +}; + +/* Lookup table of operand types. */ +mnemonic ops[256] = { + {0x00, 0, OP_NONE, NA, "halt", -1, -1, -1, -1}, + {0x01, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0x02, 2, OP_COPR, WD, "SPOPRD", 1, -1, -1, -1}, + {0x03, 3, OP_COPR, WD, "SPOPD2", 1, -1, -1, 2}, + {0x04, 2, OP_DESC, WD, "MOVAW", 0, -1, -1, 1}, + {0x05, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0x06, 2, OP_COPR, WD, "SPOPRT", 1, -1, -1, -1}, + {0x07, 3, OP_COPR, WD, "SPOPT2", 1, -1, -1, 2}, + {0x08, 0, OP_NONE, NA, "RET", -1, -1, -1, -1}, +#if defined(REV3) + {0x09, 3, OP_DESC, WD, "CASWI", 0, 1, -1, 2}, + {0x0a, 0, OP_NONE, NA, "SETX", -1, -1, -1, -1}, + {0x0b, 0, OP_NONE, NA, "CLRX", -1, -1, -1, -1}, +#else + {0x09, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0x0a, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0x0b, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, +#endif + {0x0c, 2, OP_DESC, WD, "MOVTRW", 0, -1, -1, 1}, +#if defined(REV3) + {0x0d, 2, OP_DESH, HW, "TEDTH", 1, -1, -1, 0}, + {0x0e, 2, OP_DESC, HW, "PACKB", 0, -1, -1, 1}, + {0x0f, 3, OP_DESC, HW, "UNPACKB", 0, 1, -1, 2}, +#else + {0x0d, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0x0e, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0x0f, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, +#endif + {0x10, 1, OP_DESC, WD, "SAVE", 0, -1, -1, -1}, + {0x11, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0x12, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0x13, 2, OP_COPR, WD, "SPOPWD", -1, -1, -1, 1}, + {0x14, 1, OP_BYTE, NA, "EXTOP", -1, -1, -1, -1}, + {0x15, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0x16, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0x17, 2, OP_COPR, WD, "SPOPWT", -1, -1, -1, 1}, + {0x18, 1, OP_DESC, WD, "RESTORE", 0, -1, -1, -1}, +#if defined(REV3) + {0x19, 2, OP_DESH, HW, "DTH", 1, -1, -1, 0}, +#else + {0x19, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, +#endif + {0x1a, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0x1b, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0x1c, 1, OP_DESC, WD, "SWAPWI", -1, -1, -1, 0}, +#if defined(REV3) + {0x1d, 2, OP_DESH, HW, "TGEDTH", 1, -1, -1, 0}, +#else + {0x1d, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, +#endif + {0x1e, 1, OP_DESC, HW, "SWAPHI", -1, -1, -1, 0}, + {0x1f, 1, OP_DESC, BT, "SWAPBI", -1, -1, -1, 0}, + {0x20, 1, OP_DESC, WD, "POPW", -1, -1, -1, 0}, + {0x21, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0x22, 2, OP_COPR, WD, "SPOPRS", 1, -1, -1, -1}, + {0x23, 3, OP_COPR, WD, "SPOPS2", 1, -1, -1, 2}, + {0x24, 1, OP_DESC, NA, "JMP", -1, -1, -1, 0}, + {0x25, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0x26, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0x27, 0, OP_NONE, NA, "CFLUSH", -1, -1, -1, -1}, + {0x28, 1, OP_DESC, WD, "TSTW", 0, -1, -1, -1}, +#if defined(REV3) + {0x29, 2, OP_DESB, BT, "DTB", 1, -1, -1, 0}, +#else + {0x29, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, +#endif + {0x2a, 1, OP_DESC, HW, "TSTH", 0, -1, -1, -1}, + {0x2b, 1, OP_DESC, BT, "TSTB", 0, -1, -1, -1}, + {0x2c, 2, OP_DESC, WD, "CALL", 0, -1, -1, 1}, +#if defined(REV3) + {0x2d, 2, OP_DESH, HW, "TGDTH", 1, -1, -1, 0}, +#else + {0x2d, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, +#endif + {0x2e, 0, OP_NONE, NA, "BPT", -1, -1, -1, -1}, /* TODO: Verify */ + {0x2f, 0, OP_NONE, NA, "WAIT", -1, -1, -1, -1}, + {0x30, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, /* Two-byte instructions */ + {0x31, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0x32, 1, OP_COPR, WD, "SPOP", -1, -1, -1, -1}, + {0x33, 2, OP_COPR, WD, "SPOPWS", -1, -1, -1, 1}, + {0x34, 1, OP_DESC, WD, "JSB", -1, -1, -1, 0}, + {0x35, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0x36, 1, OP_HALF, NA, "BSBH", -1, -1, -1, 0}, + {0x37, 1, OP_BYTE, NA, "BSBB", -1, -1, -1, 0}, + {0x38, 2, OP_DESC, WD, "BITW", 0, 1, -1, -1}, + {0x39, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0x3a, 2, OP_DESC, HW, "BITH", 0, 1, -1, -1}, + {0x3b, 2, OP_DESC, BT, "BITB", 0, 1, -1, -1}, + {0x3c, 2, OP_DESC, WD, "CMPW", 0, 1, -1, -1}, +#if defined(REV3) + {0x3d, 2, OP_DESH, HW, "TNEDTH", 1, -1, -1, 0}, +#else + {0x3d, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, +#endif + {0x3e, 2, OP_DESC, HW, "CMPH", 0, 1, -1, -1}, + {0x3f, 2, OP_DESC, BT, "CMPB", 0, 1, -1, -1}, + {0x40, 0, OP_NONE, NA, "RGEQ", -1, -1, -1, -1}, + {0x41, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0x42, 1, OP_HALF, NA, "BGEH", -1, -1, -1, 0}, + {0x43, 1, OP_BYTE, NA, "BGEB", -1, -1, -1, 0}, + {0x44, 0, OP_NONE, NA, "RGTR", -1, -1, -1, -1}, + {0x45, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0x46, 1, OP_HALF, NA, "BGH", -1, -1, -1, 0}, + {0x47, 1, OP_BYTE, NA, "BGB", -1, -1, -1, 0}, + {0x48, 0, OP_NONE, NA, "RLSS", -1, -1, -1, 0}, + {0x49, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0x4a, 1, OP_HALF, NA, "BLH", -1, -1, -1, 0}, + {0x4b, 1, OP_BYTE, NA, "BLB", -1, -1, -1, 0}, + {0x4c, 0, OP_NONE, NA, "RLEQ", -1, -1, -1, -1}, +#if defined(REV3) + {0x4d, 2, OP_DESB, BT, "TEDTB", 1, -1, -1, 0}, +#else + {0x4d, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, +#endif + {0x4e, 1, OP_HALF, NA, "BLEH", -1, -1, -1, 0}, + {0x4f, 1, OP_BYTE, NA, "BLEB", -1, -1, -1, 0}, + {0x50, 0, OP_NONE, NA, "RGEQU", -1, -1, -1, 0}, /* aka RCC */ + {0x51, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0x52, 1, OP_HALF, NA, "BGEUH", -1, -1, -1, 0}, /* aka BCCH */ + {0x53, 1, OP_BYTE, NA, "BGEUB", -1, -1, -1, 0}, /* aka BCCB */ + {0x54, 0, OP_NONE, NA, "RGTRU", -1, -1, -1, -1}, /* TODO: Implement */ + {0x55, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0x56, 1, OP_HALF, NA, "BGUH", -1, -1, -1, 0}, + {0x57, 1, OP_BYTE, NA, "BGUB", -1, -1, -1, 0}, + {0x58, 0, OP_NONE, NA, "RLSSU", -1, -1, -1, 0}, /* aka RCS */ /* TODO: Implement */ + {0x59, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0x5a, 1, OP_HALF, NA, "BLUH", -1, -1, -1, 0}, /* aka BCSH */ + {0x5b, 1, OP_BYTE, NA, "BLUB", -1, -1, -1, 0}, /* aka BCSB */ + {0x5c, 0, OP_NONE, NA, "RLEQU", -1, -1, -1, -1}, +#if defined(REV3) + {0x5d, 2, OP_DESB, HW, "TGEDTB", 1, -1, -1, 0}, +#else + {0x5d, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, +#endif + {0x5e, 1, OP_HALF, NA, "BLEUH", -1, -1, -1, 0}, + {0x5f, 1, OP_BYTE, NA, "BLEUB", -1, -1, -1, 0}, + {0x60, 0, OP_NONE, NA, "RVC", -1, -1, -1, -1}, /* TODO: Implement */ + {0x61, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0x62, 1, OP_HALF, NA, "BVCH", -1, -1, -1, 0}, + {0x63, 1, OP_BYTE, NA, "BVCB", -1, -1, -1, 0}, + {0x64, 0, OP_NONE, NA, "RNEQU", -1, -1, -1, -1}, + {0x65, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0x66, 1, OP_HALF, NA, "BNEH", -1, -1, -1, 0}, /* duplicate of 76 */ + {0x67, 1, OP_BYTE, NA, "BNEB", -1, -1, -1, 0}, /* duplicate of 77 */ + {0x68, 0, OP_NONE, NA, "RVS", -1, -1, -1, -1}, /* TODO: Implement */ + {0x69, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0x6a, 1, OP_HALF, NA, "BVSH", -1, -1, -1, 0}, + {0x6b, 1, OP_BYTE, NA, "BVSB", -1, -1, -1, 0}, + {0x6c, 0, OP_NONE, NA, "REQLU", -1, -1, -1, -1}, +#if defined(REV3) + {0x6d, 2, OP_DESB, BT, "TGDTB", 1, -1, -1, 0}, +#else + {0x6d, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, +#endif + {0x6e, 1, OP_HALF, NA, "BEH", -1, -1, -1, 0}, /* duplicate of 7e */ + {0x6f, 1, OP_BYTE, NA, "BEB", -1, -1, -1, 0}, /* duplicate of 7f */ + {0x70, 0, OP_NONE, NA, "NOP", -1, -1, -1, -1}, + {0x71, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0x72, 0, OP_NONE, NA, "NOP3", -1, -1, -1, -1}, + {0x73, 0, OP_NONE, NA, "NOP2", -1, -1, -1, -1}, + {0x74, 0, OP_NONE, NA, "RNEQ", -1, -1, -1, -1}, + {0x75, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0x76, 1, OP_HALF, NA, "BNEH", -1, -1, -1, 0}, /* duplicate of 66 */ + {0x77, 1, OP_BYTE, NA, "BNEB", -1, -1, -1, 0}, /* duplicate of 67 */ + {0x78, 0, OP_NONE, NA, "RSB", -1, -1, -1, -1}, + {0x79, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0x7a, 1, OP_HALF, NA, "BRH", -1, -1, -1, 0}, + {0x7b, 1, OP_BYTE, NA, "BRB", -1, -1, -1, 0}, + {0x7c, 0, OP_NONE, NA, "REQL", -1, -1, -1, -1}, +#if defined(REV3) + {0x7d, 2, OP_DESB, BT, "TNEDTB", 1, -1, -1, 0}, +#else + {0x7d, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, +#endif + {0x7e, 1, OP_HALF, NA, "BEH", -1, -1, -1, 0}, /* duplicate of 6e */ + {0x7f, 1, OP_BYTE, NA, "BEB", -1, -1, -1, 0}, /* duplicate of 6f */ + {0x80, 1, OP_DESC, WD, "CLRW", -1, -1, -1, 0}, + {0x81, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0x82, 1, OP_DESC, HW, "CLRH", -1, -1, -1, 0}, + {0x83, 1, OP_DESC, BT, "CLRB", -1, -1, -1, 0}, + {0x84, 2, OP_DESC, WD, "MOVW", 0, -1, -1, 1}, + {0x85, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0x86, 2, OP_DESC, HW, "MOVH", 0, -1, -1, 1}, + {0x87, 2, OP_DESC, BT, "MOVB", 0, -1, -1, 1}, + {0x88, 2, OP_DESC, WD, "MCOMW", 0, -1, -1, 1}, + {0x89, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0x8a, 2, OP_DESC, HW, "MCOMH", 0, -1, -1, 1}, + {0x8b, 2, OP_DESC, BT, "MCOMB", 0, -1, -1, 1}, + {0x8c, 2, OP_DESC, WD, "MNEGW", 0, -1, -1, 1}, + {0x8d, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0x8e, 2, OP_DESC, HW, "MNEGH", 0, -1, -1, 1}, + {0x8f, 2, OP_DESC, BT, "MNEGB", 0, -1, -1, 1}, + {0x90, 1, OP_DESC, WD, "INCW", -1, -1, -1, 0}, + {0x91, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0x92, 1, OP_DESC, HW, "INCH", -1, -1, -1, 0}, + {0x93, 1, OP_DESC, BT, "INCB", -1, -1, -1, 0}, + {0x94, 1, OP_DESC, WD, "DECW", -1, -1, -1, 0}, + {0x95, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0x96, 1, OP_DESC, HW, "DECH", -1, -1, -1, 0}, + {0x97, 1, OP_DESC, BT, "DECB", -1, -1, -1, 0}, +#if defined(REV3) + {0x98, 0, OP_NONE, NA, "RETQINT",-1, -1, -1, -1}, /* TODO: Implement */ +#else + {0x98, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, +#endif + {0x99, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0x9a, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, +#if defined(REV3) + {0x9b, 2, OP_DESC, BT, "SUBPB2", 0, -1, -1, 1}, +#else + {0x9b, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, +#endif + {0x9c, 2, OP_DESC, WD, "ADDW2", 0, -1, -1, 1}, + {0x9d, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0x9e, 2, OP_DESC, HW, "ADDH2", 0, -1, -1, 1}, + {0x9f, 2, OP_DESC, BT, "ADDB2", 0, -1, -1, 1}, + {0xa0, 1, OP_DESC, WD, "PUSHW", 0, -1, -1, -1}, + {0xa1, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0xa2, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, +#if defined(REV3) + {0xa3, 2, OP_DESC, BT, "ADDPB2", 0, -1, -1, 1}, +#else + {0xa3, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, +#endif + {0xa4, 2, OP_DESC, WD, "MODW2", 0, -1, -1, 1}, + {0xa5, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0xa6, 2, OP_DESC, HW, "MODH2", 0, -1, -1, 1}, + {0xa7, 2, OP_DESC, BT, "MODB2", 0, -1, -1, 1}, + {0xa8, 2, OP_DESC, WD, "MULW2", 0, -1, -1, 1}, + {0xa9, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0xaa, 2, OP_DESC, HW, "MULH2", 0, -1, -1, 1}, + {0xab, 2, OP_DESC, BT, "MULB2", 0, -1, -1, 1}, + {0xac, 2, OP_DESC, WD, "DIVW2", 0, -1, -1, 1}, + {0xad, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0xae, 2, OP_DESC, HW, "DIVH2", 0, -1, -1, 1}, + {0xaf, 2, OP_DESC, BT, "DIVB2", 0, -1, -1, 1}, + {0xb0, 2, OP_DESC, WD, "ORW2", 0, -1, -1, 1}, + {0xb1, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0xb2, 2, OP_DESC, HW, "ORH2", 0, -1, -1, 1}, + {0xb3, 2, OP_DESC, BT, "ORB2", 0, -1, -1, 1}, + {0xb4, 2, OP_DESC, WD, "XORW2", 0, -1, -1, 1}, + {0xb5, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0xb6, 2, OP_DESC, HW, "XORH2", 0, -1, -1, 1}, + {0xb7, 2, OP_DESC, BT, "XORB2", 0, -1, -1, 1}, + {0xb8, 2, OP_DESC, WD, "ANDW2", 0, -1, -1, 1}, + {0xb9, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0xba, 2, OP_DESC, HW, "ANDH2", 0, -1, -1, 1}, + {0xbb, 2, OP_DESC, BT, "ANDB2", 0, -1, -1, 1}, + {0xbc, 2, OP_DESC, WD, "SUBW2", 0, -1, -1, 1}, + {0xbd, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0xbe, 2, OP_DESC, HW, "SUBH2", 0, -1, -1, 1}, + {0xbf, 2, OP_DESC, BT, "SUBB2", 0, -1, -1, 1}, + {0xc0, 3, OP_DESC, WD, "ALSW3", 0, 1, -1, 2}, + {0xc1, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0xc2, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0xc3, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0xc4, 3, OP_DESC, WD, "ARSW3", 0, 1, -1, 2}, + {0xc5, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0xc6, 3, OP_DESC, HW, "ARSH3", 0, 1, -1, 2}, + {0xc7, 3, OP_DESC, BT, "ARSB3", 0, 1, -1, 2}, + {0xc8, 4, OP_DESC, WD, "INSFW", 0, 1, 2, 3}, + {0xc9, -1, OP_DESC, NA, "???", -1, -1, -1, -1}, + {0xca, 4, OP_DESC, HW, "INSFH", 0, 1, 2, 3}, + {0xcb, 4, OP_DESC, BT, "INSFB", 0, 1, 2, 3}, + {0xcc, 4, OP_DESC, WD, "EXTFW", 0, 1, 2, 3}, + {0xcd, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0xce, 4, OP_DESC, HW, "EXTFH", 0, 1, 2, 3}, + {0xcf, 4, OP_DESC, BT, "EXTFB", 0, 1, 2, 3}, + {0xd0, 3, OP_DESC, WD, "LLSW3", 0, 1, -1, 2}, + {0xd1, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0xd2, 3, OP_DESC, HW, "LLSH3", 0, 1, -1, 2}, + {0xd3, 3, OP_DESC, BT, "LLSB3", 0, 1, -1, 2}, + {0xd4, 3, OP_DESC, WD, "LRSW3", 0, 1, -1, 2}, + {0xd5, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0xd6, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0xd7, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0xd8, 3, OP_DESC, WD, "ROTW", 0, 1, -1, 2}, + {0xd9, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0xda, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, +#if defined(REV3) + {0xdb, 3, OP_DESC, BT, "SUBPB3", 0, 1, -1, 2}, +#else + {0xdb, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, +#endif + {0xdc, 3, OP_DESC, WD, "ADDW3", 0, 1, -1, 2}, + {0xdd, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0xde, 3, OP_DESC, HW, "ADDH3", 0, 1, -1, 2}, + {0xdf, 3, OP_DESC, BT, "ADDB3", 0, 1, -1, 2}, + {0xe0, 1, OP_DESC, WD, "PUSHAW", 0, -1, -1, -1}, + {0xe1, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0xe2, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, +#if defined(REV3) + {0xe3, 3, OP_DESC, BT, "ADDPB3", 0, 1, -1, 2}, +#else + {0xe3, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, +#endif + {0xe4, 3, OP_DESC, WD, "MODW3", 0, 1, -1, 2}, + {0xe5, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0xe6, 3, OP_DESC, HW, "MODH3", 0, 1, -1, 2}, + {0xe7, 3, OP_DESC, BT, "MODB3", 0, 1, -1, 2}, + {0xe8, 3, OP_DESC, WD, "MULW3", 0, 1, -1, 2}, + {0xe9, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0xea, 3, OP_DESC, HW, "MULH3", 0, 1, -1, 2}, + {0xeb, 3, OP_DESC, BT, "MULB3", 0, 1, -1, 2}, + {0xec, 3, OP_DESC, WD, "DIVW3", 0, 1, -1, 2}, + {0xed, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0xee, 3, OP_DESC, HW, "DIVH3", 0, 1, -1, 2}, + {0xef, 3, OP_DESC, BT, "DIVB3", 0, 1, -1, 2}, + {0xf0, 3, OP_DESC, WD, "ORW3", 0, 1, -1, 2}, + {0xf1, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0xf2, 3, OP_DESC, HW, "ORH3", 0, 1, -1, 2}, + {0xf3, 3, OP_DESC, BT, "ORB3", 0, 1, -1, 2}, + {0xf4, 3, OP_DESC, WD, "XORW3", 0, 1, -1, 2}, + {0xf5, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0xf6, 3, OP_DESC, HW, "XORH3", 0, 1, -1, 2}, + {0xf7, 3, OP_DESC, BT, "XORB3", 0, 1, -1, 2}, + {0xf8, 3, OP_DESC, WD, "ANDW3", 0, 1, -1, 2}, + {0xf9, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0xfa, 3, OP_DESC, HW, "ANDH3", 0, 1, -1, 2}, + {0xfb, 3, OP_DESC, BT, "ANDB3", 0, 1, -1, 2}, + {0xfc, 3, OP_DESC, WD, "SUBW3", 0, 1, -1, 2}, + {0xfd, -1, OP_NONE, NA, "???", -1, -1, -1, -1}, + {0xfe, 3, OP_DESC, HW, "SUBH3", 0, 1, -1, 2}, + {0xff, 3, OP_DESC, BT, "SUBB3", 0, 1, -1, 2} +}; + +/* from MAME (src/devices/cpu/m68000/m68kcpu.c) */ +const uint8 shift_8_table[65] = +{ + 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff +}; +const uint16 shift_16_table[65] = +{ + 0x0000, 0x8000, 0xc000, 0xe000, 0xf000, 0xf800, 0xfc00, 0xfe00, 0xff00, + 0xff80, 0xffc0, 0xffe0, 0xfff0, 0xfff8, 0xfffc, 0xfffe, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff +}; +const uint32 shift_32_table[65] = +{ + 0x00000000, 0x80000000, 0xc0000000, 0xe0000000, 0xf0000000, 0xf8000000, + 0xfc000000, 0xfe000000, 0xff000000, 0xff800000, 0xffc00000, 0xffe00000, + 0xfff00000, 0xfff80000, 0xfffc0000, 0xfffe0000, 0xffff0000, 0xffff8000, + 0xffffc000, 0xffffe000, 0xfffff000, 0xfffff800, 0xfffffc00, 0xfffffe00, + 0xffffff00, 0xffffff80, 0xffffffc0, 0xffffffe0, 0xfffffff0, 0xfffffff8, + 0xfffffffc, 0xfffffffe, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff +}; + +t_stat cpu_show_stack(FILE *st, UNIT *uptr, int32 val, CONST void *desc) +{ + uint32 i, j; + uint32 addr, v, count; + uint8 tmp; + char *cptr = (char *) desc; + t_stat result; + + if (cptr) { + count = (size_t) get_uint(cptr, 10, 128, &result); + if ((result != SCPE_OK) || (count == 0)) { + return SCPE_ARG; + } + } else { + count = 8; + } + + for (i = 0; i < (count * 4); i += 4) { + v = 0; + addr = R[NUM_SP] - i; + + for (j = 0; j < 4; j++) { + result = examine(addr + j, &tmp); + if (result != SCPE_OK) { + return result; + } + v |= (uint32) tmp << ((3 - j) * 8); + } + + fprintf(st, " %08x: %08x\n", addr, v); + } + + return SCPE_OK; +} + +t_stat cpu_show_cio(FILE *st, UNIT *uptr, int32 val, CONST void *desc) +{ + uint32 slot; + + fprintf(st, " SLOT DEVICE\n"); + fprintf(st, "---------------------\n"); + for (slot = 0; slot < CIO_SLOTS; slot++) { + if (cio[slot].populated) { + fprintf(st, " %2d %s\n", slot, cio[slot].name); + } else { + fprintf(st, " %2d -\n", slot); + } + } + + return SCPE_OK; +} + +#if defined(REV3) +t_stat sys_boot(int32 flag, CONST char *ptr) +{ + char gbuf[CBUFSIZE]; + + if ((ptr = get_sim_sw(ptr)) == NULL) { + return SCPE_INVSW; + } + + get_glyph(ptr, gbuf, 0); + if (gbuf[0] && strcmp(gbuf, "CPU")) { + return SCPE_ARG; + } + + return run_cmd(flag, "CPU"); +} +#else +t_stat sys_boot(int32 flag, CONST char *ptr) +{ + char gbuf[CBUFSIZE]; + size_t len = ROM_SIZE; + t_stat r; + + if ((ptr = get_sim_sw(ptr)) == NULL) { + return SCPE_INVSW; + } + + do { + ptr = get_glyph(ptr, gbuf, 0); + + if (gbuf[0] && (strcmp(gbuf, "CPU"))) { + return SCPE_ARG; + } + } while (gbuf[0]); + + return run_cmd(flag, "CPU"); +} +#endif /* Rev 2 boot */ + +t_stat cpu_boot(int32 unit_num, DEVICE *dptr) +{ + /* + * page 2-52 (pdf page 85) + * + * 1. Change to physical address mode + * 2. Fetch the word at physical address 0x80 and store it in + * the PCBP register. + * 3. Fetch the word at the PCB address and store it in the + * PSW. + * 4. Fetch the word at PCB address + 4 bytes and store it + * in the PC. + * 5. Fetch the word at PCB address + 8 bytes and store it + * in the SP. + * 6. Fetch the word at PCB address + 12 bytes and store it + * in the PCB, if bit I in PSW is set. + */ + + if (!rom_loaded) { + sim_messagef(SCPE_NXM, "Cannot boot, ROM not loaded.\n"); + return SCPE_STOP; + } + + sim_debug(EXECUTE_MSG, &cpu_dev, + "CPU Boot/Reset Initiated. PC=%08x SP=%08x\n", + R[NUM_PC], R[NUM_SP]); + + mmu_disable(); + + R[NUM_PCBP] = pread_w(0x80, BUS_CPU); + R[NUM_PSW] = pread_w(R[NUM_PCBP], BUS_CPU); + R[NUM_PC] = pread_w(R[NUM_PCBP] + 4, BUS_CPU); + R[NUM_SP] = pread_w(R[NUM_PCBP] + 8, BUS_CPU); + + if (R[NUM_PSW] & PSW_I_MASK) { + R[NUM_PSW] &= ~PSW_I_MASK; + R[NUM_PCBP] += 12; + } + + /* set ISC to External Reset */ + R[NUM_PSW] &= ~PSW_ISC_MASK; + R[NUM_PSW] |= 3 << PSW_ISC ; + + return SCPE_OK; +} + +t_stat cpu_ex(t_value *vptr, t_addr addr, UNIT *uptr, int32 sw) +{ + uint32 uaddr = (uint32) addr; + uint8 value; + t_stat succ; + + if (vptr == NULL) { + return SCPE_ARG; + } + + if (sw & EX_V_FLAG) { + succ = examine(uaddr, &value); + *vptr = value; + return succ; + } else { + if (IS_ROM(uaddr) || IS_RAM(uaddr)) { + *vptr = (uint32) pread_b(uaddr, BUS_CPU); + return SCPE_OK; + } else { + *vptr = 0; + return SCPE_NXM; + } + } +} + +t_stat cpu_dep(t_value val, t_addr addr, UNIT *uptr, int32 sw) +{ + uint32 uaddr = (uint32) addr; + + if (sw & EX_V_FLAG) { + return deposit(uaddr, (uint8) val); + } else { + if (IS_RAM(uaddr)) { + pwrite_b(uaddr, (uint8) val, BUS_CPU); + return SCPE_OK; + } else { + return SCPE_NXM; + } + } +} + +/* + * Pre-populate the interrupt->IPL map "int_map" + */ +static void build_int_map() +{ + int i; + uint8 ipl; + + for (i = 0; i < INT_MAP_LEN; i++) { +#if defined(REV3) + if (i & (INT_PWRDWN|INT_BUS_OP|INT_SBERR| + INT_MBERR|INT_BUS_RXF|INT_BUS_TMO| + INT_CLOCK)) { + ipl = CPU_IPL_15; + } else if (i & (INT_UART|INT_UART_DMA)) { + ipl = CPU_IPL_13; + } else if (i & (INT_FLOPPY|INT_FLOPPY_DMA)) { + ipl = CPU_IPL_11; + } else if (i & INT_PIR9) { + ipl = CPU_IPL_9; + } else if (i & INT_PIR8) { + ipl = CPU_IPL_8; + } else { + ipl = 0; + } +#else + if (i & (INT_CLOCK|INT_SERR)) { + ipl = CPU_IPL_15; + } else if (i & (INT_UART|INT_DMA)) { + ipl = CPU_IPL_13; + } else if (i & (INT_DISK|INT_FLOPPY)) { + ipl = CPU_IPL_11; + } else if (i & INT_PIR9) { + ipl = CPU_IPL_9; + } else if (i & INT_PIR8) { + ipl = CPU_IPL_8; + } else { + ipl = 0; + } +#endif + + int_map[i] = ipl; + } + + sim_debug(EXECUTE_MSG, &cpu_dev, + "Built interrupt->IPL map of length %d\n", INT_MAP_LEN); +} + +t_stat cpu_reset(DEVICE *dptr) +{ + int i; + t_stat r; + + sim_debug(EXECUTE_MSG, &cpu_dev, "CPU Reset.\n"); + + if (!sim_is_running) { + /* Populate the interrupt->IPL map */ + build_int_map(); + + /* Clear registers */ + for (i = 0; i < NUM_REGISTERS; i++) { + R[i] = 0; + } + + /* Allocate ROM if needed */ + if (ROM == NULL) { + ROM = (uint8 *) calloc((size_t)ROM_SIZE, sizeof(uint8)); + } + if (ROM == NULL) { + return SCPE_MEM; + } + + /* Allocate RAM if needed */ + if (RAM == NULL) { + RAM = (uint8 *) calloc((size_t)MEM_SIZE, sizeof(uint8)); + } + if (RAM == NULL) { + return SCPE_MEM; + } + + sim_vm_is_subroutine_call = cpu_is_pc_a_subroutine_call; + + /* Link in our special "boot" command so we can boot with both + * "BO{OT}" and "BO{OT} CPU" */ + sim_vm_cmd = sys_cmd; + + /* Set up the pre-calibration routine */ + sim_clock_precalibrate_commands = att3b2_clock_precalibrate_commands; + + abort_context = C_NONE; + + cpu_in_wait = FALSE; + } + + sim_brk_types = SWMASK('E'); + sim_brk_dflt = SWMASK('E'); + + return SCPE_OK; +} + +static const char *cpu_next_caveats = +"The NEXT command in this 3B2 architecture simulator currently will\n" +"enable stepping across subroutine calls which are initiated by the\n" +"JSB, CALL and CALLPS instructions.\n" +"This stepping works by dynamically establishing breakpoints at the\n" +"memory address immediately following the instruction which initiated\n" +"the subroutine call. These dynamic breakpoints are automatically\n" +"removed once the simulator returns to the sim> prompt for any reason.\n" +"If the called routine returns somewhere other than one of these\n" +"locations due to a trap, stack unwind or any other reason, instruction\n" +"execution will continue until some other reason causes execution to stop.\n"; + +t_bool cpu_is_pc_a_subroutine_call (t_addr **ret_addrs) +{ + static t_addr returns[MAX_SUB_RETURN_SKIP+1] = {0}; + static t_bool caveats_displayed = FALSE; + int i; + + if (!caveats_displayed) { + caveats_displayed = TRUE; + sim_printf ("%s", cpu_next_caveats); + } + + /* get data */ + if (SCPE_OK != get_aval (R[NUM_PC], &cpu_dev, &cpu_unit)) { + return FALSE; + } + + switch (sim_eval[0]) { + case JSB: + case CALL: + case CALLPS: +#if defined(REV3) + case UCALLPS: +#endif + returns[0] = R[NUM_PC] + (unsigned int) (1 - fprint_sym(stdnul, R[NUM_PC], + sim_eval, &cpu_unit, + SWMASK ('M'))); + for (i=1; imnemonic); + + for (i = 0; i < mn->op_count; i++) { + + /* Special cases for non-descriptor opcodes */ + if ((mn->mode == OP_BYTE) || (mn->mode == OP_DESB && i > 0)) { + mode = 6; + reg = 15; + } else if (mn->mode == OP_HALF || (mn->mode == OP_DESH && i > 0)) { + mode = 5; + reg = 15; + } else if (mn->mode == OP_COPR) { + mode = 4; + reg = 15; + } else { + desc = (uint8) val[vp++]; + +#if defined(REV3) /* WE 32200 only */ + switch (desc) { + case 0x5b: + /* Get next byte */ + desc = (uint8) val[vp++]; + /* + * Mode 0x10: Auto pre-decrement -(%rx) + * Mode 0x12: Auto post-decrement (%rx)- + * Mode 0x14: Auto pre-increment +(%rx) + * Mode 0x16: Auto post-increment (%rx)- + */ + mode = ((desc >> 5) & 0x7) | 0x10; + reg = desc & 0x1f; + break; + case 0xab: + case 0xbb: + mode = 0xab; + desc = (uint8) val[vp++]; + reg = (desc >> 4) & 0xf; + reg2 = (desc & 0xf) + 16; + break; + case 0xcb: + /* Get next byte */ + desc = (uint8) val[vp++]; + mode = (desc >> 4) & 0xf; + reg = (desc & 0xf) + 16; + break; + case 0xdb: + mode = 0xdb; + desc = (uint8) val[vp++]; + reg = (desc >> 4) & 0xf; + reg2 = (desc & 0xf) + 16; + break; + default: + mode = (desc >> 4) & 0xf; + reg = desc & 0xf; + break; + } +#else /* WE 32100 only */ + mode = (desc >> 4) & 0xf; + reg = desc & 0xf; +#endif + + /* Find the expanded data type, if any */ + if (mode == 14 && + (reg == 0 || reg == 2 || reg == 3 || + reg == 4 || reg == 6 || reg == 7)) { + etype = reg; + /* The real descriptor byte lies one ahead */ + desc = (uint8) val[vp++]; + mode = (desc >> 4) & 0xf; + reg = desc & 0xf; + } + } + + fputc(i ? ',' : ' ', of); + + switch (etype) { + case 0: + fprintf(of, "{uword}"); + break; + case 2: + fprintf(of, "{uhalf}"); + break; + case 3: + fprintf(of, "{ubyte}"); + break; + case 4: + fprintf(of, "{word}"); + break; + case 6: + fprintf(of, "{half}"); + break; + case 7: + fprintf(of, "{sbyte}"); + break; + default: + /* do nothing */ + break; + } + + switch(mode) { + case 0: /* Positive Literal */ + case 1: /* Positive Literal */ + case 2: /* Positive Literal */ + case 3: /* Positive Literal */ + case 15: /* Negative Literal */ + fprintf(of, "&%d", desc); + break; + case 4: /* Halfword Immediate, Register Mode */ + switch (reg) { + case 15: /* Word Immediate */ + OP_R_W(w, val, vp); + fprintf(of, "&0x%x", w); + break; + default: /* Register Mode */ + cpu_register_name(reg, reg_name, 8); + fprintf(of, "%s", reg_name); + break; + } + break; + case 5: /* Halfword Immediate, Register Deferred */ + switch (reg) { + case 15: + OP_R_H(w, val, vp); + fprintf(of, "&0x%x", w); + break; + default: + cpu_register_name(reg, reg_name, 8); + fprintf(of, "(%s)", reg_name); + break; + } + break; + case 6: /* Byte Immediate, FP Short Offset */ + switch (reg) { + case 15: + OP_R_B(w, val, vp); + fprintf(of, "&0x%x", w); + break; + default: + fprintf(of, "%d(%%fp)", (int8) reg); + break; + } + break; + case 7: /* Absolute, AP Short Offset */ + switch (reg) { + case 15: + OP_R_W(w, val, vp); + fprintf(of, "$0x%x", w); + break; + default: + fprintf(of, "%d(%%ap)", (int8) reg); + break; + } + break; + case 8: /* Word Displacement */ + OP_R_W(w, val, vp); + cpu_register_name(reg, reg_name, 8); + fprintf(of, "0x%x(%s)", w, reg_name); + break; + case 9: /* Word Displacement Deferred */ + OP_R_W(w, val, vp); + cpu_register_name(reg, reg_name, 8); + fprintf(of, "*0x%x(%s)", w, reg_name); + break; + case 10: /* Halfword Displacement */ + OP_R_H(w, val, vp); + cpu_register_name(reg, reg_name, 8); + fprintf(of, "0x%x(%s)", w, reg_name); + break; + case 11: /* Halfword Displacement Deferred */ + OP_R_H(w, val, vp); + cpu_register_name(reg, reg_name, 8); + fprintf(of, "*0x%x(%s)", w, reg_name); + break; + case 12: /* Byte Displacement */ + OP_R_B(w, val, vp); + cpu_register_name(reg, reg_name, 8); + fprintf(of, "%d(%s)", (int8) w, reg_name); + break; + case 13: /* Byte Displacement Deferred */ + OP_R_B(w, val, vp); + cpu_register_name(reg, reg_name, 8); + fprintf(of, "*%d(%s)", (int8) w, reg_name); + break; + case 14: + if (reg == 15) { + OP_R_W(w, val, vp); + fprintf(of, "*$0x%x", w); + } + break; +#if defined(REV3) + case 0x10: /* Auto pre-decrement */ + cpu_register_name(reg, reg_name, 8); + fprintf(of, "-(%s)", reg_name); + break; + case 0x12: /* Auto post-decrement */ + cpu_register_name(reg, reg_name, 8); + fprintf(of, "(%s)-", reg_name); + break; + case 0x14: /* Auto pre-increment */ + cpu_register_name(reg, reg_name, 8); + fprintf(of, "+(%s)", reg_name); + break; + case 0x16: /* Auto post-increment */ + cpu_register_name(reg, reg_name, 8); + fprintf(of, "(%s)+", reg_name); + break; + case 0xab: + OP_R_B(w, val, vp); + cpu_register_name(reg, reg_name, 8); + cpu_register_name(reg2, reg2_name, 8); + fprintf(of, "%d(%s,%s)", (int8) w, reg2_name, reg_name); + break; + case 0xbb: + OP_R_H(w, val, vp); + cpu_register_name(reg, reg_name, 8); + cpu_register_name(reg2, reg2_name, 8); + fprintf(of, "0x%x(%s,%s)", w, reg2_name, reg_name); + break; + case 0xdb: + cpu_register_name(reg, reg_name, 8); + cpu_register_name(reg2, reg2_name, 8); + fprintf(of, "%s[%s]", reg2_name, reg_name); + break; +#endif + default: + fprintf(of, ""); + break; + } + } + + + return -(vp - 1); +} + +void fprint_sym_hist(FILE *st, instr *ip) +{ + int32 i; + + if (ip == NULL || ip->mn == NULL) { + fprintf(st, "???"); + return; + } + + fprintf(st, "%s", ip->mn->mnemonic); + + if (ip->mn->op_count > 0) { + fputc(' ', st); + } + + /* Show the operand mnemonics */ + for (i = 0; i < ip->mn->op_count; i++) { + cpu_show_operand(st, &ip->operands[i]); + if (i < ip->mn->op_count - 1) { + fputc(',', st); + } + } +} + +t_stat cpu_show_virt(FILE *of, UNIT *uptr, int32 val, CONST void *desc) +{ + uint32 va, pa; + t_stat r; + + const char *cptr = (const char *)desc; + if (cptr) { + va = (uint32) get_uint(cptr, 16, 0xffffffff, &r); + if (r == SCPE_OK) { + r = mmu_decode_va(va, 0, FALSE, &pa); + if (r == SCPE_OK) { + fprintf(of, "Virtual %08x = Physical %08x\n", va, pa); + return SCPE_OK; + } else { + fprintf(of, "Translation not possible for virtual address.\n"); + return SCPE_ARG; + } + } else { + fprintf(of, "Illegal address format.\n"); + return SCPE_ARG; + } + } + + fprintf(of, "Address argument required.\n"); + return SCPE_ARG; +} + +t_stat cpu_set_hist(UNIT *uptr, int32 val, CONST char *cptr, void *desc) +{ + uint32 i, size; + t_stat result; + + /* Clear the history buffer if no argument */ + if (cptr == NULL) { + for (i = 0; i < cpu_hist_size; i++) { + INST[i].valid = FALSE; + } + return SCPE_OK; + } + + /* Otherwise, get the new length */ + size = (uint32) get_uint(cptr, 10, MAX_HIST_SIZE, &result); + + /* If no length was provided, give up */ + if (result != SCPE_OK) { + return SCPE_ARG; + } + + /* Legnth 0 is a special flag that means disable the feature. */ + if (size == 0) { + if (INST != NULL) { + for (i = 0; i < cpu_hist_size; i++) { + INST[i].valid = FALSE; + } + } + cpu_hist_size = 0; + cpu_hist_p = 0; + return SCPE_OK; + } + + /* Reinitialize the new history ring bufer */ + cpu_hist_p = 0; + if (size > 0) { + if (INST != NULL) { + free(INST); + } + INST = (instr *)calloc(size, sizeof(instr)); + if (INST == NULL) { + return SCPE_MEM; + } + memset(INST, 0, sizeof(instr) * size); + cpu_hist_size = size; + } + + return SCPE_OK; +} + +t_stat cpu_show_hist(FILE *st, UNIT *uptr, int32 val, CONST void *desc) +{ + uint32 i; + size_t j, count; + char *cptr = (char *) desc; + t_stat result; + instr *ip; + + int32 di; + + if (cpu_hist_size == 0) { + return SCPE_NOFNC; + } + + /* 'count' is the number of history entries the user wants */ + + if (cptr) { + count = (size_t) get_uint(cptr, 10, cpu_hist_size, &result); + if ((result != SCPE_OK) || (count == 0)) { + return SCPE_ARG; + } + } else { + count = cpu_hist_size; + } + + /* Position for reading from ring buffer */ + di = (int32) (cpu_hist_p - count); + + if (di < 0) { + di = di + (int32) cpu_hist_size; + } + + fprintf(st, "PSW SP PC IR\n"); + + for (i = 0; i < count; i++) { + ip = &INST[(di++) % (int32) cpu_hist_size]; + if (ip->valid) { + /* Show the opcode mnemonic */ + fprintf(st, "%08x %08x %08x ", ip->psw, ip->sp, ip->pc); + /* Show the operand data */ + if (ip->mn == NULL || ip->mn->op_count < 0) { + fprintf(st, "???"); + } else { + fprint_sym_hist(st, ip); + if (ip->mn->op_count > 0 && ip->mn->mode == OP_DESC) { + fprintf(st, "\n "); + for (j = 0; j < (uint32) ip->mn->op_count; j++) { + fprintf(st, "%08x", ip->operands[j].data); + if (j < (uint32) ip->mn->op_count - 1) { + fputc(' ', st); + } + } + } + } + fputc('\n', st); + } + } + + + return SCPE_OK; +} + +void cpu_register_name(uint8 reg, char *buf, size_t len) { + switch(reg) { + case 9: + snprintf(buf, len, "%%fp"); + break; + case 10: + snprintf(buf, len, "%%ap"); + break; + case 11: + snprintf(buf, len, "%%psw"); + break; + case 12: + snprintf(buf, len, "%%sp"); + break; + case 13: + snprintf(buf, len, "%%pcbp"); + break; + case 14: + snprintf(buf, len, "%%isp"); + break; + case 15: + snprintf(buf, len, "%%pc"); + break; + default: + snprintf(buf, len, "%%r%d", reg); + break; + } +} + +void cpu_show_operand(FILE *st, operand *op) +{ + char reg_name[8]; +#if defined(REV3) + char reg2_name[8]; +#endif + + if (op->etype != -1) { + switch(op->etype) { + case 0: + fprintf(st, "{uword}"); + break; + case 2: + fprintf(st, "{uhalf}"); + break; + case 3: + fprintf(st, "{ubyte}"); + break; + case 4: + fprintf(st, "{word}"); + break; + case 6: + fprintf(st, "{half}"); + break; + case 7: + fprintf(st, "{sbyte}"); + break; + } + } + + switch(op->mode) { + case 0: + case 1: + case 2: + case 3: + fprintf(st, "&0x%x", op->embedded.b); + break; + case 4: + if (op->reg == 15) { + fprintf(st, "&0x%x", op->embedded.w); + } else { + cpu_register_name(op->reg, reg_name, 8); + fprintf(st, "%s", reg_name); + } + break; + case 5: + if (op->reg == 15) { + fprintf(st, "&0x%x", op->embedded.w); + } else { + cpu_register_name(op->reg, reg_name, 8); + fprintf(st, "(%s)", reg_name); + } + break; + case 6: /* FP Short Offset */ + if (op->reg == 15) { + fprintf(st, "&0x%x", op->embedded.w); + } else { + fprintf(st, "%d(%%fp)", op->reg); + } + break; + case 7: /* AP Short Offset */ + if (op->reg == 15) { + fprintf(st, "$0x%x", op->embedded.w); + } else { + fprintf(st, "%d(%%ap)", op->embedded.w); + } + break; + case 8: + cpu_register_name(op->reg, reg_name, 8); + fprintf(st, "0x%x(%s)", (int32)op->embedded.w, reg_name); + break; + case 9: + cpu_register_name(op->reg, reg_name, 8); + fprintf(st, "*0x%x(%s)", (int32)op->embedded.w, reg_name); + break; + case 10: + cpu_register_name(op->reg, reg_name, 8); + fprintf(st, "0x%x(%s)", (int16)op->embedded.w, reg_name); + break; + case 11: + cpu_register_name(op->reg, reg_name, 8); + fprintf(st, "*0x%x(%s)", (int16)op->embedded.w, reg_name); + break; + case 12: + cpu_register_name(op->reg, reg_name, 8); + fprintf(st, "%d(%s)", (int8)op->embedded.w, reg_name); + break; + case 13: + cpu_register_name(op->reg, reg_name, 8); + fprintf(st, "*%d(%s)", (int8)op->embedded.w, reg_name); + break; + case 14: + if (op->reg == 15) { + fprintf(st, "*$0x%x", op->embedded.w); + } + break; + case 15: + fprintf(st, "&0x%x", (int32)op->embedded.w); + break; +#if defined(REV3) + case 0x10: /* Auto pre-decrement */ + cpu_register_name(op->reg, reg_name, 8); + fprintf(st, "-(%s)", reg_name); + break; + case 0x12: /* Auto post-decrement */ + cpu_register_name(op->reg, reg_name, 8); + fprintf(st, "(%s)-", reg_name); + break; + case 0x14: /* Auto pre-increment */ + cpu_register_name(op->reg, reg_name, 8); + fprintf(st, "+(%s)", reg_name); + break; + case 0x16: /* Auto post-increment */ + cpu_register_name(op->reg, reg_name, 8); + fprintf(st, "(%s)+", reg_name); + break; + case 0xab: + cpu_register_name(op->reg, reg_name, 8); + cpu_register_name(op->reg2, reg2_name, 8); + fprintf(st, "%d(%s,%s)", (int8)op->embedded.b, reg2_name, reg_name); + break; + case 0xbb: + cpu_register_name(op->reg, reg_name, 8); + cpu_register_name(op->reg2, reg2_name, 8); + fprintf(st, "0x%x(%s,%s)", op->embedded.h, reg2_name, reg_name); + break; + case 0xdb: + cpu_register_name(op->reg, reg_name, 8); + cpu_register_name(op->reg2, reg2_name, 8); + fprintf(st, "%s[%s]", reg2_name, reg_name); + break; +#endif + } +} + +t_stat cpu_set_size(UNIT *uptr, int32 val, CONST char *cptr, void *desc) +{ + uint32 uval = (uint32) val; + uint8 *nRAM = NULL; + + if ((val <= 0) || (val > MAXMEMSIZE)) { + return SCPE_ARG; + } + + /* Do (re-)allocation for memory. */ + nRAM = (uint8 *) calloc(uval, sizeof(uint32)); + + if (nRAM == NULL) { + return SCPE_MEM; + } + + free(RAM); + RAM = nRAM; + memset(RAM, 0, (size_t)uval * sizeof(uint32)); + + MEM_SIZE = uval; + + return SCPE_OK; +} + +static SIM_INLINE void clear_instruction(instr *inst) +{ + uint8 i; + + inst->mn = NULL; + inst->psw = 0; + inst->sp = 0; + inst->pc = 0; + + for (i = 0; i < 4; i++) { + inst->operands[i].mode = 0; + inst->operands[i].reg = 0; + inst->operands[i].dtype = -1; + inst->operands[i].etype = -1; + inst->operands[i].embedded.w = 0; + inst->operands[i].data = 0; + } +} + +/* + * Decode a single descriptor-defined operand from the instruction + * stream. Returns the number of bytes consumed during decode. + */ +static uint8 decode_operand(uint32 pa, instr *instr, uint8 op_number, int8 *etype) +{ + uint8 desc; + uint8 offset = 0; + operand *oper = &instr->operands[op_number]; + + /* Read in the descriptor byte */ + desc = read_b(pa + offset++, ACC_IF, BUS_CPU); + +#if defined(REV3) + /* + * Handle addressing modes specific to the WE 32200, not + * implemented in the WE 32100 + */ + switch (desc) { + case 0x5b: /* Auto post / pre-increment */ + desc = read_b(pa + offset++, ACC_IF, BUS_CPU); + /* + * Mode 0x10: Auto pre-decrement -(%rx) + * Mode 0x12: Auto post-decrement (%rx)- + * Mode 0x14: Auto pre-increment +(%rx) + * Mode 0x16: Auto post-increment (%rx)- + */ + oper->mode = ((desc >> 5) & 0x7) | 0x10; + oper->reg = desc & 0x1f; + break; + case 0xab: /* Indexed with byte displacement */ + oper->mode = 0xab; + desc = read_b(pa + offset++, ACC_IF, BUS_CPU); + oper->reg = (desc >> 4) & 0xf; + oper->reg2 = (desc & 0xf) + 16; + break; + case 0xbb: /* Indexed with halfword displacement */ + oper->mode = desc; + desc = read_b(pa + offset++, ACC_IF, BUS_CPU); + oper->reg = (desc >> 4) & 0xf; + oper->reg2 = (desc & 0xf) + 16; + break; + case 0xcb: /* Extended format 1: r16 - r31 */ + desc = read_b(pa + offset++, ACC_IF, BUS_CPU); + oper->mode = (desc >> 4) & 0xf; + oper->reg = (desc & 0xf) + 16; + break; + case 0xdb: /* Indexed with scaling */ + oper->mode = desc; + desc = read_b(pa + offset++, ACC_IF, BUS_CPU); + oper->reg = (desc >> 4) & 0xf; + oper->reg2 = (desc & 0xf) + 16; + break; + default: + oper->mode = (desc >> 4) & 0xf; + oper->reg = desc & 0xf; + break; + } +#else + /* + * WE 32100 only + */ + oper->mode = (desc >> 4) & 0xf; + oper->reg = desc & 0xf; +#endif + + oper->dtype = instr->mn->dtype; + oper->etype = *etype; + + switch (oper->mode) { + case 0: /* Positive Literal */ + case 1: /* Positive Literal */ + case 2: /* Positive Literal */ + case 3: /* Positive Literal */ + case 15: /* Negative literal */ + oper->embedded.b = desc; + oper->data = oper->embedded.b; + break; + case 4: /* Word Immediate, Register Mode */ + switch (oper->reg) { + case 15: /* Word Immediate */ + oper->embedded.w = (uint32) read_b(pa + offset++, ACC_IF, BUS_CPU); + oper->embedded.w |= ((uint32) read_b(pa + offset++, ACC_IF, BUS_CPU)) << 8u; + oper->embedded.w |= ((uint32) read_b(pa + offset++, ACC_IF, BUS_CPU)) << 16u; + oper->embedded.w |= ((uint32) read_b(pa + offset++, ACC_IF, BUS_CPU)) << 24u; + oper->data = oper->embedded.w; + break; + default: /* Register mode */ + oper->data = R[oper->reg]; + break; + } + break; + case 5: /* Halfword Immediate, Register Deferred Mode */ + switch (oper->reg) { + case 15: /* Halfword Immediate */ + oper->embedded.h = (uint16) read_b(pa + offset++, ACC_IF, BUS_CPU); + oper->embedded.h |= ((uint16) read_b(pa + offset++, ACC_IF, BUS_CPU)) << 8u; + oper->data = oper->embedded.h; + break; + case 11: /* INVALID */ + cpu_abort(NORMAL_EXCEPTION, INVALID_DESCRIPTOR); + return offset; + default: /* Register deferred mode */ + oper->data = R[oper->reg]; + break; + } + break; + case 6: /* Byte Immediate, FP Short Offset */ + switch (oper->reg) { + case 15: /* Byte Immediate */ + oper->embedded.b = read_b(pa + offset++, ACC_IF, BUS_CPU); + oper->data = oper->embedded.b; + break; + default: /* FP Short Offset */ + oper->embedded.b = oper->reg; + oper->data = oper->embedded.b; + break; + } + break; + case 7: /* Absolute, AP Short Offset */ + switch (oper->reg) { + case 15: /* Absolute */ + oper->embedded.w = (uint32) read_b(pa + offset++, ACC_IF, BUS_CPU); + oper->embedded.w |= ((uint32) read_b(pa + offset++, ACC_IF, BUS_CPU)) << 8u; + oper->embedded.w |= ((uint32) read_b(pa + offset++, ACC_IF, BUS_CPU)) << 16u; + oper->embedded.w |= ((uint32) read_b(pa + offset++, ACC_IF, BUS_CPU)) << 24u; + oper->data = oper->embedded.w; + break; + default: /* AP Short Offset */ + oper->embedded.b = oper->reg; + oper->data = oper->embedded.b; + break; + } + break; + case 8: /* Word Displacement */ + case 9: /* Word Displacement Deferred */ + oper->embedded.w = (uint32) read_b(pa + offset++, ACC_IF, BUS_CPU); + oper->embedded.w |= ((uint32) read_b(pa + offset++, ACC_IF, BUS_CPU)) << 8u; + oper->embedded.w |= ((uint32) read_b(pa + offset++, ACC_IF, BUS_CPU)) << 16u; + oper->embedded.w |= ((uint32) read_b(pa + offset++, ACC_IF, BUS_CPU)) << 24u; + oper->data = oper->embedded.w; + break; + case 10: /* Halfword Displacement */ + case 11: /* Halfword Displacement Deferred */ + oper->embedded.h = read_b(pa + offset++, ACC_IF, BUS_CPU); + oper->embedded.h |= ((uint16) read_b(pa + offset++, ACC_IF, BUS_CPU)) << 8u; + oper->data = oper->embedded.h; + break; + case 12: /* Byte Displacement */ + case 13: /* Byte Displacement Deferred */ + oper->embedded.b = read_b(pa + offset++, ACC_IF, BUS_CPU); + oper->data = oper->embedded.b; + break; + case 14: /* Absolute Deferred, Extended-Operand */ + switch (oper->reg) { + case 15: /* Absolute Deferred */ + oper->embedded.w = (uint32) read_b(pa + offset++, ACC_IF, BUS_CPU); + oper->embedded.w |= ((uint32) read_b(pa + offset++, ACC_IF, BUS_CPU)) << 8u; + oper->embedded.w |= ((uint32) read_b(pa + offset++, ACC_IF, BUS_CPU)) << 16u; + oper->embedded.w |= ((uint32) read_b(pa + offset++, ACC_IF, BUS_CPU)) << 24u; + break; + case 0: + case 2: + case 3: + case 4: + case 6: + case 7: /* Expanded Datatype */ + /* Recursively decode the remainder of the operand after + storing the expanded datatype */ + *etype = (int8) oper->reg; + oper->etype = *etype; + offset += decode_operand(pa + offset, instr, op_number, etype); + break; + default: + cpu_abort(NORMAL_EXCEPTION, RESERVED_DATATYPE); + break; + } + break; +#if defined(REV3) + case 0x10: /* Auto pre-decrement */ + case 0x12: /* Auto post-decrement */ + case 0x14: /* Auto pre-increment */ + case 0x16: /* Auto post-increment */ + oper->data = R[oper->reg]; + break; + case 0xab: /* Indexed with byte displacement */ + oper->embedded.b = read_b(pa + offset++, ACC_IF, BUS_CPU); + oper->data = oper->embedded.b; + break; + case 0xbb: /* Indexed with halfword displacement */ + oper->embedded.h = read_b(pa + offset++, ACC_IF, BUS_CPU); + oper->embedded.h |= ((uint16) read_b(pa + offset++, ACC_IF, BUS_CPU)) << 8u; + oper->data = oper->embedded.h; + break; + case 0xdb: /* Indexed with scaling */ + switch (op_type(oper)) { + case BT: + case SB: + oper->data = R[oper->reg]; + break; + case HW: + case UH: + oper->data = R[oper->reg] * 2; + break; + case WD: + case UW: + oper->data = R[oper->reg] * 4; + break; + } + + oper->data += R[oper->reg2]; + + break; +#endif + default: + cpu_abort(NORMAL_EXCEPTION, INVALID_DESCRIPTOR); + } + + return offset; +} + +/* + * Decode the instruction currently being pointed at by the PC. + * This routine does the following: + * 1. Read the opcode. + * 2. Determine the number of operands to decode based on + * the opcode type. + * 3. Fetch each opcode from main memory. + * + * This routine is guaranteed not to change state. + * + * returns: a Normal Exception if an error occured, or 0 on success. + */ +uint8 decode_instruction(instr *instr) +{ + uint8 offset = 0; + uint8 b1, b2; + uint16 hword_op; + uint32 pa; + mnemonic *mn = NULL; + int i; + int8 etype = -1; /* Expanded datatype (if any) */ + + clear_instruction(instr); + + pa = R[NUM_PC]; + + /* Store off the PC and and PSW for history keeping */ + instr->psw = R[NUM_PSW]; + instr->sp = R[NUM_SP]; + instr->pc = pa; + + if (read_operand(pa + offset++, &b1) != SCPE_OK) { + /* We tried to read out of a page that doesn't exist. We + need to let the operating system handle it.*/ + cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT); + return offset; + } + + /* It should never, ever happen that operand fetch + would cause a page fault. */ + + if (b1 == 0x30) { + read_operand(pa + offset++, &b2); + hword_op = (uint16) ((uint16)b1 << 8) | (uint16) b2; + for (i = 0; i < HWORD_OP_COUNT; i++) { + if (hword_ops[i].opcode == hword_op) { + mn = &hword_ops[i]; + break; + } + } + } else { + mn = &ops[b1]; + } + + if (mn == NULL) { + cpu_abort(NORMAL_EXCEPTION, ILLEGAL_OPCODE); + return offset; + } + + instr->mn = mn; + + if (mn->op_count < 0) { + cpu_abort(NORMAL_EXCEPTION, ILLEGAL_OPCODE); + return offset; + } + + if (mn->op_count == 0) { + /* Nothing else to do, we're done decoding. */ + return offset; + } + + switch (mn->mode) { + case OP_BYTE: + instr->operands[0].embedded.b = read_b(pa + offset++, ACC_IF, BUS_CPU); + instr->operands[0].mode = 6; + instr->operands[0].reg = 15; + break; + case OP_HALF: + instr->operands[0].embedded.h = read_b(pa + offset++, ACC_IF, BUS_CPU); + instr->operands[0].embedded.h |= (uint16)(read_b(pa + offset++, ACC_IF, BUS_CPU)) << 8; + instr->operands[0].mode = 5; + instr->operands[0].reg = 15; + break; + case OP_COPR: + instr->operands[0].embedded.w = (uint32) read_b(pa + offset++, ACC_IF, BUS_CPU); + instr->operands[0].embedded.w |= (uint32) read_b(pa + offset++, ACC_IF, BUS_CPU) << 8; + instr->operands[0].embedded.w |= (uint32) read_b(pa + offset++, ACC_IF, BUS_CPU) << 16; + instr->operands[0].embedded.w |= (uint32) read_b(pa + offset++, ACC_IF, BUS_CPU) << 24; + instr->operands[0].mode = 4; + instr->operands[0].reg = 15; + + /* Decode subsequent operands */ + for (i = 1; i < mn->op_count; i++) { + offset += decode_operand(pa + offset, instr, (uint8) i, &etype); + } + + break; + case OP_DESC: + for (i = 0; i < mn->op_count; i++) { + offset += decode_operand(pa + offset, instr, (uint8) i, &etype); + } + break; +#if defined(REV3) + case OP_DESB: + /* Operand 0 is a descriptor byte */ + offset += decode_operand(pa + offset, instr, 0, &etype); + /* Operand 1 is a signed byte offset */ + instr->operands[1].embedded.b = read_b(pa + offset++, ACC_IF, BUS_CPU); + break; + case OP_DESH: + /* Operand 0 is a descriptor byte */ + offset += decode_operand(pa + offset, instr, 0, &etype); + /* Operand 1 is a signed byte offset */ + instr->operands[1].embedded.h = read_b(pa + offset++, ACC_IF, BUS_CPU); + instr->operands[1].embedded.h |= (uint16)(read_b(pa + offset++, ACC_IF, BUS_CPU)) << 8; + break; +#endif + default: + break; + } + + return offset; +} + +static SIM_INLINE void cpu_context_switch_3(uint32 new_pcbp) +{ + if (R[NUM_PSW] & PSW_R_MASK) { + + R[0] = R[NUM_PCBP] + 64; + R[2] = read_w(R[0], ACC_AF, BUS_CPU); + R[0] += 4; + + while (R[2] != 0) { + R[1] = read_w(R[0], ACC_AF, BUS_CPU); + R[0] += 4; + + /* Execute MOVBLW instruction inside this loop */ + while (R[2] != 0) { + write_w(R[1], read_w(R[0], ACC_AF, BUS_CPU), BUS_CPU); + R[2]--; + R[0] += 4; + R[1] += 4; + } + + R[2] = read_w(R[0], ACC_AF, BUS_CPU); + R[0] += 4; + } + + R[0] = R[0] + 4; + } +} + +static SIM_INLINE void cpu_context_switch_2(uint32 new_pcbp) +{ + R[NUM_PCBP] = new_pcbp; + + /* Put new PSW, PC and SP values from PCB into registers */ + R[NUM_PSW] = read_w(R[NUM_PCBP], ACC_AF, BUS_CPU); + R[NUM_PSW] &= ~PSW_TM_MASK; /* Clear TM */ + R[NUM_PC] = read_w(R[NUM_PCBP] + 4, ACC_AF, BUS_CPU); + R[NUM_SP] = read_w(R[NUM_PCBP] + 8, ACC_AF, BUS_CPU); + + /* If i-bit is set, increment PCBP past initial context area */ + if (R[NUM_PSW] & PSW_I_MASK) { + R[NUM_PSW] &= ~PSW_I_MASK; + R[NUM_PCBP] += 12; + } +} + +static SIM_INLINE void cpu_context_switch_1(uint32 new_pcbp) +{ + /* Save the current PC in PCB */ + write_w(R[NUM_PCBP] + 4, R[NUM_PC], BUS_CPU); + + /* Copy the 'R' flag from the new PSW to the old PSW */ + R[NUM_PSW] &= ~PSW_R_MASK; + R[NUM_PSW] |= (read_w(new_pcbp, ACC_AF, BUS_CPU) & PSW_R_MASK); + + /* Save current PSW and SP in PCB */ + write_w(R[NUM_PCBP], R[NUM_PSW], BUS_CPU); + write_w(R[NUM_PCBP] + 8, R[NUM_SP], BUS_CPU); + + /* If R is set, save current R0-R8/FP/AP in PCB */ + if (R[NUM_PSW] & PSW_R_MASK) { + write_w(R[NUM_PCBP] + 24, R[NUM_FP], BUS_CPU); + write_w(R[NUM_PCBP] + 28, R[0], BUS_CPU); + write_w(R[NUM_PCBP] + 32, R[1], BUS_CPU); + write_w(R[NUM_PCBP] + 36, R[2], BUS_CPU); + write_w(R[NUM_PCBP] + 40, R[3], BUS_CPU); + write_w(R[NUM_PCBP] + 44, R[4], BUS_CPU); + write_w(R[NUM_PCBP] + 48, R[5], BUS_CPU); + write_w(R[NUM_PCBP] + 52, R[6], BUS_CPU); + write_w(R[NUM_PCBP] + 56, R[7], BUS_CPU); + write_w(R[NUM_PCBP] + 60, R[8], BUS_CPU); + write_w(R[NUM_PCBP] + 20, R[NUM_AP], BUS_CPU); + + R[NUM_FP] = R[NUM_PCBP] + 52; + } +} + +void cpu_on_interrupt(uint16 vec) +{ + uint32 new_psw_ptr, new_psw, new_pc; /* Quick-Interrupt */ + uint32 new_pcbp, new_pcbp_ptr; /* Full-Interrupt */ + t_bool quick; + + cpu_int_ack = vec; + + quick = (R[NUM_PSW] & PSW_QIE_MASK) != 0; + + sim_debug(IRQ_MSG, &cpu_dev, + "[%08x] [cpu_on_interrupt] vec=%02x (%d), quick=%d, sbd_int_req = %x, csr_data = %x\n", + R[NUM_PC], vec, vec, quick, sbd_int_req, csr_data); + + /* + * "If a nonmaskable interrupt request is received, an auto-vector + * interrupt acknowledge cycle is performed (as if an autovector + * interrupt at level 0 was being acknowledged) and no + * Interrupt-ID is fetched. The value 0 is used as the ID." + */ + if (cpu_nmi) { + vec = 0; + cpu_nmi = FALSE; + } + + cpu_km = TRUE; + + if (quick) { + /* + * Quick interrupt microsequence + */ + new_psw_ptr = (uint32)0x48c + (8 * (uint32)vec); + + /* Set ISC, TM, and ET to 2, 0, 0 before saving */ + R[NUM_PSW] &= ~(PSW_ISC_MASK|PSW_TM_MASK|PSW_ET_MASK); + R[NUM_PSW] |= (2 << PSW_ISC); + + abort_context = C_RESET_INT_STACK; + + write_w(R[NUM_ISP], R[NUM_PC], BUS_CPU); + write_w(R[NUM_ISP] + 4, R[NUM_PSW], BUS_CPU); + + /* Set ISC, TM, and ET to 1, 0, 0 */ + R[NUM_PSW] &= ~(PSW_ISC_MASK|PSW_TM_MASK|PSW_ET_MASK); + R[NUM_PSW] |= (2 << PSW_ISC); + + abort_context = C_RESET_SYSTEM_DATA; + + new_psw = read_w(new_psw_ptr, ACC_AF, BUS_CPU); + + /* Clear out PSW state */ + R[NUM_PSW] &= ~(QIE_PSW_MASK); + + /* Set PM to CM and clear out old CM */ + R[NUM_PSW] |= (R[NUM_PSW] & PSW_CM_MASK) >> 2; + R[NUM_PSW] &= ~(PSW_CM_MASK); + + /* Copy from new PSW */ + R[NUM_PSW] |= (new_psw & QIE_PSW_MASK); + + /* Grab the new PC */ + new_pc = read_w(new_psw_ptr + 4, ACC_AF, BUS_CPU); + + /* Finish ISP stack push */ + R[NUM_ISP] = R[NUM_ISP] + 8; + + /* Set new PSW ISC/TM/ET to 7/0/3 */ + R[NUM_PSW] &= ~(PSW_ISC_MASK|PSW_TM_MASK|PSW_ET_MASK); + R[NUM_PSW] |= 7 << PSW_ISC; + R[NUM_PSW] |= 3 << PSW_ET; + + /* Set new PC */ + R[NUM_PC] = new_pc; + + /* Done */ + abort_context = C_NONE; + } else { + /* + * Full interrupt microsequence + */ + new_pcbp_ptr = (uint32)0x8c + (4 * (uint32)vec); + + abort_context = C_RESET_SYSTEM_DATA; + + new_pcbp = read_w(new_pcbp_ptr, ACC_AF, BUS_CPU); + + abort_context = C_RESET_INT_STACK; + + /* Save the old PCBP */ + irq_push_word(R[NUM_PCBP]); + + /* Set ISC, TM, and ET to 0, 0, 1 before saving */ + R[NUM_PSW] &= ~(PSW_ISC_MASK|PSW_TM_MASK|PSW_ET_MASK); + R[NUM_PSW] |= (1 << PSW_ET); + + /* Context switch */ + cpu_context_switch_1(new_pcbp); + cpu_context_switch_2(new_pcbp); + + /* Set ISC, TM, and ET to 7, 0, 3 in new PSW */ + R[NUM_PSW] &= ~(PSW_ISC_MASK|PSW_TM_MASK|PSW_ET_MASK); + R[NUM_PSW] |= (7 << PSW_ISC); + R[NUM_PSW] |= (3 << PSW_ET); + + cpu_context_switch_3(new_pcbp); + + abort_context = C_NONE; + } + + cpu_km = FALSE; +} + +t_stat sim_instr(void) +{ + uint8 et, isc, trap; + + /* Temporary register used for overflow detection */ + t_uint64 result; + + /* Scratch space */ + uint32 a, b, c, d; + + /* Used for field calculation */ + uint32 width, offset; + uint32 mask; + + /* Generic index */ + uint32 i; + + /* Interrupt request IPL */ + uint8 ipl; + + /* Used by oprocessor instructions */ + uint32 coprocessor_word; + + operand *src1, *src2, *src3, *dst; + + stop_reason = 0; + + abort_reason = (uint32) setjmp(save_env); + + /* Exception handler. + * + * This gets a little messy because of exception contexts. If a + * normal-exception happens while we're handling a + * normal-exception, it needs to be treated as a stack-exception. + */ + if (abort_reason != 0) { + if (cpu_exception_stack_depth++ >= 10) { + return STOP_ESTK; + } + + if (cpu_unit.flags & UNIT_EXBRK) { + return STOP_EX; + } + + et = R[NUM_PSW] & PSW_ET_MASK; + isc = (R[NUM_PSW] & PSW_ISC_MASK) >> PSW_ISC; + + if (abort_reason == ABORT_EXC) { + switch(abort_context) { + case C_NORMAL_GATE_VECTOR: + cpu_on_normal_exception(N_GATE_VECTOR); + break; + case C_PROCESS_GATE_PCB: + cpu_on_process_exception(GATE_PCB_FAULT); + break; + case C_PROCESS_OLD_PCB: + cpu_on_process_exception(OLD_PCB_FAULT); + break; + case C_PROCESS_NEW_PCB: + cpu_on_process_exception(NEW_PCB_FAULT); + break; + case C_STACK_FAULT: + cpu_on_stack_exception(STACK_FAULT); + break; + case C_RESET_GATE_VECTOR: + cpu_on_reset_exception(GATE_VECTOR_FAULT); + break; + case C_RESET_SYSTEM_DATA: + cpu_on_reset_exception(SYSTEM_DATA_FAULT); + break; + case C_RESET_INT_STACK: + cpu_on_reset_exception(INTERRUPT_STACK_FAULT); + break; + default: + switch(et) { + case NORMAL_EXCEPTION: + cpu_on_normal_exception(isc); + break; + case STACK_EXCEPTION: + cpu_on_stack_exception(isc); + break; + case RESET_EXCEPTION: + cpu_on_reset_exception(isc); + break; + default: + stop_reason = STOP_EX; + break; + } + break; + } + } + /* Traps are handled at the end of instruction execution */ + } + + while (stop_reason == 0) { + trap = 0; + abort_context = C_NONE; + + if (sim_brk_summ && sim_brk_test(R[NUM_PC], SWMASK ('E'))) { + stop_reason = STOP_IBKPT; + break; + } + + if (cpu_exception_stack_depth > 0) { + cpu_exception_stack_depth--; + } + + AIO_CHECK_EVENT; + + if (sim_interval-- <= 0) { + if ((stop_reason = sim_process_event())) { + break; + } + } + + /* Process DMA requests */ + dmac_service_drqs(); + + /* + * Post-increment IU mode pointers (if needed). + * + * This is essentially a colossal hack. We never want to + * increment these pointers during an interlocked Read/Write + * operation, so we only increment after a CPU step has + * occured. + */ + if (iu_increment_a) { + increment_modep_a(); + } + if (iu_increment_b) { + increment_modep_b(); + } + + /* Interrupt Handling + * + * - NMI is always serviced first. + * - SBD interrupts are handled next in priority. + * - IO Bus boards are handled last. + */ + if (cpu_nmi) { + cpu_nmi = FALSE; + cpu_in_wait = FALSE; + cpu_on_interrupt(0); + } else if (cio_int_req) { + for (i = 0; i < CIO_SLOTS; i++) { + if ((cio_int_req & (1 << i)) && (PSW_CUR_IPL < cio[i].ipl)) { + cpu_in_wait = FALSE; + CIO_CLR_INT(i); + cpu_on_interrupt(cio[i].ivec); + break; + } + } + } else if (sbd_int_req) { + ipl = int_map[sbd_int_req]; + if (PSW_CUR_IPL < ipl) { + /* For the system board, interrupt vector is always + equal to IPL */ + cpu_in_wait = FALSE; + cpu_on_interrupt(ipl); + } + } + + if (cpu_in_wait) { + sim_idle(TMR_CLK, TRUE); + continue; + } + + /* Reset the TM bits */ + /* TODO: Figure out why we were doing this! */ + /* R[NUM_PSW] |= PSW_TM_MASK; */ + + /* Record the instruction for history */ + if (cpu_hist_size > 0) { + cpu_instr = &INST[cpu_hist_p]; + cpu_hist_p = (cpu_hist_p + 1) % cpu_hist_size; + } else { + cpu_instr = &inst; + } + + /* Decode the instruction */ + pc_incr = decode_instruction(cpu_instr); + + /* Make sure to update the valid bit for history keeping (if + * enabled) */ + cpu_instr->valid = TRUE; + + /* + * Operate on the decoded instruction. + */ + + /* Special case for coprocessor instructions */ + if (cpu_instr->mn->mode == OP_COPR) { + coprocessor_word = cpu_instr->operands[0].embedded.w; + } + + /* Get the operands */ + if (cpu_instr->mn->src_op1 >= 0) { + src1 = &cpu_instr->operands[cpu_instr->mn->src_op1]; + } + + if (cpu_instr->mn->src_op2 >= 0) { + src2 = &cpu_instr->operands[cpu_instr->mn->src_op2]; + } + + if (cpu_instr->mn->src_op3 >= 0) { + src3 = &cpu_instr->operands[cpu_instr->mn->src_op3]; + } + + if (cpu_instr->mn->dst_op >= 0) { + dst = &cpu_instr->operands[cpu_instr->mn->dst_op]; + } + + switch (cpu_instr->mn->opcode) { + case ADDW2: + case ADDH2: + case ADDB2: + a = cpu_read_op(src1); + b = cpu_read_op(dst); + add(a, b, dst); + break; + case ADDW3: + case ADDH3: + case ADDB3: + a = cpu_read_op(src1); + b = cpu_read_op(src2); + add(a, b, dst); + break; + case ALSW3: + a = cpu_read_op(src2); + b = cpu_read_op(src1); + result = (t_uint64)a << (b & 0x1f); + cpu_write_op(dst, result); + cpu_set_nz_flags(result, dst); + cpu_set_c_flag(0); + cpu_set_v_flag_op(result, dst); + break; + case ANDW2: + case ANDH2: + case ANDB2: + a = cpu_read_op(src1); + b = cpu_read_op(dst); + c = a & b; + cpu_write_op(dst, c); + cpu_set_nz_flags(c, dst); + cpu_set_c_flag(0); + cpu_set_v_flag_op(c, dst); + break; + case ANDW3: + case ANDH3: + case ANDB3: + a = cpu_read_op(src1); + b = cpu_read_op(src2); + c = a & b; + cpu_write_op(dst, c); + cpu_set_nz_flags(c, dst); + cpu_set_c_flag(0); + cpu_set_v_flag_op(c, dst); + break; + case BEH: + case BEH_D: + if (cpu_z_flag() == 1) { + pc_incr = sign_extend_h(dst->embedded.h); + } + break; + case BEB: + case BEB_D: + if (cpu_z_flag() == 1) { + pc_incr = sign_extend_b(dst->embedded.b); + } + break; + case BGH: + if ((cpu_n_flag() | cpu_z_flag()) == 0) { + pc_incr = sign_extend_h(dst->embedded.h); + } + break; + case BGB: + if ((cpu_n_flag() | cpu_z_flag()) == 0) { + pc_incr = sign_extend_b(dst->embedded.b); + } + break; + case BGEH: + if ((cpu_n_flag() == 0) | (cpu_z_flag() == 1)) { + pc_incr = sign_extend_h(dst->embedded.h); + } + break; + case BGEB: + if ((cpu_n_flag() == 0) | (cpu_z_flag() == 1)) { + pc_incr = sign_extend_b(dst->embedded.b); + } + break; + case BGEUH: + if (cpu_c_flag() == 0) { + pc_incr = sign_extend_h(dst->embedded.h); + } + break; + case BGEUB: + if (cpu_c_flag() == 0) { + pc_incr = sign_extend_b(dst->embedded.b); + } + break; + case BGUH: + if ((cpu_c_flag() | cpu_z_flag()) == 0) { + pc_incr = sign_extend_h(dst->embedded.h); + } + break; + case BGUB: + if ((cpu_c_flag() | cpu_z_flag()) == 0) { + pc_incr = sign_extend_b(dst->embedded.b); + } + break; + case BITW: + case BITH: + case BITB: + a = cpu_read_op(src1); + b = cpu_read_op(src2); + c = a & b; + cpu_set_nz_flags(c, src1); + cpu_set_c_flag(0); + cpu_set_v_flag(0); + break; + case BLH: + if ((cpu_n_flag() == 1) && (cpu_z_flag() == 0)) { + pc_incr = sign_extend_h(dst->embedded.h); + } + break; + case BLB: + if ((cpu_n_flag() == 1) && (cpu_z_flag() == 0)) { + pc_incr = sign_extend_b(dst->embedded.b); + } + break; + case BLEH: + if ((cpu_n_flag() | cpu_z_flag()) == 1) { + pc_incr = sign_extend_h(dst->embedded.h); + } + break; + case BLEB: + if ((cpu_n_flag() | cpu_z_flag()) == 1) { + pc_incr = sign_extend_b(dst->embedded.b); + } + break; + case BLEUH: + if ((cpu_c_flag() | cpu_z_flag()) == 1) { + pc_incr = sign_extend_h(dst->embedded.h); + } + break; + case BLEUB: + if ((cpu_c_flag() | cpu_z_flag()) == 1) { + pc_incr = sign_extend_b(dst->embedded.b); + } + break; + case BLUH: + if (cpu_c_flag() == 1) { + pc_incr = sign_extend_h(dst->embedded.h); + } + break; + case BLUB: + if (cpu_c_flag() == 1) { + pc_incr = sign_extend_b(dst->embedded.b); + } + break; + case BNEH: + case BNEH_D: + if (cpu_z_flag() == 0) { + pc_incr = sign_extend_h(dst->embedded.h); + } + break; + case BNEB: + case BNEB_D: + if (cpu_z_flag() == 0) { + pc_incr = sign_extend_b(dst->embedded.b); + } + break; + case BPT: + trap = BREAKPOINT_TRAP; + break; + case BRH: + pc_incr = sign_extend_h(dst->embedded.h); + break; + case BRB: + pc_incr = sign_extend_b(dst->embedded.b); + /* BRB is commonly used to halt the processor in a tight + * infinite loop. */ + if (pc_incr == 0) { + stop_reason = STOP_LOOP; + } + break; + case BSBH: + cpu_push_word(R[NUM_PC] + pc_incr); + pc_incr = sign_extend_h(dst->embedded.h); + break; + case BSBB: + cpu_push_word(R[NUM_PC] + pc_incr); + pc_incr = sign_extend_b(dst->embedded.b); + break; + case BVCH: + if (cpu_v_flag() == 0) { + pc_incr = sign_extend_h(dst->embedded.h); + } + break; + case BVCB: + if (cpu_v_flag() == 0) { + pc_incr = sign_extend_b(dst->embedded.b); + } + break; + case BVSH: + if (cpu_v_flag() == 1) { + pc_incr = sign_extend_h(dst->embedded.h); + } + break; + case BVSB: + if (cpu_v_flag() == 1) { + pc_incr = sign_extend_b(dst->embedded.b); + } + break; + case CALL: + a = cpu_effective_address(src1); + b = cpu_effective_address(dst); + write_w(R[NUM_SP] + 4, R[NUM_AP], BUS_CPU); + write_w(R[NUM_SP], R[NUM_PC] + pc_incr, BUS_CPU); + R[NUM_SP] += 8; + R[NUM_PC] = b; + R[NUM_AP] = a; + pc_incr = 0; + break; + case CFLUSH: + break; + case CALLPS: + if (cpu_execution_level() != EX_LVL_KERN) { + cpu_abort(NORMAL_EXCEPTION, PRIVILEGED_OPCODE); + break; + } + + a = R[0]; + + cpu_km = TRUE; + + abort_context = C_RESET_INT_STACK; + + irq_push_word(R[NUM_PCBP]); + + /* Set current PC to start of next instruction (always PC+2) */ + R[NUM_PC] += 2; + + /* Set old PSW ISC, TM, and ET to 0, 0, 1 */ + R[NUM_PSW] &= ~(PSW_ISC_MASK|PSW_TM_MASK|PSW_ET_MASK); + R[NUM_PSW] |= (1 << PSW_ET); + + cpu_context_switch_1(a); + abort_context = C_PROCESS_NEW_PCB; + cpu_context_switch_2(a); + + R[NUM_PSW] &= ~(PSW_ISC_MASK|PSW_TM_MASK|PSW_ET_MASK); + R[NUM_PSW] |= (7 << PSW_ISC); + R[NUM_PSW] |= (3 << PSW_ET); + + cpu_context_switch_3(a); + + abort_context = C_NONE; + + cpu_km = FALSE; + pc_incr = 0; + break; + case CLRW: + case CLRH: + case CLRB: + cpu_write_op(dst, 0); + cpu_set_n_flag(0); + cpu_set_z_flag(1); + cpu_set_c_flag(0); + cpu_set_v_flag(0); + break; + case CMPW: + case CMPH: + case CMPB: + a = cpu_read_op(src1); + b = cpu_read_op(src2); + + switch(op_type(src2)) { + case WD: + case UW: + cpu_set_n_flag((int32)b < (int32)a); + break; + case HW: + case UH: + cpu_set_n_flag((int16)b < (int16)a); + break; + case BT: + case SB: + cpu_set_n_flag((int8)b < (int8)a); + break; + default: + /* Unreachable */ + break; + } + + cpu_set_z_flag(b == a); + cpu_set_c_flag(b < a); + cpu_set_v_flag(0); + break; + case DECW: + case DECH: + case DECB: + a = cpu_read_op(dst); + sub(a, 1, dst); + break; + case DIVW2: + a = cpu_read_op(src1); + b = cpu_read_op(dst); + + if (a == 0) { + cpu_abort(NORMAL_EXCEPTION, INTEGER_ZERO_DIVIDE); + break; + } + + if (a == WORD_MASK && b == WD_MSB) { + cpu_set_v_flag(1); + } + + DIV(a, b, src1, dst, int32); + + cpu_write_op(dst, result); + cpu_set_nz_flags(result, dst); + cpu_set_c_flag(0); + break; + case DIVH2: + a = cpu_read_op(src1); + b = cpu_read_op(dst); + + if (a == 0) { + cpu_abort(NORMAL_EXCEPTION, INTEGER_ZERO_DIVIDE); + break; + } + + if (a == HALF_MASK && b == HW_MSB) { + cpu_set_v_flag(1); + } + + DIV(a, b, src1, dst, int16); + + cpu_write_op(dst, result); + cpu_set_nz_flags(result, dst); + cpu_set_c_flag(0); + break; + case DIVB2: + a = cpu_read_op(src1); + b = cpu_read_op(dst); + + if (a == 0) { + cpu_abort(NORMAL_EXCEPTION, INTEGER_ZERO_DIVIDE); + break; + } + + if (a == BYTE_MASK && b == BT_MSB) { + cpu_set_v_flag(1); + } + + result = (uint8)b / (uint8)a; + + cpu_write_op(dst, result); + cpu_set_nz_flags(result, dst); + cpu_set_c_flag(0); + break; + case DIVW3: + a = cpu_read_op(src1); + b = cpu_read_op(src2); + + if (a == 0) { + cpu_abort(NORMAL_EXCEPTION, INTEGER_ZERO_DIVIDE); + break; + } + + if (a == WORD_MASK && b == WD_MSB) { + cpu_set_v_flag(1); + } + + DIV(a, b, src1, src2, int32); + + cpu_write_op(dst, result); + cpu_set_nz_flags(result, dst); + cpu_set_c_flag(0); + break; + case DIVH3: + a = cpu_read_op(src1); + b = cpu_read_op(src2); + + if (a == 0) { + cpu_abort(NORMAL_EXCEPTION, INTEGER_ZERO_DIVIDE); + break; + } + + if (a == HALF_MASK && b == HW_MSB) { + cpu_set_v_flag(1); + } + + DIV(a, b, src1, src2, int16); + + cpu_write_op(dst, result); + cpu_set_nz_flags(result, dst); + cpu_set_c_flag(0); + break; + case DIVB3: + a = cpu_read_op(src1); + b = cpu_read_op(src2); + + if (a == 0) { + cpu_abort(NORMAL_EXCEPTION, INTEGER_ZERO_DIVIDE); + break; + } + + if (a == BYTE_MASK && b == BT_MSB) { + cpu_set_v_flag(1); + } + + result = (uint8)b / (uint8)a; + + cpu_write_op(dst, result); + cpu_set_nz_flags(result, dst); + cpu_set_c_flag(0); + break; + case MVERNO: + R[0] = CPU_VERSION; + break; + case ENBVJMP: + if (cpu_execution_level() != EX_LVL_KERN) { + cpu_abort(NORMAL_EXCEPTION, PRIVILEGED_OPCODE); + break; + } + mmu_enable(); + R[NUM_PC] = R[0]; + pc_incr = 0; + break; + case DISVJMP: + if (cpu_execution_level() != EX_LVL_KERN) { + cpu_abort(NORMAL_EXCEPTION, PRIVILEGED_OPCODE); + break; + } + mmu_disable(); + R[NUM_PC] = R[0]; + pc_incr = 0; + break; + case EXTFW: + case EXTFH: + case EXTFB: + width = (cpu_read_op(src1) & 0x1f) + 1; + offset = cpu_read_op(src2) & 0x1f; + if (width >= 32) { + mask = -1; + } else { + mask = (1ul << width) - 1; + } + mask = mask << offset; + + if (width + offset > 32) { + mask |= (1ul << ((width + offset) - 32)) - 1; + } + + a = cpu_read_op(src3); /* src */ + a &= mask; + a = a >> offset; + + cpu_write_op(dst, a); + cpu_set_nz_flags(a, dst); + cpu_set_c_flag(0); + cpu_set_v_flag_op(a, dst); + break; + case INCW: + case INCH: + case INCB: + a = cpu_read_op(dst); + add(a, 1, dst); + break; + case INSFW: + case INSFH: + case INSFB: + width = (cpu_read_op(src1) & 0x1f) + 1; + offset = cpu_read_op(src2) & 0x1f; + if (width >= 32) { + mask = -1; + } else { + mask = (1ul << width) - 1; + } + + a = cpu_read_op(src3) & mask; /* src */ + b = cpu_read_op(dst); /* dst */ + + b &= ~(mask << offset); + b |= (a << offset); + + cpu_write_op(dst, b); + cpu_set_nz_flags(b, dst); + cpu_set_c_flag(0); + cpu_set_v_flag_op(b, dst); + break; + case JMP: + R[NUM_PC] = cpu_effective_address(dst); + pc_incr = 0; + break; + case JSB: + cpu_push_word(R[NUM_PC] + pc_incr); + R[NUM_PC] = cpu_effective_address(dst); + pc_incr = 0; + break; + case LLSW3: + case LLSH3: + case LLSB3: + result = (t_uint64)cpu_read_op(src2) << (cpu_read_op(src1) & 0x1f); + cpu_write_op(dst, result); + cpu_set_nz_flags(result, dst); + cpu_set_c_flag(0); + cpu_set_v_flag_op(result, dst); + break; + case ARSW3: + case ARSH3: + case ARSB3: + a = cpu_read_op(src2); + b = cpu_read_op(src1) & 0x1f; + result = a >> b; + /* Ensure the MSB is copied appropriately */ + switch (op_type(src2)) { + case WD: + if (a & 0x80000000) { + result |= shift_32_table[b + 1]; + } + break; + case HW: + if (a & 0x8000) { + result |= shift_16_table[b + 1]; + } + break; + case BT: + if (a & 0x80) { + result |= shift_8_table[b + 1]; + } + break; + } + cpu_write_op(dst, result); + cpu_set_nz_flags(result, dst); + cpu_set_c_flag(0); + cpu_set_v_flag(0); + break; + case LRSW3: + a = (uint32) cpu_read_op(src2) >> (cpu_read_op(src1) & 0x1f); + cpu_write_op(dst, a); + cpu_set_nz_flags(a, dst); + cpu_set_c_flag(0); + cpu_set_v_flag_op(a, dst); + break; + case GATE: + cpu_km = TRUE; + if (R[NUM_SP] < read_w(R[NUM_PCBP] + 12, ACC_AF, BUS_CPU) || + R[NUM_SP] > read_w(R[NUM_PCBP] + 16, ACC_AF, BUS_CPU)) { + sim_debug(EXECUTE_MSG, &cpu_dev, + "[%08x] STACK OUT OF BOUNDS IN GATE. " + "SP=%08x, R[NUM_PCBP]+12=%08x, " + "R[NUM_PCBP]+16=%08x\n", + R[NUM_PC], + R[NUM_SP], + read_w(R[NUM_PCBP] + 12, ACC_AF, BUS_CPU), + read_w(R[NUM_PCBP] + 16, ACC_AF, BUS_CPU)); + cpu_abort(STACK_EXCEPTION, STACK_BOUND); + } + cpu_km = FALSE; + + abort_context = C_STACK_FAULT; + + /* Push PC+2 onto stack */ + write_w(R[NUM_SP], R[NUM_PC] + 2, BUS_CPU); + + /* Write 1, 0, 2 to ISC, TM, ET */ + R[NUM_PSW] &= ~(PSW_ISC_MASK|PSW_TM_MASK|PSW_ET_MASK); + R[NUM_PSW] |= (1 << PSW_ISC); + R[NUM_PSW] |= (2 << PSW_ET); + + /* Push PSW onto stack */ + write_w(R[NUM_SP] + 4, R[NUM_PSW], BUS_CPU); + + abort_context = C_NONE; + + /* Perform gate entry-point 2 */ + cpu_perform_gate(R[0] & 0x7c, + R[1] & 0x7ff8); + + /* Finish push of PC and PSW */ + R[NUM_SP] += 8; + pc_incr = 0; + +#if defined(REV3) + /* + * Both the WE 32100 and the WE 32200 processor manuals + * state that this is not a privileged instruction, and + * that it can be run from any processor level. This is + * true for the WE 32100, but not true for the WE + * 32200. Tests in the Rev 3 off-line processor + * diagnostics check to ensure that there is an exception + * raised when calling GATE in a non-privileged context. + */ + if (cpu_execution_level() != EX_LVL_KERN) { + cpu_abort(NORMAL_EXCEPTION, PRIVILEGED_OPCODE); + } +#endif + break; + case MCOMW: + case MCOMH: + case MCOMB: /* One's complement */ + a = ~(cpu_read_op(src1)); + cpu_write_op(dst, a); + cpu_set_nz_flags(a, dst); + cpu_set_c_flag(0); + cpu_set_v_flag_op(a, dst); + break; + case MNEGW: + case MNEGH: + case MNEGB: /* Two's complement */ + a = ~cpu_read_op(src1) + 1; + cpu_write_op(dst, a); + cpu_set_nz_flags(a, dst); + cpu_set_c_flag(0); + cpu_set_v_flag_op(a, dst); + break; + case MOVBLW: + while (R[2] != 0) { + a = read_w(R[0], ACC_AF, BUS_CPU); + write_w(R[1], a, BUS_CPU); + R[2]--; + R[0] += 4; + R[1] += 4; + } + break; + case STREND: + while (read_b(R[0], ACC_AF, BUS_CPU) != '\0') { + R[0]++; + } + break; + case SWAPWI: + case SWAPHI: + case SWAPBI: + a = cpu_read_op(dst); + cpu_write_op(dst, R[0]); + R[0] = a; + cpu_set_nz_flags(a, dst); + cpu_set_v_flag(0); + cpu_set_c_flag(0); + break; + case ROTW: + a = cpu_read_op(src1) & 0x1f; + b = (uint32) cpu_read_op(src2); + mask = (CHAR_BIT * sizeof(a) - 1); + d = (b >> a) | (b << ((~a + 1) & mask)); + cpu_write_op(dst, d); + cpu_set_nz_flags(d, dst); + cpu_set_v_flag(0); + cpu_set_c_flag(0); + break; + case MOVAW: + a = cpu_effective_address(src1); + cpu_write_op(dst, a); + cpu_set_nz_flags(a, dst); + cpu_set_v_flag(0); + cpu_set_c_flag(0); + break; + case MOVTRW: + a = cpu_effective_address(src1); + result = mmu_xlate_addr(a, ACC_MT); + cpu_write_op(dst, result); + cpu_set_nz_flags(result, dst); + cpu_set_v_flag(0); + cpu_set_c_flag(0); + break; + case MOVW: + case MOVH: + case MOVB: + a = cpu_read_op(src1); + cpu_write_op(dst, a); + + /* Flags are never set if the source or destination is the + PSW */ + if (!(op_is_psw(src1) || op_is_psw(dst))) { + cpu_set_nz_flags(a, dst); + cpu_set_c_flag(0); + cpu_set_v_flag_op(a, dst); + } + + /* However, if a move to PSW set the O bit, we have to + generate an overflow exception trap */ + if (op_is_psw(dst) && (R[NUM_PSW] & PSW_OE_MASK)) { + trap = INTEGER_OVERFLOW; + } + break; + case MODW2: + a = cpu_read_op(src1); + b = cpu_read_op(dst); + if (a == 0) { + cpu_abort(NORMAL_EXCEPTION, INTEGER_ZERO_DIVIDE); + break; + } + MOD(a, b, src1, dst, int32); + cpu_write_op(dst, result); + cpu_set_nz_flags(result, dst); + cpu_set_c_flag(0); + cpu_set_v_flag_op(result, dst); + break; + case MODH2: + a = cpu_read_op(src1); + b = cpu_read_op(dst); + if (a == 0) { + cpu_abort(NORMAL_EXCEPTION, INTEGER_ZERO_DIVIDE); + break; + } + MOD(a, b, src1, dst, int16); + cpu_write_op(dst, result); + cpu_set_nz_flags(result, dst); + cpu_set_c_flag(0); + cpu_set_v_flag_op(result, dst); + break; + case MODB2: + a = cpu_read_op(src1); + b = cpu_read_op(dst); + if (a == 0) { + cpu_abort(NORMAL_EXCEPTION, INTEGER_ZERO_DIVIDE); + break; + } + result = (uint8)b % (uint8)a; + cpu_write_op(dst, result); + cpu_set_nz_flags(result, dst); + cpu_set_c_flag(0); + cpu_set_v_flag_op(result, dst); + break; + break; + case MODW3: + a = cpu_read_op(src1); + b = cpu_read_op(src2); + if (a == 0) { + cpu_abort(NORMAL_EXCEPTION, INTEGER_ZERO_DIVIDE); + break; + } + MOD(a, b, src1, src2, int32); + cpu_write_op(dst, result); + cpu_set_nz_flags(result, dst); + cpu_set_c_flag(0); + cpu_set_v_flag_op(result, dst); + break; + case MODH3: + a = cpu_read_op(src1); + b = cpu_read_op(src2); + if (a == 0) { + cpu_abort(NORMAL_EXCEPTION, INTEGER_ZERO_DIVIDE); + break; + } + MOD(a, b, src1, src2, int16); + cpu_write_op(dst, result); + cpu_set_nz_flags(result, dst); + cpu_set_c_flag(0); + cpu_set_v_flag_op(result, dst); + break; + case MODB3: + a = cpu_read_op(src1); + b = cpu_read_op(src2); + if (a == 0) { + cpu_abort(NORMAL_EXCEPTION, INTEGER_ZERO_DIVIDE); + break; + } + result = (uint8)b % (uint8)a; + cpu_write_op(dst, result); + cpu_set_nz_flags(result, dst); + cpu_set_c_flag(0); + cpu_set_v_flag_op(result, dst); + break; + case MULW2: + result = (t_uint64)cpu_read_op(src1) * (t_uint64)cpu_read_op(dst); + cpu_write_op(dst, (uint32)(result & WORD_MASK)); + cpu_set_nz_flags((uint32)(result & WORD_MASK), dst); + cpu_set_c_flag(0); + cpu_set_v_flag_op(result, dst); + break; + case MULH2: + a = cpu_read_op(src1) * cpu_read_op(dst); + cpu_write_op(dst, a); + cpu_set_nz_flags(a, dst); + cpu_set_c_flag(0); + cpu_set_v_flag_op(result, dst); + break; + case MULB2: + a = cpu_read_op(src1) * cpu_read_op(dst); + cpu_write_op(dst, a); + cpu_set_nz_flags(a, dst); + cpu_set_c_flag(0); + cpu_set_v_flag_op(result, src1); + break; + case MULW3: + result = (t_uint64)cpu_read_op(src1) * (t_uint64)cpu_read_op(src2); + cpu_write_op(dst, (uint32)(result & WORD_MASK)); + cpu_set_nz_flags((uint32)(result & WORD_MASK), dst); + cpu_set_c_flag(0); + cpu_set_v_flag_op(result, dst); + break; + case MULH3: + a = cpu_read_op(src1) * cpu_read_op(src2); + cpu_write_op(dst, a); + cpu_set_nz_flags(a, dst); + cpu_set_c_flag(0); + cpu_set_v_flag_op(result, dst); + break; + case MULB3: + a = cpu_read_op(src1) * cpu_read_op(src2); + cpu_write_op(dst, a); + cpu_set_nz_flags(a, dst); + cpu_set_c_flag(0); + cpu_set_v_flag_op(result, dst); + break; + case NOP: + break; + case NOP2: + pc_incr += 1; + break; + case NOP3: + pc_incr += 2; + break; + case ORW2: + case ORH2: + case ORB2: + a = (cpu_read_op(src1) | cpu_read_op(dst)); + cpu_write_op(dst, a); + cpu_set_nz_flags(a, dst); + cpu_set_c_flag(0); + cpu_set_v_flag_op(a, dst); + break; + case ORW3: + case ORH3: + case ORB3: + a = (cpu_read_op(src1) | cpu_read_op(src2)); + cpu_write_op(dst, a); + cpu_set_nz_flags(a, dst); + cpu_set_c_flag(0); + cpu_set_v_flag_op(a, dst); + break; + case POPW: + /* N.B. "If dst is the stack pointer (%sp), the results + are indeterminate". The ordering here is important. If + we decrement SP before writing the results, we end up + in a weird, bad state. */ + a = read_w(R[NUM_SP] - 4, ACC_AF, BUS_CPU); + cpu_write_op(dst, a); + R[NUM_SP] -= 4; + cpu_set_nz_flags(a, dst); + cpu_set_c_flag(0); + cpu_set_v_flag(0); + break; + case PUSHAW: + a = cpu_effective_address(src1); + cpu_push_word(a); + cpu_set_nz_flags(a, src1); + cpu_set_c_flag(0); + cpu_set_v_flag(0); + break; + case PUSHW: + a = cpu_read_op(src1); + cpu_push_word(a); + cpu_set_nz_flags(a, src1); + cpu_set_c_flag(0); + cpu_set_v_flag(0); + break; + case RGEQ: + if (cpu_n_flag() == 0 || cpu_z_flag() == 1) { + R[NUM_PC] = cpu_pop_word(); + pc_incr = 0; + } + break; + case RGEQU: + if (cpu_c_flag() == 0) { + R[NUM_PC] = cpu_pop_word(); + pc_incr = 0; + } + break; + case RGTR: + if ((cpu_n_flag() | cpu_z_flag()) == 0) { + R[NUM_PC] = cpu_pop_word(); + pc_incr = 0; + } + break; + case RNEQ: + case RNEQU: + if (cpu_z_flag() == 0) { + R[NUM_PC] = cpu_pop_word(); + pc_incr = 0; + } + break; + case RET: + a = R[NUM_AP]; + b = read_w(R[NUM_SP] - 4, ACC_AF, BUS_CPU); + c = read_w(R[NUM_SP] - 8, ACC_AF, BUS_CPU); + R[NUM_AP] = b; + R[NUM_PC] = c; + R[NUM_SP] = a; + pc_incr = 0; + break; + case RETG: + abort_context = C_STACK_FAULT; + a = read_w(R[NUM_SP] - 4, ACC_AF, BUS_CPU); /* PSW */ + b = read_w(R[NUM_SP] - 8, ACC_AF, BUS_CPU); /* PC */ + abort_context = C_NONE; + if ((a & PSW_CM_MASK) < (R[NUM_PSW] & PSW_CM_MASK)) { + sim_debug(EXECUTE_MSG, &cpu_dev, + "[%08x] Illegal level change. New level=%d, Cur level=%d\n", + R[NUM_PC], + (a & PSW_CM_MASK) >> PSW_CM, + (R[NUM_PSW] & PSW_CM_MASK) >> PSW_CM); + cpu_abort(NORMAL_EXCEPTION, ILLEGAL_LEVEL_CHANGE); + break; + } + /* Clear some state and move it from the current PSW */ + a &= ~PSW_IPL_MASK; + a &= ~PSW_CFD_MASK; + a &= ~PSW_QIE_MASK; + a &= ~PSW_CD_MASK; + a &= ~PSW_R_MASK; + a &= ~PSW_ISC_MASK; + a &= ~PSW_TM_MASK; + a &= ~PSW_ET_MASK; + + a |= (R[NUM_PSW] & PSW_IPL_MASK); + a |= (R[NUM_PSW] & PSW_CFD_MASK); + a |= (R[NUM_PSW] & PSW_QIE_MASK); + a |= (R[NUM_PSW] & PSW_CD_MASK); + a |= (R[NUM_PSW] & PSW_R_MASK); + a |= (7 << PSW_ISC); + a |= (3 << PSW_ET); + + R[NUM_PSW] = a; + R[NUM_PC] = b; + + R[NUM_SP] -= 8; + pc_incr = 0; + break; + case RETPS: + if (cpu_execution_level() != EX_LVL_KERN) { + cpu_abort(NORMAL_EXCEPTION, PRIVILEGED_OPCODE); + break; + } + + /* Force kernel memory access */ + cpu_km = TRUE; + + abort_context = C_RESET_INT_STACK; + /* Restore process state */ + a = irq_pop_word(); /* New process PCBP */ + + abort_context = C_PROCESS_OLD_PCB; + b = read_w(a, ACC_AF, BUS_CPU); /* New PSW */ + + abort_context = C_PROCESS_NEW_PCB; + /* Copy the 'R' flag from the new PSW to the old PSW */ + R[NUM_PSW] &= ~PSW_R_MASK; + R[NUM_PSW] |= (b & PSW_R_MASK); + + /* a now holds the new PCBP */ + cpu_context_switch_2(a); + + /* Perform block moves, if any */ + cpu_context_switch_3(a); + + /* Restore registers if R bit is set */ + if (R[NUM_PSW] & PSW_R_MASK) { + R[NUM_FP] = read_w(a + 24, ACC_AF, BUS_CPU); + R[0] = read_w(a + 28, ACC_AF, BUS_CPU); + R[1] = read_w(a + 32, ACC_AF, BUS_CPU); + R[2] = read_w(a + 36, ACC_AF, BUS_CPU); + R[3] = read_w(a + 40, ACC_AF, BUS_CPU); + R[4] = read_w(a + 44, ACC_AF, BUS_CPU); + R[5] = read_w(a + 48, ACC_AF, BUS_CPU); + R[6] = read_w(a + 52, ACC_AF, BUS_CPU); + R[7] = read_w(a + 56, ACC_AF, BUS_CPU); + R[8] = read_w(a + 60, ACC_AF, BUS_CPU); + R[NUM_AP] = read_w(a + 20, ACC_AF, BUS_CPU); + } + + abort_context = C_NONE; + + /* Un-force kernel memory access */ + cpu_km = FALSE; + pc_incr = 0; + break; + case INTACK: + R[0] = cpu_int_ack << 2; + break; + case EXTOP: + sim_debug(EXECUTE_MSG, &cpu_dev, + "[%08x] EXTOP instruction.\n", + R[NUM_PC]); + cpu_abort(NORMAL_EXCEPTION, RESERVED_OPCODE); + break; + case SPOP: + /* Memory fault is signaled when no support processor is + active */ + if (mau_broadcast(coprocessor_word, 0, 0) != SCPE_OK) { + cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT); + } + break; + case SPOPD2: + case SPOPS2: + case SPOPT2: + a = cpu_effective_address(src1); + b = cpu_effective_address(dst); + if (mau_broadcast(coprocessor_word, a, b) != SCPE_OK) { + cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT); + } + break; + case SPOPRD: + case SPOPRS: + case SPOPRT: + a = cpu_effective_address(src1); + if (mau_broadcast(coprocessor_word, a, 0) != SCPE_OK) { + cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT); + } + break; + case SPOPWD: + case SPOPWS: + case SPOPWT: + a = cpu_effective_address(dst); + if (mau_broadcast(coprocessor_word, 0, a) != SCPE_OK) { + cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT); + } + break; + case SUBW2: + case SUBH2: + case SUBB2: + a = cpu_read_op(dst); + b = cpu_read_op(src1); + sub(a, b, dst); + break; + case SUBW3: + case SUBH3: + case SUBB3: + a = cpu_read_op(src2); + b = cpu_read_op(src1); + sub(a, b, dst); + break; + case RESTORE: + a = R[NUM_FP] - 28; /* Old FP */ + b = read_w(a, ACC_AF, BUS_CPU); /* Old FP */ + c = R[NUM_FP] - 24; /* Old save point */ + + for (d = src1->reg; d < NUM_FP; d++) { + R[d] = read_w(c, ACC_AF, BUS_CPU); + c += 4; + } + + R[NUM_FP] = b; /* Restore FP */ + R[NUM_SP] = a; /* Restore SP */ + break; + case RGTRU: + if ((cpu_c_flag() & cpu_z_flag()) == 0) { + R[NUM_PC] = cpu_pop_word(); + pc_incr = 0; + } + break; + case RLEQ: + if ((cpu_n_flag() | cpu_z_flag()) == 1) { + R[NUM_PC] = cpu_pop_word(); + pc_incr = 0; + } + break; + case RLEQU: + if ((cpu_c_flag() | cpu_z_flag()) == 1) { + R[NUM_PC] = cpu_pop_word(); + pc_incr = 0; + } + break; + case RLSS: + if ((cpu_n_flag() == 1) & (cpu_z_flag() == 0)) { + R[NUM_PC] = cpu_pop_word(); + pc_incr = 0; + } + break; + case RLSSU: + if (cpu_c_flag() == 1) { + R[NUM_PC] = cpu_pop_word(); + pc_incr = 0; + } + break; + case REQL: + if (cpu_z_flag() == 1) { + R[NUM_PC] = cpu_pop_word(); + pc_incr = 0; + } + break; + case REQLU: + if (cpu_z_flag() == 1) { + R[NUM_PC] = cpu_pop_word(); + pc_incr = 0; + } + break; + case RSB: + R[NUM_PC] = cpu_pop_word(); + pc_incr = 0; + break; + case RVC: + if (cpu_v_flag() == 0) { + R[NUM_PC] = cpu_pop_word(); + pc_incr = 0; + } + break; + case RVS: + if (cpu_v_flag() == 1) { + R[NUM_PC] = cpu_pop_word(); + pc_incr = 0; + } + break; + case SAVE: + /* Save the FP register */ + write_w(R[NUM_SP], R[NUM_FP], BUS_CPU); + + /* Save all the registers from the one identified by the + src operand up to FP (exclusive) */ + for (a = src1->reg, b = 4; a < NUM_FP; a++, b += 4) { + write_w(R[NUM_SP] + b, R[a], BUS_CPU); + } + + R[NUM_SP] = R[NUM_SP] + 28; + R[NUM_FP] = R[NUM_SP]; + break; + case STRCPY: + /* The STRCPY instruction will always copy the NULL + * terminator of a string. However, copying the NULL + * terminator never increments the source or destination + * pointer! */ + while (1) { + a = read_b(R[0], ACC_AF, BUS_CPU); + write_b(R[1], (uint8) a, BUS_CPU); + if (a == '\0') { + break; + } + R[0]++; + R[1]++; + } + break; + case TSTW: + a = cpu_read_op(src1); + cpu_set_n_flag((int32)a < 0); + cpu_set_z_flag(a == 0); + cpu_set_c_flag(0); + cpu_set_v_flag(0); + break; + case TSTH: + a = cpu_read_op(src1); + cpu_set_n_flag((int16)a < 0); + cpu_set_z_flag(a == 0); + cpu_set_c_flag(0); + cpu_set_v_flag(0); + break; + case TSTB: + a = cpu_read_op(src1); + cpu_set_n_flag((int8)a < 0); + cpu_set_z_flag(a == 0); + cpu_set_c_flag(0); + cpu_set_v_flag(0); + break; + case WAIT: + if (cpu_execution_level() != EX_LVL_KERN) { + cpu_abort(NORMAL_EXCEPTION, PRIVILEGED_OPCODE); + break; + } + cpu_in_wait = TRUE; + break; + case XORW2: + case XORH2: + case XORB2: + a = (cpu_read_op(src1) ^ cpu_read_op(dst)); + cpu_write_op(dst, a); + cpu_set_nz_flags(a, dst); + cpu_set_c_flag(0); + cpu_set_v_flag_op(a, dst); + break; + case XORW3: + case XORH3: + case XORB3: + a = (cpu_read_op(src1) ^ cpu_read_op(src2)); + cpu_write_op(dst, a); + cpu_set_nz_flags(a, dst); + cpu_set_c_flag(0); + cpu_set_v_flag_op(a, dst); + break; +#if defined(REV3) + case ADDPB2: + a = cpu_read_op(src1); + b = cpu_read_op(dst); + result = add_bcd(a, b); /* sets flags */ + cpu_write_op(dst, result); + break; + case ADDPB3: + a = cpu_read_op(src1); + b = cpu_read_op(src2); + result = add_bcd(a, b); /* sets flags */ + cpu_write_op(dst, result); + break; + case DTB: + a = cpu_read_op(dst); + result = a - 1; + cpu_write_op(dst, (uint32)(result & WORD_MASK)); + if ((int32)result > -1) { + pc_incr = sign_extend_b(src1->embedded.b); + } + sim_debug(EXECUTE_MSG, &cpu_dev, + "[%08x] DTB: dst=%08x r=%08x emb=%04x\n", + R[NUM_PC], a, (uint32)(result & WORD_MASK), src1->embedded.h); + break; + case DTH: + a = cpu_read_op(dst); + result = a - 1; + cpu_write_op(dst, (uint32)(result & WORD_MASK)); + if ((int32)result > -1) { + pc_incr = sign_extend_h(src1->embedded.h); + } + sim_debug(EXECUTE_MSG, &cpu_dev, + "[%08x] DTH: dst=%08x r=%08x emb=%04x\n", + R[NUM_PC], a, (uint32)(result & WORD_MASK), src1->embedded.h); + break; + case TEDTB: + if (cpu_z_flag() == 0) { + a = cpu_read_op(dst); + result = a - 1; + cpu_write_op(dst, (uint32)(result & WORD_MASK)); + if ((int32)result > -1) { + pc_incr = sign_extend_b(src1->embedded.b); + } + } + break; + case TEDTH: + if (cpu_z_flag() == 0) { + a = cpu_read_op(dst); + result = a - 1; + cpu_write_op(dst, (uint32)(result & WORD_MASK)); + if ((int32)result > -1) { + pc_incr = sign_extend_h(src1->embedded.h); + } + } + break; + case TGDTB: + if ((cpu_n_flag() | cpu_z_flag()) == 1) { + a = cpu_read_op(dst); + result = a - 1; + cpu_write_op(dst, (uint32)(result & WORD_MASK)); + if ((int32)result > -1) { + pc_incr = sign_extend_b(src1->embedded.b); + } + } + break; + case TGDTH: + if ((cpu_n_flag() | cpu_z_flag()) == 1) { + a = cpu_read_op(dst); + result = a - 1; + cpu_write_op(dst, (uint32)(result & WORD_MASK)); + if ((int32)result > -1) { + pc_incr = sign_extend_h(src1->embedded.h); + } + } + break; + case TGEDTB: + if ((cpu_n_flag() == 1) & (cpu_z_flag() == 0)) { + a = cpu_read_op(dst); + result = a - 1; + cpu_write_op(dst, (uint32)(result & WORD_MASK)); + if ((int32)result > -1) { + pc_incr = sign_extend_b(src1->embedded.b); + } + } + break; + case TGEDTH: + if ((cpu_n_flag() == 1) & (cpu_z_flag() == 0)) { + a = cpu_read_op(dst); + result = a - 1; + cpu_write_op(dst, (uint32)(result & WORD_MASK)); + if ((int32)result > -1) { + pc_incr = sign_extend_h(src1->embedded.h); + } + } + break; + case TNEDTB: + if (cpu_z_flag() == 1) { + a = cpu_read_op(dst); + result = a - 1; + cpu_write_op(dst, (uint32)(result & WORD_MASK)); + if ((int32)result > -1) { + pc_incr = sign_extend_b(src1->embedded.b); + } + } + break; + case TNEDTH: + if (cpu_z_flag() == 1) { + a = cpu_read_op(dst); + result = a - 1; + cpu_write_op(dst, (uint32)(result & WORD_MASK)); + if ((int32)result > -1) { + pc_incr = sign_extend_h(src1->embedded.h); + } + } + break; + case SUBPB2: + a = cpu_read_op(src1); + b = cpu_read_op(dst); + result = sub_bcd(b, a); /* sets flags */ + cpu_write_op(dst, result); + break; + case SUBPB3: + a = cpu_read_op(src1); + b = cpu_read_op(src2); + result = sub_bcd(b, a); /* sets flags */ + cpu_write_op(dst, result); + break; + case PACKB: + a = cpu_read_op(src1); + b = ((a & 0x0f00) >> 4) | (a & 0xf); + cpu_write_op(dst, b); + break; + case UNPACKB: + a = cpu_read_op(src1); /* d1, d0 */ + b = cpu_read_op(src2); /* d3, d2 */ + c = ((b & 0xf0) << 8) | ((a & 0xf0) << 4) | + ((b & 0xf) << 4) | ((a & 0xf)); /* d3, d1, d2, d0 */ + cpu_write_op(dst, c); + break; + case CASWI: + a = cpu_read_op(src1); + b = cpu_read_op(src2); + c = cpu_read_op(dst); + result = c - b; + + if (result == 0) { + cpu_write_op(dst, a); + } else { + cpu_write_op(src2, c); + } + + cpu_set_n_flag((int32)result < 0); + cpu_set_z_flag(result == 0); + cpu_set_c_flag((uint32)b > (uint32)c); + cpu_set_v_flag_op(result, dst); + break; + case SETX: + R[NUM_PSW] |= (1 << PSW_X); + break; + case CLRX: + R[NUM_PSW] &= ~(1 << PSW_X); + break; + case RETQINT: + abort_context = C_RESET_INT_STACK; + + /* Get old PSW value from interrupt stack */ + a = read_w(R[NUM_ISP] - 4, ACC_AF, BUS_CPU); + + /* Update PSW */ + R[NUM_PSW] &= ~(QIE_PSW_MASK); + R[NUM_PSW] |= (a & QIE_PSW_MASK); + + /* Get old PC value from interrupt stack */ + b = read_w(R[NUM_ISP] - 8, ACC_AF, BUS_CPU); + + /* Set new PC */ + R[NUM_PC] = b; + + /* Finish interrupt stack pop */ + R[NUM_ISP] = R[NUM_ISP] - 8; + + /* Set new PSW ISC/TM/ET to 7/0/3 */ + R[NUM_PSW] &= ~(PSW_ISC_MASK|PSW_TM_MASK|PSW_ET_MASK); + R[NUM_PSW] |= 7 << PSW_ISC; + R[NUM_PSW] |= 3 << PSW_ET; + + /* Done */ + abort_context = C_NONE; + break; + case UCALLPS: + if ((R[NUM_PSW] & PSW_EXUC_MASK) == 0) { + cpu_abort(NORMAL_EXCEPTION, ILLEGAL_OPCODE); + } + + cpu_km = TRUE; + + /* Get the new PCBP */ + abort_context = C_RESET_SYSTEM_DATA; + a = read_w(0x488, ACC_AF, BUS_CPU); + + /* Save the existing PCBP */ + abort_context = C_RESET_INT_STACK; + irq_push_word(R[NUM_PCBP]); + + /* Prepare the new PC to be pushed on the stack */ + R[NUM_PC] = R[NUM_PC] + 2; + + /* Set ISC/TM/ET to 0/0/1 */ + R[NUM_PSW] &= ~(PSW_ISC_MASK|PSW_TM_MASK|PSW_ET_MASK); + R[NUM_PSW] |= 1 << PSW_ET; + + cpu_context_switch_1(a); + abort_context = C_PROCESS_NEW_PCB; + cpu_context_switch_2(a); + + /* Set ISC/TM/ET to 7/0/3 */ + R[NUM_PSW] &= ~(PSW_ISC_MASK|PSW_TM_MASK|PSW_ET_MASK); + R[NUM_PSW] |= 7 << PSW_ISC; + R[NUM_PSW] |= 3 << PSW_ET; + + cpu_context_switch_3(a); + + abort_context = C_NONE; + cpu_km = FALSE; + + break; +#endif + default: + sim_debug(EXECUTE_MSG, &cpu_dev, + "[%08x] Illegal Opcode 0x%x\n", + R[NUM_PC], cpu_instr->mn->opcode); + cpu_abort(NORMAL_EXCEPTION, ILLEGAL_OPCODE); + }; + + /* Increment the PC appropriately */ + R[NUM_PC] += pc_incr; + + /* If TE and TM are both set, generate a trace trap */ + if ((R[NUM_PSW] & PSW_TE_MASK) && (R[NUM_PSW] & PSW_TM_MASK)) { + trap = TRACE_TRAP; + } + + /* Handle traps */ + if (trap) { + R[NUM_PSW] &= ~(PSW_ET_MASK); + R[NUM_PSW] &= ~(PSW_ISC_MASK); + R[NUM_PSW] |= NORMAL_EXCEPTION; + R[NUM_PSW] |= (uint32) (trap << PSW_ISC); + cpu_on_normal_exception(trap); + } + } + + return stop_reason; +} + +static SIM_INLINE void cpu_on_process_exception(uint8 isc) +{ + uint32 new_pcbp; + + sim_debug(EXECUTE_MSG, &cpu_dev, + "[cpu_on_process_exception %d] SP=%08x PCBP=%08x ISP=%08x\n", + isc, R[NUM_SP], R[NUM_PCBP], R[NUM_ISP]); + + cpu_km = TRUE; + + abort_context = C_RESET_SYSTEM_DATA; + new_pcbp = read_w(0x84, ACC_AF, BUS_CPU); + + abort_context = C_RESET_INT_STACK; + irq_push_word(R[NUM_PCBP]); + + cpu_context_switch_2(new_pcbp); + + /* Set TM and ET to 0 and 3 in new PSW */ + R[NUM_PSW] &= ~(PSW_TM_MASK|PSW_ET_MASK); + R[NUM_PSW] |= (3 << PSW_ET); + + cpu_km = FALSE; + abort_context = C_NONE; + return; +} + +static SIM_INLINE void cpu_on_reset_exception(uint8 isc) +{ + uint32 new_pcbp; + + sim_debug(EXECUTE_MSG, &cpu_dev, + "[cpu_on_reset_exception %d] SP=%08x PCBP=%08x ISP=%08x\n", + isc, R[NUM_SP], R[NUM_PCBP], R[NUM_ISP]); + + if (isc == EXTERNAL_RESET) { + R[NUM_PSW] &= ~(PSW_R_MASK); + } + + cpu_km = TRUE; + + mmu_disable(); + + abort_context = C_RESET_SYSTEM_DATA; + new_pcbp = read_w(0x80, ACC_AF, BUS_CPU); + + abort_context = C_RESET_NEW_PCB; + cpu_context_switch_2(new_pcbp); + + cpu_km = FALSE; + abort_context = C_NONE; +} + +static SIM_INLINE void cpu_on_stack_exception(uint8 isc) +{ + uint32 new_pcbp; + + sim_debug(EXECUTE_MSG, &cpu_dev, + "[cpu_on_stack_exception %d] SP=%08x PCBP=%08x ISP=%08x\n", + isc, R[NUM_SP], R[NUM_PCBP], R[NUM_ISP]); + + abort_context = C_RESET_SYSTEM_DATA; + cpu_km = TRUE; + new_pcbp = read_w(0x88, ACC_AF, BUS_CPU); + + abort_context = C_RESET_INT_STACK; + irq_push_word(R[NUM_PCBP]); + + abort_context = C_PROCESS_OLD_PCB; + R[NUM_PSW] &= ~(PSW_ET_MASK|PSW_ISC_MASK); + R[NUM_PSW] |= (2 << PSW_ET); + R[NUM_PSW] |= (uint32) (isc << PSW_ISC); + + cpu_context_switch_1(new_pcbp); + cpu_context_switch_2(new_pcbp); + + /* Set ISC, TM, and ET to 7, 0, 3 in new PSW */ + R[NUM_PSW] &= ~(PSW_ISC_MASK|PSW_TM_MASK|PSW_ET_MASK); + R[NUM_PSW] |= (7 << PSW_ISC); + R[NUM_PSW] |= (3 << PSW_ET); + + cpu_km = FALSE; + abort_context = C_NONE; +} + +static SIM_INLINE void cpu_on_normal_exception(uint8 isc) +{ + sim_debug(EXECUTE_MSG, &cpu_dev, + "[cpu_on_normal_exception %d] %%sp=%08x abort_context=%d\n", + isc, R[NUM_SP], abort_context); + + cpu_km = TRUE; + if (R[NUM_SP] < read_w(R[NUM_PCBP] + 12, ACC_AF, BUS_CPU) || + R[NUM_SP] > read_w(R[NUM_PCBP] + 16, ACC_AF, BUS_CPU)) { + sim_debug(EXECUTE_MSG, &cpu_dev, + "STACK OUT OF BOUNDS IN EXCEPTION HANDLER. " + "SP=%08x, R[NUM_PCBP]+12=%08x, " + "R[NUM_PCBP]+16=%08x\n", + R[NUM_SP], + read_w(R[NUM_PCBP] + 12, ACC_AF, BUS_CPU), + read_w(R[NUM_PCBP] + 16, ACC_AF, BUS_CPU)); + cpu_abort(STACK_EXCEPTION, STACK_BOUND); + } + cpu_km = FALSE; + + /* Set context for STACK (FAULT) */ + abort_context = C_STACK_FAULT; + /* Save address of next instruction to stack */ + write_w(R[NUM_SP], R[NUM_PC], BUS_CPU); + + /* Write 0, 3 to TM, ET fields of PSW */ + R[NUM_PSW] &= ~(PSW_TM_MASK|PSW_ET_MASK); + R[NUM_PSW] |= (3 << PSW_ET); + + /* Save PSW to stack */ + write_w(R[NUM_SP] + 4, R[NUM_PSW], BUS_CPU); + + /* Set context for RESET (GATE VECTOR) */ + abort_context = C_RESET_GATE_VECTOR; + cpu_perform_gate(0, ((uint32) isc) << 3); + + /* Finish push of old PC and PSW */ + R[NUM_SP] += 8; + abort_context = C_NONE; +} + +static SIM_INLINE void cpu_perform_gate(uint32 index1, uint32 index2) +{ + uint32 gate_l2, new_psw; + + abort_context = C_NORMAL_GATE_VECTOR; + cpu_km = TRUE; + + gate_l2 = read_w(index1, ACC_AF, BUS_CPU) + index2; + + /* Get new PSW from second-level table */ + new_psw = read_w(gate_l2, ACC_AF, BUS_CPU); + + /* Clear state in PSW */ + new_psw &= ~(PSW_PM_MASK|PSW_IPL_MASK|PSW_R_MASK| + PSW_ISC_MASK|PSW_TM_MASK|PSW_ET_MASK); + + /* Set PM in new PSW */ + new_psw |= (R[NUM_PSW] & PSW_CM_MASK) >> 2; /* PM */ + new_psw |= (R[NUM_PSW] & PSW_IPL_MASK); /* IPL */ + new_psw |= (R[NUM_PSW] & PSW_R_MASK); /* R */ + + /* Set new PSW ISC, TM, and ET to 7, 1, 3 */ + new_psw |= (7 << PSW_ISC); /* ISC */ + new_psw |= (1 << PSW_TM); /* TM */ + new_psw |= (3 << PSW_ET); /* ET */ + + R[NUM_PC] = read_w(gate_l2 + 4, ACC_AF, BUS_CPU); + R[NUM_PSW] = new_psw; + + cpu_km = FALSE; + abort_context = C_NONE; +} + +/* + * TODO: Setting 'data' to the effective address is bogus. We're only + * doing it because we want to get the address when we trace the + * instructions using "SHOW CPU HISTORY". We should just put + * effective_address as a field in the operand struct and make + * cpu_show_hist smarter. + */ +static uint32 cpu_effective_address(operand *op) +{ +#if defined(REV3) + uint32 tmp; +#endif + + /* Register Deferred */ + if (op->mode == 5 && op->reg != 11) { + return R[op->reg]; + } + + /* Absolute */ + if (op->mode == 7 && op->reg == 15) { + return op->embedded.w; + } + + /* Absolute Deferred */ + if (op->mode == 14 && op->reg == 15) { + /* May cause exception */ + return read_w(op->embedded.w, ACC_AF, BUS_CPU); + } + + /* FP Short Offset */ + if (op->mode == 6 && op->reg != 15) { + return R[NUM_FP] + sign_extend_b(op->embedded.b); + } + + /* AP Short Offset */ + if (op->mode == 7 && op->reg != 15) { + return R[NUM_AP] + sign_extend_b(op->embedded.b); + } + + /* Word Displacement */ + if (op->mode == 8) { + return R[op->reg] + op->embedded.w; + } + + /* Word Displacement Deferred */ + if (op->mode == 9) { + return read_w(R[op->reg] + op->embedded.w, ACC_AF, BUS_CPU); + } + + /* Halfword Displacement */ + if (op->mode == 10) { + return R[op->reg] + sign_extend_h(op->embedded.h); + } + + /* Halfword Displacement Deferred */ + if (op->mode == 11) { + return read_w(R[op->reg] + sign_extend_h(op->embedded.h), ACC_AF, BUS_CPU); + } + + /* Byte Displacement */ + if (op->mode == 12) { + return R[op->reg] + sign_extend_b(op->embedded.b); + } + + /* Byte Displacement Deferred */ + if (op->mode == 13) { + return read_w(R[op->reg] + sign_extend_b(op->embedded.b), ACC_AF, BUS_CPU); + } + +#if defined(REV3) + /* Auto pre-decrement */ + if (op->mode == 0x10) { + switch(op_type(op)) { + case BT: + case SB: + R[op->reg] -= 1; + break; + case HW: + case UH: + R[op->reg] -= 2; + break; + case WD: + case UW: + R[op->reg] -= 4; + break; + } + return R[op->reg]; + } + + /* Auto post-decrement */ + if (op->mode == 0x12) { + tmp = R[op->reg]; + switch(op_type(op)) { + case BT: + case SB: + R[op->reg] -= 1; + break; + case HW: + case UH: + R[op->reg] -= 2; + break; + case WD: + case UW: + R[op->reg] -= 4; + break; + } + return tmp; + } + + /* Auto pre-increment */ + if (op->mode == 0x14) { + switch(op_type(op)) { + case BT: + case SB: + R[op->reg] += 1; + break; + case HW: + case UH: + R[op->reg] += 2; + break; + case WD: + case UW: + R[op->reg] += 4; + break; + } + return R[op->reg]; + } + + /* Auto post-increment */ + if (op->mode == 0x16) { + tmp = R[op->reg]; + switch(op_type(op)) { + case BT: + case SB: + R[op->reg] += 1; + break; + case HW: + case UH: + R[op->reg] += 2; + break; + case WD: + case UW: + R[op->reg] += 4; + break; + } + return tmp; + } + + /* Indexed with byte displacement */ + if (op->mode == 0xab) { + tmp = sign_extend_b(op->embedded.b); + tmp += R[op->reg]; + tmp += R[op->reg2]; + return tmp; + } + + /* Indexed with halfword displacement */ + if (op->mode == 0xbb) { + tmp = sign_extend_h(op->embedded.h); + tmp += R[op->reg]; + tmp += R[op->reg2]; + return tmp; + } + + /* Indexed with scaling */ + if (op->mode == 0xdb) { + switch(op_type(op)) { + case BT: + case SB: + tmp = R[op->reg]; + break; + case HW: + case UH: + tmp = R[op->reg] * 2; + break; + case WD: + case UW: + tmp = R[op->reg] * 4; + break; + default: + /* We should never reach this */ + tmp = 0; + break; + } + + return tmp + R[op->reg2]; + } +#endif + + if (cpu_unit.flags & UNIT_OPBRK) { + stop_reason = STOP_OPCODE; + } + + return 0; +} + +/* + * Read and Write routines for operands. + * + * The rules for dealing with the type (signed/unsigned, + * byte/halfword/word) of operands are fairly complex. + * + * 1. The expanded operand mode does not affect the treatment of + * Literal Mode operands. All literals are signed. + * + * 2. The expanded operand mode does not affect the length of + * Immediate Mode operands, but does affect whether they are signed + * or unsigned. + * + * 3. When using expanded-mode operands, the new type remains in + * effect for the operands that folow in the instruction unless + * another expanded operand mode overrides it. (This rule in + * particular is managed by decode_instruction()) + * + * 4. The expanded operand mode is illegal with coprocessor instructions + * and CALL, SAVE, RESTORE, SWAP INTERLOCKED, PUSAHW, PUSHAW, POPW, + * and JSB. (Illegal Operand Fault) + * + * 5. When writing a byte, the Negative (N) flag is set based on the + * high bit of the data type being written, regardless of the SIGN + * of the extended datatype. e.g.: {ubyte} and {sbyte} both check + * for bit 7, {uhalf} and {shalf} both check for bit 15, and + * {uword} and {sword} both check for bit 31. + * + * 6. For instructions with a signed destination, V is set if the sign + * bit of the output value is different from any truncated bit of + * the result. For instructions with an unsigned destination, V is + * set if any truncated bit is 1. + */ + + +/* + * Read the data referenced by an operand. Performs sign or zero + * extension as required by the read width and operand type, then + * returns the read value. + * + * "All operations are performed only on 32-bit quantities even though + * an instruction may specify a byte or halfword operand. The WE + * 32100 Microprocessor reads in the correct number of bits for the + * operand and extends the data automatically to 32 bits. It uses + * sign extension when reading signed data or halfwords and zero + * extension when reading unsigned data or bytes (or bit fields that + * contain less than 32 bits). The data type of the source operand + * determines how many bits are fetched and what type of extension is + * applied. Bytes are treated as unsigned, while halfwords and words + * are considered signed. The type of extension applied can be + * changed using the expanded-operand type mode as described in 3.4.5 + * Expanded-Operand Type Mode. For sign extension, the value of the + * MSB or sign bit of the data fills the high-order bits to form a + * 32-bit value. In zero extension, zeros fill the high order bits. + * The microprocessor automatically extends a byte or halfword to 32 + * bits before performing an operation. Figure 3-3 illustrates sign + * and zero extension. An arithmetic, logical, data transfer, or bit + * field operation always yields an intermediate result that is 32 + * bits in length. If the result is to be stored in a register, the + * processor writes all 32 bits to that register. The processor + * automatically strips any surplus high-order bits from a result + * when writing bytes or halfwords to memory." -- "WE 32100 + * Microprocessor Information Manual", Section 3.1.1 + * + */ +static uint32 cpu_read_op(operand * op) +{ + uint32 eff; + uint32 data; + + /* Register */ + if (op->mode == 4 && op->reg != 15) { + switch (op_type(op)) { + case WD: + case UW: + data = R[op->reg]; + break; + case HW: + data = sign_extend_h(R[op->reg] & HALF_MASK); + break; + case UH: + data = R[op->reg] & HALF_MASK; + break; + case BT: + data = R[op->reg] & BYTE_MASK; + break; + case SB: + data = sign_extend_b(R[op->reg] & BYTE_MASK); + break; + default: + sim_debug(EXECUTE_MSG, &cpu_dev, + "[%08x] cpu_read_op: unknown op type (1): %d\n", + R[NUM_PC], op_type(op)); + stop_reason = STOP_ERR; + data = 0; + break; + } + + op->data = data; + return data; + } + + /* Literal */ + if (op->mode < 4 || op->mode == 15) { + /* Both positive and negative literals are _always_ treated as + signed bytes, and they are _always_ sign extended. They + simply ignore expanded datatypes. */ + data = sign_extend_b(op->embedded.b); + op->data = data; + return data; + } + + /* Immediate */ + if (op->reg == 15 && + (op->mode == 4 || op->mode == 5 || op->mode == 6)) { + switch (op->mode) { + case 4: /* Word Immediate */ + data = op->embedded.w; + op->data = data; + return data; + case 5: /* Halfword Immediate */ + data = sign_extend_h(op->embedded.h); + op->data = data; + return data; + case 6: /* Byte Immedaite */ + data = sign_extend_b(op->embedded.b); + op->data = data; + return data; + } + } + + /* At this point, we'll need to find an effective address */ + eff = cpu_effective_address(op); + + switch (op_type(op)) { + case WD: /* Signed Word */ + case UW: /* Unsigned Word */ + data = read_w(eff, ACC_OF, BUS_CPU); + op->data = data; + return data; + case HW: /* Signed Halfword */ + data = sign_extend_h(read_h(eff, ACC_OF, BUS_CPU)); + op->data = data; + return data; + case UH: /* Unsigned Halfword */ + data = read_h(eff, ACC_OF, BUS_CPU); + op->data = data; + return data; + case SB: /* Signed Byte */ + data = sign_extend_b(read_b(eff, ACC_OF, BUS_CPU)); + op->data = data; + return data; + case BT: /* Unsigned Byte */ + data = read_b(eff, ACC_OF, BUS_CPU); + op->data = data; + return data; + default: + sim_debug(EXECUTE_MSG, &cpu_dev, + "[%08x] cpu_read_op: unknown op type (2): %d\n", + R[NUM_PC], op_type(op)); + stop_reason = STOP_ERR; + return 0; + } +} + + +static void cpu_write_op(operand * op, t_uint64 val) +{ + uint32 eff; + op->data = (uint32) val; + + /* Writing to a register. */ + if (op->mode == 4 && op->reg != 15) { + if (PRIVREG(op->reg) && cpu_execution_level() != EX_LVL_KERN) { + cpu_abort(NORMAL_EXCEPTION, PRIVILEGED_REGISTER); + return; + } + + /* Registers always get the full 32-bits written, EXCEPT for + * the PSW, which has some Read-Only fields. */ + if (op->reg == NUM_PSW) { + WRITE_PSW((uint32) val); + } else { + R[op->reg] = (uint32) val; + } + + return; + } + + /* Literal mode is not legal. */ + if (op->mode < 4 || op->mode == 15) { + cpu_abort(NORMAL_EXCEPTION, INVALID_DESCRIPTOR); + return; + } + + /* Immediate mode is not legal. */ + if (op->reg == 15 && + (op->mode == 4 || op->mode == 5 || op->mode == 6)) { + cpu_abort(NORMAL_EXCEPTION, INVALID_DESCRIPTOR); + return; + } + + eff = cpu_effective_address(op); + + switch (op_type(op)) { + case UW: + case WD: + write_w(eff, (uint32) val, BUS_CPU); + break; + case HW: + case UH: + write_h(eff, val & HALF_MASK, BUS_CPU); + break; + case SB: + case BT: + write_b(eff, val & BYTE_MASK, BUS_CPU); + break; + default: + sim_debug(EXECUTE_MSG, &cpu_dev, + "[%08x] cpu_read_op: unknown op type (3): %d\n", + R[NUM_PC], op_type(op)); + stop_reason = STOP_ERR; + break; + } +} + +/* + * Returns the correct datatype for an operand -- either extended type + * or default type. + */ +static SIM_INLINE int8 op_type(operand *op) { + if (op->etype > -1) { + return op->etype; + } else { + return op->dtype; + } +} + +static SIM_INLINE t_bool op_signed(operand *op) { + return (op_type(op) == WD || op_type(op) == HW || op_type(op) == SB); +} + +static SIM_INLINE uint32 sign_extend_b(uint8 val) +{ + if (val & 0x80) + return ((uint32) val) | 0xffffff00; + return (uint32) val; +} + +static SIM_INLINE uint32 sign_extend_h(uint16 val) +{ + if (val & 0x8000) + return ((uint32) val) | 0xffff0000; + return (uint32) val; +} + +/* + * Returns the current CPU execution level. + */ +static SIM_INLINE uint8 cpu_execution_level() +{ + return (R[NUM_PSW] & PSW_CM_MASK) >> PSW_CM; +} + +static SIM_INLINE t_bool cpu_z_flag() +{ + return (R[NUM_PSW] & PSW_Z_MASK) != 0; +} + +static SIM_INLINE t_bool cpu_n_flag() +{ + return (R[NUM_PSW] & PSW_N_MASK) != 0; +} + +static SIM_INLINE t_bool cpu_c_flag() +{ + return (R[NUM_PSW] & PSW_C_MASK) != 0; +} + +static SIM_INLINE t_bool cpu_v_flag() +{ + return (R[NUM_PSW] & PSW_V_MASK) != 0; +} + +#if defined(REV3) +static SIM_INLINE t_bool cpu_x_flag() +{ + return (R[NUM_PSW] & PSW_X_MASK) != 0; +} +#endif + +static SIM_INLINE void cpu_set_z_flag(t_bool val) +{ + if (val) { + R[NUM_PSW] |= PSW_Z_MASK; + } else { + R[NUM_PSW] &= ~PSW_Z_MASK; + } +} + +static SIM_INLINE void cpu_set_n_flag(t_bool val) +{ + if (val) { + R[NUM_PSW] |= PSW_N_MASK; + } else { + R[NUM_PSW] &= ~PSW_N_MASK; + } +} + +static SIM_INLINE void cpu_set_c_flag(t_bool val) +{ + if (val) { + R[NUM_PSW] |= PSW_C_MASK; + } else { + R[NUM_PSW] &= ~PSW_C_MASK; + } +} + +#if defined(REV3) +static SIM_INLINE void cpu_set_x_flag(t_bool val) +{ + if (val) { + R[NUM_PSW] |= PSW_X_MASK; + } else { + R[NUM_PSW] &= ~PSW_X_MASK; + } +} +#endif + +static SIM_INLINE void cpu_set_v_flag_op(t_uint64 val, operand *op) +{ + switch(op_type(op)) { + case WD: + case UW: + cpu_set_v_flag(0); + break; + case HW: + case UH: + cpu_set_v_flag(val > HALF_MASK); + break; + case BT: + case SB: + default: + cpu_set_v_flag(val > BYTE_MASK); + break; + } +} + +static SIM_INLINE void cpu_set_v_flag(t_bool val) +{ + if (val) { + R[NUM_PSW] |= PSW_V_MASK; + if (R[NUM_PSW] & PSW_OE_MASK) { + cpu_abort(NORMAL_EXCEPTION, INTEGER_OVERFLOW); + } + } else { + R[NUM_PSW] &= ~PSW_V_MASK; + } +} + +static void cpu_set_nz_flags(t_uint64 data, operand *dst) +{ + int8 type = op_type(dst); + + switch (type) { + case WD: + case UW: + cpu_set_n_flag(!!(WD_MSB & data)); + cpu_set_z_flag((data & WORD_MASK) == 0); + break; + case HW: + case UH: + cpu_set_n_flag(HW_MSB & data); + cpu_set_z_flag((data & HALF_MASK) == 0); + break; + case BT: + case SB: + cpu_set_n_flag(BT_MSB & data); + cpu_set_z_flag((data & BYTE_MASK) == 0); + break; + } +} + +static SIM_INLINE void cpu_push_word(uint32 val) +{ + write_w(R[NUM_SP], val, BUS_CPU); + R[NUM_SP] += 4; +} + +static SIM_INLINE uint32 cpu_pop_word() +{ + uint32 result; + /* We always read fromthe stack first BEFORE decrementing, + in case this causes a fault. */ + result = read_w(R[NUM_SP] - 4, ACC_AF, BUS_CPU); + R[NUM_SP] -= 4; + return result; +} + +static SIM_INLINE void irq_push_word(uint32 val) +{ + write_w(R[NUM_ISP], val, BUS_CPU); + R[NUM_ISP] += 4; +} + +static SIM_INLINE uint32 irq_pop_word() +{ + R[NUM_ISP] -= 4; + return read_w(R[NUM_ISP], ACC_AF, BUS_CPU); +} + +static SIM_INLINE t_bool op_is_psw(operand *op) +{ + return (op->mode == 4 && op->reg == NUM_PSW); +} + +static SIM_INLINE void sub(t_uint64 a, t_uint64 b, operand *dst) +{ + t_uint64 result; + + result = a - b; + + cpu_write_op(dst, result); + + cpu_set_nz_flags(result, dst); + cpu_set_c_flag((uint32)b > (uint32)a); + cpu_set_v_flag_op(result, dst); +} + +static SIM_INLINE void add(t_uint64 a, t_uint64 b, operand *dst) +{ + t_uint64 result; + + result = a + b; + + cpu_write_op(dst, result); + + cpu_set_nz_flags(result, dst); + + switch(op_type(dst)) { + case WD: + cpu_set_c_flag(result > WORD_MASK); + cpu_set_v_flag(((a ^ ~b) & (a ^ result)) & WD_MSB); + break; + case UW: + cpu_set_c_flag(result > WORD_MASK); + cpu_set_v_flag(result > WORD_MASK); + break; + case HW: + cpu_set_c_flag(result > HALF_MASK); + cpu_set_v_flag(((a ^ ~b) & (a ^ result)) & HW_MSB); + break; + case UH: + cpu_set_c_flag(result > HALF_MASK); + cpu_set_v_flag(result > HALF_MASK); + break; + case BT: + cpu_set_c_flag(result > BYTE_MASK); + cpu_set_v_flag(result > BYTE_MASK); + break; + case SB: + cpu_set_c_flag(result > BYTE_MASK); + cpu_set_v_flag(((a ^ ~b) & (a ^ result)) & BT_MSB); + break; + } +} + +#if defined(REV3) +/* + * Return the packed BCD byte result of adding two packed BCD input + * bytes. This will set the C and X carry flags appropraitely if there + * is a carry. + */ +static SIM_INLINE uint8 add_bcd(uint8 packed_a, uint8 packed_b) +{ + uint16 l, h, result; + + l = (packed_a & 0x0f) + (packed_b & 0x0f) + (cpu_x_flag() ? 1 : 0); + if ((l & 0xff) > 9) { + l += 6; + } + + h = ((packed_a >> 4) & 0x0f) + ((packed_b >> 4) & 0x0f) + (l > 15 ? 1 : 0); + if ((h & 0xff) > 9) { + h += 6; + } + + result = ((l & 0x0f) | (h << 4)) & 0xff; + + cpu_set_c_flag(h > 15); + cpu_set_x_flag(h > 15); + cpu_set_z_flag(result == 0); + cpu_set_n_flag(0); + cpu_set_v_flag(0); + + return (uint8)result; +} + +/* + * Return the packed BCD byte result of subtracting two packed BCD + * input bytes. This will set the C and X carry flags appropraitely if + * there is a carry. + */ +static SIM_INLINE uint8 sub_bcd(uint8 packed_a, uint8 packed_b) +{ + uint16 l, h, result; + + l = (packed_a & 0x0f) - (packed_b & 0x0f) - (cpu_x_flag() ? 1 : 0); + if ((l & 0x10) != 0) { + l -= 6; + } + + h = ((packed_a >> 4) & 0x0f) - ((packed_b >> 4) & 0x0f) - ((l & 0x10) != 0 ? 1 : 0); + if ((h & 0x10) != 0) { + h -= 6; + } + + result = ((l & 0x0f)|(h << 4)) & 0xff; + + cpu_set_c_flag(h > 15); + cpu_set_x_flag(h > 15); + cpu_set_z_flag(result == 0); + cpu_set_n_flag(0); + cpu_set_v_flag(0); + + return (uint8)result; +} +#endif + +/* + * Set PSW's ET and ISC fields, and store global exception or fault + * state appropriately. + */ +void cpu_abort(uint8 et, uint8 isc) +{ + /* We don't trap Integer Overflow if the OE bit is not set */ + if ((R[NUM_PSW] & PSW_OE_MASK) == 0 && isc == INTEGER_OVERFLOW) { + return; + } + + R[NUM_PSW] &= ~(PSW_ET_MASK); /* Clear ET */ + R[NUM_PSW] &= ~(PSW_ISC_MASK); /* Clear ISC */ + R[NUM_PSW] |= et; /* Set ET */ + R[NUM_PSW] |= (uint32) (isc << PSW_ISC); /* Set ISC */ + + longjmp(save_env, ABORT_EXC); +} + +CONST char *cpu_description(DEVICE *dptr) +{ +#if defined(REV3) + return "3B2/700 CPU (WE 32200)"; +#else + return "3B2/400 CPU (WE 32100)"; +#endif +} + +t_stat cpu_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr) +{ +#if defined(REV3) + fprintf(st, "3B2/700 CPU Help\n\n"); + fprintf(st, "The 3B2/700 CPU simulates a WE 32200 at 22 MHz.\n\n"); +#else + fprintf(st, "3B2/400 CPU Help\n\n"); + fprintf(st, "The 3B2/400 CPU simulates a WE 32100 at 10 MHz.\n\n"); +#endif + + fprint_set_help(st, dptr); + fprint_show_help(st, dptr); + fprint_reg_help(st, dptr); + +#if defined(REV3) + fprintf(st, "\nAdditional documentation for the 3B2/700 Simulator is available on the web:\n\n"); +#else + fprintf(st, "\nAdditional documentation for the 3B2/400 Simulator is available on the web:\n\n"); +#endif + fprintf(st, " https://loomcom.com/3b2/emulator.html\n\n"); + + return SCPE_OK; +} diff --git a/3B2/3b2_cpu.h b/3B2/3b2_cpu.h index b6f9dfa7..054853e7 100644 --- a/3B2/3b2_cpu.h +++ b/3B2/3b2_cpu.h @@ -1,666 +1,684 @@ -/* 3b2_cpu.h: AT&T 3B2 CPU (WE32100 and WE32200) Header - - Copyright (c) 2017, Seth J. Morabito - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - - Except as contained in this notice, the name of the author shall - not be used in advertising or otherwise to promote the sale, use or - other dealings in this Software without prior written authorization - from the author. -*/ - -#ifndef _3B2_CPU_H_ -#define _3B2_CPU_H_ - -#include "3b2_defs.h" - -/* Execution Modes */ -#define EX_LVL_KERN 0 -#define EX_LVL_EXEC 1 -#define EX_LVL_SUPR 2 -#define EX_LVL_USER 3 - -#define MAX_HIST_SIZE 10000000 -#define MIN_HIST_SIZE 64 -#define MEM_SIZE (cpu_unit.capac) - -#define UNIT_V_MSIZE (UNIT_V_UF) -#define UNIT_MSIZE (1 << UNIT_V_MSIZE) - -#define WD_MSB 0x80000000 -#define HW_MSB 0x8000 -#define BT_MSB 0x80 -#define WORD_MASK 0xffffffff -#define HALF_MASK 0xffffu -#define BYTE_MASK 0xff - -/* Exception Types */ -#define RESET_EXCEPTION 0 -#define PROCESS_EXCEPTION 1 -#define STACK_EXCEPTION 2 -#define NORMAL_EXCEPTION 3 - -/* Reset Exceptions */ -#define OLD_PCB_FAULT 0 -#define SYSTEM_DATA_FAULT 1 -#define INTERRUPT_STACK_FAULT 2 -#define EXTERNAL_RESET 3 -#define NEW_PCB_FAULT 4 -#define GATE_VECTOR_FAULT 6 - -/* Process Exceptions */ -#define GATE_PCB_FAULT 1 - -/* Stack Exceptions */ -#define STACK_BOUND 0 -#define STACK_FAULT 1 -#define INTERRUPT_ID_FETCH 3 - -/* Normal Exceptions */ -#define INTEGER_ZERO_DIVIDE 0 -#define TRACE_TRAP 1 -#define ILLEGAL_OPCODE 2 -#define RESERVED_OPCODE 3 -#define INVALID_DESCRIPTOR 4 -#define EXTERNAL_MEMORY_FAULT 5 -#define N_GATE_VECTOR 6 -#define ILLEGAL_LEVEL_CHANGE 7 -#define RESERVED_DATATYPE 8 -#define INTEGER_OVERFLOW 9 -#define PRIVILEGED_OPCODE 10 -#define BREAKPOINT_TRAP 14 -#define PRIVILEGED_REGISTER 15 - -#define PSW_ET 0 -#define PSW_TM 2 -#define PSW_ISC 3 -#define PSW_I 7 -#define PSW_R 8 -#define PSW_PM 9 -#define PSW_CM 11 -#define PSW_IPL 13 -#define PSW_TE 17 -#define PSW_C 18 -#define PSW_V 19 -#define PSW_Z 20 -#define PSW_N 21 -#define PSW_OE 22 -#define PSW_CD 23 -#define PSW_QIE 24 -#define PSW_CFD 25 - -#define PSW_ET_MASK 3u -#define PSW_TM_MASK (1u << PSW_TM) -#define PSW_ISC_MASK (15u << PSW_ISC) -#define PSW_I_MASK (1u << PSW_I) -#define PSW_R_MASK (1u << PSW_R) -#define PSW_PM_MASK (3u << PSW_PM) -#define PSW_CM_MASK (3u << PSW_CM) -#define PSW_IPL_MASK (15u << PSW_IPL) -#define PSW_TE_MASK (1u << PSW_TE) -#define PSW_C_MASK (1u << PSW_C) -#define PSW_V_MASK (1u << PSW_V) -#define PSW_N_MASK (1u << PSW_N) -#define PSW_Z_MASK (1u << PSW_Z) -#define PSW_OE_MASK (1u << PSW_OE) -#define PSW_CD_MASK (1u << PSW_CD) -#define PSW_QIE_MASK (1u << PSW_QIE) -#define PSW_CFD_MASK (1u << PSW_CFD) -#define PSW_CUR_IPL (((R[NUM_PSW] & PSW_IPL_MASK) >> PSW_IPL) & 0xf) - -/* A helper to set the PSW, preserving read-only fields */ -#define PSW_RO_MASK 0x17f /* ET, TM, ISC, and R are read-only! */ -#define WRITE_PSW(V) (R[NUM_PSW] = ((R[NUM_PSW] & PSW_RO_MASK) | ((V) & ~PSW_RO_MASK))) - -/* Exceptional conditions handled within the instruction loop */ -#define ABORT_EXC 1 /* CPU exception */ - -/* Contexts for aborts */ -#define C_NONE 0 /* No context. Normal handling. */ -#define C_NORMAL_GATE_VECTOR 1 -#define C_PROCESS_GATE_PCB 2 -#define C_PROCESS_OLD_PCB 3 -#define C_PROCESS_NEW_PCB 4 -#define C_RESET_GATE_VECTOR 5 -#define C_RESET_INT_STACK 6 -#define C_RESET_NEW_PCB 7 -#define C_RESET_SYSTEM_DATA 8 -#define C_STACK_FAULT 9 - -/* Register numbers */ -#define NUM_FP 9 -#define NUM_AP 10 -#define NUM_PSW 11 -#define NUM_SP 12 -#define NUM_PCBP 13 -#define NUM_ISP 14 -#define NUM_PC 15 - -/* System board interrupt priority levels */ -#define CPU_IPL_8 8 -#define CPU_IPL_9 9 -#define CPU_IPL_11 11 -#define CPU_IPL_13 13 -#define CPU_IPL_15 15 - -/* Processor permission levels */ -#define L_KERNEL 0 -#define L_EXEC 1 -#define L_SUPER 2 -#define L_USER 3 - -/* Currently selected processor permission level */ -#define CPU_CM (cpu_km ? L_KERNEL : ((R[NUM_PSW] >> PSW_CM) & 3)) - -/* Data types operated on by instructions. NB: These integer values - have meaning when decoding instructions, so this is not just an - enum. Please don't change them. */ -#define UW 0 /* Unsigned Word */ -#define UH 2 /* Unsigned Halfword */ -#define BT 3 /* Unsigned Byte */ -#define WD 4 /* Signed Word */ -#define HW 6 /* Signed Halfword */ -#define SB 7 /* Signed Byte */ - -#define NA -1 - -/* - * - * Mode Syntax Mode Reg. Bytes Notes - * ---------------------------------------------------------------------- - * Absolute $expr 7 15 5 - * Abs. Deferred *$expr 14 15 5 - * Byte Disp. expr(%rn) 12 0-10,12-15 2 - * Byte Disp. Def. *expr(%rn) 13 0-10,12-15 2 - * Halfword Disp. expr(%rn) 10 0-10,12-15 3 - * Halfword Disp. Def. *expr(%rn) 11 0-10,12-15 3 - * Word Disp. expr(%rn) 8 0-10,12-15 5 - * Word Disp. Def. *expr(%rn) 9 0-10,12-15 5 - * AP Short Offset so(%ap) 7 0-14 1 1 - * FP Short Offset so(%fp) 6 0-14 1 1 - * Byte Immediate &imm8 6 15 2 2,3 - * Halfword Immediate &imm16 5 15 3 2,3 - * Word Immediate &imm32 4 15 5 2,3 - * Positive Literal &lit 0-3 0-15 1 2,3 - * Negative Literal &lit 15 0-15 1 2,3 - * Register %rn 4 0-14 1 1,3 - * Register Deferred (%rn) 5 0-10,12-14 1 1 - * Expanded Op. Type {type}opnd 14 0-14 2-6 4 - * - * Notes: - * - * 1. Mode field has special meaning if register field is 15; see - * absolute or immediate mode. - * 2. Mode may not be used for a destination operand. - * 3. Mode may not be used if the instruction takes effective address - * of the operand. - * 4. 'type' overrides instruction type; 'type' determines the operand - * type, except that it does not determine the length for immediate - * or literals or whether literals are signed or unsigned. 'opnd' - * determines actual address mode. For total bytes, add 1 to byte - * count for address mode determined by 'opnd'. - * - */ - -/* - * Opcodes - */ -typedef enum { - HALT = 0x00, /* Undocumented instruction */ - SPOPRD = 0x02, - SPOPD2 = 0x03, - MOVAW = 0x04, - SPOPRT = 0x06, - SPOPT2 = 0x07, - RET = 0x08, -#if defined(REV3) - CASWI = 0x09, - SETX = 0x0A, - CLRX = 0x0B, -#endif - MOVTRW = 0x0C, -#if defined(REV3) - TEDTH = 0x0D, - PACKB = 0x0E, - UNPACKB = 0x0F, -#endif - SAVE = 0x10, - SPOPWD = 0x13, - EXTOP = 0x14, - SPOPWT = 0x17, - RESTORE = 0x18, -#if defined(REV3) - DTH = 0x19, -#endif - SWAPWI = 0x1C, -#if defined(REV3) - TGEDTH = 0x1D, -#endif - SWAPHI = 0x1E, - SWAPBI = 0x1F, - POPW = 0x20, - SPOPRS = 0x22, - SPOPS2 = 0x23, - JMP = 0x24, - CFLUSH = 0x27, - TSTW = 0x28, -#if defined(REV3) - DTB = 0x29, -#endif - TSTH = 0x2A, - TSTB = 0x2B, - CALL = 0x2C, -#if defined(REV3) - TGDTH = 0x2D, -#endif - BPT = 0x2E, - WAIT = 0x2F, - EMB = 0x30, /* Multi-byte */ - SPOP = 0x32, - SPOPWS = 0x33, - JSB = 0x34, - BSBH = 0x36, - BSBB = 0x37, - BITW = 0x38, - BITH = 0x3A, - BITB = 0x3B, - CMPW = 0x3C, -#if defined(REV3) - TNEDTH = 0x3D, -#endif - CMPH = 0x3E, - CMPB = 0x3F, - RGEQ = 0x40, - BGEH = 0x42, - BGEB = 0x43, - RGTR = 0x44, - BGH = 0x46, - BGB = 0x47, - RLSS = 0x48, - BLH = 0x4A, - BLB = 0x4B, - RLEQ = 0x4C, -#if defined(REV3) - TEDTB = 0x4D, -#endif - BLEH = 0x4E, - BLEB = 0x4F, - RGEQU = 0x50, - BGEUH = 0x52, - BGEUB = 0x53, - RGTRU = 0x54, - BGUH = 0x56, - BGUB = 0x57, - BLSSU = 0x58, - BLUH = 0x5A, - BLUB = 0x5B, - RLEQU = 0x5C, -#if defined(REV3) - TGEDTB = 0x5D, -#endif - BLEUH = 0x5E, - BLEUB = 0x5F, - RVC = 0x60, - BVCH = 0x62, - BVCB = 0x63, - RNEQU = 0x64, - BNEH_D = 0x66, - BNEB_D = 0x67, - RVS = 0x68, - BVSH = 0x6A, - BVSB = 0x6B, - REQLU = 0x6C, -#if defined(REV3) - TGDTB = 0x6D, -#endif - BEH_D = 0x6E, - BEB_D = 0x6F, - NOP = 0x70, - NOP3 = 0x72, - NOP2 = 0x73, - RNEQ = 0x74, - BNEH = 0x76, - BNEB = 0x77, - RSB = 0x78, - BRH = 0x7A, - BRB = 0x7B, - REQL = 0x7C, -#if defined(REV3) - TNEDTB = 0x7D, -#endif - BEH = 0x7E, - BEB = 0x7F, - CLRW = 0x80, - CLRH = 0x82, - CLRB = 0x83, - MOVW = 0x84, - MOVH = 0x86, - MOVB = 0x87, - MCOMW = 0x88, - MCOMH = 0x8A, - MCOMB = 0x8B, - MNEGW = 0x8C, - MNEGH = 0x8E, - MNEGB = 0x8F, - INCW = 0x90, - INCH = 0x92, - INCB = 0x93, - DECW = 0x94, - DECH = 0x96, - DECB = 0x97, -#if defined(REV3) - RETQINT = 0x98, - SUBPB2 = 0x9B, -#endif - ADDW2 = 0x9C, - ADDH2 = 0x9E, - ADDB2 = 0x9F, - PUSHW = 0xA0, -#if defined(REV3) - ADDPB2 = 0xA3, -#endif - MODW2 = 0xA4, - MODH2 = 0xA6, - MODB2 = 0xA7, - MULW2 = 0xA8, - MULH2 = 0xAA, - MULB2 = 0xAB, - DIVW2 = 0xAC, - DIVH2 = 0xAE, - DIVB2 = 0xAF, - ORW2 = 0xB0, - ORH2 = 0xB2, - ORB2 = 0xB3, - XORW2 = 0xB4, - XORH2 = 0xB6, - XORB2 = 0xB7, - ANDW2 = 0xB8, - ANDH2 = 0xBA, - ANDB2 = 0xBB, - SUBW2 = 0xBC, - SUBH2 = 0xBE, - SUBB2 = 0xBF, - ALSW3 = 0xC0, - ARSW3 = 0xC4, - ARSH3 = 0xC6, - ARSB3 = 0xC7, - INSFW = 0xC8, - INSFH = 0xCA, - INSFB = 0xCB, - EXTFW = 0xCC, - EXTFH = 0xCE, - EXTFB = 0xCF, - LLSW3 = 0xD0, - LLSH3 = 0xD2, - LLSB3 = 0xD3, - LRSW3 = 0xD4, - ROTW = 0xD8, -#if defined(REV3) - SUBPB3 = 0xDB, -#endif - ADDW3 = 0xDC, - ADDH3 = 0xDE, - ADDB3 = 0xDF, - PUSHAW = 0xE0, -#if defined(REV3) - ADDPB3 = 0xE3, -#endif - MODW3 = 0xE4, - MODH3 = 0xE6, - MODB3 = 0xE7, - MULW3 = 0xE8, - MULH3 = 0xEA, - MULB3 = 0xEB, - DIVW3 = 0xEC, - DIVH3 = 0xEE, - DIVB3 = 0xEF, - ORW3 = 0xF0, - ORH3 = 0xF2, - ORB3 = 0xF3, - XORW3 = 0xF4, - XORH3 = 0xF6, - XORB3 = 0xF7, - ANDW3 = 0xF8, - ANDH3 = 0xFA, - ANDB3 = 0xFB, - SUBW3 = 0xFC, - SUBH3 = 0xFE, - SUBB3 = 0xFF, - MVERNO = 0x3009, - ENBVJMP = 0x300d, - DISVJMP = 0x3013, - MOVBLW = 0x3019, - STREND = 0x301f, - INTACK = 0x302f, - STRCPY = 0x3035, - RETG = 0x3045, - GATE = 0x3061, - CALLPS = 0x30ac, - RETPS = 0x30c8 -} opcode; - -/* - * Each instruction expects operands of a certain type. - * - * The large majority of instructions expect operands that have a - * descriptor as the first byte. This descriptor carries all the - * information necessary to compute the addressing mode of the - * operand. - * - * e.g.: - * - * MOVB 6(%r1),%r0 - * +------+------+------+------+ - * | 0x87 | 0xc1 | 0x06 | 0x40 | - * +------+------+------+------+ - * ^^^^^^ - * Descriptor byte. mode = 13 (0x0c), register = 1 (0x01) - * - * - * Branch instructions have either an 8-bit or a 16-bit signed - * displacement value, and lack a descriptor byte. - * - * e.g.: - * - * BCCB 0x03 - * +------+------+ - * | 0x53 | 0x03 | 8-bit displacement - * +------+------+ - * - * BCCH 0x01ff - * +------+------+------+ - * | 0x52 | 0xff | 0x01 | 16-bit displacement - * +------+------+------+ - * - * - * TODO: Describe coprocessor instructions - * - */ -typedef enum { - OP_NONE, /* NULL type */ - OP_DESC, /* Descriptor byte */ - OP_BYTE, /* 8-bit signed value */ - OP_HALF, /* 16-bit signed value */ - OP_COPR /* Coprocessor instruction */ -} op_mode; - -/* Describes a CPU opcode. - * - * e.g.: - * - * {0x09, 3, OP_DESC, WD, "CASWI", 0, 1, -1, 2} - * - * - Opcode 0x09. - * - Followed by three operands. - * - Operands use descriptor bytes. - * - Default data type is word (32 bit). - * - Operand 0 is source 1. - * - Operand 1 is source 2. - * - Operand 2 is destination. - * - */ -typedef struct { - uint16 opcode; - int8 op_count; /* Number of operands */ - op_mode mode; /* Dispatch mode */ - int8 dtype; /* Default data type */ - char mnemonic[8]; - int8 src_op1; - int8 src_op2; - int8 src_op3; - int8 dst_op; -} mnemonic; - -/* - * Structure that describes each operand in a decoded instruction - */ -typedef struct { - uint8 mode; /* Embedded data addressing mode */ - uint8 reg; /* Operand register (0-15) */ - int8 dtype; /* Default type for the operand */ - int8 etype; /* Expanded type (-1 if none) */ - union { - uint32 w; - uint16 h; - uint8 b; - } embedded; /* Data consumed as part of the instruction - stream, i.e. literals, displacement, - etc. */ - uint32 data; /* Data either read or written during - instruction execution */ -} operand; - -/* - * An inst is a combination of a decoded instruction and - * 0 to 4 operands. Also used for history record keeping. - */ -typedef struct { - mnemonic *mn; - uint32 psw; - uint32 sp; - uint32 pc; - t_bool valid; - operand operands[4]; -} instr; - -/* - * A mapping of CIO identifier word to CIO device name. - * - * Each CIO expansion card in a 3B2 system identifies itself with a - * well-knon 16-bit value, used by drivers to identify the type of - * card installed in each slot. - */ -typedef struct { - uint16 id; - const char name[8]; -} cio_device; - -/* Function prototypes */ -t_stat sys_boot(int32 flag, CONST char *ptr); -t_stat cpu_svc(UNIT *uptr); -t_stat cpu_ex(t_value *vptr, t_addr addr, UNIT *uptr, int32 sw); -t_stat cpu_dep(t_value val, t_addr addr, UNIT *uptr, int32 sw); -t_stat cpu_reset(DEVICE *dptr); -t_stat cpu_set_size(UNIT *uptr, int32 val, CONST char *cptr, void *desc); -t_stat cpu_set_hist(UNIT *uptr, int32 val, CONST char *cptr, void *desc); -t_stat cpu_show_hist(FILE *st, UNIT *uptr, int32 val, CONST void *desc); -t_stat cpu_show_virt(FILE *st, UNIT *uptr, int32 val, CONST void *desc); -t_stat cpu_show_stack(FILE *st, UNIT *uptr, int32 val, CONST void *desc); -t_stat cpu_show_cio(FILE *st, UNIT *uptr, int32 val, CONST void *desc); -t_stat cpu_set_halt(UNIT *uptr, int32 val, char *cptr, void *desc); -t_stat cpu_clear_halt(UNIT *uptr, int32 val, char *cptr, void *desc); -t_stat cpu_boot(int32 unit_num, DEVICE *dptr); -t_stat cpu_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr); -CONST char *cpu_description(DEVICE *dptr); - -t_bool cpu_is_pc_a_subroutine_call (t_addr **ret_addrs); - -void cpu_register_name(uint8 reg, char *buf, size_t len); -void cpu_show_operand(FILE *st, operand *op); -void fprint_sym_hist(FILE *st, instr *ip); -t_stat fprint_sym_m(FILE *of, t_addr addr, t_value *val); - -instr *cpu_next_instruction(void); - -uint8 decode_instruction(instr *instr); -void cpu_on_interrupt(uint16 vec); -void cpu_abort(uint8 et, uint8 isc); - -/* Helper macros */ - -#define MOD(A,B,OP1,OP2,SZ) { \ - if (op_signed(OP1) && !op_signed(OP2)) { \ - result = (SZ)(B) % (A); \ - } else if (!op_signed(OP1) && op_signed(OP2)) { \ - result = (B) % (SZ)(A); \ - } else if (op_signed(OP1) && op_signed(OP2)) { \ - result = (SZ)(B) % (SZ)(A); \ - } else { \ - result = (B) % (A); \ - } \ - } - -#define DIV(A,B,OP1,OP2,SZ) { \ - if (op_signed(OP1) && !op_signed(OP2)) { \ - result = (SZ)(B) / (A); \ - } else if (!op_signed(OP1) && op_signed(OP2)) { \ - result = (B) / (SZ)(A); \ - } else if (op_signed(OP1) && op_signed(OP2)) { \ - result = (SZ)(B) / (SZ)(A); \ - } else { \ - result = (B) / (A); \ - } \ - } - -#define OP_R_W(d,a,p) { \ - (d) = (uint32) (a)[(p)++]; \ - (d) |= (uint32) (a)[(p)++] << 8u; \ - (d) |= (uint32) (a)[(p)++] << 16u; \ - (d) |= (uint32) (a)[(p)++] << 24u; \ - } - -#define OP_R_H(d,a,p) { \ - (d) = (uint16) (a)[(p)++]; \ - (d) |= (uint16) (a)[(p)++] << 8u; \ - } - -#define OP_R_B(d,a,p) { \ - (d) = (uint8) (a)[(p)++]; \ - } - -#define CPU_SET_INT(flags) (sbd_int_req |= flags) -#define CPU_CLR_INT(flags) (sbd_int_req &= ~(flags)) - -extern volatile int32 stop_reason; -extern uint16 sbd_int_req; -extern uint32 rom_size; -extern instr *cpu_instr; -extern t_bool cpu_nmi; -extern uint32 *ROM; -extern uint32 *RAM; -extern uint32 R[NUM_REGISTERS]; -extern REG cpu_reg[]; -extern UNIT cpu_unit; -extern uint8 fault; -extern t_bool cpu_km; - -#endif +/* 3b2_cpu.h: WE32100 and WE32200 CPU + + Copyright (c) 2017-2022, Seth J. Morabito + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + Except as contained in this notice, the name of the author shall + not be used in advertising or otherwise to promote the sale, use or + other dealings in this Software without prior written authorization + from the author. +*/ + +#ifndef _3B2_CPU_H_ +#define _3B2_CPU_H_ + +#include "3b2_defs.h" + +/* Execution Modes */ +#define EX_LVL_KERN 0 +#define EX_LVL_EXEC 1 +#define EX_LVL_SUPR 2 +#define EX_LVL_USER 3 + +#define MAX_HIST_SIZE 10000000 +#define MIN_HIST_SIZE 64 +#define MEM_SIZE (cpu_unit.capac) + +#define UNIT_V_MSIZE (UNIT_V_UF) +#define UNIT_MSIZE (1 << UNIT_V_MSIZE) + +#define WD_MSB 0x80000000 +#define HW_MSB 0x8000 +#define BT_MSB 0x80 +#define WORD_MASK 0xffffffff +#define HALF_MASK 0xffffu +#define BYTE_MASK 0xff + +/* Exception Types */ +#define RESET_EXCEPTION 0 +#define PROCESS_EXCEPTION 1 +#define STACK_EXCEPTION 2 +#define NORMAL_EXCEPTION 3 + +/* Reset Exceptions */ +#define OLD_PCB_FAULT 0 +#define SYSTEM_DATA_FAULT 1 +#define INTERRUPT_STACK_FAULT 2 +#define EXTERNAL_RESET 3 +#define NEW_PCB_FAULT 4 +#define GATE_VECTOR_FAULT 6 + +/* Process Exceptions */ +#define GATE_PCB_FAULT 1 + +/* Stack Exceptions */ +#define STACK_BOUND 0 +#define STACK_FAULT 1 +#define INTERRUPT_ID_FETCH 3 + +/* Normal Exceptions */ +#define INTEGER_ZERO_DIVIDE 0 +#define TRACE_TRAP 1 +#define ILLEGAL_OPCODE 2 +#define RESERVED_OPCODE 3 +#define INVALID_DESCRIPTOR 4 +#define EXTERNAL_MEMORY_FAULT 5 +#define N_GATE_VECTOR 6 +#define ILLEGAL_LEVEL_CHANGE 7 +#define RESERVED_DATATYPE 8 +#define INTEGER_OVERFLOW 9 +#define PRIVILEGED_OPCODE 10 +#define BREAKPOINT_TRAP 14 +#define PRIVILEGED_REGISTER 15 + +#define PSW_ET 0 +#define PSW_TM 2 +#define PSW_ISC 3 +#define PSW_I 7 +#define PSW_R 8 +#define PSW_PM 9 +#define PSW_CM 11 +#define PSW_IPL 13 +#define PSW_TE 17 +#define PSW_C 18 +#define PSW_V 19 +#define PSW_Z 20 +#define PSW_N 21 +#define PSW_OE 22 +#define PSW_CD 23 +#define PSW_QIE 24 +#define PSW_CFD 25 + +#define PSW_ET_MASK 3u +#define PSW_TM_MASK (1u << PSW_TM) +#define PSW_ISC_MASK (15u << PSW_ISC) +#define PSW_I_MASK (1u << PSW_I) +#define PSW_R_MASK (1u << PSW_R) +#define PSW_PM_MASK (3u << PSW_PM) +#define PSW_CM_MASK (3u << PSW_CM) +#define PSW_IPL_MASK (15u << PSW_IPL) +#define PSW_TE_MASK (1u << PSW_TE) +#define PSW_C_MASK (1u << PSW_C) +#define PSW_V_MASK (1u << PSW_V) +#define PSW_N_MASK (1u << PSW_N) +#define PSW_Z_MASK (1u << PSW_Z) +#define PSW_OE_MASK (1u << PSW_OE) +#define PSW_CD_MASK (1u << PSW_CD) +#define PSW_QIE_MASK (1u << PSW_QIE) +#define PSW_CFD_MASK (1u << PSW_CFD) +#define PSW_CUR_IPL (((R[NUM_PSW] & PSW_IPL_MASK) >> PSW_IPL) & 0xf) + +#if defined(REV3) +#define PSW_X 26 +#define PSW_AR 27 +#define PSW_EXUC 28 +#define PSW_EA 29 + +#define PSW_X_MASK (1u << PSW_X) +#define PSW_AR_MASK (1u << PSW_AR) +#define PSW_EXUC_MASK (1u << PSW_EXUC) +#define PSW_EA_MASK (1u << PSW_EA) +#endif + +#if defined(REV3) +#define QIE_PSW_MASK (PSW_EA_MASK|PSW_EXUC_MASK|PSW_X_MASK| \ + PSW_CFD_MASK|PSW_QIE_MASK|PSW_CD_MASK|PSW_OE_MASK| \ + PSW_N_MASK|PSW_Z_MASK|PSW_V_MASK|PSW_C_MASK| \ + PSW_TE_MASK|PSW_IPL_MASK|PSW_PM_MASK|PSW_I_MASK) +#else +#define QIE_PSW_MASK (PSW_CFD_MASK|PSW_QIE_MASK|PSW_CD_MASK|PSW_OE_MASK| \ + PSW_N_MASK|PSW_Z_MASK|PSW_V_MASK|PSW_C_MASK| \ + PSW_TE_MASK|PSW_IPL_MASK|PSW_PM_MASK|PSW_I_MASK) +#endif + +/* A helper to set the PSW, preserving read-only fields */ +#define PSW_RO_MASK 0x17f /* ET, TM, ISC, and R are read-only! */ +#define WRITE_PSW(V) (R[NUM_PSW] = ((R[NUM_PSW] & PSW_RO_MASK) | ((V) & ~PSW_RO_MASK))) + +/* Exceptional conditions handled within the instruction loop */ +#define ABORT_EXC 1 /* CPU exception */ + +/* Contexts for aborts */ +#define C_NONE 0 /* No context. Normal handling. */ +#define C_NORMAL_GATE_VECTOR 1 +#define C_PROCESS_GATE_PCB 2 +#define C_PROCESS_OLD_PCB 3 +#define C_PROCESS_NEW_PCB 4 +#define C_RESET_GATE_VECTOR 5 +#define C_RESET_INT_STACK 6 +#define C_RESET_NEW_PCB 7 +#define C_RESET_SYSTEM_DATA 8 +#define C_STACK_FAULT 9 + +/* Register numbers */ +#define NUM_FP 9 +#define NUM_AP 10 +#define NUM_PSW 11 +#define NUM_SP 12 +#define NUM_PCBP 13 +#define NUM_ISP 14 +#define NUM_PC 15 + +/* System board interrupt priority levels */ +#define CPU_IPL_8 8 +#define CPU_IPL_9 9 +#define CPU_IPL_11 11 +#define CPU_IPL_13 13 +#define CPU_IPL_15 15 + +/* Processor permission levels */ +#define L_KERNEL 0 +#define L_EXEC 1 +#define L_SUPER 2 +#define L_USER 3 + +/* Currently selected processor permission level */ +#define CPU_CM (cpu_km ? L_KERNEL : ((R[NUM_PSW] >> PSW_CM) & 3)) + +/* Data types operated on by instructions. NB: These integer values + have meaning when decoding instructions, so this is not just an + enum. Please don't change them. */ +#define UW 0 /* Unsigned Word */ +#define UH 2 /* Unsigned Halfword */ +#define BT 3 /* Unsigned Byte */ +#define WD 4 /* Signed Word */ +#define HW 6 /* Signed Halfword */ +#define SB 7 /* Signed Byte */ + +#define NA -1 + +/* + * + * Mode Syntax Mode Reg. Bytes Notes + * ---------------------------------------------------------------------- + * Absolute $expr 7 15 5 + * Abs. Deferred *$expr 14 15 5 + * Byte Disp. expr(%rn) 12 0-10,12-15 2 + * Byte Disp. Def. *expr(%rn) 13 0-10,12-15 2 + * Halfword Disp. expr(%rn) 10 0-10,12-15 3 + * Halfword Disp. Def. *expr(%rn) 11 0-10,12-15 3 + * Word Disp. expr(%rn) 8 0-10,12-15 5 + * Word Disp. Def. *expr(%rn) 9 0-10,12-15 5 + * AP Short Offset so(%ap) 7 0-14 1 1 + * FP Short Offset so(%fp) 6 0-14 1 1 + * Byte Immediate &imm8 6 15 2 2,3 + * Halfword Immediate &imm16 5 15 3 2,3 + * Word Immediate &imm32 4 15 5 2,3 + * Positive Literal &lit 0-3 0-15 1 2,3 + * Negative Literal &lit 15 0-15 1 2,3 + * Register %rn 4 0-14 1 1,3 + * Register Deferred (%rn) 5 0-10,12-14 1 1 + * Expanded Op. Type {type}opnd 14 0-14 2-6 4 + * + * Notes: + * + * 1. Mode field has special meaning if register field is 15; see + * absolute or immediate mode. + * 2. Mode may not be used for a destination operand. + * 3. Mode may not be used if the instruction takes effective address + * of the operand. + * 4. 'type' overrides instruction type; 'type' determines the operand + * type, except that it does not determine the length for immediate + * or literals or whether literals are signed or unsigned. 'opnd' + * determines actual address mode. For total bytes, add 1 to byte + * count for address mode determined by 'opnd'. + * + */ + +/* + * Opcodes + */ +typedef enum { + SPOPRD = 0x02, + SPOPD2 = 0x03, + MOVAW = 0x04, + SPOPRT = 0x06, + SPOPT2 = 0x07, + RET = 0x08, +#if defined(REV3) + CASWI = 0x09, + SETX = 0x0A, + CLRX = 0x0B, +#endif + MOVTRW = 0x0C, +#if defined(REV3) + TEDTH = 0x0D, + PACKB = 0x0E, + UNPACKB = 0x0F, +#endif + SAVE = 0x10, + SPOPWD = 0x13, + EXTOP = 0x14, + SPOPWT = 0x17, + RESTORE = 0x18, +#if defined(REV3) + DTH = 0x19, +#endif + SWAPWI = 0x1C, +#if defined(REV3) + TGEDTH = 0x1D, +#endif + SWAPHI = 0x1E, + SWAPBI = 0x1F, + POPW = 0x20, + SPOPRS = 0x22, + SPOPS2 = 0x23, + JMP = 0x24, + CFLUSH = 0x27, + TSTW = 0x28, +#if defined(REV3) + DTB = 0x29, +#endif + TSTH = 0x2A, + TSTB = 0x2B, + CALL = 0x2C, +#if defined(REV3) + TGDTH = 0x2D, +#endif + BPT = 0x2E, + WAIT = 0x2F, + EMB = 0x30, /* Multi-byte */ + SPOP = 0x32, + SPOPWS = 0x33, + JSB = 0x34, + BSBH = 0x36, + BSBB = 0x37, + BITW = 0x38, + BITH = 0x3A, + BITB = 0x3B, + CMPW = 0x3C, +#if defined(REV3) + TNEDTH = 0x3D, +#endif + CMPH = 0x3E, + CMPB = 0x3F, + RGEQ = 0x40, + BGEH = 0x42, + BGEB = 0x43, + RGTR = 0x44, + BGH = 0x46, + BGB = 0x47, + RLSS = 0x48, + BLH = 0x4A, + BLB = 0x4B, + RLEQ = 0x4C, +#if defined(REV3) + TEDTB = 0x4D, +#endif + BLEH = 0x4E, + BLEB = 0x4F, + RGEQU = 0x50, + BGEUH = 0x52, + BGEUB = 0x53, + RGTRU = 0x54, + BGUH = 0x56, + BGUB = 0x57, + RLSSU = 0x58, + BLUH = 0x5A, + BLUB = 0x5B, + RLEQU = 0x5C, +#if defined(REV3) + TGEDTB = 0x5D, +#endif + BLEUH = 0x5E, + BLEUB = 0x5F, + RVC = 0x60, + BVCH = 0x62, + BVCB = 0x63, + RNEQU = 0x64, + BNEH_D = 0x66, + BNEB_D = 0x67, + RVS = 0x68, + BVSH = 0x6A, + BVSB = 0x6B, + REQLU = 0x6C, +#if defined(REV3) + TGDTB = 0x6D, +#endif + BEH_D = 0x6E, + BEB_D = 0x6F, + NOP = 0x70, + NOP3 = 0x72, + NOP2 = 0x73, + RNEQ = 0x74, + BNEH = 0x76, + BNEB = 0x77, + RSB = 0x78, + BRH = 0x7A, + BRB = 0x7B, + REQL = 0x7C, +#if defined(REV3) + TNEDTB = 0x7D, +#endif + BEH = 0x7E, + BEB = 0x7F, + CLRW = 0x80, + CLRH = 0x82, + CLRB = 0x83, + MOVW = 0x84, + MOVH = 0x86, + MOVB = 0x87, + MCOMW = 0x88, + MCOMH = 0x8A, + MCOMB = 0x8B, + MNEGW = 0x8C, + MNEGH = 0x8E, + MNEGB = 0x8F, + INCW = 0x90, + INCH = 0x92, + INCB = 0x93, + DECW = 0x94, + DECH = 0x96, + DECB = 0x97, +#if defined(REV3) + RETQINT = 0x98, + SUBPB2 = 0x9B, +#endif + ADDW2 = 0x9C, + ADDH2 = 0x9E, + ADDB2 = 0x9F, + PUSHW = 0xA0, +#if defined(REV3) + ADDPB2 = 0xA3, +#endif + MODW2 = 0xA4, + MODH2 = 0xA6, + MODB2 = 0xA7, + MULW2 = 0xA8, + MULH2 = 0xAA, + MULB2 = 0xAB, + DIVW2 = 0xAC, + DIVH2 = 0xAE, + DIVB2 = 0xAF, + ORW2 = 0xB0, + ORH2 = 0xB2, + ORB2 = 0xB3, + XORW2 = 0xB4, + XORH2 = 0xB6, + XORB2 = 0xB7, + ANDW2 = 0xB8, + ANDH2 = 0xBA, + ANDB2 = 0xBB, + SUBW2 = 0xBC, + SUBH2 = 0xBE, + SUBB2 = 0xBF, + ALSW3 = 0xC0, + ARSW3 = 0xC4, + ARSH3 = 0xC6, + ARSB3 = 0xC7, + INSFW = 0xC8, + INSFH = 0xCA, + INSFB = 0xCB, + EXTFW = 0xCC, + EXTFH = 0xCE, + EXTFB = 0xCF, + LLSW3 = 0xD0, + LLSH3 = 0xD2, + LLSB3 = 0xD3, + LRSW3 = 0xD4, + ROTW = 0xD8, +#if defined(REV3) + SUBPB3 = 0xDB, +#endif + ADDW3 = 0xDC, + ADDH3 = 0xDE, + ADDB3 = 0xDF, + PUSHAW = 0xE0, +#if defined(REV3) + ADDPB3 = 0xE3, +#endif + MODW3 = 0xE4, + MODH3 = 0xE6, + MODB3 = 0xE7, + MULW3 = 0xE8, + MULH3 = 0xEA, + MULB3 = 0xEB, + DIVW3 = 0xEC, + DIVH3 = 0xEE, + DIVB3 = 0xEF, + ORW3 = 0xF0, + ORH3 = 0xF2, + ORB3 = 0xF3, + XORW3 = 0xF4, + XORH3 = 0xF6, + XORB3 = 0xF7, + ANDW3 = 0xF8, + ANDH3 = 0xFA, + ANDB3 = 0xFB, + SUBW3 = 0xFC, + SUBH3 = 0xFE, + SUBB3 = 0xFF, + MVERNO = 0x3009, + ENBVJMP = 0x300d, + DISVJMP = 0x3013, + MOVBLW = 0x3019, + STREND = 0x301f, + INTACK = 0x302f, + STRCPY = 0x3035, + RETG = 0x3045, + GATE = 0x3061, + CALLPS = 0x30ac, +#if defined(REV3) + UCALLPS = 0x30c0, +#endif + RETPS = 0x30c8 +} opcode; + +/* + * Each instruction expects operands of a certain type. + * + * The large majority of instructions expect operands that have a + * descriptor as the first byte. This descriptor carries all the + * information necessary to compute the addressing mode of the + * operand. + * + * e.g.: + * + * MOVB 6(%r1),%r0 + * +------+------+------+------+ + * | 0x87 | 0xc1 | 0x06 | 0x40 | + * +------+------+------+------+ + * ^^^^^^ + * Descriptor byte. mode = 13 (0x0c), register = 1 (0x01) + * + * + * Branch instructions have either an 8-bit or a 16-bit signed + * displacement value, and lack a descriptor byte. + * + * e.g.: + * + * BCCB 0x03 + * +------+------+ + * | 0x53 | 0x03 | 8-bit displacement + * +------+------+ + * + * BCCH 0x01ff + * +------+------+------+ + * | 0x52 | 0xff | 0x01 | 16-bit displacement + * +------+------+------+ + * + * + * TODO: Describe coprocessor instructions + * + */ +typedef enum { + OP_NONE, /* NULL type */ + OP_DESC, /* Descriptor byte */ + OP_DESB, /* Descriptor with byte displacement (WE32200 only) */ + OP_DESH, /* Descriptor with halfword displacement (WE32200 only) */ + OP_BYTE, /* 8-bit signed value */ + OP_HALF, /* 16-bit signed value */ + OP_COPR /* Coprocessor instruction */ +} op_mode; + +/* Describes a CPU opcode. + * + * e.g.: + * + * {0x09, 3, OP_DESC, WD, "CASWI", 0, 1, -1, 2} + * + * - Opcode 0x09. + * - Followed by three operands. + * - Operands use descriptor bytes. + * - Default data type is word (32 bit). + * - Operand 0 is source 1. + * - Operand 1 is source 2. + * - Operand 2 is destination. + * + */ +typedef struct { + uint16 opcode; + int8 op_count; /* Number of operands */ + op_mode mode; /* Dispatch mode */ + int8 dtype; /* Default data type */ + char mnemonic[8]; + int8 src_op1; + int8 src_op2; + int8 src_op3; + int8 dst_op; +} mnemonic; + +/* + * Structure that describes each operand in a decoded instruction + */ +typedef struct { + uint8 mode; /* Embedded data addressing mode */ + uint8 reg; /* Operand register (0-15) */ +#if defined(REV3) + uint8 reg2; /* Operand register 2 (16-31) */ +#endif + int8 dtype; /* Default type for the operand */ + int8 etype; /* Expanded type (-1 if none) */ + union { + uint32 w; + uint16 h; + uint8 b; + } embedded; /* Data consumed as part of the instruction + stream, i.e. literals, displacement, + etc. */ + uint32 data; /* Data either read or written during + instruction execution */ +} operand; + +/* + * An inst is a combination of a decoded instruction and + * 0 to 4 operands. Also used for history record keeping. + */ +typedef struct { + mnemonic *mn; + uint32 psw; + uint32 sp; + uint32 pc; + t_bool valid; + operand operands[4]; +} instr; + +/* Function prototypes */ +t_stat sys_boot(int32 flag, CONST char *ptr); +t_stat cpu_svc(UNIT *uptr); +t_stat cpu_ex(t_value *vptr, t_addr addr, UNIT *uptr, int32 sw); +t_stat cpu_dep(t_value val, t_addr addr, UNIT *uptr, int32 sw); +t_stat cpu_reset(DEVICE *dptr); +t_stat cpu_set_size(UNIT *uptr, int32 val, CONST char *cptr, void *desc); +t_stat cpu_set_hist(UNIT *uptr, int32 val, CONST char *cptr, void *desc); +t_stat cpu_show_hist(FILE *st, UNIT *uptr, int32 val, CONST void *desc); +t_stat cpu_show_virt(FILE *st, UNIT *uptr, int32 val, CONST void *desc); +t_stat cpu_show_stack(FILE *st, UNIT *uptr, int32 val, CONST void *desc); +t_stat cpu_show_cio(FILE *st, UNIT *uptr, int32 val, CONST void *desc); +t_stat cpu_set_halt(UNIT *uptr, int32 val, char *cptr, void *desc); +t_stat cpu_clear_halt(UNIT *uptr, int32 val, char *cptr, void *desc); +t_stat cpu_boot(int32 unit_num, DEVICE *dptr); +t_stat cpu_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr); +CONST char *cpu_description(DEVICE *dptr); + +t_bool cpu_is_pc_a_subroutine_call (t_addr **ret_addrs); + +void cpu_register_name(uint8 reg, char *buf, size_t len); +void cpu_show_operand(FILE *st, operand *op); +void fprint_sym_hist(FILE *st, instr *ip); +t_stat fprint_sym_m(FILE *of, t_addr addr, t_value *val); + +instr *cpu_next_instruction(void); + +uint8 decode_instruction(instr *instr); +void cpu_on_interrupt(uint16 vec); +void cpu_abort(uint8 et, uint8 isc); + +/* Helper macros */ + +#define MOD(A,B,OP1,OP2,SZ) { \ + if (op_signed(OP1) && !op_signed(OP2)) { \ + result = (SZ)(B) % (A); \ + } else if (!op_signed(OP1) && op_signed(OP2)) { \ + result = (B) % (SZ)(A); \ + } else if (op_signed(OP1) && op_signed(OP2)) { \ + result = (SZ)(B) % (SZ)(A); \ + } else { \ + result = (B) % (A); \ + } \ + } + +#define DIV(A,B,OP1,OP2,SZ) { \ + if (op_signed(OP1) && !op_signed(OP2)) { \ + result = (SZ)(B) / (A); \ + } else if (!op_signed(OP1) && op_signed(OP2)) { \ + result = (B) / (SZ)(A); \ + } else if (op_signed(OP1) && op_signed(OP2)) { \ + result = (SZ)(B) / (SZ)(A); \ + } else { \ + result = (B) / (A); \ + } \ + } + +#define OP_R_W(d,a,p) { \ + (d) = (uint32) (a)[(p)++]; \ + (d) |= (uint32) (a)[(p)++] << 8u; \ + (d) |= (uint32) (a)[(p)++] << 16u; \ + (d) |= (uint32) (a)[(p)++] << 24u; \ + } + +#define OP_R_H(d,a,p) { \ + (d) = (uint16) (a)[(p)++]; \ + (d) |= (uint16) (a)[(p)++] << 8u; \ + } + +#define OP_R_B(d,a,p) { \ + (d) = (uint8) (a)[(p)++]; \ + } + +#define CPU_SET_INT(flags) (sbd_int_req |= flags) +#define CPU_CLR_INT(flags) (sbd_int_req &= ~(flags)) + +extern t_bool rom_loaded; +extern volatile int32 stop_reason; +extern uint16 sbd_int_req; +extern instr *cpu_instr; +extern t_bool cpu_nmi; +extern uint8 *ROM; +extern uint8 *RAM; +extern uint32 R[NUM_REGISTERS]; +extern REG cpu_reg[]; +extern UNIT cpu_unit; +extern uint8 fault; +extern t_bool cpu_km; + +#endif diff --git a/3B2/3b2_csr.h b/3B2/3b2_csr.h index c7cf27a5..3247f222 100644 --- a/3B2/3b2_csr.h +++ b/3B2/3b2_csr.h @@ -1,44 +1,46 @@ -/* 3b2_csr.h: Common CSR header - - Copyright (c) 2021, Seth J. Morabito - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - - Except as contained in this notice, the name of the author shall - not be used in advertising or otherwise to promote the sale, use or - other dealings in this Software without prior written authorization - from the author. -*/ - -#ifndef _3B2_CSR_H_ -#define _3B2_CSR_H_ - -#if defined(REV3) -#include "3b2_rev3_csr.h" -#else -#include "3b2_rev2_csr.h" -#endif - -#define SET_CSR(FLAGS) (csr_data |= (FLAGS)) -#define CLR_CSR(FLAGS) (csr_data &= ~(FLAGS)) -#define CSR(FLAGS) ((csr_data & FLAGS) != 0) - -#endif /* _3B2_CSR_H_ */ +/* 3b2_csr.h: Common CSR/CSER header + + Copyright (c) 2021-2022, Seth J. Morabito + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + Except as contained in this notice, the name of the author shall + not be used in advertising or otherwise to promote the sale, use or + other dealings in this Software without prior written authorization + from the author. +*/ + +#ifndef _3B2_CSR_H_ +#define _3B2_CSR_H_ + +#if defined(REV3) +#include "3b2_rev3_csr.h" +#else +#include "3b2_rev2_csr.h" +#endif + +#define SET_CSR(FLAGS) (csr_data |= (FLAGS)) +#define CLR_CSR(FLAGS) (csr_data &= ~(FLAGS)) +#define CSR(FLAGS) ((csr_data & FLAGS) != 0) + +extern CSR_DATA csr_data; + +#endif /* _3B2_CSR_H_ */ diff --git a/3B2/3b2_ctc.c b/3B2/3b2_ctc.c index 3bc4b08d..b6a0c896 100644 --- a/3B2/3b2_ctc.c +++ b/3B2/3b2_ctc.c @@ -1,908 +1,748 @@ -/* 3b2_ctc.c: AT&T 3B2 Model 400 "CTC" feature card - - Copyright (c) 2018, Seth J. Morabito - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - - Except as contained in this notice, the name of the author shall - not be used in advertising or otherwise to promote the sale, use or - other dealings in this Software without prior written authorization - from the author. -*/ - -#include "3b2_ctc.h" - -#include "sim_disk.h" - -#include "3b2_io.h" -#include "3b2_mem.h" - -#define CTQRESIZE 20 -#define CTQCESIZE 16 - -#define DELAY_SYSGEN 2500 -#define DELAY_FMT 1000000 -#define DELAY_RW 10000 -#define DELAY_OPEN 2500 -#define DELAY_CLOSE 2500 -#define DELAY_CONFIG 2500 -#define DELAY_DLM 1000 -#define DELAY_ULM 1000 -#define DELAY_FCF 1000 -#define DELAY_DOS 1000 -#define DELAY_DSD 1000 -#define DELAY_UNK 1000 -#define DELAY_CATCHUP 10000 - -#define CTC_DIAG_CRC1 0xa4a5752f -#define CTC_DIAG_CRC2 0xd3d20eb3 -#define CTC_DIAG_CRC3 0x0f387ce3 /* Used by SVR 2.0.5 */ - -#define TAPE_DEV 0 /* CTAPE device */ -#define XMF_DEV 1 /* XM Floppy device */ - -#define VTOC_BLOCK 0 - -/* Static function declarations */ -static t_stat ctc_show_cqueue(FILE *st, UNIT *uptr, int32 val, CONST void *desc); -static t_stat ctc_show_rqueue(FILE *st, UNIT *uptr, int32 val, CONST void *desc); -static t_stat ctc_show_queue_common(FILE *st, UNIT *uptr, int32 val, CONST void *desc, t_bool rq); - -static uint8 int_cid; /* Interrupting card ID */ -static uint8 int_subdev; /* Interrupting subdevice */ -static t_bool ctc_conf = FALSE; /* Has a CTC card been configured? */ -static uint32 ctc_crc; /* CRC32 of downloaded memory */ - -struct partition vtoc_table[VTOC_PART] = { - { 2, 0, 5272, 8928 }, /* 00 */ - { 3, 1, 126, 5146 }, /* 01 */ - { 4, 0, 14200, 31341 }, /* 02 */ - { 0, 0, 2, 45539 }, /* 03 */ - { 0, 1, 0, 0 }, /* 04 */ - { 0, 1, 0, 0 }, /* 05 */ - { 5, 1, 0, 45541 }, /* 06 */ - { 1, 1, 0, 126 }, /* 07 */ - { 0, 1, 0, 0 }, /* 08 */ - { 0, 1, 0, 0 }, /* 09 */ - { 0, 1, 0, 0 }, /* 10 */ - { 0, 1, 0, 0 }, /* 11 */ - { 0, 1, 0, 0 }, /* 12 */ - { 0, 1, 0, 0 }, /* 13 */ - { 0, 1, 0, 0 }, /* 14 */ - { 0, 1, 0, 0 } /* 15 */ -}; - -/* State. Although we technically have two devices (tape and floppy), - * only the tape drive is supported at this time. */ - -CTC_STATE ctc_state[2]; - -UNIT ctc_unit = { - UDATA (&ctc_svc, UNIT_FIX|UNIT_ATTABLE|UNIT_DISABLE| - UNIT_ROABLE|UNIT_BINK, CTC_CAPACITY) -}; - -MTAB ctc_mod[] = { - { MTAB_XTD|MTAB_VUN, 0, "write enabled", "WRITEENABLED", - &set_writelock, &show_writelock, NULL, "Write enable tape drive" }, - { MTAB_XTD|MTAB_VUN, 1, NULL, "LOCKED", - &set_writelock, NULL, NULL, "Write lock tape drive" }, - { MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, "RQUEUE=n", NULL, - NULL, &ctc_show_rqueue, NULL, "Display Request Queue for card n" }, - { MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, "CQUEUE=n", NULL, - NULL, &ctc_show_cqueue, NULL, "Display Completion Queue for card n" }, - { 0 } -}; - -static DEBTAB ctc_debug[] = { - { "IO", IO_DBG, "I/O" }, - { "TRACE", TRACE_DBG, "Call Trace" }, - { NULL } -}; - -DEVICE ctc_dev = { - "CTC", /* name */ - &ctc_unit, /* units */ - NULL, /* registers */ - ctc_mod, /* modifiers */ - 1, /* #units */ - 16, /* address radix */ - 32, /* address width */ - 1, /* address incr. */ - 16, /* data radix */ - 8, /* data width */ - NULL, /* examine routine */ - NULL, /* deposit routine */ - &ctc_reset, /* reset routine */ - NULL, /* boot routine */ - &ctc_attach, /* attach routine */ - &ctc_detach, /* detach routine */ - NULL, /* context */ - DEV_DISABLE|DEV_DIS|DEV_DEBUG|DEV_SECTORS, /* flags */ - 0, /* debug control flags */ - ctc_debug, /* debug flag names */ - NULL, /* memory size change */ - NULL, /* logical name */ - NULL, /* help routine */ - NULL, /* attach help routine */ - NULL, /* help context */ - NULL, /* device description */ -}; - -static void cio_irq(uint8 cid, uint8 dev, int32 delay) -{ - int_cid = cid; - int_subdev = dev & 0x3f; - sim_activate_after(&ctc_unit, delay); -} - -/* - * Write a VTOC and pdinfo to the tape file - */ -static t_stat ctc_write_vtoc(struct vtoc *vtoc, struct pdinfo *pdinfo, uint32 maxpass) -{ - uint8 buf[PD_BYTES]; - uint32 wr, offset; - - memcpy(buf, vtoc, sizeof(struct vtoc)); - offset = sizeof(struct vtoc); - memcpy(buf + offset, pdinfo, sizeof(struct pdinfo)); - offset += sizeof(struct pdinfo); - memcpy(buf + offset, &maxpass, sizeof(uint32)); - - return sim_disk_wrsect(&ctc_unit, VTOC_BLOCK, buf, &wr, 1); -} - -/* - * Load a VTOC and pdinfo from the tape file - */ -static t_stat ctc_read_vtoc(struct vtoc *vtoc, struct pdinfo *pdinfo, uint32 *maxpass) -{ - uint8 buf[PD_BYTES]; - uint32 wr, offset; - t_stat result; - - result = sim_disk_rdsect(&ctc_unit, VTOC_BLOCK, buf, &wr, 1); - - if (result != SCPE_OK) { - return result; - } - - memcpy(vtoc, buf, sizeof(struct vtoc)); - offset = sizeof(struct vtoc); - memcpy(pdinfo, buf + offset, sizeof(struct pdinfo)); - offset += sizeof(struct pdinfo); - memcpy(maxpass, buf + offset, sizeof(uint32)); - - return result; -} - -/* - * Update the host's in-memory copy of the VTOC and pdinfo - */ -static void ctc_update_vtoc(uint32 maxpass, - uint32 vtoc_addr, uint32 pdinfo_addr, - struct vtoc *vtoc, struct pdinfo *pdinfo) -{ - uint32 i; - - pwrite_w(vtoc_addr + 12, VTOC_VALID); - pwrite_w(vtoc_addr + 16, vtoc->version); - for (i = 0; i < 8; i++) { - pwrite_b(vtoc_addr + 20 + i, (uint8)(vtoc->volume[i])); - } - pwrite_h(vtoc_addr + 28, vtoc->sectorsz); - pwrite_h(vtoc_addr + 30, vtoc->nparts); - - for (i = 0; i < VTOC_PART; i++) { - pwrite_h(vtoc_addr + 72 + (i * 12) + 0, vtoc_table[i].id); - pwrite_h(vtoc_addr + 72 + (i * 12) + 2, vtoc_table[i].flag); - pwrite_w(vtoc_addr + 72 + (i * 12) + 4, vtoc_table[i].sstart); - pwrite_w(vtoc_addr + 72 + (i * 12) + 8, vtoc_table[i].ssize); - } - - /* Write the pdinfo */ - pwrite_w(pdinfo_addr, pdinfo->driveid); - pwrite_w(pdinfo_addr + 4, pdinfo->sanity); - pwrite_w(pdinfo_addr + 8, pdinfo->version); - for (i = 0; i < 12; i++) { - pwrite_b(pdinfo_addr + 12 + i, pdinfo->serial[i]); - } - pwrite_w(pdinfo_addr + 24, pdinfo->cyls); - pwrite_w(pdinfo_addr + 28, pdinfo->tracks); - pwrite_w(pdinfo_addr + 32, pdinfo->sectors); - pwrite_w(pdinfo_addr + 36, pdinfo->bytes); - pwrite_w(pdinfo_addr + 40, pdinfo->logicalst); - pwrite_w(pdinfo_addr + 44, pdinfo->errlogst); - pwrite_w(pdinfo_addr + 48, pdinfo->errlogsz); - pwrite_w(pdinfo_addr + 52, pdinfo->mfgst); - pwrite_w(pdinfo_addr + 56, pdinfo->mfgsz); - pwrite_w(pdinfo_addr + 60, pdinfo->defectst); - pwrite_w(pdinfo_addr + 64, pdinfo->defectsz); - pwrite_w(pdinfo_addr + 68, pdinfo->relno); - pwrite_w(pdinfo_addr + 72, pdinfo->relst); - pwrite_w(pdinfo_addr + 76, pdinfo->relsz); - pwrite_w(pdinfo_addr + 80, pdinfo->relnext); - - /* Now something horrible happens. We sneak RIGHT off the end of - * the pdinfo struct and reach deep into the pdsector struct that - * it is part of. */ - - pwrite_w(pdinfo_addr + 128, maxpass); -} - -/* - * Handle a single request taken from the Request Queue. - * - * Note that the driver stuffs parameters into various different - * fields of the Request Queue entry seemingly at random, and also - * expects response parameters to be placed in specific fields of the - * Completion Queue entry. It can be confusing to follow. - */ -static void ctc_cmd(uint8 cid, - cio_entry *rqe, uint8 *rapp_data, - cio_entry *cqe, uint8 *capp_data) -{ - uint32 vtoc_addr, pdinfo_addr, ctjob_addr; - uint32 maxpass, blkno, delay, last_byte; - uint8 dev, c; - uint8 sec_buf[VTOC_SECSZ]; - int32 b, i, j; - int32 block_count, read_bytes, remainder, dest; - t_seccnt secrw = 0; - struct vtoc vtoc = {{0}}; - struct pdinfo pdinfo = {0}; - t_stat result; - - uint32 lba; /* Logical Block Address */ - - maxpass = 0; - dev = rqe->subdevice & 1; /* Tape or Floppy device */ - - capp_data[7] = rqe->opcode; - cqe->subdevice = rqe->subdevice; - - switch(rqe->opcode) { - case CIO_DLM: - for (i = 0; i < rqe->byte_count; i++) { - ctc_crc = cio_crc32_shift(ctc_crc, pread_b(rqe->address + i)); - } - sim_debug(TRACE_DBG, &ctc_dev, - "[ctc_cmd] CIO Download Memory: bytecnt=%04x " - "addr=%08x return_addr=%08x subdev=%02x (CRC=%08x)\n", - rqe->byte_count, rqe->address, - rqe->address, rqe->subdevice, ctc_crc); - delay = DELAY_DLM; - cqe->address = rqe->address + rqe->byte_count; - cqe->opcode = CTC_SUCCESS; - break; - case CIO_ULM: - sim_debug(TRACE_DBG, &ctc_dev, - "[ctc_cmd] CIO Upload Memory: return opcode 0\n"); - delay = DELAY_ULM; - cqe->opcode = CTC_SUCCESS; - break; - case CIO_FCF: - sim_debug(TRACE_DBG, &ctc_dev, - "[ctc_cmd] CIO Force Function Call (CRC=%08x)\n", ctc_crc); - delay = DELAY_FCF; - - /* If the currently running program is a diagnostic program, - * we are expected to write results into memory at address - * 0x200f000 */ - if (ctc_crc == CTC_DIAG_CRC1 || - ctc_crc == CTC_DIAG_CRC2 || - ctc_crc == CTC_DIAG_CRC3) { - pwrite_h(0x200f000, 0x1); /* Test success */ - pwrite_h(0x200f002, 0x0); /* Test Number */ - pwrite_h(0x200f004, 0x0); /* Actual */ - pwrite_h(0x200f006, 0x0); /* Expected */ - pwrite_b(0x200f008, 0x1); /* Success flag again */ - } - - /* An interesting (?) side-effect of FORCE FUNCTION CALL is - * that it resets the card state such that a new SYSGEN is - * required in order for new commands to work. In fact, an - * INT0/INT1 combo _without_ a RESET can sysgen the board. So, - * we reset the command bits here. */ - cio[cid].sysgen_s = 0; - cqe->opcode = CTC_SUCCESS; - break; - case CIO_DOS: - sim_debug(TRACE_DBG, &ctc_dev, - "[ctc_cmd] CIO_DOS (%d)\n", - rqe->opcode); - delay = DELAY_DOS; - cqe->opcode = CTC_SUCCESS; - break; - case CIO_DSD: - sim_debug(TRACE_DBG, &ctc_dev, - "[ctc_cmd] CTC_DSD (%d)\n", - rqe->opcode); - delay = DELAY_DSD; - /* Write subdevice information to the host. */ - pwrite_h(rqe->address, CTC_NUM_SD); - pwrite_h(rqe->address + 2, CTC_SD_FT25); - pwrite_h(rqe->address + 4, CTC_SD_FD5); - cqe->opcode = CTC_SUCCESS; - break; - case CTC_FORMAT: - sim_debug(TRACE_DBG, &ctc_dev, - "[ctc_cmd] CTC_FORMAT (%d)\n", - rqe->opcode); - - delay = DELAY_FMT; - - /* FORMAT stores the job pointer in the jio_start field of the - * completion queue entry's application data */ - capp_data[0] = rapp_data[4]; - capp_data[1] = rapp_data[5]; - capp_data[2] = rapp_data[6]; - capp_data[3] = rapp_data[7]; - - if (dev == XMF_DEV) { - cqe->opcode = CTC_NOTREADY; - break; - } - - if ((ctc_unit.flags & UNIT_ATT) == 0) { - cqe->opcode = CTC_NOMEDIA; - break; - } - - if (ctc_unit.flags & UNIT_WPRT) { - cqe->opcode = CTC_RDONLY; - break; - } - - /* Write a valid VTOC and pdinfo to the tape */ - - vtoc.sanity = VTOC_VALID; - vtoc.version = 1; - strcpy((char *)vtoc.volume, "ctctape"); - vtoc.sectorsz = PD_BYTES; - vtoc.nparts = VTOC_PART; - - pdinfo.driveid = PD_DRIVEID; - pdinfo.sanity = PD_VALID; - pdinfo.version = 0; - memset(pdinfo.serial, 0, 12); - pdinfo.cyls = PD_CYLS; - pdinfo.tracks = PD_TRACKS; - pdinfo.sectors = PD_SECTORS; - pdinfo.bytes = PD_BYTES; - pdinfo.logicalst = PD_LOGICALST; - pdinfo.errlogst = 0xffffffff; - pdinfo.errlogsz = 0xffffffff; - pdinfo.mfgst = 0xffffffff; - pdinfo.mfgsz = 0xffffffff; - pdinfo.defectst = 0xffffffff; - pdinfo.defectsz = 0xffffffff; - pdinfo.relno = 0xffffffff; - pdinfo.relst = 0xffffffff; - pdinfo.relsz = 0xffffffff; - pdinfo.relnext = 0xffffffff; - - maxpass = rqe->address; - - ctc_write_vtoc(&vtoc, &pdinfo, maxpass); - - cqe->opcode = CTC_SUCCESS; - - /* The address field holds the total amount of time (in 25ms - * chunks) used during this format session. We'll fudge and - * say 1 minute for formatting. */ - cqe->address = 2400; - - break; - case CTC_OPEN: - sim_debug(TRACE_DBG, &ctc_dev, - "[ctc_cmd] CTC_OPEN (%d)\n", - rqe->opcode); - - delay = DELAY_OPEN; - - ctc_state[dev].time = 0; /* Opening always resets session time to 0 */ - ctc_state[dev].bytnum = 0; - - vtoc_addr = rqe->address; - pdinfo_addr = ATOW(rapp_data, 4); - ctjob_addr = ATOW(rapp_data, 8); - - /* For OPEN commands, the Completion Queue Entry's address - * field contains a pointer to the ctjobstat. */ - cqe->address = ctjob_addr; - - if (dev == XMF_DEV) { - cqe->opcode = CTC_NOTREADY; - break; - } - - if ((ctc_unit.flags & UNIT_ATT) == 0) { - cqe->opcode = CTC_NOMEDIA; - break; - } - - /* Load the vtoc, pdinfo, and maxpass from the tape */ - ctc_read_vtoc(&vtoc, &pdinfo, &maxpass); - - ctc_update_vtoc(maxpass, vtoc_addr, pdinfo_addr, &vtoc, &pdinfo); - cqe->opcode = CTC_SUCCESS; - break; - case CTC_CLOSE: - sim_debug(TRACE_DBG, &ctc_dev, - "[ctc_cmd] CTC_CLOSE (%d)\n", - rqe->opcode); - - delay = DELAY_CLOSE; - - /* The Request Queue Entry's address field contains the - * ctjobstat pointer, which the driver will want to find in - * the first word of our Completion Queue Entry's application - * data. This must be in place whether we have media attached - * or not. */ - capp_data[3] = rqe->address & 0xff; - capp_data[2] = (rqe->address & 0xff00) >> 8; - capp_data[1] = (rqe->address & 0xff0000) >> 16; - capp_data[0] = (rqe->address & 0xff000000) >> 24; - - /* The Completion Queue Entry's address field holds the total - * tape time used in this session. */ - cqe->address = ctc_state[dev].time; - cqe->opcode = CTC_SUCCESS; - - break; - case CTC_WRITE: - case CTC_VWRITE: - sim_debug(TRACE_DBG, &ctc_dev, - "[ctc_cmd] CTC_WRITE or CTC_VWRITE (%d)\n", - rqe->opcode); - - delay = DELAY_RW; - - cqe->byte_count = rqe->byte_count; - cqe->subdevice = rqe->subdevice; - cqe->address = ATOW(rapp_data, 4); - - if (dev == XMF_DEV) { - cqe->opcode = CTC_NOTREADY; - break; - } - - if ((ctc_unit.flags & UNIT_ATT) == 0) { - cqe->opcode = CTC_NOMEDIA; - break; - } - - if (ctc_unit.flags & UNIT_WPRT) { - cqe->opcode = CTC_RDONLY; - break; - } - - blkno = ATOW(rapp_data, 0); - - for (b = 0; b < rqe->byte_count / VTOC_SECSZ; b++) { - ctc_state[dev].time += 10; - for (j = 0; j < VTOC_SECSZ; j++) { - /* Fill the buffer */ - sec_buf[j] = pread_b(rqe->address + (b * VTOC_SECSZ) + j); - } - lba = blkno + b; - result = sim_disk_wrsect(&ctc_unit, lba, sec_buf, &secrw, 1); - if (result == SCPE_OK) { - sim_debug(TRACE_DBG, &ctc_dev, - "[ctc_cmd] ... CTC_WRITE: 512 bytes at block %d (0x%x)\n", - lba, lba); - cqe->opcode = CTC_SUCCESS; - } else { - cqe->opcode = CTC_RWERROR; - break; - } - } - - break; - case CTC_READ: - sim_debug(TRACE_DBG, &ctc_dev, - "[ctc_cmd] CTC_READ (%d)\n", - rqe->opcode); - delay = DELAY_RW; - cqe->byte_count = rqe->byte_count; - cqe->subdevice = rqe->subdevice; - cqe->address = ATOW(rapp_data, 4); - dest = rqe->address; - - if (dev == XMF_DEV) { - cqe->opcode = CTC_NOTREADY; - break; - } - - if ((ctc_unit.flags & UNIT_ATT) == 0) { - cqe->opcode = CTC_NOMEDIA; - break; - } - - /* - * This read routine supports both streaming and block - * oriented modes. - * - * Read requests from the host give a block number, and a - * number of bytes to read. In streaming mode, however, there - * is no requirement that the number of bytes to read has to - * be block-aligned, so we must support reading an arbitrary - * number of bytes from the tape stream and remembering the - * current position in the byte stream. - * - */ - - /* The block number to begin reading from is supplied in the - * request queue entry's APP_DATA field. */ - blkno = ATOW(rapp_data, 0); - - /* Since we may start reading from the data stream at an - * arbitrary location, we compute the offset of the last byte - * to be read, and use that to figure out how many bytes will - * be left over to read from an "extra" block */ - last_byte = ctc_state[dev].bytnum + rqe->byte_count; - remainder = last_byte % VTOC_SECSZ; - - /* The number of blocks we have to read in total is computed - * by looking at the byte count, PLUS any remainder that will - * be left after crossing a block boundary */ - block_count = rqe->byte_count / VTOC_SECSZ; - if (((rqe->byte_count % VTOC_SECSZ) > 0 || remainder > 0)) { - block_count++; - } - - /* Now step over each block, and start reading from the - * necessary location. */ - for (b = 0; b < block_count; b++) { - uint32 start_byte; - /* Add some read time to the read time counter */ - ctc_state[dev].time += 10; - start_byte = ctc_state[dev].bytnum % VTOC_SECSZ; - lba = blkno + b; - result = sim_disk_rdsect(&ctc_unit, lba, sec_buf, &secrw, 1); - if (result == SCPE_OK) { - /* If this is the last "extra" block, we will only - * read the remainder of bytes from it. Otherwise, we - * need to consume the whole block. */ - if (b == (block_count - 1) && remainder > 0) { - read_bytes = remainder; - } else { - read_bytes = VTOC_SECSZ - start_byte; - } - for (j = 0; j < read_bytes; j++) { - uint32 offset; - /* Drain the buffer */ - if (b == 0 && (j + start_byte) < VTOC_SECSZ) { - /* This is a partial read of the first block, - * continuing to read from a previous partial - * block read. */ - offset = j + start_byte; - } else { - offset = j; - } - c = sec_buf[offset]; - pwrite_b(dest++, c); - ctc_state[dev].bytnum++; - } - } else { - sim_debug(TRACE_DBG, &ctc_dev, - "[ctc_cmd] Error reading sector at address %d. Giving up\n", lba); - break; - } - } - - if (result == SCPE_OK) { - cqe->opcode = CTC_SUCCESS; - } else { - cqe->opcode = CTC_RWERROR; - } - - break; - case CTC_CONFIG: - sim_debug(TRACE_DBG, &ctc_dev, - "[ctc_cmd] CTC_CONFIG (%d)\n", - rqe->opcode); - delay = DELAY_CONFIG; - cqe->opcode = CTC_SUCCESS; - break; - default: - sim_debug(TRACE_DBG, &ctc_dev, - "[ctc_cmd] UNHANDLED OP: %d (0x%02x)\n", - rqe->opcode, rqe->opcode); - delay = DELAY_UNK; - cqe->opcode = CTC_HWERROR; - break; - } - - cio_irq(cid, rqe->subdevice, delay); -} - -void ctc_sysgen(uint8 cid) -{ - cio_entry cqe = {0}; - uint8 rapp_data[12] = {0}; - - ctc_crc = 0; - - sim_debug(TRACE_DBG, &ctc_dev, "[ctc_sysgen] Handling Sysgen.\n"); - sim_debug(TRACE_DBG, &ctc_dev, "[ctc_sysgen] rqp=%08x\n", cio[cid].rqp); - sim_debug(TRACE_DBG, &ctc_dev, "[ctc_sysgen] cqp=%08x\n", cio[cid].cqp); - sim_debug(TRACE_DBG, &ctc_dev, "[ctc_sysgen] rqs=%d\n", cio[cid].rqs); - sim_debug(TRACE_DBG, &ctc_dev, "[ctc_sysgen] cqs=%d\n", cio[cid].cqs); - sim_debug(TRACE_DBG, &ctc_dev, "[ctc_sysgen] ivec=%d\n", cio[cid].ivec); - sim_debug(TRACE_DBG, &ctc_dev, "[ctc_sysgen] no_rque=%d\n", cio[cid].no_rque); - - cqe.opcode = 3; /* Sysgen success! */ - - cio_cexpress(cid, CTQCESIZE, &cqe, rapp_data); - cio_cqueue(cid, CIO_STAT, CTQCESIZE, &cqe, rapp_data); - - int_cid = cid; - sim_activate_after(&ctc_unit, DELAY_SYSGEN); -} - -void ctc_express(uint8 cid) -{ - cio_entry rqe, cqe; - uint8 rapp_data[12] = {0}; - uint8 capp_data[8] = {0}; - - sim_debug(TRACE_DBG, &ctc_dev, "[ctc_express] Handling Express Request\n"); - - cio_rexpress(cid, CTQRESIZE, &rqe, rapp_data); - ctc_cmd(cid, &rqe, rapp_data, &cqe, capp_data); - - dump_entry(TRACE_DBG, &ctc_dev, "COMPLETION", - CTQCESIZE, &cqe, capp_data); - - cio_cexpress(cid, CTQCESIZE, &cqe, capp_data); -} - -void ctc_full(uint8 cid) -{ - cio_entry rqe, cqe; - uint8 rapp_data[12] = {0}; - uint8 capp_data[8] = {0}; - - sim_debug(TRACE_DBG, &ctc_dev, "[ctc_full] Handling Full Request\n"); - - while (cio_cqueue_avail(cid, CTQCESIZE) && - cio_rqueue(cid, TAPE_DEV, CTQRESIZE, &rqe, rapp_data) == SCPE_OK) { - ctc_cmd(cid, &rqe, rapp_data, &cqe, capp_data); - } - cio_cqueue(cid, CIO_STAT, CTQCESIZE, &cqe, capp_data); -} - -t_stat ctc_reset(DEVICE *dptr) -{ - uint8 cid; - - ctc_crc = 0; - - sim_debug(TRACE_DBG, &ctc_dev, - "[ctc_reset] Resetting CTC device\n"); - - memset(ctc_state, 0, 2 * sizeof(CTC_STATE)); - - if (dptr->flags & DEV_DIS) { - sim_debug(TRACE_DBG, &ctc_dev, - "[ctc_reset] REMOVING CARD\n"); - - for (cid = 0; cid < CIO_SLOTS; cid++) { - if (cio[cid].id == CTC_ID) { - break; - } - } - - if (cid == CIO_SLOTS) { - /* No card was ever attached */ - return SCPE_OK; - } - - cio[cid].id = 0; - cio[cid].ipl = 0; - cio[cid].ivec = 0; - cio[cid].exp_handler = NULL; - cio[cid].full_handler = NULL; - cio[cid].sysgen = NULL; - - ctc_conf = FALSE; - } else if (!ctc_conf) { - sim_debug(TRACE_DBG, &ctc_dev, - "[ctc_reset] ATTACHING CARD\n"); - - /* Find the first avaialable slot */ - for (cid = 0; cid < CIO_SLOTS; cid++) { - if (cio[cid].id == 0) { - break; - } - } - - /* Do we have room? */ - if (cid == CIO_SLOTS) { - return SCPE_NXM; - } - - cio[cid].id = CTC_ID; - cio[cid].ipl = CTC_IPL; - cio[cid].exp_handler = &ctc_express; - cio[cid].full_handler = &ctc_full; - cio[cid].sysgen = &ctc_sysgen; - - ctc_conf = TRUE; - } - - return SCPE_OK; -} - -t_stat ctc_svc(UNIT *uptr) -{ - uint16 lp, ulp; - - if (cio[int_cid].ivec > 0) { - sim_debug(TRACE_DBG, &ctc_dev, - "[cio_svc] IRQ for board %d (VEC=%d)\n", - int_cid, cio[int_cid].ivec); - CIO_SET_INT(int_cid); - } - - /* Check to see if the completion queue has more work in it. We - * need to schedule an interrupt for each job if we've fallen - * behind (this should be rare) */ - lp = cio_c_lp(int_cid, CTQCESIZE); - ulp = cio_c_ulp(int_cid, CTQCESIZE); - - if ((ulp + CTQCESIZE) % (CTQCESIZE * cio[int_cid].cqs) != lp) { - sim_debug(TRACE_DBG, &ctc_dev, - "[cio_svc] Completion queue has fallen behind (lp=%04x ulp=%04x)\n", - lp, ulp); - /* Schedule a catch-up interrupt */ - sim_activate_abs(&ctc_unit, DELAY_CATCHUP); - } - - return SCPE_OK; -} - -t_stat ctc_attach(UNIT *uptr, CONST char *cptr) -{ - return sim_disk_attach(uptr, cptr, VTOC_SECSZ, 1, TRUE, 0, "CIPHER23", 0, 0); -} - -t_stat ctc_detach(UNIT *uptr) -{ - return sim_disk_detach(uptr); -} - -t_stat ctc_show_rqueue(FILE *st, UNIT *uptr, int32 val, CONST void *desc) -{ - return ctc_show_queue_common(st, uptr, val, desc, TRUE); -} - -t_stat ctc_show_cqueue(FILE *st, UNIT *uptr, int32 val, CONST void *desc) -{ - return ctc_show_queue_common(st, uptr, val, desc, FALSE); -} - - -static t_stat ctc_show_queue_common(FILE *st, UNIT *uptr, int32 val, - CONST void *desc, t_bool rq) -{ - uint8 cid; - char *cptr = (char *) desc; - t_stat result; - uint32 ptr, size, no_rque, i, j; - uint8 op, dev, seq, cmdstat; - - if (cptr) { - cid = (uint8) get_uint(cptr, 10, 12, &result); - if (result != SCPE_OK) { - return SCPE_ARG; - } - } else { - return SCPE_ARG; - } - - /* If the card is not sysgen'ed, give up */ - if (cio[cid].sysgen_s != CIO_SYSGEN) { - fprintf(st, "No card in slot %d, or card has not completed sysgen\n", cid); - return SCPE_ARG; - } - - if (rq) { - ptr = cio[cid].rqp; - size = cio[cid].rqs; - no_rque = cio[cid].no_rque; - fprintf(st, "Dumping %d Request Queues\n", no_rque); - fprintf(st, "---------------------------------------------------------\n"); - fprintf(st, "EXPRESS ENTRY:\n"); - fprintf(st, " Byte Count: %d\n", pread_h(ptr)); - fprintf(st, " Subdevice: %d\n", pread_b(ptr + 2)); - fprintf(st, " Opcode: 0x%02x\n", pread_b(ptr + 3)); - fprintf(st, " Addr/Data: 0x%08x\n", pread_w(ptr + 4)); - fprintf(st, " App Data: 0x%08x\n", pread_w(ptr + 8)); - ptr += CTQRESIZE; - - for (i = 0; i < no_rque; i++) { - fprintf(st, "---------------------------------------------------------\n"); - fprintf(st, "REQUEST QUEUE %d\n", i); - fprintf(st, "---------------------------------------------------------\n"); - fprintf(st, "Load Pointer: %d\n", pread_h(ptr) / CTQRESIZE); - fprintf(st, "Unload Pointer: %d\n", pread_h(ptr + 2) / CTQRESIZE); - fprintf(st, "---------------------------------------------------------\n"); - ptr += 4; - for (j = 0; j < size; j++) { - dev = pread_b(ptr + 2); - op = pread_b(ptr + 3); - seq = (dev & 0x40) >> 6; - cmdstat = (dev & 0x80) >> 7; - fprintf(st, "REQUEST ENTRY %d\n", j); - fprintf(st, " Byte Count: %d\n", pread_h(ptr)); - fprintf(st, " Subdevice: %d\n", dev & 0x3f); - fprintf(st, " Cmd/Stat: %d\n", cmdstat); - fprintf(st, " Seqbit: %d\n", seq); - fprintf(st, " Opcode: 0x%02x (%d)\n", op, op); - fprintf(st, " Addr/Data: 0x%08x\n", pread_w(ptr + 4)); - fprintf(st, " App Data: 0x%08x 0x%08x 0x%08x\n", - pread_w(ptr + 8), pread_w(ptr + 12), pread_w(ptr + 16)); - ptr += CTQRESIZE; - } - } - } else { - ptr = cio[cid].cqp; - size = cio[cid].cqs; - no_rque = 0; /* Not used */ - fprintf(st, "Dumping Completion Queue\n"); - fprintf(st, "---------------------------------------------------------\n"); - fprintf(st, "EXPRESS ENTRY:\n"); - fprintf(st, " Byte Count: %d\n", pread_h(ptr)); - fprintf(st, " Subdevice: %d\n", pread_b(ptr + 2)); - fprintf(st, " Opcode: 0x%02x\n", pread_b(ptr + 3)); - fprintf(st, " Addr/Data: 0x%08x\n", pread_w(ptr + 4)); - fprintf(st, " App Data: 0x%08x\n", pread_w(ptr + 8)); - ptr += CTQCESIZE; - - fprintf(st, "---------------------------------------------------------\n"); - fprintf(st, "Load Pointer: %d\n", pread_h(ptr) / CTQCESIZE); - fprintf(st, "Unload Pointer: %d\n", pread_h(ptr + 2) / CTQCESIZE); - fprintf(st, "---------------------------------------------------------\n"); - ptr += 4; - for (i = 0; i < size; i++) { - dev = pread_b(ptr + 2); - op = pread_b(ptr + 3); - seq = (dev & 0x40) >> 6; - cmdstat = (dev & 0x80) >> 7; - fprintf(st, "COMPLETION ENTRY %d\n", i); - fprintf(st, " Byte Count: %d\n", pread_h(ptr)); - fprintf(st, " Subdevice: %d\n", dev & 0x3f); - fprintf(st, " Cmd/Stat: %d\n", cmdstat); - fprintf(st, " Seqbit: %d\n", seq); - fprintf(st, " Opcode: 0x%02x (%d)\n", op, op); - fprintf(st, " Addr/Data: 0x%08x\n", pread_w(ptr + 4)); - fprintf(st, " App Data: 0x%08x 0x%08x\n", - pread_w(ptr + 8), pread_w(ptr + 12)); - ptr += CTQCESIZE; - } - } - - return SCPE_OK; -} +/* 3b2_ctc.c: CM195H 23MB Cartridge Tape Controller CIO Card + + Copyright (c) 2018-2022, Seth J. Morabito + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + Except as contained in this notice, the name of the author shall + not be used in advertising or otherwise to promote the sale, use or + other dealings in this Software without prior written authorization + from the author. +*/ + +#include "3b2_ctc.h" + +#include "sim_disk.h" + +#include "3b2_io.h" +#include "3b2_mem.h" + +#define CTQRESIZE 20 +#define CTQCESIZE 16 + +#define DELAY_SYSGEN 2500 +#define DELAY_FMT 1000000 +#define DELAY_RW 10000 +#define DELAY_OPEN 2500 +#define DELAY_CLOSE 2500 +#define DELAY_CONFIG 2500 +#define DELAY_DLM 1000 +#define DELAY_ULM 1000 +#define DELAY_FCF 1000 +#define DELAY_DOS 1000 +#define DELAY_DSD 1000 +#define DELAY_UNK 1000 +#define DELAY_CATCHUP 10000 + +#define CTC_DIAG_CRC1 0xa4a5752f +#define CTC_DIAG_CRC2 0xd3d20eb3 +#define CTC_DIAG_CRC3 0x0f387ce3 /* Used by SVR 2.0.5 */ + +#define TAPE_DEV 0 /* CTAPE device */ +#define XMF_DEV 1 /* XM Floppy device */ + +#define VTOC_BLOCK 0 + +static uint8 int_slot; /* Interrupting card ID */ +static uint8 int_subdev; /* Interrupting subdevice */ +static t_bool ctc_conf = FALSE; /* Has a CTC card been configured? */ +static uint32 ctc_crc; /* CRC32 of downloaded memory */ + +struct partition vtoc_table[VTOC_PART] = { + { 2, 0, 5272, 8928 }, /* 00 */ + { 3, 1, 126, 5146 }, /* 01 */ + { 4, 0, 14200, 31341 }, /* 02 */ + { 0, 0, 2, 45539 }, /* 03 */ + { 0, 1, 0, 0 }, /* 04 */ + { 0, 1, 0, 0 }, /* 05 */ + { 5, 1, 0, 45541 }, /* 06 */ + { 1, 1, 0, 126 }, /* 07 */ + { 0, 1, 0, 0 }, /* 08 */ + { 0, 1, 0, 0 }, /* 09 */ + { 0, 1, 0, 0 }, /* 10 */ + { 0, 1, 0, 0 }, /* 11 */ + { 0, 1, 0, 0 }, /* 12 */ + { 0, 1, 0, 0 }, /* 13 */ + { 0, 1, 0, 0 }, /* 14 */ + { 0, 1, 0, 0 } /* 15 */ +}; + +/* State. Although we technically have two devices (tape and floppy), + * only the tape drive is supported at this time. */ + +CTC_STATE ctc_state[2]; + +UNIT ctc_unit = { + UDATA (&ctc_svc, UNIT_FIX|UNIT_ATTABLE|UNIT_DISABLE| + UNIT_ROABLE|UNIT_BINK, CTC_CAPACITY) +}; + +MTAB ctc_mod[] = { + { MTAB_XTD|MTAB_VUN, 0, "write enabled", "WRITEENABLED", + &set_writelock, &show_writelock, NULL, "Write enable tape drive" }, + { MTAB_XTD|MTAB_VUN, 1, NULL, "LOCKED", + &set_writelock, NULL, NULL, "Write lock tape drive" }, + { 0 } +}; + +static DEBTAB ctc_debug[] = { + { "IO", IO_DBG, "I/O" }, + { "TRACE", TRACE_DBG, "Call Trace" }, + { NULL } +}; + +DEVICE ctc_dev = { + "CTC", /* name */ + &ctc_unit, /* units */ + NULL, /* registers */ + ctc_mod, /* modifiers */ + 1, /* #units */ + 16, /* address radix */ + 32, /* address width */ + 1, /* address incr. */ + 16, /* data radix */ + 8, /* data width */ + NULL, /* examine routine */ + NULL, /* deposit routine */ + &ctc_reset, /* reset routine */ + NULL, /* boot routine */ + &ctc_attach, /* attach routine */ + &ctc_detach, /* detach routine */ + NULL, /* context */ + DEV_DISABLE|DEV_DIS|DEV_DEBUG|DEV_SECTORS, /* flags */ + 0, /* debug control flags */ + ctc_debug, /* debug flag names */ + NULL, /* memory size change */ + NULL, /* logical name */ + NULL, /* help routine */ + NULL, /* attach help routine */ + NULL, /* help context */ + NULL, /* device description */ +}; + +static void cio_irq(uint8 slot, uint8 dev, int32 delay) +{ + int_slot = slot; + int_subdev = dev & 0x3f; + sim_activate_after(&ctc_unit, delay); +} + +/* + * Write a VTOC and pdinfo to the tape file + */ +static t_stat ctc_write_vtoc(struct vtoc *vtoc, struct pdinfo *pdinfo, uint32 maxpass) +{ + uint8 buf[PD_BYTES]; + uint32 wr, offset; + + memcpy(buf, vtoc, sizeof(struct vtoc)); + offset = sizeof(struct vtoc); + memcpy(buf + offset, pdinfo, sizeof(struct pdinfo)); + offset += sizeof(struct pdinfo); + memcpy(buf + offset, &maxpass, sizeof(uint32)); + + return sim_disk_wrsect(&ctc_unit, VTOC_BLOCK, buf, &wr, 1); +} + +/* + * Load a VTOC and pdinfo from the tape file + */ +static t_stat ctc_read_vtoc(struct vtoc *vtoc, struct pdinfo *pdinfo, uint32 *maxpass) +{ + uint8 buf[PD_BYTES]; + uint32 wr, offset; + t_stat result; + + result = sim_disk_rdsect(&ctc_unit, VTOC_BLOCK, buf, &wr, 1); + + if (result != SCPE_OK) { + return result; + } + + memcpy(vtoc, buf, sizeof(struct vtoc)); + offset = sizeof(struct vtoc); + memcpy(pdinfo, buf + offset, sizeof(struct pdinfo)); + offset += sizeof(struct pdinfo); + memcpy(maxpass, buf + offset, sizeof(uint32)); + + return result; +} + +/* + * Update the host's in-memory copy of the VTOC and pdinfo + */ +static void ctc_update_vtoc(uint32 maxpass, + uint32 vtoc_addr, uint32 pdinfo_addr, + struct vtoc *vtoc, struct pdinfo *pdinfo) +{ + uint32 i; + + pwrite_w(vtoc_addr + 12, VTOC_VALID, BUS_PER); + pwrite_w(vtoc_addr + 16, vtoc->version, BUS_PER); + for (i = 0; i < 8; i++) { + pwrite_b(vtoc_addr + 20 + i, (uint8)(vtoc->volume[i]), BUS_PER); + } + pwrite_h(vtoc_addr + 28, vtoc->sectorsz, BUS_PER); + pwrite_h(vtoc_addr + 30, vtoc->nparts, BUS_PER); + + for (i = 0; i < VTOC_PART; i++) { + pwrite_h(vtoc_addr + 72 + (i * 12) + 0, vtoc_table[i].id, BUS_PER); + pwrite_h(vtoc_addr + 72 + (i * 12) + 2, vtoc_table[i].flag, BUS_PER); + pwrite_w(vtoc_addr + 72 + (i * 12) + 4, vtoc_table[i].sstart, BUS_PER); + pwrite_w(vtoc_addr + 72 + (i * 12) + 8, vtoc_table[i].ssize, BUS_PER); + } + + /* Write the pdinfo */ + pwrite_w(pdinfo_addr, pdinfo->driveid, BUS_PER); + pwrite_w(pdinfo_addr + 4, pdinfo->sanity, BUS_PER); + pwrite_w(pdinfo_addr + 8, pdinfo->version, BUS_PER); + for (i = 0; i < 12; i++) { + pwrite_b(pdinfo_addr + 12 + i, pdinfo->serial[i], BUS_PER); + } + pwrite_w(pdinfo_addr + 24, pdinfo->cyls, BUS_PER); + pwrite_w(pdinfo_addr + 28, pdinfo->tracks, BUS_PER); + pwrite_w(pdinfo_addr + 32, pdinfo->sectors, BUS_PER); + pwrite_w(pdinfo_addr + 36, pdinfo->bytes, BUS_PER); + pwrite_w(pdinfo_addr + 40, pdinfo->logicalst, BUS_PER); + pwrite_w(pdinfo_addr + 44, pdinfo->errlogst, BUS_PER); + pwrite_w(pdinfo_addr + 48, pdinfo->errlogsz, BUS_PER); + pwrite_w(pdinfo_addr + 52, pdinfo->mfgst, BUS_PER); + pwrite_w(pdinfo_addr + 56, pdinfo->mfgsz, BUS_PER); + pwrite_w(pdinfo_addr + 60, pdinfo->defectst, BUS_PER); + pwrite_w(pdinfo_addr + 64, pdinfo->defectsz, BUS_PER); + pwrite_w(pdinfo_addr + 68, pdinfo->relno, BUS_PER); + pwrite_w(pdinfo_addr + 72, pdinfo->relst, BUS_PER); + pwrite_w(pdinfo_addr + 76, pdinfo->relsz, BUS_PER); + pwrite_w(pdinfo_addr + 80, pdinfo->relnext, BUS_PER); + + /* Now something horrible happens. We sneak RIGHT off the end of + * the pdinfo struct and reach deep into the pdsector struct that + * it is part of. */ + + pwrite_w(pdinfo_addr + 128, maxpass, BUS_PER); +} + +/* + * Handle a single request taken from the Request Queue. + * + * Note that the driver stuffs parameters into various different + * fields of the Request Queue entry seemingly at random, and also + * expects response parameters to be placed in specific fields of the + * Completion Queue entry. It can be confusing to follow. + */ +static void ctc_cmd(uint8 slot, + cio_entry *rqe, uint8 *rapp_data, + cio_entry *cqe, uint8 *capp_data) +{ + uint32 vtoc_addr, pdinfo_addr, ctjob_addr; + uint32 maxpass, blkno, delay, last_byte; + uint8 dev, c; + uint8 sec_buf[VTOC_SECSZ]; + int32 b, i, j; + int32 block_count, read_bytes, remainder, dest; + t_seccnt secrw = 0; + struct vtoc vtoc = {{0}}; + struct pdinfo pdinfo = {0}; + t_stat result; + + uint32 lba; /* Logical Block Address */ + + maxpass = 0; + dev = rqe->subdevice & 1; /* Tape or Floppy device */ + + capp_data[7] = rqe->opcode; + cqe->subdevice = rqe->subdevice; + + switch(rqe->opcode) { + case CIO_DLM: + for (i = 0; i < rqe->byte_count; i++) { + ctc_crc = cio_crc32_shift(ctc_crc, pread_b(rqe->address + i, BUS_PER)); + } + sim_debug(TRACE_DBG, &ctc_dev, + "[ctc_cmd] CIO Download Memory: bytecnt=%04x " + "addr=%08x return_addr=%08x subdev=%02x (CRC=%08x)\n", + rqe->byte_count, rqe->address, + rqe->address, rqe->subdevice, ctc_crc); + delay = DELAY_DLM; + cqe->address = rqe->address + rqe->byte_count; + cqe->opcode = CTC_SUCCESS; + break; + case CIO_ULM: + sim_debug(TRACE_DBG, &ctc_dev, + "[ctc_cmd] CIO Upload Memory: return opcode 0\n"); + delay = DELAY_ULM; + cqe->opcode = CTC_SUCCESS; + break; + case CIO_FCF: + sim_debug(TRACE_DBG, &ctc_dev, + "[ctc_cmd] CIO Force Function Call (CRC=%08x)\n", ctc_crc); + delay = DELAY_FCF; + + /* If the currently running program is a diagnostic program, + * we are expected to write results into memory at address + * 0x200f000 */ + if (ctc_crc == CTC_DIAG_CRC1 || + ctc_crc == CTC_DIAG_CRC2 || + ctc_crc == CTC_DIAG_CRC3) { + pwrite_h(0x200f000, 0x1, BUS_PER); /* Test success */ + pwrite_h(0x200f002, 0x0, BUS_PER); /* Test Number */ + pwrite_h(0x200f004, 0x0, BUS_PER); /* Actual */ + pwrite_h(0x200f006, 0x0, BUS_PER); /* Expected */ + pwrite_b(0x200f008, 0x1, BUS_PER); /* Success flag again */ + } + + /* An interesting (?) side-effect of FORCE FUNCTION CALL is + * that it resets the card state such that a new SYSGEN is + * required in order for new commands to work. In fact, an + * INT0/INT1 combo _without_ a RESET can sysgen the board. So, + * we reset the command bits here. */ + cio[slot].sysgen_s = 0; + cqe->opcode = CTC_SUCCESS; + break; + case CIO_DOS: + sim_debug(TRACE_DBG, &ctc_dev, + "[ctc_cmd] CIO_DOS (%d)\n", + rqe->opcode); + delay = DELAY_DOS; + cqe->opcode = CTC_SUCCESS; + break; + case CIO_DSD: + sim_debug(TRACE_DBG, &ctc_dev, + "[ctc_cmd] CTC_DSD (%d)\n", + rqe->opcode); + delay = DELAY_DSD; + /* Write subdevice information to the host. */ + pwrite_h(rqe->address, CTC_NUM_SD, BUS_PER); + pwrite_h(rqe->address + 2, CTC_SD_FT25, BUS_PER); + pwrite_h(rqe->address + 4, CTC_SD_FD5, BUS_PER); + cqe->opcode = CTC_SUCCESS; + break; + case CTC_FORMAT: + sim_debug(TRACE_DBG, &ctc_dev, + "[ctc_cmd] CTC_FORMAT (%d)\n", + rqe->opcode); + + delay = DELAY_FMT; + + /* FORMAT stores the job pointer in the jio_start field of the + * completion queue entry's application data */ + capp_data[0] = rapp_data[4]; + capp_data[1] = rapp_data[5]; + capp_data[2] = rapp_data[6]; + capp_data[3] = rapp_data[7]; + + if (dev == XMF_DEV) { + cqe->opcode = CTC_NOTREADY; + break; + } + + if ((ctc_unit.flags & UNIT_ATT) == 0) { + cqe->opcode = CTC_NOMEDIA; + break; + } + + if (ctc_unit.flags & UNIT_WPRT) { + cqe->opcode = CTC_RDONLY; + break; + } + + /* Write a valid VTOC and pdinfo to the tape */ + + vtoc.sanity = VTOC_VALID; + vtoc.version = 1; + strcpy((char *)vtoc.volume, "ctctape"); + vtoc.sectorsz = PD_BYTES; + vtoc.nparts = VTOC_PART; + + pdinfo.driveid = PD_DRIVEID; + pdinfo.sanity = PD_VALID; + pdinfo.version = 0; + memset(pdinfo.serial, 0, 12); + pdinfo.cyls = PD_CYLS; + pdinfo.tracks = PD_TRACKS; + pdinfo.sectors = PD_SECTORS; + pdinfo.bytes = PD_BYTES; + pdinfo.logicalst = PD_LOGICALST; + pdinfo.errlogst = 0xffffffff; + pdinfo.errlogsz = 0xffffffff; + pdinfo.mfgst = 0xffffffff; + pdinfo.mfgsz = 0xffffffff; + pdinfo.defectst = 0xffffffff; + pdinfo.defectsz = 0xffffffff; + pdinfo.relno = 0xffffffff; + pdinfo.relst = 0xffffffff; + pdinfo.relsz = 0xffffffff; + pdinfo.relnext = 0xffffffff; + + maxpass = rqe->address; + + ctc_write_vtoc(&vtoc, &pdinfo, maxpass); + + cqe->opcode = CTC_SUCCESS; + + /* The address field holds the total amount of time (in 25ms + * chunks) used during this format session. We'll fudge and + * say 1 minute for formatting. */ + cqe->address = 2400; + + break; + case CTC_OPEN: + sim_debug(TRACE_DBG, &ctc_dev, + "[ctc_cmd] CTC_OPEN (%d)\n", + rqe->opcode); + + delay = DELAY_OPEN; + + ctc_state[dev].time = 0; /* Opening always resets session time to 0 */ + ctc_state[dev].bytnum = 0; + + vtoc_addr = rqe->address; + pdinfo_addr = ATOW(rapp_data, 4); + ctjob_addr = ATOW(rapp_data, 8); + + /* For OPEN commands, the Completion Queue Entry's address + * field contains a pointer to the ctjobstat. */ + cqe->address = ctjob_addr; + + if (dev == XMF_DEV) { + cqe->opcode = CTC_NOTREADY; + break; + } + + if ((ctc_unit.flags & UNIT_ATT) == 0) { + cqe->opcode = CTC_NOMEDIA; + break; + } + + /* Load the vtoc, pdinfo, and maxpass from the tape */ + ctc_read_vtoc(&vtoc, &pdinfo, &maxpass); + + ctc_update_vtoc(maxpass, vtoc_addr, pdinfo_addr, &vtoc, &pdinfo); + cqe->opcode = CTC_SUCCESS; + break; + case CTC_CLOSE: + sim_debug(TRACE_DBG, &ctc_dev, + "[ctc_cmd] CTC_CLOSE (%d)\n", + rqe->opcode); + + delay = DELAY_CLOSE; + + /* The Request Queue Entry's address field contains the + * ctjobstat pointer, which the driver will want to find in + * the first word of our Completion Queue Entry's application + * data. This must be in place whether we have media attached + * or not. */ + capp_data[3] = rqe->address & 0xff; + capp_data[2] = (rqe->address & 0xff00) >> 8; + capp_data[1] = (rqe->address & 0xff0000) >> 16; + capp_data[0] = (rqe->address & 0xff000000) >> 24; + + /* The Completion Queue Entry's address field holds the total + * tape time used in this session. */ + cqe->address = ctc_state[dev].time; + cqe->opcode = CTC_SUCCESS; + + break; + case CTC_WRITE: + case CTC_VWRITE: + sim_debug(TRACE_DBG, &ctc_dev, + "[ctc_cmd] CTC_WRITE or CTC_VWRITE (%d)\n", + rqe->opcode); + + delay = DELAY_RW; + + cqe->byte_count = rqe->byte_count; + cqe->subdevice = rqe->subdevice; + cqe->address = ATOW(rapp_data, 4); + + if (dev == XMF_DEV) { + cqe->opcode = CTC_NOTREADY; + break; + } + + if ((ctc_unit.flags & UNIT_ATT) == 0) { + cqe->opcode = CTC_NOMEDIA; + break; + } + + if (ctc_unit.flags & UNIT_WPRT) { + cqe->opcode = CTC_RDONLY; + break; + } + + blkno = ATOW(rapp_data, 0); + + for (b = 0; b < rqe->byte_count / VTOC_SECSZ; b++) { + ctc_state[dev].time += 10; + for (j = 0; j < VTOC_SECSZ; j++) { + /* Fill the buffer */ + sec_buf[j] = pread_b(rqe->address + (b * VTOC_SECSZ) + j, BUS_PER); + } + lba = blkno + b; + result = sim_disk_wrsect(&ctc_unit, lba, sec_buf, &secrw, 1); + if (result == SCPE_OK) { + sim_debug(TRACE_DBG, &ctc_dev, + "[ctc_cmd] ... CTC_WRITE: 512 bytes at block %d (0x%x)\n", + lba, lba); + cqe->opcode = CTC_SUCCESS; + } else { + cqe->opcode = CTC_RWERROR; + break; + } + } + + break; + case CTC_READ: + sim_debug(TRACE_DBG, &ctc_dev, + "[ctc_cmd] CTC_READ (%d)\n", + rqe->opcode); + delay = DELAY_RW; + cqe->byte_count = rqe->byte_count; + cqe->subdevice = rqe->subdevice; + cqe->address = ATOW(rapp_data, 4); + dest = rqe->address; + + if (dev == XMF_DEV) { + cqe->opcode = CTC_NOTREADY; + break; + } + + if ((ctc_unit.flags & UNIT_ATT) == 0) { + cqe->opcode = CTC_NOMEDIA; + break; + } + + /* + * This read routine supports both streaming and block + * oriented modes. + * + * Read requests from the host give a block number, and a + * number of bytes to read. In streaming mode, however, there + * is no requirement that the number of bytes to read has to + * be block-aligned, so we must support reading an arbitrary + * number of bytes from the tape stream and remembering the + * current position in the byte stream. + * + */ + + /* The block number to begin reading from is supplied in the + * request queue entry's APP_DATA field. */ + blkno = ATOW(rapp_data, 0); + + /* Since we may start reading from the data stream at an + * arbitrary location, we compute the offset of the last byte + * to be read, and use that to figure out how many bytes will + * be left over to read from an "extra" block */ + last_byte = ctc_state[dev].bytnum + rqe->byte_count; + remainder = last_byte % VTOC_SECSZ; + + /* The number of blocks we have to read in total is computed + * by looking at the byte count, PLUS any remainder that will + * be left after crossing a block boundary */ + block_count = rqe->byte_count / VTOC_SECSZ; + if (((rqe->byte_count % VTOC_SECSZ) > 0 || remainder > 0)) { + block_count++; + } + + /* Now step over each block, and start reading from the + * necessary location. */ + for (b = 0; b < block_count; b++) { + uint32 start_byte; + /* Add some read time to the read time counter */ + ctc_state[dev].time += 10; + start_byte = ctc_state[dev].bytnum % VTOC_SECSZ; + lba = blkno + b; + result = sim_disk_rdsect(&ctc_unit, lba, sec_buf, &secrw, 1); + if (result == SCPE_OK) { + /* If this is the last "extra" block, we will only + * read the remainder of bytes from it. Otherwise, we + * need to consume the whole block. */ + if (b == (block_count - 1) && remainder > 0) { + read_bytes = remainder; + } else { + read_bytes = VTOC_SECSZ - start_byte; + } + for (j = 0; j < read_bytes; j++) { + uint32 offset; + /* Drain the buffer */ + if (b == 0 && (j + start_byte) < VTOC_SECSZ) { + /* This is a partial read of the first block, + * continuing to read from a previous partial + * block read. */ + offset = j + start_byte; + } else { + offset = j; + } + c = sec_buf[offset]; + pwrite_b(dest++, c, BUS_PER); + ctc_state[dev].bytnum++; + } + } else { + sim_debug(TRACE_DBG, &ctc_dev, + "[ctc_cmd] Error reading sector at address %d. Giving up\n", lba); + break; + } + } + + if (result == SCPE_OK) { + cqe->opcode = CTC_SUCCESS; + } else { + cqe->opcode = CTC_RWERROR; + } + + break; + case CTC_CONFIG: + sim_debug(TRACE_DBG, &ctc_dev, + "[ctc_cmd] CTC_CONFIG (%d)\n", + rqe->opcode); + delay = DELAY_CONFIG; + cqe->opcode = CTC_SUCCESS; + break; + default: + sim_debug(TRACE_DBG, &ctc_dev, + "[ctc_cmd] UNHANDLED OP: %d (0x%02x)\n", + rqe->opcode, rqe->opcode); + delay = DELAY_UNK; + cqe->opcode = CTC_HWERROR; + break; + } + + cio_irq(slot, rqe->subdevice, delay); +} + +void ctc_sysgen(uint8 slot) +{ + cio_entry cqe = {0}; + uint8 rapp_data[12] = {0}; + + ctc_crc = 0; + + sim_debug(TRACE_DBG, &ctc_dev, "[ctc_sysgen] Handling Sysgen.\n"); + sim_debug(TRACE_DBG, &ctc_dev, "[ctc_sysgen] rqp=%08x\n", cio[slot].rqp); + sim_debug(TRACE_DBG, &ctc_dev, "[ctc_sysgen] cqp=%08x\n", cio[slot].cqp); + sim_debug(TRACE_DBG, &ctc_dev, "[ctc_sysgen] rqs=%d\n", cio[slot].rqs); + sim_debug(TRACE_DBG, &ctc_dev, "[ctc_sysgen] cqs=%d\n", cio[slot].cqs); + sim_debug(TRACE_DBG, &ctc_dev, "[ctc_sysgen] ivec=%d\n", cio[slot].ivec); + sim_debug(TRACE_DBG, &ctc_dev, "[ctc_sysgen] no_rque=%d\n", cio[slot].no_rque); + + cqe.opcode = 3; /* Sysgen success! */ + + cio_cexpress(slot, CTQCESIZE, &cqe, rapp_data); + cio_cqueue(slot, CIO_STAT, CTQCESIZE, &cqe, rapp_data); + + int_slot = slot; + sim_activate_after(&ctc_unit, DELAY_SYSGEN); +} + +void ctc_express(uint8 slot) +{ + cio_entry rqe, cqe; + uint8 rapp_data[12] = {0}; + uint8 capp_data[8] = {0}; + + sim_debug(TRACE_DBG, &ctc_dev, "[ctc_express] Handling Express Request\n"); + + cio_rexpress(slot, CTQRESIZE, &rqe, rapp_data); + ctc_cmd(slot, &rqe, rapp_data, &cqe, capp_data); + + cio_cexpress(slot, CTQCESIZE, &cqe, capp_data); +} + +void ctc_full(uint8 slot) +{ + cio_entry rqe, cqe; + uint8 rapp_data[12] = {0}; + uint8 capp_data[8] = {0}; + + sim_debug(TRACE_DBG, &ctc_dev, "[ctc_full] Handling Full Request\n"); + + while (cio_cqueue_avail(slot, CTQCESIZE) && + cio_rqueue(slot, TAPE_DEV, CTQRESIZE, &rqe, rapp_data) == SCPE_OK) { + ctc_cmd(slot, &rqe, rapp_data, &cqe, capp_data); + } + cio_cqueue(slot, CIO_STAT, CTQCESIZE, &cqe, capp_data); +} + +t_stat ctc_reset(DEVICE *dptr) +{ + uint8 slot; + t_stat r; + + ctc_crc = 0; + + memset(ctc_state, 0, 2 * sizeof(CTC_STATE)); + + if (dptr->flags & DEV_DIS) { + cio_remove_all(CTC_ID); + ctc_conf = FALSE; + return SCPE_OK; + } + + if (!ctc_conf) { + r = cio_install(CTC_ID, "CTC", CTC_IPL, + &ctc_express, &ctc_full, &ctc_sysgen, NULL, + &slot); + if (r != SCPE_OK) { + return r; + } + ctc_conf = TRUE; + } + + return SCPE_OK; +} + +t_stat ctc_svc(UNIT *uptr) +{ + uint16 lp, ulp; + + if (cio[int_slot].ivec > 0) { + sim_debug(TRACE_DBG, &ctc_dev, + "[cio_svc] IRQ for board %d (VEC=%d)\n", + int_slot, cio[int_slot].ivec); + CIO_SET_INT(int_slot); + } + + /* Check to see if the completion queue has more work in it. We + * need to schedule an interrupt for each job if we've fallen + * behind (this should be rare) */ + lp = cio_c_lp(int_slot, CTQCESIZE); + ulp = cio_c_ulp(int_slot, CTQCESIZE); + + if ((ulp + CTQCESIZE) % (CTQCESIZE * cio[int_slot].cqs) != lp) { + sim_debug(TRACE_DBG, &ctc_dev, + "[cio_svc] Completion queue has fallen behind (lp=%04x ulp=%04x)\n", + lp, ulp); + /* Schedule a catch-up interrupt */ + sim_activate_abs(&ctc_unit, DELAY_CATCHUP); + } + + return SCPE_OK; +} + +t_stat ctc_attach(UNIT *uptr, CONST char *cptr) +{ + return sim_disk_attach(uptr, cptr, VTOC_SECSZ, 1, TRUE, 0, "CIPHER23", 0, 0); +} + +t_stat ctc_detach(UNIT *uptr) +{ + return sim_disk_detach(uptr); +} diff --git a/3B2/3b2_ctc.h b/3B2/3b2_ctc.h index 67f0b884..8ba64510 100644 --- a/3B2/3b2_ctc.h +++ b/3B2/3b2_ctc.h @@ -1,153 +1,153 @@ -/* 3b2_ctc.h: AT&T 3B2 Model 400 "CTC" feature card - - Copyright (c) 2018, Seth J. Morabito - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - - Except as contained in this notice, the name of the author shall - not be used in advertising or otherwise to promote the sale, use or - other dealings in this Software without prior written authorization - from the author. -*/ - -/* - * CTC is an intelligent feature card for the 3B2 that supports a - * Cipher "FloppyTape(tm)" 525 drive that can read and write 23MB - * DC600A cartridges. - * - * The CTC card is based on the Common I/O (CIO) platform. - * - * Notes: - * ------ - * - * The Cipher FloppyTape is an odd beast. Although it's a tape drive, - * it is controlled by a floppy controller. It is divided into virtual - * sectors that can be addressed by Cylinder / Track / Sector. - * Stepping and head select pulses dictate where on the tape to read - * from or write to. Moreover, System V maps a filesystem onto the - * tape, and a properly formatted tape drive will have a VTOC on - * partition 0. - * - */ - -#ifndef _3B2_CTC_H_ -#define _3B2_CTC_H_ - -#include "3b2_defs.h" - -#define CTC_ID 0x0005 -#define CTC_IPL 12 -#define CTC_VERSION 1 - -/* Request Opcodes */ -#define CTC_CONFIG 30 -#define CTC_CLOSE 31 -#define CTC_FORMAT 32 -#define CTC_OPEN 33 -#define CTC_READ 34 -#define CTC_WRITE 35 -#define CTC_VWRITE 36 - -/* Completion Opcodes */ -#define CTC_SUCCESS 0 -#define CTC_HWERROR 32 -#define CTC_RDONLY 33 -#define CTC_NOTREADY 36 -#define CTC_RWERROR 37 -#define CTC_NOMEDIA 42 - -/* VTOC values */ -#define VTOC_VERSION 1 -#define VTOC_SECSZ 512 -#define VTOC_PART 16 /* Number of "partitions" on tape */ -#define VTOC_VALID 0x600DDEEE /* Magic number for valid VTOC */ - -#define CTC_NUM_SD 2 -#define CTC_SD_FT25 4 -#define CTC_SD_FD5 1 - -/* Physical Device Info (pdinfo) values */ -#define PD_VALID 0xCA5E600D /* Magic number for valid PDINFO */ -#define PD_DRIVEID 5 -#define PD_VERSION 0 -#define PD_CYLS 6 -#define PD_TRACKS 245 -#define PD_SECTORS 31 -#define PD_BYTES 512 -#define PD_LOGICALST 29 - -#define CTC_CAPACITY (PD_CYLS * PD_TRACKS * PD_SECTORS) /* In blocks */ - -struct partition { - uint16 id; /* Partition ID */ - uint16 flag; /* Permission Flags */ - uint32 sstart; /* Starting Sector */ - uint32 ssize; /* Size in Sectors */ -}; - -struct vtoc { - uint32 bootinfo[3]; /* n/a */ - uint32 sanity; /* magic number */ - uint32 version; /* layout version */ - uint8 volume[8]; /* volume name */ - uint16 sectorsz; /* sector size in bytes */ - uint16 nparts; /* number of partitions */ - uint32 reserved[10]; /* free space */ - struct partition part[VTOC_PART]; /* partition headers */ - uint32 timestamp[VTOC_PART]; /* partition timestamp */ -}; - -struct pdinfo { - uint32 driveid; /* identifies the device type */ - uint32 sanity; /* verifies device sanity */ - uint32 version; /* version number */ - uint8 serial[12]; /* serial number of the device */ - uint32 cyls; /* number of cylinders per drive */ - uint32 tracks; /* number tracks per cylinder */ - uint32 sectors; /* number sectors per track */ - uint32 bytes; /* number of bytes per sector */ - uint32 logicalst; /* sector address of logical sector 0 */ - uint32 errlogst; /* sector address of error log area */ - uint32 errlogsz; /* size in bytes of error log area */ - uint32 mfgst; /* sector address of mfg. defect info */ - uint32 mfgsz; /* size in bytes of mfg. defect info */ - uint32 defectst; /* sector address of the defect map */ - uint32 defectsz; /* size in bytes of defect map */ - uint32 relno; /* number of relocation areas */ - uint32 relst; /* sector address of relocation area */ - uint32 relsz; /* size in sectors of relocation area */ - uint32 relnext; /* address of next avail reloc sector */ -}; - -typedef struct { - uint32 time; /* Time used during a tape session (in 25ms chunks) */ - uint32 bytnum; /* Byte number, for streaming mode */ -} CTC_STATE; - -t_stat ctc_reset(DEVICE *dptr); -t_stat ctc_svc(UNIT *uptr); -t_stat ctc_attach(UNIT *uptr, CONST char *cptr); -t_stat ctc_detach(UNIT *uptr); -void ctc_sysgen(uint8 cid); -void ctc_express(uint8 cid); -void ctc_full(uint8 cid); - -#endif /* _3B2_CTC_H_ */ +/* 3b2_ctc.h: CM195H 23MB Cartridge Tape Controller CIO Card + + Copyright (c) 2018-2022, Seth J. Morabito + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + Except as contained in this notice, the name of the author shall + not be used in advertising or otherwise to promote the sale, use or + other dealings in this Software without prior written authorization + from the author. +*/ + +/* + * CTC is an intelligent feature card for the 3B2 that supports a + * Cipher "FloppyTape(tm)" 525 drive that can read and write 23MB + * DC600A cartridges. + * + * The CTC card is based on the Common I/O (CIO) platform. + * + * Notes: + * ------ + * + * The Cipher FloppyTape is an odd beast. Although it's a tape drive, + * it is controlled by a floppy controller. It is divided into virtual + * sectors that can be addressed by Cylinder / Track / Sector. + * Stepping and head select pulses dictate where on the tape to read + * from or write to. Moreover, System V maps a filesystem onto the + * tape, and a properly formatted tape drive will have a VTOC on + * partition 0. + * + */ + +#ifndef _3B2_CTC_H_ +#define _3B2_CTC_H_ + +#include "3b2_defs.h" + +#define CTC_ID 0x0005 +#define CTC_IPL 12 +#define CTC_VERSION 1 + +/* Request Opcodes */ +#define CTC_CONFIG 30 +#define CTC_CLOSE 31 +#define CTC_FORMAT 32 +#define CTC_OPEN 33 +#define CTC_READ 34 +#define CTC_WRITE 35 +#define CTC_VWRITE 36 + +/* Completion Opcodes */ +#define CTC_SUCCESS 0 +#define CTC_HWERROR 32 +#define CTC_RDONLY 33 +#define CTC_NOTREADY 36 +#define CTC_RWERROR 37 +#define CTC_NOMEDIA 42 + +/* VTOC values */ +#define VTOC_VERSION 1 +#define VTOC_SECSZ 512 +#define VTOC_PART 16 /* Number of "partitions" on tape */ +#define VTOC_VALID 0x600DDEEE /* Magic number for valid VTOC */ + +#define CTC_NUM_SD 2 +#define CTC_SD_FT25 4 +#define CTC_SD_FD5 1 + +/* Physical Device Info (pdinfo) values */ +#define PD_VALID 0xCA5E600D /* Magic number for valid PDINFO */ +#define PD_DRIVEID 5 +#define PD_VERSION 0 +#define PD_CYLS 6 +#define PD_TRACKS 245 +#define PD_SECTORS 31 +#define PD_BYTES 512 +#define PD_LOGICALST 29 + +#define CTC_CAPACITY (PD_CYLS * PD_TRACKS * PD_SECTORS) /* In blocks */ + +struct partition { + uint16 id; /* Partition ID */ + uint16 flag; /* Permission Flags */ + uint32 sstart; /* Starting Sector */ + uint32 ssize; /* Size in Sectors */ +}; + +struct vtoc { + uint32 bootinfo[3]; /* n/a */ + uint32 sanity; /* magic number */ + uint32 version; /* layout version */ + uint8 volume[8]; /* volume name */ + uint16 sectorsz; /* sector size in bytes */ + uint16 nparts; /* number of partitions */ + uint32 reserved[10]; /* free space */ + struct partition part[VTOC_PART]; /* partition headers */ + uint32 timestamp[VTOC_PART]; /* partition timestamp */ +}; + +struct pdinfo { + uint32 driveid; /* identifies the device type */ + uint32 sanity; /* verifies device sanity */ + uint32 version; /* version number */ + uint8 serial[12]; /* serial number of the device */ + uint32 cyls; /* number of cylinders per drive */ + uint32 tracks; /* number tracks per cylinder */ + uint32 sectors; /* number sectors per track */ + uint32 bytes; /* number of bytes per sector */ + uint32 logicalst; /* sector address of logical sector 0 */ + uint32 errlogst; /* sector address of error log area */ + uint32 errlogsz; /* size in bytes of error log area */ + uint32 mfgst; /* sector address of mfg. defect info */ + uint32 mfgsz; /* size in bytes of mfg. defect info */ + uint32 defectst; /* sector address of the defect map */ + uint32 defectsz; /* size in bytes of defect map */ + uint32 relno; /* number of relocation areas */ + uint32 relst; /* sector address of relocation area */ + uint32 relsz; /* size in sectors of relocation area */ + uint32 relnext; /* address of next avail reloc sector */ +}; + +typedef struct { + uint32 time; /* Time used during a tape session (in 25ms chunks) */ + uint32 bytnum; /* Byte number, for streaming mode */ +} CTC_STATE; + +t_stat ctc_reset(DEVICE *dptr); +t_stat ctc_svc(UNIT *uptr); +t_stat ctc_attach(UNIT *uptr, CONST char *cptr); +t_stat ctc_detach(UNIT *uptr); +void ctc_sysgen(uint8 slot); +void ctc_express(uint8 slot); +void ctc_full(uint8 slot); + +#endif /* _3B2_CTC_H_ */ diff --git a/3B2/3b2_defs.h b/3B2/3b2_defs.h index 9358e4bf..eca4d7f3 100644 --- a/3B2/3b2_defs.h +++ b/3B2/3b2_defs.h @@ -1,164 +1,166 @@ -/* 3b2_defs.h: AT&T 3B2 Shared Simulator Definitions - - Copyright (c) 2017, Seth J. Morabito - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - - Except as contained in this notice, the name of the author shall - not be used in advertising or otherwise to promote the sale, use or - other dealings in this Software without prior written authorization - from the author. -*/ - -#ifndef _3B2_DEFS_H_ -#define _3B2_DEFS_H_ - -#include - -#include "sim_defs.h" - -#if defined(REV3) -#include "3b2_rev3_defs.h" -#else -#include "3b2_rev2_defs.h" -#endif - -#ifndef FALSE -#define FALSE 0 -#endif -#ifndef TRUE -#define TRUE 1 -#endif - -#if defined(__GNUC__) -#define noret void __attribute__((noreturn)) -#else -#define noret void -#endif - -#ifndef MAX -#define MAX(x, y) ((x) > (y) ? (x) : (y)) -#endif -#ifndef MIN -#define MIN(x, y) ((x) < (y) ? (x) : (y)) -#endif -#ifndef UNUSED -#define UNUSED(x) ((void)((x))) -#endif - -#define ATOW(arr, i) \ - ((uint32)(arr)[i + 3] + ((uint32)(arr)[i + 2] << 8) + \ - ((uint32)(arr)[i + 1] << 16) + ((uint32)(arr)[i] << 24)) - -#define ATOH(arr, i) ((uint32)(arr)[i + 1] + ((uint32)(arr)[i] << 8)) - -#define CSRBIT(bit, sc) \ - { \ - if (sc) { \ - csr_data |= (bit); \ - } else { \ - csr_data &= ~(bit); \ - } \ - } - -#define PCHAR(c) (((char) (c) >= 0x20 && (char) (c) < 0x7f) ? (char) (c) : '.') - -#define UNIT_V_EXBRK (UNIT_V_UF + 0) -#define UNIT_V_OPBRK (UNIT_V_UF + 1) -#define UNIT_EXBRK (1u << UNIT_V_EXBRK) -#define UNIT_OPBRK (1u << UNIT_V_OPBRK) - -#define EX_V_FLAG 1 << 21 - -#define PHYS_MEM_BASE 0x2000000 - -#define MSIZ_512K 0x80000 -#define MSIZ_1M 0x100000 -#define MSIZ_2M 0x200000 -#define MSIZ_4M 0x400000 -#define MSIZ_8M 0x800000 -#define MSIZ_16M 0x1000000 -#define MSIZ_32M 0x2000000 -#define MSIZ_64M 0x4000000 - -/* Simulator stop codes */ -#define STOP_RSRV 1 -#define STOP_IBKPT 2 /* Breakpoint encountered */ -#define STOP_OPCODE 3 /* Invalid opcode */ -#define STOP_IRQ 4 /* Interrupt */ -#define STOP_EX 5 /* Exception */ -#define STOP_ESTK 6 /* Exception stack too deep */ -#define STOP_MMU 7 /* Unimplemented MMU Feature */ -#define STOP_POWER 8 /* System power-off */ -#define STOP_LOOP 9 /* Infinite loop stop */ -#define STOP_ERR 10 /* Other error */ - -/* Debug flags */ -#define READ_MSG 0x0001 -#define WRITE_MSG 0x0002 -#define DECODE_MSG 0x0004 -#define EXECUTE_MSG 0x0008 -#define INIT_MSG 0x0010 -#define IRQ_MSG 0x0020 -#define IO_DBG 0x0040 -#define CIO_DBG 0x0080 -#define TRACE_DBG 0x0100 -#define CALL_DBG 0x0200 -#define PKT_DBG 0x0400 -#define ERR_MSG 0x0800 -#define CACHE_DBG 0x1000 -#define DECODE_DBG 0x2000 - -#define TIMER_SANITY 0 -#define TIMER_INTERVAL 1 -#define TIMER_BUS 2 - -/* Timer */ -#define TMR_CLK 0 /* The clock responsible for IPL 15 interrupts */ -#define TPS_CLK 100 /* 100 ticks per second */ - - -/* Global symbols */ - -extern DEBTAB sys_deb_tab[]; -extern DEVICE contty_dev; -extern DEVICE cpu_dev; -extern DEVICE csr_dev; -extern DEVICE ctc_dev; -extern DEVICE dmac_dev; -extern DEVICE id_dev; -extern DEVICE if_dev; -extern DEVICE iu_timer_dev; -extern DEVICE mau_dev; -extern DEVICE mmu_dev; -extern DEVICE ni_dev; -extern DEVICE nvram_dev; -extern DEVICE ports_dev; -extern DEVICE timer_dev; -extern DEVICE tod_dev; -extern DEVICE tti_dev; -extern DEVICE tto_dev; -#if defined(REV3) -extern DEVICE flt_dev; -extern DEVICE ha_dev; -#endif - -#endif +/* 3b2_defs.h: AT&T 3B2 Shared Simulator Definitions + + Copyright (c) 2017-2022, Seth J. Morabito + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + Except as contained in this notice, the name of the author shall + not be used in advertising or otherwise to promote the sale, use or + other dealings in this Software without prior written authorization + from the author. +*/ + +#ifndef _3B2_DEFS_H_ +#define _3B2_DEFS_H_ + +#include + +#include "sim_defs.h" + +#if defined(REV3) +#include "3b2_rev3_defs.h" +#else +#include "3b2_rev2_defs.h" +#endif + +#ifndef FALSE +#define FALSE 0 +#endif +#ifndef TRUE +#define TRUE 1 +#endif + +#if defined(__GNUC__) +#define noret void __attribute__((noreturn)) +#else +#define noret void +#endif + +#ifndef MAX +#define MAX(x, y) ((x) > (y) ? (x) : (y)) +#endif +#ifndef MIN +#define MIN(x, y) ((x) < (y) ? (x) : (y)) +#endif +#ifndef UNUSED +#define UNUSED(x) ((void)((x))) +#endif + +#define ATOW(arr, i) \ + ((uint32)(arr)[i + 3] + ((uint32)(arr)[i + 2] << 8) + \ + ((uint32)(arr)[i + 1] << 16) + ((uint32)(arr)[i] << 24)) + +#define ATOH(arr, i) ((uint32)(arr)[i + 1] + ((uint32)(arr)[i] << 8)) + +#define CSRBIT(bit, sc) \ + { \ + if (sc) { \ + csr_data |= (bit); \ + } else { \ + csr_data &= ~(bit); \ + } \ + } + +#define PCHAR(c) (((char) (c) >= 0x20 && (char) (c) < 0x7f) ? (char) (c) : '.') + +#define ROM_SIZE (128 * 1024) +#define POLL_WAIT 70000 + +#define UNIT_V_EXBRK (UNIT_V_UF + 0) +#define UNIT_V_OPBRK (UNIT_V_UF + 1) +#define UNIT_EXBRK (1u << UNIT_V_EXBRK) +#define UNIT_OPBRK (1u << UNIT_V_OPBRK) + +#define EX_V_FLAG 1 << 21 + +#define ROM_BASE 0 +#define PHYS_MEM_BASE 0x2000000 + +#define MSIZ_512K 0x80000 +#define MSIZ_1M 0x100000 +#define MSIZ_2M 0x200000 +#define MSIZ_4M 0x400000 +#define MSIZ_8M 0x800000 +#define MSIZ_16M 0x1000000 +#define MSIZ_32M 0x2000000 +#define MSIZ_64M 0x4000000 + +/* Simulator stop codes */ +#define STOP_RSRV 1 +#define STOP_IBKPT 2 /* Breakpoint encountered */ +#define STOP_OPCODE 3 /* Invalid opcode */ +#define STOP_IRQ 4 /* Interrupt */ +#define STOP_EX 5 /* Exception */ +#define STOP_ESTK 6 /* Exception stack too deep */ +#define STOP_MMU 7 /* Unimplemented MMU Feature */ +#define STOP_POWER 8 /* System power-off */ +#define STOP_LOOP 9 /* Infinite loop stop */ +#define STOP_ERR 10 /* Other error */ + +/* Debug flags */ +#define READ_MSG 0x0001 +#define WRITE_MSG 0x0002 +#define DECODE_MSG 0x0004 +#define EXECUTE_MSG 0x0008 +#define INIT_MSG 0x0010 +#define IRQ_MSG 0x0020 +#define IO_DBG 0x0040 +#define CIO_DBG 0x0080 +#define TRACE_DBG 0x0100 +#define CALL_DBG 0x0200 +#define PKT_DBG 0x0400 +#define ERR_MSG 0x0800 +#define CACHE_DBG 0x1000 +#define DECODE_DBG 0x2000 + +#define TIMER_SANITY 0 +#define TIMER_INTERVAL 1 +#define TIMER_BUS 2 + +/* Timers */ +#define TMR_CLK 0 /* Calibrated 100Hz timer */ + +/* Global symbols */ + +extern DEBTAB sys_deb_tab[]; +extern DEVICE contty_dev; +extern DEVICE cpu_dev; +extern DEVICE csr_dev; +extern DEVICE ctc_dev; +extern DEVICE dmac_dev; +extern DEVICE id_dev; +extern DEVICE if_dev; +extern DEVICE iu_timer_dev; +extern DEVICE mau_dev; +extern DEVICE mmu_dev; +extern DEVICE ni_dev; +extern DEVICE nvram_dev; +extern DEVICE ports_dev; +extern DEVICE timer_dev; +extern DEVICE tod_dev; +extern DEVICE tti_dev; +extern DEVICE tto_dev; +#if defined(REV3) +extern DEVICE flt_dev; +extern DEVICE ha_dev; +#endif /* defined(REV3) */ + +#endif /* _3B2_DEFS_H_ */ diff --git a/3B2/3b2_dmac.c b/3B2/3b2_dmac.c index 08273b99..5a630d4f 100644 --- a/3B2/3b2_dmac.c +++ b/3B2/3b2_dmac.c @@ -1,468 +1,481 @@ -/* 3b2_dmac.c: AT&T 3B2 DMA Controller Implementation - - Copyright (c) 2021, Seth J. Morabito - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - - Except as contained in this notice, the name of the author shall - not be used in advertising or otherwise to promote the sale, use or - other dealings in this Software without prior written authorization - from the author. -*/ - -#include "3b2_dmac.h" - -#if defined(REV2) -#include "3b2_id.h" -#endif - -#include "3b2_cpu.h" -#include "3b2_if.h" -#include "3b2_iu.h" -#include "3b2_mem.h" - -DMA_STATE dma_state; - -UNIT dmac_unit[] = { - { UDATA (NULL, 0, 0), 0, 0 }, - { UDATA (NULL, 0, 0), 0, 1 }, - { UDATA (NULL, 0, 0), 0, 2 }, - { UDATA (NULL, 0, 0), 0, 3 }, - { NULL } -}; - -REG dmac_reg[] = { - { NULL } -}; - -DEVICE dmac_dev = { - "DMAC", dmac_unit, dmac_reg, NULL, - 1, 16, 8, 4, 16, 32, - NULL, NULL, &dmac_reset, - NULL, NULL, NULL, NULL, - DEV_DEBUG, 0, sys_deb_tab -}; - -dmac_dma_handler device_dma_handlers[] = { -#if defined(REV2) - {DMA_ID_CHAN, IDBASE+ID_DATA_REG, &id_drq, dmac_generic_dma, id_after_dma}, -#endif - {DMA_IF_CHAN, IFBASE+IF_DATA_REG, &if_state.drq, dmac_generic_dma, if_after_dma}, - {DMA_IUA_CHAN, IUBASE+IUA_DATA_REG, &iu_console.drq, iu_dma_console, NULL}, - {DMA_IUB_CHAN, IUBASE+IUB_DATA_REG, &iu_contty.drq, iu_dma_contty, NULL}, - {0, 0, NULL, NULL, NULL } -}; - -uint32 dma_address(uint8 channel, uint32 offset, t_bool r) { - uint32 addr, page; - addr = (PHYS_MEM_BASE + (uint32)(dma_state.channels[channel].addr) + offset); -#if defined (REV3) - page = (uint32)dma_state.channels[channel].page; -#else - /* In Rev 2, the top bit of the page address is a R/W bit, so - we mask it here */ - page = (uint32)dma_state.channels[channel].page & 0x7f; -#endif - addr |= page << 16; - return addr; -} - -t_stat dmac_reset(DEVICE *dptr) -{ - int i; - - memset(&dma_state, 0, sizeof(dma_state)); - - for (i = 0; i < 4; i++) { - dma_state.channels[i].page = 0; - dma_state.channels[i].addr = 0; - dma_state.channels[i].wcount = 0; - dma_state.channels[i].addr_c = 0; - dma_state.channels[i].wcount_c = -1; - dma_state.channels[i].ptr = 0; - } - - return SCPE_OK; -} - -uint32 dmac_read(uint32 pa, size_t size) -{ - uint8 reg, base, data; - - base = (uint8) (pa >> 12); - reg = pa & 0xff; - - switch (base) { - case DMA_C: /* 0x48xxx */ - switch (reg) { - case 0: /* channel 0 current address reg */ - data = ((dma_state.channels[0].addr_c) >> (dma_state.bff * 8)) & 0xff; - sim_debug(READ_MSG, &dmac_dev, - "[%08x] Reading Channel 0 Addr Reg: %08x\n", - R[NUM_PC], data); - dma_state.bff ^= 1; - break; - case 1: /* channel 0 current address reg */ - data = ((dma_state.channels[0].wcount_c) >> (dma_state.bff * 8)) & 0xff; - sim_debug(READ_MSG, &dmac_dev, - "[%08x] Reading Channel 0 Addr Count Reg: %08x\n", - R[NUM_PC], data); - dma_state.bff ^= 1; - break; - case 2: /* channel 1 current address reg */ - data = ((dma_state.channels[1].addr_c) >> (dma_state.bff * 8)) & 0xff; - sim_debug(READ_MSG, &dmac_dev, - "[%08x] Reading Channel 1 Addr Reg: %08x\n", - R[NUM_PC], data); - dma_state.bff ^= 1; - break; - case 3: /* channel 1 current address reg */ - data = ((dma_state.channels[1].wcount_c) >> (dma_state.bff * 8)) & 0xff; - sim_debug(READ_MSG, &dmac_dev, - "[%08x] Reading Channel 1 Addr Count Reg: %08x\n", - R[NUM_PC], data); - dma_state.bff ^= 1; - break; - case 4: /* channel 2 current address reg */ - data = ((dma_state.channels[2].addr_c) >> (dma_state.bff * 8)) & 0xff; - sim_debug(READ_MSG, &dmac_dev, - "[%08x] Reading Channel 2 Addr Reg: %08x\n", - R[NUM_PC], data); - dma_state.bff ^= 1; - break; - case 5: /* channel 2 current address reg */ - data = ((dma_state.channels[2].wcount_c) >> (dma_state.bff * 8)) & 0xff; - sim_debug(READ_MSG, &dmac_dev, - "[%08x] Reading Channel 2 Addr Count Reg: %08x\n", - R[NUM_PC], data); - dma_state.bff ^= 1; - break; - case 6: /* channel 3 current address reg */ - data = ((dma_state.channels[3].addr_c) >> (dma_state.bff * 8)) & 0xff; - sim_debug(READ_MSG, &dmac_dev, - "[%08x] Reading Channel 3 Addr Reg: %08x\n", - R[NUM_PC], data); - dma_state.bff ^= 1; - break; - case 7: /* channel 3 current address reg */ - data = ((dma_state.channels[3].wcount_c) >> (dma_state.bff * 8)) & 0xff; - sim_debug(READ_MSG, &dmac_dev, - "[%08x] Reading Channel 3 Addr Count Reg: %08x\n", - R[NUM_PC], data); - dma_state.bff ^= 1; - break; - case 8: - data = dma_state.status; - sim_debug(READ_MSG, &dmac_dev, - "[%08x] Reading DMAC Status %08x\n", - R[NUM_PC], data); - dma_state.status = 0; - break; - default: - sim_debug(READ_MSG, &dmac_dev, - "[%08x] DMAC READ %lu B @ %08x\n", - R[NUM_PC], size, pa); - data = 0; - } - - return data; - default: - sim_debug(READ_MSG, &dmac_dev, - "[%08x] [BASE: %08x] DMAC READ %lu B @ %08x\n", - R[NUM_PC], base, size, pa); - return 0; - } -} - -/* - * Program the DMAC - */ -void dmac_program(uint8 reg, uint8 val) -{ - uint8 channel_id, i, chan_num; - dma_channel *channel; - - if (reg < 8) { - switch (reg) { - case 0: - case 1: - chan_num = 0; - break; - case 2: - case 3: - chan_num = 1; - break; - case 4: - case 5: - chan_num = 2; - break; - case 6: - case 7: - chan_num = 3; - break; - default: - chan_num = 0; - break; - } - - channel = &dma_state.channels[chan_num]; - - switch (reg & 1) { - case 0: /* Address */ - channel->addr &= ~(0xff << dma_state.bff * 8); - channel->addr |= (val & 0xff) << (dma_state.bff * 8); - channel->addr_c = channel->addr; - sim_debug(WRITE_MSG, &dmac_dev, - "Set address channel %d byte %d = %08x\n", - chan_num, dma_state.bff, channel->addr); - break; - case 1: /* Word Count */ - channel->wcount &= ~(0xff << dma_state.bff * 8); - channel->wcount |= (val & 0xff) << (dma_state.bff * 8); - channel->wcount_c = channel->wcount; - channel->ptr = 0; - sim_debug(WRITE_MSG, &dmac_dev, - "Set word count channel %d byte %d = %08x\n", - chan_num, dma_state.bff, channel->wcount); - break; - } - - /* Toggle the byte flip-flop */ - dma_state.bff ^= 1; - - /* Handled. */ - return; - } - - /* If it hasn't been handled, it must be one of the following - registers. */ - - switch (reg) { - case 8: /* Command */ - dma_state.command = val; - sim_debug(WRITE_MSG, &dmac_dev, - "[%08x] Command: val=%02x\n", - R[NUM_PC], val); - break; - case 9: /* Request */ - sim_debug(WRITE_MSG, &dmac_dev, - "[%08x] Request set: val=%02x\n", - R[NUM_PC], val); - dma_state.request = val; - break; - case 10: /* Write Single Mask Register Bit */ - channel_id = val & 3; - - /* "Clear or Set" is bit 2 */ - if ((val >> 2) & 1) { - dma_state.mask |= (1 << channel_id); - } else { - dma_state.mask &= ~(1 << channel_id); - /* Set the appropriate DRQ */ - /* *dmac_drq_handlers[channel_id].drq = TRUE; */ - } - - sim_debug(WRITE_MSG, &dmac_dev, - "[%08x] Write Single Mask Register Bit. channel=%d set/clear=%02x\n", - R[NUM_PC], channel_id, (val >> 2) & 1); - break; - case 11: /* Mode */ - sim_debug(WRITE_MSG, &dmac_dev, - "[%08x] Mode Set. val=%02x\n", - R[NUM_PC], val); - dma_state.mode = val; - break; - case 12: /* Clear Byte Pointer Flip/Flop */ - dma_state.bff = 0; - break; - case 13: /* Master Clear */ - dma_state.bff = 0; - dma_state.command = 0; - dma_state.status = 0; - for (i = 0; i < 4; i++) { - dma_state.channels[i].page = 0; - dma_state.channels[i].addr = 0; - dma_state.channels[i].wcount = 0; - dma_state.channels[i].addr_c = 0; - dma_state.channels[i].wcount_c = -1; - dma_state.channels[i].ptr = 0; - } - break; - case 15: /* Write All Mask Register Bits */ - sim_debug(WRITE_MSG, &dmac_dev, - "[%08x] Write DMAC mask (all bits). Val=%02x\n", - R[NUM_PC], val); - dma_state.mask = val & 0xf; - break; - case 16: /* Clear DMAC Interrupt */ - sim_debug(WRITE_MSG, &dmac_dev, - "[%08x] Clear DMAC Interrupt in DMAC. val=%02x\n", - R[NUM_PC], val); - break; - default: - sim_debug(WRITE_MSG, &dmac_dev, - "[%08x] Unhandled DMAC write. reg=%x val=%02x\n", - R[NUM_PC], reg, val); - break; - } -} - -void dmac_page_update(uint8 base, uint8 reg, uint8 val) -{ - uint8 shift = 0; - - /* Sanity check */ - if (reg > 3) { - return; - } - -#if defined(REV2) - /* In Rev2 systems, the actual register is a 32-bit, - byte-addressed register, so that address 4x000 is the highest - byte, 4x003 is the lowest byte. */ - shift = -(reg - 3) * 8; -#endif - - switch (base) { -#if defined (REV2) - case DMA_ID: - sim_debug(WRITE_MSG, &dmac_dev, "Set page channel 0 = %x\n", val); - dma_state.channels[DMA_ID_CHAN].page &= ~(0xff << shift); - dma_state.channels[DMA_ID_CHAN].page |= ((uint16)val << shift); - break; -#endif - case DMA_IF: - sim_debug(WRITE_MSG, &dmac_dev, "Set page channel 1 = %x\n", val); - dma_state.channels[DMA_IF_CHAN].page &= ~(0xff << shift); - dma_state.channels[DMA_IF_CHAN].page |= ((uint16)val << shift); - break; - case DMA_IUA: - sim_debug(WRITE_MSG, &dmac_dev, "Set page channel 2 = %x\n", val); - dma_state.channels[DMA_IUA_CHAN].page &= ~(0xff << shift); - dma_state.channels[DMA_IUA_CHAN].page |= ((uint16)val << shift); - break; - case DMA_IUB: - sim_debug(WRITE_MSG, &dmac_dev, "Set page channel 3 = %x\n", val); - dma_state.channels[DMA_IUB_CHAN].page &= ~(0xff << shift); - dma_state.channels[DMA_IUB_CHAN].page |= ((uint16)val << shift); - break; - } -} - -void dmac_write(uint32 pa, uint32 val, size_t size) -{ - uint8 reg, base; - - base = (uint8) (pa >> 12); - reg = pa & 0xff; - - switch (base) { - case DMA_C: - dmac_program(reg, (uint8) val); - break; -#if defined (REV2) - case DMA_ID: -#endif - case DMA_IUA: - case DMA_IUB: - case DMA_IF: - dmac_page_update(base, reg, (uint8) val); - break; - } -} - -void dmac_generic_dma(uint8 channel, uint32 service_address) -{ - uint8 data; - int32 i; - uint32 addr; - dma_channel *chan = &dma_state.channels[channel]; - - i = chan->wcount_c; - - /* TODO: This does not handle decrement-mode transfers, - which don't seem to be used in SVR3 */ - - switch ((dma_state.mode >> 2) & 0xf) { - case DMA_MODE_VERIFY: - sim_debug(EXECUTE_MSG, &dmac_dev, - "[%08x] [dmac_generic_dma channel=%d] unhandled VERIFY request.\n", - R[NUM_PC], channel); - break; - case DMA_MODE_WRITE: - sim_debug(EXECUTE_MSG, &dmac_dev, - "[%08x] [dmac_generic_dma channel=%d] write: %d bytes to %08x from %08x (page=%04x addr=%08x)\n", - R[NUM_PC], channel, - chan->wcount + 1, - dma_address(channel, 0, TRUE), - service_address, - dma_state.channels[channel].page, - dma_state.channels[channel].addr); - for (; i >= 0; i--) { - chan->wcount_c--; - addr = dma_address(channel, chan->ptr, TRUE); - chan->addr_c = dma_state.channels[channel].addr + chan->ptr; - chan->ptr++; - data = pread_b(service_address); - write_b(addr, data); - } - break; - case DMA_MODE_READ: - sim_debug(EXECUTE_MSG, &dmac_dev, - "[%08x] [dmac_generic_dma channel=%d] read: %d bytes from %08x to %08x\n", - R[NUM_PC], channel, - chan->wcount + 1, - dma_address(channel, 0, TRUE), - service_address); - for (; i >= 0; i--) { - chan->wcount_c = i; - addr = dma_address(channel, chan->ptr++, TRUE); - chan->addr_c = dma_state.channels[channel].addr + chan->ptr; - data = pread_b(addr); - write_b(service_address, data); - } - break; - } - - /* End of Process must set the channel's mask bit */ - dma_state.mask |= (1 << channel); - dma_state.status |= (1 << channel); -} - -/* - * Service pending DRQs - */ -void dmac_service_drqs() -{ - volatile dmac_dma_handler *h; - - for (h = &device_dma_handlers[0]; h->drq != NULL; h++) { - /* Only trigger if the channel has a DRQ set and its channel's - mask bit is 0 */ - if (*h->drq && ((dma_state.mask >> h->channel) & 0x1) == 0) { - h->dma_handler(h->channel, h->service_address); - /* Each handler is responsible for clearing its own DRQ line! */ - if (h->after_dma_callback != NULL) { - h->after_dma_callback(); - } - } - } -} +/* 3b2_dmac.c: AM9517 DMA Controller + + Copyright (c) 2021-2022, Seth J. Morabito + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + Except as contained in this notice, the name of the author shall + not be used in advertising or otherwise to promote the sale, use or + other dealings in this Software without prior written authorization + from the author. +*/ + +#include "3b2_dmac.h" + +#if defined(REV2) +#include "3b2_id.h" +#endif + +#include "3b2_cpu.h" +#include "3b2_if.h" +#include "3b2_iu.h" +#include "3b2_mem.h" +#include "3b2_stddev.h" +#include "3b2_csr.h" + +DMA_STATE dma_state; + +UNIT dmac_unit[] = { + { UDATA (NULL, 0, 0), 0, 0 }, + { UDATA (NULL, 0, 0), 0, 1 }, + { UDATA (NULL, 0, 0), 0, 2 }, + { UDATA (NULL, 0, 0), 0, 3 }, + { NULL } +}; + +REG dmac_reg[] = { + { NULL } +}; + +DEVICE dmac_dev = { + "DMAC", dmac_unit, dmac_reg, NULL, + 1, 16, 8, 4, 16, 32, + NULL, NULL, &dmac_reset, + NULL, NULL, NULL, NULL, + DEV_DEBUG, 0, sys_deb_tab +}; + +dmac_dma_handler device_dma_handlers[] = { +#if defined(REV2) + {DMA_ID_CHAN, IDBASE+ID_DATA_REG, &id_drq, dmac_generic_dma, id_after_dma}, +#endif + {DMA_IF_CHAN, IFBASE+IF_DATA_REG, &if_state.drq, dmac_generic_dma, if_after_dma}, + {DMA_IUA_CHAN, IUBASE+IUA_DATA_REG, &iu_console.drq, iu_dma_console, NULL}, + {DMA_IUB_CHAN, IUBASE+IUB_DATA_REG, &iu_contty.drq, iu_dma_contty, NULL}, + {0, 0, NULL, NULL, NULL } +}; + +uint32 dma_address(uint8 channel, uint32 offset) { + uint32 addr, page; + if (DMA_DECR(channel)) { + addr = (PHYS_MEM_BASE + (uint32)(dma_state.channels[channel].addr) - offset); + } else { + addr = (PHYS_MEM_BASE + (uint32)(dma_state.channels[channel].addr) + offset); + } +#if defined (REV3) + page = (uint32)dma_state.channels[channel].page; +#else + /* In Rev 2, the top bit of the page address is a R/W bit, so + we mask it here */ + page = (uint32)dma_state.channels[channel].page & 0x7f; +#endif + addr |= page << 16; + return addr; +} + +t_stat dmac_reset(DEVICE *dptr) +{ + int i; + + memset(&dma_state, 0, sizeof(dma_state)); + + for (i = 0; i < 4; i++) { + dma_state.channels[i].page = 0; + dma_state.channels[i].addr = 0; + dma_state.channels[i].mode = 0; + dma_state.channels[i].wcount = 0; + dma_state.channels[i].addr_c = 0; + dma_state.channels[i].wcount_c = -1; + dma_state.channels[i].ptr = 0; + } + + return SCPE_OK; +} + +uint32 dmac_read(uint32 pa, size_t size) +{ + uint8 reg, base, data; + + base = (uint8) (pa >> 12); + reg = pa & 0xff; + + switch (base) { + case DMA_C: + switch (reg) { + case 0: /* channel 0 current address reg */ + data = ((dma_state.channels[0].addr_c) >> (dma_state.bff * 8)) & 0xff; + sim_debug(READ_MSG, &dmac_dev, + "Reading Channel 0 Addr Reg: %08x\n", + data); + dma_state.bff ^= 1; + break; + case 1: /* channel 0 current address reg */ + data = ((dma_state.channels[0].wcount_c) >> (dma_state.bff * 8)) & 0xff; + sim_debug(READ_MSG, &dmac_dev, + "Reading Channel 0 Addr Count Reg: %08x\n", + data); + dma_state.bff ^= 1; + break; + case 2: /* channel 1 current address reg */ + data = ((dma_state.channels[1].addr_c) >> (dma_state.bff * 8)) & 0xff; + sim_debug(READ_MSG, &dmac_dev, + "Reading Channel 1 Addr Reg: %08x\n", + data); + dma_state.bff ^= 1; + break; + case 3: /* channel 1 current address reg */ + data = ((dma_state.channels[1].wcount_c) >> (dma_state.bff * 8)) & 0xff; + sim_debug(READ_MSG, &dmac_dev, + "Reading Channel 1 Addr Count Reg: %08x\n", + data); + dma_state.bff ^= 1; + break; + case 4: /* channel 2 current address reg */ + data = ((dma_state.channels[2].addr_c) >> (dma_state.bff * 8)) & 0xff; + sim_debug(READ_MSG, &dmac_dev, + "Reading Channel 2 Addr Reg: %08x\n", + data); + dma_state.bff ^= 1; + break; + case 5: /* channel 2 current address reg */ + data = ((dma_state.channels[2].wcount_c) >> (dma_state.bff * 8)) & 0xff; + sim_debug(READ_MSG, &dmac_dev, + "Reading Channel 2 Addr Count Reg: %08x\n", + data); + dma_state.bff ^= 1; + break; + case 6: /* channel 3 current address reg */ + data = ((dma_state.channels[3].addr_c) >> (dma_state.bff * 8)) & 0xff; + sim_debug(READ_MSG, &dmac_dev, + "Reading Channel 3 Addr Reg: %08x\n", + data); + dma_state.bff ^= 1; + break; + case 7: /* channel 3 current address reg */ + data = ((dma_state.channels[3].wcount_c) >> (dma_state.bff * 8)) & 0xff; + sim_debug(READ_MSG, &dmac_dev, + "Reading Channel 3 Addr Count Reg: %08x\n", + data); + dma_state.bff ^= 1; + break; + case 8: + data = dma_state.status; + sim_debug(READ_MSG, &dmac_dev, + "Reading DMAC Status %08x\n", + data); + dma_state.status = 0; + break; + default: + sim_debug(READ_MSG, &dmac_dev, + "DMAC READ %lu B @ %08x\n", + size, pa); + data = 0; + } + + return data; + default: + sim_debug(READ_MSG, &dmac_dev, + "[BASE: %08x] DMAC READ %lu B @ %08x\n", + base, size, pa); + return 0; + } +} + +/* + * Program the DMAC + */ +void dmac_program(uint8 reg, uint8 val) +{ + uint8 channel_id, i, chan_num; + dma_channel *channel; + +#if defined(REV3) + /* TODO: More general DMA interrupt clearing */ + CPU_CLR_INT(INT_UART_DMA); + CLR_CSR(CSRDMA); +#endif + + if (reg < 8) { + switch (reg) { + case 0: + case 1: + chan_num = 0; + break; + case 2: + case 3: + chan_num = 1; + break; + case 4: + case 5: + chan_num = 2; + break; + case 6: + case 7: + chan_num = 3; + break; + default: + chan_num = 0; + break; + } + + channel = &dma_state.channels[chan_num]; + + switch (reg & 1) { + case 0: /* Address */ + channel->addr &= ~(0xff << dma_state.bff * 8); + channel->addr |= (val & 0xff) << (dma_state.bff * 8); + channel->addr_c = channel->addr; + sim_debug(WRITE_MSG, &dmac_dev, + "Set address channel %d byte %d = %08x\n", + chan_num, dma_state.bff, channel->addr); + break; + case 1: /* Word Count */ + channel->wcount &= ~(0xff << dma_state.bff * 8); + channel->wcount |= (val & 0xff) << (dma_state.bff * 8); + channel->wcount_c = channel->wcount; + channel->ptr = 0; + sim_debug(WRITE_MSG, &dmac_dev, + "Set word count channel %d byte %d = %08x\n", + chan_num, dma_state.bff, channel->wcount); + break; + } + + /* Toggle the byte flip-flop */ + dma_state.bff ^= 1; + + /* Handled. */ + return; + } + + /* If it hasn't been handled, it must be one of the following + registers. */ + + switch (reg) { + case 8: /* Command */ + dma_state.command = val; + sim_debug(WRITE_MSG, &dmac_dev, + "Command: val=%02x\n", + val); + break; + case 9: /* Request */ + sim_debug(WRITE_MSG, &dmac_dev, + "Request set: val=%02x\n", + val); + dma_state.request = val; + break; + case 10: /* Write Single Mask Register Bit */ + channel_id = val & 3; + + /* "Clear or Set" is bit 2 */ + if ((val >> 2) & 1) { + dma_state.mask |= (1 << channel_id); + } else { + dma_state.mask &= ~(1 << channel_id); + /* Set the appropriate DRQ */ + /* *dmac_drq_handlers[channel_id].drq = TRUE; */ + } + + sim_debug(WRITE_MSG, &dmac_dev, + "Write Single Mask Register Bit. channel=%d set/clear=%02x\n", + channel_id, (val >> 2) & 1); + break; + case 11: /* Mode */ + channel_id = val & 3; + sim_debug(WRITE_MSG, &dmac_dev, + "Mode Set. channel=%d val=%02x\n", + channel_id, val); + dma_state.channels[channel_id].mode = val; + break; + case 12: /* Clear Byte Pointer Flip/Flop */ + dma_state.bff = 0; + break; + case 13: /* Master Clear */ + dma_state.bff = 0; + dma_state.command = 0; + dma_state.status = 0; + for (i = 0; i < 4; i++) { + dma_state.channels[i].page = 0; + dma_state.channels[i].addr = 0; + dma_state.channels[i].wcount = 0; + dma_state.channels[i].addr_c = 0; + dma_state.channels[i].wcount_c = -1; + dma_state.channels[i].ptr = 0; + } + break; + case 15: /* Write All Mask Register Bits */ + sim_debug(WRITE_MSG, &dmac_dev, + "Write DMAC mask (all bits). Val=%02x\n", + val); + dma_state.mask = val & 0xf; + break; + case 16: /* Clear DMAC Interrupt */ + sim_debug(WRITE_MSG, &dmac_dev, + "Clear DMA Interrupt in DMAC. val=%02x\n", + val); + break; + default: + sim_debug(WRITE_MSG, &dmac_dev, + "Unhandled DMAC write. reg=%x val=%02x\n", + reg, val); + break; + } +} + +void dmac_page_update(uint8 base, uint8 reg, uint8 val) +{ + uint8 shift = 0; + + /* Sanity check */ + if (reg > 3) { + return; + } + +#if defined(REV2) + /* In Rev2 systems, the actual register is a 32-bit, + byte-addressed register, so that address 4x000 is the highest + byte, 4x003 is the lowest byte. */ + shift = -(reg - 3) * 8; +#endif + + switch (base) { +#if defined (REV2) + case DMA_ID: + sim_debug(WRITE_MSG, &dmac_dev, "Set page channel 0 = %x\n", val); + dma_state.channels[DMA_ID_CHAN].page &= ~(0xff << shift); + dma_state.channels[DMA_ID_CHAN].page |= ((uint16)val << shift); + break; +#endif + case DMA_IF: + sim_debug(WRITE_MSG, &dmac_dev, "Set page channel 1 = %x\n", val); + dma_state.channels[DMA_IF_CHAN].page &= ~(0xff << shift); + dma_state.channels[DMA_IF_CHAN].page |= ((uint16)val << shift); + break; + case DMA_IUA: + sim_debug(WRITE_MSG, &dmac_dev, "Set page channel 2 = %x\n", val); + dma_state.channels[DMA_IUA_CHAN].page &= ~(0xff << shift); + dma_state.channels[DMA_IUA_CHAN].page |= ((uint16)val << shift); + break; + case DMA_IUB: + sim_debug(WRITE_MSG, &dmac_dev, "Set page channel 3 = %x\n", val); + dma_state.channels[DMA_IUB_CHAN].page &= ~(0xff << shift); + dma_state.channels[DMA_IUB_CHAN].page |= ((uint16)val << shift); + break; + } +} + +void dmac_write(uint32 pa, uint32 val, size_t size) +{ + uint8 reg, base; + + base = (uint8) (pa >> 12); + reg = pa & 0xff; + + switch (base) { + case DMA_C: + dmac_program(reg, (uint8) val); + break; +#if defined (REV2) + case DMA_ID: +#endif + case DMA_IUA: + case DMA_IUB: + case DMA_IF: + dmac_page_update(base, reg, (uint8) val); + break; + } +} + +void dmac_generic_dma(uint8 channel, uint32 service_address) +{ + uint8 data; + int32 i; + uint32 addr; + dma_channel *chan = &dma_state.channels[channel]; + + i = chan->wcount_c; + + /* TODO: This assumes every transfer is a block mode, which is not + guaranteed to be valid, but is likely safe? */ + + switch (DMA_XFER(channel)) { + case DMA_XFER_VERIFY: + sim_debug(EXECUTE_MSG, &dmac_dev, + "[dmac_generic_dma channel=%d] unhandled VERIFY request.\n", + channel); + break; + case DMA_XFER_WRITE: + sim_debug(EXECUTE_MSG, &dmac_dev, + "[dmac_generic_dma channel=%d] write: %d bytes to %08x from %08x (page=%04x addr=%08x)\n", + channel, + chan->wcount + 1, + dma_address(channel, 0), + service_address, + dma_state.channels[channel].page, + dma_state.channels[channel].addr); + for (; i >= 0; i--) { + chan->wcount_c--; + addr = dma_address(channel, chan->ptr++); + chan->addr_c = addr; + data = pread_b(service_address, BUS_PER); + write_b(addr, data, BUS_PER); + } + break; + case DMA_XFER_READ: + sim_debug(EXECUTE_MSG, &dmac_dev, + "[dmac_generic_dma channel=%d] read: %d bytes from %08x to %08x\n", + channel, + chan->wcount + 1, + dma_address(channel, 0), + service_address); + for (; i >= 0; i--) { + chan->wcount_c = i; + addr = dma_address(channel, chan->ptr++); + chan->addr_c = addr; + data = pread_b(addr, BUS_PER); + write_b(service_address, data, BUS_PER); + } + break; + } + + /* End of Process must set the channel's mask bit */ + dma_state.mask |= (1 << channel); + dma_state.status |= (1 << channel); +} + +/* + * Service pending DRQs + */ +void dmac_service_drqs() +{ + volatile dmac_dma_handler *h; + + for (h = &device_dma_handlers[0]; h->drq != NULL; h++) { + /* Only trigger if the channel has a DRQ set and its channel's + mask bit is 0 */ + if (*h->drq && ((dma_state.mask >> h->channel) & 0x1) == 0) { + h->dma_handler(h->channel, h->service_address); + /* Each handler is responsible for clearing its own DRQ line! */ + if (h->after_dma_callback != NULL) { + h->after_dma_callback(); + } + } + } +} diff --git a/3B2/3b2_dmac.h b/3B2/3b2_dmac.h index a5fe8e79..644b7734 100644 --- a/3B2/3b2_dmac.h +++ b/3B2/3b2_dmac.h @@ -1,84 +1,89 @@ -/* 3b2_dmac.h: AT&T 3B2 DMA Controller Header - - Copyright (c) 2021, Seth J. Morabito - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - - Except as contained in this notice, the name of the author shall - not be used in advertising or otherwise to promote the sale, use or - other dealings in this Software without prior written authorization - from the author. -*/ - -#ifndef _3B2_DMAC_H_ -#define _3B2_DMAC_H_ - -#include "3b2_defs.h" - -#define DMA_MODE_VERIFY 0 -#define DMA_MODE_WRITE 1 /* Write to memory from device */ -#define DMA_MODE_READ 2 /* Read from memory to device */ - -#define DMA_IF_READ (IFBASE + IF_DATA_REG) - -typedef struct { - uint16 page; - uint16 addr; /* Original addr */ - uint16 wcount; /* Original wcount */ - uint16 addr_c; /* Current addr */ - int32 wcount_c; /* Current word-count */ - uint16 ptr; /* Pointer into memory */ -} dma_channel; - -typedef struct { - /* Byte (high/low) flip-flop */ - uint8 bff; - - /* Address and count registers for channels 0-3 */ - dma_channel channels[4]; - - /* DMAC programmable registers */ - uint8 command; - uint8 mode; - uint8 request; - uint8 mask; - uint8 status; -} DMA_STATE; - -typedef struct { - uint8 channel; - uint32 service_address; - t_bool *drq; - void (*dma_handler)(uint8 channel, uint32 service_address); - void (*after_dma_callback)(); -} dmac_dma_handler; - -/* DMAC */ -t_stat dmac_reset(DEVICE *dptr); -uint32 dmac_read(uint32 pa, size_t size); -void dmac_write(uint32 pa, uint32 val, size_t size); -void dmac_service_drqs(); -void dmac_generic_dma(uint8 channel, uint32 service_address); -uint32 dma_address(uint8 channel, uint32 offset, t_bool r); - -extern DMA_STATE dma_state; - -#endif +/* 3b2_dmac.h: AM9517 DMA Controller + + Copyright (c) 2021-2022, Seth J. Morabito + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + Except as contained in this notice, the name of the author shall + not be used in advertising or otherwise to promote the sale, use or + other dealings in this Software without prior written authorization + from the author. +*/ + +#ifndef _3B2_DMAC_H_ +#define _3B2_DMAC_H_ + +#include "3b2_defs.h" + +#define DMA_XFER_VERIFY 0 +#define DMA_XFER_WRITE 1 /* Write to memory from device */ +#define DMA_XFER_READ 2 /* Read from memory to device */ + +#define DMA_IF_READ (IFBASE + IF_DATA_REG) + +#define DMA_MODE(C) ((dma_state.channels[(C)].mode >> 6) & 3) +#define DMA_DECR(C) ((dma_state.channels[(C)].mode >> 5) & 1) +#define DMA_AUTOINIT(C) ((dma_state.channels[(C)].mode >> 4) & 1) +#define DMA_XFER(C) ((dma_state.channels[(C)].mode >> 2) & 3) + +typedef struct { + uint8 mode; /* Channel mode */ + uint16 page; /* Memory page */ + uint16 addr; /* Original addr */ + uint16 wcount; /* Original wcount */ + uint16 addr_c; /* Current addr */ + int32 wcount_c; /* Current word-count */ + uint16 ptr; /* Pointer into memory */ +} dma_channel; + +typedef struct { + /* Byte (high/low) flip-flop */ + uint8 bff; + + /* Address and count registers for channels 0-3 */ + dma_channel channels[4]; + + /* DMAC programmable registers */ + uint8 command; + uint8 request; + uint8 mask; + uint8 status; +} DMA_STATE; + +typedef struct { + uint8 channel; + uint32 service_address; + t_bool *drq; + void (*dma_handler)(uint8 channel, uint32 service_address); + void (*after_dma_callback)(); +} dmac_dma_handler; + +/* DMAC */ +t_stat dmac_reset(DEVICE *dptr); +uint32 dmac_read(uint32 pa, size_t size); +void dmac_write(uint32 pa, uint32 val, size_t size); +void dmac_service_drqs(); +void dmac_generic_dma(uint8 channel, uint32 service_address); +uint32 dma_address(uint8 channel, uint32 offset); + +extern DMA_STATE dma_state; + +#endif diff --git a/3B2/3b2_id.c b/3B2/3b2_id.c index 71762d6d..d24e03f0 100644 --- a/3B2/3b2_id.c +++ b/3B2/3b2_id.c @@ -1,1000 +1,996 @@ -/* 3b2_d.h: AT&T 3B2 Model 400 Hard Disk (uPD7261) Implementation - - Copyright (c) 2017, Seth J. Morabito - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - - Except as contained in this notice, the name of the author shall - not be used in advertising or otherwise to promote the sale, use or - other dealings in this Software without prior written authorization - from the author. -*/ - -/* - * This file contains the code for the Integrated Disk (ID) controller - * (based on the uPD7261) and up to two winchester hard disks. - * - * Supported winchester drives are: - * - * SIMH Name ID Cyl Head Sec Byte/Sec Note - * --------- -- ---- ---- --- -------- ---------------------- - * HD30 3 697 5 18 512 CDC Wren 94155-36 - * HD72 5 925 9 18 512 CDC Wren II 94156-86 - * HD72C 8 754 11 18 512 Fujitsu M2243AS - * HD135 11 1224 15 18 512 Maxtor XT1190 - */ - -#include "3b2_id.h" - -#include "sim_disk.h" - -#include "3b2_cpu.h" - -#define ID_SEEK_WAIT 50 -#define ID_SEEK_BASE 700 -#define ID_RECAL_WAIT 6000 -#define ID_RW_WAIT 1000 -#define ID_SUS_WAIT 200 -#define ID_SPEC_WAIT 1250 -#define ID_SIS_WAIT 142 -#define ID_CMD_WAIT 140 - -/* Static function declarations */ -static SIM_INLINE t_lba id_lba(uint16 cyl, uint8 head, uint8 sec); - -/* Data FIFO pointer - Read */ -uint8 id_dpr = 0; -/* Data FIFO pointer - Write */ -uint8 id_dpw = 0; -/* Controller Status Register */ -uint8 id_status = 0; -/* Unit Interrupt Status */ -uint8 id_int_status = 0; -/* Last command received */ -uint8 id_cmd = 0; -/* DMAC request */ -t_bool id_drq = FALSE; -/* 8-byte FIFO */ -uint8 id_data[ID_FIFO_LEN] = {0}; -/* SRQM bit */ -t_bool id_srqm = FALSE; -/* The logical unit number (0-1) */ -uint8 id_unit_num = 0; -/* The physical unit number (0-3) */ -uint8 id_ua = 0; -/* Cylinder the drive is positioned on */ -uint16 id_cyl[ID_NUM_UNITS] = {0}; -/* Ending Track Number (from Specify) */ -uint8 id_etn = 0; -/* Ending Sector Number (from Specify) */ -uint8 id_esn = 0; -/* DTLH word (from Specify) */ -uint8 id_dtlh = 0; -/* Physical sector number */ -uint8 id_psn = 0; -/* Physical head number */ -uint8 id_phn = 0; -/* Logical cylinder number, high byte */ -uint8 id_lcnh = 0; -/* Logical cylinder number, low byte */ -uint8 id_lcnl = 0; -/* Logical head number */ -uint8 id_lhn = 0; -/* Logical sector number */ -uint8 id_lsn = 0; -/* Number of sectors to transfer, decremented after each sector */ -uint8 id_scnt = 0; -/* Whether we are using polling mode or not */ -t_bool id_polling = FALSE; -/* Sector buffer */ -uint8 id_buf[ID_SEC_SIZE]; -/* Buffer pointer */ -size_t id_buf_ptr = 0; - -uint8 id_idfield[ID_IDFIELD_LEN]; -uint8 id_idfield_ptr = 0; - -int8 id_seek_state[ID_NUM_UNITS] = {ID_SEEK_NONE}; - -struct id_dtype { - uint8 hd; /* Number of heads */ - uint32 capac; /* Capacity (in sectors) */ - const char *name; -}; - -static struct id_dtype id_dtab[] = { - ID_DRV(HD30), - ID_DRV(HD72), - ID_DRV(HD72C), - ID_DRV(HD135), - ID_DRV(HD161), - { 0 } -}; - -UNIT id_unit[] = { - { UDATA (&id_unit_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_BINK+ID_AUTOSIZE+ - (ID_HD72_DTYPE << ID_V_DTYPE), ID_DSK_SIZE(HD72)), 0, ID0, 0 }, - { UDATA (&id_unit_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_BINK+ID_AUTOSIZE+ - (ID_HD72_DTYPE << ID_V_DTYPE), ID_DSK_SIZE(HD72)), 0, ID1, 0 }, - { UDATA (&id_ctlr_svc, 0, 0) }, - { NULL } -}; - -UNIT *id_ctlr_unit = &id_unit[ID_CTLR]; - -/* The currently selected drive number */ -UNIT *id_sel_unit = &id_unit[ID0]; - -REG id_reg[] = { - { HRDATAD(CMD, id_cmd, 8, "Command") }, - { HRDATAD(STAT, id_status, 8, "Status") }, - { BRDATAD(CYL, id_cyl, 8, 8, ID_NUM_UNITS, "Track") }, - { NULL } -}; - -/* HD161 and HD135 are identical; the difference is only in the - * software being run on the emulator. SVR 2.0 will support a maximum - * of 1024 cylinders, so can only format the first 1024 cylinders of - * the HD135. SVR 3.0+ can support all 1224 cylinders of the HD161. */ -MTAB id_mod[] = { - { MTAB_XTD|MTAB_VUN, ID_HD30_DTYPE, NULL, "HD30", - &id_set_type, NULL, NULL, "Set HD30 Disk Type" }, - { MTAB_XTD|MTAB_VUN, ID_HD72_DTYPE, NULL, "HD72", - &id_set_type, NULL, NULL, "Set HD72 Disk Type" }, - { MTAB_XTD|MTAB_VUN, ID_HD72C_DTYPE, NULL, "HD72C", - &id_set_type, NULL, NULL, "Set HD72C Disk Type" }, - { MTAB_XTD|MTAB_VUN, ID_HD135_DTYPE, NULL, "HD135", - &id_set_type, NULL, NULL, "Set HD135 Disk Type" }, - { MTAB_XTD|MTAB_VUN, ID_HD161_DTYPE, NULL, "HD161", - &id_set_type, NULL, NULL, "Set HD161 Disk Type" }, - { MTAB_XTD|MTAB_VUN, 0, "TYPE", NULL, - NULL, &id_show_type, NULL, "Display device type" }, - { ID_AUTOSIZE, ID_AUTOSIZE, "autosize", "AUTOSIZE", - NULL, NULL, NULL, "Set type based on file size at attach" }, - { ID_AUTOSIZE, 0, "noautosize", "NOAUTOSIZE", - NULL, NULL, NULL, "Disable disk autosize on attach" }, - { 0 } -}; - -DEVICE id_dev = { - "IDISK", id_unit, id_reg, id_mod, - ID_NUM_UNITS, 16, 32, 1, 16, 8, - NULL, NULL, &id_reset, - NULL, &id_attach, &id_detach, NULL, - DEV_DEBUG|DEV_DISK|DEV_SECTORS, 0, sys_deb_tab, - NULL, NULL, &id_help, NULL, NULL, - &id_description -}; - -/* Function implementation */ - -#define UPDATE_INT { \ - if ((id_status & (ID_STAT_CEL|ID_STAT_CEH)) || \ - ((id_status & ID_STAT_SRQ) && !id_srqm)) { \ - CPU_SET_INT(INT_DISK); \ - } else { \ - CPU_CLR_INT(INT_DISK); \ - } \ - } - -static SIM_INLINE void id_set_status(uint8 flags) -{ - id_status |= flags; - UPDATE_INT; -} - -static SIM_INLINE void id_clr_status(uint8 flags) -{ - id_status &= ~(flags); - UPDATE_INT; -} - -static SIM_INLINE void id_set_srqm(t_bool state) -{ - id_srqm = state; - UPDATE_INT; -} - -static SIM_INLINE void id_clear_fifo() -{ - id_dpr = 0; - id_dpw = 0; -} - -static SIM_INLINE void id_activate(UNIT *uptr, int32 delay) -{ - sim_activate_abs(uptr, delay); -} - -/* - * Service routine for ID controller. - * - * The simulated HD controller must service Sense Interrupt Status, - * Specify, and Detect Error independent of the operation of either ID - * unit, which may be in the middle of a seek or other operation. - */ -t_stat id_ctlr_svc(UNIT *uptr) -{ - uint8 cmd; - - cmd = uptr->u4; /* The command that caused the activity */ - - id_set_srqm(FALSE); - id_clr_status(ID_STAT_CB); - id_set_status(ID_STAT_CEH); - uptr->u4 = 0; - - switch (cmd) { - case ID_CMD_SIS: - sim_debug(EXECUTE_MSG, &id_dev, - "[%08x]\tINTR\t\tCOMPLETING Sense Interrupt Status.\n", - R[NUM_PC]); - id_data[0] = id_int_status; - id_int_status = 0; - break; - default: - sim_debug(EXECUTE_MSG, &id_dev, - "[%08x]\tINTR\t\tCOMPLETING OTHER COMMAND 0x%x (CONTROLLER)\n", - R[NUM_PC], cmd); - break; - } - - return SCPE_OK; -} - -/* - * Service routine for ID0 and ID1 units. - */ -t_stat id_unit_svc(UNIT *uptr) -{ - uint8 unit, other, cmd; - - unit = uptr->u3; /* The unit number that needs an interrupt */ - cmd = uptr->u4; /* The command that caused the activity */ - other = unit ^ 1; /* The number of the other unit */ - - /* If the other unit is active, we cannot interrupt, so we delay - * here */ - if (id_unit[other].u4 == ID_CMD_RDATA || - id_unit[other].u4 == ID_CMD_WDATA) { - id_activate(uptr, 1000); - return SCPE_OK; - } - - id_set_srqm(FALSE); - id_clr_status(ID_STAT_CB); - /* Note that we don't set CEH, in case this is a SEEK/RECAL ID_SEEK_1 */ - - switch (cmd) { - case ID_CMD_SEEK: /* fall-through */ - case ID_CMD_RECAL: - /* In POLLING mode, SEEK and RECAL actually interrupt twice. - * - * 1. Immediately after the correct number of stepping pulses - * have been issued (SRQ is not set) - * - * 2. After the drive has completed seeking and is ready - * for a new command (SRQ is set) - */ - if (id_polling) { - switch (id_seek_state[unit]) { - case ID_SEEK_0: - id_set_status(ID_STAT_CEH); - sim_debug(EXECUTE_MSG, &id_dev, - "[%08x]\tINTR\t\tCOMPLETING Recal/Seek SEEK_0 UNIT %d\n", - R[NUM_PC], unit); - id_seek_state[unit] = ID_SEEK_1; - id_activate(uptr, 8000); /* TODO: Correct Delay based on steps */ - break; - case ID_SEEK_1: - sim_debug(EXECUTE_MSG, &id_dev, - "[%08x]\tINTR\t\tCOMPLETING Recal/Seek SEEK_1 UNIT %d\n", - R[NUM_PC], unit); - id_seek_state[unit] = ID_SEEK_NONE; - id_set_status(ID_STAT_SRQ); - uptr->u4 = 0; /* Only clear out the command on a SEEK_1, never a SEEK_0 */ - if (uptr->flags & UNIT_ATT) { - id_int_status |= (ID_IST_SEN|unit); - } else { - id_int_status |= (ID_IST_NR|unit); - } - break; - default: - sim_debug(EXECUTE_MSG, &id_dev, - "[%08x]\tINTR\t\tERROR, NOT SEEK_0 OR SEEK_1, UNIT %d\n", - R[NUM_PC], unit); - break; - } - } else { - sim_debug(EXECUTE_MSG, &id_dev, - "[%08x]\tINTR\t\tCOMPLETING NON-POLLING Recal/Seek UNIT %d\n", - R[NUM_PC], unit); - id_set_status(ID_STAT_CEH); - uptr->u4 = 0; - if (uptr->flags & UNIT_ATT) { - id_int_status |= (ID_IST_SEN|unit); - } else { - id_int_status |= (ID_IST_NR|unit); - } - } - - break; - case ID_CMD_SUS: - sim_debug(EXECUTE_MSG, &id_dev, - "[%08x]\tINTR\t\tCOMPLETING Sense Unit Status UNIT %d\n", - R[NUM_PC], unit); - id_set_status(ID_STAT_CEH); - uptr->u4 = 0; - if ((uptr->flags & UNIT_ATT) == 0) { - /* If no HD is attached, SUS puts 0x00 into the data - buffer */ - id_data[0] = 0; - } else { - /* Put Unit Status into byte 0 */ - id_data[0] = (ID_UST_DSEL|ID_UST_SCL|ID_UST_RDY); - if (id_cyl[unit] == 0) { - id_data[0] |= ID_UST_TK0; - } - } - break; - default: - sim_debug(EXECUTE_MSG, &id_dev, - "[%08x]\tINTR\t\tCOMPLETING OTHER COMMAND 0x%x UNIT %d\n", - R[NUM_PC], cmd, unit); - id_set_status(ID_STAT_CEH); - uptr->u4 = 0; - break; - } - - return SCPE_OK; -} - -t_stat id_set_type(UNIT *uptr, int32 val, CONST char *cptr, void *desc) -{ - if (val < 0 || val > ID_MAX_DTYPE) { - return SCPE_ARG; - } - - if (uptr->flags & UNIT_ATT) { - return SCPE_ALATT; - } - - uptr->flags = (uptr->flags & ~ID_DTYPE) | (val << ID_V_DTYPE); - uptr->capac = (t_addr)id_dtab[val].capac; - - return SCPE_OK; -} - -t_stat id_show_type (FILE *st, UNIT *uptr, int32 val, CONST void *desc) -{ - fprintf (st, "%s", id_dtab[ID_GET_DTYPE(uptr->flags)].name); - return SCPE_OK; -} - -t_stat id_reset(DEVICE *dptr) -{ - id_clear_fifo(); - return SCPE_OK; -} - -t_stat id_attach(UNIT *uptr, CONST char *cptr) -{ - static const char *drives[] = {"HD30", "HD72", "HD72C", "HD135", "HD161", NULL}; - - return sim_disk_attach_ex(uptr, cptr, 512, 1, TRUE, 0, id_dtab[ID_GET_DTYPE(uptr->flags)].name, - 0, 0, (uptr->flags & ID_AUTOSIZE) ? drives : NULL); -} - -t_stat id_detach(UNIT *uptr) -{ - return sim_disk_detach(uptr); -} - -/* Return the logical block address of the given sector */ -static t_lba id_lba(uint16 cyl, uint8 head, uint8 sec) -{ - uint8 dtype; - - dtype = ID_GET_DTYPE(id_sel_unit->flags); - - return((ID_SEC_CNT * id_dtab[dtype].hd * cyl) + - (ID_SEC_CNT * head) + - sec); -} - -/* At the end of each sector read or write, we update the FIFO - * with the correct return parameters. */ -static void SIM_INLINE id_end_rw(uint8 est) -{ - id_clear_fifo(); - id_data[0] = est; - id_data[1] = id_phn; - id_data[2] = ~(id_lcnh); - id_data[3] = id_lcnl; - id_data[4] = id_lhn; - id_data[5] = id_lsn; - id_data[6] = id_scnt; -} - -/* The controller wraps id_lsn, id_lhn, and id_lcnl on each sector - * read, so that they point to the next C/H/S */ -static void SIM_INLINE id_update_chs() -{ - if (id_lsn++ >= id_esn) { - id_lsn = 0; - if (id_lhn++ >= id_etn) { - id_lhn = 0; - if (id_lcnl == 0xff) { - id_lcnl = 0; - id_lcnh++; - } else { - id_lcnl++; - } - } - } -} - -uint32 id_read(uint32 pa, size_t size) -{ - uint8 reg; - uint16 cyl; - t_lba lba; - uint32 data; - t_seccnt sectsread; - - reg = (uint8) (pa - IDBASE); - - switch(reg) { - case ID_DATA_REG: /* Data Buffer Register */ - /* If we're in a DMA transfer, we need to be reading data from - * the disk buffer. Otherwise, we're reading from the FIFO. */ - - if (id_drq) { - /* If the drive isn't attached, there's really nothing we - can do. */ - if ((id_sel_unit->flags & UNIT_ATT) == 0) { - id_end_rw(ID_EST_NR); - return 0; - } - - /* We could be in one of these commands: - * - Read Data - * - Read ID - */ - - if (CMD_NUM == ID_CMD_RDATA) { - /* If we're still in DRQ but we've read all our sectors, - * that's an error state. */ - if (id_scnt == 0) { - sim_debug(READ_MSG, &id_dev, - "[%08x] ERROR\tid_scnt = 0 but still in dma\n", - R[NUM_PC]); - id_end_rw(ID_EST_OVR); - return 0; - } - - /* If the disk buffer is empty, fill it. */ - if (id_buf_ptr == 0 || id_buf_ptr >= ID_SEC_SIZE) { - /* It's time to read a new sector into our sector buf */ - id_buf_ptr = 0; - cyl = (uint16) (((uint16)id_lcnh << 8)|(uint16)id_lcnl); - id_cyl[id_unit_num] = cyl; - lba = id_lba(cyl, id_lhn, id_lsn); - if (sim_disk_rdsect(id_sel_unit, lba, id_buf, §sread, 1) == SCPE_OK) { - if (sectsread !=1) { - sim_debug(READ_MSG, &id_dev, - "[%08x]\tERROR: ASKED TO READ ONE SECTOR, READ: %d\n", - R[NUM_PC], sectsread); - } - id_update_chs(); - } else { - /* Uh-oh! */ - sim_debug(READ_MSG, &id_dev, - "[%08x]\tRDATA READ ERROR. Failure from sim_disk_rdsect!\n", - R[NUM_PC]); - id_end_rw(ID_EST_DER); - return 0; - } - } - - data = id_buf[id_buf_ptr++]; - sim_debug(READ_MSG, &id_dev, - "[%08x]\tDATA\t%02x\n", - R[NUM_PC], data); - - /* Done with this current sector, update id_scnt */ - if (id_buf_ptr >= ID_SEC_SIZE) { - if (--id_scnt == 0) { - id_end_rw(0); - } - } - } else if (CMD_NUM == ID_CMD_RID) { - /* We have to return the ID bytes for the current C/H/S */ - if (id_idfield_ptr == 0 || id_idfield_ptr >= ID_IDFIELD_LEN) { - id_idfield[0] = ~(id_lcnh); - id_idfield[1] = id_lcnl; - id_idfield[2] = id_lhn; - id_idfield[3] = id_lsn; - id_idfield_ptr = 0; - } - - data = id_idfield[id_idfield_ptr++]; - sim_debug(READ_MSG, &id_dev, - "[%08x]\tID DATA\t%02x\n", - R[NUM_PC], data); - - if (id_idfield_ptr >= ID_IDFIELD_LEN) { - if (id_scnt-- > 0) { - /* Another sector to ID */ - id_idfield_ptr = 0; - } else { - /* All done, set return codes */ - id_clear_fifo(); - id_data[0] = 0; - id_data[1] = id_scnt; - } - } - } else { - /* cmd not Read Data or Read ID */ - stop_reason = STOP_ERR; - return 0; - } - - return data; - } else { - if (id_dpr < ID_FIFO_LEN) { - sim_debug(READ_MSG, &id_dev, - "[%08x]\tDATA\t%02x\n", - R[NUM_PC], id_data[id_dpr]); - return id_data[id_dpr++]; - } else { - sim_debug(READ_MSG, &id_dev, - "[%08x] ERROR\tFIFO OVERRUN\n", - R[NUM_PC]); - return 0; - } - } - - break; - case ID_CMD_STAT_REG: /* Status Register */ - sim_debug(READ_MSG, &id_dev, - "[%08x]\tSTATUS\t%02x\n", - R[NUM_PC], id_status|id_drq); - return id_status|(id_drq ? 1u : 0); - } - - sim_debug(READ_MSG, &id_dev, - "[%08x] Read of unsuported register %x\n", - R[NUM_PC], id_status); - - return 0; -} - -void id_write(uint32 pa, uint32 val, size_t size) -{ - uint8 reg; - uint16 cyl; - t_lba lba; - t_seccnt sectswritten; - - reg = (uint8) (pa - IDBASE); - - switch(reg) { - case ID_DATA_REG: - /* If we're in a DMA transfer, we need to be writing data to - * the disk buffer. Otherwise, we're writing to the FIFO. */ - - if (id_drq) { - /* If we're still in DRQ but we've written all our sectors, - * that's an error state. */ - if (id_scnt == 0) { - sim_debug(WRITE_MSG, &id_dev, - "[%08x] ERROR\tid_scnt = 0 but still in dma\n", - R[NUM_PC]); - id_end_rw(ID_EST_OVR); - return; - } - - /* Write to the disk buffer */ - if (id_buf_ptr < ID_SEC_SIZE) { - id_buf[id_buf_ptr++] = (uint8)(val & 0xff); - sim_debug(WRITE_MSG, &id_dev, - "[%08x]\tDATA\t%02x\n", - R[NUM_PC], (uint8)(val & 0xff)); - } else { - sim_debug(WRITE_MSG, &id_dev, - "[%08x]\tERROR\tWDATA OVERRUN\n", - R[NUM_PC]); - id_end_rw(ID_EST_OVR); - return; - } - - /* If we've hit the end of a sector, flush it */ - if (id_buf_ptr >= ID_SEC_SIZE) { - /* It's time to start the next sector, and flush the old. */ - id_buf_ptr = 0; - cyl = (uint16) (((uint16) id_lcnh << 8)|(uint16)id_lcnl); - id_cyl[id_unit_num] = cyl; - lba = id_lba(cyl, id_lhn, id_lsn); - if (sim_disk_wrsect(id_sel_unit, lba, id_buf, §swritten, 1) == SCPE_OK) { - if (sectswritten !=1) { - sim_debug(WRITE_MSG, &id_dev, - "[%08x]\tERROR: ASKED TO WRITE ONE SECTOR, WROTE: %d\n", - R[NUM_PC], sectswritten); - } - id_update_chs(); - if (--id_scnt == 0) { - id_end_rw(0); - } - } else { - /* Uh-oh! */ - sim_debug(WRITE_MSG, &id_dev, - "[%08x] ERROR\tWDATA WRITE ERROR. lba=%04x\n", - R[NUM_PC], lba); - id_end_rw(ID_EST_DER); - return; - } - } - return; - } else { - sim_debug(WRITE_MSG, &id_dev, - "[%08x]\tDATA\t%02x\n", - R[NUM_PC], val); - if (id_dpw < ID_FIFO_LEN) { - id_data[id_dpw++] = (uint8) val; - } else { - sim_debug(WRITE_MSG, &id_dev, - "[%08x] ERROR\tFIFO OVERRUN\n", - R[NUM_PC]); - } - } - return; - case ID_CMD_STAT_REG: - id_handle_command((uint8) val); - return; - default: - return; - } -} - -void id_handle_command(uint8 val) -{ - uint8 cmd, aux_cmd, sec, pattern; - uint16 cyl; - uint32 time; - t_lba lba; - - /* Reset the FIFO pointer */ - id_clear_fifo(); - - /* Is this an aux command or a full command? */ - if ((val & 0xf0) == 0) { - aux_cmd = val & 0x0f; - - if (aux_cmd & ID_AUX_CLCE) { - sim_debug(WRITE_MSG, &id_dev, - "[%08x] \tCOMMAND\t%02x\tAUX:CLCE\n", - R[NUM_PC], val); - id_clr_status(ID_STAT_CEH|ID_STAT_CEL); - } - - if (aux_cmd & ID_AUX_HSRQ) { - sim_debug(WRITE_MSG, &id_dev, - "[%08x] \tCOMMAND\t%02x\tAUX:HSRQ\n", - R[NUM_PC], val); - id_set_srqm(TRUE); - } - - if (aux_cmd & ID_AUX_CLB) { - sim_debug(WRITE_MSG, &id_dev, - "[%08x]\tCOMMAND\t%02x\tAUX:CLBUF\n", - R[NUM_PC], val); - id_clear_fifo(); - } - - if (aux_cmd & ID_AUX_RST) { - sim_debug(WRITE_MSG, &id_dev, - "[%08x]\tCOMMAND\t%02x\tAUX:RESET\n", - R[NUM_PC], val); - id_clear_fifo(); - sim_cancel(id_sel_unit); - sim_cancel(id_ctlr_unit); - id_status = 0; - id_srqm = FALSE; - UPDATE_INT; - } - - /* Just return early */ - return; - } - - /* If the controller is busy and this isn't an AUX command, do - * nothing */ - if (id_status & ID_STAT_CB) { - sim_debug(EXECUTE_MSG, &id_dev, - "!!! Controller Busy. Skipping command byte %02x\n", - val); - return; - } - - /* A full command always resets CEH and CEL */ - id_clr_status(ID_STAT_CEH|ID_STAT_CEL); - - /* Save the full command byte */ - id_cmd = val; - cmd = (id_cmd >> 4) & 0xf; - - /* Now that we know it's not an aux command, we can get the unit - * number. Note that we don't update the unit in the case of three - * special commands. */ - if (cmd != ID_CMD_SIS && cmd != ID_CMD_SPEC && cmd != ID_CMD_DERR) { - if ((id_cmd & 3) != id_ua) { - id_unit_num = id_cmd & 1; - id_ua = id_cmd & 3; - id_sel_unit = &id_unit[id_unit_num]; - } - } - - /* TODO: Fix this hack */ - if (cmd == ID_CMD_SIS || cmd == ID_CMD_SPEC || cmd == ID_CMD_DERR) { - id_ctlr_unit->u4 = cmd; - } else { - id_sel_unit->u4 = cmd; - } - - id_set_status(ID_STAT_CB); - - switch(cmd) { - case ID_CMD_SIS: - sim_debug(WRITE_MSG, &id_dev, - "[%08x]\tCOMMAND\t%02x\tSense Int. Status\n", - R[NUM_PC], val); - id_clr_status(ID_STAT_SRQ); /* SIS immediately de-asserts SRQ */ - id_activate(id_ctlr_unit, ID_SIS_WAIT); - break; - case ID_CMD_SPEC: - sim_debug(WRITE_MSG, &id_dev, - "[%08x]\tCOMMAND\t%02x\tSpecify - ETN=%02x ESN=%02x\n", - R[NUM_PC], val, id_data[3], id_data[4]); - id_dtlh = id_data[1]; - id_etn = id_data[3]; - id_esn = id_data[4]; - id_polling = (id_dtlh & ID_DTLH_POLL) == 0; - id_activate(id_ctlr_unit, ID_SPEC_WAIT); - break; - case ID_CMD_SUS: - sim_debug(WRITE_MSG, &id_dev, - "[%08x]\tCOMMAND\t%02x\tSense Unit Status - %d\n", - R[NUM_PC], val, id_ua); - id_activate(id_sel_unit, ID_SUS_WAIT); - break; - case ID_CMD_DERR: - sim_debug(WRITE_MSG, &id_dev, - "[%08x]\tCOMMAND\t%02x\tDetect Error\n", - R[NUM_PC], val); - id_activate(id_ctlr_unit, ID_CMD_WAIT); - break; - case ID_CMD_RECAL: - time = id_cyl[id_unit_num]; - id_cyl[id_unit_num] = 0; - id_seek_state[id_unit_num] = ID_SEEK_0; - if (id_polling) { - sim_debug(WRITE_MSG, &id_dev, - "[%08x]\tCOMMAND\t%02x\tRecalibrate - %d - POLLING\n", - R[NUM_PC], val, id_ua); - id_activate(id_sel_unit, 1000); - } else { - sim_debug(WRITE_MSG, &id_dev, - "[%08x]\tCOMMAND\t%02x\tRecalibrate - %d - NORMAL\n", - R[NUM_PC], val, id_ua); - id_activate(id_sel_unit, (ID_RECAL_WAIT + (time * ID_SEEK_WAIT))); - } - break; - case ID_CMD_SEEK: - id_lcnh = id_data[0]; - id_lcnl = id_data[1]; - cyl = id_lcnh << 8 | id_lcnl; - time = (uint32) abs(id_cyl[id_unit_num] - cyl); - id_cyl[id_unit_num] = cyl; - id_seek_state[id_unit_num] = ID_SEEK_0; - - if (id_polling) { - sim_debug(WRITE_MSG, &id_dev, - "[%08x]\tCOMMAND\t%02x\tSeek - %d - POLLING\n", - R[NUM_PC], val, id_ua); - id_activate(id_sel_unit, 4000); - } else { - sim_debug(WRITE_MSG, &id_dev, - "[%08x]\tCOMMAND\t%02x\tSeek - %d - NORMAL\n", - R[NUM_PC], val, id_ua); - id_activate(id_sel_unit, ID_SEEK_BASE + (time * ID_SEEK_WAIT)); - } - break; - case ID_CMD_FMT: - sim_debug(WRITE_MSG, &id_dev, - "[%08x]\tCOMMAND\t%02x\tFormat - %d\n", - R[NUM_PC], val, id_ua); - - id_phn = id_data[0]; - id_scnt = id_data[1]; - pattern = id_data[2]; - - /* Format scnt sectors with the given pattern, if attached */ - if (id_sel_unit->flags & UNIT_ATT) { - /* Formatting soft-sectored disks always begins at sector 0 */ - sec = 0; - - while (id_scnt-- > 0) { - /* Write one sector of pattern */ - for (id_buf_ptr = 0; id_buf_ptr < ID_SEC_SIZE; id_buf_ptr++) { - id_buf[id_buf_ptr] = pattern; - } - lba = id_lba(id_cyl[id_unit_num], id_phn, sec++); - if (sim_disk_wrsect(id_sel_unit, lba, id_buf, NULL, 1) == SCPE_OK) { - sim_debug(EXECUTE_MSG, &id_dev, - "[%08x]\tFORMAT: PHN=%d SCNT=%d PAT=%02x LBA=%04x\n", - R[NUM_PC], id_phn, id_scnt, pattern, lba); - } else { - sim_debug(EXECUTE_MSG, &id_dev, - "[%08x]\tFORMAT FAILED! PHN=%d SCNT=%d PAT=%02x LBA=%04x\n", - R[NUM_PC], id_phn, id_scnt, pattern, lba); - break; - } - } - - id_data[0] = 0; - } else { - /* Not attached */ - id_data[0] = ID_EST_NR; - } - - id_data[1] = id_scnt; - - id_activate(id_sel_unit, ID_CMD_WAIT); - break; - case ID_CMD_VID: - sim_debug(WRITE_MSG, &id_dev, - "[%08x]\tCOMMAND\t%02x\tVerify ID - %d\n", - R[NUM_PC], val, id_ua); - id_data[0] = 0; - id_data[1] = 0x05; /* What do we put here? */ - id_activate(id_sel_unit, ID_CMD_WAIT); - break; - case ID_CMD_RID: - sim_debug(WRITE_MSG, &id_dev, - "[%08x]\tCOMMAND\t%02x\tRead ID - %d\n", - R[NUM_PC], val, id_ua); - if (id_sel_unit->flags & UNIT_ATT) { - id_drq = TRUE; - - /* Grab our arguments */ - id_phn = id_data[0]; - id_scnt = id_data[1]; - - /* Compute logical values used by ID verification */ - id_lhn = id_phn; - id_lsn = 0; - } else { - sim_debug(EXECUTE_MSG, &id_dev, - "[%08x]\tUNIT %d NOT ATTACHED, CANNOT READ ID.\n", - R[NUM_PC], id_ua); - } - id_activate(id_sel_unit, ID_CMD_WAIT); - break; - case ID_CMD_RDIAG: - sim_debug(WRITE_MSG, &id_dev, - "[%08x]\tCOMMAND\t%02x\tRead Diag - %d\n", - R[NUM_PC], val, id_ua); - id_activate(id_sel_unit, ID_CMD_WAIT); - break; - case ID_CMD_RDATA: - sim_debug(WRITE_MSG, &id_dev, - "[%08x]\tCOMMAND\t%02x\tRead Data - %d\n", - R[NUM_PC], val, id_ua); - if (id_sel_unit->flags & UNIT_ATT) { - id_drq = TRUE; - id_buf_ptr = 0; - - /* Grab our arguments */ - id_phn = id_data[0]; - id_lcnh = ~(id_data[1]); - id_lcnl = id_data[2]; - id_lhn = id_data[3]; - id_lsn = id_data[4]; - id_scnt = id_data[5]; - } else { - sim_debug(EXECUTE_MSG, &id_dev, - "[%08x]\tUNIT %d NOT ATTACHED, CANNOT READ DATA.\n", - R[NUM_PC], id_ua); - } - id_activate(id_sel_unit, ID_RW_WAIT); - break; - case ID_CMD_CHECK: - sim_debug(WRITE_MSG, &id_dev, - "[%08x]\tCOMMAND\t%02x\tCheck - %d\n", - R[NUM_PC], val, id_ua); - id_activate(id_sel_unit, ID_CMD_WAIT); - break; - case ID_CMD_SCAN: - sim_debug(WRITE_MSG, &id_dev, - "[%08x]\tCOMMAND\t%02x\tScan - %d\n", - R[NUM_PC], val, id_ua); - id_activate(id_sel_unit, ID_CMD_WAIT); - break; - case ID_CMD_VDATA: - sim_debug(WRITE_MSG, &id_dev, - "[%08x]\tCOMMAND\t%02x\tVerify Data - %d\n", - R[NUM_PC], val, id_ua); - id_activate(id_sel_unit, ID_CMD_WAIT); - break; - case ID_CMD_WDATA: - sim_debug(WRITE_MSG, &id_dev, - "[%08x]\tCOMMAND\t%02x\tWrite Data - %d\n", - R[NUM_PC], val, id_ua); - if (id_sel_unit->flags & UNIT_ATT) { - id_drq = TRUE; - id_buf_ptr = 0; - - /* Grab our arguments */ - id_phn = id_data[0]; - id_lcnh = ~(id_data[1]); - id_lcnl = id_data[2]; - id_lhn = id_data[3]; - id_lsn = id_data[4]; - id_scnt = id_data[5]; - } else { - sim_debug(EXECUTE_MSG, &id_dev, - "[%08x]\tUNIT %d NOT ATTACHED, CANNOT WRITE.\n", - R[NUM_PC], id_ua); - } - id_activate(id_sel_unit, ID_RW_WAIT); - break; - } -} - -void id_after_dma() -{ - id_clr_status(ID_STAT_DRQ); - id_drq = FALSE; -} - -CONST char *id_description(DEVICE *dptr) -{ - return "Integrated Hard Disk"; -} - -t_stat id_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr) -{ - fprintf(st, "Integrated Hard Disk (IDISK)\n\n"); - fprintf(st, "The IDISK device implements the integrated MFM hard disk of the\n"); - fprintf(st, "3B2/400. Up to two drives are supported on a single controller.\n\n"); - fprintf(st, "Supported device types are:\n\n"); - fprintf(st, " Name Size ID Cyl Head Sec Byte/Sec Description\n"); - fprintf(st, " ---- -------- -- ---- ---- --- -------- ----------------------\n"); - fprintf(st, " HD30 30.6 MB 3 697 5 18 512 CDC Wren 94155-36\n"); - fprintf(st, " HD72 73.2 MB 5 925 9 18 512 CDC Wren II 94156-86\n"); - fprintf(st, " HD72C 72.9 MB 8 754 11 18 512 Fujitsu M2243AS\n"); - fprintf(st, " HD135 135.0 MB 11 1024 15 18 512 Maxtor XT1190 (SVR2)\n"); - fprintf(st, " HD161 161.4 MB 11 1224 15 18 512 Maxtor XT1190 (SVR3+)\n\n"); - fprintf(st, "The drive ID and geometry values are used when low-level formatting a\n"); - fprintf(st, "drive using the AT&T 'idtools' utility.\n"); - return SCPE_OK; -} +/* 3b2_d.c: uPD7261 Integrated Disk Controller + + Copyright (c) 2017-2022, Seth J. Morabito + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + Except as contained in this notice, the name of the author shall + not be used in advertising or otherwise to promote the sale, use or + other dealings in this Software without prior written authorization + from the author. +*/ + +/* + * This file contains the code for the Integrated Disk (ID) controller + * (based on the uPD7261) and up to two winchester hard disks. + * + * Supported winchester drives are: + * + * SIMH Name ID Cyl Head Sec Byte/Sec Note + * --------- -- ---- ---- --- -------- ---------------------- + * HD30 3 697 5 18 512 CDC Wren 94155-36 + * HD72 5 925 9 18 512 CDC Wren II 94156-86 + * HD72C 8 754 11 18 512 Fujitsu M2243AS + * HD135 11 1224 15 18 512 Maxtor XT1190 + */ + +#include "3b2_id.h" + +#include "sim_disk.h" + +#include "3b2_cpu.h" + +#define ID_SEEK_WAIT 50 +#define ID_SEEK_BASE 700 +#define ID_RECAL_WAIT 6000 +#define ID_RW_WAIT 1000 +#define ID_SUS_WAIT 200 +#define ID_SPEC_WAIT 1250 +#define ID_SIS_WAIT 142 +#define ID_CMD_WAIT 140 + +/* Static function declarations */ +static SIM_INLINE t_lba id_lba(uint16 cyl, uint8 head, uint8 sec); + +/* Data FIFO pointer - Read */ +uint8 id_dpr = 0; +/* Data FIFO pointer - Write */ +uint8 id_dpw = 0; +/* Controller Status Register */ +uint8 id_status = 0; +/* Unit Interrupt Status */ +uint8 id_int_status = 0; +/* Last command received */ +uint8 id_cmd = 0; +/* DMAC request */ +t_bool id_drq = FALSE; +/* 8-byte FIFO */ +uint8 id_data[ID_FIFO_LEN] = {0}; +/* SRQM bit */ +t_bool id_srqm = FALSE; +/* The logical unit number (0-1) */ +uint8 id_unit_num = 0; +/* The physical unit number (0-3) */ +uint8 id_ua = 0; +/* Cylinder the drive is positioned on */ +uint16 id_cyl[ID_NUM_UNITS] = {0}; +/* Ending Track Number (from Specify) */ +uint8 id_etn = 0; +/* Ending Sector Number (from Specify) */ +uint8 id_esn = 0; +/* DTLH word (from Specify) */ +uint8 id_dtlh = 0; +/* Physical sector number */ +uint8 id_psn = 0; +/* Physical head number */ +uint8 id_phn = 0; +/* Logical cylinder number, high byte */ +uint8 id_lcnh = 0; +/* Logical cylinder number, low byte */ +uint8 id_lcnl = 0; +/* Logical head number */ +uint8 id_lhn = 0; +/* Logical sector number */ +uint8 id_lsn = 0; +/* Number of sectors to transfer, decremented after each sector */ +uint8 id_scnt = 0; +/* Whether we are using polling mode or not */ +t_bool id_polling = FALSE; +/* Sector buffer */ +uint8 id_buf[ID_SEC_SIZE]; +/* Buffer pointer */ +size_t id_buf_ptr = 0; + +uint8 id_idfield[ID_IDFIELD_LEN]; +uint8 id_idfield_ptr = 0; + +int8 id_seek_state[ID_NUM_UNITS] = {ID_SEEK_NONE}; + +struct id_dtype { + uint8 hd; /* Number of heads */ + uint32 capac; /* Capacity (in sectors) */ + const char *name; +}; + +static struct id_dtype id_dtab[] = { + ID_DRV(HD30), + ID_DRV(HD72), + ID_DRV(HD72C), + ID_DRV(HD135), + ID_DRV(HD161), + { 0 } +}; + +UNIT id_unit[] = { + { UDATA (&id_unit_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_BINK+ID_AUTOSIZE+ + (ID_HD72_DTYPE << ID_V_DTYPE), ID_DSK_SIZE(HD72)), 0, ID0, 0 }, + { UDATA (&id_unit_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_BINK+ID_AUTOSIZE+ + (ID_HD72_DTYPE << ID_V_DTYPE), ID_DSK_SIZE(HD72)), 0, ID1, 0 }, + { UDATA (&id_ctlr_svc, 0, 0) }, + { NULL } +}; + +UNIT *id_ctlr_unit = &id_unit[ID_CTLR]; + +/* The currently selected drive number */ +UNIT *id_sel_unit = &id_unit[ID0]; + +REG id_reg[] = { + { HRDATAD(CMD, id_cmd, 8, "Command") }, + { HRDATAD(STAT, id_status, 8, "Status") }, + { BRDATAD(CYL, id_cyl, 8, 8, ID_NUM_UNITS, "Track") }, + { NULL } +}; + +/* HD161 and HD135 are identical; the difference is only in the + * software being run on the emulator. SVR 2.0 will support a maximum + * of 1024 cylinders, so can only format the first 1024 cylinders of + * the HD135. SVR 3.0+ can support all 1224 cylinders of the HD161. */ +MTAB id_mod[] = { + { MTAB_XTD|MTAB_VUN, ID_HD30_DTYPE, NULL, "HD30", + &id_set_type, NULL, NULL, "Set HD30 Disk Type" }, + { MTAB_XTD|MTAB_VUN, ID_HD72_DTYPE, NULL, "HD72", + &id_set_type, NULL, NULL, "Set HD72 Disk Type" }, + { MTAB_XTD|MTAB_VUN, ID_HD72C_DTYPE, NULL, "HD72C", + &id_set_type, NULL, NULL, "Set HD72C Disk Type" }, + { MTAB_XTD|MTAB_VUN, ID_HD135_DTYPE, NULL, "HD135", + &id_set_type, NULL, NULL, "Set HD135 Disk Type" }, + { MTAB_XTD|MTAB_VUN, ID_HD161_DTYPE, NULL, "HD161", + &id_set_type, NULL, NULL, "Set HD161 Disk Type" }, + { MTAB_XTD|MTAB_VUN, 0, "TYPE", NULL, + NULL, &id_show_type, NULL, "Display device type" }, + { ID_AUTOSIZE, ID_AUTOSIZE, "autosize", "AUTOSIZE", + NULL, NULL, NULL, "Set type based on file size at attach" }, + { ID_AUTOSIZE, 0, "noautosize", "NOAUTOSIZE", + NULL, NULL, NULL, "Disable disk autosize on attach" }, + { 0 } +}; + +DEVICE id_dev = { + "IDISK", id_unit, id_reg, id_mod, + ID_NUM_UNITS, 16, 32, 1, 16, 8, + NULL, NULL, &id_reset, + NULL, &id_attach, &id_detach, NULL, + DEV_DEBUG|DEV_DISK|DEV_SECTORS, 0, sys_deb_tab, + NULL, NULL, &id_help, NULL, NULL, + &id_description +}; + +/* Function implementation */ + +#define UPDATE_INT { \ + if ((id_status & (ID_STAT_CEL|ID_STAT_CEH)) || \ + ((id_status & ID_STAT_SRQ) && !id_srqm)) { \ + CPU_SET_INT(INT_DISK); \ + } else { \ + CPU_CLR_INT(INT_DISK); \ + } \ + } + +static SIM_INLINE void id_set_status(uint8 flags) +{ + id_status |= flags; + UPDATE_INT; +} + +static SIM_INLINE void id_clr_status(uint8 flags) +{ + id_status &= ~(flags); + UPDATE_INT; +} + +static SIM_INLINE void id_set_srqm(t_bool state) +{ + id_srqm = state; + UPDATE_INT; +} + +static SIM_INLINE void id_clear_fifo() +{ + id_dpr = 0; + id_dpw = 0; +} + +static SIM_INLINE void id_activate(UNIT *uptr, int32 delay) +{ + sim_activate_abs(uptr, delay); +} + +/* + * Service routine for ID controller. + * + * The simulated HD controller must service Sense Interrupt Status, + * Specify, and Detect Error independent of the operation of either ID + * unit, which may be in the middle of a seek or other operation. + */ +t_stat id_ctlr_svc(UNIT *uptr) +{ + uint8 cmd; + + cmd = uptr->u4; /* The command that caused the activity */ + + id_set_srqm(FALSE); + id_clr_status(ID_STAT_CB); + id_set_status(ID_STAT_CEH); + uptr->u4 = 0; + + switch (cmd) { + case ID_CMD_SIS: + sim_debug(EXECUTE_MSG, &id_dev, + "INTR\t\tCOMPLETING Sense Interrupt Status.\n"); + id_data[0] = id_int_status; + id_int_status = 0; + break; + default: + sim_debug(EXECUTE_MSG, &id_dev, + "INTR\t\tCOMPLETING OTHER COMMAND 0x%x (CONTROLLER)\n", + cmd); + break; + } + + return SCPE_OK; +} + +/* + * Service routine for ID0 and ID1 units. + */ +t_stat id_unit_svc(UNIT *uptr) +{ + uint8 unit, other, cmd; + + unit = uptr->u3; /* The unit number that needs an interrupt */ + cmd = uptr->u4; /* The command that caused the activity */ + other = unit ^ 1; /* The number of the other unit */ + + /* If the other unit is active, we cannot interrupt, so we delay + * here */ + if (id_unit[other].u4 == ID_CMD_RDATA || + id_unit[other].u4 == ID_CMD_WDATA) { + id_activate(uptr, 1000); + return SCPE_OK; + } + + id_set_srqm(FALSE); + id_clr_status(ID_STAT_CB); + /* Note that we don't set CEH, in case this is a SEEK/RECAL ID_SEEK_1 */ + + switch (cmd) { + case ID_CMD_SEEK: /* fall-through */ + case ID_CMD_RECAL: + /* In POLLING mode, SEEK and RECAL actually interrupt twice. + * + * 1. Immediately after the correct number of stepping pulses + * have been issued (SRQ is not set) + * + * 2. After the drive has completed seeking and is ready + * for a new command (SRQ is set) + */ + if (id_polling) { + switch (id_seek_state[unit]) { + case ID_SEEK_0: + id_set_status(ID_STAT_CEH); + sim_debug(EXECUTE_MSG, &id_dev, + "INTR\t\tCOMPLETING Recal/Seek SEEK_0 UNIT %d\n", + unit); + id_seek_state[unit] = ID_SEEK_1; + id_activate(uptr, 8000); /* TODO: Correct Delay based on steps */ + break; + case ID_SEEK_1: + sim_debug(EXECUTE_MSG, &id_dev, + "INTR\t\tCOMPLETING Recal/Seek SEEK_1 UNIT %d\n", + unit); + id_seek_state[unit] = ID_SEEK_NONE; + id_set_status(ID_STAT_SRQ); + uptr->u4 = 0; /* Only clear out the command on a SEEK_1, never a SEEK_0 */ + if (uptr->flags & UNIT_ATT) { + id_int_status |= (ID_IST_SEN|unit); + } else { + id_int_status |= (ID_IST_NR|unit); + } + break; + default: + sim_debug(EXECUTE_MSG, &id_dev, + "INTR\t\tERROR, NOT SEEK_0 OR SEEK_1, UNIT %d\n", + unit); + break; + } + } else { + sim_debug(EXECUTE_MSG, &id_dev, + "INTR\t\tCOMPLETING NON-POLLING Recal/Seek UNIT %d\n", + unit); + id_set_status(ID_STAT_CEH); + uptr->u4 = 0; + if (uptr->flags & UNIT_ATT) { + id_int_status |= (ID_IST_SEN|unit); + } else { + id_int_status |= (ID_IST_NR|unit); + } + } + + break; + case ID_CMD_SUS: + sim_debug(EXECUTE_MSG, &id_dev, + "INTR\t\tCOMPLETING Sense Unit Status UNIT %d\n", + unit); + id_set_status(ID_STAT_CEH); + uptr->u4 = 0; + if ((uptr->flags & UNIT_ATT) == 0) { + /* If no HD is attached, SUS puts 0x00 into the data + buffer */ + id_data[0] = 0; + } else { + /* Put Unit Status into byte 0 */ + id_data[0] = (ID_UST_DSEL|ID_UST_SCL|ID_UST_RDY); + if (id_cyl[unit] == 0) { + id_data[0] |= ID_UST_TK0; + } + } + break; + default: + sim_debug(EXECUTE_MSG, &id_dev, + "INTR\t\tCOMPLETING OTHER COMMAND 0x%x UNIT %d\n", + cmd, unit); + id_set_status(ID_STAT_CEH); + uptr->u4 = 0; + break; + } + + return SCPE_OK; +} + +t_stat id_set_type(UNIT *uptr, int32 val, CONST char *cptr, void *desc) +{ + if (val < 0 || val > ID_MAX_DTYPE) { + return SCPE_ARG; + } + + if (uptr->flags & UNIT_ATT) { + return SCPE_ALATT; + } + + uptr->flags = (uptr->flags & ~ID_DTYPE) | (val << ID_V_DTYPE); + uptr->capac = (t_addr)id_dtab[val].capac; + + return SCPE_OK; +} + +t_stat id_show_type (FILE *st, UNIT *uptr, int32 val, CONST void *desc) +{ + fprintf (st, "%s", id_dtab[ID_GET_DTYPE(uptr->flags)].name); + return SCPE_OK; +} + +t_stat id_reset(DEVICE *dptr) +{ + id_clear_fifo(); + return SCPE_OK; +} + +t_stat id_attach(UNIT *uptr, CONST char *cptr) +{ + static const char *drives[] = {"HD30", "HD72", "HD72C", "HD135", "HD161", NULL}; + + return sim_disk_attach_ex(uptr, cptr, 512, 1, TRUE, 0, id_dtab[ID_GET_DTYPE(uptr->flags)].name, + 0, 0, (uptr->flags & ID_AUTOSIZE) ? drives : NULL); +} + +t_stat id_detach(UNIT *uptr) +{ + return sim_disk_detach(uptr); +} + +/* Return the logical block address of the given sector */ +static t_lba id_lba(uint16 cyl, uint8 head, uint8 sec) +{ + uint8 dtype; + + dtype = ID_GET_DTYPE(id_sel_unit->flags); + + return((ID_SEC_CNT * id_dtab[dtype].hd * cyl) + + (ID_SEC_CNT * head) + + sec); +} + +/* At the end of each sector read or write, we update the FIFO + * with the correct return parameters. */ +static void SIM_INLINE id_end_rw(uint8 est) +{ + id_clear_fifo(); + id_data[0] = est; + id_data[1] = id_phn; + id_data[2] = ~(id_lcnh); + id_data[3] = id_lcnl; + id_data[4] = id_lhn; + id_data[5] = id_lsn; + id_data[6] = id_scnt; +} + +/* The controller wraps id_lsn, id_lhn, and id_lcnl on each sector + * read, so that they point to the next C/H/S */ +static void SIM_INLINE id_update_chs() +{ + if (id_lsn++ >= id_esn) { + id_lsn = 0; + if (id_lhn++ >= id_etn) { + id_lhn = 0; + if (id_lcnl == 0xff) { + id_lcnl = 0; + id_lcnh++; + } else { + id_lcnl++; + } + } + } +} + +uint32 id_read(uint32 pa, size_t size) +{ + uint8 reg; + uint16 cyl; + t_lba lba; + uint32 data; + t_seccnt sectsread; + + reg = (uint8) (pa - IDBASE); + + switch(reg) { + case ID_DATA_REG: /* Data Buffer Register */ + /* If we're in a DMA transfer, we need to be reading data from + * the disk buffer. Otherwise, we're reading from the FIFO. */ + + if (id_drq) { + /* If the drive isn't attached, there's really nothing we + can do. */ + if ((id_sel_unit->flags & UNIT_ATT) == 0) { + id_end_rw(ID_EST_NR); + return 0; + } + + /* We could be in one of these commands: + * - Read Data + * - Read ID + */ + + if (CMD_NUM == ID_CMD_RDATA) { + /* If we're still in DRQ but we've read all our sectors, + * that's an error state. */ + if (id_scnt == 0) { + sim_debug(READ_MSG, &id_dev, + "ERROR\tid_scnt = 0 but still in dma\n"); + id_end_rw(ID_EST_OVR); + return 0; + } + + /* If the disk buffer is empty, fill it. */ + if (id_buf_ptr == 0 || id_buf_ptr >= ID_SEC_SIZE) { + /* It's time to read a new sector into our sector buf */ + id_buf_ptr = 0; + cyl = (uint16) (((uint16)id_lcnh << 8)|(uint16)id_lcnl); + id_cyl[id_unit_num] = cyl; + lba = id_lba(cyl, id_lhn, id_lsn); + if (sim_disk_rdsect(id_sel_unit, lba, id_buf, §sread, 1) == SCPE_OK) { + if (sectsread !=1) { + sim_debug(READ_MSG, &id_dev, + "ERROR: ASKED TO READ ONE SECTOR, READ: %d\n", + sectsread); + } + id_update_chs(); + } else { + /* Uh-oh! */ + sim_debug(READ_MSG, &id_dev, + "RDATA READ ERROR. Failure from sim_disk_rdsect!\n"); + id_end_rw(ID_EST_DER); + return 0; + } + } + + data = id_buf[id_buf_ptr++]; + sim_debug(READ_MSG, &id_dev, "DATA\t%02x\n", data); + + /* Done with this current sector, update id_scnt */ + if (id_buf_ptr >= ID_SEC_SIZE) { + if (--id_scnt == 0) { + id_end_rw(0); + } + } + } else if (CMD_NUM == ID_CMD_RID) { + /* We have to return the ID bytes for the current C/H/S */ + if (id_idfield_ptr == 0 || id_idfield_ptr >= ID_IDFIELD_LEN) { + id_idfield[0] = ~(id_lcnh); + id_idfield[1] = id_lcnl; + id_idfield[2] = id_lhn; + id_idfield[3] = id_lsn; + id_idfield_ptr = 0; + } + + data = id_idfield[id_idfield_ptr++]; + sim_debug(READ_MSG, &id_dev, + "ID DATA\t%02x\n", + data); + + if (id_idfield_ptr >= ID_IDFIELD_LEN) { + if (id_scnt-- > 0) { + /* Another sector to ID */ + id_idfield_ptr = 0; + } else { + /* All done, set return codes */ + id_clear_fifo(); + id_data[0] = 0; + id_data[1] = id_scnt; + } + } + } else { + /* cmd not Read Data or Read ID */ + stop_reason = STOP_ERR; + return 0; + } + + return data; + } else { + if (id_dpr < ID_FIFO_LEN) { + sim_debug(READ_MSG, &id_dev, + "DATA\t%02x\n", + id_data[id_dpr]); + return id_data[id_dpr++]; + } else { + sim_debug(READ_MSG, &id_dev, + "ERROR\tFIFO OVERRUN\n"); + return 0; + } + } + + break; + case ID_CMD_STAT_REG: /* Status Register */ + sim_debug(READ_MSG, &id_dev, + "STATUS\t%02x\n", + id_status|id_drq); + return id_status|(id_drq ? 1u : 0); + } + + sim_debug(READ_MSG, &id_dev, + "Read of unsuported register %x\n", + id_status); + + return 0; +} + +void id_write(uint32 pa, uint32 val, size_t size) +{ + uint8 reg; + uint16 cyl; + t_lba lba; + t_seccnt sectswritten; + + reg = (uint8) (pa - IDBASE); + + switch(reg) { + case ID_DATA_REG: + /* If we're in a DMA transfer, we need to be writing data to + * the disk buffer. Otherwise, we're writing to the FIFO. */ + + if (id_drq) { + /* If we're still in DRQ but we've written all our sectors, + * that's an error state. */ + if (id_scnt == 0) { + sim_debug(WRITE_MSG, &id_dev, + "ERROR\tid_scnt = 0 but still in dma\n"); + id_end_rw(ID_EST_OVR); + return; + } + + /* Write to the disk buffer */ + if (id_buf_ptr < ID_SEC_SIZE) { + id_buf[id_buf_ptr++] = (uint8)(val & 0xff); + sim_debug(WRITE_MSG, &id_dev, + "DATA\t%02x\n", + (uint8)(val & 0xff)); + } else { + sim_debug(WRITE_MSG, &id_dev, + "ERROR\tWDATA OVERRUN\n"); + id_end_rw(ID_EST_OVR); + return; + } + + /* If we've hit the end of a sector, flush it */ + if (id_buf_ptr >= ID_SEC_SIZE) { + /* It's time to start the next sector, and flush the old. */ + id_buf_ptr = 0; + cyl = (uint16) (((uint16) id_lcnh << 8)|(uint16)id_lcnl); + id_cyl[id_unit_num] = cyl; + lba = id_lba(cyl, id_lhn, id_lsn); + if (sim_disk_wrsect(id_sel_unit, lba, id_buf, §swritten, 1) == SCPE_OK) { + if (sectswritten !=1) { + sim_debug(WRITE_MSG, &id_dev, + "ERROR: ASKED TO WRITE ONE SECTOR, WROTE: %d\n", + sectswritten); + } + id_update_chs(); + if (--id_scnt == 0) { + id_end_rw(0); + } + } else { + /* Uh-oh! */ + sim_debug(WRITE_MSG, &id_dev, + "ERROR\tWDATA WRITE ERROR. lba=%04x\n", + lba); + id_end_rw(ID_EST_DER); + return; + } + } + return; + } else { + sim_debug(WRITE_MSG, &id_dev, + "DATA\t%02x\n", + val); + if (id_dpw < ID_FIFO_LEN) { + id_data[id_dpw++] = (uint8) val; + } else { + sim_debug(WRITE_MSG, &id_dev, + "ERROR\tFIFO OVERRUN\n"); + } + } + return; + case ID_CMD_STAT_REG: + id_handle_command((uint8) val); + return; + default: + return; + } +} + +void id_handle_command(uint8 val) +{ + uint8 cmd, aux_cmd, sec, pattern; + uint16 cyl; + uint32 time; + t_lba lba; + + /* Reset the FIFO pointer */ + id_clear_fifo(); + + /* Is this an aux command or a full command? */ + if ((val & 0xf0) == 0) { + aux_cmd = val & 0x0f; + + if (aux_cmd & ID_AUX_CLCE) { + sim_debug(WRITE_MSG, &id_dev, + "COMMAND\t%02x\tAUX:CLCE\n", + val); + id_clr_status(ID_STAT_CEH|ID_STAT_CEL); + } + + if (aux_cmd & ID_AUX_HSRQ) { + sim_debug(WRITE_MSG, &id_dev, + "COMMAND\t%02x\tAUX:HSRQ\n", + val); + id_set_srqm(TRUE); + } + + if (aux_cmd & ID_AUX_CLB) { + sim_debug(WRITE_MSG, &id_dev, + "COMMAND\t%02x\tAUX:CLBUF\n", + val); + id_clear_fifo(); + } + + if (aux_cmd & ID_AUX_RST) { + sim_debug(WRITE_MSG, &id_dev, + "COMMAND\t%02x\tAUX:RESET\n", + val); + id_clear_fifo(); + sim_cancel(id_sel_unit); + sim_cancel(id_ctlr_unit); + id_status = 0; + id_srqm = FALSE; + UPDATE_INT; + } + + /* Just return early */ + return; + } + + /* If the controller is busy and this isn't an AUX command, do + * nothing */ + if (id_status & ID_STAT_CB) { + sim_debug(EXECUTE_MSG, &id_dev, + "!!! Controller Busy. Skipping command byte %02x\n", + val); + return; + } + + /* A full command always resets CEH and CEL */ + id_clr_status(ID_STAT_CEH|ID_STAT_CEL); + + /* Save the full command byte */ + id_cmd = val; + cmd = (id_cmd >> 4) & 0xf; + + /* Now that we know it's not an aux command, we can get the unit + * number. Note that we don't update the unit in the case of three + * special commands. */ + if (cmd != ID_CMD_SIS && cmd != ID_CMD_SPEC && cmd != ID_CMD_DERR) { + if ((id_cmd & 3) != id_ua) { + id_unit_num = id_cmd & 1; + id_ua = id_cmd & 3; + id_sel_unit = &id_unit[id_unit_num]; + } + } + + /* TODO: Fix this hack */ + if (cmd == ID_CMD_SIS || cmd == ID_CMD_SPEC || cmd == ID_CMD_DERR) { + id_ctlr_unit->u4 = cmd; + } else { + id_sel_unit->u4 = cmd; + } + + id_set_status(ID_STAT_CB); + + switch(cmd) { + case ID_CMD_SIS: + sim_debug(WRITE_MSG, &id_dev, + "COMMAND\t%02x\tSense Int. Status\n", + val); + id_clr_status(ID_STAT_SRQ); /* SIS immediately de-asserts SRQ */ + id_activate(id_ctlr_unit, ID_SIS_WAIT); + break; + case ID_CMD_SPEC: + sim_debug(WRITE_MSG, &id_dev, + "COMMAND\t%02x\tSpecify - ETN=%02x ESN=%02x\n", + val, id_data[3], id_data[4]); + id_dtlh = id_data[1]; + id_etn = id_data[3]; + id_esn = id_data[4]; + id_polling = (id_dtlh & ID_DTLH_POLL) == 0; + id_activate(id_ctlr_unit, ID_SPEC_WAIT); + break; + case ID_CMD_SUS: + sim_debug(WRITE_MSG, &id_dev, + "COMMAND\t%02x\tSense Unit Status - %d\n", + val, id_ua); + id_activate(id_sel_unit, ID_SUS_WAIT); + break; + case ID_CMD_DERR: + sim_debug(WRITE_MSG, &id_dev, + "COMMAND\t%02x\tDetect Error\n", + val); + id_activate(id_ctlr_unit, ID_CMD_WAIT); + break; + case ID_CMD_RECAL: + time = id_cyl[id_unit_num]; + id_cyl[id_unit_num] = 0; + id_seek_state[id_unit_num] = ID_SEEK_0; + if (id_polling) { + sim_debug(WRITE_MSG, &id_dev, + "COMMAND\t%02x\tRecalibrate - %d - POLLING\n", + val, id_ua); + id_activate(id_sel_unit, 1000); + } else { + sim_debug(WRITE_MSG, &id_dev, + "COMMAND\t%02x\tRecalibrate - %d - NORMAL\n", + val, id_ua); + id_activate(id_sel_unit, (ID_RECAL_WAIT + (time * ID_SEEK_WAIT))); + } + break; + case ID_CMD_SEEK: + id_lcnh = id_data[0]; + id_lcnl = id_data[1]; + cyl = id_lcnh << 8 | id_lcnl; + time = (uint32) abs(id_cyl[id_unit_num] - cyl); + id_cyl[id_unit_num] = cyl; + id_seek_state[id_unit_num] = ID_SEEK_0; + + if (id_polling) { + sim_debug(WRITE_MSG, &id_dev, + "COMMAND\t%02x\tSeek - %d - POLLING\n", + val, id_ua); + id_activate(id_sel_unit, 4000); + } else { + sim_debug(WRITE_MSG, &id_dev, + "COMMAND\t%02x\tSeek - %d - NORMAL\n", + val, id_ua); + id_activate(id_sel_unit, ID_SEEK_BASE + (time * ID_SEEK_WAIT)); + } + break; + case ID_CMD_FMT: + sim_debug(WRITE_MSG, &id_dev, + "COMMAND\t%02x\tFormat - %d\n", + val, id_ua); + + id_phn = id_data[0]; + id_scnt = id_data[1]; + pattern = id_data[2]; + + /* Format scnt sectors with the given pattern, if attached */ + if (id_sel_unit->flags & UNIT_ATT) { + /* Formatting soft-sectored disks always begins at sector 0 */ + sec = 0; + + while (id_scnt-- > 0) { + /* Write one sector of pattern */ + for (id_buf_ptr = 0; id_buf_ptr < ID_SEC_SIZE; id_buf_ptr++) { + id_buf[id_buf_ptr] = pattern; + } + lba = id_lba(id_cyl[id_unit_num], id_phn, sec++); + if (sim_disk_wrsect(id_sel_unit, lba, id_buf, NULL, 1) == SCPE_OK) { + sim_debug(EXECUTE_MSG, &id_dev, + "FORMAT: PHN=%d SCNT=%d PAT=%02x LBA=%04x\n", + id_phn, id_scnt, pattern, lba); + } else { + sim_debug(EXECUTE_MSG, &id_dev, + "FORMAT FAILED! PHN=%d SCNT=%d PAT=%02x LBA=%04x\n", + id_phn, id_scnt, pattern, lba); + break; + } + } + + id_data[0] = 0; + } else { + /* Not attached */ + id_data[0] = ID_EST_NR; + } + + id_data[1] = id_scnt; + + id_activate(id_sel_unit, ID_CMD_WAIT); + break; + case ID_CMD_VID: + sim_debug(WRITE_MSG, &id_dev, + "COMMAND\t%02x\tVerify ID - %d\n", + val, id_ua); + id_data[0] = 0; + id_data[1] = 0x05; /* What do we put here? */ + id_activate(id_sel_unit, ID_CMD_WAIT); + break; + case ID_CMD_RID: + sim_debug(WRITE_MSG, &id_dev, + "COMMAND\t%02x\tRead ID - %d\n", + val, id_ua); + if (id_sel_unit->flags & UNIT_ATT) { + id_drq = TRUE; + + /* Grab our arguments */ + id_phn = id_data[0]; + id_scnt = id_data[1]; + + /* Compute logical values used by ID verification */ + id_lhn = id_phn; + id_lsn = 0; + } else { + sim_debug(EXECUTE_MSG, &id_dev, + "UNIT %d NOT ATTACHED, CANNOT READ ID.\n", + id_ua); + } + id_activate(id_sel_unit, ID_CMD_WAIT); + break; + case ID_CMD_RDIAG: + sim_debug(WRITE_MSG, &id_dev, + "COMMAND\t%02x\tRead Diag - %d\n", + val, id_ua); + id_activate(id_sel_unit, ID_CMD_WAIT); + break; + case ID_CMD_RDATA: + sim_debug(WRITE_MSG, &id_dev, + "COMMAND\t%02x\tRead Data - %d\n", + val, id_ua); + if (id_sel_unit->flags & UNIT_ATT) { + id_drq = TRUE; + id_buf_ptr = 0; + + /* Grab our arguments */ + id_phn = id_data[0]; + id_lcnh = ~(id_data[1]); + id_lcnl = id_data[2]; + id_lhn = id_data[3]; + id_lsn = id_data[4]; + id_scnt = id_data[5]; + } else { + sim_debug(EXECUTE_MSG, &id_dev, + "UNIT %d NOT ATTACHED, CANNOT READ DATA.\n", + id_ua); + } + id_activate(id_sel_unit, ID_RW_WAIT); + break; + case ID_CMD_CHECK: + sim_debug(WRITE_MSG, &id_dev, + "COMMAND\t%02x\tCheck - %d\n", + val, id_ua); + id_activate(id_sel_unit, ID_CMD_WAIT); + break; + case ID_CMD_SCAN: + sim_debug(WRITE_MSG, &id_dev, + "COMMAND\t%02x\tScan - %d\n", + val, id_ua); + id_activate(id_sel_unit, ID_CMD_WAIT); + break; + case ID_CMD_VDATA: + sim_debug(WRITE_MSG, &id_dev, + "COMMAND\t%02x\tVerify Data - %d\n", + val, id_ua); + id_activate(id_sel_unit, ID_CMD_WAIT); + break; + case ID_CMD_WDATA: + sim_debug(WRITE_MSG, &id_dev, + "COMMAND\t%02x\tWrite Data - %d\n", + val, id_ua); + if (id_sel_unit->flags & UNIT_ATT) { + id_drq = TRUE; + id_buf_ptr = 0; + + /* Grab our arguments */ + id_phn = id_data[0]; + id_lcnh = ~(id_data[1]); + id_lcnl = id_data[2]; + id_lhn = id_data[3]; + id_lsn = id_data[4]; + id_scnt = id_data[5]; + } else { + sim_debug(EXECUTE_MSG, &id_dev, + "UNIT %d NOT ATTACHED, CANNOT WRITE.\n", + id_ua); + } + id_activate(id_sel_unit, ID_RW_WAIT); + break; + } +} + +void id_after_dma() +{ + id_clr_status(ID_STAT_DRQ); + id_drq = FALSE; +} + +CONST char *id_description(DEVICE *dptr) +{ + return "Integrated Hard Disk"; +} + +t_stat id_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr) +{ + fprintf(st, "Integrated Hard Disk (IDISK)\n\n"); + fprintf(st, "The IDISK device implements the integrated MFM hard disk of the\n"); + fprintf(st, "3B2/400. Up to two drives are supported on a single controller.\n\n"); + fprintf(st, "Supported device types are:\n\n"); + fprintf(st, " Name Size ID Cyl Head Sec Byte/Sec Description\n"); + fprintf(st, " ---- -------- -- ---- ---- --- -------- ----------------------\n"); + fprintf(st, " HD30 30.6 MB 3 697 5 18 512 CDC Wren 94155-36\n"); + fprintf(st, " HD72 73.2 MB 5 925 9 18 512 CDC Wren II 94156-86\n"); + fprintf(st, " HD72C 72.9 MB 8 754 11 18 512 Fujitsu M2243AS\n"); + fprintf(st, " HD135 135.0 MB 11 1024 15 18 512 Maxtor XT1190 (SVR2)\n"); + fprintf(st, " HD161 161.4 MB 11 1224 15 18 512 Maxtor XT1190 (SVR3+)\n\n"); + fprintf(st, "The drive ID and geometry values are used when low-level formatting a\n"); + fprintf(st, "drive using the AT&T 'idtools' utility.\n"); + + fprint_set_help(st, dptr); + fprint_show_help(st, dptr); + fprint_reg_help(st, dptr); + + return SCPE_OK; +} diff --git a/3B2/3b2_id.h b/3B2/3b2_id.h index cecc4830..08ecf98e 100644 --- a/3B2/3b2_id.h +++ b/3B2/3b2_id.h @@ -1,178 +1,178 @@ -/* 3b2_id.h: AT&T 3B2 Model 400 Hard Disk (uPD7261) Header - - Copyright (c) 2017, Seth J. Morabito - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - - Except as contained in this notice, the name of the author shall - not be used in advertising or otherwise to promote the sale, use or - other dealings in this Software without prior written authorization - from the author. -*/ - -#ifndef __3B2_ID_H__ -#define __3B2_ID_H__ - -#include "3b2_defs.h" - -#define ID0 0 -#define ID1 1 -#define ID_CTLR 2 - -/* Command Codes (bits 3-7 of command byte) */ - -#define ID_CMD_AUX 0x00 /* Auxiliary Command */ -#define ID_CMD_SIS 0x01 /* Sense int. status */ -#define ID_CMD_SPEC 0x02 /* Specify */ -#define ID_CMD_SUS 0x03 /* Sense unit status */ -#define ID_CMD_DERR 0x04 /* Detect Error */ -#define ID_CMD_RECAL 0x05 /* Recalibrate */ -#define ID_CMD_SEEK 0x06 /* Seek */ -#define ID_CMD_FMT 0x07 /* Format */ -#define ID_CMD_VID 0x08 /* Verify ID */ -#define ID_CMD_RID 0x09 /* Read ID */ -#define ID_CMD_RDIAG 0x0A /* Read Diagnostic */ -#define ID_CMD_RDATA 0x0B /* Read Data */ -#define ID_CMD_CHECK 0x0C /* Check */ -#define ID_CMD_SCAN 0x0D /* Scan */ -#define ID_CMD_VDATA 0x0E /* Verify Data */ -#define ID_CMD_WDATA 0x0F /* Write Data */ - -#define ID_AUX_RST 0x01 -#define ID_AUX_CLB 0x02 -#define ID_AUX_HSRQ 0x04 -#define ID_AUX_CLCE 0x08 - -#define ID_STAT_DRQ 0x01 -#define ID_STAT_NCI 0x02 -#define ID_STAT_IER 0x04 -#define ID_STAT_RRQ 0x08 -#define ID_STAT_SRQ 0x10 -#define ID_STAT_CEL 0x20 -#define ID_STAT_CEH 0x40 -#define ID_STAT_CB 0x80 - -#define ID_IST_SEN 0x80 /* Seek End */ -#define ID_IST_RC 0x40 /* Ready Change */ -#define ID_IST_SER 0x20 /* Seek Error */ -#define ID_IST_EQC 0x10 /* Equipment Check */ -#define ID_IST_NR 0x08 /* Not Ready */ - -#define ID_UST_DSEL 0x10 /* Drive Selected */ -#define ID_UST_SCL 0x08 /* Seek Complete */ -#define ID_UST_TK0 0x04 /* Track 0 */ -#define ID_UST_RDY 0x02 /* Ready */ -#define ID_UST_WFL 0x01 /* Write Fault */ - -#define ID_EST_ENC 0x80 -#define ID_EST_OVR 0x40 -#define ID_EST_DER 0x20 -#define ID_EST_EQC 0x10 -#define ID_EST_NR 0x08 -#define ID_EST_ND 0x04 -#define ID_EST_NWR 0x02 -#define ID_EST_MAM 0x01 - -#define ID_DTLH_POLL 0x10 - -#define ID_SEEK_NONE -1 -#define ID_SEEK_0 0 -#define ID_SEEK_1 1 - -/* Drive Geometries */ - -/* Common across all drive types */ -#define ID_SEC_SIZE 512 -#define ID_SEC_CNT 18 -#define ID_CYL_SIZE ID_SEC_SIZE * ID_SEC_CNT - -/* Specific to each drive type */ -#define ID_MAX_DTYPE 3 - -#define ID_HD30_DTYPE 0 -#define ID_HD30_CYL 697 -#define ID_HD30_HEADS 5 -#define ID_HD30_LBN 62730 - -#define ID_HD72_DTYPE 1 -#define ID_HD72_CYL 925 -#define ID_HD72_HEADS 9 -#define ID_HD72_LBN 149850 - -#define ID_HD72C_DTYPE 2 -#define ID_HD72C_CYL 754 -#define ID_HD72C_HEADS 11 -#define ID_HD72C_LBN 149292 - -/* The HD135 is actually just an HD161 with only 1024 cylinders - * formatted. This is a software limitation, not hardware. */ - -#define ID_HD135_DTYPE 3 -#define ID_HD135_CYL 1224 -#define ID_HD135_HEADS 15 -#define ID_HD135_LBN 330480 - -#define ID_HD161_DTYPE 3 -#define ID_HD161_CYL 1224 -#define ID_HD161_HEADS 15 -#define ID_HD161_LBN 330480 - -#define ID_V_DTYPE (DKUF_V_UF + 0) -#define ID_M_DTYPE 3 -#define ID_DTYPE (ID_M_DTYPE << ID_V_DTYPE) -#define ID_V_AUTOSIZE (ID_V_DTYPE + 2) -#define ID_AUTOSIZE (1 << ID_V_AUTOSIZE) -#define ID_GET_DTYPE(x) (((x) >> ID_V_DTYPE) & ID_M_DTYPE) -#define ID_DRV(d) { ID_##d##_HEADS, ID_##d##_LBN, #d } - -#define ID_DSK_SIZE(d) ID_##d##_LBN - -/* Unit, Register, Device descriptions */ - -#define ID_FIFO_LEN 8 -#define ID_IDFIELD_LEN 4 - -#define ID_NUM_UNITS 2 - -#define DMA_ID_SVC IDBASE+ID_DATA_REG - -#define CMD_NUM ((id_cmd >> 4) & 0xf) - -/* Function prototypes */ - -t_stat id_ctlr_svc(UNIT *uptr); -t_stat id_unit_svc(UNIT *uptr); -t_stat id_reset(DEVICE *dptr); -t_stat id_set_type(UNIT *uptr, int32 val, CONST char *cptr, void *desc); -t_stat id_show_type (FILE *st, UNIT *uptr, int32 val, CONST void *desc); -t_stat id_attach(UNIT *uptr, CONST char *cptr); -t_stat id_detach(UNIT *uptr); -uint32 id_read(uint32 pa, size_t size); -void id_write(uint32 pa, uint32 val, size_t size); -CONST char *id_description(DEVICE *dptr); -t_stat id_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr); -void id_handle_data(uint8 val); -void id_handle_command(uint8 val); -void id_after_dma(); - -extern t_bool id_drq; - -#endif +/* 3b2_id.h: uPD7261 Integrated Disk Controller + + Copyright (c) 2017-2022, Seth J. Morabito + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + Except as contained in this notice, the name of the author shall + not be used in advertising or otherwise to promote the sale, use or + other dealings in this Software without prior written authorization + from the author. +*/ + +#ifndef __3B2_ID_H__ +#define __3B2_ID_H__ + +#include "3b2_defs.h" + +#define ID0 0 +#define ID1 1 +#define ID_CTLR 2 + +/* Command Codes (bits 3-7 of command byte) */ + +#define ID_CMD_AUX 0x00 /* Auxiliary Command */ +#define ID_CMD_SIS 0x01 /* Sense int. status */ +#define ID_CMD_SPEC 0x02 /* Specify */ +#define ID_CMD_SUS 0x03 /* Sense unit status */ +#define ID_CMD_DERR 0x04 /* Detect Error */ +#define ID_CMD_RECAL 0x05 /* Recalibrate */ +#define ID_CMD_SEEK 0x06 /* Seek */ +#define ID_CMD_FMT 0x07 /* Format */ +#define ID_CMD_VID 0x08 /* Verify ID */ +#define ID_CMD_RID 0x09 /* Read ID */ +#define ID_CMD_RDIAG 0x0A /* Read Diagnostic */ +#define ID_CMD_RDATA 0x0B /* Read Data */ +#define ID_CMD_CHECK 0x0C /* Check */ +#define ID_CMD_SCAN 0x0D /* Scan */ +#define ID_CMD_VDATA 0x0E /* Verify Data */ +#define ID_CMD_WDATA 0x0F /* Write Data */ + +#define ID_AUX_RST 0x01 +#define ID_AUX_CLB 0x02 +#define ID_AUX_HSRQ 0x04 +#define ID_AUX_CLCE 0x08 + +#define ID_STAT_DRQ 0x01 +#define ID_STAT_NCI 0x02 +#define ID_STAT_IER 0x04 +#define ID_STAT_RRQ 0x08 +#define ID_STAT_SRQ 0x10 +#define ID_STAT_CEL 0x20 +#define ID_STAT_CEH 0x40 +#define ID_STAT_CB 0x80 + +#define ID_IST_SEN 0x80 /* Seek End */ +#define ID_IST_RC 0x40 /* Ready Change */ +#define ID_IST_SER 0x20 /* Seek Error */ +#define ID_IST_EQC 0x10 /* Equipment Check */ +#define ID_IST_NR 0x08 /* Not Ready */ + +#define ID_UST_DSEL 0x10 /* Drive Selected */ +#define ID_UST_SCL 0x08 /* Seek Complete */ +#define ID_UST_TK0 0x04 /* Track 0 */ +#define ID_UST_RDY 0x02 /* Ready */ +#define ID_UST_WFL 0x01 /* Write Fault */ + +#define ID_EST_ENC 0x80 +#define ID_EST_OVR 0x40 +#define ID_EST_DER 0x20 +#define ID_EST_EQC 0x10 +#define ID_EST_NR 0x08 +#define ID_EST_ND 0x04 +#define ID_EST_NWR 0x02 +#define ID_EST_MAM 0x01 + +#define ID_DTLH_POLL 0x10 + +#define ID_SEEK_NONE -1 +#define ID_SEEK_0 0 +#define ID_SEEK_1 1 + +/* Drive Geometries */ + +/* Common across all drive types */ +#define ID_SEC_SIZE 512 +#define ID_SEC_CNT 18 +#define ID_CYL_SIZE ID_SEC_SIZE * ID_SEC_CNT + +/* Specific to each drive type */ +#define ID_MAX_DTYPE 3 + +#define ID_HD30_DTYPE 0 +#define ID_HD30_CYL 697 +#define ID_HD30_HEADS 5 +#define ID_HD30_LBN 62730 + +#define ID_HD72_DTYPE 1 +#define ID_HD72_CYL 925 +#define ID_HD72_HEADS 9 +#define ID_HD72_LBN 149850 + +#define ID_HD72C_DTYPE 2 +#define ID_HD72C_CYL 754 +#define ID_HD72C_HEADS 11 +#define ID_HD72C_LBN 149292 + +/* The HD135 is actually just an HD161 with only 1024 cylinders + * formatted. This is a software limitation, not hardware. */ + +#define ID_HD135_DTYPE 3 +#define ID_HD135_CYL 1224 +#define ID_HD135_HEADS 15 +#define ID_HD135_LBN 330480 + +#define ID_HD161_DTYPE 3 +#define ID_HD161_CYL 1224 +#define ID_HD161_HEADS 15 +#define ID_HD161_LBN 330480 + +#define ID_V_DTYPE (DKUF_V_UF + 0) +#define ID_M_DTYPE 3 +#define ID_DTYPE (ID_M_DTYPE << ID_V_DTYPE) +#define ID_V_AUTOSIZE (ID_V_DTYPE + 2) +#define ID_AUTOSIZE (1 << ID_V_AUTOSIZE) +#define ID_GET_DTYPE(x) (((x) >> ID_V_DTYPE) & ID_M_DTYPE) +#define ID_DRV(d) { ID_##d##_HEADS, ID_##d##_LBN, #d } + +#define ID_DSK_SIZE(d) ID_##d##_LBN + +/* Unit, Register, Device descriptions */ + +#define ID_FIFO_LEN 8 +#define ID_IDFIELD_LEN 4 + +#define ID_NUM_UNITS 2 + +#define DMA_ID_SVC IDBASE+ID_DATA_REG + +#define CMD_NUM ((id_cmd >> 4) & 0xf) + +/* Function prototypes */ + +t_stat id_ctlr_svc(UNIT *uptr); +t_stat id_unit_svc(UNIT *uptr); +t_stat id_reset(DEVICE *dptr); +t_stat id_set_type(UNIT *uptr, int32 val, CONST char *cptr, void *desc); +t_stat id_show_type (FILE *st, UNIT *uptr, int32 val, CONST void *desc); +t_stat id_attach(UNIT *uptr, CONST char *cptr); +t_stat id_detach(UNIT *uptr); +uint32 id_read(uint32 pa, size_t size); +void id_write(uint32 pa, uint32 val, size_t size); +CONST char *id_description(DEVICE *dptr); +t_stat id_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr); +void id_handle_data(uint8 val); +void id_handle_command(uint8 val); +void id_after_dma(); + +extern t_bool id_drq; + +#endif diff --git a/3B2/3b2_if.c b/3B2/3b2_if.c index 6512d5b3..a97cb94d 100644 --- a/3B2/3b2_if.c +++ b/3B2/3b2_if.c @@ -1,640 +1,645 @@ -/* 3b2_if.c: AT&T 3B2 Floppy Controller (TMS2797NL) Implementation - - Copyright (c) 2017, Seth J. Morabito - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - - Except as contained in this notice, the name of the author shall - not be used in advertising or otherwise to promote the sale, use or - other dealings in this Software without prior written authorization - from the author. -*/ - -#include "3b2_if.h" - -#include "sim_disk.h" - -#include "3b2_cpu.h" -#include "3b2_csr.h" - -/* Static function declarations */ -static SIM_INLINE uint32 if_lba(); - -/* - * Disk Format: - * ------------ - * - * - 80 Tracks - * - 9 Sectors per track - * - 2 heads - * - 512 bytes per sector - * - * 80 * 9 * 2 * 512 = 720KB - * - */ - -#define IF_STEP_DELAY 3000 /* us */ -#define IF_R_DELAY 65000 /* us */ -#define IF_W_DELAY 70000 /* us */ -#define IF_VERIFY_DELAY 20000 /* us */ -#define IF_HLD_DELAY 60000 /* us */ -#define IF_HSW_DELAY 40000 /* us */ - -#if defined(REV3) -#define SET_INT CPU_SET_INT(INT_FLOPPY) -#define CLR_INT CPU_CLR_INT(INT_FLOPPY) -#else -#define SET_INT do { \ - CPU_SET_INT(INT_FLOPPY); \ - SET_CSR(CSRDISK); \ - } while(0) -#define CLR_INT do { \ - CPU_CLR_INT(INT_FLOPPY); \ - CLR_CSR(CSRDISK); \ - } while(0) -#endif - -UNIT if_unit = { - UDATA (&if_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_BINK+UNIT_ROABLE, - IF_DSK_SIZE_SECS) -}; - -REG if_reg[] = { - { NULL } -}; - -DEVICE if_dev = { - "IFLOPPY", &if_unit, if_reg, NULL, - 1, 16, 8, 1, 16, 8, - NULL, NULL, &if_reset, - NULL, &if_attach, &if_detach, NULL, - DEV_DEBUG|DEV_DISK|DEV_SECTORS, 0, sys_deb_tab, - NULL, NULL, &if_help, NULL, NULL, - &if_description -}; - -IF_STATE if_state; -uint8 if_buf[IF_SEC_SIZE]; -uint32 if_sec_ptr = 0; - -/* Function implementation */ - -static SIM_INLINE void if_activate(uint32 delay) -{ - sim_activate_abs(&if_unit, delay); -} - -t_stat if_svc(UNIT *uptr) -{ - uint32 lba; /* Logical block address for write */ - t_seccnt sectswritten; - - if_state.status &= ~(IF_BUSY); - - switch(if_state.cmd & 0xf0) { - case IF_RESTORE: - if_state.status = (IF_TK_0|IF_HEAD_LOADED); - break; - case IF_SEEK: - if_state.status = IF_HEAD_LOADED; - if (if_state.track == 0) { - if_state.status |= IF_TK_0; - } - break; - case IF_WRITE_SEC: - lba = if_lba(); - - /* If we're read-only, don't actually do anything. */ - if (if_unit.flags & UNIT_RO) { - break; - } - - if (sim_disk_wrsect(&if_unit, lba, if_buf, §swritten, 1) == SCPE_OK) { - if (sectswritten != 1) { - sim_debug(EXECUTE_MSG, &if_dev, - "ERROR: ASKED TO wRITE ONE SECTOR, WROTE %d\n", - sectswritten); - } - } - - break; - } - - if_state.cmd = 0; - - /* Request an interrupt */ - sim_debug(IRQ_MSG, &if_dev, "\tINTR\n"); - SET_INT; - - return SCPE_OK; -} - -t_stat if_reset(DEVICE *dptr) -{ - if_state.status = IF_TK_0; - if_state.track = 0; - if_state.sector = 1; - if_sec_ptr = 0; - - return SCPE_OK; -} - -t_stat if_attach(UNIT *uptr, CONST char *cptr) -{ - return sim_disk_attach(uptr, cptr, 512, 1, TRUE, 0, NULL, 0, 0); -} - -t_stat if_detach(UNIT *uptr) -{ - return sim_disk_detach(uptr); -} - -uint32 if_read(uint32 pa, size_t size) { - uint8 reg, data; - UNIT *uptr; - - uptr = &(if_dev.units[0]); - reg = (uint8)(pa - IFBASE); - - switch (reg) { - case IF_STATUS_REG: - data = if_state.status; - /* If there's no image attached, we're not ready */ - if ((uptr->flags & (UNIT_ATT|UNIT_BUF)) == 0) { - data |= IF_NRDY; - } - /* Reading the status register always de-asserts the IRQ line */ - CLR_INT; - sim_debug(READ_MSG, &if_dev, "\tSTATUS\t%02x\n", data); - break; - case IF_TRACK_REG: - data = if_state.track; - sim_debug(READ_MSG, &if_dev, "\tTRACK\t%02x\n", data); - break; - case IF_SECTOR_REG: - data = if_state.sector; - sim_debug(READ_MSG, &if_dev, "\tSECTOR\t%02x\n", data); - break; - case IF_DATA_REG: - if_state.status &= ~IF_DRQ; - - if (((uptr->flags & (UNIT_ATT|UNIT_BUF)) == 0) || - ((if_state.cmd & 0xf0) != IF_READ_SEC && - (if_state.cmd & 0xf0) != IF_READ_SEC_M)) { - /* Not attached, or not a read command */ - - switch (if_state.cmd & 0xf0) { - case IF_READ_ADDR: - /* Special state machine. */ - switch (if_state.read_addr_ptr++) { - case 0: - if_state.data = if_state.track; - break; - case 1: - if_state.data = if_state.side; - break; - case 2: - if_state.data = if_state.sector; - break; - case 3: - if_state.data = 2; /* 512 byte */ - break; - case 4: - /* TODO: Checksum */ - if_state.data = 0; - break; - case 5: - /* TODO: Checksum */ - if_state.data = 0; - if_state.read_addr_ptr = 0; - break; - } - } - - sim_debug(READ_MSG, &if_dev, "\tDATA\t%02x\n", if_state.data); - return if_state.data; - } - - data = if_buf[if_sec_ptr++]; - sim_debug(READ_MSG, &if_dev, "\tDATA\t%02x\n", data); - - if (if_sec_ptr >= IF_SEC_SIZE) { - if_sec_ptr = 0; - } - - break; - default: - data = 0xffu; // Compiler warning - break; - } - - return data; -} - -/* Handle the most recently received command */ -void if_handle_command() -{ - uint32 delay_ms = 0; - uint32 head_switch_delay = 0; - uint32 head_load_delay = 0; - uint32 lba; /* Logical block address */ - t_seccnt sectsread; - - if_sec_ptr = 0; - - /* We're starting a new command. */ - if_state.status = IF_BUSY; - - /* Clear read addr state */ - if_state.read_addr_ptr = 0; - - switch(if_state.cmd & 0xf0) { - case IF_RESTORE: - case IF_SEEK: - case IF_STEP: - case IF_STEP_T: - case IF_STEP_IN: - case IF_STEP_IN_T: - case IF_STEP_OUT: - case IF_STEP_OUT_T: - if_state.cmd_type = 1; - if (if_state.cmd & IF_H_FLAG) { - head_load_delay = IF_HLD_DELAY; - } - break; - - case IF_READ_SEC: - case IF_READ_SEC_M: - case IF_WRITE_SEC: - case IF_WRITE_SEC_M: - if_state.cmd_type = 2; -#if defined(REV2) - if (((if_state.cmd & IF_U_FLAG) >> 1) != if_state.side) { - head_switch_delay = IF_HSW_DELAY; - if_state.side = (if_state.cmd & IF_U_FLAG) >> 1; - } -#endif - break; - - case IF_READ_ADDR: - case IF_READ_TRACK: - case IF_WRITE_TRACK: - if_state.cmd_type = 3; -#if defined(REV2) - if (((if_state.cmd & IF_U_FLAG) >> 1) != if_state.side) { - head_switch_delay = IF_HSW_DELAY; - if_state.side = (if_state.cmd & IF_U_FLAG) >> 1; - } -#endif - break; - } - - switch(if_state.cmd & 0xf0) { - case IF_RESTORE: - sim_debug(EXECUTE_MSG, &if_dev, "\tCOMMAND\t%02x\tRestore\n", if_state.cmd); - - /* Reset HLT */ - if_state.status &= ~IF_HEAD_LOADED; - - if (if_unit.flags & UNIT_RO) { - if_state.status |= IF_WP; - } - - /* If head should be loaded immediately, do so now */ - if (if_state.cmd & IF_H_FLAG) { - if_state.status |= IF_HEAD_LOADED; - } - - if (if_state.track == 0) { - if_state.status |= IF_TK_0; - if_state.track = 1; /* Kind of a gross hack */ - } - - if (if_state.cmd & IF_V_FLAG) { - delay_ms = (IF_STEP_DELAY * if_state.track) + IF_VERIFY_DELAY; - } else { - delay_ms = IF_STEP_DELAY * if_state.track; - } - - if_activate(delay_ms); - - if_state.data = 0; - if_state.track = 0; - break; - - case IF_STEP: - case IF_STEP_T: - sim_debug(EXECUTE_MSG, &if_dev, "\tCOMMAND\t%02x\tStep\n", if_state.cmd); - if (if_unit.flags & UNIT_RO) { - if_state.status |= IF_WP; - } - if_activate(IF_STEP_DELAY); - if_state.track = (uint8) MIN(MAX((int) if_state.track + if_state.step_dir, 0), 0x4f); - break; - case IF_STEP_IN: - case IF_STEP_IN_T: - sim_debug(EXECUTE_MSG, &if_dev, "\tCOMMAND\t%02x\tStep In\n", if_state.cmd); - if (if_unit.flags & UNIT_RO) { - if_state.status |= IF_WP; - } - if_state.step_dir = IF_STEP_IN_DIR; - if_state.track = (uint8) MAX((int) if_state.track + if_state.step_dir, 0); - if_activate(IF_STEP_DELAY); - break; - case IF_STEP_OUT: - case IF_STEP_OUT_T: - sim_debug(EXECUTE_MSG, &if_dev, "\tCOMMAND\t%02x\tStep Out\n", if_state.cmd); - if (if_unit.flags & UNIT_RO) { - if_state.status |= IF_WP; - } - if_state.step_dir = IF_STEP_OUT_DIR; - if_state.track = (uint8) MIN((int) if_state.track + if_state.step_dir, 0x4f); - if_activate(IF_STEP_DELAY); - break; - case IF_SEEK: - sim_debug(EXECUTE_MSG, &if_dev, "\tCOMMAND\t%02x\tSeek\n", if_state.cmd); - - /* Reset HLT */ - if_state.status &= ~IF_HEAD_LOADED; - - if (if_unit.flags & UNIT_RO) { - if_state.status |= IF_WP; - } - - /* If head should be loaded immediately, do so now */ - if (if_state.cmd & IF_H_FLAG) { - if_state.status |= IF_HEAD_LOADED; - } - - /* Save the direction for stepping */ - if (if_state.data > if_state.track) { - if_state.step_dir = IF_STEP_IN_DIR; - } else if (if_state.data < if_state.track) { - if_state.step_dir = IF_STEP_OUT_DIR; - } - - /* The new track is in the data register */ - - if (if_state.data > IF_TRACK_COUNT-1) { - if_state.data = IF_TRACK_COUNT-1; - } - - if (if_state.data == 0) { - if_state.status |= IF_TK_0; - } else { - if_state.status &= ~(IF_TK_0); - } - - delay_ms = (uint32) abs(if_state.data - if_state.track); - - if (delay_ms == 0) { - delay_ms++; - } - - if (if_state.cmd & IF_V_FLAG) { - if_activate((IF_STEP_DELAY * delay_ms) + IF_VERIFY_DELAY + head_load_delay); - } else { - if_activate((IF_STEP_DELAY * delay_ms) + head_load_delay); - } - - if_state.track = if_state.data; - break; - - case IF_READ_SEC: - lba = if_lba(); - - sim_debug(EXECUTE_MSG, &if_dev, "\tCOMMAND\t%02x\tRead Sector %d/%d/%d (lba=%d)\n", - if_state.cmd, if_state.track, if_state.side, if_state.sector, lba); - - if (sim_disk_rdsect(&if_unit, lba, if_buf, §sread, 1) == SCPE_OK) { - if (sectsread != 1) { - sim_debug(EXECUTE_MSG, &if_dev, - "ERROR: ASKED TO READ ONE SECTOR, READ %d\n", - sectsread); - } - /* We set DRQ right away to request the transfer. */ - if_state.drq = TRUE; - if_state.status |= IF_DRQ; - if (if_state.cmd & IF_E_FLAG) { - if_activate(IF_R_DELAY + IF_VERIFY_DELAY + head_switch_delay); - } else { - if_activate(IF_R_DELAY + head_switch_delay); - } - } - - break; - case IF_READ_SEC_M: - /* Not yet implemented. Halt the emulator. */ - sim_debug(EXECUTE_MSG, &if_dev, - "\tCOMMAND\t%02x\tRead Sector (Multi) - NOT IMPLEMENTED\n", - if_state.cmd); - stop_reason = STOP_ERR; - break; - case IF_WRITE_SEC: - lba = if_lba(); - - sim_debug(EXECUTE_MSG, &if_dev, "\tCOMMAND\t%02x\tWrite Sector %d/%d/%d (lba=%d)\n", - if_state.cmd, if_state.track, if_state.side, if_state.sector, lba); - - if (if_unit.flags & UNIT_RO) { - if_state.status |= IF_WP; - sim_debug(EXECUTE_MSG, &if_dev, "\tWON'T WRITE: WRITE PROTECTED.\n"); - /* Still cause an interrupt... */ - if_activate(IF_W_DELAY + head_switch_delay); - /* But don't set DRQ and ask for a transfer. */ - break; - } - - /* We set DRQ right away to request the transfer. Data will - * be written by the host into our buffer by 512 writes to the - * data register. When the IF device later activates, the data - * will actually be written. */ - if_state.drq = TRUE; - if_state.status |= IF_DRQ; - if (if_state.cmd & IF_E_FLAG) { - if_activate(IF_W_DELAY + IF_VERIFY_DELAY + head_switch_delay); - } else { - if_activate(IF_W_DELAY + head_switch_delay); - } - break; - case IF_WRITE_SEC_M: - /* Not yet implemented. Halt the emulator. */ - sim_debug(EXECUTE_MSG, &if_dev, - "\tCOMMAND\t%02x\tWrite Sector (Multi) - NOT IMPLEMENTED\n", - if_state.cmd); - stop_reason = STOP_ERR; - break; - case IF_READ_ADDR: - sim_debug(EXECUTE_MSG, &if_dev, "\tCOMMAND\t%02x\tRead Address\n", if_state.cmd); - if_state.drq = TRUE; - if_state.status |= IF_DRQ; - if_activate(IF_R_DELAY); - break; - case IF_READ_TRACK: - sim_debug(EXECUTE_MSG, &if_dev, "\tCOMMAND\t%02x\tRead Track\n", if_state.cmd); - /* Not yet implemented. Halt the emulator. */ - stop_reason = STOP_ERR; - break; - case IF_WRITE_TRACK: - sim_debug(EXECUTE_MSG, &if_dev, "\tCOMMAND\t%02x\tWrite Track\n", if_state.cmd); - /* Set DRQ */ - if_state.drq = TRUE; - if_state.status |= IF_DRQ; - if (if_state.cmd & IF_E_FLAG) { - if_activate(IF_W_DELAY + IF_VERIFY_DELAY + head_switch_delay); - } else { - if_activate(IF_W_DELAY + head_switch_delay); - } - break; - } -} - -void if_write(uint32 pa, uint32 val, size_t size) -{ - UNIT *uptr; - uint8 reg; - - val = val & 0xff; - - uptr = &(if_dev.units[0]); - reg = (uint8) (pa - IFBASE); - - switch (reg) { - case IF_CMD_REG: - if_state.cmd = (uint8) val; - /* Writing to the command register always de-asserts the IRQ line */ - CLR_INT; - - /* If this is a FORCE INTERRUPT, handle it immediately. All - * other commands require that the unit be attached and a - * diskette loaded. This one does not. */ - if ((if_state.cmd & 0xf0) == IF_FORCE_INT) { - sim_debug(EXECUTE_MSG, &if_dev, "\tCOMMAND\t%02x\tForce Interrupt\n", if_state.cmd); - if_state.status = 0; - - if ((uptr->flags & UNIT_ATT) && if_state.track == 0) { - if_state.status |= (IF_TK_0|IF_HEAD_LOADED); - } - - if ((if_state.cmd & 0xf) == 0) { - sim_cancel(&if_unit); -#if defined(REV2) - CLR_INT; /* TODO: Confirm this is right */ -#endif - } else if ((if_state.cmd & 0x8) == 0x8) { - if_state.status |= IF_DRQ; - SET_INT; - } - break; - } - - if ((uptr->flags & UNIT_ATT) == 0) { - /* If not attached, do nothing */ - break; - } - - if_handle_command(); - break; - case IF_TRACK_REG: - if_state.track = (uint8) val; - sim_debug(WRITE_MSG, &if_dev, "\tTRACK\t%02x\n", val); - break; - case IF_SECTOR_REG: - if_state.sector = (uint8) val; - sim_debug(WRITE_MSG, &if_dev, "\tSECTOR\t%02x\n", val); - break; - case IF_DATA_REG: - if_state.data = (uint8) val; - - sim_debug(WRITE_MSG, &if_dev, "\tDATA\t%02x\n", val); - - if ((uptr->flags & UNIT_ATT) == 0) { - /* Not attached */ - break; - } - - if ((if_state.cmd & 0xf0) == IF_WRITE_TRACK) { - /* We intentionally ignore WRITE TRACK data, because - * This is only used for low-level MFM formatting, - * which we do not emulate. */ - } else if ((if_state.cmd & 0xf0) == IF_WRITE_SEC || - (if_state.cmd & 0xf0) == IF_WRITE_SEC_M) { - - if_buf[if_sec_ptr++] = (uint8) val; - - if (if_sec_ptr >= IF_SEC_SIZE) { - if_sec_ptr = 0; - } - } - - break; - default: - break; - } -} - -#if defined(REV3) -uint32 if_csr_read(uint32 pa, size_t size) -{ - return (uint32)(if_state.csr); -} - -void if_csr_write(uint32 pa, uint32 val, size_t size) -{ - if_state.csr = val & 0xff; -} -#endif - -CONST char *if_description(DEVICE *dptr) -{ - return "Integrated Floppy Disk"; -} - -t_stat if_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr) -{ - fprintf(st, "Integrated Floppy Disk (IFLOPPY)\n\n"); - fprintf(st, "The IFLOPPY device implements the integrated 720 KB floppy disk\n"); - fprintf(st, "of the 3B2/400. A single floppy disk is supported on the controller.\n\n"); - fprintf(st, "The format of the diskette media is as follows:\n\n"); - fprintf(st, " Size Sides Tracks/Side Sectors/Track Bytes/Track\n"); - fprintf(st, " ------ ----- ----------- ------------- -----------\n"); - fprintf(st, " 720 KB 2 80 9 512\n\n"); - fprintf(st, "Physical media is Double Sided/Quad Density, 96 tpi, 250kbps MFM encoding.\n"); - return SCPE_OK; -} - -/* - * Compute the offset of the currently selected C/H/S (in # of sectors) - */ -static SIM_INLINE uint32 if_lba() -{ - /* Reminder that sectors are numbered 1-9 instead - * of being numbered 0-8 */ - return((if_state.track * IF_SEC_COUNT * 2) + - (if_state.side * IF_SEC_COUNT) + - (if_state.sector - 1)); -} - -void if_after_dma() -{ - if_state.drq = FALSE; - if_state.status &= ~IF_DRQ; -} +/* 3b2_if.c: TMS2797 Integrated Floppy Controller + + Copyright (c) 2017-2022, Seth J. Morabito + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + Except as contained in this notice, the name of the author shall + not be used in advertising or otherwise to promote the sale, use or + other dealings in this Software without prior written authorization + from the author. +*/ + +#include "3b2_if.h" + +#include "sim_disk.h" + +#include "3b2_cpu.h" +#include "3b2_csr.h" + +/* Static function declarations */ +static SIM_INLINE uint32 if_lba(); + +/* + * Disk Format: + * ------------ + * + * - 80 Tracks + * - 9 Sectors per track + * - 2 heads + * - 512 bytes per sector + * + * 80 * 9 * 2 * 512 = 720KB + * + */ + +#define IF_STEP_DELAY 300 /* us */ +#define IF_R_DELAY 6500 /* us */ +#define IF_W_DELAY 7000 /* us */ +#define IF_VERIFY_DELAY 2000 /* us */ +#define IF_HLD_DELAY 6000 /* us */ +#define IF_HSW_DELAY 4000 /* us */ + +#if defined(REV3) +#define SET_INT CPU_SET_INT(INT_FLOPPY) +#define CLR_INT CPU_CLR_INT(INT_FLOPPY) +#else +#define SET_INT do { \ + CPU_SET_INT(INT_FLOPPY); \ + SET_CSR(CSRDISK); \ + } while(0) +#define CLR_INT do { \ + CPU_CLR_INT(INT_FLOPPY); \ + CLR_CSR(CSRDISK); \ + } while(0) +#endif + +UNIT if_unit = { + UDATA (&if_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_BINK+UNIT_ROABLE, + IF_DSK_SIZE_SECS) +}; + +REG if_reg[] = { + { NULL } +}; + +DEVICE if_dev = { + "IFLOPPY", &if_unit, if_reg, NULL, + 1, 16, 8, 1, 16, 8, + NULL, NULL, &if_reset, + NULL, &if_attach, &if_detach, NULL, + DEV_DEBUG|DEV_DISK|DEV_SECTORS, 0, sys_deb_tab, + NULL, NULL, &if_help, NULL, NULL, + &if_description +}; + +IF_STATE if_state; +uint8 if_buf[IF_SEC_SIZE]; +uint32 if_sec_ptr = 0; + +/* Function implementation */ + +static SIM_INLINE void if_activate(uint32 delay_us) +{ + sim_activate_after(&if_unit, delay_us); +} + +t_stat if_svc(UNIT *uptr) +{ + uint32 lba; /* Logical block address for write */ + t_seccnt sectswritten; + + if_state.status &= ~(IF_BUSY); + + switch(if_state.cmd & 0xf0) { + case IF_RESTORE: + if_state.status = (IF_TK_0|IF_HEAD_LOADED); + break; + case IF_SEEK: + if_state.status = IF_HEAD_LOADED; + if (if_state.track == 0) { + if_state.status |= IF_TK_0; + } + break; + case IF_WRITE_SEC: + lba = if_lba(); + + /* If we're read-only, don't actually do anything. */ + if (if_unit.flags & UNIT_RO) { + break; + } + + if (sim_disk_wrsect(&if_unit, lba, if_buf, §swritten, 1) == SCPE_OK) { + if (sectswritten != 1) { + sim_debug(EXECUTE_MSG, &if_dev, + "ERROR: ASKED TO wRITE ONE SECTOR, WROTE %d\n", + sectswritten); + } + } + + break; + } + + if_state.cmd = 0; + + /* Request an interrupt */ + sim_debug(IRQ_MSG, &if_dev, "\tINTR\n"); + SET_INT; + + return SCPE_OK; +} + +t_stat if_reset(DEVICE *dptr) +{ + if_state.status = IF_TK_0; + if_state.track = 0; + if_state.sector = 1; + if_sec_ptr = 0; + + return SCPE_OK; +} + +t_stat if_attach(UNIT *uptr, CONST char *cptr) +{ + return sim_disk_attach(uptr, cptr, 512, 1, TRUE, 0, NULL, 0, 0); +} + +t_stat if_detach(UNIT *uptr) +{ + return sim_disk_detach(uptr); +} + +uint32 if_read(uint32 pa, size_t size) { + uint8 reg, data; + UNIT *uptr; + + uptr = &(if_dev.units[0]); + reg = (uint8)(pa - IFBASE); + + switch (reg) { + case IF_STATUS_REG: + data = if_state.status; + /* If there's no image attached, we're not ready */ + if ((uptr->flags & (UNIT_ATT|UNIT_BUF)) == 0) { + data |= IF_NRDY; + } + /* Reading the status register always de-asserts the IRQ line */ + CLR_INT; + sim_debug(READ_MSG, &if_dev, "\tSTATUS\t%02x\n", data); + break; + case IF_TRACK_REG: + data = if_state.track; + sim_debug(READ_MSG, &if_dev, "\tTRACK\t%02x\n", data); + break; + case IF_SECTOR_REG: + data = if_state.sector; + sim_debug(READ_MSG, &if_dev, "\tSECTOR\t%02x\n", data); + break; + case IF_DATA_REG: + if_state.status &= ~IF_DRQ; + + if (((uptr->flags & (UNIT_ATT|UNIT_BUF)) == 0) || + ((if_state.cmd & 0xf0) != IF_READ_SEC && + (if_state.cmd & 0xf0) != IF_READ_SEC_M)) { + /* Not attached, or not a read command */ + + switch (if_state.cmd & 0xf0) { + case IF_READ_ADDR: + /* Special state machine. */ + switch (if_state.read_addr_ptr++) { + case 0: + if_state.data = if_state.track; + break; + case 1: + if_state.data = if_state.side; + break; + case 2: + if_state.data = if_state.sector; + break; + case 3: + if_state.data = 2; /* 512 byte */ + break; + case 4: + /* TODO: Checksum */ + if_state.data = 0; + break; + case 5: + /* TODO: Checksum */ + if_state.data = 0; + if_state.read_addr_ptr = 0; + break; + } + } + + sim_debug(READ_MSG, &if_dev, "\tDATA\t%02x\n", if_state.data); + return if_state.data; + } + + data = if_buf[if_sec_ptr++]; + sim_debug(READ_MSG, &if_dev, "\tDATA\t%02x\n", data); + + if (if_sec_ptr >= IF_SEC_SIZE) { + if_sec_ptr = 0; + } + + break; + default: + data = 0xffu; // Compiler warning + break; + } + + return data; +} + +/* Handle the most recently received command */ +void if_handle_command() +{ + uint32 delay_ms = 0; + uint32 head_switch_delay = 0; + uint32 head_load_delay = 0; + uint32 lba; /* Logical block address */ + t_seccnt sectsread; + + if_sec_ptr = 0; + + /* We're starting a new command. */ + if_state.status = IF_BUSY; + + /* Clear read addr state */ + if_state.read_addr_ptr = 0; + + switch(if_state.cmd & 0xf0) { + case IF_RESTORE: + case IF_SEEK: + case IF_STEP: + case IF_STEP_T: + case IF_STEP_IN: + case IF_STEP_IN_T: + case IF_STEP_OUT: + case IF_STEP_OUT_T: + if_state.cmd_type = 1; + if (if_state.cmd & IF_H_FLAG) { + head_load_delay = IF_HLD_DELAY; + } + break; + + case IF_READ_SEC: + case IF_READ_SEC_M: + case IF_WRITE_SEC: + case IF_WRITE_SEC_M: + if_state.cmd_type = 2; +#if defined(REV2) + if (((if_state.cmd & IF_U_FLAG) >> 1) != if_state.side) { + head_switch_delay = IF_HSW_DELAY; + if_state.side = (if_state.cmd & IF_U_FLAG) >> 1; + } +#endif + break; + + case IF_READ_ADDR: + case IF_READ_TRACK: + case IF_WRITE_TRACK: + if_state.cmd_type = 3; +#if defined(REV2) + if (((if_state.cmd & IF_U_FLAG) >> 1) != if_state.side) { + head_switch_delay = IF_HSW_DELAY; + if_state.side = (if_state.cmd & IF_U_FLAG) >> 1; + } +#endif + break; + } + + switch(if_state.cmd & 0xf0) { + case IF_RESTORE: + sim_debug(EXECUTE_MSG, &if_dev, "\tCOMMAND\t%02x\tRestore\n", if_state.cmd); + + /* Reset HLT */ + if_state.status &= ~IF_HEAD_LOADED; + + if (if_unit.flags & UNIT_RO) { + if_state.status |= IF_WP; + } + + /* If head should be loaded immediately, do so now */ + if (if_state.cmd & IF_H_FLAG) { + if_state.status |= IF_HEAD_LOADED; + } + + if (if_state.track == 0) { + if_state.status |= IF_TK_0; + if_state.track = 1; /* Kind of a gross hack */ + } + + if (if_state.cmd & IF_V_FLAG) { + delay_ms = (IF_STEP_DELAY * if_state.track) + IF_VERIFY_DELAY; + } else { + delay_ms = IF_STEP_DELAY * if_state.track; + } + + if_activate(delay_ms); + + if_state.data = 0; + if_state.track = 0; + break; + + case IF_STEP: + case IF_STEP_T: + sim_debug(EXECUTE_MSG, &if_dev, "\tCOMMAND\t%02x\tStep\n", if_state.cmd); + if (if_unit.flags & UNIT_RO) { + if_state.status |= IF_WP; + } + if_activate(IF_STEP_DELAY); + if_state.track = (uint8) MIN(MAX((int) if_state.track + if_state.step_dir, 0), 0x4f); + break; + case IF_STEP_IN: + case IF_STEP_IN_T: + sim_debug(EXECUTE_MSG, &if_dev, "\tCOMMAND\t%02x\tStep In\n", if_state.cmd); + if (if_unit.flags & UNIT_RO) { + if_state.status |= IF_WP; + } + if_state.step_dir = IF_STEP_IN_DIR; + if_state.track = (uint8) MAX((int) if_state.track + if_state.step_dir, 0); + if_activate(IF_STEP_DELAY); + break; + case IF_STEP_OUT: + case IF_STEP_OUT_T: + sim_debug(EXECUTE_MSG, &if_dev, "\tCOMMAND\t%02x\tStep Out\n", if_state.cmd); + if (if_unit.flags & UNIT_RO) { + if_state.status |= IF_WP; + } + if_state.step_dir = IF_STEP_OUT_DIR; + if_state.track = (uint8) MIN((int) if_state.track + if_state.step_dir, 0x4f); + if_activate(IF_STEP_DELAY); + break; + case IF_SEEK: + sim_debug(EXECUTE_MSG, &if_dev, "\tCOMMAND\t%02x\tSeek\n", if_state.cmd); + + /* Reset HLT */ + if_state.status &= ~IF_HEAD_LOADED; + + if (if_unit.flags & UNIT_RO) { + if_state.status |= IF_WP; + } + + /* If head should be loaded immediately, do so now */ + if (if_state.cmd & IF_H_FLAG) { + if_state.status |= IF_HEAD_LOADED; + } + + /* Save the direction for stepping */ + if (if_state.data > if_state.track) { + if_state.step_dir = IF_STEP_IN_DIR; + } else if (if_state.data < if_state.track) { + if_state.step_dir = IF_STEP_OUT_DIR; + } + + /* The new track is in the data register */ + + if (if_state.data > IF_TRACK_COUNT-1) { + if_state.data = IF_TRACK_COUNT-1; + } + + if (if_state.data == 0) { + if_state.status |= IF_TK_0; + } else { + if_state.status &= ~(IF_TK_0); + } + + delay_ms = (uint32) abs(if_state.data - if_state.track); + + if (delay_ms == 0) { + delay_ms++; + } + + if (if_state.cmd & IF_V_FLAG) { + if_activate((IF_STEP_DELAY * delay_ms) + IF_VERIFY_DELAY + head_load_delay); + } else { + if_activate((IF_STEP_DELAY * delay_ms) + head_load_delay); + } + + if_state.track = if_state.data; + break; + + case IF_READ_SEC: + lba = if_lba(); + + sim_debug(EXECUTE_MSG, &if_dev, "\tCOMMAND\t%02x\tRead Sector %d/%d/%d (lba=%d)\n", + if_state.cmd, if_state.track, if_state.side, if_state.sector, lba); + + if (sim_disk_rdsect(&if_unit, lba, if_buf, §sread, 1) == SCPE_OK) { + if (sectsread != 1) { + sim_debug(EXECUTE_MSG, &if_dev, + "ERROR: ASKED TO READ ONE SECTOR, READ %d\n", + sectsread); + } + /* We set DRQ right away to request the transfer. */ + if_state.drq = TRUE; + if_state.status |= IF_DRQ; + if (if_state.cmd & IF_E_FLAG) { + if_activate(IF_R_DELAY + IF_VERIFY_DELAY + head_switch_delay); + } else { + if_activate(IF_R_DELAY + head_switch_delay); + } + } + + break; + case IF_READ_SEC_M: + /* Not yet implemented. Halt the emulator. */ + sim_debug(EXECUTE_MSG, &if_dev, + "\tCOMMAND\t%02x\tRead Sector (Multi) - NOT IMPLEMENTED\n", + if_state.cmd); + stop_reason = STOP_ERR; + break; + case IF_WRITE_SEC: + lba = if_lba(); + + sim_debug(EXECUTE_MSG, &if_dev, "\tCOMMAND\t%02x\tWrite Sector %d/%d/%d (lba=%d)\n", + if_state.cmd, if_state.track, if_state.side, if_state.sector, lba); + + if (if_unit.flags & UNIT_RO) { + if_state.status |= IF_WP; + sim_debug(EXECUTE_MSG, &if_dev, "\tWON'T WRITE: WRITE PROTECTED.\n"); + /* Still cause an interrupt... */ + if_activate(IF_W_DELAY + head_switch_delay); + /* But don't set DRQ and ask for a transfer. */ + break; + } + + /* We set DRQ right away to request the transfer. Data will + * be written by the host into our buffer by 512 writes to the + * data register. When the IF device later activates, the data + * will actually be written. */ + if_state.drq = TRUE; + if_state.status |= IF_DRQ; + if (if_state.cmd & IF_E_FLAG) { + if_activate(IF_W_DELAY + IF_VERIFY_DELAY + head_switch_delay); + } else { + if_activate(IF_W_DELAY + head_switch_delay); + } + break; + case IF_WRITE_SEC_M: + /* Not yet implemented. Halt the emulator. */ + sim_debug(EXECUTE_MSG, &if_dev, + "\tCOMMAND\t%02x\tWrite Sector (Multi) - NOT IMPLEMENTED\n", + if_state.cmd); + stop_reason = STOP_ERR; + break; + case IF_READ_ADDR: + sim_debug(EXECUTE_MSG, &if_dev, "\tCOMMAND\t%02x\tRead Address\n", if_state.cmd); + if_state.drq = TRUE; + if_state.status |= IF_DRQ; + if_activate(IF_R_DELAY); + break; + case IF_READ_TRACK: + sim_debug(EXECUTE_MSG, &if_dev, "\tCOMMAND\t%02x\tRead Track\n", if_state.cmd); + /* Not yet implemented. Halt the emulator. */ + stop_reason = STOP_ERR; + break; + case IF_WRITE_TRACK: + sim_debug(EXECUTE_MSG, &if_dev, "\tCOMMAND\t%02x\tWrite Track\n", if_state.cmd); + /* Set DRQ */ + if_state.drq = TRUE; + if_state.status |= IF_DRQ; + if (if_state.cmd & IF_E_FLAG) { + if_activate(IF_W_DELAY + IF_VERIFY_DELAY + head_switch_delay); + } else { + if_activate(IF_W_DELAY + head_switch_delay); + } + break; + } +} + +void if_write(uint32 pa, uint32 val, size_t size) +{ + UNIT *uptr; + uint8 reg; + + val = val & 0xff; + + uptr = &(if_dev.units[0]); + reg = (uint8) (pa - IFBASE); + + switch (reg) { + case IF_CMD_REG: + if_state.cmd = (uint8) val; + /* Writing to the command register always de-asserts the IRQ line */ + CLR_INT; + + /* If this is a FORCE INTERRUPT, handle it immediately. All + * other commands require that the unit be attached and a + * diskette loaded. This one does not. */ + if ((if_state.cmd & 0xf0) == IF_FORCE_INT) { + sim_debug(EXECUTE_MSG, &if_dev, "\tCOMMAND\t%02x\tForce Interrupt\n", if_state.cmd); + if_state.status = 0; + + if ((uptr->flags & UNIT_ATT) && if_state.track == 0) { + if_state.status |= (IF_TK_0|IF_HEAD_LOADED); + } + + if ((if_state.cmd & 0xf) == 0) { + sim_cancel(&if_unit); +#if defined(REV2) + CLR_INT; /* TODO: Confirm this is right */ +#endif + } else if ((if_state.cmd & 0x8) == 0x8) { + if_state.status |= IF_DRQ; + SET_INT; + } + break; + } + + if ((uptr->flags & UNIT_ATT) == 0) { + /* If not attached, do nothing */ + break; + } + + if_handle_command(); + break; + case IF_TRACK_REG: + if_state.track = (uint8) val; + sim_debug(WRITE_MSG, &if_dev, "\tTRACK\t%02x\n", val); + break; + case IF_SECTOR_REG: + if_state.sector = (uint8) val; + sim_debug(WRITE_MSG, &if_dev, "\tSECTOR\t%02x\n", val); + break; + case IF_DATA_REG: + if_state.data = (uint8) val; + + sim_debug(WRITE_MSG, &if_dev, "\tDATA\t%02x\n", val); + + if ((uptr->flags & UNIT_ATT) == 0) { + /* Not attached */ + break; + } + + if ((if_state.cmd & 0xf0) == IF_WRITE_TRACK) { + /* We intentionally ignore WRITE TRACK data, because + * This is only used for low-level MFM formatting, + * which we do not emulate. */ + } else if ((if_state.cmd & 0xf0) == IF_WRITE_SEC || + (if_state.cmd & 0xf0) == IF_WRITE_SEC_M) { + + if_buf[if_sec_ptr++] = (uint8) val; + + if (if_sec_ptr >= IF_SEC_SIZE) { + if_sec_ptr = 0; + } + } + + break; + default: + break; + } +} + +#if defined(REV3) +uint32 if_csr_read(uint32 pa, size_t size) +{ + return (uint32)(if_state.csr); +} + +void if_csr_write(uint32 pa, uint32 val, size_t size) +{ + if_state.csr = val & 0xff; +} +#endif + +CONST char *if_description(DEVICE *dptr) +{ + return "Integrated Floppy Disk"; +} + +t_stat if_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr) +{ + fprintf(st, "Integrated Floppy Disk (IFLOPPY)\n\n"); + fprintf(st, "The IFLOPPY device implements the integrated 720 KB floppy disk\n"); + fprintf(st, "of the 3B2/400. A single floppy disk is supported on the controller.\n\n"); + fprintf(st, "The format of the diskette media is as follows:\n\n"); + fprintf(st, " Size Sides Tracks/Side Sectors/Track Bytes/Track\n"); + fprintf(st, " ------ ----- ----------- ------------- -----------\n"); + fprintf(st, " 720 KB 2 80 9 512\n\n"); + fprintf(st, "Physical media is Double Sided/Quad Density, 96 tpi, 250kbps MFM encoding.\n"); + + fprint_set_help(st, dptr); + fprint_show_help(st, dptr); + fprint_reg_help(st, dptr); + + return SCPE_OK; +} + +/* + * Compute the offset of the currently selected C/H/S (in # of sectors) + */ +static SIM_INLINE uint32 if_lba() +{ + /* Reminder that sectors are numbered 1-9 instead + * of being numbered 0-8 */ + return((if_state.track * IF_SEC_COUNT * 2) + + (if_state.side * IF_SEC_COUNT) + + (if_state.sector - 1)); +} + +void if_after_dma() +{ + if_state.drq = FALSE; + if_state.status &= ~IF_DRQ; +} diff --git a/3B2/3b2_if.h b/3B2/3b2_if.h index a6d40e58..d27640e4 100644 --- a/3B2/3b2_if.h +++ b/3B2/3b2_if.h @@ -1,131 +1,131 @@ -/* 3b2_if.h: AT&T 3B2 Model Floppy Controller (TMS2797NL) Header - - Copyright (c) 2017, Seth J. Morabito - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - - Except as contained in this notice, the name of the author shall - not be used in advertising or otherwise to promote the sale, use or - other dealings in this Software without prior written authorization - from the author. -*/ - -#ifndef __3B2_IF_H__ -#define __3B2_IF_H__ - -#include "3b2_defs.h" - -typedef struct { - uint8 data; - uint8 cmd; - uint8 cmd_type; - uint8 status; - uint8 track; - uint8 sector; - uint8 side; - uint8 read_addr_ptr; - int8 step_dir; - t_bool drq; -#if defined(REV3) - uint8 csr; -#endif -} IF_STATE; - -/* Status Bits */ -#define IF_BUSY 0x01 -#define IF_DRQ 0x02 -#define IF_INDEX 0x02 -#define IF_TK_0 0x04 -#define IF_LOST_DATA 0x04 -#define IF_CRC_ERR 0x08 -#define IF_SEEK_ERR 0x10 -#define IF_RNF 0x10 -#define IF_HEAD_LOADED 0x20 -#define IF_RECORD_TYPE 0x20 -#define IF_WP 0x40 -#define IF_NRDY 0x80 - -/* Type I Commands */ -#define IF_RESTORE 0x00 -#define IF_SEEK 0x10 -#define IF_STEP 0x20 -#define IF_STEP_T 0x30 -#define IF_STEP_IN 0x40 -#define IF_STEP_IN_T 0x50 -#define IF_STEP_OUT 0x60 -#define IF_STEP_OUT_T 0x70 - -/* Type II Commands */ -#define IF_READ_SEC 0x80 -#define IF_READ_SEC_M 0x90 -#define IF_WRITE_SEC 0xA0 -#define IF_WRITE_SEC_M 0xB0 - -/* Type III Commands */ -#define IF_READ_ADDR 0xC0 -#define IF_READ_TRACK 0xE0 -#define IF_WRITE_TRACK 0xF0 - -/* Type IV Command */ -#define IF_FORCE_INT 0xD0 - -/* Command flags */ - -#define IF_C_FLAG 0x02 -#define IF_V_FLAG 0x04 -#define IF_E_FLAG 0x04 -#define IF_U_FLAG 0x02 -#define IF_H_FLAG 0x08 -#define IF_S_FLAG 0x10 - -/* Constants */ - -#define IF_SIDES 2 -#define IF_SEC_COUNT 9 -#define IF_SEC_SIZE 512 -#define IF_TRACK_SIZE 4608 -#define IF_TRACK_COUNT 80 - -#define IF_STEP_IN_DIR 1 -#define IF_STEP_OUT_DIR -1 - -#define IF_DSK_SIZE_SECS (IF_SIDES * IF_TRACK_COUNT * IF_SEC_COUNT) - -/* Function prototypes */ - -t_stat if_svc(UNIT *uptr); -t_stat if_reset(DEVICE *dptr); -t_stat if_attach(UNIT *uptr, CONST char *cptr); -t_stat if_detach(UNIT *uptr); -uint32 if_read(uint32 pa, size_t size); -void if_write(uint32 pa, uint32 val, size_t size); -#if defined(REV3) -uint32 if_csr_read(uint32 pa, size_t size); -void if_csr_write(uint32 pa, uint32 val, size_t size); -#endif -void if_handle_command(); -void if_after_dma(); -CONST char *if_description(DEVICE *dptr); -t_stat if_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr); - -extern IF_STATE if_state; - -#endif +/* 3b2_if.h: TMS2797 Integrated Floppy Controller + + Copyright (c) 2017-2022, Seth J. Morabito + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + Except as contained in this notice, the name of the author shall + not be used in advertising or otherwise to promote the sale, use or + other dealings in this Software without prior written authorization + from the author. +*/ + +#ifndef __3B2_IF_H__ +#define __3B2_IF_H__ + +#include "3b2_defs.h" + +typedef struct { + uint8 data; + uint8 cmd; + uint8 cmd_type; + uint8 status; + uint8 track; + uint8 sector; + uint8 side; + uint8 read_addr_ptr; + int8 step_dir; + t_bool drq; +#if defined(REV3) + uint8 csr; +#endif +} IF_STATE; + +/* Status Bits */ +#define IF_BUSY 0x01 +#define IF_DRQ 0x02 +#define IF_INDEX 0x02 +#define IF_TK_0 0x04 +#define IF_LOST_DATA 0x04 +#define IF_CRC_ERR 0x08 +#define IF_SEEK_ERR 0x10 +#define IF_RNF 0x10 +#define IF_HEAD_LOADED 0x20 +#define IF_RECORD_TYPE 0x20 +#define IF_WP 0x40 +#define IF_NRDY 0x80 + +/* Type I Commands */ +#define IF_RESTORE 0x00 +#define IF_SEEK 0x10 +#define IF_STEP 0x20 +#define IF_STEP_T 0x30 +#define IF_STEP_IN 0x40 +#define IF_STEP_IN_T 0x50 +#define IF_STEP_OUT 0x60 +#define IF_STEP_OUT_T 0x70 + +/* Type II Commands */ +#define IF_READ_SEC 0x80 +#define IF_READ_SEC_M 0x90 +#define IF_WRITE_SEC 0xA0 +#define IF_WRITE_SEC_M 0xB0 + +/* Type III Commands */ +#define IF_READ_ADDR 0xC0 +#define IF_READ_TRACK 0xE0 +#define IF_WRITE_TRACK 0xF0 + +/* Type IV Command */ +#define IF_FORCE_INT 0xD0 + +/* Command flags */ + +#define IF_C_FLAG 0x02 +#define IF_V_FLAG 0x04 +#define IF_E_FLAG 0x04 +#define IF_U_FLAG 0x02 +#define IF_H_FLAG 0x08 +#define IF_S_FLAG 0x10 + +/* Constants */ + +#define IF_SIDES 2 +#define IF_SEC_COUNT 9 +#define IF_SEC_SIZE 512 +#define IF_TRACK_SIZE 4608 +#define IF_TRACK_COUNT 80 + +#define IF_STEP_IN_DIR 1 +#define IF_STEP_OUT_DIR -1 + +#define IF_DSK_SIZE_SECS (IF_SIDES * IF_TRACK_COUNT * IF_SEC_COUNT) + +/* Function prototypes */ + +t_stat if_svc(UNIT *uptr); +t_stat if_reset(DEVICE *dptr); +t_stat if_attach(UNIT *uptr, CONST char *cptr); +t_stat if_detach(UNIT *uptr); +uint32 if_read(uint32 pa, size_t size); +void if_write(uint32 pa, uint32 val, size_t size); +#if defined(REV3) +uint32 if_csr_read(uint32 pa, size_t size); +void if_csr_write(uint32 pa, uint32 val, size_t size); +#endif +void if_handle_command(); +void if_after_dma(); +CONST char *if_description(DEVICE *dptr); +t_stat if_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr); + +extern IF_STATE if_state; + +#endif diff --git a/3B2/3b2_io.c b/3B2/3b2_io.c index eba4bf54..5883eecd 100644 --- a/3B2/3b2_io.c +++ b/3B2/3b2_io.c @@ -1,786 +1,772 @@ -/* 3b2_io.c: AT&T 3B2 Model 400 IO and CIO feature cards - - Copyright (c) 2017, Seth J. Morabito - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - - Except as contained in this notice, the name of the author shall - not be used in advertising or otherwise to promote the sale, use or - other dealings in this Software without prior written authorization - from the author. -*/ - -#include "3b2_io.h" - -#include "3b2_cpu.h" -#include "3b2_csr.h" -#include "3b2_dmac.h" -#include "3b2_if.h" -#include "3b2_iu.h" -#include "3b2_mem.h" -#include "3b2_mmu.h" -#include "3b2_stddev.h" -#include "3b2_timer.h" - -#if defined(REV2) -#include "3b2_id.h" -#endif - -CIO_STATE cio[CIO_SLOTS] = {{0}}; - -uint16 cio_int_req = 0; /* Bitset of card slots requesting interrupts */ - -#if defined(REV3) -iolink iotable[] = { - { MMUBASE, MMUBASE+MMUSIZE, &mmu_read, &mmu_write }, - { IFBASE, IFBASE+IFSIZE, &if_read, &if_write }, - { IFCSRBASE, IFCSRBASE+IFCSRSIZE, &if_csr_read, &if_csr_write }, - { FLTLBASE, FLTLSIZE, &flt_read, &flt_write }, - { FLTHBASE, FLTHSIZE, &flt_read, &flt_write }, - { NVRBASE, NVRBASE+NVRSIZE, &nvram_read, &nvram_write }, - { TIMERBASE, TIMERBASE+TIMERSIZE, &timer_read, &timer_write }, - { CSRBASE, CSRBASE+CSRSIZE, &csr_read, &csr_write }, - { IUBASE, IUBASE+IUSIZE, &iu_read, &iu_write }, - { DMAIUABASE, DMAIUABASE+DMAIUASIZE, &dmac_read, &dmac_write }, - { DMAIUBBASE, DMAIUBBASE+DMAIUBSIZE, &dmac_read, &dmac_write }, - { DMACBASE, DMACBASE+DMACSIZE, &dmac_read, &dmac_write }, - { DMAIFBASE, DMAIFBASE+DMAIFSIZE, &dmac_read, &dmac_write }, - { TODBASE, TODBASE+TODSIZE, &tod_read, &tod_write }, - { 0, 0, NULL, NULL} -}; -#else -iolink iotable[] = { - { MMUBASE, MMUBASE+MMUSIZE, &mmu_read, &mmu_write }, - { IFBASE, IFBASE+IFSIZE, &if_read, &if_write }, - { IDBASE, IDBASE+IDSIZE, &id_read, &id_write }, - { DMAIDBASE, DMAIDBASE+DMAIDSIZE, &dmac_read, &dmac_write }, - { NVRBASE, NVRBASE+NVRSIZE, &nvram_read, &nvram_write }, - { TIMERBASE, TIMERBASE+TIMERSIZE, &timer_read, &timer_write }, - { CSRBASE, CSRBASE+CSRSIZE, &csr_read, &csr_write }, - { IUBASE, IUBASE+IUSIZE, &iu_read, &iu_write }, - { DMAIUABASE, DMAIUABASE+DMAIUASIZE, &dmac_read, &dmac_write }, - { DMAIUBBASE, DMAIUBBASE+DMAIUBSIZE, &dmac_read, &dmac_write }, - { DMACBASE, DMACBASE+DMACSIZE, &dmac_read, &dmac_write }, - { DMAIFBASE, DMAIFBASE+DMAIFSIZE, &dmac_read, &dmac_write }, - { TODBASE, TODBASE+TODSIZE, &tod_read, &tod_write }, - { 0, 0, NULL, NULL} -}; -#endif - -void cio_clear(uint8 cid) -{ - cio[cid].id = 0; - cio[cid].exp_handler = NULL; - cio[cid].full_handler = NULL; - cio[cid].reset_handler = NULL; - cio[cid].sysgen = NULL; - cio[cid].rqp = 0; - cio[cid].cqp = 0; - cio[cid].rqs = 0; - cio[cid].cqs = 0; - cio[cid].ivec = 0; - cio[cid].no_rque = 0; - cio[cid].ipl = 0; - cio[cid].sysgen_s = 0; - cio[cid].seqbit = 0; - cio[cid].op = 0; - CIO_CLR_INT(cid); -} - -/* - * A braindead CRC32 calculator. - * - * This is overkill for what we need: A simple way to tag the contents - * of a block of memory uploaded to a CIO card (so we can - * differentiate between desired functions without actually having to - * disassemble and understand 80186 code!) - */ -uint32 cio_crc32_shift(uint32 crc, uint8 data) -{ - uint8 i; - - crc = ~crc; - crc ^= data; - for (i = 0; i < 8; i++) { - if (crc & 1) { - crc = (crc >> 1) ^ CRC_POLYNOMIAL; - } else { - crc = crc >> 1; - } - } - - return ~crc; -} - -void cio_sysgen(uint8 cid) -{ - uint32 sysgen_p; - - sysgen_p = pread_w(SYSGEN_PTR); - - sim_debug(CIO_DBG, &cpu_dev, - "[%08x] [SYSGEN] Starting sysgen for card %d. sysgen_p=%08x\n", - R[NUM_PC], cid, sysgen_p); - - /* seqbit is always reset to 0 on completion */ - cio[cid].seqbit = 0; - - cio[cid].rqp = pread_w(sysgen_p); - cio[cid].cqp = pread_w(sysgen_p + 4); - cio[cid].rqs = pread_b(sysgen_p + 8); - cio[cid].cqs = pread_b(sysgen_p + 9); - cio[cid].ivec = pread_b(sysgen_p + 10); - cio[cid].no_rque = pread_b(sysgen_p + 11); - - sim_debug(CIO_DBG, &cpu_dev, - "[SYSGEN] sysgen rqp = %08x\n", - cio[cid].rqp); - sim_debug(CIO_DBG, &cpu_dev, - "[SYSGEN] sysgen cqp = %08x\n", - cio[cid].cqp); - sim_debug(CIO_DBG, &cpu_dev, - "[SYSGEN] sysgen rqs = %02x\n", - cio[cid].rqs); - sim_debug(CIO_DBG, &cpu_dev, - "[SYSGEN] sysgen cqs = %02x\n", - cio[cid].cqs); - sim_debug(CIO_DBG, &cpu_dev, - "[SYSGEN] sysgen ivec = %02x\n", - cio[cid].ivec); - sim_debug(CIO_DBG, &cpu_dev, - "[SYSGEN] sysgen no_rque = %02x\n", - cio[cid].no_rque); - - /* If the card has a custom sysgen handler, run it */ - if (cio[cid].sysgen != NULL) { - cio[cid].sysgen(cid); - } else { - sim_debug(CIO_DBG, &cpu_dev, - "[%08x] [cio_sysgen] Not running custom sysgen.\n", - R[NUM_PC]); - } -} - -void cio_cexpress(uint8 cid, uint32 esize, cio_entry *cqe, uint8 *app_data) -{ - uint32 i, cqp; - - cqp = cio[cid].cqp; - - sim_debug(CIO_DBG, &cpu_dev, - "[%08x] [cio_cexpress] cqp = %08x seqbit = %d\n", - R[NUM_PC], cqp, cio[cid].seqbit); - - cio[cid].seqbit ^= 1; - - cqe->subdevice |= (cio[cid].seqbit << 6); - - pwrite_h(cqp, cqe->byte_count); - pwrite_b(cqp + 2, cqe->subdevice); - pwrite_b(cqp + 3, cqe->opcode); - pwrite_w(cqp + 4, cqe->address); - - /* Write application-specific data. */ - for (i = 0; i < (esize - QESIZE); i++) { - pwrite_b(cqp + 8 + i, app_data[i]); - } -} - -void cio_cqueue(uint8 cid, uint8 cmd_stat, uint32 esize, - cio_entry *cqe, uint8 *app_data) -{ - uint32 i, cqp, top; - uint16 lp; - - /* Apply the CMD/STAT bit */ - cqe->subdevice |= (cmd_stat << 7); - - /* Get the physical address of the completion queue - * in main memory */ - cqp = cio[cid].cqp; - - /* Get the physical address of the first entry in - * the completion queue */ - top = cqp + esize + LUSIZE; - - /* Get the load pointer. This is a 16-bit absolute offset - * from the top of the queue to the start of the entry. */ - lp = pread_h(cqp + esize); - - /* Load the entry at the supplied address */ - pwrite_h(top + lp, cqe->byte_count); - pwrite_b(top + lp + 2, cqe->subdevice); - pwrite_b(top + lp + 3, cqe->opcode); - pwrite_w(top + lp + 4, cqe->address); - - /* Write application-specific data. */ - for (i = 0; i < (esize - QESIZE); i++) { - pwrite_b(top + lp + 8 + i, app_data[i]); - } - - /* Increment the load pointer to the next queue location. - * If we go past the end of the queue, wrap around to the - * start of the queue */ - if (cio[cid].cqs > 0) { - lp = (lp + esize) % (esize * cio[cid].cqs); - /* Store it back to the correct location */ - pwrite_h(cqp + esize, lp); - } -} - -/* - * Retrieve the Express Entry from the Request Queue - */ -void cio_rexpress(uint8 cid, uint32 esize, cio_entry *rqe, uint8 *app_data) -{ - uint32 i; - uint32 rqp; - - rqp = cio[cid].rqp; - - /* Unload the express entry from the request queue */ - rqe->byte_count = pread_h(rqp); - rqe->subdevice = pread_b(rqp + 2); - rqe->opcode = pread_b(rqp + 3); - rqe->address = pread_w(rqp + 4); - - for (i = 0; i < (esize - QESIZE); i++) { - app_data[i] = pread_b(rqp + 8 + i); - } -} - -/* - * Retrieve an entry from the Request Queue. This function - * returns the load pointer that points to the NEXT available slot. - * This may be used by callers to determine which queue(s) need to - * be serviced. - * - * Returns SCPE_OK on success, or SCPE_NXM if no entry was found. - * - */ -t_stat cio_rqueue(uint8 cid, uint32 qnum, uint32 esize, - cio_entry *rqe, uint8 *app_data) -{ - uint32 i, rqp, top; - uint16 lp, ulp; - - /* Get the physical address of the request queue in main memory */ - rqp = cio[cid].rqp + - esize + - (qnum * (LUSIZE + (esize * cio[cid].rqs))); - - lp = pread_h(rqp); - ulp = pread_h(rqp + 2); - - /* Check to see if the request queue is empty. If it is, there's - * nothing to take. */ - if (lp == ulp) { - return SCPE_NXM; - } - - top = rqp + LUSIZE; - - /* Retrieve the entry at the supplied address */ - rqe->byte_count = pread_h(top + ulp); - rqe->subdevice = pread_b(top + ulp + 2); - rqe->opcode = pread_b(top + ulp + 3); - rqe->address = pread_w(top + ulp + 4); - - /* Read application-specific data. */ - for (i = 0; i < (esize - QESIZE); i++) { - app_data[i] = pread_b(top + ulp + 8 + i); - } - - /* Increment the unload pointer to the next queue location. If we - * go past the end of the queue, wrap around to the start of the - * queue */ - if (cio[cid].rqs > 0) { - ulp = (ulp + esize) % (esize * cio[cid].rqs); - pwrite_h(rqp + 2, ulp); - } - - return SCPE_OK; -} - -/* - * Return the Load Pointer for the given request queue - */ -uint16 cio_r_lp(uint8 cid, uint32 qnum, uint32 esize) -{ - uint32 rqp; - - rqp = cio[cid].rqp + - esize + - (qnum * (LUSIZE + (esize * cio[cid].rqs))); - - return pread_h(rqp); -} - -/* - * Return the Unload Pointer for the given request queue - */ -uint16 cio_r_ulp(uint8 cid, uint32 qnum, uint32 esize) -{ - uint32 rqp; - - rqp = cio[cid].rqp + - esize + - (qnum * (LUSIZE + (esize * cio[cid].rqs))); - - return pread_h(rqp + 2); -} - -uint16 cio_c_lp(uint8 cid, uint32 esize) -{ - uint32 cqp; - cqp = cio[cid].cqp + esize; - return pread_h(cqp); -} - -uint16 cio_c_ulp(uint8 cid, uint32 esize) -{ - uint32 cqp; - cqp = cio[cid].cqp + esize; - return pread_h(cqp + 2); -} - -/* - * Returns true if there is room in the completion queue - * for a new entry. - */ -t_bool cio_cqueue_avail(uint8 cid, uint32 esize) -{ - uint32 lp, ulp; - - lp = pread_h(cio[cid].cqp + esize); - ulp = pread_h(cio[cid].cqp + esize + 2); - - return(((lp + esize) % (cio[cid].cqs * esize)) != ulp); -} - -t_bool cio_rqueue_avail(uint8 cid, uint32 qnum, uint32 esize) -{ - uint32 rqp, lp, ulp; - - /* Get the physical address of the request queue in main memory */ - rqp = cio[cid].rqp + - esize + - (qnum * (LUSIZE + (esize * cio[cid].rqs))); - - lp = pread_h(rqp); - ulp = pread_h(rqp + 2); - - return(lp != ulp); -} - -uint32 io_read(uint32 pa, size_t size) -{ - iolink *p; - uint8 cid, reg, data; - -#if defined (REV3) - /* - * NOTE: Not Yet Implemented, but: If 0x4BF00 is accessed and does - * not result in an error, the system assumes there are two MMUs - * installed. I think 0x4b000 is where a second MMU would live in - * IO space if there were multiple MMUs. - */ - if ((pa == MADDR_SLOT_0) || - (pa == MADDR_SLOT_1) || - (pa == MADDR_SLOT_2) || - (pa == MADDR_SLOT_3)) { - switch(MEM_SIZE) { - case MSIZ_4M: - /* Configure with one 4MB boards */ - if (pa < MADDR_SLOT_1) { - return MEMID_4M; - } - break; - case MSIZ_8M: - /* Configure with two 4MB boards */ - if (pa < MADDR_SLOT_2) { - return MEMID_4M; - } - break; - case MSIZ_16M: - /* Configure with four 4MB boards */ - return MEMID_4M; - case MSIZ_32M: - /* Configure with two 16MB boards */ - if (pa < MADDR_SLOT_2) { - return MEMID_16M; - } - break; - case MSIZ_64M: - /* Configure with four 16MB boards */ - return MEMID_16M; - default: - return 0; - } - - return 0; - } - - if (pa >= VCACHE_BOTTOM && pa < VCACHE_TOP) { - CSRBIT(CSRTIMO, TRUE); - cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT); - return 0; - } - - if (pa >= BUB_BOTTOM && pa < BUB_TOP) { - CSRBIT(CSRTIMO, TRUE); - - /* TODO: I don't remember why we do this! */ - if ((pa & 0xfff) == 3) { - cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT); - } - - /* TODO: Implement BUB */ - return 1; - } -#else - if (pa == MEMSIZE_REG) { - - /* The following values map to memory sizes: - 0x00: 512KB ( 524,288 B) - 0x01: 2MB (2,097,152 B) - 0x02: 1MB (1,048,576 B) - 0x03: 4MB (4,194,304 B) - */ - switch(MEM_SIZE) { - case 0x80000: /* 512KB */ - return 0; - case 0x100000: /* 1MB */ - return 2; - case 0x200000: /* 2MB */ - return 1; - case 0x400000: /* 4MB */ - return 3; - default: - return 0; - } - } -#endif - - /* CIO board area */ - if (pa >= CIO_BOTTOM && pa < CIO_TOP) { - cid = CID(pa); - reg = pa - CADDR(cid); - - if (cio[cid].id == 0) { - /* Nothing lives here */ - sim_debug(IO_DBG, &cpu_dev, - "[READ] [%08x] No card at cid=%d reg=%d\n", - R[NUM_PC], cid, reg); - CSRBIT(CSRTIMO, TRUE); - cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT); - return 0; - } - - /* A normal SYSGEN sequence is: RESET -> INT0 -> INT1. - * However, there's a bug in the 3B2/400 DGMON test suite that - * runs on every startup. This diagnostic code performs a - * SYSGEN by calling RESET -> INT1 -> INT0. So, we must handle - * both orders. */ - - switch (reg) { - case IOF_ID: - case IOF_VEC: - switch(cio[cid].sysgen_s) { - case CIO_INT_NONE: /* We've never seen an INT0 or INT1 */ - case CIO_INT0: /* We've seen an INT0 but not an INT1. */ - cio[cid].sysgen_s |= CIO_INT0; - sim_debug(CIO_DBG, &cpu_dev, - "[READ] [%08x] (%d INT0) ID\n", - R[NUM_PC], cid); - /* Return the correct byte of our board ID */ - if (reg == IOF_ID) { - data = (cio[cid].id >> 8) & 0xff; - } else { - data = (cio[cid].id & 0xff); - } - break; - case CIO_INT1: /* We've seen an INT1 but not an INT0. Time to sysgen */ - cio[cid].sysgen_s |= CIO_INT0; - sim_debug(CIO_DBG, &cpu_dev, - "[READ] [%08x] (%d INT0) SYSGEN\n", - R[NUM_PC], cid); - cio_sysgen(cid); - data = cio[cid].ivec; - break; - case CIO_SYSGEN: /* We've already sysgen'ed */ - cio[cid].sysgen_s |= CIO_INT0; /* This must come BEFORE the exp_handler */ - sim_debug(CIO_DBG, &cpu_dev, - "[READ] [%08x] (%d INT0) EXPRESS JOB\n", - R[NUM_PC], cid); - cio[cid].exp_handler(cid); - data = cio[cid].ivec; - break; - default: - /* This should never happen */ - stop_reason = STOP_ERR; - sim_debug(CIO_DBG, &cpu_dev, - "[READ] [%08x] (%d INT0) ERROR IN STATE MACHINE sysgen_s=%02x\n", - R[NUM_PC], cid, cio[cid].sysgen_s); - data = 0; - break; - } - - return data; - case IOF_CTRL: - switch(cio[cid].sysgen_s) { - case CIO_INT_NONE: /* We've never seen an INT0 or INT1 */ - case CIO_INT1: /* We've seen an INT1 but not an INT0 */ - /* There's nothing to do in this instance */ - sim_debug(CIO_DBG, &cpu_dev, - "[READ] [%08x] (%d INT1) IGNORED\n", - R[NUM_PC], cid); - cio[cid].sysgen_s |= CIO_INT1; - break; - case CIO_INT0: /* We've seen an INT0 but not an INT1. Time to sysgen */ - sim_debug(CIO_DBG, &cpu_dev, - "[READ] [%08x] (%d INT1) SYSGEN\n", - R[NUM_PC], cid); - cio[cid].sysgen_s |= CIO_INT1; - cio_sysgen(cid); - break; - case CIO_SYSGEN: /* We've already sysgen'ed */ - sim_debug(CIO_DBG, &cpu_dev, - "[READ] [%08x] (%d INT1) FULL\n", - R[NUM_PC], cid); - cio[cid].sysgen_s |= CIO_INT1; /* This must come BEFORE the full handler */ - cio[cid].full_handler(cid); - break; - default: - /* This should never happen */ - stop_reason = STOP_ERR; - sim_debug(CIO_DBG, &cpu_dev, - "[READ] [%08x] (%d INT1) ERROR IN STATE MACHINE sysgen_s=%02x\n", - R[NUM_PC], cid, cio[cid].sysgen_s); - break; - } - - return 0; /* Data returned is arbitrary */ - case IOF_STAT: - sim_debug(CIO_DBG, &cpu_dev, - "[READ] [%08x] (%d RESET)\n", - R[NUM_PC], cid); - if (cio[cid].reset_handler) { - cio[cid].reset_handler(cid); - } - cio[cid].sysgen_s = 0; - return 0; /* Data returned is arbitrary */ - default: - /* We should never reach here, but if we do, there's - * nothing listening. */ - sim_debug(CIO_DBG, &cpu_dev, - "[READ] [%08x] No card at cid=%d reg=%d\n", - R[NUM_PC], cid, reg); - CSRBIT(CSRTIMO, TRUE); - cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT); - return 0; - } - } - - /* Memory-mapped IO devices */ - for (p = &iotable[0]; p->low != 0; p++) { - if ((pa >= p->low) && (pa < p->high) && p->read) { - return p->read(pa, size); - } - } - - /* Not found. */ - sim_debug(IO_DBG, &cpu_dev, - "[%08x] [io_read] ADDR=%08x: No device found.\n", - R[NUM_PC], pa); - CSRBIT(CSRTIMO, TRUE); - cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT); - return 0; -} - -void io_write(uint32 pa, uint32 val, size_t size) -{ - iolink *p; - uint8 cid, reg; - -#if defined(REV3) - if (pa >= VCACHE_BOTTOM && pa < VCACHE_TOP) { - CSRBIT(CSRTIMO, TRUE); - cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT); - return; - } - - if (pa >= BUB_BOTTOM && pa < BUB_TOP) { - CSRBIT(CSRTIMO, TRUE); - /* TODO: I don't remember why we do this! */ - if ((pa & 0xfff) == 3) { - cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT); - } - /* TODO: Implement BUB */ - return; - } -#endif - - /* Feature Card Area */ - if (pa >= CIO_BOTTOM && pa < CIO_TOP) { - cid = CID(pa); - reg = pa - CADDR(cid); - - if (cio[cid].id == 0) { - /* Nothing lives here */ - sim_debug(CIO_DBG, &cpu_dev, - "[WRITE] [%08x] No card at cid=%d reg=%d\n", - R[NUM_PC], cid, reg); - CSRBIT(CSRTIMO, TRUE); - cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT); - return; - } - - /* A normal SYSGEN sequence is: RESET -> INT0 -> INT1. - * However, there's a bug in the 3B2/400 DGMON test suite that - * runs on every startup. This diagnostic code performs a - * SYSGEN by calling RESET -> INT1 -> INT0. So, we must handle - * both orders. */ - - switch (reg) { - case IOF_ID: - case IOF_VEC: - switch(cio[cid].sysgen_s) { - case CIO_INT_NONE: /* We've never seen an INT0 or INT1 */ - case CIO_INT0: /* We've seen an INT0 but not an INT1. */ - sim_debug(CIO_DBG, &cpu_dev, - "[WRITE] [%08x] (%d INT0) ID\n", - R[NUM_PC], cid); - cio[cid].sysgen_s |= CIO_INT0; - break; - case CIO_INT1: /* We've seen an INT1 but not an INT0. Time to sysgen */ - sim_debug(CIO_DBG, &cpu_dev, - "[WRITE] [%08x] (%d INT0) SYSGEN\n", - R[NUM_PC], cid); - cio[cid].sysgen_s |= CIO_INT0; - cio_sysgen(cid); - break; - case CIO_SYSGEN: /* We've already sysgen'ed */ - sim_debug(CIO_DBG, &cpu_dev, - "[WRITE] [%08x] (%d INT0) EXPRESS JOB\n", - R[NUM_PC], cid); - cio[cid].sysgen_s |= CIO_INT0; - cio[cid].exp_handler(cid); - break; - default: - /* This should never happen */ - stop_reason = STOP_ERR; - sim_debug(CIO_DBG, &cpu_dev, - "[WRITE] [%08x] (%d INT0) ERROR IN STATE MACHINE sysgen_s=%02x\n", - R[NUM_PC], cid, cio[cid].sysgen_s); - break; - } - - return; - case IOF_CTRL: - switch(cio[cid].sysgen_s) { - case CIO_INT_NONE: /* We've never seen an INT0 or INT1 */ - case CIO_INT1: /* We've seen an INT1 but not an INT0 */ - /* There's nothing to do in this instance */ - sim_debug(CIO_DBG, &cpu_dev, - "[WRITE] [%08x] (%d INT1) IGNORED\n", - R[NUM_PC], cid); - cio[cid].sysgen_s |= CIO_INT1; - break; - case CIO_INT0: /* We've seen an INT0 but not an INT1. Time to sysgen */ - sim_debug(CIO_DBG, &cpu_dev, - "[WRITE] [%08x] (%d INT1) SYSGEN\n", - R[NUM_PC], cid); - cio[cid].sysgen_s |= CIO_INT1; - cio_sysgen(cid); - break; - case CIO_SYSGEN: /* We've already sysgen'ed */ - sim_debug(CIO_DBG, &cpu_dev, - "[WRITE] [%08x] (%d INT1) FULL\n", - R[NUM_PC], cid); - cio[cid].sysgen_s |= CIO_INT1; - cio[cid].full_handler(cid); - break; - default: - /* This should never happen */ - stop_reason = STOP_ERR; - sim_debug(CIO_DBG, &cpu_dev, - "[WRITE] [%08x] (%d INT1) ERROR IN STATE MACHINE sysgen_s=%02x\n", - R[NUM_PC], cid, cio[cid].sysgen_s); - break; - } - - return; - case IOF_STAT: - sim_debug(CIO_DBG, &cpu_dev, - "[WRITE] [%08x] (%d RESET)\n", - R[NUM_PC], cid); - if (cio[cid].reset_handler) { - cio[cid].reset_handler(cid); - } - cio[cid].sysgen_s = 0; - return; - default: - /* We should never reach here, but if we do, there's - * nothing listening. */ - sim_debug(CIO_DBG, &cpu_dev, - "[WRITE] [%08x] No card at cid=%d reg=%d\n", - R[NUM_PC], cid, reg); - CSRBIT(CSRTIMO, TRUE); - cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT); - return; - } - } - - /* Memory-mapped IO devices */ - for (p = &iotable[0]; p->low != 0; p++) { - if ((pa >= p->low) && (pa < p->high) && p->write) { - p->write(pa, val, size); - return; - } - } - - /* Not found. */ - sim_debug(IO_DBG, &cpu_dev, - "[%08x] [io_write] ADDR=%08x: No device found.\n", - R[NUM_PC], pa); - CSRBIT(CSRTIMO, TRUE); - cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT); -} - - -/* For debugging only */ -void dump_entry(uint32 dbits, DEVICE *dev, CONST char *type, - uint32 esize, cio_entry *entry, uint8 *app_data) -{ - char appl[64]; - uint32 i, c_offset; - - for (i = 0, c_offset=0; i < (esize - QESIZE); i++) { - snprintf(appl + c_offset, 3, "%02x", app_data[i]); - c_offset += 2; - } - - sim_debug(dbits, dev, - "*** %s ENTRY: byte_count=%04x, subdevice=%02x, opcode=%d, address=%08x, app_data=%s\n", - type, entry->byte_count, entry->subdevice, - entry->opcode, entry->address, appl); -} +/* 3b2_io.c: Common I/O (CIO) Feature Card Support + + Copyright (c) 2017-2022, Seth J. Morabito + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + Except as contained in this notice, the name of the author shall + not be used in advertising or otherwise to promote the sale, use or + other dealings in this Software without prior written authorization + from the author. +*/ + +#include "3b2_io.h" + +#include "3b2_cpu.h" +#include "3b2_csr.h" +#include "3b2_dmac.h" +#include "3b2_if.h" +#include "3b2_iu.h" +#include "3b2_mem.h" +#include "3b2_mmu.h" +#include "3b2_stddev.h" +#include "3b2_timer.h" + +#if defined(REV2) +#include "3b2_id.h" +#endif + +CIO_STATE cio[CIO_SLOTS] = {{0}}; +uint16 cio_int_req = 0; /* Bitset of card slots requesting interrupts */ + +#if defined(REV3) +iolink iotable[] = { + { MMUBASE, MMUBASE+MMUSIZE, &mmu_read, &mmu_write }, + { IFBASE, IFBASE+IFSIZE, &if_read, &if_write }, + { IFCSRBASE, IFCSRBASE+IFCSRSIZE, &if_csr_read, &if_csr_write }, + { FLTLBASE, FLTLBASE+FLTLSIZE, &flt_read, &flt_write }, + { FLTHBASE, FLTHBASE+FLTHSIZE, &flt_read, &flt_write }, + { NVRBASE, NVRBASE+NVRSIZE, &nvram_read, &nvram_write }, + { TIMERBASE, TIMERBASE+TIMERSIZE, &timer_read, &timer_write }, + { CSRBASE, CSRBASE+CSRSIZE, &csr_read, &csr_write }, + { IUBASE, IUBASE+IUSIZE, &iu_read, &iu_write }, + { DMAIUABASE, DMAIUABASE+DMAIUASIZE, &dmac_read, &dmac_write }, + { DMAIUBBASE, DMAIUBBASE+DMAIUBSIZE, &dmac_read, &dmac_write }, + { DMACBASE, DMACBASE+DMACSIZE, &dmac_read, &dmac_write }, + { DMAIFBASE, DMAIFBASE+DMAIFSIZE, &dmac_read, &dmac_write }, + { TODBASE, TODBASE+TODSIZE, &tod_read, &tod_write }, + { 0, 0, NULL, NULL} +}; +#else +iolink iotable[] = { + { MMUBASE, MMUBASE+MMUSIZE, &mmu_read, &mmu_write }, + { IFBASE, IFBASE+IFSIZE, &if_read, &if_write }, + { IDBASE, IDBASE+IDSIZE, &id_read, &id_write }, + { DMAIDBASE, DMAIDBASE+DMAIDSIZE, &dmac_read, &dmac_write }, + { NVRBASE, NVRBASE+NVRSIZE, &nvram_read, &nvram_write }, + { TIMERBASE, TIMERBASE+TIMERSIZE, &timer_read, &timer_write }, + { CSRBASE, CSRBASE+CSRSIZE, &csr_read, &csr_write }, + { IUBASE, IUBASE+IUSIZE, &iu_read, &iu_write }, + { DMAIUABASE, DMAIUABASE+DMAIUASIZE, &dmac_read, &dmac_write }, + { DMAIUBBASE, DMAIUBBASE+DMAIUBSIZE, &dmac_read, &dmac_write }, + { DMACBASE, DMACBASE+DMACSIZE, &dmac_read, &dmac_write }, + { DMAIFBASE, DMAIFBASE+DMAIFSIZE, &dmac_read, &dmac_write }, + { TODBASE, TODBASE+TODSIZE, &tod_read, &tod_write }, + { 0, 0, NULL, NULL} +}; +#endif + +/* + * Insert a CIO card into the backplane. + * + * If a space could be found, SPCE_OK is returned, and the slot the + * card was installed in is placed in `slot`. + * + * If no room is availalbe, return SCPE_NXM. + */ +t_stat cio_install(uint16 id, + CONST char *name, + uint8 ipl, + void (*exp_handler)(uint8 slot), + void (*full_handler)(uint8 slot), + void (*sysgen)(uint8 slot), + void (*reset_handler)(uint8 slot), + uint8 *slot) +{ + uint8 s; + + for (s = 0; s < CIO_SLOTS; s++) { + sim_debug(EXECUTE_MSG, &cpu_dev, + "[cio_install] cio[%d]: populated=%d, id=%d\n", + s, cio[s].populated, cio[s].id); + if (!cio[s].populated) { + sim_debug(EXECUTE_MSG, &cpu_dev, + "[cio_install] >>> I found a free slot! Slot #%d has nothing\n", s); + *slot = s; + /* Ensure the slot is in a clean state */ + cio_remove(s); + /* Populate the slot */ + cio[s].populated = TRUE; + cio[s].id = id; + cio[s].ipl = ipl; + strncpy(cio[s].name, name, CIO_NAME_LEN); + cio[s].exp_handler = exp_handler; + cio[s].full_handler = full_handler; + cio[s].sysgen = sysgen; + cio[s].reset_handler = reset_handler; + return SCPE_OK; + } + } + + return SCPE_NXM; +} + +/* + * Remove a CIO card from the specified backplane slot. + */ +void cio_remove(uint8 slot) +{ + memset(&cio[slot], 0, sizeof(CIO_STATE)); + /* cio[slot].populated = FALSE; */ + CIO_CLR_INT(slot); +} + +/* + * Remove all CIO cards of the matching type. + */ +void cio_remove_all(uint16 id) +{ + int i; + + for (i = 0; i < CIO_SLOTS; i++) { + if (cio[i].populated && cio[i].id == id) { + cio_remove(i); + } + } +} + +/* + * A braindead CRC32 calculator. + * + * This is overkill for what we need: A simple way to tag the contents + * of a block of memory uploaded to a CIO card (so we can + * differentiate between desired functions without actually having to + * disassemble and understand 80186 code!) + */ +uint32 cio_crc32_shift(uint32 crc, uint8 data) +{ + uint8 i; + + crc = ~crc; + crc ^= data; + for (i = 0; i < 8; i++) { + if (crc & 1) { + crc = (crc >> 1) ^ CRC_POLYNOMIAL; + } else { + crc = crc >> 1; + } + } + + return ~crc; +} + +void cio_sysgen(uint8 slot) +{ + uint32 sysgen_p; + + sysgen_p = pread_w(SYSGEN_PTR, BUS_PER); + + sim_debug(CIO_DBG, &cpu_dev, + "[SYSGEN] Starting sysgen for card %d (%s). sysgen_p=%08x\n", + slot, cio[slot].name, sysgen_p); + + /* seqbit is always reset to 0 on completion */ + cio[slot].seqbit = 0; + + cio[slot].rqp = pread_w(sysgen_p, BUS_PER); + cio[slot].cqp = pread_w(sysgen_p + 4, BUS_PER); + cio[slot].rqs = pread_b(sysgen_p + 8, BUS_PER); + cio[slot].cqs = pread_b(sysgen_p + 9, BUS_PER); + cio[slot].ivec = pread_b(sysgen_p + 10, BUS_PER); + cio[slot].no_rque = pread_b(sysgen_p + 11, BUS_PER); + + sim_debug(CIO_DBG, &cpu_dev, + "[SYSGEN] sysgen rqp = %08x\n", + cio[slot].rqp); + sim_debug(CIO_DBG, &cpu_dev, + "[SYSGEN] sysgen cqp = %08x\n", + cio[slot].cqp); + sim_debug(CIO_DBG, &cpu_dev, + "[SYSGEN] sysgen rqs = %02x\n", + cio[slot].rqs); + sim_debug(CIO_DBG, &cpu_dev, + "[SYSGEN] sysgen cqs = %02x\n", + cio[slot].cqs); + sim_debug(CIO_DBG, &cpu_dev, + "[SYSGEN] sysgen ivec = %02x\n", + cio[slot].ivec); + sim_debug(CIO_DBG, &cpu_dev, + "[SYSGEN] sysgen no_rque = %02x\n", + cio[slot].no_rque); + + /* If the card has a custom sysgen handler, run it */ + if (cio[slot].sysgen != NULL) { + cio[slot].sysgen(slot); + } else { + sim_debug(CIO_DBG, &cpu_dev, + "[cio_sysgen] Not running custom sysgen.\n"); + } +} + +void cio_cexpress(uint8 slot, uint32 esize, cio_entry *cqe, uint8 *app_data) +{ + uint32 i, cqp; + + cqp = cio[slot].cqp; + + sim_debug(CIO_DBG, &cpu_dev, + "[cio_cexpress] [%s] cqp = %08x seqbit = %d\n", + cio[slot].name, cqp, cio[slot].seqbit); + + cio[slot].seqbit ^= 1; + + cqe->subdevice |= (cio[slot].seqbit << 6); + + pwrite_h(cqp, cqe->byte_count, BUS_PER); + pwrite_b(cqp + 2, cqe->subdevice, BUS_PER); + pwrite_b(cqp + 3, cqe->opcode, BUS_PER); + pwrite_w(cqp + 4, cqe->address, BUS_PER); + + /* Write application-specific data. */ + for (i = 0; i < (esize - QESIZE); i++) { + pwrite_b(cqp + 8 + i, app_data[i], BUS_PER); + } +} + +void cio_cqueue(uint8 slot, uint8 cmd_stat, uint32 esize, + cio_entry *cqe, uint8 *app_data) +{ + uint32 i, cqp, top; + uint16 lp; + + /* Apply the CMD/STAT bit */ + cqe->subdevice |= (cmd_stat << 7); + + /* Get the physical address of the completion queue + * in main memory */ + cqp = cio[slot].cqp; + + /* Get the physical address of the first entry in + * the completion queue */ + top = cqp + esize + LUSIZE; + + /* Get the load pointer. This is a 16-bit absolute offset + * from the top of the queue to the start of the entry. */ + lp = pread_h(cqp + esize, BUS_PER); + + /* Load the entry at the supplied address */ + pwrite_h(top + lp, cqe->byte_count, BUS_PER); + pwrite_b(top + lp + 2, cqe->subdevice, BUS_PER); + pwrite_b(top + lp + 3, cqe->opcode, BUS_PER); + pwrite_w(top + lp + 4, cqe->address, BUS_PER); + + /* Write application-specific data. */ + for (i = 0; i < (esize - QESIZE); i++) { + pwrite_b(top + lp + 8 + i, app_data[i], BUS_PER); + } + + /* Increment the load pointer to the next queue location. + * If we go past the end of the queue, wrap around to the + * start of the queue */ + if (cio[slot].cqs > 0) { + lp = (lp + esize) % (esize * cio[slot].cqs); + /* Store it back to the correct location */ + pwrite_h(cqp + esize, lp, BUS_PER); + } +} + +/* + * Retrieve the Express Entry from the Request Queue + */ +void cio_rexpress(uint8 slot, uint32 esize, cio_entry *rqe, uint8 *app_data) +{ + uint32 i; + uint32 rqp; + + rqp = cio[slot].rqp; + + /* Unload the express entry from the request queue */ + rqe->byte_count = pread_h(rqp, BUS_PER); + rqe->subdevice = pread_b(rqp + 2, BUS_PER); + rqe->opcode = pread_b(rqp + 3, BUS_PER); + rqe->address = pread_w(rqp + 4, BUS_PER); + + for (i = 0; i < (esize - QESIZE); i++) { + app_data[i] = pread_b(rqp + 8 + i, BUS_PER); + } +} + +/* + * Retrieve an entry from the Request Queue. This function + * returns the load pointer that points to the NEXT available slot. + * This may be used by callers to determine which queue(s) need to + * be serviced. + * + * Returns SCPE_OK on success, or SCPE_NXM if no entry was found. + * + */ +t_stat cio_rqueue(uint8 slot, uint32 qnum, uint32 esize, + cio_entry *rqe, uint8 *app_data) +{ + uint32 i, rqp, top; + uint16 lp, ulp; + + /* Get the physical address of the request queue in main memory */ + rqp = cio[slot].rqp + + esize + + (qnum * (LUSIZE + (esize * cio[slot].rqs))); + + lp = pread_h(rqp, BUS_PER); + ulp = pread_h(rqp + 2, BUS_PER); + + /* Check to see if the request queue is empty. If it is, there's + * nothing to take. */ + if (lp == ulp) { + return SCPE_NXM; + } + + top = rqp + LUSIZE; + + /* Retrieve the entry at the supplied address */ + rqe->byte_count = pread_h(top + ulp, BUS_PER); + rqe->subdevice = pread_b(top + ulp + 2, BUS_PER); + rqe->opcode = pread_b(top + ulp + 3, BUS_PER); + rqe->address = pread_w(top + ulp + 4, BUS_PER); + + /* Read application-specific data. */ + for (i = 0; i < (esize - QESIZE); i++) { + app_data[i] = pread_b(top + ulp + 8 + i, BUS_PER); + } + + /* Increment the unload pointer to the next queue location. If we + * go past the end of the queue, wrap around to the start of the + * queue */ + if (cio[slot].rqs > 0) { + ulp = (ulp + esize) % (esize * cio[slot].rqs); + pwrite_h(rqp + 2, ulp, BUS_PER); + } + + return SCPE_OK; +} + +/* + * Return the Load Pointer for the given request queue + */ +uint16 cio_r_lp(uint8 slot, uint32 qnum, uint32 esize) +{ + uint32 rqp; + + rqp = cio[slot].rqp + + esize + + (qnum * (LUSIZE + (esize * cio[slot].rqs))); + + return pread_h(rqp, BUS_PER); +} + +/* + * Return the Unload Pointer for the given request queue + */ +uint16 cio_r_ulp(uint8 slot, uint32 qnum, uint32 esize) +{ + uint32 rqp; + + rqp = cio[slot].rqp + + esize + + (qnum * (LUSIZE + (esize * cio[slot].rqs))); + + return pread_h(rqp + 2, BUS_PER); +} + +uint16 cio_c_lp(uint8 slot, uint32 esize) +{ + uint32 cqp; + cqp = cio[slot].cqp + esize; + return pread_h(cqp, BUS_PER); +} + +uint16 cio_c_ulp(uint8 slot, uint32 esize) +{ + uint32 cqp; + cqp = cio[slot].cqp + esize; + return pread_h(cqp + 2, BUS_PER); +} + +/* + * Returns true if there is room in the completion queue + * for a new entry. + */ +t_bool cio_cqueue_avail(uint8 slot, uint32 esize) +{ + uint32 lp, ulp; + + lp = pread_h(cio[slot].cqp + esize, BUS_PER); + ulp = pread_h(cio[slot].cqp + esize + 2, BUS_PER); + + return(((lp + esize) % (cio[slot].cqs * esize)) != ulp); +} + +t_bool cio_rqueue_avail(uint8 slot, uint32 qnum, uint32 esize) +{ + uint32 rqp, lp, ulp; + + /* Get the physical address of the request queue in main memory */ + rqp = cio[slot].rqp + + esize + + (qnum * (LUSIZE + (esize * cio[slot].rqs))); + + lp = pread_h(rqp, BUS_PER); + ulp = pread_h(rqp + 2, BUS_PER); + + return(lp != ulp); +} + +uint32 io_read(uint32 pa, size_t size) +{ + iolink *p; + uint8 slot, reg, data; + +#if defined (REV3) + if (pa >= VCACHE_BOTTOM && pa < VCACHE_TOP) { + sim_debug(EXECUTE_MSG, &cpu_dev, + "[UBUB] (VCACHE) Read addr %08x\n", pa); + CSRBIT(CSRTIMO, TRUE); + cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT); + return 0; + } + + if (pa >= BUB_BOTTOM && pa < BUB_TOP) { + sim_debug(EXECUTE_MSG, &cpu_dev, + "[BUB] Read addr %08x\n", pa); + CSRBIT(CSRTIMO, TRUE); + cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT); + return 0; + } +#else + if (pa == MEMSIZE_REG) { + + /* The following values map to memory sizes: + 0x00: 512KB ( 524,288 B) + 0x01: 2MB (2,097,152 B) + 0x02: 1MB (1,048,576 B) + 0x03: 4MB (4,194,304 B) + */ + switch(MEM_SIZE) { + case 0x80000: /* 512KB */ + return 0; + case 0x100000: /* 1MB */ + return 2; + case 0x200000: /* 2MB */ + return 1; + case 0x400000: /* 4MB */ + return 3; + default: + return 0; + } + } +#endif + + /* CIO board area */ + if (pa >= CIO_BOTTOM && pa < CIO_TOP) { + slot = SLOT(pa); + reg = pa - CADDR(slot); + + if (!cio[slot].populated) { + /* Nothing lives here */ + sim_debug(IO_DBG, &cpu_dev, + "[READ] No card at slot=%d reg=%d\n", + slot, reg); + CSRBIT(CSRTIMO, TRUE); + cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT); + return 0; + } + + /* A normal SYSGEN sequence is: RESET -> INT0 -> INT1. + * However, there's a bug in the 3B2/400 DGMON test suite that + * runs on every startup. This diagnostic code performs a + * SYSGEN by calling RESET -> INT1 -> INT0. So, we must handle + * both orders. */ + + switch (reg) { + case IOF_ID: + case IOF_VEC: + switch(cio[slot].sysgen_s) { + case CIO_INT_NONE: /* We've never seen an INT0 or INT1 */ + case CIO_INT0: /* We've seen an INT0 but not an INT1. */ + cio[slot].sysgen_s |= CIO_INT0; + sim_debug(CIO_DBG, &cpu_dev, + "[READ] [%s] (%d INT0) ID\n", + cio[slot].name, slot); + /* Return the correct byte of our board ID */ + if (reg == IOF_ID) { + data = (cio[slot].id >> 8) & 0xff; + } else { + data = (cio[slot].id & 0xff); + } + break; + case CIO_INT1: /* We've seen an INT1 but not an INT0. Time to sysgen */ + cio[slot].sysgen_s |= CIO_INT0; + sim_debug(CIO_DBG, &cpu_dev, + "[READ] [%s] (%d INT0) SYSGEN\n", + cio[slot].name, slot); + cio_sysgen(slot); + data = cio[slot].ivec; + break; + case CIO_SYSGEN: /* We've already sysgen'ed */ + cio[slot].sysgen_s |= CIO_INT0; /* This must come BEFORE the exp_handler */ + sim_debug(CIO_DBG, &cpu_dev, + "[READ] [%s] (%d INT0) EXPRESS JOB\n", + cio[slot].name, slot); + cio[slot].exp_handler(slot); + data = cio[slot].ivec; + break; + default: + /* This should never happen */ + stop_reason = STOP_ERR; + sim_debug(CIO_DBG, &cpu_dev, + "[READ] [%s] (%d INT0) ERROR IN STATE MACHINE sysgen_s=%02x\n", + cio[slot].name, slot, cio[slot].sysgen_s); + data = 0; + break; + } + + return data; + case IOF_CTRL: + switch(cio[slot].sysgen_s) { + case CIO_INT_NONE: /* We've never seen an INT0 or INT1 */ + case CIO_INT1: /* We've seen an INT1 but not an INT0 */ + /* There's nothing to do in this instance */ + sim_debug(CIO_DBG, &cpu_dev, + "[READ] [%s] (%d INT1) IGNORED\n", + cio[slot].name, slot); + cio[slot].sysgen_s |= CIO_INT1; + break; + case CIO_INT0: /* We've seen an INT0 but not an INT1. Time to sysgen */ + sim_debug(CIO_DBG, &cpu_dev, + "[READ] [%s] (%d INT1) SYSGEN\n", + cio[slot].name, slot); + cio[slot].sysgen_s |= CIO_INT1; + cio_sysgen(slot); + break; + case CIO_SYSGEN: /* We've already sysgen'ed */ + sim_debug(CIO_DBG, &cpu_dev, + "[READ] [%s] (%d INT1) FULL\n", + cio[slot].name, slot); + cio[slot].sysgen_s |= CIO_INT1; /* This must come BEFORE the full handler */ + cio[slot].full_handler(slot); + break; + default: + /* This should never happen */ + stop_reason = STOP_ERR; + sim_debug(CIO_DBG, &cpu_dev, + "[READ] [%s] (%d INT1) ERROR IN STATE MACHINE sysgen_s=%02x\n", + cio[slot].name, slot, cio[slot].sysgen_s); + break; + } + + return 0; /* Data returned is arbitrary */ + case IOF_STAT: + sim_debug(CIO_DBG, &cpu_dev, + "[READ] [%s] (%d RESET)\n", + cio[slot].name, slot); + if (cio[slot].reset_handler) { + cio[slot].reset_handler(slot); + } + cio[slot].sysgen_s = 0; + return 0; /* Data returned is arbitrary */ + default: + /* We should never reach here, but if we do, there's + * nothing listening. */ + sim_debug(CIO_DBG, &cpu_dev, + "[READ] No card at slot=%d reg=%d\n", + slot, reg); + CSRBIT(CSRTIMO, TRUE); + cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT); + return 0; + } + } + + /* Memory-mapped IO devices */ + for (p = &iotable[0]; p->low != 0; p++) { + if ((pa >= p->low) && (pa < p->high) && p->read) { + return p->read(pa, size); + } + } + + /* Not found. */ + sim_debug(IO_DBG, &cpu_dev, + "[io_read] ADDR=%08x: No device found.\n", + pa); + CSRBIT(CSRTIMO, TRUE); + cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT); + return 0; +} + +void io_write(uint32 pa, uint32 val, size_t size) +{ + iolink *p; + uint8 slot, reg; + +#if defined(REV3) + if (pa >= VCACHE_BOTTOM && pa < VCACHE_TOP) { + sim_debug(EXECUTE_MSG, &cpu_dev, + "[UBUB] (VCACHE) Write addr %08x val 0x%x\n", + pa, val); + CSRBIT(CSRTIMO, TRUE); + cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT); + return; + } + + if (pa >= BUB_BOTTOM && pa < BUB_TOP) { + sim_debug(EXECUTE_MSG, &cpu_dev, + "[BUB] Write addr %08x val 0x%x\n", + pa, val); + CSRBIT(CSRTIMO, TRUE); + cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT); + return; + } +#endif + + /* Feature Card Area */ + if (pa >= CIO_BOTTOM && pa < CIO_TOP) { + slot = SLOT(pa); + reg = pa - CADDR(slot); + + if (!cio[slot].populated) { + /* Nothing lives here */ + sim_debug(CIO_DBG, &cpu_dev, + "[WRITE] No card at slot=%d reg=%d\n", + slot, reg); + CSRBIT(CSRTIMO, TRUE); + cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT); + return; + } + + /* A normal SYSGEN sequence is: RESET -> INT0 -> INT1. + * However, there's a bug in the 3B2/400 DGMON test suite that + * runs on every startup. This diagnostic code performs a + * SYSGEN by calling RESET -> INT1 -> INT0. So, we must handle + * both orders. */ + + switch (reg) { + case IOF_ID: + case IOF_VEC: + switch(cio[slot].sysgen_s) { + case CIO_INT_NONE: /* We've never seen an INT0 or INT1 */ + case CIO_INT0: /* We've seen an INT0 but not an INT1. */ + sim_debug(CIO_DBG, &cpu_dev, + "[WRITE] [%s] (%d INT0) ID\n", + cio[slot].name, slot); + cio[slot].sysgen_s |= CIO_INT0; + break; + case CIO_INT1: /* We've seen an INT1 but not an INT0. Time to sysgen */ + sim_debug(CIO_DBG, &cpu_dev, + "[WRITE] [%s] (%d INT0) SYSGEN\n", + cio[slot].name, slot); + cio[slot].sysgen_s |= CIO_INT0; + cio_sysgen(slot); + break; + case CIO_SYSGEN: /* We've already sysgen'ed */ + sim_debug(CIO_DBG, &cpu_dev, + "[WRITE] [%s] (%d INT0) EXPRESS JOB\n", + cio[slot].name, slot); + cio[slot].sysgen_s |= CIO_INT0; + cio[slot].exp_handler(slot); + break; + default: + /* This should never happen */ + stop_reason = STOP_ERR; + sim_debug(CIO_DBG, &cpu_dev, + "[WRITE] [%s] (%d INT0) ERROR IN STATE MACHINE sysgen_s=%02x\n", + cio[slot].name, slot, cio[slot].sysgen_s); + break; + } + + return; + case IOF_CTRL: + switch(cio[slot].sysgen_s) { + case CIO_INT_NONE: /* We've never seen an INT0 or INT1 */ + case CIO_INT1: /* We've seen an INT1 but not an INT0 */ + /* There's nothing to do in this instance */ + sim_debug(CIO_DBG, &cpu_dev, + "[WRITE] [%s] (%d INT1) IGNORED\n", + cio[slot].name, slot); + cio[slot].sysgen_s |= CIO_INT1; + break; + case CIO_INT0: /* We've seen an INT0 but not an INT1. Time to sysgen */ + sim_debug(CIO_DBG, &cpu_dev, + "[WRITE] [%s] (%d INT1) SYSGEN\n", + cio[slot].name, slot); + cio[slot].sysgen_s |= CIO_INT1; + cio_sysgen(slot); + break; + case CIO_SYSGEN: /* We've already sysgen'ed */ + sim_debug(CIO_DBG, &cpu_dev, + "[WRITE] [%s] (%d INT1) FULL\n", + cio[slot].name, slot); + cio[slot].sysgen_s |= CIO_INT1; + cio[slot].full_handler(slot); + break; + default: + /* This should never happen */ + stop_reason = STOP_ERR; + sim_debug(CIO_DBG, &cpu_dev, + "[WRITE] [%s] (%d INT1) ERROR IN STATE MACHINE sysgen_s=%02x\n", + cio[slot].name, slot, cio[slot].sysgen_s); + break; + } + + return; + case IOF_STAT: + sim_debug(CIO_DBG, &cpu_dev, + "[WRITE] [%s] (%d RESET)\n", + cio[slot].name, slot); + if (cio[slot].reset_handler) { + cio[slot].reset_handler(slot); + } + cio[slot].sysgen_s = 0; + return; + default: + /* We should never reach here, but if we do, there's + * nothing listening. */ + sim_debug(CIO_DBG, &cpu_dev, + "[WRITE] No card at slot=%d reg=%d\n", + slot, reg); + CSRBIT(CSRTIMO, TRUE); + cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT); + return; + } + } + + /* Memory-mapped IO devices */ + for (p = &iotable[0]; p->low != 0; p++) { + if ((pa >= p->low) && (pa < p->high) && p->write) { + p->write(pa, val, size); + return; + } + } + + /* Not found. */ + sim_debug(IO_DBG, &cpu_dev, + "[io_write] ADDR=%08x: No device found.\n", + pa); + CSRBIT(CSRTIMO, TRUE); + cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT); +} diff --git a/3B2/3b2_io.h b/3B2/3b2_io.h index d06e5b90..7a8dfd23 100644 --- a/3B2/3b2_io.h +++ b/3B2/3b2_io.h @@ -1,252 +1,271 @@ -/* 3b2_io.h: AT&T 3B2 Model 400 IO dispatch (Header) - - Copyright (c) 2017, Seth J. Morabito - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - - Except as contained in this notice, the name of the author shall - not be used in advertising or otherwise to promote the sale, use or - other dealings in this Software without prior written authorization - from the author. -*/ - -/* Reference Documentation - * ======================= - * - * All communication between the system board and feature cards is - * done through in-memory queues, and causing interrupts in the - * feature card by accessing the Control or ID/VEC memory-mapped IO - * addresses. The structure of these queues is defined below in - * tables. - * - * Sysgen Block - * ------------ - * - * Pointed to by address at 0x2000000 after an INT0/INT1 combo - * - * - * | Address | Size | Contents | - * +---------------+------+-----------------------------------------+ - * | SYSGEN_P | 4 | Address of request queue | - * | SYSGEN_P + 4 | 4 | Address of completion queue | - * | SYSGEN_P + 8 | 1 | Number of entries in request queue | - * | SYSGEN_P + 9 | 1 | Number of entries in completion queue | - * | SYSGEN_P + 10 | 1 | Interrupt Vector number | - * | SYSGEN_P + 11 | 1 | Number of request queues | - * - * - * Queue Entry - * ----------- - * - * Each queue has one Express Entry, and n regular entries. - * - * | Address | Size | Contents | - * +---------------+------+-----------------------------------------+ - * | ENTRY_P | 2 | Byte Count | - * | ENTRY_P + 2 | 1 | Subdevice [1] | - * | ENTRY_P + 3 | 1 | Opcode | - * | ENTRY_P + 4 | 4 | Address / Data | - * | ENTRY_P + 8 | 4 | Application Specific Data | - * - * [1] The "Subdevice" entry is further divided into a bitset: - * Bit 7: Command (1) / Status (0) - * Bit 6: Sequence Bit - * Bit 5-1: Subdevice - * - * - * Queue - * ----- - * - * The Queue structures (one for request, one for completion) hold: - * - An express entry - * - * And then one or more queues, each queue consiting of - * - A set of pointers for load and unload from the queue - * - One or more Queue Entries - * - * | Address | Size | Contents | - * +---------------+------+-----------------------------------------+ - * | QUEUE_P | 12 | Express Queue Entry [1] | - * +---------------+------+-----------------------------------------+ - * | QUEUE_P + 12 | 2 | Load Pointer for Queue 0 | - * | QUEUE_P + 14 | 2 | Unload Pointer for Queue 0 | - * | QUEUE_P + 16 | 12 | Queue 0 Entry 0 [1] | - * | QUEUE_P + 28 | 12 | Queue 0 Entry 1 [1] | - * | ... | ... | ... | - * +---------------+------+-----------------------------------------+ - * | QUEUE_P + n | 2 | Load Pointer for Queue 1 | - * | QUEUE_P + n | 2 | Unload Pointer for Queue 1 | - * | QUEUE_P + n | 12 | Queue 1 Entry 0 [1] | - * | QUEUE_P + n | 12 | Queue 1 Entry 1 [1] | - * | ... | ... | ... | - * - * [1] See Queue Entry above - * - * NB: There are multiple Request queues, usually one per subdevice, - * and EACH Request queue starts with a Load Pointer, an Unload - * Pointer, and then 'n' Queue Entries. - * - */ - -#ifndef _3B2_IO_H_ -#define _3B2_IO_H_ - -#include "3b2_defs.h" - -#define CRC_POLYNOMIAL 0xEDB88320 - -#define CIO_SLOTS 12 - -/* IO area */ -#define IO_BOTTOM 0x40000 -#define IO_TOP 0x50000 - -/* CIO area */ -#define CIO_BOTTOM 0x200000 -#define CIO_TOP 0x2000000 - -#define IOF_ID 0 -#define IOF_VEC 1 -#define IOF_CTRL 3 -#define IOF_STAT 5 - -#define SYSGEN_PTR PHYS_MEM_BASE - -/* CIO opcodes */ -#define CIO_DLM 1 -#define CIO_ULM 2 -#define CIO_FCF 3 -#define CIO_DOS 4 -#define CIO_DSD 5 - -/* Response */ -#define CIO_SUCCESS 0 -#define CIO_FAILURE 2 -#define CIO_SYSGEN_OK 3 - -/* Map a physical address to a card ID */ -#define CID(pa) (((((pa) >> 0x14) & 0x1f) / 2) - 1) -/* Map a card ID to a base address */ -#define CADDR(bid) (((((bid) + 1) * 2) << 0x14)) - -/* Offsets into the request/completion queues of various values */ -#define LUSIZE 4 /* Load/Unload pointers size */ -#define QESIZE 8 /* Queue entry is 8 bytes + application data */ - -#define CIO_STAT 0 -#define CIO_CMD 1 - -/* Sysgen State */ -#define CIO_INT_NONE 0 -#define CIO_INT0 1 -#define CIO_INT1 2 -#define CIO_SYSGEN 3 - -#define CIO_SET_INT(slot) (cio_int_req |= (1 << slot)) -#define CIO_CLR_INT(slot) (cio_int_req &= ~(1 << slot)) - -typedef struct { - uint16 id; /* Card ID */ - void (*exp_handler)(uint8 cid); /* Handler for express jobs */ - void (*full_handler)(uint8 cid); /* Handler for full jobs */ - void (*sysgen)(uint8 cid); /* Sysgen routine (optional) */ - void (*reset_handler)(uint8 cid); /* RESET request handler (optional) */ - uint32 rqp; /* Request Queue Pointer */ - uint32 cqp; /* Completion Queue Pointer */ - uint8 rqs; /* Request queue size */ - uint8 cqs; /* Completion queue size */ - uint8 ivec; /* Interrupt Vector */ - uint8 no_rque; /* Number of request queues */ - uint8 ipl; /* IPL that this card uses */ - uint8 sysgen_s; /* Sysgen state */ - uint8 seqbit; /* Squence Bit */ - uint8 op; /* Last received opcode */ -} CIO_STATE; - -typedef struct { - uint16 byte_count; - uint8 subdevice; - uint8 opcode; - uint32 address; -} cio_entry; - -typedef struct { - uint32 low; - uint32 high; - uint32 (*read)(uint32 pa, size_t size); - void (*write)(uint32 pa, uint32 val, size_t size); -} iolink; - -/* Example pump structure - * ---------------------- - * - * Used during initial setup of PORTS card in slot 0: - * - * dev = 0100 - * min = 0000 - * cmdcode = 0003 - * options = 0000 - * bufaddr = 808821A0 - * ioaddr = 00000500 - * size = 00000650 - * numbrd = 00000000 - * retcode = 00000008 (PU_NULL) - */ - -typedef struct { - uint16 dev; - uint16 min; - uint16 cmdcode; - uint16 options; - uint32 bufaddr; - uint32 ioaddr; - uint32 size; - uint32 numbrd; - uint32 retcode; -} pump; - -t_stat cio_reset(DEVICE *dptr); -t_stat cio_svc(UNIT *uptr); - -void cio_clear(uint8 cid); -uint32 cio_crc32_shift(uint32 crc, uint8 data); -void cio_cexpress(uint8 cid, uint32 esize, cio_entry *cqe, uint8 *app_data); -void cio_cqueue(uint8 cid, uint8 cmd_stat, uint32 esize, cio_entry *cqe, uint8 *app_data); -t_bool cio_cqueue_avail(uint8 cid, uint32 esize); -void cio_rexpress(uint8 cid, uint32 esize, cio_entry *rqe, uint8 *app_data); -t_stat cio_rqueue(uint8 cid, uint32 qnum, uint32 esize, cio_entry *rqe, uint8 *app_data); -t_bool cio_rqueue_avail(uint8 cid, uint32 qnum, uint32 esize); -uint16 cio_r_lp(uint8 cid, uint32 qnum, uint32 esize); -uint16 cio_r_ulp(uint8 cid, uint32 qnum, uint32 esize); -uint16 cio_c_lp(uint8 cid, uint32 esize); -uint16 cio_c_ulp(uint8 cid, uint32 esize); -void cio_sysgen(uint8 cid); - -uint32 io_read(uint32 pa, size_t size); -void io_write(uint32 pa, uint32 val, size_t size); - -void dump_entry(uint32 dbits, DEVICE *dev, CONST char *type, - uint32 esize, cio_entry *entry, uint8 *app_data); - -extern uint16 cio_int_req; -extern CIO_STATE cio[CIO_SLOTS]; - -#endif +/* 3b2_io.h: Common I/O (CIO) Feature Card Support + + Copyright (c) 2017-2022, Seth J. Morabito + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + Except as contained in this notice, the name of the author shall + not be used in advertising or otherwise to promote the sale, use or + other dealings in this Software without prior written authorization + from the author. +*/ + +/* Reference Documentation + * ======================= + * + * All communication between the system board and feature cards is + * done through in-memory queues, and causing interrupts in the + * feature card by accessing the Control or ID/VEC memory-mapped IO + * addresses. The structure of these queues is defined below in + * tables. + * + * Sysgen Block + * ------------ + * + * Pointed to by address at 0x2000000 after an INT0/INT1 combo + * + * + * | Address | Size | Contents | + * +---------------+------+-----------------------------------------+ + * | SYSGEN_P | 4 | Address of request queue | + * | SYSGEN_P + 4 | 4 | Address of completion queue | + * | SYSGEN_P + 8 | 1 | Number of entries in request queue | + * | SYSGEN_P + 9 | 1 | Number of entries in completion queue | + * | SYSGEN_P + 10 | 1 | Interrupt Vector number | + * | SYSGEN_P + 11 | 1 | Number of request queues | + * + * + * Queue Entry + * ----------- + * + * Each queue has one Express Entry, and n regular entries. + * + * | Address | Size | Contents | + * +---------------+------+-----------------------------------------+ + * | ENTRY_P | 2 | Byte Count | + * | ENTRY_P + 2 | 1 | Subdevice [1] | + * | ENTRY_P + 3 | 1 | Opcode | + * | ENTRY_P + 4 | 4 | Address / Data | + * | ENTRY_P + 8 | 4 | Application Specific Data | + * + * [1] The "Subdevice" entry is further divided into a bitset: + * Bit 7: Command (1) / Status (0) + * Bit 6: Sequence Bit + * Bit 5-1: Subdevice + * + * + * Queue + * ----- + * + * The Queue structures (one for request, one for completion) hold: + * - An express entry + * + * And then one or more queues, each queue consiting of + * - A set of pointers for load and unload from the queue + * - One or more Queue Entries + * + * | Address | Size | Contents | + * +---------------+------+-----------------------------------------+ + * | QUEUE_P | 12 | Express Queue Entry [1] | + * +---------------+------+-----------------------------------------+ + * | QUEUE_P + 12 | 2 | Load Pointer for Queue 0 | + * | QUEUE_P + 14 | 2 | Unload Pointer for Queue 0 | + * | QUEUE_P + 16 | 12 | Queue 0 Entry 0 [1] | + * | QUEUE_P + 28 | 12 | Queue 0 Entry 1 [1] | + * | ... | ... | ... | + * +---------------+------+-----------------------------------------+ + * | QUEUE_P + n | 2 | Load Pointer for Queue 1 | + * | QUEUE_P + n | 2 | Unload Pointer for Queue 1 | + * | QUEUE_P + n | 12 | Queue 1 Entry 0 [1] | + * | QUEUE_P + n | 12 | Queue 1 Entry 1 [1] | + * | ... | ... | ... | + * + * [1] See Queue Entry above + * + * NB: There are multiple Request queues, usually one per subdevice, + * and EACH Request queue starts with a Load Pointer, an Unload + * Pointer, and then 'n' Queue Entries. + * + */ + +#ifndef _3B2_IO_H_ +#define _3B2_IO_H_ + +#include "3b2_defs.h" + +#define CRC_POLYNOMIAL 0xEDB88320 + +#define CIO_SLOTS 12 + +/* IO area */ +#define IO_BOTTOM 0x40000 +#define IO_TOP 0x50000 + +#if defined(REV3) +#define UBUS_BOTTOM 0x1c00000 +#define UBUS_TOP 0x2000000 +#endif + +/* CIO area */ +#define CIO_BOTTOM 0x200000 +#if defined(REV3) +#define CIO_TOP 0x1a00000 +#else +#define CIO_TOP 0x2000000 +#endif + +#define IOF_ID 0 +#define IOF_VEC 1 +#define IOF_CTRL 3 +#define IOF_STAT 5 + +#define SYSGEN_PTR PHYS_MEM_BASE + +/* CIO opcodes */ +#define CIO_DLM 1 +#define CIO_ULM 2 +#define CIO_FCF 3 +#define CIO_DOS 4 +#define CIO_DSD 5 + +/* Response */ +#define CIO_SUCCESS 0 +#define CIO_FAILURE 2 +#define CIO_SYSGEN_OK 3 + +/* Map a physical address to a card ID */ +#define SLOT(pa) (((((pa) >> 0x14) & 0x1f) / 2) - 1) +/* Map a card ID to a base address */ +#define CADDR(bid) (((((bid) + 1) * 2) << 0x14)) + +/* Offsets into the request/completion queues of various values */ +#define LUSIZE 4 /* Load/Unload pointers size */ +#define QESIZE 8 /* Queue entry is 8 bytes + application data */ + +#define CIO_STAT 0 +#define CIO_CMD 1 + +/* Sysgen State */ +#define CIO_INT_NONE 0 +#define CIO_INT0 1 +#define CIO_INT1 2 +#define CIO_SYSGEN 3 + +#define CIO_SET_INT(slot) if (cio[slot].populated && cio[slot].ivec >= 2) (cio_int_req |= (1 << slot)) +#define CIO_CLR_INT(slot) (cio_int_req &= ~(1 << slot)) + +#define CIO_NAME_LEN 8 + +typedef struct { + t_bool populated; /* Populated? */ + uint16 id; /* CIO identifier */ + char name[CIO_NAME_LEN]; /* Device name */ + void (*exp_handler)(uint8 slot); /* Handler for express jobs */ + void (*full_handler)(uint8 slot); /* Handler for full jobs */ + void (*sysgen)(uint8 slot); /* Sysgen routine (optional) */ + void (*reset_handler)(uint8 slot); /* RESET request handler (optional) */ + uint32 rqp; /* Request Queue Pointer */ + uint32 cqp; /* Completion Queue Pointer */ + uint8 rqs; /* Request queue size */ + uint8 cqs; /* Completion queue size */ + uint8 ivec; /* Interrupt Vector */ + uint8 no_rque; /* Number of request queues */ + uint8 ipl; /* IPL that this card uses */ + uint8 sysgen_s; /* Sysgen state */ + uint8 seqbit; /* Squence Bit */ + uint8 op; /* Last received opcode */ +} CIO_STATE; + +typedef struct { + uint16 byte_count; + uint8 subdevice; + uint8 opcode; + uint32 address; +} cio_entry; + +typedef struct { + uint32 low; + uint32 high; + uint32 (*read)(uint32 pa, size_t size); + void (*write)(uint32 pa, uint32 val, size_t size); +} iolink; + +/* Example pump structure + * ---------------------- + * + * Used during initial setup of PORTS card in slot 0: + * + * dev = 0100 + * min = 0000 + * cmdcode = 0003 + * options = 0000 + * bufaddr = 808821A0 + * ioaddr = 00000500 + * size = 00000650 + * numbrd = 00000000 + * retcode = 00000008 (PU_NULL) + */ + +typedef struct { + uint16 dev; + uint16 min; + uint16 cmdcode; + uint16 options; + uint32 bufaddr; + uint32 ioaddr; + uint32 size; + uint32 numbrd; + uint32 retcode; +} pump; + +t_stat cio_reset(DEVICE *dptr); +t_stat cio_svc(UNIT *uptr); + +t_stat cio_install(uint16 id, + CONST char *name, + uint8 ipl, + void (*exp_handler)(uint8 slot), + void (*full_handler)(uint8 slot), + void (*sysgen)(uint8 slot), + void (*reset_handler)(uint8 slot), + uint8 *slot); +void cio_remove(uint8 slot); +void cio_remove_all(uint16 id); +uint32 cio_crc32_shift(uint32 crc, uint8 data); +void cio_cexpress(uint8 slot, uint32 esize, cio_entry *cqe, uint8 *app_data); +void cio_cqueue(uint8 slot, uint8 cmd_stat, uint32 esize, cio_entry *cqe, uint8 *app_data); +t_bool cio_cqueue_avail(uint8 slot, uint32 esize); +void cio_rexpress(uint8 slot, uint32 esize, cio_entry *rqe, uint8 *app_data); +t_stat cio_rqueue(uint8 slot, uint32 qnum, uint32 esize, cio_entry *rqe, uint8 *app_data); +t_bool cio_rqueue_avail(uint8 slot, uint32 qnum, uint32 esize); +uint16 cio_r_lp(uint8 slot, uint32 qnum, uint32 esize); +uint16 cio_r_ulp(uint8 slot, uint32 qnum, uint32 esize); +uint16 cio_c_lp(uint8 slot, uint32 esize); +uint16 cio_c_ulp(uint8 slot, uint32 esize); +void cio_sysgen(uint8 slot); + +uint32 io_read(uint32 pa, size_t size); +void io_write(uint32 pa, uint32 val, size_t size); + +extern uint16 cio_int_req; +extern CIO_STATE cio[CIO_SLOTS]; + +#endif diff --git a/3B2/3b2_iu.c b/3B2/3b2_iu.c index b9a67aa6..2dcc7cba 100644 --- a/3B2/3b2_iu.c +++ b/3B2/3b2_iu.c @@ -1,1045 +1,1147 @@ -/* 3b2_iu.c: SCN2681A Dual UART Implementation - - Copyright (c) 2017, Seth J. Morabito - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - - Except as contained in this notice, the name of the author shall - not be used in advertising or otherwise to promote the sale, use or - other dealings in this Software without prior written authorization - from the author. -*/ - -#include "3b2_iu.h" - -#include "sim_tmxr.h" - -#include "3b2_cpu.h" -#include "3b2_csr.h" -#include "3b2_dmac.h" -#include "3b2_mem.h" -#include "3b2_stddev.h" -#include "3b2_timer.h" - -#define SET_INT do { \ - CPU_SET_INT(INT_UART); \ - SET_CSR(CSRUART); \ - } while (0) - -#define CLR_INT do { \ - CPU_CLR_INT(INT_UART); \ - CLR_CSR(CSRUART); \ - } while (0) - -#if defined(REV3) -#define SET_DMA_INT do { \ - CPU_SET_INT(INT_UART_DMA); \ - SET_CSR(CSRDMA); \ - } while (0) - -#define CLR_DMA_INT do { \ - CPU_CLR_INT(INT_UART_DMA); \ - CLR_CSR(CSRDMA); \ - } while (0) -#else -#define SET_DMA_INT do { \ - CPU_SET_INT(INT_DMA); \ - SET_CSR(CSRDMA); \ - } while (0) - -#define CLR_DMA_INT do { \ - CPU_CLR_INT(INT_DMA); \ - CLR_CSR(CSRDMA); \ - } while (0) -#endif - -/* Static function declarations */ -static SIM_INLINE void iu_w_cmd(uint8 portno, uint8 val); - -/* - * The 3B2/400 has two on-board serial ports, labeled CONSOLE and - * CONTTY. The CONSOLE port is (naturally) the system console. The - * CONTTY port serves as a secondary serial port for an additional - * terminal. - * - * These lines are driven by an SCN2681A Dual UART, with two receivers - * and two transmitters. - * - * In addition to the two TX/RX ports, the SCN27681A also has one - * programmable timer. - * - * The SCN2681A UART is represented here by four devices: - * - * - Console TTI (Input, port A) - * - Console TTO (Output, port A) - * - Contty (I/O, port B. Terminal multiplexer with one line) - * - IU Timer - */ - - -/* - * Registers - */ - -/* The IU state shared between A and B */ -IU_STATE iu_state; - -/* The tx/rx state for ports A and B */ -IU_PORT iu_console; -IU_PORT iu_contty; - -/* The timer state */ -IU_TIMER_STATE iu_timer_state; - -/* Flags for incrementing mode pointers */ -t_bool iu_increment_a = FALSE; -t_bool iu_increment_b = FALSE; - -BITFIELD sr_bits[] = { - BIT(RXRDY), - BIT(FFULL), - BIT(TXRDY), - BIT(TXEMT), - BIT(OVRN_E), - BIT(PRTY_E), - BIT(FRM_E), - BIT(BRK), - ENDBITS -}; - -BITFIELD isr_bits[] = { - BIT(TXRDYA), - BIT(RXRDY_FFA), - BIT(DLTA_BRKA), - BIT(CTR_RDY), - BIT(TXRDYB), - BIT(RXRDY_FFB), - BIT(DLTA_BRKB), - BIT(IPC), - ENDBITS -}; - -BITFIELD acr_bits[] = { - BIT(BRG_SET), - BITFFMT(TMR_MODE,3,%d), - BIT(DLTA_IP3), - BIT(DLTA_IP2), - BIT(DLTA_IP1), - BIT(DLTA_IP0), - ENDBITS -}; - -BITFIELD conf_bits[] = { - BIT(TX_EN), - BIT(RX_EN), - ENDBITS -}; - -/* TTI (Console) data structures */ - -REG tti_reg[] = { - { HRDATADF(STAT, iu_console.stat, 8, "Status", sr_bits) }, - { HRDATADF(CONF, iu_console.conf, 8, "Config", conf_bits) }, - { BRDATAD(DATA, iu_console.rxbuf, 16, 8, IU_BUF_SIZE, "Data") }, - { NULL } -}; - -UNIT tti_unit = { UDATA(&iu_svc_tti, UNIT_IDLE, 0), TMLN_SPD_9600_BPS }; - -DEVICE tti_dev = { - "TTI", &tti_unit, tti_reg, NULL, - 1, 8, 32, 1, 8, 8, - NULL, NULL, &tti_reset, - NULL, NULL, NULL, NULL, - DEV_DEBUG, 0, sys_deb_tab -}; - -/* TTO (Console) data structures */ - -REG tto_reg[] = { - { HRDATADF(STAT, iu_console.stat, 8, "Status", sr_bits) }, - { HRDATADF(ISTAT, iu_state.istat, 8, "Interrupt Status", isr_bits) }, - { HRDATAD(IMR, iu_state.imr, 8, "Interrupt Mask") }, - { HRDATADF(ACR, iu_state.acr, 8, "Auxiliary Control Register", acr_bits) }, - { HRDATAD(DATA, iu_console.txbuf, 8, "Data") }, - { NULL } -}; - -UNIT tto_unit = { UDATA(&iu_svc_tto, TT_MODE_8B, 0), SERIAL_OUT_WAIT }; - -DEVICE tto_dev = { - "TTO", &tto_unit, tto_reg, NULL, - 1, 8, 32, 1, 8, 8, - NULL, NULL, NULL, - NULL, NULL, NULL, NULL, - DEV_DEBUG, 0, sys_deb_tab -}; - -/* CONTTY data structures */ - -/* - * The CONTTY "multiplexer" is a bit unusual in that it serves only a - * single line, representing the built-in CONTTY port. On a real - * 3B2/400, the system board's dual UART serves both CONSOLE and - * CONTTY lines, giving support for two terminals. In the simulator, - * the CONSOLE is served by TTI and TTO devices, whereas the CONTTY is - * served by a TMXR multiplexer. - */ - -TMLN *contty_ldsc = NULL; -TMXR contty_desc = { 1, 0, 0, NULL }; - -REG contty_reg[] = { - { HRDATADF(STAT, iu_contty.stat, 8, "Status", sr_bits) }, - { HRDATADF(CONF, iu_contty.conf, 8, "Config", conf_bits) }, - { BRDATAD(RXDATA, iu_contty.rxbuf, 16, 8, IU_BUF_SIZE, "RX Data") }, - { HRDATAD(TXDATA, iu_contty.txbuf, 8, "TX Data") }, - { HRDATADF(ISTAT, iu_state.istat, 8, "Interrupt Status", isr_bits) }, - { HRDATAD(IMR, iu_state.imr, 8, "Interrupt Mask") }, - { HRDATADF(ACR, iu_state.acr, 8, "Auxiliary Control Register", acr_bits) }, - { NULL } -}; - -CONST char *brg_rates[IU_SPEED_REGS][IU_SPEEDS] = { - {NULL, "110", NULL, NULL, - "300", NULL, NULL, "1200", - "2400", "4800", NULL, "9600", - "38400", NULL, NULL, NULL}, - {NULL, "110", NULL, NULL, - "300", NULL, "1200", NULL, - NULL, "2400", "4800", "9600", - "19200", NULL, NULL, NULL} -}; - -CONST char *parity[3] = {"O", "E", "N"}; - -UNIT contty_unit[2] = { - { UDATA(&iu_svc_contty_rcv, UNIT_ATTABLE, 0) }, - { UDATA(&iu_svc_contty_xmt, TT_MODE_8B, 0), SERIAL_OUT_WAIT } -}; - -UNIT *contty_rcv_unit = &contty_unit[0]; -UNIT *contty_xmt_unit = &contty_unit[1]; - -DEBTAB contty_deb_tab[] = { - {"EXEC", EXECUTE_MSG, "Execute"}, - {"XMT", TMXR_DBG_XMT, "Transmitted Data"}, - {"RCV", TMXR_DBG_RCV, "Received Data"}, - {"MDM", TMXR_DBG_MDM, "Modem Signals"}, - {"CON", TMXR_DBG_CON, "connection activities"}, - {"TRC", TMXR_DBG_TRC, "trace routine calls"}, - {"ASY", TMXR_DBG_ASY, "Asynchronous Activities"}, - {0} -}; - - -DEVICE contty_dev = { - "CONTTY", contty_unit, contty_reg, NULL, - 1, 8, 32, 1, 8, 8, - &tmxr_ex, &tmxr_dep, &contty_reset, - NULL, &contty_attach, &contty_detach, - NULL, DEV_DISABLE|DEV_DEBUG|DEV_MUX, - 0, contty_deb_tab, NULL, NULL, - NULL, NULL, - (void *)&contty_desc, - NULL -}; - -/* IU Timer data structures */ - -REG iu_timer_reg[] = { - { HRDATAD(CTR_SET, iu_timer_state.c_set, 16, "Counter Setting") }, - { NULL } -}; - -UNIT iu_timer_unit = { UDATA(&iu_svc_timer, 0, 0) }; - -DEVICE iu_timer_dev = { - "IUTIMER", &iu_timer_unit, iu_timer_reg, NULL, - 1, 8, 32, 1, 8, 8, - NULL, NULL, &iu_timer_reset, - NULL, NULL, NULL, NULL, - DEV_DEBUG, 0, sys_deb_tab -}; - -uint8 brg_reg = 0; /* Selected baud-rate generator register */ -uint8 brg_clk = 11; /* Selected baud-rate generator clock */ -uint8 parity_sel = 1; /* Selected parity */ -uint8 bits_per_char = 7; - - -t_stat contty_attach(UNIT *uptr, CONST char *cptr) -{ - t_stat r; - TMLN *lp; - - tmxr_set_modem_control_passthru(&contty_desc); - - r = tmxr_attach(&contty_desc, uptr, cptr); - if (r != SCPE_OK) { - tmxr_clear_modem_control_passthru(&contty_desc); - return r; - } - - lp = &contty_ldsc[0]; - tmxr_set_get_modem_bits(lp, TMXR_MDM_DTR|TMXR_MDM_RTS, 0, NULL); - - return SCPE_OK; -} - -t_stat contty_detach(UNIT *uptr) -{ - t_stat r = tmxr_detach(&contty_desc, uptr); - tmxr_clear_modem_control_passthru(&contty_desc); - - return r; -} - -void increment_modep_a() -{ - iu_increment_a = FALSE; - iu_console.modep++; - - if (iu_console.modep > 1) { - iu_console.modep = 0; - } -} - -void increment_modep_b() -{ - iu_increment_b = FALSE; - iu_contty.modep++; - - if (iu_contty.modep > 1) { - iu_contty.modep = 0; - } -} - -void iu_txrdy_a_irq() { - if ((iu_state.imr & IMR_TXRA) && - (iu_console.conf & TX_EN) && - (iu_console.stat & STS_TXR)) { - sim_debug(EXECUTE_MSG, &tto_dev, - "[iu_txrdy_a_irq()] Firing IRQ after transmit of %02x (%c)\n", - (uint8) iu_console.txbuf, PCHAR(iu_console.txbuf)); - SET_INT; - } -} - -void iu_txrdy_b_irq() { - if ((iu_state.imr & IMR_TXRB) && - (iu_contty.conf & TX_EN) && - (iu_contty.stat & STS_TXR)) { - sim_debug(EXECUTE_MSG, &contty_dev, - "[iu_txrdy_b_irq()] Firing IRQ after transmit of %02x (%c)\n", - (uint8) iu_contty.txbuf, PCHAR(iu_contty.txbuf)); - SET_INT; - } -} - -t_stat tti_reset(DEVICE *dptr) -{ - memset(&iu_state, 0, sizeof(IU_STATE)); - memset(&iu_console, 0, sizeof(IU_PORT)); - - /* Input Port logic is inverted - 0 means set */ - iu_state.inprt = ~(IU_DCDA); - - /* Start the Console TTI polling loop */ - if (!sim_is_active(&tti_unit)) { - sim_activate_after(&tti_unit, tti_unit.wait); - } - - return SCPE_OK; -} - -t_stat contty_reset(DEVICE *dtpr) -{ - char line_config[16]; - - if (contty_ldsc == NULL) { - contty_desc.ldsc = - contty_ldsc = - (TMLN *)calloc(1, sizeof(*contty_ldsc)); - } - - tmxr_set_port_speed_control(&contty_desc); - tmxr_set_line_unit(&contty_desc, 0, contty_rcv_unit); - tmxr_set_line_output_unit(&contty_desc, 0, contty_xmt_unit); - tmxr_set_console_units(&tti_unit, &tto_unit); - - memset(&iu_state, 0, sizeof(IU_STATE)); - memset(&iu_contty, 0, sizeof(IU_PORT)); - - /* DCD is off (inverted logic, 1 means off) */ - iu_state.inprt |= IU_DCDB; - - brg_reg = 0; - brg_clk = BRG_DEFAULT; - parity_sel = IU_PARITY_EVEN; - bits_per_char = 7; - - sprintf(line_config, "%s-%d%s1", - brg_rates[brg_reg][brg_clk], - bits_per_char, - parity[parity_sel]); - - tmxr_set_config_line(&contty_ldsc[0], line_config); - - /* Start the CONTTY polling loop */ - if (!sim_is_active(contty_rcv_unit)) { - sim_activate_after(contty_rcv_unit, contty_rcv_unit->wait); - } - - return SCPE_OK; -} - -t_stat iu_timer_reset(DEVICE *dptr) -{ - memset(&iu_timer_state, 0, sizeof(IU_TIMER_STATE)); - - return SCPE_OK; -} - -/* Service routines */ - -t_stat iu_svc_tti(UNIT *uptr) -{ - int32 temp; - - tmxr_clock_coschedule(uptr, tmxr_poll); - - /* TODO: - - - If there has been a change on IP0-IP3, set the corresponding - bits in IPCR, if configured to do so. We'll need to figure out - how these are wired (DCD pin, etc?) - - - Update the Output Port pins (which are logically inverted) - based on the contents of the OPR, OPCR, MR, and CR registers. - */ - - if ((temp = sim_poll_kbd()) < SCPE_KFLAG) { - return temp; - } - - if (iu_console.conf & RX_EN) { - if ((iu_console.stat & STS_FFL) == 0) { - iu_console.rxbuf[iu_console.w_p] = (temp & 0xff); - iu_console.w_p = (iu_console.w_p + 1) % IU_BUF_SIZE; - if (iu_console.w_p == iu_contty.w_p) { - iu_console.stat |= STS_FFL; - } - } - iu_console.stat |= STS_RXR; - iu_state.istat |= ISTS_RAI; - if (iu_state.imr & IMR_RXRA) { - SET_INT; - } - } - - return SCPE_OK; -} - - -t_stat iu_svc_tto(UNIT *uptr) -{ - /* If there's more DMA to do, do it */ - if (iu_console.dma && ((dma_state.mask >> DMA_IUA_CHAN) & 0x1) == 0) { - iu_dma_console(DMA_IUA_CHAN, IUBASE+IUA_DATA_REG); - } else { - /* The buffer is now empty, we've transmitted, so set TXR */ - iu_console.stat |= STS_TXR; - iu_state.istat |= 1; - iu_txrdy_a_irq(); - } - - return SCPE_OK; -} - -t_stat iu_svc_contty_rcv(UNIT *uptr) -{ - int32 temp, ln; - - if ((uptr->flags & UNIT_ATT) == 0) { - return SCPE_OK; - } - - /* Check for connect */ - if ((ln = tmxr_poll_conn(&contty_desc)) >= 0) { - contty_ldsc[ln].rcve = 1; - iu_state.inprt &= ~(IU_DCDB); - iu_state.ipcr |= IU_DCDB; - SET_INT; - } - - /* Check for disconnect */ - if (!contty_ldsc[0].conn && (iu_state.inprt & IU_DCDB) == 0) { - contty_ldsc[0].rcve = 0; - iu_state.inprt |= IU_DCDB; - iu_state.ipcr |= IU_DCDB; - SET_INT; - } else if (iu_contty.conf & RX_EN) { - tmxr_poll_rx(&contty_desc); - - if (contty_ldsc[0].conn) { - temp = tmxr_getc_ln(&contty_ldsc[0]); - if (temp && !(temp & SCPE_BREAK)) { - if ((iu_contty.stat & STS_FFL) == 0) { - iu_contty.rxbuf[iu_contty.w_p] = (temp & 0xff); - iu_contty.w_p = (iu_contty.w_p + 1) % IU_BUF_SIZE; - if (iu_contty.w_p == iu_contty.r_p) { - iu_contty.stat |= STS_FFL; - } - } - iu_contty.stat |= STS_RXR; - iu_state.istat |= ISTS_RBI; - if (iu_state.imr & IMR_RXRB) { - SET_INT; - } - } - } - } - - tmxr_clock_coschedule(uptr, tmxr_poll); - - return SCPE_OK; -} - -t_stat iu_svc_contty_xmt(UNIT *uptr) -{ - dma_channel *chan = &dma_state.channels[DMA_IUB_CHAN]; - - tmxr_poll_tx(&contty_desc); - - /* If there's more DMA to do, do it */ - if (chan->wcount_c >= 0) { - iu_dma_contty(DMA_IUB_CHAN, IUBASE+IUB_DATA_REG); - } else { - /* The buffer is now empty, we've transmitted, so set TXR */ - iu_contty.stat |= STS_TXR; - iu_state.istat |= 0x10; - iu_txrdy_b_irq(); - } - - return SCPE_OK; -} - -t_stat iu_svc_timer(UNIT *uptr) -{ - iu_state.istat |= ISTS_CRI; - - if (iu_state.imr & IMR_CTR) { - SET_INT; - } - - return SCPE_OK; -} - -/* - * Reg | Name (Read) | Name (Write) - * -----+-------------------------+---------------------------- - * 0 | Mode Register 1/2 A | Mode Register 1/2 A - * 1 | Status Register A | Clock Select Register A - * 2 | BRG Test | Command Register A - * 3 | Rx Holding Register A | Tx Holding Register A - * 4 | Input Port Change Reg. | Aux. Control Register - * 5 | Interrupt Status Reg. | Interrupt Mask Register - * 6 | Counter/Timer Upper Val | C/T Upper Preset Val. - * 7 | Counter/Timer Lower Val | C/T Lower Preset Val. - * 8 | Mode Register B | Mode Register B - * 9 | Status Register B | Clock Select Register B - * 10 | 1X/16X Test | Command Register B - * 11 | Rx Holding Register B | Tx Holding Register B - * 12 | *Reserved* | *Reserved* - * 13 | Input Ports IP0 to IP6 | Output Port Conf. Reg. - * 14 | Start Counter Command | Set Output Port Bits Cmd. - * 15 | Stop Counter Command | Reset Output Port Bits Cmd. - */ - - -uint32 iu_read(uint32 pa, size_t size) -{ - uint8 reg, modep; - uint32 data = 0; - - reg = (uint8) (pa - IUBASE); - - switch (reg) { - case MR12A: - modep = iu_console.modep; - data = iu_console.mode[modep]; - iu_increment_a = TRUE; - break; - case SRA: - data = iu_console.stat; - break; - case RHRA: - if (iu_console.conf & RX_EN) { - data = iu_console.rxbuf[iu_console.r_p]; - iu_console.r_p = (iu_console.r_p + 1) % IU_BUF_SIZE; - /* If the FIFO is not empty, we must cause another interrupt - * to continue reading */ - if (iu_console.r_p == iu_console.w_p) { - iu_console.stat &= ~(STS_RXR|STS_FFL); - iu_state.istat &= ~ISTS_RAI; - } else if (iu_state.imr & IMR_RXRA) { - SET_INT; - } - } - break; - case IPCR: - data = iu_state.ipcr; - /* Reading the port resets it */ - iu_state.ipcr = 0; - CLR_INT; - break; - case ISR: - data = iu_state.istat; - break; - case CTU: - data = (iu_timer_state.c_set >> 8) & 0xff; - break; - case CTL: - data = iu_timer_state.c_set & 0xff; - break; - case MR12B: - modep = iu_contty.modep; - data = iu_contty.mode[modep]; - iu_increment_b = TRUE; - break; - case SRB: - data = iu_contty.stat; - break; - case RHRB: - if (iu_contty.conf & RX_EN) { - data = iu_contty.rxbuf[iu_contty.r_p]; - iu_contty.r_p = (iu_contty.r_p + 1) % IU_BUF_SIZE; - /* If the FIFO is not empty, we must cause another interrupt - * to continue reading */ - if (iu_contty.r_p == iu_contty.w_p) { - iu_contty.stat &= ~(STS_RXR|STS_FFL); - iu_state.istat &= ~ISTS_RBI; - } else if (iu_state.imr & IMR_RXRB) { - SET_INT; - } - } - break; - case INPRT: - data = iu_state.inprt; - break; - case START_CTR: - data = 0; - iu_state.istat &= ~ISTS_CRI; - sim_activate_abs(&iu_timer_unit, (int32)(iu_timer_state.c_set * IU_TIMER_RATE)); - break; - case STOP_CTR: - data = 0; - iu_state.istat &= ~ISTS_CRI; - CLR_INT; - sim_cancel(&iu_timer_unit); - break; - case 17: /* Clear DMAC interrupt */ - data = 0; - CLR_DMA_INT; - break; - default: - break; - } - - return data; -} - -void iu_write(uint32 pa, uint32 val, size_t size) -{ - uint8 reg; - uint8 modep; - uint8 bval = (uint8) val; - char line_config[16]; - - reg = (uint8) (pa - IUBASE); - - switch (reg) { - case MR12A: - modep = iu_console.modep; - iu_console.mode[modep] = bval; - iu_increment_a = TRUE; - break; - case CSRA: - if (brg_rates[brg_reg][brg_clk] != NULL) { - sprintf(line_config, "%s-%d%s1", - brg_rates[brg_reg][brg_clk], - bits_per_char, - parity[parity_sel]); - - sim_debug(EXECUTE_MSG, &contty_dev, - "Setting CONTTY line to %s\n", - line_config); - - tmxr_set_config_line(&contty_ldsc[0], line_config); - } - break; - case CRA: /* Command A */ - iu_w_cmd(PORT_A, bval); - break; - case THRA: /* TX/RX Buf A */ - iu_tx(PORT_A, bval); - sim_activate_abs(&tto_unit, tto_unit.wait); - break; - case ACR: /* Auxiliary Control Register */ - iu_state.acr = bval; - brg_reg = (bval >> 7) & 1; - break; - case IMR: - iu_state.imr = bval; - sim_debug(EXECUTE_MSG, &tto_dev, - "[%08x] Write IMR = %x\n", - R[NUM_PC], bval); - CLR_INT; - /* Possibly cause an interrupt */ - iu_txrdy_a_irq(); - iu_txrdy_b_irq(); - break; - case CTUR: /* Counter/Timer Upper Preset Value */ - /* Clear out high byte */ - iu_timer_state.c_set &= 0x00ff; - /* Set high byte */ - iu_timer_state.c_set |= ((uint16) bval << 8); - break; - case CTLR: /* Counter/Timer Lower Preset Value */ - /* Clear out low byte */ - iu_timer_state.c_set &= 0xff00; - /* Set low byte */ - iu_timer_state.c_set |= bval; - break; - case MR12B: - modep = iu_contty.modep; - iu_contty.mode[modep] = bval; - iu_increment_b = TRUE; - if (modep == 0) { - if ((bval >> 4) & 1) { - /* No parity */ - parity_sel = IU_PARITY_NONE; - } else { - /* Parity enabled */ - if (bval & 4) { - parity_sel = IU_PARITY_ODD; - } else { - parity_sel = IU_PARITY_EVEN; - } - } - - bits_per_char = (bval & 3) + 5; - } - break; - case CRB: /* Command B */ - iu_w_cmd(PORT_B, bval); - break; - case CSRB: - brg_clk = (bval >> 4) & 0xf; - - if (brg_rates[brg_reg][brg_clk] != NULL) { - sprintf(line_config, "%s-%d%s1", - brg_rates[brg_reg][brg_clk], - bits_per_char, - parity[parity_sel]); - - sim_debug(EXECUTE_MSG, &contty_dev, - "Setting CONTTY line to %s\n", - line_config); - - tmxr_set_config_line(&contty_ldsc[0], line_config); - } - - break; - case THRB: /* TX/RX Buf B */ - iu_tx(PORT_B, bval); - sim_activate_abs(contty_xmt_unit, contty_ldsc[0].txdeltausecs); - break; - case OPCR: - iu_state.opcr = bval; - break; - case SOPR: - /* Bit 2 of the IU output register is used as a soft power - * switch. When set, the machine will power down - * immediately. */ - if (bval & IU_KILLPWR) { - stop_reason = STOP_POWER; - } - break; - case ROPR: - break; - default: - break; - } -} - -t_stat iu_tx(uint8 portno, uint8 val) -{ - IU_PORT *p = (portno == PORT_A) ? &iu_console : &iu_contty; - uint8 ists = (portno == PORT_A) ? ISTS_RAI : ISTS_RBI; - uint8 imr_mask = (portno == PORT_A) ? IMR_RXRA : IMR_RXRB; - int32 c; - t_stat status = SCPE_OK; - - if (p->conf & TX_EN) { - if ((p->mode[1] & 0xc0) == 0x80) { /* Loopback mode */ - p->txbuf = val; - - /* This is also a Receive */ - if ((p->stat & STS_FFL) == 0) { - p->rxbuf[p->w_p] = val; - p->w_p = (p->w_p + 1) % IU_BUF_SIZE; - if (p->w_p == p->r_p) { - p->stat |= STS_FFL; - } - } - - p->stat |= STS_RXR; - if (iu_state.imr & imr_mask) { - iu_state.istat |= ists; - SET_INT; - } - - return SCPE_OK; - } else { /* Direct mode */ - c = sim_tt_outcvt(val, TTUF_MODE_8B); - - if (c >= 0) { - p->txbuf = c; - p->stat &= ~(STS_TXR|STS_TXE); - iu_state.istat &= ~(1 << (portno*4)); - - if (portno == PORT_A) { - /* Write the character to the SIMH console */ - sim_debug(EXECUTE_MSG, &tto_dev, - "[iu_tx] CONSOLE transmit %02x (%c)\n", - (uint8) c, PCHAR(c)); - status = sim_putchar_s(c); - } else { - sim_debug(EXECUTE_MSG, &contty_dev, - "[iu_tx] CONTTY transmit %02x (%c)\n", - (uint8) c, PCHAR(c)); - status = tmxr_putc_ln(&contty_ldsc[0], c); - } - } - } - } - - return status; -} - -static SIM_INLINE void iu_w_cmd(uint8 portno, uint8 cmd) -{ - - IU_PORT *p; - - if (portno == 0) { - p = &iu_console; - } else { - p = &iu_contty; - } - - /* Enable or disable transmitter */ - /* Disable always wins, if both are set */ - if (cmd & CMD_DTX) { - p->conf &= ~TX_EN; - p->stat &= ~STS_TXR; - p->stat &= ~STS_TXE; - p->drq = FALSE; - p->dma = FALSE; - } else if (cmd & CMD_ETX) { - p->conf |= TX_EN; - /* TXE and TXR are always set by an ENABLE */ - p->stat |= STS_TXR; - p->stat |= STS_TXE; - p->drq = TRUE; - iu_state.istat |= 1 << (portno*4); - if (portno == 0) { - iu_txrdy_a_irq(); - } else { - iu_txrdy_b_irq(); - } - } - - /* Enable or disable receiver. */ - /* Disable always wins, if both are set */ - if (cmd & CMD_DRX) { - p->conf &= ~RX_EN; - p->stat &= ~STS_RXR; - } else if (cmd & CMD_ERX) { - p->conf |= RX_EN; - } - - /* Command register bits 6-4 have special meaning */ - switch ((cmd >> CMD_MISC_SHIFT) & CMD_MISC_MASK) { - case 1: - /* Causes the Channel A MR pointer to point to MR1. */ - p->modep = 0; - break; - case 2: - /* Reset receiver. Resets the Channel's receiver as if a - hardware reset had been applied. The receiver is disabled - and the FIFO is flushed. */ - p->stat &= ~STS_RXR; - p->conf &= ~RX_EN; - p->w_p = 0; - p->r_p = 0; - break; - case 3: - /* Reset transmitter. Resets the Channel's transmitter as if a - hardware reset had been applied. */ - p->stat &= ~STS_TXR; - p->stat &= ~STS_TXE; - p->conf &= ~TX_EN; - p->w_p = 0; - p->r_p = 0; - break; - case 4: - /* Reset error status. Clears the Channel's Received Break, - Parity Error, and Overrun Error bits in the status register - (SRA[7:4]). Used in character mode to clear OE status - (although RB, PE and FE bits will also be cleared) and in - block mode to clear all error status after a block of data - has been received. */ - p->stat &= ~(STS_FER|STS_PER|STS_OER); - break; - case 5: - /* Reset Channel's break change interrupt. Causes the Channel - A break detect change bit in the interrupt status register - (ISR[2] for Chan. A, ISR[6] for Chan. B) to be cleared to - zero. */ - iu_state.istat &= ~(1 << (2 + portno*4)); - break; - case 6: - /* Start break. Forces the TxDA output LOW (spacing). If the - transmitter is empty the start of the break condition will - be delayed up to two bit times. If the transmitter is - active the break begins when transmission of the character - is completed. If a character is in the THR, the start of - the break will be delayed until that character, or any - other loaded subsequently are transmitted. The transmitter - must be enabled for this command to be accepted. */ - /* Not Implemented */ - break; - case 7: - /* Stop break. The TxDA line will go HIGH (marking) within two - bit times. TxDA will remain HIGH for one bit time before - the next character, if any, is transmitted. */ - /* Not Implemented */ - break; - } -} - -/* - * Initiate DMA transfer or continue one already in progress. - */ -void iu_dma_console(uint8 channel, uint32 service_address) -{ - uint8 data; - uint32 addr; - t_stat status = SCPE_OK; - dma_channel *chan = &dma_state.channels[channel]; - UNIT *uptr = &tto_unit; - IU_PORT *port = &iu_console; - - /* Immediate acknowledge of DMA */ - port->drq = FALSE; - - if (!port->dma) { - /* Set DMA transfer type */ - port->dma = 1u << ((dma_state.mode >> 2) & 0xf); - } - - if (port->dma == DMA_READ) { - addr = dma_address(channel, chan->ptr, TRUE); - chan->addr_c = chan->addr + chan->ptr + 1; - data = pread_b(addr); - status = iu_tx(channel - 2, data); - if (status == SCPE_OK) { - chan->ptr++; - chan->wcount_c--; - } - - sim_activate_abs(uptr, uptr->wait); - - if (chan->wcount_c >= 0) { - /* Return early so we don't finish DMA */ - return; - } - } - - /* Cancel any pending interrupts, we're done. */ - /* TODO: I THINK THIS BREAKS EVERYTHING!!!! */ - /* sim_cancel(uptr); */ - - /* Done with DMA */ - port->dma = DMA_NONE; - - dma_state.mask |= (1 << channel); - dma_state.status |= (1 << channel); - SET_DMA_INT; -} - -void iu_dma_contty(uint8 channel, uint32 service_address) -{ - uint8 data; - uint32 addr; - t_stat status = SCPE_OK; - dma_channel *chan = &dma_state.channels[channel]; - UNIT *uptr = contty_xmt_unit; - IU_PORT *port = &iu_contty; - uint32 wait = 0x7fffffff; - - /* Immediate acknowledge of DMA */ - port->drq = FALSE; - - if (!port->dma) { - /* Set DMA transfer type */ - port->dma = 1u << ((dma_state.mode >> 2) & 0xf); - } - - if (port->dma == DMA_READ) { - addr = dma_address(channel, chan->ptr, TRUE); - chan->addr_c = chan->addr + chan->ptr + 1; - data = pread_b(addr); - status = iu_tx(channel - 2, data); - if (status == SCPE_OK) { - wait = MIN(wait, contty_ldsc[0].txdeltausecs); - chan->ptr++; - chan->wcount_c--; - } - - tmxr_activate_after(uptr, wait); - - if (chan->wcount_c >= 0) { - /* Return early so we don't finish DMA */ - return; - } - } - - /* Done with DMA */ - port->dma = DMA_NONE; - - dma_state.mask |= (1 << channel); - dma_state.status |= (1 << channel); - SET_DMA_INT; -} +/* 3b2_iu.c: SCN2681A Dual UART + + Copyright (c) 2017-2022, Seth J. Morabito + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + Except as contained in this notice, the name of the author shall + not be used in advertising or otherwise to promote the sale, use or + other dealings in this Software without prior written authorization + from the author. +*/ + +#include "3b2_iu.h" + +#include "sim_tmxr.h" + +#include "3b2_cpu.h" +#include "3b2_csr.h" +#include "3b2_dmac.h" +#include "3b2_mem.h" +#include "3b2_stddev.h" +#include "3b2_timer.h" + +/* + * The 3B2/400 and 3B2/700 both have two on-board serial ports, + * labeled CONSOLE and CONTTY. The CONSOLE port is the system console. + * The CONTTY port serves as a secondary serial port for one + * additional terminal. + * + * These lines are driven by an SCN2681A Dual UART, with two receivers + * and two transmitters. + * + * In addition to the two TX/RX ports, the SCN27681A also has one + * programmable timer that is used in the 3B2 for various one-shot + * timing tasks. + * + * The SCN2681A UART is represented here by four devices: + * + * - Console TTI (Console Input, port A) + * - Console TTO (Console Output, port A) + * - CONTTY (I/O, port B. Terminal multiplexer with one line) + * - IU Timer + */ + +#if defined(REV3) +#define DMA_INT INT_UART_DMA +#else +#define DMA_INT INT_DMA +#endif + +#define UPDATE_IRQ do { \ + if (iu_state.imr & iu_state.isr) { \ + CPU_SET_INT(INT_UART); \ + SET_CSR(CSRUART); \ + } else { \ + CPU_CLR_INT(INT_UART); \ + CLR_CSR(CSRUART); \ + } \ + } while (0) + +#define SET_DMA_INT do { \ + CPU_SET_INT(DMA_INT); \ + SET_CSR(CSRDMA); \ + } while (0) + +#define CLR_DMA_INT do { \ + CPU_CLR_INT(DMA_INT); \ + CLR_CSR(CSRDMA); \ + } while (0) + +#define LOOPBACK(P) (((P)->mode[1] & 0xc0) == 0x80) +#define TX_ENABLED(P) ((P).conf & TX_EN) +#define PORTNO(P) ((P) == &iu_console ? PORT_A : PORT_B) + +/* Static function declarations */ +static void iu_w_cmd(IU_PORT *port, uint8 val); +static t_stat iu_tx(IU_PORT *port, uint8 val); +static void iu_rx(IU_PORT *port, uint8 val); +static uint8 iu_rx_getc(IU_PORT *port); + +/* + * Registers + */ + +/* The IU state shared between A and B */ +IU_STATE iu_state; + +/* The tx/rx state for ports A and B */ +IU_PORT iu_console; +IU_PORT iu_contty; + +/* The timer state */ +IU_TIMER_STATE iu_timer_state; + +/* Flags for incrementing mode pointers */ +t_bool iu_increment_a = FALSE; +t_bool iu_increment_b = FALSE; + +double iu_timer_multiplier = IU_TIMER_MULTIPLIER; + +BITFIELD sr_bits[] = { + BIT(RXRDY), + BIT(FFULL), + BIT(TXRDY), + BIT(TXEMT), + BIT(OVRN_E), + BIT(PRTY_E), + BIT(FRM_E), + BIT(BRK), + ENDBITS +}; + +BITFIELD isr_bits[] = { + BIT(TXRDYA), + BIT(RXRDY_FFA), + BIT(DLTA_BRKA), + BIT(CTR_RDY), + BIT(TXRDYB), + BIT(RXRDY_FFB), + BIT(DLTA_BRKB), + BIT(IPC), + ENDBITS +}; + +BITFIELD acr_bits[] = { + BIT(BRG_SET), + BITFFMT(TMR_MODE,3,%d), + BIT(DLTA_IP3), + BIT(DLTA_IP2), + BIT(DLTA_IP1), + BIT(DLTA_IP0), + ENDBITS +}; + +BITFIELD conf_bits[] = { + BIT(TX_EN), + BIT(RX_EN), + ENDBITS +}; + +/* TTI (Console) data structures */ + +UNIT tti_unit = { UDATA(&iu_svc_tti, UNIT_IDLE|TT_MODE_8B, 0), SERIAL_IN_WAIT }; + +REG tti_reg[] = { + { HRDATADF(SRA, iu_console.sr, 8, "Status", sr_bits) }, + { HRDATADF(CONF, iu_console.conf, 8, "Config", conf_bits) }, + { BRDATAD(DATA, iu_console.rxbuf, 16, 8, IU_BUF_SIZE, "Data") }, + { DRDATAD(POS, tti_unit.pos, T_ADDR_W, "number of characters input"), PV_LEFT }, + { DRDATAD(TIME, tti_unit.wait, 24, "input polling interval"), PV_LEFT }, + { NULL } +}; + +DEVICE tti_dev = { + "TTI", &tti_unit, tti_reg, NULL, + 1, 8, 32, 1, 8, 8, + NULL, NULL, &tti_reset, + NULL, NULL, NULL, NULL, + DEV_DEBUG, 0, sys_deb_tab +}; + +/* TTO (Console) data structures */ + +UNIT tto_unit = { UDATA(&iu_svc_tto, UNIT_IDLE|TT_MODE_8B, 0), SERIAL_OUT_WAIT }; + +REG tto_reg[] = { + { HRDATADF(SRA, iu_console.sr, 8, "Status Register", sr_bits) }, + { HRDATADF(ISR, iu_state.isr, 8, "Interrupt Status", isr_bits) }, + { HRDATAD(IMR, iu_state.imr, 8, "Interrupt Mask") }, + { HRDATADF(ACR, iu_state.acr, 8, "Aux. Control Register", acr_bits) }, + { NULL } +}; + +DEVICE tto_dev = { + "TTO", &tto_unit, tto_reg, NULL, + 1, 8, 32, 1, 8, 8, + NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + DEV_DEBUG, 0, sys_deb_tab +}; + +/* CONTTY data structures */ + +/* + * The CONTTY "multiplexer" is a bit unusual in that it serves only a + * single line, representing the built-in CONTTY port. On a real + * 3B2/400, the system board's dual UART serves both CONSOLE and + * CONTTY lines, giving support for two terminals. In the simulator, + * the CONSOLE is served by TTI and TTO devices, whereas the CONTTY is + * served by a TMXR multiplexer. + */ + +TMLN contty_ldsc[1] = { 0 }; +TMXR contty_desc = { 1, 0, 0, contty_ldsc }; /* One fixed line */ + +UNIT contty_unit[2] = { + { UDATA(&iu_svc_contty, UNIT_IDLE|UNIT_ATTABLE|TT_MODE_8B, 0), SERIAL_IN_WAIT }, + { UDATA(&iu_svc_contty_xmt, UNIT_IDLE|UNIT_DIS, 0), SERIAL_OUT_WAIT } +}; + +REG contty_reg[] = { + { HRDATADF(SRB, iu_contty.sr, 8, "Status Register", sr_bits) }, + { HRDATADF(CONF, iu_contty.conf, 8, "Config", conf_bits) }, + { BRDATAD(RXDATA, iu_contty.rxbuf, 16, 8, IU_BUF_SIZE, "RX Data") }, + { HRDATADF(ISR, iu_state.isr, 8, "Interrupt Status", isr_bits) }, + { HRDATAD(IMR, iu_state.imr, 8, "Interrupt Mask") }, + { HRDATADF(ACR, iu_state.acr, 8, "Auxiliary Control Register", acr_bits) }, + { DRDATAD(TIME, contty_unit[1].wait, 24, "output character delay"), PV_LEFT }, + { NULL } +}; + +MTAB contty_mod[] = { + { UNIT_ATT, UNIT_ATT, "summary", NULL, + NULL, &tmxr_show_summ, (void *)&contty_desc, "Display a summary of line state" }, + { MTAB_XTD|MTAB_VDV|MTAB_NMO, 1, "CONNECTIONS", NULL, + NULL, &tmxr_show_cstat, (void *)&contty_desc, "Display current connection" }, + { MTAB_XTD|MTAB_VDV|MTAB_NMO, 0, "STATISTICS", NULL, + NULL, &tmxr_show_cstat, (void *)&contty_desc, "Display CONTTY statistics" } +}; + +CONST char *brg_rates[IU_SPEED_REGS][IU_SPEEDS] = { + {"50", "110", "134.5", "200", + "300", "600", "1200", "1050", + "2400", "4800", "7200", "9600", + "38400", NULL, NULL, NULL}, + {"75", "110", "134.5", "150", + "300", "600", "1200", "2000", + "2400", "4800", "1800", "9600", + "19200", NULL, NULL, NULL} +}; + +CONST char *parity[3] = {"O", "E", "N"}; + +DEBTAB contty_deb_tab[] = { + {"EXEC", EXECUTE_MSG, "Execute"}, + {"XMT", TMXR_DBG_XMT, "Transmitted Data"}, + {"RCV", TMXR_DBG_RCV, "Received Data"}, + {"MDM", TMXR_DBG_MDM, "Modem Signals"}, + {"CON", TMXR_DBG_CON, "connection activities"}, + {"TRC", TMXR_DBG_TRC, "trace routine calls"}, + {"ASY", TMXR_DBG_ASY, "Asynchronous Activities"}, + {0} +}; + +DEVICE contty_dev = { + "CONTTY", contty_unit, contty_reg, contty_mod, + 2, 8, 32, 1, 8, 8, + &tmxr_ex, &tmxr_dep, &contty_reset, + NULL, &contty_attach, &contty_detach, + NULL, DEV_DISABLE|DEV_DEBUG|DEV_MUX, + 0, contty_deb_tab, NULL, NULL, + NULL, NULL, + (void *)&contty_desc, + NULL +}; + +/* IU Timer data structures */ + +MTAB iu_timer_mod[] = { + { MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, "MULT", "MULT={1|2|3|4}", + &iu_timer_set_mult, &iu_timer_show_mult, NULL, "Timer Multiplier" } +}; + +REG iu_timer_reg[] = { + { HRDATAD(CTR_SET, iu_timer_state.c_set, 16, "Counter Setting") }, + { NULL } +}; + +UNIT iu_timer_unit = { UDATA(&iu_svc_timer, UNIT_IDLE, 0) }; + +DEVICE iu_timer_dev = { + "IUTIMER", &iu_timer_unit, iu_timer_reg, iu_timer_mod, + 1, 8, 32, 1, 8, 8, + NULL, NULL, &iu_timer_reset, + NULL, NULL, NULL, NULL, + DEV_DEBUG, 0, sys_deb_tab +}; + +t_stat iu_timer_show_mult(FILE *st, UNIT *uptr, int val, const void *desc) +{ + fprintf(st, "mult=%d", (int) iu_timer_multiplier); + return SCPE_OK; +} + +t_stat iu_timer_set_mult(UNIT *uptr, int32 val, const char *cptr, void *desc) +{ + t_stat r; + t_value v; + v = get_uint(cptr, 10, 8, &r); + if (r != SCPE_OK) { + return r; + } + if (v < 1 || v > 4) { + return SCPE_ARG; + } + iu_timer_multiplier = (uint32) v; + return SCPE_OK; + +} + +uint8 brg_reg = 0; /* Selected baud-rate generator register */ +uint8 brg_clk = 11; /* Selected baud-rate generator clock */ +uint8 parity_sel = 1; /* Selected parity */ +uint8 bits_per_char = 7; + +t_stat contty_attach(UNIT *uptr, CONST char *cptr) +{ + t_stat r; + TMLN *lp; + char line_config[16]; + + /* Set initial line speed */ + brg_reg = 0; + brg_clk = BRG_DEFAULT; + parity_sel = IU_PARITY_EVEN; + bits_per_char = 7; + + sprintf(line_config, "%s-%d%s1", + brg_rates[brg_reg][brg_clk], + bits_per_char, + parity[parity_sel]); + + tmxr_set_config_line(&contty_ldsc[0], line_config); + + if ((sim_switches & SWMASK('M'))) { + tmxr_set_modem_control_passthru(&contty_desc); + } + + tmxr_set_line_output_unit(&contty_desc, 0, &contty_unit[1]); + + r = tmxr_attach(&contty_desc, uptr, cptr); + if (r != SCPE_OK) { + tmxr_clear_modem_control_passthru(&contty_desc); + return r; + } + + lp = &contty_ldsc[0]; + tmxr_set_get_modem_bits(lp, TMXR_MDM_DTR|TMXR_MDM_RTS, 0, NULL); + + return SCPE_OK; +} + +t_stat contty_detach(UNIT *uptr) +{ + t_stat r = tmxr_detach(&contty_desc, uptr); + tmxr_clear_modem_control_passthru(&contty_desc); + + return r; +} + +void increment_modep_a() +{ + iu_increment_a = FALSE; + iu_console.modep++; + + if (iu_console.modep > 1) { + iu_console.modep = 0; + } +} + +void increment_modep_b() +{ + iu_increment_b = FALSE; + iu_contty.modep++; + + if (iu_contty.modep > 1) { + iu_contty.modep = 0; + } +} + +t_stat tti_reset(DEVICE *dptr) +{ + memset(&iu_state, 0, sizeof(IU_STATE)); + memset(&iu_console, 0, sizeof(IU_PORT)); + + /* Input Port is active low */ + iu_state.inprt = ~IU_DCDA; + iu_state.ipcr = IU_DCDA_CH | (0xf & ~IU_DCDA); + + tmxr_set_console_units(&tti_unit, &tto_unit); + + /* Start the Console TTI polling loop */ + sim_activate_after(&tti_unit, tti_unit.wait); + + return SCPE_OK; +} + +t_stat contty_reset(DEVICE *dtpr) +{ + sim_set_uname(&contty_unit[0], "CONTTY-RCV"); + sim_set_uname(&contty_unit[1], "CONTTY-XMT"); + + tmxr_set_port_speed_control(&contty_desc); + + memset(&iu_contty, 0, sizeof(IU_PORT)); + + if (contty_unit[0].flags & UNIT_ATT) { + sim_activate_after(&contty_unit[0], contty_unit[0].wait); + } else { + sim_cancel(&contty_unit[0]); + } + + return SCPE_OK; +} + +static void iu_rx(IU_PORT *port, uint8 val) +{ + if (port->conf & RX_EN) { + if (!(port->sr & STS_FFL)) { + /* If not full, we're reading into the FIFO */ + port->rxbuf[port->w_p] = val; + port->w_p = (port->w_p + 1) % IU_BUF_SIZE; + if (port->w_p == port->r_p) { + port->sr |= STS_FFL; + } + } else { + /* FIFO is full, and now we're going to have to hold a + * character in the shift register until space is + * available */ + + /* If the register already had data, it's going to be + * overwritten, so we have to set the overflow flag */ + if (port->rxr_full) { + port->sr |= STS_OER; + } + + /* Save the character */ + port->rxr = val; + port->rxr_full = TRUE; + } + + port->sr |= STS_RXR; + iu_state.isr |= (port == &iu_console) ? ISTS_RXRA : ISTS_RXRB; + } + + UPDATE_IRQ; +} + +static uint8 iu_rx_getc(IU_PORT *port) +{ + uint8 val = 0; + + if (port->conf & RX_EN) { + val = port->rxbuf[port->r_p]; + port->r_p = (port->r_p + 1) % IU_BUF_SIZE; + /* No longer full */ + port->sr &= ~STS_FFL; + if (port->r_p == port->w_p) { + /* Empty FIFO, nothing left to read */ + port->sr &= ~STS_RXR; + iu_state.isr &= (port == &iu_console) ? ~ISTS_RXRA : ~ISTS_RXRB; + } + + if (port->rxr_full) { + /* Need to shift data from the Receive Shift Register into + the space that we just freed up */ + port->rxbuf[port->w_p] = port->rxr; + port->w_p = (port->w_p + 1) % IU_BUF_SIZE; + /* FIFO can logically never be full here, since we just + * freed up space above. */ + port->rxr_full = FALSE; + } + + if (!(port->mode[0] & 0x20)) { + /* Receiver is in "Char Error" mode, so reset SR error + bits on read */ + port->sr &= ~(STS_RXB|STS_FER|STS_PER); + } + } + + UPDATE_IRQ; + + return val; +} + +t_stat iu_timer_reset(DEVICE *dptr) +{ + memset(&iu_timer_state, 0, sizeof(IU_TIMER_STATE)); + + return SCPE_OK; +} + +/* Service routines */ + +t_stat iu_svc_tti(UNIT *uptr) +{ + int32 c; + + tmxr_clock_coschedule(uptr, tmxr_poll); + + if ((c = sim_poll_kbd()) < SCPE_KFLAG) { + return c; + } + + iu_rx(&iu_console, (uint8) c); + + return SCPE_OK; +} + + +t_stat iu_svc_tto(UNIT *uptr) +{ + t_stat result; + dma_channel *chan = &dma_state.channels[DMA_IUA_CHAN]; + + /* Check for data in the transmitter shift register that's ready + * to go out to the TX line */ + if (iu_console.tx_state & T_XMIT) { + if (LOOPBACK(&iu_console)) { + /* Handle loopback mode if set */ + sim_debug(EXECUTE_MSG, &tto_dev, "iu_svc_tto: CONSOLE is in loopback.\n"); + iu_console.tx_state &= ~T_XMIT; + + iu_rx(&iu_console, iu_console.txr); + + if (TX_ENABLED(iu_console) && !(iu_console.tx_state & T_HOLD)) { + iu_console.sr |= STS_TXE; + } + } else { + /* Direct mode, no loopback */ + result = sim_putchar_s(iu_console.txr); + if (result == SCPE_STALL) { + sim_debug(EXECUTE_MSG, &tto_dev, "iu_svc_tto: CONSOLE PUTC STALL\n"); + sim_activate_after(uptr, 1000); + return SCPE_OK; + } else { + iu_console.tx_state &= ~T_XMIT; + if (TX_ENABLED(iu_console) && !(iu_console.tx_state & T_HOLD)) { + iu_console.sr |= STS_TXE; + } + } + } + } + + /* Check for data in the holding register that's ready to go + * out to the transmitter shift register */ + if (iu_console.tx_state & T_HOLD) { + iu_console.tx_state &= ~T_HOLD; + iu_console.tx_state |= T_XMIT; + iu_console.txr = iu_console.thr; + /* If the transmitter is currently enabled, we need to update + * the TxRDY and TxEMT flags */ + if (TX_ENABLED(iu_console)) { + iu_console.sr &= ~STS_TXE; + iu_console.sr |= STS_TXR; + iu_state.isr |= ISTS_TXRA; + /* DRQ is always tied to TxRDY */ + iu_console.drq = TRUE; + } + + sim_activate_after_abs(uptr, uptr->wait); + } + + UPDATE_IRQ; + + /* If we're done transmitting and there's more DMA to do, + * do it. */ + if (!iu_console.tx_state && + chan->wcount_c >= 0 && + ((dma_state.mask >> DMA_IUA_CHAN) & 0x1) == 0) { + sim_debug(EXECUTE_MSG, &tto_dev, + "iu_svc_tto: Triggering next DMA\n"); + iu_dma_console(DMA_IUA_CHAN, IUBASE+IUA_DATA_REG); + } + + return SCPE_OK; +} + +t_stat iu_svc_contty(UNIT *uptr) +{ + int32 c; + + if ((uptr->flags & UNIT_ATT) == 0) { + return SCPE_OK; + } + + /* Check for connect of our single line */ + if (tmxr_poll_conn(&contty_desc) == 0) { + contty_ldsc[0].rcve = 1; + + iu_state.inprt &= ~IU_DCDB; + iu_state.ipcr &= ~IU_DCDB; + iu_state.ipcr |= IU_DCDB_CH; + + UPDATE_IRQ; + } + + tmxr_poll_tx(&contty_desc); + tmxr_poll_rx(&contty_desc); + + /* Check for disconnect */ + if (!contty_ldsc[0].conn && contty_ldsc[0].rcve) { + contty_ldsc[0].rcve = 0; + iu_state.inprt |= IU_DCDB; + iu_state.ipcr |= (IU_DCDB_CH|IU_DCDB); + + UPDATE_IRQ; + } + + /* Check for RX */ + if ((iu_contty.conf & RX_EN) && contty_ldsc[0].conn) { + c = tmxr_getc_ln(&contty_ldsc[0]); + if (c && !(c & SCPE_BREAK)) { + iu_rx(&iu_contty, (uint8) c); + } + } + + tmxr_clock_coschedule(uptr, tmxr_poll); + + return SCPE_OK; +} + +t_stat iu_svc_contty_xmt(UNIT *uptr) +{ + dma_channel *chan = &dma_state.channels[DMA_IUB_CHAN]; + TMLN *lp = &contty_ldsc[0]; + t_stat result; + + /* Check for data in the transmitter shift register that's ready + * to go out to the TX line */ + if (iu_contty.tx_state & T_XMIT) { + if (LOOPBACK(&iu_contty)) { + /* Handle loopback mode if set */ + sim_debug(EXECUTE_MSG, &contty_dev, "iu_svc_contty: CONTTY is in loopback.\n"); + iu_contty.tx_state &= ~T_XMIT; + + iu_rx(&iu_contty, iu_contty.txr); + + if (TX_ENABLED(iu_contty) && !(iu_contty.tx_state & T_HOLD)) { + iu_contty.sr |= STS_TXE; + } + } else { + /* Direct mode, no loopback */ + result = tmxr_putc_ln(lp, iu_contty.txr); + if (result == SCPE_STALL) { + sim_debug(EXECUTE_MSG, &contty_dev, "iu_svc_contty: CONTTY PUTC STALL: %d\n", result); + sim_activate_after(uptr, 1000); + return SCPE_OK; + } else { + tmxr_poll_tx(&contty_desc); + iu_contty.tx_state &= ~T_XMIT; + if (TX_ENABLED(iu_contty) && !(iu_contty.tx_state & T_HOLD)) { + iu_contty.sr |= STS_TXE; + } + } + } + } + + /* Check for data in the holding register that's ready to go + * out to the transmitter shift register */ + if (iu_contty.tx_state & T_HOLD) { + sim_debug(EXECUTE_MSG, &contty_dev, + "THRB->TXRB: 0x%02x (%c)\n", + iu_contty.thr, PCHAR(iu_contty.thr)); + iu_contty.tx_state &= ~T_HOLD; + iu_contty.tx_state |= T_XMIT; + iu_contty.txr = iu_contty.thr; + /* If the transmitter is currently enabled, we need to update + * the TxRDY and TxEMT flags */ + if (TX_ENABLED(iu_contty)) { + iu_contty.sr &= ~STS_TXE; + iu_contty.sr |= STS_TXR; + iu_state.isr |= ISTS_TXRB; + /* DRQ is always tied to TxRDY */ + iu_contty.drq = TRUE; + } + + sim_activate_after_abs(uptr, uptr->wait); + } + + UPDATE_IRQ; + + /* If we're done transmitting and there's more DMA to do, + * do it. */ + if (!iu_contty.tx_state && + chan->wcount_c >= 0 && + ((dma_state.mask >> DMA_IUB_CHAN) & 0x1) == 0) { + sim_debug(EXECUTE_MSG, &tto_dev, + "iu_svc_contty_xmt: Triggering next DMA\n"); + iu_dma_contty(DMA_IUB_CHAN, IUBASE+IUB_DATA_REG); + } + + return SCPE_OK; +} + +t_stat iu_svc_timer(UNIT *uptr) +{ + iu_state.isr |= ISTS_CRI; + + sim_debug(EXECUTE_MSG, &iu_timer_dev, + "[iu_svc_timer] IMR=%02x ISR=%02x => %02x\n", + iu_state.imr, iu_state.isr, (iu_state.imr & iu_state.isr)); + + UPDATE_IRQ; + return SCPE_OK; +} + +/* + * Reg | Name (Read) | Name (Write) + * -----+-------------------------+---------------------------- + * 0 | Mode Register 1/2 A | Mode Register 1/2 A + * 1 | Status Register A | Clock Select Register A + * 2 | BRG Test | Command Register A + * 3 | Rx Holding Register A | Tx Holding Register A + * 4 | Input Port Change Reg. | Aux. Control Register + * 5 | Interrupt Status Reg. | Interrupt Mask Register + * 6 | Counter/Timer Upper Val | C/T Upper Preset Val. + * 7 | Counter/Timer Lower Val | C/T Lower Preset Val. + * 8 | Mode Register B | Mode Register B + * 9 | Status Register B | Clock Select Register B + * 10 | 1X/16X Test | Command Register B + * 11 | Rx Holding Register B | Tx Holding Register B + * 12 | *Reserved* | *Reserved* + * 13 | Input Ports IP0 to IP6 | Output Port Conf. Reg. + * 14 | Start Counter Command | Set Output Port Bits Cmd. + * 15 | Stop Counter Command | Reset Output Port Bits Cmd. + */ + + +uint32 iu_read(uint32 pa, size_t size) +{ + uint8 reg, modep; + uint32 data = 0; + + reg = (uint8) (pa - IUBASE); + + switch (reg) { + case MR12A: + modep = iu_console.modep; + data = iu_console.mode[modep]; + iu_increment_a = TRUE; + break; + case SRA: + data = iu_console.sr; + break; + case RHRA: + data = iu_rx_getc(&iu_console); + break; + case IPCR: + data = iu_state.ipcr; + /* Reading the port resets the top 4 bits */ + iu_state.ipcr &= 0xf; + break; + case ISR: + data = iu_state.isr; + break; + case CTU: + data = (iu_timer_state.c_set >> 8) & 0xff; + break; + case CTL: + data = iu_timer_state.c_set & 0xff; + break; + case MR12B: + modep = iu_contty.modep; + data = iu_contty.mode[modep]; + iu_increment_b = TRUE; + break; + case SRB: + data = iu_contty.sr; + break; + case RHRB: + data = iu_rx_getc(&iu_contty); + break; + case INPRT: + data = iu_state.inprt; + break; + case START_CTR: + data = 0; + iu_state.isr &= ~ISTS_CRI; + sim_debug(EXECUTE_MSG, &iu_timer_dev, + "ACR=%02x : Activating IU Timer in %d ticks / %d microseconds\n", + iu_state.acr, iu_timer_state.c_set, (int32)(iu_timer_state.c_set * iu_timer_multiplier)); + sim_activate_after(&iu_timer_unit, (int32)(iu_timer_state.c_set * iu_timer_multiplier)); + break; + case STOP_CTR: + data = 0; + iu_state.isr &= ~ISTS_CRI; + UPDATE_IRQ; + sim_cancel(&iu_timer_unit); + break; + case 17: /* Clear DMA interrupt */ + data = 0; + CLR_DMA_INT; + break; + default: + break; + } + + return data; +} + +void iu_write(uint32 pa, uint32 val, size_t size) +{ + uint8 reg; + uint8 modep; + uint8 bval = (uint8) val; + char line_config[16]; + + reg = (uint8) (pa - IUBASE); + + switch (reg) { + case MR12A: + modep = iu_console.modep; + iu_console.mode[modep] = bval; + iu_increment_a = TRUE; + break; + case CSRA: + /* Nothing supported */ + break; + case CRA: /* Command A */ + iu_w_cmd(&iu_console, bval); + break; + case THRA: /* TX/RX Buf A */ + iu_tx(&iu_console, bval); + break; + case ACR: /* Auxiliary Control Register */ + iu_state.acr = bval; + brg_reg = (bval >> 7) & 1; + break; + case IMR: + iu_state.imr = bval; + UPDATE_IRQ; + break; + case CTUR: /* Counter/Timer Upper Preset Value */ + /* Clear out high byte */ + iu_timer_state.c_set &= 0x00ff; + /* Set high byte */ + iu_timer_state.c_set |= ((uint16) bval << 8); + break; + case CTLR: /* Counter/Timer Lower Preset Value */ + /* Clear out low byte */ + iu_timer_state.c_set &= 0xff00; + /* Set low byte */ + iu_timer_state.c_set |= bval; + break; + case MR12B: + modep = iu_contty.modep; + iu_contty.mode[modep] = bval; + sim_debug(EXECUTE_MSG, &tto_dev, "MR12B: Page %d Mode = %02x\n", modep, bval); + iu_increment_b = TRUE; + if (modep == 0) { + if ((bval >> 4) & 1) { + /* No parity */ + parity_sel = IU_PARITY_NONE; + } else { + /* Parity enabled */ + if (bval & 4) { + parity_sel = IU_PARITY_ODD; + } else { + parity_sel = IU_PARITY_EVEN; + } + } + + bits_per_char = (bval & 3) + 5; + } + break; + case CRB: + iu_w_cmd(&iu_contty, bval); + break; + case CSRB: + brg_clk = (bval >> 4) & 0xf; + + if (brg_rates[brg_reg][brg_clk] != NULL) { + sprintf(line_config, "%s-%d%s1", + brg_rates[brg_reg][brg_clk], + bits_per_char, + parity[parity_sel]); + + sim_debug(EXECUTE_MSG, &contty_dev, + "Setting CONTTY line to %s\n", + line_config); + + tmxr_set_config_line(&contty_ldsc[0], line_config); + } + + break; + case THRB: + iu_tx(&iu_contty, bval); + break; + case OPCR: + iu_state.opcr = bval; + break; + case SOPR: +#if defined (REV2) + /* Bit 2 of the IU output register is used as a soft power + * switch. When set, the machine will power down + * immediately. */ + if (bval & IU_KILLPWR) { + stop_reason = STOP_POWER; + } +#endif + break; + case ROPR: + break; + case 17: /* Clear DMA interrupt */ + sim_debug(EXECUTE_MSG, &tto_dev, + "[WRITE] Clear DMA interrupt in UART\n"); + CLR_DMA_INT; + break; + default: + break; + } +} + +/* + * Transmit a single character + */ +t_stat iu_tx(IU_PORT *port, uint8 val) +{ + int32 c; + uint8 tx_ists = (port == &iu_console) ? ISTS_TXRA : ISTS_TXRB; + UNIT *uptr = (port == &iu_console) ? &tto_unit : &contty_unit[1]; + + sim_debug(EXECUTE_MSG, &tto_dev, + "iu_tx PORT=%d CHAR=%02x (%c)\n", + PORTNO(port), val, PCHAR(val)); + + if (!(port->conf & TX_EN) || !(port->sr & STS_TXR)) { + sim_debug(EXECUTE_MSG, &tto_dev, + ">>> IGNORING TRANSMIT, NOT ENABLED OR NOT READY!!!\n"); + return SCPE_INCOMP; + } + + c = sim_tt_outcvt(val, TTUF_MODE_8B); + + if (c >= 0) { + port->tx_state |= T_HOLD; + port->sr &= ~(STS_TXR|STS_TXE); + port->drq = FALSE; + iu_state.isr &= ~(tx_ists); + port->thr = c; + sim_activate_after(uptr, uptr->wait); + } + + return SCPE_OK; +} + +static void iu_w_cmd(IU_PORT *port, uint8 cmd) +{ + uint8 tx_ists = (port == &iu_console) ? ISTS_TXRA : ISTS_TXRB; + uint8 dbk_ists = (port == &iu_console) ? ISTS_DBA : ISTS_DBB; + + /* Enable or disable transmitter */ + /* Disable always wins, if both are set */ + if (cmd & CMD_DTX) { + port->conf &= ~TX_EN; + port->sr &= ~(STS_TXR|STS_TXE); + port->drq = FALSE; + iu_state.isr &= ~tx_ists; + UPDATE_IRQ; + sim_debug(EXECUTE_MSG, &tto_dev, + "DISABLE TX, PORT %d\n", PORTNO(port)); + } else if (cmd & CMD_ETX) { + if (!(port->conf & TX_EN)) { + /* TXE and TXR are always set by an ENABLE if prior state + was DISABLED */ + port->sr |= (STS_TXR|STS_TXE); + port->drq = TRUE; + } + port->conf |= TX_EN; + iu_state.isr |= tx_ists; + UPDATE_IRQ; + sim_debug(EXECUTE_MSG, &tto_dev, + "ENABLE TX, PORT %d\n", PORTNO(port)); + } + + /* Enable or disable receiver. */ + /* Disable always wins, if both are set */ + if (cmd & CMD_DRX) { + port->conf &= ~RX_EN; + port->sr &= ~STS_RXR; + } else if (cmd & CMD_ERX) { + port->conf |= RX_EN; + } + + /* Command register bits 6-4 have special meaning */ + switch ((cmd >> CMD_MISC_SHIFT) & CMD_MISC_MASK) { + case CR_RST_MR: + /* Causes the Channel A MR pointer to point to MR1. */ + port->modep = 0; + break; + case CR_RST_RX: + sim_debug(EXECUTE_MSG, &tto_dev, + "PORT %d Command: RESET RX\n", PORTNO(port)); + /* Reset receiver. Resets the Channel's receiver as if a + hardware reset had been applied. The receiver is disabled + and the FIFO is flushed. */ + port->sr &= ~STS_RXR; + port->conf &= ~RX_EN; + port->w_p = 0; + port->r_p = 0; + break; + case CR_RST_TX: + sim_debug(EXECUTE_MSG, &tto_dev, + "PORT %d Command: RESET TX\n", PORTNO(port)); + /* Reset transmitter. Resets the Channel's transmitter as if a + hardware reset had been applied. */ + port->sr &= ~STS_TXR; + port->sr &= ~STS_TXE; + port->drq = FALSE; /* drq is tied to TXR */ + port->conf &= ~TX_EN; + break; + case CR_RST_ERR: + /* Reset error status. Clears the Channel's Received Break, + Parity Error, Framing Error, and Overrun Error bits in the + status register (SRn[7:4]). */ + sim_debug(EXECUTE_MSG, &tto_dev, + "PORT %d Command: RESET ERROR\n", PORTNO(port)); + port->sr &= ~(STS_RXB|STS_FER|STS_PER|STS_OER); + break; + case CR_RST_BRK: + /* Reset Channel's break change interrupt. Causes the Channel + A break detect change bit in the interrupt status register + (ISR[2] for Chan. A, ISR[6] for Chan. B) to be cleared to + zero. */ + sim_debug(EXECUTE_MSG, &tto_dev, + "PORT %d Command: RESET BREAK IRQ\n", PORTNO(port)); + iu_state.isr &= ~dbk_ists; + break; + case CR_START_BRK: + sim_debug(EXECUTE_MSG, &tto_dev, + "PORT %d Command: START BREAK. loopback=%d\n", + PORTNO(port), LOOPBACK(port)); + if (LOOPBACK(port)) { + /* Set "Received Break" and "Parity Error" bits in + SRA/SRB */ + port->sr |= (STS_RXB|STS_PER); + /* Set "Delta Break" bit A or B in ISR */ + iu_state.isr |= dbk_ists; + } + break; + case CR_STOP_BRK: + sim_debug(EXECUTE_MSG, &tto_dev, + "PORT %d Command: STOP BREAK. loopback=%d\n", + PORTNO(port), LOOPBACK(port)); + if (LOOPBACK(port)) { + /* Set "Delta Break" bit A or B in ISR */ + iu_state.isr |= dbk_ists; + } + break; + } + + UPDATE_IRQ; +} + +/* + * Initiate DMA transfer or continue one already in progress. + */ +void iu_dma_console(uint8 channel, uint32 service_address) +{ + uint8 data; + uint32 addr; + t_stat status = SCPE_OK; + dma_channel *chan = &dma_state.channels[channel]; + IU_PORT *port = &iu_console; + + /* If we're doing DMA and we're done, end it */ + if (iu_console.dma && chan->wcount_c < 0) { + sim_debug(EXECUTE_MSG, &tto_dev, + "iu_svc_tto: DMA Complete.\n"); + iu_console.dma = FALSE; + dma_state.mask |= (1 << DMA_IUA_CHAN); + dma_state.status |= (1 << DMA_IUA_CHAN); + SET_DMA_INT; + return; + } + + /* Mark that IUA is in DMA */ + port->dma = TRUE; + + switch (DMA_XFER(DMA_IUA_CHAN)) { + case DMA_XFER_READ: + addr = dma_address(channel, chan->ptr); + chan->addr_c = addr; + data = pread_b(addr, BUS_PER); + status = iu_tx(port, data); + if (status == SCPE_OK) { + chan->ptr++; + chan->wcount_c--; + } + break; + default: + sim_debug(EXECUTE_MSG, &tto_dev, + "iu_dma_console: Error, transfer type %d not supported\n", + DMA_XFER(DMA_IUA_CHAN)); + break; + } +} + +void iu_dma_contty(uint8 channel, uint32 service_address) +{ + uint8 data; + uint32 addr; + t_stat status = SCPE_OK; + dma_channel *chan = &dma_state.channels[channel]; + IU_PORT *port = &iu_contty; + + /* If we're doing DMA and we're done, end it */ + if (iu_contty.dma && chan->wcount_c < 0) { + sim_debug(EXECUTE_MSG, &contty_dev, + "iu_svc_contty_xmt: DMA Complete.\n"); + iu_contty.dma = FALSE; + dma_state.mask |= (1 << DMA_IUB_CHAN); + dma_state.status |= (1 << DMA_IUB_CHAN); + SET_DMA_INT; + return; + } + + /* Mark that IUB is in DMA */ + port->dma = TRUE; + + switch (DMA_XFER(DMA_IUB_CHAN)) { + case DMA_XFER_READ: + addr = dma_address(channel, chan->ptr); + chan->addr_c = addr; + data = pread_b(addr, BUS_PER); + status = iu_tx(port, data); + if (status == SCPE_OK) { + chan->ptr++; + chan->wcount_c--; + } + break; + default: + sim_debug(EXECUTE_MSG, &contty_dev, + "iu_dma_contty: Error, transfer type %d not supported\n", + DMA_XFER(DMA_IUB_CHAN)); + break; + } +} diff --git a/3B2/3b2_iu.h b/3B2/3b2_iu.h index 2a718ed0..9017a8bd 100644 --- a/3B2/3b2_iu.h +++ b/3B2/3b2_iu.h @@ -1,214 +1,234 @@ -/* 3b2_iu.h: SCN2681A Dual UART Header - - Copyright (c) 2017, Seth J. Morabito - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - - Except as contained in this notice, the name of the author shall - not be used in advertising or otherwise to promote the sale, use or - other dealings in this Software without prior written authorization - from the author. -*/ - -#ifndef __3B2_IU_H__ -#define __3B2_IU_H__ - -#include "3b2_defs.h" - -#define CMD_ERX 0x01 /* Enable receiver */ -#define CMD_DRX 0x02 /* Disable receiver */ -#define CMD_ETX 0x04 /* Enable transmitter */ -#define CMD_DTX 0x08 /* Disable transmitter */ -#define CMD_MISC_SHIFT 4 /* Command */ -#define CMD_MISC_MASK 0x7 - -#define IU_SPEED_REGS 2 /* Two speed select registers, */ -#define IU_SPEEDS 16 /* with 16 speeds each */ - -#define IU_PARITY_ODD 0 -#define IU_PARITY_EVEN 1 -#define IU_PARITY_NONE 2 - -#define STS_RXR 0x01 /* Receiver ready */ -#define STS_FFL 0x02 /* FIFO full */ -#define STS_TXR 0x04 /* Transmitter ready */ -#define STS_TXE 0x08 /* Transmitter empty */ -#define STS_OER 0x10 /* Overrun error */ -#define STS_PER 0x20 /* Parity error */ -#define STS_FER 0x40 /* Framing error */ -#define STS_RXB 0x80 /* Received break */ - -#define ISTS_TAI 0x01 /* Transmitter ready A */ -#define ISTS_RAI 0x02 /* Receiver ready A */ -#define ISTS_CBA 0x04 /* Change in break A */ -#define ISTS_CRI 0x08 /* Counter ready */ -#define ISTS_TBI 0x10 /* Transmitter ready B */ -#define ISTS_RBI 0x20 /* Receiver ready B */ -#define ISTS_CBB 0x40 /* Change in break B */ -#define ISTS_IPC 0x80 /* Interrupt port change */ - -#define MODE_V_CHM 6 /* Channel mode */ -#define MODE_M_CHM 0x3 - -/* Used by the DMAC */ -#define IUA_DATA_REG 3 -#define IUB_DATA_REG 11 - -/* Registers - Read */ -#define SRA 1 -#define RHRA 3 -#define IPCR 4 -#define ISR 5 -#define CTU 6 -#define CTL 7 -#define SRB 9 -#define RHRB 11 -#define INPRT 13 /* Input port data */ -#define START_CTR 14 -#define STOP_CTR 15 - -/* Registers - Write */ -#define CSRA 1 -#define CRA 2 -#define THRA 3 -#define ACR 4 -#define IMR 5 -#define CTUR 6 -#define CTLR 7 -#define CSRB 9 -#define CRB 10 -#define THRB 11 -#define OPCR 13 -#define SOPR 14 -#define ROPR 15 - -/* Registers - R/W */ -#define MR12A 0 -#define MR12B 8 - -/* Port configuration */ -#define TX_EN 1 -#define RX_EN 2 - -#define UM_CTR_EXT 0 -#define UM_CTR_TXCA 1 -#define UM_CTR_TXCB 2 -#define UM_CTR_DIV16 3 -#define UM_TMR_EXT 4 -#define UM_TMR_EXT16 5 -#define UM_TMR_XTL 6 -#define UM_TMR_XTL16 7 -#define UM_MASK 0x70 -#define UM_SHIFT 4 - -/* IMR bits */ -#define IMR_TXRA 0x01 -#define IMR_RXRA 0x02 -#define IMR_CTR 0x08 -#define IMR_TXRB 0x10 -#define IMR_RXRB 0x20 - -/* Power-off bit */ -#define IU_KILLPWR 0x04 - -#define PORT_A 0 -#define PORT_B 1 - -#define IU_MODE(x) ((x & UM_MASK) >> UM_SHIFT) - -#define IUBASE 0x49000 -#define IUSIZE 0x100 - -#define IU_BUF_SIZE 3 - -#define IU_DCDA 0x01 -#define IU_DCDB 0x02 -#define IU_DTRA 0x01 -#define IU_DTRB 0x02 - -#define DMA_NONE 0 -#define DMA_VERIFY 1 -#define DMA_WRITE 2 -#define DMA_READ 4 - -/* Default baud rate generator (9600 baud) */ -#define BRG_DEFAULT 11 - -#define IU_TIMER_RATE 2.114 /* microseconds per step */ - - -typedef struct iu_port { - uint8 stat; /* Port Status */ - uint8 cmd; /* Command */ - uint8 mode[2]; /* Two mode buffers */ - uint8 modep; /* Point to mode[0] or mode[1] */ - uint8 conf; /* Configuration bits */ - uint8 txbuf; /* Transmit Holding Register */ - uint8 rxbuf[IU_BUF_SIZE]; /* Receive Holding Register (3 bytes) */ - uint8 w_p; /* Buffer Write Pointer */ - uint8 r_p; /* Buffer Read Pointer */ - uint8 dma; /* Currently active DMA mode */ - t_bool drq; /* DMA request enabled */ -} IU_PORT; - -typedef struct iu_state { - uint8 istat; /* Interrupt Status */ - uint8 imr; /* Interrupt Mask Register */ - uint8 acr; - uint8 opcr; /* Output Port Configuration */ - uint8 inprt; /* Input Port Data */ - uint8 ipcr; /* Input Port Change Register */ -} IU_STATE; - -typedef struct iu_timer_state { - uint16 c_set; - t_bool c_en; -} IU_TIMER_STATE; - -/* Function prototypes */ -t_stat contty_attach(UNIT *uptr, CONST char *cptr); -t_stat contty_detach(UNIT *uptr); -t_stat tti_reset(DEVICE *dptr); -t_stat contty_reset(DEVICE *dptr); -t_stat iu_timer_reset(DEVICE *dptr); -t_stat iu_svc_tti(UNIT *uptr); -t_stat iu_svc_tto(UNIT *uptr); -t_stat iu_svc_contty_rcv(UNIT *uptr); -t_stat iu_svc_contty_xmt(UNIT *uptr); -t_stat iu_svc_timer(UNIT *uptr); -t_stat iu_tx(uint8 portno, uint8 val); -uint32 iu_read(uint32 pa, size_t size); -void iu_write(uint32 pa, uint32 val, size_t size); -void iua_drq_handled(); -void iub_drq_handled(); -void iu_txrdy_a_irq(); -void iu_txrdy_b_irq(); -void iu_dma_console(uint8 channel, uint32 service_address); -void iu_dma_contty(uint8 channel, uint32 service_address); -void increment_modep_a(); -void increment_modep_b(); - -extern IU_PORT iu_console; -extern IU_PORT iu_contty; -extern t_bool iu_increment_a; -extern t_bool iu_increment_b; - -#endif +/* 3b2_iu.h: SCN2681A Dual UART + + Copyright (c) 2017-2022, Seth J. Morabito + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + Except as contained in this notice, the name of the author shall + not be used in advertising or otherwise to promote the sale, use or + other dealings in this Software without prior written authorization + from the author. +*/ + +#ifndef __3B2_IU_H__ +#define __3B2_IU_H__ + +#include "3b2_defs.h" + +#define CMD_ERX 0x01 /* Enable receiver */ +#define CMD_DRX 0x02 /* Disable receiver */ +#define CMD_ETX 0x04 /* Enable transmitter */ +#define CMD_DTX 0x08 /* Disable transmitter */ +#define CMD_MISC_SHIFT 4 /* Command */ +#define CMD_MISC_MASK 0x7 + +#define IU_SPEED_REGS 2 /* Two speed select registers, */ +#define IU_SPEEDS 16 /* with 16 speeds each */ + +#define IU_PARITY_ODD 0 +#define IU_PARITY_EVEN 1 +#define IU_PARITY_NONE 2 + +#define STS_RXR 0x01 /* Receiver ready */ +#define STS_FFL 0x02 /* FIFO full */ +#define STS_TXR 0x04 /* Transmitter ready */ +#define STS_TXE 0x08 /* Transmitter empty */ +#define STS_OER 0x10 /* Overrun error */ +#define STS_PER 0x20 /* Parity error */ +#define STS_FER 0x40 /* Framing error */ +#define STS_RXB 0x80 /* Received break */ + +#define ISTS_TXRA 0x01 /* Transmitter ready A */ +#define ISTS_RXRA 0x02 /* Receiver ready A */ +#define ISTS_DBA 0x04 /* Delta Break A */ +#define ISTS_CRI 0x08 /* Counter ready */ +#define ISTS_TXRB 0x10 /* Transmitter ready B */ +#define ISTS_RXRB 0x20 /* Receiver ready B */ +#define ISTS_DBB 0x40 /* Delta Break B */ +#define ISTS_IPC 0x80 /* Interrupt port change */ + +#define MODE_V_CHM 6 /* Channel mode */ +#define MODE_M_CHM 0x3 + +/* Transmitter State bits */ +#define T_HOLD 1 +#define T_XMIT 2 + +/* Used by the DMAC */ +#define IUA_DATA_REG 3 +#define IUB_DATA_REG 11 + +/* Registers - Read */ +#define SRA 1 +#define RHRA 3 +#define IPCR 4 +#define ISR 5 +#define CTU 6 +#define CTL 7 +#define SRB 9 +#define RHRB 11 +#define INPRT 13 +#define START_CTR 14 +#define STOP_CTR 15 + +/* Registers - Write */ +#define CSRA 1 +#define CRA 2 +#define THRA 3 +#define ACR 4 +#define IMR 5 +#define CTUR 6 +#define CTLR 7 +#define CSRB 9 +#define CRB 10 +#define THRB 11 +#define OPCR 13 +#define SOPR 14 +#define ROPR 15 + +/* Registers - R/W */ +#define MR12A 0 +#define MR12B 8 + +/* Port configuration */ +#define TX_EN 1 +#define RX_EN 2 + +/* Control Register commands */ +#define CR_RST_MR 1 +#define CR_RST_RX 2 +#define CR_RST_TX 3 +#define CR_RST_ERR 4 +#define CR_RST_BRK 5 +#define CR_START_BRK 6 +#define CR_STOP_BRK 7 + +/* IMR bits */ +#define IMR_TXRA 0x01 +#define IMR_RXRA 0x02 +#define IMR_CTR 0x08 +#define IMR_TXRB 0x10 +#define IMR_RXRB 0x20 + +/* Power-off bit */ +#define IU_KILLPWR 0x04 + +#define PORT_A 0 +#define PORT_B 1 + +#define IU_MODE(x) ((x & UM_MASK) >> UM_SHIFT) + +#define IUBASE 0x49000 +#define IUSIZE 0x100 + +#define IU_BUF_SIZE 3 + +/* Data Carrier Detect inputs and input change bits */ +#if defined(REV3) +#define IU_DCDB_CH 0x80 +#define IU_DCDA_CH 0x40 +#define IU_DCDB 0x08 +#define IU_DCDA 0x04 +#else +#define IU_DCDB_CH 0x20 +#define IU_DCDA_CH 0x10 +#define IU_DCDB 0x02 +#define IU_DCDA 0x01 +#endif + +/* Default baud rate generator (9600 baud) */ +#define BRG_DEFAULT 11 + +/* The 2681 DUART includes a 16-bit timer/counter that can be used to + * trigger an interrupt after a certain amount of time has passed. + * + * The 2681 uses a crystal with a frequency of 3.686400 MHz, and the + * timer/counter uses this frequency divided by 16, giving a final + * timer/counter frequency of 230,400 Hz. There are therefore 4.34 + * microseconds of wall time per tick of the timer. + * + * The multiplier defined below is a default that can be adjusted to + * make IU timing faster, but less accurate, if desired */ + +#define IU_TIMER_MULTIPLIER 4 + +typedef struct iu_port { + uint8 cmd; /* Command */ + uint8 mode[2]; /* Two mode buffers */ + uint8 modep; /* Point to mode[0] or mode[1] */ + uint8 conf; /* Configuration bits */ + uint8 sr; /* Status Register */ + uint8 thr; /* Transmit Holding Register */ + uint8 txr; /* Transmit Shift Register */ + uint8 rxr; /* Receive Shift Register */ + uint8 rxbuf[IU_BUF_SIZE]; /* Receive Holding Register (3 bytes) */ + uint8 w_p; /* Receive Buffer Write Pointer */ + uint8 r_p; /* Receive Buffer Read Pointer */ + uint8 tx_state; /* Transmitting state flags (HOLD, XMIT) */ + t_bool dma; /* DMA currently active */ + t_bool drq; /* DMA request enabled */ + t_bool rxr_full; /* Receive Shift Register is full */ +} IU_PORT; + +typedef struct iu_state { + uint8 isr; /* Interrupt Status Register */ + uint8 imr; /* Interrupt Mask Register */ + uint8 acr; /* Aux. Control Register */ + uint8 opcr; /* Output Port Configuration */ + uint8 inprt; /* Input Port Data */ + uint8 ipcr; /* Input Port Change Register */ +} IU_STATE; + +typedef struct iu_timer_state { + uint16 c_set; + t_bool c_en; +} IU_TIMER_STATE; + +/* Function prototypes */ +t_stat contty_attach(UNIT *uptr, CONST char *cptr); +t_stat contty_detach(UNIT *uptr); +t_stat tti_reset(DEVICE *dptr); +t_stat contty_reset(DEVICE *dptr); +t_stat iu_timer_reset(DEVICE *dptr); +t_stat iu_timer_set_mult(UNIT *uptr, int32 val, CONST char *cptr, void *desc); +t_stat iu_timer_show_mult(FILE *st, UNIT *uptr, int val, CONST void *desc); +t_stat iu_svc_tti(UNIT *uptr); +t_stat iu_svc_tto(UNIT *uptr); +t_stat iu_svc_contty(UNIT *uptr); +t_stat iu_svc_contty_xmt(UNIT *uptr); +t_stat iu_svc_timer(UNIT *uptr); +uint32 iu_read(uint32 pa, size_t size); +void iu_write(uint32 pa, uint32 val, size_t size); +void iua_drq_handled(); +void iub_drq_handled(); +void iu_txrdy_a_irq(); +void iu_txrdy_b_irq(); +void iu_dma_console(uint8 channel, uint32 service_address); +void iu_dma_contty(uint8 channel, uint32 service_address); +void increment_modep_a(); +void increment_modep_b(); + +extern IU_PORT iu_console; +extern IU_PORT iu_contty; +extern t_bool iu_increment_a; +extern t_bool iu_increment_b; + +#endif diff --git a/3B2/3b2_rev2_mau.c b/3B2/3b2_mau.c similarity index 91% rename from 3B2/3b2_rev2_mau.c rename to 3B2/3b2_mau.c index 2b097794..7c10bc74 100644 --- a/3B2/3b2_rev2_mau.c +++ b/3B2/3b2_mau.c @@ -1,3597 +1,3595 @@ -/* 3b2_rev2_mau.c: AT&T 3B2 Rev 2 (Model 400) Math Acceleration - Unit (WE32106 MAU) Implementation - - Copyright (c) 2019, Seth J. Morabito - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - - Except as contained in this notice, the name of the author shall - not be used in advertising or otherwise to promote the sale, use or - other dealings in this Software without prior written authorization - from the author. - - --------------------------------------------------------------------- - - This file is part of a simulation of the WE32106 Math Acceleration - Unit. The WE32106 MAU is an IEEE-754 compabitle floating point - hardware math accelerator that was available as an optional - component on the AT&T 3B2/310 and 3B2/400, and a standard component - on the 3B2/500, 3B2/600, and 3B2/1000. - - Portions of this code are derived from the SoftFloat 2c library by - John R. Hauser. Functions derived from SoftFloat 2c are clearly - marked in the comments. - - Legal Notice - ============ - - SoftFloat was written by John R. Hauser. Release 2c of SoftFloat - was made possible in part by the International Computer Science - Institute, located at Suite 600, 1947 Center Street, Berkeley, - California 94704. Funding was partially provided by the National - Science Foundation under grant MIP-9311980. The original version - of this code was written as part of a project to build a - fixed-point vector processor in collaboration with the University - of California at Berkeley, overseen by Profs. Nelson Morgan and - John Wawrzynek. - - THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable - effort has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS - THAT WILL AT TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS - SOFTWARE IS RESTRICTED TO PERSONS AND ORGANIZATIONS WHO CAN AND - WILL TOLERATE ALL LOSSES, COSTS, OR OTHER PROBLEMS THEY INCUR DUE - TO THE SOFTWARE WITHOUT RECOMPENSE FROM JOHN HAUSER OR THE - INTERNATIONAL COMPUTER SCIENCE INSTITUTE, AND WHO FURTHERMORE - EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER - SCIENCE INSTITUTE (possibly via similar legal notice) AGAINST ALL - LOSSES, COSTS, OR OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND - CLIENTS DUE TO THE SOFTWARE, OR INCURRED BY ANYONE DUE TO A - DERIVATIVE WORK THEY CREATE USING ANY PART OF THE SOFTWARE. - - The following are expressly permitted, even for commercial - purposes: - - (1) distribution of SoftFloat in whole or in part, as long as this - and other legal notices remain and are prominent, and provided also - that, for a partial distribution, prominent notice is given that it - is a subset of the original; and - - (2) inclusion or use of SoftFloat in whole or in part in a - derivative work, provided that the use restrictions above are met - and the minimal documentation requirements stated in the source - code are satisfied. - --------------------------------------------------------------------- -*/ - -#include "3b2_rev2_mau.h" - -#include - -#include "3b2_cpu.h" -#include "3b2_mem.h" -#include "3b2_mmu.h" - -#define MAU_ID 0 /* Coprocessor ID of MAU */ - -#define TININESS_BEFORE_ROUNDING TRUE - -/* Static function declarations */ -static SIM_INLINE void mau_case_div_zero(XFP *op1, XFP *op2, XFP *result); - -static SIM_INLINE void mau_exc(uint32 flag, uint32 mask); -static SIM_INLINE void abort_on_fault(); -static SIM_INLINE void mau_decode(uint32 cmd, uint32 src, uint32 dst); -static SIM_INLINE t_bool le_128(t_uint64 a0, t_uint64 a1, t_uint64 b0, t_uint64 b1); -static SIM_INLINE t_bool eq_128(t_uint64 a0, t_uint64 a1, t_uint64 b0, t_uint64 b1); -static SIM_INLINE t_bool lt_128(t_uint64 a0, t_uint64 a1, t_uint64 b0, t_uint64 b1); -static uint8 leading_zeros(uint32 val); -static uint8 leading_zeros_64(t_int64 val); -static void shift_right_32_jamming(uint32 val, int16 count, uint32 *result); -static void shift_right_64_jamming(t_uint64 val, int16 count, t_uint64 *result); -static void shift_right_extra_64_jamming(t_uint64 val_a, t_uint64 val_b, int16 count, - t_uint64 *r_a, t_uint64 *r_b); -static void shift_right_128_jamming(t_uint64 val_a, t_uint64 val_b, int16 count, - t_uint64 *r_a, t_uint64 *r_b); -static void short_shift_left_128(t_uint64 val_a, t_uint64 val_b, int16 count, - t_uint64 *r_a, t_uint64 *r_b); -static void shift_right_128(t_uint64 val_a, t_uint64 val_b, int16 count, - t_uint64 *r_a, t_uint64 *r_b); -static void add_128(t_uint64 a0, t_uint64 a1, - t_uint64 b0, t_uint64 b1, - t_uint64 *r_low, t_uint64 *r_high); -static void sub_128(t_uint64 a0, t_uint64 a1, - t_uint64 b0, t_uint64 b1, - t_uint64 *r_low, t_uint64 *r_high); -static void mul_64_to_128(t_uint64 a, t_uint64 b, t_uint64 *r_low, t_uint64 *r_high); -static void mul_64_by_shifted_32_to_128(t_uint64 a, uint32 b, t_mau_128 *result); -static t_uint64 estimate_div_128_to_64(t_uint64 a0, t_uint64 a1, t_uint64 b); -static uint32 estimate_sqrt_32(int16 a_exp, uint32 a); - -static uint32 round_pack_int(t_bool sign, t_uint64 frac, RM rounding_mode); -static t_int64 round_pack_int64(t_bool sign, - t_uint64 abs_0, t_uint64 abs_1, - RM rounding_mode); - -static SFP round_pack_sfp(t_bool sign, int16 exp, - uint32 frac, RM rounding_mode); -static DFP round_pack_dfp(t_bool sign, int16 exp, t_uint64 frac, - t_bool xfp_sticky, RM rounding_mode); -static void round_pack_xfp(t_bool sign, int32 exp, - t_uint64 frac_a, t_uint64 frac_b, - RM rounding_mode, XFP *result); -static void propagate_xfp_nan(XFP *a, XFP *b, XFP *result); -static void propagate_xfp_nan_128(XFP* a, XFP* b, t_mau_128* result); -static void normalize_round_pack_xfp(t_bool sign, int32 exp, - t_uint64 frac_0, t_uint64 frac_1, - RM rounding_mode, XFP *result); -static void normalize_sfp_subnormal(uint32 in_frac, int16 *out_exp, uint32 *out_frac); -static void normalize_dfp_subnormal(t_uint64 in_frac, int16 *out_exp, t_uint64 *out_frac); -static void normalize_xfp_subnormal(t_uint64 in_frac, int32 *out_exp, t_uint64 *out_frac); - -static T_NAN sfp_to_common_nan(SFP val); -static T_NAN dfp_to_common_nan(DFP val); -static T_NAN xfp_to_common_nan(XFP *val); -static SFP common_nan_to_sfp(T_NAN nan); -static DFP common_nan_to_dfp(T_NAN nan); -static void common_nan_to_xfp(T_NAN nan, XFP *result); - -static void sfp_to_xfp(SFP val, XFP *result); -static void dfp_to_xfp(DFP val, XFP *result); -static SFP xfp_to_sfp(XFP *val, RM rounding_mode); -static DFP xfp_to_dfp(XFP *val, RM rounding_mode); - -static uint32 xfp_eq(XFP *a, XFP *b); -static uint32 xfp_lt(XFP *a, XFP *b); - -static void xfp_cmp(XFP *a, XFP *b); -static void xfp_cmpe(XFP *a, XFP *b); -static void xfp_cmps(XFP *a, XFP *b); -static void xfp_cmpes(XFP *a, XFP *b); -static void xfp_add(XFP *a, XFP *b, XFP *result, RM rounding_mode); -static void xfp_sub(XFP *a, XFP *b, XFP *result, RM rounding_mode); -static void xfp_mul(XFP *a, XFP *b, XFP *result, RM rounding_mode); -static void xfp_div(XFP *a, XFP *b, XFP *result, RM rounding_mode); -static void xfp_sqrt(XFP *a, XFP *result, RM rounding_mode); -static void xfp_remainder(XFP *a, XFP *b, XFP *result, RM rounding_mode); - -static void load_src_op(uint8 op, XFP *xfp); -static void load_op1_decimal(DEC *d); -static void store_op3_int(uint32 val); -static void store_op3_decimal(DEC *d); -static void store_op3(XFP *xfp); - -static void mau_rdasr(); -static void mau_wrasr(); -static void mau_move(); -static void mau_cmp(); -static void mau_cmps(); -static void mau_cmpe(); -static void mau_cmpes(); -static void mau_ldr(); -static void mau_erof(); -static void mau_rtoi(); -static void mau_ftoi(); -static void mau_dtof(); -static void mau_ftod(); -static void mau_add(); -static void mau_sub(); -static void mau_mul(); -static void mau_div(); -static void mau_neg(); -static void mau_abs(); -static void mau_sqrt(); -static void mau_itof(); -static void mau_remainder(); - -static void mau_execute(); - -UNIT mau_unit = { UDATA(NULL, 0, 0) }; - -MAU_STATE mau_state; - -BITFIELD asr_bits[] = { - BITNCF(5), - BIT(PR), - BIT(QS), - BIT(US), - BIT(OS), - BIT(IS), - BIT(PM), - BIT(QM), - BIT(UM), - BIT(OM), - BIT(IM), - BITNCF(1), - BIT(UO), - BIT(CSC), - BIT(PS), - BIT(IO), - BIT(Z), - BIT(N), - BITFFMT(RC,2,%d), - BIT(NTNC), - BIT(ECP), - BITNCF(5), - BIT(RA), - ENDBITS -}; - -REG mau_reg[] = { - { HRDATAD (CMD, mau_state.cmd, 32, "Command Word") }, - { HRDATADF (ASR, mau_state.asr, 32, "ASR", asr_bits) }, - { HRDATAD (OPCODE, mau_state.opcode, 8, "Opcode") }, - { HRDATAD (OP1, mau_state.op1, 8, "Operand 1") }, - { HRDATAD (OP2, mau_state.op2, 8, "Operand 2") }, - { HRDATAD (OP3, mau_state.op3, 8, "Operand 3") }, - { NULL } -}; - -MTAB mau_mod[] = { - { UNIT_EXBRK, UNIT_EXBRK, "Break on exceptions", "EXBRK", - NULL, NULL, NULL, "Enables break on floating point exceptions" }, - { UNIT_EXBRK, 0, "No break on exceptions", "NOEXBRK", - NULL, NULL, NULL, "Disables break on floating point exceptions" }, - { 0 } -}; - -static DEBTAB mau_debug[] = { - { "DECODE", DECODE_DBG, "Decode" }, - { "TRACE", TRACE_DBG, "Call Trace" }, - { NULL } -}; - -DEVICE mau_dev = { - "MAU", /* name */ - &mau_unit, /* units */ - mau_reg, /* registers */ - mau_mod, /* modifiers */ - 1, /* #units */ - 16, /* address radix */ - 32, /* address width */ - 1, /* address incr. */ - 16, /* data radix */ - 8, /* data width */ - NULL, /* examine routine */ - NULL, /* deposit routine */ - &mau_reset, /* reset routine */ - NULL, /* boot routine */ - NULL, /* attach routine */ - NULL, /* detach routine */ - NULL, /* context */ -#ifdef REV3 - DEV_DEBUG, /* Rev 3 flags: Always required */ -#else - DEV_DISABLE|DEV_DIS|DEV_DEBUG, /* Rev 2 flags */ -#endif - 0, /* debug control flags */ - mau_debug, /* debug flag names */ - NULL, /* memory size change */ - NULL, /* logical name */ - NULL, /* help routine */ - NULL, /* attach help routine */ - NULL, /* help context */ - &mau_description /* device description */ -}; - -XFP INF = { - 0x7fff, - 0x0000000000000000ull, - 0 -}; - -XFP TRAPPING_NAN = { - 0x7fff, - 0x7fffffffffffffffull, - 0 -}; - -/* Generated Non-Trapping NaN - * p. 2-8 "When the MAU generates a nontrapping NaN, J+fraction - * contains all 1s. The MAU never generates a trapping NaN." - */ -XFP GEN_NONTRAPPING_NAN = { - 0x7fff, - 0xffffffffffffffffull, - 0 -}; - -CONST char *mau_op_names[32] = { - "0x00", "0x01", "ADD", "SUB", "DIV", "REM", "MUL", "MOVE", /* 00-07 */ - "RDASR", "WRASR", "CMP", "CMPE", "ABS", "SQRT", "RTOI", "FTOI", /* 08-0F */ - "ITOF", "DTOF", "FTOD", "NOP", "EROF", "0x15", "0x16", "NEG", /* 10-17 */ - "LDR", "0x19", "CMPS", "CMPES", "0x1C", "0x1D", "0x1E", "0x1F" /* 18-1F */ -}; - -CONST char *src_op_names[8] = { - "F0", "F1", "F2", "F3", - "MEM S", "MEM D", "MEM X", "N/A" -}; - -CONST char *dst_op_names[16] = { - "F0 S", "F1 S", "F2 S", "F3 S", - "F0 D", "F1 D", "F2 D", "F3 D", - "F0 X", "F1 X", "F2 X", "F3 X", - "MEM S", "MEM D", "MEM X", "N/A" -}; - -/* - * Special Cases - * ------------- - * - * The handling of combinations of special input values is specified - * in the "WE32106 Math Acceleration Unit Information Manual" - * pp. 5-3--5-5. - * - * Each of these "special case" routines can be called by math - * functions based on a combination of the input values. - * - * (At the moment, only divide-by-zero is explicitly called out here - * as a special case) - */ - -static SIM_INLINE void mau_case_div_zero(XFP *op1, XFP *op2, XFP *result) -{ - mau_state.asr |= MAU_ASR_QS; - - if (mau_state.asr & MAU_ASR_QM) { - mau_state.asr |= MAU_ASR_ECP; - PACK_XFP(0, 0x7fff, 0x8000000000000000ull, result); - } else { - if (XFP_SIGN(op1) ^ XFP_SIGN(op2)) { - PACK_XFP(1, INF.sign_exp, INF.frac, result); - } else { - PACK_XFP(0, INF.sign_exp, INF.frac, result); - } - } -} - -static SIM_INLINE void mau_exc(uint32 flag, uint32 mask) -{ - sim_debug(TRACE_DBG, &mau_dev, - "[%08x] [mau_exc] asr=%08x flag=%08x mask=%08x\n", - R[NUM_PC], mau_state.asr, flag, mask); - - mau_state.asr |= flag; - - /* - * page 2-14: NTNC bit is checked if an Invalid Operation - * exception occurs while the Invalid Operation Mask bit is - * clear. If NTNC is set to 1, an exception occurs and bit 9 - * (IS) is set. If NTNC is set to 0, no exception occurs, - * and a nontraping NaN is generated. - */ - if (flag == MAU_ASR_IS && (mau_state.asr & MAU_ASR_IM) == 0) { - if (mau_state.asr & MAU_ASR_NTNC) { - mau_state.asr |= MAU_ASR_ECP; - } else { - mau_state.ntnan = TRUE; - } - return; - } - - if (mau_state.asr & mask) { - mau_state.asr |= MAU_ASR_ECP; - } -} - -/* - * Returns true if an exceptional condition is present. - */ -static SIM_INLINE t_bool mau_exception_present() -{ - - return mau_state.asr & MAU_ASR_ECP && - (((mau_state.asr & MAU_ASR_IS) && ((mau_state.asr & MAU_ASR_IM) || - (mau_state.asr & MAU_ASR_NTNC))) || - ((mau_state.asr & MAU_ASR_US) && (mau_state.asr & MAU_ASR_UM)) || - ((mau_state.asr & MAU_ASR_OS) && (mau_state.asr & MAU_ASR_OM)) || - ((mau_state.asr & MAU_ASR_PS) && (mau_state.asr & MAU_ASR_PM)) || - ((mau_state.asr & MAU_ASR_QS) && (mau_state.asr & MAU_ASR_QM))); -} - -static SIM_INLINE void abort_on_fault() -{ - switch(mau_state.opcode) { - case M_NOP: - case M_RDASR: - case M_WRASR: - case M_EROF: - case M_LDR: - return; - default: - /* - * Integer overflow is non-maskable in the MAU, but generates an Integer - * Overflow exception to be handled by the WE32100 CPU (if not masked - * in the CPU's PSW). - */ - if ((mau_state.asr & MAU_ASR_IO) && (R[NUM_PSW] & PSW_OE_MASK)) { - if (mau_unit.flags & UNIT_EXBRK) { - stop_reason = STOP_EX; - } - sim_debug(TRACE_DBG, &mau_dev, - "[%08x] [abort_on_fault] Aborting on un-maskable overflow fault. ASR=%08x\n", - R[NUM_PC], mau_state.asr); - cpu_abort(NORMAL_EXCEPTION, INTEGER_OVERFLOW); - } - - /* Otherwise, check for other exceptions. */ - if (mau_exception_present()) { - if (mau_unit.flags & UNIT_EXBRK) { - stop_reason = STOP_EX; - } - sim_debug(TRACE_DBG, &mau_dev, - "[%08x] [abort_on_fault] Aborting on ECP fault. ASR=%08x\n", - R[NUM_PC], mau_state.asr); - cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT); - } - - break; - } -} - -/* - * Clears N and Z flags in the ASR if appropriate. - */ -static void clear_asr() -{ - mau_state.ntnan = FALSE; - - switch(mau_state.opcode) { - case M_NOP: - case M_RDASR: - case M_WRASR: - case M_EROF: - return; - default: - mau_state.asr &= ~(MAU_ASR_Z|MAU_ASR_N|MAU_ASR_ECP); - break; - } -} - -/* - * Returns true if the 'nz' flags should be set. - * - * Note: There is an undocumented feature of the WE32106 expressed - * here. If an exception has occured, the Z and N flags are not to be - * set! - */ -static t_bool set_nz() -{ - - switch(mau_state.opcode) { - case M_NOP: - case M_RDASR: - case M_WRASR: - case M_EROF: - return FALSE; - default: - return (mau_state.asr & MAU_ASR_ECP) == 0; - } -} - -t_stat mau_reset(DEVICE *dptr) -{ - memset(&mau_state, 0, sizeof(MAU_STATE)); - return SCPE_OK; -} - -/************************************************************************* - * Utility Functions - ************************************************************************/ - -/* - * Compare two 128-bit values a and b. Rturns true if a <= b - * - * Derived from the SoftFloat 2c package (see copyright notice above) - */ -static SIM_INLINE t_bool le_128(t_uint64 a0, t_uint64 a1, t_uint64 b0, t_uint64 b1) -{ - return (a0 < b0) || ((a0 == b0) && (a1 <= b1)); -} - -/* - * Compare two 128-bit values a and b. Returns true if a = b - * - * Derived from the SoftFloat 2c package (see copyright notice above) - */ -static SIM_INLINE t_bool eq_128(t_uint64 a0, t_uint64 a1, t_uint64 b0, t_uint64 b1) -{ - return (a0 == b0) && (a1 == b1); -} - -/* - * Compare two 128-bit values a and b. Returns true if a < b - * - * Derived from the SoftFloat 2c package (see copyright notice above) - */ -static SIM_INLINE t_bool lt_128(t_uint64 a0, t_uint64 a1, t_uint64 b0, t_uint64 b1) -{ - return (a0 < b0) || ((a0 == b0) && (a1 < b1)); -} - -/* - * Return the number of leading binary zeros in an unsigned 32-bit - * value. - * - * Algorithm couresty of "Hacker's Delight" by Henry S. Warren. - */ -static uint8 leading_zeros(uint32 val) -{ - unsigned n = 0; - - if (val <= 0x0000ffff) { - n += 16; - val <<= 16; - } - if (val <= 0x00ffffff) { - n += 8; - val <<= 8; - } - if (val <= 0x0fffffff) { - n += 4; - val <<= 4; - } - if (val <= 0x3fffffff) { - n += 2; - val <<= 2; - } - if (val <= 0x7fffffff) { - n++; - } - - return n; -} - -/* - * Return the number of leading binary zeros in a signed 64-bit - * value. - */ -static uint8 leading_zeros_64(t_int64 val) -{ - uint8 n = 0; - - if (val == 0) { - return 64; - } - - while (1) { - if (val < 0) break; - - n++; - - val <<= 1; - } - - return n; -} - -/* - * Shift a 32-bit unsigned value, 'val', right by 'count' bits. If any - * non-zero bits are shifted off, they are "jammed" into the least - * significant bit of the result by setting the least significant bit - * to 1. - * - * Derived from the SoftFloat 2c package (see copyright notice above) - */ -static void shift_right_32_jamming(uint32 val, int16 count, uint32 *result) -{ - uint32 tmp; - - if (count == 0) { - tmp = val; - } else if (count < 32) { - tmp = (val >> count) | ((val << ((-count) & 31)) != 0); - } else { - tmp = (val != 0); - } - - *result = tmp; -} - -/* - * Shift a 64-bit unsigned value, 'val', right by 'count' bits. If any - * non-zero bits are shifted off, they are "jammed" into the least - * significant bit of the result by setting the least significant bit - * to 1. - * - * Derived from the SoftFloat 2c package (see copyright notice above) - */ -static void shift_right_64_jamming(t_uint64 val, int16 count, t_uint64 *result) -{ - t_uint64 tmp; - - if (count == 0) { - tmp = val; - } else if (count < 64) { - tmp = (val >> count) | ((val << ((-count) & 63)) != 0); - } else { - tmp = (val != 0); - } - - *result = tmp; -} - -/* - * Shifts the 128-bit value formed by concatenating val_a and val_b - * right by 64 _plus_ the number of bits given in 'count'. - * - * Derived from the SoftFloat 2c package (see copyright notice above) - */ -static void shift_right_extra_64_jamming(t_uint64 val_a, t_uint64 val_b, int16 count, - t_uint64 *r_a, t_uint64 *r_b) -{ - t_uint64 a, b; - int8 neg_count = (-count) & 63; - - if (count == 0) { - b = val_b; - a = val_a; - } else if (count < 64) { - b = (val_a << neg_count) | (val_b != 0); - a = val_a >> count; - } else { - if (count == 64) { - b = val_a | (val_b != 0); - } else { - b = ((val_a | val_b) != 0); - } - a = 0; - } - - *r_a = a; - *r_b = b; -} - -/* - * Shift the 128-bit value formed by val_a and val_b right by - * 64 plus the number of bits given in count. - * - * Derived from the SoftFloat 2c package (see copyright notice above) - */ -static void shift_right_128_jamming(t_uint64 val_a, t_uint64 val_b, int16 count, - t_uint64 *r_a, t_uint64 *r_b) -{ - t_uint64 tmp_a, tmp_b; - int8 neg_count = (-count) & 63; - - if (count == 0) { - tmp_a = val_a; - tmp_b = val_b; - } else if (count < 64) { - tmp_a = (val_a >> count); - tmp_b = (val_a << neg_count) | (val_b != 0); - } else { - if (count == 64) { - tmp_b = val_a | (val_b != 0); - } else { - tmp_b = ((val_a | val_b) != 0); - } - tmp_a = 0; - } - - *r_a = tmp_a; - *r_b = tmp_b; -} - -/* - * Shifts the 128-bit value formed by val_a and val_b left by the - * number of bits given in count. - * - * Derived from the SoftFloat 2c package (see copyright notice above) - */ -static void short_shift_left_128(t_uint64 val_a, t_uint64 val_b, int16 count, - t_uint64 *r_a, t_uint64 *r_b) -{ - *r_b = val_b << count; - if (count == 0) { - *r_a = val_a; - } else { - *r_a = (val_a << count) | (val_b >> ((-count) & 63)); - } -} - -/* - * Shifts the 128-bit value formed by val_a and val_b right by the - * number of bits given ihn 'count'. Any bits shifted off are lost. - * - * Derived from the SoftFloat 2c package (see copyright notice above) - */ -static void shift_right_128(t_uint64 val_a, t_uint64 val_b, int16 count, - t_uint64 *r_a, t_uint64 *r_b) -{ - t_uint64 tmp_a, tmp_b; - int8 neg_count; - - neg_count = (- count) & 63; - - if (count == 0) { - tmp_a = val_a; - tmp_b = val_b; - } else if (count < 64) { - tmp_a = val_a >> count; - tmp_b = (val_a << neg_count) | (val_b >> count); - } else { - tmp_a = 0; - tmp_b = (count < 128) ? (val_a >> (count & 63)) : 0; - } - - *r_a = tmp_a; - *r_b = tmp_b; -} - -/* - * Add two 128-bit values. - * - * Derived from the SoftFloat 2c package (see copyright notice above) - */ -static void add_128(t_uint64 a0, t_uint64 a1, - t_uint64 b0, t_uint64 b1, - t_uint64 *r_low, t_uint64 *r_high) -{ - t_uint64 tmp; - - tmp = a1 + b1; - *r_high = tmp; - *r_low = a0 + b0 + (tmp < a1); -} - -/* - * Subract two 128-bit values. - * - * Derived from the SoftFloat 2c package (see copyright notice above) - */ -static void sub_128(t_uint64 a0, t_uint64 a1, - t_uint64 b0, t_uint64 b1, - t_uint64 *r_low, t_uint64 *r_high) -{ - *r_high = a1 - b1; - *r_low = a0 - b0 - (a1 < b1); -} - -/* - * Multiplies a by b to obtain a 128-bit product. The product is - * broken into two 64-bit pieces which are stored at r_low and r_high. - * - * Derived from the SoftFloat 2c package (see copyright notice above) - */ -static void mul_64_to_128(t_uint64 a, t_uint64 b, t_uint64 *r_low, t_uint64 *r_high) -{ - uint32 a_high, a_low, b_high, b_low; - t_uint64 rl, rm_a, rm_b, rh; - - a_low = (uint32)a; - a_high = a >> 32; - - b_low = (uint32)b; - b_high = b >> 32; - - rh = ((t_uint64) a_low) * b_low; - rm_a = ((t_uint64) a_low) * b_high; - rm_b = ((t_uint64) a_high) * b_low; - rl = ((t_uint64) a_high) * b_high; - - rm_a += rm_b; - - rl += (((t_uint64)(rm_a < rm_b)) << 32) + (rm_a >> 32); - rm_a <<= 32; - rh += rm_a; - rl += (rh < rm_a); - - *r_high = rh; - *r_low = rl; -} - -/* - * Derived from the SoftFloat 2c package (see copyright notice above) - */ -static void mul_64_by_shifted_32_to_128(t_uint64 a, uint32 b, t_mau_128 *result) -{ - t_uint64 mid; - - mid = (t_uint64)(uint32) a * b; - result->low = mid << 32; - result->high = (t_uint64)(uint32)(a >> 32) * b + (mid >> 32); -} - -/* - * Returns an approximation of the 64-bit integer value obtained by - * dividing 'b' into the 128-bit value 'a0' and 'a1'. - * - * Derived from the SoftFloat 2c package (see copyright notice above) - */ -static t_uint64 estimate_div_128_to_64(t_uint64 a0, t_uint64 a1, t_uint64 b) -{ - t_uint64 b0, b1; - t_uint64 rem0, rem1, term0, term1; - t_uint64 z; - - if (b <= a0) { - return 0xffffffffffffffffull; - } - - b0 = b >> 32; - z = (b0 << 32 <= a0) ? 0xffffffff00000000ull : (a0 / b0) << 32; - - mul_64_to_128( b, z, &term0, &term1 ); - - sub_128( a0, a1, term0, term1, &rem0, &rem1 ); - - while (((int64_t)rem0) < 0) { - z -= 0x100000000ull; - b1 = b << 32; - add_128(rem0, rem1, b0, b1, &rem0, &rem1); - } - - rem0 = (rem0 << 32) | (rem1 >> 32); - z |= (b0<<32 <= rem0) ? 0xffffffff : rem0 / b0; - - return z; -} - -/* - * Returns an approximation of the square root of the 32-bit - * value 'a'. - * - * Derived from the SoftFloat 2c package (see copyright notice above) - */ -static uint32 estimate_sqrt_32(int16 a_exp, uint32 a) -{ - static const uint16 sqrt_odd_adjust[] = { - 0x0004, 0x0022, 0x005D, 0x00B1, 0x011D, 0x019F, 0x0236, 0x02E0, - 0x039C, 0x0468, 0x0545, 0x0631, 0x072B, 0x0832, 0x0946, 0x0A67 - }; - - static const uint16 sqrt_even_adjust[] = { - 0x0A2D, 0x08AF, 0x075A, 0x0629, 0x051A, 0x0429, 0x0356, 0x029E, - 0x0200, 0x0179, 0x0109, 0x00AF, 0x0068, 0x0034, 0x0012, 0x0002 - }; - - int8 index; - uint32 z; - - index = (a >> 27) & 0xf; - - if (a_exp & 1) { - z = 0x4000 + (a >> 17) - sqrt_odd_adjust[index]; - z = ((a / z) << 14) + (z << 15); - a >>= 1; - } - else { - z = 0x8000 + (a >> 17) - sqrt_even_adjust[index]; - z = a / z + z; - z = (0x20000 <= z) ? 0xFFFF8000 : ( z<<15 ); - if ( z <= a ) return (uint32) (((int32) a) >> 1); - } - - return ((uint32) ((((t_uint64) a )<<31 ) / z)) + (z >> 1); -} - -static uint32 approx_recip_sqrt_32(uint32 oddExpA, uint32 a) -{ - int index; - uint16 eps, r0; - uint32 ESqrR0; - uint32 sigma0; - uint32 r; - uint32 sqrSigma0; - - static const uint16 softfloat_approxRecipSqrt_1k0s[16] = { - 0xB4C9, 0xFFAB, 0xAA7D, 0xF11C, 0xA1C5, 0xE4C7, 0x9A43, 0xDA29, - 0x93B5, 0xD0E5, 0x8DED, 0xC8B7, 0x88C6, 0xC16D, 0x8424, 0xBAE1 - }; - static const uint16 softfloat_approxRecipSqrt_1k1s[16] = { - 0xA5A5, 0xEA42, 0x8C21, 0xC62D, 0x788F, 0xAA7F, 0x6928, 0x94B6, - 0x5CC7, 0x8335, 0x52A6, 0x74E2, 0x4A3E, 0x68FE, 0x432B, 0x5EFD - }; - - index = (a>>27 & 0xE) + oddExpA; - eps = (uint16) (a>>12); - r0 = softfloat_approxRecipSqrt_1k0s[index] - - ((softfloat_approxRecipSqrt_1k1s[index] * (uint32) eps) - >>20); - ESqrR0 = (uint32) r0 * r0; - if ( ! oddExpA ) ESqrR0 <<= 1; - sigma0 = ~(uint32) (((uint32) ESqrR0 * (t_uint64) a)>>23); - r = ((uint32) r0<<16) + ((r0 * (t_uint64) sigma0)>>25); - sqrSigma0 = ((t_uint64) sigma0 * sigma0)>>32; - r += ((uint32) ((r>>1) + (r>>3) - ((uint32) r0<<14)) - * (t_uint64) sqrSigma0) - >>48; - if ( ! (r & 0x80000000) ) r = 0x80000000; - return r; -} - -/* - * Return the properly rounded 32-bit integer corresponding to 'sign' - * and 'frac'. - * - * Derived from the SoftFloat 2c package (see copyright notice above) - */ -static uint32 round_pack_int(t_bool sign, t_uint64 frac, RM rounding_mode) -{ - int8 round_increment, round_bits; - int32 result; - - round_increment = 0x40; - - if (!(rounding_mode == ROUND_NEAREST)) { - if (rounding_mode == ROUND_ZERO) { - round_increment = 0; - } else { - round_increment = 0x7f; - if (sign) { - if (rounding_mode == ROUND_PLUS_INF) { - round_increment = 0; - } - } else { - if (rounding_mode == ROUND_MINUS_INF) { - round_increment = 0; - } - } - } - } - - round_bits = frac & 0x7f; - frac = (frac + round_increment) >> 7; - frac &= ~((t_uint64)((round_bits ^ 0x40) == 0) & - (t_uint64)(rounding_mode == ROUND_NEAREST)); - - result = (int32)frac; - - if (sign) { - result = -result; - } - - if ((frac >> 32) || (result && ((result < 0) ^ sign))) { - mau_exc(MAU_ASR_IO, MAU_ASR_OM); /* Integer overflow */ - mau_exc(MAU_ASR_PS, MAU_ASR_PM); /* Inexact */ - return sign ? (int32) 0x80000000 : 0x7fffffff; - } - - if (round_bits) { - mau_exc(MAU_ASR_PS, MAU_ASR_PM); - } - - return result; -} - -/* - * Return the properly rounded 64-bit integer corresponding to 'sign' - * and 'frac'. - * - * Derived from the SoftFloat 2c package (see copyright notice above) - */ -static t_int64 round_pack_int64(t_bool sign, - t_uint64 abs_0, t_uint64 abs_1, - RM rounding_mode) -{ - t_bool increment; - int64_t z; - - increment = (t_int64)abs_1 < 0; - - if (rounding_mode != ROUND_NEAREST) { - if (rounding_mode == ROUND_ZERO) { - increment = 0; - } else { - if (sign) { - increment = (rounding_mode == ROUND_MINUS_INF) && abs_1; - } else { - increment = (rounding_mode == ROUND_PLUS_INF) && abs_1; - } - } - } - - if (increment) { - ++abs_0; - if (abs_0 == 0) { - /* Overflow */ - mau_exc(MAU_ASR_OS, MAU_ASR_OM); - return sign ? 0x8000000000000000ull : 0x7fffffffffffffffull; - } - abs_0 &= ~((t_uint64)((abs_1 << 1) == 0) & - (t_uint64)(rounding_mode == ROUND_NEAREST)); - } - - z = abs_0; - if (sign) { - z = -z; - } - if (z && ((z < 0) ^ sign)) { - /* Overflow */ - mau_exc(MAU_ASR_OS, MAU_ASR_OM); - return sign ? 0x8000000000000000ull : 0x7fffffffffffffffull; - } - - if (abs_1) { - mau_exc(MAU_ASR_PS, MAU_ASR_PM); - } - - return z; -} - -/* - * Return a properly rounded 32-bit floating point value, given a sign - * bit, exponent, fractional part, and a rounding mode. - * - * Derived from the SoftFloat 2c package (see copyright notice above) - */ -static SFP round_pack_sfp(t_bool sign, int16 exp, uint32 frac, RM rounding_mode) -{ - int8 round_increment, round_bits; - uint8 is_tiny; - - is_tiny = 0; - round_increment = 0x40; - - if (rounding_mode != ROUND_NEAREST) { - if (rounding_mode == ROUND_ZERO) { - round_increment = 0; - } else { - if (sign) { - if (rounding_mode == ROUND_PLUS_INF) { - round_increment = 0; - } - } else { - if (rounding_mode == ROUND_MINUS_INF) { - round_increment = 0; - } - } - } - } - - round_bits = frac & 0x7f; - - if (0xfd <= (uint16) exp) { - if ((0xfd < exp) || - (exp == 0xfd && (int32)(frac + round_increment) < 0)) { - mau_exc(MAU_ASR_OS, MAU_ASR_OM); - mau_exc(MAU_ASR_PS, MAU_ASR_PM); - return PACK_SFP(sign, 0xff, 0) - (round_increment == 0); - } - if (exp < 0) { - is_tiny = (TININESS_BEFORE_ROUNDING || - ((exp < -1) || - (frac + round_increment < 0x80000000))); - shift_right_32_jamming(frac, -exp, &frac); - exp = 0; - round_bits = frac & 0x7f; - if (is_tiny && round_bits) { - mau_exc(MAU_ASR_US, MAU_ASR_UM); - } - } - } - - if (round_bits) { - mau_exc(MAU_ASR_PS, MAU_ASR_PM); - } - - frac = (frac + round_increment) >> 7; - frac &= ~((t_uint64)((round_bits ^ 0x40) == 0) & - (t_uint64)(rounding_mode == ROUND_NEAREST)); - if (frac == 0) { - exp = 0; - } - - return PACK_SFP(sign, exp, frac); -} - -/* - * Return a properly rounded 64-bit floating point value, given a sign - * bit, exponent, fractional part, and a rounding mode. - * - * Derived from the SoftFloat 2c package (see copyright notice above) - */ -static DFP round_pack_dfp(t_bool sign, int16 exp, t_uint64 frac, - t_bool xfp_sticky, RM rounding_mode) -{ - int16 round_increment, round_bits; - t_bool lsb, round, sticky; - uint8 is_tiny; - - is_tiny = 0; - round_increment = 0; - - if (rounding_mode != ROUND_NEAREST) { - if (rounding_mode == ROUND_ZERO) { - round_increment = 0; - } else { - round_increment = 0x7ff; - if (sign) { - if (rounding_mode == ROUND_PLUS_INF) { - round_increment = 0; - } - } else { - if (rounding_mode == ROUND_MINUS_INF) { - round_increment = 0; - } - } - } - } - - round_bits = frac & 0x7ff; - - if (0x7fd <= (uint16) exp) { - if (exp < 0) { - is_tiny = (TININESS_BEFORE_ROUNDING || - (exp < -1) || - ((frac + round_increment) < 0x8000000000000000ull)); - shift_right_64_jamming(frac, -exp, &frac); - exp = 0; - round_bits = frac & 0x7ff; - if (is_tiny && round_bits) { - mau_exc(MAU_ASR_US, MAU_ASR_UM); - } - } else if (0x7fd < exp) { - mau_exc(MAU_ASR_OS, MAU_ASR_OM); - mau_exc(MAU_ASR_PS, MAU_ASR_PM); - return (PACK_DFP(sign, 0x7ff, 0) - (round_increment == 0)); - } - } - - if (round_bits) { - mau_exc(MAU_ASR_PS, MAU_ASR_PM); - } - - if (rounding_mode == ROUND_NEAREST) { - frac >>= 11; - lsb = (frac & 1) != 0; - round = (round_bits & 0x400) != 0; - sticky = ((round_bits & 0x3ff) != 0) | xfp_sticky; - if (round & (sticky || lsb)) { - frac++; - if (frac == 0) { - exp++; - } - } - } else { - frac = (frac + round_increment) >> 11; - lsb = !((t_bool)(round_bits ^ 0x200)); - frac &= ~((t_uint64)lsb); - } - - return PACK_DFP(sign, exp, frac); -} - -/* - * Return a properly rounded 80-bit floating point value, given a sign - * bit, exponent, fractional part, and a rounding mode. - * - * Derived from the SoftFloat 2c package (see copyright notice above) - */ -static void round_pack_xfp(t_bool sign, int32 exp, - t_uint64 frac_a, t_uint64 frac_b, - RM rounding_mode, XFP *result) -{ - uint8 is_tiny; - t_int64 round_mask; - - if (0x7ffd <= (uint32)(exp - 1)) { - if (0x7ffe < exp) { - round_mask = 0; - mau_exc(MAU_ASR_OS, MAU_ASR_OM); - mau_exc(MAU_ASR_PS, MAU_ASR_PM); - if ((rounding_mode == ROUND_ZERO) || - (sign && (rounding_mode == ROUND_PLUS_INF)) || - (!sign && (rounding_mode == ROUND_MINUS_INF))) { - PACK_XFP(sign, 0x7ffe, ~round_mask, result); - return; - } - PACK_XFP(sign, 0x7fff, 0x8000000000000000ull, result); - return; - } - if (exp <= 0) { - is_tiny = (TININESS_BEFORE_ROUNDING || - (exp < 0) || - (frac_a < 0xffffffffffffffffull)); - shift_right_extra_64_jamming(frac_a, frac_b, (int16)(1 - exp), &frac_a, &frac_b); - exp = 0; - if (is_tiny && frac_b) { - mau_exc(MAU_ASR_US, MAU_ASR_UM); - } - if (frac_b) { - mau_exc(MAU_ASR_PS, MAU_ASR_PM); - } - PACK_XFP(sign, exp, frac_a, result); - return; - } - } - if (frac_b) { - mau_exc(MAU_ASR_PS, MAU_ASR_PM); - } - if (frac_a == 0) { - exp = 0; - } - PACK_XFP_S(sign, exp, frac_a, frac_b, result); -} - -/* - * Given two 80-bit floating point values 'a' and 'b', one of which is - * a NaN, return the appropriate NaN result. - * - * Derived from the SoftFloat 2c package (see copyright notice above) - */ -static void propagate_xfp_nan(XFP *a, XFP *b, XFP *result) -{ - uint8 a_is_nan, a_is_signaling_nan; - uint8 b_is_nan, b_is_signaling_nan; - - a_is_nan = XFP_IS_NAN(a); - a_is_signaling_nan = XFP_IS_TRAPPING_NAN(a); - b_is_nan = XFP_IS_NAN(b); - b_is_signaling_nan = XFP_IS_TRAPPING_NAN(b); - - a->frac |= 0xc000000000000000ull; - b->frac |= 0xc000000000000000ull; - - if (a_is_signaling_nan | b_is_signaling_nan) { - mau_exc(MAU_ASR_IS, MAU_ASR_IM); - } - - if (a_is_nan) { - if (a_is_signaling_nan & b_is_nan) { - result->sign_exp = b->sign_exp; - result->frac = b->frac; - } else { - result->sign_exp = a->sign_exp; - result->frac = a->frac; - } - } else { - result->sign_exp = b->sign_exp; - result->frac = b->frac; - } -} - -/* - * Derived from the SoftFloat 2c package (see copyright notice above) - */ -static void propagate_xfp_nan_128(XFP* a, XFP* b, t_mau_128* result) -{ - t_bool is_sig_nan_a, is_sig_nan_b; - t_uint64 non_frac_a_low, non_frac_b_low; - uint16 mag_a, mag_b; - - is_sig_nan_a = XFP_IS_TRAPPING_NAN(a); - is_sig_nan_b = XFP_IS_TRAPPING_NAN(b); - - non_frac_a_low = a->frac & 0xC000000000000000ull; - non_frac_b_low = b->frac & 0xC000000000000000ull; - - if (is_sig_nan_a | is_sig_nan_b) { - /* Invalid */ - mau_exc(MAU_ASR_IS, MAU_ASR_IM); - if (is_sig_nan_a) { - if (is_sig_nan_b) goto return_larger_mag; - if (XFP_IS_NAN(b)) goto return_b; - goto return_a; - } else { - if (XFP_IS_NAN(a)) goto return_a; - goto return_b; - } - } - - return_larger_mag: - mag_a = a->frac & 0x7fff; - mag_b = b->frac & 0x7fff; - if (mag_a < mag_b) goto return_b; - if (mag_b < mag_a) goto return_a; - if (a->frac < b->frac) goto return_b; - if (b->frac < a->frac) goto return_a; - if (a->sign_exp < b->sign_exp) goto return_a; - return_b: - result->high = b->sign_exp; - result->low = non_frac_b_low; - return; - return_a: - result->high = a->sign_exp; - result->low = non_frac_a_low; - return; -} - -/* - * Normalize and round an extended-precision floating point value. - * - * Partially derived from the SoftFloat 2c package (see copyright - * notice above) - */ -static void normalize_round_pack_xfp(t_bool sign, int32 exp, - t_uint64 frac_0, t_uint64 frac_1, - RM rounding_mode, XFP *result) -{ - int8 shift_count; - - if (frac_0 == 0) { - frac_0 = frac_1; - frac_1 = 0; - exp -= 64; - } - - shift_count = leading_zeros_64(frac_0); - short_shift_left_128(frac_0, frac_1, shift_count, &frac_0, &frac_1); - exp -= shift_count; - - round_pack_xfp(sign, exp, frac_0, frac_1, rounding_mode, result); -} - - -/* - * Normalize the subnormal 80-bit floating point value represented by - * the denormalized input fractional comonent. - * - * Derived from the SoftFloat 2c package (see copyright notice above) - */ -static void normalize_sfp_subnormal(uint32 in_frac, int16 *out_exp, uint32 *out_frac) -{ - int8 shift_count; - - shift_count = leading_zeros(in_frac) - 8; - - if (shift_count < 0) { - /* There was invalid input, there's nothing we can do. */ - *out_frac = in_frac; - *out_exp = 0; - return; - } - - *out_frac = in_frac << shift_count; - *out_exp = (uint16)(1 - shift_count); -} - -/* - * Normalize the subnormal 64-bit floating point value represented by - * the denormalized input fractional comonent. - * - * Derived from the SoftFloat 2c package (see copyright notice above) - */ -static void normalize_dfp_subnormal(t_uint64 in_frac, int16 *out_exp, t_uint64 *out_frac) -{ - int8 shift_count; - - shift_count = leading_zeros_64(in_frac) - 11; - - if (shift_count < 0) { - /* There was invalid input, there's nothing we can do. */ - *out_frac = in_frac; - *out_exp = 0; - return; - } - - *out_frac = in_frac << shift_count; - *out_exp = 1 - shift_count; -} - -/* - * Normalize the subnormal 32-bit floating point value represented by - * the denormalized input fractional comonent. - * - * Derived from the SoftFloat 2c package (see copyright notice above) - */ -static void normalize_xfp_subnormal(t_uint64 in_frac, int32 *out_exp, t_uint64 *out_frac) -{ - int8 shift_count; - - shift_count = leading_zeros_64(in_frac); - if (shift_count < 64) { - *out_frac = in_frac << shift_count; - } else { - *out_frac = 0; - } - *out_exp = 1 - shift_count; -} - -/* - * Returns the result of converting the 32-bit floating point NaN - * value to the canonincal NaN format. - * - * Derived from the SoftFloat 2c package (see copyright notice above) - */ -static T_NAN sfp_to_common_nan(SFP val) -{ - T_NAN nan = {0}; - - if (SFP_IS_TRAPPING_NAN(val)) { - mau_state.trapping_nan = TRUE; - } - - nan.sign = val >> 31; - nan.low = 0; - nan.high = ((t_uint64) val) << 41; - - return nan; -} - -/* - * Returns the result of converting the 64-bit floating point NaN - * value to the canonincal NaN format. - * - * Derived from the SoftFloat 2c package (see copyright notice above) - */ -static T_NAN dfp_to_common_nan(DFP val) -{ - T_NAN nan = {0}; - - if (DFP_IS_TRAPPING_NAN(val)) { - mau_state.trapping_nan = TRUE; - } - - nan.sign = (val >> 63) & 1; - nan.low = 0; - nan.high = (t_uint64)(val << 12); - - return nan; -} - -/* - * Returns the result of converting the 80-bit floating point NaN - * value to the canonincal NaN format. - * - * Derived from the SoftFloat 2c package (see copyright notice above) - */ -static T_NAN xfp_to_common_nan(XFP *val) -{ - T_NAN nan = {0}; - - if (XFP_IS_TRAPPING_NAN(val)) { - mau_state.trapping_nan = TRUE; - } - - nan.sign = val->sign_exp >> 15; - nan.low = 0; - nan.high = val->frac << 1; - - return nan; -} - -/* - * Returns the result of converting a canonical NAN format value to a - * 32-bit floating point format. - * - * Derived from the SoftFloat 2c package (see copyright notice above) - */ -static SFP common_nan_to_sfp(T_NAN nan) -{ - return ((((uint32)nan.sign) << 31) - | 0x7fc00000 - | (nan.high >> 41)); -} - -/* - * Returns the result of converting a canonical NAN format value to a - * 64-bit floating point format. - * - * Derived from the SoftFloat 2c package (see copyright notice above) - */ -static DFP common_nan_to_dfp(T_NAN nan) -{ - return ((((t_uint64)nan.sign) << 63) - | 0x7ff8000000000000ull - | (nan.high >> 12)); -} - -/* - * Returns the result of converting a canonical NAN format value to an - * 80-bit floating point format. - * - * Derived from the SoftFloat 2c package (see copyright notice above) - */ -static void common_nan_to_xfp(T_NAN nan, XFP *result) -{ - result->frac = 0xc000000000000000ull | (nan.high >> 1); - result->sign_exp = (((uint16)nan.sign) << 15) | 0x7fff; -} - -/* - * Convert a 32-bit floating point value to an 80-bit floating point - * value. - * - * Derived from the SoftFloat 2c package (see copyright notice above) - */ -static void sfp_to_xfp(SFP val, XFP *result) -{ - t_bool sign; - int16 exp; - uint32 frac; - - sign = SFP_SIGN(val); - exp = SFP_EXP(val); - frac = SFP_FRAC(val); - - if (exp == 0xff) { - if (frac) { - common_nan_to_xfp(sfp_to_common_nan(val), result); - return; - } - } - - if (exp == 0) { - if (frac == 0) { - PACK_XFP(sign, 0, 0, result); - return; - } - normalize_sfp_subnormal(frac, &exp, &frac); - } - - frac |= 0x800000; - - PACK_XFP(sign, exp + 0x3f80, ((t_uint64) frac) << 40, result); -} - -/* - * Convert a 64-bit floating point value to an 80-bit floating point value. - * - * Derived from the SoftFloat 2c package (see copyright notice above) - */ -void dfp_to_xfp(DFP val, XFP *result) -{ - t_bool sign; - int16 exp; - t_uint64 frac; - - sign = DFP_SIGN(val); - exp = DFP_EXP(val); - frac = DFP_FRAC(val); - - if (exp == 0x7ff) { - if (sign) { - common_nan_to_xfp(dfp_to_common_nan(val), result); - } - - PACK_XFP(sign, 0xff, 0, result); - return; - } - if (exp == 0) { - if (frac == 0) { - PACK_XFP(sign, 0, 0, result); - return; - } - normalize_dfp_subnormal(frac, &exp, &frac); - } - - PACK_XFP(sign, - exp + 0x3c00, - 0x8000000000000000ull | (frac << 11), - result); -} - -/* - * Convert an 80-bit floating point value to a 32-bit floating point - * value. - * - * Derived from the SoftFloat 2c package (see copyright notice above) - */ -static SFP xfp_to_sfp(XFP *val, RM rounding_mode) -{ - t_bool sign; - int32 exp; - t_uint64 frac; - uint32 dst_frac; - - sign = XFP_SIGN(val); - exp = XFP_EXP(val); - frac = XFP_FRAC(val); - - if (exp == 0x7fff) { - if ((t_uint64)(frac << 1)) { - return common_nan_to_sfp(xfp_to_common_nan(val)); - } - return PACK_SFP(sign, 0xff, 0); - } - - shift_right_64_jamming(frac, 33, &frac); - - dst_frac = (uint32)frac; - - if (exp || frac) { - exp -= 0x3f81; - } - - return round_pack_sfp(sign, exp, dst_frac, rounding_mode); -} - -/* - * Convert an 80-bit floating point value to a 64-bit floating point - * value. - * - * Derived from the SoftFloat 2c package (see copyright notice above) - */ -static DFP xfp_to_dfp(XFP *val, RM rounding_mode) -{ - t_bool sign; - int32 exp; - t_uint64 frac; - - sign = XFP_SIGN(val); - exp = XFP_EXP(val); - frac = XFP_FRAC(val); - - sim_debug(TRACE_DBG, &mau_dev, - "[xfp_to_dfp] input=%04x%016llx input_exp=%04x packed_exp=%04x\n", - val->sign_exp, val->frac, (uint16)exp, (uint16)(exp - 0x3c01)); - - if (exp == 0x7fff) { - if ((t_uint64)(frac << 1)) { - return common_nan_to_dfp(xfp_to_common_nan(val)); - } - return PACK_DFP(sign, 0x7ff, 0); - } - - if (exp || frac) { - exp -= 0x3c01; - } - - return round_pack_dfp(sign, exp, frac, val->s, rounding_mode); -} - -/***************************************************************************** - * Comparison Functions - ****************************************************************************/ - -/* - * Returns true if the two 80-bit floating point values are equal. - * - * Derived from the SoftFloat 2c package (see copyright notice above) - */ -static uint32 xfp_eq(XFP *a, XFP *b) -{ - if (((XFP_EXP(a) == 0x7fff) && (t_uint64)(XFP_FRAC(a) << 1)) || - ((XFP_EXP(b) == 0x7fff) && (t_uint64)(XFP_FRAC(b) << 1))) { - - /* Check for NAN and raise invalid exception */ - if (XFP_IS_TRAPPING_NAN(a) || XFP_IS_TRAPPING_NAN(b)) { - mau_exc(MAU_ASR_IS, MAU_ASR_IM); - } - - return 0; - } - - return ((a->frac == b->frac) && - ((a->sign_exp == b->sign_exp) || - ((a->frac == 0) && ((uint16)((a->sign_exp|b->sign_exp) << 1) == 0)))); -} - -/* - * Returns true if the 80-bit floating point value 'a' is less than - * the 80-bit floating point value 'b'. - * - * Derived from the SoftFloat 2c package (see copyright notice above) - */ -static uint32 xfp_lt(XFP *a, XFP *b) -{ - uint32 a_sign, b_sign; - - if (((XFP_EXP(a) == 0x7fff) && (t_uint64)(XFP_FRAC(a) << 1)) || - ((XFP_EXP(b) == 0x7fff) && (t_uint64)(XFP_FRAC(b) << 1))) { - return 0; - } - - a_sign = XFP_SIGN(a); - b_sign = XFP_SIGN(b); - - if (a_sign != b_sign) { - return(a_sign && - ((((uint16)((a->sign_exp|b->sign_exp) << 1)) | a->frac | b->frac) != 0)); - } - - if (a_sign) { - return (b->sign_exp < a->sign_exp) || ((b->sign_exp == a->sign_exp) && (b->frac < a->frac)); - } else { - return (a->sign_exp < b->sign_exp) || ((a->sign_exp == b->sign_exp) && (a->frac < b->frac)); - } -} - -/***************************************************************************** - * Conversion Functions - ****************************************************************************/ - -/* - * Convert a 32-bit signed integer value to an IEEE-754 extended - * precion (80-bit) floating point value. - * - * Derived from the SoftFloat 2c package (see copyright notice above) - */ -void mau_int_to_xfp(int32 val, XFP *result) -{ - int32 shift_width; - t_bool sign; - uint32 abs_val; - uint16 sign_exp = 0; - t_uint64 frac = 0; - - if (val) { - sign = (val < 0); - abs_val = (uint32)(sign ? -val : val); - shift_width = leading_zeros(abs_val); - sign_exp = (sign << 15) | (0x401e - shift_width); - frac = (t_uint64) (abs_val << shift_width) << 32; - } - - result->sign_exp = sign_exp; - result->frac = frac; - result->s = 0; - - if (sign_exp & 0x8000) { - mau_state.asr |= MAU_ASR_N; - } - - if ((sign_exp & 0x7fff) == 0 && frac == 0) { - mau_state.asr |= MAU_ASR_Z; - } -} - -/* - * Convert a floating point value to a 64-bit integer. - * - * Derived from the SoftFloat 2c package (see copyright notice above) - */ -t_int64 xfp_to_int64(XFP *val, RM rounding_mode) -{ - t_bool sign; - int32 exp, shift_count; - t_uint64 frac, frac_extra; - - sign = XFP_SIGN(val); - exp = XFP_EXP(val); - frac = XFP_FRAC(val); - shift_count = 0x403e - exp; - if (shift_count <= 0) { - if (shift_count) { - mau_exc(MAU_ASR_IS, MAU_ASR_IM); - if (!sign || ((exp == 0x7fff) && (frac != 0x8000000000000000ull))) { - return 0x7fffffffffffffffull; - } - return 0x8000000000000000ull; - } - frac_extra = 0; - } else { - shift_right_extra_64_jamming(frac, 0, shift_count, &frac, &frac_extra); - } - - return round_pack_int64(sign, frac, frac_extra, rounding_mode); -} - -void mau_int64_to_xfp(t_uint64 val, XFP *result) -{ - t_bool sign; - t_uint64 abs; - int8 shift_count; - - if (val == 0) { - PACK_XFP(0, 0, 0, result); - return; - } - - sign = (val & 0x8000000000000000ull) != 0ull; - abs = val & 0x7fffffffffffffffull; - shift_count = leading_zeros_64(abs); - if (shift_count < 64) { - abs = abs << shift_count; - } else { - abs = 0; - } - PACK_XFP(sign, 0x403e - shift_count, abs, result); -} - -/* - * Convert a float value to a decimal value. - */ -void xfp_to_decimal(XFP *a, DEC *d, RM rounding_mode) -{ - t_int64 tmp; - int i; - t_bool sign; - uint16 digits[19] = {0}; - - tmp = xfp_to_int64(a, rounding_mode); - - if (tmp < 0) { - sign = 0xb; - } else { - sign = 0xa; - } - - for (i = 0; i < 19; i++) { - digits[i] = tmp % 10; - tmp /= 10; - } - - d->l = sign; - d->l |= (t_uint64)digits[0] << 4; - d->l |= (t_uint64)digits[1] << 8; - d->l |= (t_uint64)digits[2] << 12; - d->l |= (t_uint64)digits[3] << 16; - d->l |= (t_uint64)digits[4] << 20; - d->l |= (t_uint64)digits[5] << 24; - d->l |= (t_uint64)digits[6] << 28; - d->l |= (t_uint64)digits[7] << 32; - d->l |= (t_uint64)digits[8] << 36; - d->l |= (t_uint64)digits[9] << 40; - d->l |= (t_uint64)digits[10] << 44; - d->l |= (t_uint64)digits[11] << 48; - d->l |= (t_uint64)digits[12] << 52; - d->l |= (t_uint64)digits[13] << 56; - d->l |= (t_uint64)digits[14] << 60; - d->h = (uint32)digits[15]; - d->h |= (uint32)digits[15] << 4; - d->h |= (uint32)digits[15] << 8; - - sim_debug(TRACE_DBG, &mau_dev, - "[%08x] [xfp_to_decimal] " - "Digits: %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d 0x%x\n", - R[NUM_PC], - digits[17], digits[16], digits[15], digits[14], digits[13], digits[12], - digits[11], digits[10], digits[9], digits[8], digits[7], digits[6], - digits[5], digits[4], digits[3], digits[2], digits[1], digits[0], - sign); -} - -/* - * Convert a decimal value to a float value. - */ -void mau_decimal_to_xfp(DEC *d, XFP *a) -{ - int i; - t_bool sign; - uint16 digits[18] = {0}; - t_uint64 multiplier = 1; - t_uint64 tmp; - t_int64 signed_tmp; - - sim_debug(TRACE_DBG, &mau_dev, - "[%08x] [mau_decimal_to_xfp] DEC input: %08x %08x %08x\n", - R[NUM_PC], d->h, (uint32)(d->l >> 32), (uint32)(d->l)); - - sign = (d->l) & 15; - digits[0] = (d->l >> 4) & 15; - digits[1] = (d->l >> 8) & 15; - digits[2] = (d->l >> 12) & 15; - digits[3] = (d->l >> 16) & 15; - digits[4] = (d->l >> 20) & 15; - digits[5] = (d->l >> 24) & 15; - digits[6] = (d->l >> 28) & 15; - digits[7] = (d->l >> 32) & 15; - digits[8] = (d->l >> 36) & 15; - digits[9] = (d->l >> 40) & 15; - digits[10] = (d->l >> 44) & 15; - digits[11] = (d->l >> 48) & 15; - digits[12] = (d->l >> 52) & 15; - digits[13] = (d->l >> 56) & 15; - digits[14] = (d->l >> 60) & 15; - digits[15] = (d->h) & 15; - digits[16] = (d->h >> 4) & 15; - digits[17] = (d->h >> 8) & 15; - - sim_debug(TRACE_DBG, &mau_dev, - "[%08x] [mau_decimal_to_xfp] " - "Digits: %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d 0x%x\n", - R[NUM_PC], - digits[17], digits[16], digits[15], digits[14], digits[13], digits[12], - digits[11], digits[10], digits[9], digits[8], digits[7], digits[6], - digits[5], digits[4], digits[3], digits[2], digits[1], digits[0], - sign); - - tmp = 0; - - for (i = 0; i < 18; i++) { - tmp += digits[i] * multiplier; - multiplier *= 10; - } - - switch (sign) { - case 0xd: - case 0xb: - /* Negative number */ - signed_tmp = -((t_int64) tmp); - break; - /* TODO: HANDLE NAN AND INFINITY */ - default: - signed_tmp = (t_int64) tmp; - } - - sim_debug(TRACE_DBG, &mau_dev, - "[%08x] [mau_decimal_to_xfp] tmp val = %lld\n", - R[NUM_PC], signed_tmp); - - mau_int64_to_xfp((t_uint64) signed_tmp, a); - - sim_debug(TRACE_DBG, &mau_dev, - "[%08x] [mau_decimal_to_xfp] XFP = %04x%016llx\n", - R[NUM_PC], a->sign_exp, a->frac); - -} - -/* - * Convert a floating point value to a 32-bit integer. - * - * Derived from the SoftFloat 2c package (see copyright notice above) - */ -uint32 xfp_to_int(XFP *val, RM rounding_mode) -{ - t_bool sign; - int32 exp, shift_count; - t_uint64 frac; - - sign = XFP_SIGN(val); - exp = XFP_EXP(val); - frac = XFP_FRAC(val); - - if ((exp == 0x7fff) && (t_uint64)(frac << 1)) { - sign = 0; - } - - shift_count = 0x4037 - exp; - - if (shift_count <= 0) { - shift_count = 1; - } - - shift_right_64_jamming(frac, shift_count, &frac); - - return round_pack_int(sign, frac, rounding_mode); -} - -/* - * Round an 80-bit extended precission floating-point value - * to an integer. - * - * Derived from the SoftFloat 2c library (see copyright notice above) - */ -void mau_round_xfp_to_int(XFP *val, XFP *result, RM rounding_mode) -{ - t_bool sign; - int32 exp; - t_uint64 last_bit_mask, round_bits_mask; - - exp = XFP_EXP(val); - - if (0x403e <= exp) { - if ((exp == 0x7fff) && (t_uint64)(XFP_FRAC(val) << 1)) { - propagate_xfp_nan(val, val, result); - return; - } - result->sign_exp = val->sign_exp; - result->frac = val->frac; - return; - } - if (exp < 0x3ff) { - if ((exp == 0) && ((t_uint64)(XFP_FRAC(val) << 1) == 0)) { - result->sign_exp = val->sign_exp; - result->frac = val->frac; - return; - } - mau_exc(MAU_ASR_PS, MAU_ASR_PM); - sign = XFP_SIGN(val); - switch (rounding_mode) { - case ROUND_NEAREST: - if (exp == 0x3ffe && (t_uint64)(XFP_FRAC(val) << 1)) { - PACK_XFP(sign, 0x3fff, 0x8000000000000000ull, result); - return; - } - break; - case ROUND_MINUS_INF: - if (sign) { - PACK_XFP(1, 0x3fff, 0x8000000000000000ull, result); - } else { - PACK_XFP(0, 0, 0, result); - } - return; - case ROUND_PLUS_INF: - if (sign) { - PACK_XFP(1, 0, 0, result); - } else { - PACK_XFP(0, 0x3fff, 0x8000000000000000ull, result); - } - return; - default: - /* Do nothing */ - break; - } - PACK_XFP(sign, 0, 0, result); - return; - } - - last_bit_mask = 1; - last_bit_mask <<= 0x403e - exp; - round_bits_mask = last_bit_mask - 1; - - result->sign_exp = val->sign_exp; - result->frac = val->frac; - - if (rounding_mode == ROUND_NEAREST) { - result->frac += last_bit_mask >> 1; - if ((result->frac & round_bits_mask) == 0) { - result->frac &= ~last_bit_mask; - } - } else if (rounding_mode != ROUND_ZERO) { - if (XFP_SIGN(result) ^ (rounding_mode == ROUND_PLUS_INF)) { - result->frac += round_bits_mask; - } - } - - result->frac &= ~round_bits_mask; - if (result->frac == 0) { - ++result->sign_exp; - result->frac = 0x8000000000000000ull; - } - - if (result->frac != val->frac) { - mau_exc(MAU_ASR_PS, MAU_ASR_PM); - } -} - -/***************************************************************************** - * Math Functions - ****************************************************************************/ - -/* - * Derived from the SoftFloat 2c package (see copyright notice above) - */ -static void xfp_add_fracs(XFP *a, XFP *b, t_bool sign, XFP *result, RM rounding_mode) -{ - int32 a_exp, b_exp, r_exp; - t_uint64 a_frac, b_frac, r_frac_0, r_frac_1; - int32 exp_diff; - - sim_debug(TRACE_DBG, &mau_dev, - "[%08x] [ADD_FRACS] a=%04x%016llx b=%04x%016llx\n", - R[NUM_PC], - a->sign_exp, a->frac, - b->sign_exp, b->frac); - - a_exp = XFP_EXP(a); - a_frac = XFP_FRAC(a); - b_exp = XFP_EXP(b); - b_frac = XFP_FRAC(b); - - exp_diff = a_exp - b_exp; - if (0 < exp_diff) { - if (a_exp == 0x7fff) { - if ((t_uint64) (a_frac << 1)) { - propagate_xfp_nan(a, b, result); - return; - } - result->sign_exp = a->sign_exp; - result->frac = a->frac; - return; - } - if (b_exp == 0) { - --exp_diff; - } - shift_right_extra_64_jamming(b_frac, 0, exp_diff, &b_frac, &r_frac_1); - r_exp = a_exp; - } else if (exp_diff < 0) { - if (b_exp == 0x7fff) { - if ((t_uint64) (b_frac << 1)) { - propagate_xfp_nan(a, b, result); - return; - } - PACK_XFP(sign, 0x7fff, 0x8000000000000000ull, result); - return; - } - if (a_exp == 0) { - ++exp_diff; - } - - shift_right_extra_64_jamming(a_frac, 0, -exp_diff, &a_frac, &r_frac_1); - r_exp = b_exp; - } else { - if (a_exp == 0x7fff) { - if ((t_uint64)((a_frac | b_frac) << 1)) { - propagate_xfp_nan(a, b, result); - return; - } - result->sign_exp = a->sign_exp; - result->frac = a->frac; - return; - } - r_frac_1 = 0; - r_frac_0 = a_frac + b_frac; - if (a_exp == 0) { - normalize_xfp_subnormal(r_frac_0, &r_exp, &r_frac_0); - - round_pack_xfp(sign, r_exp, r_frac_0, r_frac_1, rounding_mode, result); - return; - } - r_exp = a_exp; - shift_right_extra_64_jamming(r_frac_0, r_frac_1, 1, &r_frac_0, &r_frac_1); - r_frac_0 |= 0x8000000000000000ull; - ++r_exp; - round_pack_xfp(sign, r_exp, r_frac_0, r_frac_1, rounding_mode, result); - return; - } - r_frac_0 = a_frac + b_frac; - if (((t_int64) r_frac_0) < 0) { - round_pack_xfp(sign, r_exp, r_frac_0, r_frac_1, rounding_mode, result); - return; - } - shift_right_extra_64_jamming(r_frac_0, r_frac_1, 1, &r_frac_0, &r_frac_1); - r_frac_0 |= 0x8000000000000000ull; - ++r_exp; - round_pack_xfp(sign, r_exp, r_frac_0, r_frac_1, rounding_mode, result); - return; -} - -/* - * Derived from the SoftFloat 2c package (see copyright notice above) - */ -static void xfp_sub_fracs(XFP *a, XFP *b, t_bool sign, XFP *result, RM rounding_mode) -{ - int32 a_exp, b_exp, r_exp; - t_uint64 a_frac, b_frac, r_frac_0, r_frac_1; - int32 exp_diff; - - a_exp = XFP_EXP(a); - a_frac = XFP_FRAC(a); - b_exp = XFP_EXP(b); - b_frac = XFP_FRAC(b); - exp_diff = a_exp - b_exp; - - if (0 < exp_diff) { - /* aExpBigger */ - if (a_exp == 0x7fff) { - if ((t_uint64)(a_frac << 1)) { - propagate_xfp_nan(a, b, result); - return; - } - result->sign_exp = a->sign_exp; - result->frac = a->frac; - return; - } - if (b_exp == 0) { - --exp_diff; - } - shift_right_128_jamming(b_frac, 0, exp_diff, &b_frac, &r_frac_1); - /* aBigger */ - sub_128(a_frac, 0, b_frac, r_frac_1, &r_frac_0, &r_frac_1); - r_exp = a_exp; - /* normalizeRoundAndPack */ - normalize_round_pack_xfp(sign, r_exp, r_frac_0, r_frac_1, rounding_mode, result); - return; - } - if (exp_diff < 0) { - /* bExpBigger */ - if (b_exp == 0x7fff) { - if ((t_uint64)(b_frac << 1)) { - propagate_xfp_nan(a, b, result); - return; - } - PACK_XFP(sign ? 0 : 1, 0x7fff, 0x8000000000000000ull, result); - return; - } - if (a_exp == 0) { - ++exp_diff; - } - shift_right_128_jamming(a_frac, 0, -exp_diff, &a_frac, &r_frac_1); - /* bBigger */ - sub_128(b_frac, 0, a_frac, r_frac_1, &r_frac_0, &r_frac_1); - r_exp = b_exp; - sign = sign ? 0 : 1; - /* normalizeRoundAndPack */ - normalize_round_pack_xfp(sign, r_exp, - r_frac_0, r_frac_1, - rounding_mode, result); - return; - } - if (a_exp == 0x7fff) { - if ((t_uint64)((a_frac | b_frac) << 1)) { - propagate_xfp_nan(a, b, result); - return; - } - mau_exc(MAU_ASR_IS, MAU_ASR_IM); /* Invalid */ - result->sign_exp = DEFAULT_XFP_NAN_SIGN_EXP; - result->frac = DEFAULT_XFP_NAN_FRAC; - return; - } - if (a_exp == 0) { - a_exp = 1; - b_exp = 1; - } - r_frac_1 = 0; - if (b_frac < a_frac) { - /* aBigger */ - sub_128(a_frac, 0, b_frac, r_frac_1, &r_frac_0, &r_frac_1); - r_exp = a_exp; - /* normalizeRoundAndPack */ - normalize_round_pack_xfp(sign, r_exp, - r_frac_0, r_frac_1, - rounding_mode, result); - return; - } - if (a_frac < b_frac) { - /* bBigger */ - sub_128(b_frac, 0, a_frac, r_frac_1, &r_frac_0, &r_frac_1); - r_exp = b_exp; - sign ^= 1; - - /* normalizeRoundAndPack */ - normalize_round_pack_xfp(sign, r_exp, - r_frac_0, r_frac_1, - rounding_mode, result); - return; - } - - PACK_XFP(rounding_mode == ROUND_MINUS_INF, 0, 0, result); -} - -/************************************************************************* - * - * MAU-specific functions - * - *************************************************************************/ - -/* - * Set condition flags based on comparison of the two values A and B. - * - * Derived from the SoftFloat 2c package (see copyright notice above) - */ -static void xfp_cmp(XFP *a, XFP *b) -{ - mau_state.asr &= ~(MAU_ASR_N|MAU_ASR_Z|MAU_ASR_UO); - - /* Page 5-9: - * - * "An invalid operation exception condition exists if either or - * both source operands are trapping NaNs. If the exception is - * masked then the UO flag would be set. However, if this - * exception is enabled, and, if Op1 is a trapping NaN, it is - * converted to double-extended precision and stored in DR. Else, - * Op2 (converted to double-extended precision, if necessary) is - * stored in DR." - */ - - if (XFP_IS_NAN(a) || XFP_IS_NAN(b)) { - if ((mau_state.asr & MAU_ASR_IM) == 0) { - mau_state.asr |= MAU_ASR_UO; - } else if (XFP_IS_NAN(a)) { - mau_state.dr.sign_exp = a->sign_exp; - mau_state.dr.frac = a->frac; - } else { - mau_state.dr.sign_exp = b->sign_exp; - mau_state.dr.frac = b->frac; - } - return; - } - - if (xfp_lt(a, b)) { - mau_state.asr |= MAU_ASR_N; - } - - if (xfp_eq(a, b)) { - mau_state.asr |= MAU_ASR_Z; - } -} - -static void xfp_cmpe(XFP *a, XFP *b) -{ - mau_state.asr &= ~(MAU_ASR_N|MAU_ASR_Z|MAU_ASR_UO); - - /* Page 5-10: - * - * "When two unordered values are compared, then, in additon to - * the response specified below, the invalid operation exception - * sticky flag (ASR = 1) is set and the trap invoked if the - * invalid operation exceptionis enabled."" - */ - - if ((XFP_IS_NAN(a) || XFP_IS_NAN(b)) && (mau_state.asr & MAU_ASR_IM)) { - mau_state.asr |= MAU_ASR_UO; - return; - } - - if (xfp_lt(a, b)) { - mau_state.asr |= MAU_ASR_N; - } - - if (xfp_eq(a, b)) { - mau_state.asr |= MAU_ASR_Z; - } -} - -static void xfp_cmps(XFP *a, XFP *b) -{ - mau_state.asr &= ~(MAU_ASR_N|MAU_ASR_Z|MAU_ASR_UO); - - if (XFP_IS_NAN(a) || XFP_IS_NAN(b)) { - if ((mau_state.asr & MAU_ASR_IM) == 0) { - mau_state.asr |= MAU_ASR_UO; - } else if (XFP_IS_NAN(a)) { - mau_state.dr.sign_exp = a->sign_exp; - mau_state.dr.frac = a->frac; - } else { - mau_state.dr.sign_exp = b->sign_exp; - mau_state.dr.frac = b->frac; - } - return; - } - - if (xfp_lt(a, b)) { - mau_state.asr |= MAU_ASR_Z; - } else if (xfp_eq(a, b)) { - mau_state.asr |= MAU_ASR_N; - } -} - -static void xfp_cmpes(XFP *a, XFP *b) -{ - mau_state.asr &= ~(MAU_ASR_N|MAU_ASR_Z|MAU_ASR_UO); - - if ((XFP_IS_NAN(a) || XFP_IS_NAN(b)) && (mau_state.asr & MAU_ASR_IM)) { - mau_state.asr |= MAU_ASR_UO; - return; - } - - if (xfp_lt(a, b)) { - mau_state.asr |= MAU_ASR_Z; - } - - if (xfp_eq(a, b)) { - mau_state.asr |= MAU_ASR_N; - } -} - -static void xfp_add(XFP *a, XFP *b, XFP *result, RM rounding_mode) -{ - uint32 a_sign, b_sign; - - a_sign = XFP_SIGN(a); - b_sign = XFP_SIGN(b); - - if (a_sign == b_sign) { - xfp_add_fracs(a, b, a_sign, result, rounding_mode); - } else { - xfp_sub_fracs(a, b, a_sign, result, rounding_mode); - } -} - -static void xfp_sub(XFP *a, XFP *b, XFP *result, RM rounding_mode) -{ - uint32 a_sign, b_sign; - - a_sign = XFP_SIGN(a); - b_sign = XFP_SIGN(b); - - if (a_sign == b_sign) { - xfp_sub_fracs(a, b, a_sign, result, rounding_mode); - } else { - xfp_add_fracs(a, b, a_sign, result, rounding_mode); - } -} - -/* - * Derived from the SoftFloat 2c package (see copyright notice above) - */ -static void xfp_mul(XFP *a, XFP *b, XFP *result, RM rounding_mode) -{ - uint32 a_sign, b_sign, r_sign; - int32 a_exp, b_exp, r_exp; - t_uint64 a_frac, b_frac, r_frac_0, r_frac_1; - - sim_debug(TRACE_DBG, &mau_dev, - "[%08x] [MUL] op1=%04x%016llx op2=%04x%016llx\n", - R[NUM_PC], - a->sign_exp, a->frac, - b->sign_exp, b->frac); - - a_sign = XFP_SIGN(a); - a_exp = XFP_EXP(a); - a_frac = XFP_FRAC(a); - b_sign = XFP_SIGN(b); - b_exp = XFP_EXP(b); - b_frac = XFP_FRAC(b); - - r_sign = a_sign ^ b_sign; - - if (a_exp == 0x7fff) { - if ((t_uint64)(a_frac << 1) || ((b_exp == 0x7fff) && (t_uint64)(b_frac << 1))) { - propagate_xfp_nan(a, b, result); - return; - } - if ((b_exp | b_frac) == 0) { - /* invalid */ - mau_exc(MAU_ASR_IS, MAU_ASR_IM); - result->sign_exp = DEFAULT_XFP_NAN_SIGN_EXP; - result->frac = DEFAULT_XFP_NAN_FRAC; - return; - } - PACK_XFP(r_sign, 0x7fff, 0x8000000000000000ull, result); - return; - } - - if (b_exp == 0x7fff) { - if ((t_uint64)(b_frac << 1)) { - propagate_xfp_nan(a, b, result); - return; - } - if ((a_exp | a_frac) == 0) { - /* invalid */ - mau_exc(MAU_ASR_IS, MAU_ASR_IM); - result->sign_exp = DEFAULT_XFP_NAN_SIGN_EXP; - result->frac = DEFAULT_XFP_NAN_FRAC; - return; - } - PACK_XFP(r_sign, 0x7fff, 0x8000000000000000ull, result); - return; - } - - if (a_exp == 0) { - if (a_frac == 0) { - PACK_XFP(r_sign, 0, 0, result); - return; - } - normalize_xfp_subnormal(a_frac, &a_exp, &a_frac); - } - - if (b_exp == 0) { - if (b_frac == 0) { - PACK_XFP(r_sign, 0, 0, result); - return; - } - normalize_xfp_subnormal(b_frac, &b_exp, &b_frac); - } - - r_exp = a_exp + b_exp - 0x3ffe; - mul_64_to_128(a_frac, b_frac, &r_frac_0, &r_frac_1); - if (0 < (t_int64)r_frac_0) { - short_shift_left_128(r_frac_0, r_frac_1, 1, - &r_frac_0, &r_frac_1); - --r_exp; - } - - round_pack_xfp(r_sign, r_exp, r_frac_0, - r_frac_1, rounding_mode, result); -} - -/* - * Derived from the SoftFloat 2c package (see copyright notice above) - */ -static void xfp_div(XFP *a, XFP *b, XFP *result, RM rounding_mode) -{ - t_bool a_sign, b_sign, r_sign; - int32 a_exp, b_exp, r_exp; - t_uint64 a_frac, b_frac, r_frac0, r_frac1; - t_uint64 rem0, rem1, rem2, term0, term1, term2; - - sim_debug(TRACE_DBG, &mau_dev, - "[%08x] [DIV] op1=%04x%016llx op2=%04x%016llx\n", - R[NUM_PC], b->sign_exp, b->frac, a->sign_exp, a->frac); - - a_sign = XFP_SIGN(a); - a_exp = XFP_EXP(a); - a_frac = XFP_FRAC(a); - - b_sign = XFP_SIGN(b); - b_exp = XFP_EXP(b); - b_frac = XFP_FRAC(b); - - r_sign = a_sign ^ b_sign; - - if (a_exp == 0x7fff) { - if ((t_uint64)(a_frac << 1)) { - propagate_xfp_nan(a, b, result); - return; - } - - if (b_exp == 0x7fff) { - if ((t_uint64)(b_frac << 1)) { - propagate_xfp_nan(a, b, result); - return; - } - /* Invalid */ - mau_exc(MAU_ASR_IS, MAU_ASR_IM); - result->sign_exp = DEFAULT_XFP_NAN_SIGN_EXP; - result->frac = DEFAULT_XFP_NAN_FRAC; - return; - } - - PACK_XFP(r_sign, 0x7fff, 0x8000000000000000ull, result); - return; - } - - if (b_exp == 0x7fff) { - if ((t_uint64) (b_frac << 1)) { - propagate_xfp_nan(a, b, result); - return; - } - - PACK_XFP(r_sign, 0, 0, result); - return; - } - - if (b_exp == 0) { - if (b_frac == 0) { - if ((a_exp | b_frac) == 0) { - /* Invalid */ - mau_exc(MAU_ASR_IS, MAU_ASR_IM); - result->sign_exp = DEFAULT_XFP_NAN_SIGN_EXP; - result->frac = DEFAULT_XFP_NAN_FRAC; - return; - } - /* Divide by zero - SPECIAL CASE 4 */ - sim_debug(TRACE_DBG, &mau_dev, - "[%08x] [DIV] Divide by zero detected.\n", R[NUM_PC]); - mau_case_div_zero(a, b, result); - return; - } - normalize_xfp_subnormal(b_frac, &b_exp, &b_frac); - } - - if (a_exp == 0) { - if (a_frac == 0) { - PACK_XFP(r_sign, 0, 0, result); - return; - } - normalize_xfp_subnormal(a_frac, &a_exp, &a_frac); - } - - r_exp = a_exp - b_exp + 0x3ffe; - rem1 = 0; - if (b_frac <= a_frac) { - shift_right_128(a_frac, 0, 1, &a_frac, &rem1); - ++r_exp; - } - - r_frac0 = estimate_div_128_to_64(a_frac, rem1, b_frac); - mul_64_to_128(b_frac, r_frac0, &term0, &term1); - sub_128(a_frac, rem1, term0, term1, &rem0, &rem1); - - while ((t_int64) rem0 < 0) { - --r_frac0; - add_128(rem0, rem1, 0, b_frac, &rem0, &rem1); - } - - r_frac1 = estimate_div_128_to_64(rem1, 0, b_frac); - if ((t_uint64)(r_frac1 << 1) <= 8) { - mul_64_to_128(b_frac, r_frac1, &term1, &term2); - sub_128(rem1, 0, term1, term2, &rem1, &rem2); - while ((t_int64) rem1 < 0) { - --r_frac1; - add_128(rem1, rem2, 0, b_frac, &rem1, &rem2); - } - r_frac1 |= ((rem1 | rem2) != 0); - } - - round_pack_xfp(r_sign, r_exp, r_frac0, r_frac1, rounding_mode, result); -} - -/* - * Derived from the SoftFloat 2c package (see copyright notice above) - */ -static void xfp_sqrt(XFP *a, XFP *result, RM rounding_mode) -{ - XFP zero = {0, 0, 0}; - t_bool a_sign; - int32 a_exp, norm_exp, r_exp; - uint32 a_frac_32, sqrt_recip_32, r_frac_32; - t_uint64 a_frac, norm_frac, q, x64, z_frac, z_frac_extra; - t_mau_128 nan_128, rem, y, term; - - sim_debug(TRACE_DBG, &mau_dev, - "[%08x] [SQRT] op1=%04x%016llx\n", - R[NUM_PC], a->sign_exp, a->frac); - - a_sign = XFP_SIGN(a); - a_exp = XFP_EXP(a); - a_frac = XFP_FRAC(a); - - if (a_exp == 0x7fff) { - if ( a_frac & 0x7fffffffffffffffull ) { - propagate_xfp_nan_128(a, &zero, &nan_128); - result->sign_exp = (uint32) nan_128.high; - result->frac = nan_128.low; - return; - } - if ( ! a_sign ) { - result->sign_exp = a->sign_exp; - result->frac = a->frac; - } - /* Invalid */ - mau_exc(MAU_ASR_IS, MAU_ASR_IM); - result->sign_exp = DEFAULT_XFP_NAN_SIGN_EXP; - result->frac = DEFAULT_XFP_NAN_FRAC; - return; - } - - if (a_sign) { - if (!a_frac) { - PACK_XFP(a_sign, 0, 0, result); - return; - } - mau_exc(MAU_ASR_IS, MAU_ASR_IM); - result->sign_exp = DEFAULT_XFP_NAN_SIGN_EXP; - result->frac = DEFAULT_XFP_NAN_FRAC; - return; - } - - if (!a_exp) { - a_exp = 1; - } - - if (!(a_frac & 0x8000000000000000ull)) { - if (!a_frac) { - PACK_XFP(a_sign, 0, 0, result); - return; - } - normalize_xfp_subnormal(a->frac, &norm_exp, &norm_frac); - a_exp += norm_exp; - a_frac = norm_frac; - } - - /* - * r_frac_32 is guaranteed to be a lower bound on the square root of - * a_frac_32, which makes r_frac_32 also a lower bound on the square - * root of `a_frac'. - */ - r_exp = ((a_exp - 0x3FFF) >> 1) + 0x3FFF; - a_exp &= 1; - a_frac_32 = a_frac >> 32; - sqrt_recip_32 = approx_recip_sqrt_32(a_exp, a_frac_32); - r_frac_32 = ((t_uint64) a_frac_32 * sqrt_recip_32) >> 32; - - if (a_exp) { - r_frac_32 >>= 1; - short_shift_left_128(0, a_frac, 61, &rem.high, &rem.low); - } else { - short_shift_left_128(0, a_frac, 62, &rem.high, &rem.low); - } - - rem.high -= (t_uint64) r_frac_32 * r_frac_32; - - q = ((uint32) (rem.high >> 2) * (t_uint64) sqrt_recip_32) >> 32; - x64 = (t_uint64) r_frac_32 << 32; - z_frac = x64 + (q<<3); - short_shift_left_128(rem.high, rem.low, 29, &y.high, &y.low); - - /* Repeating this loop is a rare occurrence. */ - while(1) { - mul_64_by_shifted_32_to_128(x64 + z_frac, (uint32) q, &term); - sub_128(y.high, y.low, term.high, term.low, &rem.high, &rem.low); - if (!(rem.high & 0x8000000000000000ull)) { - break; - } - --q; - z_frac -= 1<<3; - } - - q = (((rem.high>>2) * sqrt_recip_32)>>32) + 2; - x64 = z_frac; - z_frac = (z_frac<<1) + (q>>25); - z_frac_extra = (t_uint64) (q<<39); - - if ( (q & 0xffffff) <= 2 ) { - q &= ~(t_uint64) 0xffff; - z_frac_extra = (t_uint64) (q<<39); - mul_64_by_shifted_32_to_128(x64 + (q >> 27), (uint32) q, &term); - x64 = (uint32) (q<<5) * (t_uint64) (uint32) q; - add_128(term.high, term.low, 0, x64, &term.high, &term.low); - short_shift_left_128(rem.high, rem.low, 28, &rem.high, &rem.low); - sub_128(rem.high, rem.low, term.high, term.low, &rem.high, &rem.low); - if (rem.high & 0x8000000000000000ull) { - if (!z_frac_extra ) { - --z_frac; - } - --z_frac_extra; - } else { - if (rem.high | rem.low) { - z_frac_extra |= 1; - } - } - } - - round_pack_xfp(0, r_exp, z_frac, z_frac_extra, rounding_mode,result); - return; -} - -static void xfp_remainder(XFP *a, XFP *b, XFP *result, RM rounding_mode) -{ - uint32 a_sign, r_sign; - int32 a_exp, b_exp, exp_diff; - t_uint64 a_frac_0, a_frac_1, b_frac; - t_uint64 q, term_0, term_1, alt_a_frac_0, alt_a_frac_1; - - a_sign = XFP_SIGN(a); - a_exp = XFP_EXP(a); - a_frac_0 = XFP_FRAC(a); - b_exp = XFP_EXP(b); - b_frac = XFP_FRAC(b); - - if (a_exp == 0x7fff) { - if ((t_uint64)(a_frac_0 << 1) || - ((b_exp == 0x7fff) && (t_uint64)(b_frac << 1))) { - propagate_xfp_nan(a, b, result); - return; - } - /* invalid */ - mau_exc(MAU_ASR_IS, MAU_ASR_IM); - result->sign_exp = DEFAULT_XFP_NAN_SIGN_EXP; - result->frac = DEFAULT_XFP_NAN_FRAC; - return; - } - - if (b_exp == 0x7fff) { - if ((t_uint64)(b_frac << 1)) { - propagate_xfp_nan(a, b, result); - } - result->sign_exp = a->sign_exp; - result->frac = a->frac; - return; - } - - if (b_exp == 0) { - if (b_frac == 0) { - /* invalid */ - mau_exc(MAU_ASR_IS, MAU_ASR_IM); - result->sign_exp = DEFAULT_XFP_NAN_SIGN_EXP; - result->frac = DEFAULT_XFP_NAN_FRAC; - return; - } - normalize_xfp_subnormal(b_frac, &b_exp, &b_frac); - } - - if (a_exp == 0) { - if ((t_uint64)(a_frac_0 << 1) == 0) { - result->sign_exp = a->sign_exp; - result->frac = a->frac; - return; - } - normalize_xfp_subnormal(a_frac_0, &a_exp, &a_frac_0); - } - - b_frac |= 0x8000000000000000ull; - r_sign = a_sign; - exp_diff = a_exp - b_exp; - a_frac_1 = 0; - if (exp_diff < 0) { - if (exp_diff < -1) { - result->sign_exp = a->sign_exp; - result->frac = a->frac; - return; - } - shift_right_128(a_frac_0, 0, 1, &a_frac_0, &a_frac_1); - exp_diff = 0; - } - - q = (b_frac <= a_frac_0); - - if (q) { - a_frac_0 -= b_frac; - } - - exp_diff -= 64; - - while (0 < exp_diff) { - q = estimate_div_128_to_64(a_frac_0, a_frac_1, b_frac); - q = (2 < q) ? q - 2 : 0; - mul_64_to_128(b_frac, q, &term_0, &term_1); - sub_128(a_frac_0, a_frac_1, term_0, term_1, &a_frac_0, &a_frac_1); - short_shift_left_128(a_frac_0, a_frac_1, 62, &a_frac_0, &a_frac_1); - exp_diff -= 62; - } - - exp_diff += 64; - - if (0 < exp_diff) { - q = estimate_div_128_to_64(a_frac_0, a_frac_1, b_frac); - q = (2 < q) ? q - 2 : 0; - q >>= 64 - exp_diff; - mul_64_to_128(b_frac, q << (64 - exp_diff), &term_0, &term_1); - sub_128(a_frac_0, a_frac_1, term_0, term_1, &a_frac_0, &a_frac_1); - short_shift_left_128(0, b_frac, 64 - exp_diff, &term_0, &term_1); - while (le_128(term_0, term_1, a_frac_0, a_frac_1)) { - ++q; - sub_128(a_frac_0, a_frac_1, term_0, term_1, &a_frac_0, &a_frac_1); - } - } else { - term_0 = b_frac; - term_1 = 0; - } - - sub_128(term_0, term_1, a_frac_0, a_frac_1, &alt_a_frac_0, &alt_a_frac_1); - - if (lt_128(alt_a_frac_0, alt_a_frac_1, a_frac_0, a_frac_1) || - (eq_128(alt_a_frac_0, alt_a_frac_1, a_frac_0, a_frac_1) && - (q & 1))) { - a_frac_0 = alt_a_frac_0; - a_frac_1 = alt_a_frac_1; - r_sign = r_sign ? 0 : 1; - } - - normalize_round_pack_xfp(r_sign, b_exp + exp_diff, - a_frac_0, a_frac_1, - rounding_mode, result); -} - -/* - * Load an extended precision 80-bit IEE-754 floating point value from - * memory or register, based on the operand's specification. - */ -static void load_src_op(uint8 op, XFP *xfp) -{ - DFP dfp; - SFP sfp; - - switch (op) { - case M_OP_F0: - xfp->sign_exp = mau_state.f0.sign_exp; - xfp->frac = mau_state.f0.frac; - break; - case M_OP_F1: - xfp->sign_exp = mau_state.f1.sign_exp; - xfp->frac = mau_state.f1.frac; - break; - case M_OP_F2: - xfp->sign_exp = mau_state.f2.sign_exp; - xfp->frac = mau_state.f2.frac; - break; - case M_OP_F3: - xfp->sign_exp = mau_state.f3.sign_exp; - xfp->frac = mau_state.f3.frac; - break; - case M_OP_MEM_SINGLE: - sfp = read_w(mau_state.src, ACC_AF); - sfp_to_xfp(sfp, xfp); - break; - case M_OP_MEM_DOUBLE: - dfp = (t_uint64) read_w(mau_state.src + 4, ACC_AF); - dfp |= ((t_uint64) read_w(mau_state.src, ACC_AF)) << 32; - sim_debug(TRACE_DBG, &mau_dev, - "[load_src_op][DOUBLE] Loaded %016llx\n", - dfp); - dfp_to_xfp(dfp, xfp); - sim_debug(TRACE_DBG, &mau_dev, - "[load_src_op][DOUBLE] Expanded To %04x%016llx\n", - xfp->sign_exp, xfp->frac); - break; - case M_OP_MEM_TRIPLE: - xfp->frac = (t_uint64) read_w(mau_state.src + 8, ACC_AF); - xfp->frac |= ((t_uint64) read_w(mau_state.src + 4, ACC_AF)) << 32; - xfp->sign_exp = (uint32) read_w(mau_state.src, ACC_AF); - break; - default: - break; - } -} - -/* - * Load OP1 as a DEC value. - */ -static void load_op1_decimal(DEC *d) -{ - uint32 low, mid, high; - - switch (mau_state.op1) { - case M_OP_MEM_TRIPLE: - low = read_w(mau_state.src + 8, ACC_AF); - mid = read_w(mau_state.src + 4, ACC_AF); - high = read_w(mau_state.src, ACC_AF); - d->l = low; - d->l |= ((t_uint64) mid << 32); - d->h = high; - break; - default: - /* Invalid */ - mau_exc(MAU_ASR_IS, MAU_ASR_IM); - break; - } -} - -static void store_op3_int(uint32 val) -{ - switch(mau_state.op3) { - case M_OP3_F0_SINGLE: - mau_state.f0.sign_exp = 0; - mau_state.f0.frac = (t_uint64)val; - break; - case M_OP3_F1_SINGLE: - mau_state.f1.sign_exp = 0; - mau_state.f1.frac = (t_uint64)val; - break; - case M_OP3_F2_SINGLE: - mau_state.f2.sign_exp = 0; - mau_state.f2.frac = (t_uint64)val; - break; - case M_OP3_F3_SINGLE: - mau_state.f3.sign_exp = 0; - mau_state.f3.frac = (t_uint64)val; - break; - case M_OP3_MEM_SINGLE: - write_w(mau_state.dst, val); - break; - default: - /* Indeterminate output, unsupported */ - break; - } - - mau_state.dr.sign_exp = 0; - mau_state.dr.frac = (t_uint64)val; -} - -static void store_op3_decimal(DEC *d) -{ - - switch(mau_state.op3) { - case M_OP3_MEM_TRIPLE: - write_w(mau_state.dst, d->h); - write_w(mau_state.dst + 4, (uint32)((t_uint64)d->l >> 32)); - write_w(mau_state.dst + 8, (uint32)d->l); - break; - default: - /* Unsupported */ - return; - } - - mau_state.dr.sign_exp = d->h; - mau_state.dr.frac = ((t_uint64)d->l >> 32) | (t_uint64)d->l; -} - -static void store_op3_reg(XFP *xfp, XFP *reg) -{ - DFP dfp; - SFP sfp; - XFP xfp_r; - - if (mau_state.ntnan) { - reg->sign_exp = GEN_NONTRAPPING_NAN.sign_exp; - reg->frac = GEN_NONTRAPPING_NAN.frac; - } else { - switch(mau_state.op3) { - case M_OP3_F0_SINGLE: - case M_OP3_F1_SINGLE: - case M_OP3_F2_SINGLE: - case M_OP3_F3_SINGLE: - sfp = xfp_to_sfp(xfp, MAU_RM); - sfp_to_xfp(sfp, &xfp_r); - reg->sign_exp = xfp_r.sign_exp; - reg->frac = xfp_r.frac; - reg->s = xfp_r.s; - break; - case M_OP3_F0_DOUBLE: - case M_OP3_F1_DOUBLE: - case M_OP3_F2_DOUBLE: - case M_OP3_F3_DOUBLE: - dfp = xfp_to_dfp(xfp, MAU_RM); - dfp_to_xfp(dfp, &xfp_r); - reg->sign_exp = xfp_r.sign_exp; - reg->frac = xfp_r.frac; - reg->s = xfp_r.s; - break; - case M_OP3_F0_TRIPLE: - case M_OP3_F1_TRIPLE: - case M_OP3_F2_TRIPLE: - case M_OP3_F3_TRIPLE: - reg->sign_exp = xfp->sign_exp; - reg->frac = xfp->frac; - reg->s = xfp->s; - break; - } - } - if (set_nz()) { - if (XFP_SIGN(xfp)) { - mau_state.asr |= MAU_ASR_N; - } - if (XFP_EXP(xfp) == 0 && XFP_FRAC(xfp) == 0) { - mau_state.asr |= MAU_ASR_Z; - } - } -} - -static void store_op3(XFP *xfp) -{ - DFP dfp; - SFP sfp; - t_bool store_dr = FALSE; - - sim_debug(TRACE_DBG, &mau_dev, - "[%08x] [store_op3] op3=%04x%016llx\n", - R[NUM_PC], - xfp->sign_exp, - xfp->frac); - - switch (mau_state.opcode) { - case M_ADD: - case M_SUB: - case M_MUL: - case M_DIV: - store_dr = TRUE; - break; - default: - break; - } - - switch (mau_state.op3) { - case M_OP3_F0_SINGLE: - case M_OP3_F0_DOUBLE: - case M_OP3_F0_TRIPLE: - store_op3_reg(xfp, &mau_state.f0); - break; - case M_OP3_F1_SINGLE: - case M_OP3_F1_DOUBLE: - case M_OP3_F1_TRIPLE: - store_op3_reg(xfp, &mau_state.f1); - break; - case M_OP3_F2_SINGLE: - case M_OP3_F2_DOUBLE: - case M_OP3_F2_TRIPLE: - store_op3_reg(xfp, &mau_state.f2); - break; - case M_OP3_F3_SINGLE: - case M_OP3_F3_DOUBLE: - case M_OP3_F3_TRIPLE: - store_op3_reg(xfp, &mau_state.f3); - break; - case M_OP3_MEM_SINGLE: - if (mau_state.ntnan) { - sfp = xfp_to_sfp(&GEN_NONTRAPPING_NAN, MAU_RM); - } else { - sfp = xfp_to_sfp(xfp, MAU_RM); - } - if (set_nz()) { - if (SFP_SIGN(sfp)) { - mau_state.asr |= MAU_ASR_N; - } - if (SFP_EXP(sfp) == 0 && SFP_FRAC(sfp) == 0) { - mau_state.asr |= MAU_ASR_Z; - } - } - write_w(mau_state.dst, (uint32)sfp); - break; - case M_OP3_MEM_DOUBLE: - if (mau_state.ntnan) { - dfp = xfp_to_dfp(&GEN_NONTRAPPING_NAN, MAU_RM); - } else { - dfp = xfp_to_dfp(xfp, MAU_RM); - } - if (store_dr) { - mau_state.dr.sign_exp = ((uint16)(DFP_SIGN(dfp)) << 15) | (uint16)(DFP_EXP(dfp)); - mau_state.dr.frac = (t_uint64)(DFP_FRAC(dfp)); - if (DFP_EXP(dfp)) { - /* If the number is normalized, add the implicit - normalized bit 52 */ - mau_state.dr.frac |= ((t_uint64)1 << 52); - } - } - if (set_nz()) { - if (DFP_SIGN(dfp)) { - mau_state.asr |= MAU_ASR_N; - } - if (DFP_EXP(dfp) == 0 && DFP_FRAC(dfp) == 0) { - mau_state.asr |= MAU_ASR_Z; - } - } - write_w(mau_state.dst, (uint32)(dfp >> 32)); - write_w(mau_state.dst + 4, (uint32)(dfp)); - break; - case M_OP3_MEM_TRIPLE: - if (mau_state.ntnan) { - write_w(mau_state.dst, (uint32)(GEN_NONTRAPPING_NAN.sign_exp)); - write_w(mau_state.dst + 4, (uint32)(GEN_NONTRAPPING_NAN.frac >> 32)); - write_w(mau_state.dst + 8, (uint32)(GEN_NONTRAPPING_NAN.frac)); - } else { - write_w(mau_state.dst, (uint32)(xfp->sign_exp)); - write_w(mau_state.dst + 4, (uint32)(xfp->frac >> 32)); - write_w(mau_state.dst + 8, (uint32)(xfp->frac)); - } - if (set_nz()) { - if (XFP_SIGN(xfp)) { - mau_state.asr |= MAU_ASR_N; - } - if (XFP_EXP(xfp) == 0 && XFP_FRAC(xfp) == 0) { - mau_state.asr |= MAU_ASR_Z; - } - } - break; - default: - sim_debug(TRACE_DBG, &mau_dev, - "[store_op3] WARNING: Unhandled destination: %02x\n", mau_state.op3); - break; - } -} - -/************************************************************************* - * - * MAU instruction impelementations - * - *************************************************************************/ - -static void mau_rdasr() -{ - switch (mau_state.op3) { - /* Handled */ - case M_OP3_MEM_SINGLE: - write_w(mau_state.dst, mau_state.asr); - break; - case M_OP3_MEM_DOUBLE: - write_w(mau_state.dst, mau_state.asr); - write_w(mau_state.dst + 4, mau_state.asr); - break; - case M_OP3_MEM_TRIPLE: - write_w(mau_state.dst, mau_state.asr); - write_w(mau_state.dst + 4, mau_state.asr); - write_w(mau_state.dst + 8, mau_state.asr); - break; - /* Unhandled */ - default: - sim_debug(TRACE_DBG, &mau_dev, - "[%08x] [mau_rdasr] WARNING: Unhandled source: %02x\n", - R[NUM_PC], mau_state.op3); - break; - } -} - -static void mau_wrasr() -{ - switch (mau_state.op1) { - /* Handled */ - case M_OP_MEM_SINGLE: - mau_state.asr = read_w(mau_state.src, ACC_AF); - sim_debug(TRACE_DBG, &mau_dev, - "[%08x] [WRASR] Writing ASR with: %08x\n", - R[NUM_PC], mau_state.asr); - break; - default: - sim_debug(TRACE_DBG, &mau_dev, - "[%08x] [mau_wrasr] WARNING: Unhandled source: %02x\n", - R[NUM_PC], - mau_state.op3); - break; - } -} - -/* - * OP3 = OP1 - */ -static void mau_move() -{ - XFP xfp = {0}; - - load_src_op(mau_state.op1, &xfp); - store_op3(&xfp); -} - -static void mau_cmp() -{ - XFP a, b; - - load_src_op(mau_state.op1, &a); - load_src_op(mau_state.op2, &b); - xfp_cmp(&a, &b); -} - -static void mau_cmps() -{ - XFP a, b; - - load_src_op(mau_state.op1, &a); - load_src_op(mau_state.op2, &b); - xfp_cmps(&a, &b); -} - -static void mau_cmpe() -{ - XFP a, b; - - load_src_op(mau_state.op1, &a); - load_src_op(mau_state.op2, &b); - xfp_cmpe(&a, &b); -} - -static void mau_cmpes() -{ - XFP a, b; - - load_src_op(mau_state.op1, &a); - load_src_op(mau_state.op2, &b); - xfp_cmpes(&a, &b); -} - -static void mau_ldr() -{ - XFP xfp; - - load_src_op(mau_state.op1, &xfp); - sim_debug(TRACE_DBG, &mau_dev, - "[%08x] [LDR] Loading DR with %04x%016llx\n", - R[NUM_PC], xfp.sign_exp, xfp.frac); - mau_state.dr.sign_exp = xfp.sign_exp; - mau_state.dr.frac = xfp.frac; -} - -static void mau_erof() -{ - DFP dfp; - SFP sfp; - - switch (mau_state.op3) { - case M_OP3_F0_SINGLE: - case M_OP3_F0_DOUBLE: - case M_OP3_F0_TRIPLE: - mau_state.f0.sign_exp = mau_state.dr.sign_exp; - mau_state.f0.frac = mau_state.dr.frac; - return; - case M_OP3_F1_SINGLE: - case M_OP3_F1_DOUBLE: - case M_OP3_F1_TRIPLE: - mau_state.f1.sign_exp = mau_state.dr.sign_exp; - mau_state.f1.frac = mau_state.dr.frac; - return; - case M_OP3_F2_SINGLE: - case M_OP3_F2_DOUBLE: - case M_OP3_F2_TRIPLE: - mau_state.f2.sign_exp = mau_state.dr.sign_exp; - mau_state.f2.frac = mau_state.dr.frac; - return; - case M_OP3_F3_SINGLE: - case M_OP3_F3_DOUBLE: - case M_OP3_F3_TRIPLE: - mau_state.f3.sign_exp = mau_state.dr.sign_exp; - mau_state.f3.frac = mau_state.dr.frac; - return; - case M_OP3_MEM_SINGLE: - sfp = xfp_to_sfp(&(mau_state.dr), MAU_RM); - write_w(mau_state.dst, (uint32)sfp); - return; - case M_OP3_MEM_DOUBLE: - dfp = xfp_to_dfp(&(mau_state.dr), MAU_RM); - write_w(mau_state.dst + 4, (uint32)(dfp >> 32)); - write_w(mau_state.dst, (uint32)(dfp)); - return; - case M_OP3_MEM_TRIPLE: - write_w(mau_state.dst, (uint32)(mau_state.dr.sign_exp)); - write_w(mau_state.dst + 4, (uint32)(mau_state.dr.frac >> 32)); - write_w(mau_state.dst + 8, (uint32)(mau_state.dr.frac)); - return; - default: - sim_debug(TRACE_DBG, &mau_dev, - "[mau_erof] WARNING: Unhandled destination: %02x\n", mau_state.op3); - return; - } -} - - -static void mau_rtoi() -{ - XFP a, result; - - load_src_op(mau_state.op1, &a); - mau_round_xfp_to_int(&a, &result, MAU_RM); - store_op3(&result); -} - -static void mau_ftoi() -{ - XFP a; - uint32 result; - - load_src_op(mau_state.op1, &a); - result = xfp_to_int(&a, MAU_RM); - store_op3_int(result); -} - -static void mau_dtof() -{ - DEC d; - XFP result; - - load_op1_decimal(&d); - mau_decimal_to_xfp(&d, &result); - store_op3(&result); -} - -static void mau_ftod() -{ - XFP a; - DEC d; - - load_src_op(mau_state.op1, &a); - xfp_to_decimal(&a, &d, MAU_RM); - store_op3_decimal(&d); -} - -static void mau_add() -{ - XFP a, b, result; - - load_src_op(mau_state.op1, &a); - load_src_op(mau_state.op2, &b); - xfp_add(&a, &b, &result, MAU_RM); - store_op3(&result); -} - -/* - * OP3 = OP2 - OP1 - */ -static void mau_sub() -{ - XFP a, b, result; - - load_src_op(mau_state.op1, &a); - load_src_op(mau_state.op2, &b); - xfp_sub(&b, &a, &result, MAU_RM); - store_op3(&result); -} - -/* - * OP3 = OP1 * OP2 - */ -static void mau_mul() -{ - XFP a, b, result; - - load_src_op(mau_state.op1, &a); - load_src_op(mau_state.op2, &b); - xfp_mul(&b, &a, &result, MAU_RM); - store_op3(&result); -} - -/* - * OP3 = OP1 / OP2 - */ -static void mau_div() -{ - XFP a, b, result; - - load_src_op(mau_state.op1, &a); - load_src_op(mau_state.op2, &b); - sim_debug(TRACE_DBG, &mau_dev, - "[%08x] [DIV OP2/OP1] OP2=0x%04x%016llx OP1=0x%04x%016llx\n", - R[NUM_PC], - b.sign_exp, b.frac, - a.sign_exp, a.frac); - xfp_div(&b, &a, &result, MAU_RM); - store_op3(&result); -} - -static void mau_neg() -{ - XFP a, result; - - load_src_op(mau_state.op1, &a); - result.sign_exp = a.sign_exp; - result.frac = a.frac; - result.sign_exp ^= 0x8000; - result.s = a.s; - store_op3(&result); -} - -static void mau_abs() -{ - XFP a, result; - - load_src_op(mau_state.op1, &a); - result.sign_exp = a.sign_exp; - result.frac = a.frac; - result.sign_exp &= 0x7fff; - result.s = a.s; - store_op3(&result); -} - -/* - * OP3 = sqrt(OP1) - */ -static void mau_sqrt() -{ - XFP a, result; - - load_src_op(mau_state.op1, &a); - xfp_sqrt(&a, &result, MAU_RM); - store_op3(&result); -} - -/* - * OP3 = float(OP1) - * - * If the source operand is more than one word wide, only the last - * word is converted. - */ -static void mau_itof() -{ - XFP xfp; - int32 val = 0; - - mau_state.asr &= ~(MAU_ASR_N|MAU_ASR_Z); - - switch(mau_state.op1) { - case M_OP_F0: - case M_OP_F1: - case M_OP_F2: - case M_OP_F3: - mau_exc(MAU_ASR_IS, MAU_ASR_IM); - return; - case M_OP_MEM_SINGLE: - val = read_w(mau_state.src, ACC_AF); - break; - case M_OP_MEM_DOUBLE: - val = read_w(mau_state.src + 4, ACC_AF); - break; - case M_OP_MEM_TRIPLE: - val = read_w(mau_state.src + 8, ACC_AF); - break; - default: - break; - } - /* Convert */ - mau_int_to_xfp(val, &xfp); - - store_op3(&xfp); -} - -/* - * OP3 = REMAINDER(b/a) - */ -static void mau_remainder() -{ - XFP a, b, result; - - load_src_op(mau_state.op1, &a); - load_src_op(mau_state.op2, &b); - xfp_remainder(&b, &a, &result, MAU_RM); - store_op3(&result); -} - -/* - * Decode the command word into its corresponding parts. Both src and - * dst are optional depending on the WE32100 operand, and may be set - * to any value if not used. - */ -static SIM_INLINE void mau_decode(uint32 cmd, uint32 src, uint32 dst) -{ - mau_state.cmd = cmd; - mau_state.src = src; - mau_state.dst = dst; - mau_state.opcode = (uint8) ((cmd & 0x7c00) >> 10); - mau_state.op1 = (uint8) ((cmd & 0x0380) >> 7); - mau_state.op2 = (uint8) ((cmd & 0x0070) >> 4); - mau_state.op3 = (uint8) (cmd & 0x000f); - sim_debug(DECODE_DBG, &mau_dev, - "opcode=%s (%02x) op1=%s op2=%s op3=%s\n", - mau_op_names[mau_state.opcode], - mau_state.opcode, - src_op_names[mau_state.op1 & 0x7], - src_op_names[mau_state.op2 & 0x7], - dst_op_names[mau_state.op3 & 0xf]); -} - -/* - * Handle a command. - */ -static void mau_execute() -{ - clear_asr(); - - switch(mau_state.opcode) { - case M_NOP: - /* Do nothing */ - break; - case M_ADD: - mau_add(); - break; - case M_SUB: - mau_sub(); - break; - case M_MUL: - mau_mul(); - break; - case M_DIV: - mau_div(); - break; - case M_RDASR: - mau_rdasr(); - break; - case M_WRASR: - mau_wrasr(); - break; - case M_MOVE: - mau_move(); - break; - case M_LDR: - mau_ldr(); - break; - case M_ITOF: - mau_itof(); - break; - case M_EROF: - mau_erof(); - break; - case M_RTOI: - mau_rtoi(); - break; - case M_FTOI: - mau_ftoi(); - break; - case M_CMP: - mau_cmp(); - break; - case M_CMPS: - mau_cmps(); - break; - case M_CMPE: - mau_cmpe(); - break; - case M_CMPES: - mau_cmpes(); - break; - case M_REM: - mau_remainder(); - break; - case M_NEG: - mau_neg(); - break; - case M_ABS: - mau_abs(); - break; - case M_SQRT: - mau_sqrt(); - break; - case M_FTOD: - mau_ftod(); - break; - case M_DTOF: - mau_dtof(); - break; - default: - sim_debug(TRACE_DBG, &mau_dev, - "[execute] unhandled opcode %s [0x%02x]\n", - mau_op_names[mau_state.opcode], - mau_state.opcode); - break; - } - - /* If an error has occured, abort */ - abort_on_fault(); - - /* Copy the N, Z, V and C (from PS) flags over to the CPU's PSW */ - R[NUM_PSW] &= ~(MAU_ASR_N|MAU_ASR_Z|MAU_ASR_IO|MAU_ASR_PS); - R[NUM_PSW] |= (mau_state.asr & (MAU_ASR_N|MAU_ASR_Z|MAU_ASR_IO|MAU_ASR_PS)); - - /* Set the RA and CSC flags in the ASR */ - mau_state.asr |= MAU_ASR_RA; - if (mau_state.opcode != M_RDASR && mau_state.opcode != M_LDR) { - mau_state.asr |= MAU_ASR_CSC; - } -} - -/* - * Receive a broadcast from the CPU, and potentially handle it. - */ -t_stat mau_broadcast(uint32 cmd, uint32 src, uint32 dst) -{ - uint8 id = (uint8) ((cmd & 0xff000000) >> 24); - - /* If the MAU isn't attached, or if this message isn't for us, - * return SCPE_NXM. Otherwise, decode and act on the command. */ - if (id != MAU_ID) { - sim_debug(DECODE_DBG, &mau_dev, - "[broadcast] Message for coprocessor id %d is not for MAU (%d)\n", - id, MAU_ID); - return SCPE_NXM; - } else if (mau_dev.flags & DEV_DIS) { - sim_debug(DECODE_DBG, &mau_dev, - "[broadcast] Message for MAU, but MAU is not attached.\n"); - return SCPE_NOATT; - } else { - mau_decode(cmd, src, dst); - mau_execute(); - return SCPE_OK; - } -} - -CONST char *mau_description(DEVICE *dptr) -{ - return "WE32106"; -} +/* 3b2_mau.c: WE32106 and WE32206 Math Accelerator Unit + + Copyright (c) 2021-2022, Seth J. Morabito + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + Except as contained in this notice, the name of the author shall + not be used in advertising or otherwise to promote the sale, use or + other dealings in this Software without prior written authorization + from the author. + + --------------------------------------------------------------------- + + This file is part of a simulation of the WE 32106 and WE 32206 Math + Acceleration Units. The WE 32106 and WE 32206 are IEEE-754 + compabitle floating point hardware math accelerators that were + available as an optional component on the AT&T 3B2/310 and 3B2/400, + and as a standard component on the 3B2/500, 3B2/600, 3B2/700, and + 3B2/1000. + + Unimplemented Features + ====================== + + All features of the WE 32106 MAU have been implemented, but there + remain some features of the WE 32206 that are not yet implemented. + Neither System V UNIX nor the Version 3 MAU diagnostics appear to + use these features in any way, but there is no guarantee that other + software does not use them. They are: + + - The FE, UW, and WF bits of the Auxiliary Status Register + - The new operand registers f4 through f7 + - The register bank select feature of the Command Register + - The RC and RCS bits of the Command Register + - The new WE 32206 instructions: + 1. ATAN + 2. COS + 3. PI + 4. SIN + + --------------------------------------------------------------------- + + Portions of this code are derived from the SoftFloat 2c library by + John R. Hauser. Functions derived from SoftFloat 2c are clearly + marked in the comments. + + Legal Notice + ============ + + SoftFloat was written by John R. Hauser. Release 2c of SoftFloat + was made possible in part by the International Computer Science + Institute, located at Suite 600, 1947 Center Street, Berkeley, + California 94704. Funding was partially provided by the National + Science Foundation under grant MIP-9311980. The original version + of this code was written as part of a project to build a + fixed-point vector processor in collaboration with the University + of California at Berkeley, overseen by Profs. Nelson Morgan and + John Wawrzynek. + + THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable + effort has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS + THAT WILL AT TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS + SOFTWARE IS RESTRICTED TO PERSONS AND ORGANIZATIONS WHO CAN AND + WILL TOLERATE ALL LOSSES, COSTS, OR OTHER PROBLEMS THEY INCUR DUE + TO THE SOFTWARE WITHOUT RECOMPENSE FROM JOHN HAUSER OR THE + INTERNATIONAL COMPUTER SCIENCE INSTITUTE, AND WHO FURTHERMORE + EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER + SCIENCE INSTITUTE (possibly via similar legal notice) AGAINST ALL + LOSSES, COSTS, OR OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND + CLIENTS DUE TO THE SOFTWARE, OR INCURRED BY ANYONE DUE TO A + DERIVATIVE WORK THEY CREATE USING ANY PART OF THE SOFTWARE. + + The following are expressly permitted, even for commercial + purposes: + + (1) distribution of SoftFloat in whole or in part, as long as this + and other legal notices remain and are prominent, and provided also + that, for a partial distribution, prominent notice is given that it + is a subset of the original; and + + (2) inclusion or use of SoftFloat in whole or in part in a + derivative work, provided that the use restrictions above are met + and the minimal documentation requirements stated in the source + code are satisfied. + --------------------------------------------------------------------- +*/ + +#include "3b2_mau.h" + +#include + +#include "3b2_cpu.h" +#include "3b2_mem.h" +#include "3b2_mmu.h" + +#define MAU_ID 0 /* Coprocessor ID of MAU */ + +#define TININESS_BEFORE_ROUNDING TRUE + +/* Static function declarations */ +static SIM_INLINE void mau_case_div_zero(XFP *op1, XFP *op2, XFP *result); + +static SIM_INLINE void mau_exc(uint32 flag, uint32 mask); +static SIM_INLINE void abort_on_fault(); +static SIM_INLINE void mau_decode(uint32 cmd, uint32 src, uint32 dst); +static SIM_INLINE t_bool le_128(t_uint64 a0, t_uint64 a1, t_uint64 b0, t_uint64 b1); +static SIM_INLINE t_bool eq_128(t_uint64 a0, t_uint64 a1, t_uint64 b0, t_uint64 b1); +static SIM_INLINE t_bool lt_128(t_uint64 a0, t_uint64 a1, t_uint64 b0, t_uint64 b1); +static uint8 leading_zeros(uint32 val); +static uint8 leading_zeros_64(t_int64 val); +static void shift_right_32_jamming(uint32 val, int16 count, uint32 *result); +static void shift_right_64_jamming(t_uint64 val, int16 count, t_uint64 *result); +static void shift_right_extra_64_jamming(t_uint64 val_a, t_uint64 val_b, int16 count, + t_uint64 *r_a, t_uint64 *r_b); +static void shift_right_128_jamming(t_uint64 val_a, t_uint64 val_b, int16 count, + t_uint64 *r_a, t_uint64 *r_b); +static void short_shift_left_128(t_uint64 val_a, t_uint64 val_b, int16 count, + t_uint64 *r_a, t_uint64 *r_b); +static void shift_right_128(t_uint64 val_a, t_uint64 val_b, int16 count, + t_uint64 *r_a, t_uint64 *r_b); +static void add_128(t_uint64 a0, t_uint64 a1, + t_uint64 b0, t_uint64 b1, + t_uint64 *r_low, t_uint64 *r_high); +static void sub_128(t_uint64 a0, t_uint64 a1, + t_uint64 b0, t_uint64 b1, + t_uint64 *r_low, t_uint64 *r_high); +static void mul_64_to_128(t_uint64 a, t_uint64 b, t_uint64 *r_low, t_uint64 *r_high); +static void mul_64_by_shifted_32_to_128(t_uint64 a, uint32 b, t_mau_128 *result); +static t_uint64 estimate_div_128_to_64(t_uint64 a0, t_uint64 a1, t_uint64 b); +static uint32 round_pack_int(t_bool sign, t_uint64 frac, RM rounding_mode); +static t_int64 round_pack_int64(t_bool sign, + t_uint64 abs_0, t_uint64 abs_1, + RM rounding_mode); + +static SFP round_pack_sfp(t_bool sign, int16 exp, + uint32 frac, RM rounding_mode); +static DFP round_pack_dfp(t_bool sign, int16 exp, t_uint64 frac, + t_bool xfp_sticky, RM rounding_mode); +static void round_pack_xfp(t_bool sign, int32 exp, + t_uint64 frac_a, t_uint64 frac_b, + RM rounding_mode, XFP *result); +static void propagate_xfp_nan(XFP *a, XFP *b, XFP *result); +static void propagate_xfp_nan_128(XFP* a, XFP* b, t_mau_128* result); +static void normalize_round_pack_xfp(t_bool sign, int32 exp, + t_uint64 frac_0, t_uint64 frac_1, + RM rounding_mode, XFP *result); +static void normalize_sfp_subnormal(uint32 in_frac, int16 *out_exp, uint32 *out_frac); +static void normalize_dfp_subnormal(t_uint64 in_frac, int16 *out_exp, t_uint64 *out_frac); +static void normalize_xfp_subnormal(t_uint64 in_frac, int32 *out_exp, t_uint64 *out_frac); + +static T_NAN sfp_to_common_nan(SFP val); +static T_NAN dfp_to_common_nan(DFP val); +static T_NAN xfp_to_common_nan(XFP *val); +static SFP common_nan_to_sfp(T_NAN nan); +static DFP common_nan_to_dfp(T_NAN nan); +static void common_nan_to_xfp(T_NAN nan, XFP *result); + +static void sfp_to_xfp(SFP val, XFP *result); +static void dfp_to_xfp(DFP val, XFP *result); +static SFP xfp_to_sfp(XFP *val, RM rounding_mode); +static DFP xfp_to_dfp(XFP *val, RM rounding_mode); + +static uint32 xfp_eq(XFP *a, XFP *b); +static uint32 xfp_lt(XFP *a, XFP *b); + +static void xfp_cmp(XFP *a, XFP *b); +static void xfp_cmpe(XFP *a, XFP *b); +static void xfp_cmps(XFP *a, XFP *b); +static void xfp_cmpes(XFP *a, XFP *b); +static void xfp_add(XFP *a, XFP *b, XFP *result, RM rounding_mode); +static void xfp_sub(XFP *a, XFP *b, XFP *result, RM rounding_mode); +static void xfp_mul(XFP *a, XFP *b, XFP *result, RM rounding_mode); +static void xfp_div(XFP *a, XFP *b, XFP *result, RM rounding_mode); +static void xfp_sqrt(XFP *a, XFP *result, RM rounding_mode); +static void xfp_remainder(XFP *a, XFP *b, XFP *result, RM rounding_mode); + +static void load_src_op(uint8 op, XFP *xfp); +static void load_op1_decimal(DEC *d); +static void store_op3_int(uint32 val); +static void store_op3_decimal(DEC *d); +static void store_op3(XFP *xfp); + +static void mau_rdasr(); +static void mau_wrasr(); +static void mau_move(); +static void mau_cmp(); +static void mau_cmps(); +static void mau_cmpe(); +static void mau_cmpes(); +static void mau_ldr(); +static void mau_erof(); +static void mau_rtoi(); +static void mau_ftoi(); +static void mau_dtof(); +static void mau_ftod(); +static void mau_add(); +static void mau_sub(); +static void mau_mul(); +static void mau_div(); +static void mau_neg(); +static void mau_abs(); +static void mau_sqrt(); +static void mau_itof(); +static void mau_remainder(); + +static void mau_execute(); + +UNIT mau_unit = { UDATA(NULL, 0, 0) }; + +MAU_STATE mau_state; + +BITFIELD asr_bits[] = { +#if defined(REV3) + BIT(FE), + BITFFMT(VER,3,%d), + BIT(UW), +#else + BITNCF(5), +#endif + BIT(PR), + BIT(QS), + BIT(US), + BIT(OS), + BIT(IS), + BIT(PM), + BIT(QM), + BIT(UM), + BIT(OM), + BIT(IM), +#if defined(REV3) + BIT(WF), +#else + BITNCF(1), +#endif + BIT(UO), + BIT(CSC), + BIT(PS), + BIT(IO), + BIT(Z), + BIT(N), + BITFFMT(RC,2,%d), + BIT(NTNC), + BIT(ECP), + BITNCF(5), + BIT(RA), + ENDBITS +}; + +REG mau_reg[] = { + { HRDATAD (CMD, mau_state.cmd, 32, "Command Word") }, + { HRDATADF (ASR, mau_state.asr, 32, "ASR", asr_bits) }, + { HRDATAD (OPCODE, mau_state.opcode, 8, "Opcode") }, + { HRDATAD (OP1, mau_state.op1, 8, "Operand 1") }, + { HRDATAD (OP2, mau_state.op2, 8, "Operand 2") }, + { HRDATAD (OP3, mau_state.op3, 8, "Operand 3") }, + { NULL } +}; + +MTAB mau_mod[] = { + { UNIT_EXBRK, UNIT_EXBRK, "Break on exceptions", "EXBRK", + NULL, NULL, NULL, "Enables break on floating point exceptions" }, + { UNIT_EXBRK, 0, "No break on exceptions", "NOEXBRK", + NULL, NULL, NULL, "Disables break on floating point exceptions" }, + { 0 } +}; + +static DEBTAB mau_debug[] = { + { "DECODE", DECODE_DBG, "Decode" }, + { "TRACE", TRACE_DBG, "Call Trace" }, + { NULL } +}; + +DEVICE mau_dev = { + "MAU", /* name */ + &mau_unit, /* units */ + mau_reg, /* registers */ + mau_mod, /* modifiers */ + 1, /* #units */ + 16, /* address radix */ + 32, /* address width */ + 1, /* address incr. */ + 16, /* data radix */ + 8, /* data width */ + NULL, /* examine routine */ + NULL, /* deposit routine */ + &mau_reset, /* reset routine */ + NULL, /* boot routine */ + NULL, /* attach routine */ + NULL, /* detach routine */ + NULL, /* context */ +#ifdef REV3 + DEV_DEBUG, /* Rev 3 flags: Always required */ +#else + DEV_DISABLE|DEV_DEBUG, /* Rev 2 flags: Can be disabled */ +#endif + 0, /* debug control flags */ + mau_debug, /* debug flag names */ + NULL, /* memory size change */ + NULL, /* logical name */ + NULL, /* help routine */ + NULL, /* attach help routine */ + NULL, /* help context */ + &mau_description /* device description */ +}; + +XFP INF = { + 0x7fff, + 0x0000000000000000ull, + 0 +}; + +XFP TRAPPING_NAN = { + 0x7fff, + 0x7fffffffffffffffull, + 0 +}; + +/* Generated Non-Trapping NaN + * p. 2-8 "When the MAU generates a nontrapping NaN, J+fraction + * contains all 1s. The MAU never generates a trapping NaN." + */ +XFP GEN_NONTRAPPING_NAN = { + 0x7fff, + 0xffffffffffffffffull, + 0 +}; + +CONST char *mau_op_names[32] = { + "0x00", "0x01", "ADD", "SUB", + "DIV", "REM", "MUL", "MOVE", + "RDASR", "WRASR", "CMP", "CMPE", + "ABS", "SQRT", "RTOI", "FTOI", + "ITOF", "DTOF", "FTOD", "NOP", + "EROF", "0x15", "0x16", "NEG", + "LDR", "0x19", "CMPS", "CMPES", +#if defined(REV3) + "SIN", "COS", "ATAN", "PI" +#else + "0x1C", "0x1D", "0x1E", "0x1F" +#endif +}; + +CONST char *src_op_names[8] = { + "F0", "F1", "F2", "F3", + "MEM S", "MEM D", "MEM X", "N/A" +}; + +CONST char *dst_op_names[16] = { + "F0 S", "F1 S", "F2 S", "F3 S", + "F0 D", "F1 D", "F2 D", "F3 D", + "F0 X", "F1 X", "F2 X", "F3 X", + "MEM S", "MEM D", "MEM X", "N/A" +}; + +/* + * Special Cases + * ------------- + * + * The handling of combinations of special input values is specified + * in the "WE32106 Math Acceleration Unit Information Manual" + * pp. 5-3--5-5. + * + * Each of these "special case" routines can be called by math + * functions based on a combination of the input values. + * + * (At the moment, only divide-by-zero is explicitly called out here + * as a special case) + */ + +static SIM_INLINE void mau_case_div_zero(XFP *op1, XFP *op2, XFP *result) +{ + mau_state.asr |= MAU_ASR_QS; + + if (mau_state.asr & MAU_ASR_QM) { + mau_state.asr |= MAU_ASR_ECP; + PACK_XFP(0, 0x7fff, 0x8000000000000000ull, result); + } else { + if (XFP_SIGN(op1) ^ XFP_SIGN(op2)) { + PACK_XFP(1, INF.sign_exp, INF.frac, result); + } else { + PACK_XFP(0, INF.sign_exp, INF.frac, result); + } + } +} + +static SIM_INLINE void mau_exc(uint32 flag, uint32 mask) +{ + sim_debug(TRACE_DBG, &mau_dev, + "[mau_exc] asr=%08x flag=%08x mask=%08x\n", + mau_state.asr, flag, mask); + + mau_state.asr |= flag; + + /* + * page 2-14: NTNC bit is checked if an Invalid Operation + * exception occurs while the Invalid Operation Mask bit is + * clear. If NTNC is set to 1, an exception occurs and bit 9 + * (IS) is set. If NTNC is set to 0, no exception occurs, + * and a nontraping NaN is generated. + */ + if (flag == MAU_ASR_IS && (mau_state.asr & MAU_ASR_IM) == 0) { + if (mau_state.asr & MAU_ASR_NTNC) { + mau_state.asr |= MAU_ASR_ECP; + } else { + mau_state.ntnan = TRUE; + } + return; + } + + if (mau_state.asr & mask) { + mau_state.asr |= MAU_ASR_ECP; + } +} + +/* + * Returns true if an exceptional condition is present. + */ +static SIM_INLINE t_bool mau_exception_present() +{ + + return mau_state.asr & MAU_ASR_ECP && + (((mau_state.asr & MAU_ASR_IS) && ((mau_state.asr & MAU_ASR_IM) || + (mau_state.asr & MAU_ASR_NTNC))) || + ((mau_state.asr & MAU_ASR_US) && (mau_state.asr & MAU_ASR_UM)) || + ((mau_state.asr & MAU_ASR_OS) && (mau_state.asr & MAU_ASR_OM)) || + ((mau_state.asr & MAU_ASR_PS) && (mau_state.asr & MAU_ASR_PM)) || + ((mau_state.asr & MAU_ASR_QS) && (mau_state.asr & MAU_ASR_QM))); +} + +static SIM_INLINE void abort_on_fault() +{ + switch(mau_state.opcode) { + case M_NOP: + case M_RDASR: + case M_WRASR: + case M_EROF: + case M_LDR: + return; + default: + /* + * Integer overflow is non-maskable in the MAU, but generates an Integer + * Overflow exception to be handled by the WE32100 CPU (if not masked + * in the CPU's PSW). + */ + if ((mau_state.asr & MAU_ASR_IO) && (R[NUM_PSW] & PSW_OE_MASK)) { + if (mau_unit.flags & UNIT_EXBRK) { + stop_reason = STOP_EX; + } + sim_debug(TRACE_DBG, &mau_dev, + "[abort_on_fault] Aborting on un-maskable overflow fault. ASR=%08x\n", + mau_state.asr); + cpu_abort(NORMAL_EXCEPTION, INTEGER_OVERFLOW); + } + + /* Otherwise, check for other exceptions. */ + if (mau_exception_present()) { + if (mau_unit.flags & UNIT_EXBRK) { + stop_reason = STOP_EX; + } + sim_debug(TRACE_DBG, &mau_dev, + "[abort_on_fault] Aborting on ECP fault. ASR=%08x\n", + mau_state.asr); + cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT); + } + + break; + } +} + +/* + * Clears N and Z flags in the ASR if appropriate. + */ +static void clear_asr() +{ + mau_state.ntnan = FALSE; + + switch(mau_state.opcode) { + case M_NOP: + case M_RDASR: + case M_WRASR: + case M_EROF: + return; + default: + mau_state.asr &= ~(MAU_ASR_Z|MAU_ASR_N|MAU_ASR_ECP); + break; + } +} + +/* + * Returns true if the 'nz' flags should be set. + * + * Note: There is an undocumented feature of the WE32106 expressed + * here. If an exception has occured, the Z and N flags are not to be + * set! + */ +static t_bool set_nz() +{ + switch(mau_state.opcode) { + case M_NOP: + case M_RDASR: + case M_WRASR: + case M_EROF: + return FALSE; + default: + return (mau_state.asr & MAU_ASR_ECP) == 0; + } +} + +t_stat mau_reset(DEVICE *dptr) +{ + memset(&mau_state, 0, sizeof(MAU_STATE)); +#if defined(REV3) + mau_state.asr |= MAU_ASR_VER; /* Version 1 MAU */ +#endif + return SCPE_OK; +} + +/************************************************************************* + * Utility Functions + ************************************************************************/ + +/* + * Compare two 128-bit values a and b. Rturns true if a <= b + * + * Derived from the SoftFloat 2c package (see copyright notice above) + */ +static SIM_INLINE t_bool le_128(t_uint64 a0, t_uint64 a1, t_uint64 b0, t_uint64 b1) +{ + return (a0 < b0) || ((a0 == b0) && (a1 <= b1)); +} + +/* + * Compare two 128-bit values a and b. Returns true if a = b + * + * Derived from the SoftFloat 2c package (see copyright notice above) + */ +static SIM_INLINE t_bool eq_128(t_uint64 a0, t_uint64 a1, t_uint64 b0, t_uint64 b1) +{ + return (a0 == b0) && (a1 == b1); +} + +/* + * Compare two 128-bit values a and b. Returns true if a < b + * + * Derived from the SoftFloat 2c package (see copyright notice above) + */ +static SIM_INLINE t_bool lt_128(t_uint64 a0, t_uint64 a1, t_uint64 b0, t_uint64 b1) +{ + return (a0 < b0) || ((a0 == b0) && (a1 < b1)); +} + +/* + * Return the number of leading binary zeros in an unsigned 32-bit + * value. + * + * Algorithm couresty of "Hacker's Delight" by Henry S. Warren. + */ +static uint8 leading_zeros(uint32 val) +{ + unsigned n = 0; + + if (val <= 0x0000ffff) { + n += 16; + val <<= 16; + } + if (val <= 0x00ffffff) { + n += 8; + val <<= 8; + } + if (val <= 0x0fffffff) { + n += 4; + val <<= 4; + } + if (val <= 0x3fffffff) { + n += 2; + val <<= 2; + } + if (val <= 0x7fffffff) { + n++; + } + + return n; +} + +/* + * Return the number of leading binary zeros in a signed 64-bit + * value. + */ +static uint8 leading_zeros_64(t_int64 val) +{ + uint8 n = 0; + + if (val == 0) { + return 64; + } + + while (1) { + if (val < 0) break; + + n++; + + val <<= 1; + } + + return n; +} + +/* + * Shift a 32-bit unsigned value, 'val', right by 'count' bits. If any + * non-zero bits are shifted off, they are "jammed" into the least + * significant bit of the result by setting the least significant bit + * to 1. + * + * Derived from the SoftFloat 2c package (see copyright notice above) + */ +static void shift_right_32_jamming(uint32 val, int16 count, uint32 *result) +{ + uint32 tmp; + + if (count == 0) { + tmp = val; + } else if (count < 32) { + tmp = (val >> count) | ((val << ((-count) & 31)) != 0); + } else { + tmp = (val != 0); + } + + *result = tmp; +} + +/* + * Shift a 64-bit unsigned value, 'val', right by 'count' bits. If any + * non-zero bits are shifted off, they are "jammed" into the least + * significant bit of the result by setting the least significant bit + * to 1. + * + * Derived from the SoftFloat 2c package (see copyright notice above) + */ +static void shift_right_64_jamming(t_uint64 val, int16 count, t_uint64 *result) +{ + t_uint64 tmp; + + if (count == 0) { + tmp = val; + } else if (count < 64) { + tmp = (val >> count) | ((val << ((-count) & 63)) != 0); + } else { + tmp = (val != 0); + } + + *result = tmp; +} + +/* + * Shifts the 128-bit value formed by concatenating val_a and val_b + * right by 64 _plus_ the number of bits given in 'count'. + * + * Derived from the SoftFloat 2c package (see copyright notice above) + */ +static void shift_right_extra_64_jamming(t_uint64 val_a, t_uint64 val_b, int16 count, + t_uint64 *r_a, t_uint64 *r_b) +{ + t_uint64 a, b; + int8 neg_count = (-count) & 63; + + if (count == 0) { + b = val_b; + a = val_a; + } else if (count < 64) { + b = (val_a << neg_count) | (val_b != 0); + a = val_a >> count; + } else { + if (count == 64) { + b = val_a | (val_b != 0); + } else { + b = ((val_a | val_b) != 0); + } + a = 0; + } + + *r_a = a; + *r_b = b; +} + +/* + * Shift the 128-bit value formed by val_a and val_b right by + * 64 plus the number of bits given in count. + * + * Derived from the SoftFloat 2c package (see copyright notice above) + */ +static void shift_right_128_jamming(t_uint64 val_a, t_uint64 val_b, int16 count, + t_uint64 *r_a, t_uint64 *r_b) +{ + t_uint64 tmp_a, tmp_b; + int8 neg_count = (-count) & 63; + + if (count == 0) { + tmp_a = val_a; + tmp_b = val_b; + } else if (count < 64) { + tmp_a = (val_a >> count); + tmp_b = (val_a << neg_count) | (val_b != 0); + } else { + if (count == 64) { + tmp_b = val_a | (val_b != 0); + } else { + tmp_b = ((val_a | val_b) != 0); + } + tmp_a = 0; + } + + *r_a = tmp_a; + *r_b = tmp_b; +} + +/* + * Shifts the 128-bit value formed by val_a and val_b left by the + * number of bits given in count. + * + * Derived from the SoftFloat 2c package (see copyright notice above) + */ +static void short_shift_left_128(t_uint64 val_a, t_uint64 val_b, int16 count, + t_uint64 *r_a, t_uint64 *r_b) +{ + *r_b = val_b << count; + if (count == 0) { + *r_a = val_a; + } else { + *r_a = (val_a << count) | (val_b >> ((-count) & 63)); + } +} + +/* + * Shifts the 128-bit value formed by val_a and val_b right by the + * number of bits given ihn 'count'. Any bits shifted off are lost. + * + * Derived from the SoftFloat 2c package (see copyright notice above) + */ +static void shift_right_128(t_uint64 val_a, t_uint64 val_b, int16 count, + t_uint64 *r_a, t_uint64 *r_b) +{ + t_uint64 tmp_a, tmp_b; + int8 neg_count; + + neg_count = (- count) & 63; + + if (count == 0) { + tmp_a = val_a; + tmp_b = val_b; + } else if (count < 64) { + tmp_a = val_a >> count; + tmp_b = (val_a << neg_count) | (val_b >> count); + } else { + tmp_a = 0; + tmp_b = (count < 128) ? (val_a >> (count & 63)) : 0; + } + + *r_a = tmp_a; + *r_b = tmp_b; +} + +/* + * Add two 128-bit values. + * + * Derived from the SoftFloat 2c package (see copyright notice above) + */ +static void add_128(t_uint64 a0, t_uint64 a1, + t_uint64 b0, t_uint64 b1, + t_uint64 *r_low, t_uint64 *r_high) +{ + t_uint64 tmp; + + tmp = a1 + b1; + *r_high = tmp; + *r_low = a0 + b0 + (tmp < a1); +} + +/* + * Subract two 128-bit values. + * + * Derived from the SoftFloat 2c package (see copyright notice above) + */ +static void sub_128(t_uint64 a0, t_uint64 a1, + t_uint64 b0, t_uint64 b1, + t_uint64 *r_low, t_uint64 *r_high) +{ + *r_high = a1 - b1; + *r_low = a0 - b0 - (a1 < b1); +} + +/* + * Multiplies a by b to obtain a 128-bit product. The product is + * broken into two 64-bit pieces which are stored at r_low and r_high. + * + * Derived from the SoftFloat 2c package (see copyright notice above) + */ +static void mul_64_to_128(t_uint64 a, t_uint64 b, t_uint64 *r_low, t_uint64 *r_high) +{ + uint32 a_high, a_low, b_high, b_low; + t_uint64 rl, rm_a, rm_b, rh; + + a_low = (uint32)a; + a_high = a >> 32; + + b_low = (uint32)b; + b_high = b >> 32; + + rh = ((t_uint64) a_low) * b_low; + rm_a = ((t_uint64) a_low) * b_high; + rm_b = ((t_uint64) a_high) * b_low; + rl = ((t_uint64) a_high) * b_high; + + rm_a += rm_b; + + rl += (((t_uint64)(rm_a < rm_b)) << 32) + (rm_a >> 32); + rm_a <<= 32; + rh += rm_a; + rl += (rh < rm_a); + + *r_high = rh; + *r_low = rl; +} + +/* + * Derived from the SoftFloat 2c package (see copyright notice above) + */ +static void mul_64_by_shifted_32_to_128(t_uint64 a, uint32 b, t_mau_128 *result) +{ + t_uint64 mid; + + mid = (t_uint64)(uint32) a * b; + result->low = mid << 32; + result->high = (t_uint64)(uint32)(a >> 32) * b + (mid >> 32); +} + +/* + * Returns an approximation of the 64-bit integer value obtained by + * dividing 'b' into the 128-bit value 'a0' and 'a1'. + * + * Derived from the SoftFloat 2c package (see copyright notice above) + */ +static t_uint64 estimate_div_128_to_64(t_uint64 a0, t_uint64 a1, t_uint64 b) +{ + t_uint64 b0, b1; + t_uint64 rem0, rem1, term0, term1; + t_uint64 z; + + if (b <= a0) { + return 0xffffffffffffffffull; + } + + b0 = b >> 32; + z = (b0 << 32 <= a0) ? 0xffffffff00000000ull : (a0 / b0) << 32; + + mul_64_to_128( b, z, &term0, &term1 ); + + sub_128( a0, a1, term0, term1, &rem0, &rem1 ); + + while (((int64_t)rem0) < 0) { + z -= 0x100000000ull; + b1 = b << 32; + add_128(rem0, rem1, b0, b1, &rem0, &rem1); + } + + rem0 = (rem0 << 32) | (rem1 >> 32); + z |= (b0<<32 <= rem0) ? 0xffffffff : rem0 / b0; + + return z; +} + +static uint32 approx_recip_sqrt_32(uint32 oddExpA, uint32 a) +{ + int index; + uint16 eps, r0; + uint32 ESqrR0; + uint32 sigma0; + uint32 r; + uint32 sqrSigma0; + + static const uint16 softfloat_approxRecipSqrt_1k0s[16] = { + 0xB4C9, 0xFFAB, 0xAA7D, 0xF11C, 0xA1C5, 0xE4C7, 0x9A43, 0xDA29, + 0x93B5, 0xD0E5, 0x8DED, 0xC8B7, 0x88C6, 0xC16D, 0x8424, 0xBAE1 + }; + static const uint16 softfloat_approxRecipSqrt_1k1s[16] = { + 0xA5A5, 0xEA42, 0x8C21, 0xC62D, 0x788F, 0xAA7F, 0x6928, 0x94B6, + 0x5CC7, 0x8335, 0x52A6, 0x74E2, 0x4A3E, 0x68FE, 0x432B, 0x5EFD + }; + + index = (a>>27 & 0xE) + oddExpA; + eps = (uint16) (a>>12); + r0 = softfloat_approxRecipSqrt_1k0s[index] + - ((softfloat_approxRecipSqrt_1k1s[index] * (uint32) eps) + >>20); + ESqrR0 = (uint32) r0 * r0; + if ( ! oddExpA ) ESqrR0 <<= 1; + sigma0 = ~(uint32) (((uint32) ESqrR0 * (t_uint64) a)>>23); + r = ((uint32) r0<<16) + ((r0 * (t_uint64) sigma0)>>25); + sqrSigma0 = ((t_uint64) sigma0 * sigma0)>>32; + r += ((uint32) ((r>>1) + (r>>3) - ((uint32) r0<<14)) + * (t_uint64) sqrSigma0) + >>48; + if ( ! (r & 0x80000000) ) r = 0x80000000; + return r; +} + +/* + * Return the properly rounded 32-bit integer corresponding to 'sign' + * and 'frac'. + * + * Derived from the SoftFloat 2c package (see copyright notice above) + */ +static uint32 round_pack_int(t_bool sign, t_uint64 frac, RM rounding_mode) +{ + int8 round_increment, round_bits; + int32 result; + + round_increment = 0x40; + + if (!(rounding_mode == ROUND_NEAREST)) { + if (rounding_mode == ROUND_ZERO) { + round_increment = 0; + } else { + round_increment = 0x7f; + if (sign) { + if (rounding_mode == ROUND_PLUS_INF) { + round_increment = 0; + } + } else { + if (rounding_mode == ROUND_MINUS_INF) { + round_increment = 0; + } + } + } + } + + round_bits = frac & 0x7f; + frac = (frac + round_increment) >> 7; + frac &= ~((t_uint64)((round_bits ^ 0x40) == 0) & + (t_uint64)(rounding_mode == ROUND_NEAREST)); + + result = (int32)frac; + + if (sign) { + result = -result; + } + + if ((frac >> 32) || (result && ((result < 0) ^ sign))) { + mau_exc(MAU_ASR_IO, MAU_ASR_OM); /* Integer overflow */ + mau_exc(MAU_ASR_PS, MAU_ASR_PM); /* Inexact */ + return sign ? (int32) 0x80000000 : 0x7fffffff; + } + + if (round_bits) { + mau_exc(MAU_ASR_PS, MAU_ASR_PM); + } + + return result; +} + +/* + * Return the properly rounded 64-bit integer corresponding to 'sign' + * and 'frac'. + * + * Derived from the SoftFloat 2c package (see copyright notice above) + */ +static t_int64 round_pack_int64(t_bool sign, + t_uint64 abs_0, t_uint64 abs_1, + RM rounding_mode) +{ + t_bool increment; + int64_t z; + + increment = (t_int64)abs_1 < 0; + + if (rounding_mode != ROUND_NEAREST) { + if (rounding_mode == ROUND_ZERO) { + increment = 0; + } else { + if (sign) { + increment = (rounding_mode == ROUND_MINUS_INF) && abs_1; + } else { + increment = (rounding_mode == ROUND_PLUS_INF) && abs_1; + } + } + } + + if (increment) { + ++abs_0; + if (abs_0 == 0) { + /* Overflow */ + mau_exc(MAU_ASR_OS, MAU_ASR_OM); + return sign ? 0x8000000000000000ull : 0x7fffffffffffffffull; + } + abs_0 &= ~((t_uint64)((abs_1 << 1) == 0) & + (t_uint64)(rounding_mode == ROUND_NEAREST)); + } + + z = abs_0; + if (sign) { + z = -z; + } + if (z && ((z < 0) ^ sign)) { + /* Overflow */ + mau_exc(MAU_ASR_OS, MAU_ASR_OM); + return sign ? 0x8000000000000000ull : 0x7fffffffffffffffull; + } + + if (abs_1) { + mau_exc(MAU_ASR_PS, MAU_ASR_PM); + } + + return z; +} + +/* + * Return a properly rounded 32-bit floating point value, given a sign + * bit, exponent, fractional part, and a rounding mode. + * + * Derived from the SoftFloat 2c package (see copyright notice above) + */ +static SFP round_pack_sfp(t_bool sign, int16 exp, uint32 frac, RM rounding_mode) +{ + int8 round_increment, round_bits; + uint8 is_tiny; + + is_tiny = 0; + round_increment = 0x40; + + if (rounding_mode != ROUND_NEAREST) { + if (rounding_mode == ROUND_ZERO) { + round_increment = 0; + } else { + if (sign) { + if (rounding_mode == ROUND_PLUS_INF) { + round_increment = 0; + } + } else { + if (rounding_mode == ROUND_MINUS_INF) { + round_increment = 0; + } + } + } + } + + round_bits = frac & 0x7f; + + if (0xfd <= (uint16) exp) { + if ((0xfd < exp) || + (exp == 0xfd && (int32)(frac + round_increment) < 0)) { + mau_exc(MAU_ASR_OS, MAU_ASR_OM); + mau_exc(MAU_ASR_PS, MAU_ASR_PM); + return PACK_SFP(sign, 0xff, 0) - (round_increment == 0); + } + if (exp < 0) { + is_tiny = (TININESS_BEFORE_ROUNDING || + ((exp < -1) || + (frac + round_increment < 0x80000000))); + shift_right_32_jamming(frac, -exp, &frac); + exp = 0; + round_bits = frac & 0x7f; + if (is_tiny && round_bits) { + mau_exc(MAU_ASR_US, MAU_ASR_UM); + } + } + } + + if (round_bits) { + mau_exc(MAU_ASR_PS, MAU_ASR_PM); + } + + frac = (frac + round_increment) >> 7; + frac &= ~((t_uint64)((round_bits ^ 0x40) == 0) & + (t_uint64)(rounding_mode == ROUND_NEAREST)); + if (frac == 0) { + exp = 0; + } + + return PACK_SFP(sign, exp, frac); +} + +/* + * Return a properly rounded 64-bit floating point value, given a sign + * bit, exponent, fractional part, and a rounding mode. + * + * Derived from the SoftFloat 2c package (see copyright notice above) + */ +static DFP round_pack_dfp(t_bool sign, int16 exp, t_uint64 frac, + t_bool xfp_sticky, RM rounding_mode) +{ + int16 round_increment, round_bits; + t_bool lsb, round, sticky; + uint8 is_tiny; + + is_tiny = 0; + round_increment = 0; + + if (rounding_mode != ROUND_NEAREST) { + if (rounding_mode == ROUND_ZERO) { + round_increment = 0; + } else { + round_increment = 0x7ff; + if (sign) { + if (rounding_mode == ROUND_PLUS_INF) { + round_increment = 0; + } + } else { + if (rounding_mode == ROUND_MINUS_INF) { + round_increment = 0; + } + } + } + } + + round_bits = frac & 0x7ff; + + if (0x7fd <= (uint16) exp) { + if (exp < 0) { + is_tiny = (TININESS_BEFORE_ROUNDING || + (exp < -1) || + ((frac + round_increment) < 0x8000000000000000ull)); + shift_right_64_jamming(frac, -exp, &frac); + exp = 0; + round_bits = frac & 0x7ff; + if (is_tiny && round_bits) { + mau_exc(MAU_ASR_US, MAU_ASR_UM); + } + } else if (0x7fd < exp) { + mau_exc(MAU_ASR_OS, MAU_ASR_OM); + mau_exc(MAU_ASR_PS, MAU_ASR_PM); + return (PACK_DFP(sign, 0x7ff, 0) - (round_increment == 0)); + } + } + + if (round_bits) { + mau_exc(MAU_ASR_PS, MAU_ASR_PM); + } + + if (rounding_mode == ROUND_NEAREST) { + frac >>= 11; + lsb = (frac & 1) != 0; + round = (round_bits & 0x400) != 0; + sticky = ((round_bits & 0x3ff) != 0) | xfp_sticky; + if (round & (sticky || lsb)) { + frac++; + if (frac == 0) { + exp++; + } + } + } else { + frac = (frac + round_increment) >> 11; + lsb = !((t_bool)(round_bits ^ 0x200)); + frac &= ~((t_uint64)lsb); + } + + return PACK_DFP(sign, exp, frac); +} + +/* + * Return a properly rounded 80-bit floating point value, given a sign + * bit, exponent, fractional part, and a rounding mode. + * + * Derived from the SoftFloat 2c package (see copyright notice above) + */ +static void round_pack_xfp(t_bool sign, int32 exp, + t_uint64 frac_a, t_uint64 frac_b, + RM rounding_mode, XFP *result) +{ + uint8 is_tiny; + t_int64 round_mask; + + if (0x7ffd <= (uint32)(exp - 1)) { + if (0x7ffe < exp) { + round_mask = 0; + mau_exc(MAU_ASR_OS, MAU_ASR_OM); + mau_exc(MAU_ASR_PS, MAU_ASR_PM); + if ((rounding_mode == ROUND_ZERO) || + (sign && (rounding_mode == ROUND_PLUS_INF)) || + (!sign && (rounding_mode == ROUND_MINUS_INF))) { + PACK_XFP(sign, 0x7ffe, ~round_mask, result); + return; + } + PACK_XFP(sign, 0x7fff, 0x8000000000000000ull, result); + return; + } + if (exp <= 0) { + is_tiny = (TININESS_BEFORE_ROUNDING || + (exp < 0) || + (frac_a < 0xffffffffffffffffull)); + shift_right_extra_64_jamming(frac_a, frac_b, (int16)(1 - exp), &frac_a, &frac_b); + exp = 0; + if (is_tiny && frac_b) { + mau_exc(MAU_ASR_US, MAU_ASR_UM); + } + if (frac_b) { + mau_exc(MAU_ASR_PS, MAU_ASR_PM); + } + PACK_XFP(sign, exp, frac_a, result); + return; + } + } + if (frac_b) { + mau_exc(MAU_ASR_PS, MAU_ASR_PM); + } + if (frac_a == 0) { + exp = 0; + } + PACK_XFP_S(sign, exp, frac_a, frac_b, result); +} + +/* + * Given two 80-bit floating point values 'a' and 'b', one of which is + * a NaN, return the appropriate NaN result. + * + * Derived from the SoftFloat 2c package (see copyright notice above) + */ +static void propagate_xfp_nan(XFP *a, XFP *b, XFP *result) +{ + uint8 a_is_nan, a_is_signaling_nan; + uint8 b_is_nan, b_is_signaling_nan; + + a_is_nan = XFP_IS_NAN(a); + a_is_signaling_nan = XFP_IS_TRAPPING_NAN(a); + b_is_nan = XFP_IS_NAN(b); + b_is_signaling_nan = XFP_IS_TRAPPING_NAN(b); + + a->frac |= 0xc000000000000000ull; + b->frac |= 0xc000000000000000ull; + + if (a_is_signaling_nan | b_is_signaling_nan) { + mau_exc(MAU_ASR_IS, MAU_ASR_IM); + } + + if (a_is_nan) { + if (a_is_signaling_nan & b_is_nan) { + result->sign_exp = b->sign_exp; + result->frac = b->frac; + } else { + result->sign_exp = a->sign_exp; + result->frac = a->frac; + } + } else { + result->sign_exp = b->sign_exp; + result->frac = b->frac; + } +} + +/* + * Derived from the SoftFloat 2c package (see copyright notice above) + */ +static void propagate_xfp_nan_128(XFP* a, XFP* b, t_mau_128* result) +{ + t_bool is_sig_nan_a, is_sig_nan_b; + t_uint64 non_frac_a_low, non_frac_b_low; + uint16 mag_a, mag_b; + + is_sig_nan_a = XFP_IS_TRAPPING_NAN(a); + is_sig_nan_b = XFP_IS_TRAPPING_NAN(b); + + non_frac_a_low = a->frac & 0xC000000000000000ull; + non_frac_b_low = b->frac & 0xC000000000000000ull; + + if (is_sig_nan_a | is_sig_nan_b) { + /* Invalid */ + mau_exc(MAU_ASR_IS, MAU_ASR_IM); + if (is_sig_nan_a) { + if (is_sig_nan_b) goto return_larger_mag; + if (XFP_IS_NAN(b)) goto return_b; + goto return_a; + } else { + if (XFP_IS_NAN(a)) goto return_a; + goto return_b; + } + } + + return_larger_mag: + mag_a = a->frac & 0x7fff; + mag_b = b->frac & 0x7fff; + if (mag_a < mag_b) goto return_b; + if (mag_b < mag_a) goto return_a; + if (a->frac < b->frac) goto return_b; + if (b->frac < a->frac) goto return_a; + if (a->sign_exp < b->sign_exp) goto return_a; + return_b: + result->high = b->sign_exp; + result->low = non_frac_b_low; + return; + return_a: + result->high = a->sign_exp; + result->low = non_frac_a_low; + return; +} + +/* + * Normalize and round an extended-precision floating point value. + * + * Partially derived from the SoftFloat 2c package (see copyright + * notice above) + */ +static void normalize_round_pack_xfp(t_bool sign, int32 exp, + t_uint64 frac_0, t_uint64 frac_1, + RM rounding_mode, XFP *result) +{ + int8 shift_count; + + if (frac_0 == 0) { + frac_0 = frac_1; + frac_1 = 0; + exp -= 64; + } + + shift_count = leading_zeros_64(frac_0); + short_shift_left_128(frac_0, frac_1, shift_count, &frac_0, &frac_1); + exp -= shift_count; + + round_pack_xfp(sign, exp, frac_0, frac_1, rounding_mode, result); +} + + +/* + * Normalize the subnormal 80-bit floating point value represented by + * the denormalized input fractional comonent. + * + * Derived from the SoftFloat 2c package (see copyright notice above) + */ +static void normalize_sfp_subnormal(uint32 in_frac, int16 *out_exp, uint32 *out_frac) +{ + int8 shift_count; + + shift_count = leading_zeros(in_frac) - 8; + + if (shift_count < 0) { + /* There was invalid input, there's nothing we can do. */ + *out_frac = in_frac; + *out_exp = 0; + return; + } + + *out_frac = in_frac << shift_count; + *out_exp = (uint16)(1 - shift_count); +} + +/* + * Normalize the subnormal 64-bit floating point value represented by + * the denormalized input fractional comonent. + * + * Derived from the SoftFloat 2c package (see copyright notice above) + */ +static void normalize_dfp_subnormal(t_uint64 in_frac, int16 *out_exp, t_uint64 *out_frac) +{ + int8 shift_count; + + shift_count = leading_zeros_64(in_frac) - 11; + + if (shift_count < 0) { + /* There was invalid input, there's nothing we can do. */ + *out_frac = in_frac; + *out_exp = 0; + return; + } + + *out_frac = in_frac << shift_count; + *out_exp = 1 - shift_count; +} + +/* + * Normalize the subnormal 32-bit floating point value represented by + * the denormalized input fractional comonent. + * + * Derived from the SoftFloat 2c package (see copyright notice above) + */ +static void normalize_xfp_subnormal(t_uint64 in_frac, int32 *out_exp, t_uint64 *out_frac) +{ + int8 shift_count; + + shift_count = leading_zeros_64(in_frac); + if (shift_count < 64) { + *out_frac = in_frac << shift_count; + } else { + *out_frac = 0; + } + *out_exp = 1 - shift_count; +} + +/* + * Returns the result of converting the 32-bit floating point NaN + * value to the canonincal NaN format. + * + * Derived from the SoftFloat 2c package (see copyright notice above) + */ +static T_NAN sfp_to_common_nan(SFP val) +{ + T_NAN nan = {0}; + + if (SFP_IS_TRAPPING_NAN(val)) { + mau_state.trapping_nan = TRUE; + } + + nan.sign = val >> 31; + nan.low = 0; + nan.high = ((t_uint64) val) << 41; + + return nan; +} + +/* + * Returns the result of converting the 64-bit floating point NaN + * value to the canonincal NaN format. + * + * Derived from the SoftFloat 2c package (see copyright notice above) + */ +static T_NAN dfp_to_common_nan(DFP val) +{ + T_NAN nan = {0}; + + if (DFP_IS_TRAPPING_NAN(val)) { + mau_state.trapping_nan = TRUE; + } + + nan.sign = (val >> 63) & 1; + nan.low = 0; + nan.high = (t_uint64)(val << 12); + + return nan; +} + +/* + * Returns the result of converting the 80-bit floating point NaN + * value to the canonincal NaN format. + * + * Derived from the SoftFloat 2c package (see copyright notice above) + */ +static T_NAN xfp_to_common_nan(XFP *val) +{ + T_NAN nan = {0}; + + if (XFP_IS_TRAPPING_NAN(val)) { + mau_state.trapping_nan = TRUE; + } + + nan.sign = val->sign_exp >> 15; + nan.low = 0; + nan.high = val->frac << 1; + + return nan; +} + +/* + * Returns the result of converting a canonical NAN format value to a + * 32-bit floating point format. + * + * Derived from the SoftFloat 2c package (see copyright notice above) + */ +static SFP common_nan_to_sfp(T_NAN nan) +{ + return ((((uint32)nan.sign) << 31) + | 0x7fc00000 + | (nan.high >> 41)); +} + +/* + * Returns the result of converting a canonical NAN format value to a + * 64-bit floating point format. + * + * Derived from the SoftFloat 2c package (see copyright notice above) + */ +static DFP common_nan_to_dfp(T_NAN nan) +{ + return ((((t_uint64)nan.sign) << 63) + | 0x7ff8000000000000ull + | (nan.high >> 12)); +} + +/* + * Returns the result of converting a canonical NAN format value to an + * 80-bit floating point format. + * + * Derived from the SoftFloat 2c package (see copyright notice above) + */ +static void common_nan_to_xfp(T_NAN nan, XFP *result) +{ + result->frac = 0xc000000000000000ull | (nan.high >> 1); + result->sign_exp = (((uint16)nan.sign) << 15) | 0x7fff; +} + +/* + * Convert a 32-bit floating point value to an 80-bit floating point + * value. + * + * Derived from the SoftFloat 2c package (see copyright notice above) + */ +static void sfp_to_xfp(SFP val, XFP *result) +{ + t_bool sign; + int16 exp; + uint32 frac; + + sign = SFP_SIGN(val); + exp = SFP_EXP(val); + frac = SFP_FRAC(val); + + if (exp == 0xff) { + if (frac) { + common_nan_to_xfp(sfp_to_common_nan(val), result); + return; + } + } + + if (exp == 0) { + if (frac == 0) { + PACK_XFP(sign, 0, 0, result); + return; + } + normalize_sfp_subnormal(frac, &exp, &frac); + } + + frac |= 0x800000; + + PACK_XFP(sign, exp + 0x3f80, ((t_uint64) frac) << 40, result); +} + +/* + * Convert a 64-bit floating point value to an 80-bit floating point value. + * + * Derived from the SoftFloat 2c package (see copyright notice above) + */ +void dfp_to_xfp(DFP val, XFP *result) +{ + t_bool sign; + int16 exp; + t_uint64 frac; + + sign = DFP_SIGN(val); + exp = DFP_EXP(val); + frac = DFP_FRAC(val); + + if (exp == 0x7ff) { + if (sign) { + common_nan_to_xfp(dfp_to_common_nan(val), result); + } + + PACK_XFP(sign, 0xff, 0, result); + return; + } + if (exp == 0) { + if (frac == 0) { + PACK_XFP(sign, 0, 0, result); + return; + } + normalize_dfp_subnormal(frac, &exp, &frac); + } + + PACK_XFP(sign, + exp + 0x3c00, + 0x8000000000000000ull | (frac << 11), + result); +} + +/* + * Convert an 80-bit floating point value to a 32-bit floating point + * value. + * + * Derived from the SoftFloat 2c package (see copyright notice above) + */ +static SFP xfp_to_sfp(XFP *val, RM rounding_mode) +{ + t_bool sign; + int32 exp; + t_uint64 frac; + uint32 dst_frac; + + sign = XFP_SIGN(val); + exp = XFP_EXP(val); + frac = XFP_FRAC(val); + + if (exp == 0x7fff) { + if ((t_uint64)(frac << 1)) { + return common_nan_to_sfp(xfp_to_common_nan(val)); + } + return PACK_SFP(sign, 0xff, 0); + } + + shift_right_64_jamming(frac, 33, &frac); + + dst_frac = (uint32)frac; + + if (exp || frac) { + exp -= 0x3f81; + } + + return round_pack_sfp(sign, exp, dst_frac, rounding_mode); +} + +/* + * Convert an 80-bit floating point value to a 64-bit floating point + * value. + * + * Derived from the SoftFloat 2c package (see copyright notice above) + */ +static DFP xfp_to_dfp(XFP *val, RM rounding_mode) +{ + t_bool sign; + int32 exp; + t_uint64 frac; + + sign = XFP_SIGN(val); + exp = XFP_EXP(val); + frac = XFP_FRAC(val); + + sim_debug(TRACE_DBG, &mau_dev, + "[xfp_to_dfp] input=%04x%016llx input_exp=%04x packed_exp=%04x\n", + val->sign_exp, val->frac, (uint16)exp, (uint16)(exp - 0x3c01)); + + if (exp == 0x7fff) { + if ((t_uint64)(frac << 1)) { + return common_nan_to_dfp(xfp_to_common_nan(val)); + } + return PACK_DFP(sign, 0x7ff, 0); + } + + if (exp || frac) { + exp -= 0x3c01; + } + + return round_pack_dfp(sign, exp, frac, val->s, rounding_mode); +} + +/***************************************************************************** + * Comparison Functions + ****************************************************************************/ + +/* + * Returns true if the two 80-bit floating point values are equal. + * + * Derived from the SoftFloat 2c package (see copyright notice above) + */ +static uint32 xfp_eq(XFP *a, XFP *b) +{ + if (((XFP_EXP(a) == 0x7fff) && (t_uint64)(XFP_FRAC(a) << 1)) || + ((XFP_EXP(b) == 0x7fff) && (t_uint64)(XFP_FRAC(b) << 1))) { + + /* Check for NAN and raise invalid exception */ + if (XFP_IS_TRAPPING_NAN(a) || XFP_IS_TRAPPING_NAN(b)) { + mau_exc(MAU_ASR_IS, MAU_ASR_IM); + } + + return 0; + } + + return ((a->frac == b->frac) && + ((a->sign_exp == b->sign_exp) || + ((a->frac == 0) && ((uint16)((a->sign_exp|b->sign_exp) << 1) == 0)))); +} + +/* + * Returns true if the 80-bit floating point value 'a' is less than + * the 80-bit floating point value 'b'. + * + * Derived from the SoftFloat 2c package (see copyright notice above) + */ +static uint32 xfp_lt(XFP *a, XFP *b) +{ + uint32 a_sign, b_sign; + + if (((XFP_EXP(a) == 0x7fff) && (t_uint64)(XFP_FRAC(a) << 1)) || + ((XFP_EXP(b) == 0x7fff) && (t_uint64)(XFP_FRAC(b) << 1))) { + return 0; + } + + a_sign = XFP_SIGN(a); + b_sign = XFP_SIGN(b); + + if (a_sign != b_sign) { + return(a_sign && + ((((uint16)((a->sign_exp|b->sign_exp) << 1)) | a->frac | b->frac) != 0)); + } + + if (a_sign) { + return (b->sign_exp < a->sign_exp) || ((b->sign_exp == a->sign_exp) && (b->frac < a->frac)); + } else { + return (a->sign_exp < b->sign_exp) || ((a->sign_exp == b->sign_exp) && (a->frac < b->frac)); + } +} + +/***************************************************************************** + * Conversion Functions + ****************************************************************************/ + +/* + * Convert a 32-bit signed integer value to an IEEE-754 extended + * precion (80-bit) floating point value. + * + * Derived from the SoftFloat 2c package (see copyright notice above) + */ +void mau_int_to_xfp(int32 val, XFP *result) +{ + int32 shift_width; + t_bool sign; + uint32 abs_val; + uint16 sign_exp = 0; + t_uint64 frac = 0; + + if (val) { + sign = (val < 0); + abs_val = (uint32)(sign ? -val : val); + shift_width = leading_zeros(abs_val); + sign_exp = (sign << 15) | (0x401e - shift_width); + frac = (t_uint64) (abs_val << shift_width) << 32; + } + + result->sign_exp = sign_exp; + result->frac = frac; + result->s = 0; + + if (sign_exp & 0x8000) { + mau_state.asr |= MAU_ASR_N; + } + + if ((sign_exp & 0x7fff) == 0 && frac == 0) { + mau_state.asr |= MAU_ASR_Z; + } +} + +/* + * Convert a floating point value to a 64-bit integer. + * + * Derived from the SoftFloat 2c package (see copyright notice above) + */ +t_int64 xfp_to_int64(XFP *val, RM rounding_mode) +{ + t_bool sign; + int32 exp, shift_count; + t_uint64 frac, frac_extra; + + sign = XFP_SIGN(val); + exp = XFP_EXP(val); + frac = XFP_FRAC(val); + shift_count = 0x403e - exp; + if (shift_count <= 0) { + if (shift_count) { + mau_exc(MAU_ASR_IS, MAU_ASR_IM); + if (!sign || ((exp == 0x7fff) && (frac != 0x8000000000000000ull))) { + return 0x7fffffffffffffffull; + } + return 0x8000000000000000ull; + } + frac_extra = 0; + } else { + shift_right_extra_64_jamming(frac, 0, shift_count, &frac, &frac_extra); + } + + return round_pack_int64(sign, frac, frac_extra, rounding_mode); +} + +void mau_int64_to_xfp(t_uint64 val, XFP *result) +{ + t_bool sign; + t_uint64 abs; + int8 shift_count; + + if (val == 0) { + PACK_XFP(0, 0, 0, result); + return; + } + + sign = (val & 0x8000000000000000ull) != 0ull; + abs = val & 0x7fffffffffffffffull; + shift_count = leading_zeros_64(abs); + if (shift_count < 64) { + abs = abs << shift_count; + } else { + abs = 0; + } + PACK_XFP(sign, 0x403e - shift_count, abs, result); +} + +/* + * Convert a float value to a decimal value. + */ +void xfp_to_decimal(XFP *a, DEC *d, RM rounding_mode) +{ + t_int64 tmp; + int i; + t_bool sign; + uint16 digits[19] = {0}; + + tmp = xfp_to_int64(a, rounding_mode); + + if (tmp < 0) { + sign = 0xb; + } else { + sign = 0xa; + } + + for (i = 0; i < 19; i++) { + digits[i] = tmp % 10; + tmp /= 10; + } + + d->l = sign; + d->l |= (t_uint64)digits[0] << 4; + d->l |= (t_uint64)digits[1] << 8; + d->l |= (t_uint64)digits[2] << 12; + d->l |= (t_uint64)digits[3] << 16; + d->l |= (t_uint64)digits[4] << 20; + d->l |= (t_uint64)digits[5] << 24; + d->l |= (t_uint64)digits[6] << 28; + d->l |= (t_uint64)digits[7] << 32; + d->l |= (t_uint64)digits[8] << 36; + d->l |= (t_uint64)digits[9] << 40; + d->l |= (t_uint64)digits[10] << 44; + d->l |= (t_uint64)digits[11] << 48; + d->l |= (t_uint64)digits[12] << 52; + d->l |= (t_uint64)digits[13] << 56; + d->l |= (t_uint64)digits[14] << 60; + d->h = (uint32)digits[15]; + d->h |= (uint32)digits[15] << 4; + d->h |= (uint32)digits[15] << 8; + + sim_debug(TRACE_DBG, &mau_dev, + "[xfp_to_decimal] " + "Digits: %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d 0x%x\n", + digits[17], digits[16], digits[15], digits[14], digits[13], digits[12], + digits[11], digits[10], digits[9], digits[8], digits[7], digits[6], + digits[5], digits[4], digits[3], digits[2], digits[1], digits[0], + sign); +} + +/* + * Convert a decimal value to a float value. + */ +void mau_decimal_to_xfp(DEC *d, XFP *a) +{ + int i; + t_bool sign; + uint16 digits[18] = {0}; + t_uint64 multiplier = 1; + t_uint64 tmp; + t_int64 signed_tmp; + + sim_debug(TRACE_DBG, &mau_dev, + "[mau_decimal_to_xfp] DEC input: %08x %08x %08x\n", + d->h, (uint32)(d->l >> 32), (uint32)(d->l)); + + sign = (d->l) & 15; + digits[0] = (d->l >> 4) & 15; + digits[1] = (d->l >> 8) & 15; + digits[2] = (d->l >> 12) & 15; + digits[3] = (d->l >> 16) & 15; + digits[4] = (d->l >> 20) & 15; + digits[5] = (d->l >> 24) & 15; + digits[6] = (d->l >> 28) & 15; + digits[7] = (d->l >> 32) & 15; + digits[8] = (d->l >> 36) & 15; + digits[9] = (d->l >> 40) & 15; + digits[10] = (d->l >> 44) & 15; + digits[11] = (d->l >> 48) & 15; + digits[12] = (d->l >> 52) & 15; + digits[13] = (d->l >> 56) & 15; + digits[14] = (d->l >> 60) & 15; + digits[15] = (d->h) & 15; + digits[16] = (d->h >> 4) & 15; + digits[17] = (d->h >> 8) & 15; + + sim_debug(TRACE_DBG, &mau_dev, + "[mau_decimal_to_xfp] " + "Digits: %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d 0x%x\n", + digits[17], digits[16], digits[15], digits[14], digits[13], digits[12], + digits[11], digits[10], digits[9], digits[8], digits[7], digits[6], + digits[5], digits[4], digits[3], digits[2], digits[1], digits[0], + sign); + + tmp = 0; + + for (i = 0; i < 18; i++) { + tmp += digits[i] * multiplier; + multiplier *= 10; + } + + switch (sign) { + case 0xd: + case 0xb: + /* Negative number */ + signed_tmp = -((t_int64) tmp); + break; + /* TODO: HANDLE NAN AND INFINITY */ + default: + signed_tmp = (t_int64) tmp; + } + + sim_debug(TRACE_DBG, &mau_dev, + "[mau_decimal_to_xfp] tmp val = %lld\n", + signed_tmp); + + mau_int64_to_xfp((t_uint64) signed_tmp, a); + + sim_debug(TRACE_DBG, &mau_dev, + "[mau_decimal_to_xfp] XFP = %04x%016llx\n", + a->sign_exp, a->frac); + +} + +/* + * Convert a floating point value to a 32-bit integer. + * + * Derived from the SoftFloat 2c package (see copyright notice above) + */ +uint32 xfp_to_int(XFP *val, RM rounding_mode) +{ + t_bool sign; + int32 exp, shift_count; + t_uint64 frac; + + sign = XFP_SIGN(val); + exp = XFP_EXP(val); + frac = XFP_FRAC(val); + + if ((exp == 0x7fff) && (t_uint64)(frac << 1)) { + sign = 0; + } + + shift_count = 0x4037 - exp; + + if (shift_count <= 0) { + shift_count = 1; + } + + shift_right_64_jamming(frac, shift_count, &frac); + + return round_pack_int(sign, frac, rounding_mode); +} + +/* + * Round an 80-bit extended precission floating-point value + * to an integer. + * + * Derived from the SoftFloat 2c library (see copyright notice above) + */ +void mau_round_xfp_to_int(XFP *val, XFP *result, RM rounding_mode) +{ + t_bool sign; + int32 exp; + t_uint64 last_bit_mask, round_bits_mask; + + exp = XFP_EXP(val); + + if (0x403e <= exp) { + if ((exp == 0x7fff) && (t_uint64)(XFP_FRAC(val) << 1)) { + propagate_xfp_nan(val, val, result); + return; + } + result->sign_exp = val->sign_exp; + result->frac = val->frac; + return; + } + if (exp < 0x3ff) { + if ((exp == 0) && ((t_uint64)(XFP_FRAC(val) << 1) == 0)) { + result->sign_exp = val->sign_exp; + result->frac = val->frac; + return; + } + mau_exc(MAU_ASR_PS, MAU_ASR_PM); + sign = XFP_SIGN(val); + switch (rounding_mode) { + case ROUND_NEAREST: + if (exp == 0x3ffe && (t_uint64)(XFP_FRAC(val) << 1)) { + PACK_XFP(sign, 0x3fff, 0x8000000000000000ull, result); + return; + } + break; + case ROUND_MINUS_INF: + if (sign) { + PACK_XFP(1, 0x3fff, 0x8000000000000000ull, result); + } else { + PACK_XFP(0, 0, 0, result); + } + return; + case ROUND_PLUS_INF: + if (sign) { + PACK_XFP(1, 0, 0, result); + } else { + PACK_XFP(0, 0x3fff, 0x8000000000000000ull, result); + } + return; + default: + /* Do nothing */ + break; + } + PACK_XFP(sign, 0, 0, result); + return; + } + + last_bit_mask = 1; + last_bit_mask <<= 0x403e - exp; + round_bits_mask = last_bit_mask - 1; + + result->sign_exp = val->sign_exp; + result->frac = val->frac; + + if (rounding_mode == ROUND_NEAREST) { + result->frac += last_bit_mask >> 1; + if ((result->frac & round_bits_mask) == 0) { + result->frac &= ~last_bit_mask; + } + } else if (rounding_mode != ROUND_ZERO) { + if (XFP_SIGN(result) ^ (rounding_mode == ROUND_PLUS_INF)) { + result->frac += round_bits_mask; + } + } + + result->frac &= ~round_bits_mask; + if (result->frac == 0) { + ++result->sign_exp; + result->frac = 0x8000000000000000ull; + } + + if (result->frac != val->frac) { + mau_exc(MAU_ASR_PS, MAU_ASR_PM); + } +} + +/***************************************************************************** + * Math Functions + ****************************************************************************/ + +/* + * Derived from the SoftFloat 2c package (see copyright notice above) + */ +static void xfp_add_fracs(XFP *a, XFP *b, t_bool sign, XFP *result, RM rounding_mode) +{ + int32 a_exp, b_exp, r_exp; + t_uint64 a_frac, b_frac, r_frac_0, r_frac_1; + int32 exp_diff; + + sim_debug(TRACE_DBG, &mau_dev, + "[ADD_FRACS] a=%04x%016llx b=%04x%016llx\n", + a->sign_exp, a->frac, + b->sign_exp, b->frac); + + a_exp = XFP_EXP(a); + a_frac = XFP_FRAC(a); + b_exp = XFP_EXP(b); + b_frac = XFP_FRAC(b); + + exp_diff = a_exp - b_exp; + if (0 < exp_diff) { + if (a_exp == 0x7fff) { + if ((t_uint64) (a_frac << 1)) { + propagate_xfp_nan(a, b, result); + return; + } + result->sign_exp = a->sign_exp; + result->frac = a->frac; + return; + } + if (b_exp == 0) { + --exp_diff; + } + shift_right_extra_64_jamming(b_frac, 0, exp_diff, &b_frac, &r_frac_1); + r_exp = a_exp; + } else if (exp_diff < 0) { + if (b_exp == 0x7fff) { + if ((t_uint64) (b_frac << 1)) { + propagate_xfp_nan(a, b, result); + return; + } + PACK_XFP(sign, 0x7fff, 0x8000000000000000ull, result); + return; + } + if (a_exp == 0) { + ++exp_diff; + } + + shift_right_extra_64_jamming(a_frac, 0, -exp_diff, &a_frac, &r_frac_1); + r_exp = b_exp; + } else { + if (a_exp == 0x7fff) { + if ((t_uint64)((a_frac | b_frac) << 1)) { + propagate_xfp_nan(a, b, result); + return; + } + result->sign_exp = a->sign_exp; + result->frac = a->frac; + return; + } + r_frac_1 = 0; + r_frac_0 = a_frac + b_frac; + if (a_exp == 0) { + normalize_xfp_subnormal(r_frac_0, &r_exp, &r_frac_0); + + round_pack_xfp(sign, r_exp, r_frac_0, r_frac_1, rounding_mode, result); + return; + } + r_exp = a_exp; + shift_right_extra_64_jamming(r_frac_0, r_frac_1, 1, &r_frac_0, &r_frac_1); + r_frac_0 |= 0x8000000000000000ull; + ++r_exp; + round_pack_xfp(sign, r_exp, r_frac_0, r_frac_1, rounding_mode, result); + return; + } + r_frac_0 = a_frac + b_frac; + if (((t_int64) r_frac_0) < 0) { + round_pack_xfp(sign, r_exp, r_frac_0, r_frac_1, rounding_mode, result); + return; + } + shift_right_extra_64_jamming(r_frac_0, r_frac_1, 1, &r_frac_0, &r_frac_1); + r_frac_0 |= 0x8000000000000000ull; + ++r_exp; + round_pack_xfp(sign, r_exp, r_frac_0, r_frac_1, rounding_mode, result); + return; +} + +/* + * Derived from the SoftFloat 2c package (see copyright notice above) + */ +static void xfp_sub_fracs(XFP *a, XFP *b, t_bool sign, XFP *result, RM rounding_mode) +{ + int32 a_exp, b_exp, r_exp; + t_uint64 a_frac, b_frac, r_frac_0, r_frac_1; + int32 exp_diff; + + a_exp = XFP_EXP(a); + a_frac = XFP_FRAC(a); + b_exp = XFP_EXP(b); + b_frac = XFP_FRAC(b); + exp_diff = a_exp - b_exp; + + if (0 < exp_diff) { + /* aExpBigger */ + if (a_exp == 0x7fff) { + if ((t_uint64)(a_frac << 1)) { + propagate_xfp_nan(a, b, result); + return; + } + result->sign_exp = a->sign_exp; + result->frac = a->frac; + return; + } + if (b_exp == 0) { + --exp_diff; + } + shift_right_128_jamming(b_frac, 0, exp_diff, &b_frac, &r_frac_1); + /* aBigger */ + sub_128(a_frac, 0, b_frac, r_frac_1, &r_frac_0, &r_frac_1); + r_exp = a_exp; + /* normalizeRoundAndPack */ + normalize_round_pack_xfp(sign, r_exp, r_frac_0, r_frac_1, rounding_mode, result); + return; + } + if (exp_diff < 0) { + /* bExpBigger */ + if (b_exp == 0x7fff) { + if ((t_uint64)(b_frac << 1)) { + propagate_xfp_nan(a, b, result); + return; + } + PACK_XFP(sign ? 0 : 1, 0x7fff, 0x8000000000000000ull, result); + return; + } + if (a_exp == 0) { + ++exp_diff; + } + shift_right_128_jamming(a_frac, 0, -exp_diff, &a_frac, &r_frac_1); + /* bBigger */ + sub_128(b_frac, 0, a_frac, r_frac_1, &r_frac_0, &r_frac_1); + r_exp = b_exp; + sign = sign ? 0 : 1; + /* normalizeRoundAndPack */ + normalize_round_pack_xfp(sign, r_exp, + r_frac_0, r_frac_1, + rounding_mode, result); + return; + } + if (a_exp == 0x7fff) { + if ((t_uint64)((a_frac | b_frac) << 1)) { + propagate_xfp_nan(a, b, result); + return; + } + mau_exc(MAU_ASR_IS, MAU_ASR_IM); /* Invalid */ + result->sign_exp = DEFAULT_XFP_NAN_SIGN_EXP; + result->frac = DEFAULT_XFP_NAN_FRAC; + return; + } + if (a_exp == 0) { + a_exp = 1; + b_exp = 1; + } + r_frac_1 = 0; + if (b_frac < a_frac) { + /* aBigger */ + sub_128(a_frac, 0, b_frac, r_frac_1, &r_frac_0, &r_frac_1); + r_exp = a_exp; + /* normalizeRoundAndPack */ + normalize_round_pack_xfp(sign, r_exp, + r_frac_0, r_frac_1, + rounding_mode, result); + return; + } + if (a_frac < b_frac) { + /* bBigger */ + sub_128(b_frac, 0, a_frac, r_frac_1, &r_frac_0, &r_frac_1); + r_exp = b_exp; + sign ^= 1; + + /* normalizeRoundAndPack */ + normalize_round_pack_xfp(sign, r_exp, + r_frac_0, r_frac_1, + rounding_mode, result); + return; + } + + PACK_XFP(rounding_mode == ROUND_MINUS_INF, 0, 0, result); +} + +/************************************************************************* + * + * MAU-specific functions + * + *************************************************************************/ + +/* + * Set condition flags based on comparison of the two values A and B. + * + * Derived from the SoftFloat 2c package (see copyright notice above) + */ +static void xfp_cmp(XFP *a, XFP *b) +{ + mau_state.asr &= ~(MAU_ASR_N|MAU_ASR_Z|MAU_ASR_UO); + + /* Page 5-9: + * + * "An invalid operation exception condition exists if either or + * both source operands are trapping NaNs. If the exception is + * masked then the UO flag would be set. However, if this + * exception is enabled, and, if Op1 is a trapping NaN, it is + * converted to double-extended precision and stored in DR. Else, + * Op2 (converted to double-extended precision, if necessary) is + * stored in DR." + */ + + if (XFP_IS_NAN(a) || XFP_IS_NAN(b)) { + if ((mau_state.asr & MAU_ASR_IM) == 0) { + mau_state.asr |= MAU_ASR_UO; + } else if (XFP_IS_NAN(a)) { + mau_state.dr.sign_exp = a->sign_exp; + mau_state.dr.frac = a->frac; + } else { + mau_state.dr.sign_exp = b->sign_exp; + mau_state.dr.frac = b->frac; + } + return; + } + + if (xfp_lt(a, b)) { + mau_state.asr |= MAU_ASR_N; + } + + if (xfp_eq(a, b)) { + mau_state.asr |= MAU_ASR_Z; + } +} + +static void xfp_cmpe(XFP *a, XFP *b) +{ + mau_state.asr &= ~(MAU_ASR_N|MAU_ASR_Z|MAU_ASR_UO); + + /* Page 5-10: + * + * "When two unordered values are compared, then, in additon to + * the response specified below, the invalid operation exception + * sticky flag (ASR = 1) is set and the trap invoked if the + * invalid operation exceptionis enabled."" + */ + + if ((XFP_IS_NAN(a) || XFP_IS_NAN(b)) && (mau_state.asr & MAU_ASR_IM)) { + mau_state.asr |= MAU_ASR_UO; + return; + } + + if (xfp_lt(a, b)) { + mau_state.asr |= MAU_ASR_N; + } + + if (xfp_eq(a, b)) { + mau_state.asr |= MAU_ASR_Z; + } +} + +static void xfp_cmps(XFP *a, XFP *b) +{ + mau_state.asr &= ~(MAU_ASR_N|MAU_ASR_Z|MAU_ASR_UO); + + if (XFP_IS_NAN(a) || XFP_IS_NAN(b)) { + if ((mau_state.asr & MAU_ASR_IM) == 0) { + mau_state.asr |= MAU_ASR_UO; + } else if (XFP_IS_NAN(a)) { + mau_state.dr.sign_exp = a->sign_exp; + mau_state.dr.frac = a->frac; + } else { + mau_state.dr.sign_exp = b->sign_exp; + mau_state.dr.frac = b->frac; + } + return; + } + + if (xfp_lt(a, b)) { + mau_state.asr |= MAU_ASR_Z; + } else if (xfp_eq(a, b)) { + mau_state.asr |= MAU_ASR_N; + } +} + +static void xfp_cmpes(XFP *a, XFP *b) +{ + mau_state.asr &= ~(MAU_ASR_N|MAU_ASR_Z|MAU_ASR_UO); + + if ((XFP_IS_NAN(a) || XFP_IS_NAN(b)) && (mau_state.asr & MAU_ASR_IM)) { + mau_state.asr |= MAU_ASR_UO; + return; + } + + if (xfp_lt(a, b)) { + mau_state.asr |= MAU_ASR_Z; + } + + if (xfp_eq(a, b)) { + mau_state.asr |= MAU_ASR_N; + } +} + +static void xfp_add(XFP *a, XFP *b, XFP *result, RM rounding_mode) +{ + uint32 a_sign, b_sign; + + a_sign = XFP_SIGN(a); + b_sign = XFP_SIGN(b); + + if (a_sign == b_sign) { + xfp_add_fracs(a, b, a_sign, result, rounding_mode); + } else { + xfp_sub_fracs(a, b, a_sign, result, rounding_mode); + } +} + +static void xfp_sub(XFP *a, XFP *b, XFP *result, RM rounding_mode) +{ + uint32 a_sign, b_sign; + + a_sign = XFP_SIGN(a); + b_sign = XFP_SIGN(b); + + if (a_sign == b_sign) { + xfp_sub_fracs(a, b, a_sign, result, rounding_mode); + } else { + xfp_add_fracs(a, b, a_sign, result, rounding_mode); + } +} + +/* + * Derived from the SoftFloat 2c package (see copyright notice above) + */ +static void xfp_mul(XFP *a, XFP *b, XFP *result, RM rounding_mode) +{ + uint32 a_sign, b_sign, r_sign; + int32 a_exp, b_exp, r_exp; + t_uint64 a_frac, b_frac, r_frac_0, r_frac_1; + + sim_debug(TRACE_DBG, &mau_dev, + "[MUL] op1=%04x%016llx op2=%04x%016llx\n", + a->sign_exp, a->frac, + b->sign_exp, b->frac); + + a_sign = XFP_SIGN(a); + a_exp = XFP_EXP(a); + a_frac = XFP_FRAC(a); + b_sign = XFP_SIGN(b); + b_exp = XFP_EXP(b); + b_frac = XFP_FRAC(b); + + r_sign = a_sign ^ b_sign; + + if (a_exp == 0x7fff) { + if ((t_uint64)(a_frac << 1) || ((b_exp == 0x7fff) && (t_uint64)(b_frac << 1))) { + propagate_xfp_nan(a, b, result); + return; + } + if ((b_exp | b_frac) == 0) { + /* invalid */ + mau_exc(MAU_ASR_IS, MAU_ASR_IM); + result->sign_exp = DEFAULT_XFP_NAN_SIGN_EXP; + result->frac = DEFAULT_XFP_NAN_FRAC; + return; + } + PACK_XFP(r_sign, 0x7fff, 0x8000000000000000ull, result); + return; + } + + if (b_exp == 0x7fff) { + if ((t_uint64)(b_frac << 1)) { + propagate_xfp_nan(a, b, result); + return; + } + if ((a_exp | a_frac) == 0) { + /* invalid */ + mau_exc(MAU_ASR_IS, MAU_ASR_IM); + result->sign_exp = DEFAULT_XFP_NAN_SIGN_EXP; + result->frac = DEFAULT_XFP_NAN_FRAC; + return; + } + PACK_XFP(r_sign, 0x7fff, 0x8000000000000000ull, result); + return; + } + + if (a_exp == 0) { + if (a_frac == 0) { + PACK_XFP(r_sign, 0, 0, result); + return; + } + normalize_xfp_subnormal(a_frac, &a_exp, &a_frac); + } + + if (b_exp == 0) { + if (b_frac == 0) { + PACK_XFP(r_sign, 0, 0, result); + return; + } + normalize_xfp_subnormal(b_frac, &b_exp, &b_frac); + } + + r_exp = a_exp + b_exp - 0x3ffe; + mul_64_to_128(a_frac, b_frac, &r_frac_0, &r_frac_1); + if (0 < (t_int64)r_frac_0) { + short_shift_left_128(r_frac_0, r_frac_1, 1, + &r_frac_0, &r_frac_1); + --r_exp; + } + + round_pack_xfp(r_sign, r_exp, r_frac_0, + r_frac_1, rounding_mode, result); +} + +/* + * Derived from the SoftFloat 2c package (see copyright notice above) + */ +static void xfp_div(XFP *a, XFP *b, XFP *result, RM rounding_mode) +{ + t_bool a_sign, b_sign, r_sign; + int32 a_exp, b_exp, r_exp; + t_uint64 a_frac, b_frac, r_frac0, r_frac1; + t_uint64 rem0, rem1, rem2, term0, term1, term2; + + sim_debug(TRACE_DBG, &mau_dev, + "[DIV] op1=%04x%016llx op2=%04x%016llx\n", + b->sign_exp, b->frac, a->sign_exp, a->frac); + + a_sign = XFP_SIGN(a); + a_exp = XFP_EXP(a); + a_frac = XFP_FRAC(a); + + b_sign = XFP_SIGN(b); + b_exp = XFP_EXP(b); + b_frac = XFP_FRAC(b); + + r_sign = a_sign ^ b_sign; + + if (a_exp == 0x7fff) { + if ((t_uint64)(a_frac << 1)) { + propagate_xfp_nan(a, b, result); + return; + } + + if (b_exp == 0x7fff) { + if ((t_uint64)(b_frac << 1)) { + propagate_xfp_nan(a, b, result); + return; + } + /* Invalid */ + mau_exc(MAU_ASR_IS, MAU_ASR_IM); + result->sign_exp = DEFAULT_XFP_NAN_SIGN_EXP; + result->frac = DEFAULT_XFP_NAN_FRAC; + return; + } + + PACK_XFP(r_sign, 0x7fff, 0x8000000000000000ull, result); + return; + } + + if (b_exp == 0x7fff) { + if ((t_uint64) (b_frac << 1)) { + propagate_xfp_nan(a, b, result); + return; + } + + PACK_XFP(r_sign, 0, 0, result); + return; + } + + if (b_exp == 0) { + if (b_frac == 0) { + if ((a_exp | b_frac) == 0) { + /* Invalid */ + mau_exc(MAU_ASR_IS, MAU_ASR_IM); + result->sign_exp = DEFAULT_XFP_NAN_SIGN_EXP; + result->frac = DEFAULT_XFP_NAN_FRAC; + return; + } + /* Divide by zero - SPECIAL CASE 4 */ + sim_debug(TRACE_DBG, &mau_dev, + "[DIV] Divide by zero detected.\n"); + mau_case_div_zero(a, b, result); + return; + } + normalize_xfp_subnormal(b_frac, &b_exp, &b_frac); + } + + if (a_exp == 0) { + if (a_frac == 0) { + PACK_XFP(r_sign, 0, 0, result); + return; + } + normalize_xfp_subnormal(a_frac, &a_exp, &a_frac); + } + + r_exp = a_exp - b_exp + 0x3ffe; + rem1 = 0; + if (b_frac <= a_frac) { + shift_right_128(a_frac, 0, 1, &a_frac, &rem1); + ++r_exp; + } + + r_frac0 = estimate_div_128_to_64(a_frac, rem1, b_frac); + mul_64_to_128(b_frac, r_frac0, &term0, &term1); + sub_128(a_frac, rem1, term0, term1, &rem0, &rem1); + + while ((t_int64) rem0 < 0) { + --r_frac0; + add_128(rem0, rem1, 0, b_frac, &rem0, &rem1); + } + + r_frac1 = estimate_div_128_to_64(rem1, 0, b_frac); + if ((t_uint64)(r_frac1 << 1) <= 8) { + mul_64_to_128(b_frac, r_frac1, &term1, &term2); + sub_128(rem1, 0, term1, term2, &rem1, &rem2); + while ((t_int64) rem1 < 0) { + --r_frac1; + add_128(rem1, rem2, 0, b_frac, &rem1, &rem2); + } + r_frac1 |= ((rem1 | rem2) != 0); + } + + round_pack_xfp(r_sign, r_exp, r_frac0, r_frac1, rounding_mode, result); +} + +/* + * Derived from the SoftFloat 2c package (see copyright notice above) + */ +static void xfp_sqrt(XFP *a, XFP *result, RM rounding_mode) +{ + XFP zero = {0, 0, 0}; + t_bool a_sign; + int32 a_exp, norm_exp, r_exp; + uint32 a_frac_32, sqrt_recip_32, r_frac_32; + t_uint64 a_frac, norm_frac, q, x64, z_frac, z_frac_extra; + t_mau_128 nan_128, rem, y, term; + + sim_debug(TRACE_DBG, &mau_dev, + "[SQRT] op1=%04x%016llx\n", + a->sign_exp, a->frac); + + a_sign = XFP_SIGN(a); + a_exp = XFP_EXP(a); + a_frac = XFP_FRAC(a); + + if (a_exp == 0x7fff) { + if ( a_frac & 0x7fffffffffffffffull ) { + propagate_xfp_nan_128(a, &zero, &nan_128); + result->sign_exp = (uint32) nan_128.high; + result->frac = nan_128.low; + return; + } + if ( ! a_sign ) { + result->sign_exp = a->sign_exp; + result->frac = a->frac; + } + /* Invalid */ + mau_exc(MAU_ASR_IS, MAU_ASR_IM); + result->sign_exp = DEFAULT_XFP_NAN_SIGN_EXP; + result->frac = DEFAULT_XFP_NAN_FRAC; + return; + } + + if (a_sign) { + if (!a_frac) { + PACK_XFP(a_sign, 0, 0, result); + return; + } + mau_exc(MAU_ASR_IS, MAU_ASR_IM); + result->sign_exp = DEFAULT_XFP_NAN_SIGN_EXP; + result->frac = DEFAULT_XFP_NAN_FRAC; + return; + } + + if (!a_exp) { + a_exp = 1; + } + + if (!(a_frac & 0x8000000000000000ull)) { + if (!a_frac) { + PACK_XFP(a_sign, 0, 0, result); + return; + } + normalize_xfp_subnormal(a->frac, &norm_exp, &norm_frac); + a_exp += norm_exp; + a_frac = norm_frac; + } + + /* + * r_frac_32 is guaranteed to be a lower bound on the square root of + * a_frac_32, which makes r_frac_32 also a lower bound on the square + * root of `a_frac'. + */ + r_exp = ((a_exp - 0x3FFF) >> 1) + 0x3FFF; + a_exp &= 1; + a_frac_32 = a_frac >> 32; + sqrt_recip_32 = approx_recip_sqrt_32(a_exp, a_frac_32); + r_frac_32 = ((t_uint64) a_frac_32 * sqrt_recip_32) >> 32; + + if (a_exp) { + r_frac_32 >>= 1; + short_shift_left_128(0, a_frac, 61, &rem.high, &rem.low); + } else { + short_shift_left_128(0, a_frac, 62, &rem.high, &rem.low); + } + + rem.high -= (t_uint64) r_frac_32 * r_frac_32; + + q = ((uint32) (rem.high >> 2) * (t_uint64) sqrt_recip_32) >> 32; + x64 = (t_uint64) r_frac_32 << 32; + z_frac = x64 + (q<<3); + short_shift_left_128(rem.high, rem.low, 29, &y.high, &y.low); + + /* Repeating this loop is a rare occurrence. */ + while(1) { + mul_64_by_shifted_32_to_128(x64 + z_frac, (uint32) q, &term); + sub_128(y.high, y.low, term.high, term.low, &rem.high, &rem.low); + if (!(rem.high & 0x8000000000000000ull)) { + break; + } + --q; + z_frac -= 1<<3; + } + + q = (((rem.high>>2) * sqrt_recip_32)>>32) + 2; + x64 = z_frac; + z_frac = (z_frac<<1) + (q>>25); + z_frac_extra = (t_uint64) (q<<39); + + if ( (q & 0xffffff) <= 2 ) { + q &= ~(t_uint64) 0xffff; + z_frac_extra = (t_uint64) (q<<39); + mul_64_by_shifted_32_to_128(x64 + (q >> 27), (uint32) q, &term); + x64 = (uint32) (q<<5) * (t_uint64) (uint32) q; + add_128(term.high, term.low, 0, x64, &term.high, &term.low); + short_shift_left_128(rem.high, rem.low, 28, &rem.high, &rem.low); + sub_128(rem.high, rem.low, term.high, term.low, &rem.high, &rem.low); + if (rem.high & 0x8000000000000000ull) { + if (!z_frac_extra ) { + --z_frac; + } + --z_frac_extra; + } else { + if (rem.high | rem.low) { + z_frac_extra |= 1; + } + } + } + + round_pack_xfp(0, r_exp, z_frac, z_frac_extra, rounding_mode,result); + return; +} + +static void xfp_remainder(XFP *a, XFP *b, XFP *result, RM rounding_mode) +{ + uint32 a_sign, r_sign; + int32 a_exp, b_exp, exp_diff; + t_uint64 a_frac_0, a_frac_1, b_frac; + t_uint64 q, term_0, term_1, alt_a_frac_0, alt_a_frac_1; + + a_sign = XFP_SIGN(a); + a_exp = XFP_EXP(a); + a_frac_0 = XFP_FRAC(a); + b_exp = XFP_EXP(b); + b_frac = XFP_FRAC(b); + + if (a_exp == 0x7fff) { + if ((t_uint64)(a_frac_0 << 1) || + ((b_exp == 0x7fff) && (t_uint64)(b_frac << 1))) { + propagate_xfp_nan(a, b, result); + return; + } + /* invalid */ + mau_exc(MAU_ASR_IS, MAU_ASR_IM); + result->sign_exp = DEFAULT_XFP_NAN_SIGN_EXP; + result->frac = DEFAULT_XFP_NAN_FRAC; + return; + } + + if (b_exp == 0x7fff) { + if ((t_uint64)(b_frac << 1)) { + propagate_xfp_nan(a, b, result); + } + result->sign_exp = a->sign_exp; + result->frac = a->frac; + return; + } + + if (b_exp == 0) { + if (b_frac == 0) { + /* invalid */ + mau_exc(MAU_ASR_IS, MAU_ASR_IM); + result->sign_exp = DEFAULT_XFP_NAN_SIGN_EXP; + result->frac = DEFAULT_XFP_NAN_FRAC; + return; + } + normalize_xfp_subnormal(b_frac, &b_exp, &b_frac); + } + + if (a_exp == 0) { + if ((t_uint64)(a_frac_0 << 1) == 0) { + result->sign_exp = a->sign_exp; + result->frac = a->frac; + return; + } + normalize_xfp_subnormal(a_frac_0, &a_exp, &a_frac_0); + } + + b_frac |= 0x8000000000000000ull; + r_sign = a_sign; + exp_diff = a_exp - b_exp; + a_frac_1 = 0; + if (exp_diff < 0) { + if (exp_diff < -1) { + result->sign_exp = a->sign_exp; + result->frac = a->frac; + return; + } + shift_right_128(a_frac_0, 0, 1, &a_frac_0, &a_frac_1); + exp_diff = 0; + } + + q = (b_frac <= a_frac_0); + + if (q) { + a_frac_0 -= b_frac; + } + + exp_diff -= 64; + + while (0 < exp_diff) { + q = estimate_div_128_to_64(a_frac_0, a_frac_1, b_frac); + q = (2 < q) ? q - 2 : 0; + mul_64_to_128(b_frac, q, &term_0, &term_1); + sub_128(a_frac_0, a_frac_1, term_0, term_1, &a_frac_0, &a_frac_1); + short_shift_left_128(a_frac_0, a_frac_1, 62, &a_frac_0, &a_frac_1); + exp_diff -= 62; + } + + exp_diff += 64; + + if (0 < exp_diff) { + q = estimate_div_128_to_64(a_frac_0, a_frac_1, b_frac); + q = (2 < q) ? q - 2 : 0; + q >>= 64 - exp_diff; + mul_64_to_128(b_frac, q << (64 - exp_diff), &term_0, &term_1); + sub_128(a_frac_0, a_frac_1, term_0, term_1, &a_frac_0, &a_frac_1); + short_shift_left_128(0, b_frac, 64 - exp_diff, &term_0, &term_1); + while (le_128(term_0, term_1, a_frac_0, a_frac_1)) { + ++q; + sub_128(a_frac_0, a_frac_1, term_0, term_1, &a_frac_0, &a_frac_1); + } + } else { + term_0 = b_frac; + term_1 = 0; + } + + sub_128(term_0, term_1, a_frac_0, a_frac_1, &alt_a_frac_0, &alt_a_frac_1); + + if (lt_128(alt_a_frac_0, alt_a_frac_1, a_frac_0, a_frac_1) || + (eq_128(alt_a_frac_0, alt_a_frac_1, a_frac_0, a_frac_1) && + (q & 1))) { + a_frac_0 = alt_a_frac_0; + a_frac_1 = alt_a_frac_1; + r_sign = r_sign ? 0 : 1; + } + + normalize_round_pack_xfp(r_sign, b_exp + exp_diff, + a_frac_0, a_frac_1, + rounding_mode, result); +} + +/* + * Load an extended precision 80-bit IEE-754 floating point value from + * memory or register, based on the operand's specification. + */ +static void load_src_op(uint8 op, XFP *xfp) +{ + DFP dfp; + SFP sfp; + + switch (op) { + case M_OP_F0: + xfp->sign_exp = mau_state.f0.sign_exp; + xfp->frac = mau_state.f0.frac; + break; + case M_OP_F1: + xfp->sign_exp = mau_state.f1.sign_exp; + xfp->frac = mau_state.f1.frac; + break; + case M_OP_F2: + xfp->sign_exp = mau_state.f2.sign_exp; + xfp->frac = mau_state.f2.frac; + break; + case M_OP_F3: + xfp->sign_exp = mau_state.f3.sign_exp; + xfp->frac = mau_state.f3.frac; + break; + case M_OP_MEM_SINGLE: + sfp = read_w(mau_state.src, ACC_AF, BUS_PER); + sfp_to_xfp(sfp, xfp); + break; + case M_OP_MEM_DOUBLE: + dfp = (t_uint64) read_w(mau_state.src + 4, ACC_AF, BUS_PER); + dfp |= ((t_uint64) read_w(mau_state.src, ACC_AF, BUS_PER)) << 32; + sim_debug(TRACE_DBG, &mau_dev, + "[load_src_op][DOUBLE] Loaded %016llx\n", + dfp); + dfp_to_xfp(dfp, xfp); + sim_debug(TRACE_DBG, &mau_dev, + "[load_src_op][DOUBLE] Expanded To %04x%016llx\n", + xfp->sign_exp, xfp->frac); + break; + case M_OP_MEM_TRIPLE: + xfp->frac = (t_uint64) read_w(mau_state.src + 8, ACC_AF, BUS_PER); + xfp->frac |= ((t_uint64) read_w(mau_state.src + 4, ACC_AF, BUS_PER)) << 32; + xfp->sign_exp = (uint32) read_w(mau_state.src, ACC_AF, BUS_PER); + break; + default: + break; + } +} + +/* + * Load OP1 as a DEC value. + */ +static void load_op1_decimal(DEC *d) +{ + uint32 low, mid, high; + + switch (mau_state.op1) { + case M_OP_MEM_TRIPLE: + low = read_w(mau_state.src + 8, ACC_AF, BUS_PER); + mid = read_w(mau_state.src + 4, ACC_AF, BUS_PER); + high = read_w(mau_state.src, ACC_AF, BUS_PER); + d->l = low; + d->l |= ((t_uint64) mid << 32); + d->h = high; + break; + default: + /* Invalid */ + mau_exc(MAU_ASR_IS, MAU_ASR_IM); + break; + } +} + +static void store_op3_int(uint32 val) +{ + switch(mau_state.op3) { + case M_OP3_F0_SINGLE: + mau_state.f0.sign_exp = 0; + mau_state.f0.frac = (t_uint64)val; + break; + case M_OP3_F1_SINGLE: + mau_state.f1.sign_exp = 0; + mau_state.f1.frac = (t_uint64)val; + break; + case M_OP3_F2_SINGLE: + mau_state.f2.sign_exp = 0; + mau_state.f2.frac = (t_uint64)val; + break; + case M_OP3_F3_SINGLE: + mau_state.f3.sign_exp = 0; + mau_state.f3.frac = (t_uint64)val; + break; + case M_OP3_MEM_SINGLE: + write_w(mau_state.dst, val, BUS_PER); + break; + default: + /* Indeterminate output, unsupported */ + break; + } + + mau_state.dr.sign_exp = 0; + mau_state.dr.frac = (t_uint64)val; +} + +static void store_op3_decimal(DEC *d) +{ + + switch(mau_state.op3) { + case M_OP3_MEM_TRIPLE: + write_w(mau_state.dst, d->h, BUS_PER); + write_w(mau_state.dst + 4, (uint32)((t_uint64)d->l >> 32), BUS_PER); + write_w(mau_state.dst + 8, (uint32)d->l, BUS_PER); + break; + default: + /* Unsupported */ + return; + } + + mau_state.dr.sign_exp = d->h; + mau_state.dr.frac = ((t_uint64)d->l >> 32) | (t_uint64)d->l; +} + +static void store_op3_reg(XFP *xfp, XFP *reg) +{ + DFP dfp; + SFP sfp; + XFP xfp_r; + + if (mau_state.ntnan) { + reg->sign_exp = GEN_NONTRAPPING_NAN.sign_exp; + reg->frac = GEN_NONTRAPPING_NAN.frac; + } else { + switch(mau_state.op3) { + case M_OP3_F0_SINGLE: + case M_OP3_F1_SINGLE: + case M_OP3_F2_SINGLE: + case M_OP3_F3_SINGLE: + sfp = xfp_to_sfp(xfp, MAU_RM); + sfp_to_xfp(sfp, &xfp_r); + reg->sign_exp = xfp_r.sign_exp; + reg->frac = xfp_r.frac; + reg->s = xfp_r.s; + break; + case M_OP3_F0_DOUBLE: + case M_OP3_F1_DOUBLE: + case M_OP3_F2_DOUBLE: + case M_OP3_F3_DOUBLE: + dfp = xfp_to_dfp(xfp, MAU_RM); + dfp_to_xfp(dfp, &xfp_r); + reg->sign_exp = xfp_r.sign_exp; + reg->frac = xfp_r.frac; + reg->s = xfp_r.s; + break; + case M_OP3_F0_TRIPLE: + case M_OP3_F1_TRIPLE: + case M_OP3_F2_TRIPLE: + case M_OP3_F3_TRIPLE: + reg->sign_exp = xfp->sign_exp; + reg->frac = xfp->frac; + reg->s = xfp->s; + break; + } + } + if (set_nz()) { + if (XFP_SIGN(xfp)) { + mau_state.asr |= MAU_ASR_N; + } + if (XFP_EXP(xfp) == 0 && XFP_FRAC(xfp) == 0) { + mau_state.asr |= MAU_ASR_Z; + } + } +} + +static void store_op3(XFP *xfp) +{ + DFP dfp; + SFP sfp; + t_bool store_dr = FALSE; + + sim_debug(TRACE_DBG, &mau_dev, + "[store_op3] op3=%04x%016llx\n", + xfp->sign_exp, + xfp->frac); + + switch (mau_state.opcode) { + case M_ADD: + case M_SUB: + case M_MUL: + case M_DIV: + store_dr = TRUE; + break; + default: + break; + } + + switch (mau_state.op3) { + case M_OP3_F0_SINGLE: + case M_OP3_F0_DOUBLE: + case M_OP3_F0_TRIPLE: + store_op3_reg(xfp, &mau_state.f0); + break; + case M_OP3_F1_SINGLE: + case M_OP3_F1_DOUBLE: + case M_OP3_F1_TRIPLE: + store_op3_reg(xfp, &mau_state.f1); + break; + case M_OP3_F2_SINGLE: + case M_OP3_F2_DOUBLE: + case M_OP3_F2_TRIPLE: + store_op3_reg(xfp, &mau_state.f2); + break; + case M_OP3_F3_SINGLE: + case M_OP3_F3_DOUBLE: + case M_OP3_F3_TRIPLE: + store_op3_reg(xfp, &mau_state.f3); + break; + case M_OP3_MEM_SINGLE: + if (mau_state.ntnan) { + sfp = xfp_to_sfp(&GEN_NONTRAPPING_NAN, MAU_RM); + } else { + sfp = xfp_to_sfp(xfp, MAU_RM); + } + if (set_nz()) { + if (SFP_SIGN(sfp)) { + mau_state.asr |= MAU_ASR_N; + } + if (SFP_EXP(sfp) == 0 && SFP_FRAC(sfp) == 0) { + mau_state.asr |= MAU_ASR_Z; + } + } + write_w(mau_state.dst, (uint32)sfp, BUS_PER); + break; + case M_OP3_MEM_DOUBLE: + if (mau_state.ntnan) { + dfp = xfp_to_dfp(&GEN_NONTRAPPING_NAN, MAU_RM); + } else { + dfp = xfp_to_dfp(xfp, MAU_RM); + } + if (store_dr) { + mau_state.dr.sign_exp = ((uint16)(DFP_SIGN(dfp)) << 15) | (uint16)(DFP_EXP(dfp)); + mau_state.dr.frac = (t_uint64)(DFP_FRAC(dfp)); + if (DFP_EXP(dfp)) { + /* If the number is normalized, add the implicit + normalized bit 52 */ + mau_state.dr.frac |= ((t_uint64)1 << 52); + } + } + if (set_nz()) { + if (DFP_SIGN(dfp)) { + mau_state.asr |= MAU_ASR_N; + } + if (DFP_EXP(dfp) == 0 && DFP_FRAC(dfp) == 0) { + mau_state.asr |= MAU_ASR_Z; + } + } + write_w(mau_state.dst, (uint32)(dfp >> 32), BUS_PER); + write_w(mau_state.dst + 4, (uint32)(dfp), BUS_PER); + break; + case M_OP3_MEM_TRIPLE: + if (mau_state.ntnan) { + write_w(mau_state.dst, (uint32)(GEN_NONTRAPPING_NAN.sign_exp), BUS_PER); + write_w(mau_state.dst + 4, (uint32)(GEN_NONTRAPPING_NAN.frac >> 32), BUS_PER); + write_w(mau_state.dst + 8, (uint32)(GEN_NONTRAPPING_NAN.frac), BUS_PER); + } else { + write_w(mau_state.dst, (uint32)(xfp->sign_exp), BUS_PER); + write_w(mau_state.dst + 4, (uint32)(xfp->frac >> 32), BUS_PER); + write_w(mau_state.dst + 8, (uint32)(xfp->frac), BUS_PER); + } + if (set_nz()) { + if (XFP_SIGN(xfp)) { + mau_state.asr |= MAU_ASR_N; + } + if (XFP_EXP(xfp) == 0 && XFP_FRAC(xfp) == 0) { + mau_state.asr |= MAU_ASR_Z; + } + } + break; + default: + sim_debug(TRACE_DBG, &mau_dev, + "[store_op3] WARNING: Unhandled destination: %02x\n", mau_state.op3); + break; + } +} + +/************************************************************************* + * + * MAU instruction impelementations + * + *************************************************************************/ + +static void mau_rdasr() +{ + switch (mau_state.op3) { + /* Handled */ + case M_OP3_MEM_SINGLE: + write_w(mau_state.dst, mau_state.asr, BUS_PER); + break; + case M_OP3_MEM_DOUBLE: + write_w(mau_state.dst, mau_state.asr, BUS_PER); + write_w(mau_state.dst + 4, mau_state.asr, BUS_PER); + break; + case M_OP3_MEM_TRIPLE: + write_w(mau_state.dst, mau_state.asr, BUS_PER); + write_w(mau_state.dst + 4, mau_state.asr, BUS_PER); + write_w(mau_state.dst + 8, mau_state.asr, BUS_PER); + break; + /* Unhandled */ + default: + sim_debug(TRACE_DBG, &mau_dev, + "[mau_rdasr] WARNING: Unhandled source: %02x\n", + mau_state.op3); + break; + } +} + +static void mau_wrasr() +{ + switch (mau_state.op1) { + /* Handled */ + case M_OP_MEM_SINGLE: + mau_state.asr = read_w(mau_state.src, ACC_AF, BUS_PER); + sim_debug(TRACE_DBG, &mau_dev, + "[WRASR] Writing ASR with: %08x\n", + mau_state.asr); + break; + default: + sim_debug(TRACE_DBG, &mau_dev, + "[mau_wrasr] WARNING: Unhandled source: %02x\n", + mau_state.op3); + break; + } +} + +/* + * OP3 = OP1 + */ +static void mau_move() +{ + XFP xfp = {0}; + + load_src_op(mau_state.op1, &xfp); + store_op3(&xfp); +} + +static void mau_cmp() +{ + XFP a, b; + + load_src_op(mau_state.op1, &a); + load_src_op(mau_state.op2, &b); + xfp_cmp(&a, &b); +} + +static void mau_cmps() +{ + XFP a, b; + + load_src_op(mau_state.op1, &a); + load_src_op(mau_state.op2, &b); + xfp_cmps(&a, &b); +} + +static void mau_cmpe() +{ + XFP a, b; + + load_src_op(mau_state.op1, &a); + load_src_op(mau_state.op2, &b); + xfp_cmpe(&a, &b); +} + +static void mau_cmpes() +{ + XFP a, b; + + load_src_op(mau_state.op1, &a); + load_src_op(mau_state.op2, &b); + xfp_cmpes(&a, &b); +} + +static void mau_ldr() +{ + XFP xfp; + + load_src_op(mau_state.op1, &xfp); + sim_debug(TRACE_DBG, &mau_dev, + "[LDR] Loading DR with %04x%016llx\n", + xfp.sign_exp, xfp.frac); + mau_state.dr.sign_exp = xfp.sign_exp; + mau_state.dr.frac = xfp.frac; +} + +static void mau_erof() +{ + DFP dfp; + SFP sfp; + + switch (mau_state.op3) { + case M_OP3_F0_SINGLE: + case M_OP3_F0_DOUBLE: + case M_OP3_F0_TRIPLE: + mau_state.f0.sign_exp = mau_state.dr.sign_exp; + mau_state.f0.frac = mau_state.dr.frac; + return; + case M_OP3_F1_SINGLE: + case M_OP3_F1_DOUBLE: + case M_OP3_F1_TRIPLE: + mau_state.f1.sign_exp = mau_state.dr.sign_exp; + mau_state.f1.frac = mau_state.dr.frac; + return; + case M_OP3_F2_SINGLE: + case M_OP3_F2_DOUBLE: + case M_OP3_F2_TRIPLE: + mau_state.f2.sign_exp = mau_state.dr.sign_exp; + mau_state.f2.frac = mau_state.dr.frac; + return; + case M_OP3_F3_SINGLE: + case M_OP3_F3_DOUBLE: + case M_OP3_F3_TRIPLE: + mau_state.f3.sign_exp = mau_state.dr.sign_exp; + mau_state.f3.frac = mau_state.dr.frac; + return; + case M_OP3_MEM_SINGLE: + sfp = xfp_to_sfp(&(mau_state.dr), MAU_RM); + write_w(mau_state.dst, (uint32)sfp, BUS_PER); + return; + case M_OP3_MEM_DOUBLE: + dfp = xfp_to_dfp(&(mau_state.dr), MAU_RM); + write_w(mau_state.dst + 4, (uint32)(dfp >> 32), BUS_PER); + write_w(mau_state.dst, (uint32)(dfp), BUS_PER); + return; + case M_OP3_MEM_TRIPLE: + write_w(mau_state.dst, (uint32)(mau_state.dr.sign_exp), BUS_PER); + write_w(mau_state.dst + 4, (uint32)(mau_state.dr.frac >> 32), BUS_PER); + write_w(mau_state.dst + 8, (uint32)(mau_state.dr.frac), BUS_PER); + return; + default: + sim_debug(TRACE_DBG, &mau_dev, + "[mau_erof] WARNING: Unhandled destination: %02x\n", mau_state.op3); + return; + } +} + + +static void mau_rtoi() +{ + XFP a, result; + + load_src_op(mau_state.op1, &a); + mau_round_xfp_to_int(&a, &result, MAU_RM); + store_op3(&result); +} + +static void mau_ftoi() +{ + XFP a; + uint32 result; + + load_src_op(mau_state.op1, &a); + result = xfp_to_int(&a, MAU_RM); + store_op3_int(result); +} + +static void mau_dtof() +{ + DEC d; + XFP result; + + load_op1_decimal(&d); + mau_decimal_to_xfp(&d, &result); + store_op3(&result); +} + +static void mau_ftod() +{ + XFP a; + DEC d; + + load_src_op(mau_state.op1, &a); + xfp_to_decimal(&a, &d, MAU_RM); + store_op3_decimal(&d); +} + +static void mau_add() +{ + XFP a, b, result; + + load_src_op(mau_state.op1, &a); + load_src_op(mau_state.op2, &b); + xfp_add(&a, &b, &result, MAU_RM); + store_op3(&result); +} + +/* + * OP3 = OP2 - OP1 + */ +static void mau_sub() +{ + XFP a, b, result; + + load_src_op(mau_state.op1, &a); + load_src_op(mau_state.op2, &b); + xfp_sub(&b, &a, &result, MAU_RM); + store_op3(&result); +} + +/* + * OP3 = OP1 * OP2 + */ +static void mau_mul() +{ + XFP a, b, result; + + load_src_op(mau_state.op1, &a); + load_src_op(mau_state.op2, &b); + xfp_mul(&b, &a, &result, MAU_RM); + store_op3(&result); +} + +/* + * OP3 = OP1 / OP2 + */ +static void mau_div() +{ + XFP a, b, result; + + load_src_op(mau_state.op1, &a); + load_src_op(mau_state.op2, &b); + sim_debug(TRACE_DBG, &mau_dev, + "[DIV OP2/OP1] OP2=0x%04x%016llx OP1=0x%04x%016llx\n", + b.sign_exp, b.frac, + a.sign_exp, a.frac); + xfp_div(&b, &a, &result, MAU_RM); + store_op3(&result); +} + +static void mau_neg() +{ + XFP a, result; + + load_src_op(mau_state.op1, &a); + result.sign_exp = a.sign_exp; + result.frac = a.frac; + result.sign_exp ^= 0x8000; + result.s = a.s; + store_op3(&result); +} + +static void mau_abs() +{ + XFP a, result; + + load_src_op(mau_state.op1, &a); + result.sign_exp = a.sign_exp; + result.frac = a.frac; + result.sign_exp &= 0x7fff; + result.s = a.s; + store_op3(&result); +} + +/* + * OP3 = sqrt(OP1) + */ +static void mau_sqrt() +{ + XFP a, result; + + load_src_op(mau_state.op1, &a); + xfp_sqrt(&a, &result, MAU_RM); + store_op3(&result); +} + +/* + * OP3 = float(OP1) + * + * If the source operand is more than one word wide, only the last + * word is converted. + */ +static void mau_itof() +{ + XFP xfp; + int32 val = 0; + + mau_state.asr &= ~(MAU_ASR_N|MAU_ASR_Z); + + switch(mau_state.op1) { + case M_OP_F0: + case M_OP_F1: + case M_OP_F2: + case M_OP_F3: + mau_exc(MAU_ASR_IS, MAU_ASR_IM); + return; + case M_OP_MEM_SINGLE: + val = read_w(mau_state.src, ACC_AF, BUS_PER); + break; + case M_OP_MEM_DOUBLE: + val = read_w(mau_state.src + 4, ACC_AF, BUS_PER); + break; + case M_OP_MEM_TRIPLE: + val = read_w(mau_state.src + 8, ACC_AF, BUS_PER); + break; + default: + break; + } + /* Convert */ + mau_int_to_xfp(val, &xfp); + + store_op3(&xfp); +} + +/* + * OP3 = REMAINDER(b/a) + */ +static void mau_remainder() +{ + XFP a, b, result; + + load_src_op(mau_state.op1, &a); + load_src_op(mau_state.op2, &b); + xfp_remainder(&b, &a, &result, MAU_RM); + store_op3(&result); +} + +/* + * Decode the command word into its corresponding parts. Both src and + * dst are optional depending on the WE32100 operand, and may be set + * to any value if not used. + */ +static SIM_INLINE void mau_decode(uint32 cmd, uint32 src, uint32 dst) +{ + mau_state.cmd = cmd; + mau_state.src = src; + mau_state.dst = dst; + mau_state.opcode = (uint8) ((cmd & 0x7c00) >> 10); + mau_state.op1 = (uint8) ((cmd & 0x0380) >> 7); + mau_state.op2 = (uint8) ((cmd & 0x0070) >> 4); + mau_state.op3 = (uint8) (cmd & 0x000f); + sim_debug(DECODE_DBG, &mau_dev, + "opcode=%s (%02x) op1=%s op2=%s op3=%s\n", + mau_op_names[mau_state.opcode], + mau_state.opcode, + src_op_names[mau_state.op1 & 0x7], + src_op_names[mau_state.op2 & 0x7], + dst_op_names[mau_state.op3 & 0xf]); +} + +/* + * Handle a command. + */ +static void mau_execute() +{ + clear_asr(); + + switch(mau_state.opcode) { + case M_NOP: + /* Do nothing */ + break; + case M_ADD: + mau_add(); + break; + case M_SUB: + mau_sub(); + break; + case M_MUL: + mau_mul(); + break; + case M_DIV: + mau_div(); + break; + case M_RDASR: + mau_rdasr(); + break; + case M_WRASR: + mau_wrasr(); + break; + case M_MOVE: + mau_move(); + break; + case M_LDR: + mau_ldr(); + break; + case M_ITOF: + mau_itof(); + break; + case M_EROF: + mau_erof(); + break; + case M_RTOI: + mau_rtoi(); + break; + case M_FTOI: + mau_ftoi(); + break; + case M_CMP: + mau_cmp(); + break; + case M_CMPS: + mau_cmps(); + break; + case M_CMPE: + mau_cmpe(); + break; + case M_CMPES: + mau_cmpes(); + break; + case M_REM: + mau_remainder(); + break; + case M_NEG: + mau_neg(); + break; + case M_ABS: + mau_abs(); + break; + case M_SQRT: + mau_sqrt(); + break; + case M_FTOD: + mau_ftod(); + break; + case M_DTOF: + mau_dtof(); + break; + default: + sim_debug(TRACE_DBG, &mau_dev, + "[execute] unhandled opcode %s [0x%02x]\n", + mau_op_names[mau_state.opcode], + mau_state.opcode); + break; + } + + /* If an error has occured, abort */ + abort_on_fault(); + + /* Copy the N, Z, V and C (from PS) flags over to the CPU's PSW */ + R[NUM_PSW] &= ~(MAU_ASR_N|MAU_ASR_Z|MAU_ASR_IO|MAU_ASR_PS); + R[NUM_PSW] |= (mau_state.asr & (MAU_ASR_N|MAU_ASR_Z|MAU_ASR_IO|MAU_ASR_PS)); + + /* Set the RA and CSC flags in the ASR */ + mau_state.asr |= MAU_ASR_RA; + if (mau_state.opcode != M_RDASR && mau_state.opcode != M_LDR) { + mau_state.asr |= MAU_ASR_CSC; + } +} + +/* + * Receive a broadcast from the CPU, and potentially handle it. + */ +t_stat mau_broadcast(uint32 cmd, uint32 src, uint32 dst) +{ + uint8 id = (uint8) ((cmd & 0xff000000) >> 24); + + /* If the MAU isn't attached, or if this message isn't for us, + * return SCPE_NXM. Otherwise, decode and act on the command. */ + if (id != MAU_ID) { + sim_debug(DECODE_DBG, &mau_dev, + "[broadcast] Message for coprocessor id %d is not for MAU (%d)\n", + id, MAU_ID); + return SCPE_NXM; + } else if (mau_dev.flags & DEV_DIS) { + sim_debug(DECODE_DBG, &mau_dev, + "[broadcast] Message for MAU, but MAU is not attached.\n"); + return SCPE_NOATT; + } else { + mau_decode(cmd, src, dst); + mau_execute(); + return SCPE_OK; + } +} + +CONST char *mau_description(DEVICE *dptr) +{ +#if defined(REV3) + return "WE 32106 MAU"; +#else + return "WE 32206 MAU"; +#endif +} diff --git a/3B2/3b2_mau.h b/3B2/3b2_mau.h index fc5589a8..6320df42 100644 --- a/3B2/3b2_mau.h +++ b/3B2/3b2_mau.h @@ -1,37 +1,389 @@ -/* 3b2_mau.h: Common CSR header - - Copyright (c) 2021, Seth J. Morabito - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - - Except as contained in this notice, the name of the author shall - not be used in advertising or otherwise to promote the sale, use or - other dealings in this Software without prior written authorization - from the author. -*/ - -#ifndef _3B2_MAU_H_ -#define _3B2_MAU_H_ - -/* TODO: Update when rev3 mau is implemented */ -#include "3b2_rev2_mau.h" - -#endif /* _3B2_MAU_H */ +/* 3b2_mau.h: WE32106 and WE32206 Math Accelerator Unit + + Copyright (c) 2021-2022, Seth J. Morabito + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + Except as contained in this notice, the name of the author shall + not be used in advertising or otherwise to promote the sale, use or + other dealings in this Software without prior written authorization + from the author. + + --------------------------------------------------------------------- + + This file is part of a simulation of the WE 32106 and WE 32206 Math + Acceleration Units. The WE 32106 and WE 32206 are IEEE-754 + compabitle floating point hardware math accelerators that were + available as an optional component on the AT&T 3B2/310 and 3B2/400, + and as a standard component on the 3B2/500, 3B2/600, 3B2/700, and + 3B2/1000. + + Portions of this code are derived from the SoftFloat 2c library by + John R. Hauser. Functions derived from SoftFloat 2c are clearly + marked in the comments. + + Legal Notice + ============ + + SoftFloat was written by John R. Hauser. Release 2c of SoftFloat + was made possible in part by the International Computer Science + Institute, located at Suite 600, 1947 Center Street, Berkeley, + California 94704. Funding was partially provided by the National + Science Foundation under grant MIP-9311980. The original version + of this code was written as part of a project to build a + fixed-point vector processor in collaboration with the University + of California at Berkeley, overseen by Profs. Nelson Morgan and + John Wawrzynek. + + THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable + effort has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS + THAT WILL AT TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS + SOFTWARE IS RESTRICTED TO PERSONS AND ORGANIZATIONS WHO CAN AND + WILL TOLERATE ALL LOSSES, COSTS, OR OTHER PROBLEMS THEY INCUR DUE + TO THE SOFTWARE WITHOUT RECOMPENSE FROM JOHN HAUSER OR THE + INTERNATIONAL COMPUTER SCIENCE INSTITUTE, AND WHO FURTHERMORE + EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER + SCIENCE INSTITUTE (possibly via similar legal notice) AGAINST ALL + LOSSES, COSTS, OR OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND + CLIENTS DUE TO THE SOFTWARE, OR INCURRED BY ANYONE DUE TO A + DERIVATIVE WORK THEY CREATE USING ANY PART OF THE SOFTWARE. + + The following are expressly permitted, even for commercial + purposes: + + (1) distribution of SoftFloat in whole or in part, as long as this + and other legal notices remain and are prominent, and provided also + that, for a partial distribution, prominent notice is given that it + is a subset of the original; and + + (2) inclusion or use of SoftFloat in whole or in part in a + derivative work, provided that the use restrictions above are met + and the minimal documentation requirements stated in the source + code are satisfied. + --------------------------------------------------------------------- + + Data Types + ========== + + The WE32106 MAU stores values using IEEE-754 1985 types, plus a + non-standard Decimal type. + + - Decimal Type - 18 BCD digits long. Each digit is 4 bits wide. + Sign is encoded in byte 0. + + 3322 2222 2222 1111 1111 1100 0000 0000 + 1098 7654 3210 9876 5432 1098 7654 3210 + +-------------------+----+----+----+----+ + | unused | D18| D17| D16| D15| High Word + +----+----+----+----+----+----+----+----+ + | D14| D13| D12| D11| D10| D09| D08| D07| Middle Word + +----+----+----+----+----+----+----+----+ + | D06| D05| D04| D03| D02| D01| D00|sign| Low Word + +----+----+----+----+----+----+----+----+ + + Sign: 0: Positive Infinity 10: Positive Number + 1: Negative Infinity 11: Negative Number + 2: Positive NaN 12: Positive Number + 3: Negative NaN 13: Negative Number + 4-9: Trapping NaN 14-15: Positive Number + + - Extended Precision (80-bit) - exponent biased by 16383 + + 3 322222222221111 1 111110000000000 + 1 098765432109876 5 432109876543210 + +-----------------+-+---------------+ + | unused |S| Exponent | High Word + +-+---------------+-+---------------+ + |J| Fraction (high word) | Middle Word + +-+---------------------------------+ + | Fraction (low word) | Low Word + +-----------------------------------+ + + + - Double Precision (64-bit) - exponent biased by 1023 + + 3 3222222222 211111111110000000000 + 1 0987654321 098765432109876543210 + +-+----------+---------------------+ + |S| Exponent | Fraction (high) | High Word + +-+----------+---------------------+ + | Fraction (low) | Low Word + +----------------------------------+ + + + - Single Precision (32-bit) - exponent biased by 127 + + 3 32222222 22211111111110000000000 + 1 09876543 21098765432109876543210 + +-+--------+-----------------------+ + |S| Exp | Fraction | + +-+--------+-----------------------+ + +*/ + +#ifndef _3B2_REV2_MAU_H_ +#define _3B2_REV2_MAU_H_ + +#include "sim_defs.h" + +#define SRC_LEN_INVALID 0 +#define SRC_LEN_SINGLE 1 +#define SRC_LEN_DOUBLE 2 +#define SRC_LEN_TRIPLE 3 + +#define MAU_ASR_RC_SHIFT 22 + +#define MAU_ASR_PR 0x20u /* Partial Remainder */ +#define MAU_ASR_QS 0x40u /* Divide By Zero Sticky */ +#define MAU_ASR_US 0x80u /* Underflow Sticky */ +#define MAU_ASR_OS 0x100u /* Overflow Sticky */ +#define MAU_ASR_IS 0x200u /* Invalid Operation Sticky */ +#define MAU_ASR_PM 0x400u /* Inexact Mask */ +#define MAU_ASR_QM 0x800u /* Divide by Zero Mask */ +#define MAU_ASR_UM 0x1000u /* Underflow Mask */ +#define MAU_ASR_OM 0x2000u /* Overflow Mask */ +#define MAU_ASR_IM 0x4000u /* Invalid Operation Mask */ + +#define MAU_ASR_UO 0x10000u /* Unordered */ +#define MAU_ASR_CSC 0x20000u /* Context Switch Control */ +#define MAU_ASR_PS 0x40000u /* Inexact Sticky */ +#define MAU_ASR_IO 0x80000u /* Integer Overflow */ +#define MAU_ASR_Z 0x100000u /* Zero Flag */ +#define MAU_ASR_N 0x200000u /* Negative Flag */ +#define MAU_ASR_RC 0x400000u /* Round Control */ + +#define MAU_ASR_NTNC 0x1000000u /* Nontrapping NaN Control */ +#define MAU_ASR_ECP 0x2000000u /* Exception Condition */ + +#define MAU_ASR_RA 0x80000000u /* Result Available */ + +#if defined(REV3) +#define MAU_ASR_FE 0x1u /* Feature Enable */ +#define MAU_ASR_VER 0x2u /* Version */ +#define MAU_ASR_UW 0x10u /* Unaligned Word */ +#define MAU_ASR_WF 0x8000u /* Write Fault Indicator */ +#define MAU_RC_RN 0 /* Round toward Nearest */ +#define MAU_RC_RP 1 /* Round toward Plus Infin. */ +#define MAU_RC_RM 2 /* Round toward Neg. Infin. */ +#define MAU_RC_RZ 3 /* Round toward Zero */ +#endif + +#define SFP_SIGN(V) (((V) >> 31) & 1) +#define SFP_EXP(V) (((V) >> 23) & 0xff) +#define SFP_FRAC(V) ((V) & 0x7fffff) + +#define DFP_SIGN(V) (((V) >> 63) & 1) +#define DFP_EXP(V) (((V) >> 52) & 0x7ff) +#define DFP_FRAC(V) ((V) & 0xfffffffffffffull) + +#define XFP_SIGN(V) (((V)->sign_exp >> 15) & 1) +#define XFP_EXP(V) ((V)->sign_exp & 0x7fff) +#define XFP_FRAC(V) ((V)->frac) + +#define XFP_IS_NORMAL(V) ((V)->frac & 0x8000000000000000ull) + +#define DEFAULT_XFP_NAN_SIGN_EXP 0xffff +#define DEFAULT_XFP_NAN_FRAC 0xc000000000000000ull + +#define SFP_IS_TRAPPING_NAN(V) (((((V) >> 22) & 0x1ff) == 0x1fe) && \ + ((V) & 0x3fffff)) +#define DFP_IS_TRAPPING_NAN(V) (((((V) >> 51) & 0xfff) == 0xffe) && \ + ((V) & 0x7ffffffffffffull)) +#define XFP_IS_NAN(V) ((((V)->sign_exp & 0x7fff) == 0x7fff) && \ + (t_uint64)((V)->frac << 1)) +#define XFP_IS_TRAPPING_NAN(V) ((((V)->sign_exp) & 0x7fff) && \ + ((((V)->frac) & ~(0x4000000000000000ull)) << 1) && \ + (((V)->frac) == ((V)->frac & ~(0x4000000000000000ull)))) +#define PACK_DFP(SIGN,EXP,FRAC) ((((t_uint64)(SIGN))<<63) + \ + (((t_uint64)(EXP))<<52) + \ + ((t_uint64)(FRAC))) +#define PACK_SFP(SIGN,EXP,FRAC) (((uint32)(SIGN)<<31) + \ + ((uint32)(EXP)<<23) + \ + ((uint32)(FRAC))) +#define PACK_XFP(SIGN,EXP,FRAC,V) do { \ + (V)->frac = (FRAC); \ + (V)->sign_exp = ((uint16)(SIGN) << 15) + (EXP); \ + (V)->s = FALSE; \ + } while (0) + +#define PACK_XFP_S(SIGN,EXP,FRAC,S,V) do { \ + (V)->frac = (FRAC); \ + (V)->sign_exp = ((uint16)(SIGN) << 15) + (EXP); \ + (V)->s = (S) != 0; \ + } while (0) + +#define MAU_RM ((RM)((mau_state.asr >> 22) & 3)) + +typedef enum { + M_ADD = 0x02, + M_SUB = 0x03, + M_DIV = 0x04, + M_REM = 0x05, + M_MUL = 0x06, + M_MOVE = 0x07, + M_RDASR = 0x08, + M_WRASR = 0x09, + M_CMP = 0x0a, + M_CMPE = 0x0b, + M_ABS = 0x0c, + M_SQRT = 0x0d, + M_RTOI = 0x0e, + M_FTOI = 0x0f, + M_ITOF = 0x10, + M_DTOF = 0x11, + M_FTOD = 0x12, + M_NOP = 0x13, + M_EROF = 0x14, + M_NEG = 0x17, + M_LDR = 0x18, + M_CMPS = 0x1a, + M_CMPES = 0x1b +} mau_opcodes; + +typedef enum { + M_OP3_F0_SINGLE, + M_OP3_F1_SINGLE, + M_OP3_F2_SINGLE, + M_OP3_F3_SINGLE, + M_OP3_F0_DOUBLE, + M_OP3_F1_DOUBLE, + M_OP3_F2_DOUBLE, + M_OP3_F3_DOUBLE, + M_OP3_F0_TRIPLE, + M_OP3_F1_TRIPLE, + M_OP3_F2_TRIPLE, + M_OP3_F3_TRIPLE, + M_OP3_MEM_SINGLE, + M_OP3_MEM_DOUBLE, + M_OP3_MEM_TRIPLE, + M_OP3_NONE +} op3_spec; + +/* Specifier bytes for Operands 1 and 2 */ +typedef enum { + M_OP_F0, + M_OP_F1, + M_OP_F2, + M_OP_F3, + M_OP_MEM_SINGLE, + M_OP_MEM_DOUBLE, + M_OP_MEM_TRIPLE, + M_OP_NONE +} op_spec; + +/* + * 128-bit value + */ +typedef struct { + t_uint64 low; + t_uint64 high; +} t_mau_128; + +/* + * Not-a-Number Type + */ +typedef struct { + t_bool sign; + t_uint64 high; + t_uint64 low; +} T_NAN; + +/* + * Extended Precision (80 bits). + * + * Note that an undocumented feature of the WE32106 requires the use + * of uint32 rather than uint16 for the sign and exponent components + * of the struct. Although bits 80-95 are "unused", several + * diagnostics actually expect these bits to be moved and preserved on + * word transfers. They are ignored and discarded by math routines, + * however. + * + * The 's' field holds the Sticky bit used by rounding. + */ +typedef struct { + uint32 sign_exp; /* Sign and Exponent */ + t_uint64 frac; /* Fraction/Significand/Mantissa */ + t_bool s; /* Sticky bit */ +} XFP; + +typedef struct { + uint32 h; + t_uint64 l; +} DEC; + +/* + * Supported rounding modes. + */ +typedef enum { + ROUND_NEAREST, + ROUND_PLUS_INF, + ROUND_MINUS_INF, + ROUND_ZERO +} RM; + +/* + * Double Precision (64 bits) + */ +typedef t_uint64 DFP; + +/* + * Single Precision (32 bits) + */ +typedef uint32 SFP; + +/* + * MAU state + */ + +typedef struct { + uint32 cmd; + /* Exception */ + uint32 exception; + /* Status register */ + uint32 asr; + t_bool trapping_nan; + /* Generate a Non-Trapping NaN */ + t_bool ntnan; + /* Source (from broadcast) */ + uint32 src; + /* Destination (from broadcast) */ + uint32 dst; + uint8 opcode; + uint8 op1; + uint8 op2; + uint8 op3; + /* Data Register */ + XFP dr; + /* Operand Registers */ + XFP f0; + XFP f1; + XFP f2; + XFP f3; +} MAU_STATE; + +t_stat mau_reset(DEVICE *dptr); +t_stat mau_attach(UNIT *uptr, CONST char *cptr); +t_stat mau_detach(UNIT *uptr); +t_stat mau_broadcast(uint32 cmd, uint32 src, uint32 dst); +CONST char *mau_description(DEVICE *dptr); +t_stat mau_broadcast(uint32 cmd, uint32 src, uint32 dst); + +#endif /* _3B2_REV2_MAU_H_ */ diff --git a/3B2/3b2_mem.c b/3B2/3b2_mem.c index 90db6946..7603fe1c 100644 --- a/3B2/3b2_mem.c +++ b/3B2/3b2_mem.c @@ -1,324 +1,346 @@ -/* 3b2_mem.c: AT&T 3B2 memory access routines - - Copyright (c) 2021, Seth J. Morabito - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - - Except as contained in this notice, the name of the author shall - not be used in advertising or otherwise to promote the sale, use or - other dealings in this Software without prior written authorization - from the author. -*/ - -#include "3b2_mem.h" - -#include "3b2_cpu.h" -#include "3b2_csr.h" -#include "3b2_io.h" -#include "3b2_mmu.h" - -t_bool addr_is_rom(uint32 pa) -{ - return (pa < rom_size); -} - -t_bool addr_is_mem(uint32 pa) -{ - return (pa >= PHYS_MEM_BASE && - pa < (PHYS_MEM_BASE + MEM_SIZE)); -} - -t_bool addr_is_io(uint32 pa) -{ -#if defined(REV3) - return ((pa >= IO_BOTTOM && pa < IO_TOP) || - (pa >= CIO_BOTTOM && pa < CIO_TOP) || - (pa >= VCACHE_BOTTOM && pa < VCACHE_TOP) || - (pa >= BUB_BOTTOM && pa < BUB_TOP)); -#else - return ((pa >= IO_BOTTOM && pa < IO_TOP) || - (pa >= CIO_BOTTOM && pa < CIO_TOP)); -#endif -} - -/* Read Word (Physical Address) */ -uint32 pread_w(uint32 pa) -{ - uint32 *m; - uint32 index; - - if (pa & 3) { - sim_debug(READ_MSG, &mmu_dev, - "[%08x] Cannot read physical address. ALIGNMENT ISSUE: %08x\n", - R[NUM_PC], pa); - CSRBIT(CSRALGN, TRUE); - cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT); - } - - if (addr_is_io(pa)) { - return io_read(pa, 32); - } - - if (addr_is_rom(pa)) { - m = ROM; - index = pa >> 2; - } else if (addr_is_mem(pa)) { - m = RAM; - index = (pa - PHYS_MEM_BASE) >> 2; - } else { - return 0; - } - - return m[index]; -} - -/* - * Write Word (Physical Address) - */ -void pwrite_w(uint32 pa, uint32 val) -{ - if (pa & 3) { - sim_debug(WRITE_MSG, &mmu_dev, - "[%08x] Cannot write physical address. ALIGNMENT ISSUE: %08x\n", - R[NUM_PC], pa); - CSRBIT(CSRALGN, TRUE); - cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT); - } - - if (addr_is_io(pa)) { - io_write(pa, val, 32); - return; - } - - if (addr_is_mem(pa)) { - RAM[(pa - PHYS_MEM_BASE) >> 2] = val; - return; - } -} - -/* - * Read Halfword (Physical Address) - */ -uint16 pread_h(uint32 pa) -{ - uint32 *m; - uint32 index; - - if (pa & 1) { - sim_debug(READ_MSG, &mmu_dev, - "[%08x] Cannot read physical address. ALIGNMENT ISSUE %08x\n", - R[NUM_PC], pa); - CSRBIT(CSRALGN, TRUE); - cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT); - } - - if (addr_is_io(pa)) { - return (uint16) io_read(pa, 16); - } - - if (addr_is_rom(pa)) { - m = ROM; - index = pa >> 2; - } else if (addr_is_mem(pa)) { - m = RAM; - index = (pa - PHYS_MEM_BASE) >> 2; - } else { - return 0; - } - - if (pa & 2) { - return m[index] & HALF_MASK; - } else { - return (m[index] >> 16) & HALF_MASK; - } -} - -/* - * Write Halfword (Physical Address) - */ -void pwrite_h(uint32 pa, uint16 val) -{ - uint32 *m; - uint32 index; - uint32 wval = (uint32)val; - - if (pa & 1) { - sim_debug(WRITE_MSG, &mmu_dev, - "[%08x] Cannot write physical address %08x, ALIGNMENT ISSUE\n", - R[NUM_PC], pa); - CSRBIT(CSRALGN, TRUE); - cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT); - } - - if (addr_is_io(pa)) { - io_write(pa, val, 16); - return; - } - - if (addr_is_mem(pa)) { - m = RAM; - index = (pa - PHYS_MEM_BASE) >> 2; - } else { - return; - } - - if (pa & 2) { - m[index] = (m[index] & ~HALF_MASK) | wval; - } else { - m[index] = (m[index] & HALF_MASK) | (wval << 16); - } -} - -/* - * Read Byte (Physical Address) - */ -uint8 pread_b(uint32 pa) -{ - uint32 data; - int32 sc = (~(pa & 3) << 3) & 0x1f; - - if (addr_is_io(pa)) { - return (uint8)(io_read(pa, 8)); - } - - if (addr_is_rom(pa)) { - data = ROM[pa >> 2]; - } else if (addr_is_mem(pa)) { - data = RAM[(pa - PHYS_MEM_BASE) >> 2]; - } else { - return 0; - } - - return (data >> sc) & BYTE_MASK; -} - -/* Write Byte (Physical Address) */ -void pwrite_b(uint32 pa, uint8 val) -{ - uint32 *m; - int32 index; - int32 sc = (~(pa & 3) << 3) & 0x1f; - uint32 mask = 0xffu << sc; - - if (addr_is_io(pa)) { - io_write(pa, val, 8); - return; - } - - if (addr_is_mem(pa)) { - m = RAM; - index = (pa - PHYS_MEM_BASE) >> 2; - m[index] = (m[index] & ~mask) | (uint32) (val << sc); - return; - } -} - -/* Read Byte (Virtual Address) */ -uint8 read_b(uint32 va, uint8 r_acc) -{ - return pread_b(mmu_xlate_addr(va, r_acc)); -} - -/* Write Byte (Virtual Address) */ -void write_b(uint32 va, uint8 val) -{ - pwrite_b(mmu_xlate_addr(va, ACC_W), val); -} - -/* Read Halfword (Virtual Address) */ -uint16 read_h(uint32 va, uint8 r_acc) -{ - return pread_h(mmu_xlate_addr(va, r_acc)); -} - -/* Write Halfword (Virtual Address) */ -void write_h(uint32 va, uint16 val) -{ - pwrite_h(mmu_xlate_addr(va, ACC_W), val); -} - -/* Read Word (Virtual Address) */ -uint32 read_w(uint32 va, uint8 r_acc) -{ - return pread_w(mmu_xlate_addr(va, r_acc)); -} - -/* Write Word (Virtual Address) */ -void write_w(uint32 va, uint32 val) -{ - pwrite_w(mmu_xlate_addr(va, ACC_W), val); -} - -t_stat read_operand(uint32 va, uint8 *val) -{ - uint32 pa; - t_stat succ; - - succ = mmu_decode_va(va, ACC_IF, TRUE, &pa); - - if (succ == SCPE_OK) { - *val = pread_b(pa); - } else { - *val = 0; - } - - return succ; -} - -t_stat examine(uint32 va, uint8 *val) -{ - uint32 pa; - t_stat succ; - - succ = mmu_decode_va(va, 0, FALSE, &pa); - - if (succ == SCPE_OK) { - if (addr_is_rom(pa) || addr_is_mem(pa)) { - *val = pread_b(pa); - return SCPE_OK; - } else { - *val = 0; - return SCPE_NXM; - } - } else { - *val = 0; - return succ; - } -} - -t_stat deposit(uint32 va, uint8 val) -{ - uint32 pa; - t_stat succ; - - succ = mmu_decode_va(va, 0, FALSE, &pa); - - if (succ == SCPE_OK) { - if (addr_is_mem(pa)) { - pwrite_b(pa, val); - return SCPE_OK; - } else { - return SCPE_NXM; - } - } else { - return succ; - } -} +/* 3b2_mem.c: Memory Map Access Routines + + Copyright (c) 2021-2022, Seth J. Morabito + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + Except as contained in this notice, the name of the author shall + not be used in advertising or otherwise to promote the sale, use or + other dealings in this Software without prior written authorization + from the author. +*/ + +#include "3b2_mem.h" + +#include "3b2_cpu.h" +#include "3b2_csr.h" +#include "3b2_io.h" +#include "3b2_mmu.h" +#include "3b2_stddev.h" +#include "3b2_dmac.h" + +#if defined(REV3) +static uint32 ecc_addr; /* ECC address */ +static t_bool ecc_err; /* ECC multi-bit error */ +#endif + +/* + * ECC is simulated just enough to pass diagnostics, and no more. + * + * Checking and setting of ECC syndrome bits is a no-op for Rev 2. + */ +static SIM_INLINE void check_ecc(uint32 pa, t_bool write, uint8 src) +{ +#if defined(REV3) + /* Force ECC Syndrome mode enables a diagnostic mode on the AM2960 + data correction ICs */ + if (write && !CSR(CSRFECC)) { + sim_debug(EXECUTE_MSG, &mmu_dev, + "ECC Error on Write. pa=%08x\n", + pa); + ecc_addr = pa; + ecc_err = TRUE; + } else if (ecc_err && !write && pa == ecc_addr) { + sim_debug(EXECUTE_MSG, &mmu_dev, + "ECC Error detected on Read. pa=%08x psw=%08x cur_ipl=%d csr=%08x\n", + pa, R[NUM_PSW], PSW_CUR_IPL, csr_data); + flt[0] = ecc_addr & 0x3ffff; + flt[1] = MA_CPU_IO|MA_CPU_BU; + ecc_err = FALSE; + CSRBIT(CSRFRF, TRUE); /* Fault registers frozen */ + CSRBIT(CSRMBERR, TRUE); /* Multi-bit error */ + CPU_SET_INT(INT_MBERR); + /* Only abort if CPU is doing the read */ + if (src == BUS_CPU) { + cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT); + } + } +#endif +} + +/* Read Word (Physical Address) */ +uint32 pread_w(uint32 pa, uint8 src) +{ + uint8 *m; + uint32 index = 0; + +#if defined(REV3) + if ((pa & 3) && (R[NUM_PSW] & PSW_EA_MASK) == 0) { +#else + if (pa & 3) { +#endif + sim_debug(READ_MSG, &mmu_dev, + "Cannot read physical address. ALIGNMENT ISSUE: %08x\n", + pa); + CSRBIT(CSRALGN, TRUE); + cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT); + } + + if (IS_IO(pa)) { + return io_read(pa, 32); + } + + if (IS_ROM(pa)) { + m = ROM; + index = pa; + } else if (IS_RAM(pa)) { + check_ecc(pa, FALSE, src); + m = RAM; + index = (pa - PHYS_MEM_BASE); + } else { + return 0; + } + + return ATOW(m, index); +} + +/* + * Write Word (Physical Address) + */ +void pwrite_w(uint32 pa, uint32 val, uint8 src) +{ + uint32 index; + + if (pa & 3) { + sim_debug(WRITE_MSG, &mmu_dev, + "Cannot write physical address. ALIGNMENT ISSUE: %08x\n", + pa); + CSRBIT(CSRALGN, TRUE); + cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT); + } + + if (IS_IO(pa)) { + io_write(pa, val, 32); + return; + } + + if (IS_RAM(pa)) { + check_ecc(pa, TRUE, src); + index = pa - PHYS_MEM_BASE; + RAM[index] = (val >> 24) & 0xff; + RAM[index + 1] = (val >> 16) & 0xff; + RAM[index + 2] = (val >> 8) & 0xff; + RAM[index + 3] = val & 0xff; + return; + } +} + +/* + * Read Halfword (Physical Address) + */ +uint16 pread_h(uint32 pa, uint8 src) +{ + uint8 *m; + uint32 index; + + if (pa & 1) { + sim_debug(READ_MSG, &mmu_dev, + "Cannot read physical address. ALIGNMENT ISSUE %08x\n", + pa); + CSRBIT(CSRALGN, TRUE); + cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT); + } + + if (IS_IO(pa)) { + return (uint16) io_read(pa, 16); + } + + if (IS_ROM(pa)) { + m = ROM; + index = pa; + } else if (IS_RAM(pa)) { + check_ecc(pa, FALSE, src); + m = RAM; + index = pa - PHYS_MEM_BASE; + } else { + return 0; + } + + return ATOH(m, index); +} + +/* + * Write Halfword (Physical Address) + */ +void pwrite_h(uint32 pa, uint16 val, uint8 src) +{ + uint32 index; + +#if defined(REV3) + if ((pa & 1) && (R[NUM_PSW] & PSW_EA_MASK) == 0) { +#else + if (pa & 1) { +#endif + sim_debug(WRITE_MSG, &mmu_dev, + "Cannot write physical address %08x, ALIGNMENT ISSUE\n", + pa); + CSRBIT(CSRALGN, TRUE); + } + + if (IS_IO(pa)) { + io_write(pa, val, 16); + return; + } + + if (IS_RAM(pa)) { + check_ecc(pa, TRUE, src); + index = pa - PHYS_MEM_BASE; + RAM[index] = (val >> 8) & 0xff; + RAM[index + 1] = val & 0xff; + return; + } +} + +/* + * Read Byte (Physical Address) + */ +uint8 pread_b(uint32 pa, uint8 src) +{ + if (IS_IO(pa)) { + return (uint8)(io_read(pa, 8)); + } + + if (IS_ROM(pa)) { + return ROM[pa]; + } else if (IS_RAM(pa)) { + check_ecc(pa, FALSE, src); + return RAM[pa - PHYS_MEM_BASE]; + } else { + return 0; + } +} + +/* Write Byte (Physical Address) */ +void pwrite_b(uint32 pa, uint8 val, uint8 src) +{ + uint32 index; + + if (IS_IO(pa)) { + io_write(pa, val, 8); + return; + } + + if (IS_RAM(pa)) { + check_ecc(pa, TRUE, src); + index = pa - PHYS_MEM_BASE; + RAM[index] = val; + return; + } +} + +/* Write to ROM (used by ROM load) */ +void pwrite_b_rom(uint32 pa, uint8 val) { + if (IS_ROM(pa)) { + ROM[pa] = val; + } + } + +/* Read Byte (Virtual Address) */ +uint8 read_b(uint32 va, uint8 r_acc, uint8 src) +{ + return pread_b(mmu_xlate_addr(va, r_acc), src); +} + +/* Write Byte (Virtual Address) */ +void write_b(uint32 va, uint8 val, uint8 src) +{ + pwrite_b(mmu_xlate_addr(va, ACC_W), val, src); +} + +/* Read Halfword (Virtual Address) */ +uint16 read_h(uint32 va, uint8 r_acc, uint8 src) +{ + return pread_h(mmu_xlate_addr(va, r_acc), src); +} + +/* Write Halfword (Virtual Address) */ +void write_h(uint32 va, uint16 val, uint8 src) +{ + pwrite_h(mmu_xlate_addr(va, ACC_W), val, src); +} + +/* Read Word (Virtual Address) */ +uint32 read_w(uint32 va, uint8 r_acc, uint8 src) +{ + return pread_w(mmu_xlate_addr(va, r_acc), src); +} + +/* Write Word (Virtual Address) */ +void write_w(uint32 va, uint32 val, uint8 src) +{ + pwrite_w(mmu_xlate_addr(va, ACC_W), val, src); +} + +t_stat read_operand(uint32 va, uint8 *val) +{ + uint32 pa; + t_stat succ; + + succ = mmu_decode_va(va, ACC_IF, TRUE, &pa); + + if (succ == SCPE_OK) { + *val = pread_b(pa, BUS_CPU); + } else { + *val = 0; + } + + return succ; +} + +t_stat examine(uint32 va, uint8 *val) +{ + uint32 pa; + t_stat succ; + + succ = mmu_decode_va(va, 0, FALSE, &pa); + + if (succ == SCPE_OK) { + if (IS_ROM(pa) || IS_RAM(pa)) { + *val = pread_b(pa, BUS_CPU); + return SCPE_OK; + } else { + *val = 0; + return SCPE_NXM; + } + } else { + *val = 0; + return succ; + } +} + +t_stat deposit(uint32 va, uint8 val) +{ + uint32 pa; + t_stat succ; + + succ = mmu_decode_va(va, 0, FALSE, &pa); + + if (succ == SCPE_OK) { + if (IS_RAM(pa)) { + pwrite_b(pa, val, BUS_CPU); + return SCPE_OK; + } else { + return SCPE_NXM; + } + } else { + return succ; + } +} diff --git a/3B2/3b2_mem.h b/3B2/3b2_mem.h index b477bfb8..79575c9e 100644 --- a/3B2/3b2_mem.h +++ b/3B2/3b2_mem.h @@ -1,62 +1,79 @@ -/* 3b2_mem.h: AT&T 3B2 3B2 memory access routines - - Copyright (c) 2021, Seth J. Morabito - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - - Except as contained in this notice, the name of the author shall - not be used in advertising or otherwise to promote the sale, use or - other dealings in this Software without prior written authorization - from the author. -*/ - -#ifndef _3B2_MEM_H_ -#define _3B2_MEM_H_ - -#include "3b2_defs.h" - -uint32 pread_w(uint32 pa); -void pwrite_w(uint32 pa, uint32 val); -uint8 pread_b(uint32 pa); -void pwrite_b(uint32 pa, uint8 val); -uint16 pread_h(uint32 pa); -void pwrite_h(uint32 pa, uint16 val); - -uint8 read_b(uint32 va, uint8 r_acc); -uint16 read_h(uint32 va, uint8 r_acc); -uint32 read_w(uint32 va, uint8 r_acc); -void write_b(uint32 va, uint8 val); -void write_h(uint32 va, uint16 val); -void write_w(uint32 va, uint32 val); - -t_stat read_operand(uint32 va, uint8 *val); -t_stat examine(uint32 va, uint8 *val); -t_stat deposit(uint32 va, uint8 val); - -t_bool addr_is_rom(uint32 pa); -t_bool addr_is_mem(uint32 pa); -t_bool addr_is_io(uint32 pa); - -t_stat mmu_decode_va(uint32 va, uint8 r_acc, t_bool fc, uint32 *pa); -void mmu_enable(); -void mmu_disable(); - -#endif /* _3B2_MEM_H_ */ +/* 3b2_mem.h: Memory Map Access Routines + + Copyright (c) 2021-2022, Seth J. Morabito + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + Except as contained in this notice, the name of the author shall + not be used in advertising or otherwise to promote the sale, use or + other dealings in this Software without prior written authorization + from the author. +*/ + +#ifndef _3B2_MEM_H_ +#define _3B2_MEM_H_ + +#include "3b2_defs.h" + +#define IS_ROM(PA) ((PA) < ROM_SIZE) +#define IS_RAM(PA) (((PA) >= PHYS_MEM_BASE) && ((PA) < (PHYS_MEM_BASE + MEM_SIZE))) +#if defined(REV3) +#define IS_IO(PA) (((PA >= IO_BOTTOM) && (PA < IO_TOP)) || \ + ((PA >= CIO_BOTTOM) && (PA < CIO_TOP)) || \ + ((PA >= VCACHE_BOTTOM) && (PA < VCACHE_TOP)) || \ + ((PA >= BUB_BOTTOM) && (PA < BUB_TOP))) +#else +#define IS_IO(PA) (((PA >= IO_BOTTOM) && (PA < IO_TOP)) || \ + ((PA >= CIO_BOTTOM) && (PA < CIO_TOP))) +#endif + +#define MA_BUB3 0x100 /* BUBUS slot 3 master on fault */ +#define MA_BUB2 0x200 /* BUBUS slot 2 master on fault */ +#define MA_BUB1 0x400 /* BUBUS slot 1 master on fault */ +#define MA_CPU_BU 0x2000 /* CPU access BUBUS peripheral */ +#define MA_BUB0 0x4000 /* BUBUS slot 0 master on fault */ +#define MA_CPU_IO 0x8000 /* CPU accessing I/O peripheral */ +#define MA_IO_NLY 0x10000 /* IO Bus Master on fault */ +#define MA_IO_BM 0x80000 /* IO Bus Master or BUBUS was master on fault */ + +#define BUS_PER 0 /* Read or Write is from peripheral */ +#define BUS_CPU 1 /* Read or Write is from CPU */ + +uint32 pread_w(uint32 pa, uint8 src); +void pwrite_w(uint32 pa, uint32 val, uint8 src); +uint8 pread_b(uint32 pa, uint8 src); +void pwrite_b(uint32 pa, uint8 val, uint8 src); +void pwrite_b_rom(uint32 pa, uint8 val); +uint16 pread_h(uint32 pa, uint8 src); +void pwrite_h(uint32 pa, uint16 val, uint8 src); + +uint8 read_b(uint32 va, uint8 r_acc, uint8 src); +uint16 read_h(uint32 va, uint8 r_acc, uint8 src); +uint32 read_w(uint32 va, uint8 r_acc, uint8 src); +void write_b(uint32 va, uint8 val, uint8 src); +void write_h(uint32 va, uint16 val, uint8 src); +void write_w(uint32 va, uint32 val, uint8 src); + +t_stat read_operand(uint32 va, uint8 *val); +t_stat examine(uint32 va, uint8 *val); +t_stat deposit(uint32 va, uint8 val); + +#endif /* _3B2_MEM_H_ */ diff --git a/3B2/3b2_mmu.h b/3B2/3b2_mmu.h index 54192991..f16a153a 100644 --- a/3B2/3b2_mmu.h +++ b/3B2/3b2_mmu.h @@ -1,40 +1,40 @@ -/* 3b2_mmu.h: Common MMU header - - Copyright (c) 2021, Seth J. Morabito - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - - Except as contained in this notice, the name of the author shall - not be used in advertising or otherwise to promote the sale, use or - other dealings in this Software without prior written authorization - from the author. -*/ - -#ifndef _3B2_MMU_H_ -#define _3B2_MMU_H_ - -#if defined(REV3) -#include "3b2_rev3_mmu.h" -#else -#include "3b2_rev2_mmu.h" -#endif - -#endif /* _3B2_MMU_H_ */ +/* 3b2_mmu.h: Common MMU header + + Copyright (c) 2021-2022, Seth J. Morabito + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + Except as contained in this notice, the name of the author shall + not be used in advertising or otherwise to promote the sale, use or + other dealings in this Software without prior written authorization + from the author. +*/ + +#ifndef _3B2_MMU_H_ +#define _3B2_MMU_H_ + +#if defined(REV3) +#include "3b2_rev3_mmu.h" +#else +#include "3b2_rev2_mmu.h" +#endif + +#endif /* _3B2_MMU_H_ */ diff --git a/3B2/3b2_ni.c b/3B2/3b2_ni.c index c17dccd6..d3e5f4b5 100644 --- a/3B2/3b2_ni.c +++ b/3B2/3b2_ni.c @@ -1,1291 +1,1121 @@ -/* 3b2_ni.c: AT&T 3B2 Model 400 "NI" feature card - - Copyright (c) 2018, Seth J. Morabito - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - - Except as contained in this notice, the name of the author shall - not be used in advertising or otherwise to promote the sale, use or - other dealings in this Software without prior written authorization - from the author. -*/ - -/* - * NI is an intelligent feature card for the 3B2 that provides a - * 10BASE5 Ethernet interface. - - * Overview - * -------- - * - * The NI board is based on the Common I/O (CIO) platform. Like other - * CIO boards, it uses an 80186 embedded processor. The board and the - * 3B2 host communicate by reading and writing to the 3B2's main - * memory at locations established by the host via a series of job - * request and job completion queues. Only three interrupts are used: - * Two interrupts (80186 interrupts INT0 and INT1) are triggered by - * the 3B2 and tell the card when work is available in the request - * queue. One WE32100 interrupt (at a negotiated vector and predefined - * IPL) is used by the CIO board to tell the 3B2 that a new entry is - * available in the completion queue. - * - * The on-board ROM does not contain the full firmware required to - * perform all application-specific work. Rather, it is used only to - * bootstrap the 80186 and provide essential communication between the - * 3B2 host and the board's internal RAM. During initialization, the - * host must upload application-specific code to the board's RAM and - * cause the board to start running it. This is known as - * "pumping". The 80186 binary code for the NI board under System V - * Release 3 is stored in the file `/lib/pump/ni` - * - * Implementation Details - * ---------------------- - * - * The 10BASE5 interface on the NI board is driven by an Intel 82586 - * IEEE 802.3 LAN Coprocessor, controlled by the board's 80186 - * CPU. The 82586 is completely opaque to the host due to the nature - * of the CIO protocol. Nevertheless, an attempt is made to simulate - * the behavior of the 82586 where appropriate and possible. - * - * The NI board uses a sanity timer to occasionally write a watchdog - * or heartbeat entry into the completion queue, indicating that the - * Ethernet interface is still alive and that all is well. If the UNIX - * driver has not seen this heartbeat after approximately 10 seconds, - * it will consider the board to be in an "DOWN" state and send it a - * TERM ioctl. - * - * The NI board does behave differently from the other CIO boards in - * one respect: Unlike other CIO boards, the NI board takes jobs from - * its two Packet Receive CIO request queues by polling them, and then - * stores the taken jobs in a small 4-entry internal cache. It polls - * these queues quite rapidly in the real NI so it always has a full - * cache available for future incoming packets. To prevent performance - * issues, this simulation polls rapidly ("fast polling mode") only - * when absolutely necessary. Typically, that means only after the - * card has been reset, but before the request queues have finished - * being built by the 3B2 host. The UNIX NI driver expects and - * requires this behavior! - * - * Open Issues - * ----------- - * - * 1. The simulated card does not yet support setting or removing - * multicast Ethernet addresses. ioctl operations that attempt to - * set or remove multicast Ethernet addresses should silently - * fail. This will be supported in a future release. - * - */ - -#include "3b2_ni.h" - -#include "3b2_io.h" -#include "3b2_mem.h" -#include "3b2_timer.h" - -/* State container for the card */ -NI_STATE ni; - -/* Static Function Declarations */ -static void dump_packet(const char *direction, ETH_PACK *pkt); -static void ni_enable(); -static void ni_disable(); -static void ni_cmd(uint8 cid, cio_entry *rentry, uint8 *rapp_data, t_bool is_exp); -static t_stat ni_show_queue_common(FILE *st, UNIT *uptr, int32 val, - CONST void *desc, t_bool rq); -static t_stat ni_show_rqueue(FILE *st, UNIT *uptr, int32 val, CONST void *desc); -static t_stat ni_show_cqueue(FILE *st, UNIT *uptr, int32 val, CONST void *desc); - -/* - * When the NI card is pumped, its CRC depends on what slot it is - * installed in and what version of driver has been installed. - */ -#define NI_DIAG_CRCS_LEN 7 -static const uint32 NI_DIAG_CRCS[] = { - 0x795268a4, - 0xfab1057c, - 0x10ca00cd, - 0x9b3ddeda, - 0x267b19a0, - 0x123f36c0, - 0xc04ca0ab, -}; - -/* - * Unit 0: Packet reception. - * Unit 1: Sanity timer. - * Unit 2: Request Queue poller. - * Unit 3: CIO requests. - */ -UNIT ni_unit[] = { - { UDATA(&ni_rcv_svc, UNIT_IDLE|UNIT_ATTABLE, 0) }, - { UDATA(&ni_sanity_svc, UNIT_IDLE|UNIT_DIS, 0) }, - { UDATA(&ni_rq_svc, UNIT_IDLE|UNIT_DIS, 0) }, - { UDATA(&ni_cio_svc, UNIT_DIS, 0) }, - { 0 } -}; - -static UNIT *rcv_unit = &ni_unit[0]; -static UNIT *sanity_unit = &ni_unit[1]; -static UNIT *rq_unit = &ni_unit[2]; -static UNIT *cio_unit = &ni_unit[3]; - -MTAB ni_mod[] = { - { MTAB_XTD|MTAB_VDV|MTAB_NMO, 0, "STATS", "STATS", - &ni_set_stats, &ni_show_stats, NULL, "Display or reset statistics" }, - { MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, "POLL", NULL, - NULL, &ni_show_poll, NULL, "Display the current polling mode" }, - { MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, "RQUEUE=n", NULL, - NULL, &ni_show_rqueue, NULL, "Display Request Queue for card n" }, - { MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, "CQUEUE=n", NULL, - NULL, &ni_show_cqueue, NULL, "Display Completion Queue for card n" }, - { MTAB_XTD|MTAB_VDV|MTAB_VALR|MTAB_NC, 0, "MAC", "MAC=xx:xx:xx:xx:xx:xx", - &ni_setmac, &ni_showmac, NULL, "MAC address" }, - { MTAB_XTD|MTAB_VDV|MTAB_NMO, 0, "FILTERS", NULL, - NULL, &ni_show_filters, NULL, "Display address filters" }, - { 0 } -}; - -static DEBTAB ni_debug[] = { - { "TRACE", DBG_TRACE, "trace routine calls" }, - { "IO", DBG_IO, "debug i/o" }, - { "CACHE", DBG_CACHE, "debug job cache" }, - { "PACKET", DBG_DAT, "display packet data" }, - { "ERR", DBG_ERR, "display errors" }, - { "ETH", DBG_ETH, "debug ethernet device" }, - { 0 } -}; - -DEVICE ni_dev = { - "NI", /* name */ - ni_unit, /* units */ - NULL, /* registers */ - ni_mod, /* modifiers */ - 4, /* #units */ - 16, /* address radix */ - 32, /* address width */ - 1, /* address incr. */ - 16, /* data radix */ - 8, /* data width */ - NULL, /* examine routine */ - NULL, /* deposit routine */ - &ni_reset, /* reset routine */ - NULL, /* boot routine */ - &ni_attach, /* attach routine */ - &ni_detach, /* detach routine */ - NULL, /* context */ - DEV_DISABLE|DEV_DIS| - DEV_DEBUG|DEV_ETHER, /* flags */ - 0, /* debug control flags */ - ni_debug, /* debug flag names */ - NULL, /* memory size change */ - NULL, /* logical name */ - &ni_help, /* help routine */ - NULL, /* attach help routine */ - NULL, /* help context */ - &ni_description, /* device description */ - NULL, -}; - -static void dump_packet(const char *direction, ETH_PACK *pkt) -{ - char dumpline[82]; - char *p; - uint32 char_offset, i; - - if (!direction) { - return; - } - - snprintf(dumpline, 10, "%08x ", 0); - char_offset = 9; - - for (i = 0; i < pkt->len; i++) { - snprintf(dumpline + char_offset, 4, "%02x ", pkt->msg[i]); - snprintf(dumpline + 61 + (i % 16), 2, "%c", CHAR(pkt->msg[i])); - char_offset += 3; - - if ((i + 1) % 16 == 0) { - - snprintf(dumpline + 56, 5, " |"); - snprintf(dumpline + 78, 2, "|"); - - for (p = dumpline; p < (dumpline + 80); p++) { - if (*p == '\0') { - *p = ' '; - } - } - *p = '\0'; - sim_debug(DBG_DAT, &ni_dev, - "[%s packet]: %s\n", direction, dumpline); - memset(dumpline, 0, 80); - snprintf(dumpline, 10, "%08x ", i + 1); - char_offset = 9; - } - } - - /* Finish any leftover bits */ - if ((i + 1) % 16 != 0) { - snprintf(dumpline + 56, 5, " |"); - snprintf(dumpline + 78, 2, "|"); - - for (p = dumpline; p < (dumpline + 80); p++) { - if (*p == '\0') { - *p = ' '; - } - } - *p = '\0'; - - sim_debug(DBG_DAT, &ni_dev, - "[%s packet]: %s\n", direction, dumpline); - } -} - -static void ni_enable() -{ - sim_debug(DBG_TRACE, &ni_dev, - "[ni_enable] Enabling the interface.\n"); - - /* Reset Statistics */ - memset(&ni.stats, 0, sizeof(ni_stat_info)); - - /* Clear out job cache */ - memset(&ni.job_cache, 0, sizeof(ni_job_cache) * 2); - - /* Enter fast polling mode */ - ni.poll_rate = NI_QPOLL_FAST; - - /* Start the queue poller in fast poll mode */ - sim_activate_abs(rq_unit, NI_QPOLL_FAST); - - /* Start the sanity timer */ - sim_activate_after(sanity_unit, NI_SANITY_INTERVAL_US); - - /* Enable the interface */ - ni.enabled = TRUE; -} - -static void ni_disable() -{ - sim_debug(DBG_TRACE, &ni_dev, - "[ni_disable] Disabling the interface.\n"); - ni.enabled = FALSE; - sim_cancel(ni_unit); - sim_cancel(rcv_unit); - sim_cancel(rq_unit); - sim_cancel(cio_unit); - sim_cancel(sanity_unit); - CIO_CLR_INT(ni.cid); -} - -static void ni_cmd(uint8 cid, cio_entry *rentry, uint8 *rapp_data, t_bool is_exp) -{ - int i, j; - int32 delay; - uint16 hdrsize; - t_stat status; - int prot_info_offset; - cio_entry centry = {0}; - uint8 app_data[4] = {rapp_data[0], rapp_data[1], rapp_data[2], rapp_data[3]}; - - /* Assume some default values, but let the handlers below - * override these where appropriate */ - centry.opcode = CIO_SUCCESS; - centry.subdevice = rentry->subdevice; - centry.address = rentry->address; - - cio[cid].op = rentry->opcode; - - delay = NI_INT_DELAY; - - switch(rentry->opcode) { - case CIO_DLM: - for (i = 0; i < rentry->byte_count; i++) { - ni.crc = cio_crc32_shift(ni.crc, pread_b(rentry->address + i)); - } - - centry.address = rentry->address + rentry->byte_count; - sim_debug(DBG_TRACE, &ni_dev, - "[ni_cmd] CIO Download Memory: bytecnt=%04x " - "addr=%08x return_addr=%08x subdev=%02x (CRC=%08x)\n", - rentry->byte_count, rentry->address, - centry.address, centry.subdevice, ni.crc); - - if (is_exp) { - cio_cexpress(cid, NIQESIZE, ¢ry, app_data); - } else { - cio_cqueue(cid, CIO_STAT, NIQESIZE, ¢ry, app_data); - } - - break; - case CIO_FCF: - sim_debug(DBG_TRACE, &ni_dev, - "[ni_cmd] CIO Force Function Call (CRC=%08x)\n", - ni.crc); - - /* If the currently running program is a diagnostics program, - * we are expected to write results into memory at address - * 0x200f000 */ - for (i = 0; i < NI_DIAG_CRCS_LEN; i++) { - if (ni.crc == NI_DIAG_CRCS[i]) { - pwrite_h(0x200f000, 0x1); /* Test success */ - pwrite_h(0x200f002, 0x0); /* Test Number */ - pwrite_h(0x200f004, 0x0); /* Actual */ - pwrite_h(0x200f006, 0x0); /* Expected */ - pwrite_b(0x200f008, 0x1); /* Success flag again */ - break; - } - } - - /* Store the sequence byte we were sent for later reply. */ - ni.fcf_seq = rapp_data[3]; - - /* "Force Function Call" causes the CIO card to start running - * pumped code as a new process, taking over from its firmware - * ROM. As a result, a new sysgen is necessary to get the card - * in the right state. */ - - ni_disable(); - cio[cid].sysgen_s = 0; - - if (cio[cid].ivec == 0 || cio[cid].ivec == 3) { - cio_cexpress(cid, NIQESIZE, ¢ry, app_data); - } else { - cio_cqueue(cid, CIO_STAT, NIQESIZE, ¢ry, app_data); - } - - break; - case CIO_DSD: - /* Determine Sub-Devices. We have none. */ - sim_debug(DBG_TRACE, &ni_dev, - "[ni_cmd] Determine Sub-Devices.\n"); - - /* The system wants us to write sub-device structures at the - * supplied address */ - pwrite_h(rentry->address, 0x0); - - if (is_exp) { - cio_cexpress(cid, NIQESIZE, ¢ry, app_data); - } else { - cio_cqueue(cid, CIO_STAT, NIQESIZE, ¢ry, app_data); - } - - break; - case NI_SETID: - sim_debug(DBG_TRACE, &ni_dev, - "[ni_cmd] NI SETID Operation\n"); - - /* Try to read the mac from memory */ - for (i = 0; i < MAC_SIZE_BYTES; i++) { - ni.mac_bytes[i] = pread_b(rentry->address + i); - } - - snprintf(ni.mac_str, MAC_SIZE_CHARS, "%02x:%02x:%02x:%02x:%02x:%02x", - ni.mac_bytes[0], ni.mac_bytes[1], ni.mac_bytes[2], - ni.mac_bytes[3], ni.mac_bytes[4], ni.mac_bytes[5]); - - sim_debug(DBG_TRACE, &ni_dev, - "[ni_cmd] NI SETID: New MAC: %s\n", - ni.mac_str); - - status = ni_setmac(ni_dev.units, 0, ni.mac_str, NULL); - - cio_cqueue(cid, CIO_STAT, NIQESIZE, ¢ry, app_data); - - break; - case NI_TURNOFF: - sim_debug(DBG_TRACE, &ni_dev, - "[ni_cmd] NI TURNOFF Operation\n"); - - ni_disable(); - - cio_cqueue(cid, CIO_STAT, NIQESIZE, ¢ry, app_data); - - break; - case NI_TURNON: - sim_debug(DBG_TRACE, &ni_dev, - "[ni_cmd] NI TURNON Operation\n"); - - ni_enable(); - - cio_cqueue(cid, CIO_STAT, NIQESIZE, ¢ry, app_data); - - break; - case NI_STATS: - sim_debug(DBG_TRACE, &ni_dev, - "[ni_cmd] NI STATS Operation\n"); - - cio_cqueue(cid, CIO_STAT, NIQESIZE, ¢ry, app_data); - - break; - case NI_SEND: - case NI_SEND_A: - sim_debug(DBG_TRACE, &ni_dev, - "[ni_cmd] NI SEND Operation (opcode=%d)\n", - rentry->opcode); - - /* TODO: Why is this always 4 for a send? */ - centry.subdevice = 4; - - /* TODO: On the real 3B2, this appears to be some sort of - * checksum. Perhaps the packet checksum? I'm not sure. I need - * to run Wireshark on the real 3B2 and investigate. - * - * However, we're in luck: The driver code doesn't seem to - * validate it or check against it in any way, so we can - * put anything in there. - */ - centry.address = rentry->address; - centry.byte_count = rentry->byte_count; - - - /* If the interface is not attached, we can't actually send - * any packets. */ - if (!(rcv_unit->flags & UNIT_ATT)) { - ni.stats.tx_fail++; - centry.opcode = CIO_FAILURE; - sim_debug(DBG_TRACE, &ni_dev, - "[ni_cmd] NI SEND failure. Not attached. tx_fail=%d\n", - ni.stats.tx_fail); - break; - } - - /* Reset the write packet */ - ni.wr_buf.len = 0; - ni.wr_buf.oversize = NULL; - - /* Read the size of the header */ - hdrsize = pread_h(rentry->address + EIG_TABLE_SIZE); - - /* Read out the packet frame */ - for (i = 0; i < rentry->byte_count; i++) { - ni.wr_buf.msg[i] = pread_b(rentry->address + PKT_START_OFFSET + i); - } - - /* Get a pointer to the buffer containing the protocol data */ - prot_info_offset = 0; - i = 0; - do { - ni.prot.addr = pread_w(rentry->address + prot_info_offset); - ni.prot.size = pread_h(rentry->address + prot_info_offset + 4); - ni.prot.last = pread_h(rentry->address + prot_info_offset + 6); - prot_info_offset += 8; - - /* Fill in the frame from this buffer */ - for (j=0; j < ni.prot.size; i++, j++) { - ni.wr_buf.msg[hdrsize + i] = pread_b(ni.prot.addr + j); - } - } while (!ni.prot.last); - - /* Fill in packet details */ - ni.wr_buf.len = rentry->byte_count; - - sim_debug(DBG_IO, &ni_dev, - "[XMT] Transmitting a packet of size %d (0x%x)\n", - ni.wr_buf.len, ni.wr_buf.len); - - /* Send it */ - status = eth_write(ni.eth, &ni.wr_buf, NULL); - - if (status == SCPE_OK) { - if (ni_dev.dctrl & DBG_DAT) { - dump_packet("XMT", &ni.wr_buf); - } - ni.stats.tx_bytes += ni.wr_buf.len; - ni.stats.tx_pkt++; - } else { - ni.stats.tx_fail++; - centry.opcode = CIO_FAILURE; - } - - /* Weird behavior seen on the real 3B2's completion queue: If - * the byte count value is < 0xff, shift it! I really wish I - * understood this card... */ - if (centry.byte_count < 0xff) { - centry.byte_count <<= 8; - } - - cio_cqueue(cid, CIO_STAT, NIQESIZE, ¢ry, app_data); - - delay = 0; - - break; - default: - sim_debug(DBG_TRACE, &ni_dev, - "[ni_cmd] Opcode %d Not Handled Yet\n", - rentry->opcode); - - cio_cqueue(cid, CIO_STAT, NIQESIZE, ¢ry, app_data); - - break; - } - - sim_activate_abs(cio_unit, delay); -} - -t_stat ni_setmac(UNIT *uptr, int32 val, CONST char* cptr, void* desc) -{ - t_stat status; - - UNUSED(val); - UNUSED(desc); - - status = SCPE_OK; - status = eth_mac_scan_ex(&ni.macs[NI_NIC_MAC], cptr, uptr); - - if (status == SCPE_OK) { - eth_filter(ni.eth, ni.filter_count, ni.macs, 0, 0); - } else { - sim_debug(DBG_ERR, &ni_dev, - "[ni_setmac] Error in eth_mac_scan_ex. status=%d\n", status); - } - - return status; -} - -t_stat ni_showmac(FILE* st, UNIT* uptr, int32 val, CONST void* desc) -{ - char buffer[20]; - - UNUSED(uptr); - UNUSED(val); - UNUSED(desc); - - eth_mac_fmt(&ni.macs[NI_NIC_MAC], buffer); - fprintf(st, "MAC=%s", buffer); - return SCPE_OK; -} - -t_stat ni_show_filters(FILE* st, UNIT* uptr, int32 val, CONST void* desc) -{ - char buffer[20]; - int i; - - UNUSED(uptr); - UNUSED(val); - UNUSED(desc); - - eth_mac_fmt(&ni.macs[NI_NIC_MAC], buffer); - fprintf(st, "Physical Address=%s\n", buffer); - if (ni.filter_count > 0) { - fprintf(st, "Filters:\n"); - for (i=0; i < ni.filter_count; i++) { - eth_mac_fmt((ETH_MAC *) ni.macs[i], buffer); - fprintf(st, "[%2d]: %s\n", i, buffer); - } - fprintf(st, "\n"); - } - - return SCPE_OK; -} - -void ni_sysgen(uint8 cid) -{ - cio_entry cqe = {0}; - uint8 app_data[4] = {0}; - - ni_disable(); - - app_data[3] = 0x64; - cqe.opcode = CIO_SYSGEN_OK; - - sim_debug(DBG_TRACE, &ni_dev, - "[ni_sysgen] CIO SYSGEN. rqp=%08x, cqp=%08x, nrq=%d, rqs=%d cqs=%d\n", - cio[cid].rqp, cio[cid].cqp, cio[cid].no_rque, cio[cid].rqs, cio[cid].cqs); - - /* If the card has been successfully pumped, then we respond with - * a full completion queue entry. Otherwise, an express entry is - * used. */ - if (ni.crc == NI_PUMP_CRC1 || - ni.crc == NI_PUMP_CRC2) { - cio_cqueue(cid, CIO_STAT, NIQESIZE, &cqe, app_data); - } else { - cio_cexpress(cid, NIQESIZE, &cqe, app_data); - } - - /* Now clear out the old CRC value, in case the card needs to be - * sysgen'ed again later. */ - ni.crc = 0; - - sim_activate_abs(cio_unit, NI_INT_DELAY); -} - -/* - * Handler for CIO INT0 (express job) requests. - */ -void ni_express(uint8 cid) -{ - cio_entry rqe = {0}; - uint8 app_data[4] = {0}; - - sim_debug(DBG_TRACE, &ni_dev, - "[ni_express] Handling express CIO request.\n"); - - cio_rexpress(cid, NIQESIZE, &rqe, app_data); - ni_cmd(cid, &rqe, app_data, TRUE); -} - -/* - * Handler for CIO INT1 (full job) requests. - */ -void ni_full(uint8 cid) -{ - cio_entry rqe = {0}; - uint8 app_data[4] = {0}; - - sim_debug(DBG_TRACE, &ni_dev, - "[ni_full] INT1 received. Handling full CIO request.\n"); - - while (cio_cqueue_avail(cid, NIQESIZE) && - cio_rqueue(cid, GE_QUEUE, NIQESIZE, &rqe, app_data) == SCPE_OK) { - ni_cmd(cid, &rqe, app_data, FALSE); - } -} - -/* - * Handler for CIO RESET requests. - */ -void ni_cio_reset(uint8 cid) -{ - UNUSED(cid); - - ni_disable(); -} - -t_stat ni_autoconfig() -{ - uint8 cid; - - /* Clear the CIO table of NI cards */ - for (cid = 0; cid < CIO_SLOTS; cid++) { - if (cio[cid].id == NI_ID) { - cio[cid].id = 0; - cio[cid].ipl = 0; - cio[cid].ivec = 0; - cio[cid].exp_handler = NULL; - cio[cid].full_handler = NULL; - cio[cid].reset_handler = NULL; - cio[cid].sysgen = NULL; - } - } - - /* Find the first avaialable slot */ - for (cid = 0; cid < CIO_SLOTS; cid++) { - if (cio[cid].id == 0) { - break; - } - } - - /* Do we have room? */ - if (cid >= CIO_SLOTS) { - return SCPE_NXM; - } - - /* Remember the card slot */ - ni.cid = cid; - - /* Set up the ni structure */ - cio[cid].id = NI_ID; - cio[cid].ipl = NI_IPL; - cio[cid].exp_handler = &ni_express; - cio[cid].full_handler = &ni_full; - cio[cid].reset_handler = &ni_cio_reset; - cio[cid].sysgen = &ni_sysgen; - - return SCPE_OK; -} - -t_stat ni_reset(DEVICE *dptr) -{ - t_stat status; - char uname[16]; - - sim_debug(DBG_TRACE, &ni_dev, - "[ni_reset] Resetting NI device\n"); - - /* Initial setup that should only ever be done once. */ - if (!(dptr->flags & DEV_DIS) && !ni.initialized) { - /* Autoconfiguration will select the correct backplane slot - * for the device, and enable CIO routines. This should only - * be done once. */ - status = ni_autoconfig(); - if (status != SCPE_OK) { - return status; - } - - /* Set an initial MAC address in the AT&T NI range */ - ni_setmac(ni_dev.units, 0, "80:00:10:03:00:00/32", NULL); - - ni.initialized = TRUE; - } - - /* Set up unit names */ - snprintf(uname, 16, "%s-RCV", dptr->name); - sim_set_uname(rcv_unit, uname); - snprintf(uname, 16, "%s-SANITY", dptr->name); - sim_set_uname(sanity_unit, uname); - snprintf(uname, 16, "%s-RQ", dptr->name); - sim_set_uname(rq_unit, uname); - snprintf(uname, 16, "%s-CIO", dptr->name); - sim_set_uname(cio_unit, uname); - - /* Ensure that the broadcast address is configured, and that we - * have a minmimum of two filters set. */ - memset(&ni.macs[NI_BCST_MAC], 0xff, sizeof(ETH_MAC)); - ni.filter_count = NI_FILTER_MIN; - - ni.poll_rate = NI_QPOLL_FAST; - - /* Make sure the transceiver is disabled and all - * polling activity and interrupts are disabled. */ - ni_disable(); - - /* We make no attempt to autoconfig until the device - * is attached. */ - - return SCPE_OK; -} - -t_stat ni_rcv_svc(UNIT *uptr) -{ - t_stat read_succ; - - UNUSED(uptr); - - /* Since we cannot know which queue (large packet or small packet - * queue) will have room for the next packet that we read, for - * safety reasons we will not call eth_read() until we're certain - * there's room available in BOTH queues. */ - while (ni.enabled && NI_BUFFERS_AVAIL) { - read_succ = eth_read(ni.eth, &ni.rd_buf, NULL); - if (!read_succ) { - break; - } - /* Attempt to process the packet that was received. */ - ni_process_packet(); - } - - return SCPE_OK; -} - -/* - * Service used by the card to poll for available request queue - * entries. - */ -t_stat ni_rq_svc(UNIT *uptr) -{ - t_bool rq_taken; - int i, wp, no_rque; - cio_entry rqe = {0}; - uint8 slot[4] = {0}; - - UNUSED(uptr); - - rq_taken = FALSE; - no_rque = cio[ni.cid].no_rque - 1; - - for (i = 0; i < no_rque; i++) { - while (NI_CACHE_HAS_SPACE(i) && cio_rqueue(ni.cid, i+1, NIQESIZE, &rqe, slot) == SCPE_OK) { - sim_debug(DBG_CACHE, &ni_dev, - "[cache - FILL] %s packet entry. lp=%02x ulp=%02x " - "slot=%d addr=0x%08x\n", - i == 0 ? "Small" : "Large", - cio_r_lp(ni.cid, i+1, NIQESIZE), - cio_r_ulp(ni.cid, i+1, NIQESIZE), - slot[3], rqe.address); - wp = ni.job_cache[i].wp; - ni.job_cache[i].req[wp].addr = rqe.address; - ni.job_cache[i].req[wp].slot = slot[3]; - ni.job_cache[i].wp = (wp + 1) % NI_CACHE_LEN; - ni.stats.rq_taken++; - rq_taken = TRUE; - } - } - - /* Somewhat of a kludge, unfortunately. */ - if (ni.poll_rate == NI_QPOLL_FAST && ni.stats.rq_taken >= 6) { - sim_debug(DBG_TRACE, &ni_dev, - "[ni_rq_svc] Switching to slow poll mode.\n"); - ni.poll_rate = NI_QPOLL_SLOW; - } - - /* If any receive jobs were found, schedule a packet read right - away */ - if (rq_taken) { - sim_activate_abs(rcv_unit, 0); - } - - /* Reactivate the poller. */ - if (ni.poll_rate == NI_QPOLL_FAST) { - sim_activate_abs(rq_unit, NI_QPOLL_FAST); - } else { - if (sim_idle_enab) { - sim_clock_coschedule(rq_unit, tmxr_poll); - } else { - sim_activate_abs(rq_unit, NI_QPOLL_SLOW); - } - } - - return SCPE_OK; -} - -/* - * The NI card uses a sanity timer to poke the host every few seconds - * and let it know that it is still alive. This service handling - * routine is responsible for scheduling these notifications. - * - * The NI driver expects these notifications to happen no more than 15 - * seconds apart. Unfortunately, I do not yet know the exact frequency - * with which the real hardware sends these updates, but it appears - * not to happen very frequently, so we'll have to settle for an - * educated guess of 10 seconds. - */ -t_stat ni_sanity_svc(UNIT *uptr) -{ - cio_entry cqe = {0}; - uint8 app_data[4] = {0}; - - UNUSED(uptr); - - sim_debug(DBG_TRACE, &ni_dev, - "[ni_sanity_svc] Firing sanity timer.\n"); - - cqe.opcode = NI_SANITY; - cio_cqueue(ni.cid, CIO_STAT, NIQESIZE, &cqe, app_data); - - if (cio[ni.cid].ivec > 0) { - CIO_SET_INT(ni.cid); - } - - sim_activate_after(sanity_unit, NI_SANITY_INTERVAL_US); - - return SCPE_OK; -} - -t_stat ni_cio_svc(UNIT *uptr) -{ - UNUSED(uptr); - - if (cio[ni.cid].ivec > 0) { - sim_debug(DBG_TRACE, &ni_dev, - "[ni_cio_svc] Handling a CIO service (Setting Interrupt) for board %d\n", ni.cid); - CIO_SET_INT(ni.cid); - } - - return SCPE_OK; -} - -/* - * Do the work of trying to process the most recently received packet - */ -void ni_process_packet() -{ - int i, rp; - uint32 addr; - uint8 slot; - cio_entry centry = {0}; - uint8 capp_data[4] = {0}; - int len = 0; - int que_num = 0; - uint8 *rbuf; - - len = ni.rd_buf.len; - rbuf = ni.rd_buf.msg; - que_num = len > SM_PKT_MAX ? LG_QUEUE : SM_QUEUE; - - sim_debug(DBG_IO, &ni_dev, - "[ni_process_packet] Receiving a packet of size %d (0x%x)\n", - len, len); - - /* Availability of a job in the job cache was checked before - * calling ni_process_packet(), so there is no need to check it - * again. */ - rp = ni.job_cache[que_num].rp; - addr = ni.job_cache[que_num].req[rp].addr; - slot = ni.job_cache[que_num].req[rp].slot; - ni.job_cache[que_num].rp = (rp + 1) % NI_CACHE_LEN; - sim_debug(DBG_CACHE, &ni_dev, - "[cache - DRAIN] %s packet entry. lp=%02x ulp=%02x " - "slot=%d addr=0x%08x\n", - que_num == 0 ? "Small" : "Large", - cio_r_lp(ni.cid, que_num+1, NIQESIZE), - cio_r_ulp(ni.cid, que_num+1, NIQESIZE), - slot, addr); - - /* Store the packet into main memory */ - for (i = 0; i < len; i++) { - pwrite_b(addr + i, rbuf[i]); - } - - if (ni_dev.dctrl & DBG_DAT) { - dump_packet("RCV", &ni.rd_buf); - } - - ni.stats.rx_pkt++; - ni.stats.rx_bytes += len; - - /* Build a reply CIO message */ - centry.subdevice = 4; /* TODO: Why is it always 4? */ - centry.opcode = 0; - centry.address = addr + len; - centry.byte_count = len; - capp_data[3] = slot; - - /* TODO: We should probably also check status here. */ - cio_cqueue(ni.cid, CIO_STAT, NIQESIZE, ¢ry, capp_data); - - /* Trigger an interrupt */ - if (cio[ni.cid].ivec > 0) { - CIO_SET_INT(ni.cid); - } -} - -t_stat ni_attach(UNIT *uptr, CONST char *cptr) -{ - t_stat status; - char *tptr; - - sim_debug(DBG_TRACE, &ni_dev, "ni_attach()\n"); - - tptr = (char *) malloc(strlen(cptr) + 1); - if (tptr == NULL) { - return SCPE_MEM; - } - strcpy(tptr, cptr); - - ni.eth = (ETH_DEV *) malloc(sizeof(ETH_DEV)); - if (!ni.eth) { - free(tptr); - return SCPE_MEM; - } - - status = eth_open(ni.eth, cptr, &ni_dev, DBG_ETH); - if (status != SCPE_OK) { - sim_debug(DBG_ERR, &ni_dev, "ni_attach failure: open\n"); - free(tptr); - free(ni.eth); - ni.eth = NULL; - return status; - } - - status = eth_check_address_conflict(ni.eth, &ni.macs[NI_NIC_MAC]); - if (status != SCPE_OK) { - sim_debug(DBG_ERR, &ni_dev, "ni_attach failure: mac check\n"); - eth_close(ni.eth); - free(tptr); - free(ni.eth); - ni.eth = NULL; - return status; - } - - /* Ensure the ethernet device is in async mode */ - /* TODO: Determine best latency */ - status = eth_set_async(ni.eth, 1000); - if (status != SCPE_OK) { - sim_debug(DBG_ERR, &ni_dev, "ni_attach failure: eth_set_async\n"); - eth_close(ni.eth); - free(tptr); - free(ni.eth); - ni.eth = NULL; - return status; - } - - uptr->filename = tptr; - uptr->flags |= UNIT_ATT; - - eth_filter(ni.eth, ni.filter_count, ni.macs, 0, 0); - - return SCPE_OK; -} - -t_stat ni_detach(UNIT *uptr) -{ - sim_debug(DBG_TRACE, &ni_dev, "ni_detach()\n"); - - if (uptr->flags & UNIT_ATT) { - /* TODO: Do we really want to disable here? Or is that ONLY FCF's job? */ - /* ni_disable(); */ - eth_close(ni.eth); - free(ni.eth); - ni.eth = NULL; - free(uptr->filename); - uptr->filename = NULL; - uptr->flags &= ~UNIT_ATT; - } - - return SCPE_OK; -} - -t_stat ni_set_stats(UNIT* uptr, int32 val, CONST char* cptr, void* desc) -{ - int init, elements, i; - uint32 *stats_array; - - UNUSED(uptr); - UNUSED(val); - UNUSED(cptr); - UNUSED(desc); - - if (cptr) { - init = atoi(cptr); - stats_array = (uint32 *)&ni.stats; - elements = sizeof(ni_stat_info) / sizeof(uint32); - - for (i = 0 ; i < elements; i++) { - stats_array[i] = init; - } - } else { - memset(&ni.stats, 0, sizeof(ni_stat_info)); - } - - - return SCPE_OK; -} - -t_stat ni_show_stats(FILE* st, UNIT* uptr, int32 val, CONST void* desc) -{ - const char *fmt = " %-15s%d\n"; - - UNUSED(uptr); - UNUSED(val); - UNUSED(desc); - - fprintf(st, "NI Ethernet statistics:\n"); - fprintf(st, fmt, "Recv:", ni.stats.rx_pkt); - fprintf(st, fmt, "Recv Bytes:", ni.stats.rx_bytes); - fprintf(st, fmt, "Xmit:", ni.stats.tx_pkt); - fprintf(st, fmt, "Xmit Bytes:", ni.stats.tx_bytes); - fprintf(st, fmt, "Xmit Fail:", ni.stats.tx_fail); - - eth_show_dev(st, ni.eth); - - return SCPE_OK; -} - -t_stat ni_show_poll(FILE *st, UNIT *uptr, int32 val, CONST void *desc) -{ - UNUSED(uptr); - UNUSED(val); - UNUSED(desc); - - if (ni.poll_rate == NI_QPOLL_FAST) { - fprintf(st, "polling=fast"); - } else { - fprintf(st, "polling=slow"); - } - - return SCPE_OK; -} - - -t_stat ni_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr) -{ - const char help_string[] = - /****************************************************************************/ - " The Network Interface (NI) 10BASE5 controller is a Common I/O card for\n" - " the AT&T 3B2 that allows the 3B2 to connect to an Ethernet Local Area\n" - " Network (LAN).\n" - "1 Enabling\n" - " The simulator allows a single NI card to be configured in the first\n" - " available slot. The NI card is disabled at startup. To use the card\n" - " you must first enable it with the command:\n" - "\n" - "+sim> SET %D ENABLE\n" - "1 Configuration\n" - " By default, the card uses a self-assigned MAC address in the AT&T address\n" - " range (beginning with 80:00:10:03), however, another MAC may be set by\n" - " using the SET %D MAC command, e.g.:\n" - "\n" - "+sim> SET %D MAC=\n" - "\n" - " Please note, however, that the %D driver for AT&T System V R3 UNIX\n" - " always sets a MAC in the AT&T range through a software command.\n" - "1 Attaching\n" - " The %D card must be attached to a LAN device to communicate with systems\n" - " on the LAN.\n" - "\n" - " To get a list of available devices on your host platform, use the command:\n" - "\n" - "+sim> SHOW ETH\n" - "\n" - " After enabling the card, it can be attached to one of the host's\n" - " Ethernet devices with the ATTACH command. For example, depending on your\n" - " platform:\n" - "\n" - "+sim> ATTACH %D eth0\n" - "+sim> ATTACH %D en0\n" - "1 Dependencies\n" -#if defined(_WIN32) - " The WinPcap package must be installed in order to enable\n" - " communication with other computers on the local LAN.\n" - "\n" - " The WinPcap package is available from http://www.winpcap.org/\n" -#else - " To build simulators with the ability to communicate to other computers\n" - " on the local LAN, the libpcap development package must be installed on\n" - " the system which builds the simulator.\n" -#endif - "1 Performance\n" - " The simulated NI device is capable of much faster transfer speeds than\n" - " the real NI card in a 3B2, which was limited to a 10 Mbit pipe shared\n" - " between all hosts on the LAN.\n"; - - return scp_help(st, dptr, uptr, flag, help_string, cptr); -} - -const char *ni_description(DEVICE *dptr) -{ - UNUSED(dptr); - - return "NI 10BASE5 Ethernet controller"; -} - -/* - * Useful routines for debugging request and completion queues - */ - -static t_stat ni_show_rqueue(FILE *st, UNIT *uptr, int32 val, CONST void *desc) -{ - return ni_show_queue_common(st, uptr, val, desc, TRUE); -} - -static t_stat ni_show_cqueue(FILE *st, UNIT *uptr, int32 val, CONST void *desc) -{ - return ni_show_queue_common(st, uptr, val, desc, FALSE); -} - -static t_stat ni_show_queue_common(FILE *st, UNIT *uptr, int32 val, - CONST void *desc, t_bool rq) -{ - uint8 cid; - char *cptr = (char *) desc; - t_stat result; - uint32 ptr, size, no_rque, i, j; - uint16 lp, ulp; - uint8 op, dev, seq, cmdstat; - - UNUSED(uptr); - UNUSED(val); - - if (cptr) { - cid = (uint8) get_uint(cptr, 10, 12, &result); - if (result != SCPE_OK) { - return SCPE_ARG; - } - } else { - return SCPE_ARG; - } - - /* If the card is not sysgen'ed, give up */ - if (cio[cid].sysgen_s != CIO_SYSGEN) { - fprintf(st, "No card in slot %d, or card has not completed sysgen\n", cid); - return SCPE_ARG; - } - - fprintf(st, "---------------------------------------------------------\n"); - fprintf(st, "Sysgen Block:\n"); - fprintf(st, "---------------------------------------------------------\n"); - fprintf(st, " Request Queue Pointer: 0x%08x\n", cio[cid].rqp); - fprintf(st, " Completion Queue Pointer: 0x%08x\n", cio[cid].cqp); - fprintf(st, " Request Queue Size: 0x%02x\n", cio[cid].rqs); - fprintf(st, " Completion Queue Size: 0x%02x\n", cio[cid].cqs); - fprintf(st, " Interrupt Vector: %d (0x%02x)\n", cio[cid].ivec, cio[cid].ivec); - fprintf(st, " Number of Request Queues: %d\n", cio[cid].no_rque); - fprintf(st, "---------------------------------------------------------\n"); - - /* Get the top of the queue */ - if (rq) { - ptr = cio[cid].rqp; - size = cio[cid].rqs; - no_rque = cio[cid].no_rque; - } else { - ptr = cio[cid].cqp; - size = cio[cid].cqs; - no_rque = 0; /* Not used */ - } - - if (rq) { - fprintf(st, "Dumping %d Request Queues\n", no_rque); - } else { - fprintf(st, "Dumping Completion Queue\n"); - } - - fprintf(st, "---------------------------------------------------------\n"); - fprintf(st, "EXPRESS ENTRY:\n"); - fprintf(st, " Byte Count: %d\n", pread_h(ptr)); - fprintf(st, " Subdevice: %d\n", pread_b(ptr + 2)); - fprintf(st, " Opcode: 0x%02x\n", pread_b(ptr + 3)); - fprintf(st, " Addr/Data: 0x%08x\n", pread_w(ptr + 4)); - fprintf(st, " App Data: 0x%08x\n", pread_w(ptr + 8)); - ptr += 12; - - if (rq) { - for (i = 0; i < no_rque; i++) { - lp = pread_h(ptr); - ulp = pread_h(ptr + 2); - ptr += 4; - fprintf(st, "---------------------------------------------------------\n"); - fprintf(st, "REQUEST QUEUE %d\n", i); - fprintf(st, "---------------------------------------------------------\n"); - fprintf(st, "Load Pointer: 0x%04x (%d)\n", lp, (lp / NIQESIZE) + 1); - fprintf(st, "Unload Pointer: 0x%04x (%d)\n", ulp, (ulp / NIQESIZE) + 1); - fprintf(st, "---------------------------------------------------------\n"); - for (j = 0; j < size; j++) { - dev = pread_b(ptr + 2); - op = pread_b(ptr + 3); - seq = (dev & 0x40) >> 6; - cmdstat = (dev & 0x80) >> 7; - fprintf(st, "REQUEST ENTRY %d (@ 0x%08x)\n", j + 1, ptr); - fprintf(st, " Byte Count: 0x%04x\n", pread_h(ptr)); - fprintf(st, " Subdevice: %d\n", dev & 0x3f); - fprintf(st, " Cmd/Stat: %d\n", cmdstat); - fprintf(st, " Seqbit: %d\n", seq); - fprintf(st, " Opcode: 0x%02x (%d)\n", op, op); - fprintf(st, " Addr/Data: 0x%08x\n", pread_w(ptr + 4)); - fprintf(st, " App Data: 0x%08x\n", pread_w(ptr + 8)); - ptr += 12; - } - } - } else { - lp = pread_h(ptr); - ulp = pread_h(ptr + 2); - ptr += 4; - fprintf(st, "---------------------------------------------------------\n"); - fprintf(st, "Load Pointer: 0x%04x (%d)\n", lp, (lp / NIQESIZE) + 1); - fprintf(st, "Unload Pointer: 0x%04x (%d)\n", ulp, (ulp / NIQESIZE) + 1); - fprintf(st, "---------------------------------------------------------\n"); - for (i = 0; i < size; i++) { - dev = pread_b(ptr + 2); - op = pread_b(ptr + 3); - seq = (dev & 0x40) >> 6; - cmdstat = (dev & 0x80) >> 7; - fprintf(st, "COMPLETION ENTRY %d (@ 0x%08x)\n", i + 1, ptr); - fprintf(st, " Byte Count: 0x%04x\n", pread_h(ptr)); - fprintf(st, " Subdevice: %d\n", dev & 0x3f); - fprintf(st, " Cmd/Stat: %d\n", cmdstat); - fprintf(st, " Seqbit: %d\n", seq); - fprintf(st, " Opcode: 0x%02x (%d)\n", op, op); - fprintf(st, " Addr/Data: 0x%08x\n", pread_w(ptr + 4)); - fprintf(st, " App Data: 0x%08x\n", pread_w(ptr + 8)); - ptr += 12; - } - } - - return SCPE_OK; -} +/* 3b2_ni.c: CM195A Network Interface CIO Card + + Copyright (c) 2018-2022, Seth J. Morabito + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + Except as contained in this notice, the name of the author shall + not be used in advertising or otherwise to promote the sale, use or + other dealings in this Software without prior written authorization + from the author. +*/ + +/* + * NI is an intelligent feature card for the 3B2 that provides a + * 10BASE5 Ethernet interface. + + * Overview + * -------- + * + * The NI board is based on the Common I/O (CIO) platform. Like other + * CIO boards, it uses an 80186 embedded processor. The board and the + * 3B2 host communicate by reading and writing to the 3B2's main + * memory at locations established by the host via a series of job + * request and job completion queues. Only three interrupts are used: + * Two interrupts (80186 interrupts INT0 and INT1) are triggered by + * the 3B2 and tell the card when work is available in the request + * queue. One WE32100 interrupt (at a negotiated vector and predefined + * IPL) is used by the CIO board to tell the 3B2 that a new entry is + * available in the completion queue. + * + * The on-board ROM does not contain the full firmware required to + * perform all application-specific work. Rather, it is used only to + * bootstrap the 80186 and provide essential communication between the + * 3B2 host and the board's internal RAM. During initialization, the + * host must upload application-specific code to the board's RAM and + * cause the board to start running it. This is known as + * "pumping". The 80186 binary code for the NI board under System V + * Release 3 is stored in the file `/lib/pump/ni` + * + * Implementation Details + * ---------------------- + * + * The 10BASE5 interface on the NI board is driven by an Intel 82586 + * IEEE 802.3 LAN Coprocessor, controlled by the board's 80186 + * CPU. The 82586 is completely opaque to the host due to the nature + * of the CIO protocol. Nevertheless, an attempt is made to simulate + * the behavior of the 82586 where appropriate and possible. + * + * The NI board uses a sanity timer to occasionally write a watchdog + * or heartbeat entry into the completion queue, indicating that the + * Ethernet interface is still alive and that all is well. If the UNIX + * driver has not seen this heartbeat after approximately 10 seconds, + * it will consider the board to be in an "DOWN" state and send it a + * TERM ioctl. + * + * The NI board does behave differently from the other CIO boards in + * one respect: Unlike other CIO boards, the NI board takes jobs from + * its two Packet Receive CIO request queues by polling them, and then + * stores the taken jobs in a small 4-entry internal cache. It polls + * these queues quite rapidly in the real NI so it always has a full + * cache available for future incoming packets. To prevent performance + * issues, this simulation polls rapidly ("fast polling mode") only + * when absolutely necessary. Typically, that means only after the + * card has been reset, but before the request queues have finished + * being built by the 3B2 host. The UNIX NI driver expects and + * requires this behavior! + * + * Open Issues + * ----------- + * + * 1. The simulated card does not yet support setting or removing + * multicast Ethernet addresses. ioctl operations that attempt to + * set or remove multicast Ethernet addresses should silently + * fail. This will be supported in a future release. + * + */ + +#include "3b2_ni.h" + +#include "3b2_io.h" +#include "3b2_mem.h" +#include "3b2_stddev.h" + +/* State container for the card */ +NI_STATE ni; + +t_bool ni_conf = FALSE; + +/* Static Function Declarations */ +static void dump_packet(const char *direction, ETH_PACK *pkt); +static void ni_enable(); +static void ni_disable(); +static void ni_cmd(uint8 slot, cio_entry *rentry, uint8 *rapp_data, t_bool is_exp); + +/* + * A list of pumped code CRCs that will cause Force Function Call to + * respond with "Test Passed". Must be null-terminated. + */ +static const uint32 NI_DIAG_CRCS[] = { + 0x795268a4, + 0xfab1057c, + 0x10ca00cd, + 0x9b3ddeda, + 0x267b19a0, + 0x123f36c0, + 0xc04ca0ab, + 0x96d0506e, /* Rev 3 NI, SVR 3.2.3 */ + 0x9d3fafde, /* Rev 3 NI, SVR 3.2.3 */ + 0, +}; + +/* + * A list of pumped code CRCs that will cause the sysgen routine to + * respond with a full completion request instead of an express + * completion request. Must be null-terminated. + */ +static const uint32 NI_PUMP_CRCS[] = { + 0xfab1057c, /* Rev 2 NI, SVR 3.x */ + 0xf6744bed, /* Rev 2 NI, SVR 3.x */ + 0x96d0506e, /* Rev 3 NI, SVR 3.2.3 */ + 0x9d3fafde, /* Rev 3 NI, SVR 3.2.3 */ + 0x3553230a, /* Rev 3 NI, SVR 3.2.3 */ + 0, +}; + +/* + * Unit 0: Packet reception. + * Unit 1: Sanity timer. + * Unit 2: Request Queue poller. + * Unit 3: CIO requests. + */ +UNIT ni_unit[] = { + { UDATA(&ni_rcv_svc, UNIT_IDLE|UNIT_ATTABLE, 0) }, + { UDATA(&ni_sanity_svc, UNIT_IDLE|UNIT_DIS, 0) }, + { UDATA(&ni_rq_svc, UNIT_IDLE|UNIT_DIS, 0) }, + { UDATA(&ni_cio_svc, UNIT_DIS, 0) }, + { 0 } +}; + +static UNIT *rcv_unit = &ni_unit[0]; +static UNIT *sanity_unit = &ni_unit[1]; +static UNIT *rq_unit = &ni_unit[2]; +static UNIT *cio_unit = &ni_unit[3]; + +MTAB ni_mod[] = { + { MTAB_XTD|MTAB_VDV|MTAB_NMO, 0, "STATS", "STATS", + &ni_set_stats, &ni_show_stats, NULL, "Display or reset statistics" }, + { MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, "POLL", NULL, + NULL, &ni_show_poll, NULL, "Display the current polling mode" }, + { MTAB_XTD|MTAB_VDV|MTAB_VALR|MTAB_NC, 0, "MAC", "MAC=xx:xx:xx:xx:xx:xx", + &ni_setmac, &ni_showmac, NULL, "MAC address" }, + { MTAB_XTD|MTAB_VDV|MTAB_NMO, 0, "FILTERS", NULL, + NULL, &ni_show_filters, NULL, "Display address filters" }, + { 0 } +}; + +static DEBTAB ni_debug[] = { + { "TRACE", DBG_TRACE, "trace routine calls" }, + { "IO", DBG_IO, "debug i/o" }, + { "CACHE", DBG_CACHE, "debug job cache" }, + { "PACKET", DBG_DAT, "display packet data" }, + { "ERR", DBG_ERR, "display errors" }, + { "ETH", DBG_ETH, "debug ethernet device" }, + { 0 } +}; + +DEVICE ni_dev = { + "NI", /* name */ + ni_unit, /* units */ + NULL, /* registers */ + ni_mod, /* modifiers */ + 4, /* #units */ + 16, /* address radix */ + 32, /* address width */ + 1, /* address incr. */ + 16, /* data radix */ + 8, /* data width */ + NULL, /* examine routine */ + NULL, /* deposit routine */ + &ni_reset, /* reset routine */ + NULL, /* boot routine */ + &ni_attach, /* attach routine */ + &ni_detach, /* detach routine */ + NULL, /* context */ + DEV_DISABLE|DEV_DIS| + DEV_DEBUG|DEV_ETHER, /* flags */ + 0, /* debug control flags */ + ni_debug, /* debug flag names */ + NULL, /* memory size change */ + NULL, /* logical name */ + &ni_help, /* help routine */ + NULL, /* attach help routine */ + NULL, /* help context */ + &ni_description, /* device description */ + NULL, +}; + +static void dump_packet(const char *direction, ETH_PACK *pkt) +{ + char dumpline[82]; + char *p; + uint32 char_offset, i; + + if (!direction) { + return; + } + + snprintf(dumpline, 10, "%08x ", 0); + char_offset = 9; + + for (i = 0; i < pkt->len; i++) { + snprintf(dumpline + char_offset, 4, "%02x ", pkt->msg[i]); + snprintf(dumpline + 61 + (i % 16), 2, "%c", CHAR(pkt->msg[i])); + char_offset += 3; + + if ((i + 1) % 16 == 0) { + + snprintf(dumpline + 56, 5, " |"); + snprintf(dumpline + 78, 2, "|"); + + for (p = dumpline; p < (dumpline + 80); p++) { + if (*p == '\0') { + *p = ' '; + } + } + *p = '\0'; + sim_debug(DBG_DAT, &ni_dev, + "[%s packet]: %s\n", direction, dumpline); + memset(dumpline, 0, 80); + snprintf(dumpline, 10, "%08x ", i + 1); + char_offset = 9; + } + } + + /* Finish any leftover bits */ + if ((i + 1) % 16 != 0) { + snprintf(dumpline + 56, 5, " |"); + snprintf(dumpline + 78, 2, "|"); + + for (p = dumpline; p < (dumpline + 80); p++) { + if (*p == '\0') { + *p = ' '; + } + } + *p = '\0'; + + sim_debug(DBG_DAT, &ni_dev, + "[%s packet]: %s\n", direction, dumpline); + } +} + +static void ni_enable() +{ + sim_debug(DBG_TRACE, &ni_dev, + "[ni_enable] Enabling the interface.\n"); + + /* Reset Statistics */ + memset(&ni.stats, 0, sizeof(ni_stat_info)); + + /* Clear out job cache */ + memset(&ni.job_cache, 0, sizeof(ni_job_cache) * 2); + + /* Enter fast polling mode */ + ni.poll_rate = NI_QPOLL_FAST; + + /* Start the queue poller in fast poll mode */ + sim_activate_abs(rq_unit, NI_QPOLL_FAST); + + /* Start the sanity timer */ + sim_activate_after(sanity_unit, NI_SANITY_INTERVAL_US); + + /* Enable the interface */ + ni.enabled = TRUE; +} + +static void ni_disable() +{ + sim_debug(DBG_TRACE, &ni_dev, + "[ni_disable] Disabling the interface.\n"); + ni.enabled = FALSE; + sim_cancel(ni_unit); + sim_cancel(rcv_unit); + sim_cancel(rq_unit); + sim_cancel(cio_unit); + sim_cancel(sanity_unit); + CIO_CLR_INT(ni.slot); +} + +static void ni_cmd(uint8 slot, cio_entry *rentry, uint8 *rapp_data, t_bool is_exp) +{ + int i, j; + int32 delay; + uint16 hdrsize; + t_stat status; + int prot_info_offset; + cio_entry centry = {0}; + uint8 app_data[4] = {rapp_data[0], rapp_data[1], rapp_data[2], rapp_data[3]}; + + /* Assume some default values, but let the handlers below + * override these where appropriate */ + centry.opcode = CIO_SUCCESS; + centry.subdevice = rentry->subdevice; + centry.address = rentry->address; + + cio[slot].op = rentry->opcode; + + delay = NI_INT_DELAY; + + switch(rentry->opcode) { + case CIO_DLM: + for (i = 0; i < rentry->byte_count; i++) { + ni.crc = cio_crc32_shift(ni.crc, pread_b(rentry->address + i, BUS_PER)); + } + + centry.address = rentry->address + rentry->byte_count; + sim_debug(DBG_TRACE, &ni_dev, + "[ni_cmd] CIO Download Memory: bytecnt=%04x " + "addr=%08x return_addr=%08x subdev=%02x (CRC=%08x)\n", + rentry->byte_count, rentry->address, + centry.address, centry.subdevice, ni.crc); + + if (is_exp) { + cio_cexpress(slot, NIQESIZE, ¢ry, app_data); + } else { + cio_cqueue(slot, CIO_STAT, NIQESIZE, ¢ry, app_data); + } + + break; + case CIO_FCF: + sim_debug(DBG_TRACE, &ni_dev, + "[ni_cmd] CIO Force Function Call (CRC=%08x)\n", + ni.crc); + + /* If the currently running program is a diagnostics program, + * we are expected to write results into memory at address + * 0x200f000 */ + for (i = 0; NI_DIAG_CRCS[i] != 0; i++) { + if (ni.crc == NI_DIAG_CRCS[i]) { + pwrite_h(0x200f000, 0x1, BUS_PER); /* Test success */ + pwrite_h(0x200f002, 0x0, BUS_PER); /* Test Number */ + pwrite_h(0x200f004, 0x0, BUS_PER); /* Actual */ + pwrite_h(0x200f006, 0x0, BUS_PER); /* Expected */ + pwrite_b(0x200f008, 0x1, BUS_PER); /* Success flag again */ + break; + } + } + + /* Store the sequence byte we were sent for later reply. */ + ni.fcf_seq = rapp_data[3]; + + /* "Force Function Call" causes the CIO card to start running + * pumped code as a new process, taking over from its firmware + * ROM. As a result, a new sysgen is necessary to get the card + * in the right state. */ + + ni_disable(); + cio[slot].sysgen_s = 0; + + if (cio[slot].ivec == 0 || cio[slot].ivec == 3) { + cio_cexpress(slot, NIQESIZE, ¢ry, app_data); + } else { + cio_cqueue(slot, CIO_STAT, NIQESIZE, ¢ry, app_data); + } + + break; + case CIO_DSD: + /* Determine Sub-Devices. We have none. */ + sim_debug(DBG_TRACE, &ni_dev, + "[ni_cmd] Determine Sub-Devices.\n"); + + /* The system wants us to write sub-device structures at the + * supplied address */ + pwrite_h(rentry->address, 0x0, BUS_PER); + + if (is_exp) { + cio_cexpress(slot, NIQESIZE, ¢ry, app_data); + } else { + cio_cqueue(slot, CIO_STAT, NIQESIZE, ¢ry, app_data); + } + + break; + case NI_SETID: + sim_debug(DBG_TRACE, &ni_dev, + "[ni_cmd] NI SETID Operation\n"); + + /* Try to read the mac from memory */ + for (i = 0; i < MAC_SIZE_BYTES; i++) { + ni.mac_bytes[i] = pread_b(rentry->address + i, BUS_PER); + } + + snprintf(ni.mac_str, MAC_SIZE_CHARS, "%02x:%02x:%02x:%02x:%02x:%02x", + ni.mac_bytes[0], ni.mac_bytes[1], ni.mac_bytes[2], + ni.mac_bytes[3], ni.mac_bytes[4], ni.mac_bytes[5]); + + sim_debug(DBG_TRACE, &ni_dev, + "[ni_cmd] NI SETID: New MAC: %s\n", + ni.mac_str); + + status = ni_setmac(ni_dev.units, 0, ni.mac_str, NULL); + + cio_cqueue(slot, CIO_STAT, NIQESIZE, ¢ry, app_data); + + break; + case NI_TURNOFF: + sim_debug(DBG_TRACE, &ni_dev, + "[ni_cmd] NI TURNOFF Operation\n"); + + ni_disable(); + + cio_cqueue(slot, CIO_STAT, NIQESIZE, ¢ry, app_data); + + break; + case NI_TURNON: + sim_debug(DBG_TRACE, &ni_dev, + "[ni_cmd] NI TURNON Operation\n"); + + ni_enable(); + + cio_cqueue(slot, CIO_STAT, NIQESIZE, ¢ry, app_data); + + break; + case NI_STATS: + sim_debug(DBG_TRACE, &ni_dev, + "[ni_cmd] NI STATS Operation\n"); + + cio_cqueue(slot, CIO_STAT, NIQESIZE, ¢ry, app_data); + + break; + case NI_SEND: + case NI_SEND_A: + sim_debug(DBG_TRACE, &ni_dev, + "[ni_cmd] NI SEND Operation (opcode=%d)\n", + rentry->opcode); + + /* TODO: Why is this always 4 for a send? */ + centry.subdevice = 4; + + /* TODO: On the real 3B2, this appears to be some sort of + * checksum. Perhaps the packet checksum? I'm not sure. I need + * to run Wireshark on the real 3B2 and investigate. + * + * However, we're in luck: The driver code doesn't seem to + * validate it or check against it in any way, so we can + * put anything in there. + */ + centry.address = rentry->address; + centry.byte_count = rentry->byte_count; + + + /* If the interface is not attached, we can't actually send + * any packets. */ + if (!(rcv_unit->flags & UNIT_ATT)) { + ni.stats.tx_fail++; + centry.opcode = CIO_FAILURE; + sim_debug(DBG_TRACE, &ni_dev, + "[ni_cmd] NI SEND failure. Not attached. tx_fail=%d\n", + ni.stats.tx_fail); + break; + } + + /* Reset the write packet */ + ni.wr_buf.len = 0; + ni.wr_buf.oversize = NULL; + + /* Read the size of the header */ + hdrsize = pread_h(rentry->address + EIG_TABLE_SIZE, BUS_PER); + + /* Read out the packet frame */ + for (i = 0; i < rentry->byte_count; i++) { + ni.wr_buf.msg[i] = pread_b(rentry->address + PKT_START_OFFSET + i, BUS_PER); + } + + /* Get a pointer to the buffer containing the protocol data */ + prot_info_offset = 0; + i = 0; + do { + ni.prot.addr = pread_w(rentry->address + prot_info_offset, BUS_PER); + ni.prot.size = pread_h(rentry->address + prot_info_offset + 4, BUS_PER); + ni.prot.last = pread_h(rentry->address + prot_info_offset + 6, BUS_PER); + prot_info_offset += 8; + + /* Fill in the frame from this buffer */ + for (j=0; j < ni.prot.size; i++, j++) { + ni.wr_buf.msg[hdrsize + i] = pread_b(ni.prot.addr + j, BUS_PER); + } + } while (!ni.prot.last); + + /* Fill in packet details */ + ni.wr_buf.len = rentry->byte_count; + + sim_debug(DBG_IO, &ni_dev, + "[XMT] Transmitting a packet of size %d (0x%x)\n", + ni.wr_buf.len, ni.wr_buf.len); + + /* Send it */ + status = eth_write(ni.eth, &ni.wr_buf, NULL); + + if (status == SCPE_OK) { + if (ni_dev.dctrl & DBG_DAT) { + dump_packet("XMT", &ni.wr_buf); + } + ni.stats.tx_bytes += ni.wr_buf.len; + ni.stats.tx_pkt++; + } else { + ni.stats.tx_fail++; + centry.opcode = CIO_FAILURE; + } + + /* Weird behavior seen on the real 3B2's completion queue: If + * the byte count value is < 0xff, shift it! I really wish I + * understood this card... */ + if (centry.byte_count < 0xff) { + centry.byte_count <<= 8; + } + + cio_cqueue(slot, CIO_STAT, NIQESIZE, ¢ry, app_data); + + delay = 0; + + break; + default: + sim_debug(DBG_TRACE, &ni_dev, + "[ni_cmd] Opcode %d Not Handled Yet\n", + rentry->opcode); + + cio_cqueue(slot, CIO_STAT, NIQESIZE, ¢ry, app_data); + + break; + } + + sim_activate_abs(cio_unit, delay); +} + +t_stat ni_setmac(UNIT *uptr, int32 val, CONST char* cptr, void* desc) +{ + t_stat status; + + UNUSED(val); + UNUSED(desc); + + status = SCPE_OK; + status = eth_mac_scan_ex(&ni.macs[NI_NIC_MAC], cptr, uptr); + + if (status == SCPE_OK) { + eth_filter(ni.eth, ni.filter_count, ni.macs, 0, 0); + } else { + sim_debug(DBG_ERR, &ni_dev, + "[ni_setmac] Error in eth_mac_scan_ex. status=%d\n", status); + } + + return status; +} + +t_stat ni_showmac(FILE* st, UNIT* uptr, int32 val, CONST void* desc) +{ + char buffer[20]; + + UNUSED(uptr); + UNUSED(val); + UNUSED(desc); + + eth_mac_fmt(&ni.macs[NI_NIC_MAC], buffer); + fprintf(st, "MAC=%s", buffer); + return SCPE_OK; +} + +t_stat ni_show_filters(FILE* st, UNIT* uptr, int32 val, CONST void* desc) +{ + char buffer[20]; + int i; + + UNUSED(uptr); + UNUSED(val); + UNUSED(desc); + + eth_mac_fmt(&ni.macs[NI_NIC_MAC], buffer); + fprintf(st, "Physical Address=%s\n", buffer); + if (ni.filter_count > 0) { + fprintf(st, "Filters:\n"); + for (i=0; i < ni.filter_count; i++) { + eth_mac_fmt((ETH_MAC *) ni.macs[i], buffer); + fprintf(st, "[%2d]: %s\n", i, buffer); + } + fprintf(st, "\n"); + } + + return SCPE_OK; +} + +void ni_sysgen(uint8 slot) +{ + int i; + t_bool pumped = FALSE; + cio_entry cqe = {0}; + uint8 app_data[4] = {0}; + + ni_disable(); + + app_data[3] = 0x64; + cqe.opcode = CIO_SYSGEN_OK; + + sim_debug(DBG_TRACE, &ni_dev, + "[ni_sysgen] CIO SYSGEN. rqp=%08x, cqp=%08x, nrq=%d, rqs=%d cqs=%d\n", + cio[slot].rqp, cio[slot].cqp, cio[slot].no_rque, cio[slot].rqs, cio[slot].cqs); + + /* If the card has been successfully pumped, then we respond with + * a full completion queue entry. Otherwise, an express entry is + * used. */ + for (i = 0; NI_PUMP_CRCS[i] != 0; i++) { + if (NI_PUMP_CRCS[i] == ni.crc) { + cio_cqueue(slot, CIO_STAT, NIQESIZE, &cqe, app_data); + pumped = TRUE; + break; + } + } + + if (!pumped) { + cio_cexpress(slot, NIQESIZE, &cqe, app_data); + } + + /* Now clear out the old CRC value, in case the card needs to be + * sysgen'ed again later. */ + ni.crc = 0; + + sim_activate_abs(cio_unit, NI_INT_DELAY); +} + +/* + * Handler for CIO INT0 (express job) requests. + */ +void ni_express(uint8 slot) +{ + cio_entry rqe = {0}; + uint8 app_data[4] = {0}; + + sim_debug(DBG_TRACE, &ni_dev, + "[ni_express] Handling express CIO request.\n"); + + cio_rexpress(slot, NIQESIZE, &rqe, app_data); + ni_cmd(slot, &rqe, app_data, TRUE); +} + +/* + * Handler for CIO INT1 (full job) requests. + */ +void ni_full(uint8 slot) +{ + cio_entry rqe = {0}; + uint8 app_data[4] = {0}; + + sim_debug(DBG_TRACE, &ni_dev, + "[ni_full] INT1 received. Handling full CIO request.\n"); + + while (cio_cqueue_avail(slot, NIQESIZE) && + cio_rqueue(slot, GE_QUEUE, NIQESIZE, &rqe, app_data) == SCPE_OK) { + ni_cmd(slot, &rqe, app_data, FALSE); + } +} + +/* + * Handler for CIO RESET requests. + */ +void ni_cio_reset(uint8 slot) +{ + UNUSED(slot); + + ni_disable(); +} + +t_stat ni_reset(DEVICE *dptr) +{ + t_stat r; + uint8 slot; + char uname[16]; + + if (dptr->flags & DEV_DIS) { + cio_remove_all(NI_ID); + ni_conf = FALSE; + return SCPE_OK; + } + + if (!ni_conf) { + r = cio_install(NI_ID, "NI", NI_IPL, + &ni_express, &ni_full, &ni_sysgen, &ni_cio_reset, + &slot); + if (r != SCPE_OK) { + return r; + } + /* Remember the card slot */ + ni.slot = slot; + ni_conf = TRUE; + } + + /* Set an initial MAC address in the AT&T NI range */ + ni_setmac(ni_dev.units, 0, "80:00:10:03:00:00/32", NULL); + + /* Set up unit names */ + snprintf(uname, 16, "%s-RCV", dptr->name); + sim_set_uname(rcv_unit, uname); + snprintf(uname, 16, "%s-SANITY", dptr->name); + sim_set_uname(sanity_unit, uname); + snprintf(uname, 16, "%s-RQ", dptr->name); + sim_set_uname(rq_unit, uname); + snprintf(uname, 16, "%s-CIO", dptr->name); + sim_set_uname(cio_unit, uname); + + /* Ensure that the broadcast address is configured, and that we + * have a minmimum of two filters set. */ + memset(&ni.macs[NI_BCST_MAC], 0xff, sizeof(ETH_MAC)); + ni.filter_count = NI_FILTER_MIN; + + ni.poll_rate = NI_QPOLL_FAST; + + /* Make sure the transceiver is disabled and all + * polling activity and interrupts are disabled. */ + ni_disable(); + + return SCPE_OK; +} + +t_stat ni_rcv_svc(UNIT *uptr) +{ + t_stat read_succ; + + UNUSED(uptr); + + /* Since we cannot know which queue (large packet or small packet + * queue) will have room for the next packet that we read, for + * safety reasons we will not call eth_read() until we're certain + * there's room available in BOTH queues. */ + while (ni.enabled && NI_BUFFERS_AVAIL) { + read_succ = eth_read(ni.eth, &ni.rd_buf, NULL); + if (!read_succ) { + break; + } + /* Attempt to process the packet that was received. */ + ni_process_packet(); + } + + return SCPE_OK; +} + +/* + * Service used by the card to poll for available request queue + * entries. + */ +t_stat ni_rq_svc(UNIT *uptr) +{ + t_bool rq_taken; + int i, wp, no_rque; + cio_entry rqe = {0}; + uint8 slot[4] = {0}; + + UNUSED(uptr); + + rq_taken = FALSE; + no_rque = cio[ni.slot].no_rque - 1; + + for (i = 0; i < no_rque; i++) { + while (NI_CACHE_HAS_SPACE(i) && cio_rqueue(ni.slot, i+1, NIQESIZE, &rqe, slot) == SCPE_OK) { + sim_debug(DBG_CACHE, &ni_dev, + "[cache - FILL] %s packet entry. lp=%02x ulp=%02x " + "slot=%d addr=0x%08x\n", + i == 0 ? "Small" : "Large", + cio_r_lp(ni.slot, i+1, NIQESIZE), + cio_r_ulp(ni.slot, i+1, NIQESIZE), + slot[3], rqe.address); + wp = ni.job_cache[i].wp; + ni.job_cache[i].req[wp].addr = rqe.address; + ni.job_cache[i].req[wp].slot = slot[3]; + ni.job_cache[i].wp = (wp + 1) % NI_CACHE_LEN; + ni.stats.rq_taken++; + rq_taken = TRUE; + } + } + + /* Somewhat of a kludge, unfortunately. */ + if (ni.poll_rate == NI_QPOLL_FAST && ni.stats.rq_taken >= 6) { + sim_debug(DBG_TRACE, &ni_dev, + "[ni_rq_svc] Switching to slow poll mode.\n"); + ni.poll_rate = NI_QPOLL_SLOW; + } + + /* If any receive jobs were found, schedule a packet read right + away */ + if (rq_taken) { + sim_activate_abs(rcv_unit, 0); + } + + /* Reactivate the poller. */ + if (ni.poll_rate == NI_QPOLL_FAST) { + sim_activate_abs(rq_unit, NI_QPOLL_FAST); + } else { + sim_clock_coschedule(rq_unit, 1000); + } + + return SCPE_OK; +} + +/* + * The NI card uses a sanity timer to poke the host every few seconds + * and let it know that it is still alive. This service handling + * routine is responsible for scheduling these notifications. + * + * The NI driver expects these notifications to happen no more than 15 + * seconds apart. Unfortunately, I do not yet know the exact frequency + * with which the real hardware sends these updates, but it appears + * not to happen very frequently, so we'll have to settle for an + * educated guess of 10 seconds. + */ +t_stat ni_sanity_svc(UNIT *uptr) +{ + cio_entry cqe = {0}; + uint8 app_data[4] = {0}; + + UNUSED(uptr); + + sim_debug(DBG_TRACE, &ni_dev, + "[ni_sanity_svc] Firing sanity timer.\n"); + + cqe.opcode = NI_SANITY; + cio_cqueue(ni.slot, CIO_STAT, NIQESIZE, &cqe, app_data); + + CIO_SET_INT(ni.slot); + + sim_activate_after(sanity_unit, NI_SANITY_INTERVAL_US); + + return SCPE_OK; +} + +t_stat ni_cio_svc(UNIT *uptr) +{ + UNUSED(uptr); + + sim_debug(DBG_TRACE, &ni_dev, + "[ni_cio_svc] Handling a CIO service (Setting Interrupt) for board %d\n", ni.slot); + CIO_SET_INT(ni.slot); + + return SCPE_OK; +} + +/* + * Do the work of trying to process the most recently received packet + */ +void ni_process_packet() +{ + int i, rp; + uint32 addr; + uint8 slot; + cio_entry centry = {0}; + uint8 capp_data[4] = {0}; + int len = 0; + int que_num = 0; + uint8 *rbuf; + + len = ni.rd_buf.len; + rbuf = ni.rd_buf.msg; + que_num = len > SM_PKT_MAX ? LG_QUEUE : SM_QUEUE; + + sim_debug(DBG_IO, &ni_dev, + "[ni_process_packet] Receiving a packet of size %d (0x%x)\n", + len, len); + + /* Availability of a job in the job cache was checked before + * calling ni_process_packet(), so there is no need to check it + * again. */ + rp = ni.job_cache[que_num].rp; + addr = ni.job_cache[que_num].req[rp].addr; + slot = ni.job_cache[que_num].req[rp].slot; + ni.job_cache[que_num].rp = (rp + 1) % NI_CACHE_LEN; + sim_debug(DBG_CACHE, &ni_dev, + "[cache - DRAIN] %s packet entry. lp=%02x ulp=%02x " + "slot=%d addr=0x%08x\n", + que_num == 0 ? "Small" : "Large", + cio_r_lp(ni.slot, que_num+1, NIQESIZE), + cio_r_ulp(ni.slot, que_num+1, NIQESIZE), + slot, addr); + + /* Store the packet into main memory */ + for (i = 0; i < len; i++) { + pwrite_b(addr + i, rbuf[i], BUS_PER); + } + + if (ni_dev.dctrl & DBG_DAT) { + dump_packet("RCV", &ni.rd_buf); + } + + ni.stats.rx_pkt++; + ni.stats.rx_bytes += len; + + /* Build a reply CIO message */ + centry.subdevice = 4; /* TODO: Why is it always 4? */ + centry.opcode = 0; + centry.address = addr + len; + centry.byte_count = len; + capp_data[3] = slot; + + /* TODO: We should probably also check status here. */ + cio_cqueue(ni.slot, CIO_STAT, NIQESIZE, ¢ry, capp_data); + + /* Trigger an interrupt */ + CIO_SET_INT(ni.slot); +} + +t_stat ni_attach(UNIT *uptr, CONST char *cptr) +{ + t_stat status; + char *tptr; + + sim_debug(DBG_TRACE, &ni_dev, "ni_attach()\n"); + + tptr = (char *) malloc(strlen(cptr) + 1); + if (tptr == NULL) { + return SCPE_MEM; + } + strcpy(tptr, cptr); + + ni.eth = (ETH_DEV *) malloc(sizeof(ETH_DEV)); + if (!ni.eth) { + free(tptr); + return SCPE_MEM; + } + + status = eth_open(ni.eth, cptr, &ni_dev, DBG_ETH); + if (status != SCPE_OK) { + sim_debug(DBG_ERR, &ni_dev, "ni_attach failure: open\n"); + free(tptr); + free(ni.eth); + ni.eth = NULL; + return status; + } + + status = eth_check_address_conflict(ni.eth, &ni.macs[NI_NIC_MAC]); + if (status != SCPE_OK) { + sim_debug(DBG_ERR, &ni_dev, "ni_attach failure: mac check\n"); + eth_close(ni.eth); + free(tptr); + free(ni.eth); + ni.eth = NULL; + return status; + } + + /* Ensure the ethernet device is in async mode */ + /* TODO: Determine best latency */ + status = eth_set_async(ni.eth, 1000); + if (status != SCPE_OK) { + sim_debug(DBG_ERR, &ni_dev, "ni_attach failure: eth_set_async\n"); + eth_close(ni.eth); + free(tptr); + free(ni.eth); + ni.eth = NULL; + return status; + } + + uptr->filename = tptr; + uptr->flags |= UNIT_ATT; + + eth_filter(ni.eth, ni.filter_count, ni.macs, 0, 0); + + return SCPE_OK; +} + +t_stat ni_detach(UNIT *uptr) +{ + sim_debug(DBG_TRACE, &ni_dev, "ni_detach()\n"); + + if (uptr->flags & UNIT_ATT) { + /* TODO: Do we really want to disable here? Or is that ONLY FCF's job? */ + /* ni_disable(); */ + eth_close(ni.eth); + free(ni.eth); + ni.eth = NULL; + free(uptr->filename); + uptr->filename = NULL; + uptr->flags &= ~UNIT_ATT; + } + + return SCPE_OK; +} + +t_stat ni_set_stats(UNIT* uptr, int32 val, CONST char* cptr, void* desc) +{ + int init, elements, i; + uint32 *stats_array; + + UNUSED(uptr); + UNUSED(val); + UNUSED(cptr); + UNUSED(desc); + + if (cptr) { + init = atoi(cptr); + stats_array = (uint32 *)&ni.stats; + elements = sizeof(ni_stat_info) / sizeof(uint32); + + for (i = 0 ; i < elements; i++) { + stats_array[i] = init; + } + } else { + memset(&ni.stats, 0, sizeof(ni_stat_info)); + } + + + return SCPE_OK; +} + +t_stat ni_show_stats(FILE* st, UNIT* uptr, int32 val, CONST void* desc) +{ + const char *fmt = " %-15s%d\n"; + + UNUSED(uptr); + UNUSED(val); + UNUSED(desc); + + fprintf(st, "NI Ethernet statistics:\n"); + fprintf(st, fmt, "Recv:", ni.stats.rx_pkt); + fprintf(st, fmt, "Recv Bytes:", ni.stats.rx_bytes); + fprintf(st, fmt, "Xmit:", ni.stats.tx_pkt); + fprintf(st, fmt, "Xmit Bytes:", ni.stats.tx_bytes); + fprintf(st, fmt, "Xmit Fail:", ni.stats.tx_fail); + + eth_show_dev(st, ni.eth); + + return SCPE_OK; +} + +t_stat ni_show_poll(FILE *st, UNIT *uptr, int32 val, CONST void *desc) +{ + UNUSED(uptr); + UNUSED(val); + UNUSED(desc); + + if (ni.poll_rate == NI_QPOLL_FAST) { + fprintf(st, "polling=fast"); + } else { + fprintf(st, "polling=slow"); + } + + return SCPE_OK; +} + + +t_stat ni_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr) +{ + const char help_string[] = + /****************************************************************************/ + " The Network Interface (NI) 10BASE5 controller is a Common I/O card for\n" + " the AT&T 3B2 that allows the 3B2 to connect to an Ethernet Local Area\n" + " Network (LAN).\n" + "1 Enabling\n" + " The simulator allows a single NI card to be configured in the first\n" + " available slot. The NI card is disabled at startup. To use the card\n" + " you must first enable it with the command:\n" + "\n" + "+sim> SET %D ENABLE\n" + "1 Configuration\n" + " By default, the card uses a self-assigned MAC address in the AT&T address\n" + " range (beginning with 80:00:10:03), however, another MAC may be set by\n" + " using the SET %D MAC command, e.g.:\n" + "\n" + "+sim> SET %D MAC=\n" + "\n" + " Please note, however, that the %D driver for AT&T System V R3 UNIX\n" + " always sets a MAC in the AT&T range through a software command.\n" + "1 Attaching\n" + " The %D card must be attached to a LAN device to communicate with systems\n" + " on the LAN.\n" + "\n" + " To get a list of available devices on your host platform, use the command:\n" + "\n" + "+sim> SHOW ETH\n" + "\n" + " After enabling the card, it can be attached to one of the host's\n" + " Ethernet devices with the ATTACH command. For example, depending on your\n" + " platform:\n" + "\n" + "+sim> ATTACH %D eth0\n" + "+sim> ATTACH %D en0\n" + "1 Dependencies\n" +#if defined(_WIN32) + " The WinPcap package must be installed in order to enable\n" + " communication with other computers on the local LAN.\n" + "\n" + " The WinPcap package is available from http://www.winpcap.org/\n" +#else + " To build simulators with the ability to communicate to other computers\n" + " on the local LAN, the libpcap development package must be installed on\n" + " the system which builds the simulator.\n" +#endif + "1 Performance\n" + " The simulated NI device is capable of much faster transfer speeds than\n" + " the real NI card in a 3B2, which was limited to a 10 Mbit pipe shared\n" + " between all hosts on the LAN.\n"; + + return scp_help(st, dptr, uptr, flag, help_string, cptr); +} + +const char *ni_description(DEVICE *dptr) +{ + UNUSED(dptr); + + return "NI 10BASE5 Ethernet controller"; +} diff --git a/3B2/3b2_ni.h b/3B2/3b2_ni.h index b8c169a9..99234104 100644 --- a/3B2/3b2_ni.h +++ b/3B2/3b2_ni.h @@ -1,214 +1,210 @@ -/* 3b2_ni.h: AT&T 3B2 Model 400 "NI" feature card - - Copyright (c) 2018, Seth J. Morabito - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - - Except as contained in this notice, the name of the author shall - not be used in advertising or otherwise to promote the sale, use or - other dealings in this Software without prior written authorization - from the author. -*/ - -#ifndef _3B2_NI_H_ -#define _3B2_NI_H_ - -#include "3b2_defs.h" -#include "sim_ether.h" - -#define NI_ID 0x0002 -#define NI_IPL 12 - -/* Opcodes for NI card */ - -#define NI_SETID 6 -#define NI_TURNOFF 7 -#define NI_TURNON 8 -#define NI_SEND 11 -#define NI_RECV 12 -#define NI_STATS 13 -#define NI_SANITY 15 -#define NI_SEND_A 22 - -#define MAC_SIZE_BYTES 6 -#define MAC_SIZE_CHARS 20 - -#define NIQESIZE 12 -#define NI_QUE_MAX 1024 -#define NI_INT_DELAY 10000 -#define NI_SANITY_INTERVAL_US 5000000 - -/* Maximum allowed number of multicast addresses */ -#define NI_MULTI_MAX 64 - -/* At least two filter addresses are always configured: - * 1. The host MAC - * 2. The broadcast address */ -#define NI_FILTER_MIN 2 - -/* Maximum total allowed number of filter addresses, including the - * host's MAC and the broadcast address. */ -#define NI_FILTER_MAX NI_MULTI_MAX + NI_FILTER_MIN - -/* Indexes in the internal filter address table of the - * host's MAC and the broadcast address */ -#define NI_NIC_MAC 0 -#define NI_BCST_MAC 1 - -/* - * For performance reasons, there are two modes of polling the receive - * queues. Initially, polling is VERY aggressive as we race the - * filling of the receive queues. Once we've taken three jobs from - * each of the two receive queues, we switch to slow polling, - * which uses coscheduling. - */ - -#define NI_QPOLL_FAST 100 -#define NI_QPOLL_SLOW 50000 - -#define NI_PUMP_CRC1 0xfab1057c -#define NI_PUMP_CRC2 0xf6744bed - -#define EIG_TABLE_SIZE 40 -#define PKT_HEADER_LEN_OFFSET EIG_TABLE_SIZE -#define PKT_START_OFFSET (PKT_HEADER_LEN_OFFSET + 4) - -/* - * The NI card has two request queues for packet receive: One for - * small packets, and one for large packets. The small queue is meant - * for packets smaller than 128 bytes. The large queue is meant for - * packets up to 1500 bytes (no jumbo frames allowed) - */ - -#define GE_QUEUE 0 /* General request CIO queue */ -#define SM_QUEUE 0 /* Small packet receive queue number */ -#define LG_QUEUE 1 /* Large packet receive queue number */ -#define SM_PKT_MAX 106 /* Max size of small packets (excluding CRC) */ -#define LG_PKT_MAX 1514 /* Max size of large packets (excluding CRC) */ - -/* - * NI-specific debugging flags - */ -#define DBG_TRACE 0x01 -#define DBG_IO 0x02 -#define DBG_CACHE 0x04 -#define DBG_DAT 0x08 -#define DBG_ERR 0x10 -#define DBG_ETH 0x20 - -#define CHAR(c) ((((c) >= 0x20) && ((c) < 0x7f)) ? (c) : '.') - -#define NI_CACHE_HAS_SPACE(i) (((ni.job_cache[(i)].wp + 1) % NI_CACHE_LEN) != ni.job_cache[(i)].rp) -/* Determine whether both job caches have available slots */ -#define NI_BUFFERS_AVAIL ((ni.job_cache[0].wp != ni.job_cache[0].rp) && \ - (ni.job_cache[1].wp != ni.job_cache[1].rp)) - -/* - * The NI card caches up to three jobs taken from each of the two - * packet receive queues so that they are available immediately after - * receipt of a packet. These jobs are kept in small circular buffers. - * Each job is represented by an ni_rec_job structure, containing a - * buffer pointer and a slot number. The slot number is used by both - * the driver and the firmware to correlate a packet receive buffer - * with a completion queue event. - */ -typedef struct { - uint32 addr; /* address of job's buffer */ - uint8 slot; /* slot number of the job */ -} ni_rec_job; - -#define NI_CACHE_LEN 4 - -typedef struct { - ni_rec_job req[NI_CACHE_LEN]; /* the cache */ - int wp; /* write pointer */ - int rp; /* read pointer */ -} ni_job_cache; - -/* - * When the NI driver submits a packet send request to the general - * request queue, it constructs one or more ni_prot_info structs in - * main memory that point to the protocol-specific byte data of the - * packet (minus the Ethernet frame). These structs are packed one - * after the other following the Ethernet frame header in the job's - * request buffer. The last entry has its "last" bit set to non-zero. - */ -typedef struct { - uint32 addr; /* Physical address of the buffer in system RAM */ - uint16 size; /* Length of the buffer */ - uint16 last; /* Is this the last entry in the list? */ -} ni_prot_info; - -typedef struct { - uint32 rq_taken; - uint32 tx_fail; - uint32 rx_dropped; - uint32 rx_pkt; - uint32 tx_pkt; - uint32 rx_bytes; - uint32 tx_bytes; -} ni_stat_info; - -typedef struct { - uint8 cid; - t_bool initialized; - t_bool enabled; - uint32 crc; - uint32 poll_rate; - char mac_str[MAC_SIZE_CHARS]; - uint8 mac_bytes[MAC_SIZE_BYTES]; - ni_job_cache job_cache[2]; - ni_prot_info prot; - ni_stat_info stats; - uint8 fcf_seq; - ETH_DEV* eth; - ETH_PACK rd_buf; - ETH_PACK wr_buf; - ETH_MAC macs[NI_FILTER_MAX]; /* List of all filter addresses */ - int filter_count; /* Number of filters available */ - ETH_PCALLBACK callback; -} NI_STATE; - -void ni_recv_callback(int status); -t_stat ni_reset(DEVICE *dptr); -t_stat ni_rcv_svc(UNIT *uptr); -t_stat ni_sanity_svc(UNIT *uptr); -t_stat ni_rq_svc(UNIT *uptr); -t_stat ni_cio_svc(UNIT *uptr); -t_stat ni_attach(UNIT *uptr, CONST char *cptr); -t_stat ni_detach(UNIT *uptr); -t_stat ni_setmac(UNIT *uptr, int32 val, CONST char *cptr, void *desc); -t_stat ni_showmac(FILE* st, UNIT *uptr, int32 val, CONST void *desc); -t_stat ni_try_job(uint8 cid); -t_stat ni_show_stats(FILE *st, UNIT *uptr, int32 val, CONST void *desc); -t_stat ni_set_stats(UNIT *uptr, int32 val, CONST char *cptr, void *desc); -t_stat ni_show_poll(FILE *st, UNIT *uptr, int32 val, CONST void *desc); -t_stat ni_show_filters(FILE *st, UNIT *uptr, int32 val, CONST void *desc); -const char *ni_description(DEVICE *dptr); -t_stat ni_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr); -void ni_cio_reset(uint8 cid); -void ni_process_packet(); -void ni_int_ack(uint8 cid); -void ni_sysgen(uint8 cid); -void ni_express(uint8 cid); -void ni_full(uint8 cid); - -#endif /* _3B2_NI_H_ */ +/* 3b2_ni.h: CM195A Network Interface CIO Card + + Copyright (c) 2018-2022, Seth J. Morabito + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + Except as contained in this notice, the name of the author shall + not be used in advertising or otherwise to promote the sale, use or + other dealings in this Software without prior written authorization + from the author. +*/ + +#ifndef _3B2_NI_H_ +#define _3B2_NI_H_ + +#include "3b2_defs.h" +#include "sim_ether.h" + +#define NI_ID 0x0002 +#define NI_IPL 12 + +/* Opcodes for NI card */ + +#define NI_SETID 6 +#define NI_TURNOFF 7 +#define NI_TURNON 8 +#define NI_SEND 11 +#define NI_RECV 12 +#define NI_STATS 13 +#define NI_SANITY 15 +#define NI_SEND_A 22 + +#define MAC_SIZE_BYTES 6 +#define MAC_SIZE_CHARS 20 + +#define NIQESIZE 12 +#define NI_QUE_MAX 1024 +#define NI_INT_DELAY 10000 +#define NI_SANITY_INTERVAL_US 5000000 + +/* Maximum allowed number of multicast addresses */ +#define NI_MULTI_MAX 64 + +/* At least two filter addresses are always configured: + * 1. The host MAC + * 2. The broadcast address */ +#define NI_FILTER_MIN 2 + +/* Maximum total allowed number of filter addresses, including the + * host's MAC and the broadcast address. */ +#define NI_FILTER_MAX NI_MULTI_MAX + NI_FILTER_MIN + +/* Indexes in the internal filter address table of the + * host's MAC and the broadcast address */ +#define NI_NIC_MAC 0 +#define NI_BCST_MAC 1 + +/* + * For performance reasons, there are two modes of polling the receive + * queues. Initially, polling is VERY aggressive as we race the + * filling of the receive queues. Once we've taken three jobs from + * each of the two receive queues, we switch to slow polling, + * which uses coscheduling. + */ + +#define NI_QPOLL_FAST 100 +#define NI_QPOLL_SLOW 50000 + +#define EIG_TABLE_SIZE 40 +#define PKT_HEADER_LEN_OFFSET EIG_TABLE_SIZE +#define PKT_START_OFFSET (PKT_HEADER_LEN_OFFSET + 4) + +/* + * The NI card has two request queues for packet receive: One for + * small packets, and one for large packets. The small queue is meant + * for packets smaller than 128 bytes. The large queue is meant for + * packets up to 1500 bytes (no jumbo frames allowed) + */ + +#define GE_QUEUE 0 /* General request CIO queue */ +#define SM_QUEUE 0 /* Small packet receive queue number */ +#define LG_QUEUE 1 /* Large packet receive queue number */ +#define SM_PKT_MAX 106 /* Max size of small packets (excluding CRC) */ +#define LG_PKT_MAX 1514 /* Max size of large packets (excluding CRC) */ + +/* + * NI-specific debugging flags + */ +#define DBG_TRACE 0x01 +#define DBG_IO 0x02 +#define DBG_CACHE 0x04 +#define DBG_DAT 0x08 +#define DBG_ERR 0x10 +#define DBG_ETH 0x20 + +#define CHAR(c) ((((c) >= 0x20) && ((c) < 0x7f)) ? (c) : '.') + +#define NI_CACHE_HAS_SPACE(i) (((ni.job_cache[(i)].wp + 1) % NI_CACHE_LEN) != ni.job_cache[(i)].rp) +/* Determine whether both job caches have available slots */ +#define NI_BUFFERS_AVAIL ((ni.job_cache[0].wp != ni.job_cache[0].rp) && \ + (ni.job_cache[1].wp != ni.job_cache[1].rp)) + +/* + * The NI card caches up to three jobs taken from each of the two + * packet receive queues so that they are available immediately after + * receipt of a packet. These jobs are kept in small circular buffers. + * Each job is represented by an ni_rec_job structure, containing a + * buffer pointer and a slot number. The slot number is used by both + * the driver and the firmware to correlate a packet receive buffer + * with a completion queue event. + */ +typedef struct { + uint32 addr; /* address of job's buffer */ + uint8 slot; /* slot number of the job */ +} ni_rec_job; + +#define NI_CACHE_LEN 4 + +typedef struct { + ni_rec_job req[NI_CACHE_LEN]; /* the cache */ + int wp; /* write pointer */ + int rp; /* read pointer */ +} ni_job_cache; + +/* + * When the NI driver submits a packet send request to the general + * request queue, it constructs one or more ni_prot_info structs in + * main memory that point to the protocol-specific byte data of the + * packet (minus the Ethernet frame). These structs are packed one + * after the other following the Ethernet frame header in the job's + * request buffer. The last entry has its "last" bit set to non-zero. + */ +typedef struct { + uint32 addr; /* Physical address of the buffer in system RAM */ + uint16 size; /* Length of the buffer */ + uint16 last; /* Is this the last entry in the list? */ +} ni_prot_info; + +typedef struct { + uint32 rq_taken; + uint32 tx_fail; + uint32 rx_dropped; + uint32 rx_pkt; + uint32 tx_pkt; + uint32 rx_bytes; + uint32 tx_bytes; +} ni_stat_info; + +typedef struct { + uint8 slot; + t_bool enabled; + uint32 crc; + uint32 poll_rate; + char mac_str[MAC_SIZE_CHARS]; + uint8 mac_bytes[MAC_SIZE_BYTES]; + ni_job_cache job_cache[2]; + ni_prot_info prot; + ni_stat_info stats; + uint8 fcf_seq; + ETH_DEV* eth; + ETH_PACK rd_buf; + ETH_PACK wr_buf; + ETH_MAC macs[NI_FILTER_MAX]; /* List of all filter addresses */ + int filter_count; /* Number of filters available */ + ETH_PCALLBACK callback; +} NI_STATE; + +void ni_recv_callback(int status); +t_stat ni_reset(DEVICE *dptr); +t_stat ni_rcv_svc(UNIT *uptr); +t_stat ni_sanity_svc(UNIT *uptr); +t_stat ni_rq_svc(UNIT *uptr); +t_stat ni_cio_svc(UNIT *uptr); +t_stat ni_attach(UNIT *uptr, CONST char *cptr); +t_stat ni_detach(UNIT *uptr); +t_stat ni_setmac(UNIT *uptr, int32 val, CONST char *cptr, void *desc); +t_stat ni_showmac(FILE* st, UNIT *uptr, int32 val, CONST void *desc); +t_stat ni_try_job(uint8 slot); +t_stat ni_show_stats(FILE *st, UNIT *uptr, int32 val, CONST void *desc); +t_stat ni_set_stats(UNIT *uptr, int32 val, CONST char *cptr, void *desc); +t_stat ni_show_poll(FILE *st, UNIT *uptr, int32 val, CONST void *desc); +t_stat ni_show_filters(FILE *st, UNIT *uptr, int32 val, CONST void *desc); +const char *ni_description(DEVICE *dptr); +t_stat ni_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr); +void ni_cio_reset(uint8 slot); +void ni_process_packet(); +void ni_int_ack(uint8 slot); +void ni_sysgen(uint8 slot); +void ni_express(uint8 slot); +void ni_full(uint8 slot); + +#endif /* _3B2_NI_H_ */ diff --git a/3B2/3b2_ports.c b/3B2/3b2_ports.c index b77db85b..4ddb7218 100644 --- a/3B2/3b2_ports.c +++ b/3B2/3b2_ports.c @@ -1,989 +1,838 @@ -/* 3b2_ports.c: AT&T 3B2 Model 400 "PORTS" feature card - - Copyright (c) 2018, Seth J. Morabito - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - - Except as contained in this notice, the name of the author shall - not be used in advertising or otherwise to promote the sale, use or - other dealings in this Software without prior written authorization - from the author. -*/ - -/* - * PORTS is an intelligent feature card for the 3B2 that supports four - * serial lines and one Centronics parallel port. - * - * The PORTS card is based on the Common I/O (CIO) platform. It uses - * two SCN2681A DUARTs to supply the four serial lines, and uses the - * SCN2681A parallel I/O pins for the Centronics parallel port. - * - * We make no attempt to emulate a PORTS card's internal workings - * precisely. Instead, we treat it as a black box as seen from the 3B2 - * system board's point of view. - * - */ - -#include "3b2_ports.h" - -#include "sim_tmxr.h" - -#include "3b2_cpu.h" -#include "3b2_io.h" -#include "3b2_mem.h" -#include "3b2_timer.h" - -/* Static function declarations */ -static t_stat ports_show_queue_common(FILE *st, UNIT *uptr, int32 val, - CONST void *desc, t_bool rq); - -/* Device and units for PORTS cards - * -------------------------------- - * - * A 3B2/400 system can have up to 12 PORTS cards installed. Each - * card, in turn, has 5 TTY devices - four serial TTYs and one - * parallel printer port (the printer port is not supported at this - * time, and is a no-op). - * - * The PORTS emulator is backed by a terminal multiplexer with up to - * 48 (12 * 4) serial lines. Lines can be specified with: - * - * SET PORTS LINES=n - * - * Lines must be specified in multiples of 4. - * - * Implementation8 - * -------------- - * - * Each set of 4 lines is mapped to a CIO_STATE struct in the "cio" - * CIO_STATE structure. - * - */ - -#define PPQESIZE 12 -#define DELAY_ASYNC 25 -#define DELAY_DLM 100 -#define DELAY_ULM 100 -#define DELAY_FCF 100 -#define DELAY_DOS 100 -#define DELAY_DSD 100 -#define DELAY_OPTIONS 100 -#define DELAY_VERS 100 -#define DELAY_CONN 100 -#define DELAY_XMIT 50 -#define DELAY_RECV 25 -#define DELAY_DEVICE 25 -#define DELAY_STD 100 - -#define PORTS_DIAG_CRC1 0x7ceec900 -#define PORTS_DIAG_CRC2 0x77a1ea56 -#define PORTS_DIAG_CRC3 0x84cf938b -#define PORTS_DIAG_CRC4 0x31b32383 /* Used by SVR 2.0.5 */ -#define PORTS_DIAG_CRC5 0x4be7bccc /* Used by SVR 2.0.5 */ -#define PORTS_DIAG_CRC6 0x3197f6dd /* Used by SVR 2.0.5 */ - -#define LN(cid,port) ((PORTS_LINES * ((cid) - ports_base_cid)) + (port)) -#define LCID(ln) (((ln) / PORTS_LINES) + ports_base_cid) -#define LPORT(ln) ((ln) % PORTS_LINES) - -int8 ports_base_cid; /* First cid in our contiguous block */ -uint8 ports_int_cid; /* Interrupting card ID */ -uint8 ports_int_subdev; /* Interrupting subdevice */ -t_bool ports_conf = FALSE; /* Have PORTS cards been configured? */ -uint32 ports_crc; /* CRC32 of downloaded memory */ - -/* PORTS-specific state for each slot */ -PORTS_LINE_STATE *ports_state = NULL; - -/* Baud rates determined by the low nybble - * of the PORT_OPTIONS cflag */ -CONST char *ports_baud[16] = { - "75", "110", "134", "150", - "300", "600", "1200", "2000", - "2400", "4800", "1800", "9600", - "19200", "9600", "9600", "9600" -}; - -TMLN *ports_ldsc = NULL; -TMXR ports_desc = { 0, 0, 0, NULL }; - -/* Three units service the Receive, Transmit, and CIO */ -UNIT ports_unit[3] = { - { UDATA(&ports_rcv_svc, UNIT_IDLE|UNIT_ATTABLE|TT_MODE_8B, 0) }, - { UDATA(&ports_xmt_svc, UNIT_DIS, 0), SERIAL_OUT_WAIT }, - { UDATA(&ports_cio_svc, UNIT_DIS, 0) } -}; - -MTAB ports_mod[] = { - { TT_MODE, TT_MODE_7B, "7b", "7B", NULL, NULL, NULL, "7 bit mode" }, - { TT_MODE, TT_MODE_8B, "8b", "8B", NULL, NULL, NULL, "8 bit mode" }, - { TT_MODE, TT_MODE_7P, "7p", "7P", NULL, NULL, NULL, "7 bit mode - non printing suppressed" }, - { MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, "RQUEUE=n", NULL, - NULL, &ports_show_rqueue, NULL, "Display Request Queue for card n" }, - { MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, "CQUEUE=n", NULL, - NULL, &ports_show_cqueue, NULL, "Display Completion Queue for card n" }, - { MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, "LINES", "LINES=n", - &ports_setnl, &tmxr_show_lines, (void *) &ports_desc, "Display number of lines" }, - { 0 } -}; - -static DEBTAB ports_debug[] = { - { "IO", IO_DBG, "I/O Character Trace" }, - { "TRACE", TRACE_DBG, "Call Trace" }, - { "XMT", TMXR_DBG_XMT, "TMXR Transmit Data" }, - { "RCV", TMXR_DBG_RCV, "TMXR Received Data" }, - { "RET", TMXR_DBG_RET, "TMXR Returned Received Data" }, - { "MDM", TMXR_DBG_XMT, "TMXR Modem Signals" }, - { "CON", TMXR_DBG_XMT, "TMXR Connection Activity" }, - { "ASY", TMXR_DBG_ASY, "TMXR Async Activity" }, - { "PXMT", TMXR_DBG_PXMT, "TMXR Transmit Packets" }, - { "PRCV", TMXR_DBG_PRCV, "TMXR Received Packets" }, - { NULL } -}; - -DEVICE ports_dev = { - "PORTS", /* name */ - ports_unit, /* units */ - NULL, /* registers */ - ports_mod, /* modifiers */ - 3, /* #units */ - 16, /* address radix */ - 32, /* address width */ - 1, /* address incr. */ - 16, /* data radix */ - 8, /* data width */ - NULL, /* examine routine */ - NULL, /* deposit routine */ - &ports_reset, /* reset routine */ - NULL, /* boot routine */ - &ports_attach, /* attach routine */ - &ports_detach, /* detach routine */ - NULL, /* context */ - DEV_DISABLE|DEV_DIS|DEV_DEBUG|DEV_MUX, /* flags */ - 0, /* debug control flags */ - ports_debug, /* debug flag names */ - NULL, /* memory size change */ - NULL, /* logical name */ - NULL, /* help routine */ - NULL, /* attach help routine */ - (void *)&ports_desc, /* help context */ - NULL, /* device description */ -}; - - -static void cio_irq(uint8 cid, uint8 dev, int32 delay) -{ - ports_int_cid = cid; - ports_int_subdev = dev & 0xf; - sim_activate(&ports_unit[2], delay); -} - -/* - * Set the number of lines for the PORTS mux. This will add or remove - * cards as necessary. The number of lines must be a multiple of 4. - */ -t_stat ports_setnl(UNIT *uptr, int32 val, CONST char *cptr, void *desc) -{ - int32 newln, i, t; - t_stat r = SCPE_OK; - - if (cptr == NULL) { - return SCPE_ARG; - } - - newln = (int32) get_uint(cptr, 10, (MAX_PORTS_CARDS * PORTS_LINES), &r); - - if ((r != SCPE_OK) || (newln == ports_desc.lines)) { - return r; - } - - if ((newln == 0) || LPORT(newln) != 0) { - return SCPE_ARG; - } - - if (newln < ports_desc.lines) { - for (i = newln, t = 0; i < ports_desc.lines; i++) { - t = t | ports_ldsc[i].conn; - } - - if (t && !get_yn("This will disconnect users; proceed [N]?", FALSE)) { - return SCPE_OK; - } - - for (i = newln; i < ports_desc.lines; i++) { - if (ports_ldsc[i].conn) { - tmxr_linemsg(&ports_ldsc[i], "\r\nOperator disconnected line\r\n"); - tmxr_send_buffered_data(&ports_ldsc[i]); - } - /* completely reset line */ - tmxr_detach_ln(&ports_ldsc[i]); - if (LPORT(i) == (PORTS_LINES - 1)) { - /* Also drop the corresponding card from the CIO array */ - cio_clear(LCID(i)); - } - } - } - - ports_desc.ldsc = ports_ldsc = (TMLN *)realloc(ports_ldsc, newln*sizeof(*ports_ldsc)); - ports_state = (PORTS_LINE_STATE *)realloc(ports_state, newln*sizeof(*ports_state)); - - if (ports_desc.lines < newln) { - memset(ports_ldsc + ports_desc.lines, 0, sizeof(*ports_ldsc)*(newln-ports_desc.lines)); - memset(ports_state + ports_desc.lines, 0, sizeof(*ports_state)*(newln-ports_desc.lines)); - } - - ports_desc.lines = newln; - - /* setup lines and auto config */ - ports_conf = FALSE; - return ports_reset(&ports_dev); -} - - -static void ports_cmd(uint8 cid, cio_entry *rentry, uint8 *rapp_data) -{ - cio_entry centry = {0}; - uint32 ln, i; - PORTS_OPTIONS opts; - char line_config[16]; - uint8 app_data[4] = {0}; - - centry.address = rentry->address; - cio[cid].op = rentry->opcode; - ln = LN(cid, rentry->subdevice & 0xf); - - switch(rentry->opcode) { - case CIO_DLM: - for (i = 0; i < rentry->byte_count; i++) { - ports_crc = cio_crc32_shift(ports_crc, pread_b(rentry->address + i)); - } - centry.address = rentry->address + rentry->byte_count; - sim_debug(TRACE_DBG, &ports_dev, - "[%08x] [ports_cmd] CIO Download Memory: bytecnt=%04x " - "addr=%08x return_addr=%08x subdev=%02x (CRC=%08x)\n", - R[NUM_PC], - rentry->byte_count, rentry->address, - centry.address, centry.subdevice, ports_crc); - /* We intentionally do not set the subdevice in - * the completion entry */ - cio_cexpress(cid, PPQESIZE, ¢ry, app_data); - cio_irq(cid, rentry->subdevice, DELAY_DLM); - break; - case CIO_ULM: - sim_debug(TRACE_DBG, &ports_dev, - "[%08x] [ports_cmd] CIO Upload Memory\n", - R[NUM_PC]); - cio_cexpress(cid, PPQESIZE, ¢ry, app_data); - cio_irq(cid, rentry->subdevice, DELAY_ULM); - break; - case CIO_FCF: - sim_debug(TRACE_DBG, &ports_dev, - "[%08x] [ports_cmd] CIO Force Function Call (CRC=%08x)\n", - R[NUM_PC], ports_crc); - - /* If the currently running program is a diagnostics program, - * we are expected to write results into memory at address - * 0x200f000 */ - if (ports_crc == PORTS_DIAG_CRC1 || - ports_crc == PORTS_DIAG_CRC2 || - ports_crc == PORTS_DIAG_CRC3 || - ports_crc == PORTS_DIAG_CRC4 || - ports_crc == PORTS_DIAG_CRC5 || - ports_crc == PORTS_DIAG_CRC6) { - pwrite_h(0x200f000, 0x1); /* Test success */ - pwrite_h(0x200f002, 0x0); /* Test Number */ - pwrite_h(0x200f004, 0x0); /* Actual */ - pwrite_h(0x200f006, 0x0); /* Expected */ - pwrite_b(0x200f008, 0x1); /* Success flag again */ - } - - /* An interesting (?) side-effect of FORCE FUNCTION CALL is - * that it resets the card state such that a new SYSGEN is - * required in order for new commands to work. In fact, an - * INT0/INT1 combo _without_ a RESET can sysgen the board. So, - * we reset the command bits here. */ - cio[cid].sysgen_s = 0; - cio_cexpress(cid, PPQESIZE, ¢ry, app_data); - cio_irq(cid, rentry->subdevice, DELAY_FCF); - break; - case CIO_DOS: - sim_debug(TRACE_DBG, &ports_dev, - "[%08x] [ports_cmd] CIO Determine Op Status\n", - R[NUM_PC]); - cio_cexpress(cid, PPQESIZE, ¢ry, app_data); - cio_irq(cid, rentry->subdevice, DELAY_DOS); - break; - case CIO_DSD: - /* Determine Sub-Devices. We have none. */ - sim_debug(TRACE_DBG, &ports_dev, - "[%08x] [ports_cmd] Determine Sub-Devices.\n", - R[NUM_PC]); - - /* The system wants us to write sub-device structures - * at the supplied address */ - - pwrite_h(rentry->address, 0x0); - cio_cexpress(cid, PPQESIZE, ¢ry, app_data); - cio_irq(cid, rentry->subdevice, DELAY_DSD); - break; - case PPC_OPTIONS: - sim_debug(TRACE_DBG, &ports_dev, - "[%08x] [ports_cmd] PPC Options Operation\n", - R[NUM_PC]); - - opts.line = pread_h(rentry->address); - opts.iflag = pread_h(rentry->address + 4); - opts.oflag = pread_h(rentry->address + 6); - opts.cflag = pread_h(rentry->address + 8); - opts.lflag = pread_h(rentry->address + 10); - opts.cerase = pread_b(rentry->address + 11); - opts.ckill = pread_b(rentry->address + 12); - opts.cinter = pread_b(rentry->address + 13); - opts.cquit = pread_b(rentry->address + 14); - opts.ceof = pread_b(rentry->address + 15); - opts.ceol = pread_b(rentry->address + 16); - opts.itime = pread_b(rentry->address + 17); - opts.vtime = pread_b(rentry->address + 18); - opts.vcount = pread_b(rentry->address + 19); - - sim_debug(TRACE_DBG, &ports_dev, " PPC Options: iflag=%04x\n", opts.iflag); - sim_debug(TRACE_DBG, &ports_dev, " PPC Options: oflag=%04x\n", opts.oflag); - sim_debug(TRACE_DBG, &ports_dev, " PPC Options: cflag=%04x\n", opts.cflag); - sim_debug(TRACE_DBG, &ports_dev, " PPC Options: lflag=%04x\n", opts.lflag); - sim_debug(TRACE_DBG, &ports_dev, " PPC Options: itime=%02x\n", opts.itime); - sim_debug(TRACE_DBG, &ports_dev, " PPC Options: vtime=%02x\n", opts.vtime); - sim_debug(TRACE_DBG, &ports_dev, " PPC Options: vcount=%02x\n", opts.vcount); - - ports_state[ln].iflag = opts.iflag; - ports_state[ln].oflag = opts.oflag; - - if ((rentry->subdevice & 0xf) < PORTS_LINES) { - /* Adjust baud rate */ - sprintf(line_config, "%s-8N1", - ports_baud[opts.cflag&0xf]); - - sim_debug(TRACE_DBG, &ports_dev, - "Setting PORTS line %d to %s\n", - ln, line_config); - - tmxr_set_config_line(&ports_ldsc[ln], line_config); - } - - centry.byte_count = 20; - centry.opcode = PPC_OPTIONS; - centry.subdevice = rentry->subdevice; - centry.address = rentry->address; - cio_cqueue(cid, CIO_STAT, PPQESIZE, ¢ry, app_data); - cio_irq(cid, rentry->subdevice, DELAY_OPTIONS); - break; - case PPC_VERS: - sim_debug(TRACE_DBG, &ports_dev, - "[%08x] [ports_cmd] PPC Version\n", - R[NUM_PC]); - - /* Write the version number at the supplied address */ - pwrite_b(rentry->address, PORTS_VERSION); - - centry.opcode = CIO_ULM; - - /* TODO: It's unknown what the value 0x50 means, but this - * is what a real board sends. */ - app_data[0] = 0x50; - cio_cqueue(cid, CIO_STAT, PPQESIZE, ¢ry, app_data); - cio_irq(cid, rentry->subdevice, DELAY_VERS); - break; - case PPC_CONN: - /* CONNECT - Full request and completion queues */ - sim_debug(TRACE_DBG, &ports_dev, - "[%08x] [ports_cmd] PPC CONNECT - subdevice = %02x\n", - R[NUM_PC], rentry->subdevice); - - ports_state[ln].conn = TRUE; - - centry.opcode = PPC_CONN; - centry.subdevice = rentry->subdevice; - centry.address = rentry->address; - cio_cqueue(cid, CIO_STAT, PPQESIZE, ¢ry, app_data); - cio_irq(cid, rentry->subdevice, DELAY_CONN); - break; - case PPC_XMIT: - /* XMIT - Full request and completion queues */ - - /* The port being referred to is in the subdevice. */ - sim_debug(TRACE_DBG, &ports_dev, - "[%08x] [ports_cmd] PPC XMIT - subdevice = %02x, address=%08x, byte_count=%d\n", - R[NUM_PC], rentry->subdevice, rentry->address, rentry->byte_count); - - /* Set state for xmit */ - ports_state[ln].tx_addr = rentry->address; - ports_state[ln].tx_req_addr = rentry->address; - ports_state[ln].tx_chars = rentry->byte_count + 1; - ports_state[ln].tx_req_chars = rentry->byte_count + 1; - - sim_activate_after(&ports_unit[1], ports_unit[1].wait); - - break; - case PPC_DEVICE: - /* DEVICE Control - Express request and completion queues */ - /* The port being referred to is in the subdevice. */ - sim_debug(TRACE_DBG, &ports_dev, - "[%08x] [ports_cmd] PPC DEVICE - subdevice = %02x\n", - R[NUM_PC], rentry->subdevice); - centry.subdevice = rentry->subdevice; - centry.opcode = PPC_DEVICE; - cio_cexpress(cid, PPQESIZE, ¢ry, app_data); - cio_irq(cid, rentry->subdevice, DELAY_DEVICE); - break; - case PPC_RECV: - /* RECV - Full request and completion queues */ - - /* The port being referred to is in the subdevice. */ - sim_debug(TRACE_DBG, &ports_dev, - "[%08x] [ports_cmd] PPC RECV - subdevice = %02x addr=%08x\n", - R[NUM_PC], rentry->subdevice, rentry->address); - - break; - case PPC_DISC: - /* Disconnect */ - centry.subdevice = rentry->subdevice; - centry.opcode = PPC_DISC; - ports_ldsc[ln].rcve = 0; - cio_cqueue(cid, CIO_STAT, PPQESIZE, ¢ry, app_data); - cio_irq(cid, rentry->subdevice, DELAY_STD); - break; - case PPC_BRK: - case PPC_CLR: - default: - sim_debug(TRACE_DBG, &ports_dev, - ">>> Op %d Not Handled Yet\n", - rentry->opcode); - - cio_cexpress(cid, PPQESIZE, ¢ry, app_data); - cio_irq(cid, rentry->subdevice, DELAY_STD); - break; - } -} - -/* - * Update the connection status of the given port. - */ -static void ports_update_conn(uint32 ln) -{ - cio_entry centry = {0}; - uint8 cid; - uint8 app_data[4] = {0}; - - cid = LCID(ln); - - /* If the card hasn't sysgened, there's no way to write a - * completion queue entry */ - if (cio[cid].sysgen_s != CIO_SYSGEN) { - return; - } - - if (ports_ldsc[ln].conn) { - app_data[0] = AC_CON; - ports_state[ln].conn = TRUE; - } else { - if (ports_state[ln].conn) { - app_data[0] = AC_DIS; - ports_state[ln].conn = FALSE; - } else { - app_data[0] = 0; - } - } - - centry.opcode = PPC_ASYNC; - centry.subdevice = LPORT(ln); - cio_cqueue(cid, CIO_CMD, PPQESIZE, ¢ry, app_data); - - /* Interrupt */ - if (cio[cid].ivec > 0) { - CIO_SET_INT(cid); - } -} - -void ports_sysgen(uint8 cid) -{ - cio_entry cqe = {0}; - uint8 app_data[4] = {0}; - - ports_crc = 0; - - cqe.opcode = 3; /* Sysgen success! */ - - /* It's not clear why we put a response in both the express - * and the full queue. */ - cio_cexpress(cid, PPQESIZE, &cqe, app_data); - cio_cqueue(cid, CIO_STAT, PPQESIZE, &cqe, app_data); - - ports_int_cid = cid; - sim_activate(&ports_unit[2], DELAY_STD); -} - -void ports_express(uint8 cid) -{ - cio_entry rqe = {0}; - uint8 app_data[4] = {0}; - cio_rexpress(cid, PPQESIZE, &rqe, app_data); - ports_cmd(cid, &rqe, app_data); -} - -void ports_full(uint8 cid) -{ - uint32 i; - cio_entry rqe = {0}; - uint8 app_data[4] = {0}; - - for (i = 0; i < PORTS_LINES; i++) { - if (cio_rqueue(cid, i, PPQESIZE, &rqe, app_data) == SCPE_OK) { - ports_cmd(cid, &rqe, app_data); - } - } -} - -t_stat ports_reset(DEVICE *dptr) -{ - int32 i; - uint8 cid, line, ln, end_slot; - TMLN *lp; - - ports_crc = 0; - - sim_debug(TRACE_DBG, &ports_dev, - "[ports_reset] Resetting PORTS device\n"); - - if ((dptr->flags & DEV_DIS)) { - for (cid = 0; cid < CIO_SLOTS; cid++) { - if (cio[cid].id == PORTS_ID) { - cio[cid].id = 0; - cio[cid].ipl = 0; - cio[cid].ivec = 0; - cio[cid].exp_handler = NULL; - cio[cid].full_handler = NULL; - cio[cid].sysgen = NULL; - } - } - - ports_conf = FALSE; - } else if (!ports_conf) { - - /* Clear out any old cards, we're starting fresh */ - for (cid = 0; cid < CIO_SLOTS; cid++) { - if (cio[cid].id == PORTS_ID) { - cio[cid].id = 0; - cio[cid].ipl = 0; - cio[cid].ivec = 0; - cio[cid].exp_handler = NULL; - cio[cid].full_handler = NULL; - cio[cid].sysgen = NULL; - } - } - - /* Find the first avaialable slot */ - for (cid = 0; cid < CIO_SLOTS; cid++) { - if (cio[cid].id == 0) { - break; - } - } - - /* Do we have room? */ - if (cid >= CIO_SLOTS || cid > (CIO_SLOTS - (ports_desc.lines/PORTS_LINES))) { - return SCPE_NXM; - } - - /* Remember the base card slot */ - ports_base_cid = cid; - - end_slot = (cid + (ports_desc.lines/PORTS_LINES)); - - for (; cid < end_slot; cid++) { - /* Set up the ports structure */ - cio[cid].id = PORTS_ID; - cio[cid].ipl = PORTS_IPL; - cio[cid].exp_handler = &ports_express; - cio[cid].full_handler = &ports_full; - cio[cid].sysgen = &ports_sysgen; - - for (line = 0; line < PORTS_LINES; line++) { - ln = LN(cid, line); - - sim_debug(TRACE_DBG, &ports_dev, - ">>> Setting up lp %d (card %d, line %d)\n", - ln, cid, line); - - lp = &ports_ldsc[ln]; - tmxr_set_get_modem_bits(lp, TMXR_MDM_DTR|TMXR_MDM_RTS, 0, NULL); - } - } - - ports_conf = TRUE; - - if (ports_ldsc == NULL) { - ports_desc.ldsc = ports_ldsc = - (TMLN *)calloc(ports_desc.lines, sizeof(*ports_ldsc)); - } - - if (ports_state == NULL) { - sim_debug(TRACE_DBG, &ports_dev, - "[ports_reset] calloc for ports_state...\n"); - ports_state = (PORTS_LINE_STATE *)calloc(ports_desc.lines, sizeof(*ports_state)); - } - - memset(ports_state, 0, ports_desc.lines*sizeof(*ports_state)); - - tmxr_set_port_speed_control(&ports_desc); - - for (i = 0; i < ports_desc.lines; i++) { - sim_debug(TRACE_DBG, &ports_dev, - "[ports_reset] Setting up line %d...\n", i); - tmxr_set_line_unit(&ports_desc, i, &ports_unit[0]); - tmxr_set_line_output_unit(&ports_desc, i, &ports_unit[1]); - if (!ports_ldsc[i].conn) { - ports_ldsc[i].xmte = 1; - } - ports_ldsc[i].rcve = 0; - tmxr_set_config_line(&ports_ldsc[i], "9600-8N1"); - } - } - - if (!sim_is_active(&ports_unit[0])) { - sim_debug(TRACE_DBG, &ports_dev, - "[ports_reset] starting receive polling...\n"); - sim_activate(&ports_unit[0], ports_unit[0].wait); - } - - sim_debug(TRACE_DBG, &ports_dev, - "[ports_reset] returning scpe_ok\n"); - return SCPE_OK; -} - -t_stat ports_cio_svc(UNIT *uptr) -{ - sim_debug(TRACE_DBG, &ports_dev, - "[ports_cio_svc] IRQ for board %d device %d\n", - ports_int_cid, ports_int_subdev); - - if (cio[ports_int_cid].ivec > 0) { - CIO_SET_INT(ports_int_cid); - } - - switch (cio[ports_int_cid].op) { - case PPC_CONN: - cio[ports_int_cid].op = PPC_ASYNC; - ports_ldsc[LN(ports_int_cid, ports_int_subdev)].rcve = 1; - sim_activate(&ports_unit[2], DELAY_ASYNC); - break; - case PPC_ASYNC: - ports_update_conn(LN(ports_int_cid, ports_int_subdev)); - break; - default: - break; - } - - return SCPE_OK; -} - -t_stat ports_rcv_svc(UNIT *uptr) -{ - uint8 cid; - int32 temp, ln; - char c; - cio_entry rentry = {0}; - cio_entry centry = {0}; - uint8 rapp_data[4] = {0}; - uint8 capp_data[4] = {0}; - - if ((uptr->flags & UNIT_ATT) == 0) { - return SCPE_OK; - } - - ln = tmxr_poll_conn(&ports_desc); - if (ln >= 0) { - ports_update_conn(ln); - } - - tmxr_poll_rx(&ports_desc); - - for (ln = 0; ln < ports_desc.lines; ln++) { - cid = LCID(ln); - - if (!ports_ldsc[ln].conn && ports_state[ln].conn) { - ports_update_conn(ln); - } else if (ports_ldsc[ln].conn && ports_state[ln].conn) { - temp = tmxr_getc_ln(&ports_ldsc[ln]); - - if (temp && !(temp & SCPE_BREAK)) { - - c = (char) (temp & 0xff); - - sim_debug(IO_DBG, &ports_dev, - "[LINE %d RECEIVE] char = %02x (%c)\n", - ln, c, c); - - if (c == 0xd && (ports_state[ln].iflag & ICRNL)) { - c = 0xa; - } - - if (cio[cid].ivec > 0 && - cio_rqueue(cid, PORTS_RCV_QUEUE, - PPQESIZE, &rentry, rapp_data) == SCPE_OK) { - CIO_SET_INT(cid); - - /* Write the character to the memory address */ - pwrite_b(rentry.address, c); - centry.subdevice = LPORT(ln); - centry.opcode = PPC_RECV; - centry.address = rentry.address; - capp_data[3] = RC_TMR; - - cio_cqueue(cid, CIO_STAT, PPQESIZE, ¢ry, capp_data); - } - } - } - } - - tmxr_clock_coschedule(uptr, tmxr_poll); - - return SCPE_OK; -} - -t_stat ports_xmt_svc(UNIT *uptr) -{ - uint8 cid, ln; - char c; - t_bool tx = FALSE; /* Did a tx ever occur? */ - cio_entry centry = {0}; - uint8 app_data[4] = {0}; - uint32 wait = 0x7fffffff; - - /* Scan all lines for output */ - for (ln = 0; ln < ports_desc.lines; ln++) { - cid = LCID(ln); - if (ports_ldsc[ln].conn && ports_state[ln].tx_chars > 0) { - tx = TRUE; /* Even an attempt at TX counts for rescheduling */ - c = sim_tt_outcvt(pread_b(ports_state[ln].tx_addr), - TT_GET_MODE(ports_unit[0].flags)); - - /* The PORTS card optionally handles NL->CRLF */ - if (c == 0xa && - (ports_state[ln].oflag & ONLCR) && - !(ports_state[ln].crlf)) { - if (tmxr_putc_ln(&ports_ldsc[ln], 0xd) == SCPE_OK) { - wait = MIN(wait, ports_ldsc[ln].txdeltausecs); - sim_debug(IO_DBG, &ports_dev, - "[%08x] [ports_xmt_svc] [LINE %d] XMIT (crlf): %02x (%c)\n", - R[NUM_PC], ln, 0xd, 0xd); - /* Indicate that we're in a CRLF translation */ - ports_state[ln].crlf = TRUE; - } - - break; - } - - ports_state[ln].crlf = FALSE; - - if (tmxr_putc_ln(&ports_ldsc[ln], c) == SCPE_OK) { - wait = MIN(wait, ports_ldsc[ln].txdeltausecs); - ports_state[ln].tx_chars--; - ports_state[ln].tx_addr++; - sim_debug(IO_DBG, &ports_dev, - "[%08x] [ports_xmt_svc] [LINE %d] XMIT: %02x (%c)\n", - R[NUM_PC], ln, c, c); - } - - if (ports_state[ln].tx_chars == 0) { - sim_debug(TRACE_DBG, &ports_dev, - "[%08x] [ports_xmt_svc] Done with xmit, card=%d port=%d. Interrupting.\n", - R[NUM_PC], cid, LPORT(ln)); - centry.byte_count = ports_state[ln].tx_req_chars; - centry.subdevice = LPORT(ln); - centry.opcode = PPC_XMIT; - centry.address = ports_state[ln].tx_req_addr; - app_data[0] = RC_FLU; - cio_cqueue(cid, CIO_STAT, PPQESIZE, ¢ry, app_data); - CIO_SET_INT(cid); - } - } - } - - tmxr_poll_tx(&ports_desc); - - if (tx) { - tmxr_activate_after(uptr, wait); - } - - return SCPE_OK; -} - -t_stat ports_attach(UNIT *uptr, CONST char *cptr) -{ - t_stat r; - - sim_debug(TRACE_DBG, &ports_dev, "ports_attach()\n"); - - tmxr_set_modem_control_passthru(&ports_desc); - - r = tmxr_attach(&ports_desc, uptr, cptr); - if (r != SCPE_OK) { - tmxr_clear_modem_control_passthru(&ports_desc); - return r; - } - - return SCPE_OK; -} - -t_stat ports_detach(UNIT *uptr) -{ - t_stat r; - - r = tmxr_detach(&ports_desc, uptr); - - if (r != SCPE_OK) { - return r; - } - - if (sim_is_active(&ports_unit[0])) { - sim_debug(TRACE_DBG, &ports_dev, - "[ports_detach] Stopping receive polling...\n"); - sim_cancel(&ports_unit[0]); - } - - tmxr_clear_modem_control_passthru(&ports_desc); - - return SCPE_OK; -} - -/* - * Useful routines for debugging request and completion queues - */ - -t_stat ports_show_rqueue(FILE *st, UNIT *uptr, int32 val, CONST void *desc) -{ - return ports_show_queue_common(st, uptr, val, desc, TRUE); -} - -t_stat ports_show_cqueue(FILE *st, UNIT *uptr, int32 val, CONST void *desc) -{ - return ports_show_queue_common(st, uptr, val, desc, FALSE); -} - - -static t_stat ports_show_queue_common(FILE *st, UNIT *uptr, int32 val, - CONST void *desc, t_bool rq) -{ - uint8 cid; - char *cptr = (char *) desc; - t_stat result; - uint32 ptr, size, no_rque, i, j; - uint8 op, dev, seq, cmdstat; - - if (cptr) { - cid = (uint8) get_uint(cptr, 10, 12, &result); - if (result != SCPE_OK) { - return SCPE_ARG; - } - } else { - return SCPE_ARG; - } - - /* If the card is not sysgen'ed, give up */ - if (cio[cid].sysgen_s != CIO_SYSGEN) { - fprintf(st, "No card in slot %d, or card has not completed sysgen\n", cid); - return SCPE_ARG; - } - - /* Get the top of the queue */ - if (rq) { - ptr = cio[cid].rqp; - size = cio[cid].rqs; - no_rque = cio[cid].no_rque; - } else { - ptr = cio[cid].cqp; - size = cio[cid].cqs; - no_rque = 0; /* Not used */ - } - - if (rq) { - fprintf(st, "Dumping %d Request Queues\n", no_rque); - } else { - fprintf(st, "Dumping Completion Queue\n"); - } - - fprintf(st, "---------------------------------------------------------\n"); - fprintf(st, "EXPRESS ENTRY:\n"); - fprintf(st, " Byte Count: %d\n", pread_h(ptr)); - fprintf(st, " Subdevice: %d\n", pread_b(ptr + 2)); - fprintf(st, " Opcode: 0x%02x\n", pread_b(ptr + 3)); - fprintf(st, " Addr/Data: 0x%08x\n", pread_w(ptr + 4)); - fprintf(st, " App Data: 0x%08x\n", pread_w(ptr + 8)); - ptr += 12; - - if (rq) { - for (i = 0; i < no_rque; i++) { - fprintf(st, "---------------------------------------------------------\n"); - fprintf(st, "REQUEST QUEUE %d\n", i); - fprintf(st, "---------------------------------------------------------\n"); - fprintf(st, "Load Pointer: %d\n", pread_h(ptr) / 12); - fprintf(st, "Unload Pointer: %d\n", pread_h(ptr + 2) / 12); - fprintf(st, "---------------------------------------------------------\n"); - ptr += 4; - for (j = 0; j < size; j++) { - dev = pread_b(ptr + 2); - op = pread_b(ptr + 3); - seq = (dev & 0x40) >> 6; - cmdstat = (dev & 0x80) >> 7; - fprintf(st, "REQUEST ENTRY %d\n", j); - fprintf(st, " Byte Count: %d\n", pread_h(ptr)); - fprintf(st, " Subdevice: %d\n", dev & 0x3f); - fprintf(st, " Cmd/Stat: %d\n", cmdstat); - fprintf(st, " Seqbit: %d\n", seq); - fprintf(st, " Opcode: 0x%02x (%d)\n", op, op); - fprintf(st, " Addr/Data: 0x%08x\n", pread_w(ptr + 4)); - fprintf(st, " App Data: 0x%08x\n", pread_w(ptr + 8)); - ptr += 12; - } - } - } else { - fprintf(st, "---------------------------------------------------------\n"); - fprintf(st, "Load Pointer: %d\n", pread_h(ptr) / 12); - fprintf(st, "Unload Pointer: %d\n", pread_h(ptr + 2) / 12); - fprintf(st, "---------------------------------------------------------\n"); - ptr += 4; - for (i = 0; i < size; i++) { - dev = pread_b(ptr + 2); - op = pread_b(ptr + 3); - seq = (dev & 0x40) >> 6; - cmdstat = (dev & 0x80) >> 7; - fprintf(st, "COMPLETION ENTRY %d\n", i); - fprintf(st, " Byte Count: %d\n", pread_h(ptr)); - fprintf(st, " Subdevice: %d\n", dev & 0x3f); - fprintf(st, " Cmd/Stat: %d\n", cmdstat); - fprintf(st, " Seqbit: %d\n", seq); - fprintf(st, " Opcode: 0x%02x (%d)\n", op, op); - fprintf(st, " Addr/Data: 0x%08x\n", pread_w(ptr + 4)); - fprintf(st, " App Data: 0x%08x\n", pread_w(ptr + 8)); - ptr += 12; - } - } - - return SCPE_OK; -} +/* 3b2_ports.c: CM195B 4-Port Serial CIO Card + + Copyright (c) 2018-2022, Seth J. Morabito + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + Except as contained in this notice, the name of the author shall + not be used in advertising or otherwise to promote the sale, use or + other dealings in this Software without prior written authorization + from the author. +*/ + +/* + * PORTS is an intelligent feature card for the 3B2 that supports four + * serial lines and one Centronics parallel port. + * + * The PORTS card is based on the Common I/O (CIO) platform. It uses + * two SCN2681A DUARTs to supply the four serial lines, and uses the + * SCN2681A parallel I/O pins for the Centronics parallel port. + * + * We make no attempt to emulate a PORTS card's internal workings + * precisely. Instead, we treat it as a black box as seen from the 3B2 + * system board's point of view. + * + */ + +#include "3b2_ports.h" + +#include "sim_tmxr.h" + +#include "3b2_cpu.h" +#include "3b2_io.h" +#include "3b2_mem.h" +#include "3b2_stddev.h" + +#define IO_SCHED 1000 + +/* Device and units for PORTS cards + * -------------------------------- + * + * A 3B2/400 system can have up to 12 PORTS cards installed. Each + * card, in turn, has 5 TTY devices - four serial TTYs and one + * parallel printer port (the printer port is not supported at this + * time, and is a no-op). + * + * The PORTS emulator is backed by a terminal multiplexer with up to + * 48 (12 * 4) serial lines. Lines can be specified with: + * + * SET PORTS LINES=n + * + * Lines must be specified in multiples of 4. + * + * Implementation8 + * -------------- + * + * Each set of 4 lines is mapped to a CIO_STATE struct in the "cio" + * CIO_STATE structure. + * + */ + +#define MAX_LINES 32 + +#define PPQESIZE 12 +#define DELAY_ASYNC 25 +#define DELAY_DLM 100 +#define DELAY_ULM 100 +#define DELAY_FCF 100 +#define DELAY_DOS 100 +#define DELAY_DSD 100 +#define DELAY_OPTIONS 100 +#define DELAY_VERS 100 +#define DELAY_CONN 100 +#define DELAY_XMIT 50 +#define DELAY_RECV 25 +#define DELAY_DEVICE 25 +#define DELAY_STD 100 + +#define PORTS_DIAG_CRC1 0x7ceec900 +#define PORTS_DIAG_CRC2 0x77a1ea56 +#define PORTS_DIAG_CRC3 0x84cf938b +#define PORTS_DIAG_CRC4 0x31b32383 /* Used by SVR 2.0.5 */ +#define PORTS_DIAG_CRC5 0x4be7bccc /* Used by SVR 2.0.5 */ +#define PORTS_DIAG_CRC6 0x3197f6dd /* Used by SVR 2.0.5 */ + +#define PORTS_DFLT_LINES 4 +#define PORTS_DFLT_CARDS 1 + +#define LN(slot,port) (ports_slot_ln[(slot)] + (port)) +#define LSLOT(ln) (ports_ln_slot[ln]) +/* #define LN(slot,port) ((PORTS_LINES * ((slot) - ports_base_slot)) + (port)) */ +/* #define LSLOT(ln) (((ln) / PORTS_LINES) + ports_base_slot) */ +#define LPORT(ln) ((ln) % PORTS_LINES) + +int8 ports_base_slot; /* First slot in our contiguous block */ +uint8 ports_int_slot; /* Interrupting card ID */ +uint8 ports_int_subdev; /* Interrupting subdevice */ +t_bool ports_conf = FALSE; /* Have PORTS cards been configured? */ +uint32 ports_crc; /* CRC32 of downloaded memory */ + +/* Mapping of line number to CIO card slot. Up to 32 lines spread over + 8 slots are supported. */ +uint8 ports_ln_slot[MAX_LINES]; + +/* Mapping of slot number to base line number belonging to the card in + that slot. I.e., if there are two PORTS cards, one in slot 3 and + one in slot 5, index 3 will have starting line 0, index 5 will have + starting line 4. */ +uint32 ports_slot_ln[CIO_SLOTS]; + +/* PORTS-specific state for each slot */ +PORTS_LINE_STATE *ports_state = NULL; + +/* Baud rates determined by the low nybble + * of the PORT_OPTIONS cflag */ +CONST char *ports_baud[16] = { + "75", "110", "134", "150", + "300", "600", "1200", "2000", + "2400", "4800", "1800", "9600", + "19200", "9600", "9600", "9600" +}; + +TMLN *ports_ldsc = NULL; +TMXR ports_desc = { 0, 0, 0, NULL }; + +/* Three units service the Receive, Transmit, and CIO */ +UNIT ports_unit[3] = { + { UDATA(&ports_rcv_svc, UNIT_IDLE|UNIT_ATTABLE|TT_MODE_8B, 0) }, + { UDATA(&ports_xmt_svc, UNIT_DIS, 0), SERIAL_OUT_WAIT }, + { UDATA(&ports_cio_svc, UNIT_DIS, 0) } +}; + +MTAB ports_mod[] = { + { TT_MODE, TT_MODE_7B, "7b", "7B", NULL, NULL, NULL, "7 bit mode" }, + { TT_MODE, TT_MODE_8B, "8b", "8B", NULL, NULL, NULL, "8 bit mode" }, + { TT_MODE, TT_MODE_7P, "7p", "7P", NULL, NULL, NULL, "7 bit mode - non printing suppressed" }, + { MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, "LINES", "LINES=n", + &ports_setnl, &tmxr_show_lines, (void *) &ports_desc, "Show or set number of lines" }, + { 0 } +}; + +static DEBTAB ports_debug[] = { + { "IO", IO_DBG, "I/O Character Trace" }, + { "TRACE", TRACE_DBG, "Call Trace" }, + { "XMT", TMXR_DBG_XMT, "TMXR Transmit Data" }, + { "RCV", TMXR_DBG_RCV, "TMXR Received Data" }, + { "RET", TMXR_DBG_RET, "TMXR Returned Received Data" }, + { "MDM", TMXR_DBG_XMT, "TMXR Modem Signals" }, + { "CON", TMXR_DBG_XMT, "TMXR Connection Activity" }, + { "ASY", TMXR_DBG_ASY, "TMXR Async Activity" }, + { "PXMT", TMXR_DBG_PXMT, "TMXR Transmit Packets" }, + { "PRCV", TMXR_DBG_PRCV, "TMXR Received Packets" }, + { NULL } +}; + +DEVICE ports_dev = { + "PORTS", /* name */ + ports_unit, /* units */ + NULL, /* registers */ + ports_mod, /* modifiers */ + 3, /* #units */ + 16, /* address radix */ + 32, /* address width */ + 1, /* address incr. */ + 16, /* data radix */ + 8, /* data width */ + NULL, /* examine routine */ + NULL, /* deposit routine */ + &ports_reset, /* reset routine */ + NULL, /* boot routine */ + &ports_attach, /* attach routine */ + &ports_detach, /* detach routine */ + NULL, /* context */ + DEV_DISABLE|DEV_DIS|DEV_DEBUG|DEV_MUX, /* flags */ + 0, /* debug control flags */ + ports_debug, /* debug flag names */ + NULL, /* memory size change */ + NULL, /* logical name */ + NULL, /* help routine */ + NULL, /* attach help routine */ + (void *)&ports_desc, /* help context */ + NULL, /* device description */ +}; + + +static void cio_irq(uint8 slot, uint8 dev, int32 delay) +{ + ports_int_slot = slot; + ports_int_subdev = dev & 0xf; + sim_activate(&ports_unit[2], delay); +} + +/* + * Set the number of lines for the PORTS mux. This will add or remove + * cards as necessary. The number of lines must be a multiple of 4. + */ +t_stat ports_setnl(UNIT *uptr, int32 val, CONST char *cptr, void *desc) +{ + int32 newln, i, t; + t_stat r = SCPE_OK; + + if (cptr == NULL) { + return SCPE_ARG; + } + + newln = (int32) get_uint(cptr, 10, (MAX_CARDS * PORTS_LINES), &r); + + if ((r != SCPE_OK) || (newln == ports_desc.lines)) { + return r; + } + + if ((newln == 0) || LPORT(newln) != 0 || newln > MAX_LINES) { + return SCPE_ARG; + } + + sim_debug(TRACE_DBG, &ports_dev, + "[ports_setnl] Setting line count to %d\n", + newln); + + if (newln < ports_desc.lines) { + for (i = newln, t = 0; i < ports_desc.lines; i++) { + t = t | ports_ldsc[i].conn; + } + + if (t && !get_yn("This will disconnect users; proceed [N]?", FALSE)) { + return SCPE_OK; + } + + for (i = newln; i < ports_desc.lines; i++) { + if (ports_ldsc[i].conn) { + tmxr_linemsg(&ports_ldsc[i], "\r\nOperator disconnected line\r\n"); + tmxr_send_buffered_data(&ports_ldsc[i]); + } + /* completely reset line */ + tmxr_detach_ln(&ports_ldsc[i]); + } + } + + ports_desc.ldsc = ports_ldsc = (TMLN *)realloc(ports_ldsc, newln*sizeof(*ports_ldsc)); + ports_state = (PORTS_LINE_STATE *)realloc(ports_state, newln*sizeof(*ports_state)); + + if (ports_desc.lines < newln) { + memset(ports_ldsc + ports_desc.lines, 0, sizeof(*ports_ldsc)*(newln-ports_desc.lines)); + memset(ports_state + ports_desc.lines, 0, sizeof(*ports_state)*(newln-ports_desc.lines)); + } + + ports_desc.lines = newln; + + /* setup lines and auto config */ + ports_conf = FALSE; + return ports_reset(&ports_dev); +} + + +static void ports_cmd(uint8 slot, cio_entry *rentry, uint8 *rapp_data) +{ + cio_entry centry = {0}; + uint32 ln, i; + PORTS_OPTIONS opts; + char line_config[16]; + uint8 app_data[4] = {0}; + + centry.address = rentry->address; + cio[slot].op = rentry->opcode; + ln = LN(slot, rentry->subdevice & 0xf); + + switch(rentry->opcode) { + case CIO_DLM: + for (i = 0; i < rentry->byte_count; i++) { + ports_crc = cio_crc32_shift(ports_crc, pread_b(rentry->address + i, BUS_PER)); + } + centry.address = rentry->address + rentry->byte_count; + sim_debug(TRACE_DBG, &ports_dev, + "[ports_cmd] CIO Download Memory: bytecnt=%04x " + "addr=%08x return_addr=%08x subdev=%02x (CRC=%08x)\n", + rentry->byte_count, rentry->address, + centry.address, centry.subdevice, ports_crc); + /* We intentionally do not set the subdevice in + * the completion entry */ + cio_cexpress(slot, PPQESIZE, ¢ry, app_data); + cio_irq(slot, rentry->subdevice, DELAY_DLM); + break; + case CIO_ULM: + sim_debug(TRACE_DBG, &ports_dev, + "[ports_cmd] CIO Upload Memory\n"); + cio_cexpress(slot, PPQESIZE, ¢ry, app_data); + cio_irq(slot, rentry->subdevice, DELAY_ULM); + break; + case CIO_FCF: + sim_debug(TRACE_DBG, &ports_dev, + "[ports_cmd] CIO Force Function Call (CRC=%08x)\n", + ports_crc); + + /* If the currently running program is a diagnostics program, + * we are expected to write results into memory at address + * 0x200f000 */ + if (ports_crc == PORTS_DIAG_CRC1 || + ports_crc == PORTS_DIAG_CRC2 || + ports_crc == PORTS_DIAG_CRC3 || + ports_crc == PORTS_DIAG_CRC4 || + ports_crc == PORTS_DIAG_CRC5 || + ports_crc == PORTS_DIAG_CRC6) { + pwrite_h(0x200f000, 0x1, BUS_PER); /* Test success */ + pwrite_h(0x200f002, 0x0, BUS_PER); /* Test Number */ + pwrite_h(0x200f004, 0x0, BUS_PER); /* Actual */ + pwrite_h(0x200f006, 0x0, BUS_PER); /* Expected */ + pwrite_b(0x200f008, 0x1, BUS_PER); /* Success flag again */ + } + + /* An interesting (?) side-effect of FORCE FUNCTION CALL is + * that it resets the card state such that a new SYSGEN is + * required in order for new commands to work. In fact, an + * INT0/INT1 combo _without_ a RESET can sysgen the board. So, + * we reset the command bits here. */ + cio[slot].sysgen_s = 0; + cio_cexpress(slot, PPQESIZE, ¢ry, app_data); + cio_irq(slot, rentry->subdevice, DELAY_FCF); + break; + case CIO_DOS: + sim_debug(TRACE_DBG, &ports_dev, + "[ports_cmd] CIO Determine Op Status\n"); + cio_cexpress(slot, PPQESIZE, ¢ry, app_data); + cio_irq(slot, rentry->subdevice, DELAY_DOS); + break; + case CIO_DSD: + /* Determine Sub-Devices. We have none. */ + sim_debug(TRACE_DBG, &ports_dev, + "[ports_cmd] Determine Sub-Devices.\n"); + + /* The system wants us to write sub-device structures + * at the supplied address */ + + pwrite_h(rentry->address, 0x0, BUS_PER); + cio_cexpress(slot, PPQESIZE, ¢ry, app_data); + cio_irq(slot, rentry->subdevice, DELAY_DSD); + break; + case PPC_OPTIONS: + sim_debug(TRACE_DBG, &ports_dev, + "[ports_cmd] PPC Options Operation\n"); + + opts.line = pread_h(rentry->address, BUS_PER); + opts.iflag = pread_h(rentry->address + 4, BUS_PER); + opts.oflag = pread_h(rentry->address + 6, BUS_PER); + opts.cflag = pread_h(rentry->address + 8, BUS_PER); + opts.lflag = pread_h(rentry->address + 10, BUS_PER); + opts.cerase = pread_b(rentry->address + 11, BUS_PER); + opts.ckill = pread_b(rentry->address + 12, BUS_PER); + opts.cinter = pread_b(rentry->address + 13, BUS_PER); + opts.cquit = pread_b(rentry->address + 14, BUS_PER); + opts.ceof = pread_b(rentry->address + 15, BUS_PER); + opts.ceol = pread_b(rentry->address + 16, BUS_PER); + opts.itime = pread_b(rentry->address + 17, BUS_PER); + opts.vtime = pread_b(rentry->address + 18, BUS_PER); + opts.vcount = pread_b(rentry->address + 19, BUS_PER); + + sim_debug(TRACE_DBG, &ports_dev, " PPC Options: iflag=%04x\n", opts.iflag); + sim_debug(TRACE_DBG, &ports_dev, " PPC Options: oflag=%04x\n", opts.oflag); + sim_debug(TRACE_DBG, &ports_dev, " PPC Options: cflag=%04x\n", opts.cflag); + sim_debug(TRACE_DBG, &ports_dev, " PPC Options: lflag=%04x\n", opts.lflag); + sim_debug(TRACE_DBG, &ports_dev, " PPC Options: itime=%02x\n", opts.itime); + sim_debug(TRACE_DBG, &ports_dev, " PPC Options: vtime=%02x\n", opts.vtime); + sim_debug(TRACE_DBG, &ports_dev, " PPC Options: vcount=%02x\n", opts.vcount); + + ports_state[ln].iflag = opts.iflag; + ports_state[ln].oflag = opts.oflag; + + if ((rentry->subdevice & 0xf) < PORTS_LINES) { + /* Adjust baud rate */ + sprintf(line_config, "%s-8N1", + ports_baud[opts.cflag&0xf]); + + sim_debug(TRACE_DBG, &ports_dev, + "Setting PORTS line %d to %s\n", + ln, line_config); + + tmxr_set_config_line(&ports_ldsc[ln], line_config); + } + + centry.byte_count = 20; + centry.opcode = PPC_OPTIONS; + centry.subdevice = rentry->subdevice; + centry.address = rentry->address; + cio_cqueue(slot, CIO_STAT, PPQESIZE, ¢ry, app_data); + cio_irq(slot, rentry->subdevice, DELAY_OPTIONS); + break; + case PPC_VERS: + sim_debug(TRACE_DBG, &ports_dev, + "[ports_cmd] PPC Version\n"); + + /* Write the version number at the supplied address */ + pwrite_b(rentry->address, PORTS_VERSION, BUS_PER); + + centry.opcode = CIO_ULM; + + /* TODO: It's unknown what the value 0x50 means, but this + * is what a real board sends. */ + app_data[0] = 0x50; + cio_cqueue(slot, CIO_STAT, PPQESIZE, ¢ry, app_data); + cio_irq(slot, rentry->subdevice, DELAY_VERS); + break; + case PPC_CONN: + /* CONNECT - Full request and completion queues */ + sim_debug(TRACE_DBG, &ports_dev, + "[ports_cmd] PPC CONNECT - subdevice = %02x\n", + rentry->subdevice); + + ports_state[ln].conn = TRUE; + + centry.opcode = PPC_CONN; + centry.subdevice = rentry->subdevice; + centry.address = rentry->address; + cio_cqueue(slot, CIO_STAT, PPQESIZE, ¢ry, app_data); + cio_irq(slot, rentry->subdevice, DELAY_CONN); + break; + case PPC_XMIT: + /* XMIT - Full request and completion queues */ + + /* The port being referred to is in the subdevice. */ + sim_debug(TRACE_DBG, &ports_dev, + "[ports_cmd] PPC XMIT - subdevice = %02x, address=%08x, byte_count=%d\n", + rentry->subdevice, rentry->address, rentry->byte_count); + + /* Set state for xmit */ + ports_state[ln].tx_addr = rentry->address; + ports_state[ln].tx_req_addr = rentry->address; + ports_state[ln].tx_chars = rentry->byte_count + 1; + ports_state[ln].tx_req_chars = rentry->byte_count + 1; + + sim_activate_after(&ports_unit[1], ports_unit[1].wait); + + break; + case PPC_DEVICE: + /* DEVICE Control - Express request and completion queues */ + /* The port being referred to is in the subdevice. */ + sim_debug(TRACE_DBG, &ports_dev, + "[ports_cmd] PPC DEVICE - subdevice = %02x\n", + rentry->subdevice); + centry.subdevice = rentry->subdevice; + centry.opcode = PPC_DEVICE; + cio_cexpress(slot, PPQESIZE, ¢ry, app_data); + cio_irq(slot, rentry->subdevice, DELAY_DEVICE); + break; + case PPC_RECV: + /* RECV - Full request and completion queues */ + + /* The port being referred to is in the subdevice. */ + sim_debug(TRACE_DBG, &ports_dev, + "[ports_cmd] PPC RECV - subdevice = %02x addr=%08x\n", + rentry->subdevice, rentry->address); + + break; + case PPC_DISC: + /* Disconnect */ + centry.subdevice = rentry->subdevice; + centry.opcode = PPC_DISC; + ports_ldsc[ln].rcve = 0; + cio_cqueue(slot, CIO_STAT, PPQESIZE, ¢ry, app_data); + cio_irq(slot, rentry->subdevice, DELAY_STD); + break; + case PPC_BRK: + case PPC_CLR: + default: + sim_debug(TRACE_DBG, &ports_dev, + ">>> Op %d Not Handled Yet\n", + rentry->opcode); + + cio_cexpress(slot, PPQESIZE, ¢ry, app_data); + cio_irq(slot, rentry->subdevice, DELAY_STD); + break; + } +} + +/* + * Update the connection status of the given port. + */ +static void ports_update_conn(uint32 ln) +{ + cio_entry centry = {0}; + uint8 slot; + uint8 app_data[4] = {0}; + + slot = LSLOT(ln); + + /* If the card hasn't sysgened, there's no way to write a + * completion queue entry */ + if (cio[slot].sysgen_s != CIO_SYSGEN) { + return; + } + + if (ports_ldsc[ln].conn) { + app_data[0] = AC_CON; + ports_state[ln].conn = TRUE; + } else { + if (ports_state[ln].conn) { + app_data[0] = AC_DIS; + ports_state[ln].conn = FALSE; + } else { + app_data[0] = 0; + } + } + + centry.opcode = PPC_ASYNC; + centry.subdevice = LPORT(ln); + cio_cqueue(slot, CIO_CMD, PPQESIZE, ¢ry, app_data); + + /* Interrupt */ + CIO_SET_INT(slot); +} + +void ports_sysgen(uint8 slot) +{ + cio_entry cqe = {0}; + uint8 app_data[4] = {0}; + + ports_crc = 0; + + cqe.opcode = 3; /* Sysgen success! */ + + /* It's not clear why we put a response in both the express + * and the full queue. */ + cio_cexpress(slot, PPQESIZE, &cqe, app_data); + cio_cqueue(slot, CIO_STAT, PPQESIZE, &cqe, app_data); + + ports_int_slot = slot; + sim_activate(&ports_unit[2], DELAY_STD); +} + +void ports_express(uint8 slot) +{ + cio_entry rqe = {0}; + uint8 app_data[4] = {0}; + cio_rexpress(slot, PPQESIZE, &rqe, app_data); + ports_cmd(slot, &rqe, app_data); +} + +void ports_full(uint8 slot) +{ + uint32 i; + cio_entry rqe = {0}; + uint8 app_data[4] = {0}; + + for (i = 0; i < PORTS_LINES; i++) { + if (cio_rqueue(slot, i, PPQESIZE, &rqe, app_data) == SCPE_OK) { + ports_cmd(slot, &rqe, app_data); + } + } +} + +t_stat ports_reset(DEVICE *dptr) +{ + int32 i, j; + uint8 slot; + t_stat r; + + ports_crc = 0; + + if (ports_ldsc == NULL) { + sim_set_uname(&ports_unit[0], "PORTS-RCV"); + sim_set_uname(&ports_unit[1], "PORTS-XMT"); + sim_set_uname(&ports_unit[2], "PORTS-CIO"); + + ports_desc.lines = PORTS_DFLT_LINES; + ports_desc.ldsc = ports_ldsc = + (TMLN *)calloc(ports_desc.lines, sizeof(*ports_ldsc)); + } + + if (ports_state == NULL) { + ports_state = (PORTS_LINE_STATE *)calloc(ports_desc.lines, sizeof(*ports_state)); + memset(ports_state, 0, ports_desc.lines*sizeof(*ports_state)); + } + + tmxr_set_port_speed_control(&ports_desc); + + if ((dptr->flags & DEV_DIS)) { + cio_remove_all(PORTS_ID); + ports_conf = FALSE; + return SCPE_OK; + } + + if (!ports_conf) { + /* Clear out any old cards, we're starting fresh */ + cio_remove_all(PORTS_ID); + + memset(ports_slot_ln, 0, sizeof(ports_slot_ln)); + memset(ports_ln_slot, 0, sizeof(ports_ln_slot)); + + /* Insert necessary cards into the backplane */ + j = 0; + for (i = 0; i < ports_desc.lines/PORTS_LINES; i++) { + r = cio_install(PORTS_ID, "PORTS", PORTS_IPL, + &ports_express, &ports_full, &ports_sysgen, NULL, + &slot); + if (r != SCPE_OK) { + return r; + } + /* Remember the port assignments */ + ports_slot_ln[slot] = i * PORTS_LINES; + for (; j < (i * PORTS_LINES) + PORTS_LINES; j++) { + ports_ln_slot[j] = slot; + } + } + + ports_conf = TRUE; + } + + /* If attached, start polling for connections */ + if (ports_unit[0].flags & UNIT_ATT) { + sim_activate_after_abs(&ports_unit[0], ports_unit[0].wait); + } else { + sim_cancel(&ports_unit[0]); + } + + return SCPE_OK; +} + +t_stat ports_cio_svc(UNIT *uptr) +{ + sim_debug(TRACE_DBG, &ports_dev, + "[ports_cio_svc] IRQ for board %d device %d\n", + ports_int_slot, ports_int_subdev); + + CIO_SET_INT(ports_int_slot); + + switch (cio[ports_int_slot].op) { + case PPC_CONN: + cio[ports_int_slot].op = PPC_ASYNC; + ports_ldsc[LN(ports_int_slot, ports_int_subdev)].rcve = 1; + sim_activate(&ports_unit[2], DELAY_ASYNC); + break; + case PPC_ASYNC: + ports_update_conn(LN(ports_int_slot, ports_int_subdev)); + break; + default: + break; + } + + return SCPE_OK; +} + +t_stat ports_rcv_svc(UNIT *uptr) +{ + uint8 slot; + int32 temp, ln; + char c; + cio_entry rentry = {0}; + cio_entry centry = {0}; + uint8 rapp_data[4] = {0}; + uint8 capp_data[4] = {0}; + + if ((uptr->flags & UNIT_ATT) == 0) { + return SCPE_OK; + } + + ln = tmxr_poll_conn(&ports_desc); + if (ln >= 0) { + ports_update_conn(ln); + } + + for (ln = 0; ln < ports_desc.lines; ln++) { + slot = LSLOT(ln); + + if (!ports_ldsc[ln].conn && ports_state[ln].conn) { + ports_update_conn(ln); + } else if (ports_ldsc[ln].conn && ports_state[ln].conn) { + temp = tmxr_getc_ln(&ports_ldsc[ln]); + + if (temp && !(temp & SCPE_BREAK)) { + + c = (char) (temp & 0xff); + + sim_debug(IO_DBG, &ports_dev, + "[LINE %d RECEIVE] char = %02x (%c)\n", + ln, c, c); + + if (c == 0xd && (ports_state[ln].iflag & ICRNL)) { + c = 0xa; + } + + if (cio[slot].ivec > 0 && + cio_rqueue(slot, PORTS_RCV_QUEUE, + PPQESIZE, &rentry, rapp_data) == SCPE_OK) { + CIO_SET_INT(slot); + + /* Write the character to the memory address */ + pwrite_b(rentry.address, c, BUS_PER); + centry.subdevice = LPORT(ln); + centry.opcode = PPC_RECV; + centry.address = rentry.address; + capp_data[3] = RC_TMR; + + cio_cqueue(slot, CIO_STAT, PPQESIZE, ¢ry, capp_data); + } + } + } + } + + tmxr_poll_rx(&ports_desc); + tmxr_poll_tx(&ports_desc); + + tmxr_clock_coschedule(uptr, tmxr_poll); + + return SCPE_OK; +} + +t_stat ports_xmt_svc(UNIT *uptr) +{ + uint8 slot, ln; + char c; + t_bool tx = FALSE; /* Did a tx ever occur? */ + cio_entry centry = {0}; + uint8 app_data[4] = {0}; + uint32 wait = 0x7fffffff; + + /* Scan all lines for output */ + for (ln = 0; ln < ports_desc.lines; ln++) { + slot = LSLOT(ln); + if (ports_ldsc[ln].conn && ports_state[ln].tx_chars > 0) { + tx = TRUE; /* Even an attempt at TX counts for rescheduling */ + c = sim_tt_outcvt(pread_b(ports_state[ln].tx_addr, BUS_PER), + TT_GET_MODE(ports_unit[0].flags)); + + /* The PORTS card optionally handles NL->CRLF */ + if (c == 0xa && + (ports_state[ln].oflag & ONLCR) && + !(ports_state[ln].crlf)) { + if (tmxr_putc_ln(&ports_ldsc[ln], 0xd) == SCPE_OK) { + wait = MIN(wait, ports_ldsc[ln].txdeltausecs); + sim_debug(IO_DBG, &ports_dev, + "[ports_xmt_svc] [LINE %d] XMIT (crlf): %02x (%c)\n", + ln, 0xd, 0xd); + /* Indicate that we're in a CRLF translation */ + ports_state[ln].crlf = TRUE; + } + + break; + } + + ports_state[ln].crlf = FALSE; + + if (tmxr_putc_ln(&ports_ldsc[ln], c) == SCPE_OK) { + wait = MIN(wait, ports_ldsc[ln].txdeltausecs); + ports_state[ln].tx_chars--; + ports_state[ln].tx_addr++; + sim_debug(IO_DBG, &ports_dev, + "[ports_xmt_svc] [LINE %d] XMIT: %02x (%c)\n", + ln, c, c); + } + + if (ports_state[ln].tx_chars == 0) { + sim_debug(TRACE_DBG, &ports_dev, + "[ports_xmt_svc] Done with xmit, card=%d port=%d. Interrupting.\n", + slot, LPORT(ln)); + centry.byte_count = ports_state[ln].tx_req_chars; + centry.subdevice = LPORT(ln); + centry.opcode = PPC_XMIT; + centry.address = ports_state[ln].tx_req_addr; + app_data[0] = RC_FLU; + cio_cqueue(slot, CIO_STAT, PPQESIZE, ¢ry, app_data); + CIO_SET_INT(slot); + } + } + } + + tmxr_poll_tx(&ports_desc); + + if (tx) { + tmxr_activate_after(uptr, wait); + } + + return SCPE_OK; +} + +t_stat ports_attach(UNIT *uptr, CONST char *cptr) +{ + TMLN *lp; + t_stat r; + int i; + + if ((sim_switches & SWMASK('M'))) { + tmxr_set_modem_control_passthru(&ports_desc); + } + + for (i = 0; i < ports_desc.lines; i++) { + sim_debug(TRACE_DBG, &ports_dev, + "[ports_reset] Setting up line %d...\n", i); + tmxr_set_line_output_unit(&ports_desc, i, &ports_unit[1]); + if (!ports_ldsc[i].conn) { + ports_ldsc[i].xmte = 1; + } + ports_ldsc[i].rcve = 0; + tmxr_set_config_line(&ports_ldsc[i], "9600-8N1"); + } + + r = tmxr_attach(&ports_desc, uptr, cptr); + if (r != SCPE_OK) { + tmxr_clear_modem_control_passthru(&ports_desc); + return r; + } + + for (i = 0; i < ports_desc.lines; i++) { + lp = &ports_ldsc[i]; + tmxr_set_get_modem_bits(lp, TMXR_MDM_DTR|TMXR_MDM_RTS, 0, NULL); + } + + return SCPE_OK; +} + +t_stat ports_detach(UNIT *uptr) +{ + t_stat r; + + r = tmxr_detach(&ports_desc, uptr); + + if (r != SCPE_OK) { + return r; + } + + tmxr_clear_modem_control_passthru(&ports_desc); + + return SCPE_OK; +} diff --git a/3B2/3b2_ports.h b/3B2/3b2_ports.h index fa9302b0..a419a928 100644 --- a/3B2/3b2_ports.h +++ b/3B2/3b2_ports.h @@ -1,230 +1,229 @@ -/* 3b2_ports.h: AT&T 3B2 Model 400 "PORTS" feature card - - Copyright (c) 2018, Seth J. Morabito - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - - Except as contained in this notice, the name of the author shall - not be used in advertising or otherwise to promote the sale, use or - other dealings in this Software without prior written authorization - from the author. -*/ - -/* - * PORTS is an intelligent feature card for the 3B2 that supports four - * serial lines and one Centronics parallel port. - * - * The PORTS card is based on the Common I/O (CIO) platform. It uses - * two SCN2681A DUARTs to supply the four serial lines, and uses the - * SCN2681A parallel I/O pins for the Centronics parallel port. - * - * This file implements the required logic for the PORTS CIO - * interface. The SCN2681A functionality is implemented in the file - * 3b2_duart.c, and is used by both this feature card and the System - * Board console/contty functionality. - */ - -#ifndef _3B2_PORTS_H_ -#define _3B2_PORTS_H_ - -#include "3b2_defs.h" - -#define PORTS_ID 0x0003 -#define PORTS_IPL 10 -#define PORTS_VERSION 1 - -#define MAX_PORTS_CARDS 12 -#define PORTS_LINES 4 -#define PORTS_RCV_QUEUE 5 - -/* - * Sub-field values for the PPC_DEVICE request entry; these are placed - * in app_data.bt[0] in the PPC_DEVICE application field. The prefix - * DR indicates that this is a code for use in "device" request - * entries only. -*/ - -#define DR_ENA 1 /* enable a device */ -#define DR_DIS 2 /* disable a device */ -#define DR_ABR 3 /* abort reception on a device */ -#define DR_ABX 4 /* abort transmission on a device */ -#define DR_BRK 5 /* transmit "break" on a device */ -#define DR_SUS 6 /* suspend xmit on a device */ -#define DR_RES 7 /* resume xmit on a device */ -#define DR_BLK 8 /* transmit STOP character */ -#define DR_UNB 9 /* transmit START character */ - -/* - * Sub-field values for the PPC_DEVICE completion entry; these appear - * in app_data.bt[0] in the PPC_DEVICE application field. These are - * mutually exclusive and cannot be combined. The prefix DC indicates - * that this is a code for use in "device" completion entries only. - */ - -#define DC_NORM 0x00 /* command executed as requested */ -#define DC_DEV 0x01 /* bad device number */ -#define DC_NON 0x02 /* bad sub-code on request */ -#define DC_FAIL 0x03 /* failed to read express entry */ - -/* - * Sub-field values for the PPC_RECV completion entry; these appear in - * app_data.bt[0] in the PPC_RECV application field. These are NOT - * mutually exclusive and may appear in combination. The prefix RC - * indicates that this is a code for use in "read" completion entries - * only. -*/ - -#define RC_DSR 0x01 /* disruption of service */ -#define RC_FLU 0x02 /* buffer flushed */ -#define RC_TMR 0x04 /* inter-character timer expired */ -#define RC_BQO 0x08 /* PPC buffer queue overflow */ -#define RC_UAO 0x10 /* uart overrun */ -#define RC_PAR 0x20 /* parity error */ -#define RC_FRA 0x40 /* framing error */ -#define RC_BRK 0x80 /* break received */ - -/* - * The following codes are included on the DISC (disconnect) command. - * They are "or"ed into the app_data.bt[1] application field in a - * request. These codes are NOT mutually exclusive and can be used in - * any combination. - */ - -#define GR_DTR 0x01 -#define GR_CREAD 0x02 - -/* - * Sub-field values for the PPC_XMIT and PPC_OPTIONS completion - * entries; these appear in app_data.bt[0] in the application fields. - * These are NOT mutually exclusive and may appear in combination. - * The prefix GC indicates that this is a code for use in "general" - * completion entries only. -*/ - -#define GC_DSR 0x01 /* disruption of service */ -#define GC_FLU 0x02 /* buffer flushed */ - -/* - * Sub-field values for the PPC_ASYNC completion entry; these appear - * in app_data.bt[0] in the PPC_ASYNC application field. These are - * mutually exclusive and cannot be combined. The prefix AC indicates - * that this is a code for use in "asynchronous" completion entries - * only. -*/ - -#define AC_CON 0x01 /* connection detected */ -#define AC_DIS 0x02 /* disconnection detected */ -#define AC_BRK 0x03 /* asynchronous "break" */ -#define AC_FLU 0x04 /* xmit flush complete */ - -/* Line Discipline flags (input and output) */ - -#define IGNBRK 0x0001 -#define BRKINT 0x0002 -#define IGNPAR 0x0004 -#define PARMRK 0x0008 -#define INPCK 0x0010 -#define ISTRIP 0x0020 -#define INLCR 0x0040 -#define IGNCR 0x0080 -#define ICRNL 0x0100 -#define IUCLC 0x0200 -#define IXON 0x0400 -#define IXANY 0x0800 - -#define OPOST 0x0001 -#define OLCUC 0x0002 -#define ONLCR 0x0004 -#define OCRNL 0x0008 -#define ONOCR 0x0010 -#define ONLRET 0x0020 -#define OFILL 0x0040 -#define OFDEL 0x0080 -#define ONLDLY 0x0100 -#define OCRDLY 0x0600 -#define OTABDLY 0x1800 -#define OBSDLY 0x2000 -#define OVTDLY 0x4000 -#define OFFDLY 0x8000 - -/* Opcodes for PORTS card */ - -#define PPC_OPTIONS 32 /* GEN, COMP queues: set PPC options */ -#define PPC_XMIT 33 /* GEN, COMP queues: transmit a buffer */ -#define PPC_CONN 34 /* GEN, COMP queues: connect a device */ -#define PPC_DISC 35 /* GEN, COMP queues: disconnect a device */ -#define PPC_BRK 36 /* GEN, COMP queues: ioctl break */ -#define PPC_DEVICE 40 /* EXP, ECOMP entries: device control command */ -#define PPC_CLR 41 /* EXP, ECOMP entries: board clear */ -#define PPC_RECV 50 /* RECV, COMP queues: receive request */ -#define PPC_ASYNC 60 /* Asynchronous request */ -#define CFW_CONFIG 70 /* GEN, COMP queues: set PPC port 0 hardware options */ -#define CFW_IREAD 71 /* GEN, COMP queues: read immediate one to four bytes */ -#define CFW_IWRITE 72 /* GEN, COMP queues: write immediate one to four bytes */ -#define CFW_WRITE 73 /* GEN, COMP queues: write */ -#define PPC_VERS 80 /* EXP, COMP queues: Version */ - -typedef struct { - uint32 tx_addr; /* Address to next read from */ - uint32 tx_req_addr; /* Original request address */ - uint32 tx_chars; /* Number of chars left to transfer */ - uint32 tx_req_chars; /* Original number of chars */ - uint8 rlp; /* Last known load pointer */ - uint16 iflag; /* Line Discipline: Input flags */ - uint16 oflag; /* Line Discipline: Output flags */ - t_bool crlf; /* Indicates we are in a CRLF output transform */ - t_bool conn; /* TRUE if connected, FALSE otherwise */ -} PORTS_LINE_STATE; - -typedef struct { - uint16 line; /* line discipline */ - uint16 pad1; - uint16 iflag; /* input options word */ - uint16 oflag; /* output options word */ - uint16 cflag; /* hardware options */ - uint16 lflag; /* line discipline options */ - uint8 cerase; /* "erase" character */ - uint8 ckill; /* "kill" character */ - uint8 cinter; /* "interrupt" character */ - uint8 cquit; /* "quit" character */ - uint8 ceof; /* "end of file" character */ - uint8 ceol; /* "end of line" character */ - uint8 itime; /* inter character timer multiplier */ - uint8 vtime; /* user-specified inter char timer */ - uint8 vcount; /* user-specified maximum buffer char count */ - uint8 pad2; - uint16 pad3; -} PORTS_OPTIONS; - -t_stat ports_reset(DEVICE *dptr); -t_stat ports_setnl(UNIT *uptr, int32 val, CONST char *cptr, void *desc); -t_stat ports_show_cqueue(FILE *st, UNIT *uptr, int32 val, CONST void *desc); -t_stat ports_show_rqueue(FILE *st, UNIT *uptr, int32 val, CONST void *desc); -t_stat ports_rcv_svc(UNIT *uptr); -t_stat ports_xmt_svc(UNIT *uptr); -t_stat ports_cio_svc(UNIT *uptr); -t_stat ports_attach(UNIT *uptr, CONST char *cptr); -t_stat ports_detach(UNIT *uptr); -void ports_sysgen(uint8 cid); -void ports_express(uint8 cid); -void ports_full(uint8 cid); - -#endif /* _3B2_PORTS_H_ */ +/* 3b2_ports.h: CM195B 4-Port Serial CIO Card + + Copyright (c) 2018-2022, Seth J. Morabito + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + Except as contained in this notice, the name of the author shall + not be used in advertising or otherwise to promote the sale, use or + other dealings in this Software without prior written authorization + from the author. +*/ + +/* + * PORTS is an intelligent feature card for the 3B2 that supports four + * serial lines and one Centronics parallel port. + * + * The PORTS card is based on the Common I/O (CIO) platform. It uses + * two SCN2681A DUARTs to supply the four serial lines, and uses the + * SCN2681A parallel I/O pins for the Centronics parallel port. + * + * This file implements the required logic for the PORTS CIO + * interface. The SCN2681A functionality is implemented in the file + * 3b2_duart.c, and is used by both this feature card and the System + * Board console/contty functionality. + */ + +#ifndef _3B2_PORTS_H_ +#define _3B2_PORTS_H_ + +#include "3b2_defs.h" + +#define PORTS_ID 0x0003 +#define PORTS_IPL 10 +#define PORTS_VERSION 1 + +#define MAX_CARDS 8 /* Up to 8 PORTS cards with 32 lines total + supported */ +#define PORTS_LINES 4 +#define PORTS_RCV_QUEUE 5 + +/* + * Sub-field values for the PPC_DEVICE request entry; these are placed + * in app_data.bt[0] in the PPC_DEVICE application field. The prefix + * DR indicates that this is a code for use in "device" request + * entries only. +*/ + +#define DR_ENA 1 /* enable a device */ +#define DR_DIS 2 /* disable a device */ +#define DR_ABR 3 /* abort reception on a device */ +#define DR_ABX 4 /* abort transmission on a device */ +#define DR_BRK 5 /* transmit "break" on a device */ +#define DR_SUS 6 /* suspend xmit on a device */ +#define DR_RES 7 /* resume xmit on a device */ +#define DR_BLK 8 /* transmit STOP character */ +#define DR_UNB 9 /* transmit START character */ + +/* + * Sub-field values for the PPC_DEVICE completion entry; these appear + * in app_data.bt[0] in the PPC_DEVICE application field. These are + * mutually exclusive and cannot be combined. The prefix DC indicates + * that this is a code for use in "device" completion entries only. + */ + +#define DC_NORM 0x00 /* command executed as requested */ +#define DC_DEV 0x01 /* bad device number */ +#define DC_NON 0x02 /* bad sub-code on request */ +#define DC_FAIL 0x03 /* failed to read express entry */ + +/* + * Sub-field values for the PPC_RECV completion entry; these appear in + * app_data.bt[0] in the PPC_RECV application field. These are NOT + * mutually exclusive and may appear in combination. The prefix RC + * indicates that this is a code for use in "read" completion entries + * only. +*/ + +#define RC_DSR 0x01 /* disruption of service */ +#define RC_FLU 0x02 /* buffer flushed */ +#define RC_TMR 0x04 /* inter-character timer expired */ +#define RC_BQO 0x08 /* PPC buffer queue overflow */ +#define RC_UAO 0x10 /* uart overrun */ +#define RC_PAR 0x20 /* parity error */ +#define RC_FRA 0x40 /* framing error */ +#define RC_BRK 0x80 /* break received */ + +/* + * The following codes are included on the DISC (disconnect) command. + * They are "or"ed into the app_data.bt[1] application field in a + * request. These codes are NOT mutually exclusive and can be used in + * any combination. + */ + +#define GR_DTR 0x01 +#define GR_CREAD 0x02 + +/* + * Sub-field values for the PPC_XMIT and PPC_OPTIONS completion + * entries; these appear in app_data.bt[0] in the application fields. + * These are NOT mutually exclusive and may appear in combination. + * The prefix GC indicates that this is a code for use in "general" + * completion entries only. +*/ + +#define GC_DSR 0x01 /* disruption of service */ +#define GC_FLU 0x02 /* buffer flushed */ + +/* + * Sub-field values for the PPC_ASYNC completion entry; these appear + * in app_data.bt[0] in the PPC_ASYNC application field. These are + * mutually exclusive and cannot be combined. The prefix AC indicates + * that this is a code for use in "asynchronous" completion entries + * only. +*/ + +#define AC_CON 0x01 /* connection detected */ +#define AC_DIS 0x02 /* disconnection detected */ +#define AC_BRK 0x03 /* asynchronous "break" */ +#define AC_FLU 0x04 /* xmit flush complete */ + +/* Line Discipline flags (input and output) */ + +#define IGNBRK 0x0001 +#define BRKINT 0x0002 +#define IGNPAR 0x0004 +#define PARMRK 0x0008 +#define INPCK 0x0010 +#define ISTRIP 0x0020 +#define INLCR 0x0040 +#define IGNCR 0x0080 +#define ICRNL 0x0100 +#define IUCLC 0x0200 +#define IXON 0x0400 +#define IXANY 0x0800 + +#define OPOST 0x0001 +#define OLCUC 0x0002 +#define ONLCR 0x0004 +#define OCRNL 0x0008 +#define ONOCR 0x0010 +#define ONLRET 0x0020 +#define OFILL 0x0040 +#define OFDEL 0x0080 +#define ONLDLY 0x0100 +#define OCRDLY 0x0600 +#define OTABDLY 0x1800 +#define OBSDLY 0x2000 +#define OVTDLY 0x4000 +#define OFFDLY 0x8000 + +/* Opcodes for PORTS card */ + +#define PPC_OPTIONS 32 /* GEN, COMP queues: set PPC options */ +#define PPC_XMIT 33 /* GEN, COMP queues: transmit a buffer */ +#define PPC_CONN 34 /* GEN, COMP queues: connect a device */ +#define PPC_DISC 35 /* GEN, COMP queues: disconnect a device */ +#define PPC_BRK 36 /* GEN, COMP queues: ioctl break */ +#define PPC_DEVICE 40 /* EXP, ECOMP entries: device control command */ +#define PPC_CLR 41 /* EXP, ECOMP entries: board clear */ +#define PPC_RECV 50 /* RECV, COMP queues: receive request */ +#define PPC_ASYNC 60 /* Asynchronous request */ +#define CFW_CONFIG 70 /* GEN, COMP queues: set PPC port 0 hardware options */ +#define CFW_IREAD 71 /* GEN, COMP queues: read immediate one to four bytes */ +#define CFW_IWRITE 72 /* GEN, COMP queues: write immediate one to four bytes */ +#define CFW_WRITE 73 /* GEN, COMP queues: write */ +#define PPC_VERS 80 /* EXP, COMP queues: Version */ + +typedef struct { + uint32 tx_addr; /* Address to next read from */ + uint32 tx_req_addr; /* Original request address */ + uint32 tx_chars; /* Number of chars left to transfer */ + uint32 tx_req_chars; /* Original number of chars */ + uint8 rlp; /* Last known load pointer */ + uint16 iflag; /* Line Discipline: Input flags */ + uint16 oflag; /* Line Discipline: Output flags */ + t_bool crlf; /* Indicates we are in a CRLF output transform */ + t_bool conn; /* TRUE if connected, FALSE otherwise */ +} PORTS_LINE_STATE; + +typedef struct { + uint16 line; /* line discipline */ + uint16 pad1; + uint16 iflag; /* input options word */ + uint16 oflag; /* output options word */ + uint16 cflag; /* hardware options */ + uint16 lflag; /* line discipline options */ + uint8 cerase; /* "erase" character */ + uint8 ckill; /* "kill" character */ + uint8 cinter; /* "interrupt" character */ + uint8 cquit; /* "quit" character */ + uint8 ceof; /* "end of file" character */ + uint8 ceol; /* "end of line" character */ + uint8 itime; /* inter character timer multiplier */ + uint8 vtime; /* user-specified inter char timer */ + uint8 vcount; /* user-specified maximum buffer char count */ + uint8 pad2; + uint16 pad3; +} PORTS_OPTIONS; + +t_stat ports_reset(DEVICE *dptr); +t_stat ports_setnl(UNIT *uptr, int32 val, CONST char *cptr, void *desc); +t_stat ports_rcv_svc(UNIT *uptr); +t_stat ports_xmt_svc(UNIT *uptr); +t_stat ports_cio_svc(UNIT *uptr); +t_stat ports_attach(UNIT *uptr, CONST char *cptr); +t_stat ports_detach(UNIT *uptr); +void ports_sysgen(uint8 slot); +void ports_express(uint8 slot); +void ports_full(uint8 slot); + +#endif /* _3B2_PORTS_H_ */ diff --git a/3B2/3b2_rev2_csr.c b/3B2/3b2_rev2_csr.c index aea82f1b..d9e1924f 100644 --- a/3B2/3b2_rev2_csr.c +++ b/3B2/3b2_rev2_csr.c @@ -1,186 +1,182 @@ -/* 3b2_rev2_csr.c: AT&T 3B2 Rev 2 Control and Status Register - - Copyright (c) 2017, Seth J. Morabito - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - - Except as contained in this notice, the name of the author shall - not be used in advertising or otherwise to promote the sale, use or - other dealings in this Software without prior written authorization - from the author. -*/ - -#include "3b2_rev2_csr.h" - -#include "3b2_cpu.h" -#include "3b2_sys.h" -#include "3b2_timer.h" - -uint16 csr_data; - -BITFIELD csr_bits[] = { - BIT(IOF), - BIT(DMA), - BIT(DISK), - BIT(UART), - BIT(PIR9), - BIT(PIR8), - BIT(CLK), - BIT(IFLT), - BIT(ITIM), - BIT(FLOP), - BIT(NA), - BIT(LED), - BIT(ALGN), - BIT(RRST), - BIT(PARE), - BIT(TIMO), - ENDBITS -}; - -UNIT csr_unit = { - UDATA(NULL, UNIT_FIX, CSRSIZE) -}; - -REG csr_reg[] = { - { HRDATADF(DATA, csr_data, 16, "CSR Data", csr_bits) }, - { NULL } -}; - -DEVICE csr_dev = { - "CSR", &csr_unit, csr_reg, NULL, - 1, 16, 8, 4, 16, 32, - &csr_ex, &csr_dep, &csr_reset, - NULL, NULL, NULL, NULL, - DEV_DEBUG, 0, sys_deb_tab -}; - -t_stat csr_ex(t_value *vptr, t_addr exta, UNIT *uptr, int32 sw) -{ - return SCPE_OK; -} - -t_stat csr_dep(t_value val, t_addr exta, UNIT *uptr, int32 sw) -{ - return SCPE_OK; -} - -t_stat csr_reset(DEVICE *dptr) -{ - csr_data = 0; - return SCPE_OK; -} - -uint32 csr_read(uint32 pa, size_t size) -{ - uint32 reg = pa - CSRBASE; - - sim_debug(READ_MSG, &csr_dev, - "[%08x] CSR=%04x\n", - R[NUM_PC], csr_data); - - switch (reg) { - case 0x2: - if (size == 8) { - return (csr_data >> 8) & 0xff; - } else { - return csr_data; - } - case 0x3: - return csr_data & 0xff; - default: - return 0; - } -} - -void csr_write(uint32 pa, uint32 val, size_t size) -{ - uint32 reg = pa - CSRBASE; - - switch (reg) { - case 0x03: /* Clear Bus Timeout Error */ - csr_data &= ~CSRTIMO; - break; - case 0x07: /* Clear Memory Parity Error */ - csr_data &= ~CSRPARE; - break; - case 0x0b: /* Set System Reset Request */ - full_reset(); - cpu_boot(0, &cpu_dev); - break; - case 0x0f: /* Clear Memory Alignment Fault */ - csr_data &= ~CSRALGN; - break; - case 0x13: /* Set Failure LED */ - csr_data |= CSRLED; - break; - case 0x17: /* Clear Failure LED */ - csr_data &= ~CSRLED; - break; - case 0x1b: /* Set Floppy Motor On */ - csr_data |= CSRFLOP; - break; - case 0x1f: /* Clear Floppy Motor On */ - csr_data &= ~CSRFLOP; - break; - case 0x23: /* Set Inhibit Timers */ - sim_debug(WRITE_MSG, &csr_dev, - "[%08x] SET INHIBIT TIMERS\n", R[NUM_PC]); - csr_data |= CSRITIM; - break; - case 0x27: /* Clear Inhibit Timers */ - sim_debug(WRITE_MSG, &csr_dev, - "[%08x] CLEAR INHIBIT TIMERS\n", R[NUM_PC]); - - /* A side effect of clearing the timer inhibit bit is to cause - * a simulated "tick" of any active timers. This is a hack to - * make diagnostics pass. This is not 100% accurate, but it - * makes SVR3 and DGMON tests happy. - */ - timer_tick(); - csr_data &= ~CSRITIM; - break; - case 0x2b: /* Set Inhibit Faults */ - csr_data |= CSRIFLT; - break; - case 0x2f: /* Clear Inhibit Faults */ - csr_data &= ~CSRIFLT; - break; - case 0x33: /* Set PIR9 */ - csr_data |= CSRPIR9; - CPU_SET_INT(INT_PIR9); - break; - case 0x37: /* Clear PIR9 */ - csr_data &= ~CSRPIR9; - CPU_CLR_INT(INT_PIR9); - break; - case 0x3b: /* Set PIR8 */ - csr_data |= CSRPIR8; - CPU_SET_INT(INT_PIR8); - break; - case 0x3f: /* Clear PIR8 */ - csr_data &= ~CSRPIR8; - CPU_CLR_INT(INT_PIR8); - break; - default: - break; - } -} +/* 3b2_rev2_csr.c: ED System Board Control and Status Register + + Copyright (c) 2017-2022, Seth J. Morabito + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + Except as contained in this notice, the name of the author shall + not be used in advertising or otherwise to promote the sale, use or + other dealings in this Software without prior written authorization + from the author. +*/ + +#include "3b2_rev2_csr.h" + +#include "3b2_cpu.h" +#include "3b2_sys.h" +#include "3b2_timer.h" +#include "3b2_sys.h" + +CSR_DATA csr_data; + +BITFIELD csr_bits[] = { + BIT(IOF), + BIT(DMA), + BIT(DISK), + BIT(UART), + BIT(PIR9), + BIT(PIR8), + BIT(CLK), + BIT(IFLT), + BIT(ITIM), + BIT(FLOP), + BIT(NA), + BIT(LED), + BIT(ALGN), + BIT(RRST), + BIT(PARE), + BIT(TIMO), + ENDBITS +}; + +UNIT csr_unit = { + UDATA(NULL, UNIT_FIX, CSRSIZE) +}; + +REG csr_reg[] = { + { HRDATADF(DATA, csr_data, 16, "CSR Data", csr_bits) }, + { NULL } +}; + +DEVICE csr_dev = { + "CSR", &csr_unit, csr_reg, NULL, + 1, 16, 8, 4, 16, 32, + &csr_ex, &csr_dep, &csr_reset, + NULL, NULL, NULL, NULL, + DEV_DEBUG, 0, sys_deb_tab +}; + +t_stat csr_ex(t_value *vptr, t_addr exta, UNIT *uptr, int32 sw) +{ + return SCPE_OK; +} + +t_stat csr_dep(t_value val, t_addr exta, UNIT *uptr, int32 sw) +{ + return SCPE_OK; +} + +t_stat csr_reset(DEVICE *dptr) +{ + csr_data = 0; + return SCPE_OK; +} + +uint32 csr_read(uint32 pa, size_t size) +{ + uint32 reg = pa - CSRBASE; + + sim_debug(READ_MSG, &csr_dev, + "CSR=%04x\n", + csr_data); + + switch (reg) { + case 0x2: + if (size == 8) { + return (csr_data >> 8) & 0xff; + } else { + return csr_data; + } + case 0x3: + return csr_data & 0xff; + default: + return 0; + } +} + +void csr_write(uint32 pa, uint32 val, size_t size) +{ + uint32 reg = pa - CSRBASE; + + switch (reg) { + case 0x03: /* Clear Bus Timeout Error */ + csr_data &= ~CSRTIMO; + break; + case 0x07: /* Clear Memory Parity Error */ + csr_data &= ~CSRPARE; + break; + case 0x0b: /* Set System Reset Request */ + full_reset(); + cpu_boot(0, &cpu_dev); + break; + case 0x0f: /* Clear Memory Alignment Fault */ + csr_data &= ~CSRALGN; + break; + case 0x13: /* Set Failure LED */ + csr_data |= CSRLED; + break; + case 0x17: /* Clear Failure LED */ + csr_data &= ~CSRLED; + break; + case 0x1b: /* Set Floppy Motor On */ + csr_data |= CSRFLOP; + break; + case 0x1f: /* Clear Floppy Motor On */ + csr_data &= ~CSRFLOP; + break; + case 0x23: /* Set Inhibit Timers */ + sim_debug(WRITE_MSG, &csr_dev, + "SET INHIBIT TIMERS\n"); + csr_data |= CSRITIM; + timer_gate(TIMER_INTERVAL, TRUE); + break; + case 0x27: /* Clear Inhibit Timers */ + sim_debug(WRITE_MSG, &csr_dev, + "CLEAR INHIBIT TIMERS\n"); + csr_data &= ~CSRITIM; + timer_gate(TIMER_INTERVAL, FALSE); + break; + case 0x2b: /* Set Inhibit Faults */ + csr_data |= CSRIFLT; + break; + case 0x2f: /* Clear Inhibit Faults */ + csr_data &= ~CSRIFLT; + break; + case 0x33: /* Set PIR9 */ + csr_data |= CSRPIR9; + CPU_SET_INT(INT_PIR9); + break; + case 0x37: /* Clear PIR9 */ + csr_data &= ~CSRPIR9; + CPU_CLR_INT(INT_PIR9); + break; + case 0x3b: /* Set PIR8 */ + csr_data |= CSRPIR8; + CPU_SET_INT(INT_PIR8); + break; + case 0x3f: /* Clear PIR8 */ + csr_data &= ~CSRPIR8; + CPU_CLR_INT(INT_PIR8); + break; + default: + break; + } +} diff --git a/3B2/3b2_rev2_csr.h b/3B2/3b2_rev2_csr.h index cb873724..c73d2e6a 100644 --- a/3B2/3b2_rev2_csr.h +++ b/3B2/3b2_rev2_csr.h @@ -1,46 +1,46 @@ -/* 3b2_rev2_csr.h: AT&T 3B2 Rev 2 Control and Status Register - - Copyright (c) 2021, Seth J. Morabito - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - - Except as contained in this notice, the name of the author shall - not be used in advertising or otherwise to promote the sale, use or - other dealings in this Software without prior written authorization - from the author. -*/ - -#ifndef _3B2_REV2_CSR_H_ -#define _3B2_REV2_CSR_H_ - -#include "3b2_defs.h" - -/* CSR */ -t_stat csr_svc(UNIT *uptr); -t_stat csr_ex(t_value *vptr, t_addr exta, UNIT *uptr, int32 sw); -t_stat csr_dep(t_value val, t_addr exta, UNIT *uptr, int32 sw); -t_stat csr_reset(DEVICE *dptr); -uint32 csr_read(uint32 pa, size_t size); -void csr_write(uint32 pa, uint32 val, size_t size); - -extern uint16 csr_data; - -#endif /* 3B2_REV2_CSR_H_ */ +/* 3b2_rev2_csr.h: ED System Board Control and Status Register + + Copyright (c) 2021-2022, Seth J. Morabito + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + Except as contained in this notice, the name of the author shall + not be used in advertising or otherwise to promote the sale, use or + other dealings in this Software without prior written authorization + from the author. +*/ + +#ifndef _3B2_REV2_CSR_H_ +#define _3B2_REV2_CSR_H_ + +#include "3b2_defs.h" + +typedef uint16 CSR_DATA; + +/* CSR */ +t_stat csr_svc(UNIT *uptr); +t_stat csr_ex(t_value *vptr, t_addr exta, UNIT *uptr, int32 sw); +t_stat csr_dep(t_value val, t_addr exta, UNIT *uptr, int32 sw); +t_stat csr_reset(DEVICE *dptr); +uint32 csr_read(uint32 pa, size_t size); +void csr_write(uint32 pa, uint32 val, size_t size); + +#endif /* 3B2_REV2_CSR_H_ */ diff --git a/3B2/3b2_rev2_defs.h b/3B2/3b2_rev2_defs.h index 3448d92c..81281209 100644 --- a/3B2/3b2_rev2_defs.h +++ b/3B2/3b2_rev2_defs.h @@ -1,132 +1,132 @@ -/* 3b2_rev2_defs.h: AT&T 3B2 Rev 2 (Model 400) Simulator Definitions - - Copyright (c) 2017, Seth J. Morabito - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - - Except as contained in this notice, the name of the author shall - not be used in advertising or otherwise to promote the sale, use or - other dealings in this Software without prior written authorization - from the author. - */ - -#ifndef _3B2_REV2_DEFS_H_ -#define _3B2_REV2_DEFS_H_ - -#define NUM_REGISTERS 16 - -#define DEFMEMSIZE MSIZ_4M -#define MAXMEMSIZE MSIZ_4M - -#define HWORD_OP_COUNT 11 -#define CPU_VERSION 0x1A /* Version encoded in WE32100 */ - -#define TODBASE 0x41000 -#define TODSIZE 0x40 -#define TIMERBASE 0x42000 -#define TIMERSIZE 0x20 -#define NVRBASE 0x43000 -#define NVRSIZE 0x1000 -#define CSRBASE 0x44000 -#define CSRSIZE 0x100 -#define IFBASE 0x4d000 -#define IFSIZE 0x10 -#define IDBASE 0x4a000 -#define IDSIZE 0x2 - -#define IF_STATUS_REG 0 -#define IF_CMD_REG 0 -#define IF_TRACK_REG 1 -#define IF_SECTOR_REG 2 -#define IF_DATA_REG 3 - -#define ID_DATA_REG 0 -#define ID_CMD_STAT_REG 1 - -/* CSR Flags */ -#define CSRTIMO 0x8000 /* Bus Timeout Error */ -#define CSRPARE 0x4000 /* Memory Parity Error */ -#define CSRRRST 0x2000 /* System Reset Request */ -#define CSRALGN 0x1000 /* Memory Alignment Fault */ -#define CSRLED 0x0800 /* Failure LED */ -#define CSRFLOP 0x0400 /* Floppy Motor On */ -#define CSRRES 0x0200 /* Reserved */ -#define CSRITIM 0x0100 /* Inhibit Timers */ -#define CSRIFLT 0x0080 /* Inhibit Faults */ -#define CSRCLK 0x0040 /* Clock Interrupt */ -#define CSRPIR8 0x0020 /* Programmed Interrupt 8 */ -#define CSRPIR9 0x0010 /* Programmed Interrupt 9 */ -#define CSRUART 0x0008 /* UART Interrupt */ -#define CSRDISK 0x0004 /* Floppy Interrupt */ -#define CSRDMA 0x0002 /* DMA Interrupt */ -#define CSRIOF 0x0001 /* I/O Board Fail */ - -/* Interrupt Sources */ -#define INT_SERR 0x01 /* IPL 15 */ -#define INT_CLOCK 0x02 /* IPL 15 */ -#define INT_DMA 0x04 /* IPL 13 */ -#define INT_UART 0x04 /* IPL 13 */ -#define INT_DISK 0x10 /* IPL 11 */ -#define INT_FLOPPY 0x20 /* IPL 11 */ -#define INT_PIR9 0x40 /* IPL 9 */ -#define INT_PIR8 0x80 /* IPL 8 */ - -#define INT_MAP_LEN 0x100 - -/* Memory */ -#define MEMSIZE_REG 0x4C003 -#define MEMID_512K 0 -#define MEMID_1M 2 -#define MEMID_2M 1 -#define MEMID_4M 3 - -/* DMA Controller */ -#define DMACBASE 0x48000 -#define DMACSIZE 0x11 - -/* DMA integrated disk page buffer */ -#define DMAIDBASE 0x45000 -#define DMAIDSIZE 0x5 - -/* DMA integrated uart A page buffer */ -#define DMAIUABASE 0x46000 -#define DMAIUASIZE 0x5 - -/* DMA integrated uart B page buffer */ -#define DMAIUBBASE 0x47000 -#define DMAIUBSIZE 0x5 - -/* DMA integrated floppy page buffer */ -#define DMAIFBASE 0x4E000 -#define DMAIFSIZE 0x5 - -#define DMA_ID_CHAN 0 -#define DMA_IF_CHAN 1 -#define DMA_IUA_CHAN 2 -#define DMA_IUB_CHAN 3 - -#define DMA_ID 0x45 -#define DMA_IUA 0x46 -#define DMA_IUB 0x47 -#define DMA_C 0x48 -#define DMA_IF 0x4E - -#endif /* _3B2_REV2_DEFS_H_ */ +/* 3b2_rev2_defs.h: Version 2 (3B2/400) Common Definitions + + Copyright (c) 2017-2022, Seth J. Morabito + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + Except as contained in this notice, the name of the author shall + not be used in advertising or otherwise to promote the sale, use or + other dealings in this Software without prior written authorization + from the author. + */ + +#ifndef _3B2_REV2_DEFS_H_ +#define _3B2_REV2_DEFS_H_ + +#define NUM_REGISTERS 16 + +#define DEFMEMSIZE MSIZ_4M +#define MAXMEMSIZE MSIZ_4M + +#define HWORD_OP_COUNT 11 +#define CPU_VERSION 0x1A /* Version encoded in WE32100 */ + +#define TODBASE 0x41000 +#define TODSIZE 0x40 +#define TIMERBASE 0x42000 +#define TIMERSIZE 0x20 +#define NVRBASE 0x43000 +#define NVRSIZE 0x1000 +#define CSRBASE 0x44000 +#define CSRSIZE 0x100 +#define IFBASE 0x4d000 +#define IFSIZE 0x10 +#define IDBASE 0x4a000 +#define IDSIZE 0x2 + +#define IF_STATUS_REG 0 +#define IF_CMD_REG 0 +#define IF_TRACK_REG 1 +#define IF_SECTOR_REG 2 +#define IF_DATA_REG 3 + +#define ID_DATA_REG 0 +#define ID_CMD_STAT_REG 1 + +/* CSR Flags */ +#define CSRTIMO 0x8000 /* Bus Timeout Error */ +#define CSRPARE 0x4000 /* Memory Parity Error */ +#define CSRRRST 0x2000 /* System Reset Request */ +#define CSRALGN 0x1000 /* Memory Alignment Fault */ +#define CSRLED 0x0800 /* Failure LED */ +#define CSRFLOP 0x0400 /* Floppy Motor On */ +#define CSRRES 0x0200 /* Reserved */ +#define CSRITIM 0x0100 /* Inhibit Timers */ +#define CSRIFLT 0x0080 /* Inhibit Faults */ +#define CSRCLK 0x0040 /* Clock Interrupt */ +#define CSRPIR8 0x0020 /* Programmed Interrupt 8 */ +#define CSRPIR9 0x0010 /* Programmed Interrupt 9 */ +#define CSRUART 0x0008 /* UART Interrupt */ +#define CSRDISK 0x0004 /* Floppy Interrupt */ +#define CSRDMA 0x0002 /* DMA Interrupt */ +#define CSRIOF 0x0001 /* I/O Board Fail */ + +/* Interrupt Sources */ +#define INT_SERR 0x01 /* IPL 15 */ +#define INT_CLOCK 0x02 /* IPL 15 */ +#define INT_DMA 0x04 /* IPL 13 */ +#define INT_UART 0x08 /* IPL 13 */ +#define INT_DISK 0x10 /* IPL 11 */ +#define INT_FLOPPY 0x20 /* IPL 11 */ +#define INT_PIR9 0x40 /* IPL 9 */ +#define INT_PIR8 0x80 /* IPL 8 */ + +#define INT_MAP_LEN 0x100 + +/* Memory */ +#define MEMSIZE_REG 0x4C003 +#define MEMID_512K 0 +#define MEMID_1M 2 +#define MEMID_2M 1 +#define MEMID_4M 3 + +/* DMA Controller */ +#define DMACBASE 0x48000 +#define DMACSIZE 0x11 + +/* DMA integrated disk page buffer */ +#define DMAIDBASE 0x45000 +#define DMAIDSIZE 0x5 + +/* DMA integrated uart A page buffer */ +#define DMAIUABASE 0x46000 +#define DMAIUASIZE 0x5 + +/* DMA integrated uart B page buffer */ +#define DMAIUBBASE 0x47000 +#define DMAIUBSIZE 0x5 + +/* DMA integrated floppy page buffer */ +#define DMAIFBASE 0x4E000 +#define DMAIFSIZE 0x5 + +#define DMA_ID_CHAN 0 +#define DMA_IF_CHAN 1 +#define DMA_IUA_CHAN 2 +#define DMA_IUB_CHAN 3 + +#define DMA_ID 0x45 +#define DMA_IUA 0x46 +#define DMA_IUB 0x47 +#define DMA_C 0x48 +#define DMA_IF 0x4E + +#endif /* _3B2_REV2_DEFS_H_ */ diff --git a/3B2/3b2_rev2_mau.h b/3B2/3b2_rev2_mau.h deleted file mode 100644 index c486b3f4..00000000 --- a/3B2/3b2_rev2_mau.h +++ /dev/null @@ -1,383 +0,0 @@ -/* 3b2_rev2_mau.c: AT&T 3B2 Rev 2 (Model 400) Math Acceleration - Unit (WE32106 MAU) Header - - Copyright (c) 2019, Seth J. Morabito - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - - Except as contained in this notice, the name of the author shall - not be used in advertising or otherwise to promote the sale, use or - other dealings in this Software without prior written authorization - from the author. - - --------------------------------------------------------------------- - - This file is part of a simulation of the WE32106 Math Acceleration - Unit. The WE32106 MAU is an IEEE-754 compabitle floating point - hardware math accelerator that was available as an optional - component on the AT&T 3B2/310 and 3B2/400, and a standard component - on the 3B2/500, 3B2/600, and 3B2/1000. - - Portions of this code are derived from the SoftFloat 2c library by - John R. Hauser. Functions derived from SoftFloat 2c are clearly - marked in the comments. - - Legal Notice - ============ - - SoftFloat was written by John R. Hauser. Release 2c of SoftFloat - was made possible in part by the International Computer Science - Institute, located at Suite 600, 1947 Center Street, Berkeley, - California 94704. Funding was partially provided by the National - Science Foundation under grant MIP-9311980. The original version - of this code was written as part of a project to build a - fixed-point vector processor in collaboration with the University - of California at Berkeley, overseen by Profs. Nelson Morgan and - John Wawrzynek. - - THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable - effort has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS - THAT WILL AT TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS - SOFTWARE IS RESTRICTED TO PERSONS AND ORGANIZATIONS WHO CAN AND - WILL TOLERATE ALL LOSSES, COSTS, OR OTHER PROBLEMS THEY INCUR DUE - TO THE SOFTWARE WITHOUT RECOMPENSE FROM JOHN HAUSER OR THE - INTERNATIONAL COMPUTER SCIENCE INSTITUTE, AND WHO FURTHERMORE - EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER - SCIENCE INSTITUTE (possibly via similar legal notice) AGAINST ALL - LOSSES, COSTS, OR OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND - CLIENTS DUE TO THE SOFTWARE, OR INCURRED BY ANYONE DUE TO A - DERIVATIVE WORK THEY CREATE USING ANY PART OF THE SOFTWARE. - - The following are expressly permitted, even for commercial - purposes: - - (1) distribution of SoftFloat in whole or in part, as long as this - and other legal notices remain and are prominent, and provided also - that, for a partial distribution, prominent notice is given that it - is a subset of the original; and - - (2) inclusion or use of SoftFloat in whole or in part in a - derivative work, provided that the use restrictions above are met - and the minimal documentation requirements stated in the source - code are satisfied. - --------------------------------------------------------------------- - - Data Types - ========== - - The WE32106 MAU stores values using IEEE-754 1985 types, plus a - non-standard Decimal type. - - - Decimal Type - 18 BCD digits long. Each digit is 4 bits wide. - Sign is encoded in byte 0. - - 3322 2222 2222 1111 1111 1100 0000 0000 - 1098 7654 3210 9876 5432 1098 7654 3210 - +-------------------+----+----+----+----+ - | unused | D18| D17| D16| D15| High Word - +----+----+----+----+----+----+----+----+ - | D14| D13| D12| D11| D10| D09| D08| D07| Middle Word - +----+----+----+----+----+----+----+----+ - | D06| D05| D04| D03| D02| D01| D00|sign| Low Word - +----+----+----+----+----+----+----+----+ - - Sign: 0: Positive Infinity 10: Positive Number - 1: Negative Infinity 11: Negative Number - 2: Positive NaN 12: Positive Number - 3: Negative NaN 13: Negative Number - 4-9: Trapping NaN 14-15: Positive Number - - - Extended Precision (80-bit) - exponent biased by 16383 - - 3 322222222221111 1 111110000000000 - 1 098765432109876 5 432109876543210 - +-----------------+-+---------------+ - | unused |S| Exponent | High Word - +-+---------------+-+---------------+ - |J| Fraction (high word) | Middle Word - +-+---------------------------------+ - | Fraction (low word) | Low Word - +-----------------------------------+ - - - - Double Precision (64-bit) - exponent biased by 1023 - - 3 3222222222 211111111110000000000 - 1 0987654321 098765432109876543210 - +-+----------+---------------------+ - |S| Exponent | Fraction (high) | High Word - +-+----------+---------------------+ - | Fraction (low) | Low Word - +----------------------------------+ - - - - Single Precision (32-bit) - exponent biased by 127 - - 3 32222222 22211111111110000000000 - 1 09876543 21098765432109876543210 - +-+--------+-----------------------+ - |S| Exp | Fraction | - +-+--------+-----------------------+ - -*/ - -#ifndef _3B2_REV2_MAU_H_ -#define _3B2_REV2_MAU_H_ - -#include "sim_defs.h" - -#define SRC_LEN_INVALID 0 -#define SRC_LEN_SINGLE 1 -#define SRC_LEN_DOUBLE 2 -#define SRC_LEN_TRIPLE 3 - -#define MAU_ASR_RC_SHIFT 22 - -#define MAU_ASR_PR 0x20u /* Partial Remainder */ -#define MAU_ASR_QS 0x40u /* Divide By Zero Sticky */ -#define MAU_ASR_US 0x80u /* Underflow Sticky */ -#define MAU_ASR_OS 0x100u /* Overflow Sticky */ -#define MAU_ASR_IS 0x200u /* Invalid Operation Sticky */ -#define MAU_ASR_PM 0x400u /* Inexact Mask */ -#define MAU_ASR_QM 0x800u /* Divide by Zero Mask */ -#define MAU_ASR_UM 0x1000u /* Underflow Mask */ -#define MAU_ASR_OM 0x2000u /* Overflow Mask */ -#define MAU_ASR_IM 0x4000u /* Invalid Operation Mask */ - -#define MAU_ASR_UO 0x10000u /* Unordered */ -#define MAU_ASR_CSC 0x20000u /* Context Switch Control */ -#define MAU_ASR_PS 0x40000u /* Inexact Sticky */ -#define MAU_ASR_IO 0x80000u /* Integer Overflow */ -#define MAU_ASR_Z 0x100000u /* Zero Flag */ -#define MAU_ASR_N 0x200000u /* Negative Flag */ -#define MAU_ASR_RC 0x400000u /* Round Control */ - -#define MAU_ASR_NTNC 0x1000000u /* Nontrapping NaN Control */ -#define MAU_ASR_ECP 0x2000000u /* Exception Condition */ - -#define MAU_ASR_RA 0x80000000u /* Result Available */ - -#define MAU_RC_RN 0 /* Round toward Nearest */ -#define MAU_RC_RP 1 /* Round toward Plus Infin. */ -#define MAU_RC_RM 2 /* Round toward Neg. Infin. */ -#define MAU_RC_RZ 3 /* Round toward Zero */ - -#define SFP_SIGN(V) (((V) >> 31) & 1) -#define SFP_EXP(V) (((V) >> 23) & 0xff) -#define SFP_FRAC(V) ((V) & 0x7fffff) - -#define DFP_SIGN(V) (((V) >> 63) & 1) -#define DFP_EXP(V) (((V) >> 52) & 0x7ff) -#define DFP_FRAC(V) ((V) & 0xfffffffffffffull) - -#define XFP_SIGN(V) (((V)->sign_exp >> 15) & 1) -#define XFP_EXP(V) ((V)->sign_exp & 0x7fff) -#define XFP_FRAC(V) ((V)->frac) - -#define XFP_IS_NORMAL(V) ((V)->frac & 0x8000000000000000ull) - -#define DEFAULT_XFP_NAN_SIGN_EXP 0xffff -#define DEFAULT_XFP_NAN_FRAC 0xc000000000000000ull - -#define SFP_IS_TRAPPING_NAN(V) (((((V) >> 22) & 0x1ff) == 0x1fe) && \ - ((V) & 0x3fffff)) -#define DFP_IS_TRAPPING_NAN(V) (((((V) >> 51) & 0xfff) == 0xffe) && \ - ((V) & 0x7ffffffffffffull)) -#define XFP_IS_NAN(V) ((((V)->sign_exp & 0x7fff) == 0x7fff) && \ - (t_uint64)((V)->frac << 1)) -#define XFP_IS_TRAPPING_NAN(V) ((((V)->sign_exp) & 0x7fff) && \ - ((((V)->frac) & ~(0x4000000000000000ull)) << 1) && \ - (((V)->frac) == ((V)->frac & ~(0x4000000000000000ull)))) -#define PACK_DFP(SIGN,EXP,FRAC) ((((t_uint64)(SIGN))<<63) + \ - (((t_uint64)(EXP))<<52) + \ - ((t_uint64)(FRAC))) -#define PACK_SFP(SIGN,EXP,FRAC) (((uint32)(SIGN)<<31) + \ - ((uint32)(EXP)<<23) + \ - ((uint32)(FRAC))) -#define PACK_XFP(SIGN,EXP,FRAC,V) do { \ - (V)->frac = (FRAC); \ - (V)->sign_exp = ((uint16)(SIGN) << 15) + (EXP); \ - (V)->s = FALSE; \ - } while (0) - -#define PACK_XFP_S(SIGN,EXP,FRAC,S,V) do { \ - (V)->frac = (FRAC); \ - (V)->sign_exp = ((uint16)(SIGN) << 15) + (EXP); \ - (V)->s = (S) != 0; \ - } while (0) - -#define MAU_RM ((RM)((mau_state.asr >> 22) & 3)) - -typedef enum { - M_ADD = 0x02, - M_SUB = 0x03, - M_DIV = 0x04, - M_REM = 0x05, - M_MUL = 0x06, - M_MOVE = 0x07, - M_RDASR = 0x08, - M_WRASR = 0x09, - M_CMP = 0x0a, - M_CMPE = 0x0b, - M_ABS = 0x0c, - M_SQRT = 0x0d, - M_RTOI = 0x0e, - M_FTOI = 0x0f, - M_ITOF = 0x10, - M_DTOF = 0x11, - M_FTOD = 0x12, - M_NOP = 0x13, - M_EROF = 0x14, - M_NEG = 0x17, - M_LDR = 0x18, - M_CMPS = 0x1a, - M_CMPES = 0x1b -} mau_opcodes; - -typedef enum { - M_OP3_F0_SINGLE, - M_OP3_F1_SINGLE, - M_OP3_F2_SINGLE, - M_OP3_F3_SINGLE, - M_OP3_F0_DOUBLE, - M_OP3_F1_DOUBLE, - M_OP3_F2_DOUBLE, - M_OP3_F3_DOUBLE, - M_OP3_F0_TRIPLE, - M_OP3_F1_TRIPLE, - M_OP3_F2_TRIPLE, - M_OP3_F3_TRIPLE, - M_OP3_MEM_SINGLE, - M_OP3_MEM_DOUBLE, - M_OP3_MEM_TRIPLE, - M_OP3_NONE -} op3_spec; - -/* Specifier bytes for Operands 1 and 2 */ -typedef enum { - M_OP_F0, - M_OP_F1, - M_OP_F2, - M_OP_F3, - M_OP_MEM_SINGLE, - M_OP_MEM_DOUBLE, - M_OP_MEM_TRIPLE, - M_OP_NONE -} op_spec; - -/* - * 128-bit value - */ -typedef struct { - t_uint64 low; - t_uint64 high; -} t_mau_128; - -/* - * Not-a-Number Type - */ -typedef struct { - t_bool sign; - t_uint64 high; - t_uint64 low; -} T_NAN; - -/* - * Extended Precision (80 bits). - * - * Note that an undocumented feature of the WE32106 requires the use - * of uint32 rather than uint16 for the sign and exponent components - * of the struct. Although bits 80-95 are "unused", several - * diagnostics actually expect these bits to be moved and preserved on - * word transfers. They are ignored and discarded by math routines, - * however. - * - * The 's' field holds the Sticky bit used by rounding. - */ -typedef struct { - uint32 sign_exp; /* Sign and Exponent */ - t_uint64 frac; /* Fraction/Significand/Mantissa */ - t_bool s; /* Sticky bit */ -} XFP; - -typedef struct { - uint32 h; - t_uint64 l; -} DEC; - -/* - * Supported rounding modes. - */ -typedef enum { - ROUND_NEAREST, - ROUND_PLUS_INF, - ROUND_MINUS_INF, - ROUND_ZERO -} RM; - -/* - * Double Precision (64 bits) - */ -typedef t_uint64 DFP; - -/* - * Single Precision (32 bits) - */ -typedef uint32 SFP; - -/* - * MAU state - */ - -typedef struct { - uint32 cmd; - /* Exception */ - uint32 exception; - /* Status register */ - uint32 asr; - t_bool trapping_nan; - /* Generate a Non-Trapping NaN */ - t_bool ntnan; - /* Source (from broadcast) */ - uint32 src; - /* Destination (from broadcast) */ - uint32 dst; - uint8 opcode; - uint8 op1; - uint8 op2; - uint8 op3; - /* Data Register */ - XFP dr; - /* Operand Registers */ - XFP f0; - XFP f1; - XFP f2; - XFP f3; -} MAU_STATE; - -t_stat mau_reset(DEVICE *dptr); -t_stat mau_attach(UNIT *uptr, CONST char *cptr); -t_stat mau_detach(UNIT *uptr); -t_stat mau_broadcast(uint32 cmd, uint32 src, uint32 dst); -CONST char *mau_description(DEVICE *dptr); -t_stat mau_broadcast(uint32 cmd, uint32 src, uint32 dst); - -#endif /* _3B2_REV2_MAU_H_ */ diff --git a/3B2/3b2_rev2_mmu.c b/3B2/3b2_rev2_mmu.c index 9c9dc2b0..7dc95497 100644 --- a/3B2/3b2_rev2_mmu.c +++ b/3B2/3b2_rev2_mmu.c @@ -1,826 +1,822 @@ -/* 3b2_rev2_mmu.c: AT&T 3B2 Rev 2 (Model 400) MMU (WE32101) Implementation - - Copyright (c) 2017, Seth J. Morabito - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - - Except as contained in this notice, the name of the author shall - not be used in advertising or otherwise to promote the sale, use or - other dealings in this Software without prior written authorization - from the author. -*/ - - -#include "3b2_cpu.h" -#include "3b2_mmu.h" -#include "3b2_sys.h" - -UNIT mmu_unit = { UDATA(NULL, 0, 0) }; - -MMU_STATE mmu_state; - -REG mmu_reg[] = { - { HRDATAD (ENABLE, mmu_state.enabled, 1, "Enabled?") }, - { HRDATAD (CONFIG, mmu_state.conf, 32, "Configuration") }, - { HRDATAD (VAR, mmu_state.var, 32, "Virtual Address") }, - { HRDATAD (FCODE, mmu_state.fcode, 32, "Fault Code") }, - { HRDATAD (FADDR, mmu_state.faddr, 32, "Fault Address") }, - { BRDATA (SDCL, mmu_state.sdcl, 16, 32, MMU_SDCS) }, - { BRDATA (SDCR, mmu_state.sdch, 16, 32, MMU_SDCS) }, - { BRDATA (PDCLL, mmu_state.pdcll, 16, 32, MMU_PDCS) }, - { BRDATA (PDCLH, mmu_state.pdclh, 16, 32, MMU_PDCS) }, - { BRDATA (PDCRL, mmu_state.pdcrl, 16, 32, MMU_PDCS) }, - { BRDATA (PDCRH, mmu_state.pdcrh, 16, 32, MMU_PDCS) }, - { BRDATA (SRAMA, mmu_state.sra, 16, 32, MMU_SRS) }, - { BRDATA (SRAMB, mmu_state.srb, 16, 32, MMU_SRS) }, - { NULL } -}; - -DEVICE mmu_dev = { - "MMU", /* name */ - &mmu_unit, /* units */ - mmu_reg, /* registers */ - NULL, /* modifiers */ - 1, /* #units */ - 16, /* address radix */ - 8, /* address width */ - 4, /* address incr */ - 16, /* data radix */ - 32, /* data width */ - NULL, /* examine routine */ - NULL, /* deposit routine */ - &mmu_init, /* reset routine */ - NULL, /* boot routine */ - NULL, /* attach routine */ - NULL, /* detach routine */ - NULL, /* context */ - DEV_DEBUG, /* flags */ - 0, /* debug control flags */ - sys_deb_tab, /* debug flag names */ - NULL, /* memory size change */ - NULL, /* logical name */ - NULL, /* help routine */ - NULL, /* attach help routine */ - NULL, /* help context */ - &mmu_description /* device description */ -}; - -/* - * Find an SD in the cache. - */ -static SIM_INLINE t_stat get_sdce(uint32 va, uint32 *sd0, uint32 *sd1) -{ - uint32 tag, sdch, sdcl; - uint8 ci; - - ci = (SID(va) * NUM_SDCE) + SD_IDX(va); - tag = SD_TAG(va); - - sdch = mmu_state.sdch[ci]; - sdcl = mmu_state.sdcl[ci]; - - if ((sdch & SD_GOOD_MASK) && SDCE_TAG(sdcl) == tag) { - *sd0 = SDCE_TO_SD0(sdch, sdcl); - *sd1 = SDCE_TO_SD1(sdch); - return SCPE_OK; - } - - return SCPE_NXM; -} - -/* - * Find a PD in the cache. Sets both the PD and the cached access - * permissions. - */ -static SIM_INLINE t_stat get_pdce(uint32 va, uint32 *pd, uint8 *pd_acc) -{ - uint32 tag, pdcll, pdclh, pdcrl, pdcrh; - uint8 ci; - - ci = (SID(va) * NUM_PDCE) + PD_IDX(va); - tag = PD_TAG(va); - - /* Left side */ - pdcll = mmu_state.pdcll[ci]; - pdclh = mmu_state.pdclh[ci]; - - /* Right side */ - pdcrl = mmu_state.pdcrl[ci]; - pdcrh = mmu_state.pdcrh[ci]; - - /* Search L and R to find a good entry with a matching tag. */ - if ((pdclh & PD_GOOD_MASK) && PDCXL_TAG(pdcll) == tag) { - *pd = PDCXH_TO_PD(pdclh); - *pd_acc = PDCXL_TO_ACC(pdcll); - return SCPE_OK; - } else if ((pdcrh & PD_GOOD_MASK) && PDCXL_TAG(pdcrl) == tag) { - *pd = PDCXH_TO_PD(pdcrh); - *pd_acc = PDCXL_TO_ACC(pdcrl); - return SCPE_OK; - } - - return SCPE_NXM; -} - -static SIM_INLINE void put_sdce(uint32 va, uint32 sd0, uint32 sd1) -{ - uint8 ci; - - ci = (SID(va) * NUM_SDCE) + SD_IDX(va); - - mmu_state.sdcl[ci] = SD_TO_SDCL(va, sd0); - mmu_state.sdch[ci] = SD_TO_SDCH(sd0, sd1); -} - - -static SIM_INLINE void put_pdce(uint32 va, uint32 sd0, uint32 pd) -{ - uint8 ci; - - ci = (SID(va) * NUM_PDCE) + PD_IDX(va); - - /* Cache Replacement Algorithm - * (from the WE32101 MMU Information Manual) - * - * 1. If G==0 for the left-hand entry, the new PD is cached in the - * left-hand entry and the U bit (left-hand side) is cleared to - * 0. - * - * 2. If G==1 for the left-hand entry, and G==0 for the right-hand - * entry, the new PD is cached in the right-hand entry and the - * U bit (left-hand side) is set to 1. - * - * 3. If G==1 for both entries, the U bit in the left-hand entry - * is examined. If U==0, the new PD is cached in the right-hand - * entry of the PDC row and U is set to 1. If U==1, it is - * cached in the left-hand entry and U is cleared to 0. - */ - - if ((mmu_state.pdclh[ci] & PD_GOOD_MASK) == 0) { - /* Use the left entry */ - mmu_state.pdcll[ci] = SD_TO_PDCXL(va, sd0); - mmu_state.pdclh[ci] = PD_TO_PDCXH(pd, sd0); - mmu_state.pdclh[ci] &= ~PDCLH_USED_MASK; - } else if ((mmu_state.pdcrh[ci] & PD_GOOD_MASK) == 0) { - /* Use the right entry */ - mmu_state.pdcrl[ci] = SD_TO_PDCXL(va, sd0); - mmu_state.pdcrh[ci] = PD_TO_PDCXH(pd, sd0); - mmu_state.pdclh[ci] |= PDCLH_USED_MASK; - } else { - /* Pick the least-recently-replaced side */ - if (mmu_state.pdclh[ci] & PDCLH_USED_MASK) { - mmu_state.pdcll[ci] = SD_TO_PDCXL(va, sd0); - mmu_state.pdclh[ci] = PD_TO_PDCXH(pd, sd0); - mmu_state.pdclh[ci] &= ~PDCLH_USED_MASK; - } else { - mmu_state.pdcrl[ci] = SD_TO_PDCXL(va, sd0); - mmu_state.pdcrh[ci] = PD_TO_PDCXH(pd, sd0); - mmu_state.pdclh[ci] |= PDCLH_USED_MASK; - } - } -} - -static SIM_INLINE void flush_sdce(uint32 va) -{ - uint8 ci; - - ci = (SID(va) * NUM_SDCE) + SD_IDX(va); - - if (mmu_state.sdch[ci] & SD_GOOD_MASK) { - mmu_state.sdch[ci] &= ~SD_GOOD_MASK; - } -} - -static SIM_INLINE void flush_pdce(uint32 va) -{ - uint32 tag, pdcll, pdclh, pdcrl, pdcrh; - uint8 ci; - - ci = (SID(va) * NUM_PDCE) + PD_IDX(va); - tag = PD_TAG(va); - - /* Left side */ - pdcll = mmu_state.pdcll[ci]; - pdclh = mmu_state.pdclh[ci]; - /* Right side */ - pdcrl = mmu_state.pdcrl[ci]; - pdcrh = mmu_state.pdcrh[ci]; - - /* Search L and R to find a good entry with a matching tag. */ - if ((pdclh & PD_GOOD_MASK) && PDCXL_TAG(pdcll) == tag) { - mmu_state.pdclh[ci] &= ~PD_GOOD_MASK; - } else if ((pdcrh & PD_GOOD_MASK) && PDCXL_TAG(pdcrl) == tag) { - mmu_state.pdcrh[ci] &= ~PD_GOOD_MASK; - } -} - -static SIM_INLINE void flush_cache_sec(uint8 sec) -{ - int i; - - for (i = 0; i < NUM_SDCE; i++) { - mmu_state.sdch[(sec * NUM_SDCE) + i] &= ~SD_GOOD_MASK; - } - for (i = 0; i < NUM_PDCE; i++) { - mmu_state.pdclh[(sec * NUM_PDCE) + i] &= ~PD_GOOD_MASK; - mmu_state.pdcrh[(sec * NUM_PDCE) + i] &= ~PD_GOOD_MASK; - } -} - -static SIM_INLINE void flush_caches() -{ - uint8 i; - - for (i = 0; i < NUM_SEC; i++) { - flush_cache_sec(i); - } -} - -static SIM_INLINE t_stat mmu_check_perm(uint8 flags, uint8 r_acc) -{ - switch(MMU_PERM(flags)) { - case 0: /* No Access */ - return SCPE_NXM; - case 1: /* Exec Only */ - if (r_acc != ACC_IF && r_acc != ACC_IFAD) { - return SCPE_NXM; - } - return SCPE_OK; - case 2: /* Read / Execute */ - if (r_acc != ACC_AF && r_acc != ACC_OF && - r_acc != ACC_IF && r_acc != ACC_IFAD && - r_acc != ACC_MT) { - return SCPE_NXM; - } - return SCPE_OK; - default: - return SCPE_OK; - } -} - -/* - * Update the M (modified) or R (referenced) bit the SD and cache - */ -static SIM_INLINE void mmu_update_sd(uint32 va, uint32 mask) -{ - uint32 sd0; - uint8 ci; - - ci = (SID(va) * NUM_SDCE) + SD_IDX(va); - - /* We go back to main memory to find the SD because the SD may - have been loaded from cache, which is lossy. */ - sd0 = pread_w(SD_ADDR(va)); - pwrite_w(SD_ADDR(va), sd0|mask); - - /* There is no 'R' bit in the SD cache, only an 'M' bit. */ - if (mask == SD_M_MASK) { - mmu_state.sdch[ci] |= mask; - } -} - -/* - * Update the M (modified) or R (referenced) bit the PD and cache - */ -static SIM_INLINE void mmu_update_pd(uint32 va, uint32 pd_addr, uint32 mask) -{ - uint32 pd, tag, pdcll, pdclh, pdcrl, pdcrh; - uint8 ci; - - tag = PD_TAG(va); - ci = (SID(va) * NUM_PDCE) + PD_IDX(va); - - /* We go back to main memory to find the PD because the PD may - have been loaded from cache, which is lossy. */ - pd = pread_w(pd_addr); - pwrite_w(pd_addr, pd|mask); - - /* Update in the cache */ - - /* Left side */ - pdcll = mmu_state.pdcll[ci]; - pdclh = mmu_state.pdclh[ci]; - - /* Right side */ - pdcrl = mmu_state.pdcrl[ci]; - pdcrh = mmu_state.pdcrh[ci]; - - /* Search L and R to find a good entry with a matching tag, then - update the appropriate bit */ - if ((pdclh & PD_GOOD_MASK) && PDCXL_TAG(pdcll) == tag) { - mmu_state.pdclh[ci] |= mask; - } else if ((pdcrh & PD_GOOD_MASK) && PDCXL_TAG(pdcrl) == tag) { - mmu_state.pdcrh[ci] |= mask; - } -} - -t_stat mmu_init(DEVICE *dptr) -{ - flush_caches(); - return SCPE_OK; -} - -uint32 mmu_read(uint32 pa, size_t size) -{ - uint32 offset; - uint32 data = 0; - - offset = (pa >> 2) & 0x1f; - - switch ((pa >> 8) & 0xf) { - case MMU_SDCL: - data = mmu_state.sdcl[offset]; - sim_debug(READ_MSG, &mmu_dev, - "[%08x] [pa=%08x] MMU_SDCL[%d] = %08x\n", - R[NUM_PC], pa, offset, data); - break; - case MMU_SDCH: - data = mmu_state.sdch[offset]; - sim_debug(READ_MSG, &mmu_dev, - "[%08x] MMU_SDCH[%d] = %08x\n", - R[NUM_PC], offset, data); - break; - case MMU_PDCRL: - data = mmu_state.pdcrl[offset]; - sim_debug(READ_MSG, &mmu_dev, - "[%08x] MMU_PDCRL[%d] = %08x\n", - R[NUM_PC], offset, data); - break; - case MMU_PDCRH: - data = mmu_state.pdcrh[offset]; - sim_debug(READ_MSG, &mmu_dev, - "[%08x] MMU_PDCRH[%d] = %08x\n", - R[NUM_PC], offset, data); - break; - case MMU_PDCLL: - data = mmu_state.pdcll[offset]; - sim_debug(READ_MSG, &mmu_dev, - "[%08x] MMU_PDCLL[%d] = %08x\n", - R[NUM_PC], offset, data); - break; - case MMU_PDCLH: - data = mmu_state.pdclh[offset]; - sim_debug(READ_MSG, &mmu_dev, - "[%08x] MMU_PDCLH[%d] = %08x\n", - R[NUM_PC], offset, data); - break; - case MMU_SRAMA: - data = mmu_state.sra[offset]; - sim_debug(READ_MSG, &mmu_dev, - "[%08x] MMU_SRAMA[%d] = %08x\n", - R[NUM_PC], offset, data); - break; - case MMU_SRAMB: - data = mmu_state.srb[offset]; - sim_debug(READ_MSG, &mmu_dev, - "[%08x] MMU_SRAMB[%d] = %08x\n", - R[NUM_PC], offset, data); - break; - case MMU_FC: - data = mmu_state.fcode; - break; - case MMU_FA: - data = mmu_state.faddr; - break; - case MMU_CONF: - data = mmu_state.conf & 0x7; - sim_debug(READ_MSG, &mmu_dev, - "[%08x] MMU_CONF = %08x\n", - R[NUM_PC], data); - break; - case MMU_VAR: - data = mmu_state.var; - sim_debug(READ_MSG, &mmu_dev, - "[%08x] MMU_VAR = %08x\n", - R[NUM_PC], data); - break; - } - - return data; -} - -void mmu_write(uint32 pa, uint32 val, size_t size) -{ - uint32 offset; - - offset = (pa >> 2) & 0x1f; - - switch ((pa >> 8) & 0xf) { - case MMU_SDCL: - sim_debug(WRITE_MSG, &mmu_dev, - "MMU_SDCL[%d] = %08x\n", - offset, val); - mmu_state.sdcl[offset] = val; - break; - case MMU_SDCH: - sim_debug(WRITE_MSG, &mmu_dev, - "MMU_SDCH[%d] = %08x\n", - offset, val); - mmu_state.sdch[offset] = val; - break; - case MMU_PDCRL: - sim_debug(WRITE_MSG, &mmu_dev, - "MMU_PDCRL[%d] = %08x\n", - offset, val); - mmu_state.pdcrl[offset] = val; - break; - case MMU_PDCRH: - sim_debug(WRITE_MSG, &mmu_dev, - "MMU_PDCRH[%d] = %08x\n", - offset, val); - mmu_state.pdcrh[offset] = val; - break; - case MMU_PDCLL: - sim_debug(WRITE_MSG, &mmu_dev, - "MMU_PDCLL[%d] = %08x\n", - offset, val); - mmu_state.pdcll[offset] = val; - break; - case MMU_PDCLH: - sim_debug(WRITE_MSG, &mmu_dev, - "MMU_PDCLH[%d] = %08x\n", - offset, val); - mmu_state.pdclh[offset] = val; - break; - case MMU_SRAMA: - offset = offset & 3; - mmu_state.sra[offset] = val; - mmu_state.sec[offset].addr = val & 0xffffffe0; - /* We flush the entire section on writing SRAMA */ - sim_debug(WRITE_MSG, &mmu_dev, - "[%08x] MMU_SRAMA[%d] = %08x\n", - R[NUM_PC], offset, val); - flush_cache_sec((uint8) offset); - break; - case MMU_SRAMB: - offset = offset & 3; - mmu_state.srb[offset] = val; - mmu_state.sec[offset].len = (val >> 10) & 0x1fff; - /* We do not flush the cache on writing SRAMB */ - sim_debug(WRITE_MSG, &mmu_dev, - "[%08x] MMU_SRAMB[%d] = %08x (len=%06x)\n", - R[NUM_PC], offset, val, mmu_state.sec[offset].len); - break; - case MMU_FC: - mmu_state.fcode = val; - break; - case MMU_FA: - mmu_state.faddr = val; - break; - case MMU_CONF: - mmu_state.conf = val & 0x7; - break; - case MMU_VAR: - mmu_state.var = val; - flush_sdce(val); - flush_pdce(val); - break; - } -} - -/* Helper functions for MMU decode. */ - -/* - * Get the Segment Descriptor for a virtual address on a cache miss. - * - * Returns SCPE_OK on success, SCPE_NXM on failure. - * - * If SCPE_NXM is returned, a failure code and fault address will be - * set in the appropriate registers. - * - * As always, the flag 'fc' may be set to FALSE to avoid certain - * typses of fault checking. - * - */ -t_stat mmu_get_sd(uint32 va, uint8 r_acc, t_bool fc, - uint32 *sd0, uint32 *sd1) -{ - /* We immediately do some bounds checking (fc flag is not checked - * because this is a fatal error) */ - if (SSL(va) > SRAMB_LEN(va)) { - MMU_FAULT(MMU_F_SDTLEN); - sim_debug(EXECUTE_MSG, &mmu_dev, - "[%08x] SDT Length Fault. sramb_len=%x ssl=%x va=%08x\n", - R[NUM_PC], SRAMB_LEN(va), SSL(va), va); - return SCPE_NXM; - } - - /* sd0 contains the segment descriptor, sd1 contains a pointer to - the PDT or Segment */ - *sd0 = pread_w(SD_ADDR(va)); - *sd1 = pread_w(SD_ADDR(va) + 4); - - if (!SD_VALID(*sd0)) { - sim_debug(EXECUTE_MSG, &mmu_dev, - "[%08x] Invalid Segment Descriptor. va=%08x sd0=%08x\n", - R[NUM_PC], va, *sd0); - MMU_FAULT(MMU_F_INV_SD); - return SCPE_NXM; - } - - /* TODO: Handle indirect lookups. */ - if (SD_INDIRECT(*sd0)) { - stop_reason = STOP_MMU; - return SCPE_NXM; - } - - /* If the segment descriptor isn't present, we need to - * fail out */ - if (!SD_PRESENT(*sd0)) { - if (SD_CONTIG(*sd0)) { - sim_debug(EXECUTE_MSG, &mmu_dev, - "[%08x] Segment Not Present. va=%08x", - R[NUM_PC], va); - MMU_FAULT(MMU_F_SEG_NOT_PRES); - return SCPE_NXM; - } else { - sim_debug(EXECUTE_MSG, &mmu_dev, - "[%08x] PDT Not Present. va=%08x", - R[NUM_PC], va); - MMU_FAULT(MMU_F_PDT_NOT_PRES); - return SCPE_NXM; - } - } - - if (SHOULD_CACHE_SD(*sd0)) { - put_sdce(va, *sd0, *sd1); - } - - return SCPE_OK; -} - -/* - * Load a page descriptor from memory - */ -t_stat mmu_get_pd(uint32 va, uint8 r_acc, t_bool fc, - uint32 sd0, uint32 sd1, - uint32 *pd, uint8 *pd_acc) -{ - uint32 pd_addr; - - /* Where do we find the page descriptor? */ - pd_addr = SD_SEG_ADDR(sd1) + (PSL(va) * 4); - - /* Bounds checking on length */ - if ((PSL(va) * 4) >= MAX_OFFSET(sd0)) { - sim_debug(EXECUTE_MSG, &mmu_dev, - "[%08x] PDT Length Fault. " - "PDT Offset=%08x Max Offset=%08x va=%08x\n", - R[NUM_PC], (PSL(va) * 4), - MAX_OFFSET(sd0), va); - MMU_FAULT(MMU_F_PDTLEN); - return SCPE_NXM; - } - - *pd = pread_w(pd_addr); - - /* Copy the access flags from the SD */ - *pd_acc = SD_ACC(sd0); - - /* Cache it */ - if (SHOULD_CACHE_PD(*pd)) { - put_pdce(va, sd0, *pd); - } - - return SCPE_OK; -} - -/* - * Decode an address from a contiguous segment. - */ -t_stat mmu_decode_contig(uint32 va, uint8 r_acc, - uint32 sd0, uint32 sd1, - t_bool fc, uint32 *pa) -{ - if (fc) { - /* Update R and M bits if configured */ - if (SHOULD_UPDATE_SD_R_BIT(sd0)) { - sim_debug(EXECUTE_MSG, &mmu_dev, - "[%08x] Updating R bit in SD\n", - R[NUM_PC]); - mmu_update_sd(va, SD_R_MASK); - } - - if (SHOULD_UPDATE_SD_M_BIT(sd0)) { - sim_debug(EXECUTE_MSG, &mmu_dev, - "[%08x] Updating M bit in SD\n", - R[NUM_PC]); - mmu_update_sd(va, SD_M_MASK); - } - - /* Generate object trap if needed */ - if (SD_TRAP(sd0)) { - sim_debug(EXECUTE_MSG, &mmu_dev, - "[%08x] Object Trap. va=%08x", - R[NUM_PC], va); - MMU_FAULT(MMU_F_OTRAP); - return SCPE_NXM; - } - } - - *pa = SD_SEG_ADDR(sd1) + SOT(va); - return SCPE_OK; -} - -t_stat mmu_decode_paged(uint32 va, uint8 r_acc, t_bool fc, - uint32 sd1, uint32 pd, - uint8 pd_acc, uint32 *pa) -{ - /* If the PD is not marked present, fail */ - if (!PD_PRESENT(pd)) { - sim_debug(EXECUTE_MSG, &mmu_dev, - "[%08x] Page Not Present. " - "pd=%08x r_acc=%x va=%08x\n", - R[NUM_PC], pd, r_acc, va); - MMU_FAULT(MMU_F_PAGE_NOT_PRES); - return SCPE_NXM; - } - - if (fc) { - /* If this is a write or interlocked read access, and - the 'W' bit is set, trigger a write fault */ - if ((r_acc == ACC_W || r_acc == ACC_IR) && PD_WFAULT(pd)) { - sim_debug(EXECUTE_MSG, &mmu_dev, - "[%08x] Page Write Fault. va=%08x\n", - R[NUM_PC], va); - MMU_FAULT(MMU_F_PW); - return SCPE_NXM; - } - - /* If this is a write, modify the M bit */ - if (SHOULD_UPDATE_PD_M_BIT(pd)) { - sim_debug(EXECUTE_MSG, &mmu_dev, - "[%08x] Updating M bit in PD\n", - R[NUM_PC]); - mmu_update_pd(va, PD_LOC(sd1, va), PD_M_MASK); - } - - /* Modify the R bit and write it back */ - if (SHOULD_UPDATE_PD_R_BIT(pd)) { - sim_debug(EXECUTE_MSG, &mmu_dev, - "[%08x] Updating R bit in PD\n", - R[NUM_PC]); - mmu_update_pd(va, PD_LOC(sd1, va), PD_R_MASK); - } - } - - *pa = PD_ADDR(pd) + POT(va); - return SCPE_OK; -} - -/* - * Translate a virtual address into a physical address. - * - * If "fc" is false, this function will bypass: - * - * - Access flag checks - * - Cache insertion - * - Setting MMU fault registers - * - Modifying segment and page descriptor bits - */ - -t_stat mmu_decode_va(uint32 va, uint8 r_acc, t_bool fc, uint32 *pa) -{ - uint32 sd0, sd1, pd; - uint8 pd_acc; - t_stat sd_cached, pd_cached; - - if (!mmu_state.enabled) { - *pa = va; - return SCPE_OK; - } - - /* We must check both caches first to determine what kind of miss - processing to do. */ - - sd_cached = get_sdce(va, &sd0, &sd1); - pd_cached = get_pdce(va, &pd, &pd_acc); - - if (sd_cached == SCPE_OK && pd_cached != SCPE_OK) { - if (SD_PAGED(sd0) && mmu_get_pd(va, r_acc, fc, sd0, sd1, &pd, &pd_acc) != SCPE_OK) { - sim_debug(EXECUTE_MSG, &mmu_dev, - "[%08x] Could not get PD (partial miss). r_acc=%d, fc=%d, va=%08x\n", - R[NUM_PC], r_acc, fc, va); - return SCPE_NXM; - } - } else if (sd_cached != SCPE_OK && pd_cached == SCPE_OK) { - if (mmu_get_sd(va, r_acc, fc, &sd0, &sd1) != SCPE_OK) { - sim_debug(EXECUTE_MSG, &mmu_dev, - "[%08x] Could not get SD (partial miss). r_acc=%d, fc=%d, va=%08x\n", - R[NUM_PC], r_acc, fc, va); - return SCPE_NXM; - } - } else if (sd_cached != SCPE_OK && pd_cached != SCPE_OK) { - if (mmu_get_sd(va, r_acc, fc, &sd0, &sd1) != SCPE_OK) { - sim_debug(EXECUTE_MSG, &mmu_dev, - "[%08x] Could not get SD (full miss). r_acc=%d, fc=%d, va=%08x\n", - R[NUM_PC], r_acc, fc, va); - return SCPE_NXM; - } - - if (SD_PAGED(sd0) && mmu_get_pd(va, r_acc, fc, sd0, sd1, &pd, &pd_acc) != SCPE_OK) { - sim_debug(EXECUTE_MSG, &mmu_dev, - "[%08x] Could not get PD (full miss). r_acc=%d, fc=%d, va=%08x\n", - R[NUM_PC], r_acc, fc, va); - return SCPE_NXM; - } - } - - if (SD_PAGED(sd0)) { - if (fc && mmu_check_perm(pd_acc, r_acc) != SCPE_OK) { - sim_debug(EXECUTE_MSG, &mmu_dev, - "[%08x] PAGED: NO ACCESS TO MEMORY AT %08x.\n" - "\t\tcpu_cm=%d r_acc=%x pd_acc=%02x\n" - "\t\tpd=%08x psw=%08x\n", - R[NUM_PC], va, CPU_CM, r_acc, pd_acc, - pd, R[NUM_PSW]); - MMU_FAULT(MMU_F_ACC); - return SCPE_NXM; - } - if (PD_LAST(pd) && (PSL_C(va) | POT(va)) >= MAX_OFFSET(sd0)) { - sim_debug(EXECUTE_MSG, &mmu_dev, - "[%08x] PAGED: Segment Offset Fault.\n", - R[NUM_PC]); - MMU_FAULT(MMU_F_SEG_OFFSET); - return SCPE_NXM; - } - return mmu_decode_paged(va, r_acc, fc, sd1, pd, pd_acc, pa); - } else { - if (fc && mmu_check_perm(SD_ACC(sd0), r_acc) != SCPE_OK) { - sim_debug(EXECUTE_MSG, &mmu_dev, - "[%08x] CONTIGUOUS: NO ACCESS TO MEMORY AT %08x.\n" - "\t\tsd0=%08x sd0_addr=%08x\n" - "\t\tcpu_cm=%d acc_req=%x sd_acc=%02x\n", - R[NUM_PC], va, - sd0, SD_ADDR(va), - CPU_CM, r_acc, SD_ACC(sd0)); - MMU_FAULT(MMU_F_ACC); - return SCPE_NXM; - } - if (SOT(va) >= MAX_OFFSET(sd0)) { - sim_debug(EXECUTE_MSG, &mmu_dev, - "[%08x] CONTIGUOUS: Segment Offset Fault. " - "sd0=%08x sd_addr=%08x SOT=%08x len=%08x va=%08x\n", - R[NUM_PC], sd0, SD_ADDR(va), SOT(va), - MAX_OFFSET(sd0), va); - MMU_FAULT(MMU_F_SEG_OFFSET); - return SCPE_NXM; - } - return mmu_decode_contig(va, r_acc, sd0, sd1, fc, pa); - } -} - -uint32 mmu_xlate_addr(uint32 va, uint8 r_acc) -{ - uint32 pa; - t_stat succ; - - succ = mmu_decode_va(va, r_acc, TRUE, &pa); - - if (succ == SCPE_OK) { - mmu_state.var = va; - return pa; - } else { - cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT); - return 0; - } -} - -void mmu_enable() -{ - sim_debug(EXECUTE_MSG, &mmu_dev, - "[%08x] Enabling MMU.\n", - R[NUM_PC]); - mmu_state.enabled = TRUE; -} - -void mmu_disable() -{ - sim_debug(EXECUTE_MSG, &mmu_dev, - "[%08x] Disabling MMU.\n", - R[NUM_PC]); - mmu_state.enabled = FALSE; -} - -CONST char *mmu_description(DEVICE *dptr) -{ - return "WE32101"; -} +/* 3b2_rev2_mmu.c: WE32101 MMU + + Copyright (c) 2017-2022, Seth J. Morabito + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + Except as contained in this notice, the name of the author shall + not be used in advertising or otherwise to promote the sale, use or + other dealings in this Software without prior written authorization + from the author. +*/ + + +#include "3b2_cpu.h" +#include "3b2_mmu.h" +#include "3b2_sys.h" +#include "3b2_mem.h" + +UNIT mmu_unit = { UDATA(NULL, 0, 0) }; + +MMU_STATE mmu_state; + +REG mmu_reg[] = { + { HRDATAD (ENABLE, mmu_state.enabled, 1, "Enabled?") }, + { HRDATAD (CONFIG, mmu_state.conf, 32, "Configuration") }, + { HRDATAD (VAR, mmu_state.var, 32, "Virtual Address") }, + { HRDATAD (FCODE, mmu_state.fcode, 32, "Fault Code") }, + { HRDATAD (FADDR, mmu_state.faddr, 32, "Fault Address") }, + { BRDATA (SDCL, mmu_state.sdcl, 16, 32, MMU_SDCS) }, + { BRDATA (SDCR, mmu_state.sdch, 16, 32, MMU_SDCS) }, + { BRDATA (PDCLL, mmu_state.pdcll, 16, 32, MMU_PDCS) }, + { BRDATA (PDCLH, mmu_state.pdclh, 16, 32, MMU_PDCS) }, + { BRDATA (PDCRL, mmu_state.pdcrl, 16, 32, MMU_PDCS) }, + { BRDATA (PDCRH, mmu_state.pdcrh, 16, 32, MMU_PDCS) }, + { BRDATA (SRAMA, mmu_state.sra, 16, 32, MMU_SRS) }, + { BRDATA (SRAMB, mmu_state.srb, 16, 32, MMU_SRS) }, + { NULL } +}; + +DEVICE mmu_dev = { + "MMU", /* name */ + &mmu_unit, /* units */ + mmu_reg, /* registers */ + NULL, /* modifiers */ + 1, /* #units */ + 16, /* address radix */ + 8, /* address width */ + 4, /* address incr */ + 16, /* data radix */ + 32, /* data width */ + NULL, /* examine routine */ + NULL, /* deposit routine */ + &mmu_init, /* reset routine */ + NULL, /* boot routine */ + NULL, /* attach routine */ + NULL, /* detach routine */ + NULL, /* context */ + DEV_DEBUG, /* flags */ + 0, /* debug control flags */ + sys_deb_tab, /* debug flag names */ + NULL, /* memory size change */ + NULL, /* logical name */ + NULL, /* help routine */ + NULL, /* attach help routine */ + NULL, /* help context */ + &mmu_description /* device description */ +}; + +/* + * Find an SD in the cache. + */ +static SIM_INLINE t_stat get_sdce(uint32 va, uint32 *sd0, uint32 *sd1) +{ + uint32 tag, sdch, sdcl; + uint8 ci; + + ci = (SID(va) * NUM_SDCE) + SD_IDX(va); + tag = SD_TAG(va); + + sdch = mmu_state.sdch[ci]; + sdcl = mmu_state.sdcl[ci]; + + if ((sdch & SD_GOOD_MASK) && SDCE_TAG(sdcl) == tag) { + *sd0 = SDCE_TO_SD0(sdch, sdcl); + *sd1 = SDCE_TO_SD1(sdch); + return SCPE_OK; + } + + return SCPE_NXM; +} + +/* + * Find a PD in the cache. Sets both the PD and the cached access + * permissions. + */ +static SIM_INLINE t_stat get_pdce(uint32 va, uint32 *pd, uint8 *pd_acc) +{ + uint32 tag, pdcll, pdclh, pdcrl, pdcrh; + uint8 ci; + + ci = (SID(va) * NUM_PDCE) + PD_IDX(va); + tag = PD_TAG(va); + + /* Left side */ + pdcll = mmu_state.pdcll[ci]; + pdclh = mmu_state.pdclh[ci]; + + /* Right side */ + pdcrl = mmu_state.pdcrl[ci]; + pdcrh = mmu_state.pdcrh[ci]; + + /* Search L and R to find a good entry with a matching tag. */ + if ((pdclh & PD_GOOD_MASK) && PDCXL_TAG(pdcll) == tag) { + *pd = PDCXH_TO_PD(pdclh); + *pd_acc = PDCXL_TO_ACC(pdcll); + return SCPE_OK; + } else if ((pdcrh & PD_GOOD_MASK) && PDCXL_TAG(pdcrl) == tag) { + *pd = PDCXH_TO_PD(pdcrh); + *pd_acc = PDCXL_TO_ACC(pdcrl); + return SCPE_OK; + } + + return SCPE_NXM; +} + +static SIM_INLINE void put_sdce(uint32 va, uint32 sd0, uint32 sd1) +{ + uint8 ci; + + ci = (SID(va) * NUM_SDCE) + SD_IDX(va); + + mmu_state.sdcl[ci] = SD_TO_SDCL(va, sd0); + mmu_state.sdch[ci] = SD_TO_SDCH(sd0, sd1); +} + + +static SIM_INLINE void put_pdce(uint32 va, uint32 sd0, uint32 pd) +{ + uint8 ci; + + ci = (SID(va) * NUM_PDCE) + PD_IDX(va); + + /* Cache Replacement Algorithm + * (from the WE32101 MMU Information Manual) + * + * 1. If G==0 for the left-hand entry, the new PD is cached in the + * left-hand entry and the U bit (left-hand side) is cleared to + * 0. + * + * 2. If G==1 for the left-hand entry, and G==0 for the right-hand + * entry, the new PD is cached in the right-hand entry and the + * U bit (left-hand side) is set to 1. + * + * 3. If G==1 for both entries, the U bit in the left-hand entry + * is examined. If U==0, the new PD is cached in the right-hand + * entry of the PDC row and U is set to 1. If U==1, it is + * cached in the left-hand entry and U is cleared to 0. + */ + + if ((mmu_state.pdclh[ci] & PD_GOOD_MASK) == 0) { + /* Use the left entry */ + mmu_state.pdcll[ci] = SD_TO_PDCXL(va, sd0); + mmu_state.pdclh[ci] = PD_TO_PDCXH(pd, sd0); + mmu_state.pdclh[ci] &= ~PDCLH_USED_MASK; + } else if ((mmu_state.pdcrh[ci] & PD_GOOD_MASK) == 0) { + /* Use the right entry */ + mmu_state.pdcrl[ci] = SD_TO_PDCXL(va, sd0); + mmu_state.pdcrh[ci] = PD_TO_PDCXH(pd, sd0); + mmu_state.pdclh[ci] |= PDCLH_USED_MASK; + } else { + /* Pick the least-recently-replaced side */ + if (mmu_state.pdclh[ci] & PDCLH_USED_MASK) { + mmu_state.pdcll[ci] = SD_TO_PDCXL(va, sd0); + mmu_state.pdclh[ci] = PD_TO_PDCXH(pd, sd0); + mmu_state.pdclh[ci] &= ~PDCLH_USED_MASK; + } else { + mmu_state.pdcrl[ci] = SD_TO_PDCXL(va, sd0); + mmu_state.pdcrh[ci] = PD_TO_PDCXH(pd, sd0); + mmu_state.pdclh[ci] |= PDCLH_USED_MASK; + } + } +} + +static SIM_INLINE void flush_sdce(uint32 va) +{ + uint8 ci; + + ci = (SID(va) * NUM_SDCE) + SD_IDX(va); + + if (mmu_state.sdch[ci] & SD_GOOD_MASK) { + mmu_state.sdch[ci] &= ~SD_GOOD_MASK; + } +} + +static SIM_INLINE void flush_pdce(uint32 va) +{ + uint32 tag, pdcll, pdclh, pdcrl, pdcrh; + uint8 ci; + + ci = (SID(va) * NUM_PDCE) + PD_IDX(va); + tag = PD_TAG(va); + + /* Left side */ + pdcll = mmu_state.pdcll[ci]; + pdclh = mmu_state.pdclh[ci]; + /* Right side */ + pdcrl = mmu_state.pdcrl[ci]; + pdcrh = mmu_state.pdcrh[ci]; + + /* Search L and R to find a good entry with a matching tag. */ + if ((pdclh & PD_GOOD_MASK) && PDCXL_TAG(pdcll) == tag) { + mmu_state.pdclh[ci] &= ~PD_GOOD_MASK; + } else if ((pdcrh & PD_GOOD_MASK) && PDCXL_TAG(pdcrl) == tag) { + mmu_state.pdcrh[ci] &= ~PD_GOOD_MASK; + } +} + +static SIM_INLINE void flush_cache_sec(uint8 sec) +{ + int i; + + for (i = 0; i < NUM_SDCE; i++) { + mmu_state.sdch[(sec * NUM_SDCE) + i] &= ~SD_GOOD_MASK; + } + for (i = 0; i < NUM_PDCE; i++) { + mmu_state.pdclh[(sec * NUM_PDCE) + i] &= ~PD_GOOD_MASK; + mmu_state.pdcrh[(sec * NUM_PDCE) + i] &= ~PD_GOOD_MASK; + } +} + +static SIM_INLINE void flush_caches() +{ + uint8 i; + + for (i = 0; i < NUM_SEC; i++) { + flush_cache_sec(i); + } +} + +static SIM_INLINE t_stat mmu_check_perm(uint8 flags, uint8 r_acc) +{ + switch(MMU_PERM(flags)) { + case 0: /* No Access */ + return SCPE_NXM; + case 1: /* Exec Only */ + if (r_acc != ACC_IF && + r_acc != ACC_IFAD) { + return SCPE_NXM; + } + return SCPE_OK; + case 2: /* Read / Execute */ + if (r_acc != ACC_IF && + r_acc != ACC_IFAD && + r_acc != ACC_OF && + r_acc != ACC_AF && + r_acc != ACC_MT) { + return SCPE_NXM; + } + return SCPE_OK; + default: + return SCPE_OK; + } +} + +/* + * Update the M (modified) or R (referenced) bit the SD and cache + */ +static SIM_INLINE void mmu_update_sd(uint32 va, uint32 mask) +{ + uint32 sd0; + uint8 ci; + + ci = (SID(va) * NUM_SDCE) + SD_IDX(va); + + /* We go back to main memory to find the SD because the SD may + have been loaded from cache, which is lossy. */ + sd0 = pread_w(SD_ADDR(va), BUS_PER); + pwrite_w(SD_ADDR(va), sd0|mask, BUS_PER); + + /* There is no 'R' bit in the SD cache, only an 'M' bit. */ + if (mask == SD_M_MASK) { + mmu_state.sdch[ci] |= mask; + } +} + +/* + * Update the M (modified) or R (referenced) bit the PD and cache + */ +static SIM_INLINE void mmu_update_pd(uint32 va, uint32 pd_addr, uint32 mask) +{ + uint32 pd, tag, pdcll, pdclh, pdcrl, pdcrh; + uint8 ci; + + tag = PD_TAG(va); + ci = (SID(va) * NUM_PDCE) + PD_IDX(va); + + /* We go back to main memory to find the PD because the PD may + have been loaded from cache, which is lossy. */ + pd = pread_w(pd_addr, BUS_PER); + pwrite_w(pd_addr, pd|mask, BUS_PER); + + /* Update in the cache */ + + /* Left side */ + pdcll = mmu_state.pdcll[ci]; + pdclh = mmu_state.pdclh[ci]; + + /* Right side */ + pdcrl = mmu_state.pdcrl[ci]; + pdcrh = mmu_state.pdcrh[ci]; + + /* Search L and R to find a good entry with a matching tag, then + update the appropriate bit */ + if ((pdclh & PD_GOOD_MASK) && PDCXL_TAG(pdcll) == tag) { + mmu_state.pdclh[ci] |= mask; + } else if ((pdcrh & PD_GOOD_MASK) && PDCXL_TAG(pdcrl) == tag) { + mmu_state.pdcrh[ci] |= mask; + } +} + +t_stat mmu_init(DEVICE *dptr) +{ + flush_caches(); + return SCPE_OK; +} + +uint32 mmu_read(uint32 pa, size_t size) +{ + uint32 offset; + uint32 data = 0; + + offset = (pa >> 2) & 0x1f; + + switch ((pa >> 8) & 0xf) { + case MMU_SDCL: + data = mmu_state.sdcl[offset]; + sim_debug(READ_MSG, &mmu_dev, + "[pa=%08x] MMU_SDCL[%d] = %08x\n", + pa, offset, data); + break; + case MMU_SDCH: + data = mmu_state.sdch[offset]; + sim_debug(READ_MSG, &mmu_dev, + "MMU_SDCH[%d] = %08x\n", + offset, data); + break; + case MMU_PDCRL: + data = mmu_state.pdcrl[offset]; + sim_debug(READ_MSG, &mmu_dev, + "MMU_PDCRL[%d] = %08x\n", + offset, data); + break; + case MMU_PDCRH: + data = mmu_state.pdcrh[offset]; + sim_debug(READ_MSG, &mmu_dev, + "MMU_PDCRH[%d] = %08x\n", + offset, data); + break; + case MMU_PDCLL: + data = mmu_state.pdcll[offset]; + sim_debug(READ_MSG, &mmu_dev, + "MMU_PDCLL[%d] = %08x\n", + offset, data); + break; + case MMU_PDCLH: + data = mmu_state.pdclh[offset]; + sim_debug(READ_MSG, &mmu_dev, + "MMU_PDCLH[%d] = %08x\n", + offset, data); + break; + case MMU_SRAMA: + data = mmu_state.sra[offset]; + sim_debug(READ_MSG, &mmu_dev, + "MMU_SRAMA[%d] = %08x\n", + offset, data); + break; + case MMU_SRAMB: + data = mmu_state.srb[offset]; + sim_debug(READ_MSG, &mmu_dev, + "MMU_SRAMB[%d] = %08x\n", + offset, data); + break; + case MMU_FC: + data = mmu_state.fcode; + break; + case MMU_FA: + data = mmu_state.faddr; + break; + case MMU_CONF: + data = mmu_state.conf & 0x7; + sim_debug(READ_MSG, &mmu_dev, + "MMU_CONF = %08x\n", + data); + break; + case MMU_VAR: + data = mmu_state.var; + sim_debug(READ_MSG, &mmu_dev, + "MMU_VAR = %08x\n", + data); + break; + } + + return data; +} + +void mmu_write(uint32 pa, uint32 val, size_t size) +{ + uint32 offset; + + offset = (pa >> 2) & 0x1f; + + switch ((pa >> 8) & 0xf) { + case MMU_SDCL: + sim_debug(WRITE_MSG, &mmu_dev, + "MMU_SDCL[%d] = %08x\n", + offset, val); + mmu_state.sdcl[offset] = val; + break; + case MMU_SDCH: + sim_debug(WRITE_MSG, &mmu_dev, + "MMU_SDCH[%d] = %08x\n", + offset, val); + mmu_state.sdch[offset] = val; + break; + case MMU_PDCRL: + sim_debug(WRITE_MSG, &mmu_dev, + "MMU_PDCRL[%d] = %08x\n", + offset, val); + mmu_state.pdcrl[offset] = val; + break; + case MMU_PDCRH: + sim_debug(WRITE_MSG, &mmu_dev, + "MMU_PDCRH[%d] = %08x\n", + offset, val); + mmu_state.pdcrh[offset] = val; + break; + case MMU_PDCLL: + sim_debug(WRITE_MSG, &mmu_dev, + "MMU_PDCLL[%d] = %08x\n", + offset, val); + mmu_state.pdcll[offset] = val; + break; + case MMU_PDCLH: + sim_debug(WRITE_MSG, &mmu_dev, + "MMU_PDCLH[%d] = %08x\n", + offset, val); + mmu_state.pdclh[offset] = val; + break; + case MMU_SRAMA: + offset = offset & 3; + mmu_state.sra[offset] = val; + mmu_state.sec[offset].addr = val & 0xffffffe0; + /* We flush the entire section on writing SRAMA */ + sim_debug(WRITE_MSG, &mmu_dev, + "MMU_SRAMA[%d] = %08x\n", + offset, val); + flush_cache_sec((uint8) offset); + break; + case MMU_SRAMB: + offset = offset & 3; + mmu_state.srb[offset] = val; + mmu_state.sec[offset].len = (val >> 10) & 0x1fff; + /* We do not flush the cache on writing SRAMB */ + sim_debug(WRITE_MSG, &mmu_dev, + "MMU_SRAMB[%d] = %08x (len=%06x)\n", + offset, val, mmu_state.sec[offset].len); + break; + case MMU_FC: + mmu_state.fcode = val; + break; + case MMU_FA: + mmu_state.faddr = val; + break; + case MMU_CONF: + mmu_state.conf = val & 0x7; + break; + case MMU_VAR: + mmu_state.var = val; + flush_sdce(val); + flush_pdce(val); + break; + } +} + +/* Helper functions for MMU decode. */ + +/* + * Get the Segment Descriptor for a virtual address on a cache miss. + * + * Returns SCPE_OK on success, SCPE_NXM on failure. + * + * If SCPE_NXM is returned, a failure code and fault address will be + * set in the appropriate registers. + * + * As always, the flag 'fc' may be set to FALSE to avoid certain + * typses of fault checking. + * + */ +t_stat mmu_get_sd(uint32 va, uint8 r_acc, t_bool fc, + uint32 *sd0, uint32 *sd1) +{ + /* We immediately do some bounds checking (fc flag is not checked + * because this is a fatal error) */ + if (SSL(va) > SRAMB_LEN(va)) { + MMU_FAULT(MMU_F_SDTLEN); + sim_debug(EXECUTE_MSG, &mmu_dev, + "SDT Length Fault. sramb_len=%x ssl=%x va=%08x\n", + SRAMB_LEN(va), SSL(va), va); + return SCPE_NXM; + } + + /* sd0 contains the segment descriptor, sd1 contains a pointer to + the PDT or Segment */ + *sd0 = pread_w(SD_ADDR(va), BUS_PER); + *sd1 = pread_w(SD_ADDR(va) + 4, BUS_PER); + + if (!SD_VALID(*sd0)) { + sim_debug(EXECUTE_MSG, &mmu_dev, + "Invalid Segment Descriptor. va=%08x sd0=%08x\n", + va, *sd0); + MMU_FAULT(MMU_F_INV_SD); + return SCPE_NXM; + } + + /* TODO: Handle indirect lookups. */ + if (SD_INDIRECT(*sd0)) { + stop_reason = STOP_MMU; + return SCPE_NXM; + } + + /* If the segment descriptor isn't present, we need to + * fail out */ + if (!SD_PRESENT(*sd0)) { + if (SD_CONTIG(*sd0)) { + sim_debug(EXECUTE_MSG, &mmu_dev, + "Segment Not Present. va=%08x", + va); + MMU_FAULT(MMU_F_SEG_NOT_PRES); + return SCPE_NXM; + } else { + sim_debug(EXECUTE_MSG, &mmu_dev, + "PDT Not Present. va=%08x", + va); + MMU_FAULT(MMU_F_PDT_NOT_PRES); + return SCPE_NXM; + } + } + + if (SHOULD_CACHE_SD(*sd0)) { + put_sdce(va, *sd0, *sd1); + } + + return SCPE_OK; +} + +/* + * Load a page descriptor from memory + */ +t_stat mmu_get_pd(uint32 va, uint8 r_acc, t_bool fc, + uint32 sd0, uint32 sd1, + uint32 *pd, uint8 *pd_acc) +{ + uint32 pd_addr; + + /* Where do we find the page descriptor? */ + pd_addr = SD_SEG_ADDR(sd1) + (PSL(va) * 4); + + /* Bounds checking on length */ + if ((PSL(va) * 4) >= MAX_OFFSET(sd0)) { + sim_debug(EXECUTE_MSG, &mmu_dev, + "PDT Length Fault. " + "PDT Offset=%08x Max Offset=%08x va=%08x\n", + (PSL(va) * 4), + MAX_OFFSET(sd0), va); + MMU_FAULT(MMU_F_PDTLEN); + return SCPE_NXM; + } + + *pd = pread_w(pd_addr, BUS_PER); + + /* Copy the access flags from the SD */ + *pd_acc = SD_ACC(sd0); + + /* Cache it */ + if (SHOULD_CACHE_PD(*pd)) { + put_pdce(va, sd0, *pd); + } + + return SCPE_OK; +} + +/* + * Decode an address from a contiguous segment. + */ +t_stat mmu_decode_contig(uint32 va, uint8 r_acc, + uint32 sd0, uint32 sd1, + t_bool fc, uint32 *pa) +{ + if (fc) { + /* Update R and M bits if configured */ + if (SHOULD_UPDATE_SD_R_BIT(sd0)) { + sim_debug(EXECUTE_MSG, &mmu_dev, + "Updating R bit in SD\n"); + mmu_update_sd(va, SD_R_MASK); + } + + if (SHOULD_UPDATE_SD_M_BIT(sd0)) { + sim_debug(EXECUTE_MSG, &mmu_dev, + "Updating M bit in SD\n"); + mmu_update_sd(va, SD_M_MASK); + } + + /* Generate object trap if needed */ + if (SD_TRAP(sd0)) { + sim_debug(EXECUTE_MSG, &mmu_dev, + "Object Trap. va=%08x", + va); + MMU_FAULT(MMU_F_OTRAP); + return SCPE_NXM; + } + } + + *pa = SD_SEG_ADDR(sd1) + SOT(va); + return SCPE_OK; +} + +t_stat mmu_decode_paged(uint32 va, uint8 r_acc, t_bool fc, + uint32 sd1, uint32 pd, + uint8 pd_acc, uint32 *pa) +{ + /* If the PD is not marked present, fail */ + if (!PD_PRESENT(pd)) { + sim_debug(EXECUTE_MSG, &mmu_dev, + "Page Not Present. " + "pd=%08x r_acc=%x va=%08x\n", + pd, r_acc, va); + MMU_FAULT(MMU_F_PAGE_NOT_PRES); + return SCPE_NXM; + } + + if (fc) { + /* If this is a write or interlocked read access, and + the 'W' bit is set, trigger a write fault */ + if ((r_acc == ACC_W || r_acc == ACC_IR) && PD_WFAULT(pd)) { + sim_debug(EXECUTE_MSG, &mmu_dev, + "Page Write Fault. va=%08x\n", + va); + MMU_FAULT(MMU_F_PW); + return SCPE_NXM; + } + + /* If this is a write, modify the M bit */ + if (SHOULD_UPDATE_PD_M_BIT(pd)) { + sim_debug(EXECUTE_MSG, &mmu_dev, + "Updating M bit in PD\n"); + mmu_update_pd(va, PD_LOC(sd1, va), PD_M_MASK); + } + + /* Modify the R bit and write it back */ + if (SHOULD_UPDATE_PD_R_BIT(pd)) { + sim_debug(EXECUTE_MSG, &mmu_dev, + "Updating R bit in PD\n"); + mmu_update_pd(va, PD_LOC(sd1, va), PD_R_MASK); + } + } + + *pa = PD_ADDR(pd) + POT(va); + return SCPE_OK; +} + +/* + * Translate a virtual address into a physical address. + * + * If "fc" is false, this function will bypass: + * + * - Access flag checks + * - Cache insertion + * - Setting MMU fault registers + * - Modifying segment and page descriptor bits + */ + +t_stat mmu_decode_va(uint32 va, uint8 r_acc, t_bool fc, uint32 *pa) +{ + uint32 sd0, sd1, pd; + uint8 pd_acc; + t_stat sd_cached, pd_cached; + + if (!mmu_state.enabled) { + *pa = va; + return SCPE_OK; + } + + /* We must check both caches first to determine what kind of miss + processing to do. */ + + sd_cached = get_sdce(va, &sd0, &sd1); + pd_cached = get_pdce(va, &pd, &pd_acc); + + if (sd_cached == SCPE_OK && pd_cached != SCPE_OK) { + if (SD_PAGED(sd0) && mmu_get_pd(va, r_acc, fc, sd0, sd1, &pd, &pd_acc) != SCPE_OK) { + sim_debug(EXECUTE_MSG, &mmu_dev, + "Could not get PD (partial miss). r_acc=%d, fc=%d, va=%08x\n", + r_acc, fc, va); + return SCPE_NXM; + } + } else if (sd_cached != SCPE_OK && pd_cached == SCPE_OK) { + if (mmu_get_sd(va, r_acc, fc, &sd0, &sd1) != SCPE_OK) { + sim_debug(EXECUTE_MSG, &mmu_dev, + "Could not get SD (partial miss). r_acc=%d, fc=%d, va=%08x\n", + r_acc, fc, va); + return SCPE_NXM; + } + } else if (sd_cached != SCPE_OK && pd_cached != SCPE_OK) { + if (mmu_get_sd(va, r_acc, fc, &sd0, &sd1) != SCPE_OK) { + sim_debug(EXECUTE_MSG, &mmu_dev, + "Could not get SD (full miss). r_acc=%d, fc=%d, va=%08x\n", + r_acc, fc, va); + return SCPE_NXM; + } + + if (SD_PAGED(sd0) && mmu_get_pd(va, r_acc, fc, sd0, sd1, &pd, &pd_acc) != SCPE_OK) { + sim_debug(EXECUTE_MSG, &mmu_dev, + "Could not get PD (full miss). r_acc=%d, fc=%d, va=%08x\n", + r_acc, fc, va); + return SCPE_NXM; + } + } + + if (SD_PAGED(sd0)) { + if (fc && mmu_check_perm(pd_acc, r_acc) != SCPE_OK) { + sim_debug(EXECUTE_MSG, &mmu_dev, + "PAGED: NO ACCESS TO MEMORY AT %08x.\n" + "\t\tcpu_cm=%d r_acc=%x pd_acc=%02x\n" + "\t\tpd=%08x psw=%08x\n", + va, CPU_CM, r_acc, pd_acc, + pd, R[NUM_PSW]); + MMU_FAULT(MMU_F_ACC); + return SCPE_NXM; + } + if (PD_LAST(pd) && (PSL_C(va) | POT(va)) >= MAX_OFFSET(sd0)) { + sim_debug(EXECUTE_MSG, &mmu_dev, + "PAGED: Segment Offset Fault.\n"); + MMU_FAULT(MMU_F_SEG_OFFSET); + return SCPE_NXM; + } + return mmu_decode_paged(va, r_acc, fc, sd1, pd, pd_acc, pa); + } else { + if (fc && mmu_check_perm(SD_ACC(sd0), r_acc) != SCPE_OK) { + sim_debug(EXECUTE_MSG, &mmu_dev, + "CONTIGUOUS: NO ACCESS TO MEMORY AT %08x.\n" + "\t\tsd0=%08x sd0_addr=%08x\n" + "\t\tcpu_cm=%d acc_req=%x sd_acc=%02x\n", + va, sd0, SD_ADDR(va), + CPU_CM, r_acc, SD_ACC(sd0)); + MMU_FAULT(MMU_F_ACC); + return SCPE_NXM; + } + if (SOT(va) >= MAX_OFFSET(sd0)) { + sim_debug(EXECUTE_MSG, &mmu_dev, + "CONTIGUOUS: Segment Offset Fault. " + "sd0=%08x sd_addr=%08x SOT=%08x len=%08x va=%08x\n", + sd0, SD_ADDR(va), SOT(va), + MAX_OFFSET(sd0), va); + MMU_FAULT(MMU_F_SEG_OFFSET); + return SCPE_NXM; + } + return mmu_decode_contig(va, r_acc, sd0, sd1, fc, pa); + } +} + +uint32 mmu_xlate_addr(uint32 va, uint8 r_acc) +{ + uint32 pa; + t_stat succ; + + succ = mmu_decode_va(va, r_acc, TRUE, &pa); + + if (succ == SCPE_OK) { + mmu_state.var = va; + return pa; + } else { + cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT); + return 0; + } +} + +void mmu_enable() +{ + sim_debug(EXECUTE_MSG, &mmu_dev, + "Enabling MMU.\n"); + mmu_state.enabled = TRUE; +} + +void mmu_disable() +{ + sim_debug(EXECUTE_MSG, &mmu_dev, + "Disabling MMU.\n"); + mmu_state.enabled = FALSE; +} + +CONST char *mmu_description(DEVICE *dptr) +{ + return "WE32101"; +} diff --git a/3B2/3b2_rev2_mmu.h b/3B2/3b2_rev2_mmu.h index 6090971e..af211f2f 100644 --- a/3B2/3b2_rev2_mmu.h +++ b/3B2/3b2_rev2_mmu.h @@ -1,383 +1,358 @@ -/* 3b2_rev2_mmu.c: AT&T 3B2 Rev 2 (Model 400) MMU (WE32101) Header - - Copyright (c) 2017, Seth J. Morabito - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - - Except as contained in this notice, the name of the author shall - not be used in advertising or otherwise to promote the sale, use or - other dealings in this Software without prior written authorization - from the author. -*/ - -#ifndef _3B2_REV2_MMU_H_ -#define _3B2_REV2_MMU_H_ - -#include "sim_defs.h" - -/************************************************************************ - * - * Vocabulary - * ---------- - * - * PD: Page Descriptor (in main memory) - * PDT: Page Descriptor Table (in main memory) - * POT: Page Offset. Bits 0-10 of a Paged virtual address. - * PSL: Page Select. Bits 11-16 of a Paged virtual address. - * SD: Segment Descriptor (in main memory) - * SDT: Segment Descriptor Table (in main memory) - * SID: Section ID. Bits 30-31 of all virtual addresses - * SOT: Segment Offset. Bits 0-16 of a Contiguous virtual address. - * SSL: Segment Select. Bits 17-29 of all virtual addresses. - * - * - * The WE32101 MMU divides the virtual address space into four - * Sections with 8K Segments per section. Virtual address bits 30 and - * 31 determine the section, bits 17-29 determine the Segment within - * the section. - * - * There are two kinds of address translation: Contiguous Translation - * and Paged Translation. Contiguous Translation just uses an offset - * (bits 0-16 of the virtual address) into each Segment to find an - * address, allowing for 128K bytes per Segment. Paged translation - * further break Segments down into 64 Pages of 2K each. - * - * Details about how to do translation are held in main memory in - * Segment Descriptors and Page Descriptors. These are located in - * Segment Descriptor Tables and Page Descriptor Tables set up by the - * computer before enabling the MMU. - * - * In addition to details in main memory, the MMU has a small cache - * of both Segment Descriptors and Page Descriptors. This is NOT just - * used for performance reasons! Various features of the cache, - * such as updating R and M bits in Segment and Page Descriptors, - * are used by various operating system features. - * - * - * Virtual Address Fields - * ---------------------- - * - * 31 30 29 17 16 0 - * +-----+-------------------+-----------------------------+ - * Contig: | SID | SSL | SOT | - * +-----+-------------------+-----------------------------+ - * - * 31 30 29 17 16 11 10 0 - * +-----+-------------------+---------+-------------------+ - * Paged: | SID | SSL | PSL | POT | - * +-----+-------------------+---------+-------------------+ - * - * - * Segment Descriptor Fields - * ------------------------- - * - * 31 24 23 10 9 8 7 6 5 4 3 2 1 0 - * +-------+---------+-----+---+---+---+---+---+---+---+---+ - * sd0: | Acc | Max Off | Res | I | V | R | T | $ | C | M | P | - * +-------+---------+-----+---+---+---+---+---+---+---+---+ - * - * +-----------------------------------------------+-------+ - * sd1: | Address (high-order 27 or 29 bits) | Soft | - * +-----------------------------------------------+-------+ - * - * - * Segment Descriptor Cache Entry - * ------------------------------ - * - * 31 24 23 10 9 0 - * +-------+-------------------------+---------------------+ - * Low: | Acc | Max Off | Tag | - * +-------+-------------------------+---------------------+ - * - * 31 5 4 3 2 1 0 - * +-----------------------------------+---+---+---+---+---+ - * High: | Address | T | $ | C | M | G | - * +-----------------------------------+---+---+---+---+---+ - * - * - * Page Descriptor Fields - * ---------------------- - * - * 31 11 10 8 7 6 5 4 3 2 1 0 - * +----------------+------+-----+---+---+-----+---+---+---+ - * | Page Address | Soft | Res | R | W | Res | L | M | P | - * +----------------+------+-----+---+---+-----+---+---+---+ - * - * - * Page Descriptor Cache Entry - * --------------------------- - * - * 31 24 23 16 15 0 - * +-----+------------------+------------------------------+ - * Low: | Acc | Res | Tag | - * +-----+------------------+------------------------------+ - * - * 31 11 10 7 6 5 4 3 2 1 0 - * +---------------------+-----+---+---+---+---+---+---+---+ - * High: | Address | Res | U | R | W | $ | L | M | G | - * +---------------------+-----+---+---+---+---+---+---+---+ - * - * "U" is only set in the left cache entry, and indicates - * which slot (left or right) was most recently updated. - * - ***********************************************************************/ - -#define MMUBASE 0x40000 -#define MMUSIZE 0x1000 - -#define MMU_SRS 0x04 /* Section RAM array size (words) */ -#define MMU_SDCS 0x20 /* Segment Descriptor Cache H/L array size - (words) */ -#define MMU_PDCS 0x20 /* Page Descriptor Cache H/L array size - (words) */ - -/* Register address offsets */ -#define MMU_SDCL 0 -#define MMU_SDCH 1 -#define MMU_PDCRL 2 -#define MMU_PDCRH 3 -#define MMU_PDCLL 4 -#define MMU_PDCLH 5 -#define MMU_SRAMA 6 -#define MMU_SRAMB 7 -#define MMU_FC 8 -#define MMU_FA 9 -#define MMU_CONF 10 -#define MMU_VAR 11 - -#define MMU_CONF_M (mmu_state.conf & 0x1) -#define MMU_CONF_R (mmu_state.conf & 0x2) - -/* Caching */ -#define NUM_SEC 4u /* Number of memory sections */ -#define NUM_SDCE 8 /* SD cache entries per section */ -#define NUM_PDCE 8 /* PD cache entries per section per side (l/r) */ -#define SET_SIZE 2 /* PDs are held in a 2-way associative set */ - -/* Cache Tag for SDs */ -#define SD_TAG(vaddr) ((vaddr >> 20) & 0x3ff) - -/* Cache Tag for PDs */ -#define PD_TAG(vaddr) (((vaddr >> 13) & 0xf) | ((vaddr >> 14) & 0xfff0)) - -/* Index of entry in the SD cache */ -#define SD_IDX(vaddr) ((vaddr >> 17) & 7) - -/* Index of entry in the PD cache */ -#define PD_IDX(vaddr) (((vaddr >> 11) & 3) | ((vaddr >> 15) & 4)) - -/* Shift and mask the flag bits for the current CPU mode */ -#define MMU_PERM(f) ((f >> ((3 - CPU_CM) * 2)) & 3) - -/* Codes set in the MMU Fault register */ -#define MMU_F_SDTLEN 0x03 -#define MMU_F_PW 0x04 -#define MMU_F_PDTLEN 0x05 -#define MMU_F_INV_SD 0x06 -#define MMU_F_SEG_NOT_PRES 0x07 -#define MMU_F_OTRAP 0x08 -#define MMU_F_PDT_NOT_PRES 0x09 -#define MMU_F_PAGE_NOT_PRES 0x0a -#define MMU_F_ACC 0x0d -#define MMU_F_SEG_OFFSET 0x0e - -/* Access Request types */ -#define ACC_MT 0 /* Move Translated */ -#define ACC_SPW 1 /* Support processor write */ -#define ACC_SPF 3 /* Support processor fetch */ -#define ACC_IR 7 /* Interlocked read */ -#define ACC_AF 8 /* Address fetch */ -#define ACC_OF 9 /* Operand fetch */ -#define ACC_W 10 /* Write */ -#define ACC_IFAD 12 /* Instruction fetch after discontinuity */ -#define ACC_IF 13 /* Instruction fetch */ - -/* Pluck out Virtual Address fields */ -#define SID(va) (((va) >> 30) & 3) -#define SSL(va) (((va) >> 17) & 0x1fff) -#define SOT(va) (va & 0x1ffff) -#define PSL(va) (((va) >> 11) & 0x3f) -#define PSL_C(va) ((va) & 0x1f800) -#define POT(va) (va & 0x7ff) - -/* Get the maximum length of an SSL from SRAMB */ -#define SRAMB_LEN(va) (mmu_state.sec[SID(va)].len + 1) - -/* Pluck out Segment Descriptor fields */ -#define SD_PRESENT(sd0) ((sd0) & 1) -#define SD_MODIFIED(sd0) (((sd0) >> 1) & 1) -#define SD_CONTIG(sd0) (((sd0) >> 2) & 1) -#define SD_PAGED(sd0) ((((sd0) >> 2) & 1) == 0) -#define SD_CACHE(sd0) (((sd0) >> 3) & 1) -#define SD_TRAP(sd0) (((sd0) >> 4) & 1) -#define SD_REF(sd0) (((sd0) >> 5) & 1) -#define SD_VALID(sd0) (((sd0) >> 6) & 1) -#define SD_INDIRECT(sd0) (((sd0) >> 7) & 1) -#define SD_SEG_ADDR(sd1) ((sd1) & 0xffffffe0) -#define SD_MAX_OFF(sd0) (((sd0) >> 10) & 0x3fff) -#define SD_ACC(sd0) (((sd0) >> 24) & 0xff) -#define SD_R_MASK 0x20 -#define SD_M_MASK 0x2 -#define SD_GOOD_MASK 0x1u -#define SDCE_TAG(sdcl) ((sdcl) & 0x3ff) - -#define SD_ADDR(va) (mmu_state.sec[SID(va)].addr + (SSL(va) * 8)) - - -/* Convert from sd to sd cache entry */ -#define SD_TO_SDCL(va,sd0) ((sd0 & 0xfffffc00)|SD_TAG(va)) -#define SD_TO_SDCH(sd0,sd1) (SD_SEG_ADDR(sd1)|(sd0 & 0x1e)|1) - -/* Note that this is a lossy transform. We will lose the state of the - I and R flags, as well as the software flags. We don't need them. - The V and P flags can be inferred as set. */ - -#define SDCE_TO_SD0(sdch,sdcl) ((sdcl & 0xfffffc00)|0x40|(sdch & 0x1e)|1) -#define SDCE_TO_SD1(sdch) (sdch & 0xffffffe0) - -/* Maximum size (in bytes) of a segment */ -#define MAX_OFFSET(sd0) ((SD_MAX_OFF(sd0) + 1) * 8) - -#define PD_PRESENT(pd) (pd & 1) -#define PD_MODIFIED(pd) ((pd >> 1) & 1) -#define PD_LAST(pd) ((pd >> 2) & 1) -#define PD_WFAULT(pd) ((pd >> 4) & 1) -#define PD_REF(pd) ((pd >> 5) & 1) -#define PD_ADDR(pd) (pd & 0xfffff800) /* Address portion of PD */ -#define PD_R_MASK 0x20 -#define PD_M_MASK 0x2 -#define PD_GOOD_MASK 0x1u -#define PDCLH_USED_MASK 0x40u -#define PDCXL_TAG(pdcxl) (pdcxl & 0xffff) - -#define PD_LOC(sd1,va) SD_SEG_ADDR(sd1) + (PSL(va) * 4) - -/* Page Descriptor Cache Entry - * - */ - -/* Convert from pd to pd cache entry. Alwasy sets "Good" bit. */ -#define SD_TO_PDCXL(va,sd0) ((sd0 & 0xff000000)|PD_TAG(va)) -#define PD_TO_PDCXH(pd,sd0) ((pd & 0xfffff836)|(sd0 & 0x8)|1) - -/* Always set 'present' to true on conversion */ -#define PDCXH_TO_PD(pdch) ((pdch & 0xfffff836)|1) -#define PDCXL_TO_ACC(pdcl) (((pdcl & 0xff000000) >> 24) & 0xff) - -/* Fault codes */ -#define MMU_FAULT(f) { \ - if (fc) { \ - mmu_state.fcode = ((((uint32)r_acc)<<7)| \ - (((uint32)(CPU_CM))<<5)|f); \ - mmu_state.faddr = va; \ - } \ - } - -typedef struct _mmu_sec { - uint32 addr; - uint32 len; -} mmu_sec; - -typedef struct _mmu_state { - t_bool enabled; /* Global enabled/disabled flag */ - - uint32 sdcl[MMU_SDCS]; /* SDC low bits (0-31) */ - uint32 sdch[MMU_SDCS]; /* SDC high bits (32-63) */ - - uint32 pdcll[MMU_PDCS]; /* PDC low bits (left) (0-31) */ - uint32 pdclh[MMU_PDCS]; /* PDC high bits (left) (32-63) */ - - uint32 pdcrl[MMU_PDCS]; /* PDC low bits (right) (0-31) */ - uint32 pdcrh[MMU_PDCS]; /* PDC high bits (right) (32-63) */ - - uint32 sra[MMU_SRS]; /* Section RAM A */ - uint32 srb[MMU_SRS]; /* Section RAM B */ - - mmu_sec sec[MMU_SRS]; /* Section descriptors decoded from - Section RAM A and B */ - - uint32 fcode; /* Fault Code Register */ - uint32 faddr; /* Fault Address Register */ - uint32 conf; /* Configuration Register */ - uint32 var; /* Virtual Address Register */ - -} MMU_STATE; - -t_stat mmu_init(DEVICE *dptr); -uint32 mmu_read(uint32 pa, size_t size); -void mmu_write(uint32 pa, uint32 val, size_t size); -CONST char *mmu_description(DEVICE *dptr); - -/* Physical memory read/write */ -uint8 pread_b(uint32 pa); -uint16 pread_h(uint32 pa); -uint32 pread_w(uint32 pa); -uint32 pread_w_u(uint32 pa); -void pwrite_b(uint32 pa, uint8 val); -void pwrite_h(uint32 pa, uint16 val); -void pwrite_w(uint32 pa, uint32 val); - -/* TODO: REMOVE AFTER DEBUGGING */ -uint32 safe_read_w(uint32 va); - -/* Virtual memory translation */ -uint32 mmu_xlate_addr(uint32 va, uint8 r_acc); -t_stat mmu_decode_vaddr(uint32 vaddr, uint8 r_acc, - t_bool fc, uint32 *pa); - -#define SHOULD_CACHE_PD(pd) \ - (fc && PD_PRESENT(pd)) - -#define SHOULD_CACHE_SD(sd) \ - (fc && SD_VALID(sd) && SD_PRESENT(sd)) - -#define SHOULD_UPDATE_SD_R_BIT(sd) \ - (MMU_CONF_R && !((sd) & SD_R_MASK)) - -#define SHOULD_UPDATE_SD_M_BIT(sd) \ - (MMU_CONF_M && r_acc == ACC_W && !((sd) & SD_M_MASK)) - -#define SHOULD_UPDATE_PD_R_BIT(pd) \ - (!((pd) & PD_R_MASK)) - -#define SHOULD_UPDATE_PD_M_BIT(pd) \ - (r_acc == ACC_W && !((pd) & PD_M_MASK)) - -/* Dispatch to the MMU when enabled, or to physical RW when - disabled */ -uint8 read_b(uint32 va, uint8 r_acc); -uint16 read_h(uint32 va, uint8 r_acc); -uint32 read_w(uint32 va, uint8 r_acc); -void write_b(uint32 va, uint8 val); -void write_h(uint32 va, uint16 val); -void write_w(uint32 va, uint32 val); - -t_bool addr_is_rom(uint32 pa); -t_bool addr_is_mem(uint32 pa); -t_bool addr_is_io(uint32 pa); - -t_stat mmu_decode_va(uint32 va, uint8 r_acc, t_bool fc, uint32 *pa); -void mmu_enable(); -void mmu_disable(); - -extern MMU_STATE mmu_state; - -#endif /* _3B2_REV2_MMU_H_ */ +/* 3b2_rev2_mmu.c: WE32101 MMU + + Copyright (c) 2017-2022, Seth J. Morabito + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + Except as contained in this notice, the name of the author shall + not be used in advertising or otherwise to promote the sale, use or + other dealings in this Software without prior written authorization + from the author. +*/ + +#ifndef _3B2_REV2_MMU_H_ +#define _3B2_REV2_MMU_H_ + +#include "sim_defs.h" + +/************************************************************************ + * + * Vocabulary + * ---------- + * + * PD: Page Descriptor (in main memory) + * PDT: Page Descriptor Table (in main memory) + * POT: Page Offset. Bits 0-10 of a Paged virtual address. + * PSL: Page Select. Bits 11-16 of a Paged virtual address. + * SD: Segment Descriptor (in main memory) + * SDT: Segment Descriptor Table (in main memory) + * SID: Section ID. Bits 30-31 of all virtual addresses + * SOT: Segment Offset. Bits 0-16 of a Contiguous virtual address. + * SSL: Segment Select. Bits 17-29 of all virtual addresses. + * + * + * The WE32101 MMU divides the virtual address space into four + * Sections with 8K Segments per section. Virtual address bits 30 and + * 31 determine the section, bits 17-29 determine the Segment within + * the section. + * + * There are two kinds of address translation: Contiguous Translation + * and Paged Translation. Contiguous Translation just uses an offset + * (bits 0-16 of the virtual address) into each Segment to find an + * address, allowing for 128K bytes per Segment. Paged translation + * further break Segments down into 64 Pages of 2K each. + * + * Details about how to do translation are held in main memory in + * Segment Descriptors and Page Descriptors. These are located in + * Segment Descriptor Tables and Page Descriptor Tables set up by the + * computer before enabling the MMU. + * + * In addition to details in main memory, the MMU has a small cache + * of both Segment Descriptors and Page Descriptors. This is NOT just + * used for performance reasons! Various features of the cache, + * such as updating R and M bits in Segment and Page Descriptors, + * are used by various operating system features. + * + * + * Virtual Address Fields + * ---------------------- + * + * 31 30 29 17 16 0 + * +-----+-------------------+-----------------------------+ + * Contig: | SID | SSL | SOT | + * +-----+-------------------+-----------------------------+ + * + * 31 30 29 17 16 11 10 0 + * +-----+-------------------+---------+-------------------+ + * Paged: | SID | SSL | PSL | POT | + * +-----+-------------------+---------+-------------------+ + * + * + * Segment Descriptor Fields + * ------------------------- + * + * 31 24 23 10 9 8 7 6 5 4 3 2 1 0 + * +-------+---------+-----+---+---+---+---+---+---+---+---+ + * sd0: | Acc | Max Off | Res | I | V | R | T | $ | C | M | P | + * +-------+---------+-----+---+---+---+---+---+---+---+---+ + * + * +-----------------------------------------------+-------+ + * sd1: | Address (high-order 27 or 29 bits) | Soft | + * +-----------------------------------------------+-------+ + * + * + * Segment Descriptor Cache Entry + * ------------------------------ + * + * 31 24 23 10 9 0 + * +-------+-------------------------+---------------------+ + * Low: | Acc | Max Off | Tag | + * +-------+-------------------------+---------------------+ + * + * 31 5 4 3 2 1 0 + * +-----------------------------------+---+---+---+---+---+ + * High: | Address | T | $ | C | M | G | + * +-----------------------------------+---+---+---+---+---+ + * + * + * Page Descriptor Fields + * ---------------------- + * + * 31 11 10 8 7 6 5 4 3 2 1 0 + * +----------------+------+-----+---+---+-----+---+---+---+ + * | Page Address | Soft | Res | R | W | Res | L | M | P | + * +----------------+------+-----+---+---+-----+---+---+---+ + * + * + * Page Descriptor Cache Entry + * --------------------------- + * + * 31 24 23 16 15 0 + * +-----+------------------+------------------------------+ + * Low: | Acc | Res | Tag | + * +-----+------------------+------------------------------+ + * + * 31 11 10 7 6 5 4 3 2 1 0 + * +---------------------+-----+---+---+---+---+---+---+---+ + * High: | Address | Res | U | R | W | $ | L | M | G | + * +---------------------+-----+---+---+---+---+---+---+---+ + * + * "U" is only set in the left cache entry, and indicates + * which slot (left or right) was most recently updated. + * + ***********************************************************************/ + +#define MMUBASE 0x40000 +#define MMUSIZE 0x1000 + +#define MMU_SRS 0x04 /* Section RAM array size (words) */ +#define MMU_SDCS 0x20 /* Segment Descriptor Cache H/L array size + (words) */ +#define MMU_PDCS 0x20 /* Page Descriptor Cache H/L array size + (words) */ + +/* Register address offsets */ +#define MMU_SDCL 0 +#define MMU_SDCH 1 +#define MMU_PDCRL 2 +#define MMU_PDCRH 3 +#define MMU_PDCLL 4 +#define MMU_PDCLH 5 +#define MMU_SRAMA 6 +#define MMU_SRAMB 7 +#define MMU_FC 8 +#define MMU_FA 9 +#define MMU_CONF 10 +#define MMU_VAR 11 + +#define MMU_CONF_M (mmu_state.conf & 0x1) +#define MMU_CONF_R (mmu_state.conf & 0x2) + +/* Caching */ +#define NUM_SEC 4u /* Number of memory sections */ +#define NUM_SDCE 8 /* SD cache entries per section */ +#define NUM_PDCE 8 /* PD cache entries per section per side (l/r) */ +#define SET_SIZE 2 /* PDs are held in a 2-way associative set */ + +/* Cache Tag for SDs */ +#define SD_TAG(vaddr) ((vaddr >> 20) & 0x3ff) + +/* Cache Tag for PDs */ +#define PD_TAG(vaddr) (((vaddr >> 13) & 0xf) | ((vaddr >> 14) & 0xfff0)) + +/* Index of entry in the SD cache */ +#define SD_IDX(vaddr) ((vaddr >> 17) & 7) + +/* Index of entry in the PD cache */ +#define PD_IDX(vaddr) (((vaddr >> 11) & 3) | ((vaddr >> 15) & 4)) + +/* Shift and mask the flag bits for the current CPU mode */ +#define MMU_PERM(f) ((f >> ((3 - CPU_CM) * 2)) & 3) + +/* Codes set in the MMU Fault register */ +#define MMU_F_SDTLEN 0x03 +#define MMU_F_PW 0x04 +#define MMU_F_PDTLEN 0x05 +#define MMU_F_INV_SD 0x06 +#define MMU_F_SEG_NOT_PRES 0x07 +#define MMU_F_OTRAP 0x08 +#define MMU_F_PDT_NOT_PRES 0x09 +#define MMU_F_PAGE_NOT_PRES 0x0a +#define MMU_F_ACC 0x0d +#define MMU_F_SEG_OFFSET 0x0e + +/* Access Request types */ +#define ACC_MT 0 /* Move Translated */ +#define ACC_SPW 1 /* Support processor write */ +#define ACC_SPF 3 /* Support processor fetch */ +#define ACC_IR 7 /* Interlocked read */ +#define ACC_AF 8 /* Address fetch */ +#define ACC_OF 9 /* Operand fetch */ +#define ACC_W 10 /* Write */ +#define ACC_IFAD 12 /* Instruction fetch after discontinuity */ +#define ACC_IF 13 /* Instruction fetch */ + +/* Pluck out Virtual Address fields */ +#define SID(va) (((va) >> 30) & 3) +#define SSL(va) (((va) >> 17) & 0x1fff) +#define SOT(va) (va & 0x1ffff) +#define PSL(va) (((va) >> 11) & 0x3f) +#define PSL_C(va) ((va) & 0x1f800) +#define POT(va) (va & 0x7ff) + +/* Get the maximum length of an SSL from SRAMB */ +#define SRAMB_LEN(va) (mmu_state.sec[SID(va)].len + 1) + +/* Pluck out Segment Descriptor fields */ +#define SD_PRESENT(sd0) ((sd0) & 1) +#define SD_MODIFIED(sd0) (((sd0) >> 1) & 1) +#define SD_CONTIG(sd0) (((sd0) >> 2) & 1) +#define SD_PAGED(sd0) ((((sd0) >> 2) & 1) == 0) +#define SD_CACHE(sd0) (((sd0) >> 3) & 1) +#define SD_TRAP(sd0) (((sd0) >> 4) & 1) +#define SD_REF(sd0) (((sd0) >> 5) & 1) +#define SD_VALID(sd0) (((sd0) >> 6) & 1) +#define SD_INDIRECT(sd0) (((sd0) >> 7) & 1) +#define SD_SEG_ADDR(sd1) ((sd1) & 0xffffffe0) +#define SD_MAX_OFF(sd0) (((sd0) >> 10) & 0x3fff) +#define SD_ACC(sd0) (((sd0) >> 24) & 0xff) +#define SD_R_MASK 0x20 +#define SD_M_MASK 0x2 +#define SD_GOOD_MASK 0x1u +#define SDCE_TAG(sdcl) ((sdcl) & 0x3ff) + +#define SD_ADDR(va) (mmu_state.sec[SID(va)].addr + (SSL(va) * 8)) + + +/* Convert from sd to sd cache entry */ +#define SD_TO_SDCL(va,sd0) ((sd0 & 0xfffffc00)|SD_TAG(va)) +#define SD_TO_SDCH(sd0,sd1) (SD_SEG_ADDR(sd1)|(sd0 & 0x1e)|1) + +/* Note that this is a lossy transform. We will lose the state of the + I and R flags, as well as the software flags. We don't need them. + The V and P flags can be inferred as set. */ + +#define SDCE_TO_SD0(sdch,sdcl) ((sdcl & 0xfffffc00)|0x40|(sdch & 0x1e)|1) +#define SDCE_TO_SD1(sdch) (sdch & 0xffffffe0) + +/* Maximum size (in bytes) of a segment */ +#define MAX_OFFSET(sd0) ((SD_MAX_OFF(sd0) + 1) * 8) + +#define PD_PRESENT(pd) (pd & 1) +#define PD_MODIFIED(pd) ((pd >> 1) & 1) +#define PD_LAST(pd) ((pd >> 2) & 1) +#define PD_WFAULT(pd) ((pd >> 4) & 1) +#define PD_REF(pd) ((pd >> 5) & 1) +#define PD_ADDR(pd) (pd & 0xfffff800) /* Address portion of PD */ +#define PD_R_MASK 0x20 +#define PD_M_MASK 0x2 +#define PD_GOOD_MASK 0x1u +#define PDCLH_USED_MASK 0x40u +#define PDCXL_TAG(pdcxl) (pdcxl & 0xffff) + +#define PD_LOC(sd1,va) SD_SEG_ADDR(sd1) + (PSL(va) * 4) + +/* Page Descriptor Cache Entry + * + */ + +/* Convert from pd to pd cache entry. Alwasy sets "Good" bit. */ +#define SD_TO_PDCXL(va,sd0) ((sd0 & 0xff000000)|PD_TAG(va)) +#define PD_TO_PDCXH(pd,sd0) ((pd & 0xfffff836)|(sd0 & 0x8)|1) + +/* Always set 'present' to true on conversion */ +#define PDCXH_TO_PD(pdch) ((pdch & 0xfffff836)|1) +#define PDCXL_TO_ACC(pdcl) (((pdcl & 0xff000000) >> 24) & 0xff) + +/* Fault codes */ +#define MMU_FAULT(f) { \ + if (fc) { \ + mmu_state.fcode = ((((uint32)r_acc)<<7)| \ + (((uint32)(CPU_CM))<<5)|f); \ + mmu_state.faddr = va; \ + } \ + } + +typedef struct _mmu_sec { + uint32 addr; + uint32 len; +} mmu_sec; + +typedef struct _mmu_state { + t_bool enabled; /* Global enabled/disabled flag */ + + uint32 sdcl[MMU_SDCS]; /* SDC low bits (0-31) */ + uint32 sdch[MMU_SDCS]; /* SDC high bits (32-63) */ + + uint32 pdcll[MMU_PDCS]; /* PDC low bits (left) (0-31) */ + uint32 pdclh[MMU_PDCS]; /* PDC high bits (left) (32-63) */ + + uint32 pdcrl[MMU_PDCS]; /* PDC low bits (right) (0-31) */ + uint32 pdcrh[MMU_PDCS]; /* PDC high bits (right) (32-63) */ + + uint32 sra[MMU_SRS]; /* Section RAM A */ + uint32 srb[MMU_SRS]; /* Section RAM B */ + + mmu_sec sec[MMU_SRS]; /* Section descriptors decoded from + Section RAM A and B */ + + uint32 fcode; /* Fault Code Register */ + uint32 faddr; /* Fault Address Register */ + uint32 conf; /* Configuration Register */ + uint32 var; /* Virtual Address Register */ + +} MMU_STATE; + +t_stat mmu_init(DEVICE *dptr); +uint32 mmu_read(uint32 pa, size_t size); +void mmu_write(uint32 pa, uint32 val, size_t size); +CONST char *mmu_description(DEVICE *dptr); + +/* Virtual memory translation */ +uint32 mmu_xlate_addr(uint32 va, uint8 r_acc); +t_stat mmu_decode_vaddr(uint32 vaddr, uint8 r_acc, + t_bool fc, uint32 *pa); + +#define SHOULD_CACHE_PD(pd) \ + (fc && PD_PRESENT(pd)) + +#define SHOULD_CACHE_SD(sd) \ + (fc && SD_VALID(sd) && SD_PRESENT(sd)) + +#define SHOULD_UPDATE_SD_R_BIT(sd) \ + (MMU_CONF_R && !((sd) & SD_R_MASK)) + +#define SHOULD_UPDATE_SD_M_BIT(sd) \ + (MMU_CONF_M && r_acc == ACC_W && !((sd) & SD_M_MASK)) + +#define SHOULD_UPDATE_PD_R_BIT(pd) \ + (!((pd) & PD_R_MASK)) + +#define SHOULD_UPDATE_PD_M_BIT(pd) \ + (r_acc == ACC_W && !((pd) & PD_M_MASK)) + +t_stat mmu_decode_va(uint32 va, uint8 r_acc, t_bool fc, uint32 *pa); +void mmu_enable(); +void mmu_disable(); + +extern MMU_STATE mmu_state; + +#endif /* _3B2_REV2_MMU_H_ */ diff --git a/3B2/3b2_rev2_sys.c b/3B2/3b2_rev2_sys.c index f869f4ec..5a5d7428 100644 --- a/3B2/3b2_rev2_sys.c +++ b/3B2/3b2_rev2_sys.c @@ -1,82 +1,82 @@ -/* 3b2_rev2_sys.c: AT&T 3B2 Rev 2 (Model 400) system definition - - Copyright (c) 2017, Seth J. Morabito - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - - Except as contained in this notice, the name of the author shall - not be used in advertising or otherwise to promote the sale, use or - other dealings in this Software without prior written authorization - from the author. -*/ - -#include "3b2_defs.h" - -#include "3b2_cpu.h" -#include "3b2_csr.h" -#include "3b2_ctc.h" -#include "3b2_id.h" -#include "3b2_if.h" -#include "3b2_iu.h" -#include "3b2_ni.h" -#include "3b2_ports.h" -#include "3b2_mau.h" -#include "3b2_stddev.h" -#include "3b2_timer.h" - -char sim_name[] = "AT&T 3B2/400"; - -DEVICE *sim_devices[] = { - &cpu_dev, - &mmu_dev, - &mau_dev, - &timer_dev, - &tod_dev, - &nvram_dev, - &csr_dev, - &tti_dev, - &tto_dev, - &contty_dev, - &iu_timer_dev, - &dmac_dev, - &if_dev, - &id_dev, - &ports_dev, - &ctc_dev, - &ni_dev, - NULL -}; - -void full_reset() -{ - cpu_reset(&cpu_dev); - mau_reset(&mau_dev); - tti_reset(&tti_dev); - contty_reset(&contty_dev); - iu_timer_reset(&iu_timer_dev); - timer_reset(&timer_dev); - if_reset(&if_dev); - id_reset(&id_dev); - csr_reset(&csr_dev); - ports_reset(&ports_dev); - ctc_reset(&ctc_dev); - ni_reset(&ni_dev); -} +/* 3b2_rev2_sys.c: Version 2 (3B2/400) System Definition + + Copyright (c) 2017-2022, Seth J. Morabito + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + Except as contained in this notice, the name of the author shall + not be used in advertising or otherwise to promote the sale, use or + other dealings in this Software without prior written authorization + from the author. +*/ + +#include "3b2_defs.h" + +#include "3b2_cpu.h" +#include "3b2_csr.h" +#include "3b2_ctc.h" +#include "3b2_id.h" +#include "3b2_if.h" +#include "3b2_iu.h" +#include "3b2_ni.h" +#include "3b2_ports.h" +#include "3b2_mau.h" +#include "3b2_stddev.h" +#include "3b2_timer.h" + +char sim_name[] = "AT&T 3B2/400"; + +DEVICE *sim_devices[] = { + &cpu_dev, + &mmu_dev, + &mau_dev, + &timer_dev, + &tod_dev, + &nvram_dev, + &csr_dev, + &tti_dev, + &tto_dev, + &contty_dev, + &iu_timer_dev, + &dmac_dev, + &if_dev, + &id_dev, + &ports_dev, + &ctc_dev, + &ni_dev, + NULL +}; + +void full_reset() +{ + cpu_reset(&cpu_dev); + mau_reset(&mau_dev); + tti_reset(&tti_dev); + contty_reset(&contty_dev); + iu_timer_reset(&iu_timer_dev); + timer_reset(&timer_dev); + if_reset(&if_dev); + id_reset(&id_dev); + csr_reset(&csr_dev); + ports_reset(&ports_dev); + ctc_reset(&ctc_dev); + ni_reset(&ni_dev); +} diff --git a/3B2/3b2_rev2_timer.c b/3B2/3b2_rev2_timer.c deleted file mode 100644 index 77c7363f..00000000 --- a/3B2/3b2_rev2_timer.c +++ /dev/null @@ -1,401 +0,0 @@ -/* 3b2_rev2_timer.c: 8253 Interval Timer - - Copyright (c) 2017, Seth J. Morabito - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - - Except as contained in this notice, the name of the author shall - not be used in advertising or otherwise to promote the sale, use or - other dealings in this Software without prior written authorization - from the author. -*/ - -/* - * 8253 Timer. - * - * The 8253 Timer IC has three interval timers, which we treat here as - * three units. - * - * Note that this simulation is very specific to the 3B2, and not - * usable as a general purpose 8253 simulator. - * - */ - -#include "3b2_cpu.h" -#include "3b2_csr.h" -#include "3b2_defs.h" -#include "3b2_timer.h" - -#define SET_INT do { \ - CPU_SET_INT(INT_CLOCK); \ - SET_CSR(CSRCLK); \ - } while (0) - -#define CLR_INT do { \ - CPU_CLR_INT(INT_CLOCK); \ - CLR_CSR(CSRCLK); \ - } while (0) - -struct timer_ctr TIMERS[3]; - -int32 tmxr_poll = 16667; - -/* - * The three timers, (A, B, C) run at different - * programmatially controlled frequencies, so each must be - * handled through a different service routine. - */ - -UNIT timer_unit[] = { - { UDATA(&timer0_svc, 0, 0) }, - { UDATA(&timer1_svc, UNIT_IDLE, 0) }, - { UDATA(&timer2_svc, 0, 0) }, - { NULL } -}; - -UNIT *timer_clk_unit = &timer_unit[1]; - -REG timer_reg[] = { - { HRDATAD(DIVA, TIMERS[0].divider, 16, "Divider A") }, - { HRDATAD(STA, TIMERS[0].mode, 8, "Mode A") }, - { HRDATAD(DIVB, TIMERS[1].divider, 16, "Divider B") }, - { HRDATAD(STB, TIMERS[1].mode, 8, "Mode B") }, - { HRDATAD(DIVC, TIMERS[2].divider, 16, "Divider C") }, - { HRDATAD(STC, TIMERS[2].mode, 8, "Mode C") }, - { NULL } -}; - -MTAB timer_mod[] = { - { MTAB_XTD|MTAB_VDV|MTAB_VALR|MTAB_NC, 0, NULL, "SHUTDOWN", - &timer_set_shutdown, NULL, NULL, "Soft Power Shutdown" }, - { 0 } -}; - -DEVICE timer_dev = { - "TIMER", timer_unit, timer_reg, timer_mod, - 1, 16, 8, 4, 16, 32, - NULL, NULL, &timer_reset, - NULL, NULL, NULL, NULL, - DEV_DEBUG, 0, sys_deb_tab -}; - -t_stat timer_reset(DEVICE *dptr) { - int32 i, t; - - memset(&TIMERS, 0, sizeof(struct timer_ctr) * 3); - - for (i = 0; i < 3; i++) { - timer_unit[i].tmrnum = i; - timer_unit[i].tmr = (void *)&TIMERS[i]; - } - - /* Timer 1 gate is always active */ - TIMERS[1].gate = 1; - - if (!sim_is_running) { - t = sim_rtcn_init_unit(timer_clk_unit, TPS_CLK, TMR_CLK); - sim_activate_after(timer_clk_unit, 1000000 / t); - } - - return SCPE_OK; -} - -static void timer_activate(uint8 ctrnum) -{ - struct timer_ctr *ctr; - - ctr = &TIMERS[ctrnum]; - - switch (ctrnum) { - case TIMER_SANITY: - break; - case TIMER_INTERVAL: - if ((csr_data & CSRITIM) == 0) { - sim_debug(EXECUTE_MSG, &timer_dev, - "[%08x] INTERVAL TIMER: Activating after %d ms\n", - R[NUM_PC], ctr->val); - sim_activate_after_abs(&timer_unit[ctrnum], ctr->val); - ctr->val--; - } else { - sim_debug(EXECUTE_MSG, &timer_dev, - "[%08x] INTERVAL TIMER: Currently disabled, not starting\n", - R[NUM_PC]); - } - break; - case TIMER_BUS: - break; - default: - break; - } -} - -t_stat timer_set_shutdown(UNIT *uptr, int32 val, CONST char* cptr, void* desc) -{ - struct timer_ctr *sanity = (struct timer_ctr *)timer_unit[0].tmr; - - sim_debug(EXECUTE_MSG, &timer_dev, - "[%08x] Setting sanity timer to 0 for shutdown.\n", R[NUM_PC]); - - sanity->val = 0; - - CLR_INT; - - CPU_SET_INT(INT_SERR); - CSRBIT(CSRTIMO, TRUE); - - return SCPE_OK; -} - -void timer_enable(uint8 ctrnum) { - timer_activate(ctrnum); -} - -void timer_disable(uint8 ctrnum) -{ - sim_debug(EXECUTE_MSG, &timer_dev, - "[%08x] Disabling timer %d\n", - R[NUM_PC], ctrnum); - sim_cancel(&timer_unit[ctrnum]); -} - -/* - * Sanity Timer - */ -t_stat timer0_svc(UNIT *uptr) -{ - struct timer_ctr *ctr; - int32 time; - - ctr = (struct timer_ctr *)uptr->tmr; - - time = ctr->divider * TIMER_STP_US; - - if (time == 0) { - time = TIMER_STP_US; - } - - sim_activate_after_abs(uptr, time); - - return SCPE_OK; -} - -/* - * Interval Timer - */ -t_stat timer1_svc(UNIT *uptr) -{ - struct timer_ctr *ctr; - int32 t; - - ctr = (struct timer_ctr *)uptr->tmr; - - if (ctr->enabled && !(csr_data & CSRITIM)) { - /* Fire the IPL 15 clock interrupt */ - SET_INT; - } - - t = sim_rtcn_calb(TPS_CLK, TMR_CLK); - sim_activate_after_abs(uptr, 1000000/TPS_CLK); - tmxr_poll = t; - - return SCPE_OK; -} - -/* - * Bus Timeout Timer - */ -t_stat timer2_svc(UNIT *uptr) -{ - struct timer_ctr *ctr; - int32 time; - - ctr = (struct timer_ctr *)uptr->tmr; - - time = ctr->divider * TIMER_STP_US; - - if (time == 0) { - time = TIMER_STP_US; - } - - sim_activate_after_abs(uptr, time); - - return SCPE_OK; -} - -uint32 timer_read(uint32 pa, size_t size) -{ - uint32 reg; - uint16 ctr_val; - uint8 ctrnum; - struct timer_ctr *ctr; - - reg = pa - TIMERBASE; - ctrnum = (reg >> 2) & 0x3; - ctr = &TIMERS[ctrnum]; - - switch (reg) { - case TIMER_REG_DIVA: - case TIMER_REG_DIVB: - case TIMER_REG_DIVC: - ctr_val = ctr->val; - - if (ctr_val != ctr->divider) { - sim_debug(READ_MSG, &timer_dev, - "[%08x] >>> ctr_val = %04x, ctr->divider = %04x\n", - R[NUM_PC], ctr_val, ctr->divider); - } - - switch (ctr->mode & CLK_RW) { - case CLK_LSB: - return ctr_val & 0xff; - case CLK_MSB: - return (ctr_val & 0xff00) >> 8; - case CLK_LMB: - if (ctr->lmb) { - ctr->lmb = FALSE; - return (ctr_val & 0xff00) >> 8; - } else { - ctr->lmb = TRUE; - return ctr_val & 0xff; - } - default: - return 0; - } - break; - case TIMER_REG_CTRL: - return ctr->mode; - case TIMER_CLR_LATCH: - /* Clearing the timer latch has a side-effect - of also clearing pending interrupts */ - CLR_INT; - return 0; - default: - /* Unhandled */ - sim_debug(READ_MSG, &timer_dev, - "[%08x] UNHANDLED TIMER READ. ADDR=%08x\n", - R[NUM_PC], pa); - return 0; - } -} - -void handle_timer_write(uint8 ctrnum, uint32 val) -{ - struct timer_ctr *ctr; - - ctr = &TIMERS[ctrnum]; - switch(ctr->mode & 0x30) { - case 0x10: - ctr->divider &= 0xff00; - ctr->divider |= val & 0xff; - ctr->val = ctr->divider; - ctr->enabled = TRUE; - ctr->stime = sim_gtime(); - sim_cancel(timer_clk_unit); - sim_activate_after_abs(timer_clk_unit, ctr->divider * TIMER_STP_US); - break; - case 0x20: - ctr->divider &= 0x00ff; - ctr->divider |= (val & 0xff) << 8; - ctr->val = ctr->divider; - ctr->enabled = TRUE; - ctr->stime = sim_gtime(); - /* Kick the timer to get the new divider value */ - sim_cancel(timer_clk_unit); - sim_activate_after_abs(timer_clk_unit, ctr->divider * TIMER_STP_US); - break; - case 0x30: - if (ctr->lmb) { - ctr->lmb = FALSE; - ctr->divider = (uint16) ((ctr->divider & 0x00ff) | ((val & 0xff) << 8)); - ctr->val = ctr->divider; - ctr->enabled = TRUE; - ctr->stime = sim_gtime(); - sim_debug(READ_MSG, &timer_dev, - "[%08x] Write timer %d val LMB (MSB): %02x\n", - R[NUM_PC], ctrnum, val & 0xff); - /* Kick the timer to get the new divider value */ - sim_cancel(timer_clk_unit); - sim_activate_after_abs(timer_clk_unit, ctr->divider * TIMER_STP_US); - } else { - ctr->lmb = TRUE; - ctr->divider = (ctr->divider & 0xff00) | (val & 0xff); - ctr->val = ctr->divider; - } - break; - default: - break; - - } -} - -void timer_write(uint32 pa, uint32 val, size_t size) -{ - uint8 reg, ctrnum; - struct timer_ctr *ctr; - - reg = (uint8) (pa - TIMERBASE); - - switch(reg) { - case TIMER_REG_DIVA: - handle_timer_write(0, val); - break; - case TIMER_REG_DIVB: - handle_timer_write(1, val); - break; - case TIMER_REG_DIVC: - handle_timer_write(2, val); - break; - case TIMER_REG_CTRL: - /* The counter number is in bits 6 and 7 */ - ctrnum = (val >> 6) & 3; - if (ctrnum > 2) { - sim_debug(WRITE_MSG, &timer_dev, - "[%08x] WARNING: Write to invalid counter: %d\n", - R[NUM_PC], ctrnum); - return; - } - ctr = &TIMERS[ctrnum]; - ctr->mode = (uint8) val; - ctr->enabled = FALSE; - ctr->lmb = FALSE; - break; - case TIMER_CLR_LATCH: - sim_debug(WRITE_MSG, &timer_dev, - "[%08x] unexpected write to clear timer latch\n", - R[NUM_PC]); - break; - } -} - -void timer_tick() -{ - if (TIMERS[0].gate && TIMERS[0].enabled) { - TIMERS[0].val = TIMERS[0].divider - 1; - } - - if (TIMERS[1].gate && TIMERS[1].enabled) { - TIMERS[1].val = TIMERS[1].divider - 1; - } - - if (TIMERS[2].gate && TIMERS[2].enabled) { - TIMERS[2].val = TIMERS[2].divider - 1; - } -} diff --git a/3B2/3b2_rev2_timer.h b/3B2/3b2_rev2_timer.h deleted file mode 100644 index d30c0202..00000000 --- a/3B2/3b2_rev2_timer.h +++ /dev/null @@ -1,72 +0,0 @@ -/* 3b2_rev2_timer.h: 8253 Interval Timer - - Copyright (c) 2017, Seth J. Morabito - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - - Except as contained in this notice, the name of the author shall - not be used in advertising or otherwise to promote the sale, use or - other dealings in this Software without prior written authorization - from the author. -*/ - -#ifndef _3B2_REV2_TIMER_H_ -#define _3B2_REV2_TIMER_H_ - -#include "sim_defs.h" - -#define TIMER_STP_US 1 -#define tmrnum u3 -#define tmr up7 - -#define TIMER_REG_DIVA 0x03 -#define TIMER_REG_DIVB 0x07 -#define TIMER_REG_DIVC 0x0b -#define TIMER_REG_CTRL 0x0f -#define TIMER_CLR_LATCH 0x13 - -#define CLK_RW 0x30 -#define CLK_LSB 0x10 -#define CLK_MSB 0x20 -#define CLK_LMB 0x30 - -struct timer_ctr { - uint16 divider; - uint16 val; - uint8 mode; - t_bool lmb; - t_bool enabled; - t_bool gate; - double stime; /* Most recent start time of counter */ -}; - -t_stat timer_reset(DEVICE *dptr); -uint32 timer_read(uint32 pa, size_t size); -void timer_write(uint32 pa, uint32 val, size_t size); -void timer_tick(); -t_stat timer0_svc(UNIT *uptr); -t_stat timer1_svc(UNIT *uptr); -t_stat timer2_svc(UNIT *uptr); -t_stat timer_set_shutdown(UNIT *uptr, int32 val, CONST char *cptr, void *desc); -void timer_disable(uint8 ctrnum); -void timer_enable(uint8 ctrnum); - -#endif /* _3B2_REV2_TIMER_H_ */ diff --git a/3B2/3b2_rev3_csr.c b/3B2/3b2_rev3_csr.c index 3b6afe57..06403b47 100644 --- a/3B2/3b2_rev3_csr.c +++ b/3B2/3b2_rev3_csr.c @@ -1,299 +1,293 @@ -/* 3b2_rev3_csr.c: AT&T 3B2/600G Control and Status Register - - Copyright (c) 2020, Seth J. Morabito - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - - Except as contained in this notice, the name of the author shall - not be used in advertising or otherwise to promote the sale, use or - other dealings in this Software without prior written authorization - from the author. -*/ - -#include "3b2_cpu.h" -#include "3b2_csr.h" -#include "3b2_if.h" -#include "3b2_timer.h" - -uint32 csr_data; - -BITFIELD csr_bits[] = { - BIT(UTIM), - BIT(PWDN), - BIT(OI15), - BIT(IUINT), - BIT(IUDMA), - BIT(PIR9), - BIT(PIR8), - BIT(IUTIM), - - BIT(ISTY), - BIT(IUBUS), - BIT(IFLT), - BIT(ISBER), - BIT(IBUS), - BIT(IBUB), - BIT(FECC), - BIT(THERM), - - BIT(FLED), - BIT(PSPWR), - BIT(FLSPD), - BIT(FLSD1), - BIT(FLMOT), - BIT(FLDEN), - BIT(FLSZ), - BIT(SBER), - - BIT(MBER), - BIT(UBFL), - BIT(TIMO), - BIT(FLTFR), - BIT(DALGN), - BIT(STTIM), - BIT(ABRT), - BIT(RSTR), - - ENDBITS -}; - -UNIT csr_unit = { - UDATA(NULL, UNIT_FIX, CSRSIZE) -}; - -REG csr_reg[] = { - { HRDATADF(DATA, csr_data, 32, "CSR Data", csr_bits) }, - { NULL } -}; - -DEVICE csr_dev = { - "CSR", &csr_unit, csr_reg, NULL, - 1, 16, 8, 4, 16, 32, - &csr_ex, &csr_dep, &csr_reset, - NULL, NULL, NULL, NULL, - DEV_DEBUG, 0, sys_deb_tab -}; - -t_stat csr_ex(t_value *vptr, t_addr exta, UNIT *uptr, int32 sw) -{ - return SCPE_OK; -} - -t_stat csr_dep(t_value val, t_addr exta, UNIT *uptr, int32 sw) -{ - return SCPE_OK; -} - -t_stat csr_reset(DEVICE *dptr) -{ - /* Accordig to the technical reference manual, the CSR is NOT - cleared on reset */ - return SCPE_OK; -} - -uint32 csr_read(uint32 pa, size_t size) -{ - uint32 reg = (pa - CSRBASE) & 0xff; - - switch (reg & 0xf0) { - case 0x00: - return csr_data & 0xff; - case 0x20: - return (csr_data >> 8) & 0xff; - case 0x40: - return (csr_data >> 16) & 0xff; - case 0x60: - return (csr_data >> 24) & 0xff; - default: - sim_debug(WRITE_MSG, &csr_dev, - "[%08x] CSR READ. Warning, unexpected register = %02x)\n", - R[NUM_PC], reg); - return 0; - } -} - -#define SET_INT(flag, val) { \ - if (val) { \ - CPU_SET_INT(flag); \ - } else { \ - CPU_CLR_INT(flag); \ - } \ - } - -void csr_write(uint32 pa, uint32 val, size_t size) -{ - uint32 reg = pa - CSRBASE; - - switch (reg) { - - case 0x00: - CSRBIT(CSRCLK, val); - SET_INT(INT_CLOCK, val); - break; - case 0x04: - CSRBIT(CSRPWRDN, val); - SET_INT(INT_PWRDWN, val); - break; - case 0x08: - CSRBIT(CSROPINT15, val); - SET_INT(INT_BUS_OP, val); - break; - case 0x0c: - CSRBIT(CSRUART, val); - SET_INT(INT_UART, val); - break; - case 0x10: - CSRBIT(CSRDMA, val); - SET_INT(INT_UART_DMA, val); - break; - case 0x14: - CSRBIT(CSRPIR9, val); - SET_INT(INT_PIR9, val); - break; - case 0x18: - CSRBIT(CSRPIR8, val); - SET_INT(INT_PIR8, val); - break; - case 0x1c: - CSRBIT(CSRITIM, val); - sim_debug(WRITE_MSG, &csr_dev, - "[%08x] CSR WRITE. Inhibit Interval Timer = %d\n", - R[NUM_PC], val); - if (csr_data & CSRITIM) { - timer_disable(TIMER_INTERVAL); - } else { - timer_enable(TIMER_INTERVAL); - } - break; - case 0x20: - CSRBIT(CSRISTIM, val); - sim_debug(WRITE_MSG, &csr_dev, - "[%08x] CSR WRITE. Inhibit Sanity Timer = %d\n", - R[NUM_PC], val); - if (csr_data & CSRISTIM) { - timer_disable(TIMER_SANITY); - } else { - timer_enable(TIMER_SANITY); - } - break; - case 0x24: - CSRBIT(CSRITIMO, val); - sim_debug(WRITE_MSG, &csr_dev, - "[%08x] CSR WRITE. Inhibit Bus Timer = %d\n", - R[NUM_PC], val); - if (csr_data & CSRITIMO) { - timer_disable(TIMER_BUS); - } else { - timer_enable(TIMER_BUS); - } - break; - case 0x28: - CSRBIT(CSRICPUFLT, val); - break; - case 0x2c: - CSRBIT(CSRISBERR, val); - break; - case 0x30: - CSRBIT(CSRIIOBUS, val); - break; - case 0x34: - CSRBIT(CSRIBUB, val); - break; - case 0x38: - CSRBIT(CSRFECC, val); - break; - case 0x3c: - CSRBIT(CSRTHERM, val); - cpu_nmi = val ? TRUE : FALSE; /* Immediate NMI */ - break; - case 0x40: - CSRBIT(CSRLED, val); - break; - case 0x44: - CSRBIT(CSRPWRSPDN, val); - break; - case 0x48: - CSRBIT(CSRFLPFST, val); - break; - case 0x4c: /* Floppy Side 1: Set when Cleared */ - if_state.side = (val & 1) ? 0 : 1; - CSRBIT(CSRFLPS1, val & 1); - break; - case 0x50: - CSRBIT(CSRFLPMO, val); - break; - case 0x54: - CSRBIT(CSRFLPDEN, val); - break; - case 0x58: - CSRBIT(CSRFLPSZ, val); - break; - case 0x5c: - CSRBIT(CSRSBERR, val); - if (val) { - if (!(csr_data & CSRISBERR)) { - SET_INT(INT_SBERR, TRUE); - } - } else { - SET_INT(INT_SBERR, FALSE); - } - break; - case 0x60: - CSRBIT(CSRMBERR, val); - SET_INT(INT_MBERR, val); - break; - case 0x64: - CSRBIT(CSRUBUBF, val); - SET_INT(INT_BUS_RXF, val); - break; - case 0x68: - CSRBIT(CSRTIMO, val); - if (val) { - if (!(csr_data & CSRITIMO)) { - SET_INT(INT_BUS_TMO, TRUE); - } - } else { - SET_INT(INT_BUS_TMO, FALSE); - } - break; - case 0x6c: - CSRBIT(CSRFRF, val); - break; - case 0x70: - CSRBIT(CSRALGN, val); - break; - case 0x74: - CSRBIT(CSRSTIMO, val); - cpu_nmi = val ? TRUE : FALSE; /* Immediate NMI */ - break; - case 0x78: - CSRBIT(CSRABRT, val); - cpu_nmi = val ? TRUE : FALSE; /* Immediate NMI */ - break; - case 0x7c: - /* System reset request */ - cpu_boot(0, &cpu_dev); - break; - default: - /* Do nothing */ - break; - } -} +/* 3b2_rev3_csr.c: CM518B System Board Control, Status & Error Register + + Copyright (c) 2020-2022, Seth J. Morabito + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + Except as contained in this notice, the name of the author shall + not be used in advertising or otherwise to promote the sale, use or + other dealings in this Software without prior written authorization + from the author. +*/ + +#include "3b2_cpu.h" +#include "3b2_csr.h" +#include "3b2_if.h" +#include "3b2_timer.h" +#include "3b2_sys.h" + +CSR_DATA csr_data; + +BITFIELD csr_bits[] = { + BIT(UTIM), + BIT(PWDN), + BIT(OI15), + BIT(IUINT), + BIT(IUDMA), + BIT(PIR9), + BIT(PIR8), + BIT(IUTIM), + + BIT(ISTY), + BIT(IUBUS), + BIT(IFLT), + BIT(ISBER), + BIT(IBUS), + BIT(IBUB), + BIT(FECC), + BIT(THERM), + + BIT(FLED), + BIT(PSPWR), + BIT(FLSPD), + BIT(FLSD1), + BIT(FLMOT), + BIT(FLDEN), + BIT(FLSZ), + BIT(SBER), + + BIT(MBER), + BIT(UBFL), + BIT(TIMO), + BIT(FLTFR), + BIT(DALGN), + BIT(STTIM), + BIT(ABRT), + BIT(RSTR), + + ENDBITS +}; + +UNIT csr_unit = { + UDATA(NULL, UNIT_FIX, CSRSIZE) +}; + +REG csr_reg[] = { + { HRDATADF(DATA, csr_data, 32, "CSR Data", csr_bits) }, + { NULL } +}; + +DEVICE csr_dev = { + "CSR", &csr_unit, csr_reg, NULL, + 1, 16, 8, 4, 16, 32, + &csr_ex, &csr_dep, &csr_reset, + NULL, NULL, NULL, NULL, + DEV_DEBUG, 0, sys_deb_tab +}; + +t_stat csr_ex(t_value *vptr, t_addr exta, UNIT *uptr, int32 sw) +{ + return SCPE_OK; +} + +t_stat csr_dep(t_value val, t_addr exta, UNIT *uptr, int32 sw) +{ + return SCPE_OK; +} + +t_stat csr_reset(DEVICE *dptr) +{ + CSRBIT(CSRFECC, TRUE); + CSRBIT(CSRTHERM, FALSE); + CSRBIT(CSRITIM, TRUE); + CSRBIT(CSRISTIM, TRUE); + CSRBIT(CSRIBUB, TRUE); + CSRBIT(CSRPWRSPDN, FALSE); + CSRBIT(CSRFLPMO, TRUE); + + return SCPE_OK; +} + +uint32 csr_read(uint32 pa, size_t size) +{ + uint32 reg = (pa - CSRBASE) & 0xff; + + switch (reg & 0xf0) { + case 0x00: + return csr_data & 0xff; + case 0x20: + return (csr_data >> 8) & 0xff; + case 0x40: + return (csr_data >> 16) & 0xff; + case 0x60: + return (csr_data >> 24) & 0xff; + default: + sim_debug(WRITE_MSG, &csr_dev, + "CSR READ. Warning, unexpected register = %02x)\n", + reg); + return 0; + } +} + +#define SET_INT(flag, val) { \ + if (val) { \ + CPU_SET_INT(flag); \ + } else { \ + CPU_CLR_INT(flag); \ + } \ + } + +void csr_write(uint32 pa, uint32 val, size_t size) +{ + uint32 reg = pa - CSRBASE; + + switch (reg) { + + case 0x00: + CSRBIT(CSRCLK, val); + SET_INT(INT_CLOCK, val); + break; + case 0x04: + CSRBIT(CSRPWRDN, val); + SET_INT(INT_PWRDWN, val); + break; + case 0x08: + CSRBIT(CSROPINT15, val); + SET_INT(INT_BUS_OP, val); + break; + case 0x0c: + CSRBIT(CSRUART, val); + SET_INT(INT_UART, val); + break; + case 0x10: + CSRBIT(CSRDMA, val); + SET_INT(INT_UART_DMA, val); + break; + case 0x14: + CSRBIT(CSRPIR9, val); + SET_INT(INT_PIR9, val); + break; + case 0x18: + CSRBIT(CSRPIR8, val); + SET_INT(INT_PIR8, val); + break; + case 0x1c: + CSRBIT(CSRITIM, val); + timer_gate(TIMER_INTERVAL, CSR(CSRITIM)); + break; + case 0x20: + CSRBIT(CSRISTIM, val); + timer_gate(TIMER_SANITY, CSR(CSRISTIM)); + break; + case 0x24: + CSRBIT(CSRITIMO, val); + timer_gate(TIMER_BUS, CSR(CSRITIMO)); + break; + case 0x28: + CSRBIT(CSRICPUFLT, val); + break; + case 0x2c: + CSRBIT(CSRISBERR, val); + break; + case 0x30: + CSRBIT(CSRIIOBUS, val); + break; + case 0x34: + CSRBIT(CSRIBUB, val); + break; + case 0x38: + CSRBIT(CSRFECC, val); + sim_debug(WRITE_MSG, &csr_dev, + "CSR WRITE. Force ECC Syndrome = %d\n", + val); + break; + case 0x3c: + CSRBIT(CSRTHERM, val); + cpu_nmi = val ? TRUE : FALSE; /* Immediate NMI */ + break; + case 0x40: + CSRBIT(CSRLED, val); + break; + case 0x44: + CSRBIT(CSRPWRSPDN, val); + if (!val) { + /* Stop the simulator - power down */ + stop_reason = STOP_POWER; + } + break; + case 0x48: + CSRBIT(CSRFLPFST, val); + break; + case 0x4c: /* Floppy Side 1: Set when Cleared */ + if_state.side = (val & 1) ? 0 : 1; + CSRBIT(CSRFLPS1, val & 1); + break; + case 0x50: + CSRBIT(CSRFLPMO, val); + break; + case 0x54: + CSRBIT(CSRFLPDEN, val); + break; + case 0x58: + CSRBIT(CSRFLPSZ, val); + break; + case 0x5c: + CSRBIT(CSRSBERR, val); + if (val) { + if (!(csr_data & CSRISBERR)) { + SET_INT(INT_SBERR, TRUE); + } + } else { + SET_INT(INT_SBERR, FALSE); + } + break; + case 0x60: + CSRBIT(CSRMBERR, val); + SET_INT(INT_MBERR, val); + break; + case 0x64: + CSRBIT(CSRUBUBF, val); + SET_INT(INT_BUS_RXF, val); + break; + case 0x68: + CSRBIT(CSRTIMO, val); + if (val) { + if (!(csr_data & CSRITIMO)) { + SET_INT(INT_BUS_TMO, TRUE); + } + } else { + SET_INT(INT_BUS_TMO, FALSE); + } + break; + case 0x6c: + CSRBIT(CSRFRF, val); + break; + case 0x70: + CSRBIT(CSRALGN, val); + break; + case 0x74: + CSRBIT(CSRSTIMO, val); + cpu_nmi = val ? TRUE : FALSE; /* Immediate NMI */ + break; + case 0x78: + CSRBIT(CSRABRT, val); + cpu_nmi = val ? TRUE : FALSE; /* Immediate NMI */ + break; + case 0x7c: + /* System reset request */ + full_reset(); + cpu_boot(0, &cpu_dev); + break; + default: + /* Do nothing */ + break; + } +} diff --git a/3B2/3b2_rev3_csr.h b/3B2/3b2_rev3_csr.h index 292efdd9..61dd7b7b 100644 --- a/3B2/3b2_rev3_csr.h +++ b/3B2/3b2_rev3_csr.h @@ -1,45 +1,45 @@ -/* 3b2_rev3_csr.h: AT&T 3B2/600G Control and Status Register - - Copyright (c) 2020, Seth J. Morabito - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - - Except as contained in this notice, the name of the author shall - not be used in advertising or otherwise to promote the sale, use or - other dealings in this Software without prior written authorization - from the author. -*/ - -#ifndef _3B2_400_CSR_H_ -#define _3B2_400_CSR_H_ - -#include "3b2_defs.h" - -t_stat csr_svc(UNIT *uptr); -t_stat csr_ex(t_value *vptr, t_addr exta, UNIT *uptr, int32 sw); -t_stat csr_dep(t_value val, t_addr exta, UNIT *uptr, int32 sw); -t_stat csr_reset(DEVICE *dptr); -uint32 csr_read(uint32 pa, size_t size); -void csr_write(uint32 pa, uint32 val, size_t size); - -extern uint32 csr_data; - -#endif +/* 3b2_rev3_csr.h: CM518B System Board Control, Status & Error Register + + Copyright (c) 2020-2022, Seth J. Morabito + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + Except as contained in this notice, the name of the author shall + not be used in advertising or otherwise to promote the sale, use or + other dealings in this Software without prior written authorization + from the author. +*/ + +#ifndef _3B2_400_CSR_H_ +#define _3B2_400_CSR_H_ + +#include "3b2_defs.h" + +typedef uint32 CSR_DATA; + +t_stat csr_svc(UNIT *uptr); +t_stat csr_ex(t_value *vptr, t_addr exta, UNIT *uptr, int32 sw); +t_stat csr_dep(t_value val, t_addr exta, UNIT *uptr, int32 sw); +t_stat csr_reset(DEVICE *dptr); +uint32 csr_read(uint32 pa, size_t size); +void csr_write(uint32 pa, uint32 val, size_t size); + +#endif diff --git a/3B2/3b2_rev3_defs.h b/3B2/3b2_rev3_defs.h index 2c5289dd..9d55a270 100644 --- a/3B2/3b2_rev3_defs.h +++ b/3B2/3b2_rev3_defs.h @@ -1,149 +1,141 @@ - /* 3b2_rev3_defs.h: AT&T 3B2 Rev 3 (Model 600G) Simulator Definitions - - Copyright (c) 2021, Seth J. Morabito - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - - Except as contained in this notice, the name of the author shall - not be used in advertising or otherwise to promote the sale, use or - other dealings in this Software without prior written authorization - from the author. - */ - -#ifndef _3B2_REV3_DEFS_H_ -#define _3B2_REV3_DEFS_H_ - -#define NUM_REGISTERS 32 - -#define DEFMEMSIZE MSIZ_16M -#define MAXMEMSIZE MSIZ_64M - -#define HWORD_OP_COUNT 12 -#define CPU_VERSION 0x1F /* Version encoded in WE32200 */ - -/* CSR Flags */ -#define CSRCLK 1u /* UNIX Interval Timer Timeout */ -#define CSRPWRDN (1u << 1) /* Power Down Request */ -#define CSROPINT15 (1u << 2) /* Oper. Interrupt Level 15 */ -#define CSRUART (1u << 3) /* DUART Interrupt */ -#define CSRDMA (1u << 4) /* DUART DMA Complete Interrupt */ -#define CSRPIR9 (1u << 5) /* Programmed Interrupt 9 */ -#define CSRPIR8 (1u << 6) /* Programmed Interrupt 8 */ -#define CSRITIM (1u << 7) /* Inhibit UNIX Interval Timer */ -#define CSRISTIM (1u << 8) /* Inhibit System Sanity Timer */ -#define CSRITIMO (1u << 9) /* Inhibit Bus Timer */ -#define CSRICPUFLT (1u << 10) /* Inhibit Faults to CPU */ -#define CSRISBERR (1u << 11) /* Inhibit Single Bit Error Rpt */ -#define CSRIIOBUS (1u << 12) /* Inhibit Integral 3B2 I/O Bus */ -#define CSRIBUB (1u << 13) /* Inhibit 4 BUB Slots */ -#define CSRFECC (1u << 14) /* Force ECC Syndrome */ -#define CSRTHERM (1u << 15) /* Thermal Shutdown Request */ -#define CSRLED (1u << 16) /* Failure LED */ -#define CSRPWRSPDN (1u << 17) /* Power Down -- Power Supply */ -#define CSRFLPFST (1u << 18) /* Floppy Speed Fast */ -#define CSRFLPS1 (1u << 19) /* Floppy Side 1 */ -#define CSRFLPMO (1u << 20) /* Floppy Motor On */ -#define CSRFLPDEN (1u << 21) /* Floppy Density */ -#define CSRFLPSZ (1u << 22) /* Floppy Size */ -#define CSRSBERR (1u << 23) /* Single Bit Error */ -#define CSRMBERR (1u << 24) /* Multiple Bit Error */ -#define CSRUBUBF (1u << 25) /* Ubus/BUB Received Fail */ -#define CSRTIMO (1u << 26) /* Bus Timer Timeout */ -#define CSRFRF (1u << 27) /* Fault Registers Frozen */ -#define CSRALGN (1u << 28) /* Data Alignment Error */ -#define CSRSTIMO (1u << 29) /* Sanity Timer Timeout */ -#define CSRABRT (1u << 30) /* Abort Switch Activated */ -#define CSRRRST (1u << 31) /* System Reset Request */ - -/* Interrupt Sources */ -#define INT_CLOCK 0x0001 /* UNIX Interval Timer Timeout - IPL 15 */ -#define INT_PWRDWN 0x0002 /* Power Down Request - IPL 15 */ -#define INT_BUS_OP 0x0004 /* UBUS or BUB Operational Interrupt - IPL 15 */ -#define INT_SBERR 0x0008 /* Single Bit Memory Error - IPL 15 */ -#define INT_MBERR 0x0010 /* Multiple Bit Memory Error - IPL 15 */ -#define INT_BUS_RXF 0x0020 /* UBUS, BUB, EIO Bus Received Fail - IPL 15 */ -#define INT_BUS_TMO 0x0040 /* UBUS Timer Timeout - IPL 15 */ -#define INT_UART_DMA 0x0080 /* UART DMA Complete - IPL 13 */ -#define INT_UART 0x0100 /* UART Interrupt - IPL 13 */ -#define INT_FLOPPY_DMA 0x0200 /* Floppy DMA Complete - IPL 11 */ -#define INT_FLOPPY 0x0400 /* Floppy Interrupt - IPL 11 */ -#define INT_PIR9 0x0800 /* PIR-9 (from CSER) - IPL 9 */ -#define INT_PIR8 0x1000 /* PIR-8 (from CSER) - IPL 8 */ - -#define INT_MAP_LEN 0x2000 - -/* Memory */ -#define MEMID_4M 6 -#define MEMID_16M 7 -#define MADDR_SLOT_0 0x4d000 -#define MADDR_SLOT_1 0x4d004 -#define MADDR_SLOT_2 0x4d008 -#define MADDR_SLOT_3 0x4d00c - -#define IFCSRBASE 0x40000 -#define IFCSRSIZE 0x100 -#define TIMERBASE 0x41000 -#define TIMERSIZE 0x20 -#define NVRBASE 0x42000 -#define NVRSIZE 0x2000 -#define CSRBASE 0x44000 -#define CSRSIZE 0x100 -#define DMAIFBASE 0x45000 -#define DMAIFSIZE 0x5 -#define DMAIUABASE 0x46000 -#define DMAIUASIZE 0x5 -#define DMAIUBBASE 0x47000 -#define DMAIUBSIZE 0x5 -#define DMACBASE 0x48000 -#define DMACSIZE 0x11 -#define IFBASE 0x4a000 -#define IFSIZE 0x10 -#define TODBASE 0x4e000 -#define TODSIZE 0x40 -#define MMUBASE 0x4f000 -#define MMUSIZE 0x1000 -#define FLTLBASE 0x4c000 -#define FLTLSIZE 0x10 -#define FLTHBASE 0x4d000 -#define FLTHSIZE 0x10 - -#define VCACHE_BOTTOM 0x1c00000 -#define VCACHE_TOP 0x2000000 - -#define BUB_BOTTOM 0x6000000 -#define BUB_TOP 0x1a000000 - -#define IF_STATUS_REG 0 -#define IF_CMD_REG 0 -#define IF_TRACK_REG 1 -#define IF_SECTOR_REG 2 -#define IF_DATA_REG 3 - -#define DMA_IF_CHAN 1 -#define DMA_IUA_CHAN 2 -#define DMA_IUB_CHAN 3 - -#define DMA_IF 0x45 -#define DMA_IUA 0x46 -#define DMA_IUB 0x47 -#define DMA_C 0x48 - -#endif +/* 3b2_rev3_defs.h: Veresion 3 (3B2/700) Common Definitions + + Copyright (c) 2021-2022, Seth J. Morabito + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + Except as contained in this notice, the name of the author shall + not be used in advertising or otherwise to promote the sale, use or + other dealings in this Software without prior written authorization + from the author. + */ + +#ifndef _3B2_REV3_DEFS_H_ +#define _3B2_REV3_DEFS_H_ + +#define NUM_REGISTERS 32 + +#define DEFMEMSIZE MSIZ_16M +#define MAXMEMSIZE MSIZ_64M + +#define HWORD_OP_COUNT 12 +#define CPU_VERSION 0x1F /* Version encoded in WE32200 */ + +/* CSR Flags */ +#define CSRCLK 1u /* UNIX Interval Timer Timeout */ +#define CSRPWRDN (1u << 1) /* Power Down Request */ +#define CSROPINT15 (1u << 2) /* Oper. Interrupt Level 15 */ +#define CSRUART (1u << 3) /* DUART Interrupt */ +#define CSRDMA (1u << 4) /* DUART DMA Complete Interrupt */ +#define CSRPIR9 (1u << 5) /* Programmed Interrupt 9 */ +#define CSRPIR8 (1u << 6) /* Programmed Interrupt 8 */ +#define CSRITIM (1u << 7) /* Inhibit UNIX Interval Timer */ +#define CSRISTIM (1u << 8) /* Inhibit System Sanity Timer */ +#define CSRITIMO (1u << 9) /* Inhibit Bus Timer */ +#define CSRICPUFLT (1u << 10) /* Inhibit Faults to CPU */ +#define CSRISBERR (1u << 11) /* Inhibit Single Bit Error Rpt */ +#define CSRIIOBUS (1u << 12) /* Inhibit Integral 3B2 I/O Bus */ +#define CSRIBUB (1u << 13) /* Inhibit 4 BUB Slots */ +#define CSRFECC (1u << 14) /* Force ECC Syndrome */ +#define CSRTHERM (1u << 15) /* Thermal Shutdown Request */ +#define CSRLED (1u << 16) /* Failure LED */ +#define CSRPWRSPDN (1u << 17) /* Power Down -- Power Supply */ +#define CSRFLPFST (1u << 18) /* Floppy Speed Fast */ +#define CSRFLPS1 (1u << 19) /* Floppy Side 1 */ +#define CSRFLPMO (1u << 20) /* Floppy Motor On */ +#define CSRFLPDEN (1u << 21) /* Floppy Density */ +#define CSRFLPSZ (1u << 22) /* Floppy Size */ +#define CSRSBERR (1u << 23) /* Single Bit Error */ +#define CSRMBERR (1u << 24) /* Multiple Bit Error */ +#define CSRUBUBF (1u << 25) /* Ubus/BUB Received Fail */ +#define CSRTIMO (1u << 26) /* Bus Timer Timeout */ +#define CSRFRF (1u << 27) /* Fault Registers Frozen */ +#define CSRALGN (1u << 28) /* Data Alignment Error */ +#define CSRSTIMO (1u << 29) /* Sanity Timer Timeout */ +#define CSRABRT (1u << 30) /* Abort Switch Activated */ +#define CSRRRST (1u << 31) /* System Reset Request */ + +/* Interrupt Sources */ +#define INT_CLOCK 0x0001 /* UNIX Interval Timer Timeout - IPL 15 */ +#define INT_PWRDWN 0x0002 /* Power Down Request - IPL 15 */ +#define INT_BUS_OP 0x0004 /* UBUS or BUB Operational Interrupt - IPL 15 */ +#define INT_SBERR 0x0008 /* Single Bit Memory Error - IPL 15 */ +#define INT_MBERR 0x0010 /* Multiple Bit Memory Error - IPL 15 */ +#define INT_BUS_RXF 0x0020 /* UBUS, BUB, EIO Bus Received Fail - IPL 15 */ +#define INT_BUS_TMO 0x0040 /* UBUS Timer Timeout - IPL 15 */ +#define INT_UART_DMA 0x0080 /* UART DMA Complete - IPL 13 */ +#define INT_UART 0x0100 /* UART Interrupt - IPL 13 */ +#define INT_FLOPPY_DMA 0x0200 /* Floppy DMA Complete - IPL 11 */ +#define INT_FLOPPY 0x0400 /* Floppy Interrupt - IPL 11 */ +#define INT_PIR9 0x0800 /* PIR-9 (from CSER) - IPL 9 */ +#define INT_PIR8 0x1000 /* PIR-8 (from CSER) - IPL 8 */ + +#define INT_MAP_LEN 0x2000 + +#define IFCSRBASE 0x40000 +#define IFCSRSIZE 0x100 +#define TIMERBASE 0x41000 +#define TIMERSIZE 0x20 +#define NVRBASE 0x42000 +#define NVRSIZE 0x2000 +#define CSRBASE 0x44000 +#define CSRSIZE 0x100 +#define DMAIFBASE 0x45000 +#define DMAIFSIZE 0x5 +#define DMAIUABASE 0x46000 +#define DMAIUASIZE 0x5 +#define DMAIUBBASE 0x47000 +#define DMAIUBSIZE 0x5 +#define DMACBASE 0x48000 +#define DMACSIZE 0x11 +#define IFBASE 0x4a000 +#define IFSIZE 0x10 +#define TODBASE 0x4e000 +#define TODSIZE 0x40 +#define MMUBASE 0x4f000 +#define MMUSIZE 0x1000 +#define FLTLBASE 0x4c000 +#define FLTLSIZE 0x1000 +#define FLTHBASE 0x4d000 +#define FLTHSIZE 0x1000 + +#define VCACHE_BOTTOM 0x1c00000 +#define VCACHE_TOP 0x2000000 + +#define BUB_BOTTOM 0x6000000 +#define BUB_TOP 0x1a000000 + +#define IF_STATUS_REG 0 +#define IF_CMD_REG 0 +#define IF_TRACK_REG 1 +#define IF_SECTOR_REG 2 +#define IF_DATA_REG 3 + +#define DMA_IF_CHAN 1 +#define DMA_IUA_CHAN 2 +#define DMA_IUB_CHAN 3 + +#define DMA_IF 0x45 +#define DMA_IUA 0x46 +#define DMA_IUB 0x47 +#define DMA_C 0x48 + +#endif diff --git a/3B2/3b2_rev3_mau.c b/3B2/3b2_rev3_mau.c deleted file mode 100644 index 53fcc2b6..00000000 --- a/3B2/3b2_rev3_mau.c +++ /dev/null @@ -1,31 +0,0 @@ -/* 3b2_rev3_mau.c: WE32206 Math Accelration Unit Implementation - - Copyright (c) 2021, Seth J. Morabito - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - - Except as contained in this notice, the name of the author shall - not be used in advertising or otherwise to promote the sale, use or - other dealings in this Software without prior written authorization - from the author. -*/ - -/* Stub file. Not Yet Implemented. */ diff --git a/3B2/3b2_rev3_mau.h b/3B2/3b2_rev3_mau.h deleted file mode 100644 index 9b54bb2b..00000000 --- a/3B2/3b2_rev3_mau.h +++ /dev/null @@ -1,36 +0,0 @@ -/* 3b2_rev3_mau.h: WE32206 Math Accelration Unit Header - - Copyright (c) 2021, Seth J. Morabito - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - - Except as contained in this notice, the name of the author shall - not be used in advertising or otherwise to promote the sale, use or - other dealings in this Software without prior written authorization - from the author. -*/ - -#ifndef _3B2_REV3_MAU_H_ -#define _3B2_REV3_MAU_H_ - -/* Stub file. Not Yet Implemented. */ - -#endif diff --git a/3B2/3b2_rev3_mmu.c b/3B2/3b2_rev3_mmu.c index 898be53b..ceee7b4d 100644 --- a/3B2/3b2_rev3_mmu.c +++ b/3B2/3b2_rev3_mmu.c @@ -1,1209 +1,1178 @@ -/* 3b2_rev3_mmu.c: AT&T 3B2/600G MMU (WE32201) - - Copyright (c) 2020, Seth J. Morabito - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - - Except as contained in this notice, the name of the author shall - not be used in advertising or otherwise to promote the sale, use or - other dealings in this Software without prior written authorization - from the author. -*/ - - -#include "3b2_cpu.h" -#include "3b2_csr.h" -#include "3b2_mem.h" -#include "3b2_mmu.h" - -UNIT mmu_unit = { UDATA(NULL, 0, 0) }; - -MMU_STATE mmu_state; - -REG mmu_reg[] = { - { HRDATAD (ENABLE, mmu_state.enabled, 1, "Enabled?") }, - { HRDATAD (CONFIG, mmu_state.conf, 32, "Configuration") }, - { HRDATAD (VAR, mmu_state.var, 32, "Virtual Address") }, - { HRDATAD (FCODE, mmu_state.fcode, 32, "Fault Code") }, - { HRDATAD (FADDR, mmu_state.faddr, 32, "Fault Address") }, - { BRDATA (SDCL, mmu_state.sdcl, 16, 32, MMU_SDCS) }, - { BRDATA (SDCH, mmu_state.sdch, 16, 32, MMU_SDCS) }, - { BRDATA (PDCL, mmu_state.pdcl, 16, 32, MMU_PDCS) }, - { BRDATA (PDCH, mmu_state.pdch, 16, 32, MMU_PDCS) }, - { BRDATA (SRAMA, mmu_state.sra, 16, 32, MMU_SRS) }, - { BRDATA (SRAMB, mmu_state.srb, 16, 32, MMU_SRS) }, - { NULL } -}; - -#define MMU_EXEC_DBG 1 -#define MMU_TRACE_DBG 1 << 1 -#define MMU_CACHE_DBG 1 << 2 -#define MMU_FAULT_DBG 1 << 3 -#define MMU_READ_DBG 1 << 4 -#define MMU_WRITE_DBG 1 << 5 - -static DEBTAB mmu_debug[] = { - { "EXEC", MMU_EXEC_DBG, "Simple execution" }, - { "CACHE", MMU_CACHE_DBG, "Cache trace" }, - { "TRACE", MMU_TRACE_DBG, "Translation trace" }, - { "FAULT", MMU_FAULT_DBG, "Faults" }, - { "READ", MMU_READ_DBG, "Peripheral Read"}, - { "WRITE", MMU_WRITE_DBG, "Peripheral Write"}, - { NULL } -}; - -MTAB mmu_mod[] = { - { MTAB_XTD|MTAB_VDV|MTAB_NMO|MTAB_SHP, 0, "SDT", NULL, - NULL, &mmu_show_sdt, NULL, "Display SDT for section n [0-3]" }, - { MTAB_XTD|MTAB_VDV|MTAB_NMO, 0, "SDC", NULL, - NULL, &mmu_show_sdc, NULL, "Display SD Cache" }, - { MTAB_XTD|MTAB_VDV|MTAB_NMO, 0, "PDC", NULL, - NULL, &mmu_show_pdc, NULL, "Display PD Cache" }, - { 0 } -}; - -DEVICE mmu_dev = { - "MMU", /* name */ - &mmu_unit, /* units */ - mmu_reg, /* registers */ - mmu_mod, /* modifiers */ - 1, /* #units */ - 16, /* address radix */ - 8, /* address width */ - 4, /* address incr */ - 16, /* data radix */ - 32, /* data width */ - NULL, /* examine routine */ - NULL, /* deposit routine */ - &mmu_init, /* reset routine */ - NULL, /* boot routine */ - NULL, /* attach routine */ - NULL, /* detach routine */ - NULL, /* context */ - DEV_DEBUG, /* flags */ - 0, /* debug control flags */ - mmu_debug, /* debug flag names */ - NULL, /* memory size change */ - NULL, /* logical name */ - NULL, /* help routine */ - NULL, /* attach help routine */ - NULL, /* help context */ - &mmu_description /* device description */ -}; - -/* - * Each bitmask corresponds to the pattern of bits used for the tag in - * the first word of a segment descriptor in the cache. The outer - * index corresponds to mode (0=Single-Context Mode, 1=Multi-Context - * Mode), the inner index corresponds to page size (0=2kB, 1=4kB, - * 2=8kB, 3=undefined) - */ -uint32 pdc_tag_masks[2][4] = { - {0x43ffffe0, 0x43ffffc0, 0x43ffff80, 0}, - {0x7fffffe0, 0x7fffffc0, 0x7fffff80, 0}, -}; - -/* - * Bitmasks for generating page addresses for contiguous segments on - * cache miss. - */ -uint32 pd_addr_masks[4] = { - 0xfffff800, 0xfffff000, 0xffffe000, 0 -}; - -uint32 pd_psl_masks[4] = { - 0x1f800, 0x1f000, 0x1e000, 0 -}; - -/* Masks used when searching the PD cache for a matching tag. */ -#define PDC_TAG_MASK (pdc_tag_masks[MMU_CONF_MCE][MMU_CONF_PS]) - -/* Mask off the bottom 10 bits of virtual address when generating PD - * cache tags */ -#define VA_TO_TAG_MASK 0xfffff800 - -/* - * Macros used to generate PD cache tags from virtual-addresses - */ -#define PDC_MTAG(VA) ((((VA) & VA_TO_TAG_MASK) >> 6) | \ - (mmu_state.cidnr[SID(VA)] << 26) | \ - (1 << 30)) - -#define PDC_STAG(VA) ((((VA) & VA_TO_TAG_MASK) >> 6) | \ - (1 << 30)) - -#define PDC_TAG(VA) (MMU_CONF_MCE ? PDC_MTAG(VA) : PDC_STAG(VA)) - -/* - * Retrieve a Segment Descriptor from the SD cache. The Segment - * Descriptor Cache entry is returned in sd_lo and sd_hi, if found. - * - * If there is a cache hit, this function returns SCPE_OK. - * If there is a cache miss, this function returns SCPE_NXM. - */ -static t_stat get_sdce(uint32 va, uint32 *sd_hi, uint32 *sd_lo) -{ - uint32 hi, lo, va_tag, sdc_tag; - - hi = mmu_state.sdch[SDC_IDX(va)]; - lo = mmu_state.sdcl[SDC_IDX(va)]; - va_tag = (va >> 20) & 0xfff; - sdc_tag = lo & 0xfff; - - if ((hi & SDC_G_MASK) && (va_tag == sdc_tag)) { - *sd_hi = SDCE_TO_SDH(hi); - *sd_lo = SDCE_TO_SDL(hi,lo); - return SCPE_OK; - } - - return SCPE_NXM; -} - -/* - * Insert a Segment Descriptor into the SD cache. - */ -static void put_sdce(uint32 va, uint32 sd_hi, uint32 sd_lo) -{ - uint8 ci = SDC_IDX(va); - - mmu_state.sdch[ci] = SD_TO_SDCH(sd_hi, sd_lo); - mmu_state.sdcl[ci] = SD_TO_SDCL(sd_lo, va); - - sim_debug(MMU_CACHE_DBG, &mmu_dev, - "[%08x] CACHED SD AT IDX %d. va=%08x sd_hi=%08x sd_lo=%08x sdc_hi=%08x sdc_lo=%08x\n", - R[NUM_PC], ci, va, sd_hi, sd_lo, mmu_state.sdch[ci], mmu_state.sdcl[ci]); - -} - -/* - * Update the "Used" bit in the Page Descriptor cache for the given - * entry. - */ -static void set_u_bit(uint32 index) -{ - uint32 i; - - mmu_state.pdch[index] |= PDC_U_MASK; - - /* Check to see if all U bits have been set. If so, the cache will - * need to be flushed on the next put */ - for (i = 0; i < MMU_PDCS; i++) { - if ((mmu_state.pdch[i] & PDC_U_MASK) == 0) { - return; - } - } - - mmu_state.flush_u = TRUE; -} - -/* - * Retrieve a Page Descriptor Cache Entry from the Page Descriptor - * Cache. - */ -static t_stat get_pdce(uint32 va, uint32 *pd, uint8 *pd_acc, uint32 *pdc_idx) -{ - uint32 i, key_tag, target_tag; - - *pdc_idx = 0; - - /* This is a fully associative cache, so we must scan for an entry - with the correct tag. */ - key_tag = PDC_TAG(va) & PDC_TAG_MASK; - - for (i = 0; i < MMU_PDCS; i++) { - target_tag = mmu_state.pdch[i] & PDC_TAG_MASK; - if (target_tag == key_tag) { - /* Construct the PD from the cached version */ - *pd = PDCE_TO_PD(mmu_state.pdcl[i]); - *pd_acc = (mmu_state.pdcl[i] >> 24) & 0xff; - *pdc_idx = i; - sim_debug(MMU_TRACE_DBG, &mmu_dev, - "[%08x] PDC HIT. va=%08x idx=%d tag=%03x pd=%08x pdcl=%08x pdch=%08x\n", - R[NUM_PC], va, i, key_tag, *pd, - mmu_state.pdcl[i], mmu_state.pdch[i]); - set_u_bit(i); - return SCPE_OK; - } - } - - sim_debug(MMU_CACHE_DBG, &mmu_dev, - "[%08x] PDC MISS. va=%08x tag=%03x\n", - R[NUM_PC], va, key_tag); - - return SCPE_NXM; -} - -/* - * Cache a Page Descriptor in the specified slot. - */ -static void put_pdce_at(uint32 va, uint32 sd_lo, uint32 pd, uint32 slot) -{ - mmu_state.pdcl[slot] = PD_TO_PDCL(pd, sd_lo); - mmu_state.pdch[slot] = VA_TO_PDCH(va, sd_lo); - sim_debug(MMU_CACHE_DBG, &mmu_dev, - "[%08x] Caching MMU PDC entry at index %d (pdc_hi=%08x pdc_lo=%08x va=%08x)\n", - R[NUM_PC], slot, mmu_state.pdch[slot], mmu_state.pdcl[slot], va); - set_u_bit(slot); - mmu_state.last_cached = slot; -} - -/* - * Cache a Page Descriptor in the first available, least recently used - * slot. - */ -static uint32 put_pdce(uint32 va, uint32 sd_lo, uint32 pd) -{ - uint32 i; - - /* - * If all the U bits have been set, flush them all EXCEPT the most - * recently cached entry. - */ - if (mmu_state.flush_u) { - sim_debug(MMU_CACHE_DBG, &mmu_dev, - "[%08x] Flushing PDC U bits on all-set condition.\n", - R[NUM_PC]); - mmu_state.flush_u = FALSE; - for (i = 0; i < MMU_PDCS; i++) { - if (i != mmu_state.last_cached) { - mmu_state.pdch[i] &= ~(PDC_U_MASK); - } - } - } - - /* TODO: This can be done in one pass! Clean it up */ - - /* Cache the Page Descriptor in the first slot with a cleared G - * bit */ - for (i = 0; i < MMU_PDCS; i++) { - if ((mmu_state.pdch[i] & PDC_G_MASK) == 0) { - put_pdce_at(va, sd_lo, pd, i); - return i; - } - } - - /* If ALL slots had their G bit set, find the first slot with a - cleared U bit */ - for (i = 0; i < MMU_PDCS; i++) { - if ((mmu_state.pdch[i] & PDC_U_MASK) == 0) { - put_pdce_at(va, sd_lo, pd, i); - return i; - } - } - - /* This should never happen, since if all U bits become set, they - * are automatically all cleared */ - stop_reason = STOP_MMU; - - return 0; -} - -/* - * Flush the cache for an individual virtual address. - */ -static void flush_pdc(uint32 va) -{ - uint32 i, j, key_tag, target_tag; - - /* Flush the PDC. This is a fully associative cache, so we must - * scan for an entry with the correct tag. */ - - key_tag = PDC_TAG(va) & PDC_TAG_MASK; - - for (i = 0; i < MMU_PDCS; i++) { - target_tag = mmu_state.pdch[i] & PDC_TAG_MASK; - if (target_tag == key_tag) { - sim_debug(MMU_CACHE_DBG, &mmu_dev, - "[%08x] Flushing MMU PDC entry pdc_lo=%08x pdc_hi=%08x index %d (va=%08x)\n", - R[NUM_PC], - mmu_state.pdcl[i], - mmu_state.pdch[i], - i, - va); - if (mmu_state.pdch[i] & PDC_C_MASK) { - sim_debug(MMU_CACHE_DBG, &mmu_dev, - "[%08x] Flushing MMU PDC entry: CONTIGUOUS\n", - R[NUM_PC]); - /* If this PD came from a contiguous SD, we need to - * flush ALL entries belonging to the same SD. All - * pages within the same segment have the same upper - * 11 bits. */ - for (j = 0; j < MMU_PDCS; j++) { - if ((mmu_state.pdch[j] & 0x3ffc000) == - (mmu_state.pdch[i] & 0x3ffc000)) { - mmu_state.pdch[j] &= ~(PDC_G_MASK|PDC_U_MASK); - } - } - } else { - /* Otherwise, just flush the one entry */ - mmu_state.pdch[i] &= ~(PDC_G_MASK|PDC_U_MASK); - } - return; - } - } - - sim_debug(MMU_CACHE_DBG, &mmu_dev, - "[%08x] Flushing MMU PDC entry: NOT FOUND (va=%08x key_tag=%08x)\n", - R[NUM_PC], va, key_tag); - -} - -/* - * Flush all entries in both SDC and PDC. - */ -static void flush_caches() -{ - uint32 i; - - sim_debug(MMU_CACHE_DBG, &mmu_dev, - "[%08x] Flushing MMU PDC and SDC\n", - R[NUM_PC]); - - for (i = 0; i < MMU_SDCS; i++) { - mmu_state.sdch[i] &= ~SDC_G_MASK; - } - - for (i = 0; i < MMU_PDCS; i++) { - mmu_state.pdch[i] &= ~PDC_G_MASK; - mmu_state.pdch[i] &= ~PDC_U_MASK; - } -} - -/* - * Check permissions for a set of permission flags and an access type. - * - * Return SCPE_OK if permission is granted, SCPE_NXM if permission is - * not allowed. - */ -static t_stat mmu_check_perm(uint8 flags, uint8 r_acc) -{ - switch(MMU_PERM(flags)) { - case 0: /* No Access */ - return SCPE_NXM; - case 1: /* Exec Only */ - if (r_acc != ACC_IF && r_acc != ACC_IFAD) { - return SCPE_NXM; - } - return SCPE_OK; - case 2: /* Read / Execute */ - if (r_acc != ACC_IF && r_acc != ACC_IFAD && - r_acc != ACC_AF && r_acc != ACC_OF && - r_acc != ACC_MT) { - return SCPE_NXM; - } - return SCPE_OK; - default: - return SCPE_OK; - } -} - -/* - * Internally, the ID Number Cache is a fully associative cache with a - * tag consisting of the upper 29 bits of the segment address, plus a - * U bit indicating that the ID is usable. The value (the ID number) - * is the fixed index of the tag within the cache. - */ -static t_stat get_idnc(uint32 va, uint8 *id) -{ - uint32 i, tag, entry; - - tag = IDNC_TAG(va); - - for (i = 0; i < MMU_IDNCS; i++) { - entry = mmu_state.idnc[i]; - if ((IDNC_TAG(entry) == tag) && IDNC_U(entry)) { - *id = ((uint8)i & 0xff); - return SCPE_OK; - } - } - - return SCPE_NXM; -} - -/* - * Initialize the MMU device - */ -t_stat mmu_init(DEVICE *dptr) -{ - flush_caches(); - return SCPE_OK; -} - -/* - * Memory-mapped (peripheral mode) read of the MMU device - */ -uint32 mmu_read(uint32 pa, size_t size) -{ - uint8 entity, index; - uint32 data = 0; - - /* Register entity */ - entity = ((uint8)(pa >> 8)) & 0xf; - - /* Index into entity */ - index = (uint8)((pa >> 2) & 0x1f); - - switch (entity) { - case MMU_SDCL: - data = mmu_state.sdcl[index]; - sim_debug(MMU_READ_DBG, &mmu_dev, - "[%08x] MMU_SDCL[%d] = %08x\n", - R[NUM_PC], index, data); - break; - case MMU_SDCH: - data = mmu_state.sdch[index]; - sim_debug(MMU_READ_DBG, &mmu_dev, - "[%08x] MMU_SDCH[%d] = %08x\n", - R[NUM_PC], index, data); - break; - case MMU_PDCL: - data = mmu_state.pdcl[index]; - sim_debug(MMU_READ_DBG, &mmu_dev, - "[%08x] MMU_PDCL[%d] = %08x\n", - R[NUM_PC], index, data); - break; - case MMU_PDCH: - data = mmu_state.pdch[index]; - sim_debug(MMU_READ_DBG, &mmu_dev, - "[%08x] MMU_PDCH[%d] = %08x\n", - R[NUM_PC], index, data); - break; - case MMU_SRAMA: - data = mmu_state.sra[index]; - sim_debug(MMU_READ_DBG, &mmu_dev, - "[%08x] MMU_SRAMA[%d] = %08x\n", - R[NUM_PC], index, data); - break; - case MMU_SRAMB: - data = mmu_state.srb[index]; - sim_debug(MMU_READ_DBG, &mmu_dev, - "[%08x] MMU_SRAMB[%d] = %08x\n", - R[NUM_PC], index, data); - break; - case MMU_FC: - data = mmu_state.fcode; - sim_debug(MMU_READ_DBG, &mmu_dev, - "[%08x] MMU_FC = %08x\n", - R[NUM_PC], data); - break; - case MMU_FA: - data = mmu_state.faddr; - sim_debug(MMU_READ_DBG, &mmu_dev, - "[%08x] MMU_FA = %08x\n", - R[NUM_PC], data); - break; - case MMU_CONF: - data = mmu_state.conf; - sim_debug(MMU_READ_DBG, &mmu_dev, - "[%08x] MMU_CONF = %02x (M=%d R=%d $=%d PS=%d MCE=%d DCE=%d)\n", - R[NUM_PC], data, - MMU_CONF_M, - MMU_CONF_R, - MMU_CONF_C, - MMU_CONF_PS, - MMU_CONF_MCE, - MMU_CONF_DCE); - break; - case MMU_VAR: - data = mmu_state.var; - sim_debug(MMU_READ_DBG, &mmu_dev, - "[%08x] MMU_VAR = %08x\n", - R[NUM_PC], data); - break; - case MMU_IDC: - /* TODO: Implement */ - data = 0; - sim_debug(MMU_READ_DBG, &mmu_dev, - "[%08x] MMU_IDC\n", R[NUM_PC]); - break; - case MMU_IDNR: - /* TODO: Implement */ - data = 0; - sim_debug(MMU_READ_DBG, &mmu_dev, - "[%08x] MMU_IDNR\n", R[NUM_PC]); - break; - case MMU_FIDNR: - /* TODO: Implement */ - data = 0; - sim_debug(MMU_READ_DBG, &mmu_dev, - "[%08x] MMU_FIDNR\n", R[NUM_PC]); - break; - case MMU_VR: - /* Simply not faulting here is good enough */ - data = 0; - sim_debug(MMU_READ_DBG, &mmu_dev, - "[%08x] MMU_VR\n", R[NUM_PC]); - break; - default: - sim_debug(MMU_READ_DBG, &mmu_dev, - "[%08x] Invalid MMU register: pa=%08x\n", - R[NUM_PC], pa); - CSRBIT(CSRTIMO, TRUE); - break; - } - - return data; -} - -void mmu_write(uint32 pa, uint32 val, size_t size) -{ - uint32 index, entity, i; - - /* Register entity */ - entity = ((uint8)(pa >> 8)) & 0xf; - - /* Index into entity */ - index = (uint8)((pa >> 2) & 0x1f); - - switch (entity) { - case MMU_SDCL: - sim_debug(MMU_WRITE_DBG, &mmu_dev, - "MMU_SDCL[%d] = %08x\n", - index, val); - mmu_state.sdcl[index] = val; - break; - case MMU_SDCH: - sim_debug(MMU_WRITE_DBG, &mmu_dev, - "MMU_SDCH[%d] = %08x\n", - index, val); - mmu_state.sdch[index] = val; - break; - case MMU_PDCL: - sim_debug(MMU_WRITE_DBG, &mmu_dev, - "MMU_PDCL[%d] = %08x\n", - index, val); - mmu_state.pdcl[index] = val; - break; - case MMU_PDCH: - sim_debug(MMU_WRITE_DBG, &mmu_dev, - "MMU_PDCH[%d] = %08x\n", - index, val); - mmu_state.pdch[index] = val; - break; - case MMU_FDCR: - sim_debug(MMU_WRITE_DBG, &mmu_dev, - "[%08x] MMU_FDCR\n", - R[NUM_PC]); - /* Data cache is not implemented */ - break; - case MMU_SRAMA: - index = index & 3; - sim_debug(MMU_WRITE_DBG, &mmu_dev, - "[%08x] MMU_SRAMA[%d] = %08x\n", - R[NUM_PC], index, val); - mmu_state.sra[index] = val; - mmu_state.sec[index].addr = val & 0xfffffffc; - - /* Flush all SDC cache entries for this section */ - for (i = 0; i < MMU_SDCS; i++) { - if (((mmu_state.sdcl[i] >> 10) & 0x3) == index) { - sim_debug(MMU_CACHE_DBG, &mmu_dev, - "[%08x] Flushing MMU SDC entry at index %d " - "(sdc_lo=%08x sdc_hi=%08x)\n", - R[NUM_PC], i, - mmu_state.sdcl[i], mmu_state.sdch[i]); - mmu_state.sdch[i] &= ~(SDC_G_MASK); - } - } - - /* Flush all PDC cache entries for this section */ - for (i = 0; i < MMU_PDCS; i++) { - if (((mmu_state.pdch[i] >> 24) & 0x3) == index) { - mmu_state.pdch[i] &= ~(PDC_G_MASK); - } - } - break; - case MMU_SRAMB: - index = index & 3; - mmu_state.srb[index] = val; - mmu_state.sec[index].len = (val >> 10) & 0x1fff; - /* We do not flush the cache on writing SRAMB */ - sim_debug(MMU_WRITE_DBG, &mmu_dev, - "[%08x] MMU_SRAMB[%d] length=%04x (%d segments)\n", - R[NUM_PC], - index, - mmu_state.sec[index].len, - mmu_state.sec[index].len + 1); - break; - case MMU_FC: - /* Set a default value */ - mmu_state.fcode = (((CPU_CM) << 5) | (0xa << 7)); - sim_debug(MMU_WRITE_DBG, &mmu_dev, - "[%08x] MMU_FC = %08x\n", - R[NUM_PC], mmu_state.fcode); - break; - case MMU_FA: - mmu_state.faddr = val; - sim_debug(MMU_WRITE_DBG, &mmu_dev, - "[%08x] MMU_FADDR = %08x\n", - R[NUM_PC], val); - break; - case MMU_CONF: - mmu_state.conf = val & 0x7f; - sim_debug(MMU_WRITE_DBG, &mmu_dev, - "[%08x] MMU_CONF = %02x (M=%d R=%d $=%d PS=%d MCE=%d DCE=%d)\n", - R[NUM_PC], val, - MMU_CONF_M, - MMU_CONF_R, - MMU_CONF_C, - MMU_CONF_PS, - MMU_CONF_MCE, - MMU_CONF_DCE); - break; - case MMU_VAR: - mmu_state.var = val; - sim_debug(MMU_WRITE_DBG, &mmu_dev, - "[%08x] MMU_VAR = %08x\n", - R[NUM_PC], val); - if ((mmu_state.sdcl[SDC_IDX(val)] & SDC_VADDR_MASK) == - ((val >> 20) & SDC_VADDR_MASK)) { - sim_debug(MMU_CACHE_DBG, &mmu_dev, - "[%08x] Flushing MMU SDC entry at index %d " - "(sdc_lo=%08x sdc_hi=%08x)\n", - R[NUM_PC], SDC_IDX(val), - mmu_state.sdcl[SDC_IDX(val)], - mmu_state.sdch[SDC_IDX(val)]); - mmu_state.sdch[SDC_IDX(val)] &= ~SDC_G_MASK; - } - flush_pdc(val); - break; - case MMU_IDC: - sim_debug(MMU_WRITE_DBG, &mmu_dev, - "[%08x] MMU_IDC = %08x\n", - R[NUM_PC], val); - break; - case MMU_IDNR: - sim_debug(MMU_WRITE_DBG, &mmu_dev, - "[%08x] MMU_IDNR = %08x\n", - R[NUM_PC], val); - break; - case MMU_FIDNR: - sim_debug(MMU_WRITE_DBG, &mmu_dev, - "[%08x] MMU_FIDNR = %08x\n", - R[NUM_PC], val); - break; - case MMU_VR: - sim_debug(MMU_WRITE_DBG, &mmu_dev, - "[%08x] MMU_VR = %08x\n", - R[NUM_PC], val); - break; - default: - sim_debug(MMU_WRITE_DBG, &mmu_dev, - "[%08x] UNHANDLED WRITE (entity=0x%x, index=0x%x, val=%08x)\n", - R[NUM_PC], entity, index, val); - break; - } -} - -/* - * Update history bits in cache and memory. - */ -static t_stat mmu_update_history(uint32 va, uint8 r_acc, uint32 pdc_idx, t_bool fc) -{ - uint32 sd_hi, sd_lo, pd; - uint32 pd_addr; - t_bool update_sdc = TRUE; - - if (get_sdce(va, &sd_hi, &sd_lo) != SCPE_OK) { - update_sdc = FALSE; - } - - sd_lo = pread_w(SD_ADDR(va)); - sd_hi = pread_w(SD_ADDR(va) + 4); - - if (MMU_CONF_M && r_acc == ACC_W && (mmu_state.sdcl[SDC_IDX(va)] & SDC_M_MASK) == 0) { - if (update_sdc) { - mmu_state.sdcl[SDC_IDX(va)] |= SDC_M_MASK; - } - - if (mmu_check_perm(SD_ACC(sd_lo), r_acc) != SCPE_OK) { - sim_debug(MMU_FAULT_DBG, &mmu_dev, - "[%08x] MMU R&M Update Fault (M)\n", - R[NUM_PC]); - MMU_FAULT(MMU_F_RM_UPD); - return SCPE_NXM; - } - - pwrite_w(SD_ADDR(va), sd_lo | SD_M_MASK); - } - - if (MMU_CONF_R && (mmu_state.sdcl[SDC_IDX(va)] & SDC_R_MASK) == 0) { - if (update_sdc) { - mmu_state.sdcl[SDC_IDX(va)] |= SDC_R_MASK; - } - - if (mmu_check_perm(SD_ACC(sd_lo), r_acc) != SCPE_OK) { - sim_debug(MMU_FAULT_DBG, &mmu_dev, - "[%08x] MMU R&M Update Fault (R)\n", - R[NUM_PC]); - MMU_FAULT(MMU_F_RM_UPD); - return SCPE_NXM; - } - - pwrite_w(SD_ADDR(va), sd_lo | SD_R_MASK); - } - - if (!SD_CONTIG(sd_lo)) { - pd_addr = SD_SEG_ADDR(sd_hi) + (PSL(va) * 4); - - if (r_acc == ACC_W && (mmu_state.pdcl[pdc_idx] & PDC_M_MASK) == 0) { - mmu_state.pdcl[pdc_idx] |= PDC_M_MASK; - pd = pread_w(pd_addr); - pwrite_w(pd_addr, pd | PD_M_MASK); - } - - if ((mmu_state.pdcl[pdc_idx] & PDC_R_MASK) == 0) { - mmu_state.pdcl[pdc_idx] |= PDC_R_MASK; - pd = pread_w(pd_addr); - pwrite_w(pd_addr, pd | PD_R_MASK); - } - } - - return SCPE_OK; -} - -/* - * Handle a Page Descriptor cache miss. - * - * - va is the virtual address for the PD. - * - r_acc is the requested access type. - * - fc is the fault check flag. - * - * If there was a miss when reading the SDC, TRUE will be returned in - * "sd_miss". The page descriptor will be returned in "pd", and the - * segment descriptor will be returned in "sd_lo" and "sd_hi". - * - * Returns SCPE_OK on success, SCPE_NXM on failure. If SCPE_NXM is - * returned, a failure code and fault address will be set in the - * appropriate registers. - * - * As always, the flag 'fc' may be set to FALSE to avoid certain - * types of fault checking. - * - * For detailed documentation, See: - * - * "WE 32201 Memory Management Unit Information Manual", AT&T Select - * Code 307-706, February 1987; Figure 2-18, pages 2-24 through 2-25. - */ -t_stat mmu_pdc_miss(uint32 va, uint8 r_acc, t_bool fc, - uint32 *pd, uint32 *pdc_idx) -{ - uint32 sd_ptr, sd_hi, sd_lo, pd_addr; - uint32 indirect_count = 0; - t_bool sdc_miss = FALSE; - - *pdc_idx = 0; - - /* If this was an instruction fetch, the actual requested level - * here will become "Instruction Fetch After Discontinuity" - * due to the page miss. */ - r_acc = (r_acc == ACC_IF ? ACC_IFAD : r_acc); - - /* We immediately do SSL bounds checking. The 'fc' flag is not - * checked because SSL out of bounds is a fatal error. */ - if (SSL(va) > SRAMB_LEN(va)) { - sim_debug(MMU_FAULT_DBG, &mmu_dev, - "[%08x] SDT Length Fault. sramb_len=%x ssl=%x va=%08x\n", - R[NUM_PC], SRAMB_LEN(va), SSL(va), va); - MMU_FAULT(MMU_F_SDTLEN); - return SCPE_NXM; - } - - /* This loop handles segment descriptor indirection (if any) */ - sd_ptr = SD_ADDR(va); - while (1) { - /* Try to find the SD in the cache */ - if (get_sdce(va, &sd_hi, &sd_lo) != SCPE_OK) { - /* This was a miss, so we need to load the SD out of - * memory. */ - sdc_miss = TRUE; - - sd_lo = pread_w(sd_ptr); /* Control Bits */ - sd_hi = pread_w(sd_ptr + 4); /* Address Bits */ - sim_debug(MMU_CACHE_DBG, &mmu_dev, - "[%08x] SDC miss. Read sd_ptr=%08x sd_lo=%08x sd_hi=%08x va=%08x\n", - R[NUM_PC], sd_ptr, sd_lo, sd_hi, va); - } - - if (!SD_VALID(sd_lo)) { - sim_debug(MMU_FAULT_DBG, &mmu_dev, - "[%08x] Invalid Segment Descriptor. va=%08x sd_hi=%08x sd_lo=%08x\n", - R[NUM_PC], va, sd_hi, sd_lo); - MMU_FAULT(MMU_F_INV_SD); - return SCPE_NXM; - } - - if (SD_INDIRECT(sd_lo)) { - if (++indirect_count > MAX_INDIRECTS) { - sim_debug(MMU_FAULT_DBG, &mmu_dev, - "[%08x] Max Indirects Fault. va=%08x sd_hi=%08x sd_lo=%08x\n", - R[NUM_PC], va, sd_hi, sd_lo); - MMU_FAULT(MMU_F_INDIRECT); - return SCPE_NXM; - } - - /* Any permission failure at this point is actually an MMU_F_MISS_MEM */ - if (mmu_check_perm(SD_ACC(sd_lo), r_acc) != SCPE_OK) { - sim_debug(MMU_FAULT_DBG, &mmu_dev, - "[%08x] MMU Miss Processing Memory Fault (SD Access) (ckm=%d pd_acc=%02x r_acc=%02x)\n", - R[NUM_PC], CPU_CM, SD_ACC(sd_lo), r_acc); - MMU_FAULT(MMU_F_MISS_MEM); - return SCPE_NXM; - } - - /* sd_hi is a pointer to a new segment descriptor */ - sd_ptr = sd_hi; - - sd_lo = pread_w(sd_ptr); - sd_hi = pread_w(sd_ptr + 4); - } else { - /* If it's not an indirection, we're done. */ - break; - } - } - - /* Fault if the segment descriptor P bit isn't set */ - if (!SD_PRESENT(sd_lo)) { - /* If the C bit is set, this is a SEGMENT NOT PRESENT - fault; otherwise, it's a PDT NOT PRESENT fault. */ - if (SD_CONTIG(sd_lo)) { - sim_debug(MMU_FAULT_DBG, &mmu_dev, - "[%08x] Segment Not Present. va=%08x\n", - R[NUM_PC], va); - MMU_FAULT(MMU_F_SEG_NOT_PRES); - return SCPE_NXM; - } else { - sim_debug(MMU_FAULT_DBG, &mmu_dev, - "[%08x] PDT Not Present. va=%08x\n", - R[NUM_PC], va); - MMU_FAULT(MMU_F_PDT_NOT_PRES); - return SCPE_NXM; - } - } - - /* Check to see if the segment is too long. */ - if (SD_CONTIG(sd_lo)) { - if (PSL(va) > SD_MAX_OFF(sd_lo)) { - sim_debug(MMU_FAULT_DBG, &mmu_dev, - "[%08x] Segment Offset Fault. va=%08x\n", - R[NUM_PC], va); - MMU_FAULT(MMU_F_SEG_OFFSET); - return SCPE_NXM; - } - } else { - if ((va & 0x1ffff) > MAX_SEG_OFF(sd_lo)) { - sim_debug(MMU_FAULT_DBG, &mmu_dev, - "[%08x] PDT Length Fault. va=%08x max_seg_off=0x%x\n", - R[NUM_PC], va, MAX_SEG_OFF(sd_lo)); - MMU_FAULT(MMU_F_PDTLEN); - return SCPE_NXM; - } - } - - /* Either load or construct the PD */ - if (SD_CONTIG(sd_lo)) { - /* TODO: VERIFY */ - if (mmu_check_perm(SD_ACC(sd_lo), r_acc) != SCPE_OK) { - sim_debug(MMU_FAULT_DBG, &mmu_dev, - "[%08x] [AFTER DISCONTINUITY] Access to Memory Denied (va=%08x ckm=%d pd_acc=%02x r_acc=%02x)\n", - R[NUM_PC], va, CPU_CM, SD_ACC(sd_lo), r_acc); - MMU_FAULT(MMU_F_ACC); - return SCPE_NXM; - } - - /* We have to construct a PD for this SD. */ - *pd = (((sd_hi & pd_addr_masks[MMU_CONF_PS]) + PSL_C(va)) | - ((sd_lo & 0x800000) >> 18) | /* Copy R bit */ - ((sd_lo & 0x400000) >> 21) | /* Copy M bit */ - 1); /* P bit */ - - sim_debug(MMU_CACHE_DBG, &mmu_dev, - "[%08x] Contiguous Segment. Constructing PD. PSIZE=%d va=%08x sd_hi=%08x sd_lo=%08x pd=%08x\n", - R[NUM_PC], MMU_CONF_PS, va, sd_hi, sd_lo, *pd); - } else { - /* We can find the PD in main memory */ - pd_addr = SD_SEG_ADDR(sd_hi) + (PSL(va) * 4); - - *pd = pread_w(pd_addr); - - sim_debug(MMU_CACHE_DBG, &mmu_dev, - "[%08x] Paged Segment. Loaded PD. va=%08x sd_hi=%08x sd_lo=%08x pd_addr=%08x pd=%08x\n", - R[NUM_PC], va, sd_hi, sd_lo, pd_addr, *pd); - } - - if (r_acc == ACC_W && (*pd & PD_W_MASK)) { - sim_debug(MMU_FAULT_DBG, &mmu_dev, - "[%08x] Page Write Fault, pd=%08x va=%08x\n", - R[NUM_PC], *pd, va); - MMU_FAULT(MMU_F_PW); - return SCPE_NXM; - } - - if ((*pd & PD_P_MASK) != PD_P_MASK) { - sim_debug(MMU_FAULT_DBG, &mmu_dev, - "[%08x] Page Not Present Fault. pd=%08x va=%08x\n", - R[NUM_PC], *pd, va); - MMU_FAULT(MMU_F_PAGE_NOT_PRES); - return SCPE_NXM; - } - - /* Finally, cache the PD */ - - if (sdc_miss) { - put_sdce(va, sd_hi, sd_lo); - } - - *pdc_idx = put_pdce(va, sd_lo, *pd); - - return SCPE_OK; -} - -/* - * Translate a virtual address into a physical address. - * - * Note that unlike 'mmu_xlate_addr', this function will _not_ abort - * on failure. The decoded physical address is returned in "pa". If - * the argument "fc" is FALSE, this function will bypass: - * - * - Access flag checks, - * - Cache insertion, - * - Setting MMU fault registers, - * - Modifying segment and page descriptor bits. - * - * In other words, setting "fc" to FALSE does the minimum work - * necessary to translate a virtual address without changing any MMU - * state. The primary use case for this flag is to provide simulator - * debugging access to memory translation while avoiding that access - * undermining the currently running operating system (if any). - * - * This function returns SCPE_OK if translation succeeded, and - * SCPE_NXM if translation failed. - * - */ -t_stat mmu_decode_va(uint32 va, uint8 r_acc, t_bool fc, uint32 *pa) -{ - uint32 pd, pdc_idx; - uint8 pd_acc; - t_stat succ; - - /* - * If the MMU is disabled, virtual == physical. - */ - if (!mmu_state.enabled) { - *pa = va; - return SCPE_OK; - } - - /* - * 1. Check PDC for an entry. - */ - if (get_pdce(va, &pd, &pd_acc, &pdc_idx) == SCPE_OK) { - if (mmu_check_perm(pd_acc, r_acc) != SCPE_OK) { - sim_debug(MMU_FAULT_DBG, &mmu_dev, - "[%08x] Access to Memory Denied (va=%08x ckm=%d pd_acc=%02x r_acc=%02x)\n", - R[NUM_PC], va, CPU_CM, pd_acc, r_acc); - MMU_FAULT(MMU_F_ACC); - return SCPE_NXM; - } - - if (r_acc == ACC_W && (pd & PD_W_MASK)) { - sim_debug(MMU_FAULT_DBG, &mmu_dev, - "[%08x] Page Write Fault, pd=%08x va=%08x\n", - R[NUM_PC], pd, va); - MMU_FAULT(MMU_F_PW); - return SCPE_NXM; - } - } else { - /* Do miss processing. This will cache the PD if necessary. */ - succ = mmu_pdc_miss(va, r_acc, fc, &pd, &pdc_idx); - if (succ != SCPE_OK) { - return succ; - } - } - - /* - * 2. Update history bits - */ - succ = mmu_update_history(va, r_acc, pdc_idx, fc); - if (succ != SCPE_OK) { - return succ; - } - - /* - * 3. Translation from Page Descriptor - */ - *pa = PD_ADDR(pd) + POT(va); - - sim_debug(MMU_TRACE_DBG, &mmu_dev, - "[%08x] XLATE DONE. r_acc=%d va=%08x pa=%08x\n", - R[NUM_PC], r_acc, va, *pa); - - return SCPE_OK; -} - -/* - * Translate a virtual address into a physical address. - * - * This function returns the translated virtual address, and aborts - * without returning if translation failed. - */ -uint32 mmu_xlate_addr(uint32 va, uint8 r_acc) -{ - uint32 pa; - t_stat succ; - - succ = mmu_decode_va(va, r_acc, TRUE, &pa); - - if (succ == SCPE_OK) { - mmu_state.var = va; - return pa; - } else { - cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT); - return 0; - } -} - -/* - * Enable the MMU and allow virtual address translation. - */ -void mmu_enable() -{ - mmu_state.enabled = TRUE; -} - -/* - * Disable the MMU. All memory access will be through physical addresses only. - */ -void mmu_disable() -{ - mmu_state.enabled = FALSE; -} - -CONST char *mmu_description(DEVICE *dptr) -{ - return "WE32201 MMU"; -} - -/* - * Display the segment descriptor cache - */ -t_stat mmu_show_sdc(FILE *st, UNIT *uptr, int32 val, CONST void *desc) -{ - uint32 sd_lo, sd_hi, base, pages, i; - - fprintf(st, "\nSegment Descriptor Cache\n\n"); - - fprintf(st, "start sdc (lo) sdc (hi) sd (lo) sd (hi) C/P seg start pages\n"); - fprintf(st, "-------- -------- -------- -------- -------- --- --------- -----\n"); - - for (i = 0; i < MMU_SDCS; i++) { - sd_lo = SDCE_TO_SDL(mmu_state.sdch[i], mmu_state.sdcl[i]); - sd_hi = SDCE_TO_SDH(mmu_state.sdch[i]); - base = ((mmu_state.sdcl[i] & 0xfff) << 20) | ((i & 7) << 17); - pages = ((sd_lo & SD_MAX_OFF_MASK) >> 18) + 1; - - fprintf(st, "%08x %08x %08x %08x %08x %s %08x %d\n", - base, - mmu_state.sdcl[i], - mmu_state.sdch[i], - sd_lo, sd_hi, - SD_CONTIG(sd_lo) ? "C" : "P", - sd_hi & SD_ADDR_MASK, - pages); - - } - - return SCPE_OK; -} - -t_stat mmu_show_pdc(FILE *st, UNIT *uptr, int32 val, CONST void *desc) -{ - uint32 i, pdc_hi, pdc_lo; - - fprintf(st, "\nPage Descriptor Cache\n\n"); - fprintf(st, "IDX pdc (hi) pdc (lo) U G C W vaddr pd addr\n"); - fprintf(st, "---- -------- -------- - - - - -------- --------\n"); - - for (i = 0; i < MMU_PDCS; i++) { - pdc_hi = mmu_state.pdch[i]; - pdc_lo = mmu_state.pdcl[i]; - - fprintf(st, "%02d %08x %08x %s %s %s %s %08x %08x\n", - i, - pdc_hi, pdc_lo, - pdc_hi & PDC_U_MASK ? "U" : " ", - pdc_hi & PDC_G_MASK ? "G" : " ", - pdc_hi & PDC_C_MASK ? "C" : "P", - pdc_lo & PDC_W_MASK ? "W" : " ", - (pdc_hi & PDC_TAG_MASK) << 6, - PDCE_TO_PD(pdc_lo)); - } - - return SCPE_OK; -} - -/* - * Display the segment table for a section. - */ -t_stat mmu_show_sdt(FILE *st, UNIT *uptr, int32 val, CONST void *desc) -{ - uint32 addr, len, sd_lo, sd_hi, base, pages, i; - uint8 sec; - char *cptr = (char *) desc; - t_stat result; - - if (cptr == NULL) { - fprintf(st, "Missing section number\n"); - return SCPE_ARG; - } - - sec = (uint8) get_uint(cptr, 10, 3, &result); - if (result != SCPE_OK) { - fprintf(st, "Please specify a section from 0-3\n"); - return SCPE_ARG; - } - - addr = mmu_state.sec[sec].addr; - len = mmu_state.sec[sec].len + 1; - - fprintf(st, "\nSection %d SDT\n\n", sec); - fprintf(st, "start end sd (lo) sd (hi) C/P seg start pages\n"); - fprintf(st, "-------- -------- -------- -------- --- --------- ------\n"); - - for (i = 0; i < len; i++) { - sd_lo = pread_w(addr + (i * 8)) & SD_RES_MASK; - sd_hi = pread_w(addr + (i * 8) + 4); - base = (sec << 14 | i << 1) << 16; - pages = ((sd_lo & SD_MAX_OFF_MASK) >> 18) + 1; - - if (SD_VALID(sd_lo)) { - fprintf(st, "%08x-%08x %08x %08x %s %08x %d\n", - base, - base + (((sd_lo & SD_MAX_OFF_MASK) >> 15) * 2048) - 1, - sd_lo, sd_hi, - SD_CONTIG(sd_lo) ? "C" : "P", - sd_hi & SD_ADDR_MASK, - pages); - } - } - - return SCPE_OK; -} +/* 3b2_rev3_mmu.c: WE32201 MMU + + Copyright (c) 2020-2022, Seth J. Morabito + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + Except as contained in this notice, the name of the author shall + not be used in advertising or otherwise to promote the sale, use or + other dealings in this Software without prior written authorization + from the author. +*/ + + +#include "3b2_cpu.h" +#include "3b2_csr.h" +#include "3b2_mem.h" +#include "3b2_mmu.h" + +UNIT mmu_unit = { UDATA(NULL, 0, 0) }; + +MMU_STATE mmu_state; + +REG mmu_reg[] = { + { HRDATAD (ENABLE, mmu_state.enabled, 1, "Enabled?") }, + { HRDATAD (CONFIG, mmu_state.conf, 32, "Configuration") }, + { HRDATAD (VAR, mmu_state.var, 32, "Virtual Address") }, + { HRDATAD (FCODE, mmu_state.fcode, 32, "Fault Code") }, + { HRDATAD (FADDR, mmu_state.faddr, 32, "Fault Address") }, + { BRDATA (SDCL, mmu_state.sdcl, 16, 32, MMU_SDCS) }, + { BRDATA (SDCH, mmu_state.sdch, 16, 32, MMU_SDCS) }, + { BRDATA (PDCL, mmu_state.pdcl, 16, 32, MMU_PDCS) }, + { BRDATA (PDCH, mmu_state.pdch, 16, 32, MMU_PDCS) }, + { BRDATA (SRAMA, mmu_state.sra, 16, 32, MMU_SRS) }, + { BRDATA (SRAMB, mmu_state.srb, 16, 32, MMU_SRS) }, + { NULL } +}; + +#define MMU_EXEC_DBG 1 +#define MMU_TRACE_DBG 1 << 1 +#define MMU_CACHE_DBG 1 << 2 +#define MMU_FAULT_DBG 1 << 3 +#define MMU_READ_DBG 1 << 4 +#define MMU_WRITE_DBG 1 << 5 + +static DEBTAB mmu_debug[] = { + { "EXEC", MMU_EXEC_DBG, "Simple execution" }, + { "CACHE", MMU_CACHE_DBG, "Cache trace" }, + { "TRACE", MMU_TRACE_DBG, "Translation trace" }, + { "FAULT", MMU_FAULT_DBG, "Faults" }, + { "READ", MMU_READ_DBG, "Peripheral Read"}, + { "WRITE", MMU_WRITE_DBG, "Peripheral Write"}, + { NULL } +}; + +MTAB mmu_mod[] = { + { MTAB_XTD|MTAB_VDV|MTAB_NMO|MTAB_SHP, 0, "SDT", NULL, + NULL, &mmu_show_sdt, NULL, "Display SDT for section n [0-3]" }, + { MTAB_XTD|MTAB_VDV|MTAB_NMO, 0, "SDC", NULL, + NULL, &mmu_show_sdc, NULL, "Display SD Cache" }, + { MTAB_XTD|MTAB_VDV|MTAB_NMO, 0, "PDC", NULL, + NULL, &mmu_show_pdc, NULL, "Display PD Cache" }, + { 0 } +}; + +DEVICE mmu_dev = { + "MMU", /* name */ + &mmu_unit, /* units */ + mmu_reg, /* registers */ + mmu_mod, /* modifiers */ + 1, /* #units */ + 16, /* address radix */ + 8, /* address width */ + 4, /* address incr */ + 16, /* data radix */ + 32, /* data width */ + NULL, /* examine routine */ + NULL, /* deposit routine */ + &mmu_init, /* reset routine */ + NULL, /* boot routine */ + NULL, /* attach routine */ + NULL, /* detach routine */ + NULL, /* context */ + DEV_DEBUG, /* flags */ + 0, /* debug control flags */ + mmu_debug, /* debug flag names */ + NULL, /* memory size change */ + NULL, /* logical name */ + NULL, /* help routine */ + NULL, /* attach help routine */ + NULL, /* help context */ + &mmu_description /* device description */ +}; + +/* + * Each bitmask corresponds to the pattern of bits used for the tag in + * the first word of a segment descriptor in the cache. The outer + * index corresponds to mode (0=Single-Context Mode, 1=Multi-Context + * Mode), the inner index corresponds to page size (0=2kB, 1=4kB, + * 2=8kB, 3=undefined) + */ +uint32 pdc_tag_masks[2][4] = { + {0x43ffffe0, 0x43ffffc0, 0x43ffff80, 0}, + {0x7fffffe0, 0x7fffffc0, 0x7fffff80, 0}, +}; + +/* + * Bitmasks for generating page addresses for contiguous segments on + * cache miss. + */ +uint32 pd_addr_masks[4] = { + 0xfffff800, 0xfffff000, 0xffffe000, 0 +}; + +uint32 pd_psl_masks[4] = { + 0x1f800, 0x1f000, 0x1e000, 0 +}; + +/* Masks used when searching the PD cache for a matching tag. */ +#define PDC_TAG_MASK (pdc_tag_masks[MMU_CONF_MCE][MMU_CONF_PS]) + +/* Mask off the bottom 10 bits of virtual address when generating PD + * cache tags */ +#define VA_TO_TAG_MASK 0xfffff800 + +/* + * Macros used to generate PD cache tags from virtual-addresses + */ +#define PDC_MTAG(VA) ((((VA) & VA_TO_TAG_MASK) >> 6) | \ + (mmu_state.cidnr[SID(VA)] << 26) | \ + (1 << 30)) + +#define PDC_STAG(VA) ((((VA) & VA_TO_TAG_MASK) >> 6) | \ + (1 << 30)) + +#define PDC_TAG(VA) (MMU_CONF_MCE ? PDC_MTAG(VA) : PDC_STAG(VA)) + +/* + * Retrieve a Segment Descriptor from the SD cache. The Segment + * Descriptor Cache entry is returned in sd_lo and sd_hi, if found. + * + * If there is a cache hit, this function returns SCPE_OK. + * If there is a cache miss, this function returns SCPE_NXM. + */ +static t_stat get_sdce(uint32 va, uint32 *sd_hi, uint32 *sd_lo) +{ + uint32 hi, lo, va_tag, sdc_tag; + + hi = mmu_state.sdch[SDC_IDX(va)]; + lo = mmu_state.sdcl[SDC_IDX(va)]; + va_tag = (va >> 20) & 0xfff; + sdc_tag = lo & 0xfff; + + if ((hi & SDC_G_MASK) && (va_tag == sdc_tag)) { + *sd_hi = SDCE_TO_SDH(hi); + *sd_lo = SDCE_TO_SDL(hi,lo); + return SCPE_OK; + } + + return SCPE_NXM; +} + +/* + * Insert a Segment Descriptor into the SD cache. + */ +static void put_sdce(uint32 va, uint32 sd_hi, uint32 sd_lo) +{ + uint8 ci = SDC_IDX(va); + + mmu_state.sdch[ci] = SD_TO_SDCH(sd_hi, sd_lo); + mmu_state.sdcl[ci] = SD_TO_SDCL(sd_lo, va); + + sim_debug(MMU_CACHE_DBG, &mmu_dev, + "CACHED SD AT IDX %d. va=%08x sd_hi=%08x sd_lo=%08x sdc_hi=%08x sdc_lo=%08x\n", + ci, va, sd_hi, sd_lo, mmu_state.sdch[ci], mmu_state.sdcl[ci]); + +} + +/* + * Update the "Used" bit in the Page Descriptor cache for the given + * entry. + */ +static void set_u_bit(uint32 index) +{ + uint32 i; + + mmu_state.pdch[index] |= PDC_U_MASK; + + /* Check to see if all U bits have been set. If so, the cache will + * need to be flushed on the next put */ + for (i = 0; i < MMU_PDCS; i++) { + if ((mmu_state.pdch[i] & PDC_U_MASK) == 0) { + return; + } + } + + mmu_state.flush_u = TRUE; +} + +/* + * Retrieve a Page Descriptor Cache Entry from the Page Descriptor + * Cache. + */ +static t_stat get_pdce(uint32 va, uint32 *pd, uint8 *pd_acc, uint32 *pdc_idx) +{ + uint32 i, key_tag, target_tag; + + *pdc_idx = 0; + + /* This is a fully associative cache, so we must scan for an entry + with the correct tag. */ + key_tag = PDC_TAG(va) & PDC_TAG_MASK; + + for (i = 0; i < MMU_PDCS; i++) { + target_tag = mmu_state.pdch[i] & PDC_TAG_MASK; + if (target_tag == key_tag) { + /* Construct the PD from the cached version */ + *pd = PDCE_TO_PD(mmu_state.pdcl[i]); + *pd_acc = (mmu_state.pdcl[i] >> 24) & 0xff; + *pdc_idx = i; + sim_debug(MMU_TRACE_DBG, &mmu_dev, + "PDC HIT. va=%08x idx=%d tag=%03x pd=%08x pdcl=%08x pdch=%08x\n", + va, i, key_tag, *pd, + mmu_state.pdcl[i], mmu_state.pdch[i]); + set_u_bit(i); + return SCPE_OK; + } + } + + sim_debug(MMU_CACHE_DBG, &mmu_dev, + "PDC MISS. va=%08x tag=%03x\n", + va, key_tag); + + return SCPE_NXM; +} + +/* + * Cache a Page Descriptor in the specified slot. + */ +static void put_pdce_at(uint32 va, uint32 sd_lo, uint32 pd, uint32 slot) +{ + mmu_state.pdcl[slot] = PD_TO_PDCL(pd, sd_lo); + mmu_state.pdch[slot] = VA_TO_PDCH(va, sd_lo); + sim_debug(MMU_CACHE_DBG, &mmu_dev, + "Caching MMU PDC entry at index %d (pdc_hi=%08x pdc_lo=%08x va=%08x)\n", + slot, mmu_state.pdch[slot], mmu_state.pdcl[slot], va); + set_u_bit(slot); + mmu_state.last_cached = slot; +} + +/* + * Cache a Page Descriptor in the first available, least recently used + * slot. + */ +static uint32 put_pdce(uint32 va, uint32 sd_lo, uint32 pd) +{ + uint32 i; + + /* + * If all the U bits have been set, flush them all EXCEPT the most + * recently cached entry. + */ + if (mmu_state.flush_u) { + sim_debug(MMU_CACHE_DBG, &mmu_dev, + "Flushing PDC U bits on all-set condition.\n"); + mmu_state.flush_u = FALSE; + for (i = 0; i < MMU_PDCS; i++) { + if (i != mmu_state.last_cached) { + mmu_state.pdch[i] &= ~(PDC_U_MASK); + } + } + } + + /* TODO: This can be done in one pass! Clean it up */ + + /* Cache the Page Descriptor in the first slot with a cleared G + * bit */ + for (i = 0; i < MMU_PDCS; i++) { + if ((mmu_state.pdch[i] & PDC_G_MASK) == 0) { + put_pdce_at(va, sd_lo, pd, i); + return i; + } + } + + /* If ALL slots had their G bit set, find the first slot with a + cleared U bit */ + for (i = 0; i < MMU_PDCS; i++) { + if ((mmu_state.pdch[i] & PDC_U_MASK) == 0) { + put_pdce_at(va, sd_lo, pd, i); + return i; + } + } + + /* This should never happen, since if all U bits become set, they + * are automatically all cleared */ + stop_reason = STOP_MMU; + + return 0; +} + +/* + * Flush the cache for an individual virtual address. + */ +static void flush_pdc(uint32 va) +{ + uint32 i, j, key_tag, target_tag; + + /* Flush the PDC. This is a fully associative cache, so we must + * scan for an entry with the correct tag. */ + + key_tag = PDC_TAG(va) & PDC_TAG_MASK; + + for (i = 0; i < MMU_PDCS; i++) { + target_tag = mmu_state.pdch[i] & PDC_TAG_MASK; + if (target_tag == key_tag) { + sim_debug(MMU_CACHE_DBG, &mmu_dev, + "Flushing MMU PDC entry pdc_lo=%08x pdc_hi=%08x index %d (va=%08x)\n", + mmu_state.pdcl[i], + mmu_state.pdch[i], + i, + va); + if (mmu_state.pdch[i] & PDC_C_MASK) { + sim_debug(MMU_CACHE_DBG, &mmu_dev, + "Flushing MMU PDC entry: CONTIGUOUS\n"); + /* If this PD came from a contiguous SD, we need to + * flush ALL entries belonging to the same SD. All + * pages within the same segment have the same upper + * 11 bits. */ + for (j = 0; j < MMU_PDCS; j++) { + if ((mmu_state.pdch[j] & 0x3ffc000) == + (mmu_state.pdch[i] & 0x3ffc000)) { + mmu_state.pdch[j] &= ~(PDC_G_MASK|PDC_U_MASK); + } + } + } else { + /* Otherwise, just flush the one entry */ + mmu_state.pdch[i] &= ~(PDC_G_MASK|PDC_U_MASK); + } + return; + } + } + + sim_debug(MMU_CACHE_DBG, &mmu_dev, + "Flushing MMU PDC entry: NOT FOUND (va=%08x key_tag=%08x)\n", + va, key_tag); + +} + +/* + * Flush all entries in both SDC and PDC. + */ +static void flush_caches() +{ + uint32 i; + + sim_debug(MMU_CACHE_DBG, &mmu_dev, + "Flushing MMU PDC and SDC\n"); + + for (i = 0; i < MMU_SDCS; i++) { + mmu_state.sdch[i] &= ~SDC_G_MASK; + } + + for (i = 0; i < MMU_PDCS; i++) { + mmu_state.pdch[i] &= ~PDC_G_MASK; + mmu_state.pdch[i] &= ~PDC_U_MASK; + } +} + +/* + * Check permissions for a set of permission flags and an access type. + * + * Return SCPE_OK if permission is granted, SCPE_NXM if permission is + * not allowed. + */ +static t_stat mmu_check_perm(uint8 flags, uint8 r_acc) +{ + switch(MMU_PERM(flags)) { + case 0: /* No Access */ + return SCPE_NXM; + case 1: /* Exec Only */ + if (r_acc != ACC_IF && + r_acc != ACC_IFAD) { + return SCPE_NXM; + } + return SCPE_OK; + case 2: /* Read / Execute */ + if (r_acc != ACC_IF && + r_acc != ACC_IFAD && + r_acc != ACC_OF && + r_acc != ACC_AF && + r_acc != ACC_MT) { + return SCPE_NXM; + } + return SCPE_OK; + default: + return SCPE_OK; + } +} + +/* + * Initialize the MMU device + */ +t_stat mmu_init(DEVICE *dptr) +{ + flush_caches(); + return SCPE_OK; +} + +/* + * Memory-mapped (peripheral mode) read of the MMU device + */ +uint32 mmu_read(uint32 pa, size_t size) +{ + uint8 entity, index; + uint32 data = 0; + + /* Register entity */ + entity = ((uint8)(pa >> 8)) & 0xf; + + /* Index into entity */ + index = (uint8)((pa >> 2) & 0x1f); + + switch (entity) { + case MMU_SDCL: + data = mmu_state.sdcl[index]; + sim_debug(MMU_READ_DBG, &mmu_dev, + "MMU_SDCL[%d] = %08x\n", + index, data); + break; + case MMU_SDCH: + data = mmu_state.sdch[index]; + sim_debug(MMU_READ_DBG, &mmu_dev, + "MMU_SDCH[%d] = %08x\n", + index, data); + break; + case MMU_PDCL: + data = mmu_state.pdcl[index]; + sim_debug(MMU_READ_DBG, &mmu_dev, + "MMU_PDCL[%d] = %08x\n", + index, data); + break; + case MMU_PDCH: + data = mmu_state.pdch[index]; + sim_debug(MMU_READ_DBG, &mmu_dev, + "MMU_PDCH[%d] = %08x\n", + index, data); + break; + case MMU_SRAMA: + data = mmu_state.sra[index]; + sim_debug(MMU_READ_DBG, &mmu_dev, + "MMU_SRAMA[%d] = %08x\n", + index, data); + break; + case MMU_SRAMB: + data = mmu_state.srb[index]; + sim_debug(MMU_READ_DBG, &mmu_dev, + "MMU_SRAMB[%d] = %08x\n", + index, data); + break; + case MMU_FC: + data = mmu_state.fcode; + sim_debug(MMU_READ_DBG, &mmu_dev, + "MMU_FC = %08x\n", + data); + break; + case MMU_FA: + data = mmu_state.faddr; + sim_debug(MMU_READ_DBG, &mmu_dev, + "MMU_FA = %08x\n", + data); + break; + case MMU_CONF: + data = mmu_state.conf; + sim_debug(MMU_READ_DBG, &mmu_dev, + "MMU_CONF = %02x (M=%d R=%d $=%d PS=%d MCE=%d DCE=%d)\n", + data, + MMU_CONF_M, + MMU_CONF_R, + MMU_CONF_C, + MMU_CONF_PS, + MMU_CONF_MCE, + MMU_CONF_DCE); + break; + case MMU_VAR: + data = mmu_state.var; + sim_debug(MMU_READ_DBG, &mmu_dev, + "MMU_VAR = %08x\n", + data); + break; + case MMU_IDC: + /* TODO: Implement */ + data = 0; + sim_debug(MMU_READ_DBG, &mmu_dev, + "MMU_IDC\n"); + break; + case MMU_IDNR: + /* TODO: Implement */ + data = 0; + sim_debug(MMU_READ_DBG, &mmu_dev, + "MMU_IDNR\n"); + break; + case MMU_FIDNR: + /* TODO: Implement */ + data = 0; + sim_debug(MMU_READ_DBG, &mmu_dev, + "MMU_FIDNR\n"); + break; + case MMU_VR: + data = MMU_REV3_VER; + sim_debug(MMU_READ_DBG, &mmu_dev, + "MMU_VR = 0x23\n"); + break; + default: + sim_debug(MMU_READ_DBG, &mmu_dev, + "Invalid MMU register: pa=%08x\n", + pa); + CSRBIT(CSRTIMO, TRUE); + break; + } + + return data; +} + +void mmu_write(uint32 pa, uint32 val, size_t size) +{ + uint32 index, entity, i; + + /* Register entity */ + entity = ((uint8)(pa >> 8)) & 0xf; + + /* Index into entity */ + index = (uint8)((pa >> 2) & 0x1f); + + switch (entity) { + case MMU_SDCL: + sim_debug(MMU_WRITE_DBG, &mmu_dev, + "MMU_SDCL[%d] = %08x\n", + index, val); + mmu_state.sdcl[index] = val; + break; + case MMU_SDCH: + sim_debug(MMU_WRITE_DBG, &mmu_dev, + "MMU_SDCH[%d] = %08x\n", + index, val); + mmu_state.sdch[index] = val; + break; + case MMU_PDCL: + sim_debug(MMU_WRITE_DBG, &mmu_dev, + "MMU_PDCL[%d] = %08x\n", + index, val); + mmu_state.pdcl[index] = val; + break; + case MMU_PDCH: + sim_debug(MMU_WRITE_DBG, &mmu_dev, + "MMU_PDCH[%d] = %08x\n", + index, val); + mmu_state.pdch[index] = val; + break; + case MMU_FDCR: + sim_debug(MMU_WRITE_DBG, &mmu_dev, + "MMU_FDCR\n"); + /* Data cache is not implemented */ + break; + case MMU_SRAMA: + index = index & 3; + sim_debug(MMU_WRITE_DBG, &mmu_dev, + "MMU_SRAMA[%d] = %08x\n", + index, val); + mmu_state.sra[index] = val; + mmu_state.sec[index].addr = val & 0xfffffffc; + + /* Flush all SDC cache entries for this section */ + for (i = 0; i < MMU_SDCS; i++) { + if (((mmu_state.sdcl[i] >> 10) & 0x3) == index) { + sim_debug(MMU_CACHE_DBG, &mmu_dev, + "Flushing MMU SDC entry at index %d " + "(sdc_lo=%08x sdc_hi=%08x)\n", + i, mmu_state.sdcl[i], mmu_state.sdch[i]); + mmu_state.sdch[i] &= ~(SDC_G_MASK); + } + } + + /* Flush all PDC cache entries for this section */ + for (i = 0; i < MMU_PDCS; i++) { + if (((mmu_state.pdch[i] >> 24) & 0x3) == index) { + mmu_state.pdch[i] &= ~(PDC_G_MASK); + } + } + break; + case MMU_SRAMB: + index = index & 3; + mmu_state.srb[index] = val; + mmu_state.sec[index].len = (val >> 10) & 0x1fff; + /* We do not flush the cache on writing SRAMB */ + sim_debug(MMU_WRITE_DBG, &mmu_dev, + "MMU_SRAMB[%d] length=%04x (%d segments)\n", + index, + mmu_state.sec[index].len, + mmu_state.sec[index].len + 1); + break; + case MMU_FC: + /* Set a default value */ + mmu_state.fcode = (((CPU_CM) << 5) | (0xa << 7)); + sim_debug(MMU_WRITE_DBG, &mmu_dev, + "MMU_FC = %08x\n", + mmu_state.fcode); + break; + case MMU_FA: + mmu_state.faddr = val; + sim_debug(MMU_WRITE_DBG, &mmu_dev, + "MMU_FADDR = %08x\n", + val); + break; + case MMU_CONF: + mmu_state.conf = val & 0x7f; + sim_debug(MMU_WRITE_DBG, &mmu_dev, + "MMU_CONF = %02x (M=%d R=%d $=%d PS=%d MCE=%d DCE=%d)\n", + val, + MMU_CONF_M, + MMU_CONF_R, + MMU_CONF_C, + MMU_CONF_PS, + MMU_CONF_MCE, + MMU_CONF_DCE); + break; + case MMU_VAR: + mmu_state.var = val; + sim_debug(MMU_WRITE_DBG, &mmu_dev, + "MMU_VAR = %08x\n", val); + if ((mmu_state.sdcl[SDC_IDX(val)] & SDC_VADDR_MASK) == + ((val >> 20) & SDC_VADDR_MASK)) { + sim_debug(MMU_CACHE_DBG, &mmu_dev, + "Flushing MMU SDC entry at index %d " + "(sdc_lo=%08x sdc_hi=%08x)\n", + SDC_IDX(val), + mmu_state.sdcl[SDC_IDX(val)], + mmu_state.sdch[SDC_IDX(val)]); + mmu_state.sdch[SDC_IDX(val)] &= ~SDC_G_MASK; + } + flush_pdc(val); + break; + case MMU_IDC: + sim_debug(MMU_WRITE_DBG, &mmu_dev, + "MMU_IDC = %08x\n", + val); + break; + case MMU_IDNR: + sim_debug(MMU_WRITE_DBG, &mmu_dev, + "MMU_IDNR = %08x\n", + val); + break; + case MMU_FIDNR: + sim_debug(MMU_WRITE_DBG, &mmu_dev, + "MMU_FIDNR = %08x\n", + val); + break; + case MMU_VR: + sim_debug(MMU_WRITE_DBG, &mmu_dev, + "MMU_VR = %08x\n", + val); + break; + default: + sim_debug(MMU_WRITE_DBG, &mmu_dev, + "UNHANDLED WRITE (entity=0x%x, index=0x%x, val=%08x)\n", + entity, index, val); + break; + } +} + +/* + * Update history bits in cache and memory. + */ +static t_stat mmu_update_history(uint32 va, uint8 r_acc, uint32 pdc_idx, t_bool fc) +{ + uint32 sd_hi, sd_lo, pd; + uint32 pd_addr; + t_bool update_sdc = TRUE; + + if (get_sdce(va, &sd_hi, &sd_lo) != SCPE_OK) { + update_sdc = FALSE; + } + + sd_lo = pread_w(SD_ADDR(va), BUS_PER); + sd_hi = pread_w(SD_ADDR(va) + 4, BUS_PER); + + if (MMU_CONF_M && r_acc == ACC_W && (mmu_state.sdcl[SDC_IDX(va)] & SDC_M_MASK) == 0) { + if (update_sdc) { + mmu_state.sdcl[SDC_IDX(va)] |= SDC_M_MASK; + } + + if (mmu_check_perm(SD_ACC(sd_lo), r_acc) != SCPE_OK) { + sim_debug(MMU_FAULT_DBG, &mmu_dev, + "MMU R&M Update Fault (M)\n"); + MMU_FAULT(MMU_F_RM_UPD); + return SCPE_NXM; + } + + pwrite_w(SD_ADDR(va), sd_lo | SD_M_MASK, BUS_PER); + } + + if (MMU_CONF_R && (mmu_state.sdcl[SDC_IDX(va)] & SDC_R_MASK) == 0) { + if (update_sdc) { + mmu_state.sdcl[SDC_IDX(va)] |= SDC_R_MASK; + } + + if (mmu_check_perm(SD_ACC(sd_lo), r_acc) != SCPE_OK) { + sim_debug(MMU_FAULT_DBG, &mmu_dev, + "MMU R&M Update Fault (R)\n"); + MMU_FAULT(MMU_F_RM_UPD); + return SCPE_NXM; + } + + pwrite_w(SD_ADDR(va), sd_lo | SD_R_MASK, BUS_PER); + } + + if (!SD_CONTIG(sd_lo)) { + pd_addr = SD_SEG_ADDR(sd_hi) + (PSL(va) * 4); + + if (r_acc == ACC_W && (mmu_state.pdcl[pdc_idx] & PDC_M_MASK) == 0) { + mmu_state.pdcl[pdc_idx] |= PDC_M_MASK; + pd = pread_w(pd_addr, BUS_PER); + pwrite_w(pd_addr, pd | PD_M_MASK, BUS_PER); + } + + if ((mmu_state.pdcl[pdc_idx] & PDC_R_MASK) == 0) { + mmu_state.pdcl[pdc_idx] |= PDC_R_MASK; + pd = pread_w(pd_addr, BUS_PER); + pwrite_w(pd_addr, pd | PD_R_MASK, BUS_PER); + } + } + + return SCPE_OK; +} + +/* + * Handle a Page Descriptor cache miss. + * + * - va is the virtual address for the PD. + * - r_acc is the requested access type. + * - fc is the fault check flag. + * + * If there was a miss when reading the SDC, TRUE will be returned in + * "sd_miss". The page descriptor will be returned in "pd", and the + * segment descriptor will be returned in "sd_lo" and "sd_hi". + * + * Returns SCPE_OK on success, SCPE_NXM on failure. If SCPE_NXM is + * returned, a failure code and fault address will be set in the + * appropriate registers. + * + * As always, the flag 'fc' may be set to FALSE to avoid certain + * types of fault checking. + * + * For detailed documentation, See: + * + * "WE 32201 Memory Management Unit Information Manual", AT&T Select + * Code 307-706, February 1987; Figure 2-18, pages 2-24 through 2-25. + */ +t_stat mmu_pdc_miss(uint32 va, uint8 r_acc, t_bool fc, + uint32 *pd, uint32 *pdc_idx) +{ + uint32 sd_ptr, sd_hi, sd_lo, pd_addr; + uint32 indirect_count = 0; + t_bool sdc_miss = FALSE; + + *pdc_idx = 0; + + /* If this was an instruction fetch, the actual requested level + * here will become "Instruction Fetch After Discontinuity" + * due to the page miss. */ + r_acc = (r_acc == ACC_IF ? ACC_IFAD : r_acc); + + /* We immediately do SSL bounds checking. The 'fc' flag is not + * checked because SSL out of bounds is a fatal error. */ + if (SSL(va) > SRAMB_LEN(va)) { + sim_debug(MMU_FAULT_DBG, &mmu_dev, + "SDT Length Fault. sramb_len=%x ssl=%x va=%08x\n", + SRAMB_LEN(va), SSL(va), va); + MMU_FAULT(MMU_F_SDTLEN); + return SCPE_NXM; + } + + /* This loop handles segment descriptor indirection (if any) */ + sd_ptr = SD_ADDR(va); + while (1) { + /* Try to find the SD in the cache */ + if (get_sdce(va, &sd_hi, &sd_lo) != SCPE_OK) { + /* This was a miss, so we need to load the SD out of + * memory. */ + sdc_miss = TRUE; + + sd_lo = pread_w(sd_ptr, BUS_PER); /* Control Bits */ + sd_hi = pread_w(sd_ptr + 4, BUS_PER); /* Address Bits */ + sim_debug(MMU_CACHE_DBG, &mmu_dev, + "SDC miss. Read sd_ptr=%08x sd_lo=%08x sd_hi=%08x va=%08x\n", + sd_ptr, sd_lo, sd_hi, va); + } + + if (!SD_VALID(sd_lo)) { + sim_debug(MMU_FAULT_DBG, &mmu_dev, + "Invalid Segment Descriptor. va=%08x sd_hi=%08x sd_lo=%08x\n", + va, sd_hi, sd_lo); + MMU_FAULT(MMU_F_INV_SD); + return SCPE_NXM; + } + + if (SD_INDIRECT(sd_lo)) { + if (++indirect_count > MAX_INDIRECTS) { + sim_debug(MMU_FAULT_DBG, &mmu_dev, + "Max Indirects Fault. va=%08x sd_hi=%08x sd_lo=%08x\n", + va, sd_hi, sd_lo); + MMU_FAULT(MMU_F_INDIRECT); + return SCPE_NXM; + } + + /* Any permission failure at this point is actually an MMU_F_MISS_MEM */ + if (mmu_check_perm(SD_ACC(sd_lo), r_acc) != SCPE_OK) { + sim_debug(MMU_FAULT_DBG, &mmu_dev, + "MMU Miss Processing Memory Fault (SD Access) (ckm=%d pd_acc=%02x r_acc=%02x)\n", + CPU_CM, SD_ACC(sd_lo), r_acc); + MMU_FAULT(MMU_F_MISS_MEM); + return SCPE_NXM; + } + + /* sd_hi is a pointer to a new segment descriptor */ + sd_ptr = sd_hi; + + sd_lo = pread_w(sd_ptr, BUS_PER); + sd_hi = pread_w(sd_ptr + 4, BUS_PER); + } else { + /* If it's not an indirection, we're done. */ + break; + } + } + + /* Fault if the segment descriptor P bit isn't set */ + if (!SD_PRESENT(sd_lo)) { + /* If the C bit is set, this is a SEGMENT NOT PRESENT + fault; otherwise, it's a PDT NOT PRESENT fault. */ + if (SD_CONTIG(sd_lo)) { + sim_debug(MMU_FAULT_DBG, &mmu_dev, + "Segment Not Present. va=%08x\n", + va); + MMU_FAULT(MMU_F_SEG_NOT_PRES); + return SCPE_NXM; + } else { + sim_debug(MMU_FAULT_DBG, &mmu_dev, + "PDT Not Present. va=%08x\n", + va); + MMU_FAULT(MMU_F_PDT_NOT_PRES); + return SCPE_NXM; + } + } + + /* Check to see if the segment is too long. */ + if (SD_CONTIG(sd_lo)) { + if (PSL(va) > SD_MAX_OFF(sd_lo)) { + sim_debug(MMU_FAULT_DBG, &mmu_dev, + "Segment Offset Fault. va=%08x\n", + va); + MMU_FAULT(MMU_F_SEG_OFFSET); + return SCPE_NXM; + } + } else { + if ((va & 0x1ffff) > MAX_SEG_OFF(sd_lo)) { + sim_debug(MMU_FAULT_DBG, &mmu_dev, + "PDT Length Fault. va=%08x max_seg_off=0x%x\n", + va, MAX_SEG_OFF(sd_lo)); + MMU_FAULT(MMU_F_PDTLEN); + return SCPE_NXM; + } + } + + /* Either load or construct the PD */ + if (SD_CONTIG(sd_lo)) { + /* TODO: VERIFY */ + if (mmu_check_perm(SD_ACC(sd_lo), r_acc) != SCPE_OK) { + sim_debug(MMU_FAULT_DBG, &mmu_dev, + "[AFTER DISCONTINUITY] Access to Memory Denied (va=%08x ckm=%d pd_acc=%02x r_acc=%02x)\n", + va, CPU_CM, SD_ACC(sd_lo), r_acc); + MMU_FAULT(MMU_F_ACC); + return SCPE_NXM; + } + + /* We have to construct a PD for this SD. */ + *pd = (((sd_hi & pd_addr_masks[MMU_CONF_PS]) + PSL_C(va)) | + ((sd_lo & 0x800000) >> 18) | /* Copy R bit */ + ((sd_lo & 0x400000) >> 21) | /* Copy M bit */ + 1); /* P bit */ + + sim_debug(MMU_CACHE_DBG, &mmu_dev, + "Contiguous Segment. Constructing PD. PSIZE=%d va=%08x sd_hi=%08x sd_lo=%08x pd=%08x\n", + MMU_CONF_PS, va, sd_hi, sd_lo, *pd); + } else { + /* We can find the PD in main memory */ + pd_addr = SD_SEG_ADDR(sd_hi) + (PSL(va) * 4); + + *pd = pread_w(pd_addr, BUS_PER); + + sim_debug(MMU_CACHE_DBG, &mmu_dev, + "Paged Segment. Loaded PD. va=%08x sd_hi=%08x sd_lo=%08x pd_addr=%08x pd=%08x\n", + va, sd_hi, sd_lo, pd_addr, *pd); + } + + if (r_acc == ACC_W && (*pd & PD_W_MASK)) { + sim_debug(MMU_FAULT_DBG, &mmu_dev, + "Page Write Fault, pd=%08x va=%08x\n", + *pd, va); + MMU_FAULT(MMU_F_PW); + return SCPE_NXM; + } + + if ((*pd & PD_P_MASK) != PD_P_MASK) { + sim_debug(MMU_FAULT_DBG, &mmu_dev, + "Page Not Present Fault. pd=%08x va=%08x\n", + *pd, va); + MMU_FAULT(MMU_F_PAGE_NOT_PRES); + return SCPE_NXM; + } + + /* Finally, cache the PD */ + + if (sdc_miss) { + put_sdce(va, sd_hi, sd_lo); + } + + *pdc_idx = put_pdce(va, sd_lo, *pd); + + return SCPE_OK; +} + +/* + * Translate a virtual address into a physical address. + * + * Note that unlike 'mmu_xlate_addr', this function will _not_ abort + * on failure. The decoded physical address is returned in "pa". If + * the argument "fc" is FALSE, this function will bypass: + * + * - Access flag checks, + * - Cache insertion, + * - Setting MMU fault registers, + * - Modifying segment and page descriptor bits. + * + * In other words, setting "fc" to FALSE does the minimum work + * necessary to translate a virtual address without changing any MMU + * state. The primary use case for this flag is to provide simulator + * debugging access to memory translation while avoiding that access + * undermining the currently running operating system (if any). + * + * This function returns SCPE_OK if translation succeeded, and + * SCPE_NXM if translation failed. + * + */ +t_stat mmu_decode_va(uint32 va, uint8 r_acc, t_bool fc, uint32 *pa) +{ + uint32 pd, pdc_idx; + uint8 pd_acc; + t_stat succ; + + /* + * If the MMU is disabled, virtual == physical. + */ + if (!mmu_state.enabled) { + *pa = va; + return SCPE_OK; + } + + /* + * 1. Check PDC for an entry. + */ + if (get_pdce(va, &pd, &pd_acc, &pdc_idx) == SCPE_OK) { + if (mmu_check_perm(pd_acc, r_acc) != SCPE_OK) { + sim_debug(MMU_FAULT_DBG, &mmu_dev, + "Access to Memory Denied (va=%08x ckm=%d pd_acc=%02x r_acc=%02x)\n", + va, CPU_CM, pd_acc, r_acc); + MMU_FAULT(MMU_F_ACC); + return SCPE_NXM; + } + + if (r_acc == ACC_W && (pd & PD_W_MASK)) { + sim_debug(MMU_FAULT_DBG, &mmu_dev, + "Page Write Fault, pd=%08x va=%08x\n", + pd, va); + MMU_FAULT(MMU_F_PW); + return SCPE_NXM; + } + } else { + /* Do miss processing. This will cache the PD if necessary. */ + succ = mmu_pdc_miss(va, r_acc, fc, &pd, &pdc_idx); + if (succ != SCPE_OK) { + return succ; + } + } + + /* + * 2. Update history bits + */ + succ = mmu_update_history(va, r_acc, pdc_idx, fc); + if (succ != SCPE_OK) { + return succ; + } + + /* + * 3. Translation from Page Descriptor + */ + *pa = PD_ADDR(pd) + POT(va); + + sim_debug(MMU_TRACE_DBG, &mmu_dev, + "XLATE DONE. r_acc=%d va=%08x pa=%08x\n", + r_acc, va, *pa); + + return SCPE_OK; +} + +/* + * Translate a virtual address into a physical address. + * + * This function returns the translated virtual address, and aborts + * without returning if translation failed. + */ +uint32 mmu_xlate_addr(uint32 va, uint8 r_acc) +{ + uint32 pa; + t_stat succ; + + succ = mmu_decode_va(va, r_acc, TRUE, &pa); + + if (succ == SCPE_OK) { + mmu_state.var = va; + return pa; + } else { + cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT); + return 0; + } +} + +/* + * Enable the MMU and allow virtual address translation. + */ +void mmu_enable() +{ + mmu_state.enabled = TRUE; +} + +/* + * Disable the MMU. All memory access will be through physical addresses only. + */ +void mmu_disable() +{ + mmu_state.enabled = FALSE; +} + +CONST char *mmu_description(DEVICE *dptr) +{ + return "WE32201 MMU"; +} + +/* + * Display the segment descriptor cache + */ +t_stat mmu_show_sdc(FILE *st, UNIT *uptr, int32 val, CONST void *desc) +{ + uint32 sd_lo, sd_hi, base, pages, i; + + fprintf(st, "\nSegment Descriptor Cache\n\n"); + + fprintf(st, "start sdc (lo) sdc (hi) sd (lo) sd (hi) C/P seg start pages\n"); + fprintf(st, "-------- -------- -------- -------- -------- --- --------- -----\n"); + + for (i = 0; i < MMU_SDCS; i++) { + sd_lo = SDCE_TO_SDL(mmu_state.sdch[i], mmu_state.sdcl[i]); + sd_hi = SDCE_TO_SDH(mmu_state.sdch[i]); + base = ((mmu_state.sdcl[i] & 0xfff) << 20) | ((i & 7) << 17); + pages = ((sd_lo & SD_MAX_OFF_MASK) >> 18) + 1; + + fprintf(st, "%08x %08x %08x %08x %08x %s %08x %d\n", + base, + mmu_state.sdcl[i], + mmu_state.sdch[i], + sd_lo, sd_hi, + SD_CONTIG(sd_lo) ? "C" : "P", + sd_hi & SD_ADDR_MASK, + pages); + + } + + return SCPE_OK; +} + +t_stat mmu_show_pdc(FILE *st, UNIT *uptr, int32 val, CONST void *desc) +{ + uint32 i, pdc_hi, pdc_lo; + + fprintf(st, "\nPage Descriptor Cache\n\n"); + fprintf(st, "IDX pdc (hi) pdc (lo) U G C W vaddr pd addr\n"); + fprintf(st, "---- -------- -------- - - - - -------- --------\n"); + + for (i = 0; i < MMU_PDCS; i++) { + pdc_hi = mmu_state.pdch[i]; + pdc_lo = mmu_state.pdcl[i]; + + fprintf(st, "%02d %08x %08x %s %s %s %s %08x %08x\n", + i, + pdc_hi, pdc_lo, + pdc_hi & PDC_U_MASK ? "U" : " ", + pdc_hi & PDC_G_MASK ? "G" : " ", + pdc_hi & PDC_C_MASK ? "C" : "P", + pdc_lo & PDC_W_MASK ? "W" : " ", + (pdc_hi & PDC_TAG_MASK) << 6, + PDCE_TO_PD(pdc_lo)); + } + + return SCPE_OK; +} + +/* + * Display the segment table for a section. + */ +t_stat mmu_show_sdt(FILE *st, UNIT *uptr, int32 val, CONST void *desc) +{ + uint32 addr, len, sd_lo, sd_hi, base, pages, i; + uint8 sec; + char *cptr = (char *) desc; + t_stat result; + + if (cptr == NULL) { + fprintf(st, "Missing section number\n"); + return SCPE_ARG; + } + + sec = (uint8) get_uint(cptr, 10, 3, &result); + if (result != SCPE_OK) { + fprintf(st, "Please specify a section from 0-3\n"); + return SCPE_ARG; + } + + addr = mmu_state.sec[sec].addr; + len = mmu_state.sec[sec].len + 1; + + fprintf(st, "\nSection %d SDT\n\n", sec); + fprintf(st, "start end sd (lo) sd (hi) C/P seg start pages\n"); + fprintf(st, "-------- -------- -------- -------- --- --------- ------\n"); + + for (i = 0; i < len; i++) { + sd_lo = pread_w(addr + (i * 8), BUS_PER) & SD_RES_MASK; + sd_hi = pread_w(addr + (i * 8) + 4, BUS_PER); + base = (sec << 14 | i << 1) << 16; + pages = ((sd_lo & SD_MAX_OFF_MASK) >> 18) + 1; + + if (SD_VALID(sd_lo)) { + fprintf(st, "%08x-%08x %08x %08x %s %08x %d\n", + base, + base + (((sd_lo & SD_MAX_OFF_MASK) >> 15) * 2048) - 1, + sd_lo, sd_hi, + SD_CONTIG(sd_lo) ? "C" : "P", + sd_hi & SD_ADDR_MASK, + pages); + } + } + + return SCPE_OK; +} diff --git a/3B2/3b2_rev3_mmu.h b/3B2/3b2_rev3_mmu.h index a946553a..d78edb4c 100644 --- a/3B2/3b2_rev3_mmu.h +++ b/3B2/3b2_rev3_mmu.h @@ -1,356 +1,358 @@ -/* 3b2_rev3_mmu.h: AT&T 3B2/600G MMU (WE32201) Header - - Copyright (c) 2020, Seth J. Morabito - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - - Except as contained in this notice, the name of the author shall - not be used in advertising or otherwise to promote the sale, use or - other dealings in this Software without prior written authorization - from the author. -*/ - -#ifndef _3B2_1000_MMU_H_ -#define _3B2_1000_MMU_H_ - -#include "3b2_defs.h" - -#define MMU_SRS 4 /* Section RAM array size (words) */ -#define MMU_SDCS 8 /* SD Cache H/L array size */ -#define MMU_PDCS 64 /* PD Cache H/L array size */ -#define MMU_IDNCS 16 /* ID Number Cache array size */ - -/* Register address offsets */ -#define MMU_SDCL 0 /* SDC - Low Bits */ -#define MMU_SDCH 1 /* SDC - High Bits */ -#define MMU_PDCL 2 /* PDC - Low Bits */ -#define MMU_PDCH 3 /* PDC - High Bits */ -#define MMU_FDCR 4 /* Flush Data Cache Register */ -#define MMU_SRAMA 6 /* Section RAM A */ -#define MMU_SRAMB 7 /* Section RAM B */ -#define MMU_FC 8 /* Fault Code */ -#define MMU_FA 9 /* Fault Address */ -#define MMU_CONF 10 /* Configuration */ -#define MMU_VAR 11 /* Virtual Address Register */ -#define MMU_IDC 12 /* ID Number Cache */ -#define MMU_IDNR 13 /* ID Number Register */ -#define MMU_FIDNR 14 /* Flush ID Number Register */ -#define MMU_VR 15 /* Version Register */ - -#define MMU_CONF_M (mmu_state.conf & 0x1) -#define MMU_CONF_R ((mmu_state.conf & 0x2) >> 1) -#define MMU_CONF_C ((mmu_state.conf & 0x4) >> 1) -#define MMU_CONF_PS ((mmu_state.conf & 0x18) >> 3) -#define MMU_CONF_MCE ((mmu_state.conf & 0x20) >> 5) -#define MMU_CONF_DCE ((mmu_state.conf & 0x40) >> 6) - -/* Shift and mask the flag bits for the current CPU mode */ -#define MMU_PERM(f) ((f >> ((3 - (CPU_CM)) * 2)) & 3) - -/* Codes set in the MMU Fault register */ -#define MMU_F_MISS_MEM 1 -#define MMU_F_RM_UPD 2 -#define MMU_F_SDTLEN 3 -#define MMU_F_PW 4 -#define MMU_F_PDTLEN 5 -#define MMU_F_INV_SD 6 -#define MMU_F_SEG_NOT_PRES 7 -#define MMU_F_PDT_NOT_PRES 9 -#define MMU_F_PAGE_NOT_PRES 10 -#define MMU_F_INDIRECT 11 -#define MMU_F_ACC 13 -#define MMU_F_SEG_OFFSET 14 - -/* Access Request types */ -#define ACC_MT 0 /* Move Translated */ -#define ACC_SPW 1 /* Support processor write */ -#define ACC_SPF 3 /* Support processor fetch */ -#define ACC_IR 7 /* Interlocked read */ -#define ACC_AF 8 /* Address fetch */ -#define ACC_OF 9 /* Operand fetch */ -#define ACC_W 10 /* Write */ -#define ACC_IFAD 12 /* Instruction fetch after discontinuity */ -#define ACC_IF 13 /* Instruction fetch */ - -/* Pluck out Virtual Address fields */ -#define SID(va) (((va) >> 30) & 3) -#define SSL(va) (((va) >> 17) & 0x1fff) -#define SOT(va) (va & 0x1ffff) - -/* PSL will be either: - * - Bits 11-16 (2K pages: MMU_CONF_PS = 0) - * - Bits 12-16 (4K pages: MMU_CONF_PS = 1) - * - Bits 13-16 (8K pages: MMU_CONF_PS = 2) - */ -#define PSL(va) (((va) >> (11 + MMU_CONF_PS)) & (0x3f >> MMU_CONF_PS)) -#define PSL_C(va) (((va) & pd_psl_masks[MMU_CONF_PS])) - -/* POT will be either: - * - Bits 0-10 (2K pages: MMU_CONF_PS = 0) - * - Bits 0-11 (4K pages: MMU_CONF_PS = 1) - * - Bits 0-12 (8K pages: MMU_CONF_PS = 2) - */ -#define POT(va) ((va) & (0x1fff >> (2 - (MMU_CONF_PS)))) - -/* Get the maximum length of an SSL from SRAMB */ -#define SRAMB_LEN(va) (mmu_state.sec[SID(va)].len) - -/* Pluck out Segment Descriptor fields */ -#define SD_PRESENT(sd_lo) ((sd_lo) & 1) -#define SD_MODIFIED(sd_lo) (((sd_lo) >> 1) & 1) -#define SD_CONTIG(sd_lo) (((sd_lo) >> 2) & 1) -#define SD_VALID(sd_lo) (((sd_lo) >> 6) & 1) -#define SD_INDIRECT(sd_lo) (((sd_lo) >> 7) & 1) -#define SD_MAX_OFF(sd_lo) (((sd_lo) >> 18) & 0x3f) -#define SD_ACC(sd_lo) (((sd_lo) >> 24) & 0xff) - -#define SD_SEG_ADDR(sd_hi) ((sd_hi) & 0xfffffff8u) - -#define SD_P_MASK 0x1 -#define SD_M_MASK 0x2 -#define SD_C_MASK 0x4 -#define SD_CACHE_MASK 0x8 -#define SD_R_MASK 0x20 -#define SD_V_MASK 0x40 -#define SD_MAX_OFF_MASK 0xfc0000 -#define SD_ACC_MASK 0xff000000u -#define SD_ADDR_MASK 0xfffffff8u -#define SD_VADDR_MASK 0xfff00000u -#define SD_RES_MASK 0xfffc00efu - -#define SDC_VADDR_MASK 0xfff -#define SDC_ACC_MASK 0xff000000u -#define SDC_MAX_OFF_MASK 0x001f8000 -#define SDC_G_MASK 0x1 -#define SDC_C_MASK 0x2 -#define SDC_CACHE_MASK 0x4 -#define SDC_M_MASK 0x400000 -#define SDC_R_MASK 0x800000 - -#define PD_P_MASK 0x1 -#define PD_M_MASK 0x2 -#define PD_W_MASK 0x10 -#define PD_R_MASK 0x20 -#define PD_PADDR_MASK 0xfffff800u - -#define PDC_PADDR_MASK 0x1fffff -#define PDC_C_MASK 0x2 -#define PDC_W_MASK 0x200000 -#define PDC_M_MASK 0x400000 -#define PDC_R_MASK 0x800000 -#define PDC_G_MASK 0x40000000 -#define PDC_U_MASK 0x80000000u - -#define MAX_INDIRECTS 3 - -#define PD_ADDR(pd) (pd & (pd_addr_masks[MMU_CONF_PS])) -#define SD_ADDR(va) (mmu_state.sec[SID(va)].addr + (SSL(va) * 8)) - -#define SDC_IDX(va) ((uint8)((va) >> 17) & 7) - -/* Convert from sd to sd cache entry */ -#define SD_TO_SDCH(hi,lo) (((hi) & SD_ADDR_MASK) | \ - ((lo) & SD_C_MASK) >> 1 | \ - ((lo) & SD_CACHE_MASK) >> 1 | \ - (SDC_G_MASK)) -#define SD_TO_SDCL(lo,va) (((lo) & SD_ACC_MASK) | \ - ((lo) & SD_MAX_OFF_MASK) >> 3 | \ - ((lo) & SD_R_MASK) << 18 | \ - ((lo) & SD_M_MASK) << 21 | \ - ((va) & SD_VADDR_MASK) >> 20) - -/* Convert from sd cache entry to sd */ -#define SDCE_TO_SDH(hi) ((hi) & SD_ADDR_MASK) -#define SDCE_TO_SDL(hi,lo) (((lo) & SDC_ACC_MASK) | \ - ((lo) & SDC_MAX_OFF_MASK) << 3 | \ - ((lo) & SDC_R_MASK) >> 18 | \ - ((lo) & SDC_M_MASK) >> 21 | \ - ((hi) & SDC_C_MASK) << 1 | \ - ((hi) & SDC_CACHE_MASK) << 1 | \ - SD_V_MASK | SD_P_MASK) - -/* Convert from pd cache entry to pd */ -#define PDCE_TO_PD(pdcl) ((((pdcl) & PDC_PADDR_MASK) << 11) | \ - (((pdcl) & PDC_W_MASK) >> 17) | \ - (((pdcl) & PDC_M_MASK) >> 21) | \ - (((pdcl) & PDC_R_MASK) >> 18) | \ - PD_P_MASK) - -/* Convert from pd to pd cache entry (low word) */ -#define PD_TO_PDCL(pd, sd_lo) ((((pd) & PD_PADDR_MASK) >> 11) | \ - (((pd) & PD_W_MASK) << 17) | \ - (((pd) & PD_M_MASK) << 21) | \ - (((pd) & PD_R_MASK) << 18) | \ - ((sd_lo) & SD_ACC_MASK)) - -/* Convert from va to pd cache entry (high word / tag) */ -#define VA_TO_PDCH(va, sd_lo) ((1 << 30) | \ - (mmu_state.cidnr[SID(va)] << 26) | \ - ((va & 0xfffff800u) >> 6) | \ - ((sd_lo & SD_CACHE_MASK) >> 1) | \ - ((sd_lo & SD_C_MASK) >> 1)) - -/* Maximum offset (in bytes) of a paged segment */ -#define MAX_SEG_OFF(w) (((SD_MAX_OFF(w) + 1) * ((MMU_CONF_PS + 1) * 2048)) - 1) - -#define IDNC_TAG(val) ((val) & 0xfffffff8) -#define IDNC_U(val) ((val) & 0x1) - -/* Fault codes */ -#define MMU_FAULT(f) { \ - if (fc) { \ - mmu_state.fcode = ((((uint32)r_acc)<<7) | \ - (((uint32)(CPU_CM))<<5) | \ - (f & 0x1f)); \ - mmu_state.faddr = va; \ - } \ - } - -typedef struct { - uint32 addr; - uint32 len; -} mmu_sec; - - -/* - * Segment Descriptor Cache Entry Format - * ===================================== - * - * The Segment Descriptor Cache is a directly mapped cache, indexed by - * bits 19, 18, and 17 of the virtual address. Some notes: - * - * - "Acc", "R", "M", "Max Offset", "Address", "$", and "C" are all - * copied from the SD in main memory. - * - "VAddr" holds bits 20-31 of the virtual address - * - "Address" holds a pointer (word-aligned, so the top 30 bits) to - * a page descriptor table in paged mode, or a segment in - * contiguous segment mode. - * - "Max Offset" holds the number of pages minus one in the - * segment. Depending on current page size, various bits of this - * field will be ignored: - * o Bits 20-15 are used for 2K pages - * o Bits 20-16 are used for 4K pages - * o Bits 20-17 are used for 8K pages - * - * Low Word (bits 0-31) - * -------------------- - * - * 31 24 23 22 21 20 15 14 12 11 0 - * +-------+---+---+---+------------+------+--------------------------+ - * | Acc | R | M | - | Max Offset | - | VAddr | - * +-------+---+---+---+------------+------+--------------------------+ - * - * High Word (bits 32-63) - * ---------------------- - * - * 31 3 2 1 0 - * +------------------------------------------------------+---+---+---+ - * | Address | $ | C | G | - * +------------------------------------------------------+---+---+---+ - * - * - * Page Descriptor Cache Entry Format - * ================================== - * - * The Page Descriptor Cache is a fully associative cache, with a - * tag constructed from the "G" and "IDN" bits, and bits 31-11 of - * the virtual address. - * - * Depending on the current page size and access mode, various bits of - * "VAddr" are ignored. - * - * o Multi-context mode, all ops except single-entry flush: - * VAddr bits 29-11 are used. - * o Multi-context mode, single-entry flush: - * VAddr bits 31-11 are used. - * o Single-context mode, all ops: - * Vaddr bits 31-11 are used. - * o In ALL CASES: - * + 2KB Page Size: Bits 11-12 are used. - * + 4KB Page Size: Bit 11 ignored, 12 used. - * + 8KB Page Size: Bits 11-12 ignored. - * - * Low Word (bits 0-31) - * -------------------- - * - * 31 24 23 22 21 20 0 - * +-------+---+---+---+----------------------------------------------+ - * | Acc | R | M | W | Physical Address | - * +-------+---+---+---+----------------------------------------------+ - * - * - * High Word (bits 32-63) - * ---------------------- - * - * 31 30 29 26 25 5 4 3 2 1 0 - * +---+---+---------+----------------------------+-------+---+---+---+ - * | U | G | IDN | (31) VAddr (11)| - | $ | C | - | - * +---+---+---------+----------------------------+-------+---+---+---+ - * - */ - -typedef struct _mmu_state { - t_bool enabled; /* Global enabled/disabled flag */ - - t_bool flush_u; /* If true, flush all but last cached entry */ - uint32 last_cached; /* The index of the last cached PDC entry */ - - uint32 sdcl[MMU_SDCS]; /* SDC low bits (0-31) */ - uint32 sdch[MMU_SDCS]; /* SDC high bits (32-63) */ - - uint32 pdcl[MMU_PDCS]; /* PDC low bits (0-31) */ - uint32 pdch[MMU_PDCS]; /* PDC high bits (32-63) */ - - uint32 sra[4]; /* Section RAM A */ - uint32 srb[4]; /* Section RAM B */ - - uint32 cidnr[4]; /* Current ID Number Registers */ - uint32 idnc[16]; /* ID Number Cache */ - - mmu_sec sec[4]; /* Section descriptors decoded from - Section RAM A and B */ - - uint32 fcode; /* Fault Code Register */ - uint32 faddr; /* Fault Address Register */ - uint32 conf; /* Configuration Register */ - uint32 var; /* Virtual Address Register */ - -} MMU_STATE; - -t_stat mmu_init(DEVICE *dptr); -uint32 mmu_read(uint32 pa, size_t size); -void mmu_write(uint32 pa, uint32 val, size_t size); -CONST char *mmu_description(DEVICE *dptr); - -/* Virtual memory translation */ -uint32 mmu_xlate_addr(uint32 va, uint8 r_acc); -t_stat mmu_decode_vaddr(uint32 vaddr, uint8 r_acc, - t_bool fc, uint32 *pa); - -t_stat mmu_decode_va(uint32 va, uint8 r_acc, t_bool fc, uint32 *pa); -void mmu_enable(); -void mmu_disable(); - -t_stat mmu_show_sdt(FILE *st, UNIT *uptr, int32 val, CONST void *desc); -t_stat mmu_show_sdc(FILE *st, UNIT *uptr, int32 val, CONST void *desc); -t_stat mmu_show_pdc(FILE *st, UNIT *uptr, int32 val, CONST void *desc); - -#endif /* _3B2_1000_MMU_H_ */ +/* 3b2_rev3_mmu.h: WE32201 MMU + + Copyright (c) 2020-2022, Seth J. Morabito + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + Except as contained in this notice, the name of the author shall + not be used in advertising or otherwise to promote the sale, use or + other dealings in this Software without prior written authorization + from the author. +*/ + +#ifndef _3B2_REV3_MMU_H_ +#define _3B2_REV3_MMU_H_ + +#include "3b2_defs.h" + +#define MMU_SRS 4 /* Section RAM array size (words) */ +#define MMU_SDCS 8 /* SD Cache H/L array size */ +#define MMU_PDCS 64 /* PD Cache H/L array size */ +#define MMU_IDNCS 16 /* ID Number Cache array size */ + +/* Register address offsets */ +#define MMU_SDCL 0 /* SDC - Low Bits */ +#define MMU_SDCH 1 /* SDC - High Bits */ +#define MMU_PDCL 2 /* PDC - Low Bits */ +#define MMU_PDCH 3 /* PDC - High Bits */ +#define MMU_FDCR 4 /* Flush Data Cache Register */ +#define MMU_SRAMA 6 /* Section RAM A */ +#define MMU_SRAMB 7 /* Section RAM B */ +#define MMU_FC 8 /* Fault Code */ +#define MMU_FA 9 /* Fault Address */ +#define MMU_CONF 10 /* Configuration */ +#define MMU_VAR 11 /* Virtual Address Register */ +#define MMU_IDC 12 /* ID Number Cache */ +#define MMU_IDNR 13 /* ID Number Register */ +#define MMU_FIDNR 14 /* Flush ID Number Register */ +#define MMU_VR 15 /* Version Register */ + +#define MMU_REV3_VER 0x23 /* Version byte returned by WE32201 MMU */ + +#define MMU_CONF_M (mmu_state.conf & 0x1) +#define MMU_CONF_R ((mmu_state.conf & 0x2) >> 1) +#define MMU_CONF_C ((mmu_state.conf & 0x4) >> 1) +#define MMU_CONF_PS ((mmu_state.conf & 0x18) >> 3) +#define MMU_CONF_MCE ((mmu_state.conf & 0x20) >> 5) +#define MMU_CONF_DCE ((mmu_state.conf & 0x40) >> 6) + +/* Shift and mask the flag bits for the current CPU mode */ +#define MMU_PERM(f) ((f >> ((3 - (CPU_CM)) * 2)) & 3) + +/* Codes set in the MMU Fault register */ +#define MMU_F_MISS_MEM 1 +#define MMU_F_RM_UPD 2 +#define MMU_F_SDTLEN 3 +#define MMU_F_PW 4 +#define MMU_F_PDTLEN 5 +#define MMU_F_INV_SD 6 +#define MMU_F_SEG_NOT_PRES 7 +#define MMU_F_PDT_NOT_PRES 9 +#define MMU_F_PAGE_NOT_PRES 10 +#define MMU_F_INDIRECT 11 +#define MMU_F_ACC 13 +#define MMU_F_SEG_OFFSET 14 + +/* Access Request types */ +#define ACC_MT 0 /* Move Translated */ +#define ACC_SPW 1 /* Support processor write */ +#define ACC_SPF 3 /* Support processor fetch */ +#define ACC_IR 7 /* Interlocked read */ +#define ACC_AF 8 /* Address fetch */ +#define ACC_OF 9 /* Operand fetch */ +#define ACC_W 10 /* Write */ +#define ACC_IFAD 12 /* Instruction fetch after discontinuity */ +#define ACC_IF 13 /* Instruction fetch */ + +/* Pluck out Virtual Address fields */ +#define SID(va) (((va) >> 30) & 3) +#define SSL(va) (((va) >> 17) & 0x1fff) +#define SOT(va) (va & 0x1ffff) + +/* PSL will be either: + * - Bits 11-16 (2K pages: MMU_CONF_PS = 0) + * - Bits 12-16 (4K pages: MMU_CONF_PS = 1) + * - Bits 13-16 (8K pages: MMU_CONF_PS = 2) + */ +#define PSL(va) (((va) >> (11 + MMU_CONF_PS)) & (0x3f >> MMU_CONF_PS)) +#define PSL_C(va) (((va) & pd_psl_masks[MMU_CONF_PS])) + +/* POT will be either: + * - Bits 0-10 (2K pages: MMU_CONF_PS = 0) + * - Bits 0-11 (4K pages: MMU_CONF_PS = 1) + * - Bits 0-12 (8K pages: MMU_CONF_PS = 2) + */ +#define POT(va) ((va) & (0x1fff >> (2 - (MMU_CONF_PS)))) + +/* Get the maximum length of an SSL from SRAMB */ +#define SRAMB_LEN(va) (mmu_state.sec[SID(va)].len) + +/* Pluck out Segment Descriptor fields */ +#define SD_PRESENT(sd_lo) ((sd_lo) & 1) +#define SD_MODIFIED(sd_lo) (((sd_lo) >> 1) & 1) +#define SD_CONTIG(sd_lo) (((sd_lo) >> 2) & 1) +#define SD_VALID(sd_lo) (((sd_lo) >> 6) & 1) +#define SD_INDIRECT(sd_lo) (((sd_lo) >> 7) & 1) +#define SD_MAX_OFF(sd_lo) (((sd_lo) >> 18) & 0x3f) +#define SD_ACC(sd_lo) (((sd_lo) >> 24) & 0xff) + +#define SD_SEG_ADDR(sd_hi) ((sd_hi) & 0xfffffff8u) + +#define SD_P_MASK 0x1 +#define SD_M_MASK 0x2 +#define SD_C_MASK 0x4 +#define SD_CACHE_MASK 0x8 +#define SD_R_MASK 0x20 +#define SD_V_MASK 0x40 +#define SD_MAX_OFF_MASK 0xfc0000 +#define SD_ACC_MASK 0xff000000u +#define SD_ADDR_MASK 0xfffffff8u +#define SD_VADDR_MASK 0xfff00000u +#define SD_RES_MASK 0xfffc00efu + +#define SDC_VADDR_MASK 0xfff +#define SDC_ACC_MASK 0xff000000u +#define SDC_MAX_OFF_MASK 0x001f8000 +#define SDC_G_MASK 0x1 +#define SDC_C_MASK 0x2 +#define SDC_CACHE_MASK 0x4 +#define SDC_M_MASK 0x400000 +#define SDC_R_MASK 0x800000 + +#define PD_P_MASK 0x1 +#define PD_M_MASK 0x2 +#define PD_W_MASK 0x10 +#define PD_R_MASK 0x20 +#define PD_PADDR_MASK 0xfffff800u + +#define PDC_PADDR_MASK 0x1fffff +#define PDC_C_MASK 0x2 +#define PDC_W_MASK 0x200000 +#define PDC_M_MASK 0x400000 +#define PDC_R_MASK 0x800000 +#define PDC_G_MASK 0x40000000 +#define PDC_U_MASK 0x80000000u + +#define MAX_INDIRECTS 3 + +#define PD_ADDR(pd) (pd & (pd_addr_masks[MMU_CONF_PS])) +#define SD_ADDR(va) (mmu_state.sec[SID(va)].addr + (SSL(va) * 8)) + +#define SDC_IDX(va) ((uint8)((va) >> 17) & 7) + +/* Convert from sd to sd cache entry */ +#define SD_TO_SDCH(hi,lo) (((hi) & SD_ADDR_MASK) | \ + ((lo) & SD_C_MASK) >> 1 | \ + ((lo) & SD_CACHE_MASK) >> 1 | \ + (SDC_G_MASK)) +#define SD_TO_SDCL(lo,va) (((lo) & SD_ACC_MASK) | \ + ((lo) & SD_MAX_OFF_MASK) >> 3 | \ + ((lo) & SD_R_MASK) << 18 | \ + ((lo) & SD_M_MASK) << 21 | \ + ((va) & SD_VADDR_MASK) >> 20) + +/* Convert from sd cache entry to sd */ +#define SDCE_TO_SDH(hi) ((hi) & SD_ADDR_MASK) +#define SDCE_TO_SDL(hi,lo) (((lo) & SDC_ACC_MASK) | \ + ((lo) & SDC_MAX_OFF_MASK) << 3 | \ + ((lo) & SDC_R_MASK) >> 18 | \ + ((lo) & SDC_M_MASK) >> 21 | \ + ((hi) & SDC_C_MASK) << 1 | \ + ((hi) & SDC_CACHE_MASK) << 1 | \ + SD_V_MASK | SD_P_MASK) + +/* Convert from pd cache entry to pd */ +#define PDCE_TO_PD(pdcl) ((((pdcl) & PDC_PADDR_MASK) << 11) | \ + (((pdcl) & PDC_W_MASK) >> 17) | \ + (((pdcl) & PDC_M_MASK) >> 21) | \ + (((pdcl) & PDC_R_MASK) >> 18) | \ + PD_P_MASK) + +/* Convert from pd to pd cache entry (low word) */ +#define PD_TO_PDCL(pd, sd_lo) ((((pd) & PD_PADDR_MASK) >> 11) | \ + (((pd) & PD_W_MASK) << 17) | \ + (((pd) & PD_M_MASK) << 21) | \ + (((pd) & PD_R_MASK) << 18) | \ + ((sd_lo) & SD_ACC_MASK)) + +/* Convert from va to pd cache entry (high word / tag) */ +#define VA_TO_PDCH(va, sd_lo) ((1 << 30) | \ + (mmu_state.cidnr[SID(va)] << 26) | \ + ((va & 0xfffff800u) >> 6) | \ + ((sd_lo & SD_CACHE_MASK) >> 1) | \ + ((sd_lo & SD_C_MASK) >> 1)) + +/* Maximum offset (in bytes) of a paged segment */ +#define MAX_SEG_OFF(w) (((SD_MAX_OFF(w) + 1) * ((MMU_CONF_PS + 1) * 2048)) - 1) + +#define IDNC_TAG(val) ((val) & 0xfffffff8) +#define IDNC_U(val) ((val) & 0x1) + +/* Fault codes */ +#define MMU_FAULT(f) { \ + if (fc) { \ + mmu_state.fcode = ((((uint32)r_acc)<<7) | \ + (((uint32)(CPU_CM))<<5) | \ + (f & 0x1f)); \ + mmu_state.faddr = va; \ + } \ + } + +typedef struct { + uint32 addr; + uint32 len; +} mmu_sec; + + +/* + * Segment Descriptor Cache Entry Format + * ===================================== + * + * The Segment Descriptor Cache is a directly mapped cache, indexed by + * bits 19, 18, and 17 of the virtual address. Some notes: + * + * - "Acc", "R", "M", "Max Offset", "Address", "$", and "C" are all + * copied from the SD in main memory. + * - "VAddr" holds bits 20-31 of the virtual address + * - "Address" holds a pointer (word-aligned, so the top 30 bits) to + * a page descriptor table in paged mode, or a segment in + * contiguous segment mode. + * - "Max Offset" holds the number of pages minus one in the + * segment. Depending on current page size, various bits of this + * field will be ignored: + * o Bits 20-15 are used for 2K pages + * o Bits 20-16 are used for 4K pages + * o Bits 20-17 are used for 8K pages + * + * Low Word (bits 0-31) + * -------------------- + * + * 31 24 23 22 21 20 15 14 12 11 0 + * +-------+---+---+---+------------+------+--------------------------+ + * | Acc | R | M | - | Max Offset | - | VAddr | + * +-------+---+---+---+------------+------+--------------------------+ + * + * High Word (bits 32-63) + * ---------------------- + * + * 31 3 2 1 0 + * +------------------------------------------------------+---+---+---+ + * | Address | $ | C | G | + * +------------------------------------------------------+---+---+---+ + * + * + * Page Descriptor Cache Entry Format + * ================================== + * + * The Page Descriptor Cache is a fully associative cache, with a + * tag constructed from the "G" and "IDN" bits, and bits 31-11 of + * the virtual address. + * + * Depending on the current page size and access mode, various bits of + * "VAddr" are ignored. + * + * o Multi-context mode, all ops except single-entry flush: + * VAddr bits 29-11 are used. + * o Multi-context mode, single-entry flush: + * VAddr bits 31-11 are used. + * o Single-context mode, all ops: + * Vaddr bits 31-11 are used. + * o In ALL CASES: + * + 2KB Page Size: Bits 11-12 are used. + * + 4KB Page Size: Bit 11 ignored, 12 used. + * + 8KB Page Size: Bits 11-12 ignored. + * + * Low Word (bits 0-31) + * -------------------- + * + * 31 24 23 22 21 20 0 + * +-------+---+---+---+----------------------------------------------+ + * | Acc | R | M | W | Physical Address | + * +-------+---+---+---+----------------------------------------------+ + * + * + * High Word (bits 32-63) + * ---------------------- + * + * 31 30 29 26 25 5 4 3 2 1 0 + * +---+---+---------+----------------------------+-------+---+---+---+ + * | U | G | IDN | (31) VAddr (11)| - | $ | C | - | + * +---+---+---------+----------------------------+-------+---+---+---+ + * + */ + +typedef struct _mmu_state { + t_bool enabled; /* Global enabled/disabled flag */ + + t_bool flush_u; /* If true, flush all but last cached entry */ + uint32 last_cached; /* The index of the last cached PDC entry */ + + uint32 sdcl[MMU_SDCS]; /* SDC low bits (0-31) */ + uint32 sdch[MMU_SDCS]; /* SDC high bits (32-63) */ + + uint32 pdcl[MMU_PDCS]; /* PDC low bits (0-31) */ + uint32 pdch[MMU_PDCS]; /* PDC high bits (32-63) */ + + uint32 sra[4]; /* Section RAM A */ + uint32 srb[4]; /* Section RAM B */ + + uint32 cidnr[4]; /* Current ID Number Registers */ + uint32 idnc[16]; /* ID Number Cache */ + + mmu_sec sec[4]; /* Section descriptors decoded from + Section RAM A and B */ + + uint32 fcode; /* Fault Code Register */ + uint32 faddr; /* Fault Address Register */ + uint32 conf; /* Configuration Register */ + uint32 var; /* Virtual Address Register */ + +} MMU_STATE; + +t_stat mmu_init(DEVICE *dptr); +uint32 mmu_read(uint32 pa, size_t size); +void mmu_write(uint32 pa, uint32 val, size_t size); +CONST char *mmu_description(DEVICE *dptr); + +/* Virtual memory translation */ +uint32 mmu_xlate_addr(uint32 va, uint8 r_acc); +t_stat mmu_decode_vaddr(uint32 vaddr, uint8 r_acc, + t_bool fc, uint32 *pa); + +t_stat mmu_decode_va(uint32 va, uint8 r_acc, t_bool fc, uint32 *pa); +void mmu_enable(); +void mmu_disable(); + +t_stat mmu_show_sdt(FILE *st, UNIT *uptr, int32 val, CONST void *desc); +t_stat mmu_show_sdc(FILE *st, UNIT *uptr, int32 val, CONST void *desc); +t_stat mmu_show_pdc(FILE *st, UNIT *uptr, int32 val, CONST void *desc); + +#endif /* _3B2_REV3_MMU_H_ */ diff --git a/3B2/3b2_rev3_sys.c b/3B2/3b2_rev3_sys.c index 8c32ba46..3b088025 100644 --- a/3B2/3b2_rev3_sys.c +++ b/3B2/3b2_rev3_sys.c @@ -1,80 +1,80 @@ -/* 3b2_rev3_sys.c: AT&T 3B2/600G system definition - - Copyright (c) 2020, Seth J. Morabito - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - - Except as contained in this notice, the name of the author shall - not be used in advertising or otherwise to promote the sale, use or - other dealings in this Software without prior written authorization - from the author. -*/ - -#include "3b2_defs.h" - -#include "3b2_cpu.h" -#include "3b2_csr.h" -#include "3b2_if.h" -#include "3b2_iu.h" -#include "3b2_mau.h" -#include "3b2_ni.h" -#include "3b2_ports.h" -#include "3b2_scsi.h" -#include "3b2_stddev.h" -#include "3b2_timer.h" - -char sim_name[] = "AT&T 3B2/600G"; - -DEVICE *sim_devices[] = { - &cpu_dev, - &csr_dev, - &flt_dev, - &mmu_dev, - &mau_dev, - &timer_dev, - &tod_dev, - &nvram_dev, - &tti_dev, - &tto_dev, - &contty_dev, - &iu_timer_dev, - &dmac_dev, - &if_dev, - &ha_dev, - &ports_dev, - &ni_dev, - NULL -}; - -void full_reset() -{ - cpu_reset(&cpu_dev); - mau_reset(&mau_dev); - tti_reset(&tti_dev); - contty_reset(&contty_dev); - iu_timer_reset(&iu_timer_dev); - timer_reset(&timer_dev); - if_reset(&if_dev); - ha_reset(&ha_dev); - csr_reset(&csr_dev); - ports_reset(&ports_dev); - ni_reset(&ni_dev); -} +/* 3b2_rev3_sys.c: Version 3 (3B2/700) System Definition + + Copyright (c) 2020-2022, Seth J. Morabito + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + Except as contained in this notice, the name of the author shall + not be used in advertising or otherwise to promote the sale, use or + other dealings in this Software without prior written authorization + from the author. +*/ + +#include "3b2_defs.h" + +#include "3b2_cpu.h" +#include "3b2_csr.h" +#include "3b2_if.h" +#include "3b2_iu.h" +#include "3b2_mau.h" +#include "3b2_ni.h" +#include "3b2_ports.h" +#include "3b2_scsi.h" +#include "3b2_stddev.h" +#include "3b2_timer.h" + +char sim_name[] = "AT&T 3B2/700"; + +DEVICE *sim_devices[] = { + &cpu_dev, + &csr_dev, + &flt_dev, + &mmu_dev, + &mau_dev, + &timer_dev, + &tod_dev, + &nvram_dev, + &tti_dev, + &tto_dev, + &contty_dev, + &iu_timer_dev, + &dmac_dev, + &if_dev, + &ha_dev, + &ports_dev, + &ni_dev, + NULL +}; + +void full_reset() +{ + cpu_reset(&cpu_dev); + mau_reset(&mau_dev); + tti_reset(&tti_dev); + contty_reset(&contty_dev); + iu_timer_reset(&iu_timer_dev); + timer_reset(&timer_dev); + if_reset(&if_dev); + ha_reset(&ha_dev); + csr_reset(&csr_dev); + ports_reset(&ports_dev); + ni_reset(&ni_dev); +} diff --git a/3B2/3b2_rev3_timer.h b/3B2/3b2_rev3_timer.h deleted file mode 100644 index c4379763..00000000 --- a/3B2/3b2_rev3_timer.h +++ /dev/null @@ -1,79 +0,0 @@ -/* 3b2_rev2_stddev.h: 82C54 Interval Timer. - - Copyright (c) 2021, Seth J. Morabito - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - - Except as contained in this notice, the name of the author shall - not be used in advertising or otherwise to promote the sale, use or - other dealings in this Software without prior written authorization - from the author. -*/ - -#ifndef _3B2_REV3_TIMER_H_ -#define _3B2_REV3_TIMER_H_ - -#include "3b2_defs.h" - -/* Timer definitions */ -#define TIMER_STP_US 1 -#define tmrnum u3 -#define tmr up7 - -#define TIMER_REG_DIVA 0x03 -#define TIMER_REG_DIVB 0x07 -#define TIMER_REG_DIVC 0x0b -#define TIMER_REG_CTRL 0x0f -#define TIMER_CLR_LATCH 0x13 - -#define TIMER_MODE(ctr) (((ctr->ctrl) >> 1) & 7) -#define TIMER_RW(ctr) (((ctr->ctrl) >> 4) & 3) - -#define CLK_LATCH 0 -#define CLK_LSB 1 -#define CLK_MSB 2 -#define CLK_LMB 3 - -struct timer_ctr { - uint16 divider; - uint16 val; - uint8 ctrl_latch; - uint16 cnt_latch; - uint8 ctrl; - t_bool r_lmb; - t_bool w_lmb; - t_bool enabled; - t_bool r_ctrl_latch; - t_bool r_cnt_latch; -}; - -/* 82C54 Timer */ -t_stat timer_reset(DEVICE *dptr); -uint32 timer_read(uint32 pa, size_t size); -void timer_write(uint32 pa, uint32 val, size_t size); -t_stat timer0_svc(UNIT *uptr); -t_stat timer1_svc(UNIT *uptr); -t_stat timer2_svc(UNIT *uptr); -/* void timer_tick(uint8 ctrnum); */ -void timer_disable(uint8 ctrnum); -void timer_enable(uint8 ctrnum); - -#endif /* _3B2_REV3_TIMER_H_ */ diff --git a/3B2/3b2_scsi.c b/3B2/3b2_scsi.c index cdc52dd2..99eee173 100644 --- a/3B2/3b2_scsi.c +++ b/3B2/3b2_scsi.c @@ -1,1468 +1,1452 @@ -/* 3b2_scsi.c: AT&T 3B2 SCSI (CM195W) feature card - - Copyright (c) 2020, Seth J. Morabito - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - - Except as contained in this notice, the name of the author shall - not be used in advertising or otherwise to promote the sale, use or - other dealings in this Software without prior written authorization - from the author. -*/ - -#include "3b2_scsi.h" - -#include "sim_scsi.h" -#include "sim_tape.h" - -#include "3b2_cpu.h" -#include "3b2_io.h" -#include "3b2_mem.h" - -#define PUMP_CRC 0x201b3617 - -static void ha_cmd(uint8 op, uint8 subdev, uint32 addr, - int32 len, t_bool express); -static void ha_build_req(uint8 subdev, t_bool express); -static void ha_ctrl(); -static void ha_write(); -static void ha_write_ext(); -static void ha_read_ext(); -static void ha_read_capacity(); - -static void dump_rep(); -static void dump_req(); -static void dump_edt(); - -/* Do not initiate host IRQ if ivec is <= this value */ -#define SCSI_MIN_IVEC 1 -#define HA_SCSI_ID 0 -#define HA_MAXFR (1u << 16) - -HA_STATE ha_state; -SCSI_BUS ha_bus; -uint8 *ha_buf; -int8 ha_subdev_tab[8]; /* Map of subdevice to SCSI target */ -uint8 ha_subdev_cnt; -uint32 ha_crc = 0; -uint32 cq_offset = 0; - -static struct scsi_dev_t ha_tab[] = { - HA_DISK(SD327), - HA_TAPE(ST120) -}; - -#define SCSI_U_FLAGS (UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+ \ - UNIT_ROABLE+(SD327_DTYPE << UNIT_V_DTYPE)) - -UNIT ha_unit[] = { - { UDATA (&ha_svc, SCSI_U_FLAGS, HA_SIZE(SD327)) }, /* SCSI ID 0 */ - { UDATA (&ha_svc, SCSI_U_FLAGS, HA_SIZE(SD327)) }, /* SCSI ID 1 */ - { UDATA (&ha_svc, SCSI_U_FLAGS, HA_SIZE(SD327)) }, /* SCSI ID 2 */ - { UDATA (&ha_svc, SCSI_U_FLAGS, HA_SIZE(SD327)) }, /* SCSI ID 3 */ - { UDATA (&ha_svc, SCSI_U_FLAGS, HA_SIZE(SD327)) }, /* SCSI ID 4 */ - { UDATA (&ha_svc, SCSI_U_FLAGS, HA_SIZE(SD327)) }, /* SCSI ID 5 */ - { UDATA (&ha_svc, SCSI_U_FLAGS, HA_SIZE(SD327)) }, /* SCSI ID 6 */ - { UDATA (&ha_svc, SCSI_U_FLAGS, HA_SIZE(SD327)) }, /* SCSI ID 7 */ - { UDATA (&ha_svc, UNIT_DIS, 0) }, /* CIO unit */ -}; - -static UNIT *cio_unit = &ha_unit[8]; - -MTAB ha_mod[] = { - { SCSI_WLK, 0, NULL, "WRITEENABLED", - &scsi_set_wlk, NULL, NULL, "Write enable disk drive" }, - { SCSI_WLK, SCSI_WLK, NULL, "LOCKED", - &scsi_set_wlk, NULL, NULL, "Write lock disk drive" }, - { MTAB_XTD|MTAB_VUN, 0, "WRITE", NULL, - NULL, &scsi_show_wlk, NULL, "Display drive writelock status" }, - { MTAB_XTD|MTAB_VUN, SD327_DTYPE, NULL, "SD327", - &ha_set_type, NULL, NULL, "Set CDC 327MB Disk Type" }, - { MTAB_XTD|MTAB_VUN, ST120_DTYPE, NULL, "ST120", - &ha_set_type, NULL, NULL, "Set Wangtek 120MB Tape Type" }, - { MTAB_XTD|MTAB_VUN, 0, "TYPE", NULL, - NULL, &ha_show_type, NULL, "Display device type" }, - { MTAB_XTD|MTAB_VUN, 0, "FORMAT", "FORMAT", - &scsi_set_fmt, &scsi_show_fmt, NULL, "Set/Display unit format" }, - { 0 } -}; - -#define HA_TRACE 1 - -static DEBTAB ha_debug[] = { - { "TRACE", HA_TRACE, "Call Trace" }, - { "SCMD", SCSI_DBG_CMD, "SCSI commands"}, - { "SBUS", SCSI_DBG_BUS, "SCSI bus activity" }, - { "SMSG", SCSI_DBG_MSG, "SCSI messages" }, - { "SDSK", SCSI_DBG_DSK, "SCSI disk activity" }, - { NULL } -}; - -DEVICE ha_dev = { - "SCSI", /* name */ - ha_unit, /* units */ - NULL, /* registers */ - ha_mod, /* modifiers */ - 9, /* #units */ - 16, /* address radix */ - 32, /* address width */ - 1, /* address incr. */ - 16, /* data radix */ - 8, /* data width */ - NULL, /* examine routine */ - NULL, /* deposit routine */ - &ha_reset, /* reset routine */ - NULL, /* boot routine */ - &ha_attach, /* attach routine */ - &ha_detach, /* detach routine */ - NULL, /* context */ - DEV_DEBUG|DEV_DISK|DEV_SECTORS, /* flags */ - 0, /* debug control flags */ - ha_debug, /* debug flag names */ - NULL, /* memory size change */ - NULL, /* logical name */ - NULL, /* help routine */ - NULL, - NULL, - NULL, -}; - -void ha_cio_reset(uint8 cid) -{ - sim_debug(HA_TRACE, &ha_dev, - "[%08x] Handling CIO reset\n", - R[NUM_PC]); - ha_state.pump_state = PUMP_NONE; - ha_crc = 0; -} - -t_stat ha_reset(DEVICE *dptr) -{ - uint8 cid; - uint32 t, dtyp; - UNIT *uptr; - t_stat r; - - sim_debug(HA_TRACE, &ha_dev, - "[%08x] [ha_reset] Resetting SCSI device\n", - R[NUM_PC]); - - ha_state.pump_state = PUMP_NONE; - - if (ha_buf == NULL) { - ha_buf = (uint8 *)calloc(HA_MAXFR, sizeof(uint8)); - } - - r = scsi_init(&ha_bus, HA_MAXFR); - - if (r != SCPE_OK) { - return r; - } - - ha_bus.dptr = dptr; - - scsi_reset(&ha_bus); - - for (t = 0; t < 8; t++) { - uptr = dptr->units + t; - if (t == HA_SCSI_ID) { - uptr->flags = UNIT_DIS; - } - scsi_add_unit(&ha_bus, t, uptr); - dtyp = GET_DTYPE(uptr->flags); - scsi_set_unit(&ha_bus, uptr, &ha_tab[dtyp]); - scsi_reset_unit(uptr); - } - - if (dptr->flags & DEV_DIS) { - sim_debug(HA_TRACE, &ha_dev, - "[ha_reset] REMOVING CARD\n"); - - for (cid = 0; cid < CIO_SLOTS; cid++) { - if (cio[cid].id == HA_ID) { - break; - } - } - - if (cid == CIO_SLOTS) { - /* No card was ever attached */ - return SCPE_OK; - } - - cio[cid].id = 0; - cio[cid].ipl = 0; - cio[cid].ivec = 0; - cio[cid].exp_handler = NULL; - cio[cid].full_handler = NULL; - cio[cid].sysgen = NULL; - - ha_state.initialized = FALSE; - - } else if (!ha_state.initialized) { - sim_debug(HA_TRACE, &ha_dev, - "[ha_reset] Attaching SCSI Card\n"); - - /* Find the first available slot */ - for (cid = 0; cid < CIO_SLOTS; cid++) { - if (cio[cid].id == 0) { - break; - } - } - - if (cid == CIO_SLOTS) { - return SCPE_NXM; - } - - cio[cid].id = HA_ID; - cio[cid].ipl = HA_IPL; - cio[cid].exp_handler = &ha_express; - cio[cid].full_handler = &ha_full; - cio[cid].reset_handler = &ha_cio_reset; - cio[cid].sysgen = &ha_sysgen; - - ha_state.initialized = TRUE; - ha_state.cid = cid; - - sim_debug(HA_TRACE, &ha_dev, - "[ha_reset] SCSI Card now enabled in IO Slot %d\n", - cid); - } - - return SCPE_OK; -} - -static void ha_calc_subdevs() -{ - uint32 target; - UNIT *uptr; - SCSI_DEV *dev; - - ha_subdev_cnt = 0; - - memset(ha_subdev_tab, -1, 8); - - for (target = 0; target < 8; target++) { - uptr = &ha_unit[target]; - if (uptr->flags & UNIT_ATT) { - dev = (SCSI_DEV *)uptr->up7; - ha_subdev_tab[ha_subdev_cnt++] = target; - } - } -} - -t_stat ha_attach(UNIT *uptr, CONST char *cptr) -{ - t_stat r; - r = scsi_attach(uptr, cptr); - ha_calc_subdevs(); - return r; -} - -t_stat ha_detach(UNIT *uptr) -{ - t_stat r; - r = scsi_detach(uptr); - ha_calc_subdevs(); - return r; -} - -t_stat ha_svc(UNIT *uptr) -{ - cio_entry cqe; - uint8 capp_data[CAPP_LEN] = {0}; - - /* Finish any pending job */ - if (ha_state.reply.pending) { - ha_state.reply.pending = FALSE; - - switch(ha_state.reply.type) { - case HA_JOB_QUICK: - ha_fcm_express(); - - sim_debug(HA_TRACE, &ha_dev, - "[ha_svc] FAST MODE CQ: status=%02x op=%02x subdev=%02x ssb=%02x\n", - ha_state.reply.status, ha_state.reply.op, ha_state.reply.subdev, ha_state.reply.ssb); - break; - case HA_JOB_EXPRESS: - case HA_JOB_FULL: - cqe.byte_count = ha_state.reply.len; - cqe.opcode = ha_state.reply.status; /* Yes, status, not opcode! */ - cqe.subdevice = ha_state.reply.subdev; - cqe.address = ha_state.reply.addr; - - sim_debug(HA_TRACE, &ha_dev, - "[ha_svc] CQE: byte_count=%04x, opcode=%02x, subdevice=%02x, addr=%08x\n", - cqe.byte_count, cqe.opcode, cqe.subdevice, cqe.address); - - if (ha_state.reply.type == HA_JOB_EXPRESS) { - sim_debug(HA_TRACE, &ha_dev, - "[ha_svc] EXPRESS MODE CQ: byte_count=%02x op=%02x subdev=%02x address=%08x\n", - cqe.byte_count, cqe.opcode, cqe.subdevice, cqe.address); - - cio_cexpress(ha_state.cid, SCQCESIZE, &cqe, capp_data); - } else { - sim_debug(HA_TRACE, &ha_dev, - "[ha_svc] FULL MODE CQ: status=%02x op=%02x subdev=%02x ssb=%02x\n", - ha_state.reply.status, ha_state.reply.op, ha_state.reply.subdev, ha_state.reply.ssb); - - cio_cqueue(ha_state.cid, 0, SCQCESIZE, &cqe, capp_data); - } - break; - } - - dump_rep(); - } - - if (cio[ha_state.cid].ivec > SCSI_MIN_IVEC) { - sim_debug(HA_TRACE, &ha_dev, - "[%08x] [ha_svc] IRQ for board %d (VEC=%d).\n", - R[NUM_PC], ha_state.cid, cio[ha_state.cid].ivec); - CIO_SET_INT(ha_state.cid); - } - - return SCPE_OK; -} - -void ha_sysgen(uint8 cid) -{ - uint32 sysgen_p; - uint32 alert_buf_p; - - cq_offset = 0; - - sim_debug(HA_TRACE, &ha_dev, "[ha_sysgen] Handling Sysgen.\n"); - sim_debug(HA_TRACE, &ha_dev, "[ha_sysgen] rqp=%08x\n", cio[cid].rqp); - sim_debug(HA_TRACE, &ha_dev, "[ha_sysgen] cqp=%08x\n", cio[cid].cqp); - sim_debug(HA_TRACE, &ha_dev, "[ha_sysgen] rqs=%d\n", cio[cid].rqs); - sim_debug(HA_TRACE, &ha_dev, "[ha_sysgen] cqs=%d\n", cio[cid].cqs); - sim_debug(HA_TRACE, &ha_dev, "[ha_sysgen] ivec=%d\n", cio[cid].ivec); - sim_debug(HA_TRACE, &ha_dev, "[ha_sysgen] no_rque=%d\n", cio[cid].no_rque); - - sysgen_p = pread_w(SYSGEN_PTR); - alert_buf_p = pread_w(sysgen_p + 12); - sim_debug(HA_TRACE, &ha_dev, "[ha_sysgen] alert_bfr=%08x\n", alert_buf_p); - - ha_state.frq = (cio[cid].no_rque == 0); - - ha_state.reply.type = ha_state.frq ? HA_JOB_QUICK : HA_JOB_EXPRESS; - ha_state.reply.addr = 0; - ha_state.reply.len = 0; - ha_state.reply.status = 3; - ha_state.reply.op = 0; - ha_state.reply.pending = TRUE; - - if (ha_crc == PUMP_CRC) { - sim_debug(HA_TRACE, &ha_dev, - "[%08x] [ha_full] PUMP: NEW STATE = PUMP_SYSGEN\n", - R[NUM_PC]); - ha_state.pump_state = PUMP_SYSGEN; - } else { - sim_debug(HA_TRACE, &ha_dev, - "[%08x] [ha_full] PUMP: NEW STATE = PUMP_NONE\n", - R[NUM_PC]); - ha_state.pump_state = PUMP_NONE; - } - - sim_activate_abs(cio_unit, 100000); -} - -void ha_fast_queue_check() -{ - uint8 busy, op, subdev; - uint32 timeout, addr, len, rqp; - rqp = cio[ha_state.cid].rqp; - - busy = pread_b(rqp); - op = pread_b(rqp + 1); - subdev = pread_b(rqp + 2); - timeout = pread_w(rqp + 4); - addr = pread_w(rqp + 8); - len = pread_w(rqp + 12); - - if (busy == 0xff || ha_state.pump_state != PUMP_COMPLETE) { - sim_debug(HA_TRACE, &ha_dev, - "[%08x] [ha_fast_queue_check] Job pending (opcode=0x%02x subdev=%02x)\n", - R[NUM_PC], op, subdev); - pwrite_b(rqp, 0); /* Job has been taken */ - ha_cmd(op, subdev, addr, len, FALSE); - } -} - -void ha_express(uint8 cid) -{ - cio_entry rqe; - uint8 rapp_data[RAPP_LEN] = {0}; - - sim_debug(HA_TRACE, &ha_dev, - "[%08x] [ha_express] Handling Express Request\n", - R[NUM_PC]); - - if (ha_state.frq) { - ha_fast_queue_check(); - } else { - cio_rexpress(cid, SCQRESIZE, &rqe, rapp_data); - - ha_cmd(rqe.opcode, rqe.subdevice, rqe.address, - rqe.byte_count, TRUE); - } -} - -void ha_full(uint8 cid) -{ - sim_debug(HA_TRACE, &ha_dev, - "[%08x] [ha_full] Handling Full Request (INT3)\n", - R[NUM_PC]); - - if (ha_state.pump_state == PUMP_SYSGEN) { - sim_debug(HA_TRACE, &ha_dev, - "[%08x] [ha_full] PUMP: NEW STATE = PUMP_COMPLETE\n", - R[NUM_PC]); - ha_state.pump_state = PUMP_COMPLETE; - } - - if (ha_state.frq) { - ha_fast_queue_check(); - } else { - sim_debug(HA_TRACE, &ha_dev, - "[%08x] [ha_full] NON_FRQ NOT HANDLED\n", - R[NUM_PC]); - } -} - -static void dump_req() -{ - sim_debug(HA_TRACE, &ha_dev, - "[REQ] [%08x] %08x\n", - cio[ha_state.cid].rqp, - pread_w(cio[ha_state.cid].rqp)); - sim_debug(HA_TRACE, &ha_dev, - "[REQ] [%08x] %08x\n", - cio[ha_state.cid].rqp + 4, - pread_w(cio[ha_state.cid].rqp + 4)); - sim_debug(HA_TRACE, &ha_dev, - "[REQ] [%08x] %08x\n", - cio[ha_state.cid].rqp + 8, - pread_w(cio[ha_state.cid].rqp + 8)); - sim_debug(HA_TRACE, &ha_dev, - "[REQ] [%08x] %08x\n", - cio[ha_state.cid].rqp + 12, - pread_w(cio[ha_state.cid].rqp + 12)); - sim_debug(HA_TRACE, &ha_dev, - "[REQ] [%08x] %08x\n", - cio[ha_state.cid].rqp + 16, - pread_w(cio[ha_state.cid].rqp + 16)); - sim_debug(HA_TRACE, &ha_dev, - "[REQ] [%08x] %08x\n", - cio[ha_state.cid].rqp + 20, - pread_w(cio[ha_state.cid].rqp + 20)); - sim_debug(HA_TRACE, &ha_dev, - "[REQ] [%08x] %08x\n", - cio[ha_state.cid].rqp + 24, - pread_w(cio[ha_state.cid].rqp + 24)); -} - -static void dump_rep() -{ - uint32 i; - uint32 cqs = cio[ha_state.cid].cqs; - - for (i = 0; i < cqs; i++) { - sim_debug(HA_TRACE, &ha_dev, - "[CEQ] [%08x] %08x\n", - cio[ha_state.cid].cqp + (i * 4), - pread_w(cio[ha_state.cid].cqp + (i * 4))); - } -} - -static void ha_boot_disk(UNIT *uptr, uint8 target) -{ - t_seccnt sectsread; - t_stat r; - uint8 buf[HA_BLKSZ]; - uint32 i, boot_loc; - - /* Read in the Physical Descriptor (PD) block (block 0) */ - r = sim_disk_rdsect(uptr, 0, buf, §sread, 1); - - if (r != SCPE_OK) { - sim_debug(HA_TRACE, &ha_dev, - "[ha_boot_disk] Could not read LBA 0\n"); - HA_STAT(HA_CKCON, CIO_SUCCESS); - return; - } - - /* Store the Physical Descriptor (PD) block at well-known - address 0x2004400 */ - sim_debug(HA_TRACE, &ha_dev, - "[ha_boot_disk] Storing PD block at 0x%08x.\n", - HA_PDINFO_ADDR); - for (i = 0; i < HA_BLKSZ; i++) { - pwrite_b(HA_PDINFO_ADDR + i, buf[i]); - } - - - /* The PD block points to the logical start of disk */ - boot_loc = ATOW(buf, HA_PDLS_OFF); - - sim_debug(HA_TRACE, &ha_dev, - "[ha_boot_disk] Logical Start is at 0x%x\n", - boot_loc); - - r = sim_disk_rdsect(uptr, boot_loc, buf, §sread, 1); - - sim_debug(HA_TRACE, &ha_dev, - "[ha_boot_disk] Storing boot block %d at 0x%08x.\n", - boot_loc, HA_BOOT_ADDR); - - for (i = 0; i < HA_BLKSZ; i++) { - pwrite_b(HA_BOOT_ADDR + i, buf[i]); - } - - sim_debug(HA_TRACE, &ha_dev, - "[ha_boot_disk] Done storing boot block at 0x%08x\n", - HA_BOOT_ADDR); - - HA_STAT(HA_GOOD, CIO_SUCCESS); - - ha_state.reply.addr = HA_BOOT_ADDR; - ha_state.reply.len = HA_BLKSZ; -} - -static void ha_boot_tape(UNIT *uptr) -{ - t_seccnt sectsread; - t_stat r; - uint8 buf[HA_BLKSZ]; - uint32 i; - - if (!(uptr->flags & UNIT_ATT)) { - sim_debug(HA_TRACE, &ha_dev, - "[ha_boot_tape] Target not attached\n"); - HA_STAT(HA_CKCON, CIO_SUCCESS); - return; - } - - r = sim_tape_rewind(uptr); - - if (r != SCPE_OK) { - sim_debug(HA_TRACE, &ha_dev, - "[ha_boot_tape] Could not rewind tape\n"); - HA_STAT(HA_CKCON, CIO_SUCCESS); - return; - } - - r = sim_tape_rdrecf(uptr, buf, §sread, HA_BLKSZ); /* Read block 0 */ - - if (r != SCPE_OK) { - sim_debug(HA_TRACE, &ha_dev, - "[ha_boot_tape] Could not read PD block.\n"); - HA_STAT(HA_CKCON, CIO_SUCCESS); - return; - } - - for (i = 0; i < HA_BLKSZ; i++) { - pwrite_b(HA_BOOT_ADDR + i, buf[i]); - } - - sim_debug(HA_TRACE, &ha_dev, - "[ha_boot_tape] Transfered 512 bytes to 0x%08x\n", - HA_BOOT_ADDR); - - r = sim_tape_sprecf(uptr, §sread); /* Skip block 1 */ - - HA_STAT(HA_GOOD, CIO_SUCCESS); - - ha_state.reply.addr = HA_BOOT_ADDR; - ha_state.reply.len = HA_BLKSZ; -} - -static void ha_read_block_tape(UNIT *uptr, uint32 addr) -{ - t_seccnt sectsread; - t_stat r; - uint8 buf[HA_BLKSZ]; - uint32 i; - - if (!(uptr->flags & UNIT_ATT)) { - sim_debug(HA_TRACE, &ha_dev, - "[ha_read_block_tape] Target not attached\n"); - HA_STAT(HA_CKCON, CIO_SUCCESS); - return; - } - - r = sim_tape_rdrecf(uptr, buf, §sread, HA_BLKSZ); - - if (r != SCPE_OK) { - sim_debug(HA_TRACE, &ha_dev, - "[ha_read_block_tape] Could not read next block.\n"); - HA_STAT(HA_CKCON, CIO_SUCCESS); - return; - } - - for (i = 0; i < HA_BLKSZ; i++) { - pwrite_b(addr + i, buf[i]); - } - - sim_debug(HA_TRACE, &ha_dev, - "[ha_read_block_tape] Transfered 512 bytes to 0x%08x\n", - addr); - - HA_STAT(HA_GOOD, CIO_SUCCESS); - - ha_state.reply.addr = addr; - ha_state.reply.len = HA_BLKSZ; -} - -static void ha_read_block_disk(UNIT *uptr, uint8 target, uint32 addr, uint32 lba) -{ - t_seccnt sectsread; - t_stat r; - uint8 buf[HA_BLKSZ]; - uint32 i; - - sim_debug(HA_TRACE, &ha_dev, - "[ha_read_block_disk] Block translated from LBA 0x%X to PBA 0x%X\n", - lba, lba); - - r = sim_disk_rdsect(uptr, lba, buf, §sread, 1); - - if (r != SCPE_OK) { - sim_debug(HA_TRACE, &ha_dev, - "[ha_read_block_disk] Could not read block %d\n", - lba); - HA_STAT(HA_CKCON, CIO_SUCCESS); - return; - } - - for (i = 0; i < HA_BLKSZ; i++) { - pwrite_b(addr + i, buf[i]); - } - - sim_debug(HA_TRACE, &ha_dev, - "[ha_read_block_disk] Transferred 512 bytes to 0x%08x\n", - addr); - - HA_STAT(HA_GOOD, CIO_SUCCESS); - - ha_state.reply.addr = addr; - ha_state.reply.len = HA_BLKSZ; -} - -static void ha_build_req(uint8 subdev, t_bool express) -{ - uint32 i, rqp, ptr, dma_lst; - uint32 len, addr; - cio_entry rqe; - uint8 rapp_data[RAPP_LEN] = {0}; - - /* - * There are two possible ways to get the SCSI command we've - * been asked to perform. - * - * 1. If this is a "fast mode" operation, then the SCSI command - * is embedded in the Fast Request Queue entry. - * - * 2. If this is a regular queue operation, then the SCSI command - * is embedded in a struct pointed to by the "address" field - * of the queue entry. - */ - - for (i = 0; i < HA_MAX_CMD; i++) { - ha_state.request.cmd[i] = 0; - } - - if (ha_state.frq) { - rqp = cio[ha_state.cid].rqp; - - subdev = pread_b(rqp + 2); - - ha_state.request.tc = FC_TC(subdev); - ha_state.request.lu = FC_LU(subdev); - ha_state.request.timeout = pread_w(rqp + 4); - ha_state.request.cmd_len = pread_h(rqp + 18); - for (i = 0; i < HA_MAX_CMD; i++) { - ha_state.request.cmd[i] = pread_b(rqp + 20 + i); - } - ha_state.request.op = ha_state.request.cmd[0]; - - /* Possible list of DMA scatter/gather addresses */ - dma_lst = pread_h(rqp + 16) / 8; - - if (dma_lst) { - t_bool link; - - /* There's a list of address / lengths. Each entry is 8 - * bytes long. */ - ptr = pread_w(rqp + 8); - link = FALSE; - - sim_debug(HA_TRACE, &ha_dev, - "[build_req] Building a list of scatter/gather addresses.\n"); - - for (i = 0; (i < dma_lst) || link; i++) { - addr = pread_w(ptr); - len = pread_w(ptr + 4); - - if (len == 0) { - sim_debug(HA_TRACE, &ha_dev, - "[build_req] Found length of 0, bailing early.\n"); - break; /* Done early */ - } - - if (len > 0x1000) { - /* There's a new pointer in town */ - ptr = pread_w(ptr); - sim_debug(HA_TRACE, &ha_dev, - "[build_req] New ptr=%08x\n", - ptr); - link = TRUE; - continue; - } - - sim_debug(HA_TRACE, &ha_dev, - "[build_req] daddr[%d]: addr=%08x, len=%d (%x)\n", - i, addr, len, len); - - ha_state.request.daddr[i].addr = addr; - ha_state.request.daddr[i].len = len; - - ptr += 8; - } - - ha_state.request.dlen = i; - } else { - /* There's only one embedded address / length */ - ha_state.request.daddr[0].addr = pread_w(rqp + 8); - ha_state.request.daddr[0].len = pread_w(rqp + 12); - ha_state.request.dlen = 1; - } - - } else { - if (express) { - cio_rexpress(ha_state.cid, SCQRESIZE, &rqe, rapp_data); - } else { - /* TODO: Find correct queue number! */ - cio_rqueue(ha_state.cid, 0, SCQRESIZE, &rqe, rapp_data); - } - - ptr = rqe.address; - - ha_state.request.tc = FC_TC(rqe.subdevice); - ha_state.request.lu = FC_LU(rqe.subdevice); - ha_state.request.cmd_len = pread_w(ptr + 4); - ha_state.request.timeout = pread_w(ptr + 8); - ha_state.request.daddr[0].addr = pread_w(ptr + 12); - ha_state.request.daddr[0].len = rqe.byte_count; - ha_state.request.dlen = 1; - - sim_debug(HA_TRACE, &ha_dev, - "[build_req] [non-fast] Building a list of 1 scatter/gather addresses.\n"); - - ptr = pread_w(ptr); - - for (i = 0; (i < ha_state.request.cmd_len) && (i < HA_MAX_CMD); i++) { - ha_state.request.cmd[i] = pread_b(ptr + i); - } - - ha_state.request.op = ha_state.request.cmd[0]; - } -} - -static void ha_cmd(uint8 op, uint8 subdev, uint32 addr, int32 len, t_bool express) -{ - int32 i, block; - UNIT *uptr; - SCSI_DEV *dev; - int8 target; - - /* Immediately cancel any pending IRQs */ - sim_cancel(cio_unit); - - ha_state.reply.pending = TRUE; - ha_state.reply.op = op; - ha_state.reply.subdev = subdev; - ha_state.reply.status = CIO_FAILURE; - ha_state.reply.ssb = 0; - ha_state.reply.len = 0; - ha_state.reply.addr = 0; - - if (ha_state.pump_state == PUMP_COMPLETE) { - ha_state.reply.op |= 0x80; - } - - if (ha_state.frq) { - ha_state.reply.type = HA_JOB_QUICK; - } else if (express) { - ha_state.reply.type = HA_JOB_EXPRESS; - } else { - ha_state.reply.type = HA_JOB_FULL; - } - - sim_debug(HA_TRACE, &ha_dev, - "[ha_cmd] --------------------------[START]---------------------------------\n"); - sim_debug(HA_TRACE, &ha_dev, - "[ha_cmd] op=%02x (%d), subdev=%02x, addr=%08x, len=%d\n", - op, op, subdev, addr, len); - - dump_req(); - - switch (op) { - case CIO_DLM: - for (i = 0; i < len; i++) { - ha_crc = cio_crc32_shift(ha_crc, pread_b(addr + i)); - } - - sim_debug(HA_TRACE, &ha_dev, - "[ha_cmd] SCSI Download Memory: bytecnt=%04x " - "addr=%08x return_addr=%08x subdev=%02x (CRC=%08x)\n", - len, addr, addr, subdev, ha_crc); - ha_state.reply.status = CIO_SUCCESS; - sim_activate_abs(cio_unit, 1200); - break; - case CIO_FCF: - sim_debug(HA_TRACE, &ha_dev, - "[ha_cmd] SCSI Force Function Call. (CRC=%08x)\n", - ha_crc); - cio[ha_state.cid].sysgen_s = 0; - ha_state.reply.status = CIO_SUCCESS; - sim_activate_abs(cio_unit, 1200); - break; - case CIO_DSD: - sim_debug(HA_TRACE, &ha_dev, - "[ha_cmd] SCSI DSD - %d CONFIGURED DEVICES (writing to addr %08x).\n", - ha_subdev_cnt, addr); - - pwrite_h(addr, ha_subdev_cnt); - - for (i = 0; i < ha_subdev_cnt; i++) { - addr += 2; - - target = ha_subdev_tab[i]; - - if (target < 0) { - pwrite_h(addr, 0); - continue; - } - - uptr = &ha_unit[target]; - - dev = (SCSI_DEV *)uptr->up7; - - sim_debug(HA_TRACE, &ha_dev, - "[ha_cmd] [DSD] Probing subdev %d, target %d, devtype %d\n", - i, target, dev->devtype); - - switch(dev->devtype) { - case SCSI_DISK: - sim_debug(HA_TRACE, &ha_dev, - "[ha_cmd] [DSD] Subdev %d is DISK (writing to addr %08x)\n", - i, addr); - pwrite_h(addr, HA_DSD_DISK); - break; - case SCSI_TAPE: - sim_debug(HA_TRACE, &ha_dev, - "[ha_cmd] [DSD] Subdev %d is TAPE (writing to addr %08x)\n", - i, addr); - pwrite_h(addr, HA_DSD_TAPE); - break; - default: - sim_debug(HA_TRACE, &ha_dev, - "[ha_cmd] [DSD] Warning: No device type for subdev %d (Writing to addr %08x)\n", - i, addr); - pwrite_h(addr, 0); - break; - } - } - - ha_state.reply.status = CIO_SUCCESS; - - sim_activate_abs(cio_unit, 5000); - - break; - case HA_BOOT: - target = ha_subdev_tab[subdev & 7]; - - sim_debug(HA_TRACE, &ha_dev, - "[ha_cmd] TARGET %d BOOTING.\n", - target); - - if (target < 0) { - ha_state.reply.status = CIO_TIMEOUT; - sim_activate_abs(cio_unit, 250); - return; - } - - uptr = &ha_unit[target]; - - if (!(uptr->flags & UNIT_ATT)) { - sim_debug(HA_TRACE, &ha_dev, - "[ha_cmd] TARGET %d NOT ATTACHED.\n", - target); - ha_state.reply.status = CIO_TIMEOUT; - sim_activate_abs(cio_unit, 250); - return; - } - - dev = (SCSI_DEV *)uptr->up7; - - switch(dev->devtype) { - case SCSI_DISK: - ha_boot_disk(uptr, target); - break; - case SCSI_TAPE: - ha_boot_tape(uptr); - break; - default: - sim_debug(HA_TRACE, &ha_dev, - "[HA_BOOT] Cannot boot target %d (not disk or tape).\n", - target); - ha_state.reply.status = CIO_SUCCESS; - break; - } - - sim_activate_abs(cio_unit, 5000); - break; - case HA_READ_BLK: - target = ha_subdev_tab[subdev & 7]; - - sim_debug(HA_TRACE, &ha_dev, - "[ha_cmd] SUBDEV %d TARGET %d READ BLOCK (BLOCK 0x%08x TO ADDR 0x%08x)\n", - subdev, target, pread_w(addr), pread_w(addr + 4)); - - sim_debug(HA_TRACE, &ha_dev, - "[boot_next] addr = %08x\n", - addr); - sim_debug(HA_TRACE, &ha_dev, - "[boot_next] %08x = %08x\n", - addr, pread_w(addr)); - sim_debug(HA_TRACE, &ha_dev, - "[boot_next] %08x = %08x\n", - addr + 4, pread_w(addr + 4)); - sim_debug(HA_TRACE, &ha_dev, - "[boot_next] %08x = %08x\n", - addr + 8, pread_w(addr + 8)); - sim_debug(HA_TRACE, &ha_dev, - "[boot_next] %08x = %08x\n", - addr + 12, pread_w(addr + 12)); - sim_debug(HA_TRACE, &ha_dev, - "[boot_next] %08x = %08x\n", - addr + 16, pread_w(addr + 16)); - - - if (target < 0) { - ha_state.reply.status = CIO_TIMEOUT; - sim_activate_abs(cio_unit, 250); - return; - } - - uptr = &ha_unit[target]; - - if (!(uptr->flags & UNIT_ATT)) { - ha_state.reply.status = CIO_TIMEOUT; - sim_activate_abs(cio_unit, 250); - return; - } - - dev = (SCSI_DEV *)uptr->up7; - block = pread_w(addr); /* Logical block we've been asked to read */ - addr = pread_w(addr + 4); /* Dereference the pointer to the destination */ - - switch(dev->devtype) { - case SCSI_TAPE: - ha_read_block_tape(uptr, addr); - break; - case SCSI_DISK: - ha_read_block_disk(uptr, target, addr, block); - break; - default: - sim_debug(HA_TRACE, &ha_dev, - "[HA_READ_BLOCK] Cannot read block %d on target %d (not disk or tape)\n", - block, target); - ha_state.reply.status = CIO_SUCCESS; - break; - } - - sim_activate_abs(cio_unit, 5000); - - break; - case HA_CNTRL: - sim_debug(HA_TRACE, &ha_dev, - "[ha_cmd] SCSI CONTROL (subdev=%02x addr=%08x)\n", - subdev, addr); - - ha_build_req(subdev, express); - ha_ctrl(); - sim_activate_abs(cio_unit, 1000); - break; - case HA_VERS: - /* - * Get Host Adapter Version - */ - - sim_debug(HA_TRACE, &ha_dev, - "[ha_cmd] SCSI GET VERSION (addr=%08x len=%08x)\n", - addr, len); - - pwrite_w(addr, HA_VERSION); - ha_state.reply.status = CIO_SUCCESS; - sim_activate_abs(cio_unit, 5000); - - break; - case HA_DL_EEDT: - /* - * This is a request to download the Extended Equipped Device - * Table from the host adapter to the 3B2 main memory. - */ - - sim_debug(HA_TRACE, &ha_dev, - "[ha_cmd] SCSI DOWNLOAD EDT (%d bytes to address %08x)\n", - len, addr); - - for (i = 0; i < len; i++) { - pwrite_b(addr + i, ha_state.edt[i]); - } - - ha_state.reply.status = CIO_SUCCESS; - - sim_activate_abs(cio_unit, 5000); - - break; - case HA_UL_EEDT: - /* - * This is a request to upload the Extended Equipped Device - * Table from the 3B2 main memory to the host adapter - */ - - sim_debug(HA_TRACE, &ha_dev, - "[ha_cmd] SCSI UPLOAD EDT (%d bytes from address %08x)\n", - len, addr); - - for (i = 0; i < len; i++) { - ha_state.edt[i] = pread_b(addr + i); - } - - ha_state.reply.status = CIO_SUCCESS; - - sim_activate_abs(cio_unit, 5000); - - break; - case HA_EDSD: - /* - * This command is used to determine which TCs are attached to - * the SCSI bus, and what LUNs they support. A "1" in a slot - * means that the target is not a direct block device. Since we - * only support direct block devices, we just put "0" in each - * slot. - */ - - sim_debug(HA_TRACE, &ha_dev, - "[%08x] [ha_cmd] SCSI EXTENDED DSD.\n", - R[NUM_PC]); - - ha_state.reply.status = CIO_SUCCESS; - ha_state.reply.addr = addr; - ha_state.reply.len = 9; - - for (i = 0; i < 8; i++) { - uptr = &ha_unit[i]; - pwrite_b(addr + i, (uptr->flags & UNIT_ATT) ? 1 : 0); - } - - pwrite_b(addr + 8, HA_SCSI_ID); /* ID of the card */ - - sim_activate_abs(cio_unit, 200); - - break; - case 0x45: - scsi_reset(&ha_bus); - - ha_state.reply.status = CIO_SUCCESS; - ha_state.reply.addr = addr; - ha_state.reply.len = 0; - - sim_activate_abs(cio_unit, 2500); - break; - default: - sim_debug(HA_TRACE, &ha_dev, - "[%08x] *** SCSI WARNING: UNHANDLED OPCODE 0x%02x\n", - R[NUM_PC], op); - - ha_state.reply.status = CIO_FAILURE; - - sim_activate_abs(cio_unit, 200); - } - - sim_debug(HA_TRACE, &ha_dev, - "[ha_cmd] ---------------------------[END]----------------------------------\n"); - -} - -/* - * Handle a raw SCSI control message. - */ -void ha_ctrl() -{ - volatile t_bool txn_done; - uint32 i, j; - uint32 plen, ha_ptr; - uint32 in_len, out_len; - uint8 lu, status; - uint8 msgi_buf[64]; - uint32 msgi_len; - uint32 to_read; - - sim_debug(HA_TRACE, &ha_dev, - "[ha_ctrl] [HA_REQ] TC=%d LU=%d TIMEOUT=%d DLEN=%d\n", - ha_state.request.tc, ha_state.request.lu, ha_state.request.timeout, ha_state.request.dlen); - - sim_debug(HA_TRACE, &ha_dev, - "[ha_ctrl] [HA_REQ] CMD_LEN=%d CMD=<%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x>\n", - ha_state.request.cmd_len, - ha_state.request.cmd[0], ha_state.request.cmd[1], - ha_state.request.cmd[2], ha_state.request.cmd[3], - ha_state.request.cmd[4], ha_state.request.cmd[5], - ha_state.request.cmd[6], ha_state.request.cmd[7], - ha_state.request.cmd[8], ha_state.request.cmd[9]); - - in_len = out_len = 0; - - /* - * These ops need special handling. - */ - switch(ha_state.request.op) { - case HA_TESTRDY: - /* Fail early if LU is set */ - if (ha_state.request.lu) { - HA_STAT(HA_CKCON, CIO_TIMEOUT); - return; - } - break; - case HA_FORMAT: /* Not yet handled by sim_scsi library */ - case HA_VERIFY: /* Not yet handled by sim_scsi library */ - /* Just mimic success */ - HA_STAT(HA_GOOD, CIO_SUCCESS); - return; - } - - /* Get the bus's attention */ - if (!scsi_arbitrate(&ha_bus, HA_SCSI_ID)) { - HA_STAT(HA_CKCON, CIO_TIMEOUT); - return; - } - - scsi_set_atn(&ha_bus); - - if (!scsi_select(&ha_bus, ha_state.request.tc)) { - HA_STAT(HA_CKCON, CIO_TIMEOUT); - scsi_release(&ha_bus); - return; - } - - /* Select the correct LU */ - lu = 0x80 | ha_state.request.lu; - scsi_write(&ha_bus, &lu, 1); - - txn_done = FALSE; - - while (!txn_done) { - switch(ha_bus.phase) { - case SCSI_CMD: - plen = scsi_write(&ha_bus, ha_state.request.cmd, ha_state.request.cmd_len); - if (plen < ha_state.request.cmd_len) { - HA_STAT(HA_CKCON, CIO_SUCCESS); - scsi_release(&ha_bus); - return; - } - break; - case SCSI_DATI: - /* This is a read */ - in_len = scsi_read(&ha_bus, ha_buf, HA_MAXFR); - - sim_debug(HA_TRACE, &ha_dev, - "[ha_ctrl] SCSI_DATI: Consumed %d (0x%X) bytes to ha_buf in SCSI read.\n", - in_len, in_len); - - /* We need special handling based on the op code */ - switch(ha_state.request.op) { - case HA_READ: - case HA_READEXT: - ha_ptr = 0; - - for (i = 0; i < ha_state.request.dlen; i++) { - /* - * Consume the lesser of: - * - The total bytes we consumed, or: - * - The length of the current block - */ - to_read = MIN(ha_state.request.daddr[i].len, in_len); - - sim_debug(HA_TRACE, &ha_dev, - "[(%02x) TC%d,LU%d] DATI: Processing %d bytes to address %08x...\n", - ha_state.request.op, ha_state.request.tc, ha_state.request.lu, to_read, ha_state.request.daddr[i].addr); - - for (j = 0; j < to_read; j++) { - pwrite_b(ha_state.request.daddr[i].addr + j, ha_buf[ha_ptr++]); - } - - if (in_len >= to_read) { - in_len -= to_read; - } else { - /* Nothing left to write */ - break; - } - } - - break; - default: - sim_debug(HA_TRACE, &ha_dev, - "[(%02x) TC%d,LU%d] DATI: Processing %d bytes to address %08x...\n", - ha_state.request.op, ha_state.request.tc, - ha_state.request.lu, in_len, - ha_state.request.daddr[0].addr); - for (i = 0; i < in_len; i++) { - sim_debug(HA_TRACE, &ha_dev, "[%04x] [DATI] 0x%02x\n", i, ha_buf[i]); - pwrite_b(ha_state.request.daddr[0].addr + i, ha_buf[i]); - } - - break; - } - - break; - case SCSI_DATO: - /* This is a write */ - ha_ptr = 0; - out_len = 0; - ha_state.reply.len = ha_state.request.dlen; - - for (i = 0; i < ha_state.request.dlen; i++) { - sim_debug(HA_TRACE, &ha_dev, - "[ha_ctrl] [%d] DATO: Writing %d bytes to ha_buf.\n", - i, ha_state.request.daddr[i].len); - - for (j = 0; j < ha_state.request.daddr[i].len; j++) { - ha_buf[ha_ptr++] = pread_b(ha_state.request.daddr[i].addr + j); - } - - out_len += ha_state.request.daddr[i].len; - } - - if (ha_state.request.op == HA_WRITE || ha_state.request.op == HA_WRTEXT) { - /* If total len is not on a block boundary, we have to - bump it up in order to write the whole block. */ - if (out_len % HA_BLKSZ) { - out_len = out_len + (HA_BLKSZ - (out_len % HA_BLKSZ)); - } - } - - scsi_write(&ha_bus, ha_buf, out_len); - - sim_debug(HA_TRACE, &ha_dev, - "[ha_ctrl] SCSI Write of %08x (%d) bytes Complete\n", - out_len, out_len); - break; - case SCSI_STS: - scsi_read(&ha_bus, &status, 1); - sim_debug(HA_TRACE, &ha_dev, - "[ha_ctrl] STATUS BYTE: %02x\n", - status); - break; - case SCSI_MSGI: - msgi_len = scsi_read(&ha_bus, msgi_buf, 64); - sim_debug(HA_TRACE, &ha_dev, - "[ha_ctrl] MESSAGE IN LENGTH %d\n", - msgi_len); - - for (i = 0; i < msgi_len; i++) { - sim_debug(HA_TRACE, &ha_dev, - "[ha_ctrl] MSGI[%02d] = %02x\n", - i, msgi_buf[i]); - } - - txn_done = TRUE; - break; - } - } - - if (ha_bus.sense_info) { - sim_debug(HA_TRACE, &ha_dev, "[ha_ctrl] SENSE INFO=%d, CKCON.\n", ha_bus.sense_info); - HA_STAT(HA_CKCON, 0x60); - } else { - sim_debug(HA_TRACE, &ha_dev, "[ha_ctrl] NO SENSE INFO.\n"); - HA_STAT(HA_GOOD, CIO_SUCCESS); - } - - /* Release the bus */ - scsi_release(&ha_bus); -} - -void ha_fcm_express() -{ - uint32 rqp, cqp, cqs; - - rqp = cio[ha_state.cid].rqp; - cqp = cio[ha_state.cid].cqp; - cqs = cio[ha_state.cid].cqs; - - /* Write the fast completion entry. */ - pwrite_b(cqp + cq_offset, ha_state.reply.status); - pwrite_b(cqp + cq_offset + 1, ha_state.reply.op); - pwrite_b(cqp + cq_offset + 2, ha_state.reply.subdev); - pwrite_b(cqp + cq_offset + 3, ha_state.reply.ssb); - - sim_debug(HA_TRACE, &ha_dev, - "[ha_fcm_express] stat=%02x, op=%02x (%d), cq_index=%d target=%d, lun=%d, ssb=%02x\n", - ha_state.reply.status, ha_state.reply.op, ha_state.reply.op, - (cq_offset / 4), - FC_TC(ha_state.reply.subdev), FC_LU(ha_state.reply.subdev), - ha_state.reply.ssb); - - if (ha_state.pump_state == PUMP_COMPLETE && cqs > 0) { - cq_offset = (cq_offset + 4) % (cqs * 4); - } else { - cq_offset = 0; - } -} - -t_stat ha_set_type(UNIT *uptr, int32 val, CONST char *cptr, void *desc) -{ - if (val < 0 || cptr || val > HA_MAX_DTYPE) { - return SCPE_ARG; - } - - if (uptr->flags & UNIT_ATT) { - return SCPE_ALATT; - } - - uptr->flags = (uptr->flags & ~UNIT_DTYPE) | (val << UNIT_V_DTYPE); - uptr->capac = (t_addr) ha_tab[val].lbn; - scsi_set_unit(&ha_bus, uptr, &ha_tab[val]); - scsi_reset_unit(uptr); - return SCPE_OK; -} - -t_stat ha_show_type(FILE *st, UNIT *uptr, int32 val, CONST void *desc) -{ - fprintf(st, "%s", ha_tab[GET_DTYPE(uptr->flags)].name); - - return SCPE_OK; -} - -/* Used for debugging only */ -/* TODO: Remove after testing */ -static void dump_edt() -{ - uint8 tc_size, lu_size, num_tc, num_lu, i, j; - - uint32 offset; - - char name[11]; - - sim_debug(HA_TRACE, &ha_dev, - "[EDT] Sanity: %08x\n", - ATOW(ha_state.edt, 0)); - - sim_debug(HA_TRACE, &ha_dev, - "[EDT] Version: %d\n", - ha_state.edt[4]); - - sim_debug(HA_TRACE, &ha_dev, - "[EDT] Slot: %d\n", - ha_state.edt[5]); - - sim_debug(HA_TRACE, &ha_dev, - "[EDT] Max TC: %d\n", - ha_state.edt[6]); - - sim_debug(HA_TRACE, &ha_dev, - "[EDT] TC Size: %d\n", - ha_state.edt[7]); - - sim_debug(HA_TRACE, &ha_dev, - "[EDT] Max LUs: %d\n", - ha_state.edt[8]); - - sim_debug(HA_TRACE, &ha_dev, - "[EDT] LU Size: %d\n", - ha_state.edt[9]); - - sim_debug(HA_TRACE, &ha_dev, - "[EDT] Equipped TCs: %d\n", - ha_state.edt[10]); - - tc_size = ha_state.edt[7]; - lu_size = ha_state.edt[9]; - num_tc = ha_state.edt[10] + 1; - - for (i = 0; i < num_tc; i++) { - offset = 12 + (tc_size * i); - num_lu = ha_state.edt[offset + 17]; - - strncpy(name, ((const char *)ha_state.edt + offset + 4), 10); - - sim_debug(HA_TRACE, &ha_dev, - "[EDT] -------------------------\n"); - sim_debug(HA_TRACE, &ha_dev, - "[EDT] [TC%d] Major Number: %d\n", - i, ATOW(ha_state.edt, offset)); - sim_debug(HA_TRACE, &ha_dev, - "[EDT] [TC%d] Name: %s\n", - i, name); - sim_debug(HA_TRACE, &ha_dev, - "[EDT] [TC%d] Type: %d\n", - i, ATOH(ha_state.edt, offset + 14)); - sim_debug(HA_TRACE, &ha_dev, - "[EDT] [TC%d] Equipped?: %d\n", - i, ha_state.edt[offset + 16]); - sim_debug(HA_TRACE, &ha_dev, - "[EDT] [TC%d] Equipped LUs: %d\n", - i, ha_state.edt[offset + 17]); - sim_debug(HA_TRACE, &ha_dev, - "[EDT] [TC%d] Maximum LUs: %d\n", - i, ha_state.edt[offset + 18]); - sim_debug(HA_TRACE, &ha_dev, - "[EDT] [TC%d] LU Index: %04x\n", - i, ATOH(ha_state.edt, offset + 20)); - - offset = ATOH(ha_state.edt, offset + 20); - - for (j = 0; j < num_lu; j++) { - - offset = offset + (j * lu_size); - - sim_debug(HA_TRACE, &ha_dev, - "[EDT] -------------------------\n"); - sim_debug(HA_TRACE, &ha_dev, - "[EDT] [TC%d,LU%d] LU #: %d\n", - i, j, ha_state.edt[offset]); - sim_debug(HA_TRACE, &ha_dev, - "[EDT] [TC%d,LU%d] PD Type: 0x%02x\n", - i, j, ha_state.edt[offset + 1]); - sim_debug(HA_TRACE, &ha_dev, - "[EDT] [TC%d,LU%d] Dev Type: 0x%02x\n", - i, j, ha_state.edt[offset + 2] >> 1); - sim_debug(HA_TRACE, &ha_dev, - "[EDT] [TC%d,LU%d] Removable?: %d\n", - i, j, ha_state.edt[offset + 2] & 1); - } - - } - -} +/* 3b2_scsi.c: CM195W SCSI Controller CIO Card + + Copyright (c) 2020-2022, Seth J. Morabito + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + Except as contained in this notice, the name of the author shall + not be used in advertising or otherwise to promote the sale, use or + other dealings in this Software without prior written authorization + from the author. +*/ + +#include "3b2_scsi.h" + +#include "sim_scsi.h" +#include "sim_tape.h" + +#include "3b2_cpu.h" +#include "3b2_io.h" +#include "3b2_mem.h" + +#define DIAG_CRC_1 0x271b114c +#define PUMP_CRC 0x201b3617 + +#define HA_SCSI_ID 0 +#define HA_MAXFR (1u << 16) + +static void ha_cmd(uint8 op, uint8 subdev, uint32 addr, + int32 len, t_bool express); +static void ha_build_req(uint8 tc, uint8 subdev, t_bool express); +static void ha_ctrl(uint8 tc); + + +HA_STATE ha_state; +SCSI_BUS ha_bus; +uint8 *ha_buf; +int8 ha_subdev_tab[8]; /* Map of subdevice to SCSI target */ +uint8 ha_subdev_cnt; +uint32 ha_crc = 0; +uint32 cq_offset = 0; +t_bool ha_conf = FALSE; + +static struct scsi_dev_t ha_tab[] = { + HA_DISK(SD155), + HA_DISK(SD300), + HA_DISK(SD327), + HA_DISK(SD630), + HA_TAPE(ST120) +}; + +#define SCSI_U_FLAGS (UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_DIS+ \ + UNIT_ROABLE+(SD155_DTYPE << UNIT_V_DTYPE)) + +UNIT ha_unit[] = { + { UDATA (&ha_svc, UNIT_DIS, 0) }, /* SCSI ID 0 - the host adapter */ + { UDATA (&ha_svc, SCSI_U_FLAGS, HA_SIZE(SD155)) }, /* SCSI ID 1 */ + { UDATA (&ha_svc, SCSI_U_FLAGS, HA_SIZE(SD155)) }, /* SCSI ID 2 */ + { UDATA (&ha_svc, SCSI_U_FLAGS, HA_SIZE(SD155)) }, /* SCSI ID 3 */ + { UDATA (&ha_svc, SCSI_U_FLAGS, HA_SIZE(SD155)) }, /* SCSI ID 4 */ + { UDATA (&ha_svc, SCSI_U_FLAGS, HA_SIZE(SD155)) }, /* SCSI ID 5 */ + { UDATA (&ha_svc, SCSI_U_FLAGS, HA_SIZE(SD155)) }, /* SCSI ID 6 */ + { UDATA (&ha_svc, SCSI_U_FLAGS, HA_SIZE(SD155)) }, /* SCSI ID 7 */ +}; + +static UNIT *cio_unit = &ha_unit[0]; + +MTAB ha_mod[] = { + { SCSI_WLK, 0, NULL, "WRITEENABLED", + &scsi_set_wlk, NULL, NULL, "Write enable disk drive" }, + { SCSI_WLK, SCSI_WLK, NULL, "LOCKED", + &scsi_set_wlk, NULL, NULL, "Write lock disk drive" }, + { MTAB_XTD|MTAB_VUN, 0, "WRITE", NULL, + NULL, &scsi_show_wlk, NULL, "Display drive writelock status" }, + { MTAB_XTD|MTAB_VUN, SD155_DTYPE, NULL, "SD155", + &ha_set_type, NULL, NULL, "Set 155MB Disk Type" }, + { MTAB_XTD|MTAB_VUN, SD300_DTYPE, NULL, "SD300", + &ha_set_type, NULL, NULL, "Set 300MB Disk Type" }, + { MTAB_XTD|MTAB_VUN, SD327_DTYPE, NULL, "SD327", + &ha_set_type, NULL, NULL, "Set 327MB Disk Type" }, + { MTAB_XTD|MTAB_VUN, SD630_DTYPE, NULL, "SD630", + &ha_set_type, NULL, NULL, "Set 630MB Disk Type" }, + { MTAB_XTD|MTAB_VUN, ST120_DTYPE, NULL, "ST120", + &ha_set_type, NULL, NULL, "Set Wangtek 120MB Tape Type" }, + { MTAB_XTD|MTAB_VUN, 0, "TYPE", NULL, + NULL, &ha_show_type, NULL, "Display device type" }, + { MTAB_XTD|MTAB_VUN, 0, "FORMAT", "FORMAT", + &scsi_set_fmt, &scsi_show_fmt, NULL, "Set/Display unit format" }, + { 0 } +}; + +#define HA_TRACE 1 + +static DEBTAB ha_debug[] = { + { "TRACE", HA_TRACE, "Call Trace" }, + { "SCMD", SCSI_DBG_CMD, "SCSI commands"}, + { "SBUS", SCSI_DBG_BUS, "SCSI bus activity" }, + { "SMSG", SCSI_DBG_MSG, "SCSI messages" }, + { "SDSK", SCSI_DBG_DSK, "SCSI disk activity" }, + { "STAP", MTSE_DBG_API, "SCSI tape activity" }, + { NULL } +}; + +DEVICE ha_dev = { + "SCSI", /* name */ + ha_unit, /* units */ + NULL, /* registers */ + ha_mod, /* modifiers */ + 8, /* #units */ + 16, /* address radix */ + 32, /* address width */ + 1, /* address incr. */ + 16, /* data radix */ + 8, /* data width */ + NULL, /* examine routine */ + NULL, /* deposit routine */ + &ha_reset, /* reset routine */ + NULL, /* boot routine */ + &ha_attach, /* attach routine */ + &ha_detach, /* detach routine */ + NULL, /* context */ + DEV_DEBUG|DEV_DISK|DEV_SECTORS, /* flags */ + 0, /* debug control flags */ + ha_debug, /* debug flag names */ + NULL, /* memory size change */ + NULL, /* logical name */ + NULL, /* help routine */ + NULL, + NULL, + NULL, +}; + +void ha_cio_reset(uint8 slot) +{ + sim_debug(HA_TRACE, &ha_dev, + "Handling CIO reset\n"); + ha_state.pump_state = PUMP_NONE; + ha_crc = 0; +} + +t_stat ha_reset(DEVICE *dptr) +{ + uint8 slot; + uint32 t, dtyp; + UNIT *uptr; + t_stat r; + + ha_state.pump_state = PUMP_NONE; + + if (ha_buf == NULL) { + ha_buf = (uint8 *)calloc(HA_MAXFR, sizeof(uint8)); + } + + r = scsi_init(&ha_bus, HA_MAXFR); + + if (r != SCPE_OK) { + return r; + } + + ha_bus.dptr = dptr; + + scsi_reset(&ha_bus); + + for (t = 0; t < 8; t++) { + uptr = dptr->units + t; + if (t == HA_SCSI_ID) { + uptr->flags = UNIT_DIS; + } + scsi_add_unit(&ha_bus, t, uptr); + dtyp = GET_DTYPE(uptr->flags); + scsi_set_unit(&ha_bus, uptr, &ha_tab[dtyp]); + scsi_reset_unit(uptr); + } + + if (dptr->flags & DEV_DIS) { + cio_remove_all(HA_ID); + ha_conf = FALSE; + return SCPE_OK; + } + + if (!ha_conf) { + r = cio_install(HA_ID, "SCSI", HA_IPL, + &ha_express, &ha_full, &ha_sysgen, &ha_cio_reset, + &slot); + if (r != SCPE_OK) { + return r; + } + ha_state.slot = slot; + ha_conf = TRUE; + } + + return SCPE_OK; +} + +static void ha_calc_subdevs() +{ + uint32 tc; + UNIT *uptr; + + ha_subdev_cnt = 0; + + memset(ha_subdev_tab, -1, 8); + + for (tc = 0; tc < 8; tc++) { + uptr = &ha_unit[tc]; + if (uptr->flags & UNIT_ATT) { + ha_subdev_tab[ha_subdev_cnt++] = tc; + } + } +} + +t_stat ha_attach(UNIT *uptr, CONST char *cptr) +{ + t_stat r; + r = scsi_attach(uptr, cptr); + ha_calc_subdevs(); + return r; +} + +t_stat ha_detach(UNIT *uptr) +{ + t_stat r; + r = scsi_detach(uptr); + ha_calc_subdevs(); + return r; +} + +t_stat ha_svc(UNIT *uptr) +{ + cio_entry cqe; + uint8 capp_data[CAPP_LEN] = {0}; + int8 i, tc = -1; + uint8 svc_req = 0; + ha_req *req = NULL; + ha_resp *rep = NULL; + + sim_debug(HA_TRACE, &ha_dev, + "[ha_svc] SERVICE ROUTINE\n"); + + /* Determine how many targets need servicing */ + for (i = 0; i < 8; i++) { + if (ha_state.ts[i].pending) { + if (req == NULL && rep == NULL) { + tc = i; + sim_debug(HA_TRACE, &ha_dev, + "[ha_svc] Found a job for target %d\n", + tc); + req = &ha_state.ts[i].req; + rep = &ha_state.ts[i].rep; + ha_state.ts[i].pending = FALSE; + } + svc_req++; + } + } + + if (tc == -1) { + return SCPE_OK; + } + + switch(rep->type) { + case HA_JOB_QUICK: + ha_fcm_express(tc); + + sim_debug(HA_TRACE, &ha_dev, + "[ha_svc] FAST MODE CQ: target=%d status=%02x op=%02x subdev=%02x ssb=%02x\n", + tc, rep->status, rep->op, rep->subdev, rep->ssb); + break; + case HA_JOB_EXPRESS: + case HA_JOB_FULL: + cqe.byte_count = rep->len; + cqe.opcode = rep->status; /* Yes, status, not opcode! */ + cqe.subdevice = rep->subdev; + cqe.address = rep->addr; + + sim_debug(HA_TRACE, &ha_dev, + "[ha_svc] CQE: target=%d, byte_count=%04x, opcode=%02x, subdevice=%02x, addr=%08x\n", + tc, cqe.byte_count, cqe.opcode, cqe.subdevice, cqe.address); + + if (rep->type == HA_JOB_EXPRESS) { + sim_debug(HA_TRACE, &ha_dev, + "[ha_svc] EXPRESS MODE CQ: target=%d, byte_count=%02x " + "op=%02x subdev=%02x address=%08x\n", + tc, cqe.byte_count, cqe.opcode, cqe.subdevice, cqe.address); + + cio_cexpress(ha_state.slot, SCQCESIZE, &cqe, capp_data); + } else { + sim_debug(HA_TRACE, &ha_dev, + "[ha_svc] FULL MODE CQ: target=%d, status=%02x op=%02x subdev=%02x ssb=%02x\n", + tc, rep->status, rep->op, rep->subdev, rep->ssb); + + cio_cqueue(ha_state.slot, 0, SCQCESIZE, &cqe, capp_data); + } + break; + } + + sim_debug(HA_TRACE, &ha_dev, + "[ha_svc] IRQ for board %d (VEC=%d). PSW_CUR_IPL=%d\n", + ha_state.slot, cio[ha_state.slot].ivec, PSW_CUR_IPL); + + CIO_SET_INT(ha_state.slot); + + /* There's more work to do after this job is done */ + if (svc_req > 1) { + sim_debug(HA_TRACE, &ha_dev, + "[ha_svc] Scheduling job to handle another %d open requests\n", + svc_req - 1); + sim_activate_abs(uptr, 1000); + } + + return SCPE_OK; +} + +void ha_sysgen(uint8 slot) +{ + uint32 sysgen_p; + uint32 alert_buf_p; + + cq_offset = 0; + + sim_debug(HA_TRACE, &ha_dev, "[ha_sysgen] Handling Sysgen.\n"); + sim_debug(HA_TRACE, &ha_dev, "[ha_sysgen] rqp=%08x\n", cio[slot].rqp); + sim_debug(HA_TRACE, &ha_dev, "[ha_sysgen] cqp=%08x\n", cio[slot].cqp); + sim_debug(HA_TRACE, &ha_dev, "[ha_sysgen] rqs=%d\n", cio[slot].rqs); + sim_debug(HA_TRACE, &ha_dev, "[ha_sysgen] cqs=%d\n", cio[slot].cqs); + sim_debug(HA_TRACE, &ha_dev, "[ha_sysgen] ivec=%d\n", cio[slot].ivec); + sim_debug(HA_TRACE, &ha_dev, "[ha_sysgen] no_rque=%d\n", cio[slot].no_rque); + + sysgen_p = pread_w(SYSGEN_PTR, BUS_PER); + alert_buf_p = pread_w(sysgen_p + 12, BUS_PER); + sim_debug(HA_TRACE, &ha_dev, "[ha_sysgen] alert_bfr=%08x\n", alert_buf_p); + + ha_state.frq = (cio[slot].no_rque == 0); + + ha_state.ts[HA_SCSI_ID].rep.type = ha_state.frq ? HA_JOB_QUICK : HA_JOB_EXPRESS; + ha_state.ts[HA_SCSI_ID].rep.addr = 0; + ha_state.ts[HA_SCSI_ID].rep.len = 0; + ha_state.ts[HA_SCSI_ID].rep.status = 3; + ha_state.ts[HA_SCSI_ID].rep.op = 0; + ha_state.ts[HA_SCSI_ID].pending = TRUE; + + if (ha_crc == PUMP_CRC) { + sim_debug(HA_TRACE, &ha_dev, + "[ha_sysgen] PUMP: NEW STATE = PUMP_SYSGEN\n"); + ha_state.pump_state = PUMP_SYSGEN; + } else { + sim_debug(HA_TRACE, &ha_dev, + "[ha_sysgen] PUMP: NEW STATE = PUMP_NONE\n"); + ha_state.pump_state = PUMP_NONE; + } + + sim_activate_abs(cio_unit, 1000); +} + +void ha_fast_queue_check() +{ + uint8 busy, op, subdev; + uint32 addr, len, rqp; + + rqp = cio[ha_state.slot].rqp; + + busy = pread_b(rqp, BUS_PER); + op = pread_b(rqp + 1, BUS_PER); + subdev = pread_b(rqp + 2, BUS_PER); + /* 4-byte timeout value at rqp + 4 not used */ + addr = pread_w(rqp + 8, BUS_PER); + len = pread_w(rqp + 12, BUS_PER); + + if (busy == 0xff || ha_state.pump_state != PUMP_COMPLETE) { + sim_debug(HA_TRACE, &ha_dev, + "[ha_fast_queue_check] Job pending (opcode=0x%02x subdev=%02x)\n", + op, subdev); + pwrite_b(rqp, 0, BUS_PER); /* Job has been taken */ + ha_cmd(op, subdev, addr, len, FALSE); + } +} + +void ha_express(uint8 slot) +{ + cio_entry rqe; + uint8 rapp_data[RAPP_LEN] = {0}; + + if (ha_state.frq) { + ha_fast_queue_check(); + } else { + cio_rexpress(slot, SCQRESIZE, &rqe, rapp_data); + + sim_debug(HA_TRACE, &ha_dev, + "[ha_express] Handling Express Request. subdev=%02x\n", + rqe.subdevice); + + ha_cmd(rqe.opcode, rqe.subdevice, rqe.address, rqe.byte_count, TRUE); + } +} + +void ha_full(uint8 slot) +{ + sim_debug(HA_TRACE, &ha_dev, + "[ha_full] Handling Full Request (INT3)\n"); + + if (ha_state.pump_state == PUMP_SYSGEN) { + sim_debug(HA_TRACE, &ha_dev, + "[ha_full] PUMP: NEW STATE = PUMP_COMPLETE\n"); + + ha_state.pump_state = PUMP_COMPLETE; + } + + if (ha_state.frq) { + ha_fast_queue_check(); + } else { + sim_debug(HA_TRACE, &ha_dev, + "[ha_full] NON_FRQ NOT HANDLED\n"); + } +} + +static void ha_boot_disk(UNIT *uptr, uint8 tc) +{ + t_seccnt sectsread; + t_stat r; + uint8 buf[HA_BLKSZ]; + uint32 i, boot_loc; + + /* Read in the Physical Descriptor (PD) block (block 0) */ + r = sim_disk_rdsect(uptr, 0, buf, §sread, 1); + + if (r != SCPE_OK) { + sim_debug(HA_TRACE, &ha_dev, + "[ha_boot_disk] Could not read LBA 0\n"); + HA_STAT(tc, HA_CKCON, CIO_SUCCESS); + return; + } + + /* Store the Physical Descriptor (PD) block at well-known + address 0x2004400 */ + sim_debug(HA_TRACE, &ha_dev, + "[ha_boot_disk] Storing PD block at 0x%08x.\n", + HA_PDINFO_ADDR); + for (i = 0; i < HA_BLKSZ; i++) { + pwrite_b(HA_PDINFO_ADDR + i, buf[i], BUS_PER); + } + + + /* The PD block points to the logical start of disk */ + boot_loc = ATOW(buf, HA_PDLS_OFF); + + sim_debug(HA_TRACE, &ha_dev, + "[ha_boot_disk] Logical Start is at 0x%x\n", + boot_loc); + + r = sim_disk_rdsect(uptr, boot_loc, buf, §sread, 1); + + sim_debug(HA_TRACE, &ha_dev, + "[ha_boot_disk] Storing boot block %d at 0x%08x.\n", + boot_loc, HA_BOOT_ADDR); + + for (i = 0; i < HA_BLKSZ; i++) { + pwrite_b(HA_BOOT_ADDR + i, buf[i], BUS_PER); + } + + sim_debug(HA_TRACE, &ha_dev, + "[ha_boot_disk] Done storing boot block at 0x%08x\n", + HA_BOOT_ADDR); + + HA_STAT(tc, HA_GOOD, CIO_SUCCESS); + + ha_state.ts[tc].rep.addr = HA_BOOT_ADDR; + ha_state.ts[tc].rep.len = HA_BLKSZ; +} + +static void ha_boot_tape(UNIT *uptr, uint8 tc) +{ + t_seccnt sectsread; + t_stat r; + uint8 buf[HA_BLKSZ]; + uint32 i; + + if (!(uptr->flags & UNIT_ATT)) { + sim_debug(HA_TRACE, &ha_dev, + "[ha_boot_tape] Target not attached\n"); + HA_STAT(tc, HA_CKCON, CIO_SUCCESS); + return; + } + + r = sim_tape_rewind(uptr); + + if (r != SCPE_OK) { + sim_debug(HA_TRACE, &ha_dev, + "[ha_boot_tape] Could not rewind tape\n"); + HA_STAT(tc, HA_CKCON, CIO_SUCCESS); + return; + } + + r = sim_tape_rdrecf(uptr, buf, §sread, HA_BLKSZ); /* Read block 0 */ + + if (r != SCPE_OK) { + sim_debug(HA_TRACE, &ha_dev, + "[ha_boot_tape] Could not read PD block.\n"); + HA_STAT(tc, HA_CKCON, CIO_SUCCESS); + return; + } + + for (i = 0; i < HA_BLKSZ; i++) { + pwrite_b(HA_BOOT_ADDR + i, buf[i], BUS_PER); + } + + sim_debug(HA_TRACE, &ha_dev, + "[ha_boot_tape] Transfered 512 bytes to 0x%08x\n", + HA_BOOT_ADDR); + + r = sim_tape_sprecf(uptr, §sread); /* Skip block 1 */ + + HA_STAT(tc, HA_GOOD, CIO_SUCCESS); + + ha_state.ts[tc].rep.addr = HA_BOOT_ADDR; + ha_state.ts[tc].rep.len = HA_BLKSZ; +} + +static void ha_read_block_tape(UNIT *uptr, uint32 addr, uint8 tc) +{ + t_seccnt sectsread; + t_stat r; + uint8 buf[HA_BLKSZ]; + uint32 i; + + if (!(uptr->flags & UNIT_ATT)) { + sim_debug(HA_TRACE, &ha_dev, + "[ha_read_block_tape] Target not attached\n"); + HA_STAT(tc, HA_CKCON, CIO_SUCCESS); + return; + } + + r = sim_tape_rdrecf(uptr, buf, §sread, HA_BLKSZ); + + if (r != SCPE_OK) { + sim_debug(HA_TRACE, &ha_dev, + "[ha_read_block_tape] Could not read next block.\n"); + HA_STAT(tc, HA_CKCON, CIO_SUCCESS); + return; + } + + for (i = 0; i < HA_BLKSZ; i++) { + pwrite_b(addr + i, buf[i], BUS_PER); + } + + sim_debug(HA_TRACE, &ha_dev, + "[ha_read_block_tape] Transfered 512 bytes to 0x%08x\n", + addr); + + HA_STAT(tc, HA_GOOD, CIO_SUCCESS); + + ha_state.ts[tc].rep.addr = addr; + ha_state.ts[tc].rep.len = HA_BLKSZ; +} + +static void ha_read_block_disk(UNIT *uptr, uint32 addr, uint8 tc, uint32 lba) +{ + t_seccnt sectsread; + t_stat r; + uint8 buf[HA_BLKSZ]; + uint32 i; + + r = sim_disk_rdsect(uptr, lba, buf, §sread, 1); + + if (r != SCPE_OK) { + sim_debug(HA_TRACE, &ha_dev, + "[ha_read_block_disk] Could not read block %d\n", + lba); + HA_STAT(tc, HA_CKCON, CIO_SUCCESS); + return; + } + + for (i = 0; i < HA_BLKSZ; i++) { + pwrite_b(addr + i, buf[i], BUS_PER); + } + + sim_debug(HA_TRACE, &ha_dev, + "[ha_read_block_disk] Transferred 512 bytes to 0x%08x\n", + addr); + + HA_STAT(tc, HA_GOOD, CIO_SUCCESS); + + ha_state.ts[tc].rep.addr = addr; + ha_state.ts[tc].rep.len = HA_BLKSZ; +} + +static void ha_write_block_disk(UNIT *uptr, uint32 addr, uint8 tc, uint32 lba) +{ + t_seccnt sectswritten; + t_stat r; + uint8 buf[HA_BLKSZ]; + uint32 i; + + for (i = 0 ; i < HA_BLKSZ; i++) { + buf[i] = pread_b(addr + i, BUS_PER); + } + + r = sim_disk_wrsect(uptr, lba, buf, §swritten, 1); + + if (r != SCPE_OK) { + sim_debug(HA_TRACE, &ha_dev, + "[ha_write_block_disk] Could not write block %d\n", + lba); + HA_STAT(tc, HA_CKCON, CIO_SUCCESS); + return; + } + + HA_STAT(tc, HA_GOOD, CIO_SUCCESS); + + ha_state.ts[tc].rep.addr = addr; + ha_state.ts[tc].rep.len = HA_BLKSZ; +} + +static void ha_build_req(uint8 tc, uint8 subdev, t_bool express) +{ + uint32 i, rqp, ptr, dma_lst, daddr_ptr; + uint32 len, addr; + cio_entry rqe; + uint8 rapp_data[RAPP_LEN] = {0}; + + /* + * There are two possible ways to get the SCSI command we've + * been asked to perform. + * + * 1. If this is a "fast mode" operation, then the SCSI command + * is embedded in the Fast Request Queue entry. + * + * 2. If this is a regular queue operation, then the SCSI command + * is embedded in a struct pointed to by the "address" field + * of the queue entry. + */ + + for (i = 0; i < HA_MAX_CMD; i++) { + ha_state.ts[tc].req.cmd[i] = 0; + } + + if (ha_state.frq) { + rqp = cio[ha_state.slot].rqp; + + subdev = pread_b(rqp + 2, BUS_PER); + + ha_state.ts[tc].req.tc = FC_TC(subdev); + ha_state.ts[tc].req.lu = FC_LU(subdev); + ha_state.ts[tc].req.timeout = pread_w(rqp + 4, BUS_PER); + ha_state.ts[tc].req.cmd_len = pread_h(rqp + 18, BUS_PER); + for (i = 0; i < HA_MAX_CMD; i++) { + ha_state.ts[tc].req.cmd[i] = pread_b(rqp + 20 + i, BUS_PER); + } + ha_state.ts[tc].req.op = ha_state.ts[tc].req.cmd[0]; + + /* Possible list of DMA scatter/gather addresses */ + dma_lst = pread_h(rqp + 16, BUS_PER) / 8; + + if (dma_lst) { + t_bool link; + + /* There's a list of address / lengths. Each entry is 8 + * bytes long. */ + ptr = pread_w(rqp + 8, BUS_PER); + link = FALSE; + + sim_debug(HA_TRACE, &ha_dev, + "[build_req] Building a list of scatter/gather addresses.\n"); + + daddr_ptr = 0; + + for (i = 0; (i < dma_lst) || link; i++) { + addr = pread_w(ptr, BUS_PER); + len = pread_w(ptr + 4, BUS_PER); + + if (len == 0) { + sim_debug(HA_TRACE, &ha_dev, + "[build_req] Found length of 0, bailing early.\n"); + break; /* Done early */ + } + + if (len > 0x1000) { + /* There's a new pointer in town */ + ptr = pread_w(ptr, BUS_PER); + sim_debug(HA_TRACE, &ha_dev, + "[build_req] New ptr=%08x\n", + ptr); + link = TRUE; + continue; + } + + sim_debug(HA_TRACE, &ha_dev, + "[build_req] daddr[%d]: addr=%08x, len=%d (%x)\n", + daddr_ptr, addr, len, len); + + ha_state.ts[tc].req.daddr[daddr_ptr].addr = addr; + ha_state.ts[tc].req.daddr[daddr_ptr].len = len; + + daddr_ptr++; + ptr += 8; + } + + ha_state.ts[tc].req.dlen = i; + } else { + /* There's only one embedded address / length */ + ha_state.ts[tc].req.daddr[0].addr = pread_w(rqp + 8, BUS_PER); + ha_state.ts[tc].req.daddr[0].len = pread_w(rqp + 12, BUS_PER); + ha_state.ts[tc].req.dlen = 1; + } + + } else { + if (express) { + cio_rexpress(ha_state.slot, SCQRESIZE, &rqe, rapp_data); + } else { + /* TODO: Find correct queue number! */ + cio_rqueue(ha_state.slot, 0, SCQRESIZE, &rqe, rapp_data); + } + + ptr = rqe.address; + + ha_state.ts[tc].req.tc = FC_TC(rqe.subdevice); + ha_state.ts[tc].req.lu = FC_LU(rqe.subdevice); + ha_state.ts[tc].req.cmd_len = pread_w(ptr + 4, BUS_PER); + ha_state.ts[tc].req.timeout = pread_w(ptr + 8, BUS_PER); + ha_state.ts[tc].req.daddr[0].addr = pread_w(ptr + 12, BUS_PER); + ha_state.ts[tc].req.daddr[0].len = rqe.byte_count; + ha_state.ts[tc].req.dlen = 1; + + sim_debug(HA_TRACE, &ha_dev, + "[build_req] [non-fast] Building a list of 1 scatter/gather addresses.\n"); + + ptr = pread_w(ptr, BUS_PER); + + for (i = 0; (i < ha_state.ts[tc].req.cmd_len) && (i < HA_MAX_CMD); i++) { + ha_state.ts[tc].req.cmd[i] = pread_b(ptr + i, BUS_PER); + } + + ha_state.ts[tc].req.op = ha_state.ts[tc].req.cmd[0]; + } +} + +static SIM_INLINE void ha_cmd_prep(uint8 tc, uint8 op, uint8 subdev, t_bool express) +{ + ha_state.ts[tc].pending = TRUE; + ha_state.ts[tc].rep.op = op; + ha_state.ts[tc].rep.subdev = subdev; + ha_state.ts[tc].rep.status = CIO_FAILURE; + ha_state.ts[tc].rep.ssb = 0; + ha_state.ts[tc].rep.len = 0; + ha_state.ts[tc].rep.addr = 0; + + if (ha_state.pump_state == PUMP_COMPLETE) { + ha_state.ts[tc].rep.op |= 0x80; + } + + if (ha_state.frq) { + ha_state.ts[tc].rep.type = HA_JOB_QUICK; + } else if (express) { + ha_state.ts[tc].rep.type = HA_JOB_EXPRESS; + } else { + ha_state.ts[tc].rep.type = HA_JOB_FULL; + } +} + +static void ha_cmd(uint8 op, uint8 subdev, uint32 addr, int32 len, t_bool express) +{ + int32 i, block; + UNIT *uptr; + SCSI_DEV *dev; + uint8 dsd_tc, tc; + + sim_debug(HA_TRACE, &ha_dev, + "[ha_cmd] --------------------------[START]---------------------------------\n"); + sim_debug(HA_TRACE, &ha_dev, + "[ha_cmd] op=%02x (%d), subdev=%02x, addr=%08x, len=%d\n", + op, op, subdev, addr, len); + + switch (op) { + case CIO_DLM: + tc = HA_SCSI_ID; + ha_cmd_prep(tc, op, subdev, express); + + for (i = 0; i < len; i++) { + ha_crc = cio_crc32_shift(ha_crc, pread_b(addr + i, BUS_PER)); + } + + sim_debug(HA_TRACE, &ha_dev, + "[ha_cmd] SCSI Download Memory: bytecnt=%04x " + "addr=%08x return_addr=%08x subdev=%02x (CRC=%08x)\n", + len, addr, addr, subdev, ha_crc); + ha_state.ts[tc].rep.status = CIO_SUCCESS; + sim_activate_abs(cio_unit, 1000); + break; + case CIO_FCF: + tc = HA_SCSI_ID; + ha_cmd_prep(tc, op, subdev, express); + + sim_debug(HA_TRACE, &ha_dev, + "[ha_cmd] SCSI Force Function Call. (CRC=%08x)\n", + ha_crc); + if (ha_crc == DIAG_CRC_1) { + pwrite_h(0x200f000, 0x1, BUS_PER); /* Test success */ + pwrite_h(0x200f002, 0x0, BUS_PER); /* Test Number */ + pwrite_h(0x200f004, 0x0, BUS_PER); /* Actual */ + pwrite_h(0x200f006, 0x0, BUS_PER); /* Expected */ + pwrite_b(0x200f008, 0x1, BUS_PER); /* Success flag again */ + } + + cio[ha_state.slot].sysgen_s = 0; + ha_state.ts[tc].rep.status = CIO_SUCCESS; + sim_activate_abs(cio_unit, 1000); + break; + case CIO_DSD: + tc = HA_SCSI_ID; + ha_cmd_prep(tc, op, subdev, express); + + sim_debug(HA_TRACE, &ha_dev, + "[ha_cmd] SCSI DSD - %d CONFIGURED DEVICES (writing to addr %08x).\n", + ha_subdev_cnt, addr); + + pwrite_h(addr, ha_subdev_cnt, BUS_PER); + + for (i = 0; i < ha_subdev_cnt; i++) { + addr += 2; + + dsd_tc = ha_subdev_tab[i]; + + if (dsd_tc < 0) { + pwrite_h(addr, 0, BUS_PER); + continue; + } + + uptr = &ha_unit[dsd_tc]; + + dev = (SCSI_DEV *)uptr->up7; + + sim_debug(HA_TRACE, &ha_dev, + "[ha_cmd] [DSD] Probing subdev %d, target %d, devtype %d\n", + i, dsd_tc, dev->devtype); + + switch(dev->devtype) { + case SCSI_DISK: + sim_debug(HA_TRACE, &ha_dev, + "[ha_cmd] [DSD] Subdev %d is DISK (writing to addr %08x)\n", + i, addr); + pwrite_h(addr, HA_DSD_DISK, BUS_PER); + break; + case SCSI_TAPE: + sim_debug(HA_TRACE, &ha_dev, + "[ha_cmd] [DSD] Subdev %d is TAPE (writing to addr %08x)\n", + i, addr); + pwrite_h(addr, HA_DSD_TAPE, BUS_PER); + break; + default: + sim_debug(HA_TRACE, &ha_dev, + "[ha_cmd] [DSD] Warning: No device type for subdev %d (Writing to addr %08x)\n", + i, addr); + pwrite_h(addr, 0, BUS_PER); + break; + } + } + + ha_state.ts[tc].rep.status = CIO_SUCCESS; + + sim_activate_abs(cio_unit, 1000); + + break; + case HA_BOOT: + tc = ha_subdev_tab[subdev & 7]; + ha_cmd_prep(tc, op, subdev, express); + + + sim_debug(HA_TRACE, &ha_dev, + "[ha_cmd] TARGET %d BOOTING.\n", + tc); + + if (tc < 0) { + ha_state.ts[tc].rep.status = CIO_TIMEOUT; + sim_activate_abs(cio_unit, 1000); + return; + } + + uptr = &ha_unit[tc]; + + if (!(uptr->flags & UNIT_ATT)) { + sim_debug(HA_TRACE, &ha_dev, + "[ha_cmd] TARGET %d NOT ATTACHED.\n", + tc); + ha_state.ts[tc].rep.status = CIO_TIMEOUT; + sim_activate_abs(cio_unit, 1000); + return; + } + + dev = (SCSI_DEV *)uptr->up7; + + switch(dev->devtype) { + case SCSI_DISK: + ha_boot_disk(uptr, tc); + break; + case SCSI_TAPE: + ha_boot_tape(uptr, tc); + break; + default: + sim_debug(HA_TRACE, &ha_dev, + "[HA_BOOT] Cannot boot target %d (not disk or tape).\n", + tc); + break; + } + + ha_state.ts[tc].rep.status = CIO_SUCCESS; + sim_activate_abs(cio_unit, 1000); + break; + case HA_READ_BLK: + tc = ha_subdev_tab[subdev & 7]; + ha_cmd_prep(tc, op, subdev, express); + + sim_debug(HA_TRACE, &ha_dev, + "[ha_cmd] SUBDEV %d TARGET %d READ BLOCK (BLOCK 0x%08x TO ADDR 0x%08x)\n", + subdev, tc, pread_w(addr, BUS_PER), pread_w(addr + 4, BUS_PER)); + + sim_debug(HA_TRACE, &ha_dev, + "[ha_read_blk] addr = %08x\n", + addr); + sim_debug(HA_TRACE, &ha_dev, + "[ha_read_blk] %08x = %08x\n", + addr, pread_w(addr, BUS_PER)); + sim_debug(HA_TRACE, &ha_dev, + "[ha_read_blk] %08x = %08x\n", + addr + 4, pread_w(addr + 4, BUS_PER)); + sim_debug(HA_TRACE, &ha_dev, + "[ha_read_blk] %08x = %08x\n", + addr + 8, pread_w(addr + 8, BUS_PER)); + sim_debug(HA_TRACE, &ha_dev, + "[ha_read_blk] %08x = %08x\n", + addr + 12, pread_w(addr + 12, BUS_PER)); + sim_debug(HA_TRACE, &ha_dev, + "[ha_read_blik] %08x = %08x\n", + addr + 16, pread_w(addr + 16, BUS_PER)); + + + if (tc < 0) { + ha_state.ts[tc].rep.status = CIO_TIMEOUT; + sim_activate_abs(cio_unit, 1000); + return; + } + + uptr = &ha_unit[tc]; + + if (!(uptr->flags & UNIT_ATT)) { + ha_state.ts[tc].rep.status = CIO_TIMEOUT; + sim_activate_abs(cio_unit, 1000); + return; + } + + dev = (SCSI_DEV *)uptr->up7; + block = pread_w(addr, BUS_PER); /* Logical block we've been asked to read */ + addr = pread_w(addr + 4, BUS_PER); /* Dereference the pointer to the destination */ + + switch(dev->devtype) { + case SCSI_TAPE: + ha_read_block_tape(uptr, addr, tc); + break; + case SCSI_DISK: + ha_read_block_disk(uptr, addr, tc, block); + break; + default: + sim_debug(HA_TRACE, &ha_dev, + "[HA_READ_BLOCK] Cannot read block %d on target %d (not disk or tape)\n", + block, tc); + break; + } + + ha_state.ts[tc].rep.status = CIO_SUCCESS; + sim_activate_abs(cio_unit, 1000); + + break; + case HA_WRITE_BLK: + tc = ha_subdev_tab[subdev & 7]; + ha_cmd_prep(tc, op, subdev, express); + + sim_debug(HA_TRACE, &ha_dev, + "[ha_cmd] SUBDEV %d TARGET %d WRITE BLOCK (BLOCK 0x%08x FROM ADDR 0x%08x)\n", + subdev, tc, pread_w(addr, BUS_PER), pread_w(addr + 4, BUS_PER)); + + sim_debug(HA_TRACE, &ha_dev, + "[ha_write_blk] addr = %08x\n", + addr); + sim_debug(HA_TRACE, &ha_dev, + "[ha_write_blk] %08x = %08x\n", + addr, pread_w(addr, BUS_PER)); + sim_debug(HA_TRACE, &ha_dev, + "[ha_write_blk] %08x = %08x\n", + addr + 4, pread_w(addr + 4, BUS_PER)); + + if (tc < 0) { + ha_state.ts[tc].rep.status = CIO_TIMEOUT; + sim_activate_abs(cio_unit, 1000); + return; + } + + uptr = &ha_unit[tc]; + + if (!(uptr->flags & UNIT_ATT)) { + ha_state.ts[tc].rep.status = CIO_TIMEOUT; + sim_activate_abs(cio_unit, 1000); + return; + } + + dev = (SCSI_DEV *)uptr->up7; + block = pread_w(addr, BUS_PER); /* Logical block we've been asked to write */ + addr = pread_w(addr + 4, BUS_PER); /* Dereference the pointer to the source */ + + switch(dev->devtype) { + case SCSI_DISK: + ha_write_block_disk(uptr, addr, tc, block); + break; + default: + sim_debug(HA_TRACE, &ha_dev, + "[ha_write_blk] Cannot write block %d on target %d (not disk)\n", + block, tc); + break; + } + + ha_state.ts[tc].rep.status = CIO_SUCCESS; + sim_activate_abs(cio_unit, 1000); + break; + case HA_CNTRL: + tc = FC_TC(subdev); + ha_cmd_prep(tc, op, subdev, express); + + sim_debug(HA_TRACE, &ha_dev, + "[ha_cmd] SCSI CONTROL (subdev=%02x addr=%08x)\n", + subdev, addr); + + ha_build_req(tc, subdev, express); + ha_ctrl(tc); + sim_activate_abs(cio_unit, 1000); + break; + case HA_VERS: + /* + * Get Host Adapter Version + */ + tc = HA_SCSI_ID; + ha_cmd_prep(tc, op, subdev, express); + + sim_debug(HA_TRACE, &ha_dev, + "[ha_cmd] SCSI GET VERSION (addr=%08x len=%08x)\n", + addr, len); + + pwrite_w(addr, HA_VERSION, BUS_PER); + ha_state.ts[tc].rep.status = CIO_SUCCESS; + sim_activate_abs(cio_unit, 1000); + + break; + case HA_DL_EEDT: + /* + * This is a request to download the Extended Equipped Device + * Table from the host adapter to the 3B2 main memory. + */ + tc = HA_SCSI_ID; + ha_cmd_prep(tc, op, subdev, express); + + sim_debug(HA_TRACE, &ha_dev, + "[ha_cmd] SCSI DOWNLOAD EDT (%d bytes to address %08x)\n", + len, addr); + + for (i = 0; i < len; i++) { + pwrite_b(addr + i, ha_state.edt[i], BUS_PER); + } + + ha_state.ts[tc].rep.status = CIO_SUCCESS; + + sim_activate_abs(cio_unit, 1000); + + break; + case HA_UL_EEDT: + /* + * This is a request to upload the Extended Equipped Device + * Table from the 3B2 main memory to the host adapter + */ + + tc = HA_SCSI_ID; + ha_cmd_prep(tc, op, subdev, express); + + sim_debug(HA_TRACE, &ha_dev, + "[ha_cmd] SCSI UPLOAD EDT (%d bytes from address %08x)\n", + len, addr); + + for (i = 0; i < len; i++) { + ha_state.edt[i] = pread_b(addr + i, BUS_PER); + } + + ha_state.ts[tc].rep.status = CIO_SUCCESS; + + sim_activate_abs(cio_unit, 1000); + + break; + case HA_EDSD: + /* + * This command is used to determine which TCs are attached to + * the SCSI bus, and what LUNs they support. + */ + tc = HA_SCSI_ID; + ha_cmd_prep(tc, op, subdev, express); + + sim_debug(HA_TRACE, &ha_dev, + "[ha_cmd] SCSI EXTENDED DSD.\n"); + + ha_state.ts[tc].rep.status = CIO_SUCCESS; + ha_state.ts[tc].rep.addr = addr; + ha_state.ts[tc].rep.len = 9; + + /* + * Loop over each SCSI ID and configure LUNs. + */ + for (i = 0; i < 8; i++) { + uptr = &ha_unit[i]; + /* + * TODO: The byte being written here is a bit mask of + * equipped luns. e.g., + * + * - 0x01 means LUN 0 is equipped, + * - 0x80 means LUN 7 is equipped, + * - 0x33 means LUNs 0, 1, 4, and 5 are equipped. + * + * For now, we only support one LUN per target, and it's + * always LUN 0. + */ + pwrite_b(addr + i, (uptr->flags & UNIT_ATT) ? 1 : 0, BUS_PER); + } + + pwrite_b(addr + 8, HA_SCSI_ID, BUS_PER); /* ID of the card */ + + sim_activate_abs(cio_unit, 1000); + + break; + case HA_RESET: + tc = HA_SCSI_ID; + ha_cmd_prep(tc, op, subdev, express); + + scsi_reset(&ha_bus); + + sim_debug(HA_TRACE, &ha_dev, + "[ha_cmd] SCSI RESET.\n"); + + ha_state.ts[tc].rep.status = CIO_SUCCESS; + ha_state.ts[tc].rep.addr = addr; + ha_state.ts[tc].rep.len = 0; + + sim_activate_abs(cio_unit, 1000); + break; + default: + tc = HA_SCSI_ID; + ha_cmd_prep(tc, op, subdev, express); + + sim_debug(HA_TRACE, &ha_dev, + "*** SCSI WARNING: UNHANDLED OPCODE 0x%02x\n", + op); + + ha_state.ts[tc].rep.status = CIO_FAILURE; + + sim_activate_abs(cio_unit, 1000); + } + + sim_debug(HA_TRACE, &ha_dev, + "[ha_cmd] ---------------------------[END]----------------------------------\n"); + +} + +/* + * Handle a raw SCSI control message. + */ +void ha_ctrl(uint8 tc) +{ + volatile t_bool txn_done; + uint32 i, j; + uint32 plen, ha_ptr; + uint32 in_len, out_len; + uint8 lu, status; + uint8 msgi_buf[64]; + uint32 msgi_len; + uint32 to_read; + + sim_debug(HA_TRACE, &ha_dev, + "[ha_ctrl] [HA_REQ] TC=%d LU=%d TIMEOUT=%d DLEN=%d\n", + ha_state.ts[tc].req.tc, + ha_state.ts[tc].req.lu, + ha_state.ts[tc].req.timeout, + ha_state.ts[tc].req.dlen); + + sim_debug(HA_TRACE, &ha_dev, + "[ha_ctrl] [HA_REQ] CMD_LEN=%d CMD=<%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x>\n", + ha_state.ts[tc].req.cmd_len, + ha_state.ts[tc].req.cmd[0], ha_state.ts[tc].req.cmd[1], + ha_state.ts[tc].req.cmd[2], ha_state.ts[tc].req.cmd[3], + ha_state.ts[tc].req.cmd[4], ha_state.ts[tc].req.cmd[5], + ha_state.ts[tc].req.cmd[6], ha_state.ts[tc].req.cmd[7], + ha_state.ts[tc].req.cmd[8], ha_state.ts[tc].req.cmd[9]); + + in_len = out_len = 0; + + /* + * These ops need special handling. + */ + switch(ha_state.ts[tc].req.op) { + case HA_TESTRDY: + /* Fail early if LU is set */ + if (ha_state.ts[tc].req.lu) { + HA_STAT(tc, HA_CKCON, CIO_TIMEOUT); + return; + } + break; + case HA_FORMAT: /* Not yet handled by sim_scsi library */ + case HA_VERIFY: /* Not yet handled by sim_scsi library */ + /* Just mimic success */ + HA_STAT(tc, HA_GOOD, CIO_SUCCESS); + return; + } + + /* Get the bus's attention */ + if (!scsi_arbitrate(&ha_bus, HA_SCSI_ID)) { + HA_STAT(tc, HA_CKCON, CIO_TIMEOUT); + return; + } + + scsi_set_atn(&ha_bus); + + if (!scsi_select(&ha_bus, ha_state.ts[tc].req.tc)) { + HA_STAT(tc, HA_CKCON, CIO_TIMEOUT); + scsi_release(&ha_bus); + return; + } + + /* Select the correct LU */ + lu = 0x80 | ha_state.ts[tc].req.lu; + scsi_write(&ha_bus, &lu, 1); + + txn_done = FALSE; + + /* TODO: Fix this. Work around a bug in command length. The host + * occasionally sends a command length of 8 for 6-byte SCSI + * commands. The sim_scsi library knows to only consume 6 bytes, + * which leaves the buffer in a bad state. */ + if (ha_state.ts[tc].req.cmd_len == 8) { + ha_state.ts[tc].req.cmd_len = 6; + } + + while (!txn_done) { + switch(ha_bus.phase) { + case SCSI_CMD: + plen = scsi_write(&ha_bus, ha_state.ts[tc].req.cmd, ha_state.ts[tc].req.cmd_len); + if (plen < ha_state.ts[tc].req.cmd_len) { + HA_STAT(tc, HA_CKCON, CIO_SUCCESS); + scsi_release(&ha_bus); + return; + } + break; + case SCSI_DATI: + /* This is a read */ + in_len = scsi_read(&ha_bus, ha_buf, HA_MAXFR); + + sim_debug(HA_TRACE, &ha_dev, + "[ha_ctrl] SCSI_DATI: Consumed %d (0x%X) bytes to ha_buf in SCSI read.\n", + in_len, in_len); + + /* We need special handling based on the op code */ + switch(ha_state.ts[tc].req.op) { + case HA_READ: + case HA_READEXT: + ha_ptr = 0; + + for (i = 0; i < ha_state.ts[tc].req.dlen; i++) { + /* + * Consume the lesser of: + * - The total bytes we consumed, or: + * - The length of the current block + */ + to_read = MIN(ha_state.ts[tc].req.daddr[i].len, in_len); + + sim_debug(HA_TRACE, &ha_dev, + "[(%02x) TC%d,LU%d] DATI: Processing %d bytes to address %08x...\n", + ha_state.ts[tc].req.op, + ha_state.ts[tc].req.tc, + ha_state.ts[tc].req.lu, + to_read, + ha_state.ts[tc].req.daddr[i].addr); + + for (j = 0; j < to_read; j++) { + pwrite_b(ha_state.ts[tc].req.daddr[i].addr + j, ha_buf[ha_ptr++], BUS_PER); + } + + if (in_len >= to_read) { + in_len -= to_read; + } else { + /* Nothing left to write */ + break; + } + } + + break; + default: + sim_debug(HA_TRACE, &ha_dev, + "[(%02x) TC%d,LU%d] DATI: Processing %d bytes to address %08x...\n", + ha_state.ts[tc].req.op, ha_state.ts[tc].req.tc, + ha_state.ts[tc].req.lu, in_len, + ha_state.ts[tc].req.daddr[0].addr); + for (i = 0; i < in_len; i++) { + sim_debug(HA_TRACE, &ha_dev, "[%04x] [DATI] 0x%02x\n", i, ha_buf[i]); + pwrite_b(ha_state.ts[tc].req.daddr[0].addr + i, ha_buf[i], BUS_PER); + } + + break; + } + + break; + case SCSI_DATO: + /* This is a write */ + ha_ptr = 0; + out_len = 0; + ha_state.ts[tc].rep.len = ha_state.ts[tc].req.dlen; + + for (i = 0; i < ha_state.ts[tc].req.dlen; i++) { + sim_debug(HA_TRACE, &ha_dev, + "[ha_ctrl] [%d] DATO: Writing %d bytes to ha_buf.\n", + i, ha_state.ts[tc].req.daddr[i].len); + + for (j = 0; j < ha_state.ts[tc].req.daddr[i].len; j++) { + ha_buf[ha_ptr++] = pread_b(ha_state.ts[tc].req.daddr[i].addr + j, BUS_PER); + if (ha_state.ts[tc].req.op == 0x15) { + sim_debug(HA_TRACE, &ha_dev, + "[ha_ctrl] [%d]\t\t%02x\n", + j, ha_buf[ha_ptr - 1]); + } + } + + out_len += ha_state.ts[tc].req.daddr[i].len; + } + + if (ha_state.ts[tc].req.op == HA_WRITE || ha_state.ts[tc].req.op == HA_WRTEXT) { + /* If total len is not on a block boundary, we have to + bump it up in order to write the whole block. */ + if (out_len % HA_BLKSZ) { + out_len = out_len + (HA_BLKSZ - (out_len % HA_BLKSZ)); + } + } + + scsi_write(&ha_bus, ha_buf, out_len); + + sim_debug(HA_TRACE, &ha_dev, + "[ha_ctrl] SCSI Write of %08x (%d) bytes Complete\n", + out_len, out_len); + break; + case SCSI_STS: + scsi_read(&ha_bus, &status, 1); + sim_debug(HA_TRACE, &ha_dev, + "[ha_ctrl] STATUS BYTE: %02x\n", + status); + break; + case SCSI_MSGI: + msgi_len = scsi_read(&ha_bus, msgi_buf, 64); + sim_debug(HA_TRACE, &ha_dev, + "[ha_ctrl] MESSAGE IN LENGTH %d\n", + msgi_len); + + for (i = 0; i < msgi_len; i++) { + sim_debug(HA_TRACE, &ha_dev, + "[ha_ctrl] MSGI[%02d] = %02x\n", + i, msgi_buf[i]); + } + + txn_done = TRUE; + break; + } + } + + if (ha_bus.sense_key || ha_bus.sense_code) { + sim_debug(HA_TRACE, &ha_dev, + "[ha_ctrl] SENSE KEY=%d CODE=%d INFO=%d, CKCON.\n", + ha_bus.sense_key, ha_bus.sense_code, ha_bus.sense_info); + HA_STAT(tc, HA_CKCON, 0x60); + } else { + sim_debug(HA_TRACE, &ha_dev, "[ha_ctrl] NO SENSE INFO.\n"); + HA_STAT(tc, HA_GOOD, CIO_SUCCESS); + } + + /* Release the bus */ + scsi_release(&ha_bus); +} + +void ha_fcm_express(uint8 tc) +{ + uint32 cqp, cqs; + + cqp = cio[ha_state.slot].cqp; + cqs = cio[ha_state.slot].cqs; + + /* Write the fast completion entry. */ + pwrite_b(cqp + cq_offset, ha_state.ts[tc].rep.status, BUS_PER); + pwrite_b(cqp + cq_offset + 1, ha_state.ts[tc].rep.op, BUS_PER); + pwrite_b(cqp + cq_offset + 2, ha_state.ts[tc].rep.subdev, BUS_PER); + pwrite_b(cqp + cq_offset + 3, ha_state.ts[tc].rep.ssb, BUS_PER); + + sim_debug(HA_TRACE, &ha_dev, + "[ha_fcm_express] stat=%02x, op=%02x (%d), cq_index=%d target=%d, lun=%d, ssb=%02x\n", + ha_state.ts[tc].rep.status, ha_state.ts[tc].rep.op, ha_state.ts[tc].rep.op, + (cq_offset / 4), + FC_TC(ha_state.ts[tc].rep.subdev), FC_LU(ha_state.ts[tc].rep.subdev), + ha_state.ts[tc].rep.ssb); + + if (ha_state.pump_state == PUMP_COMPLETE && cqs > 0) { + cq_offset = (cq_offset + 4) % (cqs * 4); + } else { + cq_offset = 0; + } +} + +t_stat ha_set_type(UNIT *uptr, int32 val, CONST char *cptr, void *desc) +{ + if (val < 0 || cptr || val > HA_MAX_DTYPE) { + return SCPE_ARG; + } + + if (uptr->flags & UNIT_ATT) { + return SCPE_ALATT; + } + + uptr->flags = (uptr->flags & ~UNIT_DTYPE) | (val << UNIT_V_DTYPE); + if (val == ST120_DTYPE) { + uptr->flags |= SCSI_QIC; + } + uptr->capac = (t_addr) ha_tab[val].lbn; + scsi_set_unit(&ha_bus, uptr, &ha_tab[val]); + scsi_reset_unit(uptr); + return SCPE_OK; +} + +t_stat ha_show_type(FILE *st, UNIT *uptr, int32 val, CONST void *desc) +{ + fprintf(st, "%s", ha_tab[GET_DTYPE(uptr->flags)].name); + + return SCPE_OK; +} diff --git a/3B2/3b2_scsi.h b/3B2/3b2_scsi.h index 3854a349..9b3815fc 100644 --- a/3B2/3b2_scsi.h +++ b/3B2/3b2_scsi.h @@ -1,260 +1,288 @@ -/* 3b2_scsi.h: AT&T 3B2 SCSI (CM195W) Host Adapter - - Copyright (c) 2020, Seth J. Morabito - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - - Except as contained in this notice, the name of the author shall - not be used in advertising or otherwise to promote the sale, use or - other dealings in this Software without prior written authorization - from the author. - */ - -#ifndef _3B2_SCSI_H_ -#define _3B2_SCSI_H_ - -#include "3b2_defs.h" - -/* CIO Opcodes */ -#define HA_BOOT 0x0a -#define HA_READ_BLK 0x0b -#define HA_CNTRL 0x20 -#define HA_VERS 0x40 -#define HA_DL_EEDT 0x42 -#define HA_UL_EEDT 0x43 -#define HA_EDSD 0x44 -#define HA_RESET 0x45 - -#define HA_TESTRDY 0x00 -#define HA_FORMAT 0x04 -#define HA_WRITE 0x0a -#define HA_INQUIRY 0x12 -#define HA_MODESNS 0x1a -#define HA_RDCPCTY 0x25 -#define HA_READ 0x08 -#define HA_READEXT 0x28 -#define HA_WRTEXT 0x2a -#define HA_VERIFY 0x2f - -#define HA_PDLS_OFF 0x28 - -/* CIO Status */ -#define CIO_TIMEOUT 0x65 - -#define HA_BOOT_ADDR 0x2004000 -#define HA_PDINFO_ADDR 0x2004400 - -#define HA_ID 0x0100 -#define HA_IPL 12 - -#define HA_GOOD 0x00 -#define HA_CKCON 0x02 - -#define HA_DSD_DISK 0x100 -#define HA_DSD_TAPE 0x101 - -#define HA_VERSION 0x01 - -#define SCQRESIZE 24 -#define RAPP_LEN (SCQRESIZE - 8) -#define SCQCESIZE 16 -#define CAPP_LEN (SCQCESIZE - 8) - -#define FC_TC(x) (((x) >> 3) & 7) -#define FC_LU(x) ((x) & 7) - -#define HA_EDT_LEN 1024 - -#define HA_BLKSZ 512 - -#define HA_MAX_CMD 12 -#define INQUIRY_MAX 36 - -#define HA_STAT(ha_stat,cio_stat) { \ - ha_state.reply.ssb = (ha_stat); \ - ha_state.reply.status = (cio_stat); \ - } - -#define HA_MAX_DTYPE 1 - -/* CDC Wren IV 327 MB Hard Disk (AT&T KS-23483,L3) */ -#define SD327_DTYPE 0 -#define SD327_PQUAL 0x00 -#define SD327_SCSI 1 -#define SD327_BLK 512 -#define SD327_LBN 640396 -#define SD327_MANU "AT&T" -#define SD327_DESC "KS23483" -#define SD327_REV "0001" /* TODO: Find real rev */ -#define SD327_TPZ 9 -#define SD327_ASEC 3 -#define SD327_ATPZ 0 -#define SD327_ATPU 0 -#define SD327_SPT 46 -#define SD327_CYL 1549 -#define SD327_HEADS 9 -#define SD327_PREC 1200 -#define SD327_RWC 1200 -#define SD327_STEP 15 -#define SD327_LZ 1549 -#define SD327_RPM 3600 - -/* Wangtek 120MB cartridge tape (AT&T KS-23465) */ -#define ST120_DTYPE 1 -#define ST120_PQUAL 0x00 -#define ST120_SCSI 1 -#define ST120_BLK 512 -#define ST120_LBN 266004 -#define ST120_MANU "WANGTEK" -#define ST120_DESC "KS23465" -#define ST120_REV "CX17" -#define ST120_DENS 5 - -#define UNIT_V_DTYPE (SCSI_V_UF + 0) -#define UNIT_M_DTYPE 0x1f -#define UNIT_DTYPE (UNIT_M_DTYPE << UNIT_V_DTYPE) - -#define GET_DTYPE(x) (((x) >> UNIT_V_DTYPE) & UNIT_M_DTYPE) -#define HA_DISK(d) { \ - SCSI_DISK, d##_PQUAL, d##_SCSI, FALSE, d##_BLK, \ - d##_LBN, d##_MANU, d##_DESC, d##_REV, #d, 0 \ - } -#define HA_TAPE(d) { \ - SCSI_TAPE, d##_PQUAL, d##_SCSI, TRUE, d##_BLK, \ - d##_LBN, d##_MANU, d##_DESC, d##_REV, #d, 0 \ - } -#define HA_SIZE(d) d##_LBN - - -/* Hardware Notes - * ============== - * - * Disk Drive - * ---------- - * - * We emulate a 300-Megabyte Hard Disk, AT&T part number KS23483,L3. - * - * This is the same as a CDC/Imprimis Wren IV 94171-327 - * - * 512 bytes per block - * 1,520 cylinders - * 2 alternate cylinders (1518 available) - * 46 Sectors per Track - * 3 Alternate Sectors per Track (43 available) - * 9 tracks per cylinder (9 heads) - * - * Formatted Size: 587,466 blocks - * - * - * Tape Drive - * ---------- - * - * Wangtek 5099EN (AT&T Part number KS23417,L2) - * - * DC600A cartridge tape - * - * 512 bytes per block - * 9 tracks - * 13,956 blocks per track - * - * Formatted Size: 125,604 blocks - * - */ - -#define HA_JOB_QUICK 0 -#define HA_JOB_EXPRESS 1 -#define HA_JOB_FULL 2 - -typedef uint8 ha_jobtype; - -typedef struct { - uint32 addr; - uint32 len; -} haddr; - -/* - * SCSI Command Request - */ -typedef struct { - uint8 op; /* Destructured from the cmd byte array */ - uint8 tc; - uint8 lu; - uint32 timeout; - - uint8 dlen; - haddr daddr[48]; /* Support up to 48 transfer addresses */ - - uint32 dma_lst; - uint16 cmd_len; - uint8 cmd[HA_MAX_CMD]; -} ha_req; - -/* - * SCSI Command Response - */ -typedef struct { - ha_jobtype type; /* Job type */ - t_bool pending; /* Pending or completed? */ - uint8 status; /* Result Status */ - uint8 op; /* Command Opcode */ - uint8 subdev; /* XXTTTLLL; T=Target, L=LUN */ - uint8 ssb; /* SCSI Status Byte */ - uint32 addr; /* Response address */ - uint32 len; /* Response length */ -} ha_resp; - -#define PUMP_NONE 0 -#define PUMP_SYSGEN 1 -#define PUMP_COMPLETE 2 - -/* - * General SCSI HA internal state. - */ -typedef struct { - uint8 cid; /* Card Backsplane Slot # */ - uint32 pump_state; - uint32 haddr; /* Host address for read/write */ - uint32 hlen; /* Length for read or write */ - t_bool initialized; /* Card has been initialized */ - t_bool frq; /* Fast Request Queue enabled */ - uint8 edt[HA_EDT_LEN]; /* Equipped Device Table */ - ha_req request; /* Current job request */ - ha_resp reply; /* Current job reply */ -} HA_STATE; - -t_stat ha_show_type(FILE *st, UNIT *uptr, int32 val, CONST void *desc); -t_stat ha_set_type(UNIT *uptr, int32 val, CONST char *cptr, void *desc); -t_stat ha_reset(DEVICE *dptr); -t_stat ha_svc(UNIT *uptr); -t_stat ha_rq_svc(UNIT *uptr); -t_stat ha_attach(UNIT *uptr, CONST char *cptr); -t_stat ha_detach(UNIT *uptr); - -void ha_fast_queue_check(); -void ha_sysgen(uint8 cid); -void ha_express(uint8 cid); -void ha_full(uint8 cid); - -/* Fast Completion */ - -void ha_fcm_express(); - -#endif /* _3B2_SCSI_H_ */ +/* 3b2_scsi.h: CM195W SCSI Controller CIO Card + + Copyright (c) 2020-2022, Seth J. Morabito + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + Except as contained in this notice, the name of the author shall + not be used in advertising or otherwise to promote the sale, use or + other dealings in this Software without prior written authorization + from the author. + */ + +#ifndef _3B2_SCSI_H_ +#define _3B2_SCSI_H_ + +#include "3b2_defs.h" + +/* CIO Opcodes */ +#define HA_BOOT 0x0a +#define HA_READ_BLK 0x0b +#define HA_WRITE_BLK 0x0c +#define HA_CNTRL 0x20 +#define HA_VERS 0x40 +#define HA_DL_EEDT 0x42 +#define HA_UL_EEDT 0x43 +#define HA_EDSD 0x44 +#define HA_RESET 0x45 + +#define HA_TESTRDY 0x00 +#define HA_FORMAT 0x04 +#define HA_WRITE 0x0a +#define HA_INQUIRY 0x12 +#define HA_MODESEL 0x15 +#define HA_MODESNS 0x1a +#define HA_RDCPCTY 0x25 +#define HA_READ 0x08 +#define HA_READEXT 0x28 +#define HA_WRTEXT 0x2a +#define HA_VERIFY 0x2f + +#define HA_PDLS_OFF 0x28 + +/* CIO Status */ +#define CIO_TIMEOUT 0x65 + +#define HA_BOOT_ADDR 0x2004000 +#define HA_PDINFO_ADDR 0x2004400 + +#define HA_ID 0x0100 +#define HA_IPL 12 + +#define HA_GOOD 0x00 +#define HA_CKCON 0x02 + +#define HA_DSD_DISK 0x100 +#define HA_DSD_TAPE 0x101 + +#define HA_VERSION 0x01 + +#define SCQRESIZE 24 +#define RAPP_LEN (SCQRESIZE - 8) +#define SCQCESIZE 16 +#define CAPP_LEN (SCQCESIZE - 8) + +#define FC_TC(x) (((x) >> 3) & 7) +#define FC_LU(x) ((x) & 7) + +#define HA_EDT_LEN 1024 + +#define HA_BLKSZ 512 + +#define HA_MAX_CMD 12 +#define INQUIRY_MAX 36 + +#define HA_STAT(tc,ha_stat,cio_stat) { \ + ha_state.ts[tc].rep.ssb = (ha_stat); \ + ha_state.ts[tc].rep.status = (cio_stat); \ + } + +#define HA_MAX_DTYPE 4 + +/* Hardware Notes + * ============== + * + * Disk Drives + * ----------- + * + * There are two emulated SCSI disk drives available. + * + * 1. 155 MB CDC Wren III (CDC 94161-9) + * 2. 327 MB CDC Wren IV (CDC 94171-9) + * + * The CDC 94161-9 was also OEMed as the "AT&T KS23483,L3" + * The CDC 94171-9 was also OEMed as the "AT&T KS23483,L25" + * + * + * Tape Drive + * ---------- + * + * Wangtek 5125EN (AT&T Part number KS23417,L2) + * + * DC600A cartridge tape at 120MB (QIC-120 format) + * + */ + + +/* Other SCSI hard disk types + * --------------------------- + * + * These geometries are supported natively and automatically + * by System V Release 3.2.3 UNIX. + * + * 1. CDC 94161-9 155 MB/148 MiB 512 B/s, 35 s/t, 9 head, 965 cyl + * 2. AT&T KS23483 327 MB/312 MiB 512 B/s, 46 s/t, 9 head, 1547 cyl + * (a.k.a CDC 94171-9) + * + * Also supported was a SCSI-to-ESDI bridge controller that used the + * Emulex MD23/S2 SCSI-to-ESDI bridge. It allowed up to four ESDI + * drives to be mapped as LUNs 0-3. + * + */ + +/* AT&T 155 MB Hard Disk (35 sec/t, 9 hd, 964 cyl) */ +#define SD155_DTYPE 0 +#define SD155_PQUAL 0x00 +#define SD155_SCSI 1 +#define SD155_BLK 512 +#define SD155_LBN 303660 +#define SD155_MANU "AT&T" +#define SD155_DESC "KS23483" +#define SD155_REV "0000" + +/* AT&T 300 MB Hard Disk (43 sec/t, 9 hd, 1514 cyl) */ +#define SD300_DTYPE 1 +#define SD300_PQUAL 0x00 +#define SD300_SCSI 1 +#define SD300_BLK 512 +#define SD300_LBN 585937 +#define SD300_MANU "AT&T" +#define SD300_DESC "KS23483" +#define SD300_REV "0000" + +/* AT&T 327 MB Hard Disk (46 sec/t, 9 hd, 1547 cyl) */ +#define SD327_DTYPE 2 +#define SD327_PQUAL 0x00 +#define SD327_SCSI 1 +#define SD327_BLK 512 +#define SD327_LBN 640458 +#define SD327_MANU "AT&T" +#define SD327_DESC "KS23483" +#define SD327_REV "0000" + +/* AT&T 630 MB Hard Disk (56 sec/t, 16 hd, 1447 cyl) */ +#define SD630_DTYPE 3 +#define SD630_PQUAL 0x00 +#define SD630_SCSI 1 +#define SD630_BLK 512 +#define SD630_LBN 1296512 +#define SD630_MANU "AT&T" +#define SD630_DESC "KS23483" +#define SD630_REV "0000" + +/* Wangtek 120MB cartridge tape */ +#define ST120_DTYPE 4 +#define ST120_PQUAL 0x00 +#define ST120_SCSI 1 +#define ST120_BLK 512 +#define ST120_LBN 1 +#define ST120_MANU "WANGTEK" +#define ST120_DESC "KS23465" +#define ST120_REV "CX17" + +#define UNIT_V_DTYPE (SCSI_V_UF + 0) +#define UNIT_M_DTYPE 0x1f +#define UNIT_DTYPE (UNIT_M_DTYPE << UNIT_V_DTYPE) + +#define GET_DTYPE(x) (((x) >> UNIT_V_DTYPE) & UNIT_M_DTYPE) +#define HA_DISK(d) \ + { SCSI_DISK, d##_PQUAL, d##_SCSI, FALSE, d##_BLK, \ + d##_LBN, d##_MANU, d##_DESC, d##_REV, #d } + +#define HA_TAPE(d) \ + { SCSI_TAPE, d##_PQUAL, d##_SCSI, TRUE, d##_BLK, \ + d##_LBN, d##_MANU, d##_DESC, d##_REV, #d } + +#define HA_SIZE(d) d##_LBN + +#define HA_JOB_QUICK 0 +#define HA_JOB_EXPRESS 1 +#define HA_JOB_FULL 2 + +typedef uint8 ha_jobtype; + +typedef struct { + uint32 addr; + uint32 len; +} haddr; + +/* + * SCSI Command Request + */ +typedef struct { + uint8 op; /* Destructured from the cmd byte array */ + uint8 tc; + uint8 lu; + uint32 timeout; + + uint8 dlen; + haddr daddr[48]; /* Support up to 48 transfer addresses */ + + uint32 dma_lst; + uint16 cmd_len; + uint8 cmd[HA_MAX_CMD]; +} ha_req; + +/* + * SCSI Command Response + */ +typedef struct { + ha_jobtype type; /* Job type */ + uint8 status; /* Result Status */ + uint8 op; /* Command Opcode */ + uint8 subdev; /* XXTTTLLL; T=Target, L=LUN */ + uint8 ssb; /* SCSI Status Byte */ + uint32 addr; /* Response address */ + uint32 len; /* Response length */ +} ha_resp; + +#define PUMP_NONE 0 +#define PUMP_SYSGEN 1 +#define PUMP_COMPLETE 2 + +/* + * SCSI Target state + */ +typedef struct { + t_bool pending; /* Service pending */ + ha_req req; /* SCSI job request */ + ha_resp rep; /* SCSI job reply */ +} ha_ts; + +/* + * General SCSI HA internal state. + */ +typedef struct { + uint8 slot; /* Card Backsplane Slot # */ + uint32 pump_state; + t_bool frq; /* Fast Request Queue enabled */ + uint8 edt[HA_EDT_LEN]; /* Equipped Device Table */ + ha_ts ts[8]; /* Target state */ +} HA_STATE; + +t_stat ha_show_type(FILE *st, UNIT *uptr, int32 val, CONST void *desc); +t_stat ha_set_type(UNIT *uptr, int32 val, CONST char *cptr, void *desc); +t_stat ha_reset(DEVICE *dptr); +t_stat ha_svc(UNIT *uptr); +t_stat ha_rq_svc(UNIT *uptr); +t_stat ha_attach(UNIT *uptr, CONST char *cptr); +t_stat ha_detach(UNIT *uptr); + +void ha_fast_queue_check(); +void ha_sysgen(uint8 slot); +void ha_express(uint8 slot); +void ha_full(uint8 slot); + +/* Fast Completion */ + +void ha_fcm_express(uint8 target); + +#endif /* _3B2_SCSI_H_ */ diff --git a/3B2/3b2_stddev.c b/3B2/3b2_stddev.c index 6d2dba9f..81cfd0db 100644 --- a/3B2/3b2_stddev.c +++ b/3B2/3b2_stddev.c @@ -1,543 +1,815 @@ -/* 3b2_stddev.c: AT&T 3B2 miscellaneous system board devices. - - Copyright (c) 2017, Seth J. Morabito - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - - Except as contained in this notice, the name of the author shall - not be used in advertising or otherwise to promote the sale, use or - other dealings in this Software without prior written authorization - from the author. -*/ - -/* - This file contains system-specific registers and devices for the - following 3B2 devices: - - - nvram Non-Volatile RAM - - tod MM58174A Real-Time-Clock - - flt Fault Register -*/ - -#include "3b2_stddev.h" - -#include "3b2_cpu.h" -#include "3b2_csr.h" - -DEBTAB sys_deb_tab[] = { - { "INIT", INIT_MSG, "Init" }, - { "READ", READ_MSG, "Read activity" }, - { "WRITE", WRITE_MSG, "Write activity" }, - { "EXECUTE", EXECUTE_MSG, "Execute activity" }, - { "IRQ", IRQ_MSG, "Interrupt activity"}, - { "TRACE", TRACE_DBG, "Detailed activity" }, - { NULL, 0 } -}; - -uint32 *NVRAM = NULL; - -/* NVRAM */ -UNIT nvram_unit = { - UDATA(NULL, UNIT_FIX+UNIT_BINK, NVRSIZE) -}; - -REG nvram_reg[] = { - { NULL } -}; - -DEVICE nvram_dev = { - "NVRAM", &nvram_unit, nvram_reg, NULL, - 1, 16, 8, 4, 16, 32, - &nvram_ex, &nvram_dep, &nvram_reset, - NULL, &nvram_attach, &nvram_detach, - NULL, DEV_DEBUG, 0, sys_deb_tab, NULL, NULL, - &nvram_help, NULL, NULL, - &nvram_description -}; - -t_stat nvram_ex(t_value *vptr, t_addr exta, UNIT *uptr, int32 sw) -{ - uint32 addr = (uint32) exta; - - if ((vptr == NULL) || (addr & 03)) { - return SCPE_ARG; - } - - if (addr >= NVRSIZE) { - return SCPE_NXM; - } - - *vptr = NVRAM[addr >> 2]; - - return SCPE_OK; -} - -t_stat nvram_dep(t_value val, t_addr exta, UNIT *uptr, int32 sw) -{ - uint32 addr = (uint32) exta; - - if (addr & 03) { - return SCPE_ARG; - } - - if (addr >= NVRSIZE) { - return SCPE_NXM; - } - - NVRAM[addr >> 2] = (uint32) val; - - return SCPE_OK; -} - -t_stat nvram_reset(DEVICE *dptr) -{ - if (NVRAM == NULL) { - NVRAM = (uint32 *)calloc(NVRSIZE >> 2, sizeof(uint32)); - memset(NVRAM, 0, sizeof(uint32) * NVRSIZE >> 2); - nvram_unit.filebuf = NVRAM; - } - - if (NVRAM == NULL) { - return SCPE_MEM; - } - - return SCPE_OK; -} - -const char *nvram_description(DEVICE *dptr) -{ - return "Non-volatile memory, used to store system state between boots.\n"; -} - -t_stat nvram_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr) -{ - fprintf(st, - "The NVRAM holds system state between boots. On initial startup,\n" - "if no valid NVRAM file is attached, you will see the message:\n" - "\n" - " FW ERROR 1-01: NVRAM SANITY FAILURE\n" - " DEFAULT VALUES ASSUMED\n" - " IF REPEATED, CHECK THE BATTERY\n" - "\n" - "To avoid this message on subsequent boots, attach a new NVRAM file\n" - "with the SIMH command:\n" - "\n" - " sim> ATTACH NVRAM \n"); - return SCPE_OK; -} - -t_stat nvram_attach(UNIT *uptr, CONST char *cptr) -{ - t_stat r; - - /* If we've been asked to attach, make sure the ATTABLE - and BUFABLE flags are set on the unit */ - uptr->flags = uptr->flags | (UNIT_ATTABLE | UNIT_BUFABLE); - - r = attach_unit(uptr, cptr); - - if (r != SCPE_OK) { - /* Unset the ATTABLE and BUFABLE flags if we failed. */ - uptr->flags = uptr->flags & (uint32) ~(UNIT_ATTABLE | UNIT_BUFABLE); - } else { - uptr->hwmark = (uint32) uptr->capac; - } - - return r; -} - -t_stat nvram_detach(UNIT *uptr) -{ - t_stat r; - - r = detach_unit(uptr); - - if ((uptr->flags & UNIT_ATT) == 0) { - uptr->flags = uptr->flags & (uint32) ~(UNIT_ATTABLE | UNIT_BUFABLE); - } - - return r; -} - - -uint32 nvram_read(uint32 pa, size_t size) -{ - uint32 offset = pa - NVRBASE; - uint32 data = 0; - uint32 sc = (~(offset & 3) << 3) & 0x1f; - - switch(size) { - case 8: - data = (NVRAM[offset >> 2] >> sc) & BYTE_MASK; - break; - case 16: - if (offset & 2) { - data = NVRAM[offset >> 2] & HALF_MASK; - } else { - data = (NVRAM[offset >> 2] >> 16) & HALF_MASK; - } - break; - case 32: - data = NVRAM[offset >> 2]; - break; - } - - return data; -} - -void nvram_write(uint32 pa, uint32 val, size_t size) -{ - uint32 offset = pa - NVRBASE; - uint32 index = offset >> 2; - uint32 sc, mask; - - switch(size) { - case 8: - sc = (~(pa & 3) << 3) & 0x1f; - mask = (uint32) (0xff << sc); - NVRAM[index] = (NVRAM[index] & ~mask) | (val << sc); - break; - case 16: - if (offset & 2) { - NVRAM[index] = (NVRAM[index] & ~HALF_MASK) | val; - } else { - NVRAM[index] = (NVRAM[index] & HALF_MASK) | (val << 16); - } - break; - case 32: - NVRAM[index] = val; - break; - } -} - -/* - * MM58174A Time Of Day Clock - */ - -UNIT tod_unit = { - UDATA(NULL, UNIT_FIX+UNIT_BINK, sizeof(TOD_DATA)) -}; - -DEVICE tod_dev = { - "TOD", &tod_unit, NULL, NULL, - 1, 16, 8, 4, 16, 32, - NULL, NULL, &tod_reset, - NULL, &tod_attach, &tod_detach, - NULL, 0, 0, sys_deb_tab, NULL, NULL, - &tod_help, NULL, NULL, - &tod_description -}; - -t_stat tod_reset(DEVICE *dptr) -{ - if (tod_unit.filebuf == NULL) { - tod_unit.filebuf = calloc(sizeof(TOD_DATA), 1); - if (tod_unit.filebuf == NULL) { - return SCPE_MEM; - } - } - - return SCPE_OK; -} - -t_stat tod_attach(UNIT *uptr, CONST char *cptr) -{ - t_stat r; - - uptr->flags = uptr->flags | (UNIT_ATTABLE | UNIT_BUFABLE); - - r = attach_unit(uptr, cptr); - - if (r != SCPE_OK) { - uptr->flags = uptr->flags & (uint32) ~(UNIT_ATTABLE | UNIT_BUFABLE); - } else { - uptr->hwmark = (uint32) uptr->capac; - } - - return r; -} - -t_stat tod_detach(UNIT *uptr) -{ - t_stat r; - - r = detach_unit(uptr); - - if ((uptr->flags & UNIT_ATT) == 0) { - uptr->flags = uptr->flags & (uint32) ~(UNIT_ATTABLE | UNIT_BUFABLE); - } - - return r; -} - -/* - * Re-set the tod_data registers based on the current simulated time. - */ -void tod_resync() -{ - struct timespec now; - struct tm tm; - time_t sec; - TOD_DATA *td = (TOD_DATA *)tod_unit.filebuf; - - sim_rtcn_get_time(&now, TMR_CLK); - sec = now.tv_sec - td->delta; - - /* Populate the tm struct based on current sim_time */ - tm = *gmtime(&sec); - - td->tsec = 0; - td->unit_sec = tm.tm_sec % 10; - td->ten_sec = tm.tm_sec / 10; - td->unit_min = tm.tm_min % 10; - td->ten_min = tm.tm_min / 10; - td->unit_hour = tm.tm_hour % 10; - td->ten_hour = tm.tm_hour / 10; - /* tm struct stores as 0-11, tod struct as 1-12 */ - td->unit_mon = (tm.tm_mon + 1) % 10; - td->ten_mon = (tm.tm_mon + 1) / 10; - td->unit_day = tm.tm_mday % 10; - td->ten_day = tm.tm_mday / 10; - td->year = 1 << ((tm.tm_year - 1) % 4); -} - -/* - * Re-calculate the delta between real time and simulated time - */ -void tod_update_delta() -{ - struct timespec now; - struct tm tm = {0}; - time_t ssec; - TOD_DATA *td = (TOD_DATA *)tod_unit.filebuf; - sim_rtcn_get_time(&now, TMR_CLK); - - /* Let the host decide if it is DST or not */ - tm.tm_isdst = -1; - - /* Compute the simulated seconds value */ - tm.tm_sec = (td->ten_sec * 10) + td->unit_sec; - tm.tm_min = (td->ten_min * 10) + td->unit_min; - tm.tm_hour = (td->ten_hour * 10) + td->unit_hour; - /* tm struct stores as 0-11, tod struct as 1-12 */ - tm.tm_mon = ((td->ten_mon * 10) + td->unit_mon) - 1; - tm.tm_mday = (td->ten_day * 10) + td->unit_day; - - /* We're forced to do this weird arithmetic because the TOD chip - * used by the 3B2 does not store the year. It only stores the - * offset from the nearest leap year. */ - switch(td->year) { - case 1: /* Leap Year - 3 */ - tm.tm_year = 85; - break; - case 2: /* Leap Year - 2 */ - tm.tm_year = 86; - break; - case 4: /* Leap Year - 1 */ - tm.tm_year = 87; - break; - case 8: /* Leap Year */ - tm.tm_year = 88; - break; - default: - break; - } - - ssec = mktime(&tm); - td->delta = (int32)(now.tv_sec - ssec); -} - -uint32 tod_read(uint32 pa, size_t size) -{ - uint8 reg; - TOD_DATA *td = (TOD_DATA *)(tod_unit.filebuf); - - tod_resync(); - - reg = pa - TODBASE; - - switch(reg) { - case 0x04: /* 1/10 Sec */ - return td->tsec; - case 0x08: /* 1 Sec */ - return td->unit_sec; - case 0x0c: /* 10 Sec */ - return td->ten_sec; - case 0x10: /* 1 Min */ - return td->unit_min; - case 0x14: /* 10 Min */ - return td->ten_min; - case 0x18: /* 1 Hour */ - return td->unit_hour; - case 0x1c: /* 10 Hour */ - return td->ten_hour; - case 0x20: /* 1 Day */ - return td->unit_day; - case 0x24: /* 10 Day */ - return td->ten_day; - case 0x28: /* Day of Week */ - return td->wday; - case 0x2c: /* 1 Month */ - return td->unit_mon; - case 0x30: /* 10 Month */ - return td->ten_mon; - case 0x34: /* Year */ - return td->year; - default: - break; - } - - return 0; -} - -void tod_write(uint32 pa, uint32 val, size_t size) -{ - uint32 reg; - TOD_DATA *td = (TOD_DATA *)(tod_unit.filebuf); - - reg = pa - TODBASE; - - switch(reg) { - case 0x04: /* 1/10 Sec */ - td->tsec = (uint8) val; - break; - case 0x08: /* 1 Sec */ - td->unit_sec = (uint8) val; - break; - case 0x0c: /* 10 Sec */ - td->ten_sec = (uint8) val; - break; - case 0x10: /* 1 Min */ - td->unit_min = (uint8) val; - break; - case 0x14: /* 10 Min */ - td->ten_min = (uint8) val; - break; - case 0x18: /* 1 Hour */ - td->unit_hour = (uint8) val; - break; - case 0x1c: /* 10 Hour */ - td->ten_hour = (uint8) val; - break; - case 0x20: /* 1 Day */ - td->unit_day = (uint8) val; - break; - case 0x24: /* 10 Day */ - td->ten_day = (uint8) val; - break; - case 0x28: /* Day of Week */ - td->wday = (uint8) val; - break; - case 0x2c: /* 1 Month */ - td->unit_mon = (uint8) val; - break; - case 0x30: /* 10 Month */ - td->ten_mon = (uint8) val; - break; - case 0x34: /* Year */ - td->year = (uint8) val; - break; - case 0x38: - if (val & 1) { - tod_update_delta(); - } - break; - default: - break; - } -} - -const char *tod_description(DEVICE *dptr) -{ - return "Time-of-Day clock, used to store system time between boots.\n"; -} - -t_stat tod_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr) -{ - fprintf(st, - "The TOD is a battery-backed time-of-day clock that holds system\n" - "time between boots. In order to store the time, a file must be\n" - "attached to the TOD device with the SIMH command:\n" - "\n" - " sim> ATTACH TOD \n" - "\n" - "On a newly installed System V Release 3 UNIX system, no system\n" - "time will be stored in the TOD clock. In order to set the system\n" - "time, run the following command from within UNIX (as root):\n" - "\n" - " # sysadm datetime\n" - "\n" - "On subsequent boots, the correct system time will restored from\n" - "from the TOD.\n"); - - return SCPE_OK; -} - -#if defined(REV3) - -/* - * Fault Register - * - * The Fault Register is composed of two 32-bit registers at addresses - * 0x4C000 and 0x4D000. These latch state of the last address to cause - * a CPU fault. - * - * Bits 00-25: Physical memory address bits 00-25 - */ - -uint32 flt_1 = 0; -uint32 flt_2 = 0; - -UNIT flt_unit = { - UDATA(NULL, UNIT_FIX+UNIT_BINK, 8) -}; - -REG flt_reg[] = { - { NULL } -}; - -DEVICE flt_dev = { - "FLT", &flt_unit, flt_reg, NULL, - 1, 16, 8, 4, 16, 32, - NULL, NULL, NULL, - NULL, NULL, NULL, - NULL, DEV_DEBUG, 0, sys_deb_tab, NULL, NULL, - NULL, NULL, NULL, - NULL -}; - -uint32 flt_read(uint32 pa, size_t size) -{ - sim_debug(READ_MSG, &flt_dev, - "[%08x] Read from FLT Register at %x\n", - R[NUM_PC], pa); - return 0; -} - -void flt_write(uint32 pa, uint32 val, size_t size) -{ - sim_debug(WRITE_MSG, &flt_dev, - "[%08x] Write to FLT Register at %x (val=%x)\n", - R[NUM_PC], pa, val); - return; -} - -#endif +/* 3b2_stddev.c: Miscellaneous System Board Devices + + Copyright (c) 2017-2022, Seth J. Morabito + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + Except as contained in this notice, the name of the author shall + not be used in advertising or otherwise to promote the sale, use or + other dealings in this Software without prior written authorization + from the author. +*/ + +/* + This file contains system-specific registers and devices for the + following 3B2 devices: + + - nvram Non-Volatile RAM + - tod MM58174A and MM58274C Real-Time-Clock + - flt Fault Register (Rev 3 only) +*/ + +#include "3b2_stddev.h" + +#include "3b2_cpu.h" +#include "3b2_csr.h" +#include "3b2_timer.h" + +DEBTAB sys_deb_tab[] = { + { "INIT", INIT_MSG, "Init" }, + { "READ", READ_MSG, "Read activity" }, + { "WRITE", WRITE_MSG, "Write activity" }, + { "EXECUTE", EXECUTE_MSG, "Execute activity" }, + { "IRQ", IRQ_MSG, "Interrupt activity"}, + { "TRACE", TRACE_DBG, "Detailed activity" }, + { NULL, 0 } +}; + +uint32 *NVRAM = NULL; + +/* NVRAM */ +UNIT nvram_unit = { + UDATA(NULL, UNIT_FIX+UNIT_BINK, NVRSIZE) +}; + +REG nvram_reg[] = { + { NULL } +}; + +DEVICE nvram_dev = { + "NVRAM", &nvram_unit, nvram_reg, NULL, + 1, 16, 8, 4, 16, 32, + &nvram_ex, &nvram_dep, &nvram_reset, + NULL, &nvram_attach, &nvram_detach, + NULL, DEV_DEBUG, 0, sys_deb_tab, NULL, NULL, + &nvram_help, NULL, NULL, + &nvram_description +}; + +t_stat nvram_ex(t_value *vptr, t_addr exta, UNIT *uptr, int32 sw) +{ + uint32 addr = (uint32) exta; + + if ((vptr == NULL) || (addr & 03)) { + return SCPE_ARG; + } + + if (addr >= NVRSIZE) { + return SCPE_NXM; + } + + *vptr = NVRAM[addr >> 2]; + + return SCPE_OK; +} + +t_stat nvram_dep(t_value val, t_addr exta, UNIT *uptr, int32 sw) +{ + uint32 addr = (uint32) exta; + + if (addr & 03) { + return SCPE_ARG; + } + + if (addr >= NVRSIZE) { + return SCPE_NXM; + } + + NVRAM[addr >> 2] = (uint32) val; + + return SCPE_OK; +} + +t_stat nvram_reset(DEVICE *dptr) +{ + if (NVRAM == NULL) { + NVRAM = (uint32 *)calloc(NVRSIZE >> 2, sizeof(uint32)); + memset(NVRAM, 0, sizeof(uint32) * NVRSIZE >> 2); + nvram_unit.filebuf = NVRAM; + } + + if (NVRAM == NULL) { + return SCPE_MEM; + } + + return SCPE_OK; +} + +const char *nvram_description(DEVICE *dptr) +{ + return "Non-Volatile RAM.\n"; +} + +t_stat nvram_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr) +{ + fprintf(st, "Non-Volatile RAM\n\n"); + fprintf(st, "The %s device is a small battery-backed, non-volatile RAM\n", dptr->name); + fprintf(st, "used by the 3B2 to hold system configuration and diagnostic data.\n\n"); + fprintf(st, "In order for the simulator to keep track of this data while not\n"); + fprintf(st, "running, the %s device may be attached to a file, e.g.\n\n", dptr->name); + fprintf(st, " sim> ATTACH NVRAM \n"); + fprint_show_help(st, dptr); + fprint_reg_help(st, dptr); + return SCPE_OK; +} + +t_stat nvram_attach(UNIT *uptr, CONST char *cptr) +{ + t_stat r; + + /* If we've been asked to attach, make sure the ATTABLE + and BUFABLE flags are set on the unit */ + uptr->flags = uptr->flags | (UNIT_ATTABLE | UNIT_BUFABLE); + + r = attach_unit(uptr, cptr); + + if (r != SCPE_OK) { + /* Unset the ATTABLE and BUFABLE flags if we failed. */ + uptr->flags = uptr->flags & (uint32) ~(UNIT_ATTABLE | UNIT_BUFABLE); + } else { + uptr->hwmark = (uint32) uptr->capac; + } + + return r; +} + +t_stat nvram_detach(UNIT *uptr) +{ + t_stat r; + + r = detach_unit(uptr); + + if ((uptr->flags & UNIT_ATT) == 0) { + uptr->flags = uptr->flags & (uint32) ~(UNIT_ATTABLE | UNIT_BUFABLE); + } + + return r; +} + +uint32 nvram_read(uint32 pa, size_t size) +{ + uint32 offset = pa - NVRBASE; + uint32 data = 0; + uint32 sc = (~(offset & 3) << 3) & 0x1f; + + switch(size) { + case 8: + data = (NVRAM[offset >> 2] >> sc) & BYTE_MASK; + break; + case 16: + if (offset & 2) { + data = NVRAM[offset >> 2] & HALF_MASK; + } else { + data = (NVRAM[offset >> 2] >> 16) & HALF_MASK; + } + break; + case 32: + data = NVRAM[offset >> 2]; + break; + } + + return data; +} + +void nvram_write(uint32 pa, uint32 val, size_t size) +{ + uint32 offset = pa - NVRBASE; + uint32 index = offset >> 2; + uint32 sc, mask; + + switch(size) { + case 8: + sc = (~(pa & 3) << 3) & 0x1f; + mask = (uint32) (0xff << sc); + NVRAM[index] = (NVRAM[index] & ~mask) | (val << sc); + break; + case 16: + if (offset & 2) { + NVRAM[index] = (NVRAM[index] & ~HALF_MASK) | val; + } else { + NVRAM[index] = (NVRAM[index] & HALF_MASK) | (val << 16); + } + break; + case 32: + NVRAM[index] = val; + break; + } +} + +/* + * MM58174A and MM58274C Time Of Day Clock. + * + * In addition to keeping track of time of day in tenths of seconds, + * this device is also used as the simulator's primary calibrated + * real-time clock. It operates at the speed of 100Hz, with every + * tenth step incrementing the time-of-day counter. + */ + +#define TOD_12H(TD) (((TD)->clkset & 1) == 0) +#define TOD_BCDH(V) (((V) / 10) & 0xf) +#define TOD_BCDL(V) (((V) % 10) & 0xf) +#define TOD_LYEAR(TD) ((TD)->lyear == 0) +#define TOD_LYEAR_INC(TD) \ + do { \ + (TD)->lyear = (((TD)->lyear + 1) & 0x3); \ + (TD)->clkset &= 3; \ + (TD)->clkset |= (TD)->lyear << 2; \ + } while(0) + +#define CTRL_DISABLE 0x4 +#define CLKSET_PM 0x2 +#define FLAG_DATA_CHANGED 0x4 +#define FLAG_INTERRUPT 0x1 +#define MIN_DIFF 5l +#define MAX_DIFF 157680000l + +#define CLK_DELAY 10000 /* 10 milliseconds per tick */ +#define CLK_TPS 100l /* 100 ticks per second */ + +static void tod_resync(UNIT *uptr); +static void tod_tick(UNIT *uptr); +static t_stat tod_svc(UNIT *uptr); +static t_bool tod_enabled; + +int32 tmr_poll = CLK_DELAY; +int32 tmxr_poll = CLK_DELAY; + +UNIT tod_unit = { + UDATA(&tod_svc, UNIT_FIX|UNIT_BINK|UNIT_IDLE, sizeof(TOD_DATA)), CLK_DELAY +}; + +REG tod_reg[] = { + { DRDATAD(POLL, tmr_poll, 24, "Calibrated poll interval") }, + { 0 } +}; + +DEVICE tod_dev = { + "TOD", &tod_unit, tod_reg, NULL, + 1, 16, 8, 4, 16, 32, + NULL, NULL, &tod_reset, + NULL, &tod_attach, &tod_detach, + NULL, DEV_DEBUG, 0, sys_deb_tab, NULL, NULL, + &tod_help, NULL, NULL, + &tod_description +}; + +/* + * Attempt to re-sync the TOD by catching up (if lagging) and updating + * the current time stored in the TOD state. + * + * Because this process may be expensive when catching up following a + * very long time without the simulator running, the process will + * short-circuit if the delta is longer than 5 years, or if no + * previous time was recorded. + */ +static void tod_resync(UNIT *uptr) +{ + TOD_DATA *td; + time_t delta; + uint32_t catchup_ticks; + + if (!(uptr->flags & UNIT_ATT) || uptr->filebuf == NULL) { + return; + } + + td = (TOD_DATA *)uptr->filebuf; + + if (td->time > 0) { + delta = time(NULL) - td->time; + if (delta > MIN_DIFF && delta < MAX_DIFF) { + catchup_ticks = (uint32_t) delta * CLK_TPS; + sim_debug(EXECUTE_MSG, &tod_dev, + "Catching up with a delta of %ld seconds (%d ticks).\n", + delta, catchup_ticks); + while (catchup_ticks-- > 0) { + tod_tick(&tod_unit); + } + } + } + + td->time = time(NULL); +} + +t_stat tod_reset(DEVICE *dptr) +{ + int32 t; + + if (tod_unit.filebuf == NULL) { + tod_unit.filebuf = calloc(sizeof(TOD_DATA), 1); + if (tod_unit.filebuf == NULL) { + return SCPE_MEM; + } + } + + /* We start in a running state */ + tod_enabled = TRUE; + + t = sim_rtcn_init_unit(&tod_unit, tod_unit.wait, TMR_CLK); + sim_activate_after(&tod_unit, 1000000/CLK_TPS); + tmr_poll = t; + tmxr_poll = t; + + return SCPE_OK; +} + +t_stat tod_attach(UNIT *uptr, CONST char *cptr) +{ + t_stat r; + + uptr->flags = uptr->flags | (UNIT_ATTABLE | UNIT_BUFABLE); + + r = attach_unit(uptr, cptr); + + if (r != SCPE_OK) { + uptr->flags = uptr->flags & (uint32) ~(UNIT_ATTABLE | UNIT_BUFABLE); + } else { + uptr->hwmark = (uint32) uptr->capac; + } + + return r; +} + +t_stat tod_detach(UNIT *uptr) +{ + t_stat r; + + r = detach_unit(uptr); + + if ((uptr->flags & UNIT_ATT) == 0) { + uptr->flags = uptr->flags & (uint32) ~(UNIT_ATTABLE | UNIT_BUFABLE); + } + + return r; +} + +static t_stat tod_svc(UNIT *uptr) +{ + TOD_DATA *td = (TOD_DATA *)uptr->filebuf; + int32 t; + + /* Re-sync the recorded system time once every second */ + if (tod_enabled) { + tod_tick(uptr); + + if (td->tsec == 0) { + tod_resync(uptr); + } + } + + t = sim_rtcn_calb(CLK_TPS, TMR_CLK); + sim_activate_after(uptr, 1000000/CLK_TPS); + tmr_poll = t; + tmxr_poll = t; + AIO_SET_INTERRUPT_LATENCY(tmr_poll * CLK_TPS); + return SCPE_OK; +} + +/* + * The MM58174 and MM58274 consist of a set of failry "dumb" roll-over + * counters. In an ideal world, we'd just look at the real system time + * and translate that into whatever read the host needs. + * Unfortunately, since the Day-of-Week and Leap Year registers are + * totally independent of whatever the "real" date and time should be, + * this doesn't map very well, and DGMON hardware diagnostics fail. + * + * Instead, we model the behavior of the chip accurately here. Each + * rollover is cascaded to the next highest register, using the same + * logic the chip uses. + */ +static void tod_tick(UNIT *uptr) +{ + TOD_DATA *td = (TOD_DATA *)uptr->filebuf; + + if (++td->tsec > 99) { + td->tsec = 0; + td->flags |= FLAG_DATA_CHANGED; + if (++td->sec > 59) { + td->sec = 0; + if (++td->min > 59) { + td->min = 0; + td->hour++; + + /* 12-hour clock cycles from 1-12, 24-hour clock cycles from 00-23 */ + if (TOD_12H(td)) { + if (td->hour == 12) { + td->clkset ^= CLKSET_PM; + } + if (td->hour > 12) { + td->hour = 1; + } + } else if (td->hour > 23) { + td->hour = 0; + } + + if ((TOD_12H(td) && td->hour == 12) || (!TOD_12H(td) && td->hour == 0)) { + /* Manage day-of-week */ + td->wday++; + if (td->wday > 7) { + td->wday = 1; + } + td->day++; + switch(td->mon) { + case 2: /* FEB */ + if (TOD_LYEAR(td)) { + if (td->day > 29) { + td->day = 1; + } + } else { + if (td->day > 28) { + td->day = 1; + } + } + break; + case 4: /* APR */ + case 6: /* JUN */ + case 9: /* SEP */ + case 11: /* NOV */ + if (td->day > 30) { + td->day = 1; + } + break; + case 1: /* JAN */ + case 3: /* MAR */ + case 5: /* MAY */ + case 7: /* JUL */ + case 8: /* AUG */ + case 10: /* OCT */ + case 12: /* DEC */ + if (td->day > 31) { + td->day = 1; + } + break; + } + if (td->day == 1) { + if (++td->mon > 12) { + td->mon = 1; + TOD_LYEAR_INC(td); + if (++td->year > 99) { + td->year = 0; + } + } + } + } + } + } + } +} + + +uint32 tod_read(uint32 pa, size_t size) +{ + uint8 reg, val; + TOD_DATA *td = (TOD_DATA *)(tod_unit.filebuf); + + reg = pa & 0xfc; + + switch(reg) { +#if defined(REV3) + case TOD_CTRL: + val = td->flags; + td->flags &= ~(FLAG_DATA_CHANGED); + break; +#endif + case TOD_TSEC: + val = TOD_BCDH(td->tsec); + break; + case TOD_1SEC: + val = TOD_BCDL(td->sec); + break; + case TOD_10SEC: + val = TOD_BCDH(td->sec); + break; + case TOD_1MIN: + val = TOD_BCDL(td->min); + break; + case TOD_10MIN: + val = TOD_BCDH(td->min); + break; + case TOD_1HOUR: + val = TOD_BCDL(td->hour); + break; + case TOD_10HOUR: + val = TOD_BCDH(td->hour); + break; + case TOD_1DAY: + val = TOD_BCDL(td->day); + break; + case TOD_10DAY: + val = TOD_BCDH(td->day); + break; + case TOD_1MON: + val = TOD_BCDL(td->mon); + break; + case TOD_10MON: + val = TOD_BCDH(td->mon); + break; + case TOD_WDAY: + val = td->wday; + break; + case TOD_1YEAR: +#if defined(REV3) + val = TOD_BCDL(td->year); +#else + val = td->lyear; +#endif + break; +#if defined(REV3) + case TOD_10YEAR: + val = TOD_BCDH(td->year); + break; + case TOD_SET_INT: + val = td->clkset; + break; +#endif + default: + val = 0; + break; + } + + return val; +} + +void tod_write(uint32 pa, uint32 val, size_t size) +{ + uint32 reg; + TOD_DATA *td = (TOD_DATA *)(tod_unit.filebuf); + + /* reg = pa - TODBASE; */ + reg = pa & 0xfc; + + switch(reg) { +#if defined(REV3) + case TOD_CTRL: + td->ctrl = (uint8) val; + if (val & CTRL_DISABLE) { + tod_enabled = FALSE; + td->tsec = 0; + } else { + tod_enabled = TRUE; + } +#else + case TOD_TEST: + /* test mode */ +#endif + break; + case TOD_TSEC: + td->tsec = (uint8) val * 10; + break; + case TOD_1SEC: + td->sec = ((td->sec / 10) * 10) + (uint8) val; + break; + case TOD_10SEC: + td->sec = ((uint8) val * 10) + (td->sec % 10); + break; + case TOD_1MIN: + td->min = ((td->min / 10) * 10) + (uint8) val; + break; + case TOD_10MIN: + td->min = ((uint8) val * 10) + (td->min % 10); + break; + case TOD_1HOUR: + td->hour = ((td->hour / 10) * 10) + (uint8) val; + break; + case TOD_10HOUR: + td->hour = ((uint8) val * 10) + (td->hour % 10); + break; + case TOD_1DAY: + td->day = ((td->day / 10) * 10) + (uint8) val; + break; + case TOD_10DAY: + td->day = ((uint8) val * 10) + (td->day % 10); + break; + case TOD_1MON: + td->mon = ((td->mon / 10) * 10) + (uint8) val; + break; + case TOD_10MON: + td->mon = ((uint8) val * 10) + (td->mon % 10); + break; + case TOD_1YEAR: +#if defined(REV3) + td->year = ((td->year / 10) * 10) + (uint8) val; +#else + td->lyear = (uint8) val; +#endif + break; +#if defined(REV3) + case TOD_10YEAR: + td->year = ((uint8) val * 10) + (td->year % 10); + break; + case TOD_SET_INT: + td->clkset = (uint8) val; + if (!TOD_12H(td)) { + /* The AM/PM indicator is always 0 if not in 12H mode */ + td->clkset &= ~(CLKSET_PM); + } + td->lyear = (val >> 2) & 3; + break; +#else + case TOD_STARTSTOP: + tod_enabled = val & 1; + break; +#endif + case TOD_WDAY: + td->wday = (uint8)val & 0x7; + break; + default: + break; + } +} + +const char *tod_description(DEVICE *dptr) +{ +#if defined(REV3) + return("MM58274C real time clock"); +#else + return("MM58174A real time clock"); +#endif +} + +t_stat tod_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr) +{ + char dname[10]; + +#if defined(REV3) + snprintf(dname, 10, "MM58274C"); +#else + snprintf(dname, 10, "MM58174A"); +#endif + + fprintf(st, "%s Time-Of-Day Clock (%s)\n\n", dname, dptr->name); + fprintf(st, "The %s controller simulates a National Semiconductor %s\n", dptr->name, dname); + fprintf(st, "real time clock. This clock keeps track of the current system time\n"); + fprintf(st, "and date.\n\n"); + fprintf(st, "In order to preserve simulated calendar time between simulator runs,\n"); + fprintf(st, "the %s clock may be attached to a file which stores its state while\n", dptr->name); + fprintf(st, "the simulator is not running, e.g.:\n\n"); + fprintf(st, " sim> ATTACH TOD \n"); + fprint_show_help(st, dptr); + fprint_reg_help(st, dptr); + return SCPE_OK; +} + +#if defined(REV3) + +/* + * Fault Register + * + * The Fault Register is composed of two 32-bit registers at addresses + * 0x4C000 and 0x4D000. These latch state of the last address to cause + * a CPU fault. + * + * Bits 00-25: Physical memory address bits + * + * Fault Register 2 does double duty. It actually consists of four + * words, each of which maps to a memory slot on the system board. If + * occupied, it records the size of memory equipped in the slot, as + * well as information about any memory faults. + * + * + * Bits Active Purpose + * ---------------------------------------------------- + * 31-26 H Upper Halfword ECC Syndrome Bits + * 25-20 H Lower Halfword ECC Syndeome Bits + * 19 L I/O Bus or BUB master on Fault + * 18 H Invert low addr bit 2 (DWORD1) + * 17 H Decrement low addr by 4 + * 16 L I/O Bus Master on Fault + * 15 L CPU accessing I/O Peripheral + * 14 L BUB Slot 0 master on fault + * 13 L CPU Accessing BUB Peripheral + * 12-11 H BUB peripheral accessed by CPU + * 10 L BUB Slot 1 master on fault + * 9 L BUB Slot 2 master on fault + * 8 L BUB Slot 3 master on fault + * 7-3 N/A Not Used + * 2 L Memory Equipped + * 1-0 H Equipped Memory Size + * + */ + +uint32 flt[2] = {0, 0}; + +UNIT flt_unit = { + UDATA(NULL, UNIT_FIX+UNIT_BINK, 64) +}; + +REG flt_reg[] = { + { HRDATAD(FLT1, flt[0], 32, "Fault Register 1") }, + { HRDATAD(FLT2, flt[1], 32, "Fault Register 2") }, + { NULL } +}; + +DEVICE flt_dev = { + "FLT", &flt_unit, flt_reg, NULL, + 1, 16, 32, 1, 16, 32, + NULL, NULL, NULL, + NULL, NULL, NULL, + NULL, DEV_DEBUG, 0, sys_deb_tab, NULL, NULL, + &flt_help, NULL, NULL, + &flt_description +}; + +/* + * Return the configured memory size for a given backplane location. + */ +static uint32 mem_size(uint8 slot) { + switch(MEM_SIZE) { + case MSIZ_8M: + if (slot <= 1) { + return MEM_EQP|MEM_4M; + } else { + return 0; + } + case MSIZ_16M: + return MEM_EQP|MEM_4M; + case MSIZ_32M: + if (slot <= 1) { + return MEM_EQP|MEM_16M; + } else { + return 0; + } + case MSIZ_64M: + return MEM_EQP|MEM_16M; + default: + return 0; + } +} + +uint32 flt_read(uint32 pa, size_t size) +{ + sim_debug(EXECUTE_MSG, &flt_dev, + "Read from FLT Register at %x\n", + pa); + + switch(pa) { + case FLTLBASE: + return flt[0]; + case FLTHBASE: + return (flt[1] & FLT_MSK) | mem_size(0); + case FLTHBASE + 4: + return (flt[1] & FLT_MSK) | mem_size(1); + case FLTHBASE + 8: + return (flt[1] & FLT_MSK) | mem_size(2); + case FLTHBASE + 12: + return (flt[1] & FLT_MSK) | mem_size(3); + default: + sim_debug(EXECUTE_MSG, &flt_dev, + "Read from FLT Register at %x: FAILURE, NO DATA!!!!\n", + pa); + return 0; + } +} + +void flt_write(uint32 pa, uint32 val, size_t size) +{ + sim_debug(EXECUTE_MSG, &flt_dev, + "Write to FLT Register at %x (val=%x)\n", + pa, val); + + return; +} + +t_stat flt_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr) +{ + fprintf(st, "Fault Register\n\n"); + fprintf(st, "The %s device is a pair of 32-bit registers that hold information about\n", dptr->name); + fprintf(st, "system memory faults.\n"); + fprint_show_help(st, dptr); + fprint_reg_help(st, dptr); + return SCPE_OK; +} + +const char *flt_description(DEVICE *dptr) +{ + return "Fault Register"; +} + +#endif diff --git a/3B2/3b2_stddev.h b/3B2/3b2_stddev.h index c709fd00..987ed87d 100644 --- a/3B2/3b2_stddev.h +++ b/3B2/3b2_stddev.h @@ -1,82 +1,138 @@ -/* 3b2_stddev.h: AT&T 3B2 miscellaneous system board devices. - - Copyright (c) 2017, Seth J. Morabito - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - - Except as contained in this notice, the name of the author shall - not be used in advertising or otherwise to promote the sale, use or - other dealings in this Software without prior written authorization - from the author. -*/ - -#ifndef _3B2_STDDEV_H_ -#define _3B2_STDDEV_H_ - -#include "3b2_defs.h" - -/* NVRAM */ -t_stat nvram_ex(t_value *vptr, t_addr exta, UNIT *uptr, int32 sw); -t_stat nvram_dep(t_value val, t_addr exta, UNIT *uptr, int32 sw); -t_stat nvram_reset(DEVICE *dptr); -uint32 nvram_read(uint32 pa, size_t size); -t_stat nvram_attach(UNIT *uptr, CONST char *cptr); -t_stat nvram_detach(UNIT *uptr); -const char *nvram_description(DEVICE *dptr); -t_stat nvram_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr); -void nvram_write(uint32 pa, uint32 val, size_t size); - -/* TOD */ -typedef struct tod_data { - int32 delta; /* Delta between simulated time and real time (sec.) */ - uint8 tsec; /* 1/10 seconds */ - uint8 unit_sec; /* 1's column seconds */ - uint8 ten_sec; /* 10's column seconds */ - uint8 unit_min; /* 1's column minutes */ - uint8 ten_min; /* 10's column minutes */ - uint8 unit_hour; /* 1's column hours */ - uint8 ten_hour; /* 10's column hours */ - uint8 unit_day; /* 1's column day of month */ - uint8 ten_day; /* 10's column day of month */ - uint8 wday; /* Day of week (0-6) */ - uint8 unit_mon; /* 1's column month */ - uint8 ten_mon; /* 10's column month */ - uint8 year; /* 1, 2, 4, 8 shift register */ - uint8 pad[3]; /* Padding to 32 bytes */ -} TOD_DATA; - -void tod_resync(); -void tod_update_delta(); -t_stat tod_reset(DEVICE *dptr); -t_stat tod_attach(UNIT *uptr, CONST char *cptr); -t_stat tod_detach(UNIT *uptr); -const char *tod_description(DEVICE *dptr); -t_stat tod_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr); -uint32 tod_read(uint32 pa, size_t size); -void tod_write(uint32, uint32 val, size_t size); - -#if defined(REV3) -/* Fault Register */ -uint32 flt_read(uint32 pa, size_t size); -void flt_write(uint32 pa, uint32 val, size_t size); -#endif - -#endif /* _3B2_STDDEV_H_ */ +/* 3b2_stddev.h: Miscellaneous System Board Devices + + Copyright (c) 2017-2022, Seth J. Morabito + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + Except as contained in this notice, the name of the author shall + not be used in advertising or otherwise to promote the sale, use or + other dealings in this Software without prior written authorization + from the author. +*/ + +#ifndef _3B2_STDDEV_H_ +#define _3B2_STDDEV_H_ + +#include "3b2_defs.h" + +/* NVRAM */ +t_stat nvram_ex(t_value *vptr, t_addr exta, UNIT *uptr, int32 sw); +t_stat nvram_dep(t_value val, t_addr exta, UNIT *uptr, int32 sw); +t_stat nvram_reset(DEVICE *dptr); +uint32 nvram_read(uint32 pa, size_t size); +t_stat nvram_attach(UNIT *uptr, CONST char *cptr); +t_stat nvram_detach(UNIT *uptr); +const char *nvram_description(DEVICE *dptr); +t_stat nvram_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr); +void nvram_write(uint32 pa, uint32 val, size_t size); + +typedef struct tod_data { + time_t time; /* System time */ + + uint8 ctrl; /* Control register (Rev 3 only) */ + uint8 flags; /* Data Changed & Interrutpt Flags (Rev 3 only) */ + uint8 clkset; /* Clock / Setting register (Rev 3 only) */ + + uint8 tsec; /* 1/100th seconds, 00-99 */ + uint8 sec; /* Seconds, 00-59 */ + uint8 min; /* Minutes, 00-59 */ + uint8 hour; /* Hours, 00-23 */ + uint8 day; /* Days, 00-27, 28, 29, or 30 */ + uint8 mon; /* Months, 00-11 */ + uint8 year; /* Years, 00-99 (Rev 3 only) */ + uint8 wday; /* Day of Week, 0-6 */ + uint8 lyear; /* Years since last leap year */ +} TOD_DATA; + +#if defined(REV2) + +#define TOD_TEST 0x00 +#define TOD_TSEC 0x04 +#define TOD_1SEC 0x08 +#define TOD_10SEC 0x0c +#define TOD_1MIN 0x10 +#define TOD_10MIN 0x14 +#define TOD_1HOUR 0x18 +#define TOD_10HOUR 0x1c +#define TOD_1DAY 0x20 +#define TOD_10DAY 0x24 +#define TOD_WDAY 0x28 +#define TOD_1MON 0x2c +#define TOD_10MON 0x30 +#define TOD_1YEAR 0x34 +#define TOD_STARTSTOP 0x38 +#define TOD_INT 0x3c + +#else + +#define TOD_FLAG_CHG 0x08 +#define TOD_FLAG_IRQ 0x01 + +#define TOD_CTRL 0x00 +#define TOD_TSEC 0x04 +#define TOD_1SEC 0x08 +#define TOD_10SEC 0x0c +#define TOD_1MIN 0x10 +#define TOD_10MIN 0x14 +#define TOD_1HOUR 0x18 +#define TOD_10HOUR 0x1c +#define TOD_1DAY 0x20 +#define TOD_10DAY 0x24 +#define TOD_1MON 0x28 +#define TOD_10MON 0x2c +#define TOD_1YEAR 0x30 +#define TOD_10YEAR 0x34 +#define TOD_WDAY 0x38 +#define TOD_SET_INT 0x3c + +#endif + +void tod_update_delta(); +t_stat tod_reset(DEVICE *dptr); +t_stat tod_attach(UNIT *uptr, CONST char *cptr); +t_stat tod_detach(UNIT *uptr); +t_stat tod_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr); +const char *tod_description(DEVICE *dptr); +uint32 tod_read(uint32 pa, size_t size); +void tod_write(uint32, uint32 val, size_t size); + +/* Global symbols */ + +extern int32 tmxr_poll; + +#if defined(REV3) +/* Fault Register */ + +#define FLT_MSK 0xffffff00 +#define MEM_EQP 0x4 +#define MEM_4M 0x2 +#define MEM_16M 0x3 + +uint32 flt_read(uint32 pa, size_t size); +void flt_write(uint32 pa, uint32 val, size_t size); +t_stat flt_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr); +const char *flt_description(DEVICE *dptr); + +extern uint32 flt[2]; + +#endif /* defined(REV3) */ + +#endif /* _3B2_STDDEV_H_ */ diff --git a/3B2/3b2_sys.c b/3B2/3b2_sys.c index e826d46c..62e36e82 100644 --- a/3B2/3b2_sys.c +++ b/3B2/3b2_sys.c @@ -1,160 +1,192 @@ -/* 3b2_sys.c: AT&T 3B2 common system definitions - - Copyright (c) 2021, Seth J. Morabito - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - - Except as contained in this notice, the name of the author shall - not be used in advertising or otherwise to promote the sale, use or - other dealings in this Software without prior written authorization - from the author. -*/ - -#include "3b2_sys.h" - -#include "3b2_cpu.h" -#include "3b2_mem.h" - -REG *sim_PC = &cpu_reg[NUM_PC]; - -/* All opcodes are 1 or 2 bytes. Operands may be up to 6 bytes, and - there may be up to 3 operands, for a maximum of 20 bytes */ -int32 sim_emax = 20; - -const char *sim_stop_messages[SCPE_BASE] = { - "Unknown error", - "Reserved Instruction", - "Breakpoint", - "Invalid Opcode", - "IRQ", - "Exception/Trap", - "Exception Stack Too Deep", - "Unimplemented MMU Feature", - "System Powered Off", - "Infinite Loop", - "Simulator Error" -}; - -t_stat sim_load(FILE *fileref, CONST char *cptr, CONST char *fnam, int flag) -{ - int32 i; - uint32 addr = 0; - int32 cnt = 0; - - if ((*cptr != 0) || (flag != 0)) { - return SCPE_ARG; - } - - addr = R[NUM_PC]; - - while ((i = getc (fileref)) != EOF) { - pwrite_b(addr, (uint8)i); - addr++; - cnt++; - } - - printf ("%d Bytes loaded.\n", cnt); - - return SCPE_OK; -} - -t_stat parse_sym(CONST char *cptr, t_addr exta, UNIT *uptr, t_value *val, int32 sw) -{ - DEVICE *dptr; - t_stat r; - int32 k, num, vp; - int32 len = 4; - - if (sw & (int32) SWMASK ('B')) { - len = 1; - } else if (sw & (int32) SWMASK ('H')) { - len = 2; - } else if (sw & (int32) SWMASK ('W')) { - len = 4; - } - - // Parse cptr - num = (int32) get_uint(cptr, 16, WORD_MASK, &r); - - if (r != SCPE_OK) { - return r; - } - - if (uptr == NULL) { - uptr = &cpu_unit; - } - - dptr = find_dev_from_unit(uptr); - - if (dptr == NULL) { - return SCPE_IERR; - } - - vp = 0; - for (k = len - 1; k >= 0; k--) { - val[vp++] = (num >> (k * 8)) & 0xff; - } - - return -(vp - 1); -} - -t_stat fprint_sym(FILE *of, t_addr addr, t_value *val, UNIT *uptr, int32 sw) -{ - uint32 len = 4; - int32 k, vp, num; - unsigned int c; - - num = 0; - vp = 0; - - if (sw & (int32) SWMASK('M')) { - return fprint_sym_m(of, addr, val); - } - - if (sw & (int32) SWMASK ('B')) { - len = 1; - } else if (sw & (int32) SWMASK ('H')) { - len = 2; - } else if (sw & (int32) SWMASK ('W')) { - len = 4; - } - - if (sw & (int32) SWMASK('C')) { - len = 16; - for (k = (int32) len - 1; k >= 0; k--) { - c = (unsigned int)val[vp++]; - if (c >= 0x20 && c < 0x7f) { - fprintf(of, "%c", c); - } else { - fprintf(of, "."); - } - } - return -(vp - 1); - } - - for (k = len - 1; k >= 0; k--) { - num = num | (((int32) val[vp++]) << (k * 8)); - } - - fprint_val(of, (uint32) num, 16, len * 8, PV_RZRO); - - return -(vp - 1); -} +/* 3b2_sys.c: Common System Definition + + Copyright (c) 2021-2022, Seth J. Morabito + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + Except as contained in this notice, the name of the author shall + not be used in advertising or otherwise to promote the sale, use or + other dealings in this Software without prior written authorization + from the author. +*/ + +#include "3b2_sys.h" + +#include "3b2_cpu.h" +#include "3b2_mem.h" + +REG *sim_PC = &cpu_reg[NUM_PC]; + +/* All opcodes are 1 or 2 bytes. Operands may be up to 6 bytes, and + there may be up to 3 operands, for a maximum of 20 bytes */ +int32 sim_emax = 20; + +const char *sim_stop_messages[SCPE_BASE] = { + "Unknown error", + "Reserved Instruction", + "Breakpoint", + "Invalid Opcode", + "IRQ", + "Exception/Trap", + "Exception Stack Too Deep", + "Unimplemented MMU Feature", + "System Powered Off", + "Infinite Loop", + "Simulator Error" +}; + +/* + * ROM and Binary loader + * + * -r load ROM + * -o for memory, specify origin + * + */ +t_stat sim_load(FILE *fileref, CONST char *cptr, CONST char *fnam, int flag) +{ + t_stat r; + int32 i; + uint32 origin = 0, limit = 0; + int32 cnt = 0; + + if (flag) { + return sim_messagef(SCPE_NOFNC, "Command not implemented."); + } + + if (sim_switches & SWMASK('R')) { + origin = ROM_BASE; + limit = ROM_BASE + ROM_SIZE; + } else { + origin = 0; + limit = (uint32) cpu_unit.capac; + if (sim_switches & SWMASK('O')) { + origin = (uint32) get_uint(cptr, 16, 0xffffffff, &r); + if (r != SCPE_OK) { + return SCPE_ARG; + } + } + } + + while ((i = Fgetc (fileref)) != EOF) { + if (origin >= limit) { + return SCPE_NXM; + } + if (sim_switches & SWMASK('R')) { + pwrite_b_rom(origin, (uint8)i); + } else { + pwrite_b(origin, (uint8)i, BUS_CPU); + } + origin++; + cnt++; + } + + if (sim_switches & SWMASK('R')) { + rom_loaded = TRUE; + sim_messagef(SCPE_OK, "%d bytes loaded into ROM\n", cnt); + } else { + sim_messagef(SCPE_OK, "%d bytes loaded at address 0x%08x\n", cnt, origin - cnt); + } + + return SCPE_OK; +} + +t_stat parse_sym(CONST char *cptr, t_addr exta, UNIT *uptr, t_value *val, int32 sw) +{ + DEVICE *dptr; + t_stat r; + int32 k, num, vp; + int32 len = 4; + + if (sw & (int32) SWMASK ('B')) { + len = 1; + } else if (sw & (int32) SWMASK ('H')) { + len = 2; + } else if (sw & (int32) SWMASK ('W')) { + len = 4; + } + + // Parse cptr + num = (int32) get_uint(cptr, 16, WORD_MASK, &r); + + if (r != SCPE_OK) { + return r; + } + + if (uptr == NULL) { + uptr = &cpu_unit; + } + + dptr = find_dev_from_unit(uptr); + + if (dptr == NULL) { + return SCPE_IERR; + } + + vp = 0; + for (k = len - 1; k >= 0; k--) { + val[vp++] = (num >> (k * 8)) & 0xff; + } + + return -(vp - 1); +} + +t_stat fprint_sym(FILE *of, t_addr addr, t_value *val, UNIT *uptr, int32 sw) +{ + uint32 len = 4; + int32 k, vp, num; + unsigned int c; + + num = 0; + vp = 0; + + if (sw & (int32) SWMASK('M')) { + return fprint_sym_m(of, addr, val); + } + + if (sw & (int32) SWMASK ('B')) { + len = 1; + } else if (sw & (int32) SWMASK ('H')) { + len = 2; + } else if (sw & (int32) SWMASK ('W')) { + len = 4; + } + + if (sw & (int32) SWMASK('C')) { + len = 16; + for (k = (int32) len - 1; k >= 0; k--) { + c = (unsigned int)val[vp++]; + if (c >= 0x20 && c < 0x7f) { + fprintf(of, "%c", c); + } else { + fprintf(of, "."); + } + } + return -(vp - 1); + } + + for (k = len - 1; k >= 0; k--) { + num = num | (((int32) val[vp++]) << (k * 8)); + } + + fprint_val(of, (uint32) num, 16, len * 8, PV_RZRO); + + return -(vp - 1); +} diff --git a/3B2/3b2_sys.h b/3B2/3b2_sys.h index d3fa72e2..dc79dde8 100644 --- a/3B2/3b2_sys.h +++ b/3B2/3b2_sys.h @@ -1,46 +1,46 @@ -/* 3b2_rev2_sys.h: AT&T 3B2 Rev 2 (Model 400) system header - - Copyright (c) 2017, Seth J. Morabito - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - - Except as contained in this notice, the name of the author shall - not be used in advertising or otherwise to promote the sale, use or - other dealings in this Software without prior written authorization - from the author. -*/ - -#ifndef _3B2_SYS_H_ -#define _3B2_SYS_H_ - -#include "3b2_defs.h" - -void full_reset(); -t_stat sim_load(FILE *fileref, CONST char *cptr, CONST char *fnam, int flag); -t_stat parse_sym(CONST char *cptr, t_addr addr, UNIT *uptr, t_value *val, - int32 sw); -t_stat fprint_sym(FILE *of, t_addr addr, t_value *val, UNIT *uptr, int32 sw); - -extern char sim_name[]; -extern REG *sim_PC; -extern int32 sim_emax; - -#endif /* _3B2_SYS_H_ */ +/* 3b2_sys.h: Common System Definition + + Copyright (c) 2017-2022, Seth J. Morabito + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + Except as contained in this notice, the name of the author shall + not be used in advertising or otherwise to promote the sale, use or + other dealings in this Software without prior written authorization + from the author. +*/ + +#ifndef _3B2_SYS_H_ +#define _3B2_SYS_H_ + +#include "3b2_defs.h" + +void full_reset(); +t_stat sim_load(FILE *fileref, CONST char *cptr, CONST char *fnam, int flag); +t_stat parse_sym(CONST char *cptr, t_addr addr, UNIT *uptr, t_value *val, + int32 sw); +t_stat fprint_sym(FILE *of, t_addr addr, t_value *val, UNIT *uptr, int32 sw); + +extern char sim_name[]; +extern REG *sim_PC; +extern int32 sim_emax; + +#endif /* _3B2_SYS_H_ */ diff --git a/3B2/3b2_rev3_timer.c b/3B2/3b2_timer.c similarity index 55% rename from 3B2/3b2_rev3_timer.c rename to 3B2/3b2_timer.c index 085a7ffd..761d282e 100644 --- a/3B2/3b2_rev3_timer.c +++ b/3B2/3b2_timer.c @@ -1,506 +1,506 @@ -/* 3b2_rev3_timer.c: 82C54 Interval Timer. - - Copyright (c) 2021, Seth J. Morabito - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - - Except as contained in this notice, the name of the author shall - not be used in advertising or otherwise to promote the sale, use or - other dealings in this Software without prior written authorization - from the author. -*/ - -/* - * 82C54 Timer. - * - * 82C54 (Rev3) Timer IC has three interval timers, which we treat - * here as three units. - * - * In the 3B2, the three timers are assigned specific purposes: - * - * - Timer 0: SYSTEM SANITY TIMER. This timer is normally loaded with - * a short timeout and allowed to run. If it times out, it - * will generate an interrupt and cause a system - * error. Software resets the timer regularly to ensure - * that it does not time out. It is fed by a 10 kHz - * clock, so each single counting step of this timer is - * 100 microseconds. - * - * - Timer 1: UNIX INTERVAL TIMER. This is the main timer that drives - * process switching in Unix. It operates at a fixed rate, - * and the counter is set up by Unix to generate an - * interrupt once every 10 milliseconds. The timer is fed - * by a 100 kHz clock, so each single counting step of - * this timer is 10 microseconds. - * - * - Timer 2: BUS TIMEOUT TIMER. This timer is reset every time the - * IO bus is accessed, and then stopped when the IO bus - * responds. It is mainly used to determine when the IO - * bus is hung (e.g., no card is installed in a given - * slot, so nothing can respond). When it times out, it - * generates an interrupt. It is fed by a 500 kHz clock, - * so each single counting step of this timer is 2 - * microseconds. - * - * - * Implementaiton Notes - * ==================== - * - * In general, no attempt has been made to create an accurate - * emulation of the 82C54 timer. This implementation is truly built - * for the 3B2, and even more specifically for System V Unix, which is - * the only operating system ever to have been ported to the 3B2. - * - * - The Bus Timeout Timer is not implemented other than a stub that - * is designed to pass hardware diagnostics. The simulator IO - * subsystem always sets the correct interrupt directly if the bus - * will not respond. - * - * - The System Sanity Timer is also not implemented other than a - * stub to pass diagnostics. - * - * - The main Unix Interval Timer is implemented as a true SIMH clock - * when set up for the correct mode. In other modes, it likewise - * implements a stub designed to pass diagnostics. - */ - -#include "3b2_cpu.h" -#include "3b2_csr.h" -#include "3b2_defs.h" -#include "3b2_timer.h" - -struct timer_ctr TIMERS[3]; - -int32 tmxr_poll = 16667; - -UNIT timer_unit[] = { - { UDATA(&timer0_svc, 0, 0) }, - { UDATA(&timer1_svc, UNIT_IDLE, 0) }, - { UDATA(&timer2_svc, 0, 0) }, - { NULL } -}; - -UNIT *timer_clk_unit = &timer_unit[1]; - -REG timer_reg[] = { - { HRDATAD(DIV0, TIMERS[0].divider, 16, "Divider (0)") }, - { HRDATAD(COUNT0, TIMERS[0].val, 16, "Count (0)") }, - { HRDATAD(CTRL0, TIMERS[0].ctrl, 8, "Control (0)") }, - { HRDATAD(DIV1, TIMERS[1].divider, 16, "Divider (1)") }, - { HRDATAD(COUNT1, TIMERS[1].val, 16, "Count (1)") }, - { HRDATAD(CTRL1, TIMERS[1].ctrl, 8, "Control (1)") }, - { HRDATAD(DIV2, TIMERS[2].divider, 16, "Divider (2)") }, - { HRDATAD(COUNT2, TIMERS[2].val, 16, "Count (2)") }, - { HRDATAD(CTRL2, TIMERS[2].ctrl, 8, "Control (2)") }, - { NULL } -}; - -DEVICE timer_dev = { - "TIMER", timer_unit, timer_reg, NULL, - 1, 16, 8, 4, 16, 32, - NULL, NULL, &timer_reset, - NULL, NULL, NULL, NULL, - DEV_DEBUG, 0, sys_deb_tab -}; - -t_stat timer_reset(DEVICE *dptr) { - int32 i; - - memset(&TIMERS, 0, sizeof(struct timer_ctr) * 3); - - for (i = 0; i < 3; i++) { - timer_unit[i].tmrnum = i; - timer_unit[i].tmr = (void *)&TIMERS[i]; - } - - /* TODO: I don't think this is right. Verify. */ - /* - if (!sim_is_running) { - t = sim_rtcn_init_unit(timer_clk_unit, TPS_CLK, TMR_CLK); - sim_activate_after_abs(timer_clk_unit, 1000000 / t); - } - */ - - return SCPE_OK; -} - -static void timer_activate(uint8 ctrnum) -{ - struct timer_ctr *ctr; - - ctr = &TIMERS[ctrnum]; - - switch (ctrnum) { - case TIMER_SANITY: - if ((csr_data & CSRISTIM) == 0) { - sim_debug(EXECUTE_MSG, &timer_dev, - "[%08x] SANITY TIMER: Activating after %d steps\n", - R[NUM_PC], ctr->val); - sim_activate_abs(&timer_unit[ctrnum], ctr->val); - ctr->val--; - } else { - sim_debug(EXECUTE_MSG, &timer_dev, - "[%08x] SANITY TIMER: Currently disabled, not starting\n", - R[NUM_PC]); - } - break; - case TIMER_INTERVAL: - if ((csr_data & CSRITIM) == 0) { - sim_debug(EXECUTE_MSG, &timer_dev, - "[%08x] INTERVAL TIMER: Activating after %d ms\n", - R[NUM_PC], ctr->val); - sim_activate_after_abs(&timer_unit[ctrnum], ctr->val); - ctr->val--; - } else { - sim_debug(EXECUTE_MSG, &timer_dev, - "[%08x] INTERVAL TIMER: Currently disabled, not starting\n", - R[NUM_PC]); - } - break; - case TIMER_BUS: - if ((csr_data & CSRITIMO) == 0) { - sim_debug(EXECUTE_MSG, &timer_dev, - "[%08x] BUS TIMER: Activating after %d steps\n", - R[NUM_PC], ctr->val); - sim_activate_abs(&timer_unit[ctrnum], (ctr->val - 2)); - ctr->val -= 2; - } else { - sim_debug(EXECUTE_MSG, &timer_dev, - "[%08x] BUS TIMER: Currently disabled, not starting\n", - R[NUM_PC]); - } - break; - default: - break; - } -} - -void timer_enable(uint8 ctrnum) -{ - sim_debug(EXECUTE_MSG, &timer_dev, - "[%08x] Enabling timer %d\n", - R[NUM_PC], ctrnum); - timer_activate(ctrnum); -} - -void timer_disable(uint8 ctrnum) -{ - sim_debug(EXECUTE_MSG, &timer_dev, - "[%08x] Disabling timer %d\n", - R[NUM_PC], ctrnum); - sim_cancel(&timer_unit[ctrnum]); -} - -/* - * Sanity Timer - */ -t_stat timer0_svc(UNIT *uptr) -{ - struct timer_ctr *ctr; - - ctr = (struct timer_ctr *)uptr->tmr; - - if (ctr->enabled) { - sim_debug(EXECUTE_MSG, &timer_dev, - "[%08x] TIMER 0 COMPLETION.\n", - R[NUM_PC]); - if (!(csr_data & CSRISTIM)) { - sim_debug(EXECUTE_MSG, &timer_dev, - "[%08x] TIMER 0 NMI IRQ.\n", - R[NUM_PC]); - ctr->val = 0xffff; - cpu_nmi = TRUE; - CSRBIT(CSRSTIMO, TRUE); - CPU_SET_INT(INT_BUS_TMO); - } - } - - return SCPE_OK; -} - -/* - * Interval Timer - */ -t_stat timer1_svc(UNIT *uptr) -{ - struct timer_ctr *ctr; - int32 t; - - ctr = (struct timer_ctr *)uptr->tmr; - - if (ctr->enabled && !(csr_data & CSRITIM)) { - /* Fire the IPL 15 clock interrupt */ - CSRBIT(CSRCLK, TRUE); - CPU_SET_INT(INT_CLOCK); - } - - t = sim_rtcn_calb(TPS_CLK, TMR_CLK); - sim_activate_after_abs(uptr, 1000000/TPS_CLK); - tmxr_poll = t; - - return SCPE_OK; -} - -/* - * Bus Timeout Timer - */ -t_stat timer2_svc(UNIT *uptr) -{ - struct timer_ctr *ctr; - - ctr = (struct timer_ctr *)uptr->tmr; - - if (ctr->enabled && TIMER_RW(ctr) == CLK_LSB) { - sim_debug(EXECUTE_MSG, &timer_dev, - "[%08x] TIMER 2 COMPLETION.\n", - R[NUM_PC]); - if (!(csr_data & CSRITIMO)) { - sim_debug(EXECUTE_MSG, &timer_dev, - "[%08x] TIMER 2 IRQ.\n", - R[NUM_PC]); - ctr->val = 0xffff; - CSRBIT(CSRTIMO, TRUE); - CPU_SET_INT(INT_BUS_TMO); - /* Also trigger a bus abort */ - cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT); - } - } - - return SCPE_OK; -} - -uint32 timer_read(uint32 pa, size_t size) -{ - uint32 reg; - uint16 ctr_val; - uint8 ctrnum, retval; - struct timer_ctr *ctr; - - reg = pa - TIMERBASE; - ctrnum = (reg >> 2) & 0x3; - ctr = &TIMERS[ctrnum]; - - switch (reg) { - case TIMER_REG_DIVA: - case TIMER_REG_DIVB: - case TIMER_REG_DIVC: - ctr_val = ctr->val; - - switch (TIMER_RW(ctr)) { - case CLK_LSB: - retval = ctr_val & 0xff; - sim_debug(READ_MSG, &timer_dev, - "[%08x] [%d] [LSB] val=%d (0x%x)\n", - R[NUM_PC], ctrnum, retval, retval); - break; - case CLK_MSB: - retval = (ctr_val & 0xff00) >> 8; - sim_debug(READ_MSG, &timer_dev, - "[%08x] [%d] [MSB] val=%d (0x%x)\n", - R[NUM_PC], ctrnum, retval, retval); - break; - case CLK_LMB: - if (ctr->r_ctrl_latch) { - ctr->r_ctrl_latch = FALSE; - retval = ctr->ctrl_latch; - sim_debug(READ_MSG, &timer_dev, - "[%08x] [%d] [LATCH CTRL] val=%d (0x%x)\n", - R[NUM_PC], ctrnum, retval, retval); - } else if (ctr->r_cnt_latch) { - if (ctr->r_lmb) { - ctr->r_lmb = FALSE; - retval = (ctr->cnt_latch & 0xff00) >> 8; - ctr->r_cnt_latch = FALSE; - sim_debug(READ_MSG, &timer_dev, - "[%08x] [%d] [LATCH DATA MSB] val=%d (0x%x)\n", - R[NUM_PC], ctrnum, retval, retval); - } else { - ctr->r_lmb = TRUE; - retval = ctr->cnt_latch & 0xff; - sim_debug(READ_MSG, &timer_dev, - "[%08x] [%d] [LATCH DATA LSB] val=%d (0x%x)\n", - R[NUM_PC], ctrnum, retval, retval); - } - } else if (ctr->r_lmb) { - ctr->r_lmb = FALSE; - retval = (ctr_val & 0xff00) >> 8; - sim_debug(READ_MSG, &timer_dev, - "[%08x] [%d] [LMB - MSB] val=%d (0x%x)\n", - R[NUM_PC], ctrnum, retval, retval); - } else { - ctr->r_lmb = TRUE; - retval = ctr_val & 0xff; - sim_debug(READ_MSG, &timer_dev, - "[%08x] [%d] [LMB - LSB] val=%d (0x%x)\n", - R[NUM_PC], ctrnum, retval, retval); - } - break; - default: - retval = 0; - } - - return retval; - case TIMER_REG_CTRL: - return ctr->ctrl; - case TIMER_CLR_LATCH: - /* Clearing the timer latch has a side-effect - of also clearing pending interrupts */ - CSRBIT(CSRCLK, FALSE); - CPU_CLR_INT(INT_CLOCK); - return 0; - default: - /* Unhandled */ - sim_debug(READ_MSG, &timer_dev, - "[%08x] UNHANDLED TIMER READ. ADDR=%08x\n", - R[NUM_PC], pa); - return 0; - } -} - -void handle_timer_write(uint8 ctrnum, uint32 val) -{ - struct timer_ctr *ctr; - UNIT *unit = &timer_unit[ctrnum]; - - ctr = &TIMERS[ctrnum]; - ctr->enabled = TRUE; - - switch(TIMER_RW(ctr)) { - case CLK_LSB: - ctr->divider = val & 0xff; - ctr->val = ctr->divider; - sim_debug(WRITE_MSG, &timer_dev, - "[%08x] [%d] [LSB] val=%d (0x%x)\n", - R[NUM_PC], ctrnum, val & 0xff, val & 0xff); - timer_activate(ctrnum); - break; - case CLK_MSB: - ctr->divider = (val & 0xff) << 8; - ctr->val = ctr->divider; - sim_debug(WRITE_MSG, &timer_dev, - "[%08x] [%d] [MSB] val=%d (0x%x)\n", - R[NUM_PC], ctrnum, val & 0xff, val & 0xff); - timer_activate(ctrnum); - break; - case CLK_LMB: - if (ctr->w_lmb) { - ctr->w_lmb = FALSE; - ctr->divider = (uint16) ((ctr->divider & 0x00ff) | ((val & 0xff) << 8)); - ctr->val = ctr->divider; - sim_debug(WRITE_MSG, &timer_dev, - "[%08x] [%d] [LMB - MSB] val=%d (0x%x)\n", - R[NUM_PC], ctrnum, val & 0xff, val & 0xff); - timer_activate(ctrnum); - } else { - ctr->w_lmb = TRUE; - ctr->divider = (ctr->divider & 0xff00) | (val & 0xff); - ctr->val = ctr->divider; - sim_debug(WRITE_MSG, &timer_dev, - "[%08x] [%d] [LMB - LSB] val=%d (0x%x)\n", - R[NUM_PC], ctrnum, val & 0xff, val & 0xff); - } - break; - default: - break; - - } -} - -void timer_write(uint32 pa, uint32 val, size_t size) -{ - uint8 reg, ctrnum; - struct timer_ctr *ctr; - - reg = (uint8) (pa - TIMERBASE); - - switch(reg) { - case TIMER_REG_DIVA: - handle_timer_write(0, val); - break; - case TIMER_REG_DIVB: - handle_timer_write(1, val); - break; - case TIMER_REG_DIVC: - handle_timer_write(2, val); - break; - case TIMER_REG_CTRL: - ctrnum = (val >> 6) & 3; - if (ctrnum == 3) { - sim_debug(WRITE_MSG, &timer_dev, - "[%08x] READ BACK COMMAND. DATA=%02x\n", - R[NUM_PC], val); - if (val & 2) { - ctr = &TIMERS[0]; - if ((val & 0x20) == 0) { - ctr->ctrl_latch = (uint16) TIMERS[2].ctrl; - ctr->r_ctrl_latch = TRUE; - } - if ((val & 0x20) == 0) { - ctr->cnt_latch = ctr->val; - ctr->r_cnt_latch = TRUE; - } - } - if (val & 4) { - ctr = &TIMERS[1]; - if ((val & 0x10) == 0) { - ctr->ctrl_latch = (uint16) TIMERS[2].ctrl; - ctr->r_ctrl_latch = TRUE; - } - if ((val & 0x20) == 0) { - ctr->cnt_latch = ctr->val; - ctr->r_cnt_latch = TRUE; - } - } - if (val & 8) { - ctr = &TIMERS[2]; - if ((val & 0x10) == 0) { - ctr->ctrl_latch = (uint16) TIMERS[2].ctrl; - ctr->r_ctrl_latch = TRUE; - } - if ((val & 0x20) == 0) { - ctr->cnt_latch = ctr->val; - ctr->r_cnt_latch = TRUE; - } - } - } else { - sim_debug(WRITE_MSG, &timer_dev, - "[%08x] Timer Control Write: timer %d => %02x\n", - R[NUM_PC], ctrnum, val & 0xff); - ctr = &TIMERS[ctrnum]; - ctr->ctrl = (uint8) val; - ctr->enabled = FALSE; - ctr->w_lmb = FALSE; - ctr->r_lmb = FALSE; - ctr->val = 0xffff; - ctr->divider = 0xffff; - } - break; - case TIMER_CLR_LATCH: - sim_debug(WRITE_MSG, &timer_dev, - "[%08x] unexpected write to clear timer latch\n", - R[NUM_PC]); - break; - default: - sim_debug(WRITE_MSG, &timer_dev, - "[%08x] unknown timer register: %d\n", - R[NUM_PC], reg); - } -} +/* 3b2_timer.c: 8253/82C54 Interval Timer + + Copyright (c) 2021-2022, Seth J. Morabito + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + Except as contained in this notice, the name of the author shall + not be used in advertising or otherwise to promote the sale, use or + other dealings in this Software without prior written authorization + from the author. +*/ + +/* + * The 8253/82C54 Timer IC has three interval timers, which we treat + * here as three units. + * + * In the 3B2, the three timers are assigned specific purposes: + * + * - Timer 0: SYSTEM SANITY TIMER. This timer is normally loaded with + * a short timeout and allowed to run. If it times out, it + * will generate an interrupt and cause a system + * error. Software resets the timer regularly to ensure + * that it does not time out. It is fed by a 10 kHz + * clock, so each single counting step of this timer is + * 100 microseconds. + * + * - Timer 1: UNIX INTERVAL TIMER. This is the main timer that drives + * process switching in Unix. It operates at a fixed rate, + * and the counter is set up by Unix to generate an + * interrupt once every 10 milliseconds. The timer is fed + * by a 100 kHz clock, so each single counting step of + * this timer is 10 microseconds. + * + * - Timer 2: BUS TIMEOUT TIMER. This timer is reset every time the + * IO bus is accessed, and then stopped when the IO bus + * responds. It is mainly used to determine when the IO + * bus is hung (e.g., no card is installed in a given + * slot, so nothing can respond). When it times out, it + * generates an interrupt. It is fed by a 500 kHz clock, + * so each single counting step of this timer is 2 + * microseconds. + * + * + * Implementaiton Notes + * ==================== + * + * In general, no attempt has been made to create a truly accurate + * simulation of the 8253/82C54 timer. This implementation is built + * for the 3B2, and even more specifically to pass System V timer + * "Sanity/Interval Timer" diagnostics. + * + * - The Bus Timeout Timer is not implemented other than a stub that + * is designed to pass hardware diagnostics. The simulator IO + * subsystem always sets the correct interrupt directly if the bus + * will not respond. + * + * - The System Sanity Timer is also not implemented other than a + * stub to pass diagnostics. + * + * - The main Unix Interval Timer is more fully implemented, because + * it drives system interrupts in System V UNIX. + */ + +#include "3b2_cpu.h" +#include "3b2_csr.h" +#include "3b2_defs.h" +#include "3b2_timer.h" + +#define MIN_DIVIDER 50 + +#if defined (REV3) +#define QUICK_DELAY 10 +#else +#define QUICK_DELAY 100 +#endif + +#define DELAY_US(C,N) ((TIMER_MODE(C) == 3) ? \ + (TIME_BASE[(N)] * (C)->divider) / 2 : \ + TIME_BASE[(N)] * (C)->divider) + +#if defined(REV3) +/* Microseconds per step (Version 3 system board): + * + * Timer 0: 10KHz time base + * Timer 1: 100KHz time base + * Timer 2: 500KHz time base + */ +static uint32 TIME_BASE[3] = { + 100, 10, 1 +}; +#else +/* Microseconds per step (Version 2 system board): + * + * Timer 0: 100Khz time base + * Timer 1: 100Khz time base + * Timer 2: 500Khz time base + */ +static uint32 TIME_BASE[3] = { + 10, 10, 2 +}; +#endif + +struct timer_ctr TIMERS[3]; + +UNIT timer_unit[] = { + { UDATA(&tmr_svc, UNIT_IDLE, 0) }, + { UDATA(&tmr_svc, UNIT_IDLE, 0) }, + { UDATA(&tmr_svc, UNIT_IDLE, 0) }, + { NULL } +}; + +UNIT *tmr_int_unit = &timer_unit[3]; + +REG timer_reg[] = { + { HRDATAD(DIV0, TIMERS[0].divider, 16, "Divider (0)") }, + { HRDATAD(COUNT0, TIMERS[0].val, 16, "Count (0)") }, + { HRDATAD(CTRL0, TIMERS[0].ctrl, 8, "Control (0)") }, + { HRDATAD(DIV1, TIMERS[1].divider, 16, "Divider (1)") }, + { HRDATAD(COUNT1, TIMERS[1].val, 16, "Count (1)") }, + { HRDATAD(CTRL1, TIMERS[1].ctrl, 8, "Control (1)") }, + { HRDATAD(DIV2, TIMERS[2].divider, 16, "Divider (2)") }, + { HRDATAD(COUNT2, TIMERS[2].val, 16, "Count (2)") }, + { HRDATAD(CTRL2, TIMERS[2].ctrl, 8, "Control (2)") }, + { NULL } +}; + +DEVICE timer_dev = { + "TMR", + timer_unit, + timer_reg, + NULL, + 3, + 16, + 8, + 4, + 16, + 32, + NULL, + NULL, + &timer_reset, + NULL, + NULL, + NULL, + NULL, + DEV_DEBUG, + 0, + sys_deb_tab, + NULL, + NULL, + &tmr_help, + NULL, + NULL, + &tmr_description +}; + +t_stat timer_reset(DEVICE *dptr) { + int32 i; + + memset(&TIMERS, 0, sizeof(struct timer_ctr) * 3); + + /* Store the timer/counter number in the UNIT */ + for (i = 0; i < 3; i++) { + timer_unit[i].u3 = i; + } + + return SCPE_OK; +} + +/* + * Inhibit or allow a timer externally. + */ +void timer_gate(uint8 ctrnum, t_bool inhibit) +{ + struct timer_ctr *ctr = &TIMERS[ctrnum]; + + if (inhibit) { + ctr->gate = FALSE; + sim_cancel(&timer_unit[ctrnum]); + } else { + ctr->gate = TRUE; + if (ctr->enabled && !sim_is_active(&timer_unit[ctrnum])) { + sim_activate_after(&timer_unit[ctrnum], DELAY_US(ctr, ctrnum)); + ctr->val--; + } + } +} + +static void timer_activate(uint8 ctrnum) +{ + struct timer_ctr *ctr = &TIMERS[ctrnum]; + + if (ctr->enabled && ctr->gate) { + if (ctr->divider < MIN_DIVIDER) { + /* If the timer delay is too short, we need to force a + very quick activation */ + sim_activate_abs(&timer_unit[ctrnum], QUICK_DELAY); + } else { + /* Otherwise, use a computed time in microseconds */ + sim_activate_after_abs(&timer_unit[ctrnum], DELAY_US(ctr, ctrnum)); + } + } +} + +/* + * Sanity, Non-calibrated Interval, and Bus Timeout Timer service routine + */ +t_stat tmr_svc(UNIT *uptr) +{ + int32 ctr_num = uptr->u3; + uint32 usec_delay; + struct timer_ctr *ctr = &TIMERS[ctr_num]; + + if (ctr == NULL) { + return SCPE_SUB; + } + + /* If the timer isn't enabled, do nothing. */ + if (!ctr->enabled) { + return SCPE_OK; + } + + sim_debug(EXECUTE_MSG, &timer_dev, + "[tmr_svc] Handling timeout for ctr number %d\n", + ctr_num); + + switch (ctr_num) { + case TMR_SANITY: +#if defined (REV3) + if (!CSR(CSRISTIM) && TIMER_MODE(ctr) != 4) { + cpu_nmi = TRUE; + CSRBIT(CSRSTIMO, TRUE); + CPU_SET_INT(INT_BUS_TMO); + ctr->val = 0xffff; + } +#endif + break; + case TMR_INT: + if (!CSR(CSRITIM)) { + CSRBIT(CSRCLK, TRUE); + CPU_SET_INT(INT_CLOCK); + if (ctr->enabled && ctr->gate) { + usec_delay = DELAY_US(ctr, TMR_INT); + sim_debug(EXECUTE_MSG, &timer_dev, + "[tmr_svc] Re-triggering TMR_INT in %d usec\n", usec_delay); + sim_activate_after(uptr, usec_delay); + } + ctr->val = 0xffff; + } + break; + case TMR_BUS: +#if defined (REV3) + /* Only used during diagnostics */ + if (TIMER_RW(ctr) == CLK_LSB) { + sim_debug(EXECUTE_MSG, &timer_dev, + "[tmr_svc] BUS TIMER FIRING. Setting memory fault and interrupt\n"); + CSRBIT(CSRTIMO, TRUE); + CPU_SET_INT(INT_BUS_TMO); + cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT); + ctr->val = 0xffff; + } +#endif + break; + } + + + return SCPE_OK; +} + +uint32 timer_read(uint32 pa, size_t size) +{ + uint32 reg; + uint16 ctr_val; + uint8 ctrnum, retval; + struct timer_ctr *ctr; + + reg = pa - TIMERBASE; + ctrnum = (reg >> 2) & 0x3; + ctr = &TIMERS[ctrnum]; + + sim_debug(EXECUTE_MSG, &timer_dev, + "timer_read: reg=%x\n", reg); + + switch (reg) { + case TIMER_REG_DIVA: + case TIMER_REG_DIVB: + case TIMER_REG_DIVC: + ctr_val = ctr->val; + + switch (TIMER_RW(ctr)) { + case CLK_LSB: + retval = ctr_val & 0xff; + break; + case CLK_MSB: + retval = (ctr_val & 0xff00) >> 8; + break; + case CLK_LMB: + if (ctr->r_ctrl_latch) { + ctr->r_ctrl_latch = FALSE; + retval = ctr->ctrl_latch; + } else if (ctr->r_cnt_latch) { + if (ctr->r_lmb) { + ctr->r_lmb = FALSE; + retval = (ctr->cnt_latch & 0xff00) >> 8; + ctr->r_cnt_latch = FALSE; + } else { + ctr->r_lmb = TRUE; + retval = ctr->cnt_latch & 0xff; + } + } else if (ctr->r_lmb) { + ctr->r_lmb = FALSE; + retval = (ctr_val & 0xff00) >> 8; + } else { + ctr->r_lmb = TRUE; + retval = ctr_val & 0xff; + } + break; + default: + retval = 0; + } + + break; + case TIMER_REG_CTRL: + retval = ctr->ctrl; + break; + case TIMER_CLR_LATCH: + /* Clearing the timer latch has a side-effect + of also clearing pending interrupts */ + CSRBIT(CSRCLK, FALSE); + CPU_CLR_INT(INT_CLOCK); + /* Acknowledge a clock tick */ + sim_rtcn_tick_ack(1, TMR_CLK); + retval = 0; + break; + default: + /* Unhandled */ + retval = 0; + break; + } + + return retval; +} + +void handle_timer_write(uint8 ctrnum, uint32 val) +{ + struct timer_ctr *ctr; + + ctr = &TIMERS[ctrnum]; + ctr->enabled = TRUE; + + switch(TIMER_RW(ctr)) { + case CLK_LSB: + ctr->divider = val & 0xff; + ctr->val = ctr->divider; + sim_debug(EXECUTE_MSG, &timer_dev, "TIMER_WRITE: CTR=%d LSB=%02x\n", ctrnum, val & 0xff); + timer_activate(ctrnum); + break; + case CLK_MSB: + ctr->divider = (val & 0xff) << 8; + ctr->val = ctr->divider; + sim_debug(EXECUTE_MSG, &timer_dev, "TIMER_WRITE: CTR=%d MSB=%02x\n", ctrnum, val & 0xff); + timer_activate(ctrnum); + break; + case CLK_LMB: + if (ctr->w_lmb) { + ctr->w_lmb = FALSE; + ctr->divider = (uint16) ((ctr->divider & 0x00ff) | ((val & 0xff) << 8)); + ctr->val = ctr->divider; + sim_debug(EXECUTE_MSG, &timer_dev, "TIMER_WRITE: CTR=%d (L/M) MSB=%02x\n", ctrnum, val & 0xff); + timer_activate(ctrnum); + } else { + ctr->w_lmb = TRUE; + ctr->divider = (ctr->divider & 0xff00) | (val & 0xff); + ctr->val = ctr->divider; + sim_debug(EXECUTE_MSG, &timer_dev, "TIMER_WRITE: CTR=%d (L/M) LSB=%02x\n", ctrnum, val & 0xff); + } + break; + default: + break; + + } +} + +void timer_write(uint32 pa, uint32 val, size_t size) +{ + uint8 reg, ctrnum; + struct timer_ctr *ctr; + + reg = (uint8) (pa - TIMERBASE); + + sim_debug(EXECUTE_MSG, &timer_dev, + "timer_write: reg=%x val=%x\n", reg, val); + + switch(reg) { + case TIMER_REG_DIVA: + handle_timer_write(0, val); + break; + case TIMER_REG_DIVB: + handle_timer_write(1, val); + break; + case TIMER_REG_DIVC: + handle_timer_write(2, val); + break; + case TIMER_REG_CTRL: + ctrnum = (val >> 6) & 3; + if (ctrnum == 3) { + if (val & 2) { + ctr = &TIMERS[0]; + if ((val & 0x20) == 0) { + ctr->ctrl_latch = (uint16) TIMERS[2].ctrl; + ctr->r_ctrl_latch = TRUE; + } + if ((val & 0x20) == 0) { + ctr->cnt_latch = ctr->val; + ctr->r_cnt_latch = TRUE; + } + } + if (val & 4) { + ctr = &TIMERS[1]; + if ((val & 0x10) == 0) { + ctr->ctrl_latch = (uint16) TIMERS[2].ctrl; + ctr->r_ctrl_latch = TRUE; + } + if ((val & 0x20) == 0) { + ctr->cnt_latch = ctr->val; + ctr->r_cnt_latch = TRUE; + } + } + if (val & 8) { + ctr = &TIMERS[2]; + if ((val & 0x10) == 0) { + ctr->ctrl_latch = (uint16) TIMERS[2].ctrl; + ctr->r_ctrl_latch = TRUE; + } + if ((val & 0x20) == 0) { + ctr->cnt_latch = ctr->val; + ctr->r_cnt_latch = TRUE; + } + } + } else { + ctr = &TIMERS[ctrnum]; + ctr->ctrl = (uint8) val; + ctr->enabled = FALSE; + ctr->w_lmb = FALSE; + ctr->r_lmb = FALSE; + ctr->val = 0xffff; + ctr->divider = 0xffff; + } + break; + case TIMER_CLR_LATCH: + sim_debug(WRITE_MSG, &timer_dev, + "unexpected write to clear timer latch\n"); + break; + default: + sim_debug(WRITE_MSG, &timer_dev, + "unknown timer register: %d\n", + reg); + } +} + +CONST char *tmr_description(DEVICE *dptr) +{ +#if defined (REV3) + return "82C54 Programmable Interval Timer"; +#else + return "8253 Programmable Interval Timer"; +#endif +} + +t_stat tmr_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr) +{ +#if defined (REV3) + fprintf(st, "82C54 Programmable Interval Timer (TMR)\n\n"); + fprintf(st, "The TMR device implements three programmable timers used by the 3B2/700\n"); +#else + fprintf(st, "8253 Programmable Interval Timer (TMR)\n\n"); + fprintf(st, "The TMR device implements three programmable timers used by the 3B2/400\n"); +#endif + fprintf(st, "to perform periodic tasks and sanity checks.\n\n"); + fprintf(st, "- TMR0: Used as a system sanity timer.\n"); + fprintf(st, "- TMR1: Used as a periodic 10 millisecond interval timer.\n"); + fprintf(st, "- TMR2: Used as a bus timeout timer.\n"); + + fprint_set_help(st, dptr); + fprint_show_help(st, dptr); + fprint_reg_help(st, dptr); + + return SCPE_OK; +} diff --git a/3B2/3b2_timer.h b/3B2/3b2_timer.h index 35df9b67..19205b92 100644 --- a/3B2/3b2_timer.h +++ b/3B2/3b2_timer.h @@ -1,42 +1,78 @@ -/* 3b2_timer.h: Common TIMER header - - Copyright (c) 2021, Seth J. Morabito - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - - Except as contained in this notice, the name of the author shall - not be used in advertising or otherwise to promote the sale, use or - other dealings in this Software without prior written authorization - from the author. -*/ - -#ifndef _3B2_TIMER_H_ -#define _3B2_TIMER_H_ - -#if defined(REV3) -#include "3b2_rev3_timer.h" -#else -#include "3b2_rev2_timer.h" -#endif - -extern int32 tmxr_poll; - -#endif /* _3B2_TIMER_H_ */ +/* 3b2_timer.h: 8253/82C54 Interval Timer + + Copyright (c) 2021-2022, Seth J. Morabito + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + Except as contained in this notice, the name of the author shall + not be used in advertising or otherwise to promote the sale, use or + other dealings in this Software without prior written authorization + from the author. +*/ + +#ifndef _3B2_TIMER_H_ +#define _3B2_TIMER_H_ + +#include "3b2_defs.h" + +#define TIMER_REG_DIVA 0x03 +#define TIMER_REG_DIVB 0x07 +#define TIMER_REG_DIVC 0x0b +#define TIMER_REG_CTRL 0x0f +#define TIMER_CLR_LATCH 0x13 + +#define TIMER_MODE(ctr) (((ctr->ctrl) >> 1) & 7) +#define TIMER_RW(ctr) (((ctr->ctrl) >> 4) & 3) + +#define CLK_LATCH 0 +#define CLK_LSB 1 +#define CLK_MSB 2 +#define CLK_LMB 3 + +#define TMR_SANITY 0 +#define TMR_INT 1 +#define TMR_BUS 2 + +struct timer_ctr { + uint16 divider; + uint16 val; + uint8 ctrl_latch; + uint16 cnt_latch; + uint8 ctrl; + t_bool r_lmb; + t_bool w_lmb; + t_bool enabled; + t_bool gate; + t_bool r_ctrl_latch; + t_bool r_cnt_latch; +}; + +t_stat timer_reset(DEVICE *dptr); +uint32 timer_read(uint32 pa, size_t size); +void timer_write(uint32 pa, uint32 val, size_t size); +void timer_gate(uint8 ctrnum, t_bool inhibit); + +t_stat tmr_svc(UNIT *uptr); +t_stat tmr_int_svc(UNIT *uptr); +CONST char *tmr_description(DEVICE *dptr); +t_stat tmr_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr); + +#endif /* _3B2_TIMER_H_ */ diff --git a/3B2/README.md b/3B2/README.md index 96eb02f8..0afa967b 100644 --- a/3B2/README.md +++ b/3B2/README.md @@ -1,129 +1,135 @@ -AT&T 3B2 Simulator -================== - -This module contains the source for two simulators: - -1. A simulator for the AT&T 3B2 Model 400 computer (Rev. 2) -2. A simulator for the AT&T 3B2 Model 600 computer (Rev. 3) - -The 3B2/400 simulator is complete, usable, and robust. The 3B2/600 simulator -is not yet usable, however. It is under active development. - -Full documentation for the 3B2 simulator is available here: - - - https://loomcom.com/3b2/emulator.html - -Devices -------- - -The following devices are simulated. The SIMH names for the simulated -devices are given in parentheses: - - - 3B2 Model 400 System Board with 1MB, 2MB, or 4MB RAM (CSR, NVRAM) - - WE32100 CPU (CPU) - - WE32101 MMU (MMU) - - PD8253 Interval Timer (TIMER) - - AM9517 DMA controller (DMAC) - - SCN2681A Integrated DUART (IU) - - TMS2793 Integrated Floppy Controller (IFLOPPY) - - uPD7261A Integrated MFM Fixed Disk Controller (IDISK) - - Non-Volatile Memory (NVRAM) - - MM58174A Time Of Day Clock (TOD) - - CM195A Ethernet Network Interface (NI) - - CM195B 4-port Serial MUX (PORTS) - - CM195H Cartridge Tape Controller (CTC) - -Usage ------ - -To boot the 3B2 simulator into firmware mode, simply type: - - sim> BOOT - -You will be greeted with the message: - - FW ERROR 1-01: NVRAM SANITY FAILURE - DEFAULT VALUES ASSUMED - IF REPEATED, CHECK THE BATTERY - - FW ERROR 1-02: DISK SANITY FAILURE - EXECUTION HALTED - - SYSTEM FAILURE: CONSULT YOUR SYSTEM ADMINISTRATION UTILITIES GUIDE - -NVRAM and Time of Day can be saved between boots by attaching both -devices to files. - - sim> ATTACH NVRAM - sim> ATTACH TOD - -If you have no operating system installed on the hard drive, on -subsequent boots you will instead see the message - - SELF-CHECK - - - FW ERROR 1-02: DISK SANITY FAILURE - EXECUTION HALTED - - SYSTEM FAILURE: CONSULT YOUR SYSTEM ADMINISTRATION UTILITIES GUIDE - - -Once you see the `SYSTEM FAILURE` message, this is actually an -invisible prompt. To access firmware mode, type the default 3B2 -firmware password `mcp`, then press Enter or carriage return. - -You should then be prompted with: - - Enter name of program to execute [ ]: - -Here, you may type a question mark (?) and press Enter to see a list -of available firmware programs. - -Booting UNIX SVR3 ------------------ - -UNIX SVR3 is the only operating system available for the 3B2. To boot -UNIX, attach the first disk image from the 3B2 "Essential Utilities" -distribution. - - sim> ATTACH IFLOPPY - sim> BOOT - -Once you reach the `SYSTEM FAILURE` message, type `mcp` to enter -firmware mode. When prompted for the name of a program to boot, enter -`unix`, and confirm the boot device is `FD5` by pressing Enter or -carriage return. - - Enter name of program to execute [ ]: unix - Possible load devices are: - - Option Number Slot Name - --------------------------------------- - 0 0 FD5 - - Enter Load Device Option Number [0 (FD5)]: - -Installing SVR3 ---------------- - -To install SVR3 to the first hard disk, first, attach a new image -to the IDISK0 device: - - sim> ATTACH IDISK0 - -Then, boot the file `idtools` from the "3B2 Maintenance Utilities - -Issue 4.0" floppy diskette. - -From `idtools`, select the `formhard` option and low-level format -integrated disk 0. Parameters for the default 72MB hard disk are: - - Drive Id: 5 - Number cylinders: 925 - Number tracks/cyl: 9 - Number sectors/track: 18 - Number bytes/sector: 512 - -After low-level formatting integrated disk 0, boot the file `unix` -from the first diskette of the 3B2 "Essential Utilities" distribution, -and follow the prompts. +AT&T 3B2 Simulator +================== + +This module contains the source for two simulators: + +1. A simulator for the AT&T 3B2/400 computer (3b2 or 3B2.EXE) +2. A simulator for the AT&T 3B2/700 computer (3b2-700 or 3B2-700.EXE) + +The 3B2/400 simulator is complete, usable, and robust. The 3B2/700 +simulator is under active development and is not yet considered +stable. + +Full documentation for the 3B2 simulator is available here: + + - https://loomcom.com/3b2/emulator.html + +3B2/400 Simulator Devices +------------------------- + +The following devices are simulated. The SIMH names for the simulated +devices are given in parentheses: + + - 3B2 Model 400 System Board with 1MB, 2MB, or 4MB RAM (CSR, NVRAM) + - WE32100 CPU (CPU) + - WE32101 MMU (MMU) + - PD8253 Interval Timer (TMR) + - AM9517 DMA controller (DMAC) + - SCN2681A Integrated DUART (IU) + - TMS2793 Integrated Floppy Controller (IFLOPPY) + - uPD7261A Integrated MFM Fixed Disk Controller (IDISK) + - Non-Volatile Memory (NVRAM) + - MM58174A Time Of Day Clock (TOD) + - CM195A Ethernet Network Interface (NI) + - CM195B 4-port Serial MUX (PORTS) + - CM195H Cartridge Tape Controller (CTC) + +3B2/400 Simulator Usage +----------------------- + +To boot the 3B2 simulator into firmware mode, simply type: + + sim> BOOT + +You will be greeted with the message: + + FW ERROR 1-01: NVRAM SANITY FAILURE + DEFAULT VALUES ASSUMED + IF REPEATED, CHECK THE BATTERY + + FW ERROR 1-02: DISK SANITY FAILURE + EXECUTION HALTED + + SYSTEM FAILURE: CONSULT YOUR SYSTEM ADMINISTRATION UTILITIES GUIDE + +NVRAM and Time of Day can be saved between boots by attaching both +devices to files. + + sim> ATTACH NVRAM + sim> ATTACH TOD + +If you have no operating system installed on the hard drive, on +subsequent boots you will instead see the message + + SELF-CHECK + + + FW ERROR 1-02: DISK SANITY FAILURE + EXECUTION HALTED + + SYSTEM FAILURE: CONSULT YOUR SYSTEM ADMINISTRATION UTILITIES GUIDE + + +Once you see the `SYSTEM FAILURE` message, this is actually an +invisible prompt. To access firmware mode, type the default 3B2 +firmware password `mcp`, then press Enter or carriage return. + +You should then be prompted with: + + Enter name of program to execute [ ]: + +Here, you may type a question mark (?) and press Enter to see a list +of available firmware programs. + +Booting UNIX SVR3 on the 3B2/400 +-------------------------------- + +UNIX System V UNIX is the only operating system available for the 3B2. +To boot UNIX, attach the first disk image from the 3B2 "Essential +Utilities" distribution. + + sim> ATTACH IFLOPPY + sim> BOOT + +Once you reach the `SYSTEM FAILURE` message, type `mcp` to enter +firmware mode. When prompted for the name of a program to boot, enter +`unix`, and confirm the boot device is `FD5` by pressing Enter or +carriage return. + + Enter name of program to execute [ ]: unix + Possible load devices are: + + Option Number Slot Name + --------------------------------------- + 0 0 FD5 + + Enter Load Device Option Number [0 (FD5)]: + +Installing SVR3 on the 3B2/400 +------------------------------ + +To install SVR3 to the first hard disk, first, attach a new image +to the IDISK0 device: + + sim> ATTACH IDISK0 + +Then, boot the file `idtools` from the "3B2 Maintenance Utilities - +Issue 4.0" floppy diskette. + +From `idtools`, select the `formhard` option and low-level format +integrated disk 0. Parameters for the default 72MB hard disk are: + + Drive Id: 5 + Number cylinders: 925 + Number tracks/cyl: 9 + Number sectors/track: 18 + Number bytes/sector: 512 + +After low-level formatting integrated disk 0, boot the file `unix` +from the first diskette of the 3B2 "Essential Utilities" distribution, +and follow the prompts. + +More information about installing AT&T System V Release 3.2 UNIX is +available on the web: + + - https://loomcom.com/3b2/installing_unix.html diff --git a/3B2/rom_rev2.bin b/3B2/rom_rev2.bin deleted file mode 100644 index 6ebc5390606fbaa069b7fe7a657588a1f2d80ddb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32768 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 duDKuiHaJx5HU8T;avS~?_s}ukL diff --git a/3B2/rom_rev2_bin.h b/3B2/rom_rev2_bin.h deleted file mode 100644 index cb87901e..00000000 --- a/3B2/rom_rev2_bin.h +++ /dev/null @@ -1,2081 +0,0 @@ -#ifndef ROM_rom_rev2_bin_H -#define ROM_rom_rev2_bin_H 0 -/* - 3B2/rom_rev2_bin.h produced at Mon Aug 23 13:30:22 2021 - from 3B2/rom_rev2.bin which was last modified at Mon Jul 26 08:03:30 2021 - file size: 32768 (0x8000) - checksum: 0xFFD55762 - This file is a generated file and should NOT be edited or changed by hand. -*/ -#undef BOOT_CODE_SIZE -#define BOOT_CODE_SIZE 0x8000 -#undef BOOT_CODE_FILENAME -#define BOOT_CODE_FILENAME "rom_rev2.bin" -#undef BOOT_CODE_ARRAY -#define BOOT_CODE_ARRAY rom_rev2_bin -#if !defined(BOOT_CODE_SIZE_1) -#define BOOT_CODE_SIZE_1 0x8000 -#define BOOT_CODE_FILENAME_1 "rom_rev2.bin" -#define BOOT_CODE_ARRAY_1 rom_rev2_bin -#elif !defined(BOOT_CODE_SIZE_2) -#define BOOT_CODE_SIZE_2 0x8000 -#define BOOT_CODE_FILENAME_2 "rom_rev2.bin" -#define BOOT_CODE_ARRAY_2 rom_rev2_bin -#elif !defined(BOOT_CODE_SIZE_3) -#define BOOT_CODE_SIZE_3 0x8000 -#define BOOT_CODE_FILENAME_3 "rom_rev2.bin" -#define BOOT_CODE_ARRAY_3 rom_rev2_bin -#elif !defined(BOOT_CODE_SIZE_4) -#define BOOT_CODE_SIZE_4 0x8000 -#define BOOT_CODE_FILENAME_4 "rom_rev2.bin" -#define BOOT_CODE_ARRAY_4 rom_rev2_bin -#endif -unsigned char rom_rev2_bin[] = { -0x00,0x00,0x05,0x48,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0x00,0x00,0x05,0xD8,0x02,0x00,0x0B,0x78,0x02,0x00,0x0B,0x78,0x02,0x00,0x0B,0xC8, -0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8, -0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0C,0x18, -0x02,0x00,0x0C,0x68,0x02,0x00,0x0C,0xB8,0x02,0x00,0x0D,0x08,0x02,0x00,0x0D,0x58, -0x02,0x00,0x0D,0xA8,0x02,0x00,0x0D,0xA8,0x02,0x00,0x0E,0x48,0x02,0x00,0x0B,0xC8, -0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8, -0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8, -0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8, -0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8, -0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8, -0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8, -0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8, -0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8, -0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8, -0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8, -0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8, -0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8, -0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8, -0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8, -0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8, -0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8, -0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8, -0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8, -0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8, -0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8, -0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8, -0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8, -0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8, -0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8, -0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8, -0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8, -0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8, -0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8, -0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8, -0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8, -0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8, -0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8, -0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8, -0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8, -0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8, -0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8, -0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8, -0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8, -0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8, -0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8, -0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8, -0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8, -0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8, -0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8, -0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8, -0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8, -0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8, -0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8, -0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8, -0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8, -0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8, -0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8, -0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8, -0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8, -0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8, -0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8, -0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8, -0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8, -0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8, -0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x0B,0xC8,0x02,0x00,0x08,0x64, -0x02,0x00,0x15,0x14,0x02,0x00,0x11,0xF8,0x02,0x00,0x11,0xF4,0x02,0x00,0x08,0x58, -0x02,0x00,0x12,0x00,0x02,0x00,0x12,0xA8,0x02,0x00,0x12,0x6C,0x00,0x00,0x4D,0xD4, -0x00,0x00,0x44,0xE4,0x00,0x00,0x43,0x60,0x00,0x00,0x4A,0xE4,0x00,0x00,0x7F,0x68, -0x00,0x00,0x2A,0xF8,0x02,0x00,0x12,0x68,0x00,0x00,0x44,0x84,0x00,0x00,0x53,0x20, -0x00,0x00,0x52,0x24,0x00,0x00,0x52,0xA0,0x00,0x00,0x76,0x98,0x00,0x00,0x7B,0x2C, -0x02,0x00,0x11,0xF0,0x02,0x00,0x11,0xEC,0x02,0x00,0x15,0x04,0x00,0x00,0x11,0x68, -0x02,0x00,0x0A,0x80,0x02,0x00,0x12,0x58,0x02,0x00,0x12,0x5C,0x02,0x00,0x11,0xE8, -0x00,0x00,0x3D,0x74,0x02,0x00,0x12,0x64,0x00,0x00,0x7F,0xF0,0x02,0x00,0x12,0xD8, -0x02,0x00,0x12,0xD0,0x02,0x00,0x08,0x6C,0x00,0x00,0x54,0x38,0x00,0x00,0x54,0x50, -0x00,0x00,0x54,0xA1,0x00,0x00,0x4E,0x14,0x00,0x00,0x55,0x04,0x02,0x00,0x12,0xDC, -0x02,0x00,0x12,0xE0,0x02,0x00,0x12,0xE4,0x00,0x00,0x55,0xEC,0x00,0x00,0x5B,0xAA, -0x00,0x00,0x51,0xD2,0x02,0x00,0x0A,0x74,0x00,0x81,0xE1,0x00,0x00,0x00,0x42,0x1F, -0x00,0x81,0xE1,0x00,0x00,0x00,0x42,0x59,0x00,0x81,0xE1,0x00,0x00,0x00,0x42,0x1F, -0x00,0x81,0xE1,0x00,0x00,0x00,0x42,0x1F,0x00,0x81,0xE1,0x00,0x00,0x00,0x42,0x1F, -0x00,0x81,0xE1,0x00,0x00,0x00,0x42,0x1F,0x00,0x81,0xE1,0x00,0x00,0x00,0x42,0x1F, -0x00,0x81,0xE1,0x00,0x00,0x00,0x42,0x1F,0x00,0x81,0xE1,0x00,0x00,0x00,0x42,0x1F, -0x00,0x81,0xE1,0x00,0x00,0x00,0x42,0x1F,0x00,0x81,0xE1,0x00,0x00,0x00,0x42,0x1F, -0x00,0x81,0xE1,0x00,0x00,0x00,0x42,0x1F,0x00,0x81,0xE1,0x00,0x00,0x00,0x42,0x1F, -0x00,0x81,0xE1,0x00,0x00,0x00,0x42,0x1F,0x00,0x81,0xE1,0x00,0x00,0x00,0x42,0x59, -0x00,0x81,0xE1,0x00,0x00,0x00,0x42,0x1F,0x2F,0x66,0x69,0x6C,0x6C,0x65,0x64,0x74, -0x00,0x46,0x44,0x35,0x00,0x00,0x00,0x00,0x00,0x81,0xE1,0x80,0x00,0x00,0x12,0x74, -0x02,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x02,0x00,0x00,0x08,0x02,0x00,0x08,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x53,0x42,0x44,0x00,0x0A,0x45,0x6E,0x74, -0x65,0x72,0x20,0x6E,0x61,0x6D,0x65,0x20,0x6F,0x66,0x20,0x70,0x72,0x6F,0x67,0x72, -0x61,0x6D,0x20,0x74,0x6F,0x20,0x65,0x78,0x65,0x63,0x75,0x74,0x65,0x20,0x5B,0x20, -0x25,0x73,0x20,0x5D,0x3A,0x20,0x00,0x0A,0x00,0x70,0x61,0x73,0x73,0x77,0x64,0x00, -0x0A,0x65,0x6E,0x74,0x65,0x72,0x20,0x6F,0x6C,0x64,0x20,0x70,0x61,0x73,0x73,0x77, -0x6F,0x72,0x64,0x3A,0x20,0x00,0x0A,0x65,0x6E,0x74,0x65,0x72,0x20,0x6E,0x65,0x77, -0x20,0x70,0x61,0x73,0x73,0x77,0x6F,0x72,0x64,0x3A,0x20,0x00,0x0A,0x63,0x6F,0x6E, -0x66,0x69,0x72,0x6D,0x61,0x74,0x69,0x6F,0x6E,0x3A,0x20,0x00,0x0A,0x00,0x6E,0x65, -0x77,0x6B,0x65,0x79,0x00,0x0A,0x43,0x72,0x65,0x61,0x74,0x69,0x6E,0x67,0x20,0x61, -0x20,0x66,0x6C,0x6F,0x70,0x70,0x79,0x20,0x6B,0x65,0x79,0x20,0x74,0x6F,0x20,0x65, -0x6E,0x61,0x62,0x6C,0x65,0x20,0x63,0x6C,0x65,0x61,0x72,0x69,0x6E,0x67,0x20,0x6F, -0x66,0x20,0x73,0x61,0x76,0x65,0x64,0x20,0x4E,0x56,0x52,0x41,0x4D,0x20,0x69,0x6E, -0x66,0x6F,0x72,0x6D,0x61,0x74,0x69,0x6F,0x6E,0x0A,0x0A,0x00,0x67,0x6F,0x00,0x49, -0x6E,0x73,0x65,0x72,0x74,0x20,0x61,0x20,0x66,0x6F,0x72,0x6D,0x61,0x74,0x74,0x65, -0x64,0x20,0x66,0x6C,0x6F,0x70,0x70,0x79,0x2C,0x20,0x74,0x68,0x65,0x6E,0x20,0x74, -0x79,0x70,0x65,0x20,0x27,0x67,0x6F,0x27,0x20,0x28,0x71,0x20,0x74,0x6F,0x20,0x71, -0x75,0x69,0x74,0x29,0x3A,0x20,0x00,0x0A,0x43,0x72,0x65,0x61,0x74,0x69,0x6F,0x6E, -0x20,0x6F,0x66,0x20,0x66,0x6C,0x6F,0x70,0x70,0x79,0x20,0x6B,0x65,0x79,0x20,0x63, -0x6F,0x6D,0x70,0x6C,0x65,0x74,0x65,0x0A,0x0A,0x00,0x73,0x79,0x73,0x64,0x75,0x6D, -0x70,0x00,0x76,0x65,0x72,0x73,0x69,0x6F,0x6E,0x00,0x0A,0x43,0x72,0x65,0x61,0x74, -0x65,0x64,0x3A,0x20,0x25,0x73,0x0A,0x00,0x49,0x73,0x73,0x75,0x65,0x3A,0x20,0x25, -0x30,0x38,0x6C,0x78,0x0A,0x00,0x52,0x65,0x6C,0x65,0x61,0x73,0x65,0x3A,0x20,0x25, -0x73,0x0A,0x4C,0x6F,0x61,0x64,0x3A,0x20,0x25,0x73,0x0A,0x00,0x53,0x65,0x72,0x69, -0x61,0x6C,0x20,0x4E,0x75,0x6D,0x62,0x65,0x72,0x3A,0x20,0x25,0x30,0x38,0x6C,0x78, -0x0A,0x0A,0x00,0x71,0x00,0x65,0x64,0x74,0x00,0x65,0x72,0x72,0x6F,0x72,0x20,0x69, -0x6E,0x66,0x6F,0x00,0x62,0x61,0x75,0x64,0x00,0x3F,0x00,0x0A,0x45,0x6E,0x74,0x65, -0x72,0x20,0x61,0x6E,0x20,0x65,0x78,0x65,0x63,0x75,0x74,0x61,0x62,0x6C,0x65,0x20, -0x6F,0x72,0x20,0x73,0x79,0x73,0x74,0x65,0x6D,0x20,0x66,0x69,0x6C,0x65,0x2C,0x20, -0x61,0x20,0x64,0x69,0x72,0x65,0x63,0x74,0x6F,0x72,0x79,0x20,0x6E,0x61,0x6D,0x65, -0x2C,0x0A,0x00,0x6F,0x72,0x20,0x6F,0x6E,0x65,0x20,0x6F,0x66,0x20,0x74,0x68,0x65, -0x20,0x70,0x6F,0x73,0x73,0x69,0x62,0x6C,0x65,0x20,0x66,0x69,0x72,0x6D,0x77,0x61, -0x72,0x65,0x20,0x70,0x72,0x6F,0x67,0x72,0x61,0x6D,0x20,0x6E,0x61,0x6D,0x65,0x73, -0x3A,0x0A,0x0A,0x00,0x62,0x61,0x75,0x64,0x20,0x20,0x20,0x20,0x65,0x64,0x74,0x20, -0x20,0x20,0x20,0x6E,0x65,0x77,0x6B,0x65,0x79,0x20,0x20,0x20,0x20,0x70,0x61,0x73, -0x73,0x77,0x64,0x20,0x20,0x20,0x20,0x73,0x79,0x73,0x64,0x75,0x6D,0x70,0x20,0x20, -0x20,0x20,0x76,0x65,0x72,0x73,0x69,0x6F,0x6E,0x20,0x20,0x20,0x20,0x71,0x28,0x75, -0x69,0x74,0x29,0x0A,0x0A,0x00,0x2A,0x56,0x4F,0x49,0x44,0x2A,0x00,0x09,0x50,0x6F, -0x73,0x73,0x69,0x62,0x6C,0x65,0x20,0x6C,0x6F,0x61,0x64,0x20,0x64,0x65,0x76,0x69, -0x63,0x65,0x73,0x20,0x61,0x72,0x65,0x3A,0x0A,0x0A,0x00,0x4F,0x70,0x74,0x69,0x6F, -0x6E,0x20,0x4E,0x75,0x6D,0x62,0x65,0x72,0x20,0x20,0x20,0x20,0x53,0x6C,0x6F,0x74, -0x20,0x20,0x20,0x20,0x20,0x4E,0x61,0x6D,0x65,0x0A,0x00,0x2D,0x2D,0x2D,0x2D,0x2D, -0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D, -0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D, -0x2D,0x2D,0x0A,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x25,0x32,0x64,0x20,0x20,0x20, -0x20,0x20,0x20,0x20,0x20,0x20,0x25,0x32,0x64,0x00,0x2A,0x56,0x4F,0x49,0x44,0x2A, -0x00,0x20,0x20,0x20,0x20,0x20,0x25,0x31,0x30,0x73,0x00,0x0A,0x00,0x0A,0x45,0x6E, -0x74,0x65,0x72,0x20,0x4C,0x6F,0x61,0x64,0x20,0x44,0x65,0x76,0x69,0x63,0x65,0x20, -0x4F,0x70,0x74,0x69,0x6F,0x6E,0x20,0x4E,0x75,0x6D,0x62,0x65,0x72,0x20,0x00,0x5B, -0x25,0x64,0x00,0x2A,0x56,0x4F,0x49,0x44,0x2A,0x00,0x20,0x28,0x25,0x73,0x29,0x00, -0x5D,0x3A,0x20,0x00,0x0A,0x00,0x0A,0x25,0x73,0x20,0x69,0x73,0x20,0x6E,0x6F,0x74, -0x20,0x61,0x20,0x76,0x61,0x6C,0x69,0x64,0x20,0x6F,0x70,0x74,0x69,0x6F,0x6E,0x20, -0x6E,0x75,0x6D,0x62,0x65,0x72,0x2E,0x0A,0x00,0x50,0x6F,0x73,0x73,0x69,0x62,0x6C, -0x65,0x20,0x73,0x75,0x62,0x64,0x65,0x76,0x69,0x63,0x65,0x73,0x20,0x61,0x72,0x65, -0x3A,0x0A,0x0A,0x00,0x4F,0x70,0x74,0x69,0x6F,0x6E,0x20,0x4E,0x75,0x6D,0x62,0x65, -0x72,0x20,0x20,0x20,0x53,0x75,0x62,0x64,0x65,0x76,0x69,0x63,0x65,0x20,0x20,0x20, -0x20,0x4E,0x61,0x6D,0x65,0x0A,0x00,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D, -0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D, -0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D, -0x2D,0x2D,0x2D,0x0A,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x25,0x32,0x64,0x20,0x20, -0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x25,0x32,0x64,0x00,0x2A,0x56,0x4F,0x49, -0x44,0x2A,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x25,0x31,0x30,0x73, -0x00,0x0A,0x00,0x0A,0x45,0x6E,0x74,0x65,0x72,0x20,0x53,0x75,0x62,0x64,0x65,0x76, -0x69,0x63,0x65,0x20,0x4F,0x70,0x74,0x69,0x6F,0x6E,0x20,0x4E,0x75,0x6D,0x62,0x65, -0x72,0x20,0x00,0x5B,0x25,0x64,0x00,0x2A,0x56,0x4F,0x49,0x44,0x2A,0x00,0x28,0x25, -0x73,0x29,0x00,0x5D,0x3A,0x20,0x00,0x0A,0x00,0x0A,0x25,0x73,0x20,0x69,0x73,0x20, -0x6E,0x6F,0x74,0x20,0x61,0x20,0x76,0x61,0x6C,0x69,0x64,0x20,0x6F,0x70,0x74,0x69, -0x6F,0x6E,0x20,0x6E,0x75,0x6D,0x62,0x65,0x72,0x2E,0x0A,0x00,0x0A,0x53,0x4F,0x52, -0x52,0x59,0x21,0x0A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x32,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x4B,0x02,0x00,0x80,0x00,0x00,0x00, -0x00,0x6E,0x03,0x11,0x00,0x00,0x00,0x00,0x00,0x86,0x04,0x22,0x00,0x00,0x00,0x00, -0x00,0x96,0x05,0x33,0x80,0x00,0x00,0x00,0x00,0xC8,0x06,0x33,0x00,0x00,0x00,0x00, -0x01,0x2C,0x07,0x44,0x00,0x00,0x00,0x00,0x02,0x58,0x08,0x55,0x00,0x00,0x00,0x00, -0x04,0xB0,0x09,0x66,0x00,0x00,0x00,0x00,0x07,0x08,0x0A,0xAA,0x80,0x00,0x00,0x00, -0x09,0x60,0x0B,0x88,0x00,0x00,0x00,0x00,0x12,0xC0,0x0C,0x99,0x00,0x00,0x00,0x00, -0x25,0x80,0x0D,0xBB,0x00,0x00,0x00,0x00,0x4B,0x00,0x0E,0xCC,0x80,0x00,0x00,0x00, -0x96,0x00,0x0F,0xCC,0x00,0x00,0x00,0x00,0x55,0x6E,0x73,0x75,0x70,0x70,0x6F,0x72, -0x74,0x65,0x64,0x20,0x42,0x61,0x75,0x64,0x20,0x52,0x61,0x74,0x65,0x3A,0x20,0x25, -0x64,0x0A,0x00,0x45,0x6E,0x74,0x65,0x72,0x20,0x6E,0x65,0x77,0x20,0x72,0x61,0x74, -0x65,0x20,0x5B,0x25,0x64,0x5D,0x3A,0x20,0x00,0x25,0x64,0x00,0x43,0x68,0x61,0x6E, -0x67,0x65,0x20,0x62,0x61,0x75,0x64,0x20,0x72,0x61,0x74,0x65,0x20,0x74,0x6F,0x20, -0x25,0x64,0x0A,0x00,0x20,0x08,0x00,0x0A,0x6D,0x61,0x78,0x20,0x69,0x6E,0x70,0x75, -0x74,0x20,0x6F,0x66,0x20,0x25,0x64,0x20,0x63,0x68,0x61,0x72,0x61,0x63,0x74,0x65, -0x72,0x73,0x2C,0x20,0x72,0x65,0x2D,0x65,0x6E,0x74,0x65,0x72,0x20,0x65,0x6E,0x74, -0x69,0x72,0x65,0x20,0x6C,0x69,0x6E,0x65,0x0A,0x00,0x00,0x00,0x30,0x31,0x32,0x33, -0x34,0x35,0x36,0x37,0x38,0x39,0x61,0x62,0x63,0x64,0x65,0x66,0x00,0x00,0x00,0x00, -0x28,0x6E,0x75,0x6C,0x6C,0x20,0x70,0x6F,0x69,0x6E,0x74,0x65,0x72,0x29,0x00,0x00, -0x0A,0x0A,0x43,0x75,0x72,0x72,0x65,0x6E,0x74,0x20,0x53,0x79,0x73,0x74,0x65,0x6D, -0x20,0x43,0x6F,0x6E,0x66,0x69,0x67,0x75,0x72,0x61,0x74,0x69,0x6F,0x6E,0x0A,0x0A, -0x00,0x53,0x79,0x73,0x74,0x65,0x6D,0x20,0x42,0x6F,0x61,0x72,0x64,0x20,0x6D,0x65, -0x6D,0x6F,0x72,0x79,0x20,0x73,0x69,0x7A,0x65,0x3A,0x20,0x00,0x25,0x64,0x20,0x6D, -0x65,0x67,0x61,0x62,0x79,0x74,0x65,0x28,0x73,0x29,0x00,0x25,0x64,0x20,0x6B,0x69, -0x6C,0x6F,0x62,0x79,0x74,0x65,0x73,0x00,0x0A,0x0A,0x25,0x30,0x32,0x64,0x20,0x2D, -0x20,0x64,0x65,0x76,0x69,0x63,0x65,0x20,0x6E,0x61,0x6D,0x65,0x20,0x3D,0x20,0x25, -0x2D,0x39,0x73,0x2C,0x20,0x00,0x6F,0x63,0x63,0x75,0x72,0x72,0x65,0x6E,0x63,0x65, -0x20,0x3D,0x20,0x25,0x32,0x64,0x2C,0x20,0x73,0x6C,0x6F,0x74,0x20,0x3D,0x20,0x25, -0x30,0x32,0x64,0x2C,0x20,0x49,0x44,0x20,0x63,0x6F,0x64,0x65,0x20,0x3D,0x20,0x30, -0x78,0x25,0x30,0x32,0x78,0x0A,0x00,0x20,0x20,0x20,0x20,0x20,0x62,0x6F,0x6F,0x74, -0x20,0x64,0x65,0x76,0x69,0x63,0x65,0x20,0x3D,0x20,0x25,0x63,0x2C,0x20,0x62,0x6F, -0x61,0x72,0x64,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x3D,0x20,0x25,0x73,0x2C,0x20, -0x77,0x6F,0x72,0x64,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x3D,0x20,0x25,0x64,0x20, -0x62,0x79,0x74,0x65,0x28,0x73,0x29,0x2C,0x0A,0x00,0x64,0x6F,0x75,0x62,0x6C,0x65, -0x00,0x73,0x69,0x6E,0x67,0x6C,0x65,0x00,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x71, -0x20,0x51,0x20,0x73,0x69,0x7A,0x65,0x20,0x3D,0x20,0x30,0x78,0x25,0x30,0x32,0x78, -0x2C,0x20,0x63,0x6F,0x6D,0x70,0x20,0x51,0x20,0x73,0x69,0x7A,0x65,0x20,0x3D,0x20, -0x30,0x78,0x25,0x30,0x32,0x78,0x2C,0x20,0x00,0x63,0x6F,0x6E,0x73,0x6F,0x6C,0x65, -0x20,0x61,0x62,0x69,0x6C,0x69,0x74,0x79,0x20,0x3D,0x20,0x25,0x63,0x00,0x2C,0x20, -0x70,0x75,0x6D,0x70,0x20,0x66,0x69,0x6C,0x65,0x20,0x3D,0x20,0x25,0x63,0x00,0x20, -0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x0A, -0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x62,0x64,0x65,0x76,0x69,0x63,0x65,0x28,0x73, -0x29,0x00,0x25,0x73,0x23,0x25,0x30,0x32,0x64,0x20,0x3D,0x20,0x25,0x2D,0x39,0x73, -0x2C,0x20,0x49,0x44,0x20,0x63,0x6F,0x64,0x65,0x20,0x3D,0x20,0x30,0x78,0x25,0x30, -0x32,0x78,0x00,0x0A,0x20,0x20,0x20,0x20,0x20,0x00,0x2C,0x20,0x00,0x0A,0x0A,0x50, -0x72,0x65,0x73,0x73,0x20,0x61,0x6E,0x79,0x20,0x6B,0x65,0x79,0x20,0x74,0x6F,0x20, -0x63,0x6F,0x6E,0x74,0x69,0x6E,0x75,0x65,0x0A,0x00,0x0A,0x44,0x4F,0x4E,0x45,0x0A, -0x0A,0x00,0x00,0x00,0x50,0x45,0x52,0x49,0x50,0x48,0x45,0x52,0x41,0x4C,0x20,0x49, -0x2F,0x4F,0x20,0x25,0x73,0x20,0x45,0x52,0x52,0x4F,0x52,0x20,0x41,0x54,0x20,0x42, -0x4C,0x4F,0x43,0x4B,0x20,0x25,0x64,0x2C,0x20,0x53,0x55,0x42,0x44,0x45,0x56,0x49, -0x43,0x45,0x20,0x25,0x64,0x2C,0x20,0x53,0x4C,0x4F,0x54,0x20,0x25,0x64,0x0A,0x00, -0x52,0x45,0x41,0x44,0x00,0x57,0x52,0x49,0x54,0x45,0x00,0x00,0x0A,0x46,0x57,0x20, -0x45,0x52,0x52,0x4F,0x52,0x20,0x31,0x2D,0x25,0x73,0x0A,0x00,0x20,0x20,0x20,0x20, -0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x45,0x58,0x45,0x43,0x55, -0x54,0x49,0x4F,0x4E,0x20,0x48,0x41,0x4C,0x54,0x45,0x44,0x0A,0x00,0x00,0x00,0x00, -0x30,0x31,0x3A,0x20,0x4E,0x56,0x52,0x41,0x4D,0x20,0x53,0x41,0x4E,0x49,0x54,0x59, -0x20,0x46,0x41,0x49,0x4C,0x55,0x52,0x45,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20, -0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x45,0x46,0x41,0x55,0x4C,0x54,0x20, -0x56,0x41,0x4C,0x55,0x45,0x53,0x20,0x41,0x53,0x53,0x55,0x4D,0x45,0x44,0x0A,0x20, -0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x49,0x46, -0x20,0x52,0x45,0x50,0x45,0x41,0x54,0x45,0x44,0x2C,0x20,0x43,0x48,0x45,0x43,0x4B, -0x20,0x54,0x48,0x45,0x20,0x42,0x41,0x54,0x54,0x45,0x52,0x59,0x0A,0x00,0x0A,0x46, -0x57,0x20,0x57,0x41,0x52,0x4E,0x49,0x4E,0x47,0x3A,0x20,0x4E,0x56,0x52,0x41,0x4D, -0x20,0x44,0x45,0x46,0x41,0x55,0x4C,0x54,0x20,0x56,0x41,0x4C,0x55,0x45,0x53,0x20, -0x41,0x53,0x53,0x55,0x4D,0x45,0x44,0x0A,0x0A,0x00,0x30,0x32,0x3A,0x20,0x44,0x49, -0x53,0x4B,0x20,0x53,0x41,0x4E,0x49,0x54,0x59,0x20,0x46,0x41,0x49,0x4C,0x55,0x52, -0x45,0x00,0x30,0x35,0x3A,0x20,0x53,0x45,0x4C,0x46,0x2D,0x43,0x4F,0x4E,0x46,0x49, -0x47,0x55,0x52,0x41,0x54,0x49,0x4F,0x4E,0x20,0x46,0x41,0x49,0x4C,0x55,0x52,0x45, -0x00,0x30,0x36,0x3A,0x20,0x42,0x4F,0x4F,0x54,0x20,0x46,0x41,0x49,0x4C,0x55,0x52, -0x45,0x00,0x30,0x37,0x3A,0x20,0x46,0x4C,0x4F,0x50,0x50,0x59,0x20,0x4B,0x45,0x59, -0x20,0x43,0x52,0x45,0x41,0x54,0x45,0x20,0x46,0x41,0x49,0x4C,0x55,0x52,0x45,0x00, -0x30,0x38,0x3A,0x20,0x4D,0x45,0x4D,0x4F,0x52,0x59,0x20,0x54,0x45,0x53,0x54,0x20, -0x46,0x41,0x49,0x4C,0x55,0x52,0x45,0x00,0x30,0x39,0x3A,0x20,0x44,0x49,0x53,0x4B, -0x20,0x46,0x4F,0x52,0x4D,0x41,0x54,0x20,0x4E,0x4F,0x54,0x20,0x43,0x4F,0x4D,0x50, -0x41,0x54,0x49,0x42,0x4C,0x45,0x20,0x57,0x49,0x54,0x48,0x20,0x53,0x59,0x53,0x54, -0x45,0x4D,0x00,0x25,0x73,0x00,0x0A,0x0A,0x53,0x45,0x4C,0x46,0x2D,0x43,0x48,0x45, -0x43,0x4B,0x0A,0x00,0x0A,0x4E,0x4F,0x4E,0x45,0x0A,0x0A,0x00,0x0A,0x45,0x58,0x43, -0x45,0x50,0x54,0x49,0x4F,0x4E,0x2C,0x20,0x50,0x43,0x20,0x3D,0x20,0x30,0x78,0x25, -0x30,0x38,0x78,0x2C,0x20,0x50,0x53,0x57,0x20,0x3D,0x20,0x30,0x78,0x25,0x30,0x38, -0x78,0x2C,0x20,0x43,0x53,0x52,0x20,0x3D,0x20,0x30,0x78,0x25,0x30,0x34,0x78,0x0A, -0x0A,0x00,0x0A,0x49,0x4E,0x54,0x45,0x52,0x52,0x55,0x50,0x54,0x2C,0x20,0x50,0x43, -0x20,0x3D,0x20,0x30,0x78,0x25,0x30,0x38,0x78,0x2C,0x20,0x50,0x53,0x57,0x20,0x3D, -0x20,0x30,0x78,0x25,0x30,0x38,0x78,0x2C,0x20,0x43,0x53,0x52,0x20,0x3D,0x20,0x30, -0x78,0x25,0x30,0x34,0x78,0x2C,0x20,0x4C,0x56,0x4C,0x20,0x3D,0x20,0x25,0x64,0x0A, -0x0A,0x00,0x0A,0x53,0x41,0x4E,0x49,0x54,0x59,0x20,0x4F,0x4E,0x20,0x44,0x49,0x53, -0x4B,0x20,0x25,0x64,0x2C,0x20,0x45,0x52,0x52,0x4F,0x52,0x20,0x25,0x64,0x0A,0x00, -0x43,0x4F,0x4D,0x4D,0x41,0x4E,0x44,0x20,0x3D,0x20,0x30,0x78,0x25,0x30,0x32,0x78, -0x2C,0x20,0x55,0x4E,0x49,0x54,0x20,0x53,0x54,0x41,0x54,0x55,0x53,0x20,0x3D,0x20, -0x30,0x78,0x25,0x30,0x32,0x78,0x2C,0x20,0x45,0x52,0x52,0x4F,0x52,0x20,0x53,0x54, -0x41,0x54,0x55,0x53,0x20,0x3D,0x20,0x30,0x78,0x25,0x30,0x32,0x78,0x2C,0x20,0x53, -0x54,0x41,0x54,0x55,0x53,0x20,0x3D,0x20,0x30,0x78,0x25,0x30,0x32,0x78,0x00,0x0A, -0x0A,0x00,0x0A,0x4E,0x4F,0x4E,0x45,0x0A,0x0A,0x00,0x00,0x00,0x30,0x34,0x3A,0x20, -0x55,0x4E,0x45,0x58,0x50,0x45,0x43,0x54,0x45,0x44,0x20,0x49,0x4E,0x54,0x45,0x52, -0x52,0x55,0x50,0x54,0x0A,0x00,0x00,0x00,0x30,0x33,0x3A,0x20,0x55,0x4E,0x45,0x58, -0x50,0x45,0x43,0x54,0x45,0x44,0x20,0x46,0x41,0x55,0x4C,0x54,0x0A,0x00,0x00,0x00, -0x6D,0x63,0x70,0x00,0x2F,0x66,0x69,0x6C,0x6C,0x65,0x64,0x74,0x00,0x0A,0x53,0x59, -0x53,0x54,0x45,0x4D,0x20,0x46,0x41,0x49,0x4C,0x55,0x52,0x45,0x3A,0x20,0x43,0x4F, -0x4E,0x53,0x55,0x4C,0x54,0x20,0x59,0x4F,0x55,0x52,0x20,0x53,0x59,0x53,0x54,0x45, -0x4D,0x20,0x41,0x44,0x4D,0x49,0x4E,0x49,0x53,0x54,0x52,0x41,0x54,0x49,0x4F,0x4E, -0x20,0x55,0x54,0x49,0x4C,0x49,0x54,0x49,0x45,0x53,0x20,0x47,0x55,0x49,0x44,0x45, -0x0A,0x0A,0x00,0x0A,0x46,0x49,0x52,0x4D,0x57,0x41,0x52,0x45,0x20,0x4D,0x4F,0x44, -0x45,0x0A,0x0A,0x00,0x2F,0x66,0x69,0x6C,0x6C,0x65,0x64,0x74,0x00,0x2F,0x64,0x67, -0x6D,0x6F,0x6E,0x00,0x2F,0x75,0x6E,0x69,0x78,0x00,0x00,0x00,0x30,0x34,0x3A,0x20, -0x55,0x4E,0x45,0x58,0x50,0x45,0x43,0x54,0x45,0x44,0x20,0x49,0x4E,0x54,0x45,0x52, -0x52,0x55,0x50,0x54,0x00,0x30,0x33,0x3A,0x20,0x55,0x4E,0x45,0x58,0x50,0x45,0x43, -0x54,0x45,0x44,0x20,0x46,0x41,0x55,0x4C,0x54,0x00,0x00,0x00,0x18,0xF2,0x00,0x03, -0x11,0x0D,0x00,0x80,0x69,0x64,0x25,0x64,0x20,0x43,0x52,0x43,0x20,0x65,0x72,0x72, -0x6F,0x72,0x20,0x61,0x74,0x20,0x64,0x69,0x73,0x6B,0x20,0x61,0x64,0x64,0x72,0x65, -0x73,0x73,0x20,0x25,0x30,0x38,0x78,0x20,0x28,0x25,0x64,0x20,0x72,0x65,0x74,0x72, -0x69,0x65,0x73,0x29,0x0A,0x00,0x00,0x00,0x69,0x66,0x20,0x43,0x52,0x43,0x20,0x65, -0x72,0x72,0x6F,0x72,0x20,0x61,0x74,0x20,0x64,0x69,0x73,0x6B,0x20,0x61,0x64,0x64, -0x72,0x65,0x73,0x73,0x20,0x25,0x30,0x38,0x78,0x20,0x28,0x25,0x64,0x20,0x72,0x65, -0x74,0x72,0x69,0x65,0x73,0x29,0x0A,0x00,0x30,0x35,0x2F,0x33,0x31,0x2F,0x38,0x35, -0x00,0x00,0x00,0x00,0x50,0x46,0x33,0x00,0x31,0x2E,0x32,0x2E,0x31,0x00,0x00,0x00, -0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x20, -0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, -0x20,0x48,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10, -0x10,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x10,0x10,0x10,0x10,0x10, -0x10,0x10,0x81,0x81,0x81,0x81,0x81,0x81,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, -0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x10,0x10,0x10,0x10, -0x10,0x10,0x82,0x82,0x82,0x82,0x82,0x82,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02, -0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x10,0x10,0x10,0x10, -0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x04,0x7F,0x08,0x00,0x00,0x02,0x4C,0x04,0x7F,0x08,0x00,0x00, -0x02,0x49,0x04,0x7F,0x08,0x00,0x00,0x02,0x4A,0x04,0x7F,0x08,0x08,0x00,0x02,0x4E, -0x87,0x16,0x7F,0x0F,0x20,0x04,0x00,0x70,0x87,0x6F,0x64,0x7F,0x03,0x20,0x04,0x00, -0x70,0x87,0x5F,0x94,0x00,0x7F,0x0F,0x20,0x04,0x00,0x70,0x87,0x0A,0x7F,0x0B,0x20, -0x04,0x00,0x70,0x87,0x6F,0x74,0x7F,0x0F,0x20,0x04,0x00,0x70,0x24,0x7F,0xD5,0x12, -0x00,0x00,0x70,0x70,0x10,0x43,0x9C,0x4F,0x08,0x00,0x00,0x00,0x4C,0x87,0x01,0x7F, -0x1B,0x40,0x04,0x00,0x70,0x70,0x84,0x4B,0x40,0xB8,0x4F,0xFF,0xFF,0xC3,0xFF,0x40, -0x84,0x40,0x4B,0x77,0x05,0x7A,0x3E,0x06,0x47,0x05,0x7A,0x39,0x06,0x43,0x05,0x7A, -0x34,0x06,0x57,0x05,0x7A,0x2F,0x06,0x53,0x05,0x7A,0x2A,0x06,0x53,0x05,0x7A,0x25, -0x06,0x63,0x05,0x7A,0x20,0x06,0x70,0x84,0x4B,0x40,0xB0,0x4F,0x00,0x00,0x3C,0x00, -0x40,0x84,0x40,0x4B,0x7F,0x05,0x7A,0x0D,0x06,0x4F,0x05,0x7A,0x08,0x06,0x43,0x05, -0x7A,0x03,0x06,0x5F,0x05,0x7A,0xFE,0x05,0x5B,0x05,0x7A,0xF9,0x05,0x5B,0x05,0x7A, -0xF4,0x05,0x6B,0x05,0x7A,0xEF,0x05,0x70,0x84,0x4B,0x40,0xB8,0x4F,0xFF,0xFF,0xC3, -0xFF,0x40,0xB0,0x4F,0x00,0x00,0x10,0x00,0x40,0x84,0x40,0x4B,0x43,0x05,0x7A,0xD5, -0x05,0x70,0x84,0x4B,0x40,0xB8,0x4F,0xFF,0xFF,0xC3,0xFF,0x40,0xB0,0x4F,0x00,0x00, -0x04,0x00,0x40,0x84,0x40,0x4B,0x5E,0x06,0x00,0x7A,0xBA,0x05,0x70,0x84,0x4B,0x40, -0xB8,0x4F,0xFF,0xFF,0xC3,0xFF,0x40,0xB0,0x4F,0x00,0x00,0x20,0x00,0x40,0x84,0x40, -0x4B,0x4B,0x05,0x7A,0xA0,0x05,0x84,0xFF,0x40,0x84,0x40,0x41,0x84,0x41,0x42,0x84, -0x42,0x43,0x84,0x43,0x44,0x84,0x44,0x45,0x84,0x45,0x46,0x84,0x46,0x47,0x84,0x47, -0x48,0x3C,0x40,0x48,0x76,0x7F,0x05,0xD0,0x01,0x40,0x40,0x43,0x04,0x7B,0xDC,0x84, -0xFE,0x40,0x88,0x40,0x41,0x88,0x41,0x42,0x88,0x42,0x43,0x88,0x43,0x44,0x88,0x44, -0x45,0x88,0x45,0x46,0x88,0x46,0x47,0x88,0x47,0x48,0x88,0x40,0x48,0x88,0x41,0x47, -0x88,0x42,0x46,0x88,0x43,0x45,0x88,0x48,0x41,0x88,0x47,0x42,0x88,0x46,0x43,0x88, -0x44,0x40,0x88,0x41,0x44,0x3C,0x40,0x48,0x76,0x3B,0x05,0xD0,0x01,0x40,0x40,0x4B, -0x07,0x88,0x40,0x40,0x7B,0xBE,0x84,0x49,0x41,0x84,0x4A,0x42,0x84,0x4C,0x43,0x84, -0x4D,0x44,0x84,0x4E,0x45,0x84,0xFF,0x40,0x84,0x40,0x49,0x84,0x49,0x4A,0x84,0x4A, -0x4C,0x84,0x4C,0x4D,0x84,0x4D,0x4E,0x3C,0x49,0x4E,0x76,0x4C,0x00,0xD0,0x01,0x40, -0x40,0x43,0x04,0x7B,0xE5,0x84,0x01,0x40,0x88,0x40,0x49,0x88,0x49,0x4A,0x88,0x4A, -0x4C,0x88,0x4C,0x4D,0x88,0x4D,0x4E,0x88,0x49,0x4E,0x88,0x4A,0x4D,0x88,0x4C,0x49, -0x88,0x4E,0x4A,0x88,0x4D,0x4C,0x3C,0x49,0x4E,0x76,0x1D,0x00,0xD0,0x01,0x40,0x40, -0x4B,0x04,0x7B,0xD6,0x84,0x41,0x49,0x84,0x42,0x4A,0x84,0x43,0x4C,0x84,0x44,0x4D, -0x84,0x45,0x4E,0x7A,0x15,0x00,0x84,0x41,0x49,0x84,0x42,0x4A,0x84,0x43,0x4C,0x84, -0x44,0x4D,0x84,0x45,0x4E,0x7A,0xAE,0x04,0x82,0x48,0x84,0x5F,0xEE,0x7F,0x45,0x80, -0x47,0x7B,0x3F,0x86,0xE2,0x48,0xE0,0x40,0x87,0x57,0xE2,0x41,0xBA,0x5F,0xFF,0x00, -0x41,0x86,0xE2,0x41,0xE0,0x41,0x9C,0x41,0x40,0x86,0x40,0x48,0x86,0xE2,0x48,0xE0, -0x40,0xD0,0x01,0x40,0x40,0x86,0xE2,0x40,0xE0,0x40,0x86,0xE2,0x48,0xE0,0x41,0xD4, -0x0F,0x41,0x41,0x86,0xE2,0x41,0xE0,0x41,0xB0,0x41,0x40,0x86,0x40,0x48,0x90,0x47, -0x3C,0x45,0x47,0x5B,0xC0,0x86,0xE2,0x48,0xE0,0x40,0x88,0x40,0x40,0x86,0x40,0x48, -0x86,0xE2,0x48,0xE0,0x40,0x87,0x57,0xE0,0x41,0x87,0xC7,0x01,0xE0,0x42,0xD0,0x08, -0x42,0x42,0xB0,0x42,0x41,0x3C,0x41,0x40,0x77,0x08,0x24,0x7F,0x6E,0x15,0x00,0x00, -0x86,0xE2,0x48,0xE0,0x40,0x88,0x40,0x40,0x86,0x40,0x48,0x9C,0x4F,0x00,0x80,0x00, -0x00,0x45,0x7B,0x3F,0x86,0xE2,0x48,0xE0,0x40,0x87,0x57,0xE2,0x41,0xBA,0x5F,0xFF, -0x00,0x41,0x86,0xE2,0x41,0xE0,0x41,0x9C,0x41,0x40,0x86,0x40,0x48,0x86,0xE2,0x48, -0xE0,0x40,0xD0,0x01,0x40,0x40,0x86,0xE2,0x40,0xE0,0x40,0x86,0xE2,0x48,0xE0,0x41, -0xD4,0x0F,0x41,0x41,0x86,0xE2,0x41,0xE0,0x41,0xB0,0x41,0x40,0x86,0x40,0x48,0x90, -0x47,0x3C,0x45,0x47,0x5B,0xC0,0x86,0xE2,0x48,0xE0,0x40,0x88,0x40,0x40,0x86,0x40, -0x48,0x86,0xE2,0x48,0xE0,0x40,0x87,0x57,0xE0,0x41,0x87,0xC7,0x01,0xE0,0x42,0xD0, -0x08,0x42,0x42,0xB0,0x42,0x41,0x3C,0x41,0x40,0x7F,0x05,0x7A,0xC1,0x03,0x3C,0x4F, -0xED,0x0D,0x1C,0xA1,0x7F,0x64,0x08,0x00,0x02,0x7F,0x15,0x3C,0x4F,0x0D,0xF0,0xAD, -0x8B,0x7F,0x64,0x08,0x00,0x02,0x7F,0x08,0x24,0x7F,0xBC,0x16,0x00,0x00,0x2C,0x5C, -0x7F,0x90,0x3B,0x00,0x00,0xDC,0x01,0x7F,0xA0,0x04,0x00,0x00,0x40,0x3F,0x02,0x50, -0x77,0x07,0x84,0x01,0x40,0x7B,0x04,0x80,0x40,0xA0,0x40,0x2C,0xCC,0xFC,0x7F,0x2C, -0x73,0x00,0x00,0xA0,0x00,0x2C,0xCC,0xFC,0x7F,0x8C,0x79,0x00,0x00,0x87,0x7F,0x00, -0xD0,0x04,0x00,0xE0,0x45,0x87,0x01,0x7F,0x1F,0x40,0x04,0x00,0x70,0x87,0x10,0x7F, -0x0F,0x90,0x04,0x00,0x70,0x87,0x20,0x7F,0x0F,0x90,0x04,0x00,0x70,0x87,0x01,0x7F, -0x68,0x08,0x00,0x02,0x70,0xDC,0x02,0x7F,0xA4,0x04,0x00,0x00,0x40,0x2B,0x50,0x7F, -0x10,0x2C,0x5C,0x7F,0x72,0x5F,0x00,0x00,0x2C,0x5C,0x7F,0x78,0x63,0x00,0x00,0xDC, -0x04,0x7F,0xA4,0x04,0x00,0x00,0x40,0x3F,0x01,0x50,0x77,0x08,0x24,0x7F,0xA0,0x16, -0x00,0x00,0x2C,0x5C,0x7F,0x72,0x5F,0x00,0x00,0xA0,0x4F,0x0C,0x30,0x04,0x00,0xDC, -0x01,0x7F,0xA0,0x04,0x00,0x00,0x40,0xA0,0x40,0xA0,0x01,0x2C,0xCC,0xF4,0x7F,0x24, -0x52,0x00,0x00,0x28,0x40,0x77,0x28,0xDC,0x01,0x7F,0xA0,0x04,0x00,0x00,0x40,0x87, -0x01,0x50,0x70,0xDC,0x01,0x7F,0xA0,0x04,0x00,0x00,0x40,0xA0,0x40,0xA0,0x4F,0x0C, -0x30,0x04,0x00,0xA0,0x01,0x2C,0xCC,0xF4,0x7F,0xA0,0x52,0x00,0x00,0x84,0x7F,0x64, -0x08,0x00,0x02,0x59,0x70,0x83,0xEF,0xA0,0x04,0x00,0x00,0x70,0xDC,0x02,0x7F,0xA0, -0x04,0x00,0x00,0x40,0xA0,0x40,0xA0,0x4F,0xC8,0x05,0x00,0x00,0x2C,0xCC,0xF8,0x7F, -0xB0,0x7F,0x00,0x00,0x2C,0x5C,0x7F,0x70,0x69,0x00,0x00,0x3C,0x4F,0xEF,0xBE,0xED, -0xFE,0x7F,0x64,0x08,0x00,0x02,0x7F,0x0A,0x84,0x59,0x7F,0x64,0x08,0x00,0x02,0x70, -0x3C,0x4F,0xED,0x0D,0x1C,0xA1,0x7F,0x64,0x08,0x00,0x02,0x77,0x0B,0x2C,0x5C,0xEF, -0x58,0x08,0x00,0x02,0x7B,0x08,0x24,0x7F,0xF0,0x65,0x00,0x00,0x3C,0x4F,0xD0,0xF1, -0x02,0x3B,0x7F,0x6C,0x08,0x00,0x02,0x7F,0x2A,0x87,0x6F,0x70,0x7F,0x04,0x90,0x04, -0x00,0x70,0x87,0x6F,0x40,0x7F,0x06,0x90,0x04,0x00,0x70,0x83,0x7F,0x07,0x90,0x04, -0x00,0x70,0x87,0x04,0x7F,0x0D,0x90,0x04,0x00,0x70,0x80,0x7F,0x5C,0x08,0x00,0x02, -0x70,0x84,0x7F,0x64,0x08,0x00,0x02,0x45,0x84,0x7F,0x6C,0x08,0x00,0x02,0x44,0x84, -0x7F,0x5C,0x08,0x00,0x02,0x43,0x84,0x4F,0x00,0x00,0x00,0x02,0x47,0x84,0x4F,0x04, -0x15,0x00,0x02,0x46,0x7B,0x4B,0x87,0x5F,0xFF,0x00,0x57,0x70,0x3F,0x5F,0xFF,0x00, -0x57,0x7F,0x08,0x24,0x7F,0x35,0x19,0x00,0x00,0x87,0x5F,0xAA,0x00,0x57,0x70,0x3F, -0x5F,0xAA,0x00,0x57,0x7F,0x08,0x24,0x7F,0x35,0x19,0x00,0x00,0x87,0x6F,0x55,0x57, -0x70,0x3F,0x6F,0x55,0x57,0x7F,0x08,0x24,0x7F,0x35,0x19,0x00,0x00,0x83,0x57,0x70, -0x84,0x47,0x40,0x90,0x47,0x2B,0x50,0x7F,0x08,0x24,0x7F,0x35,0x19,0x00,0x00,0x3C, -0x46,0x47,0x5B,0xB4,0x3C,0x4F,0x00,0x40,0x00,0x02,0x47,0x4B,0x04,0x7B,0x40,0x3C, -0x4F,0xEF,0xBE,0xED,0xFE,0x45,0x7F,0x26,0x3C,0x4F,0xD0,0xF1,0x02,0x3B,0x45,0x7F, -0x1D,0x3C,0x4F,0x0D,0xF0,0xAD,0x8B,0x45,0x7F,0x14,0x3C,0x4F,0x1E,0xAC,0xEB,0xAD, -0x45,0x7F,0x0B,0x3C,0x4F,0xED,0x0D,0x1C,0xA1,0x45,0x77,0x09,0x84,0x4F,0x00,0x30, -0x00,0x02,0x47,0x84,0x4F,0x00,0x40,0x00,0x02,0x46,0x7A,0x6A,0xFF,0x84,0x44,0x7F, -0x6C,0x08,0x00,0x02,0x70,0x84,0x45,0x7F,0x64,0x08,0x00,0x02,0x70,0x84,0x43,0x7F, -0x5C,0x08,0x00,0x02,0x70,0x87,0x01,0x7F,0x68,0x08,0x00,0x02,0x70,0x82,0x48,0x84, -0x4F,0x00,0x38,0x04,0x00,0x45,0x84,0x4F,0x00,0x30,0x04,0x00,0x47,0x7B,0x40,0x86, -0xE2,0x48,0xE0,0x40,0x86,0xE2,0xC7,0x02,0xE0,0x41,0xBA,0x0F,0x41,0x86,0xE2,0x41, -0xE0,0x41,0x9C,0x41,0x40,0x86,0x40,0x48,0x86,0xE2,0x48,0xE0,0x40,0xD0,0x01,0x40, -0x40,0x86,0xE2,0x40,0xE0,0x40,0x86,0xE2,0x48,0xE0,0x41,0xD4,0x0F,0x41,0x41,0x86, -0xE2,0x41,0xE0,0x41,0xB0,0x41,0x40,0x86,0x40,0x48,0x9C,0x04,0x47,0x3C,0x45,0x47, -0x5B,0xBF,0x86,0xE2,0x48,0xE0,0x40,0x88,0x40,0x40,0x86,0x40,0x48,0x86,0xE2,0x48, -0xE0,0x40,0xF8,0x0F,0x57,0x41,0xF8,0x0F,0xC7,0x04,0x42,0xD0,0x04,0x42,0x42,0xB0, -0x42,0x41,0xF8,0x0F,0xC7,0x08,0x42,0xD0,0x08,0x42,0x42,0xB0,0x42,0x41,0xF8,0x0F, -0xC7,0x0C,0x42,0xD0,0x0C,0x42,0x42,0xB0,0x42,0x41,0x3C,0x41,0x40,0x77,0x08,0x24, -0x7F,0x1D,0x19,0x00,0x00,0x84,0x4F,0x00,0x30,0x04,0x00,0x47,0x7B,0x08,0x80,0x57, -0x70,0x9C,0x04,0x47,0x3C,0x45,0x47,0x5B,0xF7,0x84,0x01,0x7F,0x60,0x30,0x04,0x00, -0x70,0x80,0x7F,0x64,0x30,0x04,0x00,0x70,0x82,0x48,0x84,0x4F,0x00,0x30,0x04,0x00, -0x47,0x7B,0x40,0x86,0xE2,0x48,0xE0,0x40,0x86,0xE2,0xC7,0x02,0xE0,0x41,0xBA,0x0F, -0x41,0x86,0xE2,0x41,0xE0,0x41,0x9C,0x41,0x40,0x86,0x40,0x48,0x86,0xE2,0x48,0xE0, -0x40,0xD0,0x01,0x40,0x40,0x86,0xE2,0x40,0xE0,0x40,0x86,0xE2,0x48,0xE0,0x41,0xD4, -0x0F,0x41,0x41,0x86,0xE2,0x41,0xE0,0x41,0xB0,0x41,0x40,0x86,0x40,0x48,0x9C,0x04, -0x47,0x3C,0x45,0x47,0x5B,0xBF,0x86,0xE2,0x48,0xE0,0x40,0x88,0x40,0x40,0x86,0x40, -0x48,0x86,0xE2,0x48,0xE0,0x57,0x70,0x86,0xE2,0x48,0xE0,0x40,0xD4,0x04,0x40,0x40, -0x84,0x40,0xC7,0x04,0x70,0x86,0xE2,0x48,0xE0,0x40,0xD4,0x08,0x40,0x40,0x84,0x40, -0xC7,0x08,0x70,0x86,0xE2,0x48,0xE0,0x40,0xD4,0x0C,0x40,0x40,0x84,0x40,0xC7,0x0C, -0x70,0xB0,0x4F,0x00,0x00,0x00,0x20,0x7F,0x5C,0x08,0x00,0x02,0x70,0x24,0x7F,0xB1, -0x21,0x00,0x00,0x84,0x02,0x44,0x24,0x7F,0x41,0x19,0x00,0x00,0x84,0x03,0x44,0x24, -0x7F,0x41,0x19,0x00,0x00,0x84,0x04,0x44,0x24,0x7F,0x41,0x19,0x00,0x00,0x84,0x05, -0x44,0x83,0x7F,0x0D,0x90,0x04,0x00,0x70,0x87,0x08,0x7F,0x0F,0x90,0x04,0x00,0x70, -0x87,0x01,0x7F,0x17,0x40,0x04,0x00,0x70,0x87,0x01,0x7F,0x03,0x40,0x04,0x00,0x70, -0x80,0x45,0x7B,0x32,0x80,0x43,0x7B,0x04,0x90,0x43,0x3C,0x4F,0x50,0xC3,0x00,0x00, -0x43,0x5F,0xF7,0x87,0x01,0x7F,0x13,0x40,0x04,0x00,0x70,0x80,0x43,0x7B,0x04,0x90, -0x43,0x3C,0x4F,0x50,0xC3,0x00,0x00,0x43,0x5F,0xF7,0x87,0x01,0x7F,0x17,0x40,0x04, -0x00,0x70,0x90,0x45,0x3C,0x44,0x45,0x5B,0xCD,0x3F,0x01,0xEF,0x10,0x05,0x00,0x00, -0x7F,0x2B,0x3F,0x6F,0x64,0x7F,0x03,0x20,0x04,0x00,0x7F,0x21,0x80,0xEF,0x8C,0x04, -0x00,0x00,0x70,0x80,0xEF,0x14,0x05,0x00,0x00,0x70,0x83,0x7F,0x0D,0x90,0x04,0x00, -0x70,0x87,0x04,0x7F,0x0E,0x90,0x04,0x00,0x70,0x7B,0x00,0x80,0x43,0x7B,0x04,0x90, -0x43,0xE8,0x4F,0x50,0xC3,0x00,0x00,0x44,0x40,0x3C,0x40,0x43,0x5F,0xF3,0x24,0x7F, -0x60,0x19,0x00,0x00,0x04,0x59,0x4C,0x20,0x48,0x20,0x47,0x20,0x46,0x20,0x45,0x20, -0x44,0x20,0x43,0x20,0x49,0x08,0x70,0x70,0x10,0x43,0x9C,0x4F,0x00,0x00,0x00,0x00, -0x4C,0x87,0x5F,0xD0,0x00,0x7F,0x00,0xD0,0x04,0x00,0x70,0xA0,0x01,0x2C,0xCC,0xFC, -0xEF,0x28,0x05,0x00,0x00,0x87,0x01,0x7F,0x70,0x08,0x00,0x02,0x70,0x87,0x5F,0xFF, -0x00,0x7F,0x71,0x08,0x00,0x02,0x70,0x84,0x4F,0x00,0x38,0x04,0x00,0x43,0xA0,0x00, -0xA0,0x4F,0x74,0x08,0x00,0x02,0xA0,0x00,0xA0,0x03,0x2C,0xCC,0xF0,0x7F,0x2C,0x7B, -0x00,0x00,0x28,0x40,0x77,0x08,0x24,0x7F,0x67,0x1B,0x00,0x00,0xDC,0x03,0x7F,0x08, -0x05,0x00,0x00,0x40,0x3F,0x50,0x7F,0x74,0x08,0x00,0x02,0x7F,0x08,0x24,0x7F,0x67, -0x1B,0x00,0x00,0xDC,0x07,0x7F,0x08,0x05,0x00,0x00,0x40,0x3F,0x50,0x7F,0x75,0x08, -0x00,0x02,0x7F,0x08,0x24,0x7F,0x67,0x1B,0x00,0x00,0xDC,0x0B,0x7F,0x08,0x05,0x00, -0x00,0x40,0x3F,0x50,0x7F,0x76,0x08,0x00,0x02,0x7F,0x08,0x24,0x7F,0x67,0x1B,0x00, -0x00,0xDC,0x0F,0x7F,0x08,0x05,0x00,0x00,0x40,0x3F,0x50,0x7F,0x77,0x08,0x00,0x02, -0x7F,0x08,0x24,0x7F,0x67,0x1B,0x00,0x00,0x84,0x4F,0x00,0x30,0x04,0x00,0x48,0x7B, -0x08,0x80,0x58,0x70,0x9C,0x04,0x48,0x3C,0x43,0x48,0x5B,0xF7,0x84,0x01,0x7F,0x60, -0x30,0x04,0x00,0x70,0x80,0x7F,0x64,0x30,0x04,0x00,0x70,0x82,0x44,0x84,0x4F,0x00, -0x30,0x04,0x00,0x48,0x7B,0x40,0x86,0xE2,0x44,0xE0,0x40,0x86,0xE2,0xC8,0x02,0xE0, -0x41,0xBA,0x0F,0x41,0x86,0xE2,0x41,0xE0,0x41,0x9C,0x41,0x40,0x86,0x40,0x44,0x86, -0xE2,0x44,0xE0,0x40,0xD0,0x01,0x40,0x40,0x86,0xE2,0x40,0xE0,0x40,0x86,0xE2,0x44, -0xE0,0x41,0xD4,0x0F,0x41,0x41,0x86,0xE2,0x41,0xE0,0x41,0xB0,0x41,0x40,0x86,0x40, -0x44,0x9C,0x04,0x48,0x3C,0x43,0x48,0x5B,0xBF,0x86,0xE2,0x44,0xE0,0x40,0x88,0x40, -0x40,0x86,0x40,0x44,0x86,0xE2,0x44,0xE0,0x58,0x70,0x86,0xE2,0x44,0xE0,0x40,0xD4, -0x04,0x40,0x40,0x84,0x40,0xC8,0x04,0x70,0x86,0xE2,0x44,0xE0,0x40,0xD4,0x08,0x40, -0x40,0x84,0x40,0xC8,0x08,0x70,0x86,0xE2,0x44,0xE0,0x40,0xD4,0x0C,0x40,0x40,0x84, -0x40,0xC8,0x0C,0x70,0xB0,0x4F,0x00,0x00,0x00,0x40,0x7F,0x5C,0x08,0x00,0x02,0x70, -0x2C,0x5C,0x7F,0xE0,0x5D,0x00,0x00,0xA0,0x4F,0x0C,0x30,0x04,0x00,0xA0,0x4F,0x61, -0x08,0x00,0x02,0xA0,0x01,0x2C,0xCC,0xF4,0x7F,0x24,0x52,0x00,0x00,0x28,0x40,0x77, -0x20,0x87,0x01,0x7F,0x61,0x08,0x00,0x02,0x70,0xA0,0x4F,0x61,0x08,0x00,0x02,0xA0, -0x4F,0x0C,0x30,0x04,0x00,0xA0,0x01,0x2C,0xCC,0xF4,0x7F,0xA0,0x52,0x00,0x00,0x3F, -0x01,0x7F,0x61,0x08,0x00,0x02,0x7F,0x0B,0x3F,0x02,0x7F,0x61,0x08,0x00,0x02,0x77, -0x12,0x87,0x01,0x45,0xFF,0x01,0x7F,0x61,0x08,0x00,0x02,0x40,0x87,0x40,0x47,0x7B, -0x06,0x83,0x45,0x83,0x47,0x83,0x7F,0x60,0x08,0x00,0x02,0x70,0x82,0x44,0x7B,0x1A, -0x86,0xE2,0x44,0xE0,0x40,0x86,0xE2,0x44,0xE0,0x41,0x87,0x81,0xEC,0x10,0x00,0x00, -0x80,0x74,0x0A,0x00,0x02,0x70,0x92,0x44,0x86,0xE2,0x44,0xE0,0x40,0x3C,0x08,0x40, -0x5B,0xE0,0x82,0x44,0x7B,0x23,0x87,0x47,0xE0,0x40,0xA0,0x40,0x2C,0xCC,0xFC,0x7F, -0x2C,0x73,0x00,0x00,0x28,0x40,0x7F,0x04,0x7B,0x19,0xA0,0x6F,0x64,0x2C,0xCC,0xFC, -0xEF,0x28,0x05,0x00,0x00,0x92,0x44,0x86,0xE2,0x44,0xE0,0x40,0x3C,0x3C,0x40,0x5B, -0xD7,0x87,0x47,0xE0,0x40,0xA0,0x40,0x2C,0xCC,0xFC,0x7F,0x28,0x6E,0x00,0x00,0x28, -0x40,0x77,0x39,0xF0,0x02,0x7F,0x7C,0x0A,0x00,0x02,0x40,0x87,0x47,0xE0,0x41,0xD0, -0x17,0x41,0x41,0xB0,0x41,0x40,0xA0,0x40,0x2C,0xCC,0xFC,0x7F,0xC0,0x61,0x00,0x00, -0x87,0x01,0x7F,0x13,0x40,0x04,0x00,0x70,0x84,0x4F,0xEF,0xBE,0xED,0xFE,0xEF,0x8C, -0x04,0x00,0x00,0x70,0x24,0x7F,0x37,0x1E,0x00,0x00,0xEB,0x6F,0x54,0x47,0x40,0x3C, -0x4F,0x0D,0x60,0x5E,0xCA,0x80,0x84,0x0A,0x00,0x02,0x7F,0x08,0x24,0x7F,0xA0,0x1D, -0x00,0x00,0xDF,0x01,0x47,0x40,0xB3,0x40,0x7F,0x60,0x08,0x00,0x02,0x70,0xBB,0x5F, -0xF0,0x00,0x7F,0x75,0x0A,0x00,0x02,0x70,0xEB,0x6F,0x54,0x47,0x40,0xD4,0x08,0x80, -0xA4,0x0A,0x00,0x02,0x40,0xB3,0x40,0x7F,0x75,0x0A,0x00,0x02,0x70,0xEB,0x6F,0x54, -0x47,0x40,0x87,0x80,0xA7,0x0A,0x00,0x02,0x7F,0x76,0x0A,0x00,0x02,0x70,0xEB,0x6F, -0x54,0x47,0x40,0xFF,0x01,0x80,0x9F,0x0A,0x00,0x02,0x40,0x87,0x40,0x7F,0x77,0x0A, -0x00,0x02,0x70,0xEB,0x6F,0x54,0x47,0x40,0xFF,0x01,0x80,0xA3,0x0A,0x00,0x02,0x40, -0x87,0x40,0x7F,0x78,0x0A,0x00,0x02,0x70,0xEB,0x6F,0x54,0x47,0x40,0xD4,0x09,0x80, -0x98,0x0A,0x00,0x02,0x40,0x87,0x40,0x7F,0x7A,0x0A,0x00,0x02,0x70,0xEB,0x6F,0x54, -0x47,0x40,0xD4,0x01,0x80,0x98,0x0A,0x00,0x02,0x40,0x87,0x40,0x7F,0x7B,0x0A,0x00, -0x02,0x70,0x87,0x47,0xE0,0x40,0xA0,0x40,0x2C,0xCC,0xFC,0x7F,0x2C,0x73,0x00,0x00, -0x28,0x40,0x77,0x35,0x2B,0x45,0x7F,0x31,0x87,0x47,0xE0,0x40,0xD0,0x17,0x40,0x40, -0xB0,0x4F,0x02,0x00,0x04,0x00,0x40,0xA0,0x40,0x2C,0xCC,0xFC,0x7F,0xC0,0x61,0x00, -0x00,0x87,0x01,0x7F,0x13,0x40,0x04,0x00,0x70,0x84,0x4F,0xEF,0xBE,0xED,0xFE,0xEF, -0x8C,0x04,0x00,0x00,0x70,0x7B,0x45,0x2B,0x45,0x7F,0x41,0x87,0x47,0xE0,0x40,0xA0, -0x40,0x2C,0xCC,0xFC,0x7F,0xD4,0x78,0x00,0x00,0x28,0x40,0x77,0x2F,0x87,0x47,0xE0, -0x40,0xD0,0x17,0x40,0x40,0xB0,0x4F,0x02,0x00,0x05,0x00,0x40,0xA0,0x40,0x2C,0xCC, -0xFC,0x7F,0xC0,0x61,0x00,0x00,0x87,0x01,0x7F,0x13,0x40,0x04,0x00,0x70,0x84,0x4F, -0xEF,0xBE,0xED,0xFE,0xEF,0x8C,0x04,0x00,0x00,0x70,0x24,0x7F,0x37,0x1E,0x00,0x00, -0x3C,0x4F,0xEF,0xBE,0xED,0xFE,0x7F,0x78,0x08,0x00,0x02,0x77,0x5B,0x84,0x3D,0x7F, -0x64,0x08,0x00,0x02,0x70,0xA0,0x4F,0x64,0x08,0x00,0x02,0xA0,0x4F,0x0A,0x30,0x04, -0x00,0xA0,0x02,0x2C,0xCC,0xF4,0x7F,0xA0,0x52,0x00,0x00,0x2C,0x5C,0x7F,0x90,0x3B, -0x00,0x00,0x87,0x01,0x7F,0x61,0x08,0x00,0x02,0x70,0xA0,0x4F,0x61,0x08,0x00,0x02, -0xA0,0x4F,0x0C,0x30,0x04,0x00,0xA0,0x01,0x2C,0xCC,0xF4,0x7F,0xA0,0x52,0x00,0x00, -0x84,0x4F,0x1E,0xAC,0xEB,0xAD,0x7F,0x64,0x08,0x00,0x02,0x70,0xB0,0x10,0x7F,0x5C, -0x08,0x00,0x02,0x70,0x7B,0x33,0x2B,0x45,0x7F,0x2F,0x87,0x47,0xE0,0x40,0xD0,0x17, -0x40,0x40,0xB0,0x4F,0x02,0x00,0x02,0x00,0x40,0xA0,0x40,0x2C,0xCC,0xFC,0x7F,0xC0, -0x61,0x00,0x00,0x87,0x01,0x7F,0x13,0x40,0x04,0x00,0x70,0x84,0x4F,0xEF,0xBE,0xED, -0xFE,0xEF,0x8C,0x04,0x00,0x00,0x70,0xF7,0x01,0x47,0x40,0x87,0x40,0x46,0xA0,0x4F, -0x3A,0x30,0x04,0x00,0xA0,0x4F,0x61,0x08,0x00,0x02,0xA0,0x01,0x2C,0xCC,0xF4,0x7F, -0x24,0x52,0x00,0x00,0x28,0x40,0x77,0x1F,0x83,0x7F,0x61,0x08,0x00,0x02,0x70,0xA0, -0x4F,0x61,0x08,0x00,0x02,0xA0,0x4F,0x3A,0x30,0x04,0x00,0xA0,0x01,0x2C,0xCC,0xF4, -0x7F,0xA0,0x52,0x00,0x00,0x3F,0x01,0x7F,0x61,0x08,0x00,0x02,0x77,0x05,0x86,0x3B, -0x44,0xA0,0x6F,0x64,0x2C,0xCC,0xFC,0xEF,0x28,0x05,0x00,0x00,0x87,0x46,0xE0,0x40, -0xA0,0x40,0x2C,0xCC,0xFC,0x7F,0x80,0x73,0x00,0x00,0x28,0x40,0x7F,0x04,0x7B,0x0E, -0x92,0x44,0x86,0xE2,0x44,0xE0,0x40,0x3C,0x3C,0x40,0x5B,0xD7,0x86,0xE2,0x44,0xE0, -0x40,0x3C,0x3C,0x40,0x5B,0x26,0x87,0x01,0x7F,0x61,0x08,0x00,0x02,0x70,0xA0,0x4F, -0x61,0x08,0x00,0x02,0xA0,0x4F,0x3A,0x30,0x04,0x00,0xA0,0x01,0x2C,0xCC,0xF4,0x7F, -0xA0,0x52,0x00,0x00,0x24,0x7F,0xA9,0x20,0x00,0x00,0x87,0x46,0xE0,0x40,0xA0,0x40, -0x2C,0xCC,0xFC,0x7F,0x28,0x6E,0x00,0x00,0x28,0x40,0x77,0x39,0xF0,0x02,0x7F,0x7C, -0x0A,0x00,0x02,0x40,0x87,0x46,0xE0,0x41,0xD0,0x17,0x41,0x41,0xB0,0x41,0x40,0xA0, -0x40,0x2C,0xCC,0xFC,0x7F,0xC0,0x61,0x00,0x00,0x87,0x01,0x7F,0x13,0x40,0x04,0x00, -0x70,0x84,0x4F,0xEF,0xBE,0xED,0xFE,0xEF,0x8C,0x04,0x00,0x00,0x70,0x24,0x7F,0xA9, -0x20,0x00,0x00,0xEB,0x6F,0x54,0x46,0x40,0x3C,0x4F,0x0D,0x60,0x5E,0xCA,0x80,0x84, -0x0A,0x00,0x02,0x7F,0x35,0x87,0x46,0xE0,0x40,0xD0,0x17,0x40,0x40,0xB0,0x4F,0x02, -0x00,0x02,0x00,0x40,0xA0,0x40,0x2C,0xCC,0xFC,0x7F,0xC0,0x61,0x00,0x00,0x87,0x01, -0x7F,0x13,0x40,0x04,0x00,0x70,0x84,0x4F,0xEF,0xBE,0xED,0xFE,0xEF,0x8C,0x04,0x00, -0x00,0x70,0x24,0x7F,0xA9,0x20,0x00,0x00,0xDF,0x01,0x46,0x40,0xB3,0x40,0x7F,0x60, -0x08,0x00,0x02,0x70,0x80,0x43,0xEB,0x6F,0x54,0x46,0x40,0xEB,0x6F,0x54,0x47,0x41, -0x3C,0x81,0xA4,0x0A,0x00,0x02,0x80,0xA4,0x0A,0x00,0x02,0x5F,0x35,0xBB,0x5F,0xF0, -0x00,0x7F,0x75,0x0A,0x00,0x02,0x70,0xEB,0x6F,0x54,0x46,0x40,0xD4,0x08,0x80,0xA4, -0x0A,0x00,0x02,0x40,0xB3,0x40,0x7F,0x75,0x0A,0x00,0x02,0x70,0xEB,0x6F,0x54,0x46, -0x40,0x87,0x80,0xA7,0x0A,0x00,0x02,0x7F,0x76,0x0A,0x00,0x02,0x70,0x84,0x01,0x43, -0xEB,0x6F,0x54,0x46,0x40,0xEB,0x6F,0x54,0x47,0x41,0x3C,0x81,0x9C,0x0A,0x00,0x02, -0x80,0x9C,0x0A,0x00,0x02,0x5F,0x1A,0xEB,0x6F,0x54,0x46,0x40,0xFF,0x01,0x80,0x9F, -0x0A,0x00,0x02,0x40,0x87,0x40,0x7F,0x77,0x0A,0x00,0x02,0x70,0x84,0x01,0x43,0xEB, -0x6F,0x54,0x46,0x40,0xEB,0x6F,0x54,0x47,0x41,0x3C,0x81,0xA0,0x0A,0x00,0x02,0x80, -0xA0,0x0A,0x00,0x02,0x5F,0x1A,0xEB,0x6F,0x54,0x46,0x40,0xFF,0x01,0x80,0xA3,0x0A, -0x00,0x02,0x40,0x87,0x40,0x7F,0x78,0x0A,0x00,0x02,0x70,0x84,0x01,0x43,0xEB,0x6F, -0x54,0x46,0x40,0xEB,0x6F,0x54,0x47,0x41,0x3C,0x81,0x98,0x0A,0x00,0x02,0x80,0x98, -0x0A,0x00,0x02,0x5F,0x2F,0xEB,0x6F,0x54,0x46,0x40,0xD4,0x09,0x80,0x98,0x0A,0x00, -0x02,0x40,0x87,0x40,0x7F,0x7A,0x0A,0x00,0x02,0x70,0xEB,0x6F,0x54,0x46,0x40,0xD4, -0x01,0x80,0x98,0x0A,0x00,0x02,0x40,0x87,0x40,0x7F,0x7B,0x0A,0x00,0x02,0x70,0x84, -0x01,0x43,0x28,0x43,0x7F,0x45,0x87,0x46,0xE0,0x40,0xA0,0x40,0x2C,0xCC,0xFC,0x7F, -0x2C,0x73,0x00,0x00,0x28,0x40,0x77,0x33,0x2B,0x45,0x7F,0x2F,0x87,0x46,0xE0,0x40, -0xD0,0x17,0x40,0x40,0xB0,0x4F,0x02,0x00,0x04,0x00,0x40,0xA0,0x40,0x2C,0xCC,0xFC, -0x7F,0xC0,0x61,0x00,0x00,0x87,0x01,0x7F,0x13,0x40,0x04,0x00,0x70,0x84,0x4F,0xEF, -0xBE,0xED,0xFE,0xEF,0x8C,0x04,0x00,0x00,0x70,0x2C,0x5C,0x7F,0xE0,0x5D,0x00,0x00, -0x3F,0x02,0x7F,0x60,0x08,0x00,0x02,0x4F,0x12,0x87,0x7F,0x60,0x08,0x00,0x02,0xE2, -0x40,0xBE,0x01,0x40,0x86,0x40,0x44,0x7B,0x0D,0x87,0x7F,0x60,0x08,0x00,0x02,0xE2, -0x40,0x86,0x40,0x44,0xDC,0x04,0x7F,0x90,0x04,0x00,0x00,0x40,0x86,0xE2,0x44,0xE0, -0x41,0x90,0x41,0xC8,0x03,0x00,0x41,0x50,0x70,0xDC,0x08,0x7F,0x90,0x04,0x00,0x00, -0x40,0x84,0xEF,0xE8,0x04,0x00,0x00,0x50,0x70,0xDC,0x04,0x7F,0x90,0x04,0x00,0x00, -0x40,0xCC,0x03,0x00,0x50,0x40,0xA8,0x0C,0x40,0x9C,0x40,0xEF,0xE8,0x04,0x00,0x00, -0x70,0xDC,0x08,0x7F,0x90,0x04,0x00,0x00,0x40,0x86,0x01,0xD0,0x00,0x70,0xDC,0x08, -0x7F,0x90,0x04,0x00,0x00,0x40,0xDC,0x02,0x50,0x40,0xA0,0x40,0xA0,0x4F,0xD1,0x05, -0x00,0x00,0x2C,0xCC,0xF8,0x7F,0xB0,0x7F,0x00,0x00,0x3B,0x7F,0x60,0x08,0x00,0x02, -0x01,0x7F,0x23,0x3C,0x4F,0x0D,0x60,0x5E,0xCA,0x7F,0x84,0x0A,0x00,0x02,0x77,0x16, -0xDC,0x08,0x7F,0x90,0x04,0x00,0x00,0x40,0x84,0x50,0x40,0x86,0x7F,0x82,0x0A,0x00, -0x02,0xC0,0x0C,0x70,0x3B,0x7F,0x60,0x08,0x00,0x02,0x02,0x7F,0x23,0x3C,0x4F,0x0D, -0x60,0x5E,0xCA,0x7F,0xD8,0x0A,0x00,0x02,0x77,0x16,0xDC,0x08,0x7F,0x90,0x04,0x00, -0x00,0x40,0x84,0x50,0x40,0x86,0x7F,0xD6,0x0A,0x00,0x02,0xC0,0x18,0x70,0x24,0x7F, -0xF0,0x65,0x00,0x00,0x04,0x59,0x4C,0x20,0x48,0x20,0x47,0x20,0x46,0x20,0x45,0x20, -0x44,0x20,0x43,0x20,0x49,0x08,0x70,0x70,0x10,0x45,0x9C,0x4F,0x00,0x00,0x00,0x00, -0x4C,0x84,0x4F,0x28,0x0B,0x00,0x02,0x48,0x84,0x4F,0xE4,0x05,0x00,0x00,0x47,0x80, -0x45,0x7B,0x12,0x84,0x48,0x40,0x90,0x48,0x84,0x47,0x41,0x90,0x47,0x87,0x51,0x50, -0x70,0x90,0x45,0x3C,0x6F,0x44,0x45,0x5B,0xEC,0x84,0x4F,0x80,0xE1,0x81,0x00,0x7F, -0x78,0x0B,0x00,0x02,0x70,0x84,0x4F,0xF8,0x41,0x00,0x00,0x7F,0x7C,0x0B,0x00,0x02, -0x70,0x84,0x4F,0xE8,0x0E,0x00,0x02,0x7F,0x80,0x0B,0x00,0x02,0x70,0x84,0x4F,0xE8, -0x0E,0x00,0x02,0x7F,0x90,0x0B,0x00,0x02,0x70,0x84,0x4F,0xE8,0x10,0x00,0x02,0x7F, -0x94,0x0B,0x00,0x02,0x70,0x80,0x7F,0xC4,0x0B,0x00,0x02,0x70,0x80,0x45,0x7B,0x3A, -0xE8,0x6F,0x50,0x45,0x40,0x9C,0x4F,0xC8,0x0B,0x00,0x02,0x40,0x84,0x40,0x46,0x84, -0x4F,0x80,0xE1,0x81,0x00,0x56,0x70,0x84,0x4F,0xE8,0x10,0x00,0x02,0xC6,0x08,0x70, -0x84,0x4F,0xE8,0x10,0x00,0x02,0xC6,0x18,0x70,0x84,0x4F,0xE8,0x11,0x00,0x02,0xC6, -0x1C,0x70,0x80,0xC6,0x4C,0x70,0x90,0x45,0x3C,0x09,0x45,0x4B,0xC5,0x84,0x4F,0xA0, -0x40,0x00,0x00,0x7F,0xCC,0x0B,0x00,0x02,0x70,0x84,0x4F,0xC6,0x40,0x00,0x00,0x7F, -0x1C,0x0C,0x00,0x02,0x70,0x84,0x4F,0xEC,0x40,0x00,0x00,0x7F,0x6C,0x0C,0x00,0x02, -0x70,0x84,0x4F,0x12,0x41,0x00,0x00,0x7F,0xBC,0x0C,0x00,0x02,0x70,0x84,0x4F,0x38, -0x41,0x00,0x00,0x7F,0x0C,0x0D,0x00,0x02,0x70,0x84,0x4F,0x5E,0x41,0x00,0x00,0x7F, -0x5C,0x0D,0x00,0x02,0x70,0x84,0x4F,0x84,0x41,0x00,0x00,0x7F,0xAC,0x0D,0x00,0x02, -0x70,0x84,0x4F,0xAA,0x41,0x00,0x00,0x7F,0xFC,0x0D,0x00,0x02,0x70,0x84,0x4F,0xD0, -0x41,0x00,0x00,0x7F,0x4C,0x0E,0x00,0x02,0x70,0x84,0x4F,0x80,0xE1,0x81,0x00,0x7F, -0x98,0x0E,0x00,0x02,0x70,0x84,0x4F,0x8E,0x42,0x00,0x00,0x7F,0x9C,0x0E,0x00,0x02, -0x70,0x84,0x4F,0xE8,0x0E,0x00,0x02,0x7F,0xA0,0x0E,0x00,0x02,0x70,0x84,0x4F,0xE8, -0x0E,0x00,0x02,0x7F,0xB0,0x0E,0x00,0x02,0x70,0x84,0x4F,0xE8,0x10,0x00,0x02,0x7F, -0xB4,0x0E,0x00,0x02,0x70,0x80,0x7F,0xE4,0x0E,0x00,0x02,0x70,0x04,0x7F,0x28,0x0B, -0x00,0x02,0x4D,0x24,0x7F,0x31,0x23,0x00,0x00,0x04,0xC9,0xF8,0x4C,0x20,0x48,0x20, -0x47,0x20,0x46,0x20,0x45,0x20,0x49,0x08,0x10,0x49,0x9C,0x4F,0x08,0x00,0x00,0x00, -0x4C,0x84,0x4F,0x00,0x90,0x04,0x00,0x7F,0xE8,0x11,0x00,0x02,0x70,0x2C,0x5C,0x7F, -0x90,0x3B,0x00,0x00,0x2C,0x5C,0xAF,0x7C,0x03,0x87,0x40,0x59,0x70,0x2B,0x59,0x77, -0x0A,0x24,0x7F,0x3E,0x19,0x00,0x00,0x7B,0x0D,0x3F,0x02,0x59,0x77,0x08,0x24,0x7F, -0xD5,0x12,0x00,0x00,0xB0,0x4F,0x00,0x00,0x00,0x80,0x7F,0x5C,0x08,0x00,0x02,0x70, -0x2C,0x5C,0x7F,0xE0,0x5D,0x00,0x00,0x2C,0x5C,0x7F,0x7C,0x29,0x00,0x00,0x84,0x40, -0xEF,0xE4,0x04,0x00,0x00,0x70,0x84,0x4F,0x14,0x15,0x00,0x02,0xEF,0xE8,0x04,0x00, -0x00,0x70,0x9C,0x20,0xEF,0xE8,0x04,0x00,0x00,0x70,0x87,0x00,0xE0,0x40,0xC8,0x03, -0x0C,0x40,0xEF,0x90,0x04,0x00,0x00,0x70,0x87,0x01,0xE0,0x40,0xC8,0x0F,0x10,0x40, -0xEF,0x90,0x04,0x00,0x00,0x70,0xDC,0x04,0x7F,0x90,0x04,0x00,0x00,0x40,0x87,0x01, -0xE0,0x41,0xC8,0x00,0x05,0x41,0x50,0x70,0xDC,0x04,0x7F,0x90,0x04,0x00,0x00,0x40, -0x87,0x01,0xE0,0x41,0xC8,0x00,0x06,0x41,0x50,0x70,0xDC,0x0C,0x7F,0x90,0x04,0x00, -0x00,0x40,0xA0,0x40,0xA0,0x4F,0x28,0x06,0x00,0x00,0x2C,0xCC,0xF8,0x7F,0xB0,0x7F, -0x00,0x00,0xDC,0x04,0x7F,0x90,0x04,0x00,0x00,0x40,0x87,0x01,0xE0,0x41,0xC8,0x00, -0x07,0x41,0x50,0x70,0xDC,0x04,0x7F,0x90,0x04,0x00,0x00,0x40,0x87,0x01,0xE0,0x41, -0xC8,0x00,0x09,0x41,0x50,0x70,0x84,0x4F,0xA4,0x65,0x00,0x00,0xEF,0x98,0x04,0x00, -0x00,0x70,0x84,0x4F,0xA4,0x65,0x00,0x00,0xEF,0x0C,0x05,0x00,0x00,0x70,0x2C,0x5C, -0x7F,0x72,0x5F,0x00,0x00,0x87,0x01,0x7F,0x1F,0x40,0x04,0x00,0x70,0x87,0x01,0xEF, -0xE0,0x04,0x00,0x00,0x70,0x83,0x7F,0xF1,0x11,0x00,0x02,0x70,0x84,0x4F,0xE0,0x25, -0x00,0x00,0xEF,0x98,0x04,0x00,0x00,0x70,0x84,0x4F,0xE0,0x25,0x00,0x00,0xEF,0x0C, -0x05,0x00,0x00,0x70,0x2C,0x5C,0xEF,0xC0,0x04,0x00,0x00,0x24,0x7F,0x3A,0x25,0x00, -0x00,0x87,0x7F,0xF1,0x11,0x00,0x02,0xE0,0x40,0xD0,0x15,0x40,0x40,0x83,0xC0,0x05, -0x70,0xA0,0x14,0x2C,0xCC,0xFC,0xEF,0x28,0x05,0x00,0x00,0x87,0xEF,0xE0,0x04,0x00, -0x00,0xE0,0x40,0xD0,0x05,0x40,0x40,0x9C,0x7F,0x90,0x04,0x00,0x00,0x40,0x87,0x7F, -0xF1,0x11,0x00,0x02,0xE0,0x41,0xD0,0x15,0x41,0x41,0x87,0xC1,0x01,0xE0,0x42,0xC8, -0x0F,0x10,0x42,0x50,0x70,0x9C,0x20,0xEF,0xE8,0x04,0x00,0x00,0x70,0x87,0xEF,0xE0, -0x04,0x00,0x00,0x40,0x93,0xEF,0xE0,0x04,0x00,0x00,0x70,0x87,0x40,0xE0,0x40,0xD0, -0x05,0x40,0x40,0x9C,0x7F,0x90,0x04,0x00,0x00,0x40,0x87,0x7F,0xF1,0x11,0x00,0x02, -0xE0,0x41,0xC8,0x03,0x0C,0x41,0x50,0x70,0x87,0x7F,0xF1,0x11,0x00,0x02,0xE0,0x40, -0xD0,0x15,0x40,0x40,0x87,0x50,0xE2,0x40,0x86,0x40,0x62,0x70,0x97,0xEF,0xE0,0x04, -0x00,0x00,0x70,0x87,0xEF,0xE0,0x04,0x00,0x00,0xE0,0x40,0xD0,0x05,0x40,0x40,0x9C, -0x7F,0x90,0x04,0x00,0x00,0x40,0x84,0x40,0x64,0x70,0xCC,0x0F,0x10,0xD9,0x04,0x40, -0x86,0xE2,0x62,0xE0,0x41,0xD0,0x08,0x41,0x41,0xB0,0x41,0x40,0xC8,0x0F,0x10,0x40, -0xD9,0x04,0x70,0x93,0xEF,0xE0,0x04,0x00,0x00,0x70,0x93,0x7F,0xF1,0x11,0x00,0x02, -0x70,0x3F,0x0C,0x7F,0xF1,0x11,0x00,0x02,0x4E,0x29,0xFF,0x84,0x4F,0xA4,0x65,0x00, -0x00,0xEF,0x98,0x04,0x00,0x00,0x70,0x84,0x4F,0xA4,0x65,0x00,0x00,0xEF,0x0C,0x05, -0x00,0x00,0x70,0xDC,0x02,0x7F,0xA4,0x04,0x00,0x00,0x40,0x2B,0x50,0x7F,0x28,0x2C, -0x5C,0x7F,0x72,0x5F,0x00,0x00,0x2C,0x5C,0x7F,0x78,0x63,0x00,0x00,0x3C,0x01,0x40, -0x77,0x15,0xB0,0x4F,0x00,0x00,0x00,0x80,0x7F,0x5C,0x08,0x00,0x02,0x70,0x2C,0x5C, -0x7F,0xE0,0x5D,0x00,0x00,0x3C,0x4F,0xEF,0xBE,0xED,0xFE,0x7F,0x64,0x08,0x00,0x02, -0x7F,0x2C,0x3C,0x4F,0x0D,0xF0,0xAD,0x8B,0x7F,0x64,0x08,0x00,0x02,0x7F,0x1F,0x3C, -0x4F,0x1E,0xAC,0xEB,0xAD,0x7F,0x64,0x08,0x00,0x02,0x7F,0x12,0x2C,0x5C,0xAF,0x80, -0x00,0x28,0x40,0x77,0x09,0x2C,0x5C,0x7F,0xE0,0x5D,0x00,0x00,0x2C,0x5C,0x7F,0x72, -0x5F,0x00,0x00,0x24,0x7F,0x01,0x1A,0x00,0x00,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08, -0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x86,0xE2,0x7F,0x02,0x40,0x04,0x00, -0xE0,0x40,0x38,0x40,0x4F,0x00,0x80,0x00,0x00,0x7F,0x0C,0x87,0x01,0x7F,0x27,0x40, -0x04,0x00,0x70,0x7B,0x32,0x84,0x4F,0xEF,0xBE,0xED,0xFE,0xEF,0x8C,0x04,0x00,0x00, -0x70,0x2C,0x5C,0x7F,0x72,0x5F,0x00,0x00,0x87,0x01,0x7F,0x1F,0x40,0x04,0x00,0x70, -0xB0,0x01,0x7F,0x5C,0x08,0x00,0x02,0x70,0x2C,0x5C,0x7F,0xE0,0x5D,0x00,0x00,0x24, -0x7F,0xF0,0x65,0x00,0x00,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x10,0x47,0x9C,0x4F, -0x00,0x00,0x00,0x00,0x4C,0x84,0x4F,0x00,0x40,0x00,0x02,0x48,0x84,0x4F,0x00,0x00, -0x04,0x02,0x47,0x7B,0x3B,0x87,0x5F,0xFF,0x00,0x58,0x70,0x3F,0x5F,0xFF,0x00,0x58, -0x7F,0x04,0x7B,0x31,0x87,0x5F,0xAA,0x00,0x58,0x70,0x3F,0x5F,0xAA,0x00,0x58,0x7F, -0x04,0x7B,0x22,0x87,0x6F,0x55,0x58,0x70,0x3F,0x6F,0x55,0x58,0x7F,0x04,0x7B,0x15, -0x83,0x58,0x70,0x84,0x48,0x40,0x90,0x48,0x2B,0x50,0x7F,0x04,0x7B,0x07,0x3C,0x47, -0x48,0x5B,0xC4,0x3C,0x47,0x48,0x53,0x1A,0xB0,0x08,0x7F,0x5C,0x08,0x00,0x02,0x70, -0x84,0x4F,0xEF,0xBE,0xED,0xFE,0x7F,0x64,0x08,0x00,0x02,0x70,0x80,0x40,0x7B,0x07, -0x84,0x01,0x40,0x7B,0x02,0x04,0xC9,0xF0,0x4C,0x20,0x48,0x20,0x47,0x20,0x49,0x08, -0x10,0x49,0x9C,0x4F,0x04,0x00,0x00,0x00,0x4C,0x87,0x20,0x7F,0x02,0x90,0x04,0x00, -0x70,0x87,0x30,0x7F,0x02,0x90,0x04,0x00,0x70,0x87,0x10,0x7F,0x02,0x90,0x04,0x00, -0x70,0x87,0x7F,0x00,0x90,0x04,0x00,0xE2,0x40,0x86,0x40,0x59,0x70,0xB3,0x5F,0x80, -0x00,0x7F,0x00,0x90,0x04,0x00,0x70,0x87,0x05,0x7F,0x02,0x90,0x04,0x00,0x70,0xA0, -0x14,0x2C,0xCC,0xFC,0xEF,0x28,0x05,0x00,0x00,0x87,0x6F,0x55,0x7F,0x03,0x90,0x04, -0x00,0x70,0xA0,0x14,0x2C,0xCC,0xFC,0xEF,0x28,0x05,0x00,0x00,0x3B,0x7F,0x01,0x90, -0x04,0x00,0x01,0x77,0x0A,0x80,0x40,0x24,0x7F,0x73,0x29,0x00,0x00,0x3F,0x6F,0x55, -0x7F,0x03,0x90,0x04,0x00,0x7F,0x0A,0x80,0x40,0x24,0x7F,0x73,0x29,0x00,0x00,0x3B, -0x7F,0x01,0x90,0x04,0x00,0x01,0x7F,0x0A,0x80,0x40,0x24,0x7F,0x73,0x29,0x00,0x00, -0x87,0x5F,0xAA,0x00,0x7F,0x03,0x90,0x04,0x00,0x70,0xA0,0x14,0x2C,0xCC,0xFC,0xEF, -0x28,0x05,0x00,0x00,0x3B,0x7F,0x01,0x90,0x04,0x00,0x01,0x77,0x0A,0x80,0x40,0x24, -0x7F,0x73,0x29,0x00,0x00,0x3F,0x5F,0xAA,0x00,0x7F,0x03,0x90,0x04,0x00,0x7F,0x0A, -0x80,0x40,0x24,0x7F,0x73,0x29,0x00,0x00,0x87,0x20,0x7F,0x02,0x90,0x04,0x00,0x70, -0x87,0x30,0x7F,0x02,0x90,0x04,0x00,0x70,0x87,0x10,0x7F,0x02,0x90,0x04,0x00,0x70, -0x87,0x7F,0x00,0x90,0x04,0x00,0xE2,0x40,0x86,0x40,0x59,0x70,0xBB,0x6F,0x7F,0x7F, -0x00,0x90,0x04,0x00,0x70,0x87,0x05,0x7F,0x02,0x90,0x04,0x00,0x70,0xA0,0x14,0x2C, -0xCC,0xFC,0xEF,0x28,0x05,0x00,0x00,0x87,0x20,0x7F,0x0A,0x90,0x04,0x00,0x70,0x87, -0x30,0x7F,0x0A,0x90,0x04,0x00,0x70,0x87,0x10,0x7F,0x0A,0x90,0x04,0x00,0x70,0x87, -0x7F,0x08,0x90,0x04,0x00,0xE2,0x40,0x86,0x40,0x59,0x70,0xB3,0x5F,0x80,0x00,0x7F, -0x08,0x90,0x04,0x00,0x70,0x87,0x05,0x7F,0x0A,0x90,0x04,0x00,0x70,0xA0,0x14,0x2C, -0xCC,0xFC,0xEF,0x28,0x05,0x00,0x00,0x87,0x6F,0x55,0x7F,0x0B,0x90,0x04,0x00,0x70, -0xA0,0x14,0x2C,0xCC,0xFC,0xEF,0x28,0x05,0x00,0x00,0x3B,0x7F,0x09,0x90,0x04,0x00, -0x01,0x77,0x0A,0x80,0x40,0x24,0x7F,0x73,0x29,0x00,0x00,0x3F,0x6F,0x55,0x7F,0x0B, -0x90,0x04,0x00,0x7F,0x0A,0x80,0x40,0x24,0x7F,0x73,0x29,0x00,0x00,0x3B,0x7F,0x09, -0x90,0x04,0x00,0x01,0x7F,0x0A,0x80,0x40,0x24,0x7F,0x73,0x29,0x00,0x00,0x87,0x5F, -0xAA,0x00,0x7F,0x0B,0x90,0x04,0x00,0x70,0xA0,0x14,0x2C,0xCC,0xFC,0xEF,0x28,0x05, -0x00,0x00,0x3B,0x7F,0x09,0x90,0x04,0x00,0x01,0x77,0x0A,0x80,0x40,0x24,0x7F,0x73, -0x29,0x00,0x00,0x3F,0x5F,0xAA,0x00,0x7F,0x0B,0x90,0x04,0x00,0x7F,0x0A,0x80,0x40, -0x24,0x7F,0x73,0x29,0x00,0x00,0x87,0x20,0x7F,0x0A,0x90,0x04,0x00,0x70,0x87,0x30, -0x7F,0x0A,0x90,0x04,0x00,0x70,0x87,0x10,0x7F,0x0A,0x90,0x04,0x00,0x70,0x87,0x7F, -0x08,0x90,0x04,0x00,0xE0,0x40,0xD0,0x08,0x40,0x40,0x86,0xE2,0x40,0xE0,0x40,0x87, -0x7F,0x08,0x90,0x04,0x00,0xE0,0x41,0x84,0x4F,0x7F,0xFF,0x00,0x00,0x42,0x86,0xE2, -0x42,0xE0,0x42,0xB8,0x42,0x41,0x86,0xE2,0x41,0xE0,0x41,0xB0,0x41,0x40,0x86,0x40, -0x59,0x70,0x87,0x10,0x7F,0x02,0x90,0x04,0x00,0x70,0x87,0x10,0x7F,0x0A,0x90,0x04, -0x00,0x70,0x87,0x7F,0x00,0x90,0x04,0x00,0x7F,0x08,0x90,0x04,0x00,0x70,0x87,0x7F, -0x00,0x90,0x04,0x00,0x7F,0x08,0x90,0x04,0x00,0x70,0x87,0x05,0x7F,0x0A,0x90,0x04, -0x00,0x70,0xA0,0x14,0x2C,0xCC,0xFC,0xEF,0x28,0x05,0x00,0x00,0x87,0x20,0x7F,0x03, -0x90,0x04,0x00,0x70,0xA0,0x14,0x2C,0xCC,0xFC,0xEF,0x28,0x05,0x00,0x00,0x3B,0x7F, -0x09,0x90,0x04,0x00,0x01,0x7F,0x10,0x3F,0x20,0x7F,0x0B,0x90,0x04,0x00,0x77,0x07, -0x84,0x02,0x40,0x7B,0x40,0x87,0x20,0x7F,0x0A,0x90,0x04,0x00,0x70,0x87,0x30,0x7F, -0x0A,0x90,0x04,0x00,0x70,0x87,0x10,0x7F,0x0A,0x90,0x04,0x00,0x70,0x86,0xE2,0x59, -0xE0,0x40,0xD4,0x08,0x40,0x40,0x87,0x40,0x7F,0x08,0x90,0x04,0x00,0x70,0x87,0x61, -0x7F,0x08,0x90,0x04,0x00,0x70,0x87,0x05,0x7F,0x0A,0x90,0x04,0x00,0x70,0x84,0x01, -0x40,0x7B,0x02,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x10,0x45,0x9C,0x4F, -0x00,0x00,0x00,0x00,0x4C,0x84,0x4F,0xC4,0x2A,0x00,0x00,0x7F,0xF4,0x11,0x00,0x02, -0x70,0x84,0x4F,0xDC,0x2A,0x00,0x00,0x7F,0xF8,0x11,0x00,0x02,0x70,0x83,0xEF,0xC4, -0x04,0x00,0x00,0x70,0x83,0x7F,0xF2,0x11,0x00,0x02,0x70,0x80,0x46,0x3B,0x7F,0x03, -0xC0,0x04,0x00,0x01,0x7F,0x0E,0x84,0x4F,0x00,0x00,0x10,0x00,0x48,0x84,0x48,0x40, -0x7B,0x0C,0x84,0x4F,0x00,0x00,0x04,0x00,0x48,0x84,0x48,0x40,0x3B,0x7F,0x03,0xC0, -0x04,0x00,0x02,0x7F,0x06,0xD0,0x01,0x48,0x48,0x2C,0x5C,0xEF,0xC0,0x04,0x00,0x00, -0x2B,0x7F,0xF2,0x11,0x00,0x02,0x7F,0x08,0x24,0x7F,0x97,0x2A,0x00,0x00,0x3C,0x4F, -0xD0,0xF1,0x02,0x3B,0x7F,0x6C,0x08,0x00,0x02,0x77,0x09,0x84,0x88,0x00,0x00,0x00, -0x02,0x47,0x84,0x4F,0xEF,0xBE,0xED,0xFE,0x88,0x00,0x00,0x00,0x02,0x70,0x3C,0x4F, -0xEF,0xBE,0xED,0xFE,0x88,0x00,0x00,0x00,0x02,0x77,0x05,0x84,0x01,0x46,0x84,0x47, -0x88,0x00,0x00,0x00,0x02,0x70,0x28,0x46,0x7F,0x6F,0x3C,0x4F,0x00,0x00,0x20,0x00, -0x48,0x77,0x66,0xE8,0x03,0x48,0x40,0xAC,0x04,0x40,0x70,0x84,0x40,0x48,0xD0,0x01, -0x48,0x40,0x84,0x40,0x45,0x83,0x7F,0xF2,0x11,0x00,0x02,0x70,0x2C,0x5C,0xEF,0xC0, -0x04,0x00,0x00,0x2B,0x7F,0xF2,0x11,0x00,0x02,0x77,0x3E,0x3C,0x4F,0xD0,0xF1,0x02, -0x3B,0x7F,0x6C,0x08,0x00,0x02,0x77,0x09,0x84,0x85,0x00,0x00,0x00,0x02,0x47,0x84, -0x4F,0xEF,0xBE,0xED,0xFE,0x85,0x00,0x00,0x00,0x02,0x70,0x3C,0x4F,0xEF,0xBE,0xED, -0xFE,0x85,0x00,0x00,0x00,0x02,0x77,0x09,0x84,0x4F,0x00,0x00,0x20,0x00,0x48,0x84, -0x47,0x85,0x00,0x00,0x00,0x02,0x70,0x84,0x4F,0xA4,0x65,0x00,0x00,0x7F,0xF4,0x11, -0x00,0x02,0x70,0x84,0x4F,0x04,0x65,0x00,0x00,0x7F,0xF8,0x11,0x00,0x02,0x70,0xD0, -0x46,0x48,0x40,0x7B,0x02,0x04,0xC9,0xF8,0x4C,0x20,0x48,0x20,0x47,0x20,0x46,0x20, -0x45,0x20,0x49,0x08,0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x87,0x01,0x7F, -0xF2,0x11,0x00,0x02,0x70,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x10,0x49,0x9C,0x4F, -0x00,0x00,0x00,0x00,0x4C,0x84,0x4F,0x00,0xE1,0x81,0x00,0xCD,0x0C,0x70,0x04,0xC9, -0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x70,0x84,0xCC,0xF8,0x7F,0xFC,0x11,0x00,0x02, -0x70,0x08,0x70,0x70,0x10,0x49,0x9C,0x4F,0xB8,0x01,0x00,0x00,0x4C,0xA0,0x4F,0x0D, -0x30,0x04,0x00,0xE0,0x59,0xA0,0x2D,0x2C,0xCC,0xF4,0x7F,0x24,0x52,0x00,0x00,0xA0, -0x4F,0x2C,0x06,0x00,0x00,0xE0,0x59,0x2C,0xCC,0xF8,0x7F,0xE4,0x44,0x00,0x00,0xA0, -0x00,0x2C,0xCC,0xFC,0xEF,0x40,0x05,0x00,0x00,0xDC,0x02,0x7F,0xA0,0x04,0x00,0x00, -0x40,0xA0,0x40,0x2C,0xCC,0xFC,0x7F,0x60,0x43,0x00,0x00,0x3C,0xFF,0x40,0x77,0x20, -0xA0,0x01,0x2C,0xCC,0xFC,0xEF,0x40,0x05,0x00,0x00,0xA0,0x4F,0x57,0x06,0x00,0x00, -0x2C,0xCC,0xFC,0x7F,0xE4,0x44,0x00,0x00,0x24,0x7F,0xAB,0x3A,0x00,0x00,0xA0,0x01, -0x2C,0xCC,0xFC,0xEF,0x40,0x05,0x00,0x00,0xDC,0x02,0x7F,0xA0,0x04,0x00,0x00,0x40, -0xA0,0x40,0xA0,0x4F,0x59,0x06,0x00,0x00,0x2C,0xCC,0xF8,0x7F,0x68,0x7F,0x00,0x00, -0x28,0x40,0x7F,0x08,0x24,0x7F,0x6B,0x2C,0x00,0x00,0xA0,0x4F,0x60,0x06,0x00,0x00, -0x2C,0xCC,0xFC,0x7F,0xE4,0x44,0x00,0x00,0xE0,0xC9,0x50,0x2C,0xCC,0xFC,0xAF,0x09, -0x0F,0x28,0x40,0x77,0x07,0x2C,0x5C,0xAF,0x59,0x0F,0xA0,0x4F,0x00,0x30,0x04,0x00, -0xE0,0xC9,0x5A,0xA0,0x09,0x2C,0xCC,0xF4,0x7F,0x24,0x52,0x00,0x00,0xE0,0xC9,0x50, -0xE0,0xC9,0x5A,0x2C,0xCC,0xF8,0x7F,0x68,0x7F,0x00,0x00,0x28,0x40,0x7F,0x07,0x2C, -0x5C,0xAF,0x2F,0x0F,0xA0,0x4F,0x76,0x06,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xE4,0x44, -0x00,0x00,0xE0,0x59,0x2C,0xCC,0xFC,0xAF,0xC0,0x0E,0x28,0x40,0x77,0x07,0x2C,0x5C, -0xAF,0x10,0x0F,0xA0,0x4F,0x8C,0x06,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xE4,0x44,0x00, -0x00,0xE0,0xC9,0x50,0x2C,0xCC,0xFC,0xAF,0xA0,0x0E,0x28,0x40,0x77,0x07,0x2C,0x5C, -0xAF,0xF0,0x0E,0xE0,0xC9,0x50,0xE0,0x59,0x2C,0xCC,0xF8,0x7F,0x68,0x7F,0x00,0x00, -0x28,0x40,0x7F,0x07,0x2C,0x5C,0xAF,0xDA,0x0E,0xA0,0x4F,0x9C,0x06,0x00,0x00,0x2C, -0xCC,0xFC,0x7F,0xE4,0x44,0x00,0x00,0xE0,0x59,0xA0,0x4F,0x00,0x30,0x04,0x00,0xE0, -0x59,0x2C,0xCC,0xFC,0x7F,0x98,0x7F,0x00,0x00,0x90,0x40,0xA0,0x40,0x2C,0xCC,0xF4, -0x7F,0xA0,0x52,0x00,0x00,0x24,0x7F,0xA8,0x3A,0x00,0x00,0xDC,0x02,0x7F,0xA0,0x04, -0x00,0x00,0x40,0xA0,0x40,0xA0,0x4F,0x9E,0x06,0x00,0x00,0x2C,0xCC,0xF8,0x7F,0x68, -0x7F,0x00,0x00,0x28,0x40,0x7F,0x08,0x24,0x7F,0x52,0x2D,0x00,0x00,0xA0,0x4F,0xA5, -0x06,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xE4,0x44,0x00,0x00,0x83,0x59,0x70,0x7B,0x26, -0xA0,0x4F,0xEF,0x06,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xE4,0x44,0x00,0x00,0xE0,0x59, -0x2C,0xCC,0xFC,0x7F,0x60,0x43,0x00,0x00,0x3F,0x6F,0x71,0x59,0x77,0x08,0x24,0x7F, -0xAB,0x3A,0x00,0x00,0xE0,0x59,0xA0,0x4F,0xEC,0x06,0x00,0x00,0x2C,0xCC,0xF8,0x7F, -0x68,0x7F,0x00,0x00,0x28,0x40,0x77,0xCA,0xDC,0x03,0x7F,0x08,0x05,0x00,0x00,0x40, -0x87,0x50,0xC9,0x5A,0x70,0xDC,0x07,0x7F,0x08,0x05,0x00,0x00,0x40,0x87,0x50,0xC9, -0x5B,0x70,0xDC,0x0B,0x7F,0x08,0x05,0x00,0x00,0x40,0x87,0x50,0xC9,0x5C,0x70,0xDC, -0x0F,0x7F,0x08,0x05,0x00,0x00,0x40,0x87,0x50,0xC9,0x5D,0x70,0xA0,0x00,0xE0,0xC9, -0x5A,0xA0,0x01,0xA0,0x03,0x2C,0xCC,0xF0,0x7F,0x2C,0x7B,0x00,0x00,0x28,0x40,0x77, -0x1F,0xB0,0x20,0x7F,0x5C,0x08,0x00,0x02,0x70,0x2C,0x5C,0x7F,0xE0,0x5D,0x00,0x00, -0xA0,0x4F,0xEF,0xBE,0xED,0xFE,0x2C,0xCC,0xFC,0x7F,0x22,0x63,0x00,0x00,0xA0,0x4F, -0x27,0x07,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xE4,0x44,0x00,0x00,0x24,0x7F,0xA8,0x3A, -0x00,0x00,0xDC,0x02,0x7F,0xA0,0x04,0x00,0x00,0x40,0xA0,0x40,0xA0,0x4F,0x4A,0x07, -0x00,0x00,0x2C,0xCC,0xF8,0x7F,0x68,0x7F,0x00,0x00,0x28,0x40,0x77,0x1D,0x2C,0x5C, -0x7F,0x00,0x40,0x00,0x02,0xA0,0x4F,0xEF,0xBE,0xED,0xFE,0x2C,0xCC,0xFC,0x7F,0x22, -0x63,0x00,0x00,0x24,0x7F,0xA8,0x3A,0x00,0x00,0xDC,0x02,0x7F,0xA0,0x04,0x00,0x00, -0x40,0xA0,0x40,0xA0,0x4F,0x52,0x07,0x00,0x00,0x2C,0xCC,0xF8,0x7F,0x68,0x7F,0x00, -0x00,0x28,0x40,0x7F,0x08,0x24,0x7F,0x38,0x2E,0x00,0x00,0xA0,0x4F,0x5A,0x07,0x00, -0x00,0xA0,0x4F,0x58,0x11,0x00,0x00,0x2C,0xCC,0xF8,0x7F,0xE4,0x44,0x00,0x00,0xA0, -0x4F,0x68,0x07,0x00,0x00,0xA0,0x7F,0xF0,0x7F,0x00,0x00,0x2C,0xCC,0xF8,0x7F,0xE4, -0x44,0x00,0x00,0xA0,0x4F,0x76,0x07,0x00,0x00,0xA0,0x4F,0x68,0x11,0x00,0x00,0xA0, -0x4F,0x64,0x11,0x00,0x00,0x2C,0xCC,0xF4,0x7F,0xE4,0x44,0x00,0x00,0xA0,0x4F,0x8C, -0x07,0x00,0x00,0x87,0x7F,0xF3,0x7F,0x00,0x00,0xE0,0x40,0xD0,0x08,0x40,0x40,0x87, -0x7F,0xF7,0x7F,0x00,0x00,0xE0,0x41,0xB0,0x41,0x40,0xD0,0x08,0x40,0x40,0x87,0x7F, -0xFB,0x7F,0x00,0x00,0xE0,0x41,0xB0,0x41,0x40,0xD0,0x08,0x40,0x40,0x87,0x7F,0xFF, -0x7F,0x00,0x00,0xE0,0x41,0xB0,0x41,0x40,0xA0,0x40,0x2C,0xCC,0xF8,0x7F,0xE4,0x44, -0x00,0x00,0x24,0x7F,0xA8,0x3A,0x00,0x00,0xDC,0x02,0x7F,0xA0,0x04,0x00,0x00,0x40, -0xA0,0x40,0xA0,0x4F,0xA3,0x07,0x00,0x00,0x2C,0xCC,0xF8,0x7F,0x68,0x7F,0x00,0x00, -0x28,0x40,0x77,0x08,0x24,0x7F,0xAB,0x3A,0x00,0x00,0xDC,0x02,0x7F,0xA0,0x04,0x00, -0x00,0x40,0xA0,0x40,0xA0,0x4F,0xA5,0x07,0x00,0x00,0x2C,0xCC,0xF8,0x7F,0x68,0x7F, -0x00,0x00,0x28,0x40,0x77,0x0F,0x2C,0x5C,0x7F,0x14,0x4E,0x00,0x00,0x24,0x7F,0xA8, -0x3A,0x00,0x00,0xDC,0x02,0x7F,0xA0,0x04,0x00,0x00,0x40,0xA0,0x40,0xA0,0x4F,0xA9, -0x07,0x00,0x00,0x2C,0xCC,0xF8,0x7F,0x68,0x7F,0x00,0x00,0x28,0x40,0x77,0x0F,0x2C, -0x5C,0x7F,0xE6,0x5F,0x00,0x00,0x24,0x7F,0xA8,0x3A,0x00,0x00,0xDC,0x02,0x7F,0xA0, -0x04,0x00,0x00,0x40,0xA0,0x40,0xA0,0x4F,0xB4,0x07,0x00,0x00,0x2C,0xCC,0xF8,0x7F, -0x68,0x7F,0x00,0x00,0x28,0x40,0x77,0x0F,0x2C,0x5C,0x7F,0xCC,0x3F,0x00,0x00,0x24, -0x7F,0xA8,0x3A,0x00,0x00,0xDC,0x02,0x7F,0xA0,0x04,0x00,0x00,0x40,0xA0,0x40,0xA0, -0x4F,0xB9,0x07,0x00,0x00,0x2C,0xCC,0xF8,0x7F,0x68,0x7F,0x00,0x00,0x28,0x40,0x77, -0x32,0xA0,0x4F,0xBB,0x07,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xE4,0x44,0x00,0x00,0xA0, -0x4F,0xF3,0x07,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xE4,0x44,0x00,0x00,0xA0,0x4F,0x24, -0x08,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xE4,0x44,0x00,0x00,0x24,0x7F,0xA8,0x3A,0x00, -0x00,0xDC,0x02,0x7F,0xA0,0x04,0x00,0x00,0x40,0x2B,0x50,0x77,0x16,0xDC,0x02,0x7F, -0xA0,0x04,0x00,0x00,0x40,0xA0,0x40,0xE0,0x59,0x2C,0xCC,0xF8,0x7F,0xB0,0x7F,0x00, -0x00,0x82,0xA9,0xB4,0x00,0x70,0x7B,0x5E,0x04,0xA9,0xB8,0x00,0x40,0x86,0xA9,0xB4, -0x00,0xE4,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x82,0x50,0x70,0x04,0xA9,0xB8, -0x00,0x40,0x86,0xA9,0xB4,0x00,0xE4,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x82, -0xC0,0x02,0x70,0x04,0xA9,0xB8,0x00,0x40,0x86,0xA9,0xB4,0x00,0xE4,0x41,0xD0,0x04, -0x41,0x41,0x9C,0x41,0x40,0x82,0xC0,0x04,0x70,0x04,0xA9,0xB8,0x00,0x40,0x86,0xA9, -0xB4,0x00,0xE4,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x83,0xC0,0x06,0x70,0x92, -0xA9,0xB4,0x00,0x70,0x3E,0x10,0xA9,0xB4,0x00,0x4B,0x9F,0x83,0xA9,0xAC,0x00,0x70, -0x04,0xA9,0xB8,0x00,0x40,0x87,0xA9,0xAC,0x00,0xE0,0x41,0xD0,0x04,0x41,0x41,0x9C, -0x41,0x40,0x9C,0x06,0x40,0xA0,0x40,0xDC,0x08,0x7F,0x90,0x04,0x00,0x00,0x40,0xDC, -0x02,0x50,0x40,0xA0,0x40,0x2C,0xCC,0xF8,0x7F,0xB0,0x7F,0x00,0x00,0x04,0xA9,0xB8, -0x00,0x40,0x87,0xA9,0xAC,0x00,0xE0,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x86, -0x01,0xC0,0x02,0x70,0x04,0xA9,0xB8,0x00,0x40,0x87,0xA9,0xAC,0x00,0x41,0x93,0xA9, -0xAC,0x00,0x70,0x87,0x41,0xE0,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x82,0x50, -0x70,0x87,0x7F,0x60,0x08,0x00,0x02,0xE0,0x40,0x24,0x7F,0xB5,0x31,0x00,0x00,0x04, -0xA9,0xB8,0x00,0x40,0x87,0xA9,0xAC,0x00,0xE0,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41, -0x40,0x9C,0x06,0x40,0xA0,0x40,0xDC,0x08,0x7F,0x90,0x04,0x00,0x00,0x40,0xDC,0x0E, -0x50,0x40,0xA0,0x40,0x2C,0xCC,0xF8,0x7F,0xB0,0x7F,0x00,0x00,0x04,0xA9,0xB8,0x00, -0x40,0x87,0xA9,0xAC,0x00,0xE0,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x86,0x01, -0xC0,0x02,0x70,0x04,0xA9,0xB8,0x00,0x40,0x87,0xA9,0xAC,0x00,0x41,0x93,0xA9,0xAC, -0x00,0x70,0x87,0x41,0xE0,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x86,0x01,0x50, -0x70,0x24,0x7F,0xC7,0x31,0x00,0x00,0x04,0xA9,0xB8,0x00,0x40,0x87,0xA9,0xAC,0x00, -0xE0,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x9C,0x06,0x40,0xA0,0x40,0xDC,0x08, -0x7F,0x90,0x04,0x00,0x00,0x40,0xDC,0x1A,0x50,0x40,0xA0,0x40,0x2C,0xCC,0xF8,0x7F, -0xB0,0x7F,0x00,0x00,0x04,0xA9,0xB8,0x00,0x40,0x87,0xA9,0xAC,0x00,0xE0,0x41,0xD0, -0x04,0x41,0x41,0x9C,0x41,0x40,0x86,0x01,0xC0,0x02,0x70,0x04,0xA9,0xB8,0x00,0x40, -0x87,0xA9,0xAC,0x00,0x41,0x93,0xA9,0xAC,0x00,0x70,0x87,0x41,0xE0,0x41,0xD0,0x04, -0x41,0x41,0x9C,0x41,0x40,0x86,0x02,0x50,0x70,0x24,0x7F,0xC7,0x31,0x00,0x00,0x04, -0xA9,0xB8,0x00,0x40,0x87,0xA9,0xAC,0x00,0xE0,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41, -0x40,0x9C,0x06,0x40,0xA0,0x40,0xDC,0x08,0x7F,0x90,0x04,0x00,0x00,0x40,0xDC,0x0E, -0x50,0x40,0xA0,0x40,0x2C,0xCC,0xF8,0x7F,0xB0,0x7F,0x00,0x00,0x04,0xA9,0xB8,0x00, -0x40,0x87,0xA9,0xAC,0x00,0xE0,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x86,0x01, -0xC0,0x02,0x70,0x04,0xA9,0xB8,0x00,0x40,0x87,0xA9,0xAC,0x00,0x41,0x93,0xA9,0xAC, -0x00,0x70,0x87,0x41,0xE0,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x86,0x01,0x50, -0x70,0x04,0xA9,0xB8,0x00,0x40,0x87,0xA9,0xAC,0x00,0xE0,0x41,0xD0,0x04,0x41,0x41, -0x9C,0x41,0x40,0x9C,0x06,0x40,0xA0,0x40,0xDC,0x08,0x7F,0x90,0x04,0x00,0x00,0x40, -0xDC,0x1A,0x50,0x40,0xA0,0x40,0x2C,0xCC,0xF8,0x7F,0xB0,0x7F,0x00,0x00,0x04,0xA9, -0xB8,0x00,0x40,0x87,0xA9,0xAC,0x00,0xE0,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40, -0x86,0x01,0xC0,0x02,0x70,0x04,0xA9,0xB8,0x00,0x40,0x87,0xA9,0xAC,0x00,0x41,0x93, -0xA9,0xAC,0x00,0x70,0x87,0x41,0xE0,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x86, -0x02,0x50,0x70,0x7B,0x14,0x3C,0x40,0x01,0x7E,0x67,0xFE,0x3C,0x40,0x02,0x7E,0xC9, -0xFE,0x3C,0x40,0x03,0x7E,0x2B,0xFF,0x86,0x01,0xA9,0xB4,0x00,0x70,0x24,0x7F,0x39, -0x33,0x00,0x00,0x86,0xA9,0xB4,0x00,0xE4,0x40,0xD0,0x05,0x40,0x40,0x9C,0x7F,0x90, -0x04,0x00,0x00,0x40,0xCC,0x00,0x07,0xC0,0x04,0x40,0x3C,0x00,0x40,0x77,0x08,0x24, -0x7F,0x93,0x32,0x00,0x00,0x04,0xA9,0xB8,0x00,0x40,0x87,0xA9,0xAC,0x00,0xE0,0x41, -0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x9C,0x06,0x40,0xA0,0x40,0x86,0xA9,0xB4,0x00, -0xE4,0x40,0xD0,0x05,0x40,0x40,0x9C,0x7F,0x90,0x04,0x00,0x00,0x40,0x9C,0x0C,0x40, -0xA0,0x40,0x2C,0xCC,0xF8,0x7F,0xB0,0x7F,0x00,0x00,0x04,0xA9,0xB8,0x00,0x40,0x87, -0xA9,0xAC,0x00,0xE0,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x82,0xC0,0x02,0x70, -0x04,0xA9,0xB8,0x00,0x40,0x87,0xA9,0xAC,0x00,0xE0,0x41,0xD0,0x04,0x41,0x41,0x9C, -0x41,0x40,0x86,0xA9,0xB4,0x00,0xE4,0x41,0xD0,0x05,0x41,0x41,0x9C,0x7F,0x90,0x04, -0x00,0x00,0x41,0xCC,0x03,0x0C,0x51,0x41,0x86,0x41,0xC0,0x04,0x70,0x04,0xA9,0xB8, -0x00,0x40,0x87,0xA9,0xAC,0x00,0x41,0x93,0xA9,0xAC,0x00,0x70,0x87,0x41,0xE0,0x41, -0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x86,0xA9,0xB4,0x00,0x50,0x70,0x24,0x7F,0x34, -0x33,0x00,0x00,0x86,0xA9,0xB4,0x00,0xE4,0x40,0xD0,0x05,0x40,0x40,0x9C,0x7F,0x90, -0x04,0x00,0x00,0x40,0x2B,0xC0,0x0C,0x7F,0x2A,0x86,0xA9,0xB4,0x00,0xE4,0x40,0xD0, -0x05,0x40,0x40,0x9C,0x7F,0x90,0x04,0x00,0x00,0x40,0x9C,0x0C,0x40,0xA0,0x40,0xA0, -0x4F,0x66,0x08,0x00,0x00,0x2C,0xCC,0xF8,0x7F,0x68,0x7F,0x00,0x00,0x28,0x40,0x77, -0x65,0x04,0xA9,0xB8,0x00,0x40,0x87,0xA9,0xAC,0x00,0xE0,0x41,0xD0,0x04,0x41,0x41, -0x9C,0x41,0x40,0x82,0xC0,0x02,0x70,0x04,0xA9,0xB8,0x00,0x40,0x87,0xA9,0xAC,0x00, -0xE0,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x86,0xA9,0xB4,0x00,0xE4,0x41,0xD0, -0x05,0x41,0x41,0x9C,0x7F,0x90,0x04,0x00,0x00,0x41,0xCC,0x03,0x0C,0x51,0x41,0x86, -0x41,0xC0,0x04,0x70,0x04,0xA9,0xB8,0x00,0x40,0x87,0xA9,0xAC,0x00,0x41,0x93,0xA9, -0xAC,0x00,0x70,0x87,0x41,0xE0,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x86,0xA9, -0xB4,0x00,0x50,0x70,0x92,0xA9,0xB4,0x00,0x70,0x86,0xA9,0xB4,0x00,0xE4,0x40,0x87, -0xEF,0xE0,0x04,0x00,0x00,0xE0,0x41,0x3C,0x41,0x40,0x4A,0x89,0xFE,0xA0,0x4F,0x6D, -0x08,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xE4,0x44,0x00,0x00,0xA0,0x4F,0x8B,0x08,0x00, -0x00,0x2C,0xCC,0xFC,0x7F,0xE4,0x44,0x00,0x00,0xA0,0x4F,0xAB,0x08,0x00,0x00,0x2C, -0xCC,0xFC,0x7F,0xE4,0x44,0x00,0x00,0x82,0xA9,0xB4,0x00,0x70,0x24,0x7F,0x13,0x34, -0x00,0x00,0xA0,0x4F,0xD4,0x08,0x00,0x00,0x86,0xA9,0xB4,0x00,0xE4,0x40,0xA0,0x40, -0x04,0xA9,0xB8,0x00,0x40,0x86,0xA9,0xB4,0x00,0xE4,0x41,0xD0,0x04,0x41,0x41,0x9C, -0x41,0x40,0x86,0xE2,0xC0,0x04,0xE0,0x40,0xA0,0x40,0x2C,0xCC,0xF4,0x7F,0xE4,0x44, -0x00,0x00,0x04,0xA9,0xB8,0x00,0x40,0x86,0xA9,0xB4,0x00,0xE4,0x41,0xD0,0x04,0x41, -0x41,0x9C,0x41,0x40,0x9C,0x06,0x40,0xA0,0x40,0xA0,0x4F,0xEA,0x08,0x00,0x00,0x2C, -0xCC,0xF8,0x7F,0x68,0x7F,0x00,0x00,0x28,0x40,0x7F,0x27,0xA0,0x4F,0xF1,0x08,0x00, -0x00,0x04,0xA9,0xB8,0x00,0x40,0x86,0xA9,0xB4,0x00,0xE4,0x41,0xD0,0x04,0x41,0x41, -0x9C,0x41,0x40,0x9C,0x06,0x40,0xA0,0x40,0x2C,0xCC,0xF8,0x7F,0xE4,0x44,0x00,0x00, -0xA0,0x4F,0xFB,0x08,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xE4,0x44,0x00,0x00,0x92,0xA9, -0xB4,0x00,0x70,0x86,0xA9,0xB4,0x00,0xE4,0x40,0x87,0xA9,0xAC,0x00,0xE0,0x41,0x3C, -0x41,0x40,0x5A,0x60,0xFF,0xA0,0x4F,0x0C,0x30,0x04,0x00,0xDC,0x01,0x7F,0xA0,0x04, -0x00,0x00,0x40,0xA0,0x40,0xA0,0x01,0x2C,0xCC,0xF4,0x7F,0x24,0x52,0x00,0x00,0x83, -0xA9,0xAA,0x00,0x70,0x82,0xA9,0xB4,0x00,0x70,0x24,0x7F,0xD5,0x34,0x00,0x00,0x04, -0xA9,0xB8,0x00,0x40,0x86,0xA9,0xB4,0x00,0xE4,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41, -0x40,0x86,0xE2,0xC0,0x02,0xE0,0x40,0x7F,0x34,0xDC,0x01,0x7F,0xA0,0x04,0x00,0x00, -0x40,0x87,0x50,0xE0,0x40,0x04,0xA9,0xB8,0x00,0x41,0x86,0xA9,0xB4,0x00,0xE4,0x42, -0xD0,0x04,0x42,0x42,0x9C,0x42,0x41,0x86,0xE2,0x51,0xE0,0x41,0x3C,0x41,0x40,0x77, -0x0A,0x87,0x01,0xA9,0xAA,0x00,0x70,0x7B,0x50,0x7B,0x37,0x04,0xA9,0xB8,0x00,0x40, -0x86,0xA9,0xB4,0x00,0xE4,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x86,0xE2,0xC0, -0x04,0xE0,0x40,0xDC,0x01,0x7F,0xA0,0x04,0x00,0x00,0x41,0x87,0x51,0xE0,0x41,0xD4, -0x04,0x41,0x41,0x3C,0x41,0x40,0x77,0x0A,0x87,0x01,0xA9,0xAA,0x00,0x70,0x7B,0x19, -0x92,0xA9,0xB4,0x00,0x70,0x86,0xA9,0xB4,0x00,0xE4,0x40,0x87,0xA9,0xAC,0x00,0xE0, -0x41,0x3C,0x41,0x40,0x5A,0x6B,0xFF,0x2B,0xA9,0xAA,0x00,0x77,0x09,0x83,0xA9,0xAF, -0x00,0x70,0x7B,0x0A,0x87,0xA9,0xB5,0x00,0xA9,0xAF,0x00,0x70,0xA0,0x4F,0xFD,0x08, -0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xE4,0x44,0x00,0x00,0xA0,0x4F,0x1F,0x09,0x00,0x00, -0x87,0xA9,0xAF,0x00,0xE0,0x40,0xA0,0x40,0x2C,0xCC,0xF8,0x7F,0xE4,0x44,0x00,0x00, -0x04,0xA9,0xB8,0x00,0x40,0x87,0xA9,0xAF,0x00,0xE0,0x41,0xD0,0x04,0x41,0x41,0x9C, -0x41,0x40,0x9C,0x06,0x40,0xA0,0x40,0xA0,0x4F,0x23,0x09,0x00,0x00,0x2C,0xCC,0xF8, -0x7F,0x68,0x7F,0x00,0x00,0x28,0x40,0x7F,0x27,0xA0,0x4F,0x2A,0x09,0x00,0x00,0x04, -0xA9,0xB8,0x00,0x40,0x87,0xA9,0xAF,0x00,0xE0,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41, -0x40,0x9C,0x06,0x40,0xA0,0x40,0x2C,0xCC,0xF8,0x7F,0xE4,0x44,0x00,0x00,0xA0,0x4F, -0x30,0x09,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xE4,0x44,0x00,0x00,0xA0,0x00,0x2C,0xCC, -0xFC,0xEF,0x40,0x05,0x00,0x00,0xE0,0xC9,0x5A,0x2C,0xCC,0xFC,0x7F,0x60,0x43,0x00, -0x00,0x3C,0xFF,0x40,0x77,0x20,0xA0,0x01,0x2C,0xCC,0xFC,0xEF,0x40,0x05,0x00,0x00, -0xA0,0x4F,0x34,0x09,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xE4,0x44,0x00,0x00,0x24,0x7F, -0xAB,0x3A,0x00,0x00,0xA0,0x01,0x2C,0xCC,0xFC,0xEF,0x40,0x05,0x00,0x00,0x83,0xA9, -0xAA,0x00,0x70,0x2B,0xC9,0x5A,0x7F,0x5F,0x82,0xA9,0xB4,0x00,0x70,0x7B,0x23,0xE0, -0xC9,0x5A,0x2C,0xCC,0xFC,0xAF,0x68,0x05,0x86,0xA9,0xB4,0x00,0xE4,0x41,0x3C,0x40, -0x41,0x77,0x0A,0x87,0x01,0xA9,0xAA,0x00,0x70,0x7B,0x18,0x92,0xA9,0xB4,0x00,0x70, -0x86,0xA9,0xB4,0x00,0xE4,0x40,0x87,0xA9,0xAC,0x00,0xE0,0x41,0x3C,0x41,0x40,0x5B, -0xD0,0x2B,0xA9,0xAA,0x00,0x77,0x16,0xA0,0x4F,0x36,0x09,0x00,0x00,0xE0,0xC9,0x5A, -0x2C,0xCC,0xF8,0x7F,0xE4,0x44,0x00,0x00,0x7A,0xE4,0xFE,0x87,0xA9,0xB5,0x00,0xA9, -0xAE,0x00,0x70,0x7B,0x0A,0x87,0xA9,0xAF,0x00,0xA9,0xAE,0x00,0x70,0x04,0xA9,0xB8, -0x00,0x40,0x87,0xA9,0xAE,0x00,0xE0,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x86, -0xE2,0xC0,0x02,0xE0,0x40,0x7F,0x27,0xDC,0x01,0x7F,0xA0,0x04,0x00,0x00,0x40,0x04, -0xA9,0xB8,0x00,0x41,0x87,0xA9,0xAE,0x00,0xE0,0x42,0xD0,0x04,0x42,0x42,0x9C,0x42, -0x41,0x87,0xC1,0x01,0x50,0x70,0x24,0x7F,0x78,0x3A,0x00,0x00,0x3F,0xA9,0xAF,0x00, -0xA9,0xAE,0x00,0x77,0x16,0xDC,0x01,0x7F,0xA0,0x04,0x00,0x00,0x40,0xFB,0x0F,0x50, -0x40,0x87,0x40,0xA9,0xAD,0x00,0x70,0x7B,0x07,0x83,0xA9,0xAD,0x00,0x70,0xDC,0x01, -0x7F,0xA0,0x04,0x00,0x00,0x40,0x04,0xA9,0xB8,0x00,0x41,0x87,0xA9,0xAE,0x00,0xE0, -0x42,0xD0,0x04,0x42,0x42,0x9C,0x42,0x41,0x86,0xE2,0xC1,0x04,0xE0,0x41,0xD0,0x04, -0x41,0x41,0x87,0x41,0x50,0x70,0x04,0xA9,0xB8,0x00,0x40,0x87,0xA9,0xAE,0x00,0xE0, -0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x86,0x50,0xA9,0xB4,0x00,0x70,0x82,0xA9, -0xB6,0x00,0x70,0x7B,0x5E,0x04,0xA9,0xB8,0x00,0x40,0x86,0xA9,0xB6,0x00,0xE4,0x41, -0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x82,0x50,0x70,0x04,0xA9,0xB8,0x00,0x40,0x86, -0xA9,0xB6,0x00,0xE4,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x82,0xC0,0x02,0x70, -0x04,0xA9,0xB8,0x00,0x40,0x86,0xA9,0xB6,0x00,0xE4,0x41,0xD0,0x04,0x41,0x41,0x9C, -0x41,0x40,0x82,0xC0,0x04,0x70,0x04,0xA9,0xB8,0x00,0x40,0x86,0xA9,0xB6,0x00,0xE4, -0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x83,0xC0,0x06,0x70,0x92,0xA9,0xB6,0x00, -0x70,0x3E,0x10,0xA9,0xB6,0x00,0x4B,0x9F,0x87,0x01,0xA9,0xAB,0x00,0x70,0x86,0xA9, -0xB4,0x00,0xE4,0x40,0xD0,0x05,0x40,0x40,0x9C,0x7F,0x90,0x04,0x00,0x00,0x40,0xCC, -0x03,0x00,0xC0,0x04,0x40,0x87,0x40,0xA9,0xAC,0x00,0x70,0x2B,0xA9,0xAC,0x00,0x77, -0x0D,0x87,0x0F,0xA9,0xAC,0x00,0x70,0x83,0xA9,0xAB,0x00,0x70,0x82,0xA9,0xB6,0x00, -0x70,0x7B,0x60,0x04,0xA9,0xB8,0x00,0x40,0x86,0xA9,0xB6,0x00,0xE4,0x41,0xD0,0x04, -0x41,0x41,0x9C,0x41,0x40,0x9C,0x06,0x40,0xA0,0x40,0x86,0xA9,0xB4,0x00,0xE4,0x40, -0xD0,0x05,0x40,0x40,0x9C,0x7F,0x90,0x04,0x00,0x00,0x40,0xEA,0x0C,0xA9,0xB6,0x00, -0x41,0xDC,0x41,0xC0,0x08,0x40,0x9C,0x02,0x40,0xA0,0x40,0x2C,0xCC,0xF8,0x7F,0xB0, -0x7F,0x00,0x00,0x04,0xA9,0xB8,0x00,0x40,0x86,0xA9,0xB6,0x00,0xE4,0x41,0xD0,0x04, -0x41,0x41,0x9C,0x41,0x40,0x86,0xA9,0xB6,0x00,0xC0,0x04,0x70,0x92,0xA9,0xB6,0x00, -0x70,0x86,0xA9,0xB6,0x00,0xE4,0x40,0x87,0xA9,0xAC,0x00,0xE0,0x41,0x3C,0x41,0x40, -0x5B,0x93,0xA0,0x4F,0x59,0x09,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xE4,0x44,0x00,0x00, -0xA0,0x4F,0x74,0x09,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xE4,0x44,0x00,0x00,0xA0,0x4F, -0x97,0x09,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xE4,0x44,0x00,0x00,0x82,0xA9,0xB6,0x00, -0x70,0x24,0x7F,0xAE,0x38,0x00,0x00,0xA0,0x4F,0xC5,0x09,0x00,0x00,0x86,0xA9,0xB6, -0x00,0xE4,0x40,0xA0,0x40,0x04,0xA9,0xB8,0x00,0x40,0x86,0xA9,0xB6,0x00,0xE4,0x41, -0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x86,0xE2,0xC0,0x04,0xE0,0x40,0xA0,0x40,0x2C, -0xCC,0xF4,0x7F,0xE4,0x44,0x00,0x00,0x04,0xA9,0xB8,0x00,0x40,0x86,0xA9,0xB6,0x00, -0xE4,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x9C,0x06,0x40,0xA0,0x40,0xA0,0x4F, -0xDC,0x09,0x00,0x00,0x2C,0xCC,0xF8,0x7F,0x68,0x7F,0x00,0x00,0x28,0x40,0x7F,0x2D, -0x2B,0xA9,0xAB,0x00,0x7F,0x27,0xA0,0x4F,0xE3,0x09,0x00,0x00,0x04,0xA9,0xB8,0x00, -0x40,0x86,0xA9,0xB6,0x00,0xE4,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x9C,0x06, -0x40,0xA0,0x40,0x2C,0xCC,0xF8,0x7F,0xE4,0x44,0x00,0x00,0xA0,0x4F,0xF1,0x09,0x00, -0x00,0x2C,0xCC,0xFC,0x7F,0xE4,0x44,0x00,0x00,0x92,0xA9,0xB6,0x00,0x70,0x86,0xA9, -0xB6,0x00,0xE4,0x40,0x87,0xA9,0xAC,0x00,0xE0,0x41,0x3C,0x41,0x40,0x5A,0x5A,0xFF, -0x83,0xA9,0xAA,0x00,0x70,0x82,0xA9,0xB6,0x00,0x70,0x7B,0x32,0x04,0xA9,0xB8,0x00, -0x40,0x86,0xA9,0xB6,0x00,0xE4,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x86,0xE2, -0xC0,0x04,0xE0,0x40,0x87,0xA9,0xAD,0x00,0xE0,0x41,0x3C,0x41,0x40,0x77,0x0A,0x87, -0x01,0xA9,0xAA,0x00,0x70,0x7B,0x18,0x92,0xA9,0xB6,0x00,0x70,0x86,0xA9,0xB6,0x00, -0xE4,0x40,0x87,0xA9,0xAC,0x00,0xE0,0x41,0x3C,0x41,0x40,0x5B,0xC1,0x2B,0xA9,0xAA, -0x00,0x77,0x09,0x83,0xA9,0xAF,0x00,0x70,0x7B,0x0A,0x87,0xA9,0xB7,0x00,0xA9,0xAF, -0x00,0x70,0xA0,0x4F,0xF3,0x09,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xE4,0x44,0x00,0x00, -0xA0,0x4F,0x13,0x0A,0x00,0x00,0x87,0xA9,0xAF,0x00,0xE0,0x40,0xA0,0x40,0x2C,0xCC, -0xF8,0x7F,0xE4,0x44,0x00,0x00,0x04,0xA9,0xB8,0x00,0x40,0x87,0xA9,0xAF,0x00,0xE0, -0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x9C,0x06,0x40,0xA0,0x40,0xA0,0x4F,0x17, -0x0A,0x00,0x00,0x2C,0xCC,0xF8,0x7F,0x68,0x7F,0x00,0x00,0x28,0x40,0x7F,0x2D,0x2B, -0xA9,0xAB,0x00,0x7F,0x27,0xA0,0x4F,0x1E,0x0A,0x00,0x00,0x04,0xA9,0xB8,0x00,0x40, -0x87,0xA9,0xAF,0x00,0xE0,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x9C,0x06,0x40, -0xA0,0x40,0x2C,0xCC,0xF8,0x7F,0xE4,0x44,0x00,0x00,0xA0,0x4F,0x23,0x0A,0x00,0x00, -0x2C,0xCC,0xFC,0x7F,0xE4,0x44,0x00,0x00,0xA0,0x00,0x2C,0xCC,0xFC,0xEF,0x40,0x05, -0x00,0x00,0xE0,0xC9,0x5A,0x2C,0xCC,0xFC,0x7F,0x60,0x43,0x00,0x00,0x3C,0xFF,0x40, -0x77,0x20,0xA0,0x01,0x2C,0xCC,0xFC,0xEF,0x40,0x05,0x00,0x00,0xA0,0x4F,0x27,0x0A, -0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xE4,0x44,0x00,0x00,0x24,0x7F,0xAB,0x3A,0x00,0x00, -0xA0,0x01,0x2C,0xCC,0xFC,0xEF,0x40,0x05,0x00,0x00,0x83,0xA9,0xAA,0x00,0x70,0x2B, -0xC9,0x5A,0x7F,0x5F,0x82,0xA9,0xB6,0x00,0x70,0x7B,0x23,0xE0,0xC9,0x5A,0x2C,0xCC, -0xFC,0xAF,0x3C,0x01,0x86,0xA9,0xB6,0x00,0xE4,0x41,0x3C,0x40,0x41,0x77,0x0A,0x87, -0x01,0xA9,0xAA,0x00,0x70,0x7B,0x18,0x92,0xA9,0xB6,0x00,0x70,0x86,0xA9,0xB6,0x00, -0xE4,0x40,0x87,0xA9,0xAC,0x00,0xE0,0x41,0x3C,0x41,0x40,0x5B,0xD0,0x2B,0xA9,0xAA, -0x00,0x77,0x16,0xA0,0x4F,0x29,0x0A,0x00,0x00,0xE0,0xC9,0x5A,0x2C,0xCC,0xF8,0x7F, -0xE4,0x44,0x00,0x00,0x7A,0xDE,0xFE,0x87,0xA9,0xB7,0x00,0xA9,0xAE,0x00,0x70,0x7B, -0x0A,0x87,0xA9,0xAF,0x00,0xA9,0xAE,0x00,0x70,0xDC,0x01,0x7F,0xA0,0x04,0x00,0x00, -0x40,0x04,0xA9,0xB8,0x00,0x41,0x87,0xA9,0xAE,0x00,0xE0,0x42,0xD0,0x04,0x42,0x42, -0x9C,0x42,0x41,0xB3,0xC1,0x05,0x50,0x70,0x87,0x01,0xEF,0xA0,0x04,0x00,0x00,0x70, -0x2C,0x5C,0x7F,0x70,0x69,0x00,0x00,0x28,0x40,0x77,0x1F,0xB0,0x04,0x7F,0x5C,0x08, -0x00,0x02,0x70,0x2C,0x5C,0x7F,0xE0,0x5D,0x00,0x00,0xA0,0x4F,0xEF,0xBE,0xED,0xFE, -0x2C,0xCC,0xFC,0x7F,0x22,0x63,0x00,0x00,0x7A,0x65,0xF0,0x04,0xC9,0xE8,0x4C,0x20, -0x49,0x08,0x70,0x70,0x10,0x49,0x9C,0x4F,0x04,0x00,0x00,0x00,0x4C,0x82,0x59,0x70, -0x7B,0x37,0x7B,0x02,0x2C,0x5C,0x7F,0x84,0x44,0x00,0x00,0x87,0x40,0xDA,0x00,0x70, -0x2B,0x40,0x7F,0xF2,0x3F,0x0D,0xDA,0x00,0x7F,0x08,0x3F,0x0A,0xDA,0x00,0x77,0x13, -0x2A,0x59,0x77,0x06,0x80,0x40,0x7B,0x1F,0x83,0xDA,0x00,0x70,0x84,0x01,0x40,0x7B, -0x16,0x90,0x5A,0x70,0x92,0x59,0x70,0x3E,0x08,0x59,0x4B,0xC8,0x83,0xDA,0x00,0x70, -0x84,0x01,0x40,0x7B,0x02,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x10,0x49, -0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0xA0,0x4F,0x4C,0x0A,0x00,0x00,0x2C,0xCC,0xFC, -0x7F,0xE4,0x44,0x00,0x00,0xA0,0x4F,0x1E,0xAC,0xEB,0xAD,0x2C,0xCC,0xFC,0x7F,0x22, -0x63,0x00,0x00,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x10,0x49,0x9C,0x4F,0x08,0x00, -0x00,0x00,0x4C,0x82,0x64,0x70,0x86,0x64,0x62,0x70,0x7B,0x29,0x3F,0x30,0x59,0x4B, -0x14,0x3F,0x39,0x59,0x47,0x0F,0x87,0x59,0xE2,0x40,0xBE,0x30,0x40,0x86,0x40,0x64, -0x70,0x7B,0x07,0x84,0xFF,0x40,0x7B,0x21,0xEA,0x0A,0x62,0x40,0x9E,0x64,0x40,0x86, -0x40,0x62,0x70,0x84,0x5A,0x40,0x90,0x5A,0x70,0x87,0x50,0x59,0x70,0x2B,0x59,0x77, -0xCD,0x86,0x62,0xE4,0x40,0x7B,0x02,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70, -0x10,0x49,0x9C,0x4F,0x04,0x00,0x00,0x00,0x4C,0xDC,0x04,0x7F,0xA4,0x04,0x00,0x00, -0x40,0x83,0x50,0x70,0xA0,0x4F,0x09,0x30,0x04,0x00,0xDC,0x03,0x7F,0xA4,0x04,0x00, -0x00,0x40,0xA0,0x40,0xA0,0x01,0x2C,0xCC,0xF4,0x7F,0x24,0x52,0x00,0x00,0x3C,0x01, -0x40,0x77,0x51,0xDC,0x02,0x7F,0xA4,0x04,0x00,0x00,0x40,0xDC,0x03,0x7F,0xA4,0x04, -0x00,0x00,0x41,0xFB,0x5F,0xF0,0x00,0x51,0x41,0xD4,0x04,0x41,0x41,0x87,0x41,0x50, -0x70,0xDC,0x03,0x7F,0xA4,0x04,0x00,0x00,0x40,0xBB,0x0F,0x50,0x70,0x3C,0x4F,0x00, -0x80,0x00,0x00,0x7F,0x08,0x05,0x00,0x00,0x4F,0x18,0xDC,0x03,0x7F,0xA4,0x04,0x00, -0x00,0x40,0x83,0x50,0x70,0xDC,0x02,0x7F,0xA4,0x04,0x00,0x00,0x40,0x83,0x50,0x70, -0x7B,0x18,0xDC,0x02,0x7F,0xA4,0x04,0x00,0x00,0x40,0x83,0x50,0x70,0xDC,0x03,0x7F, -0xA4,0x04,0x00,0x00,0x40,0x83,0x50,0x70,0xA0,0x4F,0x80,0x30,0x04,0x00,0xE0,0x59, -0xA0,0x02,0x2C,0xCC,0xF4,0x7F,0x24,0x52,0x00,0x00,0x28,0x40,0x7F,0x09,0x86,0xE2, -0x59,0xE0,0x40,0x77,0x1A,0x86,0x5F,0xBD,0x04,0x59,0x70,0xE0,0x59,0xA0,0x4F,0x80, -0x30,0x04,0x00,0xA0,0x02,0x2C,0xCC,0xF4,0x7F,0xA0,0x52,0x00,0x00,0x86,0x59,0xEF, -0xA4,0x04,0x00,0x00,0x70,0xDC,0x02,0x7F,0xA4,0x04,0x00,0x00,0x40,0x2B,0x50,0x7F, -0x08,0x86,0x5F,0xBD,0x04,0x59,0x70,0x86,0xE2,0x59,0xE0,0x40,0xA0,0x40,0xA0,0x4F, -0x00,0x90,0x04,0x00,0x2C,0xCC,0xF8,0x7F,0x84,0x3E,0x00,0x00,0xDC,0x02,0x7F,0xA4, -0x04,0x00,0x00,0x40,0x2B,0x50,0x77,0x19,0xDC,0x03,0x7F,0xA4,0x04,0x00,0x00,0x40, -0x3F,0x01,0x50,0x77,0x0C,0x86,0xEF,0xA4,0x04,0x00,0x00,0x59,0x70,0x7B,0x35,0xA0, -0x4F,0x0A,0x30,0x04,0x00,0xE0,0x59,0xA0,0x02,0x2C,0xCC,0xF4,0x7F,0x24,0x52,0x00, -0x00,0x28,0x40,0x7F,0x09,0x86,0xE2,0x59,0xE0,0x40,0x77,0x18,0x86,0x3D,0x59,0x70, -0xE0,0x59,0xA0,0x4F,0x0A,0x30,0x04,0x00,0xA0,0x02,0x2C,0xCC,0xF4,0x7F,0xA0,0x52, -0x00,0x00,0x86,0xE2,0x59,0xE0,0x40,0xA0,0x40,0xA0,0x4F,0x08,0x90,0x04,0x00,0x2C, -0xCC,0xF8,0x7F,0x84,0x3E,0x00,0x00,0xDC,0x02,0x7F,0xA4,0x04,0x00,0x00,0x40,0x2B, -0x50,0x77,0x6B,0xDC,0x03,0x7F,0xA4,0x04,0x00,0x00,0x40,0x2B,0x50,0x77,0x0E,0x8B, -0x7F,0x0D,0x90,0x04,0x00,0x40,0x38,0x40,0x01,0x77,0x1B,0xDC,0x03,0x7F,0xA4,0x04, -0x00,0x00,0x40,0x3F,0x01,0x50,0x77,0x46,0x8B,0x7F,0x0D,0x90,0x04,0x00,0x40,0x38, -0x40,0x02,0x7F,0x3A,0xDC,0x04,0x7F,0xA4,0x04,0x00,0x00,0x40,0x87,0x01,0x50,0x70, -0xDC,0x03,0x7F,0xA4,0x04,0x00,0x00,0x40,0x2B,0x50,0x7F,0x13,0x84,0x4F,0x08,0x90, -0x04,0x00,0x40,0x84,0x40,0xEF,0xFC,0x04,0x00,0x00,0x70,0x7B,0x11,0x84,0x4F,0x00, -0x90,0x04,0x00,0x40,0x84,0x40,0xEF,0xFC,0x04,0x00,0x00,0x70,0x04,0xC9,0xE8,0x4C, -0x20,0x49,0x08,0x70,0x10,0x48,0x9C,0x4F,0x04,0x00,0x00,0x00,0x4C,0x86,0x01,0x48, -0x7B,0x23,0x3E,0x10,0x48,0x5B,0x1C,0xA0,0x4F,0xD8,0x0A,0x00,0x00,0x86,0x72,0xE4, -0x40,0xA0,0x40,0x2C,0xCC,0xF8,0x7F,0xE4,0x44,0x00,0x00,0x24,0x7F,0x7A,0x3E,0x00, -0x00,0x92,0x48,0x86,0x48,0xE4,0x40,0xD0,0x03,0x40,0x40,0x3E,0x72,0x80,0x58,0x0A, -0x00,0x00,0x77,0xD0,0x3C,0x4F,0x08,0x90,0x04,0x00,0x74,0x77,0x31,0x86,0x48,0xE4, -0x40,0xD0,0x03,0x40,0x40,0x87,0x80,0x5A,0x0A,0x00,0x00,0xE2,0x40,0xB2,0x30,0x40, -0x86,0x40,0x59,0x70,0xE0,0x59,0xA0,0x4F,0x0A,0x30,0x04,0x00,0xA0,0x02,0x2C,0xCC, -0xF4,0x7F,0xA0,0x52,0x00,0x00,0x24,0x7F,0x6B,0x3E,0x00,0x00,0xA0,0x4F,0x80,0x30, -0x04,0x00,0xE0,0x59,0xA0,0x02,0x2C,0xCC,0xF4,0x7F,0x24,0x52,0x00,0x00,0x86,0xE2, -0x59,0xE0,0x40,0x7F,0x38,0x86,0xE2,0x59,0xE0,0x40,0x84,0x4F,0xF0,0xFF,0x00,0x00, -0x41,0x86,0xE2,0x41,0xE0,0x41,0xB8,0x41,0x40,0x86,0x40,0x59,0x70,0x86,0xE2,0x59, -0xE0,0x40,0x86,0x48,0xE4,0x41,0xD0,0x03,0x41,0x41,0x87,0x81,0x5A,0x0A,0x00,0x00, -0xE0,0x41,0xB0,0x41,0x40,0x86,0x40,0x59,0x70,0x7B,0x20,0x86,0x48,0xE4,0x40,0xD0, -0x03,0x40,0x40,0x87,0x80,0x5A,0x0A,0x00,0x00,0xE2,0x40,0xB2,0x5F,0x30,0x04,0x40, -0xB2,0x5F,0x80,0x00,0x40,0x86,0x40,0x59,0x70,0xE0,0x59,0xA0,0x4F,0x80,0x30,0x04, -0x00,0xA0,0x02,0x2C,0xCC,0xF4,0x7F,0xA0,0x52,0x00,0x00,0x86,0xE2,0x59,0xE0,0x40, -0xA0,0x40,0xA0,0x74,0x2C,0xCC,0xF8,0xAF,0x10,0x00,0x04,0xC9,0xEC,0x4C,0x20,0x48, -0x20,0x49,0x08,0x70,0x10,0x47,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x86,0x01,0x48, -0x7B,0x17,0x86,0xE2,0x48,0xE0,0x40,0x3C,0x10,0x40,0x5B,0x0B,0x86,0x0D,0x48,0x86, -0x30,0x72,0x70,0x7B,0x22,0x92,0x48,0x86,0xE2,0x48,0xE0,0x40,0xD0,0x03,0x40,0x40, -0x87,0x80,0x5A,0x0A,0x00,0x00,0xE0,0x40,0x86,0xE2,0x72,0xE0,0x41,0xB8,0x0F,0x41, -0x3C,0x41,0x40,0x77,0xCF,0xDC,0x02,0x74,0x40,0x87,0x1A,0x50,0x70,0xDC,0x02,0x74, -0x40,0x87,0x20,0x50,0x70,0xDC,0x02,0x74,0x40,0x87,0x30,0x50,0x70,0xDC,0x02,0x74, -0x40,0x87,0x6F,0x40,0x50,0x70,0xDC,0x02,0x74,0x40,0x87,0x6F,0x70,0x50,0x70,0x86, -0xE2,0x72,0xE0,0x40,0x38,0x40,0x5F,0x00,0x01,0x7F,0x1A,0x86,0xE2,0x72,0xE0,0x40, -0x38,0x40,0x5F,0x00,0x02,0x7F,0x07,0x84,0x04,0x40,0x7B,0x04,0x80,0x40,0xB0,0x00, -0x40,0x7B,0x05,0x84,0x10,0x40,0xB3,0x00,0x40,0x87,0x40,0x47,0x86,0xE2,0x72,0xE0, -0x40,0xB8,0x30,0x40,0x7B,0x13,0x7B,0x22,0xB3,0x01,0x47,0x7B,0x1D,0xB3,0x02,0x47, -0x7B,0x18,0xB3,0x03,0x47,0x7B,0x13,0x3C,0x40,0x00,0x7F,0xEC,0x3C,0x40,0x10,0x7F, -0xE9,0x3C,0x40,0x20,0x7F,0xE9,0x7B,0xEC,0x87,0x47,0xDA,0x04,0x70,0x86,0xE2,0x72, -0xE0,0x40,0x38,0x40,0x6F,0x40,0x7F,0x07,0x84,0x0F,0x40,0x7B,0x05,0x84,0x07,0x40, -0xB3,0x00,0x40,0x87,0x40,0xDA,0x04,0x70,0xDC,0x01,0x74,0x40,0x86,0xE2,0x48,0xE0, -0x41,0xD0,0x03,0x41,0x41,0x87,0x81,0x5B,0x0A,0x00,0x00,0x50,0x70,0x86,0xE2,0x48, -0xE0,0x40,0xD0,0x03,0x40,0x40,0x87,0x80,0x5C,0x0A,0x00,0x00,0x7F,0x54,0x12,0x00, -0x02,0x70,0xDC,0x04,0x74,0x40,0x87,0x7F,0x54,0x12,0x00,0x02,0x50,0x70,0xDC,0x02, -0x74,0x40,0x87,0x15,0x50,0x70,0x87,0x03,0x7F,0x0E,0x90,0x04,0x00,0x70,0xA0,0x01, -0x2C,0xCC,0xFC,0xEF,0x28,0x05,0x00,0x00,0xDC,0x03,0x74,0x40,0x87,0x20,0x50,0x70, -0x04,0xC9,0xF0,0x4C,0x20,0x48,0x20,0x47,0x20,0x49,0x08,0x70,0x10,0x49,0x9C,0x4F, -0x54,0x00,0x00,0x00,0x4C,0xA0,0x4F,0x80,0x30,0x04,0x00,0xE0,0x59,0xA0,0x02,0x2C, -0xCC,0xF4,0x7F,0x24,0x52,0x00,0x00,0xA0,0x4F,0xF3,0x0A,0x00,0x00,0x86,0xE2,0x59, -0xE0,0x40,0xB8,0x0F,0x40,0xD0,0x03,0x40,0x40,0x86,0x80,0x58,0x0A,0x00,0x00,0xE4, -0x40,0xA0,0x40,0x2C,0xCC,0xF8,0x7F,0xE4,0x44,0x00,0x00,0xE0,0x62,0x2C,0xCC,0xFC, -0xEF,0xB4,0x04,0x00,0x00,0x2B,0x62,0x7F,0x3C,0xE0,0x62,0xA0,0x4F,0x09,0x0B,0x00, -0x00,0xE0,0x59,0x2C,0xCC,0xF4,0x7F,0xE4,0x4A,0x00,0x00,0xA0,0x4F,0x0C,0x0B,0x00, -0x00,0x86,0xE2,0x59,0xE0,0x40,0xA0,0x40,0x2C,0xCC,0xF8,0x7F,0xE4,0x44,0x00,0x00, -0x86,0xE2,0x59,0xE0,0x40,0xA0,0x40,0xA0,0x4F,0x00,0x90,0x04,0x00,0x2C,0xCC,0xF8, -0xAF,0x27,0xFD,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x10,0x49,0x9C,0x4F, -0x00,0x00,0x00,0x00,0x4C,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x10,0x49,0x9C,0x4F, -0x04,0x00,0x00,0x00,0x4C,0x87,0x7F,0x13,0x20,0x04,0x00,0x59,0x70,0x04,0xC9,0xE8, -0x4C,0x20,0x49,0x08,0x28,0x5D,0x70,0x70,0x70,0x70,0x10,0x49,0x84,0x5A,0x42,0x84, -0x74,0x41,0x84,0x78,0x40,0x30,0x19,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70, -0x84,0xCE,0xFC,0x40,0x84,0x50,0x7F,0x58,0x12,0x00,0x02,0x70,0x84,0xC0,0x04,0x7F, -0x5C,0x12,0x00,0x02,0x70,0x87,0x00,0x7F,0x60,0x12,0x00,0x02,0x70,0x2C,0x5C,0x7F, -0xEC,0x64,0x00,0x00,0x30,0xC8,0x84,0xCE,0xFC,0x40,0x84,0x50,0x7F,0x58,0x12,0x00, -0x02,0x70,0x84,0xC0,0x04,0x7F,0x5C,0x12,0x00,0x02,0x70,0x87,0x08,0x7F,0x60,0x12, -0x00,0x02,0x70,0x2C,0x5C,0x7F,0xEC,0x64,0x00,0x00,0x30,0xC8,0x84,0xCE,0xFC,0x40, -0x84,0x50,0x7F,0x58,0x12,0x00,0x02,0x70,0x84,0xC0,0x04,0x7F,0x5C,0x12,0x00,0x02, -0x70,0x87,0x09,0x7F,0x60,0x12,0x00,0x02,0x70,0x2C,0x5C,0x7F,0xEC,0x64,0x00,0x00, -0x30,0xC8,0x84,0xCE,0xFC,0x40,0x84,0x50,0x7F,0x58,0x12,0x00,0x02,0x70,0x84,0xC0, -0x04,0x7F,0x5C,0x12,0x00,0x02,0x70,0x87,0x0A,0x7F,0x60,0x12,0x00,0x02,0x70,0x2C, -0x5C,0x7F,0xEC,0x64,0x00,0x00,0x30,0xC8,0x84,0xCE,0xFC,0x40,0x84,0x50,0x7F,0x58, -0x12,0x00,0x02,0x70,0x84,0xC0,0x04,0x7F,0x5C,0x12,0x00,0x02,0x70,0x87,0x0B,0x7F, -0x60,0x12,0x00,0x02,0x70,0x2C,0x5C,0x7F,0xEC,0x64,0x00,0x00,0x30,0xC8,0x84,0xCE, -0xFC,0x40,0x84,0x50,0x7F,0x58,0x12,0x00,0x02,0x70,0x84,0xC0,0x04,0x7F,0x5C,0x12, -0x00,0x02,0x70,0x87,0x0C,0x7F,0x60,0x12,0x00,0x02,0x70,0x2C,0x5C,0x7F,0xEC,0x64, -0x00,0x00,0x30,0xC8,0x84,0xCE,0xFC,0x40,0x84,0x50,0x7F,0x58,0x12,0x00,0x02,0x70, -0x84,0xC0,0x04,0x7F,0x5C,0x12,0x00,0x02,0x70,0x87,0x0D,0x7F,0x60,0x12,0x00,0x02, -0x70,0x2C,0x5C,0x7F,0xEC,0x64,0x00,0x00,0x30,0xC8,0x84,0xCE,0xFC,0x40,0x84,0x50, -0x7F,0x58,0x12,0x00,0x02,0x70,0x84,0xC0,0x04,0x7F,0x5C,0x12,0x00,0x02,0x70,0x87, -0x0E,0x7F,0x60,0x12,0x00,0x02,0x70,0x2C,0x5C,0x7F,0xEC,0x64,0x00,0x00,0x30,0xC8, -0x84,0xCE,0xFC,0x40,0x84,0x50,0x7F,0x58,0x12,0x00,0x02,0x70,0x84,0xC0,0x04,0x7F, -0x5C,0x12,0x00,0x02,0x70,0x87,0x0F,0x7F,0x60,0x12,0x00,0x02,0x70,0x2C,0x5C,0x7F, -0xEC,0x64,0x00,0x00,0x30,0xC8,0x70,0x70,0x84,0xCE,0xFC,0x40,0x84,0x50,0x7F,0x58, -0x12,0x00,0x02,0x70,0x84,0xC0,0x04,0x7F,0x5C,0x12,0x00,0x02,0x70,0x84,0xC0,0x1C, -0x7F,0x64,0x12,0x00,0x02,0x70,0x2C,0x5C,0x7F,0x50,0x65,0x00,0x00,0x30,0xC8,0x84, -0xCC,0xFC,0x7F,0x58,0x12,0x00,0x02,0x70,0x84,0xCC,0xF8,0x7F,0x5C,0x12,0x00,0x02, -0x70,0x84,0x40,0x7F,0x64,0x12,0x00,0x02,0x70,0x84,0x4F,0x00,0xE1,0x81,0x00,0x4B, -0x2C,0x5C,0x7F,0x50,0x65,0x00,0x00,0x84,0x7F,0xFC,0x11,0x00,0x02,0xCC,0xF8,0x70, -0x84,0x7F,0x58,0x12,0x00,0x02,0x4B,0x30,0x45,0x84,0x40,0x7F,0x64,0x12,0x00,0x02, -0x70,0x84,0xCC,0xFC,0x7F,0x58,0x12,0x00,0x02,0x70,0x84,0xCC,0xF8,0x7F,0x5C,0x12, -0x00,0x02,0x70,0x04,0x7F,0x98,0x0E,0x00,0x02,0x40,0x30,0xAC,0x84,0x7F,0xFC,0x11, -0x00,0x02,0xCC,0xF8,0x70,0x84,0x7F,0x58,0x12,0x00,0x02,0x4B,0x30,0x45,0x84,0x4F, -0x00,0xE1,0x81,0x00,0x4B,0x2C,0x5C,0x7F,0x50,0x65,0x00,0x00,0x30,0xC8,0x70,0x70, -0x10,0x49,0x9C,0x4F,0x04,0x00,0x00,0x00,0x4C,0xDC,0x02,0x7F,0xA4,0x04,0x00,0x00, -0x40,0x2B,0x50,0x7F,0x15,0xDC,0x04,0x7F,0xA4,0x04,0x00,0x00,0x40,0x3F,0x01,0x50, -0x77,0x08,0x24,0x7F,0x48,0x43,0x00,0x00,0x7B,0x09,0x2C,0x5C,0x7F,0xDE,0x62,0x00, -0x00,0xDC,0x01,0x5A,0x40,0x3B,0x50,0x01,0x7F,0xF2,0x3C,0x7F,0xE8,0x11,0x00,0x02, -0x5A,0x77,0x59,0x2B,0x7F,0x68,0x08,0x00,0x02,0x77,0x51,0xDC,0x01,0x5A,0x40,0x3B, -0x50,0x5F,0x80,0x00,0x7F,0x46,0xDC,0x02,0x5A,0x40,0x87,0x6F,0x40,0x50,0x70,0xDC, -0x02,0x5A,0x40,0x87,0x6F,0x50,0x50,0x70,0xDC,0x03,0x5A,0x40,0x87,0x50,0x59,0x70, -0x7B,0x1C,0xDC,0x02,0x5A,0x40,0x87,0x6F,0x40,0x50,0x70,0xDC,0x02,0x5A,0x40,0x87, -0x6F,0x50,0x50,0x70,0xDC,0x03,0x5A,0x40,0x87,0x50,0x59,0x70,0xDC,0x01,0x5A,0x40, -0x3B,0x50,0x01,0x77,0xDF,0x84,0xFF,0x40,0x7B,0x20,0xDC,0x03,0x5A,0x40,0x87,0x50, -0x59,0x70,0x87,0x59,0xE0,0x40,0x7B,0x12,0xA0,0x00,0x2C,0xCC,0xFC,0x7F,0xF8,0x56, -0x00,0x00,0x86,0x40,0xE4,0x40,0x7B,0x02,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70, -0x10,0x47,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x2B,0xEF,0xC4,0x04,0x00,0x00,0x77, -0x11,0x2C,0x5C,0x7F,0xDE,0x62,0x00,0x00,0x80,0x40,0x24,0x7F,0x78,0x44,0x00,0x00, -0x84,0x5A,0x48,0x24,0x7F,0x55,0x44,0x00,0x00,0xA0,0x7F,0xE8,0x11,0x00,0x02,0x2C, -0xCC,0xFC,0x7F,0xA0,0x42,0x00,0x00,0x84,0x40,0x47,0x43,0x0B,0x84,0xFF,0x40,0x24, -0x7F,0x78,0x44,0x00,0x00,0xF8,0x5F,0xFF,0x00,0x47,0xE3,0x40,0x87,0x40,0xDA,0x00, -0x70,0x3F,0x0A,0xDA,0x00,0x7F,0x08,0x3F,0x0D,0xDA,0x00,0x77,0x2C,0x83,0xDA,0x00, -0x70,0xA0,0x0A,0xA0,0x7F,0xE8,0x11,0x00,0x02,0x2C,0xCC,0xF8,0x7F,0xB8,0x48,0x00, -0x00,0x28,0x40,0x43,0x0B,0x84,0xFF,0x40,0x24,0x7F,0x78,0x44,0x00,0x00,0x84,0x01, -0x40,0x24,0x7F,0x78,0x44,0x00,0x00,0x87,0xDA,0x00,0xE0,0x40,0xA0,0x40,0xA0,0x7F, -0xE8,0x11,0x00,0x02,0x2C,0xCC,0xF8,0x7F,0xB8,0x48,0x00,0x00,0x28,0x40,0x43,0x07, -0x84,0xFF,0x40,0x7B,0x75,0x3F,0x08,0xDA,0x00,0x77,0x23,0x3C,0x48,0x5A,0x7F,0x1C, -0xA0,0x4F,0x24,0x0B,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xE4,0x44,0x00,0x00,0x28,0x40, -0x43,0x07,0x84,0xFF,0x40,0x7B,0x53,0x94,0x5A,0x70,0x7B,0x2B,0x3F,0x6F,0x40,0xDA, -0x00,0x77,0x21,0x84,0x48,0x5A,0x70,0xA0,0x0A,0xA0,0x7F,0xE8,0x11,0x00,0x02,0x2C, -0xCC,0xF8,0x7F,0xB8,0x48,0x00,0x00,0x28,0x40,0x43,0x07,0x84,0xFF,0x40,0x7B,0x2A, -0x7B,0x05,0x90,0x5A,0x70,0xFC,0x48,0x5A,0x40,0x3C,0x6F,0x50,0x40,0x4A,0x2C,0xFF, -0xA0,0x4F,0x27,0x0B,0x00,0x00,0xA0,0x6F,0x50,0x2C,0xCC,0xF8,0x7F,0xE4,0x44,0x00, -0x00,0x84,0x48,0x5A,0x70,0x7A,0x0E,0xFF,0x04,0xC9,0xF0,0x4C,0x20,0x48,0x20,0x47, -0x20,0x49,0x08,0x70,0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x2C,0x5C,0x7F, -0xDE,0x62,0x00,0x00,0xDC,0x02,0x7F,0xA4,0x04,0x00,0x00,0x40,0x2B,0x50,0x7F,0x0F, -0xDC,0x04,0x7F,0xA4,0x04,0x00,0x00,0x40,0x3F,0x01,0x50,0x7F,0x21,0xDC,0x01,0x7F, -0xE8,0x11,0x00,0x02,0x40,0x3B,0x50,0x01,0x7F,0x10,0xDC,0x03,0x7F,0xE8,0x11,0x00, -0x02,0x40,0x87,0x50,0xE0,0x40,0x7B,0x16,0x80,0x40,0x7B,0x12,0xA0,0x01,0x2C,0xCC, -0xFC,0x7F,0xF8,0x56,0x00,0x00,0x87,0x40,0xE0,0x40,0x7B,0x02,0x04,0xC9,0xE8,0x4C, -0x20,0x49,0x08,0x70,0x10,0x49,0x9C,0x4F,0x38,0x00,0x00,0x00,0x4C,0x2B,0xEF,0xC4, -0x04,0x00,0x00,0x77,0x11,0x2C,0x5C,0x7F,0xDE,0x62,0x00,0x00,0x80,0x40,0x24,0x7F, -0xAE,0x48,0x00,0x00,0xDC,0x02,0x7F,0xE8,0x11,0x00,0x02,0x40,0x87,0x15,0x50,0x70, -0x80,0xC9,0x28,0x70,0x04,0x74,0x59,0x70,0x24,0x7F,0x88,0x48,0x00,0x00,0x3F,0x25, -0xDA,0x00,0x7F,0x08,0x24,0x7F,0x67,0x48,0x00,0x00,0x84,0x20,0x68,0x70,0x80,0x64, -0x70,0x80,0xC9,0x18,0x70,0x80,0xC9,0x1C,0x70,0x90,0x5A,0x70,0x3F,0x2D,0xDA,0x00, -0x77,0x09,0x84,0x01,0x64,0x70,0x90,0x5A,0x70,0x3F,0x30,0xDA,0x00,0x77,0x0D,0x28, -0x64,0x77,0x06,0x84,0x30,0x68,0x70,0x90,0x5A,0x70,0x7B,0x17,0xE8,0x0A,0xC9,0x1C, -0x40,0xFF,0x30,0xDA,0x00,0x41,0x9C,0x41,0x40,0x84,0x40,0xC9,0x1C,0x70,0x90,0x5A, -0x70,0x3F,0x30,0xDA,0x00,0x4B,0x08,0x3F,0x39,0xDA,0x00,0x4F,0xE1,0x3F,0x6F,0x6C, -0xDA,0x00,0x7F,0x09,0x3F,0x6F,0x68,0xDA,0x00,0x77,0x05,0x90,0x5A,0x70,0x87,0xDA, -0x00,0xE0,0x40,0x24,0x7F,0x12,0x48,0x00,0x00,0xDC,0x03,0x59,0x40,0x87,0x50,0xC9, -0x10,0x70,0x9C,0x04,0x59,0x70,0x2B,0xC9,0x10,0x7F,0x20,0x87,0xC9,0x10,0xE0,0x40, -0xA0,0x40,0xA0,0x7F,0xE8,0x11,0x00,0x02,0x2C,0xCC,0xF8,0x7F,0xB8,0x48,0x00,0x00, -0x28,0x40,0x43,0x07,0x84,0x01,0xC9,0x28,0x70,0x24,0x7F,0x65,0x48,0x00,0x00,0x84, -0xD9,0x00,0xC9,0x14,0x70,0x9C,0x04,0x59,0x70,0x28,0xC9,0x14,0x77,0x0B,0x84,0x4F, -0x70,0x0B,0x00,0x00,0xC9,0x14,0x70,0x80,0x6C,0x70,0x7B,0x2A,0x90,0x6C,0x70,0x84, -0xC9,0x14,0x40,0x90,0xC9,0x14,0x70,0x87,0x50,0xE0,0x40,0xA0,0x40,0xA0,0x7F,0xE8, -0x11,0x00,0x02,0x2C,0xCC,0xF8,0x7F,0xB8,0x48,0x00,0x00,0x28,0x40,0x43,0x07,0x84, -0x01,0xC9,0x28,0x70,0x2B,0xD9,0x14,0x77,0xD5,0x7B,0x1B,0xA0,0x20,0xA0,0x7F,0xE8, -0x11,0x00,0x02,0x2C,0xCC,0xF8,0x7F,0xB8,0x48,0x00,0x00,0x28,0x40,0x43,0x07,0x84, -0x01,0xC9,0x28,0x70,0x84,0x6C,0x40,0x90,0x6C,0x70,0x3C,0xC9,0x1C,0x40,0x4B,0xDD, -0x24,0x7F,0x65,0x48,0x00,0x00,0x84,0x10,0xC9,0x24,0x70,0x7B,0x13,0x84,0x01,0xC9, -0x18,0x70,0x84,0x0A,0xC9,0x24,0x70,0x7B,0x07,0x84,0x08,0xC9,0x24,0x70,0x84,0xD9, -0x00,0xC9,0x20,0x70,0x9C,0x04,0x59,0x70,0x28,0xC9,0x20,0x77,0x15,0x84,0x01,0x6C, -0x70,0x87,0x7F,0x5C,0x0B,0x00,0x00,0xC9,0x2C,0x70,0x80,0xC9,0x18,0x70,0x7B,0x74, -0x3C,0x01,0xC9,0x18,0x77,0x17,0xD4,0x1F,0xC9,0x20,0x40,0x7F,0x10,0x88,0xC9,0x20, -0x40,0x9C,0x01,0x40,0x84,0x40,0xC9,0x20,0x70,0x7B,0x06,0x80,0xC9,0x18,0x70,0x80, -0x6C,0x70,0x7B,0x22,0x04,0xC9,0x2C,0x40,0x9C,0x6C,0x40,0xE4,0xE0,0xC9,0x24,0xC9, -0x20,0x41,0x87,0x81,0x5C,0x0B,0x00,0x00,0x50,0x70,0xAC,0xE0,0xC9,0x24,0xC9,0x20, -0x70,0x90,0x6C,0x70,0x28,0xC9,0x20,0x7F,0x07,0x3C,0x0C,0x6C,0x4B,0xD8,0x3C,0x0C, -0x6C,0x4B,0x21,0xA0,0x3F,0xA0,0x7F,0xE8,0x11,0x00,0x02,0x2C,0xCC,0xF8,0x7F,0xB8, -0x48,0x00,0x00,0x28,0x40,0x43,0x07,0x84,0x01,0xC9,0x28,0x70,0x24,0x7F,0x65,0x48, -0x00,0x00,0x28,0x64,0x77,0x78,0x3C,0x01,0xC9,0x18,0x77,0x24,0x94,0xC9,0x1C,0x70, -0x3C,0x30,0x68,0x77,0x1B,0xA0,0x2D,0xA0,0x7F,0xE8,0x11,0x00,0x02,0x2C,0xCC,0xF8, -0x7F,0xB8,0x48,0x00,0x00,0x28,0x40,0x43,0x07,0x84,0x01,0xC9,0x28,0x70,0x7B,0x1B, -0xA0,0x68,0xA0,0x7F,0xE8,0x11,0x00,0x02,0x2C,0xCC,0xF8,0x7F,0xB8,0x48,0x00,0x00, -0x28,0x40,0x43,0x07,0x84,0x01,0xC9,0x28,0x70,0x84,0xC9,0x1C,0x40,0x94,0xC9,0x1C, -0x70,0x3C,0x6C,0x40,0x47,0xDC,0x3C,0x01,0xC9,0x18,0x77,0x20,0x3C,0x20,0x68,0x77, -0x1B,0xA0,0x2D,0xA0,0x7F,0xE8,0x11,0x00,0x02,0x2C,0xCC,0xF8,0x7F,0xB8,0x48,0x00, -0x00,0x28,0x40,0x43,0x07,0x84,0x01,0xC9,0x28,0x70,0x7B,0x2A,0x3C,0x01,0xC9,0x18, -0x77,0x1F,0x94,0xC9,0x1C,0x70,0xA0,0x2D,0xA0,0x7F,0xE8,0x11,0x00,0x02,0x2C,0xCC, -0xF8,0x7F,0xB8,0x48,0x00,0x00,0x28,0x40,0x43,0x07,0x84,0x01,0xC9,0x28,0x70,0xBC, -0x6C,0xC9,0x1C,0x70,0x7B,0x26,0x04,0xC9,0x2C,0x40,0x9C,0x6C,0x40,0x87,0x50,0xE0, -0x40,0xA0,0x40,0xA0,0x7F,0xE8,0x11,0x00,0x02,0x2C,0xCC,0xF8,0x7F,0xB8,0x48,0x00, -0x00,0x28,0x40,0x43,0x07,0x84,0x01,0xC9,0x28,0x70,0x94,0x6C,0x70,0x43,0xD9,0x3C, -0x01,0x64,0x77,0x2E,0x7B,0x1B,0xA0,0x68,0xA0,0x7F,0xE8,0x11,0x00,0x02,0x2C,0xCC, -0xF8,0x7F,0xB8,0x48,0x00,0x00,0x28,0x40,0x43,0x07,0x84,0x01,0xC9,0x28,0x70,0x84, -0xC9,0x1C,0x40,0x94,0xC9,0x1C,0x70,0xDC,0x01,0x6C,0x41,0x3C,0x41,0x40,0x47,0xD8, -0x7B,0x75,0x87,0xDA,0x00,0xE0,0x40,0xA0,0x40,0xA0,0x7F,0xE8,0x11,0x00,0x02,0x2C, -0xCC,0xF8,0x7F,0xB8,0x48,0x00,0x00,0x28,0x40,0x43,0x07,0x84,0x01,0xC9,0x28,0x70, -0x7B,0x55,0x3C,0x6F,0x6F,0x40,0x7E,0x43,0xFE,0x47,0x2F,0x3C,0x6F,0x63,0x40,0x7E, -0x7A,0xFD,0x47,0x1D,0x3C,0x6F,0x4F,0x40,0x7E,0x31,0xFE,0x47,0x0B,0x3C,0x6F,0x44, -0x40,0x7E,0x1C,0xFE,0x7B,0xBE,0x3C,0x6F,0x58,0x40,0x7E,0x0C,0xFE,0x7B,0xB5,0x3C, -0x6F,0x64,0x40,0x7E,0x0A,0xFE,0x7B,0xAC,0x3C,0x6F,0x75,0x40,0x7E,0x06,0xFE,0x47, -0x0B,0x3C,0x6F,0x73,0x40,0x7E,0x7A,0xFD,0x7B,0x9A,0x3C,0x6F,0x78,0x40,0x7E,0xE8, -0xFD,0x7B,0x91,0x7B,0x8F,0x7B,0x20,0x87,0xDA,0x00,0xE0,0x40,0xA0,0x40,0xA0,0x7F, -0xE8,0x11,0x00,0x02,0x2C,0xCC,0xF8,0x7F,0xB8,0x48,0x00,0x00,0x28,0x40,0x43,0x07, -0x84,0x01,0xC9,0x28,0x70,0x90,0x5A,0x70,0x2B,0xDA,0x00,0x76,0x93,0xFC,0x3C,0x01, -0xC9,0x28,0x77,0x17,0xA0,0x0A,0xA0,0x7F,0xE8,0x11,0x00,0x02,0x2C,0xCC,0xF8,0x7F, -0xB8,0x48,0x00,0x00,0x84,0xFF,0x40,0x7B,0x07,0x84,0x01,0x40,0x7B,0x02,0x04,0xC9, -0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x70,0x10,0x49,0x9C,0x4F,0x04,0x00,0x00,0x00, -0x4C,0x2C,0x5C,0x7F,0xDE,0x62,0x00,0x00,0xDC,0x02,0x7F,0xA4,0x04,0x00,0x00,0x40, -0x2B,0x50,0x7F,0x15,0xDC,0x04,0x7F,0xA4,0x04,0x00,0x00,0x40,0x3F,0x01,0x50,0x77, -0x08,0x24,0x7F,0x63,0x4A,0x00,0x00,0x87,0x73,0xE2,0x40,0x86,0x40,0x62,0x70,0x3C, -0x7F,0xE8,0x11,0x00,0x02,0x74,0x7F,0x08,0x24,0x7F,0xF0,0x49,0x00,0x00,0x2B,0x7F, -0x68,0x08,0x00,0x02,0x7F,0x08,0x24,0x7F,0xF0,0x49,0x00,0x00,0xDC,0x01,0x74,0x40, -0x3B,0x50,0x01,0x77,0x08,0x24,0x7F,0xF0,0x49,0x00,0x00,0xDC,0x01,0x74,0x40,0x3B, -0x50,0x5F,0x80,0x00,0x7F,0x4F,0xDC,0x02,0x74,0x40,0x87,0x6F,0x40,0x50,0x70,0xDC, -0x02,0x74,0x40,0x87,0x6F,0x50,0x50,0x70,0xDC,0x03,0x74,0x40,0x87,0x50,0xE2,0x40, -0x86,0x40,0x59,0x70,0x7B,0x20,0xDC,0x02,0x74,0x40,0x87,0x6F,0x40,0x50,0x70,0xDC, -0x02,0x74,0x40,0x87,0x6F,0x50,0x50,0x70,0xDC,0x03,0x74,0x40,0x87,0x50,0xE2,0x40, -0x86,0x40,0x59,0x70,0xDC,0x01,0x74,0x40,0x3B,0x50,0x01,0x77,0xDB,0x86,0xFF,0x62, -0x70,0x7B,0x7F,0xDC,0x03,0x74,0x40,0x3F,0x13,0x50,0x77,0x76,0x7B,0x09,0x2C,0x5C, -0x7F,0xDE,0x62,0x00,0x00,0xDC,0x01,0x74,0x40,0x3B,0x50,0x01,0x7F,0xF2,0xDC,0x01, -0x74,0x40,0x3B,0x50,0x5F,0x80,0x00,0x7F,0x4D,0xDC,0x02,0x74,0x40,0x87,0x6F,0x40, -0x50,0x70,0xDC,0x02,0x74,0x40,0x87,0x6F,0x50,0x50,0x70,0xDC,0x03,0x74,0x40,0x87, -0x50,0xE2,0x40,0x86,0x40,0x59,0x70,0x7B,0x20,0xDC,0x02,0x74,0x40,0x87,0x6F,0x40, -0x50,0x70,0xDC,0x02,0x74,0x40,0x87,0x6F,0x50,0x50,0x70,0xDC,0x03,0x74,0x40,0x87, -0x50,0xE2,0x40,0x86,0x40,0x59,0x70,0xDC,0x01,0x74,0x40,0x3B,0x50,0x01,0x77,0xDB, -0x86,0xFF,0x62,0x70,0xDC,0x03,0x74,0x40,0x87,0x50,0xE2,0x40,0x86,0x40,0x59,0x70, -0x7B,0x09,0x2C,0x5C,0x7F,0xDE,0x62,0x00,0x00,0xDC,0x01,0x74,0x40,0x3B,0x50,0x04, -0x7F,0xF2,0x3C,0x7F,0xE8,0x11,0x00,0x02,0x74,0x77,0x2B,0xDC,0x03,0x74,0x40,0x87, -0x73,0x50,0x70,0x3F,0x0A,0x73,0x77,0x1C,0x7B,0x09,0x2C,0x5C,0x7F,0xDE,0x62,0x00, -0x00,0xDC,0x01,0x74,0x40,0x3B,0x50,0x04,0x7F,0xF2,0xDC,0x03,0x74,0x40,0x87,0x0D, -0x50,0x70,0x7B,0x19,0x3F,0x0A,0x73,0x77,0x0C,0xDC,0x03,0x74,0x40,0x87,0x0D,0x50, -0x70,0x7B,0x0A,0xDC,0x03,0x74,0x40,0x87,0x73,0x50,0x70,0x7B,0x09,0x2C,0x5C,0x7F, -0xDE,0x62,0x00,0x00,0xDC,0x01,0x74,0x40,0x3B,0x50,0x04,0x7F,0xF2,0x86,0x62,0xE4, -0x40,0x7B,0x7B,0x87,0x73,0xE0,0x40,0xA0,0x40,0x2C,0xCC,0xFC,0x7F,0x6A,0x58,0x00, -0x00,0x86,0x40,0x59,0x70,0x3E,0xFF,0x59,0x77,0x08,0x86,0x59,0xE4,0x40,0x7B,0x5E, -0x3E,0x13,0x59,0x77,0x19,0x7B,0x09,0x2C,0x5C,0x7F,0xDE,0x62,0x00,0x00,0xA0,0x01, -0x2C,0xCC,0xFC,0x7F,0xF8,0x56,0x00,0x00,0x28,0x40,0x7F,0xED,0x3F,0x0A,0x73,0x77, -0x37,0xA0,0x0D,0x2C,0xCC,0xFC,0x7F,0x6A,0x58,0x00,0x00,0x86,0x40,0x59,0x70,0x3E, -0xFF,0x59,0x77,0x08,0x86,0x59,0xE4,0x40,0x7B,0x24,0x3E,0x13,0x59,0x77,0x19,0x7B, -0x09,0x2C,0x5C,0x7F,0xDE,0x62,0x00,0x00,0xA0,0x01,0x2C,0xCC,0xFC,0x7F,0xF8,0x56, -0x00,0x00,0x28,0x40,0x7F,0xED,0x86,0x59,0xE4,0x40,0x7B,0x02,0x04,0xC9,0xE8,0x4C, -0x20,0x49,0x08,0x70,0x10,0x45,0x9C,0x4F,0x1C,0x00,0x00,0x00,0x4C,0x04,0x78,0x68, -0x70,0x24,0x7F,0xC4,0x4C,0x00,0x00,0x80,0x46,0x7B,0x0F,0x2B,0xDA,0x04,0x77,0x07, -0x84,0x01,0x46,0x7B,0x0B,0x90,0x74,0x70,0x3F,0x25,0xDA,0x04,0x77,0xEF,0x28,0x46, -0x7F,0x08,0x24,0x7F,0xCA,0x4C,0x00,0x00,0x7B,0x05,0x90,0x5A,0x70,0x3F,0x20,0xDA, -0x00,0x77,0x07,0x84,0x01,0x40,0x7B,0x04,0x80,0x40,0x84,0x40,0x6C,0x70,0x3F,0x09, -0xDA,0x00,0x77,0x07,0x84,0x01,0x40,0x7B,0x04,0x80,0x40,0x84,0x40,0xC9,0x10,0x70, -0x3F,0x2D,0xDA,0x00,0x77,0x07,0x84,0x01,0x40,0x7B,0x04,0x80,0x40,0x84,0x40,0xC9, -0x14,0x70,0x3F,0x2C,0xDA,0x00,0x77,0x07,0x84,0x01,0x40,0x7B,0x04,0x80,0x40,0x84, -0x40,0xC9,0x18,0x70,0x3F,0x3D,0xDA,0x00,0x77,0x07,0x84,0x01,0x40,0x7B,0x04,0x80, -0x40,0xF0,0xC9,0x10,0x6C,0x41,0xB0,0xC9,0x14,0x41,0xB0,0xC9,0x18,0x41,0xB0,0x41, -0x40,0x77,0x99,0x90,0x74,0x70,0x87,0xDA,0x04,0xE0,0x40,0x24,0x7F,0x96,0x4C,0x00, -0x00,0x84,0x5A,0x48,0xE0,0x5A,0x2C,0xCC,0xFC,0xAF,0x46,0x01,0x7B,0x14,0x84,0xD9, -0x08,0x40,0x70,0x84,0x48,0x41,0x90,0x48,0x87,0x51,0x50,0x70,0x90,0xD9,0x08,0x70, -0x3C,0x5A,0x48,0x77,0xEB,0x84,0xD9,0x08,0x40,0x83,0x50,0x70,0x24,0x7F,0xC0,0x4C, -0x00,0x00,0x84,0xD9,0x08,0x40,0x87,0xDA,0x00,0x50,0x70,0x90,0x5A,0x70,0x24,0x7F, -0xC0,0x4C,0x00,0x00,0x84,0x07,0x46,0x7B,0x0E,0x04,0x59,0x40,0x9C,0x46,0x40,0x87, -0x30,0x50,0x70,0x94,0x46,0x28,0x46,0x43,0xF2,0x84,0x5A,0x48,0x04,0x67,0x47,0xE0, -0x5A,0x2C,0xCC,0xFC,0xAF,0xEB,0x00,0x94,0x5A,0x70,0x87,0xDA,0x00,0x57,0x70,0x3C, -0x48,0x5A,0x77,0x04,0x7B,0x09,0x94,0x47,0x94,0x5A,0x70,0x7B,0xEF,0x80,0x45,0x04, -0x59,0x47,0x84,0x07,0x46,0x7B,0x1D,0x87,0x57,0xE0,0x40,0xA0,0x40,0x2C,0xCC,0xFC, -0xAF,0x5F,0x01,0xD0,0x02,0x46,0x41,0xD0,0x41,0x40,0x40,0xB0,0x40,0x45,0x90,0x47, -0x94,0x46,0x28,0x46,0x43,0xE3,0xE0,0x5A,0x2C,0xCC,0xFC,0xAF,0xA4,0x00,0x3F,0x6F, -0x78,0xDA,0x04,0x77,0x12,0x84,0xD9,0x08,0x40,0x84,0x45,0x41,0x86,0x41,0x41,0x86, -0x41,0x50,0x70,0x7B,0x0A,0x84,0xD9,0x08,0x40,0x84,0x45,0x50,0x70,0x7B,0x63,0x3F, -0x6F,0x64,0xDA,0x04,0x77,0x16,0xA0,0x5A,0x2C,0xCC,0xFC,0x7F,0xD0,0x7E,0x00,0x00, -0x84,0xD9,0x08,0x41,0x86,0x40,0x51,0x70,0x7B,0x14,0xA0,0x5A,0x2C,0xCC,0xFC,0x7F, -0x38,0x7E,0x00,0x00,0x84,0xD9,0x08,0x41,0x84,0x40,0x51,0x70,0xE0,0x5A,0x2C,0xCC, -0xFC,0xAF,0x4E,0x00,0x7B,0x2C,0x3C,0x40,0x6F,0x44,0x7F,0xC5,0x3C,0x40,0x6F,0x58, -0x7E,0x34,0xFF,0x3C,0x40,0x6F,0x63,0x7E,0x1B,0xFF,0x3C,0x40,0x6F,0x64,0x7F,0xB1, -0x3C,0x40,0x6F,0x73,0x7E,0xDD,0xFE,0x3C,0x40,0x6F,0x78,0x7E,0x19,0xFF,0x7B,0xD6, -0x9C,0x04,0x68,0x70,0x2B,0xDA,0x04,0x76,0x30,0xFE,0x04,0xC9,0xF8,0x4C,0x20,0x48, -0x20,0x47,0x20,0x46,0x20,0x45,0x20,0x49,0x08,0x70,0x70,0x70,0x10,0x49,0x9C,0x4F, -0x14,0x00,0x00,0x00,0x4C,0x7B,0x06,0x90,0xDA,0x00,0x70,0x84,0xDA,0x00,0x40,0x3F, -0x20,0x50,0x7F,0x07,0x84,0x01,0x40,0x7B,0x04,0x80,0x40,0x84,0x40,0x59,0x70,0x84, -0xDA,0x00,0x40,0x3F,0x09,0x50,0x7F,0x07,0x84,0x01,0x40,0x7B,0x04,0x80,0x40,0x84, -0x40,0x64,0x70,0x84,0xDA,0x00,0x40,0x3F,0x2D,0x50,0x7F,0x07,0x84,0x01,0x40,0x7B, -0x04,0x80,0x40,0x84,0x40,0x68,0x70,0x84,0xDA,0x00,0x40,0x3F,0x2C,0x50,0x7F,0x07, -0x84,0x01,0x40,0x7B,0x04,0x80,0x40,0x84,0x40,0x6C,0x70,0x84,0xDA,0x00,0x40,0x2B, -0x50,0x7F,0x07,0x84,0x01,0x40,0x7B,0x04,0x80,0x40,0x84,0x40,0xC9,0x10,0x70,0x84, -0xDA,0x00,0x40,0x3F,0x3D,0x50,0x7F,0x07,0x84,0x01,0x40,0x7B,0x04,0x80,0x40,0xF8, -0x64,0x59,0x41,0xB8,0x68,0x41,0xB8,0x6C,0x41,0xB8,0xC9,0x10,0x41,0x38,0x41,0x40, -0x76,0x77,0xFF,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x10,0x49,0x9C,0x4F, -0x04,0x00,0x00,0x00,0x4C,0x3F,0x39,0x73,0x57,0x07,0x84,0x01,0x40,0x7B,0x04,0x80, -0x40,0x84,0x40,0x59,0x70,0x3F,0x30,0x73,0x5B,0x07,0x84,0x01,0x40,0x7B,0x04,0x80, -0x40,0x38,0x40,0x59,0x7F,0x0C,0xFF,0x30,0x73,0x40,0x87,0x40,0xE0,0x40,0x7B,0x1D, -0x3F,0x6F,0x61,0x73,0x5B,0x0D,0xFF,0x6F,0x57,0x73,0x40,0x87,0x40,0xE0,0x40,0x7B, -0x0C,0xFF,0x37,0x73,0x40,0x87,0x40,0xE0,0x40,0x7B,0x02,0x04,0xC9,0xE8,0x4C,0x20, -0x49,0x08,0x70,0x70,0x10,0x49,0x9C,0x4F,0x08,0x00,0x00,0x00,0x4C,0x87,0x77,0xE0, -0x40,0xD0,0x05,0x40,0x40,0x9C,0x7F,0x90,0x04,0x00,0x00,0x40,0x84,0x40,0x64,0x70, -0x80,0x59,0x70,0x7B,0x15,0x84,0x5A,0x40,0x90,0x5A,0x70,0x84,0x64,0x41,0x90,0x64, -0x70,0x87,0x51,0x50,0x70,0x90,0x59,0x70,0x3C,0x20,0x59,0x5B,0xEA,0x04,0xC9,0xE8, -0x4C,0x20,0x49,0x08,0x10,0x49,0x9C,0x4F,0x08,0x00,0x00,0x00,0x4C,0xA0,0x00,0x2C, -0xCC,0xFC,0xAF,0xB3,0x03,0xA0,0x4F,0x80,0x0B,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xE4, -0x44,0x00,0x00,0x28,0x40,0x43,0x08,0x24,0x7F,0xC0,0x51,0x00,0x00,0x84,0xEF,0xE4, -0x04,0x00,0x00,0x64,0x70,0xA0,0x4F,0xA1,0x0B,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xE4, -0x44,0x00,0x00,0x28,0x40,0x43,0x08,0x24,0x7F,0xC0,0x51,0x00,0x00,0x3C,0x4F,0x00, -0x00,0x10,0x00,0x64,0x4B,0x26,0xA0,0x4F,0xBC,0x0B,0x00,0x00,0xD4,0x14,0xEF,0xE4, -0x04,0x00,0x00,0x40,0xA0,0x40,0x2C,0xCC,0xF8,0x7F,0xE4,0x44,0x00,0x00,0x28,0x40, -0x43,0x08,0x24,0x7F,0xC0,0x51,0x00,0x00,0x7B,0x24,0xA0,0x4F,0xCB,0x0B,0x00,0x00, -0xD4,0x0A,0xEF,0xE4,0x04,0x00,0x00,0x40,0xA0,0x40,0x2C,0xCC,0xF8,0x7F,0xE4,0x44, -0x00,0x00,0x28,0x40,0x43,0x08,0x24,0x7F,0xC0,0x51,0x00,0x00,0x83,0x59,0x70,0x24, -0x7F,0xA8,0x51,0x00,0x00,0xA0,0x4F,0xD8,0x0B,0x00,0x00,0x87,0x59,0xE0,0x40,0xA0, -0x40,0x87,0x59,0xE0,0x40,0xD0,0x05,0x40,0x40,0x9C,0x7F,0x90,0x04,0x00,0x00,0x40, -0x9C,0x0C,0x40,0xA0,0x40,0x2C,0xCC,0xF4,0x7F,0xE4,0x44,0x00,0x00,0x28,0x40,0x43, -0x08,0x24,0x7F,0xC0,0x51,0x00,0x00,0xA0,0x4F,0xF6,0x0B,0x00,0x00,0x87,0x59,0xE0, -0x40,0xD0,0x05,0x40,0x40,0x9C,0x7F,0x90,0x04,0x00,0x00,0x40,0xCC,0x03,0x08,0x50, -0x40,0xA0,0x40,0x87,0x59,0xE0,0x40,0xD0,0x05,0x40,0x40,0x9C,0x7F,0x90,0x04,0x00, -0x00,0x40,0xCC,0x03,0x0C,0x50,0x40,0xA0,0x40,0x87,0x59,0xE0,0x40,0xD0,0x05,0x40, -0x40,0x9C,0x7F,0x90,0x04,0x00,0x00,0x40,0xCC,0x0F,0x10,0x50,0x40,0xA0,0x40,0x2C, -0xCC,0xF0,0x7F,0xE4,0x44,0x00,0x00,0x28,0x40,0x43,0x08,0x24,0x7F,0xC0,0x51,0x00, -0x00,0xA0,0x4F,0x27,0x0C,0x00,0x00,0x87,0x59,0xE0,0x40,0xD0,0x05,0x40,0x40,0x9C, -0x7F,0x90,0x04,0x00,0x00,0x40,0xCC,0x00,0x07,0xC0,0x04,0x40,0x3C,0x00,0x40,0x7F, -0x08,0x84,0x6F,0x79,0x40,0x7B,0x06,0x84,0x6F,0x6E,0x40,0xA0,0x40,0x87,0x59,0xE0, -0x40,0xD0,0x05,0x40,0x40,0x9C,0x7F,0x90,0x04,0x00,0x00,0x40,0xCC,0x00,0x05,0xC0, -0x04,0x40,0x3C,0x00,0x40,0x7F,0x0B,0x84,0x4F,0x6A,0x0C,0x00,0x00,0x40,0x7B,0x09, -0x84,0x4F,0x71,0x0C,0x00,0x00,0x40,0xA0,0x40,0x87,0x59,0xE0,0x40,0xD0,0x05,0x40, -0x40,0x9C,0x7F,0x90,0x04,0x00,0x00,0x40,0xCC,0x00,0x06,0xC0,0x04,0x40,0x9C,0x01, -0x40,0xA0,0x40,0x2C,0xCC,0xF0,0x7F,0xE4,0x44,0x00,0x00,0x28,0x40,0x43,0x08,0x24, -0x7F,0xC0,0x51,0x00,0x00,0xA0,0x4F,0x78,0x0C,0x00,0x00,0x87,0x59,0xE0,0x40,0xD0, -0x05,0x40,0x40,0x9C,0x7F,0x90,0x04,0x00,0x00,0x40,0xCC,0x07,0x00,0x50,0x40,0xA0, -0x40,0x87,0x59,0xE0,0x40,0xD0,0x05,0x40,0x40,0x9C,0x7F,0x90,0x04,0x00,0x00,0x40, -0xCC,0x07,0x18,0xC0,0x04,0x40,0xA0,0x40,0x2C,0xCC,0xF4,0x7F,0xE4,0x44,0x00,0x00, -0x28,0x40,0x43,0x08,0x24,0x7F,0xC0,0x51,0x00,0x00,0xA0,0x4F,0xA9,0x0C,0x00,0x00, -0x87,0x59,0xE0,0x40,0xD0,0x05,0x40,0x40,0x9C,0x7F,0x90,0x04,0x00,0x00,0x40,0xCC, -0x00,0x09,0xC0,0x04,0x40,0x3C,0x00,0x40,0x7F,0x08,0x84,0x6F,0x79,0x40,0x7B,0x06, -0x84,0x6F,0x6E,0x40,0xA0,0x40,0x2C,0xCC,0xF8,0x7F,0xE4,0x44,0x00,0x00,0x28,0x40, -0x43,0x08,0x24,0x7F,0xC0,0x51,0x00,0x00,0x87,0x59,0xE0,0x40,0xD0,0x05,0x40,0x40, -0x9C,0x7F,0x90,0x04,0x00,0x00,0x40,0xCC,0x00,0x09,0xC0,0x04,0x40,0x3C,0x00,0x40, -0x7F,0x42,0xA0,0x4F,0xBE,0x0C,0x00,0x00,0x87,0x59,0xE0,0x40,0xD0,0x05,0x40,0x40, -0x9C,0x7F,0x90,0x04,0x00,0x00,0x40,0xCC,0x00,0x08,0xC0,0x04,0x40,0x3C,0x00,0x40, -0x7F,0x08,0x84,0x6F,0x79,0x40,0x7B,0x06,0x84,0x6F,0x6E,0x40,0xA0,0x40,0x2C,0xCC, -0xF8,0x7F,0xE4,0x44,0x00,0x00,0x28,0x40,0x43,0x08,0x24,0x7F,0xC0,0x51,0x00,0x00, -0x7B,0x1A,0xA0,0x4F,0xCF,0x0C,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xE4,0x44,0x00,0x00, -0x28,0x40,0x43,0x08,0x24,0x7F,0xC0,0x51,0x00,0x00,0x83,0x61,0x70,0x24,0x7F,0x54, -0x51,0x00,0x00,0x2B,0x61,0x77,0x1A,0xA0,0x4F,0xDF,0x0C,0x00,0x00,0x2C,0xCC,0xFC, -0x7F,0xE4,0x44,0x00,0x00,0x28,0x40,0x43,0x08,0x24,0x7F,0xC0,0x51,0x00,0x00,0xA0, -0x4F,0xF2,0x0C,0x00,0x00,0x87,0x61,0xE0,0x40,0xA4,0xE0,0x02,0x40,0x77,0x0B,0x84, -0x4F,0x13,0x0D,0x00,0x00,0x40,0x7B,0x09,0x84,0x4F,0x1A,0x0D,0x00,0x00,0x40,0xA0, -0x40,0x87,0x61,0xE0,0x40,0xA0,0x40,0x87,0x59,0xE0,0x40,0xD0,0x05,0x40,0x40,0x9C, -0x7F,0x90,0x04,0x00,0x00,0x40,0xEB,0x0C,0x61,0x41,0xDC,0x41,0xC0,0x08,0x40,0x9C, -0x02,0x40,0xA0,0x40,0x87,0x59,0xE0,0x40,0xD0,0x05,0x40,0x40,0x9C,0x7F,0x90,0x04, -0x00,0x00,0x40,0xEB,0x0C,0x61,0x41,0xDC,0x41,0xC0,0x08,0x40,0x86,0xE2,0x50,0xE0, -0x40,0xA0,0x40,0x2C,0xCC,0xEC,0x7F,0xE4,0x44,0x00,0x00,0x28,0x40,0x43,0x04,0x7B, -0x71,0x93,0x61,0x70,0x87,0x61,0xE0,0x40,0x87,0x59,0xE0,0x41,0xD0,0x05,0x41,0x41, -0x9C,0x7F,0x90,0x04,0x00,0x00,0x41,0xCC,0x03,0x00,0xC1,0x04,0x41,0x3C,0x41,0x40, -0x5A,0x53,0xFF,0x87,0x59,0xE0,0x40,0xFF,0x01,0xEF,0xE0,0x04,0x00,0x00,0x41,0x3C, -0x41,0x40,0x53,0x23,0xA0,0x4F,0x1D,0x0D,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xE4,0x44, -0x00,0x00,0x28,0x40,0x43,0x04,0x7B,0x2A,0x7B,0x02,0x2C,0x5C,0xEF,0xC8,0x04,0x00, -0x00,0x28,0x40,0x7F,0xF7,0x93,0x59,0x70,0x3F,0xEF,0xE0,0x04,0x00,0x00,0x59,0x5A, -0x06,0xFD,0xA0,0x4F,0x3A,0x0D,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xE4,0x44,0x00,0x00, -0xA0,0x01,0x2C,0xCC,0xFC,0xAF,0x10,0x00,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70, -0x70,0x70,0x10,0x49,0x9C,0x4F,0x04,0x00,0x00,0x00,0x4C,0x87,0x73,0x7F,0x68,0x08, -0x00,0x02,0x70,0x2B,0x73,0x77,0x37,0x7B,0x28,0xDC,0x02,0x7F,0xE8,0x11,0x00,0x02, -0x40,0x87,0x6F,0x40,0x50,0x70,0xDC,0x02,0x7F,0xE8,0x11,0x00,0x02,0x40,0x87,0x6F, -0x50,0x50,0x70,0xDC,0x03,0x7F,0xE8,0x11,0x00,0x02,0x40,0x87,0x50,0x59,0x70,0xDC, -0x01,0x7F,0xE8,0x11,0x00,0x02,0x40,0x3B,0x50,0x01,0x77,0xCF,0x04,0xC9,0xE8,0x4C, -0x20,0x49,0x08,0x70,0x10,0x48,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0xF8,0x5F,0x00, -0xF0,0x5A,0x40,0xF8,0x5F,0xFF,0x0F,0x5A,0x41,0xD0,0x03,0x41,0x41,0x9C,0x41,0x40, -0x84,0x40,0x48,0x7B,0x2A,0x84,0x48,0x40,0x9C,0x04,0x48,0xFB,0x0F,0xC0,0x03,0x40, -0x87,0x40,0xDA,0x04,0x70,0x84,0x74,0x40,0x90,0x74,0x70,0x84,0x48,0x41,0x9C,0x04, -0x48,0xF8,0x0F,0x51,0x41,0xD0,0x04,0x41,0x41,0xB3,0x41,0x50,0x70,0x86,0x7A,0x40, -0x96,0x7A,0x70,0x86,0xE2,0x40,0xE0,0x40,0x77,0xCD,0x80,0x7F,0x70,0x12,0x00,0x02, -0x70,0xA0,0x7F,0x70,0x12,0x00,0x02,0x37,0x04,0x7B,0x0B,0xA0,0x4A,0xFC,0x0C,0x4C, -0x4A,0x7A,0x8F,0x00,0x7B,0x02,0x04,0xC9,0xEC,0x4C,0x20,0x48,0x20,0x49,0x08,0x70, -0x10,0x48,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0xF8,0x5F,0x00,0xF0,0x74,0x40,0xF8, -0x5F,0xFF,0x0F,0x74,0x41,0xD0,0x03,0x41,0x41,0x9C,0x41,0x40,0x84,0x40,0x48,0x7B, -0x2B,0x84,0x48,0x40,0x9C,0x04,0x48,0xFB,0x0F,0xDA,0x00,0x41,0x84,0x41,0x50,0x70, -0x84,0x48,0x40,0x9C,0x04,0x48,0x84,0x5A,0x41,0x90,0x5A,0x70,0xFB,0x5F,0xF0,0x00, -0x51,0x41,0xD4,0x04,0x41,0x41,0x84,0x41,0x50,0x70,0x86,0x7A,0x40,0x96,0x7A,0x70, -0x86,0xE2,0x40,0xE0,0x40,0x77,0xCC,0x84,0x01,0x7F,0x70,0x12,0x00,0x02,0x70,0xA0, -0x7F,0x70,0x12,0x00,0x02,0x37,0x04,0x7B,0x0B,0xA0,0x4A,0xFC,0x0C,0x4C,0x4A,0x7A, -0x11,0x00,0x7B,0x02,0x04,0xC9,0xEC,0x4C,0x20,0x48,0x20,0x49,0x08,0x70,0x70,0x70, -0x10,0x47,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x82,0x48,0x84,0x4F,0x00,0x30,0x04, -0x00,0x47,0x7B,0x40,0x86,0xE2,0x48,0xE0,0x40,0x86,0xE2,0xC7,0x02,0xE0,0x41,0xBA, -0x0F,0x41,0x86,0xE2,0x41,0xE0,0x41,0x9C,0x41,0x40,0x86,0x40,0x48,0x86,0xE2,0x48, -0xE0,0x40,0xD0,0x01,0x40,0x40,0x86,0xE2,0x40,0xE0,0x40,0x86,0xE2,0x48,0xE0,0x41, -0xD4,0x0F,0x41,0x41,0x86,0xE2,0x41,0xE0,0x41,0xB0,0x41,0x40,0x86,0x40,0x48,0x9C, -0x04,0x47,0x3C,0x4F,0x00,0x38,0x04,0x00,0x47,0x5B,0xBB,0x86,0xE2,0x48,0xE0,0x40, -0x88,0x40,0x40,0x86,0x40,0x48,0x3F,0x01,0x73,0x77,0x41,0x86,0xE2,0x48,0xE0,0x40, -0xB8,0x0F,0x40,0x84,0x40,0x57,0x70,0x86,0xE2,0x48,0xE0,0x40,0xD4,0x04,0x40,0x40, -0xB8,0x0F,0x40,0x84,0x40,0xC7,0x04,0x70,0x86,0xE2,0x48,0xE0,0x40,0xD4,0x08,0x40, -0x40,0xB8,0x0F,0x40,0x84,0x40,0xC7,0x08,0x70,0x86,0xE2,0x48,0xE0,0x40,0xD4,0x0C, -0x40,0x40,0xB8,0x0F,0x40,0x84,0x40,0xC7,0x0C,0x70,0x86,0xE2,0x48,0xE0,0x40,0x86, -0xE2,0xC7,0x02,0xE0,0x41,0xBA,0x0F,0x41,0x86,0xE2,0x41,0xE0,0x41,0xF8,0x0F,0xC7, -0x04,0x42,0xD0,0x04,0x42,0x42,0x86,0xE2,0x42,0xE0,0x42,0xB0,0x42,0x41,0x86,0xE2, -0x41,0xE0,0x41,0xF8,0x0F,0xC7,0x08,0x42,0xD0,0x08,0x42,0x42,0x86,0xE2,0x42,0xE0, -0x42,0xB0,0x42,0x41,0x86,0xE2,0x41,0xE0,0x41,0xF8,0x0F,0xC7,0x0C,0x42,0xD0,0x0C, -0x42,0x42,0x86,0xE2,0x42,0xE0,0x42,0xB0,0x42,0x41,0x86,0xE2,0x41,0xE0,0x41,0x3C, -0x41,0x40,0x77,0x07,0x84,0x01,0x40,0x7B,0x06,0x80,0x40,0x7B,0x02,0x04,0xC9,0xF0, -0x4C,0x20,0x48,0x20,0x47,0x20,0x49,0x08,0x84,0x5A,0x40,0x84,0x74,0x42,0xC4,0x02, -0x42,0x42,0x80,0x50,0x70,0x94,0x42,0x4F,0x08,0x04,0xC0,0x04,0x41,0x30,0x19,0x08, -0x84,0x5A,0x40,0x70,0x28,0x40,0x77,0x09,0x04,0x7F,0x74,0x12,0x00,0x02,0x40,0x84, -0x43,0x50,0x70,0x84,0x44,0xC0,0x04,0x70,0x84,0x45,0xC0,0x08,0x70,0x84,0x46,0xC0, -0x0C,0x70,0x84,0x47,0xC0,0x10,0x70,0x84,0x48,0xC0,0x14,0x70,0x84,0xCC,0xFC,0xC0, -0x18,0x70,0x84,0xCC,0xF8,0xC0,0x1C,0x70,0x84,0x4A,0xC0,0x20,0x70,0x84,0x49,0xC0, -0x24,0x70,0x84,0xCD,0x0C,0xC0,0x28,0x70,0x84,0xCD,0x10,0xC0,0x2C,0x70,0x80,0x40, -0x08,0x84,0x5A,0x40,0x70,0x28,0x40,0x77,0x09,0x04,0x7F,0x74,0x12,0x00,0x02,0x40, -0x84,0x50,0x43,0x84,0xC0,0x04,0x44,0x84,0xC0,0x08,0x45,0x84,0xC0,0x0C,0x46,0x84, -0xC0,0x10,0x47,0x84,0xC0,0x14,0x48,0x84,0xC0,0x18,0x4A,0x84,0xC0,0x1C,0x41,0x84, -0xC0,0x20,0x4C,0x84,0xC0,0x24,0x49,0x84,0xC0,0x28,0xCD,0x0C,0x70,0x84,0xC0,0x2C, -0xCD,0x10,0x70,0x80,0x40,0x90,0x40,0x24,0x51,0x70,0x70,0x70,0x10,0x49,0x9C,0x4F, -0x00,0x00,0x00,0x00,0x4C,0x87,0x01,0x7F,0xA4,0x12,0x00,0x02,0x70,0x04,0xC9,0xE8, -0x4C,0x20,0x49,0x08,0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x86,0xE2,0x72, -0xE0,0x40,0xA0,0x40,0xA0,0x5F,0xFF,0x08,0x2C,0xCC,0xF8,0xAF,0x14,0x00,0x86,0xE2, -0x40,0xE0,0x40,0x7B,0x02,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x10,0x49,0x9C,0x4F, -0x08,0x00,0x00,0x00,0x4C,0x83,0x7F,0xA4,0x12,0x00,0x02,0x70,0x84,0xEF,0x94,0x04, -0x00,0x00,0x64,0x70,0x84,0x4F,0xEC,0x54,0x00,0x00,0xEF,0x94,0x04,0x00,0x00,0x70, -0xF3,0x30,0x7F,0x54,0x12,0x00,0x02,0x40,0x87,0x40,0x7F,0x04,0x90,0x04,0x00,0x70, -0x7B,0x62,0x87,0x7F,0x0F,0x90,0x04,0x00,0x59,0x70,0x86,0xE2,0x76,0xE0,0x40,0xD4, -0x08,0x40,0x40,0x87,0x40,0x7F,0x06,0x90,0x04,0x00,0x70,0xFB,0x5F,0xFF,0x00,0x77, -0x40,0x87,0x40,0x7F,0x07,0x90,0x04,0x00,0x70,0x87,0x7F,0x0E,0x90,0x04,0x00,0x59, -0x70,0x7B,0x28,0x2C,0x5C,0x7F,0xDE,0x62,0x00,0x00,0x2B,0x7F,0xA4,0x12,0x00,0x02, -0x7F,0x19,0x87,0x7F,0x0F,0x90,0x04,0x00,0x59,0x70,0x84,0x64,0xEF,0x94,0x04,0x00, -0x00,0x70,0x86,0xE2,0x72,0xE0,0x40,0x7B,0x2C,0x3B,0x7F,0x05,0x90,0x04,0x00,0x08, -0x7F,0xD3,0x86,0x72,0x40,0x96,0x72,0x70,0x86,0xE2,0x40,0xE0,0x40,0x77,0x95,0x87, -0x7F,0x0F,0x90,0x04,0x00,0x59,0x70,0x84,0x64,0xEF,0x94,0x04,0x00,0x00,0x70,0x80, -0x40,0x7B,0x02,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x10,0x49,0x9C,0x4F, -0x08,0x00,0x00,0x00,0x4C,0x83,0x64,0x70,0x84,0xEF,0x94,0x04,0x00,0x00,0x7F,0xC8, -0x12,0x00,0x02,0x70,0x84,0x4F,0x00,0x5D,0x00,0x00,0xEF,0x94,0x04,0x00,0x00,0x70, -0x70,0xCC,0x03,0x0D,0x4B,0x7F,0xC4,0x12,0x00,0x02,0x70,0xC8,0x03,0x0D,0x0F,0x4B, -0x84,0x4F,0xB8,0x12,0x00,0x02,0x7F,0x00,0x00,0x00,0x02,0x70,0x84,0x4F,0xF4,0x37, -0x00,0x02,0x7F,0xB8,0x12,0x00,0x02,0x70,0x84,0x4F,0xEC,0x37,0x00,0x02,0x7F,0xBC, -0x12,0x00,0x02,0x70,0x87,0x02,0x7F,0xC0,0x12,0x00,0x02,0x70,0x87,0x02,0x7F,0xC1, -0x12,0x00,0x02,0x70,0x87,0x01,0x7F,0xC3,0x12,0x00,0x02,0x70,0xA0,0x4F,0xEC,0x37, -0x00,0x02,0xA0,0x5F,0x14,0x08,0x2C,0xCC,0xF8,0xEF,0x18,0x05,0x00,0x00,0xA0,0x14, -0x2C,0xCC,0xFC,0xEF,0x28,0x05,0x00,0x00,0xD0,0x15,0x5A,0x40,0x87,0xC0,0x01,0xE0, -0x59,0x70,0xA0,0x14,0x2C,0xCC,0xFC,0xEF,0x28,0x05,0x00,0x00,0xD0,0x15,0x5A,0x40, -0x87,0xC0,0x03,0xE0,0x59,0x70,0x80,0x59,0x70,0x7B,0x1E,0x3F,0x03,0x7F,0xEF,0x37, -0x00,0x02,0x77,0x08,0x87,0x01,0x64,0x70,0x7B,0x15,0xA0,0x01,0x2C,0xCC,0xFC,0xEF, -0x28,0x05,0x00,0x00,0x90,0x59,0x70,0x3C,0x6F,0x64,0x59,0x5B,0xE0,0x3C,0x6F,0x64, -0x59,0x5B,0x1B,0xD0,0x15,0x5A,0x40,0x87,0x01,0xC0,0x05,0x70,0xA0,0x14,0x2C,0xCC, -0xFC,0xEF,0x28,0x05,0x00,0x00,0x87,0x64,0xE0,0x40,0x7B,0x15,0x2C,0x5C,0xAF,0x62, -0x06,0x3C,0x01,0x40,0x7F,0x05,0x83,0x64,0x70,0x87,0x64,0xE0,0x40,0x7B,0x02,0x04, -0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x10,0x49,0x9C,0x4F,0x04,0x00,0x00,0x00, -0x4C,0x84,0xEF,0x94,0x04,0x00,0x00,0x7F,0xC8,0x12,0x00,0x02,0x70,0x84,0x4F,0x00, -0x5D,0x00,0x00,0xEF,0x94,0x04,0x00,0x00,0x70,0x70,0xCC,0x03,0x0D,0x4B,0x7F,0xC4, -0x12,0x00,0x02,0x70,0xC8,0x03,0x0D,0x0F,0x4B,0x87,0x08,0x7F,0xF7,0x37,0x00,0x02, -0x70,0x3F,0x01,0x73,0x77,0x18,0xDC,0x03,0x7F,0xA4,0x04,0x00,0x00,0x40,0xF3,0x20, -0x50,0x40,0x87,0x40,0x7F,0xF6,0x37,0x00,0x02,0x70,0x7B,0x19,0xDC,0x03,0x7F,0xA4, -0x04,0x00,0x00,0x40,0x87,0x50,0x7F,0xF6,0x37,0x00,0x02,0x70,0x87,0x7F,0xF6,0x37, -0x00,0x02,0x40,0x87,0x7F,0x68,0x08,0x00,0x02,0xE0,0x7F,0xF8,0x37,0x00,0x02,0x70, -0x87,0x5F,0xFF,0x00,0x7F,0xEF,0x37,0x00,0x02,0x70,0xDC,0x02,0x7F,0xA4,0x04,0x00, -0x00,0x40,0x87,0x50,0xE0,0x40,0xD0,0x15,0x40,0x40,0x87,0xC0,0x01,0xE2,0x40,0x86, -0x40,0x59,0x70,0x82,0x59,0x70,0x24,0x7F,0x56,0x58,0x00,0x00,0xA0,0x01,0xA0,0x5F, -0xE6,0x00,0x2C,0xCC,0xF8,0x7F,0x2C,0x55,0x00,0x00,0x3F,0x5F,0xFF,0x00,0x7F,0xEF, -0x37,0x00,0x02,0x7F,0x6A,0x2B,0x7F,0xEF,0x37,0x00,0x02,0x77,0x4C,0x2C,0x5C,0xAF, -0x81,0x05,0x3C,0x01,0x40,0x7F,0x18,0x84,0x4F,0xEF,0xBE,0xED,0xFE,0xEF,0x8C,0x04, -0x00,0x00,0x70,0x87,0x01,0x7F,0x0B,0x40,0x04,0x00,0x70,0x7B,0x00,0x86,0xE2,0x7F, -0xEC,0x37,0x00,0x02,0xE0,0x40,0xBA,0x5F,0xFF,0x00,0x40,0x86,0x40,0x62,0x70,0x86, -0xE2,0x62,0xE0,0x40,0x3C,0x5F,0xFF,0x00,0x40,0x77,0x07,0x84,0xFF,0x40,0x7B,0x07, -0x86,0xE2,0x62,0xE0,0x40,0x7B,0x5D,0x84,0x4F,0xEF,0xBE,0xED,0xFE,0xEF,0x8C,0x04, -0x00,0x00,0x70,0x87,0x01,0x7F,0x0B,0x40,0x04,0x00,0x70,0x7B,0x00,0x86,0xE2,0x59, -0xE0,0x40,0x3C,0x6F,0x64,0x40,0x5B,0x1F,0x2C,0x5C,0x7F,0xDE,0x62,0x00,0x00,0x84, -0x4F,0xEF,0xBE,0xED,0xFE,0xEF,0x8C,0x04,0x00,0x00,0x70,0x87,0x01,0x7F,0x0B,0x40, -0x04,0x00,0x70,0x7B,0x00,0x3F,0x01,0x73,0x77,0x07,0x92,0x59,0x70,0x7B,0x09,0x2C, -0x5C,0x7F,0xDE,0x62,0x00,0x00,0x86,0xE2,0x59,0xE0,0x40,0x3C,0x6F,0x64,0x40,0x5A, -0x3D,0xFF,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x10,0x49,0x9C,0x4F,0x04,0x00, -0x00,0x00,0x4C,0x84,0xEF,0x94,0x04,0x00,0x00,0x7F,0xC8,0x12,0x00,0x02,0x70,0x84, -0x4F,0x00,0x5D,0x00,0x00,0xEF,0x94,0x04,0x00,0x00,0x70,0x70,0xCC,0x03,0x0D,0x4B, -0x7F,0xC4,0x12,0x00,0x02,0x70,0xC8,0x03,0x0D,0x0F,0x4B,0x87,0x09,0x7F,0xF7,0x37, -0x00,0x02,0x70,0xDC,0x03,0x7F,0xA4,0x04,0x00,0x00,0x40,0x87,0x50,0x7F,0xF6,0x37, -0x00,0x02,0x70,0x87,0x73,0xE2,0x40,0x86,0x40,0x7F,0xF4,0x37,0x00,0x02,0x70,0x87, -0x5F,0xFF,0x00,0x7F,0xEF,0x37,0x00,0x02,0x70,0x87,0x7F,0x68,0x08,0x00,0x02,0xE0, -0x7F,0xF8,0x37,0x00,0x02,0x70,0xDC,0x02,0x7F,0xA4,0x04,0x00,0x00,0x40,0x87,0x50, -0xE0,0x40,0xD0,0x15,0x40,0x40,0x87,0xC0,0x01,0xE2,0x40,0x86,0x40,0x59,0x70,0x82, -0x59,0x70,0x24,0x7F,0xB2,0x59,0x00,0x00,0xA0,0x01,0xA0,0x5F,0xE6,0x00,0x2C,0xCC, -0xF8,0x7F,0x2C,0x55,0x00,0x00,0x3F,0x5F,0xFF,0x00,0x7F,0xEF,0x37,0x00,0x02,0x7F, -0x78,0x2B,0x7F,0xEF,0x37,0x00,0x02,0x77,0x53,0x2C,0x5C,0xAF,0x25,0x04,0x3C,0x01, -0x40,0x7F,0x1F,0x2C,0x5C,0x7F,0xDE,0x62,0x00,0x00,0x84,0x4F,0xEF,0xBE,0xED,0xFE, -0xEF,0x8C,0x04,0x00,0x00,0x70,0x87,0x01,0x7F,0x0B,0x40,0x04,0x00,0x70,0x7B,0x00, -0x86,0xE2,0x7F,0xEC,0x37,0x00,0x02,0xE0,0x40,0xBA,0x5F,0xFF,0x00,0x40,0x86,0x40, -0x62,0x70,0x86,0xE2,0x62,0xE0,0x40,0x3C,0x5F,0xFF,0x00,0x40,0x77,0x07,0x84,0xFF, -0x40,0x7B,0x07,0x86,0xE2,0x62,0xE0,0x40,0x7B,0x56,0x2C,0x5C,0x7F,0xDE,0x62,0x00, -0x00,0x84,0x4F,0xEF,0xBE,0xED,0xFE,0xEF,0x8C,0x04,0x00,0x00,0x70,0x87,0x01,0x7F, -0x0B,0x40,0x04,0x00,0x70,0x7B,0x00,0x86,0xE2,0x59,0xE0,0x40,0x3C,0x6F,0x64,0x40, -0x5B,0x1F,0x2C,0x5C,0x7F,0xDE,0x62,0x00,0x00,0x84,0x4F,0xEF,0xBE,0xED,0xFE,0xEF, -0x8C,0x04,0x00,0x00,0x70,0x87,0x01,0x7F,0x0B,0x40,0x04,0x00,0x70,0x7B,0x00,0x92, -0x59,0x70,0x86,0xE2,0x59,0xE0,0x40,0x3C,0x6F,0x64,0x40,0x5A,0x3D,0xFF,0x04,0xC9, -0xE8,0x4C,0x20,0x49,0x08,0x70,0x10,0x49,0x9C,0x4F,0x10,0x00,0x00,0x00,0x4C,0x83, -0x64,0x70,0x84,0xEF,0x94,0x04,0x00,0x00,0x7F,0xC8,0x12,0x00,0x02,0x70,0x84,0x4F, -0x00,0x5D,0x00,0x00,0xEF,0x94,0x04,0x00,0x00,0x70,0x70,0xCC,0x03,0x0D,0x4B,0x7F, -0xC4,0x12,0x00,0x02,0x70,0xC8,0x03,0x0D,0x0F,0x4B,0x87,0x07,0x7F,0xF7,0x37,0x00, -0x02,0x70,0x87,0x77,0x7F,0xF6,0x37,0x00,0x02,0x70,0x87,0x5F,0xFF,0x00,0x7F,0xEF, -0x37,0x00,0x02,0x70,0x04,0x68,0x7F,0xF8,0x37,0x00,0x02,0x70,0x86,0xEF,0xA4,0x04, -0x00,0x00,0x68,0x70,0x83,0x6C,0x70,0x87,0x73,0xE0,0x40,0xD0,0x15,0x40,0x40,0x87, -0xC0,0x01,0xE0,0x59,0x70,0x80,0x59,0x70,0x7B,0x5D,0xA0,0x01,0x2C,0xCC,0xFC,0xEF, -0x28,0x05,0x00,0x00,0x2B,0x7F,0xEF,0x37,0x00,0x02,0x77,0x28,0x87,0x01,0x64,0x70, -0xDC,0x03,0x7F,0xA4,0x04,0x00,0x00,0x40,0x87,0x6B,0x50,0x70,0xDC,0x04,0x7F,0xA4, -0x04,0x00,0x00,0x40,0x87,0x01,0x50,0x70,0x86,0x68,0xEF,0xA4,0x04,0x00,0x00,0x70, -0x7B,0x2B,0x3C,0x6F,0x64,0x59,0x5B,0x1C,0x83,0x64,0x70,0x87,0x73,0xE0,0x40,0xD0, -0x15,0x40,0x40,0x87,0x01,0xC0,0x05,0x70,0xA0,0x14,0x2C,0xCC,0xFC,0xEF,0x28,0x05, -0x00,0x00,0x90,0x59,0x70,0x3C,0x6F,0x64,0x59,0x5B,0xA1,0x2C,0x5C,0xAF,0xA3,0x02, -0x3C,0x01,0x40,0x7F,0x1C,0x83,0x64,0x70,0x87,0x73,0xE0,0x40,0xD0,0x15,0x40,0x40, -0x87,0x01,0xC0,0x05,0x70,0xA0,0x14,0x2C,0xCC,0xFC,0xEF,0x28,0x05,0x00,0x00,0x87, -0x64,0xE0,0x40,0x7B,0x02,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x10,0x49, -0x9C,0x4F,0x08,0x00,0x00,0x00,0x4C,0x87,0x73,0xE0,0x40,0xD0,0x15,0x40,0x40,0x87, -0x01,0xC0,0x05,0x70,0xA0,0x14,0x2C,0xCC,0xFC,0xEF,0x28,0x05,0x00,0x00,0x87,0x73, -0xE0,0x40,0xA0,0x40,0x2C,0xCC,0xFC,0xAF,0xF8,0xFA,0x28,0x40,0x77,0x0A,0x80,0x40, -0x24,0x7F,0xA3,0x5B,0x00,0x00,0x84,0xEF,0x94,0x04,0x00,0x00,0x7F,0xC8,0x12,0x00, -0x02,0x70,0x84,0x4F,0x00,0x5D,0x00,0x00,0xEF,0x94,0x04,0x00,0x00,0x70,0x70,0xCC, -0x03,0x0D,0x4B,0x7F,0xC4,0x12,0x00,0x02,0x70,0xC8,0x03,0x0D,0x0F,0x4B,0x87,0x0A, -0x7F,0xF7,0x37,0x00,0x02,0x70,0x87,0x77,0x7F,0xF6,0x37,0x00,0x02,0x70,0x87,0x5F, -0xFF,0x00,0x7F,0xEF,0x37,0x00,0x02,0x70,0x87,0x73,0xE0,0x40,0xD0,0x15,0x40,0x40, -0x87,0xC0,0x01,0xE0,0x64,0x70,0x80,0x64,0x70,0x7B,0x31,0xA0,0x01,0x2C,0xCC,0xFC, -0xEF,0x28,0x05,0x00,0x00,0x3F,0x5F,0xFF,0x00,0x7F,0xEF,0x37,0x00,0x02,0x7F,0x19, -0x2B,0x7F,0xEF,0x37,0x00,0x02,0x77,0x0C,0x84,0x7F,0xF0,0x37,0x00,0x02,0x59,0x70, -0x7B,0x11,0x80,0x59,0x70,0x7B,0x0C,0x90,0x64,0x70,0x3C,0x5F,0x30,0x75,0x64,0x4B, -0xCC,0x2C,0x5C,0xAF,0xAD,0x01,0x28,0x40,0x7F,0x07,0x84,0x59,0x40,0x7B,0x06,0x80, -0x40,0x7B,0x02,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x10,0x49,0x9C,0x4F,0x08,0x00, -0x00,0x00,0x4C,0x70,0xCC,0x03,0x0D,0x4B,0x7F,0xC4,0x12,0x00,0x02,0x70,0xC8,0x03, -0x0D,0x0F,0x4B,0x84,0xEF,0x94,0x04,0x00,0x00,0x7F,0xC8,0x12,0x00,0x02,0x70,0x84, -0x4F,0x00,0x5D,0x00,0x00,0xEF,0x94,0x04,0x00,0x00,0x70,0x83,0x59,0x70,0x84,0x74, -0x7F,0xB0,0x12,0x00,0x02,0x70,0x84,0x78,0x7F,0xB4,0x12,0x00,0x02,0x70,0x3F,0x01, -0xCA,0x0F,0x77,0x0C,0x87,0x0C,0x7F,0xF7,0x37,0x00,0x02,0x70,0x7B,0x2F,0x2B,0xCA, -0x0F,0x77,0x0C,0x87,0x0B,0x7F,0xF7,0x37,0x00,0x02,0x70,0x7B,0x20,0x84,0x7F,0xC8, -0x12,0x00,0x02,0xEF,0x94,0x04,0x00,0x00,0x70,0xC8,0x03,0x0D,0x7F,0xC4,0x12,0x00, -0x02,0x4B,0x84,0x00,0x40,0x24,0x7F,0xF9,0x5C,0x00,0x00,0xFB,0x5F,0xF0,0x00,0x73, -0x40,0xD4,0x04,0x40,0x40,0x87,0x40,0x62,0x70,0x2B,0x62,0x77,0x0A,0x80,0x40,0x24, -0x7F,0xF9,0x5C,0x00,0x00,0xFB,0x0F,0x73,0x40,0x87,0x40,0x61,0x70,0x87,0x61,0x7F, -0xF6,0x37,0x00,0x02,0x70,0x84,0x4F,0xB0,0x12,0x00,0x02,0x7F,0xF8,0x37,0x00,0x02, -0x70,0x87,0x5F,0xFF,0x00,0x7F,0xEF,0x37,0x00,0x02,0x70,0x87,0x62,0xE0,0x40,0xD0, -0x15,0x40,0x40,0x87,0xC0,0x01,0xE0,0x64,0x70,0x80,0x64,0x70,0x7B,0x2D,0xA0,0x01, -0x2C,0xCC,0xFC,0xEF,0x28,0x05,0x00,0x00,0x3F,0x5F,0xFF,0x00,0x7F,0xEF,0x37,0x00, -0x02,0x7F,0x15,0x2B,0x7F,0xEF,0x37,0x00,0x02,0x77,0x08,0x87,0x01,0x59,0x70,0x7B, -0x11,0x83,0x59,0x70,0x7B,0x0C,0x90,0x64,0x70,0x3C,0x5F,0x28,0x23,0x64,0x4B,0xD0, -0x2C,0x5C,0xAF,0x8E,0x00,0x28,0x40,0x7F,0x06,0x2B,0x59,0x77,0x39,0xA0,0x4F,0x44, -0x0D,0x00,0x00,0x2B,0xCA,0x0F,0x77,0x0B,0x84,0x4F,0x80,0x0D,0x00,0x00,0x40,0x7B, -0x09,0x84,0x4F,0x85,0x0D,0x00,0x00,0x40,0xA0,0x40,0xA0,0x74,0x87,0x61,0xE0,0x40, -0xA0,0x40,0x87,0x62,0xE0,0x40,0xA0,0x40,0x2C,0xCC,0xEC,0x7F,0xE4,0x44,0x00,0x00, -0x80,0x40,0x7B,0x07,0x84,0x01,0x40,0x7B,0x02,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08, -0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0xC8,0x03,0x0D,0x0F,0x4B,0x2C,0x5C, -0x7F,0xDE,0x62,0x00,0x00,0x86,0xE2,0x7F,0x02,0x40,0x04,0x00,0xE0,0x40,0x38,0x40, -0x6F,0x7E,0x7F,0x0C,0x86,0x01,0x7F,0xCE,0x12,0x00,0x02,0x70,0x7B,0x09,0x82,0x7F, -0xCC,0x12,0x00,0x02,0x70,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x10,0x49, -0x9C,0x4F,0x04,0x00,0x00,0x00,0x4C,0x86,0x01,0x7F,0xCC,0x12,0x00,0x02,0x70,0x80, -0x59,0x70,0x82,0x7F,0xCE,0x12,0x00,0x02,0x70,0xC8,0x03,0x0D,0x00,0x4B,0x70,0x70, -0x70,0x70,0xC8,0x03,0x0D,0x0F,0x4B,0x86,0xE2,0x7F,0xCC,0x12,0x00,0x02,0xE0,0x40, -0x77,0x1C,0x84,0x7F,0xC8,0x12,0x00,0x02,0xEF,0x94,0x04,0x00,0x00,0x70,0xC8,0x03, -0x0D,0x7F,0xC4,0x12,0x00,0x02,0x4B,0x84,0x01,0x40,0x7B,0x4D,0x3C,0x5F,0xFF,0x00, -0x59,0x4F,0x1C,0x84,0x7F,0xC8,0x12,0x00,0x02,0xEF,0x94,0x04,0x00,0x00,0x70,0xC8, -0x03,0x0D,0x7F,0xC4,0x12,0x00,0x02,0x4B,0x84,0x00,0x40,0x7B,0x2C,0x86,0xE2,0x7F, -0xCE,0x12,0x00,0x02,0xE0,0x40,0x7F,0x1C,0x84,0x7F,0xC8,0x12,0x00,0x02,0xEF,0x94, -0x04,0x00,0x00,0x70,0xC8,0x03,0x0D,0x7F,0xC4,0x12,0x00,0x02,0x4B,0x84,0x00,0x40, -0x7B,0x07,0x90,0x59,0x70,0x7B,0x84,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70, -0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x2C,0x5C,0xAF,0x89,0x01,0x87,0x01, -0xEF,0xC4,0x04,0x00,0x00,0x70,0x38,0x7F,0x5C,0x08,0x00,0x02,0x4F,0x00,0x00,0x00, -0x20,0x7F,0x24,0xA0,0x4F,0x8C,0x0D,0x00,0x00,0xA0,0x4F,0xC0,0x0D,0x00,0x00,0x2C, -0xCC,0xF8,0x7F,0xE4,0x44,0x00,0x00,0xA0,0x4F,0xD9,0x0D,0x00,0x00,0x2C,0xCC,0xFC, -0x7F,0xE4,0x44,0x00,0x00,0x38,0x7F,0x5C,0x08,0x00,0x02,0x4F,0x00,0x00,0x00,0x40, -0x7F,0x10,0xA0,0x4F,0x2E,0x0E,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xE4,0x44,0x00,0x00, -0x38,0x7F,0x5C,0x08,0x00,0x02,0x02,0x7F,0x16,0xA0,0x4F,0x8C,0x0D,0x00,0x00,0xA0, -0x4F,0x5A,0x0E,0x00,0x00,0x2C,0xCC,0xF8,0x7F,0xE4,0x44,0x00,0x00,0x38,0x7F,0x5C, -0x08,0x00,0x02,0x01,0x7F,0x16,0xA0,0x4F,0x8C,0x0D,0x00,0x00,0xA0,0x4F,0x72,0x0E, -0x00,0x00,0x2C,0xCC,0xF8,0x7F,0xE4,0x44,0x00,0x00,0x38,0x7F,0x5C,0x08,0x00,0x02, -0x04,0x7F,0x16,0xA0,0x4F,0x8C,0x0D,0x00,0x00,0xA0,0x4F,0x91,0x0E,0x00,0x00,0x2C, -0xCC,0xF8,0x7F,0xE4,0x44,0x00,0x00,0x38,0x7F,0x5C,0x08,0x00,0x02,0x20,0x7F,0x16, -0xA0,0x4F,0x8C,0x0D,0x00,0x00,0xA0,0x4F,0xA2,0x0E,0x00,0x00,0x2C,0xCC,0xF8,0x7F, -0xE4,0x44,0x00,0x00,0x38,0x7F,0x5C,0x08,0x00,0x02,0x08,0x7F,0x16,0xA0,0x4F,0x8C, -0x0D,0x00,0x00,0xA0,0x4F,0xC0,0x0E,0x00,0x00,0x2C,0xCC,0xF8,0x7F,0xE4,0x44,0x00, -0x00,0x38,0x7F,0x5C,0x08,0x00,0x02,0x10,0x7F,0x16,0xA0,0x4F,0x8C,0x0D,0x00,0x00, -0xA0,0x4F,0xD8,0x0E,0x00,0x00,0x2C,0xCC,0xF8,0x7F,0xE4,0x44,0x00,0x00,0x28,0x7F, -0x5C,0x08,0x00,0x02,0x7F,0x23,0x3C,0x4F,0x00,0x00,0x00,0x01,0x7F,0x5C,0x08,0x00, -0x02,0x53,0x16,0xA0,0x4F,0x03,0x0F,0x00,0x00,0xA0,0x4F,0x9C,0x0D,0x00,0x00,0x2C, -0xCC,0xF8,0x7F,0xE4,0x44,0x00,0x00,0x3C,0x4F,0x00,0x00,0x00,0x80,0x7F,0x5C,0x08, -0x00,0x02,0x77,0x29,0x3C,0x4F,0xEF,0xBE,0xED,0xFE,0x7F,0x64,0x08,0x00,0x02,0x7F, -0x1C,0xA0,0x4F,0x06,0x0F,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xE4,0x44,0x00,0x00,0xB8, -0x4F,0xFF,0xFF,0xFF,0x7F,0x7F,0x5C,0x08,0x00,0x02,0x70,0xDC,0x04,0x7F,0xA4,0x04, -0x00,0x00,0x40,0x3F,0x01,0x50,0x77,0x09,0x80,0x7F,0x5C,0x08,0x00,0x02,0x70,0xA0, -0x01,0x2C,0xCC,0xFC,0xEF,0x28,0x05,0x00,0x00,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08, -0x70,0x70,0x10,0x49,0x9C,0x4F,0x04,0x00,0x00,0x00,0x4C,0x87,0x01,0x7F,0x03,0x40, -0x04,0x00,0x70,0x87,0x01,0x7F,0x07,0x40,0x04,0x00,0x70,0x87,0x01,0x7F,0x0F,0x40, -0x04,0x00,0x70,0x87,0x01,0x7F,0x3F,0x40,0x04,0x00,0x70,0x87,0x01,0x7F,0x37,0x40, -0x04,0x00,0x70,0x87,0x01,0x7F,0x0D,0x80,0x04,0x00,0x70,0x87,0x7F,0x11,0x90,0x04, -0x00,0x59,0x70,0x87,0x7F,0x00,0xD0,0x04,0x00,0x59,0x70,0x87,0x6F,0x56,0x7F,0x0F, -0x20,0x04,0x00,0x70,0x87,0x7F,0x13,0x20,0x04,0x00,0x59,0x70,0x87,0x01,0x7F,0x27, -0x40,0x04,0x00,0x70,0x87,0x01,0x7F,0x2F,0x40,0x04,0x00,0x70,0x04,0xC9,0xE8,0x4C, -0x20,0x49,0x08,0x70,0x70,0x70,0x10,0x49,0x9C,0x4F,0x10,0x00,0x00,0x00,0x4C,0xA0, -0x4F,0xEC,0x31,0x04,0x00,0xE0,0x59,0xA0,0x04,0x2C,0xCC,0xF4,0x7F,0x24,0x52,0x00, -0x00,0x3C,0x4F,0xEF,0xBE,0x0D,0x60,0x59,0x7F,0x08,0x24,0x7F,0x4E,0x61,0x00,0x00, -0xA0,0x4F,0xF0,0x31,0x04,0x00,0xE0,0x59,0xA0,0x04,0x2C,0xCC,0xF4,0x7F,0x24,0x52, -0x00,0x00,0x28,0x59,0x77,0x16,0xA0,0x4F,0x14,0x0F,0x00,0x00,0x2C,0xCC,0xFC,0x7F, -0xE4,0x44,0x00,0x00,0x24,0x7F,0xB9,0x61,0x00,0x00,0x38,0x59,0x6F,0x40,0x77,0x0F, -0x38,0x59,0x5F,0x80,0x00,0x77,0x08,0x24,0x7F,0xD0,0x60,0x00,0x00,0xA0,0x4F,0xF4, -0x31,0x04,0x00,0xE0,0x68,0xA0,0x04,0x2C,0xCC,0xF4,0x7F,0x24,0x52,0x00,0x00,0xA0, -0x4F,0xF8,0x31,0x04,0x00,0xE0,0x64,0xA0,0x04,0x2C,0xCC,0xF4,0x7F,0x24,0x52,0x00, -0x00,0xA0,0x4F,0xFC,0x31,0x04,0x00,0xE0,0x6C,0xA0,0x04,0x2C,0xCC,0xF4,0x7F,0x24, -0x52,0x00,0x00,0x38,0x59,0x6F,0x40,0x7F,0x20,0xA0,0x4F,0x1C,0x0F,0x00,0x00,0xA0, -0x64,0xA0,0x68,0xF8,0x4F,0xFF,0xFF,0x00,0x00,0x6C,0x40,0xA0,0x40,0x2C,0xCC,0xF0, -0x7F,0xE4,0x44,0x00,0x00,0x7B,0x29,0xA0,0x4F,0x52,0x0F,0x00,0x00,0xA0,0x64,0xA0, -0x68,0xF8,0x4F,0xFF,0xFF,0x00,0x00,0x6C,0x40,0xA0,0x40,0xD4,0x10,0x6C,0x40,0xB8, -0x5F,0xFF,0x00,0x40,0xA0,0x40,0x2C,0xCC,0xEC,0x7F,0xE4,0x44,0x00,0x00,0x7B,0x7E, -0x38,0x59,0x02,0x7F,0x79,0xA0,0x4F,0x92,0x0F,0x00,0x00,0xD4,0x17,0x59,0x40,0xB8, -0x01,0x40,0xA0,0x40,0xD4,0x10,0x59,0x40,0xB8,0x6F,0x7F,0x40,0xA0,0x40,0x2C,0xCC, -0xF4,0x7F,0xE4,0x44,0x00,0x00,0xA0,0x4F,0xFC,0x31,0x04,0x00,0xE0,0x6C,0xA0,0x04, -0x2C,0xCC,0xF4,0x7F,0x24,0x52,0x00,0x00,0x28,0x6C,0x7F,0x34,0xA0,0x4F,0xB0,0x0F, -0x00,0x00,0xD4,0x18,0x6C,0x40,0xA0,0x40,0xD4,0x10,0x6C,0x40,0xB8,0x5F,0xFF,0x00, -0x40,0xA0,0x40,0xD4,0x08,0x6C,0x40,0xB8,0x5F,0xFF,0x00,0x40,0xA0,0x40,0xF8,0x5F, -0xFF,0x00,0x6C,0x40,0xA0,0x40,0x2C,0xCC,0xEC,0x7F,0xE4,0x44,0x00,0x00,0xA0,0x4F, -0xFF,0x0F,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xE4,0x44,0x00,0x00,0x7B,0x10,0xA0,0x4F, -0x02,0x10,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xE4,0x44,0x00,0x00,0x80,0x59,0x70,0xE0, -0x59,0xA0,0x4F,0xF0,0x31,0x04,0x00,0xA0,0x04,0x2C,0xCC,0xF4,0x7F,0xA0,0x52,0x00, -0x00,0xE0,0x59,0xA0,0x4F,0xF4,0x31,0x04,0x00,0xA0,0x04,0x2C,0xCC,0xF4,0x7F,0xA0, -0x52,0x00,0x00,0xE0,0x59,0xA0,0x4F,0xF8,0x31,0x04,0x00,0xA0,0x04,0x2C,0xCC,0xF4, -0x7F,0xA0,0x52,0x00,0x00,0xE0,0x59,0xA0,0x4F,0xFC,0x31,0x04,0x00,0xA0,0x04,0x2C, -0xCC,0xF4,0x7F,0xA0,0x52,0x00,0x00,0xE0,0x59,0xA0,0x4F,0xEC,0x31,0x04,0x00,0xA0, -0x04,0x2C,0xCC,0xF4,0x7F,0xA0,0x52,0x00,0x00,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08, -0x10,0x49,0x9C,0x4F,0x0C,0x00,0x00,0x00,0x4C,0xA0,0x4F,0xEC,0x31,0x04,0x00,0xE0, -0x64,0xA0,0x04,0x2C,0xCC,0xF4,0x7F,0x24,0x52,0x00,0x00,0x3C,0x4F,0xEF,0xBE,0x0D, -0x60,0x64,0x77,0x16,0xA0,0x4F,0xF0,0x31,0x04,0x00,0xE0,0x59,0xA0,0x04,0x2C,0xCC, -0xF4,0x7F,0x24,0x52,0x00,0x00,0x7B,0x0A,0x84,0x7F,0x5C,0x08,0x00,0x02,0x59,0x70, -0x80,0x64,0x70,0xE0,0x64,0xA0,0x4F,0xEC,0x31,0x04,0x00,0xA0,0x04,0x2C,0xCC,0xF4, -0x7F,0xA0,0x52,0x00,0x00,0xB0,0x5A,0x59,0x70,0x84,0x59,0x7F,0x5C,0x08,0x00,0x02, -0x70,0xE0,0x59,0xA0,0x4F,0xF0,0x31,0x04,0x00,0xA0,0x04,0x2C,0xCC,0xF4,0x7F,0xA0, -0x52,0x00,0x00,0x38,0x5A,0x6F,0x40,0x77,0x09,0x38,0x5A,0x5F,0x80,0x00,0x7F,0x63, -0xA0,0x4F,0x58,0x12,0x00,0x02,0xA0,0x4F,0xF4,0x31,0x04,0x00,0xA0,0x04,0x2C,0xCC, -0xF4,0x7F,0xA0,0x52,0x00,0x00,0xA0,0x4F,0x5C,0x12,0x00,0x02,0xA0,0x4F,0xF8,0x31, -0x04,0x00,0xA0,0x04,0x2C,0xCC,0xF4,0x7F,0xA0,0x52,0x00,0x00,0x86,0xE2,0x7F,0x02, -0x40,0x04,0x00,0xE0,0x68,0x70,0x38,0x5A,0x5F,0x80,0x00,0x7F,0x12,0x87,0x7F,0x60, -0x12,0x00,0x02,0xE0,0x40,0xD0,0x10,0x40,0x40,0xB0,0x40,0x68,0x70,0xE0,0x68,0xA0, -0x4F,0xFC,0x31,0x04,0x00,0xA0,0x04,0x2C,0xCC,0xF4,0x7F,0xA0,0x52,0x00,0x00,0x7B, -0x1D,0x38,0x5A,0x02,0x7F,0x18,0xA0,0x4F,0xD4,0x12,0x00,0x02,0xA0,0x4F,0xFC,0x31, -0x04,0x00,0xA0,0x04,0x2C,0xCC,0xF4,0x7F,0xA0,0x52,0x00,0x00,0x84,0x4F,0xEF,0xBE, -0x0D,0x60,0x64,0x70,0xE0,0x64,0xA0,0x4F,0xEC,0x31,0x04,0x00,0xA0,0x04,0x2C,0xCC, -0xF4,0x7F,0xA0,0x52,0x00,0x00,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x10,0x49, -0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x3F,0x01,0xEF,0x10,0x05,0x00,0x00,0x7F,0x2B, -0x3F,0x6F,0x64,0x7F,0x03,0x20,0x04,0x00,0x7F,0x21,0x80,0xEF,0x8C,0x04,0x00,0x00, -0x70,0x80,0xEF,0x14,0x05,0x00,0x00,0x70,0x83,0x7F,0x0D,0x90,0x04,0x00,0x70,0x87, -0x04,0x7F,0x0E,0x90,0x04,0x00,0x70,0x7B,0x00,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08, -0x70,0x70,0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x2C,0x5C,0xCF,0xB3,0x84, -0x5A,0xEF,0x8C,0x04,0x00,0x00,0x70,0x87,0x01,0x7F,0x0B,0x40,0x04,0x00,0x70,0x7B, -0x00,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x10,0x49,0x9C,0x4F,0x00,0x00, -0x00,0x00,0x4C,0x84,0x4F,0xEF,0xBE,0xED,0xFE,0xEF,0x8C,0x04,0x00,0x00,0x70,0x2C, -0x5C,0xAF,0x81,0xFA,0x87,0x01,0x7F,0x0B,0x40,0x04,0x00,0x70,0x7B,0x00,0x04,0xC9, -0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x70,0x10,0x49,0x9C,0x4F,0x04,0x00,0x00,0x00, -0x4C,0xDC,0x02,0x7F,0xA4,0x04,0x00,0x00,0x40,0x2B,0x50,0x77,0x0B,0x84,0x01,0x40, -0x24,0x7F,0xE5,0x64,0x00,0x00,0x86,0x01,0x59,0x70,0x7B,0x2D,0x86,0xE2,0x59,0xE0, -0x40,0xD0,0x05,0x40,0x40,0x9C,0x7F,0x90,0x04,0x00,0x00,0x40,0xCC,0x03,0x0C,0x50, -0x40,0xDC,0x02,0x7F,0xA4,0x04,0x00,0x00,0x41,0x87,0x51,0xE0,0x41,0x3C,0x41,0x40, -0x77,0x04,0x7B,0x17,0x92,0x59,0x70,0x86,0xE2,0x59,0xE0,0x40,0x87,0xEF,0xE0,0x04, -0x00,0x00,0xE0,0x41,0x3C,0x41,0x40,0x5B,0xC5,0x86,0xE2,0x59,0xE0,0x40,0x87,0xEF, -0xE0,0x04,0x00,0x00,0xE0,0x41,0x3C,0x41,0x40,0x5B,0x2A,0xDC,0x02,0x7F,0xA4,0x04, -0x00,0x00,0x40,0x83,0x50,0x70,0xDC,0x03,0x7F,0xA4,0x04,0x00,0x00,0x40,0x83,0x50, -0x70,0x86,0x5F,0xBD,0x04,0xEF,0xA4,0x04,0x00,0x00,0x70,0x80,0x40,0x24,0x7F,0xE5, -0x64,0x00,0x00,0xDC,0x02,0x7F,0xA4,0x04,0x00,0x00,0x40,0x87,0x50,0xE0,0x40,0xD0, -0x15,0x40,0x40,0x87,0x01,0xC0,0x05,0x70,0xA0,0x14,0x2C,0xCC,0xFC,0xEF,0x28,0x05, -0x00,0x00,0xDC,0x02,0x7F,0xA4,0x04,0x00,0x00,0x40,0x87,0x50,0xE0,0x40,0xA0,0x40, -0x2C,0xCC,0xFC,0x7F,0xEC,0x55,0x00,0x00,0x3C,0x01,0x40,0x7F,0x08,0x24,0x7F,0xE1, -0x64,0x00,0x00,0xDC,0x02,0x7F,0xA4,0x04,0x00,0x00,0x40,0x87,0x50,0xE0,0x40,0xA0, -0x40,0xDC,0x03,0x7F,0xA4,0x04,0x00,0x00,0x40,0x87,0x50,0xE0,0x40,0xA0,0x40,0x2C, -0xCC,0xF8,0x7F,0xC6,0x59,0x00,0x00,0x3C,0x01,0x40,0x77,0x67,0xDC,0x04,0x7F,0xA4, -0x04,0x00,0x00,0x40,0x87,0x01,0x50,0x70,0x86,0xEF,0xA4,0x04,0x00,0x00,0x59,0x70, -0xE0,0x59,0xA0,0x4F,0x80,0x30,0x04,0x00,0xA0,0x02,0x2C,0xCC,0xF4,0x7F,0xA0,0x52, -0x00,0x00,0xDC,0x02,0x7F,0xA4,0x04,0x00,0x00,0x40,0x87,0x50,0xE0,0x40,0xD0,0x04, -0x40,0x40,0xBB,0x5F,0xF0,0x00,0x40,0xDC,0x03,0x7F,0xA4,0x04,0x00,0x00,0x41,0xFB, -0x0F,0x51,0x41,0xB3,0x41,0x40,0x87,0x40,0x62,0x70,0xE0,0x62,0xA0,0x4F,0x09,0x30, -0x04,0x00,0xA0,0x01,0x2C,0xCC,0xF4,0x7F,0xA0,0x52,0x00,0x00,0x84,0x01,0x40,0x7B, -0x06,0x80,0x40,0x7B,0x02,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x10,0x49,0x9C,0x4F, -0x00,0x00,0x00,0x00,0x4C,0x2C,0x5C,0xEF,0xF8,0x11,0x00,0x02,0x04,0xC9,0xE8,0x4C, -0x20,0x49,0x08,0x70,0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0xA0,0x5F,0x80, -0x00,0x2C,0xCC,0xFC,0x7F,0xC0,0x61,0x00,0x00,0xA0,0x4F,0x8C,0x0D,0x00,0x00,0xA0, -0x4F,0x0C,0x10,0x00,0x00,0x2C,0xCC,0xF8,0x7F,0xE4,0x44,0x00,0x00,0xA0,0x4F,0x9C, -0x0D,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xE4,0x44,0x00,0x00,0xA0,0x4F,0xEF,0xBE,0xED, -0xFE,0x2C,0xCC,0xFC,0x7F,0x22,0x63,0x00,0x00,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08, -0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0xF8,0x03,0x7F,0x58,0x12,0x00,0x02, -0x40,0x3C,0x03,0x40,0x77,0x31,0xF8,0x6F,0x78,0x7F,0x58,0x12,0x00,0x02,0x40,0x3C, -0x6F,0x70,0x40,0x7F,0x10,0xF8,0x6F,0x78,0x7F,0x58,0x12,0x00,0x02,0x40,0x3C,0x08, -0x40,0x77,0x0B,0x2C,0x5C,0xEF,0xD8,0x12,0x00,0x02,0x7B,0x09,0x2C,0x5C,0xEF,0xF4, -0x11,0x00,0x02,0x7B,0x09,0x2C,0x5C,0xEF,0xF4,0x11,0x00,0x02,0x04,0xC9,0xE8,0x4C, -0x20,0x49,0x08,0x70,0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0xA0,0x6F,0x40, -0x2C,0xCC,0xFC,0x7F,0xC0,0x61,0x00,0x00,0xA0,0x4F,0x8C,0x0D,0x00,0x00,0xA0,0x4F, -0x28,0x10,0x00,0x00,0x2C,0xCC,0xF8,0x7F,0xE4,0x44,0x00,0x00,0xA0,0x4F,0x9C,0x0D, -0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xE4,0x44,0x00,0x00,0xA0,0x4F,0xEF,0xBE,0xED,0xFE, -0x2C,0xCC,0xFC,0x7F,0x22,0x63,0x00,0x00,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70, -0x10,0x48,0x9C,0x4F,0x74,0x00,0x00,0x00,0x4C,0x87,0x01,0xEF,0xC4,0x04,0x00,0x00, -0x70,0x84,0x4F,0x04,0x65,0x00,0x00,0x7F,0xF8,0x11,0x00,0x02,0x70,0x84,0x4F,0xA4, -0x65,0x00,0x00,0x7F,0xF4,0x11,0x00,0x02,0x70,0x84,0x7F,0xF4,0x11,0x00,0x02,0x7F, -0xD8,0x12,0x00,0x02,0x70,0x3C,0x4F,0xEF,0xBE,0xED,0xFE,0x7F,0x64,0x08,0x00,0x02, -0x7F,0x09,0x84,0x4F,0x00,0x00,0x80,0x00,0x4B,0x84,0x7F,0x64,0x08,0x00,0x02,0x48, -0x3C,0x4F,0xEF,0xBE,0xED,0xFE,0x7F,0x64,0x08,0x00,0x02,0x7F,0x15,0x3C,0x4F,0x1E, -0xAC,0xEB,0xAD,0x7F,0x64,0x08,0x00,0x02,0x7F,0x08,0x24,0x7F,0x38,0x68,0x00,0x00, -0x84,0x4F,0xD0,0xF1,0x02,0x3B,0x7F,0x64,0x08,0x00,0x02,0x70,0xA0,0x4F,0x00,0x30, -0x04,0x00,0xE0,0xC9,0x64,0xA0,0x09,0x2C,0xCC,0xF4,0x7F,0x24,0x52,0x00,0x00,0x2B, -0xC9,0x64,0x77,0x26,0xE0,0xC9,0x64,0xA0,0x4F,0x40,0x10,0x00,0x00,0x2C,0xCC,0xF8, -0x7F,0xB0,0x7F,0x00,0x00,0xE0,0xC9,0x64,0xA0,0x4F,0x00,0x30,0x04,0x00,0xA0,0x09, -0x2C,0xCC,0xF4,0x7F,0xA0,0x52,0x00,0x00,0x3C,0x4F,0x0D,0xF0,0xAD,0x8B,0x48,0x77, -0x08,0x24,0x7F,0x3C,0x67,0x00,0x00,0x3C,0x4F,0xEF,0xBE,0xED,0xFE,0x48,0x7F,0x7E, -0xDC,0x04,0x7F,0xA4,0x04,0x00,0x00,0x40,0x2B,0x50,0x77,0x72,0xA0,0x4F,0x0C,0x30, -0x04,0x00,0xE0,0xC9,0x6E,0xA0,0x01,0x2C,0xCC,0xF4,0x7F,0x24,0x52,0x00,0x00,0x28, -0x40,0x77,0x28,0x87,0x01,0xC9,0x6E,0x70,0xE0,0xC9,0x6E,0xA0,0x4F,0x0C,0x30,0x04, -0x00,0xA0,0x01,0x2C,0xCC,0xF4,0x7F,0xA0,0x52,0x00,0x00,0xDC,0x01,0x7F,0xA0,0x04, -0x00,0x00,0x40,0x87,0x01,0x50,0x70,0x7B,0x0F,0xDC,0x01,0x7F,0xA0,0x04,0x00,0x00, -0x40,0x87,0xC9,0x6E,0x50,0x70,0x83,0xEF,0xA0,0x04,0x00,0x00,0x70,0xDC,0x02,0x7F, -0xA0,0x04,0x00,0x00,0x40,0xA0,0x40,0xA0,0x4F,0x44,0x10,0x00,0x00,0x2C,0xCC,0xF8, -0x7F,0xB0,0x7F,0x00,0x00,0x2C,0x5C,0x7F,0x70,0x69,0x00,0x00,0x7B,0x57,0xDC,0x02, -0x7F,0xA4,0x04,0x00,0x00,0x40,0x83,0x50,0x70,0xDC,0x03,0x7F,0xA4,0x04,0x00,0x00, -0x40,0x83,0x50,0x70,0x87,0x01,0x7F,0x13,0x40,0x04,0x00,0x70,0x80,0xC9,0x70,0x70, -0x7B,0x06,0x90,0xC9,0x70,0x70,0x3C,0x4F,0x50,0xC3,0x00,0x00,0xC9,0x70,0x4B,0xF4, -0x87,0x01,0x7F,0x17,0x40,0x04,0x00,0x70,0x80,0xC9,0x70,0x70,0x7B,0x06,0x90,0xC9, -0x70,0x70,0x3C,0x4F,0xF0,0x49,0x02,0x00,0xC9,0x70,0x4B,0xF4,0x2C,0x5C,0x7F,0xDE, -0x62,0x00,0x00,0xDC,0x04,0x7F,0xA4,0x04,0x00,0x00,0x40,0x3F,0x01,0x50,0x7F,0x11, -0x8B,0x7F,0x0D,0x90,0x04,0x00,0x40,0xB8,0x01,0x40,0x3C,0x01,0x40,0x77,0x91,0x2C, -0x5C,0x7F,0xE0,0x5D,0x00,0x00,0x3C,0x4F,0xEF,0xBE,0xED,0xFE,0x48,0x77,0x1A,0x87, -0x01,0x7F,0x13,0x40,0x04,0x00,0x70,0xA0,0x4F,0x4D,0x10,0x00,0x00,0x2C,0xCC,0xFC, -0x7F,0xE4,0x44,0x00,0x00,0x7B,0x18,0x87,0x01,0x7F,0x17,0x40,0x04,0x00,0x70,0xA0, -0x4F,0x93,0x10,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xE4,0x44,0x00,0x00,0xE0,0x59,0x2C, -0xCC,0xFC,0x7F,0xB4,0x3A,0x00,0x00,0xE0,0x59,0xE0,0xC9,0x64,0x2C,0xCC,0xF8,0x7F, -0x68,0x7F,0x00,0x00,0x28,0x40,0x77,0x2F,0x84,0x4F,0xEF,0xBE,0xED,0xFE,0x7F,0x64, -0x08,0x00,0x02,0x70,0x2C,0x5C,0x7F,0x04,0x2B,0x00,0x00,0x84,0x7F,0x64,0x08,0x00, -0x02,0x48,0xA0,0x4F,0x00,0x30,0x04,0x00,0xE0,0xC9,0x64,0xA0,0x09,0x2C,0xCC,0xF4, -0x7F,0x24,0x52,0x00,0x00,0x7A,0x73,0xFE,0xA0,0x4F,0x0C,0x30,0x04,0x00,0xE0,0xC9, -0x6E,0xA0,0x01,0x2C,0xCC,0xF4,0x7F,0x24,0x52,0x00,0x00,0x28,0x40,0x77,0x28,0x87, -0x01,0xC9,0x6E,0x70,0xE0,0xC9,0x6E,0xA0,0x4F,0x0C,0x30,0x04,0x00,0xA0,0x01,0x2C, -0xCC,0xF4,0x7F,0xA0,0x52,0x00,0x00,0xDC,0x01,0x7F,0xA0,0x04,0x00,0x00,0x40,0x87, -0x01,0x50,0x70,0x7B,0x0F,0xDC,0x01,0x7F,0xA0,0x04,0x00,0x00,0x40,0x87,0xC9,0x6E, -0x50,0x70,0x83,0xEF,0xA0,0x04,0x00,0x00,0x70,0x3C,0x4F,0x0D,0xF0,0xAD,0x8B,0x48, -0x7F,0x56,0xDC,0x02,0x7F,0xA0,0x04,0x00,0x00,0x40,0xA0,0x40,0xA0,0x4F,0xA4,0x10, -0x00,0x00,0x2C,0xCC,0xF8,0x7F,0xB0,0x7F,0x00,0x00,0x2C,0x5C,0x7F,0x70,0x69,0x00, -0x00,0x28,0x40,0x77,0x09,0x2C,0x5C,0x7F,0x4A,0x63,0x00,0x00,0xDC,0x02,0x7F,0xA0, -0x04,0x00,0x00,0x40,0xA0,0x40,0xA0,0x4F,0xAD,0x10,0x00,0x00,0x2C,0xCC,0xF8,0x7F, -0xB0,0x7F,0x00,0x00,0x2C,0x5C,0x7F,0x70,0x69,0x00,0x00,0x28,0x40,0x77,0x09,0x2C, -0x5C,0x7F,0x4A,0x63,0x00,0x00,0x3C,0x4F,0xEF,0xBE,0xED,0xFE,0x7F,0x64,0x08,0x00, -0x02,0x7F,0x0A,0x87,0x01,0x7F,0x17,0x40,0x04,0x00,0x70,0xA0,0x4F,0x0D,0x30,0x04, -0x00,0xDC,0x02,0x7F,0xA0,0x04,0x00,0x00,0x40,0xA0,0x40,0xA0,0x2D,0x2C,0xCC,0xF4, -0x7F,0x24,0x52,0x00,0x00,0x28,0x40,0x77,0x34,0xDC,0x02,0x7F,0xA0,0x04,0x00,0x00, -0x40,0xA0,0x40,0xA0,0x4F,0xB4,0x10,0x00,0x00,0x2C,0xCC,0xF8,0x7F,0xB0,0x7F,0x00, -0x00,0xDC,0x02,0x7F,0xA0,0x04,0x00,0x00,0x40,0xA0,0x40,0xA0,0x4F,0x0D,0x30,0x04, -0x00,0xA0,0x2D,0x2C,0xCC,0xF4,0x7F,0xA0,0x52,0x00,0x00,0x87,0x02,0xEF,0xA0,0x04, -0x00,0x00,0x70,0x2C,0x5C,0x7F,0x70,0x69,0x00,0x00,0x2C,0x5C,0x7F,0x4A,0x63,0x00, -0x00,0x7A,0xD8,0xFC,0x04,0xC9,0xEC,0x4C,0x20,0x48,0x20,0x49,0x08,0x70,0x70,0x70, -0x10,0x49,0x9C,0x4F,0x10,0x00,0x00,0x00,0x4C,0x3F,0x01,0xEF,0xA0,0x04,0x00,0x00, -0x77,0x0F,0x3C,0x4F,0xF0,0xFF,0x00,0x00,0x7F,0x08,0x05,0x00,0x00,0x7F,0x26,0x84, -0x4F,0x52,0x6C,0x00,0x00,0x7F,0xF8,0x11,0x00,0x02,0x70,0x84,0x4F,0x9E,0x6C,0x00, -0x00,0x7F,0xD8,0x12,0x00,0x02,0x70,0x84,0x7F,0xD8,0x12,0x00,0x02,0x7F,0xF4,0x11, -0x00,0x02,0x70,0x3C,0x4F,0xD0,0xF1,0x02,0x3B,0x7F,0x6C,0x08,0x00,0x02,0x7F,0x55, -0x84,0x4F,0xD0,0xF1,0x02,0x3B,0x7F,0x6C,0x08,0x00,0x02,0x70,0x84,0xEF,0xE4,0x04, -0x00,0x00,0x59,0x70,0xDC,0x4F,0x00,0x00,0x00,0x02,0xEF,0xE4,0x04,0x00,0x00,0x40, -0xBC,0xEF,0xE8,0x04,0x00,0x00,0x40,0xD4,0x02,0x40,0x40,0x84,0x40,0x59,0x70,0x84, -0xEF,0xE8,0x04,0x00,0x00,0x40,0x80,0x50,0x70,0xA0,0x59,0xDC,0x04,0xEF,0xE8,0x04, -0x00,0x00,0x40,0xA0,0x40,0xA0,0xEF,0xE8,0x04,0x00,0x00,0x2C,0xCC,0xF4,0x7F,0x84, -0x40,0x00,0x00,0x83,0x7F,0x0D,0x90,0x04,0x00,0x70,0x87,0x08,0x7F,0x0F,0x90,0x04, -0x00,0x70,0x2C,0x5C,0x7F,0x72,0x5F,0x00,0x00,0xA0,0x00,0x2C,0xCC,0xFC,0xEF,0x40, -0x05,0x00,0x00,0x2B,0xEF,0xA0,0x04,0x00,0x00,0x7F,0x0F,0x3C,0x4F,0x00,0x80,0x00, -0x00,0x7F,0x08,0x05,0x00,0x00,0x43,0x10,0x84,0x4F,0xEF,0xBE,0xED,0xFE,0xEF,0x8C, -0x04,0x00,0x00,0x70,0x7B,0x0E,0x84,0x4F,0xED,0x0D,0x1C,0xA1,0xEF,0x8C,0x04,0x00, -0x00,0x70,0x84,0x4F,0x00,0x40,0x00,0x02,0x64,0x70,0xDC,0x01,0x7F,0xA0,0x04,0x00, -0x00,0x40,0x87,0x50,0xE0,0x40,0xD4,0x04,0x40,0x40,0x87,0x40,0x69,0x70,0xDC,0x01, -0x7F,0xA0,0x04,0x00,0x00,0x40,0x3F,0x01,0x50,0x77,0x4A,0x87,0x01,0x7F,0x1F,0x40, -0x04,0x00,0x70,0xA0,0x00,0x2C,0xCC,0xFC,0x7F,0x2C,0x73,0x00,0x00,0x28,0x40,0x77, -0x0A,0x80,0x40,0x24,0x7F,0x4B,0x6C,0x00,0x00,0xA0,0x00,0xA0,0x7F,0xA8,0x0A,0x00, -0x02,0xA0,0x4F,0x00,0x40,0x00,0x02,0xA0,0x00,0x2C,0xCC,0xF0,0x7F,0x98,0x76,0x00, -0x00,0x28,0x40,0x77,0x0A,0x80,0x40,0x24,0x7F,0x4B,0x6C,0x00,0x00,0x24,0x7F,0x99, -0x6B,0x00,0x00,0xDC,0x01,0x7F,0xA0,0x04,0x00,0x00,0x40,0x3F,0x02,0x50,0x77,0x46, -0x87,0x01,0x7F,0x1F,0x40,0x04,0x00,0x70,0xA0,0x01,0x2C,0xCC,0xFC,0x7F,0x2C,0x73, -0x00,0x00,0x28,0x40,0x77,0x0A,0x80,0x40,0x24,0x7F,0x4B,0x6C,0x00,0x00,0xA0,0x01, -0xA0,0x7F,0xFC,0x0A,0x00,0x02,0xA0,0x4F,0x00,0x40,0x00,0x02,0xA0,0x00,0x2C,0xCC, -0xF0,0x7F,0x98,0x76,0x00,0x00,0x28,0x40,0x77,0x0A,0x80,0x40,0x24,0x7F,0x4B,0x6C, -0x00,0x00,0x7B,0x77,0xDC,0x01,0x7F,0xA0,0x04,0x00,0x00,0x40,0x2B,0x50,0x77,0x2B, -0xA0,0x00,0xA0,0x4F,0x00,0x40,0x00,0x02,0xA0,0x00,0xA0,0x00,0x2C,0xCC,0xF0,0x7F, -0x2C,0x7B,0x00,0x00,0x28,0x40,0x77,0x11,0x2C,0x5C,0x7F,0x34,0x7A,0x00,0x00,0x80, -0x40,0x24,0x7F,0x4B,0x6C,0x00,0x00,0x7B,0x42,0xDC,0x01,0x7F,0xA0,0x04,0x00,0x00, -0x40,0xFB,0x0F,0x50,0x40,0x87,0x40,0x68,0x70,0x87,0x69,0xE0,0x40,0xA0,0x40,0x87, -0x68,0xE0,0x40,0xA0,0x40,0x2C,0xCC,0xF8,0x7F,0xCE,0x5A,0x00,0x00,0x84,0x40,0x64, -0x70,0x28,0x64,0x77,0x16,0x87,0x69,0xE0,0x40,0xD0,0x15,0x40,0x40,0x83,0xC0,0x05, -0x70,0x80,0x40,0x24,0x7F,0x4B,0x6C,0x00,0x00,0xA0,0x00,0x2C,0xCC,0xFC,0xEF,0x1C, -0x05,0x00,0x00,0x28,0x40,0x7F,0x47,0xA0,0x01,0x2C,0xCC,0xFC,0xEF,0x40,0x05,0x00, -0x00,0xDC,0x01,0x7F,0xA0,0x04,0x00,0x00,0x40,0x2B,0x50,0x77,0x0B,0x2C,0x5C,0x7F, -0x34,0x7A,0x00,0x00,0x7B,0x12,0x2B,0x69,0x7F,0x0E,0x87,0x69,0xE0,0x40,0xD0,0x15, -0x40,0x40,0x83,0xC0,0x05,0x70,0x3C,0x4F,0xEF,0xBE,0xED,0xFE,0x7F,0x64,0x08,0x00, -0x02,0x77,0x06,0x80,0x40,0x7B,0x05,0x84,0x01,0x40,0x7B,0x61,0xDC,0x04,0x64,0x40, -0x3C,0x50,0xD9,0x04,0x77,0x20,0xDC,0x04,0x64,0x40,0xDC,0x08,0x64,0x41,0x3C,0x51, -0x50,0x77,0x13,0xDC,0x08,0x64,0x40,0xDC,0x0C,0x64,0x41,0x3C,0x51,0x50,0x77,0x06, -0x80,0x40,0x7B,0x39,0x2C,0x5C,0xD9,0x04,0xDC,0x01,0x7F,0xA0,0x04,0x00,0x00,0x40, -0x2B,0x50,0x77,0x09,0x2C,0x5C,0x7F,0x34,0x7A,0x00,0x00,0xA0,0x01,0x2C,0xCC,0xFC, -0xEF,0x40,0x05,0x00,0x00,0x3C,0x4F,0xEF,0xBE,0xED,0xFE,0x7F,0x64,0x08,0x00,0x02, -0x77,0x06,0x80,0x40,0x7B,0x05,0x84,0x01,0x40,0x7B,0x02,0x04,0xC9,0xE8,0x4C,0x20, -0x49,0x08,0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0xA0,0x4F,0x8C,0x0D,0x00, -0x00,0xA0,0x4F,0xBC,0x10,0x00,0x00,0x2C,0xCC,0xF8,0xEF,0xB0,0x04,0x00,0x00,0xA0, -0x4F,0x9C,0x0D,0x00,0x00,0x2C,0xCC,0xFC,0xEF,0xB0,0x04,0x00,0x00,0xA0,0x5F,0x80, -0x00,0x2C,0xCC,0xFC,0x7F,0xC0,0x61,0x00,0x00,0xA0,0x4F,0xEF,0xBE,0xED,0xFE,0x2C, -0xCC,0xFC,0x7F,0x22,0x63,0x00,0x00,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x10,0x49, -0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0xA0,0x4F,0x8C,0x0D,0x00,0x00,0xA0,0x4F,0xD5, -0x10,0x00,0x00,0x2C,0xCC,0xF8,0xEF,0xB0,0x04,0x00,0x00,0xA0,0x4F,0x9C,0x0D,0x00, -0x00,0x2C,0xCC,0xFC,0xEF,0xB0,0x04,0x00,0x00,0xA0,0x6F,0x40,0x2C,0xCC,0xFC,0x7F, -0xC0,0x61,0x00,0x00,0xA0,0x4F,0xEF,0xBE,0xED,0xFE,0x2C,0xCC,0xFC,0x7F,0x22,0x63, -0x00,0x00,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x70,0x10,0x49,0x9C,0x4F, -0x00,0x00,0x00,0x00,0x4C,0xEC,0x4F,0x00,0x00,0x01,0x00,0x5A,0x40,0x86,0xE2,0x7A, -0xE0,0x41,0x9C,0x5A,0x41,0xBC,0x01,0x41,0xAC,0xE0,0x4F,0x00,0x00,0x01,0x00,0x41, -0x3C,0x41,0x40,0x53,0x0A,0x80,0x40,0x24,0x7F,0x1F,0x6E,0x00,0x00,0x83,0x7F,0x0D, -0x80,0x04,0x00,0x70,0x83,0x7F,0x08,0x80,0x04,0x00,0x70,0x83,0x7F,0x0C,0x80,0x04, -0x00,0x70,0x3B,0x77,0x01,0x7F,0x35,0x87,0x73,0x7F,0x02,0x80,0x04,0x00,0x70,0x87, -0x72,0x7F,0x02,0x80,0x04,0x00,0x70,0x3B,0x77,0x08,0x7F,0x12,0xF3,0x5F,0x80,0x00, -0x71,0x40,0x87,0x40,0x7F,0x03,0xE0,0x04,0x00,0x70,0x7B,0x0E,0xF3,0x00,0x71,0x40, -0x87,0x40,0x7F,0x03,0xE0,0x04,0x00,0x70,0x7B,0x33,0x87,0x73,0x7F,0x00,0x80,0x04, -0x00,0x70,0x87,0x72,0x7F,0x00,0x80,0x04,0x00,0x70,0x3B,0x77,0x08,0x7F,0x12,0xF3, -0x5F,0x80,0x00,0x71,0x40,0x87,0x40,0x7F,0x03,0x50,0x04,0x00,0x70,0x7B,0x0E,0xF3, -0x00,0x71,0x40,0x87,0x40,0x7F,0x03,0x50,0x04,0x00,0x70,0x83,0x7F,0x0C,0x80,0x04, -0x00,0x70,0x3B,0x77,0x01,0x7F,0x2E,0xFF,0x01,0x7B,0x40,0xBB,0x5F,0xFF,0x00,0x40, -0x87,0x40,0x7F,0x03,0x80,0x04,0x00,0x70,0x86,0xE2,0x7A,0xE0,0x40,0xBC,0x01,0x40, -0xD4,0x08,0x40,0x40,0xBB,0x5F,0xFF,0x00,0x40,0x87,0x40,0x7F,0x03,0x80,0x04,0x00, -0x70,0x7B,0x2C,0xFF,0x01,0x7B,0x40,0xBB,0x5F,0xFF,0x00,0x40,0x87,0x40,0x7F,0x01, -0x80,0x04,0x00,0x70,0x86,0xE2,0x7A,0xE0,0x40,0xBC,0x01,0x40,0xD4,0x08,0x40,0x40, -0xBB,0x5F,0xFF,0x00,0x40,0x87,0x40,0x7F,0x01,0x80,0x04,0x00,0x70,0x87,0x77,0x7F, -0x0B,0x80,0x04,0x00,0x70,0xFB,0x03,0x77,0x40,0x9F,0x01,0x40,0x8B,0x40,0x40,0xBB, -0x0F,0x40,0x87,0x40,0x7F,0x0F,0x80,0x04,0x00,0x70,0x84,0x01,0x40,0x7B,0x02,0x04, -0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x10,0x44,0x9C,0x4F,0x00,0x00,0x00,0x00, -0x4C,0x83,0x7F,0xF0,0x14,0x00,0x02,0x70,0xEB,0x6F,0x54,0x73,0x40,0x84,0x5F,0x00, -0x02,0x80,0xA4,0x0A,0x00,0x02,0x70,0xEB,0x6F,0x54,0x73,0x40,0x84,0x12,0x80,0xA0, -0x0A,0x00,0x02,0x70,0xEB,0x6F,0x54,0x73,0x40,0x84,0x04,0x80,0x9C,0x0A,0x00,0x02, -0x70,0xEB,0x6F,0x54,0x73,0x40,0x84,0x5F,0x32,0x01,0x80,0x98,0x0A,0x00,0x02,0x70, -0x80,0x7F,0x7C,0x0A,0x00,0x02,0x70,0x87,0x73,0xE0,0x40,0xA0,0x40,0xA0,0x00,0xA0, -0x4F,0x74,0x08,0x00,0x02,0xA0,0x00,0x2C,0xCC,0xF0,0x7F,0x98,0x76,0x00,0x00,0x28, -0x40,0x77,0x16,0x84,0x4F,0x00,0x00,0x01,0x00,0x7F,0x7C,0x0A,0x00,0x02,0x70,0x80, -0x40,0x24,0x7F,0xEC,0x70,0x00,0x00,0x3C,0x4F,0x0D,0x60,0x5E,0xCA,0x7F,0x78,0x08, -0x00,0x02,0x7F,0x16,0x84,0x4F,0x00,0x00,0x02,0x00,0x7F,0x7C,0x0A,0x00,0x02,0x70, -0x80,0x40,0x24,0x7F,0xEC,0x70,0x00,0x00,0xEB,0x6F,0x54,0x73,0x40,0x9C,0x4F,0x80, -0x0A,0x00,0x02,0x40,0x84,0x40,0x48,0x84,0x4F,0x74,0x08,0x00,0x02,0x47,0x82,0x46, -0x7B,0x12,0x84,0x48,0x40,0x90,0x48,0x84,0x47,0x41,0x90,0x47,0x87,0x51,0x50,0x70, -0x92,0x46,0x86,0xE2,0x46,0xE0,0x40,0x3C,0x6F,0x54,0x40,0x5B,0xE7,0x87,0x73,0xE0, -0x40,0xD0,0x01,0x40,0x40,0xEB,0x6F,0x54,0x73,0x41,0xEB,0x6F,0x54,0x73,0x42,0xEC, -0xE0,0x82,0xA4,0x0A,0x00,0x02,0x81,0xC0,0x0A,0x00,0x02,0x41,0x86,0x41,0x80,0xE8, -0x14,0x00,0x02,0x70,0x82,0x46,0x7B,0x1E,0x87,0x73,0xE0,0x40,0xD0,0x08,0x40,0x40, -0x9C,0x4F,0xE8,0x12,0x00,0x02,0x40,0x86,0xE2,0x46,0xE0,0x41,0x9C,0x41,0x40,0x83, -0x50,0x70,0x92,0x46,0x86,0xE2,0x46,0xE0,0x40,0x3C,0x5F,0x00,0x01,0x40,0x5B,0xDA, -0xEB,0x6F,0x54,0x73,0x40,0xEC,0xE0,0x08,0x80,0xA4,0x0A,0x00,0x02,0x40,0x86,0x40, -0x44,0x87,0x5F,0xFF,0x00,0x7F,0x71,0x08,0x00,0x02,0x70,0x87,0x73,0xE0,0x40,0xD0, -0x01,0x40,0x40,0x82,0x80,0xEC,0x14,0x00,0x02,0x70,0x24,0x7F,0x8B,0x70,0x00,0x00, -0x87,0x73,0xE0,0x40,0xA0,0x40,0xEB,0x6F,0x54,0x73,0x40,0x87,0x73,0xE0,0x41,0xD0, -0x01,0x41,0x41,0x86,0xE2,0x81,0xEC,0x14,0x00,0x02,0xE0,0x41,0xDC,0x41,0x80,0xBC, -0x0A,0x00,0x02,0x40,0xA0,0x40,0xA0,0x4F,0x74,0x08,0x00,0x02,0xA0,0x00,0x2C,0xCC, -0xF0,0x7F,0x98,0x76,0x00,0x00,0x28,0x40,0x77,0x2A,0x87,0x73,0xE0,0x40,0xD0,0x01, -0x40,0x40,0x86,0xE2,0x80,0xEC,0x14,0x00,0x02,0xE0,0x40,0x9C,0x06,0x40,0xD0,0x10, -0x40,0x40,0x84,0x40,0x7F,0x7C,0x0A,0x00,0x02,0x70,0x80,0x40,0x24,0x7F,0xEC,0x70, -0x00,0x00,0x82,0x45,0x7B,0x77,0x86,0xE2,0x45,0xE0,0x40,0xD0,0x03,0x40,0x40,0x3F, -0x5F,0xFF,0x00,0x80,0x74,0x08,0x00,0x02,0x77,0x04,0x7B,0x71,0x86,0xE2,0x45,0xE0, -0x40,0xD0,0x03,0x40,0x40,0x87,0x80,0x74,0x08,0x00,0x02,0xE0,0x40,0xD0,0x08,0x40, -0x40,0x86,0xE2,0x40,0xE0,0x40,0x86,0xE2,0x45,0xE0,0x41,0xD0,0x03,0x41,0x41,0x87, -0x81,0x75,0x08,0x00,0x02,0xE0,0x41,0x9C,0x41,0x40,0x86,0x40,0x46,0x87,0x73,0xE0, -0x40,0xD0,0x08,0x40,0x40,0x9C,0x4F,0xE8,0x12,0x00,0x02,0x40,0x86,0xE2,0x46,0xE0, -0x41,0xAC,0xE0,0x08,0x41,0x9C,0x41,0x40,0x86,0xE2,0x46,0xE0,0x41,0xA4,0xE0,0x08, -0x41,0xD0,0x41,0x01,0x41,0xB3,0x41,0x50,0x70,0x92,0x45,0x86,0xE2,0x45,0xE0,0x40, -0x86,0xE2,0x44,0xE0,0x41,0x3C,0x41,0x40,0x5A,0x7E,0xFF,0x86,0xE2,0x45,0xE0,0x40, -0x86,0xE2,0x44,0xE0,0x41,0x3C,0x41,0x40,0x53,0x04,0x7B,0x39,0x87,0x73,0xE0,0x40, -0xD0,0x01,0x40,0x40,0x92,0x80,0xEC,0x14,0x00,0x02,0x70,0x87,0x73,0xE0,0x40,0xD0, -0x01,0x40,0x40,0x86,0xE2,0x80,0xEC,0x14,0x00,0x02,0xE0,0x40,0x87,0x73,0xE0,0x41, -0xD0,0x01,0x41,0x41,0x86,0xE2,0x81,0xE8,0x14,0x00,0x02,0xE0,0x41,0x3C,0x41,0x40, -0x5A,0xD0,0xFE,0x87,0x73,0xE0,0x40,0xD0,0x01,0x40,0x40,0x87,0x73,0xE0,0x41,0xD0, -0x01,0x41,0x41,0x86,0xE2,0x81,0xE8,0x14,0x00,0x02,0xE0,0x41,0xBE,0x01,0x41,0x86, -0x41,0x80,0xEC,0x14,0x00,0x02,0x70,0x87,0x73,0x7F,0x71,0x08,0x00,0x02,0x70,0x87, -0x01,0x7F,0xF0,0x14,0x00,0x02,0x70,0x84,0x01,0x40,0x7B,0x02,0x04,0xC9,0xFC,0x4C, -0x20,0x48,0x20,0x47,0x20,0x46,0x20,0x45,0x20,0x44,0x20,0x49,0x08,0x70,0x70,0x70, -0x10,0x48,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x2B,0x7F,0xF0,0x14,0x00,0x02,0x77, -0x0B,0x84,0x01,0x40,0x24,0x7F,0x22,0x73,0x00,0x00,0xEB,0x6F,0x54,0x73,0x40,0x3C, -0x4F,0x0D,0x60,0x5E,0xCA,0x80,0x84,0x0A,0x00,0x02,0x7F,0x0A,0x80,0x40,0x24,0x7F, -0x22,0x73,0x00,0x00,0x87,0xDA,0x04,0xE0,0x40,0xD0,0x08,0x40,0x40,0xDC,0x01,0x74, -0x41,0x87,0x51,0xE2,0x41,0x9E,0x41,0x40,0x86,0x40,0x48,0x87,0x73,0xE0,0x40,0xD0, -0x08,0x40,0x40,0x9C,0x4F,0xE8,0x12,0x00,0x02,0x40,0x86,0x48,0xE4,0x41,0xAC,0x08, -0x41,0x9C,0x41,0x40,0x87,0x50,0xE0,0x40,0x86,0x48,0xE4,0x41,0xA4,0x08,0x41,0xD0, -0x41,0x01,0x41,0x38,0x40,0x41,0x77,0x0B,0x84,0x01,0x40,0x24,0x7F,0x22,0x73,0x00, -0x00,0x3F,0x73,0x7F,0x71,0x08,0x00,0x02,0x7F,0x46,0x87,0x73,0xE0,0x40,0xA0,0x40, -0xEB,0x6F,0x54,0x73,0x40,0xA0,0x80,0xBC,0x0A,0x00,0x02,0xA0,0x4F,0x74,0x08,0x00, -0x02,0xA0,0x00,0x2C,0xCC,0xF0,0x7F,0x98,0x76,0x00,0x00,0x28,0x40,0x77,0x0A,0x80, -0x40,0x24,0x7F,0x22,0x73,0x00,0x00,0x87,0x73,0xE0,0x40,0xD0,0x01,0x40,0x40,0x82, -0x80,0xEC,0x14,0x00,0x02,0x70,0x87,0x73,0x7F,0x71,0x08,0x00,0x02,0x70,0x3C,0xDA, -0x04,0x7F,0x74,0x08,0x00,0x02,0x57,0x08,0x24,0x7F,0x70,0x72,0x00,0x00,0x7B,0x6F, -0x87,0x73,0xE0,0x40,0xD0,0x01,0x40,0x40,0x86,0xE2,0x80,0xEC,0x14,0x00,0x02,0xE0, -0x40,0x77,0x0B,0x84,0x01,0x40,0x24,0x7F,0x22,0x73,0x00,0x00,0x87,0x73,0xE0,0x40, -0xD0,0x01,0x40,0x40,0x96,0x80,0xEC,0x14,0x00,0x02,0x70,0x87,0x73,0xE0,0x40,0xA0, -0x40,0xEB,0x6F,0x54,0x73,0x40,0x87,0x73,0xE0,0x41,0xD0,0x01,0x41,0x41,0x86,0xE2, -0x81,0xEC,0x14,0x00,0x02,0xE0,0x41,0xDC,0x41,0x80,0xBC,0x0A,0x00,0x02,0x40,0xA0, -0x40,0xA0,0x4F,0x74,0x08,0x00,0x02,0xA0,0x00,0x2C,0xCC,0xF0,0x7F,0x98,0x76,0x00, -0x00,0x28,0x40,0x77,0x0A,0x80,0x40,0x24,0x7F,0x22,0x73,0x00,0x00,0x3C,0xDA,0x04, -0x7F,0x74,0x08,0x00,0x02,0x57,0x8B,0xA0,0x74,0xA0,0x4F,0x74,0x08,0x00,0x02,0x2C, -0xCC,0xF8,0x7F,0xD6,0x7D,0x00,0x00,0x84,0x01,0x40,0x24,0x7F,0x22,0x73,0x00,0x00, -0xA0,0x74,0xA0,0x4F,0x74,0x08,0x00,0x02,0x2C,0xCC,0xF8,0x7F,0xD6,0x7D,0x00,0x00, -0x28,0x40,0x7F,0x0B,0x84,0x01,0x40,0x24,0x7F,0x22,0x73,0x00,0x00,0x7B,0x68,0x87, -0x73,0xE0,0x40,0xA0,0x40,0xEB,0x6F,0x54,0x73,0x40,0x87,0x73,0xE0,0x41,0xD0,0x01, -0x41,0x41,0x86,0xE2,0x81,0xEC,0x14,0x00,0x02,0xE0,0x41,0xDC,0x41,0x80,0xBC,0x0A, -0x00,0x02,0x40,0xA0,0x40,0xA0,0x4F,0x74,0x08,0x00,0x02,0xA0,0x00,0x2C,0xCC,0xF0, -0x7F,0x98,0x76,0x00,0x00,0x28,0x40,0x77,0x06,0x80,0x40,0x7B,0x57,0xA0,0x74,0xA0, -0x4F,0x74,0x08,0x00,0x02,0x2C,0xCC,0xF8,0x7F,0xD6,0x7D,0x00,0x00,0x28,0x40,0x7F, -0x07,0x84,0x01,0x40,0x7B,0x3E,0x87,0x73,0xE0,0x40,0xD0,0x01,0x40,0x40,0x92,0x80, -0xEC,0x14,0x00,0x02,0x70,0x87,0x73,0xE0,0x40,0xD0,0x01,0x40,0x40,0x86,0xE2,0x80, -0xEC,0x14,0x00,0x02,0xE0,0x40,0x87,0x73,0xE0,0x41,0xD0,0x01,0x41,0x41,0x86,0xE2, -0x81,0xE8,0x14,0x00,0x02,0xE0,0x41,0x3C,0x41,0x40,0x5A,0x75,0xFF,0x84,0x01,0x40, -0x7B,0x02,0x04,0xC9,0xEC,0x4C,0x20,0x48,0x20,0x49,0x08,0x70,0x10,0x49,0x9C,0x4F, -0x00,0x00,0x00,0x00,0x4C,0x87,0x01,0x7F,0x01,0xA0,0x04,0x00,0x70,0xA0,0x01,0x2C, -0xCC,0xFC,0xEF,0x28,0x05,0x00,0x00,0xA0,0x20,0xA0,0x4F,0x74,0x0A,0x00,0x02,0xA0, -0x08,0x2C,0xCC,0xF4,0xAF,0x83,0x00,0x28,0x40,0x7F,0x1B,0x87,0x73,0xE0,0x40,0xA0, -0x40,0x2C,0xCC,0xFC,0xAF,0x1F,0x00,0x28,0x40,0x7F,0x07,0x84,0x01,0x40,0x7B,0x0A, -0x80,0x40,0x7B,0x06,0x80,0x40,0x7B,0x02,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70, -0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x87,0x73,0xE0,0x40,0xA0,0x40,0x2C, -0xCC,0xFC,0xAF,0xA1,0x02,0x28,0x40,0x77,0x06,0x80,0x40,0x7B,0x31,0xF3,0x6F,0x58, -0x73,0x40,0xA0,0x40,0xA0,0x00,0xA0,0x00,0x2C,0xCC,0xF4,0xAF,0x2C,0x00,0xF3,0x6F, -0x58,0x73,0x40,0xA0,0x40,0xA0,0x00,0xA0,0x00,0x2C,0xCC,0xF4,0xAF,0x1B,0x00,0x28, -0x40,0x7F,0x07,0x84,0x01,0x40,0x7B,0x06,0x80,0x40,0x7B,0x02,0x04,0xC9,0xE8,0x4C, -0x20,0x49,0x08,0x70,0x10,0x49,0x9C,0x4F,0x08,0x00,0x00,0x00,0x4C,0x70,0x84,0x4B, -0x7F,0xFC,0x14,0x00,0x02,0x70,0x70,0xB0,0x4F,0x00,0xE1,0x01,0x00,0x4B,0x87,0x7F, -0x01,0xA0,0x04,0x00,0xE0,0x40,0x84,0x40,0x7F,0xD4,0x12,0x00,0x02,0x70,0x38,0x40, -0x5F,0x80,0x00,0x7F,0x2A,0x87,0x73,0xE0,0x40,0xD0,0x18,0x40,0x40,0xB0,0x40,0x7F, -0xD4,0x12,0x00,0x02,0x70,0x87,0x08,0x7F,0x01,0xA0,0x04,0x00,0x70,0x84,0x7F,0xFC, -0x14,0x00,0x02,0x4B,0x84,0x00,0x40,0x24,0x7F,0x26,0x76,0x00,0x00,0x87,0x02,0x7F, -0x01,0xA0,0x04,0x00,0x70,0x87,0x08,0x7F,0x01,0xA0,0x04,0x00,0x70,0x7B,0x13,0x84, -0x74,0x40,0x90,0x74,0x70,0x87,0x50,0x7F,0x00,0xA0,0x04,0x00,0x70,0x97,0x7B,0x70, -0x2B,0x7B,0x77,0xED,0x87,0x73,0x7F,0x01,0xA0,0x04,0x00,0x70,0x82,0x59,0x70,0x7B, -0x0F,0xA0,0x01,0x2C,0xCC,0xFC,0xEF,0x28,0x05,0x00,0x00,0x92,0x59,0x70,0x86,0xE2, -0x59,0xE0,0x40,0x3C,0x5F,0xC8,0x00,0x40,0x53,0x0D,0x3B,0x7F,0x01,0xA0,0x04,0x00, -0x5F,0x80,0x00,0x77,0xDE,0x87,0x7F,0x01,0xA0,0x04,0x00,0xE0,0x40,0x84,0x40,0x7F, -0xD4,0x12,0x00,0x02,0x70,0x38,0x40,0x5F,0x80,0x00,0x7F,0x2A,0x87,0x73,0xE0,0x40, -0xD0,0x18,0x40,0x40,0xB0,0x40,0x7F,0xD4,0x12,0x00,0x02,0x70,0x87,0x08,0x7F,0x01, -0xA0,0x04,0x00,0x70,0x84,0x7F,0xFC,0x14,0x00,0x02,0x4B,0x84,0x00,0x40,0x24,0x7F, -0x26,0x76,0x00,0x00,0x3B,0x73,0x5F,0xF0,0x00,0x7F,0x2A,0x82,0x59,0x70,0x7B,0x0F, -0xA0,0x01,0x2C,0xCC,0xFC,0xEF,0x28,0x05,0x00,0x00,0x92,0x59,0x70,0x86,0xE2,0x59, -0xE0,0x40,0x3C,0x05,0x40,0x53,0x0C,0x3B,0x7F,0x01,0xA0,0x04,0x00,0x6F,0x60,0x7F, -0xE1,0x7B,0x21,0x80,0x7F,0xD4,0x12,0x00,0x02,0x70,0x87,0x08,0x7F,0x01,0xA0,0x04, -0x00,0x70,0x84,0x7F,0xFC,0x14,0x00,0x02,0x4B,0x84,0x01,0x40,0x24,0x7F,0x26,0x76, -0x00,0x00,0x87,0x7F,0x01,0xA0,0x04,0x00,0xE0,0x40,0x84,0x40,0x7F,0xD4,0x12,0x00, -0x02,0x70,0xB8,0x6F,0x60,0x40,0x3C,0x6F,0x40,0x40,0x77,0x08,0x24,0x7F,0xB7,0x75, -0x00,0x00,0x87,0x73,0xE0,0x40,0xD0,0x18,0x40,0x40,0x87,0x7F,0x00,0xA0,0x04,0x00, -0xE0,0x41,0xD0,0x08,0x41,0x41,0xB0,0x41,0x40,0xB0,0x40,0x7F,0xD4,0x12,0x00,0x02, -0x70,0x38,0x7F,0xD4,0x12,0x00,0x02,0x5F,0x00,0x20,0x7F,0x11,0x3B,0x73,0x5F,0xB0, -0x00,0x7F,0x0A,0x87,0x01,0x7F,0x00,0x15,0x00,0x02,0x70,0x38,0x7F,0xD4,0x12,0x00, -0x02,0x08,0x7F,0x31,0x84,0x7F,0xD4,0x12,0x00,0x02,0x64,0x70,0xFB,0x01,0x73,0x40, -0xA0,0x40,0x2C,0xCC,0xFC,0xAF,0xAA,0xFD,0x28,0x40,0x7F,0x11,0xFB,0x01,0x73,0x40, -0xB4,0x01,0x40,0xA0,0x40,0x2C,0xCC,0xFC,0xAF,0xEB,0xFD,0x84,0x64,0x7F,0xD4,0x12, -0x00,0x02,0x70,0x87,0x08,0x7F,0x01,0xA0,0x04,0x00,0x70,0x84,0x7F,0xFC,0x14,0x00, -0x02,0x4B,0x84,0x00,0x40,0x7B,0x71,0x38,0x7F,0xD4,0x12,0x00,0x02,0x08,0x7F,0x4D, -0x87,0x73,0xE0,0x40,0xD0,0x18,0x40,0x40,0xB0,0x40,0x7F,0xD4,0x12,0x00,0x02,0x70, -0x84,0x7F,0xD4,0x12,0x00,0x02,0x64,0x70,0xFB,0x01,0x73,0x40,0xA0,0x40,0x2C,0xCC, -0xFC,0xAF,0x4E,0xFD,0x28,0x40,0x7F,0x11,0xFB,0x01,0x73,0x40,0xB4,0x01,0x40,0xA0, -0x40,0x2C,0xCC,0xFC,0xAF,0x8F,0xFD,0x84,0x64,0x7F,0xD4,0x12,0x00,0x02,0x70,0x84, -0x7F,0xFC,0x14,0x00,0x02,0x4B,0x84,0x00,0x40,0x7B,0x1D,0x87,0x08,0x7F,0x01,0xA0, -0x04,0x00,0x70,0x80,0x7F,0xD4,0x12,0x00,0x02,0x70,0x84,0x7F,0xFC,0x14,0x00,0x02, -0x4B,0x84,0x01,0x40,0x7B,0x02,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x70, -0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0xF3,0x30,0x73,0x40,0xA0,0x40,0xA0, -0x00,0xA0,0x00,0x2C,0xCC,0xF4,0xAF,0x91,0xFD,0x28,0x40,0x77,0x06,0x80,0x40,0x7B, -0x40,0x87,0x7F,0x00,0xA0,0x04,0x00,0xE0,0x40,0x84,0x40,0x7F,0xD4,0x12,0x00,0x02, -0x70,0x38,0x40,0x02,0x7F,0x0E,0x80,0x7F,0xD4,0x12,0x00,0x02,0x70,0x84,0x01,0x40, -0x7B,0x1F,0xD0,0x10,0x7F,0xD4,0x12,0x00,0x02,0x7F,0xD4,0x12,0x00,0x02,0x70,0xB0, -0x4F,0x00,0x00,0x00,0x30,0x7F,0xD4,0x12,0x00,0x02,0x70,0x80,0x40,0x7B,0x02,0x04, -0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x10,0x49,0x9C,0x4F,0x14,0x00,0x00,0x00, -0x4C,0xEB,0x6F,0x54,0x73,0x40,0xEB,0x6F,0x54,0x73,0x41,0xE8,0x81,0xA0,0x0A,0x00, -0x02,0x80,0x9C,0x0A,0x00,0x02,0x40,0xEC,0xE0,0x40,0x74,0x40,0x84,0x40,0x64,0x70, -0xEB,0x6F,0x54,0x73,0x41,0x3C,0x81,0x98,0x0A,0x00,0x02,0x40,0x5B,0x0A,0x80,0x40, -0x24,0x7F,0x79,0x78,0x00,0x00,0xD4,0x08,0x64,0x40,0xBB,0x5F,0xFF,0x00,0x40,0x87, -0x40,0x6C,0x70,0xFB,0x5F,0xFF,0x00,0x67,0x40,0x87,0x40,0x6D,0x70,0xEB,0x6F,0x54, -0x73,0x40,0xEB,0x6F,0x54,0x73,0x41,0xE8,0x81,0xA0,0x0A,0x00,0x02,0x80,0x9C,0x0A, -0x00,0x02,0x40,0xE4,0xE0,0x40,0x74,0x40,0x84,0x40,0x59,0x70,0xEB,0x6F,0x54,0x73, -0x40,0xEC,0xE0,0x80,0xA0,0x0A,0x00,0x02,0x59,0x40,0x87,0x40,0x6E,0x70,0xEB,0x6F, -0x54,0x73,0x40,0xE4,0xE0,0x80,0xA0,0x0A,0x00,0x02,0x59,0x40,0x87,0x40,0xC9,0x0F, -0x70,0x87,0x73,0xE0,0x40,0xA0,0x40,0xE0,0x6C,0x2C,0xCC,0xF8,0x7F,0x00,0x71,0x00, -0x00,0x28,0x40,0x77,0x0A,0x80,0x40,0x24,0x7F,0x79,0x78,0x00,0x00,0x3F,0x07,0x6E, -0x5F,0x0D,0xDF,0x02,0x73,0x40,0x87,0x40,0xC9,0x11,0x70,0x7B,0x07,0x87,0x73,0xC9, -0x11,0x70,0x82,0x68,0x70,0x24,0x7F,0x43,0x78,0x00,0x00,0x86,0xE2,0x68,0xE0,0x40, -0x7F,0x10,0x87,0x73,0xE0,0x40,0xA0,0x40,0x2C,0xCC,0xFC,0x7F,0x80,0x73,0x00,0x00, -0x87,0x73,0xE0,0x40,0xA0,0x40,0xE0,0x6C,0x2C,0xCC,0xF8,0xAF,0xF8,0x00,0x28,0x40, -0x77,0x08,0x24,0x7F,0x40,0x78,0x00,0x00,0x87,0x6E,0x7F,0xF4,0x14,0x00,0x02,0x70, -0x8B,0x6C,0x40,0x87,0x40,0x7F,0xF5,0x14,0x00,0x02,0x70,0x87,0x6D,0x7F,0xF6,0x14, -0x00,0x02,0x70,0x87,0x6E,0x7F,0xF7,0x14,0x00,0x02,0x70,0x87,0xC9,0x0F,0x7F,0xF8, -0x14,0x00,0x02,0x70,0x87,0x01,0x7F,0xF9,0x14,0x00,0x02,0x70,0x2B,0xCA,0x0F,0x77, -0x07,0x84,0x04,0x40,0x7B,0x05,0x84,0x08,0x40,0xB3,0x00,0x40,0x87,0x40,0xC9,0x10, -0x70,0xA0,0x78,0x87,0xC9,0x10,0xE0,0x40,0xA0,0x40,0xEB,0x6F,0x54,0x73,0x40,0xA0, -0x80,0xA4,0x0A,0x00,0x02,0x2C,0xCC,0xF4,0x7F,0xEC,0x6C,0x00,0x00,0x28,0x40,0x77, -0x06,0x80,0x40,0x7B,0x76,0x83,0x7F,0x00,0x15,0x00,0x02,0x70,0x2B,0xCA,0x0F,0x77, -0x09,0x84,0x5F,0xB0,0x00,0x40,0x7B,0x07,0x84,0x5F,0xF0,0x00,0x40,0x87,0xC9,0x11, -0xE0,0x41,0xB0,0x41,0x40,0xA0,0x40,0xA0,0x4F,0xF4,0x14,0x00,0x02,0xA0,0x06,0x2C, -0xCC,0xF4,0x7F,0xD4,0x73,0x00,0x00,0x28,0x40,0x7F,0x07,0x84,0x01,0x40,0x7B,0x3B, -0x92,0x68,0x70,0x86,0xE2,0x68,0xE0,0x40,0x3C,0x10,0x40,0x5A,0x20,0xFF,0x2B,0x7F, -0x00,0x15,0x00,0x02,0x7F,0x21,0xA0,0x4F,0xF4,0x10,0x00,0x00,0x87,0x73,0xE0,0x40, -0xA0,0x40,0xA0,0x6C,0xA0,0x10,0x2C,0xCC,0xF0,0xEF,0xB0,0x04,0x00,0x00,0x83,0x7F, -0x00,0x15,0x00,0x02,0x70,0x80,0x40,0x7B,0x02,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08, -0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x87,0x73,0xE0,0x40,0xA0,0x40,0x2C, -0xCC,0xFC,0x7F,0x30,0x76,0x00,0x00,0x28,0x40,0x77,0x06,0x80,0x40,0x7B,0x30,0x87, -0xDA,0x04,0x7F,0xF4,0x14,0x00,0x02,0x70,0xDC,0x01,0x74,0x40,0x87,0x50,0x7F,0xF5, -0x14,0x00,0x02,0x70,0xF3,0x6F,0x68,0x73,0x40,0xA0,0x40,0xA0,0x4F,0xF4,0x14,0x00, -0x02,0xA0,0x02,0x2C,0xCC,0xF4,0x7F,0xD4,0x73,0x00,0x00,0x7B,0x02,0x04,0xC9,0xE8, -0x4C,0x20,0x49,0x08,0x10,0x49,0x9C,0x4F,0x0C,0x00,0x00,0x00,0x4C,0x84,0x4F,0x74, -0x08,0x00,0x02,0x68,0x70,0x87,0x5F,0xFF,0x00,0x7F,0x71,0x08,0x00,0x02,0x70,0x87, -0x73,0xE0,0x40,0xA0,0x40,0xEB,0x6F,0x54,0x73,0x40,0xFC,0x01,0x80,0x98,0x0A,0x00, -0x02,0x40,0xEB,0x6F,0x54,0x73,0x41,0xA8,0x81,0x9C,0x0A,0x00,0x02,0x40,0xEB,0x6F, -0x54,0x73,0x41,0xA8,0x81,0xA0,0x0A,0x00,0x02,0x40,0xA0,0x40,0xA0,0x68,0xA0,0x00, -0x2C,0xCC,0xF0,0x7F,0x98,0x76,0x00,0x00,0x28,0x40,0x77,0x06,0x80,0x40,0x7B,0x54, -0x80,0x59,0x70,0x7B,0x38,0x80,0x64,0x70,0x7B,0x29,0xE4,0x02,0x59,0x40,0x7F,0x0A, -0xFC,0x64,0x5F,0xFF,0x00,0x40,0x7B,0x05,0x84,0x64,0x40,0x84,0x68,0x41,0x90,0x68, -0x70,0x87,0x51,0xE0,0x41,0x3C,0x40,0x41,0x7F,0x06,0x80,0x40,0x7B,0x26,0x90,0x64, -0x70,0x3C,0x5F,0x00,0x01,0x64,0x4B,0xD4,0x90,0x59,0x70,0xEB,0x6F,0x54,0x73,0x40, -0xD4,0x08,0x80,0xA4,0x0A,0x00,0x02,0x40,0x3C,0x40,0x59,0x5B,0xBA,0x84,0x01,0x40, -0x7B,0x02,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x70,0x10,0x49,0x9C,0x4F, -0x04,0x00,0x00,0x00,0x4C,0x87,0x10,0x7F,0x0E,0x90,0x04,0x00,0x70,0x87,0x20,0x7F, -0x0E,0x90,0x04,0x00,0x70,0x86,0xE2,0x7F,0x02,0x40,0x04,0x00,0xE0,0x40,0xB8,0x5F, -0x00,0x04,0x40,0x3C,0x5F,0x00,0x04,0x40,0x7F,0x16,0x87,0x01,0x7F,0x1B,0x40,0x04, -0x00,0x70,0xA0,0x5F,0x2C,0x01,0x2C,0xCC,0xFC,0xEF,0x28,0x05,0x00,0x00,0xA0,0x5F, -0xC8,0x00,0x2C,0xCC,0xFC,0xEF,0x28,0x05,0x00,0x00,0x87,0x5F,0xD0,0x00,0x7F,0x00, -0xD0,0x04,0x00,0x70,0xA0,0x01,0x2C,0xCC,0xFC,0xEF,0x28,0x05,0x00,0x00,0x3B,0x7F, -0x00,0xD0,0x04,0x00,0x5F,0x80,0x00,0x7F,0x0B,0x2C,0x5C,0xAF,0x3B,0x00,0x80,0x40, -0x7B,0x2D,0x3F,0x01,0x73,0x77,0x07,0x84,0x04,0x40,0x7B,0x04,0x80,0x40,0xB0,0x08, -0x40,0xA0,0x40,0xA0,0x10,0x2C,0xCC,0xF8,0xAF,0x47,0x00,0x28,0x40,0x7F,0x07,0x84, -0x01,0x40,0x7B,0x0B,0x2C,0x5C,0xAF,0x10,0x00,0x80,0x40,0x7B,0x02,0x04,0xC9,0xE8, -0x4C,0x20,0x49,0x08,0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x87,0x01,0x7F, -0x1F,0x40,0x04,0x00,0x70,0x87,0x10,0x7F,0x0F,0x90,0x04,0x00,0x70,0x87,0x20,0x7F, -0x0F,0x90,0x04,0x00,0x70,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x10,0x49,0x9C,0x4F, -0x04,0x00,0x00,0x00,0x4C,0x3B,0x7F,0x00,0xD0,0x04,0x00,0x01,0x7F,0x0A,0x80,0x40, -0x24,0x7F,0x24,0x7B,0x00,0x00,0x70,0x84,0x4B,0x7F,0xFC,0x14,0x00,0x02,0x70,0x70, -0xB0,0x4F,0x00,0xE1,0x01,0x00,0x4B,0x87,0x73,0x7F,0x00,0xD0,0x04,0x00,0x70,0xA0, -0x01,0xA0,0x5F,0xE6,0x00,0x2C,0xCC,0xF8,0x7F,0x2C,0x55,0x00,0x00,0x80,0x59,0x70, -0x7B,0x21,0x3C,0x6F,0x64,0x59,0x4F,0x0E,0x84,0x7F,0xFC,0x14,0x00,0x02,0x4B,0x84, -0x00,0x40,0x7B,0x72,0xA0,0x01,0x2C,0xCC,0xFC,0xEF,0x28,0x05,0x00,0x00,0x90,0x59, -0x70,0x3B,0x7F,0x00,0xD0,0x04,0x00,0x01,0x77,0xDA,0xFB,0x5F,0xA0,0x00,0x73,0x40, -0x3C,0x5F,0xA0,0x00,0x40,0x7F,0x0F,0xFB,0x5F,0xF0,0x00,0x73,0x40,0x3C,0x5F,0xF0, -0x00,0x40,0x77,0x10,0xA0,0x01,0xA0,0x5F,0xE6,0x00,0x2C,0xCC,0xF8,0x7F,0x2C,0x55, -0x00,0x00,0x3B,0x7F,0x00,0xD0,0x04,0x00,0x77,0x7F,0x1F,0x3B,0x7F,0x00,0xD0,0x04, -0x00,0x08,0x7F,0x0A,0x87,0x01,0x7F,0x00,0x15,0x00,0x02,0x70,0x84,0x7F,0xFC,0x14, -0x00,0x02,0x4B,0x84,0x00,0x40,0x7B,0x0E,0x84,0x7F,0xFC,0x14,0x00,0x02,0x4B,0x84, -0x01,0x40,0x7B,0x02,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x10,0x49,0x9C,0x4F, -0x0C,0x00,0x00,0x00,0x4C,0xEC,0xE0,0x12,0x5A,0x40,0x3C,0x6F,0x50,0x40,0x5B,0x0A, -0x80,0x40,0x24,0x7F,0x94,0x7D,0x00,0x00,0x2B,0xCA,0x0F,0x7F,0x08,0x3F,0x03,0xCA, -0x0F,0x77,0x79,0xA0,0x01,0x2C,0xCC,0xFC,0x7F,0x8C,0x79,0x00,0x00,0x28,0x40,0x77, -0x0A,0x80,0x40,0x24,0x7F,0x94,0x7D,0x00,0x00,0x87,0x5F,0xFF,0x00,0x7F,0x71,0x08, -0x00,0x02,0x70,0x83,0x7F,0x70,0x08,0x00,0x02,0x70,0xA0,0x5F,0x8E,0x05,0xA0,0x4F, -0x74,0x08,0x00,0x02,0xA0,0x00,0xA0,0x01,0x2C,0xCC,0xF0,0xCF,0xA4,0x28,0x40,0x77, -0x0A,0x80,0x40,0x24,0x7F,0x94,0x7D,0x00,0x00,0x3C,0x4F,0x0D,0x60,0x5E,0xCA,0x7F, -0x78,0x08,0x00,0x02,0x77,0x18,0x86,0x7F,0xB2,0x08,0x00,0x02,0x7F,0x02,0x15,0x00, -0x02,0x70,0x87,0x01,0x7F,0x70,0x08,0x00,0x02,0x70,0x7B,0x10,0x82,0x7F,0x02,0x15, -0x00,0x02,0x70,0x83,0x7F,0x70,0x08,0x00,0x02,0x70,0x83,0x68,0x70,0xEC,0xE0,0x12, -0x5A,0x40,0x87,0x40,0x69,0x70,0xE4,0xE0,0x12,0x5A,0x40,0xAC,0xE0,0x09,0x40,0x87, -0x40,0x6A,0x70,0xE4,0xE0,0x09,0x5A,0x40,0x87,0x40,0x6B,0x70,0x2B,0x7F,0x70,0x08, -0x00,0x02,0x7F,0x60,0x3F,0x02,0x7F,0x71,0x08,0x00,0x02,0x7F,0x49,0x87,0x5F,0xFF, -0x00,0x7F,0x71,0x08,0x00,0x02,0x70,0x83,0x7F,0x70,0x08,0x00,0x02,0x70,0x86,0x7F, -0x02,0x15,0x00,0x02,0xE4,0x40,0xA0,0x40,0xA0,0x4F,0x74,0x08,0x00,0x02,0xA0,0x00, -0xA0,0x01,0x2C,0xCC,0xF0,0xAF,0x0A,0xFF,0x28,0x40,0x77,0x0A,0x80,0x40,0x24,0x7F, -0x94,0x7D,0x00,0x00,0x87,0x02,0x7F,0x71,0x08,0x00,0x02,0x70,0x87,0x01,0x7F,0x70, -0x08,0x00,0x02,0x70,0xE0,0x68,0xA0,0x4F,0x74,0x08,0x00,0x02,0x2C,0xCC,0xF8,0xAF, -0x8A,0x01,0x87,0x5F,0x9C,0x00,0x66,0x70,0x3F,0x01,0x7B,0x77,0x14,0x87,0x6F,0x49, -0x64,0x70,0x87,0x5F,0xA0,0x00,0x65,0x70,0xB3,0x6F,0x40,0x66,0x70,0x7B,0x0D,0x87, -0x6F,0x45,0x64,0x70,0x87,0x5F,0x80,0x00,0x65,0x70,0x87,0x6A,0xE0,0x40,0xD0,0x01, -0x40,0x40,0xB3,0x08,0x40,0xB3,0x40,0x65,0x70,0x82,0x62,0x70,0x82,0x59,0x70,0x24, -0x7F,0x30,0x7D,0x00,0x00,0x87,0x69,0xE0,0x40,0xA0,0x40,0x2C,0xCC,0xFC,0xAF,0x01, -0x01,0x28,0x40,0x77,0x1A,0xA0,0x01,0x2C,0xCC,0xFC,0x7F,0x8C,0x79,0x00,0x00,0x28, -0x40,0x77,0x0A,0x80,0x40,0x24,0x7F,0x94,0x7D,0x00,0x00,0x7B,0x72,0xDF,0x01,0x6B, -0x40,0x87,0x40,0x7F,0x02,0xD0,0x04,0x00,0x70,0xA0,0x74,0x87,0x64,0xE0,0x40,0xA0, -0x40,0xA0,0x5F,0x00,0x02,0x2C,0xCC,0xF4,0x7F,0xEC,0x6C,0x00,0x00,0x28,0x40,0x77, -0x0A,0x80,0x40,0x24,0x7F,0x94,0x7D,0x00,0x00,0x83,0x7F,0x00,0x15,0x00,0x02,0x70, -0x87,0x65,0xE0,0x40,0xA0,0x40,0x87,0x66,0xE0,0x40,0xA0,0x40,0x2C,0xCC,0xF8,0x7F, -0x5C,0x7A,0x00,0x00,0x28,0x40,0x7F,0x08,0x86,0x01,0x62,0x70,0x7B,0x2A,0x3B,0x7F, -0x00,0xD0,0x04,0x00,0x5F,0x80,0x00,0x7F,0x04,0x7B,0x1D,0xA0,0x01,0x2C,0xCC,0xFC, -0x7F,0x8C,0x79,0x00,0x00,0x28,0x40,0x77,0x06,0x80,0x40,0x7B,0x69,0x92,0x59,0x70, -0x3E,0x10,0x59,0x4A,0x62,0xFF,0x2B,0x7F,0x00,0x15,0x00,0x02,0x7F,0x1B,0xA0,0x4F, -0x28,0x11,0x00,0x00,0xA0,0x68,0xA0,0x10,0x2C,0xCC,0xF4,0xEF,0xB0,0x04,0x00,0x00, -0x83,0x7F,0x00,0x15,0x00,0x02,0x70,0x2A,0x62,0x7F,0x0E,0x3F,0x02,0xCA,0x0F,0x7F, -0x08,0x3F,0x03,0xCA,0x0F,0x77,0x29,0x2B,0x7F,0x70,0x08,0x00,0x02,0x7F,0x1A,0x83, -0x7F,0x70,0x08,0x00,0x02,0x70,0x82,0x7F,0x02,0x15,0x00,0x02,0x70,0x87,0x5F,0xFF, -0x00,0x7F,0x71,0x08,0x00,0x02,0x70,0x2C,0x5C,0x7F,0x34,0x7A,0x00,0x00,0x86,0x62, -0xE4,0x40,0x7B,0x02,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x10,0x49,0x9C,0x4F, -0x00,0x00,0x00,0x00,0x4C,0x3F,0x73,0x7F,0x01,0xD0,0x04,0x00,0x77,0x07,0x84,0x01, -0x40,0x7B,0x1D,0x87,0x73,0x7F,0x03,0xD0,0x04,0x00,0x70,0xA0,0x1C,0xA0,0x10,0x2C, -0xCC,0xF8,0x7F,0x5C,0x7A,0x00,0x00,0x86,0xE2,0x40,0xE0,0x40,0x7B,0x02,0x04,0xC9, -0xE8,0x4C,0x20,0x49,0x08,0x70,0x10,0x49,0x9C,0x4F,0x04,0x00,0x00,0x00,0x4C,0x82, -0x59,0x70,0x7B,0x42,0x86,0x59,0xE4,0x40,0xD0,0x03,0x40,0x40,0x9C,0x74,0x40,0x3C, -0xDA,0x00,0x50,0x77,0x18,0x86,0x59,0xE4,0x40,0xD0,0x03,0x40,0x40,0x9C,0x74,0x40, -0x84,0xC0,0x04,0xDA,0x00,0x70,0x84,0x01,0x40,0x7B,0x25,0x86,0x59,0xE4,0x40,0xD0, -0x03,0x40,0x40,0x9C,0x74,0x40,0x3C,0xDA,0x00,0x50,0x5F,0x07,0x84,0x01,0x40,0x7B, -0x0F,0x92,0x59,0x70,0x3E,0x6F,0x40,0x59,0x4B,0xBC,0x80,0x40,0x7B,0x02,0x04,0xC9, -0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x70,0x10,0x47,0x84,0x5A,0x41,0x84,0x00,0x47, -0x87,0x51,0xE0,0x48,0x3B,0x88,0x71,0x11,0x00,0x00,0x04,0x77,0x46,0x7B,0x13,0x04, -0xC9,0xF0,0x4C,0x20,0x48,0x20,0x47,0x20,0x49,0x08,0x90,0x41,0x87,0x51,0xE0,0x48, -0x3B,0x88,0x71,0x11,0x00,0x00,0x08,0x77,0xF3,0x3C,0x48,0x2B,0x7F,0x09,0x3C,0x48, -0x2D,0x77,0x0A,0x90,0x47,0x90,0x41,0x87,0x51,0xE0,0x48,0x3B,0x88,0x71,0x11,0x00, -0x00,0x04,0x77,0x0F,0x80,0x40,0x04,0xC9,0xF0,0x4C,0x20,0x48,0x20,0x47,0x20,0x49, -0x08,0xFC,0x48,0x30,0x42,0x7B,0x0C,0xA8,0x0A,0x42,0xFC,0x48,0x30,0x40,0x9C,0x40, -0x42,0x90,0x41,0x87,0x51,0xE0,0x48,0x3B,0x88,0x71,0x11,0x00,0x00,0x04,0x77,0xE9, -0x28,0x47,0x7F,0x10,0x84,0x42,0x40,0x04,0xC9,0xF0,0x4C,0x20,0x48,0x20,0x47,0x20, -0x49,0x08,0x8C,0x42,0x40,0x04,0xC9,0xF0,0x4C,0x20,0x48,0x20,0x47,0x20,0x49,0x08, -0x10,0x47,0x84,0x5A,0x41,0x84,0x00,0x47,0x87,0x51,0xE0,0x48,0x3B,0x88,0x71,0x11, -0x00,0x00,0x04,0x77,0x46,0x7B,0x13,0x04,0xC9,0xF0,0x4C,0x20,0x48,0x20,0x47,0x20, -0x49,0x08,0x90,0x41,0x87,0x51,0xE0,0x48,0x3B,0x88,0x71,0x11,0x00,0x00,0x08,0x77, -0xF3,0x3C,0x48,0x2B,0x7F,0x09,0x3C,0x48,0x2D,0x77,0x0A,0x90,0x47,0x90,0x41,0x87, -0x51,0xE0,0x48,0x3B,0x88,0x71,0x11,0x00,0x00,0x04,0x77,0x0F,0x80,0x40,0x04,0xC9, -0xF0,0x4C,0x20,0x48,0x20,0x47,0x20,0x49,0x08,0xFC,0x48,0x30,0x42,0x7B,0x0C,0xA8, -0x0A,0x42,0xFC,0x48,0x30,0x40,0x9C,0x40,0x42,0x90,0x41,0x87,0x51,0xE0,0x48,0x3B, -0x88,0x71,0x11,0x00,0x00,0x04,0x77,0xE9,0x28,0x47,0x7F,0x10,0x84,0x42,0x40,0x04, -0xC9,0xF0,0x4C,0x20,0x48,0x20,0x47,0x20,0x49,0x08,0x8C,0x42,0x40,0x04,0xC9,0xF0, -0x4C,0x20,0x48,0x20,0x47,0x20,0x49,0x08,0x10,0x49,0x84,0x5A,0x40,0x84,0x74,0x41, -0x3C,0x41,0x40,0x77,0x08,0x7B,0x10,0x90,0x40,0x90,0x41,0x3F,0x51,0x50,0x77,0x07, -0x3F,0x50,0x00,0x77,0xF4,0xFF,0x51,0x50,0x40,0x87,0xE7,0x40,0xE4,0x40,0x04,0xC9, -0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x70,0x10,0x49,0x84,0x5A,0x40,0x7B,0x04,0x90, -0x40,0x2B,0x50,0x77,0xFC,0xBC,0x5A,0x40,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70, -0x10,0x49,0x84,0x5A,0x41,0x84,0x74,0x40,0x30,0x35,0x84,0x5A,0x40,0x04,0xC9,0xE8, -0x4C,0x20,0x49,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x25,0x72, -0x22,0x22,0x22,0x22,0x03,0x02,0x01,0x30,0x03,0x02,0x01,0x0E,0x03,0x02,0x01,0x0B,}; -#endif /* ROM_rom_rev2_bin_H */ diff --git a/3B2/rom_rev2_demon.bin b/3B2/rom_rev2_demon.bin deleted file mode 100644 index 222eb33e8cd5c87be535de3951a81610dfda13ad..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 65536 zcmeFaePC2qnLmCenLr4E1PE^}Z7(I16p}VjYAH;cJ9!TYOiFm0Pz@myNNmVVGYJDs zkiT?yARw{Cigm@v&3L>%h|nxX8-`Uu6Ma&NFzP#p4rVE44Ku#Mn8sQ-`M-?RE&U z7kPW{!SfW_RfXs*7NRgyi0jeTibsX;=LyksOo$I&0?ck9o(3+Tzgjq61diS&Bm87a z+)RJ3L#v$|cei(RwEDV5W%yfvwHDNedz(t49+NO(Veui!P5mW!;chKjn%qO$6Wvf3<>Rk=;6 z*tE&BNm*G`ymGCgY}~rZy+LVkZ>-tuRVv*zbz3%7WCA+dvis3p~6ino2x67QupS~6`Q;%&96f92lsjv4cwH02aY!hKRN!c|hyP;x( zXOmaiT+uKY#9L8{`%vlGw86bu*@(8wJR9nPWNBT6vaM!wwbI~i*j%wec7B_C)5e;O zRj4HiKM7&SQ?_DzMcEead9}L^ZtYS!oA=LFN5x6_F(Z&B0*EC$d_(j=#gFaEianN7*v9vo(~I+T!or-QKmgxx3xp z$v{xxuGRx0tE{UPiJg0tW@UGWKM**eAekHPY~Iz;spHg{1z&LxIp-i?wHV4>38*4n9b9|*K6%l7z}DFt^E{JVSFyRRoyBnJLY zYQcs=i+^vRqqVyg(1QnpzMj1Sv9Gl&2>gvIt?2I3V3w!}276lZTD+!Xf0o$P3WS3c z4`$W*n~gFJtzGTS9m>X@y}Mew%(7YHZb34t#3X-nr$KJ+xxY(6!`-cW6$rD|LiEhn z-qqUD?e99k167zMP{iNKBZe+20e>*qPBbG*hnl;PVvHk=Yj7=kg63#KO5)R-97}pL zI!UiaKk4=E0wNP?F5l{@DPJz8)tilUpmU0^bzgf+YfwRB1l|*%@in?h)f+ne+@P`% z7-Wf}xA)Iv+NG;}1cd+L-NZr0R~84siw5HorIm6{yzpSgcI@4!yLZ94(s6sB#@ z+(M!A#I)TMPR-2vas=VDozss}e0DthlN2tE%=j*awPNO}2*Qtx9M~;FZ0QX41Oomp zn#rZjJw9bqb2rT^AFxw0Mb_Tt{Yrahpr@NA?oyx9($?J7+yXHcEL6H$i=-UFUrZXM zqrDUCCq(heRX44^`F*#nxwUy$i?5aOD(LL#=)mM@CvkQ?WMNiWPgfTzDh+b_m67b) z)6>Pm3tVm_m-?H#e9GR|y)+?%?FWII02+H+_cZT1(A`=9Rzviz_6|Qq!K_(Ji^0%E z#-x$L_BLf{(XBvO_*+`I)s|KTX{&sNN|5Fb-chMgsVP@l{65Mn-j5Ur8e#`!mmg&$ zZ&J~gLZlE@p>|()8>Ikr2!c70;8P6bAU=Hl9*7GOgm^{30J~c6R_@^5SWOk8<-LLN zsRA-R=!dvz-qqgG-hF@(5QRzrqLM|HOkl8yKO&3YttrK13NB&N0AD6XYG;i)fDIzn zceMr~a5^nT0W_dMdN96O<(`cd7$A&c%|_S>o3_+%Ru(T->KnEJbjN;0sW0Ofk{hP& zvU;tuWn;zm`ie3rL&d6RPDzRRgi2H7J|{%(t9V`)V%8Kq^YDO!W|iQ1Kb|f;AI9?l zo-gD1I-ZkwzK`c=JTKunk7o?CVLG1c@VrlmgDrRt;Q1(?FC<3%B{J!>m?Y>sgjakyF;BP>Xk-P_b$sZu*5}<5r7pYhy-rgw%qpvmC($yY-<`EV9 zF-ba6#o+th%{?96Vh?5}vYZf?12Tn&~JT|I$r5%7mV+TG3V9Z>th)^1TR z>xu@dC^mA7qQ1Gay+x3|vHGPfSqj78+NHs3m1gK4pO1N(=XS?_%%EUM&OS0I#NL*G zu+}qK(grk5&9$%*H#U$#?e%QgWEhBwyL>~<#+ruBhJ_1judZfu4b1JTEj8sdL9!}q zHf?|fS)pw3aDoN@M&F*juyAhd>1^Lm^T=-Hzpa^q`7(a8B!PKLE}jsC5DWe!(r3*O zk#--%YT2eTrM0UIg9HNl+JkplRD>P2UnxM5uGa3Z_SWF_BoEqmzq1;}D{ox2^2Rlo zi$bhySbYO2wv{)mq$vK)@5l26Jebq-F{kHaPS3}jp8q2}SSQba2G1|?oW}DCo^yC0 zBj#U1FEa3CkBrM8x$ew zZo+3fLc(VULc-?*2nnBNgoKX|A?$z!yN&QJgoIxwLc;HEgoGb_1B_qD2;oy;JbR7s z2tva5s1e?aa0%jnV}$TAh63 zjSw<=!D9%QBYXnk3WWcRa4|xRABR6fSco{rQWPQl1;QH;ju_z!2o=O%LI}oKfN>UA zBm5mgqW2#V621S3a3(^?d8Rk`fa(3;2#MZrBAhM6LIeUlu@E#Cc?dy6F&81mRLnyN zm|{LcjFnh`5M`;-Lc9y`(ZWRtuS9qaLcA{o?Zj0GK?4CET8O@gVuY)VIQc~=PJD!a z3yF_Vcj4^_!D|c45UxhJ9wEvu^dJQ9E!>O{Fcx|dg69@CAuK_-2O;V%>_m7A!fu3X z5FSK`HWo$@x)ACJ(bmGhGQxWiu0@>2m%{rHstEs1@}a1Q_J%YR(A^v~)KkzDuA^qA^VEg{NFMR~O--zLh-MfnC%Cd%A(b)sQ| zXs8wdSGhq{)*u1K$7ZonlzHmCqO4w2i7JoSEFiqgDn!F({LgQdqS8pJ6b;5}=_avh zgMin-4Hto^*vP>h;*KruIL_Ta*ep<^SZrD;HmwqyZW5bTi%mC+ zP45$%ZV{W-P=C-X>MGE;`a#_``dsSXQZDFEwJ604f)cSAFL0EI(k)e z0wV{inA{q)Shd#qqROvy!y>XYNn3k&mMDkkW}{LD%isnDHI-}k_^&0%39GZzGCqRJ zZLr6Rz^jTPpyHvMuwG$xv}XVHNN(}>bW&2A??yZd8VIgMF$Ebub|I{SjoPx;a2gP| zm`@oQ|7de}M|(>*t#9`F_mNk`X8E8&?w=6x!NFdK`U6LLJT3B1?jJd(#HU7n?9LEB z9DJhJsh)CV$7e*Ia_5Mr2Y=c-Q_T`T8T{wo>FSVUT0ArIr2ARNg80J7bM7m}F9)CR zy+XZO{A%!p-fPrrM^$RHu!q)E$V+dZjP^xoOip##lbgwZ&Sw{CGp!Mm)!sD zSQ}p#dBc6H_^-hWy=&A0ac1z9-s{!hIab7%M}F)6gX4zyjghnNBJumdS9=T9mmT@> zrIBB|mxb2tZ;7h$r)E6C#<4R=I9dqoAH%C72ZV_J?{QKTr>TdDH!T-~{ zNBsv!Yup!k(A^;(9{g(WUUk6Xk9S7C=KiwdgYml}UvamKFAYA_+otXpCkMaXdqDlJ zBOE^%`HuT>$Dz0u`M&!@;(LRS_1>dC>gbO5M84?`iEj=5WA8q-OMGMSk=~&Cb;sTD zK;#5C`Pks!_THi1?`Vi`irnY^xMOR4TjUe&E#mJ6kN0j?`yF@2-yivmyGeX*@Uy)i zP#eXk20z`qL;a+~8{Zyzz(!0oqk|vo^{9X2*buLad;~LE zAN+7{g&K8K#VaFy?!%7Kcv<9#+bwzrBfY9B#8>=yAVAS8(K2R7s~U&k``pU@1#+L$~~m~Cy!vX1s( z3+7r;y(nrB<^E77`HF~Jmy*i{43FsuUzfSO2x8$tGf_HT$bZLvHF%GZL6fBr#(4Xl z_D-5h0=6AZCYaM}c|yVcNKTwxSmdLXR?Gp+C*$AJ{k+-@V!kv3O6&drHARR(YG5AP zv*GYjTK5L9jy3S1E_SuPMHd@j`I~(su>g<-OM%{6>ZYx6K+js%b9rD{o4cAjg8}%` zAiOrvgfCLC*in{!z`cxMx9%r_w5_?T6J1!Vl=?wy7Cs;*dB4b83FPt4QUNWJ!GeF^ zfF1S?=;p7(Hlgqx#eXlvBX{BXtq_m4qHY}Fm=NEDZShUmh~J!Dv{6|9V`$dG3jzlP zF^W)#Q8+U_nQO67_8d zg6&wo$=F(@p&PE`RuaHTBAo`^mX$0#L2dRC5N`|91!SxS$$KgS?If6s-Uoko%dP;u zf*qwh!(_N1yyng129mi*o}j?4lme-Z(e$9UNS-&a{vwtI1DH!w${@u+|E`7odhL(! zyoBdJVKPGpEP-vfWDy?Nd`n<^E!lvl1y4I3$c807c*1yk@kH@_6wk-;d=}4F@SMam zgy&g2zs7SGrgsjW6?oiu+VJedgSz>DhX*!yejLv)@w^JN+=*u)9<&DzgRg__dEL!;s_^WbAg9`q-E2+zHE(4Y7};Q0m~jNc$=6-V7T)jf|m#&Hm1IEXd}cj37U4`?}v z{tUvn90WZF`|x}S&&SZ;r>0s{0*;N&UutC-z=&|Q`+ESR63!3IGcYGN zx*Mhy6@V0LkpP<^oZBe1Vr7%h&3{YzZyEnB=f5ysky|OG6(^uj2vuP?Muhb8?&{eM z@S?4CKN&*s&2)APUu#P{d3CG=!!2b(Fugwzi{0XGh>P~!?SO%BPbb@m)aSP5j@|4e zZEhjYPirtGKRM4PG~i8x>yaUDg#H2rT6pKC9oTjCNTmh|BptimuwDf_yG#SsaJ(wi zBOmlzw`l3`Gx6{4@xv?SZYZm%NpvmPx`$B?LeN7mcC>cxfdb$`0fnTe&Maf|*aey~ zw4@<1XiyIDT2VqbBbo%mtn1&s8`J{hkY~?KG)l@uVi^q30cdc!B?avrlyDObC$(vU zvEzXShI9sk-HM7@+FD!g0&_}l9iW*K-Sm!;+fQkxttM&Si(RxQ0H=Jb@G%=h((i5c z_jHRQQ-do$Klq&5+}+*{WQmsD?R$uEC7%e|S?k2sl-PUIs^%L|8G`{MqKh-QI4Bkb zM61h|<0&ZUmC+9N>}3l>5C=%tDxC7&7$tZr$*E{ADTIZ*DavguWST*?B&?xoHj9dC zQBy4{wqr4cW!{#CicKPm_5R|iS#Yt)ZFs0%YfD%xZ4pIFgY+Myh!8)5toYGkJjd}s zUj67Ko}b_u!Se?pevC3do{c9T&ni4Bo{f0!#PdNs`|%vky2G45fC@VY))@IG>1`uO z>;}K@gA=}~n*>0^fxWx@9YO3QEe$FwXww3!5)wa1N)zbG7pQZJllDX|bUWE)<}*&0 zq6nwm$m*5cd@^B|VpF(Apev4K(~)0_$qF0V6`~Z4LxUR#F$Uwqj3s_W?sdlcfT~sHli6Roe5x64z#~ z@{Z5tYphPGvHC6BSd&s?4QlYeU%|Hf)s1+*i-+ECg9o`z@Smlt(R12JfvW@v(<}RD zG!X)v={|e}z8A*iIxyk=@>z|R{%l{k`{F4O^^S`tS{!za2F4*e5 zuHw|-ib$)IL5&R7BghnK8>92I9K|UDQNK@1=a;7A!br-}rpv5unUJpy76}mu<442uGWS!4t_JED&ydZjIxY_U&+{(aqx>74H*YNPk;I| zS~3oPB7-WN@Q_QIDrgx8^$btOL5(UL%xKCu*psm%<6waP+?8=x#=+fO!DxZ%<#Iig zu1n2va?S^)h=VIrvlPy%%{VweLnlPty1P^_Ez`@&_3{e6qEfG{(yOXnYW2R?oWl-P zEpvuP^h@ed)qT`mdbG6cXj%Eu@`|Gsl}9V9j#gD4RjZG>tB#gd9xbalTJ1hsReH3t z>}a`q)Ll+6zQHhRryf<+@Z)-oTVG$Q*OloT%Jq#E+}BTsz=?=0b;mp#~6QypKTMcFAYun)R zvK8(3h=>qX{~sX$j!G9U&+lg}`n=`?n`?7jo*C!9dasNCyJIV{zjUW|3_20PJx7Iz ziNaGCwStcd5!J-7Q;b%DyRRYcj^=7P$0$^c(4n;fW?&>ud(bI_x}sjo1&}+j4};)j zNQe=q%qely6Dhi7V^kpK$u0(LZ_H76>bzEuWo3aHx=wd^14!dMnR5y`BMvP_@S~3U zKzODVYpDw2t30HpetfGSAt^e}74KJxllUOTb2) z(DcGP&u&ML!oYP+SO~C-N33y*Dg?l`GR*9NKR-$vb$=)4opDXSliB9`HeTS@3prce z7jk~&EFE?-+u%LZWFfp~mkwu}?4;e$=OC0Am(0l4fC2M$J!fk`2Mqd?Nq@2fVJEQH zI?$VPNu>&xXZVk4>o`eU67>f(Cl97y)uzzP5p62Ro!SfvBUSm@?KfdqszS5TB;;nL z?x`yjX=UL`NyrNAItj8uyGn9Zg_h^?T>bFxzFMJ8mvpTNO(%R&IXq2P2NaC2pizgCie3kuK*uCmG5P$CqfV-AQZ;HfDBR!%>Hpjf9<)5uSELzT|6H!B3*6mFH^@0vkQud~upD8RbVL zd7_!t9GK5@!=WvsFj5g-6{!k4fsUshPNAx%*U`)z&Kj4@HIG%e$}4s}RpL0C3zpSZ zlo$#~TO2w25#s8|**s)me0W@vrv>gS zzdf_O_BWIrtr}HhDoIe1r3I?y3{OXP(|JdE?XMG=Cy$uq%)Uj4-}yIJshC1LKk$=C z1OSP#Dg6aUmHLP(+x~9TIidAXYh3!7%t#Co%1$IkBVVA}`>ax9j>xB}R8-YM_QcN_ ziCAix@TNtM8;J)Ki4H3ZqD=M_BPo!BR!+fr@n3cR6UX2pPiF$#*;eKDX zPQLaj^xY8F`-xXt^xNcQj(JFl#XMQXP7zBZ%|ZIX&|jAyZ=D5`1aks1k3|A%Ubsz& z@U?H%kJm90QMEE!X^!qNk1i=SI=YZZPYf)jW2h=q2bR)ba8z0Y8!6*bG^%b_FAXY> zY}3t2BVMUaFyfV}eZ+M~5~K$R68&kqf*VNXg_Pp`RGj`KiYIYNN^xQqW{##C8TvEh z`3ESc@DE@VlxeFI)H2xUEy-_;6Xqz*L(l9eho{xY9k9O2!!yh{A}~219)UROtVTpGrr`{sN{lxG&m-Z+_{yo7)fsHo>zeb)c+GR zMOxL7%5a`urS?0k^lCT6r+!C$;Qq>zS(UZF(>=vgxM2Qe3g&Uah%DIsmIa4p!MvQw zo0brV0jk=m5sn-3wckUXI)~1i>WCCkZjG^Kg8auoX+D4q7&Ex=&Vij7QPmq*;SFWw zYoCWM3(qJ?^U^e<6&L9N5izIkz^OFU)61Z!)w3^?rqn%m!a$Lu*{{ejDn`{O)3epH z#1*gs5X;FmVkRdb)%~Q%AYL(eL#9ljlx)d8#01LJ1QR5eoI0-VG^FUB^9O`D`+&ra z-?K4>=Z%Q)km~WB0>i%$c1H)XOaUEA>jM^@xQ2Sa#3G8N&jfWrNOa5I zY_$F~rr@r?CyaXI+tpQH;8afTb57XJyGGr^nQk|hQ8Wn8IRi#>_sdR~WOKOj`mxC< zXIpCIgNip02hc*p0BM0? z0Jh+w{0@{q`vh?UEFzQJL)Y8aF0gs>nG-K+55YH1?tn2(!ZvN&!kA~3tw_w{O^Wr} zVzNq_mK*bYeO$7Wl7BHSIg^r|aD9-WLpVqvxs<$QT(UyRa2wqO~`{L)qiQ}RI&PNmi6G($|7Lzfsk3`aV~j+O&cjWEXuON{Uq zBb*VTa@s7CQ*x5B;cUG7w;JvtZH{6UFqQ!Tej@>~nh)ewS#q4#KeUV!&a|rVI$8#8 z=Vj1#7>g@u2}Du+MfBRJe+y#xgUH+?u#BtKW7SytIKxw2Rn)WM%d{PgX?D*A7BduhSf; z;?RDEK5=brT$YtUr1(o(Fsmn;csu?6u3x)+w-qgmsZwl&xkjjEBH2beiUy(?GIs*n zO{e^KM!RXKV$hCiCpxxHlUd2M`wLni+9fvu+FhpKP#2l18kIDFPfZ(he}kN5yU1%K zdCj5|>wQTbrZiWYlv0Xh0W$aHV%6+xZi&JuhNkLiYPe)F{Q7pi4BHvFsYW|3$?X}F zL`rzrCl%H_JynkNctC37m+8Hm-j7J>Y^d!>d@{p>DB7PPBoyb)o2J#-3kN2q$WeRCpY$CTVwogG{)~hMnc!CWS&&YCPm6&+DM8F zSE9?1GZ#!duL8=_(rFNdEIU(m9e}^sE1t@>$w(dky8T3B!%pmWKvu;(Gm6<$SY&z% zV;(xfKk6m-9x0y~DUh>j2K*A11CUhBsYVcYObsd0(Ln`bo)xHS>Y;q??;DWDZjj{a zF;5YfyP&=N3NPa^R>4ZDzuH!Rbf_Mn240^5<6$avchyXwM#v5|#-^Frq7dSQs{x8i zUWJnD?U2x!ivwRX0bQCA^X#-|%Z5H`=KpF2L1hBifIf*@0edZYQW+fruI0fIdW?M& za@7pxL+29|i+Q@Zu7xMMysL`3e82|t2xR?rG0zWdNrZ%LtJj0n=TC$ejVxRfNd<;fNw?I+DCl%k*5+l;ZWf-Q)thO()G82I6nn zupHmrtFfJ%7?#jAFeOPdPYldXr|Xg`(llOQO?1NPO8m{ulVF)MJuXVq&W+jA)^oXh zl#6*5aq07tk3Bn)6V?8V(xyCpo!-e{mg4n|p4-W+b;VsUg zZnbYH@UnZ@>84GY!}X96DM|6P3DTV7(vHNZ1nvXS+jEBkwO=|iw3|yrhjwEjB7yf$ z!JIJH?sBzHq$F&pQG3xohtVn$-S-1l6q`l~9HkRt6oyV^?fA;c?aU;v!nMOyE6rNb`cdkWoBC8r zTYUYc*f+d`n+Q#dIshoVKD>GYFzB`c#2rQXXCSYDmRV=sc!c+jtr+r!GLH|3J!wg%bpQ)!rCXinPku{F%fY zJ7=qrYK{?+R}3|3Tba^|1T(NOgW1ESx=m8d9Y=~C|3;LU7xVlH;0^1G^zp$zULv}* zF@4$*%Ko%joi|2rsX2PccSncXu%|Ca4vsULmV2N;ONIa-G}kQoMovAJ7(;sk*fGLi zGdUGN-|0c8Y%K~;+PLQHF)0oYby-TV%bEw460{{*O3ePBwO<0u zwaS@mbMV0z4lxM)cZ1@)L(`)=V`>=-jx1Vt~aiu&m&nfVu}z*bo2##i*IXQzhtX%nRyM`nDg50U@l3X z*Qw+%=k>1v-afBi#k>yM=JjOL?~%a__^%!ExCqQ#Iu?S(+cG`#Z7e7b?)#(Z&$B#f z@?qiX1izNYUv=m~E~5!372 zczwhj!BSQH1ZXViyGEmrs0P zkHHbT(o825Dy@t(ZLK*pbU4Z^gs#oeJ=6poL1!;gufwz8Z?PwsgPdD!_=It^D7@tM z-0B_JUN{cU>w|E%FDnm%DEC$ORl|HvSJm6QB6%nj8g_9z-Jz9cPBbzP8K>265X((O zgM95SfEquBOdD+t2fBxr%<_QMN%A9l1DuXV+{5YE!0M$&cwtO=VP#zFO~p?28*pJ; zNThHBF$>1L8-p;A3;FjdIj?As$Mn+^J?8TXEmy9(V|w3=>b_!#t7}06Iyy*1kX@xi zf?cETlR0djJw1{Jd+G|}V}yzk78{{oHD6%fQ#Fh(uAkJdu-?WA$nQ60~7*#Em%734S&3o(u7rE>9p4ft&_4 zT~qSV14M|ZGZ@a2oKfC3@xlgTX;bii98$tAjow(Qcf0ldYVksoMFaXz zFRFUI_6)mX<4)~adV$C-gbT9xNu0W!C|{2+(ngGeF)paXw2&|`#~FsM$|B^8bckAj zq>?&2Ax~Yv@j@zITU=q48wbIu<)MgL{O|;ol7JGPR^LsrhKV}YoWL}*u?BqvPRsD> zcYYdd#L=j(t9NKWcJY>aW5~OLkGnx6a}Mq1RF0%Is!_><^iq#OO~(tQe|XX4c?Rgv z3#2?0vqlsXC_FpH23vLj@z#Lr_Kb3%RrSW|eC^d8kQv-HvJgkT zwCi70HXSI*LKm19CJb?*f8ma)sB^r)52EsVK2LwWk_3FlnTIGVv!x>Py7pogp zm%mQ4vVHXYMYD#n{cM{%k0O@>fGa>n$ z7|P=+1w(ms?)4%@6)BO9KzRAFj(|RtryfI`2s|O15vUc<<%Rw&d}U0TfDI{M?@$5C zh0fLfyU}d!P<|jhM|XfYdKSG;)iV(gI*Ngg5}K}hEOVGLWa9ts1ln0%r!#_ zcH)oXZ@+^`rC$*BL#&>?j@Y2$VhNa`-|wybUZz935mCR6QH+nOwxs*oL>b{C@RN*`=x*UH%sJ z(7`vWu5$T3>YV9e7*_y zmwjWqFrOJVjG2--e9D}n?@lQ*w%U&qcy72n9`6WGHn+?UzAKx7&~utLLw9H^Lk!kK zg9bxY@4m+X$&hAX4Y!bBWn0lKvx&b5IxST5wW&Vh8j_}@j8EN7MhF(xV_vM%yk>#h z=XgWq@20VY`ol5qf1+OOip@xED3clrd)}i)7?^GSjk5@g1li8}+rX6PT7|%;OF1i^ zcjC;0qcS}GSa$$w(iu97vjCV8ub}`N7bOam8c$oSBXqSRP%1A+U8=ua`yu{rKeT!bLCc{lDe!4u$KT+gf5(QDfB&I{W8t6oJKG?5o%@O}r5v2# zRZzbN`@*6wJmnZUjh@GuHl-fxICzhEK)o_;nmx@Y(~9hAZ8ELUo(4k%@UZeofCD>l z8@DAAFZjIflWp#k9qyAux$ZS?bzcbfXsTbR6iq&T?4jIU9>TJ~6R5GFZ{ z$E!;G&A}Zr#{AoigzT|fj5iyZkGB`AmuRViyV;&!h(#k2O(qEhR+}Ki-n_LO-G0$P6hOO+W^i0~` zO@V+t#fegLa^+U=IX+`xhy2I{kj?E-EmQX&P{UJnf9C`(i43`Es=>;A4Nz42y6a7P z8IP5ig0iqINl1^!!I>lJVej2koXZ~%XX*mLAt2*Pbn^s2#54oNq>h*?tOOZSiD=a; z#R;8>;AXx(xZx{eo*k%9@`JXX5-lES1~){&4J(>MD0J6^g<_sV)Oho#`rv4qN~?*_ zA$;;lea?~ z#t7V)Jf==54NGF4FC`=I3@;~N_}M4na)i=+{eFl9-X8WgPI)ut`H`(OYghKX8A2uD z9f=0zhk7f5phN-$)x)W|;m*Q@xTk-vrA@m=;5$`7AQ9KjI0wD26B%z>e? zO?nZZajG)@V{$_xlg?jqfgfiY3E5^swoK?dZO7_D&X48yuzjaXN9kK?{yrP2^2^xN zRQZi;QY!dU8bGx5f?=`FKtqM--K9^Ym6k?eVU&6@opGnTcwr{e1K0_g=G0y#mxx}5 zAt}d3rCt%oSBRDPm`AUQLr+%6^8#=r;*%YmR*WwS=OoqLtAJ<*L@NP_FadI)@d2ofymSz>g!TJj-5T4PB1G{ zOUnVXO9j^HN6;?@r>R5&-E#tWze)IkQ|U8mH5Vm6nLZ<@7GFT&9b0=`?))uyrv%h_ zmEKp=do)d3V}!SI=+M?t7~?Xrro2q(inDZ2_V8S|NaK!CukHI9nU;<;vP)K%q-$pZ zIg}ZNLkdufP?E)|N>8l_WW0eGr$xHupc;S4ls>xF4-3EKrTh6${~)1jQMBIpMbMX&OW)h+!ifugu{nVgwQZMX9jNjZzxy(I;F3N)?cKk-dd1HvnC^$)hYxt z7KdndC0mqyok2n_Ei_1$t!w8nfiS;kk-*Mo6pMR&wWrYa2OY3gr|MoTcP7z2;}py! z_+z1`cWVWtNA&$#A%!K5pX7wHquH_};TuN<|YS3ncArD5B$9=v9oEX}Wt=QU3C_S69+qX% zvZ#fLBo#jZQa-HoMH3Si4wMa~YrLLG3J5h^2q=UHPH|3NXeuU8Shv|>;AfnZv2Mb_ zijDRamts4)kBC~tGQ_^hrPaDop3irZ#p(>tH^q(ZSnZA!7H6- zk<*{{PN{LToTVC)MSwk z1Co5~!rtC6*qZJ*Frm8Nz>4b;H?#WaE_u#~xK)0xLcTBi^t5;n%gt_B>~>yZo|GEG zyf*@;8AOb?^JBdAZ@Lj;ozEZ^=(#7}h4btmmq zZ;P#7cp0VKX-}C8!d3k)o~Eh=YVAw;$36ngW1d|oGU}z1JTaBe^B_MKfwhj2qvINK z{0dK&;rcAQUHfywAsdSx04PPl4jrTF)mwT(CyRlBmGj z;lP6qd@jM)puKmaYh$V5L*@cX3PJn8i#Z7qU<^F$Gh@vri=%VKhjjLe)80u%`#hRw zjz+Rvrf)lK@U3q=fz4`Lx+mAxu05UV$G8?vsA!txad^o#)4-r>ftNsqF&Rbjb|aY% z{@O7~^wus{OdB5zOmilb4w9ue!7ghK<6W`{2ayeG zjK7G*$u@k`h~0j1ArjoYuJy~;oxG3~-z01bDW03rDDfrf#AM8UX$%t9etX_h8y zMB2#hRzKzE7;S-Q`zRz`w2l6h2BOoeQwts^`SXb~F6zJ%8XJC;&oeI2>9#TK& zQ16AYnnNw*P$F@IIf7UVmmBM#BbskE<~DA`3aWaONaLHljOc8>UCW3#`DQM&;3|1f z7O&GW!7=!BtDawok8K8A6Q}J*0eSrcC31uPo_jFCAUSZi2-UATTp6B?ZG~gi zdX@WF744VaSJ`*E623G4W_8DJcnR%LRjTZ!Kc%mZ9*zM-?_>Cb9q|ZkHe7mF8NQl} z!iV4QxfAjetWn9grNTNeA@cd(=NXSzM>FN!bhwR+y@`CGpxN5t$WDTquZ?^d@|yhv zTnn%6VF%r_+DipSv5gfuN&NvqE<=vP72#0d=?W}!VeQhoKSEu{Lh5cSHOfgSfe!SY zhR>ODjHAzVSs{0&50|@ALTnzZYv!7%drGI`@5PixBI6CFeb99hD;^tAi4eCI8rWg`yG;XllzA>m7> z@*kAMS%c5=ttifD9}KFF%4ERd+U1M$+t~zgSi}!;-rh; zq?JWeThnIV$4!!v26(reMp#+R-y7?e*poilcOUc#t@No#Y6etFf)?R6Lg`)MKssgH z1i<;I#qDNK-w~trj2TR0?N^$<9O!XJ3?feIFS;ERhfzJHwwKP&(2-yWpNElAFtA1D+l30GQhskkL3UE)y^pJffH$25yaIb6+y|XYNPpV7zb5-orknXVHp@G{@U;u-^C!ZA72(kD z!Es!jKJLm%(7|-gxSF06YQqexz0j|$*U6h+7lf-rTRs`c47DL!LhX^2s@+hDK3283U-LMrlpQSX^8N;=c3`;~ z7D5NM-N(cpsQA57FOP%uvV`T8*{_bWLdQvQwNs|NoJbkUF_ige2T6%~=xFrCYPMu* zXVZ)q(#VB7Gz$l|qd^3R>5Sj6K4NM`t~oFRzG?Cg{F2f;wKf{udpl51Yp2)fUhRV% zc4~KVIFzGx@QXv+OChG zMx&#^Pgo^6Q+Z5T39o*rIzUmL74SmCZ*wQ=#-3I?n# zj(Hx2g(@q=I%2t4YOwWdG@Lr`G0gDsn6gB>fcao>NHNrwBo3Xl#dK!s{Mp~e{3Ma& zuk;8>OPCPf;X_ioTa&B?tQNolhH6d7>WjuLrpyly_0pB9(q?*y`HUF0Ey-3RmfcL- z3~Oj#;`*1sF4eo^JBF;b z?}@Vv#NAqa88q&`;?Q!apKKDi)q?(LwD9I1Cx|r_@=Zr9(jmey>E-3m)`ifA@!@F3 zeY*m;ui91n-s82OzJs??7~2`C90|DEGn8LujRN+a*KSb z4_&tFkjCv3AA`p#RnXI70jTlTdj@S{t@3*Qo9MkbA**pX-s`aor*;%HK!=`xqbY`c z6&L=(o|l^}E@JEu?+!7{rZefd<4)EHY1hb?%!Gus$u_H*RGG%S_3G$s`K6DPI;&wY zU_#;Zq;yQH1B@}>wr@^6Dv;pABl2SISkp%{Op}SKoO}8~dwFTe@uDEKpilb-m|5Fr zhylLXJDhu1CK&LJv;`QisM;QQnGk$mlC7!LjKisq zA(FE;3A2H$F*|Bdxu&hkn2fer#?!!GJEBefVmJ24!lAsVzXm&%7?Re&BYt&v0Jr-3 zD<~y`l;{VgN%#nan2K8ocG1Oo`P%T`f>!OLK!G%vgJk6u6H_$Y^@8Ir5}RqnIkE02 z&RPI*tkF^hAJN~CKhahy6x}TwxS(D9CVHtfJeSuRsIB=np5)Gr%PIV{J=^!sd3M zkJ3wj73NAh_jnOcRqg^Wf|6$_OB1q9O6dqXt)=?ARTmCtgPjryIKX6l!@ks(O2wL3 zGv`pB{i?V2F}nniI+|rb!2Tg+_Z;XazVeM;oZ8M6X#yWo+T?*LHzvEUldsr>cw44o zOyTLmeR9|f#ObH2MH*x}1vN5QFRxABfZKfOYGPHUV(%>1jF(>{aPv_l$!{3T09$Fh zK0)^**kv!{B|i?;WG{GsLfcOr!RWXS3Sn-$V5dWy8Jj~2;=;h2BAgw|mG6Hvfm$OM z^E|K+4084Y`G3xy$6u3CVtKO8_r}$6YOdn~WSe7l8%;qzTo|~|ESj*wp&?Vs=E}0W zCn|e9rR*$OcI`xE<0)nHWZ9YH%etfsHng}v8@UP#^@Si;{b#X;>ee1*e(2UtQfQW2 zt8dgYF^++Y_?;eva;j?`zd)6G?IJ+nASMMgQk<%47bsP4)J`zKH0>ybF=y&n65W~a zbuI~i>zJ(K%Jqik&^8*4txDTyP22^saVOg^N+@Ayy{ zU~#&T!JlPhM;6I)I)9FgyAdYDfKDjf3VNOYci1p4yo`V|!#7DvYI7n?QCyfu9ldV^ zJY=zNcqT5z(thMpXKFtQ|4Zr&10?p68{TmP4pOIlF2VVUUN@@YOnoC{#Z;F%TYH_b zvb4QzuH!%@Y`^Y}ve*Tad;ex=yDo;c7d(hu=#;N;*2q2SFC&XLrJ11x9A?NmEw zm=BI8SR#fme=iR7JBZETS^uOE5p5AMaYR!nK&MOp6-aqr1!^eDh~;Y^<$~RdxZr*Y zKuelcRN?T8&{f(Q#I#jrlP>L5#Ot*MG(8O-f$1(qTo_j-bLDWsacz{KcrIT~A`tUr zT#-O3qCF|mIYoh4;tE>{6PIK4fiwQiUTo<_M&{y9|3Z!(=Lj5H1}{&9XC0TMKW@Eu z6m?}CPCXWR775hlJgpe~{32SrxWy>Y@=pQC*cB7(^K_h0o(f}B* zM0$RWM$X}ttR{{cL?fJC#0G zTRW5+%A`-2!!wW``ze*~2*j{^dvU;biRKM1dWG=K^VYtfQw?2!&&DxI#=x}k$b@Dy zQZDYhkB;0(bjor#y&%GreVRalmM4xeb8Awh#Jn+I3@iHc1AptZNm1qw17Ft?cv+4~ z_OejLG7xuV{+%2L?dLqq8f4kPEN8e9rDXSUz?iRrz5h+QLsg6Z_&hUXO(#e`FbY7? zr$(6FX!_7Qp=&88i&x(on@^6%rb>j@j>9Iyj!o^P*qE}<@;OJU!?{4Q+C=wQwQGKL z?OEIQDobNtBV7(#T-MeR^L%DJw!I?UW5YIrg14i=HdPLxb^}w>U<4nLt4(!zdDxi; z5c5fnaE7z6Aa~7gs~s$8BdWKJ>t~y)J0#i7aW{SI=;zhkPor64qiU!GTi0=<P<0!8Kh5t8U6h^6$!7hG$-p&JZ|#uY4i9%C^_-JzpoN6t!}I+F_> zVYMq;qXc*KZ>f3K3^LW6P!b7;6l5~Oqrjt=V2gz9R-iow<&Cd*4TBXSCBUMF9u+uJ z;qQiB!KAL&Zs!=*3g+N==_(=OQCUuxniQnOAtk%1$`VLlx zZ|BX_XRs?KKW3o4MdO?2QS4(@j+Q=J>OR?opO-W?Hcw%`j=CSE4K>{2t{$%{P^-Sj zK*$_O`k5T=E$bEXA@Y%G?7=&Quj#dd{bf*0XYgS-jc@*MVC$|b*pFMzJ(p~0G0&W< zY$ad@%(ca1p5^u!a|%InUD_W)(L!5h!G6#6G0%;*lo$Lv!*HdLe#a$s$K*w35AGxz zVWq7Yn@a<_leM!$dwDs=On%{EUowz9Tut_myhx01E2En`Z<3GEP=W52MF-} z9YA5V27!-{G`AQ{8d^0|zl8MVG0*no^lXeN*9$|1?c7A9Bb{z)o+4HIN4!f5Ov{Tk zom*@c$=9g$(T-RFar&oVlN`~`5eE3c6K$}cp3#hXC>aIY$U-Q??nN0oBH&a{1{LM% zqxAXl2W`DfG{1yo-Fz}O2>AJdUF7C=hVLM;<@45_30JY6mSzy8QA1Yg)w1-GFdFXw z{Fs-aFp6wG8J+yTsmU+`tR;qV;YGjaJo=!Xnbs&T&VfzhIZi+thjDjQEJC@aSHhlR zF237P{wq|zjTDn~bB%O2s>5kG>&dk}pigW+-6=%|;rW3p*}gE#xVVf@!{vJ4ve72y zd5VDghT+}sm(Y@Nfx~H8%yXU#VVGoRb7P(LOZv1tu-bL`VYp$}$P| z#}kwR@6VH5Ks!YNenA!i?QC5bxB$uaEXCNf_FKe8DMnV#zzAYzC^nU1KNaDuQC^ie z9q>_5Goe4~jU8CK`5%Iv@I)R;N7(0&>OkHgx*BT+AeYil%m!rua;%u{ri!>Y@TGJ( z&oL*5dlM4T%H=EF;GaKF^r4+tegnc#f8|!Gf!22k!`0L)d{`i6_(G4yrp7$~iDpcw z=d~OD1JlVvO~*3j)SG(&xZVP*htP3laOk-P<40-?xo&z|@iN+MP z(`ZLUYGI=zjVQ(PqyF_iZ0R6Bt?x88P^7$F_d0r35o;=D9a#TQ018IFIPfh;YHyRf zm(q9gls#*k<~k!Prw|sls>7fW>G~OA`puK^`+_W~>=c4m#ixdYcCtXdF;H)a*2}M8 ze#P*Ev=;|59bun2!{GYl@c@cEmBaJk7UU@|=O&de#|2KhoRKhY2Vx?;)QpC&yol3A zwR2rl)T-P#DJr!#GyfP|SeE}<@-yR$0hl7m`^W#J>xM?AG^&Jfvzu?Yok}MsafiZ5 zj~K%ZrqAH#?kGJ1HeM9Q&o9&OG&!~ZqREJDYW{^L+WgJ*)xxAtJ?csMm}1RNi*AWMj79l^IAgpME+)n zfbhwN*GdX-d`}=RnLImwe@E7FXb+NQZ7D_VAtP$o9At$(OiAGix%Tqf%5nyrs=Neq zaaAt7V^M`yOIJ>qV*++TnhUj$=fGHeW}83)Zio<6~7 z;^Wr;dCYKWJ*itsqv3Q8tvE2dX!>jIqd84t21o5RQltI+3G#(#Cnv!79SrB>>~5}4 zu!I>_Ftv>(%)kedv16H_PcgA8d28$vrfVwb^aN;LlSd`3N#{jlstsnC=PFgPEU7|5rKsttWp7Biy4-TxIzHb6b z)6Rg&i8_mEXu6rwGym|V{#<-|!sE|b_?3F!j$h;V08r5?+$0_LM9C=hDLxehS}~to z4VY`lWD21hWQuFD8|{;J1DZ9p_2Vh6@06`~qV+x)-&itp>wRr>uw|0gVNfMnKQL+Q z{q)^UO6TuSY5q>xy!0z#N5gXuH_w|46R-wWhScJRgzh4CTg#@Z-XAftoTF$iu;46Q|Ekj#K71oEl)(`X3cSVuo4y0}`LC zOs%97My?@7aNioU5*w}BnNwgD4ATXz7~baoG|nQE!mu~~E$p!>fN&RW705l^?;Ky@ zYBC1bFMrdOsaEE{8E12F{grR#A6tN)^(ThYI3TU!fV8EwSVHouM{+mq**U%?M9DJt zjcU_NuH~1|Zk=7Hs^M0R)?;VOwL<2R^MGXw?>Suu0~#y1n3`I{kS^NKz_}${vm^9< z1D&FEKyvMXj-9d9knwqwslDBpd(?d z(ka@uSVwFq7t3|yfUR-I-9S!)AuNp+z7|*7AKQ;{l)K0z?Ih#U`1Rk@NOzAN@5U8W zRnJ=NWZw_CCFXe$T^LTUh8He(E`5Agtv;AZUl@2EMh0IEhr{@S$tfLg&;02{UGygfeNn-4janf4f=3#N2CPjI#)=WS+=)Bp22hZF{Sy%NjtH?sAh|>m ztxy8&U~vQXN2y1N&XY7{A55a}gy*#;KgK-Ykn_eoVsRDWG>bT1mlD8a_CJJg0t|Bl zg-Tt`^TI3V#mot+U=M%X8BoA@`7=c2f$bUj+NZIf6l=;QjXJQznOHaEYbWJSQ!dUV zS&`enYKxqF*cN%#p40U;TTb?XEmD5M7Kzy-;_J4YFWT$uwCAjcWg^ib=k-PHA92Ra zi1XyI#qn##N%>hR@#!h??36g)n{9(PGbKMKCC;bPY~}eRqb<%N$QCC*mmU9EDe>7U zaTX-D`s7ly*JoQXk&khH=wD3YAQCxki>&^cEmDAkOx6$=zhH~39W^7^iJ^o2Z zaG4`!7TjZ#<{8z<$vJ7g2{X~cc_?ZNtw%p?ie>Hr<$cl^WeX}VTlluWau$=y~i49!|cR$kRryxPTbt)RxPlPDJl{vaaNay7zO2H+~7)#*T~ z2smmlM|4vF2^M7qJ12uNbOu>T3~yTaVpn*__+p z0s79~RaIR!FKPKS@Do}*Jw1Y7{lTu8?LJ!RPXzIC+q=a^ie#fdl}wW_ub8lGOPqu^ zE_@9xSH~~g%q{UBd|p(|e52_Ffh*qmr;u=)aLKj!p_@6lHQyYN5<=ytCXo{>01y|q zvBCwj0_WIE))||$^f8OIu(H-OB}!16yCSH~Dp?oQvP-4~QDZHx&>a7PCc|foMbe4P z)`6Tcb6mcBi3Z@}!22kLPFZS1Iw^1!(n8#m*55{7iXKO-Gu3q7_EpV3R&zA-pNRe_~nAiNte1wi1E!i_U!QQ%LFOFA!*h z`m2bU%d~ztB#ac}69!vKwp_~DQgX+oyS7l(A3ySU4_++JIbgI}dqip%Evyp?OFV%@L1Sok*&f6aju8 z#vvSXX$<9>00`ftQn)e6;M?tQCNc{+)ng)XTo!^x$k)oil6C|V)c9_OJO}cAi9HTz z8Yc(s#Ycw}9A(GEB$-h7TZ8=vMyBu?3C#&)wCpoDGr^RdpsNu$Fr~6M-9evIcmDl08L1=Cw!SsSXLY4dRgI*BkK$HYn84v@c z0*ToYc#ybLD1@J1@$Zm=9KQ{%7-TgkCeP}D10V@%lS?i!WFroSp_bfGAEL7e#8t!T zXw{HvvpCYv;!F;ABxShKKm4c_|2CLO#Y7FeGKUt>5oo2@lrY0i{N@&Q7--@L z*zj9p2E1fwuhA!%6FUz7x_@X9kSuno1&6-&rc1s4&=2u<`JsF8x9CtY{@!q?1%Gcm zRP_d!eaE4HdGp}ymy*C6)IYS~4TJ5Hs0F68|*i9IGK3?IIMHA=py~){>pV z2NX9&s-cWvOo)aHZH$tEZuo8Wq~35q7N39NOz>2scC`kdkQx$h}_{)B@dlJ!k4tH&I!EAdK! z0S~#j!{p5H|84JTW81pQu;aQU&C=GT>DH+o30nY{Wt}&5rBVZSQY|qJa6Mp5&NQVP z*%YCO7+UHgPr4qxr28>3qg4n*Brc+$3JR{oesrin1wxv&KS7#=I;AK;MvH)@f+7Xg zZFrvdeB67}q#YkW_~A&A?>+Z?zUQ3xyx-@c73Jn#GYIXloHCP8Kg2yy;o;&S2wQ)o z>!f5R_JFC=>=nAR?_ZPxuuHL2kbrb=6k?pL-IFs3U@H&@ zprLgO6nu?{5G!l9TBIt2aK63VHY?ovV5CUxKHGXLOYQqFnmrkAR_0pTU4S<&#u%;Yl%ht|oJMYzRmvj5=lhRoz3GvVqY_%?>TxI()N zcOZr9T9z$n6Ar3vJWvg<23|*Co08Kknza zZaZ;AR%LC?t{KmsO333(T-g-PjsqKE-NSeZnJtZ-1nt6uwCJ5jPzPMf$I~>|SI9m7 z!;1P~H3j6wwvs;eoTa6u7oqpT<&V+}x5IW77RMix6Wh2beic%a)Ck4XwfH}T!~onz zsBFC1h#rrQ2An2cVk}Z$BOCew2Q)kic96761ik^&B-E<0vx|r(UKP=$=p0 zin{dkqNG{NW2Kw1KiWk(qqL}CMmOf1U;57H*b%pgqRNxmcMr)k-JNkok0?WY=V+*7 zp{@jdNx4ZB;La)*4Ic9(?Pfw-&+R}d^slPs$xUtL%AR7d`VR+OQ``M=5ngKBD-vD5oz&dw)m?u_EyL~QKVOP#O@H>1W*eG zEbEp0cbD&clg$;B(1*f*v)9OBCkn%JzVp3MAra3RnLM>Sh~VOnRvt8~*|t{Nf=9v? zHIwZYy@KzYT%|QL=Qqp~d;LnN1G?Ae!u3EQabvGv3l;j$dre&j92-_?E!1mSsTi`- zu&^cA#0`LkXD zO)!U|$c_C=qdS^XC^oi7Q)r@-Ms0A!4Z5S;iWT>(y7OeHL2oR391&l$gOkP(R@=Gm zAr4Oow~okxBj8zGh>IZvjm6GE?D;M&1jYOH4Bj^>F({Wa@-*C-sH?KCw=*67qvJxc zBt`c?sf=WtoD;Pd0val%C^=2A*53IJPDEk?-e`cto_caph{bMOnpZHF_bo2US@(7d zkSXh1Ti?n}Q?%8f=Fv*5^a^{t6vK3=?t+QK7mye|?gJPzo?CcyRBSoqUt}2A*KgzK zz_re{fCH4sFr!PY*;AvjHm3LBF6y3oH`~kxWhdv<3Ej)Hnv8NUhnYf?DQPBcvmzzo z-m?grf{lTn-QGXl%0RQMF>kZs0=LC_inpk>YR9Ddu3~w=>2@{9sB1#k(&UxFw6=mE zsHa)qfgqdoaJru67-b&|#9fi_?xUIa`ZbmrttM!8nr$wtI7WK{;muNwp zeQMvh#zn5I9)cQwW_GY`4HO||emGGB(Vq=&Qu_o%G(ek*vLL&nv>sxHQ;<}OD5+&x zjyW_pc#RVJ5EEl%x$`(?SYg#trk7Z;I`G z=&-c+U1@J>jHZ55hn2zK+iP#N@n7ZmyhA~IJ3Y47cWBJTJ)ysm_JFzIZ+WYB1n0xm zk(5HPXlOq#u{lV0cJC0BYn0vF?4pz~A9Qn)(&bI~ppI2l7O%&lvxM6Z$*K;CnNpj8 z6TD9~YVE1OJUo~`P{%+OU%CKVMg+!g2iXQh-ke(#(=lx9dEs7G&kSPG72J)P(Np+o%S=98ASOD8V^;~ceR)zR1P(H=_2Dza^=Tr2=-biM zX{M^J>Aqi;fvyq(qR9Qw^iP%WBM#Z+i8IdCrE5!SKxdq#uIu_4*l?~TCWD6Kj`|+$ z*Rr;xTg%#V*(sBD!y13UDK18d%ZPIwd9|KSbdcA{mF7?0ZRKv=#�sK51?qiWj>i&lkTPhD|4EoM{qUd5r_&bUz z;u4moTX1gKriF-9pRo7L79SHAd2zbe<5iHMJs<1#9+nD7ob?YPj3 zz$_56i5(4c^9Zed}Q)#$^LyR@6oWqLXVKbVxDAh09Y6UE?U>wSutlu?c((wH~j|;%XuQYl0pX$`%^sK zA{{K2pY)vr(X1V(O7Y$BX6C!$+syl<3U-&RN0*B;57d=+&uMDFETOOw3#t*=h1OdaRFkA!QO$n8XwYy6ALcvvnNjbth z{Ubyca|N6^hx&1eHQkXots{luKZf^-l)&Kh{zlg;=>#-dK00z`VFsTel)+%+$~oNG zOpb4=(z!ksQ}nTt8u?E94W-W9vXlfZBqd6}**-Dx8Y$i3J9Sf%gq>kfSmpJG`deG+?|r#@ z-F1Dr`%3NAq41|fX=5cDD%QxQ2g)5M+XwIf(fvR)@1IgbZqgeF7kDA^hU>NeKl}Az zEJAEih&W1ZLG$GK0KobH@2>eeVupWPF;w@GD$MOH@ FzX0*WzPSJZ diff --git a/3B2/rom_rev2_demon_bin.h b/3B2/rom_rev2_demon_bin.h deleted file mode 100644 index 0184366a..00000000 --- a/3B2/rom_rev2_demon_bin.h +++ /dev/null @@ -1,4129 +0,0 @@ -#ifndef ROM_rom_rev2_demon_bin_H -#define ROM_rom_rev2_demon_bin_H 0 -/* - 3B2/rom_rev2_demon_bin.h produced at Mon Aug 23 13:30:22 2021 - from 3B2/rom_rev2_demon.bin which was last modified at Mon Jul 26 08:03:30 2021 - file size: 65536 (0x10000) - checksum: 0xFFB345BB - This file is a generated file and should NOT be edited or changed by hand. -*/ -#undef BOOT_CODE_SIZE -#define BOOT_CODE_SIZE 0x10000 -#undef BOOT_CODE_FILENAME -#define BOOT_CODE_FILENAME "rom_rev2_demon.bin" -#undef BOOT_CODE_ARRAY -#define BOOT_CODE_ARRAY rom_rev2_demon_bin -#if !defined(BOOT_CODE_SIZE_1) -#define BOOT_CODE_SIZE_1 0x10000 -#define BOOT_CODE_FILENAME_1 "rom_rev2_demon.bin" -#define BOOT_CODE_ARRAY_1 rom_rev2_demon_bin -#elif !defined(BOOT_CODE_SIZE_2) -#define BOOT_CODE_SIZE_2 0x10000 -#define BOOT_CODE_FILENAME_2 "rom_rev2_demon.bin" -#define BOOT_CODE_ARRAY_2 rom_rev2_demon_bin -#elif !defined(BOOT_CODE_SIZE_3) -#define BOOT_CODE_SIZE_3 0x10000 -#define BOOT_CODE_FILENAME_3 "rom_rev2_demon.bin" -#define BOOT_CODE_ARRAY_3 rom_rev2_demon_bin -#elif !defined(BOOT_CODE_SIZE_4) -#define BOOT_CODE_SIZE_4 0x10000 -#define BOOT_CODE_FILENAME_4 "rom_rev2_demon.bin" -#define BOOT_CODE_ARRAY_4 rom_rev2_demon_bin -#endif -unsigned char rom_rev2_demon_bin[] = { -0x00,0x00,0x05,0x50,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0x00,0x00,0x05,0xE0,0x02,0x00,0x0E,0x74,0x02,0x00,0x0E,0x74,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24, -0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x0E,0x24,0x02,0x00,0x08,0x64, -0x02,0x00,0x2C,0x5C,0x02,0x00,0x0F,0x74,0x02,0x00,0x0F,0x70,0x02,0x00,0x08,0x58, -0x02,0x00,0x0F,0x7C,0x02,0x00,0x10,0x20,0x02,0x00,0x0F,0xE4,0x00,0x00,0x67,0x00, -0x00,0x00,0x5C,0xA8,0x00,0x00,0x5A,0xCC,0x00,0x00,0x64,0x10,0x00,0x00,0xE9,0xE4, -0x00,0x00,0x45,0x00,0x02,0x00,0x0F,0xE0,0x00,0x00,0x5C,0x1C,0x00,0x00,0x6C,0x4C, -0x00,0x00,0x6B,0x50,0x00,0x00,0x6B,0xCC,0x00,0x00,0x8B,0x34,0x00,0x00,0x8F,0xCC, -0x02,0x00,0x0F,0x6C,0x02,0x00,0x0F,0x68,0x02,0x00,0x2C,0x4C,0x00,0x00,0x14,0x24, -0x02,0x00,0x0A,0x7C,0x02,0x00,0x0F,0xD4,0x02,0x00,0x0F,0xD8,0x02,0x00,0x0F,0x64, -0x00,0x00,0x56,0x74,0x02,0x00,0x0F,0xDC,0x00,0x00,0xFF,0xF0,0x02,0x00,0x10,0x4C, -0x02,0x00,0x10,0x48,0x02,0x00,0x08,0x6C,0x00,0x00,0x6D,0x64,0x00,0x00,0x6D,0x7C, -0x00,0x00,0x6D,0xCD,0x00,0x00,0x67,0x40,0x00,0x00,0x6E,0x30,0x00,0x00,0x2C,0x08, -0x00,0x00,0x29,0xE0,0x00,0x00,0x2B,0xB4,0x00,0x00,0x6F,0x14,0x00,0x00,0x75,0x90, -0x00,0x00,0x6A,0xFE,0x02,0x00,0x0A,0x74,0x00,0x00,0xCF,0xE4,0x00,0x00,0xA1,0x1E, -0x00,0x01,0xE1,0x00,0x00,0x00,0x59,0x5F,0x00,0x01,0xE1,0x00,0x00,0x00,0x59,0x99, -0x00,0x01,0xE1,0x00,0x00,0x00,0x59,0x5F,0x00,0x01,0xE1,0x00,0x00,0x00,0x59,0x5F, -0x00,0x01,0xE1,0x00,0x00,0x00,0x59,0x5F,0x00,0x01,0xE1,0x00,0x00,0x00,0x59,0x5F, -0x00,0x01,0xE1,0x00,0x00,0x00,0x59,0x5F,0x00,0x01,0xE1,0x00,0x00,0x00,0x59,0x5F, -0x00,0x01,0xE1,0x00,0x00,0x00,0x59,0x5F,0x00,0x01,0xE1,0x00,0x00,0x00,0x59,0x5F, -0x00,0x01,0xE1,0x00,0x00,0x00,0x59,0x5F,0x00,0x01,0xE1,0x00,0x00,0x00,0x59,0x5F, -0x00,0x01,0xE1,0x00,0x00,0x00,0x59,0x5F,0x00,0x01,0xE1,0x00,0x00,0x00,0x59,0x5F, -0x00,0x01,0xE1,0x00,0x00,0x00,0x59,0x99,0x00,0x01,0xE1,0x00,0x00,0x00,0x59,0x5F, -0x2F,0x66,0x69,0x6C,0x6C,0x65,0x64,0x74,0x00,0x46,0x44,0x35,0x00,0x00,0x00,0x00, -0x00,0x81,0xE1,0x80,0x00,0x00,0x2D,0x60,0x02,0x00,0x00,0x08,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x08,0x02,0x00,0x08,0x08, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x81,0xE1,0x80,0x00,0x00,0x59,0x18,0x02,0x00,0x0B,0x24,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x0B,0x24,0x02,0x00,0x0C,0x24, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x81,0xE1,0x80,0x00,0x00,0x59,0x38,0x02,0x00,0x0C,0x24,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x0C,0x24,0x02,0x00,0x0E,0x24, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x81,0xE1,0x80,0x00,0x00,0x59,0xCE,0x02,0x00,0x0C,0x24,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x0C,0x24,0x02,0x00,0x0E,0x24, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x53,0x42,0x44,0x00,0x0A,0x0A,0x53,0x45,0x4C,0x46,0x2D,0x43,0x48,0x45,0x43,0x4B, -0x0A,0x00,0x0A,0x46,0x57,0x20,0x45,0x52,0x52,0x4F,0x52,0x20,0x31,0x2D,0x30,0x31, -0x3A,0x20,0x20,0x4E,0x56,0x52,0x41,0x4D,0x20,0x53,0x41,0x4E,0x49,0x54,0x59,0x20, -0x46,0x41,0x49,0x4C,0x55,0x52,0x45,0x0A,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20, -0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x45,0x46,0x41,0x55,0x4C,0x54, -0x20,0x56,0x41,0x4C,0x55,0x45,0x53,0x20,0x41,0x53,0x53,0x55,0x4D,0x45,0x44,0x0A, -0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, -0x20,0x49,0x46,0x20,0x52,0x45,0x50,0x45,0x41,0x54,0x45,0x44,0x2C,0x20,0x43,0x48, -0x45,0x43,0x4B,0x20,0x54,0x48,0x45,0x20,0x42,0x41,0x54,0x54,0x45,0x52,0x59,0x0A, -0x00,0x0A,0x46,0x57,0x20,0x45,0x52,0x52,0x4F,0x52,0x20,0x31,0x2D,0x30,0x32,0x3A, -0x20,0x20,0x44,0x49,0x53,0x4B,0x20,0x53,0x41,0x4E,0x49,0x54,0x59,0x20,0x46,0x41, -0x49,0x4C,0x55,0x52,0x45,0x0A,0x00,0x0A,0x46,0x57,0x20,0x45,0x52,0x52,0x4F,0x52, -0x20,0x31,0x2D,0x30,0x35,0x3A,0x20,0x20,0x53,0x45,0x4C,0x46,0x2D,0x43,0x4F,0x4E, -0x46,0x49,0x47,0x55,0x52,0x41,0x54,0x49,0x4F,0x4E,0x20,0x46,0x41,0x49,0x4C,0x55, -0x52,0x45,0x0A,0x00,0x0A,0x46,0x57,0x20,0x45,0x52,0x52,0x4F,0x52,0x20,0x31,0x2D, -0x30,0x36,0x3A,0x20,0x20,0x42,0x4F,0x4F,0x54,0x20,0x46,0x41,0x49,0x4C,0x55,0x52, -0x45,0x0A,0x00,0x0A,0x46,0x57,0x20,0x45,0x52,0x52,0x4F,0x52,0x20,0x31,0x2D,0x30, -0x37,0x3A,0x20,0x20,0x46,0x4C,0x4F,0x50,0x50,0x59,0x20,0x4B,0x45,0x59,0x20,0x43, -0x52,0x45,0x41,0x54,0x45,0x20,0x46,0x41,0x49,0x4C,0x55,0x52,0x45,0x0A,0x00,0x0A, -0x46,0x57,0x20,0x45,0x52,0x52,0x4F,0x52,0x20,0x31,0x2D,0x30,0x38,0x3A,0x20,0x20, -0x4D,0x45,0x4D,0x4F,0x52,0x59,0x20,0x54,0x45,0x53,0x54,0x20,0x46,0x41,0x49,0x4C, -0x55,0x52,0x45,0x0A,0x00,0x0A,0x46,0x57,0x20,0x45,0x52,0x52,0x4F,0x52,0x20,0x31, -0x2D,0x30,0x39,0x3A,0x20,0x20,0x44,0x49,0x53,0x4B,0x20,0x46,0x4F,0x52,0x4D,0x41, -0x54,0x20,0x4E,0x4F,0x54,0x20,0x43,0x4F,0x4D,0x50,0x41,0x54,0x49,0x42,0x4C,0x45, -0x20,0x57,0x49,0x54,0x48,0x20,0x53,0x59,0x53,0x54,0x45,0x4D,0x0A,0x00,0x0A,0x46, -0x57,0x20,0x57,0x41,0x52,0x4E,0x49,0x4E,0x47,0x3A,0x20,0x20,0x4E,0x56,0x52,0x41, -0x4D,0x20,0x44,0x45,0x46,0x41,0x55,0x4C,0x54,0x20,0x56,0x41,0x4C,0x55,0x45,0x53, -0x20,0x41,0x53,0x53,0x55,0x4D,0x45,0x44,0x0A,0x0A,0x00,0x20,0x20,0x20,0x20,0x20, -0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x45,0x58,0x45,0x43,0x55, -0x54,0x49,0x4F,0x4E,0x20,0x48,0x41,0x4C,0x54,0x45,0x44,0x0A,0x00,0x00,0x00,0x00, -0x0A,0x45,0x6E,0x74,0x65,0x72,0x20,0x6E,0x61,0x6D,0x65,0x20,0x6F,0x66,0x20,0x70, -0x72,0x6F,0x67,0x72,0x61,0x6D,0x20,0x74,0x6F,0x20,0x65,0x78,0x65,0x63,0x75,0x74, -0x65,0x20,0x5B,0x20,0x25,0x73,0x20,0x5D,0x3A,0x20,0x00,0x0A,0x00,0x70,0x61,0x73, -0x73,0x77,0x64,0x00,0x0A,0x65,0x6E,0x74,0x65,0x72,0x20,0x6F,0x6C,0x64,0x20,0x70, -0x61,0x73,0x73,0x77,0x6F,0x72,0x64,0x3A,0x20,0x00,0x0A,0x65,0x6E,0x74,0x65,0x72, -0x20,0x6E,0x65,0x77,0x20,0x70,0x61,0x73,0x73,0x77,0x6F,0x72,0x64,0x3A,0x20,0x00, -0x0A,0x63,0x6F,0x6E,0x66,0x69,0x72,0x6D,0x61,0x74,0x69,0x6F,0x6E,0x3A,0x20,0x00, -0x0A,0x00,0x6E,0x65,0x77,0x6B,0x65,0x79,0x00,0x0A,0x43,0x72,0x65,0x61,0x74,0x69, -0x6E,0x67,0x20,0x61,0x20,0x66,0x6C,0x6F,0x70,0x70,0x79,0x20,0x6B,0x65,0x79,0x20, -0x74,0x6F,0x20,0x65,0x6E,0x61,0x62,0x6C,0x65,0x20,0x63,0x6C,0x65,0x61,0x72,0x69, -0x6E,0x67,0x20,0x6F,0x66,0x20,0x73,0x61,0x76,0x65,0x64,0x20,0x4E,0x56,0x52,0x41, -0x4D,0x20,0x69,0x6E,0x66,0x6F,0x72,0x6D,0x61,0x74,0x69,0x6F,0x6E,0x0A,0x0A,0x00, -0x67,0x6F,0x00,0x49,0x6E,0x73,0x65,0x72,0x74,0x20,0x61,0x20,0x66,0x6F,0x72,0x6D, -0x61,0x74,0x74,0x65,0x64,0x20,0x66,0x6C,0x6F,0x70,0x70,0x79,0x2C,0x20,0x74,0x68, -0x65,0x6E,0x20,0x74,0x79,0x70,0x65,0x20,0x27,0x67,0x6F,0x27,0x20,0x28,0x71,0x20, -0x74,0x6F,0x20,0x71,0x75,0x69,0x74,0x29,0x3A,0x20,0x00,0x0A,0x43,0x72,0x65,0x61, -0x74,0x69,0x6F,0x6E,0x20,0x6F,0x66,0x20,0x66,0x6C,0x6F,0x70,0x70,0x79,0x20,0x6B, -0x65,0x79,0x20,0x63,0x6F,0x6D,0x70,0x6C,0x65,0x74,0x65,0x0A,0x0A,0x00,0x73,0x79, -0x73,0x64,0x75,0x6D,0x70,0x00,0x76,0x65,0x72,0x73,0x69,0x6F,0x6E,0x00,0x0A,0x43, -0x72,0x65,0x61,0x74,0x65,0x64,0x3A,0x20,0x25,0x73,0x0A,0x00,0x49,0x73,0x73,0x75, -0x65,0x3A,0x20,0x25,0x30,0x38,0x6C,0x78,0x0A,0x00,0x52,0x65,0x6C,0x65,0x61,0x73, -0x65,0x3A,0x20,0x25,0x73,0x0A,0x4C,0x6F,0x61,0x64,0x3A,0x20,0x25,0x73,0x0A,0x00, -0x53,0x65,0x72,0x69,0x61,0x6C,0x20,0x4E,0x75,0x6D,0x62,0x65,0x72,0x3A,0x20,0x25, -0x30,0x38,0x6C,0x78,0x0A,0x0A,0x00,0x71,0x00,0x65,0x64,0x74,0x00,0x3F,0x00,0x0A, -0x45,0x6E,0x74,0x65,0x72,0x20,0x61,0x6E,0x20,0x65,0x78,0x65,0x63,0x75,0x74,0x61, -0x62,0x6C,0x65,0x20,0x6F,0x72,0x20,0x73,0x79,0x73,0x74,0x65,0x6D,0x20,0x66,0x69, -0x6C,0x65,0x2C,0x20,0x61,0x20,0x64,0x69,0x72,0x65,0x63,0x74,0x6F,0x72,0x79,0x20, -0x6E,0x61,0x6D,0x65,0x2C,0x0A,0x00,0x6F,0x72,0x20,0x6F,0x6E,0x65,0x20,0x6F,0x66, -0x20,0x74,0x68,0x65,0x20,0x70,0x6F,0x73,0x73,0x69,0x62,0x6C,0x65,0x20,0x66,0x69, -0x72,0x6D,0x77,0x61,0x72,0x65,0x20,0x70,0x72,0x6F,0x67,0x72,0x61,0x6D,0x20,0x6E, -0x61,0x6D,0x65,0x73,0x3A,0x0A,0x0A,0x00,0x65,0x64,0x74,0x20,0x20,0x20,0x20,0x6E, -0x65,0x77,0x6B,0x65,0x79,0x20,0x20,0x20,0x20,0x70,0x61,0x73,0x73,0x77,0x64,0x20, -0x20,0x20,0x20,0x73,0x79,0x73,0x64,0x75,0x6D,0x70,0x20,0x20,0x20,0x20,0x76,0x65, -0x72,0x73,0x69,0x6F,0x6E,0x20,0x20,0x20,0x20,0x71,0x28,0x75,0x69,0x74,0x29,0x0A, -0x0A,0x00,0x2A,0x56,0x4F,0x49,0x44,0x2A,0x00,0x09,0x50,0x6F,0x73,0x73,0x69,0x62, -0x6C,0x65,0x20,0x6C,0x6F,0x61,0x64,0x20,0x64,0x65,0x76,0x69,0x63,0x65,0x73,0x20, -0x61,0x72,0x65,0x3A,0x0A,0x0A,0x00,0x4F,0x70,0x74,0x69,0x6F,0x6E,0x20,0x4E,0x75, -0x6D,0x62,0x65,0x72,0x20,0x20,0x20,0x20,0x53,0x6C,0x6F,0x74,0x20,0x20,0x20,0x20, -0x20,0x4E,0x61,0x6D,0x65,0x0A,0x00,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D, -0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D, -0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x0A,0x00, -0x20,0x20,0x20,0x20,0x20,0x20,0x25,0x32,0x64,0x20,0x20,0x20,0x20,0x20,0x20,0x20, -0x20,0x20,0x25,0x32,0x64,0x00,0x2A,0x56,0x4F,0x49,0x44,0x2A,0x00,0x20,0x20,0x20, -0x20,0x20,0x25,0x31,0x30,0x73,0x00,0x0A,0x00,0x0A,0x45,0x6E,0x74,0x65,0x72,0x20, -0x4C,0x6F,0x61,0x64,0x20,0x44,0x65,0x76,0x69,0x63,0x65,0x20,0x4F,0x70,0x74,0x69, -0x6F,0x6E,0x20,0x4E,0x75,0x6D,0x62,0x65,0x72,0x20,0x00,0x5B,0x25,0x64,0x00,0x2A, -0x56,0x4F,0x49,0x44,0x2A,0x00,0x20,0x28,0x25,0x73,0x29,0x00,0x5D,0x3A,0x20,0x00, -0x0A,0x00,0x0A,0x25,0x73,0x20,0x69,0x73,0x20,0x6E,0x6F,0x74,0x20,0x61,0x20,0x76, -0x61,0x6C,0x69,0x64,0x20,0x6F,0x70,0x74,0x69,0x6F,0x6E,0x20,0x6E,0x75,0x6D,0x62, -0x65,0x72,0x2E,0x0A,0x00,0x50,0x6F,0x73,0x73,0x69,0x62,0x6C,0x65,0x20,0x73,0x75, -0x62,0x64,0x65,0x76,0x69,0x63,0x65,0x73,0x20,0x61,0x72,0x65,0x3A,0x0A,0x0A,0x00, -0x4F,0x70,0x74,0x69,0x6F,0x6E,0x20,0x4E,0x75,0x6D,0x62,0x65,0x72,0x20,0x20,0x20, -0x53,0x75,0x62,0x64,0x65,0x76,0x69,0x63,0x65,0x20,0x20,0x20,0x20,0x4E,0x61,0x6D, -0x65,0x0A,0x00,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D, -0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D, -0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x0A, -0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x25,0x32,0x64,0x20,0x20,0x20,0x20,0x20,0x20, -0x20,0x20,0x20,0x20,0x25,0x32,0x64,0x00,0x2A,0x56,0x4F,0x49,0x44,0x2A,0x00,0x20, -0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x25,0x31,0x30,0x73,0x00,0x0A,0x00,0x0A, -0x45,0x6E,0x74,0x65,0x72,0x20,0x53,0x75,0x62,0x64,0x65,0x76,0x69,0x63,0x65,0x20, -0x4F,0x70,0x74,0x69,0x6F,0x6E,0x20,0x4E,0x75,0x6D,0x62,0x65,0x72,0x20,0x00,0x5B, -0x25,0x64,0x00,0x2A,0x56,0x4F,0x49,0x44,0x2A,0x00,0x28,0x25,0x73,0x29,0x00,0x5D, -0x3A,0x20,0x00,0x0A,0x00,0x0A,0x25,0x73,0x20,0x69,0x73,0x20,0x6E,0x6F,0x74,0x20, -0x61,0x20,0x76,0x61,0x6C,0x69,0x64,0x20,0x6F,0x70,0x74,0x69,0x6F,0x6E,0x20,0x6E, -0x75,0x6D,0x62,0x65,0x72,0x2E,0x0A,0x00,0x0A,0x53,0x4F,0x52,0x52,0x59,0x21,0x0A, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x32,0x01,0x00, -0x00,0x00,0x00,0x00,0x00,0x4B,0x02,0x00,0x80,0x00,0x00,0x00,0x00,0x6E,0x03,0x11, -0x00,0x00,0x00,0x00,0x00,0x86,0x04,0x22,0x00,0x00,0x00,0x00,0x00,0x96,0x05,0x33, -0x80,0x00,0x00,0x00,0x00,0xC8,0x06,0x33,0x00,0x00,0x00,0x00,0x01,0x2C,0x07,0x44, -0x00,0x00,0x00,0x00,0x02,0x58,0x08,0x55,0x00,0x00,0x00,0x00,0x04,0xB0,0x09,0x66, -0x00,0x00,0x00,0x00,0x07,0x08,0x0A,0xAA,0x80,0x00,0x00,0x00,0x09,0x60,0x0B,0x88, -0x00,0x00,0x00,0x00,0x12,0xC0,0x0C,0x99,0x00,0x00,0x00,0x00,0x25,0x80,0x0D,0xBB, -0x00,0x00,0x00,0x00,0x4B,0x00,0x0E,0xCC,0x80,0x00,0x00,0x00,0x96,0x00,0x0F,0xCC, -0x00,0x00,0x00,0x00,0x55,0x6E,0x73,0x75,0x70,0x70,0x6F,0x72,0x74,0x65,0x64,0x20, -0x42,0x61,0x75,0x64,0x20,0x52,0x61,0x74,0x65,0x3A,0x20,0x25,0x64,0x0A,0x00,0x00, -0x20,0x08,0x00,0x0A,0x6D,0x61,0x78,0x20,0x69,0x6E,0x70,0x75,0x74,0x20,0x6F,0x66, -0x20,0x25,0x64,0x20,0x63,0x68,0x61,0x72,0x61,0x63,0x74,0x65,0x72,0x73,0x2C,0x20, -0x72,0x65,0x2D,0x65,0x6E,0x74,0x65,0x72,0x20,0x65,0x6E,0x74,0x69,0x72,0x65,0x20, -0x6C,0x69,0x6E,0x65,0x0A,0x00,0x00,0x00,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37, -0x38,0x39,0x61,0x62,0x63,0x64,0x65,0x66,0x00,0x00,0x00,0x00,0x28,0x6E,0x75,0x6C, -0x6C,0x20,0x70,0x6F,0x69,0x6E,0x74,0x65,0x72,0x29,0x00,0x00,0x0A,0x0A,0x43,0x75, -0x72,0x72,0x65,0x6E,0x74,0x20,0x53,0x79,0x73,0x74,0x65,0x6D,0x20,0x43,0x6F,0x6E, -0x66,0x69,0x67,0x75,0x72,0x61,0x74,0x69,0x6F,0x6E,0x0A,0x0A,0x00,0x53,0x79,0x73, -0x74,0x65,0x6D,0x20,0x42,0x6F,0x61,0x72,0x64,0x20,0x6D,0x65,0x6D,0x6F,0x72,0x79, -0x20,0x73,0x69,0x7A,0x65,0x3A,0x20,0x00,0x25,0x64,0x20,0x6D,0x65,0x67,0x61,0x62, -0x79,0x74,0x65,0x28,0x73,0x29,0x00,0x25,0x64,0x20,0x6B,0x69,0x6C,0x6F,0x62,0x79, -0x74,0x65,0x73,0x00,0x0A,0x0A,0x25,0x30,0x32,0x64,0x20,0x2D,0x20,0x64,0x65,0x76, -0x69,0x63,0x65,0x20,0x6E,0x61,0x6D,0x65,0x20,0x3D,0x20,0x25,0x2D,0x39,0x73,0x2C, -0x20,0x00,0x6F,0x63,0x63,0x75,0x72,0x72,0x65,0x6E,0x63,0x65,0x20,0x3D,0x20,0x25, -0x32,0x64,0x2C,0x20,0x73,0x6C,0x6F,0x74,0x20,0x3D,0x20,0x25,0x30,0x32,0x64,0x2C, -0x20,0x49,0x44,0x20,0x63,0x6F,0x64,0x65,0x20,0x3D,0x20,0x30,0x78,0x25,0x30,0x32, -0x78,0x0A,0x00,0x20,0x20,0x20,0x20,0x20,0x62,0x6F,0x6F,0x74,0x20,0x64,0x65,0x76, -0x69,0x63,0x65,0x20,0x3D,0x20,0x25,0x63,0x2C,0x20,0x62,0x6F,0x61,0x72,0x64,0x20, -0x77,0x69,0x64,0x74,0x68,0x20,0x3D,0x20,0x25,0x73,0x2C,0x20,0x77,0x6F,0x72,0x64, -0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x3D,0x20,0x25,0x64,0x20,0x62,0x79,0x74,0x65, -0x28,0x73,0x29,0x2C,0x0A,0x00,0x64,0x6F,0x75,0x62,0x6C,0x65,0x00,0x73,0x69,0x6E, -0x67,0x6C,0x65,0x00,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x71,0x20,0x51,0x20,0x73, -0x69,0x7A,0x65,0x20,0x3D,0x20,0x30,0x78,0x25,0x30,0x32,0x78,0x2C,0x20,0x63,0x6F, -0x6D,0x70,0x20,0x51,0x20,0x73,0x69,0x7A,0x65,0x20,0x3D,0x20,0x30,0x78,0x25,0x30, -0x32,0x78,0x2C,0x20,0x00,0x63,0x6F,0x6E,0x73,0x6F,0x6C,0x65,0x20,0x61,0x62,0x69, -0x6C,0x69,0x74,0x79,0x20,0x3D,0x20,0x25,0x63,0x00,0x2C,0x20,0x70,0x75,0x6D,0x70, -0x20,0x66,0x69,0x6C,0x65,0x20,0x3D,0x20,0x25,0x63,0x00,0x20,0x20,0x20,0x20,0x20, -0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x0A,0x20,0x20,0x20,0x20, -0x20,0x73,0x75,0x62,0x64,0x65,0x76,0x69,0x63,0x65,0x28,0x73,0x29,0x00,0x25,0x73, -0x23,0x25,0x30,0x32,0x64,0x20,0x3D,0x20,0x25,0x2D,0x39,0x73,0x2C,0x20,0x49,0x44, -0x20,0x63,0x6F,0x64,0x65,0x20,0x3D,0x20,0x30,0x78,0x25,0x30,0x32,0x78,0x00,0x0A, -0x20,0x20,0x20,0x20,0x20,0x00,0x2C,0x20,0x00,0x0A,0x0A,0x50,0x72,0x65,0x73,0x73, -0x20,0x61,0x6E,0x79,0x20,0x6B,0x65,0x79,0x20,0x74,0x6F,0x20,0x63,0x6F,0x6E,0x74, -0x69,0x6E,0x75,0x65,0x0A,0x00,0x0A,0x44,0x4F,0x4E,0x45,0x0A,0x0A,0x00,0x00,0x00, -0x0A,0x49,0x4E,0x54,0x45,0x52,0x52,0x55,0x50,0x54,0x20,0x21,0x21,0x20,0x50,0x53, -0x57,0x3D,0x20,0x25,0x6C,0x78,0x20,0x20,0x50,0x43,0x3D,0x20,0x25,0x6C,0x78,0x0A, -0x00,0x0A,0x45,0x52,0x52,0x4F,0x52,0x20,0x31,0x2D,0x30,0x34,0x3A,0x20,0x55,0x4E, -0x45,0x58,0x50,0x45,0x43,0x54,0x45,0x44,0x20,0x49,0x4E,0x54,0x45,0x52,0x52,0x55, -0x50,0x54,0x0A,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, -0x45,0x58,0x45,0x43,0x55,0x54,0x49,0x4F,0x4E,0x20,0x48,0x41,0x4C,0x54,0x45,0x44, -0x0A,0x00,0x00,0x00,0x00,0x00,0x10,0xD9,0x00,0x00,0x10,0xEC,0x00,0x00,0x10,0xF7, -0x00,0x00,0x11,0x06,0x00,0x00,0x11,0x16,0x00,0x00,0x11,0x29,0x00,0x00,0x11,0x3F, -0x00,0x00,0x11,0x5D,0x00,0x00,0x11,0x72,0x00,0x00,0x11,0x85,0x00,0x00,0x11,0x98, -0x00,0x00,0x11,0xAA,0x00,0x00,0x11,0xB1,0x00,0x00,0x11,0xB8,0x00,0x00,0x11,0xBF, -0x00,0x00,0x11,0xCF,0x00,0x00,0x11,0xE3,0x00,0x00,0x11,0xF4,0x00,0x00,0x11,0xFF, -0x00,0x00,0x12,0x0B,0x00,0x00,0x12,0x26,0x00,0x00,0x12,0x36,0x00,0x00,0x7A,0x63, -0x00,0x00,0x7A,0x79,0x00,0x00,0x7A,0x8E,0x00,0x00,0x7A,0xA3,0x0A,0x45,0x52,0x52, -0x4F,0x52,0x20,0x31,0x2D,0x30,0x33,0x3A,0x20,0x55,0x4E,0x45,0x58,0x50,0x45,0x43, -0x54,0x45,0x44,0x20,0x46,0x41,0x55,0x4C,0x54,0x0A,0x00,0x20,0x20,0x20,0x20,0x20, -0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x45,0x58,0x45,0x43,0x55,0x54,0x49,0x4F,0x4E, -0x20,0x48,0x41,0x4C,0x54,0x45,0x44,0x0A,0x00,0x69,0x6E,0x74,0x65,0x67,0x65,0x72, -0x20,0x7A,0x65,0x72,0x6F,0x64,0x69,0x76,0x69,0x64,0x65,0x00,0x74,0x72,0x61,0x63, -0x65,0x20,0x74,0x72,0x61,0x70,0x00,0x69,0x6C,0x6C,0x65,0x67,0x61,0x6C,0x20,0x6F, -0x70,0x63,0x6F,0x64,0x65,0x00,0x72,0x65,0x73,0x65,0x72,0x76,0x65,0x64,0x20,0x6F, -0x70,0x63,0x6F,0x64,0x65,0x00,0x69,0x6E,0x76,0x61,0x6C,0x69,0x64,0x20,0x64,0x65, -0x73,0x63,0x72,0x69,0x70,0x74,0x6F,0x72,0x00,0x45,0x78,0x74,0x65,0x72,0x6E,0x61, -0x6C,0x20,0x6D,0x65,0x6D,0x6F,0x72,0x79,0x20,0x66,0x61,0x75,0x6C,0x74,0x00,0x67, -0x61,0x74,0x65,0x20,0x76,0x65,0x63,0x74,0x6F,0x72,0x20,0x7C,0x7C,0x20,0x52,0x45, -0x54,0x47,0x20,0x70,0x72,0x69,0x20,0x6C,0x65,0x76,0x65,0x6C,0x00,0x69,0x6C,0x6C, -0x65,0x67,0x61,0x6C,0x20,0x6C,0x65,0x76,0x65,0x6C,0x20,0x63,0x68,0x61,0x6E,0x67, -0x65,0x00,0x72,0x65,0x73,0x65,0x72,0x76,0x65,0x64,0x20,0x64,0x61,0x74,0x61,0x20, -0x74,0x79,0x70,0x65,0x00,0x6F,0x76,0x65,0x72,0x66,0x6C,0x6F,0x77,0x20,0x65,0x78, -0x63,0x65,0x70,0x74,0x69,0x6F,0x6E,0x00,0x70,0x72,0x69,0x76,0x65,0x6C,0x65,0x67, -0x65,0x64,0x20,0x6F,0x70,0x63,0x6F,0x64,0x65,0x00,0x75,0x6E,0x75,0x73,0x65,0x64, -0x00,0x75,0x6E,0x75,0x73,0x65,0x64,0x00,0x75,0x6E,0x75,0x73,0x65,0x64,0x00,0x62, -0x72,0x65,0x61,0x6B,0x70,0x6F,0x69,0x6E,0x74,0x20,0x74,0x72,0x61,0x70,0x00,0x70, -0x72,0x69,0x76,0x65,0x6C,0x65,0x67,0x65,0x64,0x20,0x72,0x65,0x67,0x69,0x73,0x74, -0x65,0x72,0x00,0x6E,0x6F,0x72,0x6D,0x61,0x6C,0x20,0x65,0x78,0x63,0x65,0x70,0x74, -0x69,0x6F,0x6E,0x00,0x73,0x74,0x72,0x61,0x79,0x20,0x67,0x61,0x74,0x65,0x00,0x73, -0x79,0x73,0x74,0x65,0x6D,0x20,0x63,0x61,0x6C,0x6C,0x00,0x70,0x72,0x6F,0x63,0x65, -0x73,0x73,0x20,0x6F,0x72,0x20,0x73,0x74,0x61,0x63,0x6B,0x20,0x65,0x78,0x63,0x65, -0x70,0x74,0x69,0x6F,0x6E,0x00,0x73,0x74,0x72,0x61,0x79,0x20,0x69,0x6E,0x74,0x65, -0x72,0x72,0x75,0x70,0x74,0x00,0x70,0x6F,0x77,0x65,0x72,0x20,0x66,0x61,0x69,0x6C, -0x00,0x52,0x65,0x73,0x65,0x74,0x00,0x50,0x72,0x6F,0x63,0x65,0x73,0x73,0x00,0x53, -0x74,0x61,0x63,0x6B,0x00,0x4E,0x6F,0x72,0x6D,0x61,0x6C,0x00,0x50,0x61,0x6E,0x69, -0x63,0x00,0x0A,0x25,0x73,0x20,0x65,0x78,0x63,0x65,0x70,0x74,0x69,0x6F,0x6E,0x20, -0x23,0x25,0x64,0x3A,0x20,0x22,0x25,0x73,0x22,0x20,0x61,0x74,0x20,0x61,0x64,0x64, -0x72,0x65,0x73,0x73,0x20,0x3D,0x20,0x30,0x78,0x25,0x6C,0x78,0x2C,0x20,0x70,0x73, -0x77,0x20,0x3D,0x20,0x30,0x78,0x25,0x6C,0x78,0x0A,0x00,0x00,0x6D,0x63,0x70,0x00, -0x2F,0x66,0x69,0x6C,0x6C,0x65,0x64,0x74,0x00,0x0A,0x53,0x59,0x53,0x54,0x45,0x4D, -0x20,0x46,0x41,0x49,0x4C,0x55,0x52,0x45,0x3A,0x20,0x43,0x4F,0x4E,0x53,0x55,0x4C, -0x54,0x20,0x59,0x4F,0x55,0x52,0x20,0x53,0x59,0x53,0x54,0x45,0x4D,0x20,0x41,0x44, -0x4D,0x49,0x4E,0x49,0x53,0x54,0x52,0x41,0x54,0x49,0x4F,0x4E,0x20,0x55,0x54,0x49, -0x4C,0x49,0x54,0x49,0x45,0x53,0x20,0x47,0x55,0x49,0x44,0x45,0x0A,0x0A,0x00,0x0A, -0x46,0x49,0x52,0x4D,0x57,0x41,0x52,0x45,0x20,0x4D,0x4F,0x44,0x45,0x0A,0x0A,0x00, -0x2F,0x66,0x69,0x6C,0x6C,0x65,0x64,0x74,0x00,0x2F,0x64,0x67,0x6D,0x6F,0x6E,0x00, -0x2F,0x75,0x6E,0x69,0x78,0x00,0x00,0x00,0x0A,0x46,0x57,0x20,0x45,0x52,0x52,0x4F, -0x52,0x20,0x31,0x2D,0x30,0x34,0x3A,0x20,0x55,0x4E,0x45,0x58,0x50,0x45,0x43,0x54, -0x45,0x44,0x20,0x49,0x4E,0x54,0x45,0x52,0x52,0x55,0x50,0x54,0x0A,0x00,0x20,0x20, -0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x45,0x58,0x45, -0x43,0x55,0x54,0x49,0x4F,0x4E,0x20,0x48,0x41,0x4C,0x54,0x45,0x44,0x0A,0x00,0x0A, -0x46,0x57,0x20,0x45,0x52,0x52,0x4F,0x52,0x20,0x31,0x2D,0x30,0x33,0x3A,0x20,0x55, -0x4E,0x45,0x58,0x50,0x45,0x43,0x54,0x45,0x44,0x20,0x46,0x41,0x55,0x4C,0x54,0x0A, -0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, -0x45,0x58,0x45,0x43,0x55,0x54,0x49,0x4F,0x4E,0x20,0x48,0x41,0x4C,0x54,0x45,0x44, -0x0A,0x00,0x00,0x00,0x18,0xF2,0x00,0x03,0x11,0x0D,0x00,0x80,0x69,0x64,0x25,0x64, -0x20,0x43,0x52,0x43,0x20,0x65,0x72,0x72,0x6F,0x72,0x20,0x61,0x74,0x20,0x64,0x69, -0x73,0x6B,0x20,0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x20,0x25,0x30,0x38,0x78,0x20, -0x28,0x25,0x64,0x20,0x72,0x65,0x74,0x72,0x69,0x65,0x73,0x29,0x0A,0x00,0x00,0x00, -0x69,0x66,0x20,0x43,0x52,0x43,0x20,0x65,0x72,0x72,0x6F,0x72,0x20,0x61,0x74,0x20, -0x64,0x69,0x73,0x6B,0x20,0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x20,0x25,0x30,0x38, -0x78,0x20,0x28,0x25,0x64,0x20,0x72,0x65,0x74,0x72,0x69,0x65,0x73,0x29,0x0A,0x00, -0x30,0x31,0x2F,0x32,0x31,0x2F,0x38,0x36,0x00,0x00,0x00,0x00,0x31,0x53,0x34,0x2E, -0x33,0x00,0x00,0x00,0x31,0x2E,0x31,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x17,0x9C, -0x00,0x00,0x17,0xA3,0x00,0x00,0x17,0xAA,0x00,0x00,0x17,0xB1,0x00,0x00,0x17,0xB8, -0x00,0x00,0x17,0xBF,0x00,0x00,0x17,0xC6,0x00,0x00,0x17,0xCD,0x00,0x00,0x17,0xD4, -0x00,0x00,0x17,0xDB,0x00,0x00,0x17,0xE2,0x00,0x00,0x17,0xE9,0x00,0x00,0x17,0xF0, -0x00,0x00,0x17,0xF7,0x00,0x00,0x17,0xFE,0x00,0x00,0x18,0x05,0x00,0x00,0x18,0x0C, -0x00,0x00,0x18,0x13,0x00,0x00,0x18,0x1A,0x00,0x00,0x18,0x21,0x00,0x00,0x00,0x00, -0x00,0x00,0x18,0x25,0x00,0x00,0x00,0x01,0x00,0x00,0x18,0x28,0x00,0x00,0x00,0x02, -0x00,0x00,0x18,0x2B,0x00,0x00,0x00,0x03,0x00,0x00,0x18,0x2F,0x00,0x00,0x00,0x04, -0x00,0x00,0x18,0x33,0x00,0x00,0x00,0x05,0x00,0x00,0x18,0x36,0x00,0x00,0x00,0x06, -0x00,0x00,0x18,0x39,0x00,0x00,0x00,0x07,0x00,0x00,0x18,0x3B,0x00,0x00,0x00,0x08, -0x00,0x00,0x18,0x3D,0x00,0x00,0x00,0x09,0x00,0x00,0x18,0x3F,0x00,0x00,0x00,0x0A, -0x00,0x00,0x18,0x41,0x00,0x00,0x00,0x0B,0x00,0x00,0x18,0x43,0x00,0x00,0x00,0x0C, -0x00,0x00,0x18,0x45,0x00,0x00,0x00,0x0D,0x00,0x00,0x18,0x47,0x00,0x00,0x00,0x0E, -0x00,0x00,0x18,0x49,0x00,0x00,0x00,0x0F,0x00,0x00,0x18,0x4B,0x00,0x00,0x00,0x10, -0x00,0x00,0x18,0x50,0x00,0x00,0x00,0x11,0x00,0x00,0x18,0x54,0xFF,0xFF,0xFF,0xFF, -0x00,0x00,0x18,0x55,0x00,0x00,0x00,0x01,0x00,0x00,0x18,0x58,0x00,0x00,0x00,0x02, -0x00,0x00,0x18,0x5B,0x00,0x00,0x00,0x03,0x00,0x00,0x18,0x5E,0x00,0x00,0x00,0x04, -0x00,0x00,0x18,0x61,0x00,0x00,0x00,0x05,0x00,0x00,0x18,0x64,0x00,0x00,0x00,0x22, -0x00,0x00,0x18,0x66,0x00,0x00,0x00,0x22,0x00,0x00,0x18,0x6B,0x00,0x00,0x00,0x06, -0x00,0x00,0x18,0x6E,0x00,0x00,0x00,0x07,0x00,0x00,0x18,0x71,0x00,0x00,0x00,0x08, -0x00,0x00,0x18,0x74,0x00,0x00,0x00,0x09,0x00,0x00,0x18,0x77,0x00,0x00,0x00,0x09, -0x00,0x00,0x18,0x7C,0x00,0x00,0x00,0x0A,0x00,0x00,0x18,0x81,0x00,0x00,0x00,0x0A, -0x00,0x00,0x18,0x83,0x00,0x00,0x00,0x0B,0x00,0x00,0x18,0x88,0x00,0x00,0x00,0x0B, -0x00,0x00,0x18,0x8B,0x00,0x00,0x00,0x23,0x00,0x00,0x18,0x8D,0x00,0x00,0x00,0x23, -0x00,0x00,0x18,0x90,0x00,0x00,0x00,0x24,0x00,0x00,0x18,0x92,0x00,0x00,0x00,0x24, -0x00,0x00,0x18,0x98,0x00,0x00,0x00,0x25,0x00,0x00,0x18,0x9B,0x00,0x00,0x00,0x25, -0x00,0x00,0x18,0xA2,0x00,0x00,0x00,0x26,0x00,0x00,0x18,0xA4,0x00,0x00,0x00,0x26, -0x00,0x00,0x18,0xAB,0x00,0x00,0x00,0x27,0x00,0x00,0x18,0xAE,0x00,0x00,0x00,0x27, -0x00,0x00,0x18,0xB6,0x00,0x00,0x00,0x28,0x00,0x00,0x18,0xB9,0x00,0x00,0x00,0x29, -0x00,0x00,0x18,0xBC,0x00,0x00,0x00,0x2A,0x00,0x00,0x18,0xC4,0x00,0x00,0x00,0x2B, -0x00,0x00,0x18,0xCB,0x00,0x00,0x00,0x21,0x00,0x00,0x18,0xCD,0x00,0x00,0x00,0x21, -0x00,0x00,0x18,0xD2,0x00,0x00,0x00,0x2C,0x00,0x00,0x18,0xD4,0x00,0x00,0x00,0x2D, -0x00,0x00,0x18,0xD7,0x00,0x00,0x00,0x2E,0x00,0x00,0x18,0xDC,0x00,0x00,0x00,0x2E, -0x00,0x00,0x18,0xDF,0x00,0x00,0x00,0x20,0x00,0x00,0x18,0xE3,0x00,0x00,0x00,0x31, -0x00,0x00,0x18,0xE9,0x00,0x00,0x00,0x1E,0x00,0x00,0x18,0xEB,0x00,0x00,0x00,0x0C, -0x00,0x00,0x18,0xEE,0x00,0x00,0x00,0x0D,0x00,0x00,0x18,0xF1,0x00,0x00,0x00,0x0E, -0x00,0x00,0x18,0xF4,0x00,0x00,0x00,0x0F,0x00,0x00,0x18,0xF7,0x00,0x00,0x00,0x10, -0x00,0x00,0x18,0xFA,0x00,0x00,0x00,0x11,0x00,0x00,0x18,0xFD,0x00,0x00,0x00,0x12, -0x00,0x00,0x19,0x00,0x00,0x00,0x00,0x13,0x00,0x00,0x19,0x03,0x00,0x00,0x00,0x14, -0x00,0x00,0x19,0x06,0x00,0x00,0x00,0x15,0x00,0x00,0x19,0x09,0x00,0x00,0x00,0x16, -0x00,0x00,0x19,0x0C,0x00,0x00,0x00,0x17,0x00,0x00,0x19,0x10,0x00,0x00,0x00,0x18, -0x00,0x00,0x19,0x13,0x00,0x00,0x00,0x19,0x00,0x00,0x19,0x18,0x00,0x00,0x00,0x1A, -0x00,0x00,0x19,0x1C,0x00,0x00,0x00,0x1B,0x00,0x00,0x19,0x1F,0x00,0x00,0x00,0x1C, -0x00,0x00,0x19,0x23,0x00,0x00,0x00,0x1D,0x00,0x00,0x19,0x27,0x00,0x00,0x00,0x2F, -0x00,0x00,0x19,0x2C,0x00,0x00,0x00,0x30,0x00,0x00,0x19,0x32,0x00,0x00,0x00,0x2F, -0x00,0x00,0x19,0x35,0x00,0x00,0x00,0x30,0x00,0x00,0x19,0x39,0x00,0x00,0x00,0x00, -0x00,0x00,0x19,0x3B,0x00,0x00,0x00,0x1F,0x00,0x00,0x19,0x3E,0x00,0x00,0x00,0x33, -0x00,0x00,0x19,0x43,0x00,0x00,0x00,0x34,0x00,0x00,0x19,0x4A,0x00,0x00,0x00,0x35, -0x00,0x00,0x19,0x4F,0x00,0x00,0x00,0x36,0x00,0x00,0x19,0x54,0x00,0x00,0x00,0x32, -0x00,0x00,0x19,0x59,0x00,0x00,0x00,0x3D,0x00,0x00,0x19,0x5F,0x00,0x00,0x00,0x3F, -0x00,0x00,0x19,0x67,0x00,0x00,0x00,0x3E,0x00,0x00,0x19,0x6E,0x00,0x00,0x00,0x37, -0x00,0x00,0x19,0x74,0x00,0x00,0x00,0x38,0x00,0x00,0x19,0x7A,0x00,0x00,0x00,0x39, -0x00,0x00,0x19,0x80,0x00,0x00,0x00,0x3C,0x00,0x00,0x19,0x84,0x00,0x00,0x00,0x3B, -0x00,0x00,0x19,0x89,0x00,0x00,0x00,0x3B,0x00,0x00,0x19,0x8B,0x00,0x00,0x00,0x3A, -0x00,0x00,0x19,0x90,0x00,0x00,0x00,0x3A,0x00,0x00,0x19,0x92,0x00,0x00,0x00,0x40, -0x00,0x00,0x19,0x95,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x50,0x50,0x53,0x57,0x20, -0x3D,0x20,0x00,0x20,0x50,0x43,0x20,0x3D,0x20,0x00,0x20,0x53,0x50,0x20,0x3D,0x20, -0x00,0x53,0x4C,0x42,0x20,0x3D,0x20,0x00,0x53,0x55,0x42,0x20,0x3D,0x20,0x00,0x20, -0x41,0x50,0x20,0x3D,0x20,0x00,0x20,0x46,0x50,0x20,0x3D,0x20,0x00,0x20,0x72,0x30, -0x20,0x3D,0x20,0x00,0x20,0x72,0x31,0x20,0x3D,0x20,0x00,0x20,0x72,0x32,0x20,0x3D, -0x20,0x00,0x20,0x72,0x33,0x20,0x3D,0x20,0x00,0x20,0x72,0x34,0x20,0x3D,0x20,0x00, -0x20,0x72,0x35,0x20,0x3D,0x20,0x00,0x20,0x72,0x36,0x20,0x3D,0x20,0x00,0x20,0x72, -0x37,0x20,0x3D,0x20,0x00,0x20,0x72,0x38,0x20,0x3D,0x20,0x00,0x4D,0x4F,0x56,0x42, -0x57,0x3D,0x00,0x50,0x43,0x42,0x50,0x3D,0x20,0x00,0x49,0x53,0x50,0x20,0x3D,0x20, -0x00,0x50,0x53,0x57,0x00,0x50,0x43,0x00,0x53,0x50,0x00,0x53,0x4C,0x42,0x00,0x53, -0x55,0x42,0x00,0x41,0x50,0x00,0x46,0x50,0x00,0x30,0x00,0x31,0x00,0x32,0x00,0x33, -0x00,0x34,0x00,0x35,0x00,0x36,0x00,0x37,0x00,0x38,0x00,0x50,0x43,0x42,0x50,0x00, -0x49,0x53,0x50,0x00,0x00,0x44,0x42,0x00,0x44,0x48,0x00,0x44,0x57,0x00,0x44,0x44, -0x00,0x44,0x4D,0x00,0x43,0x00,0x43,0x41,0x4C,0x4C,0x00,0x53,0x4D,0x00,0x53,0x48, -0x00,0x53,0x57,0x00,0x46,0x4D,0x00,0x46,0x49,0x4C,0x4C,0x00,0x4E,0x45,0x58,0x54, -0x00,0x4E,0x00,0x43,0x4F,0x50,0x59,0x00,0x43,0x50,0x00,0x47,0x00,0x47,0x4F,0x00, -0x54,0x00,0x54,0x52,0x41,0x43,0x45,0x00,0x53,0x54,0x00,0x53,0x54,0x52,0x41,0x43, -0x45,0x00,0x46,0x00,0x46,0x54,0x52,0x41,0x43,0x45,0x00,0x53,0x46,0x00,0x53,0x46, -0x54,0x52,0x41,0x43,0x45,0x00,0x42,0x52,0x00,0x52,0x4D,0x00,0x44,0x49,0x53,0x41, -0x42,0x4C,0x45,0x00,0x45,0x4E,0x41,0x42,0x4C,0x45,0x00,0x51,0x00,0x51,0x55,0x41, -0x4C,0x00,0x55,0x00,0x44,0x4C,0x00,0x52,0x45,0x41,0x44,0x00,0x52,0x45,0x00,0x4F, -0x4C,0x44,0x00,0x52,0x45,0x53,0x45,0x54,0x00,0x52,0x00,0x52,0x30,0x00,0x52,0x31, -0x00,0x52,0x32,0x00,0x52,0x33,0x00,0x52,0x34,0x00,0x52,0x35,0x00,0x52,0x36,0x00, -0x52,0x37,0x00,0x52,0x38,0x00,0x46,0x50,0x00,0x41,0x50,0x00,0x50,0x53,0x57,0x00, -0x53,0x50,0x00,0x50,0x43,0x42,0x50,0x00,0x49,0x53,0x50,0x00,0x50,0x43,0x00,0x53, -0x4C,0x42,0x00,0x53,0x55,0x42,0x00,0x42,0x41,0x55,0x44,0x00,0x42,0x41,0x55,0x44, -0x48,0x00,0x42,0x44,0x00,0x42,0x44,0x48,0x00,0x3F,0x00,0x54,0x44,0x00,0x42,0x4F, -0x4F,0x54,0x00,0x42,0x55,0x47,0x4F,0x55,0x54,0x00,0x43,0x49,0x53,0x43,0x00,0x4C, -0x49,0x53,0x43,0x00,0x49,0x4E,0x46,0x4F,0x00,0x49,0x44,0x45,0x4E,0x54,0x00,0x55, -0x4E,0x49,0x44,0x45,0x4E,0x54,0x00,0x53,0x57,0x49,0x54,0x43,0x48,0x00,0x53,0x52, -0x41,0x4D,0x41,0x00,0x53,0x52,0x41,0x4D,0x42,0x00,0x46,0x4C,0x55,0x53,0x48,0x00, -0x4D,0x41,0x50,0x00,0x56,0x49,0x52,0x54,0x00,0x56,0x00,0x50,0x48,0x59,0x53,0x00, -0x50,0x00,0x44,0x53,0x00,0x00,0x00,0x00,0x0A,0x49,0x4E,0x54,0x45,0x52,0x52,0x55, -0x50,0x54,0x20,0x21,0x21,0x20,0x20,0x50,0x43,0x20,0x3D,0x20,0x30,0x78,0x25,0x78, -0x2C,0x20,0x50,0x53,0x57,0x20,0x3D,0x20,0x30,0x78,0x25,0x78,0x0A,0x00,0x00,0x00, -0x07,0x50,0x41,0x4E,0x49,0x43,0x21,0x20,0x42,0x61,0x64,0x20,0x61,0x72,0x67,0x75, -0x6D,0x65,0x6E,0x74,0x20,0x74,0x6F,0x20,0x78,0x73,0x77,0x69,0x74,0x63,0x68,0x20, -0x69,0x73,0x20,0x27,0x25,0x78,0x27,0x0A,0x00,0x00,0x00,0x00,0x55,0x73,0x65,0x72, -0x20,0x65,0x78,0x65,0x63,0x75,0x74,0x69,0x6F,0x6E,0x20,0x63,0x6F,0x6D,0x70,0x6C, -0x65,0x74,0x65,0x0A,0x00,0x47,0x6F,0x20,0x74,0x69,0x6C,0x6C,0x20,0x61,0x64,0x64, -0x72,0x65,0x73,0x73,0x20,0x68,0x69,0x74,0x0A,0x00,0x44,0x45,0x4D,0x4F,0x4E,0x20, -0x43,0x61,0x6C,0x6C,0x2E,0x20,0x55,0x73,0x65,0x20,0x22,0x67,0x6F,0x22,0x20,0x74, -0x6F,0x20,0x63,0x6F,0x6E,0x74,0x69,0x6E,0x75,0x65,0x0A,0x00,0x42,0x72,0x65,0x61, -0x6B,0x70,0x6F,0x69,0x6E,0x74,0x73,0x20,0x3D,0x0A,0x00,0x20,0x2D,0x20,0x00,0x20, -0x20,0x20,0x00,0x23,0x25,0x64,0x20,0x61,0x74,0x3A,0x20,0x25,0x38,0x78,0x20,0x28, -0x25,0x38,0x78,0x29,0x20,0x00,0x20,0x63,0x6F,0x75,0x6E,0x74,0x3A,0x20,0x25,0x68, -0x64,0x2F,0x25,0x68,0x64,0x20,0x68,0x69,0x74,0x73,0x3A,0x25,0x64,0x20,0x20,0x20, -0x63,0x6F,0x64,0x65,0x3A,0x20,0x25,0x30,0x32,0x78,0x20,0x20,0x63,0x6D,0x64,0x3A, -0x20,0x25,0x73,0x0A,0x00,0x41,0x4C,0x4C,0x00,0x41,0x4C,0x4C,0x00,0x41,0x4C,0x4C, -0x00,0x43,0x6F,0x64,0x65,0x20,0x63,0x6F,0x6E,0x66,0x6C,0x69,0x63,0x74,0x2C,0x20, -0x72,0x65,0x6D,0x6F,0x76,0x69,0x6E,0x67,0x20,0x62,0x72,0x65,0x61,0x6B,0x70,0x6F, -0x69,0x6E,0x74,0x20,0x23,0x25,0x64,0x0A,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xC1, -0xC1,0x81,0x01,0x40,0xC3,0x01,0x03,0xC0,0x02,0x80,0xC2,0x41,0xC6,0x01,0x06,0xC0, -0x07,0x80,0xC7,0x41,0x05,0x00,0xC5,0xC1,0xC4,0x81,0x04,0x40,0xCC,0x01,0x0C,0xC0, -0x0D,0x80,0xCD,0x41,0x0F,0x00,0xCF,0xC1,0xCE,0x81,0x0E,0x40,0x0A,0x00,0xCA,0xC1, -0xCB,0x81,0x0B,0x40,0xC9,0x01,0x09,0xC0,0x08,0x80,0xC8,0x41,0xD8,0x01,0x18,0xC0, -0x19,0x80,0xD9,0x41,0x1B,0x00,0xDB,0xC1,0xDA,0x81,0x1A,0x40,0x1E,0x00,0xDE,0xC1, -0xDF,0x81,0x1F,0x40,0xDD,0x01,0x1D,0xC0,0x1C,0x80,0xDC,0x41,0x14,0x00,0xD4,0xC1, -0xD5,0x81,0x15,0x40,0xD7,0x01,0x17,0xC0,0x16,0x80,0xD6,0x41,0xD2,0x01,0x12,0xC0, -0x13,0x80,0xD3,0x41,0x11,0x00,0xD1,0xC1,0xD0,0x81,0x10,0x40,0xF0,0x01,0x30,0xC0, -0x31,0x80,0xF1,0x41,0x33,0x00,0xF3,0xC1,0xF2,0x81,0x32,0x40,0x36,0x00,0xF6,0xC1, -0xF7,0x81,0x37,0x40,0xF5,0x01,0x35,0xC0,0x34,0x80,0xF4,0x41,0x3C,0x00,0xFC,0xC1, -0xFD,0x81,0x3D,0x40,0xFF,0x01,0x3F,0xC0,0x3E,0x80,0xFE,0x41,0xFA,0x01,0x3A,0xC0, -0x3B,0x80,0xFB,0x41,0x39,0x00,0xF9,0xC1,0xF8,0x81,0x38,0x40,0x28,0x00,0xE8,0xC1, -0xE9,0x81,0x29,0x40,0xEB,0x01,0x2B,0xC0,0x2A,0x80,0xEA,0x41,0xEE,0x01,0x2E,0xC0, -0x2F,0x80,0xEF,0x41,0x2D,0x00,0xED,0xC1,0xEC,0x81,0x2C,0x40,0xE4,0x01,0x24,0xC0, -0x25,0x80,0xE5,0x41,0x27,0x00,0xE7,0xC1,0xE6,0x81,0x26,0x40,0x22,0x00,0xE2,0xC1, -0xE3,0x81,0x23,0x40,0xE1,0x01,0x21,0xC0,0x20,0x80,0xE0,0x41,0xA0,0x01,0x60,0xC0, -0x61,0x80,0xA1,0x41,0x63,0x00,0xA3,0xC1,0xA2,0x81,0x62,0x40,0x66,0x00,0xA6,0xC1, -0xA7,0x81,0x67,0x40,0xA5,0x01,0x65,0xC0,0x64,0x80,0xA4,0x41,0x6C,0x00,0xAC,0xC1, -0xAD,0x81,0x6D,0x40,0xAF,0x01,0x6F,0xC0,0x6E,0x80,0xAE,0x41,0xAA,0x01,0x6A,0xC0, -0x6B,0x80,0xAB,0x41,0x69,0x00,0xA9,0xC1,0xA8,0x81,0x68,0x40,0x78,0x00,0xB8,0xC1, -0xB9,0x81,0x79,0x40,0xBB,0x01,0x7B,0xC0,0x7A,0x80,0xBA,0x41,0xBE,0x01,0x7E,0xC0, -0x7F,0x80,0xBF,0x41,0x7D,0x00,0xBD,0xC1,0xBC,0x81,0x7C,0x40,0xB4,0x01,0x74,0xC0, -0x75,0x80,0xB5,0x41,0x77,0x00,0xB7,0xC1,0xB6,0x81,0x76,0x40,0x72,0x00,0xB2,0xC1, -0xB3,0x81,0x73,0x40,0xB1,0x01,0x71,0xC0,0x70,0x80,0xB0,0x41,0x50,0x00,0x90,0xC1, -0x91,0x81,0x51,0x40,0x93,0x01,0x53,0xC0,0x52,0x80,0x92,0x41,0x96,0x01,0x56,0xC0, -0x57,0x80,0x97,0x41,0x55,0x00,0x95,0xC1,0x94,0x81,0x54,0x40,0x9C,0x01,0x5C,0xC0, -0x5D,0x80,0x9D,0x41,0x5F,0x00,0x9F,0xC1,0x9E,0x81,0x5E,0x40,0x5A,0x00,0x9A,0xC1, -0x9B,0x81,0x5B,0x40,0x99,0x01,0x59,0xC0,0x58,0x80,0x98,0x41,0x88,0x01,0x48,0xC0, -0x49,0x80,0x89,0x41,0x4B,0x00,0x8B,0xC1,0x8A,0x81,0x4A,0x40,0x4E,0x00,0x8E,0xC1, -0x8F,0x81,0x4F,0x40,0x8D,0x01,0x4D,0xC0,0x4C,0x80,0x8C,0x41,0x44,0x00,0x84,0xC1, -0x85,0x81,0x45,0x40,0x87,0x01,0x47,0xC0,0x46,0x80,0x86,0x41,0x82,0x01,0x42,0xC0, -0x43,0x80,0x83,0x41,0x41,0x00,0x81,0xC1,0x80,0x81,0x40,0x40,0x00,0x00,0xAB,0x6F, -0x00,0x00,0xAB,0x92,0x00,0x00,0xAB,0x08,0x00,0x00,0xAB,0x92,0x00,0x00,0xAB,0x92, -0x00,0x00,0xAB,0x30,0x00,0x00,0xAB,0x60,0x2F,0x75,0x73,0x72,0x2F,0x6C,0x75,0x62, -0x69,0x6E,0x2F,0x44,0x45,0x4D,0x4F,0x4E,0x5F,0x53,0x45,0x43,0x54,0x00,0x2F,0x75, -0x73,0x72,0x2F,0x6C,0x75,0x62,0x69,0x6E,0x2F,0x44,0x45,0x4D,0x4F,0x4E,0x5F,0x43, -0x41,0x54,0x00,0x20,0x00,0x2F,0x75,0x73,0x72,0x2F,0x6C,0x75,0x62,0x69,0x6E,0x2F, -0x44,0x45,0x4D,0x4F,0x4E,0x5F,0x47,0x45,0x54,0x00,0x20,0x00,0x20,0x50,0x00,0x20, -0x00,0x0A,0x00,0x0A,0x27,0x64,0x6C,0x27,0x20,0x6E,0x6F,0x74,0x20,0x63,0x6F,0x6D, -0x70,0x61,0x74,0x69,0x62,0x6C,0x65,0x20,0x77,0x69,0x74,0x68,0x20,0x27,0x6C,0x69, -0x73,0x63,0x27,0x0A,0x00,0x2D,0x50,0x00,0x2D,0x53,0x00,0x44,0x6F,0x77,0x6E,0x6C, -0x6F,0x61,0x64,0x69,0x6E,0x67,0x20,0x25,0x73,0x00,0x0A,0x00,0x25,0x64,0x20,0x69, -0x73,0x20,0x61,0x6E,0x20,0x69,0x6E,0x76,0x61,0x6C,0x69,0x64,0x20,0x73,0x65,0x63, -0x74,0x69,0x6F,0x6E,0x20,0x6E,0x75,0x6D,0x62,0x65,0x72,0x20,0x66,0x6F,0x72,0x20, -0x25,0x73,0x0A,0x00,0x20,0x20,0x53,0x65,0x63,0x74,0x20,0x25,0x68,0x64,0x2C,0x20, -0x6F,0x72,0x69,0x67,0x69,0x6E,0x20,0x25,0x38,0x78,0x00,0x20,0x28,0x25,0x38,0x78, -0x29,0x20,0x25,0x73,0x20,0x3A,0x00,0x20,0x63,0x6F,0x75,0x6C,0x64,0x20,0x6E,0x6F, -0x74,0x20,0x62,0x65,0x20,0x6C,0x6F,0x61,0x64,0x65,0x64,0x0A,0x00,0x20,0x20,0x20, -0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x25,0x78,0x20,0x62,0x79,0x74,0x65,0x73,0x20, -0x72,0x65,0x61,0x64,0x2C,0x20,0x65,0x78,0x70,0x65,0x63,0x74,0x69,0x6E,0x67,0x20, -0x25,0x78,0x0A,0x00,0x3A,0x20,0x25,0x78,0x20,0x62,0x79,0x74,0x65,0x73,0x20,0x72, -0x65,0x61,0x64,0x2E,0x0A,0x00,0x20,0x65,0x6D,0x70,0x74,0x79,0x20,0x73,0x65,0x63, -0x74,0x69,0x6F,0x6E,0x0A,0x00,0x0A,0x27,0x72,0x65,0x27,0x20,0x6E,0x6F,0x74,0x20, -0x63,0x6F,0x6D,0x70,0x61,0x74,0x69,0x62,0x6C,0x65,0x20,0x77,0x69,0x74,0x68,0x20, -0x27,0x6C,0x69,0x73,0x63,0x27,0x0A,0x00,0x2D,0x53,0x00,0x52,0x65,0x61,0x64,0x69, -0x6E,0x67,0x20,0x25,0x73,0x20,0x74,0x6F,0x20,0x25,0x78,0x20,0x28,0x25,0x78,0x29, -0x20,0x3A,0x00,0x25,0x64,0x20,0x20,0x62,0x79,0x74,0x65,0x73,0x20,0x72,0x65,0x61, -0x64,0x2E,0x0A,0x00,0x0A,0x27,0x75,0x27,0x20,0x6E,0x6F,0x74,0x20,0x63,0x6F,0x6D, -0x70,0x61,0x74,0x69,0x62,0x6C,0x65,0x20,0x77,0x69,0x74,0x68,0x20,0x27,0x6C,0x69, -0x73,0x63,0x27,0x0A,0x00,0x0A,0x54,0x72,0x61,0x6E,0x73,0x70,0x61,0x72,0x65,0x6E, -0x74,0x20,0x4D,0x6F,0x64,0x65,0x20,0x2D,0x20,0x75,0x73,0x65,0x20,0x27,0x5E,0x41, -0x27,0x20,0x74,0x6F,0x20,0x65,0x78,0x69,0x74,0x0A,0x00,0x57,0x61,0x72,0x6E,0x69, -0x6E,0x67,0x3A,0x20,0x42,0x6F,0x74,0x68,0x20,0x42,0x72,0x65,0x61,0x6B,0x20,0x61, -0x6E,0x64,0x20,0x44,0x65,0x6C,0x65,0x74,0x65,0x20,0x73,0x65,0x6E,0x64,0x20,0x62, -0x72,0x65,0x61,0x6B,0x0A,0x00,0x0A,0x00,0x2E,0x00,0x00,0x00,0x00,0x00,0xB2,0x07, -0x00,0x00,0xB2,0x3E,0x00,0x00,0xB1,0xEB,0x00,0x00,0xB2,0x3E,0x00,0x00,0xB2,0x07, -0x00,0x00,0xB2,0x3E,0x00,0x00,0xB1,0xEB,0x00,0x00,0xB2,0x3E,0x00,0x00,0xB2,0x07, -0x00,0x00,0xB2,0x3E,0x00,0x00,0xB1,0xEB,0x00,0x00,0xB2,0x3E,0x00,0x00,0xB2,0x07, -0x00,0x00,0xB2,0x3E,0x00,0x00,0xB1,0xEB,0x00,0x00,0xB2,0xED,0x00,0x00,0xB3,0x6B, -0x00,0x00,0xB3,0xEA,0x00,0x00,0xB4,0x65,0x00,0x00,0xB2,0xC0,0x00,0x00,0xB4,0xFF, -0x00,0x00,0xB5,0x1D,0x00,0x00,0xB5,0x55,0x00,0x00,0xB5,0x12,0x2D,0x4E,0x00,0x2D, -0x4E,0x00,0x2D,0x4E,0x00,0x2D,0x4E,0x00,0x25,0x38,0x78,0x3A,0x20,0x00,0x25,0x30, -0x32,0x78,0x00,0x20,0x00,0x20,0x00,0x20,0x20,0x00,0x0A,0x00,0x25,0x38,0x78,0x3A, -0x20,0x25,0x30,0x32,0x78,0x20,0x20,0x27,0x00,0x27,0x0A,0x00,0x25,0x38,0x78,0x3A, -0x20,0x25,0x30,0x34,0x78,0x20,0x20,0x27,0x00,0x27,0x0A,0x00,0x25,0x38,0x78,0x3A, -0x20,0x25,0x30,0x38,0x78,0x20,0x20,0x27,0x00,0x27,0x0A,0x00,0x25,0x38,0x78,0x3A, -0x20,0x25,0x30,0x38,0x78,0x20,0x25,0x30,0x38,0x78,0x20,0x20,0x27,0x00,0x27,0x0A, -0x00,0x2D,0x46,0x00,0x25,0x2D,0x37,0x73,0x20,0x25,0x73,0x00,0x20,0x20,0x00,0x0A, -0x00,0x0A,0x00,0x56,0x69,0x72,0x74,0x75,0x61,0x6C,0x20,0x4D,0x6F,0x64,0x65,0x00, -0x50,0x68,0x79,0x73,0x69,0x63,0x61,0x6C,0x20,0x4D,0x6F,0x64,0x65,0x00,0x3A,0x20, -0x53,0x74,0x6F,0x70,0x70,0x65,0x64,0x20,0x61,0x74,0x20,0x74,0x69,0x6C,0x6C,0x20, -0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x0A,0x00,0x3A,0x20,0x53,0x74,0x6F,0x70,0x70, -0x65,0x64,0x20,0x61,0x74,0x20,0x62,0x72,0x65,0x61,0x6B,0x70,0x6F,0x69,0x6E,0x74, -0x20,0x23,0x25,0x64,0x20,0x2D,0x20,0x25,0x6C,0x78,0x20,0x20,0x00,0x0A,0x00,0x0A, -0x00,0x43,0x75,0x72,0x72,0x65,0x6E,0x74,0x20,0x70,0x72,0x6F,0x63,0x65,0x73,0x73, -0x65,0x73,0x3A,0x0A,0x00,0x70,0x69,0x64,0x3A,0x20,0x25,0x2D,0x36,0x64,0x20,0x70, -0x63,0x62,0x70,0x3A,0x20,0x25,0x2D,0x38,0x78,0x00,0x0A,0x20,0x20,0x20,0x20,0x20, -0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x72,0x61,0x6D,0x61,0x20,0x00,0x25, -0x64,0x3A,0x20,0x25,0x2D,0x38,0x78,0x20,0x20,0x20,0x00,0x0A,0x20,0x20,0x20,0x20, -0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x72,0x61,0x6D,0x62,0x20,0x00, -0x25,0x64,0x3A,0x20,0x25,0x2D,0x38,0x78,0x20,0x20,0x20,0x00,0x0A,0x00,0x43,0x75, -0x72,0x72,0x65,0x6E,0x74,0x20,0x70,0x72,0x6F,0x63,0x65,0x73,0x73,0x20,0x69,0x73, -0x20,0x70,0x69,0x64,0x3A,0x25,0x64,0x0A,0x00,0x53,0x77,0x69,0x74,0x63,0x68,0x69, -0x6E,0x67,0x20,0x74,0x6F,0x20,0x70,0x72,0x6F,0x63,0x65,0x73,0x73,0x20,0x25,0x64, -0x0A,0x00,0x41,0x4C,0x4C,0x00,0x00,0x00,0x00,0x00,0x22,0xC4,0x00,0x00,0x22,0xC6, -0x00,0x00,0x22,0xE3,0x00,0x00,0x22,0xF5,0x00,0x00,0x23,0x0A,0x00,0x00,0x23,0x13, -0x00,0x00,0x23,0x1C,0x00,0x00,0x23,0x2C,0x00,0x00,0x23,0x39,0x00,0x00,0x23,0x4D, -0x00,0x00,0x23,0x63,0x00,0x00,0x23,0x69,0x00,0x00,0x23,0x6F,0x00,0x00,0x23,0x75, -0x00,0x00,0x23,0x7B,0x00,0x00,0x23,0x81,0x00,0x00,0x23,0x87,0x00,0x00,0x23,0x8E, -0x00,0x00,0x23,0x96,0x00,0x00,0x23,0x9E,0x00,0x00,0x23,0xAB,0x00,0x00,0x23,0xB8, -0x00,0x00,0x23,0xC9,0x00,0x00,0x23,0xD8,0x00,0x00,0x23,0xE5,0x00,0x00,0x23,0xEF, -0x00,0x00,0x24,0x0F,0x00,0x00,0x24,0x2B,0x00,0x00,0x24,0x41,0x00,0x00,0x24,0x68, -0x00,0x00,0x24,0x76,0x00,0x00,0x24,0x87,0x00,0x00,0x24,0x95,0x00,0x00,0x24,0xA4, -0x00,0x00,0x24,0xC0,0x00,0x00,0x24,0xDB,0x00,0x00,0x24,0xEC,0x00,0x00,0x25,0x04, -0x00,0x00,0x25,0x19,0x00,0x00,0x25,0x2E,0x00,0x00,0x25,0x44,0x00,0x00,0x25,0x60, -0x00,0x00,0x25,0x74,0x00,0x00,0x25,0x92,0x00,0x00,0x25,0xB4,0x00,0x00,0x25,0xBE, -0x00,0x00,0x25,0xCD,0x00,0x00,0x25,0xF8,0x00,0x00,0x26,0x01,0x00,0x00,0x26,0x11, -0x00,0x00,0x26,0x1F,0x00,0x00,0x26,0x35,0x00,0x00,0x26,0x47,0x00,0x00,0x26,0x5B, -0x00,0x00,0x26,0x68,0x00,0x00,0x26,0x71,0x00,0x00,0x26,0x84,0x00,0x00,0x26,0x97, -0x00,0x00,0x26,0x98,0x00,0x00,0x26,0x9D,0x00,0x00,0x26,0xA0,0x00,0x00,0x26,0xA3, -0x00,0x00,0x26,0xA6,0x00,0x00,0x26,0xAB,0x00,0x00,0xBD,0xC3,0x00,0x00,0xBD,0xDD, -0x00,0x00,0xBD,0xF7,0x00,0x00,0xBE,0x04,0x00,0x00,0xBE,0x11,0x00,0x00,0xBE,0x1E, -0x00,0x00,0xBD,0xEA,0x00,0x00,0xBE,0x2B,0x00,0x00,0xBE,0x38,0x00,0x00,0xBE,0x45, -0x00,0x00,0xBE,0x52,0x00,0x00,0xBE,0x5F,0x00,0x00,0xBE,0x6C,0x00,0x00,0xBE,0x79, -0x00,0x00,0xBE,0x89,0x00,0x00,0xBE,0x99,0x00,0x00,0xBE,0xA9,0x00,0x00,0xBE,0xB9, -0x00,0x00,0xBE,0xC9,0x00,0x00,0xBE,0xD9,0x00,0x00,0xBE,0xE9,0x00,0x00,0xBE,0xF9, -0x00,0x00,0xBF,0x09,0x00,0x00,0xBF,0x19,0x00,0x00,0xBF,0x29,0x00,0x00,0xBF,0x39, -0x00,0x00,0xBF,0x49,0x00,0x00,0xBF,0x59,0x00,0x00,0xBF,0x69,0x00,0x00,0xBF,0x79, -0x00,0x00,0xBF,0x89,0x00,0x00,0xBF,0x99,0x00,0x00,0xBF,0xA6,0x00,0x00,0xBF,0xB3, -0x00,0x00,0xBF,0xC0,0x00,0x00,0xBF,0xCD,0x00,0x00,0xBF,0xDA,0x00,0x00,0xBF,0xE7, -0x00,0x00,0xC0,0x02,0x00,0x00,0xC0,0x1E,0x00,0x00,0xC0,0x3A,0x00,0x00,0xC0,0x57, -0x00,0x00,0xC0,0x64,0x00,0x00,0xC0,0x71,0x00,0x00,0xC0,0x7E,0x00,0x00,0xC0,0x8B, -0x00,0x00,0xC0,0x98,0x00,0x00,0xC0,0xA5,0x00,0x00,0xC0,0xB2,0x00,0x00,0xC0,0xC6, -0x00,0x00,0xC1,0x2E,0x00,0x00,0xC0,0xDA,0x00,0x00,0xC0,0xE7,0x00,0x00,0xC0,0xF4, -0x00,0x00,0xC1,0x0A,0x00,0x00,0xC1,0x1C,0x00,0x00,0xC1,0x59,0x00,0x00,0xC1,0x62, -0x00,0x00,0xC1,0x6B,0x00,0x00,0xC1,0x44,0x00,0x00,0xC1,0x38,0x00,0x00,0xC1,0x50, -0x00,0x00,0xC1,0x74,0x00,0x00,0xC1,0x86,0x00,0x00,0xC1,0x7D,0x00,0x00,0xC1,0x8F, -0x00,0x00,0xBD,0xCD,0x07,0x00,0x56,0x69,0x72,0x74,0x75,0x61,0x6C,0x20,0x74,0x72, -0x61,0x6E,0x73,0x6C,0x61,0x74,0x69,0x6F,0x6E,0x20,0x66,0x61,0x69,0x6C,0x65,0x64, -0x2D,0x2D,0x00,0x43,0x6F,0x6D,0x6D,0x61,0x6E,0x64,0x20,0x72,0x65,0x71,0x75,0x69, -0x72,0x65,0x73,0x20,0x00,0x56,0x61,0x6C,0x75,0x65,0x20,0x74,0x6F,0x6F,0x20,0x6C, -0x61,0x72,0x67,0x65,0x20,0x66,0x6F,0x72,0x20,0x00,0x4D,0x69,0x73,0x73,0x69,0x6E, -0x67,0x20,0x00,0x49,0x6C,0x6C,0x65,0x67,0x61,0x6C,0x20,0x00,0x50,0x45,0x45,0x4B, -0x20,0x75,0x73,0x65,0x20,0x65,0x72,0x72,0x6F,0x72,0x20,0x00,0x4E,0x6F,0x20,0x70, -0x72,0x65,0x76,0x69,0x6F,0x75,0x73,0x20,0x00,0x46,0x61,0x69,0x6C,0x65,0x64,0x20, -0x74,0x6F,0x20,0x74,0x72,0x61,0x6E,0x73,0x66,0x65,0x72,0x20,0x00,0x4E,0x6F,0x20, -0x73,0x70,0x61,0x63,0x65,0x20,0x66,0x6F,0x72,0x20,0x61,0x6E,0x6F,0x74,0x68,0x65, -0x72,0x20,0x00,0x45,0x31,0x5F,0x64,0x41,0x00,0x45,0x31,0x5F,0x64,0x42,0x00,0x45, -0x31,0x5F,0x64,0x43,0x00,0x45,0x31,0x5F,0x64,0x44,0x00,0x45,0x31,0x5F,0x64,0x45, -0x00,0x45,0x31,0x5F,0x64,0x46,0x00,0x50,0x41,0x4E,0x49,0x43,0x21,0x00,0x63,0x6F, -0x6D,0x6D,0x61,0x6E,0x64,0x00,0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x00,0x69,0x6E, -0x70,0x75,0x74,0x20,0x62,0x75,0x66,0x66,0x65,0x72,0x00,0x68,0x65,0x78,0x20,0x63, -0x6F,0x6E,0x73,0x74,0x61,0x6E,0x74,0x00,0x64,0x65,0x63,0x69,0x6D,0x61,0x6C,0x20, -0x63,0x6F,0x6E,0x73,0x74,0x61,0x6E,0x74,0x00,0x6D,0x65,0x6D,0x6F,0x72,0x79,0x20, -0x63,0x6F,0x6D,0x6D,0x61,0x6E,0x64,0x00,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72, -0x20,0x73,0x65,0x74,0x00,0x71,0x75,0x61,0x6C,0x69,0x66,0x69,0x65,0x72,0x00,0x61, -0x6C,0x69,0x67,0x6E,0x6D,0x65,0x6E,0x74,0x20,0x66,0x6F,0x72,0x20,0x68,0x61,0x6C, -0x66,0x77,0x6F,0x72,0x64,0x20,0x61,0x63,0x63,0x65,0x73,0x73,0x65,0x73,0x00,0x61, -0x6C,0x69,0x67,0x6E,0x6D,0x65,0x6E,0x74,0x20,0x66,0x6F,0x72,0x20,0x77,0x6F,0x72, -0x64,0x20,0x61,0x63,0x63,0x65,0x73,0x73,0x65,0x73,0x00,0x62,0x72,0x65,0x61,0x6B, -0x70,0x6F,0x69,0x6E,0x74,0x20,0x69,0x64,0x65,0x6E,0x74,0x69,0x66,0x69,0x65,0x72, -0x00,0x4E,0x6F,0x6E,0x20,0x74,0x72,0x61,0x63,0x61,0x62,0x6C,0x65,0x20,0x69,0x6E, -0x73,0x74,0x72,0x75,0x63,0x74,0x69,0x6F,0x6E,0x20,0x61,0x74,0x20,0x63,0x75,0x72, -0x72,0x65,0x6E,0x74,0x20,0x50,0x43,0x00,0x64,0x61,0x74,0x61,0x20,0x61,0x72,0x67, -0x75,0x6D,0x65,0x6E,0x74,0x00,0x73,0x69,0x6E,0x67,0x6C,0x65,0x20,0x68,0x65,0x78, -0x20,0x64,0x69,0x67,0x69,0x74,0x00,0x63,0x6C,0x6F,0x73,0x69,0x6E,0x67,0x20,0x71, -0x75,0x6F,0x74,0x65,0x00,0x41,0x53,0x43,0x49,0x49,0x20,0x63,0x6F,0x6E,0x73,0x74, -0x61,0x6E,0x74,0x00,0x73,0x65,0x67,0x6D,0x65,0x6E,0x74,0x20,0x73,0x65,0x6C,0x65, -0x63,0x74,0x20,0x6C,0x65,0x6E,0x67,0x74,0x68,0x20,0x65,0x72,0x72,0x6F,0x72,0x00, -0x69,0x6E,0x76,0x61,0x6C,0x69,0x64,0x20,0x73,0x65,0x67,0x6D,0x65,0x6E,0x74,0x20, -0x64,0x65,0x73,0x63,0x72,0x69,0x70,0x74,0x6F,0x72,0x00,0x70,0x61,0x67,0x65,0x20, -0x6E,0x6F,0x74,0x20,0x70,0x72,0x65,0x73,0x65,0x6E,0x74,0x00,0x70,0x61,0x67,0x65, -0x20,0x74,0x61,0x62,0x6C,0x65,0x20,0x6C,0x65,0x6E,0x67,0x74,0x68,0x20,0x65,0x72, -0x72,0x6F,0x72,0x00,0x73,0x65,0x67,0x6D,0x65,0x6E,0x74,0x20,0x6F,0x66,0x66,0x73, -0x65,0x74,0x20,0x66,0x61,0x75,0x6C,0x74,0x00,0x73,0x65,0x67,0x6D,0x65,0x6E,0x74, -0x20,0x6C,0x65,0x6E,0x67,0x74,0x68,0x20,0x66,0x61,0x75,0x6C,0x74,0x00,0x74,0x6F, -0x6F,0x20,0x6D,0x61,0x6E,0x79,0x20,0x69,0x6E,0x64,0x69,0x72,0x65,0x63,0x74,0x69, -0x6F,0x6E,0x73,0x00,0x70,0x61,0x67,0x65,0x20,0x64,0x65,0x73,0x63,0x72,0x69,0x70, -0x74,0x6F,0x72,0x20,0x6E,0x6F,0x74,0x20,0x70,0x72,0x65,0x73,0x65,0x6E,0x74,0x00, -0x73,0x65,0x67,0x6D,0x65,0x6E,0x74,0x20,0x6E,0x6F,0x74,0x20,0x70,0x72,0x65,0x73, -0x65,0x6E,0x74,0x00,0x50,0x43,0x42,0x20,0x63,0x68,0x61,0x6E,0x67,0x69,0x6E,0x67, -0x2D,0x2D,0x63,0x68,0x65,0x63,0x6B,0x20,0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72, -0x73,0x00,0x70,0x68,0x79,0x73,0x69,0x63,0x61,0x6C,0x20,0x61,0x64,0x64,0x72,0x65, -0x73,0x73,0x20,0x75,0x73,0x65,0x64,0x20,0x61,0x73,0x20,0x61,0x72,0x67,0x75,0x6D, -0x65,0x6E,0x74,0x00,0x62,0x61,0x75,0x64,0x20,0x72,0x61,0x74,0x65,0x00,0x64,0x75, -0x65,0x20,0x74,0x6F,0x20,0x74,0x69,0x6D,0x65,0x6F,0x75,0x74,0x00,0x2D,0x20,0x73, -0x65,0x63,0x74,0x69,0x6F,0x6E,0x20,0x64,0x6F,0x65,0x73,0x20,0x6E,0x6F,0x74,0x20, -0x66,0x69,0x74,0x20,0x69,0x6E,0x20,0x63,0x6F,0x6E,0x74,0x69,0x67,0x6F,0x75,0x73, -0x20,0x6D,0x65,0x6D,0x6F,0x72,0x79,0x00,0x66,0x69,0x6C,0x65,0x6E,0x61,0x6D,0x65, -0x00,0x6D,0x33,0x32,0x61,0x2E,0x6F,0x75,0x74,0x20,0x68,0x65,0x61,0x64,0x65,0x72, -0x00,0x66,0x69,0x6C,0x65,0x20,0x63,0x6F,0x6E,0x74,0x65,0x6E,0x74,0x73,0x00,0x2D, -0x20,0x74,0x6F,0x6F,0x20,0x6D,0x61,0x6E,0x79,0x20,0x43,0x52,0x43,0x20,0x65,0x72, -0x72,0x6F,0x72,0x73,0x00,0x43,0x52,0x43,0x20,0x63,0x68,0x65,0x63,0x6B,0x73,0x75, -0x6D,0x20,0x72,0x65,0x61,0x64,0x00,0x74,0x72,0x61,0x63,0x65,0x20,0x74,0x72,0x61, -0x70,0x20,0x64,0x65,0x74,0x65,0x63,0x74,0x65,0x64,0x00,0x63,0x61,0x6C,0x6C,0x20, -0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x00,0x61,0x72,0x67,0x75,0x6D,0x65,0x6E,0x74, -0x00,0x70,0x72,0x6F,0x63,0x65,0x73,0x73,0x20,0x69,0x64,0x65,0x6E,0x74,0x69,0x66, -0x69,0x65,0x72,0x00,0x73,0x65,0x63,0x74,0x69,0x6F,0x6E,0x20,0x69,0x64,0x65,0x6E, -0x74,0x69,0x66,0x69,0x65,0x72,0x00,0x00,0x49,0x4E,0x49,0x54,0x00,0x45,0x48,0x00, -0x49,0x48,0x00,0x45,0x58,0x00,0x49,0x44,0x4C,0x45,0x00,0x55,0x53,0x45,0x52,0x00, -0x0A,0x42,0x72,0x65,0x61,0x6B,0x21,0x07,0x0A,0x00,0x07,0x00,0x20,0x45,0x52,0x52, -0x4F,0x52,0x3A,0x20,0x00,0x57,0x41,0x52,0x4E,0x49,0x4E,0x47,0x3A,0x20,0x00,0x25, -0x63,0x00,0x2D,0x25,0x73,0x25,0x73,0x25,0x73,0x0A,0x00,0x00,0x00,0x00,0xC6,0x74, -0x00,0x00,0xC6,0x82,0x00,0x00,0xC6,0x94,0x00,0x00,0xC6,0xA6,0x00,0x00,0xC6,0xB8, -0x00,0x00,0xC6,0xCA,0x00,0x00,0xC6,0xDC,0x00,0x00,0xC6,0xEE,0x00,0x00,0xC7,0x00, -0x00,0x00,0xC7,0x12,0x00,0x00,0xC7,0x24,0x00,0x00,0xC7,0x32,0x00,0x00,0xC7,0x40, -0x00,0x00,0xC7,0x4E,0x00,0x00,0xC7,0x5C,0x00,0x00,0xC7,0x6A,0x00,0x00,0xC7,0x78, -0x00,0x00,0xC7,0x82,0x0A,0x51,0x75,0x61,0x6C,0x69,0x66,0x69,0x65,0x72,0x73,0x0A, -0x00,0x25,0x78,0x20,0x20,0x25,0x38,0x6C,0x78,0x0A,0x00,0x25,0x78,0x20,0x20,0x4E, -0x6F,0x74,0x20,0x41,0x63,0x74,0x69,0x76,0x65,0x0A,0x00,0x5F,0x74,0x00,0x4E,0x6F, -0x20,0x53,0x79,0x6D,0x62,0x6F,0x6C,0x73,0x21,0x0A,0x00,0x25,0x73,0x20,0x2B,0x20, -0x30,0x78,0x25,0x78,0x00,0x0A,0x00,0x00,0x25,0x73,0x25,0x2D,0x38,0x78,0x25,0x63, -0x00,0x25,0x73,0x25,0x2D,0x38,0x78,0x20,0x25,0x73,0x25,0x2D,0x38,0x78,0x20,0x20, -0x20,0x20,0x00,0x0A,0x00,0x25,0x73,0x00,0x25,0x78,0x0A,0x00,0x25,0x78,0x0A,0x00, -0x25,0x78,0x0A,0x00,0x73,0x72,0x61,0x6D,0x61,0x20,0x00,0x25,0x64,0x3A,0x20,0x25, -0x2D,0x38,0x78,0x20,0x20,0x00,0x0A,0x00,0x73,0x72,0x61,0x6D,0x61,0x2F,0x25,0x64, -0x3A,0x20,0x25,0x30,0x38,0x78,0x20,0x0A,0x00,0x73,0x72,0x61,0x6D,0x62,0x20,0x00, -0x25,0x64,0x3A,0x20,0x25,0x2D,0x38,0x78,0x20,0x20,0x00,0x0A,0x00,0x73,0x72,0x61, -0x6D,0x62,0x2F,0x25,0x64,0x3A,0x20,0x25,0x30,0x38,0x78,0x20,0x0A,0x00,0x20,0x43, -0x75,0x72,0x72,0x65,0x6E,0x74,0x3A,0x20,0x73,0x70,0x3A,0x20,0x25,0x2D,0x38,0x78, -0x20,0x20,0x20,0x61,0x70,0x3A,0x20,0x25,0x2D,0x38,0x78,0x20,0x20,0x20,0x66,0x70, -0x3A,0x20,0x25,0x2D,0x38,0x78,0x20,0x20,0x20,0x70,0x63,0x3A,0x25,0x2D,0x38,0x78, -0x20,0x20,0x20,0x00,0x0A,0x00,0x48,0x69,0x74,0x20,0x6C,0x6F,0x77,0x65,0x72,0x20, -0x73,0x74,0x61,0x63,0x6B,0x20,0x62,0x6F,0x75,0x6E,0x64,0x61,0x72,0x79,0x0A,0x00, -0x25,0x38,0x64,0x3A,0x20,0x73,0x70,0x3A,0x20,0x25,0x2D,0x38,0x78,0x20,0x20,0x20, -0x61,0x70,0x3A,0x20,0x25,0x2D,0x38,0x78,0x20,0x20,0x20,0x66,0x70,0x3A,0x20,0x25, -0x2D,0x38,0x78,0x20,0x20,0x20,0x72,0x61,0x3A,0x25,0x2D,0x38,0x78,0x20,0x20,0x20, -0x00,0x0A,0x00,0x00,0x25,0x78,0x20,0x6D,0x61,0x70,0x73,0x20,0x74,0x6F,0x20,0x25, -0x78,0x0A,0x00,0x0A,0x56,0x65,0x72,0x69,0x66,0x79,0x20,0x66,0x61,0x69,0x6C,0x65, -0x64,0x20,0x61,0x74,0x20,0x25,0x38,0x78,0x2D,0x2D,0x72,0x65,0x61,0x64,0x20,0x25, -0x30,0x32,0x78,0x2C,0x20,0x65,0x78,0x70,0x65,0x63,0x74,0x69,0x6E,0x67,0x20,0x25, -0x30,0x32,0x78,0x0A,0x00,0x0A,0x56,0x65,0x72,0x69,0x66,0x79,0x20,0x66,0x61,0x69, -0x6C,0x65,0x64,0x20,0x61,0x74,0x20,0x25,0x38,0x78,0x2D,0x2D,0x72,0x65,0x61,0x64, -0x20,0x25,0x30,0x34,0x78,0x2C,0x20,0x65,0x78,0x70,0x65,0x63,0x74,0x69,0x6E,0x67, -0x20,0x25,0x30,0x34,0x78,0x0A,0x00,0x0A,0x56,0x65,0x72,0x69,0x66,0x79,0x20,0x66, -0x61,0x69,0x6C,0x65,0x64,0x20,0x61,0x74,0x20,0x25,0x38,0x78,0x2D,0x2D,0x72,0x65, -0x61,0x64,0x20,0x25,0x30,0x38,0x78,0x2C,0x20,0x65,0x78,0x70,0x65,0x63,0x74,0x69, -0x6E,0x67,0x20,0x25,0x30,0x38,0x78,0x0A,0x00,0x00,0x00,0x00,0x00,0x00,0xDE,0x1D, -0x00,0x00,0xDE,0x2F,0x00,0x00,0xDE,0xBB,0x00,0x00,0xDE,0x1D,0x00,0x00,0xDE,0x3D, -0x54,0x49,0x4C,0x4C,0x00,0x54,0x49,0x4C,0x4C,0x00,0x25,0x34,0x64,0x3A,0x20,0x20, -0x20,0x50,0x43,0x20,0x3D,0x20,0x25,0x38,0x78,0x20,0x20,0x20,0x50,0x53,0x57,0x20, -0x3D,0x20,0x25,0x38,0x78,0x20,0x20,0x20,0x53,0x50,0x20,0x3D,0x20,0x25,0x38,0x78, -0x20,0x20,0x20,0x00,0x0A,0x00,0x73,0x74,0x61,0x63,0x6B,0x3A,0x00,0x2D,0x4D,0x00, -0x2D,0x53,0x00,0x2D,0x43,0x00,0x2D,0x54,0x00,0x00,0x00,0x00,0x0A,0x07,0x33,0x42, -0x32,0x20,0x4D,0x6F,0x6E,0x69,0x74,0x6F,0x72,0x2F,0x43,0x6F,0x6E,0x74,0x72,0x6F, -0x6C,0x20,0x50,0x72,0x6F,0x67,0x72,0x61,0x6D,0x20,0x2D,0x20,0x65,0x72,0x61,0x73, -0x65,0x20,0x27,0x5E,0x48,0x27,0x2C,0x20,0x6B,0x69,0x6C,0x6C,0x20,0x27,0x40,0x27, -0x0A,0x00,0x00,0x00,0x3E,0x00,0x54,0x65,0x72,0x6D,0x69,0x6E,0x61,0x6C,0x20,0x61, -0x74,0x20,0x25,0x64,0x20,0x2D,0x20,0x00,0x64,0x61,0x74,0x61,0x2D,0x6C,0x69,0x6E, -0x6B,0x20,0x61,0x74,0x20,0x25,0x64,0x0A,0x00,0x43,0x68,0x61,0x6E,0x67,0x65,0x20, -0x62,0x61,0x75,0x64,0x20,0x74,0x6F,0x20,0x25,0x64,0x0A,0x00,0x25,0x63,0x00,0x00, -0x00,0x81,0xE1,0x00,0x00,0x02,0x92,0xE1,0x00,0x81,0xE1,0x00,0x00,0x02,0x92,0xE1, -0x00,0x81,0xE1,0x00,0x00,0x02,0x92,0xE1,0x00,0x81,0xE1,0x00,0x00,0x02,0x92,0xE1, -0x00,0x81,0xE1,0x00,0x00,0x02,0x92,0xE1,0x00,0x81,0xE1,0x00,0x00,0x02,0x92,0xE1, -0x00,0x81,0xE1,0x00,0x00,0x02,0x92,0xE1,0x00,0x81,0xE1,0x00,0x00,0x02,0x92,0xE1, -0x00,0x81,0xE1,0x00,0x00,0x02,0x92,0xE1,0x00,0x81,0xE1,0x00,0x00,0x02,0x92,0xE1, -0x00,0x81,0xE1,0x00,0x00,0x02,0x92,0xE1,0x00,0x81,0xE1,0x00,0x00,0x02,0x92,0xE1, -0x00,0x81,0xE1,0x00,0x00,0x02,0x92,0xE1,0x00,0x81,0xE1,0x00,0x00,0x02,0x92,0xE1, -0x00,0x81,0xE1,0x00,0x00,0x02,0x92,0xE1,0x00,0x81,0xE1,0x00,0x00,0x02,0x92,0xE1, -0xD3,0x21,0x20,0x4A,0x00,0x81,0xE1,0x80,0x00,0x00,0xE1,0x1C,0x02,0x00,0x1E,0x18, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x1E,0x18, -0x02,0x00,0x1F,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0xE1,0x80,0x00,0x00,0xE3,0x38, -0x02,0x00,0x1E,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x02,0x00,0x1E,0x18,0x02,0x00,0x1F,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0xE1,0x80, -0x00,0x00,0x93,0xA4,0x02,0x00,0x1E,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x02,0x00,0x1E,0x18,0x02,0x00,0x1F,0x44,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x81,0xE1,0x80,0x00,0x02,0x94,0x56,0x02,0x00,0x1E,0x18,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x1E,0x18,0x02,0x00,0x1F,0x44, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x81,0xE1,0x80,0x00,0x02,0x94,0xAE,0x02,0x00,0x1E,0x18, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x1E,0x18, -0x02,0x00,0x1F,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0xE1,0x80,0x00,0x02,0x94,0x2A, -0x02,0x00,0x1E,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x02,0x00,0x1E,0x18,0x02,0x00,0x1F,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x20, -0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x28,0x28,0x28,0x28,0x20,0x20,0x20,0x20,0x20, -0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x48,0x10,0x10, -0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x84,0x84,0x84, -0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x81,0x81, -0x81,0x81,0x81,0x81,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, -0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x10,0x10,0x10,0x10,0x10,0x10,0x82,0x82, -0x82,0x82,0x82,0x82,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02, -0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x10,0x10,0x10,0x10,0x20,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x04,0x7F,0x08,0x00,0x00,0x02,0x4C,0x04,0x7F,0x08,0x00,0x00,0x02,0x49,0x04,0x7F, -0x08,0x00,0x00,0x02,0x4A,0x04,0x7F,0x08,0x08,0x00,0x02,0x4E,0x87,0x16,0x7F,0x0F, -0x20,0x04,0x00,0x70,0x87,0x6F,0x64,0x7F,0x03,0x20,0x04,0x00,0x70,0x87,0x5F,0x94, -0x00,0x7F,0x0F,0x20,0x04,0x00,0x70,0x87,0x0A,0x7F,0x0B,0x20,0x04,0x00,0x70,0x87, -0x6F,0x74,0x7F,0x0F,0x20,0x04,0x00,0x70,0x24,0x7F,0xC1,0x2D,0x00,0x00,0x70,0x70, -0x10,0x43,0x9C,0x4F,0x08,0x00,0x00,0x00,0x4C,0x87,0x01,0x7F,0x1B,0x40,0x04,0x00, -0x70,0x70,0x84,0x4B,0x40,0xB8,0x4F,0xFF,0xFF,0xC3,0xFF,0x40,0x84,0x40,0x4B,0x77, -0x05,0x7A,0xB5,0x05,0x47,0x05,0x7A,0xB0,0x05,0x43,0x05,0x7A,0xAB,0x05,0x57,0x05, -0x7A,0xA6,0x05,0x53,0x05,0x7A,0xA1,0x05,0x53,0x05,0x7A,0x9C,0x05,0x63,0x05,0x7A, -0x97,0x05,0x70,0x84,0x4B,0x40,0xB0,0x4F,0x00,0x00,0x3C,0x00,0x40,0x84,0x40,0x4B, -0x7F,0x05,0x7A,0x84,0x05,0x4F,0x05,0x7A,0x7F,0x05,0x43,0x05,0x7A,0x7A,0x05,0x5F, -0x05,0x7A,0x75,0x05,0x5B,0x05,0x7A,0x70,0x05,0x5B,0x05,0x7A,0x6B,0x05,0x6B,0x05, -0x7A,0x66,0x05,0x70,0x84,0x4B,0x40,0xB8,0x4F,0xFF,0xFF,0xC3,0xFF,0x40,0xB0,0x4F, -0x00,0x00,0x10,0x00,0x40,0x84,0x40,0x4B,0x43,0x05,0x7A,0x4C,0x05,0x70,0x84,0x4B, -0x40,0xB8,0x4F,0xFF,0xFF,0xC3,0xFF,0x40,0xB0,0x4F,0x00,0x00,0x04,0x00,0x40,0x84, -0x40,0x4B,0x5E,0x06,0x00,0x7A,0x31,0x05,0x70,0x84,0x4B,0x40,0xB8,0x4F,0xFF,0xFF, -0xC3,0xFF,0x40,0xB0,0x4F,0x00,0x00,0x20,0x00,0x40,0x84,0x40,0x4B,0x4B,0x05,0x7A, -0x17,0x05,0x84,0xFF,0x40,0x84,0x40,0x41,0x84,0x41,0x42,0x84,0x42,0x43,0x84,0x43, -0x44,0x84,0x44,0x45,0x84,0x45,0x46,0x84,0x46,0x47,0x84,0x47,0x48,0x3C,0x40,0x48, -0x76,0xF6,0x04,0xD0,0x01,0x40,0x40,0x43,0x04,0x7B,0xDC,0x84,0xFE,0x40,0x88,0x40, -0x41,0x88,0x41,0x42,0x88,0x42,0x43,0x88,0x43,0x44,0x88,0x44,0x45,0x88,0x45,0x46, -0x88,0x46,0x47,0x88,0x47,0x48,0x88,0x40,0x48,0x88,0x41,0x47,0x88,0x42,0x46,0x88, -0x43,0x45,0x88,0x48,0x41,0x88,0x47,0x42,0x88,0x46,0x43,0x88,0x44,0x40,0x88,0x41, -0x44,0x3C,0x40,0x48,0x76,0xB2,0x04,0xD0,0x01,0x40,0x40,0x4B,0x07,0x88,0x40,0x40, -0x7B,0xBE,0x84,0x49,0x41,0x84,0x4A,0x42,0x84,0x4C,0x43,0x84,0x4D,0x44,0x84,0x4E, -0x45,0x84,0xFF,0x40,0x84,0x40,0x49,0x84,0x49,0x4A,0x84,0x4A,0x4C,0x84,0x4C,0x4D, -0x84,0x4D,0x4E,0x3C,0x49,0x4E,0x76,0x4C,0x00,0xD0,0x01,0x40,0x40,0x43,0x04,0x7B, -0xE5,0x84,0x01,0x40,0x88,0x40,0x49,0x88,0x49,0x4A,0x88,0x4A,0x4C,0x88,0x4C,0x4D, -0x88,0x4D,0x4E,0x88,0x49,0x4E,0x88,0x4A,0x4D,0x88,0x4C,0x49,0x88,0x4E,0x4A,0x88, -0x4D,0x4C,0x3C,0x49,0x4E,0x76,0x1D,0x00,0xD0,0x01,0x40,0x40,0x4B,0x04,0x7B,0xD6, -0x84,0x41,0x49,0x84,0x42,0x4A,0x84,0x43,0x4C,0x84,0x44,0x4D,0x84,0x45,0x4E,0x7A, -0x12,0x00,0x84,0x41,0x49,0x84,0x42,0x4A,0x84,0x43,0x4C,0x84,0x44,0x4D,0x84,0x45, -0x4E,0x82,0x48,0x84,0x5F,0xEE,0x7F,0x47,0x80,0x46,0x7B,0x3F,0x86,0xE2,0x48,0xE0, -0x40,0x87,0x56,0xE2,0x41,0xBA,0x5F,0xFF,0x00,0x41,0x86,0xE2,0x41,0xE0,0x41,0x9C, -0x41,0x40,0x86,0x40,0x48,0x86,0xE2,0x48,0xE0,0x40,0xD0,0x01,0x40,0x40,0x86,0xE2, -0x40,0xE0,0x40,0x86,0xE2,0x48,0xE0,0x41,0xD4,0x0F,0x41,0x41,0x86,0xE2,0x41,0xE0, -0x41,0xB0,0x41,0x40,0x86,0x40,0x48,0x90,0x46,0x3C,0x47,0x46,0x5B,0xC0,0x86,0xE2, -0x48,0xE0,0x40,0x88,0x40,0x40,0x86,0x40,0x48,0x86,0xE2,0x48,0xE0,0x40,0x87,0x56, -0xE0,0x41,0x87,0xC6,0x01,0xE0,0x42,0xD0,0x08,0x42,0x42,0xB0,0x42,0x41,0x3C,0x41, -0x40,0x77,0x08,0x24,0x7F,0x57,0x30,0x00,0x00,0x86,0xE2,0x48,0xE0,0x40,0x88,0x40, -0x40,0x86,0x40,0x48,0x9C,0x4F,0x00,0x80,0x00,0x00,0x47,0x7B,0x3F,0x86,0xE2,0x48, -0xE0,0x40,0x87,0x56,0xE2,0x41,0xBA,0x5F,0xFF,0x00,0x41,0x86,0xE2,0x41,0xE0,0x41, -0x9C,0x41,0x40,0x86,0x40,0x48,0x86,0xE2,0x48,0xE0,0x40,0xD0,0x01,0x40,0x40,0x86, -0xE2,0x40,0xE0,0x40,0x86,0xE2,0x48,0xE0,0x41,0xD4,0x0F,0x41,0x41,0x86,0xE2,0x41, -0xE0,0x41,0xB0,0x41,0x40,0x86,0x40,0x48,0x90,0x46,0x3C,0x47,0x46,0x5B,0xC0,0x86, -0xE2,0x48,0xE0,0x40,0x88,0x40,0x40,0x86,0x40,0x48,0x86,0xE2,0x48,0xE0,0x40,0x87, -0x56,0xE0,0x41,0x87,0xC6,0x01,0xE0,0x42,0xD0,0x08,0x42,0x42,0xB0,0x42,0x41,0x3C, -0x41,0x40,0x7F,0x05,0x7A,0x03,0x00,0x3C,0x4F,0xED,0x0D,0x1C,0xA1,0x7F,0x64,0x08, -0x00,0x02,0x7F,0x15,0x3C,0x4F,0x0D,0xF0,0xAD,0x8B,0x7F,0x64,0x08,0x00,0x02,0x7F, -0x08,0x24,0x7F,0x90,0x31,0x00,0x00,0x2C,0x5C,0x7F,0x90,0x54,0x00,0x00,0x2C,0x5C, -0x7F,0x7C,0x88,0x00,0x00,0xA0,0x00,0x2C,0xCC,0xFC,0x7F,0x28,0x8E,0x00,0x00,0x87, -0x7F,0x00,0xD0,0x04,0x00,0xE0,0x47,0x87,0x01,0x7F,0x1F,0x40,0x04,0x00,0x70,0x87, -0x10,0x7F,0x0F,0x90,0x04,0x00,0x70,0x87,0x20,0x7F,0x0F,0x90,0x04,0x00,0x70,0x87, -0x01,0x7F,0x68,0x08,0x00,0x02,0x70,0xDC,0x02,0x7F,0xA4,0x04,0x00,0x00,0x40,0x2B, -0x50,0x7F,0x10,0x2C,0x5C,0x7F,0x5C,0x3F,0x00,0x00,0x2C,0x5C,0x7F,0xB8,0x77,0x00, -0x00,0xDC,0x04,0x7F,0xA4,0x04,0x00,0x00,0x40,0x3F,0x01,0x50,0x77,0x08,0x24,0x7F, -0x74,0x31,0x00,0x00,0x2C,0x5C,0x7F,0x5C,0x3F,0x00,0x00,0xA0,0x4F,0x0C,0x30,0x04, -0x00,0xE0,0x59,0xA0,0x01,0x2C,0xCC,0xF4,0x7F,0x50,0x6B,0x00,0x00,0x28,0x40,0x77, -0x26,0x84,0x01,0x59,0x70,0xE0,0x59,0xA0,0x4F,0x0C,0x30,0x04,0x00,0xA0,0x01,0x2C, -0xCC,0xF4,0x7F,0xCC,0x6B,0x00,0x00,0xDC,0x01,0x7F,0xA0,0x04,0x00,0x00,0x40,0x87, -0x01,0x50,0x70,0x7B,0x0E,0xDC,0x01,0x7F,0xA0,0x04,0x00,0x00,0x40,0x87,0x63,0x50, -0x70,0x84,0x7F,0x64,0x08,0x00,0x02,0x59,0x70,0x83,0xEF,0xA0,0x04,0x00,0x00,0x70, -0xDC,0x02,0x7F,0xA0,0x04,0x00,0x00,0x40,0xA0,0x40,0xA0,0x4F,0xD0,0x05,0x00,0x00, -0x2C,0xCC,0xF8,0x7F,0x6C,0xEA,0x00,0x00,0x2C,0x5C,0x7F,0x90,0x7F,0x00,0x00,0x3C, -0x4F,0xEF,0xBE,0xED,0xFE,0x7F,0x64,0x08,0x00,0x02,0x7F,0x0A,0x84,0x59,0x7F,0x64, -0x08,0x00,0x02,0x70,0x3C,0x4F,0xED,0x0D,0x1C,0xA1,0x7F,0x64,0x08,0x00,0x02,0x77, -0x0B,0x2C,0x5C,0xEF,0x58,0x08,0x00,0x02,0x7B,0x08,0x24,0x7F,0x38,0x7B,0x00,0x00, -0x82,0x48,0x84,0x4F,0x00,0x38,0x04,0x00,0x47,0x84,0x4F,0x00,0x30,0x04,0x00,0x46, -0x7B,0x40,0x86,0xE2,0x48,0xE0,0x40,0x86,0xE2,0xC6,0x02,0xE0,0x41,0xBA,0x0F,0x41, -0x86,0xE2,0x41,0xE0,0x41,0x9C,0x41,0x40,0x86,0x40,0x48,0x86,0xE2,0x48,0xE0,0x40, -0xD0,0x01,0x40,0x40,0x86,0xE2,0x40,0xE0,0x40,0x86,0xE2,0x48,0xE0,0x41,0xD4,0x0F, -0x41,0x41,0x86,0xE2,0x41,0xE0,0x41,0xB0,0x41,0x40,0x86,0x40,0x48,0x9C,0x04,0x46, -0x3C,0x47,0x46,0x5B,0xBF,0x86,0xE2,0x48,0xE0,0x40,0x88,0x40,0x40,0x86,0x40,0x48, -0x86,0xE2,0x48,0xE0,0x40,0xF8,0x0F,0x56,0x41,0xF8,0x0F,0xC6,0x04,0x42,0xD0,0x04, -0x42,0x42,0xB0,0x42,0x41,0xF8,0x0F,0xC6,0x08,0x42,0xD0,0x08,0x42,0x42,0xB0,0x42, -0x41,0xF8,0x0F,0xC6,0x0C,0x42,0xD0,0x0C,0x42,0x42,0xB0,0x42,0x41,0x3C,0x41,0x40, -0x7F,0x2E,0x86,0x01,0x48,0x84,0x4F,0x00,0x30,0x04,0x00,0x46,0x7B,0x08,0x80,0x56, -0x70,0x9C,0x04,0x46,0x3C,0x47,0x46,0x5B,0xF7,0x84,0x0F,0x56,0x70,0x84,0x0F,0xC6, -0x04,0x70,0x84,0x0F,0xC6,0x08,0x70,0x84,0x0F,0xC6,0x0C,0x70,0x7B,0x04,0x82,0x48, -0x84,0x7F,0x6C,0x08,0x00,0x02,0x44,0x84,0x7F,0x64,0x08,0x00,0x02,0x45,0x3C,0x4F, -0xD0,0xF1,0x02,0x3B,0x7F,0x6C,0x08,0x00,0x02,0x7F,0x23,0x87,0x6F,0x70,0x7F,0x04, -0x90,0x04,0x00,0x70,0x87,0x6F,0x40,0x7F,0x06,0x90,0x04,0x00,0x70,0x83,0x7F,0x07, -0x90,0x04,0x00,0x70,0x87,0x04,0x7F,0x0D,0x90,0x04,0x00,0x70,0x80,0x47,0x24,0x7F, -0x3E,0x33,0x00,0x00,0x28,0x47,0x77,0x12,0x84,0x4F,0x00,0x00,0x00,0x02,0x46,0x84, -0x4F,0x4C,0x2C,0x00,0x02,0x43,0x7B,0x46,0x3C,0x4F,0xEF,0xBE,0xED,0xFE,0x45,0x7F, -0x26,0x3C,0x4F,0xD0,0xF1,0x02,0x3B,0x45,0x7F,0x1D,0x3C,0x4F,0x0D,0xF0,0xAD,0x8B, -0x45,0x7F,0x14,0x3C,0x4F,0x1E,0xAC,0xEB,0xAD,0x45,0x7F,0x0B,0x3C,0x4F,0xED,0x0D, -0x1C,0xA1,0x45,0x77,0x0B,0x84,0x4F,0x00,0x30,0x00,0x02,0x46,0x7B,0x09,0x84,0x4F, -0x4C,0x2C,0x00,0x02,0x46,0x84,0x4F,0x00,0x40,0x00,0x02,0x43,0x7B,0x4B,0x87,0x5F, -0xFF,0x00,0x56,0x70,0x3F,0x5F,0xFF,0x00,0x56,0x7F,0x08,0x24,0x7F,0x98,0x33,0x00, -0x00,0x87,0x5F,0xAA,0x00,0x56,0x70,0x3F,0x5F,0xAA,0x00,0x56,0x7F,0x08,0x24,0x7F, -0x98,0x33,0x00,0x00,0x87,0x6F,0x55,0x56,0x70,0x3F,0x6F,0x55,0x56,0x7F,0x08,0x24, -0x7F,0x98,0x33,0x00,0x00,0x83,0x56,0x70,0x84,0x46,0x40,0x90,0x46,0x2B,0x50,0x7F, -0x08,0x24,0x7F,0x98,0x33,0x00,0x00,0x3C,0x43,0x46,0x5B,0xB4,0x90,0x47,0x3C,0x02, -0x47,0x5A,0x53,0xFF,0x84,0x44,0x7F,0x6C,0x08,0x00,0x02,0x70,0x84,0x45,0x7F,0x64, -0x08,0x00,0x02,0x70,0x86,0xE2,0x48,0xE0,0x7F,0x5C,0x08,0x00,0x02,0x70,0x87,0x01, -0x7F,0x68,0x08,0x00,0x02,0x70,0x38,0x7F,0x5C,0x08,0x00,0x02,0x01,0x7F,0x0C,0x87, -0x01,0x7F,0x60,0x08,0x00,0x02,0x70,0x7B,0x09,0x83,0x7F,0x60,0x08,0x00,0x02,0x70, -0x24,0x7F,0x1D,0x3A,0x00,0x00,0x84,0x02,0x44,0x24,0x7F,0xA4,0x33,0x00,0x00,0x84, -0x03,0x44,0x24,0x7F,0xA4,0x33,0x00,0x00,0x84,0x04,0x44,0x24,0x7F,0xA4,0x33,0x00, -0x00,0x84,0x05,0x44,0x83,0x7F,0x0D,0x90,0x04,0x00,0x70,0x87,0x08,0x7F,0x0F,0x90, -0x04,0x00,0x70,0x87,0x01,0x7F,0x17,0x40,0x04,0x00,0x70,0x87,0x01,0x7F,0x27,0x40, -0x04,0x00,0x70,0x80,0x45,0x7B,0x32,0x80,0x47,0x7B,0x04,0x90,0x47,0x3C,0x4F,0x50, -0xC3,0x00,0x00,0x47,0x5F,0xF7,0x87,0x01,0x7F,0x13,0x40,0x04,0x00,0x70,0x80,0x47, -0x7B,0x04,0x90,0x47,0x3C,0x4F,0x50,0xC3,0x00,0x00,0x47,0x5F,0xF7,0x87,0x01,0x7F, -0x17,0x40,0x04,0x00,0x70,0x90,0x45,0x3C,0x44,0x45,0x5B,0xCD,0x3F,0x01,0xEF,0x10, -0x05,0x00,0x00,0x7F,0x2B,0x3F,0x6F,0x64,0x7F,0x03,0x20,0x04,0x00,0x7F,0x21,0x80, -0xEF,0x8C,0x04,0x00,0x00,0x70,0x80,0xEF,0x14,0x05,0x00,0x00,0x70,0x83,0x7F,0x0D, -0x90,0x04,0x00,0x70,0x87,0x04,0x7F,0x0E,0x90,0x04,0x00,0x70,0x7B,0x00,0x80,0x47, -0x7B,0x04,0x90,0x47,0xE8,0x4F,0x50,0xC3,0x00,0x00,0x44,0x40,0x3C,0x40,0x47,0x5F, -0xF3,0x24,0x7F,0xC3,0x33,0x00,0x00,0x04,0x59,0x4C,0x20,0x48,0x20,0x47,0x20,0x46, -0x20,0x45,0x20,0x44,0x20,0x43,0x20,0x49,0x08,0x70,0x70,0x70,0x10,0x43,0x9C,0x4F, -0x00,0x00,0x00,0x00,0x4C,0x87,0x5F,0xD0,0x00,0x7F,0x00,0xD0,0x04,0x00,0x70,0xA0, -0x01,0x2C,0xCC,0xFC,0xEF,0x28,0x05,0x00,0x00,0x87,0x01,0x7F,0x72,0x08,0x00,0x02, -0x70,0x87,0x5F,0xFF,0x00,0x7F,0x73,0x08,0x00,0x02,0x70,0xA0,0x00,0xA0,0x4F,0x74, -0x08,0x00,0x02,0xA0,0x00,0xA0,0x03,0x2C,0xCC,0xF0,0x7F,0xCC,0x8F,0x00,0x00,0x28, -0x40,0x77,0x08,0x24,0x7F,0x2C,0x35,0x00,0x00,0xDC,0x03,0x7F,0x08,0x05,0x00,0x00, -0x40,0x3F,0x50,0x7F,0x74,0x08,0x00,0x02,0x77,0x74,0xDC,0x07,0x7F,0x08,0x05,0x00, -0x00,0x40,0x3F,0x50,0x7F,0x75,0x08,0x00,0x02,0x77,0x63,0xDC,0x0B,0x7F,0x08,0x05, -0x00,0x00,0x40,0x3F,0x50,0x7F,0x76,0x08,0x00,0x02,0x77,0x52,0xDC,0x0F,0x7F,0x08, -0x05,0x00,0x00,0x40,0x3F,0x50,0x7F,0x77,0x08,0x00,0x02,0x77,0x41,0x84,0x4F,0x00, -0x30,0x04,0x00,0x48,0x7B,0x08,0x80,0x58,0x70,0x9C,0x04,0x48,0x3C,0x4F,0x00,0x38, -0x04,0x00,0x48,0x5B,0xF3,0x84,0x0F,0x58,0x70,0x84,0x0F,0xC8,0x04,0x70,0x84,0x0F, -0xC8,0x08,0x70,0x84,0x0F,0xC8,0x0C,0x70,0xB0,0x4F,0x00,0x00,0x01,0x00,0x7F,0x5C, -0x08,0x00,0x02,0x70,0x87,0x01,0x7F,0x60,0x08,0x00,0x02,0x70,0x2B,0x7F,0x60,0x08, -0x00,0x02,0x77,0x1C,0xA0,0x4F,0x0C,0x30,0x04,0x00,0xA0,0x4F,0x71,0x08,0x00,0x02, -0xA0,0x01,0x2C,0xCC,0xF4,0x7F,0x50,0x6B,0x00,0x00,0x28,0x40,0x77,0x27,0x87,0x01, -0x7F,0x71,0x08,0x00,0x02,0x70,0xA0,0x4F,0x71,0x08,0x00,0x02,0xA0,0x4F,0x0C,0x30, -0x04,0x00,0xA0,0x01,0x2C,0xCC,0xF4,0x7F,0xCC,0x6B,0x00,0x00,0x83,0x7F,0x60,0x08, -0x00,0x02,0x70,0x3F,0x01,0x7F,0x71,0x08,0x00,0x02,0x7F,0x0B,0x3F,0x02,0x7F,0x71, -0x08,0x00,0x02,0x77,0x12,0x87,0x01,0x45,0xFF,0x01,0x7F,0x71,0x08,0x00,0x02,0x40, -0x87,0x40,0x47,0x7B,0x06,0x83,0x45,0x83,0x47,0x83,0x7F,0x70,0x08,0x00,0x02,0x70, -0x82,0x44,0x7B,0x18,0x86,0x44,0xE4,0x40,0x86,0x44,0xE4,0x41,0x87,0x81,0xA4,0x13, -0x00,0x00,0x80,0x74,0x0A,0x00,0x02,0x70,0x92,0x44,0x3E,0x08,0x44,0x4B,0xE7,0x82, -0x44,0x7B,0x18,0x87,0x47,0xE0,0x40,0xA0,0x40,0x2C,0xCC,0xFC,0x7F,0x7C,0x88,0x00, -0x00,0x28,0x40,0x7F,0x04,0x7B,0x0B,0x92,0x44,0x3E,0x5F,0xF4,0x01,0x44,0x4B,0xE5, -0x87,0x47,0xE0,0x40,0xA0,0x40,0x2C,0xCC,0xFC,0x7F,0xB8,0x83,0x00,0x00,0x28,0x40, -0x77,0x08,0x24,0x7F,0x0C,0x37,0x00,0x00,0xEB,0x6F,0x54,0x47,0x40,0x3C,0x4F,0x0D, -0x60,0x5E,0xCA,0x80,0x80,0x0A,0x00,0x02,0x7F,0x08,0x24,0x7F,0x0C,0x37,0x00,0x00, -0xDF,0x01,0x47,0x40,0xB3,0x40,0x7F,0x70,0x08,0x00,0x02,0x70,0xBB,0x5F,0xF0,0x00, -0x7F,0x75,0x0A,0x00,0x02,0x70,0xEB,0x6F,0x54,0x47,0x40,0xD4,0x08,0x80,0xA0,0x0A, -0x00,0x02,0x40,0xB3,0x40,0x7F,0x75,0x0A,0x00,0x02,0x70,0xEB,0x6F,0x54,0x47,0x40, -0x87,0x80,0xA3,0x0A,0x00,0x02,0x7F,0x76,0x0A,0x00,0x02,0x70,0xEB,0x6F,0x54,0x47, -0x40,0xFF,0x01,0x80,0x9B,0x0A,0x00,0x02,0x40,0x87,0x40,0x7F,0x77,0x0A,0x00,0x02, -0x70,0xEB,0x6F,0x54,0x47,0x40,0xFF,0x01,0x80,0x9F,0x0A,0x00,0x02,0x40,0x87,0x40, -0x7F,0x78,0x0A,0x00,0x02,0x70,0xEB,0x6F,0x54,0x47,0x40,0xD4,0x09,0x80,0x94,0x0A, -0x00,0x02,0x40,0x87,0x40,0x7F,0x7A,0x0A,0x00,0x02,0x70,0xEB,0x6F,0x54,0x47,0x40, -0xD4,0x01,0x80,0x94,0x0A,0x00,0x02,0x40,0x87,0x40,0x7F,0x7B,0x0A,0x00,0x02,0x70, -0x87,0x47,0xE0,0x40,0xA0,0x40,0x2C,0xCC,0xFC,0x7F,0x7C,0x88,0x00,0x00,0x28,0x40, -0x77,0x24,0x2B,0x45,0x7F,0x1E,0xB0,0x02,0x7F,0x5C,0x08,0x00,0x02,0x70,0x87,0x01, -0x7F,0x13,0x40,0x04,0x00,0x70,0x84,0x4F,0xEF,0xBE,0xED,0xFE,0xEF,0x8C,0x04,0x00, -0x00,0x70,0x7B,0x34,0x2B,0x45,0x7F,0x30,0x87,0x47,0xE0,0x40,0xA0,0x40,0x2C,0xCC, -0xFC,0x7F,0x70,0x8D,0x00,0x00,0x28,0x40,0x77,0x1E,0xB0,0x02,0x7F,0x5C,0x08,0x00, -0x02,0x70,0x87,0x01,0x7F,0x13,0x40,0x04,0x00,0x70,0x84,0x4F,0xEF,0xBE,0xED,0xFE, -0xEF,0x8C,0x04,0x00,0x00,0x70,0x24,0x7F,0x9A,0x37,0x00,0x00,0x3C,0x4F,0xEF,0xBE, -0xED,0xFE,0x7F,0x78,0x08,0x00,0x02,0x77,0x63,0x84,0x3D,0x7F,0x64,0x08,0x00,0x02, -0x70,0xA0,0x4F,0x64,0x08,0x00,0x02,0xA0,0x4F,0x0A,0x30,0x04,0x00,0xA0,0x02,0x2C, -0xCC,0xF4,0x7F,0xCC,0x6B,0x00,0x00,0x2C,0x5C,0x7F,0x90,0x54,0x00,0x00,0x87,0x01, -0x7F,0x71,0x08,0x00,0x02,0x70,0xA0,0x4F,0x71,0x08,0x00,0x02,0xA0,0x4F,0x0C,0x30, -0x04,0x00,0xA0,0x01,0x2C,0xCC,0xF4,0x7F,0xCC,0x6B,0x00,0x00,0x84,0x4F,0x1E,0xAC, -0xEB,0xAD,0x7F,0x64,0x08,0x00,0x02,0x70,0xB0,0x6F,0x40,0x7F,0x5C,0x08,0x00,0x02, -0x70,0x2C,0x5C,0x7F,0xF8,0x3D,0x00,0x00,0x7B,0x22,0x2B,0x45,0x7F,0x1E,0xB0,0x02, -0x7F,0x5C,0x08,0x00,0x02,0x70,0x87,0x01,0x7F,0x13,0x40,0x04,0x00,0x70,0x84,0x4F, -0xEF,0xBE,0xED,0xFE,0xEF,0x8C,0x04,0x00,0x00,0x70,0xF7,0x01,0x47,0x40,0x87,0x40, -0x46,0x87,0x46,0xE0,0x40,0xA0,0x40,0x2C,0xCC,0xFC,0x7F,0xD0,0x88,0x00,0x00,0x28, -0x40,0x77,0x08,0x24,0x7F,0x19,0x39,0x00,0x00,0x87,0x46,0xE0,0x40,0xA0,0x40,0x2C, -0xCC,0xFC,0x7F,0xB8,0x83,0x00,0x00,0x28,0x40,0x77,0x08,0x24,0x7F,0x19,0x39,0x00, -0x00,0xEB,0x6F,0x54,0x46,0x40,0x3C,0x4F,0x0D,0x60,0x5E,0xCA,0x80,0x80,0x0A,0x00, -0x02,0x7F,0x08,0x24,0x7F,0x19,0x39,0x00,0x00,0xDF,0x01,0x46,0x40,0xB3,0x40,0x7F, -0x70,0x08,0x00,0x02,0x70,0x80,0x43,0xEB,0x6F,0x54,0x46,0x40,0xEB,0x6F,0x54,0x47, -0x41,0x3C,0x81,0xA0,0x0A,0x00,0x02,0x80,0xA0,0x0A,0x00,0x02,0x5F,0x35,0xBB,0x5F, -0xF0,0x00,0x7F,0x75,0x0A,0x00,0x02,0x70,0xEB,0x6F,0x54,0x46,0x40,0xD4,0x08,0x80, -0xA0,0x0A,0x00,0x02,0x40,0xB3,0x40,0x7F,0x75,0x0A,0x00,0x02,0x70,0xEB,0x6F,0x54, -0x46,0x40,0x87,0x80,0xA3,0x0A,0x00,0x02,0x7F,0x76,0x0A,0x00,0x02,0x70,0x84,0x01, -0x43,0xEB,0x6F,0x54,0x46,0x40,0xEB,0x6F,0x54,0x47,0x41,0x3C,0x81,0x98,0x0A,0x00, -0x02,0x80,0x98,0x0A,0x00,0x02,0x5F,0x1A,0xEB,0x6F,0x54,0x46,0x40,0xFF,0x01,0x80, -0x9B,0x0A,0x00,0x02,0x40,0x87,0x40,0x7F,0x77,0x0A,0x00,0x02,0x70,0x84,0x01,0x43, -0xEB,0x6F,0x54,0x46,0x40,0xEB,0x6F,0x54,0x47,0x41,0x3C,0x81,0x9C,0x0A,0x00,0x02, -0x80,0x9C,0x0A,0x00,0x02,0x5F,0x1A,0xEB,0x6F,0x54,0x46,0x40,0xFF,0x01,0x80,0x9F, -0x0A,0x00,0x02,0x40,0x87,0x40,0x7F,0x78,0x0A,0x00,0x02,0x70,0x84,0x01,0x43,0xEB, -0x6F,0x54,0x46,0x40,0xEB,0x6F,0x54,0x47,0x41,0x3C,0x81,0x94,0x0A,0x00,0x02,0x80, -0x94,0x0A,0x00,0x02,0x5F,0x2F,0xEB,0x6F,0x54,0x46,0x40,0xD4,0x09,0x80,0x94,0x0A, -0x00,0x02,0x40,0x87,0x40,0x7F,0x7A,0x0A,0x00,0x02,0x70,0xEB,0x6F,0x54,0x46,0x40, -0xD4,0x01,0x80,0x94,0x0A,0x00,0x02,0x40,0x87,0x40,0x7F,0x7B,0x0A,0x00,0x02,0x70, -0x84,0x01,0x43,0x28,0x43,0x7F,0x34,0x87,0x46,0xE0,0x40,0xA0,0x40,0x2C,0xCC,0xFC, -0x7F,0x7C,0x88,0x00,0x00,0x28,0x40,0x77,0x22,0x2B,0x45,0x7F,0x1E,0xB0,0x02,0x7F, -0x5C,0x08,0x00,0x02,0x70,0x87,0x01,0x7F,0x13,0x40,0x04,0x00,0x70,0x84,0x4F,0xEF, -0xBE,0xED,0xFE,0xEF,0x8C,0x04,0x00,0x00,0x70,0x2C,0x5C,0x7F,0xF8,0x3D,0x00,0x00, -0x3F,0x02,0x7F,0x70,0x08,0x00,0x02,0x4F,0x12,0x87,0x7F,0x70,0x08,0x00,0x02,0xE2, -0x40,0xBE,0x01,0x40,0x86,0x40,0x44,0x7B,0x0D,0x87,0x7F,0x70,0x08,0x00,0x02,0xE2, -0x40,0x86,0x40,0x44,0xDC,0x04,0x7F,0x90,0x04,0x00,0x00,0x40,0xDE,0x01,0x44,0x41, -0xC8,0x03,0x00,0x41,0x50,0x70,0xDC,0x08,0x7F,0x90,0x04,0x00,0x00,0x40,0x84,0xEF, -0xE8,0x04,0x00,0x00,0x50,0x70,0xDC,0x04,0x7F,0x90,0x04,0x00,0x00,0x40,0xCC,0x03, -0x00,0x50,0x40,0xA8,0x0C,0x40,0x9C,0x40,0xEF,0xE8,0x04,0x00,0x00,0x70,0xDC,0x08, -0x7F,0x90,0x04,0x00,0x00,0x40,0x86,0x01,0xD0,0x00,0x70,0xDC,0x08,0x7F,0x90,0x04, -0x00,0x00,0x40,0xDC,0x02,0x50,0x40,0xA0,0x40,0xA0,0x4F,0xD9,0x05,0x00,0x00,0x2C, -0xCC,0xF8,0x7F,0x6C,0xEA,0x00,0x00,0x3B,0x7F,0x70,0x08,0x00,0x02,0x01,0x7F,0x23, -0x3C,0x4F,0x0D,0x60,0x5E,0xCA,0x7F,0x80,0x0A,0x00,0x02,0x77,0x16,0xDC,0x08,0x7F, -0x90,0x04,0x00,0x00,0x40,0x84,0x50,0x40,0x86,0x7F,0x7E,0x0A,0x00,0x02,0xC0,0x0C, -0x70,0x3B,0x7F,0x70,0x08,0x00,0x02,0x02,0x7F,0x23,0x3C,0x4F,0x0D,0x60,0x5E,0xCA, -0x7F,0xD4,0x0A,0x00,0x02,0x77,0x16,0xDC,0x08,0x7F,0x90,0x04,0x00,0x00,0x40,0x84, -0x50,0x40,0x86,0x7F,0xD2,0x0A,0x00,0x02,0xC0,0x18,0x70,0x24,0x7F,0x38,0x7B,0x00, -0x00,0x04,0x59,0x4C,0x20,0x48,0x20,0x47,0x20,0x46,0x20,0x45,0x20,0x44,0x20,0x43, -0x20,0x49,0x08,0x70,0x10,0x46,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x84,0x4F,0xEC, -0x05,0x00,0x00,0x48,0x84,0x4F,0xC4,0x0E,0x00,0x02,0x47,0x83,0x46,0x7B,0x14,0x84, -0x47,0x40,0x9C,0x04,0x47,0x84,0x48,0x41,0x9C,0x04,0x48,0x84,0x51,0x50,0x70,0x93, -0x46,0x3F,0x11,0x46,0x4B,0xEB,0x84,0x4F,0x30,0x06,0x00,0x00,0x48,0x84,0x4F,0x24, -0x0E,0x00,0x02,0x47,0x83,0x46,0x7B,0x14,0x84,0x47,0x40,0x9C,0x04,0x47,0x84,0x48, -0x41,0x9C,0x04,0x48,0x84,0x51,0x50,0x70,0x93,0x46,0x3F,0x14,0x46,0x4B,0xEB,0x84, -0x4F,0x80,0x06,0x00,0x00,0x48,0x84,0x4F,0x74,0x0E,0x00,0x02,0x47,0x83,0x46,0x7B, -0x14,0x84,0x47,0x40,0x9C,0x04,0x47,0x84,0x48,0x41,0x9C,0x04,0x48,0x84,0x51,0x50, -0x70,0x93,0x46,0x3F,0x14,0x46,0x4B,0xEB,0x84,0x4F,0xD0,0x06,0x00,0x00,0x48,0x84, -0x4F,0x14,0x0F,0x00,0x02,0x47,0x83,0x46,0x7B,0x14,0x84,0x47,0x40,0x9C,0x04,0x47, -0x84,0x48,0x41,0x9C,0x04,0x48,0x84,0x51,0x50,0x70,0x93,0x46,0x3F,0x14,0x46,0x4B, -0xEB,0x84,0x4F,0xD0,0x0E,0x00,0x02,0x48,0x04,0x7F,0xC4,0x0E,0x00,0x02,0x4D,0x24, -0x7F,0xED,0x3A,0x00,0x00,0x04,0xC9,0xF4,0x4C,0x20,0x48,0x20,0x47,0x20,0x46,0x20, -0x49,0x08,0x70,0x70,0x10,0x49,0x9C,0x4F,0x08,0x00,0x00,0x00,0x4C,0x84,0x4F,0x00, -0x90,0x04,0x00,0x7F,0x64,0x0F,0x00,0x02,0x70,0x2C,0x5C,0x7F,0x90,0x54,0x00,0x00, -0x2C,0x5C,0xAF,0x60,0x05,0x87,0x40,0x59,0x70,0x2B,0x59,0x77,0x0A,0x24,0x7F,0xA1, -0x33,0x00,0x00,0x7B,0x0D,0x3F,0x02,0x59,0x77,0x08,0x24,0x7F,0xC1,0x2D,0x00,0x00, -0xB0,0x4F,0x00,0x00,0x00,0x80,0x7F,0x5C,0x08,0x00,0x02,0x70,0x2C,0x5C,0xAF,0xCC, -0x02,0x2C,0x5C,0x7F,0x84,0x43,0x00,0x00,0x84,0x40,0xEF,0xE4,0x04,0x00,0x00,0x70, -0x84,0x4F,0x5C,0x2C,0x00,0x02,0xEF,0xE8,0x04,0x00,0x00,0x70,0x9C,0x20,0xEF,0xE8, -0x04,0x00,0x00,0x70,0x87,0x00,0xE0,0x40,0xC8,0x03,0x0C,0x40,0xEF,0x90,0x04,0x00, -0x00,0x70,0x87,0x01,0xE0,0x40,0xC8,0x0F,0x10,0x40,0xEF,0x90,0x04,0x00,0x00,0x70, -0xDC,0x04,0x7F,0x90,0x04,0x00,0x00,0x40,0x87,0x01,0xE0,0x41,0xC8,0x00,0x05,0x41, -0x50,0x70,0xDC,0x04,0x7F,0x90,0x04,0x00,0x00,0x40,0x87,0x01,0xE0,0x41,0xC8,0x00, -0x06,0x41,0x50,0x70,0xDC,0x0C,0x7F,0x90,0x04,0x00,0x00,0x40,0xA0,0x40,0xA0,0x4F, -0x20,0x07,0x00,0x00,0x2C,0xCC,0xF8,0x7F,0x6C,0xEA,0x00,0x00,0xDC,0x04,0x7F,0x90, -0x04,0x00,0x00,0x40,0x87,0x01,0xE0,0x41,0xC8,0x00,0x07,0x41,0x50,0x70,0xDC,0x04, -0x7F,0x90,0x04,0x00,0x00,0x40,0x87,0x01,0xE0,0x41,0xC8,0x00,0x09,0x41,0x50,0x70, -0x84,0x4F,0xF4,0x79,0x00,0x00,0xEF,0x98,0x04,0x00,0x00,0x70,0x84,0x4F,0xF4,0x79, -0x00,0x00,0xEF,0x0C,0x05,0x00,0x00,0x70,0x2C,0x5C,0xAF,0x74,0x03,0x87,0x01,0x7F, -0x1F,0x40,0x04,0x00,0x70,0x83,0x7F,0x6E,0x0F,0x00,0x02,0x70,0x87,0x01,0xEF,0xE0, -0x04,0x00,0x00,0x70,0x83,0x7F,0x6D,0x0F,0x00,0x02,0x70,0x84,0x4F,0xA0,0x3D,0x00, -0x00,0xEF,0x98,0x04,0x00,0x00,0x70,0x84,0x4F,0xA0,0x3D,0x00,0x00,0xEF,0x0C,0x05, -0x00,0x00,0x70,0x2C,0x5C,0xEF,0xC0,0x04,0x00,0x00,0x24,0x7F,0xF9,0x3C,0x00,0x00, -0x87,0x7F,0x6D,0x0F,0x00,0x02,0xE0,0x40,0xD0,0x15,0x40,0x40,0x83,0xC0,0x05,0x70, -0xA0,0x14,0x2C,0xCC,0xFC,0xEF,0x28,0x05,0x00,0x00,0x87,0xEF,0xE0,0x04,0x00,0x00, -0xE0,0x40,0xD0,0x05,0x40,0x40,0x9C,0x7F,0x90,0x04,0x00,0x00,0x40,0x87,0x7F,0x6D, -0x0F,0x00,0x02,0xE0,0x41,0xD0,0x15,0x41,0x41,0x87,0xC1,0x01,0xE0,0x42,0xC8,0x0F, -0x10,0x42,0x50,0x70,0x9C,0x20,0xEF,0xE8,0x04,0x00,0x00,0x70,0x87,0xEF,0xE0,0x04, -0x00,0x00,0x40,0x93,0xEF,0xE0,0x04,0x00,0x00,0x70,0x87,0x40,0xE0,0x40,0xD0,0x05, -0x40,0x40,0x9C,0x7F,0x90,0x04,0x00,0x00,0x40,0x87,0x7F,0x6D,0x0F,0x00,0x02,0xE0, -0x41,0xC8,0x03,0x0C,0x41,0x50,0x70,0x87,0x7F,0x6D,0x0F,0x00,0x02,0xE0,0x40,0xD0, -0x15,0x40,0x40,0x87,0x50,0xE2,0x40,0x86,0x40,0x62,0x70,0x97,0xEF,0xE0,0x04,0x00, -0x00,0x70,0x87,0xEF,0xE0,0x04,0x00,0x00,0xE0,0x40,0xD0,0x05,0x40,0x40,0x9C,0x7F, -0x90,0x04,0x00,0x00,0x40,0x84,0x40,0x64,0x70,0xCC,0x0F,0x10,0xD9,0x04,0x40,0x86, -0xE2,0x62,0xE0,0x41,0xD0,0x08,0x41,0x41,0xB0,0x41,0x40,0xC8,0x0F,0x10,0x40,0xD9, -0x04,0x70,0x93,0xEF,0xE0,0x04,0x00,0x00,0x70,0x93,0x7F,0x6D,0x0F,0x00,0x02,0x70, -0x3F,0x0C,0x7F,0x6D,0x0F,0x00,0x02,0x4E,0x29,0xFF,0x84,0x4F,0xF4,0x79,0x00,0x00, -0xEF,0x98,0x04,0x00,0x00,0x70,0x84,0x4F,0xF4,0x79,0x00,0x00,0xEF,0x0C,0x05,0x00, -0x00,0x70,0xDC,0x02,0x7F,0xA4,0x04,0x00,0x00,0x40,0x2B,0x50,0x7F,0x24,0x2C,0x5C, -0xAF,0x2E,0x02,0x2C,0x5C,0x7F,0xB8,0x77,0x00,0x00,0x3C,0x01,0x40,0x77,0x13,0xB0, -0x4F,0x00,0x00,0x00,0x80,0x7F,0x5C,0x08,0x00,0x02,0x70,0x2C,0x5C,0xAF,0xAD,0x00, -0x3C,0x4F,0xEF,0xBE,0xED,0xFE,0x7F,0x64,0x08,0x00,0x02,0x7F,0x32,0x3C,0x4F,0x0D, -0xF0,0xAD,0x8B,0x7F,0x64,0x08,0x00,0x02,0x7F,0x25,0x3C,0x4F,0x1E,0xAC,0xEB,0xAD, -0x7F,0x64,0x08,0x00,0x02,0x7F,0x18,0x2C,0x5C,0xAF,0x65,0x02,0x28,0x40,0x77,0x0F, -0xB0,0x20,0x7F,0x5C,0x08,0x00,0x02,0x70,0x2C,0x5C,0xAF,0x70,0x00,0x2C,0x5C,0xAF, -0xCF,0x01,0x24,0x7F,0x65,0x34,0x00,0x00,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70, -0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x86,0xE2,0x7F,0x02,0x40,0x04,0x00, -0xE0,0x40,0x38,0x40,0x4F,0x00,0x80,0x00,0x00,0x7F,0x0C,0x87,0x01,0x7F,0x27,0x40, -0x04,0x00,0x70,0x7B,0x2E,0x84,0x4F,0xEF,0xBE,0xED,0xFE,0xEF,0x8C,0x04,0x00,0x00, -0x70,0x2C,0x5C,0xAF,0x8B,0x01,0x87,0x01,0x7F,0x1F,0x40,0x04,0x00,0x70,0xB0,0x04, -0x7F,0x5C,0x08,0x00,0x02,0x70,0x2C,0x5C,0xAF,0x12,0x00,0x24,0x7F,0x38,0x7B,0x00, -0x00,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00, -0x4C,0x2C,0x5C,0xAF,0x5B,0x01,0x87,0x01,0xEF,0xC4,0x04,0x00,0x00,0x70,0x3C,0x4F, -0x00,0x00,0x00,0x80,0x7F,0x5C,0x08,0x00,0x02,0x77,0x29,0x3C,0x4F,0xEF,0xBE,0xED, -0xFE,0x7F,0x64,0x08,0x00,0x02,0x7F,0x1C,0xA0,0x4F,0x24,0x07,0x00,0x00,0x2C,0xCC, -0xFC,0x7F,0xA8,0x5C,0x00,0x00,0xB8,0x4F,0xFF,0xFF,0xFF,0x7F,0x7F,0x5C,0x08,0x00, -0x02,0x70,0x38,0x7F,0x5C,0x08,0x00,0x02,0x01,0x7F,0x2C,0xA0,0x4F,0x32,0x07,0x00, -0x00,0x2C,0xCC,0xFC,0x7F,0xA8,0x5C,0x00,0x00,0xA0,0x4F,0x59,0x07,0x00,0x00,0x2C, -0xCC,0xFC,0x7F,0xA8,0x5C,0x00,0x00,0xA0,0x4F,0x81,0x07,0x00,0x00,0x2C,0xCC,0xFC, -0x7F,0xA8,0x5C,0x00,0x00,0x38,0x7F,0x5C,0x08,0x00,0x02,0x02,0x7F,0x10,0xA0,0x4F, -0xB1,0x07,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xA8,0x5C,0x00,0x00,0x38,0x7F,0x5C,0x08, -0x00,0x02,0x04,0x7F,0x10,0xA0,0x4F,0xD7,0x07,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xA8, -0x5C,0x00,0x00,0x38,0x7F,0x5C,0x08,0x00,0x02,0x08,0x7F,0x10,0xA0,0x4F,0x04,0x08, -0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xA8,0x5C,0x00,0x00,0x38,0x7F,0x5C,0x08,0x00,0x02, -0x10,0x7F,0x10,0xA0,0x4F,0x23,0x08,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xA8,0x5C,0x00, -0x00,0x38,0x7F,0x5C,0x08,0x00,0x02,0x20,0x7F,0x10,0xA0,0x4F,0x4F,0x08,0x00,0x00, -0x2C,0xCC,0xFC,0x7F,0xA8,0x5C,0x00,0x00,0x38,0x7F,0x5C,0x08,0x00,0x02,0x6F,0x40, -0x7F,0x10,0xA0,0x4F,0x75,0x08,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xA8,0x5C,0x00,0x00, -0x38,0x7F,0x5C,0x08,0x00,0x02,0x4F,0x00,0x00,0x01,0x00,0x7F,0x10,0xA0,0x4F,0xAE, -0x08,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xA8,0x5C,0x00,0x00,0x3C,0x01,0x7F,0x5C,0x08, -0x00,0x02,0x4F,0x1D,0x3C,0x4F,0x00,0x00,0x01,0x00,0x7F,0x5C,0x08,0x00,0x02,0x43, -0x10,0xA0,0x4F,0xDB,0x08,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xA8,0x5C,0x00,0x00,0xDC, -0x04,0x7F,0xA4,0x04,0x00,0x00,0x40,0x3F,0x01,0x50,0x77,0x09,0x80,0x7F,0x5C,0x08, -0x00,0x02,0x70,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x10,0x49,0x9C,0x4F, -0x00,0x00,0x00,0x00,0x4C,0x87,0x01,0x7F,0x03,0x40,0x04,0x00,0x70,0x87,0x01,0x7F, -0x07,0x40,0x04,0x00,0x70,0x87,0x01,0x7F,0x0F,0x40,0x04,0x00,0x70,0x87,0x01,0x7F, -0x3F,0x40,0x04,0x00,0x70,0x87,0x01,0x7F,0x37,0x40,0x04,0x00,0x70,0x87,0x01,0x7F, -0x0D,0x80,0x04,0x00,0x70,0x87,0x7F,0x11,0x90,0x04,0x00,0x7F,0x6E,0x0F,0x00,0x02, -0x70,0x87,0x7F,0x00,0xD0,0x04,0x00,0x7F,0x6E,0x0F,0x00,0x02,0x70,0x87,0x6F,0x56, -0x7F,0x0F,0x20,0x04,0x00,0x70,0x87,0x7F,0x13,0x20,0x04,0x00,0x7F,0x6E,0x0F,0x00, -0x02,0x70,0x87,0x01,0x7F,0x27,0x40,0x04,0x00,0x70,0x87,0x01,0x7F,0x2F,0x40,0x04, -0x00,0x70,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x70,0x10,0x47,0x9C,0x4F, -0x00,0x00,0x00,0x00,0x4C,0x84,0x4F,0x00,0x40,0x00,0x02,0x48,0x84,0x4F,0x00,0x00, -0x04,0x02,0x47,0x7B,0x3B,0x87,0x5F,0xFF,0x00,0x58,0x70,0x3F,0x5F,0xFF,0x00,0x58, -0x7F,0x04,0x7B,0x31,0x87,0x5F,0xAA,0x00,0x58,0x70,0x3F,0x5F,0xAA,0x00,0x58,0x7F, -0x04,0x7B,0x22,0x87,0x6F,0x55,0x58,0x70,0x3F,0x6F,0x55,0x58,0x7F,0x04,0x7B,0x15, -0x83,0x58,0x70,0x84,0x48,0x40,0x90,0x48,0x2B,0x50,0x7F,0x04,0x7B,0x07,0x3C,0x47, -0x48,0x5B,0xC4,0x3C,0x47,0x48,0x53,0x1A,0xB0,0x20,0x7F,0x5C,0x08,0x00,0x02,0x70, -0x84,0x4F,0xEF,0xBE,0xED,0xFE,0x7F,0x64,0x08,0x00,0x02,0x70,0x80,0x40,0x7B,0x07, -0x84,0x01,0x40,0x7B,0x02,0x04,0xC9,0xF0,0x4C,0x20,0x48,0x20,0x47,0x20,0x49,0x08, -0x10,0x49,0x9C,0x4F,0x04,0x00,0x00,0x00,0x4C,0x87,0x20,0x7F,0x02,0x90,0x04,0x00, -0x70,0x87,0x30,0x7F,0x02,0x90,0x04,0x00,0x70,0x87,0x10,0x7F,0x02,0x90,0x04,0x00, -0x70,0x87,0x7F,0x00,0x90,0x04,0x00,0xE2,0x40,0x86,0x40,0x59,0x70,0xB3,0x5F,0x80, -0x00,0x7F,0x00,0x90,0x04,0x00,0x70,0x87,0x05,0x7F,0x02,0x90,0x04,0x00,0x70,0x82, -0x59,0x70,0x7B,0x05,0x92,0x59,0x70,0x3E,0x5F,0xFF,0x00,0x59,0x4B,0xF8,0x87,0x6F, -0x55,0x7F,0x03,0x90,0x04,0x00,0x70,0x82,0x59,0x70,0x7B,0x29,0x86,0x5F,0xE2,0x04, -0x62,0x70,0x7B,0x02,0x86,0x62,0x40,0x96,0x62,0x70,0x2A,0x40,0x47,0xF8,0x86,0x59, -0x40,0x92,0x59,0x70,0x3E,0x5F,0xFF,0x00,0x40,0x4F,0x0A,0x80,0x40,0x24,0x7F,0x7A, -0x43,0x00,0x00,0x3B,0x7F,0x01,0x90,0x04,0x00,0x01,0x7F,0xD2,0x3F,0x6F,0x55,0x7F, -0x03,0x90,0x04,0x00,0x7F,0x0A,0x80,0x40,0x24,0x7F,0x7A,0x43,0x00,0x00,0x3B,0x7F, -0x01,0x90,0x04,0x00,0x01,0x7F,0x0A,0x80,0x40,0x24,0x7F,0x7A,0x43,0x00,0x00,0x87, -0x5F,0xAA,0x00,0x7F,0x03,0x90,0x04,0x00,0x70,0x82,0x59,0x70,0x7B,0x29,0x86,0x5F, -0xE2,0x04,0x62,0x70,0x7B,0x02,0x86,0x62,0x40,0x96,0x62,0x70,0x2A,0x40,0x47,0xF8, -0x86,0x59,0x40,0x92,0x59,0x70,0x3E,0x5F,0xFF,0x00,0x40,0x4F,0x0A,0x80,0x40,0x24, -0x7F,0x7A,0x43,0x00,0x00,0x3B,0x7F,0x01,0x90,0x04,0x00,0x01,0x7F,0xD2,0x3F,0x5F, -0xAA,0x00,0x7F,0x03,0x90,0x04,0x00,0x7F,0x0A,0x80,0x40,0x24,0x7F,0x7A,0x43,0x00, -0x00,0x87,0x20,0x7F,0x02,0x90,0x04,0x00,0x70,0x87,0x30,0x7F,0x02,0x90,0x04,0x00, -0x70,0x87,0x10,0x7F,0x02,0x90,0x04,0x00,0x70,0x87,0x7F,0x00,0x90,0x04,0x00,0xE2, -0x40,0x86,0x40,0x59,0x70,0xBB,0x6F,0x7F,0x7F,0x00,0x90,0x04,0x00,0x70,0x87,0x05, -0x7F,0x02,0x90,0x04,0x00,0x70,0x82,0x59,0x70,0x7B,0x05,0x92,0x59,0x70,0x3E,0x5F, -0xFF,0x00,0x59,0x4B,0xF8,0x87,0x20,0x7F,0x0A,0x90,0x04,0x00,0x70,0x87,0x30,0x7F, -0x0A,0x90,0x04,0x00,0x70,0x87,0x10,0x7F,0x0A,0x90,0x04,0x00,0x70,0x87,0x7F,0x08, -0x90,0x04,0x00,0xE2,0x40,0x86,0x40,0x59,0x70,0xB3,0x5F,0x80,0x00,0x7F,0x08,0x90, -0x04,0x00,0x70,0x87,0x05,0x7F,0x0A,0x90,0x04,0x00,0x70,0x82,0x59,0x70,0x7B,0x05, -0x92,0x59,0x70,0x3E,0x5F,0xFF,0x00,0x59,0x4B,0xF8,0x87,0x6F,0x55,0x7F,0x0B,0x90, -0x04,0x00,0x70,0x82,0x59,0x70,0x7B,0x29,0x86,0x5F,0xE2,0x04,0x62,0x70,0x7B,0x02, -0x86,0x62,0x40,0x96,0x62,0x70,0x2A,0x40,0x47,0xF8,0x86,0x59,0x40,0x92,0x59,0x70, -0x3E,0x5F,0xFF,0x00,0x40,0x4F,0x0A,0x80,0x40,0x24,0x7F,0x7A,0x43,0x00,0x00,0x3B, -0x7F,0x09,0x90,0x04,0x00,0x01,0x7F,0xD2,0x3F,0x6F,0x55,0x7F,0x0B,0x90,0x04,0x00, -0x7F,0x0A,0x80,0x40,0x24,0x7F,0x7A,0x43,0x00,0x00,0x3B,0x7F,0x09,0x90,0x04,0x00, -0x01,0x7F,0x0A,0x80,0x40,0x24,0x7F,0x7A,0x43,0x00,0x00,0x87,0x5F,0xAA,0x00,0x7F, -0x0B,0x90,0x04,0x00,0x70,0x82,0x59,0x70,0x7B,0x29,0x86,0x5F,0xE2,0x04,0x62,0x70, -0x7B,0x02,0x86,0x62,0x40,0x96,0x62,0x70,0x2A,0x40,0x47,0xF8,0x86,0x59,0x40,0x92, -0x59,0x70,0x3E,0x5F,0xFF,0x00,0x40,0x4F,0x0A,0x80,0x40,0x24,0x7F,0x7A,0x43,0x00, -0x00,0x3B,0x7F,0x09,0x90,0x04,0x00,0x01,0x7F,0xD2,0x3F,0x5F,0xAA,0x00,0x7F,0x0B, -0x90,0x04,0x00,0x7F,0x0A,0x80,0x40,0x24,0x7F,0x7A,0x43,0x00,0x00,0x87,0x20,0x7F, -0x0A,0x90,0x04,0x00,0x70,0x87,0x30,0x7F,0x0A,0x90,0x04,0x00,0x70,0x87,0x10,0x7F, -0x0A,0x90,0x04,0x00,0x70,0x87,0x7F,0x08,0x90,0x04,0x00,0xE0,0x40,0xD0,0x08,0x40, -0x40,0x87,0x7F,0x08,0x90,0x04,0x00,0xE2,0x41,0xBA,0x5F,0x7F,0xFF,0x41,0xB2,0x41, -0x40,0x86,0x40,0x62,0x70,0x87,0x10,0x7F,0x02,0x90,0x04,0x00,0x70,0x87,0x10,0x7F, -0x0A,0x90,0x04,0x00,0x70,0x87,0x7F,0x00,0x90,0x04,0x00,0x7F,0x08,0x90,0x04,0x00, -0x70,0x87,0x7F,0x00,0x90,0x04,0x00,0x7F,0x08,0x90,0x04,0x00,0x70,0x87,0x05,0x7F, -0x0A,0x90,0x04,0x00,0x70,0x82,0x59,0x70,0x7B,0x05,0x92,0x59,0x70,0x3E,0x5F,0xFF, -0x00,0x59,0x4B,0xF8,0x87,0x20,0x7F,0x03,0x90,0x04,0x00,0x70,0xA0,0x02,0x2C,0xCC, -0xFC,0xEF,0x28,0x05,0x00,0x00,0x3B,0x7F,0x09,0x90,0x04,0x00,0x01,0x7F,0x10,0x3F, -0x20,0x7F,0x0B,0x90,0x04,0x00,0x77,0x07,0x84,0x02,0x40,0x7B,0x3F,0x87,0x20,0x7F, -0x0A,0x90,0x04,0x00,0x70,0x87,0x30,0x7F,0x0A,0x90,0x04,0x00,0x70,0x87,0x10,0x7F, -0x0A,0x90,0x04,0x00,0x70,0x86,0x62,0xE4,0x40,0xD4,0x08,0x40,0x40,0x87,0x40,0x7F, -0x08,0x90,0x04,0x00,0x70,0x87,0x63,0x7F,0x08,0x90,0x04,0x00,0x70,0x87,0x05,0x7F, -0x0A,0x90,0x04,0x00,0x70,0x84,0x01,0x40,0x7B,0x02,0x04,0xC9,0xE8,0x4C,0x20,0x49, -0x08,0x70,0x70,0x70,0x10,0x45,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x84,0x4F,0xCC, -0x44,0x00,0x00,0x7F,0x70,0x0F,0x00,0x02,0x70,0x84,0x4F,0xE4,0x44,0x00,0x00,0x7F, -0x74,0x0F,0x00,0x02,0x70,0x83,0xEF,0xC4,0x04,0x00,0x00,0x70,0x83,0x7F,0x6E,0x0F, -0x00,0x02,0x70,0x80,0x46,0x3B,0x7F,0x03,0xC0,0x04,0x00,0x01,0x7F,0x0E,0x84,0x4F, -0x00,0x00,0x10,0x00,0x48,0x84,0x48,0x40,0x7B,0x0C,0x84,0x4F,0x00,0x00,0x04,0x00, -0x48,0x84,0x48,0x40,0x3B,0x7F,0x03,0xC0,0x04,0x00,0x02,0x7F,0x06,0xD0,0x01,0x48, -0x48,0x2C,0x5C,0xEF,0xC0,0x04,0x00,0x00,0x2B,0x7F,0x6E,0x0F,0x00,0x02,0x7F,0x08, -0x24,0x7F,0x9F,0x44,0x00,0x00,0x3C,0x4F,0xD0,0xF1,0x02,0x3B,0x7F,0x6C,0x08,0x00, -0x02,0x77,0x09,0x84,0x88,0x00,0x00,0x00,0x02,0x47,0x84,0x4F,0xEF,0xBE,0xED,0xFE, -0x88,0x00,0x00,0x00,0x02,0x70,0x3C,0x4F,0xEF,0xBE,0xED,0xFE,0x88,0x00,0x00,0x00, -0x02,0x77,0x05,0x84,0x01,0x46,0x84,0x47,0x88,0x00,0x00,0x00,0x02,0x70,0x28,0x46, -0x7F,0x6F,0x3C,0x4F,0x00,0x00,0x20,0x00,0x48,0x77,0x66,0xE8,0x03,0x48,0x40,0xAC, -0x04,0x40,0x70,0x84,0x40,0x48,0xD0,0x01,0x48,0x40,0x84,0x40,0x45,0x83,0x7F,0x6E, -0x0F,0x00,0x02,0x70,0x2C,0x5C,0xEF,0xC0,0x04,0x00,0x00,0x2B,0x7F,0x6E,0x0F,0x00, -0x02,0x77,0x3E,0x3C,0x4F,0xD0,0xF1,0x02,0x3B,0x7F,0x6C,0x08,0x00,0x02,0x77,0x09, -0x84,0x85,0x00,0x00,0x00,0x02,0x47,0x84,0x4F,0xEF,0xBE,0xED,0xFE,0x85,0x00,0x00, -0x00,0x02,0x70,0x3C,0x4F,0xEF,0xBE,0xED,0xFE,0x85,0x00,0x00,0x00,0x02,0x77,0x09, -0x84,0x4F,0x00,0x00,0x20,0x00,0x48,0x84,0x47,0x85,0x00,0x00,0x00,0x02,0x70,0x84, -0x4F,0xF4,0x79,0x00,0x00,0x7F,0x70,0x0F,0x00,0x02,0x70,0x84,0x4F,0x44,0x79,0x00, -0x00,0x7F,0x74,0x0F,0x00,0x02,0x70,0xD0,0x46,0x48,0x40,0x7B,0x02,0x04,0xC9,0xF8, -0x4C,0x20,0x48,0x20,0x47,0x20,0x46,0x20,0x45,0x20,0x49,0x08,0x10,0x49,0x9C,0x4F, -0x00,0x00,0x00,0x00,0x4C,0x87,0x01,0x7F,0x6E,0x0F,0x00,0x02,0x70,0x04,0xC9,0xE8, -0x4C,0x20,0x49,0x08,0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x84,0x4F,0x00, -0xE1,0x81,0x00,0xCD,0x0C,0x70,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x70, -0x84,0xCC,0xF8,0x7F,0x78,0x0F,0x00,0x02,0x70,0x08,0x70,0x70,0x10,0x49,0x9C,0x4F, -0x74,0x01,0x00,0x00,0x4C,0xA0,0x4F,0x0D,0x30,0x04,0x00,0xE0,0x59,0xA0,0x2D,0x2C, -0xCC,0xF4,0x7F,0x50,0x6B,0x00,0x00,0xA0,0x4F,0x00,0x09,0x00,0x00,0xE0,0x59,0x2C, -0xCC,0xF8,0x7F,0xA8,0x5C,0x00,0x00,0xA0,0x00,0x2C,0xCC,0xFC,0xEF,0x40,0x05,0x00, -0x00,0xDC,0x02,0x7F,0xA0,0x04,0x00,0x00,0x40,0xA0,0x40,0x2C,0xCC,0xFC,0x7F,0xCC, -0x5A,0x00,0x00,0x3C,0xFF,0x40,0x77,0x20,0xA0,0x01,0x2C,0xCC,0xFC,0xEF,0x40,0x05, -0x00,0x00,0xA0,0x4F,0x2B,0x09,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xA8,0x5C,0x00,0x00, -0x24,0x7F,0xA2,0x53,0x00,0x00,0xA0,0x01,0x2C,0xCC,0xFC,0xEF,0x40,0x05,0x00,0x00, -0xDC,0x02,0x7F,0xA0,0x04,0x00,0x00,0x40,0xA0,0x40,0xA0,0x4F,0x2D,0x09,0x00,0x00, -0x2C,0xCC,0xF8,0x7F,0xE4,0xE9,0x00,0x00,0x28,0x40,0x7F,0x08,0x24,0x7F,0x73,0x46, -0x00,0x00,0xA0,0x4F,0x34,0x09,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xA8,0x5C,0x00,0x00, -0xE0,0xC9,0x50,0x2C,0xCC,0xFC,0xAF,0xF7,0x0D,0x28,0x40,0x77,0x07,0x2C,0x5C,0xAF, -0x47,0x0E,0xA0,0x4F,0x00,0x30,0x04,0x00,0xE0,0xC9,0x5A,0xA0,0x09,0x2C,0xCC,0xF4, -0x7F,0x50,0x6B,0x00,0x00,0xE0,0xC9,0x50,0xE0,0xC9,0x5A,0x2C,0xCC,0xF8,0x7F,0xE4, -0xE9,0x00,0x00,0x28,0x40,0x7F,0x07,0x2C,0x5C,0xAF,0x1D,0x0E,0xA0,0x4F,0x4A,0x09, -0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xA8,0x5C,0x00,0x00,0xE0,0x59,0x2C,0xCC,0xFC,0xAF, -0xAE,0x0D,0x28,0x40,0x77,0x07,0x2C,0x5C,0xAF,0xFE,0x0D,0xA0,0x4F,0x60,0x09,0x00, -0x00,0x2C,0xCC,0xFC,0x7F,0xA8,0x5C,0x00,0x00,0xE0,0xC9,0x50,0x2C,0xCC,0xFC,0xAF, -0x8E,0x0D,0x28,0x40,0x77,0x07,0x2C,0x5C,0xAF,0xDE,0x0D,0xE0,0xC9,0x50,0xE0,0x59, -0x2C,0xCC,0xF8,0x7F,0xE4,0xE9,0x00,0x00,0x28,0x40,0x7F,0x07,0x2C,0x5C,0xAF,0xC8, -0x0D,0xA0,0x4F,0x70,0x09,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xA8,0x5C,0x00,0x00,0xE0, -0x59,0xA0,0x4F,0x00,0x30,0x04,0x00,0xE0,0x59,0x2C,0xCC,0xFC,0x7F,0x14,0xEA,0x00, -0x00,0x90,0x40,0xA0,0x40,0x2C,0xCC,0xF4,0x7F,0xCC,0x6B,0x00,0x00,0x24,0x7F,0x9F, -0x53,0x00,0x00,0xDC,0x02,0x7F,0xA0,0x04,0x00,0x00,0x40,0xA0,0x40,0xA0,0x4F,0x72, -0x09,0x00,0x00,0x2C,0xCC,0xF8,0x7F,0xE4,0xE9,0x00,0x00,0x28,0x40,0x7F,0x08,0x24, -0x7F,0x62,0x47,0x00,0x00,0xA0,0x4F,0x79,0x09,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xA8, -0x5C,0x00,0x00,0x83,0x59,0x70,0x7B,0x26,0xA0,0x4F,0xC3,0x09,0x00,0x00,0x2C,0xCC, -0xFC,0x7F,0xA8,0x5C,0x00,0x00,0xE0,0x59,0x2C,0xCC,0xFC,0x7F,0xCC,0x5A,0x00,0x00, -0x3F,0x6F,0x71,0x59,0x77,0x08,0x24,0x7F,0xA2,0x53,0x00,0x00,0xE0,0x59,0xA0,0x4F, -0xC0,0x09,0x00,0x00,0x2C,0xCC,0xF8,0x7F,0xE4,0xE9,0x00,0x00,0x28,0x40,0x77,0xCA, -0xDC,0x03,0x7F,0x08,0x05,0x00,0x00,0x40,0x87,0x50,0xC9,0x5A,0x70,0xDC,0x07,0x7F, -0x08,0x05,0x00,0x00,0x40,0x87,0x50,0xC9,0x5B,0x70,0xDC,0x0B,0x7F,0x08,0x05,0x00, -0x00,0x40,0x87,0x50,0xC9,0x5C,0x70,0xDC,0x0F,0x7F,0x08,0x05,0x00,0x00,0x40,0x87, -0x50,0xC9,0x5D,0x70,0xA0,0x00,0xE0,0xC9,0x5A,0xA0,0x01,0xA0,0x03,0x2C,0xCC,0xF0, -0x7F,0xCC,0x8F,0x00,0x00,0x28,0x40,0x77,0x27,0x84,0x10,0x7F,0x5C,0x08,0x00,0x02, -0x70,0x2C,0x5C,0x7F,0xF8,0x3D,0x00,0x00,0x84,0x4F,0xEF,0xBE,0xED,0xFE,0xEF,0x8C, -0x04,0x00,0x00,0x70,0x87,0x01,0x7F,0x0B,0x40,0x04,0x00,0x70,0x7B,0x00,0xA0,0x4F, -0xFB,0x09,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xA8,0x5C,0x00,0x00,0x24,0x7F,0x9F,0x53, -0x00,0x00,0xDC,0x02,0x7F,0xA0,0x04,0x00,0x00,0x40,0xA0,0x40,0xA0,0x4F,0x1E,0x0A, -0x00,0x00,0x2C,0xCC,0xF8,0x7F,0xE4,0xE9,0x00,0x00,0x28,0x40,0x77,0x1F,0x2C,0x5C, -0x7F,0x00,0x40,0x00,0x02,0x84,0x4F,0xEF,0xBE,0xED,0xFE,0xEF,0x8C,0x04,0x00,0x00, -0x70,0x87,0x01,0x7F,0x0B,0x40,0x04,0x00,0x70,0x7B,0x00,0xDC,0x02,0x7F,0xA0,0x04, -0x00,0x00,0x40,0xA0,0x40,0xA0,0x4F,0x26,0x0A,0x00,0x00,0x2C,0xCC,0xF8,0x7F,0xE4, -0xE9,0x00,0x00,0x28,0x40,0x7F,0x08,0x24,0x7F,0x4A,0x48,0x00,0x00,0xA0,0x4F,0x2E, -0x0A,0x00,0x00,0xA0,0x4F,0x10,0x14,0x00,0x00,0x2C,0xCC,0xF8,0x7F,0xA8,0x5C,0x00, -0x00,0xA0,0x4F,0x3C,0x0A,0x00,0x00,0xA0,0x7F,0xF0,0xFF,0x00,0x00,0x2C,0xCC,0xF8, -0x7F,0xA8,0x5C,0x00,0x00,0xA0,0x4F,0x4A,0x0A,0x00,0x00,0xA0,0x4F,0x24,0x14,0x00, -0x00,0xA0,0x4F,0x1C,0x14,0x00,0x00,0x2C,0xCC,0xF4,0x7F,0xA8,0x5C,0x00,0x00,0xA0, -0x4F,0x60,0x0A,0x00,0x00,0x87,0x7F,0xF3,0xFF,0x00,0x00,0xE0,0x40,0xD0,0x08,0x40, -0x40,0x87,0x7F,0xF7,0xFF,0x00,0x00,0xE0,0x41,0xB0,0x41,0x40,0xD0,0x08,0x40,0x40, -0x87,0x7F,0xFB,0xFF,0x00,0x00,0xE0,0x41,0xB0,0x41,0x40,0xD0,0x08,0x40,0x40,0x87, -0x7F,0xFF,0xFF,0x00,0x00,0xE0,0x41,0xB0,0x41,0x40,0xA0,0x40,0x2C,0xCC,0xF8,0x7F, -0xA8,0x5C,0x00,0x00,0x24,0x7F,0x9F,0x53,0x00,0x00,0xDC,0x02,0x7F,0xA0,0x04,0x00, -0x00,0x40,0xA0,0x40,0xA0,0x4F,0x77,0x0A,0x00,0x00,0x2C,0xCC,0xF8,0x7F,0xE4,0xE9, -0x00,0x00,0x28,0x40,0x77,0x08,0x24,0x7F,0xA2,0x53,0x00,0x00,0xDC,0x02,0x7F,0xA0, -0x04,0x00,0x00,0x40,0xA0,0x40,0xA0,0x4F,0x79,0x0A,0x00,0x00,0x2C,0xCC,0xF8,0x7F, -0xE4,0xE9,0x00,0x00,0x28,0x40,0x77,0x0F,0x2C,0x5C,0x7F,0x40,0x67,0x00,0x00,0x24, -0x7F,0x9F,0x53,0x00,0x00,0xDC,0x02,0x7F,0xA0,0x04,0x00,0x00,0x40,0xA0,0x40,0xA0, -0x4F,0x7D,0x0A,0x00,0x00,0x2C,0xCC,0xF8,0x7F,0xE4,0xE9,0x00,0x00,0x28,0x40,0x77, -0x32,0xA0,0x4F,0x7F,0x0A,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xA8,0x5C,0x00,0x00,0xA0, -0x4F,0xB7,0x0A,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xA8,0x5C,0x00,0x00,0xA0,0x4F,0xE8, -0x0A,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xA8,0x5C,0x00,0x00,0x24,0x7F,0x9F,0x53,0x00, -0x00,0xDC,0x02,0x7F,0xA0,0x04,0x00,0x00,0x40,0x2B,0x50,0x77,0x16,0xDC,0x02,0x7F, -0xA0,0x04,0x00,0x00,0x40,0xA0,0x40,0xE0,0x59,0x2C,0xCC,0xF8,0x7F,0x6C,0xEA,0x00, -0x00,0x82,0xC9,0x70,0x70,0x7B,0x55,0x04,0xC9,0x74,0x40,0x86,0xC9,0x70,0xE4,0x41, -0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x82,0x50,0x70,0x04,0xC9,0x74,0x40,0x86,0xC9, -0x70,0xE4,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x82,0xC0,0x02,0x70,0x04,0xC9, -0x74,0x40,0x86,0xC9,0x70,0xE4,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x82,0xC0, -0x04,0x70,0x04,0xC9,0x74,0x40,0x86,0xC9,0x70,0xE4,0x41,0xD0,0x04,0x41,0x41,0x9C, -0x41,0x40,0x83,0xC0,0x06,0x70,0x92,0xC9,0x70,0x70,0x3E,0x10,0xC9,0x70,0x4B,0xA9, -0x83,0xC9,0x66,0x70,0x04,0xC9,0x74,0x40,0x87,0xC9,0x66,0xE0,0x41,0xD0,0x04,0x41, -0x41,0x9C,0x41,0x40,0x9C,0x06,0x40,0xA0,0x40,0xDC,0x08,0x7F,0x90,0x04,0x00,0x00, -0x40,0xDC,0x02,0x50,0x40,0xA0,0x40,0x2C,0xCC,0xF8,0x7F,0x6C,0xEA,0x00,0x00,0x04, -0xC9,0x74,0x40,0x87,0xC9,0x66,0xE0,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x86, -0x01,0xC0,0x02,0x70,0x04,0xC9,0x74,0x40,0x87,0xC9,0x66,0x41,0x93,0xC9,0x66,0x70, -0x87,0x41,0xE0,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x82,0x50,0x70,0x87,0x7F, -0x70,0x08,0x00,0x02,0xE0,0x40,0x24,0x7F,0x46,0x4B,0x00,0x00,0x04,0xC9,0x74,0x40, -0x87,0xC9,0x66,0xE0,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x9C,0x06,0x40,0xA0, -0x40,0xDC,0x08,0x7F,0x90,0x04,0x00,0x00,0x40,0xDC,0x0E,0x50,0x40,0xA0,0x40,0x2C, -0xCC,0xF8,0x7F,0x6C,0xEA,0x00,0x00,0x04,0xC9,0x74,0x40,0x87,0xC9,0x66,0xE0,0x41, -0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x86,0x01,0xC0,0x02,0x70,0x04,0xC9,0x74,0x40, -0x87,0xC9,0x66,0x41,0x93,0xC9,0x66,0x70,0x87,0x41,0xE0,0x41,0xD0,0x04,0x41,0x41, -0x9C,0x41,0x40,0x86,0x01,0x50,0x70,0x24,0x7F,0x58,0x4B,0x00,0x00,0x04,0xC9,0x74, -0x40,0x87,0xC9,0x66,0xE0,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x9C,0x06,0x40, -0xA0,0x40,0xDC,0x08,0x7F,0x90,0x04,0x00,0x00,0x40,0xDC,0x1A,0x50,0x40,0xA0,0x40, -0x2C,0xCC,0xF8,0x7F,0x6C,0xEA,0x00,0x00,0x04,0xC9,0x74,0x40,0x87,0xC9,0x66,0xE0, -0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x86,0x01,0xC0,0x02,0x70,0x04,0xC9,0x74, -0x40,0x87,0xC9,0x66,0x41,0x93,0xC9,0x66,0x70,0x87,0x41,0xE0,0x41,0xD0,0x04,0x41, -0x41,0x9C,0x41,0x40,0x86,0x02,0x50,0x70,0x24,0x7F,0x58,0x4B,0x00,0x00,0x04,0xC9, -0x74,0x40,0x87,0xC9,0x66,0xE0,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x9C,0x06, -0x40,0xA0,0x40,0xDC,0x08,0x7F,0x90,0x04,0x00,0x00,0x40,0xDC,0x0E,0x50,0x40,0xA0, -0x40,0x2C,0xCC,0xF8,0x7F,0x6C,0xEA,0x00,0x00,0x04,0xC9,0x74,0x40,0x87,0xC9,0x66, -0xE0,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x86,0x01,0xC0,0x02,0x70,0x04,0xC9, -0x74,0x40,0x87,0xC9,0x66,0x41,0x93,0xC9,0x66,0x70,0x87,0x41,0xE0,0x41,0xD0,0x04, -0x41,0x41,0x9C,0x41,0x40,0x86,0x01,0x50,0x70,0x04,0xC9,0x74,0x40,0x87,0xC9,0x66, -0xE0,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x9C,0x06,0x40,0xA0,0x40,0xDC,0x08, -0x7F,0x90,0x04,0x00,0x00,0x40,0xDC,0x1A,0x50,0x40,0xA0,0x40,0x2C,0xCC,0xF8,0x7F, -0x6C,0xEA,0x00,0x00,0x04,0xC9,0x74,0x40,0x87,0xC9,0x66,0xE0,0x41,0xD0,0x04,0x41, -0x41,0x9C,0x41,0x40,0x86,0x01,0xC0,0x02,0x70,0x04,0xC9,0x74,0x40,0x87,0xC9,0x66, -0x41,0x93,0xC9,0x66,0x70,0x87,0x41,0xE0,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40, -0x86,0x02,0x50,0x70,0x7B,0x14,0x3C,0x40,0x01,0x7E,0x83,0xFE,0x3C,0x40,0x02,0x7E, -0xDE,0xFE,0x3C,0x40,0x03,0x7E,0x39,0xFF,0x86,0x01,0xC9,0x70,0x70,0x24,0x7F,0xB0, -0x4C,0x00,0x00,0x86,0xC9,0x70,0xE4,0x40,0xD0,0x05,0x40,0x40,0x9C,0x7F,0x90,0x04, -0x00,0x00,0x40,0xCC,0x00,0x07,0xC0,0x04,0x40,0x3C,0x00,0x40,0x77,0x08,0x24,0x7F, -0x16,0x4C,0x00,0x00,0x04,0xC9,0x74,0x40,0x87,0xC9,0x66,0xE0,0x41,0xD0,0x04,0x41, -0x41,0x9C,0x41,0x40,0x9C,0x06,0x40,0xA0,0x40,0x86,0xC9,0x70,0xE4,0x40,0xD0,0x05, -0x40,0x40,0x9C,0x7F,0x90,0x04,0x00,0x00,0x40,0x9C,0x0C,0x40,0xA0,0x40,0x2C,0xCC, -0xF8,0x7F,0x6C,0xEA,0x00,0x00,0x04,0xC9,0x74,0x40,0x87,0xC9,0x66,0xE0,0x41,0xD0, -0x04,0x41,0x41,0x9C,0x41,0x40,0x82,0xC0,0x02,0x70,0x04,0xC9,0x74,0x40,0x87,0xC9, -0x66,0xE0,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x86,0xC9,0x70,0xE4,0x41,0xD0, -0x05,0x41,0x41,0x9C,0x7F,0x90,0x04,0x00,0x00,0x41,0xCC,0x03,0x0C,0x51,0x41,0x86, -0x41,0xC0,0x04,0x70,0x04,0xC9,0x74,0x40,0x87,0xC9,0x66,0x41,0x93,0xC9,0x66,0x70, -0x87,0x41,0xE0,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x86,0xC9,0x70,0x50,0x70, -0x24,0x7F,0xAC,0x4C,0x00,0x00,0x86,0xC9,0x70,0xE4,0x40,0xD0,0x05,0x40,0x40,0x9C, -0x7F,0x90,0x04,0x00,0x00,0x40,0x2B,0xC0,0x0C,0x7F,0x29,0x86,0xC9,0x70,0xE4,0x40, -0xD0,0x05,0x40,0x40,0x9C,0x7F,0x90,0x04,0x00,0x00,0x40,0x9C,0x0C,0x40,0xA0,0x40, -0xA0,0x4F,0x22,0x0B,0x00,0x00,0x2C,0xCC,0xF8,0x7F,0xE4,0xE9,0x00,0x00,0x28,0x40, -0x77,0x5C,0x04,0xC9,0x74,0x40,0x87,0xC9,0x66,0xE0,0x41,0xD0,0x04,0x41,0x41,0x9C, -0x41,0x40,0x82,0xC0,0x02,0x70,0x04,0xC9,0x74,0x40,0x87,0xC9,0x66,0xE0,0x41,0xD0, -0x04,0x41,0x41,0x9C,0x41,0x40,0x86,0xC9,0x70,0xE4,0x41,0xD0,0x05,0x41,0x41,0x9C, -0x7F,0x90,0x04,0x00,0x00,0x41,0xCC,0x03,0x0C,0x51,0x41,0x86,0x41,0xC0,0x04,0x70, -0x04,0xC9,0x74,0x40,0x87,0xC9,0x66,0x41,0x93,0xC9,0x66,0x70,0x87,0x41,0xE0,0x41, -0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x86,0xC9,0x70,0x50,0x70,0x92,0xC9,0x70,0x70, -0x86,0xC9,0x70,0xE4,0x40,0x87,0xEF,0xE0,0x04,0x00,0x00,0xE0,0x41,0x3C,0x41,0x40, -0x4A,0xA3,0xFE,0xA0,0x4F,0x29,0x0B,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xA8,0x5C,0x00, -0x00,0xA0,0x4F,0x47,0x0B,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xA8,0x5C,0x00,0x00,0xA0, -0x4F,0x67,0x0B,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xA8,0x5C,0x00,0x00,0x82,0xC9,0x70, -0x70,0x24,0x7F,0x80,0x4D,0x00,0x00,0xA0,0x4F,0x90,0x0B,0x00,0x00,0x86,0xC9,0x70, -0xE4,0x40,0xA0,0x40,0x04,0xC9,0x74,0x40,0x86,0xC9,0x70,0xE4,0x41,0xD0,0x04,0x41, -0x41,0x9C,0x41,0x40,0x86,0xE2,0xC0,0x04,0xE0,0x40,0xA0,0x40,0x2C,0xCC,0xF4,0x7F, -0xA8,0x5C,0x00,0x00,0x04,0xC9,0x74,0x40,0x86,0xC9,0x70,0xE4,0x41,0xD0,0x04,0x41, -0x41,0x9C,0x41,0x40,0x9C,0x06,0x40,0xA0,0x40,0xA0,0x4F,0xA6,0x0B,0x00,0x00,0x2C, -0xCC,0xF8,0x7F,0xE4,0xE9,0x00,0x00,0x28,0x40,0x7F,0x25,0xA0,0x4F,0xAD,0x0B,0x00, -0x00,0x04,0xC9,0x74,0x40,0x86,0xC9,0x70,0xE4,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41, -0x40,0x9C,0x06,0x40,0xA0,0x40,0x2C,0xCC,0xF8,0x7F,0xA8,0x5C,0x00,0x00,0xA0,0x4F, -0xB7,0x0B,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xA8,0x5C,0x00,0x00,0x92,0xC9,0x70,0x70, -0x86,0xC9,0x70,0xE4,0x40,0x87,0xC9,0x66,0xE0,0x41,0x3C,0x41,0x40,0x5A,0x6A,0xFF, -0xA0,0x4F,0x0C,0x30,0x04,0x00,0xDC,0x01,0x7F,0xA0,0x04,0x00,0x00,0x40,0xA0,0x40, -0xA0,0x01,0x2C,0xCC,0xF4,0x7F,0x50,0x6B,0x00,0x00,0x83,0xC9,0x64,0x70,0x82,0xC9, -0x70,0x70,0x7B,0x7F,0x04,0xC9,0x74,0x40,0x86,0xC9,0x70,0xE4,0x41,0xD0,0x04,0x41, -0x41,0x9C,0x41,0x40,0x86,0xE2,0xC0,0x02,0xE0,0x40,0x7F,0x31,0xDC,0x01,0x7F,0xA0, -0x04,0x00,0x00,0x40,0x87,0x50,0xE0,0x40,0x04,0xC9,0x74,0x41,0x86,0xC9,0x70,0xE4, -0x42,0xD0,0x04,0x42,0x42,0x9C,0x42,0x41,0x86,0xE2,0x51,0xE0,0x41,0x3C,0x41,0x40, -0x77,0x09,0x87,0x01,0xC9,0x64,0x70,0x7B,0x4A,0x7B,0x34,0x04,0xC9,0x74,0x40,0x86, -0xC9,0x70,0xE4,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x86,0xE2,0xC0,0x04,0xE0, -0x40,0xDC,0x01,0x7F,0xA0,0x04,0x00,0x00,0x41,0x87,0x51,0xE0,0x41,0xD4,0x04,0x41, -0x41,0x3C,0x41,0x40,0x77,0x09,0x87,0x01,0xC9,0x64,0x70,0x7B,0x16,0x92,0xC9,0x70, -0x70,0x86,0xC9,0x70,0xE4,0x40,0x87,0xC9,0x66,0xE0,0x41,0x3C,0x41,0x40,0x5A,0x76, -0xFF,0x2B,0xC9,0x64,0x77,0x08,0x83,0xC9,0x69,0x70,0x7B,0x08,0x87,0xC9,0x71,0xC9, -0x69,0x70,0xA0,0x4F,0xB9,0x0B,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xA8,0x5C,0x00,0x00, -0xA0,0x4F,0xDB,0x0B,0x00,0x00,0x87,0xC9,0x69,0xE0,0x40,0xA0,0x40,0x2C,0xCC,0xF8, -0x7F,0xA8,0x5C,0x00,0x00,0x04,0xC9,0x74,0x40,0x87,0xC9,0x69,0xE0,0x41,0xD0,0x04, -0x41,0x41,0x9C,0x41,0x40,0x9C,0x06,0x40,0xA0,0x40,0xA0,0x4F,0xDF,0x0B,0x00,0x00, -0x2C,0xCC,0xF8,0x7F,0xE4,0xE9,0x00,0x00,0x28,0x40,0x7F,0x25,0xA0,0x4F,0xE6,0x0B, -0x00,0x00,0x04,0xC9,0x74,0x40,0x87,0xC9,0x69,0xE0,0x41,0xD0,0x04,0x41,0x41,0x9C, -0x41,0x40,0x9C,0x06,0x40,0xA0,0x40,0x2C,0xCC,0xF8,0x7F,0xA8,0x5C,0x00,0x00,0xA0, -0x4F,0xEC,0x0B,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xA8,0x5C,0x00,0x00,0xA0,0x00,0x2C, -0xCC,0xFC,0xEF,0x40,0x05,0x00,0x00,0xE0,0xC9,0x5A,0x2C,0xCC,0xFC,0x7F,0xCC,0x5A, -0x00,0x00,0x3C,0xFF,0x40,0x77,0x20,0xA0,0x01,0x2C,0xCC,0xFC,0xEF,0x40,0x05,0x00, -0x00,0xA0,0x4F,0xF0,0x0B,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xA8,0x5C,0x00,0x00,0x24, -0x7F,0xA2,0x53,0x00,0x00,0xA0,0x01,0x2C,0xCC,0xFC,0xEF,0x40,0x05,0x00,0x00,0x83, -0xC9,0x64,0x70,0x2B,0xC9,0x5A,0x7F,0x56,0x82,0xC9,0x70,0x70,0x7B,0x20,0xE0,0xC9, -0x5A,0x2C,0xCC,0xFC,0xAF,0x19,0x05,0x86,0xC9,0x70,0xE4,0x41,0x3C,0x40,0x41,0x77, -0x09,0x87,0x01,0xC9,0x64,0x70,0x7B,0x15,0x92,0xC9,0x70,0x70,0x86,0xC9,0x70,0xE4, -0x40,0x87,0xC9,0x66,0xE0,0x41,0x3C,0x41,0x40,0x5B,0xD5,0x2B,0xC9,0x64,0x77,0x16, -0xA0,0x4F,0xF2,0x0B,0x00,0x00,0xE0,0xC9,0x5A,0x2C,0xCC,0xF8,0x7F,0xA8,0x5C,0x00, -0x00,0x7A,0xF1,0xFE,0x87,0xC9,0x71,0xC9,0x68,0x70,0x7B,0x08,0x87,0xC9,0x69,0xC9, -0x68,0x70,0x04,0xC9,0x74,0x40,0x87,0xC9,0x68,0xE0,0x41,0xD0,0x04,0x41,0x41,0x9C, -0x41,0x40,0x86,0xE2,0xC0,0x02,0xE0,0x40,0x7F,0x25,0xDC,0x01,0x7F,0xA0,0x04,0x00, -0x00,0x40,0x04,0xC9,0x74,0x41,0x87,0xC9,0x68,0xE0,0x42,0xD0,0x04,0x42,0x42,0x9C, -0x42,0x41,0x87,0xC1,0x01,0x50,0x70,0x24,0x7F,0x67,0x53,0x00,0x00,0x3F,0xC9,0x69, -0xC9,0x68,0x77,0x15,0xDC,0x01,0x7F,0xA0,0x04,0x00,0x00,0x40,0xFB,0x0F,0x50,0x40, -0x87,0x40,0xC9,0x67,0x70,0x7B,0x06,0x83,0xC9,0x67,0x70,0xDC,0x01,0x7F,0xA0,0x04, -0x00,0x00,0x40,0x04,0xC9,0x74,0x41,0x87,0xC9,0x68,0xE0,0x42,0xD0,0x04,0x42,0x42, -0x9C,0x42,0x41,0x86,0xE2,0xC1,0x04,0xE0,0x41,0xD0,0x04,0x41,0x41,0x87,0x41,0x50, -0x70,0x04,0xC9,0x74,0x40,0x87,0xC9,0x68,0xE0,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41, -0x40,0x86,0x50,0xC9,0x70,0x70,0x82,0xC9,0x72,0x70,0x7B,0x55,0x04,0xC9,0x74,0x40, -0x86,0xC9,0x72,0xE4,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x82,0x50,0x70,0x04, -0xC9,0x74,0x40,0x86,0xC9,0x72,0xE4,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x82, -0xC0,0x02,0x70,0x04,0xC9,0x74,0x40,0x86,0xC9,0x72,0xE4,0x41,0xD0,0x04,0x41,0x41, -0x9C,0x41,0x40,0x82,0xC0,0x04,0x70,0x04,0xC9,0x74,0x40,0x86,0xC9,0x72,0xE4,0x41, -0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x83,0xC0,0x06,0x70,0x92,0xC9,0x72,0x70,0x3E, -0x10,0xC9,0x72,0x4B,0xA9,0x87,0x01,0xC9,0x65,0x70,0x86,0xC9,0x70,0xE4,0x40,0xD0, -0x05,0x40,0x40,0x9C,0x7F,0x90,0x04,0x00,0x00,0x40,0xCC,0x03,0x00,0xC0,0x04,0x40, -0x87,0x40,0xC9,0x66,0x70,0x2B,0xC9,0x66,0x77,0x0B,0x87,0x0F,0xC9,0x66,0x70,0x83, -0xC9,0x65,0x70,0x82,0xC9,0x72,0x70,0x7B,0x58,0x04,0xC9,0x74,0x40,0x86,0xC9,0x72, -0xE4,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x9C,0x06,0x40,0xA0,0x40,0x86,0xC9, -0x70,0xE4,0x40,0xD0,0x05,0x40,0x40,0x9C,0x7F,0x90,0x04,0x00,0x00,0x40,0xEA,0x0C, -0xC9,0x72,0x41,0xDC,0x41,0xC0,0x08,0x40,0x9C,0x02,0x40,0xA0,0x40,0x2C,0xCC,0xF8, -0x7F,0x6C,0xEA,0x00,0x00,0x04,0xC9,0x74,0x40,0x86,0xC9,0x72,0xE4,0x41,0xD0,0x04, -0x41,0x41,0x9C,0x41,0x40,0x86,0xC9,0x72,0xC0,0x04,0x70,0x92,0xC9,0x72,0x70,0x86, -0xC9,0x72,0xE4,0x40,0x87,0xC9,0x66,0xE0,0x41,0x3C,0x41,0x40,0x5B,0x9D,0xA0,0x4F, -0x15,0x0C,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xA8,0x5C,0x00,0x00,0xA0,0x4F,0x30,0x0C, -0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xA8,0x5C,0x00,0x00,0xA0,0x4F,0x53,0x0C,0x00,0x00, -0x2C,0xCC,0xFC,0x7F,0xA8,0x5C,0x00,0x00,0x82,0xC9,0x72,0x70,0x24,0x7F,0xC0,0x51, -0x00,0x00,0xA0,0x4F,0x81,0x0C,0x00,0x00,0x86,0xC9,0x72,0xE4,0x40,0xA0,0x40,0x04, -0xC9,0x74,0x40,0x86,0xC9,0x72,0xE4,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x86, -0xE2,0xC0,0x04,0xE0,0x40,0xA0,0x40,0x2C,0xCC,0xF4,0x7F,0xA8,0x5C,0x00,0x00,0x04, -0xC9,0x74,0x40,0x86,0xC9,0x72,0xE4,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x9C, -0x06,0x40,0xA0,0x40,0xA0,0x4F,0x98,0x0C,0x00,0x00,0x2C,0xCC,0xF8,0x7F,0xE4,0xE9, -0x00,0x00,0x28,0x40,0x7F,0x2A,0x2B,0xC9,0x65,0x7F,0x25,0xA0,0x4F,0x9F,0x0C,0x00, -0x00,0x04,0xC9,0x74,0x40,0x86,0xC9,0x72,0xE4,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41, -0x40,0x9C,0x06,0x40,0xA0,0x40,0x2C,0xCC,0xF8,0x7F,0xA8,0x5C,0x00,0x00,0xA0,0x4F, -0xAD,0x0C,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xA8,0x5C,0x00,0x00,0x92,0xC9,0x72,0x70, -0x86,0xC9,0x72,0xE4,0x40,0x87,0xC9,0x66,0xE0,0x41,0x3C,0x41,0x40,0x5A,0x65,0xFF, -0x83,0xC9,0x64,0x70,0x82,0xC9,0x72,0x70,0x7B,0x2D,0x04,0xC9,0x74,0x40,0x86,0xC9, -0x72,0xE4,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x86,0xE2,0xC0,0x04,0xE0,0x40, -0x87,0xC9,0x67,0xE0,0x41,0x3C,0x41,0x40,0x77,0x09,0x87,0x01,0xC9,0x64,0x70,0x7B, -0x15,0x92,0xC9,0x72,0x70,0x86,0xC9,0x72,0xE4,0x40,0x87,0xC9,0x66,0xE0,0x41,0x3C, -0x41,0x40,0x5B,0xC8,0x2B,0xC9,0x64,0x77,0x08,0x83,0xC9,0x69,0x70,0x7B,0x08,0x87, -0xC9,0x73,0xC9,0x69,0x70,0xA0,0x4F,0xAF,0x0C,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xA8, -0x5C,0x00,0x00,0xA0,0x4F,0xCF,0x0C,0x00,0x00,0x87,0xC9,0x69,0xE0,0x40,0xA0,0x40, -0x2C,0xCC,0xF8,0x7F,0xA8,0x5C,0x00,0x00,0x04,0xC9,0x74,0x40,0x87,0xC9,0x69,0xE0, -0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x9C,0x06,0x40,0xA0,0x40,0xA0,0x4F,0xD3, -0x0C,0x00,0x00,0x2C,0xCC,0xF8,0x7F,0xE4,0xE9,0x00,0x00,0x28,0x40,0x7F,0x2A,0x2B, -0xC9,0x65,0x7F,0x25,0xA0,0x4F,0xDA,0x0C,0x00,0x00,0x04,0xC9,0x74,0x40,0x87,0xC9, -0x69,0xE0,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x9C,0x06,0x40,0xA0,0x40,0x2C, -0xCC,0xF8,0x7F,0xA8,0x5C,0x00,0x00,0xA0,0x4F,0xDF,0x0C,0x00,0x00,0x2C,0xCC,0xFC, -0x7F,0xA8,0x5C,0x00,0x00,0xA0,0x00,0x2C,0xCC,0xFC,0xEF,0x40,0x05,0x00,0x00,0xE0, -0xC9,0x5A,0x2C,0xCC,0xFC,0x7F,0xCC,0x5A,0x00,0x00,0x3C,0xFF,0x40,0x77,0x20,0xA0, -0x01,0x2C,0xCC,0xFC,0xEF,0x40,0x05,0x00,0x00,0xA0,0x4F,0xE3,0x0C,0x00,0x00,0x2C, -0xCC,0xFC,0x7F,0xA8,0x5C,0x00,0x00,0x24,0x7F,0xA2,0x53,0x00,0x00,0xA0,0x01,0x2C, -0xCC,0xFC,0xEF,0x40,0x05,0x00,0x00,0x83,0xC9,0x64,0x70,0x2B,0xC9,0x5A,0x7F,0x56, -0x82,0xC9,0x72,0x70,0x7B,0x20,0xE0,0xC9,0x5A,0x2C,0xCC,0xFC,0xAF,0x41,0x01,0x86, -0xC9,0x72,0xE4,0x41,0x3C,0x40,0x41,0x77,0x09,0x87,0x01,0xC9,0x64,0x70,0x7B,0x15, -0x92,0xC9,0x72,0x70,0x86,0xC9,0x72,0xE4,0x40,0x87,0xC9,0x66,0xE0,0x41,0x3C,0x41, -0x40,0x5B,0xD5,0x2B,0xC9,0x64,0x77,0x16,0xA0,0x4F,0xE5,0x0C,0x00,0x00,0xE0,0xC9, -0x5A,0x2C,0xCC,0xF8,0x7F,0xA8,0x5C,0x00,0x00,0x7A,0xEC,0xFE,0x87,0xC9,0x73,0xC9, -0x68,0x70,0x7B,0x08,0x87,0xC9,0x69,0xC9,0x68,0x70,0xDC,0x01,0x7F,0xA0,0x04,0x00, -0x00,0x40,0x04,0xC9,0x74,0x41,0x87,0xC9,0x68,0xE0,0x42,0xD0,0x04,0x42,0x42,0x9C, -0x42,0x41,0xB3,0xC1,0x05,0x50,0x70,0x87,0x01,0xEF,0xA0,0x04,0x00,0x00,0x70,0x2C, -0x5C,0x7F,0x90,0x7F,0x00,0x00,0x28,0x40,0x77,0x27,0x84,0x08,0x7F,0x5C,0x08,0x00, -0x02,0x70,0x2C,0x5C,0x7F,0xF8,0x3D,0x00,0x00,0x84,0x4F,0xEF,0xBE,0xED,0xFE,0xEF, -0x8C,0x04,0x00,0x00,0x70,0x87,0x01,0x7F,0x0B,0x40,0x04,0x00,0x70,0x7B,0x00,0x7A, -0x76,0xF1,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x10,0x49,0x9C,0x4F,0x04,0x00, -0x00,0x00,0x4C,0x82,0x59,0x70,0x7B,0x37,0x7B,0x02,0x2C,0x5C,0x7F,0x1C,0x5C,0x00, -0x00,0x87,0x40,0xDA,0x00,0x70,0x2B,0x40,0x7F,0xF2,0x3F,0x0D,0xDA,0x00,0x7F,0x08, -0x3F,0x0A,0xDA,0x00,0x77,0x13,0x2A,0x59,0x77,0x06,0x80,0x40,0x7B,0x1F,0x83,0xDA, -0x00,0x70,0x84,0x01,0x40,0x7B,0x16,0x90,0x5A,0x70,0x92,0x59,0x70,0x3E,0x08,0x59, -0x4B,0xC8,0x83,0xDA,0x00,0x70,0x84,0x01,0x40,0x7B,0x02,0x04,0xC9,0xE8,0x4C,0x20, -0x49,0x08,0x70,0x70,0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0xA0,0x4F,0x08, -0x0D,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xA8,0x5C,0x00,0x00,0x84,0x4F,0x1E,0xAC,0xEB, -0xAD,0x7F,0x64,0x08,0x00,0x02,0x70,0x87,0x01,0x7F,0x0B,0x40,0x04,0x00,0x70,0x7B, -0x00,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x10,0x49,0x9C,0x4F,0x08,0x00, -0x00,0x00,0x4C,0x82,0x64,0x70,0x86,0x64,0x62,0x70,0x7B,0x29,0x3F,0x30,0x59,0x4B, -0x14,0x3F,0x39,0x59,0x47,0x0F,0x87,0x59,0xE2,0x40,0xBE,0x30,0x40,0x86,0x40,0x64, -0x70,0x7B,0x07,0x84,0xFF,0x40,0x7B,0x21,0xEA,0x0A,0x62,0x40,0x9E,0x64,0x40,0x86, -0x40,0x62,0x70,0x84,0x5A,0x40,0x90,0x5A,0x70,0x87,0x50,0x59,0x70,0x2B,0x59,0x77, -0xCD,0x86,0x62,0xE4,0x40,0x7B,0x02,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70, -0x10,0x49,0x9C,0x4F,0x04,0x00,0x00,0x00,0x4C,0xDC,0x04,0x7F,0xA4,0x04,0x00,0x00, -0x40,0x83,0x50,0x70,0xA0,0x4F,0x09,0x30,0x04,0x00,0xDC,0x03,0x7F,0xA4,0x04,0x00, -0x00,0x40,0xA0,0x40,0xA0,0x01,0x2C,0xCC,0xF4,0x7F,0x50,0x6B,0x00,0x00,0x3C,0x01, -0x40,0x77,0x51,0xDC,0x02,0x7F,0xA4,0x04,0x00,0x00,0x40,0xDC,0x03,0x7F,0xA4,0x04, -0x00,0x00,0x41,0xFB,0x5F,0xF0,0x00,0x51,0x41,0xD4,0x04,0x41,0x41,0x87,0x41,0x50, -0x70,0xDC,0x03,0x7F,0xA4,0x04,0x00,0x00,0x40,0xBB,0x0F,0x50,0x70,0x3C,0x4F,0x00, -0x80,0x00,0x00,0x7F,0x08,0x05,0x00,0x00,0x4F,0x18,0xDC,0x03,0x7F,0xA4,0x04,0x00, -0x00,0x40,0x83,0x50,0x70,0xDC,0x02,0x7F,0xA4,0x04,0x00,0x00,0x40,0x83,0x50,0x70, -0x7B,0x18,0xDC,0x02,0x7F,0xA4,0x04,0x00,0x00,0x40,0x83,0x50,0x70,0xDC,0x03,0x7F, -0xA4,0x04,0x00,0x00,0x40,0x83,0x50,0x70,0xA0,0x4F,0x80,0x30,0x04,0x00,0xE0,0x59, -0xA0,0x02,0x2C,0xCC,0xF4,0x7F,0x50,0x6B,0x00,0x00,0x28,0x40,0x7F,0x09,0x86,0xE2, -0x59,0xE0,0x40,0x77,0x1A,0x86,0x5F,0xBD,0x04,0x59,0x70,0xE0,0x59,0xA0,0x4F,0x80, -0x30,0x04,0x00,0xA0,0x02,0x2C,0xCC,0xF4,0x7F,0xCC,0x6B,0x00,0x00,0x86,0x59,0xEF, -0xA4,0x04,0x00,0x00,0x70,0xDC,0x02,0x7F,0xA4,0x04,0x00,0x00,0x40,0x2B,0x50,0x7F, -0x08,0x86,0x5F,0xBD,0x04,0x59,0x70,0x86,0xE2,0x59,0xE0,0x40,0xA0,0x40,0xA0,0x4F, -0x00,0x90,0x04,0x00,0x2C,0xCC,0xF8,0x7F,0x84,0x57,0x00,0x00,0xDC,0x02,0x7F,0xA4, -0x04,0x00,0x00,0x40,0x2B,0x50,0x77,0x19,0xDC,0x03,0x7F,0xA4,0x04,0x00,0x00,0x40, -0x3F,0x01,0x50,0x77,0x0C,0x86,0xEF,0xA4,0x04,0x00,0x00,0x59,0x70,0x7B,0x35,0xA0, -0x4F,0x0A,0x30,0x04,0x00,0xE0,0x59,0xA0,0x02,0x2C,0xCC,0xF4,0x7F,0x50,0x6B,0x00, -0x00,0x28,0x40,0x7F,0x09,0x86,0xE2,0x59,0xE0,0x40,0x77,0x18,0x86,0x3D,0x59,0x70, -0xE0,0x59,0xA0,0x4F,0x0A,0x30,0x04,0x00,0xA0,0x02,0x2C,0xCC,0xF4,0x7F,0xCC,0x6B, -0x00,0x00,0x86,0xE2,0x59,0xE0,0x40,0xA0,0x40,0xA0,0x4F,0x08,0x90,0x04,0x00,0x2C, -0xCC,0xF8,0x7F,0x84,0x57,0x00,0x00,0xDC,0x02,0x7F,0xA4,0x04,0x00,0x00,0x40,0x2B, -0x50,0x77,0x6B,0xDC,0x03,0x7F,0xA4,0x04,0x00,0x00,0x40,0x2B,0x50,0x77,0x0E,0x8B, -0x7F,0x0D,0x90,0x04,0x00,0x40,0x38,0x40,0x01,0x77,0x1B,0xDC,0x03,0x7F,0xA4,0x04, -0x00,0x00,0x40,0x3F,0x01,0x50,0x77,0x46,0x8B,0x7F,0x0D,0x90,0x04,0x00,0x40,0x38, -0x40,0x02,0x7F,0x3A,0xDC,0x04,0x7F,0xA4,0x04,0x00,0x00,0x40,0x87,0x01,0x50,0x70, -0xDC,0x03,0x7F,0xA4,0x04,0x00,0x00,0x40,0x2B,0x50,0x7F,0x13,0x84,0x4F,0x08,0x90, -0x04,0x00,0x40,0x84,0x40,0xEF,0xFC,0x04,0x00,0x00,0x70,0x7B,0x11,0x84,0x4F,0x00, -0x90,0x04,0x00,0x40,0x84,0x40,0xEF,0xFC,0x04,0x00,0x00,0x70,0x04,0xC9,0xE8,0x4C, -0x20,0x49,0x08,0x70,0x10,0x48,0x9C,0x4F,0x04,0x00,0x00,0x00,0x4C,0x86,0x01,0x48, -0x7B,0x23,0x3E,0x10,0x48,0x5B,0x1C,0xA0,0x4F,0x94,0x0D,0x00,0x00,0x86,0x72,0xE4, -0x40,0xA0,0x40,0x2C,0xCC,0xF8,0x7F,0xA8,0x5C,0x00,0x00,0x24,0x7F,0x7A,0x57,0x00, -0x00,0x92,0x48,0x86,0x48,0xE4,0x40,0xD0,0x03,0x40,0x40,0x3E,0x72,0x80,0x14,0x0D, -0x00,0x00,0x77,0xD0,0x3C,0x4F,0x08,0x90,0x04,0x00,0x74,0x77,0x31,0x86,0x48,0xE4, -0x40,0xD0,0x03,0x40,0x40,0x87,0x80,0x16,0x0D,0x00,0x00,0xE2,0x40,0xB2,0x30,0x40, -0x86,0x40,0x59,0x70,0xE0,0x59,0xA0,0x4F,0x0A,0x30,0x04,0x00,0xA0,0x02,0x2C,0xCC, -0xF4,0x7F,0xCC,0x6B,0x00,0x00,0x24,0x7F,0x6B,0x57,0x00,0x00,0xA0,0x4F,0x80,0x30, -0x04,0x00,0xE0,0x59,0xA0,0x02,0x2C,0xCC,0xF4,0x7F,0x50,0x6B,0x00,0x00,0x86,0xE2, -0x59,0xE0,0x40,0x7F,0x38,0x86,0xE2,0x59,0xE0,0x40,0x84,0x4F,0xF0,0xFF,0x00,0x00, -0x41,0x86,0xE2,0x41,0xE0,0x41,0xB8,0x41,0x40,0x86,0x40,0x59,0x70,0x86,0xE2,0x59, -0xE0,0x40,0x86,0x48,0xE4,0x41,0xD0,0x03,0x41,0x41,0x87,0x81,0x16,0x0D,0x00,0x00, -0xE0,0x41,0xB0,0x41,0x40,0x86,0x40,0x59,0x70,0x7B,0x20,0x86,0x48,0xE4,0x40,0xD0, -0x03,0x40,0x40,0x87,0x80,0x16,0x0D,0x00,0x00,0xE2,0x40,0xB2,0x5F,0x30,0x04,0x40, -0xB2,0x5F,0x80,0x00,0x40,0x86,0x40,0x59,0x70,0xE0,0x59,0xA0,0x4F,0x80,0x30,0x04, -0x00,0xA0,0x02,0x2C,0xCC,0xF4,0x7F,0xCC,0x6B,0x00,0x00,0x86,0xE2,0x59,0xE0,0x40, -0xA0,0x40,0xA0,0x74,0x2C,0xCC,0xF8,0xAF,0x10,0x00,0x04,0xC9,0xEC,0x4C,0x20,0x48, -0x20,0x49,0x08,0x70,0x10,0x47,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x86,0x01,0x48, -0x7B,0x17,0x86,0xE2,0x48,0xE0,0x40,0x3C,0x10,0x40,0x5B,0x0B,0x86,0x0D,0x48,0x86, -0x30,0x72,0x70,0x7B,0x22,0x92,0x48,0x86,0xE2,0x48,0xE0,0x40,0xD0,0x03,0x40,0x40, -0x87,0x80,0x16,0x0D,0x00,0x00,0xE0,0x40,0x86,0xE2,0x72,0xE0,0x41,0xB8,0x0F,0x41, -0x3C,0x41,0x40,0x77,0xCF,0xDC,0x02,0x74,0x40,0x87,0x1A,0x50,0x70,0xDC,0x02,0x74, -0x40,0x87,0x20,0x50,0x70,0xDC,0x02,0x74,0x40,0x87,0x30,0x50,0x70,0xDC,0x02,0x74, -0x40,0x87,0x6F,0x40,0x50,0x70,0xDC,0x02,0x74,0x40,0x87,0x6F,0x70,0x50,0x70,0x86, -0xE2,0x72,0xE0,0x40,0x38,0x40,0x5F,0x00,0x01,0x7F,0x1A,0x86,0xE2,0x72,0xE0,0x40, -0x38,0x40,0x5F,0x00,0x02,0x7F,0x07,0x84,0x04,0x40,0x7B,0x04,0x80,0x40,0xB0,0x00, -0x40,0x7B,0x05,0x84,0x10,0x40,0xB3,0x00,0x40,0x87,0x40,0x47,0x86,0xE2,0x72,0xE0, -0x40,0xB8,0x30,0x40,0x7B,0x13,0x7B,0x22,0xB3,0x01,0x47,0x7B,0x1D,0xB3,0x02,0x47, -0x7B,0x18,0xB3,0x03,0x47,0x7B,0x13,0x3C,0x40,0x00,0x7F,0xEC,0x3C,0x40,0x10,0x7F, -0xE9,0x3C,0x40,0x20,0x7F,0xE9,0x7B,0xEC,0x87,0x47,0xDA,0x04,0x70,0x86,0xE2,0x72, -0xE0,0x40,0x38,0x40,0x6F,0x40,0x7F,0x07,0x84,0x0F,0x40,0x7B,0x05,0x84,0x07,0x40, -0xB3,0x00,0x40,0x87,0x40,0xDA,0x04,0x70,0xDC,0x01,0x74,0x40,0x86,0xE2,0x48,0xE0, -0x41,0xD0,0x03,0x41,0x41,0x87,0x81,0x17,0x0D,0x00,0x00,0x50,0x70,0x86,0xE2,0x48, -0xE0,0x40,0xD0,0x03,0x40,0x40,0x87,0x80,0x18,0x0D,0x00,0x00,0x7F,0xD0,0x0F,0x00, -0x02,0x70,0xDC,0x04,0x74,0x40,0x87,0x7F,0xD0,0x0F,0x00,0x02,0x50,0x70,0xDC,0x02, -0x74,0x40,0x87,0x15,0x50,0x70,0x87,0x03,0x7F,0x0E,0x90,0x04,0x00,0x70,0x86,0x01, -0x48,0x7B,0x04,0x92,0x48,0x86,0xE2,0x48,0xE0,0x40,0x3C,0x5F,0x00,0x01,0x40,0x5B, -0xF4,0xDC,0x03,0x74,0x40,0x87,0x20,0x50,0x70,0x04,0xC9,0xF0,0x4C,0x20,0x48,0x20, -0x47,0x20,0x49,0x08,0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x04,0xC9,0xE8, -0x4C,0x20,0x49,0x08,0x10,0x49,0x9C,0x4F,0x04,0x00,0x00,0x00,0x4C,0x87,0x7F,0x13, -0x20,0x04,0x00,0x59,0x70,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x28,0x5D,0x70,0x70, -0x70,0x70,0x10,0x49,0x84,0x5A,0x42,0x84,0x74,0x41,0x84,0x78,0x40,0x30,0x19,0x04, -0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x84,0xCE,0xFC,0x40,0x84,0x50,0x7F,0xD4, -0x0F,0x00,0x02,0x70,0x84,0xC0,0x04,0x7F,0xD8,0x0F,0x00,0x02,0x70,0x2C,0x5C,0x7F, -0x2C,0x79,0x00,0x00,0x30,0xC8,0x70,0x70,0x84,0xCE,0xFC,0x40,0x84,0x50,0x7F,0xD4, -0x0F,0x00,0x02,0x70,0x84,0xC0,0x04,0x7F,0xD8,0x0F,0x00,0x02,0x70,0x84,0xC0,0x1C, -0x7F,0xDC,0x0F,0x00,0x02,0x70,0x2C,0x5C,0x7F,0xA0,0x79,0x00,0x00,0x30,0xC8,0x84, -0xCC,0xFC,0x7F,0xD4,0x0F,0x00,0x02,0x70,0x84,0xCC,0xF8,0x7F,0xD8,0x0F,0x00,0x02, -0x70,0x84,0x40,0x7F,0xDC,0x0F,0x00,0x02,0x70,0x84,0x4F,0x00,0xE1,0x01,0x00,0x4B, -0x2C,0x5C,0x7F,0xA0,0x79,0x00,0x00,0x84,0x7F,0x78,0x0F,0x00,0x02,0xCC,0xF8,0x70, -0x84,0x7F,0xD4,0x0F,0x00,0x02,0x4B,0x30,0x45,0x84,0x40,0x7F,0xDC,0x0F,0x00,0x02, -0x70,0x84,0xCC,0xFC,0x7F,0xD4,0x0F,0x00,0x02,0x70,0x84,0xCC,0xF8,0x7F,0xD8,0x0F, -0x00,0x02,0x70,0x04,0x7F,0x14,0x0F,0x00,0x02,0x40,0x30,0xAC,0x84,0x7F,0x78,0x0F, -0x00,0x02,0xCC,0xF8,0x70,0x84,0x7F,0xD4,0x0F,0x00,0x02,0x4B,0x30,0x45,0x84,0x4F, -0x00,0xE1,0x01,0x00,0x4B,0x2C,0x5C,0x7F,0xA0,0x79,0x00,0x00,0x30,0xC8,0x70,0x70, -0x10,0x49,0x9C,0x4F,0x04,0x00,0x00,0x00,0x4C,0xDC,0x02,0x7F,0xA4,0x04,0x00,0x00, -0x40,0x2B,0x50,0x7F,0x15,0xDC,0x04,0x7F,0xA4,0x04,0x00,0x00,0x40,0x3F,0x01,0x50, -0x77,0x08,0x24,0x7F,0xB3,0x5A,0x00,0x00,0x7B,0x34,0x3F,0x01,0xEF,0x10,0x05,0x00, -0x00,0x7F,0x2B,0x3F,0x6F,0x64,0x7F,0x03,0x20,0x04,0x00,0x7F,0x21,0x80,0xEF,0x8C, -0x04,0x00,0x00,0x70,0x80,0xEF,0x14,0x05,0x00,0x00,0x70,0x83,0x7F,0x0D,0x90,0x04, -0x00,0x70,0x87,0x04,0x7F,0x0E,0x90,0x04,0x00,0x70,0x7B,0x00,0xDC,0x01,0x5A,0x40, -0x3B,0x50,0x01,0x7F,0xC7,0x3C,0x7F,0x64,0x0F,0x00,0x02,0x5A,0x77,0x59,0x2B,0x7F, -0x68,0x08,0x00,0x02,0x77,0x51,0xDC,0x01,0x5A,0x40,0x3B,0x50,0x5F,0x80,0x00,0x7F, -0x46,0xDC,0x02,0x5A,0x40,0x87,0x6F,0x40,0x50,0x70,0xDC,0x02,0x5A,0x40,0x87,0x6F, -0x50,0x50,0x70,0xDC,0x03,0x5A,0x40,0x87,0x50,0x59,0x70,0x7B,0x1C,0xDC,0x02,0x5A, -0x40,0x87,0x6F,0x40,0x50,0x70,0xDC,0x02,0x5A,0x40,0x87,0x6F,0x50,0x50,0x70,0xDC, -0x03,0x5A,0x40,0x87,0x50,0x59,0x70,0xDC,0x01,0x5A,0x40,0x3B,0x50,0x01,0x77,0xDF, -0x84,0xFF,0x40,0x7B,0x20,0xDC,0x03,0x5A,0x40,0x87,0x50,0x59,0x70,0x87,0x59,0xE0, -0x40,0x7B,0x12,0xA0,0x00,0x2C,0xCC,0xFC,0x7F,0x0C,0x70,0x00,0x00,0x86,0x40,0xE4, -0x40,0x7B,0x02,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x10,0x47,0x9C,0x4F, -0x00,0x00,0x00,0x00,0x4C,0x2B,0xEF,0xC4,0x04,0x00,0x00,0x77,0x3C,0x3F,0x01,0xEF, -0x10,0x05,0x00,0x00,0x7F,0x2B,0x3F,0x6F,0x64,0x7F,0x03,0x20,0x04,0x00,0x7F,0x21, -0x80,0xEF,0x8C,0x04,0x00,0x00,0x70,0x80,0xEF,0x14,0x05,0x00,0x00,0x70,0x83,0x7F, -0x0D,0x90,0x04,0x00,0x70,0x87,0x04,0x7F,0x0E,0x90,0x04,0x00,0x70,0x7B,0x00,0x80, -0x40,0x24,0x7F,0x0F,0x5C,0x00,0x00,0x84,0x5A,0x48,0x24,0x7F,0xEC,0x5B,0x00,0x00, -0xA0,0x7F,0x64,0x0F,0x00,0x02,0x2C,0xCC,0xFC,0x7F,0xE0,0x59,0x00,0x00,0x84,0x40, -0x47,0x43,0x0B,0x84,0xFF,0x40,0x24,0x7F,0x0F,0x5C,0x00,0x00,0xF8,0x5F,0xFF,0x00, -0x47,0xE3,0x40,0x87,0x40,0xDA,0x00,0x70,0x3F,0x0A,0xDA,0x00,0x7F,0x08,0x3F,0x0D, -0xDA,0x00,0x77,0x2C,0x83,0xDA,0x00,0x70,0xA0,0x0A,0xA0,0x7F,0x64,0x0F,0x00,0x02, -0x2C,0xCC,0xF8,0x7F,0xA4,0x60,0x00,0x00,0x28,0x40,0x43,0x0B,0x84,0xFF,0x40,0x24, -0x7F,0x0F,0x5C,0x00,0x00,0x84,0x01,0x40,0x24,0x7F,0x0F,0x5C,0x00,0x00,0x87,0xDA, -0x00,0xE0,0x40,0xA0,0x40,0xA0,0x7F,0x64,0x0F,0x00,0x02,0x2C,0xCC,0xF8,0x7F,0xA4, -0x60,0x00,0x00,0x28,0x40,0x43,0x07,0x84,0xFF,0x40,0x7B,0x75,0x3F,0x08,0xDA,0x00, -0x77,0x23,0x3C,0x48,0x5A,0x7F,0x1C,0xA0,0x4F,0xB0,0x0D,0x00,0x00,0x2C,0xCC,0xFC, -0x7F,0xA8,0x5C,0x00,0x00,0x28,0x40,0x43,0x07,0x84,0xFF,0x40,0x7B,0x53,0x94,0x5A, -0x70,0x7B,0x2B,0x3F,0x6F,0x40,0xDA,0x00,0x77,0x21,0x84,0x48,0x5A,0x70,0xA0,0x0A, -0xA0,0x7F,0x64,0x0F,0x00,0x02,0x2C,0xCC,0xF8,0x7F,0xA4,0x60,0x00,0x00,0x28,0x40, -0x43,0x07,0x84,0xFF,0x40,0x7B,0x2A,0x7B,0x05,0x90,0x5A,0x70,0xFC,0x48,0x5A,0x40, -0x3C,0x6F,0x50,0x40,0x4A,0x2C,0xFF,0xA0,0x4F,0xB3,0x0D,0x00,0x00,0xA0,0x6F,0x50, -0x2C,0xCC,0xF8,0x7F,0xA8,0x5C,0x00,0x00,0x84,0x48,0x5A,0x70,0x7A,0x0E,0xFF,0x04, -0xC9,0xF0,0x4C,0x20,0x48,0x20,0x47,0x20,0x49,0x08,0x70,0x70,0x10,0x49,0x9C,0x4F, -0x00,0x00,0x00,0x00,0x4C,0x3F,0x01,0xEF,0x10,0x05,0x00,0x00,0x7F,0x2B,0x3F,0x6F, -0x64,0x7F,0x03,0x20,0x04,0x00,0x7F,0x21,0x80,0xEF,0x8C,0x04,0x00,0x00,0x70,0x80, -0xEF,0x14,0x05,0x00,0x00,0x70,0x83,0x7F,0x0D,0x90,0x04,0x00,0x70,0x87,0x04,0x7F, -0x0E,0x90,0x04,0x00,0x70,0x7B,0x00,0xDC,0x02,0x7F,0xA4,0x04,0x00,0x00,0x40,0x2B, -0x50,0x7F,0x0F,0xDC,0x04,0x7F,0xA4,0x04,0x00,0x00,0x40,0x3F,0x01,0x50,0x7F,0x21, -0xDC,0x01,0x7F,0x64,0x0F,0x00,0x02,0x40,0x3B,0x50,0x01,0x7F,0x10,0xDC,0x03,0x7F, -0x64,0x0F,0x00,0x02,0x40,0x87,0x50,0xE0,0x40,0x7B,0x16,0x80,0x40,0x7B,0x12,0xA0, -0x01,0x2C,0xCC,0xFC,0x7F,0x0C,0x70,0x00,0x00,0x87,0x40,0xE0,0x40,0x7B,0x02,0x04, -0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x10,0x49,0x9C,0x4F,0x38,0x00,0x00,0x00, -0x4C,0x2B,0xEF,0xC4,0x04,0x00,0x00,0x77,0x3C,0x3F,0x01,0xEF,0x10,0x05,0x00,0x00, -0x7F,0x2B,0x3F,0x6F,0x64,0x7F,0x03,0x20,0x04,0x00,0x7F,0x21,0x80,0xEF,0x8C,0x04, -0x00,0x00,0x70,0x80,0xEF,0x14,0x05,0x00,0x00,0x70,0x83,0x7F,0x0D,0x90,0x04,0x00, -0x70,0x87,0x04,0x7F,0x0E,0x90,0x04,0x00,0x70,0x7B,0x00,0x80,0x40,0x24,0x7F,0x9D, -0x60,0x00,0x00,0xDC,0x02,0x7F,0x64,0x0F,0x00,0x02,0x40,0x87,0x15,0x50,0x70,0x80, -0xC9,0x28,0x70,0x04,0x74,0x59,0x70,0x24,0x7F,0x77,0x60,0x00,0x00,0x3F,0x25,0xDA, -0x00,0x7F,0x08,0x24,0x7F,0x56,0x60,0x00,0x00,0x84,0x20,0x68,0x70,0x80,0x64,0x70, -0x80,0xC9,0x18,0x70,0x80,0xC9,0x1C,0x70,0x90,0x5A,0x70,0x3F,0x2D,0xDA,0x00,0x77, -0x09,0x84,0x01,0x64,0x70,0x90,0x5A,0x70,0x3F,0x30,0xDA,0x00,0x77,0x0D,0x28,0x64, -0x77,0x06,0x84,0x30,0x68,0x70,0x90,0x5A,0x70,0x7B,0x17,0xE8,0x0A,0xC9,0x1C,0x40, -0xFF,0x30,0xDA,0x00,0x41,0x9C,0x41,0x40,0x84,0x40,0xC9,0x1C,0x70,0x90,0x5A,0x70, -0x3F,0x30,0xDA,0x00,0x4B,0x08,0x3F,0x39,0xDA,0x00,0x4F,0xE1,0x3F,0x6F,0x6C,0xDA, -0x00,0x7F,0x09,0x3F,0x6F,0x68,0xDA,0x00,0x77,0x05,0x90,0x5A,0x70,0x87,0xDA,0x00, -0xE0,0x40,0x24,0x7F,0x01,0x60,0x00,0x00,0xDC,0x03,0x59,0x40,0x87,0x50,0xC9,0x10, -0x70,0x9C,0x04,0x59,0x70,0x2B,0xC9,0x10,0x7F,0x20,0x87,0xC9,0x10,0xE0,0x40,0xA0, -0x40,0xA0,0x7F,0x64,0x0F,0x00,0x02,0x2C,0xCC,0xF8,0x7F,0xA4,0x60,0x00,0x00,0x28, -0x40,0x43,0x07,0x84,0x01,0xC9,0x28,0x70,0x24,0x7F,0x54,0x60,0x00,0x00,0x84,0xD9, -0x00,0xC9,0x14,0x70,0x9C,0x04,0x59,0x70,0x28,0xC9,0x14,0x77,0x0B,0x84,0x4F,0xFC, -0x0D,0x00,0x00,0xC9,0x14,0x70,0x80,0x6C,0x70,0x7B,0x2A,0x90,0x6C,0x70,0x84,0xC9, -0x14,0x40,0x90,0xC9,0x14,0x70,0x87,0x50,0xE0,0x40,0xA0,0x40,0xA0,0x7F,0x64,0x0F, -0x00,0x02,0x2C,0xCC,0xF8,0x7F,0xA4,0x60,0x00,0x00,0x28,0x40,0x43,0x07,0x84,0x01, -0xC9,0x28,0x70,0x2B,0xD9,0x14,0x77,0xD5,0x7B,0x1B,0xA0,0x20,0xA0,0x7F,0x64,0x0F, -0x00,0x02,0x2C,0xCC,0xF8,0x7F,0xA4,0x60,0x00,0x00,0x28,0x40,0x43,0x07,0x84,0x01, -0xC9,0x28,0x70,0x84,0x6C,0x40,0x90,0x6C,0x70,0x3C,0xC9,0x1C,0x40,0x4B,0xDD,0x24, -0x7F,0x54,0x60,0x00,0x00,0x84,0x10,0xC9,0x24,0x70,0x7B,0x13,0x84,0x01,0xC9,0x18, -0x70,0x84,0x0A,0xC9,0x24,0x70,0x7B,0x07,0x84,0x08,0xC9,0x24,0x70,0x84,0xD9,0x00, -0xC9,0x20,0x70,0x9C,0x04,0x59,0x70,0x28,0xC9,0x20,0x77,0x15,0x84,0x01,0x6C,0x70, -0x87,0x7F,0xE8,0x0D,0x00,0x00,0xC9,0x2C,0x70,0x80,0xC9,0x18,0x70,0x7B,0x74,0x3C, -0x01,0xC9,0x18,0x77,0x17,0xD4,0x1F,0xC9,0x20,0x40,0x7F,0x10,0x88,0xC9,0x20,0x40, -0x9C,0x01,0x40,0x84,0x40,0xC9,0x20,0x70,0x7B,0x06,0x80,0xC9,0x18,0x70,0x80,0x6C, -0x70,0x7B,0x22,0x04,0xC9,0x2C,0x40,0x9C,0x6C,0x40,0xE4,0xE0,0xC9,0x24,0xC9,0x20, -0x41,0x87,0x81,0xE8,0x0D,0x00,0x00,0x50,0x70,0xAC,0xE0,0xC9,0x24,0xC9,0x20,0x70, -0x90,0x6C,0x70,0x28,0xC9,0x20,0x7F,0x07,0x3C,0x0C,0x6C,0x4B,0xD8,0x3C,0x0C,0x6C, -0x4B,0x21,0xA0,0x3F,0xA0,0x7F,0x64,0x0F,0x00,0x02,0x2C,0xCC,0xF8,0x7F,0xA4,0x60, -0x00,0x00,0x28,0x40,0x43,0x07,0x84,0x01,0xC9,0x28,0x70,0x24,0x7F,0x54,0x60,0x00, -0x00,0x28,0x64,0x77,0x78,0x3C,0x01,0xC9,0x18,0x77,0x24,0x94,0xC9,0x1C,0x70,0x3C, -0x30,0x68,0x77,0x1B,0xA0,0x2D,0xA0,0x7F,0x64,0x0F,0x00,0x02,0x2C,0xCC,0xF8,0x7F, -0xA4,0x60,0x00,0x00,0x28,0x40,0x43,0x07,0x84,0x01,0xC9,0x28,0x70,0x7B,0x1B,0xA0, -0x68,0xA0,0x7F,0x64,0x0F,0x00,0x02,0x2C,0xCC,0xF8,0x7F,0xA4,0x60,0x00,0x00,0x28, -0x40,0x43,0x07,0x84,0x01,0xC9,0x28,0x70,0x84,0xC9,0x1C,0x40,0x94,0xC9,0x1C,0x70, -0x3C,0x6C,0x40,0x47,0xDC,0x3C,0x01,0xC9,0x18,0x77,0x20,0x3C,0x20,0x68,0x77,0x1B, -0xA0,0x2D,0xA0,0x7F,0x64,0x0F,0x00,0x02,0x2C,0xCC,0xF8,0x7F,0xA4,0x60,0x00,0x00, -0x28,0x40,0x43,0x07,0x84,0x01,0xC9,0x28,0x70,0x7B,0x2A,0x3C,0x01,0xC9,0x18,0x77, -0x1F,0x94,0xC9,0x1C,0x70,0xA0,0x2D,0xA0,0x7F,0x64,0x0F,0x00,0x02,0x2C,0xCC,0xF8, -0x7F,0xA4,0x60,0x00,0x00,0x28,0x40,0x43,0x07,0x84,0x01,0xC9,0x28,0x70,0xBC,0x6C, -0xC9,0x1C,0x70,0x7B,0x26,0x04,0xC9,0x2C,0x40,0x9C,0x6C,0x40,0x87,0x50,0xE0,0x40, -0xA0,0x40,0xA0,0x7F,0x64,0x0F,0x00,0x02,0x2C,0xCC,0xF8,0x7F,0xA4,0x60,0x00,0x00, -0x28,0x40,0x43,0x07,0x84,0x01,0xC9,0x28,0x70,0x94,0x6C,0x70,0x43,0xD9,0x3C,0x01, -0x64,0x77,0x2E,0x7B,0x1B,0xA0,0x68,0xA0,0x7F,0x64,0x0F,0x00,0x02,0x2C,0xCC,0xF8, -0x7F,0xA4,0x60,0x00,0x00,0x28,0x40,0x43,0x07,0x84,0x01,0xC9,0x28,0x70,0x84,0xC9, -0x1C,0x40,0x94,0xC9,0x1C,0x70,0xDC,0x01,0x6C,0x41,0x3C,0x41,0x40,0x47,0xD8,0x7B, -0x75,0x87,0xDA,0x00,0xE0,0x40,0xA0,0x40,0xA0,0x7F,0x64,0x0F,0x00,0x02,0x2C,0xCC, -0xF8,0x7F,0xA4,0x60,0x00,0x00,0x28,0x40,0x43,0x07,0x84,0x01,0xC9,0x28,0x70,0x7B, -0x55,0x3C,0x6F,0x6F,0x40,0x7E,0x43,0xFE,0x47,0x2F,0x3C,0x6F,0x63,0x40,0x7E,0x7A, -0xFD,0x47,0x1D,0x3C,0x6F,0x4F,0x40,0x7E,0x31,0xFE,0x47,0x0B,0x3C,0x6F,0x44,0x40, -0x7E,0x1C,0xFE,0x7B,0xBE,0x3C,0x6F,0x58,0x40,0x7E,0x0C,0xFE,0x7B,0xB5,0x3C,0x6F, -0x64,0x40,0x7E,0x0A,0xFE,0x7B,0xAC,0x3C,0x6F,0x75,0x40,0x7E,0x06,0xFE,0x47,0x0B, -0x3C,0x6F,0x73,0x40,0x7E,0x7A,0xFD,0x7B,0x9A,0x3C,0x6F,0x78,0x40,0x7E,0xE8,0xFD, -0x7B,0x91,0x7B,0x8F,0x7B,0x20,0x87,0xDA,0x00,0xE0,0x40,0xA0,0x40,0xA0,0x7F,0x64, -0x0F,0x00,0x02,0x2C,0xCC,0xF8,0x7F,0xA4,0x60,0x00,0x00,0x28,0x40,0x43,0x07,0x84, -0x01,0xC9,0x28,0x70,0x90,0x5A,0x70,0x2B,0xDA,0x00,0x76,0x93,0xFC,0x3C,0x01,0xC9, -0x28,0x77,0x17,0xA0,0x0A,0xA0,0x7F,0x64,0x0F,0x00,0x02,0x2C,0xCC,0xF8,0x7F,0xA4, -0x60,0x00,0x00,0x84,0xFF,0x40,0x7B,0x07,0x84,0x01,0x40,0x7B,0x02,0x04,0xC9,0xE8, -0x4C,0x20,0x49,0x08,0x10,0x49,0x9C,0x4F,0x04,0x00,0x00,0x00,0x4C,0x3F,0x01,0xEF, -0x10,0x05,0x00,0x00,0x7F,0x2B,0x3F,0x6F,0x64,0x7F,0x03,0x20,0x04,0x00,0x7F,0x21, -0x80,0xEF,0x8C,0x04,0x00,0x00,0x70,0x80,0xEF,0x14,0x05,0x00,0x00,0x70,0x83,0x7F, -0x0D,0x90,0x04,0x00,0x70,0x87,0x04,0x7F,0x0E,0x90,0x04,0x00,0x70,0x7B,0x00,0xDC, -0x02,0x7F,0xA4,0x04,0x00,0x00,0x40,0x2B,0x50,0x7F,0x15,0xDC,0x04,0x7F,0xA4,0x04, -0x00,0x00,0x40,0x3F,0x01,0x50,0x77,0x08,0x24,0x7F,0x34,0x63,0x00,0x00,0x87,0x73, -0xE2,0x40,0x86,0x40,0x62,0x70,0x3C,0x7F,0x64,0x0F,0x00,0x02,0x74,0x7F,0x08,0x24, -0x7F,0x3C,0x62,0x00,0x00,0x2B,0x7F,0x68,0x08,0x00,0x02,0x7F,0x08,0x24,0x7F,0x3C, -0x62,0x00,0x00,0xDC,0x01,0x74,0x40,0x3B,0x50,0x01,0x77,0x08,0x24,0x7F,0x3C,0x62, -0x00,0x00,0xDC,0x01,0x74,0x40,0x3B,0x50,0x5F,0x80,0x00,0x7F,0x53,0xDC,0x02,0x74, -0x40,0x87,0x6F,0x40,0x50,0x70,0xDC,0x02,0x74,0x40,0x87,0x6F,0x50,0x50,0x70,0xDC, -0x03,0x74,0x40,0x87,0x50,0xE2,0x40,0x86,0x40,0x59,0x70,0x7B,0x20,0xDC,0x02,0x74, -0x40,0x87,0x6F,0x40,0x50,0x70,0xDC,0x02,0x74,0x40,0x87,0x6F,0x50,0x50,0x70,0xDC, -0x03,0x74,0x40,0x87,0x50,0xE2,0x40,0x86,0x40,0x59,0x70,0xDC,0x01,0x74,0x40,0x3B, -0x50,0x01,0x77,0xDB,0x86,0xFF,0x62,0x70,0x24,0x7F,0x3C,0x62,0x00,0x00,0xDC,0x03, -0x74,0x40,0x3F,0x13,0x50,0x7F,0x08,0x24,0x7F,0x3C,0x62,0x00,0x00,0x7B,0x34,0x3F, -0x01,0xEF,0x10,0x05,0x00,0x00,0x7F,0x2B,0x3F,0x6F,0x64,0x7F,0x03,0x20,0x04,0x00, -0x7F,0x21,0x80,0xEF,0x8C,0x04,0x00,0x00,0x70,0x80,0xEF,0x14,0x05,0x00,0x00,0x70, -0x83,0x7F,0x0D,0x90,0x04,0x00,0x70,0x87,0x04,0x7F,0x0E,0x90,0x04,0x00,0x70,0x7B, -0x00,0xDC,0x01,0x74,0x40,0x3B,0x50,0x01,0x7F,0xC7,0xDC,0x01,0x74,0x40,0x3B,0x50, -0x5F,0x80,0x00,0x7F,0x4D,0xDC,0x02,0x74,0x40,0x87,0x6F,0x40,0x50,0x70,0xDC,0x02, -0x74,0x40,0x87,0x6F,0x50,0x50,0x70,0xDC,0x03,0x74,0x40,0x87,0x50,0xE2,0x40,0x86, -0x40,0x59,0x70,0x7B,0x20,0xDC,0x02,0x74,0x40,0x87,0x6F,0x40,0x50,0x70,0xDC,0x02, -0x74,0x40,0x87,0x6F,0x50,0x50,0x70,0xDC,0x03,0x74,0x40,0x87,0x50,0xE2,0x40,0x86, -0x40,0x59,0x70,0xDC,0x01,0x74,0x40,0x3B,0x50,0x01,0x77,0xDB,0x86,0xFF,0x62,0x70, -0xDC,0x03,0x74,0x40,0x87,0x50,0xE2,0x40,0x86,0x40,0x59,0x70,0x7B,0x34,0x3F,0x01, -0xEF,0x10,0x05,0x00,0x00,0x7F,0x2B,0x3F,0x6F,0x64,0x7F,0x03,0x20,0x04,0x00,0x7F, -0x21,0x80,0xEF,0x8C,0x04,0x00,0x00,0x70,0x80,0xEF,0x14,0x05,0x00,0x00,0x70,0x83, -0x7F,0x0D,0x90,0x04,0x00,0x70,0x87,0x04,0x7F,0x0E,0x90,0x04,0x00,0x70,0x7B,0x00, -0xDC,0x01,0x74,0x40,0x3B,0x50,0x04,0x7F,0xC7,0x3C,0x7F,0x64,0x0F,0x00,0x02,0x74, -0x77,0x56,0xDC,0x03,0x74,0x40,0x87,0x73,0x50,0x70,0x3F,0x0A,0x73,0x77,0x47,0x7B, -0x34,0x3F,0x01,0xEF,0x10,0x05,0x00,0x00,0x7F,0x2B,0x3F,0x6F,0x64,0x7F,0x03,0x20, -0x04,0x00,0x7F,0x21,0x80,0xEF,0x8C,0x04,0x00,0x00,0x70,0x80,0xEF,0x14,0x05,0x00, -0x00,0x70,0x83,0x7F,0x0D,0x90,0x04,0x00,0x70,0x87,0x04,0x7F,0x0E,0x90,0x04,0x00, -0x70,0x7B,0x00,0xDC,0x01,0x74,0x40,0x3B,0x50,0x04,0x7F,0xC7,0xDC,0x03,0x74,0x40, -0x87,0x0D,0x50,0x70,0x7B,0x19,0x3F,0x0A,0x73,0x77,0x0C,0xDC,0x03,0x74,0x40,0x87, -0x0D,0x50,0x70,0x7B,0x0A,0xDC,0x03,0x74,0x40,0x87,0x73,0x50,0x70,0x7B,0x34,0x3F, -0x01,0xEF,0x10,0x05,0x00,0x00,0x7F,0x2B,0x3F,0x6F,0x64,0x7F,0x03,0x20,0x04,0x00, -0x7F,0x21,0x80,0xEF,0x8C,0x04,0x00,0x00,0x70,0x80,0xEF,0x14,0x05,0x00,0x00,0x70, -0x83,0x7F,0x0D,0x90,0x04,0x00,0x70,0x87,0x04,0x7F,0x0E,0x90,0x04,0x00,0x70,0x7B, -0x00,0xDC,0x01,0x74,0x40,0x3B,0x50,0x04,0x7F,0xC7,0x86,0x62,0xE4,0x40,0x24,0x7F, -0x07,0x64,0x00,0x00,0x87,0x73,0xE0,0x40,0xA0,0x40,0x2C,0xCC,0xFC,0x7F,0xCC,0x71, -0x00,0x00,0x86,0x40,0x59,0x70,0x3E,0xFF,0x59,0x77,0x0C,0x86,0x59,0xE4,0x40,0x24, -0x7F,0x07,0x64,0x00,0x00,0x3E,0x13,0x59,0x77,0x44,0x7B,0x34,0x3F,0x01,0xEF,0x10, -0x05,0x00,0x00,0x7F,0x2B,0x3F,0x6F,0x64,0x7F,0x03,0x20,0x04,0x00,0x7F,0x21,0x80, -0xEF,0x8C,0x04,0x00,0x00,0x70,0x80,0xEF,0x14,0x05,0x00,0x00,0x70,0x83,0x7F,0x0D, -0x90,0x04,0x00,0x70,0x87,0x04,0x7F,0x0E,0x90,0x04,0x00,0x70,0x7B,0x00,0xA0,0x01, -0x2C,0xCC,0xFC,0x7F,0x0C,0x70,0x00,0x00,0x28,0x40,0x7F,0xC2,0x3F,0x0A,0x73,0x77, -0x62,0xA0,0x0D,0x2C,0xCC,0xFC,0x7F,0xCC,0x71,0x00,0x00,0x86,0x40,0x59,0x70,0x3E, -0xFF,0x59,0x77,0x08,0x86,0x59,0xE4,0x40,0x7B,0x4F,0x3E,0x13,0x59,0x77,0x44,0x7B, -0x34,0x3F,0x01,0xEF,0x10,0x05,0x00,0x00,0x7F,0x2B,0x3F,0x6F,0x64,0x7F,0x03,0x20, -0x04,0x00,0x7F,0x21,0x80,0xEF,0x8C,0x04,0x00,0x00,0x70,0x80,0xEF,0x14,0x05,0x00, -0x00,0x70,0x83,0x7F,0x0D,0x90,0x04,0x00,0x70,0x87,0x04,0x7F,0x0E,0x90,0x04,0x00, -0x70,0x7B,0x00,0xA0,0x01,0x2C,0xCC,0xFC,0x7F,0x0C,0x70,0x00,0x00,0x28,0x40,0x7F, -0xC2,0x86,0x59,0xE4,0x40,0x7B,0x02,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70, -0x10,0x45,0x9C,0x4F,0x1C,0x00,0x00,0x00,0x4C,0x04,0x78,0x68,0x70,0x24,0x7F,0xF0, -0x65,0x00,0x00,0x80,0x46,0x7B,0x0F,0x2B,0xDA,0x04,0x77,0x07,0x84,0x01,0x46,0x7B, -0x0B,0x90,0x74,0x70,0x3F,0x25,0xDA,0x04,0x77,0xEF,0x28,0x46,0x7F,0x08,0x24,0x7F, -0xF6,0x65,0x00,0x00,0x7B,0x05,0x90,0x5A,0x70,0x3F,0x20,0xDA,0x00,0x77,0x07,0x84, -0x01,0x40,0x7B,0x04,0x80,0x40,0x84,0x40,0x6C,0x70,0x3F,0x09,0xDA,0x00,0x77,0x07, -0x84,0x01,0x40,0x7B,0x04,0x80,0x40,0x84,0x40,0xC9,0x10,0x70,0x3F,0x2D,0xDA,0x00, -0x77,0x07,0x84,0x01,0x40,0x7B,0x04,0x80,0x40,0x84,0x40,0xC9,0x14,0x70,0x3F,0x2C, -0xDA,0x00,0x77,0x07,0x84,0x01,0x40,0x7B,0x04,0x80,0x40,0x84,0x40,0xC9,0x18,0x70, -0x3F,0x3D,0xDA,0x00,0x77,0x07,0x84,0x01,0x40,0x7B,0x04,0x80,0x40,0xF0,0xC9,0x10, -0x6C,0x41,0xB0,0xC9,0x14,0x41,0xB0,0xC9,0x18,0x41,0xB0,0x41,0x40,0x77,0x99,0x90, -0x74,0x70,0x87,0xDA,0x04,0xE0,0x40,0x24,0x7F,0xC2,0x65,0x00,0x00,0x84,0x5A,0x48, -0xE0,0x5A,0x2C,0xCC,0xFC,0xAF,0x46,0x01,0x7B,0x14,0x84,0xD9,0x08,0x40,0x70,0x84, -0x48,0x41,0x90,0x48,0x87,0x51,0x50,0x70,0x90,0xD9,0x08,0x70,0x3C,0x5A,0x48,0x77, -0xEB,0x84,0xD9,0x08,0x40,0x83,0x50,0x70,0x24,0x7F,0xEC,0x65,0x00,0x00,0x84,0xD9, -0x08,0x40,0x87,0xDA,0x00,0x50,0x70,0x90,0x5A,0x70,0x24,0x7F,0xEC,0x65,0x00,0x00, -0x84,0x07,0x46,0x7B,0x0E,0x04,0x59,0x40,0x9C,0x46,0x40,0x87,0x30,0x50,0x70,0x94, -0x46,0x28,0x46,0x43,0xF2,0x84,0x5A,0x48,0x04,0x67,0x47,0xE0,0x5A,0x2C,0xCC,0xFC, -0xAF,0xEB,0x00,0x94,0x5A,0x70,0x87,0xDA,0x00,0x57,0x70,0x3C,0x48,0x5A,0x77,0x04, -0x7B,0x09,0x94,0x47,0x94,0x5A,0x70,0x7B,0xEF,0x80,0x45,0x04,0x59,0x47,0x84,0x07, -0x46,0x7B,0x1D,0x87,0x57,0xE0,0x40,0xA0,0x40,0x2C,0xCC,0xFC,0xAF,0x5F,0x01,0xD0, -0x02,0x46,0x41,0xD0,0x41,0x40,0x40,0xB0,0x40,0x45,0x90,0x47,0x94,0x46,0x28,0x46, -0x43,0xE3,0xE0,0x5A,0x2C,0xCC,0xFC,0xAF,0xA4,0x00,0x3F,0x6F,0x78,0xDA,0x04,0x77, -0x12,0x84,0xD9,0x08,0x40,0x84,0x45,0x41,0x86,0x41,0x41,0x86,0x41,0x50,0x70,0x7B, -0x0A,0x84,0xD9,0x08,0x40,0x84,0x45,0x50,0x70,0x7B,0x63,0x3F,0x6F,0x64,0xDA,0x04, -0x77,0x16,0xA0,0x5A,0x2C,0xCC,0xFC,0x7F,0x4C,0xE9,0x00,0x00,0x84,0xD9,0x08,0x41, -0x86,0x40,0x51,0x70,0x7B,0x14,0xA0,0x5A,0x2C,0xCC,0xFC,0x7F,0xB4,0xE8,0x00,0x00, -0x84,0xD9,0x08,0x41,0x84,0x40,0x51,0x70,0xE0,0x5A,0x2C,0xCC,0xFC,0xAF,0x4E,0x00, -0x7B,0x2C,0x3C,0x40,0x6F,0x44,0x7F,0xC5,0x3C,0x40,0x6F,0x58,0x7E,0x34,0xFF,0x3C, -0x40,0x6F,0x63,0x7E,0x1B,0xFF,0x3C,0x40,0x6F,0x64,0x7F,0xB1,0x3C,0x40,0x6F,0x73, -0x7E,0xDD,0xFE,0x3C,0x40,0x6F,0x78,0x7E,0x19,0xFF,0x7B,0xD6,0x9C,0x04,0x68,0x70, -0x2B,0xDA,0x04,0x76,0x30,0xFE,0x04,0xC9,0xF8,0x4C,0x20,0x48,0x20,0x47,0x20,0x46, -0x20,0x45,0x20,0x49,0x08,0x70,0x70,0x70,0x10,0x49,0x9C,0x4F,0x14,0x00,0x00,0x00, -0x4C,0x7B,0x06,0x90,0xDA,0x00,0x70,0x84,0xDA,0x00,0x40,0x3F,0x20,0x50,0x7F,0x07, -0x84,0x01,0x40,0x7B,0x04,0x80,0x40,0x84,0x40,0x59,0x70,0x84,0xDA,0x00,0x40,0x3F, -0x09,0x50,0x7F,0x07,0x84,0x01,0x40,0x7B,0x04,0x80,0x40,0x84,0x40,0x64,0x70,0x84, -0xDA,0x00,0x40,0x3F,0x2D,0x50,0x7F,0x07,0x84,0x01,0x40,0x7B,0x04,0x80,0x40,0x84, -0x40,0x68,0x70,0x84,0xDA,0x00,0x40,0x3F,0x2C,0x50,0x7F,0x07,0x84,0x01,0x40,0x7B, -0x04,0x80,0x40,0x84,0x40,0x6C,0x70,0x84,0xDA,0x00,0x40,0x2B,0x50,0x7F,0x07,0x84, -0x01,0x40,0x7B,0x04,0x80,0x40,0x84,0x40,0xC9,0x10,0x70,0x84,0xDA,0x00,0x40,0x3F, -0x3D,0x50,0x7F,0x07,0x84,0x01,0x40,0x7B,0x04,0x80,0x40,0xF8,0x64,0x59,0x41,0xB8, -0x68,0x41,0xB8,0x6C,0x41,0xB8,0xC9,0x10,0x41,0x38,0x41,0x40,0x76,0x77,0xFF,0x04, -0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x10,0x49,0x9C,0x4F,0x04,0x00,0x00,0x00, -0x4C,0x3F,0x39,0x73,0x57,0x07,0x84,0x01,0x40,0x7B,0x04,0x80,0x40,0x84,0x40,0x59, -0x70,0x3F,0x30,0x73,0x5B,0x07,0x84,0x01,0x40,0x7B,0x04,0x80,0x40,0x38,0x40,0x59, -0x7F,0x0C,0xFF,0x30,0x73,0x40,0x87,0x40,0xE0,0x40,0x7B,0x1D,0x3F,0x6F,0x61,0x73, -0x5B,0x0D,0xFF,0x6F,0x57,0x73,0x40,0x87,0x40,0xE0,0x40,0x7B,0x0C,0xFF,0x37,0x73, -0x40,0x87,0x40,0xE0,0x40,0x7B,0x02,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70, -0x10,0x49,0x9C,0x4F,0x08,0x00,0x00,0x00,0x4C,0x87,0x77,0xE0,0x40,0xD0,0x05,0x40, -0x40,0x9C,0x7F,0x90,0x04,0x00,0x00,0x40,0x84,0x40,0x64,0x70,0x80,0x59,0x70,0x7B, -0x15,0x84,0x5A,0x40,0x90,0x5A,0x70,0x84,0x64,0x41,0x90,0x64,0x70,0x87,0x51,0x50, -0x70,0x90,0x59,0x70,0x3C,0x20,0x59,0x5B,0xEA,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08, -0x10,0x49,0x9C,0x4F,0x08,0x00,0x00,0x00,0x4C,0xA0,0x00,0x2C,0xCC,0xFC,0xAF,0xB3, -0x03,0xA0,0x4F,0x0C,0x0E,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xA8,0x5C,0x00,0x00,0x28, -0x40,0x43,0x08,0x24,0x7F,0xEC,0x6A,0x00,0x00,0x84,0xEF,0xE4,0x04,0x00,0x00,0x64, -0x70,0xA0,0x4F,0x2D,0x0E,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xA8,0x5C,0x00,0x00,0x28, -0x40,0x43,0x08,0x24,0x7F,0xEC,0x6A,0x00,0x00,0x3C,0x4F,0x00,0x00,0x10,0x00,0x64, -0x4B,0x26,0xA0,0x4F,0x48,0x0E,0x00,0x00,0xD4,0x14,0xEF,0xE4,0x04,0x00,0x00,0x40, -0xA0,0x40,0x2C,0xCC,0xF8,0x7F,0xA8,0x5C,0x00,0x00,0x28,0x40,0x43,0x08,0x24,0x7F, -0xEC,0x6A,0x00,0x00,0x7B,0x24,0xA0,0x4F,0x57,0x0E,0x00,0x00,0xD4,0x0A,0xEF,0xE4, -0x04,0x00,0x00,0x40,0xA0,0x40,0x2C,0xCC,0xF8,0x7F,0xA8,0x5C,0x00,0x00,0x28,0x40, -0x43,0x08,0x24,0x7F,0xEC,0x6A,0x00,0x00,0x83,0x59,0x70,0x24,0x7F,0xD4,0x6A,0x00, -0x00,0xA0,0x4F,0x64,0x0E,0x00,0x00,0x87,0x59,0xE0,0x40,0xA0,0x40,0x87,0x59,0xE0, -0x40,0xD0,0x05,0x40,0x40,0x9C,0x7F,0x90,0x04,0x00,0x00,0x40,0x9C,0x0C,0x40,0xA0, -0x40,0x2C,0xCC,0xF4,0x7F,0xA8,0x5C,0x00,0x00,0x28,0x40,0x43,0x08,0x24,0x7F,0xEC, -0x6A,0x00,0x00,0xA0,0x4F,0x82,0x0E,0x00,0x00,0x87,0x59,0xE0,0x40,0xD0,0x05,0x40, -0x40,0x9C,0x7F,0x90,0x04,0x00,0x00,0x40,0xCC,0x03,0x08,0x50,0x40,0xA0,0x40,0x87, -0x59,0xE0,0x40,0xD0,0x05,0x40,0x40,0x9C,0x7F,0x90,0x04,0x00,0x00,0x40,0xCC,0x03, -0x0C,0x50,0x40,0xA0,0x40,0x87,0x59,0xE0,0x40,0xD0,0x05,0x40,0x40,0x9C,0x7F,0x90, -0x04,0x00,0x00,0x40,0xCC,0x0F,0x10,0x50,0x40,0xA0,0x40,0x2C,0xCC,0xF0,0x7F,0xA8, -0x5C,0x00,0x00,0x28,0x40,0x43,0x08,0x24,0x7F,0xEC,0x6A,0x00,0x00,0xA0,0x4F,0xB3, -0x0E,0x00,0x00,0x87,0x59,0xE0,0x40,0xD0,0x05,0x40,0x40,0x9C,0x7F,0x90,0x04,0x00, -0x00,0x40,0xCC,0x00,0x07,0xC0,0x04,0x40,0x3C,0x00,0x40,0x7F,0x08,0x84,0x6F,0x79, -0x40,0x7B,0x06,0x84,0x6F,0x6E,0x40,0xA0,0x40,0x87,0x59,0xE0,0x40,0xD0,0x05,0x40, -0x40,0x9C,0x7F,0x90,0x04,0x00,0x00,0x40,0xCC,0x00,0x05,0xC0,0x04,0x40,0x3C,0x00, -0x40,0x7F,0x0B,0x84,0x4F,0xF6,0x0E,0x00,0x00,0x40,0x7B,0x09,0x84,0x4F,0xFD,0x0E, -0x00,0x00,0x40,0xA0,0x40,0x87,0x59,0xE0,0x40,0xD0,0x05,0x40,0x40,0x9C,0x7F,0x90, -0x04,0x00,0x00,0x40,0xCC,0x00,0x06,0xC0,0x04,0x40,0x9C,0x01,0x40,0xA0,0x40,0x2C, -0xCC,0xF0,0x7F,0xA8,0x5C,0x00,0x00,0x28,0x40,0x43,0x08,0x24,0x7F,0xEC,0x6A,0x00, -0x00,0xA0,0x4F,0x04,0x0F,0x00,0x00,0x87,0x59,0xE0,0x40,0xD0,0x05,0x40,0x40,0x9C, -0x7F,0x90,0x04,0x00,0x00,0x40,0xCC,0x07,0x00,0x50,0x40,0xA0,0x40,0x87,0x59,0xE0, -0x40,0xD0,0x05,0x40,0x40,0x9C,0x7F,0x90,0x04,0x00,0x00,0x40,0xCC,0x07,0x18,0xC0, -0x04,0x40,0xA0,0x40,0x2C,0xCC,0xF4,0x7F,0xA8,0x5C,0x00,0x00,0x28,0x40,0x43,0x08, -0x24,0x7F,0xEC,0x6A,0x00,0x00,0xA0,0x4F,0x35,0x0F,0x00,0x00,0x87,0x59,0xE0,0x40, -0xD0,0x05,0x40,0x40,0x9C,0x7F,0x90,0x04,0x00,0x00,0x40,0xCC,0x00,0x09,0xC0,0x04, -0x40,0x3C,0x00,0x40,0x7F,0x08,0x84,0x6F,0x79,0x40,0x7B,0x06,0x84,0x6F,0x6E,0x40, -0xA0,0x40,0x2C,0xCC,0xF8,0x7F,0xA8,0x5C,0x00,0x00,0x28,0x40,0x43,0x08,0x24,0x7F, -0xEC,0x6A,0x00,0x00,0x87,0x59,0xE0,0x40,0xD0,0x05,0x40,0x40,0x9C,0x7F,0x90,0x04, -0x00,0x00,0x40,0xCC,0x00,0x09,0xC0,0x04,0x40,0x3C,0x00,0x40,0x7F,0x42,0xA0,0x4F, -0x4A,0x0F,0x00,0x00,0x87,0x59,0xE0,0x40,0xD0,0x05,0x40,0x40,0x9C,0x7F,0x90,0x04, -0x00,0x00,0x40,0xCC,0x00,0x08,0xC0,0x04,0x40,0x3C,0x00,0x40,0x7F,0x08,0x84,0x6F, -0x79,0x40,0x7B,0x06,0x84,0x6F,0x6E,0x40,0xA0,0x40,0x2C,0xCC,0xF8,0x7F,0xA8,0x5C, -0x00,0x00,0x28,0x40,0x43,0x08,0x24,0x7F,0xEC,0x6A,0x00,0x00,0x7B,0x1A,0xA0,0x4F, -0x5B,0x0F,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xA8,0x5C,0x00,0x00,0x28,0x40,0x43,0x08, -0x24,0x7F,0xEC,0x6A,0x00,0x00,0x83,0x61,0x70,0x24,0x7F,0x80,0x6A,0x00,0x00,0x2B, -0x61,0x77,0x1A,0xA0,0x4F,0x6B,0x0F,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xA8,0x5C,0x00, -0x00,0x28,0x40,0x43,0x08,0x24,0x7F,0xEC,0x6A,0x00,0x00,0xA0,0x4F,0x7E,0x0F,0x00, -0x00,0x87,0x61,0xE0,0x40,0xA4,0xE0,0x02,0x40,0x77,0x0B,0x84,0x4F,0x9F,0x0F,0x00, -0x00,0x40,0x7B,0x09,0x84,0x4F,0xA6,0x0F,0x00,0x00,0x40,0xA0,0x40,0x87,0x61,0xE0, -0x40,0xA0,0x40,0x87,0x59,0xE0,0x40,0xD0,0x05,0x40,0x40,0x9C,0x7F,0x90,0x04,0x00, -0x00,0x40,0xEB,0x0C,0x61,0x41,0xDC,0x41,0xC0,0x08,0x40,0x9C,0x02,0x40,0xA0,0x40, -0x87,0x59,0xE0,0x40,0xD0,0x05,0x40,0x40,0x9C,0x7F,0x90,0x04,0x00,0x00,0x40,0xEB, -0x0C,0x61,0x41,0xDC,0x41,0xC0,0x08,0x40,0x86,0xE2,0x50,0xE0,0x40,0xA0,0x40,0x2C, -0xCC,0xEC,0x7F,0xA8,0x5C,0x00,0x00,0x28,0x40,0x43,0x04,0x7B,0x71,0x93,0x61,0x70, -0x87,0x61,0xE0,0x40,0x87,0x59,0xE0,0x41,0xD0,0x05,0x41,0x41,0x9C,0x7F,0x90,0x04, -0x00,0x00,0x41,0xCC,0x03,0x00,0xC1,0x04,0x41,0x3C,0x41,0x40,0x5A,0x53,0xFF,0x87, -0x59,0xE0,0x40,0xFF,0x01,0xEF,0xE0,0x04,0x00,0x00,0x41,0x3C,0x41,0x40,0x53,0x23, -0xA0,0x4F,0xA9,0x0F,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xA8,0x5C,0x00,0x00,0x28,0x40, -0x43,0x04,0x7B,0x2A,0x7B,0x02,0x2C,0x5C,0xEF,0xC8,0x04,0x00,0x00,0x28,0x40,0x7F, -0xF7,0x93,0x59,0x70,0x3F,0xEF,0xE0,0x04,0x00,0x00,0x59,0x5A,0x06,0xFD,0xA0,0x4F, -0xC6,0x0F,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xA8,0x5C,0x00,0x00,0xA0,0x01,0x2C,0xCC, -0xFC,0xAF,0x10,0x00,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x70,0x10,0x49, -0x9C,0x4F,0x04,0x00,0x00,0x00,0x4C,0x87,0x73,0x7F,0x68,0x08,0x00,0x02,0x70,0x2B, -0x73,0x77,0x37,0x7B,0x28,0xDC,0x02,0x7F,0x64,0x0F,0x00,0x02,0x40,0x87,0x6F,0x40, -0x50,0x70,0xDC,0x02,0x7F,0x64,0x0F,0x00,0x02,0x40,0x87,0x6F,0x50,0x50,0x70,0xDC, -0x03,0x7F,0x64,0x0F,0x00,0x02,0x40,0x87,0x50,0x59,0x70,0xDC,0x01,0x7F,0x64,0x0F, -0x00,0x02,0x40,0x3B,0x50,0x01,0x77,0xCF,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70, -0x10,0x48,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0xF8,0x5F,0x00,0xF0,0x5A,0x40,0xF8, -0x5F,0xFF,0x0F,0x5A,0x41,0xD0,0x03,0x41,0x41,0x9C,0x41,0x40,0x84,0x40,0x48,0x7B, -0x2A,0x84,0x48,0x40,0x9C,0x04,0x48,0xFB,0x0F,0xC0,0x03,0x40,0x87,0x40,0xDA,0x04, -0x70,0x84,0x74,0x40,0x90,0x74,0x70,0x84,0x48,0x41,0x9C,0x04,0x48,0xF8,0x0F,0x51, -0x41,0xD0,0x04,0x41,0x41,0xB3,0x41,0x50,0x70,0x86,0x7A,0x40,0x96,0x7A,0x70,0x86, -0xE2,0x40,0xE0,0x40,0x77,0xCD,0x80,0x7F,0xE8,0x0F,0x00,0x02,0x70,0xA0,0x7F,0xE8, -0x0F,0x00,0x02,0x37,0x04,0x7B,0x0B,0xA0,0x4A,0xFC,0x0C,0x4C,0x4A,0x7A,0x8F,0x00, -0x7B,0x02,0x04,0xC9,0xEC,0x4C,0x20,0x48,0x20,0x49,0x08,0x70,0x10,0x48,0x9C,0x4F, -0x00,0x00,0x00,0x00,0x4C,0xF8,0x5F,0x00,0xF0,0x74,0x40,0xF8,0x5F,0xFF,0x0F,0x74, -0x41,0xD0,0x03,0x41,0x41,0x9C,0x41,0x40,0x84,0x40,0x48,0x7B,0x2B,0x84,0x48,0x40, -0x9C,0x04,0x48,0xFB,0x0F,0xDA,0x00,0x41,0x84,0x41,0x50,0x70,0x84,0x48,0x40,0x9C, -0x04,0x48,0x84,0x5A,0x41,0x90,0x5A,0x70,0xFB,0x5F,0xF0,0x00,0x51,0x41,0xD4,0x04, -0x41,0x41,0x84,0x41,0x50,0x70,0x86,0x7A,0x40,0x96,0x7A,0x70,0x86,0xE2,0x40,0xE0, -0x40,0x77,0xCC,0x84,0x01,0x7F,0xE8,0x0F,0x00,0x02,0x70,0xA0,0x7F,0xE8,0x0F,0x00, -0x02,0x37,0x04,0x7B,0x0B,0xA0,0x4A,0xFC,0x0C,0x4C,0x4A,0x7A,0x11,0x00,0x7B,0x02, -0x04,0xC9,0xEC,0x4C,0x20,0x48,0x20,0x49,0x08,0x70,0x70,0x70,0x10,0x47,0x9C,0x4F, -0x00,0x00,0x00,0x00,0x4C,0x82,0x48,0x84,0x4F,0x00,0x30,0x04,0x00,0x47,0x7B,0x40, -0x86,0xE2,0x48,0xE0,0x40,0x86,0xE2,0xC7,0x02,0xE0,0x41,0xBA,0x0F,0x41,0x86,0xE2, -0x41,0xE0,0x41,0x9C,0x41,0x40,0x86,0x40,0x48,0x86,0xE2,0x48,0xE0,0x40,0xD0,0x01, -0x40,0x40,0x86,0xE2,0x40,0xE0,0x40,0x86,0xE2,0x48,0xE0,0x41,0xD4,0x0F,0x41,0x41, -0x86,0xE2,0x41,0xE0,0x41,0xB0,0x41,0x40,0x86,0x40,0x48,0x9C,0x04,0x47,0x3C,0x4F, -0x00,0x38,0x04,0x00,0x47,0x5B,0xBB,0x86,0xE2,0x48,0xE0,0x40,0x88,0x40,0x40,0x86, -0x40,0x48,0x3F,0x01,0x73,0x77,0x41,0x86,0xE2,0x48,0xE0,0x40,0xB8,0x0F,0x40,0x84, -0x40,0x57,0x70,0x86,0xE2,0x48,0xE0,0x40,0xD4,0x04,0x40,0x40,0xB8,0x0F,0x40,0x84, -0x40,0xC7,0x04,0x70,0x86,0xE2,0x48,0xE0,0x40,0xD4,0x08,0x40,0x40,0xB8,0x0F,0x40, -0x84,0x40,0xC7,0x08,0x70,0x86,0xE2,0x48,0xE0,0x40,0xD4,0x0C,0x40,0x40,0xB8,0x0F, -0x40,0x84,0x40,0xC7,0x0C,0x70,0x86,0xE2,0x48,0xE0,0x40,0x86,0xE2,0xC7,0x02,0xE0, -0x41,0xBA,0x0F,0x41,0x86,0xE2,0x41,0xE0,0x41,0xF8,0x0F,0xC7,0x04,0x42,0xD0,0x04, -0x42,0x42,0x86,0xE2,0x42,0xE0,0x42,0xB0,0x42,0x41,0x86,0xE2,0x41,0xE0,0x41,0xF8, -0x0F,0xC7,0x08,0x42,0xD0,0x08,0x42,0x42,0x86,0xE2,0x42,0xE0,0x42,0xB0,0x42,0x41, -0x86,0xE2,0x41,0xE0,0x41,0xF8,0x0F,0xC7,0x0C,0x42,0xD0,0x0C,0x42,0x42,0x86,0xE2, -0x42,0xE0,0x42,0xB0,0x42,0x41,0x86,0xE2,0x41,0xE0,0x41,0x3C,0x41,0x40,0x77,0x07, -0x84,0x01,0x40,0x7B,0x06,0x80,0x40,0x7B,0x02,0x04,0xC9,0xF0,0x4C,0x20,0x48,0x20, -0x47,0x20,0x49,0x08,0x84,0x5A,0x40,0x84,0x74,0x42,0xC4,0x02,0x42,0x42,0x80,0x50, -0x70,0x94,0x42,0x4F,0x08,0x04,0xC0,0x04,0x41,0x30,0x19,0x08,0x84,0x5A,0x40,0x70, -0x28,0x40,0x77,0x09,0x04,0x7F,0xEC,0x0F,0x00,0x02,0x40,0x84,0x43,0x50,0x70,0x84, -0x44,0xC0,0x04,0x70,0x84,0x45,0xC0,0x08,0x70,0x84,0x46,0xC0,0x0C,0x70,0x84,0x47, -0xC0,0x10,0x70,0x84,0x48,0xC0,0x14,0x70,0x84,0xCC,0xFC,0xC0,0x18,0x70,0x84,0xCC, -0xF8,0xC0,0x1C,0x70,0x84,0x4A,0xC0,0x20,0x70,0x84,0x49,0xC0,0x24,0x70,0x84,0xCD, -0x0C,0xC0,0x28,0x70,0x84,0xCD,0x10,0xC0,0x2C,0x70,0x80,0x40,0x08,0x84,0x5A,0x40, -0x70,0x28,0x40,0x77,0x09,0x04,0x7F,0xEC,0x0F,0x00,0x02,0x40,0x84,0x50,0x43,0x84, -0xC0,0x04,0x44,0x84,0xC0,0x08,0x45,0x84,0xC0,0x0C,0x46,0x84,0xC0,0x10,0x47,0x84, -0xC0,0x14,0x48,0x84,0xC0,0x18,0x4A,0x84,0xC0,0x1C,0x41,0x84,0xC0,0x20,0x4C,0x84, -0xC0,0x24,0x49,0x84,0xC0,0x28,0xCD,0x0C,0x70,0x84,0xC0,0x2C,0xCD,0x10,0x70,0x80, -0x40,0x90,0x40,0x24,0x51,0x70,0x70,0x70,0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00, -0x4C,0x87,0x01,0x7F,0x1C,0x10,0x00,0x02,0x70,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08, -0x10,0x49,0x9C,0x4F,0x08,0x00,0x00,0x00,0x4C,0x83,0x7F,0x1C,0x10,0x00,0x02,0x70, -0x84,0xEF,0x94,0x04,0x00,0x00,0x64,0x70,0x84,0x4F,0x18,0x6E,0x00,0x00,0xEF,0x94, -0x04,0x00,0x00,0x70,0xF3,0x30,0x7F,0xD0,0x0F,0x00,0x02,0x40,0x87,0x40,0x7F,0x04, -0x90,0x04,0x00,0x70,0x24,0x7F,0xE8,0x6E,0x00,0x00,0x87,0x7F,0x0F,0x90,0x04,0x00, -0x59,0x70,0x87,0x08,0x7F,0x06,0x90,0x04,0x00,0x70,0x87,0x5F,0xFF,0x00,0x7F,0x07, -0x90,0x04,0x00,0x70,0x87,0x7F,0x0E,0x90,0x04,0x00,0x59,0x70,0x7B,0x53,0x3F,0x01, -0xEF,0x10,0x05,0x00,0x00,0x7F,0x2B,0x3F,0x6F,0x64,0x7F,0x03,0x20,0x04,0x00,0x7F, -0x21,0x80,0xEF,0x8C,0x04,0x00,0x00,0x70,0x80,0xEF,0x14,0x05,0x00,0x00,0x70,0x83, -0x7F,0x0D,0x90,0x04,0x00,0x70,0x87,0x04,0x7F,0x0E,0x90,0x04,0x00,0x70,0x7B,0x00, -0x2B,0x7F,0x1C,0x10,0x00,0x02,0x7F,0x19,0x87,0x7F,0x0F,0x90,0x04,0x00,0x59,0x70, -0x84,0x64,0xEF,0x94,0x04,0x00,0x00,0x70,0x86,0xE2,0x72,0xE0,0x40,0x7B,0x2D,0x3B, -0x7F,0x05,0x90,0x04,0x00,0x08,0x7F,0xA8,0x86,0x72,0x40,0x96,0x72,0x70,0x86,0xE2, -0x40,0xE0,0x40,0x76,0x77,0xFF,0x87,0x7F,0x0F,0x90,0x04,0x00,0x59,0x70,0x84,0x64, -0xEF,0x94,0x04,0x00,0x00,0x70,0x80,0x40,0x7B,0x02,0x04,0xC9,0xE8,0x4C,0x20,0x49, -0x08,0x70,0x70,0x70,0x10,0x49,0x9C,0x4F,0x08,0x00,0x00,0x00,0x4C,0x83,0x64,0x70, -0x84,0xEF,0x94,0x04,0x00,0x00,0x7F,0x40,0x10,0x00,0x02,0x70,0x84,0x4F,0xB0,0x76, -0x00,0x00,0xEF,0x94,0x04,0x00,0x00,0x70,0x70,0xCC,0x03,0x0D,0x4B,0x7F,0x3C,0x10, -0x00,0x02,0x70,0xC8,0x03,0x0D,0x0F,0x4B,0x84,0x4F,0x30,0x10,0x00,0x02,0x7F,0x00, -0x00,0x00,0x02,0x70,0x84,0x4F,0xF4,0x37,0x00,0x02,0x7F,0x30,0x10,0x00,0x02,0x70, -0x84,0x4F,0xEC,0x37,0x00,0x02,0x7F,0x34,0x10,0x00,0x02,0x70,0x87,0x02,0x7F,0x38, -0x10,0x00,0x02,0x70,0x87,0x02,0x7F,0x39,0x10,0x00,0x02,0x70,0x87,0x01,0x7F,0x3B, -0x10,0x00,0x02,0x70,0xA0,0x4F,0xEC,0x37,0x00,0x02,0xA0,0x5F,0x14,0x08,0x2C,0xCC, -0xF8,0xEF,0x18,0x05,0x00,0x00,0xD0,0x15,0x5A,0x40,0x87,0xC0,0x01,0xE0,0x59,0x70, -0xA0,0x14,0x2C,0xCC,0xFC,0xEF,0x28,0x05,0x00,0x00,0xD0,0x15,0x5A,0x40,0x87,0xC0, -0x03,0xE0,0x59,0x70,0x80,0x59,0x70,0x7B,0x34,0x3F,0x03,0x7F,0xEF,0x37,0x00,0x02, -0x77,0x08,0x87,0x01,0x64,0x70,0x7B,0x2C,0x3C,0x5F,0xFF,0x0F,0x59,0x77,0x1B,0xD0, -0x15,0x5A,0x40,0x87,0x01,0xC0,0x05,0x70,0xA0,0x14,0x2C,0xCC,0xFC,0xEF,0x28,0x05, -0x00,0x00,0x87,0x64,0xE0,0x40,0x7B,0x1F,0x90,0x59,0x70,0x3C,0x5F,0xFF,0x0F,0x59, -0x5F,0xC9,0x2C,0x5C,0xAF,0x26,0x07,0x3C,0x01,0x40,0x7F,0x05,0x83,0x64,0x70,0x87, -0x64,0xE0,0x40,0x7B,0x02,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x10,0x49,0x9C,0x4F, -0x04,0x00,0x00,0x00,0x4C,0x84,0xEF,0x94,0x04,0x00,0x00,0x7F,0x40,0x10,0x00,0x02, -0x70,0x84,0x4F,0xB0,0x76,0x00,0x00,0xEF,0x94,0x04,0x00,0x00,0x70,0x70,0xCC,0x03, -0x0D,0x4B,0x7F,0x3C,0x10,0x00,0x02,0x70,0xC8,0x03,0x0D,0x0F,0x4B,0x87,0x08,0x7F, -0xF7,0x37,0x00,0x02,0x70,0x3F,0x01,0x73,0x77,0x18,0xDC,0x03,0x7F,0xA4,0x04,0x00, -0x00,0x40,0xF3,0x20,0x50,0x40,0x87,0x40,0x7F,0xF6,0x37,0x00,0x02,0x70,0x7B,0x19, -0xDC,0x03,0x7F,0xA4,0x04,0x00,0x00,0x40,0x87,0x50,0x7F,0xF6,0x37,0x00,0x02,0x70, -0x87,0x7F,0xF6,0x37,0x00,0x02,0x40,0x87,0x7F,0x68,0x08,0x00,0x02,0xE0,0x7F,0xF8, -0x37,0x00,0x02,0x70,0x87,0x5F,0xFF,0x00,0x7F,0xEF,0x37,0x00,0x02,0x70,0xDC,0x02, -0x7F,0xA4,0x04,0x00,0x00,0x40,0x87,0x50,0xE0,0x40,0xD0,0x15,0x40,0x40,0x87,0xC0, -0x01,0xE2,0x40,0x86,0x40,0x59,0x70,0x82,0x59,0x70,0x24,0x7F,0xB7,0x71,0x00,0x00, -0x3F,0x5F,0xFF,0x00,0x7F,0xEF,0x37,0x00,0x02,0x7F,0x6E,0x2B,0x7F,0xEF,0x37,0x00, -0x02,0x77,0x50,0x2C,0x5C,0xAF,0x55,0x06,0x3C,0x01,0x40,0x7F,0x18,0x84,0x4F,0xEF, -0xBE,0xED,0xFE,0xEF,0x8C,0x04,0x00,0x00,0x70,0x87,0x01,0x7F,0x0B,0x40,0x04,0x00, -0x70,0x7B,0x00,0x86,0xE2,0x7F,0xEC,0x37,0x00,0x02,0xE0,0x40,0xBA,0x5F,0xFF,0x00, -0x40,0x86,0x40,0x62,0x70,0x86,0xE2,0x62,0xE0,0x40,0x3C,0x5F,0xFF,0x00,0x40,0x77, -0x07,0x84,0xFF,0x40,0x7B,0x07,0x86,0xE2,0x62,0xE0,0x40,0x24,0x7F,0xC4,0x71,0x00, -0x00,0x84,0x4F,0xEF,0xBE,0xED,0xFE,0xEF,0x8C,0x04,0x00,0x00,0x70,0x87,0x01,0x7F, -0x0B,0x40,0x04,0x00,0x70,0x7B,0x00,0x86,0xE2,0x59,0xE0,0x40,0x3C,0x5F,0xFF,0x0F, -0x40,0x77,0x4A,0x3F,0x01,0xEF,0x10,0x05,0x00,0x00,0x7F,0x2B,0x3F,0x6F,0x64,0x7F, -0x03,0x20,0x04,0x00,0x7F,0x21,0x80,0xEF,0x8C,0x04,0x00,0x00,0x70,0x80,0xEF,0x14, -0x05,0x00,0x00,0x70,0x83,0x7F,0x0D,0x90,0x04,0x00,0x70,0x87,0x04,0x7F,0x0E,0x90, -0x04,0x00,0x70,0x7B,0x00,0x84,0x4F,0xEF,0xBE,0xED,0xFE,0xEF,0x8C,0x04,0x00,0x00, -0x70,0x87,0x01,0x7F,0x0B,0x40,0x04,0x00,0x70,0x7B,0x00,0x3F,0x01,0x73,0x77,0x07, -0x92,0x59,0x70,0x7B,0x34,0x3F,0x01,0xEF,0x10,0x05,0x00,0x00,0x7F,0x2B,0x3F,0x6F, -0x64,0x7F,0x03,0x20,0x04,0x00,0x7F,0x21,0x80,0xEF,0x8C,0x04,0x00,0x00,0x70,0x80, -0xEF,0x14,0x05,0x00,0x00,0x70,0x83,0x7F,0x0D,0x90,0x04,0x00,0x70,0x87,0x04,0x7F, -0x0E,0x90,0x04,0x00,0x70,0x7B,0x00,0x86,0xE2,0x59,0xE0,0x40,0x3C,0x5F,0xFF,0x0F, -0x40,0x5E,0xEF,0xFE,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x10,0x49,0x9C,0x4F, -0x04,0x00,0x00,0x00,0x4C,0x84,0xEF,0x94,0x04,0x00,0x00,0x7F,0x40,0x10,0x00,0x02, -0x70,0x84,0x4F,0xB0,0x76,0x00,0x00,0xEF,0x94,0x04,0x00,0x00,0x70,0x70,0xCC,0x03, -0x0D,0x4B,0x7F,0x3C,0x10,0x00,0x02,0x70,0xC8,0x03,0x0D,0x0F,0x4B,0x87,0x09,0x7F, -0xF7,0x37,0x00,0x02,0x70,0xDC,0x03,0x7F,0xA4,0x04,0x00,0x00,0x40,0x87,0x50,0x7F, -0xF6,0x37,0x00,0x02,0x70,0x87,0x73,0xE2,0x40,0x86,0x40,0x7F,0xF4,0x37,0x00,0x02, -0x70,0x87,0x5F,0xFF,0x00,0x7F,0xEF,0x37,0x00,0x02,0x70,0x87,0x7F,0x68,0x08,0x00, -0x02,0xE0,0x7F,0xF8,0x37,0x00,0x02,0x70,0xDC,0x02,0x7F,0xA4,0x04,0x00,0x00,0x40, -0x87,0x50,0xE0,0x40,0xD0,0x15,0x40,0x40,0x87,0xC0,0x01,0xE2,0x40,0x86,0x40,0x59, -0x70,0x82,0x59,0x70,0x24,0x7F,0x98,0x73,0x00,0x00,0x3F,0x5F,0xFF,0x00,0x7F,0xEF, -0x37,0x00,0x02,0x77,0x08,0x24,0x7F,0x41,0x73,0x00,0x00,0x2B,0x7F,0xEF,0x37,0x00, -0x02,0x7F,0x08,0x24,0x7F,0xF9,0x72,0x00,0x00,0x2C,0x5C,0xAF,0x9F,0x04,0x3C,0x01, -0x40,0x7F,0x4A,0x3F,0x01,0xEF,0x10,0x05,0x00,0x00,0x7F,0x2B,0x3F,0x6F,0x64,0x7F, -0x03,0x20,0x04,0x00,0x7F,0x21,0x80,0xEF,0x8C,0x04,0x00,0x00,0x70,0x80,0xEF,0x14, -0x05,0x00,0x00,0x70,0x83,0x7F,0x0D,0x90,0x04,0x00,0x70,0x87,0x04,0x7F,0x0E,0x90, -0x04,0x00,0x70,0x7B,0x00,0x84,0x4F,0xEF,0xBE,0xED,0xFE,0xEF,0x8C,0x04,0x00,0x00, -0x70,0x87,0x01,0x7F,0x0B,0x40,0x04,0x00,0x70,0x7B,0x00,0x86,0xE2,0x7F,0xEC,0x37, -0x00,0x02,0xE0,0x40,0xBA,0x5F,0xFF,0x00,0x40,0x86,0x40,0x62,0x70,0x86,0xE2,0x62, -0xE0,0x40,0x3C,0x5F,0xFF,0x00,0x40,0x77,0x07,0x84,0xFF,0x40,0x7B,0x07,0x86,0xE2, -0x62,0xE0,0x40,0x24,0x7F,0xA5,0x73,0x00,0x00,0x3F,0x01,0xEF,0x10,0x05,0x00,0x00, -0x7F,0x2B,0x3F,0x6F,0x64,0x7F,0x03,0x20,0x04,0x00,0x7F,0x21,0x80,0xEF,0x8C,0x04, -0x00,0x00,0x70,0x80,0xEF,0x14,0x05,0x00,0x00,0x70,0x83,0x7F,0x0D,0x90,0x04,0x00, -0x70,0x87,0x04,0x7F,0x0E,0x90,0x04,0x00,0x70,0x7B,0x00,0x84,0x4F,0xEF,0xBE,0xED, -0xFE,0xEF,0x8C,0x04,0x00,0x00,0x70,0x87,0x01,0x7F,0x0B,0x40,0x04,0x00,0x70,0x7B, -0x00,0x86,0xE2,0x59,0xE0,0x40,0x3C,0x5F,0xFF,0x0F,0x40,0x77,0x4A,0x3F,0x01,0xEF, -0x10,0x05,0x00,0x00,0x7F,0x2B,0x3F,0x6F,0x64,0x7F,0x03,0x20,0x04,0x00,0x7F,0x21, -0x80,0xEF,0x8C,0x04,0x00,0x00,0x70,0x80,0xEF,0x14,0x05,0x00,0x00,0x70,0x83,0x7F, -0x0D,0x90,0x04,0x00,0x70,0x87,0x04,0x7F,0x0E,0x90,0x04,0x00,0x70,0x7B,0x00,0x84, -0x4F,0xEF,0xBE,0xED,0xFE,0xEF,0x8C,0x04,0x00,0x00,0x70,0x87,0x01,0x7F,0x0B,0x40, -0x04,0x00,0x70,0x7B,0x00,0x92,0x59,0x70,0x86,0xE2,0x59,0xE0,0x40,0x3C,0x5F,0xFF, -0x0F,0x40,0x5E,0xB8,0xFE,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x10,0x49,0x9C,0x4F, -0x10,0x00,0x00,0x00,0x4C,0x83,0x64,0x70,0x84,0xEF,0x94,0x04,0x00,0x00,0x7F,0x40, -0x10,0x00,0x02,0x70,0x84,0x4F,0xB0,0x76,0x00,0x00,0xEF,0x94,0x04,0x00,0x00,0x70, -0x70,0xCC,0x03,0x0D,0x4B,0x7F,0x3C,0x10,0x00,0x02,0x70,0xC8,0x03,0x0D,0x0F,0x4B, -0x87,0x07,0x7F,0xF7,0x37,0x00,0x02,0x70,0x87,0x77,0x7F,0xF6,0x37,0x00,0x02,0x70, -0x87,0x5F,0xFF,0x00,0x7F,0xEF,0x37,0x00,0x02,0x70,0x04,0x68,0x7F,0xF8,0x37,0x00, -0x02,0x70,0x86,0xEF,0xA4,0x04,0x00,0x00,0x68,0x70,0x83,0x6C,0x70,0x87,0x73,0xE0, -0x40,0xD0,0x15,0x40,0x40,0x87,0xC0,0x01,0xE0,0x59,0x70,0x80,0x59,0x70,0x7B,0x54, -0x2B,0x7F,0xEF,0x37,0x00,0x02,0x77,0x28,0x87,0x01,0x64,0x70,0xDC,0x03,0x7F,0xA4, -0x04,0x00,0x00,0x40,0x87,0x6B,0x50,0x70,0xDC,0x04,0x7F,0xA4,0x04,0x00,0x00,0x40, -0x87,0x01,0x50,0x70,0x86,0x68,0xEF,0xA4,0x04,0x00,0x00,0x70,0x7B,0x2D,0x3C,0x5F, -0xFF,0x0F,0x59,0x77,0x1C,0x83,0x64,0x70,0x87,0x73,0xE0,0x40,0xD0,0x15,0x40,0x40, -0x87,0x01,0xC0,0x05,0x70,0xA0,0x14,0x2C,0xCC,0xFC,0xEF,0x28,0x05,0x00,0x00,0x90, -0x59,0x70,0x3C,0x5F,0xFF,0x0F,0x59,0x5F,0xA9,0x2C,0x5C,0xAF,0x9F,0x02,0x3C,0x01, -0x40,0x7F,0x1C,0x83,0x64,0x70,0x87,0x73,0xE0,0x40,0xD0,0x15,0x40,0x40,0x87,0x01, -0xC0,0x05,0x70,0xA0,0x14,0x2C,0xCC,0xFC,0xEF,0x28,0x05,0x00,0x00,0x87,0x64,0xE0, -0x40,0x7B,0x02,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x10,0x49,0x9C,0x4F, -0x08,0x00,0x00,0x00,0x4C,0x87,0x73,0xE0,0x40,0xD0,0x15,0x40,0x40,0x87,0x01,0xC0, -0x05,0x70,0x80,0x64,0x70,0x7B,0x05,0x90,0x64,0x70,0x3C,0x5F,0x00,0x01,0x64,0x4B, -0xF8,0x87,0x73,0xE0,0x40,0xA0,0x40,0x2C,0xCC,0xFC,0xAF,0x3D,0xFA,0x28,0x40,0x77, -0x0A,0x80,0x40,0x24,0x7F,0x86,0x75,0x00,0x00,0x84,0xEF,0x94,0x04,0x00,0x00,0x7F, -0x40,0x10,0x00,0x02,0x70,0x84,0x4F,0xB0,0x76,0x00,0x00,0xEF,0x94,0x04,0x00,0x00, -0x70,0x70,0xCC,0x03,0x0D,0x4B,0x7F,0x3C,0x10,0x00,0x02,0x70,0xC8,0x03,0x0D,0x0F, -0x4B,0x87,0x0A,0x7F,0xF7,0x37,0x00,0x02,0x70,0x87,0x77,0x7F,0xF6,0x37,0x00,0x02, -0x70,0x87,0x5F,0xFF,0x00,0x7F,0xEF,0x37,0x00,0x02,0x70,0x87,0x73,0xE0,0x40,0xD0, -0x15,0x40,0x40,0x87,0xC0,0x01,0xE0,0x64,0x70,0x80,0x64,0x70,0x7B,0x31,0xA0,0x01, -0x2C,0xCC,0xFC,0xEF,0x28,0x05,0x00,0x00,0x3F,0x5F,0xFF,0x00,0x7F,0xEF,0x37,0x00, -0x02,0x7F,0x19,0x2B,0x7F,0xEF,0x37,0x00,0x02,0x77,0x0C,0x84,0x7F,0xF0,0x37,0x00, -0x02,0x59,0x70,0x7B,0x11,0x80,0x59,0x70,0x7B,0x0C,0x90,0x64,0x70,0x3C,0x5F,0x30, -0x75,0x64,0x4B,0xCC,0x2C,0x5C,0xAF,0xA4,0x01,0x28,0x40,0x7F,0x07,0x84,0x59,0x40, -0x7B,0x06,0x80,0x40,0x7B,0x02,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x70, -0x10,0x49,0x9C,0x4F,0x08,0x00,0x00,0x00,0x4C,0x70,0xCC,0x03,0x0D,0x4B,0x7F,0x3C, -0x10,0x00,0x02,0x70,0xC8,0x03,0x0D,0x0F,0x4B,0x84,0xEF,0x94,0x04,0x00,0x00,0x7F, -0x40,0x10,0x00,0x02,0x70,0x84,0x4F,0xB0,0x76,0x00,0x00,0xEF,0x94,0x04,0x00,0x00, -0x70,0x83,0x59,0x70,0x84,0x74,0x7F,0x28,0x10,0x00,0x02,0x70,0x84,0x78,0x7F,0x2C, -0x10,0x00,0x02,0x70,0x3F,0x01,0xCA,0x0F,0x77,0x0C,0x87,0x0C,0x7F,0xF7,0x37,0x00, -0x02,0x70,0x7B,0x2F,0x2B,0xCA,0x0F,0x77,0x0C,0x87,0x0B,0x7F,0xF7,0x37,0x00,0x02, -0x70,0x7B,0x20,0x84,0x7F,0x40,0x10,0x00,0x02,0xEF,0x94,0x04,0x00,0x00,0x70,0xC8, -0x03,0x0D,0x7F,0x3C,0x10,0x00,0x02,0x4B,0x84,0x00,0x40,0x24,0x7F,0xA9,0x76,0x00, -0x00,0xFB,0x5F,0xF0,0x00,0x73,0x40,0xD4,0x04,0x40,0x40,0x87,0x40,0x62,0x70,0x2B, -0x62,0x77,0x0A,0x80,0x40,0x24,0x7F,0xA9,0x76,0x00,0x00,0xFB,0x0F,0x73,0x40,0x87, -0x40,0x61,0x70,0x87,0x61,0x7F,0xF6,0x37,0x00,0x02,0x70,0x84,0x4F,0x28,0x10,0x00, -0x02,0x7F,0xF8,0x37,0x00,0x02,0x70,0x87,0x5F,0xFF,0x00,0x7F,0xEF,0x37,0x00,0x02, -0x70,0x87,0x62,0xE0,0x40,0xD0,0x15,0x40,0x40,0x87,0xC0,0x01,0xE0,0x64,0x70,0x80, -0x64,0x70,0x7B,0x2D,0xA0,0x01,0x2C,0xCC,0xFC,0xEF,0x28,0x05,0x00,0x00,0x3F,0x5F, -0xFF,0x00,0x7F,0xEF,0x37,0x00,0x02,0x7F,0x15,0x2B,0x7F,0xEF,0x37,0x00,0x02,0x77, -0x08,0x87,0x01,0x59,0x70,0x7B,0x11,0x83,0x59,0x70,0x7B,0x0C,0x90,0x64,0x70,0x3C, -0x5F,0x28,0x23,0x64,0x4B,0xD0,0x2C,0x5C,0xAF,0x82,0x00,0x28,0x40,0x7F,0x08,0x87, -0x59,0xE0,0x40,0x7B,0x06,0x80,0x40,0x7B,0x02,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08, -0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0xC8,0x03,0x0D,0x0F,0x4B,0x3F,0x01, -0xEF,0x10,0x05,0x00,0x00,0x7F,0x2B,0x3F,0x6F,0x64,0x7F,0x03,0x20,0x04,0x00,0x7F, -0x21,0x80,0xEF,0x8C,0x04,0x00,0x00,0x70,0x80,0xEF,0x14,0x05,0x00,0x00,0x70,0x83, -0x7F,0x0D,0x90,0x04,0x00,0x70,0x87,0x04,0x7F,0x0E,0x90,0x04,0x00,0x70,0x7B,0x00, -0x86,0xE2,0x7F,0x02,0x40,0x04,0x00,0xE0,0x40,0x38,0x40,0x6F,0x7E,0x7F,0x0C,0x86, -0x01,0x7F,0x46,0x10,0x00,0x02,0x70,0x7B,0x09,0x82,0x7F,0x44,0x10,0x00,0x02,0x70, -0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x10,0x49,0x9C,0x4F,0x04,0x00,0x00,0x00, -0x4C,0x86,0x01,0x7F,0x44,0x10,0x00,0x02,0x70,0x80,0x59,0x70,0x82,0x7F,0x46,0x10, -0x00,0x02,0x70,0xC8,0x03,0x0D,0x00,0x4B,0x70,0x70,0x70,0x70,0xC8,0x03,0x0D,0x0F, -0x4B,0x86,0xE2,0x7F,0x44,0x10,0x00,0x02,0xE0,0x40,0x77,0x1C,0x84,0x7F,0x40,0x10, -0x00,0x02,0xEF,0x94,0x04,0x00,0x00,0x70,0xC8,0x03,0x0D,0x7F,0x3C,0x10,0x00,0x02, -0x4B,0x84,0x01,0x40,0x7B,0x4D,0x3C,0x5F,0xFF,0x00,0x59,0x4F,0x1C,0x84,0x7F,0x40, -0x10,0x00,0x02,0xEF,0x94,0x04,0x00,0x00,0x70,0xC8,0x03,0x0D,0x7F,0x3C,0x10,0x00, -0x02,0x4B,0x84,0x00,0x40,0x7B,0x2C,0x86,0xE2,0x7F,0x46,0x10,0x00,0x02,0xE0,0x40, -0x7F,0x1C,0x84,0x7F,0x40,0x10,0x00,0x02,0xEF,0x94,0x04,0x00,0x00,0x70,0xC8,0x03, -0x0D,0x7F,0x3C,0x10,0x00,0x02,0x4B,0x84,0x00,0x40,0x7B,0x07,0x90,0x59,0x70,0x7B, -0x84,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x10,0x49,0x9C,0x4F,0x04,0x00,0x00,0x00, -0x4C,0xDC,0x02,0x7F,0xA4,0x04,0x00,0x00,0x40,0x2B,0x50,0x77,0x0B,0x84,0x01,0x40, -0x24,0x7F,0x25,0x79,0x00,0x00,0x86,0x01,0x59,0x70,0x7B,0x2D,0x86,0xE2,0x59,0xE0, -0x40,0xD0,0x05,0x40,0x40,0x9C,0x7F,0x90,0x04,0x00,0x00,0x40,0xCC,0x03,0x0C,0x50, -0x40,0xDC,0x02,0x7F,0xA4,0x04,0x00,0x00,0x41,0x87,0x51,0xE0,0x41,0x3C,0x41,0x40, -0x77,0x04,0x7B,0x17,0x92,0x59,0x70,0x86,0xE2,0x59,0xE0,0x40,0x87,0xEF,0xE0,0x04, -0x00,0x00,0xE0,0x41,0x3C,0x41,0x40,0x5B,0xC5,0x86,0xE2,0x59,0xE0,0x40,0x87,0xEF, -0xE0,0x04,0x00,0x00,0xE0,0x41,0x3C,0x41,0x40,0x5B,0x2A,0xDC,0x02,0x7F,0xA4,0x04, -0x00,0x00,0x40,0x83,0x50,0x70,0xDC,0x03,0x7F,0xA4,0x04,0x00,0x00,0x40,0x83,0x50, -0x70,0x86,0x5F,0xBD,0x04,0xEF,0xA4,0x04,0x00,0x00,0x70,0x80,0x40,0x24,0x7F,0x25, -0x79,0x00,0x00,0xDC,0x02,0x7F,0xA4,0x04,0x00,0x00,0x40,0x87,0x50,0xE0,0x40,0xD0, -0x15,0x40,0x40,0x87,0x01,0xC0,0x05,0x70,0xA0,0x14,0x2C,0xCC,0xFC,0xEF,0x28,0x05, -0x00,0x00,0xDC,0x02,0x7F,0xA4,0x04,0x00,0x00,0x40,0x87,0x50,0xE0,0x40,0xA0,0x40, -0x2C,0xCC,0xFC,0x7F,0x14,0x6F,0x00,0x00,0x3C,0x01,0x40,0x7F,0x08,0x24,0x7F,0x21, -0x79,0x00,0x00,0xDC,0x02,0x7F,0xA4,0x04,0x00,0x00,0x40,0x87,0x50,0xE0,0x40,0xA0, -0x40,0xDC,0x03,0x7F,0xA4,0x04,0x00,0x00,0x40,0x87,0x50,0xE0,0x40,0xA0,0x40,0x2C, -0xCC,0xF8,0x7F,0xAC,0x73,0x00,0x00,0x3C,0x01,0x40,0x77,0x67,0xDC,0x04,0x7F,0xA4, -0x04,0x00,0x00,0x40,0x87,0x01,0x50,0x70,0x86,0xEF,0xA4,0x04,0x00,0x00,0x59,0x70, -0xE0,0x59,0xA0,0x4F,0x80,0x30,0x04,0x00,0xA0,0x02,0x2C,0xCC,0xF4,0x7F,0xCC,0x6B, -0x00,0x00,0xDC,0x02,0x7F,0xA4,0x04,0x00,0x00,0x40,0x87,0x50,0xE0,0x40,0xD0,0x04, -0x40,0x40,0xBB,0x5F,0xF0,0x00,0x40,0xDC,0x03,0x7F,0xA4,0x04,0x00,0x00,0x41,0xFB, -0x0F,0x51,0x41,0xB3,0x41,0x40,0x87,0x40,0x62,0x70,0xE0,0x62,0xA0,0x4F,0x09,0x30, -0x04,0x00,0xA0,0x01,0x2C,0xCC,0xF4,0x7F,0xCC,0x6B,0x00,0x00,0x84,0x01,0x40,0x7B, -0x06,0x80,0x40,0x7B,0x02,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x10,0x49,0x9C,0x4F, -0x00,0x00,0x00,0x00,0x4C,0x2C,0x5C,0xEF,0x74,0x0F,0x00,0x02,0x04,0xC9,0xE8,0x4C, -0x20,0x49,0x08,0x70,0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x84,0x4F,0xEF, -0xBE,0xED,0xFE,0x7F,0x64,0x08,0x00,0x02,0x70,0xA0,0x4F,0xD0,0x0F,0x00,0x00,0xA0, -0x7F,0xD4,0x0F,0x00,0x02,0xA0,0x7F,0xD8,0x0F,0x00,0x02,0x2C,0xCC,0xF4,0x7F,0xA8, -0x5C,0x00,0x00,0xA0,0x4F,0xF1,0x0F,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xA8,0x5C,0x00, -0x00,0xA0,0x4F,0x14,0x10,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xA8,0x5C,0x00,0x00,0x87, -0x01,0x7F,0x0B,0x40,0x04,0x00,0x70,0x7B,0x00,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08, -0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0xF8,0x03,0x7F,0xD4,0x0F,0x00,0x02, -0x40,0x3C,0x03,0x40,0x77,0x31,0xF8,0x6F,0x78,0x7F,0xD4,0x0F,0x00,0x02,0x40,0x3C, -0x6F,0x70,0x40,0x7F,0x10,0xF8,0x6F,0x78,0x7F,0xD4,0x0F,0x00,0x02,0x40,0x3C,0x08, -0x40,0x77,0x0B,0x2C,0x5C,0xEF,0x4C,0x10,0x00,0x02,0x7B,0x09,0x2C,0x5C,0xEF,0x70, -0x0F,0x00,0x02,0x7B,0x09,0x2C,0x5C,0xEF,0x70,0x0F,0x00,0x02,0x04,0xC9,0xE8,0x4C, -0x20,0x49,0x08,0x70,0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x84,0x4F,0xEF, -0xBE,0xED,0xFE,0x7F,0x64,0x08,0x00,0x02,0x70,0x2C,0x5C,0xAF,0x33,0x00,0xA0,0x4F, -0x9C,0x10,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xA8,0x5C,0x00,0x00,0xA0,0x4F,0xBB,0x10, -0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xA8,0x5C,0x00,0x00,0x87,0x01,0x7F,0x0B,0x40,0x04, -0x00,0x70,0x7B,0x00,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x10,0x48,0x9C,0x4F, -0x10,0x00,0x00,0x00,0x4C,0xF8,0x6F,0x78,0x7F,0xD4,0x0F,0x00,0x02,0x40,0xD4,0x03, -0x40,0x40,0x86,0x40,0x48,0xF8,0x03,0x7F,0xD4,0x0F,0x00,0x02,0x40,0x24,0x7F,0xEA, -0x7A,0x00,0x00,0xE0,0x59,0xA0,0x4F,0x41,0x12,0x00,0x00,0x2C,0xCC,0xF8,0x7F,0x6C, -0xEA,0x00,0x00,0x24,0x7F,0xFD,0x7A,0x00,0x00,0xE0,0x59,0xA0,0x4F,0x47,0x12,0x00, -0x00,0x2C,0xCC,0xF8,0x7F,0x6C,0xEA,0x00,0x00,0x86,0x13,0x48,0x7B,0x71,0xE0,0x59, -0xA0,0x4F,0x4F,0x12,0x00,0x00,0x2C,0xCC,0xF8,0x7F,0x6C,0xEA,0x00,0x00,0x86,0x13, -0x48,0x7B,0x5C,0x3E,0x0E,0x48,0x77,0x07,0x84,0x01,0x40,0x7B,0x04,0x80,0x40,0x84, -0x40,0x6C,0x70,0x3E,0x01,0x48,0x77,0x07,0x84,0x01,0x40,0x7B,0x04,0x80,0x40,0xB0, -0x6C,0x40,0x7F,0x04,0x7B,0x69,0xE0,0x59,0xA0,0x4F,0x55,0x12,0x00,0x00,0x2C,0xCC, -0xF8,0x7F,0x6C,0xEA,0x00,0x00,0x7B,0x27,0xE0,0x59,0xA0,0x4F,0x5C,0x12,0x00,0x00, -0x2C,0xCC,0xF8,0x7F,0x6C,0xEA,0x00,0x00,0x7B,0x15,0x3C,0x03,0x40,0x47,0xEB,0xC0, -0x02,0x40,0x40,0x28,0x40,0x4B,0xE3,0x24,0x90,0x8C,0x10,0x00,0x00,0xA0,0x4F,0x62, -0x12,0x00,0x00,0xE0,0x59,0x86,0x48,0xE4,0x40,0xA0,0x40,0x86,0x48,0xE4,0x40,0xD0, -0x02,0x40,0x40,0xA0,0x80,0x34,0x10,0x00,0x00,0xA0,0x7F,0xD8,0x0F,0x00,0x02,0xA0, -0x7F,0xD4,0x0F,0x00,0x02,0x2C,0xCC,0xE8,0x7F,0xA8,0x5C,0x00,0x00,0x04,0xC9,0xEC, -0x4C,0x20,0x48,0x20,0x49,0x08,0x70,0x70,0x10,0x48,0x9C,0x4F,0x74,0x00,0x00,0x00, -0x4C,0x87,0x01,0xEF,0xC4,0x04,0x00,0x00,0x70,0x84,0x4F,0x44,0x79,0x00,0x00,0x7F, -0x74,0x0F,0x00,0x02,0x70,0x84,0x4F,0xF4,0x79,0x00,0x00,0x7F,0x70,0x0F,0x00,0x02, -0x70,0x84,0x4F,0xF4,0x79,0x00,0x00,0x7F,0x4C,0x10,0x00,0x02,0x70,0x3C,0x4F,0xEF, -0xBE,0xED,0xFE,0x7F,0x64,0x08,0x00,0x02,0x7F,0x09,0x84,0x4F,0x00,0x00,0x80,0x00, -0x4B,0x84,0x7F,0x64,0x08,0x00,0x02,0x48,0x3C,0x4F,0xEF,0xBE,0xED,0xFE,0x7F,0x64, -0x08,0x00,0x02,0x7F,0x15,0x3C,0x4F,0x1E,0xAC,0xEB,0xAD,0x7F,0x64,0x08,0x00,0x02, -0x7F,0x08,0x24,0x7F,0xF2,0x7D,0x00,0x00,0x84,0x4F,0xD0,0xF1,0x02,0x3B,0x7F,0x64, -0x08,0x00,0x02,0x70,0xA0,0x4F,0x00,0x30,0x04,0x00,0xE0,0xC9,0x64,0xA0,0x09,0x2C, -0xCC,0xF4,0x7F,0x50,0x6B,0x00,0x00,0x2B,0xC9,0x64,0x77,0x26,0xE0,0xC9,0x64,0xA0, -0x4F,0x9C,0x12,0x00,0x00,0x2C,0xCC,0xF8,0x7F,0x6C,0xEA,0x00,0x00,0xE0,0xC9,0x64, -0xA0,0x4F,0x00,0x30,0x04,0x00,0xA0,0x09,0x2C,0xCC,0xF4,0x7F,0xCC,0x6B,0x00,0x00, -0x3C,0x4F,0x0D,0xF0,0xAD,0x8B,0x48,0x77,0x08,0x24,0x7F,0x84,0x7C,0x00,0x00,0x3C, -0x4F,0xEF,0xBE,0xED,0xFE,0x48,0x7F,0x7E,0xDC,0x04,0x7F,0xA4,0x04,0x00,0x00,0x40, -0x2B,0x50,0x77,0x72,0xA0,0x4F,0x0C,0x30,0x04,0x00,0xE0,0xC9,0x6E,0xA0,0x01,0x2C, -0xCC,0xF4,0x7F,0x50,0x6B,0x00,0x00,0x28,0x40,0x77,0x28,0x87,0x01,0xC9,0x6E,0x70, -0xE0,0xC9,0x6E,0xA0,0x4F,0x0C,0x30,0x04,0x00,0xA0,0x01,0x2C,0xCC,0xF4,0x7F,0xCC, -0x6B,0x00,0x00,0xDC,0x01,0x7F,0xA0,0x04,0x00,0x00,0x40,0x87,0x01,0x50,0x70,0x7B, -0x0F,0xDC,0x01,0x7F,0xA0,0x04,0x00,0x00,0x40,0x87,0xC9,0x6E,0x50,0x70,0x83,0xEF, -0xA0,0x04,0x00,0x00,0x70,0xDC,0x02,0x7F,0xA0,0x04,0x00,0x00,0x40,0xA0,0x40,0xA0, -0x4F,0xA0,0x12,0x00,0x00,0x2C,0xCC,0xF8,0x7F,0x6C,0xEA,0x00,0x00,0x2C,0x5C,0x7F, -0x90,0x7F,0x00,0x00,0x24,0x7F,0x0A,0x7D,0x00,0x00,0xDC,0x02,0x7F,0xA4,0x04,0x00, -0x00,0x40,0x83,0x50,0x70,0xDC,0x03,0x7F,0xA4,0x04,0x00,0x00,0x40,0x83,0x50,0x70, -0x87,0x01,0x7F,0x13,0x40,0x04,0x00,0x70,0x80,0xC9,0x70,0x70,0x7B,0x06,0x90,0xC9, -0x70,0x70,0x3C,0x4F,0x50,0xC3,0x00,0x00,0xC9,0x70,0x4B,0xF4,0x87,0x01,0x7F,0x17, -0x40,0x04,0x00,0x70,0x80,0xC9,0x70,0x70,0x7B,0x06,0x90,0xC9,0x70,0x70,0x3C,0x4F, -0xF0,0x49,0x02,0x00,0xC9,0x70,0x4B,0xF4,0x3F,0x01,0xEF,0x10,0x05,0x00,0x00,0x7F, -0x2B,0x3F,0x6F,0x64,0x7F,0x03,0x20,0x04,0x00,0x7F,0x21,0x80,0xEF,0x8C,0x04,0x00, -0x00,0x70,0x80,0xEF,0x14,0x05,0x00,0x00,0x70,0x83,0x7F,0x0D,0x90,0x04,0x00,0x70, -0x87,0x04,0x7F,0x0E,0x90,0x04,0x00,0x70,0x7B,0x00,0xDC,0x04,0x7F,0xA4,0x04,0x00, -0x00,0x40,0x3F,0x01,0x50,0x7F,0x12,0x8B,0x7F,0x0D,0x90,0x04,0x00,0x40,0xB8,0x01, -0x40,0x3C,0x01,0x40,0x76,0x66,0xFF,0x2C,0x5C,0x7F,0xF8,0x3D,0x00,0x00,0x3C,0x4F, -0xEF,0xBE,0xED,0xFE,0x48,0x77,0x1A,0x87,0x01,0x7F,0x13,0x40,0x04,0x00,0x70,0xA0, -0x4F,0xA9,0x12,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xA8,0x5C,0x00,0x00,0x7B,0x18,0x87, -0x01,0x7F,0x17,0x40,0x04,0x00,0x70,0xA0,0x4F,0xEF,0x12,0x00,0x00,0x2C,0xCC,0xFC, -0x7F,0xA8,0x5C,0x00,0x00,0xE0,0x59,0x2C,0xCC,0xFC,0x7F,0xAA,0x53,0x00,0x00,0xE0, -0x59,0xE0,0xC9,0x64,0x2C,0xCC,0xF8,0x7F,0xE4,0xE9,0x00,0x00,0x28,0x40,0x77,0x71, -0x84,0x4F,0xF6,0x93,0x00,0x00,0x7F,0x74,0x0F,0x00,0x02,0x70,0x84,0x4F,0xA4,0x93, -0x00,0x00,0x7F,0x70,0x0F,0x00,0x02,0x70,0x84,0x4F,0xA4,0x93,0x00,0x00,0x7F,0x4C, -0x10,0x00,0x02,0x70,0x84,0x4F,0x0C,0x93,0x00,0x00,0x7F,0x58,0x08,0x00,0x02,0x70, -0x87,0x01,0x7F,0x50,0x10,0x00,0x02,0x70,0x84,0x4F,0xED,0x0D,0x1C,0xA1,0x7F,0x64, -0x08,0x00,0x02,0x70,0x2C,0x5C,0x7F,0x0C,0x93,0x00,0x00,0x84,0x4F,0x44,0x79,0x00, -0x00,0x7F,0x74,0x0F,0x00,0x02,0x70,0x84,0x4F,0xF4,0x79,0x00,0x00,0x7F,0x70,0x0F, -0x00,0x02,0x70,0x84,0x4F,0xF4,0x79,0x00,0x00,0x7F,0x4C,0x10,0x00,0x02,0x70,0x7A, -0x01,0xFE,0xA0,0x4F,0x0C,0x30,0x04,0x00,0xE0,0xC9,0x6E,0xA0,0x01,0x2C,0xCC,0xF4, -0x7F,0x50,0x6B,0x00,0x00,0x28,0x40,0x77,0x28,0x87,0x01,0xC9,0x6E,0x70,0xE0,0xC9, -0x6E,0xA0,0x4F,0x0C,0x30,0x04,0x00,0xA0,0x01,0x2C,0xCC,0xF4,0x7F,0xCC,0x6B,0x00, -0x00,0xDC,0x01,0x7F,0xA0,0x04,0x00,0x00,0x40,0x87,0x01,0x50,0x70,0x7B,0x0F,0xDC, -0x01,0x7F,0xA0,0x04,0x00,0x00,0x40,0x87,0xC9,0x6E,0x50,0x70,0x83,0xEF,0xA0,0x04, -0x00,0x00,0x70,0x3C,0x4F,0x0D,0xF0,0xAD,0x8B,0x48,0x77,0x08,0x24,0x7F,0xD0,0x7E, -0x00,0x00,0x84,0x4F,0xEF,0xBE,0xED,0xFE,0x7F,0x64,0x08,0x00,0x02,0x70,0xDC,0x02, -0x7F,0xA0,0x04,0x00,0x00,0x40,0xA0,0x40,0xA0,0x4F,0x00,0x13,0x00,0x00,0x2C,0xCC, -0xF8,0x7F,0x6C,0xEA,0x00,0x00,0x2C,0x5C,0x7F,0x90,0x7F,0x00,0x00,0x28,0x40,0x77, -0x18,0x84,0x4F,0xEF,0xBE,0xED,0xFE,0x7F,0x64,0x08,0x00,0x02,0x70,0x87,0x01,0x7F, -0x0B,0x40,0x04,0x00,0x70,0x7B,0x00,0xDC,0x02,0x7F,0xA0,0x04,0x00,0x00,0x40,0xA0, -0x40,0xA0,0x4F,0x09,0x13,0x00,0x00,0x2C,0xCC,0xF8,0x7F,0x6C,0xEA,0x00,0x00,0x2C, -0x5C,0x7F,0x90,0x7F,0x00,0x00,0x28,0x40,0x77,0x18,0x84,0x4F,0xEF,0xBE,0xED,0xFE, -0x7F,0x64,0x08,0x00,0x02,0x70,0x87,0x01,0x7F,0x0B,0x40,0x04,0x00,0x70,0x7B,0x00, -0x3C,0x4F,0xEF,0xBE,0xED,0xFE,0x7F,0x64,0x08,0x00,0x02,0x7F,0x16,0x87,0x01,0x7F, -0x17,0x40,0x04,0x00,0x70,0x84,0x4F,0xEF,0xBE,0xED,0xFE,0x7F,0x64,0x08,0x00,0x02, -0x70,0xA0,0x4F,0x0D,0x30,0x04,0x00,0xDC,0x02,0x7F,0xA0,0x04,0x00,0x00,0x40,0xA0, -0x40,0xA0,0x2D,0x2C,0xCC,0xF4,0x7F,0x50,0x6B,0x00,0x00,0x28,0x40,0x77,0x34,0xDC, -0x02,0x7F,0xA0,0x04,0x00,0x00,0x40,0xA0,0x40,0xA0,0x4F,0x10,0x13,0x00,0x00,0x2C, -0xCC,0xF8,0x7F,0x6C,0xEA,0x00,0x00,0xDC,0x02,0x7F,0xA0,0x04,0x00,0x00,0x40,0xA0, -0x40,0xA0,0x4F,0x0D,0x30,0x04,0x00,0xA0,0x2D,0x2C,0xCC,0xF4,0x7F,0xCC,0x6B,0x00, -0x00,0x87,0x02,0xEF,0xA0,0x04,0x00,0x00,0x70,0x84,0x01,0x7F,0x54,0x10,0x00,0x02, -0x70,0x2C,0x5C,0x7F,0x70,0xE3,0x00,0x00,0x84,0xFF,0x7F,0x54,0x10,0x00,0x02,0x70, -0x84,0x01,0x7F,0x58,0x10,0x00,0x02,0x70,0x2C,0x5C,0x7F,0x90,0x7F,0x00,0x00,0x84, -0x4F,0xEF,0xBE,0xED,0xFE,0x7F,0x64,0x08,0x00,0x02,0x70,0x87,0x01,0x7F,0x0B,0x40, -0x04,0x00,0x70,0x7B,0x00,0x04,0xC9,0xEC,0x4C,0x20,0x48,0x20,0x49,0x08,0x70,0x70, -0x10,0x49,0x9C,0x4F,0x10,0x00,0x00,0x00,0x4C,0x3F,0x01,0xEF,0xA0,0x04,0x00,0x00, -0x77,0x0F,0x3C,0x4F,0xF0,0xFF,0x00,0x00,0x7F,0x08,0x05,0x00,0x00,0x7F,0x26,0x84, -0x4F,0xF4,0x81,0x00,0x00,0x7F,0x74,0x0F,0x00,0x02,0x70,0x84,0x4F,0x38,0x82,0x00, -0x00,0x7F,0x4C,0x10,0x00,0x02,0x70,0x84,0x7F,0x4C,0x10,0x00,0x02,0x7F,0x70,0x0F, -0x00,0x02,0x70,0x3C,0x4F,0xD0,0xF1,0x02,0x3B,0x7F,0x6C,0x08,0x00,0x02,0x7F,0x55, -0x84,0x4F,0xD0,0xF1,0x02,0x3B,0x7F,0x6C,0x08,0x00,0x02,0x70,0x84,0xEF,0xE4,0x04, -0x00,0x00,0x59,0x70,0xDC,0x4F,0x00,0x00,0x00,0x02,0xEF,0xE4,0x04,0x00,0x00,0x40, -0xBC,0xEF,0xE8,0x04,0x00,0x00,0x40,0xD4,0x02,0x40,0x40,0x84,0x40,0x59,0x70,0x84, -0xEF,0xE8,0x04,0x00,0x00,0x40,0x80,0x50,0x70,0xA0,0x59,0xDC,0x04,0xEF,0xE8,0x04, -0x00,0x00,0x40,0xA0,0x40,0xA0,0xEF,0xE8,0x04,0x00,0x00,0x2C,0xCC,0xF4,0x7F,0xFC, -0x58,0x00,0x00,0x83,0x7F,0x0D,0x90,0x04,0x00,0x70,0x87,0x08,0x7F,0x0F,0x90,0x04, -0x00,0x70,0x2C,0x5C,0x7F,0x5C,0x3F,0x00,0x00,0xA0,0x00,0x2C,0xCC,0xFC,0xEF,0x40, -0x05,0x00,0x00,0x84,0x4F,0x00,0x40,0x00,0x02,0x64,0x70,0xDC,0x01,0x7F,0xA0,0x04, -0x00,0x00,0x40,0x3F,0x01,0x50,0x77,0x4A,0x87,0x01,0x7F,0x1F,0x40,0x04,0x00,0x70, -0xA0,0x00,0x2C,0xCC,0xFC,0x7F,0x7C,0x88,0x00,0x00,0x28,0x40,0x77,0x0A,0x80,0x40, -0x24,0x7F,0xED,0x81,0x00,0x00,0xA0,0x00,0xA0,0x7F,0xA4,0x0A,0x00,0x02,0xA0,0x4F, -0x00,0x40,0x00,0x02,0xA0,0x00,0x2C,0xCC,0xF0,0x7F,0x34,0x8B,0x00,0x00,0x28,0x40, -0x77,0x0A,0x80,0x40,0x24,0x7F,0xED,0x81,0x00,0x00,0x24,0x7F,0x73,0x81,0x00,0x00, -0xDC,0x01,0x7F,0xA0,0x04,0x00,0x00,0x40,0x3F,0x02,0x50,0x77,0x46,0x87,0x01,0x7F, -0x1F,0x40,0x04,0x00,0x70,0xA0,0x01,0x2C,0xCC,0xFC,0x7F,0x7C,0x88,0x00,0x00,0x28, -0x40,0x77,0x0A,0x80,0x40,0x24,0x7F,0xED,0x81,0x00,0x00,0xA0,0x01,0xA0,0x7F,0xF8, -0x0A,0x00,0x02,0xA0,0x4F,0x00,0x40,0x00,0x02,0xA0,0x00,0x2C,0xCC,0xF0,0x7F,0x34, -0x8B,0x00,0x00,0x28,0x40,0x77,0x0A,0x80,0x40,0x24,0x7F,0xED,0x81,0x00,0x00,0x7B, -0x74,0xDC,0x01,0x7F,0xA0,0x04,0x00,0x00,0x40,0x2B,0x50,0x77,0x24,0xA0,0x00,0xA0, -0x4F,0x00,0x40,0x00,0x02,0xA0,0x00,0xA0,0x00,0x2C,0xCC,0xF0,0x7F,0xCC,0x8F,0x00, -0x00,0x28,0x40,0x77,0x0A,0x80,0x40,0x24,0x7F,0xED,0x81,0x00,0x00,0x7B,0x46,0xDC, -0x01,0x7F,0xA0,0x04,0x00,0x00,0x40,0x87,0x50,0xE0,0x40,0xD4,0x04,0x40,0x40,0x87, -0x40,0x69,0x70,0xDC,0x01,0x7F,0xA0,0x04,0x00,0x00,0x40,0xFB,0x0F,0x50,0x40,0x87, -0x40,0x68,0x70,0x87,0x69,0xE0,0x40,0xA0,0x40,0x87,0x68,0xE0,0x40,0xA0,0x40,0x2C, -0xCC,0xF8,0x7F,0xAC,0x74,0x00,0x00,0x84,0x40,0x64,0x70,0x28,0x64,0x77,0x06,0x80, -0x40,0x7B,0x7C,0xA0,0x00,0x2C,0xCC,0xFC,0xEF,0x1C,0x05,0x00,0x00,0x28,0x40,0x7F, -0x22,0xA0,0x01,0x2C,0xCC,0xFC,0xEF,0x40,0x05,0x00,0x00,0x3C,0x4F,0xEF,0xBE,0xED, -0xFE,0x7F,0x64,0x08,0x00,0x02,0x77,0x06,0x80,0x40,0x7B,0x05,0x84,0x01,0x40,0x7B, -0x4E,0xDC,0x04,0x64,0x40,0x3C,0x50,0xD9,0x04,0x77,0x20,0xDC,0x04,0x64,0x40,0xDC, -0x08,0x64,0x41,0x3C,0x51,0x50,0x77,0x13,0xDC,0x08,0x64,0x40,0xDC,0x0C,0x64,0x41, -0x3C,0x51,0x50,0x77,0x06,0x80,0x40,0x7B,0x26,0x2C,0x5C,0xD9,0x04,0xA0,0x01,0x2C, -0xCC,0xFC,0xEF,0x40,0x05,0x00,0x00,0x3C,0x4F,0xEF,0xBE,0xED,0xFE,0x7F,0x64,0x08, -0x00,0x02,0x77,0x06,0x80,0x40,0x7B,0x05,0x84,0x01,0x40,0x7B,0x02,0x04,0xC9,0xE8, -0x4C,0x20,0x49,0x08,0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0xA0,0x4F,0x18, -0x13,0x00,0x00,0x2C,0xCC,0xFC,0xEF,0xB0,0x04,0x00,0x00,0xA0,0x4F,0x3E,0x13,0x00, -0x00,0x2C,0xCC,0xFC,0xEF,0xB0,0x04,0x00,0x00,0x84,0x4F,0xEF,0xBE,0xED,0xFE,0x7F, -0x64,0x08,0x00,0x02,0x70,0x87,0x01,0x7F,0x0B,0x40,0x04,0x00,0x70,0x7B,0x00,0x04, -0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00, -0x4C,0xA0,0x4F,0x5F,0x13,0x00,0x00,0x2C,0xCC,0xFC,0xEF,0xB0,0x04,0x00,0x00,0xA0, -0x4F,0x81,0x13,0x00,0x00,0x2C,0xCC,0xFC,0xEF,0xB0,0x04,0x00,0x00,0x84,0x4F,0xEF, -0xBE,0xED,0xFE,0x7F,0x64,0x08,0x00,0x02,0x70,0x87,0x01,0x7F,0x0B,0x40,0x04,0x00, -0x70,0x7B,0x00,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x10,0x49,0x9C,0x4F, -0x00,0x00,0x00,0x00,0x4C,0xEC,0x4F,0x00,0x00,0x01,0x00,0x5A,0x40,0x86,0xE2,0x7A, -0xE0,0x41,0x9C,0x5A,0x41,0xBC,0x01,0x41,0xAC,0xE0,0x4F,0x00,0x00,0x01,0x00,0x41, -0x3C,0x41,0x40,0x53,0x0A,0x80,0x40,0x24,0x7F,0xAF,0x83,0x00,0x00,0x83,0x7F,0x0D, -0x80,0x04,0x00,0x70,0x83,0x7F,0x08,0x80,0x04,0x00,0x70,0x83,0x7F,0x0C,0x80,0x04, -0x00,0x70,0x3B,0x77,0x01,0x7F,0x35,0x87,0x73,0x7F,0x02,0x80,0x04,0x00,0x70,0x87, -0x72,0x7F,0x02,0x80,0x04,0x00,0x70,0x3B,0x77,0x08,0x7F,0x12,0xF3,0x5F,0x80,0x00, -0x71,0x40,0x87,0x40,0x7F,0x03,0xE0,0x04,0x00,0x70,0x7B,0x0E,0xF3,0x00,0x71,0x40, -0x87,0x40,0x7F,0x03,0xE0,0x04,0x00,0x70,0x7B,0x33,0x87,0x73,0x7F,0x00,0x80,0x04, -0x00,0x70,0x87,0x72,0x7F,0x00,0x80,0x04,0x00,0x70,0x3B,0x77,0x08,0x7F,0x12,0xF3, -0x5F,0x80,0x00,0x71,0x40,0x87,0x40,0x7F,0x03,0x50,0x04,0x00,0x70,0x7B,0x0E,0xF3, -0x00,0x71,0x40,0x87,0x40,0x7F,0x03,0x50,0x04,0x00,0x70,0x83,0x7F,0x0C,0x80,0x04, -0x00,0x70,0x3B,0x77,0x01,0x7F,0x2E,0xFF,0x01,0x7B,0x40,0xBB,0x5F,0xFF,0x00,0x40, -0x87,0x40,0x7F,0x03,0x80,0x04,0x00,0x70,0x86,0xE2,0x7A,0xE0,0x40,0xBC,0x01,0x40, -0xD4,0x08,0x40,0x40,0xBB,0x5F,0xFF,0x00,0x40,0x87,0x40,0x7F,0x03,0x80,0x04,0x00, -0x70,0x7B,0x2C,0xFF,0x01,0x7B,0x40,0xBB,0x5F,0xFF,0x00,0x40,0x87,0x40,0x7F,0x01, -0x80,0x04,0x00,0x70,0x86,0xE2,0x7A,0xE0,0x40,0xBC,0x01,0x40,0xD4,0x08,0x40,0x40, -0xBB,0x5F,0xFF,0x00,0x40,0x87,0x40,0x7F,0x01,0x80,0x04,0x00,0x70,0x87,0x77,0x7F, -0x0B,0x80,0x04,0x00,0x70,0xFB,0x03,0x77,0x40,0x9F,0x01,0x40,0x8B,0x40,0x40,0xBB, -0x0F,0x40,0x87,0x40,0x7F,0x0F,0x80,0x04,0x00,0x70,0x84,0x01,0x40,0x7B,0x02,0x04, -0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x10,0x44,0x9C,0x4F,0x00,0x00,0x00,0x00, -0x4C,0x83,0x7F,0x64,0x12,0x00,0x02,0x70,0xEB,0x6F,0x54,0x73,0x40,0x84,0x5F,0x00, -0x02,0x80,0xA0,0x0A,0x00,0x02,0x70,0xEB,0x6F,0x54,0x73,0x40,0x84,0x12,0x80,0x9C, -0x0A,0x00,0x02,0x70,0xEB,0x6F,0x54,0x73,0x40,0x84,0x04,0x80,0x98,0x0A,0x00,0x02, -0x70,0xEB,0x6F,0x54,0x73,0x40,0x84,0x5F,0x32,0x01,0x80,0x94,0x0A,0x00,0x02,0x70, -0x87,0x73,0xE0,0x40,0xA0,0x40,0xA0,0x00,0xA0,0x4F,0x74,0x08,0x00,0x02,0xA0,0x00, -0x2C,0xCC,0xF0,0x7F,0x34,0x8B,0x00,0x00,0x28,0x40,0x77,0x0A,0x80,0x40,0x24,0x7F, -0x3D,0x86,0x00,0x00,0x3C,0x4F,0x0D,0x60,0x5E,0xCA,0x7F,0x78,0x08,0x00,0x02,0x7F, -0x0A,0x80,0x40,0x24,0x7F,0x3D,0x86,0x00,0x00,0xEB,0x6F,0x54,0x73,0x40,0x9C,0x4F, -0x7C,0x0A,0x00,0x02,0x40,0x84,0x40,0x48,0x84,0x4F,0x74,0x08,0x00,0x02,0x47,0x82, -0x46,0x7B,0x12,0x84,0x48,0x40,0x90,0x48,0x84,0x47,0x41,0x90,0x47,0x87,0x51,0x50, -0x70,0x92,0x46,0x86,0xE2,0x46,0xE0,0x40,0x3C,0x6F,0x54,0x40,0x5B,0xE7,0x87,0x73, -0xE0,0x40,0xD0,0x01,0x40,0x40,0xEB,0x6F,0x54,0x73,0x41,0xEB,0x6F,0x54,0x73,0x42, -0xEC,0xE0,0x82,0xA0,0x0A,0x00,0x02,0x81,0xBC,0x0A,0x00,0x02,0x41,0x86,0x41,0x80, -0x5C,0x12,0x00,0x02,0x70,0x82,0x46,0x7B,0x1E,0x87,0x73,0xE0,0x40,0xD0,0x08,0x40, -0x40,0x9C,0x4F,0x5C,0x10,0x00,0x02,0x40,0x86,0xE2,0x46,0xE0,0x41,0x9C,0x41,0x40, -0x83,0x50,0x70,0x92,0x46,0x86,0xE2,0x46,0xE0,0x40,0x3C,0x5F,0x00,0x01,0x40,0x5B, -0xDA,0xEB,0x6F,0x54,0x73,0x40,0xEC,0xE0,0x08,0x80,0xA0,0x0A,0x00,0x02,0x40,0x86, -0x40,0x44,0x87,0x5F,0xFF,0x00,0x7F,0x73,0x08,0x00,0x02,0x70,0x87,0x73,0xE0,0x40, -0xD0,0x01,0x40,0x40,0x82,0x80,0x60,0x12,0x00,0x02,0x70,0x24,0x7F,0xDC,0x85,0x00, -0x00,0x87,0x73,0xE0,0x40,0xA0,0x40,0xEB,0x6F,0x54,0x73,0x40,0x87,0x73,0xE0,0x41, -0xD0,0x01,0x41,0x41,0x86,0xE2,0x81,0x60,0x12,0x00,0x02,0xE0,0x41,0xDC,0x41,0x80, -0xB8,0x0A,0x00,0x02,0x40,0xA0,0x40,0xA0,0x4F,0x74,0x08,0x00,0x02,0xA0,0x00,0x2C, -0xCC,0xF0,0x7F,0x34,0x8B,0x00,0x00,0x28,0x40,0x77,0x0A,0x80,0x40,0x24,0x7F,0x3D, -0x86,0x00,0x00,0x82,0x45,0x7B,0x77,0x86,0xE2,0x45,0xE0,0x40,0xD0,0x03,0x40,0x40, -0x3F,0x5F,0xFF,0x00,0x80,0x74,0x08,0x00,0x02,0x77,0x04,0x7B,0x71,0x86,0xE2,0x45, -0xE0,0x40,0xD0,0x03,0x40,0x40,0x87,0x80,0x74,0x08,0x00,0x02,0xE0,0x40,0xD0,0x08, -0x40,0x40,0x86,0xE2,0x40,0xE0,0x40,0x86,0xE2,0x45,0xE0,0x41,0xD0,0x03,0x41,0x41, -0x87,0x81,0x75,0x08,0x00,0x02,0xE0,0x41,0x9C,0x41,0x40,0x86,0x40,0x46,0x87,0x73, -0xE0,0x40,0xD0,0x08,0x40,0x40,0x9C,0x4F,0x5C,0x10,0x00,0x02,0x40,0x86,0xE2,0x46, -0xE0,0x41,0xAC,0xE0,0x08,0x41,0x9C,0x41,0x40,0x86,0xE2,0x46,0xE0,0x41,0xA4,0xE0, -0x08,0x41,0xD0,0x41,0x01,0x41,0xB3,0x41,0x50,0x70,0x92,0x45,0x86,0xE2,0x45,0xE0, -0x40,0x86,0xE2,0x44,0xE0,0x41,0x3C,0x41,0x40,0x5A,0x7E,0xFF,0x86,0xE2,0x45,0xE0, -0x40,0x86,0xE2,0x44,0xE0,0x41,0x3C,0x41,0x40,0x53,0x04,0x7B,0x39,0x87,0x73,0xE0, -0x40,0xD0,0x01,0x40,0x40,0x92,0x80,0x60,0x12,0x00,0x02,0x70,0x87,0x73,0xE0,0x40, -0xD0,0x01,0x40,0x40,0x86,0xE2,0x80,0x60,0x12,0x00,0x02,0xE0,0x40,0x87,0x73,0xE0, -0x41,0xD0,0x01,0x41,0x41,0x86,0xE2,0x81,0x5C,0x12,0x00,0x02,0xE0,0x41,0x3C,0x41, -0x40,0x5A,0xF0,0xFE,0x87,0x73,0xE0,0x40,0xD0,0x01,0x40,0x40,0x87,0x73,0xE0,0x41, -0xD0,0x01,0x41,0x41,0x86,0xE2,0x81,0x5C,0x12,0x00,0x02,0xE0,0x41,0xBE,0x01,0x41, -0x86,0x41,0x80,0x60,0x12,0x00,0x02,0x70,0x87,0x73,0x7F,0x73,0x08,0x00,0x02,0x70, -0x87,0x01,0x7F,0x64,0x12,0x00,0x02,0x70,0x84,0x01,0x40,0x7B,0x02,0x04,0xC9,0xFC, -0x4C,0x20,0x48,0x20,0x47,0x20,0x46,0x20,0x45,0x20,0x44,0x20,0x49,0x08,0x70,0x70, -0x10,0x48,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x2B,0x7F,0x64,0x12,0x00,0x02,0x77, -0x0B,0x84,0x01,0x40,0x24,0x7F,0x72,0x88,0x00,0x00,0xEB,0x6F,0x54,0x73,0x40,0x3C, -0x4F,0x0D,0x60,0x5E,0xCA,0x80,0x80,0x0A,0x00,0x02,0x7F,0x0A,0x80,0x40,0x24,0x7F, -0x72,0x88,0x00,0x00,0x87,0xDA,0x04,0xE0,0x40,0xD0,0x08,0x40,0x40,0xDC,0x01,0x74, -0x41,0x87,0x51,0xE2,0x41,0x9E,0x41,0x40,0x86,0x40,0x48,0x87,0x73,0xE0,0x40,0xD0, -0x08,0x40,0x40,0x9C,0x4F,0x5C,0x10,0x00,0x02,0x40,0x86,0x48,0xE4,0x41,0xAC,0x08, -0x41,0x9C,0x41,0x40,0x87,0x50,0xE0,0x40,0x86,0x48,0xE4,0x41,0xA4,0x08,0x41,0xD0, -0x41,0x01,0x41,0x38,0x40,0x41,0x77,0x0B,0x84,0x01,0x40,0x24,0x7F,0x72,0x88,0x00, -0x00,0x3F,0x73,0x7F,0x73,0x08,0x00,0x02,0x7F,0x46,0x87,0x73,0xE0,0x40,0xA0,0x40, -0xEB,0x6F,0x54,0x73,0x40,0xA0,0x80,0xB8,0x0A,0x00,0x02,0xA0,0x4F,0x74,0x08,0x00, -0x02,0xA0,0x00,0x2C,0xCC,0xF0,0x7F,0x34,0x8B,0x00,0x00,0x28,0x40,0x77,0x0A,0x80, -0x40,0x24,0x7F,0x72,0x88,0x00,0x00,0x87,0x73,0xE0,0x40,0xD0,0x01,0x40,0x40,0x82, -0x80,0x60,0x12,0x00,0x02,0x70,0x87,0x73,0x7F,0x73,0x08,0x00,0x02,0x70,0x3C,0xDA, -0x04,0x7F,0x74,0x08,0x00,0x02,0x57,0x08,0x24,0x7F,0xC0,0x87,0x00,0x00,0x7B,0x6F, -0x87,0x73,0xE0,0x40,0xD0,0x01,0x40,0x40,0x86,0xE2,0x80,0x60,0x12,0x00,0x02,0xE0, -0x40,0x77,0x0B,0x84,0x01,0x40,0x24,0x7F,0x72,0x88,0x00,0x00,0x87,0x73,0xE0,0x40, -0xD0,0x01,0x40,0x40,0x96,0x80,0x60,0x12,0x00,0x02,0x70,0x87,0x73,0xE0,0x40,0xA0, -0x40,0xEB,0x6F,0x54,0x73,0x40,0x87,0x73,0xE0,0x41,0xD0,0x01,0x41,0x41,0x86,0xE2, -0x81,0x60,0x12,0x00,0x02,0xE0,0x41,0xDC,0x41,0x80,0xB8,0x0A,0x00,0x02,0x40,0xA0, -0x40,0xA0,0x4F,0x74,0x08,0x00,0x02,0xA0,0x00,0x2C,0xCC,0xF0,0x7F,0x34,0x8B,0x00, -0x00,0x28,0x40,0x77,0x0A,0x80,0x40,0x24,0x7F,0x72,0x88,0x00,0x00,0x3C,0xDA,0x04, -0x7F,0x74,0x08,0x00,0x02,0x57,0x8B,0xA0,0x74,0xA0,0x4F,0x74,0x08,0x00,0x02,0x2C, -0xCC,0xF8,0x7F,0x76,0x92,0x00,0x00,0x84,0x01,0x40,0x24,0x7F,0x72,0x88,0x00,0x00, -0xA0,0x74,0xA0,0x4F,0x74,0x08,0x00,0x02,0x2C,0xCC,0xF8,0x7F,0x76,0x92,0x00,0x00, -0x28,0x40,0x7F,0x0B,0x84,0x01,0x40,0x24,0x7F,0x72,0x88,0x00,0x00,0x7B,0x68,0x87, -0x73,0xE0,0x40,0xA0,0x40,0xEB,0x6F,0x54,0x73,0x40,0x87,0x73,0xE0,0x41,0xD0,0x01, -0x41,0x41,0x86,0xE2,0x81,0x60,0x12,0x00,0x02,0xE0,0x41,0xDC,0x41,0x80,0xB8,0x0A, -0x00,0x02,0x40,0xA0,0x40,0xA0,0x4F,0x74,0x08,0x00,0x02,0xA0,0x00,0x2C,0xCC,0xF0, -0x7F,0x34,0x8B,0x00,0x00,0x28,0x40,0x77,0x06,0x80,0x40,0x7B,0x57,0xA0,0x74,0xA0, -0x4F,0x74,0x08,0x00,0x02,0x2C,0xCC,0xF8,0x7F,0x76,0x92,0x00,0x00,0x28,0x40,0x7F, -0x07,0x84,0x01,0x40,0x7B,0x3E,0x87,0x73,0xE0,0x40,0xD0,0x01,0x40,0x40,0x92,0x80, -0x60,0x12,0x00,0x02,0x70,0x87,0x73,0xE0,0x40,0xD0,0x01,0x40,0x40,0x86,0xE2,0x80, -0x60,0x12,0x00,0x02,0xE0,0x40,0x87,0x73,0xE0,0x41,0xD0,0x01,0x41,0x41,0x86,0xE2, -0x81,0x5C,0x12,0x00,0x02,0xE0,0x41,0x3C,0x41,0x40,0x5A,0x75,0xFF,0x84,0x01,0x40, -0x7B,0x02,0x04,0xC9,0xEC,0x4C,0x20,0x48,0x20,0x49,0x08,0x70,0x10,0x49,0x9C,0x4F, -0x00,0x00,0x00,0x00,0x4C,0x87,0x01,0x7F,0x01,0xA0,0x04,0x00,0x70,0xA0,0x01,0x2C, -0xCC,0xFC,0xEF,0x28,0x05,0x00,0x00,0xA0,0x20,0xA0,0x4F,0x74,0x0A,0x00,0x02,0xA0, -0x08,0x2C,0xCC,0xF4,0xAF,0x83,0x00,0x28,0x40,0x7F,0x1B,0x87,0x73,0xE0,0x40,0xA0, -0x40,0x2C,0xCC,0xFC,0xAF,0x1F,0x00,0x28,0x40,0x7F,0x07,0x84,0x01,0x40,0x7B,0x0A, -0x80,0x40,0x7B,0x06,0x80,0x40,0x7B,0x02,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70, -0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x87,0x73,0xE0,0x40,0xA0,0x40,0x2C, -0xCC,0xFC,0xAF,0x19,0x02,0x28,0x40,0x77,0x06,0x80,0x40,0x7B,0x31,0xF3,0x6F,0x58, -0x73,0x40,0xA0,0x40,0xA0,0x00,0xA0,0x00,0x2C,0xCC,0xF4,0xAF,0x2C,0x00,0xF3,0x6F, -0x58,0x73,0x40,0xA0,0x40,0xA0,0x00,0xA0,0x00,0x2C,0xCC,0xF4,0xAF,0x1B,0x00,0x28, -0x40,0x7F,0x07,0x84,0x01,0x40,0x7B,0x06,0x80,0x40,0x7B,0x02,0x04,0xC9,0xE8,0x4C, -0x20,0x49,0x08,0x70,0x10,0x49,0x9C,0x4F,0x04,0x00,0x00,0x00,0x4C,0x70,0x84,0x4B, -0x7F,0x70,0x12,0x00,0x02,0x70,0x70,0xB0,0x4F,0x00,0xE1,0x01,0x00,0x4B,0x3B,0x7F, -0x01,0xA0,0x04,0x00,0x5F,0x80,0x00,0x7F,0x1A,0x87,0x08,0x7F,0x01,0xA0,0x04,0x00, -0x70,0x84,0x7F,0x70,0x12,0x00,0x02,0x4B,0x84,0x00,0x40,0x24,0x7F,0xF0,0x8A,0x00, -0x00,0x87,0x02,0x7F,0x01,0xA0,0x04,0x00,0x70,0x87,0x08,0x7F,0x01,0xA0,0x04,0x00, -0x70,0x7B,0x13,0x84,0x74,0x40,0x90,0x74,0x70,0x87,0x50,0x7F,0x00,0xA0,0x04,0x00, -0x70,0x97,0x7B,0x70,0x2B,0x7B,0x77,0xED,0x87,0x73,0x7F,0x01,0xA0,0x04,0x00,0x70, -0x82,0x59,0x70,0x7B,0x0F,0xA0,0x01,0x2C,0xCC,0xFC,0xEF,0x28,0x05,0x00,0x00,0x92, -0x59,0x70,0x86,0xE2,0x59,0xE0,0x40,0x3C,0x5F,0xC8,0x00,0x40,0x53,0x0D,0x3B,0x7F, -0x01,0xA0,0x04,0x00,0x5F,0x80,0x00,0x77,0xDE,0x3B,0x7F,0x01,0xA0,0x04,0x00,0x5F, -0x80,0x00,0x7F,0x1A,0x87,0x08,0x7F,0x01,0xA0,0x04,0x00,0x70,0x84,0x7F,0x70,0x12, -0x00,0x02,0x4B,0x84,0x00,0x40,0x24,0x7F,0xF0,0x8A,0x00,0x00,0x3B,0x73,0x5F,0xF0, -0x00,0x7F,0x2A,0x82,0x59,0x70,0x7B,0x0F,0xA0,0x01,0x2C,0xCC,0xFC,0xEF,0x28,0x05, -0x00,0x00,0x92,0x59,0x70,0x86,0xE2,0x59,0xE0,0x40,0x3C,0x05,0x40,0x53,0x0C,0x3B, -0x7F,0x01,0xA0,0x04,0x00,0x6F,0x60,0x7F,0xE1,0x7B,0x1A,0x87,0x08,0x7F,0x01,0xA0, -0x04,0x00,0x70,0x84,0x7F,0x70,0x12,0x00,0x02,0x4B,0x84,0x01,0x40,0x24,0x7F,0xF0, -0x8A,0x00,0x00,0xFB,0x6F,0x60,0x7F,0x01,0xA0,0x04,0x00,0x40,0x3C,0x6F,0x40,0x40, -0x7F,0x6B,0x3B,0x73,0x5F,0xB0,0x00,0x7F,0x13,0x3B,0x7F,0x00,0xA0,0x04,0x00,0x20, -0x7F,0x0A,0x87,0x01,0x7F,0x74,0x12,0x00,0x02,0x70,0x3B,0x7F,0x01,0xA0,0x04,0x00, -0x08,0x7F,0x36,0xFB,0x01,0x73,0x40,0xA0,0x40,0x2C,0xCC,0xFC,0xAF,0x23,0xFE,0x28, -0x40,0x77,0x16,0x87,0x08,0x7F,0x01,0xA0,0x04,0x00,0x70,0x84,0x7F,0x70,0x12,0x00, -0x02,0x4B,0x84,0x00,0x40,0x7B,0x7B,0xA0,0x00,0x2C,0xCC,0xFC,0xAF,0x57,0xFE,0xA0, -0x01,0x2C,0xCC,0xFC,0xAF,0x4F,0xFE,0x87,0x08,0x7F,0x01,0xA0,0x04,0x00,0x70,0x84, -0x7F,0x70,0x12,0x00,0x02,0x4B,0x84,0x00,0x40,0x7B,0x57,0x3B,0x7F,0x01,0xA0,0x04, -0x00,0x08,0x7F,0x3A,0xFB,0x01,0x73,0x40,0xA0,0x40,0x2C,0xCC,0xFC,0xAF,0xD2,0xFD, -0x28,0x40,0x77,0x0E,0x84,0x7F,0x70,0x12,0x00,0x02,0x4B,0x84,0x00,0x40,0x7B,0x32, -0xA0,0x00,0x2C,0xCC,0xFC,0xAF,0x0E,0xFE,0xA0,0x01,0x2C,0xCC,0xFC,0xAF,0x06,0xFE, -0x84,0x7F,0x70,0x12,0x00,0x02,0x4B,0x84,0x00,0x40,0x7B,0x16,0x87,0x08,0x7F,0x01, -0xA0,0x04,0x00,0x70,0x84,0x7F,0x70,0x12,0x00,0x02,0x4B,0x84,0x01,0x40,0x7B,0x02, -0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00, -0x4C,0xF3,0x30,0x73,0x40,0xA0,0x40,0xA0,0x00,0xA0,0x00,0x2C,0xCC,0xF4,0xAF,0x19, -0xFE,0x28,0x40,0x77,0x06,0x80,0x40,0x7B,0x14,0x3B,0x7F,0x00,0xA0,0x04,0x00,0x02, -0x7F,0x07,0x84,0x01,0x40,0x7B,0x06,0x80,0x40,0x7B,0x02,0x04,0xC9,0xE8,0x4C,0x20, -0x49,0x08,0x70,0x70,0x10,0x49,0x9C,0x4F,0x14,0x00,0x00,0x00,0x4C,0xEB,0x6F,0x54, -0x73,0x40,0xEB,0x6F,0x54,0x73,0x41,0xE8,0x81,0x9C,0x0A,0x00,0x02,0x80,0x98,0x0A, -0x00,0x02,0x40,0xEC,0xE0,0x40,0x74,0x40,0x84,0x40,0x64,0x70,0xEB,0x6F,0x54,0x73, -0x41,0x3C,0x81,0x94,0x0A,0x00,0x02,0x40,0x5B,0x0A,0x80,0x40,0x24,0x7F,0x14,0x8D, -0x00,0x00,0xD4,0x08,0x64,0x40,0xBB,0x5F,0xFF,0x00,0x40,0x87,0x40,0x6C,0x70,0xFB, -0x5F,0xFF,0x00,0x67,0x40,0x87,0x40,0x6D,0x70,0xEB,0x6F,0x54,0x73,0x40,0xEB,0x6F, -0x54,0x73,0x41,0xE8,0x81,0x9C,0x0A,0x00,0x02,0x80,0x98,0x0A,0x00,0x02,0x40,0xE4, -0xE0,0x40,0x74,0x40,0x84,0x40,0x59,0x70,0xEB,0x6F,0x54,0x73,0x40,0xEC,0xE0,0x80, -0x9C,0x0A,0x00,0x02,0x59,0x40,0x87,0x40,0x6E,0x70,0xEB,0x6F,0x54,0x73,0x40,0xE4, -0xE0,0x80,0x9C,0x0A,0x00,0x02,0x59,0x40,0x87,0x40,0xC9,0x0F,0x70,0x87,0x73,0xE0, -0x40,0xA0,0x40,0xE0,0x6C,0x2C,0xCC,0xF8,0x7F,0x50,0x86,0x00,0x00,0x28,0x40,0x77, -0x0A,0x80,0x40,0x24,0x7F,0x14,0x8D,0x00,0x00,0x3F,0x07,0x6E,0x5F,0x0D,0xDF,0x02, -0x73,0x40,0x87,0x40,0xC9,0x11,0x70,0x7B,0x07,0x87,0x73,0xC9,0x11,0x70,0x82,0x68, -0x70,0x24,0x7F,0xDE,0x8C,0x00,0x00,0x87,0x73,0xE0,0x40,0xA0,0x40,0xE0,0x6C,0x2C, -0xCC,0xF8,0xAF,0x0D,0x01,0x28,0x40,0x77,0x08,0x24,0x7F,0xDB,0x8C,0x00,0x00,0x87, -0x6E,0x7F,0x68,0x12,0x00,0x02,0x70,0x8B,0x6C,0x40,0x87,0x40,0x7F,0x69,0x12,0x00, -0x02,0x70,0x87,0x6D,0x7F,0x6A,0x12,0x00,0x02,0x70,0x87,0x6E,0x7F,0x6B,0x12,0x00, -0x02,0x70,0x87,0xC9,0x0F,0x7F,0x6C,0x12,0x00,0x02,0x70,0x87,0x01,0x7F,0x6D,0x12, -0x00,0x02,0x70,0x2B,0xCA,0x0F,0x77,0x07,0x84,0x04,0x40,0x7B,0x05,0x84,0x08,0x40, -0xB3,0x00,0x40,0x87,0x40,0xC9,0x10,0x70,0xA0,0x78,0x87,0xC9,0x10,0xE0,0x40,0xA0, -0x40,0xEB,0x6F,0x54,0x73,0x40,0xA0,0x80,0xA0,0x0A,0x00,0x02,0x2C,0xCC,0xF4,0x7F, -0x7C,0x82,0x00,0x00,0x28,0x40,0x77,0x0A,0x80,0x40,0x24,0x7F,0x14,0x8D,0x00,0x00, -0x83,0x7F,0x74,0x12,0x00,0x02,0x70,0x2B,0xCA,0x0F,0x77,0x09,0x84,0x5F,0xB0,0x00, -0x40,0x7B,0x07,0x84,0x5F,0xF0,0x00,0x40,0x87,0xC9,0x11,0xE0,0x41,0xB0,0x41,0x40, -0xA0,0x40,0xA0,0x4F,0x68,0x12,0x00,0x02,0xA0,0x06,0x2C,0xCC,0xF4,0x7F,0x24,0x89, -0x00,0x00,0x28,0x40,0x77,0x12,0x87,0x73,0xE0,0x40,0xA0,0x40,0x2C,0xCC,0xFC,0x7F, -0xD0,0x88,0x00,0x00,0x7B,0x07,0x84,0x01,0x40,0x7B,0x3B,0x92,0x68,0x70,0x86,0xE2, -0x68,0xE0,0x40,0x3C,0x10,0x40,0x5A,0x21,0xFF,0x2B,0x7F,0x74,0x12,0x00,0x02,0x7F, -0x21,0xA0,0x4F,0xAC,0x13,0x00,0x00,0x87,0x73,0xE0,0x40,0xA0,0x40,0xA0,0x6C,0xA0, -0x10,0x2C,0xCC,0xF0,0xEF,0xB0,0x04,0x00,0x00,0x83,0x7F,0x74,0x12,0x00,0x02,0x70, -0x80,0x40,0x7B,0x02,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x10,0x49,0x9C,0x4F, -0x00,0x00,0x00,0x00,0x4C,0x87,0x73,0xE0,0x40,0xA0,0x40,0x2C,0xCC,0xFC,0x7F,0xF8, -0x8A,0x00,0x00,0x28,0x40,0x77,0x06,0x80,0x40,0x7B,0x30,0x87,0xDA,0x04,0x7F,0x68, -0x12,0x00,0x02,0x70,0xDC,0x01,0x74,0x40,0x87,0x50,0x7F,0x69,0x12,0x00,0x02,0x70, -0xF3,0x6F,0x68,0x73,0x40,0xA0,0x40,0xA0,0x4F,0x68,0x12,0x00,0x02,0xA0,0x02,0x2C, -0xCC,0xF4,0x7F,0x24,0x89,0x00,0x00,0x7B,0x02,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08, -0x10,0x49,0x9C,0x4F,0x0C,0x00,0x00,0x00,0x4C,0x84,0x4F,0x74,0x08,0x00,0x02,0x68, -0x70,0x87,0x5F,0xFF,0x00,0x7F,0x73,0x08,0x00,0x02,0x70,0x87,0x73,0xE0,0x40,0xA0, -0x40,0xEB,0x6F,0x54,0x73,0x40,0xFC,0x01,0x80,0x94,0x0A,0x00,0x02,0x40,0xEB,0x6F, -0x54,0x73,0x41,0xA8,0x81,0x98,0x0A,0x00,0x02,0x40,0xEB,0x6F,0x54,0x73,0x41,0xA8, -0x81,0x9C,0x0A,0x00,0x02,0x40,0xA0,0x40,0xA0,0x68,0xA0,0x00,0x2C,0xCC,0xF0,0x7F, -0x34,0x8B,0x00,0x00,0x28,0x40,0x77,0x06,0x80,0x40,0x7B,0x54,0x80,0x59,0x70,0x7B, -0x38,0x80,0x64,0x70,0x7B,0x29,0xE4,0x02,0x59,0x40,0x7F,0x0A,0xFC,0x64,0x5F,0xFF, -0x00,0x40,0x7B,0x05,0x84,0x64,0x40,0x84,0x68,0x41,0x90,0x68,0x70,0x87,0x51,0xE0, -0x41,0x3C,0x40,0x41,0x7F,0x06,0x80,0x40,0x7B,0x26,0x90,0x64,0x70,0x3C,0x5F,0x00, -0x01,0x64,0x4B,0xD4,0x90,0x59,0x70,0xEB,0x6F,0x54,0x73,0x40,0xD4,0x08,0x80,0xA0, -0x0A,0x00,0x02,0x40,0x3C,0x40,0x59,0x5B,0xBA,0x84,0x01,0x40,0x7B,0x02,0x04,0xC9, -0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x70,0x10,0x49,0x9C,0x4F,0x04,0x00,0x00,0x00, -0x4C,0x87,0x10,0x7F,0x0E,0x90,0x04,0x00,0x70,0x87,0x20,0x7F,0x0E,0x90,0x04,0x00, -0x70,0x86,0xE2,0x7F,0x02,0x40,0x04,0x00,0xE0,0x40,0xB8,0x5F,0x00,0x04,0x40,0x3C, -0x5F,0x00,0x04,0x40,0x7F,0x16,0x87,0x01,0x7F,0x1B,0x40,0x04,0x00,0x70,0xA0,0x5F, -0x2C,0x01,0x2C,0xCC,0xFC,0xEF,0x28,0x05,0x00,0x00,0xA0,0x5F,0xC8,0x00,0x2C,0xCC, -0xFC,0xEF,0x28,0x05,0x00,0x00,0x87,0x5F,0xD0,0x00,0x7F,0x00,0xD0,0x04,0x00,0x70, -0x82,0x62,0x70,0x7B,0x05,0x92,0x62,0x70,0x3E,0x32,0x62,0x4B,0xFA,0x3B,0x7F,0x00, -0xD0,0x04,0x00,0x5F,0x80,0x00,0x7F,0x0B,0x2C,0x5C,0xAF,0x3C,0x00,0x80,0x40,0x7B, -0x2D,0x3F,0x01,0x73,0x77,0x07,0x84,0x04,0x40,0x7B,0x04,0x80,0x40,0xB0,0x08,0x40, -0xA0,0x40,0xA0,0x10,0x2C,0xCC,0xF8,0xAF,0x48,0x00,0x28,0x40,0x7F,0x07,0x84,0x01, -0x40,0x7B,0x0B,0x2C,0x5C,0xAF,0x11,0x00,0x80,0x40,0x7B,0x02,0x04,0xC9,0xE8,0x4C, -0x20,0x49,0x08,0x70,0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x87,0x01,0x7F, -0x1F,0x40,0x04,0x00,0x70,0x87,0x10,0x7F,0x0F,0x90,0x04,0x00,0x70,0x87,0x20,0x7F, -0x0F,0x90,0x04,0x00,0x70,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x10,0x49,0x9C,0x4F, -0x04,0x00,0x00,0x00,0x4C,0x3B,0x7F,0x00,0xD0,0x04,0x00,0x01,0x7F,0x0A,0x80,0x40, -0x24,0x7F,0xC4,0x8F,0x00,0x00,0x70,0x84,0x4B,0x7F,0x70,0x12,0x00,0x02,0x70,0x70, -0xB0,0x4F,0x00,0xE1,0x01,0x00,0x4B,0x87,0x73,0x7F,0x00,0xD0,0x04,0x00,0x70,0x80, -0x59,0x70,0x7B,0x05,0x90,0x59,0x70,0x3C,0x32,0x59,0x4F,0xFA,0x80,0x59,0x70,0x7B, -0x21,0xA0,0x01,0x2C,0xCC,0xFC,0xEF,0x28,0x05,0x00,0x00,0x3C,0x6F,0x64,0x59,0x4F, -0x0E,0x84,0x7F,0x70,0x12,0x00,0x02,0x4B,0x84,0x00,0x40,0x7B,0x69,0x90,0x59,0x70, -0x3B,0x7F,0x00,0xD0,0x04,0x00,0x01,0x77,0xDA,0xFB,0x5F,0xA0,0x00,0x73,0x40,0x3C, -0x5F,0xA0,0x00,0x40,0x7F,0x0F,0xFB,0x5F,0xF0,0x00,0x73,0x40,0x3C,0x5F,0xF0,0x00, -0x40,0x77,0x11,0x80,0x59,0x70,0x7B,0x05,0x90,0x59,0x70,0x3C,0x5F,0xE8,0x03,0x59, -0x4B,0xF8,0x3B,0x7F,0x00,0xD0,0x04,0x00,0x77,0x7F,0x1F,0x3B,0x7F,0x00,0xD0,0x04, -0x00,0x08,0x7F,0x0A,0x87,0x01,0x7F,0x74,0x12,0x00,0x02,0x70,0x84,0x7F,0x70,0x12, -0x00,0x02,0x4B,0x84,0x00,0x40,0x7B,0x0E,0x84,0x7F,0x70,0x12,0x00,0x02,0x4B,0x84, -0x01,0x40,0x7B,0x02,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x10,0x49,0x9C,0x4F, -0x0C,0x00,0x00,0x00,0x4C,0xEC,0xE0,0x12,0x5A,0x40,0x3C,0x6F,0x50,0x40,0x5B,0x0A, -0x80,0x40,0x24,0x7F,0x34,0x92,0x00,0x00,0x2B,0xCA,0x0F,0x7F,0x08,0x3F,0x03,0xCA, -0x0F,0x77,0x79,0xA0,0x01,0x2C,0xCC,0xFC,0x7F,0x28,0x8E,0x00,0x00,0x28,0x40,0x77, -0x0A,0x80,0x40,0x24,0x7F,0x34,0x92,0x00,0x00,0x87,0x5F,0xFF,0x00,0x7F,0x73,0x08, -0x00,0x02,0x70,0x83,0x7F,0x72,0x08,0x00,0x02,0x70,0xA0,0x5F,0x8E,0x05,0xA0,0x4F, -0x74,0x08,0x00,0x02,0xA0,0x00,0xA0,0x01,0x2C,0xCC,0xF0,0xCF,0xA4,0x28,0x40,0x77, -0x0A,0x80,0x40,0x24,0x7F,0x34,0x92,0x00,0x00,0x3C,0x4F,0x0D,0x60,0x5E,0xCA,0x7F, -0x78,0x08,0x00,0x02,0x77,0x18,0x86,0x7F,0xB2,0x08,0x00,0x02,0x7F,0x76,0x12,0x00, -0x02,0x70,0x87,0x01,0x7F,0x72,0x08,0x00,0x02,0x70,0x7B,0x10,0x82,0x7F,0x76,0x12, -0x00,0x02,0x70,0x83,0x7F,0x72,0x08,0x00,0x02,0x70,0x83,0x68,0x70,0xEC,0xE0,0x12, -0x5A,0x40,0x87,0x40,0x69,0x70,0xE4,0xE0,0x12,0x5A,0x40,0xAC,0xE0,0x09,0x40,0x87, -0x40,0x6A,0x70,0xE4,0xE0,0x09,0x5A,0x40,0x87,0x40,0x6B,0x70,0x2B,0x7F,0x72,0x08, -0x00,0x02,0x7F,0x60,0x3F,0x02,0x7F,0x73,0x08,0x00,0x02,0x7F,0x49,0x87,0x5F,0xFF, -0x00,0x7F,0x73,0x08,0x00,0x02,0x70,0x83,0x7F,0x72,0x08,0x00,0x02,0x70,0x86,0x7F, -0x76,0x12,0x00,0x02,0xE4,0x40,0xA0,0x40,0xA0,0x4F,0x74,0x08,0x00,0x02,0xA0,0x00, -0xA0,0x01,0x2C,0xCC,0xF0,0xAF,0x0A,0xFF,0x28,0x40,0x77,0x0A,0x80,0x40,0x24,0x7F, -0x34,0x92,0x00,0x00,0x87,0x02,0x7F,0x73,0x08,0x00,0x02,0x70,0x87,0x01,0x7F,0x72, -0x08,0x00,0x02,0x70,0xE0,0x68,0xA0,0x4F,0x74,0x08,0x00,0x02,0x2C,0xCC,0xF8,0xAF, -0x8A,0x01,0x87,0x5F,0x9C,0x00,0x66,0x70,0x3F,0x01,0x7B,0x77,0x14,0x87,0x6F,0x49, -0x64,0x70,0x87,0x5F,0xA0,0x00,0x65,0x70,0xB3,0x6F,0x40,0x66,0x70,0x7B,0x0D,0x87, -0x6F,0x45,0x64,0x70,0x87,0x5F,0x80,0x00,0x65,0x70,0x87,0x6A,0xE0,0x40,0xD0,0x01, -0x40,0x40,0xB3,0x08,0x40,0xB3,0x40,0x65,0x70,0x82,0x62,0x70,0x82,0x59,0x70,0x24, -0x7F,0xD0,0x91,0x00,0x00,0x87,0x69,0xE0,0x40,0xA0,0x40,0x2C,0xCC,0xFC,0xAF,0x01, -0x01,0x28,0x40,0x77,0x1A,0xA0,0x01,0x2C,0xCC,0xFC,0x7F,0x28,0x8E,0x00,0x00,0x28, -0x40,0x77,0x0A,0x80,0x40,0x24,0x7F,0x34,0x92,0x00,0x00,0x7B,0x72,0xDF,0x01,0x6B, -0x40,0x87,0x40,0x7F,0x02,0xD0,0x04,0x00,0x70,0xA0,0x74,0x87,0x64,0xE0,0x40,0xA0, -0x40,0xA0,0x5F,0x00,0x02,0x2C,0xCC,0xF4,0x7F,0x7C,0x82,0x00,0x00,0x28,0x40,0x77, -0x0A,0x80,0x40,0x24,0x7F,0x34,0x92,0x00,0x00,0x83,0x7F,0x74,0x12,0x00,0x02,0x70, -0x87,0x65,0xE0,0x40,0xA0,0x40,0x87,0x66,0xE0,0x40,0xA0,0x40,0x2C,0xCC,0xF8,0x7F, -0xFC,0x8E,0x00,0x00,0x28,0x40,0x7F,0x08,0x86,0x01,0x62,0x70,0x7B,0x2A,0x3B,0x7F, -0x00,0xD0,0x04,0x00,0x5F,0x80,0x00,0x7F,0x04,0x7B,0x1D,0xA0,0x01,0x2C,0xCC,0xFC, -0x7F,0x28,0x8E,0x00,0x00,0x28,0x40,0x77,0x06,0x80,0x40,0x7B,0x69,0x92,0x59,0x70, -0x3E,0x10,0x59,0x4A,0x62,0xFF,0x2B,0x7F,0x74,0x12,0x00,0x02,0x7F,0x1B,0xA0,0x4F, -0xE0,0x13,0x00,0x00,0xA0,0x68,0xA0,0x10,0x2C,0xCC,0xF4,0xEF,0xB0,0x04,0x00,0x00, -0x83,0x7F,0x74,0x12,0x00,0x02,0x70,0x2A,0x62,0x7F,0x0E,0x3F,0x02,0xCA,0x0F,0x7F, -0x08,0x3F,0x03,0xCA,0x0F,0x77,0x29,0x2B,0x7F,0x72,0x08,0x00,0x02,0x7F,0x1A,0x83, -0x7F,0x72,0x08,0x00,0x02,0x70,0x82,0x7F,0x76,0x12,0x00,0x02,0x70,0x87,0x5F,0xFF, -0x00,0x7F,0x73,0x08,0x00,0x02,0x70,0x2C,0x5C,0x7F,0xD4,0x8E,0x00,0x00,0x86,0x62, -0xE4,0x40,0x7B,0x02,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x10,0x49,0x9C,0x4F, -0x00,0x00,0x00,0x00,0x4C,0x3F,0x73,0x7F,0x01,0xD0,0x04,0x00,0x77,0x07,0x84,0x01, -0x40,0x7B,0x1D,0x87,0x73,0x7F,0x03,0xD0,0x04,0x00,0x70,0xA0,0x1C,0xA0,0x10,0x2C, -0xCC,0xF8,0x7F,0xFC,0x8E,0x00,0x00,0x86,0xE2,0x40,0xE0,0x40,0x7B,0x02,0x04,0xC9, -0xE8,0x4C,0x20,0x49,0x08,0x70,0x10,0x49,0x9C,0x4F,0x04,0x00,0x00,0x00,0x4C,0x82, -0x59,0x70,0x7B,0x42,0x86,0x59,0xE4,0x40,0xD0,0x03,0x40,0x40,0x9C,0x74,0x40,0x3C, -0xDA,0x00,0x50,0x77,0x18,0x86,0x59,0xE4,0x40,0xD0,0x03,0x40,0x40,0x9C,0x74,0x40, -0x84,0xC0,0x04,0xDA,0x00,0x70,0x84,0x01,0x40,0x7B,0x25,0x86,0x59,0xE4,0x40,0xD0, -0x03,0x40,0x40,0x9C,0x74,0x40,0x3C,0xDA,0x00,0x50,0x5F,0x07,0x84,0x01,0x40,0x7B, -0x0F,0x92,0x59,0x70,0x3E,0x6F,0x40,0x59,0x4B,0xBC,0x80,0x40,0x7B,0x02,0x04,0xC9, -0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x70,0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00, -0x4C,0x70,0x84,0x40,0x7F,0xDC,0x0F,0x00,0x02,0x70,0x84,0xCC,0xFC,0x7F,0x74,0x13, -0x00,0x02,0x70,0x84,0xCC,0xF8,0x7F,0x78,0x13,0x00,0x02,0x70,0x04,0x7F,0x60,0x2B, -0x02,0x00,0x40,0x30,0xAC,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x10,0x49,0x9C,0x4F, -0x00,0x00,0x00,0x00,0x4C,0x87,0x01,0x7F,0x03,0x40,0x04,0x00,0x70,0x87,0x01,0x7F, -0x07,0x40,0x04,0x00,0x70,0x87,0x01,0x7F,0x0F,0x40,0x04,0x00,0x70,0x87,0x01,0x7F, -0x2F,0x40,0x04,0x00,0x70,0x87,0x01,0x7F,0x27,0x40,0x04,0x00,0x70,0x84,0x4F,0x00, -0xE1,0x81,0x00,0x4B,0x70,0x70,0x84,0x4F,0x18,0x1E,0x00,0x02,0x4C,0x84,0x4F,0x18, -0x1E,0x00,0x02,0x49,0x84,0x4F,0x18,0x1E,0x00,0x02,0x4A,0x84,0x4F,0xC4,0x0E,0x00, -0x02,0x4D,0xDC,0x0C,0x7F,0xC4,0x0E,0x00,0x02,0x40,0x84,0x4F,0x18,0x1E,0x00,0x02, -0x50,0x70,0xDC,0x10,0x7F,0xC4,0x0E,0x00,0x02,0x40,0x84,0x4F,0x44,0x1F,0x00,0x02, -0x50,0x70,0x80,0x7F,0x54,0x10,0x00,0x02,0x70,0x2C,0x5C,0x7F,0x70,0xE3,0x00,0x00, -0xA0,0x05,0x2C,0xCC,0xFC,0x7F,0x62,0x97,0x00,0x00,0x04,0xC9,0xE8,0x4C,0x20,0x49, -0x08,0x70,0x70,0x70,0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x84,0x7F,0xD4, -0x0F,0x00,0x02,0x7F,0x74,0x13,0x00,0x02,0x70,0x84,0x7F,0xD8,0x0F,0x00,0x02,0x7F, -0x78,0x13,0x00,0x02,0x70,0x2C,0x5C,0x7F,0x3C,0x7A,0x00,0x00,0xF8,0x03,0x7F,0xD4, -0x0F,0x00,0x02,0x40,0x3C,0x03,0x40,0x7F,0x0E,0xA0,0x13,0xA0,0x00,0x2C,0xCC,0xF8, -0xAF,0xFD,0x00,0x7B,0x0C,0xA0,0x10,0xA0,0x00,0x2C,0xCC,0xF8,0xAF,0xF1,0x00,0x04, -0xC9,0xE8,0x4C,0x20,0x49,0x08,0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0xA0, -0x4F,0x98,0x19,0x00,0x00,0xA0,0xEF,0xF8,0x04,0x00,0x00,0xA0,0xEF,0xF4,0x04,0x00, -0x00,0x2C,0xCC,0xF4,0xEF,0xB0,0x04,0x00,0x00,0xA0,0x14,0xA0,0x00,0x2C,0xCC,0xF8, -0xAF,0xBD,0x00,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x10,0x49,0x9C,0x4F,0x00,0x00, -0x00,0x00,0x4C,0x04,0x7F,0x3C,0x94,0x00,0x00,0x40,0x30,0x13,0x70,0x84,0x4F,0x18, -0x1E,0x00,0x02,0x4C,0xA0,0x13,0xA0,0x01,0x2C,0xCC,0xF8,0xAF,0x92,0x00,0x04,0xC9, -0xE8,0x4C,0x20,0x49,0x08,0x70,0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x04, -0x7F,0x68,0x94,0x00,0x00,0x40,0x30,0x13,0x70,0x84,0x4F,0x18,0x1E,0x00,0x02,0x4C, -0xA0,0x10,0xA0,0x01,0x2C,0xCC,0xF8,0xAF,0x66,0x00,0x04,0xC9,0xE8,0x4C,0x20,0x49, -0x08,0x70,0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x04,0x7F,0x94,0x94,0x00, -0x00,0x40,0x30,0x13,0x70,0x84,0x4F,0x18,0x1E,0x00,0x02,0x4C,0xA0,0x11,0xA0,0x01, -0x2C,0xCC,0xF8,0xAF,0x3A,0x00,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x10,0x49, -0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x04,0x7F,0xC0,0x94,0x00,0x00,0x40,0x30,0x13, -0x70,0x84,0x4F,0x18,0x1E,0x00,0x02,0x4C,0xA0,0x14,0xA0,0x01,0x2C,0xCC,0xF8,0xAF, -0x0E,0x00,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x10,0x49,0x9C,0x4F,0x00,0x00, -0x00,0x00,0x4C,0x3C,0x01,0x7F,0x58,0x10,0x00,0x02,0x77,0x21,0x28,0x7F,0xDC,0x1D, -0x00,0x02,0x77,0x19,0x2C,0x5C,0x7F,0x50,0x9E,0x00,0x00,0x84,0x74,0x7F,0xB4,0x13, -0x00,0x02,0x70,0x84,0x74,0x7F,0xB8,0x13,0x00,0x02,0x70,0x3C,0x01,0x7F,0x58,0x10, -0x00,0x02,0x77,0x3A,0x84,0x4E,0x7F,0x08,0x1E,0x00,0x02,0x70,0xFC,0x04,0x7F,0x08, -0x1E,0x00,0x02,0x40,0xA0,0x40,0x2C,0xCC,0xFC,0x7F,0x6C,0xD7,0x00,0x00,0x84,0x50, -0x7F,0xFC,0x1D,0x00,0x02,0x70,0xA0,0x7F,0xFC,0x1D,0x00,0x02,0x2C,0xCC,0xFC,0x7F, -0x6C,0xD7,0x00,0x00,0x84,0x40,0x7F,0xF8,0x1D,0x00,0x02,0x70,0x84,0x5A,0x7F,0xB0, -0x13,0x00,0x02,0x70,0x84,0x02,0x7F,0x88,0x13,0x00,0x02,0x70,0xA0,0x04,0x2C,0xCC, -0xFC,0x7F,0x62,0x97,0x00,0x00,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x10,0x49, -0x9C,0x4F,0x04,0x00,0x00,0x00,0x4C,0x84,0x7F,0xB0,0x13,0x00,0x02,0x59,0x70,0x84, -0xFF,0x7F,0xB0,0x13,0x00,0x02,0x70,0x3C,0x10,0x59,0x77,0x13,0xF8,0x6F,0x78,0x7F, -0x74,0x13,0x00,0x02,0x40,0xD4,0x03,0x40,0x40,0x84,0x40,0x59,0x70,0x04,0xC9,0xE8, -0x4C,0x20,0x49,0x08,0x70,0x70,0x10,0x49,0x9C,0x4F,0x04,0x00,0x00,0x00,0x4C,0x84, -0x7F,0xB0,0x13,0x00,0x02,0x59,0x70,0x84,0xFF,0x7F,0xB0,0x13,0x00,0x02,0x70,0x3C, -0x11,0x59,0x7F,0x07,0x3C,0x10,0x59,0x77,0x58,0xBC,0x04,0x7F,0x08,0x1E,0x00,0x02, -0x70,0xDC,0x08,0x7F,0xF8,0x1D,0x00,0x02,0x40,0xBC,0x08,0x50,0x70,0xDC,0x04,0x7F, -0xF8,0x1D,0x00,0x02,0x40,0x84,0x7F,0x78,0x13,0x00,0x02,0x50,0x70,0x84,0x7F,0x74, -0x13,0x00,0x02,0xEF,0xF8,0x1D,0x00,0x02,0x70,0xDC,0x1C,0x7F,0xF8,0x1D,0x00,0x02, -0x40,0x84,0x7F,0xDC,0x0F,0x00,0x02,0x50,0x70,0x3C,0x10,0x59,0x77,0x13,0xF8,0x6F, -0x78,0x7F,0x74,0x13,0x00,0x02,0x40,0xD4,0x03,0x40,0x40,0x84,0x40,0x59,0x70,0x84, -0x59,0x40,0x7B,0x39,0x2C,0x5C,0x7F,0xF4,0xDD,0x00,0x00,0x7B,0x3C,0x2C,0x5C,0x7F, -0xDC,0x97,0x00,0x00,0x7B,0x33,0x28,0x7F,0xDC,0x1D,0x00,0x02,0x7F,0x13,0x80,0x7F, -0xDC,0x1D,0x00,0x02,0x70,0xA0,0x00,0x2C,0xCC,0xFC,0x7F,0x92,0xDC,0x00,0x00,0xA0, -0x05,0x2C,0xCC,0xFC,0x7F,0x62,0x97,0x00,0x00,0x7B,0x0E,0x3C,0x40,0x01,0x7F,0xC6, -0x3C,0x40,0x0E,0x7F,0xCA,0x7B,0xD1,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x10,0x49, -0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x2C,0x5C,0x7F,0x70,0xE3,0x00,0x00,0x84,0x01, -0x7F,0x58,0x10,0x00,0x02,0x70,0x80,0x7F,0xDC,0x1D,0x00,0x02,0x70,0x2C,0x5C,0x7F, -0x06,0x9F,0x00,0x00,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x10,0x49,0x9C,0x4F, -0x04,0x00,0x00,0x00,0x4C,0x84,0x5A,0x40,0x7B,0x08,0x84,0x4E,0x59,0x70,0x7B,0x07, -0x3C,0x40,0x12,0x7F,0xF7,0x84,0x59,0x40,0x7B,0x02,0x04,0xC9,0xE8,0x4C,0x20,0x49, -0x08,0x70,0x70,0x70,0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x84,0x5A,0x40, -0x7B,0x07,0x84,0x74,0x4E,0x7B,0x07,0x3C,0x40,0x12,0x7F,0xF8,0x04,0xC9,0xE8,0x4C, -0x20,0x49,0x08,0x70,0x10,0x49,0x9C,0x4F,0x04,0x00,0x00,0x00,0x4C,0x84,0x7F,0x88, -0x13,0x00,0x02,0x59,0x70,0x84,0x04,0x7F,0x88,0x13,0x00,0x02,0x70,0x84,0x59,0x40, -0x7B,0x4E,0x3C,0x01,0x7F,0x58,0x10,0x00,0x02,0x77,0x1A,0x84,0x02,0x7F,0x58,0x10, -0x00,0x02,0x70,0x2C,0x5C,0x7F,0xA6,0x95,0x00,0x00,0x2C,0x5C,0x7F,0xA8,0xBD,0x00, -0x00,0x7B,0x09,0x2C,0x5C,0x7F,0x6E,0x95,0x00,0x00,0x3C,0x03,0x7F,0x58,0x10,0x00, -0x02,0x77,0x11,0x84,0x02,0x7F,0x58,0x10,0x00,0x02,0x70,0x2C,0x5C,0x7F,0xA8,0xBD, -0x00,0x00,0xA0,0x04,0x2C,0xCC,0xFC,0x7F,0xEA,0xC1,0x00,0x00,0x7B,0x0E,0x3C,0x40, -0x02,0x7F,0xB1,0x3C,0x40,0x03,0x7F,0xD4,0x7B,0xEA,0x04,0xC9,0xE8,0x4C,0x20,0x49, -0x08,0x70,0x10,0x49,0x9C,0x4F,0x04,0x00,0x00,0x00,0x4C,0x84,0x5A,0x40,0x7B,0x30, -0x84,0x4F,0x78,0x12,0x00,0x02,0x59,0x70,0x7B,0x37,0x84,0x4F,0x64,0x2A,0x00,0x00, -0x59,0x70,0x7B,0x2D,0xA0,0x4F,0xC0,0x19,0x00,0x00,0xA0,0x5A,0x2C,0xCC,0xF8,0xEF, -0xB0,0x04,0x00,0x00,0x84,0x4F,0xB8,0x2A,0x00,0x00,0x59,0x70,0x7B,0x13,0x3C,0x40, -0x04,0x7F,0xCF,0x3C,0x40,0x05,0x7F,0xEE,0x3C,0x40,0x06,0x7F,0xCF,0x7B,0xD7,0x84, -0x59,0x7F,0x7C,0x13,0x00,0x02,0x70,0x04,0x7F,0x80,0x13,0x00,0x02,0x4E,0x30,0xC8, -0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x70,0x10,0x49,0x9C,0x4F,0x00,0x00, -0x00,0x00,0x4C,0x30,0xC8,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x10,0x49,0x9C,0x4F, -0x04,0x00,0x00,0x00,0x4C,0xDC,0x04,0x7F,0xF8,0x1D,0x00,0x02,0x40,0x94,0x50,0x70, -0xDC,0x04,0x7F,0xF8,0x1D,0x00,0x02,0x40,0xA0,0x50,0x2C,0xCC,0xFC,0xAF,0x9C,0x01, -0x84,0x40,0x59,0x70,0x24,0x7F,0x73,0x99,0x00,0x00,0x80,0x7F,0x1C,0x1D,0x00,0x02, -0x70,0x80,0x7F,0x20,0x1D,0x00,0x02,0x70,0x2C,0x5C,0x7F,0x42,0xD3,0x00,0x00,0xA0, -0x4F,0xEC,0x19,0x00,0x00,0x2C,0xCC,0xFC,0xEF,0xB0,0x04,0x00,0x00,0x24,0x7F,0x8E, -0x99,0x00,0x00,0x80,0x7F,0x74,0x1C,0x00,0x02,0x70,0x80,0x7F,0x78,0x1C,0x00,0x02, -0x70,0x84,0x04,0x7F,0xDC,0x1D,0x00,0x02,0x70,0x2C,0x5C,0x7F,0x82,0xE1,0x00,0x00, -0x28,0x7F,0xE8,0x1D,0x00,0x02,0x7F,0x32,0xDC,0x04,0x7F,0xF8,0x1D,0x00,0x02,0x40, -0x3C,0x7F,0xEC,0x1D,0x00,0x02,0x50,0x7F,0x18,0xA0,0x01,0x2C,0xCC,0xFC,0x7F,0x92, -0xDC,0x00,0x00,0xA0,0x06,0x2C,0xCC,0xFC,0x7F,0x62,0x97,0x00,0x00,0x7B,0x09,0x80, -0x7F,0xDC,0x1D,0x00,0x02,0x70,0x7B,0x28,0x94,0x7F,0xE0,0x1D,0x00,0x02,0x70,0x4F, -0x18,0xA0,0x01,0x2C,0xCC,0xFC,0x7F,0x92,0xDC,0x00,0x00,0xA0,0x06,0x2C,0xCC,0xFC, -0x7F,0x62,0x97,0x00,0x00,0x7B,0x09,0x80,0x7F,0xDC,0x1D,0x00,0x02,0x70,0x24,0x7F, -0x8E,0x99,0x00,0x00,0xA0,0x4F,0x05,0x1A,0x00,0x00,0x2C,0xCC,0xFC,0xEF,0xB0,0x04, -0x00,0x00,0x80,0x7F,0xC8,0x1C,0x00,0x02,0x70,0x80,0x7F,0xCC,0x1C,0x00,0x02,0x70, -0x24,0x7F,0x8E,0x99,0x00,0x00,0xA0,0x4F,0x1A,0x1A,0x00,0x00,0x2C,0xCC,0xFC,0xEF, -0xB0,0x04,0x00,0x00,0xDC,0x04,0x7F,0xF8,0x1D,0x00,0x02,0x40,0x90,0x50,0x70,0xE8, -0x6F,0x54,0x59,0x40,0x3C,0x01,0x80,0xDC,0x15,0x00,0x02,0x4F,0x2C,0xE8,0x6F,0x54, -0x59,0x40,0x94,0x80,0xDC,0x15,0x00,0x02,0x70,0x84,0x01,0x7F,0xDC,0x1D,0x00,0x02, -0x70,0xA0,0x01,0x2C,0xCC,0xFC,0x7F,0x92,0xDC,0x00,0x00,0xA0,0x06,0x2C,0xCC,0xFC, -0x7F,0x62,0x97,0x00,0x00,0x7B,0x4C,0xE8,0x6F,0x54,0x59,0x40,0xE8,0x6F,0x54,0x59, -0x41,0x84,0x81,0xE0,0x15,0x00,0x02,0x80,0xDC,0x15,0x00,0x02,0x70,0xE8,0x6F,0x54, -0x59,0x40,0x90,0x80,0xD8,0x15,0x00,0x02,0x70,0x2C,0x5C,0x7F,0x74,0xB8,0x00,0x00, -0xE8,0x6F,0x54,0x59,0x40,0x2B,0x80,0xF1,0x15,0x00,0x02,0x7F,0x16,0xE8,0x6F,0x54, -0x59,0x40,0x9C,0x4F,0xF1,0x15,0x00,0x02,0x40,0x84,0x40,0x7F,0xCC,0x13,0x00,0x02, -0x70,0x7B,0x1D,0x3C,0x40,0xFF,0x7E,0x60,0xFF,0x3C,0x40,0x14,0x7E,0xB7,0xFE,0x3C, -0x40,0x15,0x7E,0x32,0xFF,0x3C,0x40,0x16,0x7E,0x82,0xFE,0x7A,0x64,0xFF,0x04,0xC9, -0xE8,0x4C,0x20,0x49,0x08,0x70,0x10,0x49,0x9C,0x4F,0x08,0x00,0x00,0x00,0x4C,0xA0, -0x5A,0x2C,0xCC,0xFC,0x7F,0x6C,0xD7,0x00,0x00,0x84,0x40,0x64,0x70,0x84,0x16,0x59, -0x70,0x7B,0x33,0xE8,0x6F,0x54,0x59,0x40,0x28,0x80,0xE4,0x15,0x00,0x02,0x7F,0x23, -0xE8,0x6F,0x54,0x59,0x40,0x3C,0x80,0xD4,0x15,0x00,0x02,0x64,0x77,0x15,0xE8,0x6F, -0x54,0x59,0x40,0x3C,0x80,0xD0,0x15,0x00,0x02,0x5A,0x77,0x07,0x84,0x59,0x40,0x7B, -0x0E,0x94,0x59,0x70,0x28,0x59,0x43,0xCD,0x84,0xFF,0x40,0x7B,0x02,0x04,0xC9,0xE8, -0x4C,0x20,0x49,0x08,0x10,0x49,0x9C,0x4F,0x14,0x00,0x00,0x00,0x4C,0x2C,0x5C,0x7F, -0x76,0xC4,0x00,0x00,0x28,0x40,0x77,0x08,0x24,0x7F,0xF7,0x9A,0x00,0x00,0xA0,0x4F, -0x3C,0x1A,0x00,0x00,0x2C,0xCC,0xFC,0xEF,0xB0,0x04,0x00,0x00,0x80,0x59,0x70,0x24, -0x7F,0xEB,0x9A,0x00,0x00,0xE8,0x6F,0x54,0x59,0x40,0x28,0x80,0xE8,0x15,0x00,0x02, -0x77,0x08,0x24,0x7F,0xE8,0x9A,0x00,0x00,0xE8,0x6F,0x54,0x59,0x40,0x28,0x80,0xE4, -0x15,0x00,0x02,0x77,0x12,0xA0,0x4F,0x4B,0x1A,0x00,0x00,0x2C,0xCC,0xFC,0xEF,0xB0, -0x04,0x00,0x00,0x7B,0x10,0xA0,0x4F,0x4F,0x1A,0x00,0x00,0x2C,0xCC,0xFC,0xEF,0xB0, -0x04,0x00,0x00,0xA0,0x4F,0x53,0x1A,0x00,0x00,0xA0,0x59,0xE8,0x6F,0x54,0x59,0x40, -0xA0,0x80,0xD0,0x15,0x00,0x02,0xE8,0x6F,0x54,0x59,0x40,0xA0,0x80,0xD4,0x15,0x00, -0x02,0x2C,0xCC,0xF0,0xEF,0xB0,0x04,0x00,0x00,0xE8,0x6F,0x54,0x59,0x40,0xA0,0x80, -0xD0,0x15,0x00,0x02,0x2C,0xCC,0xFC,0x7F,0x9C,0xD0,0x00,0x00,0xA0,0x4F,0x66,0x1A, -0x00,0x00,0xE8,0x6F,0x54,0x59,0x40,0xA0,0x80,0xDC,0x15,0x00,0x02,0xE8,0x6F,0x54, -0x59,0x40,0xA0,0x80,0xE0,0x15,0x00,0x02,0xE8,0x6F,0x54,0x59,0x40,0xA0,0x80,0xD8, -0x15,0x00,0x02,0xE8,0x6F,0x54,0x59,0x40,0x87,0x80,0xF0,0x15,0x00,0x02,0xE0,0x40, -0xA0,0x40,0xE8,0x6F,0x54,0x59,0x40,0x9C,0x4F,0xF1,0x15,0x00,0x02,0x40,0xA0,0x40, -0x2C,0xCC,0xE8,0xEF,0xB0,0x04,0x00,0x00,0x90,0x59,0x70,0x3C,0x14,0x59,0x4A,0x37, -0xFF,0x24,0x7F,0xAD,0x9B,0x00,0x00,0x2C,0x5C,0x7F,0xDC,0xC5,0x00,0x00,0x84,0x40, -0x64,0x70,0x2C,0x5C,0x7F,0x76,0xC4,0x00,0x00,0x28,0x40,0x77,0x14,0x2C,0x5C,0x7F, -0xF6,0xC3,0x00,0x00,0x87,0x40,0xC9,0x10,0x70,0x3F,0x3A,0xC9,0x10,0x77,0x08,0x84, -0x01,0x6C,0x70,0x7B,0x0D,0x2C,0x5C,0x7F,0xA0,0xCE,0x00,0x00,0x84,0x40,0x6C,0x70, -0xA0,0x64,0x2C,0xCC,0xFC,0xAF,0x64,0xFE,0x84,0x40,0x59,0x70,0x3C,0xFF,0x40,0x7F, -0x07,0x3C,0x14,0x59,0x4B,0x5D,0xA0,0x64,0x2C,0xCC,0xFC,0x7F,0x6C,0xD7,0x00,0x00, -0x84,0x40,0x68,0x70,0x80,0x59,0x70,0x7B,0x23,0xE8,0x6F,0x54,0x59,0x40,0x3C,0x68, -0x80,0xD4,0x15,0x00,0x02,0x77,0x12,0xE8,0x6F,0x54,0x59,0x40,0x3C,0x80,0xD0,0x15, -0x00,0x02,0x64,0x77,0x04,0x7B,0x17,0x90,0x59,0x70,0x3C,0x14,0x59,0x43,0x0F,0xE8, -0x6F,0x54,0x59,0x40,0x28,0x80,0xE8,0x15,0x00,0x02,0x77,0xCF,0x3C,0x14,0x59,0x4B, -0x12,0xA0,0x4F,0xB0,0x90,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xEA,0xC1,0x00,0x00,0x7B, -0x0E,0xA0,0x59,0xA0,0x64,0xA0,0x6C,0x2C,0xCC,0xF4,0xAF,0x91,0x04,0x04,0xC9,0xE8, -0x4C,0x20,0x49,0x08,0x10,0x49,0x9C,0x4F,0x08,0x00,0x00,0x00,0x4C,0x2C,0x5C,0x7F, -0xF6,0xC3,0x00,0x00,0x3C,0x23,0x40,0x77,0x16,0x90,0x7F,0xCC,0x13,0x00,0x02,0x70, -0x2C,0x5C,0x7F,0xA0,0xCE,0x00,0x00,0x84,0x40,0x64,0x70,0x7B,0x32,0xA0,0x4F,0x95, -0x1A,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xD6,0xC4,0x00,0x00,0x28,0x40,0x7F,0x09,0x2C, -0x5C,0xAF,0x11,0x04,0x7B,0x46,0x2C,0x5C,0x7F,0xDC,0xC5,0x00,0x00,0x84,0x40,0x59, -0x70,0xA0,0x59,0x2C,0xCC,0xFC,0xAF,0x93,0xFD,0x84,0x40,0x64,0x70,0x28,0x64,0x4B, -0x07,0x3C,0x14,0x64,0x4F,0x0E,0xA0,0x5F,0xB0,0x50,0x2C,0xCC,0xFC,0x7F,0xEA,0xC1, -0x00,0x00,0xE8,0x6F,0x54,0x64,0x40,0x80,0x80,0xE4,0x15,0x00,0x02,0x70,0xE8,0x6F, -0x54,0x64,0x40,0x80,0x80,0xE8,0x15,0x00,0x02,0x70,0x04,0xC9,0xE8,0x4C,0x20,0x49, -0x08,0x70,0x10,0x49,0x9C,0x4F,0x08,0x00,0x00,0x00,0x4C,0x2C,0x5C,0x7F,0xF6,0xC3, -0x00,0x00,0x3C,0x23,0x40,0x77,0x16,0x90,0x7F,0xCC,0x13,0x00,0x02,0x70,0x2C,0x5C, -0x7F,0xA0,0xCE,0x00,0x00,0x84,0x40,0x64,0x70,0x7B,0x32,0xA0,0x4F,0x99,0x1A,0x00, -0x00,0x2C,0xCC,0xFC,0x7F,0xD6,0xC4,0x00,0x00,0x28,0x40,0x7F,0x09,0x2C,0x5C,0xAF, -0x47,0x00,0x7B,0x3A,0x2C,0x5C,0x7F,0xDC,0xC5,0x00,0x00,0x84,0x40,0x59,0x70,0xA0, -0x59,0x2C,0xCC,0xFC,0xAF,0x05,0xFD,0x84,0x40,0x64,0x70,0x28,0x64,0x4B,0x07,0x3C, -0x14,0x64,0x4B,0x0E,0xA0,0x5F,0xB0,0x50,0x2C,0xCC,0xFC,0x7F,0xEA,0xC1,0x00,0x00, -0xE8,0x6F,0x54,0x64,0x40,0x80,0x80,0xE4,0x15,0x00,0x02,0x70,0x04,0xC9,0xE8,0x4C, -0x20,0x49,0x08,0x70,0x10,0x48,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x80,0x48,0x7B, -0x10,0xE8,0x6F,0x54,0x48,0x40,0x80,0x80,0xE4,0x15,0x00,0x02,0x70,0x90,0x48,0x3C, -0x17,0x48,0x4B,0xEF,0x04,0xC9,0xEC,0x4C,0x20,0x48,0x20,0x49,0x08,0x70,0x70,0x70, -0x10,0x49,0x9C,0x4F,0x0C,0x00,0x00,0x00,0x4C,0x2C,0x5C,0x7F,0xF6,0xC3,0x00,0x00, -0x3C,0x23,0x40,0x77,0x16,0x90,0x7F,0xCC,0x13,0x00,0x02,0x70,0x2C,0x5C,0x7F,0xA0, -0xCE,0x00,0x00,0x84,0x40,0x68,0x70,0x7B,0x6C,0xA0,0x4F,0x9D,0x1A,0x00,0x00,0x2C, -0xCC,0xFC,0x7F,0xD6,0xC4,0x00,0x00,0x28,0x40,0x7F,0x09,0x2C,0x5C,0xAF,0x81,0x00, -0x7B,0x75,0x2C,0x5C,0x7F,0xDC,0xC5,0x00,0x00,0x84,0x40,0x59,0x70,0x80,0x68,0x70, -0x7B,0x3E,0xE8,0x6F,0x54,0x68,0x40,0x28,0x80,0xE8,0x15,0x00,0x02,0x7F,0x2E,0xA0, -0x59,0x2C,0xCC,0xFC,0x7F,0x6C,0xD7,0x00,0x00,0x84,0x40,0x64,0x70,0xE8,0x6F,0x54, -0x68,0x40,0x3C,0x59,0x80,0xD0,0x15,0x00,0x02,0x77,0x12,0xE8,0x6F,0x54,0x68,0x40, -0x3C,0x64,0x80,0xD4,0x15,0x00,0x02,0x77,0x04,0x7B,0x0A,0x90,0x68,0x70,0x3C,0x17, -0x68,0x4B,0xC1,0x28,0x68,0x4B,0x07,0x3C,0x14,0x68,0x4B,0x0E,0xA0,0x5F,0xB0,0x50, -0x2C,0xCC,0xFC,0x7F,0xEA,0xC1,0x00,0x00,0xE8,0x6F,0x54,0x68,0x40,0x84,0x01,0x80, -0xE4,0x15,0x00,0x02,0x70,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x10,0x48,0x9C,0x4F, -0x00,0x00,0x00,0x00,0x4C,0x80,0x48,0x7B,0x1E,0xE8,0x6F,0x54,0x48,0x40,0x28,0x80, -0xE8,0x15,0x00,0x02,0x7F,0x0F,0xE8,0x6F,0x54,0x48,0x40,0x84,0x01,0x80,0xE4,0x15, -0x00,0x02,0x70,0x90,0x48,0x3C,0x17,0x48,0x4B,0xE1,0x04,0xC9,0xEC,0x4C,0x20,0x48, -0x20,0x49,0x08,0x70,0x10,0x49,0x9C,0x4F,0x04,0x00,0x00,0x00,0x4C,0x80,0x59,0x70, -0x7B,0x51,0xE8,0x6F,0x54,0x59,0x40,0x28,0x80,0xE4,0x15,0x00,0x02,0x7F,0x41,0xE8, -0x6F,0x54,0x59,0x40,0xE8,0x6F,0x54,0x59,0x41,0x3F,0x81,0xF0,0x15,0x00,0x02,0x90, -0xD4,0x15,0x00,0x02,0x7F,0x2A,0xE8,0x6F,0x54,0x59,0x40,0x80,0x80,0xE4,0x15,0x00, -0x02,0x70,0xE8,0x6F,0x54,0x59,0x40,0x80,0x80,0xE8,0x15,0x00,0x02,0x70,0xA0,0x4F, -0xA1,0x1A,0x00,0x00,0xA0,0x59,0x2C,0xCC,0xF8,0xEF,0xB0,0x04,0x00,0x00,0x90,0x59, -0x70,0x3C,0x17,0x59,0x4B,0xAE,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x70, -0x10,0x49,0x9C,0x4F,0x0C,0x00,0x00,0x00,0x4C,0x80,0x59,0x70,0x7B,0x36,0xE8,0x6F, -0x54,0x59,0x40,0x28,0x80,0xE4,0x15,0x00,0x02,0x7F,0x26,0xE8,0x6F,0x54,0x59,0x40, -0x3F,0x2E,0x90,0xD4,0x15,0x00,0x02,0x77,0x18,0xE8,0x6F,0x54,0x59,0x40,0xE8,0x6F, -0x54,0x59,0x41,0x87,0x81,0xF0,0x15,0x00,0x02,0x90,0xD4,0x15,0x00,0x02,0x70,0x90, -0x59,0x70,0x3C,0x17,0x59,0x4B,0xC9,0x84,0x7F,0xB8,0x13,0x00,0x02,0x68,0x70,0x28, -0x7F,0x88,0x27,0x00,0x02,0x4F,0x42,0x84,0x01,0x7F,0xB8,0x13,0x00,0x02,0x70,0xA0, -0x00,0x2C,0xCC,0xFC,0x7F,0xA0,0xDA,0x00,0x00,0x84,0x40,0x64,0x70,0xDC,0x6F,0x70, -0x64,0x40,0xA0,0x40,0xA0,0x7F,0x94,0x27,0x00,0x02,0x2C,0xCC,0xF8,0x7F,0xA0,0xDB, -0x00,0x00,0xDC,0x6F,0x74,0x64,0x40,0xA0,0x40,0xA0,0x7F,0x98,0x27,0x00,0x02,0x2C, -0xCC,0xF8,0x7F,0xA0,0xDB,0x00,0x00,0x84,0x68,0x7F,0xB8,0x13,0x00,0x02,0x70,0x80, -0x7F,0x84,0x27,0x00,0x02,0x70,0x80,0x7F,0x88,0x27,0x00,0x02,0x70,0x04,0xC9,0xE8, -0x4C,0x20,0x49,0x08,0x70,0x70,0x10,0x49,0x9C,0x4F,0x0C,0x00,0x00,0x00,0x4C,0x80, -0x7F,0x84,0x27,0x00,0x02,0x70,0x80,0x7F,0x88,0x27,0x00,0x02,0x70,0x80,0x59,0x70, -0x7B,0x4C,0xE8,0x6F,0x54,0x59,0x40,0x28,0x80,0xE4,0x15,0x00,0x02,0x7F,0x3C,0xE8, -0x6F,0x54,0x59,0x40,0x87,0x2E,0x90,0xD4,0x15,0x00,0x02,0x70,0xE8,0x6F,0x54,0x59, -0x40,0x3F,0x2E,0x90,0xD4,0x15,0x00,0x02,0x77,0x21,0xE8,0x6F,0x54,0x59,0x40,0x28, -0x80,0xEC,0x15,0x00,0x02,0x7F,0x0B,0x90,0x7F,0x88,0x27,0x00,0x02,0x70,0x7B,0x09, -0x90,0x7F,0x84,0x27,0x00,0x02,0x70,0x7B,0x02,0x90,0x59,0x70,0x3C,0x17,0x59,0x4B, -0xB3,0x84,0x7F,0xB8,0x13,0x00,0x02,0x68,0x70,0x28,0x7F,0x88,0x27,0x00,0x02,0x4F, -0x70,0x84,0x01,0x7F,0xB8,0x13,0x00,0x02,0x70,0xA0,0x00,0x2C,0xCC,0xFC,0x7F,0xA0, -0xDA,0x00,0x00,0x84,0x40,0x64,0x70,0xDC,0x6F,0x70,0x64,0x40,0xA0,0x40,0x2C,0xCC, -0xFC,0x7F,0xA0,0xDA,0x00,0x00,0x84,0x40,0x7F,0x94,0x27,0x00,0x02,0x70,0xDC,0x6F, -0x74,0x64,0x40,0xA0,0x40,0x2C,0xCC,0xFC,0x7F,0xA0,0xDA,0x00,0x00,0x84,0x40,0x7F, -0x98,0x27,0x00,0x02,0x70,0xDC,0x6F,0x70,0x64,0x40,0xA0,0x40,0xA0,0x4F,0x00,0xE1, -0x81,0x00,0x2C,0xCC,0xF8,0x7F,0xA0,0xDB,0x00,0x00,0xDC,0x6F,0x74,0x64,0x40,0xA0, -0x40,0xA0,0x4F,0xE1,0x92,0x02,0x00,0x2C,0xCC,0xF8,0x7F,0xA0,0xDB,0x00,0x00,0x84, -0x68,0x7F,0xB8,0x13,0x00,0x02,0x70,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70, -0x10,0x48,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x80,0x48,0x7B,0x1C,0xE8,0x6F,0x54, -0x48,0x40,0x80,0x80,0xE4,0x15,0x00,0x02,0x70,0xE8,0x6F,0x54,0x48,0x40,0x80,0x80, -0xE8,0x15,0x00,0x02,0x70,0x90,0x48,0x3C,0x17,0x48,0x4B,0xE3,0x04,0xC9,0xEC,0x4C, -0x20,0x48,0x20,0x49,0x08,0x70,0x70,0x70,0x10,0x49,0x9C,0x4F,0x04,0x00,0x00,0x00, -0x4C,0xE8,0x6F,0x54,0x5A,0x40,0x84,0x74,0x80,0xD0,0x15,0x00,0x02,0x70,0xA0,0x74, -0x2C,0xCC,0xFC,0x7F,0x6C,0xD7,0x00,0x00,0xE8,0x6F,0x54,0x5A,0x41,0x84,0x40,0x81, -0xD4,0x15,0x00,0x02,0x70,0xE8,0x6F,0x54,0x5A,0x40,0x80,0x80,0xD8,0x15,0x00,0x02, -0x70,0xE8,0x6F,0x54,0x5A,0x40,0x84,0x78,0x80,0xDC,0x15,0x00,0x02,0x70,0xE8,0x6F, -0x54,0x5A,0x40,0x84,0x78,0x80,0xE0,0x15,0x00,0x02,0x70,0x2C,0x5C,0x7F,0xF6,0xC3, -0x00,0x00,0x87,0x40,0x59,0x70,0x3F,0x3A,0x59,0x77,0x2E,0x90,0x7F,0xCC,0x13,0x00, -0x02,0x70,0xE8,0x6F,0x54,0x5A,0x40,0x9C,0x4F,0xF1,0x15,0x00,0x02,0x40,0xA0,0x40, -0xA0,0x7F,0xCC,0x13,0x00,0x02,0x2C,0xCC,0xF8,0x7F,0x6C,0xEA,0x00,0x00,0x83,0xEF, -0xCC,0x13,0x00,0x02,0x70,0x7B,0x0E,0xE8,0x6F,0x54,0x5A,0x40,0x83,0x80,0xF1,0x15, -0x00,0x02,0x70,0xE8,0x6F,0x54,0x5A,0x40,0xE8,0x6F,0x54,0x5A,0x41,0x87,0x91,0xD4, -0x15,0x00,0x02,0x80,0xF0,0x15,0x00,0x02,0x70,0xE8,0x6F,0x54,0x5A,0x40,0x84,0x01, -0x80,0xE4,0x15,0x00,0x02,0x70,0xE8,0x6F,0x54,0x5A,0x40,0x84,0x01,0x80,0xE8,0x15, -0x00,0x02,0x70,0xE8,0x6F,0x54,0x5A,0x40,0x84,0x7F,0xB8,0x13,0x00,0x02,0x80,0xEC, -0x15,0x00,0x02,0x70,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x70,0x10,0x49, -0x9C,0x4F,0x04,0x00,0x00,0x00,0x4C,0x28,0x7F,0xBC,0x13,0x00,0x02,0x77,0x12,0x84, -0x01,0x7F,0x58,0x10,0x00,0x02,0x70,0x84,0x01,0x7F,0xBC,0x13,0x00,0x02,0x70,0x84, -0x7F,0x00,0x00,0x00,0x00,0x59,0x70,0xDC,0x6F,0x74,0x59,0x40,0x3C,0x4F,0xE1,0x92, -0x02,0x00,0x50,0x7F,0x3E,0xDC,0x6F,0x74,0x59,0x40,0x84,0x50,0x7F,0x98,0x27,0x00, -0x02,0x70,0xDC,0x6F,0x70,0x59,0x40,0x84,0x50,0x7F,0x94,0x27,0x00,0x02,0x70,0xDC, -0x6F,0x74,0x59,0x40,0x84,0x4F,0xE1,0x92,0x02,0x00,0x50,0x70,0xDC,0x6F,0x70,0x59, -0x40,0x84,0x4F,0x00,0xE1,0x81,0x00,0x50,0x70,0x84,0x01,0x7F,0x88,0x27,0x00,0x02, -0x70,0x2E,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x70,0x10,0x46,0x9C,0x4F, -0x00,0x00,0x00,0x00,0x4C,0x84,0x5A,0x48,0x84,0x74,0x47,0x86,0x7A,0x46,0x7B,0x3E, -0x86,0xE2,0x46,0xE0,0x40,0xD4,0x08,0x40,0x40,0xBA,0x5F,0xFF,0x00,0x40,0x86,0xE2, -0x40,0xE0,0x40,0x84,0x48,0x41,0x90,0x48,0x87,0x51,0xE0,0x41,0x86,0xE2,0x46,0xE0, -0x42,0xB4,0x42,0x41,0xB8,0x5F,0xFF,0x00,0x41,0xD0,0x01,0x41,0x41,0x86,0xE2,0x81, -0xCC,0x1A,0x00,0x00,0xE0,0x41,0xB4,0x41,0x40,0x86,0x40,0x46,0x84,0x47,0x40,0x94, -0x47,0x28,0x40,0x47,0xBD,0x86,0xE2,0x46,0xE0,0x40,0x7B,0x02,0x04,0xC9,0xF4,0x4C, -0x20,0x48,0x20,0x47,0x20,0x46,0x20,0x49,0x08,0x70,0x70,0x70,0x10,0x49,0x9C,0x4F, -0x08,0x00,0x00,0x00,0x4C,0x80,0x64,0x70,0x7B,0x05,0x90,0x64,0x70,0x3C,0x4F,0x00, -0x00,0x04,0x00,0x64,0x5F,0xF6,0x28,0x78,0x43,0x12,0xA0,0x4F,0xE8,0x1C,0x00,0x00, -0x2C,0xCC,0xFC,0x7F,0x24,0xE7,0x00,0x00,0x7B,0x32,0x28,0x78,0x77,0x20,0xA0,0x4F, -0xFE,0x1C,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0x24,0xE7,0x00,0x00,0xA0,0x4F,0x13,0x1D, -0x00,0x00,0x2C,0xCC,0xFC,0x7F,0x24,0xE7,0x00,0x00,0x7B,0x10,0xA0,0x4F,0x15,0x1D, -0x00,0x00,0x2C,0xCC,0xFC,0x7F,0x24,0xE7,0x00,0x00,0xA0,0x4F,0x2A,0x1D,0x00,0x00, -0x2C,0xCC,0xFC,0x7F,0x24,0xE7,0x00,0x00,0xA0,0x74,0x2C,0xCC,0xFC,0x7F,0x24,0xE7, -0x00,0x00,0x3C,0xFE,0x78,0x77,0x10,0xA0,0x4F,0x2C,0x1D,0x00,0x00,0x2C,0xCC,0xFC, -0x7F,0x24,0xE7,0x00,0x00,0x28,0x78,0x4F,0x29,0xA0,0x4F,0x2F,0x1D,0x00,0x00,0x2C, -0xCC,0xFC,0x7F,0x24,0xE7,0x00,0x00,0xDF,0x6F,0x60,0x7B,0x40,0x87,0x40,0xE0,0x40, -0xA0,0x40,0xA0,0x4F,0x08,0x90,0x04,0x00,0x2C,0xCC,0xF8,0x7F,0xA4,0x60,0x00,0x00, -0xA0,0x4F,0x31,0x1D,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0x24,0xE7,0x00,0x00,0xA0,0x5A, -0x2C,0xCC,0xFC,0xAF,0x84,0x04,0x84,0x40,0x59,0x70,0x3C,0x01,0x7F,0xE4,0x2A,0x00, -0x02,0x77,0x07,0x84,0xFF,0x40,0x7B,0x07,0x84,0x59,0x40,0x7B,0x02,0x04,0xC9,0xE8, -0x4C,0x20,0x49,0x08,0x10,0x49,0x9C,0x4F,0x34,0x00,0x00,0x00,0x4C,0x3C,0x4F,0x08, -0x90,0x04,0x00,0xEF,0xFC,0x04,0x00,0x00,0x77,0x16,0xA0,0x4F,0x33,0x1D,0x00,0x00, -0x2C,0xCC,0xFC,0xEF,0xB0,0x04,0x00,0x00,0x24,0x7F,0x6F,0xA4,0x00,0x00,0x87,0x15, -0x7F,0x0A,0x90,0x04,0x00,0x70,0x80,0x7F,0xE8,0x2A,0x00,0x02,0x70,0x84,0xFF,0x68, -0x70,0x7B,0x42,0xA0,0x4F,0x55,0x1D,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xD6,0xC4,0x00, -0x00,0x28,0x40,0x7F,0x08,0x84,0xFE,0x68,0x70,0x7B,0x2A,0xA0,0x4F,0x58,0x1D,0x00, -0x00,0x2C,0xCC,0xFC,0x7F,0xD6,0xC4,0x00,0x00,0x28,0x40,0x7F,0x0C,0x84,0x01,0x7F, -0xE8,0x2A,0x00,0x02,0x70,0x7B,0x0E,0xA0,0x5F,0x60,0x52,0x2C,0xCC,0xFC,0x7F,0xEA, -0xC1,0x00,0x00,0x2C,0x5C,0x7F,0xF6,0xC3,0x00,0x00,0x3C,0x2D,0x40,0x7F,0xB6,0x2C, -0x5C,0x7F,0x76,0xC4,0x00,0x00,0x28,0x40,0x7F,0x14,0xA0,0x5F,0xF0,0x21,0x2C,0xCC, -0xFC,0x7F,0xEA,0xC1,0x00,0x00,0x24,0x7F,0x6F,0xA4,0x00,0x00,0xE0,0x6C,0xA0,0x28, -0x2C,0xCC,0xF8,0x7F,0x9A,0xC3,0x00,0x00,0x83,0x7F,0xF0,0x2A,0x00,0x02,0x70,0xA0, -0x4F,0x5B,0x1D,0x00,0x00,0xE0,0x6C,0x2C,0xCC,0xF8,0xEF,0xB0,0x04,0x00,0x00,0xA0, -0x4F,0xF0,0x2A,0x00,0x02,0xE0,0x6C,0xA0,0x68,0x2C,0xCC,0xF4,0xAF,0x43,0xFE,0x28, -0x40,0x43,0x16,0xA0,0x4F,0x00,0x82,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xEA,0xC1,0x00, -0x00,0x24,0x7F,0x6F,0xA4,0x00,0x00,0x87,0x7F,0xF0,0x2A,0x00,0x02,0xE0,0x64,0x70, -0xA0,0x4F,0x6A,0x1D,0x00,0x00,0x2C,0xCC,0xFC,0xEF,0xB0,0x04,0x00,0x00,0x2C,0x5C, -0x7F,0x76,0xC4,0x00,0x00,0x28,0x40,0x7F,0x23,0x80,0x59,0x70,0x7B,0x17,0xA0,0x59, -0xA0,0x64,0xE0,0x6C,0x2C,0xCC,0xF4,0xAF,0x62,0x00,0x28,0x40,0x77,0x04,0x7B,0x51, -0x90,0x59,0x70,0x3C,0x64,0x59,0x4B,0xE8,0x7B,0x47,0x7B,0x3A,0x2C,0x5C,0x7F,0xA0, -0xCE,0x00,0x00,0x84,0x40,0x59,0x70,0x3C,0x64,0x40,0x43,0x16,0xA0,0x59,0xA0,0x64, -0xE0,0x6C,0x2C,0xCC,0xF4,0xAF,0x34,0x00,0x28,0x40,0x77,0x04,0x7B,0x23,0x7B,0x16, -0xA0,0x4F,0x6C,0x1D,0x00,0x00,0xA0,0x59,0xE0,0x6C,0x2C,0xCC,0xF4,0xEF,0xB0,0x04, -0x00,0x00,0x7B,0x0D,0x2C,0x5C,0x7F,0x76,0xC4,0x00,0x00,0x28,0x40,0x7F,0xBF,0x04, -0xC9,0xE8,0x4C,0x20,0x49,0x08,0x10,0x49,0x9C,0x4F,0x0C,0x00,0x00,0x00,0x4C,0xD0, -0x03,0x74,0x40,0x9C,0x4F,0xF4,0x2A,0x00,0x02,0x40,0xE8,0x09,0x5A,0x41,0x9C,0x41, -0x40,0x84,0x40,0x59,0x70,0xA0,0x4F,0x94,0x1D,0x00,0x00,0xA0,0x5A,0xD0,0x02,0x5A, -0x40,0xA0,0x80,0xF4,0x2A,0x00,0x02,0x2C,0xCC,0xF4,0xEF,0xB0,0x04,0x00,0x00,0xD0, -0x02,0x5A,0x40,0xA0,0x80,0xF4,0x2A,0x00,0x02,0x2C,0xCC,0xFC,0x7F,0x6C,0xD7,0x00, -0x00,0x84,0x40,0x68,0x70,0xA0,0x4F,0xAB,0x1D,0x00,0x00,0xA0,0x68,0xA0,0x59,0x2C, -0xCC,0xF4,0xEF,0xB0,0x04,0x00,0x00,0xDC,0x74,0x5A,0x40,0xD0,0x02,0x40,0x40,0x28, -0x80,0xF4,0x2A,0x00,0x02,0x4F,0x6C,0xA0,0x68,0xA0,0x78,0xDC,0x01,0x5A,0x40,0xA0, -0x40,0x2C,0xCC,0xF4,0xAF,0x1B,0xFD,0x84,0x40,0x64,0x70,0xDC,0x74,0x5A,0x40,0xD0, -0x02,0x40,0x40,0x3C,0x80,0xF4,0x2A,0x00,0x02,0x64,0x7F,0x35,0xA0,0x4F,0xB7,0x1D, -0x00,0x00,0x2C,0xCC,0xFC,0xEF,0xB0,0x04,0x00,0x00,0xA0,0x4F,0xCD,0x1D,0x00,0x00, -0xA0,0x64,0xD0,0x01,0x74,0x40,0x9C,0x5A,0x40,0xD0,0x02,0x40,0x40,0xA0,0x80,0xF4, -0x2A,0x00,0x02,0x2C,0xCC,0xF4,0xEF,0xB0,0x04,0x00,0x00,0x80,0x40,0x7B,0x27,0xA0, -0x4F,0xF4,0x1D,0x00,0x00,0xA0,0x64,0x2C,0xCC,0xF8,0xEF,0xB0,0x04,0x00,0x00,0x7B, -0x10,0xA0,0x4F,0x06,0x1E,0x00,0x00,0x2C,0xCC,0xFC,0xEF,0xB0,0x04,0x00,0x00,0x84, -0x01,0x40,0x7B,0x02,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x10,0x49,0x9C,0x4F, -0x34,0x00,0x00,0x00,0x4C,0x3C,0x4F,0x08,0x90,0x04,0x00,0xEF,0xFC,0x04,0x00,0x00, -0x77,0x16,0xA0,0x4F,0x16,0x1E,0x00,0x00,0x2C,0xCC,0xFC,0xEF,0xB0,0x04,0x00,0x00, -0x24,0x7F,0x38,0xA6,0x00,0x00,0x87,0x15,0x7F,0x0A,0x90,0x04,0x00,0x70,0xA0,0x4F, -0x38,0x1E,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xD6,0xC4,0x00,0x00,0x84,0x40,0x7F,0xE8, -0x2A,0x00,0x02,0x70,0x2C,0x5C,0x7F,0xDC,0xC5,0x00,0x00,0x84,0x40,0x59,0x70,0x2C, -0x5C,0x7F,0x76,0xC4,0x00,0x00,0x28,0x40,0x7F,0x10,0xA0,0x5F,0xF0,0x21,0x2C,0xCC, -0xFC,0x7F,0xEA,0xC1,0x00,0x00,0x7B,0x62,0xE0,0x6C,0xA0,0x28,0x2C,0xCC,0xF8,0x7F, -0x9A,0xC3,0x00,0x00,0xA0,0x59,0x2C,0xCC,0xFC,0x7F,0x6C,0xD7,0x00,0x00,0x84,0x40, -0x68,0x70,0xA0,0x4F,0x3B,0x1E,0x00,0x00,0xE0,0x6C,0xA0,0x59,0xA0,0x68,0x2C,0xCC, -0xF0,0xEF,0xB0,0x04,0x00,0x00,0xA0,0x68,0xE0,0x6C,0xA0,0x00,0x2C,0xCC,0xF4,0xAF, -0x00,0xFC,0x84,0x40,0x64,0x70,0x43,0x12,0xA0,0x4F,0x10,0x82,0x00,0x00,0x2C,0xCC, -0xFC,0x7F,0xEA,0xC1,0x00,0x00,0x7B,0x12,0xA0,0x4F,0x53,0x1E,0x00,0x00,0xA0,0x64, -0x2C,0xCC,0xF8,0xEF,0xB0,0x04,0x00,0x00,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70, -0x70,0x70,0x10,0x49,0x9C,0x4F,0x08,0x00,0x00,0x00,0x4C,0x3C,0x4F,0x08,0x90,0x04, -0x00,0xEF,0xFC,0x04,0x00,0x00,0x77,0x16,0xA0,0x4F,0x64,0x1E,0x00,0x00,0x2C,0xCC, -0xFC,0xEF,0xB0,0x04,0x00,0x00,0x24,0x7F,0x16,0xA7,0x00,0x00,0x87,0x15,0x7F,0x0A, -0x90,0x04,0x00,0x70,0xA0,0x4F,0x85,0x1E,0x00,0x00,0x2C,0xCC,0xFC,0xEF,0xB0,0x04, -0x00,0x00,0xA0,0x4F,0xAB,0x1E,0x00,0x00,0x2C,0xCC,0xFC,0xEF,0xB0,0x04,0x00,0x00, -0x3B,0x7F,0x09,0x90,0x04,0x00,0x01,0x7F,0x12,0x84,0xEF,0xFC,0x04,0x00,0x00,0x40, -0x87,0x7F,0x0B,0x90,0x04,0x00,0xC0,0x03,0x70,0x84,0xEF,0xFC,0x04,0x00,0x00,0x40, -0x3B,0xC0,0x01,0x01,0x7F,0x5F,0x84,0xEF,0xFC,0x04,0x00,0x00,0x40,0x87,0xC0,0x03, -0x59,0x70,0x3F,0x01,0x59,0x77,0x12,0xA0,0x4F,0xD6,0x1E,0x00,0x00,0x2C,0xCC,0xFC, -0xEF,0xB0,0x04,0x00,0x00,0x7B,0x41,0x2B,0x59,0x77,0x07,0x84,0x01,0x40,0x7B,0x04, -0x80,0x40,0x84,0x40,0x64,0x70,0x3F,0x6F,0x7F,0x59,0x77,0x07,0x84,0x01,0x40,0x7B, -0x04,0x80,0x40,0xB0,0x64,0x40,0x7F,0x09,0x2C,0x5C,0xAF,0x28,0x00,0x7B,0x16,0x87, -0x59,0xE0,0x40,0xA0,0x40,0xA0,0x4F,0x08,0x90,0x04,0x00,0x2C,0xCC,0xF8,0x7F,0xA4, -0x60,0x00,0x00,0x7A,0x7D,0xFF,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x70, -0x10,0x49,0x9C,0x4F,0x04,0x00,0x00,0x00,0x4C,0x87,0x6F,0x65,0x7F,0x0A,0x90,0x04, -0x00,0x70,0x80,0x59,0x70,0x7B,0x05,0x90,0x59,0x70,0x3C,0x4F,0x50,0xC3,0x00,0x00, -0x59,0x4B,0xF6,0x87,0x6F,0x75,0x7F,0x0A,0x90,0x04,0x00,0x70,0x04,0xC9,0xE8,0x4C, -0x20,0x49,0x08,0x70,0x10,0x49,0x9C,0x4F,0x10,0x00,0x00,0x00,0x4C,0x80,0x7F,0xC0, -0x2B,0x00,0x02,0x70,0x80,0x68,0x70,0x84,0x01,0x7F,0xC0,0x2B,0x00,0x02,0x70,0x80, -0x7F,0xE4,0x2A,0x00,0x02,0x70,0x80,0x7F,0xC4,0x2B,0x00,0x02,0x70,0x84,0xFF,0x7F, -0xC8,0x2B,0x00,0x02,0x70,0x80,0x7F,0xCC,0x2B,0x00,0x02,0x70,0xA0,0x4F,0xD0,0x2B, -0x00,0x02,0xA0,0x06,0x2C,0xCC,0xF8,0xAF,0xF8,0x00,0xA0,0x4F,0xD8,0x2B,0x00,0x02, -0xA0,0x01,0x2C,0xCC,0xF8,0xAF,0xEA,0x00,0xA0,0x4F,0xE0,0x2B,0x00,0x02,0xA0,0x02, -0x2C,0xCC,0xF8,0xAF,0xDC,0x00,0xA0,0x4F,0xE8,0x2B,0x00,0x02,0xA0,0x07,0x2C,0xCC, -0xF8,0xAF,0xCE,0x00,0x7B,0x0A,0xE0,0x64,0x2C,0xCC,0xFC,0xAF,0x04,0x01,0x3C,0x03, -0x7F,0xC0,0x2B,0x00,0x02,0x77,0xF1,0x84,0x5A,0x6C,0x70,0x24,0x7F,0x6F,0xA8,0x00, -0x00,0x84,0x01,0x7F,0xF0,0x2B,0x00,0x02,0x70,0x80,0x7F,0xCC,0x2B,0x00,0x02,0x70, -0x7B,0x76,0xA0,0x5A,0x2C,0xCC,0xFC,0xAF,0xD8,0x00,0x84,0x40,0x64,0x70,0xDC,0x64, -0x68,0x40,0x84,0x40,0x68,0x70,0x28,0x64,0x7F,0x0D,0xDC,0x64,0x5A,0x40,0xBC,0x01, -0x40,0x84,0x40,0x6C,0x70,0x80,0x59,0x70,0x7B,0x41,0xE8,0x6F,0x54,0x59,0x40,0x3C, -0x5A,0x80,0xD4,0x15,0x00,0x02,0x4B,0x30,0xE8,0x6F,0x54,0x59,0x40,0x3C,0x6C,0x80, -0xD4,0x15,0x00,0x02,0x43,0x22,0x28,0x7F,0xE8,0x2A,0x00,0x02,0x77,0x1A,0xE8,0x6F, -0x54,0x59,0x40,0x80,0x80,0xE4,0x15,0x00,0x02,0x70,0xE8,0x6F,0x54,0x59,0x40,0x80, -0x80,0xE8,0x15,0x00,0x02,0x70,0x90,0x59,0x70,0x3C,0x17,0x59,0x4B,0xBE,0xDC,0x64, -0x5A,0x40,0x84,0x40,0x5A,0x70,0x3C,0x01,0x7F,0xF0,0x2B,0x00,0x02,0x7F,0x85,0x28, -0x7F,0xE4,0x2A,0x00,0x02,0x77,0x0B,0x28,0x7F,0xC4,0x2B,0x00,0x02,0x7E,0x64,0xFF, -0x84,0x68,0x40,0x7B,0x02,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x10,0x49,0x9C,0x4F, -0x00,0x00,0x00,0x00,0x4C,0x87,0x05,0xDA,0x00,0x70,0xDC,0x01,0x5A,0x40,0x87,0x77, -0x50,0x70,0xDC,0x02,0x5A,0x40,0x87,0x5F,0xC0,0x00,0x50,0x70,0xDC,0x03,0x5A,0x40, -0x83,0x50,0x70,0xDC,0x04,0x5A,0x40,0x83,0x50,0x70,0xDC,0x05,0x5A,0x40,0x87,0x01, -0x50,0x70,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x70,0x10,0x49,0x9C,0x4F, -0x10,0x00,0x00,0x00,0x4C,0xA0,0x4F,0x08,0x90,0x04,0x00,0x2C,0xCC,0xFC,0xAF,0xA9, -0x03,0x28,0x40,0x7F,0x10,0xA0,0x4F,0xD0,0x81,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xEA, -0xC1,0x00,0x00,0xA0,0x4F,0x08,0x90,0x04,0x00,0x2C,0xCC,0xFC,0x7F,0xE0,0x59,0x00, -0x00,0x87,0x40,0x7F,0xF4,0x2B,0x00,0x02,0x70,0xFB,0x5F,0xFF,0x00,0x7F,0xF4,0x2B, -0x00,0x02,0x40,0x84,0x40,0x64,0x70,0x7B,0x44,0xA0,0x4F,0x08,0x90,0x04,0x00,0x2C, -0xCC,0xFC,0xAF,0x65,0x03,0x28,0x40,0x7F,0x10,0xA0,0x4F,0xD0,0x81,0x00,0x00,0x2C, -0xCC,0xFC,0x7F,0xEA,0xC1,0x00,0x00,0xA0,0x4F,0x08,0x90,0x04,0x00,0x2C,0xCC,0xFC, -0x7F,0xE0,0x59,0x00,0x00,0x87,0x40,0x7F,0xF4,0x2B,0x00,0x02,0x70,0xFB,0x5F,0xFF, -0x00,0x7F,0xF4,0x2B,0x00,0x02,0x40,0x84,0x40,0x64,0x70,0x3C,0x5F,0x81,0x00,0x64, -0x7F,0x07,0x3C,0x05,0x64,0x77,0xB4,0xA0,0x07,0xA0,0x4F,0xF5,0x2B,0x00,0x02,0xA0, -0x4F,0x08,0x90,0x04,0x00,0x2C,0xCC,0xF4,0x7F,0x2E,0xE6,0x00,0x00,0xA0,0x4F,0xF4, -0x2B,0x00,0x02,0xA0,0x08,0xA0,0x00,0x2C,0xCC,0xF4,0xAF,0x15,0xF8,0x28,0x40,0x7F, -0x37,0x90,0x7F,0xCC,0x2B,0x00,0x02,0x70,0x3C,0x05,0x7F,0xCC,0x2B,0x00,0x02,0x4F, -0x1F,0x84,0x01,0x7F,0xE4,0x2A,0x00,0x02,0x70,0x80,0x7F,0xF0,0x2B,0x00,0x02,0x70, -0xA0,0x4F,0x20,0x82,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xEA,0xC1,0x00,0x00,0x80,0x40, -0x24,0x7F,0xE4,0xAA,0x00,0x00,0x3C,0x5F,0x81,0x00,0x64,0x7F,0x08,0x24,0x7F,0xDB, -0xAA,0x00,0x00,0xFB,0x5F,0xFF,0x00,0x7F,0xF5,0x2B,0x00,0x02,0x40,0x84,0x40,0x59, -0x70,0xFB,0x3F,0x7F,0xF6,0x2B,0x00,0x02,0x40,0xD0,0x08,0x40,0x40,0xB0,0x40,0x59, -0x70,0xFB,0x5F,0xFF,0x00,0x7F,0xF8,0x2B,0x00,0x02,0x40,0x84,0x40,0x7F,0xFC,0x2B, -0x00,0x02,0x70,0xA0,0x7F,0xC8,0x2B,0x00,0x02,0x2C,0xCC,0xFC,0xAF,0x57,0x02,0x84, -0x40,0x6C,0x70,0x3C,0x7F,0xFC,0x2B,0x00,0x02,0x6C,0x7F,0x08,0x24,0x7F,0xD9,0xAA, -0x00,0x00,0xA0,0x59,0xA0,0x5A,0xA0,0x4F,0x08,0x90,0x04,0x00,0x2C,0xCC,0xF4,0x7F, -0x2E,0xE6,0x00,0x00,0xA0,0x02,0xE0,0x68,0xA0,0x4F,0x08,0x90,0x04,0x00,0x2C,0xCC, -0xF4,0x7F,0x2E,0xE6,0x00,0x00,0xA0,0x5A,0xA0,0x59,0xA0,0x00,0x2C,0xCC,0xF4,0xAF, -0x50,0xF7,0x86,0x40,0x6A,0x70,0xE0,0x68,0xA0,0x02,0x86,0xE2,0x6A,0xE0,0x40,0xA0, -0x40,0x2C,0xCC,0xF4,0xAF,0x3B,0xF7,0x28,0x40,0x7F,0x45,0xA0,0x5F,0x30,0x52,0x2C, -0xCC,0xFC,0x7F,0x50,0xC2,0x00,0x00,0xA0,0x02,0x2C,0xCC,0xFC,0xAF,0xB7,0x01,0x90, -0x7F,0xCC,0x2B,0x00,0x02,0x70,0x3C,0x05,0x7F,0xCC,0x2B,0x00,0x02,0x4F,0x1F,0xA0, -0x4F,0x20,0x82,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xEA,0xC1,0x00,0x00,0x84,0x01,0x7F, -0xE4,0x2A,0x00,0x02,0x70,0x80,0x7F,0xF0,0x2B,0x00,0x02,0x70,0x7B,0x2D,0xA0,0x4F, -0xD8,0x1E,0x00,0x00,0x2C,0xCC,0xFC,0xEF,0xB0,0x04,0x00,0x00,0x84,0x7F,0xFC,0x2B, -0x00,0x02,0x7F,0xC8,0x2B,0x00,0x02,0x70,0x2C,0x5C,0xAF,0x40,0x01,0x80,0x7F,0xF0, -0x2B,0x00,0x02,0x70,0x84,0x59,0x40,0x7B,0x0D,0x7B,0x07,0x2C,0x5C,0xAF,0x11,0x00, -0x80,0x40,0x7B,0x02,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x10,0x49,0x9C,0x4F, -0x08,0x00,0x00,0x00,0x4C,0xFB,0x5F,0xFF,0x00,0x7F,0xF5,0x2B,0x00,0x02,0x40,0x84, -0x40,0x64,0x70,0x84,0x64,0x40,0x7B,0x73,0xFB,0x5F,0xFF,0x00,0x7F,0xF8,0x2B,0x00, -0x02,0x40,0x84,0x40,0x59,0x70,0x3C,0x7F,0xC8,0x2B,0x00,0x02,0x59,0x77,0x09,0x2C, -0x5C,0xAF,0xE9,0x00,0x7B,0x0A,0xA0,0x03,0x2C,0xCC,0xFC,0xAF,0x08,0x01,0x7B,0x64, -0x3C,0x03,0x7F,0xC0,0x2B,0x00,0x02,0x77,0x13,0x80,0x7F,0xF0,0x2B,0x00,0x02,0x70, -0x84,0x01,0x7F,0xC4,0x2B,0x00,0x02,0x70,0x7B,0x16,0x84,0x02,0x7F,0xC0,0x2B,0x00, -0x02,0x70,0xA0,0x4F,0xE8,0x2B,0x00,0x02,0x2C,0xCC,0xFC,0xAF,0x44,0x00,0x7B,0x34, -0x84,0x03,0x7F,0xC0,0x2B,0x00,0x02,0x70,0x2C,0x5C,0xAF,0xA0,0x00,0x7B,0x25,0x84, -0x03,0x7F,0xC0,0x2B,0x00,0x02,0x70,0x7B,0x1B,0xFC,0x01,0x40,0x40,0x4B,0x15,0x3C, -0x06,0x40,0x47,0x10,0xC0,0x02,0x40,0x40,0x28,0x40,0x4B,0x08,0x24,0x90,0xCC,0x1C, -0x00,0x00,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x70,0x10,0x49,0x9C,0x4F, -0x08,0x00,0x00,0x00,0x4C,0xA0,0x5A,0xA0,0x06,0xA0,0x00,0x2C,0xCC,0xF4,0xAF,0xF1, -0xF5,0x86,0x40,0x59,0x70,0xDC,0x06,0x5A,0x40,0xFB,0x5F,0xFF,0x00,0x61,0x41,0x87, -0x41,0x50,0x70,0xDC,0x07,0x5A,0x40,0x86,0xE2,0x59,0xE0,0x41,0xB8,0x4F,0x00,0xFF, -0x00,0x00,0x41,0xD4,0x08,0x41,0x41,0x87,0x41,0x50,0x70,0x80,0x64,0x70,0x7B,0x1C, -0x7B,0x02,0x3B,0x7F,0x09,0x90,0x04,0x00,0x04,0x7F,0xF9,0xDC,0x64,0x5A,0x40,0x87, -0x50,0x7F,0x0B,0x90,0x04,0x00,0x70,0x90,0x64,0x70,0x3C,0x08,0x64,0x4B,0xE3,0x04, -0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00, -0x4C,0x87,0x7F,0xCB,0x2B,0x00,0x02,0x7F,0xDB,0x2B,0x00,0x02,0x70,0xA0,0x4F,0xD8, -0x2B,0x00,0x02,0x2C,0xCC,0xFC,0xAF,0x79,0xFF,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08, -0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x87,0x73,0x7F,0xE2,0x2B,0x00,0x02, -0x70,0x87,0x7F,0xCB,0x2B,0x00,0x02,0x7F,0xE3,0x2B,0x00,0x02,0x70,0xA0,0x4F,0xE0, -0x2B,0x00,0x02,0x2C,0xCC,0xFC,0xAF,0x49,0xFF,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08, -0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x3C,0x5F,0xFF,0x00,0x5A,0x77,0x06, -0x80,0x40,0x7B,0x08,0xDC,0x01,0x5A,0x40,0x7B,0x02,0x04,0xC9,0xE8,0x4C,0x20,0x49, -0x08,0x70,0x70,0x70,0x10,0x49,0x9C,0x4F,0x04,0x00,0x00,0x00,0x4C,0x84,0x4F,0x80, -0x8D,0x5B,0x00,0x59,0x70,0x7B,0x0C,0x94,0x59,0x70,0x77,0x07,0x84,0x01,0x40,0x7B, -0x0F,0xDC,0x01,0x5A,0x40,0x3B,0x50,0x01,0x7F,0xEF,0x80,0x40,0x7B,0x02,0x04,0xC9, -0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x70,0x10,0x49,0x9C,0x4F,0x04,0x00,0x00,0x00, -0x4C,0x84,0x01,0x7F,0xA4,0x27,0x00,0x02,0x70,0x2C,0x5C,0x7F,0xDC,0xC5,0x00,0x00, -0x84,0x40,0x7F,0xA8,0x27,0x00,0x02,0x70,0x2C,0x5C,0x7F,0x76,0xC4,0x00,0x00,0x28, -0x40,0x7F,0x0C,0x84,0x01,0x7F,0xAC,0x27,0x00,0x02,0x70,0x7B,0x45,0x84,0x7F,0xB8, -0x13,0x00,0x02,0x59,0x70,0x2C,0x5C,0x7F,0xDC,0xC5,0x00,0x00,0x84,0x40,0x7F,0xAC, -0x27,0x00,0x02,0x70,0x84,0x59,0x7F,0xB8,0x13,0x00,0x02,0x70,0x3C,0x7F,0xA8,0x27, -0x00,0x02,0x7F,0xAC,0x27,0x00,0x02,0x5B,0x19,0xFC,0x7F,0xA8,0x27,0x00,0x02,0x7F, -0xAC,0x27,0x00,0x02,0x40,0x9C,0x01,0x40,0x84,0x40,0x7F,0xAC,0x27,0x00,0x02,0x70, -0x2C,0x5C,0xAF,0x64,0x05,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x10,0x49, -0x9C,0x4F,0x04,0x00,0x00,0x00,0x4C,0x84,0x05,0x7F,0xA4,0x27,0x00,0x02,0x70,0x2C, -0x5C,0x7F,0xDC,0xC5,0x00,0x00,0x84,0x40,0x7F,0xA8,0x27,0x00,0x02,0x70,0x2C,0x5C, -0x7F,0x76,0xC4,0x00,0x00,0x28,0x40,0x7F,0x0C,0x84,0x10,0x7F,0xAC,0x27,0x00,0x02, -0x70,0x7B,0x45,0x84,0x7F,0xB8,0x13,0x00,0x02,0x59,0x70,0x2C,0x5C,0x7F,0xDC,0xC5, -0x00,0x00,0x84,0x40,0x7F,0xAC,0x27,0x00,0x02,0x70,0x84,0x59,0x7F,0xB8,0x13,0x00, -0x02,0x70,0x3C,0x7F,0xA8,0x27,0x00,0x02,0x7F,0xAC,0x27,0x00,0x02,0x5B,0x19,0xFC, -0x7F,0xA8,0x27,0x00,0x02,0x7F,0xAC,0x27,0x00,0x02,0x40,0x9C,0x01,0x40,0x84,0x40, -0x7F,0xAC,0x27,0x00,0x02,0x70,0x7B,0x09,0x90,0x7F,0xAC,0x27,0x00,0x02,0x70,0xE4, -0xE0,0x10,0x7F,0xAC,0x27,0x00,0x02,0x40,0x77,0xF0,0x2C,0x5C,0xAF,0xCA,0x04,0x04, -0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x10,0x49,0x9C,0x4F,0x04,0x00,0x00,0x00, -0x4C,0x84,0x02,0x7F,0xA4,0x27,0x00,0x02,0x70,0x2C,0x5C,0x7F,0xDC,0xC5,0x00,0x00, -0x84,0x40,0x7F,0xA8,0x27,0x00,0x02,0x70,0x2C,0x5C,0x7F,0x76,0xC4,0x00,0x00,0x28, -0x40,0x7F,0x0C,0x84,0x01,0x7F,0xAC,0x27,0x00,0x02,0x70,0x7B,0x49,0x84,0x7F,0xB8, -0x13,0x00,0x02,0x59,0x70,0x2C,0x5C,0x7F,0xDC,0xC5,0x00,0x00,0x84,0x40,0x7F,0xAC, -0x27,0x00,0x02,0x70,0x84,0x59,0x7F,0xB8,0x13,0x00,0x02,0x70,0x3C,0x7F,0xA8,0x27, -0x00,0x02,0x7F,0xAC,0x27,0x00,0x02,0x5B,0x1D,0xFC,0x7F,0xA8,0x27,0x00,0x02,0x7F, -0xAC,0x27,0x00,0x02,0x40,0xAC,0xE0,0x02,0x40,0x9C,0x01,0x40,0x84,0x40,0x7F,0xAC, -0x27,0x00,0x02,0x70,0xD0,0x01,0x7F,0xAC,0x27,0x00,0x02,0x40,0x84,0x40,0x7F,0xAC, -0x27,0x00,0x02,0x70,0x2C,0x5C,0xAF,0x30,0x04,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08, -0x70,0x70,0x10,0x49,0x9C,0x4F,0x04,0x00,0x00,0x00,0x4C,0x84,0x03,0x7F,0xA4,0x27, -0x00,0x02,0x70,0x2C,0x5C,0x7F,0xDC,0xC5,0x00,0x00,0x84,0x40,0x7F,0xA8,0x27,0x00, -0x02,0x70,0x2C,0x5C,0x7F,0x76,0xC4,0x00,0x00,0x28,0x40,0x7F,0x0C,0x84,0x01,0x7F, -0xAC,0x27,0x00,0x02,0x70,0x7B,0x49,0x84,0x7F,0xB8,0x13,0x00,0x02,0x59,0x70,0x2C, -0x5C,0x7F,0xDC,0xC5,0x00,0x00,0x84,0x40,0x7F,0xAC,0x27,0x00,0x02,0x70,0x84,0x59, -0x7F,0xB8,0x13,0x00,0x02,0x70,0x3C,0x7F,0xA8,0x27,0x00,0x02,0x7F,0xAC,0x27,0x00, -0x02,0x5B,0x1D,0xFC,0x7F,0xA8,0x27,0x00,0x02,0x7F,0xAC,0x27,0x00,0x02,0x40,0xAC, -0xE0,0x04,0x40,0x9C,0x01,0x40,0x84,0x40,0x7F,0xAC,0x27,0x00,0x02,0x70,0xD0,0x02, -0x7F,0xAC,0x27,0x00,0x02,0x40,0x84,0x40,0x7F,0xAC,0x27,0x00,0x02,0x70,0x2C,0x5C, -0xAF,0x96,0x03,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x10,0x49,0x9C,0x4F, -0x04,0x00,0x00,0x00,0x4C,0x84,0x04,0x7F,0xA4,0x27,0x00,0x02,0x70,0x2C,0x5C,0x7F, -0xDC,0xC5,0x00,0x00,0x84,0x40,0x7F,0xA8,0x27,0x00,0x02,0x70,0x2C,0x5C,0x7F,0x76, -0xC4,0x00,0x00,0x28,0x40,0x7F,0x0C,0x84,0x01,0x7F,0xAC,0x27,0x00,0x02,0x70,0x7B, -0x49,0x84,0x7F,0xB8,0x13,0x00,0x02,0x59,0x70,0x2C,0x5C,0x7F,0xDC,0xC5,0x00,0x00, -0x84,0x40,0x7F,0xAC,0x27,0x00,0x02,0x70,0x84,0x59,0x7F,0xB8,0x13,0x00,0x02,0x70, -0x3C,0x7F,0xA8,0x27,0x00,0x02,0x7F,0xAC,0x27,0x00,0x02,0x5B,0x1D,0xFC,0x7F,0xA8, -0x27,0x00,0x02,0x7F,0xAC,0x27,0x00,0x02,0x40,0xAC,0xE0,0x08,0x40,0x9C,0x01,0x40, -0x84,0x40,0x7F,0xAC,0x27,0x00,0x02,0x70,0xD0,0x03,0x7F,0xAC,0x27,0x00,0x02,0x40, -0x84,0x40,0x7F,0xAC,0x27,0x00,0x02,0x70,0x2C,0x5C,0xAF,0xFC,0x02,0x04,0xC9,0xE8, -0x4C,0x20,0x49,0x08,0x70,0x70,0x10,0x49,0x9C,0x4F,0x04,0x00,0x00,0x00,0x4C,0x84, -0x09,0x7F,0xA4,0x27,0x00,0x02,0x70,0xA0,0x4F,0x3C,0x1F,0x00,0x00,0x2C,0xCC,0xFC, -0x7F,0xD6,0xC4,0x00,0x00,0x84,0x40,0x7F,0xB8,0x27,0x00,0x02,0x70,0x2C,0x5C,0x7F, -0xDC,0xC5,0x00,0x00,0x84,0x40,0x7F,0xA8,0x27,0x00,0x02,0x70,0x84,0x7F,0xB8,0x13, -0x00,0x02,0x59,0x70,0x2C,0x5C,0x7F,0xDC,0xC5,0x00,0x00,0x84,0x40,0x7F,0xAC,0x27, -0x00,0x02,0x70,0x84,0x59,0x7F,0xB8,0x13,0x00,0x02,0x70,0x3C,0x7F,0xA8,0x27,0x00, -0x02,0x7F,0xAC,0x27,0x00,0x02,0x5B,0x19,0xFC,0x7F,0xA8,0x27,0x00,0x02,0x7F,0xAC, -0x27,0x00,0x02,0x40,0x9C,0x01,0x40,0x84,0x40,0x7F,0xAC,0x27,0x00,0x02,0x70,0x2C, -0x5C,0x7F,0x76,0xC4,0x00,0x00,0x28,0x40,0x7F,0x0E,0xA0,0x5F,0xD0,0x20,0x2C,0xCC, -0xFC,0x7F,0xEA,0xC1,0x00,0x00,0x2C,0x5C,0xAF,0x5E,0x02,0x04,0xC9,0xE8,0x4C,0x20, -0x49,0x08,0x70,0x70,0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x84,0x06,0x7F, -0xA4,0x27,0x00,0x02,0x70,0xA0,0x4F,0x3F,0x1F,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xD6, -0xC4,0x00,0x00,0x84,0x40,0x7F,0xB8,0x27,0x00,0x02,0x70,0x2C,0x5C,0x7F,0xDC,0xC5, -0x00,0x00,0x84,0x40,0x7F,0xA8,0x27,0x00,0x02,0x70,0x2C,0x5C,0x7F,0x76,0xC4,0x00, -0x00,0x28,0x40,0x7F,0x0E,0xA0,0x5F,0xD0,0x20,0x2C,0xCC,0xFC,0x7F,0xEA,0xC1,0x00, -0x00,0x2C,0x5C,0xAF,0x03,0x02,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x70, -0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x84,0x07,0x7F,0xA4,0x27,0x00,0x02, -0x70,0xA0,0x4F,0x42,0x1F,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xD6,0xC4,0x00,0x00,0x84, -0x40,0x7F,0xB8,0x27,0x00,0x02,0x70,0x2C,0x5C,0x7F,0xDC,0xC5,0x00,0x00,0x84,0x40, -0x7F,0xA8,0x27,0x00,0x02,0x70,0x80,0x7F,0xAC,0x27,0x00,0x02,0x70,0x2C,0x5C,0x7F, -0x76,0xC4,0x00,0x00,0x28,0x40,0x7F,0x0E,0xA0,0x5F,0xD0,0x20,0x2C,0xCC,0xFC,0x7F, -0xEA,0xC1,0x00,0x00,0x2C,0x5C,0xAF,0xA0,0x01,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08, -0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x84,0x08,0x7F,0xA4,0x27,0x00,0x02, -0x70,0xA0,0x4F,0x45,0x1F,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xD6,0xC4,0x00,0x00,0x84, -0x40,0x7F,0xB8,0x27,0x00,0x02,0x70,0x2C,0x5C,0x7F,0xDC,0xC5,0x00,0x00,0x84,0x40, -0x7F,0xA8,0x27,0x00,0x02,0x70,0x80,0x7F,0xAC,0x27,0x00,0x02,0x70,0x2C,0x5C,0x7F, -0x76,0xC4,0x00,0x00,0x28,0x40,0x7F,0x0E,0xA0,0x5F,0xD0,0x20,0x2C,0xCC,0xFC,0x7F, -0xEA,0xC1,0x00,0x00,0x2C,0x5C,0xAF,0x40,0x01,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08, -0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x2C,0x5C,0xAF,0x2B,0x01,0x04,0xC9, -0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x70,0x10,0x48,0x9C,0x4F,0x10,0x00,0x00,0x00, -0x4C,0xA0,0x4F,0x48,0x1F,0x00,0x00,0xA0,0x5A,0x2C,0xCC,0xF8,0xEF,0xB0,0x04,0x00, -0x00,0x28,0x40,0x43,0x0C,0xA0,0x05,0x2C,0xCC,0xFC,0x7F,0x62,0x97,0x00,0x00,0x80, -0x48,0x24,0x7F,0x40,0xB2,0x00,0x00,0x84,0x5A,0x40,0x90,0x5A,0x70,0xA0,0x40,0x2C, -0xCC,0xFC,0x7F,0x4E,0xDA,0x00,0x00,0x04,0x59,0x41,0x9C,0x48,0x41,0x87,0x40,0x51, -0x70,0xA0,0x4F,0x4E,0x1F,0x00,0x00,0x04,0x59,0x40,0x9C,0x48,0x40,0x87,0x50,0xE0, -0x40,0xA0,0x40,0x2C,0xCC,0xF8,0xEF,0xB0,0x04,0x00,0x00,0x28,0x40,0x43,0x0C,0xA0, -0x05,0x2C,0xCC,0xFC,0x7F,0x62,0x97,0x00,0x00,0x7B,0x3C,0xA0,0x4F,0x53,0x1F,0x00, -0x00,0x2C,0xCC,0xFC,0xEF,0xB0,0x04,0x00,0x00,0x28,0x40,0x43,0x0C,0xA0,0x05,0x2C, -0xCC,0xFC,0x7F,0x62,0x97,0x00,0x00,0xA0,0x4F,0x55,0x1F,0x00,0x00,0x2C,0xCC,0xFC, -0xEF,0xB0,0x04,0x00,0x00,0x28,0x40,0x43,0x0C,0xA0,0x05,0x2C,0xCC,0xFC,0x7F,0x62, -0x97,0x00,0x00,0x7B,0x1B,0xFC,0x01,0x48,0x40,0x4B,0x15,0x3C,0x0E,0x40,0x47,0x10, -0xC0,0x02,0x40,0x40,0x28,0x40,0x4B,0x08,0x24,0x90,0xDC,0x1E,0x00,0x00,0x90,0x48, -0x3C,0x10,0x48,0x4A,0x64,0xFF,0xA0,0x4F,0x57,0x1F,0x00,0x00,0x2C,0xCC,0xFC,0xEF, -0xB0,0x04,0x00,0x00,0x28,0x40,0x43,0x0C,0xA0,0x05,0x2C,0xCC,0xFC,0x7F,0x62,0x97, -0x00,0x00,0xE0,0x59,0xA0,0x10,0x2C,0xCC,0xF8,0x7F,0x56,0xE7,0x00,0x00,0xA0,0x4F, -0x5A,0x1F,0x00,0x00,0x2C,0xCC,0xFC,0xEF,0xB0,0x04,0x00,0x00,0x28,0x40,0x43,0x0C, -0xA0,0x05,0x2C,0xCC,0xFC,0x7F,0x62,0x97,0x00,0x00,0x04,0xC9,0xEC,0x4C,0x20,0x48, -0x20,0x49,0x08,0x70,0x10,0x49,0x9C,0x4F,0x18,0x00,0x00,0x00,0x4C,0xA0,0x00,0x2C, -0xCC,0xFC,0xEF,0x40,0x05,0x00,0x00,0x84,0x7F,0xA4,0x27,0x00,0x02,0x40,0x24,0x7F, -0x86,0xB5,0x00,0x00,0xA0,0x5F,0x60,0x70,0x2C,0xCC,0xFC,0x7F,0xEA,0xC1,0x00,0x00, -0x84,0x7F,0xA8,0x27,0x00,0x02,0x64,0x70,0x7B,0x0E,0xA0,0x64,0x2C,0xCC,0xFC,0xAF, -0xAC,0xFE,0x9C,0x10,0x64,0x70,0xDC,0x7F,0xAC,0x27,0x00,0x02,0x7F,0xA8,0x27,0x00, -0x02,0x40,0x3C,0x40,0x64,0x5B,0xE5,0x24,0x7F,0xA2,0xB5,0x00,0x00,0x84,0x7F,0xA8, -0x27,0x00,0x02,0x64,0x70,0x7B,0x5F,0xA0,0x64,0x2C,0xCC,0xFC,0x7F,0x4E,0xDA,0x00, -0x00,0x87,0x40,0x59,0x70,0xA0,0x4F,0x5C,0x1F,0x00,0x00,0xA0,0x64,0x87,0x59,0xE0, -0x40,0xA0,0x40,0x2C,0xCC,0xF4,0xEF,0xB0,0x04,0x00,0x00,0x28,0x40,0x43,0x0C,0xA0, -0x05,0x2C,0xCC,0xFC,0x7F,0x62,0x97,0x00,0x00,0xE0,0x59,0xA0,0x01,0x2C,0xCC,0xF8, -0x7F,0x56,0xE7,0x00,0x00,0xA0,0x4F,0x69,0x1F,0x00,0x00,0x2C,0xCC,0xFC,0xEF,0xB0, -0x04,0x00,0x00,0x28,0x40,0x43,0x0C,0xA0,0x05,0x2C,0xCC,0xFC,0x7F,0x62,0x97,0x00, -0x00,0x90,0x64,0x70,0xDC,0x7F,0xAC,0x27,0x00,0x02,0x7F,0xA8,0x27,0x00,0x02,0x40, -0x3C,0x40,0x64,0x5B,0x94,0x24,0x7F,0xA2,0xB5,0x00,0x00,0x84,0x7F,0xA8,0x27,0x00, -0x02,0x64,0x70,0x7B,0x60,0xA0,0x64,0x2C,0xCC,0xFC,0x7F,0x6E,0xDA,0x00,0x00,0x86, -0x40,0x68,0x70,0xA0,0x4F,0x6C,0x1F,0x00,0x00,0xA0,0x64,0x86,0x68,0xE4,0x40,0xA0, -0x40,0x2C,0xCC,0xF4,0xEF,0xB0,0x04,0x00,0x00,0x28,0x40,0x43,0x0C,0xA0,0x05,0x2C, -0xCC,0xFC,0x7F,0x62,0x97,0x00,0x00,0xE0,0x68,0xA0,0x02,0x2C,0xCC,0xF8,0x7F,0x56, -0xE7,0x00,0x00,0xA0,0x4F,0x79,0x1F,0x00,0x00,0x2C,0xCC,0xFC,0xEF,0xB0,0x04,0x00, -0x00,0x28,0x40,0x43,0x0C,0xA0,0x05,0x2C,0xCC,0xFC,0x7F,0x62,0x97,0x00,0x00,0x9C, -0x02,0x64,0x70,0xDC,0x7F,0xAC,0x27,0x00,0x02,0x7F,0xA8,0x27,0x00,0x02,0x40,0x3C, -0x40,0x64,0x5B,0x93,0x24,0x7F,0xA2,0xB5,0x00,0x00,0x84,0x7F,0xA8,0x27,0x00,0x02, -0x64,0x70,0x7B,0x5C,0xA0,0x64,0x2C,0xCC,0xFC,0x7F,0xA0,0xDA,0x00,0x00,0x84,0x40, -0x6C,0x70,0xA0,0x4F,0x7C,0x1F,0x00,0x00,0xA0,0x64,0xA0,0x6C,0x2C,0xCC,0xF4,0xEF, -0xB0,0x04,0x00,0x00,0x28,0x40,0x43,0x0C,0xA0,0x05,0x2C,0xCC,0xFC,0x7F,0x62,0x97, -0x00,0x00,0xE0,0x6C,0xA0,0x04,0x2C,0xCC,0xF8,0x7F,0x56,0xE7,0x00,0x00,0xA0,0x4F, -0x89,0x1F,0x00,0x00,0x2C,0xCC,0xFC,0xEF,0xB0,0x04,0x00,0x00,0x28,0x40,0x43,0x0C, -0xA0,0x05,0x2C,0xCC,0xFC,0x7F,0x62,0x97,0x00,0x00,0x9C,0x04,0x64,0x70,0xDC,0x7F, -0xAC,0x27,0x00,0x02,0x7F,0xA8,0x27,0x00,0x02,0x40,0x3C,0x40,0x64,0x5B,0x97,0x24, -0x7F,0xA2,0xB5,0x00,0x00,0x84,0x7F,0xA8,0x27,0x00,0x02,0x64,0x70,0x7B,0x75,0xA0, -0x64,0x2C,0xCC,0xFC,0x7F,0xA0,0xDA,0x00,0x00,0x84,0x40,0xC9,0x10,0x70,0xDC,0x04, -0x64,0x40,0xA0,0x40,0x2C,0xCC,0xFC,0x7F,0xA0,0xDA,0x00,0x00,0x84,0x40,0xC9,0x14, -0x70,0xA0,0x4F,0x8C,0x1F,0x00,0x00,0xA0,0x64,0xA0,0xC9,0x10,0xA0,0xC9,0x14,0x2C, -0xCC,0xF0,0xEF,0xB0,0x04,0x00,0x00,0x28,0x40,0x43,0x0C,0xA0,0x05,0x2C,0xCC,0xFC, -0x7F,0x62,0x97,0x00,0x00,0xE0,0xC9,0x10,0xA0,0x08,0x2C,0xCC,0xF8,0x7F,0x56,0xE7, -0x00,0x00,0xA0,0x4F,0x9E,0x1F,0x00,0x00,0x2C,0xCC,0xFC,0xEF,0xB0,0x04,0x00,0x00, -0x28,0x40,0x43,0x0C,0xA0,0x05,0x2C,0xCC,0xFC,0x7F,0x62,0x97,0x00,0x00,0x9C,0x08, -0x64,0x70,0xDC,0x7F,0xAC,0x27,0x00,0x02,0x7F,0xA8,0x27,0x00,0x02,0x40,0x3C,0x40, -0x64,0x53,0x08,0x24,0x7F,0x6F,0xB4,0x00,0x00,0x24,0x7F,0xA2,0xB5,0x00,0x00,0x2C, -0x5C,0xAF,0xC3,0x00,0x84,0x40,0x7F,0xAC,0x27,0x00,0x02,0x70,0x24,0x7F,0xA2,0xB5, -0x00,0x00,0x2C,0x5C,0xAF,0xB0,0x00,0x24,0x7F,0xA2,0xB5,0x00,0x00,0x80,0x7F,0xAC, -0x27,0x00,0x02,0x70,0x7B,0x24,0xA0,0x7F,0xA8,0x27,0x00,0x02,0xA0,0x02,0x2C,0xCC, -0xFC,0x7F,0xE8,0xCC,0x00,0x00,0xA0,0x40,0x2C,0xCC,0xF8,0x7F,0x30,0xDB,0x00,0x00, -0x9C,0x02,0x7F,0xA8,0x27,0x00,0x02,0x70,0x2C,0x5C,0x7F,0x76,0xC4,0x00,0x00,0x28, -0x40,0x7F,0xD5,0x7B,0x4F,0x7B,0x24,0xA0,0x7F,0xA8,0x27,0x00,0x02,0xA0,0x04,0x2C, -0xCC,0xFC,0x7F,0xE8,0xCC,0x00,0x00,0xA0,0x40,0x2C,0xCC,0xF8,0x7F,0xA0,0xDB,0x00, -0x00,0x9C,0x04,0x7F,0xA8,0x27,0x00,0x02,0x70,0x2C,0x5C,0x7F,0x76,0xC4,0x00,0x00, -0x28,0x40,0x7F,0xD5,0x7B,0x1E,0xFC,0x01,0x40,0x40,0x4A,0x2A,0xFD,0x3C,0x08,0x40, -0x46,0x24,0xFD,0xC0,0x02,0x40,0x40,0x28,0x40,0x4A,0x1B,0xFD,0x24,0x90,0x18,0x1F, -0x00,0x00,0x9C,0x7F,0xAC,0x27,0x00,0x02,0x7F,0xA8,0x27,0x00,0x02,0x70,0xA0,0x01, -0x2C,0xCC,0xFC,0xEF,0x40,0x05,0x00,0x00,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70, -0x70,0x70,0x10,0x49,0x9C,0x4F,0x10,0x00,0x00,0x00,0x4C,0x84,0x7F,0xA8,0x27,0x00, -0x02,0x59,0x70,0x24,0x7F,0x01,0xB7,0x00,0x00,0x3F,0x27,0xEF,0xCC,0x13,0x00,0x02, -0x7F,0x0B,0x3F,0x22,0xEF,0xCC,0x13,0x00,0x02,0x77,0x66,0x84,0x7F,0xCC,0x13,0x00, -0x02,0x40,0x90,0x7F,0xCC,0x13,0x00,0x02,0x70,0x87,0x50,0x6C,0x70,0x7B,0x3C,0x2B, -0xEF,0xCC,0x13,0x00,0x02,0x77,0x10,0xA0,0x5F,0xF0,0x40,0x2C,0xCC,0xFC,0x7F,0xEA, -0xC1,0x00,0x00,0x7B,0x26,0x84,0x59,0x40,0x90,0x59,0x70,0xA0,0x40,0x84,0x7F,0xCC, -0x13,0x00,0x02,0x40,0x90,0x7F,0xCC,0x13,0x00,0x02,0x70,0x87,0x50,0xE0,0x40,0xA0, -0x40,0x2C,0xCC,0xF8,0x7F,0xD2,0xDA,0x00,0x00,0x3F,0xEF,0xCC,0x13,0x00,0x02,0x6C, -0x77,0xBF,0x90,0x7F,0xCC,0x13,0x00,0x02,0x70,0x24,0x7F,0x01,0xB7,0x00,0x00,0x84, -0x7F,0xCC,0x13,0x00,0x02,0x40,0x90,0x7F,0xCC,0x13,0x00,0x02,0x70,0x87,0x50,0xE0, -0x40,0xA0,0x40,0x2C,0xCC,0xFC,0x7F,0x70,0xCF,0x00,0x00,0x84,0x40,0x64,0x70,0x43, -0x0E,0xA0,0x5F,0x40,0x50,0x2C,0xCC,0xFC,0x7F,0xEA,0xC1,0x00,0x00,0x3F,0x27,0xEF, -0xCC,0x13,0x00,0x02,0x7F,0x21,0x3F,0x22,0xEF,0xCC,0x13,0x00,0x02,0x7F,0x18,0x87, -0xEF,0xCC,0x13,0x00,0x02,0xE0,0x40,0xA0,0x40,0x2C,0xCC,0xFC,0x7F,0xA2,0xC4,0x00, -0x00,0x28,0x40,0x7F,0x17,0xA0,0x5F,0xE0,0x00,0x2C,0xCC,0xFC,0x7F,0x50,0xC2,0x00, -0x00,0x84,0x64,0x68,0x70,0x80,0x64,0x70,0x7B,0x30,0x84,0x7F,0xCC,0x13,0x00,0x02, -0x40,0x90,0x7F,0xCC,0x13,0x00,0x02,0x70,0x87,0x50,0xE0,0x40,0xA0,0x40,0x2C,0xCC, -0xFC,0x7F,0x70,0xCF,0x00,0x00,0x84,0x40,0x68,0x70,0x43,0x0E,0xA0,0x5F,0x40,0x50, -0x2C,0xCC,0xFC,0x7F,0xEA,0xC1,0x00,0x00,0x84,0x59,0x40,0x90,0x59,0x70,0xA0,0x40, -0xD0,0x04,0x64,0x40,0x9C,0x68,0x40,0xA0,0x40,0x2C,0xCC,0xF8,0x7F,0xD2,0xDA,0x00, -0x00,0x2C,0x5C,0x7F,0x76,0xC4,0x00,0x00,0x28,0x40,0x7E,0xCF,0xFE,0x3C,0x09,0x7F, -0xA4,0x27,0x00,0x02,0x77,0x23,0xA0,0x7F,0xA8,0x27,0x00,0x02,0xDC,0x7F,0xAC,0x27, -0x00,0x02,0x7F,0xA8,0x27,0x00,0x02,0x40,0xBC,0x59,0x40,0xA0,0x40,0xA0,0x59,0xA0, -0x01,0x2C,0xCC,0xF0,0xAF,0xA1,0x00,0xFC,0x7F,0xA8,0x27,0x00,0x02,0x59,0x40,0x7B, -0x02,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x10,0x49,0x9C,0x4F,0x14,0x00, -0x00,0x00,0x4C,0x80,0x7F,0xB8,0x27,0x00,0x02,0x70,0xA0,0x4F,0xA1,0x1F,0x00,0x00, -0x2C,0xCC,0xFC,0x7F,0xD6,0xC4,0x00,0x00,0x84,0x40,0x64,0x70,0x2C,0x5C,0x7F,0xDC, -0xC5,0x00,0x00,0x84,0x40,0x68,0x70,0x84,0x7F,0xB8,0x13,0x00,0x02,0x59,0x70,0x2C, -0x5C,0x7F,0xDC,0xC5,0x00,0x00,0x84,0x40,0x6C,0x70,0x84,0x59,0x7F,0xB8,0x13,0x00, -0x02,0x70,0x3C,0x68,0x6C,0x4B,0x0D,0xFC,0x68,0x6C,0x40,0x9C,0x01,0x40,0x84,0x40, -0x6C,0x70,0x2C,0x5C,0x7F,0xDC,0xC5,0x00,0x00,0x84,0x40,0xC9,0x10,0x70,0xA0,0x68, -0xA0,0x6C,0xA0,0xC9,0x10,0x28,0x64,0x7F,0x07,0x84,0x04,0x40,0x7B,0x05,0x84,0x01, -0x40,0xA0,0x40,0x2C,0xCC,0xF0,0xAF,0x0F,0x00,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08, -0x70,0x70,0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x7B,0x22,0x84,0x78,0x40, -0x90,0x78,0x70,0xA0,0x40,0xA0,0x5A,0x2C,0xCC,0xFC,0x7F,0x4E,0xDA,0x00,0x00,0xA0, -0x40,0x2C,0xCC,0xF8,0x7F,0xD2,0xDA,0x00,0x00,0x9C,0x7C,0x5A,0x70,0x84,0x74,0x40, -0x94,0x74,0x70,0x28,0x40,0x47,0xD8,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70, -0x10,0x48,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x80,0x48,0x7B,0x37,0xA0,0x4F,0xA4, -0x1F,0x00,0x00,0xD0,0x03,0x48,0x40,0xA0,0x80,0x10,0x15,0x00,0x00,0xDC,0x01,0x48, -0x40,0xA4,0x08,0x40,0x7F,0x0B,0x84,0x4F,0xAC,0x1F,0x00,0x00,0x40,0x7B,0x09,0x84, -0x4F,0xAF,0x1F,0x00,0x00,0x40,0xA0,0x40,0x2C,0xCC,0xF4,0xEF,0xB0,0x04,0x00,0x00, -0x90,0x48,0x3C,0x7F,0x98,0x17,0x00,0x00,0x48,0x77,0xC4,0xA0,0x4F,0xB1,0x1F,0x00, -0x00,0x2C,0xCC,0xFC,0xEF,0xB0,0x04,0x00,0x00,0x04,0xC9,0xEC,0x4C,0x20,0x48,0x20, -0x49,0x08,0x70,0x70,0x10,0x49,0x9C,0x4F,0x04,0x00,0x00,0x00,0x4C,0x28,0x7F,0xB4, -0x13,0x00,0x02,0x7F,0x12,0xA0,0x4F,0xB3,0x1F,0x00,0x00,0x2C,0xCC,0xFC,0xEF,0xB0, -0x04,0x00,0x00,0x7B,0x10,0xA0,0x4F,0xC0,0x1F,0x00,0x00,0x2C,0xCC,0xFC,0xEF,0xB0, -0x04,0x00,0x00,0xDC,0x04,0x7F,0xF8,0x1D,0x00,0x02,0x40,0xA0,0x50,0x2C,0xCC,0xFC, -0x7F,0x96,0x99,0x00,0x00,0x84,0x40,0x59,0x70,0x3C,0xFF,0x40,0x7F,0x53,0x3C,0x15, -0x59,0x77,0x12,0xA0,0x4F,0xCE,0x1F,0x00,0x00,0x2C,0xCC,0xFC,0xEF,0xB0,0x04,0x00, -0x00,0x7B,0x3C,0xA0,0x4F,0xE9,0x1F,0x00,0x00,0xA0,0x59,0xDC,0x04,0x7F,0xF8,0x1D, -0x00,0x02,0x40,0xA0,0x50,0x2C,0xCC,0xF4,0xEF,0xB0,0x04,0x00,0x00,0xDC,0x04,0x7F, -0xF8,0x1D,0x00,0x02,0x40,0xA0,0x50,0x2C,0xCC,0xFC,0x7F,0x9C,0xD0,0x00,0x00,0xA0, -0x4F,0x0D,0x20,0x00,0x00,0x2C,0xCC,0xFC,0xEF,0xB0,0x04,0x00,0x00,0x7B,0x10,0xA0, -0x4F,0x0F,0x20,0x00,0x00,0x2C,0xCC,0xFC,0xEF,0xB0,0x04,0x00,0x00,0x04,0xC9,0xE8, -0x4C,0x20,0x49,0x08,0x10,0x49,0x9C,0x4F,0x10,0x00,0x00,0x00,0x4C,0x2C,0x5C,0x7F, -0x76,0xC4,0x00,0x00,0x28,0x40,0x77,0x08,0x24,0x7F,0x25,0xBA,0x00,0x00,0xA0,0x4F, -0x11,0x20,0x00,0x00,0x2C,0xCC,0xFC,0xEF,0xB0,0x04,0x00,0x00,0x80,0x59,0x70,0x24, -0x7F,0x19,0xBA,0x00,0x00,0xE8,0x28,0x59,0x40,0x3C,0xFF,0x80,0xC8,0x27,0x00,0x02, -0x77,0x08,0x24,0x7F,0x16,0xBA,0x00,0x00,0xA0,0x4F,0x25,0x20,0x00,0x00,0xE8,0x28, -0x59,0x40,0xA0,0x80,0xC4,0x27,0x00,0x02,0xE8,0x28,0x59,0x40,0xA0,0x80,0xC8,0x27, -0x00,0x02,0x2C,0xCC,0xF4,0xEF,0xB0,0x04,0x00,0x00,0xA0,0x4F,0x3A,0x20,0x00,0x00, -0x2C,0xCC,0xFC,0xEF,0xB0,0x04,0x00,0x00,0x80,0x64,0x70,0x7B,0x29,0xA0,0x4F,0x4F, -0x20,0x00,0x00,0xA0,0x64,0xE8,0x28,0x59,0x40,0x9C,0x4F,0xCC,0x27,0x00,0x02,0x40, -0xD0,0x02,0x64,0x41,0x9C,0x41,0x40,0xA0,0x50,0x2C,0xCC,0xF4,0xEF,0xB0,0x04,0x00, -0x00,0x90,0x64,0x70,0x3C,0x04,0x64,0x4B,0xD6,0xA0,0x4F,0x5B,0x20,0x00,0x00,0x2C, -0xCC,0xFC,0xEF,0xB0,0x04,0x00,0x00,0x80,0x64,0x70,0x7B,0x29,0xA0,0x4F,0x70,0x20, -0x00,0x00,0xA0,0x64,0xE8,0x28,0x59,0x40,0x9C,0x4F,0xDC,0x27,0x00,0x02,0x40,0xD0, -0x02,0x64,0x41,0x9C,0x41,0x40,0xA0,0x50,0x2C,0xCC,0xF4,0xEF,0xB0,0x04,0x00,0x00, -0x90,0x64,0x70,0x3C,0x04,0x64,0x4B,0xD6,0xA0,0x4F,0x7C,0x20,0x00,0x00,0x2C,0xCC, -0xFC,0xEF,0xB0,0x04,0x00,0x00,0x90,0x59,0x70,0x3C,0x14,0x59,0x4A,0x39,0xFF,0x24, -0x7F,0x1A,0xBC,0x00,0x00,0x2C,0x5C,0x7F,0xA0,0xCE,0x00,0x00,0x84,0x40,0x68,0x70, -0x2C,0x5C,0x7F,0x76,0xC4,0x00,0x00,0x28,0x40,0x77,0x0E,0x2C,0x5C,0x7F,0xF6,0xC3, -0x00,0x00,0x3C,0x2D,0x40,0x77,0x0C,0x84,0x7F,0xFC,0x1D,0x00,0x02,0x6C,0x70,0x7B, -0x0D,0x2C,0x5C,0x7F,0xDC,0xC5,0x00,0x00,0x84,0x40,0x6C,0x70,0x84,0xFF,0x59,0x70, -0x80,0x64,0x70,0x7B,0x16,0xE8,0x28,0x64,0x40,0x3C,0x68,0x80,0xC4,0x27,0x00,0x02, -0x77,0x06,0x84,0x64,0x59,0x70,0x90,0x64,0x70,0x3C,0x14,0x64,0x4B,0xE9,0x3C,0xFF, -0x59,0x77,0x1C,0x80,0x59,0x70,0x7B,0x05,0x90,0x59,0x70,0x3C,0x14,0x59,0x43,0x0F, -0xE8,0x28,0x59,0x40,0x3C,0xFF,0x80,0xC8,0x27,0x00,0x02,0x77,0xED,0x3C,0x14,0x59, -0x77,0x10,0xA0,0x4F,0x70,0x92,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xEA,0xC1,0x00,0x00, -0x80,0x64,0x70,0x7B,0x49,0xE8,0x28,0x59,0x40,0x9C,0x4F,0xCC,0x27,0x00,0x02,0x40, -0xD0,0x02,0x64,0x41,0x9C,0x41,0x40,0xD0,0x02,0x64,0x41,0xD0,0x02,0x41,0x41,0x84, -0x81,0x00,0x06,0x04,0x00,0x50,0x70,0xE8,0x28,0x59,0x40,0x9C,0x4F,0xDC,0x27,0x00, -0x02,0x40,0xD0,0x02,0x64,0x41,0x9C,0x41,0x40,0xD0,0x02,0x64,0x41,0xD0,0x02,0x41, -0x41,0x84,0x81,0x00,0x07,0x04,0x00,0x50,0x70,0x90,0x64,0x70,0x3C,0x04,0x64,0x4B, -0xB6,0x2C,0x5C,0x7F,0xF6,0xC3,0x00,0x00,0x3C,0x2D,0x40,0x7F,0x08,0x24,0x7F,0x02, -0xBC,0x00,0x00,0x90,0x7F,0xCC,0x13,0x00,0x02,0x70,0x24,0x7F,0xF6,0xBB,0x00,0x00, -0xA0,0x01,0x2C,0xCC,0xFC,0x7F,0x28,0xCE,0x00,0x00,0x84,0x40,0x64,0x70,0x4B,0x07, -0x3C,0x03,0x64,0x4F,0x0E,0xA0,0x5F,0x60,0x52,0x2C,0xCC,0xFC,0x7F,0xEA,0xC1,0x00, -0x00,0x2C,0x5C,0x7F,0xF6,0xC3,0x00,0x00,0x3C,0x28,0x40,0x7F,0x0E,0xA0,0x5F,0x60, -0x52,0x2C,0xCC,0xFC,0x7F,0xEA,0xC1,0x00,0x00,0x90,0x7F,0xCC,0x13,0x00,0x02,0x70, -0x2C,0x5C,0x7F,0xF6,0xC3,0x00,0x00,0x3C,0x2C,0x40,0x7F,0x22,0xA0,0x08,0x2C,0xCC, -0xFC,0x7F,0x28,0xCE,0x00,0x00,0xE8,0x28,0x59,0x41,0x9C,0x4F,0xCC,0x27,0x00,0x02, -0x41,0xD0,0x02,0x64,0x42,0x9C,0x42,0x41,0x84,0x40,0x51,0x70,0x2C,0x5C,0x7F,0xF6, -0xC3,0x00,0x00,0x3C,0x2C,0x40,0x7F,0x0E,0xA0,0x5F,0x60,0x52,0x2C,0xCC,0xFC,0x7F, -0xEA,0xC1,0x00,0x00,0x90,0x7F,0xCC,0x13,0x00,0x02,0x70,0x2C,0x5C,0x7F,0xF6,0xC3, -0x00,0x00,0x3C,0x29,0x40,0x7F,0x22,0xA0,0x08,0x2C,0xCC,0xFC,0x7F,0x28,0xCE,0x00, -0x00,0xE8,0x28,0x59,0x41,0x9C,0x4F,0xDC,0x27,0x00,0x02,0x41,0xD0,0x02,0x64,0x42, -0x9C,0x42,0x41,0x84,0x40,0x51,0x70,0x2C,0x5C,0x7F,0xF6,0xC3,0x00,0x00,0x3C,0x29, -0x40,0x7F,0x0E,0xA0,0x5F,0x60,0x52,0x2C,0xCC,0xFC,0x7F,0xEA,0xC1,0x00,0x00,0x90, -0x7F,0xCC,0x13,0x00,0x02,0x70,0x2C,0x5C,0x7F,0x76,0xC4,0x00,0x00,0x28,0x40,0x7E, -0x21,0xFF,0xE8,0x28,0x59,0x40,0x84,0x68,0x80,0xC4,0x27,0x00,0x02,0x70,0xE8,0x28, -0x59,0x40,0x84,0x6C,0x80,0xC8,0x27,0x00,0x02,0x70,0x04,0xC9,0xE8,0x4C,0x20,0x49, -0x08,0x70,0x70,0x70,0x10,0x49,0x9C,0x4F,0x0C,0x00,0x00,0x00,0x4C,0x2C,0x5C,0x7F, -0x76,0xC4,0x00,0x00,0x28,0x40,0x7F,0x1C,0xA0,0x4F,0x7E,0x20,0x00,0x00,0xA0,0x7F, -0xBC,0x27,0x00,0x02,0x2C,0xCC,0xF8,0xEF,0xB0,0x04,0x00,0x00,0x24,0x7F,0x17,0xBD, -0x00,0x00,0x2C,0x5C,0x7F,0xA0,0xCE,0x00,0x00,0x84,0x40,0x68,0x70,0xA0,0x4F,0x99, -0x20,0x00,0x00,0xA0,0x68,0x2C,0xCC,0xF8,0xEF,0xB0,0x04,0x00,0x00,0x80,0x59,0x70, -0x7B,0x05,0x90,0x59,0x70,0x3C,0x14,0x59,0x43,0x0F,0xE8,0x28,0x59,0x40,0x3C,0x68, -0x80,0xC4,0x27,0x00,0x02,0x77,0xED,0x3C,0x14,0x59,0x77,0x0E,0xA0,0x5F,0x70,0x52, -0x2C,0xCC,0xFC,0x7F,0xEA,0xC1,0x00,0x00,0xE8,0x28,0x59,0x40,0x84,0x80,0xC8,0x27, -0x00,0x02,0x7F,0xFC,0x1D,0x00,0x02,0x70,0xA0,0x7F,0xFC,0x1D,0x00,0x02,0x2C,0xCC, -0xFC,0x7F,0x6C,0xD7,0x00,0x00,0x84,0x40,0x7F,0xF8,0x1D,0x00,0x02,0x70,0x80,0x64, -0x70,0x7B,0x49,0xD0,0x02,0x64,0x40,0xD0,0x02,0x40,0x40,0xE8,0x28,0x59,0x41,0x9C, -0x4F,0xCC,0x27,0x00,0x02,0x41,0xD0,0x02,0x64,0x42,0x9C,0x42,0x41,0x84,0x51,0x80, -0x00,0x06,0x04,0x00,0x70,0xD0,0x02,0x64,0x40,0xD0,0x02,0x40,0x40,0xE8,0x28,0x59, -0x41,0x9C,0x4F,0xDC,0x27,0x00,0x02,0x41,0xD0,0x02,0x64,0x42,0x9C,0x42,0x41,0x84, -0x51,0x80,0x00,0x07,0x04,0x00,0x70,0x90,0x64,0x70,0x3C,0x04,0x64,0x4B,0xB6,0x84, -0x68,0x7F,0xBC,0x27,0x00,0x02,0x70,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70, -0x10,0x49,0x9C,0x4F,0x08,0x00,0x00,0x00,0x4C,0x2C,0x5C,0x7F,0x76,0xC4,0x00,0x00, -0x28,0x40,0x7F,0x0E,0xA0,0x5F,0x70,0x22,0x2C,0xCC,0xFC,0x7F,0xEA,0xC1,0x00,0x00, -0xA0,0x4F,0xB2,0x20,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xD6,0xC4,0x00,0x00,0x28,0x40, -0x7F,0x1D,0x80,0x64,0x70,0x7B,0x11,0xE8,0x28,0x64,0x40,0x84,0xFF,0x80,0xC8,0x27, -0x00,0x02,0x70,0x90,0x64,0x70,0x3C,0x14,0x64,0x4B,0xEE,0x7B,0x33,0x2C,0x5C,0x7F, -0xA0,0xCE,0x00,0x00,0x84,0x40,0x59,0x70,0x80,0x64,0x70,0x7B,0x1E,0xE8,0x28,0x64, -0x40,0x3C,0x59,0x80,0xC4,0x27,0x00,0x02,0x77,0x0E,0xE8,0x28,0x64,0x40,0x84,0xFF, -0x80,0xC8,0x27,0x00,0x02,0x70,0x90,0x64,0x70,0x3C,0x14,0x64,0x4B,0xE1,0x04,0xC9, -0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x70,0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00, -0x4C,0x2C,0x5C,0x7F,0xE4,0x9D,0x00,0x00,0x2C,0x5C,0xAF,0x58,0x05,0x24,0x7F,0x9B, -0xC1,0x00,0x00,0xA0,0x5F,0x10,0x50,0x2C,0xCC,0xFC,0xAF,0x23,0x04,0xA0,0x05,0x2C, -0xCC,0xFC,0x7F,0x62,0x97,0x00,0x00,0x24,0x7F,0xB8,0xC1,0x00,0x00,0x2C,0x5C,0x7F, -0x10,0xB8,0x00,0x00,0x24,0x7F,0xB8,0xC1,0x00,0x00,0x2C,0x5C,0x7F,0x3E,0xAD,0x00, -0x00,0x24,0x7F,0xB8,0xC1,0x00,0x00,0x2C,0x5C,0x7F,0xB8,0xAC,0x00,0x00,0x24,0x7F, -0xB8,0xC1,0x00,0x00,0x2C,0x5C,0x7F,0xD8,0xAD,0x00,0x00,0x24,0x7F,0xB8,0xC1,0x00, -0x00,0x2C,0x5C,0x7F,0x72,0xAE,0x00,0x00,0x24,0x7F,0xB8,0xC1,0x00,0x00,0x2C,0x5C, -0x7F,0x0C,0xAF,0x00,0x00,0x24,0x7F,0xB8,0xC1,0x00,0x00,0x2C,0x5C,0x7F,0x44,0xB0, -0x00,0x00,0x24,0x7F,0xB8,0xC1,0x00,0x00,0x2C,0x5C,0x7F,0xA0,0xB0,0x00,0x00,0x24, -0x7F,0xB8,0xC1,0x00,0x00,0x2C,0x5C,0x7F,0x00,0xB1,0x00,0x00,0x24,0x7F,0xB8,0xC1, -0x00,0x00,0x2C,0x5C,0x7F,0xA6,0xAF,0x00,0x00,0x24,0x7F,0xB8,0xC1,0x00,0x00,0x2C, -0x5C,0x7F,0x60,0xB1,0x00,0x00,0x24,0x7F,0xB8,0xC1,0x00,0x00,0x2C,0x5C,0x7F,0x4A, -0xB7,0x00,0x00,0x24,0x7F,0xB8,0xC1,0x00,0x00,0xA0,0x07,0x2C,0xCC,0xFC,0x7F,0xB6, -0xD3,0x00,0x00,0x24,0x7F,0xB8,0xC1,0x00,0x00,0xA0,0x08,0x2C,0xCC,0xFC,0x7F,0xB6, -0xD3,0x00,0x00,0x24,0x7F,0xB8,0xC1,0x00,0x00,0xA0,0x09,0x2C,0xCC,0xFC,0x7F,0xB6, -0xD3,0x00,0x00,0x24,0x7F,0xB8,0xC1,0x00,0x00,0xA0,0x0A,0x2C,0xCC,0xFC,0x7F,0xB6, -0xD3,0x00,0x00,0x24,0x7F,0xB8,0xC1,0x00,0x00,0xA0,0x0B,0x2C,0xCC,0xFC,0x7F,0xB6, -0xD3,0x00,0x00,0x24,0x7F,0xB8,0xC1,0x00,0x00,0xA0,0x0C,0x2C,0xCC,0xFC,0x7F,0xB6, -0xD3,0x00,0x00,0x24,0x7F,0xB8,0xC1,0x00,0x00,0xA0,0x0D,0x2C,0xCC,0xFC,0x7F,0xB6, -0xD3,0x00,0x00,0x24,0x7F,0xB8,0xC1,0x00,0x00,0xA0,0x0E,0x2C,0xCC,0xFC,0x7F,0xB6, -0xD3,0x00,0x00,0x24,0x7F,0xB8,0xC1,0x00,0x00,0xA0,0x0F,0x2C,0xCC,0xFC,0x7F,0xB6, -0xD3,0x00,0x00,0x24,0x7F,0xB8,0xC1,0x00,0x00,0xA0,0x06,0x2C,0xCC,0xFC,0x7F,0xB6, -0xD3,0x00,0x00,0x24,0x7F,0xB8,0xC1,0x00,0x00,0xA0,0x05,0x2C,0xCC,0xFC,0x7F,0xB6, -0xD3,0x00,0x00,0x24,0x7F,0xB8,0xC1,0x00,0x00,0xA0,0x00,0x2C,0xCC,0xFC,0x7F,0xB6, -0xD3,0x00,0x00,0x24,0x7F,0xB8,0xC1,0x00,0x00,0xA0,0x02,0x2C,0xCC,0xFC,0x7F,0xB6, -0xD3,0x00,0x00,0x24,0x7F,0xB8,0xC1,0x00,0x00,0xA0,0x11,0x2C,0xCC,0xFC,0x7F,0xB6, -0xD3,0x00,0x00,0x24,0x7F,0xB8,0xC1,0x00,0x00,0xA0,0x12,0x2C,0xCC,0xFC,0x7F,0xB6, -0xD3,0x00,0x00,0x24,0x7F,0xB8,0xC1,0x00,0x00,0xA0,0x01,0x2C,0xCC,0xFC,0x7F,0xB6, -0xD3,0x00,0x00,0x24,0x7F,0xB8,0xC1,0x00,0x00,0xA0,0x03,0x2C,0xCC,0xFC,0x7F,0xB6, -0xD3,0x00,0x00,0x24,0x7F,0xB8,0xC1,0x00,0x00,0xA0,0x04,0x2C,0xCC,0xFC,0x7F,0xB6, -0xD3,0x00,0x00,0x24,0x7F,0xB8,0xC1,0x00,0x00,0x2C,0x5C,0x7F,0xA8,0xD1,0x00,0x00, -0x24,0x7F,0xB8,0xC1,0x00,0x00,0x2C,0x5C,0x7F,0x80,0xE2,0x00,0x00,0x24,0x7F,0xB8, -0xC1,0x00,0x00,0x2C,0x5C,0x7F,0x34,0xD2,0x00,0x00,0x24,0x7F,0xB8,0xC1,0x00,0x00, -0x2C,0x5C,0x7F,0x28,0xC5,0x00,0x00,0x24,0x7F,0xB8,0xC1,0x00,0x00,0x2C,0x5C,0x7F, -0x30,0xDF,0x00,0x00,0x24,0x7F,0xB8,0xC1,0x00,0x00,0x2C,0x5C,0x7F,0x3A,0xE0,0x00, -0x00,0x24,0x7F,0xB8,0xC1,0x00,0x00,0x80,0x7F,0xC0,0x13,0x00,0x02,0x70,0x80,0x7F, -0xC4,0x13,0x00,0x02,0x70,0x2C,0x5C,0x7F,0x08,0xDC,0x00,0x00,0x24,0x7F,0xB8,0xC1, -0x00,0x00,0x84,0x01,0x7F,0xC0,0x13,0x00,0x02,0x70,0x80,0x7F,0xC4,0x13,0x00,0x02, -0x70,0x2C,0x5C,0x7F,0x08,0xDC,0x00,0x00,0x24,0x7F,0xB8,0xC1,0x00,0x00,0x80,0x7F, -0xC0,0x13,0x00,0x02,0x70,0x84,0x01,0x7F,0xC4,0x13,0x00,0x02,0x70,0x2C,0x5C,0x7F, -0x08,0xDC,0x00,0x00,0x24,0x7F,0xB8,0xC1,0x00,0x00,0x84,0x01,0x7F,0xC0,0x13,0x00, -0x02,0x70,0x84,0x01,0x7F,0xC4,0x13,0x00,0x02,0x70,0x2C,0x5C,0x7F,0x08,0xDC,0x00, -0x00,0x24,0x7F,0xB8,0xC1,0x00,0x00,0x2C,0x5C,0x7F,0xF4,0x99,0x00,0x00,0x24,0x7F, -0xB8,0xC1,0x00,0x00,0x2C,0x5C,0x7F,0xB4,0x9B,0x00,0x00,0x24,0x7F,0xB8,0xC1,0x00, -0x00,0x2C,0x5C,0x7F,0x42,0x9C,0x00,0x00,0x24,0x7F,0xB8,0xC1,0x00,0x00,0x2C,0x5C, -0x7F,0xF0,0x9C,0x00,0x00,0x24,0x7F,0xB8,0xC1,0x00,0x00,0x2C,0x5C,0x7F,0x42,0xA6, -0x00,0x00,0x24,0x7F,0xB8,0xC1,0x00,0x00,0x2C,0x5C,0x7F,0xF4,0xA2,0x00,0x00,0x24, -0x7F,0xB8,0xC1,0x00,0x00,0x2C,0x5C,0x7F,0x6C,0xA5,0x00,0x00,0x24,0x7F,0xB8,0xC1, -0x00,0x00,0xA0,0x4F,0x00,0x90,0x04,0x00,0x2C,0xCC,0xFC,0x7F,0x60,0xE6,0x00,0x00, -0x24,0x7F,0xB8,0xC1,0x00,0x00,0xA0,0x4F,0x08,0x90,0x04,0x00,0x2C,0xCC,0xFC,0x7F, -0x60,0xE6,0x00,0x00,0x24,0x7F,0xB8,0xC1,0x00,0x00,0x2C,0x5C,0x7F,0x74,0xB8,0x00, -0x00,0x24,0x7F,0xB8,0xC1,0x00,0x00,0x2C,0x5C,0x7F,0x0C,0x45,0x00,0x00,0x24,0x7F, -0xB8,0xC1,0x00,0x00,0x84,0x4F,0x1E,0xAC,0xEB,0xAD,0xEF,0x8C,0x04,0x00,0x00,0x70, -0x87,0x01,0x7F,0x0B,0x40,0x04,0x00,0x70,0x7B,0x00,0x84,0x4F,0x00,0x90,0x04,0x00, -0xEF,0xFC,0x04,0x00,0x00,0x70,0x24,0x7F,0xB8,0xC1,0x00,0x00,0x84,0x4F,0x08,0x90, -0x04,0x00,0xEF,0xFC,0x04,0x00,0x00,0x70,0x24,0x7F,0xB8,0xC1,0x00,0x00,0x87,0x01, -0x7F,0x0B,0x40,0x04,0x00,0x70,0x7B,0x00,0xA0,0x01,0x2C,0xCC,0xFC,0x7F,0xF6,0xD9, -0x00,0x00,0x7B,0x76,0xA0,0x00,0x2C,0xCC,0xFC,0x7F,0xF6,0xD9,0x00,0x00,0x7B,0x6A, -0x2C,0x5C,0x7F,0x88,0xD9,0x00,0x00,0x7B,0x61,0x2C,0x5C,0x7F,0xA8,0xD4,0x00,0x00, -0x7B,0x58,0x2C,0x5C,0x7F,0x5E,0xD5,0x00,0x00,0x7B,0x4F,0x2C,0x5C,0x7F,0x14,0xD6, -0x00,0x00,0x7B,0x46,0x2C,0x5C,0x7F,0x24,0xB9,0x00,0x00,0x7B,0x3D,0x2C,0x5C,0x7F, -0x20,0xBD,0x00,0x00,0x7B,0x34,0x2C,0x5C,0x7F,0x24,0xBC,0x00,0x00,0x7B,0x2B,0xA0, -0x00,0x2C,0xCC,0xFC,0x7F,0x9C,0xD0,0x00,0x00,0x7B,0x1F,0xFC,0xFF,0x40,0x40,0x4A, -0x24,0xFC,0x3C,0x6F,0x42,0x40,0x46,0x1D,0xFC,0xC0,0x02,0x40,0x40,0x28,0x40,0x4A, -0x14,0xFC,0x24,0x90,0xB8,0x21,0x00,0x00,0x7B,0x09,0x90,0x7F,0xCC,0x13,0x00,0x02, -0x70,0x3F,0x3B,0xEF,0xCC,0x13,0x00,0x02,0x7F,0x0A,0x2B,0xEF,0xCC,0x13,0x00,0x02, -0x77,0xEA,0x84,0x7F,0xB4,0x13,0x00,0x02,0x7F,0xB8,0x13,0x00,0x02,0x70,0x7A,0xD3, -0xFB,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x10,0x49,0x9C,0x4F,0x04,0x00, -0x00,0x00,0x4C,0x3C,0xFF,0x5A,0x77,0x12,0xA0,0x4F,0xB0,0x26,0x00,0x00,0x2C,0xCC, -0xFC,0xEF,0xB0,0x04,0x00,0x00,0x7B,0x2D,0x3C,0x04,0x5A,0x77,0x12,0xA0,0x4F,0xBA, -0x26,0x00,0x00,0x2C,0xCC,0xFC,0xEF,0xB0,0x04,0x00,0x00,0x7B,0x18,0xA0,0x4F,0xBC, -0x26,0x00,0x00,0x2C,0xCC,0xFC,0xEF,0xB0,0x04,0x00,0x00,0xA0,0x5A,0x2C,0xCC,0xFC, -0xAF,0x4B,0x00,0x84,0x7F,0xB4,0x13,0x00,0x02,0x7F,0xB8,0x13,0x00,0x02,0x70,0xA0, -0x05,0x2C,0xCC,0xFC,0x7F,0x62,0x97,0x00,0x00,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08, -0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0xA0,0x4F,0xC5,0x26,0x00,0x00,0x2C, -0xCC,0xFC,0xEF,0xB0,0x04,0x00,0x00,0xA0,0x5A,0x2C,0xCC,0xFC,0xAF,0x0F,0x00,0x04, -0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x10,0x49,0x9C,0x4F,0x10,0x00,0x00,0x00, -0x4C,0xF8,0x4F,0x00,0xF0,0x00,0x00,0x5A,0x40,0xD4,0x0C,0x40,0x40,0x84,0x40,0x59, -0x70,0xF8,0x5F,0xF0,0x0F,0x5A,0x40,0xD4,0x04,0x40,0x40,0x84,0x40,0x64,0x70,0xF8, -0x0F,0x5A,0x40,0x84,0x40,0x68,0x70,0x84,0x7F,0xC8,0x13,0x00,0x02,0x6C,0x70,0x7B, -0x1C,0xA0,0x4F,0xCF,0x26,0x00,0x00,0x84,0x6C,0x40,0x90,0x6C,0x70,0x87,0x50,0xE0, -0x40,0xA0,0x40,0x2C,0xCC,0xF8,0xEF,0xB0,0x04,0x00,0x00,0x87,0xD9,0x0C,0xE0,0x40, -0xA0,0x40,0x2C,0xCC,0xFC,0xAF,0xD0,0x01,0x28,0x40,0x7F,0xD7,0xA0,0x4F,0xD2,0x26, -0x00,0x00,0xD0,0x02,0x59,0x40,0xA0,0x80,0xB8,0x20,0x00,0x00,0xD0,0x02,0x64,0x40, -0xA0,0x80,0xF8,0x20,0x00,0x00,0xD0,0x02,0x68,0x40,0xA0,0x80,0x9C,0x21,0x00,0x00, -0x2C,0xCC,0xF0,0xEF,0xB0,0x04,0x00,0x00,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70, -0x10,0x48,0x9C,0x4F,0x08,0x00,0x00,0x00,0x4C,0x7B,0x09,0x90,0x7F,0xCC,0x13,0x00, -0x02,0x70,0x2C,0x5C,0xAF,0xD4,0x00,0x3C,0x3B,0x40,0x7F,0xF1,0x2B,0xEF,0xCC,0x13, -0x00,0x02,0x77,0x08,0x84,0x6F,0x41,0x40,0x7B,0x58,0xA0,0x7F,0xCC,0x13,0x00,0x02, -0x2C,0xCC,0xFC,0xAF,0xEE,0x00,0x80,0x48,0x84,0x7F,0xCC,0x13,0x00,0x02,0x7F,0xC8, -0x13,0x00,0x02,0x70,0xE0,0x59,0xA0,0x08,0x2C,0xCC,0xF8,0xAF,0x42,0x00,0x7B,0x04, -0x90,0x48,0x3C,0x7F,0x98,0x17,0x00,0x00,0x48,0x43,0x1A,0xD0,0x03,0x48,0x40,0xA0, -0x80,0x10,0x15,0x00,0x00,0xE0,0x59,0x2C,0xCC,0xF8,0x7F,0xE4,0xE9,0x00,0x00,0x28, -0x40,0x77,0xDF,0xD0,0x03,0x48,0x40,0x84,0x80,0x14,0x15,0x00,0x00,0x40,0x7B,0x02, -0x04,0xC9,0xEC,0x4C,0x20,0x48,0x20,0x49,0x08,0x70,0x10,0x47,0x9C,0x4F,0x00,0x00, -0x00,0x00,0x4C,0xFC,0x01,0x74,0x40,0x70,0x84,0x40,0x47,0x80,0x48,0x7B,0x1C,0x84, -0x48,0x40,0x90,0x48,0x9C,0x5A,0x40,0x84,0x7F,0xCC,0x13,0x00,0x02,0x41,0x90,0x7F, -0xCC,0x13,0x00,0x02,0x70,0x87,0x51,0x50,0x70,0x3C,0x47,0x48,0x43,0x16,0x87,0xEF, -0xCC,0x13,0x00,0x02,0xE0,0x40,0xA0,0x40,0x2C,0xCC,0xFC,0xAF,0xCA,0x00,0x28,0x40, -0x7F,0xCF,0xDC,0x48,0x5A,0x40,0x83,0x50,0x70,0x04,0xC9,0xF0,0x4C,0x20,0x48,0x20, -0x47,0x20,0x49,0x08,0x70,0x70,0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x7B, -0x09,0x90,0x7F,0xCC,0x13,0x00,0x02,0x70,0x3F,0x20,0xEF,0xCC,0x13,0x00,0x02,0x7F, -0xF2,0x3F,0x09,0xEF,0xCC,0x13,0x00,0x02,0x7F,0xE9,0x87,0xEF,0xCC,0x13,0x00,0x02, -0xE0,0x40,0x7B,0x02,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x70,0x10,0x49, -0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x7B,0x1F,0x3F,0x6F,0x61,0xDA,0x00,0x4B,0x15, -0x3F,0x6F,0x7A,0xDA,0x00,0x47,0x0E,0xFB,0x5F,0xDF,0x00,0xDA,0x00,0x40,0x87,0x40, -0xDA,0x00,0x70,0x90,0x5A,0x70,0x3F,0x22,0xDA,0x00,0x7F,0x13,0x87,0xDA,0x00,0xE0, -0x40,0xA0,0x40,0x2C,0xCC,0xFC,0xAF,0x3F,0x00,0x28,0x40,0x7F,0xCE,0x04,0xC9,0xE8, -0x4C,0x20,0x49,0x08,0x70,0x70,0x10,0x49,0x9C,0x4F,0x04,0x00,0x00,0x00,0x4C,0x2C, -0x5C,0xAF,0x77,0xFF,0x87,0x40,0x59,0x70,0x2B,0x59,0x7F,0x07,0x3F,0x3B,0x59,0x77, -0x07,0x84,0x01,0x40,0x7B,0x06,0x80,0x40,0x7B,0x02,0x04,0xC9,0xE8,0x4C,0x20,0x49, -0x08,0x70,0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x3F,0x20,0x73,0x7F,0x15, -0x2B,0x73,0x7F,0x11,0x3F,0x3B,0x73,0x7F,0x0C,0x3F,0x09,0x73,0x7F,0x07,0x3F,0x3A, -0x73,0x77,0x07,0x84,0x01,0x40,0x7B,0x06,0x80,0x40,0x7B,0x02,0x04,0xC9,0xE8,0x4C, -0x20,0x49,0x08,0x70,0x70,0x70,0x10,0x49,0x9C,0x4F,0x0C,0x00,0x00,0x00,0x4C,0x84, -0x7F,0xCC,0x13,0x00,0x02,0x68,0x70,0x2C,0x5C,0xAF,0x0F,0xFF,0xE0,0x59,0xA0,0x08, -0x2C,0xCC,0xF8,0xAF,0xAA,0xFE,0xE0,0x59,0x2C,0xCC,0xFC,0xAF,0x36,0xFF,0xE0,0x59, -0xA0,0x5A,0x2C,0xCC,0xF8,0x7F,0xE4,0xE9,0x00,0x00,0x28,0x40,0x77,0x07,0x84,0x01, -0x40,0x7B,0x0E,0x84,0x68,0x7F,0xCC,0x13,0x00,0x02,0x70,0x80,0x40,0x7B,0x02,0x04, -0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x10,0x49,0x9C,0x4F,0x04,0x00,0x00,0x00, -0x4C,0x2C,0x5C,0x7F,0x76,0xC4,0x00,0x00,0x28,0x40,0x7F,0x57,0xA0,0x4F,0x24,0x27, -0x00,0x00,0x2C,0xCC,0xFC,0xEF,0xB0,0x04,0x00,0x00,0x80,0x59,0x70,0x7B,0x3D,0xD0, -0x03,0x59,0x40,0x28,0x80,0x60,0x1D,0x00,0x02,0x7F,0x1E,0xA0,0x4F,0x31,0x27,0x00, -0x00,0xA0,0x59,0xD0,0x03,0x59,0x40,0xA0,0x80,0x5C,0x1D,0x00,0x02,0x2C,0xCC,0xF4, -0xEF,0xB0,0x04,0x00,0x00,0x7B,0x12,0xA0,0x4F,0x3B,0x27,0x00,0x00,0xA0,0x59,0x2C, -0xCC,0xF8,0xEF,0xB0,0x04,0x00,0x00,0x90,0x59,0x70,0x3C,0x10,0x59,0x4B,0xC2,0x7B, -0x43,0xA0,0x01,0x2C,0xCC,0xFC,0xAF,0x17,0x08,0x84,0x40,0x59,0x70,0x2C,0x5C,0x7F, -0x76,0xC4,0x00,0x00,0x28,0x40,0x7F,0x0F,0xD0,0x03,0x59,0x40,0x80,0x80,0x60,0x1D, -0x00,0x02,0x70,0x7B,0x1F,0x2C,0x5C,0xAF,0x27,0x00,0xD0,0x03,0x59,0x41,0x84,0x40, -0x81,0x5C,0x1D,0x00,0x02,0x70,0xD0,0x03,0x59,0x40,0x84,0x01,0x80,0x60,0x1D,0x00, -0x02,0x70,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x70,0x10,0x49,0x9C,0x4F, -0x00,0x00,0x00,0x00,0x4C,0x80,0x7F,0x00,0x2C,0x00,0x02,0x70,0x2C,0x5C,0xAF,0x10, -0x00,0x7B,0x02,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x10,0x49,0x9C,0x4F, -0x48,0x00,0x00,0x00,0x4C,0x80,0x6C,0x70,0x83,0xC9,0x20,0x70,0x84,0x7F,0xB4,0x13, -0x00,0x02,0x7F,0xB8,0x13,0x00,0x02,0x70,0x2C,0x5C,0x7F,0xF6,0xC3,0x00,0x00,0xA0, -0x40,0x2C,0xCC,0xFC,0x7F,0xA2,0xC4,0x00,0x00,0x28,0x40,0x7F,0x0E,0xA0,0x5F,0x20, -0x20,0x2C,0xCC,0xFC,0x7F,0xEA,0xC1,0x00,0x00,0x24,0x7F,0x13,0xCB,0x00,0x00,0x87, -0xEF,0xCC,0x13,0x00,0x02,0xE0,0x40,0x24,0x7F,0xE5,0xCA,0x00,0x00,0x90,0x7F,0xCC, -0x13,0x00,0x02,0x70,0x87,0xEF,0xCC,0x13,0x00,0x02,0xE0,0x40,0x24,0x7F,0xF0,0xC7, -0x00,0x00,0x90,0x7F,0xCC,0x13,0x00,0x02,0x70,0x2C,0x5C,0xAF,0xE1,0x04,0x24,0x7F, -0x9A,0xC7,0x00,0x00,0x9C,0xEF,0xF8,0x1D,0x00,0x02,0x6C,0x70,0x24,0x7F,0xAD,0xC7, -0x00,0x00,0xDC,0x04,0x7F,0xF8,0x1D,0x00,0x02,0x40,0x9C,0x50,0x6C,0x70,0x24,0x7F, -0xAD,0xC7,0x00,0x00,0xDC,0x08,0x7F,0xF8,0x1D,0x00,0x02,0x40,0x9C,0x50,0x6C,0x70, -0x24,0x7F,0xAD,0xC7,0x00,0x00,0xDC,0x0C,0x7F,0xF8,0x1D,0x00,0x02,0x40,0x9C,0x50, -0x6C,0x70,0x24,0x7F,0xAD,0xC7,0x00,0x00,0xDC,0x10,0x7F,0xF8,0x1D,0x00,0x02,0x40, -0x9C,0x50,0x6C,0x70,0x24,0x7F,0xAD,0xC7,0x00,0x00,0xDC,0x14,0x7F,0xF8,0x1D,0x00, -0x02,0x40,0x9C,0x50,0x6C,0x70,0x24,0x7F,0xAD,0xC7,0x00,0x00,0xDC,0x18,0x7F,0xF8, -0x1D,0x00,0x02,0x40,0x9C,0x50,0x6C,0x70,0x24,0x7F,0xAD,0xC7,0x00,0x00,0xDC,0x1C, -0x7F,0xF8,0x1D,0x00,0x02,0x40,0x9C,0x50,0x6C,0x70,0x24,0x7F,0xAD,0xC7,0x00,0x00, -0xDC,0x20,0x7F,0xF8,0x1D,0x00,0x02,0x40,0x9C,0x50,0x6C,0x70,0x24,0x7F,0xAD,0xC7, -0x00,0x00,0xDC,0x24,0x7F,0xF8,0x1D,0x00,0x02,0x40,0x9C,0x50,0x6C,0x70,0x24,0x7F, -0xAD,0xC7,0x00,0x00,0xDC,0x28,0x7F,0xF8,0x1D,0x00,0x02,0x40,0x9C,0x50,0x6C,0x70, -0x7B,0x7D,0xDC,0x2C,0x7F,0xF8,0x1D,0x00,0x02,0x40,0x9C,0x50,0x6C,0x70,0x7B,0x6F, -0xDC,0x30,0x7F,0xF8,0x1D,0x00,0x02,0x40,0x9C,0x50,0x6C,0x70,0x7B,0x61,0xDC,0x34, -0x7F,0xF8,0x1D,0x00,0x02,0x40,0x9C,0x50,0x6C,0x70,0x7B,0x53,0xDC,0x38,0x7F,0xF8, -0x1D,0x00,0x02,0x40,0x9C,0x50,0x6C,0x70,0x7B,0x45,0xDC,0x3C,0x7F,0xF8,0x1D,0x00, -0x02,0x40,0x9C,0x50,0x6C,0x70,0x7B,0x37,0x9C,0x7F,0xFC,0x1D,0x00,0x02,0x6C,0x70, -0x7B,0x2D,0x9C,0x7F,0x08,0x1E,0x00,0x02,0x6C,0x70,0x7B,0x23,0xA0,0x5F,0x20,0x50, -0x2C,0xCC,0xFC,0x7F,0xEA,0xC1,0x00,0x00,0x7B,0x15,0x3C,0x11,0x40,0x47,0xEF,0xC0, -0x02,0x40,0x40,0x28,0x40,0x4B,0xE7,0x24,0x90,0xDC,0x26,0x00,0x00,0x7B,0x77,0x90, -0x7F,0xCC,0x13,0x00,0x02,0x70,0x84,0x01,0x7F,0xB8,0x13,0x00,0x02,0x70,0x7B,0x66, -0x90,0x7F,0xCC,0x13,0x00,0x02,0x70,0x80,0x7F,0xB8,0x13,0x00,0x02,0x70,0x7B,0x56, -0x90,0x7F,0xCC,0x13,0x00,0x02,0x70,0x2C,0x5C,0xAF,0xC9,0x06,0x9C,0x40,0x6C,0x70, -0x7B,0x44,0xA0,0x5F,0x20,0x50,0x2C,0xCC,0xFC,0x7F,0xEA,0xC1,0x00,0x00,0x7B,0x36, -0x3C,0x40,0x6F,0x44,0x7F,0xDC,0x3C,0x40,0x6F,0x50,0x7F,0xC6,0x3C,0x40,0x6F,0x52, -0x7E,0x62,0xFE,0x3C,0x40,0x6F,0x56,0x7F,0xA8,0x3C,0x40,0x6F,0x64,0x7F,0xC3,0x3C, -0x40,0x6F,0x70,0x7F,0xAD,0x3C,0x40,0x6F,0x72,0x7E,0x49,0xFE,0x3C,0x40,0x6F,0x76, -0x7F,0x8F,0x7B,0xC0,0x24,0x7F,0x13,0xCB,0x00,0x00,0x90,0x7F,0xCC,0x13,0x00,0x02, -0x70,0x3F,0x3E,0xEF,0xCC,0x13,0x00,0x02,0x77,0x19,0x90,0x7F,0xCC,0x13,0x00,0x02, -0x70,0xA0,0x6C,0x2C,0xCC,0xFC,0x7F,0xA0,0xDA,0x00,0x00,0x84,0x40,0x6C,0x70,0x7B, -0x0E,0xA0,0x5F,0x20,0x50,0x2C,0xCC,0xFC,0x7F,0xEA,0xC1,0x00,0x00,0x24,0x7F,0x13, -0xCB,0x00,0x00,0x90,0x7F,0xCC,0x13,0x00,0x02,0x70,0x24,0x7F,0x13,0xCB,0x00,0x00, -0x90,0x7F,0xCC,0x13,0x00,0x02,0x70,0x2C,0x5C,0xAF,0x85,0xFD,0x84,0x40,0xC9,0x10, -0x70,0xA0,0xC9,0x10,0x2C,0xCC,0xFC,0x7F,0xA0,0xDA,0x00,0x00,0x9C,0x40,0x6C,0x70, -0x24,0x7F,0x13,0xCB,0x00,0x00,0x90,0x7F,0xCC,0x13,0x00,0x02,0x70,0x90,0x7F,0x00, -0x2C,0x00,0x02,0x70,0x2C,0x5C,0xAF,0x58,0xFD,0x9C,0x40,0x6C,0x70,0x24,0x7F,0x13, -0xCB,0x00,0x00,0x28,0x7F,0x00,0x2C,0x00,0x02,0x4F,0x19,0x90,0x7F,0xCC,0x13,0x00, -0x02,0x70,0x94,0x7F,0x00,0x2C,0x00,0x02,0x70,0x84,0x6C,0x40,0x24,0x7F,0x43,0xCB, -0x00,0x00,0xA0,0x5F,0x20,0x50,0x2C,0xCC,0xFC,0x7F,0xEA,0xC1,0x00,0x00,0x90,0x7F, -0xCC,0x13,0x00,0x02,0x70,0x2C,0x5C,0xAF,0xBB,0x05,0x84,0x40,0x64,0x70,0x3F,0x6F, -0x5D,0xEF,0xCC,0x13,0x00,0x02,0x77,0x0B,0x90,0x7F,0xCC,0x13,0x00,0x02,0x70,0x7B, -0x0E,0xA0,0x5F,0x20,0x50,0x2C,0xCC,0xFC,0x7F,0xEA,0xC1,0x00,0x00,0xE0,0xC9,0x20, -0xA0,0x4F,0x4B,0x27,0x00,0x00,0x2C,0xCC,0xF8,0x7F,0x2C,0xEA,0x00,0x00,0xA0,0x40, -0x2C,0xCC,0xFC,0xAF,0xDC,0x06,0x84,0x40,0x68,0x70,0x28,0x7F,0x04,0x2C,0x00,0x02, -0x7F,0x0C,0xE8,0x64,0x68,0x40,0x9C,0x40,0x6C,0x70,0x7B,0x0E,0xA0,0x5F,0x20,0x50, -0x2C,0xCC,0xFC,0x7F,0xEA,0xC1,0x00,0x00,0x24,0x7F,0x13,0xCB,0x00,0x00,0x80,0xC9, -0x14,0x70,0x84,0x7F,0xCC,0x13,0x00,0x02,0x59,0x70,0x7B,0x2D,0x3C,0x27,0xC9,0x14, -0x77,0x0E,0xA0,0x5F,0x20,0x50,0x2C,0xCC,0xFC,0x7F,0xEA,0xC1,0x00,0x00,0x04,0xC9, -0x20,0x40,0x84,0xC9,0x14,0x41,0x90,0xC9,0x14,0x70,0x9C,0x41,0x40,0x84,0x59,0x41, -0x90,0x59,0x70,0x87,0x51,0x50,0x70,0x87,0xD9,0x00,0xE0,0x40,0xA0,0x40,0x2C,0xCC, -0xFC,0xAF,0x26,0x03,0x28,0x40,0x77,0x15,0x87,0xD9,0x00,0xE0,0x40,0xA0,0x40,0x2C, -0xCC,0xFC,0x7F,0xA2,0xC4,0x00,0x00,0x28,0x40,0x7F,0xB3,0x04,0xC9,0x20,0x40,0x9C, -0xC9,0x14,0x40,0x83,0x50,0x70,0xE0,0xC9,0x20,0x2C,0xCC,0xFC,0xAF,0x43,0x06,0x84, -0x40,0xC9,0x14,0x70,0x28,0x7F,0x04,0x2C,0x00,0x02,0x7F,0x23,0x84,0x59,0x7F,0xCC, -0x13,0x00,0x02,0x70,0x9C,0xC9,0x14,0x6C,0x70,0x3F,0x6F,0x5B,0xEF,0xCC,0x13,0x00, -0x02,0x7F,0x06,0x83,0xC9,0x20,0x70,0x24,0x7F,0x13,0xCB,0x00,0x00,0x87,0xEF,0xCC, -0x13,0x00,0x02,0xE0,0x40,0xA0,0x40,0x2C,0xCC,0xFC,0xAF,0x79,0x05,0x84,0x40,0xC9, -0x14,0x70,0x43,0x0E,0xA0,0x5F,0x20,0x50,0x2C,0xCC,0xFC,0x7F,0xEA,0xC1,0x00,0x00, -0xDC,0x01,0x7F,0xCC,0x13,0x00,0x02,0x40,0x3F,0x2E,0x50,0x77,0x37,0x90,0x7F,0xCC, -0x13,0x00,0x02,0x70,0xD0,0x03,0xC9,0x14,0x40,0x28,0x80,0x60,0x1D,0x00,0x02,0x7F, -0x11,0xD0,0x03,0xC9,0x14,0x40,0x9C,0x80,0x5C,0x1D,0x00,0x02,0x6C,0x70,0x7B,0x0E, -0xA0,0x5F,0x80,0x50,0x2C,0xCC,0xFC,0x7F,0xEA,0xC1,0x00,0x00,0x24,0x7F,0x13,0xCB, -0x00,0x00,0x84,0xC9,0x14,0xC9,0x1C,0x70,0x84,0x01,0xC9,0x18,0x70,0x90,0x7F,0xCC, -0x13,0x00,0x02,0x70,0x7B,0x50,0x87,0xEF,0xCC,0x13,0x00,0x02,0xE0,0x40,0xA0,0x40, -0x2C,0xCC,0xFC,0xAF,0x00,0x05,0x84,0x40,0xC9,0x14,0x70,0x43,0x0E,0xA0,0x5F,0x20, -0x50,0x2C,0xCC,0xFC,0x7F,0xEA,0xC1,0x00,0x00,0x3C,0x08,0xC9,0x18,0x4B,0x0E,0xA0, -0x5F,0x20,0x30,0x2C,0xCC,0xFC,0x7F,0xEA,0xC1,0x00,0x00,0xD0,0x04,0xC9,0x1C,0x40, -0x9C,0xC9,0x14,0x40,0x84,0x40,0xC9,0x1C,0x70,0x90,0xC9,0x18,0x70,0x90,0x7F,0xCC, -0x13,0x00,0x02,0x70,0x87,0xEF,0xCC,0x13,0x00,0x02,0xE0,0x40,0xA0,0x40,0x2C,0xCC, -0xFC,0xAF,0xF6,0x01,0x28,0x40,0x77,0x18,0x87,0xEF,0xCC,0x13,0x00,0x02,0xE0,0x40, -0xA0,0x40,0x2C,0xCC,0xFC,0x7F,0xA2,0xC4,0x00,0x00,0x28,0x40,0x7F,0x8A,0x9C,0xC9, -0x1C,0x6C,0x70,0x7B,0x30,0x3C,0x40,0x28,0x7E,0xAE,0xFD,0x3C,0x40,0x29,0x7E,0xC5, -0xFD,0x3C,0x40,0x2A,0x7E,0x7C,0xFD,0x3C,0x40,0x2D,0x7E,0x30,0xFD,0x3C,0x40,0x2E, -0x7E,0x63,0xFD,0x3C,0x40,0x2F,0x7E,0x47,0xFB,0x3C,0x40,0x6F,0x5B,0x7E,0xD1,0xFD, -0x7A,0x3E,0xFE,0x87,0xEF,0xCC,0x13,0x00,0x02,0xE0,0x40,0xA0,0x40,0x2C,0xCC,0xFC, -0x7F,0xA2,0xC4,0x00,0x00,0x28,0x40,0x7E,0x18,0xFB,0x28,0x7F,0x00,0x2C,0x00,0x02, -0x4F,0x0E,0xA0,0x5F,0x20,0x50,0x2C,0xCC,0xFC,0x7F,0xEA,0xC1,0x00,0x00,0x84,0x6C, -0x40,0x7B,0x02,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x10,0x47,0x9C,0x4F,0x08,0x00, -0x00,0x00,0x4C,0x2C,0x5C,0x7F,0xF6,0xC3,0x00,0x00,0x87,0xEF,0xCC,0x13,0x00,0x02, -0xE0,0x40,0xA0,0x40,0x2C,0xCC,0xFC,0x7F,0xA2,0xC4,0x00,0x00,0x28,0x40,0x77,0x16, -0x87,0xEF,0xCC,0x13,0x00,0x02,0xE0,0x40,0xA0,0x40,0x2C,0xCC,0xFC,0xAF,0x3A,0x01, -0x28,0x40,0x7F,0x07,0x84,0xFF,0x40,0x7B,0x52,0x80,0x48,0xE0,0x59,0xA0,0x05,0x2C, -0xCC,0xF8,0xAF,0x55,0x00,0x7B,0x04,0x90,0x48,0x3C,0x11,0x48,0x47,0x26,0xD0,0x03, -0x48,0x40,0xA0,0x80,0x78,0x14,0x00,0x00,0xE0,0x59,0x2C,0xCC,0xF8,0x7F,0xE4,0xE9, -0x00,0x00,0x28,0x40,0x7F,0x07,0x84,0x01,0x40,0x7B,0x04,0x80,0x40,0x84,0x40,0x47, -0x77,0xD7,0x3C,0x11,0x48,0x4F,0x07,0x84,0xFF,0x40,0x7B,0x0F,0xD0,0x03,0x48,0x40, -0x84,0x80,0x7C,0x14,0x00,0x00,0x40,0x7B,0x02,0x04,0xC9,0xF0,0x4C,0x20,0x48,0x20, -0x47,0x20,0x49,0x08,0x10,0x47,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0xFC,0x01,0x74, -0x40,0x70,0x84,0x40,0x47,0x80,0x48,0x7B,0x1C,0x84,0x48,0x40,0x90,0x48,0x9C,0x5A, -0x40,0x84,0x7F,0xCC,0x13,0x00,0x02,0x41,0x90,0x7F,0xCC,0x13,0x00,0x02,0x70,0x87, -0x51,0x50,0x70,0x3C,0x47,0x48,0x43,0x2C,0x87,0xEF,0xCC,0x13,0x00,0x02,0xE0,0x40, -0xA0,0x40,0x2C,0xCC,0xFC,0x7F,0xA2,0xC4,0x00,0x00,0x28,0x40,0x77,0x16,0x87,0xEF, -0xCC,0x13,0x00,0x02,0xE0,0x40,0xA0,0x40,0x2C,0xCC,0xFC,0xAF,0x7C,0x00,0x28,0x40, -0x7F,0xB9,0xDC,0x48,0x5A,0x40,0x83,0x50,0x70,0xA0,0x5A,0x2C,0xCC,0xFC,0xAF,0x13, -0x00,0x04,0xC9,0xF0,0x4C,0x20,0x48,0x20,0x47,0x20,0x49,0x08,0x70,0x70,0x10,0x49, -0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x7B,0x1F,0x3F,0x6F,0x61,0xDA,0x00,0x4B,0x15, -0x3F,0x6F,0x7A,0xDA,0x00,0x47,0x0E,0xFB,0x5F,0xDF,0x00,0xDA,0x00,0x40,0x87,0x40, -0xDA,0x00,0x70,0x90,0x5A,0x70,0x87,0xDA,0x00,0xE0,0x40,0xA0,0x40,0x2C,0xCC,0xFC, -0x7F,0xA2,0xC4,0x00,0x00,0x28,0x40,0x77,0x13,0x87,0xDA,0x00,0xE0,0x40,0xA0,0x40, -0x2C,0xCC,0xFC,0xAF,0x14,0x00,0x28,0x40,0x7F,0xC1,0x04,0xC9,0xE8,0x4C,0x20,0x49, -0x08,0x70,0x70,0x70,0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x3F,0x2E,0x73, -0x7F,0x17,0x3F,0x6F,0x5B,0x73,0x7F,0x11,0x3F,0x28,0x73,0x7F,0x0C,0x3F,0x29,0x73, -0x7F,0x07,0x3F,0x2D,0x73,0x77,0x07,0x84,0x01,0x40,0x7B,0x06,0x80,0x40,0x7B,0x02, -0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x10,0x49,0x9C,0x4F,0x08,0x00,0x00,0x00, -0x4C,0x3F,0x27,0xEF,0xCC,0x13,0x00,0x02,0x7F,0x11,0x3F,0x22,0xEF,0xCC,0x13,0x00, -0x02,0x7F,0x08,0x24,0x7F,0x92,0xCD,0x00,0x00,0x80,0x64,0x70,0x84,0x7F,0xCC,0x13, -0x00,0x02,0x40,0x90,0x7F,0xCC,0x13,0x00,0x02,0x70,0x87,0x50,0x59,0x70,0x7B,0x4C, -0x3F,0x59,0xEF,0xCC,0x13,0x00,0x02,0x77,0x10,0xA0,0x5F,0x00,0x51,0x2C,0xCC,0xFC, -0x7F,0xEA,0xC1,0x00,0x00,0x7B,0x35,0x2B,0xEF,0xCC,0x13,0x00,0x02,0x77,0x10,0xA0, -0x5F,0xF0,0x40,0x2C,0xCC,0xFC,0x7F,0xEA,0xC1,0x00,0x00,0x7B,0x1F,0xD0,0x08,0x64, -0x40,0x84,0x7F,0xCC,0x13,0x00,0x02,0x41,0x90,0x7F,0xCC,0x13,0x00,0x02,0x70,0x87, -0x51,0xE0,0x41,0x9C,0x41,0x40,0x84,0x40,0x64,0x70,0x84,0x5A,0x40,0x94,0x5A,0x70, -0x28,0x40,0x47,0xAE,0x3F,0x59,0xEF,0xCC,0x13,0x00,0x02,0x7F,0x0E,0xA0,0x5F,0x00, -0x31,0x2C,0xCC,0xFC,0x7F,0xEA,0xC1,0x00,0x00,0x90,0x7F,0xCC,0x13,0x00,0x02,0x70, -0x7B,0x0B,0x2C,0x5C,0xAF,0x4A,0xF8,0x84,0x40,0x64,0x70,0x84,0x64,0x40,0x7B,0x02, -0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x70,0x10,0x49,0x9C,0x4F,0x0C,0x00, -0x00,0x00,0x4C,0x80,0x64,0x70,0x80,0x68,0x70,0x7B,0x4D,0x87,0xEF,0xCC,0x13,0x00, -0x02,0xE0,0x40,0xA0,0x40,0x2C,0xCC,0xFC,0xAF,0xAB,0x01,0x84,0x40,0x59,0x70,0x3C, -0xFF,0x40,0x77,0x0E,0xA0,0x5F,0x40,0x50,0x2C,0xCC,0xFC,0x7F,0xEA,0xC1,0x00,0x00, -0xD0,0x04,0x68,0x40,0x9C,0x59,0x40,0x84,0x40,0x68,0x70,0x90,0x7F,0xCC,0x13,0x00, -0x02,0x70,0x90,0x64,0x70,0x3C,0x5A,0x64,0x4F,0x0E,0xA0,0x5F,0x40,0x30,0x2C,0xCC, -0xFC,0x7F,0xEA,0xC1,0x00,0x00,0x87,0xEF,0xCC,0x13,0x00,0x02,0xE0,0x40,0xA0,0x40, -0x2C,0xCC,0xFC,0x7F,0xA2,0xC4,0x00,0x00,0x28,0x40,0x7F,0xA1,0x84,0x68,0x40,0x7B, -0x02,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x10,0x49,0x9C,0x4F,0x0C,0x00,0x00,0x00, -0x4C,0x80,0x64,0x70,0x80,0x68,0x70,0x7B,0x46,0x87,0xEF,0xCC,0x13,0x00,0x02,0xE0, -0x40,0xA0,0x40,0x2C,0xCC,0xFC,0xAF,0x2D,0x01,0x84,0x40,0x59,0x70,0x3C,0xFF,0x40, -0x77,0x07,0x84,0x68,0x40,0x7B,0x43,0xD0,0x04,0x68,0x40,0x9C,0x59,0x40,0x84,0x40, -0x68,0x70,0x90,0x7F,0xCC,0x13,0x00,0x02,0x70,0x90,0x64,0x70,0x3C,0x5A,0x64,0x4F, -0x0E,0xA0,0x5F,0x40,0x30,0x2C,0xCC,0xFC,0x7F,0xEA,0xC1,0x00,0x00,0x87,0xEF,0xCC, -0x13,0x00,0x02,0xE0,0x40,0xA0,0x40,0x2C,0xCC,0xFC,0x7F,0xA2,0xC4,0x00,0x00,0x28, -0x40,0x7F,0xA8,0x84,0x68,0x40,0x7B,0x02,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70, -0x10,0x49,0x9C,0x4F,0x0C,0x00,0x00,0x00,0x4C,0x2C,0x5C,0x7F,0xF6,0xC3,0x00,0x00, -0xA0,0x40,0x2C,0xCC,0xFC,0x7F,0xA2,0xC4,0x00,0x00,0x28,0x40,0x7F,0x0E,0xA0,0x5F, -0x50,0x20,0x2C,0xCC,0xFC,0x7F,0xEA,0xC1,0x00,0x00,0x80,0x64,0x70,0x80,0x68,0x70, -0x7B,0x4D,0x87,0xEF,0xCC,0x13,0x00,0x02,0xE0,0x40,0xA0,0x40,0x2C,0xCC,0xFC,0xAF, -0xE0,0x00,0x84,0x40,0x59,0x70,0x3C,0xFF,0x40,0x77,0x0E,0xA0,0x5F,0x50,0x50,0x2C, -0xCC,0xFC,0x7F,0xEA,0xC1,0x00,0x00,0xE8,0x0A,0x68,0x40,0x9C,0x59,0x40,0x84,0x40, -0x68,0x70,0x90,0x7F,0xCC,0x13,0x00,0x02,0x70,0x90,0x64,0x70,0x3C,0x0A,0x64,0x4F, -0x0E,0xA0,0x5F,0x50,0x30,0x2C,0xCC,0xFC,0x7F,0xEA,0xC1,0x00,0x00,0x87,0xEF,0xCC, -0x13,0x00,0x02,0xE0,0x40,0xA0,0x40,0x2C,0xCC,0xFC,0x7F,0xA2,0xC4,0x00,0x00,0x28, -0x40,0x77,0x32,0x3F,0x2F,0xEF,0xCC,0x13,0x00,0x02,0x7F,0x29,0x3F,0x2E,0xEF,0xCC, -0x13,0x00,0x02,0x7F,0x20,0x3F,0x6F,0x5B,0xEF,0xCC,0x13,0x00,0x02,0x7F,0x16,0x3F, -0x28,0xEF,0xCC,0x13,0x00,0x02,0x7F,0x0D,0x3F,0x6F,0x5D,0xEF,0xCC,0x13,0x00,0x02, -0x76,0x72,0xFF,0x84,0x68,0x40,0x7B,0x02,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70, -0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x3F,0x30,0x73,0x4B,0x0D,0x3F,0x39, -0x73,0x47,0x08,0xFF,0x30,0x73,0x40,0x7B,0x2C,0x3F,0x6F,0x61,0x73,0x4B,0x0F,0x3F, -0x6F,0x66,0x73,0x47,0x09,0xFF,0x6F,0x57,0x73,0x40,0x7B,0x19,0x3F,0x6F,0x41,0x73, -0x4B,0x0E,0x3F,0x6F,0x46,0x73,0x47,0x08,0xFF,0x37,0x73,0x40,0x7B,0x07,0x84,0xFF, -0x40,0x7B,0x02,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x10,0x49,0x9C,0x4F, -0x00,0x00,0x00,0x00,0x4C,0x3F,0x30,0x73,0x4B,0x0D,0x3F,0x39,0x73,0x47,0x08,0xFF, -0x30,0x73,0x40,0x7B,0x07,0x84,0xFF,0x40,0x7B,0x02,0x04,0xC9,0xE8,0x4C,0x20,0x49, -0x08,0x70,0x70,0x70,0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x84,0x5A,0x7F, -0x08,0x2C,0x00,0x02,0x70,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x10,0x48,0x9C,0x4F, -0x0C,0x00,0x00,0x00,0x4C,0x28,0x7F,0x08,0x2C,0x00,0x02,0x77,0x0E,0xE4,0x04,0x7F, -0x08,0x2C,0x00,0x02,0x40,0x7F,0x04,0x7B,0x75,0xDC,0x08,0x7F,0x08,0x2C,0x00,0x02, -0x40,0x70,0x84,0x40,0x48,0xDC,0xEF,0x08,0x2C,0x00,0x02,0x7F,0x08,0x2C,0x00,0x02, -0x40,0x84,0x40,0x59,0x70,0x7B,0x52,0xA0,0x48,0x2C,0xCC,0xFC,0x7F,0x14,0xEA,0x00, -0x00,0x90,0x40,0x84,0x40,0x68,0x70,0xDC,0x03,0x68,0x40,0xAC,0x04,0x40,0x84,0x40, -0x68,0x70,0xD0,0x02,0x68,0x40,0x84,0x40,0x68,0x70,0xDC,0x68,0x48,0x40,0x84,0x40, -0x64,0x70,0xA0,0x5A,0xA0,0x48,0x2C,0xCC,0xF8,0x7F,0xE4,0xE9,0x00,0x00,0x28,0x40, -0x77,0x10,0x84,0x01,0x7F,0x04,0x2C,0x00,0x02,0x70,0x84,0xD9,0x04,0x40,0x7B,0x15, -0xDC,0x04,0x68,0x40,0x9C,0x40,0x48,0x3C,0x59,0x48,0x5B,0xAD,0x80,0x7F,0x04,0x2C, -0x00,0x02,0x70,0x04,0xC9,0xEC,0x4C,0x20,0x48,0x20,0x49,0x08,0x10,0x48,0x9C,0x4F, -0x18,0x00,0x00,0x00,0x4C,0x84,0x4F,0xFF,0xFF,0xFF,0x8F,0x68,0x70,0x80,0x6C,0x70, -0x28,0x7F,0x08,0x2C,0x00,0x02,0x7F,0x0C,0xE4,0x04,0x7F,0x08,0x2C,0x00,0x02,0x40, -0x7F,0x16,0xA0,0x4F,0x4E,0x27,0x00,0x00,0x2C,0xCC,0xFC,0xEF,0xB0,0x04,0x00,0x00, -0x24,0x7F,0x91,0xD1,0x00,0x00,0x28,0x5A,0x77,0x0E,0x2C,0x5C,0xAF,0x02,0xF5,0x84, -0x40,0xC9,0x10,0x70,0x7B,0x07,0x84,0x5A,0xC9,0x10,0x70,0xDC,0x08,0x7F,0x08,0x2C, -0x00,0x02,0x40,0x70,0x84,0x40,0x48,0xDC,0xEF,0x08,0x2C,0x00,0x02,0x7F,0x08,0x2C, -0x00,0x02,0x40,0x84,0x40,0x59,0x70,0x7B,0x5B,0xA0,0x48,0x2C,0xCC,0xFC,0x7F,0x14, -0xEA,0x00,0x00,0x90,0x40,0x84,0x40,0xC9,0x14,0x70,0xDC,0x03,0xC9,0x14,0x40,0xAC, -0x04,0x40,0x84,0x40,0xC9,0x14,0x70,0xD0,0x02,0xC9,0x14,0x40,0x84,0x40,0xC9,0x14, -0x70,0xDC,0xC9,0x14,0x48,0x40,0x84,0x40,0x64,0x70,0x3C,0xC9,0x10,0xD9,0x04,0x57, -0x1B,0xFC,0xD9,0x04,0xC9,0x10,0x40,0x3C,0x40,0x68,0x5F,0x10,0xFC,0xD9,0x04,0xC9, -0x10,0x40,0x84,0x40,0x68,0x70,0x84,0x48,0x6C,0x70,0xDC,0x04,0xC9,0x14,0x40,0x9C, -0x40,0x48,0x3C,0x59,0x48,0x5B,0xA4,0x28,0x6C,0x7F,0x28,0xA0,0x4F,0x5B,0x27,0x00, -0x00,0xA0,0x6C,0xA0,0x68,0x2C,0xCC,0xF4,0xEF,0xB0,0x04,0x00,0x00,0x28,0x5A,0x77, -0x10,0xA0,0x4F,0x65,0x27,0x00,0x00,0x2C,0xCC,0xFC,0xEF,0xB0,0x04,0x00,0x00,0x7B, -0x0E,0xA0,0x5F,0x20,0x50,0x2C,0xCC,0xFC,0x7F,0xEA,0xC1,0x00,0x00,0x04,0xC9,0xEC, -0x4C,0x20,0x48,0x20,0x49,0x08,0x70,0x70,0x10,0x48,0x9C,0x4F,0x00,0x00,0x00,0x00, -0x4C,0x80,0x48,0x7B,0x3C,0xA0,0x4F,0x68,0x27,0x00,0x00,0xD0,0x02,0x48,0x40,0xA0, -0x80,0x2C,0x14,0x00,0x00,0xD0,0x02,0x48,0x40,0x9C,0x7F,0xF8,0x1D,0x00,0x02,0x40, -0xA0,0x50,0xDC,0x01,0x48,0x40,0xA4,0x05,0x40,0x7F,0x07,0x84,0x20,0x40,0x7B,0x05, -0x84,0x0A,0x40,0xA0,0x40,0x2C,0xCC,0xF0,0xEF,0xB0,0x04,0x00,0x00,0x90,0x48,0x3C, -0x0F,0x48,0x4F,0xC3,0xA0,0x4F,0x71,0x27,0x00,0x00,0xA0,0x7F,0x70,0x14,0x00,0x00, -0xA0,0x7F,0xFC,0x1D,0x00,0x02,0xA0,0x7F,0x74,0x14,0x00,0x00,0xA0,0x7F,0x08,0x1E, -0x00,0x02,0x2C,0xCC,0xEC,0xEF,0xB0,0x04,0x00,0x00,0xA0,0x4F,0x83,0x27,0x00,0x00, -0x2C,0xCC,0xFC,0xEF,0xB0,0x04,0x00,0x00,0x04,0xC9,0xEC,0x4C,0x20,0x48,0x20,0x49, -0x08,0x70,0x70,0x70,0x10,0x48,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x28,0x7F,0x10, -0x1E,0x00,0x02,0x77,0x0E,0xA0,0x5F,0x70,0x70,0x2C,0xCC,0xFC,0x7F,0xEA,0xC1,0x00, -0x00,0x84,0x7F,0x10,0x1E,0x00,0x02,0x7F,0xFC,0x1D,0x00,0x02,0x70,0xA0,0x7F,0xFC, -0x1D,0x00,0x02,0x2C,0xCC,0xFC,0x7F,0x6C,0xD7,0x00,0x00,0x84,0x40,0x7F,0xF8,0x1D, -0x00,0x02,0x70,0x84,0x7F,0x0C,0x1E,0x00,0x02,0x7F,0x08,0x1E,0x00,0x02,0x70,0x2C, -0x5C,0xAF,0xEB,0x00,0x2C,0x5C,0xAF,0x24,0xFF,0x04,0xC9,0xEC,0x4C,0x20,0x48,0x20, -0x49,0x08,0x70,0x70,0x10,0x48,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x84,0x7F,0xFC, -0x1D,0x00,0x02,0x7F,0x14,0x1E,0x00,0x02,0x70,0x84,0x7F,0xF8,0x1D,0x00,0x02,0x7F, -0x10,0x1E,0x00,0x02,0x70,0x84,0x7F,0x08,0x1E,0x00,0x02,0x7F,0x0C,0x1E,0x00,0x02, -0x70,0x80,0x48,0x7B,0x1B,0xD0,0x02,0x48,0x40,0xD0,0x02,0x48,0x41,0x9C,0x7F,0xF8, -0x1D,0x00,0x02,0x41,0x84,0x51,0x80,0xC8,0x12,0x00,0x02,0x70,0x90,0x48,0x3C,0x0F, -0x48,0x4F,0xE4,0x04,0xC9,0xEC,0x4C,0x20,0x48,0x20,0x49,0x08,0x10,0x48,0x9C,0x4F, -0x00,0x00,0x00,0x00,0x4C,0x80,0x48,0x7B,0x1B,0xD0,0x02,0x48,0x40,0xD0,0x02,0x48, -0x41,0x9C,0x7F,0xF8,0x1D,0x00,0x02,0x41,0x84,0x51,0x80,0x1C,0x13,0x00,0x02,0x70, -0x90,0x48,0x3C,0x0F,0x48,0x4F,0xE4,0x84,0x4F,0x1C,0x13,0x00,0x02,0x7F,0xFC,0x1D, -0x00,0x02,0x70,0xA0,0x7F,0xFC,0x1D,0x00,0x02,0x2C,0xCC,0xFC,0x7F,0x6C,0xD7,0x00, -0x00,0x84,0x40,0x7F,0xF8,0x1D,0x00,0x02,0x70,0x04,0xC9,0xEC,0x4C,0x20,0x48,0x20, -0x49,0x08,0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x84,0x7F,0x14,0x1E,0x00, -0x02,0x7F,0xFC,0x1D,0x00,0x02,0x70,0x84,0x7F,0x10,0x1E,0x00,0x02,0x7F,0xF8,0x1D, -0x00,0x02,0x70,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x10,0x48,0x9C,0x4F,0x00,0x00, -0x00,0x00,0x4C,0x84,0x7F,0x14,0x1E,0x00,0x02,0x7F,0xFC,0x1D,0x00,0x02,0x70,0x84, -0x7F,0x0C,0x1E,0x00,0x02,0x7F,0x08,0x1E,0x00,0x02,0x70,0x80,0x48,0x7B,0x1B,0xD0, -0x02,0x48,0x40,0x9C,0x7F,0xF8,0x1D,0x00,0x02,0x40,0xD0,0x02,0x48,0x41,0x84,0x81, -0xC8,0x12,0x00,0x02,0x50,0x70,0x90,0x48,0x3C,0x0F,0x48,0x4F,0xE4,0x04,0xC9,0xEC, -0x4C,0x20,0x48,0x20,0x49,0x08,0x10,0x49,0x9C,0x4F,0x04,0x00,0x00,0x00,0x4C,0x2C, -0x5C,0x7F,0x76,0xC4,0x00,0x00,0x28,0x40,0x77,0x65,0x84,0x5A,0x40,0x7B,0x12,0xA0, -0x08,0x2C,0xCC,0xFC,0x7F,0xAA,0xCD,0x00,0x00,0x84,0x40,0x59,0x70,0x7B,0x04,0x7B, -0xF0,0x84,0x5A,0x40,0x7B,0x3D,0x84,0x59,0x7F,0xFC,0x1D,0x00,0x02,0x70,0xA0,0x7F, -0xFC,0x1D,0x00,0x02,0x2C,0xCC,0xFC,0x7F,0x6C,0xD7,0x00,0x00,0x84,0x40,0x7F,0xF8, -0x1D,0x00,0x02,0x70,0x7B,0x29,0x84,0x59,0x7F,0x08,0x1E,0x00,0x02,0x70,0x7B,0x1F, -0xD0,0x02,0x5A,0x40,0x9C,0x7F,0xF8,0x1D,0x00,0x02,0x40,0x84,0x59,0x50,0x70,0x7B, -0x0E,0x3C,0x40,0x11,0x7F,0xC2,0x3C,0x40,0x12,0x7F,0xDD,0x7B,0xE5,0xA0,0x4F,0x85, -0x27,0x00,0x00,0xD0,0x02,0x5A,0x40,0xA0,0x80,0x2C,0x14,0x00,0x00,0x2C,0xCC,0xF8, -0xEF,0xB0,0x04,0x00,0x00,0x84,0x5A,0x40,0x7B,0x4B,0xA0,0x4F,0x88,0x27,0x00,0x00, -0xA0,0x7F,0xFC,0x1D,0x00,0x02,0x2C,0xCC,0xF8,0xEF,0xB0,0x04,0x00,0x00,0x7B,0x41, -0xA0,0x4F,0x8C,0x27,0x00,0x00,0xA0,0x7F,0x08,0x1E,0x00,0x02,0x2C,0xCC,0xF8,0xEF, -0xB0,0x04,0x00,0x00,0x7B,0x2B,0xA0,0x4F,0x90,0x27,0x00,0x00,0xD0,0x02,0x5A,0x40, -0x9C,0x7F,0xF8,0x1D,0x00,0x02,0x40,0xA0,0x50,0x2C,0xCC,0xF8,0xEF,0xB0,0x04,0x00, -0x00,0x7B,0x0E,0x3C,0x40,0x11,0x7F,0xB4,0x3C,0x40,0x12,0x7F,0xC5,0x7B,0xD9,0x04, -0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x10,0x49,0x9C,0x4F,0x04,0x00,0x00,0x00, -0x4C,0x2C,0x5C,0x7F,0x76,0xC4,0x00,0x00,0x28,0x40,0x7F,0x47,0xA0,0x4F,0x94,0x27, -0x00,0x00,0x2C,0xCC,0xFC,0xEF,0xB0,0x04,0x00,0x00,0x80,0x59,0x70,0x7B,0x1F,0xA0, -0x4F,0x9B,0x27,0x00,0x00,0xA0,0x59,0xD0,0x02,0x59,0x40,0xA0,0x80,0x00,0x06,0x04, -0x00,0x2C,0xCC,0xF4,0xEF,0xB0,0x04,0x00,0x00,0x90,0x59,0x70,0x3C,0x04,0x59,0x4B, -0xE0,0xA0,0x4F,0xA6,0x27,0x00,0x00,0x2C,0xCC,0xFC,0xEF,0xB0,0x04,0x00,0x00,0x7B, -0x58,0x2C,0x5C,0x7F,0xA0,0xCE,0x00,0x00,0x84,0x40,0x59,0x70,0x4B,0x07,0x3C,0x03, -0x59,0x4F,0x0E,0xA0,0x5F,0x80,0x32,0x2C,0xCC,0xFC,0x7F,0xEA,0xC1,0x00,0x00,0x2C, -0x5C,0x7F,0x76,0xC4,0x00,0x00,0x28,0x40,0x77,0x15,0x2C,0x5C,0x7F,0xAA,0xCD,0x00, -0x00,0xD0,0x02,0x59,0x41,0x84,0x40,0x81,0x00,0x06,0x04,0x00,0x70,0xA0,0x4F,0xA8, -0x27,0x00,0x00,0xA0,0x59,0xD0,0x02,0x59,0x40,0xA0,0x80,0x00,0x06,0x04,0x00,0x2C, -0xCC,0xF4,0xEF,0xB0,0x04,0x00,0x00,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x10,0x49, -0x9C,0x4F,0x04,0x00,0x00,0x00,0x4C,0x2C,0x5C,0x7F,0x76,0xC4,0x00,0x00,0x28,0x40, -0x7F,0x47,0xA0,0x4F,0xB9,0x27,0x00,0x00,0x2C,0xCC,0xFC,0xEF,0xB0,0x04,0x00,0x00, -0x80,0x59,0x70,0x7B,0x1F,0xA0,0x4F,0xC0,0x27,0x00,0x00,0xA0,0x59,0xD0,0x02,0x59, -0x40,0xA0,0x80,0x00,0x07,0x04,0x00,0x2C,0xCC,0xF4,0xEF,0xB0,0x04,0x00,0x00,0x90, -0x59,0x70,0x3C,0x04,0x59,0x4B,0xE0,0xA0,0x4F,0xCB,0x27,0x00,0x00,0x2C,0xCC,0xFC, -0xEF,0xB0,0x04,0x00,0x00,0x7B,0x58,0x2C,0x5C,0x7F,0xA0,0xCE,0x00,0x00,0x84,0x40, -0x59,0x70,0x4B,0x07,0x3C,0x03,0x59,0x4F,0x0E,0xA0,0x5F,0x80,0x32,0x2C,0xCC,0xFC, -0x7F,0xEA,0xC1,0x00,0x00,0x2C,0x5C,0x7F,0x76,0xC4,0x00,0x00,0x28,0x40,0x77,0x15, -0x2C,0x5C,0x7F,0xAA,0xCD,0x00,0x00,0xD0,0x02,0x59,0x41,0x84,0x40,0x81,0x00,0x07, -0x04,0x00,0x70,0xA0,0x4F,0xCD,0x27,0x00,0x00,0xA0,0x59,0xD0,0x02,0x59,0x40,0xA0, -0x80,0x00,0x07,0x04,0x00,0x2C,0xCC,0xF4,0xEF,0xB0,0x04,0x00,0x00,0x04,0xC9,0xE8, -0x4C,0x20,0x49,0x08,0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x2C,0x5C,0x7F, -0xDC,0xC5,0x00,0x00,0x84,0x40,0xEF,0x00,0x0B,0x04,0x00,0x70,0x04,0xC9,0xE8,0x4C, -0x20,0x49,0x08,0x70,0x70,0x70,0x10,0x49,0x9C,0x4F,0x18,0x00,0x00,0x00,0x4C,0x2C, -0x5C,0x7F,0x76,0xC4,0x00,0x00,0x28,0x40,0x7F,0x08,0x84,0x14,0x64,0x70,0x7B,0x0D, -0x2C,0x5C,0x7F,0xA0,0xCE,0x00,0x00,0x84,0x40,0x64,0x70,0xDC,0x0C,0x7F,0xF8,0x1D, -0x00,0x02,0x40,0x84,0x50,0xC9,0x10,0x70,0xDC,0x18,0x7F,0xF8,0x1D,0x00,0x02,0x40, -0x84,0x50,0x68,0x70,0xDC,0x14,0x7F,0xF8,0x1D,0x00,0x02,0x40,0x84,0x50,0x59,0x70, -0xDC,0x08,0x7F,0xF8,0x1D,0x00,0x02,0x40,0x84,0x50,0xC9,0x14,0x70,0xDC,0x04,0x7F, -0xF8,0x1D,0x00,0x02,0x40,0x84,0x50,0x6C,0x70,0xA0,0x4F,0xDE,0x27,0x00,0x00,0xA0, -0xC9,0x14,0xA0,0x59,0xA0,0x68,0xA0,0x6C,0x2C,0xCC,0xEC,0xEF,0xB0,0x04,0x00,0x00, -0xA0,0x6C,0x2C,0xCC,0xFC,0x7F,0x9C,0xD0,0x00,0x00,0xA0,0x4F,0x14,0x28,0x00,0x00, -0x2C,0xCC,0xFC,0xEF,0xB0,0x04,0x00,0x00,0x24,0x7F,0x57,0xD7,0x00,0x00,0xFC,0x24, -0x68,0x40,0x3C,0xC9,0x10,0x40,0x43,0x15,0xA0,0x4F,0x16,0x28,0x00,0x00,0x2C,0xCC, -0xFC,0xEF,0xB0,0x04,0x00,0x00,0x80,0x64,0x70,0x7B,0x6E,0x84,0x59,0xC9,0x14,0x70, -0xFC,0x24,0x68,0x40,0xA0,0x40,0x2C,0xCC,0xFC,0x7F,0xA0,0xDA,0x00,0x00,0x84,0x40, -0x6C,0x70,0xFC,0x20,0x68,0x40,0xA0,0x40,0x2C,0xCC,0xFC,0x7F,0xA0,0xDA,0x00,0x00, -0x84,0x40,0x59,0x70,0xFC,0x1C,0x68,0x40,0xA0,0x40,0x2C,0xCC,0xFC,0x7F,0xA0,0xDA, -0x00,0x00,0x84,0x40,0x68,0x70,0xA0,0x4F,0x30,0x28,0x00,0x00,0xA0,0x64,0xA0,0xC9, -0x14,0xA0,0x59,0xA0,0x68,0xA0,0x6C,0x2C,0xCC,0xE8,0xEF,0xB0,0x04,0x00,0x00,0xA0, -0x6C,0x2C,0xCC,0xFC,0x7F,0x9C,0xD0,0x00,0x00,0xA0,0x4F,0x61,0x28,0x00,0x00,0x2C, -0xCC,0xFC,0xEF,0xB0,0x04,0x00,0x00,0x84,0x64,0x40,0x94,0x64,0x70,0x28,0x40,0x46, -0x6F,0xFF,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x70,0x10,0x49,0x9C,0x4F, -0x38,0x00,0x00,0x00,0x4C,0x28,0x7F,0xB8,0x13,0x00,0x02,0x77,0x0B,0x84,0x5A,0x40, -0x24,0x7F,0x7F,0xD9,0x00,0x00,0xF8,0x4F,0x00,0x00,0x00,0xC0,0x5A,0x40,0xD4,0x1E, -0x40,0x40,0x84,0x40,0x59,0x70,0xF8,0x4F,0x00,0x00,0xFE,0x3F,0x5A,0x40,0xD4,0x11, -0x40,0x40,0x84,0x40,0x64,0x70,0xD0,0x02,0x59,0x40,0xF8,0x4F,0x00,0xFC,0x7F,0x00, -0x80,0x00,0x07,0x04,0x00,0x40,0xD4,0x0A,0x40,0x40,0x84,0x40,0x68,0x70,0x3C,0x68, -0x64,0x4F,0x0E,0xA0,0x5F,0x10,0x11,0x2C,0xCC,0xFC,0x7F,0xEA,0xC1,0x00,0x00,0xD0, -0x02,0x59,0x40,0xF8,0x6F,0xE0,0x80,0x00,0x06,0x04,0x00,0x40,0xD0,0x01,0x64,0x41, -0xD0,0x02,0x41,0x41,0x9C,0x41,0x40,0x84,0x40,0x6C,0x70,0x84,0xD9,0x0C,0xC9,0x10, -0x70,0xDC,0x04,0x6C,0x40,0x84,0x50,0xC9,0x14,0x70,0x38,0xC9,0x10,0x6F,0x40,0x77, -0x0E,0xA0,0x5F,0x20,0x11,0x2C,0xCC,0xFC,0x7F,0xEA,0xC1,0x00,0x00,0x80,0xC9,0x18, -0x70,0x7B,0x43,0xF8,0xF8,0xC9,0x14,0x40,0x84,0x40,0x6C,0x70,0x84,0xD9,0x0C,0xC9, -0x10,0x70,0xDC,0x04,0x6C,0x40,0x84,0x50,0xC9,0x14,0x70,0x38,0xC9,0x10,0x6F,0x40, -0x77,0x0E,0xA0,0x5F,0x20,0x11,0x2C,0xCC,0xFC,0x7F,0xEA,0xC1,0x00,0x00,0x90,0xC9, -0x18,0x70,0x3C,0x05,0xC9,0x18,0x4F,0x0E,0xA0,0x5F,0x70,0x11,0x2C,0xCC,0xFC,0x7F, -0xEA,0xC1,0x00,0x00,0x38,0xC9,0x10,0x5F,0x80,0x00,0x77,0xB9,0xF8,0x4F,0x00,0xFC, -0xFF,0x00,0xC9,0x10,0x40,0xD4,0x0A,0x40,0x40,0x84,0x40,0xC9,0x1C,0x70,0x38,0xC9, -0x10,0x04,0x7F,0x08,0x24,0x7F,0x31,0xD9,0x00,0x00,0x38,0xC9,0x10,0x01,0x77,0x0E, -0xA0,0x5F,0x80,0x11,0x2C,0xCC,0xFC,0x7F,0xEA,0xC1,0x00,0x00,0xF8,0x4F,0x00,0xF8, -0x01,0x00,0x5A,0x40,0xD4,0x0B,0x40,0x40,0x84,0x40,0xC9,0x20,0x70,0xDC,0x01,0xC9, -0x1C,0x40,0xD0,0x03,0x40,0x40,0x9C,0x5F,0xFF,0x07,0x40,0xAC,0x5F,0x00,0x08,0x40, -0x84,0x40,0xC9,0x24,0x70,0x3C,0xC9,0x24,0xC9,0x20,0x4F,0x0E,0xA0,0x5F,0x40,0x11, -0x2C,0xCC,0xFC,0x7F,0xEA,0xC1,0x00,0x00,0xF8,0x6F,0xE0,0xC9,0x14,0x40,0x84,0x40, -0xC9,0x2C,0x70,0xD0,0x02,0xC9,0x20,0x40,0x9C,0xC9,0x2C,0x40,0x84,0x50,0xC9,0x28, -0x70,0x38,0xC9,0x28,0x01,0x77,0x0E,0xA0,0x5F,0x30,0x11,0x2C,0xCC,0xFC,0x7F,0xEA, -0xC1,0x00,0x00,0x38,0xC9,0x28,0x04,0x7F,0x23,0xF8,0x4F,0xFF,0xFF,0x01,0x00,0x5A, -0x40,0xD0,0x03,0xC9,0x1C,0x41,0x9C,0x07,0x41,0x3C,0x41,0x40,0x4F,0x0E,0xA0,0x5F, -0x50,0x11,0x2C,0xCC,0xFC,0x7F,0xEA,0xC1,0x00,0x00,0xF8,0x5F,0x00,0xF8,0xC9,0x28, -0x40,0xF8,0x5F,0xFF,0x07,0x5A,0x41,0x9C,0x41,0x40,0x84,0x40,0xC9,0x34,0x70,0x7B, -0x4A,0x38,0xC9,0x10,0x01,0x77,0x0E,0xA0,0x5F,0x90,0x11,0x2C,0xCC,0xFC,0x7F,0xEA, -0xC1,0x00,0x00,0xF8,0x4F,0xFF,0xFF,0x01,0x00,0x5A,0x40,0x84,0x40,0xC9,0x30,0x70, -0xD0,0x03,0xC9,0x1C,0x40,0x9C,0x07,0x40,0x3C,0x40,0xC9,0x30,0x4F,0x0E,0xA0,0x5F, -0x60,0x11,0x2C,0xCC,0xFC,0x7F,0xEA,0xC1,0x00,0x00,0xF8,0x6F,0xE0,0xC9,0x14,0x40, -0x9C,0xC9,0x30,0x40,0x84,0x40,0xC9,0x34,0x70,0x84,0xC9,0x34,0x40,0x7B,0x02,0x04, -0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x10,0x49,0x9C,0x4F,0x04,0x00,0x00,0x00, -0x4C,0x2C,0x5C,0x7F,0x76,0xC4,0x00,0x00,0x28,0x40,0x7F,0x0E,0xA0,0x5F,0x20,0x20, -0x2C,0xCC,0xFC,0x7F,0xEA,0xC1,0x00,0x00,0x7B,0x3B,0x2C,0x5C,0x7F,0xDC,0xC5,0x00, -0x00,0x84,0x40,0x59,0x70,0x28,0x7F,0xB8,0x13,0x00,0x02,0x77,0x0E,0xA0,0x5F,0xB0, -0x01,0x2C,0xCC,0xFC,0x7F,0x50,0xC2,0x00,0x00,0xA0,0x4F,0x64,0x28,0x00,0x00,0xA0, -0x59,0xA0,0x59,0x2C,0xCC,0xFC,0xAF,0x99,0xFD,0xA0,0x40,0x2C,0xCC,0xF4,0xEF,0xB0, -0x04,0x00,0x00,0x2C,0x5C,0x7F,0x76,0xC4,0x00,0x00,0x28,0x40,0x7F,0xBE,0x04,0xC9, -0xE8,0x4C,0x20,0x49,0x08,0x70,0x10,0x49,0x9C,0x4F,0x04,0x00,0x00,0x00,0x4C,0x84, -0x5A,0x7F,0xB4,0x13,0x00,0x02,0x70,0x84,0x7F,0xB4,0x13,0x00,0x02,0x7F,0xB8,0x13, -0x00,0x02,0x70,0xA0,0x7F,0xFC,0x1D,0x00,0x02,0x2C,0xCC,0xFC,0xAF,0x53,0xFD,0x84, -0x40,0x59,0x70,0x3C,0x7F,0xF8,0x1D,0x00,0x02,0x40,0x7F,0x0E,0xA0,0x5F,0xA0,0x01, -0x2C,0xCC,0xFC,0x7F,0x50,0xC2,0x00,0x00,0x84,0x59,0x7F,0xF8,0x1D,0x00,0x02,0x70, -0x2C,0x5C,0x7F,0x74,0xB8,0x00,0x00,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x10,0x49, -0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0xA0,0x5A,0x2C,0xCC,0xFC,0xAF,0x13,0xFD,0x87, -0x50,0xE0,0x40,0x7B,0x02,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x10,0x49, -0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0xE4,0x02,0x5A,0x40,0x7F,0x0E,0xA0,0x5F,0x90, -0x50,0x2C,0xCC,0xFC,0x7F,0xEA,0xC1,0x00,0x00,0xA0,0x5A,0x2C,0xCC,0xFC,0xAF,0xE1, -0xFC,0x86,0x50,0xE4,0x40,0x7B,0x02,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70, -0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0xE4,0x04,0x5A,0x40,0x7F,0x0E,0xA0, -0x5F,0xA0,0x50,0x2C,0xCC,0xFC,0x7F,0xEA,0xC1,0x00,0x00,0xA0,0x5A,0x2C,0xCC,0xFC, -0xAF,0xAF,0xFC,0x84,0x50,0x40,0x7B,0x02,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70, -0x70,0x70,0x10,0x49,0x9C,0x4F,0x08,0x00,0x00,0x00,0x4C,0xA0,0x5A,0x2C,0xCC,0xFC, -0xAF,0x8F,0xFC,0x84,0x40,0x59,0x70,0x87,0x77,0xD9,0x00,0x70,0x28,0x7F,0xB8,0x27, -0x00,0x02,0x77,0x36,0x87,0xD9,0x00,0x64,0x70,0x3F,0x77,0x64,0x7F,0x2C,0xA0,0x4F, -0x73,0x28,0x00,0x00,0xA0,0x5A,0x87,0x64,0xE0,0x40,0xA0,0x40,0x87,0x77,0xE0,0x40, -0xA0,0x40,0x2C,0xCC,0xF0,0xEF,0xB0,0x04,0x00,0x00,0x28,0x40,0x43,0x0C,0xA0,0x05, -0x2C,0xCC,0xFC,0x7F,0x62,0x97,0x00,0x00,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70, -0x10,0x49,0x9C,0x4F,0x08,0x00,0x00,0x00,0x4C,0xE4,0x02,0x5A,0x40,0x7F,0x0E,0xA0, -0x5F,0x90,0x50,0x2C,0xCC,0xFC,0x7F,0xEA,0xC1,0x00,0x00,0xA0,0x5A,0x2C,0xCC,0xFC, -0xAF,0x1F,0xFC,0x84,0x40,0x59,0x70,0x86,0x76,0xD9,0x00,0x70,0x28,0x7F,0xB8,0x27, -0x00,0x02,0x77,0x36,0x86,0xD9,0x00,0x64,0x70,0x3E,0x76,0x64,0x7F,0x2C,0xA0,0x4F, -0xA5,0x28,0x00,0x00,0xA0,0x5A,0x86,0x64,0xE4,0x40,0xA0,0x40,0x86,0x76,0xE4,0x40, -0xA0,0x40,0x2C,0xCC,0xF0,0xEF,0xB0,0x04,0x00,0x00,0x28,0x40,0x43,0x0C,0xA0,0x05, -0x2C,0xCC,0xFC,0x7F,0x62,0x97,0x00,0x00,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70, -0x10,0x49,0x9C,0x4F,0x08,0x00,0x00,0x00,0x4C,0xE4,0x04,0x5A,0x40,0x7F,0x0E,0xA0, -0x5F,0xA0,0x50,0x2C,0xCC,0xFC,0x7F,0xEA,0xC1,0x00,0x00,0xA0,0x5A,0x2C,0xCC,0xFC, -0xAF,0xAF,0xFB,0x84,0x40,0x59,0x70,0x84,0x74,0xD9,0x00,0x70,0x28,0x7F,0xB8,0x27, -0x00,0x02,0x77,0x2E,0x84,0xD9,0x00,0x64,0x70,0x3C,0x74,0x64,0x7F,0x24,0xA0,0x4F, -0xD7,0x28,0x00,0x00,0xA0,0x5A,0xA0,0x64,0xA0,0x74,0x2C,0xCC,0xF0,0xEF,0xB0,0x04, -0x00,0x00,0x28,0x40,0x43,0x0C,0xA0,0x05,0x2C,0xCC,0xFC,0x7F,0x62,0x97,0x00,0x00, -0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00, -0x4C,0x80,0x7F,0xE8,0x1D,0x00,0x02,0x70,0x2C,0x5C,0x7F,0x76,0xC4,0x00,0x00,0x28, -0x40,0x7F,0x0C,0x84,0x01,0x7F,0xE0,0x1D,0x00,0x02,0x70,0x7B,0x3C,0xA0,0x4F,0x20, -0x29,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xD6,0xC4,0x00,0x00,0x28,0x40,0x7F,0x1B,0x2C, -0x5C,0x7F,0xDC,0xC5,0x00,0x00,0x84,0x40,0x7F,0xEC,0x1D,0x00,0x02,0x70,0x84,0x01, -0x7F,0xE8,0x1D,0x00,0x02,0x70,0x7B,0x11,0x2C,0x5C,0x7F,0xA0,0xCE,0x00,0x00,0x84, -0x40,0x7F,0xE0,0x1D,0x00,0x02,0x70,0x2C,0x5C,0x7F,0x94,0xD2,0x00,0x00,0x28,0x7F, -0xC4,0x13,0x00,0x02,0x7F,0x0C,0xA0,0x04,0x2C,0xCC,0xFC,0xAF,0x6C,0x04,0x7B,0x0A, -0xA0,0x02,0x2C,0xCC,0xFC,0xAF,0x62,0x04,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70, -0x70,0x70,0x10,0x49,0x9C,0x4F,0x08,0x00,0x00,0x00,0x4C,0x28,0x5A,0x77,0x08,0x24, -0x7F,0x82,0xDD,0x00,0x00,0x84,0xEF,0xF8,0x1D,0x00,0x02,0x7F,0x0C,0x2C,0x00,0x02, -0x70,0xB0,0x4F,0x00,0xE0,0x03,0x00,0xEF,0xF8,0x1D,0x00,0x02,0x70,0xDC,0x04,0x7F, -0xF8,0x1D,0x00,0x02,0x40,0x84,0x50,0x7F,0xF0,0x1D,0x00,0x02,0x70,0xA0,0x7F,0xF0, -0x1D,0x00,0x02,0x2C,0xCC,0xFC,0x7F,0x4E,0xDA,0x00,0x00,0x3C,0x30,0x40,0x77,0x38, -0xDC,0x01,0x7F,0xF0,0x1D,0x00,0x02,0x40,0xA0,0x40,0x2C,0xCC,0xFC,0x7F,0x4E,0xDA, -0x00,0x00,0x87,0x40,0x59,0x70,0x3F,0x5F,0xC8,0x00,0x59,0x7F,0x0F,0x3F,0x5F,0xAC, -0x00,0x59,0x7F,0x08,0x3F,0x6F,0x45,0x59,0x77,0x0E,0xA0,0x5F,0xC0,0x00,0x2C,0xCC, -0xFC,0x7F,0xEA,0xC1,0x00,0x00,0xA0,0x00,0x2C,0xCC,0xFC,0x7F,0xA0,0xDA,0x00,0x00, -0x84,0x40,0x64,0x70,0xDC,0x08,0x64,0x40,0xA0,0x40,0x2C,0xCC,0xFC,0x7F,0xA0,0xDA, -0x00,0x00,0x84,0x40,0x7F,0xA0,0x27,0x00,0x02,0x70,0xDC,0x0C,0x64,0x40,0xA0,0x40, -0x2C,0xCC,0xFC,0x7F,0xA0,0xDA,0x00,0x00,0x84,0x40,0x7F,0x9C,0x27,0x00,0x02,0x70, -0x28,0x7F,0xB8,0x13,0x00,0x02,0x7F,0x2A,0xDC,0x08,0x64,0x40,0xA0,0x40,0xA0,0x4F, -0x00,0xE1,0x81,0x00,0x2C,0xCC,0xF8,0x7F,0xA0,0xDB,0x00,0x00,0xDC,0x0C,0x64,0x40, -0xA0,0x40,0xA0,0x4F,0xE1,0x92,0x02,0x00,0x2C,0xCC,0xF8,0x7F,0xA0,0xDB,0x00,0x00, -0x7B,0x6C,0xB8,0x4F,0xFB,0xFF,0xFD,0xFF,0xEF,0xF8,0x1D,0x00,0x02,0x70,0xB8,0x4F, -0xFF,0x1F,0xFE,0xFF,0xEF,0xF8,0x1D,0x00,0x02,0x70,0xF8,0x4F,0x00,0xE0,0x01,0x00, -0x7F,0x0C,0x2C,0x00,0x02,0x40,0xB0,0x40,0xEF,0xF8,0x1D,0x00,0x02,0x70,0xA0,0x00, -0x2C,0xCC,0xFC,0x7F,0xA0,0xDA,0x00,0x00,0x84,0x40,0x64,0x70,0x28,0x7F,0xB8,0x13, -0x00,0x02,0x7F,0x2A,0xDC,0x08,0x64,0x40,0xA0,0x40,0xA0,0x7F,0xA0,0x27,0x00,0x02, -0x2C,0xCC,0xF8,0x7F,0xA0,0xDB,0x00,0x00,0xDC,0x0C,0x64,0x40,0xA0,0x40,0xA0,0x7F, -0x9C,0x27,0x00,0x02,0x2C,0xCC,0xF8,0x7F,0xA0,0xDB,0x00,0x00,0x04,0xC9,0xE8,0x4C, -0x20,0x49,0x08,0x70,0x10,0x49,0x9C,0x4F,0x08,0x00,0x00,0x00,0x4C,0xA0,0x00,0x2C, -0xCC,0xFC,0xAF,0x93,0xFE,0x84,0x7F,0xDC,0x1D,0x00,0x02,0x64,0x70,0x80,0x7F,0xDC, -0x1D,0x00,0x02,0x70,0x84,0x64,0x40,0x24,0x7F,0x12,0xDF,0x00,0x00,0xA0,0x5F,0x40, -0x52,0x2C,0xCC,0xFC,0x7F,0xEA,0xC1,0x00,0x00,0x24,0x7F,0x27,0xDF,0x00,0x00,0xA0, -0x00,0x2C,0xCC,0xFC,0xAF,0xB3,0x02,0x24,0x7F,0x27,0xDF,0x00,0x00,0xA0,0x7F,0xF0, -0x1D,0x00,0x02,0x2C,0xCC,0xFC,0x7F,0x4E,0xDA,0x00,0x00,0x87,0x40,0x59,0x70,0x3F, -0x2C,0x59,0x77,0x2E,0xA0,0x14,0xDC,0x08,0x7F,0xF8,0x1D,0x00,0x02,0x40,0xFC,0x08, -0x50,0x40,0xA0,0x40,0x2C,0xCC,0xFC,0x7F,0xA0,0xDA,0x00,0x00,0xA0,0x40,0xA0,0x01, -0x2C,0xCC,0xF4,0x7F,0x38,0xA0,0x00,0x00,0xA0,0x00,0x2C,0xCC,0xFC,0xAF,0x6A,0x02, -0x3F,0x37,0x59,0x7F,0x0C,0x3F,0x36,0x59,0x7F,0x07,0x3F,0x34,0x59,0x77,0x2E,0xA0, -0x14,0xDC,0x08,0x7F,0xF8,0x1D,0x00,0x02,0x40,0xFC,0x04,0x50,0x40,0xA0,0x40,0x2C, -0xCC,0xFC,0x7F,0xA0,0xDA,0x00,0x00,0xA0,0x40,0xA0,0x01,0x2C,0xCC,0xF4,0x7F,0x38, -0xA0,0x00,0x00,0xA0,0x00,0x2C,0xCC,0xFC,0xAF,0x2F,0x02,0xA0,0x00,0x2C,0xCC,0xFC, -0xEF,0x40,0x05,0x00,0x00,0x2C,0x5C,0xAF,0xBD,0x02,0x87,0x7F,0x10,0x2C,0x00,0x02, -0xE0,0x40,0xA0,0x40,0x2C,0xCC,0xFC,0xEF,0x40,0x05,0x00,0x00,0x28,0x7F,0xE8,0x1D, -0x00,0x02,0x7F,0x1D,0xDC,0x04,0x7F,0xF8,0x1D,0x00,0x02,0x40,0x3C,0x7F,0xEC,0x1D, -0x00,0x02,0x50,0x7F,0x0A,0xA0,0x64,0x2C,0xCC,0xFC,0xAF,0xED,0x01,0x7B,0x13,0x94, -0x7F,0xE0,0x1D,0x00,0x02,0x70,0x4F,0x0A,0xA0,0x64,0x2C,0xCC,0xFC,0xAF,0xDA,0x01, -0x7B,0x17,0x3C,0x04,0x40,0x46,0x08,0xFF,0xC0,0x02,0x40,0x40,0x28,0x40,0x4A,0xFF, -0xFE,0x24,0x90,0x0C,0x29,0x00,0x00,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70, -0x10,0x48,0x9C,0x4F,0x08,0x00,0x00,0x00,0x4C,0x2C,0x5C,0x7F,0x76,0xC4,0x00,0x00, -0x28,0x40,0x7F,0x0C,0x84,0x7F,0x14,0x2C,0x00,0x02,0x64,0x70,0x7B,0x55,0x2C,0x5C, -0x7F,0xDC,0xC5,0x00,0x00,0x84,0x40,0x64,0x70,0x80,0x7F,0x8C,0x13,0x00,0x02,0x70, -0x80,0x48,0x7B,0x28,0x90,0x48,0x3C,0x09,0x48,0x4B,0x0E,0xA0,0x5F,0x60,0x52,0x2C, -0xCC,0xFC,0x7F,0xEA,0xC1,0x00,0x00,0x2C,0x5C,0x7F,0xDC,0xC5,0x00,0x00,0xD0,0x02, -0x48,0x41,0x84,0x40,0x81,0x8C,0x13,0x00,0x02,0x70,0x2C,0x5C,0x7F,0x76,0xC4,0x00, -0x00,0x28,0x40,0x7F,0xD1,0xD0,0x02,0x48,0x40,0x84,0x40,0x7F,0x8C,0x13,0x00,0x02, -0x70,0xA0,0x64,0x2C,0xCC,0xFC,0x7F,0x4E,0xDA,0x00,0x00,0x3C,0x10,0x40,0x7F,0x0E, -0xA0,0x5F,0x50,0x52,0x2C,0xCC,0xFC,0x7F,0xEA,0xC1,0x00,0x00,0x84,0x64,0x7F,0x14, -0x2C,0x00,0x02,0x70,0x2C,0x5C,0x7F,0x94,0xD2,0x00,0x00,0x2C,0x5C,0x7F,0xEC,0xD2, -0x00,0x00,0x84,0x64,0x7F,0x84,0x13,0x00,0x02,0x70,0x28,0x7F,0xB8,0x13,0x00,0x02, -0x7F,0x26,0xA0,0x16,0xA0,0x4F,0x59,0xE8,0x02,0x00,0xA0,0x01,0x2C,0xCC,0xF4,0x7F, -0x38,0xA0,0x00,0x00,0xDC,0x04,0x7F,0xF8,0x1D,0x00,0x02,0x40,0x84,0x4F,0x23,0xE8, -0x02,0x00,0x50,0x70,0x7B,0x24,0xA0,0x16,0xA0,0x4F,0x90,0xE8,0x00,0x00,0xA0,0x01, -0x2C,0xCC,0xF4,0x7F,0x38,0xA0,0x00,0x00,0xDC,0x04,0x7F,0xF8,0x1D,0x00,0x02,0x40, -0x84,0x4F,0x5A,0xE8,0x00,0x00,0x50,0x70,0xA0,0x00,0x2C,0xCC,0xFC,0xAF,0xBA,0x00, -0x04,0xC9,0xEC,0x4C,0x20,0x48,0x20,0x49,0x08,0x70,0x10,0x49,0x9C,0x4F,0x08,0x00, -0x00,0x00,0x4C,0x2C,0x5C,0x7F,0x76,0xC4,0x00,0x00,0x28,0x40,0x7F,0x10,0xDC,0x04, -0x7F,0xF8,0x1D,0x00,0x02,0x40,0x84,0x50,0x64,0x70,0x7B,0x46,0xA0,0x4F,0x25,0x29, -0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xD6,0xC4,0x00,0x00,0x28,0x40,0x7F,0x29,0xDC,0x04, -0x7F,0xF8,0x1D,0x00,0x02,0x40,0x84,0x50,0x64,0x70,0x2C,0x5C,0x7F,0xDC,0xC5,0x00, -0x00,0x84,0x40,0x59,0x70,0xA0,0x15,0xA0,0x59,0xA0,0x01,0x2C,0xCC,0xF4,0x7F,0x38, -0xA0,0x00,0x00,0x7B,0x0D,0x2C,0x5C,0x7F,0xDC,0xC5,0x00,0x00,0x84,0x40,0x64,0x70, -0xDC,0x04,0x7F,0xF8,0x1D,0x00,0x02,0x40,0x84,0x64,0x50,0x70,0x84,0x01,0x7F,0xBC, -0x13,0x00,0x02,0x70,0x2C,0x5C,0x7F,0x94,0xD2,0x00,0x00,0xA0,0x64,0x2C,0xCC,0xFC, -0x7F,0x96,0x99,0x00,0x00,0x3C,0xFF,0x40,0x7F,0x0C,0xA0,0x01,0x2C,0xCC,0xFC,0xAF, -0x18,0x00,0x7B,0x0A,0xA0,0x00,0x2C,0xCC,0xFC,0xAF,0x0E,0x00,0x04,0xC9,0xE8,0x4C, -0x20,0x49,0x08,0x70,0x10,0x49,0x9C,0x4F,0x04,0x00,0x00,0x00,0x4C,0x84,0x5A,0x7F, -0xDC,0x1D,0x00,0x02,0x70,0x28,0x5A,0x77,0x0B,0x2C,0x5C,0x7F,0xE4,0x9D,0x00,0x00, -0x7B,0x0A,0xA0,0x01,0x2C,0xCC,0xFC,0xAF,0x8E,0xFB,0xA0,0x06,0x2C,0xCC,0xFC,0x7F, -0x62,0x97,0x00,0x00,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x10,0x49,0x9C,0x4F, -0x00,0x00,0x00,0x00,0x4C,0xF0,0x5F,0x00,0x01,0xEF,0xF8,0x1D,0x00,0x02,0x40,0x84, -0x40,0xEF,0xF8,0x1D,0x00,0x02,0x70,0x84,0x01,0x7F,0x58,0x10,0x00,0x02,0x70,0x28, -0x7F,0xDC,0x1D,0x00,0x02,0x77,0x09,0x2C,0x5C,0x7F,0x06,0x9F,0x00,0x00,0x87,0x7F, -0x10,0x2C,0x00,0x02,0xE0,0x40,0xA0,0x40,0x2C,0xCC,0xFC,0xEF,0x40,0x05,0x00,0x00, -0x28,0x7F,0xB8,0x13,0x00,0x02,0x7F,0x0B,0x2C,0x5C,0x7F,0xB0,0xE7,0x00,0x00,0x7B, -0x09,0x2C,0x5C,0x7F,0xEE,0xE7,0x00,0x00,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70, -0x70,0x70,0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x28,0x7F,0xC0,0x13,0x00, -0x02,0x7F,0x11,0x3C,0x01,0x7F,0xE0,0x1D,0x00,0x02,0x4F,0x08,0x24,0x7F,0x79,0xE2, -0x00,0x00,0x28,0x7F,0xC0,0x13,0x00,0x02,0x7F,0x21,0x28,0x7F,0xE8,0x1D,0x00,0x02, -0x7F,0x19,0xDC,0x04,0x7F,0xF8,0x1D,0x00,0x02,0x40,0x3C,0x7F,0xEC,0x1D,0x00,0x02, -0x50,0x7F,0x08,0x24,0x7F,0x79,0xE2,0x00,0x00,0xA0,0x4F,0x2A,0x29,0x00,0x00,0xA0, -0x7F,0xE0,0x1D,0x00,0x02,0xDC,0x04,0x7F,0xF8,0x1D,0x00,0x02,0x40,0xA0,0x50,0xA0, -0xEF,0xF8,0x1D,0x00,0x02,0xDC,0x08,0x7F,0xF8,0x1D,0x00,0x02,0x40,0xA0,0x50,0x2C, -0xCC,0xEC,0xEF,0xB0,0x04,0x00,0x00,0x28,0x40,0x43,0x0E,0xA0,0x05,0x2C,0xCC,0xFC, -0x7F,0x62,0x97,0x00,0x00,0x7B,0x22,0xDC,0x04,0x7F,0xF8,0x1D,0x00,0x02,0x40,0xA0, -0x50,0x2C,0xCC,0xFC,0x7F,0x9C,0xD0,0x00,0x00,0xA0,0x4F,0x54,0x29,0x00,0x00,0x2C, -0xCC,0xFC,0xEF,0xB0,0x04,0x00,0x00,0x38,0x7F,0xF4,0x1D,0x00,0x02,0x01,0x7F,0x10, -0xA0,0x7F,0x78,0x27,0x00,0x02,0x2C,0xCC,0xFC,0x7F,0x78,0xB1,0x00,0x00,0x38,0x7F, -0xF4,0x1D,0x00,0x02,0x02,0x7F,0x34,0xA0,0x4F,0x56,0x29,0x00,0x00,0x2C,0xCC,0xFC, -0xEF,0xB0,0x04,0x00,0x00,0x28,0x40,0x43,0x0C,0xA0,0x05,0x2C,0xCC,0xFC,0x7F,0x62, -0x97,0x00,0x00,0xDC,0x08,0x7F,0xF8,0x1D,0x00,0x02,0x40,0xFC,0x10,0x50,0x40,0xA0, -0x40,0x2C,0xCC,0xFC,0x7F,0x78,0xB1,0x00,0x00,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08, -0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x2C,0x5C,0x7F,0x76,0xC4,0x00,0x00, -0x28,0x40,0x7F,0x14,0x80,0x7F,0xE0,0x1D,0x00,0x02,0x70,0x2C,0x5C,0xAF,0xE7,0xFE, -0x24,0x7F,0x30,0xE3,0x00,0x00,0xA0,0x4F,0x5D,0x29,0x00,0x00,0x2C,0xCC,0xFC,0x7F, -0xD6,0xC4,0x00,0x00,0x28,0x40,0x7F,0x1B,0x2C,0x5C,0x7F,0xDC,0xC5,0x00,0x00,0x84, -0x40,0x7F,0x78,0x27,0x00,0x02,0x70,0xB0,0x01,0x7F,0xF4,0x1D,0x00,0x02,0x70,0x7B, -0x61,0xA0,0x4F,0x60,0x29,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xD6,0xC4,0x00,0x00,0x28, -0x40,0x7F,0x0C,0xB0,0x02,0x7F,0xF4,0x1D,0x00,0x02,0x70,0x7B,0x45,0xA0,0x4F,0x63, -0x29,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xD6,0xC4,0x00,0x00,0x28,0x40,0x7F,0x0C,0x84, -0x04,0x7F,0xF4,0x1D,0x00,0x02,0x70,0x7B,0x29,0xA0,0x4F,0x66,0x29,0x00,0x00,0x2C, -0xCC,0xFC,0x7F,0xD6,0xC4,0x00,0x00,0x28,0x40,0x7F,0x0B,0x2C,0x5C,0x7F,0x36,0xD6, -0x00,0x00,0x7B,0x0E,0xA0,0x5F,0x60,0x52,0x2C,0xCC,0xFC,0x7F,0xEA,0xC1,0x00,0x00, -0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00, -0x4C,0x87,0x7F,0x68,0x08,0x00,0x02,0x7F,0x10,0x2C,0x00,0x02,0x70,0xA0,0x01,0x2C, -0xCC,0xFC,0xEF,0x40,0x05,0x00,0x00,0x84,0x03,0x7F,0x58,0x10,0x00,0x02,0x70,0x2C, -0x5C,0x7F,0x9C,0xE5,0x00,0x00,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x70, -0x10,0x49,0x9C,0x4F,0x08,0x00,0x00,0x00,0x4C,0x80,0x7F,0xB4,0x13,0x00,0x02,0x70, -0x80,0x7F,0xB8,0x13,0x00,0x02,0x70,0x84,0x01,0x7F,0x7C,0x27,0x00,0x02,0x70,0x84, -0x4F,0x00,0x30,0x00,0x02,0x7F,0x08,0x1E,0x00,0x02,0x70,0x80,0x7F,0x10,0x1E,0x00, -0x02,0x70,0x84,0x4F,0x50,0x30,0x00,0x02,0x7F,0xFC,0x1D,0x00,0x02,0x70,0xA0,0x7F, -0xFC,0x1D,0x00,0x02,0x2C,0xCC,0xFC,0x7F,0x6C,0xD7,0x00,0x00,0x84,0x40,0x7F,0xF8, -0x1D,0x00,0x02,0x70,0x84,0x4F,0x00,0xE1,0x81,0x00,0xEF,0xF8,0x1D,0x00,0x02,0x70, -0xDC,0x04,0x7F,0xF8,0x1D,0x00,0x02,0x40,0x84,0x4F,0x00,0x50,0x00,0x02,0x50,0x70, -0xDC,0x08,0x7F,0xF8,0x1D,0x00,0x02,0x40,0x84,0x4F,0x94,0x30,0x00,0x02,0x50,0x70, -0xDC,0x0C,0x7F,0xF8,0x1D,0x00,0x02,0x40,0x84,0x4F,0x94,0x30,0x00,0x02,0x50,0x70, -0xDC,0x10,0x7F,0xF8,0x1D,0x00,0x02,0x40,0x84,0x4F,0xEC,0x37,0x00,0x02,0x50,0x70, -0xDC,0x14,0x7F,0xF8,0x1D,0x00,0x02,0x40,0x84,0x4F,0x94,0x30,0x00,0x02,0x50,0x70, -0xDC,0x18,0x7F,0xF8,0x1D,0x00,0x02,0x40,0x84,0x4F,0x94,0x30,0x00,0x02,0x50,0x70, -0xDC,0x6F,0x40,0x7F,0xF8,0x1D,0x00,0x02,0x40,0x80,0x50,0x70,0x2B,0x7F,0x50,0x10, -0x00,0x02,0x7F,0x62,0x80,0x59,0x70,0x7B,0x1D,0xE8,0x6F,0x54,0x59,0x40,0x80,0x80, -0xE4,0x15,0x00,0x02,0x70,0xE8,0x6F,0x54,0x59,0x40,0x80,0x80,0xE8,0x15,0x00,0x02, -0x70,0x90,0x59,0x70,0x3C,0x17,0x59,0x4B,0xE2,0x80,0x59,0x70,0x7B,0x10,0xD0,0x03, -0x59,0x40,0x80,0x80,0x60,0x1D,0x00,0x02,0x70,0x90,0x59,0x70,0x3C,0x10,0x59,0x4B, -0xEF,0x83,0x7F,0x50,0x10,0x00,0x02,0x70,0x28,0x7F,0x54,0x10,0x00,0x02,0x77,0x14, -0xA0,0x01,0x2C,0xCC,0xFC,0xEF,0x40,0x05,0x00,0x00,0x87,0x01,0x7F,0x10,0x2C,0x00, -0x02,0x70,0x7B,0x09,0x2C,0x5C,0x7F,0x50,0x9E,0x00,0x00,0x84,0x4F,0x80,0xE1,0x81, -0x00,0x7F,0x78,0x12,0x00,0x02,0x70,0x84,0x4F,0xE4,0x96,0x00,0x00,0x7F,0x7C,0x12, -0x00,0x02,0x70,0x84,0x4F,0xC8,0x22,0x00,0x02,0x7F,0x80,0x12,0x00,0x02,0x70,0x84, -0x4F,0xC8,0x22,0x00,0x02,0x7F,0x90,0x12,0x00,0x02,0x70,0x84,0x4F,0x78,0x27,0x00, -0x02,0x7F,0x94,0x12,0x00,0x02,0x70,0x84,0x4F,0xC8,0x22,0x00,0x02,0x7F,0x98,0x12, -0x00,0x02,0x70,0x84,0x4F,0xC8,0x22,0x00,0x02,0x7F,0x9C,0x12,0x00,0x02,0x70,0x80, -0x7F,0xC4,0x12,0x00,0x02,0x70,0x84,0xFF,0x7F,0xB0,0x13,0x00,0x02,0x70,0x84,0x4F, -0xD0,0x13,0x00,0x02,0x7F,0xCC,0x13,0x00,0x02,0x70,0x83,0x7F,0xD0,0x13,0x00,0x02, -0x70,0x80,0x7F,0x9C,0x27,0x00,0x02,0x70,0x80,0x7F,0xDC,0x1D,0x00,0x02,0x70,0x80, -0x7F,0xE0,0x1D,0x00,0x02,0x70,0x84,0x04,0x7F,0xF4,0x1D,0x00,0x02,0x70,0x80,0x7F, -0xB8,0x27,0x00,0x02,0x70,0x84,0xFF,0x7F,0xA4,0x27,0x00,0x02,0x70,0x84,0xFF,0x7F, -0xBC,0x27,0x00,0x02,0x70,0x80,0x59,0x70,0x7B,0x11,0xE8,0x28,0x59,0x40,0x84,0xFF, -0x80,0xC8,0x27,0x00,0x02,0x70,0x90,0x59,0x70,0x3C,0x14,0x59,0x4B,0xEE,0x28,0x7F, -0x54,0x10,0x00,0x02,0x77,0x10,0xA0,0x4F,0x6C,0x29,0x00,0x00,0x2C,0xCC,0xFC,0xEF, -0xB0,0x04,0x00,0x00,0x28,0x7F,0x54,0x10,0x00,0x02,0x77,0x09,0x2C,0x5C,0x7F,0x74, -0xB8,0x00,0x00,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x10,0x49,0x9C,0x4F, -0x00,0x00,0x00,0x00,0x4C,0x87,0x01,0xEF,0xC4,0x04,0x00,0x00,0x70,0xDC,0x02,0x7F, -0x64,0x0F,0x00,0x02,0x40,0x87,0x15,0x50,0x70,0xA0,0x4F,0xA4,0x29,0x00,0x00,0x2C, -0xCC,0xFC,0xEF,0xB0,0x04,0x00,0x00,0x84,0x4F,0xD0,0x13,0x00,0x02,0x7F,0xCC,0x13, -0x00,0x02,0x70,0xA0,0x4F,0xD0,0x13,0x00,0x02,0x2C,0xCC,0xFC,0xEF,0xB4,0x04,0x00, -0x00,0x2B,0x7F,0xD0,0x13,0x00,0x02,0x77,0x18,0xA0,0x4F,0xD0,0x13,0x00,0x02,0xA0, -0x4F,0x18,0x2C,0x00,0x02,0x2C,0xCC,0xF8,0x7F,0x6C,0xEA,0x00,0x00,0x7B,0x16,0xA0, -0x4F,0x18,0x2C,0x00,0x02,0xA0,0x4F,0xD0,0x13,0x00,0x02,0x2C,0xCC,0xF8,0x7F,0x6C, -0xEA,0x00,0x00,0x84,0x03,0x7F,0x88,0x13,0x00,0x02,0x70,0xA0,0x04,0x2C,0xCC,0xFC, -0x7F,0x62,0x97,0x00,0x00,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x10,0x49, -0x9C,0x4F,0x04,0x00,0x00,0x00,0x4C,0x80,0x59,0x70,0x7B,0x19,0xA0,0x78,0x2C,0xCC, -0xFC,0x7F,0xE0,0x59,0x00,0x00,0x84,0x74,0x41,0x90,0x74,0x70,0x87,0x40,0x51,0x70, -0x90,0x59,0x70,0x3C,0x5A,0x59,0x4B,0xE6,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70, -0x10,0x49,0x9C,0x4F,0x04,0x00,0x00,0x00,0x4C,0x2C,0x5C,0x7F,0x76,0xC4,0x00,0x00, -0x28,0x40,0x7F,0x70,0xA0,0x4F,0x80,0x30,0x04,0x00,0xE0,0x59,0xA0,0x02,0x2C,0xCC, -0xF4,0xEF,0xD0,0x04,0x00,0x00,0xA0,0x4F,0xA6,0x29,0x00,0x00,0x86,0xE2,0x59,0xE0, -0x40,0xB8,0x0F,0x40,0xD0,0x03,0x40,0x40,0x86,0x80,0x14,0x0D,0x00,0x00,0xE4,0x40, -0xA0,0x40,0x2C,0xCC,0xF8,0xEF,0xB0,0x04,0x00,0x00,0xA0,0x4F,0x0A,0x30,0x04,0x00, -0xE0,0x59,0xA0,0x02,0x2C,0xCC,0xF4,0xEF,0xD0,0x04,0x00,0x00,0xA0,0x4F,0xB8,0x29, -0x00,0x00,0x86,0xE2,0x59,0xE0,0x40,0xB8,0x0F,0x40,0xD0,0x03,0x40,0x40,0x86,0x80, -0x14,0x0D,0x00,0x00,0xE4,0x40,0xA0,0x40,0x2C,0xCC,0xF8,0xEF,0xB0,0x04,0x00,0x00, -0x7B,0x3C,0x2C,0x5C,0x7F,0xA0,0xCE,0x00,0x00,0x86,0x40,0x59,0x70,0x3C,0x4F,0x00, -0x90,0x04,0x00,0x5A,0x77,0x17,0xA0,0x4F,0xC9,0x29,0x00,0x00,0x86,0xE2,0x59,0xE0, -0x40,0xA0,0x40,0x2C,0xCC,0xF8,0xEF,0xB0,0x04,0x00,0x00,0x86,0xE2,0x59,0xE0,0x40, -0xA0,0x40,0xA0,0x5A,0x2C,0xCC,0xF8,0xEF,0x00,0x05,0x00,0x00,0x04,0xC9,0xE8,0x4C, -0x20,0x49,0x08,0x70,0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x7B,0x1C,0x84, -0x5A,0x40,0x90,0x5A,0x70,0x87,0x50,0xE0,0x40,0xA0,0x40,0xA0,0x4F,0x08,0x90,0x04, -0x00,0x2C,0xCC,0xF8,0x7F,0xA4,0x60,0x00,0x00,0x2B,0xDA,0x00,0x77,0xE3,0x04,0xC9, -0xE8,0x4C,0x20,0x49,0x08,0x70,0x10,0x48,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x7B, -0x3B,0x84,0x5A,0x40,0x90,0x5A,0x70,0x87,0x50,0x48,0x3F,0x1F,0x48,0x4F,0x08,0x3F, -0x6F,0x7F,0x48,0x4B,0x05,0x87,0x2E,0x48,0xA0,0x4F,0xDC,0x29,0x00,0x00,0x87,0x48, -0xE0,0x40,0xA0,0x40,0x2C,0xCC,0xF8,0xEF,0xB0,0x04,0x00,0x00,0x28,0x40,0x43,0x0C, -0xA0,0x05,0x2C,0xCC,0xFC,0x7F,0x62,0x97,0x00,0x00,0x84,0x74,0x40,0x94,0x74,0x70, -0x28,0x40,0x47,0xBF,0x04,0xC9,0xEC,0x4C,0x20,0x48,0x20,0x49,0x08,0x70,0x70,0x70, -0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0xA0,0x7F,0x08,0x1E,0x00,0x02,0x2C, -0xCC,0xFC,0x7F,0x6C,0xD7,0x00,0x00,0x84,0x7F,0xFC,0x1D,0x00,0x02,0x50,0x70,0x2C, -0x5C,0xAF,0xCB,0x00,0x04,0x7F,0xDD,0xE7,0x02,0x00,0x40,0x30,0x0D,0xDC,0x04,0x7F, -0x08,0x1E,0x00,0x02,0x4E,0x30,0xC8,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x10,0x49, -0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x2C,0x5C,0xAF,0xA3,0x00,0x84,0x7F,0xF8,0x1D, -0x00,0x02,0xEF,0x08,0x1E,0x00,0x02,0x70,0xDC,0x04,0x7F,0x08,0x1E,0x00,0x02,0x4E, -0x30,0xC8,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x10,0x49,0x9C,0x4F,0x00,0x00, -0x00,0x00,0x4C,0x70,0x80,0x40,0x3C,0x7F,0x8C,0x13,0x00,0x02,0x00,0x7F,0x21,0x84, -0x04,0x40,0xA0,0x80,0x8C,0x13,0x00,0x02,0x9C,0x04,0x40,0x3C,0x7F,0x8C,0x13,0x00, -0x02,0x40,0x4F,0xF0,0xBC,0x04,0x40,0x80,0x7F,0x8C,0x13,0x00,0x02,0x70,0xFC,0x40, -0x4C,0x40,0x2C,0x50,0xEF,0x84,0x13,0x00,0x02,0x2E,0x80,0x40,0x70,0x3C,0x7F,0x8C, -0x13,0x00,0x02,0x00,0x7F,0x21,0x84,0x04,0x40,0xA0,0x80,0x8C,0x13,0x00,0x02,0x9C, -0x04,0x40,0x3C,0x7F,0x8C,0x13,0x00,0x02,0x40,0x4F,0xF0,0xBC,0x04,0x40,0x80,0x7F, -0x8C,0x13,0x00,0x02,0x70,0xFC,0x40,0x4C,0x40,0x2C,0x50,0xEF,0x84,0x13,0x00,0x02, -0x2E,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x70,0x10,0x49,0x9C,0x4F,0x04,0x00, -0x00,0x00,0x4C,0x87,0x7F,0x13,0x20,0x04,0x00,0x59,0x70,0x04,0xC9,0xE8,0x4C,0x20, -0x49,0x08,0x70,0x70,0x10,0x47,0x84,0x5A,0x41,0x84,0x00,0x47,0x87,0x51,0xE0,0x48, -0x3B,0x88,0x5D,0x2C,0x00,0x00,0x04,0x77,0x46,0x7B,0x13,0x04,0xC9,0xF0,0x4C,0x20, -0x48,0x20,0x47,0x20,0x49,0x08,0x90,0x41,0x87,0x51,0xE0,0x48,0x3B,0x88,0x5D,0x2C, -0x00,0x00,0x08,0x77,0xF3,0x3C,0x48,0x2B,0x7F,0x09,0x3C,0x48,0x2D,0x77,0x0A,0x90, -0x47,0x90,0x41,0x87,0x51,0xE0,0x48,0x3B,0x88,0x5D,0x2C,0x00,0x00,0x04,0x77,0x0F, -0x80,0x40,0x04,0xC9,0xF0,0x4C,0x20,0x48,0x20,0x47,0x20,0x49,0x08,0xFC,0x48,0x30, -0x42,0x7B,0x0C,0xA8,0x0A,0x42,0xFC,0x48,0x30,0x40,0x9C,0x40,0x42,0x90,0x41,0x87, -0x51,0xE0,0x48,0x3B,0x88,0x5D,0x2C,0x00,0x00,0x04,0x77,0xE9,0x28,0x47,0x7F,0x10, -0x84,0x42,0x40,0x04,0xC9,0xF0,0x4C,0x20,0x48,0x20,0x47,0x20,0x49,0x08,0x8C,0x42, -0x40,0x04,0xC9,0xF0,0x4C,0x20,0x48,0x20,0x47,0x20,0x49,0x08,0x10,0x47,0x84,0x5A, -0x41,0x84,0x00,0x47,0x87,0x51,0xE0,0x48,0x3B,0x88,0x5D,0x2C,0x00,0x00,0x04,0x77, -0x46,0x7B,0x13,0x04,0xC9,0xF0,0x4C,0x20,0x48,0x20,0x47,0x20,0x49,0x08,0x90,0x41, -0x87,0x51,0xE0,0x48,0x3B,0x88,0x5D,0x2C,0x00,0x00,0x08,0x77,0xF3,0x3C,0x48,0x2B, -0x7F,0x09,0x3C,0x48,0x2D,0x77,0x0A,0x90,0x47,0x90,0x41,0x87,0x51,0xE0,0x48,0x3B, -0x88,0x5D,0x2C,0x00,0x00,0x04,0x77,0x0F,0x80,0x40,0x04,0xC9,0xF0,0x4C,0x20,0x48, -0x20,0x47,0x20,0x49,0x08,0xFC,0x48,0x30,0x42,0x7B,0x0C,0xA8,0x0A,0x42,0xFC,0x48, -0x30,0x40,0x9C,0x40,0x42,0x90,0x41,0x87,0x51,0xE0,0x48,0x3B,0x88,0x5D,0x2C,0x00, -0x00,0x04,0x77,0xE9,0x28,0x47,0x7F,0x10,0x84,0x42,0x40,0x04,0xC9,0xF0,0x4C,0x20, -0x48,0x20,0x47,0x20,0x49,0x08,0x8C,0x42,0x40,0x04,0xC9,0xF0,0x4C,0x20,0x48,0x20, -0x47,0x20,0x49,0x08,0x10,0x49,0x84,0x5A,0x40,0x84,0x74,0x41,0x3C,0x41,0x40,0x77, -0x08,0x7B,0x10,0x90,0x40,0x90,0x41,0x3F,0x51,0x50,0x77,0x07,0x3F,0x50,0x00,0x77, -0xF4,0xFF,0x51,0x50,0x40,0x87,0xE7,0x40,0xE4,0x40,0x04,0xC9,0xE8,0x4C,0x20,0x49, -0x08,0x70,0x70,0x70,0x10,0x49,0x84,0x5A,0x40,0x7B,0x04,0x90,0x40,0x2B,0x50,0x77, -0xFC,0xBC,0x5A,0x40,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x10,0x47,0x84,0x5A, -0x42,0x84,0x74,0x48,0x70,0x84,0x42,0x47,0x84,0x42,0x40,0x90,0x42,0x2B,0x50,0x77, -0xF9,0x94,0x42,0x84,0x42,0x40,0x84,0x48,0x41,0x90,0x42,0x90,0x48,0x87,0x51,0x50, -0x70,0x77,0xF2,0x84,0x47,0x40,0x04,0xC9,0xF0,0x4C,0x20,0x48,0x20,0x47,0x20,0x49, -0x08,0x04,0xC9,0xF0,0x4C,0x20,0x48,0x20,0x47,0x20,0x49,0x08,0x10,0x49,0x84,0x5A, -0x41,0x84,0x74,0x40,0x30,0x35,0x84,0x5A,0x40,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x0D,0x0D,0x0D,0x0D,0x03,0x02,0x01,0x90,0x03,0x02,0x01,0x02,0x03,0x02,0x01,0x55,}; -#endif /* ROM_rom_rev2_demon_bin_H */ diff --git a/3B2/rom_rev3.bin b/3B2/rom_rev3.bin deleted file mode 100644 index 94afbfaf3b76085741fa78934796b1722b3d7243..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 131072 zcmeHweRv$zb@!~avZS?S$sd3L0|UrGSTe}QfDH?pm9)~zk~PATu~#M$vRAeRvQ|hk zYdooEV@EkZ+f=D2`csM$ zIpy_5`jv{(aZpiiISh9tek4OsQDT3FrbMi?l%2L9i zAtMtU^q!}bdImDgLkM(KpE^A9!|uRKrg3>_s3NBi4VmnSojX~CUSgt#s_xw4ejk2>5C6A z6GV8h_YoyfKhz7)f!%74x~o4vIQWPPZ_aq2XGedpy0gExXNbZf)^N|my)m`z-p!#+ zYTv-FxWg|HPl?X| zL=h6i2Pg-R2s`6@2m5S|By@Sfby+gy0-$~Mo;;tMHD9yve`+DK5S>L}u zplt4iz{B)D9B7UAIB`09hx&T@)wX?mck~XqaRbUjO7H%`q2A$Pr8hRB^bQThQPf>= zWk=7xm{RN3O3#2(3k*nnNQFEjy?fPNef_=FC~&NAsCVZ`eCQFbzv=*D#0R(@QE+uI zK0MqhW#kM8tZ+yZ)fkYij0w!q7PCFaDY(p*U=vzp{LqO_2d4vL9~Ff`u+a}6p?i0 z+L+5jgj>3TRK!HPTdxIao(ESI>SwyL#lL(81rAp z&yN?}k|f6~3vQu@uey-+Uf#B%E%fd`TD*&%g++nSB=Ic1f8jX2FG-htf}SgrrC*?D zi?Zlg63>q-Wyk1!%fRry!NK?tX^uK{33YSN2=(JwKykDqblMR7RMa!oEb8?_X`mMB z_w)?x?p3LCiB!-z#7j|&l)&De{m@{8`$kCVtc__w`_aYwNEP2mrD(hrzfJhm%D~E3kDA&Vd zH3{qSt%m*#tgJz&TkZ68F^1fwu3WtVWl`cgcd`IGdsX_&|SBNig>Gt9>`e)gAkWm7Vd`P*_kQ!|@?yZ{N%h!`Cx*kb=>gjfRs3oPcsWjT36m zKxTl%kcxqGAKFHsL2nDAG8Lsgyt%nO5{5ogN$ElBgg0;2H>;sewXRjKZ$b4{s~ubF z8p8KB*N4ShtKJC*My_zELD{;wxihTPth+ji|H*en3-pRc*(74s% zx^{I2W-c6)@V0RMmd<9qO^t+Fk($%gthvJ(w>v^@&7D!TG1T0;Wph}`rejw_xG}V) zwNt$})Vd|yp@up-wrm26S+SZM)y?7da0uM1)%r*nZb4}eREXp40mKxt;7Hl5ZREp5V1{ESpb4>-h}Gvh-~R>(6_cBC<8Z& z-Fj~;HBwYhAiS+U+)l#59jeneqc+;>okqBRf1tf%YxbqSBfL5LrZl#$$-XtVuFbx9 zBnj;siIai069z@k?t%C)oIGx$8Ik1?3lxvUccUZJs+9vbs!FU6W($lV(mLKYu?BVR zV33Qc-iU%As3}wz1v+S99b4MlQ4rMdrqH(LO$R z+q-j635YVe?d%Q}$aYXiiRxQ6I|Wul4V#+Vnman3CfuOcqw}Y5Gf*Hsg}o#}cg zwhwe7%x^aMmAqE*Xcmu+c$6r4Z58HSOBH2su)O}Tj;Km&()4S7CAHoxE5{=~BA(sP zD~{tG#au`sK7J(43d9~Y^A*2h`AiKjLH#GCE1op%d?nAkF{l@O?oU4`URDJ4(lgIK zDqhNh`oUMf{#|}a6jhi{UalxfvmNONtrqPCeP-s%Gn%Ef3?>Q=+*#06aNxFr`ho*% z3bqy;s4nOzIB)}z>k4)j9Js20QXGZ!L4{M81qX@?^nwF^N-^W_E;#UW|Mr3d|4!tL z|G|O-KlXd_poHZjA)-&s4)Tkj4=qp*JU=^36=5v}2R`AqNZODUsyiCHjOt$#U&YZ| z{Khw}P_tFH(W-B?8a7$swgZe(bm%Z%vq5bhh6-MjZ*kKJTjmpJ#`S1>>(O>BYQuR=mj3(_C9lzFv1YagXSSMXUn|hQEd4Y1 z+Zq&)tnU{5!IvMdZ*ps8Cf#9wQ?RjV`}09v(ZC%5RR;CbfAf>`VRKlA4!wueW0Ue=>&Rdky(aE(p<*@ zl}!7Y?g6z-WyY_B*K<0*S)Me>H)&D~@LtTkz5V%SZ-2hd+n+D-^k>4b5UWtY0hyc2 zQ5=-*Fw~W;R3AHMetNf}q)f&3E7M^FME2lSV1u`V9q7ne6_Qw3ec$P4pi7Lkp1c#+ zjGjhvg&+geHrEERKEF*-3}pXd0GaBZQaBgehoIAy1(d(7+W-#F{OV(8%<5ib=F<`# zmRW>gtu~!+Qh1^+<56fnNgiu59t+J+l82h{C^P?mF_aiu8fM>j$o4c{R+t;EL=EIMRG5|2^z&VZ-*pr;prxUrlVRiLWWC{^s1NG)m`|zi{+Xl6 zXZecg6X9S(c>C0P0FQb_n>qbaR7BEjz^kE%ByTXI1}&)7cfVa>-UI=b*B1?zhn+FT z((Oe`9`uKQfub})fW=lsn}}FVp^2u{J?+RMjy!&1>B;YZL@|@x5&CaOcd^*1l_6uy zTG2h&`Gjzm!}lQYooxCmo^(_y^`4YGA^hpoQvh`wMzT<(Cw{ zOlwmGns%7uXenhn^h$n7sC}NWG2eW?oFZ>wDD9soNy-OyO2K;tE|@>?aEWGXwjM!K ztv+_vtQ>@9VR5yO@gs#n&nq`)R0v*{{zM#weS*p@oF&jPj*7GNS5+r4&dOG2U4M|_BWDl`^qzX--2#O5#2 z*eRC6sSdA9DRfO_qK#?M-xXLeg%Oa8iKWHHPDKGzQD*#q&F_r+ulWUxk8vh$8@szi zYs;S*o5{uG*REC+H^$TznwCoDYrX}X|2%M@HP0xDFfk~5vL47auuB=kDZ;bLv+V>t6bUrKK z`>CM3_aj_xdz}TPPuti(lj(!m4(cc!Dt*2}omY5Rte(TFeiX7+3ymS%k zhgOe%5Z0lX=u~^Hq-%t^C_8&TKi&#!Q8sQIPqK@M{e`%B0jX6pK&7b>k8<%ai{O_nFTJ6>6fs-66biF2$LCJ7 z81J*nOHs0NI#IG7T;7YZq4MVPK{d@4+tN+wRcE%xMaa(hQqKESk#}wvg#pXe?UtM8 z1zcQ)ixbT)xjLtYxZq}at;%vH3avcNxMN-+dAvD}@g}7S?mga2M2ke{;NG#ET4Zu^ z83qgtXHj}2l^8uVWe+_RUw?A4+$f*Qn=IFo$!ZwB6O-jZ|77|0wjo>ZbDXfkyp(2ZJa5WPZtK6|D7rV|G`FF--p&tDddrjEKiMv_ zI`Via6kH)R-E^sq88W1v>>{y?U9m+};Y)HmY$?gJNb-ALu2f*if27uB`Y2)?^~T8L zyTXmKr_{+oB+kj870J`y?#sFl~4Ft%f zhx2IExY5>^7LpAqAa*KBR7P$5p(xqVgu19!y`1B^ToW%l)6G;mf3hp%E}Yz+aW9;_ zFXJwo{Gjb3?XxpeT~x)@N5wSM8FF%G&bHp-k#KHF2XbYqfaOZ93cTjd!sn)bI43nV zoI5HBr-Sgf^=~gBY@Bwhf0X>pGgw~A`u!fqdlT_&{dJE0j%eljQG}$-w-H;|m?`sT zy-*zY3<=2I^?Q?w6d2_w|v%N;s3m$8@dvQa{(a{KprLaoq@I1T#T`kwNqBbaG2YLLZByLKz;1+Q)oYyoE3MF~`UVmXV2J^F+)qxrgEjY-Sf=tf9Ta?4K)sRl3BioKHL~0b%~` zX{-;<0qcKC(8n4`AZPYLi?bVlTLZ+@Nm_uQE%(Fd*5%d^|1H-dRy=CzAp`GiuuK$mT$fi z)C$dS7~h|r5w{Lo@8MLgVm4RW`X2bq8<}c^$6yW1_3F7902UNGSg0j7IQ=)3_DwT-Ayi4-l%GwFu~YYOK8ezl58Nuu zSHP>neBpu|6RT$zMO1*uB$RpyQ>5ci0JIL@JWo^-Dql<7I!_R)@hH}0(Z5OG2v%T| zC}z=&CAq+q&s0I+#DdYVQSx(aFEsoBwp`fOM?6s4`p5B>3XAq3z~+qMm7`K%NN_T5 zwLJ-+c_U}5?Ni>osBN(^7%5$-8A~A0Wq;#%Pn{MR0|XPquZvgmoO!-KkL8C&2WuZf`hL z?~WVwbH)vik2`L7y_|6)>qX;6{oRY}TaM1sfyeR{sP&W&ed6e*0PmyAeu^UIcG)L3uOzFaHD)RcBY zNu7Z8T&0;)RWz{xOE_1Kp1}6LW-OiPdMtW(QMBc&j)yZ#&8#um z`l}u&ZQdNEA({5&ctT4tIe%MEX6CSY?qm@2$zqR#St)t zE{_gU~_7%3?xe&PzQO9-L zTZP$$%pZ%4MPO*=YuepI$>RVZF%{H_;Yi|6tH#;#jz9tC)582W5y4sfo?oU4vxQ4E z4?tXY^EOLAlUafxFWzz2qOKIFB6kYh%!IcBPj5Z5``D>c)tiu zNNFW(Zr}}jEO>7ZjFm>lYKDwk&{D=uVFzIL_CEoX6>SJomysEf_>wiErLIWl(L)uF z8u5s0&T}xGH+E`hT3fGSE!?~!5GYYJ7?Kwrmn8guZs6mT0u6xec zWL)(ew&s^Vm)~Tto%d!?D>r`>)Kv3F#+#|86MlzbTm!!{VpJ#?o$x~_E{CYQZ=vqe zJ}$B-&9~uUwqk*Xgl9*ZlB6z4=V7sL5!!%QMWNkiQNH}l$}XMF!CKBd)okl=YHGA+ z@F3c-t9F?8v4^eyDpERgw~S3;US{j#woNK zlWo$RtEYP%`OkCc50xKewj~>v(hWf z6$0Q0*5Cjz6f9Q&bRkuMrExe`F0p;yGKh+xcowfC9y@Ds++*iz!fw1-$^9m6ENeB- zeB8^`+Vk!AfE{7O57!Uy0Ox~7S0rR zc6zp>)8m=Wk2+}*r)tIdkc8j(1dcixB_bTtJ{o{%|C;qt)#;ZZOX9|hNJ9Gr5sZ3P zSER!H035bBqXP53l6LL2rpl)Jg~&%lJB!Ij6WKE-6dDvUG-7~ERAB_P18&N*rz?=M zQu8E(78L1g<0j%~`PD9ECX3nToMvqiVqF)EbeUJ$`itnSGzU3~ zLLw`U@xjNtjN5DDkPRnNB3<)H#L;dumgHpXpXfRl>C%Gnc5P!mW}sgJYdhW!EzjJ+ z>A(-qlcLIu?AV#aL_LpocHOn3|_uUWNJc-N+(J zEq1c}us>QgS#DmFnk*+ncTT-7uzZu173O6m)oaS+GQ_W(T$Tt}dQpjj_hi3u!$d!A z0ZdFTOSNB^N7ZY~65lqiu+{mqu==%${vb-z@;xWF^2rLL9Jw#I0&p#`iY6;a0+l6D z6H6>#f69CZ4PmkxP#OI}L`__B{F+HsGZ&46P7orhQ9wZU8`tATG9nxOh#jBemaS0TxT@_MmE>X3r*`nEUo>46jO*IL*7HpZaX3mlxZ%94dOWQWlCBh()oHMIN@)&{f=n|-B$;1;rxGFBfA z1b9#96OX8y=(|;Xjxtd&HnYRn?ul?W6m>LF<_!+sy)>G*{o-SjkjFgX;r4zKz3ayk zNzkt)zUdS&5hf19>HONj@cYX*%Ysstrt^)n7-|UcY8VLKBhHJyXiWYbEecyam6} zDFt@352EZrTC^pz9KL9Bh}DI3*)SX!E`^19xJgUZwBy)sQB%vmdGkv9h$p1pRi`MA zcUgr^#$`_Y6G}Se_{Nd_N|UM~X2913OoWiEy%!lCMOpb4`V$ z)I~?8B0cGw%4-Tug*5G`*2v7hlPT_9zS{VHz{iDc#8N%}p?t+u_Qoj%CCC=XD)yF# z8NKZ-&QBGmIBS6mii7AED^9T;k5O^%@XaaCObw80M7=jsHDC7WK%;S=FTBwV}NoBV8}ptT1_BKjAM zTfl4u2ZC8CJ2tqHR)|PHFcuMB=C=qZ)1qY)arlL?!R7}}za(;w4B~iPGKzlHrA>5M zvCu?}&cH^4YIOTs87#zHk<7m%g??MFgslKK?=HX;L|^$<1Qwj$d;$L${Esi=Gnk&$ zi)>2lPq(G$gkByUz`P%JyoNJAw_~*(2`RwVW(6N#Cbsy+9&DBqPBIjKEL!W2ZvXR9 zSYlsdu^!FkQjj_2>Fln}W@774J1IOTE05(DQI;%6mcz09l6ic`PO;@gXS`{dF)Q9^ z&+PPh3$b`?Jmk!tPat1f+~H%Mz8<6B@&B>M-`MJSp7naxIi9}KTn?)o|D_&(;}YzV zG`*1q+Lc<%bj8GSaI*DF5QSsA%S&0gt9nQwKFVmWM6}tZaCSD$A}js~>}o4MFb`Bp z0g8$>He6QN4IUcwnLa>{xu_}&5LKLem<^$=@0%+C+w*hSq;j|Jvc;Jren3ceg{?mY z=5w3&Xb-kTQF`EjIM2-+$JW0>g7r*mPfh31Frfbn-no=-kpto(Y>tpWF6r^C{m+st z6PRgHZ@MkYZ^S>=LmZJLXBRkM!7eb&yspj};x;4B_mWQsb{&73E4$ygk(OakzrvF` z^JnNge26yM_3AlWU$iI-1}`KXDW-MQjP;coW?QIgII+%H>CT1NesbnTJehXfG@%ww znusUR!P4 z=upoIN_FFVQoySR&%<-`dUf4 z()wC?x;m*9&EnBsj}^uSD_s<}(j|>ny1dCsFN;{|g#Vf>7 zqwXTJs4C9bywc%maps&Yi*2lZx5z92KP_0KB|bkkq%wrCMT9D!=#LGP19B8O2q*5(TN@U86Avgr^vU58UH` zFnBD#w8gaH`AU9iS<9fMKMuEvJOI@@x5G*Ami{I=pMVn=*$#`xAJC)3{6l*9%s;}z z=4f{JGOCc%%VCpbPsLXCCYH|lcJa-KlrKqFBaFo)F<%StCG!>Ef}GeZGO?3%F=9HJ z6S^!Ln$Mv*%x(uW7-%bM^Uc!`Jb|s{n6WIot`A!+9*b^2#q_pcPP9}Ejch3nJKmI! z{^B2vvB#|XNe!c5eocejNZUDLM%H*93HXHblUV(HfAx_Hm_I`aQVH`v=z*rlC8{kQ zPAp}klrB~Hl2l-0$&7DU;42V|C1b`-*+SR4iOtKZ1S|_J^9;B~jWU3>a3U7$uGtrB z`3ID3a~@r?E3~4n>JTFsx4k({M)a;(4Qmv$fAgbg6xM!o0*_kXt7X{hFX7@CtE>2J zp?JH-GAT9lK{Mp$*fL0qzSp9iVyJxY2%|d*?&Acvwj;Gebb^vp{!Y;ec8CWCe#X$! zNh%XJy0UOq?M$FS?Z^QS4GNZm(>l39#jyX9xtN$mbE$(S8X1s;UCu~WULR}u29PYm zgwR}26-{ig_2sY)xZsxF2`Ae*QF1_wjX0JL#HZFGY!-BU&k{~%hIJ9$BbM`hi93ZO zt|it8mzt;)j-tdh!cm^MR5<*J()E0~kk)jXY*4c39=Ml`+z&%UTki&Stz29GD8Gs6 z47Mxi7DVp;H7r%1`Dq}{HjAr|lkA1owhHx(oeusJnkOitW2InDM{PMiZv(NInO8UR zxB$@C_^{bdI}6$CnyOjhmgHzoNhUod$wt@Aa_ohdWobkjFF>x%*wX2^=_$Hme6HKH-5;`;F*yGNMr2SwG>?NV{E zIcciwt`Gs${8Gb|E;%FadVUEqtz;^0JS*(>Gc96T!nB;}GN#Kx!D0m-ZcAH1Bc!c= z?-rb0=kwuy_p|~*Q+j`t*4K_~ArOBsH%?_V0gPYrpjKh-Mn6~|?N+#kCv$?HWj_Bx zeD+X3&g5n5KPJ!EEYG*evwxQ7&&U%u6>`(R%f8EI`JQIqb-$1$+ z__|ZRqkCFUN+JJ*y(Wa7@76t4o#JZ z$OcH6*NazNwBgr$euWboU=CQh5Qr;eMI^@ykfT<7LLgBMlg;F7E5S0&+>(7O)y$^s zTOlr}yGg*I5gd*wWllmLUjq?-F0-tk$k<02*LgB-J+>HEywWgQU%(LpEqY8@BG_Ss zD}3G`HI^Jx7H514Ui3%lt04JG^jHBRQo5-nv~(LaHvYFc73Ol{sTvFzKZcZ*ZfVPp zUFOIMA&o`HF3-L>IOn!1H{Ig1-O99(pAwegbtd!bq|9x4>$|AmU6bN70Ml+Q=C(w- zS_hruq@U9uy|bN*jO$hx-yVdv`!Jf0kg8N7Jn|oBb7F~AUgz}6oi$K4tQYx< z1axc}cIoA#u80&)LxlUWf)4ccswgc%S#Yt@GENRMQ=9|5J^bR{jClkrK7Z-E5W7b` zs)IE4+8JF@_7n9n&10I+)X%hl=>n#OOpBNnGYv3Z$h3rMDbqzv%b1okUCeX|)1^$8 zF};N8rA#klx}53dOs`;iCDRp5uVQ*N(`%TjOs{2n9n77i2Oz&cPH`7|C8q*Nd zI;QnZ8<>WfHZpBu8e!VZbR*LirmajjF>Pb2Gi_&j57W&|JD7Gd-NN)4%thGrgZ_57Qk?cQTDJ?Pa=)>29WbnD#M!fa!xw`0o}bdc#o zOox~bGaX^NkLklq6HNCreT3-&rUugwGyN5&2br2olT1It^bpfgrWVs*Wje+*#dMtM zuQB~~rjIiHDAV6y`kPFDi|GW@-)8z4(~mKIoayf{{W#O#W%>luPcZ#GroYehFw;L^ z`iD&ah^fu=Nv5A<`o~P4V)`dc|CH&cn0}h+(@a0Z^s`K#Vfrl7KVy1?=~1SC&h&Fk zpJVzw)6X;g3#Na`^aZAW#q_V4eu3$WOuxwVZzsB_Mnf?RQDW+d%`j1S%!Sp!Oe`5Mgrr%=vZKkg=J;C%lOiwcX zzf8Z&^m|OFnSP(?DW*SQ`a08pX8J>>|HAYQraxl(uS|c;^i8HeVfq%+(@f7W{VCIb zWBNAJcbNV=)Bj-lGp1*m{wLF)GkuroIi|m0dYe@jTICnXD5h&M{2;y@FB#o%1`<27O{@Hm8o zagsD2$G5A_`4|iR3Ak~i43tpm#J6hPDLEPGd;`XF!M|4A0Zjy|%r{V!#0M<>Y5-_H z#owvfMNSo_t;H0XnV+Tr)5dffHx7M?+iaM`iiRu|8~nvLnSk+PI<~k+QCu`|^bnC^ z6=wHNtagd?wS{0%m1O{Vk9?j^0PwOH)niVo(FdG#d{auS@bpn#(K6?~8h-8UP}+F>(mP`ALG#GD0!9Tx(mf*SS@V@P;Go4SWB6vnC3g2anMJ3^`tL64Z}|#N zU)@xj{{U71so9DZKw3XF%4d9io^Q`&vX5!OwEs1K;%Y0VVZS=~Qc;>tN;oei=^|cr z;l{E8tG1|*1=aVx<`)YE8hkv}kI#E?HRJd}woc6tydQZyD-#LYimGs%;-xq(%5AaK z%6>?U_AN52M{MJ|OE2TV+O<91g%IcJV$Q-9eesQEsm@)7%=($j=aU!a6W6lqU$fZo zdI@%au?lYn(NVZ4yK8+$;yP<2dJ@(wmNH+b-a~-ORKv_&1bRp z#udn4Z=)(j6y5Ir&4SDq)zGfa{KNB3&^mnf8hTo&I<3$XBQti={*t0lzV1?D?MWL1b*^L7!pK6^r>cwvdG8tnTBs?>AaT&1V2# zs+U4(lS0gOV$g29E)M988}8&~GMWJTjVp4H#$hL1x+#xt9GeGe*ujRODi;R z@rhjzaAi5bWzLOd+H38w>4UgpD{lpMkn>6S6~ybTNkZ|~k!OzxjgRjO)s02PEtlX4 zCCQ)3yUg{ml2p;+lF&-m(~Z{6tIms1h`1JQc@bSTyT8FbF=<8sd(zwnikW679%A{p z+*~F;3Tk&(XVg~eTK?Rq-Texy7`j<8&!_&fctXV-S&wnVxQTW~GxtUKvprO11d8nm zXb6g1LUBpL3}TRpzDz1Ub4s&J&pj%Uk57DRdPaEg`Go)t z0zXG7@qNi8AyUM&1Qf;0qsI_GYKszytE_IN2yC#AI(Dkdxrt=vwPUqmd2(L=QIj~) z7OA13SLNe{4;|3{=@;PZdcGYG@gC|z%COWd!^16*cLl`KZ5SIS_L;Ef_%e_%q3Yl) zhMqNHz`=QxA}nJkePz;I&dw5wfQ4T~pyTDH%FYS|@TbV=(dlzj!u}CX6}&wk0`&}NCeDK^N)oLH!y?i~ykYp(CVg~N zd_@YYYHB~C@*6BET8`nbpkzO>QZ?D0sCGQ{H=R+64mi1flt@IUrB;K!rmAW1x|Zxc zYK=+p9~ATe7>wt{ZuSy8R)+@6r`4#>`ME@S4qVezxV{Jwih~{zjPc)pzm=^wpy#RAKJi& z3Ao7O&>70$T~gP`=dQZp)_Ec) z!?ufLNH&VoyxeM`FAjNR&U|(VNUihu>svgmz5bNm=2X<|mcPqA>(;wl!#RdZF+q|Gj2 zH@FGJw&1UMBs7{u0&KzDW)vmO{Yc~bB>oMlX@tz#WPRG3nm(jUh#D&ax7cCzmN<96 zRp>IzrMaYM^ZCvgf7oHoS)6JuN4ar%Xb}6F+1DZ*xkDZ*!VI+C(=^e`IC4<3z4ovu zXxbxct`VM*cDCUR)Nw)x*AeMlQjt+Up-qHp?`cmI*0w8&cV_OvkUjYZ{;LO!AHOT` HyY{~T_H*-9 diff --git a/3B2/rom_rev3_bin.h b/3B2/rom_rev3_bin.h deleted file mode 100644 index e63d4881..00000000 --- a/3B2/rom_rev3_bin.h +++ /dev/null @@ -1,8225 +0,0 @@ -#ifndef ROM_rom_rev3_bin_H -#define ROM_rom_rev3_bin_H 0 -/* - 3B2/rom_rev3_bin.h produced at Mon Aug 23 13:30:22 2021 - from 3B2/rom_rev3.bin which was last modified at Mon Jul 26 08:03:30 2021 - file size: 131072 (0x20000) - checksum: 0xFFDC0EB8 - This file is a generated file and should NOT be edited or changed by hand. -*/ -#undef BOOT_CODE_SIZE -#define BOOT_CODE_SIZE 0x20000 -#undef BOOT_CODE_FILENAME -#define BOOT_CODE_FILENAME "rom_rev3.bin" -#undef BOOT_CODE_ARRAY -#define BOOT_CODE_ARRAY rom_rev3_bin -#if !defined(BOOT_CODE_SIZE_1) -#define BOOT_CODE_SIZE_1 0x20000 -#define BOOT_CODE_FILENAME_1 "rom_rev3.bin" -#define BOOT_CODE_ARRAY_1 rom_rev3_bin -#elif !defined(BOOT_CODE_SIZE_2) -#define BOOT_CODE_SIZE_2 0x20000 -#define BOOT_CODE_FILENAME_2 "rom_rev3.bin" -#define BOOT_CODE_ARRAY_2 rom_rev3_bin -#elif !defined(BOOT_CODE_SIZE_3) -#define BOOT_CODE_SIZE_3 0x20000 -#define BOOT_CODE_FILENAME_3 "rom_rev3.bin" -#define BOOT_CODE_ARRAY_3 rom_rev3_bin -#elif !defined(BOOT_CODE_SIZE_4) -#define BOOT_CODE_SIZE_4 0x20000 -#define BOOT_CODE_FILENAME_4 "rom_rev3.bin" -#define BOOT_CODE_ARRAY_4 rom_rev3_bin -#endif -unsigned char rom_rev3_bin[] = { -0x00,0x00,0x05,0x78,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, -0x00,0x00,0x05,0xF8,0x02,0x00,0x00,0x30,0x02,0x00,0x00,0x30,0x02,0x00,0x00,0x80, -0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0, -0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x01,0x20, -0x02,0x00,0x01,0x70,0x02,0x00,0x01,0xC0,0x02,0x00,0x02,0x10,0x02,0x00,0x02,0x60, -0x02,0x00,0x02,0xB0,0x02,0x00,0x02,0xB0,0x02,0x00,0x03,0x50,0x02,0x00,0x00,0xD0, -0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0, -0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0, -0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0, -0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0, -0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0, -0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0, -0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0, -0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0, -0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0, -0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0, -0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0, -0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0, -0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0, -0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0, -0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0, -0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0, -0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0, -0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0, -0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0, -0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0, -0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0, -0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0, -0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0, -0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0, -0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0, -0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0, -0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0, -0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0, -0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0, -0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0, -0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0, -0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0, -0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0, -0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0, -0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0, -0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0, -0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0, -0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0, -0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0, -0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0, -0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0, -0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0, -0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0, -0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0, -0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0, -0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0, -0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0, -0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0, -0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0, -0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0, -0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0, -0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0, -0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0, -0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0, -0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0, -0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0, -0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0, -0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0, -0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0, -0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x00,0xD0,0x02,0x00,0x03,0xA0, -0x02,0x00,0x12,0xC4,0x02,0x00,0x03,0xA4,0x02,0x00,0x03,0xA8,0x02,0x00,0x03,0xAC, -0x02,0x00,0x03,0xB0,0x00,0x00,0x00,0x00,0x02,0x00,0x04,0x04,0x00,0x00,0x44,0x98, -0x00,0x00,0x3B,0xB4,0x00,0x00,0x39,0xF0,0x00,0x00,0x40,0xE0,0x00,0x00,0x6F,0xE8, -0x00,0x00,0x24,0xCC,0x02,0x00,0x04,0x08,0x00,0x00,0x3B,0x4C,0x00,0x00,0x4A,0x8C, -0x00,0x00,0x49,0x2C,0x00,0x00,0x49,0xDC,0x00,0x00,0x00,0x00,0x00,0x00,0x65,0x2C, -0x02,0x00,0x04,0x09,0x02,0x00,0x04,0x0C,0x02,0x00,0x12,0xB4,0x00,0x00,0x12,0xEC, -0x00,0x00,0x00,0x00,0x02,0x00,0x04,0x10,0x02,0x00,0x04,0x14,0x02,0x00,0x04,0x18, -0x00,0x00,0x34,0x44,0x02,0x00,0x04,0x1C,0x00,0x01,0xFF,0xF0,0x02,0x00,0x04,0x20, -0x02,0x00,0x04,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x4B,0x6C,0x00,0x00,0x4B,0x84, -0x00,0x00,0x4B,0xC8,0x00,0x00,0x44,0xD0,0x00,0x00,0x4C,0x2C,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x4D,0x28,0x00,0x00,0x4F,0xA4, -0x00,0x00,0x48,0xE2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x02,0x00,0x04,0x25,0x00,0x00,0x53,0x7E,0x00,0x00,0x33,0x9C,0x02,0x00,0x04,0x28, -0x02,0x00,0x04,0x2C,0x02,0x00,0x04,0x3C,0x00,0x00,0x64,0xAE,0x02,0x00,0x04,0x40, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0xE1,0x00,0x00,0x00,0x38,0xF0, -0x00,0x81,0xE1,0x00,0x00,0x00,0x39,0x28,0x00,0x81,0xE1,0x00,0x00,0x00,0x38,0xF0, -0x00,0x81,0xE1,0x00,0x00,0x00,0x38,0xF0,0x00,0x81,0xE1,0x00,0x00,0x00,0x38,0xF0, -0x00,0x81,0xE1,0x00,0x00,0x00,0x38,0xF0,0x00,0x81,0xE1,0x00,0x00,0x00,0x38,0xF0, -0x00,0x81,0xE1,0x00,0x00,0x00,0x38,0xF0,0x00,0x81,0xE1,0x00,0x00,0x00,0x38,0xF0, -0x00,0x81,0xE1,0x00,0x00,0x00,0x38,0xF0,0x00,0x81,0xE1,0x00,0x00,0x00,0x38,0xF0, -0x00,0x81,0xE1,0x00,0x00,0x00,0x38,0xF0,0x00,0x81,0xE1,0x00,0x00,0x00,0x38,0xF0, -0x00,0x81,0xE1,0x00,0x00,0x00,0x38,0xF0,0x00,0x81,0xE1,0x00,0x00,0x00,0x39,0x28, -0x00,0x81,0xE1,0x00,0x00,0x00,0x38,0xF0,0x00,0x81,0xE1,0x80,0x00,0x00,0x13,0x10, -0x02,0x00,0x04,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x02,0x00,0x04,0x44,0x02,0x00,0x0C,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x53,0x42,0x44,0x00,0x46,0x44,0x35,0x00, -0x0A,0x45,0x6E,0x74,0x65,0x72,0x20,0x6E,0x61,0x6D,0x65,0x20,0x6F,0x66,0x20,0x70, -0x72,0x6F,0x67,0x72,0x61,0x6D,0x20,0x74,0x6F,0x20,0x65,0x78,0x65,0x63,0x75,0x74, -0x65,0x20,0x5B,0x20,0x25,0x73,0x20,0x5D,0x3A,0x20,0x00,0x0A,0x00,0x70,0x61,0x73, -0x73,0x77,0x64,0x00,0x0A,0x65,0x6E,0x74,0x65,0x72,0x20,0x6F,0x6C,0x64,0x20,0x70, -0x61,0x73,0x73,0x77,0x6F,0x72,0x64,0x3A,0x20,0x00,0x0A,0x65,0x6E,0x74,0x65,0x72, -0x20,0x6E,0x65,0x77,0x20,0x70,0x61,0x73,0x73,0x77,0x6F,0x72,0x64,0x3A,0x20,0x00, -0x0A,0x63,0x6F,0x6E,0x66,0x69,0x72,0x6D,0x61,0x74,0x69,0x6F,0x6E,0x3A,0x20,0x00, -0x0A,0x00,0x6E,0x65,0x77,0x6B,0x65,0x79,0x00,0x0A,0x43,0x72,0x65,0x61,0x74,0x69, -0x6E,0x67,0x20,0x61,0x20,0x66,0x6C,0x6F,0x70,0x70,0x79,0x20,0x6B,0x65,0x79,0x20, -0x74,0x6F,0x20,0x65,0x6E,0x61,0x62,0x6C,0x65,0x20,0x63,0x6C,0x65,0x61,0x72,0x69, -0x6E,0x67,0x20,0x6F,0x66,0x20,0x73,0x61,0x76,0x65,0x64,0x20,0x4E,0x56,0x52,0x41, -0x4D,0x20,0x69,0x6E,0x66,0x6F,0x72,0x6D,0x61,0x74,0x69,0x6F,0x6E,0x0A,0x0A,0x00, -0x67,0x6F,0x00,0x49,0x6E,0x73,0x65,0x72,0x74,0x20,0x61,0x20,0x66,0x6F,0x72,0x6D, -0x61,0x74,0x74,0x65,0x64,0x20,0x66,0x6C,0x6F,0x70,0x70,0x79,0x2C,0x20,0x74,0x68, -0x65,0x6E,0x20,0x74,0x79,0x70,0x65,0x20,0x27,0x67,0x6F,0x27,0x20,0x28,0x71,0x20, -0x74,0x6F,0x20,0x71,0x75,0x69,0x74,0x29,0x3A,0x20,0x00,0x0A,0x43,0x72,0x65,0x61, -0x74,0x69,0x6F,0x6E,0x20,0x6F,0x66,0x20,0x66,0x6C,0x6F,0x70,0x70,0x79,0x20,0x6B, -0x65,0x79,0x20,0x63,0x6F,0x6D,0x70,0x6C,0x65,0x74,0x65,0x0A,0x0A,0x00,0x73,0x79, -0x73,0x64,0x75,0x6D,0x70,0x00,0x76,0x65,0x72,0x73,0x69,0x6F,0x6E,0x00,0x0A,0x43, -0x72,0x65,0x61,0x74,0x65,0x64,0x3A,0x20,0x25,0x73,0x0A,0x00,0x49,0x73,0x73,0x75, -0x65,0x3A,0x20,0x25,0x30,0x38,0x6C,0x78,0x0A,0x00,0x52,0x65,0x6C,0x65,0x61,0x73, -0x65,0x3A,0x20,0x25,0x73,0x0A,0x4C,0x6F,0x61,0x64,0x3A,0x20,0x25,0x73,0x0A,0x00, -0x53,0x65,0x72,0x69,0x61,0x6C,0x20,0x4E,0x75,0x6D,0x62,0x65,0x72,0x3A,0x20,0x25, -0x30,0x38,0x6C,0x78,0x0A,0x0A,0x00,0x71,0x00,0x65,0x78,0x70,0x72,0x65,0x73,0x73, -0x00,0x65,0x64,0x74,0x00,0x65,0x72,0x72,0x6F,0x72,0x69,0x6E,0x66,0x6F,0x00,0x62, -0x61,0x75,0x64,0x00,0x3F,0x00,0x0A,0x45,0x6E,0x74,0x65,0x72,0x20,0x61,0x6E,0x20, -0x65,0x78,0x65,0x63,0x75,0x74,0x61,0x62,0x6C,0x65,0x20,0x6F,0x72,0x20,0x73,0x79, -0x73,0x74,0x65,0x6D,0x20,0x66,0x69,0x6C,0x65,0x2C,0x20,0x61,0x20,0x64,0x69,0x72, -0x65,0x63,0x74,0x6F,0x72,0x79,0x20,0x6E,0x61,0x6D,0x65,0x2C,0x0A,0x6F,0x72,0x20, -0x6F,0x6E,0x65,0x20,0x6F,0x66,0x20,0x74,0x68,0x65,0x20,0x70,0x6F,0x73,0x73,0x69, -0x62,0x6C,0x65,0x20,0x66,0x69,0x72,0x6D,0x77,0x61,0x72,0x65,0x20,0x70,0x72,0x6F, -0x67,0x72,0x61,0x6D,0x20,0x6E,0x61,0x6D,0x65,0x73,0x3A,0x0A,0x0A,0x62,0x61,0x75, -0x64,0x0A,0x65,0x64,0x74,0x0A,0x65,0x72,0x72,0x6F,0x72,0x69,0x6E,0x66,0x6F,0x0A, -0x65,0x78,0x70,0x72,0x65,0x73,0x73,0x0A,0x6E,0x65,0x77,0x6B,0x65,0x79,0x0A,0x70, -0x61,0x73,0x73,0x77,0x64,0x0A,0x73,0x79,0x73,0x64,0x75,0x6D,0x70,0x0A,0x76,0x65, -0x72,0x73,0x69,0x6F,0x6E,0x0A,0x28,0x71,0x20,0x74,0x6F,0x20,0x71,0x75,0x69,0x74, -0x29,0x0A,0x0A,0x00,0x2A,0x56,0x4F,0x49,0x44,0x2A,0x00,0x09,0x50,0x6F,0x73,0x73, -0x69,0x62,0x6C,0x65,0x20,0x6C,0x6F,0x61,0x64,0x20,0x64,0x65,0x76,0x69,0x63,0x65, -0x73,0x20,0x61,0x72,0x65,0x3A,0x0A,0x0A,0x00,0x4F,0x70,0x74,0x69,0x6F,0x6E,0x20, -0x4E,0x75,0x6D,0x62,0x65,0x72,0x20,0x20,0x20,0x20,0x53,0x6C,0x6F,0x74,0x20,0x20, -0x20,0x20,0x20,0x54,0x79,0x70,0x65,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, -0x4E,0x61,0x6D,0x65,0x0A,0x00,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D, -0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D, -0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D, -0x2D,0x0A,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x25,0x32,0x64,0x20,0x20,0x20,0x20, -0x20,0x20,0x20,0x20,0x20,0x25,0x32,0x64,0x00,0x20,0x20,0x20,0x20,0x20,0x49,0x2F, -0x4F,0x20,0x42,0x55,0x53,0x20,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x42,0x55,0x42, -0x55,0x53,0x20,0x20,0x00,0x20,0x20,0x20,0x20,0x20,0x49,0x4E,0x54,0x45,0x47,0x52, -0x41,0x4C,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, -0x00,0x2A,0x56,0x4F,0x49,0x44,0x2A,0x00,0x20,0x20,0x20,0x20,0x20,0x25,0x31,0x30, -0x73,0x00,0x0A,0x00,0x0A,0x45,0x6E,0x74,0x65,0x72,0x20,0x4C,0x6F,0x61,0x64,0x20, -0x44,0x65,0x76,0x69,0x63,0x65,0x20,0x4F,0x70,0x74,0x69,0x6F,0x6E,0x20,0x4E,0x75, -0x6D,0x62,0x65,0x72,0x20,0x00,0x5B,0x25,0x64,0x00,0x2A,0x56,0x4F,0x49,0x44,0x2A, -0x00,0x20,0x28,0x25,0x73,0x29,0x00,0x5D,0x3A,0x20,0x00,0x0A,0x00,0x25,0x64,0x00, -0x0A,0x25,0x73,0x20,0x69,0x73,0x20,0x6E,0x6F,0x74,0x20,0x61,0x20,0x76,0x61,0x6C, -0x69,0x64,0x20,0x6F,0x70,0x74,0x69,0x6F,0x6E,0x20,0x6E,0x75,0x6D,0x62,0x65,0x72, -0x2E,0x0A,0x00,0x50,0x6F,0x73,0x73,0x69,0x62,0x6C,0x65,0x20,0x73,0x75,0x62,0x64, -0x65,0x76,0x69,0x63,0x65,0x73,0x20,0x61,0x72,0x65,0x3A,0x0A,0x0A,0x00,0x4F,0x70, -0x74,0x69,0x6F,0x6E,0x20,0x4E,0x75,0x6D,0x62,0x65,0x72,0x20,0x20,0x20,0x53,0x75, -0x62,0x64,0x65,0x76,0x69,0x63,0x65,0x20,0x20,0x20,0x20,0x4E,0x61,0x6D,0x65,0x0A, -0x00,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D, -0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D, -0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x2D,0x0A,0x00,0x20, -0x20,0x20,0x20,0x20,0x20,0x25,0x32,0x64,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, -0x20,0x20,0x25,0x32,0x64,0x00,0x2A,0x56,0x4F,0x49,0x44,0x2A,0x00,0x20,0x20,0x20, -0x20,0x20,0x20,0x20,0x20,0x20,0x25,0x31,0x30,0x73,0x00,0x0A,0x00,0x0A,0x45,0x6E, -0x74,0x65,0x72,0x20,0x53,0x75,0x62,0x64,0x65,0x76,0x69,0x63,0x65,0x20,0x4F,0x70, -0x74,0x69,0x6F,0x6E,0x20,0x4E,0x75,0x6D,0x62,0x65,0x72,0x20,0x00,0x5B,0x25,0x64, -0x00,0x2A,0x56,0x4F,0x49,0x44,0x2A,0x00,0x20,0x28,0x25,0x73,0x29,0x00,0x5D,0x3A, -0x20,0x00,0x0A,0x00,0x25,0x64,0x00,0x0A,0x25,0x73,0x20,0x69,0x73,0x20,0x6E,0x6F, -0x74,0x20,0x61,0x20,0x76,0x61,0x6C,0x69,0x64,0x20,0x6F,0x70,0x74,0x69,0x6F,0x6E, -0x20,0x6E,0x75,0x6D,0x62,0x65,0x72,0x2E,0x0A,0x00,0x0A,0x53,0x4F,0x52,0x52,0x59, -0x21,0x0A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x32,0x01,0x00, -0x00,0x00,0x00,0x00,0x00,0x4B,0x02,0x00,0x80,0x00,0x00,0x00,0x00,0x6E,0x03,0x11, -0x00,0x00,0x00,0x00,0x00,0x86,0x04,0x22,0x00,0x00,0x00,0x00,0x00,0x96,0x05,0x33, -0x80,0x00,0x00,0x00,0x00,0xC8,0x06,0x33,0x00,0x00,0x00,0x00,0x01,0x2C,0x07,0x44, -0x00,0x00,0x00,0x00,0x02,0x58,0x08,0x55,0x00,0x00,0x00,0x00,0x04,0xB0,0x09,0x66, -0x00,0x00,0x00,0x00,0x07,0x08,0x0A,0xAA,0x80,0x00,0x00,0x00,0x09,0x60,0x0B,0x88, -0x00,0x00,0x00,0x00,0x12,0xC0,0x0C,0x99,0x00,0x00,0x00,0x00,0x25,0x80,0x0D,0xBB, -0x00,0x00,0x00,0x00,0x4B,0x00,0x0E,0xCC,0x80,0x00,0x00,0x00,0x96,0x00,0x0F,0xCC, -0x00,0x00,0x00,0x00,0x55,0x6E,0x73,0x75,0x70,0x70,0x6F,0x72,0x74,0x65,0x64,0x20, -0x42,0x61,0x75,0x64,0x20,0x52,0x61,0x74,0x65,0x3A,0x20,0x25,0x64,0x0A,0x00,0x45, -0x6E,0x74,0x65,0x72,0x20,0x6E,0x65,0x77,0x20,0x72,0x61,0x74,0x65,0x20,0x5B,0x25, -0x64,0x5D,0x3A,0x20,0x00,0x25,0x64,0x00,0x55,0x6E,0x73,0x75,0x70,0x70,0x6F,0x72, -0x74,0x65,0x64,0x20,0x42,0x61,0x75,0x64,0x20,0x52,0x61,0x74,0x65,0x3A,0x20,0x25, -0x73,0x0A,0x00,0x43,0x68,0x61,0x6E,0x67,0x65,0x20,0x62,0x61,0x75,0x64,0x20,0x72, -0x61,0x74,0x65,0x20,0x74,0x6F,0x20,0x25,0x64,0x0A,0x00,0x00,0x20,0x08,0x00,0x0A, -0x6D,0x61,0x78,0x20,0x69,0x6E,0x70,0x75,0x74,0x20,0x6F,0x66,0x20,0x25,0x64,0x20, -0x63,0x68,0x61,0x72,0x61,0x63,0x74,0x65,0x72,0x73,0x2C,0x20,0x72,0x65,0x2D,0x65, -0x6E,0x74,0x65,0x72,0x20,0x65,0x6E,0x74,0x69,0x72,0x65,0x20,0x6C,0x69,0x6E,0x65, -0x0A,0x00,0x00,0x00,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x61,0x62, -0x63,0x64,0x65,0x66,0x00,0x00,0x00,0x00,0x28,0x6E,0x75,0x6C,0x6C,0x20,0x70,0x6F, -0x69,0x6E,0x74,0x65,0x72,0x29,0x00,0x00,0x00,0x00,0x46,0x35,0x00,0x00,0x46,0x4D, -0x00,0x00,0x46,0x62,0x00,0x00,0x46,0x77,0x0A,0x0A,0x43,0x75,0x72,0x72,0x65,0x6E, -0x74,0x20,0x53,0x79,0x73,0x74,0x65,0x6D,0x20,0x43,0x6F,0x6E,0x66,0x69,0x67,0x75, -0x72,0x61,0x74,0x69,0x6F,0x6E,0x0A,0x0A,0x00,0x53,0x79,0x73,0x74,0x65,0x6D,0x20, -0x42,0x6F,0x61,0x72,0x64,0x20,0x6D,0x65,0x6D,0x6F,0x72,0x79,0x20,0x73,0x69,0x7A, -0x65,0x3A,0x20,0x00,0x25,0x64,0x20,0x6D,0x65,0x67,0x61,0x62,0x79,0x74,0x65,0x28, -0x73,0x29,0x0A,0x00,0x23,0x25,0x64,0x20,0x2D,0x20,0x25,0x64,0x20,0x6D,0x65,0x67, -0x61,0x62,0x79,0x74,0x65,0x28,0x73,0x29,0x2C,0x20,0x00,0x0A,0x0A,0x25,0x30,0x32, -0x64,0x20,0x2D,0x20,0x64,0x65,0x76,0x69,0x63,0x65,0x20,0x6E,0x61,0x6D,0x65,0x20, -0x3D,0x20,0x25,0x2D,0x39,0x73,0x2C,0x20,0x00,0x6F,0x63,0x63,0x75,0x72,0x72,0x65, -0x6E,0x63,0x65,0x20,0x3D,0x20,0x25,0x32,0x64,0x2C,0x20,0x73,0x6C,0x6F,0x74,0x20, -0x3D,0x20,0x25,0x30,0x32,0x64,0x2C,0x20,0x49,0x44,0x20,0x63,0x6F,0x64,0x65,0x20, -0x3D,0x20,0x30,0x78,0x25,0x30,0x32,0x78,0x0A,0x00,0x69,0x6E,0x74,0x65,0x67,0x72, -0x61,0x6C,0x20,0x69,0x2F,0x6F,0x20,0x62,0x75,0x73,0x00,0x63,0x6F,0x2D,0x70,0x72, -0x6F,0x63,0x65,0x73,0x73,0x6F,0x72,0x00,0x6D,0x69,0x63,0x72,0x6F,0x62,0x75,0x73, -0x00,0x62,0x75,0x66,0x66,0x65,0x72,0x65,0x64,0x20,0x6D,0x69,0x63,0x72,0x6F,0x62, -0x75,0x73,0x00,0x3F,0x00,0x20,0x20,0x20,0x20,0x20,0x74,0x79,0x70,0x65,0x20,0x3D, -0x20,0x25,0x73,0x0A,0x00,0x20,0x20,0x20,0x20,0x20,0x62,0x6F,0x6F,0x74,0x20,0x64, -0x65,0x76,0x69,0x63,0x65,0x20,0x3D,0x20,0x25,0x63,0x2C,0x20,0x62,0x6F,0x61,0x72, -0x64,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x3D,0x20,0x25,0x73,0x2C,0x20,0x77,0x6F, -0x72,0x64,0x20,0x77,0x69,0x64,0x74,0x68,0x20,0x3D,0x20,0x25,0x64,0x20,0x62,0x79, -0x74,0x65,0x28,0x73,0x29,0x0A,0x00,0x64,0x6F,0x75,0x62,0x6C,0x65,0x00,0x73,0x69, -0x6E,0x67,0x6C,0x65,0x00,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x71,0x20,0x51,0x20, -0x73,0x69,0x7A,0x65,0x20,0x3D,0x20,0x30,0x78,0x25,0x30,0x32,0x78,0x2C,0x20,0x63, -0x6F,0x6D,0x70,0x20,0x51,0x20,0x73,0x69,0x7A,0x65,0x20,0x3D,0x20,0x30,0x78,0x25, -0x30,0x32,0x78,0x00,0x2C,0x20,0x69,0x6E,0x64,0x69,0x72,0x65,0x63,0x74,0x20,0x65, -0x64,0x74,0x00,0x0A,0x20,0x20,0x20,0x20,0x20,0x73,0x75,0x62,0x64,0x65,0x76,0x69, -0x63,0x65,0x28,0x73,0x29,0x00,0x25,0x73,0x23,0x25,0x30,0x32,0x64,0x20,0x3D,0x20, -0x25,0x2D,0x39,0x73,0x2C,0x20,0x49,0x44,0x20,0x63,0x6F,0x64,0x65,0x20,0x3D,0x20, -0x30,0x78,0x25,0x30,0x32,0x78,0x00,0x0A,0x20,0x20,0x20,0x20,0x20,0x00,0x2C,0x20, -0x00,0x0A,0x0A,0x50,0x72,0x65,0x73,0x73,0x20,0x61,0x6E,0x79,0x20,0x6B,0x65,0x79, -0x20,0x74,0x6F,0x20,0x63,0x6F,0x6E,0x74,0x69,0x6E,0x75,0x65,0x0A,0x00,0x0A,0x44, -0x4F,0x4E,0x45,0x0A,0x0A,0x00,0x00,0x00,0x50,0x45,0x52,0x49,0x50,0x48,0x45,0x52, -0x41,0x4C,0x20,0x49,0x2F,0x4F,0x20,0x25,0x73,0x20,0x45,0x52,0x52,0x4F,0x52,0x20, -0x41,0x54,0x20,0x42,0x4C,0x4F,0x43,0x4B,0x20,0x25,0x64,0x2C,0x20,0x53,0x55,0x42, -0x44,0x45,0x56,0x49,0x43,0x45,0x20,0x25,0x64,0x2C,0x20,0x53,0x4C,0x4F,0x54,0x20, -0x25,0x64,0x0A,0x00,0x52,0x45,0x41,0x44,0x00,0x57,0x52,0x49,0x54,0x45,0x00,0x30, -0x34,0x3A,0x20,0x55,0x4E,0x45,0x58,0x50,0x45,0x43,0x54,0x45,0x44,0x20,0x49,0x4E, -0x54,0x45,0x52,0x52,0x55,0x50,0x54,0x0A,0x00,0x00,0x00,0x00,0x0A,0x46,0x57,0x20, -0x45,0x52,0x52,0x4F,0x52,0x20,0x32,0x2D,0x25,0x73,0x0A,0x00,0x20,0x20,0x20,0x20, -0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x45,0x58,0x45,0x43,0x55, -0x54,0x49,0x4F,0x4E,0x20,0x48,0x41,0x4C,0x54,0x45,0x44,0x0A,0x00,0x00,0x00,0x00, -0x30,0x31,0x3A,0x20,0x4E,0x56,0x52,0x41,0x4D,0x20,0x53,0x41,0x4E,0x49,0x54,0x59, -0x20,0x46,0x41,0x49,0x4C,0x55,0x52,0x45,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20, -0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x44,0x45,0x46,0x41,0x55,0x4C,0x54,0x20, -0x56,0x41,0x4C,0x55,0x45,0x53,0x20,0x41,0x53,0x53,0x55,0x4D,0x45,0x44,0x0A,0x20, -0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x49,0x46, -0x20,0x52,0x45,0x50,0x45,0x41,0x54,0x45,0x44,0x2C,0x20,0x43,0x48,0x45,0x43,0x4B, -0x20,0x54,0x48,0x45,0x20,0x42,0x41,0x54,0x54,0x45,0x52,0x59,0x0A,0x00,0x0A,0x46, -0x57,0x20,0x57,0x41,0x52,0x4E,0x49,0x4E,0x47,0x3A,0x20,0x4E,0x56,0x52,0x41,0x4D, -0x20,0x44,0x45,0x46,0x41,0x55,0x4C,0x54,0x20,0x56,0x41,0x4C,0x55,0x45,0x53,0x20, -0x41,0x53,0x53,0x55,0x4D,0x45,0x44,0x0A,0x0A,0x00,0x30,0x35,0x3A,0x20,0x53,0x45, -0x4C,0x46,0x2D,0x43,0x4F,0x4E,0x46,0x49,0x47,0x55,0x52,0x41,0x54,0x49,0x4F,0x4E, -0x20,0x46,0x41,0x49,0x4C,0x55,0x52,0x45,0x00,0x30,0x36,0x3A,0x20,0x42,0x4F,0x4F, -0x54,0x20,0x46,0x41,0x49,0x4C,0x55,0x52,0x45,0x00,0x30,0x37,0x3A,0x20,0x46,0x4C, -0x4F,0x50,0x50,0x59,0x20,0x4B,0x45,0x59,0x20,0x43,0x52,0x45,0x41,0x54,0x45,0x20, -0x46,0x41,0x49,0x4C,0x55,0x52,0x45,0x00,0x30,0x38,0x3A,0x20,0x4D,0x45,0x4D,0x4F, -0x52,0x59,0x20,0x54,0x45,0x53,0x54,0x20,0x46,0x41,0x49,0x4C,0x55,0x52,0x45,0x00, -0x25,0x73,0x00,0x0A,0x0A,0x53,0x45,0x4C,0x46,0x2D,0x43,0x48,0x45,0x43,0x4B,0x0A, -0x00,0x0A,0x4E,0x4F,0x4E,0x45,0x0A,0x0A,0x00,0x0A,0x54,0x48,0x45,0x52,0x4D,0x41, -0x4C,0x20,0x53,0x48,0x55,0x54,0x44,0x4F,0x57,0x4E,0x0A,0x00,0x0A,0x49,0x4E,0x54, -0x45,0x52,0x52,0x55,0x50,0x54,0x20,0x20,0x20,0x4C,0x56,0x4C,0x20,0x3D,0x20,0x25, -0x64,0x0A,0x00,0x0A,0x45,0x58,0x43,0x45,0x50,0x54,0x49,0x4F,0x4E,0x0A,0x00,0x0A, -0x41,0x42,0x4F,0x52,0x54,0x0A,0x00,0x50,0x43,0x20,0x3D,0x20,0x30,0x78,0x25,0x30, -0x38,0x78,0x0A,0x50,0x53,0x57,0x20,0x3D,0x20,0x30,0x78,0x25,0x30,0x38,0x78,0x0A, -0x43,0x53,0x45,0x52,0x20,0x3D,0x20,0x30,0x78,0x25,0x30,0x38,0x78,0x0A,0x00,0x46, -0x4C,0x31,0x20,0x3D,0x20,0x30,0x78,0x25,0x30,0x38,0x78,0x0A,0x46,0x4C,0x32,0x20, -0x3D,0x20,0x30,0x78,0x25,0x30,0x38,0x78,0x0A,0x0A,0x00,0x0A,0x4E,0x4F,0x4E,0x45, -0x0A,0x0A,0x00,0x0A,0x41,0x75,0x74,0x6F,0x6D,0x61,0x74,0x69,0x63,0x20,0x64,0x69, -0x61,0x67,0x6E,0x6F,0x73,0x74,0x69,0x63,0x73,0x20,0x61,0x72,0x65,0x20,0x25,0x73, -0x61,0x62,0x6C,0x65,0x64,0x0A,0x09,0x74,0x6F,0x67,0x67,0x6C,0x65,0x3F,0x20,0x28, -0x6E,0x29,0x20,0x00,0x64,0x69,0x73,0x00,0x65,0x6E,0x00,0x0A,0x00,0x00,0x00,0x00, -0x0A,0x46,0x57,0x20,0x45,0x52,0x52,0x4F,0x52,0x20,0x32,0x2D,0x31,0x31,0x3A,0x20, -0x4D,0x45,0x4D,0x4F,0x52,0x59,0x20,0x43,0x4F,0x4E,0x46,0x49,0x47,0x55,0x52,0x41, -0x54,0x49,0x4F,0x4E,0x20,0x4F,0x46,0x20,0x25,0x64,0x20,0x4D,0x45,0x47,0x41,0x42, -0x59,0x54,0x45,0x53,0x20,0x55,0x4E,0x53,0x55,0x50,0x50,0x4F,0x52,0x54,0x45,0x44, -0x0A,0x4D,0x41,0x58,0x49,0x4D,0x55,0x4D,0x20,0x49,0x53,0x20,0x25,0x64,0x20,0x4D, -0x45,0x47,0x41,0x42,0x59,0x54,0x45,0x53,0x0A,0x00,0x0A,0x46,0x57,0x20,0x45,0x52, -0x52,0x4F,0x52,0x20,0x32,0x2D,0x31,0x33,0x3A,0x20,0x4D,0x45,0x4D,0x4F,0x52,0x59, -0x20,0x42,0x4F,0x41,0x52,0x44,0x20,0x4E,0x4F,0x54,0x20,0x53,0x55,0x50,0x50,0x4F, -0x52,0x54,0x45,0x44,0x20,0x4F,0x4E,0x20,0x54,0x48,0x49,0x53,0x20,0x53,0x59,0x53, -0x54,0x45,0x4D,0x0A,0x00,0x0A,0x46,0x57,0x20,0x45,0x52,0x52,0x4F,0x52,0x20,0x32, -0x2D,0x31,0x32,0x3A,0x20,0x4D,0x45,0x4D,0x4F,0x52,0x59,0x20,0x47,0x41,0x50,0x20, -0x49,0x4E,0x20,0x53,0x4C,0x4F,0x54,0x20,0x25,0x64,0x0A,0x00,0x0A,0x46,0x57,0x20, -0x45,0x52,0x52,0x4F,0x52,0x20,0x32,0x2D,0x30,0x32,0x3A,0x20,0x4E,0x4F,0x20,0x4C, -0x4F,0x41,0x44,0x20,0x44,0x45,0x56,0x49,0x43,0x45,0x20,0x49,0x4E,0x20,0x25,0x73, -0x20,0x53,0x4C,0x4F,0x54,0x20,0x25,0x64,0x0A,0x00,0x49,0x2F,0x4F,0x20,0x42,0x55, -0x53,0x00,0x42,0x55,0x42,0x55,0x53,0x00,0x30,0x34,0x3A,0x20,0x20,0x55,0x4E,0x45, -0x58,0x50,0x45,0x43,0x54,0x45,0x44,0x20,0x49,0x4E,0x54,0x45,0x52,0x52,0x55,0x50, -0x54,0x00,0x30,0x33,0x3A,0x20,0x20,0x55,0x4E,0x45,0x58,0x50,0x45,0x43,0x54,0x45, -0x44,0x20,0x46,0x41,0x55,0x4C,0x54,0x00,0x69,0x66,0x20,0x43,0x52,0x43,0x20,0x65, -0x72,0x72,0x6F,0x72,0x20,0x61,0x74,0x20,0x64,0x69,0x73,0x6B,0x20,0x61,0x64,0x64, -0x72,0x65,0x73,0x73,0x20,0x25,0x30,0x38,0x78,0x20,0x28,0x25,0x64,0x20,0x72,0x65, -0x74,0x72,0x69,0x65,0x73,0x29,0x0A,0x00,0x00,0x00,0x00,0x00,0x6D,0x63,0x70,0x00, -0x0A,0x53,0x59,0x53,0x54,0x45,0x4D,0x20,0x46,0x41,0x49,0x4C,0x55,0x52,0x45,0x3A, -0x20,0x43,0x4F,0x4E,0x53,0x55,0x4C,0x54,0x20,0x59,0x4F,0x55,0x52,0x20,0x53,0x59, -0x53,0x54,0x45,0x4D,0x20,0x41,0x44,0x4D,0x49,0x4E,0x49,0x53,0x54,0x52,0x41,0x54, -0x49,0x4F,0x4E,0x20,0x44,0x4F,0x43,0x55,0x4D,0x45,0x4E,0x54,0x41,0x54,0x49,0x4F, -0x4E,0x0A,0x0A,0x00,0x0A,0x46,0x49,0x52,0x4D,0x57,0x41,0x52,0x45,0x20,0x4D,0x4F, -0x44,0x45,0x0A,0x0A,0x00,0x2F,0x66,0x69,0x6C,0x6C,0x65,0x64,0x74,0x00,0x2F,0x64, -0x67,0x6D,0x6F,0x6E,0x00,0x2F,0x75,0x6E,0x69,0x78,0x00,0x00,0x30,0x34,0x3A,0x20, -0x55,0x4E,0x45,0x58,0x50,0x45,0x43,0x54,0x45,0x44,0x20,0x49,0x4E,0x54,0x45,0x52, -0x52,0x55,0x50,0x54,0x0A,0x00,0x0A,0x54,0x48,0x45,0x52,0x4D,0x41,0x4C,0x20,0x53, -0x48,0x55,0x54,0x44,0x4F,0x57,0x4E,0x0A,0x00,0x30,0x39,0x3A,0x20,0x55,0x4E,0x45, -0x58,0x50,0x45,0x43,0x54,0x45,0x44,0x20,0x53,0x41,0x4E,0x49,0x54,0x59,0x20,0x54, -0x49,0x4D,0x45,0x2D,0x4F,0x55,0x54,0x0A,0x00,0x31,0x30,0x3A,0x20,0x55,0x4E,0x45, -0x58,0x50,0x45,0x43,0x54,0x45,0x44,0x20,0x41,0x42,0x4F,0x52,0x54,0x0A,0x00,0x00, -0x30,0x33,0x3A,0x20,0x55,0x4E,0x45,0x58,0x50,0x45,0x43,0x54,0x45,0x44,0x20,0x46, -0x41,0x55,0x4C,0x54,0x0A,0x00,0x00,0x00,0x30,0x35,0x2F,0x30,0x36,0x2F,0x38,0x38, -0x00,0x00,0x00,0x00,0x33,0x46,0x50,0x31,0x33,0x00,0x00,0x00,0x33,0x2E,0x32,0x2E, -0x31,0x00,0x00,0x00,0x28,0x63,0x29,0x20,0x31,0x39,0x38,0x34,0x2C,0x20,0x31,0x39, -0x38,0x37,0x2C,0x20,0x31,0x39,0x38,0x38,0x20,0x41,0x54,0x26,0x54,0x00,0x00,0x00, -0x04,0x7F,0x44,0x04,0x00,0x02,0x4C,0x04,0x7F,0x44,0x04,0x00,0x02,0x49,0x04,0x7F, -0x44,0x04,0x00,0x02,0x4A,0x04,0x7F,0x44,0x0C,0x00,0x02,0x4E,0x24,0x7F,0x3D,0x13, -0x00,0x00,0x70,0x70,0x10,0x43,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x80,0x7F,0x04, -0x40,0x04,0x00,0x87,0x38,0x7F,0x0F,0x10,0x04,0x00,0x87,0x6F,0x74,0x7F,0x0F,0x10, -0x04,0x00,0x87,0x5F,0xB4,0x00,0x7F,0x0F,0x10,0x04,0x00,0x87,0x5F,0xF4,0x00,0x7F, -0x0B,0x10,0x04,0x00,0x87,0x01,0x7F,0x0B,0x10,0x04,0x00,0x80,0x7F,0x24,0x40,0x04, -0x00,0x83,0x7F,0x03,0x00,0x04,0x00,0x84,0x01,0x7F,0x40,0x40,0x04,0x00,0x3C,0x4F, -0xED,0x0D,0x1C,0xA1,0x7F,0xA0,0x03,0x00,0x02,0x7F,0x29,0x3C,0x4F,0x05,0xB2,0xA6, -0x5D,0x7F,0xA0,0x03,0x00,0x02,0x7F,0x1C,0x3C,0x4F,0x0D,0xF0,0xAD,0x8B,0x7F,0xA0, -0x03,0x00,0x02,0x7F,0x0F,0x3C,0x4F,0x7E,0xCA,0xD1,0xDE,0x7F,0xA0,0x03,0x00,0x02, -0x77,0x08,0x24,0x7F,0xA1,0x19,0x00,0x00,0x80,0x7F,0x50,0x40,0x04,0x00,0x70,0x84, -0x4B,0x40,0xB8,0x4F,0xFF,0xFF,0xC3,0xFF,0x40,0x84,0x40,0x4B,0x70,0x77,0x05,0x7A, -0x3B,0x05,0x47,0x05,0x7A,0x36,0x05,0x43,0x05,0x7A,0x31,0x05,0x57,0x05,0x7A,0x2C, -0x05,0x53,0x05,0x7A,0x27,0x05,0x53,0x05,0x7A,0x22,0x05,0x63,0x05,0x7A,0x1D,0x05, -0x70,0x84,0x4B,0x40,0xB0,0x4F,0x00,0x00,0x3C,0x00,0x40,0x84,0x40,0x4B,0x70,0x7F, -0x05,0x7A,0x09,0x05,0x4F,0x05,0x7A,0x04,0x05,0x43,0x05,0x7A,0xFF,0x04,0x5F,0x05, -0x7A,0xFA,0x04,0x5B,0x05,0x7A,0xF5,0x04,0x5B,0x05,0x7A,0xF0,0x04,0x6B,0x05,0x7A, -0xEB,0x04,0x70,0x84,0x4B,0x40,0xB8,0x4F,0xFF,0xFF,0xC3,0xFF,0x40,0xB0,0x4F,0x00, -0x00,0x10,0x00,0x40,0x84,0x40,0x4B,0x70,0x43,0x05,0x7A,0xD0,0x04,0x70,0x84,0x4B, -0x40,0xB8,0x4F,0xFF,0xFF,0xC3,0xFF,0x40,0xB0,0x4F,0x00,0x00,0x04,0x00,0x40,0x84, -0x40,0x4B,0x70,0x5E,0x06,0x00,0x7A,0xB4,0x04,0x70,0x84,0x4B,0x40,0xB8,0x4F,0xFF, -0xFF,0xC3,0xFF,0x40,0xB0,0x4F,0x00,0x00,0x20,0x00,0x40,0x84,0x40,0x4B,0x70,0x4B, -0x05,0x7A,0x99,0x04,0x84,0xFF,0x40,0x84,0x40,0x41,0x84,0x41,0x42,0x84,0x42,0x43, -0x84,0x43,0x44,0x84,0x44,0x45,0x84,0x45,0x46,0x84,0x46,0x47,0x84,0x47,0x48,0x3C, -0x40,0x48,0x76,0x78,0x04,0xD0,0x01,0x40,0x40,0x43,0x04,0x7B,0xDC,0x84,0xFE,0x40, -0x88,0x40,0x41,0x88,0x41,0x42,0x88,0x42,0x43,0x88,0x43,0x44,0x88,0x44,0x45,0x88, -0x45,0x46,0x88,0x46,0x47,0x88,0x47,0x48,0x88,0x40,0x48,0x88,0x41,0x47,0x88,0x42, -0x46,0x88,0x43,0x45,0x88,0x48,0x41,0x88,0x47,0x42,0x88,0x46,0x43,0x88,0x44,0x40, -0x88,0x41,0x44,0x3C,0x40,0x48,0x76,0x34,0x04,0xD0,0x01,0x40,0x40,0x4B,0x07,0x88, -0x40,0x40,0x7B,0xBE,0x84,0x49,0x41,0x84,0x4A,0x42,0x84,0x4C,0x43,0x84,0x4D,0x44, -0x84,0x4E,0x45,0x84,0xFF,0x40,0x84,0x40,0x49,0x84,0x49,0x4A,0x84,0x4A,0x4C,0x84, -0x4C,0x4D,0x84,0x4D,0x4E,0x3C,0x49,0x4E,0x76,0x4C,0x00,0xD0,0x01,0x40,0x40,0x43, -0x04,0x7B,0xE5,0x84,0x01,0x40,0x88,0x40,0x49,0x88,0x49,0x4A,0x88,0x4A,0x4C,0x88, -0x4C,0x4D,0x88,0x4D,0x4E,0x88,0x49,0x4E,0x88,0x4A,0x4D,0x88,0x4C,0x49,0x88,0x4E, -0x4A,0x88,0x4D,0x4C,0x3C,0x49,0x4E,0x76,0x1D,0x00,0xD0,0x01,0x40,0x40,0x4B,0x04, -0x7B,0xD6,0x84,0x41,0x49,0x84,0x42,0x4A,0x84,0x43,0x4C,0x84,0x44,0x4D,0x84,0x45, -0x4E,0x7A,0x15,0x00,0x84,0x41,0x49,0x84,0x42,0x4A,0x84,0x43,0x4C,0x84,0x44,0x4D, -0x84,0x45,0x4E,0x7A,0xA7,0x03,0x82,0x48,0x84,0x4F,0xEE,0xFF,0x01,0x00,0x45,0x80, -0x47,0x7B,0x47,0x84,0x5F,0xFF,0x00,0x40,0x86,0xE2,0x40,0xE0,0x40,0x87,0x57,0xE0, -0x41,0xB8,0x41,0x40,0x86,0xE2,0x40,0xE0,0x40,0x86,0xE2,0x48,0xE0,0x41,0x9C,0x41, -0x40,0x86,0x40,0x48,0x86,0xE2,0x48,0xE0,0x40,0xD4,0x0F,0x40,0x40,0x86,0xE2,0x40, -0xE0,0x40,0x86,0xE2,0x48,0xE0,0x41,0xD0,0x01,0x41,0x41,0x86,0xE2,0x41,0xE0,0x41, -0xB0,0x41,0x40,0x86,0x40,0x48,0x90,0x47,0x3C,0x45,0x47,0x5B,0xB8,0x86,0xE2,0x48, -0xE0,0x40,0x88,0x40,0x40,0x86,0x40,0x48,0x86,0xE2,0x48,0xE0,0x40,0x87,0x57,0xE0, -0x41,0x87,0xC7,0x01,0xE0,0x42,0xD0,0x08,0x42,0x42,0xB0,0x42,0x41,0x3C,0x41,0x40, -0x7F,0x05,0x7A,0x31,0x03,0x84,0x7F,0xA0,0x03,0x00,0x02,0x45,0x84,0x7F,0x98,0x0C, -0x00,0x02,0x43,0x84,0x01,0x7F,0x38,0x40,0x04,0x00,0x84,0x4F,0x00,0x00,0x00,0x02, -0x47,0x84,0x4F,0xB4,0x12,0x00,0x02,0x46,0x7B,0x4B,0x84,0xFF,0x57,0x3C,0xFF,0x57, -0x7F,0x08,0x24,0x7F,0x1C,0x19,0x00,0x00,0x84,0x4F,0xAA,0xAA,0xAA,0xAA,0x57,0x3C, -0x4F,0xAA,0xAA,0xAA,0xAA,0x57,0x7F,0x08,0x24,0x7F,0x1C,0x19,0x00,0x00,0x84,0x4F, -0x55,0x55,0x55,0x55,0x57,0x3C,0x4F,0x55,0x55,0x55,0x55,0x57,0x7F,0x08,0x24,0x7F, -0x1C,0x19,0x00,0x00,0x80,0x57,0x28,0x57,0x7F,0x08,0x24,0x7F,0x1C,0x19,0x00,0x00, -0x9C,0x04,0x47,0x3C,0x46,0x47,0x5B,0xB4,0x3C,0x4F,0x00,0x40,0x00,0x02,0x47,0x4B, -0x04,0x7B,0x28,0x3C,0x4F,0xEF,0xBE,0xED,0xFE,0x45,0x7F,0x0B,0x3C,0x4F,0x1E,0xAC, -0xEB,0xAD,0x45,0x77,0x0B,0x84,0x4F,0x00,0x30,0x00,0x02,0x47,0x7B,0x04,0x80,0x43, -0x84,0x4F,0x00,0x40,0x00,0x02,0x46,0x7B,0x81,0x84,0x45,0x7F,0xA0,0x03,0x00,0x02, -0x84,0x43,0x7F,0x98,0x0C,0x00,0x02,0x87,0x01,0x7F,0x9D,0x0C,0x00,0x02,0x24,0x7F, -0xA1,0x19,0x00,0x00,0x84,0x4F,0x72,0x6E,0x00,0x00,0x7F,0x28,0x04,0x00,0x02,0x28, -0x7F,0x40,0x04,0x00,0x02,0x77,0x09,0x2C,0x5C,0x7F,0x00,0x6A,0x00,0x00,0x80,0x7F, -0x40,0x04,0x00,0x02,0x80,0x7F,0x00,0x00,0x00,0x02,0x84,0x4F,0x32,0x30,0x6D,0x61, -0x7F,0x00,0x00,0x00,0x03,0x3C,0x4F,0x32,0x30,0x6D,0x61,0x7F,0x00,0x00,0x00,0x02, -0x77,0x0B,0x87,0x02,0x7F,0x94,0x0C,0x00,0x02,0x7B,0x09,0x87,0x04,0x7F,0x94,0x0C, -0x00,0x02,0x80,0x7F,0x00,0x00,0x00,0x03,0x80,0x7F,0x60,0x40,0x04,0x00,0x80,0x7F, -0x5C,0x40,0x04,0x00,0x83,0x7F,0x0D,0x90,0x04,0x00,0x87,0x08,0x7F,0x0F,0x90,0x04, -0x00,0x80,0x7F,0x34,0x40,0x04,0x00,0x80,0x7F,0x28,0x40,0x04,0x00,0x80,0x7F,0x6C, -0x40,0x04,0x00,0x80,0x7F,0x68,0x40,0x04,0x00,0x84,0x7F,0x00,0xFF,0x04,0x00,0x45, -0x38,0x7F,0x60,0x40,0x04,0x00,0x04,0x7F,0x10,0x80,0x7F,0x68,0x40,0x04,0x00,0x80, -0x7F,0x6C,0x40,0x04,0x00,0x7B,0x09,0x87,0x11,0x7F,0x94,0x0C,0x00,0x02,0x3C,0x4F, -0xED,0x0D,0x1C,0xA1,0x7F,0xA0,0x03,0x00,0x02,0x7F,0x2F,0x3C,0x4F,0x05,0xB2,0xA6, -0x5D,0x7F,0xA0,0x03,0x00,0x02,0x7F,0x22,0x3C,0x4F,0x0D,0xF0,0xAD,0x8B,0x7F,0xA0, -0x03,0x00,0x02,0x7F,0x15,0x3C,0x4F,0x7E,0xCA,0xD1,0xDE,0x7F,0xA0,0x03,0x00,0x02, -0x7F,0x08,0x24,0x7F,0x07,0x18,0x00,0x00,0x84,0x4F,0x00,0x90,0x04,0x00,0x7F,0x18, -0x04,0x00,0x02,0x2C,0x5C,0x7F,0x9C,0x33,0x00,0x00,0xA0,0x00,0x2C,0xCC,0xFC,0x7F, -0xA8,0x67,0x00,0x00,0x87,0x7F,0x00,0xA0,0x04,0x00,0xE0,0x45,0x2C,0x5C,0x7F,0x48, -0x68,0x00,0x00,0x87,0x01,0x7F,0x9D,0x0C,0x00,0x02,0x2C,0x5C,0x7F,0x7E,0x53,0x00, -0x00,0x3C,0x4F,0xED,0x0D,0x1C,0xA1,0x7F,0xA0,0x03,0x00,0x02,0x77,0x0B,0x2C,0x5C, -0xEF,0xAC,0x03,0x00,0x02,0x7B,0x32,0x3C,0x4F,0x05,0xB2,0xA6,0x5D,0x7F,0xA0,0x03, -0x00,0x02,0x77,0x1F,0x83,0xEF,0xA0,0x04,0x00,0x00,0x2C,0x5C,0x7F,0x00,0x40,0x00, -0x02,0xA0,0x4F,0xEF,0xBE,0xED,0xFE,0x2C,0xCC,0xFC,0x7F,0xFE,0x58,0x00,0x00,0x7B, -0x08,0x24,0x7F,0x7C,0x6A,0x00,0x00,0x87,0x5F,0xD0,0x00,0x7F,0x00,0xA0,0x04,0x00, -0xA0,0x01,0x2C,0xCC,0xFC,0xEF,0x28,0x05,0x00,0x00,0xA0,0x00,0xA0,0x4F,0xA0,0x0C, -0x00,0x02,0xA0,0x00,0xA0,0x03,0x2C,0xCC,0xF0,0x7F,0x2C,0x65,0x00,0x00,0x3C,0x01, -0x40,0x77,0x53,0x84,0x7F,0x08,0x05,0x00,0x00,0x40,0x3F,0xC0,0x03,0x7F,0xA0,0x0C, -0x00,0x02,0x77,0x42,0x84,0x7F,0x08,0x05,0x00,0x00,0x40,0x3F,0xC0,0x07,0x7F,0xA1, -0x0C,0x00,0x02,0x77,0x31,0x84,0x7F,0x08,0x05,0x00,0x00,0x40,0x3F,0xC0,0x0B,0x7F, -0xA2,0x0C,0x00,0x02,0x77,0x20,0x84,0x7F,0x08,0x05,0x00,0x00,0x40,0x3F,0xC0,0x0F, -0x7F,0xA3,0x0C,0x00,0x02,0x77,0x0F,0xB0,0x4F,0x00,0x00,0x00,0x40,0x7F,0x98,0x0C, -0x00,0x02,0x7B,0x1B,0xA0,0x00,0x2C,0xCC,0xFC,0x7F,0x8C,0x4A,0x00,0x00,0x28,0x40, -0x77,0x0D,0xB0,0x4F,0x00,0x00,0x00,0x20,0x7F,0x98,0x0C,0x00,0x02,0x38,0x7F,0x98, -0x0C,0x00,0x02,0x4F,0x00,0x00,0x00,0x20,0x77,0x0F,0x38,0x7F,0x98,0x0C,0x00,0x02, -0x4F,0x00,0x00,0x00,0x40,0x7F,0x39,0x84,0x4F,0x04,0x20,0x04,0x00,0x47,0x84,0x4F, -0x04,0x24,0x04,0x00,0x45,0x7B,0x07,0x80,0x57,0x9C,0x04,0x47,0x3C,0x45,0x47,0x5B, -0xF8,0x87,0x10,0x7F,0x9C,0x0C,0x00,0x02,0xA0,0x4F,0x9C,0x0C,0x00,0x02,0xA0,0x4F, -0x0C,0x30,0x04,0x00,0xA0,0x01,0x2C,0xCC,0xF4,0x7F,0xDC,0x49,0x00,0x00,0xA0,0x4F, -0x94,0x0C,0x00,0x02,0xA0,0x4F,0xC4,0x30,0x04,0x00,0xA0,0x01,0x2C,0xCC,0xF4,0x7F, -0xDC,0x49,0x00,0x00,0x24,0x7F,0x39,0x1B,0x00,0x00,0x84,0x02,0x44,0x24,0x7F,0x28, -0x19,0x00,0x00,0x84,0x03,0x44,0x24,0x7F,0x28,0x19,0x00,0x00,0x84,0x04,0x44,0x24, -0x7F,0x28,0x19,0x00,0x00,0x84,0x05,0x44,0x80,0x7F,0x40,0x40,0x04,0x00,0x80,0x45, -0x7B,0x2F,0x80,0x43,0x7B,0x04,0x90,0x43,0x3C,0x4F,0xA0,0x86,0x01,0x00,0x43,0x5F, -0xF7,0x84,0x01,0x7F,0x40,0x40,0x04,0x00,0x80,0x43,0x7B,0x04,0x90,0x43,0x3C,0x4F, -0xA0,0x86,0x01,0x00,0x43,0x5F,0xF7,0x80,0x7F,0x40,0x40,0x04,0x00,0x90,0x45,0x3C, -0x44,0x45,0x5B,0xD0,0x38,0x7F,0x00,0x40,0x04,0x00,0x02,0x7F,0x10,0x80,0xEF,0x8C, -0x04,0x00,0x00,0x80,0x7F,0x44,0x40,0x04,0x00,0x7B,0x00,0x80,0x43,0x7B,0x04,0x90, -0x43,0xE8,0x4F,0xA0,0x86,0x01,0x00,0x44,0x40,0x3C,0x40,0x43,0x5F,0xF3,0x24,0x7F, -0x2E,0x19,0x00,0x00,0x18,0x43,0x08,0x70,0x10,0x45,0x9C,0x4F,0x00,0x00,0x00,0x00, -0x4C,0x84,0x4F,0xA0,0x0E,0x00,0x02,0x48,0x84,0x4F,0x04,0x06,0x00,0x00,0x47,0x80, -0x45,0x7B,0x11,0x84,0x48,0x40,0x90,0x48,0x84,0x47,0x41,0x90,0x47,0x87,0x51,0x50, -0x90,0x45,0x3C,0x6F,0x44,0x45,0x5B,0xED,0x84,0x4F,0x80,0xE1,0x81,0x00,0x7F,0x80, -0x00,0x00,0x02,0x84,0x4F,0x6C,0x37,0x00,0x00,0x7F,0x84,0x00,0x00,0x02,0x84,0x4F, -0x40,0x0F,0x00,0x02,0x7F,0x88,0x00,0x00,0x02,0x84,0x4F,0x40,0x0F,0x00,0x02,0x7F, -0x98,0x00,0x00,0x02,0x84,0x4F,0x40,0x10,0x00,0x02,0x7F,0x9C,0x00,0x00,0x02,0x80, -0x7F,0xCC,0x00,0x00,0x02,0x84,0x4F,0x80,0xE1,0x81,0x00,0x7F,0x30,0x00,0x00,0x02, -0x84,0x4F,0xCC,0x38,0x00,0x00,0x7F,0x34,0x00,0x00,0x02,0x84,0x4F,0x40,0x10,0x00, -0x02,0x7F,0x38,0x00,0x00,0x02,0x84,0x4F,0x40,0x10,0x00,0x02,0x7F,0x48,0x00,0x00, -0x02,0x84,0x4F,0x40,0x12,0x00,0x02,0x7F,0x4C,0x00,0x00,0x02,0x80,0x7F,0x7C,0x00, -0x00,0x02,0x80,0x45,0x7B,0x35,0xE8,0x6F,0x50,0x45,0x40,0x9C,0x4F,0xD0,0x00,0x00, -0x02,0x40,0x84,0x40,0x46,0x84,0x4F,0x80,0xE1,0x81,0x00,0x56,0x84,0x4F,0x40,0x0F, -0x00,0x02,0xC6,0x08,0x84,0x4F,0x40,0x0F,0x00,0x02,0xC6,0x18,0x84,0x4F,0x40,0x10, -0x00,0x02,0xC6,0x1C,0x80,0xC6,0x4C,0x90,0x45,0x3C,0x09,0x45,0x4B,0xCA,0x84,0x4F, -0x8F,0x37,0x00,0x00,0x7F,0xD4,0x00,0x00,0x02,0x84,0x4F,0xB2,0x37,0x00,0x00,0x7F, -0x24,0x01,0x00,0x02,0x84,0x4F,0xD5,0x37,0x00,0x00,0x7F,0x74,0x01,0x00,0x02,0x84, -0x4F,0xF8,0x37,0x00,0x00,0x7F,0xC4,0x01,0x00,0x02,0x84,0x4F,0x1B,0x38,0x00,0x00, -0x7F,0x14,0x02,0x00,0x02,0x84,0x4F,0x3E,0x38,0x00,0x00,0x7F,0x64,0x02,0x00,0x02, -0x84,0x4F,0x61,0x38,0x00,0x00,0x7F,0xB4,0x02,0x00,0x02,0x84,0x4F,0x84,0x38,0x00, -0x00,0x7F,0x04,0x03,0x00,0x02,0x84,0x4F,0xA7,0x38,0x00,0x00,0x7F,0x54,0x03,0x00, -0x02,0x84,0x4F,0x80,0xE1,0x81,0x00,0x7F,0xF0,0x0E,0x00,0x02,0x84,0x4F,0x5A,0x39, -0x00,0x00,0x7F,0xF4,0x0E,0x00,0x02,0x84,0x4F,0x40,0x10,0x00,0x02,0x7F,0xF8,0x0E, -0x00,0x02,0x84,0x4F,0x40,0x10,0x00,0x02,0x7F,0x08,0x0F,0x00,0x02,0x84,0x4F,0x40, -0x12,0x00,0x02,0x7F,0x0C,0x0F,0x00,0x02,0x80,0x7F,0x3C,0x0F,0x00,0x02,0x04,0x7F, -0xA0,0x0E,0x00,0x02,0x4D,0x24,0x7F,0xA4,0x16,0x00,0x00,0x18,0x45,0x08,0x70,0x70, -0x10,0x47,0x9C,0x4F,0x08,0x00,0x00,0x00,0x4C,0x84,0x4F,0x00,0x90,0x04,0x00,0x7F, -0x18,0x04,0x00,0x02,0x2C,0x5C,0x7F,0x9C,0x33,0x00,0x00,0x2C,0x5C,0xAF,0x4F,0x06, -0x86,0x40,0x7F,0x44,0x12,0x00,0x02,0x86,0x7F,0x44,0x12,0x00,0x02,0xE4,0x40,0x2A, -0x40,0x77,0x0A,0x24,0x7F,0x25,0x19,0x00,0x00,0x7B,0x11,0x3E,0x02,0x7F,0x44,0x12, -0x00,0x02,0x77,0x08,0x24,0x7F,0x3D,0x13,0x00,0x00,0xB0,0x4F,0x00,0x00,0x00,0x80, -0x7F,0x98,0x0C,0x00,0x02,0x2C,0x5C,0x7F,0x44,0x52,0x00,0x00,0x2C,0x5C,0x7F,0x2C, -0x24,0x00,0x00,0x84,0x40,0xEF,0xE4,0x04,0x00,0x00,0x84,0x7F,0x90,0x04,0x00,0x00, -0xEF,0xE8,0x04,0x00,0x00,0x83,0xEF,0xE0,0x04,0x00,0x00,0x9C,0x20,0xEF,0xE8,0x04, -0x00,0x00,0x87,0xEF,0xE0,0x04,0x00,0x00,0xE0,0x40,0xD0,0x05,0x40,0x40,0x9C,0x7F, -0x90,0x04,0x00,0x00,0x40,0x87,0x00,0xE0,0x41,0xC8,0x03,0x0C,0x41,0x50,0x87,0xEF, -0xE0,0x04,0x00,0x00,0xE0,0x40,0xD0,0x05,0x40,0x40,0x9C,0x7F,0x90,0x04,0x00,0x00, -0x40,0x86,0x01,0x50,0x87,0xEF,0xE0,0x04,0x00,0x00,0xE0,0x40,0xD0,0x05,0x40,0x40, -0x9C,0x7F,0x90,0x04,0x00,0x00,0x40,0x87,0x00,0xE0,0x41,0xC8,0x02,0x0B,0x41,0xC0, -0x04,0x87,0xEF,0xE0,0x04,0x00,0x00,0xE0,0x40,0xD0,0x05,0x40,0x40,0x9C,0x7F,0x90, -0x04,0x00,0x00,0x40,0x87,0x01,0xE0,0x41,0xC8,0x00,0x05,0x41,0xC0,0x04,0x87,0xEF, -0xE0,0x04,0x00,0x00,0xE0,0x40,0xD0,0x05,0x40,0x40,0x9C,0x7F,0x90,0x04,0x00,0x00, -0x40,0x87,0x01,0xE0,0x41,0xC8,0x00,0x06,0x41,0xC0,0x04,0x87,0xEF,0xE0,0x04,0x00, -0x00,0xE0,0x40,0xD0,0x05,0x40,0x40,0x9C,0x7F,0x90,0x04,0x00,0x00,0x40,0x9C,0x0C, -0x40,0xA0,0x40,0xA0,0x4F,0x48,0x06,0x00,0x00,0x2C,0xCC,0xF8,0x7F,0x28,0x70,0x00, -0x00,0x87,0xEF,0xE0,0x04,0x00,0x00,0x40,0x93,0xEF,0xE0,0x04,0x00,0x00,0x87,0x40, -0xE0,0x40,0xD0,0x05,0x40,0x40,0x9C,0x7F,0x90,0x04,0x00,0x00,0x40,0x87,0x01,0xE0, -0x41,0xC8,0x00,0x07,0x41,0xC0,0x04,0x84,0x4F,0x98,0x6F,0x00,0x00,0xEF,0x98,0x04, -0x00,0x00,0x84,0x4F,0x98,0x6F,0x00,0x00,0xEF,0x0C,0x05,0x00,0x00,0x2C,0x5C,0x7F, -0x7E,0x53,0x00,0x00,0x84,0x4F,0xCA,0x20,0x00,0x00,0xEF,0x98,0x04,0x00,0x00,0x87, -0x01,0xEF,0xE0,0x04,0x00,0x00,0x82,0x7F,0x44,0x12,0x00,0x02,0x2C,0x5C,0xEF,0xC0, -0x04,0x00,0x00,0x24,0x7F,0xB5,0x1D,0x00,0x00,0xFE,0x01,0x7F,0x44,0x12,0x00,0x02, -0x40,0xD0,0x15,0x40,0x40,0x83,0x80,0x05,0x00,0x20,0x00,0xA0,0x14,0x2C,0xCC,0xFC, -0xEF,0x28,0x05,0x00,0x00,0x87,0xEF,0xE0,0x04,0x00,0x00,0xE0,0x40,0xD0,0x05,0x40, -0x40,0x9C,0x7F,0x90,0x04,0x00,0x00,0x40,0xFE,0x01,0x7F,0x44,0x12,0x00,0x02,0x41, -0xD0,0x15,0x41,0x41,0x87,0x81,0x01,0x00,0x20,0x00,0xE2,0x41,0x86,0x41,0x50,0x9C, -0x20,0xEF,0xE8,0x04,0x00,0x00,0x87,0xEF,0xE0,0x04,0x00,0x00,0xE0,0x40,0xD0,0x05, -0x40,0x40,0x9C,0x7F,0x90,0x04,0x00,0x00,0x40,0x87,0x00,0xE0,0x41,0xC8,0x02,0x0B, -0x41,0xC0,0x04,0x87,0xEF,0xE0,0x04,0x00,0x00,0x40,0x93,0xEF,0xE0,0x04,0x00,0x00, -0x87,0x40,0xE0,0x40,0xD0,0x05,0x40,0x40,0x9C,0x7F,0x90,0x04,0x00,0x00,0x40,0x86, -0xE2,0x7F,0x44,0x12,0x00,0x02,0xE0,0x41,0xC8,0x03,0x0C,0x41,0x50,0xFE,0x01,0x7F, -0x44,0x12,0x00,0x02,0x40,0xD0,0x15,0x40,0x40,0x87,0x80,0x00,0x00,0x20,0x00,0xE2, -0x40,0x86,0x40,0x59,0x97,0xEF,0xE0,0x04,0x00,0x00,0x87,0xEF,0xE0,0x04,0x00,0x00, -0xE0,0x40,0x87,0x40,0xE0,0x40,0xD0,0x05,0x40,0x40,0x9C,0x7F,0x90,0x04,0x00,0x00, -0x40,0x84,0x40,0x64,0x86,0xE2,0x59,0xE0,0x40,0xD0,0x08,0x40,0x40,0x86,0xE2,0x40, -0xE0,0x40,0x86,0xE2,0xD9,0x04,0xE0,0x41,0xB0,0x41,0x40,0x86,0x40,0xD9,0x04,0x93, -0xEF,0xE0,0x04,0x00,0x00,0x92,0x7F,0x44,0x12,0x00,0x02,0x86,0x7F,0x44,0x12,0x00, -0x02,0xE4,0x40,0x3E,0x0C,0x40,0x4E,0x03,0xFF,0x86,0xFF,0x7F,0x44,0x12,0x00,0x02, -0x2C,0x5C,0xEF,0xC0,0x04,0x00,0x00,0x24,0x7F,0x89,0x1E,0x00,0x00,0x86,0x7F,0x44, -0x12,0x00,0x02,0xE4,0x40,0xD0,0x1A,0x40,0x40,0x87,0x80,0x03,0x40,0x01,0x06,0xE2, -0x40,0x86,0x40,0x59,0x87,0xEF,0xE0,0x04,0x00,0x00,0xE0,0x40,0xD0,0x05,0x40,0x40, -0x9C,0x7F,0x90,0x04,0x00,0x00,0x40,0x84,0x4F,0x00,0xFF,0x00,0x00,0x41,0x86,0xE2, -0x41,0xE0,0x41,0x86,0xE2,0x59,0xE0,0x42,0xB0,0x42,0x41,0x86,0x41,0x50,0x9C,0x20, -0xEF,0xE8,0x04,0x00,0x00,0x87,0xEF,0xE0,0x04,0x00,0x00,0xE0,0x40,0xD0,0x05,0x40, -0x40,0x9C,0x7F,0x90,0x04,0x00,0x00,0x40,0x87,0x03,0xE0,0x41,0xC8,0x02,0x0B,0x41, -0xC0,0x04,0x87,0xEF,0xE0,0x04,0x00,0x00,0x40,0x93,0xEF,0xE0,0x04,0x00,0x00,0x87, -0x40,0xE0,0x40,0xD0,0x05,0x40,0x40,0x9C,0x7F,0x90,0x04,0x00,0x00,0x40,0x86,0xE2, -0x7F,0x44,0x12,0x00,0x02,0xE0,0x41,0xC8,0x03,0x0C,0x41,0x50,0x86,0x7F,0x44,0x12, -0x00,0x02,0xE4,0x40,0x93,0x80,0x40,0x12,0x00,0x02,0xFB,0x10,0x7F,0x94,0x0C,0x00, -0x02,0x40,0x3C,0x10,0x40,0x7F,0x04,0x7B,0x16,0x92,0x7F,0x44,0x12,0x00,0x02,0x86, -0x7F,0x44,0x12,0x00,0x02,0xE4,0x40,0x3E,0x04,0x40,0x4E,0x43,0xFF,0xFC,0x4F,0xFC, -0x59,0x00,0x00,0x4F,0x02,0x5A,0x00,0x00,0x47,0x86,0xFF,0x7F,0x44,0x12,0x00,0x02, -0x84,0x4F,0x0E,0x21,0x00,0x00,0xEF,0x98,0x04,0x00,0x00,0x2C,0x5C,0xEF,0xC0,0x04, -0x00,0x00,0x92,0x7F,0x44,0x12,0x00,0x02,0x86,0x7F,0x44,0x12,0x00,0x02,0xE4,0x40, -0x3E,0x5F,0x00,0x01,0x40,0x4B,0x08,0x24,0x7F,0x6B,0x1F,0x00,0x00,0x04,0x7F,0xFC, -0x59,0x00,0x00,0x48,0x86,0x7F,0x44,0x12,0x00,0x02,0xE4,0x40,0xA8,0x47,0x40,0x9C, -0x40,0x48,0x34,0x58,0x87,0xEF,0xE0,0x04,0x00,0x00,0xE0,0x40,0xD0,0x05,0x40,0x40, -0x9C,0x7F,0x90,0x04,0x00,0x00,0x40,0x84,0x4F,0x00,0xFD,0x00,0x00,0x41,0x86,0xE2, -0x41,0xE0,0x41,0x86,0xE2,0x7F,0x44,0x12,0x00,0x02,0xE0,0x42,0xB0,0x42,0x41,0x86, -0x41,0x50,0x9C,0x20,0xEF,0xE8,0x04,0x00,0x00,0x87,0xEF,0xE0,0x04,0x00,0x00,0xE0, -0x40,0xD0,0x05,0x40,0x40,0x9C,0x7F,0x90,0x04,0x00,0x00,0x40,0x87,0x01,0xE0,0x41, -0xC8,0x02,0x0B,0x41,0xC0,0x04,0x87,0xEF,0xE0,0x04,0x00,0x00,0x40,0x93,0xEF,0xE0, -0x04,0x00,0x00,0x87,0x40,0xE0,0x40,0xD0,0x05,0x40,0x40,0x9C,0x7F,0x90,0x04,0x00, -0x00,0x40,0x87,0x00,0xE0,0x41,0xC8,0x03,0x0C,0x41,0x50,0x84,0x4F,0xCA,0x20,0x00, -0x00,0xEF,0x98,0x04,0x00,0x00,0x86,0xFF,0x7F,0x44,0x12,0x00,0x02,0x2C,0x5C,0xEF, -0xC0,0x04,0x00,0x00,0x24,0x7F,0x0D,0x20,0x00,0x00,0x87,0x7F,0x00,0x00,0xC0,0x01, -0xE2,0x40,0x86,0x40,0x59,0x87,0xEF,0xE0,0x04,0x00,0x00,0xE0,0x40,0xD0,0x05,0x40, -0x40,0x9C,0x7F,0x90,0x04,0x00,0x00,0x40,0x84,0x4F,0x00,0xFE,0x00,0x00,0x41,0x86, -0xE2,0x41,0xE0,0x41,0x86,0xE2,0x59,0xE0,0x42,0xB0,0x42,0x41,0x86,0x41,0x50,0x9C, -0x20,0xEF,0xE8,0x04,0x00,0x00,0x87,0xEF,0xE0,0x04,0x00,0x00,0xE0,0x40,0xD0,0x05, -0x40,0x40,0x9C,0x7F,0x90,0x04,0x00,0x00,0x40,0x87,0x02,0xE0,0x41,0xC8,0x02,0x0B, -0x41,0xC0,0x04,0x87,0xEF,0xE0,0x04,0x00,0x00,0x40,0x93,0xEF,0xE0,0x04,0x00,0x00, -0x87,0x40,0xE0,0x40,0xD0,0x05,0x40,0x40,0x9C,0x7F,0x90,0x04,0x00,0x00,0x40,0x86, -0xE2,0x7F,0x44,0x12,0x00,0x02,0xE0,0x41,0xC8,0x03,0x0C,0x41,0x50,0x92,0x7F,0x44, -0x12,0x00,0x02,0x86,0x7F,0x44,0x12,0x00,0x02,0xE4,0x40,0x3E,0x01,0x40,0x4A,0x6C, -0xFF,0x2C,0x5C,0x7F,0x7E,0x53,0x00,0x00,0x84,0x4F,0x98,0x6F,0x00,0x00,0xEF,0x98, -0x04,0x00,0x00,0x84,0x7F,0x90,0x04,0x00,0x00,0x40,0x87,0x01,0xE0,0x41,0xC8,0x03, -0x00,0x41,0xC0,0x04,0x84,0x7F,0x90,0x04,0x00,0x00,0x40,0x84,0xEF,0xE8,0x04,0x00, -0x00,0xC0,0x08,0x9C,0x0C,0xEF,0xE8,0x04,0x00,0x00,0x84,0x7F,0x90,0x04,0x00,0x00, -0x40,0x86,0x01,0xD0,0x08,0x84,0x7F,0x90,0x04,0x00,0x00,0x40,0xDC,0x02,0xC0,0x08, -0x40,0xA0,0x40,0xA0,0x4F,0x4C,0x06,0x00,0x00,0x2C,0xCC,0xF8,0x7F,0x28,0x70,0x00, -0x00,0x3C,0x4F,0xEF,0xBE,0xED,0xFE,0x7F,0xA0,0x03,0x00,0x02,0x7F,0x2C,0x3C,0x4F, -0x0D,0xF0,0xAD,0x8B,0x7F,0xA0,0x03,0x00,0x02,0x7F,0x1F,0x3C,0x4F,0x1E,0xAC,0xEB, -0xAD,0x7F,0xA0,0x03,0x00,0x02,0x7F,0x12,0x2C,0x5C,0xAF,0x72,0x00,0x28,0x40,0x77, -0x09,0x2C,0x5C,0x7F,0x44,0x52,0x00,0x00,0x2C,0x5C,0x7F,0x7E,0x53,0x00,0x00,0x24, -0x7F,0x7C,0x6A,0x00,0x00,0x18,0x47,0x08,0x70,0x70,0x10,0x49,0x9C,0x4F,0x00,0x00, -0x00,0x00,0x4C,0x38,0x7F,0x60,0x40,0x04,0x00,0x04,0x7F,0x0A,0x80,0x7F,0x68,0x40, -0x04,0x00,0x7B,0x28,0x84,0x4F,0xEF,0xBE,0xED,0xFE,0xEF,0x8C,0x04,0x00,0x00,0x2C, -0x5C,0x7F,0x7E,0x53,0x00,0x00,0xB0,0x01,0x7F,0x98,0x0C,0x00,0x02,0x2C,0x5C,0x7F, -0x44,0x52,0x00,0x00,0x24,0x7F,0x7C,0x6A,0x00,0x00,0x18,0x49,0x08,0x70,0x10,0x49, -0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x18,0x49,0x08,0x10,0x48,0x9C,0x4F,0x00,0x00, -0x00,0x00,0x4C,0x84,0x4F,0x00,0x40,0x00,0x02,0x48,0x7B,0x3E,0x84,0xFF,0x58,0x3C, -0xFF,0x58,0x7F,0x04,0x7B,0x3D,0x84,0x4F,0xAA,0xAA,0xAA,0xAA,0x58,0x3C,0x4F,0xAA, -0xAA,0xAA,0xAA,0x58,0x7F,0x04,0x7B,0x2B,0x84,0x4F,0x55,0x55,0x55,0x55,0x58,0x3C, -0x4F,0x55,0x55,0x55,0x55,0x58,0x7F,0x04,0x7B,0x19,0x80,0x58,0x84,0x48,0x40,0x9C, -0x04,0x48,0x28,0x50,0x7F,0x04,0x7B,0x0B,0x3C,0x4F,0x00,0x00,0x04,0x02,0x48,0x5B, -0xBD,0x3C,0x4F,0x00,0x00,0x04,0x02,0x48,0x53,0x18,0xB0,0x08,0x7F,0x98,0x0C,0x00, -0x02,0x84,0x4F,0xEF,0xBE,0xED,0xFE,0x7F,0xA0,0x03,0x00,0x02,0x80,0x40,0x7B,0x07, -0x84,0x01,0x40,0x7B,0x02,0x18,0x48,0x08,0x70,0x70,0x10,0x49,0x9C,0x4F,0x04,0x00, -0x00,0x00,0x4C,0x87,0x20,0x7F,0x02,0x90,0x04,0x00,0x87,0x30,0x7F,0x02,0x90,0x04, -0x00,0x87,0x10,0x7F,0x02,0x90,0x04,0x00,0x87,0x7F,0x00,0x90,0x04,0x00,0xE2,0x40, -0x86,0x40,0x59,0xB3,0x5F,0x80,0x00,0x7F,0x00,0x90,0x04,0x00,0x87,0x05,0x7F,0x02, -0x90,0x04,0x00,0xA0,0x14,0x2C,0xCC,0xFC,0xEF,0x28,0x05,0x00,0x00,0x87,0x6F,0x55, -0x7F,0x03,0x90,0x04,0x00,0xA0,0x14,0x2C,0xCC,0xFC,0xEF,0x28,0x05,0x00,0x00,0x3B, -0x7F,0x01,0x90,0x04,0x00,0x01,0x77,0x0A,0x80,0x40,0x24,0x7F,0x27,0x24,0x00,0x00, -0x3F,0x6F,0x55,0x7F,0x03,0x90,0x04,0x00,0x7F,0x0A,0x80,0x40,0x24,0x7F,0x27,0x24, -0x00,0x00,0x3B,0x7F,0x01,0x90,0x04,0x00,0x01,0x7F,0x0A,0x80,0x40,0x24,0x7F,0x27, -0x24,0x00,0x00,0x87,0x5F,0xAA,0x00,0x7F,0x03,0x90,0x04,0x00,0xA0,0x14,0x2C,0xCC, -0xFC,0xEF,0x28,0x05,0x00,0x00,0x3B,0x7F,0x01,0x90,0x04,0x00,0x01,0x77,0x0A,0x80, -0x40,0x24,0x7F,0x27,0x24,0x00,0x00,0x3F,0x5F,0xAA,0x00,0x7F,0x03,0x90,0x04,0x00, -0x7F,0x0A,0x80,0x40,0x24,0x7F,0x27,0x24,0x00,0x00,0x87,0x20,0x7F,0x02,0x90,0x04, -0x00,0x87,0x30,0x7F,0x02,0x90,0x04,0x00,0x87,0x10,0x7F,0x02,0x90,0x04,0x00,0x87, -0x7F,0x00,0x90,0x04,0x00,0xE2,0x40,0x86,0x40,0x59,0xBB,0x6F,0x7F,0x7F,0x00,0x90, -0x04,0x00,0x87,0x05,0x7F,0x02,0x90,0x04,0x00,0xA0,0x14,0x2C,0xCC,0xFC,0xEF,0x28, -0x05,0x00,0x00,0x87,0x20,0x7F,0x0A,0x90,0x04,0x00,0x87,0x30,0x7F,0x0A,0x90,0x04, -0x00,0x87,0x10,0x7F,0x0A,0x90,0x04,0x00,0x87,0x7F,0x08,0x90,0x04,0x00,0xE2,0x40, -0x86,0x40,0x59,0xB3,0x5F,0x80,0x00,0x7F,0x08,0x90,0x04,0x00,0x87,0x05,0x7F,0x0A, -0x90,0x04,0x00,0xA0,0x14,0x2C,0xCC,0xFC,0xEF,0x28,0x05,0x00,0x00,0x87,0x6F,0x55, -0x7F,0x0B,0x90,0x04,0x00,0xA0,0x14,0x2C,0xCC,0xFC,0xEF,0x28,0x05,0x00,0x00,0x3B, -0x7F,0x09,0x90,0x04,0x00,0x01,0x77,0x0A,0x80,0x40,0x24,0x7F,0x27,0x24,0x00,0x00, -0x3F,0x6F,0x55,0x7F,0x0B,0x90,0x04,0x00,0x7F,0x0A,0x80,0x40,0x24,0x7F,0x27,0x24, -0x00,0x00,0x3B,0x7F,0x09,0x90,0x04,0x00,0x01,0x7F,0x0A,0x80,0x40,0x24,0x7F,0x27, -0x24,0x00,0x00,0x87,0x5F,0xAA,0x00,0x7F,0x0B,0x90,0x04,0x00,0xA0,0x14,0x2C,0xCC, -0xFC,0xEF,0x28,0x05,0x00,0x00,0x3B,0x7F,0x09,0x90,0x04,0x00,0x01,0x77,0x0A,0x80, -0x40,0x24,0x7F,0x27,0x24,0x00,0x00,0x3F,0x5F,0xAA,0x00,0x7F,0x0B,0x90,0x04,0x00, -0x7F,0x0A,0x80,0x40,0x24,0x7F,0x27,0x24,0x00,0x00,0x87,0x20,0x7F,0x0A,0x90,0x04, -0x00,0x87,0x30,0x7F,0x0A,0x90,0x04,0x00,0x87,0x10,0x7F,0x0A,0x90,0x04,0x00,0x84, -0x4F,0x7F,0xFF,0x00,0x00,0x40,0x86,0xE2,0x40,0xE0,0x40,0x87,0x7F,0x08,0x90,0x04, -0x00,0xE0,0x41,0xB8,0x41,0x40,0x86,0xE2,0x40,0xE0,0x40,0x87,0x7F,0x08,0x90,0x04, -0x00,0xE0,0x41,0xD0,0x08,0x41,0x41,0x86,0xE2,0x41,0xE0,0x41,0xB0,0x41,0x40,0x86, -0x40,0x59,0x87,0x10,0x7F,0x02,0x90,0x04,0x00,0x87,0x10,0x7F,0x0A,0x90,0x04,0x00, -0x87,0x7F,0x00,0x90,0x04,0x00,0x7F,0x08,0x90,0x04,0x00,0x87,0x7F,0x00,0x90,0x04, -0x00,0x7F,0x08,0x90,0x04,0x00,0x87,0x05,0x7F,0x0A,0x90,0x04,0x00,0xA0,0x14,0x2C, -0xCC,0xFC,0xEF,0x28,0x05,0x00,0x00,0x87,0x20,0x7F,0x03,0x90,0x04,0x00,0xA0,0x14, -0x2C,0xCC,0xFC,0xEF,0x28,0x05,0x00,0x00,0x3B,0x7F,0x09,0x90,0x04,0x00,0x01,0x7F, -0x10,0x3F,0x20,0x7F,0x0B,0x90,0x04,0x00,0x77,0x07,0x84,0x02,0x40,0x7B,0x3A,0x87, -0x20,0x7F,0x0A,0x90,0x04,0x00,0x87,0x30,0x7F,0x0A,0x90,0x04,0x00,0x87,0x10,0x7F, -0x0A,0x90,0x04,0x00,0x86,0xE2,0x59,0xE0,0x40,0xD4,0x08,0x40,0x40,0x87,0x40,0x7F, -0x08,0x90,0x04,0x00,0x87,0x61,0x7F,0x08,0x90,0x04,0x00,0x87,0x05,0x7F,0x0A,0x90, -0x04,0x00,0x84,0x01,0x40,0x7B,0x02,0x18,0x49,0x08,0x70,0x70,0x10,0x49,0x9C,0x4F, -0x18,0x00,0x00,0x00,0x4C,0x80,0xC9,0x14,0x84,0x4F,0x00,0x00,0x20,0x00,0x59,0x84, -0x4F,0x00,0x00,0x80,0x00,0x64,0x84,0x4F,0x00,0x00,0x40,0x00,0x68,0x84,0x4F,0x00, -0x00,0x00,0x01,0x6C,0x80,0xC9,0x10,0x7B,0x10,0xD0,0x02,0xC9,0x10,0x40,0x80,0x80, -0x2C,0x04,0x00,0x02,0x90,0xC9,0x10,0x3C,0x04,0xC9,0x10,0x5B,0xEE,0x80,0xC9,0x10, -0x7B,0x4A,0xD0,0x02,0xC9,0x10,0x40,0xCC,0x00,0x02,0x80,0x00,0xD0,0x04,0x00,0x40, -0x28,0x40,0x7F,0x33,0xD0,0x02,0xC9,0x10,0x40,0x04,0x59,0x41,0xD0,0x02,0xC9,0x10, -0x42,0xCC,0x01,0x00,0x82,0x00,0xD0,0x04,0x00,0x42,0xD0,0x02,0x42,0x42,0x9C,0x42, -0x41,0x84,0x51,0x80,0x2C,0x04,0x00,0x02,0x84,0x80,0x2C,0x04,0x00,0x02,0x40,0x9C, -0x40,0xC9,0x14,0x7B,0x04,0x7B,0x0B,0x90,0xC9,0x10,0x3C,0x04,0xC9,0x10,0x5B,0xB4, -0x84,0xC9,0x14,0x40,0x7B,0x02,0x18,0x49,0x08,0x70,0x70,0x70,0x84,0xCC,0xF8,0x7F, -0x48,0x12,0x00,0x02,0x08,0x70,0x70,0x70,0x10,0x43,0x9C,0x4F,0xC0,0x01,0x00,0x00, -0x4C,0xA0,0x4F,0x0D,0x30,0x04,0x00,0x04,0x59,0x40,0xA0,0x40,0xA0,0x2D,0x2C,0xCC, -0xF4,0x7F,0x2C,0x49,0x00,0x00,0xA0,0x4F,0x50,0x06,0x00,0x00,0x04,0x59,0x40,0xA0, -0x40,0x2C,0xCC,0xF8,0x7F,0xB4,0x3B,0x00,0x00,0xA0,0x00,0x2C,0xCC,0xFC,0xEF,0x40, -0x05,0x00,0x00,0xDC,0x02,0x7F,0xA0,0x04,0x00,0x00,0x40,0xA0,0x40,0x2C,0xCC,0xFC, -0x7F,0xF0,0x39,0x00,0x00,0x3C,0xFF,0x40,0x77,0x20,0xA0,0x01,0x2C,0xCC,0xFC,0xEF, -0x40,0x05,0x00,0x00,0xA0,0x4F,0x7B,0x06,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xB4,0x3B, -0x00,0x00,0x24,0x7F,0x16,0x33,0x00,0x00,0xA0,0x01,0x2C,0xCC,0xFC,0xEF,0x40,0x05, -0x00,0x00,0xDC,0x02,0x7F,0xA0,0x04,0x00,0x00,0x40,0xA0,0x40,0xA0,0x4F,0x7D,0x06, -0x00,0x00,0x2C,0xCC,0xF8,0x7F,0xE8,0x6F,0x00,0x00,0x28,0x40,0x7F,0x08,0x24,0x7F, -0x63,0x26,0x00,0x00,0xA0,0x4F,0x84,0x06,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xB4,0x3B, -0x00,0x00,0x04,0xC9,0x50,0x40,0xA0,0x40,0x2C,0xCC,0xFC,0xAF,0x94,0x0D,0x28,0x40, -0x77,0x07,0x2C,0x5C,0xAF,0xE0,0x0D,0xA0,0x4F,0x00,0x30,0x04,0x00,0x04,0xC9,0x5A, -0x40,0xA0,0x40,0xA0,0x09,0x2C,0xCC,0xF4,0x7F,0x2C,0x49,0x00,0x00,0x04,0xC9,0x50, -0x40,0xA0,0x40,0x04,0xC9,0x5A,0x40,0xA0,0x40,0x2C,0xCC,0xF8,0x7F,0xE8,0x6F,0x00, -0x00,0x28,0x40,0x7F,0x07,0x2C,0x5C,0xAF,0xAD,0x0D,0xA0,0x4F,0x9A,0x06,0x00,0x00, -0x2C,0xCC,0xFC,0x7F,0xB4,0x3B,0x00,0x00,0x04,0x59,0x40,0xA0,0x40,0x2C,0xCC,0xFC, -0xAF,0x3F,0x0D,0x28,0x40,0x77,0x07,0x2C,0x5C,0xAF,0x8B,0x0D,0xA0,0x4F,0xB0,0x06, -0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xB4,0x3B,0x00,0x00,0x04,0xC9,0x50,0x40,0xA0,0x40, -0x2C,0xCC,0xFC,0xAF,0x1C,0x0D,0x28,0x40,0x77,0x07,0x2C,0x5C,0xAF,0x68,0x0D,0x04, -0xC9,0x50,0x40,0xA0,0x40,0x04,0x59,0x40,0xA0,0x40,0x2C,0xCC,0xF8,0x7F,0xE8,0x6F, -0x00,0x00,0x28,0x40,0x7F,0x07,0x2C,0x5C,0xAF,0x4C,0x0D,0xA0,0x4F,0xC0,0x06,0x00, -0x00,0x2C,0xCC,0xFC,0x7F,0xB4,0x3B,0x00,0x00,0x04,0x59,0x40,0xA0,0x40,0xA0,0x4F, -0x00,0x30,0x04,0x00,0x04,0x59,0x40,0xA0,0x40,0x2C,0xCC,0xFC,0x7F,0x10,0x70,0x00, -0x00,0x90,0x40,0xA0,0x40,0x2C,0xCC,0xF4,0x7F,0xDC,0x49,0x00,0x00,0x24,0x7F,0x13, -0x33,0x00,0x00,0xDC,0x02,0x7F,0xA0,0x04,0x00,0x00,0x40,0xA0,0x40,0xA0,0x4F,0xC2, -0x06,0x00,0x00,0x2C,0xCC,0xF8,0x7F,0xE8,0x6F,0x00,0x00,0x28,0x40,0x7F,0x08,0x24, -0x7F,0x4D,0x27,0x00,0x00,0xA0,0x4F,0xC9,0x06,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xB4, -0x3B,0x00,0x00,0x83,0x59,0x7B,0x29,0xA0,0x4F,0x13,0x07,0x00,0x00,0x2C,0xCC,0xFC, -0x7F,0xB4,0x3B,0x00,0x00,0x04,0x59,0x40,0xA0,0x40,0x2C,0xCC,0xFC,0x7F,0xF0,0x39, -0x00,0x00,0x3F,0x6F,0x71,0x59,0x77,0x08,0x24,0x7F,0x16,0x33,0x00,0x00,0x04,0x59, -0x40,0xA0,0x40,0xA0,0x4F,0x10,0x07,0x00,0x00,0x2C,0xCC,0xF8,0x7F,0xE8,0x6F,0x00, -0x00,0x28,0x40,0x77,0xC4,0x84,0x7F,0x08,0x05,0x00,0x00,0x40,0x87,0xC0,0x03,0xC9, -0x5A,0x84,0x7F,0x08,0x05,0x00,0x00,0x40,0x87,0xC0,0x07,0xC9,0x5B,0x84,0x7F,0x08, -0x05,0x00,0x00,0x40,0x87,0xC0,0x0B,0xC9,0x5C,0x84,0x7F,0x08,0x05,0x00,0x00,0x40, -0x87,0xC0,0x0F,0xC9,0x5D,0xA0,0x00,0x04,0xC9,0x5A,0x40,0xA0,0x40,0xA0,0x01,0xA0, -0x03,0x2C,0xCC,0xF0,0x7F,0x2C,0x65,0x00,0x00,0x28,0x40,0x77,0x1E,0xB0,0x20,0x7F, -0x98,0x0C,0x00,0x02,0x2C,0x5C,0x7F,0x44,0x52,0x00,0x00,0xA0,0x4F,0xEF,0xBE,0xED, -0xFE,0x2C,0xCC,0xFC,0x7F,0xFE,0x58,0x00,0x00,0xA0,0x4F,0x4B,0x07,0x00,0x00,0x2C, -0xCC,0xFC,0x7F,0xB4,0x3B,0x00,0x00,0x24,0x7F,0x13,0x33,0x00,0x00,0xDC,0x02,0x7F, -0xA0,0x04,0x00,0x00,0x40,0xA0,0x40,0xA0,0x4F,0x6E,0x07,0x00,0x00,0x2C,0xCC,0xF8, -0x7F,0xE8,0x6F,0x00,0x00,0x28,0x40,0x77,0x24,0x87,0x01,0xEF,0xA0,0x04,0x00,0x00, -0x2C,0x5C,0x7F,0x00,0x40,0x00,0x02,0xA0,0x4F,0xEF,0xBE,0xED,0xFE,0x2C,0xCC,0xFC, -0x7F,0xFE,0x58,0x00,0x00,0x24,0x7F,0x13,0x33,0x00,0x00,0xDC,0x02,0x7F,0xA0,0x04, -0x00,0x00,0x40,0xA0,0x40,0xA0,0x4F,0x76,0x07,0x00,0x00,0x2C,0xCC,0xF8,0x7F,0xE8, -0x6F,0x00,0x00,0x28,0x40,0x7F,0x08,0x24,0x7F,0x3A,0x28,0x00,0x00,0xA0,0x4F,0x7E, -0x07,0x00,0x00,0xA0,0x4F,0xD8,0x12,0x00,0x00,0x2C,0xCC,0xF8,0x7F,0xB4,0x3B,0x00, -0x00,0xA0,0x4F,0x8C,0x07,0x00,0x00,0xA0,0x7F,0xF0,0xFF,0x01,0x00,0x2C,0xCC,0xF8, -0x7F,0xB4,0x3B,0x00,0x00,0xA0,0x4F,0x9A,0x07,0x00,0x00,0xA0,0x4F,0xEC,0x12,0x00, -0x00,0xA0,0x4F,0xE4,0x12,0x00,0x00,0x2C,0xCC,0xF4,0x7F,0xB4,0x3B,0x00,0x00,0xA0, -0x4F,0xB0,0x07,0x00,0x00,0x87,0x7F,0xF3,0xFF,0x01,0x00,0xE0,0x40,0xD0,0x08,0x40, -0x40,0x87,0x7F,0xF7,0xFF,0x01,0x00,0xE0,0x41,0xB0,0x41,0x40,0xD0,0x08,0x40,0x40, -0x87,0x7F,0xFB,0xFF,0x01,0x00,0xE0,0x41,0xB0,0x41,0x40,0xD0,0x08,0x40,0x40,0x87, -0x7F,0xFF,0xFF,0x01,0x00,0xE0,0x41,0xB0,0x41,0x40,0xA0,0x40,0x2C,0xCC,0xF8,0x7F, -0xB4,0x3B,0x00,0x00,0x24,0x7F,0x13,0x33,0x00,0x00,0xDC,0x02,0x7F,0xA0,0x04,0x00, -0x00,0x40,0xA0,0x40,0xA0,0x4F,0xC7,0x07,0x00,0x00,0x2C,0xCC,0xF8,0x7F,0xE8,0x6F, -0x00,0x00,0x28,0x40,0x77,0x08,0x24,0x7F,0x16,0x33,0x00,0x00,0xDC,0x02,0x7F,0xA0, -0x04,0x00,0x00,0x40,0xA0,0x40,0xA0,0x4F,0xC9,0x07,0x00,0x00,0x2C,0xCC,0xF8,0x7F, -0xE8,0x6F,0x00,0x00,0x28,0x40,0x77,0x0F,0x2C,0x5C,0x7F,0x62,0x59,0x00,0x00,0x24, -0x7F,0x13,0x33,0x00,0x00,0xDC,0x02,0x7F,0xA0,0x04,0x00,0x00,0x40,0xA0,0x40,0xA0, -0x4F,0xD1,0x07,0x00,0x00,0x2C,0xCC,0xF8,0x7F,0xE8,0x6F,0x00,0x00,0x28,0x40,0x77, -0x0F,0x2C,0x5C,0x7F,0xD0,0x44,0x00,0x00,0x24,0x7F,0x13,0x33,0x00,0x00,0xDC,0x02, -0x7F,0xA0,0x04,0x00,0x00,0x40,0xA0,0x40,0xA0,0x4F,0xD5,0x07,0x00,0x00,0x2C,0xCC, -0xF8,0x7F,0xE8,0x6F,0x00,0x00,0x28,0x40,0x77,0x0F,0x2C,0x5C,0x7F,0x4A,0x54,0x00, -0x00,0x24,0x7F,0x13,0x33,0x00,0x00,0xDC,0x02,0x7F,0xA0,0x04,0x00,0x00,0x40,0xA0, -0x40,0xA0,0x4F,0xDF,0x07,0x00,0x00,0x2C,0xCC,0xF8,0x7F,0xE8,0x6F,0x00,0x00,0x28, -0x40,0x77,0x0F,0x2C,0x5C,0x7F,0xA4,0x36,0x00,0x00,0x24,0x7F,0x13,0x33,0x00,0x00, -0xDC,0x02,0x7F,0xA0,0x04,0x00,0x00,0x40,0xA0,0x40,0xA0,0x4F,0xE4,0x07,0x00,0x00, -0x2C,0xCC,0xF8,0x7F,0xE8,0x6F,0x00,0x00,0x28,0x40,0x77,0x16,0xA0,0x4F,0xE6,0x07, -0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xB4,0x3B,0x00,0x00,0x24,0x7F,0x13,0x33,0x00,0x00, -0x84,0x7F,0xA0,0x04,0x00,0x00,0x40,0x2B,0xC0,0x02,0x77,0x19,0xDC,0x02,0x7F,0xA0, -0x04,0x00,0x00,0x40,0xA0,0x40,0x04,0x59,0x40,0xA0,0x40,0x2C,0xCC,0xF8,0x7F,0x28, -0x70,0x00,0x00,0x82,0x44,0x7B,0x4F,0x04,0xA9,0xAC,0x00,0x40,0x86,0x44,0xE4,0x41, -0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x82,0x50,0x04,0xA9,0xAC,0x00,0x40,0x86,0x44, -0xE4,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x82,0xC0,0x02,0x04,0xA9,0xAC,0x00, -0x40,0x86,0x44,0xE4,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x82,0xC0,0x04,0x04, -0xA9,0xAC,0x00,0x40,0x86,0x44,0xE4,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x83, -0xC0,0x06,0x92,0x44,0x3E,0x11,0x44,0x4B,0xB0,0x83,0x48,0x04,0xA9,0xAC,0x00,0x40, -0x87,0x48,0xE0,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x9C,0x06,0x40,0xA0,0x40, -0x84,0x7F,0x90,0x04,0x00,0x00,0x40,0xDC,0x02,0xC0,0x08,0x40,0xA0,0x40,0x2C,0xCC, -0xF8,0x7F,0x28,0x70,0x00,0x00,0x04,0xA9,0xAC,0x00,0x40,0x87,0x48,0xE0,0x41,0xD0, -0x04,0x41,0x41,0x9C,0x41,0x40,0x86,0x07,0xC0,0x02,0x04,0xA9,0xAC,0x00,0x40,0x87, -0x48,0x41,0x93,0x48,0x87,0x41,0xE0,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x82, -0x50,0x86,0x01,0x44,0x24,0x7F,0x6E,0x2B,0x00,0x00,0x86,0x44,0xE4,0x40,0xD0,0x05, -0x40,0x40,0x9C,0x7F,0x90,0x04,0x00,0x00,0x40,0xCC,0x00,0x07,0xC0,0x04,0x40,0x28, -0x40,0x77,0x08,0x24,0x7F,0xC9,0x2A,0x00,0x00,0x04,0xA9,0xAC,0x00,0x40,0x87,0x48, -0xE0,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x9C,0x06,0x40,0xA0,0x40,0x86,0x44, -0xE4,0x40,0xD0,0x05,0x40,0x40,0x9C,0x7F,0x90,0x04,0x00,0x00,0x40,0x9C,0x0C,0x40, -0xA0,0x40,0x2C,0xCC,0xF8,0x7F,0x28,0x70,0x00,0x00,0x04,0xA9,0xAC,0x00,0x40,0x87, -0x48,0xE0,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x86,0x44,0xE4,0x41,0xD0,0x05, -0x41,0x41,0x9C,0x7F,0x90,0x04,0x00,0x00,0x41,0xCC,0x02,0x0B,0xC1,0x04,0x41,0x86, -0x41,0xC0,0x02,0x04,0xA9,0xAC,0x00,0x40,0x87,0x48,0xE0,0x41,0xD0,0x04,0x41,0x41, -0x9C,0x41,0x40,0x86,0x44,0xE4,0x41,0xD0,0x05,0x41,0x41,0x9C,0x7F,0x90,0x04,0x00, -0x00,0x41,0xCC,0x03,0x0C,0x51,0x41,0x86,0x41,0xC0,0x04,0x04,0xA9,0xAC,0x00,0x40, -0x87,0x48,0x41,0x93,0x48,0x87,0x41,0xE0,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40, -0x86,0x44,0x50,0x24,0x7F,0x6C,0x2B,0x00,0x00,0x86,0x44,0xE4,0x40,0xD0,0x05,0x40, -0x40,0x9C,0x7F,0x90,0x04,0x00,0x00,0x40,0x2B,0xC0,0x0C,0x7F,0x28,0x86,0x44,0xE4, -0x40,0xD0,0x05,0x40,0x40,0x9C,0x7F,0x90,0x04,0x00,0x00,0x40,0x9C,0x0C,0x40,0xA0, -0x40,0xA0,0x4F,0x94,0x08,0x00,0x00,0x2C,0xCC,0xF8,0x7F,0xE8,0x6F,0x00,0x00,0x28, -0x40,0x77,0x6B,0x04,0xA9,0xAC,0x00,0x40,0x87,0x48,0xE0,0x41,0xD0,0x04,0x41,0x41, -0x9C,0x41,0x40,0x86,0x44,0xE4,0x41,0xD0,0x05,0x41,0x41,0x9C,0x7F,0x90,0x04,0x00, -0x00,0x41,0xCC,0x02,0x0B,0xC1,0x04,0x41,0x86,0x41,0xC0,0x02,0x04,0xA9,0xAC,0x00, -0x40,0x87,0x48,0xE0,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x86,0x44,0xE4,0x41, -0xD0,0x05,0x41,0x41,0x9C,0x7F,0x90,0x04,0x00,0x00,0x41,0xCC,0x03,0x0C,0x51,0x41, -0x86,0x41,0xC0,0x04,0x04,0xA9,0xAC,0x00,0x40,0x87,0x48,0x41,0x93,0x48,0x87,0x41, -0xE0,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x86,0x44,0x50,0x92,0x44,0x86,0x44, -0xE4,0x40,0x87,0xEF,0xE0,0x04,0x00,0x00,0xE0,0x41,0x3C,0x41,0x40,0x4A,0x8D,0xFE, -0xA0,0x4F,0x9B,0x08,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xB4,0x3B,0x00,0x00,0xA0,0x4F, -0xB9,0x08,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xB4,0x3B,0x00,0x00,0xA0,0x4F,0xE6,0x08, -0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xB4,0x3B,0x00,0x00,0x82,0x44,0x24,0x7F,0xA1,0x2C, -0x00,0x00,0xA0,0x4F,0x13,0x09,0x00,0x00,0x86,0x44,0xE4,0x40,0xA0,0x40,0x04,0xA9, -0xAC,0x00,0x40,0x86,0x44,0xE4,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x86,0xE2, -0xC0,0x04,0xE0,0x40,0xA0,0x40,0x2C,0xCC,0xF4,0x7F,0xB4,0x3B,0x00,0x00,0x04,0xA9, -0xAC,0x00,0x40,0x86,0x44,0xE4,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x86,0xE2, -0xC0,0x02,0xE0,0x40,0x7B,0x42,0xA0,0x4F,0x29,0x09,0x00,0x00,0x2C,0xCC,0xFC,0x7F, -0xB4,0x3B,0x00,0x00,0x7B,0x43,0xA0,0x4F,0x37,0x09,0x00,0x00,0x2C,0xCC,0xFC,0x7F, -0xB4,0x3B,0x00,0x00,0x7B,0x33,0xA0,0x4F,0x45,0x09,0x00,0x00,0x2C,0xCC,0xFC,0x7F, -0xB4,0x3B,0x00,0x00,0x7B,0x23,0xA0,0x4F,0x53,0x09,0x00,0x00,0x2C,0xCC,0xFC,0x7F, -0xB4,0x3B,0x00,0x00,0x7B,0x13,0x3C,0x40,0x00,0x7F,0xBD,0x3C,0x40,0x03,0x7F,0xC8, -0x3C,0x40,0x07,0x7F,0xD3,0x7B,0xE1,0x04,0xA9,0xAC,0x00,0x40,0x86,0x44,0xE4,0x41, -0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x9C,0x06,0x40,0xA0,0x40,0xA0,0x4F,0x61,0x09, -0x00,0x00,0x2C,0xCC,0xF8,0x7F,0xE8,0x6F,0x00,0x00,0x28,0x40,0x7F,0x25,0xA0,0x4F, -0x68,0x09,0x00,0x00,0x04,0xA9,0xAC,0x00,0x40,0x86,0x44,0xE4,0x41,0xD0,0x04,0x41, -0x41,0x9C,0x41,0x40,0x9C,0x06,0x40,0xA0,0x40,0x2C,0xCC,0xF8,0x7F,0xB4,0x3B,0x00, -0x00,0xA0,0x4F,0x72,0x09,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xB4,0x3B,0x00,0x00,0x92, -0x44,0x86,0x44,0xE4,0x40,0x87,0x48,0xE0,0x41,0x3C,0x41,0x40,0x5A,0x06,0xFF,0xA0, -0x4F,0x0C,0x30,0x04,0x00,0xDC,0x01,0x7F,0xA0,0x04,0x00,0x00,0x40,0xA0,0x40,0xA0, -0x01,0x2C,0xCC,0xF4,0x7F,0x2C,0x49,0x00,0x00,0x83,0xA9,0xAA,0x00,0x82,0x44,0x24, -0x7F,0xBA,0x2D,0x00,0x00,0x04,0xA9,0xAC,0x00,0x40,0x86,0x44,0xE4,0x41,0xD0,0x04, -0x41,0x41,0x9C,0x41,0x40,0x86,0xE2,0xC0,0x02,0xE0,0x40,0x3C,0x07,0x40,0x77,0x39, -0x84,0x7F,0xA0,0x04,0x00,0x00,0x40,0x87,0xC0,0x01,0xE0,0x40,0x04,0xA9,0xAC,0x00, -0x41,0x86,0x44,0xE4,0x42,0xD0,0x04,0x42,0x42,0x9C,0x42,0x41,0x86,0xE2,0x51,0xE0, -0x41,0x3C,0x41,0x40,0x77,0x0D,0x87,0x01,0xA9,0xAA,0x00,0x24,0x7F,0xC8,0x2D,0x00, -0x00,0x24,0x7F,0xB8,0x2D,0x00,0x00,0x04,0xA9,0xAC,0x00,0x40,0x86,0x44,0xE4,0x41, -0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x86,0xE2,0xC0,0x02,0xE0,0x40,0x77,0x2D,0x04, -0xA9,0xAC,0x00,0x40,0x86,0x44,0xE4,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x86, -0xE2,0xC0,0x04,0xE0,0x40,0x84,0x7F,0xA0,0x04,0x00,0x00,0x41,0x87,0xC1,0x01,0xE0, -0x41,0xD4,0x04,0x41,0x41,0x3C,0x41,0x40,0x7F,0x49,0x04,0xA9,0xAC,0x00,0x40,0x86, -0x44,0xE4,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x86,0xE2,0xC0,0x02,0xE0,0x40, -0x3C,0x03,0x40,0x77,0x35,0x04,0xA9,0xAC,0x00,0x40,0x86,0x44,0xE4,0x41,0xD0,0x04, -0x41,0x41,0x9C,0x41,0x40,0x86,0xE2,0xC0,0x04,0xE0,0x40,0xB0,0x5F,0xD0,0x00,0x40, -0x84,0x7F,0xA0,0x04,0x00,0x00,0x41,0x87,0xC1,0x01,0xE0,0x41,0x3C,0x41,0x40,0x77, -0x09,0x87,0x01,0xA9,0xAA,0x00,0x7B,0x12,0x92,0x44,0x86,0x44,0xE4,0x40,0x87,0x48, -0xE0,0x41,0x3C,0x41,0x40,0x5A,0x10,0xFF,0x2B,0xA9,0xAA,0x00,0x77,0x06,0x83,0x45, -0x7B,0x0C,0xFA,0x5F,0xFF,0x00,0x44,0xE3,0x40,0x87,0x40,0x45,0xA0,0x4F,0x74,0x09, -0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xB4,0x3B,0x00,0x00,0xA0,0x4F,0x96,0x09,0x00,0x00, -0x87,0x45,0xE0,0x40,0xA0,0x40,0x2C,0xCC,0xF8,0x7F,0xB4,0x3B,0x00,0x00,0x04,0xA9, -0xAC,0x00,0x40,0x87,0x45,0xE0,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x9C,0x06, -0x40,0xA0,0x40,0xA0,0x4F,0x9A,0x09,0x00,0x00,0x2C,0xCC,0xF8,0x7F,0xE8,0x6F,0x00, -0x00,0x28,0x40,0x7F,0x25,0xA0,0x4F,0xA1,0x09,0x00,0x00,0x04,0xA9,0xAC,0x00,0x40, -0x87,0x45,0xE0,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x9C,0x06,0x40,0xA0,0x40, -0x2C,0xCC,0xF8,0x7F,0xB4,0x3B,0x00,0x00,0xA0,0x4F,0xA7,0x09,0x00,0x00,0x2C,0xCC, -0xFC,0x7F,0xB4,0x3B,0x00,0x00,0xA0,0x00,0x2C,0xCC,0xFC,0xEF,0x40,0x05,0x00,0x00, -0x04,0xC9,0x5A,0x40,0xA0,0x40,0x2C,0xCC,0xFC,0x7F,0xF0,0x39,0x00,0x00,0x3C,0xFF, -0x40,0x77,0x20,0xA0,0x01,0x2C,0xCC,0xFC,0xEF,0x40,0x05,0x00,0x00,0xA0,0x4F,0xAB, -0x09,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xB4,0x3B,0x00,0x00,0x24,0x7F,0x16,0x33,0x00, -0x00,0xA0,0x01,0x2C,0xCC,0xFC,0xEF,0x40,0x05,0x00,0x00,0x2B,0xC9,0x5A,0x7F,0x4F, -0x04,0xC9,0x5A,0x40,0xA0,0x40,0xA0,0x4F,0xAD,0x09,0x00,0x00,0x04,0xA9,0xBC,0x01, -0x40,0xA0,0x40,0x2C,0xCC,0xF4,0x7F,0xE0,0x40,0x00,0x00,0x3C,0x01,0x40,0x77,0x11, -0x86,0xA9,0xBC,0x01,0xE4,0x40,0x87,0x48,0xE0,0x41,0x3C,0x41,0x40,0x5B,0x19,0xA0, -0x4F,0xB0,0x09,0x00,0x00,0x04,0xC9,0x5A,0x40,0xA0,0x40,0x2C,0xCC,0xF8,0x7F,0xB4, -0x3B,0x00,0x00,0x7A,0xF9,0xFE,0x87,0xA9,0xBD,0x01,0x46,0x7B,0x05,0x87,0x45,0x46, -0x7B,0x02,0x04,0xA9,0xAC,0x00,0x40,0x87,0x46,0xE0,0x41,0xD0,0x04,0x41,0x41,0x9C, -0x41,0x40,0x86,0xE2,0xC0,0x02,0xE0,0x40,0x3C,0x07,0x40,0x77,0x12,0x84,0x7F,0xA0, -0x04,0x00,0x00,0x40,0x83,0xC0,0x01,0x24,0x7F,0xE5,0x32,0x00,0x00,0x04,0xA9,0xAC, -0x00,0x40,0x87,0x46,0xE0,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x86,0xE2,0xC0, -0x02,0xE0,0x40,0x7F,0x08,0x24,0x7F,0xC3,0x32,0x00,0x00,0x3F,0x45,0x46,0x77,0x13, -0x84,0x7F,0xA0,0x04,0x00,0x00,0x40,0xFB,0x0F,0xC0,0x01,0x40,0x87,0x40,0x47,0x7B, -0x04,0x83,0x47,0x84,0x7F,0xA0,0x04,0x00,0x00,0x40,0x04,0xA9,0xAC,0x00,0x41,0x87, -0x46,0xE0,0x42,0xD0,0x04,0x42,0x42,0x9C,0x42,0x41,0x86,0xE2,0xC1,0x04,0xE0,0x41, -0xD0,0x04,0x41,0x41,0x87,0x41,0xC0,0x01,0x04,0xA9,0xAC,0x00,0x40,0x87,0x46,0xE0, -0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x86,0x50,0x44,0x82,0x43,0x7B,0x4F,0x04, -0xA9,0xAC,0x00,0x40,0x86,0x43,0xE4,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x82, -0x50,0x04,0xA9,0xAC,0x00,0x40,0x86,0x43,0xE4,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41, -0x40,0x82,0xC0,0x02,0x04,0xA9,0xAC,0x00,0x40,0x86,0x43,0xE4,0x41,0xD0,0x04,0x41, -0x41,0x9C,0x41,0x40,0x82,0xC0,0x04,0x04,0xA9,0xAC,0x00,0x40,0x86,0x43,0xE4,0x41, -0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x83,0xC0,0x06,0x92,0x43,0x3E,0x11,0x43,0x4B, -0xB0,0x86,0x44,0xE4,0x40,0xD0,0x05,0x40,0x40,0x9C,0x7F,0x90,0x04,0x00,0x00,0x40, -0xCC,0x03,0x00,0xC0,0x04,0x40,0x87,0x40,0x48,0x2B,0x48,0x77,0x0B,0x87,0x0F,0x48, -0x83,0xA9,0xAB,0x00,0x7B,0x07,0x87,0x01,0xA9,0xAB,0x00,0x82,0x43,0x7B,0x52,0x04, -0xA9,0xAC,0x00,0x40,0x86,0x43,0xE4,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x9C, -0x06,0x40,0xA0,0x40,0x86,0x44,0xE4,0x40,0xD0,0x05,0x40,0x40,0x9C,0x7F,0x90,0x04, -0x00,0x00,0x40,0xEA,0x0C,0x43,0x41,0xDC,0x41,0xC0,0x08,0x40,0x9C,0x02,0x40,0xA0, -0x40,0x2C,0xCC,0xF8,0x7F,0x28,0x70,0x00,0x00,0x04,0xA9,0xAC,0x00,0x40,0x86,0x43, -0xE4,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x86,0x43,0xC0,0x04,0x92,0x43,0x86, -0x43,0xE4,0x40,0x87,0x48,0xE0,0x41,0x3C,0x41,0x40,0x5B,0xA5,0xA0,0x4F,0xD3,0x09, -0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xB4,0x3B,0x00,0x00,0xA0,0x4F,0xEE,0x09,0x00,0x00, -0x2C,0xCC,0xFC,0x7F,0xB4,0x3B,0x00,0x00,0xA0,0x4F,0x11,0x0A,0x00,0x00,0x2C,0xCC, -0xFC,0x7F,0xB4,0x3B,0x00,0x00,0x82,0x43,0x24,0x7F,0x2A,0x31,0x00,0x00,0xA0,0x4F, -0x3F,0x0A,0x00,0x00,0x86,0x43,0xE4,0x40,0xA0,0x40,0x04,0xA9,0xAC,0x00,0x40,0x86, -0x43,0xE4,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x86,0xE2,0xC0,0x04,0xE0,0x40, -0xA0,0x40,0x2C,0xCC,0xF4,0x7F,0xB4,0x3B,0x00,0x00,0x04,0xA9,0xAC,0x00,0x40,0x86, -0x43,0xE4,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x9C,0x06,0x40,0xA0,0x40,0xA0, -0x4F,0x56,0x0A,0x00,0x00,0x2C,0xCC,0xF8,0x7F,0xE8,0x6F,0x00,0x00,0x28,0x40,0x7F, -0x2B,0x2B,0xA9,0xAB,0x00,0x7F,0x25,0xA0,0x4F,0x5D,0x0A,0x00,0x00,0x04,0xA9,0xAC, -0x00,0x40,0x86,0x43,0xE4,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x9C,0x06,0x40, -0xA0,0x40,0x2C,0xCC,0xF8,0x7F,0xB4,0x3B,0x00,0x00,0xA0,0x4F,0x6B,0x0A,0x00,0x00, -0x2C,0xCC,0xFC,0x7F,0xB4,0x3B,0x00,0x00,0x92,0x43,0x86,0x43,0xE4,0x40,0x87,0x48, -0xE0,0x41,0x3C,0x41,0x40,0x5A,0x69,0xFF,0x83,0xA9,0xAA,0x00,0x82,0x43,0x7B,0x2A, -0x04,0xA9,0xAC,0x00,0x40,0x86,0x43,0xE4,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40, -0x86,0xE2,0xC0,0x04,0xE0,0x40,0x87,0x47,0xE0,0x41,0x3C,0x41,0x40,0x77,0x09,0x87, -0x01,0xA9,0xAA,0x00,0x7B,0x11,0x92,0x43,0x86,0x43,0xE4,0x40,0x87,0x48,0xE0,0x41, -0x3C,0x41,0x40,0x5B,0xCD,0x2B,0xA9,0xAA,0x00,0x77,0x06,0x83,0x45,0x7B,0x0C,0xFA, -0x5F,0xFF,0x00,0x43,0xE3,0x40,0x87,0x40,0x45,0xA0,0x4F,0x6D,0x0A,0x00,0x00,0x2C, -0xCC,0xFC,0x7F,0xB4,0x3B,0x00,0x00,0xA0,0x4F,0x8D,0x0A,0x00,0x00,0x87,0x45,0xE0, -0x40,0xA0,0x40,0x2C,0xCC,0xF8,0x7F,0xB4,0x3B,0x00,0x00,0x04,0xA9,0xAC,0x00,0x40, -0x87,0x45,0xE0,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x9C,0x06,0x40,0xA0,0x40, -0xA0,0x4F,0x91,0x0A,0x00,0x00,0x2C,0xCC,0xF8,0x7F,0xE8,0x6F,0x00,0x00,0x28,0x40, -0x7F,0x2B,0x2B,0xA9,0xAB,0x00,0x7F,0x25,0xA0,0x4F,0x98,0x0A,0x00,0x00,0x04,0xA9, -0xAC,0x00,0x40,0x87,0x45,0xE0,0x41,0xD0,0x04,0x41,0x41,0x9C,0x41,0x40,0x9C,0x06, -0x40,0xA0,0x40,0x2C,0xCC,0xF8,0x7F,0xB4,0x3B,0x00,0x00,0xA0,0x4F,0x9E,0x0A,0x00, -0x00,0x2C,0xCC,0xFC,0x7F,0xB4,0x3B,0x00,0x00,0xA0,0x00,0x2C,0xCC,0xFC,0xEF,0x40, -0x05,0x00,0x00,0x04,0xC9,0x5A,0x40,0xA0,0x40,0x2C,0xCC,0xFC,0x7F,0xF0,0x39,0x00, -0x00,0x3C,0xFF,0x40,0x77,0x20,0xA0,0x01,0x2C,0xCC,0xFC,0xEF,0x40,0x05,0x00,0x00, -0xA0,0x4F,0xA2,0x0A,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xB4,0x3B,0x00,0x00,0x24,0x7F, -0x16,0x33,0x00,0x00,0xA0,0x01,0x2C,0xCC,0xFC,0xEF,0x40,0x05,0x00,0x00,0x2B,0xC9, -0x5A,0x7F,0x4F,0x04,0xC9,0x5A,0x40,0xA0,0x40,0xA0,0x4F,0xA4,0x0A,0x00,0x00,0x04, -0xA9,0xBC,0x01,0x40,0xA0,0x40,0x2C,0xCC,0xF4,0x7F,0xE0,0x40,0x00,0x00,0x3C,0x01, -0x40,0x77,0x11,0x86,0xA9,0xBC,0x01,0xE4,0x40,0x87,0x48,0xE0,0x41,0x3C,0x41,0x40, -0x5B,0x19,0xA0,0x4F,0xA7,0x0A,0x00,0x00,0x04,0xC9,0x5A,0x40,0xA0,0x40,0x2C,0xCC, -0xF8,0x7F,0xB4,0x3B,0x00,0x00,0x7A,0xF3,0xFE,0x87,0xA9,0xBD,0x01,0x46,0x7B,0x05, -0x87,0x45,0x46,0x7B,0x02,0x84,0x7F,0xA0,0x04,0x00,0x00,0x40,0x04,0xA9,0xAC,0x00, -0x41,0x87,0x46,0xE0,0x42,0xD0,0x04,0x42,0x42,0x9C,0x42,0x41,0xB3,0xC1,0x05,0xC0, -0x01,0x7B,0x24,0x84,0x7F,0xA0,0x04,0x00,0x00,0x40,0x04,0xA9,0xAC,0x00,0x41,0x87, -0x46,0xE0,0x42,0xD0,0x04,0x42,0x42,0x9C,0x42,0x41,0xF3,0x5F,0xD0,0x00,0xC1,0x05, -0x41,0x87,0x41,0xC0,0x01,0x87,0x01,0xEF,0xA0,0x04,0x00,0x00,0x2C,0x5C,0x7F,0xFC, -0x5F,0x00,0x00,0x28,0x40,0x77,0x1E,0xB0,0x04,0x7F,0x98,0x0C,0x00,0x02,0x2C,0x5C, -0x7F,0x44,0x52,0x00,0x00,0xA0,0x4F,0xEF,0xBE,0xED,0xFE,0x2C,0xCC,0xFC,0x7F,0xFE, -0x58,0x00,0x00,0x7A,0xCE,0xF1,0x18,0x43,0x08,0x70,0x70,0x70,0x10,0x49,0x9C,0x4F, -0x04,0x00,0x00,0x00,0x4C,0x82,0x59,0x7B,0x38,0x7B,0x02,0x2C,0x5C,0x7F,0x4C,0x3B, -0x00,0x00,0x87,0x40,0xDA,0x00,0x87,0xDA,0x00,0xE0,0x40,0x2B,0x40,0x7F,0xEE,0x3F, -0x0D,0xDA,0x00,0x7F,0x08,0x3F,0x0A,0xDA,0x00,0x77,0x12,0x2A,0x59,0x77,0x06,0x80, -0x40,0x7B,0x1B,0x83,0xDA,0x00,0x84,0x01,0x40,0x7B,0x13,0x90,0x5A,0x92,0x59,0x3E, -0x08,0x59,0x4B,0xC7,0x83,0xDA,0x00,0x84,0x01,0x40,0x7B,0x02,0x18,0x49,0x08,0x70, -0x70,0x70,0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0xA0,0x4F,0xCA,0x0A,0x00, -0x00,0x2C,0xCC,0xFC,0x7F,0xB4,0x3B,0x00,0x00,0xA0,0x4F,0x1E,0xAC,0xEB,0xAD,0x2C, -0xCC,0xFC,0x7F,0xFE,0x58,0x00,0x00,0x18,0x49,0x08,0x70,0x70,0x10,0x49,0x9C,0x4F, -0x04,0x00,0x00,0x00,0x4C,0xA0,0x4F,0x80,0x30,0x04,0x00,0x04,0x59,0x40,0xA0,0x40, -0xA0,0x02,0x2C,0xCC,0xF4,0x7F,0x2C,0x49,0x00,0x00,0x28,0x40,0x7F,0x09,0x86,0xE2, -0x59,0xE0,0x40,0x77,0x1C,0x86,0x5F,0xBD,0x04,0x59,0x04,0x59,0x40,0xA0,0x40,0xA0, -0x4F,0x80,0x30,0x04,0x00,0xA0,0x02,0x2C,0xCC,0xF4,0x7F,0xDC,0x49,0x00,0x00,0x86, -0xE2,0x59,0xE0,0x40,0xA0,0x40,0xA0,0x4F,0x00,0x90,0x04,0x00,0x2C,0xCC,0xF8,0x7F, -0x60,0x35,0x00,0x00,0xA0,0x4F,0x0A,0x30,0x04,0x00,0x04,0x59,0x40,0xA0,0x40,0xA0, -0x02,0x2C,0xCC,0xF4,0x7F,0x2C,0x49,0x00,0x00,0x28,0x40,0x7F,0x09,0x86,0xE2,0x59, -0xE0,0x40,0x77,0x1A,0x86,0x3D,0x59,0x04,0x59,0x40,0xA0,0x40,0xA0,0x4F,0x0A,0x30, -0x04,0x00,0xA0,0x02,0x2C,0xCC,0xF4,0x7F,0xDC,0x49,0x00,0x00,0x86,0xE2,0x59,0xE0, -0x40,0xA0,0x40,0xA0,0x4F,0x08,0x90,0x04,0x00,0x2C,0xCC,0xF8,0x7F,0x60,0x35,0x00, -0x00,0x18,0x49,0x08,0x10,0x48,0x9C,0x4F,0x04,0x00,0x00,0x00,0x4C,0x86,0x01,0x48, -0x7B,0x23,0x3E,0x10,0x48,0x5B,0x1C,0xA0,0x4F,0x54,0x0B,0x00,0x00,0x86,0x72,0xE4, -0x40,0xA0,0x40,0x2C,0xCC,0xF8,0x7F,0xB4,0x3B,0x00,0x00,0x24,0x7F,0x5A,0x35,0x00, -0x00,0x92,0x48,0x86,0x48,0xE4,0x40,0xD0,0x03,0x40,0x40,0x3E,0x72,0x80,0xD4,0x0A, -0x00,0x00,0x77,0xD0,0x3C,0x4F,0x08,0x90,0x04,0x00,0x74,0x77,0x3B,0x84,0x30,0x40, -0x86,0xE2,0x40,0xE0,0x40,0x86,0x48,0xE4,0x41,0xD0,0x03,0x41,0x41,0x87,0x81,0xD6, -0x0A,0x00,0x00,0xE0,0x41,0xB0,0x41,0x40,0x86,0x40,0x59,0x04,0x59,0x40,0xA0,0x40, -0xA0,0x4F,0x0A,0x30,0x04,0x00,0xA0,0x02,0x2C,0xCC,0xF4,0x7F,0xDC,0x49,0x00,0x00, -0x24,0x7F,0x4B,0x35,0x00,0x00,0xA0,0x4F,0x80,0x30,0x04,0x00,0x04,0x59,0x40,0xA0, -0x40,0xA0,0x02,0x2C,0xCC,0xF4,0x7F,0x2C,0x49,0x00,0x00,0x86,0xE2,0x59,0xE0,0x40, -0x7F,0x36,0x84,0x4F,0xF0,0xFF,0x00,0x00,0x40,0x86,0xE2,0x40,0xE0,0x40,0x86,0xE2, -0x59,0xE0,0x41,0xB8,0x41,0x40,0x86,0x40,0x59,0x86,0x48,0xE4,0x40,0xD0,0x03,0x40, -0x40,0x87,0x80,0xD6,0x0A,0x00,0x00,0xE0,0x40,0x86,0xE2,0x59,0xE0,0x41,0xB0,0x41, -0x40,0x86,0x40,0x59,0x7B,0x22,0x84,0x5F,0xB0,0x04,0x40,0x86,0xE2,0x40,0xE0,0x40, -0x86,0x48,0xE4,0x41,0xD0,0x03,0x41,0x41,0x87,0x81,0xD6,0x0A,0x00,0x00,0xE0,0x41, -0xB0,0x41,0x40,0x86,0x40,0x59,0x04,0x59,0x40,0xA0,0x40,0xA0,0x4F,0x80,0x30,0x04, -0x00,0xA0,0x02,0x2C,0xCC,0xF4,0x7F,0xDC,0x49,0x00,0x00,0x86,0xE2,0x59,0xE0,0x40, -0xA0,0x40,0xA0,0x74,0x2C,0xCC,0xF8,0xAF,0x0C,0x00,0x18,0x48,0x08,0x70,0x70,0x70, -0x10,0x47,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x86,0x01,0x48,0x7B,0x27,0x86,0xE2, -0x48,0xE0,0x40,0x3C,0x10,0x40,0x5B,0x0A,0x86,0x0D,0x48,0x86,0x30,0x72,0x7B,0x33, -0x84,0x01,0x40,0x86,0xE2,0x40,0xE0,0x40,0x86,0xE2,0x48,0xE0,0x41,0x9C,0x41,0x40, -0x86,0x40,0x48,0x86,0xE2,0x48,0xE0,0x40,0xD0,0x03,0x40,0x40,0x87,0x80,0xD6,0x0A, -0x00,0x00,0xE0,0x40,0x86,0xE2,0x72,0xE0,0x41,0xB8,0x0F,0x41,0x3C,0x41,0x40,0x77, -0xBF,0x84,0x74,0x40,0x87,0x1A,0xC0,0x02,0x84,0x74,0x40,0x87,0x20,0xC0,0x02,0x84, -0x74,0x40,0x87,0x30,0xC0,0x02,0x84,0x74,0x40,0x87,0x6F,0x40,0xC0,0x02,0x84,0x74, -0x40,0x87,0x6F,0x70,0xC0,0x02,0x86,0xE2,0x72,0xE0,0x40,0x38,0x40,0x5F,0x00,0x01, -0x7F,0x1A,0x86,0xE2,0x72,0xE0,0x40,0x38,0x40,0x5F,0x00,0x02,0x7F,0x07,0x84,0x04, -0x40,0x7B,0x04,0x80,0x40,0xB0,0x00,0x40,0x7B,0x05,0x84,0x10,0x40,0xB3,0x00,0x40, -0x87,0x40,0x47,0x86,0xE2,0x72,0xE0,0x40,0xB8,0x30,0x40,0x7B,0x13,0x7B,0x22,0xB3, -0x01,0x47,0x7B,0x1D,0xB3,0x02,0x47,0x7B,0x18,0xB3,0x03,0x47,0x7B,0x13,0x3C,0x40, -0x00,0x7F,0xEC,0x3C,0x40,0x10,0x7F,0xE9,0x3C,0x40,0x20,0x7F,0xE9,0x7B,0xEC,0x87, -0x47,0xDA,0x04,0x86,0xE2,0x72,0xE0,0x40,0x38,0x40,0x6F,0x40,0x7F,0x07,0x84,0x0F, -0x40,0x7B,0x05,0x84,0x07,0x40,0xB3,0x00,0x40,0x87,0x40,0xDA,0x04,0x84,0x74,0x40, -0x86,0xE2,0x48,0xE0,0x41,0xD0,0x03,0x41,0x41,0x87,0x81,0xD7,0x0A,0x00,0x00,0xC0, -0x01,0x86,0xE2,0x48,0xE0,0x40,0xD0,0x03,0x40,0x40,0x87,0x80,0xD8,0x0A,0x00,0x00, -0x7F,0x4C,0x12,0x00,0x02,0x84,0x74,0x40,0x87,0x7F,0x4C,0x12,0x00,0x02,0xC0,0x04, -0x84,0x74,0x40,0x87,0x15,0xC0,0x02,0x87,0x30,0x7F,0x0E,0x90,0x04,0x00,0xA0,0x01, -0x2C,0xCC,0xFC,0xEF,0x28,0x05,0x00,0x00,0x84,0x74,0x40,0x87,0x20,0xC0,0x03,0x18, -0x47,0x08,0x70,0x70,0x10,0x49,0x9C,0x4F,0x54,0x00,0x00,0x00,0x4C,0xA0,0x4F,0x80, -0x30,0x04,0x00,0x04,0x59,0x40,0xA0,0x40,0xA0,0x02,0x2C,0xCC,0xF4,0x7F,0x2C,0x49, -0x00,0x00,0xA0,0x4F,0x6F,0x0B,0x00,0x00,0x86,0xE2,0x59,0xE0,0x40,0xB8,0x0F,0x40, -0xD0,0x03,0x40,0x40,0x86,0x80,0xD4,0x0A,0x00,0x00,0xE4,0x40,0xA0,0x40,0x2C,0xCC, -0xF8,0x7F,0xB4,0x3B,0x00,0x00,0x04,0x62,0x40,0xA0,0x40,0x2C,0xCC,0xFC,0xEF,0xB4, -0x04,0x00,0x00,0x2B,0x62,0x7F,0x5C,0x04,0x62,0x40,0xA0,0x40,0xA0,0x4F,0x85,0x0B, -0x00,0x00,0x04,0x59,0x40,0xA0,0x40,0x2C,0xCC,0xF4,0x7F,0xE0,0x40,0x00,0x00,0x3C, -0x01,0x40,0x7F,0x17,0xA0,0x4F,0x88,0x0B,0x00,0x00,0x04,0x62,0x40,0xA0,0x40,0x2C, -0xCC,0xF8,0x7F,0xB4,0x3B,0x00,0x00,0x7B,0x2A,0xA0,0x4F,0xA3,0x0B,0x00,0x00,0x86, -0xE2,0x59,0xE0,0x40,0xA0,0x40,0x2C,0xCC,0xF8,0x7F,0xB4,0x3B,0x00,0x00,0x86,0xE2, -0x59,0xE0,0x40,0xA0,0x40,0xA0,0x4F,0x00,0x90,0x04,0x00,0x2C,0xCC,0xF8,0xAF,0xF9, -0xFC,0x18,0x49,0x08,0x28,0x5D,0x70,0x70,0x70,0x10,0x49,0x84,0x5A,0x42,0x84,0x74, -0x41,0x84,0x78,0x40,0x30,0x19,0x18,0x49,0x08,0x70,0x70,0x70,0x84,0xCE,0xFC,0x40, -0x84,0x50,0x7F,0x10,0x04,0x00,0x02,0x84,0xC0,0x04,0x7F,0x14,0x04,0x00,0x02,0x87, -0x00,0x7F,0x25,0x04,0x00,0x02,0x2C,0x5C,0x7F,0x5E,0x6E,0x00,0x00,0x30,0xC8,0x84, -0xCE,0xFC,0x40,0x84,0x50,0x7F,0x10,0x04,0x00,0x02,0x84,0xC0,0x04,0x7F,0x14,0x04, -0x00,0x02,0x87,0x00,0x7F,0x25,0x04,0x00,0x02,0x2C,0x5C,0x7F,0xBC,0x6D,0x00,0x00, -0x30,0xC8,0x84,0xCE,0xFC,0x40,0x84,0x50,0x7F,0x10,0x04,0x00,0x02,0x84,0xC0,0x04, -0x7F,0x14,0x04,0x00,0x02,0x87,0x08,0x7F,0x25,0x04,0x00,0x02,0x2C,0x5C,0x7F,0xBC, -0x6D,0x00,0x00,0x30,0xC8,0x84,0xCE,0xFC,0x40,0x84,0x50,0x7F,0x10,0x04,0x00,0x02, -0x84,0xC0,0x04,0x7F,0x14,0x04,0x00,0x02,0x87,0x09,0x7F,0x25,0x04,0x00,0x02,0x2C, -0x5C,0x7F,0xBC,0x6D,0x00,0x00,0x30,0xC8,0x84,0xCE,0xFC,0x40,0x84,0x50,0x7F,0x10, -0x04,0x00,0x02,0x84,0xC0,0x04,0x7F,0x14,0x04,0x00,0x02,0x87,0x0A,0x7F,0x25,0x04, -0x00,0x02,0x2C,0x5C,0x7F,0xBC,0x6D,0x00,0x00,0x30,0xC8,0x84,0xCE,0xFC,0x40,0x84, -0x50,0x7F,0x10,0x04,0x00,0x02,0x84,0xC0,0x04,0x7F,0x14,0x04,0x00,0x02,0x87,0x0B, -0x7F,0x25,0x04,0x00,0x02,0x2C,0x5C,0x7F,0xBC,0x6D,0x00,0x00,0x30,0xC8,0x84,0xCE, -0xFC,0x40,0x84,0x50,0x7F,0x10,0x04,0x00,0x02,0x84,0xC0,0x04,0x7F,0x14,0x04,0x00, -0x02,0x87,0x0C,0x7F,0x25,0x04,0x00,0x02,0x2C,0x5C,0x7F,0xBC,0x6D,0x00,0x00,0x30, -0xC8,0x84,0xCE,0xFC,0x40,0x84,0x50,0x7F,0x10,0x04,0x00,0x02,0x84,0xC0,0x04,0x7F, -0x14,0x04,0x00,0x02,0x87,0x0D,0x7F,0x25,0x04,0x00,0x02,0x2C,0x5C,0x7F,0xBC,0x6D, -0x00,0x00,0x30,0xC8,0x84,0xCE,0xFC,0x40,0x84,0x50,0x7F,0x10,0x04,0x00,0x02,0x84, -0xC0,0x04,0x7F,0x14,0x04,0x00,0x02,0x87,0x0E,0x7F,0x25,0x04,0x00,0x02,0x2C,0x5C, -0x7F,0xBC,0x6D,0x00,0x00,0x30,0xC8,0x84,0xCE,0xFC,0x40,0x84,0x50,0x7F,0x10,0x04, -0x00,0x02,0x84,0xC0,0x04,0x7F,0x14,0x04,0x00,0x02,0x87,0x0F,0x7F,0x25,0x04,0x00, -0x02,0x2C,0x5C,0x7F,0xBC,0x6D,0x00,0x00,0x30,0xC8,0x70,0x70,0x84,0xCE,0xFC,0x40, -0x84,0x50,0x7F,0x10,0x04,0x00,0x02,0x84,0xC0,0x04,0x7F,0x14,0x04,0x00,0x02,0x84, -0xC0,0x1C,0x7F,0x1C,0x04,0x00,0x02,0x2C,0x5C,0x7F,0x48,0x6F,0x00,0x00,0x30,0xC8, -0x84,0xCC,0xFC,0x7F,0x10,0x04,0x00,0x02,0x84,0xCC,0xF8,0x7F,0x14,0x04,0x00,0x02, -0x84,0x40,0x7F,0x1C,0x04,0x00,0x02,0x84,0x4F,0x00,0xE1,0x81,0x00,0x4B,0x70,0x2C, -0x5C,0x7F,0x48,0x6F,0x00,0x00,0x84,0x7F,0x48,0x12,0x00,0x02,0xCC,0xF8,0x84,0x7F, -0x10,0x04,0x00,0x02,0xCC,0xFC,0x30,0x45,0x84,0x40,0x7F,0x1C,0x04,0x00,0x02,0x84, -0xCC,0xFC,0x7F,0x10,0x04,0x00,0x02,0x84,0xCC,0xF8,0x7F,0x14,0x04,0x00,0x02,0x04, -0x7F,0xF0,0x0E,0x00,0x02,0x40,0x30,0xAC,0x84,0x7F,0x48,0x12,0x00,0x02,0xCC,0xF8, -0x84,0x7F,0x10,0x04,0x00,0x02,0x4B,0x70,0x30,0x45,0x84,0x4F,0x00,0xE1,0x81,0x00, -0x4B,0x70,0x2C,0x5C,0x7F,0x48,0x6F,0x00,0x00,0x30,0xC8,0x70,0x10,0x49,0x9C,0x4F, -0x04,0x00,0x00,0x00,0x4C,0x7B,0x21,0x2B,0xEF,0x10,0x05,0x00,0x00,0x77,0x19,0x38, -0x7F,0x00,0x40,0x04,0x00,0x02,0x7F,0x10,0x80,0xEF,0x8C,0x04,0x00,0x00,0x80,0x7F, -0x44,0x40,0x04,0x00,0x7B,0x00,0x84,0x5A,0x40,0x3B,0xC0,0x01,0x01,0x7F,0xDA,0x3C, -0x7F,0x18,0x04,0x00,0x02,0x5A,0x77,0x3D,0x84,0x5A,0x40,0x3B,0xC0,0x01,0x5F,0x80, -0x00,0x7F,0x32,0x84,0x5A,0x40,0x87,0x6F,0x40,0xC0,0x02,0x84,0x5A,0x40,0x87,0x6F, -0x50,0xC0,0x02,0x84,0x5A,0x40,0x87,0xC0,0x03,0x59,0x84,0x5A,0x40,0x3B,0xC0,0x01, -0x01,0x77,0xE2,0x3F,0x01,0x7F,0x9D,0x0C,0x00,0x02,0x77,0x04,0x7B,0x99,0x84,0xFF, -0x40,0x7B,0x0C,0x84,0x5A,0x40,0x87,0xC0,0x03,0xE0,0x40,0x7B,0x02,0x18,0x49,0x08, -0x10,0x47,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x2B,0xEF,0xC4,0x04,0x00,0x00,0x77, -0x29,0x2B,0xEF,0x10,0x05,0x00,0x00,0x77,0x19,0x38,0x7F,0x00,0x40,0x04,0x00,0x02, -0x7F,0x10,0x80,0xEF,0x8C,0x04,0x00,0x00,0x80,0x7F,0x44,0x40,0x04,0x00,0x7B,0x00, -0x80,0x40,0x24,0x7F,0x48,0x3B,0x00,0x00,0x84,0x5A,0x48,0x24,0x7F,0x26,0x3B,0x00, -0x00,0xA0,0x7F,0x18,0x04,0x00,0x02,0x2C,0xCC,0xFC,0xEF,0x28,0x00,0x00,0x02,0x84, -0x40,0x47,0x28,0x47,0x43,0x0B,0x84,0xFF,0x40,0x24,0x7F,0x48,0x3B,0x00,0x00,0xF8, -0x5F,0xFF,0x00,0x47,0xE3,0x40,0x87,0x40,0xDA,0x00,0x3F,0x0A,0xDA,0x00,0x7F,0x08, -0x3F,0x0D,0xDA,0x00,0x77,0x2B,0x83,0xDA,0x00,0xA0,0x0A,0xA0,0x7F,0x18,0x04,0x00, -0x02,0x2C,0xCC,0xF8,0xEF,0x24,0x00,0x00,0x02,0x28,0x40,0x43,0x0B,0x84,0xFF,0x40, -0x24,0x7F,0x48,0x3B,0x00,0x00,0x84,0x01,0x40,0x24,0x7F,0x48,0x3B,0x00,0x00,0x3F, -0x6F,0x7F,0xDA,0x00,0x77,0x0B,0x84,0xFF,0x40,0x24,0x7F,0x48,0x3B,0x00,0x00,0x3F, -0x13,0xDA,0x00,0x7F,0x08,0x3F,0x11,0xDA,0x00,0x77,0x04,0x7B,0x20,0x87,0xDA,0x00, -0xE0,0x40,0xA0,0x40,0xA0,0x7F,0x18,0x04,0x00,0x02,0x2C,0xCC,0xF8,0xEF,0x24,0x00, -0x00,0x02,0x28,0x40,0x43,0x07,0x84,0xFF,0x40,0x7B,0x7F,0x3F,0x08,0xDA,0x00,0x77, -0x22,0x3C,0x48,0x5A,0x7F,0x1B,0xA0,0x4F,0xBC,0x0B,0x00,0x00,0x2C,0xCC,0xFC,0xEF, -0xB0,0x04,0x00,0x00,0x28,0x40,0x43,0x07,0x84,0xFF,0x40,0x7B,0x5D,0x94,0x5A,0x7B, -0x37,0x3F,0x6F,0x40,0xDA,0x00,0x77,0x20,0x84,0x48,0x5A,0xA0,0x0A,0xA0,0x7F,0x18, -0x04,0x00,0x02,0x2C,0xCC,0xF8,0xEF,0x24,0x00,0x00,0x02,0x28,0x40,0x43,0x07,0x84, -0xFF,0x40,0x7B,0x36,0x7B,0x12,0x3F,0x13,0xDA,0x00,0x7F,0x08,0x3F,0x11,0xDA,0x00, -0x77,0x04,0x7B,0x04,0x90,0x5A,0xFC,0x48,0x5A,0x40,0x3C,0x6F,0x50,0x40,0x4A,0x03, -0xFF,0xA0,0x4F,0xBF,0x0B,0x00,0x00,0xA0,0x6F,0x50,0x2C,0xCC,0xF8,0xEF,0xB0,0x04, -0x00,0x00,0x84,0x48,0x5A,0x7A,0xE6,0xFE,0x18,0x47,0x08,0x70,0x10,0x49,0x9C,0x4F, -0x00,0x00,0x00,0x00,0x4C,0x2C,0x5C,0xEF,0x2C,0x00,0x00,0x02,0x87,0x40,0xE0,0x40, -0x7B,0x02,0x18,0x49,0x08,0x70,0x70,0x70,0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00, -0x4C,0x2B,0xEF,0x10,0x05,0x00,0x00,0x77,0x19,0x38,0x7F,0x00,0x40,0x04,0x00,0x02, -0x7F,0x10,0x80,0xEF,0x8C,0x04,0x00,0x00,0x80,0x7F,0x44,0x40,0x04,0x00,0x7B,0x00, -0x84,0x7F,0x18,0x04,0x00,0x02,0x40,0x3B,0xC0,0x01,0x01,0x7F,0x10,0x84,0x7F,0x18, -0x04,0x00,0x02,0x40,0x87,0xC0,0x03,0xE0,0x40,0x7B,0x06,0x80,0x40,0x7B,0x02,0x18, -0x49,0x08,0x70,0x70,0x10,0x49,0x9C,0x4F,0x38,0x00,0x00,0x00,0x4C,0x2B,0xEF,0xC4, -0x04,0x00,0x00,0x77,0x29,0x2B,0xEF,0x10,0x05,0x00,0x00,0x77,0x19,0x38,0x7F,0x00, -0x40,0x04,0x00,0x02,0x7F,0x10,0x80,0xEF,0x8C,0x04,0x00,0x00,0x80,0x7F,0x44,0x40, -0x04,0x00,0x7B,0x00,0x80,0x40,0x24,0x7F,0x5E,0x3F,0x00,0x00,0x84,0x7F,0x18,0x04, -0x00,0x02,0x40,0x87,0x15,0xC0,0x02,0x80,0xC9,0x28,0x04,0x74,0x40,0x84,0x40,0x59, -0x24,0x7F,0x38,0x3F,0x00,0x00,0x3F,0x25,0xDA,0x00,0x7F,0x08,0x24,0x7F,0x19,0x3F, -0x00,0x00,0x84,0x20,0x68,0x80,0x64,0x80,0xC9,0x18,0x80,0xC9,0x1C,0x90,0x5A,0x3F, -0x2D,0xDA,0x00,0x77,0x07,0x84,0x01,0x64,0x90,0x5A,0x3F,0x30,0xDA,0x00,0x77,0x0B, -0x28,0x64,0x77,0x05,0x84,0x30,0x68,0x90,0x5A,0x7B,0x15,0xE8,0x0A,0xC9,0x1C,0x40, -0xFF,0x30,0xDA,0x00,0x41,0x9C,0x41,0x40,0x84,0x40,0xC9,0x1C,0x90,0x5A,0x3F,0x30, -0xDA,0x00,0x4B,0x08,0x3F,0x39,0xDA,0x00,0x4F,0xE3,0x3F,0x6F,0x6C,0xDA,0x00,0x7F, -0x09,0x3F,0x6F,0x68,0xDA,0x00,0x77,0x04,0x90,0x5A,0x87,0xDA,0x00,0xE0,0x40,0x24, -0x7F,0xC4,0x3E,0x00,0x00,0x84,0x59,0x40,0x87,0xC0,0x03,0xC9,0x10,0x9C,0x04,0x59, -0x2B,0xC9,0x10,0x7F,0x1F,0x87,0xC9,0x10,0xE0,0x40,0xA0,0x40,0xA0,0x7F,0x18,0x04, -0x00,0x02,0x2C,0xCC,0xF8,0xEF,0x24,0x00,0x00,0x02,0x28,0x40,0x43,0x06,0x84,0x01, -0xC9,0x28,0x24,0x7F,0x17,0x3F,0x00,0x00,0x84,0xD9,0x00,0xC9,0x14,0x9C,0x04,0x59, -0x28,0xC9,0x14,0x77,0x0A,0x84,0x4F,0x08,0x0C,0x00,0x00,0xC9,0x14,0x80,0x6C,0x7B, -0x27,0x90,0x6C,0x84,0xC9,0x14,0x40,0x90,0xC9,0x14,0x87,0x50,0xE0,0x40,0xA0,0x40, -0xA0,0x7F,0x18,0x04,0x00,0x02,0x2C,0xCC,0xF8,0xEF,0x24,0x00,0x00,0x02,0x28,0x40, -0x43,0x06,0x84,0x01,0xC9,0x28,0x2B,0xD9,0x14,0x77,0xD8,0x7B,0x1A,0xA0,0x20,0xA0, -0x7F,0x18,0x04,0x00,0x02,0x2C,0xCC,0xF8,0xEF,0x24,0x00,0x00,0x02,0x28,0x40,0x43, -0x06,0x84,0x01,0xC9,0x28,0x84,0x6C,0x40,0x90,0x6C,0x3C,0xC9,0x1C,0x40,0x4B,0xDF, -0x24,0x7F,0x17,0x3F,0x00,0x00,0x84,0x10,0xC9,0x24,0x7B,0x10,0x84,0x01,0xC9,0x18, -0x84,0x0A,0xC9,0x24,0x7B,0x06,0x84,0x08,0xC9,0x24,0x84,0xD9,0x00,0xC9,0x20,0x9C, -0x04,0x59,0x28,0xC9,0x20,0x77,0x12,0x84,0x01,0x6C,0x87,0x7F,0xF4,0x0B,0x00,0x00, -0xC9,0x2C,0x80,0xC9,0x18,0x7B,0x6C,0x3C,0x01,0xC9,0x18,0x77,0x15,0xD4,0x1F,0xC9, -0x20,0x40,0x7F,0x0E,0x88,0xC9,0x20,0x40,0x90,0x40,0x84,0x40,0xC9,0x20,0x7B,0x05, -0x80,0xC9,0x18,0x80,0x6C,0x7B,0x1F,0x04,0xC9,0x2C,0x40,0x9C,0x6C,0x40,0xE4,0xE0, -0xC9,0x24,0xC9,0x20,0x41,0x87,0x81,0xF4,0x0B,0x00,0x00,0x50,0xAC,0xE0,0xC9,0x24, -0xC9,0x20,0x90,0x6C,0x28,0xC9,0x20,0x7F,0x07,0x3C,0x0C,0x6C,0x4B,0xDB,0x3C,0x0C, -0x6C,0x4B,0x20,0xA0,0x3F,0xA0,0x7F,0x18,0x04,0x00,0x02,0x2C,0xCC,0xF8,0xEF,0x24, -0x00,0x00,0x02,0x28,0x40,0x43,0x06,0x84,0x01,0xC9,0x28,0x24,0x7F,0x17,0x3F,0x00, -0x00,0x28,0x64,0x77,0x73,0x3C,0x01,0xC9,0x18,0x77,0x22,0x94,0xC9,0x1C,0x3C,0x30, -0x68,0x77,0x1A,0xA0,0x2D,0xA0,0x7F,0x18,0x04,0x00,0x02,0x2C,0xCC,0xF8,0xEF,0x24, -0x00,0x00,0x02,0x28,0x40,0x43,0x06,0x84,0x01,0xC9,0x28,0x7B,0x1A,0xA0,0x68,0xA0, -0x7F,0x18,0x04,0x00,0x02,0x2C,0xCC,0xF8,0xEF,0x24,0x00,0x00,0x02,0x28,0x40,0x43, -0x06,0x84,0x01,0xC9,0x28,0x84,0xC9,0x1C,0x40,0x94,0xC9,0x1C,0x3C,0x6C,0x40,0x47, -0xDE,0x3C,0x01,0xC9,0x18,0x77,0x1F,0x3C,0x20,0x68,0x77,0x1A,0xA0,0x2D,0xA0,0x7F, -0x18,0x04,0x00,0x02,0x2C,0xCC,0xF8,0xEF,0x24,0x00,0x00,0x02,0x28,0x40,0x43,0x06, -0x84,0x01,0xC9,0x28,0x7B,0x27,0x3C,0x01,0xC9,0x18,0x77,0x1D,0x94,0xC9,0x1C,0xA0, -0x2D,0xA0,0x7F,0x18,0x04,0x00,0x02,0x2C,0xCC,0xF8,0xEF,0x24,0x00,0x00,0x02,0x28, -0x40,0x43,0x06,0x84,0x01,0xC9,0x28,0xBC,0x6C,0xC9,0x1C,0x7B,0x25,0x04,0xC9,0x2C, -0x40,0x9C,0x6C,0x40,0x87,0x50,0xE0,0x40,0xA0,0x40,0xA0,0x7F,0x18,0x04,0x00,0x02, -0x2C,0xCC,0xF8,0xEF,0x24,0x00,0x00,0x02,0x28,0x40,0x43,0x06,0x84,0x01,0xC9,0x28, -0x94,0x6C,0x43,0xDB,0x3C,0x01,0x64,0x77,0x2C,0x7B,0x1A,0xA0,0x68,0xA0,0x7F,0x18, -0x04,0x00,0x02,0x2C,0xCC,0xF8,0xEF,0x24,0x00,0x00,0x02,0x28,0x40,0x43,0x06,0x84, -0x01,0xC9,0x28,0x84,0xC9,0x1C,0x40,0x94,0xC9,0x1C,0xDC,0x01,0x6C,0x41,0x3C,0x41, -0x40,0x47,0xDA,0x7B,0x74,0x87,0xDA,0x00,0xE0,0x40,0xA0,0x40,0xA0,0x7F,0x18,0x04, -0x00,0x02,0x2C,0xCC,0xF8,0xEF,0x24,0x00,0x00,0x02,0x28,0x40,0x43,0x06,0x84,0x01, -0xC9,0x28,0x7B,0x55,0x3C,0x6F,0x6F,0x40,0x7E,0x5E,0xFE,0x47,0x2F,0x3C,0x6F,0x63, -0x40,0x7E,0xA4,0xFD,0x47,0x1D,0x3C,0x6F,0x4F,0x40,0x7E,0x4C,0xFE,0x47,0x0B,0x3C, -0x6F,0x44,0x40,0x7E,0x39,0xFE,0x7B,0xBF,0x3C,0x6F,0x58,0x40,0x7E,0x2A,0xFE,0x7B, -0xB6,0x3C,0x6F,0x64,0x40,0x7E,0x27,0xFE,0x7B,0xAD,0x3C,0x6F,0x75,0x40,0x7E,0x22, -0xFE,0x47,0x0B,0x3C,0x6F,0x73,0x40,0x7E,0xA1,0xFD,0x7B,0x9B,0x3C,0x6F,0x78,0x40, -0x7E,0x06,0xFE,0x7B,0x92,0x7B,0x90,0x7B,0x1F,0x87,0xDA,0x00,0xE0,0x40,0xA0,0x40, -0xA0,0x7F,0x18,0x04,0x00,0x02,0x2C,0xCC,0xF8,0xEF,0x24,0x00,0x00,0x02,0x28,0x40, -0x43,0x06,0x84,0x01,0xC9,0x28,0x90,0x5A,0x2B,0xDA,0x00,0x76,0xCB,0xFC,0x3C,0x01, -0xC9,0x28,0x77,0x17,0xA0,0x0A,0xA0,0x7F,0x18,0x04,0x00,0x02,0x2C,0xCC,0xF8,0xEF, -0x24,0x00,0x00,0x02,0x84,0xFF,0x40,0x7B,0x07,0x84,0x01,0x40,0x7B,0x02,0x18,0x49, -0x08,0x70,0x70,0x70,0x10,0x49,0x9C,0x4F,0x04,0x00,0x00,0x00,0x4C,0x2B,0xEF,0x10, -0x05,0x00,0x00,0x77,0x19,0x38,0x7F,0x00,0x40,0x04,0x00,0x02,0x7F,0x10,0x80,0xEF, -0x8C,0x04,0x00,0x00,0x80,0x7F,0x44,0x40,0x04,0x00,0x7B,0x00,0x87,0x73,0xE2,0x40, -0x86,0x40,0x62,0x3C,0x7F,0x18,0x04,0x00,0x02,0x74,0x7F,0x08,0x24,0x7F,0x46,0x40, -0x00,0x00,0x84,0x74,0x40,0x3B,0xC0,0x01,0x01,0x77,0x08,0x24,0x7F,0x46,0x40,0x00, -0x00,0x84,0x74,0x40,0x3B,0xC0,0x01,0x5F,0x80,0x00,0x7F,0x33,0x84,0x74,0x40,0x87, -0x6F,0x40,0xC0,0x02,0x84,0x74,0x40,0x87,0x6F,0x50,0xC0,0x02,0x84,0x74,0x40,0x87, -0xC0,0x03,0xE2,0x40,0x86,0x40,0x59,0x84,0x74,0x40,0x3B,0xC0,0x01,0x01,0x77,0xDE, -0x2B,0x7F,0x9D,0x0C,0x00,0x02,0x77,0x05,0x86,0xFF,0x62,0x7B,0x5B,0x84,0x74,0x40, -0x87,0xC0,0x03,0xE2,0x40,0x86,0x40,0x59,0x3E,0x5F,0xFF,0x00,0x59,0x77,0x0F,0x2B, -0x7F,0x9D,0x0C,0x00,0x02,0x77,0x05,0x86,0xFF,0x62,0x7B,0x3C,0x3E,0x13,0x59,0x77, -0x37,0x7B,0x21,0x2B,0xEF,0x10,0x05,0x00,0x00,0x77,0x19,0x38,0x7F,0x00,0x40,0x04, -0x00,0x02,0x7F,0x10,0x80,0xEF,0x8C,0x04,0x00,0x00,0x80,0x7F,0x44,0x40,0x04,0x00, -0x7B,0x00,0x84,0x74,0x40,0x3B,0xC0,0x01,0x01,0x7F,0xDA,0x84,0x74,0x40,0x87,0xC0, -0x03,0xE2,0x40,0x86,0x40,0x59,0x7B,0x21,0x2B,0xEF,0x10,0x05,0x00,0x00,0x77,0x19, -0x38,0x7F,0x00,0x40,0x04,0x00,0x02,0x7F,0x10,0x80,0xEF,0x8C,0x04,0x00,0x00,0x80, -0x7F,0x44,0x40,0x04,0x00,0x7B,0x00,0x84,0x74,0x40,0xFB,0x04,0xC0,0x01,0x40,0x3C, -0x04,0x40,0x77,0xD6,0x3C,0x7F,0x18,0x04,0x00,0x02,0x74,0x77,0x45,0x84,0x74,0x40, -0x87,0x73,0xC0,0x03,0x3F,0x0A,0x73,0x77,0x37,0x7B,0x21,0x2B,0xEF,0x10,0x05,0x00, -0x00,0x77,0x19,0x38,0x7F,0x00,0x40,0x04,0x00,0x02,0x7F,0x10,0x80,0xEF,0x8C,0x04, -0x00,0x00,0x80,0x7F,0x44,0x40,0x04,0x00,0x7B,0x00,0x84,0x74,0x40,0xFB,0x04,0xC0, -0x01,0x40,0x3C,0x04,0x40,0x77,0xD6,0x84,0x74,0x40,0x87,0x0D,0xC0,0x03,0x7B,0x17, -0x3F,0x0A,0x73,0x77,0x0B,0x84,0x74,0x40,0x87,0x0D,0xC0,0x03,0x7B,0x09,0x84,0x74, -0x40,0x87,0x73,0xC0,0x03,0x86,0x62,0xE4,0x40,0x7B,0x02,0x18,0x49,0x08,0x70,0x70, -0x10,0x45,0x9C,0x4F,0x10,0x00,0x00,0x00,0x4C,0x04,0x78,0x40,0x84,0x40,0x6C,0x80, -0x45,0x80,0x47,0x24,0x7F,0x6B,0x43,0x00,0x00,0x7B,0x0E,0x2B,0xDA,0x04,0x77,0x07, -0x84,0x01,0x47,0x7B,0x0A,0x90,0x74,0x3F,0x25,0xDA,0x04,0x77,0xF0,0x28,0x47,0x7F, -0x08,0x24,0x7F,0x71,0x43,0x00,0x00,0x7B,0x04,0x90,0x5A,0x3F,0x20,0xDA,0x00,0x7F, -0xFA,0x3F,0x09,0xDA,0x00,0x7F,0xF4,0x3F,0x2C,0xDA,0x00,0x7F,0xEE,0x3F,0x2D,0xDA, -0x00,0x7F,0xE8,0x3F,0x3D,0xDA,0x00,0x7F,0xE2,0x90,0x74,0x84,0x74,0x40,0x87,0x50, -0xE0,0x40,0x24,0x7F,0x3C,0x43,0x00,0x00,0x84,0x5A,0x48,0x04,0x5A,0x40,0xA0,0x40, -0x2C,0xCC,0xFC,0xAF,0x2C,0x02,0x3C,0x5A,0x48,0x7F,0x22,0x90,0x45,0x7B,0x11,0x84, -0x6C,0x40,0x84,0x48,0x41,0x90,0x48,0x87,0x51,0xD0,0x00,0x90,0xD9,0x0C,0x3C,0x5A, -0x48,0x77,0xEE,0x84,0x6C,0x40,0x83,0xD0,0x00,0x7B,0x05,0x84,0x01,0x47,0x24,0x7F, -0x68,0x43,0x00,0x00,0x2B,0xDA,0x00,0x7F,0x10,0x84,0x6C,0x40,0x87,0xDA,0x00,0xD0, -0x00,0x90,0x5A,0x90,0x45,0x7B,0x05,0x84,0x01,0x47,0x24,0x7F,0x68,0x43,0x00,0x00, -0x80,0x47,0x7B,0x0D,0x04,0x59,0x40,0x9C,0x47,0x40,0x87,0x30,0x50,0x90,0x47,0x3C, -0x08,0x47,0x4B,0xF2,0x84,0x5A,0x48,0x04,0x5A,0x40,0xA0,0x40,0x2C,0xCC,0xFC,0xAF, -0xC0,0x01,0x3C,0x5A,0x48,0x77,0x08,0x24,0x7F,0x66,0x42,0x00,0x00,0x94,0x5A,0x84, -0x07,0x47,0x7B,0x17,0x04,0x59,0x40,0x9C,0x47,0x40,0x87,0xDA,0x00,0x50,0x3C,0x48, -0x5A,0x77,0x04,0x7B,0x0A,0x94,0x5A,0x94,0x47,0x28,0x47,0x43,0xE9,0x04,0x59,0x40, -0xA0,0x40,0xA0,0x07,0xA0,0x6F,0x78,0x2C,0xCC,0xF4,0xAF,0x09,0x02,0x28,0x40,0x77, -0x0B,0x84,0x01,0x47,0x24,0x7F,0x68,0x43,0x00,0x00,0x90,0x45,0x80,0x46,0x84,0x07, -0x47,0x7B,0x25,0x04,0x59,0x40,0xFC,0x47,0x07,0x41,0x9C,0x41,0x40,0x87,0x50,0xE0, -0x40,0xA0,0x40,0x2C,0xCC,0xFC,0xAF,0xA1,0x01,0xD0,0x02,0x47,0x41,0xD0,0x41,0x40, -0x40,0xB0,0x40,0x46,0x94,0x47,0x28,0x47,0x43,0xDB,0x04,0x5A,0x40,0xA0,0x40,0x2C, -0xCC,0xFC,0xAF,0x3D,0x01,0x3F,0x6F,0x78,0xDA,0x04,0x77,0x11,0x84,0x6C,0x40,0x84, -0x46,0x41,0x86,0x41,0x41,0x86,0x41,0xD0,0x00,0x7B,0x09,0x84,0x6C,0x40,0x84,0x46, -0xD0,0x00,0x80,0x47,0x7B,0x05,0x84,0x01,0x47,0x24,0x7F,0x68,0x43,0x00,0x00,0x84, -0x09,0x47,0x7B,0x0D,0x04,0x59,0x40,0x9C,0x47,0x40,0x87,0x30,0x50,0x94,0x47,0x28, -0x47,0x43,0xF3,0x84,0x5A,0x48,0x04,0x5A,0x40,0xA0,0x40,0x2C,0xCC,0xFC,0xAF,0xF1, -0x00,0x3C,0x5A,0x48,0x77,0x08,0x24,0x7F,0x32,0x43,0x00,0x00,0x94,0x5A,0x84,0x09, -0x47,0x7B,0x17,0x04,0x59,0x40,0x9C,0x47,0x40,0x87,0xDA,0x00,0x50,0x3C,0x48,0x5A, -0x77,0x04,0x7B,0x0A,0x94,0x5A,0x94,0x47,0x28,0x47,0x43,0xE9,0x04,0x59,0x40,0xA0, -0x40,0xA0,0x09,0xA0,0x6F,0x64,0x2C,0xCC,0xF4,0xAF,0x3A,0x01,0x28,0x40,0x77,0x0B, -0x84,0x01,0x47,0x24,0x7F,0x68,0x43,0x00,0x00,0x90,0x45,0x80,0x46,0xFF,0x30,0x59, -0x40,0x9C,0x46,0x40,0x84,0x40,0x46,0x84,0x01,0x47,0x7B,0x17,0xA8,0x0A,0x46,0x04, -0x59,0x40,0x9C,0x47,0x40,0xFF,0x30,0x50,0x40,0x9C,0x46,0x40,0x84,0x40,0x46,0x90, -0x47,0x3C,0x0A,0x47,0x4B,0xE8,0x04,0x5A,0x40,0xA0,0x40,0x2C,0xCC,0xFC,0xAF,0x71, -0x00,0x3F,0x6F,0x64,0xDA,0x04,0x77,0x11,0x84,0x6C,0x40,0x84,0x46,0x41,0x86,0x41, -0x41,0x86,0x41,0xD0,0x00,0x7B,0x09,0x84,0x6C,0x40,0x84,0x46,0xD0,0x00,0x80,0x47, -0x7B,0x05,0x84,0x01,0x47,0x7B,0x33,0x84,0x01,0x47,0x7B,0x2E,0x3C,0x40,0x6F,0x44, -0x7E,0x2F,0xFF,0x3C,0x40,0x6F,0x58,0x7E,0x59,0xFE,0x3C,0x40,0x6F,0x63,0x7E,0x36, -0xFE,0x3C,0x40,0x6F,0x64,0x7E,0x1A,0xFF,0x3C,0x40,0x6F,0x73,0x7E,0xEC,0xFD,0x3C, -0x40,0x6F,0x78,0x7E,0x3D,0xFE,0x7B,0xD1,0x9C,0x04,0x6C,0x2B,0xDA,0x04,0x76,0x8B, -0xFD,0x84,0x45,0x40,0x7B,0x02,0x18,0x45,0x08,0x70,0x70,0x70,0x10,0x49,0x9C,0x4F, -0x00,0x00,0x00,0x00,0x4C,0x7B,0x05,0x90,0xDA,0x00,0x84,0x5A,0x40,0x3F,0x20,0xD0, -0x00,0x7F,0x2E,0x84,0x5A,0x40,0x3F,0x09,0xD0,0x00,0x7F,0x25,0x84,0x5A,0x40,0x3F, -0x2D,0xD0,0x00,0x7F,0x1C,0x84,0x5A,0x40,0x3F,0x2C,0xD0,0x00,0x7F,0x13,0x84,0x5A, -0x40,0x2B,0xD0,0x00,0x7F,0x0B,0x84,0x5A,0x40,0x3F,0x3D,0xD0,0x00,0x77,0xCA,0x18, -0x49,0x08,0x70,0x70,0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x3F,0x30,0x73, -0x5B,0x11,0x3F,0x39,0x73,0x57,0x0C,0xFF,0x30,0x73,0x40,0x87,0x40,0xE0,0x40,0x7B, -0x1D,0x3F,0x6F,0x61,0x73,0x5B,0x0D,0xFF,0x6F,0x57,0x73,0x40,0x87,0x40,0xE0,0x40, -0x7B,0x0C,0xFF,0x37,0x73,0x40,0x87,0x40,0xE0,0x40,0x7B,0x02,0x18,0x49,0x08,0x70, -0x10,0x48,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x87,0x7B,0xE0,0x40,0x7B,0x74,0x80, -0x48,0x7B,0x44,0xDC,0x48,0x5A,0x40,0x3F,0x30,0x50,0x4B,0x0B,0xDC,0x48,0x5A,0x40, -0x3F,0x39,0x50,0x4F,0x2A,0xDC,0x48,0x5A,0x40,0x3F,0x6F,0x41,0x50,0x4B,0x0C,0xDC, -0x48,0x5A,0x40,0x3F,0x6F,0x46,0x50,0x4F,0x16,0xDC,0x48,0x5A,0x40,0x3F,0x6F,0x61, -0x50,0x4B,0x0E,0xDC,0x48,0x5A,0x40,0x3F,0x6F,0x66,0x50,0x47,0x04,0x7B,0x06,0x80, -0x40,0x7B,0x41,0x90,0x48,0x3C,0x74,0x48,0x4F,0xBB,0x7B,0x33,0x80,0x48,0x7B,0x1C, -0xDC,0x48,0x5A,0x40,0x3F,0x30,0x50,0x4B,0x0D,0xDC,0x48,0x5A,0x40,0x3F,0x39,0x50, -0x47,0x04,0x7B,0x06,0x80,0x40,0x7B,0x1C,0x90,0x48,0x3C,0x74,0x48,0x4F,0xE3,0x7B, -0x0E,0x3C,0x40,0x6F,0x64,0x7F,0xD7,0x3C,0x40,0x6F,0x78,0x7F,0x84,0x84,0x01,0x40, -0x7B,0x02,0x18,0x48,0x08,0x70,0x70,0x70,0x10,0x49,0x9C,0x4F,0x08,0x00,0x00,0x00, -0x4C,0x87,0x77,0xE0,0x40,0xD0,0x05,0x40,0x40,0x9C,0x7F,0x90,0x04,0x00,0x00,0x40, -0x84,0x40,0x64,0x80,0x59,0x7B,0x11,0x84,0x5A,0x40,0x90,0x5A,0x84,0x64,0x41,0x90, -0x64,0x87,0x51,0x50,0x90,0x59,0x3C,0x20,0x59,0x5B,0xEE,0x18,0x49,0x08,0x70,0x70, -0x10,0x49,0x9C,0x4F,0x54,0x00,0x00,0x00,0x4C,0xA0,0x00,0x2C,0xCC,0xFC,0xAF,0x07, -0x04,0xA0,0x4F,0x28,0x0C,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xB4,0x3B,0x00,0x00,0x28, -0x40,0x43,0x08,0x24,0x7F,0xD7,0x48,0x00,0x00,0xA0,0x4F,0x49,0x0C,0x00,0x00,0x2C, -0xCC,0xFC,0x7F,0xB4,0x3B,0x00,0x00,0x28,0x40,0x43,0x08,0x24,0x7F,0xD7,0x48,0x00, -0x00,0xA0,0x4F,0x64,0x0C,0x00,0x00,0xD4,0x14,0xEF,0xE4,0x04,0x00,0x00,0x40,0xA0, -0x40,0x2C,0xCC,0xF8,0x7F,0xB4,0x3B,0x00,0x00,0x28,0x40,0x43,0x08,0x24,0x7F,0xD7, -0x48,0x00,0x00,0x83,0x59,0x7B,0x4E,0x87,0x59,0xE0,0x40,0xD0,0x02,0x40,0x40,0x9C, -0x7F,0x60,0x05,0x00,0x00,0x40,0x28,0x50,0x7F,0x37,0xA0,0x4F,0x74,0x0C,0x00,0x00, -0x87,0x59,0xE0,0x40,0xA0,0x40,0x87,0x59,0xE0,0x40,0xD0,0x02,0x40,0x40,0x9C,0x7F, -0x60,0x05,0x00,0x00,0x40,0xD4,0x14,0x50,0x40,0xA0,0x40,0x2C,0xCC,0xF4,0x7F,0xB4, -0x3B,0x00,0x00,0x28,0x40,0x43,0x08,0x24,0x7F,0xD7,0x48,0x00,0x00,0x7B,0x04,0x7B, -0x09,0x93,0x59,0x3F,0x04,0x59,0x5B,0xB1,0x83,0x59,0x24,0x7F,0xBF,0x48,0x00,0x00, -0xA0,0x4F,0x8B,0x0C,0x00,0x00,0x87,0x59,0xE0,0x40,0xA0,0x40,0x87,0x59,0xE0,0x40, -0xD0,0x05,0x40,0x40,0x9C,0x7F,0x90,0x04,0x00,0x00,0x40,0x9C,0x0C,0x40,0xA0,0x40, -0x2C,0xCC,0xF4,0x7F,0xB4,0x3B,0x00,0x00,0x28,0x40,0x43,0x08,0x24,0x7F,0xD7,0x48, -0x00,0x00,0xA0,0x4F,0xA9,0x0C,0x00,0x00,0x87,0x59,0xE0,0x40,0xD0,0x05,0x40,0x40, -0x9C,0x7F,0x90,0x04,0x00,0x00,0x40,0xCC,0x03,0x08,0x50,0x40,0xA0,0x40,0x87,0x59, -0xE0,0x40,0xD0,0x05,0x40,0x40,0x9C,0x7F,0x90,0x04,0x00,0x00,0x40,0xCC,0x03,0x0C, -0x50,0x40,0xA0,0x40,0x87,0x59,0xE0,0x40,0xD0,0x05,0x40,0x40,0x9C,0x7F,0x90,0x04, -0x00,0x00,0x40,0x86,0xE2,0x50,0xE0,0x40,0xA0,0x40,0x2C,0xCC,0xF0,0x7F,0xB4,0x3B, -0x00,0x00,0x28,0x40,0x43,0x08,0x24,0x7F,0xD7,0x48,0x00,0x00,0x83,0x61,0x87,0x59, -0xE0,0x40,0xD0,0x05,0x40,0x40,0x9C,0x7F,0x90,0x04,0x00,0x00,0x40,0xCC,0x02,0x0B, -0xC0,0x04,0x40,0x7B,0x71,0x04,0x62,0x40,0xA0,0x40,0xA0,0x4F,0xDA,0x0C,0x00,0x00, -0x2C,0xCC,0xF8,0x7F,0x28,0x70,0x00,0x00,0x87,0x01,0x61,0x7B,0x6C,0x04,0x62,0x40, -0xA0,0x40,0xA0,0x4F,0xEB,0x0C,0x00,0x00,0x2C,0xCC,0xF8,0x7F,0x28,0x70,0x00,0x00, -0x7B,0x57,0x04,0x62,0x40,0xA0,0x40,0xA0,0x4F,0xF8,0x0C,0x00,0x00,0x2C,0xCC,0xF8, -0x7F,0x28,0x70,0x00,0x00,0x7B,0x42,0x04,0x62,0x40,0xA0,0x40,0xA0,0x4F,0x01,0x0D, -0x00,0x00,0x2C,0xCC,0xF8,0x7F,0x28,0x70,0x00,0x00,0x87,0x01,0x61,0x7B,0x2A,0x04, -0x62,0x40,0xA0,0x40,0xA0,0x4F,0x13,0x0D,0x00,0x00,0x2C,0xCC,0xF8,0x7F,0x28,0x70, -0x00,0x00,0x7B,0x15,0x3C,0x03,0x40,0x47,0xE8,0xC0,0x02,0x40,0x40,0x28,0x40,0x4B, -0xE0,0x24,0x90,0x18,0x0C,0x00,0x00,0xA0,0x4F,0x15,0x0D,0x00,0x00,0x04,0x62,0x40, -0xA0,0x40,0x2C,0xCC,0xF8,0x7F,0xB4,0x3B,0x00,0x00,0x28,0x40,0x43,0x08,0x24,0x7F, -0xD7,0x48,0x00,0x00,0x2B,0x61,0x77,0x08,0x24,0x7F,0x8B,0x48,0x00,0x00,0xA0,0x4F, -0x25,0x0D,0x00,0x00,0x87,0x59,0xE0,0x40,0xD0,0x05,0x40,0x40,0x9C,0x7F,0x90,0x04, -0x00,0x00,0x40,0xCC,0x00,0x07,0xC0,0x04,0x40,0x28,0x40,0x7F,0x08,0x84,0x6F,0x79, -0x40,0x7B,0x06,0x84,0x6F,0x6E,0x40,0xA0,0x40,0x87,0x59,0xE0,0x40,0xD0,0x05,0x40, -0x40,0x9C,0x7F,0x90,0x04,0x00,0x00,0x40,0xCC,0x00,0x05,0xC0,0x04,0x40,0x28,0x40, -0x7F,0x0B,0x84,0x4F,0x67,0x0D,0x00,0x00,0x40,0x7B,0x09,0x84,0x4F,0x6E,0x0D,0x00, -0x00,0x40,0xA0,0x40,0x87,0x59,0xE0,0x40,0xD0,0x05,0x40,0x40,0x9C,0x7F,0x90,0x04, -0x00,0x00,0x40,0xCC,0x00,0x06,0xC0,0x04,0x40,0x90,0x40,0xA0,0x40,0x2C,0xCC,0xF0, -0x7F,0xB4,0x3B,0x00,0x00,0x28,0x40,0x43,0x08,0x24,0x7F,0xD7,0x48,0x00,0x00,0xA0, -0x4F,0x75,0x0D,0x00,0x00,0x87,0x59,0xE0,0x40,0xD0,0x05,0x40,0x40,0x9C,0x7F,0x90, -0x04,0x00,0x00,0x40,0x87,0xC0,0x03,0xE0,0x40,0xA0,0x40,0x87,0x59,0xE0,0x40,0xD0, -0x05,0x40,0x40,0x9C,0x7F,0x90,0x04,0x00,0x00,0x40,0x87,0xC0,0x04,0xE0,0x40,0xA0, -0x40,0x2C,0xCC,0xF4,0x7F,0xB4,0x3B,0x00,0x00,0x28,0x40,0x43,0x08,0x24,0x7F,0xD7, -0x48,0x00,0x00,0x87,0x59,0xE0,0x40,0xD0,0x05,0x40,0x40,0x9C,0x7F,0x90,0x04,0x00, -0x00,0x40,0xCC,0x00,0x0A,0xC0,0x04,0x40,0x28,0x40,0x7F,0x1A,0xA0,0x4F,0xA4,0x0D, -0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xB4,0x3B,0x00,0x00,0x28,0x40,0x43,0x08,0x24,0x7F, -0xD7,0x48,0x00,0x00,0x83,0x61,0x24,0x7F,0x6C,0x48,0x00,0x00,0x2B,0x61,0x77,0x1A, -0xA0,0x4F,0xB3,0x0D,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xB4,0x3B,0x00,0x00,0x28,0x40, -0x43,0x08,0x24,0x7F,0xD7,0x48,0x00,0x00,0xA0,0x4F,0xC6,0x0D,0x00,0x00,0x87,0x61, -0xE0,0x40,0xA4,0xE0,0x02,0x40,0x77,0x0B,0x84,0x4F,0xE7,0x0D,0x00,0x00,0x40,0x7B, -0x09,0x84,0x4F,0xEE,0x0D,0x00,0x00,0x40,0xA0,0x40,0x87,0x61,0xE0,0x40,0xA0,0x40, -0x87,0x59,0xE0,0x40,0xD0,0x05,0x40,0x40,0x9C,0x7F,0x90,0x04,0x00,0x00,0x40,0xEB, -0x0C,0x61,0x41,0xDC,0x41,0xC0,0x08,0x40,0x9C,0x02,0x40,0xA0,0x40,0x87,0x59,0xE0, -0x40,0xD0,0x05,0x40,0x40,0x9C,0x7F,0x90,0x04,0x00,0x00,0x40,0xEB,0x0C,0x61,0x41, -0xDC,0x41,0xC0,0x08,0x40,0x86,0xE2,0x50,0xE0,0x40,0xA0,0x40,0x2C,0xCC,0xEC,0x7F, -0xB4,0x3B,0x00,0x00,0x28,0x40,0x43,0x04,0x7B,0x6F,0x93,0x61,0x87,0x61,0xE0,0x40, -0x87,0x59,0xE0,0x41,0xD0,0x05,0x41,0x41,0x9C,0x7F,0x90,0x04,0x00,0x00,0x41,0xCC, -0x03,0x00,0xC1,0x04,0x41,0x3C,0x41,0x40,0x5A,0x54,0xFF,0x87,0x59,0xE0,0x40,0xFF, -0x01,0xEF,0xE0,0x04,0x00,0x00,0x41,0x3C,0x41,0x40,0x53,0x23,0xA0,0x4F,0xF1,0x0D, -0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xB4,0x3B,0x00,0x00,0x28,0x40,0x43,0x04,0x7B,0x29, -0x7B,0x02,0x2C,0x5C,0xEF,0xC8,0x04,0x00,0x00,0x28,0x40,0x7F,0xF7,0x93,0x59,0x3F, -0xEF,0xE0,0x04,0x00,0x00,0x59,0x5A,0xCA,0xFC,0xA0,0x4F,0x0E,0x0E,0x00,0x00,0x2C, -0xCC,0xFC,0x7F,0xB4,0x3B,0x00,0x00,0xA0,0x01,0x2C,0xCC,0xFC,0xAF,0x09,0x00,0x18, -0x49,0x08,0x10,0x49,0x9C,0x4F,0x04,0x00,0x00,0x00,0x4C,0x87,0x73,0x7F,0x9D,0x0C, -0x00,0x02,0x2B,0x73,0x77,0x34,0x7B,0x25,0x84,0x7F,0x18,0x04,0x00,0x02,0x40,0x87, -0x6F,0x40,0xC0,0x02,0x84,0x7F,0x18,0x04,0x00,0x02,0x40,0x87,0x6F,0x50,0xC0,0x02, -0x84,0x7F,0x18,0x04,0x00,0x02,0x40,0x87,0xC0,0x03,0x59,0x84,0x7F,0x18,0x04,0x00, -0x02,0x40,0x3B,0xC0,0x01,0x01,0x77,0xD2,0x18,0x49,0x08,0x70,0x10,0x48,0x9C,0x4F, -0x00,0x00,0x00,0x00,0x4C,0x3C,0x4F,0x00,0x30,0x04,0x00,0x5A,0x5B,0x2D,0x3C,0x4F, -0xFF,0x37,0x04,0x00,0x5A,0x57,0x24,0x86,0xE2,0x7A,0xE0,0x40,0x9C,0x5A,0x40,0x3C, -0x4F,0x00,0x30,0x04,0x00,0x40,0x5B,0x13,0x86,0xE2,0x7A,0xE0,0x40,0x9C,0x5A,0x40, -0x3C,0x4F,0xFF,0x37,0x04,0x00,0x40,0x5F,0x06,0x80,0x40,0x7B,0x6B,0xBC,0x5F,0xFF, -0x0F,0x5A,0xF8,0x4F,0x00,0xF0,0x0F,0x00,0x5A,0x40,0xF8,0x5F,0xFF,0x0F,0x5A,0x41, -0xD0,0x02,0x41,0x41,0x9C,0x41,0x40,0x84,0x40,0x48,0x7B,0x17,0x84,0x74,0x40,0x90, -0x74,0x84,0x48,0x41,0x9C,0x04,0x48,0xFB,0x5F,0xFF,0x00,0xC1,0x03,0x41,0x87,0x41, -0x50,0x86,0x7A,0x40,0x96,0x7A,0x86,0xE2,0x40,0xE0,0x40,0x77,0xE1,0x3C,0x4F,0x01, -0x21,0x04,0x00,0x5A,0x5B,0x07,0x84,0x01,0x40,0x7B,0x1D,0x80,0x7F,0x50,0x12,0x00, -0x02,0xA0,0x7F,0x50,0x12,0x00,0x02,0x37,0x04,0x7B,0x0B,0xA0,0x4A,0xFC,0x0C,0x4C, -0x4A,0x7A,0xBB,0x00,0x7B,0x02,0x18,0x48,0x08,0x70,0x70,0x70,0x10,0x48,0x9C,0x4F, -0x00,0x00,0x00,0x00,0x4C,0x3C,0x4F,0x00,0x30,0x04,0x00,0x74,0x5B,0x2D,0x3C,0x4F, -0xFF,0x37,0x04,0x00,0x74,0x57,0x24,0x86,0xE2,0x7A,0xE0,0x40,0x9C,0x74,0x40,0x3C, -0x4F,0x00,0x30,0x04,0x00,0x40,0x5B,0x13,0x86,0xE2,0x7A,0xE0,0x40,0x9C,0x74,0x40, -0x3C,0x4F,0xFF,0x37,0x04,0x00,0x40,0x5F,0x06,0x80,0x40,0x7B,0x6B,0xBC,0x5F,0xFF, -0x0F,0x74,0xF8,0x4F,0x00,0xF0,0x0F,0x00,0x74,0x40,0xF8,0x5F,0xFF,0x0F,0x74,0x41, -0xD0,0x02,0x41,0x41,0x9C,0x41,0x40,0x84,0x40,0x48,0x7B,0x16,0x84,0x48,0x40,0x9C, -0x04,0x48,0x84,0x5A,0x41,0x90,0x5A,0xFB,0x5F,0xFF,0x00,0x51,0x41,0x84,0x41,0x50, -0x86,0x7A,0x40,0x96,0x7A,0x86,0xE2,0x40,0xE0,0x40,0x77,0xE2,0x3C,0x4F,0x01,0x21, -0x04,0x00,0x74,0x5B,0x07,0x84,0x01,0x40,0x7B,0x1E,0x84,0x01,0x7F,0x50,0x12,0x00, -0x02,0xA0,0x7F,0x50,0x12,0x00,0x02,0x37,0x04,0x7B,0x0B,0xA0,0x4A,0xFC,0x0C,0x4C, -0x4A,0x7A,0x0B,0x00,0x7B,0x02,0x18,0x48,0x08,0x70,0x70,0x70,0x10,0x46,0x9C,0x4F, -0x00,0x00,0x00,0x00,0x4C,0x82,0x48,0x84,0x4F,0x04,0x20,0x04,0x00,0x47,0x84,0x4F, -0x04,0x24,0x04,0x00,0x46,0x7B,0x4A,0x84,0x5F,0xFF,0x00,0x40,0x86,0xE2,0x40,0xE0, -0x40,0x86,0xE2,0xC7,0x02,0xE0,0x41,0xB8,0x41,0x40,0x86,0xE2,0x40,0xE0,0x40,0x86, -0xE2,0x48,0xE0,0x41,0x9C,0x41,0x40,0x86,0x40,0x48,0x86,0xE2,0x48,0xE0,0x40,0xD4, -0x0F,0x40,0x40,0x86,0xE2,0x40,0xE0,0x40,0x86,0xE2,0x48,0xE0,0x41,0xD0,0x01,0x41, -0x41,0x86,0xE2,0x41,0xE0,0x41,0xB0,0x41,0x40,0x86,0x40,0x48,0x9C,0x04,0x47,0x3C, -0x46,0x47,0x5B,0xB5,0x86,0xE2,0x48,0xE0,0x40,0x88,0x40,0x40,0x86,0x40,0x48,0x3F, -0x01,0x73,0x77,0x21,0x86,0xE2,0x48,0xE0,0x40,0xB8,0x5F,0xFF,0x00,0x40,0x84,0x40, -0x57,0x86,0xE2,0x48,0xE0,0x40,0xD4,0x08,0x40,0x40,0xB8,0x5F,0xFF,0x00,0x40,0x84, -0x40,0xC7,0x04,0x86,0xE2,0x48,0xE0,0x40,0x84,0x5F,0xFF,0x00,0x41,0x86,0xE2,0x41, -0xE0,0x41,0x86,0xE2,0xC7,0x02,0xE0,0x42,0xB8,0x42,0x41,0x86,0xE2,0x41,0xE0,0x41, -0xF8,0x5F,0xFF,0x00,0xC7,0x04,0x42,0xD0,0x08,0x42,0x42,0x86,0xE2,0x42,0xE0,0x42, -0xB0,0x42,0x41,0x86,0xE2,0x41,0xE0,0x41,0x3C,0x41,0x40,0x77,0x07,0x84,0x01,0x40, -0x7B,0x06,0x80,0x40,0x7B,0x02,0x18,0x46,0x08,0x70,0x70,0x70,0x84,0x5A,0x40,0x84, -0x74,0x42,0xC4,0x02,0x42,0x42,0x80,0x50,0x94,0x42,0x4F,0x08,0x04,0xC0,0x04,0x41, -0x30,0x19,0x08,0x70,0x84,0x5A,0x40,0x28,0x40,0x77,0x09,0x04,0x7F,0x54,0x12,0x00, -0x02,0x40,0x84,0x43,0x50,0x84,0x44,0xC0,0x04,0x84,0x45,0xC0,0x08,0x84,0x46,0xC0, -0x0C,0x84,0x47,0xC0,0x10,0x84,0x48,0xC0,0x14,0x84,0xCC,0xFC,0xC0,0x18,0x84,0xCC, -0xF8,0xC0,0x1C,0x84,0x4A,0xC0,0x20,0x84,0x49,0xC0,0x24,0x84,0xCD,0x0C,0xC0,0x28, -0x84,0xCD,0x10,0xC0,0x2C,0x80,0x40,0x08,0x84,0x5A,0x40,0x28,0x40,0x77,0x09,0x04, -0x7F,0x54,0x12,0x00,0x02,0x40,0x84,0x50,0x43,0x84,0xC0,0x04,0x44,0x84,0xC0,0x08, -0x45,0x84,0xC0,0x0C,0x46,0x84,0xC0,0x10,0x47,0x84,0xC0,0x14,0x48,0x84,0xC0,0x18, -0x4A,0x84,0xC0,0x1C,0x41,0x84,0xC0,0x20,0x4C,0x84,0xC0,0x24,0x49,0x84,0xC0,0x28, -0xCD,0x0C,0x84,0xC0,0x2C,0xCD,0x10,0x80,0x40,0x90,0x40,0x24,0x51,0x70,0x70,0x70, -0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x87,0x01,0x7F,0x84,0x12,0x00,0x02, -0x2C,0x5C,0xEF,0x88,0x12,0x00,0x02,0x18,0x49,0x08,0x70,0x70,0x10,0x49,0x9C,0x4F, -0x00,0x00,0x00,0x00,0x4C,0x86,0xE2,0x72,0xE0,0x40,0xA0,0x40,0xA0,0x5F,0xFF,0x08, -0x2C,0xCC,0xF8,0xAF,0x10,0x00,0x86,0xE2,0x40,0xE0,0x40,0x7B,0x02,0x18,0x49,0x08, -0x10,0x49,0x9C,0x4F,0x04,0x00,0x00,0x00,0x4C,0x83,0x7F,0x84,0x12,0x00,0x02,0x84, -0xEF,0x94,0x04,0x00,0x00,0x7F,0x88,0x12,0x00,0x02,0x84,0x4F,0x10,0x4C,0x00,0x00, -0xEF,0x94,0x04,0x00,0x00,0xF3,0x30,0x7F,0x4C,0x12,0x00,0x02,0x40,0x87,0x40,0x7F, -0x04,0x90,0x04,0x00,0x7B,0x7C,0x87,0x7F,0x0F,0x90,0x04,0x00,0x59,0x86,0xE2,0x76, -0xE0,0x40,0xD4,0x08,0x40,0x40,0x87,0x40,0x7F,0x06,0x90,0x04,0x00,0xFB,0x5F,0xFF, -0x00,0x77,0x40,0x87,0x40,0x7F,0x07,0x90,0x04,0x00,0x87,0x7F,0x0E,0x90,0x04,0x00, -0x59,0x7B,0x42,0x2B,0xEF,0x10,0x05,0x00,0x00,0x77,0x19,0x38,0x7F,0x00,0x40,0x04, -0x00,0x02,0x7F,0x10,0x80,0xEF,0x8C,0x04,0x00,0x00,0x80,0x7F,0x44,0x40,0x04,0x00, -0x7B,0x00,0x2B,0x7F,0x84,0x12,0x00,0x02,0x7F,0x1B,0x87,0x7F,0x0F,0x90,0x04,0x00, -0x59,0x84,0x7F,0x88,0x12,0x00,0x02,0xEF,0x94,0x04,0x00,0x00,0x86,0xE2,0x72,0xE0, -0x40,0x7B,0x32,0xFB,0x08,0x7F,0x05,0x90,0x04,0x00,0x40,0x3C,0x08,0x40,0x77,0xB5, -0x86,0x72,0x40,0x96,0x72,0x86,0xE2,0x40,0xE0,0x40,0x76,0x7C,0xFF,0x87,0x7F,0x0F, -0x90,0x04,0x00,0x59,0x84,0x7F,0x88,0x12,0x00,0x02,0xEF,0x94,0x04,0x00,0x00,0x80, -0x40,0x7B,0x02,0x18,0x49,0x08,0x70,0x70,0x10,0x49,0x9C,0x4F,0x08,0x00,0x00,0x00, -0x4C,0x28,0x5A,0x77,0x0A,0x80,0x40,0x24,0x7F,0xC3,0x4E,0x00,0x00,0x83,0x65,0xD4, -0x04,0x5A,0x40,0x87,0x40,0x66,0x87,0x66,0xE0,0x40,0x3F,0x0D,0x40,0x77,0x0E,0x87, -0x03,0x65,0xFB,0x0F,0x73,0x40,0x87,0x40,0x66,0x7B,0x09,0x2B,0x66,0x77,0x05,0x87, -0x73,0x66,0x83,0x64,0x84,0xEF,0x94,0x04,0x00,0x00,0x7F,0xA4,0x12,0x00,0x02,0x84, -0x4F,0x26,0x51,0x00,0x00,0xEF,0x94,0x04,0x00,0x00,0x70,0xCC,0x03,0x0D,0x4B,0x7F, -0xA0,0x12,0x00,0x02,0xC8,0x03,0x0D,0x0F,0x4B,0x70,0x84,0x4F,0x94,0x12,0x00,0x02, -0x7F,0x00,0x00,0x00,0x02,0x84,0x4F,0xF4,0x37,0x00,0x02,0x7F,0x94,0x12,0x00,0x02, -0x84,0x4F,0xEC,0x37,0x00,0x02,0x7F,0x98,0x12,0x00,0x02,0x87,0x02,0x7F,0x9C,0x12, -0x00,0x02,0x87,0x02,0x7F,0x9D,0x12,0x00,0x02,0x87,0x0C,0x7F,0x9E,0x12,0x00,0x02, -0x87,0x01,0x7F,0x9F,0x12,0x00,0x02,0xA0,0x4F,0xEC,0x37,0x00,0x02,0xA0,0x5F,0x14, -0x08,0x2C,0xCC,0xF8,0xEF,0x18,0x05,0x00,0x00,0xA0,0x14,0x2C,0xCC,0xFC,0xEF,0x28, -0x05,0x00,0x00,0x2B,0x65,0x77,0x13,0xFF,0x01,0x66,0x40,0xD0,0x15,0x40,0x40,0x87, -0x01,0x80,0x05,0x00,0x20,0x00,0x7B,0x11,0x87,0x66,0xE0,0x40,0xD0,0x1A,0x40,0x40, -0x87,0x01,0x80,0x03,0x00,0x01,0x06,0xA0,0x14,0x2C,0xCC,0xFC,0xEF,0x28,0x05,0x00, -0x00,0x2B,0x65,0x77,0x1C,0xFF,0x01,0x66,0x40,0xD0,0x15,0x40,0x40,0x87,0x80,0x01, -0x00,0x20,0x00,0xE0,0x59,0xA0,0x14,0x2C,0xCC,0xFC,0xEF,0x28,0x05,0x00,0x00,0x2B, -0x65,0x77,0x14,0xFF,0x01,0x66,0x40,0xD0,0x15,0x40,0x40,0x87,0x80,0x03,0x00,0x20, -0x00,0xE0,0x59,0x7B,0x11,0x87,0x66,0xE0,0x40,0xD0,0x1A,0x40,0x40,0x87,0x01,0x80, -0x37,0x00,0x01,0x06,0x80,0x59,0x7B,0x1C,0x3F,0x03,0x7F,0xEF,0x37,0x00,0x02,0x77, -0x07,0x87,0x01,0x64,0x7B,0x14,0xA0,0x01,0x2C,0xCC,0xFC,0xEF,0x28,0x05,0x00,0x00, -0x90,0x59,0x3C,0x6F,0x64,0x59,0x5B,0xE2,0x3C,0x6F,0x64,0x59,0x5B,0x36,0x2B,0x65, -0x77,0x13,0xFF,0x01,0x66,0x40,0xD0,0x15,0x40,0x40,0x87,0x01,0x80,0x05,0x00,0x20, -0x00,0x7B,0x11,0x87,0x66,0xE0,0x40,0xD0,0x1A,0x40,0x40,0x87,0x01,0x80,0x03,0x00, -0x01,0x06,0xA0,0x14,0x2C,0xCC,0xFC,0xEF,0x28,0x05,0x00,0x00,0x87,0x64,0xE0,0x40, -0x7B,0x13,0x2C,0x5C,0xAF,0x2E,0x03,0x28,0x40,0x77,0x04,0x83,0x64,0x87,0x64,0xE0, -0x40,0x7B,0x02,0x18,0x49,0x08,0x70,0x70,0x10,0x49,0x9C,0x4F,0x08,0x00,0x00,0x00, -0x4C,0x87,0x73,0xE0,0x40,0xD0,0x04,0x40,0x40,0x87,0x77,0xE0,0x41,0xB0,0x41,0x40, -0xA0,0x40,0x2C,0xCC,0xFC,0xAF,0x46,0xFE,0x28,0x40,0x77,0x0A,0x80,0x40,0x24,0x7F, -0xA1,0x4F,0x00,0x00,0x84,0xEF,0x94,0x04,0x00,0x00,0x7F,0xA4,0x12,0x00,0x02,0x84, -0x4F,0x26,0x51,0x00,0x00,0xEF,0x94,0x04,0x00,0x00,0x70,0xCC,0x03,0x0D,0x4B,0x7F, -0xA0,0x12,0x00,0x02,0xC8,0x03,0x0D,0x0F,0x4B,0x70,0x87,0x0A,0x7F,0xF7,0x37,0x00, -0x02,0x87,0x77,0x7F,0xF6,0x37,0x00,0x02,0x87,0x5F,0xFF,0x00,0x7F,0xEF,0x37,0x00, -0x02,0x3F,0x0D,0x73,0x77,0x13,0x87,0x77,0xE0,0x40,0xD0,0x1A,0x40,0x40,0x87,0x01, -0x80,0x37,0x00,0x01,0x06,0x7B,0x12,0xFF,0x01,0x73,0x40,0xD0,0x15,0x40,0x40,0x87, -0x80,0x01,0x00,0x20,0x00,0xE0,0x64,0x80,0x64,0x7B,0x2E,0xA0,0x01,0x2C,0xCC,0xFC, -0xEF,0x28,0x05,0x00,0x00,0x3F,0x5F,0xFF,0x00,0x7F,0xEF,0x37,0x00,0x02,0x7F,0x17, -0x2B,0x7F,0xEF,0x37,0x00,0x02,0x77,0x0B,0x84,0x7F,0xF0,0x37,0x00,0x02,0x59,0x7B, -0x0F,0x80,0x59,0x7B,0x0B,0x90,0x64,0x3C,0x5F,0x30,0x75,0x64,0x4B,0xCF,0x2C,0x5C, -0xAF,0x52,0x02,0x3C,0x01,0x40,0x77,0x07,0x84,0x59,0x40,0x7B,0x06,0x80,0x40,0x7B, -0x02,0x18,0x49,0x08,0x10,0x49,0x9C,0x4F,0x08,0x00,0x00,0x00,0x4C,0x70,0xCC,0x03, -0x0D,0x4B,0x7F,0xA0,0x12,0x00,0x02,0xC8,0x03,0x0D,0x0F,0x4B,0x70,0x84,0xEF,0x94, -0x04,0x00,0x00,0x7F,0xA4,0x12,0x00,0x02,0x84,0x4F,0x26,0x51,0x00,0x00,0xEF,0x94, -0x04,0x00,0x00,0x83,0x59,0x84,0x74,0x7F,0x8C,0x12,0x00,0x02,0x84,0x78,0x7F,0x90, -0x12,0x00,0x02,0x3F,0x01,0xCA,0x0F,0x77,0x0B,0x87,0x0C,0x7F,0xF7,0x37,0x00,0x02, -0x7B,0x2D,0x2B,0xCA,0x0F,0x77,0x0B,0x87,0x0B,0x7F,0xF7,0x37,0x00,0x02,0x7B,0x1F, -0x84,0x7F,0xA4,0x12,0x00,0x02,0xEF,0x94,0x04,0x00,0x00,0xC8,0x03,0x0D,0x7F,0xA0, -0x12,0x00,0x02,0x4B,0x70,0x80,0x40,0x24,0x7F,0x21,0x51,0x00,0x00,0x2B,0x73,0x77, -0x1F,0x84,0x7F,0xA4,0x12,0x00,0x02,0xEF,0x94,0x04,0x00,0x00,0xC8,0x03,0x0D,0x7F, -0xA0,0x12,0x00,0x02,0x4B,0x70,0x80,0x40,0x24,0x7F,0x21,0x51,0x00,0x00,0x83,0x63, -0x87,0x73,0xE0,0x40,0xD4,0x04,0x40,0x40,0x87,0x40,0x62,0x87,0x62,0xE0,0x40,0x3F, -0x0D,0x40,0x77,0x0C,0x87,0x03,0x63,0xFB,0x0F,0x73,0x40,0x87,0x40,0x62,0xFB,0x0F, -0x73,0x40,0x87,0x40,0x61,0x87,0x61,0x7F,0xF6,0x37,0x00,0x02,0x84,0x4F,0x8C,0x12, -0x00,0x02,0x7F,0xF8,0x37,0x00,0x02,0x87,0x5F,0xFF,0x00,0x7F,0xEF,0x37,0x00,0x02, -0x2B,0x63,0x77,0x14,0xFF,0x01,0x62,0x40,0xD0,0x15,0x40,0x40,0x87,0x80,0x01,0x00, -0x20,0x00,0xE0,0x64,0x7B,0x11,0x87,0x61,0xE0,0x40,0xD0,0x1A,0x40,0x40,0x87,0x01, -0x80,0x37,0x00,0x01,0x06,0x80,0x64,0x7B,0x2A,0xA0,0x01,0x2C,0xCC,0xFC,0xEF,0x28, -0x05,0x00,0x00,0x3F,0x5F,0xFF,0x00,0x7F,0xEF,0x37,0x00,0x02,0x7F,0x13,0x2B,0x7F, -0xEF,0x37,0x00,0x02,0x77,0x07,0x87,0x01,0x59,0x7B,0x0F,0x83,0x59,0x7B,0x0B,0x90, -0x64,0x3C,0x5F,0x28,0x23,0x64,0x4B,0xD3,0x2C,0x5C,0xAF,0x08,0x01,0x28,0x40,0x7F, -0x06,0x2B,0x59,0x77,0x39,0xA0,0x4F,0x18,0x0E,0x00,0x00,0x2B,0xCA,0x0F,0x77,0x0B, -0x84,0x4F,0x54,0x0E,0x00,0x00,0x40,0x7B,0x09,0x84,0x4F,0x59,0x0E,0x00,0x00,0x40, -0xA0,0x40,0xA0,0x74,0x87,0x61,0xE0,0x40,0xA0,0x40,0x87,0x62,0xE0,0x40,0xA0,0x40, -0x2C,0xCC,0xEC,0x7F,0xB4,0x3B,0x00,0x00,0x80,0x40,0x7B,0x07,0x84,0x01,0x40,0x7B, -0x02,0x18,0x49,0x08,0x70,0x70,0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x2B, -0xEF,0x10,0x05,0x00,0x00,0x77,0x19,0x38,0x7F,0x00,0x40,0x04,0x00,0x02,0x7F,0x10, -0x80,0xEF,0x8C,0x04,0x00,0x00,0x80,0x7F,0x44,0x40,0x04,0x00,0x7B,0x00,0x38,0x7F, -0x00,0x40,0x04,0x00,0x01,0x77,0x3B,0x38,0x7F,0x00,0x40,0x04,0x00,0x6F,0x40,0x77, -0x31,0x38,0x7F,0x00,0x40,0x04,0x00,0x20,0x77,0x28,0x38,0x7F,0x00,0x40,0x04,0x00, -0x08,0x77,0x1F,0x38,0x7F,0x00,0x40,0x04,0x00,0x10,0x77,0x16,0x38,0x7F,0x00,0x40, -0x04,0x00,0x04,0x77,0x0D,0x38,0x7F,0x40,0x40,0x04,0x00,0x5F,0x80,0x00,0x7F,0x47, -0xA0,0x5F,0x80,0x00,0x2C,0xCC,0xFC,0x7F,0x6A,0x56,0x00,0x00,0xA0,0x4F,0x7C,0x0E, -0x00,0x00,0xA0,0x4F,0x5F,0x0E,0x00,0x00,0x2C,0xCC,0xF8,0x7F,0xB4,0x3B,0x00,0x00, -0xA0,0x4F,0x8C,0x0E,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xB4,0x3B,0x00,0x00,0x2C,0x5C, -0x7F,0x7E,0x53,0x00,0x00,0xA0,0x4F,0xEF,0xBE,0xED,0xFE,0x2C,0xCC,0xFC,0x7F,0xFE, -0x58,0x00,0x00,0x7B,0x09,0x84,0x01,0x7F,0xA8,0x12,0x00,0x02,0x18,0x49,0x08,0x70, -0x10,0x49,0x9C,0x4F,0x04,0x00,0x00,0x00,0x4C,0x80,0x7F,0xA8,0x12,0x00,0x02,0x80, -0x59,0x7B,0x2A,0xC8,0x03,0x0D,0x00,0x4B,0x70,0x70,0x70,0x70,0x70,0x70,0xC8,0x03, -0x0D,0x0F,0x4B,0x70,0x3C,0x01,0x7F,0xA8,0x12,0x00,0x02,0x77,0x04,0x7B,0x14,0xA0, -0x01,0x2C,0xCC,0xFC,0xEF,0x28,0x05,0x00,0x00,0x90,0x59,0x3C,0x6F,0x64,0x59,0x4B, -0xD4,0x84,0x7F,0xA4,0x12,0x00,0x02,0xEF,0x94,0x04,0x00,0x00,0xC8,0x03,0x0D,0x7F, -0xA0,0x12,0x00,0x02,0x4B,0x70,0x84,0x7F,0xA8,0x12,0x00,0x02,0x40,0x7B,0x02,0x18, -0x49,0x08,0x70,0x70,0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x2C,0x5C,0xAF, -0x31,0x01,0x87,0x01,0xEF,0xC4,0x04,0x00,0x00,0x38,0x7F,0x98,0x0C,0x00,0x02,0x4F, -0x00,0x00,0x00,0x20,0x7F,0x24,0xA0,0x4F,0x7C,0x0E,0x00,0x00,0xA0,0x4F,0xB0,0x0E, -0x00,0x00,0x2C,0xCC,0xF8,0x7F,0xB4,0x3B,0x00,0x00,0xA0,0x4F,0xC9,0x0E,0x00,0x00, -0x2C,0xCC,0xFC,0x7F,0xB4,0x3B,0x00,0x00,0x38,0x7F,0x98,0x0C,0x00,0x02,0x4F,0x00, -0x00,0x00,0x40,0x7F,0x10,0xA0,0x4F,0x1E,0x0F,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xB4, -0x3B,0x00,0x00,0x38,0x7F,0x98,0x0C,0x00,0x02,0x01,0x7F,0x16,0xA0,0x4F,0x7C,0x0E, -0x00,0x00,0xA0,0x4F,0x4A,0x0F,0x00,0x00,0x2C,0xCC,0xF8,0x7F,0xB4,0x3B,0x00,0x00, -0x38,0x7F,0x98,0x0C,0x00,0x02,0x04,0x7F,0x16,0xA0,0x4F,0x7C,0x0E,0x00,0x00,0xA0, -0x4F,0x69,0x0F,0x00,0x00,0x2C,0xCC,0xF8,0x7F,0xB4,0x3B,0x00,0x00,0x38,0x7F,0x98, -0x0C,0x00,0x02,0x20,0x7F,0x16,0xA0,0x4F,0x7C,0x0E,0x00,0x00,0xA0,0x4F,0x7A,0x0F, -0x00,0x00,0x2C,0xCC,0xF8,0x7F,0xB4,0x3B,0x00,0x00,0x38,0x7F,0x98,0x0C,0x00,0x02, -0x08,0x7F,0x16,0xA0,0x4F,0x7C,0x0E,0x00,0x00,0xA0,0x4F,0x98,0x0F,0x00,0x00,0x2C, -0xCC,0xF8,0x7F,0xB4,0x3B,0x00,0x00,0x28,0x7F,0x98,0x0C,0x00,0x02,0x7F,0x23,0x3C, -0x4F,0x00,0x00,0x00,0x01,0x7F,0x98,0x0C,0x00,0x02,0x53,0x16,0xA0,0x4F,0xB0,0x0F, -0x00,0x00,0xA0,0x4F,0x8C,0x0E,0x00,0x00,0x2C,0xCC,0xF8,0x7F,0xB4,0x3B,0x00,0x00, -0x3C,0x4F,0x00,0x00,0x00,0x80,0x7F,0x98,0x0C,0x00,0x02,0x77,0x1D,0x3C,0x4F,0xEF, -0xBE,0xED,0xFE,0x7F,0xA0,0x03,0x00,0x02,0x7F,0x10,0xA0,0x4F,0xB3,0x0F,0x00,0x00, -0x2C,0xCC,0xFC,0x7F,0xB4,0x3B,0x00,0x00,0x80,0x7F,0x98,0x0C,0x00,0x02,0xA0,0x01, -0x2C,0xCC,0xFC,0xEF,0x28,0x05,0x00,0x00,0x18,0x49,0x08,0x70,0x70,0x70,0x10,0x49, -0x9C,0x4F,0x04,0x00,0x00,0x00,0x4C,0x87,0x01,0x7F,0x0D,0x80,0x04,0x00,0x87,0x7F, -0x00,0xA0,0x04,0x00,0x59,0x87,0x38,0x7F,0x0F,0x10,0x04,0x00,0x87,0x6F,0x74,0x7F, -0x0F,0x10,0x04,0x00,0x84,0x6F,0x64,0x7F,0x00,0x20,0x04,0x00,0x80,0x7F,0x60,0x40, -0x04,0x00,0x80,0x7F,0x64,0x40,0x04,0x00,0x80,0x7F,0x68,0x40,0x04,0x00,0x80,0x7F, -0x70,0x40,0x04,0x00,0x80,0x7F,0x74,0x40,0x04,0x00,0x80,0x7F,0x78,0x40,0x04,0x00, -0x84,0x01,0x7F,0x44,0x40,0x04,0x00,0x80,0x7F,0x5C,0x40,0x04,0x00,0x80,0x7F,0x20, -0x40,0x04,0x00,0x80,0x7F,0x24,0x40,0x04,0x00,0x84,0x01,0x7F,0x2C,0x40,0x04,0x00, -0x80,0x7F,0x30,0x40,0x04,0x00,0x80,0x7F,0x34,0x40,0x04,0x00,0x84,0x01,0x7F,0x38, -0x40,0x04,0x00,0x80,0x7F,0x3C,0x40,0x04,0x00,0x80,0x7F,0x28,0x40,0x04,0x00,0x80, -0x7F,0x6C,0x40,0x04,0x00,0x80,0x7F,0x00,0x40,0x04,0x00,0x80,0x7F,0x04,0x40,0x04, -0x00,0x80,0x7F,0x08,0x40,0x04,0x00,0x80,0x7F,0x0C,0x40,0x04,0x00,0x80,0x7F,0x10, -0x40,0x04,0x00,0x80,0x7F,0x14,0x40,0x04,0x00,0x80,0x7F,0x18,0x40,0x04,0x00,0x84, -0x01,0x7F,0x1C,0x40,0x04,0x00,0x18,0x49,0x08,0x70,0x10,0x49,0x9C,0x4F,0x1C,0x00, -0x00,0x00,0x4C,0xA0,0x4F,0xDF,0x33,0x04,0x00,0x04,0x59,0x40,0xA0,0x40,0xA0,0x04, -0x2C,0xCC,0xF4,0x7F,0x2C,0x49,0x00,0x00,0x3C,0x4F,0xEF,0xBE,0x0D,0x60,0x59,0x7F, -0x08,0x24,0x7F,0xAF,0x55,0x00,0x00,0xA0,0x4F,0xE3,0x33,0x04,0x00,0x04,0x59,0x40, -0xA0,0x40,0xA0,0x04,0x2C,0xCC,0xF4,0x7F,0x2C,0x49,0x00,0x00,0x28,0x59,0x77,0x16, -0xA0,0x4F,0xC1,0x0F,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xB4,0x3B,0x00,0x00,0x24,0x7F, -0x67,0x56,0x00,0x00,0x38,0x59,0x5F,0x00,0x04,0x7F,0x16,0xA0,0x4F,0xC9,0x0F,0x00, -0x00,0x2C,0xCC,0xFC,0x7F,0xB4,0x3B,0x00,0x00,0x24,0x7F,0xAD,0x55,0x00,0x00,0xA0, -0x4F,0xE7,0x33,0x04,0x00,0x04,0x68,0x40,0xA0,0x40,0xA0,0x04,0x2C,0xCC,0xF4,0x7F, -0x2C,0x49,0x00,0x00,0xA0,0x4F,0xEB,0x33,0x04,0x00,0x04,0x64,0x40,0xA0,0x40,0xA0, -0x04,0x2C,0xCC,0xF4,0x7F,0x2C,0x49,0x00,0x00,0xA0,0x4F,0xF3,0x33,0x04,0x00,0x04, -0x6C,0x40,0xA0,0x40,0xA0,0x04,0x2C,0xCC,0xF4,0x7F,0x2C,0x49,0x00,0x00,0xA0,0x4F, -0xF7,0x33,0x04,0x00,0x04,0xC9,0x10,0x40,0xA0,0x40,0xA0,0x04,0x2C,0xCC,0xF4,0x7F, -0x2C,0x49,0x00,0x00,0xA0,0x4F,0xFB,0x33,0x04,0x00,0x04,0xC9,0x14,0x40,0xA0,0x40, -0xA0,0x04,0x2C,0xCC,0xF4,0x7F,0x2C,0x49,0x00,0x00,0xA0,0x4F,0xEF,0x33,0x04,0x00, -0x04,0xC9,0x18,0x40,0xA0,0x40,0xA0,0x04,0x2C,0xCC,0xF4,0x7F,0x2C,0x49,0x00,0x00, -0x38,0x59,0x5F,0x80,0x00,0x7F,0x15,0xA0,0x4F,0xDC,0x0F,0x00,0x00,0xA0,0xC9,0x18, -0x2C,0xCC,0xF8,0x7F,0xB4,0x3B,0x00,0x00,0x7B,0x2D,0x38,0x59,0x6F,0x40,0x7F,0x12, -0xA0,0x4F,0xF3,0x0F,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xB4,0x3B,0x00,0x00,0x7B,0x17, -0x38,0x59,0x5F,0x00,0x01,0x7F,0x10,0xA0,0x4F,0xFF,0x0F,0x00,0x00,0x2C,0xCC,0xFC, -0x7F,0xB4,0x3B,0x00,0x00,0xA0,0x4F,0x07,0x10,0x00,0x00,0xA0,0x64,0xA0,0x68,0xA0, -0x6C,0x2C,0xCC,0xF0,0x7F,0xB4,0x3B,0x00,0x00,0xA0,0x4F,0x2F,0x10,0x00,0x00,0xA0, -0xC9,0x10,0xA0,0xC9,0x14,0x2C,0xCC,0xF4,0x7F,0xB4,0x3B,0x00,0x00,0x7B,0x10,0xA0, -0x4F,0x4B,0x10,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xB4,0x3B,0x00,0x00,0x80,0x59,0x04, -0x59,0x40,0xA0,0x40,0xA0,0x4F,0xE3,0x33,0x04,0x00,0xA0,0x04,0x2C,0xCC,0xF4,0x7F, -0xDC,0x49,0x00,0x00,0x04,0x59,0x40,0xA0,0x40,0xA0,0x4F,0xE7,0x33,0x04,0x00,0xA0, -0x04,0x2C,0xCC,0xF4,0x7F,0xDC,0x49,0x00,0x00,0x04,0x59,0x40,0xA0,0x40,0xA0,0x4F, -0xEB,0x33,0x04,0x00,0xA0,0x04,0x2C,0xCC,0xF4,0x7F,0xDC,0x49,0x00,0x00,0x04,0x59, -0x40,0xA0,0x40,0xA0,0x4F,0xF3,0x33,0x04,0x00,0xA0,0x04,0x2C,0xCC,0xF4,0x7F,0xDC, -0x49,0x00,0x00,0x04,0x59,0x40,0xA0,0x40,0xA0,0x4F,0xF7,0x33,0x04,0x00,0xA0,0x04, -0x2C,0xCC,0xF4,0x7F,0xDC,0x49,0x00,0x00,0x04,0x59,0x40,0xA0,0x40,0xA0,0x4F,0xFB, -0x33,0x04,0x00,0xA0,0x04,0x2C,0xCC,0xF4,0x7F,0xDC,0x49,0x00,0x00,0x04,0x59,0x40, -0xA0,0x40,0xA0,0x4F,0xEF,0x33,0x04,0x00,0xA0,0x04,0x2C,0xCC,0xF4,0x7F,0xDC,0x49, -0x00,0x00,0x04,0x59,0x40,0xA0,0x40,0xA0,0x4F,0xDF,0x33,0x04,0x00,0xA0,0x04,0x2C, -0xCC,0xF4,0x7F,0xDC,0x49,0x00,0x00,0x18,0x49,0x08,0x10,0x49,0x9C,0x4F,0x04,0x00, -0x00,0x00,0x4C,0x84,0x5A,0x7F,0x98,0x0C,0x00,0x02,0xA0,0x4F,0x98,0x0C,0x00,0x02, -0xA0,0x4F,0xE3,0x33,0x04,0x00,0xA0,0x04,0x2C,0xCC,0xF4,0x7F,0xDC,0x49,0x00,0x00, -0x3C,0x5F,0x00,0x04,0x5A,0x77,0x08,0x24,0x7F,0xDC,0x58,0x00,0x00,0xA0,0x4F,0x10, -0x04,0x00,0x02,0xA0,0x4F,0xE7,0x33,0x04,0x00,0xA0,0x04,0x2C,0xCC,0xF4,0x7F,0xDC, -0x49,0x00,0x00,0xA0,0x4F,0x14,0x04,0x00,0x02,0xA0,0x4F,0xEB,0x33,0x04,0x00,0xA0, -0x04,0x2C,0xCC,0xF4,0x7F,0xDC,0x49,0x00,0x00,0x87,0x7F,0x63,0x40,0x04,0x00,0xE0, -0x40,0xD0,0x18,0x40,0x40,0x87,0x7F,0x43,0x40,0x04,0x00,0xE0,0x41,0xD0,0x10,0x41, -0x41,0xB0,0x41,0x40,0x87,0x7F,0x23,0x40,0x04,0x00,0xE0,0x41,0xD0,0x08,0x41,0x41, -0xB0,0x41,0x40,0x87,0x7F,0x03,0x40,0x04,0x00,0xE0,0x41,0xB0,0x41,0x40,0x84,0x40, -0x59,0x04,0x59,0x40,0xA0,0x40,0xA0,0x4F,0xF3,0x33,0x04,0x00,0xA0,0x04,0x2C,0xCC, -0xF4,0x7F,0xDC,0x49,0x00,0x00,0x38,0x7F,0x60,0x40,0x04,0x00,0x08,0x77,0x08,0x24, -0x7F,0xB8,0x58,0x00,0x00,0x3F,0x02,0x7F,0x94,0x0C,0x00,0x02,0x77,0x2C,0xCC,0x03, -0x0D,0x7F,0x00,0xD0,0x04,0x00,0x40,0x3C,0x0F,0x40,0x7F,0x55,0xCC,0x03,0x0D,0x7F, -0x00,0xD0,0x04,0x00,0x40,0x3C,0x0D,0x40,0x7F,0x47,0xCC,0x03,0x0D,0x7F,0x00,0xD0, -0x04,0x00,0x40,0x3C,0x07,0x40,0x7F,0x39,0x3F,0x02,0x7F,0x94,0x0C,0x00,0x02,0x77, -0x08,0x24,0x7F,0x46,0x58,0x00,0x00,0xCC,0x00,0x0F,0x7F,0x00,0xD0,0x04,0x00,0x40, -0x3C,0x01,0x40,0x7F,0x08,0x24,0x7F,0x46,0x58,0x00,0x00,0xCC,0x00,0x0D,0x7F,0x00, -0xD0,0x04,0x00,0x40,0x3C,0x01,0x40,0x7F,0x08,0x24,0x7F,0x46,0x58,0x00,0x00,0x38, -0x7F,0x60,0x40,0x04,0x00,0x01,0x77,0x08,0x24,0x7F,0x42,0x58,0x00,0x00,0x3F,0x02, -0x7F,0x94,0x0C,0x00,0x02,0x77,0x4C,0xCC,0x11,0x00,0x7F,0x00,0xC0,0x04,0x00,0x40, -0xB8,0xFC,0x40,0x84,0x40,0x59,0xCC,0x00,0x12,0x7F,0x00,0xD0,0x04,0x00,0x40,0x28, -0x40,0x7F,0x07,0xB4,0x04,0x59,0x7B,0x12,0xCC,0x00,0x11,0x7F,0x00,0xD0,0x04,0x00, -0x40,0x28,0x40,0x7F,0x05,0xBC,0x04,0x59,0xB8,0x4F,0xFF,0xFF,0x03,0x00,0x59,0xCC, -0x05,0x12,0x7F,0x00,0xC0,0x04,0x00,0x40,0xD0,0x12,0x40,0x40,0xB0,0x40,0x59,0x7B, -0x4A,0xCC,0x11,0x00,0x7F,0x00,0xC0,0x04,0x00,0x40,0xB8,0xFC,0x40,0x84,0x40,0x59, -0xCC,0x00,0x12,0x7F,0x00,0xD0,0x04,0x00,0x40,0x28,0x40,0x7F,0x07,0xB4,0x04,0x59, -0x7B,0x12,0xCC,0x00,0x11,0x7F,0x00,0xD0,0x04,0x00,0x40,0x28,0x40,0x7F,0x05,0xBC, -0x04,0x59,0xB8,0x4F,0xFF,0xFF,0x03,0x00,0x59,0xCC,0x07,0x12,0x7F,0x00,0xC0,0x04, -0x00,0x40,0xD0,0x12,0x40,0x40,0xB0,0x40,0x59,0x9C,0x4F,0x00,0x00,0x00,0x02,0x59, -0x7B,0x04,0x80,0x59,0x7B,0x25,0x3F,0x02,0x7F,0x94,0x0C,0x00,0x02,0x77,0x10,0xCC, -0x17,0x00,0x7F,0x00,0xC0,0x04,0x00,0x40,0x84,0x40,0x59,0x7B,0x0E,0xCC,0x19,0x00, -0x7F,0x00,0xC0,0x04,0x00,0x40,0x84,0x40,0x59,0x04,0x59,0x40,0xA0,0x40,0xA0,0x4F, -0xF7,0x33,0x04,0x00,0xA0,0x04,0x2C,0xCC,0xF4,0x7F,0xDC,0x49,0x00,0x00,0x3F,0x02, -0x7F,0x94,0x0C,0x00,0x02,0x77,0x11,0xF8,0x5F,0x00,0xE0,0x7F,0x00,0xD0,0x04,0x00, -0x40,0x84,0x40,0x59,0x7B,0x0F,0xF8,0x5F,0x00,0xFF,0x7F,0x00,0xD0,0x04,0x00,0x40, -0x84,0x40,0x59,0x04,0x59,0x40,0xA0,0x40,0xA0,0x4F,0xFB,0x33,0x04,0x00,0xA0,0x04, -0x2C,0xCC,0xF4,0x7F,0xDC,0x49,0x00,0x00,0x38,0x5A,0x5F,0x80,0x00,0x7F,0x1F,0x87, -0x7F,0x25,0x04,0x00,0x02,0xE0,0x59,0x04,0x59,0x40,0xA0,0x40,0xA0,0x4F,0xEF,0x33, -0x04,0x00,0xA0,0x04,0x2C,0xCC,0xF4,0x7F,0xDC,0x49,0x00,0x00,0x84,0x4F,0xEF,0xBE, -0x0D,0x60,0x59,0x04,0x59,0x40,0xA0,0x40,0xA0,0x4F,0xDF,0x33,0x04,0x00,0xA0,0x04, -0x2C,0xCC,0xF4,0x7F,0xDC,0x49,0x00,0x00,0x18,0x49,0x08,0x70,0x70,0x70,0x10,0x49, -0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x2B,0xEF,0x10,0x05,0x00,0x00,0x77,0x19,0x38, -0x7F,0x00,0x40,0x04,0x00,0x02,0x7F,0x10,0x80,0xEF,0x8C,0x04,0x00,0x00,0x80,0x7F, -0x44,0x40,0x04,0x00,0x7B,0x00,0x84,0x5A,0xEF,0x8C,0x04,0x00,0x00,0x84,0x01,0x7F, -0x7C,0x40,0x04,0x00,0x7B,0x00,0x18,0x49,0x08,0x70,0x10,0x49,0x9C,0x4F,0x00,0x00, -0x00,0x00,0x4C,0x84,0x4F,0xEF,0xBE,0xED,0xFE,0xEF,0x8C,0x04,0x00,0x00,0x2C,0x5C, -0xAF,0xF6,0xF8,0x84,0x01,0x7F,0x7C,0x40,0x04,0x00,0x7B,0x00,0x18,0x49,0x08,0x70, -0x70,0x70,0x10,0x49,0x9C,0x4F,0x54,0x00,0x00,0x00,0x4C,0xA0,0x4F,0x3B,0x30,0x04, -0x00,0x04,0x59,0x40,0xA0,0x40,0xA0,0x01,0x2C,0xCC,0xF4,0x7F,0x2C,0x49,0x00,0x00, -0x28,0x40,0x77,0x19,0x83,0x59,0x04,0x59,0x40,0xA0,0x40,0xA0,0x4F,0x3B,0x30,0x04, -0x00,0xA0,0x01,0x2C,0xCC,0xF4,0x7F,0xDC,0x49,0x00,0x00,0xA0,0x4F,0x53,0x10,0x00, -0x00,0x2B,0x59,0x7F,0x0B,0x84,0x4F,0x84,0x10,0x00,0x00,0x40,0x7B,0x09,0x84,0x4F, -0x88,0x10,0x00,0x00,0x40,0xA0,0x40,0x2C,0xCC,0xF8,0x7F,0xB4,0x3B,0x00,0x00,0x04, -0x61,0x40,0xA0,0x40,0x2C,0xCC,0xFC,0x7F,0xF0,0x39,0x00,0x00,0x3F,0x6F,0x79,0x61, -0x77,0x1A,0xB7,0x01,0x59,0x04,0x59,0x40,0xA0,0x40,0xA0,0x4F,0x3B,0x30,0x04,0x00, -0xA0,0x01,0x2C,0xCC,0xF4,0x7F,0xDC,0x49,0x00,0x00,0xA0,0x4F,0x8B,0x10,0x00,0x00, -0x2C,0xCC,0xFC,0x7F,0xB4,0x3B,0x00,0x00,0x18,0x49,0x08,0x70,0x32,0xFF,0x4F,0x00, -0x00,0x78,0x32,0xFF,0x4F,0x00,0x01,0x78,0x32,0xFF,0x4F,0x00,0x02,0x78,0x32,0xFF, -0x4F,0x00,0x03,0x78,0x32,0xFF,0x4F,0x00,0x04,0x78,0x32,0xFF,0x4F,0x00,0x05,0x78, -0x32,0xFF,0x4F,0x00,0x06,0x78,0x32,0xFF,0x4F,0x00,0x07,0x78,0x32,0xFF,0x4F,0x00, -0x08,0x78,0x32,0xFF,0x4F,0x00,0x09,0x78,0x32,0xFF,0x4F,0x00,0x0A,0x78,0x32,0xFF, -0x4F,0x00,0x0B,0x78,0x32,0xFF,0x4F,0x00,0x0C,0x78,0x32,0xFF,0x4F,0x00,0x0D,0x78, -0x32,0xFF,0x4F,0x00,0x0E,0x78,0x32,0xFF,0x4F,0x00,0x0F,0x78,0x32,0xFF,0x4F,0x00, -0x10,0x78,0x32,0xFF,0x4F,0x00,0x11,0x78,0x32,0xFF,0x4F,0x00,0x12,0x78,0x32,0xFF, -0x4F,0x00,0x13,0x78,0x32,0xFF,0x4F,0x00,0x14,0x78,0x32,0xFF,0x4F,0x00,0x15,0x78, -0x32,0xFF,0x4F,0x00,0x16,0x78,0x32,0xFF,0x4F,0x00,0x17,0x78,0x32,0xFF,0x4F,0x00, -0x18,0x78,0x32,0xFF,0x4F,0x00,0x19,0x78,0x32,0xFF,0x4F,0x00,0x1A,0x78,0x32,0xFF, -0x4F,0x00,0x1B,0x78,0x32,0xFF,0x4F,0x00,0x1C,0x78,0x32,0xFF,0x4F,0x00,0x1D,0x78, -0x32,0xFF,0x4F,0x00,0x1E,0x78,0x32,0xFF,0x4F,0x00,0x1F,0x78,0x32,0xFF,0x4F,0x00, -0x20,0x78,0x32,0xFF,0x4F,0x00,0x21,0x78,0x32,0xFF,0x4F,0x00,0x22,0x78,0x32,0xFF, -0x4F,0x00,0x23,0x78,0x32,0xFF,0x4F,0x00,0x24,0x78,0x32,0xFF,0x4F,0x00,0x25,0x78, -0x32,0xFF,0x4F,0x00,0x26,0x78,0x32,0xFF,0x4F,0x00,0x27,0x78,0x32,0xFF,0x4F,0x00, -0x28,0x78,0x32,0xFF,0x4F,0x00,0x29,0x78,0x32,0xFF,0x4F,0x00,0x2A,0x78,0x32,0xFF, -0x4F,0x00,0x2B,0x78,0x32,0xFF,0x4F,0x00,0x2C,0x78,0x32,0xFF,0x4F,0x00,0x2D,0x78, -0x32,0xFF,0x4F,0x00,0x2E,0x78,0x32,0xFF,0x4F,0x00,0x2F,0x78,0x32,0xFF,0x4F,0x00, -0x30,0x78,0x32,0xFF,0x4F,0x00,0x31,0x78,0x32,0xFF,0x4F,0x00,0x32,0x78,0x32,0xFF, -0x4F,0x00,0x33,0x78,0x32,0xFF,0x4F,0x00,0x34,0x78,0x32,0xFF,0x4F,0x00,0x35,0x78, -0x32,0xFF,0x4F,0x00,0x36,0x78,0x32,0xFF,0x4F,0x00,0x37,0x78,0x32,0xFF,0x4F,0x00, -0x38,0x78,0x32,0xFF,0x4F,0x00,0x39,0x78,0x32,0xFF,0x4F,0x00,0x3A,0x78,0x32,0xFF, -0x4F,0x00,0x3B,0x78,0x32,0xFF,0x4F,0x00,0x3C,0x78,0x32,0xFF,0x4F,0x00,0x3D,0x78, -0x32,0xFF,0x4F,0x00,0x3E,0x78,0x32,0xFF,0x4F,0x00,0x3F,0x78,0x32,0xFF,0x4F,0x00, -0x40,0x78,0x32,0xFF,0x4F,0x00,0x41,0x78,0x32,0xFF,0x4F,0x00,0x42,0x78,0x32,0xFF, -0x4F,0x00,0x43,0x78,0x32,0xFF,0x4F,0x00,0x44,0x78,0x32,0xFF,0x4F,0x00,0x45,0x78, -0x32,0xFF,0x4F,0x00,0x46,0x78,0x32,0xFF,0x4F,0x00,0x47,0x78,0x32,0xFF,0x4F,0x00, -0x48,0x78,0x32,0xFF,0x4F,0x00,0x49,0x78,0x32,0xFF,0x4F,0x00,0x4A,0x78,0x32,0xFF, -0x4F,0x00,0x4B,0x78,0x32,0xFF,0x4F,0x00,0x4C,0x78,0x32,0xFF,0x4F,0x00,0x4D,0x78, -0x32,0xFF,0x4F,0x00,0x4E,0x78,0x32,0xFF,0x4F,0x00,0x4F,0x78,0x32,0xFF,0x4F,0x00, -0x50,0x78,0x32,0xFF,0x4F,0x00,0x51,0x78,0x32,0xFF,0x4F,0x00,0x52,0x78,0x32,0xFF, -0x4F,0x00,0x53,0x78,0x32,0xFF,0x4F,0x00,0x54,0x78,0x32,0xFF,0x4F,0x00,0x55,0x78, -0x32,0xFF,0x4F,0x00,0x56,0x78,0x32,0xFF,0x4F,0x00,0x57,0x78,0x32,0xFF,0x4F,0x00, -0x58,0x78,0x32,0xFF,0x4F,0x00,0x59,0x78,0x32,0xFF,0x4F,0x00,0x5A,0x78,0x32,0xFF, -0x4F,0x00,0x5B,0x78,0x32,0xFF,0x4F,0x00,0x5C,0x78,0x32,0xFF,0x4F,0x00,0x5D,0x78, -0x32,0xFF,0x4F,0x00,0x5E,0x78,0x32,0xFF,0x4F,0x00,0x5F,0x78,0x32,0xFF,0x4F,0x00, -0x60,0x78,0x32,0xFF,0x4F,0x00,0x61,0x78,0x32,0xFF,0x4F,0x00,0x62,0x78,0x32,0xFF, -0x4F,0x00,0x63,0x78,0x32,0xFF,0x4F,0x00,0x64,0x78,0x32,0xFF,0x4F,0x00,0x65,0x78, -0x32,0xFF,0x4F,0x00,0x66,0x78,0x32,0xFF,0x4F,0x00,0x67,0x78,0x32,0xFF,0x4F,0x00, -0x68,0x78,0x32,0xFF,0x4F,0x00,0x69,0x78,0x32,0xFF,0x4F,0x00,0x6A,0x78,0x32,0xFF, -0x4F,0x00,0x6B,0x78,0x32,0xFF,0x4F,0x00,0x6C,0x78,0x32,0xFF,0x4F,0x00,0x6D,0x78, -0x32,0xFF,0x4F,0x00,0x6E,0x78,0x32,0xFF,0x4F,0x00,0x6F,0x78,0x32,0xFF,0x4F,0x00, -0x70,0x78,0x32,0xFF,0x4F,0x00,0x71,0x78,0x32,0xFF,0x4F,0x00,0x72,0x78,0x32,0xFF, -0x4F,0x00,0x73,0x78,0x32,0xFF,0x4F,0x00,0x74,0x78,0x32,0xFF,0x4F,0x00,0x75,0x78, -0x32,0xFF,0x4F,0x00,0x76,0x78,0x32,0xFF,0x4F,0x00,0x77,0x78,0x32,0xFF,0x4F,0x00, -0x78,0x78,0x32,0xFF,0x4F,0x00,0x79,0x78,0x32,0xFF,0x4F,0x00,0x7A,0x78,0x32,0xFF, -0x4F,0x00,0x7B,0x78,0x32,0xFF,0x4F,0x00,0x7C,0x78,0x32,0xFF,0x4F,0x00,0x7D,0x78, -0x32,0xFF,0x4F,0x00,0x7E,0x78,0x32,0xFF,0x4F,0x00,0x7F,0x78,0x32,0xFF,0x4F,0x00, -0x80,0x78,0x32,0xFF,0x4F,0x00,0x81,0x78,0x32,0xFF,0x4F,0x00,0x82,0x78,0x32,0xFF, -0x4F,0x00,0x83,0x78,0x32,0xFF,0x4F,0x00,0x84,0x78,0x32,0xFF,0x4F,0x00,0x85,0x78, -0x32,0xFF,0x4F,0x00,0x86,0x78,0x32,0xFF,0x4F,0x00,0x87,0x78,0x32,0xFF,0x4F,0x00, -0x88,0x78,0x32,0xFF,0x4F,0x00,0x89,0x78,0x32,0xFF,0x4F,0x00,0x8A,0x78,0x32,0xFF, -0x4F,0x00,0x8B,0x78,0x32,0xFF,0x4F,0x00,0x8C,0x78,0x32,0xFF,0x4F,0x00,0x8D,0x78, -0x32,0xFF,0x4F,0x00,0x8E,0x78,0x32,0xFF,0x4F,0x00,0x8F,0x78,0x32,0xFF,0x4F,0x00, -0x90,0x78,0x32,0xFF,0x4F,0x00,0x91,0x78,0x32,0xFF,0x4F,0x00,0x92,0x78,0x32,0xFF, -0x4F,0x00,0x93,0x78,0x32,0xFF,0x4F,0x00,0x94,0x78,0x32,0xFF,0x4F,0x00,0x95,0x78, -0x32,0xFF,0x4F,0x00,0x96,0x78,0x32,0xFF,0x4F,0x00,0x97,0x78,0x32,0xFF,0x4F,0x00, -0x98,0x78,0x32,0xFF,0x4F,0x00,0x99,0x78,0x32,0xFF,0x4F,0x00,0x9A,0x78,0x32,0xFF, -0x4F,0x00,0x9B,0x78,0x32,0xFF,0x4F,0x00,0x9C,0x78,0x32,0xFF,0x4F,0x00,0x9D,0x78, -0x32,0xFF,0x4F,0x00,0x9E,0x78,0x32,0xFF,0x4F,0x00,0x9F,0x78,0x32,0xFF,0x4F,0x00, -0xA0,0x78,0x32,0xFF,0x4F,0x00,0xA1,0x78,0x32,0xFF,0x4F,0x00,0xA2,0x78,0x32,0xFF, -0x4F,0x00,0xA3,0x78,0x32,0xFF,0x4F,0x00,0xA4,0x78,0x32,0xFF,0x4F,0x00,0xA5,0x78, -0x32,0xFF,0x4F,0x00,0xA6,0x78,0x32,0xFF,0x4F,0x00,0xA7,0x78,0x32,0xFF,0x4F,0x00, -0xA8,0x78,0x32,0xFF,0x4F,0x00,0xA9,0x78,0x32,0xFF,0x4F,0x00,0xAA,0x78,0x32,0xFF, -0x4F,0x00,0xAB,0x78,0x32,0xFF,0x4F,0x00,0xAC,0x78,0x32,0xFF,0x4F,0x00,0xAD,0x78, -0x32,0xFF,0x4F,0x00,0xAE,0x78,0x32,0xFF,0x4F,0x00,0xAF,0x78,0x32,0xFF,0x4F,0x00, -0xB0,0x78,0x32,0xFF,0x4F,0x00,0xB1,0x78,0x32,0xFF,0x4F,0x00,0xB2,0x78,0x32,0xFF, -0x4F,0x00,0xB3,0x78,0x32,0xFF,0x4F,0x00,0xB4,0x78,0x32,0xFF,0x4F,0x00,0xB5,0x78, -0x32,0xFF,0x4F,0x00,0xB6,0x78,0x32,0xFF,0x4F,0x00,0xB7,0x78,0x32,0xFF,0x4F,0x00, -0xB8,0x78,0x32,0xFF,0x4F,0x00,0xB9,0x78,0x32,0xFF,0x4F,0x00,0xBA,0x78,0x32,0xFF, -0x4F,0x00,0xBB,0x78,0x32,0xFF,0x4F,0x00,0xBC,0x78,0x32,0xFF,0x4F,0x00,0xBD,0x78, -0x32,0xFF,0x4F,0x00,0xBE,0x78,0x32,0xFF,0x4F,0x00,0xBF,0x78,0x32,0xFF,0x4F,0x00, -0xC0,0x78,0x32,0xFF,0x4F,0x00,0xC1,0x78,0x32,0xFF,0x4F,0x00,0xC2,0x78,0x32,0xFF, -0x4F,0x00,0xC3,0x78,0x32,0xFF,0x4F,0x00,0xC4,0x78,0x32,0xFF,0x4F,0x00,0xC5,0x78, -0x32,0xFF,0x4F,0x00,0xC6,0x78,0x32,0xFF,0x4F,0x00,0xC7,0x78,0x32,0xFF,0x4F,0x00, -0xC8,0x78,0x32,0xFF,0x4F,0x00,0xC9,0x78,0x32,0xFF,0x4F,0x00,0xCA,0x78,0x32,0xFF, -0x4F,0x00,0xCB,0x78,0x32,0xFF,0x4F,0x00,0xCC,0x78,0x32,0xFF,0x4F,0x00,0xCD,0x78, -0x32,0xFF,0x4F,0x00,0xCE,0x78,0x32,0xFF,0x4F,0x00,0xCF,0x78,0x32,0xFF,0x4F,0x00, -0xD0,0x78,0x32,0xFF,0x4F,0x00,0xD1,0x78,0x32,0xFF,0x4F,0x00,0xD2,0x78,0x32,0xFF, -0x4F,0x00,0xD3,0x78,0x32,0xFF,0x4F,0x00,0xD4,0x78,0x32,0xFF,0x4F,0x00,0xD5,0x78, -0x32,0xFF,0x4F,0x00,0xD6,0x78,0x32,0xFF,0x4F,0x00,0xD7,0x78,0x32,0xFF,0x4F,0x00, -0xD8,0x78,0x32,0xFF,0x4F,0x00,0xD9,0x78,0x32,0xFF,0x4F,0x00,0xDA,0x78,0x32,0xFF, -0x4F,0x00,0xDB,0x78,0x32,0xFF,0x4F,0x00,0xDC,0x78,0x32,0xFF,0x4F,0x00,0xDD,0x78, -0x32,0xFF,0x4F,0x00,0xDE,0x78,0x32,0xFF,0x4F,0x00,0xDF,0x78,0x32,0xFF,0x4F,0x00, -0xE0,0x78,0x32,0xFF,0x4F,0x00,0xE1,0x78,0x32,0xFF,0x4F,0x00,0xE2,0x78,0x32,0xFF, -0x4F,0x00,0xE3,0x78,0x32,0xFF,0x4F,0x00,0xE4,0x78,0x32,0xFF,0x4F,0x00,0xE5,0x78, -0x32,0xFF,0x4F,0x00,0xE6,0x78,0x32,0xFF,0x4F,0x00,0xE7,0x78,0x32,0xFF,0x4F,0x00, -0xE8,0x78,0x32,0xFF,0x4F,0x00,0xE9,0x78,0x32,0xFF,0x4F,0x00,0xEA,0x78,0x32,0xFF, -0x4F,0x00,0xEB,0x78,0x32,0xFF,0x4F,0x00,0xEC,0x78,0x32,0xFF,0x4F,0x00,0xED,0x78, -0x32,0xFF,0x4F,0x00,0xEE,0x78,0x32,0xFF,0x4F,0x00,0xEF,0x78,0x32,0xFF,0x4F,0x00, -0xF0,0x78,0x32,0xFF,0x4F,0x00,0xF1,0x78,0x32,0xFF,0x4F,0x00,0xF2,0x78,0x32,0xFF, -0x4F,0x00,0xF3,0x78,0x32,0xFF,0x4F,0x00,0xF4,0x78,0x32,0xFF,0x4F,0x00,0xF5,0x78, -0x32,0xFF,0x4F,0x00,0xF6,0x78,0x32,0xFF,0x4F,0x00,0xF7,0x78,0x32,0xFF,0x4F,0x00, -0xF8,0x78,0x32,0xFF,0x4F,0x00,0xF9,0x78,0x32,0xFF,0x4F,0x00,0xFA,0x78,0x32,0xFF, -0x4F,0x00,0xFB,0x78,0x32,0xFF,0x4F,0x00,0xFC,0x78,0x32,0xFF,0x4F,0x00,0xFD,0x78, -0x32,0xFF,0x4F,0x00,0xFE,0x78,0x32,0xFF,0x4F,0x00,0xFF,0x78,0x10,0x49,0x9C,0x4F, -0x10,0x00,0x00,0x00,0x4C,0x2C,0x5C,0x7F,0x2C,0x24,0x00,0x00,0x84,0x40,0x59,0x3C, -0x4F,0x00,0x00,0x00,0x01,0x59,0x5F,0x2D,0xFB,0x10,0x7F,0x94,0x0C,0x00,0x02,0x40, -0x3C,0x10,0x40,0x7F,0x20,0xA0,0x4F,0x90,0x10,0x00,0x00,0xD4,0x14,0x59,0x40,0xA0, -0x40,0xA0,0x10,0x2C,0xCC,0xF4,0x7F,0xB4,0x3B,0x00,0x00,0x80,0x40,0x24,0x7F,0x1A, -0x64,0x00,0x00,0x3B,0x7F,0x94,0x0C,0x00,0x02,0x10,0x77,0x2E,0x3C,0x4F,0x00,0x00, -0x00,0x01,0x59,0x77,0x25,0xCC,0x00,0x02,0x7F,0x04,0xD0,0x04,0x00,0x40,0x28,0x40, -0x77,0x18,0xA0,0x4F,0xEA,0x10,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xB4,0x3B,0x00,0x00, -0x80,0x40,0x24,0x7F,0x1A,0x64,0x00,0x00,0x83,0x6E,0x82,0x6C,0x87,0x01,0x69,0x7B, -0x4A,0x87,0x69,0xE0,0x40,0xD0,0x02,0x40,0x40,0xCC,0x00,0x02,0x80,0x00,0xD0,0x04, -0x00,0x40,0x28,0x40,0x77,0x07,0x87,0x01,0x6E,0x7B,0x0E,0x3F,0x01,0x6E,0x77,0x09, -0x87,0x69,0xE2,0x40,0x86,0x40,0x6C,0x2A,0x6C,0x7F,0x1E,0xA0,0x4F,0x25,0x11,0x00, -0x00,0x86,0x6C,0xE4,0x40,0xA0,0x40,0x2C,0xCC,0xF8,0x7F,0xB4,0x3B,0x00,0x00,0x80, -0x40,0x24,0x7F,0x1A,0x64,0x00,0x00,0x93,0x69,0x3F,0x04,0x69,0x5B,0xB5,0x80,0x59, -0x82,0x6C,0x7B,0x1C,0x86,0x6C,0xE4,0x40,0xD0,0x05,0x40,0x40,0x9C,0x7F,0x90,0x04, -0x00,0x00,0x40,0xCC,0x03,0x00,0xC0,0x04,0x40,0x9C,0x40,0x59,0x92,0x6C,0x86,0x6C, -0xE4,0x40,0x87,0xEF,0xE0,0x04,0x00,0x00,0xE0,0x41,0x3C,0x41,0x40,0x4B,0xD7,0x87, -0xEF,0xE0,0x04,0x00,0x00,0xE0,0x40,0xD0,0x05,0x40,0x40,0x9C,0x7F,0x90,0x04,0x00, -0x00,0x40,0xE8,0x0C,0x59,0x41,0x9C,0x41,0x40,0x84,0x40,0xEF,0xE8,0x04,0x00,0x00, -0xFC,0x5F,0x94,0x30,0xEF,0xE4,0x04,0x00,0x00,0x40,0xD4,0x02,0x40,0x40,0x84,0x40, -0x59,0x80,0x7F,0x94,0x30,0x00,0x02,0xFC,0x01,0x59,0x40,0xA0,0x40,0xA0,0x4F,0x98, -0x30,0x00,0x02,0xA0,0x4F,0x94,0x30,0x00,0x02,0x2C,0xCC,0xF4,0x7F,0x54,0x37,0x00, -0x00,0x2C,0x5C,0x7F,0x7E,0x53,0x00,0x00,0xA0,0x00,0x2C,0xCC,0xFC,0xEF,0x40,0x05, -0x00,0x00,0x84,0x4F,0xEF,0xBE,0xED,0xFE,0x7F,0xA0,0x03,0x00,0x02,0x3F,0x01,0xEF, -0xA0,0x04,0x00,0x00,0x77,0x0A,0x2B,0x7F,0xE8,0x11,0x00,0x00,0x77,0x26,0x84,0x4F, -0x1E,0x64,0x00,0x00,0x7F,0xA4,0x03,0x00,0x02,0x84,0x4F,0x66,0x64,0x00,0x00,0x7F, -0x20,0x04,0x00,0x02,0x84,0x7F,0x20,0x04,0x00,0x02,0x40,0x84,0x40,0x7F,0xA8,0x03, -0x00,0x02,0x84,0x7F,0xA0,0x04,0x00,0x00,0x40,0x2B,0xC0,0x01,0x77,0x36,0xA0,0x00, -0xA0,0x4F,0x00,0x40,0x00,0x02,0xA0,0x00,0xA0,0x00,0x2C,0xCC,0xF0,0x7F,0x2C,0x65, -0x00,0x00,0x28,0x40,0x77,0x11,0x2C,0x5C,0x7F,0x48,0x68,0x00,0x00,0x80,0x40,0x24, -0x7F,0x1A,0x64,0x00,0x00,0x84,0x4F,0x00,0x40,0x00,0x02,0x64,0x24,0x7F,0x5F,0x63, -0x00,0x00,0x84,0x7F,0xA0,0x04,0x00,0x00,0x40,0x3F,0x07,0xC0,0x01,0x77,0x2B,0xA0, -0x00,0xA0,0x4F,0x00,0x40,0x00,0x02,0xA0,0x00,0x2C,0xCC,0xF4,0xAF,0xB5,0x02,0x28, -0x40,0x77,0x0A,0x80,0x40,0x24,0x7F,0x1A,0x64,0x00,0x00,0x84,0x4F,0x00,0x40,0x00, -0x02,0x64,0x24,0x7F,0x5F,0x63,0x00,0x00,0x83,0x6A,0x84,0x7F,0xA0,0x04,0x00,0x00, -0x40,0x87,0xC0,0x01,0xE0,0x40,0xD4,0x04,0x40,0x40,0x87,0x40,0x69,0x87,0x69,0xE0, -0x40,0x3F,0x0D,0x40,0x77,0x14,0x87,0x03,0x6A,0x84,0x7F,0xA0,0x04,0x00,0x00,0x40, -0xFB,0x0F,0xC0,0x01,0x40,0x87,0x40,0x69,0x86,0x01,0x6C,0x7B,0x41,0x86,0x6C,0xE4, -0x40,0xD0,0x05,0x40,0x40,0x9C,0x7F,0x90,0x04,0x00,0x00,0x40,0xCC,0x02,0x0B,0xC0, -0x04,0x40,0x87,0x6A,0xE0,0x41,0x3C,0x41,0x40,0x77,0x21,0x86,0x6C,0xE4,0x40,0xD0, -0x05,0x40,0x40,0x9C,0x7F,0x90,0x04,0x00,0x00,0x40,0xCC,0x03,0x0C,0x50,0x40,0x87, -0x69,0xE0,0x41,0x3C,0x41,0x40,0x77,0x04,0x7B,0x15,0x92,0x6C,0x86,0x6C,0xE4,0x40, -0x87,0xEF,0xE0,0x04,0x00,0x00,0xE0,0x41,0x3C,0x41,0x40,0x4B,0xB2,0x86,0x6C,0xE4, -0x40,0x87,0xEF,0xE0,0x04,0x00,0x00,0xE0,0x41,0x3C,0x41,0x40,0x4B,0x34,0xA0,0x4F, -0x4C,0x11,0x00,0x00,0x2B,0x6A,0x77,0x0B,0x84,0x4F,0x7A,0x11,0x00,0x00,0x40,0x7B, -0x09,0x84,0x4F,0x82,0x11,0x00,0x00,0x40,0xA0,0x40,0x87,0x69,0xE0,0x40,0xA0,0x40, -0x2C,0xCC,0xF4,0x7F,0xB4,0x3B,0x00,0x00,0x80,0x40,0x24,0x7F,0x1A,0x64,0x00,0x00, -0x84,0x7F,0xA0,0x04,0x00,0x00,0x40,0xFB,0x0F,0xC0,0x01,0x40,0x87,0x40,0x68,0x82, -0x6C,0x7B,0x39,0x84,0x7F,0xA0,0x04,0x00,0x00,0x40,0x87,0xC0,0x01,0xE0,0x40,0xD4, -0x04,0x40,0x40,0xA0,0x40,0x87,0x68,0xE0,0x40,0xA0,0x40,0x2C,0xCC,0xF8,0x7F,0xC8, -0x4E,0x00,0x00,0x84,0x40,0x64,0x28,0x64,0x7F,0x04,0x7B,0x15,0xA0,0x5F,0xF4,0x01, -0x2C,0xCC,0xFC,0xEF,0x28,0x05,0x00,0x00,0x92,0x6C,0x3E,0x08,0x6C,0x4B,0xC6,0x28, -0x64,0x77,0x2E,0x3F,0x03,0x6A,0x77,0x13,0x87,0x69,0xE0,0x40,0xD0,0x1A,0x40,0x40, -0x87,0x01,0x80,0x03,0x00,0x01,0x06,0x7B,0x10,0xFF,0x01,0x69,0x40,0xD0,0x15,0x40, -0x40,0x83,0x80,0x05,0x00,0x20,0x00,0x80,0x40,0x24,0x7F,0x1A,0x64,0x00,0x00,0x84, -0x64,0x40,0x3C,0xC0,0x04,0xD9,0x04,0x77,0x1E,0x84,0x64,0x40,0x84,0x64,0x41,0x3C, -0xC1,0x08,0xC0,0x04,0x77,0x11,0x84,0x64,0x40,0x84,0x64,0x41,0x3C,0xC1,0x0C,0xC0, -0x08,0x77,0x04,0x7B,0x14,0xA0,0x00,0x2C,0xCC,0xFC,0xEF,0x1C,0x05,0x00,0x00,0x28, -0x40,0x77,0x06,0x2C,0x5C,0xD9,0x04,0xA0,0x01,0x2C,0xCC,0xFC,0xEF,0x40,0x05,0x00, -0x00,0x84,0x7F,0xA0,0x04,0x00,0x00,0x40,0x2B,0xC0,0x01,0x77,0x0B,0x2C,0x5C,0x7F, -0x48,0x68,0x00,0x00,0x7B,0x33,0x84,0x7F,0xA0,0x04,0x00,0x00,0x40,0x3F,0x07,0xC0, -0x01,0x7F,0x26,0x3F,0x03,0x6A,0x77,0x13,0x87,0x69,0xE0,0x40,0xD0,0x1A,0x40,0x40, -0x87,0x01,0x80,0x03,0x00,0x01,0x06,0x7B,0x10,0xFF,0x01,0x69,0x40,0xD0,0x15,0x40, -0x40,0x83,0x80,0x05,0x00,0x20,0x00,0x3C,0x4F,0xEF,0xBE,0xED,0xFE,0x7F,0xA0,0x03, -0x00,0x02,0x77,0x06,0x80,0x40,0x7B,0x24,0x3F,0x01,0xEF,0xA0,0x04,0x00,0x00,0x77, -0x16,0x3F,0x01,0x7F,0xE8,0x11,0x00,0x00,0x77,0x0D,0x84,0x4F,0xED,0x0D,0x1C,0xA1, -0x7F,0xA0,0x03,0x00,0x02,0x84,0x01,0x40,0x7B,0x02,0x18,0x49,0x08,0x70,0x10,0x49, -0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0xA0,0x4F,0x7C,0x0E,0x00,0x00,0xA0,0x4F,0x88, -0x11,0x00,0x00,0x2C,0xCC,0xF8,0x7F,0xB4,0x3B,0x00,0x00,0xA0,0x4F,0x8C,0x0E,0x00, -0x00,0x2C,0xCC,0xFC,0x7F,0xB4,0x3B,0x00,0x00,0xA0,0x5F,0x80,0x00,0x2C,0xCC,0xFC, -0x7F,0x6A,0x56,0x00,0x00,0xA0,0x4F,0xEF,0xBE,0xED,0xFE,0x2C,0xCC,0xFC,0x7F,0xFE, -0x58,0x00,0x00,0x18,0x49,0x08,0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0xA0, -0x4F,0x7C,0x0E,0x00,0x00,0xA0,0x4F,0xA2,0x11,0x00,0x00,0x2C,0xCC,0xF8,0x7F,0xB4, -0x3B,0x00,0x00,0xA0,0x4F,0x8C,0x0E,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xB4,0x3B,0x00, -0x00,0xA0,0x6F,0x40,0x2C,0xCC,0xFC,0x7F,0x6A,0x56,0x00,0x00,0xA0,0x4F,0xEF,0xBE, -0xED,0xFE,0x2C,0xCC,0xFC,0x7F,0xFE,0x58,0x00,0x00,0x18,0x49,0x08,0x70,0x10,0x49, -0x9C,0x4F,0x0C,0x00,0x00,0x00,0x4C,0x28,0x7F,0x3C,0x04,0x00,0x02,0x77,0x06,0x80, -0x40,0x7B,0x67,0x3F,0x01,0x7B,0x77,0x22,0x84,0x74,0x59,0xDC,0x4F,0x00,0x00,0x00, -0x02,0xEF,0xE4,0x04,0x00,0x00,0x40,0x86,0xE2,0x72,0xE0,0x41,0xD0,0x09,0x41,0x41, -0x9C,0x41,0x40,0x84,0x40,0x64,0x7B,0x20,0xDC,0x4F,0x00,0x00,0x00,0x02,0xEF,0xE4, -0x04,0x00,0x00,0x40,0x86,0xE2,0x72,0xE0,0x41,0xD0,0x09,0x41,0x41,0x9C,0x41,0x40, -0x84,0x40,0x59,0x84,0x74,0x64,0xDC,0x5F,0x00,0x02,0x64,0x40,0x84,0x40,0x68,0x7B, -0x0F,0x84,0x64,0x40,0x90,0x64,0x84,0x59,0x41,0x90,0x59,0x87,0x51,0x50,0x3C,0x68, -0x64,0x5B,0xF0,0x84,0x01,0x40,0x7B,0x02,0x18,0x49,0x08,0x70,0x10,0x49,0x9C,0x4F, -0x0C,0x00,0x00,0x00,0x4C,0x86,0x01,0x62,0xEC,0xE0,0x12,0x5A,0x40,0x3C,0x6F,0x50, -0x40,0x5B,0x06,0x82,0x62,0x7B,0x72,0x2B,0xCA,0x0F,0x7F,0x08,0x3F,0x03,0xCA,0x0F, -0x77,0x67,0x83,0x7F,0xAD,0x12,0x00,0x02,0xA0,0x01,0x2C,0xCC,0xFC,0x7F,0xA8,0x67, -0x00,0x00,0x28,0x40,0x77,0x06,0x82,0x62,0x7B,0x4F,0xA0,0x5F,0x8E,0x05,0xA0,0x4F, -0xA0,0x0C,0x00,0x02,0xA0,0x00,0xA0,0x01,0x2C,0xCC,0xF0,0xCF,0xB4,0x28,0x40,0x77, -0x06,0x82,0x62,0x7B,0x34,0x3C,0x4F,0x0D,0x60,0x5E,0xCA,0x7F,0xA4,0x0C,0x00,0x02, -0x77,0x27,0xA0,0x7F,0xDC,0x0C,0x00,0x02,0xA0,0x4F,0xA0,0x0C,0x00,0x02,0xA0,0x00, -0xA0,0x01,0x2C,0xCC,0xF0,0xAF,0x8A,0xFF,0x28,0x40,0x77,0x06,0x82,0x62,0x7B,0x09, -0x87,0x01,0x7F,0xAD,0x12,0x00,0x02,0x2A,0x62,0x77,0x23,0x3F,0x02,0xCA,0x0F,0x7F, -0x08,0x3F,0x03,0xCA,0x0F,0x77,0x17,0x83,0x7F,0xAD,0x12,0x00,0x02,0x2C,0x5C,0x7F, -0x48,0x68,0x00,0x00,0x80,0x40,0x24,0x7F,0x13,0x67,0x00,0x00,0x83,0x68,0xEC,0xE0, -0x12,0x5A,0x40,0x87,0x40,0x69,0xE4,0xE0,0x12,0x5A,0x40,0xAC,0xE0,0x09,0x40,0x87, -0x40,0x6A,0xE4,0xE0,0x09,0x5A,0x40,0x87,0x40,0x6B,0x2B,0x7F,0xAD,0x12,0x00,0x02, -0x7F,0x13,0x04,0x68,0x40,0xA0,0x40,0xA0,0x4F,0xA0,0x0C,0x00,0x02,0x2C,0xCC,0xF8, -0xAF,0x3F,0x01,0x87,0x5F,0x9C,0x00,0x66,0x3F,0x01,0x7B,0x77,0x10,0x87,0x08,0x64, -0x87,0x5F,0xA0,0x00,0x65,0xB3,0x6F,0x40,0x66,0x7B,0x0A,0x87,0x04,0x64,0x87,0x5F, -0x80,0x00,0x65,0xB3,0x08,0x65,0x8B,0x6A,0x40,0x84,0x40,0x7F,0x4C,0x40,0x04,0x00, -0x82,0x62,0x82,0x59,0x24,0x7F,0xD4,0x66,0x00,0x00,0x87,0x69,0xE0,0x40,0xA0,0x40, -0x2C,0xCC,0xFC,0xAF,0xC6,0x00,0x28,0x40,0x77,0x14,0xA0,0x01,0x2C,0xCC,0xFC,0x7F, -0xA8,0x67,0x00,0x00,0x28,0x40,0x77,0x04,0x7B,0x72,0x7B,0x68,0xDF,0x01,0x6B,0x40, -0x87,0x40,0x7F,0x02,0xA0,0x04,0x00,0xA0,0x74,0x87,0x64,0xE0,0x40,0xA0,0x40,0xA0, -0x5F,0x00,0x02,0x2C,0xCC,0xF4,0x7F,0x2C,0x69,0x00,0x00,0x28,0x40,0x77,0x04,0x7B, -0x4B,0x83,0x7F,0xAC,0x12,0x00,0x02,0x87,0x65,0xE0,0x40,0xA0,0x40,0x87,0x66,0xE0, -0x40,0xA0,0x40,0x2C,0xCC,0xF8,0x7F,0x64,0x68,0x00,0x00,0x3C,0x01,0x40,0x77,0x07, -0x86,0x01,0x62,0x7B,0x27,0x3B,0x7F,0x00,0xA0,0x04,0x00,0x5F,0x80,0x00,0x7F,0x04, -0x7B,0x1A,0xA0,0x01,0x2C,0xCC,0xFC,0x7F,0xA8,0x67,0x00,0x00,0x28,0x40,0x77,0x04, -0x7B,0x0A,0x92,0x59,0x3E,0x10,0x59,0x4A,0x73,0xFF,0x2B,0x7F,0xAC,0x12,0x00,0x02, -0x7F,0x14,0xA0,0x4F,0xB8,0x11,0x00,0x00,0xA0,0x68,0xA0,0x10,0x2C,0xCC,0xF4,0xEF, -0xB0,0x04,0x00,0x00,0x3F,0x02,0xCA,0x0F,0x7F,0x08,0x3F,0x03,0xCA,0x0F,0x77,0x0F, -0x83,0x7F,0xAD,0x12,0x00,0x02,0x2C,0x5C,0x7F,0x48,0x68,0x00,0x00,0x86,0x62,0xE4, -0x40,0x7B,0x02,0x18,0x49,0x08,0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x3F, -0x73,0x7F,0x01,0xA0,0x04,0x00,0x77,0x07,0x84,0x01,0x40,0x7B,0x1C,0x87,0x73,0x7F, -0x03,0xA0,0x04,0x00,0xA0,0x1C,0xA0,0x10,0x2C,0xCC,0xF8,0x7F,0x64,0x68,0x00,0x00, -0x86,0xE2,0x40,0xE0,0x40,0x7B,0x02,0x18,0x49,0x08,0x70,0x70,0x10,0x49,0x9C,0x4F, -0x04,0x00,0x00,0x00,0x4C,0x82,0x59,0x7B,0x42,0x86,0x59,0xE4,0x40,0xD0,0x03,0x40, -0x40,0x3C,0xDA,0x00,0x80,0xA0,0x0C,0x00,0x02,0x77,0x17,0x86,0x59,0xE4,0x40,0xD0, -0x03,0x40,0x40,0x84,0x80,0xA4,0x0C,0x00,0x02,0xDA,0x00,0x84,0x01,0x40,0x7B,0x25, -0x86,0x59,0xE4,0x40,0xD0,0x03,0x40,0x40,0x3C,0xDA,0x00,0x80,0xA0,0x0C,0x00,0x02, -0x5F,0x07,0x84,0x01,0x40,0x7B,0x0E,0x92,0x59,0x3E,0x6F,0x40,0x59,0x4B,0xBC,0x80, -0x40,0x7B,0x02,0x18,0x49,0x08,0x70,0x70,0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00, -0x4C,0x80,0x7F,0x48,0x40,0x04,0x00,0x80,0x7F,0x58,0x40,0x04,0x00,0x84,0x01,0x7F, -0x54,0x40,0x04,0x00,0x38,0x7F,0x40,0x40,0x04,0x00,0x10,0x7F,0x14,0x80,0x7F,0x50, -0x40,0x04,0x00,0xA0,0x5F,0x2C,0x01,0x2C,0xCC,0xFC,0xEF,0x28,0x05,0x00,0x00,0x87, -0x21,0x7F,0x03,0x00,0x04,0x00,0xA0,0x5F,0xC8,0x00,0x2C,0xCC,0xFC,0xEF,0x28,0x05, -0x00,0x00,0x87,0x5F,0xD0,0x00,0x7F,0x00,0xA0,0x04,0x00,0xA0,0x01,0x2C,0xCC,0xFC, -0xEF,0x28,0x05,0x00,0x00,0x3B,0x7F,0x00,0xA0,0x04,0x00,0x5F,0x80,0x00,0x7F,0x0B, -0x2C,0x5C,0xAF,0x38,0x00,0x80,0x40,0x7B,0x2E,0x3F,0x01,0x73,0x77,0x07,0x84,0x04, -0x40,0x7B,0x04,0x80,0x40,0xB0,0x08,0x40,0xA0,0x40,0xA0,0x10,0x2C,0xCC,0xF8,0xAF, -0x38,0x00,0x3C,0x01,0x40,0x77,0x07,0x84,0x01,0x40,0x7B,0x0B,0x2C,0x5C,0xAF,0x0C, -0x00,0x80,0x40,0x7B,0x02,0x18,0x49,0x08,0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00, -0x4C,0x84,0x01,0x7F,0x50,0x40,0x04,0x00,0x83,0x7F,0x03,0x00,0x04,0x00,0x18,0x49, -0x08,0x70,0x70,0x70,0x10,0x49,0x9C,0x4F,0x04,0x00,0x00,0x00,0x4C,0x3B,0x7F,0x00, -0xA0,0x04,0x00,0x01,0x7F,0x0A,0x80,0x40,0x24,0x7F,0x29,0x69,0x00,0x00,0x70,0x84, -0x4B,0x7F,0xB0,0x12,0x00,0x02,0x70,0xB0,0x4F,0x00,0xE1,0x01,0x00,0x4B,0x70,0x87, -0x73,0x7F,0x00,0xA0,0x04,0x00,0xA0,0x01,0xA0,0x5F,0xE6,0x00,0x2C,0xCC,0xF8,0x7F, -0x50,0x4C,0x00,0x00,0x80,0x59,0x7B,0x20,0x3C,0x6F,0x64,0x59,0x4F,0x0E,0x84,0x7F, -0xB0,0x12,0x00,0x02,0x4B,0x70,0x80,0x40,0x7B,0x71,0xA0,0x01,0x2C,0xCC,0xFC,0xEF, -0x28,0x05,0x00,0x00,0x90,0x59,0x3B,0x7F,0x00,0xA0,0x04,0x00,0x01,0x77,0xDB,0xFB, -0x5F,0xA0,0x00,0x73,0x40,0x3C,0x5F,0xA0,0x00,0x40,0x7F,0x0F,0xFB,0x5F,0xF0,0x00, -0x73,0x40,0x3C,0x5F,0xF0,0x00,0x40,0x77,0x10,0xA0,0x01,0xA0,0x5F,0xE6,0x00,0x2C, -0xCC,0xF8,0x7F,0x50,0x4C,0x00,0x00,0x3B,0x7F,0x00,0xA0,0x04,0x00,0x77,0x7F,0x1E, -0x3B,0x7F,0x00,0xA0,0x04,0x00,0x08,0x7F,0x09,0x87,0x01,0x7F,0xAC,0x12,0x00,0x02, -0x84,0x7F,0xB0,0x12,0x00,0x02,0x4B,0x70,0x80,0x40,0x7B,0x0F,0x84,0x7F,0xB0,0x12, -0x00,0x02,0x4B,0x70,0x84,0x01,0x40,0x7B,0x02,0x18,0x49,0x08,0x10,0x49,0x9C,0x4F, -0x00,0x00,0x00,0x00,0x4C,0xBC,0x4F,0x00,0x00,0x00,0x02,0x5A,0x96,0x7A,0xEC,0xE0, -0x4F,0x00,0x00,0x01,0x00,0x5A,0x40,0x86,0xE2,0x7A,0xE0,0x41,0x9C,0x5A,0x41,0xAC, -0xE0,0x4F,0x00,0x00,0x01,0x00,0x41,0x3C,0x41,0x40,0x53,0x0A,0x80,0x40,0x24,0x7F, -0xFA,0x69,0x00,0x00,0x83,0x7F,0x0D,0x80,0x04,0x00,0x83,0x7F,0x08,0x80,0x04,0x00, -0x83,0x7F,0x0C,0x80,0x04,0x00,0x87,0x73,0x7F,0x02,0x80,0x04,0x00,0x87,0x72,0x7F, -0x02,0x80,0x04,0x00,0x3F,0x08,0x77,0x77,0x1D,0x84,0x5F,0x00,0x08,0x40,0x86,0xE2, -0x40,0xE0,0x40,0x86,0xE2,0x5A,0xE0,0x41,0xB0,0x41,0x40,0x86,0x40,0x7F,0x02,0x50, -0x04,0x00,0x7B,0x18,0x80,0x40,0x86,0xE2,0x40,0xE0,0x40,0x86,0xE2,0x5A,0xE0,0x41, -0xB0,0x41,0x40,0x86,0x40,0x7F,0x02,0x50,0x04,0x00,0x83,0x7F,0x0C,0x80,0x04,0x00, -0xFB,0x5F,0xFF,0x00,0x7B,0x40,0x87,0x40,0x7F,0x03,0x80,0x04,0x00,0x86,0xE2,0x7A, -0xE0,0x40,0xD4,0x08,0x40,0x40,0xBB,0x5F,0xFF,0x00,0x40,0x87,0x40,0x7F,0x03,0x80, -0x04,0x00,0xF3,0x6F,0x41,0x77,0x40,0x87,0x40,0x7F,0x0B,0x80,0x04,0x00,0x87,0x0D, -0x7F,0x0F,0x80,0x04,0x00,0x84,0x01,0x40,0x7B,0x02,0x18,0x49,0x08,0x70,0x70,0x70, -0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x84,0x4F,0xA0,0x03,0x00,0x02,0x7F, -0x08,0x00,0x00,0x02,0x84,0x4F,0xC4,0x12,0x00,0x02,0x7F,0x0C,0x00,0x00,0x02,0x84, -0x4F,0x09,0x04,0x00,0x02,0x7F,0x10,0x00,0x00,0x02,0x84,0x4F,0xB0,0x03,0x00,0x02, -0x7F,0x14,0x00,0x00,0x02,0x84,0x4F,0xAC,0x03,0x00,0x02,0x7F,0x18,0x00,0x00,0x02, -0x84,0x4F,0x0C,0x04,0x00,0x02,0x7F,0x1C,0x00,0x00,0x02,0x84,0x4F,0x18,0x04,0x00, -0x02,0x7F,0x20,0x00,0x00,0x02,0x84,0x4F,0x64,0x3F,0x00,0x00,0x7F,0x24,0x00,0x00, -0x02,0x84,0x4F,0x6C,0x39,0x00,0x00,0x7F,0x28,0x00,0x00,0x02,0x84,0x4F,0x68,0x3B, -0x00,0x00,0x7F,0x2C,0x00,0x00,0x02,0x18,0x49,0x08,0x70,0x70,0x10,0x47,0x9C,0x4F, -0x5C,0x00,0x00,0x00,0x4C,0x87,0x01,0xEF,0xC4,0x04,0x00,0x00,0x84,0x4F,0x0C,0x6E, -0x00,0x00,0x7F,0xA4,0x03,0x00,0x02,0x84,0x4F,0x98,0x6F,0x00,0x00,0x7F,0xA8,0x03, -0x00,0x02,0x84,0x4F,0x98,0x6F,0x00,0x00,0x7F,0x20,0x04,0x00,0x02,0x84,0x4F,0x72, -0x6E,0x00,0x00,0x7F,0x28,0x04,0x00,0x02,0x3C,0x4F,0xEF,0xBE,0xED,0xFE,0x7F,0xA0, -0x03,0x00,0x02,0x7F,0x0A,0x84,0x4F,0x00,0x00,0x80,0x00,0x4B,0x70,0x84,0x7F,0xA0, -0x03,0x00,0x02,0x48,0x3C,0x4F,0xEF,0xBE,0xED,0xFE,0x7F,0xA0,0x03,0x00,0x02,0x7F, -0x15,0x3C,0x4F,0x1E,0xAC,0xEB,0xAD,0x7F,0xA0,0x03,0x00,0x02,0x7F,0x08,0x24,0x7F, -0x20,0x6C,0x00,0x00,0x80,0x7F,0xA0,0x03,0x00,0x02,0xA0,0x4F,0x00,0x30,0x04,0x00, -0x04,0xC9,0x50,0x40,0xA0,0x40,0xA0,0x09,0x2C,0xCC,0xF4,0x7F,0x2C,0x49,0x00,0x00, -0x2B,0xC9,0x50,0x77,0x2C,0x04,0xC9,0x50,0x40,0xA0,0x40,0xA0,0x4F,0xEC,0x11,0x00, -0x00,0x2C,0xCC,0xF8,0x7F,0x28,0x70,0x00,0x00,0x04,0xC9,0x50,0x40,0xA0,0x40,0xA0, -0x4F,0x00,0x30,0x04,0x00,0xA0,0x09,0x2C,0xCC,0xF4,0x7F,0xDC,0x49,0x00,0x00,0x7B, -0x43,0x84,0x01,0x7F,0x40,0x40,0x04,0x00,0xA0,0x21,0x2C,0xCC,0xFC,0xEF,0x28,0x05, -0x00,0x00,0x80,0x7F,0x40,0x40,0x04,0x00,0xA0,0x6F,0x43,0x2C,0xCC,0xFC,0xEF,0x28, -0x05,0x00,0x00,0x2B,0xEF,0x10,0x05,0x00,0x00,0x77,0x19,0x38,0x7F,0x00,0x40,0x04, -0x00,0x02,0x7F,0x10,0x80,0xEF,0x8C,0x04,0x00,0x00,0x80,0x7F,0x44,0x40,0x04,0x00, -0x7B,0x00,0x3B,0x7F,0x0D,0x90,0x04,0x00,0x04,0x77,0x07,0x84,0x01,0x40,0x7B,0x04, -0x80,0x40,0x28,0x40,0x7F,0xAD,0x3C,0x4F,0xEF,0xBE,0xED,0xFE,0x48,0x77,0x19,0x84, -0x01,0x7F,0x40,0x40,0x04,0x00,0xA0,0x4F,0xF0,0x11,0x00,0x00,0x2C,0xCC,0xFC,0x7F, -0xB4,0x3B,0x00,0x00,0x7B,0x16,0x80,0x7F,0x40,0x40,0x04,0x00,0xA0,0x4F,0x34,0x12, -0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xB4,0x3B,0x00,0x00,0x04,0x59,0x40,0xA0,0x40,0x2C, -0xCC,0xFC,0x7F,0x1C,0x33,0x00,0x00,0x04,0x59,0x40,0xA0,0x40,0x04,0xC9,0x50,0x40, -0xA0,0x40,0x2C,0xCC,0xF8,0x7F,0xE8,0x6F,0x00,0x00,0x28,0x40,0x77,0x31,0x84,0x4F, -0x1E,0xAC,0xEB,0xAD,0x7F,0xA0,0x03,0x00,0x02,0x2C,0x5C,0x7F,0xD8,0x24,0x00,0x00, -0x84,0x7F,0xA0,0x03,0x00,0x02,0x48,0xA0,0x4F,0x00,0x30,0x04,0x00,0x04,0xC9,0x50, -0x40,0xA0,0x40,0xA0,0x09,0x2C,0xCC,0xF4,0x7F,0x2C,0x49,0x00,0x00,0x7A,0x22,0xFF, -0x3C,0x4F,0x7E,0xCA,0xD1,0xDE,0x7F,0xA0,0x03,0x00,0x02,0x7F,0x4F,0xA0,0x4F,0x0C, -0x30,0x04,0x00,0x04,0xC9,0x5A,0x40,0xA0,0x40,0xA0,0x01,0x2C,0xCC,0xF4,0x7F,0x2C, -0x49,0x00,0x00,0x28,0x40,0x77,0x29,0x84,0x7F,0xA0,0x04,0x00,0x00,0x40,0x87,0x10, -0xC0,0x01,0xDC,0x01,0x7F,0xA0,0x04,0x00,0x00,0x40,0xA0,0x40,0xA0,0x4F,0x0C,0x30, -0x04,0x00,0xA0,0x01,0x2C,0xCC,0xF4,0x7F,0xDC,0x49,0x00,0x00,0x7B,0x0E,0x84,0x7F, -0xA0,0x04,0x00,0x00,0x40,0x87,0xC9,0x5A,0xC0,0x01,0x83,0xEF,0xA0,0x04,0x00,0x00, -0x3C,0x4F,0x0D,0xF0,0xAD,0x8B,0x48,0x77,0x08,0x24,0x7F,0x40,0x6D,0x00,0x00,0x3C, -0x4F,0x7E,0xCA,0xD1,0xDE,0x48,0x77,0x0F,0x84,0x7F,0xA0,0x04,0x00,0x00,0x40,0x3F, -0x07,0xC0,0x01,0x77,0x2C,0xDC,0x02,0x7F,0xA0,0x04,0x00,0x00,0x40,0xA0,0x40,0xA0, -0x4F,0x45,0x12,0x00,0x00,0x2C,0xCC,0xF8,0x7F,0x28,0x70,0x00,0x00,0x2C,0x5C,0x7F, -0xFC,0x5F,0x00,0x00,0x28,0x40,0x77,0x09,0x2C,0x5C,0x7F,0x3A,0x59,0x00,0x00,0x3C, -0x4F,0x7E,0xCA,0xD1,0xDE,0x48,0x77,0x08,0x87,0x01,0xC9,0x5A,0x7B,0x35,0xA0,0x4F, -0x3B,0x30,0x04,0x00,0x04,0xC9,0x5A,0x40,0xA0,0x40,0xA0,0x01,0x2C,0xCC,0xF4,0x7F, -0x2C,0x49,0x00,0x00,0x28,0x40,0x77,0x1B,0x83,0xC9,0x5A,0x04,0xC9,0x5A,0x40,0xA0, -0x40,0xA0,0x4F,0x3B,0x30,0x04,0x00,0xA0,0x01,0x2C,0xCC,0xF4,0x7F,0xDC,0x49,0x00, -0x00,0x2B,0xC9,0x5A,0x77,0x2C,0xDC,0x02,0x7F,0xA0,0x04,0x00,0x00,0x40,0xA0,0x40, -0xA0,0x4F,0x4E,0x12,0x00,0x00,0x2C,0xCC,0xF8,0x7F,0x28,0x70,0x00,0x00,0x2C,0x5C, -0x7F,0xFC,0x5F,0x00,0x00,0x28,0x40,0x77,0x09,0x2C,0x5C,0x7F,0x3A,0x59,0x00,0x00, -0x3C,0x4F,0xEF,0xBE,0xED,0xFE,0x7F,0xA0,0x03,0x00,0x02,0x7F,0x08,0x80,0x7F,0x40, -0x40,0x04,0x00,0xA0,0x4F,0x0D,0x30,0x04,0x00,0xDC,0x02,0x7F,0xA0,0x04,0x00,0x00, -0x40,0xA0,0x40,0xA0,0x2D,0x2C,0xCC,0xF4,0x7F,0x2C,0x49,0x00,0x00,0x28,0x40,0x77, -0x34,0xDC,0x02,0x7F,0xA0,0x04,0x00,0x00,0x40,0xA0,0x40,0xA0,0x4F,0x55,0x12,0x00, -0x00,0x2C,0xCC,0xF8,0x7F,0x28,0x70,0x00,0x00,0xDC,0x02,0x7F,0xA0,0x04,0x00,0x00, -0x40,0xA0,0x40,0xA0,0x4F,0x0D,0x30,0x04,0x00,0xA0,0x2D,0x2C,0xCC,0xF4,0x7F,0xDC, -0x49,0x00,0x00,0x87,0x02,0xEF,0xA0,0x04,0x00,0x00,0x2C,0x5C,0x7F,0xFC,0x5F,0x00, -0x00,0x2C,0x5C,0x7F,0x3A,0x59,0x00,0x00,0x18,0x47,0x08,0x70,0x10,0x48,0x9C,0x4F, -0x00,0x00,0x00,0x00,0x4C,0x2C,0x5C,0xEF,0xA4,0x03,0x00,0x02,0x80,0x48,0x7B,0x34, -0x2B,0x88,0x40,0x12,0x00,0x02,0x7F,0x2A,0xD0,0x1A,0x48,0x40,0x83,0x80,0x0B,0x00, -0x01,0x06,0xD0,0x1A,0x48,0x40,0x83,0x80,0x23,0x00,0x01,0x06,0xD0,0x1A,0x48,0x40, -0x83,0x80,0x27,0x00,0x01,0x06,0xD0,0x1A,0x48,0x40,0x83,0x80,0x2B,0x00,0x01,0x06, -0x90,0x48,0x3C,0x04,0x48,0x4B,0xCB,0x18,0x48,0x08,0x70,0x70,0x10,0x49,0x9C,0x4F, -0x00,0x00,0x00,0x00,0x4C,0xA0,0x5F,0x80,0x00,0x2C,0xCC,0xFC,0x7F,0x6A,0x56,0x00, -0x00,0xA0,0x4F,0x7C,0x0E,0x00,0x00,0xA0,0x4F,0x5C,0x12,0x00,0x00,0x2C,0xCC,0xF8, -0x7F,0xB4,0x3B,0x00,0x00,0xA0,0x4F,0x8C,0x0E,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xB4, -0x3B,0x00,0x00,0x2C,0x5C,0x7F,0x7E,0x53,0x00,0x00,0xA0,0x4F,0xEF,0xBE,0xED,0xFE, -0x2C,0xCC,0xFC,0x7F,0xFE,0x58,0x00,0x00,0x18,0x49,0x08,0x70,0x70,0x70,0x10,0x49, -0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x2C,0x5C,0xEF,0x28,0x04,0x00,0x02,0x18,0x49, -0x08,0x70,0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00,0x4C,0x38,0x7F,0x20,0x40,0x04, -0x00,0x5F,0x80,0x00,0x7F,0x24,0xA0,0x5F,0x00,0x04,0x2C,0xCC,0xFC,0x7F,0x6A,0x56, -0x00,0x00,0xA0,0x4F,0x76,0x12,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xB4,0x3B,0x00,0x00, -0x80,0x7F,0x44,0x40,0x04,0x00,0x7B,0x00,0x38,0x7F,0x60,0x40,0x04,0x00,0x20,0x7F, -0x2A,0x80,0x7F,0x74,0x40,0x04,0x00,0xA0,0x5F,0x00,0x02,0x2C,0xCC,0xFC,0x7F,0x6A, -0x56,0x00,0x00,0xA0,0x4F,0x7C,0x0E,0x00,0x00,0xA0,0x4F,0x89,0x12,0x00,0x00,0x2C, -0xCC,0xF8,0x7F,0xB4,0x3B,0x00,0x00,0x7B,0x49,0x38,0x7F,0x60,0x40,0x04,0x00,0x6F, -0x40,0x7F,0x36,0x7B,0x08,0x80,0x7F,0x78,0x40,0x04,0x00,0x38,0x7F,0x60,0x40,0x04, -0x00,0x6F,0x40,0x77,0xF2,0xA0,0x5F,0x00,0x01,0x2C,0xCC,0xFC,0x7F,0x6A,0x56,0x00, -0x00,0xA0,0x4F,0x7C,0x0E,0x00,0x00,0xA0,0x4F,0xA9,0x12,0x00,0x00,0x2C,0xCC,0xF8, -0x7F,0xB4,0x3B,0x00,0x00,0x7B,0x0B,0x2C,0x5C,0xEF,0xA4,0x03,0x00,0x02,0x7B,0x25, -0x2C,0x5C,0x7F,0x7E,0x53,0x00,0x00,0xA0,0x4F,0x8C,0x0E,0x00,0x00,0x2C,0xCC,0xFC, -0x7F,0xB4,0x3B,0x00,0x00,0xA0,0x4F,0xEF,0xBE,0xED,0xFE,0x2C,0xCC,0xFC,0x7F,0xFE, -0x58,0x00,0x00,0x18,0x49,0x08,0x70,0x70,0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00, -0x4C,0xF8,0x03,0x7F,0x10,0x04,0x00,0x02,0x40,0x3C,0x03,0x40,0x77,0x31,0xF8,0x6F, -0x78,0x7F,0x10,0x04,0x00,0x02,0x40,0x3C,0x6F,0x70,0x40,0x7F,0x10,0xF8,0x6F,0x78, -0x7F,0x10,0x04,0x00,0x02,0x40,0x3C,0x08,0x40,0x77,0x0B,0x2C,0x5C,0xEF,0x20,0x04, -0x00,0x02,0x7B,0x09,0x2C,0x5C,0xEF,0xA8,0x03,0x00,0x02,0x7B,0x09,0x2C,0x5C,0xEF, -0xA8,0x03,0x00,0x02,0x18,0x49,0x08,0x70,0x10,0x49,0x9C,0x4F,0x00,0x00,0x00,0x00, -0x4C,0xA0,0x6F,0x40,0x2C,0xCC,0xFC,0x7F,0x6A,0x56,0x00,0x00,0xA0,0x4F,0x7C,0x0E, -0x00,0x00,0xA0,0x4F,0xC0,0x12,0x00,0x00,0x2C,0xCC,0xF8,0x7F,0xB4,0x3B,0x00,0x00, -0xA0,0x4F,0x8C,0x0E,0x00,0x00,0x2C,0xCC,0xFC,0x7F,0xB4,0x3B,0x00,0x00,0x2C,0x5C, -0x7F,0x7E,0x53,0x00,0x00,0xA0,0x4F,0xEF,0xBE,0xED,0xFE,0x2C,0xCC,0xFC,0x7F,0xFE, -0x58,0x00,0x00,0x18,0x49,0x08,0x70,0x70,0x10,0x49,0x84,0x5A,0x40,0x84,0x74,0x41, -0x3C,0x41,0x40,0x77,0x08,0x7B,0x10,0x90,0x40,0x90,0x41,0x3F,0x51,0x50,0x77,0x07, -0x3F,0x50,0x00,0x77,0xF4,0xFF,0x51,0x50,0x40,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08, -0x10,0x49,0x84,0x5A,0x40,0x7B,0x04,0x90,0x40,0x2B,0x50,0x77,0xFC,0xBC,0x5A,0x40, -0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x70,0x10,0x49,0x84,0x5A,0x41,0x84,0x74,0x40, -0x30,0x35,0x84,0x5A,0x40,0x04,0xC9,0xE8,0x4C,0x20,0x49,0x08,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x95, -0x06,0x06,0x06,0x06,0x03,0x02,0x01,0x78,0x03,0x02,0x01,0x1A,0x03,0x02,0x01,0x21,}; -#endif /* ROM_rom_rev3_bin_H */ diff --git a/3B2/tests/3b2_test.ini b/3B2/tests/3b2_test.ini deleted file mode 100644 index 39f6a980..00000000 --- a/3B2/tests/3b2_test.ini +++ /dev/null @@ -1,34 +0,0 @@ -:: 3b2-diag.ini -:: This script will run the available 3B2/400 core diagnostics. -:: -cd %~p0 -set runlimit 2 minutes -set on -on error ignore -on runtime echof "\r\n*** Test Runtime Limit %SIM_RUNLIMIT% %SIM_RUNLIMIT_UNITS% Exceeded ***\n"; exit 1 - -set env DIAG_QUIET_MODE=0 -if ("%1" == "-v") set console notelnet -else set -qu console telnet=localhost:65432,telnet=buffered; set env -a DIAG_QUIET_MODE=1 - -:: Set maximum memory size -set cpu 4M - -if not exist rev2_diags.dsk echof "\r\nMISSING - Diagnostic disk image '%~p0rev2_diags.dsk' is missing\n"; exit 1 -attach -rq ifloppy rev2_diags.dsk - -:: Initial setup -expect "UTILITIES GUIDE" send "mcp\r"; go -q -expect "Enter name of program to execute [ ]:" send "filledt\r"; go -q -expect "Enter Load Device Option Number [0 (FD5)]:" send "0\r"; go -q -expect "Enter name of program to execute [ ]:" send "dgmon\r"; go -q -expect "Enter Load Device Option Number [0 (FD5)]:" send "0\r"; go -q -expect "Did you boot filledt? [y or n] (n)" send "y\r"; go -q -expect "DGMON > " send "DGN SBD\r"; go -q -expect "SBD 0 (IN SLOT 0) DIAGNOSTICS PASSED" echof; echof "PASSED: 3B2 DGMON SBD Diagnostics."; exit 0 -expect [4] "FAIL" echof; echof "FAILED: 3B2 DGMON SBD Diagnostics."; exit 1 - -:: Run tests -if (DIAG_QUIET_MODE) echof "\nStarting 3B2 DGMON SBD Diagnostics." -boot -q CPU -return diff --git a/3B2/tests/rev2_diags.dsk b/3B2/tests/rev2_diags.dsk deleted file mode 100644 index 1fbfe90921e9c20c74ec7622d05884a5255af866..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 737280 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
Iv>P+nO5QhR?ot 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 @@ -26,7 +26,7 @@ @@ -220,15 +220,7 @@ > - - - - - - + + + + + + @@ -499,6 +499,10 @@ RelativePath="..\3B2\3b2_cpu.h" > + + @@ -507,10 +511,6 @@ RelativePath="..\3B2\3b2_defs.h" > - - @@ -532,21 +532,17 @@ > - - - - + + @@ -555,22 +551,18 @@ RelativePath="..\3B2\3b2_ports.h" > - - - - - - + + + + diff --git a/Visual Studio Projects/3B2-600.vcproj b/Visual Studio Projects/3B2-700.vcproj similarity index 90% rename from Visual Studio Projects/3B2-600.vcproj rename to Visual Studio Projects/3B2-700.vcproj index 421267e2..4fe4a614 100644 --- a/Visual Studio Projects/3B2-600.vcproj +++ b/Visual Studio Projects/3B2-700.vcproj @@ -2,9 +2,9 @@ @@ -26,7 +26,7 @@ @@ -211,6 +211,10 @@ RelativePath="..\3B2\3b2_iu.c" > + + @@ -223,10 +227,6 @@ RelativePath="..\3B2\3b2_ports.c" > - - @@ -239,10 +239,6 @@ RelativePath="..\3B2\3b2_rev3_sys.c" > - - @@ -255,6 +251,10 @@ RelativePath="..\3B2\3b2_sys.c" > + + @@ -500,7 +500,7 @@ > + + + + @@ -539,30 +547,6 @@ RelativePath="..\3B2\3b2_ports.h" > - - - - - - - - - - - - @@ -571,6 +555,10 @@ RelativePath="..\3B2\3b2_sys.h" > + + diff --git a/Visual Studio Projects/Simh.sln b/Visual Studio Projects/Simh.sln index 3a213c5a..b3a3b940 100755 --- a/Visual Studio Projects/Simh.sln +++ b/Visual Studio Projects/Simh.sln @@ -228,7 +228,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "scelbi", "scelbi.vcproj", " {D40F3AF1-EEE7-4432-9807-2AD287B490F8} = {D40F3AF1-EEE7-4432-9807-2AD287B490F8} EndProjectSection EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "3B2", "3B2.vcproj", "{56178F08-8783-4ADA-820C-20C06412678E}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "3B2-400", "3B2-400.vcproj", "{56178F08-8783-4ADA-820C-20C06412678E}" ProjectSection(ProjectDependencies) = postProject {D40F3AF1-EEE7-4432-9807-2AD287B490F8} = {D40F3AF1-EEE7-4432-9807-2AD287B490F8} EndProjectSection @@ -373,7 +373,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tt2500", "tt2500.vcproj", " {D40F3AF1-EEE7-4432-9807-2AD287B490F8} = {D40F3AF1-EEE7-4432-9807-2AD287B490F8} EndProjectSection EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "3B2-600", "3B2-600.vcproj", "{A7AE7747-DFA0-49F5-9D6C-9094657A8EE3}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "3B2-700", "3B2-700.vcproj", "{A7AE7747-DFA0-49F5-9D6C-9094657A8EE3}" ProjectSection(ProjectDependencies) = postProject {D40F3AF1-EEE7-4432-9807-2AD287B490F8} = {D40F3AF1-EEE7-4432-9807-2AD287B490F8} EndProjectSection diff --git a/makefile b/makefile index 43c51bf5..94283484 100644 --- a/makefile +++ b/makefile @@ -2066,25 +2066,25 @@ KS10_OPT = -DKS=1 -DUSE_INT64 -I $(KS10D) -I $(PDP11D) ${NETWORK_OPT} ATT3B2D = ${SIMHD}/3B2 ATT3B2M400 = ${ATT3B2D}/3b2_cpu.c ${ATT3B2D}/3b2_sys.c \ - ${ATT3B2D}/3b2_rev2_sys.c ${ATT3B2D}/3b2_rev2_mmu.c \ - ${ATT3B2D}/3b2_rev2_mau.c ${ATT3B2D}/3b2_rev2_csr.c \ - ${ATT3B2D}/3b2_rev2_timer.c ${ATT3B2D}/3b2_stddev.c \ - ${ATT3B2D}/3b2_mem.c ${ATT3B2D}/3b2_iu.c \ - ${ATT3B2D}/3b2_if.c ${ATT3B2D}/3b2_id.c \ - ${ATT3B2D}/3b2_dmac.c ${ATT3B2D}/3b2_io.c \ - ${ATT3B2D}/3b2_ports.c ${ATT3B2D}/3b2_ctc.c \ - ${ATT3B2D}/3b2_ni.c + ${ATT3B2D}/3b2_rev2_sys.c ${ATT3B2D}/3b2_rev2_mmu.c \ + ${ATT3B2D}/3b2_mau.c ${ATT3B2D}/3b2_rev2_csr.c \ + ${ATT3B2D}/3b2_timer.c ${ATT3B2D}/3b2_stddev.c \ + ${ATT3B2D}/3b2_mem.c ${ATT3B2D}/3b2_iu.c \ + ${ATT3B2D}/3b2_if.c ${ATT3B2D}/3b2_id.c \ + ${ATT3B2D}/3b2_dmac.c ${ATT3B2D}/3b2_io.c \ + ${ATT3B2D}/3b2_ports.c ${ATT3B2D}/3b2_ctc.c \ + ${ATT3B2D}/3b2_ni.c ATT3B2M400_OPT = -DUSE_INT64 -DUSE_ADDR64 -DREV2 -I ${ATT3B2D} ${NETWORK_OPT} -ATT3B2M600 = ${ATT3B2D}/3b2_cpu.c ${ATT3B2D}/3b2_sys.c \ - ${ATT3B2D}/3b2_rev3_sys.c ${ATT3B2D}/3b2_rev3_mmu.c \ - ${ATT3B2D}/3b2_rev2_mau.c ${ATT3B2D}/3b2_rev3_csr.c \ - ${ATT3B2D}/3b2_rev3_timer.c ${ATT3B2D}/3b2_stddev.c \ - ${ATT3B2D}/3b2_mem.c ${ATT3B2D}/3b2_iu.c \ - ${ATT3B2D}/3b2_if.c ${ATT3B2D}/3b2_dmac.c \ - ${ATT3B2D}/3b2_io.c ${ATT3B2D}/3b2_ports.c \ - ${ATT3B2D}/3b2_scsi.c ${ATT3B2D}/3b2_ni.c -ATT3B2M600_OPT = -DUSE_INT64 -DUSE_ADDR64 -DREV3 -I ${ATT3B2D} ${NETWORK_OPT} +ATT3B2M700 = ${ATT3B2D}/3b2_cpu.c ${ATT3B2D}/3b2_sys.c \ + ${ATT3B2D}/3b2_rev3_sys.c ${ATT3B2D}/3b2_rev3_mmu.c \ + ${ATT3B2D}/3b2_mau.c ${ATT3B2D}/3b2_rev3_csr.c \ + ${ATT3B2D}/3b2_timer.c ${ATT3B2D}/3b2_stddev.c \ + ${ATT3B2D}/3b2_mem.c ${ATT3B2D}/3b2_iu.c \ + ${ATT3B2D}/3b2_if.c ${ATT3B2D}/3b2_dmac.c \ + ${ATT3B2D}/3b2_io.c ${ATT3B2D}/3b2_ports.c \ + ${ATT3B2D}/3b2_scsi.c ${ATT3B2D}/3b2_ni.c +ATT3B2M700_OPT = -DUSE_INT64 -DUSE_ADDR64 -DREV3 -I ${ATT3B2D} ${NETWORK_OPT} SIGMAD = ${SIMHD}/sigma SIGMA = ${SIGMAD}/sigma_cpu.c ${SIGMAD}/sigma_sys.c ${SIGMAD}/sigma_cis.c \ @@ -2155,13 +2155,13 @@ ALL = pdp1 pdp4 pdp7 pdp8 pdp9 pdp15 pdp11 pdp10 \ nova eclipse hp2100 hp3000 i1401 i1620 s3 altair altairz80 gri \ i7094 ibm1130 id16 id32 sds lgp h316 cdc1700 \ swtp6800mp-a swtp6800mp-a2 tx-0 ssem b5500 intel-mds \ - scelbi 3b2 i701 i704 i7010 i7070 i7080 i7090 \ + scelbi 3b2 3b2-700 i701 i704 i7010 i7070 i7080 i7090 \ sigma uc15 pdp10-ka pdp10-ki pdp10-kl pdp10-ks pdp6 i650 \ imlac tt2500 sel32 all : ${ALL} -EXPERIMENTAL = cdc1700 3b2-600 +EXPERIMENTAL = cdc1700 experimental : ${EXPERIMENTAL} @@ -2806,22 +2806,29 @@ ifneq (,$(call find_test,${B5500D},b5500)) $@ $(call find_test,${B5500D},b5500) ${TEST_ARG} endif +3b2-400 : 3b2 + 3b2 : ${BIN}3b2${EXE} -${BIN}3b2${EXE} : ${ATT3B2M400} ${SIM} ${BUILD_ROMS} +${BIN}3b2${EXE} : ${ATT3B2M400} ${SIM} ${MKDIRBIN} ${CC} ${ATT3B2M400} ${SIM} ${ATT3B2M400_OPT} ${CC_OUTSPEC} ${LDFLAGS} +ifeq (${WIN32},) + cp ${BIN}3b2${EXE} ${BIN}3b2-400${EXE} +else + copy $(@D)\3b2${EXE} $(@D)\3b2-400${EXE} +endif ifneq (,$(call find_test,${ATT3B2D},3b2)) $@ $(call find_test,${ATT3B2D},3b2) ${TEST_ARG} endif -3b2-600 : ${BIN}3b2-600${EXE} +3b2-700 : ${BIN}3b2-700${EXE} -${BIN}3b2-600${EXE} : ${ATT3B2M600} ${SIM} ${BUILD_ROMS} +${BIN}3b2-700${EXE} : ${ATT3B2M700} ${SIM} ${MKDIRBIN} - ${CC} ${ATT3B2M600} ${SCSI} ${SIM} ${ATT3B2M600_OPT} ${CC_OUTSPEC} ${LDFLAGS} -ifneq (,$(call find_test,${ATT3B2D},3b2-600)) - $@ $(call find_test,${ATT3B2D},3b2-600) ${TEST_ARG} + ${CC} ${ATT3B2M700} ${SCSI} ${SIM} ${ATT3B2M700_OPT} ${CC_OUTSPEC} ${LDFLAGS} +ifneq (,$(call find_test,${ATT3B2D},3b2-700)) + $@ $(call find_test,${ATT3B2D},3b2-700) ${TEST_ARG} endif i7090 : ${BIN}i7090${EXE} diff --git a/sim_BuildROMs.c b/sim_BuildROMs.c index 5c571cb0..fdcae15f 100644 --- a/sim_BuildROMs.c +++ b/sim_BuildROMs.c @@ -70,9 +70,6 @@ struct ROM_File_Descriptor { {"PDP11/dazzledart/dazzle.lda", "PDP11/pdp11_dazzle_dart_rom.h", 6096, 0xFFF83848, "dazzle_lda"}, {"PDP11/11logo/11logo.lda", "PDP11/pdp11_11logo_rom.h", 26009, 0xFFDD77F7, "logo_lda"}, {"swtp6800/swtp6800/swtbugv10.bin", "swtp6800/swtp6800/swtp_swtbugv10_bin.h", 1024, 0xFFFE4FBC, "swtp_swtbugv10_bin"}, - {"3B2/rom_rev2.bin", "3B2/rom_rev2_bin.h", 32768, 0xFFD55762, "rom_rev2_bin"}, - {"3B2/rom_rev2_demon.bin", "3B2/rom_rev2_demon_bin.h", 65536, 0xFFB345BB, "rom_rev2_demon_bin"}, - {"3B2/rom_rev3.bin", "3B2/rom_rev3_bin.h", 131072, 0xFFDC0EB8, "rom_rev3_bin"}, }; diff --git a/sim_scsi.c b/sim_scsi.c index f909a3b8..bbb7a128 100644 --- a/sim_scsi.c +++ b/sim_scsi.c @@ -490,6 +490,9 @@ scsi_set_req (bus); /* request to send data void scsi_mode_sel6 (SCSI_BUS *bus, uint8 *data, uint32 len) { +UNIT *uptr = bus->dev[bus->target]; +SCSI_DEV *dev = (SCSI_DEV *)uptr->up7; +uint32 blk_size; if (bus->phase == SCSI_CMD) { scsi_debug_cmd (bus, "Mode Select(6) - CMD\n"); memcpy (&bus->cmd[0], &data[0], 6); @@ -499,9 +502,24 @@ if (bus->phase == SCSI_CMD) { } else if (bus->phase == SCSI_DATO) { scsi_debug_cmd (bus, "Mode Select(6) - DATO\n"); - /* Not currently implemented so just return - good status for now */ - scsi_status (bus, STS_OK, KEY_OK, ASC_OK); + if (dev->devtype == SCSI_TAPE && uptr->flags & SCSI_QIC) { + blk_size = ((uint32)bus->buf[9]) << 16 | + ((uint32)bus->buf[10]) << 8 | + (uint32)bus->buf[11]; + /* QIC tape ONLY supports requesting a fixed block size of + * 0x200 bytes. Any other block size will cause an illegal + * request. */ + if (blk_size == SCSI_QIC_BLKSZ) { + scsi_status(bus, STS_OK, KEY_OK, ASC_OK); + } + else { + scsi_status(bus, STS_CHK, KEY_ILLREQ|KEY_M_ILI, ASC_INVCDB); + } + } + else { + /* Not implemented for disk and non-QIC tape */ + scsi_status(bus, STS_OK, KEY_OK, ASC_OK); + } } } @@ -784,8 +802,9 @@ void scsi_read6_tape (SCSI_BUS *bus, uint8 *data, uint32 len) { UNIT *uptr = bus->dev[bus->target]; SCSI_DEV *dev = (SCSI_DEV *)uptr->up7; -t_seccnt sects, sectsread; +t_seccnt sects, sectsread, new_buf_b; t_stat r; +uint32 i; if ((data[1] & 0x3) == 0x3) { /* SILI and FIXED? */ scsi_status (bus, STS_CHK, KEY_ILLREQ, ASC_INVCDB); @@ -793,6 +812,7 @@ if ((data[1] & 0x3) == 0x3) { /* SILI and FIXED? */ } sects = GETW (data, 3) | (data[2] << 16); +new_buf_b = 0; sectsread = 0; if (sects == 0) { /* no data to read */ @@ -803,35 +823,64 @@ if (sects == 0) { /* no data to read */ scsi_debug_cmd (bus, "Read(6) blks %d fixed %d\n", sects, (data[1] & 0x1)); if (uptr->flags & UNIT_ATT) { - if (data[1] & 0x1) { - r = sim_tape_rdrecf (uptr, &bus->buf[0], §sread, (sects * dev->block_size)); - scsi_debug_cmd (bus, "Read tape blk %d, read %d, r = %d\n", sects, sectsread, r); + if (uptr->flags & SCSI_QIC) { + if (data[1] & 0x1) { + /* If this is a QIC tape drive and bit 0 is set, this is a + request to read multiple fixed-length blocks. */ + scsi_debug_cmd(bus, "QIC in fixed block mode\n"); + for (i = 0; i < sects; i++) { + r = sim_tape_rdrecf(uptr, &bus->buf[new_buf_b], §sread, SCSI_QIC_BLKSZ); + scsi_debug_cmd(bus, "Read tape blk %d, read %d, r = %d\n", + sects, sectsread, r); + if (r == MTSE_OK) { + new_buf_b += SCSI_QIC_BLKSZ; + } else { + scsi_tape_status(bus, r); + scsi_status(bus, bus->status, bus->sense_key, bus->sense_code); + return; + } + } + } else { + /* QIC drives respond with an illegal request when the + request does not specify fixed-block mode */ + scsi_debug_cmd(bus, "QIC not in fixed block mode, invalid command\n"); + scsi_status(bus, STS_CHK, KEY_ILLREQ|KEY_M_ILI, ASC_INVCDB); + return; + } } else { - r = sim_tape_rdrecf (uptr, &bus->buf[0], §sread, sects); - scsi_debug_cmd (bus, "Read tape max %d, read %d, r = %d\n", sects, sectsread, r); - if (r == MTSE_INVRL) { /* overlength condition */ - scsi_debug_cmd (bus, "Overlength\n"); - if ((data[1] & 0x2) && (dev->block_size == 0)) { /* SILI set */ - scsi_debug_cmd (bus, "SILI set\n"); + /* Otherwise, this is a normal streaming tape read */ + if (data[1] & 0x1) { + r = sim_tape_rdrecf (uptr, &bus->buf[0], §sread, (sects * dev->block_size)); + scsi_debug_cmd (bus, "Read tape blk %d, read %d, r = %d\n", sects, sectsread, r); + } + else { + r = sim_tape_rdrecf (uptr, &bus->buf[0], §sread, sects); + scsi_debug_cmd (bus, "Read tape max %d, read %d, r = %d\n", sects, sectsread, r); + if (r == MTSE_INVRL) { /* overlength condition */ + scsi_debug_cmd (bus, "Overlength\n"); + if ((data[1] & 0x2) && (dev->block_size == 0)) { /* SILI set */ + scsi_debug_cmd (bus, "SILI set\n"); + } + else { + scsi_debug_cmd (bus, "SILI not set - check condition\n"); + scsi_status (bus, STS_CHK, (KEY_OK | KEY_M_ILI), ASC_OK); + return; + } } - else { - scsi_debug_cmd (bus, "SILI not set - check condition\n"); - scsi_status (bus, STS_CHK, (KEY_OK | KEY_M_ILI), ASC_OK); - return; - } - } - else if ((r == MTSE_OK) && (sectsread < sects)) { /* underlength condition */ - scsi_debug_cmd (bus, "Underlength\n"); - if (data[1] & 0x2) { /* SILI set */ - scsi_debug_cmd (bus, "SILI set\n"); - } - else { - scsi_debug_cmd (bus, "SILI not set - check condition\n"); - scsi_status_deferred (bus, STS_CHK, (KEY_OK | KEY_M_ILI), ASC_OK); - bus->sense_info = (sects - sectsread); + else if ((r == MTSE_OK) && (sectsread < sects)) { /* underlength condition */ + scsi_debug_cmd (bus, "Underlength\n"); + if (data[1] & 0x2) { /* SILI set */ + scsi_debug_cmd (bus, "SILI set\n"); + } + else { + scsi_debug_cmd (bus, "SILI not set - check condition\n"); + scsi_status_deferred (bus, STS_CHK, (KEY_OK | KEY_M_ILI), ASC_OK); + bus->sense_info = (sects - sectsread); + } } } + new_buf_b = sectsread; } if (r != MTSE_OK) { @@ -845,7 +894,7 @@ else { } if (sectsread > 0) { - bus->buf_b = sectsread; + bus->buf_b = new_buf_b; scsi_set_phase (bus, SCSI_DATI); /* data in phase next */ } else { diff --git a/sim_scsi.h b/sim_scsi.h index 4ef8e3f7..c07e290c 100644 --- a/sim_scsi.h +++ b/sim_scsi.h @@ -68,10 +68,13 @@ #define SCSI_DBG_TAP 0x10000000 /* tape activity */ #define SCSI_V_NOAUTO ((DKUF_V_UF > MTUF_V_UF) ? DKUF_V_UF : MTUF_V_UF)/* noautosize */ -#define SCSI_V_UF (SCSI_V_NOAUTO + 1) +#define SCSI_V_QIC (SCSI_V_NOAUTO + 1) +#define SCSI_V_UF (SCSI_V_QIC + 1) +#define SCSI_QIC (1 << SCSI_V_QIC) #define SCSI_WLK (UNIT_WLK|UNIT_RO) /* hwre write lock */ #define SCSI_NOAUTO DKUF_NOAUTOSIZE +#define SCSI_QIC_BLKSZ 0x200 struct scsi_dev_t { uint8 devtype; /* device type */