浏览代码

Add sdcard and sysclock units; reshuffle address map

Add sdcard and sysclock (local clock that can follow the RTC but be
accessed faster for filesystem operations) units.

It turns out that RISC-V has 12 bits for an address offset, not 11, so
give each iodev one more address bit (highly useful for the sdcard
unit.)

Some reorganizations in the firmware code.
H. Peter Anvin 3 年之前
父节点
当前提交
6a406133f0
共有 24 个文件被更改,包括 3962 次插入1325 次删除
  1. 4 1
      fpga/max80.qsf
  2. 32 13
      fpga/max80.sv
  3. 二进制
      fpga/output_files/max80.jbc
  4. 二进制
      fpga/output_files/max80.jic
  5. 二进制
      fpga/output_files/max80.pof
  6. 二进制
      fpga/output_files/max80.sof
  7. 101 73
      fpga/sdcard.sv
  8. 141 0
      fpga/sysclock.sv
  9. 5 6
      fpga/tty.sv
  10. 1 0
      fw/.gitignore
  11. 1 1
      fw/Makefile
  12. 2362 1199
      fw/boot.mif
  13. 2 0
      fw/fatfs/orig/README
  14. 301 0
      fw/fatfs/orig/ffconf.h
  15. 6 6
      fw/fatfs/source/ffconf.h
  16. 8 0
      fw/fw.h
  17. 18 1
      fw/head.S
  18. 10 4
      fw/hello.c
  19. 71 0
      fw/io.h
  20. 58 21
      fw/iodev.h
  21. 24 0
      fw/sbrk.c
  22. 761 0
      fw/sdcard.c
  23. 1 0
      fw/sys.h
  24. 55 0
      fw/systime.h

+ 4 - 1
fpga/max80.qsf

@@ -212,6 +212,7 @@ set_instance_assignment -name WEAK_PULL_UP_RESISTOR OFF -to altera_reserved_tms
 
 set_global_assignment -name SYSTEMVERILOG_FILE tty.sv
 set_global_assignment -name SYSTEMVERILOG_FILE sdcard.sv
+set_global_assignment -name SYSTEMVERILOG_FILE sysclock.sv
 set_global_assignment -name VERILOG_FILE ip/fastmem_ip.v
 set_global_assignment -name SYSTEMVERILOG_FILE fast_mem.sv
 set_global_assignment -name MIF_FILE ../fw/boot.mif
@@ -238,4 +239,6 @@ set_global_assignment -name VERILOG_FILE ip/ddufifo.v
 
 set_global_assignment -name OCP_HW_EVAL DISABLE
 set_global_assignment -name TIMING_ANALYZER_DO_REPORT_TIMING ON
-set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
+
+
+set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top

+ 32 - 13
fpga/max80.sv

