From 9b683eb5f68ab35bfdb303c1b55c2869788bfc49 Mon Sep 17 00:00:00 2001 From: antoniovillena Date: Thu, 28 Apr 2016 14:17:52 +0200 Subject: [PATCH] SamCoupe a test2 --- cores/SamCoupe/asic.v | 114 +- cores/SamCoupe/genkeybmap_es.c | 473 + cores/SamCoupe/keyb_es_hex.txt | 16384 ++++++++++++++++++++++++++ cores/SamCoupe/ps2_keyb.v | 126 + cores/SamCoupe/ps2_port.v | 275 + cores/SamCoupe/ram.v | 4 +- cores/SamCoupe/samcoupe.v | 56 +- cores/SamCoupe/samcoupe.xise | 22 +- cores/SamCoupe/scancode_to_speccy.v | 269 + cores/SamCoupe/tld_sam.v | 8 +- cores/SamCoupe/tv80_core.v | 2 + 11 files changed, 17666 insertions(+), 67 deletions(-) create mode 100644 cores/SamCoupe/genkeybmap_es.c create mode 100644 cores/SamCoupe/keyb_es_hex.txt create mode 100644 cores/SamCoupe/ps2_keyb.v create mode 100644 cores/SamCoupe/ps2_port.v create mode 100644 cores/SamCoupe/scancode_to_speccy.v diff --git a/cores/SamCoupe/asic.v b/cores/SamCoupe/asic.v index a007277..d6f0aeb 100644 --- a/cores/SamCoupe/asic.v +++ b/cores/SamCoupe/asic.v @@ -88,12 +88,19 @@ module asic ( VBPORCH + TBORDER; + // Start of vertical sync, horizontal counter (last 4 scanlines) parameter BEGINVSYNCH = HACTIVEREGION + RBORDER + HFPORCH + HSYNC + HBPORCH; - parameter BEGINVINTH = HACTIVEREGION + RBORDER + HFPORCH; + + // Start and end of vertical retrace interrupt, horizontal counter + parameter BEGINVINTH = BEGINVSYNCH; //HACTIVEREGION + RBORDER + HFPORCH; + parameter ENDVINTH = (BEGINVINTH + 256)%HTOTAL; + + // Start and end of vertical retrace interrupt, vertical counter parameter BEGINVINTV = VACTIVEREGION + BBORDER + VFPORCH - 1; parameter ENDVINTV = VACTIVEREGION + BBORDER + VFPORCH; - parameter ENDVINTH = (BEGINVINTH + 256)%HTOTAL; - parameter BEGINHINTH = HACTIVEREGION + RBORDER + HFPORCH; + + // Start and end of raster interrupt, horizontal counter + parameter BEGINHINTH = HACTIVEREGION + RBORDER; parameter ENDHINTH = (BEGINHINTH + 256)%HTOTAL; parameter IOADDR_VMPR = 8'd252, @@ -103,7 +110,8 @@ module asic ( IOADDR_LINEINT = 8'd249, IOADDR_STATUS = 8'd249, IOADDR_BASECLUT = 8'd248, - IOADDR_ATTRIB = 8'd255; + IOADDR_ATTRIB = 8'd255, + IOADDR_HLPEN = 8'd248; ////////////////////////////////////////////////////////////////////////// // IO regs @@ -122,7 +130,7 @@ module asic ( wire rom_in_section_d = lmpr[6]; wire write_protect_section_a = lmpr[7]; - reg [7:0] hmpr = 8'h02; // port 251. Bit 7 is not used for now. R/W + reg [7:0] hmpr = 8'h00; // port 251. Bit 7 is not used for now. R/W wire [4:0] high_page = hmpr[4:0]; wire [1:0] clut_mode_3_hi = hmpr[6:5]; @@ -134,6 +142,9 @@ module asic ( reg [7:0] lineint = 8'hFF; // port 249 write only + reg [7:0] hpen = 8'h00; + reg [7:0] lpen = 8'h00; + reg [6:0] clut[0:15]; // Port xF8h where x=0..F initial begin clut[ 0] = 7'b000_0_000; @@ -171,6 +182,23 @@ module asic ( end end + ////////////////////////////////////////////////////////////////////////// + // HPEN and LPEN counters + always @(posedge clk) begin + if (hc[0] == 1'b0) begin + if (hc == HACTIVEREGION) begin + if (vc == VTOTAL-1) + hpen <= 8'h00; + else if (vc < VACTIVEREGION) + hpen <= hpen + 1; + end + if (hc < HACTIVEREGION) + lpen <= lpen + 1; + else + lpen <= 8'h00; + end + end + ////////////////////////////////////////////////////////////////////////// // Syncs and vertical retrace/raster line int generation reg vint_n; @@ -189,18 +217,29 @@ module asic ( csync = ~csync; if ( (vc == BEGINVINTV && hc >= BEGINVINTH) || (vc == ENDVINTV && hc < ENDVINTH) ) - vint_n = 1'b0; +// if (vc == BEGINVINTV && hc >= BEGINVINTH) + vint_n = 1'b0; if (lineint >= 8'd0 && lineint <= 8'd191) begin +// if (lineint == 8'd0) begin +// if (vc == VTOTAL-1 && hc >= BEGINHINTH || +// vc == 9'd0 && hc < ENDHINTH) +// rint_n = 1'b0; +// end +// else begin +// if ({1'b0, lineint} == vc-1 && hc >= BEGINHINTH || +// {1'b0, lineint} == vc && hc < ENDHINTH) +// rint_n = 1'b0; +// end +// end if (lineint == 8'd0) begin - if (vc == VTOTAL-1 && hc >= BEGINHINTH || - vc == 9'd0 && hc < ENDHINTH) - rint_n = 1'b0; + if (vc == VTOTAL-1 && hc >= BEGINHINTH) + rint_n = 1'b0; end else begin - if ({1'b0, lineint} == vc-1 && hc >= BEGINHINTH || - {1'b0, lineint} == vc && hc < ENDHINTH) - rint_n = 1'b0; + if ({1'b0, lineint} == vc-1 && hc >= BEGINHINTH) + rint_n = 1'b0; end + end end assign int_n = vint_n & rint_n; @@ -233,41 +272,47 @@ module asic ( ////////////////////////////////////////////////////////////////////////// // Contention signal (risk of) - reg contention; + reg mem_contention; + reg io_contention; always @* begin - contention = 1'b0; + mem_contention = 1'b0; + + if (hc[3:0]<4'd10) + io_contention = 1'b1; + else + io_contention = 1'b0; + if (fetching_pixels == 1'b1 && hc[3:0]<4'd10) - contention = 1'b1; + mem_contention = 1'b1; else if (fetching_pixels == 1'b0 && (hc[3:0]==4'd0 || hc[3:0]==4'd1 || hc[3:0]==4'd8 || hc[3:0]==4'd9) ) - contention = 1'b1; + mem_contention = 1'b1; if (screen_mode == 2'b00 && hc[3:0]<4'd10 && hc[9:4]<6'd40) - contention = 1'b1; + mem_contention = 1'b1; // extra contention for MODE 1 end - assign asic_is_using_ram = contention & fetching_pixels; + assign asic_is_using_ram = mem_contention & fetching_pixels; ////////////////////////////////////////////////////////////////////////// // WAIT signal with contention applied always @* begin wait_n = 1'b1; - if (cpuaddr<16'h4000 && rom_in_section_a==1'b1) + if (mreq_n == 1'b0 && cpuaddr<16'h4000 && rom_in_section_a==1'b1) wait_n = 1'b1; - else if (cpuaddr>=16'hC000 && rom_in_section_d==1'b1) + else if (mreq_n == 1'b0 && cpuaddr>=16'hC000 && rom_in_section_d==1'b1) wait_n = 1'b1; - else if (contention == 1'b1) begin - if (mreq_n == 1'b0) - wait_n = 1'b0; - else if (iorq_n == 1'b0) - if (rd_n == 1'b0 || wr_n == 1'b0) - wait_n = 1'b0; - end + else if (mem_contention == 1'b1 && mreq_n == 1'b0) + wait_n = 1'b0; + else if (io_contention == 1'b1 && iorq_n == 1'b0) + wait_n = 1'b0; end ////////////////////////////////////////////////////////////////////////// // VRAM address generation + reg [14:0] screen_offs = 15'h0000; + reg [4:0] screen_column = 5'h00; always @* begin if (screen_mode == 2'd0) begin if (hc[2] == 1'b0) @@ -282,13 +327,11 @@ module asic ( vramaddr = {screen_page, 1'b1, screen_offs[12:0]}; end else - vramaddr = {screen_page[4:0], 14'b00000000000000} + {3'b000, screen_offs}; + vramaddr = {screen_page[4:1], screen_offs}; end ////////////////////////////////////////////////////////////////////////// // FSM for fetching pixels from RAM and shift registers - reg [15:0] screen_offs = 16'h0000; - reg [4:0] screen_column = 5'h00; reg [7:0] vram_byte1, vram_byte2, vram_byte3, vram_byte4; reg [7:0] sregm12 = 8'h00; reg [7:0] attrreg = 8'h00; @@ -300,7 +343,7 @@ module asic ( always @(posedge clk) begin // a good time to reset pixel address counters and advance flash counter for modes 1 and 2 if (vc==(VTOTAL-1) && hc==(HTOTAL-1)) begin - screen_offs <= 16'h0000; + screen_offs <= 15'h0000; screen_column <= 5'h00; flash_counter <= flash_counter + 1; end @@ -433,15 +476,14 @@ module asic ( // Write to IO ports from CPU always @(posedge clk) begin if (rst_n == 1'b0) begin -`ifdef SYNTH +`ifdef SYNTH vmpr <= 8'h00; `else vmpr <= 8'b01100000; `endif lmpr <= 8'h00; - hmpr <= 8'h02; + hmpr <= 8'h00; border <= 8'h00; - lineint <= 8'hFF; end else begin if (iorq_n == 1'b0 && wr_n == 1'b0) begin @@ -481,6 +523,10 @@ module asic ( data_to_cpu = hmpr; else if (cpuaddr[7:0] == IOADDR_LMPR) data_to_cpu = lmpr; + else if (cpuaddr[8:0] == {1'b0, IOADDR_HLPEN} ) + data_to_cpu = lpen; + else if (cpuaddr[8:0] == {1'b1, IOADDR_HLPEN} ) + data_to_cpu = hpen; else if (cpuaddr[7:0]>=8'd224 && cpuaddr[7:0]<=8'd231) begin disc1_n = 1'b0; data_enable_n = 1'b1; diff --git a/cores/SamCoupe/genkeybmap_es.c b/cores/SamCoupe/genkeybmap_es.c new file mode 100644 index 0000000..014cf83 --- /dev/null +++ b/cores/SamCoupe/genkeybmap_es.c @@ -0,0 +1,473 @@ +#include +#include + +typedef unsigned char BYTE; +/* + 12 12 3 3 2 +AAAA DDDDDDDD AAAA DDDDDDDD MRN MMM XX + +AAAA = semifila del teclado a modificar | esta información está +DDDDDDDD = dato (AND negado con lo que haya) de esa semifila | repetida para dos teclas +MRN = Master reset, Reset de usuario, NMI +MMM = la tecla es un modificador +XX = Reservado para uso futuro + +Ej: en la dirección de memoria correspondiente al código de la tecla ESC, +que correspondería la tecla ESC del SAM, pondríamos: +1000 00100000 0000 00000000 000 000 00 +En la dirección de memoria correspondiente al código de la tecla < que se +corresponde con la pulsación SYMBOL+Q pondríamos: +0111 00000010 0010 00000001 000 000 00 + +256 codigos + E0 = 512 codigos +SHIFT, CTRL, ALT = 8 combinaciones + +512*8=4096 direcciones x 32 bits = 16384 bytes +En el core se dispondrá como una memoria de 16384x8 bits + +Cada tecla ocupará cuatro direcciones consecutivas según el esquema anterior. +*/ + +// You shouldn't have to touch these defs unless your Spectrum has a different keyboard +// layout (because, for example, you are using a different ROM + +// CCCC BBBBAAAA -- hex digits for coding +#define SAM_1 0x301 // 0011 00000001 +#define SAM_2 0x302 // 0011 00000010 +#define SAM_3 0x304 // 0011 00000100 +#define SAM_4 0x308 // 0011 00001000 +#define SAM_5 0x310 // 0011 00010000 +#define SAM_ESC 0x320 // 0011 00100000 +#define SAM_TAB 0x340 // 0011 01000000 +#define SAM_CAPS 0x380 // 0011 10000000 + +#define SAM_0 0x401 // 0100 00000001 +#define SAM_9 0x402 // 0100 00000010 +#define SAM_8 0x404 // 0100 00000100 +#define SAM_7 0x408 // 0100 00001000 +#define SAM_6 0x410 // 0100 00010000 +#define SAM_MINUS 0x420 // 0100 00100000 +#define SAM_PLUS 0x440 // 0100 01000000 +#define SAM_DELETE 0x480 // 0100 10000000 + +#define SAM_Q 0x201 // 0010 00000001 +#define SAM_W 0x202 // 0010 00000010 +#define SAM_E 0x204 // 0010 00000100 +#define SAM_R 0x208 // 0010 00001000 +#define SAM_T 0x210 // 0010 00010000 +#define SAM_F7 0x220 // 0010 00100000 +#define SAM_F8 0x240 // 0010 01000000 +#define SAM_F9 0x280 // 0010 10000000 + +#define SAM_P 0x501 // 0101 00000001 +#define SAM_O 0x502 // 0101 00000010 +#define SAM_I 0x504 // 0101 00000100 +#define SAM_U 0x508 // 0101 00001000 +#define SAM_Y 0x510 // 0101 00010000 +#define SAM_EQUAL 0x520 // 0101 00100000 +#define SAM_QUOTE 0x540 // 0101 01000000 +#define SAM_F0 0x580 // 0101 10000000 + +#define SAM_A 0x101 // 0001 00000001 +#define SAM_S 0x102 // 0001 00000010 +#define SAM_D 0x104 // 0001 00000100 +#define SAM_F 0x108 // 0001 00001000 +#define SAM_G 0x110 // 0001 00010000 +#define SAM_F4 0x120 // 0001 00100000 +#define SAM_F5 0x140 // 0001 01000000 +#define SAM_F6 0x180 // 0001 10000000 + +#define SAM_RETURN 0x601 // 0110 00000001 +#define SAM_L 0x602 // 0110 00000010 +#define SAM_K 0x604 // 0110 00000100 +#define SAM_J 0x608 // 0110 00001000 +#define SAM_H 0x610 // 0110 00010000 +#define SAM_SEMICOL 0x620 //0110 00100000 +#define SAM_COLON 0x640 // 0110 01000000 +#define SAM_EDIT 0x680 // 0110 10000000 + +#define SAM_SHIFT 0x001 // 0000 00000001 +#define SAM_Z 0x002 // 0000 00000010 +#define SAM_X 0x004 // 0000 00000100 +#define SAM_C 0x008 // 0000 00001000 +#define SAM_V 0x010 // 0000 00010000 +#define SAM_F1 0x020 // 0000 00100000 +#define SAM_F2 0x040 // 0000 01000000 +#define SAM_F3 0x080 // 0000 10000000 + +#define SAM_SPACE 0x701 // 0111 00000001 +#define SAM_SYMBOL 0x702 // 0111 00000010 +#define SAM_M 0x704 // 0111 00000100 +#define SAM_N 0x708 // 0111 00001000 +#define SAM_B 0x710 // 0111 00010000 +#define SAM_COMMA 0x720 // 0111 00100000 +#define SAM_DOT 0x740 // 0111 01000000 +#define SAM_INV 0x780 // 0111 10000000 + +#define SAM_CTRL 0x801 // 1000 00000001 +#define SAM_UP 0x802 // 1000 00000010 +#define SAM_DOWN 0x804 // 1000 00000100 +#define SAM_LEFT 0x808 // 1000 00001000 +#define SAM_RIGHT 0x810 // 1000 00010000 + +#define SAM_BANG ((SAM_SHIFT<<12) | SAM_1) +#define SAM_AT ((SAM_SHIFT<<12) | SAM_2) +#define SAM_HASH ((SAM_SHIFT<<12) | SAM_3) +#define SAM_DOLLAR ((SAM_SHIFT<<12) | SAM_4) +#define SAM_PERCEN ((SAM_SHIFT<<12) | SAM_5) +#define SAM_AMP ((SAM_SHIFT<<12) | SAM_6) +#define SAM_APOSTRO ((SAM_SHIFT<<12) | SAM_7) +#define SAM_PAROPEN ((SAM_SHIFT<<12) | SAM_8) +#define SAM_PARCLOS ((SAM_SHIFT<<12) | SAM_9) +#define SAM_TILDE ((SAM_SHIFT<<12) | SAM_0) +#define SAM_SLASH ((SAM_SHIFT<<12) | SAM_MINUS) +#define SAM_STAR ((SAM_SHIFT<<12) | SAM_PLUS) +#define SAM_LESS ((SAM_SYMBOL<<12) | SAM_Q) +#define SAM_GREATER ((SAM_SYMBOL<<12) | SAM_W) +#define SAM_BRAOPEN ((SAM_SYMBOL<<12) | SAM_R) +#define SAM_BRACLOS ((SAM_SYMBOL<<12) | SAM_T) +#define SAM_UNDERSC ((SAM_SHIFT<<12) | SAM_EQUAL) +#define SAM_COPY ((SAM_SHIFT<<12) | SAM_QUOTE) +#define SAM_PIPE ((SAM_SYMBOL<<12) | SAM_9) +#define SAM_BACKSLA ((SAM_SYMBOL<<12) | SAM_INV) +#define SAM_CUROPEN ((SAM_SYMBOL<<12) | SAM_F) +#define SAM_CURCLOS ((SAM_SYMBOL<<12) | SAM_G) +#define SAM_CARET ((SAM_SYMBOL<<12) | SAM_H) +#define SAM_POUND ((SAM_SYMBOL<<12) | SAM_L) +#define SAM_QUEST ((SAM_SYMBOL<<12) | SAM_X) + +// END of SAM Coupé key definitions + +// Definitions for additional signals generated by the keyboard core +// AAAADDDDDDDD AAAADDDDDDDD MRN MMM XX +#define MODIFIER1 0x04 +#define MODIFIER2 0x08 +#define MODIFIER3 0x10 + +#define MRESET 0x80 +#define URESET 0x40 +#define NMI 0x20 + +#define USER2 0x02 +#define USER1 0x01 +// End of additional signals + +// A key can be pressed with up to three key modifiers +// which generates 8 combinations for each key +#define EXT 0x100 +#define MD1 0x200 +#define MD2 0x400 +#define MD3 0x800 + +// Scan code 2 list. First, non localized keys +#define PC_A 0x1C +#define PC_B 0x32 +#define PC_C 0x21 +#define PC_D 0x23 +#define PC_E 0x24 +#define PC_F 0x2B +#define PC_G 0x34 +#define PC_H 0x33 +#define PC_I 0x43 +#define PC_J 0x3B +#define PC_K 0x42 +#define PC_L 0x4B +#define PC_M 0x3A +#define PC_N 0x31 +#define PC_O 0x44 +#define PC_P 0x4D +#define PC_Q 0x15 +#define PC_R 0x2D +#define PC_S 0x1B +#define PC_T 0x2C +#define PC_U 0x3C +#define PC_V 0x2A +#define PC_W 0x1D +#define PC_X 0x22 +#define PC_Y 0x35 +#define PC_Z 0x1A + +#define PC_0 0x45 +#define PC_1 0x16 +#define PC_2 0x1E +#define PC_3 0x26 +#define PC_4 0x25 +#define PC_5 0x2E +#define PC_6 0x36 +#define PC_7 0x3D +#define PC_8 0x3E +#define PC_9 0x46 + +#define PC_F1 0x05 +#define PC_F2 0x06 +#define PC_F3 0x04 +#define PC_F4 0x0C +#define PC_F5 0x03 +#define PC_F6 0x0B +#define PC_F7 0x83 +#define PC_F8 0x0A +#define PC_F9 0x01 +#define PC_F10 0x09 +#define PC_F11 0x78 +#define PC_F12 0x07 + +#define PC_ESC 0x76 +#define PC_SPACE 0x29 +#define PC_LCTRL 0x14 +#define PC_RCTRL 0x14 | EXT +#define PC_LSHIFT 0x12 +#define PC_RSHIFT 0x59 +#define PC_LALT 0x11 +#define PC_RALT 0x11 | EXT +#define PC_LWIN 0x1F | EXT +#define PC_RWIN 0x27 | EXT +#define PC_APPS 0x2F | EXT + +#define PC_TAB 0x0D +#define PC_CPSLOCK 0x58 +#define PC_SCRLOCK 0x7E + +#define PC_INSERT 0x70 | EXT +#define PC_DELETE 0x71 | EXT +#define PC_HOME 0x6C | EXT +#define PC_END 0x69 | EXT +#define PC_PGUP 0x7D | EXT +#define PC_PGDOWN 0x7A | EXT +#define PC_BKSPACE 0x66 +#define PC_ENTER 0x5A +#define PC_UP 0x75 | EXT +#define PC_DOWN 0x72 | EXT +#define PC_LEFT 0x6B | EXT +#define PC_RIGHT 0x74 | EXT + +#define PC_NUMLOCK 0x77 +#define PC_KP_DIVIS 0x4A | EXT +#define PC_KP_MULT 0x7C +#define PC_KP_MINUS 0x7B +#define PC_KP_PLUS 0x79 +#define PC_KP_ENTER 0x5A | EXT +#define PC_KP_DOT 0x71 +#define PC_KP_0 0x70 +#define PC_KP_1 0x69 +#define PC_KP_2 0x72 +#define PC_KP_3 0x7A +#define PC_KP_4 0x6B +#define PC_KP_5 0x73 +#define PC_KP_6 0x74 +#define PC_KP_7 0x6C +#define PC_KP_8 0x75 +#define PC_KP_9 0x7D + +// Localized keyboards start to differenciate from here + +// Localized keyboard ES (Spain) +#define PC_BACKSLA 0x0E +#define PC_APOSTRO 0x4E +#define PC_OPNBANG 0x55 +#define PC_GRAVEAC 0x54 +#define PC_PLUS 0x5B +#define PC_EGNE 0x4C +#define PC_ACUTEAC 0x52 +#define PC_CEDILLA 0x5D +#define PC_LESS 0x61 +#define PC_COMMA 0x41 +#define PC_DOT 0x49 +#define PC_MINUS 0x4A + +#define MAP(pc,sam,rmu) { \ + rom[(pc)*4] = (((sam)>>16)&0xFF); \ + rom[(pc)*4+1] = (((sam)>>8)&0xFF); \ + rom[(pc)*4+2] = (((sam))&0xFF); \ + rom[(pc)*4+3] = (rmu); \ + } + +#define MAPANY(pc,sam,rmu) { \ + MAP(pc,sam,rmu); \ + MAP(MD1|pc,sam,rmu); \ + MAP(MD2|pc,sam,rmu); \ + MAP(MD3|pc,sam,rmu); \ + MAP(MD1|MD2|pc,sam,rmu); \ + MAP(MD1|MD3|pc,sam,rmu); \ + MAP(MD2|MD3|pc,sam,rmu); \ + MAP(MD1|MD2|MD3|pc,sam,rmu); \ + } + +#define CLEANMAP { \ + int i; \ + for (i=0;i<(sizeof(rom)/sizeof(rom[0]));i++) \ + rom[i] = 0; \ + } +#define SAVEMAPHEX(name) { \ + FILE *f; \ + int i; \ + f=fopen(name,"w"); \ + for(i=0;i<(sizeof(rom)/sizeof(rom[0]));i++) \ + fprintf(f,"%.2X\n",rom[i]); \ + fclose(f); \ + } + +#define SAVEMAPBIN(name) { \ + FILE *f; \ + int i; \ + f=fopen(name,"wb"); \ + fwrite (rom, 1, sizeof(rom), f); \ + fclose(f); \ + } + + +int main() +{ + BYTE rom[16384]; + + CLEANMAP; + + MAPANY(PC_LSHIFT,0,MODIFIER1); // MD1 is SHIFT + MAPANY(PC_RSHIFT,0,MODIFIER1); // MD1 is SHIFT + MAPANY(PC_LCTRL,SAM_CTRL,MODIFIER2); // MD2 is CTRL + MAPANY(PC_RCTRL,SAM_CTRL,MODIFIER2); // MD2 is CTRL + MAPANY(PC_LALT,SAM_SHIFT,MODIFIER3); // MD3 is ALT. + MAPANY(PC_RALT,SAM_SYMBOL,MODIFIER3); // MD3 is ALT. + + MAPANY(PC_RWIN,SAM_EDIT,0); // EDIT key + + // Basic mapping: each key from PC is mapped to a key in the SAM + MAP(PC_1,SAM_1,0); + MAP(PC_2,SAM_2,0); + MAP(PC_3,SAM_3,0); + MAP(PC_4,SAM_4,0); + MAP(PC_5,SAM_5,0); + MAP(PC_6,SAM_6,0); + MAP(PC_7,SAM_7,0); + MAP(PC_8,SAM_8,0); + MAP(PC_9,SAM_9,0); + MAP(PC_0,SAM_0,0); + + MAP(PC_Q,SAM_Q,0); + MAP(PC_W,SAM_W,0); + MAP(PC_E,SAM_E,0); + MAP(PC_R,SAM_R,0); + MAP(PC_T,SAM_T,0); + MAP(PC_Y,SAM_Y,0); + MAP(PC_U,SAM_U,0); + MAP(PC_I,SAM_I,0); + MAP(PC_O,SAM_O,0); + MAP(PC_P,SAM_P,0); + MAP(PC_A,SAM_A,0); + MAP(PC_S,SAM_S,0); + MAP(PC_D,SAM_D,0); + MAP(PC_F,SAM_F,0); + MAP(PC_G,SAM_G,0); + MAP(PC_H,SAM_H,0); + MAP(PC_J,SAM_J,0); + MAP(PC_K,SAM_K,0); + MAP(PC_L,SAM_L,0); + MAP(PC_Z,SAM_Z,0); + MAP(PC_X,SAM_X,0); + MAP(PC_C,SAM_C,0); + MAP(PC_V,SAM_V,0); + MAP(PC_B,SAM_B,0); + MAP(PC_N,SAM_N,0); + MAP(PC_M,SAM_M,0); + + MAP(MD1|PC_Q,SAM_SHIFT<<12|SAM_Q,0); + MAP(MD1|PC_W,SAM_SHIFT<<12|SAM_W,0); + MAP(MD1|PC_E,SAM_SHIFT<<12|SAM_E,0); + MAP(MD1|PC_R,SAM_SHIFT<<12|SAM_R,0); + MAP(MD1|PC_T,SAM_SHIFT<<12|SAM_T,0); + MAP(MD1|PC_Y,SAM_SHIFT<<12|SAM_Y,0); + MAP(MD1|PC_U,SAM_SHIFT<<12|SAM_U,0); + MAP(MD1|PC_I,SAM_SHIFT<<12|SAM_I,0); + MAP(MD1|PC_O,SAM_SHIFT<<12|SAM_O,0); + MAP(MD1|PC_P,SAM_SHIFT<<12|SAM_P,0); + MAP(MD1|PC_A,SAM_SHIFT<<12|SAM_A,0); + MAP(MD1|PC_S,SAM_SHIFT<<12|SAM_S,0); + MAP(MD1|PC_D,SAM_SHIFT<<12|SAM_D,0); + MAP(MD1|PC_F,SAM_SHIFT<<12|SAM_F,0); + MAP(MD1|PC_G,SAM_SHIFT<<12|SAM_G,0); + MAP(MD1|PC_H,SAM_SHIFT<<12|SAM_H,0); + MAP(MD1|PC_J,SAM_SHIFT<<12|SAM_J,0); + MAP(MD1|PC_K,SAM_SHIFT<<12|SAM_K,0); + MAP(MD1|PC_L,SAM_SHIFT<<12|SAM_L,0); + MAP(MD1|PC_Z,SAM_SHIFT<<12|SAM_Z,0); + MAP(MD1|PC_X,SAM_SHIFT<<12|SAM_X,0); + MAP(MD1|PC_C,SAM_SHIFT<<12|SAM_C,0); + MAP(MD1|PC_V,SAM_SHIFT<<12|SAM_V,0); + MAP(MD1|PC_B,SAM_SHIFT<<12|SAM_B,0); + MAP(MD1|PC_N,SAM_SHIFT<<12|SAM_N,0); + MAP(MD1|PC_M,SAM_SHIFT<<12|SAM_M,0); + + MAPANY(PC_SPACE,SAM_SPACE,0); + MAPANY(PC_ENTER,SAM_RETURN,0); + + //Complex mapping. This is for the spanish keyboard although many + //combos can be used with any other PC keyboard + MAPANY(PC_ESC,SAM_ESC,0); + MAPANY(PC_CPSLOCK,SAM_CAPS,0); + MAPANY(PC_TAB,SAM_TAB,0); + MAP(PC_BKSPACE,SAM_DELETE,0); + MAPANY(PC_UP,SAM_UP,0); + MAPANY(PC_DOWN,SAM_DOWN,0); + MAPANY(PC_LEFT,SAM_LEFT,0); + MAPANY(PC_RIGHT,SAM_RIGHT,0); + + MAP(PC_F5|MD2|MD3,0,NMI); // Ctrl-Alt-F5 for NMI + MAP(PC_DELETE|MD2|MD3,0,URESET); // + MAP(PC_KP_DOT|MD2|MD3,0,URESET); // Ctrl-Alt-Del for user reset + MAP(PC_BKSPACE|MD2|MD3,0,MRESET); // Ctrl-Alt-BkSpace for master reset + + //keypad + MAPANY(PC_KP_DIVIS,SAM_SLASH,0); + MAPANY(PC_KP_MULT,SAM_STAR,0); + MAPANY(PC_KP_MINUS,SAM_MINUS,0); + MAPANY(PC_KP_PLUS,SAM_PLUS,0); + MAPANY(PC_KP_ENTER,SAM_RETURN,0); + MAPANY(PC_KP_0,SAM_F0,0); + MAPANY(PC_KP_1,SAM_F1,0); + MAPANY(PC_KP_2,SAM_F2,0); + MAPANY(PC_KP_3,SAM_F3,0); + MAPANY(PC_KP_4,SAM_F4,0); + MAPANY(PC_KP_5,SAM_F5,0); + MAPANY(PC_KP_6,SAM_F6,0); + MAPANY(PC_KP_7,SAM_F7,0); + MAPANY(PC_KP_8,SAM_F8,0); + MAPANY(PC_KP_9,SAM_F9,0); + + //Some shift+key mappings for the ES keyboard + MAP(MD1|PC_1,SAM_BANG,0); + MAP(MD1|PC_2,SAM_QUOTE,0); + MAP(MD1|PC_3,SAM_HASH,0); + MAP(MD1|PC_4,SAM_DOLLAR,0); + MAP(MD1|PC_5,SAM_PERCEN,0); + MAP(MD1|PC_6,SAM_AMP,0); + MAP(MD1|PC_7,SAM_SLASH,0); + MAP(MD1|PC_8,SAM_PAROPEN,0); + MAP(MD1|PC_9,SAM_PARCLOS,0); + MAP(MD1|PC_0,SAM_EQUAL,0); + MAP(PC_APOSTRO,SAM_APOSTRO,0); + MAP(MD1|PC_APOSTRO,SAM_QUEST,0); + MAP(PC_GRAVEAC,SAM_POUND,0); + MAP(MD1|PC_GRAVEAC,SAM_CARET,0); + MAP(PC_PLUS,SAM_PLUS,0); + MAP(MD1|PC_PLUS,SAM_STAR,0); + MAP(PC_ACUTEAC,SAM_CUROPEN,0); + MAP(MD1|PC_ACUTEAC,SAM_CUROPEN,0); + MAP(PC_ACUTEAC,SAM_CUROPEN,0); + MAP(MD1|PC_ACUTEAC,SAM_CUROPEN,0); + MAP(PC_CEDILLA,SAM_CURCLOS,0); + MAP(MD1|PC_CEDILLA,SAM_COPY,0); + MAP(PC_COMMA,SAM_COMMA,0); + MAP(MD1|PC_COMMA,SAM_SEMICOL,0); + MAP(PC_DOT,SAM_DOT,0); + MAP(MD1|PC_DOT,SAM_COLON,0); + MAP(PC_MINUS,SAM_MINUS,0); + MAP(MD1|PC_MINUS,SAM_UNDERSC,0); + MAP(PC_BACKSLA,SAM_BACKSLA,0); + MAP(MD1|PC_BACKSLA,SAM_BACKSLA,0); + MAP(PC_EGNE,SAM_TILDE,0); + MAP(PC_LESS,SAM_LESS,0); + MAP(MD1|PC_LESS,SAM_GREATER,0); + + // End of mapping. Save .HEX file for Verilog + SAVEMAPHEX("keyb_es_hex.txt"); +} + diff --git a/cores/SamCoupe/keyb_es_hex.txt b/cores/SamCoupe/keyb_es_hex.txt new file mode 100644 index 0000000..b08b61f --- /dev/null +++ b/cores/SamCoupe/keyb_es_hex.txt @@ -0,0 +1,16384 @@ +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +03 +40 +00 +70 +27 +80 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +01 +10 +00 +00 +00 +04 +00 +00 +00 +00 +00 +08 +01 +08 +00 +02 +01 +00 +00 +03 +01 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +02 +00 +00 +01 +02 +00 +00 +01 +01 +00 +00 +02 +02 +00 +00 +03 +02 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +08 +00 +00 +00 +04 +00 +00 +01 +04 +00 +00 +02 +04 +00 +00 +03 +08 +00 +00 +03 +04 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +07 +01 +00 +00 +00 +10 +00 +00 +01 +08 +00 +00 +02 +10 +00 +00 +02 +08 +00 +00 +03 +10 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +07 +08 +00 +00 +07 +10 +00 +00 +06 +10 +00 +00 +01 +10 +00 +00 +05 +10 +00 +00 +04 +10 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +07 +04 +00 +00 +06 +08 +00 +00 +05 +08 +00 +00 +04 +08 +00 +00 +04 +04 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +07 +20 +00 +00 +06 +04 +00 +00 +05 +04 +00 +00 +05 +02 +00 +00 +04 +01 +00 +00 +04 +02 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +07 +40 +00 +00 +04 +20 +00 +00 +06 +02 +00 +00 +14 +01 +00 +00 +05 +01 +00 +00 +14 +08 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +70 +21 +08 +00 +00 +00 +00 +00 +70 +26 +02 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +03 +80 +00 +00 +00 +00 +04 +00 +06 +01 +00 +00 +04 +40 +00 +00 +00 +00 +00 +70 +21 +10 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +70 +22 +01 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +04 +80 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +20 +00 +00 +00 +00 +00 +00 +01 +20 +00 +00 +02 +20 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +05 +80 +00 +00 +00 +00 +00 +00 +00 +40 +00 +00 +01 +40 +00 +00 +01 +80 +00 +00 +02 +40 +00 +00 +03 +20 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +04 +40 +00 +00 +00 +80 +00 +00 +04 +20 +00 +00 +14 +40 +00 +00 +02 +80 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +07 +02 +10 +00 +00 +00 +00 +00 +00 +00 +00 +00 +08 +01 +08 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +06 +80 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +14 +20 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +06 +01 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +08 +08 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +08 +04 +00 +00 +00 +00 +00 +00 +08 +10 +00 +00 +08 +02 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +03 +40 +00 +70 +27 +80 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +01 +10 +00 +00 +00 +04 +00 +00 +00 +00 +00 +08 +01 +08 +00 +12 +01 +00 +00 +13 +01 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +10 +02 +00 +00 +11 +02 +00 +00 +11 +01 +00 +00 +12 +02 +00 +00 +05 +40 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +10 +08 +00 +00 +10 +04 +00 +00 +11 +04 +00 +00 +12 +04 +00 +00 +13 +08 +00 +00 +13 +04 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +07 +01 +00 +00 +10 +10 +00 +00 +11 +08 +00 +00 +12 +10 +00 +00 +12 +08 +00 +00 +13 +10 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +17 +08 +00 +00 +17 +10 +00 +00 +16 +10 +00 +00 +11 +10 +00 +00 +15 +10 +00 +00 +14 +10 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +17 +04 +00 +00 +16 +08 +00 +00 +15 +08 +00 +00 +14 +20 +00 +00 +14 +04 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +06 +20 +00 +00 +16 +04 +00 +00 +15 +04 +00 +00 +15 +02 +00 +00 +05 +20 +00 +00 +14 +02 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +06 +40 +00 +00 +15 +20 +00 +00 +16 +02 +00 +00 +00 +00 +00 +00 +15 +01 +00 +70 +20 +04 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +70 +21 +08 +00 +00 +00 +00 +00 +70 +26 +10 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +03 +80 +00 +00 +00 +00 +04 +00 +06 +01 +00 +00 +14 +40 +00 +00 +00 +00 +00 +00 +15 +40 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +70 +22 +02 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +20 +00 +00 +00 +00 +00 +00 +01 +20 +00 +00 +02 +20 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +05 +80 +00 +00 +00 +00 +00 +00 +00 +40 +00 +00 +01 +40 +00 +00 +01 +80 +00 +00 +02 +40 +00 +00 +03 +20 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +04 +40 +00 +00 +00 +80 +00 +00 +04 +20 +00 +00 +14 +40 +00 +00 +02 +80 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +07 +02 +10 +00 +00 +00 +00 +00 +00 +00 +00 +00 +08 +01 +08 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +06 +80 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +14 +20 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +06 +01 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +08 +08 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +08 +04 +00 +00 +00 +00 +00 +00 +08 +10 +00 +00 +08 +02 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +03 +40 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +01 +10 +00 +00 +00 +04 +00 +00 +00 +00 +00 +08 +01 +08 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +07 +01 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +03 +80 +00 +00 +00 +00 +04 +00 +06 +01 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +20 +00 +00 +00 +00 +00 +00 +01 +20 +00 +00 +02 +20 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +05 +80 +00 +00 +00 +00 +00 +00 +00 +40 +00 +00 +01 +40 +00 +00 +01 +80 +00 +00 +02 +40 +00 +00 +03 +20 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +04 +40 +00 +00 +00 +80 +00 +00 +04 +20 +00 +00 +14 +40 +00 +00 +02 +80 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +07 +02 +10 +00 +00 +00 +00 +00 +00 +00 +00 +00 +08 +01 +08 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +06 +80 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +14 +20 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +06 +01 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +08 +08 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +08 +04 +00 +00 +00 +00 +00 +00 +08 +10 +00 +00 +08 +02 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +03 +40 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +01 +10 +00 +00 +00 +04 +00 +00 +00 +00 +00 +08 +01 +08 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +07 +01 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +03 +80 +00 +00 +00 +00 +04 +00 +06 +01 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +20 +00 +00 +00 +00 +00 +00 +01 +20 +00 +00 +02 +20 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +05 +80 +00 +00 +00 +00 +00 +00 +00 +40 +00 +00 +01 +40 +00 +00 +01 +80 +00 +00 +02 +40 +00 +00 +03 +20 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +04 +40 +00 +00 +00 +80 +00 +00 +04 +20 +00 +00 +14 +40 +00 +00 +02 +80 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +07 +02 +10 +00 +00 +00 +00 +00 +00 +00 +00 +00 +08 +01 +08 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +06 +80 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +14 +20 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +06 +01 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +08 +08 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +08 +04 +00 +00 +00 +00 +00 +00 +08 +10 +00 +00 +08 +02 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +03 +40 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +01 +10 +00 +00 +00 +04 +00 +00 +00 +00 +00 +08 +01 +08 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +07 +01 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +03 +80 +00 +00 +00 +00 +04 +00 +06 +01 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +20 +00 +00 +00 +00 +00 +00 +01 +20 +00 +00 +02 +20 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +05 +80 +00 +00 +00 +00 +00 +00 +00 +40 +00 +00 +01 +40 +00 +00 +01 +80 +00 +00 +02 +40 +00 +00 +03 +20 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +04 +40 +00 +00 +00 +80 +00 +00 +04 +20 +00 +00 +14 +40 +00 +00 +02 +80 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +07 +02 +10 +00 +00 +00 +00 +00 +00 +00 +00 +00 +08 +01 +08 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +06 +80 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +14 +20 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +06 +01 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +08 +08 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +08 +04 +00 +00 +00 +00 +00 +00 +08 +10 +00 +00 +08 +02 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +03 +40 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +01 +10 +00 +00 +00 +04 +00 +00 +00 +00 +00 +08 +01 +08 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +07 +01 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +03 +80 +00 +00 +00 +00 +04 +00 +06 +01 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +20 +00 +00 +00 +00 +00 +00 +01 +20 +00 +00 +02 +20 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +05 +80 +00 +00 +00 +00 +00 +00 +00 +40 +00 +00 +01 +40 +00 +00 +01 +80 +00 +00 +02 +40 +00 +00 +03 +20 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +04 +40 +00 +00 +00 +80 +00 +00 +04 +20 +00 +00 +14 +40 +00 +00 +02 +80 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +07 +02 +10 +00 +00 +00 +00 +00 +00 +00 +00 +00 +08 +01 +08 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +06 +80 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +14 +20 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +06 +01 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +08 +08 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +08 +04 +00 +00 +00 +00 +00 +00 +08 +10 +00 +00 +08 +02 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +20 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +03 +40 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +01 +10 +00 +00 +00 +04 +00 +00 +00 +00 +00 +08 +01 +08 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +07 +01 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +03 +80 +00 +00 +00 +00 +04 +00 +06 +01 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +80 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +20 +00 +00 +00 +00 +00 +00 +01 +20 +00 +00 +02 +20 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +05 +80 +00 +00 +00 +00 +40 +00 +00 +40 +00 +00 +01 +40 +00 +00 +01 +80 +00 +00 +02 +40 +00 +00 +03 +20 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +04 +40 +00 +00 +00 +80 +00 +00 +04 +20 +00 +00 +14 +40 +00 +00 +02 +80 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +07 +02 +10 +00 +00 +00 +00 +00 +00 +00 +00 +00 +08 +01 +08 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +06 +80 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +14 +20 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +06 +01 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +08 +08 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +40 +00 +08 +04 +00 +00 +00 +00 +00 +00 +08 +10 +00 +00 +08 +02 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +03 +40 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +01 +10 +00 +00 +00 +04 +00 +00 +00 +00 +00 +08 +01 +08 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +07 +01 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +03 +80 +00 +00 +00 +00 +04 +00 +06 +01 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +20 +00 +00 +00 +00 +00 +00 +01 +20 +00 +00 +02 +20 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +05 +80 +00 +00 +00 +00 +00 +00 +00 +40 +00 +00 +01 +40 +00 +00 +01 +80 +00 +00 +02 +40 +00 +00 +03 +20 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +04 +40 +00 +00 +00 +80 +00 +00 +04 +20 +00 +00 +14 +40 +00 +00 +02 +80 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +07 +02 +10 +00 +00 +00 +00 +00 +00 +00 +00 +00 +08 +01 +08 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +06 +80 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +14 +20 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +06 +01 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +08 +08 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +08 +04 +00 +00 +00 +00 +00 +00 +08 +10 +00 +00 +08 +02 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 diff --git a/cores/SamCoupe/ps2_keyb.v b/cores/SamCoupe/ps2_keyb.v new file mode 100644 index 0000000..6cfdd4a --- /dev/null +++ b/cores/SamCoupe/ps2_keyb.v @@ -0,0 +1,126 @@ +`timescale 1ns / 1ps +`default_nettype none + +////////////////////////////////////////////////////////////////////////////////// +// Company: +// Engineer: +// +// Create Date: 15:18:53 06/03/2015 +// Design Name: +// Module Name: ps2_keyb +// Project Name: +// Target Devices: +// Tool versions: +// Description: +// +// Dependencies: +// +// Revision: +// Revision 0.01 - File Created +// Additional Comments: +// +////////////////////////////////////////////////////////////////////////////////// +module ps2_keyb( + input wire clk, + inout wire clkps2, + inout wire dataps2, + //--------------------------------- + input wire [8:0] rows, + output wire [7:0] cols, + output wire rst_out_n, + output wire nmi_out_n, + output wire mrst_out_n, + output wire [1:0] user_toggles, + //--------------------------------- + input wire [7:0] zxuno_addr, + input wire zxuno_regrd, + input wire zxuno_regwr, + input wire regaddr_changed, + input wire [7:0] din, + output wire [7:0] keymap_dout, + output wire oe_n_keymap, + output wire [7:0] scancode_dout, + output wire oe_n_scancode, + output reg [7:0] kbstatus_dout, + output wire oe_n_kbstatus + ); + + parameter SCANCODE = 8'h04; + parameter KBSTATUS = 8'h05; + parameter KEYMAP = 8'h07; + + wire master_reset, user_reset, user_nmi; + assign mrst_out_n = ~master_reset; + assign rst_out_n = ~user_reset; + assign nmi_out_n = ~user_nmi; + + assign oe_n_keymap = ~(zxuno_addr == KEYMAP && zxuno_regrd == 1'b1); + assign oe_n_scancode = ~(zxuno_addr == SCANCODE && zxuno_regrd == 1'b1); + assign oe_n_kbstatus = ~(zxuno_addr == KBSTATUS && zxuno_regrd == 1'b1); + + wire [7:0] kbcode; + wire ps2busy; + wire kberror; + wire nueva_tecla; + wire extended; + wire released; + assign scancode_dout = kbcode; + + /* + | BSY | x | x | x | ERR | RLS | EXT | PEN | + */ + reg reading_kbstatus = 1'b0; + always @(posedge clk) begin + kbstatus_dout[7:1] <= {ps2busy, 3'b000, kberror, released, extended}; + if (nueva_tecla == 1'b1) + kbstatus_dout[0] <= 1'b1; + if (oe_n_kbstatus == 1'b0) + reading_kbstatus <= 1'b1; + else if (reading_kbstatus == 1'b1) begin + kbstatus_dout[0] <= 1'b0; + reading_kbstatus <= 1'b0; + end + end + + ps2_port lectura_de_teclado ( + .clk(clk), + .enable_rcv(~ps2busy), + .kb_or_mouse(1'b0), + .ps2clk_ext(clkps2), + .ps2data_ext(dataps2), + .kb_interrupt(nueva_tecla), + .scancode(kbcode), + .released(released), + .extended(extended) + ); + + scancode_to_sam traductor ( + .clk(clk), + .rst(1'b0), + .scan_received(nueva_tecla), + .scan(kbcode), + .extended(extended), + .released(released), + .sam_row(rows), + .sam_col(cols), + .master_reset(master_reset), + .user_reset(user_reset), + .user_nmi(user_nmi), + .user_toggles(user_toggles), + .din(din), + .dout(keymap_dout), + .cpuwrite(zxuno_addr == KEYMAP && zxuno_regwr == 1'b1), + .cpuread(zxuno_addr == KEYMAP && zxuno_regrd == 1'b1), + .rewind(regaddr_changed == 1'b1 && zxuno_addr == KEYMAP) + ); + + ps2_host_to_kb escritura_a_teclado ( + .clk(clk), + .ps2clk_ext(clkps2), + .ps2data_ext(dataps2), + .data(din), + .dataload(zxuno_addr == SCANCODE && zxuno_regwr== 1'b1), + .ps2busy(ps2busy), + .ps2error(kberror) + ); +endmodule diff --git a/cores/SamCoupe/ps2_port.v b/cores/SamCoupe/ps2_port.v new file mode 100644 index 0000000..039a59f --- /dev/null +++ b/cores/SamCoupe/ps2_port.v @@ -0,0 +1,275 @@ +`timescale 1ns / 1ps +`default_nettype none + +////////////////////////////////////////////////////////////////////////////////// +// Company: +// Engineer: +// +// Create Date: 20:16:31 12/26/2014 +// Design Name: +// Module Name: ps2_port +// Project Name: +// Target Devices: +// Tool versions: +// Description: +// +// Dependencies: +// +// Revision: +// Revision 0.01 - File Created +// Additional Comments: +// +////////////////////////////////////////////////////////////////////////////////// +module ps2_port ( + input wire clk, // se recomienda 1 MHz <= clk <= 600 MHz + input wire enable_rcv, // habilitar la maquina de estados de recepcion + input wire kb_or_mouse, // 0: kb, 1: mouse + input wire ps2clk_ext, + input wire ps2data_ext, + output wire kb_interrupt, // a 1 durante 1 clk para indicar nueva tecla recibida + output reg [7:0] scancode, // make o breakcode de la tecla + output wire released, // soltada=1, pulsada=0 + output wire extended // extendida=1, no extendida=0 + ); + + `define RCVSTART 2'b00 + `define RCVDATA 2'b01 + `define RCVPARITY 2'b10 + `define RCVSTOP 2'b11 + + reg [7:0] key = 8'h00; + + // Fase de sincronizacion de señales externas con el reloj del sistema + reg [1:0] ps2clk_synchr; + reg [1:0] ps2dat_synchr; + wire ps2clk = ps2clk_synchr[1]; + wire ps2data = ps2dat_synchr[1]; + always @(posedge clk) begin + ps2clk_synchr[0] <= ps2clk_ext; + ps2clk_synchr[1] <= ps2clk_synchr[0]; + ps2dat_synchr[0] <= ps2data_ext; + ps2dat_synchr[1] <= ps2dat_synchr[0]; + end + + // De-glitcher. Sólo detecto flanco de bajada + reg [15:0] negedgedetect = 16'h0000; + always @(posedge clk) begin + negedgedetect <= {negedgedetect[14:0], ps2clk}; + end + wire ps2clkedge = (negedgedetect == 16'hF000)? 1'b1 : 1'b0; + + // Paridad instantánea de los bits recibidos + wire paritycalculated = ^key; + + // Contador de time-out. Al llegar a 65536 ciclos sin que ocurra + // un flanco de bajada en PS2CLK, volvemos al estado inicial + reg [15:0] timeoutcnt = 16'h0000; + + reg [1:0] state = `RCVSTART; + reg [1:0] regextended = 2'b00; + reg [1:0] regreleased = 2'b00; + reg rkb_interrupt = 1'b0; + assign released = regreleased[1]; + assign extended = regextended[1]; + assign kb_interrupt = rkb_interrupt; + + always @(posedge clk) begin + if (rkb_interrupt == 1'b1) begin + rkb_interrupt <= 1'b0; + end + if (ps2clkedge && enable_rcv) begin + timeoutcnt <= 16'h0000; + case (state) + `RCVSTART: begin + if (ps2data == 1'b0) begin + state <= `RCVDATA; + key <= 8'h80; + end + end + `RCVDATA: begin + key <= {ps2data, key[7:1]}; + if (key[0] == 1'b1) begin + state <= `RCVPARITY; + end + end + `RCVPARITY: begin + if (ps2data^paritycalculated == 1'b1) begin + state <= `RCVSTOP; + end + else begin + state <= `RCVSTART; + end + end + `RCVSTOP: begin + state <= `RCVSTART; + if (ps2data == 1'b1) begin + scancode <= key; + if (kb_or_mouse == 1'b1) begin + rkb_interrupt <= 1'b1; // no se requiere mirar E0 o F0 + end + else begin + if (key == 8'hE0) begin + regextended <= 2'b01; + end + else if (key == 8'hF0) begin + regreleased <= 2'b01; + end + else begin + regextended <= {regextended[0], 1'b0}; + regreleased <= {regreleased[0], 1'b0}; + rkb_interrupt <= 1'b1; + end + end + end + end + default: state <= `RCVSTART; + endcase + end + else begin + timeoutcnt <= timeoutcnt + 1; + if (timeoutcnt == 16'hFFFF) begin + state <= `RCVSTART; + end + end + end +endmodule + + +module ps2_host_to_kb ( + input wire clk, // se recomienda 1 MHz <= clk <= 600 MHz + inout wire ps2clk_ext, + inout wire ps2data_ext, + input wire [7:0] data, + input wire dataload, + output wire ps2busy, + output wire ps2error + ); + + `define PULLCLKLOW 3'b000 + `define PULLDATALOW 3'b001 + `define SENDDATA 3'b010 + `define SENDPARITY 3'b011 + `define RCVACK 3'b100 + `define RCVIDLE 3'b101 + `define SENDFINISHED 3'b110 + + reg busy = 1'b0; + reg error = 1'b0; + assign ps2busy = busy; + assign ps2error = error; + + // Fase de sincronizacion de señales externas con el reloj del sistema + reg [1:0] ps2clk_synchr; + reg [1:0] ps2dat_synchr; + wire ps2clk = ps2clk_synchr[1]; + wire ps2data_in = ps2dat_synchr[1]; + always @(posedge clk) begin + ps2clk_synchr[0] <= ps2clk_ext; + ps2clk_synchr[1] <= ps2clk_synchr[0]; + ps2dat_synchr[0] <= ps2data_ext; + ps2dat_synchr[1] <= ps2dat_synchr[0]; + end + + // De-glitcher. Sólo detecto flanco de bajada + reg [15:0] edgedetect = 16'h0000; + always @(posedge clk) begin + edgedetect <= {edgedetect[14:0], ps2clk}; + end + wire ps2clknedge = (edgedetect == 16'hF000)? 1'b1 : 1'b0; + wire ps2clkpedge = (edgedetect == 16'h0FFF)? 1'b1 : 1'b0; + + // Contador de time-out. Al llegar a 65536 ciclos sin que ocurra + // un flanco de bajada en PS2CLK, volvemos al estado inicial + reg [15:0] timeoutcnt = 16'h0000; + + reg [2:0] state = `SENDFINISHED; + reg [7:0] shiftreg = 8'h00; + reg [2:0] cntbits = 3'd0; + + // Dato a enviar se guarda en rdata + reg [7:0] rdata = 8'h00; + + // Paridad instantánea de los bits a enviar + wire paritycalculated = ~(^rdata); + + always @(posedge clk) begin + // Carga de rdata desde el exterior + if (dataload) begin + rdata <= data; + busy <= 1'b1; + error <= 1'b0; + timeoutcnt <= 16'h0000; + state <= `PULLCLKLOW; + end + + if (!ps2clknedge) begin + timeoutcnt <= timeoutcnt + 1; + if (timeoutcnt == 16'hFFFF && state != `SENDFINISHED) begin + error <= 1'b1; + state <= `SENDFINISHED; + end + end + + case (state) + `PULLCLKLOW: begin // 40000 cuentas es poco más de 10ms + if (timeoutcnt >= 16'd40000) begin + state <= `PULLDATALOW; + shiftreg <= rdata; + cntbits <= 3'd0; + timeoutcnt <= 16'h0000; + end + end + `PULLDATALOW: begin + if (ps2clknedge) begin + state <= `SENDDATA; + timeoutcnt <= 16'h0000; + end + end + `SENDDATA: begin + if (ps2clknedge) begin + timeoutcnt <= 16'h0000; + shiftreg <= {1'b0, shiftreg[7:1]}; + cntbits <= cntbits + 1; + if (cntbits == 3'd7) + state <= `SENDPARITY; + end + end + `SENDPARITY: begin + if (ps2clknedge) begin + state <= `RCVIDLE; + timeoutcnt <= 16'h0000; + end + end + `RCVIDLE: begin + if (ps2clknedge) begin + state <= `RCVACK; + timeoutcnt <= 16'h0000; + end + end + `RCVACK: begin + if (ps2clknedge) begin + state <= `SENDFINISHED; + timeoutcnt <= 16'h0000; + end + end + `SENDFINISHED: begin + busy <= 1'b0; + timeoutcnt <= 16'h0000; + end + default: begin + timeoutcnt <= timeoutcnt + 1; + if (timeoutcnt == 16'hFFFF && state != `SENDFINISHED) begin + error <= 1'b1; + state <= `SENDFINISHED; + end + end + endcase + end + + assign ps2data_ext = (state == `PULLCLKLOW || state == `PULLDATALOW) ? 1'b0 : + (state == `SENDDATA && shiftreg[0] == 1'b0) ? 1'b0 : + (state == `SENDPARITY && paritycalculated == 1'b0) ? 1'b0 : // si lo que se va a enviar es un 1 + 1'bZ; // no se manda, sino que se pone la línea a alta impedancia + assign ps2clk_ext = (state == `PULLCLKLOW) ? 1'b0 : + 1'bZ; +endmodule diff --git a/cores/SamCoupe/ram.v b/cores/SamCoupe/ram.v index d9ca7e5..ba56e85 100644 --- a/cores/SamCoupe/ram.v +++ b/cores/SamCoupe/ram.v @@ -140,9 +140,9 @@ module ram_dual_port ( sram_we_n = 1'b1; end else begin - sram_a = cpuramaddr; + sram_a = cpuramaddr; data_to_cpu = sram_d; - if (state == CPU5 || state == CPU6) + if (state == CPU6 || state == CPU5) sram_we_n = 1'b0; else sram_we_n = 1'b1; diff --git a/cores/SamCoupe/samcoupe.v b/cores/SamCoupe/samcoupe.v index f87e9fc..14c1aff 100644 --- a/cores/SamCoupe/samcoupe.v +++ b/cores/SamCoupe/samcoupe.v @@ -36,8 +36,8 @@ module samcoupe ( output wire audio_out_left, output wire audio_out_right, // PS/2 keyoard interface - input wire clkps2, - input wire dataps2, + inout wire clkps2, + inout wire dataps2, // SRAM interface output wire [18:0] sram_addr, inout wire [7:0] sram_data, @@ -82,7 +82,7 @@ module samcoupe ( // Audio signals wire mic, beep; - assign audio_out_left = mic; + assign audio_out_left = ear; assign audio_out_right = beep; // MUX from memory/devices to Z80 data bus @@ -138,7 +138,7 @@ module samcoupe ( .mic(mic), .beep(beep), // keyboard I/O - .keyboard({3'b111,kbcolumns[4:0]}), + .keyboard(kbcolumns), .rdmsel(rdmsel), // disk I/O .disc1_n(), @@ -191,17 +191,41 @@ module samcoupe ( .sram_d(sram_data) ); - ps2k el_teclado ( - .clk(clk6), - .ps2clk(clkps2), - .ps2data(dataps2), - .rows(kbrows[7:0]), - .cols(kbcolumns[4:0]), - .joy(), // Implementación joystick kempston en teclado numerico - .scancode(), // El scancode original desde el teclado - .rst(kb_rst_n), // esto son salidas, no entradas - .nmi(kb_nmi_n), // Señales de reset y NMI - .mrst() // generadas por pulsaciones especiales del teclado - ); +// ps2k el_teclado ( +// .clk(clk6), +// .ps2clk(clkps2), +// .ps2data(dataps2), +// .rows(kbrows[7:0]), +// .cols(kbcolumns[4:0]), +// .joy(), // Implementación joystick kempston en teclado numerico +// .scancode(), // El scancode original desde el teclado +// .rst(kb_rst_n), // esto son salidas, no entradas +// .nmi(kb_nmi_n), // Señales de reset y NMI +// .mrst() // generadas por pulsaciones especiales del teclado +// ); + ps2_keyb el_teclado ( + .clk(clk6), + .clkps2(clkps2), + .dataps2(dataps2), + //--------------------------------- + .rows(kbrows), + .cols(kbcolumns), + .rst_out_n(kb_rst_n), + .nmi_out_n(kb_nmi_n), + .mrst_out_n(), + .user_toggles(), + //--------------------------------- + .zxuno_addr(8'h00), + .zxuno_regrd(1'b0), + .zxuno_regwr(1'b0), + .regaddr_changed(1'b0), + .din(data_from_cpu), + .keymap_dout(), + .oe_n_keymap(), + .scancode_dout(), + .oe_n_scancode(), + .kbstatus_dout(), + .oe_n_kbstatus() + ); endmodule diff --git a/cores/SamCoupe/samcoupe.xise b/cores/SamCoupe/samcoupe.xise index 00592b0..d01185e 100644 --- a/cores/SamCoupe/samcoupe.xise +++ b/cores/SamCoupe/samcoupe.xise @@ -43,14 +43,6 @@ - - - - - - - - @@ -81,6 +73,18 @@ + + + + + + + + + + + + @@ -107,7 +111,7 @@ - + diff --git a/cores/SamCoupe/scancode_to_speccy.v b/cores/SamCoupe/scancode_to_speccy.v new file mode 100644 index 0000000..dc3e81f --- /dev/null +++ b/cores/SamCoupe/scancode_to_speccy.v @@ -0,0 +1,269 @@ +`timescale 1ns / 1ps +`default_nettype none +////////////////////////////////////////////////////////////////////////////////// +// Company: +// Engineer: +// +// Create Date: 17:42:40 06/01/2015 +// Design Name: +// Module Name: scancode_to_speccy +// Project Name: +// Target Devices: +// Tool versions: +// Description: +// +// Dependencies: +// +// Revision: +// Revision 0.01 - File Created +// Additional Comments: +// +////////////////////////////////////////////////////////////////////////////////// +module scancode_to_sam ( + input wire clk, // el mismo clk de ps/2 + input wire rst, + input wire scan_received, + input wire [7:0] scan, + input wire extended, + input wire released, + //------------------------ + input wire [8:0] sam_row, + output wire [7:0] sam_col, + output wire user_reset, + output wire master_reset, + output wire user_nmi, + output wire [1:0] user_toggles, + //------------------------ + input wire [7:0] din, + output reg [7:0] dout, + input wire cpuwrite, + input wire cpuread, + input wire rewind + ); + + // las teclas del SAM. Se inicializan a "no pulsadas". + reg [7:0] row[0:8]; + initial begin + row[0] = 8'hFF; + row[1] = 8'hFF; + row[2] = 8'hFF; + row[3] = 8'hFF; + row[4] = 8'hFF; + row[5] = 8'hFF; + row[6] = 8'hFF; + row[7] = 8'hFF; + row[8] = 8'hFF; + end + + // El gran mapa de teclado y sus registros de acceso + reg [7:0] keymap[0:16383]; // 16K x 8 bits + reg [13:0] addr = 14'h0000; + reg [13:0] cpuaddr = 14'h0000; // Dirección E/S desde la CPU. Se autoincrementa en cada acceso + initial begin + $readmemh ("keyb_es_hex.txt", keymap); + end + + reg [3:0] keyrow1 = 4'h0; + reg [7:0] keycol1 = 8'h00; + reg [3:0] keyrow2 = 4'h0; + reg [7:0] keycol2 = 8'h00; + reg [2:0] keymodifiers = 3'b000; + reg [2:0] signalstate = 3'b000; + reg [1:0] togglestate = 2'b00; + + reg rmaster_reset = 1'b0, ruser_reset = 1'b0, ruser_nmi = 1'b0; + reg [1:0] ruser_toggles = 2'b00; + assign master_reset = rmaster_reset; + assign user_reset = ruser_reset; + assign user_nmi = ruser_nmi; + assign user_toggles = ruser_toggles; + + // Asi funciona la matriz de teclado cuando se piden semifilas + // desde la CPU. + // Un always @* hubiera quedado más claro en la descripción + // pero por algun motivo, el XST no lo ha admitido en este caso + assign sam_col = ((sam_row[0] == 1'b0)? row[0] : 8'hFF) & + ((sam_row[1] == 1'b0)? row[1] : 8'hFF) & + ((sam_row[2] == 1'b0)? row[2] : 8'hFF) & + ((sam_row[3] == 1'b0)? row[3] : 8'hFF) & + ((sam_row[4] == 1'b0)? row[4] : 8'hFF) & + ((sam_row[5] == 1'b0)? row[5] : 8'hFF) & + ((sam_row[6] == 1'b0)? row[6] : 8'hFF) & + ((sam_row[7] == 1'b0)? row[7] : 8'hFF) & + ((sam_row[8] == 1'b0)? row[8] : 8'hFF); + + reg [2:0] modifiers = 3'b000; + reg [3:0] keycount = 4'b0000; + + parameter + CLEANMATRIX = 4'd0, + IDLE = 4'd1, + ADDR0PUT = 4'd2, + ADDR1PUT = 4'd3, + ADDR2PUT = 4'd4, + ADDR3PUT = 4'd5, + TRANSLATE1 = 4'd6, + TRANSLATE2 = 4'd7, + TRANSLATE3 = 4'd8, + CPUTIME = 4'd9, + CPUREAD = 4'd10, + CPUWRITE = 4'd11, + CPUINCADD = 4'd12, + UPDCOUNTERS1= 4'd13, + UPDCOUNTERS2= 4'd14; + + reg [3:0] state = CLEANMATRIX; + reg key_is_pending = 1'b0; + + always @(posedge clk) begin + if (scan_received == 1'b1) + key_is_pending <= 1'b1; + if (rst == 1'b1) + state <= CLEANMATRIX; + else begin + case (state) + CLEANMATRIX: begin + modifiers <= 3'b000; + keycount <= 4'b0000; + row[0] <= 8'hFF; + row[1] <= 8'hFF; + row[2] <= 8'hFF; + row[3] <= 8'hFF; + row[4] <= 8'hFF; + row[5] <= 8'hFF; + row[6] <= 8'hFF; + row[7] <= 8'hFF; + row[8] <= 8'hFF; + state <= IDLE; + end + IDLE: begin + if (key_is_pending == 1'b1) begin + addr <= {modifiers, extended, scan, 2'b00}; // 1 scan tiene 8 bits + 1 bit para indicar scan extendido + 3 bits para el modificador usado + state <= ADDR0PUT; + key_is_pending <= 1'b0; + end + else if (cpuread == 1'b1 || cpuwrite == 1'b1 || rewind == 1'b1) + state <= CPUTIME; + end + ADDR0PUT: begin + {keyrow1,keycol1[7:4]} <= keymap[addr]; + addr <= {modifiers, extended, scan, 2'b01}; + state <= ADDR1PUT; + end + ADDR1PUT: begin + {keycol1[3:0],keyrow2} <= keymap[addr]; + addr <= {modifiers, extended, scan, 2'b10}; + state <= ADDR2PUT; + end + ADDR2PUT: begin + {keycol2} <= keymap[addr]; + addr <= {modifiers, extended, scan, 2'b11}; + state <= ADDR3PUT; + end + ADDR3PUT: begin + {signalstate,keymodifiers,togglestate} <= keymap[addr]; + state <= TRANSLATE1; + end + TRANSLATE1: begin + // Actualiza las 8 semifilas del teclado con la primera tecla + if (~released) begin + if (keyrow1[3] == 1'b1) + row[8] <= row[8] & ~keycol1; + else + row[keyrow1[2:0]] <= row[keyrow1[2:0]] & ~keycol1; + end + else begin + if (keyrow1[3] == 1'b1) + row[8] <= row[8] | keycol1; + else + row[keyrow1[2:0]] <= row[keyrow1[2:0]] | keycol1; + end + state <= TRANSLATE2; + end + TRANSLATE2: begin + // Actualiza las 8 semifilas del teclado con la segunda tecla + if (~released) begin + if (keyrow2[3] == 1'b1) + row[8] <= row[8] & ~keycol2; + else + row[keyrow2[2:0]] <= row[keyrow2[2:0]] & ~keycol2; + end + else begin + if (keyrow2[3] == 1'b1) + row[8] <= row[8] | keycol2; + else + row[keyrow2[2:0]] <= row[keyrow2[2:0]] | keycol2; + end + state <= TRANSLATE3; + end + TRANSLATE3: begin + // Actualiza modificadores + if (~released) + modifiers <= modifiers | keymodifiers; + else + modifiers <= modifiers & ~keymodifiers; + + // Y de la misma forma tendria que actualizar resets y los user_toogles + if (~released) + {rmaster_reset,ruser_reset,ruser_nmi} <= {rmaster_reset,ruser_reset,ruser_nmi} | signalstate; + else + {rmaster_reset,ruser_reset,ruser_nmi} <= {rmaster_reset,ruser_reset,ruser_nmi} & ~signalstate; + + if (~released) + ruser_toggles <= ruser_toggles | togglestate; + else + ruser_toggles <= ruser_toggles & ~togglestate; + + //state <= UPDCOUNTERS1; + state <= IDLE; + end + CPUTIME: begin + if (rewind == 1'b1) begin + cpuaddr = 14'h0000; + state <= IDLE; + end + else if (cpuread == 1'b1) begin + addr <= cpuaddr; + state <= CPUREAD; + end + else if (cpuwrite == 1'b1) begin + addr <= cpuaddr; + state <= CPUWRITE; + end + else + state <= IDLE; + end + CPUREAD: begin // CPU wants to read from keymap + dout <= keymap[addr]; + state <= CPUINCADD; + end + CPUWRITE: begin + keymap[addr] <= din; + state <= CPUINCADD; + end + CPUINCADD: begin + if (cpuread == 1'b0 && cpuwrite == 1'b0) begin + cpuaddr <= cpuaddr + 1; + state <= IDLE; + end + end + // else if (state == UPDCOUNTERS1) begin + // if (~released) + // keycount <= keycount + 4'b0001; // suma 1 al contador de pulsaciones + // else if (released && keycount != 4'b0000) + // keycount <= keycount + 4'b1111; // o le resta 1 al contador de pulsaciones, pero sin bajar de 0 + // state <= UPDCOUNTERS2; + // end + // else if (state == UPDCOUNTERS2) begin + // if (keycount == 4'b0000) // si es la última tecla soltada, limpia la matriz de teclado del Spectrum + // state <= CLEANMATRIX; + // else + // state <= IDLE; + // end + default: begin + state <= IDLE; + end + endcase + end + end +endmodule diff --git a/cores/SamCoupe/tld_sam.v b/cores/SamCoupe/tld_sam.v index 5d6a3c0..6b88e80 100644 --- a/cores/SamCoupe/tld_sam.v +++ b/cores/SamCoupe/tld_sam.v @@ -38,14 +38,10 @@ module tld_sam ( inout wire [7:0] sram_data, output wire sram_we_n, // PS/2 keyoard interface - input wire clkps2, - input wire dataps2 + inout wire clkps2, + inout wire dataps2 ); - // Interface with ROM - wire [14:0] romaddr; - wire [7:0] data_from_rom; - // Interface with RAM wire [18:0] ramaddr; wire [7:0] data_from_ram; diff --git a/cores/SamCoupe/tv80_core.v b/cores/SamCoupe/tv80_core.v index e3f7d24..13a2ad6 100644 --- a/cores/SamCoupe/tv80_core.v +++ b/cores/SamCoupe/tv80_core.v @@ -22,6 +22,8 @@ // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +`define TV80_REFRESH + module tv80_core (/*AUTOARG*/ // Outputs m1_n, iorq, no_read, write, rfsh_n, halt_n, busak_n, A, dout, mc,