@@ -34,8 +34,8 @@ module max80 (
 	      output	    abc_int800_x, // System INT request (ABC800)
 	      output	    abc_nmi_x, // System NMI request (ABC800)
 	      output	    abc_xm_x, // System memory override (ABC800)
-	      // Master/slave control
-	      output	    abc_master, // 1 = master, 0 = slave
+	      // Host/device control
+	      output	    abc_master, // 1 = host, 0 = device
 	      output	    abc_a_oe,
 	      // Bus isolation
 	      output	    abc_d_ce_n,
@@ -232,6 +232,7 @@ module max80 (
 		  );
 
    // ABC bus
+   assign abc_master = 1'b0;	// Only device mode supported
 
    // On ABC800, only one of XINPSTB# or XOUTPSTB# will be active;
    // on ABC80 they will either be 00 or ZZ; in the latter case pulled
@@ -373,8 +374,6 @@ module max80 (
    reg  [31:0]		      cpu_mem_rdata;
    wire			      cpu_mem_ready;
 
-   wire			      cpu_mem_read = cpu_mem_valid & ~|cpu_mem_wstrb;
-
    wire                       cpu_la_read;
    wire                       cpu_la_write;
    wire [31:0]                cpu_la_addr;
@@ -392,11 +391,13 @@ module max80 (
    //  1 - Reset
    //  2 - SPI->SDRAM downloader
    //  3 - Serial port
+   //  4 - SD card
+   //  5 - system local clock (not RTC)
    //
    // A device has IRQ (devno)+16 if it needs an interrupt.
    //
 
-   wire [15:0] iodev = cpu_mem_quad[3] << cpu_mem_addr[9:6];
+   wire [15:0] iodev = cpu_mem_quad[3] << cpu_mem_addr[10:7];
    tri0 [15:0] iodev_irq;	// tri0: if nothing is driving, value is 0
 
    //
@@ -419,7 +420,7 @@ module max80 (
    wire        sdram_req = cpu_mem_quad[1] & ~sdram_acked;
 
    sdram sdram (
-		.rst_n    ( rst_n & ~iodev[12] ),
+		.rst_n    ( rst_n ),
 		.clk      ( sdram_clk ), // Internal clock
 		.out_clk  ( sdram_out_clk ), // External clock (phase shifted)
 
@@ -495,6 +496,10 @@ module max80 (
 	      .ENABLE_IRQ ( 1 ),
 	      .ENABLE_IRQ_QREGS ( 1 ),
 	      .ENABLE_IRQ_TIMER ( 1 ),
+	      .LATCHED_IRQ ( 32'h0000_0007 ), // Device IRQs are level
+	      .MASKED_IRQ  ( 32'h0000_fff8 ), // Unused IRQs for now
+	      .PROGADDR_RESET ( 32'h0000_0000 ),
+	      .PROGADDR_IRQ ( 32'h0000_0020 ),
 	      .REGS_INIT_ZERO ( 1 ),
 	      .STACKADDR ( 32'h4 << cpu_fast_mem_bits )
 	      )
@@ -692,26 +697,40 @@ module max80 (
 		  .sd_sclk ( sd_clk ),
 		  .sd_do   ( sd_dat[0] ),
 		  .sd_cd_n ( 1'b0 ),
-		  .sd_we_n ( 1'b0 ),
 
 		  .wdata   ( cpu_mem_wdata ),
 		  .rdata   ( sdcard_rdata ),
 		  .valid   ( iodev[4] ),
 		  .wstrb   ( cpu_mem_wstrb ),
-		  .addr    ( cpu_mem_addr[3:2] ),
+		  .addr    ( cpu_mem_addr[6:2] ),
 		  .wait_n  ( iodev_wait_n[4] )
 		  );
    assign sd_dat[2:1] = 2'bzz;
 
+   // System local clock (not an RTC, but settable from one)
+   wire [31:0] sysclock_rdata;
+
+   sysclock sysclock (
+		      .rst_n ( rst_n ),
+		      .sys_clk ( sys_clk ),
+		      .rtc_clk ( rtc_32khz ),
+
+		      .wdata   ( cpu_mem_wdata ),
+		      .rdata   ( sysclock_rdata ),
+		      .valid   ( iodev[5] ),
+		      .wstrb   ( cpu_mem_wstrb ),
+		      .addr    ( cpu_mem_addr[2] )
+		      );
    //
    // I/O device input data MUX
    //
    always @(*)
-     case ( cpu_mem_addr[9:6] )
-       4'h0:    iodev_rdata  = { 29'b0, led_q };
-       4'h2:    iodev_rdata  = { 31'b0, rom_done_q };
-       4'h3:	iodev_rdata  = tty_rdata;
-       4'h4:    iodev_rdata  = sdcard_rdata;
+     case ( cpu_mem_addr[10:7] )
+       4'd0:    iodev_rdata  = { 29'b0, led_q };
+       4'd2:    iodev_rdata  = { 31'b0, rom_done_q };
+       4'd3:	iodev_rdata  = tty_rdata;
+       4'd4:    iodev_rdata  = sdcard_rdata;
+       4'd5:    iodev_rdata  = sysclock_rdata;
        default: iodev_rdata  = 32'h0;
      endcase
 

二进制
fpga/output_files/max80.jbc


二进制
fpga/output_files/max80.jic


二进制
fpga/output_files/max80.pof


二进制
fpga/output_files/max80.sof


+ 101 - 73
fpga/sdcard.sv

@@ -18,23 +18,21 @@
 //
 
 module sdcard (
-	       input		 rst_n, // Global reset
-	       input		 clk, // System clock (84 MHz)
+	       input 		 rst_n, // Global reset
+	       input 		 clk, // System clock (84 MHz)
 
-	       inout		 sd_cs_n, // SD card CS# (CD, DAT3)
-	       inout		 sd_di, // SD card DI (MOSI, CMD)
-	       inout		 sd_sclk, // SD card CLK (SCLK)
-	       inout		 sd_do, // SD card SO (MISO, DAT0)
+	       output 		 sd_cs_n, // SD card CS# (CD, DAT3)
+	       output 		 sd_di, // SD card DI (MOSI, CMD)
+	       output 		 sd_sclk, // SD card CLK (SCLK)
+	       input 		 sd_do, // SD card SO (MISO, DAT0)
+	       input 		 sd_cd_n, // Card detect
 
-	       input		 sd_cd_n, // SD socket CD# (Card Detect) switch
-	       input		 sd_we_n, // SD socket WE# (Write Enable) switch
-
-	       input [31:0]	 wdata, // CPU data out (CPU->controller)
+	       input [31:0] 	 wdata, // CPU data out (CPU->controller)
 	       output reg [31:0] rdata, // CPU data in (controller->CPU)
-	       input		 valid, // Memory valid
-	       input [3:0]	 wstrb, // Write strobes
-	       input [1:0]	 addr, // Address bits
-	       output		 wait_n	// Hold mem_ready
+	       input 		 valid, // Memory valid
+	       input [3:0] 	 wstrb, // Write strobes
+	       input [4:0] 	 addr, // Address bits
+	       output 		 wait_n	// Hold mem_ready
 	       );
 
    // ------------------------------------------------------------------------
@@ -48,37 +46,47 @@ module sdcard (
    //  The actual connection to the CPU bus shifts the addresses left
    //  by two so that dword accesses can be done.
    //
-   //  Write, A[1:0]:
-   //  00	- control register:
+   //  Write:
+   //  00000	- control register:
    //             [6:0] - speed divider (CPU_HZ/(2*(divider+1)))
    //                 7 - CS# active
-   //                 8 - clear CRC registers
-   //                 9 - select CRC register inputs (0 = input, 1 = output)
-   //  01	- load output shift register from the CPU
-   //  10       - start transaction without loading
-   //  11       - load output shift register and start transaction
+   //                 8 - clear read CRC registers
+   //		      9 - clear write CRC registers
+   //  x0xxx	- reserved
+   //  x1e00     - load shift register but don't start transaction
+   //  x1e01     - load shift register and start transaction, 8 bits
+   //  x1e10     - load shift register and start transaction, 16 bits
+   //  x1e11     - load shift register and start transaction, 32 bits
+   //  11xxx     - clear write CRC registers
+   //  e = endian; 0 = wire byte order; 1 = bigendian byte order
    //
    //  Note: the triggered bus transaction size is set by byte enables.
    //  The output latch should be written left-aligned (most significant
    //  bytes within a dword); the input latch right-aligned.
    //
-   //  On read, A[1:0]:
-   //  00       - control register
-   //  01       - read input latch
-   //  10       - read CRC7 (in D[7:1], D0 = 1)
-   //  11       - read CRC16
+   //  Read:
+   //  00000	- control register
+   //  00010	-   [7:0] - read CRC7  + final 1 bit
+   //             [31:16] - read CRC16
+   //  00011	-   [7:0] - write CRC7 + final 1 bit
+   //             [31:16] - write CRC16
+   //  x0xxx    - reserved
+   //  x1e00    - read shift register but don't start transaction
+   //  x1e01    - read shift register and start transaction, 8 bits
+   //  x1e10    - read shift register and start transaction, 16 bits
+   //  x1e11    - read shift register and start transaction, 32 bits
+   //  11xxx    - clear read CRC registers
+   //
    // ------------------------------------------------------------------------
 
    reg [31:0] sd_shr_out;
    reg [31:0] sd_shr_in;
+   reg [31:0] sd_shr_in_q;
    reg [4:0]  sd_out_ctr;	// Output bit counter
    reg	      sd_active;	// Transfer in progress
    reg	      sd_active_neg;	// Transfer in progress, first pos clock seen
-   reg        sd_crcsrc;	// CRC generator input
    reg	      sd_crcstb;	// Strobe for CRC generator
    reg	      sd_cs_reg;	// CS# active (positive logic, so inverted)
-   reg [6:0]  sd_crc7;		// CRC-7 generator
-   reg [15:0] sd_crc16;		// CRC-16 generator
    wire       sd_cmd = valid & ~sd_active; // CPU command we can act on
    reg	      sd_cmd_ok;	// Valid CPU command received
    wire       sd_data_out = sd_shr_out[31];
@@ -88,7 +96,6 @@ module sdcard (
    assign     sd_di   = ~sd_cd_n ? sd_data_out : 1'bz;
    assign     sd_sclk = ~sd_cd_n ? sd_clk_out  : 1'bz;
    assign     sd_cs_n = ~sd_cd_n ? ~sd_cs_reg  : 1'bz;
-   assign     sd_do   = 1'bz;	// Always an input
 
    // If we try an action while a bus transaction is in progress,
    // wait.  The register sd_cmd_ok is used to prevent WAIT# from
@@ -142,8 +149,7 @@ module sdcard (
      else
        sd_clk_out <= (sd_clk_out | sd_clk_pos) & ~sd_clk_neg;
 
-   wire [2:0] nwrite = wstrb[3] + wstrb[2] + wstrb[1] + wstrb[0];
-   wire       rstrb = valid & ~|wstrb;
+   reg [1:0]  clear_crc;
 
    always @(negedge rst_n or posedge clk)
      if (~rst_n)
@@ -156,7 +162,8 @@ module sdcard (
 	  sd_out_ctr    <= 5'h0;
 	  sd_crcstb     <= 1'b0;
 	  sd_shr_in     <= 32'hffff_ffff;
-	  sd_crcsrc     <= 1'b0;
+	  sd_shr_in_q   <= 32'hffff_ffff;
+	  clear_crc     <= 2'b11;
        end
      else
        begin
@@ -171,73 +178,94 @@ module sdcard (
 	       sd_shr_out    <= {sd_shr_out[30:0], 1'b1};
 	       sd_active     <= |sd_out_ctr;
 	       sd_active_neg <= |sd_out_ctr;
+	       if (~|sd_out_ctr)
+		 sd_shr_in_q <= sd_shr_in;
 	    end
+
+	  clear_crc <= 2'b00;	   // No clearing by default
 	  sd_crcstb <= sd_clk_pos; // CRCs are computed one cycle after posedge
 
 	  if (sd_cmd)
 	    begin
-	       if (addr[1:0] == 2'b00)
-		 begin
-		    if (wstrb[0]) {sd_cs_reg, sd_clk_div} <= wdata[7:0];
-		    if (wstrb[1]) sd_crcsrc <= wdata[9];
+	       if (addr[4:3] == 2'b11)
+		 clear_crc <= {|wstrb, ~|wstrb};
+	       
+	       casez (addr)
+		 5'b?10??: begin
+		    // Load in host (littleendian) byte order
+		    if (wstrb[3]) sd_shr_out[ 7: 0] <= wdata[31:24];
+		    if (wstrb[2]) sd_shr_out[15: 8] <= wdata[23:16];
+		    if (wstrb[1]) sd_shr_out[23:16] <= wdata[15: 8];
+		    if (wstrb[0]) sd_shr_out[31:24] <= wdata[ 7: 0];
 		 end
-
-	       if (addr[0])
-		 begin
+		 5'b?11??: begin
+		    // Load in SPI (bigendian) byte order
 		    if (wstrb[3]) sd_shr_out[31:24] <= wdata[31:24];
 		    if (wstrb[2]) sd_shr_out[23:16] <= wdata[23:16];
 		    if (wstrb[1]) sd_shr_out[15: 8] <= wdata[15: 8];
 		    if (wstrb[0]) sd_shr_out[ 7: 0] <= wdata[ 7: 0];
 		 end
+		 5'b00000: begin
+		    if (wstrb[0]) {sd_cs_reg, sd_clk_div} <= wdata[7:0];
+		    if (wstrb[1]) clear_crc <= wdata[9:8];
+		 end
+		 default: begin
+		    // do nothing
+		 end
+	       endcase
 
-	       if (addr[1])
+	       // Begin transaction
+	       if (addr[3] & (|addr[1:0]))
 		 begin
-		    sd_active  <= |wstrb;
-		    sd_out_ctr <= { nwrite[1:0], 3'b000 };
+		    sd_active  <= 1'b1;
+		    sd_out_ctr <= { ~addr[0], ~addr[1], 3'b000 };
 		 end
 	    end // if (sd_cmd)
        end // else: !if(~rst_n)
 
-   wire clear_crc = ~rst_n |
-	(sd_cmd & (addr[1:0] == 2'b00) & wstrb[1] & wdata[8]);
-
-   // CRC generators: we have one 7-bit and one 16-bit, shared between
-   // input and output.  The controller CPU has to specify where it wants
-   // the input from by setting A3 properly when starting a bus
-   // transaction (A4 = 1).
+   //
+   // CRC generators: we have two 7-bit and two 16-bit, one each for
+   // input [0] and output [1].
    //
    // The CRC generators run one cycle behind the positive sd_clk strobe.
 
-   wire sd_crcbit = sd_crcsrc ? sd_data_out : sd_shr_in[0];
-   wire sd_crc7in = sd_crcbit ^ sd_crc7[6];
-
-   always @(posedge clk)
-     if (clear_crc)
-       sd_crc7 <= 7'h00;
-     else if (sd_crcstb)
-       sd_crc7 <= {sd_crc7[5:3], sd_crc7[2]^sd_crc7in,
-		   sd_crc7[1:0], sd_crc7in};
+   wire [1:0] sd_crcbit = { sd_data_out, sd_shr_in[0] };
 
-   wire sd_crc16in = sd_crcbit ^ sd_crc16[15];
+   reg  [6:0] sd_crc7 [0:1];	// CRC-7 shift register
+   reg [15:0] sd_crc16[0:1];	// CRC-16 shift register
 
+   localparam  [6:0] crc7_poly  = 7'b000_1001;
+   localparam [15:0] crc16_poly = 16'b0001_0000_0010_0001;
+   
    always @(posedge clk)
-     if (clear_crc)
-       sd_crc16 <= 16'h0000;
-     else if (sd_crcstb)
-       sd_crc16 <= {sd_crc16[14:12], sd_crc16[11]^sd_crc16in,
-		    sd_crc16[10:5], sd_crc16[4]^sd_crc16in,
-		    sd_crc16[3:0], sd_crc16in};
+     for (int i = 0; i < 2; i = i+1)
+       begin
+	  if (clear_crc[i])
+	    begin
+	       sd_crc7[i]  <= 7'h00;
+	       sd_crc16[i] <= 16'h0000;
+	    end
+	  else if (sd_crcstb)
+	    begin
+	       sd_crc7[i]  <= { sd_crc7[i][5:0], 1'b0 }
+			      ^ ({7{sd_crcbit[i]}} & crc7_poly);
+	       sd_crc16[i] <= { sd_crc16[i][14:0], 1'b0 }
+			      ^ ({16{sd_crcbit[i]}} & crc16_poly);
+	    end // else: !if(clear_crc[i])
+       end // for (int i = 0; i < 2; i = i+1)
 
    // Data out MUX
-   // Currently no registers with read side effects
    always @(*)
      begin
-	case (addr)
-	  2'b00: rdata = { 22'b0, sd_crcsrc, 1'b0, sd_cs_reg, sd_clk_div };
-	  2'b01: rdata = sd_shr_in;
-	  2'b10: rdata = { 24'b0, sd_crc7, 1'b1 };
-	  2'b11: rdata = { 16'b0, sd_crc16 };
-	endcase // case (addr)
+	casez (addr)
+	  5'b0_0000: rdata = { 24'b0, sd_cs_reg, sd_clk_div };
+	  5'b0_0010: rdata = { sd_crc16[0], 8'b0, sd_crc7[0], 1'b1 };
+	  5'b0_0011: rdata = { sd_crc16[1], 8'b0, sd_crc7[1], 1'b1 };
+	  5'b?_01??: rdata = { sd_shr_in_q[7:0], sd_shr_in_q[15:8],
+			       sd_shr_in_q[23:16], sd_shr_in_q[31:24] };
+	  5'b?_11??: rdata = sd_shr_in_q;
+	  default:   rdata = 32'hxxxx_xxxx;
+	endcase
      end
 
 endmodule // sdcard

+ 141 - 0
fpga/sysclock.sv

@@ -0,0 +1,141 @@
+//
+// sysclock.sv
+//
+// Very simple unit that keeps track of time in "human" format based
+// on 32 kHz signal from the RTC. The registers have to be set from
+// software, presumably from reading the RTC.
+//
+// Register 0 contains the 2 s granular date and time in FAT filesystem format.
+// Register 1 contains two copies of a 16-bit 32 kHz counter:
+// the upper half contains the current counter, and the lower half is
+// a holding register updated when register 0 is read, and, if written
+// to in adcance, will write the counter when register 0 is written.
+
+module sysclock (
+		input 		  rst_n,
+		input 		  sys_clk,
+		input 		  rtc_clk,
+
+		input 		  valid,
+		input  	  	  addr,
+		output reg [31:0] rdata,
+		input [31:0] 	  wdata,
+		input [3:0] 	  wstrb
+		);
+
+   wire		rtc_clk_sync;
+   reg 		rtc_clk_q;
+   reg 		rtc_clk_stb;
+
+   synchronizer rtc_sync (
+			  .rst_n ( 1'b1 ),
+			  .clk ( sys_clk ),
+			  .d ( rtc_clk ),
+			  .q ( rtc_clk_sync )
+			  );
+
+   always @(posedge sys_clk)
+     begin
+	rtc_clk_q <= rtc_clk_sync;
+	rtc_clk_stb <= rtc_clk_sync & ~rtc_clk_q;
+     end
+
+   function logic [4:0] maxday(input [3:0] mon,
+			       input [6:0] year);
+      case (mon)
+	4'd4,			// April
+	4'd6,			// June
+	4'd9,			// September
+	4'd11: begin		// November
+	   maxday = 5'd30;
+	end
+	4'd2: begin		// February
+	   if ((|year[1:0]) | (year == (2100 - 1980)))
+	     maxday = 5'd28;
+	   else
+	     maxday = 5'd29;
+	end
+	default: begin
+	   maxday = 5'd31;
+	end
+	endcase // case (mon)
+   endfunction // mdays
+
+   function logic [7:0] tick(input [7:0] me,
+			     input [7:0] start,
+			     input 	 wrap_pre,
+			     input 	 wrap_me);
+      
+      tick = wrap_me ? start : me + wrap_pre;
+   endfunction // tick
+
+   // Counter read/writes holding register
+   reg [15:0] tm_hold;
+   reg [ 1:0] tm_whold;		// Byte enables for hold register
+   
+   reg [15:0] tm_tick;
+   reg [31:0] tm_dt;		// Day and time in FAT filesystem format
+
+   wire [4:0] tm_2sec = tm_dt[4:0];
+   wire [5:0] tm_min  = tm_dt[10:5];
+   wire [4:0] tm_hour = tm_dt[15:11];
+
+   wire [4:0] tm_mday = tm_dt[20:16];
+   wire [3:0] tm_mon  = tm_dt[24:21];
+   wire [6:0] tm_year = tm_dt[31:25];
+   
+   wire wrap_tick = rtc_clk_stb & |tm_tick;
+   wire wrap_sec  = wrap_tick & (tm_2sec >= 5'd29);
+   wire wrap_min  = wrap_sec  & (tm_min  >= 6'd59);
+   wire wrap_hour = wrap_min  & (tm_hour >= 5'd23);
+   wire wrap_mday = wrap_hour & (tm_mday >= maxday(tm_mon, tm_year));
+   wire wrap_mon  = wrap_mday & (tm_mon  >= 4'd12);
+
+   always @(posedge sys_clk)
+     begin
+	tm_tick      <= tm_tick + rtc_clk_stb;
+	tm_dt[4:0]   <= tick(tm_2sec, 5'd0, wrap_tick, wrap_sec);
+	tm_dt[10:5]  <= tick(tm_min,  6'd0, wrap_sec,  wrap_min);
+	tm_dt[15:11] <= tick(tm_hour, 4'd0, wrap_min,  wrap_hour);
+	tm_dt[20:16] <= tick(tm_mday, 5'd1, wrap_hour, wrap_mday);
+	tm_dt[24:21] <= tick(tm_mon,  4'd1, wrap_mday, wrap_mon);
+	tm_dt[31:25] <= tick(tm_year, 7'hxx, wrap_mon,  1'b0);
+
+	if (~rst_n)
+	  begin
+	     tm_hold <= tm_tick;
+	     tm_whold <= 2'b00;
+	  end
+	else if (valid)
+	  case (addr)
+	    1'b0: begin
+	       // Datetime register
+	       if (wstrb[0]) tm_dt[7:0]   <= wdata[7:0];
+	       if (wstrb[1]) tm_dt[15:8]  <= wdata[15:8];
+	       if (wstrb[2]) tm_dt[23:16] <= wdata[23:16];
+	       if (wstrb[3]) tm_dt[31:24] <= wdata[31:24];
+	    
+	       if (tm_whold[0]) tm_tick[7:0]  <= tm_hold[7:0];
+	       if (tm_whold[1]) tm_tick[15:8] <= tm_hold[15:8];
+	       tm_hold  <= tm_tick;
+	       tm_whold <= 2'b00;
+	    end // case: 1'b0
+	    1'b1: begin
+	       // Tick register
+	       if (wstrb[0]) tm_hold[7:0]  <= wdata[7:0];
+	       if (wstrb[1]) tm_hold[15:8] <= wdata[15:8];
+	       if (wstrb[2]) tm_tick[7:0]  <= wdata[23:16];
+	       if (wstrb[3]) tm_tick[15:8] <= wdata[31:24];
+	       tm_whold <= tm_whold | wstrb[1:0];
+	    end
+	  endcase // case (addr)
+     end // always @ (posedge sys_clk)
+
+   // Read data MUX
+   always @(*)
+     case (addr)
+       1'b0: rdata = tm_dt;
+       1'b1: rdata = { tm_tick, tm_hold };
+     endcase // case (addr)
+	
+endmodule // sysclock

+ 5 - 6
fpga/tty.sv

@@ -140,7 +140,6 @@ module tty (
 
    // Status register definition
    localparam status_bits = 5;
-   
    wire [status_bits-1:0] status;
 
    assign status[0] = tx_rdempty & (tx_bits == 4'd0);
@@ -149,8 +148,7 @@ module tty (
    assign status[3] = tx_usedw[8];
    assign status[4] = tx_usedw[8:7] == 2'b11;
    
-   reg [status_bits-1:0]   irq_en;
-
+   reg [status_bits-1:0]  irq_en;
    //
    // Control register writes.
    // Only full word writes are supported.
@@ -171,9 +169,10 @@ module tty (
      begin
 	rdata = 32'b0;
 	case (addr)
-	  2'b01: rdata = divisor;
-	  2'b10: rdata = status;
-	  2'b11: rdata = irq_en;
+	  2'b01:   rdata[NCO_BITS-1:0]    = divisor;
+	  2'b10:   rdata[status_bits-1:0] = status;
+	  2'b11:   rdata[status_bits-1:0] = irq_en;
+	  default: rdata = 32'b0;
 	endcase // case (addr)
      end
 

+ 1 - 0
fw/.gitignore

@@ -1,6 +1,7 @@
 *.o
 *.i
 *.s
+*.a
 *.elf
 *.bin
 *.ver

+ 1 - 1
fw/Makefile

@@ -32,7 +32,7 @@ boot_depth  := 8192
 boot_width  := 32
 boot_stride := 1
 
-boot.elf: head.o die.o hello.o console.o fatfs.a
+boot.elf: head.o die.o sbrk.o hello.o console.o sdcard.o fatfs.a
 
 FATFS_C = $(wildcard fatfs/source/*.c)
 FATFS_O = $(FATFS_C:.c=.o)

+ 2362 - 1199
fw/boot.mif

@@ -4,1203 +4,2366 @@ WIDTH = 32;
 ADDRESS_RADIX = HEX;
 DATA_RADIX = HEX;
 CONTENT BEGIN
-0000 : 00008137;
-0001 : 31E0006F;
-0002 : 00000000;
-0003 : 00000000;
-0004 : C0067139;
-0005 : C41AC216;
-0006 : C872C61E;
-0007 : CC7ACA76;
-0008 : D02ACE7E;
-0009 : D432D22E;
-000A : D83AD636;
-000B : DC42DA3E;
-000C : 850BDE46;
-000D : 00EF0000;
-000E : 408236C0;
-000F : 43224292;
-0010 : 4E4243B2;
-0011 : 4F624ED2;
-0012 : 55024FF2;
-0013 : 56225592;
-0014 : 574256B2;
-0015 : 586257D2;
-0016 : 612158F2;
-0017 : 0400000B;
-0018 : 71396571;
-0019 : 20050513;
-001A : DC22DE06;
-001B : D84ADA26;
-001C : D452D64E;
-001D : D05AD256;
-001E : CC62CE5E;
-001F : C86ACA66;
-0020 : 2E49C66E;
-0021 : C0000023;
-0022 : C8002783;
-0023 : 2473DFF5;
-0024 : 6085C010;
-0025 : 16808513;
-0026 : 83132E6D;
-0027 : 25838601;
-0028 : 63850003;
-0029 : 05C38513;
-002A : 00158713;
-002B : 00E32023;
-002C : 05932EE1;
-002D : 55B30540;
-002E : 648502B4;
-002F : 07048513;
-0030 : 89ABD937;
-0031 : 1D951A37;
-0032 : 40000437;
-0033 : 09B74AA1;
-0034 : 6B850002;
-0035 : DEF90C13;
-0036 : C84A0C93;
-0037 : 40080B37;
-0038 : 66052665;
-0039 : 11160D93;
-003A : 0B634010;
-003B : 19FD01B6;
-003C : 000A8863;
-003D : 85A286EE;
-003E : 08CB8513;
-003F : 26691AFD;
-0040 : 038D86B3;
-0041 : 03940833;
-0042 : BD330411;
-0043 : 88B3038D;
-0044 : 8DB30106;
-0045 : 19E301A8;
-0046 : 6E05FD64;
-0047 : 00020637;
-0048 : 051385CE;
-0049 : 268D0ACE;
-004A : 40000CB7;
-004B : 6C416B85;
-004C : 40080937;
-004D : 8A1384E6;
-004E : 8EA6020C;
-004F : 0004D583;
-0050 : 002ED603;
-0051 : 85130491;
-0052 : 2E3D0C0B;
-0053 : FF4497E3;
-0054 : 9CE24529;
-0055 : 9FE324C5;
-0056 : 2B73FD2C;
-0057 : 8F13C010;
-0058 : 26838641;
-0059 : 6F85000F;
-005A : 42000637;
-005B : 0CCF8513;
-005C : 400005B7;
-005D : 07932E11;
-005E : 432102D0;
-005F : 45C12737;
-0060 : 78DAD3B7;
-0061 : 02000637;
-0062 : 00800837;
-0063 : 86418493;
-0064 : 86F186A3;
-0065 : 8661AA23;
-0066 : 49814A85;
-0067 : 86D18913;
-0068 : 87418A13;
-0069 : 40000F37;
-006A : 0B935CFD;
-006B : 8C13BA17;
-006C : 0D93ECB3;
-006D : 0D13FFF6;
-006E : 84330018;
-006F : 458101E9;
-0070 : 20238522;
-0071 : 24110004;
-0072 : 852255FD;
-0073 : 01942023;
-0074 : C5932AED;
-0075 : C00CFFF9;
-0076 : 2AC58522;
-0077 : 852285CE;
-0078 : 01342023;
-0079 : 86B322DD;
-007A : 85220379;
-007B : 018685B3;
-007C : 2AE1C00C;
-007D : 000408B7;
-007E : FFF88E13;
-007F : 01CAFEB3;
-0080 : 40000F37;
-0081 : 02D00F93;
-0082 : 000E9863;
-0083 : 00094083;
-0084 : CC100023;
-0085 : 01F90023;
-0086 : 0A854088;
-0087 : F9B399AA;
-0088 : 9CE301B9;
-0089 : 6785F9AA;
-008A : 10478513;
-008B : DCB7241D;
-008C : 42A178DA;
-008D : 45C12337;
-008E : 00040737;
-008F : 020003B7;
-0090 : 008005B7;
-0091 : 005A2023;
-0092 : ECBC8C13;
-0093 : 49814A05;
-0094 : BA130B93;
-0095 : 40000D37;
-0096 : FFF70C93;
-0097 : 02D00D93;
-0098 : FFF38413;
-0099 : 00158A93;
-009A : 03798633;
-009B : 01A98533;
-009C : 018605B3;
-009D : 78332A99;
-009E : 1863019A;
-009F : 46830008;
-00A0 : 00230009;
-00A1 : 0023CCD0;
-00A2 : A88301B9;
-00A3 : 0A050004;
-00A4 : 41198E33;
-00A5 : 008E79B3;
-00A6 : FD5A18E3;
-00A7 : C0102973;
-00A8 : 8F136ED5;
-00A9 : 0B33820E;
-00AA : 55B34169;
-00AB : 6F8503EB;
-00AC : 12CF8513;
-00AD : 42000DB7;
-00AE : 40882AC1;
-00AF : 03B7478D;
-00B0 : 82B34000;
-00B1 : F33302A7;
-00B2 : DB930082;
-00B3 : 4C330172;
-00B4 : 7D130173;
-00B5 : 6713FF8C;
-00B6 : C098004D;
-00B7 : DEADC4B7;
-00B8 : EEF48C93;
-00B9 : 0193A023;
-00BA : 9DE30391;
-00BB : 20F3FFB3;
-00BC : 8437C010;
-00BD : 05930A03;
-00BE : 2AF39FF4;
-00BF : 8633C010;
-00C0 : FCE3401A;
-00C1 : 6805FEC5;
-00C2 : 15080513;
-00C3 : 26832299;
-00C4 : F893CC80;
-00C5 : 8CE30016;
-00C6 : 4E05FE08;
-00C7 : C5C02023;
-00C8 : 1197BFF5;
-00C9 : 81930000;
-00CA : 851372A1;
-00CB : 861386C1;
-00CC : 8E098A01;
-00CD : 2AD94581;
-00CE : 00000513;
-00CF : 0513C519;
-00D0 : 00970000;
-00D1 : 00E70000;
-00D2 : 2AB10000;
-00D3 : 004C4502;
-00D4 : 33394601;
-00D5 : 1141A0B9;
-00D6 : C783C422;
-00D7 : C60686C1;
-00D8 : 0293EF99;
-00D9 : 89630000;
-00DA : 65050002;
-00DB : 24050513;
-00DC : 00000097;
-00DD : 000000E7;
-00DE : 86234305;
-00DF : 40B28661;
-00E0 : 01414422;
-00E1 : 02938082;
-00E2 : 8B630000;
-00E3 : 65050002;
-00E4 : 88818593;
-00E5 : 24050513;
-00E6 : 00000317;
-00E7 : 00000067;
-00E8 : 77378082;
-00E9 : 47890140;
-00EA : F3F70293;
-00EB : 0FF7F693;
-00EC : C0D00023;
-00ED : 0077C793;
-00EE : C0102673;
-00EF : C0102373;
-00F0 : 40C303B3;
-00F1 : FE72FCE3;
-00F2 : 4110B7D5;
-00F3 : 04B60363;
-00F4 : C4221141;
-00F5 : 87418413;
-00F6 : C606401C;
-00F7 : 86AECF89;
-00F8 : 650585AA;
-00F9 : 03C50513;
-00FA : 22832045;
-00FB : 83130004;
-00FC : 2023FFF2;
-00FD : 85930064;
-00FE : 41908701;
-00FF : 05800713;
-0100 : 00160693;
-0101 : 4422C194;
-0102 : 86E186A3;
-0103 : 014140B2;
-0104 : 80828082;
-0105 : 3216D737;
-0106 : 0313478D;
-0107 : 82B39487;
-0108 : 353302A7;
-0109 : 83B30265;
-010A : 859300A2;
-010B : 2223FFF3;
-010C : 8082CCB0;
-010D : CC802783;
-010E : 0107F293;
-010F : FE029CE3;
-0110 : 15634329;
-0111 : 43B50065;
-0112 : CC700023;
-0113 : CCA00023;
-0114 : 11418082;
-0115 : C606C422;
-0116 : 4503842A;
-0117 : E5090004;
-0118 : 442240B2;
-0119 : 80820141;
-011A : 37E90405;
-011B : 7175B7FD;
-011C : 86AE862A;
-011D : 0593850A;
-011E : C7060800;
-011F : 850A2219;
-0120 : 40BA3FC9;
-0121 : 80826149;
-0122 : D22E7139;
-0123 : CE06104C;
-0124 : D636D432;
-0125 : DA3ED83A;
-0126 : DE46DC42;
-0127 : 3FC1C62E;
-0128 : 612140F2;
-0129 : 11418082;
-012A : C226C422;
-012B : 64856405;
-012C : 24448793;
-012D : 0093C606;
-012E : 82B32444;
-012F : C04A40F0;
-0130 : 4022D413;
-0131 : 24448493;
-0132 : 17634901;
-0133 : 63050289;
-0134 : 03936505;
-0135 : 05932443;
-0136 : 86332485;
-0137 : 54134075;
-0138 : 04934026;
-0139 : 49012443;
-013A : 00891D63;
-013B : 442240B2;
-013C : 49024492;
-013D : 80820141;
-013E : 09054098;
-013F : 97020491;
-0140 : 4094B7E9;
-0141 : 04910905;
-0142 : BFF99682;
-0143 : C611832A;
-0144 : 00B30023;
-0145 : 0305167D;
-0146 : 8082FE65;
-0147 : DCA27119;
-0148 : DE86DAA6;
-0149 : 84AAD8CA;
-014A : 5D638432;
-014B : 03930006;
-014C : 202308B0;
-014D : 557D0075;
-014E : 546650F6;
-014F : 594654D6;
-0150 : 80826109;
-0151 : 20800793;
-0152 : 00F11A23;
-0153 : CC2EC42E;
-0154 : 40818636;
-0155 : C01986BA;
-0156 : FFF40093;
-0157 : 002C597D;
-0158 : C8068526;
-0159 : 1B23CE06;
-015A : 2A390121;
-015B : 01255663;
-015C : 08B00293;
-015D : 0054A023;
-015E : 4322D061;
-015F : 00030023;
-0160 : 8736BF65;
-0161 : 862E86B2;
-0162 : A50385AA;
-0163 : B7798681;
-0164 : C05A1101;
-0165 : 0085AB03;
-0166 : C64ECC22;
-0167 : C256C452;
-0168 : CA26CE06;
-0169 : AA83C84A;
-016A : 842E0005;
-016B : 89B68A32;
-016C : 0766EC63;
-016D : 00C5D783;
-016E : 4807F713;
-016F : 2083C725;
-0170 : 448D0144;
-0171 : 82B34309;
-0172 : 498C0214;
-0173 : 00168393;
-0174 : 8AB38B2A;
-0175 : 853340BA;
-0176 : C4B30153;
-0177 : F3630262;
-0178 : 84AA00A4;
-0179 : 4007F613;
-017A : 85A6CE25;
-017B : 00EF855A;
-017C : 892A0450;
-017D : 480CCD3D;
-017E : 27358656;
-017F : 00C45583;
-0180 : B7F5F693;
-0181 : 0806E813;
-0182 : 01041623;
-0183 : 015908B3;
-0184 : 41548E33;
-0185 : 01242823;
-0186 : 01142023;
-0187 : 8B4EC844;
-0188 : 01C42423;
-0189 : 0169F363;
-018A : 40088B4E;
-018B : 865A85D2;
-018C : 2E832731;
-018D : 2F830084;
-018E : 45010004;
-018F : 416E8F33;
-0190 : 016F8A33;
-0191 : 01E42423;
-0192 : 01442023;
-0193 : 446240F2;
-0194 : 494244D2;
-0195 : 4A2249B2;
-0196 : 4B024A92;
-0197 : 80826105;
-0198 : 855A8626;
-0199 : 0C3000EF;
-019A : F14D892A;
-019B : 855A480C;
-019C : 57832DCD;
-019D : 49B100C4;
-019E : 013B2023;
-019F : 0407E713;
-01A0 : 00E41623;
-01A1 : B7D9557D;
-01A2 : 00C5D783;
-01A3 : D7067171;
-01A4 : D326D522;
-01A5 : CD52D14A;
-01A6 : CB56CF4E;
-01A7 : C75EC95A;
-01A8 : C366C562;
-01A9 : DEEEC16A;
-01AA : 0807F093;
-01AB : 892E8A2A;
-01AC : 843684B2;
-01AD : 04008563;
-01AE : 0105A283;
-01AF : 04029163;
-01B0 : 04000593;
-01B1 : 202327BD;
-01B2 : 282300A9;
-01B3 : E50500A9;
-01B4 : 20234AB1;
-01B5 : 557D015A;
-01B6 : 542A50BA;
-01B7 : 590A549A;
-01B8 : 4A6A49FA;
-01B9 : 4B4A4ADA;
-01BA : 4C2A4BBA;
-01BB : 4D0A4C9A;
-01BC : 614D5DF6;
-01BD : 03138082;
-01BE : 2A230400;
-01BF : 03930069;
-01C0 : 05130200;
-01C1 : D2020300;
-01C2 : 027104A3;
-01C3 : 02A10523;
-01C4 : 0C93C622;
-01C5 : 6B050250;
-01C6 : 6D056B85;
-01C7 : 00000A93;
-01C8 : 45838426;
-01C9 : C1990004;
-01CA : 0B959163;
-01CB : 40940DB3;
-01CC : 00940E63;
-01CD : 86EE8626;
-01CE : 855285CA;
-01CF : 54FD3D91;
-01D0 : 1A950B63;
-01D1 : 06B35612;
-01D2 : D23601B6;
-01D3 : 00044703;
-01D4 : 1A070363;
-01D5 : 0493587D;
-01D6 : C8020014;
-01D7 : CA42CE02;
-01D8 : 09A3CC02;
-01D9 : D4820401;
-01DA : C5834D85;
-01DB : 46150004;
-01DC : 1ACB0513;
-01DD : 48C22B61;
-01DE : 00148413;
-01DF : FE13E929;
-01E0 : 06630108;
-01E1 : 0E93000E;
-01E2 : 09A30200;
-01E3 : FF1305D1;
-01E4 : 06630088;
-01E5 : 0F93000F;
-01E6 : 09A302B0;
-01E7 : C78305F1;
-01E8 : 00930004;
-01E9 : 8F6302A0;
-01EA : 4DF20217;
-01EB : 45A58426;
-01EC : 45294481;
-01ED : 00044283;
-01EE : 00140393;
-01EF : FD028313;
-01F0 : 0665F763;
-01F1 : CE6EC885;
-01F2 : 0405A035;
-01F3 : 0613BF99;
-01F4 : 06B31ACB;
-01F5 : 983340C5;
-01F6 : E73300DD;
-01F7 : C83A0108;
-01F8 : B76184A2;
-01F9 : 42184632;
-01FA : 00460693;
-01FB : 4963C636;
-01FC : CE3A0207;
-01FD : 00044E03;
-01FE : 02E00E93;
-01FF : 07DE1263;
-0200 : 00144F03;
-0201 : 02A00F93;
-0202 : 03FF1C63;
-0203 : 040944B2;
-0204 : 8613408C;
-0205 : C6320044;
-0206 : 0205C263;
-0207 : A089CA2E;
-0208 : 40E00833;
-0209 : 0028E893;
-020A : C846CE42;
-020B : 8433B7E1;
-020C : 448502AD;
-020D : 00640DB3;
-020E : BFAD841E;
-020F : BFF955FD;
-0210 : CA020405;
-0211 : 45814D81;
-0212 : 43A94525;
-0213 : 00044083;
-0214 : 00140313;
-0215 : FD008293;
-0216 : 06557363;
-0217 : FC0D90E3;
-0218 : 00044583;
-0219 : 8513460D;
-021A : 214D1B4B;
-021B : 4E42CD11;
-021C : 1B4B8693;
-021D : 40D50833;
-021E : 04000713;
-021F : 010718B3;
-0220 : 011E6EB3;
-0221 : C8760405;
-0222 : 00044583;
-0223 : 05134619;
-0224 : 04931B8D;
-0225 : 04230014;
-0226 : 298D02B1;
-0227 : 9E63C535;
-0228 : 40C2020A;
-0229 : F2934FB2;
-022A : 81631000;
-022B : 85130202;
-022C : C62A004F;
-022D : 85B35792;
-022E : D22E0137;
-022F : 87B3B595;
-0230 : 841A0275;
-0231 : 85B34D85;
-0232 : B7490057;
-0233 : 007F8313;
-0234 : FF837393;
-0235 : 00838513;
-0236 : 0078BFE9;
-0237 : 59000693;
-0238 : 080C864A;
-0239 : 00978552;
-023A : 00E70000;
-023B : 5F7D0000;
-023C : 11E389AA;
-023D : 5983FDE5;
-023E : 557D00C9;
-023F : 0409F913;
-0240 : DC091CE3;
-0241 : BBC95512;
-0242 : 06930078;
-0243 : 864A5900;
-0244 : 8552080C;
-0245 : BFE12A0D;
-0246 : CC527179;
-0247 : 8A3A499C;
-0248 : D4224598;
-0249 : CE4ED04A;
-024A : D606CA56;
-024B : C85AD226;
-024C : 89AAC65E;
-024D : 8932842E;
-024E : D3638AB6;
-024F : 87BA00E7;
-0250 : 00F92023;
-0251 : 04344083;
-0252 : 00008663;
-0253 : 00178293;
-0254 : 00592023;
-0255 : 00042303;
-0256 : 02037393;
-0257 : 00038863;
-0258 : 00092483;
-0259 : 00248513;
-025A : 00A92023;
-025B : F493400C;
-025C : E8990065;
-025D : 01940B13;
-025E : 44505BFD;
-025F : 00092683;
-0260 : 40D60833;
-0261 : 0704C363;
-0262 : 00042B03;
-0263 : 04344883;
-0264 : 020B7B93;
-0265 : 011036B3;
-0266 : 060B9E63;
-0267 : 04340613;
-0268 : 854E85D6;
-0269 : 57FD9A02;
-026A : 04F50863;
-026B : 00042083;
-026C : 44814311;
-026D : 0060F293;
-026E : 00629B63;
-026F : 00C42383;
-0270 : 00092903;
-0271 : 412384B3;
-0272 : 0004D363;
-0273 : 44084481;
-0274 : D563480C;
-0275 : 063300A5;
-0276 : 94B240B5;
-0277 : 04694B81;
-0278 : 99635B7D;
-0279 : 45010574;
-027A : 4685A809;
-027B : 85D6865A;
-027C : 9A02854E;
-027D : 01751E63;
-027E : 50B2557D;
-027F : 54925422;
-0280 : 49F25902;
-0281 : 4AD24A62;
-0282 : 4BB24B42;
-0283 : 80826145;
-0284 : B7A50485;
-0285 : 00D40EB3;
-0286 : 03000F13;
-0287 : 05EE81A3;
-0288 : 04544F83;
-0289 : 00168E13;
-028A : 01C40733;
-028B : 01A30689;
-028C : B7AD05F7;
-028D : 86224685;
-028E : 854E85D6;
-028F : 0DE39A02;
-0290 : 0B85FB65;
-0291 : 7179BF79;
-0292 : D226D422;
-0293 : CE4ED04A;
-0294 : CC52D606;
-0295 : C85ACA56;
-0296 : 0185C883;
-0297 : 07800793;
-0298 : 842E84AA;
-0299 : 89B68932;
-029A : 0117EE63;
-029B : 06200093;
-029C : 04358693;
-029D : 0110ED63;
-029E : 20088863;
-029F : 05800593;
-02A0 : 1CB88463;
-02A1 : 04240A93;
-02A2 : 05140123;
-02A3 : 8293A81D;
-02A4 : F313F9D8;
-02A5 : 46550FF2;
-02A6 : FE6666E3;
-02A7 : 13936505;
-02A8 : 05930023;
-02A9 : 88331E85;
-02AA : 2A0300B3;
-02AB : 8A020008;
-02AC : 0A93431C;
-02AD : 43900424;
-02AE : 00478693;
-02AF : 0123C314;
-02B0 : 4F8504C4;
-02B1 : 2E03AAC5;
-02B2 : 2E830004;
-02B3 : 7F930007;
-02B4 : 8F13080E;
-02B5 : 8363004E;
-02B6 : A783020F;
-02B7 : 2023000E;
-02B8 : 628501E7;
-02B9 : 0007D863;
-02BA : 02D00313;
-02BB : 40F007B3;
-02BC : 046401A3;
-02BD : 1C028393;
-02BE : A8A948A9;
-02BF : 000EA783;
-02C0 : 040E7093;
-02C1 : 01E72023;
-02C2 : FC008DE3;
-02C3 : 01079713;
-02C4 : 41075793;
-02C5 : 2F83B7F9;
-02C6 : 431C0004;
-02C7 : 080FF293;
-02C8 : 00478093;
-02C9 : 00028663;
-02CA : 00172023;
-02CB : A809439C;
-02CC : 040FF313;
-02CD : 00172023;
-02CE : FE030AE3;
-02CF : 0007D783;
-02D0 : 06136385;
-02D1 : 839306F0;
-02D2 : 83631C03;
-02D3 : 48A910C8;
-02D4 : 040401A3;
-02D5 : 00442283;
-02D6 : 00542423;
-02D7 : 0002C763;
-02D8 : 00042303;
-02D9 : FFB37613;
-02DA : E781C010;
-02DB : 81638AB6;
-02DC : 8AB60202;
-02DD : 0317F5B3;
-02DE : 853E1AFD;
-02DF : 00B38A33;
-02E0 : 000A4803;
-02E1 : 0317D7B3;
-02E2 : 010A8023;
-02E3 : FF1574E3;
-02E4 : 936343A1;
-02E5 : 28830278;
-02E6 : FB130004;
-02E7 : 0D630018;
-02E8 : 2E03000B;
-02E9 : 2E830044;
-02EA : C7630104;
-02EB : 0F1301CE;
-02EC : 8FA30300;
-02ED : 1AFDFFEA;
-02EE : 415686B3;
-02EF : 874EC814;
-02F0 : 007086CA;
-02F1 : 852685A2;
-02F2 : 5A7D3B81;
-02F3 : 0F451963;
-02F4 : 50B2557D;
-02F5 : 54925422;
-02F6 : 49F25902;
-02F7 : 4AD24A62;
-02F8 : 61454B42;
-02F9 : 2E038082;
-02FA : 6E930004;
-02FB : 2023020E;
-02FC : 6F0501D4;
-02FD : 07800893;
-02FE : 1D4F0393;
-02FF : 051402A3;
-0300 : 00042803;
-0301 : 7B134308;
-0302 : 411C0808;
-0303 : 00450A93;
-0304 : 000B1A63;
-0305 : 04087E13;
-0306 : 000E0663;
-0307 : 01079E93;
-0308 : 010ED793;
-0309 : 01572023;
-030A : 00187F13;
-030B : 000F0663;
-030C : 02086F93;
-030D : 01F42023;
-030E : FB9948C1;
-030F : 00042083;
-0310 : FDF0F713;
-0311 : B729C018;
-0312 : 03936A05;
-0313 : B77D1C0A;
-0314 : BDFD48A1;
-0315 : 00042883;
-0316 : 00072A03;
-0317 : F813484C;
-0318 : 05130808;
-0319 : 0863004A;
-031A : C3080008;
-031B : 000A2B03;
-031C : 00BB2023;
-031D : C308A811;
-031E : 0408FA93;
-031F : 000A2B03;
-0320 : FE0A88E3;
-0321 : 00BB1023;
-0322 : 00042823;
-0323 : BF058AB6;
-0324 : 00072A83;
-0325 : 45814050;
-0326 : 004A8B13;
-0327 : 01672023;
-0328 : 000AAA83;
-0329 : 209D8556;
-032A : 0733C501;
-032B : C0584155;
-032C : 00442F83;
-032D : 01F42823;
-032E : 040401A3;
-032F : 4814B709;
-0330 : 85CA8656;
-0331 : 99828526;
-0332 : F14504E3;
-0333 : 00042083;
-0334 : 0020F713;
-0335 : 44B2E71D;
-0336 : 5CE34448;
-0337 : 8526EE95;
-0338 : 4685BDCD;
-0339 : 85CA8656;
-033A : 99828526;
-033B : EF6502E3;
-033C : 22830A05;
-033D : 433200C4;
-033E : 40628633;
-033F : FECA43E3;
-0340 : 4A01BFD9;
-0341 : 01940A93;
-0342 : B7E55B7D;
-0343 : 0FF5F593;
-0344 : 1463962A;
-0345 : 450100C5;
-0346 : 47838082;
-0347 : 8DE30005;
-0348 : 0505FEB7;
-0349 : 832AB7FD;
-034A : 8383CA09;
-034B : 00230005;
-034C : 167D0073;
-034D : 05850305;
-034E : 8082FA6D;
-034F : 832AC215;
-0350 : 67634685;
-0351 : 56FD00B5;
-0352 : FFF60713;
-0353 : 95BA933A;
-0354 : 00058383;
-0355 : 00730023;
-0356 : 9336167D;
-0357 : FA6D95B6;
-0358 : C5F98082;
-0359 : FFC5A783;
-035A : CC221101;
-035B : 8413CE06;
-035C : D363FFC5;
-035D : 943E0007;
-035E : 24B1C62A;
-035F : 8781A803;
-0360 : 1A634532;
-0361 : 22230008;
-0362 : AC230004;
-0363 : 44628681;
-0364 : 610540F2;
-0365 : 7363AC15;
-0366 : 20830304;
-0367 : 06B30004;
-0368 : 1A630014;
-0369 : 260300D8;
-036A : 28030008;
-036B : 02B30048;
-036C : 20230016;
-036D : 22230054;
-036E : BFC10104;
-036F : 280380C2;
-0370 : 04630048;
-0371 : 7BE30008;
-0372 : A683FF04;
-0373 : 86330000;
-0374 : 176300D0;
-0375 : 2E030286;
-0376 : 8EB30004;
-0377 : A02301C6;
-0378 : 8F3301D0;
-0379 : 14E301D0;
-037A : 2F83FBE8;
-037B : 24030008;
-037C : 87B30048;
-037D : A02301DF;
-037E : A22300F0;
-037F : BF410080;
-0380 : 00C47663;
-0381 : 202348B1;
-0382 : B7510115;
-0383 : 00042283;
-0384 : 00540333;
-0385 : 00681963;
-0386 : 00082383;
-0387 : 00482803;
-0388 : 005385B3;
-0389 : 2223C00C;
-038A : A2230104;
-038B : B7850080;
-038C : 11018082;
-038D : 8493CA26;
-038E : CE060035;
-038F : FFC4F093;
-0390 : CC22C84A;
-0391 : 8493C64E;
-0392 : 47B10080;
-0393 : F663892A;
-0394 : 44B104F4;
-0395 : 04B4E563;
-0396 : 22B5854A;
-0397 : 87818713;
-0398 : 00072883;
-0399 : 87818693;
-039A : E4298446;
-039B : 87C18993;
-039C : 0009A303;
-039D : 00031763;
-039E : 854A4581;
-039F : A0232A31;
-03A0 : 85A600A9;
-03A1 : 2A09854A;
-03A2 : 116359FD;
-03A3 : 45310935;
-03A4 : 00A92023;
-03A5 : 2A0D854A;
-03A6 : DDE3A031;
-03A7 : 42B1FA04;
-03A8 : 00592023;
-03A9 : 40F24501;
-03AA : 44D24462;
-03AB : 49B24942;
-03AC : 80826105;
-03AD : 8833400C;
-03AE : 46634095;
-03AF : 462D0408;
-03B0 : 01067763;
-03B1 : 01042023;
-03B2 : C0049442;
-03B3 : 2E03A039;
-03B4 : 97630044;
-03B5 : A0230288;
-03B6 : 854A01C6;
-03B7 : 0F1320F5;
-03B8 : 0E9300B4;
-03B9 : 75130044;
-03BA : 0FB3FF8F;
-03BB : 0CE341D5;
-03BC : 00B3FBD5;
-03BD : 87B301F4;
-03BE : A02340AE;
-03BF : B76500F0;
-03C0 : 01C8A223;
-03C1 : 88A2BFD9;
-03C2 : B7854040;
-03C3 : 00350393;
-03C4 : FFC3F413;
-03C5 : FA850BE3;
-03C6 : 40A405B3;
-03C7 : 28AD854A;
-03C8 : FB3515E3;
-03C9 : 1101B7AD;
-03CA : CE06CC22;
-03CB : C84ACA26;
-03CC : C452C64E;
-03CD : E9918432;
-03CE : 40F24462;
-03CF : 494244D2;
-03D0 : 4A2249B2;
-03D1 : 610585B2;
-03D2 : EE01B5ED;
-03D3 : 44813D19;
-03D4 : 446240F2;
-03D5 : 49B24942;
-03D6 : 85264A22;
-03D7 : 610544D2;
-03D8 : 8A2A8082;
-03D9 : 2095892E;
-03DA : 676389AA;
-03DB : 57930085;
-03DC : 84CA0015;
-03DD : FC87EEE3;
-03DE : 855285A2;
-03DF : 84AA3D5D;
-03E0 : 8622D961;
-03E1 : 0089F363;
-03E2 : 85CA864E;
-03E3 : 3B618526;
-03E4 : 855285CA;
-03E5 : BF6D33F9;
-03E6 : C4221141;
-03E7 : 842AC226;
-03E8 : C606852E;
-03E9 : 8801A023;
-03EA : 57FD2825;
-03EB : 00F51863;
-03EC : 8801A083;
-03ED : 00008463;
-03EE : 00142023;
-03EF : 442240B2;
-03F0 : 01414492;
-03F1 : 80828082;
-03F2 : A7838082;
-03F3 : 8513FFC5;
-03F4 : D663FFC7;
-03F5 : 95AA0007;
-03F6 : 0005A283;
-03F7 : 80829516;
-03F8 : 87931141;
-03F9 : C6068841;
-03FA : 0007A083;
-03FB : 829386AA;
-03FC : 93638841;
-03FD : 08930200;
-03FE : 45010D60;
-03FF : 00000073;
-0400 : 1963537D;
-0401 : 28050065;
-0402 : C1104631;
-0403 : 40B2557D;
-0404 : 80820141;
-0405 : 00A2A023;
-0406 : 0002A383;
-0407 : 0D600893;
-0408 : 007685B3;
-0409 : 0073852E;
-040A : 1EE30000;
-040B : A023FCB5;
-040C : 851E00A2;
-040D : A503BFE9;
-040E : 80828681;
-040F : 2070250A;
-0410 : 6572203A;
-0411 : 25206461;
-0412 : 20783830;
-0413 : 65707865;
-0414 : 64657463;
-0415 : 38302520;
-0416 : 00000A78;
-0417 : 73696854;
-0418 : 20736920;
-0419 : 706F6F6C;
-041A : 7525203A;
-041B : 0000000A;
-041C : 41524453;
-041D : 6F64204D;
-041E : 6F6C6E77;
-041F : 74206461;
-0420 : 206B6F6F;
-0421 : 75207525;
-0422 : 00000A73;
-0423 : 3A207025;
-0424 : 25783020;
-0425 : 20783830;
-0426 : 65707865;
-0427 : 64657463;
-0428 : 25783020;
-0429 : 0A783830;
-042A : 00000000;
-042B : 252F7525;
-042C : 6F772075;
-042D : 20736472;
-042E : 0A0A4B4F;
-042F : 00000000;
-0430 : 34302520;
-0431 : 30252E78;
-0432 : 00007834;
-0433 : 74736554;
-0434 : 20676E69;
-0435 : 41524453;
-0436 : 7266204D;
-0437 : 30206D6F;
-0438 : 38302578;
-0439 : 6F742078;
-043A : 25783020;
-043B : 2C783830;
-043C : 72747320;
-043D : 20656469;
-043E : 30257830;
-043F : 2E2E7838;
-0440 : 00000A2E;
-0441 : 6165520A;
-0442 : 676E6964;
-0443 : 63616220;
-0444 : 6F74206B;
-0445 : 65686320;
-0446 : 66206B63;
-0447 : 6120726F;
-0448 : 7361696C;
-0449 : 2E2E7365;
-044A : 00000A2E;
-044B : 5244530A;
-044C : 74204D41;
-044D : 20747365;
-044E : 706D6F63;
-044F : 6574656C;
-0450 : 6974202C;
-0451 : 3D20656D;
-0452 : 20752520;
-0453 : 000A736D;
-0454 : 202A2A2A;
-0455 : 6E696F44;
-0456 : 65722067;
-0457 : 20746573;
-0458 : 0A2A2A2A;
-0459 : 00000000;
-045A : 2A2A2A0A;
-045B : 6C654820;
-045C : 202C6F6C;
-045D : 6C726F57;
-045E : 2A202164;
-045F : 460A2A2A;
-0460 : 776D7269;
-0461 : 20657261;
-0462 : 706D6F63;
-0463 : 64656C69;
-0464 : 3A6E6F20;
-0465 : 74634F20;
-0466 : 20342020;
-0467 : 31323032;
-0468 : 3A333020;
-0469 : 303A3632;
-046A : 000A0A35;
-046B : 2B302D23;
-046C : 00000020;
-046D : 004C6C68;
-046E : 45676665;
-046F : 00004746;
-0470 : 33323130;
-0471 : 37363534;
-0472 : 42413938;
-0473 : 46454443;
-0474 : 00000000;
-0475 : 33323130;
-0476 : 37363534;
-0477 : 62613938;
-0478 : 66656463;
-0479 : 00000000;
-047A : 00000AB0;
-047B : 00000AC6;
-047C : 00000A84;
-047D : 00000A84;
-047E : 00000A84;
-047F : 00000A84;
-0480 : 00000AC6;
-0481 : 00000A84;
-0482 : 00000A84;
-0483 : 00000A84;
-0484 : 00000A84;
-0485 : 00000C54;
-0486 : 00000B16;
-0487 : 00000BE6;
-0488 : 00000A84;
-0489 : 00000A84;
-048A : 00000C90;
-048B : 00000A84;
-048C : 00000B16;
-048D : 00000A84;
-048E : 00000A84;
-048F : 00000BF2;
-0490 : 00000000;
-0491 : 00000386;
-0492 : 00000356;
-0493 : 00000000;
-0494 : 00000000;
-0495 : 00000000;
-0496 : 00000000;
-0497 : 00000000;
-0498 : 00000000;
-0499 : 00000000;
-049A : 00000000;
-049B : 00000000;
-049C : 00000000;
-049D : 00000000;
-049E : 00000000;
-049F : 00000000;
-04A0 : 00000000;
-04A1 : 00000000;
-04A2 : 00000000;
-04A3 : 00000000;
-04A4 : 00000000;
-04A5 : 00000000;
-04A6 : 00000000;
-04A7 : 00000000;
-04A8 : 00000000;
-04A9 : 00000000;
-04AA : 00000000;
-04AB : 00000001;
-04AC : 00000004;
-04AD : 0000124C;
-[04AE..1FFF] : 00;
+0000 : C01022F3;
+0001 : 00008137;
+0002 : 00002317;
+0003 : F0830313;
+0004 : 00532023;
+0005 : 3200006F;
+0006 : 00000000;
+0007 : 00000000;
+0008 : C0067139;
+0009 : C41AC216;
+000A : C872C61E;
+000B : CC7ACA76;
+000C : D02ACE7E;
+000D : D432D22E;
+000E : D83AD636;
+000F : DC42DA3E;
+0010 : 850BDE46;
+0011 : 00EF0000;
+0012 : 40823720;
+0013 : 43224292;
+0014 : 4E4243B2;
+0015 : 4F624ED2;
+0016 : 55024FF2;
+0017 : 56225592;
+0018 : 574256B2;
+0019 : 586257D2;
+001A : 612158F2;
+001B : 0400000B;
+001C : DE067139;
+001D : DA26DC22;
+001E : D64ED84A;
+001F : D256D452;
+0020 : CE5ED05A;
+0021 : CA66CC62;
+0022 : C66EC86A;
+0023 : 90002783;
+0024 : 2473DFF5;
+0025 : 6089C010;
+0026 : F100A283;
+0027 : 05136509;
+0028 : 04B30405;
+0029 : 2ED14054;
+002A : 89418393;
+002B : 0003A583;
+002C : 05136609;
+002D : 8713F346;
+002E : A0230015;
+002F : 2ED500E3;
+0030 : 05400593;
+0031 : 02B4D5B3;
+0032 : 85136689;
+0033 : D937F486;
+0034 : 1A3789AB;
+0035 : 04B71D95;
+0036 : 4AA14000;
+0037 : 000209B7;
+0038 : 0C136B89;
+0039 : 0C93DEF9;
+003A : 0B37C84A;
+003B : 26D14008;
+003C : 04136805;
+003D : 40901118;
+003E : 00860B63;
+003F : 886319FD;
+0040 : 86A2000A;
+0041 : 851385A6;
+0042 : 1AFDF64B;
+0043 : 08B3265D;
+0044 : 8D330384;
+0045 : 04910394;
+0046 : 03843E33;
+0047 : 01A88DB3;
+0048 : 01CD8433;
+0049 : FD6499E3;
+004A : 06376E89;
+004B : 85CE0002;
+004C : F84E8513;
+004D : 0B372EBD;
+004E : 6B894000;
+004F : 09376C41;
+0050 : 8CDA4008;
+0051 : 020B0A13;
+0052 : D5838F66;
+0053 : 5603000C;
+0054 : 0C91002F;
+0055 : F98B8513;
+0056 : 97E32EA9;
+0057 : 4529FF4C;
+0058 : 2CED9B62;
+0059 : FD2B1FE3;
+005A : 24F000EF;
+005B : C0102B73;
+005C : 89818F93;
+005D : 000FA683;
+005E : 06376789;
+005F : 85134200;
+0060 : 05B7FA47;
+0061 : 26354000;
+0062 : 02D00513;
+0063 : 273743A1;
+0064 : D63745C1;
+0065 : 083778DA;
+0066 : 08B70200;
+0067 : 84930080;
+0068 : 80A38981;
+0069 : A4238AA1;
+006A : 4A858A71;
+006B : 89134981;
+006C : 8A138A11;
+006D : 0FB78A81;
+006E : 5CFD4000;
+006F : BA170B93;
+0070 : ECB60C13;
+0071 : FFF80D93;
+0072 : 00188D13;
+0073 : 01F98433;
+0074 : 85224581;
+0075 : 00042023;
+0076 : 55FD2C2D;
+0077 : 20238522;
+0078 : 2C050194;
+0079 : FFF9C593;
+007A : 8522C00C;
+007B : 85CE241D;
+007C : 20238522;
+007D : 2C310134;
+007E : 037986B3;
+007F : 85B38522;
+0080 : C00C0186;
+0081 : 0E372439;
+0082 : 0E930004;
+0083 : FF33FFFE;
+0084 : 0FB701DA;
+0085 : 02934000;
+0086 : 186302D0;
+0087 : 4083000F;
+0088 : 00230009;
+0089 : 00239810;
+008A : 409C0059;
+008B : 99BE0A85;
+008C : 01B9F9B3;
+008D : F9AA9CE3;
+008E : 05136509;
+008F : 2C35FDC5;
+0090 : 78DADCB7;
+0091 : 23B74321;
+0092 : 073745C1;
+0093 : 06370004;
+0094 : 05B70200;
+0095 : 20230080;
+0096 : 8C13006A;
+0097 : 4A05ECBC;
+0098 : 8B934981;
+0099 : 0D37BA13;
+009A : 0C934000;
+009B : 0D93FFF7;
+009C : 041302D0;
+009D : 8A93FFF6;
+009E : 88330015;
+009F : 85330379;
+00A0 : 05B301A9;
+00A1 : 22710188;
+00A2 : 019A78B3;
+00A3 : 00089863;
+00A4 : 00094683;
+00A5 : 98D00023;
+00A6 : 01B90023;
+00A7 : 0004AE03;
+00A8 : 8EB30A05;
+00A9 : F9B341C9;
+00AA : 18E3008E;
+00AB : 2973FD5A;
+00AC : 6F55C010;
+00AD : 820F0F93;
+00AE : 41690B33;
+00AF : 03FB55B3;
+00B0 : 85136289;
+00B1 : 0DB70042;
+00B2 : 22E54200;
+00B3 : 478D4088;
+00B4 : 40000637;
+00B5 : 02A78333;
+00B6 : 008373B3;
+00B7 : 01735B93;
+00B8 : 0173CC33;
+00B9 : FF8C7D13;
+00BA : 004D6713;
+00BB : C4B7C098;
+00BC : 8C93DEAD;
+00BD : 2023EEF4;
+00BE : 06110196;
+00BF : FFB61DE3;
+00C0 : C01020F3;
+00C1 : 0A038437;
+00C2 : 9FF40593;
+00C3 : C0102AF3;
+00C4 : 401A8833;
+00C5 : FF05FCE3;
+00C6 : 85136889;
+00C7 : 2AB10288;
+00C8 : 98802683;
+00C9 : 0016FE13;
+00CA : FE0E0CE3;
+00CB : 20234E85;
+00CC : BFF589D0;
+00CD : 00003197;
+00CE : 91018193;
+00CF : 8A018513;
+00D0 : B1818613;
+00D1 : 45818E09;
+00D2 : 102010EF;
+00D3 : 00000513;
+00D4 : 0513C519;
+00D5 : 00970000;
+00D6 : 00E70000;
+00D7 : 10EF0000;
+00D8 : 450204A0;
+00D9 : 4601004C;
+00DA : A0B93321;
+00DB : C4221141;
+00DC : 8A01C783;
+00DD : EF99C606;
+00DE : 00000293;
+00DF : 00028963;
+00E0 : 05136509;
+00E1 : 00974385;
+00E2 : 00E70000;
+00E3 : 43050000;
+00E4 : 8A618023;
+00E5 : 442240B2;
+00E6 : 80820141;
+00E7 : 00000293;
+00E8 : 00028B63;
+00E9 : 85936509;
+00EA : 05138C41;
+00EB : 03174385;
+00EC : 00670000;
+00ED : 80820000;
+00EE : 01407737;
+00EF : 02934789;
+00F0 : F693F3F7;
+00F1 : 00230FF7;
+00F2 : C79380D0;
+00F3 : 26730077;
+00F4 : 2373C010;
+00F5 : 03B3C010;
+00F6 : FCE340C3;
+00F7 : B7D5FE72;
+00F8 : 89018293;
+00F9 : 0002A783;
+00FA : 831366A1;
+00FB : 953E8006;
+00FC : 00A37D63;
+00FD : C6061141;
+00FE : 7AB000EF;
+00FF : 202343B1;
+0100 : 40B20075;
+0101 : 0141557D;
+0102 : A0238082;
+0103 : 853E00A2;
+0104 : 41108082;
+0105 : 04B60363;
+0106 : C4221141;
+0107 : 8A818413;
+0108 : C606401C;
+0109 : 86AECF89;
+010A : 650985AA;
+010B : F1450513;
+010C : 22832049;
+010D : 83130004;
+010E : 2023FFF2;
+010F : 85930064;
+0110 : 41908A41;
+0111 : 05800713;
+0112 : 00160693;
+0113 : 4422C194;
+0114 : 8AE180A3;
+0115 : 014140B2;
+0116 : 80828082;
+0117 : 98802783;
+0118 : 0107F293;
+0119 : FE029CE3;
+011A : 15634329;
+011B : 43B50065;
+011C : 98700023;
+011D : 98A00023;
+011E : 11418082;
+011F : C606C422;
+0120 : 4503842A;
+0121 : E5090004;
+0122 : 442240B2;
+0123 : 80820141;
+0124 : 37E90405;
+0125 : 7175B7FD;
+0126 : 86AE862A;
+0127 : 0593850A;
+0128 : C7060800;
+0129 : 01C010EF;
+012A : 3FC1850A;
+012B : 614940BA;
+012C : 71398082;
+012D : 104CD22E;
+012E : D432CE06;
+012F : D83AD636;
+0130 : DC42DA3E;
+0131 : C62EDE46;
+0132 : 40F237F9;
+0133 : 80826121;
+0134 : A4A00A23;
+0135 : A2B02E23;
+0136 : A0C04783;
+0137 : F29343C1;
+0138 : 0A230FF7;
+0139 : 4503A050;
+013A : 1313A130;
+013B : 55130185;
+013C : 56634183;
+013D : 13FD0005;
+013E : FE0397E3;
+013F : 8082557D;
+0140 : C6061141;
+0141 : 081387AE;
+0142 : 08930FE0;
+0143 : 47030FD0;
+0144 : 7593A570;
+0145 : 03630FF7;
+0146 : E7630307;
+0147 : 608900B8;
+0148 : 08408513;
+0149 : A0393779;
+014A : F275167D;
+014B : 05136509;
+014C : 37410A85;
+014D : 40B2557D;
+014E : 80820141;
+014F : 00157293;
+0150 : 896385AA;
+0151 : 43030002;
+0152 : 0593A170;
+0153 : 17FD0015;
+0154 : 00650023;
+0155 : A1704703;
+0156 : 0025F393;
+0157 : 00038863;
+0158 : A1A05603;
+0159 : 17F90589;
+015A : FEC59F23;
+015B : A1A05703;
+015C : 17E9C291;
+015D : 83B3863E;
+015E : 431D00F5;
+015F : 40C38EB3;
+0160 : 004E8713;
+0161 : 0AC34563;
+0162 : FFC78F13;
+0163 : 002F5F93;
+0164 : 88B35871;
+0165 : 9093030F;
+0166 : 82B3002F;
+0167 : 258300B0;
+0168 : A023A180;
+0169 : 853300B2;
+016A : 8B8900F8;
+016B : 5303C799;
+016C : 8713A1A0;
+016D : 92230062;
+016E : 73930062;
+016F : 87630015;
+0170 : 46030003;
+0171 : 0705A160;
+0172 : FEC70FA3;
+0173 : 4E83C2B9;
+0174 : 0023A120;
+0175 : 4F0301D7;
+0176 : 00A3A130;
+0177 : 0A2301E7;
+0178 : 4683A4D0;
+0179 : 0123A130;
+017A : 2E2300D7;
+017B : 4F83A200;
+017C : 01A3A100;
+017D : 480301F7;
+017E : 0223A110;
+017F : 48830107;
+0180 : 02A3A120;
+0181 : 45030117;
+0182 : 7093A0C0;
+0183 : 0A230FF5;
+0184 : 5283A010;
+0185 : 4703A0A0;
+0186 : 4501A170;
+0187 : 01029593;
+0188 : 8AE381C1;
+0189 : 6789F002;
+018A : 0CC78513;
+018B : 2E03BDE5;
+018C : 1671A1C0;
+018D : 01CEA023;
+018E : 1141B791;
+018F : 842EC422;
+0190 : C2264581;
+0191 : C04AC606;
+0192 : 84AA3561;
+0193 : 4681E115;
+0194 : 7D000613;
+0195 : 852245C1;
+0196 : 84AA3565;
+0197 : 0913E911;
+0198 : 40080104;
+0199 : 511000EF;
+019A : 0411C008;
+019B : FE891BE3;
+019C : 442240B2;
+019D : 85264902;
+019E : 01414492;
+019F : 11018082;
+01A0 : CE06C64E;
+01A1 : CA26CC22;
+01A2 : C452C84A;
+01A3 : C24189B2;
+01A4 : 892A86AA;
+01A5 : 862E6509;
+01A6 : 051384AE;
+01A7 : 85CE0F85;
+01A8 : 67893D09;
+01A9 : 44578703;
+01AA : 13634285;
+01AB : 04A60057;
+01AC : 051385A6;
+01AD : 3D290520;
+01AE : E12184AA;
+01AF : FFF98413;
+01B0 : 000319B7;
+01B1 : 89935A7D;
+01B2 : 9093D409;
+01B3 : 05330094;
+01B4 : 17630019;
+01B5 : 47830544;
+01B6 : 4303A170;
+01B7 : 1393A170;
+01B8 : D4130183;
+01B9 : 75934183;
+01BA : 48E30FF3;
+01BB : CD81FE04;
+01BC : 05136609;
+01BD : 3B751446;
+01BE : 6689A039;
+01BF : 851385AA;
+01C0 : 3B451206;
+01C1 : 48114481;
+01C2 : 8B018623;
+01C3 : 40F289A6;
+01C4 : 44D24462;
+01C5 : 4A224942;
+01C6 : 49B2854E;
+01C7 : 80826105;
+01C8 : 04C00693;
+01C9 : 4681C011;
+01CA : 0593864E;
+01CB : 3BC92000;
+01CC : F971147D;
+01CD : BF510485;
+01CE : 852E1141;
+01CF : 863685B2;
+01D0 : C606C422;
+01D1 : 3F258436;
+01D2 : 8D0140B2;
+01D3 : 35334422;
+01D4 : 014100A0;
+01D5 : 11418082;
+01D6 : C606C226;
+01D7 : C04AC422;
+01D8 : 046384B2;
+01D9 : 86AA0E06;
+01DA : 6509842A;
+01DB : 892E862E;
+01DC : 17850513;
+01DD : 3B3585A6;
+01DE : 87036789;
+01DF : 42854457;
+01E0 : 00571363;
+01E1 : 85CA0926;
+01E2 : 05900513;
+01E3 : 85AA3391;
+01E4 : 5571E545;
+01E5 : 4885587D;
+01E6 : 0A234315;
+01E7 : 0693A0A0;
+01E8 : 08232004;
+01E9 : 7613A500;
+01EA : 77930014;
+01EB : F2930034;
+01EC : 8EA2FFC6;
+01ED : 4083C619;
+01EE : 0E930004;
+01EF : 0A230014;
+01F0 : 8809A010;
+01F1 : DE03C411;
+01F2 : 0E89000E;
+01F3 : A1C01C23;
+01F4 : 63638476;
+01F5 : 0F330854;
+01F6 : 7F9340F0;
+01F7 : 8763002F;
+01F8 : 5703000F;
+01F9 : 04090004;
+01FA : A0E01C23;
+01FB : 001F7293;
+01FC : 00028763;
+01FD : 00044683;
+01FE : 0A230405;
+01FF : 5603A0D0;
+0200 : 7093A0E0;
+0201 : 1C230FF6;
+0202 : 4383A010;
+0203 : FE93A170;
+0204 : FE130113;
+0205 : 9AE30FF3;
+0206 : 7F13FF1E;
+0207 : 026301FE;
+0208 : 5375046F;
+0209 : A0600A23;
+020A : A1704483;
+020B : 4803FCF5;
+020C : 0EE3A170;
+020D : A031FE08;
+020E : 05136909;
+020F : 39951A49;
+0210 : 44114581;
+0211 : 8A818623;
+0212 : 40B284AE;
+0213 : 49024422;
+0214 : 44928526;
+0215 : 80820141;
+0216 : 04114018;
+0217 : A0E02E23;
+0218 : 4F83BF8D;
+0219 : 8EE3A170;
+021A : 0585FE0F;
+021B : F2B497E3;
+021C : E105BF4D;
+021D : 852E1141;
+021E : 863685B2;
+021F : C606C422;
+0220 : 3DD18436;
+0221 : 8D0140B2;
+0222 : 35334422;
+0223 : 014100A0;
+0224 : 45058082;
+0225 : 17638082;
+0226 : 711D3005;
+0227 : 6409CCA2;
+0228 : 03000613;
+0229 : 05134581;
+022A : CE864444;
+022B : C8CACAA6;
+022C : 00EFC6CE;
+022D : 07933990;
+022E : 002307F0;
+022F : 52FDA0F0;
+0230 : A1C00713;
+0231 : 00572023;
+0232 : 00572023;
+0233 : 00572023;
+0234 : 00572023;
+0235 : 00572023;
+0236 : 00572023;
+0237 : 00572023;
+0238 : 00572023;
+0239 : A0500023;
+023A : 05134581;
+023B : 36CD0400;
+023C : 09134305;
+023D : 84AA4444;
+023E : 44440413;
+023F : 02650563;
+0240 : 85AA6309;
+0241 : 1C830513;
+0242 : 4391366D;
+0243 : 8623498D;
+0244 : 00238A71;
+0245 : 450D0139;
+0246 : 446640F6;
+0247 : 494644D6;
+0248 : 612549B6;
+0249 : 00938082;
+024A : 0023F820;
+024B : 4585A010;
+024C : 07B00513;
+024D : 05933E71;
+024E : 05131AA0;
+024F : 3E490480;
+0250 : 00457393;
+0251 : 996385AA;
+0252 : 99710403;
+0253 : 6789CD01;
+0254 : 1E478513;
+0255 : 47113EB9;
+0256 : 8AE18623;
+0257 : 00990023;
+0258 : BF5D4505;
+0259 : A1704783;
+025A : A1A05783;
+025B : A3802583;
+025C : 05136609;
+025D : 24232006;
+025E : 3E2500B9;
+025F : 00892583;
+0260 : 1AA00813;
+0261 : 400009B7;
+0262 : 1FF5F693;
+0263 : 01068763;
+0264 : 85136F89;
+0265 : BF7D220F;
+0266 : 45814981;
+0267 : 07700513;
+0268 : 78933E05;
+0269 : 85AA0045;
+026A : 00089763;
+026B : 051385CE;
+026C : 3E390690;
+026D : FE1385AA;
+026E : 1A630045;
+026F : FE93060E;
+0270 : 8D63FFE5;
+0271 : 6909000E;
+0272 : 24C90513;
+0273 : 4E9134DD;
+0274 : 8BD18623;
+0275 : 00234F05;
+0276 : B75901E4;
+0277 : 0593FDDD;
+0278 : 0023F810;
+0279 : 0513A0B0;
+027A : 85CE07A0;
+027B : 85AA34D5;
+027C : 6F89C509;
+027D : 268F8513;
+027E : 4783BFD1;
+027F : 5783A170;
+0280 : 2F03A1A0;
+0281 : 4905A380;
+0282 : 01E42623;
+0283 : 20000593;
+0284 : 05000513;
+0285 : 85AA3C75;
+0286 : 8AC18493;
+0287 : 6809C905;
+0288 : 2A080513;
+0289 : 48913479;
+028A : 01148023;
+028B : 4581B765;
+028C : 04100513;
+028D : 77933C71;
+028E : 85AAFFE5;
+028F : 6489C789;
+0290 : 28448513;
+0291 : F565B761;
+0292 : B7C94901;
+0293 : 01040593;
+0294 : 04900513;
+0295 : C90936DD;
+0296 : 00042823;
+0297 : 00042A23;
+0298 : 00042C23;
+0299 : 00042E23;
+029A : 4C58480C;
+029B : 48504C14;
+029C : 85136289;
+029D : 3C352BC2;
+029E : 02040593;
+029F : 04A00513;
+02A0 : C9093E6D;
+02A1 : 02042023;
+02A2 : 02042223;
+02A3 : 02042423;
+02A4 : 02042623;
+02A5 : 54585050;
+02A6 : 500C5414;
+02A7 : 05136309;
+02A8 : 3C012E03;
+02A9 : 01042383;
+02AA : D9934605;
+02AB : 851301E3;
+02AC : 00A30019;
+02AD : 0C6300A4;
+02AE : 460908C5;
+02AF : 0CC50A63;
+02B0 : 000400A3;
+02B1 : 00144E83;
+02B2 : 73634E09;
+02B3 : 4E8101DE;
+02B4 : 9F136F89;
+02B5 : 8793002E;
+02B6 : 8733370F;
+02B7 : 405001E7;
+02B8 : 6289430C;
+02B9 : 30428513;
+02BA : 0B6332E9;
+02BB : 29030409;
+02BC : 05B70144;
+02BD : F3334000;
+02BE : 03630125;
+02BF : 03B70403;
+02C0 : 85938100;
+02C1 : 0513FF13;
+02C2 : 32D90460;
+02C3 : 4681E915;
+02C4 : 7D000613;
+02C5 : 04000593;
+02C6 : 32DD850A;
+02C7 : 4983E115;
+02C8 : 450502F1;
+02C9 : 00F9F613;
+02CA : 00A61C63;
+02CB : A1C02783;
+02CC : F8000093;
+02CD : 00236689;
+02CE : 8513A010;
+02CF : 3A953306;
+02D0 : 00040023;
+02D1 : 80234411;
+02D2 : 45010084;
+02D3 : 2083B3F1;
+02D4 : 4C540184;
+02D5 : 01645703;
+02D6 : D5936E85;
+02D7 : D81300F0;
+02D8 : 9E1301E6;
+02D9 : 8F130020;
+02DA : 7293FFCE;
+02DB : F31300F7;
+02DC : 08930075;
+02DD : 7FB30018;
+02DE : 83B301EE;
+02DF : 87B30062;
+02E0 : 899301F8;
+02E1 : 98B3FF93;
+02E2 : 22230137;
+02E3 : BF1D0114;
+02E4 : 56834848;
+02E5 : 109301A4;
+02E6 : 88330105;
+02E7 : 189300D0;
+02E8 : B7E500A8;
+02E9 : 80824505;
+02EA : 6789E509;
+02EB : 4447C503;
+02EC : 45058082;
+02ED : 65898082;
+02EE : 46051141;
+02EF : F9458593;
+02F0 : 8DC18513;
+02F1 : 00EFC606;
+02F2 : 40B27500;
+02F3 : 80820141;
+02F4 : 00154703;
+02F5 : 00054783;
+02F6 : 00254383;
+02F7 : 00354503;
+02F8 : 00871293;
+02F9 : 00F2E333;
+02FA : 01039593;
+02FB : 0065E633;
+02FC : 01851693;
+02FD : 00C6E533;
+02FE : 47838082;
+02FF : 46830015;
+0300 : 47030055;
+0301 : 43830005;
+0302 : 4E030025;
+0303 : 4F830045;
+0304 : 46030065;
+0305 : 45030035;
+0306 : 92930075;
+0307 : 9E930087;
+0308 : E3330086;
+0309 : 959300E2;
+030A : EF330103;
+030B : 971301CE;
+030C : E833010F;
+030D : 12930065;
+030E : 18930185;
+030F : 67B30186;
+0310 : E53301E7;
+0311 : E5B30108;
+0312 : 808200F2;
+0313 : 15F94D5C;
+0314 : FFE78293;
+0315 : 0055FA63;
+0316 : 00A55303;
+0317 : 03B35918;
+0318 : 853302B3;
+0319 : 808200E3;
+031A : 80824501;
+031B : 86AA4118;
+031C : 87BAC305;
+031D : 0593457D;
+031E : C60303A0;
+031F : 07850007;
+0320 : 02C57263;
+0321 : FEB61BE3;
+0322 : 00270293;
+0323 : 00578463;
+0324 : 8082557D;
+0325 : 00074303;
+0326 : 03000393;
+0327 : 1AE3557D;
+0328 : C29CFE73;
+0329 : 80824501;
+032A : CE061101;
+032B : CA26CC22;
+032C : 00354783;
+032D : 4481EB81;
+032E : 446240F2;
+032F : 44D28526;
+0330 : 80826105;
+0331 : 03C50593;
+0332 : 842A5D10;
+0333 : 00154503;
+0334 : C62E4685;
+0335 : 84AA3E79;
+0336 : 5C10E51D;
+0337 : 02842083;
+0338 : 01A35018;
+0339 : 02B30004;
+033A : F6E34016;
+033B : 4683FCE2;
+033C : 43090024;
+033D : 90E345B2;
+033E : 4503FC66;
+033F : 46850014;
+0340 : 3E85963A;
+0341 : 4485BF55;
+0342 : 5D1CBF45;
+0343 : 02B78B63;
+0344 : C4221141;
+0345 : C606C226;
+0346 : 84AE842A;
+0347 : ED093771;
+0348 : 00144503;
+0349 : 86264685;
+034A : 03C40593;
+034B : A0DFF0EF;
+034C : 4505C119;
+034D : DC0454FD;
+034E : 442240B2;
+034F : 01414492;
+0350 : 45018082;
+0351 : 11418082;
+0352 : C606C422;
+0353 : 57FDC226;
+0354 : 000501A3;
+0355 : 842ADD1C;
+0356 : 4E113F4D;
+0357 : 10051463;
+0358 : 23B44483;
+0359 : 23A44083;
+035A : 9293632D;
+035B : E4B30084;
+035C : 03930012;
+035D : 9B63A553;
+035E : 65890074;
+035F : 8593462D;
+0360 : 051337C5;
+0361 : 256103C4;
+0362 : CD694E05;
+0363 : 03C44503;
+0364 : 0EB00713;
+0365 : 00E50963;
+0366 : 01850613;
+0367 : 0FF67693;
+0368 : 6A634805;
+0369 : 68AD0AD8;
+036A : A5588E13;
+036B : 01C49B63;
+036C : 46216E89;
+036D : 388E8593;
+036E : 08E40513;
+036F : 4E012D89;
+0370 : 4F83C155;
+0371 : 4F030484;
+0372 : 02930474;
+0373 : 97932000;
+0374 : E0B3008F;
+0375 : 906301E7;
+0376 : 43030850;
+0377 : 0C630494;
+0378 : 03930603;
+0379 : F5B3FFF3;
+037A : E5B50063;
+037B : 04B44703;
+037C : 04A44503;
+037D : 00871613;
+037E : 00A666B3;
+037F : 4803CEA9;
+0380 : 4E0504C4;
+0381 : FFF80893;
+0382 : 051E6763;
+0383 : 04E44F03;
+0384 : 04D44E83;
+0385 : 008F1F93;
+0386 : 01DFE7B3;
+0387 : 4283CF8D;
+0388 : 40830504;
+0389 : 059304F4;
+038A : 931307F0;
+038B : 63B30082;
+038C : E8630013;
+038D : 05130075;
+038E : 3B5905C4;
+038F : 6C636741;
+0390 : 450300E5;
+0391 : 44030524;
+0392 : 4E010534;
+0393 : 00841613;
+0394 : 00A666B3;
+0395 : 682DEA81;
+0396 : A5580893;
+0397 : 83634E09;
+0398 : 4E0D0114;
+0399 : 442240B2;
+039A : 85724492;
+039B : 80820141;
+039C : D2267179;
+039D : CC52CE4E;
+039E : D422D606;
+039F : CA56D04A;
+03A0 : 0005A023;
+03A1 : 8A3289AE;
+03A2 : 44AD33D5;
+03A3 : 04054163;
+03A4 : 00251713;
+03A5 : 8B018093;
+03A6 : 00E082B3;
+03A7 : 0002A403;
+03A8 : 44B1892A;
+03A9 : A023C40D;
+03AA : 43030089;
+03AB : 74930004;
+03AC : 08630FEA;
+03AD : 45030203;
+03AE : 31FD0014;
+03AF : 00157393;
+03B0 : 02039163;
+03B1 : 7493C489;
+03B2 : C0910045;
+03B3 : 50B244A9;
+03B4 : 59025422;
+03B5 : 4A6249F2;
+03B6 : 85264AD2;
+03B7 : 61455492;
+03B8 : 75138082;
+03B9 : 00230FF9;
+03BA : 00A30004;
+03BB : F0EF00A4;
+03BC : 75939A9F;
+03BD : 96630015;
+03BE : C0994005;
+03BF : F5798911;
+03C0 : 85224581;
+03C1 : 44893589;
+03C2 : 04951163;
+03C3 : 0A13848A;
+03C4 : 0A932024;
+03C5 : 89A62424;
+03C6 : 395D8552;
+03C7 : 00A9A023;
+03C8 : 09910A41;
+03C9 : FF5A1AE3;
+03CA : 01048913;
+03CB : 408C4A85;
+03CC : C589450D;
+03CD : 3D018522;
+03CE : 02AAF363;
+03CF : 98E30491;
+03D0 : 4411FF24;
+03D1 : 00851B63;
+03D2 : 4611A021;
+03D3 : 00C51463;
+03D4 : BFB54485;
+03D5 : F4634685;
+03D6 : 44B500A6;
+03D7 : 4805BF8D;
+03D8 : 03842983;
+03D9 : 1B051263;
+03DA : 04740E13;
+03DB : 07C40513;
+03DC : 000E4903;
+03DD : FE0913E3;
+03DE : 1BE30E05;
+03DF : 4E83FFC5;
+03E0 : 4A030A54;
+03E1 : 0F930A44;
+03E2 : 9F131000;
+03E3 : 64B3008E;
+03E4 : 94E3014F;
+03E5 : 4703FDF4;
+03E6 : 40A50A84;
+03E7 : FA171FE3;
+03E8 : 08440513;
+03E9 : 8A333999;
+03EA : 3AB300A9;
+03EB : 87B3013A;
+03EC : F7C500BA;
+03ED : 09040513;
+03EE : 42833921;
+03EF : D0080AA4;
+03F0 : 01234305;
+03F1 : 9AE30054;
+03F2 : 4383F862;
+03F3 : 9AB30A94;
+03F4 : 95930072;
+03F5 : D613010A;
+03F6 : 15230105;
+03F7 : DE3500C4;
+03F8 : 09840513;
+03F9 : 06B736F5;
+03FA : C8138000;
+03FB : 892AFFD6;
+03FC : F6A865E3;
+03FD : 00250893;
+03FE : 01142E23;
+03FF : 03342223;
+0400 : 09440513;
+0401 : 04B336F1;
+0402 : D8040135;
+0403 : 08C40513;
+0404 : 954E36C1;
+0405 : 010A9993;
+0406 : 0109DE13;
+0407 : 032E0EB3;
+0408 : 8F33D408;
+0409 : 6AE3009E;
+040A : 68E3F3DF;
+040B : 0513F3EA;
+040C : 3E7909C4;
+040D : 4901D448;
+040E : 0A134A81;
+040F : 10630810;
+0410 : 5F830209;
+0411 : FAE300A4;
+0412 : 544CF1FA;
+0413 : 3EFD8522;
+0414 : 015505B3;
+0415 : 39558522;
+0416 : EE051CE3;
+0417 : 07330A85;
+0418 : 40830124;
+0419 : 876303C7;
+041A : 07930140;
+041B : F9130209;
+041C : B7F11FF7;
+041D : 01490293;
+041E : 03C40993;
+041F : 00598533;
+0420 : 43053E81;
+0421 : 7AE384AA;
+0422 : 2383ECA3;
+0423 : 76E301C4;
+0424 : 5583EC75;
+0425 : 061300A4;
+0426 : 2803FFE5;
+0427 : 86B30304;
+0428 : 5A7D02C5;
+0429 : 010688B3;
+042A : 03142A23;
+042B : 02842E03;
+042C : 0074D513;
+042D : 01C505B3;
+042E : 39818522;
+042F : E8051AE3;
+0430 : 07F4FE93;
+0431 : 002E9F13;
+0432 : 01E98533;
+0433 : 06633611;
+0434 : 04850145;
+0435 : FC950CE3;
+0436 : 2C23B549;
+0437 : 2A230144;
+0438 : 49110144;
+0439 : 8B418A93;
+043A : 000AD703;
+043B : 01240023;
+043C : 00934481;
+043D : 97930017;
+043E : D9130100;
+043F : 90230107;
+0440 : 1323012A;
+0441 : B3E10124;
+0442 : 04844E03;
+0443 : 04744883;
+0444 : 20000F93;
+0445 : 008E1E93;
+0446 : 011EEF33;
+0447 : E3FF1FE3;
+0448 : 05344783;
+0449 : 05244703;
+044A : 00879093;
+044B : 00E0EA33;
+044C : 000A1663;
+044D : 06040513;
+044E : 8A2A3C61;
+044F : 04C44483;
+0450 : 03442023;
+0451 : 82934385;
+0452 : 0123FFF4;
+0453 : F3130094;
+0454 : E4E30FF2;
+0455 : 4903E063;
+0456 : 15930494;
+0457 : D5130109;
+0458 : 15230105;
+0459 : 0AE300A4;
+045A : 0A93DE05;
+045B : F633FFF9;
+045C : 14E3012A;
+045D : 4803DE06;
+045E : 468304E4;
+045F : 189304D4;
+0460 : EAB30088;
+0461 : 142300D8;
+0462 : FE130154;
+0463 : 16E300FA;
+0464 : 4F03DC0E;
+0465 : 4E830504;
+0466 : 1F9304F4;
+0467 : E533008F;
+0468 : E50901DF;
+0469 : 05C40513;
+046A : A29FF0EF;
+046B : 04B44783;
+046C : 04A44703;
+046D : 00879093;
+046E : 00E0E2B3;
+046F : D8028FE3;
+0470 : 03448333;
+0471 : 004AD493;
+0472 : 005483B3;
+0473 : 006385B3;
+0474 : D8B565E3;
+0475 : 56338D0D;
+0476 : 60E30325;
+0477 : 0937D925;
+0478 : 06931000;
+0479 : EAE3FF59;
+047A : 6841D6C6;
+047B : FF580893;
+047C : 10C8FB63;
+047D : 0493490D;
+047E : 8FB30026;
+047F : 87330132;
+0480 : CC4400B9;
+0481 : 03342223;
+0482 : 03F42423;
+0483 : 408DD818;
+0484 : 0C191663;
+0485 : 06744503;
+0486 : 06644583;
+0487 : 00851613;
+0488 : 00B666B3;
+0489 : 00DAE833;
+048A : D20819E3;
+048B : 06840513;
+048C : 9A1FF0EF;
+048D : 00249393;
+048E : 1FF38893;
+048F : DE13D448;
+0490 : 6CE30098;
+0491 : 5A7DD1CA;
+0492 : F8000E93;
+0493 : 01442C23;
+0494 : 01442A23;
+0495 : 01D40223;
+0496 : 15E34F0D;
+0497 : 4F83E9E9;
+0498 : 448306D4;
+0499 : 4A8506C4;
+049A : 008F9713;
+049B : 009760B3;
+049C : E7509AE3;
+049D : 00198593;
+049E : 3C418522;
+049F : E60514E3;
+04A0 : 23B44783;
+04A1 : 23A44983;
+04A2 : 929363AD;
+04A3 : 02230087;
+04A4 : E3330004;
+04A5 : 85930132;
+04A6 : 15E3A553;
+04A7 : 0513E4B3;
+04A8 : F0EF03C4;
+04A9 : 563792FF;
+04AA : 06934161;
+04AB : 1BE32526;
+04AC : 0513E2D5;
+04AD : F0EF2204;
+04AE : 783791BF;
+04AF : 08936141;
+04B0 : 11E32728;
+04B1 : 0513E315;
+04B2 : F0EF2244;
+04B3 : CC08907F;
+04B4 : 22840513;
+04B5 : 8FDFF0EF;
+04B6 : B529C848;
+04B7 : C60A8FE3;
+04B8 : 85334A89;
+04B9 : 1563006F;
+04BA : 93930159;
+04BB : B7A90014;
+04BC : 021487B3;
+04BD : 0014F313;
+04BE : 0017D293;
+04BF : 006283B3;
+04C0 : 448DBF25;
+04C1 : 6E05B6E9;
+04C2 : FF5E0E93;
+04C3 : 00CEBF33;
+04C4 : 001F0913;
+04C5 : 7179B5CD;
+04C6 : 0868C62A;
+04C7 : D606D422;
+04C8 : 8432C42E;
+04C9 : F0EFCE2E;
+04CA : 4363947F;
+04CB : 87130405;
+04CC : 050A8B01;
+04CD : 00A700B3;
+04CE : 0000A283;
+04CF : 8B018313;
+04D0 : 00028463;
+04D1 : 00028023;
+04D2 : 846343B2;
+04D3 : 80230003;
+04D4 : 05B30003;
+04D5 : A02300A3;
+04D6 : C4110075;
+04D7 : 006C4601;
+04D8 : 36390028;
+04D9 : 50B2842A;
+04DA : 54228522;
+04DB : 80826145;
+04DC : BFD5442D;
+04DD : 579366C1;
+04DE : 17130185;
+04DF : 53130185;
+04E0 : 83930085;
+04E1 : E2B3F006;
+04E2 : 75B300E7;
+04E3 : 05220073;
+04E4 : 00FF0837;
+04E5 : 00B2E633;
+04E6 : 010578B3;
+04E7 : 01166533;
+04E8 : A5038082;
+04E9 : 808289C1;
+04EA : C4221141;
+04EB : 6409C226;
+04EC : 87936489;
+04ED : C60643C4;
+04EE : 43C40093;
+04EF : 40F082B3;
+04F0 : D413C04A;
+04F1 : 84934022;
+04F2 : 490143C4;
+04F3 : 02891763;
+04F4 : 65096309;
+04F5 : 43C30393;
+04F6 : 44050593;
+04F7 : 40758633;
+04F8 : 40265413;
+04F9 : 43C30493;
+04FA : 1D634901;
+04FB : 40B20089;
+04FC : 44924422;
+04FD : 01414902;
+04FE : 40988082;
+04FF : 04910905;
+0500 : B7E99702;
+0501 : 09054094;
+0502 : 96820491;
+0503 : 4701BFF9;
+0504 : 00E61463;
+0505 : 80824501;
+0506 : 00E507B3;
+0507 : 86B30705;
+0508 : C28300E5;
+0509 : C3030007;
+050A : 83E3FFF6;
+050B : 8533FE62;
+050C : 80824062;
+050D : CA09832A;
+050E : 00058383;
+050F : 00730023;
+0510 : 0305167D;
+0511 : FA6D0585;
+0512 : 832A8082;
+0513 : 0023C611;
+0514 : 167D00B3;
+0515 : FE650305;
+0516 : 71198082;
+0517 : DAA6DCA2;
+0518 : D8CADE86;
+0519 : 843284AA;
+051A : 00065D63;
+051B : 08B00393;
+051C : 00752023;
+051D : 50F6557D;
+051E : 54D65466;
+051F : 61095946;
+0520 : 07938082;
+0521 : 1A232080;
+0522 : C42E00F1;
+0523 : 8636CC2E;
+0524 : 86BA4081;
+0525 : 0093C019;
+0526 : 597DFFF4;
+0527 : 8526002C;
+0528 : CE06C806;
+0529 : 01211B23;
+052A : 56632A39;
+052B : 02930125;
+052C : A02308B0;
+052D : D0610054;
+052E : 00234322;
+052F : BF650003;
+0530 : 86B28736;
+0531 : 85AA862E;
+0532 : 89C1A503;
+0533 : 1101B779;
+0534 : AB03C05A;
+0535 : CC220085;
+0536 : C452C64E;
+0537 : CE06C256;
+0538 : C84ACA26;
+0539 : 0005AA83;
+053A : 8A32842E;
+053B : EC6389B6;
+053C : D7830766;
+053D : F71300C5;
+053E : C7254807;
+053F : 01442083;
+0540 : 4309448D;
+0541 : 021482B3;
+0542 : 8393498C;
+0543 : 8B2A0016;
+0544 : 40BA8AB3;
+0545 : 01538533;
+0546 : 0262C4B3;
+0547 : 00A4F363;
+0548 : F61384AA;
+0549 : CE254007;
+054A : 855A85A6;
+054B : 031000EF;
+054C : CD3D892A;
+054D : 8656480C;
+054E : 55833DF5;
+054F : F69300C4;
+0550 : E813B7F5;
+0551 : 16230806;
+0552 : 08B30104;
+0553 : 8E330159;
+0554 : 28234154;
+0555 : 20230124;
+0556 : C8440114;
+0557 : 24238B4E;
+0558 : F36301C4;
+0559 : 8B4E0169;
+055A : 85D24008;
+055B : 2DE5865A;
+055C : 00842E83;
+055D : 00042F83;
+055E : 8F334501;
+055F : 8A33416E;
+0560 : 2423016F;
+0561 : 202301E4;
+0562 : 40F20144;
+0563 : 44D24462;
+0564 : 49B24942;
+0565 : 4A924A22;
+0566 : 61054B02;
+0567 : 86268082;
+0568 : 00EF855A;
+0569 : 892A0AF0;
+056A : 480CF14D;
+056B : 2DF9855A;
+056C : 00C45783;
+056D : 202349B1;
+056E : E713013B;
+056F : 16230407;
+0570 : 557D00E4;
+0571 : D783B7D9;
+0572 : 717100C5;
+0573 : D522D706;
+0574 : D14AD326;
+0575 : CF4ECD52;
+0576 : C95ACB56;
+0577 : C562C75E;
+0578 : C16AC366;
+0579 : F093DEEE;
+057A : 8A2A0807;
+057B : 84B2892E;
+057C : 85638436;
+057D : A2830400;
+057E : 91630105;
+057F : 05930402;
+0580 : 2FA90400;
+0581 : 00A92023;
+0582 : 00A92823;
+0583 : 4AB1E505;
+0584 : 015A2023;
+0585 : 50BA557D;
+0586 : 549A542A;
+0587 : 49FA590A;
+0588 : 4ADA4A6A;
+0589 : 4BBA4B4A;
+058A : 4C9A4C2A;
+058B : 5DF64D0A;
+058C : 8082614D;
+058D : 04000313;
+058E : 00692A23;
+058F : 02000393;
+0590 : 03000513;
+0591 : 04A3D202;
+0592 : 05230271;
+0593 : C62202A1;
+0594 : 02500C93;
+0595 : 6B896B09;
+0596 : 6C056D09;
+0597 : 00000A93;
+0598 : 45838426;
+0599 : C1990004;
+059A : 0B959163;
+059B : 40940DB3;
+059C : 00940E63;
+059D : 86EE8626;
+059E : 855285CA;
+059F : 54FD3D89;
+05A0 : 1A950B63;
+05A1 : 06B35612;
+05A2 : D23601B6;
+05A3 : 00044703;
+05A4 : 1A070363;
+05A5 : 0493587D;
+05A6 : C8020014;
+05A7 : CA42CE02;
+05A8 : 09A3CC02;
+05A9 : D4820401;
+05AA : C5834D85;
+05AB : 46150004;
+05AC : 394B0513;
+05AD : 48C22B61;
+05AE : 00148413;
+05AF : FE13E929;
+05B0 : 06630108;
+05B1 : 0E93000E;
+05B2 : 09A30200;
+05B3 : FF1305D1;
+05B4 : 06630088;
+05B5 : 0F93000F;
+05B6 : 09A302B0;
+05B7 : C78305F1;
+05B8 : 00930004;
+05B9 : 8F6302A0;
+05BA : 4DF20217;
+05BB : 45A58426;
+05BC : 45294481;
+05BD : 00044283;
+05BE : 00140393;
+05BF : FD028313;
+05C0 : 0665F763;
+05C1 : CE6EC885;
+05C2 : 0405A035;
+05C3 : 0613BF99;
+05C4 : 06B3394B;
+05C5 : 983340C5;
+05C6 : E73300DD;
+05C7 : C83A0108;
+05C8 : B76184A2;
+05C9 : 42184632;
+05CA : 00460693;
+05CB : 4963C636;
+05CC : CE3A0207;
+05CD : 00044E03;
+05CE : 02E00E93;
+05CF : 07DE1263;
+05D0 : 00144F03;
+05D1 : 02A00F93;
+05D2 : 03FF1C63;
+05D3 : 040944B2;
+05D4 : 8613408C;
+05D5 : C6320044;
+05D6 : 0205C263;
+05D7 : A089CA2E;
+05D8 : 40E00833;
+05D9 : 0028E893;
+05DA : C846CE42;
+05DB : 8433B7E1;
+05DC : 448502AD;
+05DD : 00640DB3;
+05DE : BFAD841E;
+05DF : BFF955FD;
+05E0 : CA020405;
+05E1 : 45814D81;
+05E2 : 43A94525;
+05E3 : 00044083;
+05E4 : 00140313;
+05E5 : FD008293;
+05E6 : 06557363;
+05E7 : FC0D90E3;
+05E8 : 00044583;
+05E9 : 8513460D;
+05EA : 214D39CB;
+05EB : 4E42CD11;
+05EC : 39CB8693;
+05ED : 40D50833;
+05EE : 04000713;
+05EF : 010718B3;
+05F0 : 011E6EB3;
+05F1 : C8760405;
+05F2 : 00044583;
+05F3 : 05134619;
+05F4 : 04933A0D;
+05F5 : 04230014;
+05F6 : 298D02B1;
+05F7 : 9E63C535;
+05F8 : 40C2020A;
+05F9 : F2934FB2;
+05FA : 81631000;
+05FB : 85130202;
+05FC : C62A004F;
+05FD : 85B35792;
+05FE : D22E0137;
+05FF : 87B3B595;
+0600 : 841A0275;
+0601 : 85B34D85;
+0602 : B7490057;
+0603 : 007F8313;
+0604 : FF837393;
+0605 : 00838513;
+0606 : 0078BFE9;
+0607 : 4CEC0693;
+0608 : 080C864A;
+0609 : 00978552;
+060A : 00E70000;
+060B : 5F7D0000;
+060C : 11E389AA;
+060D : 5983FDE5;
+060E : 557D00C9;
+060F : 0409F913;
+0610 : DC091BE3;
+0611 : BBC15512;
+0612 : 06930078;
+0613 : 864A4CEC;
+0614 : 8552080C;
+0615 : BFE12A0D;
+0616 : CC527179;
+0617 : 8A3A499C;
+0618 : D4224598;
+0619 : CE4ED04A;
+061A : D606CA56;
+061B : C85AD226;
+061C : 89AAC65E;
+061D : 8932842E;
+061E : D3638AB6;
+061F : 87BA00E7;
+0620 : 00F92023;
+0621 : 04344083;
+0622 : 00008663;
+0623 : 00178293;
+0624 : 00592023;
+0625 : 00042303;
+0626 : 02037393;
+0627 : 00038863;
+0628 : 00092483;
+0629 : 00248513;
+062A : 00A92023;
+062B : F493400C;
+062C : E8990065;
+062D : 01940B13;
+062E : 44505BFD;
+062F : 00092683;
+0630 : 40D60833;
+0631 : 0704C363;
+0632 : 00042B03;
+0633 : 04344883;
+0634 : 020B7B93;
+0635 : 011036B3;
+0636 : 060B9E63;
+0637 : 04340613;
+0638 : 854E85D6;
+0639 : 57FD9A02;
+063A : 04F50863;
+063B : 00042083;
+063C : 44814311;
+063D : 0060F293;
+063E : 00629B63;
+063F : 00C42383;
+0640 : 00092903;
+0641 : 412384B3;
+0642 : 0004D363;
+0643 : 44084481;
+0644 : D563480C;
+0645 : 063300A5;
+0646 : 94B240B5;
+0647 : 04694B81;
+0648 : 99635B7D;
+0649 : 45010574;
+064A : 4685A809;
+064B : 85D6865A;
+064C : 9A02854E;
+064D : 01751E63;
+064E : 50B2557D;
+064F : 54925422;
+0650 : 49F25902;
+0651 : 4AD24A62;
+0652 : 4BB24B42;
+0653 : 80826145;
+0654 : B7A50485;
+0655 : 00D40EB3;
+0656 : 03000F13;
+0657 : 05EE81A3;
+0658 : 04544F83;
+0659 : 00168E13;
+065A : 01C40733;
+065B : 01A30689;
+065C : B7AD05F7;
+065D : 86224685;
+065E : 854E85D6;
+065F : 0DE39A02;
+0660 : 0B85FB65;
+0661 : 7179BF79;
+0662 : D226D422;
+0663 : CE4ED04A;
+0664 : CC52D606;
+0665 : C85ACA56;
+0666 : 0185C883;
+0667 : 07800793;
+0668 : 842E84AA;
+0669 : 89B68932;
+066A : 0117EE63;
+066B : 06200093;
+066C : 04358693;
+066D : 0110ED63;
+066E : 20088863;
+066F : 05800593;
+0670 : 1CB88463;
+0671 : 04240A93;
+0672 : 05140123;
+0673 : 8293A81D;
+0674 : F313F9D8;
+0675 : 46550FF2;
+0676 : FE6666E3;
+0677 : 13936509;
+0678 : 05930023;
+0679 : 88333D05;
+067A : 2A0300B3;
+067B : 8A020008;
+067C : 0A93431C;
+067D : 43900424;
+067E : 00478693;
+067F : 0123C314;
+0680 : 4F8504C4;
+0681 : 2E03AAC5;
+0682 : 2E830004;
+0683 : 7F930007;
+0684 : 8F13080E;
+0685 : 8363004E;
+0686 : A783020F;
+0687 : 2023000E;
+0688 : 628901E7;
+0689 : 0007D863;
+068A : 02D00313;
+068B : 40F007B3;
+068C : 046401A3;
+068D : 3A828393;
+068E : A8A948A9;
+068F : 000EA783;
+0690 : 040E7093;
+0691 : 01E72023;
+0692 : FC008DE3;
+0693 : 01079713;
+0694 : 41075793;
+0695 : 2F83B7F9;
+0696 : 431C0004;
+0697 : 080FF293;
+0698 : 00478093;
+0699 : 00028663;
+069A : 00172023;
+069B : A809439C;
+069C : 040FF313;
+069D : 00172023;
+069E : FE030AE3;
+069F : 0007D783;
+06A0 : 06136389;
+06A1 : 839306F0;
+06A2 : 83633A83;
+06A3 : 48A910C8;
+06A4 : 040401A3;
+06A5 : 00442283;
+06A6 : 00542423;
+06A7 : 0002C763;
+06A8 : 00042303;
+06A9 : FFB37613;
+06AA : E781C010;
+06AB : 81638AB6;
+06AC : 8AB60202;
+06AD : 0317F5B3;
+06AE : 853E1AFD;
+06AF : 00B38A33;
+06B0 : 000A4803;
+06B1 : 0317D7B3;
+06B2 : 010A8023;
+06B3 : FF1574E3;
+06B4 : 936343A1;
+06B5 : 28830278;
+06B6 : FB130004;
+06B7 : 0D630018;
+06B8 : 2E03000B;
+06B9 : 2E830044;
+06BA : C7630104;
+06BB : 0F1301CE;
+06BC : 8FA30300;
+06BD : 1AFDFFEA;
+06BE : 415686B3;
+06BF : 874EC814;
+06C0 : 007086CA;
+06C1 : 852685A2;
+06C2 : 5A7D3B81;
+06C3 : 0F451963;
+06C4 : 50B2557D;
+06C5 : 54925422;
+06C6 : 49F25902;
+06C7 : 4AD24A62;
+06C8 : 61454B42;
+06C9 : 2E038082;
+06CA : 6E930004;
+06CB : 2023020E;
+06CC : 6F0901D4;
+06CD : 07800893;
+06CE : 3BCF0393;
+06CF : 051402A3;
+06D0 : 00042803;
+06D1 : 7B134308;
+06D2 : 411C0808;
+06D3 : 00450A93;
+06D4 : 000B1A63;
+06D5 : 04087E13;
+06D6 : 000E0663;
+06D7 : 01079E93;
+06D8 : 010ED793;
+06D9 : 01572023;
+06DA : 00187F13;
+06DB : 000F0663;
+06DC : 02086F93;
+06DD : 01F42023;
+06DE : FB9948C1;
+06DF : 00042083;
+06E0 : FDF0F713;
+06E1 : B729C018;
+06E2 : 03936A09;
+06E3 : B77D3A8A;
+06E4 : BDFD48A1;
+06E5 : 00042883;
+06E6 : 00072A03;
+06E7 : F813484C;
+06E8 : 05130808;
+06E9 : 0863004A;
+06EA : C3080008;
+06EB : 000A2B03;
+06EC : 00BB2023;
+06ED : C308A811;
+06EE : 0408FA93;
+06EF : 000A2B03;
+06F0 : FE0A88E3;
+06F1 : 00BB1023;
+06F2 : 00042823;
+06F3 : BF058AB6;
+06F4 : 00072A83;
+06F5 : 45814050;
+06F6 : 004A8B13;
+06F7 : 01672023;
+06F8 : 000AAA83;
+06F9 : 209D8556;
+06FA : 0733C501;
+06FB : C0584155;
+06FC : 00442F83;
+06FD : 01F42823;
+06FE : 040401A3;
+06FF : 4814B709;
+0700 : 85CA8656;
+0701 : 99828526;
+0702 : F14504E3;
+0703 : 00042083;
+0704 : 0020F713;
+0705 : 44B2E71D;
+0706 : 5CE34448;
+0707 : 8526EE95;
+0708 : 4685BDCD;
+0709 : 85CA8656;
+070A : 99828526;
+070B : EF6502E3;
+070C : 22830A05;
+070D : 433200C4;
+070E : 40628633;
+070F : FECA43E3;
+0710 : 4A01BFD9;
+0711 : 01940A93;
+0712 : B7E55B7D;
+0713 : 0FF5F593;
+0714 : 1463962A;
+0715 : 450100C5;
+0716 : 47838082;
+0717 : 8DE30005;
+0718 : 0505FEB7;
+0719 : C215B7FD;
+071A : 4685832A;
+071B : 00B56763;
+071C : 071356FD;
+071D : 933AFFF6;
+071E : 838395BA;
+071F : 00230005;
+0720 : 167D0073;
+0721 : 95B69336;
+0722 : 8082FA6D;
+0723 : A783C5F9;
+0724 : 1101FFC5;
+0725 : CE06CC22;
+0726 : FFC58413;
+0727 : 0007D363;
+0728 : C62A943E;
+0729 : A8032C81;
+072A : 45328B81;
+072B : 00081A63;
+072C : 00042223;
+072D : 8A81AC23;
+072E : 40F24462;
+072F : AC256105;
+0730 : 03047363;
+0731 : 00042083;
+0732 : 001406B3;
+0733 : 00D81A63;
+0734 : 00082603;
+0735 : 00482803;
+0736 : 001602B3;
+0737 : 00542023;
+0738 : 01042223;
+0739 : 80C2BFC1;
+073A : 00482803;
+073B : 00080463;
+073C : FF047BE3;
+073D : 0000A683;
+073E : 00D08633;
+073F : 02861763;
+0740 : 00042E03;
+0741 : 01C68EB3;
+0742 : 01D0A023;
+0743 : 01D08F33;
+0744 : FBE814E3;
+0745 : 00082F83;
+0746 : 00482403;
+0747 : 01DF87B3;
+0748 : 00F0A023;
+0749 : 0080A223;
+074A : 7663BF41;
+074B : 48B100C4;
+074C : 01152023;
+074D : 2283B751;
+074E : 03330004;
+074F : 19630054;
+0750 : 23830068;
+0751 : 28030008;
+0752 : 85B30048;
+0753 : C00C0053;
+0754 : 01042223;
+0755 : 0080A223;
+0756 : 8082B785;
+0757 : CA261101;
+0758 : 00358493;
+0759 : F093CE06;
+075A : C84AFFC4;
+075B : C64ECC22;
+075C : 00808493;
+075D : 892A47B1;
+075E : 04F4F663;
+075F : E56344B1;
+0760 : 854A04B4;
+0761 : 87132A85;
+0762 : 28838B81;
+0763 : 86930007;
+0764 : 84468B81;
+0765 : 8993E429;
+0766 : A3038BC1;
+0767 : 17630009;
+0768 : 45810003;
+0769 : 2A39854A;
+076A : 00A9A023;
+076B : 854A85A6;
+076C : 59FD2A11;
+076D : 09351163;
+076E : 20234531;
+076F : 854A00A9;
+0770 : A0312A1D;
+0771 : FA04DDE3;
+0772 : 202342B1;
+0773 : 45010059;
+0774 : 446240F2;
+0775 : 494244D2;
+0776 : 610549B2;
+0777 : 400C8082;
+0778 : 40958833;
+0779 : 04084663;
+077A : 7763462D;
+077B : 20230106;
+077C : 94420104;
+077D : A039C004;
+077E : 00442E03;
+077F : 02889763;
+0780 : 01C6A023;
+0781 : 28C5854A;
+0782 : 00B40F13;
+0783 : 00440E93;
+0784 : FF8F7513;
+0785 : 41D50FB3;
+0786 : FBD50CE3;
+0787 : 01F400B3;
+0788 : 40AE87B3;
+0789 : 00F0A023;
+078A : A223B765;
+078B : BFD901C8;
+078C : 404088A2;
+078D : 0393B785;
+078E : F4130035;
+078F : 0BE3FFC3;
+0790 : 05B3FA85;
+0791 : 854A40A4;
+0792 : 15E328B5;
+0793 : B7ADFB35;
+0794 : CC221101;
+0795 : CA26CE06;
+0796 : C64EC84A;
+0797 : 8432C452;
+0798 : 4462E991;
+0799 : 44D240F2;
+079A : 49B24942;
+079B : 85B24A22;
+079C : B5ED6105;
+079D : 3D19EE01;
+079E : 40F24481;
+079F : 49424462;
+07A0 : 4A2249B2;
+07A1 : 44D28526;
+07A2 : 80826105;
+07A3 : 892E8A2A;
+07A4 : 89AA20A5;
+07A5 : 00856763;
+07A6 : 00155793;
+07A7 : EEE384CA;
+07A8 : 85A2FC87;
+07A9 : 3D5D8552;
+07AA : D96184AA;
+07AB : F3638622;
+07AC : 864E0089;
+07AD : 852685CA;
+07AE : D7CFF0EF;
+07AF : 855285CA;
+07B0 : BF6533F1;
+07B1 : C4221141;
+07B2 : 842AC226;
+07B3 : C606852E;
+07B4 : 8C01A023;
+07B5 : D0CFE0EF;
+07B6 : 186357FD;
+07B7 : A08300F5;
+07B8 : 84638C01;
+07B9 : 20230000;
+07BA : 40B20014;
+07BB : 44924422;
+07BC : 80820141;
+07BD : 80828082;
+07BE : FFC5A783;
+07BF : FFC78513;
+07C0 : 0007D663;
+07C1 : A28395AA;
+07C2 : 95160005;
+07C3 : 00008082;
+07C4 : 00000000;
+07C5 : 2070250A;
+07C6 : 6572203A;
+07C7 : 25206461;
+07C8 : 20783830;
+07C9 : 65707865;
+07CA : 64657463;
+07CB : 38302520;
+07CC : 00000A78;
+07CD : 73696854;
+07CE : 20736920;
+07CF : 706F6F6C;
+07D0 : 7525203A;
+07D1 : 0000000A;
+07D2 : 41524453;
+07D3 : 6F64204D;
+07D4 : 6F6C6E77;
+07D5 : 74206461;
+07D6 : 206B6F6F;
+07D7 : 75207525;
+07D8 : 00000A73;
+07D9 : 3A207025;
+07DA : 25783020;
+07DB : 20783830;
+07DC : 65707865;
+07DD : 64657463;
+07DE : 25783020;
+07DF : 0A783830;
+07E0 : 00000000;
+07E1 : 252F7525;
+07E2 : 6F772075;
+07E3 : 20736472;
+07E4 : 0A0A4B4F;
+07E5 : 00000000;
+07E6 : 34302520;
+07E7 : 30252E78;
+07E8 : 00007834;
+07E9 : 74736554;
+07EA : 20676E69;
+07EB : 41524453;
+07EC : 7266204D;
+07ED : 30206D6F;
+07EE : 38302578;
+07EF : 6F742078;
+07F0 : 25783020;
+07F1 : 2C783830;
+07F2 : 72747320;
+07F3 : 20656469;
+07F4 : 30257830;
+07F5 : 2E2E7838;
+07F6 : 00000A2E;
+07F7 : 6165520A;
+07F8 : 676E6964;
+07F9 : 63616220;
+07FA : 6F74206B;
+07FB : 65686320;
+07FC : 66206B63;
+07FD : 6120726F;
+07FE : 7361696C;
+07FF : 2E2E7365;
+0800 : 00000A2E;
+0801 : 5244530A;
+0802 : 74204D41;
+0803 : 20747365;
+0804 : 706D6F63;
+0805 : 6574656C;
+0806 : 6974202C;
+0807 : 3D20656D;
+0808 : 20752520;
+0809 : 000A736D;
+080A : 202A2A2A;
+080B : 6E696F44;
+080C : 65722067;
+080D : 20746573;
+080E : 0A2A2A2A;
+080F : 00000000;
+0810 : 2A2A2A0A;
+0811 : 6C654820;
+0812 : 202C6F6C;
+0813 : 6C726F57;
+0814 : 2A202164;
+0815 : 460A2A2A;
+0816 : 776D7269;
+0817 : 20657261;
+0818 : 706D6F63;
+0819 : 64656C69;
+081A : 3A6E6F20;
+081B : 74634F20;
+081C : 20352020;
+081D : 31323032;
+081E : 3A363120;
+081F : 353A3935;
+0820 : 000A0A30;
+0821 : 61636473;
+0822 : 725F6472;
+0823 : 5F646165;
+0824 : 636F6C62;
+0825 : 62203A6B;
+0826 : 74206461;
+0827 : 6E656B6F;
+0828 : 3025203A;
+0829 : 000A7832;
+082A : 61636473;
+082B : 725F6472;
+082C : 5F646165;
+082D : 636F6C62;
+082E : 72203A6B;
+082F : 796C7065;
+0830 : 6D697420;
+0831 : 74756F65;
+0832 : 0000000A;
+0833 : 61636473;
+0834 : 725F6472;
+0835 : 5F646165;
+0836 : 636F6C62;
+0837 : 43203A6B;
+0838 : 65204352;
+0839 : 726F7272;
+083A : 637A2820;
+083B : 3D206372;
+083C : 34302520;
+083D : 000A2978;
+083E : 61636473;
+083F : 203A6472;
+0840 : 64616572;
+0841 : 20676E69;
+0842 : 73206425;
+0843 : 6F746365;
+0844 : 61207372;
+0845 : 75252074;
+0846 : 206F7420;
+0847 : 000A7025;
+0848 : 61636473;
+0849 : 203A6472;
+084A : 64616572;
+084B : 6C756D5F;
+084C : 6C706974;
+084D : 72652065;
+084E : 20726F72;
+084F : 78323025;
+0850 : 0000000A;
+0851 : 61636473;
+0852 : 203A6472;
+0853 : 64616572;
+0854 : 6365735F;
+0855 : 73726F74;
+0856 : 6574203A;
+0857 : 6E696D72;
+0858 : 20657461;
+0859 : 6D6D6F63;
+085A : 20646E61;
+085B : 6F727265;
+085C : 30252072;
+085D : 000A7832;
+085E : 61636473;
+085F : 203A6472;
+0860 : 74697277;
+0861 : 20676E69;
+0862 : 73206425;
+0863 : 6F746365;
+0864 : 61207372;
+0865 : 75252074;
+0866 : 6F726620;
+0867 : 7025206D;
+0868 : 0000000A;
+0869 : 61636473;
+086A : 203A6472;
+086B : 74697277;
+086C : 756D5F65;
+086D : 7069746C;
+086E : 6520656C;
+086F : 726F7272;
+0870 : 32302520;
+0871 : 00000A78;
+0872 : 61636473;
+0873 : 203A6472;
+0874 : 30444D43;
+0875 : 72726520;
+0876 : 2520726F;
+0877 : 0A783230;
+0878 : 00000000;
+0879 : 61636473;
+087A : 203B6472;
+087B : 38444D43;
+087C : 72726520;
+087D : 2520726F;
+087E : 0A783230;
+087F : 00000000;
+0880 : 61636473;
+0881 : 203A6472;
+0882 : 38444D43;
+0883 : 74657220;
+0884 : 656E7275;
+0885 : 78302064;
+0886 : 78383025;
+0887 : 0000000A;
+0888 : 61636473;
+0889 : 203A6472;
+088A : 38444D43;
+088B : 70657220;
+088C : 7374726F;
+088D : 756E7520;
+088E : 6C626173;
+088F : 61632065;
+0890 : 28206472;
+0891 : 78257830;
+0892 : 00000A29;
+0893 : 61636473;
+0894 : 203A6472;
+0895 : 444D4341;
+0896 : 65203134;
+0897 : 726F7272;
+0898 : 32302520;
+0899 : 00000A78;
+089A : 61636473;
+089B : 203A6472;
+089C : 35444D43;
+089D : 72652038;
+089E : 20726F72;
+089F : 78323025;
+08A0 : 0000000A;
+08A1 : 61636473;
+08A2 : 203A6472;
+08A3 : 31444D43;
+08A4 : 72726520;
+08A5 : 2520726F;
+08A6 : 0A783230;
+08A7 : 00000000;
+08A8 : 61636473;
+08A9 : 203A6472;
+08AA : 31444D43;
+08AB : 72652036;
+08AC : 20726F72;
+08AD : 78323025;
+08AE : 0000000A;
+08AF : 61636473;
+08B0 : 203A6472;
+08B1 : 3A445343;
+08B2 : 38302520;
+08B3 : 30252078;
+08B4 : 25207838;
+08B5 : 20783830;
+08B6 : 78383025;
+08B7 : 0000000A;
+08B8 : 61636473;
+08B9 : 203A6472;
+08BA : 3A444943;
+08BB : 38302520;
+08BC : 30252078;
+08BD : 25207838;
+08BE : 20783830;
+08BF : 78383025;
+08C0 : 0000000A;
+08C1 : 61636473;
+08C2 : 203A6472;
+08C3 : 63207325;
+08C4 : 20647261;
+08C5 : 6E756F66;
+08C6 : 63202C64;
+08C7 : 63617061;
+08C8 : 20797469;
+08C9 : 73207525;
+08CA : 6F746365;
+08CB : 000A7372;
+08CC : 61636473;
+08CD : 203A6472;
+08CE : 74697773;
+08CF : 64656863;
+08D0 : 206F7420;
+08D1 : 68676968;
+08D2 : 65707320;
+08D3 : 000A6465;
+08D4 : 6E6B6E75;
+08D5 : 006E776F;
+08D6 : 4D2F4453;
+08D7 : 0000434D;
+08D8 : 43484453;
+08D9 : 5844532F;
+08DA : 4D652F43;
+08DB : 0000434D;
+08DC : 00002350;
+08DD : 00002358;
+08DE : 00002360;
+08DF : 459076EB;
+08E0 : 54414658;
+08E1 : 00202020;
+08E2 : 33544146;
+08E3 : 20202032;
+08E4 : 00000000;
+08E5 : 2B302D23;
+08E6 : 00000020;
+08E7 : 004C6C68;
+08E8 : 45676665;
+08E9 : 00004746;
+08EA : 33323130;
+08EB : 37363534;
+08EC : 42413938;
+08ED : 46454443;
+08EE : 00000000;
+08EF : 33323130;
+08F0 : 37363534;
+08F1 : 62613938;
+08F2 : 66656463;
+08F3 : 00000000;
+08F4 : 000019F0;
+08F5 : 00001A06;
+08F6 : 000019C4;
+08F7 : 000019C4;
+08F8 : 000019C4;
+08F9 : 000019C4;
+08FA : 00001A06;
+08FB : 000019C4;
+08FC : 000019C4;
+08FD : 000019C4;
+08FE : 000019C4;
+08FF : 00001B94;
+0900 : 00001A56;
+0901 : 00001B26;
+0902 : 000019C4;
+0903 : 000019C4;
+0904 : 00001BD0;
+0905 : 000019C4;
+0906 : 00001A56;
+0907 : 000019C4;
+0908 : 000019C4;
+0909 : 00001B32;
+090A : 00000000;
+090B : 00000000;
+090C : 00000000;
+090D : 00000000;
+090E : 00000000;
+090F : 0000039C;
+0910 : 0000036C;
+0911 : 00000001;
+0912 : 00000000;
+0913 : 00000000;
+0914 : 00000000;
+0915 : 00000000;
+0916 : 00000000;
+0917 : 00000000;
+0918 : 00000000;
+0919 : 00000000;
+091A : 00000000;
+091B : 00000000;
+091C : 00000000;
+091D : 00000000;
+091E : 00000000;
+091F : 00000000;
+0920 : 00000000;
+0921 : 00000000;
+0922 : 00000000;
+0923 : 00000000;
+0924 : 00000000;
+0925 : 00000000;
+0926 : 00000000;
+0927 : 00000000;
+0928 : 00000000;
+0929 : 00000000;
+092A : 00000000;
+092B : 00000000;
+092C : 00000000;
+092D : 00000000;
+092E : 00000000;
+092F : 00000000;
+0930 : 00000000;
+0931 : 00000000;
+0932 : 00000000;
+0933 : 00000000;
+0934 : 00000000;
+0935 : 0000275C;
+0936 : 00000001;
+0937 : 00000004;
+0938 : 00002474;
+[0939..1FFF] : 00;
 END;

+ 2 - 0
fw/fatfs/orig/README

@@ -0,0 +1,2 @@
+This directory contains unmodified versions of source
+files that have been modified for the MAX80 project.

+ 301 - 0
fw/fatfs/orig/ffconf.h

@@ -0,0 +1,301 @@
+/*---------------------------------------------------------------------------/
+/  FatFs Functional Configurations
+/---------------------------------------------------------------------------*/
+
+#define FFCONF_DEF	86631	/* Revision ID */
+
+/*---------------------------------------------------------------------------/
+/ Function Configurations
+/---------------------------------------------------------------------------*/
+
+#define FF_FS_READONLY	0
+/* This option switches read-only configuration. (0:Read/Write or 1:Read-only)
+/  Read-only configuration removes writing API functions, f_write(), f_sync(),
+/  f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree()
+/  and optional writing functions as well. */
+
+
+#define FF_FS_MINIMIZE	0
+/* This option defines minimization level to remove some basic API functions.
+/
+/   0: Basic functions are fully enabled.
+/   1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_truncate() and f_rename()
+/      are removed.
+/   2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1.
+/   3: f_lseek() function is removed in addition to 2. */
+
+
+#define FF_USE_FIND		0
+/* This option switches filtered directory read functions, f_findfirst() and
+/  f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */
+
+
+#define FF_USE_MKFS		0
+/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */
+
+
+#define FF_USE_FASTSEEK	0
+/* This option switches fast seek function. (0:Disable or 1:Enable) */
+
+
+#define FF_USE_EXPAND	0
+/* This option switches f_expand function. (0:Disable or 1:Enable) */
+
+
+#define FF_USE_CHMOD	0
+/* This option switches attribute manipulation functions, f_chmod() and f_utime().
+/  (0:Disable or 1:Enable) Also FF_FS_READONLY needs to be 0 to enable this option. */
+
+
+#define FF_USE_LABEL	0
+/* This option switches volume label functions, f_getlabel() and f_setlabel().
+/  (0:Disable or 1:Enable) */
+
+
+#define FF_USE_FORWARD	0
+/* This option switches f_forward() function. (0:Disable or 1:Enable) */
+
+
+#define FF_USE_STRFUNC	0
+#define FF_PRINT_LLI	0
+#define FF_PRINT_FLOAT	0
+#define FF_STRF_ENCODE	0
+/* FF_USE_STRFUNC switches string functions, f_gets(), f_putc(), f_puts() and
+/  f_printf().
+/
+/   0: Disable. FF_PRINT_LLI, FF_PRINT_FLOAT and FF_STRF_ENCODE have no effect.
+/   1: Enable without LF-CRLF conversion.
+/   2: Enable with LF-CRLF conversion.
+/
+/  FF_PRINT_LLI = 1 makes f_printf() support long long argument and FF_PRINT_FLOAT = 1/2
+   makes f_printf() support floating point argument. These features want C99 or later.
+/  When FF_LFN_UNICODE >= 1 with LFN enabled, string functions convert the character
+/  encoding in it. FF_STRF_ENCODE selects assumption of character encoding ON THE FILE
+/  to be read/written via those functions.
+/
+/   0: ANSI/OEM in current CP
+/   1: Unicode in UTF-16LE
+/   2: Unicode in UTF-16BE
+/   3: Unicode in UTF-8
+*/
+
+
+/*---------------------------------------------------------------------------/
+/ Locale and Namespace Configurations
+/---------------------------------------------------------------------------*/
+
+#define FF_CODE_PAGE	932
+/* This option specifies the OEM code page to be used on the target system.
+/  Incorrect code page setting can cause a file open failure.
+/
+/   437 - U.S.
+/   720 - Arabic
+/   737 - Greek
+/   771 - KBL
+/   775 - Baltic
+/   850 - Latin 1
+/   852 - Latin 2
+/   855 - Cyrillic
+/   857 - Turkish
+/   860 - Portuguese
+/   861 - Icelandic
+/   862 - Hebrew
+/   863 - Canadian French
+/   864 - Arabic
+/   865 - Nordic
+/   866 - Russian
+/   869 - Greek 2
+/   932 - Japanese (DBCS)
+/   936 - Simplified Chinese (DBCS)
+/   949 - Korean (DBCS)
+/   950 - Traditional Chinese (DBCS)
+/     0 - Include all code pages above and configured by f_setcp()
+*/
+
+
+#define FF_USE_LFN		0
+#define FF_MAX_LFN		255
+/* The FF_USE_LFN switches the support for LFN (long file name).
+/
+/   0: Disable LFN. FF_MAX_LFN has no effect.
+/   1: Enable LFN with static  working buffer on the BSS. Always NOT thread-safe.
+/   2: Enable LFN with dynamic working buffer on the STACK.
+/   3: Enable LFN with dynamic working buffer on the HEAP.
+/
+/  To enable the LFN, ffunicode.c needs to be added to the project. The LFN function
+/  requiers certain internal working buffer occupies (FF_MAX_LFN + 1) * 2 bytes and
+/  additional (FF_MAX_LFN + 44) / 15 * 32 bytes when exFAT is enabled.
+/  The FF_MAX_LFN defines size of the working buffer in UTF-16 code unit and it can
+/  be in range of 12 to 255. It is recommended to be set it 255 to fully support LFN
+/  specification.
+/  When use stack for the working buffer, take care on stack overflow. When use heap
+/  memory for the working buffer, memory management functions, ff_memalloc() and
+/  ff_memfree() exemplified in ffsystem.c, need to be added to the project. */
+
+
+#define FF_LFN_UNICODE	0
+/* This option switches the character encoding on the API when LFN is enabled.
+/
+/   0: ANSI/OEM in current CP (TCHAR = char)
+/   1: Unicode in UTF-16 (TCHAR = WCHAR)
+/   2: Unicode in UTF-8 (TCHAR = char)
+/   3: Unicode in UTF-32 (TCHAR = DWORD)
+/
+/  Also behavior of string I/O functions will be affected by this option.
+/  When LFN is not enabled, this option has no effect. */
+
+
+#define FF_LFN_BUF		255
+#define FF_SFN_BUF		12
+/* This set of options defines size of file name members in the FILINFO structure
+/  which is used to read out directory items. These values should be suffcient for
+/  the file names to read. The maximum possible length of the read file name depends
+/  on character encoding. When LFN is not enabled, these options have no effect. */
+
+
+#define FF_FS_RPATH		0
+/* This option configures support for relative path.
+/
+/   0: Disable relative path and remove related functions.
+/   1: Enable relative path. f_chdir() and f_chdrive() are available.
+/   2: f_getcwd() function is available in addition to 1.
+*/
+
+
+/*---------------------------------------------------------------------------/
+/ Drive/Volume Configurations
+/---------------------------------------------------------------------------*/
+
+#define FF_VOLUMES		1
+/* Number of volumes (logical drives) to be used. (1-10) */
+
+
+#define FF_STR_VOLUME_ID	0
+#define FF_VOLUME_STRS		"RAM","NAND","CF","SD","SD2","USB","USB2","USB3"
+/* FF_STR_VOLUME_ID switches support for volume ID in arbitrary strings.
+/  When FF_STR_VOLUME_ID is set to 1 or 2, arbitrary strings can be used as drive
+/  number in the path name. FF_VOLUME_STRS defines the volume ID strings for each
+/  logical drives. Number of items must not be less than FF_VOLUMES. Valid
+/  characters for the volume ID strings are A-Z, a-z and 0-9, however, they are
+/  compared in case-insensitive. If FF_STR_VOLUME_ID >= 1 and FF_VOLUME_STRS is
+/  not defined, a user defined volume string table needs to be defined as:
+/
+/  const char* VolumeStr[FF_VOLUMES] = {"ram","flash","sd","usb",...
+*/
+
+
+#define FF_MULTI_PARTITION	0
+/* This option switches support for multiple volumes on the physical drive.
+/  By default (0), each logical drive number is bound to the same physical drive
+/  number and only an FAT volume found on the physical drive will be mounted.
+/  When this function is enabled (1), each logical drive number can be bound to
+/  arbitrary physical drive and partition listed in the VolToPart[]. Also f_fdisk()
+/  funciton will be available. */
+
+
+#define FF_MIN_SS		512
+#define FF_MAX_SS		512
+/* This set of options configures the range of sector size to be supported. (512,
+/  1024, 2048 or 4096) Always set both 512 for most systems, generic memory card and
+/  harddisk, but a larger value may be required for on-board flash memory and some
+/  type of optical media. When FF_MAX_SS is larger than FF_MIN_SS, FatFs is configured
+/  for variable sector size mode and disk_ioctl() function needs to implement
+/  GET_SECTOR_SIZE command. */
+
+
+#define FF_LBA64		0
+/* This option switches support for 64-bit LBA. (0:Disable or 1:Enable)
+/  To enable the 64-bit LBA, also exFAT needs to be enabled. (FF_FS_EXFAT == 1) */
+
+
+#define FF_MIN_GPT		0x10000000
+/* Minimum number of sectors to switch GPT as partitioning format in f_mkfs and
+/  f_fdisk function. 0x100000000 max. This option has no effect when FF_LBA64 == 0. */
+
+
+#define FF_USE_TRIM		0
+/* This option switches support for ATA-TRIM. (0:Disable or 1:Enable)
+/  To enable Trim function, also CTRL_TRIM command should be implemented to the
+/  disk_ioctl() function. */
+
+
+
+/*---------------------------------------------------------------------------/
+/ System Configurations
+/---------------------------------------------------------------------------*/
+
+#define FF_FS_TINY		0
+/* This option switches tiny buffer configuration. (0:Normal or 1:Tiny)
+/  At the tiny configuration, size of file object (FIL) is shrinked FF_MAX_SS bytes.
+/  Instead of private sector buffer eliminated from the file object, common sector
+/  buffer in the filesystem object (FATFS) is used for the file data transfer. */
+
+
+#define FF_FS_EXFAT		0
+/* This option switches support for exFAT filesystem. (0:Disable or 1:Enable)
+/  To enable exFAT, also LFN needs to be enabled. (FF_USE_LFN >= 1)
+/  Note that enabling exFAT discards ANSI C (C89) compatibility. */
+
+
+#define FF_FS_NORTC		0
+#define FF_NORTC_MON	1
+#define FF_NORTC_MDAY	1
+#define FF_NORTC_YEAR	2020
+/* The option FF_FS_NORTC switches timestamp functiton. If the system does not have
+/  any RTC function or valid timestamp is not needed, set FF_FS_NORTC = 1 to disable
+/  the timestamp function. Every object modified by FatFs will have a fixed timestamp
+/  defined by FF_NORTC_MON, FF_NORTC_MDAY and FF_NORTC_YEAR in local time.
+/  To enable timestamp function (FF_FS_NORTC = 0), get_fattime() function need to be
+/  added to the project to read current time form real-time clock. FF_NORTC_MON,
+/  FF_NORTC_MDAY and FF_NORTC_YEAR have no effect.
+/  These options have no effect in read-only configuration (FF_FS_READONLY = 1). */
+
+
+#define FF_FS_NOFSINFO	0
+/* If you need to know correct free space on the FAT32 volume, set bit 0 of this
+/  option, and f_getfree() function at first time after volume mount will force
+/  a full FAT scan. Bit 1 controls the use of last allocated cluster number.
+/
+/  bit0=0: Use free cluster count in the FSINFO if available.
+/  bit0=1: Do not trust free cluster count in the FSINFO.
+/  bit1=0: Use last allocated cluster number in the FSINFO if available.
+/  bit1=1: Do not trust last allocated cluster number in the FSINFO.
+*/
+
+
+#define FF_FS_LOCK		0
+/* The option FF_FS_LOCK switches file lock function to control duplicated file open
+/  and illegal operation to open objects. This option must be 0 when FF_FS_READONLY
+/  is 1.
+/
+/  0:  Disable file lock function. To avoid volume corruption, application program
+/      should avoid illegal open, remove and rename to the open objects.
+/  >0: Enable file lock function. The value defines how many files/sub-directories
+/      can be opened simultaneously under file lock control. Note that the file
+/      lock control is independent of re-entrancy. */
+
+
+/* #include <somertos.h>	// O/S definitions */
+#define FF_FS_REENTRANT	0
+#define FF_FS_TIMEOUT	1000
+#define FF_SYNC_t		HANDLE
+/* The option FF_FS_REENTRANT switches the re-entrancy (thread safe) of the FatFs
+/  module itself. Note that regardless of this option, file access to different
+/  volume is always re-entrant and volume control functions, f_mount(), f_mkfs()
+/  and f_fdisk() function, are always not re-entrant. Only file/directory access
+/  to the same volume is under control of this function.
+/
+/   0: Disable re-entrancy. FF_FS_TIMEOUT and FF_SYNC_t have no effect.
+/   1: Enable re-entrancy. Also user provided synchronization handlers,
+/      ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj()
+/      function, must be added to the project. Samples are available in
+/      option/syscall.c.
+/
+/  The FF_FS_TIMEOUT defines timeout period in unit of time tick.
+/  The FF_SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*,
+/  SemaphoreHandle_t and etc. A header file for O/S definitions needs to be
+/  included somewhere in the scope of ff.h. */
+
+
+
+/*--- End of configuration options ---*/

+ 6 - 6
fw/fatfs/source/ffconf.h

@@ -34,7 +34,7 @@
 /* This option switches f_mkfs() function. (0:Disable or 1:Enable) */
 
 
-#define FF_USE_FASTSEEK	0
+#define FF_USE_FASTSEEK	1
 /* This option switches fast seek function. (0:Disable or 1:Enable) */
 
 
@@ -42,12 +42,12 @@
 /* This option switches f_expand function. (0:Disable or 1:Enable) */
 
 
-#define FF_USE_CHMOD	0
+#define FF_USE_CHMOD	1
 /* This option switches attribute manipulation functions, f_chmod() and f_utime().
 /  (0:Disable or 1:Enable) Also FF_FS_READONLY needs to be 0 to enable this option. */
 
 
-#define FF_USE_LABEL	0
+#define FF_USE_LABEL	1
 /* This option switches volume label functions, f_getlabel() and f_setlabel().
 /  (0:Disable or 1:Enable) */
 
@@ -84,7 +84,7 @@
 / Locale and Namespace Configurations
 /---------------------------------------------------------------------------*/
 
-#define FF_CODE_PAGE	932
+#define FF_CODE_PAGE	437	/* XXX: add explicit support for ISO-646-SE2? */
 /* This option specifies the OEM code page to be used on the target system.
 /  Incorrect code page setting can cause a file open failure.
 /
@@ -113,7 +113,7 @@
 */
 
 
-#define FF_USE_LFN		0
+#define FF_USE_LFN		2
 #define FF_MAX_LFN		255
 /* The FF_USE_LFN switches the support for LFN (long file name).
 /
@@ -231,7 +231,7 @@
 /  buffer in the filesystem object (FATFS) is used for the file data transfer. */
 
 
-#define FF_FS_EXFAT		0
+#define FF_FS_EXFAT		1
 /* This option switches support for exFAT filesystem. (0:Disable or 1:Enable)
 /  To enable exFAT, also LFN needs to be enabled. (FF_USE_LFN >= 1)
 /  Note that enabling exFAT discards ANSI C (C89) compatibility. */

+ 8 - 0
fw/fw.h

@@ -4,6 +4,14 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#define likely(x)	__builtin_expect(!!(x), 1)
+#define unlikely(x)	__builtin_expect(!!(x), 0)
+
 extern void __attribute__((noreturn)) _die(void);
 
+extern const uint8_t _end[];
+extern void *_sbrk(size_t);
+
+extern int disk_init(void);
+
 #endif /* FW_H */

+ 18 - 1
fw/head.S

@@ -6,10 +6,25 @@
 	.org 0
 	.globl _reset
 _reset:
+	rdtime t0		// Record timer at reset
 	li sp,SRAM_SIZE
+	la t1,time_zero
+	sw t0,(t1)
 	j _start
+	.type _reset, @function
+	.size _reset, . - _reset
 
-	.org 0x10
+	.pushsection ".rodata","a"
+	// Not really readonly, but close enough
+	.balign 4
+	.globl time_zero
+time_zero:
+	.long 0
+	.type time_zero, @object
+	.size time_zero, . - time_zero
+	.popsection
+	
+	.org 0x20
 	.globl __irq
 __irq:
 	add sp,sp,-64
@@ -53,3 +68,5 @@ __irq:
 
 	add sp,sp,64
 	retirq
+	.type __irq, @function
+	.size __irq, . - __irq

+ 10 - 4
fw/hello.c

@@ -139,6 +139,12 @@ static void scrub_sdram(void)
 	*p = 0xdeadbeef;
 }
 
+static void init(void)
+{
+    con_set_baudrate(115000);
+    set_led(0);
+}
+
 void main(void)
 {
     static const char hello[] =
@@ -151,13 +157,10 @@ void main(void)
     uint8_t led = 0;
     uint32_t done;
 
-    con_set_baudrate(115200);
-    set_led(led = 0);
-
     while (!ROMCOPY_DONE)
 	pause();
 
-    done = rdtime();
+    done = rdtime() - time_zero;
 
     con_puts(hello);
 
@@ -165,6 +168,9 @@ void main(void)
     con_printf("SDRAM download took %u us\n", done/(CPU_HZ/1000000));
 
     test_download();
+
+    disk_init();
+    
     test_sdram();
 
     scrub_sdram();

+ 71 - 0
fw/io.h

@@ -1,6 +1,9 @@
 #ifndef IO_H
 #define IO_H
 
+#include <stdint.h>
+#include <stdarg.h>
+#include <stdbool.h>
 #include "iodev.h"
 
 static inline void pause(void)
@@ -13,6 +16,8 @@ static inline void set_led(uint8_t leds)
     LED = leds;
 }
 
+extern const uint32_t time_zero;
+
 static inline uint32_t rdtime(void)
 {
     uint32_t t;
@@ -40,4 +45,70 @@ static inline void udelay(uint32_t us)
 	pause();
 }
 
+static inline void sd_set_mode(uint8_t divisor, bool cs)
+{
+    SD_CTL_SPEED = (divisor - 1) | (cs << 7);
+}
+
+/* Read/write SD card and start transaction */
+enum sd_data_flags {
+    SD_B0       = 0x00,		/* Byte offset 0 */
+    SD_B1       = 0x01,		/* Byte offset 1 */
+    SD_B2       = 0x02,		/* Byte offset 2 */
+    SD_B3       = 0x03,		/* Byte offset 3 */
+    SD_GO8      = 0x04,		/* Start 8-bit transaction */
+    SD_GO16     = 0x08,		/* Start 16-bit transaction */
+    SD_GO32     = 0x0c,		/* Start 32-bit transaction */
+    SD_DATA	= 0x10,		/* Data register access (assumed) */
+    SD_BE       = 0x20,		/* Bigendian data */
+    SD_CLEARCRC = 0x40		/* Clear CRC registers */
+};
+
+static inline void sd_writeb(uint8_t d, enum sd_data_flags flags)
+{
+    flags ^= (flags & SD_BE) ? 3 : 0;
+    *(volatile uint8_t *)IODEVA(SD_DEV,0,flags | SD_DATA) = d;
+}
+static inline void sd_writeh(uint16_t d, enum sd_data_flags flags)
+{
+    flags ^= (flags & SD_BE) ? 2 : 0;
+    *(volatile uint16_t *)IODEVA(SD_DEV,0,flags | SD_DATA) = d;
+}
+static inline void sd_writel(uint32_t d, enum sd_data_flags flags)
+{
+    *(volatile uint32_t *)IODEVA(SD_DEV,0,flags | SD_DATA) = d;
+}
+static inline uint8_t sd_readb(enum sd_data_flags flags)
+{
+    flags ^= (flags & SD_BE) ? 0 : 3;
+    return *(const volatile uint8_t *)IODEVA(SD_DEV,0,flags | SD_DATA);
+}
+static inline uint16_t sd_readh(enum sd_data_flags flags)
+{
+    flags ^= (flags & SD_BE) ? 0 : 2;
+    return *(const volatile uint16_t *)IODEVA(SD_DEV,0,flags | SD_DATA);
+}
+static inline uint32_t sd_readl(enum sd_data_flags flags)
+{
+    return *(const volatile uint32_t *)IODEVA(SD_DEV,0,flags | SD_DATA);
+}
+
+static inline uint8_t sd_crc7_rd(void)
+{
+    return SD_CRC7_RD;
+}
+static inline uint8_t sd_crc7_wr(void)
+{
+    return SD_CRC7_WR;
+}
+static inline uint16_t sd_crc16_rd(void)
+{
+    return SD_CRC16_RD;
+}
+static inline uint8_t sd_crc16_wr(void)
+{
+    return SD_CRC16_WR;
+}
+
+
 #endif /* IO_H */

+ 58 - 21
fw/iodev.h

@@ -1,8 +1,8 @@
 #ifndef IODEV_H
 #define IODEV_H
 
-/* Address for I/O device d, subregister r */
-#define IODEVA(d,r) (0xfffffc00+((d) << 6)+((r) << 2))
+/* Address for I/O device d, subregister r, offset o */
+#define IODEVA(d,r,o)   (0xfffff800+((d) << 7)+((r) << 2)+(o))
 
 #ifdef __ASSEMBLY__
 
@@ -11,42 +11,79 @@
  * negative offsets from the zero register, so no explicit base
  * pointer register is necesary.
  */
-#define IODEVV(d,r) IODEVA(d,r)(zero)
-#define IODEVB(d,r) IODEVV(d,r)
-#define IODEVH(d,r) IODEVV(d,r)
-#define IODEVL(d,r) IODEVV(d,r)
+#define IODEVV(d,r) IODEVA(d,r,0)(zero)
+#define IODEVB(d,r) IODEVV(d,r,0)
+#define IODEVH(d,r) IODEVV(d,r,0)
+#define IODEVL(d,r) IODEVV(d,r,0)
 
 #else
 
 #include <stdint.h>
 
 /* Writable registers */
-#define IODEVV(d,r) (*(volatile void     *)IODEVA(d,r))
-#define IODEVB(d,r) (*(volatile uint8_t  *)IODEVA(d,r))
-#define IODEVH(d,r) (*(volatile uint16_t *)IODEVA(d,r))
-#define IODEVL(d,r) (*(volatile uint32_t *)IODEVA(d,r))
+#define IODEVV(d,r)   (*(volatile void     *)IODEVA(d,r,0))
+#define IODEVB(d,r)   (*(volatile uint8_t  *)IODEVA(d,r,0))
+#define IODEVB0(d,r)  (*(volatile uint8_t  *)IODEVA(d,r,0))
+#define IODEVB1(d,r)  (*(volatile uint8_t  *)IODEVA(d,r,1))
+#define IODEVB2(d,r)  (*(volatile uint8_t  *)IODEVA(d,r,2))
+#define IODEVB3(d,r)  (*(volatile uint8_t  *)IODEVA(d,r,3))
+#define IODEVH(d,r)   (*(volatile uint16_t *)IODEVA(d,r,0))
+#define IODEVH0(d,r)  (*(volatile uint16_t *)IODEVA(d,r,0))
+#define IODEVH1(d,r)  (*(volatile uint16_t *)IODEVA(d,r,2))
+#define IODEVL(d,r)   (*(volatile uint32_t *)IODEVA(d,r,0))
 
 /* Readonly registers */
-#define IODEVRV(d,r) (*(const volatile void     *)IODEVA(d,r))
-#define IODEVRB(d,r) (*(const volatile uint8_t  *)IODEVA(d,r))
-#define IODEVRH(d,r) (*(const volatile uint16_t *)IODEVA(d,r))
-#define IODEVRL(d,r) (*(const volatile uint32_t *)IODEVA(d,r))
+#define IODEVRV(d,r)  (*(const volatile void     *)IODEVA(d,r,0))
+#define IODEVRB(d,r)  (*(const volatile uint8_t  *)IODEVA(d,r,0))
+#define IODEVRB0(d,r) (*(const volatile uint8_t  *)IODEVA(d,r,0))
+#define IODEVRB1(d,r) (*(const volatile uint8_t  *)IODEVA(d,r,1))
+#define IODEVRB2(d,r) (*(const volatile uint8_t  *)IODEVA(d,r,2))
+#define IODEVRB3(d,r) (*(const volatile uint8_t  *)IODEVA(d,r,3))
+#define IODEVRH(d,r)  (*(const volatile uint16_t *)IODEVA(d,r,0))
+#define IODEVRH0(d,r) (*(const volatile uint16_t *)IODEVA(d,r,0))
+#define IODEVRH1(d,r) (*(const volatile uint16_t *)IODEVA(d,r,2))
+#define IODEVRL(d,r)  (*(const volatile uint32_t *)IODEVA(d,r,0))
 
 #endif
 
 #define CPU_HZ		84000000
 
-#define LED		IODEVB(0,0)
+#define LED_DEV		0
+#define LED		IODEVB(LED_DEV,0)
 
-#define RESET_CMD	IODEVL(1,0)
+#define RESET_DEV	1
+#define RESET_CMD	IODEVL(RESET_DEV,0)
 
-#define ROMCOPY_DONE	IODEVRL(2,0)
+#define ROMCOPY_DEV	2
+#define ROMCOPY_DONE	IODEVRL(ROMCOPY_DEV,0)
 
-#define CONSOLE		IODEVB(3,0)
-#define CON_BAUDDIV	IODEVL(3,1)
+#define CON_DEV		3
+#define CONSOLE		IODEVB(CON_DEV,0)
+#define CON_BAUDDIV	IODEVL(CON_DEV,1)
 #define CON_BAUD_BASE	(CPU_HZ >> 4)
 #define CON_BAUD_BITS	24
-#define CON_STATUS	IODEVRL(3,2)
-#define CON_IRQEN	IODEVL(3,3)
+#define CON_STATUS	IODEVRL(CON_DEV,2)
+#define CON_IRQEN	IODEVL(CON_DEV,3)
+
+#define SD_DEV		4
+#define SD_CTL		IODEVL(SD_DEV,0)
+#define SD_CTL_SPEED	IODEVB0(SD_DEV,0)
+#define SD_CTL_CLRCRC	IODEVB1(SD_DEV,0)
+#define SD_CRC7_RD	IODEVRB0(SD_DEV,2)
+#define SD_CRC16_RD	IODEVRH1(SD_DEV,2)
+#define SD_CRC7_WR	IODEVRB0(SD_DEV,3)
+#define SD_CRC16_WR	IODEVRH1(SD_DEV,3)
+
+/* Speed values, not including -1 adjustment */
+#define SD_SLOW		128	/* 328 kHz */
+#define SD_20MHZ	3	/* Really 14 MHz */
+#define SD_25MHZ	2	/* Really 21 MHz */
+#define SD_50MHZ	1	/* Really 42 MHz */
+
+#define SYSCLOCK_DEV		5
+#define SYSCLOCK_DATETIME	IODEVL(SYSCLOCK_DEV,0)
+#define SYSCLOCK_TICK		IODEVL(SYSCLOCK_DEV,1)
+#define SYSCLOCK_TICK_HOLD	IODEVH0(SYSCLOCK_DEV,1)
+#define SYSCLOCK_TICK_NOW	IODEVH1(SYSCLOCK_DEV,1)
 
 #endif /* IODEV_H */

+ 24 - 0
fw/sbrk.c

@@ -0,0 +1,24 @@
+/*
+ * sbrk allocator
+ */
+
+#include <stddef.h>
+#include <errno.h>
+#include "sys.h"
+#include "fw.h"
+
+void *_sbrk(size_t increment)
+{
+    static size_t cur_brk = (size_t)_end;
+    size_t old_brk = cur_brk;
+    size_t new_brk = old_brk + increment;
+
+    if (unlikely(new_brk > SRAM_SIZE - STACK_SIZE)) {
+	errno = ENOMEM;
+	return (void *)(-1);
+    }
+
+    cur_brk = new_brk;
+    return (void *)old_brk;
+}
+    

+ 761 - 0
fw/sdcard.c

@@ -0,0 +1,761 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2010-2021 H. Peter Anvin - All Rights Reserved
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ *   Boston MA 02110-1301, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * sdcard.c
+ *
+ * SD card block driver
+ *
+ * Note: the handling of read operations is tricky, because they pick up
+ * the results from the *previous* transaction.  Therefore there are some
+ * serious subtleties, especially with which byte position in the shift
+ * register the result ends up in and what the size flag should be set to.
+ */
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <string.h>
+
+#include "fw.h"
+#include "console.h"
+#include "io.h"
+#include "systime.h"
+#include "ff.h"
+#include "diskio.h"
+
+#define SECTOR_SHIFT	9
+#define SECTOR_SIZE	(1UL << SECTOR_SHIFT)
+
+/* Command codes, including the leading 01 sequence */
+enum sdcard_cmd {
+    CMD_GO_IDLE_STATE 		= 0x40,	/* a.k.a. reset */
+    CMD_SEND_OP_COND		= 0x41,
+    CMD_SWITCH_FUNC		= 0x46,
+    CMD_SEND_IF_COND		= 0x48,
+    CMD_SEND_CSD		= 0x49,
+    CMD_SEND_CID		= 0x4a,
+    CMD_STOP_TRANSMISSION	= 0x4c,
+    CMD_SEND_STATUS		= 0x4d,
+    CMD_SET_BLOCKLEN		= 0x50,
+    CMD_READ_SINGLE_BLOCK	= 0x51,
+    CMD_READ_MULTIPLE_BLOCK	= 0x52,
+    CMD_WRITE_BLOCK		= 0x58,
+    CMD_WRITE_MULTIPLE_BLOCK	= 0x59,
+    CMD_PROGRAM_CSD		= 0x5b,
+    CMD_SET_WRITE_PROT		= 0x5c,
+    CMD_CLR_WRITE_PROT		= 0x5d,
+    CMD_SEND_WRITE_PROT		= 0x5e,
+    CMD_ERASE_WR_BLK_START_ADDR	= 0x60,
+    CMD_ERASE_WR_BLK_END_ADDR	= 0x61,
+    CMD_ERASE			= 0x66,
+    CMD_LOCK_UNLOCK		= 0x6a,
+    CMD_APP_CMD			= 0x77, /* == ACMD prefix */
+    CMD_GEN_CMD			= 0x78,
+    CMD_READ_OCR		= 0x7a,
+    CMD_CRC_ON_OFF		= 0x7b
+};
+enum sdcard_acmd {
+    ACMD_SD_STATUS		= 0x4d,
+    ACMD_SEND_NUM_WR_BLOCKS	= 0x56,
+    ACMD_SET_WR_BLK_ERASE_COUNT	= 0x57,
+    ACMD_SD_SEND_OP_COND	= 0x69,
+    ACMD_SET_CLR_CARD_DETECT	= 0x6a,
+    ACMD_SEND_SCR		= 0x73
+};
+
+
+struct sdcard_csd {
+    uint32_t raw[4];
+};
+
+struct sdcard_cid {
+    uint32_t raw[4];
+};
+
+struct sdcard_info {
+    DSTATUS	 status;
+    int8_t   card_type;
+    unsigned long lbasize;
+    uint32_t if_cond;
+    uint32_t ocr;
+    struct sdcard_csd csd;
+    struct sdcard_cid cid;
+};
+
+struct sdcard_info sdc = {
+    .status = STA_NOINIT
+};
+
+/* < 0 if it should be left on, 0 for off, > 0 for off after timeout */
+static volatile int8_t sdcard_led;
+
+/*
+ * Called by the timer interrupt
+ */
+void sdcard_timer_tick(void)
+{
+#if 0
+    if (sdcard_led > 0) {
+	if (--sdcard_led == 0)
+	    *IO_SYS_LED &= ~0x01;
+    }
+#endif
+}
+
+/*
+ * Enable LED
+ */
+static void sdcard_led_on(void)
+{
+#if 0
+    sdcard_led = -1;
+    *IO_SYS_LED |= 0x01;
+#endif
+}
+
+/*
+ * Disable LED after timeout
+ */
+static void sdcard_led_off(void)
+{
+    sdcard_led = 4;		/* 4 ticks @ 64 Hz = 62.5 ms */
+}
+
+static int sdcard_send_cmd(uint8_t opcode, uint32_t argument)
+{
+    uint8_t crc7;
+    int i;
+
+    if (!opcode)
+	return 0;		/* No command */
+    
+    sd_writeb(opcode, SD_GO8|SD_CLEARCRC);
+    sd_writel(argument, SD_BE|SD_GO32);
+    crc7 = sd_crc7_wr();
+    sd_writeb(crc7, SD_GO8);
+
+    /* The spec says a reply within 8 cycles, cut it some slack */
+    for (i = 16; i; i--) {
+	int8_t status = sd_readb(0);
+	if (status >= 0) /* Bit 7 = 0 for a valid reply */
+	    return status;
+    }
+
+    return -1;		/* Error */
+}
+
+static int sdcard_send_acmd(uint8_t opcode, uint32_t argument)
+{
+    int rv;
+
+    /* CMD55 = application command follows */
+    rv = sdcard_send_cmd(CMD_APP_CMD, 0);
+    if (rv & 0x04)		/* Unknown command (very old card)? */
+	return rv;
+    return sdcard_send_cmd(opcode, argument);
+}
+
+/*
+ * Read a data block of length len, with a timeout of (timeout)
+ * byte-times.  Note that the minimum length is 4 by spec;
+ * this function may fail if this is not the case.
+ *
+ * The input buffer is allowed to be unaligned.
+ */
+union xptr {
+	uint32_t *l;
+	uint16_t *w;
+	uint8_t  *b;
+	size_t    a;
+};
+union xcptr {
+	const uint32_t *l;
+	const uint16_t *w;
+	const uint8_t  *b;
+	size_t    a;
+};
+
+static int sdcard_read_block(void *buf, int len, int timeout,
+			     uint8_t xcmd, uint32_t xarg)
+{
+    uint8_t tok;
+    uint16_t zcrc;
+    union xptr p;
+    int i;
+
+    p.b = buf;
+    
+    for (;;) {
+	tok = sd_readb(SD_GO8|SD_CLEARCRC);
+	if (tok == 0xfe)
+	    break;
+	if (tok < 0xfe) {
+	    con_printf("sdcard_read_block: bad token: %02x\n", tok);
+	    return -1; /* Bad token */
+	}
+	if (!--timeout) {
+	    con_printf("sdcard_read_block: reply timeout\n");
+	    return -1; /* Timeout */
+	}
+    }
+
+    /*
+     * At this point the first byte after the token is latched into
+     * the input shift register. After dealing with alignment,
+     * use dummy reads to shift in the rest of the first longword.
+     */
+    
+    /* Shift in bytes if needed for alignment */
+    if (p.a & 1) {
+	*p.b++ = sd_readb(SD_GO8);
+	len--;
+    }
+    sd_readb(SD_GO8);		/* Now total of 2 bytes latched */
+
+    if (p.a & 2) {
+	*p.w++ = sd_readh(SD_GO16);
+	len -= 2;
+    }
+    sd_readh(SD_GO16);		/* Now total of 4 bytes latched */
+
+    /*
+     * Are we supposed to send a command in parallel?
+     * This is unsafe for small blocks, but we only need to do this
+     * for full sectors (used to send STOP_TRANSMISSION).
+     */
+    if (xcmd)
+	len -= 6;	/* Handle the last 6 bytes specially */
+
+    while (len >= 8) {
+	*p.l++ = sd_readl(SD_GO32);
+	len -= 4;
+    }
+    if (len & 4)
+	*p.l++ = sd_readl(SD_GO16); /* Consume latched lword + shift in CRC */
+    if (len & 2)
+	*p.w++ = sd_readh(SD_GO16);
+    if (len & 1)
+	*p.b++ = sd_readb(SD_GO8 | 1);
+
+    /*
+     * If we're sending a command in parallel, then we have to
+     * read in the last 6 bytes in parallel with transmitting the
+     * command out.  Because pb may be misaligned at this point,
+     * do the latch reads/writes to memory as byte I/O.
+     * We still have 2 bytes of data latched, and should end
+     * with the same (for the CRC).
+     */
+    if (xcmd) {
+	uint8_t crc7;
+
+	*p.b++ = sd_readb(1);
+	*p.b++ = sd_readb(0);
+	sd_writeb(xcmd, SD_GO8|SD_CLEARCRC);
+	*p.b++ = sd_readb(0);
+	sd_writel(xarg, SD_GO32|SD_BE);
+	*p.b++ = sd_readb(3);
+	*p.b++ = sd_readb(2);
+	*p.b++ = sd_readb(1);
+	crc7 = sd_crc7_wr();
+	sd_writeb(crc7, SD_GO8);
+    }
+
+    /*
+     * Now the CRC is latched in the shift register, and the CRC
+     * in the CRC generator should be zero.  Shift in the first
+     * byte after the CRC for the next round.
+     */
+
+    zcrc = sd_crc16_rd();
+    sd_readb(SD_GO8);
+
+    if (zcrc != 0x0000) {
+	con_printf("sdcard_read_block: CRC error (zcrc = %04x)\n", zcrc);
+	return -1;
+    }
+
+    return 0;
+}
+
+/*
+ * Read a number of sectors; returns the number of sectors read.
+ * The input buffer may be unaligned.
+ */
+int sdcard_read_sectors(void *buf, uint32_t lba, int count)
+{
+    int rv;
+    int okcount = 0;
+    static const uint16_t stop_transmission[3] =
+	{ (0x40|CMD_STOP_TRANSMISSION) << 8, 0x0000, 0x0061 };
+    uint8_t resp;
+    uint8_t *p = buf;
+
+    if (!count)
+	return 0;
+
+    sdcard_led_on();
+
+    con_printf("sdcard: reading %d sectors at %u to %p\n", count, lba, buf);
+
+    if (sdc.card_type == 1)
+	lba <<= SECTOR_SHIFT;	/* Convert to a byte address */
+
+    rv = sdcard_send_cmd(CMD_READ_MULTIPLE_BLOCK, lba);
+    if (rv) {
+	con_printf("sdcard: read_multiple error %02x\n", rv);
+	goto out;
+    }
+
+    while (count--) {
+	rv = sdcard_read_block(p, SECTOR_SIZE, 200000,
+			       count ? 0 : CMD_STOP_TRANSMISSION, 0);
+	if (rv)
+	    goto out;
+
+	okcount++;
+	p += SECTOR_SIZE;
+    }
+
+    /* The first byte after the stop command is undefined */
+    sd_readb(SD_GO8);
+
+    /* Wait for the response to the STOP TRANSMISSION command */
+    do {
+	resp = sd_readb(SD_GO8);
+    } while ((int8_t)resp < 0);
+
+    if (resp) {
+	con_printf("sdcard: read_sectors: terminate command error %02x\n",
+	       resp);
+    }
+
+out:
+    sdcard_led_off();
+    return okcount;
+}
+
+DRESULT disk_read(BYTE drive, BYTE *buffer,
+		  LBA_t sectornumber, UINT sectorcount)
+{
+    int rv;
+
+    (void)drive;
+
+    rv = sdcard_read_sectors(buffer, sectornumber, sectorcount);
+    return (rv == sectorcount) ? RES_OK : RES_ERROR;
+}
+
+/*
+ * Read CSD/CID
+ */
+static int sdcard_read_reg(uint8_t opcode, void *buf)
+{
+    int rv;
+    uint32_t *bp = buf;
+    unsigned int i;
+
+    rv = sdcard_send_cmd(opcode, 0);
+    if (rv)
+	return rv;
+
+    rv = sdcard_read_block(buf, 16, 2000, 0, 0);
+    if (rv)
+	return rv;
+
+    for (i = 0; i < 4; i++)
+	bp[i] = __builtin_bswap32(bp[i]);
+}
+
+/*
+ * Write a number of sectors; returns the number of sectors written.
+ * The buffer may be unaligned.
+ */
+int sdcard_write_sectors(const void *buf, uint32_t lba, int count)
+{
+    int rv;
+    int okcount = 0;
+    uint16_t crc;
+    uint8_t resp;
+    union xcptr p;
+
+    if (!count)
+	return 0;
+
+    p.b = buf;
+
+    sdcard_led_on();
+
+    con_printf("sdcard: writing %d sectors at %u from %p\n", count, lba, buf);
+
+    if (sdc.card_type == 1)
+	lba <<= SECTOR_SHIFT;	/* Convert to a byte address */
+
+    rv = sdcard_send_cmd(CMD_WRITE_MULTIPLE_BLOCK, lba);
+    if (rv) {
+	con_printf("sdcard: write_multiple error %02x\n", rv);
+	goto out;
+    }
+
+    while (count--) {
+	unsigned int podd = p.a & 3;
+	size_t endloop = (p.a + SECTOR_SIZE) & ~3;
+
+	/* Start block token */
+	sd_writeb(0xfc, SD_GO8);
+
+	/* Clear the CRC generator; dummy cycle */
+	sd_writeb(~0, SD_CLEARCRC);
+
+	if (podd & 1)
+	    sd_writeb(*p.b++, SD_GO8);
+	if (podd & 2)
+	    sd_writeh(*p.w++, SD_GO16);
+
+	while (p.a < endloop)
+	    sd_writel(*p.l++, SD_GO32);
+
+	podd = -podd;
+	
+	if (podd & 2)
+	    sd_writeh(*p.w++, SD_GO16);
+	if (podd & 1)
+	    sd_writeb(*p.b++, SD_GO8);
+
+	sd_writeh(sd_crc16_wr(), SD_GO16);
+
+	/* Wait for data response token */
+	do {
+	    resp = sd_readb(SD_GO8);
+	} while ((resp & 0x11) != 0x01);
+
+	resp &= ~0xe0;
+	if (resp != 0x05) {
+	    /*
+	     * Things are confusing here... the spec says
+	     * that on error we are supposed to issue a
+	     * STOP_TRANSMISSION command, which isn't the normal
+	     * thing to do for a write... figure this out later.
+	     */
+	    break;	/* Error */
+	}
+
+	/* Wait until the card is ready for the next block */
+	do {
+	    resp = sd_readb(SD_GO8);
+	} while (resp == 0x00);
+
+	okcount++;
+    }
+
+    /* Send stop transmission token */
+    sd_writeb(0xfd, SD_GO8);
+
+    /* Wait for the card to go busy, then unbusy */
+    do {
+	resp = sd_readb(SD_GO8);
+    } while (resp != 0x00);
+    do {
+	resp = sd_readb(SD_GO8);
+    } while (resp == 0x00);
+
+out:
+    sdcard_led_off();
+    return okcount;
+}
+
+DRESULT disk_write(BYTE drive, const BYTE *buffer, LBA_t sectornumber,
+		   UINT sectorcount)
+{
+    int rv;
+
+    if (drive != 0)
+	return STA_NOINIT;
+
+    rv = sdcard_write_sectors(buffer, sectornumber, sectorcount);
+    return (rv == sectorcount) ? RES_OK : RES_ERROR;
+}
+
+DRESULT disk_ioctl(BYTE drive, BYTE command, void *buffer)
+{
+    if (drive != 0)
+	return STA_NOINIT;
+
+    switch (command) {
+    case CTRL_SYNC:
+	return RES_OK;
+    case GET_SECTOR_SIZE:
+	*(WORD *)buffer = 512;
+	return RES_OK;
+    case GET_SECTOR_COUNT:
+	*(DWORD *)buffer = sdc.lbasize;
+	return RES_OK;
+    case GET_BLOCK_SIZE:
+	*(DWORD *)buffer = 1; /* XXX */
+	return RES_OK;
+    default:
+	return RES_PARERR;
+    }
+}
+
+DWORD get_fattime(void)
+{
+    return SYSCLOCK_DATETIME;	/* Already in FAT format */
+}
+
+static unsigned long sdcard_compute_size(struct sdcard_info *sdi)
+{
+    unsigned int c_size;
+    unsigned int c_size_mult;
+    unsigned int read_bl_len;
+    unsigned long lbasize;
+
+    sdi->card_type = (sdi->csd.raw[0] >> 30)+1;
+    switch (sdi->card_type) {
+    case 1:			/* Classic SD/MMC card */
+	c_size = ((sdi->csd.raw[2] & 0x3ff) << 2) +
+	    (sdi->csd.raw[3] >> 30);
+	c_size_mult = (sdi->csd.raw[2] >> 15) & 7;
+	read_bl_len = (sdi->csd.raw[1] >> 16) & 0xf;
+
+	lbasize = (c_size + 1) << (c_size_mult + read_bl_len + 2 - 9);
+	break;
+    case 2:			/* SDHC/SDXC/eMMC card */
+	c_size = ((sdi->csd.raw[1] & 0x3f) << 16) +
+	    (sdi->csd.raw[2] >> 16);
+
+	lbasize = c_size << 10;
+	break;
+    default:
+	sdi->card_type = 0;
+	return 0;
+    }
+
+    return sdi->lbasize = lbasize;
+}
+
+static const char *sdcard_type_name(uint8_t type)
+{
+    static const char * const names[] = {
+	"unknown",
+	"SD/MMC",
+	"SDHC/SDXC/eMMC"
+    };
+
+    if (type >= sizeof names/sizeof names[0])
+	type = 0;
+
+    return names[type];
+}
+
+static void sdcard_try_high_speed(void)
+{
+    int rv;
+    uint8_t swdata[64];		/* Response from CMD6 */
+
+    if (!(sdc.csd.raw[1] & (1 << 30)))
+	return;			/* Cmd group 10 = CMD6 not supported */
+
+    /* Try to switch to high speed mode */
+    rv = sdcard_send_cmd(CMD_SWITCH_FUNC, 0x80fffff1);
+    if (rv)
+	return;
+
+    rv = sdcard_read_block(swdata, sizeof swdata, 2000, 0, 0);
+    if (rv)
+	return;
+
+    if ((swdata[47] & 0x0f) != 1)
+	return;			/* Failed to switch to high speed mode */
+
+    /* Success, now switch mode! */
+    sd_readl(SD_GO32);		/* Issue at least 8 clocks; go for 32 */
+    sd_set_mode(SD_50MHZ, true);
+
+    con_printf("sdcard: switched to high speed\n");
+}
+
+DSTATUS disk_initialize(BYTE drive)
+{
+    uint16_t  status;
+    uint32_t try_sdhc;
+    bool is_sd;
+    int i, rv;
+
+    if (drive != 0)
+	return STA_NOINIT;
+
+    memset(&sdc, 0, sizeof sdc);
+
+#if 0
+    status = /* Check card detect if present */
+
+    if (!(status & 0x04)) {
+	con_printf("No memory card installed\n");
+	return sdc.status = STA_NOINIT|STA_NODISK;
+    }
+#endif
+
+    sdcard_led_on();
+
+    /* Generate 256 clock cycles in slow mode, with CS# high */
+    sd_set_mode(SD_SLOW, false);
+    for (i = 0; i < 8; i++)
+	sd_writel(~0, SD_GO32);
+
+    /* Assert CS# and send reset command; if no response assume no disk */
+    sd_set_mode(SD_SLOW, true);
+    rv = sdcard_send_cmd(CMD_GO_IDLE_STATE, 0);
+    if (rv != 0x01) {
+	con_printf("sdcard: CMD0 error %02x\n", rv);
+	sdcard_led_off();
+	return sdc.status = STA_NOINIT | STA_NODISK;
+    }
+
+    /* Switch to 20 MHz */
+    sd_set_mode(SD_20MHZ, true);
+
+    /* Enable command CRC checking (ignore result) */
+    sdcard_send_cmd(CMD_CRC_ON_OFF, 0x0001);
+
+    /* Probe for extended features */
+    /*
+     * Bit  7:0 = check pattern
+     * Bit 11:8 = supply voltage (3.3 V)
+     */
+    rv = sdcard_send_cmd(CMD_SEND_IF_COND, 0x01aa);
+    if ((rv & 0x04) == 0) {
+	/* CMD8 supported */
+	if (rv & ~0x03) {
+	    con_printf("sdcard; CMD8 error %02x\n", rv);
+	    sdcard_led_off();
+	    return sdc.status = STA_NOINIT;
+	}
+
+	/* Shift in additional data bytes */
+	sd_readb(SD_GO8);
+	sd_readh(SD_GO16);
+	sdc.if_cond = sd_readl(SD_GO16|SD_BE);
+
+	con_printf("sdcard: CMD8 returned 0x%08x\n", sdc.if_cond);
+
+	if ((sdc.if_cond & 0x1ff) != 0x1aa) {
+	    con_printf("sdcard: CMD8 reports unusable card (0x%x)\n",
+		   sdc.if_cond);
+	    sdcard_led_off();
+	    return sdc.status = STA_NOINIT;
+	}
+	try_sdhc = 1 << 30;
+    } else {
+	try_sdhc = 0;
+    }
+
+    /* Initialize card */
+    do {
+	rv = sdcard_send_acmd(ACMD_SD_SEND_OP_COND, try_sdhc);
+	if (rv & 0x04)
+	    break;
+
+	if (rv & ~0x01) {
+	    con_printf("sdcard: ACMD41 error %02x\n", rv);
+	    sdcard_led_off();
+	    return sdc.status = STA_NOINIT;
+	}
+    } while (rv);
+
+    if (!rv) {
+	/* ACMD41 successful; this is an SD card: can switch to 25 MHz */
+	is_sd = true;
+	
+	sd_set_mode(SD_25MHZ, true);
+	rv = sdcard_send_cmd(CMD_READ_OCR, try_sdhc);
+	if (rv) {
+	    con_printf("sdcard: CMD58 error %02x\n", rv);
+	    sdcard_led_off();
+	    return sdc.status = STA_NOINIT;
+	}
+	/* Shift in additional data bytes */
+	sd_readb(SD_GO8);
+	sd_readh(SD_GO16);
+	sdc.ocr = sd_readl(SD_GO16|SD_BE);
+    } else {
+	/* ACMD41 unsupported, try CMD1 */
+	is_sd = false;
+		
+	do {
+	    rv = sdcard_send_cmd(CMD_SEND_OP_COND, 0);
+	    if (rv & ~0x01) {
+		con_printf("sdcard: CMD1 error %02x\n", rv);
+		sdcard_led_off();
+		return sdc.status = STA_NOINIT;
+	    }
+	} while (rv);
+    }
+
+    /*
+     * Set block length -- some cards power up to a larger block size
+     * than 512 bytes even though that violates the spec.
+     */
+    rv = sdcard_send_cmd(CMD_SET_BLOCKLEN, 512);
+    if (rv) {
+	con_printf("sdcard: CMD16 error %02x\n", rv);
+	sdcard_led_off();
+	return sdc.status = STA_NOINIT;
+    }
+
+    /*
+     * Read CSD and CID
+     */
+    if (sdcard_read_reg(CMD_SEND_CSD, &sdc.csd))
+	memset(&sdc.csd, 0, sizeof sdc.csd);
+
+    con_printf("sdcard: CSD: %08x %08x %08x %08x\n",
+	   sdc.csd.raw[0], sdc.csd.raw[1], sdc.csd.raw[2], sdc.csd.raw[3]);
+
+    if (sdcard_read_reg(CMD_SEND_CID, &sdc.cid))
+	memset(&sdc.cid, 0, sizeof sdc.cid);
+
+    con_printf("sdcard: CID: %08x %08x %08x %08x\n",
+	   sdc.cid.raw[0], sdc.cid.raw[1], sdc.cid.raw[2], sdc.cid.raw[3]);
+
+    sdcard_compute_size(&sdc);
+
+    con_printf("sdcard: %s card found, capacity %u sectors\n",
+	   sdcard_type_name(sdc.card_type), sdc.lbasize);
+
+
+    /*
+     * Try to switch to 50 MHz (optional)
+     */
+    if (is_sd)
+	sdcard_try_high_speed();
+    
+    sdc.status = 0;
+
+    sdcard_led_off();
+    return sdc.status;
+}
+
+DSTATUS disk_status(BYTE drive)
+{
+    if (drive != 0)
+	return STA_NOINIT;
+
+    return sdc.status;
+}
+
+static FATFS sd_fs;
+
+int disk_init(void)
+{
+    return f_mount(&sd_fs, "", 1);
+}
+

+ 1 - 0
fw/sys.h

@@ -2,5 +2,6 @@
 #define SYS_H
 
 #define SRAM_SIZE	32768	/* Size of builtin SRAM */
+#define STACK_SIZE	2048	/* Minimum stack size */
 
 #endif /* SYS_H */

+ 55 - 0
fw/systime.h

@@ -0,0 +1,55 @@
+/*
+ * Get time according to system (RTC or whatever we have...)
+ * This is similar to localtime() in the standard C library, except
+ * only the current time is supported and some of the derived fields
+ * are not produced.
+ */
+
+#ifndef SYSTIME_H
+#define SYSTIME_H
+
+#include <stdint.h>
+
+struct tms_tick_reg {
+    union {
+	uint16_t ticks;
+	struct {
+	    unsigned int tm_1sec : 1;
+	    unsigned int tm_tick : 15;
+	};
+    };
+} __attribute__((aligned(2)));
+
+struct tms {
+    union {
+	uint32_t words[2];
+	struct {
+	    unsigned int tm_2sec     : 5;
+	    unsigned int tm_min      : 6;
+	    unsigned int tm_hour     : 5;
+	    unsigned int tm_mday     : 5;
+	    unsigned int tm_mon      : 4;
+	    unsigned int tm_year     : 7;
+	    struct tms_tick_reg hold;
+	    struct tms_tick_reg now;
+	};
+    };
+} __attribute__((aligned(4)));
+
+static inline struct tms get_systime(void)
+{
+    struct tms tms;
+
+    tms.words[0] = SYSCLOCK_DATETIME;
+    tms.words[1] = SYSCLOCK_TICK;
+
+    return tms;
+}
+
+static inline void set_systime(struct tms tms)
+{
+    SYSCLOCK_TICK_HOLD = tms.hold.ticks;
+    SYSCLOCK_DATETIME  = tms.words[0];
+}
+
+#endif /* SYSTIME_H */