Compare commits

..

5 Commits

135 changed files with 21036 additions and 16749 deletions

View File

@ -1,4 +1,4 @@
OBJS = header.ips reset.o65 main.o65 font.o65 palette.o65 data.o65 const.o65 logo.o65 logospr.o65 text.o65 dma.o65 filesel.o65 pad.o65 time.o65 mainmenu.o65 sysinfo.o65 spc700.o65 spcplay.o65 # gfx.o65 # vars.o65
OBJS = header.ips reset.o65 main.o65 font.o65 palette.o65 data.o65 const.o65 logo.o65 logospr.o65 text.o65 dma.o65 menu.o65 pad.o65 time.o65 mainmenu.o65 sysinfo.o65 spc700.o65 spcplay.o65 # gfx.o65 # vars.o65
all: clean menu.bin map

View File

@ -2,7 +2,8 @@ version .byt " v0.1",0
zero .word 0
bg2tile .byt $20
space64 .byt $20, $20, $20, $20, $20, $20, $20, $20
space64
.byt $20, $20, $20, $20, $20, $20, $20, $20
.byt $20, $20, $20, $20, $20, $20, $20, $20
.byt $20, $20, $20, $20, $20, $20, $20, $20
.byt $20, $20, $20, $20, $20, $20, $20, $20

View File

@ -1,41 +1,43 @@
.data
;don't anger the stack!
;----------parameters for text output----------
print_x .byt 0 ;x coordinate
.byt 0
print_y .byt 0 ;y coordinate
.byt 0
print_src .word 0 ;source data address
print_bank .byt 0 ;source data bank
print_pal .word 0 ;palette number for text output
print_temp .word 0 ;work variable
print_count .byt 0 ;how many characters may be printed?
print_count_tmp .byt 0 ;work variable
print_done .word 0 ;how many characters were printed?
print_x .byt 0 ; x coordinate
.byt 0
print_y .byt 0 ; y coordinate
.byt 0
print_src .word 0 ; source data address
print_bank .byt 0 ; source data bank
print_pal .word 0 ; palette number for text output
print_temp .word 0 ; work variable
print_count .byt 0 ; how many characters may be printed?
print_count_tmp .byt 0 ; work variable
print_done .word 0 ; how many characters were printed?
;----------parameters for dma----------
dma_a_bank .byt 0
dma_a_addr .word 0
dma_b_reg .byt 0
dma_len .word 0
dma_mode .byt 0
dma_a_bank .byt 0
dma_a_addr .word 0
dma_b_reg .byt 0
dma_len .word 0
dma_mode .byt 0
;----------state information----------
isr_done .byt 0 ; isr done flag
isr_done .byt 0 ; isr done flag
;----------menu layout/system constants (224/448)
textdmasize .word 0 ; number of bytes to copy each frame
textdmasize .word 0 ; number of bytes to copy each frame
infloop .byt 0,0 ; to be filled w/ 80 FE
infloop .byt 0,0 ; to be filled w/ 80 FE
printloop_wram .byt 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
.byt 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
.byt 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
.byt 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
.byt 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
.byt 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
.byt 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
printloop_wram
.byt 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
.byt 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
.byt 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
.byt 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
.byt 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
.byt 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
.byt 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
loprint_wram .byt 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
.byt 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
.byt 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
.byt 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
.byt 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
loprint_wram
.byt 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
.byt 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
.byt 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
.byt 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
.byt 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

View File

@ -1,4 +1,4 @@
palette
;fonts
.byt $42, $08, $ff, $7f, $00, $00, $9c, $73
.byt $42, $08, $ff, $43, $00, $00, $18, $63
.byt $42, $08, $ff, $43, $00, $00, $18, $63

View File

@ -11,24 +11,24 @@
; NMI - called on VBlank
NMI_ROUTINE:
sep #$20 : .as
rep #$10 : .xl
lda #$00
pha
plb
lda $4210
sep #$20 : .as
rep #$10 : .xl
lda #$00
pha
plb
lda $4210
ldx #BG1_TILE_BASE
stx $2116
DMA0(#$01, #36*64, #^BG1_TILE_BUF, #!BG1_TILE_BUF, #$18)
ldx #BG1_TILE_BASE
stx $2116
DMA0(#$01, #36*64, #^BG1_TILE_BUF, #!BG1_TILE_BUF, #$18)
lda #$01
sta isr_done
rtl
lda #$01
sta isr_done
rtl
; IRQ - called when triggered
IRQ_ROUTINE:
sep #$20 : .as
lda $4211 ;Acknowledge irq
rtl
sep #$20 : .as
lda $4211 ;Acknowledge irq
rtl

View File

@ -45,9 +45,9 @@ bar_x .byt 0 ; pixel x position of select bar
bar_y .byt 0 ; pixel y position of select bar
bar_w .byt 0 ; bar width
bar_wl .byt 0 ; bar width
filesel_state .byt 0 ; menu state (0=file select)
filesel_dirty .byt 0 ; menu dirty (e.g. after state change or when redraw is needed)
filesel_sel .word 0 ; selected item #
menu_state .byt 0 ; menu state (0=file select)
menu_dirty .byt 0 ; menu dirty (e.g. after state change or when redraw is needed)
menu_sel .word 0 ; selected item #
cursor_x .byt 0 ; current cursor position (x)
cursor_y .byt 0 ; current cursor position (y)
fd_addr .word 0 ; address of current "file descriptor"
@ -96,8 +96,6 @@ barstep .byt 0 ; step size for bar
;-misc
testvar .word 0,0,0,0
;menu system
menu_stack .word 0,0,0,0,0,0,0,0
;----------hdma tables in WRAM (must be stable when cartridge is cut off)
hdma_pal .byt 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
.byt 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

View File

@ -21,15 +21,15 @@ GAME_MAIN:
tcs
sep #$20 : .as
; jsr killdma ; The following initialization processes must not touch memory
jsr waitblank ; structures used by the file selector !
jsr killdma ; The following initialization processes must not touch memory
jsr waitblank ; structures used by the main menu !
jsr snes_init
cli
lda #$01
sta $420d ; fast cpu
jsr setup_gfx
jsr colortest
jsr video_init
jsr tests
jsr setup_hdma
lda #$0f
sta cur_bright
@ -43,15 +43,15 @@ set_bank:
coldboot: ; Regular, cold-start init
sep #$20 : .as
; jsr killdma
jsr killdma
jsr waitblank
jsr snes_init
lda #$01
sta $420d ; fast cpu
jsr setup_gfx
jsr colortest
jsr filesel_init
jsr video_init
jsr menu_init
jsr tests
jsr setup_hdma
jsr screen_on
@ -60,7 +60,7 @@ coldboot: ; Regular, cold-start init
beq +
jsl time_init
+
jsr fileselloop
jsr menuloop
cli
stz $4200
jmp @infloop ;infinite loop in WRAM
@ -138,30 +138,6 @@ killdma:
stz $4359
stz $435a
stz $435b
stz $4360
stz $4361
stz $4362
stz $4363
stz $4364
stz $4365
stz $4366
stz $4367
stz $4368
stz $4369
stz $436a
stz $436b
stz $4370
stz $4371
stz $4372
stz $4373
stz $4374
stz $4375
stz $4376
stz $4377
stz $4378
stz $4379
stz $437a
stz $437b
stz $420b
stz $420c
@ -214,7 +190,7 @@ setup_gfx:
;clear OAM tables
ldx #$0000
stx $2102
DMA0(#$08, #$220, #^zero, #!zero, #$04)
DMA0(#$08, #$544, #^zero, #!zero, #$04)
;copy logo tiles
ldx #$2000
@ -297,7 +273,7 @@ setup_gfx:
DMA0(#$00, #$6C, #^fadeloop, #!fadeloop, #$80);
rts
video_init:
tests:
sep #$20 : .as ;8-bit accumulator
rep #$10 : .xl ;16-bit index
lda #$03 ;mode 3, mode 5 via HDMA

View File

@ -80,12 +80,15 @@ mm_entloop
plb
phx
jsr hiprint
rep #$20 : .al
pla
clc
adc #$08
tax
sep #$20 : .as
plx
inx
inx
inx
inx
inx
inx
inx
inx
inc mm_tmp
lda mm_tmp
cmp @main_entries

View File

@ -1,7 +1,7 @@
#include "memmap.i65"
#include "dma.i65"
filesel_init:
menu_init:
sep #$20 : .as
rep #$10 : .xl
lda #^ROOT_DIR
@ -10,7 +10,7 @@ filesel_init:
stx dirptr_addr
sta dirstart_bank
stx dirstart_addr
stz filesel_state
stz menu_state
stz dirend_onscreen
lda #$02
sta cursor_x
@ -22,11 +22,11 @@ filesel_init:
sta bar_wl
ldx #$0000
stx dirptr_idx
stx filesel_sel
stx menu_sel
stx direntry_xscroll
stx direntry_xscroll_state
lda #$01
sta filesel_dirty
sta menu_dirty
rep #$20 : .al
lda #!dirlog
sta dirlog_idx
@ -35,39 +35,39 @@ filesel_init:
sta dirlog_idx+2
rts
fileselloop:
fileselloop_s1
menuloop:
menuloop_s1
sep #$20 : .as
rep #$10 : .xl
lda isr_done
lsr
bcc fileselloop_s1
bcc menuloop_s1
stz isr_done
jsr printtime
jsr filesel_updates ;update stuff, check keys etc
lda filesel_dirty ;is there ANY reason to redraw the menu?
jsr menu_updates ;update stuff, check keys etc
lda menu_dirty ;is there ANY reason to redraw the menu?
cmp #$01
beq fileselloop_redraw ;then do
beq menuloop_redraw ;then do
jsr scroll_direntry
bra fileselloop_s1
fileselloop_redraw
stz filesel_dirty
jsr filesel_statusbar
jsr filesel_redraw
jsr filesel_cleanup ;update phase 2
bra fileselloop_s1
bra menuloop_s1
menuloop_redraw
stz menu_dirty
jsr menu_statusbar
jsr menu_redraw
jsr menu_cleanup ;update phase 2
bra menuloop_s1
rts
filesel_cleanup:
menu_cleanup:
sep #$20 : .as
rep #$10 : .xl
lda dirend_onscreen ;end of file list on screen?
beq filesel_cleanup_out ;
beq menu_cleanup_out ;
lda dirend_idx
lsr
lsr
pha
filesel_cleanup_loop ;pad rest of screen with empty lines
menu_cleanup_loop ;pad rest of screen with empty lines
cmp listdisp ;end of screen reached?
beq + ;then leave
pha
@ -86,24 +86,24 @@ filesel_cleanup_loop ;pad rest of screen with empty lines
jsr hiprint
pla
inc
bra filesel_cleanup_loop
bra menu_cleanup_loop
+
pla
cmp filesel_sel
beq filesel_cleanup_out
bpl filesel_cleanup_out
sta filesel_sel
filesel_cleanup_out
cmp menu_sel
beq menu_cleanup_out
bpl menu_cleanup_out
sta menu_sel
menu_cleanup_out
rts
filesel_updates:
menu_updates:
;update selection, scroll etc
lda filesel_sel
lda menu_sel
asl
asl
sta dirptr_idx
lda filesel_sel
lda menu_sel
clc
adc #$08
sta bar_yl
@ -140,47 +140,47 @@ filesel_updates:
lda #$40
and pad1trig
bne key_x
bra fileselupd_out
bra menuupd_out
key_down
jsr filesel_key_down
bra fileselupd_out
jsr menu_key_down
bra menuupd_out
key_up
jsr filesel_key_up
bra fileselupd_out
jsr menu_key_up
bra menuupd_out
key_right
jsr filesel_key_right
bra fileselupd_out
jsr menu_key_right
bra menuupd_out
key_left
jsr filesel_key_left
bra fileselupd_out
jsr menu_key_left
bra menuupd_out
key_b
jsr filesel_key_b
bra fileselupd_out
jsr menu_key_b
bra menuupd_out
key_a
jsr filesel_key_a
bra fileselupd_out
jsr menu_key_a
bra menuupd_out
key_x
jsr filesel_key_x
bra fileselupd_out
jsr menu_key_x
bra menuupd_out
key_select
jsr filesel_key_select
bra fileselupd_out
jsr menu_key_select
bra menuupd_out
key_start
jsr filesel_key_start
bra fileselupd_out
jsr menu_key_start
bra menuupd_out
fileselupd_out
menuupd_out
lda #$09
sta cursor_y
rts
filesel_redraw:
lda filesel_state
menu_redraw:
lda menu_state
beq redraw_filelist
; cmp 1
; beq redraw_main
filesel_redraw_out
menu_redraw_out
rts
redraw_filelist
@ -236,7 +236,7 @@ redraw_filelist_last ;check if next offscreen item is end of dir
redraw_filelist_out
ldx #$0000
stx dirptr_idx
brl filesel_redraw_out
brl menu_redraw_out
print_direntry:
lda cursor_y
@ -355,14 +355,14 @@ dirent_type_cont_2
rts
filesel_key_down:
menu_key_down:
jsr scroll_direntry_clean
lda listdisp
dec
cmp filesel_sel
cmp menu_sel
bne down_noscroll
lda #$01
sta filesel_dirty
sta menu_dirty
lda dirend_onscreen
bne down_out
rep #$20 : .al
@ -380,21 +380,21 @@ down_noscroll
lda dirend_idx
lsr
lsr
cmp filesel_sel
beq fileselupd_lastcursor
bcc fileselupd_lastcursor
+ lda filesel_sel
cmp menu_sel
beq menuupd_lastcursor
bcc menuupd_lastcursor
+ lda menu_sel
inc
sta filesel_sel
sta menu_sel
down_out
rts
filesel_key_up:
menu_key_up:
jsr scroll_direntry_clean
lda filesel_sel
lda menu_sel
bne up_noscroll
lda #$01
sta filesel_dirty
sta menu_dirty
rep #$20 : .al
lda dirptr_addr
cmp dirstart_addr
@ -407,25 +407,25 @@ filesel_key_up:
bra up_out
up_noscroll
dec
sta filesel_sel
sta menu_sel
up_out
sep #$20 : .as
rts
fileselupd_lastcursor
menuupd_lastcursor
jsr scroll_direntry_clean
lda dirend_idx
lsr
lsr
sta filesel_sel
sta menu_sel
rts
; go back one page
filesel_key_left:
menu_key_left:
stz direntry_xscroll
stz direntry_xscroll_state
lda #$01 ; must redraw afterwards
sta filesel_dirty
sta menu_dirty
rep #$20 : .al
lda dirptr_addr ; get current direntry pointer
beq + ; special case: if 0, we are at the first entry in memory
@ -444,18 +444,18 @@ filesel_key_left:
sep #$20 : .as
rts
+ lda dirstart_addr ; reset pointer to start of directory
stz filesel_sel ; reset the selection cursor too
stz menu_sel ; reset the selection cursor too
bra -
; go forth one page
filesel_key_right:
menu_key_right:
stz direntry_xscroll
stz direntry_xscroll_state
sep #$20 : .as
lda dirend_onscreen
bne fileselupd_lastcursor
bne menuupd_lastcursor
lda #$01
sta filesel_dirty
sta menu_dirty
rep #$20 : .al
lda listdisp
asl
@ -466,18 +466,18 @@ filesel_key_right:
sep #$20 : .as
rts
filesel_key_a:
menu_key_a:
jsr select_item
rts
filesel_key_select:
menu_key_select:
rts
filesel_key_start:
menu_key_start:
jsr select_last_file
rts
filesel_key_b:
menu_key_b:
stz direntry_xscroll
stz direntry_xscroll_state
rep #$20 : .al
@ -485,7 +485,7 @@ filesel_key_b:
beq skip_key_b
sta dirptr_addr
lda #$0000
sta filesel_sel
sta menu_sel
bra select_item
skip_key_b
sep #$20 : .as
@ -493,7 +493,7 @@ skip_key_b
select_item:
rep #$20 : .al
lda filesel_sel
lda menu_sel
and #$00ff
asl
asl
@ -568,7 +568,7 @@ select_dir:
lda @dirptr_bank
sta [dirlog_idx], y
iny
lda @filesel_sel
lda @menu_sel
sta [dirlog_idx], y
lda @dirlog_idx
clc
@ -604,12 +604,12 @@ select_dir:
sta @dirptr_addr
sta @dirstart_addr
lda #$0000
sta @filesel_sel
sta @menu_sel
sta @direntry_xscroll
sta @direntry_xscroll_state
sep #$20 : .as
lda #$01
sta @filesel_dirty
sta @menu_dirty
plb
rts
@ -638,11 +638,11 @@ select_parent:
sta @dirptr_bank
iny
rep #$20 : .al
lda [dirlog_idx], y ; load filesel_sel
sta @filesel_sel
lda [dirlog_idx], y ; load menu_sel
sta @menu_sel
sep #$20 : .as
lda #$01
sta @filesel_dirty
sta @menu_dirty
rts
select_spc:
@ -666,7 +666,7 @@ wait_spc:
jsr restore_screen
rts
filesel_key_x:
menu_key_x:
jsr mainmenu
rts
@ -676,11 +676,11 @@ setup_224:
lda #18
sta listdisp
dec
cmp filesel_sel
cmp menu_sel
bmi setup_224_adjsel
bra +
setup_224_adjsel
sta filesel_sel
sta menu_sel
+
lda #18*64
sta textdmasize
@ -699,7 +699,7 @@ setup_224_adjsel
sta hdma_math_selection
stz vidmode
lda #$01
sta filesel_dirty
sta menu_dirty
lda #^space64
ldx #!space64
sta print_bank
@ -719,7 +719,7 @@ setup_224_adjsel
plp
rts
filesel_statusbar
menu_statusbar
pha
phx
php
@ -822,7 +822,7 @@ scroll_direntry_clean:
rts
scroll_direntry:
ldy filesel_sel
ldy menu_sel
lda direntry_xscroll_state
bne +
lda direntry_fits, y
@ -852,7 +852,7 @@ scroll_direntry_scrollfast
lda #$02
sta cursor_x
rep #$20 : .al
lda filesel_sel
lda menu_sel
asl
asl
tay
@ -869,7 +869,7 @@ scroll_direntry_scrollfast
lda [dirptr_addr], y
iny
sta @dirent_type
ldy filesel_sel
ldy menu_sel
sty direntry_fits_idx
phy
jsr print_direntry

View File

@ -55,7 +55,7 @@ TARGET = $(OBJDIR)/sd2snes
# List C source files here. (C dependencies are automatically generated.)
SRC = main.c ff.c ccsbcs.c clock.c uart.c power.c led.c timer.c printf.c spi.c fileops.c rtc.c fpga.c fpga_spi.c snes.c smc.c memory.c filetypes.c faulthandler.c sort.c crc32.c cic.c cli.c xmodem.c irq.c rle.c sdnative.c msu1.c crc16.c sysinfo.c cfg.c
SRC = main.c ff.c ccsbcs.c clock.c uart.c power.c led.c timer.c printf.c spi.c fileops.c rtc.c fpga.c fpga_spi.c snes.c smc.c memory.c filetypes.c faulthandler.c sort.c crc32.c cic.c cli.c xmodem.c irq.c rle.c sdnative.c msu1.c crc16.c sysinfo.c cfg.c tests.c
# usbcontrol.c usb_hid.c usbhw_lpc.c usbinit.c usbstdreq.c
@ -124,7 +124,8 @@ NM = $(ARCH)-nm
REMOVE = rm -f
COPY = cp
AWK = awk
RLE = ../utils/rle
BIN2H = utils/bin2h
#---------------- Compiler Options ----------------
# -g*: generate debugging information
@ -197,7 +198,7 @@ ALL_ASFLAGS = -I. -x assembler-with-cpp $(ASFLAGS) $(CDEFS)
# Default target.
all: build
build: elf bin hex
build: snesboot.h cfgware.h elf bin hex
$(E) " SIZE $(TARGET).elf"
$(Q)$(ELFSIZE)|grep -v debug
cp $(TARGET).bin $(OBJDIR)/firmware.img
@ -217,19 +218,37 @@ sym: $(TARGET).sym
program: build
utils/lpcchksum $(TARGET).bin
openocd -f openocd-usb.cfg -f lpc1754.cfg -f flash.cfg
openocd -f interface/olimex-arm-usb-ocd.cfg -f lpc1754.cfg -f flash.cfg
debug: build
openocd -f openocd-usb.cfg -f lpc1754.cfg
openocd -f interface/olimex-arm-usb-ocd.cfg -f lpc1754.cfg
reset:
openocd -f openocd-usb.cfg -f lpc1754.cfg -f reset.cfg
openocd -f interface/olimex-arm-usb-ocd.cfg -f lpc1754.cfg -f reset.cfg
# Display size of file.
HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex
ELFSIZE = $(SIZE) -A $(TARGET).elf
# Generate cfgware.h
cfgware.h: $(OBJDIR)/fpga_rle.bit
$(E) " BIN2H $@"
$(Q) $(BIN2H) $< $@ cfgware
$(OBJDIR)/fpga_rle.bit: ../verilog/sd2sneslite/main.bit
$(E) " RLE $@"
$(Q) $(RLE) $< $@
#generate snesboot.h
snesboot.h: $(OBJDIR)/snesboot.rle
$(E) " BIN2H $@"
$(Q) $(BIN2H) $< $@ bootrle
$(OBJDIR)/snesboot.rle: ../snes/boot/menu.bin
$(E) " RLE $@"
$(Q) $(RLE) $< $@
# Generate autoconf.h from config
.PRECIOUS : $(OBJDIR)/autoconf.h
@ -302,6 +321,7 @@ clean_list :
$(Q)$(REMOVE) $(TARGET).sym
$(Q)$(REMOVE) $(TARGET).lss
$(Q)$(REMOVE) $(OBJ)
$(Q)$(REMOVE) cfgware.h
$(Q)$(REMOVE) $(OBJDIR)/autoconf.h
$(Q)$(REMOVE) $(OBJDIR)/*.bin
$(Q)$(REMOVE) $(LST)

View File

@ -17,7 +17,6 @@ b) Cortex M3 toolchain
- texinfo
- libmpfr-dev
- libgmp3-dev
- libmpc-dev
- gawk
- bison
- recode

View File

@ -6,16 +6,16 @@
/* CM3 bit-band access macro - no error checks! */
#define BITBAND(addr,bit) \
(*((volatile unsigned long *)( \
((unsigned long)&(addr) & 0x01ffffff)*32 + \
(bit)*4 + 0x02000000 + ((unsigned long)&(addr) & 0xfe000000) \
)))
(*((volatile unsigned long *)( \
((unsigned long)&(addr) & 0x01ffffff)*32 + \
(bit)*4 + 0x02000000 + ((unsigned long)&(addr) & 0xfe000000) \
)))
#define BITBAND_OFF(addr,offset,bit) \
(*((volatile unsigned long *)( \
(((unsigned long)&(addr) + offset) & 0x01ffffff)*32 + \
(bit)*4 + 0x02000000 + (((unsigned long)&(addr) + offset) & 0xfe000000) \
)))
(*((volatile unsigned long *)( \
(((unsigned long)&(addr) + offset) & 0x01ffffff)*32 + \
(bit)*4 + 0x02000000 + (((unsigned long)&(addr) + offset) & 0xfe000000) \
)))
#endif

View File

@ -4,18 +4,18 @@
/* The classic macro */
#define BV(x) (1<<(x))
/* CM3 bit-band access macro - no error checks! */
#define BITBAND(addr,bit) \
(*((volatile unsigned long *)( \
((unsigned long)&(addr) & 0x01ffffff)*32 + \
(bit)*4 + 0x02000000 + ((unsigned long)&(addr) & 0xfe000000) \
)))
/* CM3 bit-bang access macro - no error checks! */
#define BITBANG(addr,bit) \
(*((volatile unsigned long *)( \
((unsigned long)&(addr) & 0x01ffffff)*32 + \
(bit)*4 + 0x02000000 + ((unsigned long)&(addr) & 0xfe000000) \
)))
#define BITBAND_OFF(addr,offset,bit) \
(*((volatile unsigned long *)( \
(((unsigned long)&(addr) + offset) & 0x01ffffff)*32 + \
(bit)*4 + 0x02000000 + (((unsigned long)&(addr) + offset) & 0xfe000000) \
)))
#define BITBANG_OFF(addr,offset,bit) \
(*((volatile unsigned long *)( \
(((unsigned long)&(addr) + offset) & 0x01ffffff)*32 + \
(bit)*4 + 0x02000000 + (((unsigned long)&(addr) + offset) & 0xfe000000) \
)))
#endif

View File

@ -31,463 +31,484 @@
#if _CODE_PAGE == 437
#define _TBLDEF 1
static
const WCHAR Tbl[] = { /* CP437(0x80-0xFF) to Unicode conversion table */
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
0x00FF, 0x00D6, 0x00DC, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4,
0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248,
0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
const WCHAR Tbl[] = /* CP437(0x80-0xFF) to Unicode conversion table */
{
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
0x00FF, 0x00D6, 0x00DC, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4,
0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248,
0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
};
#elif _CODE_PAGE == 720
#define _TBLDEF 1
static
const WCHAR Tbl[] = { /* CP720(0x80-0xFF) to Unicode conversion table */
0x0000, 0x0000, 0x00E9, 0x00E2, 0x0000, 0x00E0, 0x0000, 0x00E7,
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0000, 0x0000, 0x0000,
0x0000, 0x0651, 0x0652, 0x00F4, 0x00A4, 0x0640, 0x00FB, 0x00F9,
0x0621, 0x0622, 0x0623, 0x0624, 0x00A3, 0x0625, 0x0626, 0x0627,
0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F,
0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
0x0636, 0x0637, 0x0638, 0x0639, 0x063A, 0x0641, 0x00B5, 0x0642,
0x0643, 0x0644, 0x0645, 0x0646, 0x0647, 0x0648, 0x0649, 0x064A,
0x2261, 0x064B, 0x064C, 0x064D, 0x064E, 0x064F, 0xO650, 0x2248,
0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
const WCHAR Tbl[] = /* CP720(0x80-0xFF) to Unicode conversion table */
{
0x0000, 0x0000, 0x00E9, 0x00E2, 0x0000, 0x00E0, 0x0000, 0x00E7,
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0000, 0x0000, 0x0000,
0x0000, 0x0651, 0x0652, 0x00F4, 0x00A4, 0x0640, 0x00FB, 0x00F9,
0x0621, 0x0622, 0x0623, 0x0624, 0x00A3, 0x0625, 0x0626, 0x0627,
0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F,
0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
0x0636, 0x0637, 0x0638, 0x0639, 0x063A, 0x0641, 0x00B5, 0x0642,
0x0643, 0x0644, 0x0645, 0x0646, 0x0647, 0x0648, 0x0649, 0x064A,
0x2261, 0x064B, 0x064C, 0x064D, 0x064E, 0x064F, 0xO650, 0x2248,
0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
};
#elif _CODE_PAGE == 737
#define _TBLDEF 1
static
const WCHAR Tbl[] = { /* CP737(0x80-0xFF) to Unicode conversion table */
0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398,
0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, 0x03A0,
0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9,
0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, 0x03B8,
0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0,
0x03C1, 0x03C3, 0x03C2, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
0x03C9, 0x03AC, 0x03AD, 0x03AE, 0x03CA, 0x03AF, 0x03CC, 0x03CD,
0x03CB, 0x03CE, 0x0386, 0x0388, 0x0389, 0x038A, 0x038C, 0x038E,
0x038F, 0x00B1, 0x2265, 0x2264, 0x03AA, 0x03AB, 0x00F7, 0x2248,
0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
const WCHAR Tbl[] = /* CP737(0x80-0xFF) to Unicode conversion table */
{
0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398,
0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, 0x03A0,
0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9,
0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, 0x03B8,
0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0,
0x03C1, 0x03C3, 0x03C2, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
0x03C9, 0x03AC, 0x03AD, 0x03AE, 0x03CA, 0x03AF, 0x03CC, 0x03CD,
0x03CB, 0x03CE, 0x0386, 0x0388, 0x0389, 0x038A, 0x038C, 0x038E,
0x038F, 0x00B1, 0x2265, 0x2264, 0x03AA, 0x03AB, 0x00F7, 0x2248,
0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
};
#elif _CODE_PAGE == 775
#define _TBLDEF 1
static
const WCHAR Tbl[] = { /* CP775(0x80-0xFF) to Unicode conversion table */
0x0106, 0x00FC, 0x00E9, 0x0101, 0x00E4, 0x0123, 0x00E5, 0x0107,
0x0142, 0x0113, 0x0156, 0x0157, 0x012B, 0x0179, 0x00C4, 0x00C5,
0x00C9, 0x00E6, 0x00C6, 0x014D, 0x00F6, 0x0122, 0x00A2, 0x015A,
0x015B, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x00A4,
0x0100, 0x012A, 0x00F3, 0x017B, 0x017C, 0x017A, 0x201D, 0x00A6,
0x00A9, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x0141, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0104, 0x010C, 0x0118,
0x0116, 0x2563, 0x2551, 0x2557, 0x255D, 0x012E, 0x0160, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0172, 0x016A,
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x017D,
0x0105, 0x010D, 0x0119, 0x0117, 0x012F, 0x0161, 0x0173, 0x016B,
0x017E, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
0x00D3, 0x00DF, 0x014C, 0x0143, 0x00F5, 0x00D5, 0x00B5, 0x0144,
0x0136, 0x0137, 0x013B, 0x013C, 0x0146, 0x0112, 0x0145, 0x2019,
0x00AD, 0x00B1, 0x201C, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x201E,
0x00B0, 0x2219, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
const WCHAR Tbl[] = /* CP775(0x80-0xFF) to Unicode conversion table */
{
0x0106, 0x00FC, 0x00E9, 0x0101, 0x00E4, 0x0123, 0x00E5, 0x0107,
0x0142, 0x0113, 0x0156, 0x0157, 0x012B, 0x0179, 0x00C4, 0x00C5,
0x00C9, 0x00E6, 0x00C6, 0x014D, 0x00F6, 0x0122, 0x00A2, 0x015A,
0x015B, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x00A4,
0x0100, 0x012A, 0x00F3, 0x017B, 0x017C, 0x017A, 0x201D, 0x00A6,
0x00A9, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x0141, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0104, 0x010C, 0x0118,
0x0116, 0x2563, 0x2551, 0x2557, 0x255D, 0x012E, 0x0160, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0172, 0x016A,
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x017D,
0x0105, 0x010D, 0x0119, 0x0117, 0x012F, 0x0161, 0x0173, 0x016B,
0x017E, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
0x00D3, 0x00DF, 0x014C, 0x0143, 0x00F5, 0x00D5, 0x00B5, 0x0144,
0x0136, 0x0137, 0x013B, 0x013C, 0x0146, 0x0112, 0x0145, 0x2019,
0x00AD, 0x00B1, 0x201C, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x201E,
0x00B0, 0x2219, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
};
#elif _CODE_PAGE == 850
#define _TBLDEF 1
static
const WCHAR Tbl[] = { /* CP850(0x80-0xFF) to Unicode conversion table */
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192,
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0,
0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3,
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x0131, 0x00CD, 0x00CE,
0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580,
0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE,
0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4,
0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8,
0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
const WCHAR Tbl[] = /* CP850(0x80-0xFF) to Unicode conversion table */
{
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192,
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0,
0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3,
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x0131, 0x00CD, 0x00CE,
0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580,
0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE,
0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4,
0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8,
0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
};
#elif _CODE_PAGE == 852
#define _TBLDEF 1
static
const WCHAR Tbl[] = { /* CP852(0x80-0xFF) to Unicode conversion table */
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x016F, 0x0107, 0x00E7,
0x0142, 0x00EB, 0x0150, 0x0151, 0x00EE, 0x0179, 0x00C4, 0x0106,
0x00C9, 0x0139, 0x013A, 0x00F4, 0x00F6, 0x013D, 0x013E, 0x015A,
0x015B, 0x00D6, 0x00DC, 0x0164, 0x0165, 0x0141, 0x00D7, 0x010D,
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x0104, 0x0105, 0x017D, 0x017E,
0x0118, 0x0119, 0x00AC, 0x017A, 0x010C, 0x015F, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x011A,
0x015E, 0x2563, 0x2551, 0x2557, 0x255D, 0x017B, 0x017C, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0102, 0x0103,
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
0x0111, 0x0110, 0x010E, 0x00CB, 0x010F, 0x0147, 0x00CD, 0x00CE,
0x011B, 0x2518, 0x250C, 0x2588, 0x2584, 0x0162, 0x016E, 0x2580,
0x00D3, 0x00DF, 0x00D4, 0x0143, 0x0144, 0x0148, 0x0160, 0x0161,
0x0154, 0x00DA, 0x0155, 0x0170, 0x00FD, 0x00DD, 0x0163, 0x00B4,
0x00AD, 0x02DD, 0x02DB, 0x02C7, 0x02D8, 0x00A7, 0x00F7, 0x00B8,
0x00B0, 0x00A8, 0x02D9, 0x0171, 0x0158, 0x0159, 0x25A0, 0x00A0
const WCHAR Tbl[] = /* CP852(0x80-0xFF) to Unicode conversion table */
{
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x016F, 0x0107, 0x00E7,
0x0142, 0x00EB, 0x0150, 0x0151, 0x00EE, 0x0179, 0x00C4, 0x0106,
0x00C9, 0x0139, 0x013A, 0x00F4, 0x00F6, 0x013D, 0x013E, 0x015A,
0x015B, 0x00D6, 0x00DC, 0x0164, 0x0165, 0x0141, 0x00D7, 0x010D,
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x0104, 0x0105, 0x017D, 0x017E,
0x0118, 0x0119, 0x00AC, 0x017A, 0x010C, 0x015F, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x011A,
0x015E, 0x2563, 0x2551, 0x2557, 0x255D, 0x017B, 0x017C, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0102, 0x0103,
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
0x0111, 0x0110, 0x010E, 0x00CB, 0x010F, 0x0147, 0x00CD, 0x00CE,
0x011B, 0x2518, 0x250C, 0x2588, 0x2584, 0x0162, 0x016E, 0x2580,
0x00D3, 0x00DF, 0x00D4, 0x0143, 0x0144, 0x0148, 0x0160, 0x0161,
0x0154, 0x00DA, 0x0155, 0x0170, 0x00FD, 0x00DD, 0x0163, 0x00B4,
0x00AD, 0x02DD, 0x02DB, 0x02C7, 0x02D8, 0x00A7, 0x00F7, 0x00B8,
0x00B0, 0x00A8, 0x02D9, 0x0171, 0x0158, 0x0159, 0x25A0, 0x00A0
};
#elif _CODE_PAGE == 855
#define _TBLDEF 1
static
const WCHAR Tbl[] = { /* CP855(0x80-0xFF) to Unicode conversion table */
0x0452, 0x0402, 0x0453, 0x0403, 0x0451, 0x0401, 0x0454, 0x0404,
0x0455, 0x0405, 0x0456, 0x0406, 0x0457, 0x0407, 0x0458, 0x0408,
0x0459, 0x0409, 0x045A, 0x040A, 0x045B, 0x040B, 0x045C, 0x040C,
0x045E, 0x040E, 0x045F, 0x040F, 0x044E, 0x042E, 0x044A, 0x042A,
0x0430, 0x0410, 0x0431, 0x0411, 0x0446, 0x0426, 0x0434, 0x0414,
0x0435, 0x0415, 0x0444, 0x0424, 0x0433, 0x0413, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0445, 0x0425, 0x0438,
0x0418, 0x2563, 0x2551, 0x2557, 0x255D, 0x0439, 0x0419, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x043A, 0x041A,
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
0x043B, 0x041B, 0x043C, 0x041C, 0x043D, 0x041D, 0x043E, 0x041E,
0x043F, 0x2518, 0x250C, 0x2588, 0x2584, 0x041F, 0x044F, 0x2580,
0x042F, 0x0440, 0x0420, 0x0441, 0x0421, 0x0442, 0x0422, 0x0443,
0x0423, 0x0436, 0x0416, 0x0432, 0x0412, 0x044C, 0x042C, 0x2116,
0x00AD, 0x044B, 0x042B, 0x0437, 0x0417, 0x0448, 0x0428, 0x044D,
0x042D, 0x0449, 0x0429, 0x0447, 0x0427, 0x00A7, 0x25A0, 0x00A0
const WCHAR Tbl[] = /* CP855(0x80-0xFF) to Unicode conversion table */
{
0x0452, 0x0402, 0x0453, 0x0403, 0x0451, 0x0401, 0x0454, 0x0404,
0x0455, 0x0405, 0x0456, 0x0406, 0x0457, 0x0407, 0x0458, 0x0408,
0x0459, 0x0409, 0x045A, 0x040A, 0x045B, 0x040B, 0x045C, 0x040C,
0x045E, 0x040E, 0x045F, 0x040F, 0x044E, 0x042E, 0x044A, 0x042A,
0x0430, 0x0410, 0x0431, 0x0411, 0x0446, 0x0426, 0x0434, 0x0414,
0x0435, 0x0415, 0x0444, 0x0424, 0x0433, 0x0413, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0445, 0x0425, 0x0438,
0x0418, 0x2563, 0x2551, 0x2557, 0x255D, 0x0439, 0x0419, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x043A, 0x041A,
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
0x043B, 0x041B, 0x043C, 0x041C, 0x043D, 0x041D, 0x043E, 0x041E,
0x043F, 0x2518, 0x250C, 0x2588, 0x2584, 0x041F, 0x044F, 0x2580,
0x042F, 0x0440, 0x0420, 0x0441, 0x0421, 0x0442, 0x0422, 0x0443,
0x0423, 0x0436, 0x0416, 0x0432, 0x0412, 0x044C, 0x042C, 0x2116,
0x00AD, 0x044B, 0x042B, 0x0437, 0x0417, 0x0448, 0x0428, 0x044D,
0x042D, 0x0449, 0x0429, 0x0447, 0x0427, 0x00A7, 0x25A0, 0x00A0
};
#elif _CODE_PAGE == 857
#define _TBLDEF 1
static
const WCHAR Tbl[] = { /* CP857(0x80-0xFF) to Unicode conversion table */
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0131, 0x00C4, 0x00C5,
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
0x0130, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x015E, 0x015F,
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x011E, 0x011F,
0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0,
0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3,
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
0x00BA, 0x00AA, 0x00CA, 0x00CB, 0x00C8, 0x0000, 0x00CD, 0x00CE,
0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580,
0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x0000,
0x00D7, 0x00DA, 0x00DB, 0x00D9, 0x00EC, 0x00FF, 0x00AF, 0x00B4,
0x00AD, 0x00B1, 0x0000, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8,
0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
const WCHAR Tbl[] = /* CP857(0x80-0xFF) to Unicode conversion table */
{
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0131, 0x00C4, 0x00C5,
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
0x0130, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x015E, 0x015F,
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x011E, 0x011F,
0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0,
0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3,
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
0x00BA, 0x00AA, 0x00CA, 0x00CB, 0x00C8, 0x0000, 0x00CD, 0x00CE,
0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580,
0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x0000,
0x00D7, 0x00DA, 0x00DB, 0x00D9, 0x00EC, 0x00FF, 0x00AF, 0x00B4,
0x00AD, 0x00B1, 0x0000, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8,
0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
};
#elif _CODE_PAGE == 858
#define _TBLDEF 1
static
const WCHAR Tbl[] = { /* CP858(0x80-0xFF) to Unicode conversion table */
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192,
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0,
0x00A9, 0x2563, 0x2551, 0x2557, 0x2550, 0x00A2, 0x00A5, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3,
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x20AC, 0x00CD, 0x00CE,
0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00C6, 0x00CC, 0x2580,
0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE,
0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4,
0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8,
0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
const WCHAR Tbl[] = /* CP858(0x80-0xFF) to Unicode conversion table */
{
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192,
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0,
0x00A9, 0x2563, 0x2551, 0x2557, 0x2550, 0x00A2, 0x00A5, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3,
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x20AC, 0x00CD, 0x00CE,
0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00C6, 0x00CC, 0x2580,
0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE,
0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4,
0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8,
0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
};
#elif _CODE_PAGE == 862
#define _TBLDEF 1
static
const WCHAR Tbl[] = { /* CP862(0x80-0xFF) to Unicode conversion table */
0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7,
0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,
0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7,
0x05E8, 0x05E9, 0x05EA, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4,
0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248,
0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
const WCHAR Tbl[] = /* CP862(0x80-0xFF) to Unicode conversion table */
{
0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7,
0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,
0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7,
0x05E8, 0x05E9, 0x05EA, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4,
0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248,
0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
};
#elif _CODE_PAGE == 866
#define _TBLDEF 1
static
const WCHAR Tbl[] = { /* CP866(0x80-0xFF) to Unicode conversion table */
0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
0x0401, 0x0451, 0x0404, 0x0454, 0x0407, 0x0457, 0x040E, 0x045E,
0x00B0, 0x2219, 0x00B7, 0x221A, 0x2116, 0x00A4, 0x25A0, 0x00A0
const WCHAR Tbl[] = /* CP866(0x80-0xFF) to Unicode conversion table */
{
0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
0x0401, 0x0451, 0x0404, 0x0454, 0x0407, 0x0457, 0x040E, 0x045E,
0x00B0, 0x2219, 0x00B7, 0x221A, 0x2116, 0x00A4, 0x25A0, 0x00A0
};
#elif _CODE_PAGE == 874
#define _TBLDEF 1
static
const WCHAR Tbl[] = { /* CP874(0x80-0xFF) to Unicode conversion table */
0x20AC, 0x0000, 0x0000, 0x0000, 0x0000, 0x2026, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x00A0, 0x0E01, 0x0E02, 0x0E03, 0x0E04, 0x0E05, 0x0E06, 0x0E07,
0x0E08, 0x0E09, 0x0E0A, 0x0E0B, 0x0E0C, 0x0E0D, 0x0E0E, 0x0E0F,
0x0E10, 0x0E11, 0x0E12, 0x0E13, 0x0E14, 0x0E15, 0x0E16, 0x0E17,
0x0E18, 0x0E19, 0x0E1A, 0x0E1B, 0x0E1C, 0x0E1D, 0x0E1E, 0x0E1F,
0x0E20, 0x0E21, 0x0E22, 0x0E23, 0x0E24, 0x0E25, 0x0E26, 0x0E27,
0x0E28, 0x0E29, 0x0E2A, 0x0E2B, 0x0E2C, 0x0E2D, 0x0E2E, 0x0E2F,
0x0E30, 0x0E31, 0x0E32, 0x0E33, 0x0E34, 0x0E35, 0x0E36, 0x0E37,
0x0E38, 0x0E39, 0x0E3A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0E3F,
0x0E40, 0x0E41, 0x0E42, 0x0E43, 0x0E44, 0x0E45, 0x0E46, 0x0E47,
0x0E48, 0x0E49, 0x0E4A, 0x0E4B, 0x0E4C, 0x0E4D, 0x0E4E, 0x0E4F,
0x0E50, 0x0E51, 0x0E52, 0x0E53, 0x0E54, 0x0E55, 0x0E56, 0x0E57,
0x0E58, 0x0E59, 0x0E5A, 0x0E5B, 0x0000, 0x0000, 0x0000, 0x0000
const WCHAR Tbl[] = /* CP874(0x80-0xFF) to Unicode conversion table */
{
0x20AC, 0x0000, 0x0000, 0x0000, 0x0000, 0x2026, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x00A0, 0x0E01, 0x0E02, 0x0E03, 0x0E04, 0x0E05, 0x0E06, 0x0E07,
0x0E08, 0x0E09, 0x0E0A, 0x0E0B, 0x0E0C, 0x0E0D, 0x0E0E, 0x0E0F,
0x0E10, 0x0E11, 0x0E12, 0x0E13, 0x0E14, 0x0E15, 0x0E16, 0x0E17,
0x0E18, 0x0E19, 0x0E1A, 0x0E1B, 0x0E1C, 0x0E1D, 0x0E1E, 0x0E1F,
0x0E20, 0x0E21, 0x0E22, 0x0E23, 0x0E24, 0x0E25, 0x0E26, 0x0E27,
0x0E28, 0x0E29, 0x0E2A, 0x0E2B, 0x0E2C, 0x0E2D, 0x0E2E, 0x0E2F,
0x0E30, 0x0E31, 0x0E32, 0x0E33, 0x0E34, 0x0E35, 0x0E36, 0x0E37,
0x0E38, 0x0E39, 0x0E3A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0E3F,
0x0E40, 0x0E41, 0x0E42, 0x0E43, 0x0E44, 0x0E45, 0x0E46, 0x0E47,
0x0E48, 0x0E49, 0x0E4A, 0x0E4B, 0x0E4C, 0x0E4D, 0x0E4E, 0x0E4F,
0x0E50, 0x0E51, 0x0E52, 0x0E53, 0x0E54, 0x0E55, 0x0E56, 0x0E57,
0x0E58, 0x0E59, 0x0E5A, 0x0E5B, 0x0000, 0x0000, 0x0000, 0x0000
};
#elif _CODE_PAGE == 1250
#define _TBLDEF 1
static
const WCHAR Tbl[] = { /* CP1250(0x80-0xFF) to Unicode conversion table */
0x20AC, 0x0000, 0x201A, 0x0000, 0x201E, 0x2026, 0x2020, 0x2021,
0x0000, 0x2030, 0x0160, 0x2039, 0x015A, 0x0164, 0x017D, 0x0179,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x0000, 0x2122, 0x0161, 0x203A, 0x015B, 0x0165, 0x017E, 0x017A,
0x00A0, 0x02C7, 0x02D8, 0x0141, 0x00A4, 0x0104, 0x00A6, 0x00A7,
0x00A8, 0x00A9, 0x015E, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x017B,
0x00B0, 0x00B1, 0x02DB, 0x0142, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
0x00B8, 0x0105, 0x015F, 0x00BB, 0x013D, 0x02DD, 0x013E, 0x017C,
0x0154, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0139, 0x0106, 0x00C7,
0x010C, 0x00C9, 0x0118, 0x00CB, 0x011A, 0x00CD, 0x00CE, 0x010E,
0x0110, 0x0143, 0x0147, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x00D7,
0x0158, 0x016E, 0x00DA, 0x0170, 0x00DC, 0x00DD, 0x0162, 0x00DF,
0x0155, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x013A, 0x0107, 0x00E7,
0x010D, 0x00E9, 0x0119, 0x00EB, 0x011B, 0x00ED, 0x00EE, 0x010F,
0x0111, 0x0144, 0x0148, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x00F7,
0x0159, 0x016F, 0x00FA, 0x0171, 0x00FC, 0x00FD, 0x0163, 0x02D9
const WCHAR Tbl[] = /* CP1250(0x80-0xFF) to Unicode conversion table */
{
0x20AC, 0x0000, 0x201A, 0x0000, 0x201E, 0x2026, 0x2020, 0x2021,
0x0000, 0x2030, 0x0160, 0x2039, 0x015A, 0x0164, 0x017D, 0x0179,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x0000, 0x2122, 0x0161, 0x203A, 0x015B, 0x0165, 0x017E, 0x017A,
0x00A0, 0x02C7, 0x02D8, 0x0141, 0x00A4, 0x0104, 0x00A6, 0x00A7,
0x00A8, 0x00A9, 0x015E, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x017B,
0x00B0, 0x00B1, 0x02DB, 0x0142, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
0x00B8, 0x0105, 0x015F, 0x00BB, 0x013D, 0x02DD, 0x013E, 0x017C,
0x0154, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0139, 0x0106, 0x00C7,
0x010C, 0x00C9, 0x0118, 0x00CB, 0x011A, 0x00CD, 0x00CE, 0x010E,
0x0110, 0x0143, 0x0147, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x00D7,
0x0158, 0x016E, 0x00DA, 0x0170, 0x00DC, 0x00DD, 0x0162, 0x00DF,
0x0155, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x013A, 0x0107, 0x00E7,
0x010D, 0x00E9, 0x0119, 0x00EB, 0x011B, 0x00ED, 0x00EE, 0x010F,
0x0111, 0x0144, 0x0148, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x00F7,
0x0159, 0x016F, 0x00FA, 0x0171, 0x00FC, 0x00FD, 0x0163, 0x02D9
};
#elif _CODE_PAGE == 1251
#define _TBLDEF 1
static
const WCHAR Tbl[] = { /* CP1251(0x80-0xFF) to Unicode conversion table */
0x0402, 0x0403, 0x201A, 0x0453, 0x201E, 0x2026, 0x2020, 0x2021,
0x20AC, 0x2030, 0x0409, 0x2039, 0x040A, 0x040C, 0x040B, 0x040F,
0x0452, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x0000, 0x2111, 0x0459, 0x203A, 0x045A, 0x045C, 0x045B, 0x045F,
0x00A0, 0x040E, 0x045E, 0x0408, 0x00A4, 0x0490, 0x00A6, 0x00A7,
0x0401, 0x00A9, 0x0404, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x0407,
0x00B0, 0x00B1, 0x0406, 0x0456, 0x0491, 0x00B5, 0x00B6, 0x00B7,
0x0451, 0x2116, 0x0454, 0x00BB, 0x0458, 0x0405, 0x0455, 0x0457,
0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F
const WCHAR Tbl[] = /* CP1251(0x80-0xFF) to Unicode conversion table */
{
0x0402, 0x0403, 0x201A, 0x0453, 0x201E, 0x2026, 0x2020, 0x2021,
0x20AC, 0x2030, 0x0409, 0x2039, 0x040A, 0x040C, 0x040B, 0x040F,
0x0452, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x0000, 0x2111, 0x0459, 0x203A, 0x045A, 0x045C, 0x045B, 0x045F,
0x00A0, 0x040E, 0x045E, 0x0408, 0x00A4, 0x0490, 0x00A6, 0x00A7,
0x0401, 0x00A9, 0x0404, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x0407,
0x00B0, 0x00B1, 0x0406, 0x0456, 0x0491, 0x00B5, 0x00B6, 0x00B7,
0x0451, 0x2116, 0x0454, 0x00BB, 0x0458, 0x0405, 0x0455, 0x0457,
0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F
};
#elif _CODE_PAGE == 1252
#define _TBLDEF 1
static
const WCHAR Tbl[] = { /* CP1252(0x80-0xFF) to Unicode conversion table */
0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x017D, 0x0000,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x0000, 0x017E, 0x0178,
0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF,
0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF
const WCHAR Tbl[] = /* CP1252(0x80-0xFF) to Unicode conversion table */
{
0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x017D, 0x0000,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x0000, 0x017E, 0x0178,
0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF,
0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF
};
#elif _CODE_PAGE == 1253
#define _TBLDEF 1
static
const WCHAR Tbl[] = { /* CP1253(0x80-0xFF) to Unicode conversion table */
0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
0x0000, 0x2030, 0x0000, 0x2039, 0x000C, 0x0000, 0x0000, 0x0000,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x0000, 0x2122, 0x0000, 0x203A, 0x0000, 0x0000, 0x0000, 0x0000,
0x00A0, 0x0385, 0x0386, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
0x00A8, 0x00A9, 0x0000, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x2015,
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x0384, 0x00B5, 0x00B6, 0x00B7,
0x0388, 0x0389, 0x038A, 0x00BB, 0x038C, 0x00BD, 0x038E, 0x038F,
0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397,
0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F,
0x03A0, 0x03A1, 0x0000, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7,
0x03A8, 0x03A9, 0x03AA, 0x03AD, 0x03AC, 0x03AD, 0x03AE, 0x03AF,
0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7,
0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF,
0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7,
0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, 0x0000
const WCHAR Tbl[] = /* CP1253(0x80-0xFF) to Unicode conversion table */
{
0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
0x0000, 0x2030, 0x0000, 0x2039, 0x000C, 0x0000, 0x0000, 0x0000,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x0000, 0x2122, 0x0000, 0x203A, 0x0000, 0x0000, 0x0000, 0x0000,
0x00A0, 0x0385, 0x0386, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
0x00A8, 0x00A9, 0x0000, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x2015,
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x0384, 0x00B5, 0x00B6, 0x00B7,
0x0388, 0x0389, 0x038A, 0x00BB, 0x038C, 0x00BD, 0x038E, 0x038F,
0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397,
0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F,
0x03A0, 0x03A1, 0x0000, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7,
0x03A8, 0x03A9, 0x03AA, 0x03AD, 0x03AC, 0x03AD, 0x03AE, 0x03AF,
0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7,
0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF,
0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7,
0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, 0x0000
};
#elif _CODE_PAGE == 1254
#define _TBLDEF 1
static
const WCHAR Tbl[] = { /* CP1254(0x80-0xFF) to Unicode conversion table */
0x20AC, 0x0000, 0x210A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x0000, 0x0000,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x0000, 0x0000, 0x0178,
0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
0x011E, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
0x00D8, 0x00D9, 0x00DA, 0x00BD, 0x00DC, 0x0130, 0x015E, 0x00DF,
0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
0x011F, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x0131, 0x015F, 0x00FF
const WCHAR Tbl[] = /* CP1254(0x80-0xFF) to Unicode conversion table */
{
0x20AC, 0x0000, 0x210A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x0000, 0x0000,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x0000, 0x0000, 0x0178,
0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
0x011E, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
0x00D8, 0x00D9, 0x00DA, 0x00BD, 0x00DC, 0x0130, 0x015E, 0x00DF,
0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
0x011F, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x0131, 0x015F, 0x00FF
};
#elif _CODE_PAGE == 1255
#define _TBLDEF 1
static
const WCHAR Tbl[] = { /* CP1255(0x80-0xFF) to Unicode conversion table */
0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
0x02C6, 0x2030, 0x0000, 0x2039, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x02DC, 0x2122, 0x0000, 0x203A, 0x0000, 0x0000, 0x0000, 0x0000,
0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
0x00A8, 0x00A9, 0x00D7, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
0x00B8, 0x00B9, 0x00F7, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
0x05B0, 0x05B1, 0x05B2, 0x05B3, 0x05B4, 0x05B5, 0x05B6, 0x05B7,
0x05B8, 0x05B9, 0x0000, 0x05BB, 0x05BC, 0x05BD, 0x05BE, 0x05BF,
0x05C0, 0x05C1, 0x05C2, 0x05C3, 0x05F0, 0x05F1, 0x05F2, 0x05F3,
0x05F4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7,
0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,
0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7,
0x05E8, 0x05E9, 0x05EA, 0x0000, 0x0000, 0x200E, 0x200F, 0x0000
const WCHAR Tbl[] = /* CP1255(0x80-0xFF) to Unicode conversion table */
{
0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
0x02C6, 0x2030, 0x0000, 0x2039, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x02DC, 0x2122, 0x0000, 0x203A, 0x0000, 0x0000, 0x0000, 0x0000,
0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
0x00A8, 0x00A9, 0x00D7, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
0x00B8, 0x00B9, 0x00F7, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
0x05B0, 0x05B1, 0x05B2, 0x05B3, 0x05B4, 0x05B5, 0x05B6, 0x05B7,
0x05B8, 0x05B9, 0x0000, 0x05BB, 0x05BC, 0x05BD, 0x05BE, 0x05BF,
0x05C0, 0x05C1, 0x05C2, 0x05C3, 0x05F0, 0x05F1, 0x05F2, 0x05F3,
0x05F4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7,
0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,
0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7,
0x05E8, 0x05E9, 0x05EA, 0x0000, 0x0000, 0x200E, 0x200F, 0x0000
};
#elif _CODE_PAGE == 1256
#define _TBLDEF 1
static
const WCHAR Tbl[] = { /* CP1256(0x80-0xFF) to Unicode conversion table */
0x20AC, 0x067E, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
0x02C6, 0x2030, 0x0679, 0x2039, 0x0152, 0x0686, 0x0698, 0x0688,
0x06AF, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x06A9, 0x2122, 0x0691, 0x203A, 0x0153, 0x200C, 0x200D, 0x06BA,
0x00A0, 0x060C, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
0x00A8, 0x00A9, 0x06BE, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
0x00B8, 0x00B9, 0x061B, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x061F,
0x06C1, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627,
0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F,
0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x00D7,
0x0637, 0x0638, 0x0639, 0x063A, 0x0640, 0x0640, 0x0642, 0x0643,
0x00E0, 0x0644, 0x00E2, 0x0645, 0x0646, 0x0647, 0x0648, 0x00E7,
0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x0649, 0x064A, 0x00EE, 0x00EF,
0x064B, 0x064C, 0x064D, 0x064E, 0x00F4, 0x064F, 0x0650, 0x00F7,
0x0651, 0x00F9, 0x0652, 0x00FB, 0x00FC, 0x200E, 0x200F, 0x06D2
const WCHAR Tbl[] = /* CP1256(0x80-0xFF) to Unicode conversion table */
{
0x20AC, 0x067E, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
0x02C6, 0x2030, 0x0679, 0x2039, 0x0152, 0x0686, 0x0698, 0x0688,
0x06AF, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x06A9, 0x2122, 0x0691, 0x203A, 0x0153, 0x200C, 0x200D, 0x06BA,
0x00A0, 0x060C, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
0x00A8, 0x00A9, 0x06BE, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
0x00B8, 0x00B9, 0x061B, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x061F,
0x06C1, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627,
0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F,
0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x00D7,
0x0637, 0x0638, 0x0639, 0x063A, 0x0640, 0x0640, 0x0642, 0x0643,
0x00E0, 0x0644, 0x00E2, 0x0645, 0x0646, 0x0647, 0x0648, 0x00E7,
0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x0649, 0x064A, 0x00EE, 0x00EF,
0x064B, 0x064C, 0x064D, 0x064E, 0x00F4, 0x064F, 0x0650, 0x00F7,
0x0651, 0x00F9, 0x0652, 0x00FB, 0x00FC, 0x200E, 0x200F, 0x06D2
}
#elif _CODE_PAGE == 1257
#define _TBLDEF 1
static
const WCHAR Tbl[] = { /* CP1257(0x80-0xFF) to Unicode conversion table */
0x20AC, 0x0000, 0x201A, 0x0000, 0x201E, 0x2026, 0x2020, 0x2021,
0x0000, 0x2030, 0x0000, 0x2039, 0x0000, 0x00A8, 0x02C7, 0x00B8,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x0000, 0x2122, 0x0000, 0x203A, 0x0000, 0x00AF, 0x02DB, 0x0000,
0x00A0, 0x0000, 0x00A2, 0x00A3, 0x00A4, 0x0000, 0x00A6, 0x00A7,
0x00D8, 0x00A9, 0x0156, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
0x00B8, 0x00B9, 0x0157, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00E6,
0x0104, 0x012E, 0x0100, 0x0106, 0x00C4, 0x00C5, 0x0118, 0x0112,
0x010C, 0x00C9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012A, 0x013B,
0x0160, 0x0143, 0x0145, 0x00D3, 0x014C, 0x00D5, 0x00D6, 0x00D7,
0x0172, 0x0141, 0x015A, 0x016A, 0x00DC, 0x017B, 0x017D, 0x00DF,
0x0105, 0x012F, 0x0101, 0x0107, 0x00E4, 0x00E5, 0x0119, 0x0113,
0x010D, 0x00E9, 0x017A, 0x0117, 0x0123, 0x0137, 0x012B, 0x013C,
0x0161, 0x0144, 0x0146, 0x00F3, 0x014D, 0x00F5, 0x00F6, 0x00F7,
0x0173, 0x014E, 0x015B, 0x016B, 0x00FC, 0x017C, 0x017E, 0x02D9
const WCHAR Tbl[] = /* CP1257(0x80-0xFF) to Unicode conversion table */
{
0x20AC, 0x0000, 0x201A, 0x0000, 0x201E, 0x2026, 0x2020, 0x2021,
0x0000, 0x2030, 0x0000, 0x2039, 0x0000, 0x00A8, 0x02C7, 0x00B8,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x0000, 0x2122, 0x0000, 0x203A, 0x0000, 0x00AF, 0x02DB, 0x0000,
0x00A0, 0x0000, 0x00A2, 0x00A3, 0x00A4, 0x0000, 0x00A6, 0x00A7,
0x00D8, 0x00A9, 0x0156, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
0x00B8, 0x00B9, 0x0157, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00E6,
0x0104, 0x012E, 0x0100, 0x0106, 0x00C4, 0x00C5, 0x0118, 0x0112,
0x010C, 0x00C9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012A, 0x013B,
0x0160, 0x0143, 0x0145, 0x00D3, 0x014C, 0x00D5, 0x00D6, 0x00D7,
0x0172, 0x0141, 0x015A, 0x016A, 0x00DC, 0x017B, 0x017D, 0x00DF,
0x0105, 0x012F, 0x0101, 0x0107, 0x00E4, 0x00E5, 0x0119, 0x0113,
0x010D, 0x00E9, 0x017A, 0x0117, 0x0123, 0x0137, 0x012B, 0x013C,
0x0161, 0x0144, 0x0146, 0x00F3, 0x014D, 0x00F5, 0x00F6, 0x00F7,
0x0173, 0x014E, 0x015B, 0x016B, 0x00FC, 0x017C, 0x017E, 0x02D9
};
#elif _CODE_PAGE == 1258
#define _TBLDEF 1
static
const WCHAR Tbl[] = { /* CP1258(0x80-0xFF) to Unicode conversion table */
0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
0x02C6, 0x2030, 0x0000, 0x2039, 0x0152, 0x0000, 0x0000, 0x0000,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x02DC, 0x2122, 0x0000, 0x203A, 0x0153, 0x0000, 0x0000, 0x0178,
0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
0x00C0, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x0300, 0x00CD, 0x00CE, 0x00CF,
0x0110, 0x00D1, 0x0309, 0x00D3, 0x00D4, 0x01A0, 0x00D6, 0x00D7,
0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x01AF, 0x0303, 0x00DF,
0x00E0, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x0301, 0x00ED, 0x00EE, 0x00EF,
0x0111, 0x00F1, 0x0323, 0x00F3, 0x00F4, 0x01A1, 0x00F6, 0x00F7,
0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x01B0, 0x20AB, 0x00FF
const WCHAR Tbl[] = /* CP1258(0x80-0xFF) to Unicode conversion table */
{
0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
0x02C6, 0x2030, 0x0000, 0x2039, 0x0152, 0x0000, 0x0000, 0x0000,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x02DC, 0x2122, 0x0000, 0x203A, 0x0153, 0x0000, 0x0000, 0x0178,
0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
0x00C0, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x0300, 0x00CD, 0x00CE, 0x00CF,
0x0110, 0x00D1, 0x0309, 0x00D3, 0x00D4, 0x01A0, 0x00D6, 0x00D7,
0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x01AF, 0x0303, 0x00DF,
0x00E0, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x0301, 0x00ED, 0x00EE, 0x00EF,
0x0111, 0x00F1, 0x0323, 0x00F3, 0x00F4, 0x01A1, 0x00F6, 0x00F7,
0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x01B0, 0x20AB, 0x00FF
};
#endif
@ -498,43 +519,54 @@ const WCHAR Tbl[] = { /* CP1258(0x80-0xFF) to Unicode conversion table */
#endif
WCHAR ff_convert ( /* Converted character, Returns zero on error */
WCHAR src, /* Character code to be converted */
UINT dir /* 0: Unicode to OEMCP, 1: OEMCP to Unicode */
WCHAR ff_convert ( /* Converted character, Returns zero on error */
WCHAR src, /* Character code to be converted */
UINT dir /* 0: Unicode to OEMCP, 1: OEMCP to Unicode */
)
{
WCHAR c;
WCHAR c;
if (src < 0x80) { /* ASCII */
c = src;
if ( src < 0x80 ) /* ASCII */
{
c = src;
} else {
if (dir) { /* OEMCP to Unicode */
c = (src >= 0x100) ? 0 : Tbl[src - 0x80];
}
else
{
if ( dir ) /* OEMCP to Unicode */
{
c = ( src >= 0x100 ) ? 0 : Tbl[src - 0x80];
} else { /* Unicode to OEMCP */
for (c = 0; c < 0x80; c++) {
if (src == Tbl[c]) break;
}
c = (c + 0x80) & 0xFF;
}
}
}
else /* Unicode to OEMCP */
{
for ( c = 0; c < 0x80; c++ )
{
if ( src == Tbl[c] )
{
break;
}
}
return c;
c = ( c + 0x80 ) & 0xFF;
}
}
return c;
}
WCHAR ff_wtoupper ( /* Upper converted character */
WCHAR chr /* Input character */
WCHAR ff_wtoupper ( /* Upper converted character */
WCHAR chr /* Input character */
)
{
static const WCHAR tbl_lower[] = { 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0xA1, 0x00A2, 0x00A3, 0x00A5, 0x00AC, 0x00AF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0x0FF, 0x101, 0x103, 0x105, 0x107, 0x109, 0x10B, 0x10D, 0x10F, 0x111, 0x113, 0x115, 0x117, 0x119, 0x11B, 0x11D, 0x11F, 0x121, 0x123, 0x125, 0x127, 0x129, 0x12B, 0x12D, 0x12F, 0x131, 0x133, 0x135, 0x137, 0x13A, 0x13C, 0x13E, 0x140, 0x142, 0x144, 0x146, 0x148, 0x14B, 0x14D, 0x14F, 0x151, 0x153, 0x155, 0x157, 0x159, 0x15B, 0x15D, 0x15F, 0x161, 0x163, 0x165, 0x167, 0x169, 0x16B, 0x16D, 0x16F, 0x171, 0x173, 0x175, 0x177, 0x17A, 0x17C, 0x17E, 0x192, 0x3B1, 0x3B2, 0x3B3, 0x3B4, 0x3B5, 0x3B6, 0x3B7, 0x3B8, 0x3B9, 0x3BA, 0x3BB, 0x3BC, 0x3BD, 0x3BE, 0x3BF, 0x3C0, 0x3C1, 0x3C3, 0x3C4, 0x3C5, 0x3C6, 0x3C7, 0x3C8, 0x3C9, 0x3CA, 0x430, 0x431, 0x432, 0x433, 0x434, 0x435, 0x436, 0x437, 0x438, 0x439, 0x43A, 0x43B, 0x43C, 0x43D, 0x43E, 0x43F, 0x440, 0x441, 0x442, 0x443, 0x444, 0x445, 0x446, 0x447, 0x448, 0x449, 0x44A, 0x44B, 0x44C, 0x44D, 0x44E, 0x44F, 0x451, 0x452, 0x453, 0x454, 0x455, 0x456, 0x457, 0x458, 0x459, 0x45A, 0x45B, 0x45C, 0x45E, 0x45F, 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177, 0x2178, 0x2179, 0x217A, 0x217B, 0x217C, 0x217D, 0x217E, 0x217F, 0xFF41, 0xFF42, 0xFF43, 0xFF44, 0xFF45, 0xFF46, 0xFF47, 0xFF48, 0xFF49, 0xFF4A, 0xFF4B, 0xFF4C, 0xFF4D, 0xFF4E, 0xFF4F, 0xFF50, 0xFF51, 0xFF52, 0xFF53, 0xFF54, 0xFF55, 0xFF56, 0xFF57, 0xFF58, 0xFF59, 0xFF5A, 0 };
static const WCHAR tbl_upper[] = { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x21, 0xFFE0, 0xFFE1, 0xFFE5, 0xFFE2, 0xFFE3, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0x178, 0x100, 0x102, 0x104, 0x106, 0x108, 0x10A, 0x10C, 0x10E, 0x110, 0x112, 0x114, 0x116, 0x118, 0x11A, 0x11C, 0x11E, 0x120, 0x122, 0x124, 0x126, 0x128, 0x12A, 0x12C, 0x12E, 0x130, 0x132, 0x134, 0x136, 0x139, 0x13B, 0x13D, 0x13F, 0x141, 0x143, 0x145, 0x147, 0x14A, 0x14C, 0x14E, 0x150, 0x152, 0x154, 0x156, 0x158, 0x15A, 0x15C, 0x15E, 0x160, 0x162, 0x164, 0x166, 0x168, 0x16A, 0x16C, 0x16E, 0x170, 0x172, 0x174, 0x176, 0x179, 0x17B, 0x17D, 0x191, 0x391, 0x392, 0x393, 0x394, 0x395, 0x396, 0x397, 0x398, 0x399, 0x39A, 0x39B, 0x39C, 0x39D, 0x39E, 0x39F, 0x3A0, 0x3A1, 0x3A3, 0x3A4, 0x3A5, 0x3A6, 0x3A7, 0x3A8, 0x3A9, 0x3AA, 0x410, 0x411, 0x412, 0x413, 0x414, 0x415, 0x416, 0x417, 0x418, 0x419, 0x41A, 0x41B, 0x41C, 0x41D, 0x41E, 0x41F, 0x420, 0x421, 0x422, 0x423, 0x424, 0x425, 0x426, 0x427, 0x428, 0x429, 0x42A, 0x42B, 0x42C, 0x42D, 0x42E, 0x42F, 0x401, 0x402, 0x403, 0x404, 0x405, 0x406, 0x407, 0x408, 0x409, 0x40A, 0x40B, 0x40C, 0x40E, 0x40F, 0x2160, 0x2161, 0x2162, 0x2163, 0x2164, 0x2165, 0x2166, 0x2167, 0x2168, 0x2169, 0x216A, 0x216B, 0x216C, 0x216D, 0x216E, 0x216F, 0xFF21, 0xFF22, 0xFF23, 0xFF24, 0xFF25, 0xFF26, 0xFF27, 0xFF28, 0xFF29, 0xFF2A, 0xFF2B, 0xFF2C, 0xFF2D, 0xFF2E, 0xFF2F, 0xFF30, 0xFF31, 0xFF32, 0xFF33, 0xFF34, 0xFF35, 0xFF36, 0xFF37, 0xFF38, 0xFF39, 0xFF3A, 0 };
int i;
static const WCHAR tbl_lower[] = { 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0xA1, 0x00A2, 0x00A3, 0x00A5, 0x00AC, 0x00AF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0x0FF, 0x101, 0x103, 0x105, 0x107, 0x109, 0x10B, 0x10D, 0x10F, 0x111, 0x113, 0x115, 0x117, 0x119, 0x11B, 0x11D, 0x11F, 0x121, 0x123, 0x125, 0x127, 0x129, 0x12B, 0x12D, 0x12F, 0x131, 0x133, 0x135, 0x137, 0x13A, 0x13C, 0x13E, 0x140, 0x142, 0x144, 0x146, 0x148, 0x14B, 0x14D, 0x14F, 0x151, 0x153, 0x155, 0x157, 0x159, 0x15B, 0x15D, 0x15F, 0x161, 0x163, 0x165, 0x167, 0x169, 0x16B, 0x16D, 0x16F, 0x171, 0x173, 0x175, 0x177, 0x17A, 0x17C, 0x17E, 0x192, 0x3B1, 0x3B2, 0x3B3, 0x3B4, 0x3B5, 0x3B6, 0x3B7, 0x3B8, 0x3B9, 0x3BA, 0x3BB, 0x3BC, 0x3BD, 0x3BE, 0x3BF, 0x3C0, 0x3C1, 0x3C3, 0x3C4, 0x3C5, 0x3C6, 0x3C7, 0x3C8, 0x3C9, 0x3CA, 0x430, 0x431, 0x432, 0x433, 0x434, 0x435, 0x436, 0x437, 0x438, 0x439, 0x43A, 0x43B, 0x43C, 0x43D, 0x43E, 0x43F, 0x440, 0x441, 0x442, 0x443, 0x444, 0x445, 0x446, 0x447, 0x448, 0x449, 0x44A, 0x44B, 0x44C, 0x44D, 0x44E, 0x44F, 0x451, 0x452, 0x453, 0x454, 0x455, 0x456, 0x457, 0x458, 0x459, 0x45A, 0x45B, 0x45C, 0x45E, 0x45F, 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177, 0x2178, 0x2179, 0x217A, 0x217B, 0x217C, 0x217D, 0x217E, 0x217F, 0xFF41, 0xFF42, 0xFF43, 0xFF44, 0xFF45, 0xFF46, 0xFF47, 0xFF48, 0xFF49, 0xFF4A, 0xFF4B, 0xFF4C, 0xFF4D, 0xFF4E, 0xFF4F, 0xFF50, 0xFF51, 0xFF52, 0xFF53, 0xFF54, 0xFF55, 0xFF56, 0xFF57, 0xFF58, 0xFF59, 0xFF5A, 0 };
static const WCHAR tbl_upper[] = { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x21, 0xFFE0, 0xFFE1, 0xFFE5, 0xFFE2, 0xFFE3, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0x178, 0x100, 0x102, 0x104, 0x106, 0x108, 0x10A, 0x10C, 0x10E, 0x110, 0x112, 0x114, 0x116, 0x118, 0x11A, 0x11C, 0x11E, 0x120, 0x122, 0x124, 0x126, 0x128, 0x12A, 0x12C, 0x12E, 0x130, 0x132, 0x134, 0x136, 0x139, 0x13B, 0x13D, 0x13F, 0x141, 0x143, 0x145, 0x147, 0x14A, 0x14C, 0x14E, 0x150, 0x152, 0x154, 0x156, 0x158, 0x15A, 0x15C, 0x15E, 0x160, 0x162, 0x164, 0x166, 0x168, 0x16A, 0x16C, 0x16E, 0x170, 0x172, 0x174, 0x176, 0x179, 0x17B, 0x17D, 0x191, 0x391, 0x392, 0x393, 0x394, 0x395, 0x396, 0x397, 0x398, 0x399, 0x39A, 0x39B, 0x39C, 0x39D, 0x39E, 0x39F, 0x3A0, 0x3A1, 0x3A3, 0x3A4, 0x3A5, 0x3A6, 0x3A7, 0x3A8, 0x3A9, 0x3AA, 0x410, 0x411, 0x412, 0x413, 0x414, 0x415, 0x416, 0x417, 0x418, 0x419, 0x41A, 0x41B, 0x41C, 0x41D, 0x41E, 0x41F, 0x420, 0x421, 0x422, 0x423, 0x424, 0x425, 0x426, 0x427, 0x428, 0x429, 0x42A, 0x42B, 0x42C, 0x42D, 0x42E, 0x42F, 0x401, 0x402, 0x403, 0x404, 0x405, 0x406, 0x407, 0x408, 0x409, 0x40A, 0x40B, 0x40C, 0x40E, 0x40F, 0x2160, 0x2161, 0x2162, 0x2163, 0x2164, 0x2165, 0x2166, 0x2167, 0x2168, 0x2169, 0x216A, 0x216B, 0x216C, 0x216D, 0x216E, 0x216F, 0xFF21, 0xFF22, 0xFF23, 0xFF24, 0xFF25, 0xFF26, 0xFF27, 0xFF28, 0xFF29, 0xFF2A, 0xFF2B, 0xFF2C, 0xFF2D, 0xFF2E, 0xFF2F, 0xFF30, 0xFF31, 0xFF32, 0xFF33, 0xFF34, 0xFF35, 0xFF36, 0xFF37, 0xFF38, 0xFF39, 0xFF3A, 0 };
int i;
for (i = 0; tbl_lower[i] && chr != tbl_lower[i]; i++) ;
for ( i = 0; tbl_lower[i] && chr != tbl_lower[i]; i++ ) ;
return tbl_lower[i] ? tbl_upper[i] : chr;
return tbl_lower[i] ? tbl_upper[i] : chr;
}

View File

@ -7,101 +7,116 @@
#include "bits.h"
#include "uart.h"
void clock_disconnect() {
disconnectPLL0();
disablePLL0();
void clock_disconnect()
{
disconnectPLL0();
disablePLL0();
}
void clock_init() {
void clock_init()
{
/* set flash access time to 6 clks (safe setting) */
setFlashAccessTime(6);
/* set flash access time to 6 clks (safe setting) */
setFlashAccessTime( 6 );
/* setup PLL0 for ~44100*256*8 Hz
Base clock: 12MHz
Multiplier: 429
Pre-Divisor: 19
Divisor: 6
(want: 90316800, get: 90315789.47)
-> DAC freq = 44099.5 Hz
-> FPGA freq = 11289473.7Hz
First, disable and disconnect PLL0.
*/
// clock_disconnect();
/* setup PLL0 for ~44100*256*8 Hz
Base clock: 12MHz
Multiplier: 429
Pre-Divisor: 19
Divisor: 6
(want: 90316800, get: 90315789.47)
-> DAC freq = 44099.5 Hz
-> FPGA freq = 11289473.7Hz
First, disable and disconnect PLL0.
*/
// clock_disconnect();
/* PLL is disabled and disconnected. setup PCLK NOW as it cannot be changed
reliably with PLL0 connected.
see:
http://ics.nxp.com/support/documents/microcontrollers/pdf/errata.lpc1754.pdf
*/
/* PLL is disabled and disconnected. setup PCLK NOW as it cannot be changed
reliably with PLL0 connected.
see:
http://ics.nxp.com/support/documents/microcontrollers/pdf/errata.lpc1754.pdf
*/
/* continue with PLL0 setup:
enable the xtal oscillator and wait for it to become stable
set the oscillator as clk source for PLL0
set PLL0 multiplier+predivider
enable PLL0
set CCLK divider
wait for PLL0 to lock
connect PLL0
done
*/
enableMainOsc();
setClkSrc(CLKSRC_MAINOSC);
setPLL0MultPrediv(12, 1);
enablePLL0();
setCCLKDiv(3);
connectPLL0();
/* continue with PLL0 setup:
enable the xtal oscillator and wait for it to become stable
set the oscillator as clk source for PLL0
set PLL0 multiplier+predivider
enable PLL0
set CCLK divider
wait for PLL0 to lock
connect PLL0
done
*/
enableMainOsc();
setClkSrc( CLKSRC_MAINOSC );
setPLL0MultPrediv( 12, 1 );
enablePLL0();
setCCLKDiv( 3 );
connectPLL0();
}
void setFlashAccessTime(uint8_t clocks) {
LPC_SC->FLASHCFG=FLASHTIM(clocks);
void setFlashAccessTime( uint8_t clocks )
{
LPC_SC->FLASHCFG = FLASHTIM( clocks );
}
void setPLL0MultPrediv(uint16_t mult, uint8_t prediv) {
LPC_SC->PLL0CFG=PLL_MULT(mult) | PLL_PREDIV(prediv);
PLL0feed();
void setPLL0MultPrediv( uint16_t mult, uint8_t prediv )
{
LPC_SC->PLL0CFG = PLL_MULT( mult ) | PLL_PREDIV( prediv );
PLL0feed();
}
void enablePLL0() {
LPC_SC->PLL0CON |= PLLE0;
PLL0feed();
void enablePLL0()
{
LPC_SC->PLL0CON |= PLLE0;
PLL0feed();
}
void disablePLL0() {
LPC_SC->PLL0CON &= ~PLLE0;
PLL0feed();
void disablePLL0()
{
LPC_SC->PLL0CON &= ~PLLE0;
PLL0feed();
}
void connectPLL0() {
while(!(LPC_SC->PLL0STAT&PLOCK0));
LPC_SC->PLL0CON |= PLLC0;
PLL0feed();
void connectPLL0()
{
while ( !( LPC_SC->PLL0STAT & PLOCK0 ) );
LPC_SC->PLL0CON |= PLLC0;
PLL0feed();
}
void disconnectPLL0() {
LPC_SC->PLL0CON &= ~PLLC0;
PLL0feed();
void disconnectPLL0()
{
LPC_SC->PLL0CON &= ~PLLC0;
PLL0feed();
}
void setCCLKDiv(uint8_t div) {
LPC_SC->CCLKCFG=CCLK_DIV(div);
void setCCLKDiv( uint8_t div )
{
LPC_SC->CCLKCFG = CCLK_DIV( div );
}
void enableMainOsc() {
LPC_SC->SCS=OSCEN;
while(!(LPC_SC->SCS&OSCSTAT));
void enableMainOsc()
{
LPC_SC->SCS = OSCEN;
while ( !( LPC_SC->SCS & OSCSTAT ) );
}
void disableMainOsc() {
LPC_SC->SCS=0;
void disableMainOsc()
{
LPC_SC->SCS = 0;
}
void PLL0feed() {
LPC_SC->PLL0FEED=0xaa;
LPC_SC->PLL0FEED=0x55;
void PLL0feed()
{
LPC_SC->PLL0FEED = 0xaa;
LPC_SC->PLL0FEED = 0x55;
}
void setClkSrc(uint8_t src) {
LPC_SC->CLKSRCSEL=src;
void setClkSrc( uint8_t src )
{
LPC_SC->CLKSRCSEL = src;
}

View File

@ -18,62 +18,62 @@
#define PCLK_CCLK2(x) (2<<(x))
/* shift values for use with PCLKSEL0 */
#define PCLK_WDT (0)
#define PCLK_TIMER0 (2)
#define PCLK_TIMER1 (4)
#define PCLK_UART0 (6)
#define PCLK_UART1 (8)
#define PCLK_PWM1 (12)
#define PCLK_I2C0 (14)
#define PCLK_SPI (16)
#define PCLK_SSP1 (20)
#define PCLK_DAC (22)
#define PCLK_ADC (24)
#define PCLK_CAN1 (26)
#define PCLK_CAN2 (28)
#define PCLK_ACF (30)
#define PCLK_WDT (0)
#define PCLK_TIMER0 (2)
#define PCLK_TIMER1 (4)
#define PCLK_UART0 (6)
#define PCLK_UART1 (8)
#define PCLK_PWM1 (12)
#define PCLK_I2C0 (14)
#define PCLK_SPI (16)
#define PCLK_SSP1 (20)
#define PCLK_DAC (22)
#define PCLK_ADC (24)
#define PCLK_CAN1 (26)
#define PCLK_CAN2 (28)
#define PCLK_ACF (30)
/* shift values for use with PCLKSEL1 */
#define PCLK_QEI (0)
#define PCLK_GPIOINT (2)
#define PCLK_PCB (4)
#define PCLK_I2C1 (6)
#define PCLK_SSP0 (10)
#define PCLK_TIMER2 (12)
#define PCLK_QEI (0)
#define PCLK_GPIOINT (2)
#define PCLK_PCB (4)
#define PCLK_I2C1 (6)
#define PCLK_SSP0 (10)
#define PCLK_TIMER2 (12)
#define PCLK_TIMER3 (14)
#define PCLK_UART2 (16)
#define PCLK_UART3 (18)
#define PCLK_I2C2 (20)
#define PCLK_I2S (22)
#define PCLK_RIT (26)
#define PCLK_SYSCON (28)
#define PCLK_MC (30)
#define PCLK_UART2 (16)
#define PCLK_UART3 (18)
#define PCLK_I2C2 (20)
#define PCLK_I2S (22)
#define PCLK_RIT (26)
#define PCLK_SYSCON (28)
#define PCLK_MC (30)
void clock_disconnect(void);
void clock_disconnect( void );
void clock_init(void);
void clock_init( void );
void setFlashAccessTime(uint8_t clocks);
void setFlashAccessTime( uint8_t clocks );
void setPLL0MultPrediv(uint16_t mult, uint8_t prediv);
void setPLL0MultPrediv( uint16_t mult, uint8_t prediv );
void enablePLL0(void);
void enablePLL0( void );
void disablePLL0(void);
void disablePLL0( void );
void connectPLL0(void);
void connectPLL0( void );
void disconnectPLL0(void);
void disconnectPLL0( void );
void setCCLKDiv(uint8_t div);
void setCCLKDiv( uint8_t div );
void enableMainOsc(void);
void enableMainOsc( void );
void disableMainOsc(void);
void disableMainOsc( void );
void PLL0feed(void);
void PLL0feed( void );
void setClkSrc(uint8_t src);
void setClkSrc( uint8_t src );
#endif

View File

@ -4,7 +4,7 @@
# file to a C header. No copyright claimed.
BEGIN {
print "// autoconf.h generated from " ARGV[1] " at " strftime() "\n" \
print "// autoconf.h generated from " ARGV[1] " at NOW\n" \
"#ifndef AUTOCONF_H\n" \
"#define AUTOCONF_H"
}

View File

@ -27,12 +27,12 @@
#define IN_AHBRAM __attribute__ ((section(".ahbram")))
#define SD_DT_INT_SETUP() do {\
BITBAND(LPC_GPIOINT->IO2IntEnR, SD_DT_BIT) = 1;\
BITBAND(LPC_GPIOINT->IO2IntEnF, SD_DT_BIT) = 1;\
} while(0)
BITBANG(LPC_GPIOINT->IO2IntEnR, SD_DT_BIT) = 1;\
BITBANG(LPC_GPIOINT->IO2IntEnF, SD_DT_BIT) = 1;\
} while(0)
#define SD_CHANGE_DETECT (BITBAND(LPC_GPIOINT->IO2IntStatR, SD_DT_BIT)\
|BITBAND(LPC_GPIOINT->IO2IntStatF, SD_DT_BIT))
#define SD_CHANGE_DETECT (BITBANG(LPC_GPIOINT->IO2IntStatR, SD_DT_BIT)\
|BITBANG(LPC_GPIOINT->IO2IntStatF, SD_DT_BIT))
#define SD_CHANGE_CLR() do {LPC_GPIOINT->IO2IntClr = BV(SD_DT_BIT);} while(0)
@ -41,15 +41,15 @@
#define SD_WP_REG LPC_GPIO0
#define SD_WP_BIT 6
#define SDCARD_DETECT (!(BITBAND(SD_DT_REG->FIOPIN, SD_DT_BIT)))
#define SDCARD_WP (BITBAND(SD_WP_REG->FIOPIN, SD_WP_BIT))
#define SDCARD_DETECT (!(BITBANG(SD_DT_REG->FIOPIN, SD_DT_BIT)))
#define SDCARD_WP (BITBANG(SD_WP_REG->FIOPIN, SD_WP_BIT))
#define SD_SUPPLY_VOLTAGE (1L<<21) /* 3.3V - 3.4V */
#define CONFIG_SD_BLOCKTRANSFER 1
#define CONFIG_SD_AUTO_RETRIES 10
// #define SD_CHANGE_VECT
#define CONFIG_SD_DATACRC 1
#define CONFIG_UART_NUM 3
#define CONFIG_UART_NUM 3
// #define CONFIG_CPU_FREQUENCY 90315789
#define CONFIG_CPU_FREQUENCY (96000000L)
//#define CONFIG_CPU_FREQUENCY 46000000

View File

@ -1,9 +1,9 @@
#ifndef CRC_H
#define CRC_H
uint8_t crc7update(uint8_t crc, uint8_t data);
uint16_t crc_xmodem_update(uint16_t crc, uint8_t data);
uint16_t crc_xmodem_block(uint16_t crc, const uint8_t *data, uint32_t length);
uint8_t crc7update( uint8_t crc, uint8_t data );
uint16_t crc_xmodem_update( uint16_t crc, uint8_t data );
uint16_t crc_xmodem_block( uint16_t crc, const uint8_t *data, uint32_t length );
// AVR-libc compatibility
#define _crc_xmodem_update(crc,data) crc_xmodem_update(crc,data)

View File

@ -26,17 +26,19 @@
* \param data_len The width of \a data expressed in number of bits.
* \return The reflected data.
******************************************************************************/
uint32_t crc_reflect(uint32_t data, size_t data_len)
uint32_t crc_reflect( uint32_t data, size_t data_len )
{
unsigned int i;
uint32_t ret;
ret = data & 0x01;
for (i = 1; i < data_len; i++)
for ( i = 1; i < data_len; i++ )
{
data >>= 1;
ret = (ret << 1) | (data & 0x01);
ret = ( ret << 1 ) | ( data & 0x01 );
}
return ret;
}
@ -49,23 +51,31 @@ uint32_t crc_reflect(uint32_t data, size_t data_len)
* \param data_len Number of bytes in the \a data buffer.
* \return The updated crc value.
*****************************************************************************/
uint32_t crc32_update(uint32_t crc, const unsigned char data)
uint32_t crc32_update( uint32_t crc, const unsigned char data )
{
unsigned int i;
uint32_t bit;
unsigned char c;
c = data;
for (i = 0x01; i & 0xff; i <<= 1) {
for ( i = 0x01; i & 0xff; i <<= 1 )
{
bit = crc & 0x80000000;
if (c & i) {
if ( c & i )
{
bit = !bit;
}
crc <<= 1;
if (bit) {
if ( bit )
{
crc ^= 0x04c11db7;
}
}
return crc & 0xffffffff;
}

View File

@ -42,14 +42,14 @@ extern "C" {
* \param data_len The width of \a data expressed in number of bits.
* \return The reflected data.
*****************************************************************************/
uint32_t crc_reflect(uint32_t data, size_t data_len);
uint32_t crc_reflect( uint32_t data, size_t data_len );
/**
* Calculate the initial crc value.
*
* \return The initial crc value.
*****************************************************************************/
static inline uint32_t crc_init(void)
static inline uint32_t crc_init( void )
{
return 0xffffffff;
}
@ -62,7 +62,7 @@ static inline uint32_t crc_init(void)
* \param data_len Number of bytes in the \a data buffer.
* \return The updated crc value.
*****************************************************************************/
uint32_t crc32_update(uint32_t crc, const unsigned char data);
uint32_t crc32_update( uint32_t crc, const unsigned char data );
/**
* Calculate the final crc value.
@ -70,9 +70,9 @@ uint32_t crc32_update(uint32_t crc, const unsigned char data);
* \param crc The current crc value.
* \return The final crc value.
*****************************************************************************/
static inline uint32_t crc_finalize(uint32_t crc)
static inline uint32_t crc_finalize( uint32_t crc )
{
return crc_reflect(crc, 32) ^ 0xffffffff;
return crc_reflect( crc, 32 ) ^ 0xffffffff;
}

View File

@ -4,8 +4,8 @@
#ifndef _DISKIO
#define _READONLY 0 /* 1: Remove write functions */
#define _USE_IOCTL 1 /* 1: Use disk_ioctl fucntion */
#define _READONLY 0 /* 1: Remove write functions */
#define _USE_IOCTL 1 /* 1: Use disk_ioctl fucntion */
#include <arm/NXP/LPC17xx/LPC17xx.h>
@ -13,15 +13,16 @@
/* Status of Disk Functions */
typedef BYTE DSTATUS;
typedef BYTE DSTATUS;
/* Results of Disk Functions */
typedef enum {
RES_OK = 0, /* 0: Successful */
RES_ERROR, /* 1: R/W Error */
RES_WRPRT, /* 2: Write Protected */
RES_NOTRDY, /* 3: Not Ready */
RES_PARERR /* 4: Invalid Parameter */
typedef enum
{
RES_OK = 0, /* 0: Successful */
RES_ERROR, /* 1: R/W Error */
RES_WRPRT, /* 2: Write Protected */
RES_NOTRDY, /* 3: Not Ready */
RES_PARERR /* 4: Invalid Parameter */
} DRESULT;
/**
@ -35,12 +36,13 @@ typedef enum {
* This is the struct returned in the data buffer when disk_getinfo
* is called with page=0.
*/
typedef struct {
uint8_t validbytes;
uint8_t maxpage;
uint8_t disktype;
uint8_t sectorsize; /* divided by 256 */
uint32_t sectorcount; /* 2 TB should be enough... (512 byte sectors) */
typedef struct
{
uint8_t validbytes;
uint8_t maxpage;
uint8_t disktype;
uint8_t sectorsize; /* divided by 256 */
uint32_t sectorcount; /* 2 TB should be enough... (512 byte sectors) */
} diskinfo0_t;
@ -48,17 +50,17 @@ typedef struct {
/*---------------------------------------*/
/* Prototypes for disk control functions */
int assign_drives (int, int);
DSTATUS disk_initialize (BYTE);
DSTATUS disk_status (BYTE);
DRESULT disk_read (BYTE, BYTE*, DWORD, BYTE);
#if _READONLY == 0
DRESULT disk_write (BYTE, const BYTE*, DWORD, BYTE);
int assign_drives ( int, int );
DSTATUS disk_initialize ( BYTE );
DSTATUS disk_status ( BYTE );
DRESULT disk_read ( BYTE, BYTE *, DWORD, BYTE );
#if _READONLY == 0
DRESULT disk_write ( BYTE, const BYTE *, DWORD, BYTE );
#endif
#define disk_ioctl(a,b,c) RES_OK
#define get_fattime() (0)
#define get_fattime() (0)
void disk_init(void);
void disk_init( void );
/* Will be set to DISK_ERROR if any access on the card fails */
enum diskstates { DISK_CHANGED = 0, DISK_REMOVED, DISK_OK, DISK_ERROR };
@ -80,39 +82,39 @@ extern volatile enum diskstates disk_state;
/* Disk Status Bits (DSTATUS) */
#define STA_NOINIT 0x01 /* Drive not initialized */
#define STA_NODISK 0x02 /* No medium in the drive */
#define STA_PROTECT 0x04 /* Write protected */
#define STA_NOINIT 0x01 /* Drive not initialized */
#define STA_NODISK 0x02 /* No medium in the drive */
#define STA_PROTECT 0x04 /* Write protected */
/* Command code for disk_ioctrl fucntion */
/* Generic command (defined for FatFs) */
#define CTRL_SYNC 0 /* Flush disk cache (for write functions) */
#define GET_SECTOR_COUNT 1 /* Get media size (for only f_mkfs()) */
#define GET_SECTOR_SIZE 2 /* Get sector size (for multiple sector size (_MAX_SS >= 1024)) */
#define GET_BLOCK_SIZE 3 /* Get erase block size (for only f_mkfs()) */
#define CTRL_ERASE_SECTOR 4 /* Force erased a block of sectors (for only _USE_ERASE) */
#define CTRL_SYNC 0 /* Flush disk cache (for write functions) */
#define GET_SECTOR_COUNT 1 /* Get media size (for only f_mkfs()) */
#define GET_SECTOR_SIZE 2 /* Get sector size (for multiple sector size (_MAX_SS >= 1024)) */
#define GET_BLOCK_SIZE 3 /* Get erase block size (for only f_mkfs()) */
#define CTRL_ERASE_SECTOR 4 /* Force erased a block of sectors (for only _USE_ERASE) */
/* Generic command */
#define CTRL_POWER 5 /* Get/Set power status */
#define CTRL_LOCK 6 /* Lock/Unlock media removal */
#define CTRL_EJECT 7 /* Eject media */
#define CTRL_POWER 5 /* Get/Set power status */
#define CTRL_LOCK 6 /* Lock/Unlock media removal */
#define CTRL_EJECT 7 /* Eject media */
/* MMC/SDC specific ioctl command */
#define MMC_GET_TYPE 10 /* Get card type */
#define MMC_GET_CSD 11 /* Get CSD */
#define MMC_GET_CID 12 /* Get CID */
#define MMC_GET_OCR 13 /* Get OCR */
#define MMC_GET_SDSTAT 14 /* Get SD status */
#define MMC_GET_TYPE 10 /* Get card type */
#define MMC_GET_CSD 11 /* Get CSD */
#define MMC_GET_CID 12 /* Get CID */
#define MMC_GET_OCR 13 /* Get OCR */
#define MMC_GET_SDSTAT 14 /* Get SD status */
/* ATA/CF specific ioctl command */
#define ATA_GET_REV 20 /* Get F/W revision */
#define ATA_GET_MODEL 21 /* Get model name */
#define ATA_GET_SN 22 /* Get serial number */
#define ATA_GET_REV 20 /* Get F/W revision */
#define ATA_GET_MODEL 21 /* Get model name */
#define ATA_GET_SN 22 /* Get serial number */
/* NAND specific ioctl command */
#define NAND_FORMAT 30 /* Create physical format */
#define NAND_FORMAT 30 /* Create physical format */
#define _DISKIO

View File

@ -2,21 +2,26 @@
#include "config.h"
#include "uart.h"
void HardFault_Handler(void) {
DBG_BL printf("HFSR: %lx\n", SCB->HFSR);
DBG_UART uart_putc('H');
while (1) ;
void HardFault_Handler( void )
{
DBG_BL printf( "HFSR: %lx\n", SCB->HFSR );
DBG_UART uart_putc( 'H' );
while ( 1 ) ;
}
void MemManage_Handler(void) {
DBG_BL printf("MemManage - CFSR: %lx; MMFAR: %lx\n", SCB->CFSR, SCB->MMFAR);
void MemManage_Handler( void )
{
DBG_BL printf( "MemManage - CFSR: %lx; MMFAR: %lx\n", SCB->CFSR, SCB->MMFAR );
}
void BusFault_Handler(void) {
DBG_BL printf("BusFault - CFSR: %lx; BFAR: %lx\n", SCB->CFSR, SCB->BFAR);
void BusFault_Handler( void )
{
DBG_BL printf( "BusFault - CFSR: %lx; BFAR: %lx\n", SCB->CFSR, SCB->BFAR );
}
void UsageFault_Handler(void) {
DBG_BL printf("UsageFault - CFSR: %lx; BFAR: %lx\n", SCB->CFSR, SCB->BFAR);
void UsageFault_Handler( void )
{
DBG_BL printf( "UsageFault - CFSR: %lx; BFAR: %lx\n", SCB->CFSR, SCB->BFAR );
}

File diff suppressed because it is too large Load Diff

View File

@ -15,14 +15,14 @@
/----------------------------------------------------------------------------*/
#ifndef _FATFS
#define _FATFS 8255 /* Revision ID */
#define _FATFS 8255 /* Revision ID */
#ifdef __cplusplus
extern "C" {
#endif
#include "integer.h" /* Basic integer types */
#include "ffconf.h" /* FatFs configuration options */
#include "integer.h" /* Basic integer types */
#include "ffconf.h" /* FatFs configuration options */
#if _FATFS != _FFCONF
#error Wrong configuration file (ffconf.h).
@ -31,191 +31,191 @@ extern "C" {
/* DBCS code ranges and SBCS extend char conversion table */
#if _CODE_PAGE == 932 /* Japanese Shift-JIS */
#define _DF1S 0x81 /* DBC 1st byte range 1 start */
#define _DF1E 0x9F /* DBC 1st byte range 1 end */
#define _DF2S 0xE0 /* DBC 1st byte range 2 start */
#define _DF2E 0xFC /* DBC 1st byte range 2 end */
#define _DS1S 0x40 /* DBC 2nd byte range 1 start */
#define _DS1E 0x7E /* DBC 2nd byte range 1 end */
#define _DS2S 0x80 /* DBC 2nd byte range 2 start */
#define _DS2E 0xFC /* DBC 2nd byte range 2 end */
#if _CODE_PAGE == 932 /* Japanese Shift-JIS */
#define _DF1S 0x81 /* DBC 1st byte range 1 start */
#define _DF1E 0x9F /* DBC 1st byte range 1 end */
#define _DF2S 0xE0 /* DBC 1st byte range 2 start */
#define _DF2E 0xFC /* DBC 1st byte range 2 end */
#define _DS1S 0x40 /* DBC 2nd byte range 1 start */
#define _DS1E 0x7E /* DBC 2nd byte range 1 end */
#define _DS2S 0x80 /* DBC 2nd byte range 2 start */
#define _DS2E 0xFC /* DBC 2nd byte range 2 end */
#elif _CODE_PAGE == 936 /* Simplified Chinese GBK */
#define _DF1S 0x81
#define _DF1E 0xFE
#define _DS1S 0x40
#define _DS1E 0x7E
#define _DS2S 0x80
#define _DS2E 0xFE
#elif _CODE_PAGE == 936 /* Simplified Chinese GBK */
#define _DF1S 0x81
#define _DF1E 0xFE
#define _DS1S 0x40
#define _DS1E 0x7E
#define _DS2S 0x80
#define _DS2E 0xFE
#elif _CODE_PAGE == 949 /* Korean */
#define _DF1S 0x81
#define _DF1E 0xFE
#define _DS1S 0x41
#define _DS1E 0x5A
#define _DS2S 0x61
#define _DS2E 0x7A
#define _DS3S 0x81
#define _DS3E 0xFE
#elif _CODE_PAGE == 949 /* Korean */
#define _DF1S 0x81
#define _DF1E 0xFE
#define _DS1S 0x41
#define _DS1E 0x5A
#define _DS2S 0x61
#define _DS2E 0x7A
#define _DS3S 0x81
#define _DS3E 0xFE
#elif _CODE_PAGE == 950 /* Traditional Chinese Big5 */
#define _DF1S 0x81
#define _DF1E 0xFE
#define _DS1S 0x40
#define _DS1E 0x7E
#define _DS2S 0xA1
#define _DS2E 0xFE
#elif _CODE_PAGE == 950 /* Traditional Chinese Big5 */
#define _DF1S 0x81
#define _DF1E 0xFE
#define _DS1S 0x40
#define _DS1E 0x7E
#define _DS2S 0xA1
#define _DS2E 0xFE
#elif _CODE_PAGE == 437 /* U.S. (OEM) */
#define _DF1S 0
#elif _CODE_PAGE == 437 /* U.S. (OEM) */
#define _DF1S 0
#define _EXCVT {0x80,0x9A,0x90,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x49,0x49,0x49,0x8E,0x8F,0x90,0x92,0x92,0x4F,0x99,0x4F,0x55,0x55,0x59,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
#elif _CODE_PAGE == 720 /* Arabic (OEM) */
#define _DF1S 0
#elif _CODE_PAGE == 720 /* Arabic (OEM) */
#define _DF1S 0
#define _EXCVT {0x80,0x81,0x45,0x41,0x84,0x41,0x86,0x43,0x45,0x45,0x45,0x49,0x49,0x8D,0x8E,0x8F,0x90,0x92,0x92,0x93,0x94,0x95,0x49,0x49,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
#elif _CODE_PAGE == 737 /* Greek (OEM) */
#define _DF1S 0
#elif _CODE_PAGE == 737 /* Greek (OEM) */
#define _DF1S 0
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x92,0x92,0x93,0x94,0x95,0x96,0x97,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87, \
0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0xAA,0x92,0x93,0x94,0x95,0x96,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0x97,0xEA,0xEB,0xEC,0xE4,0xED,0xEE,0xE7,0xE8,0xF1,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0xAA,0x92,0x93,0x94,0x95,0x96,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0x97,0xEA,0xEB,0xEC,0xE4,0xED,0xEE,0xE7,0xE8,0xF1,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
#elif _CODE_PAGE == 775 /* Baltic (OEM) */
#define _DF1S 0
#elif _CODE_PAGE == 775 /* Baltic (OEM) */
#define _DF1S 0
#define _EXCVT {0x80,0x9A,0x91,0xA0,0x8E,0x95,0x8F,0x80,0xAD,0xED,0x8A,0x8A,0xA1,0x8D,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0x95,0x96,0x97,0x97,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \
0xA0,0xA1,0xE0,0xA3,0xA3,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xB5,0xB6,0xB7,0xB8,0xBD,0xBE,0xC6,0xC7,0xA5,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE3,0xE8,0xE8,0xEA,0xEA,0xEE,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
0xA0,0xA1,0xE0,0xA3,0xA3,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xB5,0xB6,0xB7,0xB8,0xBD,0xBE,0xC6,0xC7,0xA5,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE3,0xE8,0xE8,0xEA,0xEA,0xEE,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
#elif _CODE_PAGE == 850 /* Multilingual Latin 1 (OEM) */
#define _DF1S 0
#elif _CODE_PAGE == 850 /* Multilingual Latin 1 (OEM) */
#define _DF1S 0
#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0xDE,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x59,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \
0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE7,0xE9,0xEA,0xEB,0xED,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE7,0xE9,0xEA,0xEB,0xED,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
#elif _CODE_PAGE == 852 /* Latin 2 (OEM) */
#define _DF1S 0
#elif _CODE_PAGE == 852 /* Latin 2 (OEM) */
#define _DF1S 0
#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xDE,0x8F,0x80,0x9D,0xD3,0x8A,0x8A,0xD7,0x8D,0x8E,0x8F,0x90,0x91,0x91,0xE2,0x99,0x95,0x95,0x97,0x97,0x99,0x9A,0x9B,0x9B,0x9D,0x9E,0x9F, \
0xB5,0xD6,0xE0,0xE9,0xA4,0xA4,0xA6,0xA6,0xA8,0xA8,0xAA,0x8D,0xAC,0xB8,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBD,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC6,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD2,0xD3,0xD2,0xD5,0xD6,0xD7,0xB7,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xE0,0xE1,0xE2,0xE3,0xE3,0xD5,0xE6,0xE6,0xE8,0xE9,0xE8,0xEB,0xED,0xED,0xDD,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xEB,0xFC,0xFC,0xFE,0xFF}
0xB5,0xD6,0xE0,0xE9,0xA4,0xA4,0xA6,0xA6,0xA8,0xA8,0xAA,0x8D,0xAC,0xB8,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBD,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC6,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD2,0xD3,0xD2,0xD5,0xD6,0xD7,0xB7,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xE0,0xE1,0xE2,0xE3,0xE3,0xD5,0xE6,0xE6,0xE8,0xE9,0xE8,0xEB,0xED,0xED,0xDD,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xEB,0xFC,0xFC,0xFE,0xFF}
#elif _CODE_PAGE == 855 /* Cyrillic (OEM) */
#define _DF1S 0
#elif _CODE_PAGE == 855 /* Cyrillic (OEM) */
#define _DF1S 0
#define _EXCVT {0x81,0x81,0x83,0x83,0x85,0x85,0x87,0x87,0x89,0x89,0x8B,0x8B,0x8D,0x8D,0x8F,0x8F,0x91,0x91,0x93,0x93,0x95,0x95,0x97,0x97,0x99,0x99,0x9B,0x9B,0x9D,0x9D,0x9F,0x9F, \
0xA1,0xA1,0xA3,0xA3,0xA5,0xA5,0xA7,0xA7,0xA9,0xA9,0xAB,0xAB,0xAD,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB6,0xB6,0xB8,0xB8,0xB9,0xBA,0xBB,0xBC,0xBE,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD3,0xD3,0xD5,0xD5,0xD7,0xD7,0xDD,0xD9,0xDA,0xDB,0xDC,0xDD,0xE0,0xDF, \
0xE0,0xE2,0xE2,0xE4,0xE4,0xE6,0xE6,0xE8,0xE8,0xEA,0xEA,0xEC,0xEC,0xEE,0xEE,0xEF,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF8,0xFA,0xFA,0xFC,0xFC,0xFD,0xFE,0xFF}
0xA1,0xA1,0xA3,0xA3,0xA5,0xA5,0xA7,0xA7,0xA9,0xA9,0xAB,0xAB,0xAD,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB6,0xB6,0xB8,0xB8,0xB9,0xBA,0xBB,0xBC,0xBE,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD3,0xD3,0xD5,0xD5,0xD7,0xD7,0xDD,0xD9,0xDA,0xDB,0xDC,0xDD,0xE0,0xDF, \
0xE0,0xE2,0xE2,0xE4,0xE4,0xE6,0xE6,0xE8,0xE8,0xEA,0xEA,0xEC,0xEC,0xEE,0xEE,0xEF,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF8,0xFA,0xFA,0xFC,0xFC,0xFD,0xFE,0xFF}
#elif _CODE_PAGE == 857 /* Turkish (OEM) */
#define _DF1S 0
#elif _CODE_PAGE == 857 /* Turkish (OEM) */
#define _DF1S 0
#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0x98,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x98,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9E, \
0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA6,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xDE,0x59,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA6,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xDE,0x59,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
#elif _CODE_PAGE == 858 /* Multilingual Latin 1 + Euro (OEM) */
#define _DF1S 0
#elif _CODE_PAGE == 858 /* Multilingual Latin 1 + Euro (OEM) */
#define _DF1S 0
#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0xDE,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x59,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \
0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE7,0xE9,0xEA,0xEB,0xED,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE7,0xE9,0xEA,0xEB,0xED,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
#elif _CODE_PAGE == 862 /* Hebrew (OEM) */
#define _DF1S 0
#elif _CODE_PAGE == 862 /* Hebrew (OEM) */
#define _DF1S 0
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
#elif _CODE_PAGE == 866 /* Russian (OEM) */
#define _DF1S 0
#elif _CODE_PAGE == 866 /* Russian (OEM) */
#define _DF1S 0
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0x90,0x91,0x92,0x93,0x9d,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,0xF0,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0x90,0x91,0x92,0x93,0x9d,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,0xF0,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
#elif _CODE_PAGE == 874 /* Thai (OEM, Windows) */
#define _DF1S 0
#elif _CODE_PAGE == 874 /* Thai (OEM, Windows) */
#define _DF1S 0
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
#elif _CODE_PAGE == 1250 /* Central Europe (Windows) */
#define _DF1S 0
#define _DF1S 0
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x8D,0x8E,0x8F, \
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xA3,0xB4,0xB5,0xB6,0xB7,0xB8,0xA5,0xAA,0xBB,0xBC,0xBD,0xBC,0xAF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF}
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xA3,0xB4,0xB5,0xB6,0xB7,0xB8,0xA5,0xAA,0xBB,0xBC,0xBD,0xBC,0xAF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF}
#elif _CODE_PAGE == 1251 /* Cyrillic (Windows) */
#define _DF1S 0
#define _DF1S 0
#define _EXCVT {0x80,0x81,0x82,0x82,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x80,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x8D,0x8E,0x8F, \
0xA0,0xA2,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB2,0xA5,0xB5,0xB6,0xB7,0xA8,0xB9,0xAA,0xBB,0xA3,0xBD,0xBD,0xAF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF}
0xA0,0xA2,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB2,0xA5,0xB5,0xB6,0xB7,0xA8,0xB9,0xAA,0xBB,0xA3,0xBD,0xBD,0xAF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF}
#elif _CODE_PAGE == 1252 /* Latin 1 (Windows) */
#define _DF1S 0
#define _DF1S 0
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0xAd,0x9B,0x8C,0x9D,0xAE,0x9F, \
0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x9F}
0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x9F}
#elif _CODE_PAGE == 1253 /* Greek (Windows) */
#define _DF1S 0
#define _DF1S 0
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xA2,0xB8,0xB9,0xBA, \
0xE0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xF2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xFB,0xBC,0xFD,0xBF,0xFF}
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xA2,0xB8,0xB9,0xBA, \
0xE0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xF2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xFB,0xBC,0xFD,0xBF,0xFF}
#elif _CODE_PAGE == 1254 /* Turkish (Windows) */
#define _DF1S 0
#define _DF1S 0
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x9D,0x9E,0x9F, \
0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x9F}
0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x9F}
#elif _CODE_PAGE == 1255 /* Hebrew (Windows) */
#define _DF1S 0
#define _DF1S 0
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
#elif _CODE_PAGE == 1256 /* Arabic (Windows) */
#define _DF1S 0
#define _DF1S 0
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x8C,0x9D,0x9E,0x9F, \
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0x41,0xE1,0x41,0xE3,0xE4,0xE5,0xE6,0x43,0x45,0x45,0x45,0x45,0xEC,0xED,0x49,0x49,0xF0,0xF1,0xF2,0xF3,0x4F,0xF5,0xF6,0xF7,0xF8,0x55,0xFA,0x55,0x55,0xFD,0xFE,0xFF}
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0x41,0xE1,0x41,0xE3,0xE4,0xE5,0xE6,0x43,0x45,0x45,0x45,0x45,0xEC,0xED,0x49,0x49,0xF0,0xF1,0xF2,0xF3,0x4F,0xF5,0xF6,0xF7,0xF8,0x55,0xFA,0x55,0x55,0xFD,0xFE,0xFF}
#elif _CODE_PAGE == 1257 /* Baltic (Windows) */
#define _DF1S 0
#define _DF1S 0
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xA8,0xB9,0xAA,0xBB,0xBC,0xBD,0xBE,0xAF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF}
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xA8,0xB9,0xAA,0xBB,0xBC,0xBD,0xBE,0xAF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF}
#elif _CODE_PAGE == 1258 /* Vietnam (OEM, Windows) */
#define _DF1S 0
#define _DF1S 0
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0xAC,0x9D,0x9E,0x9F, \
0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xEC,0xCD,0xCE,0xCF,0xD0,0xD1,0xF2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xFE,0x9F}
0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xEC,0xCD,0xCE,0xCF,0xD0,0xD1,0xF2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xFE,0x9F}
#elif _CODE_PAGE == 1 /* ASCII (for only non-LFN cfg) */
#define _DF1S 0
#elif _CODE_PAGE == 1 /* ASCII (for only non-LFN cfg) */
#define _DF1S 0
#else
#error Unknown code page
@ -226,18 +226,19 @@ extern "C" {
/* Definitions of volume management */
#if _MULTI_PARTITION /* Multiple partition configuration */
#define LD2PD(vol) (VolToPart[vol].pd) /* Get physical drive# */
#define LD2PT(vol) (VolToPart[vol].pt) /* Get partition# */
typedef struct {
BYTE pd; /* Physical drive# */
BYTE pt; /* Partition # (0-3) */
#if _MULTI_PARTITION /* Multiple partition configuration */
#define LD2PD(vol) (VolToPart[vol].pd) /* Get physical drive# */
#define LD2PT(vol) (VolToPart[vol].pt) /* Get partition# */
typedef struct
{
BYTE pd; /* Physical drive# */
BYTE pt; /* Partition # (0-3) */
} PARTITION;
extern const PARTITION VolToPart[]; /* Volume - Physical location resolution table */
extern const PARTITION VolToPart[]; /* Volume - Physical location resolution table */
#else /* Single partition configuration */
#define LD2PD(vol) (vol) /* Logical drive# is bound to the same physical drive# */
#define LD2PT(vol) 0 /* Always mounts the 1st partition */
#else /* Single partition configuration */
#define LD2PD(vol) (vol) /* Logical drive# is bound to the same physical drive# */
#define LD2PT(vol) 0 /* Always mounts the 1st partition */
#endif
@ -245,7 +246,7 @@ extern const PARTITION VolToPart[]; /* Volume - Physical location resolution tab
/* Type of path name strings on FatFs API */
#if _LFN_UNICODE /* Unicode string */
#if _LFN_UNICODE /* Unicode string */
#if !_USE_LFN
#error _LFN_UNICODE must be 0 in non-LFN cfg.
#endif
@ -255,7 +256,7 @@ typedef WCHAR TCHAR;
#define _TEXT(x) L ## x
#endif
#else /* ANSI/OEM string */
#else /* ANSI/OEM string */
#ifndef _INC_TCHAR
typedef char TCHAR;
#define _T(x) x
@ -268,64 +269,66 @@ typedef char TCHAR;
/* File system object structure (FATFS) */
typedef struct {
BYTE fs_type; /* FAT sub-type (0:Not mounted) */
BYTE drv; /* Physical drive number */
BYTE csize; /* Sectors per cluster (1,2,4...128) */
BYTE n_fats; /* Number of FAT copies (1,2) */
BYTE wflag; /* win[] dirty flag (1:must be written back) */
BYTE fsi_flag; /* fsinfo dirty flag (1:must be written back) */
WORD id; /* File system mount ID */
WORD n_rootdir; /* Number of root directory entries (FAT12/16) */
typedef struct
{
BYTE fs_type; /* FAT sub-type (0:Not mounted) */
BYTE drv; /* Physical drive number */
BYTE csize; /* Sectors per cluster (1,2,4...128) */
BYTE n_fats; /* Number of FAT copies (1,2) */
BYTE wflag; /* win[] dirty flag (1:must be written back) */
BYTE fsi_flag; /* fsinfo dirty flag (1:must be written back) */
WORD id; /* File system mount ID */
WORD n_rootdir; /* Number of root directory entries (FAT12/16) */
#if _MAX_SS != 512
WORD ssize; /* Bytes per sector (512,1024,2048,4096) */
WORD ssize; /* Bytes per sector (512,1024,2048,4096) */
#endif
#if _FS_REENTRANT
_SYNC_t sobj; /* Identifier of sync object */
_SYNC_t sobj; /* Identifier of sync object */
#endif
#if !_FS_READONLY
DWORD last_clust; /* Last allocated cluster */
DWORD free_clust; /* Number of free clusters */
DWORD fsi_sector; /* fsinfo sector (FAT32) */
DWORD last_clust; /* Last allocated cluster */
DWORD free_clust; /* Number of free clusters */
DWORD fsi_sector; /* fsinfo sector (FAT32) */
#endif
#if _FS_RPATH
DWORD cdir; /* Current directory start cluster (0:root) */
DWORD cdir; /* Current directory start cluster (0:root) */
#endif
DWORD n_fatent; /* Number of FAT entries (= number of clusters + 2) */
DWORD fsize; /* Sectors per FAT */
DWORD fatbase; /* FAT start sector */
DWORD dirbase; /* Root directory start sector (FAT32:Cluster#) */
DWORD database; /* Data start sector */
DWORD winsect; /* Current sector appearing in the win[] */
BYTE win[_MAX_SS]; /* Disk access window for Directory, FAT (and Data on tiny cfg) */
DWORD n_fatent; /* Number of FAT entries (= number of clusters + 2) */
DWORD fsize; /* Sectors per FAT */
DWORD fatbase; /* FAT start sector */
DWORD dirbase; /* Root directory start sector (FAT32:Cluster#) */
DWORD database; /* Data start sector */
DWORD winsect; /* Current sector appearing in the win[] */
BYTE win[_MAX_SS]; /* Disk access window for Directory, FAT (and Data on tiny cfg) */
} FATFS;
/* File object structure (FIL) */
typedef struct {
FATFS* fs; /* Pointer to the owner file system object */
WORD id; /* Owner file system mount ID */
BYTE flag; /* File status flags */
BYTE pad1;
DWORD fptr; /* File read/write pointer (0 on file open) */
DWORD fsize; /* File size */
DWORD org_clust; /* File start cluster (0 when fsize==0) */
DWORD curr_clust; /* Current cluster */
DWORD dsect; /* Current data sector */
typedef struct
{
FATFS *fs; /* Pointer to the owner file system object */
WORD id; /* Owner file system mount ID */
BYTE flag; /* File status flags */
BYTE pad1;
DWORD fptr; /* File read/write pointer (0 on file open) */
DWORD fsize; /* File size */
DWORD org_clust; /* File start cluster (0 when fsize==0) */
DWORD curr_clust; /* Current cluster */
DWORD dsect; /* Current data sector */
#if !_FS_READONLY
DWORD dir_sect; /* Sector containing the directory entry */
BYTE* dir_ptr; /* Ponter to the directory entry in the window */
DWORD dir_sect; /* Sector containing the directory entry */
BYTE *dir_ptr; /* Ponter to the directory entry in the window */
#endif
#if _USE_FASTSEEK
DWORD* cltbl; /* Pointer to the cluster link map table (null on file open) */
DWORD *cltbl; /* Pointer to the cluster link map table (null on file open) */
#endif
#if _FS_SHARE
UINT lockid; /* File lock ID (index of file semaphore table) */
UINT lockid; /* File lock ID (index of file semaphore table) */
#endif
#if !_FS_TINY
BYTE buf[_MAX_SS]; /* File data read/write buffer */
BYTE buf[_MAX_SS]; /* File data read/write buffer */
#endif
} FIL;
@ -333,18 +336,19 @@ typedef struct {
/* Directory object structure (DIR) */
typedef struct {
FATFS* fs; /* Pointer to the owner file system object */
WORD id; /* Owner file system mount ID */
WORD index; /* Current read/write index number */
DWORD sclust; /* Table start cluster (0:Root dir) */
DWORD clust; /* Current cluster */
DWORD sect; /* Current sector */
BYTE* dir; /* Pointer to the current SFN entry in the win[] */
BYTE* fn; /* Pointer to the SFN (in/out) {file[8],ext[3],status[1]} */
typedef struct
{
FATFS *fs; /* Pointer to the owner file system object */
WORD id; /* Owner file system mount ID */
WORD index; /* Current read/write index number */
DWORD sclust; /* Table start cluster (0:Root dir) */
DWORD clust; /* Current cluster */
DWORD sect; /* Current sector */
BYTE *dir; /* Pointer to the current SFN entry in the win[] */
BYTE *fn; /* Pointer to the SFN (in/out) {file[8],ext[3],status[1]} */
#if _USE_LFN
WCHAR* lfn; /* Pointer to the LFN working buffer */
WORD lfn_idx; /* Last matched LFN index number (0xFFFF:No LFN) */
WCHAR *lfn; /* Pointer to the LFN working buffer */
WORD lfn_idx; /* Last matched LFN index number (0xFFFF:No LFN) */
#endif
} DIR;
@ -352,16 +356,17 @@ typedef struct {
/* File status structure (FILINFO) */
typedef struct {
DWORD fsize; /* File size */
WORD fdate; /* Last modified date */
WORD ftime; /* Last modified time */
BYTE fattrib; /* Attribute */
TCHAR fname[13]; /* Short file name (8.3 format) */
DWORD clust; /* start cluster */
typedef struct
{
DWORD fsize; /* File size */
WORD fdate; /* Last modified date */
WORD ftime; /* Last modified time */
BYTE fattrib; /* Attribute */
TCHAR fname[13]; /* Short file name (8.3 format) */
DWORD clust; /* start cluster */
#if _USE_LFN
TCHAR* lfname; /* Pointer to the LFN buffer */
UINT lfsize; /* Size of LFN buffer in TCHAR */
TCHAR *lfname; /* Pointer to the LFN buffer */
UINT lfsize; /* Size of LFN buffer in TCHAR */
#endif
} FILINFO;
@ -369,26 +374,27 @@ typedef struct {
/* File function return code (FRESULT) */
typedef enum {
FR_OK = 0, /* (0) Succeeded */
FR_DISK_ERR, /* (1) A hard error occured in the low level disk I/O layer */
FR_INT_ERR, /* (2) Assertion failed */
FR_NOT_READY, /* (3) The physical drive cannot work */
FR_NO_FILE, /* (4) Could not find the file */
FR_NO_PATH, /* (5) Could not find the path */
FR_INVALID_NAME, /* (6) The path name format is invalid */
FR_DENIED, /* (7) Acces denied due to prohibited access or directory full */
FR_EXIST, /* (8) Acces denied due to prohibited access */
FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */
FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */
FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */
FR_NOT_ENABLED, /* (12) The volume has no work area */
FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume on the physical drive */
FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any parameter error */
FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */
FR_LOCKED, /* (16) The operation is rejected according to the file shareing policy */
FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */
FR_TOO_MANY_OPEN_FILES /* (18) Number of open files > _FS_SHARE */
typedef enum
{
FR_OK = 0, /* (0) Succeeded */
FR_DISK_ERR, /* (1) A hard error occured in the low level disk I/O layer */
FR_INT_ERR, /* (2) Assertion failed */
FR_NOT_READY, /* (3) The physical drive cannot work */
FR_NO_FILE, /* (4) Could not find the file */
FR_NO_PATH, /* (5) Could not find the path */
FR_INVALID_NAME, /* (6) The path name format is invalid */
FR_DENIED, /* (7) Acces denied due to prohibited access or directory full */
FR_EXIST, /* (8) Acces denied due to prohibited access */
FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */
FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */
FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */
FR_NOT_ENABLED, /* (12) The volume has no work area */
FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume on the physical drive */
FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any parameter error */
FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */
FR_LOCKED, /* (16) The operation is rejected according to the file shareing policy */
FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */
FR_TOO_MANY_OPEN_FILES /* (18) Number of open files > _FS_SHARE */
} FRESULT;
@ -397,49 +403,50 @@ typedef enum {
/* FatFs module application interface */
/* Low Level functions */
FRESULT l_openfilebycluster(FATFS *fs, FIL *fp, const TCHAR *path, DWORD clust, DWORD fsize); /* Open a file by its start cluster using supplied file size */
FRESULT l_openfilebycluster( FATFS *fs, FIL *fp, const TCHAR *path, DWORD clust,
DWORD fsize ); /* Open a file by its start cluster using supplied file size */
/* application level functions */
FRESULT f_mount (BYTE, FATFS*); /* Mount/Unmount a logical drive */
FRESULT f_open (FIL*, const TCHAR*, BYTE); /* Open or create a file */
FRESULT f_read (FIL*, void*, UINT, UINT*); /* Read data from a file */
FRESULT f_lseek (FIL*, DWORD); /* Move file pointer of a file object */
FRESULT f_close (FIL*); /* Close an open file object */
FRESULT f_opendir (DIR*, const TCHAR*); /* Open an existing directory */
FRESULT f_readdir (DIR*, FILINFO*); /* Read a directory item */
FRESULT f_stat (const TCHAR*, FILINFO*); /* Get file status */
FRESULT f_mount ( BYTE, FATFS * ); /* Mount/Unmount a logical drive */
FRESULT f_open ( FIL *, const TCHAR *, BYTE ); /* Open or create a file */
FRESULT f_read ( FIL *, void *, UINT, UINT * ); /* Read data from a file */
FRESULT f_lseek ( FIL *, DWORD ); /* Move file pointer of a file object */
FRESULT f_close ( FIL * ); /* Close an open file object */
FRESULT f_opendir ( DIR *, const TCHAR * ); /* Open an existing directory */
FRESULT f_readdir ( DIR *, FILINFO * ); /* Read a directory item */
FRESULT f_stat ( const TCHAR *, FILINFO * ); /* Get file status */
#if !_FS_READONLY
FRESULT f_write (FIL*, const void*, UINT, UINT*); /* Write data to a file */
FRESULT f_getfree (const TCHAR*, DWORD*, FATFS**); /* Get number of free clusters on the drive */
FRESULT f_truncate (FIL*); /* Truncate file */
FRESULT f_sync (FIL*); /* Flush cached data of a writing file */
FRESULT f_unlink (const TCHAR*); /* Delete an existing file or directory */
FRESULT f_mkdir (const TCHAR*); /* Create a new directory */
FRESULT f_chmod (const TCHAR*, BYTE, BYTE); /* Change attriburte of the file/dir */
FRESULT f_utime (const TCHAR*, const FILINFO*); /* Change timestamp of the file/dir */
FRESULT f_rename (const TCHAR*, const TCHAR*); /* Rename/Move a file or directory */
FRESULT f_write ( FIL *, const void *, UINT, UINT * ); /* Write data to a file */
FRESULT f_getfree ( const TCHAR *, DWORD *, FATFS ** ); /* Get number of free clusters on the drive */
FRESULT f_truncate ( FIL * ); /* Truncate file */
FRESULT f_sync ( FIL * ); /* Flush cached data of a writing file */
FRESULT f_unlink ( const TCHAR * ); /* Delete an existing file or directory */
FRESULT f_mkdir ( const TCHAR * ); /* Create a new directory */
FRESULT f_chmod ( const TCHAR *, BYTE, BYTE ); /* Change attriburte of the file/dir */
FRESULT f_utime ( const TCHAR *, const FILINFO * ); /* Change timestamp of the file/dir */
FRESULT f_rename ( const TCHAR *, const TCHAR * ); /* Rename/Move a file or directory */
#endif
#if _USE_FORWARD
FRESULT f_forward (FIL*, UINT(*)(const BYTE*,UINT), UINT, UINT*); /* Forward data to the stream */
FRESULT f_forward ( FIL *, UINT( * )( const BYTE *, UINT ), UINT, UINT * ); /* Forward data to the stream */
#endif
#if _USE_MKFS
FRESULT f_mkfs (BYTE, BYTE, UINT); /* Create a file system on the drive */
FRESULT f_mkfs ( BYTE, BYTE, UINT ); /* Create a file system on the drive */
#endif
#if _FS_RPATH
FRESULT f_chdrive (BYTE); /* Change current drive */
FRESULT f_chdir (const TCHAR*); /* Change current directory */
FRESULT f_getcwd (TCHAR*, UINT); /* Get current directory */
FRESULT f_chdrive ( BYTE ); /* Change current drive */
FRESULT f_chdir ( const TCHAR * ); /* Change current directory */
FRESULT f_getcwd ( TCHAR *, UINT ); /* Get current directory */
#endif
#if _USE_STRFUNC
int f_putc (TCHAR, FIL*); /* Put a character to the file */
int f_puts (const TCHAR*, FIL*); /* Put a string to the file */
int f_printf (FIL*, const TCHAR*, ...); /* Put a formatted string to the file */
TCHAR* f_gets (TCHAR*, int, FIL*); /* Get a string from the file */
int f_putc ( TCHAR, FIL * ); /* Put a character to the file */
int f_puts ( const TCHAR *, FIL * ); /* Put a string to the file */
int f_printf ( FIL *, const TCHAR *, ... ); /* Put a formatted string to the file */
TCHAR *f_gets ( TCHAR *, int, FIL * ); /* Get a string from the file */
#ifndef EOF
#define EOF (-1)
#endif
@ -457,25 +464,25 @@ TCHAR* f_gets (TCHAR*, int, FIL*); /* Get a string from the file */
/* RTC function */
#if !_FS_READONLY
DWORD get_fattime (void);
DWORD get_fattime ( void );
#endif
/* Unicode support functions */
#if _USE_LFN /* Unicode - OEM code conversion */
WCHAR ff_convert (WCHAR, UINT); /* OEM-Unicode bidirectional conversion */
WCHAR ff_wtoupper (WCHAR); /* Unicode upper-case conversion */
#if _USE_LFN == 3 /* Memory functions */
void* ff_memalloc (UINT); /* Allocate memory block */
void ff_memfree (void*); /* Free memory block */
#if _USE_LFN /* Unicode - OEM code conversion */
WCHAR ff_convert ( WCHAR, UINT ); /* OEM-Unicode bidirectional conversion */
WCHAR ff_wtoupper ( WCHAR ); /* Unicode upper-case conversion */
#if _USE_LFN == 3 /* Memory functions */
void *ff_memalloc ( UINT ); /* Allocate memory block */
void ff_memfree ( void * ); /* Free memory block */
#endif
#endif
/* Sync functions */
#if _FS_REENTRANT
int ff_cre_syncobj (BYTE, _SYNC_t*);/* Create a sync object */
int ff_del_syncobj (_SYNC_t); /* Delete a sync object */
int ff_req_grant (_SYNC_t); /* Lock sync object */
void ff_rel_grant (_SYNC_t); /* Unlock sync object */
int ff_cre_syncobj ( BYTE, _SYNC_t * ); /* Create a sync object */
int ff_del_syncobj ( _SYNC_t ); /* Delete a sync object */
int ff_req_grant ( _SYNC_t ); /* Lock sync object */
void ff_rel_grant ( _SYNC_t ); /* Unlock sync object */
#endif
@ -487,56 +494,56 @@ void ff_rel_grant (_SYNC_t); /* Unlock sync object */
/* File access control and file status flags (FIL.flag) */
#define FA_READ 0x01
#define FA_OPEN_EXISTING 0x00
#define FA__ERROR 0x80
#define FA_READ 0x01
#define FA_OPEN_EXISTING 0x00
#define FA__ERROR 0x80
#if !_FS_READONLY
#define FA_WRITE 0x02
#define FA_CREATE_NEW 0x04
#define FA_CREATE_ALWAYS 0x08
#define FA_OPEN_ALWAYS 0x10
#define FA__WRITTEN 0x20
#define FA__DIRTY 0x40
#define FA_WRITE 0x02
#define FA_CREATE_NEW 0x04
#define FA_CREATE_ALWAYS 0x08
#define FA_OPEN_ALWAYS 0x10
#define FA__WRITTEN 0x20
#define FA__DIRTY 0x40
#endif
/* FAT sub type (FATFS.fs_type) */
#define FS_FAT12 1
#define FS_FAT16 2
#define FS_FAT32 3
#define FS_FAT12 1
#define FS_FAT16 2
#define FS_FAT32 3
/* File attribute bits for directory entry */
#define AM_RDO 0x01 /* Read only */
#define AM_HID 0x02 /* Hidden */
#define AM_SYS 0x04 /* System */
#define AM_VOL 0x08 /* Volume label */
#define AM_LFN 0x0F /* LFN entry */
#define AM_DIR 0x10 /* Directory */
#define AM_ARC 0x20 /* Archive */
#define AM_MASK 0x3F /* Mask of defined bits */
#define AM_RDO 0x01 /* Read only */
#define AM_HID 0x02 /* Hidden */
#define AM_SYS 0x04 /* System */
#define AM_VOL 0x08 /* Volume label */
#define AM_LFN 0x0F /* LFN entry */
#define AM_DIR 0x10 /* Directory */
#define AM_ARC 0x20 /* Archive */
#define AM_MASK 0x3F /* Mask of defined bits */
/* Fast seek function */
#define CREATE_LINKMAP 0xFFFFFFFF
#define CREATE_LINKMAP 0xFFFFFFFF
/*--------------------------------*/
/* Multi-byte word access macros */
#if _WORD_ACCESS == 1 /* Enable word access to the FAT structure */
#define LD_WORD(ptr) (WORD)(*(WORD*)(BYTE*)(ptr))
#define LD_DWORD(ptr) (DWORD)(*(DWORD*)(BYTE*)(ptr))
#define ST_WORD(ptr,val) *(WORD*)(BYTE*)(ptr)=(WORD)(val)
#define ST_DWORD(ptr,val) *(DWORD*)(BYTE*)(ptr)=(DWORD)(val)
#else /* Use byte-by-byte access to the FAT structure */
#define LD_WORD(ptr) (WORD)(((WORD)*(BYTE*)((ptr)+1)<<8)|(WORD)*(BYTE*)(ptr))
#define LD_DWORD(ptr) (DWORD)(((DWORD)*(BYTE*)((ptr)+3)<<24)|((DWORD)*(BYTE*)((ptr)+2)<<16)|((WORD)*(BYTE*)((ptr)+1)<<8)|*(BYTE*)(ptr))
#define ST_WORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *(BYTE*)((ptr)+1)=(BYTE)((WORD)(val)>>8)
#define ST_DWORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *(BYTE*)((ptr)+1)=(BYTE)((WORD)(val)>>8); *(BYTE*)((ptr)+2)=(BYTE)((DWORD)(val)>>16); *(BYTE*)((ptr)+3)=(BYTE)((DWORD)(val)>>24)
#if _WORD_ACCESS == 1 /* Enable word access to the FAT structure */
#define LD_WORD(ptr) (WORD)(*(WORD*)(BYTE*)(ptr))
#define LD_DWORD(ptr) (DWORD)(*(DWORD*)(BYTE*)(ptr))
#define ST_WORD(ptr,val) *(WORD*)(BYTE*)(ptr)=(WORD)(val)
#define ST_DWORD(ptr,val) *(DWORD*)(BYTE*)(ptr)=(DWORD)(val)
#else /* Use byte-by-byte access to the FAT structure */
#define LD_WORD(ptr) (WORD)(((WORD)*(BYTE*)((ptr)+1)<<8)|(WORD)*(BYTE*)(ptr))
#define LD_DWORD(ptr) (DWORD)(((DWORD)*(BYTE*)((ptr)+3)<<24)|((DWORD)*(BYTE*)((ptr)+2)<<16)|((WORD)*(BYTE*)((ptr)+1)<<8)|*(BYTE*)(ptr))
#define ST_WORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *(BYTE*)((ptr)+1)=(BYTE)((WORD)(val)>>8)
#define ST_DWORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *(BYTE*)((ptr)+1)=(BYTE)((WORD)(val)>>8); *(BYTE*)((ptr)+2)=(BYTE)((DWORD)(val)>>16); *(BYTE*)((ptr)+3)=(BYTE)((DWORD)(val)>>24)
#endif
#ifdef __cplusplus

View File

@ -7,26 +7,26 @@
/
/----------------------------------------------------------------------------*/
#ifndef _FFCONF
#define _FFCONF 8255 /* Revision ID */
#define _FFCONF 8255 /* Revision ID */
/*---------------------------------------------------------------------------/
/ Function and Buffer Configurations
/----------------------------------------------------------------------------*/
#define _FS_TINY 1 /* 0:Normal or 1:Tiny */
#define _FS_TINY 1 /* 0:Normal or 1:Tiny */
/* When _FS_TINY is set to 1, FatFs uses the sector buffer in the file system
/ object instead of the sector buffer in the individual file object for file
/ data transfer. This reduces memory consumption 512 bytes each file object. */
#define _FS_READONLY 1 /* 0:Read/Write or 1:Read only */
#define _FS_READONLY 1 /* 0:Read/Write or 1:Read only */
/* Setting _FS_READONLY to 1 defines read only configuration. This removes
/ writing functions, f_write, f_sync, f_unlink, f_mkdir, f_chmod, f_rename,
/ f_truncate and useless f_getfree. */
#define _FS_MINIMIZE 3 /* 0 to 3 */
#define _FS_MINIMIZE 3 /* 0 to 3 */
/* The _FS_MINIMIZE option defines minimization level to remove some functions.
/
/ 0: Full function.
@ -36,19 +36,19 @@
/ 3: f_lseek is removed in addition to 2. */
#define _USE_STRFUNC 0 /* 0:Disable or 1/2:Enable */
#define _USE_STRFUNC 0 /* 0:Disable or 1/2:Enable */
/* To enable string functions, set _USE_STRFUNC to 1 or 2. */
#define _USE_MKFS 0 /* 0:Disable or 1:Enable */
#define _USE_MKFS 0 /* 0:Disable or 1:Enable */
/* To enable f_mkfs function, set _USE_MKFS to 1 and set _FS_READONLY to 0 */
#define _USE_FORWARD 0 /* 0:Disable or 1:Enable */
#define _USE_FORWARD 0 /* 0:Disable or 1:Enable */
/* To enable f_forward function, set _USE_FORWARD to 1 and set _FS_TINY to 1. */
#define _USE_FASTSEEK 0 /* 0:Disable or 1:Enable */
#define _USE_FASTSEEK 0 /* 0:Disable or 1:Enable */
/* To enable fast seek feature, set _USE_FASTSEEK to 1. */
@ -57,7 +57,7 @@
/ Locale and Namespace Configurations
/----------------------------------------------------------------------------*/
#define _CODE_PAGE 1
#define _CODE_PAGE 1
/* The _CODE_PAGE specifies the OEM code page to be used on the target system.
/ Incorrect setting of the code page can cause a file open failure.
/
@ -86,12 +86,12 @@
/ 857 - Turkish (OEM)
/ 862 - Hebrew (OEM)
/ 874 - Thai (OEM, Windows)
/ 1 - ASCII only (Valid for non LFN cfg.)
/ 1 - ASCII only (Valid for non LFN cfg.)
*/
#define _USE_LFN 0 /* 0 to 3 */
#define _MAX_LFN 255 /* Maximum LFN length to handle (12 to 255) */
#define _USE_LFN 0 /* 0 to 3 */
#define _MAX_LFN 255 /* Maximum LFN length to handle (12 to 255) */
/* The _USE_LFN option switches the LFN support.
/
/ 0: Disable LFN feature. _MAX_LFN and _LFN_UNICODE have no effect.
@ -105,12 +105,12 @@
/ ff_memalloc() and ff_memfree() must be added to the project. */
#define _LFN_UNICODE 0 /* 0:ANSI/OEM or 1:Unicode */
#define _LFN_UNICODE 0 /* 0:ANSI/OEM or 1:Unicode */
/* To switch the character code set on FatFs API to Unicode,
/ enable LFN feature and set _LFN_UNICODE to 1. */
#define _FS_RPATH 0 /* 0 to 2 */
#define _FS_RPATH 0 /* 0 to 2 */
/* The _FS_RPATH option configures relative path feature.
/
/ 0: Disable relative path feature and remove related functions.
@ -125,11 +125,11 @@
/ Physical Drive Configurations
/----------------------------------------------------------------------------*/
#define _VOLUMES 1
#define _VOLUMES 1
/* Number of volumes (logical drives) to be used. */
#define _MAX_SS 512 /* 512, 1024, 2048 or 4096 */
#define _MAX_SS 512 /* 512, 1024, 2048 or 4096 */
/* Maximum sector size to be handled.
/ Always set 512 for memory card and hard disk but a larger value may be
/ required for floppy disk (512/1024) and optical disk (512/2048).
@ -137,13 +137,13 @@
/ to the disk_ioctl function. */
#define _MULTI_PARTITION 0 /* 0:Single partition or 1:Multiple partition */
#define _MULTI_PARTITION 0 /* 0:Single partition or 1:Multiple partition */
/* When set to 0, each volume is bound to the same physical drive number and
/ it can mount only first primaly partition. When it is set to 1, each volume
/ is tied to the partitions listed in VolToPart[]. */
#define _USE_ERASE 0 /* 0:Disable or 1:Enable */
#define _USE_ERASE 0 /* 0:Disable or 1:Enable */
/* To enable sector erase feature, set _USE_ERASE to 1. */
@ -152,7 +152,7 @@
/ System Configurations
/----------------------------------------------------------------------------*/
#define _WORD_ACCESS 0 /* 0 or 1 */
#define _WORD_ACCESS 0 /* 0 or 1 */
/* Set 0 first and it is always compatible with all platforms. The _WORD_ACCESS
/ option defines which access method is used to the word data on the FAT volume.
/
@ -168,9 +168,9 @@
/* Include a header file here to define sync object types on the O/S */
/* #include <windows.h>, <ucos_ii.h.h>, <semphr.h> or ohters. */
#define _FS_REENTRANT 0 /* 0:Disable or 1:Enable */
#define _FS_TIMEOUT 1000 /* Timeout period in unit of time ticks */
#define _SYNC_t HANDLE /* O/S dependent type of sync object. e.g. HANDLE, OS_EVENT*, ID and etc.. */
#define _FS_REENTRANT 0 /* 0:Disable or 1:Enable */
#define _FS_TIMEOUT 1000 /* Timeout period in unit of time ticks */
#define _SYNC_t HANDLE /* O/S dependent type of sync object. e.g. HANDLE, OS_EVENT*, ID and etc.. */
/* The _FS_REENTRANT option switches the reentrancy of the FatFs module.
/
@ -180,7 +180,7 @@
/ function must be added to the project. */
#define _FS_SHARE 0 /* 0:Disable or >=1:Enable */
#define _FS_SHARE 0 /* 0:Disable or >=1:Enable */
/* To enable file shareing feature, set _FS_SHARE to 1 or greater. The value
defines how many files can be opened simultaneously. */

View File

@ -12,39 +12,47 @@ WCHAR ff_convert(WCHAR w, UINT dir) {
int newcard;
void file_init() {
file_res=f_mount(0, &fatfs);
newcard = 0;
void file_init()
{
file_res = f_mount( 0, &fatfs );
newcard = 0;
}
void file_reinit(void) {
disk_init();
file_init();
void file_reinit( void )
{
disk_init();
file_init();
}
void file_open_by_filinfo(FILINFO* fno) {
file_res = l_openfilebycluster(&fatfs, &file_handle, (TCHAR*)"", fno->clust, fno->fsize);
void file_open_by_filinfo( FILINFO *fno )
{
file_res = l_openfilebycluster( &fatfs, &file_handle, ( TCHAR * )"", fno->clust, fno->fsize );
}
void file_open(uint8_t* filename, BYTE flags) {
if (disk_state == DISK_CHANGED) {
file_reinit();
newcard = 1;
}
file_res = f_open(&file_handle, (TCHAR*)filename, flags);
file_block_off = sizeof(file_buf);
file_block_max = sizeof(file_buf);
file_status = file_res ? FILE_ERR : FILE_OK;
void file_open( uint8_t *filename, BYTE flags )
{
if ( disk_state == DISK_CHANGED )
{
file_reinit();
newcard = 1;
}
file_res = f_open( &file_handle, ( TCHAR * )filename, flags );
file_block_off = sizeof( file_buf );
file_block_max = sizeof( file_buf );
file_status = file_res ? FILE_ERR : FILE_OK;
}
void file_close() {
file_res = f_close(&file_handle);
void file_close()
{
file_res = f_close( &file_handle );
}
UINT file_read() {
UINT bytes_read;
file_res = f_read(&file_handle, file_buf, sizeof(file_buf), &bytes_read);
return bytes_read;
UINT file_read()
{
UINT bytes_read;
file_res = f_read( &file_handle, file_buf, sizeof( file_buf ), &bytes_read );
return bytes_read;
}
/*UINT file_write() {
@ -56,14 +64,18 @@ UINT file_read() {
return bytes_written;
}*/
UINT file_readblock(void* buf, uint32_t addr, uint16_t size) {
UINT bytes_read;
file_res = f_lseek(&file_handle, addr);
if(file_handle.fptr != addr) {
return 0;
}
file_res = f_read(&file_handle, buf, size, &bytes_read);
return bytes_read;
UINT file_readblock( void *buf, uint32_t addr, uint16_t size )
{
UINT bytes_read;
file_res = f_lseek( &file_handle, addr );
if ( file_handle.fptr != addr )
{
return 0;
}
file_res = f_read( &file_handle, buf, size, &bytes_read );
return bytes_read;
}
/*UINT file_writeblock(void* buf, uint32_t addr, uint16_t size) {
@ -74,11 +86,19 @@ UINT file_readblock(void* buf, uint32_t addr, uint16_t size) {
return bytes_written;
}*/
uint8_t file_getc() {
if(file_block_off == file_block_max) {
file_block_max = file_read();
if(file_block_max == 0) file_status = FILE_EOF;
file_block_off = 0;
}
return file_buf[file_block_off++];
uint8_t file_getc()
{
if ( file_block_off == file_block_max )
{
file_block_max = file_read();
if ( file_block_max == 0 )
{
file_status = FILE_EOF;
}
file_block_off = 0;
}
return file_buf[file_block_off++];
}

View File

@ -29,24 +29,25 @@
#include <arm/NXP/LPC17xx/LPC17xx.h>
#include "ff.h"
enum filestates { FILE_OK=0, FILE_ERR, FILE_EOF };
enum filestates { FILE_OK = 0, FILE_ERR, FILE_EOF };
BYTE file_buf[512] __attribute__((aligned(4)));
FATFS fatfs;
FIL file_handle;
FRESULT file_res;
uint8_t file_lfn[258];
uint16_t file_block_off, file_block_max;
enum filestates file_status;
#define GCC_ALIGN_WORKAROUND __attribute__ ((aligned(4)))
extern BYTE file_buf[512];
extern FATFS fatfs;
extern FIL file_handle;
extern FRESULT file_res;
extern uint8_t file_lfn[258];
extern uint16_t file_block_off, file_block_max;
extern enum filestates file_status;
void file_init(void);
void file_open(uint8_t* filename, BYTE flags);
void file_open_by_filinfo(FILINFO* fno);
void file_close(void);
UINT file_read(void);
UINT file_write(void);
UINT file_readblock(void* buf, uint32_t addr, uint16_t size);
UINT file_writeblock(void* buf, uint32_t addr, uint16_t size);
void file_init( void );
void file_open( uint8_t *filename, BYTE flags );
void file_open_by_filinfo( FILINFO *fno );
void file_close( void );
UINT file_read( void );
UINT file_write( void );
UINT file_readblock( void *buf, uint32_t addr, uint16_t size );
UINT file_writeblock( void *buf, uint32_t addr, uint16_t size );
uint8_t file_getc(void);
uint8_t file_getc( void );
#endif

View File

@ -12,197 +12,284 @@ uint32_t iap_cmd[5];
uint32_t iap_res[5];
uint32_t flash_sig[4];
IAP iap_entry = (IAP) IAP_LOCATION;
IAP iap_entry = ( IAP ) IAP_LOCATION;
uint32_t calc_flash_crc(uint32_t start, uint32_t len) {
DBG_BL printf("calc_flash_crc(%08lx, %08lx) {\n", start, len);
uint32_t end = start + len;
if(end > 0x20000) {
len = 0x1ffff - start;
end = 0x20000;
}
uint32_t crc = 0xffffffff;
uint32_t s = start;
while(s < end) {
crc = crc32_update(crc, *(const unsigned char*)(s));
s++;
}
crc = crc_finalize(crc);
DBG_BL printf(" crc generated. result=%08lx\n", crc);
DBG_BL printf("} //calc_flash_crc\n");
return crc;
}
uint32_t calc_flash_crc( uint32_t start, uint32_t len )
{
DBG_BL printf( "calc_flash_crc(%08lx, %08lx) {\n", start, len );
uint32_t end = start + len;
void test_iap() {
iap_cmd[0]=54;
iap_entry(iap_cmd, iap_res);
DBG_BL printf("Part ID=%08lx\n", iap_res[1]);
}
void print_header(sd2snes_fw_header *header) {
DBG_BL printf(" magic = %08lx\n version = %08lx\n size = %08lx\n crc = %08lx\n ~crc = %08lx\n",
header->magic, header->version, header->size,
header->crc, header->crcc);
}
int check_header(sd2snes_fw_header *header, uint32_t crc) {
if((header->magic != FW_MAGIC)
|| (header->size < 0x200)
|| (header->size > (0x1ffff - FW_START))
|| ((header->crc ^ header->crcc) != 0xffffffff)) {
return ERR_FLASHHD;
}
if(header->crc != crc) {
return ERR_FLASHCRC;
}
return ERR_OK;
}
FLASH_RES check_flash() {
sd2snes_fw_header *fw_header = (sd2snes_fw_header*) FW_START;
uint32_t flash_addr = FW_START;
if(flash_addr != FW_START) {
DBG_BL printf("address sanity check failed. expected 0x%08lx, got 0x%08lx.\nSomething is terribly wrong.\nBailing out to avoid bootldr self-corruption.\n", FW_START, flash_addr);
return ERR_HW;
}
DBG_BL printf("Current flash contents:\n");
DBG_BL print_header(fw_header);
uint32_t crc = calc_flash_crc(flash_addr + 0x100, (fw_header->size & 0x1ffff));
return check_header(fw_header, crc);
}
IAP_RES iap_wrap(uint32_t *iap_cmd, uint32_t *iap_res) {
// NVIC_DisableIRQ(RIT_IRQn);
// NVIC_DisableIRQ(UART_IRQ);
for(volatile int i=0; i<2048; i++);
iap_entry(iap_cmd, iap_res);
for(volatile int i=0; i<2048; i++);
// NVIC_EnableIRQ(UART_IRQ);
return iap_res[0];
}
IAP_RES iap_prepare_for_write(uint32_t start, uint32_t end) {
if(start < (FW_START / 0x1000)) return INVALID_SECTOR;
iap_cmd[0] = 50;
iap_cmd[1] = start;
iap_cmd[2] = end;
iap_wrap(iap_cmd, iap_res);
return iap_res[0];
}
IAP_RES iap_erase(uint32_t start, uint32_t end) {
if(start < (FW_START / 0x1000)) return INVALID_SECTOR;
iap_cmd[0] = 52;
iap_cmd[1] = start;
iap_cmd[2] = end;
iap_cmd[3] = CONFIG_CPU_FREQUENCY / 1000L;
iap_wrap(iap_cmd, iap_res);
return iap_res[0];
}
IAP_RES iap_ram2flash(uint32_t tgt, uint8_t *src, int num) {
iap_cmd[0] = 51;
iap_cmd[1] = tgt;
iap_cmd[2] = (uint32_t)src;
iap_cmd[3] = num;
iap_cmd[4] = CONFIG_CPU_FREQUENCY / 1000L;
iap_wrap(iap_cmd, iap_res);
return iap_res[0];
}
FLASH_RES flash_file(uint8_t *filename) {
sd2snes_fw_header *fw_header = (sd2snes_fw_header*) FW_START;
uint32_t flash_addr = FW_START;
uint32_t file_crc = 0xffffffff;
uint16_t count;
sd2snes_fw_header file_header;
UINT bytes_read;
if(flash_addr != FW_START) {
DBG_BL printf("address sanity check failed. expected 0x%08lx, got 0x%08lx.\nSomething is terribly wrong.\nBailing out to avoid bootldr self-corruption.\n", FW_START, flash_addr);
return ERR_HW;
}
file_open(filename, FA_READ);
if(file_res) {
DBG_BL printf("file_open: error %d\n", file_res);
return ERR_FS;
}
DBG_BL printf("firmware image found. file size: %ld\n", file_handle.fsize);
DBG_BL printf("reading header...\n");
f_read(&file_handle, &file_header, 32, &bytes_read);
DBG_BL print_header(&file_header);
if(check_flash() || file_header.version != fw_header->version || file_header.version == FW_MAGIC || fw_header->version == FW_MAGIC) {
DBG_UART uart_putc('F');
f_read(&file_handle, file_buf, 0xe0, &bytes_read);
for(;;) {
bytes_read = file_read();
if(file_res || !bytes_read) break;
for(count = 0; count < bytes_read; count++) {
file_crc = crc32_update(file_crc, file_buf[count]);
}
}
file_crc = crc_finalize(file_crc);
DBG_BL printf("file crc=%08lx\n", file_crc);
if(check_header(&file_header, file_header.crc) != ERR_OK) {
DBG_BL printf("Invalid firmware file (header corrupted).\n");
return ERR_FILEHD;
}
if(file_header.crc != file_crc) {
DBG_BL printf("Firmware file checksum error.\n");
return ERR_FILECHK;
if ( end > 0x20000 )
{
len = 0x1ffff - start;
end = 0x20000;
}
uint32_t res;
uint32_t crc = 0xffffffff;
uint32_t s = start;
writeled(1);
DBG_BL printf("erasing flash...\n");
DBG_UART uart_putc('P');
if((res = iap_prepare_for_write(FW_START / 0x1000, FLASH_SECTORS)) != CMD_SUCCESS) {
DBG_BL printf("error %ld while preparing for erase\n", res);
DBG_UART uart_putc('X');
return ERR_FLASHPREP;
};
DBG_UART uart_putc('E');
if((res = iap_erase(FW_START / 0x1000, FLASH_SECTORS)) != CMD_SUCCESS) {
DBG_BL printf("error %ld while erasing\n", res);
DBG_UART uart_putc('X');
return ERR_FLASHERASE;
while ( s < end )
{
crc = crc32_update( crc, *( const unsigned char * )( s ) );
s++;
}
DBG_BL printf("writing... @%08lx\n", flash_addr);
file_close();
file_open(filename, FA_READ);
uint8_t current_sec;
uint32_t total_read = 0;
for(flash_addr = FW_START; flash_addr < 0x00020000; flash_addr += 0x200) {
total_read += (bytes_read = file_read());
if(file_res || !bytes_read) break;
current_sec = flash_addr & 0x10000 ? (16 + ((flash_addr >> 15) & 1))
: (flash_addr >> 12);
DBG_BL printf("current_sec=%d flash_addr=%08lx\n", current_sec, flash_addr);
DBG_UART uart_putc('.');
if(current_sec < (FW_START / 0x1000)) return ERR_FLASH;
DBG_UART uart_putc(current_sec["0123456789ABCDEFGH"]);
DBG_UART uart_putc('p');
if((res = iap_prepare_for_write(current_sec, current_sec)) != CMD_SUCCESS) {
DBG_BL printf("error %ld while preparing sector %d for write\n", res, current_sec);
DBG_UART uart_putc('X');
return ERR_FLASH;
}
DBG_UART uart_putc('w');
if((res = iap_ram2flash(flash_addr, file_buf, 512)) != CMD_SUCCESS) {
DBG_BL printf("error %ld while writing from %08lX to address %08lx (sector %d)\n", res, (uint32_t)file_buf, flash_addr, current_sec);
DBG_UART uart_putc('X');
return ERR_FLASH;
}
}
if(total_read != (file_header.size + 0x100)) {
DBG_BL printf("wrote less data than expected! (%08lx vs. %08lx)\n", total_read, file_header.size);
// DBG_UART uart_putc('X');
return ERR_FILECHK;
}
writeled(0);
} else {
DBG_UART uart_putc('n');
DBG_BL printf("flash content is ok, no version mismatch, no forced upgrade. No need to flash\n");
}
return ERR_OK;
crc = crc_finalize( crc );
DBG_BL printf( " crc generated. result=%08lx\n", crc );
DBG_BL printf( "} //calc_flash_crc\n" );
return crc;
}
void test_iap()
{
iap_cmd[0] = 54;
iap_entry( iap_cmd, iap_res );
DBG_BL printf( "Part ID=%08lx\n", iap_res[1] );
}
void print_header( sd2snes_fw_header *header )
{
DBG_BL printf( " magic = %08lx\n version = %08lx\n size = %08lx\n crc = %08lx\n ~crc = %08lx\n",
header->magic, header->version, header->size,
header->crc, header->crcc );
}
int check_header( sd2snes_fw_header *header, uint32_t crc )
{
if ( ( header->magic != FW_MAGIC )
|| ( header->size < 0x200 )
|| ( header->size > ( 0x1ffff - FW_START ) )
|| ( ( header->crc ^ header->crcc ) != 0xffffffff ) )
{
return ERR_FLASHHD;
}
if ( header->crc != crc )
{
return ERR_FLASHCRC;
}
return ERR_OK;
}
FLASH_RES check_flash()
{
sd2snes_fw_header *fw_header = ( sd2snes_fw_header * ) FW_START;
uint32_t flash_addr = FW_START;
if ( flash_addr != FW_START )
{
DBG_BL printf( "address sanity check failed. expected 0x%08lx, got 0x%08lx.\nSomething is terribly wrong.\nBailing out to avoid bootldr self-corruption.\n",
FW_START, flash_addr );
return ERR_HW;
}
DBG_BL printf( "Current flash contents:\n" );
DBG_BL print_header( fw_header );
uint32_t crc = calc_flash_crc( flash_addr + 0x100, ( fw_header->size & 0x1ffff ) );
return check_header( fw_header, crc );
}
IAP_RES iap_wrap( uint32_t *iap_cmd, uint32_t *iap_res )
{
// NVIC_DisableIRQ(RIT_IRQn);
// NVIC_DisableIRQ(UART_IRQ);
for ( volatile int i = 0; i < 2048; i++ );
iap_entry( iap_cmd, iap_res );
for ( volatile int i = 0; i < 2048; i++ );
// NVIC_EnableIRQ(UART_IRQ);
return iap_res[0];
}
IAP_RES iap_prepare_for_write( uint32_t start, uint32_t end )
{
if ( start < ( FW_START / 0x1000 ) )
{
return INVALID_SECTOR;
}
iap_cmd[0] = 50;
iap_cmd[1] = start;
iap_cmd[2] = end;
iap_wrap( iap_cmd, iap_res );
return iap_res[0];
}
IAP_RES iap_erase( uint32_t start, uint32_t end )
{
if ( start < ( FW_START / 0x1000 ) )
{
return INVALID_SECTOR;
}
iap_cmd[0] = 52;
iap_cmd[1] = start;
iap_cmd[2] = end;
iap_cmd[3] = CONFIG_CPU_FREQUENCY / 1000L;
iap_wrap( iap_cmd, iap_res );
return iap_res[0];
}
IAP_RES iap_ram2flash( uint32_t tgt, uint8_t *src, int num )
{
iap_cmd[0] = 51;
iap_cmd[1] = tgt;
iap_cmd[2] = ( uint32_t )src;
iap_cmd[3] = num;
iap_cmd[4] = CONFIG_CPU_FREQUENCY / 1000L;
iap_wrap( iap_cmd, iap_res );
return iap_res[0];
}
FLASH_RES flash_file( uint8_t *filename )
{
sd2snes_fw_header *fw_header = ( sd2snes_fw_header * ) FW_START;
uint32_t flash_addr = FW_START;
uint32_t file_crc = 0xffffffff;
uint16_t count;
sd2snes_fw_header file_header;
UINT bytes_read;
if ( flash_addr != FW_START )
{
DBG_BL printf( "address sanity check failed. expected 0x%08lx, got 0x%08lx.\nSomething is terribly wrong.\nBailing out to avoid bootldr self-corruption.\n",
FW_START, flash_addr );
return ERR_HW;
}
file_open( filename, FA_READ );
if ( file_res )
{
DBG_BL printf( "file_open: error %d\n", file_res );
return ERR_FS;
}
DBG_BL printf( "firmware image found. file size: %ld\n", file_handle.fsize );
DBG_BL printf( "reading header...\n" );
f_read( &file_handle, &file_header, 32, &bytes_read );
DBG_BL print_header( &file_header );
if ( check_flash() || file_header.version != fw_header->version || file_header.version == FW_MAGIC
|| fw_header->version == FW_MAGIC )
{
DBG_UART uart_putc( 'F' );
f_read( &file_handle, file_buf, 0xe0, &bytes_read );
for ( ;; )
{
bytes_read = file_read();
if ( file_res || !bytes_read )
{
break;
}
for ( count = 0; count < bytes_read; count++ )
{
file_crc = crc32_update( file_crc, file_buf[count] );
}
}
file_crc = crc_finalize( file_crc );
DBG_BL printf( "file crc=%08lx\n", file_crc );
if ( check_header( &file_header, file_header.crc ) != ERR_OK )
{
DBG_BL printf( "Invalid firmware file (header corrupted).\n" );
return ERR_FILEHD;
}
if ( file_header.crc != file_crc )
{
DBG_BL printf( "Firmware file checksum error.\n" );
return ERR_FILECHK;
}
uint32_t res;
writeled( 1 );
DBG_BL printf( "erasing flash...\n" );
DBG_UART uart_putc( 'P' );
if ( ( res = iap_prepare_for_write( FW_START / 0x1000, FLASH_SECTORS ) ) != CMD_SUCCESS )
{
DBG_BL printf( "error %ld while preparing for erase\n", res );
DBG_UART uart_putc( 'X' );
return ERR_FLASHPREP;
};
DBG_UART uart_putc( 'E' );
if ( ( res = iap_erase( FW_START / 0x1000, FLASH_SECTORS ) ) != CMD_SUCCESS )
{
DBG_BL printf( "error %ld while erasing\n", res );
DBG_UART uart_putc( 'X' );
return ERR_FLASHERASE;
}
DBG_BL printf( "writing... @%08lx\n", flash_addr );
file_close();
file_open( filename, FA_READ );
uint8_t current_sec;
uint32_t total_read = 0;
for ( flash_addr = FW_START; flash_addr < 0x00020000; flash_addr += 0x200 )
{
total_read += ( bytes_read = file_read() );
if ( file_res || !bytes_read )
{
break;
}
current_sec = flash_addr & 0x10000 ? ( 16 + ( ( flash_addr >> 15 ) & 1 ) )
: ( flash_addr >> 12 );
DBG_BL printf( "current_sec=%d flash_addr=%08lx\n", current_sec, flash_addr );
DBG_UART uart_putc( '.' );
if ( current_sec < ( FW_START / 0x1000 ) )
{
return ERR_FLASH;
}
DBG_UART uart_putc( current_sec["0123456789ABCDEFGH"] );
DBG_UART uart_putc( 'p' );
if ( ( res = iap_prepare_for_write( current_sec, current_sec ) ) != CMD_SUCCESS )
{
DBG_BL printf( "error %ld while preparing sector %d for write\n", res, current_sec );
DBG_UART uart_putc( 'X' );
return ERR_FLASH;
}
DBG_UART uart_putc( 'w' );
if ( ( res = iap_ram2flash( flash_addr, file_buf, 512 ) ) != CMD_SUCCESS )
{
//printf("error %ld while writing to address %08lx (sector %d)\n", res, flash_addr, current_sec);
DBG_UART uart_putc( 'X' );
return ERR_FLASH;
}
}
if ( total_read != ( file_header.size + 0x100 ) )
{
DBG_BL printf( "wrote less data than expected! (%08lx vs. %08lx)\n", total_read, file_header.size );
// DBG_UART uart_putc('X');
return ERR_FILECHK;
}
writeled( 0 );
}
else
{
DBG_UART uart_putc( 'n' );
DBG_BL printf( "flash content is ok, no version mismatch, no forced upgrade. No need to flash\n" );
}
return ERR_OK;
}

View File

@ -2,39 +2,41 @@
#define IAP_H
#define IAP_LOCATION 0x1fff1ff1
typedef void (*IAP)(uint32_t*, uint32_t*);
typedef void ( *IAP )( uint32_t *, uint32_t * );
typedef enum {ERR_OK = 0, ERR_HW, ERR_FS, ERR_FILEHD, ERR_FILECHK, ERR_FLASHHD, ERR_FLASHCRC, ERR_FLASHPREP, ERR_FLASHERASE, ERR_FLASH} FLASH_RES;
typedef enum {
/* 0*/ CMD_SUCCESS = 0,
/* 1*/ INVALID_COMMAND,
/* 2*/ SRC_ADDR_ERROR,
/* 3*/ DST_ADDR_ERROR,
/* 4*/ SRC_ADDR_NOT_MAPPED,
/* 5*/ DST_ADDR_NOT_MAPPED,
/* 6*/ COUNT_ERROR,
/* 7*/ INVALID_SECTOR,
/* 8*/ SECTOR_NOT_BLANK,
/* 9*/ SECTOR_NOT_PREPARED_FOR_WRITE_OPERATION,
/*10*/ COMPARE_ERROR,
/*11*/ BUSY
typedef enum
{
/* 0*/ CMD_SUCCESS = 0,
/* 1*/ INVALID_COMMAND,
/* 2*/ SRC_ADDR_ERROR,
/* 3*/ DST_ADDR_ERROR,
/* 4*/ SRC_ADDR_NOT_MAPPED,
/* 5*/ DST_ADDR_NOT_MAPPED,
/* 6*/ COUNT_ERROR,
/* 7*/ INVALID_SECTOR,
/* 8*/ SECTOR_NOT_BLANK,
/* 9*/ SECTOR_NOT_PREPARED_FOR_WRITE_OPERATION,
/*10*/ COMPARE_ERROR,
/*11*/ BUSY
} IAP_RES;
#define FW_MAGIC (0x44534E53)
typedef struct {
uint32_t magic;
uint32_t version;
uint32_t size;
uint32_t crc;
uint32_t crcc;
typedef struct
{
uint32_t magic;
uint32_t version;
uint32_t size;
uint32_t crc;
uint32_t crcc;
} sd2snes_fw_header;
uint32_t calc_flash_crc(uint32_t start, uint32_t end);
void test_iap(void);
FLASH_RES check_flash(void);
FLASH_RES flash_file(uint8_t* filename);
uint32_t calc_flash_crc( uint32_t start, uint32_t end );
void test_iap( void );
FLASH_RES check_flash( void );
FLASH_RES flash_file( uint8_t *filename );
#endif

View File

@ -5,7 +5,7 @@
#ifndef _INTEGER
#define _INTEGER
#ifdef _WIN32 /* FatFs development platform */
#ifdef _WIN32 /* FatFs development platform */
#include <windows.h>
#include <tchar.h>

View File

@ -18,73 +18,85 @@ int led_writeledstate = 0;
write red P1.23 PWM1[4]
*/
void rdyled(unsigned int state) {
BITBAND(LPC_GPIO2->FIODIR, 4) = state;
led_rdyledstate = state;
void rdyled( unsigned int state )
{
BITBANG( LPC_GPIO2->FIODIR, 4 ) = state;
led_rdyledstate = state;
}
void readled(unsigned int state) {
BITBAND(LPC_GPIO2->FIODIR, 5) = state;
led_readledstate = state;
void readled( unsigned int state )
{
BITBANG( LPC_GPIO2->FIODIR, 5 ) = state;
led_readledstate = state;
}
void writeled(unsigned int state) {
BITBAND(LPC_GPIO1->FIODIR, 23) = state;
led_writeledstate = state;
void writeled( unsigned int state )
{
BITBANG( LPC_GPIO1->FIODIR, 23 ) = state;
led_writeledstate = state;
}
void led_clkout32(uint32_t val) {
while(1) {
rdyled(1);
delay_ms(400);
readled((val & BV(31))>>31);
rdyled(0);
val<<=1;
delay_ms(400);
}
void led_clkout32( uint32_t val )
{
while ( 1 )
{
rdyled( 1 );
delay_ms( 400 );
readled( ( val & BV( 31 ) ) >> 31 );
rdyled( 0 );
val <<= 1;
delay_ms( 400 );
}
}
void toggle_rdy_led() {
rdyled(~led_rdyledstate);
void toggle_rdy_led()
{
rdyled( ~led_rdyledstate );
}
void toggle_read_led() {
readled(~led_readledstate);
void toggle_read_led()
{
readled( ~led_readledstate );
}
void toggle_write_led() {
writeled(~led_writeledstate);
void toggle_write_led()
{
writeled( ~led_writeledstate );
}
void led_panic() {
while(1) {
LPC_GPIO2->FIODIR |= BV(4) | BV(5);
LPC_GPIO1->FIODIR |= BV(23);
delay_ms(350);
LPC_GPIO2->FIODIR &= ~(BV(4) | BV(5));
LPC_GPIO1->FIODIR &= ~BV(23);
delay_ms(350);
}
void led_panic()
{
while ( 1 )
{
LPC_GPIO2->FIODIR |= BV( 4 ) | BV( 5 );
LPC_GPIO1->FIODIR |= BV( 23 );
delay_ms( 350 );
LPC_GPIO2->FIODIR &= ~( BV( 4 ) | BV( 5 ) );
LPC_GPIO1->FIODIR &= ~BV( 23 );
delay_ms( 350 );
}
}
void led_std() {
BITBAND(LPC_PINCON->PINSEL4, 9) = 0;
BITBAND(LPC_PINCON->PINSEL4, 8) = 0;
void led_std()
{
BITBANG( LPC_PINCON->PINSEL4, 9 ) = 0;
BITBANG( LPC_PINCON->PINSEL4, 8 ) = 0;
BITBAND(LPC_PINCON->PINSEL4, 11) = 0;
BITBAND(LPC_PINCON->PINSEL4, 10) = 0;
BITBANG( LPC_PINCON->PINSEL4, 11 ) = 0;
BITBANG( LPC_PINCON->PINSEL4, 10 ) = 0;
BITBAND(LPC_PINCON->PINSEL3, 15) = 0;
BITBAND(LPC_PINCON->PINSEL3, 14) = 0;
BITBANG( LPC_PINCON->PINSEL3, 15 ) = 0;
BITBANG( LPC_PINCON->PINSEL3, 14 ) = 0;
BITBAND(LPC_PWM1->PCR, 12) = 0;
BITBAND(LPC_PWM1->PCR, 13) = 0;
BITBAND(LPC_PWM1->PCR, 14) = 0;
BITBANG( LPC_PWM1->PCR, 12 ) = 0;
BITBANG( LPC_PWM1->PCR, 13 ) = 0;
BITBANG( LPC_PWM1->PCR, 14 ) = 0;
}
void led_init() {
/* power is already connected by default */
/* set PCLK divider to 8 */
BITBAND(LPC_SC->PCLKSEL1, 21) = 1;
BITBAND(LPC_SC->PCLKSEL1, 20) = 1;
void led_init()
{
/* power is already connected by default */
/* set PCLK divider to 8 */
BITBANG( LPC_SC->PCLKSEL1, 21 ) = 1;
BITBANG( LPC_SC->PCLKSEL1, 20 ) = 1;
}

View File

@ -3,15 +3,15 @@
#ifndef _LED_H
#define _LED_H
void readled(unsigned int state);
void writeled(unsigned int state);
void rdyled(unsigned int state);
void led_clkout32(uint32_t val);
void toggle_rdy_led(void);
void toggle_read_led(void);
void toggle_write_led(void);
void led_panic(void);
void led_std(void);
void led_init(void);
void readled( unsigned int state );
void writeled( unsigned int state );
void rdyled( unsigned int state );
void led_clkout32( uint32_t val );
void toggle_rdy_led( void );
void toggle_read_led( void );
void toggle_write_led( void );
void led_panic( void );
void led_std( void );
void led_init( void );
#endif

View File

@ -27,9 +27,9 @@ if { [info exists CPUTAPID ] } {
#delays on reset lines
#if your OpenOCD version rejects "jtag_nsrst_delay" replace it with:
#adapter_nsrst_delay 200
jtag_nsrst_delay 200
jtag_ntrst_delay 200
adapter_nsrst_delay 200
#jtag_nsrst_delay 200
#jtag_ntrst_delay 200
# LPC2000 & LPC1700 -> SRST causes TRST
#reset_config srst_pulls_trst
@ -56,7 +56,7 @@ flash bank $_FLASHNAME lpc2000 0x0 0x20000 0 0 $_TARGETNAME \
# Run with *real slow* clock by default since the
# boot rom could have been playing with the PLL, so
# we have no idea what clock the target is running at.
jtag_khz 1000
adapter_khz 1000
$_TARGETNAME configure -event reset-init {
# Do not remap 0x0000-0x0020 to anything but the flash (i.e. select

View File

@ -15,88 +15,118 @@
#include "fileops.h"
#include "iap.h"
#define EMC0TOGGLE (3<<4)
#define MR0R (1<<1)
#define EMC0TOGGLE (3<<4)
#define MR0R (1<<1)
int i;
BYTE file_buf[512] GCC_ALIGN_WORKAROUND;
FATFS fatfs;
FIL file_handle;
FRESULT file_res;
uint8_t file_lfn[258];
uint16_t file_block_off, file_block_max;
enum filestates file_status;
volatile enum diskstates disk_state;
extern volatile tick_t ticks;
int (*chain)(void);
int ( *chain )( void );
int main(void) {
SNES_CIC_PAIR_REG->FIODIR = BV(SNES_CIC_PAIR_BIT);
BITBAND(SNES_CIC_PAIR_REG->FIOSET, SNES_CIC_PAIR_BIT) = 1;
/* LPC_GPIO2->FIODIR = BV(0) | BV(1) | BV(2); */
// LPC_GPIO0->FIODIR = BV(16);
int main( void )
{
SNES_CIC_PAIR_REG->FIODIR = BV( SNES_CIC_PAIR_BIT );
BITBANG( SNES_CIC_PAIR_REG->FIOSET, SNES_CIC_PAIR_BIT ) = 1;
/* connect UART3 on P0[25:26] + SSP0 on P0[15:18] + MAT3.0 on P0[10] */
LPC_PINCON->PINSEL1 = BV(18) | BV(19) | BV(20) | BV(21) /* UART3 */
| BV(3) | BV(5); /* SSP0 (FPGA) except SS */
LPC_PINCON->PINSEL0 = BV(31); /* SSP0 */
/* | BV(13) | BV(15) | BV(17) | BV(19) SSP1 (SD) */
/* LPC_GPIO2->FIODIR = BV(0) | BV(1) | BV(2); */
// LPC_GPIO0->FIODIR = BV(16);
/* pull-down CIC data lines */
LPC_PINCON->PINMODE0 = BV(0) | BV(1) | BV(2) | BV(3);
/* connect UART3 on P0[25:26] + SSP0 on P0[15:18] + MAT3.0 on P0[10] */
LPC_PINCON->PINSEL1 = BV( 18 ) | BV( 19 ) | BV( 20 ) | BV( 21 ) /* UART3 */
| BV( 3 ) | BV( 5 ); /* SSP0 (FPGA) except SS */
LPC_PINCON->PINSEL0 = BV( 31 ); /* SSP0 */
/* | BV(13) | BV(15) | BV(17) | BV(19) SSP1 (SD) */
clock_disconnect();
power_init();
timer_init();
DBG_UART uart_init();
led_init();
readled(0);
rdyled(1);
writeled(0);
/* do this last because the peripheral init()s change PCLK dividers */
clock_init();
// LPC_PINCON->PINSEL0 |= BV(20) | BV(21); /* MAT3.0 (FPGA clock) */
sdn_init();
DBG_BL printf("chksum=%08lx\n", *(uint32_t*)28);
DBG_BL printf("\n\nsd2snes mk.2 bootloader\nver.: " VER "\ncpu clock: %ld Hz\n", CONFIG_CPU_FREQUENCY);
DBG_BL printf("PCONP=%lx\n", LPC_SC->PCONP);
/* setup timer (fpga clk) */
LPC_TIM3->CTCR=0;
LPC_TIM3->EMR=EMC0TOGGLE;
LPC_TIM3->MCR=MR0R;
LPC_TIM3->MR0=1;
LPC_TIM3->TCR=1;
NVIC->ICER[0] = 0xffffffff;
NVIC->ICER[1] = 0xffffffff;
FLASH_RES res = flash_file((uint8_t*)"/sd2snes/firmware.img");
if(res == ERR_FLASHPREP || res == ERR_FLASHERASE || res == ERR_FLASH) {
rdyled(0);
writeled(1);
}
if(res == ERR_FILEHD || res == ERR_FILECHK) {
rdyled(0);
readled(1);
}
DBG_BL printf("flash result = %d\n", res);
if(res != ERR_OK) {
if((res = check_flash()) != ERR_OK) {
DBG_BL printf("check_flash() failed with error %d, not booting.\n", res);
while(1) {
toggle_rdy_led();
delay_ms(500);
}
/* pull-down CIC data lines */
LPC_PINCON->PINMODE0 = BV( 0 ) | BV( 1 ) | BV( 2 ) | BV( 3 );
clock_disconnect();
power_init();
timer_init();
DBG_UART uart_init();
led_init();
readled( 0 );
rdyled( 1 );
writeled( 0 );
/* do this last because the peripheral init()s change PCLK dividers */
clock_init();
// LPC_PINCON->PINSEL0 |= BV(20) | BV(21); /* MAT3.0 (FPGA clock) */
sdn_init();
for ( i = 0; i < 20; i++ )
{
uart_putc( '-' );
}
}
NVIC_DisableIRQ(RIT_IRQn);
NVIC_DisableIRQ(UART_IRQ);
SCB->VTOR=FW_START+0x00000100;
chain = (void*)(*((uint32_t*)(FW_START+0x00000104)));
uart_putc("0123456789abcdef"[((uint32_t)chain>>28)&15]);
uart_putc("0123456789abcdef"[((uint32_t)chain>>24)&15]);
uart_putc("0123456789abcdef"[((uint32_t)chain>>20)&15]);
uart_putc("0123456789abcdef"[((uint32_t)chain>>16)&15]);
uart_putc("0123456789abcdef"[((uint32_t)chain>>12)&15]);
uart_putc("0123456789abcdef"[((uint32_t)chain>>8)&15]);
uart_putc("0123456789abcdef"[((uint32_t)chain>>4)&15]);
uart_putc("0123456789abcdef"[((uint32_t)chain)&15]);
uart_putc('\n');
chain();
while(1);
uart_putc( '\n' );
DBG_BL printf( "chksum=%08lx\n", *( uint32_t * )28 );
/*DBG_BL*/ printf( "\n\nsd2snes mk.2 bootloader\nver.: " VER "\ncpu clock: %ld Hz\n", CONFIG_CPU_FREQUENCY );
DBG_BL printf( "PCONP=%lx\n", LPC_SC->PCONP );
/* setup timer (fpga clk) */
LPC_TIM3->CTCR = 0;
LPC_TIM3->EMR = EMC0TOGGLE;
LPC_TIM3->MCR = MR0R;
LPC_TIM3->MR0 = 1;
LPC_TIM3->TCR = 1;
NVIC->ICER[0] = 0xffffffff;
NVIC->ICER[1] = 0xffffffff;
FLASH_RES res = flash_file( ( uint8_t * )"/sd2snes/firmware.img" );
if ( res == ERR_FLASHPREP || res == ERR_FLASHERASE || res == ERR_FLASH )
{
rdyled( 0 );
writeled( 1 );
}
if ( res == ERR_FILEHD || res == ERR_FILECHK )
{
rdyled( 0 );
readled( 1 );
}
DBG_BL printf( "flash result = %d\n", res );
if ( res != ERR_OK )
{
if ( ( res = check_flash() ) != ERR_OK )
{
DBG_BL printf( "check_flash() failed with error %d, not booting.\n", res );
while ( 1 )
{
toggle_rdy_led();
delay_ms( 500 );
}
}
}
NVIC_DisableIRQ( RIT_IRQn );
NVIC_DisableIRQ( UART_IRQ );
SCB->VTOR = FW_START + 0x00000100;
chain = ( void * )( *( ( uint32_t * )( FW_START + 0x00000104 ) ) );
uart_putc( "0123456789abcdef"[( ( uint32_t )chain >> 28 ) & 15] );
uart_putc( "0123456789abcdef"[( ( uint32_t )chain >> 24 ) & 15] );
uart_putc( "0123456789abcdef"[( ( uint32_t )chain >> 20 ) & 15] );
uart_putc( "0123456789abcdef"[( ( uint32_t )chain >> 16 ) & 15] );
uart_putc( "0123456789abcdef"[( ( uint32_t )chain >> 12 ) & 15] );
uart_putc( "0123456789abcdef"[( ( uint32_t )chain >> 8 ) & 15] );
uart_putc( "0123456789abcdef"[( ( uint32_t )chain >> 4 ) & 15] );
uart_putc( "0123456789abcdef"[( ( uint32_t )chain ) & 15] );
uart_putc( '\n' );
chain();
while ( 1 );
}

View File

@ -5,8 +5,14 @@
#
interface ft2232
ft2232_vid_pid 0x0403 0x6010
ft2232_device_desc "Dual RS232"
ft2232_layout "oocdlink"
ft2232_latency 2
ft2232_vid_pid 0x15ba 0x0003
ft2232_device_desc "Olimex OpenOCD JTAG"
ft2232_layout "olimex-jtag"
#interface ft2232
#ft2232_vid_pid 0x0403 0x6010
#ft2232_device_desc "Dual RS232"
#ft2232_layout "oocdlink"
#ft2232_latency 2
#adapter_khz 10

View File

@ -15,12 +15,13 @@
* USB [enabled via usb_init]
* PWM1
*/
void power_init() {
LPC_SC->PCONP = BV(PCSSP0)
| BV(PCTIM3)
| BV(PCRTC)
| BV(PCGPIO)
| BV(PCPWM1)
// | BV(PCUSB)
;
void power_init()
{
LPC_SC->PCONP = BV( PCSSP0 )
| BV( PCTIM3 )
| BV( PCRTC )
| BV( PCGPIO )
| BV( PCPWM1 )
// | BV(PCUSB)
;
}

View File

@ -5,7 +5,7 @@
#include "bits.h"
#define PCUART0 (3)
#define PCUART0 (3)
#define PCUART1 (4)
#define PCUART2 (24)
#define PCUART3 (25)
@ -38,6 +38,6 @@
#define PCQEI (18)
#define PCGPIO (15)
void power_init(void);
void power_init( void );
#endif

View File

@ -62,239 +62,313 @@ static char *outptr;
static int maxlen;
/* printf */
static void outchar(char x) {
if (maxlen) {
maxlen--;
outfunc(x);
outlength++;
}
static void outchar( char x )
{
if ( maxlen )
{
maxlen--;
outfunc( x );
outlength++;
}
}
/* sprintf */
static void outstr(char x) {
if (maxlen) {
maxlen--;
*outptr++ = x;
outlength++;
}
static void outstr( char x )
{
if ( maxlen )
{
maxlen--;
*outptr++ = x;
outlength++;
}
}
static int internal_nprintf(void (*output_function)(char c), const char *fmt, va_list ap) {
unsigned int width;
unsigned int flags;
unsigned int base = 0;
char *ptr = NULL;
static int internal_nprintf( void ( *output_function )( char c ), const char *fmt, va_list ap )
{
unsigned int width;
unsigned int flags;
unsigned int base = 0;
char *ptr = NULL;
outlength = 0;
outlength = 0;
while (*fmt) {
while (1) {
if (*fmt == 0)
goto end;
while ( *fmt )
{
while ( 1 )
{
if ( *fmt == 0 )
{
goto end;
}
if (*fmt == '%') {
fmt++;
if (*fmt != '%')
break;
}
if ( *fmt == '%' )
{
fmt++;
output_function(*fmt++);
}
if ( *fmt != '%' )
{
break;
}
}
flags = 0;
width = 0;
/* read all flags */
do {
if (flags < FLAG_WIDTH) {
switch (*fmt) {
case '0':
flags |= FLAG_ZEROPAD;
continue;
case '-':
flags |= FLAG_LEFTADJ;
continue;
case ' ':
flags |= FLAG_BLANK;
continue;
case '+':
flags |= FLAG_FORCESIGN;
continue;
}
}
if (flags < FLAG_LONG) {
if (*fmt >= '0' && *fmt <= '9') {
unsigned char tmp = *fmt - '0';
width = 10*width + tmp;
flags |= FLAG_WIDTH;
continue;
output_function( *fmt++ );
}
if (*fmt == 'h')
continue;
flags = 0;
width = 0;
if (*fmt == 'l') {
flags |= FLAG_LONG;
continue;
/* read all flags */
do
{
if ( flags < FLAG_WIDTH )
{
switch ( *fmt )
{
case '0':
flags |= FLAG_ZEROPAD;
continue;
case '-':
flags |= FLAG_LEFTADJ;
continue;
case ' ':
flags |= FLAG_BLANK;
continue;
case '+':
flags |= FLAG_FORCESIGN;
continue;
}
}
if ( flags < FLAG_LONG )
{
if ( *fmt >= '0' && *fmt <= '9' )
{
unsigned char tmp = *fmt - '0';
width = 10 * width + tmp;
flags |= FLAG_WIDTH;
continue;
}
if ( *fmt == 'h' )
{
continue;
}
if ( *fmt == 'l' )
{
flags |= FLAG_LONG;
continue;
}
}
break;
}
}
while ( *fmt++ );
break;
} while (*fmt++);
/* Strings */
if ( *fmt == 'c' || *fmt == 's' )
{
switch ( *fmt )
{
case 'c':
buffer[0] = va_arg( ap, int );
ptr = buffer;
break;
/* Strings */
if (*fmt == 'c' || *fmt == 's') {
switch (*fmt) {
case 'c':
buffer[0] = va_arg(ap, int);
ptr = buffer;
break;
case 's':
ptr = va_arg( ap, char * );
break;
}
case 's':
ptr = va_arg(ap, char *);
break;
}
goto output;
}
goto output;
}
/* Numbers */
switch ( *fmt )
{
case 'u':
flags |= FLAG_UNSIGNED;
/* Numbers */
switch (*fmt) {
case 'u':
flags |= FLAG_UNSIGNED;
case 'd':
base = 10;
break;
case 'd':
base = 10;
break;
case 'o':
base = 8;
flags |= FLAG_UNSIGNED;
break;
case 'o':
base = 8;
flags |= FLAG_UNSIGNED;
break;
case 'p': // pointer
output_function('0');
output_function('x');
width -= 2;
case 'x':
case 'X':
base = 16;
flags |= FLAG_UNSIGNED;
break;
}
case 'p': // pointer
output_function( '0' );
output_function( 'x' );
width -= 2;
unsigned int num;
case 'x':
case 'X':
base = 16;
flags |= FLAG_UNSIGNED;
break;
}
if (!(flags & FLAG_UNSIGNED)) {
int tmp = va_arg(ap, int);
if (tmp < 0) {
num = -tmp;
flags |= FLAG_NEGATIVE;
} else
num = tmp;
} else {
num = va_arg(ap, unsigned int);
}
unsigned int num;
/* Convert number into buffer */
ptr = buffer + sizeof(buffer);
*--ptr = 0;
do {
*--ptr = hexdigits[num % base];
num /= base;
} while (num != 0);
if ( !( flags & FLAG_UNSIGNED ) )
{
int tmp = va_arg( ap, int );
/* Sign */
if (flags & FLAG_NEGATIVE) {
output_function('-');
width--;
} else if (flags & FLAG_FORCESIGN) {
output_function('+');
width--;
} else if (flags & FLAG_BLANK) {
output_function(' ');
width--;
}
output:
/* left padding */
if ((flags & FLAG_WIDTH) && !(flags & FLAG_LEFTADJ)) {
while (strlen(ptr) < width) {
if (flags & FLAG_ZEROPAD)
output_function('0');
if ( tmp < 0 )
{
num = -tmp;
flags |= FLAG_NEGATIVE;
}
else
{
num = tmp;
}
}
else
output_function(' ');
width--;
}
{
num = va_arg( ap, unsigned int );
}
/* Convert number into buffer */
ptr = buffer + sizeof( buffer );
*--ptr = 0;
do
{
*--ptr = hexdigits[num % base];
num /= base;
}
while ( num != 0 );
/* Sign */
if ( flags & FLAG_NEGATIVE )
{
output_function( '-' );
width--;
}
else if ( flags & FLAG_FORCESIGN )
{
output_function( '+' );
width--;
}
else if ( flags & FLAG_BLANK )
{
output_function( ' ' );
width--;
}
output:
/* left padding */
if ( ( flags & FLAG_WIDTH ) && !( flags & FLAG_LEFTADJ ) )
{
while ( strlen( ptr ) < width )
{
if ( flags & FLAG_ZEROPAD )
{
output_function( '0' );
}
else
{
output_function( ' ' );
}
width--;
}
}
/* data */
while ( *ptr )
{
output_function( *ptr++ );
if ( width )
{
width--;
}
}
/* right padding */
if ( flags & FLAG_WIDTH )
{
while ( width )
{
output_function( ' ' );
width--;
}
}
fmt++;
}
/* data */
while (*ptr) {
output_function(*ptr++);
if (width)
width--;
}
/* right padding */
if (flags & FLAG_WIDTH) {
while (width) {
output_function(' ');
width--;
}
}
fmt++;
}
end:
return outlength;
end:
return outlength;
}
int printf(const char *format, ...) {
va_list ap;
int res;
int printf( const char *format, ... )
{
va_list ap;
int res;
maxlen = -1;
va_start(ap, format);
res = internal_nprintf(outchar, format, ap);
va_end(ap);
return res;
maxlen = -1;
va_start( ap, format );
res = internal_nprintf( outchar, format, ap );
va_end( ap );
return res;
}
int snprintf(char *str, size_t size, const char *format, ...) {
va_list ap;
int res;
int snprintf( char *str, size_t size, const char *format, ... )
{
va_list ap;
int res;
maxlen = size;
outptr = str;
va_start(ap, format);
res = internal_nprintf(outstr, format, ap);
va_end(ap);
if (res < size)
str[res] = 0;
return res;
maxlen = size;
outptr = str;
va_start( ap, format );
res = internal_nprintf( outstr, format, ap );
va_end( ap );
if ( res < size )
{
str[res] = 0;
}
return res;
}
/* Required for gcc compatibility */
int puts(const char *str) {
uart_puts(str);
uart_putc('\n');
return 0;
int puts( const char *str )
{
uart_puts( str );
uart_putc( '\n' );
return 0;
}
#undef putchar
int putchar(int c) {
uart_putc(c);
return 0;
int putchar( int c )
{
uart_putc( c );
return 0;
}
#else
int printf(const char *format, ...) { return 0; }
int snprintf(char *str, size_t size, const char *format, ...) { return 0; }
int puts(const char *str) { return 0; }
int printf( const char *format, ... )
{
return 0;
}
//int snprintf(char *str, size_t size, const char *format, ...) { return 0; }
int puts( const char *str )
{
return 0;
}
#undef putchar
int putchar(int c) { return 0; }
int putchar( int c )
{
return 0;
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,4 @@
/* ___INGO___ */
#include <arm/NXP/LPC17xx/LPC17xx.h>
#include "bits.h"
#include "config.h"
@ -18,41 +17,44 @@ extern volatile int sd_changed;
volatile tick_t ticks;
volatile int wokefromrit;
void timer_init(void) {
/* turn on power to RIT */
BITBAND(LPC_SC->PCONP, PCRIT) = 1;
void timer_init( void )
{
/* turn on power to RIT */
BITBANG( LPC_SC->PCONP, PCRIT ) = 1;
/* clear RIT mask */
LPC_RIT->RIMASK = 0; /*xffffffff;*/
/* clear RIT mask */
LPC_RIT->RIMASK = 0; /*xffffffff;*/
/* PCLK = CCLK */
BITBAND(LPC_SC->PCLKSEL1, 26) = 1;
BITBAND(LPC_SC->PCLKSEL1, PCLK_TIMER3) = 1;
/* PCLK = CCLK */
BITBANG( LPC_SC->PCLKSEL1, 26 ) = 1;
BITBANG( LPC_SC->PCLKSEL1, PCLK_TIMER3 ) = 1;
}
void delay_us(unsigned int time) {
/* Prepare RIT */
LPC_RIT->RICOUNTER = 0;
LPC_RIT->RICOMPVAL = (CONFIG_CPU_FREQUENCY / 1000000) * time;
LPC_RIT->RICTRL = BV(RITEN) | BV(RITINT);
void delay_us( unsigned int time )
{
/* Prepare RIT */
LPC_RIT->RICOUNTER = 0;
LPC_RIT->RICOMPVAL = ( CONFIG_CPU_FREQUENCY / 1000000 ) * time;
LPC_RIT->RICTRL = BV( RITEN ) | BV( RITINT );
/* Wait until RIT signals an interrupt */
while (!(BITBAND(LPC_RIT->RICTRL, RITINT))) ;
/* Wait until RIT signals an interrupt */
while ( !( BITBANG( LPC_RIT->RICTRL, RITINT ) ) ) ;
/* Disable RIT */
LPC_RIT->RICTRL = 0;
/* Disable RIT */
LPC_RIT->RICTRL = 0;
}
void delay_ms(unsigned int time) {
/* Prepare RIT */
LPC_RIT->RICOUNTER = 0;
LPC_RIT->RICOMPVAL = (CONFIG_CPU_FREQUENCY / 1000) * time;
LPC_RIT->RICTRL = BV(RITEN) | BV(RITINT);
void delay_ms( unsigned int time )
{
/* Prepare RIT */
LPC_RIT->RICOUNTER = 0;
LPC_RIT->RICOMPVAL = ( CONFIG_CPU_FREQUENCY / 1000 ) * time;
LPC_RIT->RICTRL = BV( RITEN ) | BV( RITINT );
/* Wait until RIT signals an interrupt */
while (!(BITBAND(LPC_RIT->RICTRL, RITINT))) ;
/* Wait until RIT signals an interrupt */
while ( !( BITBANG( LPC_RIT->RICTRL, RITINT ) ) ) ;
/* Disable RIT */
LPC_RIT->RICTRL = 0;
/* Disable RIT */
LPC_RIT->RICTRL = 0;
}

View File

@ -13,8 +13,9 @@ extern volatile tick_t ticks;
*
* This inline function returns the current system tick count.
*/
static inline tick_t getticks(void) {
return ticks;
static inline tick_t getticks( void )
{
return ticks;
}
#define MS_TO_TICKS(x) (x/10)
@ -35,17 +36,17 @@ static inline tick_t getticks(void) {
* (">=0" refers to the time_after_eq macro which wasn't copied)
*/
#define time_after(a,b) \
((int)(b) - (int)(a) < 0)
((int)(b) - (int)(a) < 0)
#define time_before(a,b) time_after(b,a)
void timer_init(void);
void timer_init( void );
/* delay for "time" microseconds - uses the RIT */
void delay_us(unsigned int time);
void delay_us( unsigned int time );
/* delay for "time" milliseconds - uses the RIT */
void delay_ms(unsigned int time);
void sleep_ms(unsigned int time);
void delay_ms( unsigned int time );
void sleep_ms( unsigned int time );
#endif

View File

@ -75,128 +75,179 @@
}
*/
//static char txbuf[1 << CONFIG_UART_TX_BUF_SHIFT];
static volatile unsigned int read_idx,write_idx;
static volatile unsigned int read_idx, write_idx;
void uart_putc(char c) {
if (c == '\n')
uart_putc('\r');
while(!(UART_REGS->LSR & (0x20)));
UART_REGS->THR = c;
void uart_putc( char c )
{
if ( c == '\n' )
{
uart_putc( '\r' );
}
while ( !( UART_REGS->LSR & ( 0x20 ) ) );
UART_REGS->THR = c;
}
/* Polling version only */
unsigned char uart_getc(void) {
/* wait for character */
while (!(BITBAND(UART_REGS->LSR, 0))) ;
return UART_REGS->RBR;
unsigned char uart_getc( void )
{
/* wait for character */
while ( !( BITBANG( UART_REGS->LSR, 0 ) ) ) ;
return UART_REGS->RBR;
}
/* Returns true if a char is ready */
unsigned char uart_gotc(void) {
return BITBAND(UART_REGS->LSR, 0);
unsigned char uart_gotc( void )
{
return BITBANG( UART_REGS->LSR, 0 );
}
void uart_init(void) {
uint32_t div;
void uart_init( void )
{
uint32_t div;
/* Turn on power to UART */
BITBAND(LPC_SC->PCONP, UART_PCONBIT) = 1;
/* Turn on power to UART */
BITBANG( LPC_SC->PCONP, UART_PCONBIT ) = 1;
/* UART clock = CPU clock - this block is reduced at compile-time */
if (CONFIG_UART_PCLKDIV == 1) {
BITBAND(LPC_SC->UART_PCLKREG, UART_PCLKBIT ) = 1;
BITBAND(LPC_SC->UART_PCLKREG, UART_PCLKBIT+1) = 0;
} else if (CONFIG_UART_PCLKDIV == 2) {
BITBAND(LPC_SC->UART_PCLKREG, UART_PCLKBIT ) = 0;
BITBAND(LPC_SC->UART_PCLKREG, UART_PCLKBIT+1) = 1;
} else if (CONFIG_UART_PCLKDIV == 4) {
BITBAND(LPC_SC->UART_PCLKREG, UART_PCLKBIT ) = 0;
BITBAND(LPC_SC->UART_PCLKREG, UART_PCLKBIT+1) = 0;
} else { // Fallback: Divide by 8
BITBAND(LPC_SC->UART_PCLKREG, UART_PCLKBIT ) = 1;
BITBAND(LPC_SC->UART_PCLKREG, UART_PCLKBIT+1) = 1;
}
/* UART clock = CPU clock - this block is reduced at compile-time */
if ( CONFIG_UART_PCLKDIV == 1 )
{
BITBANG( LPC_SC->UART_PCLKREG, UART_PCLKBIT ) = 1;
BITBANG( LPC_SC->UART_PCLKREG, UART_PCLKBIT + 1 ) = 0;
}
else if ( CONFIG_UART_PCLKDIV == 2 )
{
BITBANG( LPC_SC->UART_PCLKREG, UART_PCLKBIT ) = 0;
BITBANG( LPC_SC->UART_PCLKREG, UART_PCLKBIT + 1 ) = 1;
}
else if ( CONFIG_UART_PCLKDIV == 4 )
{
BITBANG( LPC_SC->UART_PCLKREG, UART_PCLKBIT ) = 0;
BITBANG( LPC_SC->UART_PCLKREG, UART_PCLKBIT + 1 ) = 0;
}
else // Fallback: Divide by 8
{
BITBANG( LPC_SC->UART_PCLKREG, UART_PCLKBIT ) = 1;
BITBANG( LPC_SC->UART_PCLKREG, UART_PCLKBIT + 1 ) = 1;
}
/* set baud rate - no fractional stuff for now */
UART_REGS->LCR = BV(7) | 3; // always 8n1
div = 0xF80022; //0x850004; // baud2divisor(CONFIG_UART_BAUDRATE);
/* set baud rate - no fractional stuff for now */
UART_REGS->LCR = BV( 7 ) | 3; // always 8n1
div = 0xF80022; //0x850004; // baud2divisor(CONFIG_UART_BAUDRATE);
UART_REGS->DLL = div & 0xff;
UART_REGS->DLM = (div >> 8) & 0xff;
BITBAND(UART_REGS->LCR, 7) = 0;
UART_REGS->DLL = div & 0xff;
UART_REGS->DLM = ( div >> 8 ) & 0xff;
BITBANG( UART_REGS->LCR, 7 ) = 0;
if (div & 0xff0000) {
UART_REGS->FDR = (div >> 16) & 0xff;
}
if ( div & 0xff0000 )
{
UART_REGS->FDR = ( div >> 16 ) & 0xff;
}
/* reset and enable FIFO */
UART_REGS->FCR = BV(0);
/* reset and enable FIFO */
UART_REGS->FCR = BV( 0 );
UART_REGS->THR = '?';
UART_REGS->THR = '?';
}
/* --- generic code below --- */
void uart_puthex(uint8_t num) {
uint8_t tmp;
tmp = (num & 0xf0) >> 4;
if (tmp < 10)
uart_putc('0'+tmp);
else
uart_putc('a'+tmp-10);
void uart_puthex( uint8_t num )
{
uint8_t tmp;
tmp = ( num & 0xf0 ) >> 4;
tmp = num & 0x0f;
if (tmp < 10)
uart_putc('0'+tmp);
else
uart_putc('a'+tmp-10);
}
void uart_trace(void *ptr, uint16_t start, uint16_t len) {
uint16_t i;
uint8_t j;
uint8_t ch;
uint8_t *data = ptr;
data+=start;
for(i=0;i<len;i+=16) {
uart_puthex(start>>8);
uart_puthex(start&0xff);
uart_putc('|');
uart_putc(' ');
for(j=0;j<16;j++) {
if(i+j<len) {
ch=*(data + j);
uart_puthex(ch);
} else {
uart_putc(' ');
uart_putc(' ');
}
uart_putc(' ');
if ( tmp < 10 )
{
uart_putc( '0' + tmp );
}
uart_putc('|');
for(j=0;j<16;j++) {
if(i+j<len) {
ch=*(data++);
if(ch<32 || ch>0x7e)
ch='.';
uart_putc(ch);
} else {
uart_putc(' ');
}
else
{
uart_putc( 'a' + tmp - 10 );
}
tmp = num & 0x0f;
if ( tmp < 10 )
{
uart_putc( '0' + tmp );
}
else
{
uart_putc( 'a' + tmp - 10 );
}
uart_putc('|');
uart_putcrlf();
start+=16;
}
}
void uart_flush(void) {
while (read_idx != write_idx) ;
void uart_trace( void *ptr, uint16_t start, uint16_t len )
{
uint16_t i;
uint8_t j;
uint8_t ch;
uint8_t *data = ptr;
data += start;
for ( i = 0; i < len; i += 16 )
{
uart_puthex( start >> 8 );
uart_puthex( start & 0xff );
uart_putc( '|' );
uart_putc( ' ' );
for ( j = 0; j < 16; j++ )
{
if ( i + j < len )
{
ch = *( data + j );
uart_puthex( ch );
}
else
{
uart_putc( ' ' );
uart_putc( ' ' );
}
uart_putc( ' ' );
}
uart_putc( '|' );
for ( j = 0; j < 16; j++ )
{
if ( i + j < len )
{
ch = *( data++ );
if ( ch < 32 || ch > 0x7e )
{
ch = '.';
}
uart_putc( ch );
}
else
{
uart_putc( ' ' );
}
}
uart_putc( '|' );
uart_putcrlf();
start += 16;
}
}
void uart_puts(const char *text) {
while (*text) {
uart_putc(*text++);
}
void uart_flush( void )
{
while ( read_idx != write_idx ) ;
}
void uart_puts( const char *text )
{
while ( *text )
{
uart_putc( *text++ );
}
}

View File

@ -16,21 +16,21 @@
#ifdef __AVR__
# include <avr/pgmspace.h>
void uart_puts_P(prog_char *text);
void uart_puts_P( prog_char *text );
#else
# define uart_puts_P(str) uart_puts(str)
#endif
void uart_init(void);
unsigned char uart_getc(void);
unsigned char uart_gotc(void);
void uart_putc(char c);
void uart_puts(const char *str);
void uart_puthex(uint8_t num);
void uart_trace(void *ptr, uint16_t start, uint16_t len);
void uart_flush(void);
int printf(const char *fmt, ...);
int snprintf(char *str, size_t size, const char *format, ...);
void uart_init( void );
unsigned char uart_getc( void );
unsigned char uart_gotc( void );
void uart_putc( char c );
void uart_puts( const char *str );
void uart_puthex( uint8_t num );
void uart_trace( void *ptr, uint16_t start, uint16_t len );
void uart_flush( void );
int printf( const char *fmt, ... );
int snprintf( char *str, size_t size, const char *format, ... );
#define uart_putcrlf() uart_putc('\n')
/* A few symbols to make this code work for all four UARTs */

View File

@ -31,463 +31,484 @@
#if _CODE_PAGE == 437
#define _TBLDEF 1
static
const WCHAR Tbl[] = { /* CP437(0x80-0xFF) to Unicode conversion table */
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
0x00FF, 0x00D6, 0x00DC, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4,
0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248,
0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
const WCHAR Tbl[] = /* CP437(0x80-0xFF) to Unicode conversion table */
{
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
0x00FF, 0x00D6, 0x00DC, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4,
0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248,
0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
};
#elif _CODE_PAGE == 720
#define _TBLDEF 1
static
const WCHAR Tbl[] = { /* CP720(0x80-0xFF) to Unicode conversion table */
0x0000, 0x0000, 0x00E9, 0x00E2, 0x0000, 0x00E0, 0x0000, 0x00E7,
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0000, 0x0000, 0x0000,
0x0000, 0x0651, 0x0652, 0x00F4, 0x00A4, 0x0640, 0x00FB, 0x00F9,
0x0621, 0x0622, 0x0623, 0x0624, 0x00A3, 0x0625, 0x0626, 0x0627,
0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F,
0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
0x0636, 0x0637, 0x0638, 0x0639, 0x063A, 0x0641, 0x00B5, 0x0642,
0x0643, 0x0644, 0x0645, 0x0646, 0x0647, 0x0648, 0x0649, 0x064A,
0x2261, 0x064B, 0x064C, 0x064D, 0x064E, 0x064F, 0xO650, 0x2248,
0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
const WCHAR Tbl[] = /* CP720(0x80-0xFF) to Unicode conversion table */
{
0x0000, 0x0000, 0x00E9, 0x00E2, 0x0000, 0x00E0, 0x0000, 0x00E7,
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0000, 0x0000, 0x0000,
0x0000, 0x0651, 0x0652, 0x00F4, 0x00A4, 0x0640, 0x00FB, 0x00F9,
0x0621, 0x0622, 0x0623, 0x0624, 0x00A3, 0x0625, 0x0626, 0x0627,
0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F,
0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
0x0636, 0x0637, 0x0638, 0x0639, 0x063A, 0x0641, 0x00B5, 0x0642,
0x0643, 0x0644, 0x0645, 0x0646, 0x0647, 0x0648, 0x0649, 0x064A,
0x2261, 0x064B, 0x064C, 0x064D, 0x064E, 0x064F, 0xO650, 0x2248,
0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
};
#elif _CODE_PAGE == 737
#define _TBLDEF 1
static
const WCHAR Tbl[] = { /* CP737(0x80-0xFF) to Unicode conversion table */
0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398,
0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, 0x03A0,
0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9,
0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, 0x03B8,
0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0,
0x03C1, 0x03C3, 0x03C2, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
0x03C9, 0x03AC, 0x03AD, 0x03AE, 0x03CA, 0x03AF, 0x03CC, 0x03CD,
0x03CB, 0x03CE, 0x0386, 0x0388, 0x0389, 0x038A, 0x038C, 0x038E,
0x038F, 0x00B1, 0x2265, 0x2264, 0x03AA, 0x03AB, 0x00F7, 0x2248,
0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
const WCHAR Tbl[] = /* CP737(0x80-0xFF) to Unicode conversion table */
{
0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398,
0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, 0x03A0,
0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9,
0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, 0x03B8,
0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0,
0x03C1, 0x03C3, 0x03C2, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
0x03C9, 0x03AC, 0x03AD, 0x03AE, 0x03CA, 0x03AF, 0x03CC, 0x03CD,
0x03CB, 0x03CE, 0x0386, 0x0388, 0x0389, 0x038A, 0x038C, 0x038E,
0x038F, 0x00B1, 0x2265, 0x2264, 0x03AA, 0x03AB, 0x00F7, 0x2248,
0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
};
#elif _CODE_PAGE == 775
#define _TBLDEF 1
static
const WCHAR Tbl[] = { /* CP775(0x80-0xFF) to Unicode conversion table */
0x0106, 0x00FC, 0x00E9, 0x0101, 0x00E4, 0x0123, 0x00E5, 0x0107,
0x0142, 0x0113, 0x0156, 0x0157, 0x012B, 0x0179, 0x00C4, 0x00C5,
0x00C9, 0x00E6, 0x00C6, 0x014D, 0x00F6, 0x0122, 0x00A2, 0x015A,
0x015B, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x00A4,
0x0100, 0x012A, 0x00F3, 0x017B, 0x017C, 0x017A, 0x201D, 0x00A6,
0x00A9, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x0141, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0104, 0x010C, 0x0118,
0x0116, 0x2563, 0x2551, 0x2557, 0x255D, 0x012E, 0x0160, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0172, 0x016A,
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x017D,
0x0105, 0x010D, 0x0119, 0x0117, 0x012F, 0x0161, 0x0173, 0x016B,
0x017E, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
0x00D3, 0x00DF, 0x014C, 0x0143, 0x00F5, 0x00D5, 0x00B5, 0x0144,
0x0136, 0x0137, 0x013B, 0x013C, 0x0146, 0x0112, 0x0145, 0x2019,
0x00AD, 0x00B1, 0x201C, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x201E,
0x00B0, 0x2219, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
const WCHAR Tbl[] = /* CP775(0x80-0xFF) to Unicode conversion table */
{
0x0106, 0x00FC, 0x00E9, 0x0101, 0x00E4, 0x0123, 0x00E5, 0x0107,
0x0142, 0x0113, 0x0156, 0x0157, 0x012B, 0x0179, 0x00C4, 0x00C5,
0x00C9, 0x00E6, 0x00C6, 0x014D, 0x00F6, 0x0122, 0x00A2, 0x015A,
0x015B, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x00A4,
0x0100, 0x012A, 0x00F3, 0x017B, 0x017C, 0x017A, 0x201D, 0x00A6,
0x00A9, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x0141, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0104, 0x010C, 0x0118,
0x0116, 0x2563, 0x2551, 0x2557, 0x255D, 0x012E, 0x0160, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0172, 0x016A,
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x017D,
0x0105, 0x010D, 0x0119, 0x0117, 0x012F, 0x0161, 0x0173, 0x016B,
0x017E, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
0x00D3, 0x00DF, 0x014C, 0x0143, 0x00F5, 0x00D5, 0x00B5, 0x0144,
0x0136, 0x0137, 0x013B, 0x013C, 0x0146, 0x0112, 0x0145, 0x2019,
0x00AD, 0x00B1, 0x201C, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x201E,
0x00B0, 0x2219, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
};
#elif _CODE_PAGE == 850
#define _TBLDEF 1
static
const WCHAR Tbl[] = { /* CP850(0x80-0xFF) to Unicode conversion table */
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192,
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0,
0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3,
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x0131, 0x00CD, 0x00CE,
0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580,
0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE,
0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4,
0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8,
0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
const WCHAR Tbl[] = /* CP850(0x80-0xFF) to Unicode conversion table */
{
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192,
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0,
0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3,
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x0131, 0x00CD, 0x00CE,
0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580,
0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE,
0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4,
0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8,
0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
};
#elif _CODE_PAGE == 852
#define _TBLDEF 1
static
const WCHAR Tbl[] = { /* CP852(0x80-0xFF) to Unicode conversion table */
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x016F, 0x0107, 0x00E7,
0x0142, 0x00EB, 0x0150, 0x0151, 0x00EE, 0x0179, 0x00C4, 0x0106,
0x00C9, 0x0139, 0x013A, 0x00F4, 0x00F6, 0x013D, 0x013E, 0x015A,
0x015B, 0x00D6, 0x00DC, 0x0164, 0x0165, 0x0141, 0x00D7, 0x010D,
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x0104, 0x0105, 0x017D, 0x017E,
0x0118, 0x0119, 0x00AC, 0x017A, 0x010C, 0x015F, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x011A,
0x015E, 0x2563, 0x2551, 0x2557, 0x255D, 0x017B, 0x017C, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0102, 0x0103,
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
0x0111, 0x0110, 0x010E, 0x00CB, 0x010F, 0x0147, 0x00CD, 0x00CE,
0x011B, 0x2518, 0x250C, 0x2588, 0x2584, 0x0162, 0x016E, 0x2580,
0x00D3, 0x00DF, 0x00D4, 0x0143, 0x0144, 0x0148, 0x0160, 0x0161,
0x0154, 0x00DA, 0x0155, 0x0170, 0x00FD, 0x00DD, 0x0163, 0x00B4,
0x00AD, 0x02DD, 0x02DB, 0x02C7, 0x02D8, 0x00A7, 0x00F7, 0x00B8,
0x00B0, 0x00A8, 0x02D9, 0x0171, 0x0158, 0x0159, 0x25A0, 0x00A0
const WCHAR Tbl[] = /* CP852(0x80-0xFF) to Unicode conversion table */
{
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x016F, 0x0107, 0x00E7,
0x0142, 0x00EB, 0x0150, 0x0151, 0x00EE, 0x0179, 0x00C4, 0x0106,
0x00C9, 0x0139, 0x013A, 0x00F4, 0x00F6, 0x013D, 0x013E, 0x015A,
0x015B, 0x00D6, 0x00DC, 0x0164, 0x0165, 0x0141, 0x00D7, 0x010D,
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x0104, 0x0105, 0x017D, 0x017E,
0x0118, 0x0119, 0x00AC, 0x017A, 0x010C, 0x015F, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x011A,
0x015E, 0x2563, 0x2551, 0x2557, 0x255D, 0x017B, 0x017C, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0102, 0x0103,
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
0x0111, 0x0110, 0x010E, 0x00CB, 0x010F, 0x0147, 0x00CD, 0x00CE,
0x011B, 0x2518, 0x250C, 0x2588, 0x2584, 0x0162, 0x016E, 0x2580,
0x00D3, 0x00DF, 0x00D4, 0x0143, 0x0144, 0x0148, 0x0160, 0x0161,
0x0154, 0x00DA, 0x0155, 0x0170, 0x00FD, 0x00DD, 0x0163, 0x00B4,
0x00AD, 0x02DD, 0x02DB, 0x02C7, 0x02D8, 0x00A7, 0x00F7, 0x00B8,
0x00B0, 0x00A8, 0x02D9, 0x0171, 0x0158, 0x0159, 0x25A0, 0x00A0
};
#elif _CODE_PAGE == 855
#define _TBLDEF 1
static
const WCHAR Tbl[] = { /* CP855(0x80-0xFF) to Unicode conversion table */
0x0452, 0x0402, 0x0453, 0x0403, 0x0451, 0x0401, 0x0454, 0x0404,
0x0455, 0x0405, 0x0456, 0x0406, 0x0457, 0x0407, 0x0458, 0x0408,
0x0459, 0x0409, 0x045A, 0x040A, 0x045B, 0x040B, 0x045C, 0x040C,
0x045E, 0x040E, 0x045F, 0x040F, 0x044E, 0x042E, 0x044A, 0x042A,
0x0430, 0x0410, 0x0431, 0x0411, 0x0446, 0x0426, 0x0434, 0x0414,
0x0435, 0x0415, 0x0444, 0x0424, 0x0433, 0x0413, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0445, 0x0425, 0x0438,
0x0418, 0x2563, 0x2551, 0x2557, 0x255D, 0x0439, 0x0419, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x043A, 0x041A,
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
0x043B, 0x041B, 0x043C, 0x041C, 0x043D, 0x041D, 0x043E, 0x041E,
0x043F, 0x2518, 0x250C, 0x2588, 0x2584, 0x041F, 0x044F, 0x2580,
0x042F, 0x0440, 0x0420, 0x0441, 0x0421, 0x0442, 0x0422, 0x0443,
0x0423, 0x0436, 0x0416, 0x0432, 0x0412, 0x044C, 0x042C, 0x2116,
0x00AD, 0x044B, 0x042B, 0x0437, 0x0417, 0x0448, 0x0428, 0x044D,
0x042D, 0x0449, 0x0429, 0x0447, 0x0427, 0x00A7, 0x25A0, 0x00A0
const WCHAR Tbl[] = /* CP855(0x80-0xFF) to Unicode conversion table */
{
0x0452, 0x0402, 0x0453, 0x0403, 0x0451, 0x0401, 0x0454, 0x0404,
0x0455, 0x0405, 0x0456, 0x0406, 0x0457, 0x0407, 0x0458, 0x0408,
0x0459, 0x0409, 0x045A, 0x040A, 0x045B, 0x040B, 0x045C, 0x040C,
0x045E, 0x040E, 0x045F, 0x040F, 0x044E, 0x042E, 0x044A, 0x042A,
0x0430, 0x0410, 0x0431, 0x0411, 0x0446, 0x0426, 0x0434, 0x0414,
0x0435, 0x0415, 0x0444, 0x0424, 0x0433, 0x0413, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0445, 0x0425, 0x0438,
0x0418, 0x2563, 0x2551, 0x2557, 0x255D, 0x0439, 0x0419, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x043A, 0x041A,
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
0x043B, 0x041B, 0x043C, 0x041C, 0x043D, 0x041D, 0x043E, 0x041E,
0x043F, 0x2518, 0x250C, 0x2588, 0x2584, 0x041F, 0x044F, 0x2580,
0x042F, 0x0440, 0x0420, 0x0441, 0x0421, 0x0442, 0x0422, 0x0443,
0x0423, 0x0436, 0x0416, 0x0432, 0x0412, 0x044C, 0x042C, 0x2116,
0x00AD, 0x044B, 0x042B, 0x0437, 0x0417, 0x0448, 0x0428, 0x044D,
0x042D, 0x0449, 0x0429, 0x0447, 0x0427, 0x00A7, 0x25A0, 0x00A0
};
#elif _CODE_PAGE == 857
#define _TBLDEF 1
static
const WCHAR Tbl[] = { /* CP857(0x80-0xFF) to Unicode conversion table */
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0131, 0x00C4, 0x00C5,
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
0x0130, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x015E, 0x015F,
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x011E, 0x011F,
0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0,
0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3,
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
0x00BA, 0x00AA, 0x00CA, 0x00CB, 0x00C8, 0x0000, 0x00CD, 0x00CE,
0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580,
0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x0000,
0x00D7, 0x00DA, 0x00DB, 0x00D9, 0x00EC, 0x00FF, 0x00AF, 0x00B4,
0x00AD, 0x00B1, 0x0000, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8,
0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
const WCHAR Tbl[] = /* CP857(0x80-0xFF) to Unicode conversion table */
{
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0131, 0x00C4, 0x00C5,
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
0x0130, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x015E, 0x015F,
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x011E, 0x011F,
0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0,
0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3,
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
0x00BA, 0x00AA, 0x00CA, 0x00CB, 0x00C8, 0x0000, 0x00CD, 0x00CE,
0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580,
0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x0000,
0x00D7, 0x00DA, 0x00DB, 0x00D9, 0x00EC, 0x00FF, 0x00AF, 0x00B4,
0x00AD, 0x00B1, 0x0000, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8,
0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
};
#elif _CODE_PAGE == 858
#define _TBLDEF 1
static
const WCHAR Tbl[] = { /* CP858(0x80-0xFF) to Unicode conversion table */
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192,
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0,
0x00A9, 0x2563, 0x2551, 0x2557, 0x2550, 0x00A2, 0x00A5, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3,
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x20AC, 0x00CD, 0x00CE,
0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00C6, 0x00CC, 0x2580,
0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE,
0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4,
0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8,
0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
const WCHAR Tbl[] = /* CP858(0x80-0xFF) to Unicode conversion table */
{
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192,
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0,
0x00A9, 0x2563, 0x2551, 0x2557, 0x2550, 0x00A2, 0x00A5, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3,
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x20AC, 0x00CD, 0x00CE,
0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00C6, 0x00CC, 0x2580,
0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE,
0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4,
0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8,
0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
};
#elif _CODE_PAGE == 862
#define _TBLDEF 1
static
const WCHAR Tbl[] = { /* CP862(0x80-0xFF) to Unicode conversion table */
0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7,
0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,
0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7,
0x05E8, 0x05E9, 0x05EA, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4,
0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248,
0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
const WCHAR Tbl[] = /* CP862(0x80-0xFF) to Unicode conversion table */
{
0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7,
0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,
0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7,
0x05E8, 0x05E9, 0x05EA, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4,
0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248,
0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
};
#elif _CODE_PAGE == 866
#define _TBLDEF 1
static
const WCHAR Tbl[] = { /* CP866(0x80-0xFF) to Unicode conversion table */
0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
0x0401, 0x0451, 0x0404, 0x0454, 0x0407, 0x0457, 0x040E, 0x045E,
0x00B0, 0x2219, 0x00B7, 0x221A, 0x2116, 0x00A4, 0x25A0, 0x00A0
const WCHAR Tbl[] = /* CP866(0x80-0xFF) to Unicode conversion table */
{
0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
0x0401, 0x0451, 0x0404, 0x0454, 0x0407, 0x0457, 0x040E, 0x045E,
0x00B0, 0x2219, 0x00B7, 0x221A, 0x2116, 0x00A4, 0x25A0, 0x00A0
};
#elif _CODE_PAGE == 874
#define _TBLDEF 1
static
const WCHAR Tbl[] = { /* CP874(0x80-0xFF) to Unicode conversion table */
0x20AC, 0x0000, 0x0000, 0x0000, 0x0000, 0x2026, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x00A0, 0x0E01, 0x0E02, 0x0E03, 0x0E04, 0x0E05, 0x0E06, 0x0E07,
0x0E08, 0x0E09, 0x0E0A, 0x0E0B, 0x0E0C, 0x0E0D, 0x0E0E, 0x0E0F,
0x0E10, 0x0E11, 0x0E12, 0x0E13, 0x0E14, 0x0E15, 0x0E16, 0x0E17,
0x0E18, 0x0E19, 0x0E1A, 0x0E1B, 0x0E1C, 0x0E1D, 0x0E1E, 0x0E1F,
0x0E20, 0x0E21, 0x0E22, 0x0E23, 0x0E24, 0x0E25, 0x0E26, 0x0E27,
0x0E28, 0x0E29, 0x0E2A, 0x0E2B, 0x0E2C, 0x0E2D, 0x0E2E, 0x0E2F,
0x0E30, 0x0E31, 0x0E32, 0x0E33, 0x0E34, 0x0E35, 0x0E36, 0x0E37,
0x0E38, 0x0E39, 0x0E3A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0E3F,
0x0E40, 0x0E41, 0x0E42, 0x0E43, 0x0E44, 0x0E45, 0x0E46, 0x0E47,
0x0E48, 0x0E49, 0x0E4A, 0x0E4B, 0x0E4C, 0x0E4D, 0x0E4E, 0x0E4F,
0x0E50, 0x0E51, 0x0E52, 0x0E53, 0x0E54, 0x0E55, 0x0E56, 0x0E57,
0x0E58, 0x0E59, 0x0E5A, 0x0E5B, 0x0000, 0x0000, 0x0000, 0x0000
const WCHAR Tbl[] = /* CP874(0x80-0xFF) to Unicode conversion table */
{
0x20AC, 0x0000, 0x0000, 0x0000, 0x0000, 0x2026, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x00A0, 0x0E01, 0x0E02, 0x0E03, 0x0E04, 0x0E05, 0x0E06, 0x0E07,
0x0E08, 0x0E09, 0x0E0A, 0x0E0B, 0x0E0C, 0x0E0D, 0x0E0E, 0x0E0F,
0x0E10, 0x0E11, 0x0E12, 0x0E13, 0x0E14, 0x0E15, 0x0E16, 0x0E17,
0x0E18, 0x0E19, 0x0E1A, 0x0E1B, 0x0E1C, 0x0E1D, 0x0E1E, 0x0E1F,
0x0E20, 0x0E21, 0x0E22, 0x0E23, 0x0E24, 0x0E25, 0x0E26, 0x0E27,
0x0E28, 0x0E29, 0x0E2A, 0x0E2B, 0x0E2C, 0x0E2D, 0x0E2E, 0x0E2F,
0x0E30, 0x0E31, 0x0E32, 0x0E33, 0x0E34, 0x0E35, 0x0E36, 0x0E37,
0x0E38, 0x0E39, 0x0E3A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0E3F,
0x0E40, 0x0E41, 0x0E42, 0x0E43, 0x0E44, 0x0E45, 0x0E46, 0x0E47,
0x0E48, 0x0E49, 0x0E4A, 0x0E4B, 0x0E4C, 0x0E4D, 0x0E4E, 0x0E4F,
0x0E50, 0x0E51, 0x0E52, 0x0E53, 0x0E54, 0x0E55, 0x0E56, 0x0E57,
0x0E58, 0x0E59, 0x0E5A, 0x0E5B, 0x0000, 0x0000, 0x0000, 0x0000
};
#elif _CODE_PAGE == 1250
#define _TBLDEF 1
static
const WCHAR Tbl[] = { /* CP1250(0x80-0xFF) to Unicode conversion table */
0x20AC, 0x0000, 0x201A, 0x0000, 0x201E, 0x2026, 0x2020, 0x2021,
0x0000, 0x2030, 0x0160, 0x2039, 0x015A, 0x0164, 0x017D, 0x0179,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x0000, 0x2122, 0x0161, 0x203A, 0x015B, 0x0165, 0x017E, 0x017A,
0x00A0, 0x02C7, 0x02D8, 0x0141, 0x00A4, 0x0104, 0x00A6, 0x00A7,
0x00A8, 0x00A9, 0x015E, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x017B,
0x00B0, 0x00B1, 0x02DB, 0x0142, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
0x00B8, 0x0105, 0x015F, 0x00BB, 0x013D, 0x02DD, 0x013E, 0x017C,
0x0154, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0139, 0x0106, 0x00C7,
0x010C, 0x00C9, 0x0118, 0x00CB, 0x011A, 0x00CD, 0x00CE, 0x010E,
0x0110, 0x0143, 0x0147, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x00D7,
0x0158, 0x016E, 0x00DA, 0x0170, 0x00DC, 0x00DD, 0x0162, 0x00DF,
0x0155, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x013A, 0x0107, 0x00E7,
0x010D, 0x00E9, 0x0119, 0x00EB, 0x011B, 0x00ED, 0x00EE, 0x010F,
0x0111, 0x0144, 0x0148, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x00F7,
0x0159, 0x016F, 0x00FA, 0x0171, 0x00FC, 0x00FD, 0x0163, 0x02D9
const WCHAR Tbl[] = /* CP1250(0x80-0xFF) to Unicode conversion table */
{
0x20AC, 0x0000, 0x201A, 0x0000, 0x201E, 0x2026, 0x2020, 0x2021,
0x0000, 0x2030, 0x0160, 0x2039, 0x015A, 0x0164, 0x017D, 0x0179,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x0000, 0x2122, 0x0161, 0x203A, 0x015B, 0x0165, 0x017E, 0x017A,
0x00A0, 0x02C7, 0x02D8, 0x0141, 0x00A4, 0x0104, 0x00A6, 0x00A7,
0x00A8, 0x00A9, 0x015E, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x017B,
0x00B0, 0x00B1, 0x02DB, 0x0142, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
0x00B8, 0x0105, 0x015F, 0x00BB, 0x013D, 0x02DD, 0x013E, 0x017C,
0x0154, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0139, 0x0106, 0x00C7,
0x010C, 0x00C9, 0x0118, 0x00CB, 0x011A, 0x00CD, 0x00CE, 0x010E,
0x0110, 0x0143, 0x0147, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x00D7,
0x0158, 0x016E, 0x00DA, 0x0170, 0x00DC, 0x00DD, 0x0162, 0x00DF,
0x0155, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x013A, 0x0107, 0x00E7,
0x010D, 0x00E9, 0x0119, 0x00EB, 0x011B, 0x00ED, 0x00EE, 0x010F,
0x0111, 0x0144, 0x0148, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x00F7,
0x0159, 0x016F, 0x00FA, 0x0171, 0x00FC, 0x00FD, 0x0163, 0x02D9
};
#elif _CODE_PAGE == 1251
#define _TBLDEF 1
static
const WCHAR Tbl[] = { /* CP1251(0x80-0xFF) to Unicode conversion table */
0x0402, 0x0403, 0x201A, 0x0453, 0x201E, 0x2026, 0x2020, 0x2021,
0x20AC, 0x2030, 0x0409, 0x2039, 0x040A, 0x040C, 0x040B, 0x040F,
0x0452, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x0000, 0x2111, 0x0459, 0x203A, 0x045A, 0x045C, 0x045B, 0x045F,
0x00A0, 0x040E, 0x045E, 0x0408, 0x00A4, 0x0490, 0x00A6, 0x00A7,
0x0401, 0x00A9, 0x0404, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x0407,
0x00B0, 0x00B1, 0x0406, 0x0456, 0x0491, 0x00B5, 0x00B6, 0x00B7,
0x0451, 0x2116, 0x0454, 0x00BB, 0x0458, 0x0405, 0x0455, 0x0457,
0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F
const WCHAR Tbl[] = /* CP1251(0x80-0xFF) to Unicode conversion table */
{
0x0402, 0x0403, 0x201A, 0x0453, 0x201E, 0x2026, 0x2020, 0x2021,
0x20AC, 0x2030, 0x0409, 0x2039, 0x040A, 0x040C, 0x040B, 0x040F,
0x0452, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x0000, 0x2111, 0x0459, 0x203A, 0x045A, 0x045C, 0x045B, 0x045F,
0x00A0, 0x040E, 0x045E, 0x0408, 0x00A4, 0x0490, 0x00A6, 0x00A7,
0x0401, 0x00A9, 0x0404, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x0407,
0x00B0, 0x00B1, 0x0406, 0x0456, 0x0491, 0x00B5, 0x00B6, 0x00B7,
0x0451, 0x2116, 0x0454, 0x00BB, 0x0458, 0x0405, 0x0455, 0x0457,
0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F
};
#elif _CODE_PAGE == 1252
#define _TBLDEF 1
static
const WCHAR Tbl[] = { /* CP1252(0x80-0xFF) to Unicode conversion table */
0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x017D, 0x0000,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x0000, 0x017E, 0x0178,
0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF,
0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF
const WCHAR Tbl[] = /* CP1252(0x80-0xFF) to Unicode conversion table */
{
0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x017D, 0x0000,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x0000, 0x017E, 0x0178,
0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF,
0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF
};
#elif _CODE_PAGE == 1253
#define _TBLDEF 1
static
const WCHAR Tbl[] = { /* CP1253(0x80-0xFF) to Unicode conversion table */
0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
0x0000, 0x2030, 0x0000, 0x2039, 0x000C, 0x0000, 0x0000, 0x0000,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x0000, 0x2122, 0x0000, 0x203A, 0x0000, 0x0000, 0x0000, 0x0000,
0x00A0, 0x0385, 0x0386, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
0x00A8, 0x00A9, 0x0000, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x2015,
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x0384, 0x00B5, 0x00B6, 0x00B7,
0x0388, 0x0389, 0x038A, 0x00BB, 0x038C, 0x00BD, 0x038E, 0x038F,
0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397,
0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F,
0x03A0, 0x03A1, 0x0000, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7,
0x03A8, 0x03A9, 0x03AA, 0x03AD, 0x03AC, 0x03AD, 0x03AE, 0x03AF,
0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7,
0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF,
0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7,
0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, 0x0000
const WCHAR Tbl[] = /* CP1253(0x80-0xFF) to Unicode conversion table */
{
0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
0x0000, 0x2030, 0x0000, 0x2039, 0x000C, 0x0000, 0x0000, 0x0000,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x0000, 0x2122, 0x0000, 0x203A, 0x0000, 0x0000, 0x0000, 0x0000,
0x00A0, 0x0385, 0x0386, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
0x00A8, 0x00A9, 0x0000, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x2015,
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x0384, 0x00B5, 0x00B6, 0x00B7,
0x0388, 0x0389, 0x038A, 0x00BB, 0x038C, 0x00BD, 0x038E, 0x038F,
0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397,
0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F,
0x03A0, 0x03A1, 0x0000, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7,
0x03A8, 0x03A9, 0x03AA, 0x03AD, 0x03AC, 0x03AD, 0x03AE, 0x03AF,
0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7,
0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF,
0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7,
0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, 0x0000
};
#elif _CODE_PAGE == 1254
#define _TBLDEF 1
static
const WCHAR Tbl[] = { /* CP1254(0x80-0xFF) to Unicode conversion table */
0x20AC, 0x0000, 0x210A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x0000, 0x0000,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x0000, 0x0000, 0x0178,
0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
0x011E, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
0x00D8, 0x00D9, 0x00DA, 0x00BD, 0x00DC, 0x0130, 0x015E, 0x00DF,
0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
0x011F, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x0131, 0x015F, 0x00FF
const WCHAR Tbl[] = /* CP1254(0x80-0xFF) to Unicode conversion table */
{
0x20AC, 0x0000, 0x210A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x0000, 0x0000,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x0000, 0x0000, 0x0178,
0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
0x011E, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
0x00D8, 0x00D9, 0x00DA, 0x00BD, 0x00DC, 0x0130, 0x015E, 0x00DF,
0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
0x011F, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x0131, 0x015F, 0x00FF
};
#elif _CODE_PAGE == 1255
#define _TBLDEF 1
static
const WCHAR Tbl[] = { /* CP1255(0x80-0xFF) to Unicode conversion table */
0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
0x02C6, 0x2030, 0x0000, 0x2039, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x02DC, 0x2122, 0x0000, 0x203A, 0x0000, 0x0000, 0x0000, 0x0000,
0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
0x00A8, 0x00A9, 0x00D7, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
0x00B8, 0x00B9, 0x00F7, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
0x05B0, 0x05B1, 0x05B2, 0x05B3, 0x05B4, 0x05B5, 0x05B6, 0x05B7,
0x05B8, 0x05B9, 0x0000, 0x05BB, 0x05BC, 0x05BD, 0x05BE, 0x05BF,
0x05C0, 0x05C1, 0x05C2, 0x05C3, 0x05F0, 0x05F1, 0x05F2, 0x05F3,
0x05F4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7,
0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,
0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7,
0x05E8, 0x05E9, 0x05EA, 0x0000, 0x0000, 0x200E, 0x200F, 0x0000
const WCHAR Tbl[] = /* CP1255(0x80-0xFF) to Unicode conversion table */
{
0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
0x02C6, 0x2030, 0x0000, 0x2039, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x02DC, 0x2122, 0x0000, 0x203A, 0x0000, 0x0000, 0x0000, 0x0000,
0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
0x00A8, 0x00A9, 0x00D7, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
0x00B8, 0x00B9, 0x00F7, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
0x05B0, 0x05B1, 0x05B2, 0x05B3, 0x05B4, 0x05B5, 0x05B6, 0x05B7,
0x05B8, 0x05B9, 0x0000, 0x05BB, 0x05BC, 0x05BD, 0x05BE, 0x05BF,
0x05C0, 0x05C1, 0x05C2, 0x05C3, 0x05F0, 0x05F1, 0x05F2, 0x05F3,
0x05F4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7,
0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,
0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7,
0x05E8, 0x05E9, 0x05EA, 0x0000, 0x0000, 0x200E, 0x200F, 0x0000
};
#elif _CODE_PAGE == 1256
#define _TBLDEF 1
static
const WCHAR Tbl[] = { /* CP1256(0x80-0xFF) to Unicode conversion table */
0x20AC, 0x067E, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
0x02C6, 0x2030, 0x0679, 0x2039, 0x0152, 0x0686, 0x0698, 0x0688,
0x06AF, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x06A9, 0x2122, 0x0691, 0x203A, 0x0153, 0x200C, 0x200D, 0x06BA,
0x00A0, 0x060C, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
0x00A8, 0x00A9, 0x06BE, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
0x00B8, 0x00B9, 0x061B, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x061F,
0x06C1, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627,
0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F,
0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x00D7,
0x0637, 0x0638, 0x0639, 0x063A, 0x0640, 0x0640, 0x0642, 0x0643,
0x00E0, 0x0644, 0x00E2, 0x0645, 0x0646, 0x0647, 0x0648, 0x00E7,
0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x0649, 0x064A, 0x00EE, 0x00EF,
0x064B, 0x064C, 0x064D, 0x064E, 0x00F4, 0x064F, 0x0650, 0x00F7,
0x0651, 0x00F9, 0x0652, 0x00FB, 0x00FC, 0x200E, 0x200F, 0x06D2
const WCHAR Tbl[] = /* CP1256(0x80-0xFF) to Unicode conversion table */
{
0x20AC, 0x067E, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
0x02C6, 0x2030, 0x0679, 0x2039, 0x0152, 0x0686, 0x0698, 0x0688,
0x06AF, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x06A9, 0x2122, 0x0691, 0x203A, 0x0153, 0x200C, 0x200D, 0x06BA,
0x00A0, 0x060C, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
0x00A8, 0x00A9, 0x06BE, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
0x00B8, 0x00B9, 0x061B, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x061F,
0x06C1, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627,
0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F,
0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x00D7,
0x0637, 0x0638, 0x0639, 0x063A, 0x0640, 0x0640, 0x0642, 0x0643,
0x00E0, 0x0644, 0x00E2, 0x0645, 0x0646, 0x0647, 0x0648, 0x00E7,
0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x0649, 0x064A, 0x00EE, 0x00EF,
0x064B, 0x064C, 0x064D, 0x064E, 0x00F4, 0x064F, 0x0650, 0x00F7,
0x0651, 0x00F9, 0x0652, 0x00FB, 0x00FC, 0x200E, 0x200F, 0x06D2
}
#elif _CODE_PAGE == 1257
#define _TBLDEF 1
static
const WCHAR Tbl[] = { /* CP1257(0x80-0xFF) to Unicode conversion table */
0x20AC, 0x0000, 0x201A, 0x0000, 0x201E, 0x2026, 0x2020, 0x2021,
0x0000, 0x2030, 0x0000, 0x2039, 0x0000, 0x00A8, 0x02C7, 0x00B8,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x0000, 0x2122, 0x0000, 0x203A, 0x0000, 0x00AF, 0x02DB, 0x0000,
0x00A0, 0x0000, 0x00A2, 0x00A3, 0x00A4, 0x0000, 0x00A6, 0x00A7,
0x00D8, 0x00A9, 0x0156, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
0x00B8, 0x00B9, 0x0157, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00E6,
0x0104, 0x012E, 0x0100, 0x0106, 0x00C4, 0x00C5, 0x0118, 0x0112,
0x010C, 0x00C9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012A, 0x013B,
0x0160, 0x0143, 0x0145, 0x00D3, 0x014C, 0x00D5, 0x00D6, 0x00D7,
0x0172, 0x0141, 0x015A, 0x016A, 0x00DC, 0x017B, 0x017D, 0x00DF,
0x0105, 0x012F, 0x0101, 0x0107, 0x00E4, 0x00E5, 0x0119, 0x0113,
0x010D, 0x00E9, 0x017A, 0x0117, 0x0123, 0x0137, 0x012B, 0x013C,
0x0161, 0x0144, 0x0146, 0x00F3, 0x014D, 0x00F5, 0x00F6, 0x00F7,
0x0173, 0x014E, 0x015B, 0x016B, 0x00FC, 0x017C, 0x017E, 0x02D9
const WCHAR Tbl[] = /* CP1257(0x80-0xFF) to Unicode conversion table */
{
0x20AC, 0x0000, 0x201A, 0x0000, 0x201E, 0x2026, 0x2020, 0x2021,
0x0000, 0x2030, 0x0000, 0x2039, 0x0000, 0x00A8, 0x02C7, 0x00B8,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x0000, 0x2122, 0x0000, 0x203A, 0x0000, 0x00AF, 0x02DB, 0x0000,
0x00A0, 0x0000, 0x00A2, 0x00A3, 0x00A4, 0x0000, 0x00A6, 0x00A7,
0x00D8, 0x00A9, 0x0156, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
0x00B8, 0x00B9, 0x0157, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00E6,
0x0104, 0x012E, 0x0100, 0x0106, 0x00C4, 0x00C5, 0x0118, 0x0112,
0x010C, 0x00C9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012A, 0x013B,
0x0160, 0x0143, 0x0145, 0x00D3, 0x014C, 0x00D5, 0x00D6, 0x00D7,
0x0172, 0x0141, 0x015A, 0x016A, 0x00DC, 0x017B, 0x017D, 0x00DF,
0x0105, 0x012F, 0x0101, 0x0107, 0x00E4, 0x00E5, 0x0119, 0x0113,
0x010D, 0x00E9, 0x017A, 0x0117, 0x0123, 0x0137, 0x012B, 0x013C,
0x0161, 0x0144, 0x0146, 0x00F3, 0x014D, 0x00F5, 0x00F6, 0x00F7,
0x0173, 0x014E, 0x015B, 0x016B, 0x00FC, 0x017C, 0x017E, 0x02D9
};
#elif _CODE_PAGE == 1258
#define _TBLDEF 1
static
const WCHAR Tbl[] = { /* CP1258(0x80-0xFF) to Unicode conversion table */
0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
0x02C6, 0x2030, 0x0000, 0x2039, 0x0152, 0x0000, 0x0000, 0x0000,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x02DC, 0x2122, 0x0000, 0x203A, 0x0153, 0x0000, 0x0000, 0x0178,
0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
0x00C0, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x0300, 0x00CD, 0x00CE, 0x00CF,
0x0110, 0x00D1, 0x0309, 0x00D3, 0x00D4, 0x01A0, 0x00D6, 0x00D7,
0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x01AF, 0x0303, 0x00DF,
0x00E0, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x0301, 0x00ED, 0x00EE, 0x00EF,
0x0111, 0x00F1, 0x0323, 0x00F3, 0x00F4, 0x01A1, 0x00F6, 0x00F7,
0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x01B0, 0x20AB, 0x00FF
const WCHAR Tbl[] = /* CP1258(0x80-0xFF) to Unicode conversion table */
{
0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
0x02C6, 0x2030, 0x0000, 0x2039, 0x0152, 0x0000, 0x0000, 0x0000,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x02DC, 0x2122, 0x0000, 0x203A, 0x0153, 0x0000, 0x0000, 0x0178,
0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
0x00C0, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x0300, 0x00CD, 0x00CE, 0x00CF,
0x0110, 0x00D1, 0x0309, 0x00D3, 0x00D4, 0x01A0, 0x00D6, 0x00D7,
0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x01AF, 0x0303, 0x00DF,
0x00E0, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x0301, 0x00ED, 0x00EE, 0x00EF,
0x0111, 0x00F1, 0x0323, 0x00F3, 0x00F4, 0x01A1, 0x00F6, 0x00F7,
0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x01B0, 0x20AB, 0x00FF
};
#endif
@ -498,43 +519,54 @@ const WCHAR Tbl[] = { /* CP1258(0x80-0xFF) to Unicode conversion table */
#endif
WCHAR ff_convert ( /* Converted character, Returns zero on error */
WCHAR src, /* Character code to be converted */
UINT dir /* 0: Unicode to OEMCP, 1: OEMCP to Unicode */
WCHAR ff_convert ( /* Converted character, Returns zero on error */
WCHAR src, /* Character code to be converted */
UINT dir /* 0: Unicode to OEMCP, 1: OEMCP to Unicode */
)
{
WCHAR c;
WCHAR c;
if (src < 0x80) { /* ASCII */
c = src;
if ( src < 0x80 ) /* ASCII */
{
c = src;
} else {
if (dir) { /* OEMCP to Unicode */
c = (src >= 0x100) ? 0 : Tbl[src - 0x80];
}
else
{
if ( dir ) /* OEMCP to Unicode */
{
c = ( src >= 0x100 ) ? 0 : Tbl[src - 0x80];
} else { /* Unicode to OEMCP */
for (c = 0; c < 0x80; c++) {
if (src == Tbl[c]) break;
}
c = (c + 0x80) & 0xFF;
}
}
}
else /* Unicode to OEMCP */
{
for ( c = 0; c < 0x80; c++ )
{
if ( src == Tbl[c] )
{
break;
}
}
return c;
c = ( c + 0x80 ) & 0xFF;
}
}
return c;
}
WCHAR ff_wtoupper ( /* Upper converted character */
WCHAR chr /* Input character */
WCHAR ff_wtoupper ( /* Upper converted character */
WCHAR chr /* Input character */
)
{
static const WCHAR tbl_lower[] = { 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0xA1, 0x00A2, 0x00A3, 0x00A5, 0x00AC, 0x00AF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0x0FF, 0x101, 0x103, 0x105, 0x107, 0x109, 0x10B, 0x10D, 0x10F, 0x111, 0x113, 0x115, 0x117, 0x119, 0x11B, 0x11D, 0x11F, 0x121, 0x123, 0x125, 0x127, 0x129, 0x12B, 0x12D, 0x12F, 0x131, 0x133, 0x135, 0x137, 0x13A, 0x13C, 0x13E, 0x140, 0x142, 0x144, 0x146, 0x148, 0x14B, 0x14D, 0x14F, 0x151, 0x153, 0x155, 0x157, 0x159, 0x15B, 0x15D, 0x15F, 0x161, 0x163, 0x165, 0x167, 0x169, 0x16B, 0x16D, 0x16F, 0x171, 0x173, 0x175, 0x177, 0x17A, 0x17C, 0x17E, 0x192, 0x3B1, 0x3B2, 0x3B3, 0x3B4, 0x3B5, 0x3B6, 0x3B7, 0x3B8, 0x3B9, 0x3BA, 0x3BB, 0x3BC, 0x3BD, 0x3BE, 0x3BF, 0x3C0, 0x3C1, 0x3C3, 0x3C4, 0x3C5, 0x3C6, 0x3C7, 0x3C8, 0x3C9, 0x3CA, 0x430, 0x431, 0x432, 0x433, 0x434, 0x435, 0x436, 0x437, 0x438, 0x439, 0x43A, 0x43B, 0x43C, 0x43D, 0x43E, 0x43F, 0x440, 0x441, 0x442, 0x443, 0x444, 0x445, 0x446, 0x447, 0x448, 0x449, 0x44A, 0x44B, 0x44C, 0x44D, 0x44E, 0x44F, 0x451, 0x452, 0x453, 0x454, 0x455, 0x456, 0x457, 0x458, 0x459, 0x45A, 0x45B, 0x45C, 0x45E, 0x45F, 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177, 0x2178, 0x2179, 0x217A, 0x217B, 0x217C, 0x217D, 0x217E, 0x217F, 0xFF41, 0xFF42, 0xFF43, 0xFF44, 0xFF45, 0xFF46, 0xFF47, 0xFF48, 0xFF49, 0xFF4A, 0xFF4B, 0xFF4C, 0xFF4D, 0xFF4E, 0xFF4F, 0xFF50, 0xFF51, 0xFF52, 0xFF53, 0xFF54, 0xFF55, 0xFF56, 0xFF57, 0xFF58, 0xFF59, 0xFF5A, 0 };
static const WCHAR tbl_upper[] = { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x21, 0xFFE0, 0xFFE1, 0xFFE5, 0xFFE2, 0xFFE3, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0x178, 0x100, 0x102, 0x104, 0x106, 0x108, 0x10A, 0x10C, 0x10E, 0x110, 0x112, 0x114, 0x116, 0x118, 0x11A, 0x11C, 0x11E, 0x120, 0x122, 0x124, 0x126, 0x128, 0x12A, 0x12C, 0x12E, 0x130, 0x132, 0x134, 0x136, 0x139, 0x13B, 0x13D, 0x13F, 0x141, 0x143, 0x145, 0x147, 0x14A, 0x14C, 0x14E, 0x150, 0x152, 0x154, 0x156, 0x158, 0x15A, 0x15C, 0x15E, 0x160, 0x162, 0x164, 0x166, 0x168, 0x16A, 0x16C, 0x16E, 0x170, 0x172, 0x174, 0x176, 0x179, 0x17B, 0x17D, 0x191, 0x391, 0x392, 0x393, 0x394, 0x395, 0x396, 0x397, 0x398, 0x399, 0x39A, 0x39B, 0x39C, 0x39D, 0x39E, 0x39F, 0x3A0, 0x3A1, 0x3A3, 0x3A4, 0x3A5, 0x3A6, 0x3A7, 0x3A8, 0x3A9, 0x3AA, 0x410, 0x411, 0x412, 0x413, 0x414, 0x415, 0x416, 0x417, 0x418, 0x419, 0x41A, 0x41B, 0x41C, 0x41D, 0x41E, 0x41F, 0x420, 0x421, 0x422, 0x423, 0x424, 0x425, 0x426, 0x427, 0x428, 0x429, 0x42A, 0x42B, 0x42C, 0x42D, 0x42E, 0x42F, 0x401, 0x402, 0x403, 0x404, 0x405, 0x406, 0x407, 0x408, 0x409, 0x40A, 0x40B, 0x40C, 0x40E, 0x40F, 0x2160, 0x2161, 0x2162, 0x2163, 0x2164, 0x2165, 0x2166, 0x2167, 0x2168, 0x2169, 0x216A, 0x216B, 0x216C, 0x216D, 0x216E, 0x216F, 0xFF21, 0xFF22, 0xFF23, 0xFF24, 0xFF25, 0xFF26, 0xFF27, 0xFF28, 0xFF29, 0xFF2A, 0xFF2B, 0xFF2C, 0xFF2D, 0xFF2E, 0xFF2F, 0xFF30, 0xFF31, 0xFF32, 0xFF33, 0xFF34, 0xFF35, 0xFF36, 0xFF37, 0xFF38, 0xFF39, 0xFF3A, 0 };
int i;
static const WCHAR tbl_lower[] = { 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0xA1, 0x00A2, 0x00A3, 0x00A5, 0x00AC, 0x00AF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0x0FF, 0x101, 0x103, 0x105, 0x107, 0x109, 0x10B, 0x10D, 0x10F, 0x111, 0x113, 0x115, 0x117, 0x119, 0x11B, 0x11D, 0x11F, 0x121, 0x123, 0x125, 0x127, 0x129, 0x12B, 0x12D, 0x12F, 0x131, 0x133, 0x135, 0x137, 0x13A, 0x13C, 0x13E, 0x140, 0x142, 0x144, 0x146, 0x148, 0x14B, 0x14D, 0x14F, 0x151, 0x153, 0x155, 0x157, 0x159, 0x15B, 0x15D, 0x15F, 0x161, 0x163, 0x165, 0x167, 0x169, 0x16B, 0x16D, 0x16F, 0x171, 0x173, 0x175, 0x177, 0x17A, 0x17C, 0x17E, 0x192, 0x3B1, 0x3B2, 0x3B3, 0x3B4, 0x3B5, 0x3B6, 0x3B7, 0x3B8, 0x3B9, 0x3BA, 0x3BB, 0x3BC, 0x3BD, 0x3BE, 0x3BF, 0x3C0, 0x3C1, 0x3C3, 0x3C4, 0x3C5, 0x3C6, 0x3C7, 0x3C8, 0x3C9, 0x3CA, 0x430, 0x431, 0x432, 0x433, 0x434, 0x435, 0x436, 0x437, 0x438, 0x439, 0x43A, 0x43B, 0x43C, 0x43D, 0x43E, 0x43F, 0x440, 0x441, 0x442, 0x443, 0x444, 0x445, 0x446, 0x447, 0x448, 0x449, 0x44A, 0x44B, 0x44C, 0x44D, 0x44E, 0x44F, 0x451, 0x452, 0x453, 0x454, 0x455, 0x456, 0x457, 0x458, 0x459, 0x45A, 0x45B, 0x45C, 0x45E, 0x45F, 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177, 0x2178, 0x2179, 0x217A, 0x217B, 0x217C, 0x217D, 0x217E, 0x217F, 0xFF41, 0xFF42, 0xFF43, 0xFF44, 0xFF45, 0xFF46, 0xFF47, 0xFF48, 0xFF49, 0xFF4A, 0xFF4B, 0xFF4C, 0xFF4D, 0xFF4E, 0xFF4F, 0xFF50, 0xFF51, 0xFF52, 0xFF53, 0xFF54, 0xFF55, 0xFF56, 0xFF57, 0xFF58, 0xFF59, 0xFF5A, 0 };
static const WCHAR tbl_upper[] = { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x21, 0xFFE0, 0xFFE1, 0xFFE5, 0xFFE2, 0xFFE3, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0x178, 0x100, 0x102, 0x104, 0x106, 0x108, 0x10A, 0x10C, 0x10E, 0x110, 0x112, 0x114, 0x116, 0x118, 0x11A, 0x11C, 0x11E, 0x120, 0x122, 0x124, 0x126, 0x128, 0x12A, 0x12C, 0x12E, 0x130, 0x132, 0x134, 0x136, 0x139, 0x13B, 0x13D, 0x13F, 0x141, 0x143, 0x145, 0x147, 0x14A, 0x14C, 0x14E, 0x150, 0x152, 0x154, 0x156, 0x158, 0x15A, 0x15C, 0x15E, 0x160, 0x162, 0x164, 0x166, 0x168, 0x16A, 0x16C, 0x16E, 0x170, 0x172, 0x174, 0x176, 0x179, 0x17B, 0x17D, 0x191, 0x391, 0x392, 0x393, 0x394, 0x395, 0x396, 0x397, 0x398, 0x399, 0x39A, 0x39B, 0x39C, 0x39D, 0x39E, 0x39F, 0x3A0, 0x3A1, 0x3A3, 0x3A4, 0x3A5, 0x3A6, 0x3A7, 0x3A8, 0x3A9, 0x3AA, 0x410, 0x411, 0x412, 0x413, 0x414, 0x415, 0x416, 0x417, 0x418, 0x419, 0x41A, 0x41B, 0x41C, 0x41D, 0x41E, 0x41F, 0x420, 0x421, 0x422, 0x423, 0x424, 0x425, 0x426, 0x427, 0x428, 0x429, 0x42A, 0x42B, 0x42C, 0x42D, 0x42E, 0x42F, 0x401, 0x402, 0x403, 0x404, 0x405, 0x406, 0x407, 0x408, 0x409, 0x40A, 0x40B, 0x40C, 0x40E, 0x40F, 0x2160, 0x2161, 0x2162, 0x2163, 0x2164, 0x2165, 0x2166, 0x2167, 0x2168, 0x2169, 0x216A, 0x216B, 0x216C, 0x216D, 0x216E, 0x216F, 0xFF21, 0xFF22, 0xFF23, 0xFF24, 0xFF25, 0xFF26, 0xFF27, 0xFF28, 0xFF29, 0xFF2A, 0xFF2B, 0xFF2C, 0xFF2D, 0xFF2E, 0xFF2F, 0xFF30, 0xFF31, 0xFF32, 0xFF33, 0xFF34, 0xFF35, 0xFF36, 0xFF37, 0xFF38, 0xFF39, 0xFF3A, 0 };
int i;
for (i = 0; tbl_lower[i] && chr != tbl_lower[i]; i++) ;
for ( i = 0; tbl_lower[i] && chr != tbl_lower[i]; i++ ) ;
return tbl_lower[i] ? tbl_upper[i] : chr;
return tbl_lower[i] ? tbl_upper[i] : chr;
}

View File

@ -3,57 +3,70 @@
#include "uart.h"
#include "fileops.h"
cfg_t CFG = {
.cfg_ver_maj = 1,
.cfg_ver_min = 0,
.last_game_valid = 0,
.vidmode_menu = VIDMODE_AUTO,
.vidmode_game = VIDMODE_AUTO,
.pair_mode_allowed = 0,
.bsx_use_systime = 0,
.bsx_time = 0x0619970301180530LL
cfg_t CFG =
{
.cfg_ver_maj = 1,
.cfg_ver_min = 0,
.last_game_valid = 0,
.vidmode_menu = VIDMODE_AUTO,
.vidmode_game = VIDMODE_AUTO,
.pair_mode_allowed = 0,
.bsx_use_systime = 0,
.bsx_time = 0x0619970301180530LL
};
int cfg_save() {
int err = 0;
file_open(CFG_FILE, FA_CREATE_ALWAYS | FA_WRITE);
if(file_writeblock(&CFG, 0, sizeof(CFG)) < sizeof(CFG)) {
err = file_res;
}
file_close();
return err;
int cfg_save()
{
int err = 0;
file_open( CFG_FILE, FA_CREATE_ALWAYS | FA_WRITE );
if ( file_writeblock( &CFG, 0, sizeof( CFG ) ) < sizeof( CFG ) )
{
err = file_res;
}
file_close();
return err;
}
int cfg_load() {
int err = 0;
file_open(CFG_FILE, FA_READ);
if(file_readblock(&CFG, 0, sizeof(CFG)) < sizeof(CFG)) {
err = file_res;
}
file_close();
return err;
int cfg_load()
{
int err = 0;
file_open( CFG_FILE, FA_READ );
if ( file_readblock( &CFG, 0, sizeof( CFG ) ) < sizeof( CFG ) )
{
err = file_res;
}
file_close();
return err;
}
int cfg_save_last_game(uint8_t *fn) {
int err = 0;
file_open(LAST_FILE, FA_CREATE_ALWAYS | FA_WRITE);
err = f_puts((const TCHAR*)fn, &file_handle);
file_close();
return err;
int cfg_save_last_game( uint8_t *fn )
{
int err = 0;
file_open( LAST_FILE, FA_CREATE_ALWAYS | FA_WRITE );
err = f_puts( ( const TCHAR * )fn, &file_handle );
file_close();
return err;
}
int cfg_get_last_game(uint8_t *fn) {
int err = 0;
file_open(LAST_FILE, FA_READ);
f_gets((TCHAR*)fn, 255, &file_handle);
file_close();
return err;
int cfg_get_last_game( uint8_t *fn )
{
int err = 0;
file_open( LAST_FILE, FA_READ );
f_gets( ( TCHAR * )fn, 255, &file_handle );
file_close();
return err;
}
void cfg_set_last_game_valid(uint8_t valid) {
CFG.last_game_valid = valid;
void cfg_set_last_game_valid( uint8_t valid )
{
CFG.last_game_valid = valid;
}
uint8_t cfg_is_last_game_valid() {
return CFG.last_game_valid;
uint8_t cfg_is_last_game_valid()
{
return CFG.last_game_valid;
}

View File

@ -6,34 +6,36 @@
#define CFG_FILE ((const uint8_t*)"/sd2snes/sd2snes.cfg")
#define LAST_FILE ((const uint8_t*)"/sd2snes/lastgame.cfg")
typedef enum {
VIDMODE_AUTO = 0,
VIDMODE_60,
VIDMODE_50
typedef enum
{
VIDMODE_AUTO = 0,
VIDMODE_60,
VIDMODE_50
} cfg_vidmode_t;
typedef struct _cfg_block {
uint8_t cfg_ver_maj;
uint8_t cfg_ver_min;
uint8_t last_game_valid;
uint8_t vidmode_menu;
uint8_t vidmode_game;
uint8_t pair_mode_allowed;
uint8_t bsx_use_systime;
uint64_t bsx_time;
typedef struct _cfg_block
{
uint8_t cfg_ver_maj;
uint8_t cfg_ver_min;
uint8_t last_game_valid;
uint8_t vidmode_menu;
uint8_t vidmode_game;
uint8_t pair_mode_allowed;
uint8_t bsx_use_systime;
uint64_t bsx_time;
} cfg_t;
int cfg_save(void);
int cfg_load(void);
int cfg_save( void );
int cfg_load( void );
int cfg_save_last_game(uint8_t *fn);
int cfg_get_last_game(uint8_t *fn);
int cfg_save_last_game( uint8_t *fn );
int cfg_get_last_game( uint8_t *fn );
cfg_vidmode_t cfg_get_vidmode_menu(void);
cfg_vidmode_t cfg_get_vidmode_game(void);
cfg_vidmode_t cfg_get_vidmode_menu( void );
cfg_vidmode_t cfg_get_vidmode_game( void );
void cfg_set_last_game_valid(uint8_t);
uint8_t cfg_is_last_game_valid(void);
uint8_t cfg_is_pair_mode_allowed(void);
void cfg_set_last_game_valid( uint8_t );
uint8_t cfg_is_last_game_valid( void );
uint8_t cfg_is_pair_mode_allowed( void );
#endif

File diff suppressed because it is too large Load Diff

136
src/cic.c
View File

@ -7,74 +7,108 @@
char *cicstatenames[4] = { "CIC_OK", "CIC_FAIL", "CIC_PAIR", "CIC_SCIC" };
char *cicstatefriendly[4] = {"Original or no CIC", "Original CIC(failed)", "SuperCIC enhanced", "SuperCIC detected, not used"};
void print_cic_state() {
printf("CIC state: %s\n", get_cic_statename(get_cic_state()));
void print_cic_state()
{
printf( "CIC state: %s\n", get_cic_statename( get_cic_state() ) );
}
inline char *get_cic_statefriendlyname(enum cicstates state) {
return cicstatefriendly[state];
inline char *get_cic_statefriendlyname( enum cicstates state )
{
return cicstatefriendly[state];
}
inline char *get_cic_statename(enum cicstates state) {
return cicstatenames[state];
inline char *get_cic_statename( enum cicstates state )
{
return cicstatenames[state];
}
enum cicstates get_cic_state() {
uint32_t count;
uint32_t togglecount = 0;
uint8_t state, state_old;
enum cicstates get_cic_state()
{
uint32_t count;
uint32_t togglecount = 0;
uint8_t state, state_old;
state_old = BITBAND(SNES_CIC_STATUS_REG->FIOPIN, SNES_CIC_STATUS_BIT);
/* this loop samples at ~10MHz */
for(count=0; count<CIC_SAMPLECOUNT; count++) {
state = BITBAND(SNES_CIC_STATUS_REG->FIOPIN, SNES_CIC_STATUS_BIT);
if(state != state_old) {
togglecount++;
state_old = BITBAND( SNES_CIC_STATUS_REG->FIOPIN, SNES_CIC_STATUS_BIT );
/* this loop samples at ~10MHz */
for ( count = 0; count < CIC_SAMPLECOUNT; count++ )
{
state = BITBAND( SNES_CIC_STATUS_REG->FIOPIN, SNES_CIC_STATUS_BIT );
if ( state != state_old )
{
togglecount++;
}
state_old = state;
}
printf( "%ld\n", togglecount );
/* CIC_TOGGLE_THRESH_PAIR > CIC_TOGGLE_THRESH_SCIC */
if ( togglecount > CIC_TOGGLE_THRESH_PAIR )
{
return CIC_PAIR;
}
else if ( togglecount > CIC_TOGGLE_THRESH_SCIC )
{
return CIC_SCIC;
}
else if ( state )
{
return CIC_OK;
}
else
{
return CIC_FAIL;
}
state_old = state;
}
printf("%ld\n", togglecount);
/* CIC_TOGGLE_THRESH_PAIR > CIC_TOGGLE_THRESH_SCIC */
if(togglecount > CIC_TOGGLE_THRESH_PAIR) {
return CIC_PAIR;
} else if(togglecount > CIC_TOGGLE_THRESH_SCIC) {
return CIC_SCIC;
} else if(state) {
return CIC_OK;
} else return CIC_FAIL;
}
void cic_init(int allow_pairmode) {
BITBAND(SNES_CIC_PAIR_REG->FIODIR, SNES_CIC_PAIR_BIT) = 1;
if(allow_pairmode) {
BITBAND(SNES_CIC_PAIR_REG->FIOCLR, SNES_CIC_PAIR_BIT) = 1;
} else {
BITBAND(SNES_CIC_PAIR_REG->FIOSET, SNES_CIC_PAIR_BIT) = 1;
}
void cic_init( int allow_pairmode )
{
BITBAND( SNES_CIC_PAIR_REG->FIODIR, SNES_CIC_PAIR_BIT ) = 1;
if ( allow_pairmode )
{
BITBAND( SNES_CIC_PAIR_REG->FIOCLR, SNES_CIC_PAIR_BIT ) = 1;
}
else
{
BITBAND( SNES_CIC_PAIR_REG->FIOSET, SNES_CIC_PAIR_BIT ) = 1;
}
}
/* prepare GPIOs for pair mode + set initial modes */
void cic_pair(int init_vmode, int init_d4) {
cic_videomode(init_vmode);
cic_d4(init_d4);
void cic_pair( int init_vmode, int init_d4 )
{
cic_videomode( init_vmode );
cic_d4( init_d4 );
BITBAND(SNES_CIC_D0_REG->FIODIR, SNES_CIC_D0_BIT) = 1;
BITBAND(SNES_CIC_D1_REG->FIODIR, SNES_CIC_D1_BIT) = 1;
BITBAND( SNES_CIC_D0_REG->FIODIR, SNES_CIC_D0_BIT ) = 1;
BITBAND( SNES_CIC_D1_REG->FIODIR, SNES_CIC_D1_BIT ) = 1;
}
void cic_videomode(int value) {
if(value) {
BITBAND(SNES_CIC_D0_REG->FIOSET, SNES_CIC_D0_BIT) = 1;
} else {
BITBAND(SNES_CIC_D0_REG->FIOCLR, SNES_CIC_D0_BIT) = 1;
}
void cic_videomode( int value )
{
if ( value )
{
BITBAND( SNES_CIC_D0_REG->FIOSET, SNES_CIC_D0_BIT ) = 1;
}
else
{
BITBAND( SNES_CIC_D0_REG->FIOCLR, SNES_CIC_D0_BIT ) = 1;
}
}
void cic_d4(int value) {
if(value) {
BITBAND(SNES_CIC_D1_REG->FIOSET, SNES_CIC_D1_BIT) = 1;
} else {
BITBAND(SNES_CIC_D1_REG->FIOCLR, SNES_CIC_D1_BIT) = 1;
}
void cic_d4( int value )
{
if ( value )
{
BITBAND( SNES_CIC_D1_REG->FIOSET, SNES_CIC_D1_BIT ) = 1;
}
else
{
BITBAND( SNES_CIC_D1_REG->FIOCLR, SNES_CIC_D1_BIT ) = 1;
}
}

View File

@ -1,9 +1,9 @@
#ifndef _CIC_H
#define _CIC_H
#define CIC_SAMPLECOUNT (100000)
#define CIC_TOGGLE_THRESH_PAIR (2500)
#define CIC_TOGGLE_THRESH_SCIC (10)
#define CIC_SAMPLECOUNT (100000)
#define CIC_TOGGLE_THRESH_PAIR (2500)
#define CIC_TOGGLE_THRESH_SCIC (10)
#include <arm/NXP/LPC17xx/LPC17xx.h>
#include "bits.h"
@ -11,14 +11,14 @@
enum cicstates { CIC_OK = 0, CIC_FAIL, CIC_PAIR, CIC_SCIC };
enum cic_region { CIC_NTSC = 0, CIC_PAL };
void print_cic_state(void);
char *get_cic_statename(enum cicstates state);
char *get_cic_statefriendlyname(enum cicstates state);
enum cicstates get_cic_state(void);
void cic_init(int allow_pairmode);
void print_cic_state( void );
char *get_cic_statename( enum cicstates state );
char *get_cic_statefriendlyname( enum cicstates state );
enum cicstates get_cic_state( void );
void cic_init( int allow_pairmode );
void cic_pair(int init_vmode, int init_d4);
void cic_videomode(int value);
void cic_d4(int value);
void cic_pair( int init_vmode, int init_d4 );
void cic_videomode( int value );
void cic_d4( int value );
#endif

959
src/cli.c

File diff suppressed because it is too large Load Diff

View File

@ -27,8 +27,8 @@
#ifndef CLI_H
#define CLI_H
void cli_init(void);
void cli_loop(void);
void cli_entrycheck(void);
void cli_init( void );
void cli_loop( void );
void cli_entrycheck( void );
#endif

View File

@ -7,141 +7,116 @@
#include "bits.h"
#include "uart.h"
void clock_disconnect() {
disconnectPLL0();
disablePLL0();
void clock_disconnect()
{
disconnectPLL0();
disablePLL0();
}
void clock_init() {
void clock_init()
{
/* set flash access time to 5 clks (80<f<=100MHz) */
setFlashAccessTime(5);
/* set flash access time to 5 clks (80<f<=100MHz) */
setFlashAccessTime( 5 );
/* setup PLL0 for ~44100*256*8 Hz
Base clock: 12MHz
Multiplier: 429
Pre-Divisor: 19
Divisor: 6
(want: 90316800, get: 90315789.47)
-> DAC freq = 44099.5 Hz
-> FPGA freq = 11289473.7Hz
First, disable and disconnect PLL0.
*/
clock_disconnect();
/* setup PLL0 for ~44100*256*8 Hz
Base clock: 12MHz
Multiplier: 429
Pre-Divisor: 19
Divisor: 6
(want: 90316800, get: 90315789.47)
-> DAC freq = 44099.5 Hz
-> FPGA freq = 11289473.7Hz
First, disable and disconnect PLL0.
*/
clock_disconnect();
/* PLL is disabled and disconnected. setup PCLK NOW as it cannot be changed
reliably with PLL0 connected.
see:
http://ics.nxp.com/support/documents/microcontrollers/pdf/errata.lpc1754.pdf
*/
/* PLL is disabled and disconnected. setup PCLK NOW as it cannot be changed
reliably with PLL0 connected.
see:
http://ics.nxp.com/support/documents/microcontrollers/pdf/errata.lpc1754.pdf
*/
/* continue with PLL0 setup:
enable the xtal oscillator and wait for it to become stable
set the oscillator as clk source for PLL0
set PLL0 multiplier+predivider
enable PLL0
set CCLK divider
wait for PLL0 to lock
connect PLL0
done
*/
enableMainOsc();
setClkSrc(CLKSRC_MAINOSC);
setPLL0MultPrediv(22, 1);
enablePLL0();
setCCLKDiv(6);
connectPLL0();
/* configure PLL1 for USB operation */
disconnectPLL1();
disablePLL1();
LPC_SC->PLL1CFG = 0x23;
enablePLL1();
connectPLL1();
/* continue with PLL0 setup:
enable the xtal oscillator and wait for it to become stable
set the oscillator as clk source for PLL0
set PLL0 multiplier+predivider
enable PLL0
set CCLK divider
wait for PLL0 to lock
connect PLL0
done
*/
enableMainOsc();
setClkSrc( CLKSRC_MAINOSC );
setPLL0MultPrediv( 22, 1 );
enablePLL0();
setCCLKDiv( 6 );
connectPLL0();
}
void setFlashAccessTime(uint8_t clocks) {
LPC_SC->FLASHCFG=FLASHTIM(clocks);
void setFlashAccessTime( uint8_t clocks )
{
LPC_SC->FLASHCFG = FLASHTIM( clocks );
}
void setPLL0MultPrediv(uint16_t mult, uint8_t prediv) {
LPC_SC->PLL0CFG=PLL_MULT(mult) | PLL_PREDIV(prediv);
PLL0feed();
void setPLL0MultPrediv( uint16_t mult, uint8_t prediv )
{
LPC_SC->PLL0CFG = PLL_MULT( mult ) | PLL_PREDIV( prediv );
PLL0feed();
}
void enablePLL0() {
LPC_SC->PLL0CON |= PLLE0;
PLL0feed();
void enablePLL0()
{
LPC_SC->PLL0CON |= PLLE0;
PLL0feed();
}
void disablePLL0() {
LPC_SC->PLL0CON &= ~PLLE0;
PLL0feed();
void disablePLL0()
{
LPC_SC->PLL0CON &= ~PLLE0;
PLL0feed();
}
void connectPLL0() {
while(!(LPC_SC->PLL0STAT & PLOCK0));
LPC_SC->PLL0CON |= PLLC0;
PLL0feed();
void connectPLL0()
{
while ( !( LPC_SC->PLL0STAT & PLOCK0 ) );
LPC_SC->PLL0CON |= PLLC0;
PLL0feed();
}
void disconnectPLL0() {
LPC_SC->PLL0CON &= ~PLLC0;
PLL0feed();
void disconnectPLL0()
{
LPC_SC->PLL0CON &= ~PLLC0;
PLL0feed();
}
void setPLL1MultPrediv(uint16_t mult, uint8_t prediv) {
LPC_SC->PLL1CFG=PLL_MULT(mult) | PLL_PREDIV(prediv);
PLL1feed();
void setCCLKDiv( uint8_t div )
{
LPC_SC->CCLKCFG = CCLK_DIV( div );
}
void enablePLL1() {
LPC_SC->PLL1CON |= PLLE1;
PLL1feed();
void enableMainOsc()
{
LPC_SC->SCS = OSCEN;
while ( !( LPC_SC->SCS & OSCSTAT ) );
}
void disablePLL1() {
LPC_SC->PLL1CON &= ~PLLE1;
PLL1feed();
void disableMainOsc()
{
LPC_SC->SCS = 0;
}
void connectPLL1() {
while(!(LPC_SC->PLL1STAT & PLOCK1));
LPC_SC->PLL1CON |= PLLC1;
PLL1feed();
void PLL0feed()
{
LPC_SC->PLL0FEED = 0xaa;
LPC_SC->PLL0FEED = 0x55;
}
void disconnectPLL1() {
LPC_SC->PLL1CON &= ~PLLC1;
PLL1feed();
}
void setCCLKDiv(uint8_t div) {
LPC_SC->CCLKCFG=CCLK_DIV(div);
}
void enableMainOsc() {
LPC_SC->SCS=OSCEN;
while(!(LPC_SC->SCS&OSCSTAT));
}
void disableMainOsc() {
LPC_SC->SCS=0;
}
void PLL0feed() {
LPC_SC->PLL0FEED=0xaa;
LPC_SC->PLL0FEED=0x55;
}
void PLL1feed() {
LPC_SC->PLL1FEED=0xaa;
LPC_SC->PLL1FEED=0x55;
}
void setClkSrc(uint8_t src) {
LPC_SC->CLKSRCSEL=src;
void setClkSrc( uint8_t src )
{
LPC_SC->CLKSRCSEL = src;
}

View File

@ -8,9 +8,6 @@
#define PLLE0 (1<<0)
#define PLLC0 (1<<1)
#define PLOCK0 (1<<26)
#define PLLE1 (1<<0)
#define PLLC1 (1<<1)
#define PLOCK1 (1<<10)
#define OSCEN (1<<5)
#define OSCSTAT (1<<6)
#define FLASHTIM(x) (((x-1)<<12)|0x3A)
@ -21,62 +18,60 @@
#define PCLK_CCLK2(x) (2<<(x))
/* shift values for use with PCLKSEL0 */
#define PCLK_WDT (0)
#define PCLK_TIMER0 (2)
#define PCLK_TIMER1 (4)
#define PCLK_UART0 (6)
#define PCLK_UART1 (8)
#define PCLK_PWM1 (12)
#define PCLK_I2C0 (14)
#define PCLK_SPI (16)
#define PCLK_SSP1 (20)
#define PCLK_DAC (22)
#define PCLK_ADC (24)
#define PCLK_CAN1 (26)
#define PCLK_CAN2 (28)
#define PCLK_ACF (30)
#define PCLK_WDT (0)
#define PCLK_TIMER0 (2)
#define PCLK_TIMER1 (4)
#define PCLK_UART0 (6)
#define PCLK_UART1 (8)
#define PCLK_PWM1 (12)
#define PCLK_I2C0 (14)
#define PCLK_SPI (16)
#define PCLK_SSP1 (20)
#define PCLK_DAC (22)
#define PCLK_ADC (24)
#define PCLK_CAN1 (26)
#define PCLK_CAN2 (28)
#define PCLK_ACF (30)
/* shift values for use with PCLKSEL1 */
#define PCLK_QEI (0)
#define PCLK_GPIOINT (2)
#define PCLK_PCB (4)
#define PCLK_I2C1 (6)
#define PCLK_SSP0 (10)
#define PCLK_TIMER2 (12)
#define PCLK_QEI (0)
#define PCLK_GPIOINT (2)
#define PCLK_PCB (4)
#define PCLK_I2C1 (6)
#define PCLK_SSP0 (10)
#define PCLK_TIMER2 (12)
#define PCLK_TIMER3 (14)
#define PCLK_UART2 (16)
#define PCLK_UART3 (18)
#define PCLK_I2C2 (20)
#define PCLK_I2S (22)
#define PCLK_RIT (26)
#define PCLK_SYSCON (28)
#define PCLK_MC (30)
#define PCLK_UART2 (16)
#define PCLK_UART3 (18)
#define PCLK_I2C2 (20)
#define PCLK_I2S (22)
#define PCLK_RIT (26)
#define PCLK_SYSCON (28)
#define PCLK_MC (30)
void clock_disconnect(void);
void clock_disconnect( void );
void clock_init(void);
void clock_init( void );
void setFlashAccessTime(uint8_t clocks);
void setFlashAccessTime( uint8_t clocks );
void setPLL0MultPrediv(uint16_t mult, uint8_t prediv);
void enablePLL0(void);
void disablePLL0(void);
void connectPLL0(void);
void disconnectPLL0(void);
void PLL0feed(void);
void setPLL0MultPrediv( uint16_t mult, uint8_t prediv );
void setPLL1MultPrediv(uint16_t mult, uint8_t prediv);
void enablePLL1(void);
void disablePLL1(void);
void connectPLL1(void);
void disconnectPLL1(void);
void PLL1feed(void);
void enablePLL0( void );
void setCCLKDiv(uint8_t div);
void disablePLL0( void );
void enableMainOsc(void);
void connectPLL0( void );
void disableMainOsc(void);
void disconnectPLL0( void );
void setClkSrc(uint8_t src);
void setCCLKDiv( uint8_t div );
void enableMainOsc( void );
void disableMainOsc( void );
void PLL0feed( void );
void setClkSrc( uint8_t src );
#endif

View File

@ -11,9 +11,9 @@
#define IN_AHBRAM __attribute__ ((section(".ahbram")))
#define SD_DT_INT_SETUP() do {\
BITBAND(LPC_GPIOINT->IO2IntEnR, SD_DT_BIT) = 1;\
BITBAND(LPC_GPIOINT->IO2IntEnF, SD_DT_BIT) = 1;\
} while(0)
BITBAND(LPC_GPIOINT->IO2IntEnR, SD_DT_BIT) = 1;\
BITBAND(LPC_GPIOINT->IO2IntEnF, SD_DT_BIT) = 1;\
} while(0)
#define SD_CHANGE_DETECT (BITBAND(LPC_GPIOINT->IO2IntStatR, SD_DT_BIT)\
|BITBAND(LPC_GPIOINT->IO2IntStatF, SD_DT_BIT))
@ -33,7 +33,7 @@
// #define SD_CHANGE_VECT
// #define CONFIG_SD_DATACRC 1
#define CONFIG_UART_NUM 3
#define CONFIG_UART_NUM 3
// #define CONFIG_CPU_FREQUENCY 90315789
#define CONFIG_CPU_FREQUENCY 88000000
//#define CONFIG_CPU_FREQUENCY 46000000
@ -65,7 +65,7 @@
#define QSORT_MAXELEM 2048
#define SORT_STRLEN 256
#define CLTBL_SIZE 100
#define CLTBL_SIZE 100
#define DIR_FILE_MAX 16380
@ -96,7 +96,4 @@
#define SD_DAT (LPC_GPIO2->FIOPIN0)
#define USB_CONNREG LPC_GPIO4
#define USB_CONNBIT 28
#endif

View File

@ -1,9 +1,9 @@
#ifndef CRC_H
#define CRC_H
uint8_t crc7update(uint8_t crc, uint8_t data);
uint16_t crc_xmodem_update(uint16_t crc, uint8_t data);
uint16_t crc_xmodem_block(uint16_t crc, const uint8_t *data, uint32_t length);
uint8_t crc7update( uint8_t crc, uint8_t data );
uint16_t crc_xmodem_update( uint16_t crc, uint8_t data );
uint16_t crc_xmodem_block( uint16_t crc, const uint8_t *data, uint32_t length );
// AVR-libc compatibility
#define _crc_xmodem_update(crc,data) crc_xmodem_update(crc,data)

View File

@ -20,7 +20,8 @@
/**
* Static table used for the table_driven implementation.
*****************************************************************************/
static const uint16_t crc_table[256] = {
static const uint16_t crc_table[256] =
{
0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241,
0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440,
0xcc01, 0x0cc0, 0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40,
@ -63,12 +64,12 @@ static const uint16_t crc_table[256] = {
* \param data_len Number of bytes in the \a data buffer.
* \return The updated crc value.
*****************************************************************************/
uint16_t crc16_update(uint16_t crc, const unsigned char data)
uint16_t crc16_update( uint16_t crc, const unsigned char data )
{
unsigned int tbl_idx;
tbl_idx = (crc ^ data) & 0xff;
crc = (crc_table[tbl_idx] ^ (crc >> 8)) & 0xffff;
return crc & 0xffff;
unsigned int tbl_idx;
tbl_idx = ( crc ^ data ) & 0xff;
crc = ( crc_table[tbl_idx] ^ ( crc >> 8 ) ) & 0xffff;
return crc & 0xffff;
}

View File

@ -37,7 +37,7 @@ extern "C" {
* \param data_len Number of bytes in the \a data buffer.
* \return The updated crc value.
*****************************************************************************/
uint16_t crc16_update(uint16_t crc, const unsigned char data);
uint16_t crc16_update( uint16_t crc, const unsigned char data );
#ifdef __cplusplus
} /* closing brace for extern "C" */

View File

@ -22,71 +22,72 @@
/**
* Static table used for the table_driven implementation.
*****************************************************************************/
static const uint32_t crc32_table[256] = {
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
static const uint32_t crc32_table[256] =
{
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
};
/**
@ -97,14 +98,14 @@ static const uint32_t crc32_table[256] = {
* \param data_len Number of bytes in the \a data buffer.
* \return The updated crc value.
*****************************************************************************/
uint32_t crc32_update(uint32_t crc, const unsigned char data)
uint32_t crc32_update( uint32_t crc, const unsigned char data )
{
unsigned int tbl_idx;
unsigned int tbl_idx;
tbl_idx = (crc ^ data) & 0xff;
crc = (crc32_table[tbl_idx] ^ (crc >> 8)) & 0xffffffff;
tbl_idx = ( crc ^ data ) & 0xff;
crc = ( crc32_table[tbl_idx] ^ ( crc >> 8 ) ) & 0xffffffff;
return crc & 0xffffffff;
return crc & 0xffffffff;
}

View File

@ -34,9 +34,9 @@ extern "C" {
*
* \return The initial crc value.
*****************************************************************************/
static inline uint32_t crc_init(void)
static inline uint32_t crc_init( void )
{
return 0xffffffff;
return 0xffffffff;
}
/**
@ -47,7 +47,7 @@ static inline uint32_t crc_init(void)
* \param data_len Number of bytes in the \a data buffer.
* \return The updated crc value.
*****************************************************************************/
uint32_t crc32_update(uint32_t crc, const unsigned char data);
uint32_t crc32_update( uint32_t crc, const unsigned char data );
/**
* Calculate the final crc value.
@ -55,9 +55,9 @@ uint32_t crc32_update(uint32_t crc, const unsigned char data);
* \param crc The current crc value.
* \return The final crc value.
*****************************************************************************/
static inline uint32_t crc32_finalize(uint32_t crc)
static inline uint32_t crc32_finalize( uint32_t crc )
{
return crc ^ 0xffffffff;
return crc ^ 0xffffffff;
}

View File

@ -4,8 +4,8 @@
#ifndef _DISKIO
#define _READONLY 0 /* 1: Remove write functions */
#define _USE_IOCTL 1 /* 1: Use disk_ioctl fucntion */
#define _READONLY 0 /* 1: Remove write functions */
#define _USE_IOCTL 1 /* 1: Use disk_ioctl fucntion */
#include <arm/NXP/LPC17xx/LPC17xx.h>
@ -13,15 +13,16 @@
/* Status of Disk Functions */
typedef BYTE DSTATUS;
typedef BYTE DSTATUS;
/* Results of Disk Functions */
typedef enum {
RES_OK = 0, /* 0: Successful */
RES_ERROR, /* 1: R/W Error */
RES_WRPRT, /* 2: Write Protected */
RES_NOTRDY, /* 3: Not Ready */
RES_PARERR /* 4: Invalid Parameter */
typedef enum
{
RES_OK = 0, /* 0: Successful */
RES_ERROR, /* 1: R/W Error */
RES_WRPRT, /* 2: Write Protected */
RES_NOTRDY, /* 3: Not Ready */
RES_PARERR /* 4: Invalid Parameter */
} DRESULT;
/**
@ -35,12 +36,13 @@ typedef enum {
* This is the struct returned in the data buffer when disk_getinfo
* is called with page=0.
*/
typedef struct {
uint8_t validbytes;
uint8_t maxpage;
uint8_t disktype;
uint8_t sectorsize; /* divided by 256 */
uint32_t sectorcount; /* 2 TB should be enough... (512 byte sectors) */
typedef struct
{
uint8_t validbytes;
uint8_t maxpage;
uint8_t disktype;
uint8_t sectorsize; /* divided by 256 */
uint32_t sectorcount; /* 2 TB should be enough... (512 byte sectors) */
} diskinfo0_t;
@ -48,16 +50,16 @@ typedef struct {
/*---------------------------------------*/
/* Prototypes for disk control functions */
int assign_drives (int, int);
DSTATUS disk_initialize (BYTE);
DSTATUS disk_status (BYTE);
DRESULT disk_read (BYTE, BYTE*, DWORD, BYTE);
#if _READONLY == 0
DRESULT disk_write (BYTE, const BYTE*, DWORD, BYTE);
int assign_drives ( int, int );
DSTATUS disk_initialize ( BYTE );
DSTATUS disk_status ( BYTE );
DRESULT disk_read ( BYTE, BYTE *, DWORD, BYTE );
#if _READONLY == 0
DRESULT disk_write ( BYTE, const BYTE *, DWORD, BYTE );
#endif
DRESULT disk_ioctl (BYTE, BYTE, void*);
DRESULT disk_ioctl ( BYTE, BYTE, void * );
void disk_init(void);
void disk_init( void );
/* Will be set to DISK_ERROR if any access on the card fails */
enum diskstates { DISK_CHANGED = 0, DISK_REMOVED, DISK_OK, DISK_ERROR };
@ -79,39 +81,39 @@ extern volatile enum diskstates disk_state;
/* Disk Status Bits (DSTATUS) */
#define STA_NOINIT 0x01 /* Drive not initialized */
#define STA_NODISK 0x02 /* No medium in the drive */
#define STA_PROTECT 0x04 /* Write protected */
#define STA_NOINIT 0x01 /* Drive not initialized */
#define STA_NODISK 0x02 /* No medium in the drive */
#define STA_PROTECT 0x04 /* Write protected */
/* Command code for disk_ioctrl fucntion */
/* Generic command (defined for FatFs) */
#define CTRL_SYNC 0 /* Flush disk cache (for write functions) */
#define GET_SECTOR_COUNT 1 /* Get media size (for only f_mkfs()) */
#define GET_SECTOR_SIZE 2 /* Get sector size (for multiple sector size (_MAX_SS >= 1024)) */
#define GET_BLOCK_SIZE 3 /* Get erase block size (for only f_mkfs()) */
#define CTRL_ERASE_SECTOR 4 /* Force erased a block of sectors (for only _USE_ERASE) */
#define CTRL_SYNC 0 /* Flush disk cache (for write functions) */
#define GET_SECTOR_COUNT 1 /* Get media size (for only f_mkfs()) */
#define GET_SECTOR_SIZE 2 /* Get sector size (for multiple sector size (_MAX_SS >= 1024)) */
#define GET_BLOCK_SIZE 3 /* Get erase block size (for only f_mkfs()) */
#define CTRL_ERASE_SECTOR 4 /* Force erased a block of sectors (for only _USE_ERASE) */
/* Generic command */
#define CTRL_POWER 5 /* Get/Set power status */
#define CTRL_LOCK 6 /* Lock/Unlock media removal */
#define CTRL_EJECT 7 /* Eject media */
#define CTRL_POWER 5 /* Get/Set power status */
#define CTRL_LOCK 6 /* Lock/Unlock media removal */
#define CTRL_EJECT 7 /* Eject media */
/* MMC/SDC specific ioctl command */
#define MMC_GET_TYPE 10 /* Get card type */
#define MMC_GET_CSD 11 /* Get CSD */
#define MMC_GET_CID 12 /* Get CID */
#define MMC_GET_OCR 13 /* Get OCR */
#define MMC_GET_SDSTAT 14 /* Get SD status */
#define MMC_GET_TYPE 10 /* Get card type */
#define MMC_GET_CSD 11 /* Get CSD */
#define MMC_GET_CID 12 /* Get CID */
#define MMC_GET_OCR 13 /* Get OCR */
#define MMC_GET_SDSTAT 14 /* Get SD status */
/* ATA/CF specific ioctl command */
#define ATA_GET_REV 20 /* Get F/W revision */
#define ATA_GET_MODEL 21 /* Get model name */
#define ATA_GET_SN 22 /* Get serial number */
#define ATA_GET_REV 20 /* Get F/W revision */
#define ATA_GET_MODEL 21 /* Get model name */
#define ATA_GET_SN 22 /* Get serial number */
/* NAND specific ioctl command */
#define NAND_FORMAT 30 /* Create physical format */
#define NAND_FORMAT 30 /* Create physical format */
#define _DISKIO

View File

@ -1,20 +1,25 @@
#include <arm/NXP/LPC17xx/LPC17xx.h>
#include "uart.h"
void HardFault_Handler(void) {
printf("HFSR: %lx\n", SCB->HFSR);
while (1) ;
void HardFault_Handler( void )
{
printf( "HFSR: %lx\n", SCB->HFSR );
while ( 1 ) ;
}
void MemManage_Handler(void) {
printf("MemManage - CFSR: %lx; MMFAR: %lx\n", SCB->CFSR, SCB->MMFAR);
void MemManage_Handler( void )
{
printf( "MemManage - CFSR: %lx; MMFAR: %lx\n", SCB->CFSR, SCB->MMFAR );
}
void BusFault_Handler(void) {
printf("BusFault - CFSR: %lx; BFAR: %lx\n", SCB->CFSR, SCB->BFAR);
void BusFault_Handler( void )
{
printf( "BusFault - CFSR: %lx; BFAR: %lx\n", SCB->CFSR, SCB->BFAR );
}
void UsageFault_Handler(void) {
printf("UsageFault - CFSR: %lx; BFAR: %lx\n", SCB->CFSR, SCB->BFAR);
void UsageFault_Handler( void )
{
printf( "UsageFault - CFSR: %lx; BFAR: %lx\n", SCB->CFSR, SCB->BFAR );
}

7113
src/ff.c

File diff suppressed because it is too large Load Diff

591
src/ff.h
View File

@ -15,14 +15,14 @@
/----------------------------------------------------------------------------*/
#ifndef _FATFS
#define _FATFS 8255 /* Revision ID */
#define _FATFS 8255 /* Revision ID */
#ifdef __cplusplus
extern "C" {
#endif
#include "integer.h" /* Basic integer types */
#include "ffconf.h" /* FatFs configuration options */
#include "integer.h" /* Basic integer types */
#include "ffconf.h" /* FatFs configuration options */
#if _FATFS != _FFCONF
#error Wrong configuration file (ffconf.h).
@ -31,191 +31,191 @@ extern "C" {
/* DBCS code ranges and SBCS extend char conversion table */
#if _CODE_PAGE == 932 /* Japanese Shift-JIS */
#define _DF1S 0x81 /* DBC 1st byte range 1 start */
#define _DF1E 0x9F /* DBC 1st byte range 1 end */
#define _DF2S 0xE0 /* DBC 1st byte range 2 start */
#define _DF2E 0xFC /* DBC 1st byte range 2 end */
#define _DS1S 0x40 /* DBC 2nd byte range 1 start */
#define _DS1E 0x7E /* DBC 2nd byte range 1 end */
#define _DS2S 0x80 /* DBC 2nd byte range 2 start */
#define _DS2E 0xFC /* DBC 2nd byte range 2 end */
#if _CODE_PAGE == 932 /* Japanese Shift-JIS */
#define _DF1S 0x81 /* DBC 1st byte range 1 start */
#define _DF1E 0x9F /* DBC 1st byte range 1 end */
#define _DF2S 0xE0 /* DBC 1st byte range 2 start */
#define _DF2E 0xFC /* DBC 1st byte range 2 end */
#define _DS1S 0x40 /* DBC 2nd byte range 1 start */
#define _DS1E 0x7E /* DBC 2nd byte range 1 end */
#define _DS2S 0x80 /* DBC 2nd byte range 2 start */
#define _DS2E 0xFC /* DBC 2nd byte range 2 end */
#elif _CODE_PAGE == 936 /* Simplified Chinese GBK */
#define _DF1S 0x81
#define _DF1E 0xFE
#define _DS1S 0x40
#define _DS1E 0x7E
#define _DS2S 0x80
#define _DS2E 0xFE
#elif _CODE_PAGE == 936 /* Simplified Chinese GBK */
#define _DF1S 0x81
#define _DF1E 0xFE
#define _DS1S 0x40
#define _DS1E 0x7E
#define _DS2S 0x80
#define _DS2E 0xFE
#elif _CODE_PAGE == 949 /* Korean */
#define _DF1S 0x81
#define _DF1E 0xFE
#define _DS1S 0x41
#define _DS1E 0x5A
#define _DS2S 0x61
#define _DS2E 0x7A
#define _DS3S 0x81
#define _DS3E 0xFE
#elif _CODE_PAGE == 949 /* Korean */
#define _DF1S 0x81
#define _DF1E 0xFE
#define _DS1S 0x41
#define _DS1E 0x5A
#define _DS2S 0x61
#define _DS2E 0x7A
#define _DS3S 0x81
#define _DS3E 0xFE
#elif _CODE_PAGE == 950 /* Traditional Chinese Big5 */
#define _DF1S 0x81
#define _DF1E 0xFE
#define _DS1S 0x40
#define _DS1E 0x7E
#define _DS2S 0xA1
#define _DS2E 0xFE
#elif _CODE_PAGE == 950 /* Traditional Chinese Big5 */
#define _DF1S 0x81
#define _DF1E 0xFE
#define _DS1S 0x40
#define _DS1E 0x7E
#define _DS2S 0xA1
#define _DS2E 0xFE
#elif _CODE_PAGE == 437 /* U.S. (OEM) */
#define _DF1S 0
#elif _CODE_PAGE == 437 /* U.S. (OEM) */
#define _DF1S 0
#define _EXCVT {0x80,0x9A,0x90,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x49,0x49,0x49,0x8E,0x8F,0x90,0x92,0x92,0x4F,0x99,0x4F,0x55,0x55,0x59,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
#elif _CODE_PAGE == 720 /* Arabic (OEM) */
#define _DF1S 0
#elif _CODE_PAGE == 720 /* Arabic (OEM) */
#define _DF1S 0
#define _EXCVT {0x80,0x81,0x45,0x41,0x84,0x41,0x86,0x43,0x45,0x45,0x45,0x49,0x49,0x8D,0x8E,0x8F,0x90,0x92,0x92,0x93,0x94,0x95,0x49,0x49,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
#elif _CODE_PAGE == 737 /* Greek (OEM) */
#define _DF1S 0
#elif _CODE_PAGE == 737 /* Greek (OEM) */
#define _DF1S 0
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x92,0x92,0x93,0x94,0x95,0x96,0x97,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87, \
0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0xAA,0x92,0x93,0x94,0x95,0x96,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0x97,0xEA,0xEB,0xEC,0xE4,0xED,0xEE,0xE7,0xE8,0xF1,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0xAA,0x92,0x93,0x94,0x95,0x96,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0x97,0xEA,0xEB,0xEC,0xE4,0xED,0xEE,0xE7,0xE8,0xF1,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
#elif _CODE_PAGE == 775 /* Baltic (OEM) */
#define _DF1S 0
#elif _CODE_PAGE == 775 /* Baltic (OEM) */
#define _DF1S 0
#define _EXCVT {0x80,0x9A,0x91,0xA0,0x8E,0x95,0x8F,0x80,0xAD,0xED,0x8A,0x8A,0xA1,0x8D,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0x95,0x96,0x97,0x97,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \
0xA0,0xA1,0xE0,0xA3,0xA3,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xB5,0xB6,0xB7,0xB8,0xBD,0xBE,0xC6,0xC7,0xA5,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE3,0xE8,0xE8,0xEA,0xEA,0xEE,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
0xA0,0xA1,0xE0,0xA3,0xA3,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xB5,0xB6,0xB7,0xB8,0xBD,0xBE,0xC6,0xC7,0xA5,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE3,0xE8,0xE8,0xEA,0xEA,0xEE,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
#elif _CODE_PAGE == 850 /* Multilingual Latin 1 (OEM) */
#define _DF1S 0
#elif _CODE_PAGE == 850 /* Multilingual Latin 1 (OEM) */
#define _DF1S 0
#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0xDE,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x59,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \
0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE7,0xE9,0xEA,0xEB,0xED,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE7,0xE9,0xEA,0xEB,0xED,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
#elif _CODE_PAGE == 852 /* Latin 2 (OEM) */
#define _DF1S 0
#elif _CODE_PAGE == 852 /* Latin 2 (OEM) */
#define _DF1S 0
#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xDE,0x8F,0x80,0x9D,0xD3,0x8A,0x8A,0xD7,0x8D,0x8E,0x8F,0x90,0x91,0x91,0xE2,0x99,0x95,0x95,0x97,0x97,0x99,0x9A,0x9B,0x9B,0x9D,0x9E,0x9F, \
0xB5,0xD6,0xE0,0xE9,0xA4,0xA4,0xA6,0xA6,0xA8,0xA8,0xAA,0x8D,0xAC,0xB8,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBD,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC6,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD2,0xD3,0xD2,0xD5,0xD6,0xD7,0xB7,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xE0,0xE1,0xE2,0xE3,0xE3,0xD5,0xE6,0xE6,0xE8,0xE9,0xE8,0xEB,0xED,0xED,0xDD,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xEB,0xFC,0xFC,0xFE,0xFF}
0xB5,0xD6,0xE0,0xE9,0xA4,0xA4,0xA6,0xA6,0xA8,0xA8,0xAA,0x8D,0xAC,0xB8,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBD,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC6,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD2,0xD3,0xD2,0xD5,0xD6,0xD7,0xB7,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xE0,0xE1,0xE2,0xE3,0xE3,0xD5,0xE6,0xE6,0xE8,0xE9,0xE8,0xEB,0xED,0xED,0xDD,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xEB,0xFC,0xFC,0xFE,0xFF}
#elif _CODE_PAGE == 855 /* Cyrillic (OEM) */
#define _DF1S 0
#elif _CODE_PAGE == 855 /* Cyrillic (OEM) */
#define _DF1S 0
#define _EXCVT {0x81,0x81,0x83,0x83,0x85,0x85,0x87,0x87,0x89,0x89,0x8B,0x8B,0x8D,0x8D,0x8F,0x8F,0x91,0x91,0x93,0x93,0x95,0x95,0x97,0x97,0x99,0x99,0x9B,0x9B,0x9D,0x9D,0x9F,0x9F, \
0xA1,0xA1,0xA3,0xA3,0xA5,0xA5,0xA7,0xA7,0xA9,0xA9,0xAB,0xAB,0xAD,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB6,0xB6,0xB8,0xB8,0xB9,0xBA,0xBB,0xBC,0xBE,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD3,0xD3,0xD5,0xD5,0xD7,0xD7,0xDD,0xD9,0xDA,0xDB,0xDC,0xDD,0xE0,0xDF, \
0xE0,0xE2,0xE2,0xE4,0xE4,0xE6,0xE6,0xE8,0xE8,0xEA,0xEA,0xEC,0xEC,0xEE,0xEE,0xEF,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF8,0xFA,0xFA,0xFC,0xFC,0xFD,0xFE,0xFF}
0xA1,0xA1,0xA3,0xA3,0xA5,0xA5,0xA7,0xA7,0xA9,0xA9,0xAB,0xAB,0xAD,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB6,0xB6,0xB8,0xB8,0xB9,0xBA,0xBB,0xBC,0xBE,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD3,0xD3,0xD5,0xD5,0xD7,0xD7,0xDD,0xD9,0xDA,0xDB,0xDC,0xDD,0xE0,0xDF, \
0xE0,0xE2,0xE2,0xE4,0xE4,0xE6,0xE6,0xE8,0xE8,0xEA,0xEA,0xEC,0xEC,0xEE,0xEE,0xEF,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF8,0xFA,0xFA,0xFC,0xFC,0xFD,0xFE,0xFF}
#elif _CODE_PAGE == 857 /* Turkish (OEM) */
#define _DF1S 0
#elif _CODE_PAGE == 857 /* Turkish (OEM) */
#define _DF1S 0
#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0x98,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x98,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9E, \
0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA6,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xDE,0x59,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA6,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xDE,0x59,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
#elif _CODE_PAGE == 858 /* Multilingual Latin 1 + Euro (OEM) */
#define _DF1S 0
#elif _CODE_PAGE == 858 /* Multilingual Latin 1 + Euro (OEM) */
#define _DF1S 0
#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0xDE,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x59,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \
0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE7,0xE9,0xEA,0xEB,0xED,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE7,0xE9,0xEA,0xEB,0xED,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
#elif _CODE_PAGE == 862 /* Hebrew (OEM) */
#define _DF1S 0
#elif _CODE_PAGE == 862 /* Hebrew (OEM) */
#define _DF1S 0
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
#elif _CODE_PAGE == 866 /* Russian (OEM) */
#define _DF1S 0
#elif _CODE_PAGE == 866 /* Russian (OEM) */
#define _DF1S 0
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0x90,0x91,0x92,0x93,0x9d,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,0xF0,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0x90,0x91,0x92,0x93,0x9d,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,0xF0,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
#elif _CODE_PAGE == 874 /* Thai (OEM, Windows) */
#define _DF1S 0
#elif _CODE_PAGE == 874 /* Thai (OEM, Windows) */
#define _DF1S 0
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
#elif _CODE_PAGE == 1250 /* Central Europe (Windows) */
#define _DF1S 0
#define _DF1S 0
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x8D,0x8E,0x8F, \
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xA3,0xB4,0xB5,0xB6,0xB7,0xB8,0xA5,0xAA,0xBB,0xBC,0xBD,0xBC,0xAF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF}
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xA3,0xB4,0xB5,0xB6,0xB7,0xB8,0xA5,0xAA,0xBB,0xBC,0xBD,0xBC,0xAF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF}
#elif _CODE_PAGE == 1251 /* Cyrillic (Windows) */
#define _DF1S 0
#define _DF1S 0
#define _EXCVT {0x80,0x81,0x82,0x82,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x80,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x8D,0x8E,0x8F, \
0xA0,0xA2,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB2,0xA5,0xB5,0xB6,0xB7,0xA8,0xB9,0xAA,0xBB,0xA3,0xBD,0xBD,0xAF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF}
0xA0,0xA2,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB2,0xA5,0xB5,0xB6,0xB7,0xA8,0xB9,0xAA,0xBB,0xA3,0xBD,0xBD,0xAF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF}
#elif _CODE_PAGE == 1252 /* Latin 1 (Windows) */
#define _DF1S 0
#define _DF1S 0
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0xAd,0x9B,0x8C,0x9D,0xAE,0x9F, \
0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x9F}
0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x9F}
#elif _CODE_PAGE == 1253 /* Greek (Windows) */
#define _DF1S 0
#define _DF1S 0
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xA2,0xB8,0xB9,0xBA, \
0xE0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xF2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xFB,0xBC,0xFD,0xBF,0xFF}
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xA2,0xB8,0xB9,0xBA, \
0xE0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xF2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xFB,0xBC,0xFD,0xBF,0xFF}
#elif _CODE_PAGE == 1254 /* Turkish (Windows) */
#define _DF1S 0
#define _DF1S 0
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x9D,0x9E,0x9F, \
0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x9F}
0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x9F}
#elif _CODE_PAGE == 1255 /* Hebrew (Windows) */
#define _DF1S 0
#define _DF1S 0
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
#elif _CODE_PAGE == 1256 /* Arabic (Windows) */
#define _DF1S 0
#define _DF1S 0
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x8C,0x9D,0x9E,0x9F, \
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0x41,0xE1,0x41,0xE3,0xE4,0xE5,0xE6,0x43,0x45,0x45,0x45,0x45,0xEC,0xED,0x49,0x49,0xF0,0xF1,0xF2,0xF3,0x4F,0xF5,0xF6,0xF7,0xF8,0x55,0xFA,0x55,0x55,0xFD,0xFE,0xFF}
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0x41,0xE1,0x41,0xE3,0xE4,0xE5,0xE6,0x43,0x45,0x45,0x45,0x45,0xEC,0xED,0x49,0x49,0xF0,0xF1,0xF2,0xF3,0x4F,0xF5,0xF6,0xF7,0xF8,0x55,0xFA,0x55,0x55,0xFD,0xFE,0xFF}
#elif _CODE_PAGE == 1257 /* Baltic (Windows) */
#define _DF1S 0
#define _DF1S 0
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xA8,0xB9,0xAA,0xBB,0xBC,0xBD,0xBE,0xAF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF}
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xA8,0xB9,0xAA,0xBB,0xBC,0xBD,0xBE,0xAF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF}
#elif _CODE_PAGE == 1258 /* Vietnam (OEM, Windows) */
#define _DF1S 0
#define _DF1S 0
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0xAC,0x9D,0x9E,0x9F, \
0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xEC,0xCD,0xCE,0xCF,0xD0,0xD1,0xF2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xFE,0x9F}
0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xEC,0xCD,0xCE,0xCF,0xD0,0xD1,0xF2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xFE,0x9F}
#elif _CODE_PAGE == 1 /* ASCII (for only non-LFN cfg) */
#define _DF1S 0
#elif _CODE_PAGE == 1 /* ASCII (for only non-LFN cfg) */
#define _DF1S 0
#else
#error Unknown code page
@ -226,18 +226,19 @@ extern "C" {
/* Definitions of volume management */
#if _MULTI_PARTITION /* Multiple partition configuration */
#define LD2PD(vol) (VolToPart[vol].pd) /* Get physical drive# */
#define LD2PT(vol) (VolToPart[vol].pt) /* Get partition# */
typedef struct {
BYTE pd; /* Physical drive# */
BYTE pt; /* Partition # (0-3) */
#if _MULTI_PARTITION /* Multiple partition configuration */
#define LD2PD(vol) (VolToPart[vol].pd) /* Get physical drive# */
#define LD2PT(vol) (VolToPart[vol].pt) /* Get partition# */
typedef struct
{
BYTE pd; /* Physical drive# */
BYTE pt; /* Partition # (0-3) */
} PARTITION;
extern const PARTITION VolToPart[]; /* Volume - Physical location resolution table */
extern const PARTITION VolToPart[]; /* Volume - Physical location resolution table */
#else /* Single partition configuration */
#define LD2PD(vol) (vol) /* Logical drive# is bound to the same physical drive# */
#define LD2PT(vol) 0 /* Always mounts the 1st partition */
#else /* Single partition configuration */
#define LD2PD(vol) (vol) /* Logical drive# is bound to the same physical drive# */
#define LD2PT(vol) 0 /* Always mounts the 1st partition */
#endif
@ -245,7 +246,7 @@ extern const PARTITION VolToPart[]; /* Volume - Physical location resolution tab
/* Type of path name strings on FatFs API */
#if _LFN_UNICODE /* Unicode string */
#if _LFN_UNICODE /* Unicode string */
#if !_USE_LFN
#error _LFN_UNICODE must be 0 in non-LFN cfg.
#endif
@ -255,7 +256,7 @@ typedef WCHAR TCHAR;
#define _TEXT(x) L ## x
#endif
#else /* ANSI/OEM string */
#else /* ANSI/OEM string */
#ifndef _INC_TCHAR
typedef char TCHAR;
#define _T(x) x
@ -268,64 +269,66 @@ typedef char TCHAR;
/* File system object structure (FATFS) */
typedef struct {
BYTE fs_type; /* FAT sub-type (0:Not mounted) */
BYTE drv; /* Physical drive number */
BYTE csize; /* Sectors per cluster (1,2,4...128) */
BYTE n_fats; /* Number of FAT copies (1,2) */
BYTE wflag; /* win[] dirty flag (1:must be written back) */
BYTE fsi_flag; /* fsinfo dirty flag (1:must be written back) */
WORD id; /* File system mount ID */
WORD n_rootdir; /* Number of root directory entries (FAT12/16) */
typedef struct
{
BYTE fs_type; /* FAT sub-type (0:Not mounted) */
BYTE drv; /* Physical drive number */
BYTE csize; /* Sectors per cluster (1,2,4...128) */
BYTE n_fats; /* Number of FAT copies (1,2) */
BYTE wflag; /* win[] dirty flag (1:must be written back) */
BYTE fsi_flag; /* fsinfo dirty flag (1:must be written back) */
WORD id; /* File system mount ID */
WORD n_rootdir; /* Number of root directory entries (FAT12/16) */
#if _MAX_SS != 512
WORD ssize; /* Bytes per sector (512,1024,2048,4096) */
WORD ssize; /* Bytes per sector (512,1024,2048,4096) */
#endif
#if _FS_REENTRANT
_SYNC_t sobj; /* Identifier of sync object */
_SYNC_t sobj; /* Identifier of sync object */
#endif
#if !_FS_READONLY
DWORD last_clust; /* Last allocated cluster */
DWORD free_clust; /* Number of free clusters */
DWORD fsi_sector; /* fsinfo sector (FAT32) */
DWORD last_clust; /* Last allocated cluster */
DWORD free_clust; /* Number of free clusters */
DWORD fsi_sector; /* fsinfo sector (FAT32) */
#endif
#if _FS_RPATH
DWORD cdir; /* Current directory start cluster (0:root) */
DWORD cdir; /* Current directory start cluster (0:root) */
#endif
DWORD n_fatent; /* Number of FAT entries (= number of clusters + 2) */
DWORD fsize; /* Sectors per FAT */
DWORD fatbase; /* FAT start sector */
DWORD dirbase; /* Root directory start sector (FAT32:Cluster#) */
DWORD database; /* Data start sector */
DWORD winsect; /* Current sector appearing in the win[] */
BYTE win[_MAX_SS]; /* Disk access window for Directory, FAT (and Data on tiny cfg) */
DWORD n_fatent; /* Number of FAT entries (= number of clusters + 2) */
DWORD fsize; /* Sectors per FAT */
DWORD fatbase; /* FAT start sector */
DWORD dirbase; /* Root directory start sector (FAT32:Cluster#) */
DWORD database; /* Data start sector */
DWORD winsect; /* Current sector appearing in the win[] */
BYTE win[_MAX_SS]; /* Disk access window for Directory, FAT (and Data on tiny cfg) */
} FATFS;
/* File object structure (FIL) */
typedef struct {
FATFS* fs; /* Pointer to the owner file system object */
WORD id; /* Owner file system mount ID */
BYTE flag; /* File status flags */
BYTE pad1;
DWORD fptr; /* File read/write pointer (0 on file open) */
DWORD fsize; /* File size */
DWORD org_clust; /* File start cluster (0 when fsize==0) */
DWORD curr_clust; /* Current cluster */
DWORD dsect; /* Current data sector */
typedef struct
{
FATFS *fs; /* Pointer to the owner file system object */
WORD id; /* Owner file system mount ID */
BYTE flag; /* File status flags */
BYTE pad1;
DWORD fptr; /* File read/write pointer (0 on file open) */
DWORD fsize; /* File size */
DWORD org_clust; /* File start cluster (0 when fsize==0) */
DWORD curr_clust; /* Current cluster */
DWORD dsect; /* Current data sector */
#if !_FS_READONLY
DWORD dir_sect; /* Sector containing the directory entry */
BYTE* dir_ptr; /* Ponter to the directory entry in the window */
DWORD dir_sect; /* Sector containing the directory entry */
BYTE *dir_ptr; /* Ponter to the directory entry in the window */
#endif
#if _USE_FASTSEEK
DWORD* cltbl; /* Pointer to the cluster link map table (null on file open) */
DWORD *cltbl; /* Pointer to the cluster link map table (null on file open) */
#endif
#if _FS_SHARE
UINT lockid; /* File lock ID (index of file semaphore table) */
UINT lockid; /* File lock ID (index of file semaphore table) */
#endif
#if !_FS_TINY
BYTE buf[_MAX_SS]; /* File data read/write buffer */
BYTE buf[_MAX_SS]; /* File data read/write buffer */
#endif
} FIL;
@ -333,18 +336,19 @@ typedef struct {
/* Directory object structure (DIR) */
typedef struct {
FATFS* fs; /* Pointer to the owner file system object */
WORD id; /* Owner file system mount ID */
WORD index; /* Current read/write index number */
DWORD sclust; /* Table start cluster (0:Root dir) */
DWORD clust; /* Current cluster */
DWORD sect; /* Current sector */
BYTE* dir; /* Pointer to the current SFN entry in the win[] */
BYTE* fn; /* Pointer to the SFN (in/out) {file[8],ext[3],status[1]} */
typedef struct
{
FATFS *fs; /* Pointer to the owner file system object */
WORD id; /* Owner file system mount ID */
WORD index; /* Current read/write index number */
DWORD sclust; /* Table start cluster (0:Root dir) */
DWORD clust; /* Current cluster */
DWORD sect; /* Current sector */
BYTE *dir; /* Pointer to the current SFN entry in the win[] */
BYTE *fn; /* Pointer to the SFN (in/out) {file[8],ext[3],status[1]} */
#if _USE_LFN
WCHAR* lfn; /* Pointer to the LFN working buffer */
WORD lfn_idx; /* Last matched LFN index number (0xFFFF:No LFN) */
WCHAR *lfn; /* Pointer to the LFN working buffer */
WORD lfn_idx; /* Last matched LFN index number (0xFFFF:No LFN) */
#endif
} DIR;
@ -352,16 +356,17 @@ typedef struct {
/* File status structure (FILINFO) */
typedef struct {
DWORD fsize; /* File size */
WORD fdate; /* Last modified date */
WORD ftime; /* Last modified time */
BYTE fattrib; /* Attribute */
TCHAR fname[13]; /* Short file name (8.3 format) */
DWORD clust; /* start cluster */
typedef struct
{
DWORD fsize; /* File size */
WORD fdate; /* Last modified date */
WORD ftime; /* Last modified time */
BYTE fattrib; /* Attribute */
TCHAR fname[13]; /* Short file name (8.3 format) */
DWORD clust; /* start cluster */
#if _USE_LFN
TCHAR* lfname; /* Pointer to the LFN buffer */
UINT lfsize; /* Size of LFN buffer in TCHAR */
TCHAR *lfname; /* Pointer to the LFN buffer */
UINT lfsize; /* Size of LFN buffer in TCHAR */
#endif
} FILINFO;
@ -369,26 +374,27 @@ typedef struct {
/* File function return code (FRESULT) */
typedef enum {
FR_OK = 0, /* (0) Succeeded */
FR_DISK_ERR, /* (1) A hard error occured in the low level disk I/O layer */
FR_INT_ERR, /* (2) Assertion failed */
FR_NOT_READY, /* (3) The physical drive cannot work */
FR_NO_FILE, /* (4) Could not find the file */
FR_NO_PATH, /* (5) Could not find the path */
FR_INVALID_NAME, /* (6) The path name format is invalid */
FR_DENIED, /* (7) Acces denied due to prohibited access or directory full */
FR_EXIST, /* (8) Acces denied due to prohibited access */
FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */
FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */
FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */
FR_NOT_ENABLED, /* (12) The volume has no work area */
FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume on the physical drive */
FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any parameter error */
FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */
FR_LOCKED, /* (16) The operation is rejected according to the file shareing policy */
FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */
FR_TOO_MANY_OPEN_FILES /* (18) Number of open files > _FS_SHARE */
typedef enum
{
FR_OK = 0, /* (0) Succeeded */
FR_DISK_ERR, /* (1) A hard error occured in the low level disk I/O layer */
FR_INT_ERR, /* (2) Assertion failed */
FR_NOT_READY, /* (3) The physical drive cannot work */
FR_NO_FILE, /* (4) Could not find the file */
FR_NO_PATH, /* (5) Could not find the path */
FR_INVALID_NAME, /* (6) The path name format is invalid */
FR_DENIED, /* (7) Acces denied due to prohibited access or directory full */
FR_EXIST, /* (8) Acces denied due to prohibited access */
FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */
FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */
FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */
FR_NOT_ENABLED, /* (12) The volume has no work area */
FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume on the physical drive */
FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any parameter error */
FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */
FR_LOCKED, /* (16) The operation is rejected according to the file shareing policy */
FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */
FR_TOO_MANY_OPEN_FILES /* (18) Number of open files > _FS_SHARE */
} FRESULT;
@ -397,50 +403,51 @@ typedef enum {
/* FatFs module application interface */
/* Low Level functions */
FRESULT l_openfilebycluster(FATFS *fs, FIL *fp, const TCHAR *path, DWORD clust, DWORD fsize); /* Open a file by its start cluster using supplied file size */
FRESULT l_opendirbycluster (FATFS *fs, DIR *dj, const TCHAR *path, DWORD clust);
FRESULT l_openfilebycluster( FATFS *fs, FIL *fp, const TCHAR *path, DWORD clust,
DWORD fsize ); /* Open a file by its start cluster using supplied file size */
FRESULT l_opendirbycluster ( FATFS *fs, DIR *dj, const TCHAR *path, DWORD clust );
/* application level functions */
FRESULT f_mount (BYTE, FATFS*); /* Mount/Unmount a logical drive */
FRESULT f_open (FIL*, const TCHAR*, BYTE); /* Open or create a file */
FRESULT f_read (FIL*, void*, UINT, UINT*); /* Read data from a file */
FRESULT f_lseek (FIL*, DWORD); /* Move file pointer of a file object */
FRESULT f_close (FIL*); /* Close an open file object */
FRESULT f_opendir (DIR*, const TCHAR*); /* Open an existing directory */
FRESULT f_readdir (DIR*, FILINFO*); /* Read a directory item */
FRESULT f_stat (const TCHAR*, FILINFO*); /* Get file status */
FRESULT f_mount ( BYTE, FATFS * ); /* Mount/Unmount a logical drive */
FRESULT f_open ( FIL *, const TCHAR *, BYTE ); /* Open or create a file */
FRESULT f_read ( FIL *, void *, UINT, UINT * ); /* Read data from a file */
FRESULT f_lseek ( FIL *, DWORD ); /* Move file pointer of a file object */
FRESULT f_close ( FIL * ); /* Close an open file object */
FRESULT f_opendir ( DIR *, const TCHAR * ); /* Open an existing directory */
FRESULT f_readdir ( DIR *, FILINFO * ); /* Read a directory item */
FRESULT f_stat ( const TCHAR *, FILINFO * ); /* Get file status */
#if !_FS_READONLY
FRESULT f_write (FIL*, const void*, UINT, UINT*); /* Write data to a file */
FRESULT f_getfree (const TCHAR*, DWORD*, FATFS**); /* Get number of free clusters on the drive */
FRESULT f_truncate (FIL*); /* Truncate file */
FRESULT f_sync (FIL*); /* Flush cached data of a writing file */
FRESULT f_unlink (const TCHAR*); /* Delete an existing file or directory */
FRESULT f_mkdir (const TCHAR*); /* Create a new directory */
FRESULT f_chmod (const TCHAR*, BYTE, BYTE); /* Change attriburte of the file/dir */
FRESULT f_utime (const TCHAR*, const FILINFO*); /* Change timestamp of the file/dir */
FRESULT f_rename (const TCHAR*, const TCHAR*); /* Rename/Move a file or directory */
FRESULT f_write ( FIL *, const void *, UINT, UINT * ); /* Write data to a file */
FRESULT f_getfree ( const TCHAR *, DWORD *, FATFS ** ); /* Get number of free clusters on the drive */
FRESULT f_truncate ( FIL * ); /* Truncate file */
FRESULT f_sync ( FIL * ); /* Flush cached data of a writing file */
FRESULT f_unlink ( const TCHAR * ); /* Delete an existing file or directory */
FRESULT f_mkdir ( const TCHAR * ); /* Create a new directory */
FRESULT f_chmod ( const TCHAR *, BYTE, BYTE ); /* Change attriburte of the file/dir */
FRESULT f_utime ( const TCHAR *, const FILINFO * ); /* Change timestamp of the file/dir */
FRESULT f_rename ( const TCHAR *, const TCHAR * ); /* Rename/Move a file or directory */
#endif
#if _USE_FORWARD
FRESULT f_forward (FIL*, UINT(*)(const BYTE*,UINT), UINT, UINT*); /* Forward data to the stream */
FRESULT f_forward ( FIL *, UINT( * )( const BYTE *, UINT ), UINT, UINT * ); /* Forward data to the stream */
#endif
#if _USE_MKFS
FRESULT f_mkfs (BYTE, BYTE, UINT); /* Create a file system on the drive */
FRESULT f_mkfs ( BYTE, BYTE, UINT ); /* Create a file system on the drive */
#endif
#if _FS_RPATH
FRESULT f_chdrive (BYTE); /* Change current drive */
FRESULT f_chdir (const TCHAR*); /* Change current directory */
FRESULT f_getcwd (TCHAR*, UINT); /* Get current directory */
FRESULT f_chdrive ( BYTE ); /* Change current drive */
FRESULT f_chdir ( const TCHAR * ); /* Change current directory */
FRESULT f_getcwd ( TCHAR *, UINT ); /* Get current directory */
#endif
#if _USE_STRFUNC
int f_putc (TCHAR, FIL*); /* Put a character to the file */
int f_puts (const TCHAR*, FIL*); /* Put a string to the file */
int f_printf (FIL*, const TCHAR*, ...); /* Put a formatted string to the file */
TCHAR* f_gets (TCHAR*, int, FIL*); /* Get a string from the file */
int f_putc ( TCHAR, FIL * ); /* Put a character to the file */
int f_puts ( const TCHAR *, FIL * ); /* Put a string to the file */
int f_printf ( FIL *, const TCHAR *, ... ); /* Put a formatted string to the file */
TCHAR *f_gets ( TCHAR *, int, FIL * ); /* Get a string from the file */
#ifndef EOF
#define EOF (-1)
#endif
@ -458,25 +465,25 @@ TCHAR* f_gets (TCHAR*, int, FIL*); /* Get a string from the file */
/* RTC function */
#if !_FS_READONLY
DWORD get_fattime (void);
DWORD get_fattime ( void );
#endif
/* Unicode support functions */
#if _USE_LFN /* Unicode - OEM code conversion */
WCHAR ff_convert (WCHAR, UINT); /* OEM-Unicode bidirectional conversion */
WCHAR ff_wtoupper (WCHAR); /* Unicode upper-case conversion */
#if _USE_LFN == 3 /* Memory functions */
void* ff_memalloc (UINT); /* Allocate memory block */
void ff_memfree (void*); /* Free memory block */
#if _USE_LFN /* Unicode - OEM code conversion */
WCHAR ff_convert ( WCHAR, UINT ); /* OEM-Unicode bidirectional conversion */
WCHAR ff_wtoupper ( WCHAR ); /* Unicode upper-case conversion */
#if _USE_LFN == 3 /* Memory functions */
void *ff_memalloc ( UINT ); /* Allocate memory block */
void ff_memfree ( void * ); /* Free memory block */
#endif
#endif
/* Sync functions */
#if _FS_REENTRANT
int ff_cre_syncobj (BYTE, _SYNC_t*);/* Create a sync object */
int ff_del_syncobj (_SYNC_t); /* Delete a sync object */
int ff_req_grant (_SYNC_t); /* Lock sync object */
void ff_rel_grant (_SYNC_t); /* Unlock sync object */
int ff_cre_syncobj ( BYTE, _SYNC_t * ); /* Create a sync object */
int ff_del_syncobj ( _SYNC_t ); /* Delete a sync object */
int ff_req_grant ( _SYNC_t ); /* Lock sync object */
void ff_rel_grant ( _SYNC_t ); /* Unlock sync object */
#endif
@ -488,56 +495,56 @@ void ff_rel_grant (_SYNC_t); /* Unlock sync object */
/* File access control and file status flags (FIL.flag) */
#define FA_READ 0x01
#define FA_OPEN_EXISTING 0x00
#define FA__ERROR 0x80
#define FA_READ 0x01
#define FA_OPEN_EXISTING 0x00
#define FA__ERROR 0x80
#if !_FS_READONLY
#define FA_WRITE 0x02
#define FA_CREATE_NEW 0x04
#define FA_CREATE_ALWAYS 0x08
#define FA_OPEN_ALWAYS 0x10
#define FA__WRITTEN 0x20
#define FA__DIRTY 0x40
#define FA_WRITE 0x02
#define FA_CREATE_NEW 0x04
#define FA_CREATE_ALWAYS 0x08
#define FA_OPEN_ALWAYS 0x10
#define FA__WRITTEN 0x20
#define FA__DIRTY 0x40
#endif
/* FAT sub type (FATFS.fs_type) */
#define FS_FAT12 1
#define FS_FAT16 2
#define FS_FAT32 3
#define FS_FAT12 1
#define FS_FAT16 2
#define FS_FAT32 3
/* File attribute bits for directory entry */
#define AM_RDO 0x01 /* Read only */
#define AM_HID 0x02 /* Hidden */
#define AM_SYS 0x04 /* System */
#define AM_VOL 0x08 /* Volume label */
#define AM_LFN 0x0F /* LFN entry */
#define AM_DIR 0x10 /* Directory */
#define AM_ARC 0x20 /* Archive */
#define AM_MASK 0x3F /* Mask of defined bits */
#define AM_RDO 0x01 /* Read only */
#define AM_HID 0x02 /* Hidden */
#define AM_SYS 0x04 /* System */
#define AM_VOL 0x08 /* Volume label */
#define AM_LFN 0x0F /* LFN entry */
#define AM_DIR 0x10 /* Directory */
#define AM_ARC 0x20 /* Archive */
#define AM_MASK 0x3F /* Mask of defined bits */
/* Fast seek function */
#define CREATE_LINKMAP 0xFFFFFFFF
#define CREATE_LINKMAP 0xFFFFFFFF
/*--------------------------------*/
/* Multi-byte word access macros */
#if _WORD_ACCESS == 1 /* Enable word access to the FAT structure */
#define LD_WORD(ptr) (WORD)(*(WORD*)(BYTE*)(ptr))
#define LD_DWORD(ptr) (DWORD)(*(DWORD*)(BYTE*)(ptr))
#define ST_WORD(ptr,val) *(WORD*)(BYTE*)(ptr)=(WORD)(val)
#define ST_DWORD(ptr,val) *(DWORD*)(BYTE*)(ptr)=(DWORD)(val)
#else /* Use byte-by-byte access to the FAT structure */
#define LD_WORD(ptr) (WORD)(((WORD)*(BYTE*)((ptr)+1)<<8)|(WORD)*(BYTE*)(ptr))
#define LD_DWORD(ptr) (DWORD)(((DWORD)*(BYTE*)((ptr)+3)<<24)|((DWORD)*(BYTE*)((ptr)+2)<<16)|((WORD)*(BYTE*)((ptr)+1)<<8)|*(BYTE*)(ptr))
#define ST_WORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *(BYTE*)((ptr)+1)=(BYTE)((WORD)(val)>>8)
#define ST_DWORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *(BYTE*)((ptr)+1)=(BYTE)((WORD)(val)>>8); *(BYTE*)((ptr)+2)=(BYTE)((DWORD)(val)>>16); *(BYTE*)((ptr)+3)=(BYTE)((DWORD)(val)>>24)
#if _WORD_ACCESS == 1 /* Enable word access to the FAT structure */
#define LD_WORD(ptr) (WORD)(*(WORD*)(BYTE*)(ptr))
#define LD_DWORD(ptr) (DWORD)(*(DWORD*)(BYTE*)(ptr))
#define ST_WORD(ptr,val) *(WORD*)(BYTE*)(ptr)=(WORD)(val)
#define ST_DWORD(ptr,val) *(DWORD*)(BYTE*)(ptr)=(DWORD)(val)
#else /* Use byte-by-byte access to the FAT structure */
#define LD_WORD(ptr) (WORD)(((WORD)*(BYTE*)((ptr)+1)<<8)|(WORD)*(BYTE*)(ptr))
#define LD_DWORD(ptr) (DWORD)(((DWORD)*(BYTE*)((ptr)+3)<<24)|((DWORD)*(BYTE*)((ptr)+2)<<16)|((WORD)*(BYTE*)((ptr)+1)<<8)|*(BYTE*)(ptr))
#define ST_WORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *(BYTE*)((ptr)+1)=(BYTE)((WORD)(val)>>8)
#define ST_DWORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *(BYTE*)((ptr)+1)=(BYTE)((WORD)(val)>>8); *(BYTE*)((ptr)+2)=(BYTE)((DWORD)(val)>>16); *(BYTE*)((ptr)+3)=(BYTE)((DWORD)(val)>>24)
#endif
#ifdef __cplusplus

View File

@ -7,26 +7,26 @@
/
/----------------------------------------------------------------------------*/
#ifndef _FFCONF
#define _FFCONF 8255 /* Revision ID */
#define _FFCONF 8255 /* Revision ID */
/*---------------------------------------------------------------------------/
/ Function and Buffer Configurations
/----------------------------------------------------------------------------*/
#define _FS_TINY 0 /* 0:Normal or 1:Tiny */
#define _FS_TINY 0 /* 0:Normal or 1:Tiny */
/* When _FS_TINY is set to 1, FatFs uses the sector buffer in the file system
/ object instead of the sector buffer in the individual file object for file
/ data transfer. This reduces memory consumption 512 bytes each file object. */
#define _FS_READONLY 0 /* 0:Read/Write or 1:Read only */
#define _FS_READONLY 0 /* 0:Read/Write or 1:Read only */
/* Setting _FS_READONLY to 1 defines read only configuration. This removes
/ writing functions, f_write, f_sync, f_unlink, f_mkdir, f_chmod, f_rename,
/ f_truncate and useless f_getfree. */
#define _FS_MINIMIZE 0 /* 0 to 3 */
#define _FS_MINIMIZE 0 /* 0 to 3 */
/* The _FS_MINIMIZE option defines minimization level to remove some functions.
/
/ 0: Full function.
@ -36,19 +36,19 @@
/ 3: f_lseek is removed in addition to 2. */
#define _USE_STRFUNC 1 /* 0:Disable or 1/2:Enable */
#define _USE_STRFUNC 1 /* 0:Disable or 1/2:Enable */
/* To enable string functions, set _USE_STRFUNC to 1 or 2. */
#define _USE_MKFS 0 /* 0:Disable or 1:Enable */
#define _USE_MKFS 0 /* 0:Disable or 1:Enable */
/* To enable f_mkfs function, set _USE_MKFS to 1 and set _FS_READONLY to 0 */
#define _USE_FORWARD 0 /* 0:Disable or 1:Enable */
#define _USE_FORWARD 0 /* 0:Disable or 1:Enable */
/* To enable f_forward function, set _USE_FORWARD to 1 and set _FS_TINY to 1. */
#define _USE_FASTSEEK 1 /* 0:Disable or 1:Enable */
#define _USE_FASTSEEK 1 /* 0:Disable or 1:Enable */
/* To enable fast seek feature, set _USE_FASTSEEK to 1. */
@ -57,7 +57,7 @@
/ Locale and Namespace Configurations
/----------------------------------------------------------------------------*/
#define _CODE_PAGE 1252
#define _CODE_PAGE 1252
/* The _CODE_PAGE specifies the OEM code page to be used on the target system.
/ Incorrect setting of the code page can cause a file open failure.
/
@ -86,12 +86,12 @@
/ 857 - Turkish (OEM)
/ 862 - Hebrew (OEM)
/ 874 - Thai (OEM, Windows)
/ 1 - ASCII only (Valid for non LFN cfg.)
/ 1 - ASCII only (Valid for non LFN cfg.)
*/
#define _USE_LFN 1 /* 0 to 3 */
#define _MAX_LFN 255 /* Maximum LFN length to handle (12 to 255) */
#define _USE_LFN 1 /* 0 to 3 */
#define _MAX_LFN 255 /* Maximum LFN length to handle (12 to 255) */
/* The _USE_LFN option switches the LFN support.
/
/ 0: Disable LFN feature. _MAX_LFN and _LFN_UNICODE have no effect.
@ -105,12 +105,12 @@
/ ff_memalloc() and ff_memfree() must be added to the project. */
#define _LFN_UNICODE 0 /* 0:ANSI/OEM or 1:Unicode */
#define _LFN_UNICODE 0 /* 0:ANSI/OEM or 1:Unicode */
/* To switch the character code set on FatFs API to Unicode,
/ enable LFN feature and set _LFN_UNICODE to 1. */
#define _FS_RPATH 2 /* 0 to 2 */
#define _FS_RPATH 2 /* 0 to 2 */
/* The _FS_RPATH option configures relative path feature.
/
/ 0: Disable relative path feature and remove related functions.
@ -125,11 +125,11 @@
/ Physical Drive Configurations
/----------------------------------------------------------------------------*/
#define _VOLUMES 1
#define _VOLUMES 1
/* Number of volumes (logical drives) to be used. */
#define _MAX_SS 512 /* 512, 1024, 2048 or 4096 */
#define _MAX_SS 512 /* 512, 1024, 2048 or 4096 */
/* Maximum sector size to be handled.
/ Always set 512 for memory card and hard disk but a larger value may be
/ required for floppy disk (512/1024) and optical disk (512/2048).
@ -137,13 +137,13 @@
/ to the disk_ioctl function. */
#define _MULTI_PARTITION 0 /* 0:Single partition or 1:Multiple partition */
#define _MULTI_PARTITION 0 /* 0:Single partition or 1:Multiple partition */
/* When set to 0, each volume is bound to the same physical drive number and
/ it can mount only first primaly partition. When it is set to 1, each volume
/ is tied to the partitions listed in VolToPart[]. */
#define _USE_ERASE 0 /* 0:Disable or 1:Enable */
#define _USE_ERASE 0 /* 0:Disable or 1:Enable */
/* To enable sector erase feature, set _USE_ERASE to 1. */
@ -152,7 +152,7 @@
/ System Configurations
/----------------------------------------------------------------------------*/
#define _WORD_ACCESS 0 /* 0 or 1 */
#define _WORD_ACCESS 0 /* 0 or 1 */
/* Set 0 first and it is always compatible with all platforms. The _WORD_ACCESS
/ option defines which access method is used to the word data on the FAT volume.
/
@ -168,9 +168,9 @@
/* Include a header file here to define sync object types on the O/S */
/* #include <windows.h>, <ucos_ii.h.h>, <semphr.h> or ohters. */
#define _FS_REENTRANT 0 /* 0:Disable or 1:Enable */
#define _FS_TIMEOUT 1000 /* Timeout period in unit of time ticks */
#define _SYNC_t HANDLE /* O/S dependent type of sync object. e.g. HANDLE, OS_EVENT*, ID and etc.. */
#define _FS_REENTRANT 0 /* 0:Disable or 1:Enable */
#define _FS_TIMEOUT 1000 /* Timeout period in unit of time ticks */
#define _SYNC_t HANDLE /* O/S dependent type of sync object. e.g. HANDLE, OS_EVENT*, ID and etc.. */
/* The _FS_REENTRANT option switches the reentrancy of the FatFs module.
/
@ -180,7 +180,7 @@
/ function must be added to the project. */
#define _FS_SHARE 0 /* 0:Disable or >=1:Enable */
#define _FS_SHARE 0 /* 0:Disable or >=1:Enable */
/* To enable file shareing feature, set _FS_SHARE to 1 or greater. The value
defines how many files can be opened simultaneously. */

View File

@ -37,81 +37,113 @@ WCHAR ff_convert(WCHAR w, UINT dir) {
int newcard;
void file_init() {
file_res=f_mount(0, &fatfs);
newcard = 0;
void file_init()
{
file_res = f_mount( 0, &fatfs );
newcard = 0;
}
void file_reinit(void) {
disk_init();
file_init();
void file_reinit( void )
{
disk_init();
file_init();
}
FRESULT dir_open_by_filinfo(DIR* dir, FILINFO* fno) {
return l_opendirbycluster(&fatfs, dir, (TCHAR*)"", fno->clust);
FRESULT dir_open_by_filinfo( DIR *dir, FILINFO *fno )
{
return l_opendirbycluster( &fatfs, dir, ( TCHAR * )"", fno->clust );
}
void file_open_by_filinfo(FILINFO* fno) {
file_res = l_openfilebycluster(&fatfs, &file_handle, (TCHAR*)"", fno->clust, fno->fsize);
void file_open_by_filinfo( FILINFO *fno )
{
file_res = l_openfilebycluster( &fatfs, &file_handle, ( TCHAR * )"", fno->clust, fno->fsize );
}
void file_open(const uint8_t* filename, BYTE flags) {
if (disk_state == DISK_CHANGED) {
file_reinit();
newcard = 1;
}
file_res = f_open(&file_handle, (TCHAR*)filename, flags);
file_block_off = sizeof(file_buf);
file_block_max = sizeof(file_buf);
file_status = file_res ? FILE_ERR : FILE_OK;
void file_open( const uint8_t *filename, BYTE flags )
{
if ( disk_state == DISK_CHANGED )
{
file_reinit();
newcard = 1;
}
file_res = f_open( &file_handle, ( TCHAR * )filename, flags );
file_block_off = sizeof( file_buf );
file_block_max = sizeof( file_buf );
file_status = file_res ? FILE_ERR : FILE_OK;
}
void file_close() {
file_res = f_close(&file_handle);
void file_close()
{
file_res = f_close( &file_handle );
}
void file_seek(uint32_t offset) {
file_res = f_lseek(&file_handle, (DWORD)offset);
void file_seek( uint32_t offset )
{
file_res = f_lseek( &file_handle, ( DWORD )offset );
}
UINT file_read() {
UINT bytes_read;
file_res = f_read(&file_handle, file_buf, sizeof(file_buf), &bytes_read);
return bytes_read;
UINT file_read()
{
UINT bytes_read;
file_res = f_read( &file_handle, file_buf, sizeof( file_buf ), &bytes_read );
return bytes_read;
}
UINT file_write() {
UINT bytes_written;
file_res = f_write(&file_handle, file_buf, sizeof(file_buf), &bytes_written);
if(bytes_written < sizeof(file_buf)) {
printf("wrote less than expected - card full?\n");
}
return bytes_written;
UINT file_write()
{
UINT bytes_written;
file_res = f_write( &file_handle, file_buf, sizeof( file_buf ), &bytes_written );
if ( bytes_written < sizeof( file_buf ) )
{
printf( "wrote less than expected - card full?\n" );
}
return bytes_written;
}
UINT file_readblock(void* buf, uint32_t addr, uint16_t size) {
UINT bytes_read;
file_res = f_lseek(&file_handle, addr);
if(file_handle.fptr != addr) {
return 0;
}
file_res = f_read(&file_handle, buf, size, &bytes_read);
return bytes_read;
UINT file_readblock( void *buf, uint32_t addr, uint16_t size )
{
UINT bytes_read;
file_res = f_lseek( &file_handle, addr );
if ( file_handle.fptr != addr )
{
return 0;
}
file_res = f_read( &file_handle, buf, size, &bytes_read );
return bytes_read;
}
UINT file_writeblock(void* buf, uint32_t addr, uint16_t size) {
UINT bytes_written;
file_res = f_lseek(&file_handle, addr);
if(file_res) return 0;
file_res = f_write(&file_handle, buf, size, &bytes_written);
return bytes_written;
UINT file_writeblock( void *buf, uint32_t addr, uint16_t size )
{
UINT bytes_written;
file_res = f_lseek( &file_handle, addr );
if ( file_res )
{
return 0;
}
file_res = f_write( &file_handle, buf, size, &bytes_written );
return bytes_written;
}
uint8_t file_getc() {
if(file_block_off == file_block_max) {
file_block_max = file_read();
if(file_block_max == 0) file_status = FILE_EOF;
file_block_off = 0;
}
return file_buf[file_block_off++];
uint8_t file_getc()
{
if ( file_block_off == file_block_max )
{
file_block_max = file_read();
if ( file_block_max == 0 )
{
file_status = FILE_EOF;
}
file_block_off = 0;
}
return file_buf[file_block_off++];
}

View File

@ -29,7 +29,7 @@
#include <arm/NXP/LPC17xx/LPC17xx.h>
#include "ff.h"
enum filestates { FILE_OK=0, FILE_ERR, FILE_EOF };
enum filestates { FILE_OK = 0, FILE_ERR, FILE_EOF };
BYTE file_buf[512];
FATFS fatfs;
@ -39,16 +39,16 @@ uint8_t file_lfn[258];
uint16_t file_block_off, file_block_max;
enum filestates file_status;
void file_init(void);
void file_open(const uint8_t* filename, BYTE flags);
FRESULT dir_open_by_filinfo(DIR* dir, FILINFO* fno_param);
void file_open_by_filinfo(FILINFO* fno);
void file_close(void);
void file_seek(uint32_t offset);
UINT file_read(void);
UINT file_write(void);
UINT file_readblock(void* buf, uint32_t addr, uint16_t size);
UINT file_writeblock(void* buf, uint32_t addr, uint16_t size);
void file_init( void );
void file_open( const uint8_t *filename, BYTE flags );
FRESULT dir_open_by_filinfo( DIR *dir, FILINFO *fno_param );
void file_open_by_filinfo( FILINFO *fno );
void file_close( void );
void file_seek( uint32_t offset );
UINT file_read( void );
UINT file_write( void );
UINT file_readblock( void *buf, uint32_t addr, uint16_t size );
UINT file_writeblock( void *buf, uint32_t addr, uint16_t size );
uint8_t file_getc(void);
uint8_t file_getc( void );
#endif

View File

@ -36,300 +36,428 @@
#include "led.h"
#include "sort.h"
uint16_t scan_flat(const char* path) {
DIR dir;
FRESULT res;
FILINFO fno;
fno.lfname = NULL;
res = f_opendir(&dir, (TCHAR*)path);
uint16_t numentries = 0;
if (res == FR_OK) {
for (;;) {
res = f_readdir(&dir, &fno);
if(res != FR_OK || fno.fname[0] == 0)break;
numentries++;
uint16_t scan_flat( const char *path )
{
DIR dir;
FRESULT res;
FILINFO fno;
fno.lfname = NULL;
res = f_opendir( &dir, ( TCHAR * )path );
uint16_t numentries = 0;
if ( res == FR_OK )
{
for ( ;; )
{
res = f_readdir( &dir, &fno );
if ( res != FR_OK || fno.fname[0] == 0 )
{
break;
}
numentries++;
}
}
}
return numentries;
return numentries;
}
uint32_t scan_dir(char* path, FILINFO* fno_param, char mkdb, uint32_t this_dir_tgt) {
DIR dir;
FILINFO fno;
FRESULT res;
uint8_t len;
TCHAR* fn;
static unsigned char depth = 0;
static uint32_t crc, fncrc;
static uint32_t db_tgt;
static uint32_t next_subdir_tgt;
static uint32_t parent_tgt;
static uint32_t dir_end = 0;
/* static uint8_t was_empty = 0;*/
static uint16_t num_files_total = 0;
static uint16_t num_dirs_total = 0;
uint32_t dir_tgt;
uint32_t switched_dir_tgt = 0;
uint16_t numentries;
uint32_t dirsize;
uint8_t pass = 0;
char buf[7];
char *size_units[3] = {" ", "k", "M"};
uint32_t entry_fsize;
uint8_t entry_unit_idx;
uint16_t entrycnt;
uint32_t scan_dir( char *path, FILINFO *fno_param, char mkdb, uint32_t this_dir_tgt )
{
DIR dir;
FILINFO fno;
FRESULT res;
uint8_t len;
TCHAR *fn;
static unsigned char depth = 0;
static uint32_t crc, fncrc;
static uint32_t db_tgt;
static uint32_t next_subdir_tgt;
static uint32_t parent_tgt;
static uint32_t dir_end = 0;
static uint8_t was_empty = 0;
static uint16_t num_files_total = 0;
static uint16_t num_dirs_total = 0;
uint32_t dir_tgt;
uint32_t switched_dir_tgt = 0;
uint16_t numentries;
uint32_t dirsize;
uint8_t pass = 0;
char buf[7];
char *size_units[3] = {" ", "k", "M"};
uint32_t entry_fsize;
uint8_t entry_unit_idx;
uint16_t entrycnt;
dir_tgt = this_dir_tgt;
if(depth==0) {
crc = 0;
db_tgt = SRAM_DB_ADDR+0x10;
dir_tgt = SRAM_DIR_ADDR;
next_subdir_tgt = SRAM_DIR_ADDR;
this_dir_tgt = SRAM_DIR_ADDR;
parent_tgt = 0;
printf("root dir @%lx\n", dir_tgt);
}
dir_tgt = this_dir_tgt;
fno.lfsize = 255;
fno.lfname = (TCHAR*)file_lfn;
numentries=0;
for(pass = 0; pass < (mkdb ? 2 : 1); pass++) {
if(pass) {
dirsize = 4*(numentries);
if(((next_subdir_tgt + dirsize + 8) & 0xff0000) > (next_subdir_tgt & 0xff0000)) {
printf("switchdir! old=%lX ", next_subdir_tgt + dirsize + 4);
next_subdir_tgt &= 0xffff0000;
next_subdir_tgt += 0x00010004;
printf("new=%lx\n", next_subdir_tgt);
dir_tgt &= 0xffff0000;
dir_tgt += 0x00010004;
}
switched_dir_tgt = dir_tgt;
next_subdir_tgt += dirsize + 4;
if(parent_tgt) next_subdir_tgt += 4;
if(next_subdir_tgt > dir_end) {
dir_end = next_subdir_tgt;
}
DBG_FS printf("path=%s depth=%d ptr=%lx entries=%d parent=%lx next subdir @%lx\n", path, depth, db_tgt, numentries, parent_tgt, next_subdir_tgt);
if(mkdb) {
num_dirs_total++;
// printf("d=%d Saving %lx to Address %lx [end]\n", depth, 0L, next_subdir_tgt - 4);
sram_writelong(0L, next_subdir_tgt - 4);
}
if ( depth == 0 )
{
crc = 0;
db_tgt = SRAM_DB_ADDR + 0x10;
dir_tgt = SRAM_DIR_ADDR;
next_subdir_tgt = SRAM_DIR_ADDR;
this_dir_tgt = SRAM_DIR_ADDR;
parent_tgt = 0;
printf( "root dir @%lx\n", dir_tgt );
}
if(fno_param) {
res = dir_open_by_filinfo(&dir, fno_param);
} else {
res = f_opendir(&dir, path);
}
if (res == FR_OK) {
if(pass && parent_tgt && mkdb) {
/* write backlink to parent dir
switch to next bank if record does not fit in current bank */
if((db_tgt&0xffff) > ((0x10000-(sizeof(next_subdir_tgt)+sizeof(len)+4))&0xffff)) {
printf("switch! old=%lx ", db_tgt);
db_tgt &= 0xffff0000;
db_tgt += 0x00010000;
printf("new=%lx\n", db_tgt);
}
// printf("writing link to parent, %lx to address %lx [../]\n", parent_tgt-SRAM_MENU_ADDR, db_tgt);
sram_writelong((parent_tgt-SRAM_MENU_ADDR), db_tgt);
sram_writebyte(0, db_tgt+sizeof(next_subdir_tgt));
sram_writeblock("../\0", db_tgt+sizeof(next_subdir_tgt)+sizeof(len), 4);
sram_writelong((db_tgt-SRAM_MENU_ADDR)|((uint32_t)0x81<<24), dir_tgt);
db_tgt += sizeof(next_subdir_tgt)+sizeof(len)+4;
dir_tgt += 4;
}
len = strlen((char*)path);
/* scan at most DIR_FILE_MAX entries per directory */
for(entrycnt=0; entrycnt < DIR_FILE_MAX; entrycnt++) {
// toggle_read_led();
res = f_readdir(&dir, &fno);
if (res != FR_OK || fno.fname[0] == 0) {
if(pass) {
/* if(!numentries) was_empty=1;*/
}
break;
}
fn = *fno.lfname ? fno.lfname : fno.fname;
if ((*fn == '.') || !(strncasecmp(fn, SYS_DIR_NAME, strlen(SYS_DIR_NAME)+1))) continue;
if (fno.fattrib & AM_DIR) {
depth++;
if(depth < FS_MAX_DEPTH) {
numentries++;
if(pass && mkdb) {
path[len]='/';
strncpy(path+len+1, (char*)fn, sizeof(fs_path)-len);
uint16_t pathlen = 0;
uint32_t old_db_tgt = 0;
if(mkdb) {
pathlen = strlen(path);
DBG_FS printf("d=%d Saving %lx to Address %lx [dir]\n", depth, db_tgt, dir_tgt);
/* save element:
- path name
- pointer to sub dir structure */
if((db_tgt&0xffff) > ((0x10000-(sizeof(next_subdir_tgt) + sizeof(len) + pathlen + 2))&0xffff)) {
printf("switch! old=%lx ", db_tgt);
db_tgt &= 0xffff0000;
db_tgt += 0x00010000;
printf("new=%lx\n", db_tgt);
}
/* write element pointer to current dir structure */
sram_writelong((db_tgt-SRAM_MENU_ADDR)|((uint32_t)0x80<<24), dir_tgt);
/* save element:
- path name
- pointer to sub dir structure
moved below */
old_db_tgt = db_tgt;
db_tgt += sizeof(next_subdir_tgt) + sizeof(len) + pathlen + 2;
}
parent_tgt = this_dir_tgt;
/* scan subdir before writing current dir element to account for bank switches */
uint32_t corrected_subdir_tgt = scan_dir(path, &fno, mkdb, next_subdir_tgt);
if(mkdb) {
DBG_FS printf(" Saving dir descriptor to %lx tgt=%lx, path=%s\n", old_db_tgt, corrected_subdir_tgt, path);
sram_writelong((corrected_subdir_tgt-SRAM_MENU_ADDR), old_db_tgt);
sram_writebyte(len+1, old_db_tgt+sizeof(next_subdir_tgt));
sram_writeblock(path, old_db_tgt+sizeof(next_subdir_tgt)+sizeof(len), pathlen);
sram_writeblock("/\0", old_db_tgt + sizeof(next_subdir_tgt) + sizeof(len) + pathlen, 2);
}
dir_tgt += 4;
/* was_empty = 0;*/
} else if(!mkdb) {
path[len]='/';
strncpy(path+len+1, (char*)fn, sizeof(fs_path)-len);
scan_dir(path, &fno, mkdb, next_subdir_tgt);
fno.lfsize = 255;
fno.lfname = ( TCHAR * )file_lfn;
numentries = 0;
for ( pass = 0; pass < ( mkdb ? 2 : 1 ); pass++ )
{
if ( pass )
{
dirsize = 4 * ( numentries );
if ( ( ( next_subdir_tgt + dirsize + 8 ) & 0xff0000 ) > ( next_subdir_tgt & 0xff0000 ) )
{
printf( "switchdir! old=%lX ", next_subdir_tgt + dirsize + 4 );
next_subdir_tgt &= 0xffff0000;
next_subdir_tgt += 0x00010004;
printf( "new=%lx\n", next_subdir_tgt );
dir_tgt &= 0xffff0000;
dir_tgt += 0x00010004;
}
}
depth--;
path[len]=0;
} else {
SNES_FTYPE type = determine_filetype((char*)fn);
if(type != TYPE_UNKNOWN) {
numentries++;
if(pass) {
if(mkdb) {
num_files_total++;
/* snes_romprops_t romprops; */
path[len]='/';
strncpy(path+len+1, (char*)fn, sizeof(fs_path)-len);
uint16_t pathlen = strlen(path);
switch(type) {
case TYPE_IPS:
case TYPE_SMC:
case TYPE_SPC:
/* write element pointer to current dir structure */
DBG_FS printf("d=%d Saving %lX to Address %lX [file %s]\n", depth, db_tgt, dir_tgt, path);
if((db_tgt&0xffff) > ((0x10000-(sizeof(len) + pathlen + sizeof(buf)-1 + 1))&0xffff)) {
printf("switch! old=%lx ", db_tgt);
db_tgt &= 0xffff0000;
db_tgt += 0x00010000;
printf("new=%lx\n", db_tgt);
switched_dir_tgt = dir_tgt;
next_subdir_tgt += dirsize + 4;
if ( parent_tgt )
{
next_subdir_tgt += 4;
}
if ( next_subdir_tgt > dir_end )
{
dir_end = next_subdir_tgt;
}
DBG_FS printf( "path=%s depth=%d ptr=%lx entries=%d parent=%lx next subdir @%lx\n", path, depth, db_tgt, numentries,
parent_tgt, next_subdir_tgt );
if ( mkdb )
{
num_dirs_total++;
// printf("d=%d Saving %lx to Address %lx [end]\n", depth, 0L, next_subdir_tgt - 4);
sram_writelong( 0L, next_subdir_tgt - 4 );
}
}
if ( fno_param )
{
res = dir_open_by_filinfo( &dir, fno_param );
}
else
{
res = f_opendir( &dir, path );
}
if ( res == FR_OK )
{
if ( pass && parent_tgt && mkdb )
{
/* write backlink to parent dir
switch to next bank if record does not fit in current bank */
if ( ( db_tgt & 0xffff ) > ( ( 0x10000 - ( sizeof( next_subdir_tgt ) + sizeof( len ) + 4 ) ) & 0xffff ) )
{
printf( "switch! old=%lx ", db_tgt );
db_tgt &= 0xffff0000;
db_tgt += 0x00010000;
printf( "new=%lx\n", db_tgt );
}
// printf("writing link to parent, %lx to address %lx [../]\n", parent_tgt-SRAM_MENU_ADDR, db_tgt);
sram_writelong( ( parent_tgt - SRAM_MENU_ADDR ), db_tgt );
sram_writebyte( 0, db_tgt + sizeof( next_subdir_tgt ) );
sram_writeblock( "../\0", db_tgt + sizeof( next_subdir_tgt ) + sizeof( len ), 4 );
sram_writelong( ( db_tgt - SRAM_MENU_ADDR ) | ( ( uint32_t )0x81 << 24 ), dir_tgt );
db_tgt += sizeof( next_subdir_tgt ) + sizeof( len ) + 4;
dir_tgt += 4;
}
len = strlen( ( char * )path );
/* scan at most DIR_FILE_MAX entries per directory */
for ( entrycnt = 0; entrycnt < DIR_FILE_MAX; entrycnt++ )
{
// toggle_read_led();
res = f_readdir( &dir, &fno );
if ( res != FR_OK || fno.fname[0] == 0 )
{
if ( pass )
{
/* if(!numentries) was_empty=1;*/
}
sram_writelong((db_tgt-SRAM_MENU_ADDR) | ((uint32_t)type << 24), dir_tgt);
dir_tgt += 4;
/* save element:
- index of last slash character
- file name
- file size */
/* sram_writeblock((uint8_t*)&romprops, db_tgt, sizeof(romprops)); */
entry_fsize = fno.fsize;
entry_unit_idx = 0;
while(entry_fsize > 9999) {
entry_fsize >>= 10;
entry_unit_idx++;
}
snprintf(buf, sizeof(buf), "% 5ld", entry_fsize);
strncat(buf, size_units[entry_unit_idx], 1);
sram_writeblock(buf, db_tgt, sizeof(buf)-1);
sram_writebyte(len+1, db_tgt + sizeof(buf)-1);
sram_writeblock(path, db_tgt + sizeof(len) + sizeof(buf)-1, pathlen + 1);
// sram_writelong(fno.fsize, db_tgt + sizeof(len) + pathlen + 1);
db_tgt += sizeof(len) + pathlen + sizeof(buf)-1 + 1;
break;
case TYPE_UNKNOWN:
default:
break;
}
path[len] = 0;
/* printf("%s ", path);
_delay_ms(30); */
}
} else {
TCHAR* fn2 = fn;
fncrc = 0;
while(*fn2 != 0) {
fncrc += crc_xmodem_update(fncrc, *((unsigned char*)fn2++));
}
crc += fncrc;
fn = *fno.lfname ? fno.lfname : fno.fname;
if ( ( *fn == '.' ) || !( strncasecmp( fn, SYS_DIR_NAME, sizeof( SYS_DIR_NAME ) ) ) )
{
continue;
}
if ( fno.fattrib & AM_DIR )
{
depth++;
if ( depth < FS_MAX_DEPTH )
{
numentries++;
if ( pass && mkdb )
{
path[len] = '/';
strncpy( path + len + 1, ( char * )fn, sizeof( fs_path ) - len );
uint16_t pathlen = 0;
uint32_t old_db_tgt = 0;
if ( mkdb )
{
pathlen = strlen( path );
DBG_FS printf( "d=%d Saving %lx to Address %lx [dir]\n", depth, db_tgt, dir_tgt );
/* save element:
- path name
- pointer to sub dir structure */
if ( ( db_tgt & 0xffff ) > ( ( 0x10000 - ( sizeof( next_subdir_tgt ) + sizeof( len ) + pathlen + 2 ) ) & 0xffff ) )
{
printf( "switch! old=%lx ", db_tgt );
db_tgt &= 0xffff0000;
db_tgt += 0x00010000;
printf( "new=%lx\n", db_tgt );
}
/* write element pointer to current dir structure */
sram_writelong( ( db_tgt - SRAM_MENU_ADDR ) | ( ( uint32_t )0x80 << 24 ), dir_tgt );
/* save element:
- path name
- pointer to sub dir structure
moved below */
old_db_tgt = db_tgt;
db_tgt += sizeof( next_subdir_tgt ) + sizeof( len ) + pathlen + 2;
}
parent_tgt = this_dir_tgt;
/* scan subdir before writing current dir element to account for bank switches */
uint32_t corrected_subdir_tgt = scan_dir( path, &fno, mkdb, next_subdir_tgt );
if ( mkdb )
{
DBG_FS printf( " Saving dir descriptor to %lx tgt=%lx, path=%s\n", old_db_tgt, corrected_subdir_tgt, path );
sram_writelong( ( corrected_subdir_tgt - SRAM_MENU_ADDR ), old_db_tgt );
sram_writebyte( len + 1, old_db_tgt + sizeof( next_subdir_tgt ) );
sram_writeblock( path, old_db_tgt + sizeof( next_subdir_tgt ) + sizeof( len ), pathlen );
sram_writeblock( "/\0", old_db_tgt + sizeof( next_subdir_tgt ) + sizeof( len ) + pathlen, 2 );
}
dir_tgt += 4;
/* was_empty = 0;*/
}
else if ( !mkdb )
{
path[len] = '/';
strncpy( path + len + 1, ( char * )fn, sizeof( fs_path ) - len );
scan_dir( path, &fno, mkdb, next_subdir_tgt );
}
}
depth--;
path[len] = 0;
}
else
{
SNES_FTYPE type = determine_filetype( ( char * )fn );
if ( type != TYPE_UNKNOWN )
{
numentries++;
if ( pass )
{
if ( mkdb )
{
num_files_total++;
/* snes_romprops_t romprops; */
path[len] = '/';
strncpy( path + len + 1, ( char * )fn, sizeof( fs_path ) - len );
uint16_t pathlen = strlen( path );
switch ( type )
{
case TYPE_IPS:
case TYPE_SMC:
case TYPE_SPC:
/* write element pointer to current dir structure */
DBG_FS printf( "d=%d Saving %lX to Address %lX [file %s]\n", depth, db_tgt, dir_tgt, path );
if ( ( db_tgt & 0xffff ) > ( ( 0x10000 - ( sizeof( len ) + pathlen + sizeof( buf ) - 1 + 1 ) ) & 0xffff ) )
{
printf( "switch! old=%lx ", db_tgt );
db_tgt &= 0xffff0000;
db_tgt += 0x00010000;
printf( "new=%lx\n", db_tgt );
}
sram_writelong( ( db_tgt - SRAM_MENU_ADDR ) | ( ( uint32_t )type << 24 ), dir_tgt );
dir_tgt += 4;
/* save element:
- index of last slash character
- file name
- file size */
/* sram_writeblock((uint8_t*)&romprops, db_tgt, sizeof(romprops)); */
entry_fsize = fno.fsize;
entry_unit_idx = 0;
while ( entry_fsize > 9999 )
{
entry_fsize >>= 10;
entry_unit_idx++;
}
snprintf( buf, sizeof( buf ), "% 5ld", entry_fsize );
strncat( buf, size_units[entry_unit_idx], 1 );
sram_writeblock( buf, db_tgt, sizeof( buf ) - 1 );
sram_writebyte( len + 1, db_tgt + sizeof( buf ) - 1 );
sram_writeblock( path, db_tgt + sizeof( len ) + sizeof( buf ) - 1, pathlen + 1 );
// sram_writelong(fno.fsize, db_tgt + sizeof(len) + pathlen + 1);
db_tgt += sizeof( len ) + pathlen + sizeof( buf ) - 1 + 1;
break;
case TYPE_UNKNOWN:
default:
break;
}
path[len] = 0;
/* printf("%s ", path);
_delay_ms(30); */
}
}
else
{
TCHAR *fn2 = fn;
fncrc = 0;
while ( *fn2 != 0 )
{
fncrc += crc_xmodem_update( fncrc, *( ( unsigned char * )fn2++ ) );
}
crc += fncrc;
}
}
}
}
}
}
}
} else uart_putc(0x30+res);
}
DBG_FS printf("db_tgt=%lx dir_end=%lx\n", db_tgt, dir_end);
sram_writelong(db_tgt, SRAM_DB_ADDR+4);
sram_writelong(dir_end, SRAM_DB_ADDR+8);
sram_writeshort(num_files_total, SRAM_DB_ADDR+12);
sram_writeshort(num_dirs_total, SRAM_DB_ADDR+14);
if(depth==0) return crc;
else return switched_dir_tgt;
}
SNES_FTYPE determine_filetype(char* filename) {
char* ext = strrchr(filename, '.');
if(ext == NULL)
return TYPE_UNKNOWN;
if( (!strcasecmp(ext+1, "SMC"))
||(!strcasecmp(ext+1, "SFC"))
||(!strcasecmp(ext+1, "FIG"))
||(!strcasecmp(ext+1, "BS"))
) {
return TYPE_SMC;
}
/* if( (!strcasecmp(ext+1, "IPS"))
||(!strcasecmp(ext+1, "UPS"))
) {
return TYPE_IPS;
}*/
if(!strcasecmp(ext+1, "SPC")) {
return TYPE_SPC;
}
return TYPE_UNKNOWN;
}
FRESULT get_db_id(uint32_t* id) {
file_open((uint8_t*)"/sd2snes/sd2snes.db", FA_READ);
if(file_res == FR_OK) {
file_readblock(id, 0, 4);
/* XXX */// *id=0xdead;
file_close();
} else {
*id=0xdeadbeef;
}
return file_res;
}
int get_num_dirent(uint32_t addr) {
int result = 0;
while(sram_readlong(addr+result*4)) {
result++;
}
return result;
}
void sort_all_dir(uint32_t endaddr) {
uint32_t entries = 0;
uint32_t current_base = SRAM_DIR_ADDR;
while(current_base<(endaddr)) {
while(sram_readlong(current_base+entries*4)) {
entries++;
else
{
uart_putc( 0x30 + res );
}
}
DBG_FS printf( "db_tgt=%lx dir_end=%lx\n", db_tgt, dir_end );
sram_writelong( db_tgt, SRAM_DB_ADDR + 4 );
sram_writelong( dir_end, SRAM_DB_ADDR + 8 );
sram_writeshort( num_files_total, SRAM_DB_ADDR + 12 );
sram_writeshort( num_dirs_total, SRAM_DB_ADDR + 14 );
if ( depth == 0 )
{
return crc;
}
else
{
return switched_dir_tgt;
}
return was_empty; // tricky!
}
SNES_FTYPE determine_filetype( char *filename )
{
char *ext = strrchr( filename, '.' );
if ( ext == NULL )
{
return TYPE_UNKNOWN;
}
if ( ( !strcasecmp( ext + 1, "SMC" ) )
|| ( !strcasecmp( ext + 1, "SFC" ) )
|| ( !strcasecmp( ext + 1, "FIG" ) )
|| ( !strcasecmp( ext + 1, "BS" ) )
)
{
return TYPE_SMC;
}
/* if( (!strcasecmp(ext+1, "IPS"))
||(!strcasecmp(ext+1, "UPS"))
) {
return TYPE_IPS;
}*/
if ( !strcasecmp( ext + 1, "SPC" ) )
{
return TYPE_SPC;
}
return TYPE_UNKNOWN;
}
FRESULT get_db_id( uint32_t *id )
{
file_open( ( uint8_t * )"/sd2snes/sd2snes.db", FA_READ );
if ( file_res == FR_OK )
{
file_readblock( id, 0, 4 );
/* XXX */// *id=0xdead;
file_close();
}
else
{
*id = 0xdeadbeef;
}
return file_res;
}
int get_num_dirent( uint32_t addr )
{
int result = 0;
while ( sram_readlong( addr + result * 4 ) )
{
result++;
}
return result;
}
void sort_all_dir( uint32_t endaddr )
{
uint32_t entries = 0;
uint32_t current_base = SRAM_DIR_ADDR;
while ( current_base < ( endaddr ) )
{
while ( sram_readlong( current_base + entries * 4 ) )
{
entries++;
}
printf( "sorting dir @%lx, entries: %ld\n", current_base, entries );
sort_dir( current_base, entries );
current_base += 4 * entries + 4;
entries = 0;
}
printf("sorting dir @%lx, entries: %ld\n", current_base, entries);
sort_dir(current_base, entries);
current_base += 4*entries + 4;
entries = 0;
}
}

View File

@ -35,24 +35,25 @@
#include "ff.h"
#define FS_MAX_DEPTH (10)
#define SYS_DIR_NAME ((const char*)"sd2snes")
typedef enum {
TYPE_UNKNOWN = 0, /* 0 */
TYPE_SMC, /* 1 */
TYPE_SRM, /* 2 */
TYPE_SPC, /* 3 */
TYPE_IPS /* 4 */
#define FS_MAX_DEPTH (10)
#define SYS_DIR_NAME ((const char*)"sd2snes")
typedef enum
{
TYPE_UNKNOWN = 0, /* 0 */
TYPE_SMC, /* 1 */
TYPE_SRM, /* 2 */
TYPE_SPC, /* 3 */
TYPE_IPS /* 4 */
} SNES_FTYPE;
char fs_path[256];
SNES_FTYPE determine_filetype(char* filename);
SNES_FTYPE determine_filetype( char *filename );
//uint32_t scan_fs();
uint16_t scan_flat(const char* path);
uint32_t scan_dir(char* path, FILINFO* fno_param, char mkdb, uint32_t this_subdir_tgt);
FRESULT get_db_id(uint32_t*);
int get_num_dirent(uint32_t addr);
void sort_all_dir(uint32_t endaddr);
uint16_t scan_flat( const char *path );
uint32_t scan_dir( char *path, FILINFO *fno_param, char mkdb, uint32_t this_subdir_tgt );
FRESULT get_db_id( uint32_t * );
int get_num_dirent( uint32_t addr );
void sort_all_dir( uint32_t endaddr );
#endif

View File

@ -52,156 +52,208 @@
#include "rle.h"
#include "cfgware.h"
void fpga_set_prog_b(uint8_t val) {
if(val)
BITBAND(PROGBREG->FIOSET, PROGBBIT) = 1;
else
BITBAND(PROGBREG->FIOCLR, PROGBBIT) = 1;
}
void fpga_set_cclk(uint8_t val) {
if(val)
BITBAND(CCLKREG->FIOSET, CCLKBIT) = 1;
else
BITBAND(CCLKREG->FIOCLR, CCLKBIT) = 1;
}
int fpga_get_initb() {
return BITBAND(INITBREG->FIOPIN, INITBBIT);
}
void fpga_init() {
/* mainly GPIO directions */
BITBAND(CCLKREG->FIODIR, CCLKBIT) = 1; /* CCLK */
BITBAND(DONEREG->FIODIR, DONEBIT) = 0; /* DONE */
BITBAND(PROGBREG->FIODIR, PROGBBIT) = 1; /* PROG_B */
BITBAND(DINREG->FIODIR, DINBIT) = 1; /* DIN */
BITBAND(INITBREG->FIODIR, INITBBIT) = 0; /* INIT_B */
LPC_GPIO2->FIOMASK1 = 0;
SPI_OFFLOAD=0;
fpga_set_cclk(0); /* initial clk=0 */
}
int fpga_get_done(void) {
return BITBAND(DONEREG->FIOPIN, DONEBIT);
}
void fpga_postinit() {
LPC_GPIO2->FIOMASK1 = 0;
}
void fpga_pgm(uint8_t* filename) {
int MAXRETRIES = 10;
int retries = MAXRETRIES;
uint8_t data;
int i;
tick_t timeout;
/* open configware file */
file_open(filename, FA_READ);
if(file_res) {
uart_putc('?');
uart_putc(0x30+file_res);
return;
}
do {
i=0;
timeout = getticks() + 1;
fpga_set_prog_b(0);
while(BITBAND(PROGBREG->FIOPIN, PROGBBIT)) {
if(getticks() > timeout) {
printf("PROGB is stuck high!\n");
led_panic(LED_PANIC_FPGA_PROGB_STUCK);
}
void fpga_set_prog_b( uint8_t val )
{
if ( val )
{
BITBAND( PROGBREG->FIOSET, PROGBBIT ) = 1;
}
timeout = getticks() + 100;
uart_putc('P');
fpga_set_prog_b(1);
while(!fpga_get_initb()){
if(getticks() > timeout) {
printf("no response from FPGA trying to initiate configuration!\n");
led_panic(LED_PANIC_FPGA_NO_INITB);
}
};
timeout = getticks() + 100;
while(fpga_get_done()) {
if(getticks() > timeout) {
printf("DONE is stuck high!\n");
led_panic(LED_PANIC_FPGA_DONE_STUCK);
}
else
{
BITBAND( PROGBREG->FIOCLR, PROGBBIT ) = 1;
}
LPC_GPIO2->FIOMASK1 = ~(BV(0));
uart_putc('p');
uart_putc('C');
for (;;) {
data = rle_file_getc();
i++;
if (file_status || file_res) break; /* error or eof */
FPGA_SEND_BYTE_SERIAL(data);
}
uart_putc('c');
file_close();
printf("fpga_pgm: %d bytes programmed\n", i);
delay_ms(1);
} while (!fpga_get_done() && retries--);
if(!fpga_get_done()) {
printf("FPGA failed to configure after %d tries.\n", MAXRETRIES);
led_panic(LED_PANIC_FPGA_NOCONF);
}
printf("FPGA configured\n");
fpga_postinit();
}
void fpga_rompgm() {
int MAXRETRIES = 10;
int retries = MAXRETRIES;
uint8_t data;
int i;
tick_t timeout;
do {
i=0;
timeout = getticks() + 100;
fpga_set_prog_b(0);
uart_putc('P');
fpga_set_prog_b(1);
while(!fpga_get_initb()){
if(getticks() > timeout) {
printf("no response from FPGA trying to initiate configuration!\n");
led_panic(LED_PANIC_FPGA_NO_INITB);
}
};
timeout = getticks() + 100;
while(fpga_get_done()) {
if(getticks() > timeout) {
printf("DONE is stuck high!\n");
led_panic(LED_PANIC_FPGA_DONE_STUCK);
}
void fpga_set_cclk( uint8_t val )
{
if ( val )
{
BITBAND( CCLKREG->FIOSET, CCLKBIT ) = 1;
}
LPC_GPIO2->FIOMASK1 = ~(BV(0));
uart_putc('p');
/* open configware file */
rle_mem_init(cfgware, sizeof(cfgware));
printf("sizeof(cfgware) = %d\n", sizeof(cfgware));
for (;;) {
data = rle_mem_getc();
if(rle_state) break;
i++;
FPGA_SEND_BYTE_SERIAL(data);
else
{
BITBAND( CCLKREG->FIOCLR, CCLKBIT ) = 1;
}
uart_putc('c');
printf("fpga_pgm: %d bytes programmed\n", i);
delay_ms(1);
} while (!fpga_get_done() && retries--);
if(!fpga_get_done()) {
printf("FPGA failed to configure after %d tries.\n", MAXRETRIES);
led_panic(LED_PANIC_FPGA_NOCONF);
}
printf("FPGA configured\n");
fpga_postinit();
}
int fpga_get_initb()
{
return BITBAND( INITBREG->FIOPIN, INITBBIT );
}
void fpga_init()
{
/* mainly GPIO directions */
BITBAND( CCLKREG->FIODIR, CCLKBIT ) = 1; /* CCLK */
BITBAND( DONEREG->FIODIR, DONEBIT ) = 0; /* DONE */
BITBAND( PROGBREG->FIODIR, PROGBBIT ) = 1; /* PROG_B */
BITBAND( DINREG->FIODIR, DINBIT ) = 1; /* DIN */
BITBAND( INITBREG->FIODIR, INITBBIT ) = 0; /* INIT_B */
LPC_GPIO2->FIOMASK1 = 0;
SPI_OFFLOAD = 0;
fpga_set_cclk( 0 ); /* initial clk=0 */
}
int fpga_get_done( void )
{
return BITBAND( DONEREG->FIOPIN, DONEBIT );
}
void fpga_postinit()
{
LPC_GPIO2->FIOMASK1 = 0;
}
void fpga_pgm( uint8_t *filename )
{
int MAXRETRIES = 10;
int retries = MAXRETRIES;
uint8_t data;
int i;
tick_t timeout;
do
{
i = 0;
timeout = getticks() + 100;
fpga_set_prog_b( 0 );
if ( BITBAND( PROGBREG->FIOPIN, PROGBBIT ) )
{
printf( "PROGB is stuck high!\n" );
led_panic();
}
uart_putc( 'P' );
fpga_set_prog_b( 1 );
while ( !fpga_get_initb() )
{
if ( getticks() > timeout )
{
printf( "no response from FPGA trying to initiate configuration!\n" );
led_panic();
}
};
if ( fpga_get_done() )
{
printf( "DONE is stuck high!\n" );
led_panic();
}
LPC_GPIO2->FIOMASK1 = ~( BV( 0 ) );
uart_putc( 'p' );
/* open configware file */
file_open( filename, FA_READ );
if ( file_res )
{
uart_putc( '?' );
uart_putc( 0x30 + file_res );
return;
}
uart_putc( 'C' );
for ( ;; )
{
data = rle_file_getc();
i++;
if ( file_status || file_res )
{
break; /* error or eof */
}
FPGA_SEND_BYTE_SERIAL( data );
}
uart_putc( 'c' );
file_close();
printf( "fpga_pgm: %d bytes programmed\n", i );
delay_ms( 1 );
}
while ( !fpga_get_done() && retries-- );
if ( !fpga_get_done() )
{
printf( "FPGA failed to configure after %d tries.\n", MAXRETRIES );
led_panic();
}
printf( "FPGA configured\n" );
fpga_postinit();
}
void fpga_rompgm()
{
int MAXRETRIES = 10;
int retries = MAXRETRIES;
uint8_t data;
int i;
tick_t timeout;
do
{
i = 0;
timeout = getticks() + 100;
fpga_set_prog_b( 0 );
uart_putc( 'P' );
fpga_set_prog_b( 1 );
while ( !fpga_get_initb() )
{
if ( getticks() > timeout )
{
printf( "no response from FPGA trying to initiate configuration!\n" );
led_panic();
}
};
if ( fpga_get_done() )
{
printf( "DONE is stuck high!\n" );
led_panic();
}
LPC_GPIO2->FIOMASK1 = ~( BV( 0 ) );
uart_putc( 'p' );
/* open configware file */
rle_mem_init( cfgware, sizeof( cfgware ) );
printf( "sizeof(cfgware) = %d\n", sizeof( cfgware ) );
for ( ;; )
{
data = rle_mem_getc();
if ( rle_state )
{
break;
}
i++;
FPGA_SEND_BYTE_SERIAL( data );
}
uart_putc( 'c' );
printf( "fpga_pgm: %d bytes programmed\n", i );
delay_ms( 1 );
}
while ( !fpga_get_done() && retries-- );
if ( !fpga_get_done() )
{
printf( "FPGA failed to configure after %d tries.\n", MAXRETRIES );
led_panic();
}
printf( "FPGA configured\n" );
fpga_postinit();
}

View File

@ -30,14 +30,14 @@
#include <arm/NXP/LPC17xx/LPC17xx.h>
#include "bits.h"
void fpga_set_prog_b(uint8_t val);
void fpga_set_cclk(uint8_t val);
int fpga_get_initb(void);
void fpga_set_prog_b( uint8_t val );
void fpga_set_cclk( uint8_t val );
int fpga_get_initb( void );
void fpga_init(void);
void fpga_postinit(void);
void fpga_pgm(uint8_t* filename);
void fpga_rompgm(void);
void fpga_init( void );
void fpga_postinit( void );
void fpga_pgm( uint8_t *filename );
void fpga_rompgm( void );
uint8_t SPI_OFFLOAD;
@ -54,16 +54,16 @@ uint8_t SPI_OFFLOAD;
#define DONEBIT (22)
#define FPGA_TEST_TOKEN (0xa5)
#define FPGA_TEST_TOKEN (0xa5)
// some macros for bulk transfers (faster)
#define FPGA_SEND_BYTE_SERIAL(data) do {SET_FPGA_DIN(data>>7); CCLK();\
SET_FPGA_DIN(data>>6); CCLK(); SET_FPGA_DIN(data>>5); CCLK();\
SET_FPGA_DIN(data>>4); CCLK(); SET_FPGA_DIN(data>>3); CCLK();\
SET_FPGA_DIN(data>>2); CCLK(); SET_FPGA_DIN(data>>1); CCLK();\
SET_FPGA_DIN(data); CCLK();} while (0)
#define SET_CCLK() do {BITBAND(LPC_GPIO0->FIOSET, 11) = 1;} while (0)
#define CLR_CCLK() do {BITBAND(LPC_GPIO0->FIOCLR, 11) = 1;} while (0)
#define CCLK() do {SET_CCLK(); CLR_CCLK();} while (0)
#define SET_FPGA_DIN(data) do {LPC_GPIO2->FIOPIN1 = data;} while (0)
#define FPGA_SEND_BYTE_SERIAL(data) do {SET_FPGA_DIN(data>>7); CCLK();\
SET_FPGA_DIN(data>>6); CCLK(); SET_FPGA_DIN(data>>5); CCLK();\
SET_FPGA_DIN(data>>4); CCLK(); SET_FPGA_DIN(data>>3); CCLK();\
SET_FPGA_DIN(data>>2); CCLK(); SET_FPGA_DIN(data>>1); CCLK();\
SET_FPGA_DIN(data); CCLK();} while (0)
#define SET_CCLK() do {BITBAND(LPC_GPIO0->FIOSET, 11) = 1;} while (0)
#define CLR_CCLK() do {BITBAND(LPC_GPIO0->FIOCLR, 11) = 1;} while (0)
#define CCLK() do {SET_CCLK(); CLR_CCLK();} while (0)
#define SET_FPGA_DIN(data) do {LPC_GPIO2->FIOPIN1 = data;} while (0)
#endif

View File

@ -25,110 +25,110 @@
*/
/*
SPI commands
SPI commands
cmd param function
cmd param function
=============================================
0t bbhhll set address to 0xbbhhll
t = target
target: 0 = RAM
1 = MSU Audio buffer
2 = MSU Data buffer
targets 1 & 2 only require 2 address bytes to
be written.
0t bbhhll set address to 0xbbhhll
t = target
target: 0 = RAM
1 = MSU Audio buffer
2 = MSU Data buffer
targets 1 & 2 only require 2 address bytes to
be written.
10 bbhhll set SNES input address mask to 0xbbhhll
20 bbhhll set SRAM address mask to 0xbbhhll
10 bbhhll set SNES input address mask to 0xbbhhll
20 bbhhll set SRAM address mask to 0xbbhhll
3m - set mapper to m
0=HiROM, 1=LoROM, 2=ExHiROM, 6=SF96, 7=Menu
3m - set mapper to m
0=HiROM, 1=LoROM, 2=ExHiROM, 6=SF96, 7=Menu
4s - trigger SD DMA (512b from SD to memory)
4s - trigger SD DMA (512b from SD to memory)
s: Bit 2 = partial, Bit 1:0 = target
target: see above
60 xsssyeee set SD DMA partial transfer parameters
x: 0 = read from sector start (skip until
start offset reached)
8 = assume mid-sector position and read
immediately
sss = start offset (msb first)
y: 0 = skip rest of SD sector
8 = stop mid-sector if end offset reached
eee = end offset (msb first)
60 xsssyeee set SD DMA partial transfer parameters
x: 0 = read from sector start (skip until
start offset reached)
8 = assume mid-sector position and read
immediately
sss = start offset (msb first)
y: 0 = skip rest of SD sector
8 = stop mid-sector if end offset reached
eee = end offset (msb first)
8p - read (RAM only)
p: 0 = no increment after read
8 = increment after read
8p - read (RAM only)
p: 0 = no increment after read
8 = increment after read
9p {xx}* write xx
p: i-tt
tt = target (see above)
i = increment (see above)
9p {xx}* write xx
p: i-tt
tt = target (see above)
i = increment (see above)
E0 ssrr set MSU-1 status register (=FPGA status [7:0])
ss = bits to set in status register (1=set)
rr = bits to reset in status register (1=reset)
E0 ssrr set MSU-1 status register (=FPGA status [7:0])
ss = bits to set in status register (1=set)
rr = bits to reset in status register (1=reset)
E1 - pause DAC
E2 - resume/play DAC
E3 - reset DAC playback pointer (0)
E4 hhll set MSU read pointer
E1 - pause DAC
E2 - resume/play DAC
E3 - reset DAC playback pointer (0)
E4 hhll set MSU read pointer
E5 tt{7} set RTC (SPC7110 format + 1000s of year,
nibbles packed)
E5 tt{7} set RTC (SPC7110 format + 1000s of year,
nibbles packed)
eg 0x20111210094816 is 2011-12-10, 9:48:16
E6 ssrr set/reset BS-X status register [7:0]
E7 - reset SRTC state
E8 - reset DSP program and data ROM write pointers
E9 hhmmllxxxx write+incr. DSP program ROM (xxxx=dummy writes)
EA hhllxxxx write+incr. DSP data ROM (xxxx=dummy writes)
EB - put DSP into reset
EC - release DSP from reset
ED - set feature enable bits (see below)
EE - set $213f override value (0=NTSC, 1=PAL)
F0 - receive test token (to see if FPGA is alive)
F1 - receive status (16bit, MSB first), see below
E6 ssrr set/reset BS-X status register [7:0]
E7 - reset SRTC state
E8 - reset DSP program and data ROM write pointers
E9 hhmmllxxxx write+incr. DSP program ROM (xxxx=dummy writes)
EA hhllxxxx write+incr. DSP data ROM (xxxx=dummy writes)
EB - put DSP into reset
EC - release DSP from reset
ED - set feature enable bits (see below)
EE - set $213f override value (0=NTSC, 1=PAL)
F0 - receive test token (to see if FPGA is alive)
F1 - receive status (16bit, MSB first), see below
F2 - get MSU data address (32bit, MSB first)
F3 - get MSU audio track no. (16bit, MSB first)
F4 - get MSU volume (8bit)
F2 - get MSU data address (32bit, MSB first)
F3 - get MSU audio track no. (16bit, MSB first)
F4 - get MSU volume (8bit)
FE - get SNES master clock frequency (32bit, MSB first)
measured 1x/sec
FF {xx}* echo (returns the sent data in the next byte)
FE - get SNES master clock frequency (32bit, MSB first)
measured 1x/sec
FF {xx}* echo (returns the sent data in the next byte)
FPGA status word:
bit function
FPGA status word:
bit function
==========================================================================
15 SD DMA busy (0=idle, 1=busy)
14 DAC read pointer MSB
13 MSU read pointer MSB
12 reserved (0)
11 reserved (0)
10 reserved (0)
9 reserved (0)
8 reserved (0)
7 reserved (0)
6 reserved (0)
5 MSU1 Audio request from SNES
4 MSU1 Data request from SNES
3 reserved (0)
2 MSU1 Audio control status: 0=no repeat, 1=repeat
1 MSU1 Audio control status: 0=pause, 1=play
0 MSU1 Audio control request
15 SD DMA busy (0=idle, 1=busy)
14 DAC read pointer MSB
13 MSU read pointer MSB
12 reserved (0)
11 reserved (0)
10 reserved (0)
9 reserved (0)
8 reserved (0)
7 reserved (0)
6 reserved (0)
5 MSU1 Audio request from SNES
4 MSU1 Data request from SNES
3 reserved (0)
2 MSU1 Audio control status: 0=no repeat, 1=repeat
1 MSU1 Audio control status: 0=pause, 1=play
0 MSU1 Audio control request
FPGA feature enable bits:
bit function
FPGA feature enable bits:
bit function
==========================================================================
7 -
6 -
5 -
4 enable $213F override
3 enable MSU1 registers
2 enable SRTC registers
1 enable ST0010 mapping
0 enable DSPx mapping
7 -
6 -
5 -
4 enable $213F override
3 enable MSU1 registers
2 enable SRTC registers
1 enable ST0010 mapping
0 enable DSPx mapping
*/
@ -142,257 +142,292 @@
#include "timer.h"
#include "sdnative.h"
void fpga_spi_init(void) {
spi_init();
BITBAND(FPGA_MCU_RDY_REG->FIODIR, FPGA_MCU_RDY_BIT) = 0;
void fpga_spi_init( void )
{
spi_init();
BITBAND( FPGA_MCU_RDY_REG->FIODIR, FPGA_MCU_RDY_BIT ) = 0;
}
void set_msu_addr(uint16_t address) {
FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_SETADDR | FPGA_TGT_MSUBUF);
FPGA_TX_BYTE((address>>8)&0xff);
FPGA_TX_BYTE((address)&0xff);
FPGA_DESELECT();
void set_msu_addr( uint16_t address )
{
FPGA_SELECT();
FPGA_TX_BYTE( FPGA_CMD_SETADDR | FPGA_TGT_MSUBUF );
FPGA_TX_BYTE( ( address >> 8 ) & 0xff );
FPGA_TX_BYTE( ( address ) & 0xff );
FPGA_DESELECT();
}
void set_dac_addr(uint16_t address) {
FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_SETADDR | FPGA_TGT_DACBUF);
FPGA_TX_BYTE((address>>8)&0xff);
FPGA_TX_BYTE((address)&0xff);
FPGA_DESELECT();
void set_dac_addr( uint16_t address )
{
FPGA_SELECT();
FPGA_TX_BYTE( FPGA_CMD_SETADDR | FPGA_TGT_DACBUF );
FPGA_TX_BYTE( ( address >> 8 ) & 0xff );
FPGA_TX_BYTE( ( address ) & 0xff );
FPGA_DESELECT();
}
void set_mcu_addr(uint32_t address) {
FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_SETADDR | FPGA_TGT_MEM);
FPGA_TX_BYTE((address>>16)&0xff);
FPGA_TX_BYTE((address>>8)&0xff);
FPGA_TX_BYTE((address)&0xff);
FPGA_DESELECT();
void set_mcu_addr( uint32_t address )
{
FPGA_SELECT();
FPGA_TX_BYTE( FPGA_CMD_SETADDR | FPGA_TGT_MEM );
FPGA_TX_BYTE( ( address >> 16 ) & 0xff );
FPGA_TX_BYTE( ( address >> 8 ) & 0xff );
FPGA_TX_BYTE( ( address ) & 0xff );
FPGA_DESELECT();
}
void set_saveram_mask(uint32_t mask) {
FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_SETRAMMASK);
FPGA_TX_BYTE((mask>>16)&0xff);
FPGA_TX_BYTE((mask>>8)&0xff);
FPGA_TX_BYTE((mask)&0xff);
FPGA_DESELECT();
void set_saveram_mask( uint32_t mask )
{
FPGA_SELECT();
FPGA_TX_BYTE( FPGA_CMD_SETRAMMASK );
FPGA_TX_BYTE( ( mask >> 16 ) & 0xff );
FPGA_TX_BYTE( ( mask >> 8 ) & 0xff );
FPGA_TX_BYTE( ( mask ) & 0xff );
FPGA_DESELECT();
}
void set_rom_mask(uint32_t mask) {
FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_SETROMMASK);
FPGA_TX_BYTE((mask>>16)&0xff);
FPGA_TX_BYTE((mask>>8)&0xff);
FPGA_TX_BYTE((mask)&0xff);
FPGA_DESELECT();
void set_rom_mask( uint32_t mask )
{
FPGA_SELECT();
FPGA_TX_BYTE( FPGA_CMD_SETROMMASK );
FPGA_TX_BYTE( ( mask >> 16 ) & 0xff );
FPGA_TX_BYTE( ( mask >> 8 ) & 0xff );
FPGA_TX_BYTE( ( mask ) & 0xff );
FPGA_DESELECT();
}
void set_mapper(uint8_t val) {
FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_SETMAPPER(val));
FPGA_DESELECT();
void set_mapper( uint8_t val )
{
FPGA_SELECT();
FPGA_TX_BYTE( FPGA_CMD_SETMAPPER( val ) );
FPGA_DESELECT();
}
uint8_t fpga_test() {
FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_TEST);
uint8_t result = FPGA_RX_BYTE();
FPGA_DESELECT();
return result;
uint8_t fpga_test()
{
FPGA_SELECT();
FPGA_TX_BYTE( FPGA_CMD_TEST );
uint8_t result = FPGA_RX_BYTE();
FPGA_DESELECT();
return result;
}
uint16_t fpga_status() {
FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_GETSTATUS);
uint16_t result = (FPGA_RX_BYTE()) << 8;
result |= FPGA_RX_BYTE();
FPGA_DESELECT();
return result;
uint16_t fpga_status()
{
FPGA_SELECT();
FPGA_TX_BYTE( FPGA_CMD_GETSTATUS );
uint16_t result = ( FPGA_RX_BYTE() ) << 8;
result |= FPGA_RX_BYTE();
FPGA_DESELECT();
return result;
}
void fpga_set_sddma_range(uint16_t start, uint16_t end) {
FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_SDDMA_RANGE);
FPGA_TX_BYTE(start>>8);
FPGA_TX_BYTE(start&0xff);
FPGA_TX_BYTE(end>>8);
FPGA_TX_BYTE(end&0xff);
FPGA_DESELECT();
void fpga_set_sddma_range( uint16_t start, uint16_t end )
{
printf( "%s %08X -> %08X\n", __func__, start, end );
FPGA_SELECT();
FPGA_TX_BYTE( FPGA_CMD_SDDMA_RANGE );
FPGA_TX_BYTE( start >> 8 );
FPGA_TX_BYTE( start & 0xff );
FPGA_TX_BYTE( end >> 8 );
FPGA_TX_BYTE( end & 0xff );
FPGA_DESELECT();
}
void fpga_sddma(uint8_t tgt, uint8_t partial) {
BITBAND(SD_CLKREG->FIODIR, SD_CLKPIN) = 0;
FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_SDDMA | (tgt & 3) | (partial ? FPGA_SDDMA_PARTIAL : 0));
FPGA_TX_BYTE(0x00); /* dummy for falling DMA_EN edge */
FPGA_DESELECT();
FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_GETSTATUS);
DBG_SD printf("FPGA DMA request sent, wait for completion...");
while(FPGA_RX_BYTE() & 0x80) {
FPGA_RX_BYTE(); /* eat the 2nd status byte */
}
DBG_SD printf("...complete\n");
FPGA_DESELECT();
BITBAND(SD_CLKREG->FIODIR, SD_CLKPIN) = 1;
void fpga_sddma( uint8_t tgt, uint8_t partial )
{
//printf("%s %02X -> %02X\n", __func__, tgt, partial);
//uint32_t test = 0;
//uint8_t status = 0;
BITBAND( SD_CLKREG->FIODIR, SD_CLKPIN ) = 0;
FPGA_SELECT();
FPGA_TX_BYTE( FPGA_CMD_SDDMA | ( tgt & 3 ) | ( partial ? FPGA_SDDMA_PARTIAL : 0 ) );
FPGA_TX_BYTE( 0x00 ); /* dummy for falling DMA_EN edge */
FPGA_DESELECT();
FPGA_SELECT();
FPGA_TX_BYTE( FPGA_CMD_GETSTATUS );
DBG_SD printf( "FPGA DMA request sent, wait for completion..." );
while ( FPGA_RX_BYTE() & 0x80 )
{
FPGA_RX_BYTE(); /* eat the 2nd status byte */
}
DBG_SD printf( "...complete\n" );
FPGA_DESELECT();
BITBAND( SD_CLKREG->FIODIR, SD_CLKPIN ) = 1;
}
void dac_play() {
FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_DACPLAY);
FPGA_TX_BYTE(0x00); /* latch reset */
FPGA_DESELECT();
void dac_play()
{
FPGA_SELECT();
FPGA_TX_BYTE( FPGA_CMD_DACPLAY );
FPGA_TX_BYTE( 0x00 ); /* latch reset */
FPGA_DESELECT();
}
void dac_pause() {
FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_DACPAUSE);
FPGA_TX_BYTE(0x00); /* latch reset */
FPGA_DESELECT();
void dac_pause()
{
FPGA_SELECT();
FPGA_TX_BYTE( FPGA_CMD_DACPAUSE );
FPGA_TX_BYTE( 0x00 ); /* latch reset */
FPGA_DESELECT();
}
void dac_reset() {
FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_DACRESETPTR);
FPGA_TX_BYTE(0x00); /* latch reset */
FPGA_TX_BYTE(0x00); /* latch reset */
FPGA_DESELECT();
void dac_reset()
{
FPGA_SELECT();
FPGA_TX_BYTE( FPGA_CMD_DACRESETPTR );
FPGA_TX_BYTE( 0x00 ); /* latch reset */
FPGA_TX_BYTE( 0x00 ); /* latch reset */
FPGA_DESELECT();
}
void msu_reset(uint16_t address) {
FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_MSUSETPTR);
FPGA_TX_BYTE((address>>8) & 0xff); /* address hi */
FPGA_TX_BYTE(address & 0xff); /* address lo */
FPGA_TX_BYTE(0x00); /* latch reset */
FPGA_TX_BYTE(0x00); /* latch reset */
FPGA_DESELECT();
void msu_reset( uint16_t address )
{
FPGA_SELECT();
FPGA_TX_BYTE( FPGA_CMD_MSUSETPTR );
FPGA_TX_BYTE( ( address >> 8 ) & 0xff ); /* address hi */
FPGA_TX_BYTE( address & 0xff ); /* address lo */
FPGA_TX_BYTE( 0x00 ); /* latch reset */
FPGA_TX_BYTE( 0x00 ); /* latch reset */
FPGA_DESELECT();
}
void set_msu_status(uint8_t set, uint8_t reset) {
FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_MSUSETBITS);
FPGA_TX_BYTE(set);
FPGA_TX_BYTE(reset);
FPGA_TX_BYTE(0x00); /* latch reset */
FPGA_DESELECT();
void set_msu_status( uint8_t set, uint8_t reset )
{
FPGA_SELECT();
FPGA_TX_BYTE( FPGA_CMD_MSUSETBITS );
FPGA_TX_BYTE( set );
FPGA_TX_BYTE( reset );
FPGA_TX_BYTE( 0x00 ); /* latch reset */
FPGA_DESELECT();
}
uint16_t get_msu_track() {
FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_MSUGETTRACK);
uint16_t result = (FPGA_RX_BYTE()) << 8;
result |= FPGA_RX_BYTE();
FPGA_DESELECT();
return result;
uint16_t get_msu_track()
{
FPGA_SELECT();
FPGA_TX_BYTE( FPGA_CMD_MSUGETTRACK );
uint16_t result = ( FPGA_RX_BYTE() ) << 8;
result |= FPGA_RX_BYTE();
FPGA_DESELECT();
return result;
}
uint32_t get_msu_offset() {
FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_MSUGETADDR);
uint32_t result = (FPGA_RX_BYTE()) << 24;
result |= (FPGA_RX_BYTE()) << 16;
result |= (FPGA_RX_BYTE()) << 8;
result |= (FPGA_RX_BYTE());
FPGA_DESELECT();
return result;
uint32_t get_msu_offset()
{
FPGA_SELECT();
FPGA_TX_BYTE( FPGA_CMD_MSUGETADDR );
uint32_t result = ( FPGA_RX_BYTE() ) << 24;
result |= ( FPGA_RX_BYTE() ) << 16;
result |= ( FPGA_RX_BYTE() ) << 8;
result |= ( FPGA_RX_BYTE() );
FPGA_DESELECT();
return result;
}
uint32_t get_snes_sysclk() {
FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_GETSYSCLK);
FPGA_TX_BYTE(0x00); /* dummy (copy current sysclk count to register) */
uint32_t result = (FPGA_RX_BYTE()) << 24;
result |= (FPGA_RX_BYTE()) << 16;
result |= (FPGA_RX_BYTE()) << 8;
result |= (FPGA_RX_BYTE());
FPGA_DESELECT();
return result;
uint32_t get_snes_sysclk()
{
FPGA_SELECT();
FPGA_TX_BYTE( FPGA_CMD_GETSYSCLK );
FPGA_TX_BYTE( 0x00 ); /* dummy (copy current sysclk count to register) */
uint32_t result = ( FPGA_RX_BYTE() ) << 24;
result |= ( FPGA_RX_BYTE() ) << 16;
result |= ( FPGA_RX_BYTE() ) << 8;
result |= ( FPGA_RX_BYTE() );
FPGA_DESELECT();
return result;
}
void set_bsx_regs(uint8_t set, uint8_t reset) {
FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_BSXSETBITS);
FPGA_TX_BYTE(set);
FPGA_TX_BYTE(reset);
FPGA_TX_BYTE(0x00); /* latch reset */
FPGA_DESELECT();
void set_bsx_regs( uint8_t set, uint8_t reset )
{
FPGA_SELECT();
FPGA_TX_BYTE( FPGA_CMD_BSXSETBITS );
FPGA_TX_BYTE( set );
FPGA_TX_BYTE( reset );
FPGA_TX_BYTE( 0x00 ); /* latch reset */
FPGA_DESELECT();
}
void set_fpga_time(uint64_t time) {
FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_RTCSET);
FPGA_TX_BYTE((time >> 48) & 0xff);
FPGA_TX_BYTE((time >> 40) & 0xff);
FPGA_TX_BYTE((time >> 32) & 0xff);
FPGA_TX_BYTE((time >> 24) & 0xff);
FPGA_TX_BYTE((time >> 16) & 0xff);
FPGA_TX_BYTE((time >> 8) & 0xff);
FPGA_TX_BYTE(time & 0xff);
FPGA_TX_BYTE(0x00);
FPGA_DESELECT();
void set_fpga_time( uint64_t time )
{
FPGA_SELECT();
FPGA_TX_BYTE( FPGA_CMD_RTCSET );
FPGA_TX_BYTE( ( time >> 48 ) & 0xff );
FPGA_TX_BYTE( ( time >> 40 ) & 0xff );
FPGA_TX_BYTE( ( time >> 32 ) & 0xff );
FPGA_TX_BYTE( ( time >> 24 ) & 0xff );
FPGA_TX_BYTE( ( time >> 16 ) & 0xff );
FPGA_TX_BYTE( ( time >> 8 ) & 0xff );
FPGA_TX_BYTE( time & 0xff );
FPGA_TX_BYTE( 0x00 );
FPGA_DESELECT();
}
void fpga_reset_srtc_state() {
FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_SRTCRESET);
FPGA_TX_BYTE(0x00);
FPGA_TX_BYTE(0x00);
FPGA_DESELECT();
void fpga_reset_srtc_state()
{
FPGA_SELECT();
FPGA_TX_BYTE( FPGA_CMD_SRTCRESET );
FPGA_TX_BYTE( 0x00 );
FPGA_TX_BYTE( 0x00 );
FPGA_DESELECT();
}
void fpga_reset_dspx_addr() {
FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_DSPRESETPTR);
FPGA_TX_BYTE(0x00);
FPGA_TX_BYTE(0x00);
FPGA_DESELECT();
void fpga_reset_dspx_addr()
{
FPGA_SELECT();
FPGA_TX_BYTE( FPGA_CMD_DSPRESETPTR );
FPGA_TX_BYTE( 0x00 );
FPGA_TX_BYTE( 0x00 );
FPGA_DESELECT();
}
void fpga_write_dspx_pgm(uint32_t data) {
FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_DSPWRITEPGM);
FPGA_TX_BYTE((data>>16)&0xff);
FPGA_TX_BYTE((data>>8)&0xff);
FPGA_TX_BYTE((data)&0xff);
FPGA_TX_BYTE(0x00);
FPGA_TX_BYTE(0x00);
FPGA_DESELECT();
void fpga_write_dspx_pgm( uint32_t data )
{
FPGA_SELECT();
FPGA_TX_BYTE( FPGA_CMD_DSPWRITEPGM );
FPGA_TX_BYTE( ( data >> 16 ) & 0xff );
FPGA_TX_BYTE( ( data >> 8 ) & 0xff );
FPGA_TX_BYTE( ( data ) & 0xff );
FPGA_TX_BYTE( 0x00 );
FPGA_TX_BYTE( 0x00 );
FPGA_DESELECT();
}
void fpga_write_dspx_dat(uint16_t data) {
FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_DSPWRITEDAT);
FPGA_TX_BYTE((data>>8)&0xff);
FPGA_TX_BYTE((data)&0xff);
FPGA_TX_BYTE(0x00);
FPGA_TX_BYTE(0x00);
FPGA_DESELECT();
void fpga_write_dspx_dat( uint16_t data )
{
FPGA_SELECT();
FPGA_TX_BYTE( FPGA_CMD_DSPWRITEDAT );
FPGA_TX_BYTE( ( data >> 8 ) & 0xff );
FPGA_TX_BYTE( ( data ) & 0xff );
FPGA_TX_BYTE( 0x00 );
FPGA_TX_BYTE( 0x00 );
FPGA_DESELECT();
}
void fpga_dspx_reset(uint8_t reset) {
FPGA_SELECT();
FPGA_TX_BYTE(reset ? FPGA_CMD_DSPRESET : FPGA_CMD_DSPUNRESET);
FPGA_TX_BYTE(0x00);
FPGA_DESELECT();
void fpga_dspx_reset( uint8_t reset )
{
FPGA_SELECT();
FPGA_TX_BYTE( reset ? FPGA_CMD_DSPRESET : FPGA_CMD_DSPUNRESET );
FPGA_TX_BYTE( 0x00 );
FPGA_DESELECT();
}
void fpga_set_features(uint8_t feat) {
printf("set features: %02x\n", feat);
FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_SETFEATURE);
FPGA_TX_BYTE(feat);
FPGA_DESELECT();
void fpga_set_features( uint8_t feat )
{
printf( "set features: %02x\n", feat );
FPGA_SELECT();
FPGA_TX_BYTE( FPGA_CMD_SETFEATURE );
FPGA_TX_BYTE( feat );
FPGA_DESELECT();
}
void fpga_set_213f(uint8_t data) {
printf("set 213f: %d\n", data);
FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_SET213F);
FPGA_TX_BYTE(data);
FPGA_DESELECT();
void fpga_set_213f( uint8_t data )
{
printf( "set 213f: %d\n", data );
FPGA_SELECT();
FPGA_TX_BYTE( FPGA_CMD_SET213F );
FPGA_TX_BYTE( data );
FPGA_DESELECT();
}

View File

@ -32,13 +32,13 @@
#include "spi.h"
#include "config.h"
#define FPGA_SS_BIT 16
#define FPGA_SS_REG LPC_GPIO0
#define FPGA_SS_BIT 16
#define FPGA_SS_REG LPC_GPIO0
#define FPGA_SELECT() do {FPGA_TX_SYNC(); BITBAND(FPGA_SS_REG->FIOCLR, FPGA_SS_BIT) = 1;} while (0)
#define FPGA_SELECT_ASYNC() do {BITBAND(FPGA_SS_REG->FIOCLR, FPGA_SS_BIT) = 1;} while (0)
#define FPGA_DESELECT() do {FPGA_TX_SYNC(); BITBAND(FPGA_SS_REG->FIOSET, FPGA_SS_BIT) = 1;} while (0)
#define FPGA_DESELECT_ASYNC() do {BITBAND(FPGA_SS_REG->FIOSET, FPGA_SS_BIT) = 1;} while (0)
#define FPGA_SELECT() do {FPGA_TX_SYNC(); BITBAND(FPGA_SS_REG->FIOCLR, FPGA_SS_BIT) = 1;} while (0)
#define FPGA_SELECT_ASYNC() do {BITBAND(FPGA_SS_REG->FIOCLR, FPGA_SS_BIT) = 1;} while (0)
#define FPGA_DESELECT() do {FPGA_TX_SYNC(); BITBAND(FPGA_SS_REG->FIOSET, FPGA_SS_BIT) = 1;} while (0)
#define FPGA_DESELECT_ASYNC() do {BITBAND(FPGA_SS_REG->FIOSET, FPGA_SS_BIT) = 1;} while (0)
#define FPGA_TX_SYNC() spi_tx_sync()
#define FPGA_TX_BYTE(x) spi_tx_byte(x)
@ -95,35 +95,35 @@
#define FPGA_CMD_GETSYSCLK (0xfe)
#define FPGA_CMD_ECHO (0xff)
void fpga_spi_init(void);
uint8_t fpga_test(void);
uint16_t fpga_status(void);
void spi_fpga(void);
void spi_sd(void);
void spi_none(void);
void set_mcu_addr(uint32_t);
void set_dac_addr(uint16_t);
void dac_play(void);
void dac_pause(void);
void dac_reset(void);
void msu_reset(uint16_t);
void set_msu_addr(uint16_t);
void set_msu_status(uint8_t set, uint8_t reset);
void set_saveram_mask(uint32_t);
void set_rom_mask(uint32_t);
void set_mapper(uint8_t val);
void fpga_sddma(uint8_t tgt, uint8_t partial);
void fpga_set_sddma_range(uint16_t start, uint16_t end);
uint16_t get_msu_track(void);
uint32_t get_msu_offset(void);
uint32_t get_snes_sysclk(void);
void set_bsx_regs(uint8_t set, uint8_t reset);
void set_fpga_time(uint64_t time);
void fpga_reset_srtc_state(void);
void fpga_reset_dspx_addr(void);
void fpga_write_dspx_pgm(uint32_t data);
void fpga_write_dspx_dat(uint16_t data);
void fpga_dspx_reset(uint8_t reset);
void fpga_set_features(uint8_t feat);
void fpga_set_213f(uint8_t data);
void fpga_spi_init( void );
uint8_t fpga_test( void );
uint16_t fpga_status( void );
void spi_fpga( void );
void spi_sd( void );
void spi_none( void );
void set_mcu_addr( uint32_t );
void set_dac_addr( uint16_t );
void dac_play( void );
void dac_pause( void );
void dac_reset( void );
void msu_reset( uint16_t );
void set_msu_addr( uint16_t );
void set_msu_status( uint8_t set, uint8_t reset );
void set_saveram_mask( uint32_t );
void set_rom_mask( uint32_t );
void set_mapper( uint8_t val );
void fpga_sddma( uint8_t tgt, uint8_t partial );
void fpga_set_sddma_range( uint16_t start, uint16_t end );
uint16_t get_msu_track( void );
uint32_t get_msu_offset( void );
uint32_t get_snes_sysclk( void );
void set_bsx_regs( uint8_t set, uint8_t reset );
void set_fpga_time( uint64_t time );
void fpga_reset_srtc_state( void );
void fpga_reset_dspx_addr( void );
void fpga_write_dspx_pgm( uint32_t data );
void fpga_write_dspx_dat( uint16_t data );
void fpga_dspx_reset( uint8_t reset );
void fpga_set_features( uint8_t feat );
void fpga_set_213f( uint8_t data );
#endif

View File

@ -4,12 +4,15 @@
#include "sdnative.h"
#include "uart.h"
void EINT3_IRQHandler(void) {
NVIC_ClearPendingIRQ(EINT3_IRQn);
if(SD_CHANGE_DETECT) {
SD_CHANGE_CLR();
sdn_changed();
}
void EINT3_IRQHandler( void )
{
NVIC_ClearPendingIRQ( EINT3_IRQn );
if ( SD_CHANGE_DETECT )
{
SD_CHANGE_CLR();
sdn_changed();
}
}

213
src/led.c
View File

@ -6,7 +6,7 @@
#include "led.h"
#include "cli.h"
static uint8_t led_bright[16]={255,253,252,251,249,247,244,239,232,223,210,191,165,127,74,0};
static uint8_t led_bright[16] = {255, 253, 252, 251, 249, 247, 244, 239, 232, 223, 210, 191, 165, 127, 74, 0};
int led_rdyledstate = 0;
int led_readledstate = 0;
@ -22,127 +22,156 @@ int led_pwmstate = 0;
write red P1.23 PWM1[4]
*/
void rdyled(unsigned int state) {
if(led_pwmstate) {
rdybright(state?15:0);
} else {
BITBAND(LPC_GPIO2->FIODIR, 4) = state;
}
led_rdyledstate = state;
void rdyled( unsigned int state )
{
if ( led_pwmstate )
{
rdybright( state ? 15 : 0 );
}
else
{
BITBAND( LPC_GPIO2->FIODIR, 4 ) = state;
}
led_rdyledstate = state;
}
void readled(unsigned int state) {
if(led_pwmstate) {
readbright(state?15:0);
} else {
BITBAND(LPC_GPIO2->FIODIR, 5) = state;
}
led_readledstate = state;
void readled( unsigned int state )
{
if ( led_pwmstate )
{
readbright( state ? 15 : 0 );
}
else
{
BITBAND( LPC_GPIO2->FIODIR, 5 ) = state;
}
led_readledstate = state;
}
void writeled(unsigned int state) {
if(led_pwmstate) {
writebright(state?15:0);
} else {
BITBAND(LPC_GPIO1->FIODIR, 23) = state;
}
led_writeledstate = state;
void writeled( unsigned int state )
{
if ( led_pwmstate )
{
writebright( state ? 15 : 0 );
}
else
{
BITBAND( LPC_GPIO1->FIODIR, 23 ) = state;
}
led_writeledstate = state;
}
void rdybright(uint8_t bright) {
LPC_PWM1->MR5 = led_bright[(bright & 15)];
BITBAND(LPC_PWM1->LER, 5) = 1;
void rdybright( uint8_t bright )
{
LPC_PWM1->MR5 = led_bright[( bright & 15 )];
BITBAND( LPC_PWM1->LER, 5 ) = 1;
}
void readbright(uint8_t bright) {
LPC_PWM1->MR6 = led_bright[(bright & 15)];
BITBAND(LPC_PWM1->LER, 6) = 1;
void readbright( uint8_t bright )
{
LPC_PWM1->MR6 = led_bright[( bright & 15 )];
BITBAND( LPC_PWM1->LER, 6 ) = 1;
}
void writebright(uint8_t bright) {
LPC_PWM1->MR4 = led_bright[(bright & 15)];
BITBAND(LPC_PWM1->LER, 4) = 1;
void writebright( uint8_t bright )
{
LPC_PWM1->MR4 = led_bright[( bright & 15 )];
BITBAND( LPC_PWM1->LER, 4 ) = 1;
}
void led_clkout32(uint32_t val) {
while(1) {
rdyled(1);
delay_ms(400);
readled((val & BV(31))>>31);
rdyled(0);
val<<=1;
delay_ms(400);
}
void led_clkout32( uint32_t val )
{
while ( 1 )
{
rdyled( 1 );
delay_ms( 400 );
readled( ( val & BV( 31 ) ) >> 31 );
rdyled( 0 );
val <<= 1;
delay_ms( 400 );
}
}
void toggle_rdy_led() {
rdyled(~led_rdyledstate);
void toggle_rdy_led()
{
rdyled( ~led_rdyledstate );
}
void toggle_read_led() {
readled(~led_readledstate);
void toggle_read_led()
{
readled( ~led_readledstate );
}
void toggle_write_led() {
writeled(~led_writeledstate);
void toggle_write_led()
{
writeled( ~led_writeledstate );
}
void led_panic(uint8_t led_states) {
led_std();
while(1) {
rdyled((led_states >> 2) & 1);
readled((led_states >> 1) & 1);
writeled(led_states & 1);
delay_ms(100);
rdyled(0);
readled(0);
writeled(0);
delay_ms(100);
cli_entrycheck();
}
void led_panic()
{
led_std();
while ( 1 )
{
rdyled( 1 );
readled( 1 );
writeled( 1 );
delay_ms( 100 );
rdyled( 0 );
readled( 0 );
writeled( 0 );
delay_ms( 100 );
cli_entrycheck();
}
}
void led_pwm() {
/* Rev.C P2.4, P2.5, P1.23 */
BITBAND(LPC_PINCON->PINSEL4, 9) = 0;
BITBAND(LPC_PINCON->PINSEL4, 8) = 1;
void led_pwm()
{
/* Rev.C P2.4, P2.5, P1.23 */
BITBAND( LPC_PINCON->PINSEL4, 9 ) = 0;
BITBAND( LPC_PINCON->PINSEL4, 8 ) = 1;
BITBAND(LPC_PINCON->PINSEL4, 11) = 0;
BITBAND(LPC_PINCON->PINSEL4, 10) = 1;
BITBAND( LPC_PINCON->PINSEL4, 11 ) = 0;
BITBAND( LPC_PINCON->PINSEL4, 10 ) = 1;
BITBAND(LPC_PINCON->PINSEL3, 15) = 1;
BITBAND(LPC_PINCON->PINSEL3, 14) = 0;
BITBAND( LPC_PINCON->PINSEL3, 15 ) = 1;
BITBAND( LPC_PINCON->PINSEL3, 14 ) = 0;
BITBAND(LPC_PWM1->PCR, 12) = 1;
BITBAND(LPC_PWM1->PCR, 13) = 1;
BITBAND(LPC_PWM1->PCR, 14) = 1;
BITBAND( LPC_PWM1->PCR, 12 ) = 1;
BITBAND( LPC_PWM1->PCR, 13 ) = 1;
BITBAND( LPC_PWM1->PCR, 14 ) = 1;
led_pwmstate = 1;
led_pwmstate = 1;
}
void led_std() {
BITBAND(LPC_PINCON->PINSEL4, 9) = 0;
BITBAND(LPC_PINCON->PINSEL4, 8) = 0;
void led_std()
{
BITBAND( LPC_PINCON->PINSEL4, 9 ) = 0;
BITBAND( LPC_PINCON->PINSEL4, 8 ) = 0;
BITBAND(LPC_PINCON->PINSEL4, 11) = 0;
BITBAND(LPC_PINCON->PINSEL4, 10) = 0;
BITBAND( LPC_PINCON->PINSEL4, 11 ) = 0;
BITBAND( LPC_PINCON->PINSEL4, 10 ) = 0;
BITBAND(LPC_PINCON->PINSEL3, 15) = 0;
BITBAND(LPC_PINCON->PINSEL3, 14) = 0;
BITBAND( LPC_PINCON->PINSEL3, 15 ) = 0;
BITBAND( LPC_PINCON->PINSEL3, 14 ) = 0;
BITBAND(LPC_PWM1->PCR, 12) = 0;
BITBAND(LPC_PWM1->PCR, 13) = 0;
BITBAND(LPC_PWM1->PCR, 14) = 0;
BITBAND( LPC_PWM1->PCR, 12 ) = 0;
BITBAND( LPC_PWM1->PCR, 13 ) = 0;
BITBAND( LPC_PWM1->PCR, 14 ) = 0;
led_pwmstate = 0;
led_pwmstate = 0;
}
void led_init() {
/* power is already connected by default */
/* set PCLK divider to 8 */
BITBAND(LPC_SC->PCLKSEL0, 13) = 1;
BITBAND(LPC_SC->PCLKSEL0, 12) = 1;
LPC_PWM1->MR0 = 255;
BITBAND(LPC_PWM1->LER, 0) = 1;
BITBAND(LPC_PWM1->TCR, 0) = 1;
BITBAND(LPC_PWM1->TCR, 3) = 1;
BITBAND(LPC_PWM1->MCR, 1) = 1;
void led_init()
{
/* power is already connected by default */
/* set PCLK divider to 8 */
BITBAND( LPC_SC->PCLKSEL0, 13 ) = 1;
BITBAND( LPC_SC->PCLKSEL0, 12 ) = 1;
LPC_PWM1->MR0 = 255;
BITBAND( LPC_PWM1->LER, 0 ) = 1;
BITBAND( LPC_PWM1->TCR, 0 ) = 1;
BITBAND( LPC_PWM1->TCR, 3 ) = 1;
BITBAND( LPC_PWM1->MCR, 1 ) = 1;
}

View File

@ -3,12 +3,6 @@
#ifndef _LED_H
#define _LED_H
#define LED_PANIC_FPGA_PROGB_STUCK (1)
#define LED_PANIC_FPGA_NO_INITB (2)
#define LED_PANIC_FPGA_DONE_STUCK (3)
#define LED_PANIC_FPGA_NOCONF (4)
#define LED_PANIC_FPGA_DEAD (5)
void readbright(uint8_t bright);
void writebright(uint8_t bright);
void rdybright(uint8_t bright);
@ -19,7 +13,7 @@ void led_clkout32(uint32_t val);
void toggle_rdy_led(void);
void toggle_read_led(void);
void toggle_write_led(void);
void led_panic(uint8_t led_states);
void led_panic(void);
void led_pwm(void);
void led_std(void);
void led_init(void);

View File

@ -26,9 +26,9 @@ if { [info exists CPUTAPID ] } {
}
#delays on reset lines
#if your OpenOCD version rejects "adapter_nsrst_delay" replace it with:
#jtag_nsrst_delay 200
#if your OpenOCD version rejects "jtag_nsrst_delay" replace it with:
adapter_nsrst_delay 200
#jtag_nsrst_delay 200
jtag_ntrst_delay 200
# LPC2000 & LPC1700 -> SRST causes TRST
@ -39,6 +39,7 @@ jtag newtap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID
#jtag newtap x3s tap -irlen 6 -ircapture 0x11 -irmask 0x11 -expected-id 0x0141c093
set _TARGETNAME $_CHIPNAME.cpu
#target create $_TARGETNAME cortex_m3 -chain-position $_TARGETNAME -event reset-init 0
target create $_TARGETNAME cortex_m -chain-position $_TARGETNAME -event reset-init 0
# LPC1754 has 16kB of SRAM In the ARMv7-M "Code" area (at 0x10000000)

View File

@ -29,8 +29,8 @@
#include "sysinfo.h"
#include "cfg.h"
#define EMC0TOGGLE (3<<4)
#define MR0R (1<<1)
#define EMC0TOGGLE (3<<4)
#define MR0R (1<<1)
int i;
@ -48,305 +48,415 @@ extern volatile int reset_changed;
extern volatile cfg_t CFG;
enum system_states {
SYS_RTC_STATUS = 0,
SYS_LAST_STATUS = 1
enum system_states
{
SYS_RTC_STATUS = 0,
SYS_LAST_STATUS = 1
};
int main(void) {
LPC_GPIO2->FIODIR = BV(4) | BV(5);
LPC_GPIO1->FIODIR = BV(23) | BV(SNES_CIC_PAIR_BIT);
BITBAND(SNES_CIC_PAIR_REG->FIOSET, SNES_CIC_PAIR_BIT) = 1;
LPC_GPIO0->FIODIR = BV(16);
/* connect UART3 on P0[25:26] + SSP0 on P0[15:18] + MAT3.0 on P0[10] */
LPC_PINCON->PINSEL1 = BV(18) | BV(19) | BV(20) | BV(21) /* UART3 */
| BV(3) | BV(5); /* SSP0 (FPGA) except SS */
LPC_PINCON->PINSEL0 = BV(31); /* SSP0 */
/* | BV(13) | BV(15) | BV(17) | BV(19) SSP1 (SD) */
/* pull-down CIC data lines */
LPC_PINCON->PINMODE0 = BV(0) | BV(1) | BV(2) | BV(3);
clock_disconnect();
snes_init();
snes_reset(1);
power_init();
timer_init();
uart_init();
fpga_spi_init();
spi_preinit();
led_init();
/* do this last because the peripheral init()s change PCLK dividers */
clock_init();
LPC_PINCON->PINSEL0 |= BV(20) | BV(21); /* MAT3.0 (FPGA clock) */
led_pwm();
sdn_init();
printf("\n\nsd2snes mk.2\n============\nfw ver.: " CONFIG_VERSION "\ncpu clock: %d Hz\n", CONFIG_CPU_FREQUENCY);
printf("PCONP=%lx\n", LPC_SC->PCONP);
file_init();
cic_init(0);
/* setup timer (fpga clk) */
LPC_TIM3->TCR=2;
LPC_TIM3->CTCR=0;
LPC_TIM3->PR=0;
LPC_TIM3->EMR=EMC0TOGGLE;
LPC_TIM3->MCR=MR0R;
LPC_TIM3->MR0=1;
LPC_TIM3->TCR=1;
fpga_init();
fpga_rompgm();
sram_writebyte(0, SRAM_CMD_ADDR);
while(1) {
if(disk_state == DISK_CHANGED) {
sdn_init();
newcard = 1;
}
load_bootrle(SRAM_MENU_ADDR);
set_saveram_mask(0x1fff);
set_rom_mask(0x3fffff);
set_mapper(0x7);
snes_reset(0);
while(get_cic_state() == CIC_FAIL) {
rdyled(0);
readled(0);
writeled(0);
delay_ms(500);
rdyled(1);
readled(1);
writeled(1);
delay_ms(500);
}
/* some sanity checks */
int main( void )
{
uint8_t card_go = 0;
while(!card_go) {
if(disk_status(0) & (STA_NOINIT|STA_NODISK)) {
snes_bootprint(" No SD Card found! \0");
while(disk_status(0) & (STA_NOINIT|STA_NODISK));
delay_ms(200);
}
file_open((uint8_t*)"/sd2snes/menu.bin", FA_READ);
if(file_status != FILE_OK) {
snes_bootprint(" /sd2snes/menu.bin not found! \0");
while(disk_status(0) == RES_OK);
} else {
card_go = 1;
}
file_close();
}
snes_bootprint(" Loading ... \0");
if(get_cic_state() == CIC_PAIR) {
printf("PAIR MODE ENGAGED!\n");
cic_pair(CIC_NTSC, CIC_NTSC);
}
rdyled(1);
readled(0);
writeled(0);
cfg_load();
cfg_save();
sram_writebyte(cfg_is_last_game_valid(), SRAM_STATUS_ADDR+SYS_LAST_STATUS);
cfg_get_last_game(file_lfn);
sram_writeblock(strrchr((const char*)file_lfn, '/')+1, SRAM_LASTGAME_ADDR, 256);
*fs_path=0;
uint32_t saved_dir_id;
get_db_id(&saved_dir_id);
uint32_t mem_dir_id = sram_readlong(SRAM_DIRID);
uint32_t mem_magic = sram_readlong(SRAM_SCRATCHPAD);
printf("mem_magic=%lx mem_dir_id=%lx saved_dir_id=%lx\n", mem_magic, mem_dir_id, saved_dir_id);
if((mem_magic != 0x12345678) || (mem_dir_id != saved_dir_id) || (newcard)) {
newcard = 0;
/* generate fs footprint (interesting files only) */
uint32_t curr_dir_id = scan_dir(fs_path, NULL, 0, 0);
printf("curr dir id = %lx\n", curr_dir_id);
/* files changed or no database found? */
if((get_db_id(&saved_dir_id) != FR_OK)
|| saved_dir_id != curr_dir_id) {
/* rebuild database */
printf("saved dir id = %lx\n", saved_dir_id);
printf("rebuilding database...");
snes_bootprint(" rebuilding database ... \0");
curr_dir_id = scan_dir(fs_path, NULL, 1, 0);
sram_writeblock(&curr_dir_id, SRAM_DB_ADDR, 4);
uint32_t endaddr, direndaddr;
sram_readblock(&endaddr, SRAM_DB_ADDR+4, 4);
sram_readblock(&direndaddr, SRAM_DB_ADDR+8, 4);
printf("%lx %lx\n", endaddr, direndaddr);
printf("sorting database...");
snes_bootprint(" sorting database ... \0");
sort_all_dir(direndaddr);
printf("done\n");
snes_bootprint(" saving database ... \0");
save_sram((uint8_t*)"/sd2snes/sd2snes.db", endaddr-SRAM_DB_ADDR, SRAM_DB_ADDR);
save_sram((uint8_t*)"/sd2snes/sd2snes.dir", direndaddr-(SRAM_DIR_ADDR), SRAM_DIR_ADDR);
fpga_pgm((uint8_t*)"/sd2snes/fpga_base.bit");
printf("done\n");
} else {
printf("saved dir id = %lx\n", saved_dir_id);
printf("different card, consistent db, loading db...\n");
fpga_pgm((uint8_t*)"/sd2snes/fpga_base.bit");
load_sram_offload((uint8_t*)"/sd2snes/sd2snes.db", SRAM_DB_ADDR);
load_sram_offload((uint8_t*)"/sd2snes/sd2snes.dir", SRAM_DIR_ADDR);
}
sram_writelong(curr_dir_id, SRAM_DIRID);
sram_writelong(0x12345678, SRAM_SCRATCHPAD);
} else {
snes_bootprint(" same card, loading db... \0");
printf("same card, loading db...\n");
fpga_pgm((uint8_t*)"/sd2snes/fpga_base.bit");
load_sram_offload((uint8_t*)"/sd2snes/sd2snes.db", SRAM_DB_ADDR);
load_sram_offload((uint8_t*)"/sd2snes/sd2snes.dir", SRAM_DIR_ADDR);
}
/* cli_loop(); */
/* load menu */
fpga_dspx_reset(1);
uart_putc('(');
load_rom((uint8_t*)"/sd2snes/menu.bin", SRAM_MENU_ADDR, 0);
/* force memory size + mapper */
set_rom_mask(0x3fffff);
set_mapper(0x7);
uart_putc(')');
uart_putcrlf();
sram_writebyte(0, SRAM_CMD_ADDR);
if((rtc_state = rtc_isvalid()) != RTC_OK) {
printf("RTC invalid!\n");
sram_writebyte(0xff, SRAM_STATUS_ADDR+SYS_RTC_STATUS);
set_bcdtime(0x20120701000000LL);
set_fpga_time(0x20120701000000LL);
invalidate_rtc();
} else {
printf("RTC valid!\n");
sram_writebyte(0x00, SRAM_STATUS_ADDR+SYS_RTC_STATUS);
set_fpga_time(get_bcdtime());
}
sram_memset(SRAM_SYSINFO_ADDR, 13*40, 0x20);
printf("SNES GO!\n");
snes_reset(1);
fpga_reset_srtc_state();
delay_ms(SNES_RESET_PULSELEN_MS);
sram_writebyte(32, SRAM_CMD_ADDR);
snes_reset(0);
uint32_t mem_dir_id;
uint32_t mem_magic;
uint8_t cmd = 0;
uint64_t btime = 0;
uint32_t filesize=0;
printf("test sram\n");
while(!sram_reliable()) cli_entrycheck();
printf("ok\n");
//while(1) {
// delay_ms(1000);
// printf("Estimated SNES master clock: %ld Hz\n", get_snes_sysclk());
//}
//sram_hexdump(SRAM_DB_ADDR, 0x200);
//sram_hexdump(SRAM_MENU_ADDR, 0x400);
while(!cmd) {
cmd=menu_main_loop();
printf("cmd: %d\n", cmd);
uart_putc('-');
switch(cmd) {
case SNES_CMD_LOADROM:
get_selected_name(file_lfn);
printf("Selected name: %s\n", file_lfn);
cfg_save_last_game(file_lfn);
cfg_set_last_game_valid(1);
cfg_save();
filesize = load_rom(file_lfn, SRAM_ROM_ADDR, LOADROM_WITH_SRAM | LOADROM_WITH_RESET);
break;
case SNES_CMD_SETRTC:
/* get time from RAM */
btime = sram_gettime(SRAM_PARAM_ADDR);
/* set RTC */
set_bcdtime(btime);
set_fpga_time(btime);
cmd=0; /* stay in menu loop */
break;
case SNES_CMD_SYSINFO:
/* go to sysinfo loop */
sysinfo_loop();
cmd=0; /* stay in menu loop */
break;
case SNES_CMD_LOADSPC:
/* load SPC file */
get_selected_name(file_lfn);
printf("Selected name: %s\n", file_lfn);
filesize = load_spc(file_lfn, SRAM_SPC_DATA_ADDR, SRAM_SPC_HEADER_ADDR);
cmd=0; /* stay in menu loop */
break;
case SNES_CMD_RESET:
/* process RESET request from SNES */
printf("RESET requested by SNES\n");
snes_reset_pulse();
cmd=0; /* stay in menu loop */
break;
case SNES_CMD_LOADLAST:
cfg_get_last_game(file_lfn);
printf("Selected name: %s\n", file_lfn);
filesize = load_rom(file_lfn, SRAM_ROM_ADDR, LOADROM_WITH_SRAM | LOADROM_WITH_RESET);
break;
default:
printf("unknown cmd: %d\n", cmd);
cmd=0; /* unknown cmd: stay in loop */
break;
}
}
printf("loaded %lu bytes\n", filesize);
printf("cmd was %x, going to snes main loop\n", cmd);
uint32_t filesize = 0;
uint8_t snes_reset_prev = 0, snes_reset_now = 0, snes_reset_state = 0;
uint16_t reset_count = 0;
if(romprops.has_msu1) {
while(!msu1_loop());
prepare_reset();
continue;
}
LPC_GPIO2->FIODIR = BV( 4 ) | BV( 5 );
LPC_GPIO1->FIODIR = BV( 23 ) | BV( SNES_CIC_PAIR_BIT );
BITBAND( SNES_CIC_PAIR_REG->FIOSET, SNES_CIC_PAIR_BIT ) = 1;
LPC_GPIO0->FIODIR = BV( 16 );
cmd=0;
uint8_t snes_reset_prev=0, snes_reset_now=0, snes_reset_state=0;
uint16_t reset_count=0;
while(fpga_test() == FPGA_TEST_TOKEN) {
cli_entrycheck();
sleep_ms(250);
sram_reliable();
printf("%s ", get_cic_statename(get_cic_state()));
if(reset_changed) {
printf("reset\n");
reset_changed = 0;
/* connect UART3 on P0[25:26] + SSP0 on P0[15:18] + MAT3.0 on P0[10] */
LPC_PINCON->PINSEL1 = BV( 18 ) | BV( 19 ) | BV( 20 ) | BV( 21 ) /* UART3 */
| BV( 3 ) | BV( 5 ); /* SSP0 (FPGA) except SS */
LPC_PINCON->PINSEL0 = BV( 31 ); /* SSP0 */
/* | BV(13) | BV(15) | BV(17) | BV(19) SSP1 (SD) */
/* pull-down CIC data lines */
LPC_PINCON->PINMODE0 = BV( 0 ) | BV( 1 ) | BV( 2 ) | BV( 3 );
clock_disconnect(); /* Disable clock */
snes_init(); /* Set SNES Reset */
power_init(); /* Enable power block of LPC */
timer_init(); /* Enable internal timer */
uart_init(); /* Configure UART */
fpga_spi_init(); /* Configure FPGA_SPI IOs */
spi_preinit(); /* Initialise SPI IO */
led_init(); /* Initialise LEDs IO */
/* do this last because the peripheral init()s change PCLK dividers */
clock_init();
/* Output FPGA clock */
LPC_PINCON->PINSEL0 |= BV( 20 ) | BV( 21 ); /* MAT3.0 (FPGA clock) */
led_pwm(); /* Enabke PWM on LED (even if not used...) */
sdn_init(); /* SD init */
/* Print banner */
printf( "\n\nsd2snes mk.2\n============\nfw ver.: " CONFIG_VERSION "\ncpu clock: %d Hz\n", CONFIG_CPU_FREQUENCY );
/* Init file manager */
file_init();
/* */
cic_init( 0 );
/* setup timer (fpga clk) */
LPC_TIM3->TCR = 2;
LPC_TIM3->CTCR = 0;
LPC_TIM3->PR = 0;
LPC_TIM3->EMR = EMC0TOGGLE;
LPC_TIM3->MCR = MR0R;
LPC_TIM3->MR0 = 1;
LPC_TIM3->TCR = 1;
fpga_init();
fpga_rompgm();
sram_writebyte( 0, SRAM_CMD_ADDR );
while ( 1 ) /* Main loop */
{
if ( disk_state == DISK_CHANGED )
{
sdn_init(); /* Reinit SD card */
newcard = 1;
}
load_bootrle( SRAM_MENU_ADDR );
set_saveram_mask( 0xffff );
set_rom_mask( 0x3fffff );
set_mapper( 0x7 );
snes_reset( 0 );
while ( get_cic_state() == CIC_FAIL )
{
rdyled( 0 );
readled( 0 );
writeled( 0 );
delay_ms( 500 );
rdyled( 1 );
readled( 1 );
writeled( 1 );
delay_ms( 500 );
}
/* Wait for valid card inserted */
card_go = 0;
while ( !card_go )
{
if ( disk_status( 0 ) & ( STA_NOINIT | STA_NODISK ) )
{
snes_bootprint( " No SD Card found! \0" );
while ( disk_status( 0 ) & ( STA_NOINIT | STA_NODISK ) );
delay_ms( 200 );
}
file_open( ( uint8_t * )"/sd2snes/menu.bin", FA_READ );
if ( file_status != FILE_OK )
{
snes_bootprint( " /sd2snes/menu.bin not found! \0" );
while ( disk_status( 0 ) == RES_OK );
}
else
{
/* Card found ! */
card_go = 1;
}
file_close();
}
snes_bootprint( " Loading ... \0" );
if ( get_cic_state() == CIC_PAIR )
{
printf( "PAIR MODE ENGAGED!\n" );
cic_pair( CIC_NTSC, CIC_NTSC );
}
rdyled( 1 );
readled( 0 );
writeled( 0 );
/* Load user config */
cfg_load();
cfg_save();
sram_writebyte( cfg_is_last_game_valid(), SRAM_STATUS_ADDR + SYS_LAST_STATUS );
cfg_get_last_game( file_lfn );
sram_writeblock( strrchr( ( const char * )file_lfn, '/' ) + 1, SRAM_LASTGAME_ADDR, 256 );
*fs_path = 0;
get_db_id( &saved_dir_id );
mem_dir_id = sram_readlong( SRAM_DIRID );
mem_magic = sram_readlong( SRAM_SCRATCHPAD );
printf( "mem_magic=%lx mem_dir_id=%lx saved_dir_id=%lx\n", mem_magic, mem_dir_id, saved_dir_id );
if ( ( mem_magic != 0x12345678 ) || ( mem_dir_id != saved_dir_id ) || ( newcard ) )
{
newcard = 0;
/* generate fs footprint (interesting files only) */
uint32_t curr_dir_id = scan_dir( fs_path, NULL, 0, 0 );
printf( "curr dir id = %lx\n", curr_dir_id );
/* files changed or no database found? */
if ( ( get_db_id( &saved_dir_id ) != FR_OK ) || saved_dir_id != curr_dir_id )
{
uint32_t endaddr, direndaddr;
/* rebuild database */
printf( "saved dir id = %lx\n", saved_dir_id );
printf( "rebuilding database..." );
snes_bootprint( " rebuilding database ... \0" );
curr_dir_id = scan_dir( fs_path, NULL, 1, 0 );
sram_writeblock( &curr_dir_id, SRAM_DB_ADDR, 4 );
sram_readblock( &endaddr, SRAM_DB_ADDR + 4, 4 );
sram_readblock( &direndaddr, SRAM_DB_ADDR + 8, 4 );
printf( "%lx %lx\n", endaddr, direndaddr );
printf( "sorting database..." );
snes_bootprint( " sorting database ... \0" );
sort_all_dir( direndaddr );
printf( "done\n" );
snes_bootprint( " saving database ... \0" );
save_sram( ( uint8_t * )"/sd2snes/sd2snes.db", endaddr - SRAM_DB_ADDR, SRAM_DB_ADDR );
save_sram( ( uint8_t * )"/sd2snes/sd2snes.dir", direndaddr - ( SRAM_DIR_ADDR ), SRAM_DIR_ADDR );
fpga_pgm( ( uint8_t * )"/sd2snes/fpga_base.bit" );
printf( "done\n" );
}
else
{
printf( "saved dir id = %lx\n", saved_dir_id );
printf( "different card, consistent db, loading db...\n" );
fpga_pgm( ( uint8_t * )"/sd2snes/fpga_base.bit" );
load_sram_offload( ( uint8_t * )"/sd2snes/sd2snes.db", SRAM_DB_ADDR );
load_sram_offload( ( uint8_t * )"/sd2snes/sd2snes.dir", SRAM_DIR_ADDR );
}
sram_writelong( curr_dir_id, SRAM_DIRID );
sram_writelong( 0x12345678, SRAM_SCRATCHPAD );
}
else
{
snes_bootprint( " same card, loading db... \n" );
fpga_pgm( ( uint8_t * )"/sd2snes/fpga_base.bit" );
load_sram_offload( ( uint8_t * )"/sd2snes/sd2snes.db", SRAM_DB_ADDR );
load_sram_offload( ( uint8_t * )"/sd2snes/sd2snes.dir", SRAM_DIR_ADDR );
}
/* cli_loop(); */
/* load menu */
fpga_dspx_reset( 1 );
uart_putc( '(' );
uart_putcrlf();
load_rom( ( uint8_t * )"/sd2snes/menu.bin", SRAM_MENU_ADDR, 0 );
/* force memory size + mapper */
set_rom_mask( 0x3fffff );
set_mapper( 0x7 );
uart_putc( ')' );
uart_putcrlf();
sram_writebyte( 0, SRAM_CMD_ADDR );
snes_bootprint( " same card, loading db... \n" );
if ( ( rtc_state = rtc_isvalid() ) != RTC_OK )
{
printf( "RTC invalid!\n" );
sram_writebyte( 0xff, SRAM_STATUS_ADDR + SYS_RTC_STATUS );
set_bcdtime( 0x20120701000000LL );
set_fpga_time( 0x20120701000000LL );
invalidate_rtc();
}
else
{
printf( "RTC valid!\n" );
sram_writebyte( 0x00, SRAM_STATUS_ADDR + SYS_RTC_STATUS );
set_fpga_time( get_bcdtime() );
}
sram_memset( SRAM_SYSINFO_ADDR, 13 * 40, 0x20 );
printf( "SNES GO!\n" );
snes_reset( 1 );
fpga_reset_srtc_state();
}
snes_reset_now=get_snes_reset();
if(snes_reset_now) {
if(!snes_reset_prev) {
printf("RESET BUTTON DOWN\n");
snes_reset_state=1;
reset_count=0;
}
} else {
if(snes_reset_prev) {
printf("RESET BUTTON UP\n");
snes_reset_state=0;
}
}
if(snes_reset_state) {
reset_count++;
} else {
sram_reliable();
snes_main_loop();
}
if(reset_count>4) {
reset_count=0;
prepare_reset();
break;
}
snes_reset_prev = snes_reset_now;
delay_ms( SNES_RESET_PULSELEN_MS );
sram_writebyte( 32, SRAM_CMD_ADDR );
snes_reset( 0 );
cmd = 0;
btime = 0;
filesize = 0;
printf( "test sram... " );
while ( !sram_reliable() )
{
cli_entrycheck();
}
printf( "ok\nWaiting command from menu...\n" );
//while(1) {
// delay_ms(1000);
// printf("Estimated SNES master clock: %ld Hz\n", get_snes_sysclk());
//}
//sram_hexdump(SRAM_DB_ADDR, 0x200);
//sram_hexdump(SRAM_MENU_ADDR, 0x400);
while ( !cmd )
{
cmd = menu_main_loop();
printf( "cmd: %d\n", cmd );
switch ( cmd )
{
case SNES_CMD_LOADROM:
get_selected_name( file_lfn );
printf( "Selected name: %s\n", file_lfn );
cfg_save_last_game( file_lfn );
cfg_set_last_game_valid( 1 );
cfg_save();
filesize = load_rom( file_lfn, SRAM_ROM_ADDR, LOADROM_WITH_SRAM | LOADROM_WITH_RESET );
printf( "Filesize = %lu\n", filesize );
break;
case SNES_CMD_SETRTC:
/* get time from RAM */
btime = sram_gettime( SRAM_PARAM_ADDR );
/* set RTC */
set_bcdtime( btime );
set_fpga_time( btime );
cmd = 0; /* stay in menu loop */
break;
case SNES_CMD_SYSINFO:
/* go to sysinfo loop */
sysinfo_loop();
cmd = 0; /* stay in menu loop */
break;
case SNES_CMD_LOADSPC:
/* load SPC file */
get_selected_name( file_lfn );
printf( "Selected name: %s\n", file_lfn );
filesize = load_spc( file_lfn, SRAM_SPC_DATA_ADDR, SRAM_SPC_HEADER_ADDR );
cmd = 0; /* stay in menu loop */
break;
case SNES_CMD_RESET:
/* process RESET request from SNES */
printf( "RESET requested by SNES\n" );
snes_reset_pulse();
cmd = 0; /* stay in menu loop */
break;
case SNES_CMD_LOADLAST:
cfg_get_last_game( file_lfn );
printf( "Selected name: %s\n", file_lfn );
filesize = load_rom( file_lfn, SRAM_ROM_ADDR, LOADROM_WITH_SRAM | LOADROM_WITH_RESET );
break;
default:
printf( "unknown cmd: %d\n", cmd );
cmd = 0; /* unknown cmd: stay in loop */
break;
}
}
printf( "loaded %lu bytes\n", filesize );
printf( "cmd was %x, going to snes main loop\n", cmd );
if ( romprops.has_msu1 )
{
while ( !msu1_loop() );
prepare_reset();
continue;
}
cmd = 0;
snes_reset_prev = 0;
snes_reset_now = 0;
snes_reset_state = 0;
reset_count = 0;
while ( fpga_test() == FPGA_TEST_TOKEN )
{
cli_entrycheck();
sleep_ms( 250 );
sram_reliable();
printf( "%s ", get_cic_statename( get_cic_state() ) );
if ( reset_changed )
{
printf( "reset\n" );
reset_changed = 0;
fpga_reset_srtc_state();
}
snes_reset_now = get_snes_reset();
if ( snes_reset_now )
{
if ( !snes_reset_prev )
{
printf( "RESET BUTTON DOWN\n" );
snes_reset_state = 1;
reset_count = 0;
}
}
else
{
if ( snes_reset_prev )
{
printf( "RESET BUTTON UP\n" );
snes_reset_state = 0;
}
}
if ( snes_reset_state )
{
reset_count++;
}
else
{
sram_reliable();
snes_main_loop();
}
if ( reset_count > 4 )
{
reset_count = 0;
prepare_reset();
break;
}
snes_reset_prev = snes_reset_now;
}
/* fpga test fail: panic */
if ( fpga_test() != FPGA_TEST_TOKEN )
{
led_panic();
}
/* else reset */
}
/* fpga test fail: panic */
if(fpga_test() != FPGA_TEST_TOKEN){
led_panic(LED_PANIC_FPGA_DEAD);
}
/* else reset */
}
}

File diff suppressed because it is too large Load Diff

View File

@ -30,51 +30,74 @@
#include <arm/NXP/LPC17xx/LPC17xx.h>
#include "smc.h"
#define SRAM_ROM_ADDR (0x000000L)
#define SRAM_SAVE_ADDR (0xE00000L)
#define MASK_BITS (0x000000)
#if 0
#define SRAM_ROM_ADDR ((0x000000L) & ~MASK_BITS)
#define SRAM_SAVE_ADDR ((0x400000L) & ~MASK_BITS)
#define SRAM_MENU_ADDR (0xC00000L)
#define SRAM_DIR_ADDR (0xC10000L)
#define SRAM_DB_ADDR (0xC80000L)
#define SRAM_MENU_ADDR ((0x7A0000L) & ~MASK_BITS)
#define SRAM_DIR_ADDR ((0x410000L) & ~MASK_BITS)
#define SRAM_DB_ADDR ((0x420000L) & ~MASK_BITS)
#define SRAM_SPC_DATA_ADDR (0xFD0000L)
#define SRAM_SPC_HEADER_ADDR (0xFE0000L)
#define SRAM_SPC_DATA_ADDR ((0x430000L) & ~MASK_BITS)
#define SRAM_SPC_HEADER_ADDR ((0x440000L) & ~MASK_BITS)
#define SRAM_MENU_SAVE_ADDR (0xFF0000L)
#define SRAM_CMD_ADDR (0xFF1000L)
#define SRAM_PARAM_ADDR (0xFF1004L)
#define SRAM_STATUS_ADDR (0xFF1100L)
#define SRAM_SYSINFO_ADDR (0xFF1200L)
#define SRAM_LASTGAME_ADDR (0xFF1420L)
#define SRAM_SCRATCHPAD (0xFFFF00L)
#define SRAM_DIRID (0xFFFFF0L)
#define SRAM_MENU_SAVE_ADDR ((0x7F0000L) & ~MASK_BITS)
#define SRAM_CMD_ADDR ((0x7F1000L) & ~MASK_BITS)
#define SRAM_PARAM_ADDR ((0x7F1004L) & ~MASK_BITS)
#define SRAM_STATUS_ADDR ((0x7F1100L) & ~MASK_BITS)
#define SRAM_SYSINFO_ADDR ((0x7F1200L) & ~MASK_BITS)
#define SRAM_LASTGAME_ADDR ((0x7F1420L) & ~MASK_BITS)
#define SRAM_SCRATCHPAD ((0x7FFF00L) & ~MASK_BITS)
#define SRAM_DIRID ((0x7FFFF0L) & ~MASK_BITS)
#define SRAM_RELIABILITY_SCORE (0x100)
#else
#define SRAM_ROM_ADDR ((0x000000L) & ~MASK_BITS)
#define SRAM_SAVE_ADDR ((0x600000L) & ~MASK_BITS)
#define LOADROM_WITH_SRAM (1)
#define LOADROM_WITH_RESET (2)
#define SRAM_MENU_ADDR ((0x500000L) & ~MASK_BITS)
#define SRAM_DIR_ADDR ((0x510000L) & ~MASK_BITS)
#define SRAM_DB_ADDR ((0x580000L) & ~MASK_BITS)
uint32_t load_rom(uint8_t* filename, uint32_t base_addr, uint8_t flags);
uint32_t load_spc(uint8_t* filename, uint32_t spc_data_addr, uint32_t spc_header_addr);
uint32_t load_sram(uint8_t* filename, uint32_t base_addr);
uint32_t load_sram_offload(uint8_t* filename, uint32_t base_addr);
uint32_t load_sram_rle(uint8_t* filename, uint32_t base_addr);
uint32_t load_bootrle(uint32_t base_addr);
void load_dspx(const uint8_t* filename, uint8_t st0010);
void sram_hexdump(uint32_t addr, uint32_t len);
uint8_t sram_readbyte(uint32_t addr);
uint16_t sram_readshort(uint32_t addr);
uint32_t sram_readlong(uint32_t addr);
void sram_writebyte(uint8_t val, uint32_t addr);
void sram_writeshort(uint16_t val, uint32_t addr);
void sram_writelong(uint32_t val, uint32_t addr);
void sram_readblock(void* buf, uint32_t addr, uint16_t size);
void sram_readstrn(void* buf, uint32_t addr, uint16_t size);
void sram_readlongblock(uint32_t* buf, uint32_t addr, uint16_t count);
void sram_writeblock(void* buf, uint32_t addr, uint16_t size);
void save_sram(uint8_t* filename, uint32_t sram_size, uint32_t base_addr);
uint32_t calc_sram_crc(uint32_t base_addr, uint32_t size);
uint8_t sram_reliable(void);
void sram_memset(uint32_t base_addr, uint32_t len, uint8_t val);
uint64_t sram_gettime(uint32_t base_addr);
#define SRAM_SPC_DATA_ADDR ((0x7D0000L) & ~MASK_BITS)
#define SRAM_SPC_HEADER_ADDR ((0x7E0000L) & ~MASK_BITS)
#define SRAM_MENU_SAVE_ADDR ((0x7F0000L) & ~MASK_BITS)
#define SRAM_CMD_ADDR ((0x7F1000L) & ~MASK_BITS)
#define SRAM_PARAM_ADDR ((0x7F1004L) & ~MASK_BITS)
#define SRAM_STATUS_ADDR ((0x7F1100L) & ~MASK_BITS)
#define SRAM_SYSINFO_ADDR ((0x7F1200L) & ~MASK_BITS)
#define SRAM_LASTGAME_ADDR ((0x7F1420L) & ~MASK_BITS)
#define SRAM_SCRATCHPAD ((0x7FFF00L) & ~MASK_BITS)
#define SRAM_DIRID ((0x7FFFF0L) & ~MASK_BITS)
#define SRAM_RELIABILITY_SCORE (0x100)
#endif
#define LOADROM_WITH_SRAM (1)
#define LOADROM_WITH_RESET (2)
uint32_t load_rom( uint8_t *filename, uint32_t base_addr, uint8_t flags );
uint32_t load_spc( uint8_t *filename, uint32_t spc_data_addr, uint32_t spc_header_addr );
uint32_t load_sram( uint8_t *filename, uint32_t base_addr );
uint32_t load_sram_offload( uint8_t *filename, uint32_t base_addr );
uint32_t load_sram_rle( uint8_t *filename, uint32_t base_addr );
uint32_t load_bootrle( uint32_t base_addr );
void load_dspx( const uint8_t *filename, uint8_t st0010 );
void sram_hexdump( uint32_t addr, uint32_t len );
uint8_t sram_readbyte( uint32_t addr );
uint16_t sram_readshort( uint32_t addr );
uint32_t sram_readlong( uint32_t addr );
void sram_writebyte( uint8_t val, uint32_t addr );
void sram_writeshort( uint16_t val, uint32_t addr );
void sram_writelong( uint32_t val, uint32_t addr );
void sram_readblock( void *buf, uint32_t addr, uint16_t size );
void sram_readlongblock( uint32_t *buf, uint32_t addr, uint16_t count );
void sram_writeblock( void *buf, uint32_t addr, uint16_t size );
void save_sram( uint8_t *filename, uint32_t sram_size, uint32_t base_addr );
uint32_t calc_sram_crc( uint32_t base_addr, uint32_t size );
uint8_t sram_reliable( void );
void sram_memset( uint32_t base_addr, uint32_t len, uint8_t val );
uint64_t sram_gettime( uint32_t base_addr );
void sram_readstrn( void *buf, uint32_t addr, uint16_t size );
#endif

View File

@ -29,272 +29,348 @@ uint16_t fpga_status_now;
enum msu_reset_state { MSU_RESET_NONE = 0, MSU_RESET_SHORT, MSU_RESET_LONG };
void prepare_audio_track(uint16_t msu_track) {
/* open file, fill buffer */
char suffix[11];
f_close(&file_handle);
snprintf(suffix, sizeof(suffix), "-%d.pcm", msu_track);
strcpy((char*)file_buf, (char*)file_lfn);
strcpy(strrchr((char*)file_buf, (int)'.'), suffix);
DBG_MSU1 printf("filename: %s\n", file_buf);
if(f_open(&file_handle, (const TCHAR*)file_buf, FA_READ) == FR_OK) {
file_handle.cltbl = pcm_cltbl;
pcm_cltbl[0] = CLTBL_SIZE;
f_lseek(&file_handle, CREATE_LINKMAP);
f_lseek(&file_handle, 4L);
f_read(&file_handle, &msu_loop_point, 4, &msu_audio_bytes_read);
DBG_MSU1 printf("loop point: %ld samples\n", msu_loop_point);
ff_sd_offload=1;
sd_offload_tgt=1;
f_lseek(&file_handle, 8L);
set_dac_addr(0);
void prepare_audio_track( uint16_t msu_track )
{
/* open file, fill buffer */
char suffix[11];
f_close( &file_handle );
snprintf( suffix, sizeof( suffix ), "-%d.pcm", msu_track );
strcpy( ( char * )file_buf, ( char * )file_lfn );
strcpy( strrchr( ( char * )file_buf, ( int )'.' ), suffix );
DBG_MSU1 printf( "filename: %s\n", file_buf );
if ( f_open( &file_handle, ( const TCHAR * )file_buf, FA_READ ) == FR_OK )
{
file_handle.cltbl = pcm_cltbl;
pcm_cltbl[0] = CLTBL_SIZE;
f_lseek( &file_handle, CREATE_LINKMAP );
f_lseek( &file_handle, 4L );
f_read( &file_handle, &msu_loop_point, 4, &msu_audio_bytes_read );
DBG_MSU1 printf( "loop point: %ld samples\n", msu_loop_point );
ff_sd_offload = 1;
sd_offload_tgt = 1;
f_lseek( &file_handle, 8L );
set_dac_addr( 0 );
dac_pause();
dac_reset();
ff_sd_offload = 1;
sd_offload_tgt = 1;
f_read( &file_handle, file_buf, MSU_DAC_BUFSIZE, &msu_audio_bytes_read );
/* clear busy bit */
set_msu_status( 0x00, 0x28 ); /* set no bits, reset audio_busy + audio_error */
}
else
{
f_close( &file_handle );
set_msu_status( 0x08, 0x20 ); /* reset audio_busy, set audio_error */
}
}
void prepare_data( uint32_t msu_offset )
{
DBG_MSU1 printf( "Data requested! Offset=%08lx page1=%08lx page2=%08lx\n", msu_offset, msu_page1_start,
msu_page2_start );
if ( ( ( msu_offset < msu_page1_start )
|| ( msu_offset >= msu_page1_start + msu_page_size ) )
&& ( ( msu_offset < msu_page2_start )
|| ( msu_offset >= msu_page2_start + msu_page_size ) ) )
{
DBG_MSU1 printf( "offset %08lx out of range (%08lx-%08lx, %08lx-%08lx), reload\n", msu_offset, msu_page1_start,
msu_page1_start + msu_page_size - 1, msu_page2_start, msu_page2_start + msu_page_size - 1 );
/* "cache miss" */
/* fill buffer */
set_msu_addr( 0x0 );
sd_offload_tgt = 2;
ff_sd_offload = 1;
msu_res = f_lseek( &msufile, msu_offset );
DBG_MSU1 printf( "seek to %08lx, res = %d\n", msu_offset, msu_res );
sd_offload_tgt = 2;
ff_sd_offload = 1;
msu_res = f_read( &msufile, file_buf, 16384, &msu_data_bytes_read );
DBG_MSU1 printf( "read res = %d\n", msu_res );
DBG_MSU1 printf( "read %d bytes\n", msu_data_bytes_read );
msu_reset( 0x0 );
msu_page1_start = msu_offset;
msu_page2_start = msu_offset + msu_page_size;
}
else
{
if ( msu_offset >= msu_page1_start && msu_offset <= msu_page1_start + msu_page_size )
{
msu_reset( 0x0000 + msu_offset - msu_page1_start );
DBG_MSU1 printf( "inside page1, new offset: %08lx\n", 0x0000 + msu_offset - msu_page1_start );
if ( !( msu_page2_start == msu_page1_start + msu_page_size ) )
{
set_msu_addr( 0x2000 );
sd_offload_tgt = 2;
ff_sd_offload = 1;
f_read( &msufile, file_buf, 8192, &msu_data_bytes_read );
DBG_MSU1 printf( "next page dirty (was: %08lx), loaded page2 (start now: ", msu_page2_start );
msu_page2_start = msu_page1_start + msu_page_size;
DBG_MSU1 printf( "%08lx)\n", msu_page2_start );
}
}
else if ( msu_offset >= msu_page2_start && msu_offset <= msu_page2_start + msu_page_size )
{
DBG_MSU1 printf( "inside page2, new offset: %08lx\n", 0x2000 + msu_offset - msu_page2_start );
msu_reset( 0x2000 + msu_offset - msu_page2_start );
if ( !( msu_page1_start == msu_page2_start + msu_page_size ) )
{
set_msu_addr( 0x0 );
sd_offload_tgt = 2;
ff_sd_offload = 1;
f_read( &msufile, file_buf, 8192, &msu_data_bytes_read );
DBG_MSU1 printf( "next page dirty (was: %08lx), loaded page1 (start now: ", msu_page1_start );
msu_page1_start = msu_page2_start + msu_page_size;
DBG_MSU1 printf( "%08lx)\n", msu_page1_start );
}
}
else
{
printf( "!!!WATWATWAT!!!\n" );
}
}
/* clear bank bit to mask bank reset artifact */
fpga_status_now &= ~0x2000;
fpga_status_prev &= ~0x2000;
/* clear busy bit */
set_msu_status( 0x00, 0x10 );
}
int msu1_check_reset( void )
{
static tick_t rising_ticks;
static uint8_t resbutton = 0, resbutton_prev = 0;
int result = MSU_RESET_NONE;
resbutton = get_snes_reset();
if ( resbutton && !resbutton_prev ) /* push */
{
rising_ticks = getticks();
}
else if ( resbutton && resbutton_prev ) /* hold */
{
if ( getticks() > rising_ticks + 99 )
{
result = MSU_RESET_LONG;
}
}
else if ( !resbutton && resbutton_prev ) /* release */
{
if ( getticks() < rising_ticks + 99 )
{
result = MSU_RESET_SHORT;
}
}
else
{
result = MSU_RESET_NONE;
}
resbutton_prev = resbutton;
return result;
}
int msu1_check( uint8_t *filename )
{
/* open MSU file */
strcpy( ( char * )file_buf, ( char * )filename );
strcpy( strrchr( ( char * )file_buf, ( int )'.' ), ".msu" );
printf( "MSU datafile: %s\n", file_buf );
if ( f_open( &msufile, ( const TCHAR * )file_buf, FA_READ ) != FR_OK )
{
printf( "MSU datafile not found\n" );
return 0;
}
msufile.cltbl = msu_cltbl;
msu_cltbl[0] = CLTBL_SIZE;
if ( f_lseek( &msufile, CREATE_LINKMAP ) )
{
printf( "Error creating FF linkmap for MSU file!\n" );
}
romprops.fpga_features |= FEAT_MSU1;
return 1;
}
int msu1_loop()
{
/* it is assumed that the MSU file is already opened by calling msu1_check(). */
while ( fpga_status() & 0x4000 );
uint16_t dac_addr = 0;
uint16_t msu_addr = 0;
uint8_t msu_repeat = 0;
uint16_t msu_track = 0;
uint32_t msu_offset = 0;
fpga_status_prev = fpga_status();
fpga_status_now = fpga_status();
int msu_res;
/* set_msu_addr(0x0);
msu_reset(0x0);
ff_sd_offload=1;
sd_offload_tgt=2;
f_lseek(&msufile, 0L);
ff_sd_offload=1;
sd_offload_tgt=2;
f_read(&msufile, file_buf, 16384, &msu_data_bytes_read);
*/
set_dac_addr( dac_addr );
dac_pause();
dac_reset();
ff_sd_offload=1;
sd_offload_tgt=1;
f_read(&file_handle, file_buf, MSU_DAC_BUFSIZE, &msu_audio_bytes_read);
/* clear busy bit */
set_msu_status(0x00, 0x28); /* set no bits, reset audio_busy + audio_error */
} else {
f_close(&file_handle);
set_msu_status(0x08, 0x20); /* reset audio_busy, set audio_error */
}
}
void prepare_data(uint32_t msu_offset) {
DBG_MSU1 printf("Data requested! Offset=%08lx page1=%08lx page2=%08lx\n", msu_offset, msu_page1_start, msu_page2_start);
if( ((msu_offset < msu_page1_start)
|| (msu_offset >= msu_page1_start + msu_page_size))
&& ((msu_offset < msu_page2_start)
|| (msu_offset >= msu_page2_start + msu_page_size))) {
DBG_MSU1 printf("offset %08lx out of range (%08lx-%08lx, %08lx-%08lx), reload\n", msu_offset, msu_page1_start,
msu_page1_start+msu_page_size-1, msu_page2_start, msu_page2_start+msu_page_size-1);
/* "cache miss" */
/* fill buffer */
set_msu_addr(0x0);
sd_offload_tgt=2;
ff_sd_offload=1;
msu_res = f_lseek(&msufile, msu_offset);
DBG_MSU1 printf("seek to %08lx, res = %d\n", msu_offset, msu_res);
sd_offload_tgt=2;
ff_sd_offload=1;
msu_res = f_read(&msufile, file_buf, 16384, &msu_data_bytes_read);
DBG_MSU1 printf("read res = %d\n", msu_res);
DBG_MSU1 printf("read %d bytes\n", msu_data_bytes_read);
msu_reset(0x0);
msu_page1_start = msu_offset;
msu_page2_start = msu_offset + msu_page_size;
} else {
if (msu_offset >= msu_page1_start && msu_offset <= msu_page1_start + msu_page_size) {
msu_reset(0x0000 + msu_offset - msu_page1_start);
DBG_MSU1 printf("inside page1, new offset: %08lx\n", 0x0000 + msu_offset-msu_page1_start);
if(!(msu_page2_start == msu_page1_start + msu_page_size)) {
set_msu_addr(0x2000);
sd_offload_tgt=2;
ff_sd_offload=1;
f_read(&msufile, file_buf, 8192, &msu_data_bytes_read);
DBG_MSU1 printf("next page dirty (was: %08lx), loaded page2 (start now: ", msu_page2_start);
msu_page2_start = msu_page1_start + msu_page_size;
DBG_MSU1 printf("%08lx)\n", msu_page2_start);
}
} else if (msu_offset >= msu_page2_start && msu_offset <= msu_page2_start + msu_page_size) {
DBG_MSU1 printf("inside page2, new offset: %08lx\n", 0x2000 + msu_offset-msu_page2_start);
msu_reset(0x2000 + msu_offset - msu_page2_start);
if(!(msu_page1_start == msu_page2_start + msu_page_size)) {
set_msu_addr(0x0);
sd_offload_tgt=2;
ff_sd_offload=1;
f_read(&msufile, file_buf, 8192, &msu_data_bytes_read);
DBG_MSU1 printf("next page dirty (was: %08lx), loaded page1 (start now: ", msu_page1_start);
msu_page1_start = msu_page2_start + msu_page_size;
DBG_MSU1 printf("%08lx)\n", msu_page1_start);
}
} else printf("!!!WATWATWAT!!!\n");
}
/* clear bank bit to mask bank reset artifact */
fpga_status_now &= ~0x2000;
fpga_status_prev &= ~0x2000;
/* clear busy bit */
set_msu_status(0x00, 0x10);
}
set_msu_addr( 0x0 );
msu_reset( 0x0 );
ff_sd_offload = 1;
sd_offload_tgt = 2;
f_lseek( &msufile, 0L );
ff_sd_offload = 1;
sd_offload_tgt = 2;
f_read( &msufile, file_buf, 16384, &msu_data_bytes_read );
int msu1_check_reset(void) {
static tick_t rising_ticks;
prepare_audio_track( 0 );
prepare_data( 0 );
static uint8_t resbutton=0, resbutton_prev=0;
int result = MSU_RESET_NONE;
resbutton = get_snes_reset();
if(resbutton && !resbutton_prev) { /* push */
rising_ticks = getticks();
} else if(resbutton && resbutton_prev) { /* hold */
if(getticks() > rising_ticks + 99) {
result = MSU_RESET_LONG;
/* audio_start, data_start, 0, audio_ctrl[1:0], ctrl_start */
while ( ( msu_res = msu1_check_reset() ) == MSU_RESET_NONE )
{
cli_entrycheck();
fpga_status_now = fpga_status();
/* Data buffer refill */
if ( ( fpga_status_now & 0x2000 ) != ( fpga_status_prev & 0x2000 ) )
{
DBG_MSU1 printf( "data\n" );
if ( fpga_status_now & 0x2000 )
{
msu_addr = 0x0;
msu_page1_start = msu_page2_start + msu_page_size;
}
else
{
msu_addr = 0x2000;
msu_page2_start = msu_page1_start + msu_page_size;
}
set_msu_addr( msu_addr );
sd_offload_tgt = 2;
ff_sd_offload = 1;
msu_res = f_read( &msufile, file_buf, 8192, &msu_data_bytes_read );
DBG_MSU1 printf( "data buffer refilled. res=%d page1=%08lx page2=%08lx\n", msu_res, msu_page1_start, msu_page2_start );
}
/* Audio buffer refill */
if ( ( fpga_status_now & 0x4000 ) != ( fpga_status_prev & 0x4000 ) )
{
if ( fpga_status_now & 0x4000 )
{
dac_addr = 0;
}
else
{
dac_addr = MSU_DAC_BUFSIZE / 2;
}
set_dac_addr( dac_addr );
sd_offload_tgt = 1;
ff_sd_offload = 1;
f_read( &file_handle, file_buf, MSU_DAC_BUFSIZE / 2, &msu_audio_bytes_read );
}
if ( fpga_status_now & 0x0020 )
{
/* get trackno */
msu_track = get_msu_track();
DBG_MSU1 printf( "Audio requested! Track=%d\n", msu_track );
prepare_audio_track( msu_track );
}
if ( fpga_status_now & 0x0010 )
{
/* get address */
msu_offset = get_msu_offset();
prepare_data( msu_offset );
}
if ( fpga_status_now & 0x0001 )
{
if ( fpga_status_now & 0x0004 )
{
msu_repeat = 1;
set_msu_status( 0x04, 0x01 ); /* set bit 2, reset bit 0 */
DBG_MSU1 printf( "Repeat set!\n" );
}
else
{
msu_repeat = 0;
set_msu_status( 0x00, 0x05 ); /* set no bits, reset bit 0+2 */
DBG_MSU1 printf( "Repeat clear!\n" );
}
if ( fpga_status_now & 0x0002 )
{
DBG_MSU1 printf( "PLAY!\n" );
set_msu_status( 0x02, 0x01 ); /* set bit 0, reset bit 1 */
dac_play();
}
else
{
DBG_MSU1 printf( "PAUSE!\n" );
set_msu_status( 0x00, 0x03 ); /* set no bits, reset bit 1+0 */
dac_pause();
}
}
fpga_status_prev = fpga_status_now;
/* handle loop / end */
if ( msu_audio_bytes_read < MSU_DAC_BUFSIZE / 2 )
{
ff_sd_offload = 0;
sd_offload = 0;
if ( msu_repeat )
{
DBG_MSU1 printf( "loop\n" );
ff_sd_offload = 1;
sd_offload_tgt = 1;
f_lseek( &file_handle, 8L + msu_loop_point * 4 );
ff_sd_offload = 1;
sd_offload_tgt = 1;
f_read( &file_handle, file_buf, ( MSU_DAC_BUFSIZE / 2 ) - msu_audio_bytes_read, &msu_audio_bytes_read );
}
else
{
set_msu_status( 0x00, 0x02 ); /* clear play bit */
dac_pause();
}
msu_audio_bytes_read = MSU_DAC_BUFSIZE;
}
}
} else if(!resbutton && resbutton_prev) { /* release */
if(getticks() < rising_ticks + 99) {
result = MSU_RESET_SHORT;
}
} else {
result = MSU_RESET_NONE;
}
resbutton_prev = resbutton;
return result;
}
int msu1_check(uint8_t* filename) {
/* open MSU file */
strcpy((char*)file_buf, (char*)filename);
strcpy(strrchr((char*)file_buf, (int)'.'), ".msu");
printf("MSU datafile: %s\n", file_buf);
if(f_open(&msufile, (const TCHAR*)file_buf, FA_READ) != FR_OK) {
printf("MSU datafile not found\n");
f_close( &file_handle );
DBG_MSU1 printf( "Reset " );
if ( msu_res == MSU_RESET_LONG )
{
f_close( &msufile );
DBG_MSU1 printf( "to menu\n" );
return 1;
}
DBG_MSU1 printf( "game\n" );
return 0;
}
msufile.cltbl = msu_cltbl;
msu_cltbl[0] = CLTBL_SIZE;
if(f_lseek(&msufile, CREATE_LINKMAP)) {
printf("Error creating FF linkmap for MSU file!\n");
}
romprops.fpga_features |= FEAT_MSU1;
return 1;
}
int msu1_loop() {
/* it is assumed that the MSU file is already opened by calling msu1_check(). */
while(fpga_status() & 0x4000);
uint16_t dac_addr = 0;
uint16_t msu_addr = 0;
uint8_t msu_repeat = 0;
uint16_t msu_track = 0;
uint32_t msu_offset = 0;
fpga_status_prev = fpga_status();
fpga_status_now = fpga_status();
int msu_res;
/* set_msu_addr(0x0);
msu_reset(0x0);
ff_sd_offload=1;
sd_offload_tgt=2;
f_lseek(&msufile, 0L);
ff_sd_offload=1;
sd_offload_tgt=2;
f_read(&msufile, file_buf, 16384, &msu_data_bytes_read);
*/
set_dac_addr(dac_addr);
dac_pause();
dac_reset();
set_msu_addr(0x0);
msu_reset(0x0);
ff_sd_offload=1;
sd_offload_tgt=2;
f_lseek(&msufile, 0L);
ff_sd_offload=1;
sd_offload_tgt=2;
f_read(&msufile, file_buf, 16384, &msu_data_bytes_read);
prepare_audio_track(0);
prepare_data(0);
/* audio_start, data_start, 0, audio_ctrl[1:0], ctrl_start */
while((msu_res = msu1_check_reset()) == MSU_RESET_NONE){
cli_entrycheck();
fpga_status_now = fpga_status();
/* Data buffer refill */
if((fpga_status_now & 0x2000) != (fpga_status_prev & 0x2000)) {
DBG_MSU1 printf("data\n");
if(fpga_status_now & 0x2000) {
msu_addr = 0x0;
msu_page1_start = msu_page2_start + msu_page_size;
} else {
msu_addr = 0x2000;
msu_page2_start = msu_page1_start + msu_page_size;
}
set_msu_addr(msu_addr);
sd_offload_tgt=2;
ff_sd_offload=1;
msu_res = f_read(&msufile, file_buf, 8192, &msu_data_bytes_read);
DBG_MSU1 printf("data buffer refilled. res=%d page1=%08lx page2=%08lx\n", msu_res, msu_page1_start, msu_page2_start);
}
/* Audio buffer refill */
if((fpga_status_now & 0x4000) != (fpga_status_prev & 0x4000)) {
if(fpga_status_now & 0x4000) {
dac_addr = 0;
} else {
dac_addr = MSU_DAC_BUFSIZE/2;
}
set_dac_addr(dac_addr);
sd_offload_tgt=1;
ff_sd_offload=1;
f_read(&file_handle, file_buf, MSU_DAC_BUFSIZE/2, &msu_audio_bytes_read);
}
if(fpga_status_now & 0x0020) {
/* get trackno */
msu_track = get_msu_track();
DBG_MSU1 printf("Audio requested! Track=%d\n", msu_track);
prepare_audio_track(msu_track);
}
if(fpga_status_now & 0x0010) {
/* get address */
msu_offset=get_msu_offset();
prepare_data(msu_offset);
}
if(fpga_status_now & 0x0001) {
if(fpga_status_now & 0x0004) {
msu_repeat = 1;
set_msu_status(0x04, 0x01); /* set bit 2, reset bit 0 */
DBG_MSU1 printf("Repeat set!\n");
} else {
msu_repeat = 0;
set_msu_status(0x00, 0x05); /* set no bits, reset bit 0+2 */
DBG_MSU1 printf("Repeat clear!\n");
}
if(fpga_status_now & 0x0002) {
DBG_MSU1 printf("PLAY!\n");
set_msu_status(0x02, 0x01); /* set bit 0, reset bit 1 */
dac_play();
} else {
DBG_MSU1 printf("PAUSE!\n");
set_msu_status(0x00, 0x03); /* set no bits, reset bit 1+0 */
dac_pause();
}
}
fpga_status_prev = fpga_status_now;
/* handle loop / end */
if(msu_audio_bytes_read < MSU_DAC_BUFSIZE / 2) {
ff_sd_offload=0;
sd_offload=0;
if(msu_repeat) {
DBG_MSU1 printf("loop\n");
ff_sd_offload=1;
sd_offload_tgt=1;
f_lseek(&file_handle, 8L+msu_loop_point*4);
ff_sd_offload=1;
sd_offload_tgt=1;
f_read(&file_handle, file_buf, (MSU_DAC_BUFSIZE / 2) - msu_audio_bytes_read, &msu_audio_bytes_read);
} else {
set_msu_status(0x00, 0x02); /* clear play bit */
dac_pause();
}
msu_audio_bytes_read = MSU_DAC_BUFSIZE;
}
}
f_close(&file_handle);
DBG_MSU1 printf("Reset ");
if(msu_res == MSU_RESET_LONG) {
f_close(&msufile);
DBG_MSU1 printf("to menu\n");
return 1;
}
DBG_MSU1 printf("game\n");
return 0;
}
/* END OF MSU1 STUFF */

View File

@ -7,9 +7,9 @@
#define DBG_MSU1 while(0)
#endif
#define MSU_DAC_BUFSIZE (2048)
#define MSU_DAC_BUFSIZE (2048)
int msu1_check(uint8_t*);
int msu1_loop(void);
int msu1_check( uint8_t * );
int msu1_loop( void );
#endif

View File

@ -4,9 +4,16 @@
# http://www.hs-augsburg.de/~hhoegl/proj/usbjtag/usbjtag.html
#
interface ft2232
ft2232_vid_pid 0x0403 0x6010
ft2232_device_desc "Dual RS232"
ft2232_layout "oocdlink"
ft2232_latency 2
#interface ft2232
interface ftdi
#ft2232_vid_pid 0x15ba 0x0003
#ft2232_device_desc "Olimex OpenOCD JTAG"
#ft2232_layout "olimex-jtag"
#interface ft2232
#ft2232_vid_pid 0x0403 0x6010
#ft2232_device_desc "Dual RS232"
#ft2232_layout "oocdlink"
#ft2232_latency 2
#adapter_khz 10

View File

@ -15,12 +15,12 @@
* USB [enabled via usb_init]
* PWM1
*/
void power_init() {
LPC_SC->PCONP = BV(PCSSP0)
| BV(PCTIM3)
| BV(PCRTC)
| BV(PCGPIO)
| BV(PCPWM1)
| BV(PCUSB)
;
void power_init()
{
LPC_SC->PCONP = BV( PCSSP0 )
| BV( PCTIM3 )
| BV( PCRTC )
| BV( PCGPIO )
| BV( PCPWM1 )
| BV( PCUSB );
}

View File

@ -5,7 +5,7 @@
#include "bits.h"
#define PCUART0 (3)
#define PCUART0 (3)
#define PCUART1 (4)
#define PCUART2 (24)
#define PCUART3 (25)
@ -38,6 +38,6 @@
#define PCQEI (18)
#define PCGPIO (15)
void power_init(void);
void power_init( void );
#endif

View File

@ -61,231 +61,296 @@ static char *outptr;
static int maxlen;
/* printf */
static void outchar(char x) {
if (maxlen) {
maxlen--;
outfunc(x);
outlength++;
}
static void outchar( char x )
{
if ( maxlen )
{
maxlen--;
outfunc( x );
outlength++;
}
}
/* sprintf */
static void outstr(char x) {
if (maxlen) {
maxlen--;
*outptr++ = x;
outlength++;
}
static void outstr( char x )
{
if ( maxlen )
{
maxlen--;
*outptr++ = x;
outlength++;
}
}
static int internal_nprintf(void (*output_function)(char c), const char *fmt, va_list ap) {
unsigned int width;
unsigned int flags;
unsigned int base = 0;
char *ptr = NULL;
static int internal_nprintf( void ( *output_function )( char c ), const char *fmt, va_list ap )
{
unsigned int width;
unsigned int flags;
unsigned int base = 0;
char *ptr = NULL;
outlength = 0;
outlength = 0;
while (*fmt) {
while (1) {
if (*fmt == 0)
goto end;
while ( *fmt )
{
while ( 1 )
{
if ( *fmt == 0 )
{
goto end;
}
if (*fmt == '%') {
fmt++;
if (*fmt != '%')
break;
}
if ( *fmt == '%' )
{
fmt++;
output_function(*fmt++);
}
if ( *fmt != '%' )
{
break;
}
}
flags = 0;
width = 0;
/* read all flags */
do {
if (flags < FLAG_WIDTH) {
switch (*fmt) {
case '0':
flags |= FLAG_ZEROPAD;
continue;
case '-':
flags |= FLAG_LEFTADJ;
continue;
case ' ':
flags |= FLAG_BLANK;
continue;
case '+':
flags |= FLAG_FORCESIGN;
continue;
}
}
if (flags < FLAG_LONG) {
if (*fmt >= '0' && *fmt <= '9') {
unsigned char tmp = *fmt - '0';
width = 10*width + tmp;
flags |= FLAG_WIDTH;
continue;
output_function( *fmt++ );
}
if (*fmt == 'h')
continue;
flags = 0;
width = 0;
if (*fmt == 'l') {
flags |= FLAG_LONG;
continue;
/* read all flags */
do
{
if ( flags < FLAG_WIDTH )
{
switch ( *fmt )
{
case '0':
flags |= FLAG_ZEROPAD;
continue;
case '-':
flags |= FLAG_LEFTADJ;
continue;
case ' ':
flags |= FLAG_BLANK;
continue;
case '+':
flags |= FLAG_FORCESIGN;
continue;
}
}
if ( flags < FLAG_LONG )
{
if ( *fmt >= '0' && *fmt <= '9' )
{
unsigned char tmp = *fmt - '0';
width = 10 * width + tmp;
flags |= FLAG_WIDTH;
continue;
}
if ( *fmt == 'h' )
{
continue;
}
if ( *fmt == 'l' )
{
flags |= FLAG_LONG;
continue;
}
}
break;
}
}
while ( *fmt++ );
break;
} while (*fmt++);
/* Strings */
if ( *fmt == 'c' || *fmt == 's' )
{
switch ( *fmt )
{
case 'c':
buffer[0] = va_arg( ap, int );
ptr = buffer;
break;
/* Strings */
if (*fmt == 'c' || *fmt == 's') {
switch (*fmt) {
case 'c':
buffer[0] = va_arg(ap, int);
ptr = buffer;
break;
case 's':
ptr = va_arg( ap, char * );
break;
}
case 's':
ptr = va_arg(ap, char *);
break;
}
goto output;
}
goto output;
}
/* Numbers */
switch ( *fmt )
{
case 'u':
flags |= FLAG_UNSIGNED;
/* Numbers */
switch (*fmt) {
case 'u':
flags |= FLAG_UNSIGNED;
case 'd':
base = 10;
break;
case 'd':
base = 10;
break;
case 'o':
base = 8;
flags |= FLAG_UNSIGNED;
break;
case 'o':
base = 8;
flags |= FLAG_UNSIGNED;
break;
case 'p': // pointer
output_function('0');
output_function('x');
width -= 2;
case 'x':
case 'X':
base = 16;
flags |= FLAG_UNSIGNED;
break;
}
case 'p': // pointer
output_function( '0' );
output_function( 'x' );
width -= 2;
unsigned int num;
case 'x':
case 'X':
base = 16;
flags |= FLAG_UNSIGNED;
break;
}
if (!(flags & FLAG_UNSIGNED)) {
int tmp = va_arg(ap, int);
if (tmp < 0) {
num = -tmp;
flags |= FLAG_NEGATIVE;
} else
num = tmp;
} else {
num = va_arg(ap, unsigned int);
}
unsigned int num;
/* Convert number into buffer */
ptr = buffer + sizeof(buffer);
*--ptr = 0;
do {
*--ptr = hexdigits[num % base];
num /= base;
} while (num != 0);
if ( !( flags & FLAG_UNSIGNED ) )
{
int tmp = va_arg( ap, int );
/* Sign */
if (flags & FLAG_NEGATIVE) {
output_function('-');
width--;
} else if (flags & FLAG_FORCESIGN) {
output_function('+');
width--;
} else if (flags & FLAG_BLANK) {
output_function(' ');
width--;
}
output:
/* left padding */
if ((flags & FLAG_WIDTH) && !(flags & FLAG_LEFTADJ)) {
while (strlen(ptr) < width) {
if (flags & FLAG_ZEROPAD)
output_function('0');
if ( tmp < 0 )
{
num = -tmp;
flags |= FLAG_NEGATIVE;
}
else
{
num = tmp;
}
}
else
output_function(' ');
width--;
}
{
num = va_arg( ap, unsigned int );
}
/* Convert number into buffer */
ptr = buffer + sizeof( buffer );
*--ptr = 0;
do
{
*--ptr = hexdigits[num % base];
num /= base;
}
while ( num != 0 );
/* Sign */
if ( flags & FLAG_NEGATIVE )
{
output_function( '-' );
width--;
}
else if ( flags & FLAG_FORCESIGN )
{
output_function( '+' );
width--;
}
else if ( flags & FLAG_BLANK )
{
output_function( ' ' );
width--;
}
output:
/* left padding */
if ( ( flags & FLAG_WIDTH ) && !( flags & FLAG_LEFTADJ ) )
{
while ( strlen( ptr ) < width )
{
if ( flags & FLAG_ZEROPAD )
{
output_function( '0' );
}
else
{
output_function( ' ' );
}
width--;
}
}
/* data */
while ( *ptr )
{
output_function( *ptr++ );
if ( width )
{
width--;
}
}
/* right padding */
if ( flags & FLAG_WIDTH )
{
while ( width )
{
output_function( ' ' );
width--;
}
}
fmt++;
}
/* data */
while (*ptr) {
output_function(*ptr++);
if (width)
width--;
}
/* right padding */
if (flags & FLAG_WIDTH) {
while (width) {
output_function(' ');
width--;
}
}
fmt++;
}
end:
return outlength;
end:
return outlength;
}
int printf(const char *format, ...) {
va_list ap;
int res;
int printf( const char *format, ... )
{
va_list ap;
int res;
maxlen = -1;
va_start(ap, format);
res = internal_nprintf(outchar, format, ap);
va_end(ap);
return res;
maxlen = -1;
va_start( ap, format );
res = internal_nprintf( outchar, format, ap );
va_end( ap );
return res;
}
int snprintf(char *str, size_t size, const char *format, ...) {
va_list ap;
int res;
int snprintf( char *str, size_t size, const char *format, ... )
{
va_list ap;
int res;
maxlen = size;
outptr = str;
va_start(ap, format);
res = internal_nprintf(outstr, format, ap);
va_end(ap);
if (res < size)
str[res] = 0;
return res;
maxlen = size;
outptr = str;
va_start( ap, format );
res = internal_nprintf( outstr, format, ap );
va_end( ap );
if ( res < size )
{
str[res] = 0;
}
return res;
}
/* Required for gcc compatibility */
int puts(const char *str) {
uart_puts(str);
uart_putc('\n');
return 0;
int puts( const char *str )
{
uart_puts( str );
uart_putc( '\n' );
return 0;
}
#undef putchar
int putchar(int c) {
uart_putc(c);
return 0;
int putchar( int c )
{
uart_putc( c );
return 0;
}

131
src/rle.c
View File

@ -2,65 +2,92 @@
#include "rle.h"
#include "fileops.h"
uint8_t rle_file_getc() {
static uint16_t rle_filled = 0;
static uint8_t data;
if(!rle_filled) {
data = file_getc();
switch(data) {
case RLE_RUN:
uint8_t rle_file_getc()
{
static uint16_t rle_filled = 0;
static uint8_t data;
if ( !rle_filled )
{
data = file_getc();
rle_filled = file_getc()-1;
break;
case RLE_RUNLONG:
data = file_getc();
rle_filled = file_getc();
rle_filled |= file_getc() << 8;
switch ( data )
{
case RLE_RUN:
data = file_getc();
rle_filled = file_getc() - 1;
break;
case RLE_RUNLONG:
data = file_getc();
rle_filled = file_getc();
rle_filled |= file_getc() << 8;
rle_filled--;
break;
case RLE_ESC:
data = file_getc();
break;
}
}
else
{
rle_filled--;
break;
case RLE_ESC:
data = file_getc();
break;
}
} else {
rle_filled--;
}
if(file_status || file_res) rle_filled = 0;
return data;
if ( file_status || file_res )
{
rle_filled = 0;
}
return data;
}
void rle_mem_init(const uint8_t* address, uint32_t len) {
rle_mem_ptr = address;
rle_mem_endptr = address+len;
rle_state = 0;
void rle_mem_init( const uint8_t *address, uint32_t len )
{
rle_mem_ptr = address;
rle_mem_endptr = address + len;
rle_state = 0;
}
uint8_t rle_mem_getc() {
static uint16_t rle_mem_filled = 0;
static uint8_t rle_mem_data;
if(!rle_mem_filled) {
rle_mem_data = *(rle_mem_ptr++);
switch(rle_mem_data) {
case RLE_RUN:
rle_mem_data = *(rle_mem_ptr)++;
rle_mem_filled = *(rle_mem_ptr)++ - 1;
break;
case RLE_RUNLONG:
rle_mem_data = *(rle_mem_ptr)++;
rle_mem_filled = *(rle_mem_ptr)++;
rle_mem_filled |= *(rle_mem_ptr)++ << 8;
uint8_t rle_mem_getc()
{
static uint16_t rle_mem_filled = 0;
static uint8_t rle_mem_data;
if ( !rle_mem_filled )
{
rle_mem_data = *( rle_mem_ptr++ );
switch ( rle_mem_data )
{
case RLE_RUN:
rle_mem_data = *( rle_mem_ptr )++;
rle_mem_filled = *( rle_mem_ptr )++ - 1;
break;
case RLE_RUNLONG:
rle_mem_data = *( rle_mem_ptr )++;
rle_mem_filled = *( rle_mem_ptr )++;
rle_mem_filled |= *( rle_mem_ptr )++ << 8;
rle_mem_filled--;
break;
case RLE_ESC:
rle_mem_data = *( rle_mem_ptr )++;
break;
}
}
else
{
rle_mem_filled--;
break;
case RLE_ESC:
rle_mem_data = *(rle_mem_ptr)++;
break;
}
} else {
rle_mem_filled--;
}
if(rle_mem_ptr>=rle_mem_endptr){
rle_mem_filled = 0;
rle_state = 1;
}
return rle_mem_data;
if ( rle_mem_ptr >= rle_mem_endptr )
{
rle_mem_filled = 0;
rle_state = 1;
}
return rle_mem_data;
}

View File

@ -7,9 +7,9 @@
#define RLE_RUN (0x5b)
#define RLE_RUNLONG (0x77)
uint8_t rle_file_getc(void);
uint8_t rle_mem_getc(void);
void rle_mem_init(const uint8_t *address, uint32_t len);
uint8_t rle_file_getc( void );
uint8_t rle_mem_getc( void );
void rle_mem_init( const uint8_t *address, uint32_t len );
const uint8_t *rle_mem_ptr;
const uint8_t *rle_mem_endptr;
uint8_t rle_state;

220
src/rtc.c
View File

@ -11,125 +11,149 @@ rtcstate_t rtc_state;
#define CLKEN 0
#define CTCRST 1
uint8_t rtc_isvalid(void) {
if(LPC_RTC->GPREG0 == RTC_MAGIC) {
return RTC_OK;
}
return RTC_INVALID;
uint8_t rtc_isvalid( void )
{
if ( LPC_RTC->GPREG0 == RTC_MAGIC )
{
return RTC_OK;
}
return RTC_INVALID;
}
void rtc_init(void) {
if (LPC_RTC->CCR & BV(CLKEN)) {
rtc_state = RTC_OK;
} else {
rtc_state = RTC_INVALID;
}
void rtc_init( void )
{
if ( LPC_RTC->CCR & BV( CLKEN ) )
{
rtc_state = RTC_OK;
}
else
{
rtc_state = RTC_INVALID;
}
}
void read_rtc(struct tm *time) {
do {
time->tm_sec = LPC_RTC->SEC;
time->tm_min = LPC_RTC->MIN;
time->tm_hour = LPC_RTC->HOUR;
time->tm_mday = LPC_RTC->DOM;
time->tm_mon = LPC_RTC->MONTH;
time->tm_year = LPC_RTC->YEAR;
time->tm_wday = LPC_RTC->DOW;
} while (time->tm_sec != LPC_RTC->SEC);
void read_rtc( struct tm *time )
{
do
{
time->tm_sec = LPC_RTC->SEC;
time->tm_min = LPC_RTC->MIN;
time->tm_hour = LPC_RTC->HOUR;
time->tm_mday = LPC_RTC->DOM;
time->tm_mon = LPC_RTC->MONTH;
time->tm_year = LPC_RTC->YEAR;
time->tm_wday = LPC_RTC->DOW;
}
while ( time->tm_sec != LPC_RTC->SEC );
}
uint8_t calc_weekday(struct tm *time) {
int month = time->tm_mon;
int year = time->tm_year;
int day = time->tm_mday;
uint8_t calc_weekday( struct tm *time )
{
int month = time->tm_mon;
int year = time->tm_year;
int day = time->tm_mday;
/* Variation of Sillke for the Gregorian calendar.
* http://www.mathematik.uni-bielefeld.de/~sillke/ALGORITHMS/calendar/weekday.c */
if (month <= 2) {
month += 10;
year--;
} else month -= 2;
return (83*month/32 + day + year + year/4 - year/100 + year/400) % 7;
/* Variation of Sillke for the Gregorian calendar.
* http://www.mathematik.uni-bielefeld.de/~sillke/ALGORITHMS/calendar/weekday.c */
if ( month <= 2 )
{
month += 10;
year--;
}
else
{
month -= 2;
}
return ( 83 * month / 32 + day + year + year / 4 - year / 100 + year / 400 ) % 7;
}
void set_rtc(struct tm *time) {
LPC_RTC->CCR = BV(CTCRST);
LPC_RTC->SEC = time->tm_sec;
LPC_RTC->MIN = time->tm_min;
LPC_RTC->HOUR = time->tm_hour;
LPC_RTC->DOM = time->tm_mday;
LPC_RTC->MONTH = time->tm_mon;
LPC_RTC->YEAR = time->tm_year;
LPC_RTC->DOW = calc_weekday(time);
LPC_RTC->CCR = BV(CLKEN);
LPC_RTC->GPREG0 = RTC_MAGIC;
void set_rtc( struct tm *time )
{
LPC_RTC->CCR = BV( CTCRST );
LPC_RTC->SEC = time->tm_sec;
LPC_RTC->MIN = time->tm_min;
LPC_RTC->HOUR = time->tm_hour;
LPC_RTC->DOM = time->tm_mday;
LPC_RTC->MONTH = time->tm_mon;
LPC_RTC->YEAR = time->tm_year;
LPC_RTC->DOW = calc_weekday( time );
LPC_RTC->CCR = BV( CLKEN );
LPC_RTC->GPREG0 = RTC_MAGIC;
}
void invalidate_rtc() {
LPC_RTC->GPREG0 = 0;
void invalidate_rtc()
{
LPC_RTC->GPREG0 = 0;
}
uint32_t get_fattime(void) {
struct tm time;
uint32_t get_fattime( void )
{
struct tm time;
read_rtc(&time);
return ((uint32_t)time.tm_year-1980) << 25 |
((uint32_t)time.tm_mon) << 21 |
((uint32_t)time.tm_mday) << 16 |
((uint32_t)time.tm_hour) << 11 |
((uint32_t)time.tm_min) << 5 |
((uint32_t)time.tm_sec) >> 1;
read_rtc( &time );
return ( ( uint32_t )time.tm_year - 1980 ) << 25 |
( ( uint32_t )time.tm_mon ) << 21 |
( ( uint32_t )time.tm_mday ) << 16 |
( ( uint32_t )time.tm_hour ) << 11 |
( ( uint32_t )time.tm_min ) << 5 |
( ( uint32_t )time.tm_sec ) >> 1;
}
uint64_t get_bcdtime(void) {
struct tm time;
read_rtc(&time);
uint16_t year = time.tm_year;
uint64_t get_bcdtime( void )
{
struct tm time;
read_rtc( &time );
uint16_t year = time.tm_year;
return ((uint64_t)(time.tm_wday % 7) << 56)
|((uint64_t)((year / 1000) % 10) << 52)
|((uint64_t)((year / 100) % 10) << 48)
|((uint64_t)((year / 10) % 10) << 44)
|((uint64_t)(year % 10) << 40)
|((uint64_t)(time.tm_mon / 10) << 36)
|((uint64_t)(time.tm_mon % 10) << 32)
|((time.tm_mday / 10) << 28)
|((time.tm_mday % 10) << 24)
|((time.tm_hour / 10) << 20)
|((time.tm_hour % 10) << 16)
|((time.tm_min / 10) << 12)
|((time.tm_min % 10) << 8)
|((time.tm_sec / 10) << 4)
|(time.tm_sec % 10);
return ( ( uint64_t )( time.tm_wday % 7 ) << 56 )
| ( ( uint64_t )( ( year / 1000 ) % 10 ) << 52 )
| ( ( uint64_t )( ( year / 100 ) % 10 ) << 48 )
| ( ( uint64_t )( ( year / 10 ) % 10 ) << 44 )
| ( ( uint64_t )( year % 10 ) << 40 )
| ( ( uint64_t )( time.tm_mon / 10 ) << 36 )
| ( ( uint64_t )( time.tm_mon % 10 ) << 32 )
| ( ( time.tm_mday / 10 ) << 28 )
| ( ( time.tm_mday % 10 ) << 24 )
| ( ( time.tm_hour / 10 ) << 20 )
| ( ( time.tm_hour % 10 ) << 16 )
| ( ( time.tm_min / 10 ) << 12 )
| ( ( time.tm_min % 10 ) << 8 )
| ( ( time.tm_sec / 10 ) << 4 )
| ( time.tm_sec % 10 );
}
void set_bcdtime(uint64_t btime) {
struct tm time;
time.tm_sec = (btime & 0xf) + ((btime >> 4) & 0xf) * 10;
time.tm_min = ((btime >> 8) & 0xf) + ((btime >> 12) & 0xf) * 10;
time.tm_hour = ((btime >> 16) & 0xf) + ((btime >> 20) & 0xf) * 10;
time.tm_mday = ((btime >> 24) & 0xf) + ((btime >> 28) & 0xf) * 10;
time.tm_mon = ((btime >> 32) & 0xf) + ((btime >> 36) & 0xf) * 10;
time.tm_year = ((btime >> 40) & 0xf) + ((btime >> 44) & 0xf) * 10
+ ((btime >> 48) & 0xf) * 100 + ((btime >> 52) & 0xf) * 1000;
printtime(&time);
set_rtc(&time);
void set_bcdtime( uint64_t btime )
{
struct tm time;
time.tm_sec = ( btime & 0xf ) + ( ( btime >> 4 ) & 0xf ) * 10;
time.tm_min = ( ( btime >> 8 ) & 0xf ) + ( ( btime >> 12 ) & 0xf ) * 10;
time.tm_hour = ( ( btime >> 16 ) & 0xf ) + ( ( btime >> 20 ) & 0xf ) * 10;
time.tm_mday = ( ( btime >> 24 ) & 0xf ) + ( ( btime >> 28 ) & 0xf ) * 10;
time.tm_mon = ( ( btime >> 32 ) & 0xf ) + ( ( btime >> 36 ) & 0xf ) * 10;
time.tm_year = ( ( btime >> 40 ) & 0xf ) + ( ( btime >> 44 ) & 0xf ) * 10
+ ( ( btime >> 48 ) & 0xf ) * 100 + ( ( btime >> 52 ) & 0xf ) * 1000;
printtime( &time );
set_rtc( &time );
}
void printtime(struct tm *time) {
printf("%04d-%02d-%02d %02d:%02d:%02d\n", time->tm_year, time->tm_mon,
time->tm_mday, time->tm_hour, time->tm_min, time->tm_sec);
void printtime( struct tm *time )
{
printf( "%04d-%02d-%02d %02d:%02d:%02d\n", time->tm_year, time->tm_mon,
time->tm_mday, time->tm_hour, time->tm_min, time->tm_sec );
}
void testbattery() {
printf("%lx\n", LPC_RTC->GPREG0);
LPC_RTC->GPREG0 = RTC_MAGIC;
printf("%lx\n", LPC_RTC->GPREG0);
LPC_RTC->CCR = 0;
BITBAND(LPC_SC->PCONP, PCRTC) = 0;
delay_ms(20000);
BITBAND(LPC_SC->PCONP, PCRTC) = 1;
printf("%lx\n", LPC_RTC->GPREG0);
delay_ms(20);
LPC_RTC->CCR = BV(CLKEN);
void testbattery()
{
printf( "%lx\n", LPC_RTC->GPREG0 );
LPC_RTC->GPREG0 = RTC_MAGIC;
printf( "%lx\n", LPC_RTC->GPREG0 );
LPC_RTC->CCR = 0;
BITBAND( LPC_SC->PCONP, PCRTC ) = 0;
delay_ms( 20000 );
BITBAND( LPC_SC->PCONP, PCRTC ) = 1;
printf( "%lx\n", LPC_RTC->GPREG0 );
delay_ms( 20 );
LPC_RTC->CCR = BV( CLKEN );
}

View File

@ -29,50 +29,52 @@
#include <stdint.h>
typedef enum {
RTC_NOT_FOUND, /* No RTC present */
RTC_INVALID, /* RTC present, but contents invalid */
RTC_OK /* RTC present and working */
typedef enum
{
RTC_NOT_FOUND, /* No RTC present */
RTC_INVALID, /* RTC present, but contents invalid */
RTC_OK /* RTC present and working */
} rtcstate_t;
struct tm {
uint8_t tm_sec; // 0..59
uint8_t tm_min; // 0..59
uint8_t tm_hour; // 0..23
uint8_t tm_mday; // 1..[28..31]
uint8_t tm_mon; // 0..11
uint16_t tm_year; // since 0 A.D.
uint8_t tm_wday; // 0 to 6, sunday is 6
// A Unix struct tm has a few more fields we don't need in this application
struct tm
{
uint8_t tm_sec; // 0..59
uint8_t tm_min; // 0..59
uint8_t tm_hour; // 0..23
uint8_t tm_mday; // 1..[28..31]
uint8_t tm_mon; // 0..11
uint16_t tm_year; // since 0 A.D.
uint8_t tm_wday; // 0 to 6, sunday is 6
// A Unix struct tm has a few more fields we don't need in this application
};
#define RTC_MAGIC (0x43545253L)
extern rtcstate_t rtc_state;
void rtc_init(void);
void rtc_init( void );
/* return RTC valid state based on magic token in backup register */
uint8_t rtc_isvalid(void);
uint8_t rtc_isvalid( void );
/* Return current time in struct tm */
void read_rtc(struct tm *time);
void read_rtc( struct tm *time );
/* Set time from struct tm, also sets RTC valid */
void set_rtc(struct tm *time);
void set_rtc( struct tm *time );
/* Set RTC invalid */
void invalidate_rtc(void);
void invalidate_rtc( void );
/* get current time in 60-bit BCD format (WYYYYMMDDHHMMSS) (W=DOW) */
uint64_t get_bcdtime(void);
uint64_t get_bcdtime( void );
/* set current time from 56-bit BCD format (YYYYMMDDHHMMSS)
DOW is calculated */
void set_bcdtime(uint64_t btime);
void set_bcdtime( uint64_t btime );
/* print the time to the console */
void printtime(struct tm *time);
void printtime( struct tm *time );
void testbattery(void);
void testbattery( void );
#endif

File diff suppressed because it is too large Load Diff

View File

@ -16,16 +16,16 @@
extern int sd_offload;
/* These functions are weak-aliased to disk_... */
void sdn_init(void);
DSTATUS sdn_status(BYTE drv);
DSTATUS sdn_initialize(BYTE drv);
DRESULT sdn_read(BYTE drv, BYTE *buffer, DWORD sector, BYTE count);
DRESULT sdn_write(BYTE drv, const BYTE *buffer, DWORD sector, BYTE count);
DRESULT sdn_getinfo(BYTE drv, BYTE page, void *buffer);
DRESULT sdn_ioctl(BYTE drv, BYTE cmd, void *buffer);
void sdn_init( void );
DSTATUS sdn_status( BYTE drv );
DSTATUS sdn_initialize( BYTE drv );
DRESULT sdn_read( BYTE drv, BYTE *buffer, DWORD sector, BYTE count );
DRESULT sdn_write( BYTE drv, const BYTE *buffer, DWORD sector, BYTE count );
DRESULT sdn_getinfo( BYTE drv, BYTE page, void *buffer );
DRESULT sdn_ioctl( BYTE drv, BYTE cmd, void *buffer );
void sdn_changed(void);
uint8_t* sdn_getcid(void);
void sdn_gettacc(uint32_t *tacc_max, uint32_t *tacc_avg);
void sdn_changed( void );
uint8_t *sdn_getcid( void );
void sdn_gettacc( uint32_t *tacc_max, uint32_t *tacc_avg );
#endif

511
src/smc.c
View File

@ -35,228 +35,333 @@ snes_romprops_t romprops;
uint32_t hdr_addr[6] = {0xffb0, 0x101b0, 0x7fb0, 0x81b0, 0x40ffb0, 0x4101b0};
uint8_t isFixed(uint8_t* data, int size, uint8_t value) {
uint8_t res = 1;
do {
size--;
if(data[size] != value) {
res = 0;
}
} while (size);
return res;
}
uint8_t isFixed( uint8_t *data, int size, uint8_t value )
{
uint8_t res = 1;
uint8_t checkChksum(uint16_t cchk, uint16_t chk) {
uint32_t sum = cchk + chk;
uint8_t res = 0;
if(sum==0x0000ffff) {
res = 1;
}
return res;
}
do
{
size--;
void smc_id(snes_romprops_t* props) {
uint8_t score, maxscore=1, score_idx=2; /* assume LoROM */
snes_header_t* header = &(props->header);
props->load_address = 0;
props->has_dspx = 0;
props->has_st0010 = 0;
props->has_cx4 = 0;
props->fpga_features = 0;
props->fpga_conf = NULL;
for(uint8_t num = 0; num < 6; num++) {
score = smc_headerscore(hdr_addr[num], header);
printf("%d: offset = %lX; score = %d\n", num, hdr_addr[num], score); // */
if(score>=maxscore) {
score_idx=num;
maxscore=score;
}
}
if(score_idx & 1) {
props->offset = 0x200;
} else {
props->offset = 0;
}
/* restore the chosen one */
/*dprintf("winner is %d\n", score_idx); */
file_readblock(header, hdr_addr[score_idx], sizeof(snes_header_t));
if(header->name[0x13] == 0x00 || header->name[0x13] == 0xff) {
if(header->name[0x14] == 0x00) {
const uint8_t n15 = header->map;
if(n15 == 0x00 || n15 == 0x80 || n15 == 0x84 || n15 == 0x9c
|| n15 == 0xbc || n15 == 0xfc) {
if(header->licensee == 0x33 || header->licensee == 0xff) {
props->mapper_id = 0;
/*XXX do this properly */
props->ramsize_bytes = 0x8000;
props->romsize_bytes = 0x100000;
props->expramsize_bytes = 0;
props->mapper_id = 3; /* BS-X Memory Map */
props->region = 0; /* BS-X only existed in Japan */
uint8_t alloc = header->name[0x10];
if(alloc) {
while(!(alloc & 0x01)) {
props->load_address += 0x20000;
alloc >>= 1;
}
}
printf("load address: %lx\n", props->load_address);
return;
if ( data[size] != value )
{
res = 0;
}
}
}
}
switch(header->map & 0xef) {
while ( size );
return res;
}
uint8_t checkChksum( uint16_t cchk, uint16_t chk )
{
uint32_t sum = cchk + chk;
uint8_t res = 0;
if ( sum == 0x0000ffff )
{
res = 1;
}
return res;
}
void smc_id( snes_romprops_t *props )
{
uint8_t score, maxscore = 1, score_idx = 2; /* assume LoROM */
snes_header_t *header = &( props->header );
props->has_dspx = 0;
props->has_st0010 = 0;
props->has_cx4 = 0;
props->fpga_features = 0;
props->fpga_conf = NULL;
for ( uint8_t num = 0; num < 6; num++ )
{
score = smc_headerscore( hdr_addr[num], header );
printf( "%d: offset = %lX; score = %d\n", num, hdr_addr[num], score ); // */
if ( score >= maxscore )
{
score_idx = num;
maxscore = score;
}
}
if ( score_idx & 1 )
{
props->offset = 0x200;
}
else
{
props->offset = 0;
}
/* restore the chosen one */
/*dprintf("winner is %d\n", score_idx); */
file_readblock( header, hdr_addr[score_idx], sizeof( snes_header_t ) );
if ( header->name[0x13] == 0x00 || header->name[0x13] == 0xff )
{
if ( header->name[0x14] == 0x00 )
{
const uint8_t n15 = header->map;
if ( n15 == 0x00 || n15 == 0x80 || n15 == 0x84 || n15 == 0x9c
|| n15 == 0xbc || n15 == 0xfc )
{
if ( header->licensee == 0x33 || header->licensee == 0xff )
{
props->mapper_id = 0;
/*XXX do this properly */
props->ramsize_bytes = 0x8000;
props->romsize_bytes = 0x100000;
props->expramsize_bytes = 0;
props->mapper_id = 3; /* BS-X Memory Map */
props->region = 0; /* BS-X only existed in Japan */
return;
}
}
}
}
switch ( header->map & 0xef )
{
case 0x21: /* HiROM */
props->mapper_id = 0;
if(header->map == 0x31 && (header->carttype == 0x03 || header->carttype == 0x05)) {
props->has_dspx = 1;
props->dsp_fw = DSPFW_1B;
props->fpga_features |= FEAT_DSPX;
}
break;
props->mapper_id = 0;
if ( header->map == 0x31 && ( header->carttype == 0x03 || header->carttype == 0x05 ) )
{
props->has_dspx = 1;
props->dsp_fw = DSPFW_1B;
props->fpga_features |= FEAT_DSPX;
}
break;
case 0x20: /* LoROM */
props->mapper_id = 1;
if (header->map == 0x20 && header->carttype == 0xf3) {
props->has_cx4 = 1;
props->dsp_fw = CX4FW;
props->fpga_conf = FPGA_CX4;
props->fpga_features |= FEAT_CX4;
}
else if ((header->map == 0x20 && header->carttype == 0x03) ||
(header->map == 0x30 && header->carttype == 0x05 && header->licensee != 0xb2)) {
props->has_dspx = 1;
props->fpga_features |= FEAT_DSPX;
/* Pilotwings uses DSP1 instead of DSP1B */
if(!memcmp(header->name, "PILOTWINGS", 10)) {
props->dsp_fw = DSPFW_1;
} else {
props->dsp_fw = DSPFW_1B;
props->mapper_id = 1;
if ( header->map == 0x20 && header->carttype == 0xf3 )
{
props->has_cx4 = 1;
props->dsp_fw = CX4FW;
props->fpga_conf = FPGA_CX4;
props->fpga_features |= FEAT_CX4;
}
} else if (header->map == 0x20 && header->carttype == 0x05) {
props->has_dspx = 1;
props->dsp_fw = DSPFW_2;
props->fpga_features |= FEAT_DSPX;
} else if (header->map == 0x30 && header->carttype == 0x05 && header->licensee == 0xb2) {
props->has_dspx = 1;
props->dsp_fw = DSPFW_3;
props->fpga_features |= FEAT_DSPX;
} else if (header->map == 0x30 && header->carttype == 0x03) {
props->has_dspx = 1;
props->dsp_fw = DSPFW_4;
props->fpga_features |= FEAT_DSPX;
} else if (header->map == 0x30 && header->carttype == 0xf6 && header->romsize >= 0xa) {
props->has_dspx = 1;
props->has_st0010 = 1;
props->dsp_fw = DSPFW_ST0010;
props->fpga_features |= FEAT_ST0010;
header->ramsize = 2;
}
break;
else if ( ( header->map == 0x20 && header->carttype == 0x03 ) ||
( header->map == 0x30 && header->carttype == 0x05 && header->licensee != 0xb2 ) )
{
props->has_dspx = 1;
props->fpga_features |= FEAT_DSPX;
/* Pilotwings uses DSP1 instead of DSP1B */
if ( !memcmp( header->name, "PILOTWINGS", 10 ) )
{
props->dsp_fw = DSPFW_1;
}
else
{
props->dsp_fw = DSPFW_1B;
}
}
else if ( header->map == 0x20 && header->carttype == 0x05 )
{
props->has_dspx = 1;
props->dsp_fw = DSPFW_2;
props->fpga_features |= FEAT_DSPX;
}
else if ( header->map == 0x30 && header->carttype == 0x05 && header->licensee == 0xb2 )
{
props->has_dspx = 1;
props->dsp_fw = DSPFW_3;
props->fpga_features |= FEAT_DSPX;
}
else if ( header->map == 0x30 && header->carttype == 0x03 )
{
props->has_dspx = 1;
props->dsp_fw = DSPFW_4;
props->fpga_features |= FEAT_DSPX;
}
else if ( header->map == 0x30 && header->carttype == 0xf6 && header->romsize >= 0xa )
{
props->has_dspx = 1;
props->has_st0010 = 1;
props->dsp_fw = DSPFW_ST0010;
props->fpga_features |= FEAT_ST0010;
header->ramsize = 2;
}
break;
case 0x25: /* ExHiROM */
props->mapper_id = 2;
break;
props->mapper_id = 2;
break;
case 0x22: /* ExLoROM */
if(file_handle.fsize > 0x400200) {
props->mapper_id = 6; /* SO96 */
} else {
props->mapper_id = 1;
}
break;
if ( file_handle.fsize > 0x400200 )
{
props->mapper_id = 6; /* SO96 */
}
else
{
props->mapper_id = 1;
}
break;
default: /* invalid/unsupported mapper, use header location */
switch(score_idx) {
switch ( score_idx )
{
case 0:
case 1:
props->mapper_id = 0;
break;
props->mapper_id = 0;
break;
case 2:
case 3:
if(file_handle.fsize > 0x800200) {
props->mapper_id = 6; /* SO96 interleaved */
} else if(file_handle.fsize > 0x400200) {
props->mapper_id = 1; /* ExLoROM */
} else {
props->mapper_id = 1; /* LoROM */
}
break;
if ( file_handle.fsize > 0x800200 )
{
props->mapper_id = 6; /* SO96 interleaved */
}
else if ( file_handle.fsize > 0x400200 )
{
props->mapper_id = 1; /* ExLoROM */
}
else
{
props->mapper_id = 1; /* LoROM */
}
break;
case 4:
case 5:
props->mapper_id = 2;
break;
default:
props->mapper_id = 1; // whatever
}
}
if(header->romsize == 0 || header->romsize > 13) {
props->romsize_bytes = 1024;
header->romsize = 0;
if(file_handle.fsize >= 1024) {
while(props->romsize_bytes < file_handle.fsize-1) {
header->romsize++;
props->romsize_bytes <<= 1;
}
}
}
props->ramsize_bytes = (uint32_t)1024 << header->ramsize;
props->romsize_bytes = (uint32_t)1024 << header->romsize;
props->expramsize_bytes = (uint32_t)1024 << header->expramsize;
/*dprintf("ramsize_bytes: %ld\n", props->ramsize_bytes); */
if(props->ramsize_bytes < 2048) {
props->ramsize_bytes = 0;
}
props->region = (header->destcode <= 1 || header->destcode >= 13) ? 0 : 1;
props->mapper_id = 2;
break;
/*dprintf("ramsize_bytes: %ld\n", props->ramsize_bytes); */
default:
props->mapper_id = 1; // whatever
}
}
if ( header->romsize == 0 || header->romsize > 13 )
{
props->romsize_bytes = 1024;
header->romsize = 0;
if ( file_handle.fsize >= 1024 )
{
while ( props->romsize_bytes < file_handle.fsize - 1 )
{
header->romsize++;
props->romsize_bytes <<= 1;
}
}
}
props->ramsize_bytes = ( uint32_t )1024 << header->ramsize;
props->romsize_bytes = ( uint32_t )1024 << header->romsize;
props->expramsize_bytes = ( uint32_t )1024 << header->expramsize;
//dprintf("ramsize_bytes: %ld\n", props->ramsize_bytes);
if ( props->ramsize_bytes > 32768 || props->ramsize_bytes < 2048 )
{
props->ramsize_bytes = 0;
}
props->region = ( header->destcode <= 1 || header->destcode >= 13 ) ? 0 : 1;
/*dprintf("ramsize_bytes: %ld\n", props->ramsize_bytes); */
}
uint8_t smc_headerscore(uint32_t addr, snes_header_t* header) {
int score=0;
uint8_t reset_inst;
uint16_t header_offset;
if((addr & 0xfff) == 0x1b0) {
header_offset = 0x200;
} else {
header_offset = 0;
}
if((file_readblock(header, addr, sizeof(snes_header_t)) < sizeof(snes_header_t))
|| file_res) {
return 0;
}
uint8_t mapper = header->map & ~0x10;
uint16_t resetvector = header->vect_reset; /* not endian safe! */
uint32_t file_addr = (((addr - header_offset) & ~0x7fff) | (resetvector & 0x7fff)) + header_offset;
if(resetvector < 0x8000) return 0;
uint8_t smc_headerscore( uint32_t addr, snes_header_t *header )
{
int score = 0;
uint8_t reset_inst;
uint16_t header_offset;
score += 2*isFixed(&header->licensee, sizeof(header->licensee), 0x33);
score += 4*checkChksum(header->cchk, header->chk);
if(header->carttype < 0x08) score++;
if(header->romsize < 0x10) score++;
if(header->ramsize < 0x08) score++;
if(header->destcode < 0x0e) score++;
if ( ( addr & 0xfff ) == 0x1b0 )
{
header_offset = 0x200;
}
else
{
header_offset = 0;
}
if((addr-header_offset) == 0x007fc0 && mapper == 0x20) score += 2;
if((addr-header_offset) == 0x00ffc0 && mapper == 0x21) score += 2;
if((addr-header_offset) == 0x007fc0 && mapper == 0x22) score += 2;
if((addr-header_offset) == 0x40ffc0 && mapper == 0x25) score += 2;
if ( ( file_readblock( header, addr, sizeof( snes_header_t ) ) < sizeof( snes_header_t ) )
|| file_res )
{
return 0;
}
file_readblock(&reset_inst, file_addr, 1);
switch(reset_inst) {
uint8_t mapper = header->map & ~0x10;
uint16_t resetvector = header->vect_reset; /* not endian safe! */
uint32_t file_addr = ( ( ( addr - header_offset ) & ~0x7fff ) | ( resetvector & 0x7fff ) ) + header_offset;
if ( resetvector < 0x8000 )
{
return 0;
}
score += 2 * isFixed( &header->licensee, sizeof( header->licensee ), 0x33 );
score += 4 * checkChksum( header->cchk, header->chk );
if ( header->carttype < 0x08 )
{
score++;
}
if ( header->romsize < 0x10 )
{
score++;
}
if ( header->ramsize < 0x08 )
{
score++;
}
if ( header->destcode < 0x0e )
{
score++;
}
if ( ( addr - header_offset ) == 0x007fc0 && mapper == 0x20 )
{
score += 2;
}
if ( ( addr - header_offset ) == 0x00ffc0 && mapper == 0x21 )
{
score += 2;
}
if ( ( addr - header_offset ) == 0x007fc0 && mapper == 0x22 )
{
score += 2;
}
if ( ( addr - header_offset ) == 0x40ffc0 && mapper == 0x25 )
{
score += 2;
}
file_readblock( &reset_inst, file_addr, 1 );
switch ( reset_inst )
{
case 0x78: /* sei */
case 0x18: /* clc */
case 0x38: /* sec */
case 0x9c: /* stz abs */
case 0x4c: /* jmp abs */
case 0x5c: /* jml abs */
score += 8;
break;
score += 8;
break;
case 0xc2: /* rep */
case 0xe2: /* sep */
@ -269,8 +374,8 @@ uint8_t smc_headerscore(uint32_t addr, snes_header_t* header) {
case 0xa0: /* ldy imm */
case 0x20: /* jsr abs */
case 0x22: /* jsl abs */
score += 4;
break;
score += 4;
break;
case 0x40: /* rti */
case 0x60: /* rts */
@ -278,20 +383,28 @@ uint8_t smc_headerscore(uint32_t addr, snes_header_t* header) {
case 0xcd: /* cmp abs */
case 0xec: /* cpx abs */
case 0xcc: /* cpy abs */
score -= 4;
break;
score -= 4;
break;
case 0x00: /* brk */
case 0x02: /* cop */
case 0xdb: /* stp */
case 0x42: /* wdm */
case 0xff: /* sbc abs long indexed */
score -= 8;
break;
}
score -= 8;
break;
}
if(score && addr > 0x400000) score += 4;
if(score < 0) score = 0;
return score;
if ( score && addr > 0x400000 )
{
score += 4;
}
if ( score < 0 )
{
score = 0;
}
return score;
}

View File

@ -37,58 +37,59 @@
#define FPGA_CX4 ((const uint8_t*)"/sd2snes/fpga_cx4.bit")
typedef struct _snes_header {
uint8_t maker[2]; /* 0xB0 */
uint8_t gamecode[4]; /* 0xB2 */
uint8_t fixed_00[7]; /* 0xB6 */
uint8_t expramsize; /* 0xBD */
uint8_t specver; /* 0xBE */
uint8_t carttype2; /* 0xBF */
uint8_t name[21]; /* 0xC0 */
uint8_t map; /* 0xD5 */
uint8_t carttype; /* 0xD6 */
uint8_t romsize; /* 0xD7 */
uint8_t ramsize; /* 0xD8 */
uint8_t destcode; /* 0xD9 */
uint8_t licensee; /* 0xDA */
uint8_t ver; /* 0xDB */
uint16_t cchk; /* 0xDC */
uint16_t chk; /* 0xDE */
uint32_t pad1; /* 0xE0 */
uint16_t vect_cop16; /* 0xE4 */
uint16_t vect_brk16; /* 0xE6 */
uint16_t vect_abt16; /* 0xE8 */
uint16_t vect_nmi16; /* 0xEA */
uint16_t vect_irq16; /* 0xEE */
uint16_t pad2; /* 0xF0 */
uint16_t vect_cop8; /* 0xF4 */
uint32_t pad3; /* 0xF6 */
uint16_t vect_abt8; /* 0xF8 */
uint16_t vect_nmi8; /* 0xFA */
uint16_t vect_reset; /* 0xFC */
uint16_t vect_brk8; /* 0xFE */
typedef struct _snes_header
{
uint8_t maker[2]; /* 0xB0 */
uint8_t gamecode[4]; /* 0xB2 */
uint8_t fixed_00[7]; /* 0xB6 */
uint8_t expramsize; /* 0xBD */
uint8_t specver; /* 0xBE */
uint8_t carttype2; /* 0xBF */
uint8_t name[21]; /* 0xC0 */
uint8_t map; /* 0xD5 */
uint8_t carttype; /* 0xD6 */
uint8_t romsize; /* 0xD7 */
uint8_t ramsize; /* 0xD8 */
uint8_t destcode; /* 0xD9 */
uint8_t licensee; /* 0xDA */
uint8_t ver; /* 0xDB */
uint16_t cchk; /* 0xDC */
uint16_t chk; /* 0xDE */
uint32_t pad1; /* 0xE0 */
uint16_t vect_cop16; /* 0xE4 */
uint16_t vect_brk16; /* 0xE6 */
uint16_t vect_abt16; /* 0xE8 */
uint16_t vect_nmi16; /* 0xEA */
uint16_t vect_irq16; /* 0xEE */
uint16_t pad2; /* 0xF0 */
uint16_t vect_cop8; /* 0xF4 */
uint32_t pad3; /* 0xF6 */
uint16_t vect_abt8; /* 0xF8 */
uint16_t vect_nmi8; /* 0xFA */
uint16_t vect_reset; /* 0xFC */
uint16_t vect_brk8; /* 0xFE */
} snes_header_t;
typedef struct _snes_romprops {
uint16_t offset; /* start of actual ROM image */
uint8_t mapper_id; /* FPGA mapper */
uint8_t pad1; /* for alignment */
uint32_t expramsize_bytes; /* ExpRAM size in bytes */
uint32_t ramsize_bytes; /* CartRAM size in bytes */
uint32_t romsize_bytes; /* ROM size in bytes (rounded up) */
const uint8_t* dsp_fw; /* DSP (NEC / Hitachi) ROM filename */
const uint8_t* fpga_conf; /* FPGA config file to load (default: base) */
uint8_t has_dspx; /* DSP[1-4] presence flag */
uint8_t has_st0010; /* st0010 presence flag (additional to dspx) */
uint8_t has_msu1; /* MSU1 presence flag */
uint8_t has_cx4; /* CX4 presence flag */
uint8_t fpga_features; /* feature/peripheral enable bits*/
uint8_t region; /* game region (derived from destination code) */
uint32_t load_address; /* where to load the ROM image */
snes_header_t header; /* original header from ROM image */
typedef struct _snes_romprops
{
uint16_t offset; /* start of actual ROM image */
uint8_t mapper_id; /* FPGA mapper */
uint8_t pad1; /* for alignment */
uint32_t expramsize_bytes; /* ExpRAM size in bytes */
uint32_t ramsize_bytes; /* CartRAM size in bytes */
uint32_t romsize_bytes; /* ROM size in bytes (rounded up) */
const uint8_t *dsp_fw; /* DSP (NEC / Hitachi) ROM filename */
const uint8_t *fpga_conf; /* FPGA config file to load (default: base) */
uint8_t has_dspx; /* DSP[1-4] presence flag */
uint8_t has_st0010; /* st0010 presence flag (additional to dspx) */
uint8_t has_msu1; /* MSU1 presence flag */
uint8_t has_cx4; /* CX4 presence flag */
uint8_t fpga_features; /* feature/peripheral enable bits*/
uint8_t region; /* game region (derived from destination code) */
snes_header_t header; /* original header from ROM image */
} snes_romprops_t;
void smc_id(snes_romprops_t*);
uint8_t smc_headerscore(uint32_t addr, snes_header_t* header);
void smc_id( snes_romprops_t * );
uint8_t smc_headerscore( uint32_t addr, snes_header_t *header );
#endif

View File

@ -25,6 +25,7 @@
*/
#include <arm/NXP/LPC17xx/LPC17xx.h>
#include <string.h>
#include "bits.h"
#include "config.h"
#include "uart.h"
@ -39,42 +40,51 @@
#include "fpga.h"
#include "fpga_spi.h"
uint8_t initloop=1;
uint8_t initloop = 1;
uint32_t saveram_crc, saveram_crc_old;
extern snes_romprops_t romprops;
volatile int reset_changed;
volatile int reset_pressed;
void prepare_reset() {
snes_reset(1);
delay_ms(SNES_RESET_PULSELEN_MS);
if(romprops.ramsize_bytes && fpga_test() == FPGA_TEST_TOKEN) {
writeled(1);
save_sram(file_lfn, romprops.ramsize_bytes, SRAM_SAVE_ADDR);
writeled(0);
}
rdyled(1);
readled(1);
writeled(1);
snes_reset(0);
while(get_snes_reset());
snes_reset(1);
fpga_dspx_reset(1);
delay_ms(200);
void prepare_reset()
{
snes_reset( 1 );
delay_ms( SNES_RESET_PULSELEN_MS );
if ( romprops.ramsize_bytes && fpga_test() == FPGA_TEST_TOKEN )
{
writeled( 1 );
save_sram( file_lfn, romprops.ramsize_bytes, SRAM_SAVE_ADDR );
writeled( 0 );
}
rdyled( 1 );
readled( 1 );
writeled( 1 );
snes_reset( 0 );
while ( get_snes_reset() );
snes_reset( 1 );
fpga_dspx_reset( 1 );
delay_ms( 200 );
}
void snes_init() {
/* put reset level on reset pin */
BITBAND(SNES_RESET_REG->FIOCLR, SNES_RESET_BIT) = 1;
/* reset the SNES */
snes_reset(1);
void snes_init()
{
/* put reset level on reset pin */
BITBAND( SNES_RESET_REG->FIOCLR, SNES_RESET_BIT ) = 1;
/* reset the SNES */
snes_reset( 1 );
}
void snes_reset_pulse() {
snes_reset(1);
delay_ms(SNES_RESET_PULSELEN_MS);
snes_reset(0);
void snes_reset_pulse()
{
snes_reset( 1 );
delay_ms( SNES_RESET_PULSELEN_MS );
snes_reset( 0 );
}
/*
@ -82,8 +92,9 @@ void snes_reset_pulse() {
*
* state: put SNES in reset state when 1, release when 0
*/
void snes_reset(int state) {
BITBAND(SNES_RESET_REG->FIODIR, SNES_RESET_BIT) = state;
void snes_reset( int state )
{
BITBAND( SNES_RESET_REG->FIODIR, SNES_RESET_BIT ) = state;
}
/*
@ -91,8 +102,9 @@ void snes_reset(int state) {
*
* returns: 1 when reset, 0 when not reset
*/
uint8_t get_snes_reset() {
return !BITBAND(SNES_RESET_REG->FIOPIN, SNES_RESET_BIT);
uint8_t get_snes_reset()
{
return !BITBAND( SNES_RESET_REG->FIOPIN, SNES_RESET_BIT );
}
/*
@ -101,81 +113,123 @@ uint8_t get_snes_reset() {
*/
uint32_t diffcount = 0, samecount = 0, didnotsave = 0;
uint8_t sram_valid = 0;
void snes_main_loop() {
if(!romprops.ramsize_bytes)return;
if(initloop) {
saveram_crc_old = calc_sram_crc(SRAM_SAVE_ADDR, romprops.ramsize_bytes);
initloop=0;
}
saveram_crc = calc_sram_crc(SRAM_SAVE_ADDR, romprops.ramsize_bytes);
sram_valid = sram_reliable();
if(crc_valid && sram_valid) {
if(saveram_crc != saveram_crc_old) {
if(samecount) {
diffcount=1;
} else {
diffcount++;
didnotsave++;
}
samecount=0;
void snes_main_loop()
{
if ( !romprops.ramsize_bytes )
{
return;
}
if(saveram_crc == saveram_crc_old) {
samecount++;
if ( initloop )
{
saveram_crc_old = calc_sram_crc( SRAM_SAVE_ADDR, romprops.ramsize_bytes );
initloop = 0;
}
if(diffcount>=1 && samecount==5) {
printf("SaveRAM CRC: 0x%04lx; saving %s\n", saveram_crc, file_lfn);
writeled(1);
save_sram(file_lfn, romprops.ramsize_bytes, SRAM_SAVE_ADDR);
writeled(0);
didnotsave=0;
saveram_crc = calc_sram_crc( SRAM_SAVE_ADDR, romprops.ramsize_bytes );
sram_valid = sram_reliable();
if ( crc_valid && sram_valid )
{
if ( saveram_crc != saveram_crc_old )
{
if ( samecount )
{
diffcount = 1;
}
else
{
diffcount++;
didnotsave++;
}
samecount = 0;
}
if ( saveram_crc == saveram_crc_old )
{
samecount++;
}
if ( diffcount >= 1 && samecount == 5 )
{
printf( "SaveRAM CRC: 0x%04lx; saving %s\n", saveram_crc, file_lfn );
writeled( 1 );
save_sram( file_lfn, romprops.ramsize_bytes, SRAM_SAVE_ADDR );
writeled( 0 );
didnotsave = 0;
}
if ( didnotsave > 50 )
{
printf( "periodic save (sram contents keep changing...)\n" );
diffcount = 0;
writeled( 1 );
save_sram( file_lfn, romprops.ramsize_bytes, SRAM_SAVE_ADDR );
didnotsave = 0;
writeled( 1 );
}
saveram_crc_old = saveram_crc;
}
if(didnotsave>50) {
printf("periodic save (sram contents keep changing...)\n");
diffcount=0;
writeled(1);
save_sram(file_lfn, romprops.ramsize_bytes, SRAM_SAVE_ADDR);
didnotsave=0;
writeled(1);
}
saveram_crc_old = saveram_crc;
}
printf("crc=%lx crc_valid=%d sram_valid=%d diffcount=%ld samecount=%ld, didnotsave=%ld\n", saveram_crc, crc_valid, sram_valid, diffcount, samecount, didnotsave);
printf( "crc=%lx crc_valid=%d sram_valid=%d diffcount=%ld samecount=%ld, didnotsave=%ld\n", saveram_crc, crc_valid,
sram_valid, diffcount, samecount, didnotsave );
}
/*
* SD2SNES menu loop.
* monitors menu selection. return when selection was made.
*/
uint8_t menu_main_loop() {
uint8_t cmd = 0;
sram_writebyte(0, SRAM_CMD_ADDR);
while(!cmd) {
if(!get_snes_reset()) {
while(!sram_reliable())printf("hurr\n");
cmd = sram_readbyte(SRAM_CMD_ADDR);
uint8_t menu_main_loop()
{
uint8_t cmd = 0;
sram_writebyte( 0, SRAM_CMD_ADDR );
while ( !cmd )
{
if ( !get_snes_reset() )
{
while ( !sram_reliable() )
{
printf( "hurr\n" );
}
cmd = sram_readbyte( SRAM_CMD_ADDR );
//cmd = SNES_CMD_LOADSPC;
}
if ( get_snes_reset() )
{
cmd = 0;
}
sleep_ms( 20 );
cli_entrycheck();
}
if(get_snes_reset()) {
cmd = 0;
}
sleep_ms(20);
cli_entrycheck();
}
return cmd;
return cmd;
}
void get_selected_name(uint8_t* fn) {
uint32_t addr;
addr = sram_readlong(SRAM_PARAM_ADDR);
printf("fd addr=%lx\n", addr);
sram_readblock(fn, addr + 7 + SRAM_MENU_ADDR, 256);
void get_selected_name( uint8_t *fn )
{
uint32_t addr;
addr = sram_readlong( SRAM_PARAM_ADDR );
printf( "fd addr=%lx\n", addr );
sram_readblock( fn, addr + 7 + SRAM_MENU_ADDR, 256 );
//memcpy(fn, "dossier sans titre/ff6.sfc", 28);
}
void snes_bootprint(void* msg) {
sram_writeblock(msg, SRAM_CMD_ADDR, 33);
void snes_bootprint( void *msg )
{
printf( "SNES SAY: %s\n", ( char * )msg );
sram_writeblock( msg, SRAM_CMD_ADDR, 33 );
}
void snes_menu_errmsg(int err, void* msg) {
sram_writeblock(msg, SRAM_CMD_ADDR+1, 64);
sram_writebyte(err, SRAM_CMD_ADDR);
void snes_menu_errmsg( int err, void *msg )
{
printf( "%d: %s\n", err, ( char * )msg );
sram_writeblock( msg, SRAM_CMD_ADDR + 1, 64 );
sram_writebyte( err, SRAM_CMD_ADDR );
}

View File

@ -38,18 +38,18 @@
#define MENU_ERR_NODSP (1)
#define MENU_ERR_NOBSX (2)
#define SNES_RESET_PULSELEN_MS (1)
#define SNES_RESET_PULSELEN_MS (100)
uint8_t crc_valid;
void prepare_reset(void);
void snes_init(void);
void snes_reset_pulse(void);
void snes_reset(int state);
uint8_t get_snes_reset(void);
void snes_main_loop(void);
uint8_t menu_main_loop(void);
void get_selected_name(uint8_t* lfn);
void snes_bootprint(void* msg);
void snes_menu_errmsg(int err, void* msg);
void prepare_reset( void );
void snes_init( void );
void snes_reset_pulse( void );
void snes_reset( int state );
uint8_t get_snes_reset( void );
void snes_main_loop( void );
uint8_t menu_main_loop( void );
void get_selected_name( uint8_t *lfn );
void snes_bootprint( void *msg );
void snes_menu_errmsg( int err, void *msg );
#endif

View File

@ -1,330 +1,295 @@
const uint8_t bootrle[] = {
0xe2, 0x20, 0xc2, 0x10, 0xa9, 0x00, 0x48, 0xab,
0xad, 0x10, 0x42, 0xa2, 0x00, 0x58, 0x8e, 0x16,
0x21, 0xa9, 0x01, 0x8d, 0x15, 0x00, 0xa2, 0x00,
0xb0, 0xa9, 0x7f, 0x8e, 0x10, 0x00, 0x8d, 0x0f,
0x00, 0xa2, 0x00, 0x09, 0x8e, 0x13, 0x00, 0xa9,
0x18, 0x8d, 0x12, 0x00, 0x20, 0xdc, 0x0b, 0xa9,
0x01, 0x8d, 0x16, 0x00, 0x6b, 0xe2, 0x20, 0xad,
0x11, 0x42, 0x6b, 0xe2, 0x20, 0xc2, 0x10, 0x78,
0x9c, 0x00, 0x42, 0x20, 0x2a, 0x01, 0xa9, 0x01,
0x8d, 0x0d, 0x42, 0x20, 0x84, 0x02, 0x20, 0x93,
0x01, 0x20, 0x8b, 0x01, 0x20, 0x04, 0x0c, 0x20,
0x57, 0x02, 0xa2, 0x41, 0x00, 0xa9, 0x00, 0xca,
0x9f, 0x00, 0x70, 0x30, 0xd0, 0xf9, 0xa9, 0x7e,
0xa2, 0x1b, 0x00, 0x8d, 0x83, 0x21, 0x8e, 0x81,
0x21, 0xa9, 0x00, 0x8d, 0x15, 0x00, 0xa2, 0xbc,
0x00, 0xa9, 0xc0, 0x8e, 0x10, 0x00, 0x8d, 0x0f,
0x00, 0xa2, 0x6f, 0x00, 0x8e, 0x13, 0x00, 0xa9,
0x80, 0x8d, 0x12, 0x00, 0x20, 0xdc, 0x0b, 0xa9,
0x7e, 0xa2, 0x8b, 0x00, 0x8d, 0x83, 0x21, 0x8e,
0x81, 0x21, 0xa9, 0x00, 0x8d, 0x15, 0x00, 0xa2,
0x8c, 0x0b, 0xa9, 0xc0, 0x8e, 0x10, 0x00, 0x8d,
0x0f, 0x00, 0xa2, 0x4f, 0x00, 0x8e, 0x13, 0x00,
0xa9, 0x80, 0x8d, 0x12, 0x00, 0x20, 0xdc, 0x0b,
0x22, 0x1b, 0x00, 0x7e, 0xc2, 0x10, 0xe2, 0x20,
0xa9, 0x00, 0x8f, 0x00, 0x00, 0x7e, 0xa9, 0x0d,
0x8f, 0x02, 0x00, 0x7e, 0xa9, 0x30, 0x8f, 0x06,
0x00, 0x7e, 0xc2, 0x20, 0xa9, 0x00, 0x70, 0x8f,
0x04, 0x00, 0x7e, 0xe2, 0x20, 0xa9, 0x00, 0x8f,
0x07, 0x00, 0x7e, 0x20, 0x8b, 0x00, 0xc2, 0x20,
0xa9, 0x00, 0x58, 0x8d, 0x16, 0x21, 0xe2, 0x20,
0xa9, 0x01, 0x8d, 0x00, 0x43, 0xa9, 0x18, 0x8d,
0x01, 0x43, 0xa9, 0x7f, 0x8d, 0x04, 0x43, 0xa2,
0x00, 0xb0, 0x8e, 0x02, 0x43, 0xa2, 0x00, 0x09,
0x8e, 0x05, 0x43, 0xaf, 0x12, 0x42, 0x00, 0x29,
0x80, 0xd0, 0xf8, 0xaf, 0x12, 0x42, 0x00, 0x29,
0x80, 0xf0, 0xf8, 0xa9, 0x01, 0x8d, 0x0b, 0x42,
0x80, 0x9a, 0x58, 0x9c, 0x00, 0x42, 0x5c, 0x19,
0x00, 0x7e, 0x9c, 0x0b, 0x42, 0x9c, 0x0c, 0x42,
0x9c, 0x10, 0x43, 0x9c, 0x11, 0x43, 0x9c, 0x12,
0x43, 0x9c, 0x13, 0x43, 0x9c, 0x14, 0x43, 0x9c,
0x20, 0x43, 0x9c, 0x21, 0x43, 0x9c, 0x22, 0x43,
0x9c, 0x23, 0x43, 0x9c, 0x24, 0x43, 0x9c, 0x30,
0x43, 0x9c, 0x31, 0x43, 0x9c, 0x32, 0x43, 0x9c,
0x33, 0x43, 0x9c, 0x34, 0x43, 0x9c, 0x40, 0x43,
0x9c, 0x41, 0x43, 0x9c, 0x42, 0x43, 0x9c, 0x43,
0x43, 0x9c, 0x44, 0x43, 0x9c, 0x50, 0x43, 0x9c,
0x51, 0x43, 0x9c, 0x52, 0x43, 0x9c, 0x53, 0x43,
0x9c, 0x54, 0x43, 0x60, 0xad, 0x12, 0x42, 0x29,
0x80, 0xd0, 0xf9, 0xad, 0x12, 0x42, 0x29, 0x80,
0xf0, 0xf9, 0x60, 0xe2, 0x20, 0xc2, 0x10, 0x9c,
0x30, 0x21, 0x60, 0xe2, 0x20, 0xc2, 0x10, 0x9c,
0x00, 0x42, 0x9c, 0x0b, 0x42, 0x9c, 0x0c, 0x42,
0xa2, 0x00, 0xb0, 0x8e, 0x81, 0x21, 0xa9, 0x01,
0x8d, 0x83, 0x21, 0xa9, 0x08, 0x8d, 0x15, 0x00,
0xa2, 0x59, 0xff, 0xa9, 0xc0, 0x8e, 0x10, 0x00,
0x8d, 0x0f, 0x00, 0xa2, 0x40, 0x07, 0x8e, 0x13,
0x00, 0xa9, 0x80, 0x8d, 0x12, 0x00, 0x20, 0xdc,
0x0b, 0xa2, 0x00, 0x00, 0x8e, 0x16, 0x21, 0xa9,
0x01, 0x8d, 0x15, 0x00, 0xa2, 0x7c, 0x03, 0xa9,
0xc0, 0x8e, 0x10, 0x00, 0x8d, 0x0f, 0x00, 0xa2,
0x00, 0x08, 0x8e, 0x13, 0x00, 0xa9, 0x18, 0x8d,
0x12, 0x00, 0x20, 0xdc, 0x0b, 0xa2, 0x00, 0x58,
0x8e, 0x16, 0x21, 0xa9, 0x09, 0x8d, 0x15, 0x00,
0xa2, 0x59, 0xff, 0xa9, 0xc0, 0x8e, 0x10, 0x00,
0x8d, 0x0f, 0x00, 0xa2, 0x40, 0x07, 0x8e, 0x13,
0x00, 0xa9, 0x18, 0x8d, 0x12, 0x00, 0x20, 0xdc,
0x0b, 0xa2, 0x00, 0x00, 0x8e, 0x02, 0x21, 0xa9,
0x08, 0x8d, 0x15, 0x00, 0xa2, 0x59, 0xff, 0xa9,
0xc0, 0x8e, 0x10, 0x00, 0x8d, 0x0f, 0x00, 0xa2,
0x20, 0x02, 0x8e, 0x13, 0x00, 0xa9, 0x04, 0x8d,
0x12, 0x00, 0x20, 0xdc, 0x0b, 0x9c, 0x21, 0x21,
0xa9, 0x00, 0x8d, 0x15, 0x00, 0xa2, 0x7c, 0x0b,
0xa9, 0xc0, 0x8e, 0x10, 0x00, 0x8d, 0x0f, 0x00,
0xa2, 0x10, 0x00, 0x8e, 0x13, 0x00, 0xa9, 0x22,
0x8d, 0x12, 0x00, 0x20, 0xdc, 0x0b, 0x60, 0xe2,
0x20, 0xc2, 0x10, 0xa9, 0x00, 0x8d, 0x05, 0x21,
0xa9, 0x58, 0x09, 0x02, 0x8d, 0x07, 0x21, 0xa9,
0x40, 0x8d, 0x0b, 0x21, 0xa9, 0x01, 0x8d, 0x2c,
0x21, 0xa9, 0x01, 0x8d, 0x2d, 0x21, 0xa9, 0x00,
0x8d, 0x30, 0x21, 0x9c, 0x21, 0x21, 0xa9, 0x0f,
0x8d, 0x00, 0x21, 0x60, 0xe2, 0x20, 0xc2, 0x10,
0x9c, 0x00, 0x42, 0xa9, 0xff, 0x8d, 0x01, 0x42,
0x9c, 0x02, 0x42, 0x9c, 0x03, 0x42, 0x9c, 0x04,
0x42, 0x9c, 0x05, 0x42, 0x9c, 0x06, 0x42, 0x9c,
0x07, 0x42, 0x9c, 0x08, 0x42, 0x9c, 0x09, 0x42,
0x9c, 0x0a, 0x42, 0x9c, 0x0b, 0x42, 0x9c, 0x0c,
0x42, 0xa9, 0x00, 0x8d, 0x0d, 0x42, 0xa9, 0x8f,
0x8d, 0x00, 0x21, 0xa9, 0x03, 0x8d, 0x01, 0x21,
0x9c, 0x02, 0x21, 0x9c, 0x03, 0x21, 0x9c, 0x05,
0x21, 0x9c, 0x06, 0x21, 0x9c, 0x07, 0x21, 0x9c,
0x08, 0x21, 0x9c, 0x09, 0x21, 0x9c, 0x0a, 0x21,
0x9c, 0x0b, 0x21, 0x9c, 0x0c, 0x21, 0x9c, 0x0d,
0x21, 0x9c, 0x0d, 0x21, 0x9c, 0x0e, 0x21, 0x9c,
0x0e, 0x21, 0x9c, 0x0f, 0x21, 0x9c, 0x0f, 0x21,
0xa9, 0x05, 0x8d, 0x10, 0x21, 0x9c, 0x10, 0x21,
0x9c, 0x11, 0x21, 0x9c, 0x11, 0x21, 0x9c, 0x12,
0x21, 0x9c, 0x12, 0x21, 0x9c, 0x13, 0x21, 0x9c,
0x13, 0x21, 0x9c, 0x14, 0x21, 0x9c, 0x14, 0x21,
0xa9, 0x80, 0x8d, 0x15, 0x21, 0x9c, 0x16, 0x21,
0x9c, 0x17, 0x21, 0x9c, 0x1a, 0x21, 0x9c, 0x1b,
0x21, 0xa9, 0x01, 0x8d, 0x1b, 0x21, 0x9c, 0x1c,
0x21, 0x9c, 0x1c, 0x21, 0x9c, 0x1d, 0x21, 0x9c,
0x1d, 0x21, 0x9c, 0x1e, 0x21, 0x8d, 0x1e, 0x21,
0x9c, 0x1f, 0x21, 0x9c, 0x1f, 0x21, 0x9c, 0x20,
0x21, 0x9c, 0x20, 0x21, 0x9c, 0x21, 0x21, 0x9c,
0x23, 0x21, 0x9c, 0x24, 0x21, 0x9c, 0x25, 0x21,
0x9c, 0x26, 0x21, 0x9c, 0x27, 0x21, 0x9c, 0x28,
0x21, 0x9c, 0x29, 0x21, 0x9c, 0x2a, 0x21, 0x9c,
0x2b, 0x21, 0x9c, 0x2c, 0x21, 0x9c, 0x2d, 0x21,
0x9c, 0x2e, 0x21, 0xa9, 0x30, 0x8d, 0x30, 0x21,
0x9c, 0x31, 0x21, 0xa9, 0xe0, 0x8d, 0x32, 0x21,
0x9c, 0x33, 0x21, 0x60, 0x77, 0x00, 0x11, 0x02,
0x30, 0x30, 0x48, 0x30, 0x48, 0x30, 0x48, 0x20,
0x58, 0x00, 0x30, 0x30, 0x48, 0x00, 0x30, 0x00,
0x6c, 0x6c, 0x92, 0x24, 0x5a, 0x00, 0x36, 0x5b,
0x00, 0x09, 0x6c, 0x6c, 0x92, 0xfe, 0x01, 0x6c,
0x92, 0xfe, 0x01, 0x6c, 0x92, 0x00, 0x6c, 0x00,
0x00, 0x10, 0x6c, 0x7c, 0xc6, 0xc6, 0x39, 0xf0,
0x0e, 0x1e, 0xe1, 0xc6, 0x39, 0x7c, 0xc6, 0x10,
0x6c, 0x42, 0xa5, 0xa4, 0x5a, 0x48, 0xb4, 0x10,
0x6c, 0x24, 0x5a, 0x4a, 0xb5, 0x84, 0x4a, 0x00,
0x84, 0x70, 0xc8, 0xc0, 0x34, 0xc4, 0x2e, 0x6e,
0xdb, 0xc4, 0x2a, 0xc4, 0x3a, 0x7c, 0xc6, 0x00,
0x7c, 0x00, 0x18, 0x18, 0x24, 0x10, 0x28, 0x00,
0x10, 0x5b, 0x00, 0x08, 0x18, 0x24, 0x30, 0x68,
0x30, 0x48, 0x30, 0x48, 0x30, 0x48, 0x30, 0x68,
0x18, 0x24, 0x00, 0x18, 0x30, 0x48, 0x18, 0x2c,
0x18, 0x24, 0x18, 0x24, 0x18, 0x24, 0x18, 0x2c,
0x30, 0x48, 0x00, 0x30, 0x00, 0x6c, 0x6c, 0x92,
0x38, 0x44, 0x7c, 0x82, 0x38, 0x44, 0x6c, 0x92,
0x00, 0x6c, 0x00, 0x00, 0x00, 0x18, 0x18, 0x24,
0x18, 0x66, 0x7e, 0x81, 0x18, 0x66, 0x18, 0x24,
0x00, 0x18, 0x5b, 0x00, 0x0b, 0x18, 0x18, 0x24,
0x18, 0x24, 0x10, 0x28, 0x5b, 0x00, 0x05, 0x7e,
0x7e, 0x81, 0x00, 0x7e, 0x5b, 0x00, 0x0f, 0x18,
0x18, 0x24, 0x18, 0x24, 0x00, 0x18, 0x03, 0x04,
0x06, 0x09, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48,
0x60, 0x90, 0xc0, 0x20, 0x00, 0xc0, 0x7c, 0xc6,
0xe6, 0x39, 0xc6, 0x29, 0xc6, 0x29, 0xc6, 0x29,
0xce, 0x39, 0x7c, 0xc6, 0x00, 0x7c, 0x18, 0x34,
0x18, 0x24, 0x18, 0x24, 0x18, 0x24, 0x18, 0x24,
0x18, 0x24, 0x18, 0x24, 0x00, 0x18, 0xfc, 0x06,
0x06, 0xf9, 0x06, 0x79, 0x7c, 0x86, 0xc0, 0xbc,
0xc0, 0x3e, 0xfe, 0x01, 0x00, 0xfe, 0xfc, 0x06,
0x06, 0xf9, 0x06, 0x39, 0x3c, 0x46, 0x06, 0x39,
0x06, 0xf9, 0xfc, 0x06, 0x00, 0xfc, 0xc6, 0x29,
0xc6, 0x29, 0xc6, 0x39, 0x7e, 0xc1, 0x06, 0x79,
0x06, 0x09, 0x06, 0x09, 0x00, 0x06, 0xfe, 0x01,
0xc0, 0x3e, 0xc0, 0x3c, 0xfc, 0x06, 0x06, 0xf9,
0x06, 0xf9, 0xfc, 0x06, 0x00, 0xf8, 0x7c, 0xc2,
0xc0, 0x3c, 0xc0, 0x3c, 0xfc, 0x06, 0xc6, 0x39,
0xc6, 0x39, 0x7c, 0xc6, 0x00, 0x7c, 0xfc, 0x06,
0x06, 0xf9, 0x06, 0x09, 0x06, 0x09, 0x06, 0x09,
0x06, 0x09, 0x06, 0x09, 0x00, 0x06, 0x7c, 0xc6,
0xc6, 0x39, 0xc6, 0x39, 0x7c, 0xc6, 0xc6, 0x39,
0xc6, 0x39, 0x7c, 0xc6, 0x00, 0x7c, 0x7c, 0xc6,
0xc6, 0x39, 0xc6, 0x39, 0x7e, 0xc1, 0x06, 0x79,
0x06, 0x79, 0x7c, 0x86, 0x00, 0x7c, 0x00, 0x00,
0x00, 0x30, 0x30, 0x48, 0x00, 0x30, 0x00, 0x30,
0x30, 0x48, 0x00, 0x30, 0x5b, 0x00, 0x05, 0x30,
0x30, 0x48, 0x00, 0x30, 0x00, 0x30, 0x30, 0x48,
0x20, 0x50, 0x00, 0x20, 0x00, 0x18, 0x18, 0x24,
0x30, 0x48, 0x60, 0x90, 0x30, 0x48, 0x18, 0x24,
0x00, 0x18, 0x5b, 0x00, 0x05, 0x3c, 0x3c, 0x42,
0x00, 0x3c, 0x00, 0x3c, 0x3c, 0x42, 0x00, 0x3c,
0x00, 0x00, 0x00, 0x30, 0x30, 0x48, 0x18, 0x24,
0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x00, 0x30,
0x00, 0x00, 0xf8, 0x0c, 0x0c, 0xf2, 0x0c, 0x12,
0x18, 0x24, 0x30, 0x48, 0x00, 0x30, 0x30, 0x48,
0x00, 0x30, 0x7c, 0xc6, 0xc6, 0x39, 0xc6, 0x39,
0xde, 0x21, 0xde, 0x21, 0xc0, 0x3e, 0x7e, 0xc1,
0x00, 0x7e, 0x7c, 0xc6, 0xc6, 0x39, 0xc6, 0x39,
0xde, 0x21, 0xc6, 0x39, 0xc6, 0x29, 0xc6, 0x29,
0x00, 0xc6, 0xfc, 0x06, 0xc6, 0x39, 0xc6, 0x39,
0xdc, 0x26, 0xc6, 0x39, 0xc6, 0x39, 0xfc, 0x06,
0x00, 0xfc, 0x7e, 0xc1, 0xc0, 0x3e, 0xc0, 0x20,
0xc0, 0x20, 0xc0, 0x20, 0xc0, 0x3e, 0x7e, 0xc1,
0x00, 0x7e, 0xfc, 0x02, 0xc6, 0x3b, 0xc6, 0x29,
0xc6, 0x29, 0xc6, 0x29, 0xc6, 0x3b, 0xfc, 0x02,
0x00, 0xfc, 0xfe, 0x01, 0xc0, 0x3e, 0xc0, 0x38,
0xf8, 0x04, 0xc0, 0x38, 0xc0, 0x3e, 0xfe, 0x01,
0x00, 0xfe, 0xfe, 0x01, 0xc0, 0x3e, 0xc0, 0x38,
0xf8, 0x04, 0xc0, 0x38, 0xc0, 0x20, 0xc0, 0x20,
0x00, 0xc0, 0x7e, 0xc1, 0xc0, 0x3e, 0xc0, 0x2e,
0xce, 0x33, 0xc6, 0x29, 0xc6, 0x39, 0x7c, 0xc6,
0x00, 0x7c, 0xc6, 0x29, 0xc6, 0x29, 0xc6, 0x39,
0xfe, 0x01, 0xc6, 0x39, 0xc6, 0x29, 0xc6, 0x29,
0x00, 0xc6, 0x18, 0x24, 0x18, 0x24, 0x18, 0x24,
0x18, 0x24, 0x18, 0x24, 0x18, 0x24, 0x18, 0x24,
0x00, 0x18, 0x0c, 0x12, 0x0c, 0x12, 0x0c, 0x12,
0x0c, 0x12, 0x0c, 0x12, 0x0c, 0xf6, 0xf8, 0x06,
0x00, 0xfc, 0xc6, 0x29, 0xc6, 0x29, 0xc6, 0x38,
0xfc, 0x06, 0xc6, 0x39, 0xc6, 0x29, 0xc6, 0x29,
0x00, 0xc7, 0xc0, 0x20, 0xc0, 0x20, 0xc0, 0x20,
0xc0, 0x20, 0xc0, 0x20, 0xc0, 0x3c, 0xfc, 0x02,
0x00, 0xfc, 0xec, 0x16, 0xd6, 0x29, 0xd6, 0x29,
0xd6, 0x29, 0xc6, 0x39, 0xc6, 0x29, 0xc6, 0x29,
0x00, 0xc7, 0xfc, 0x06, 0xc6, 0x39, 0xc6, 0x29,
0xc6, 0x29, 0xc6, 0x29, 0xc6, 0x29, 0xc6, 0x29,
0x00, 0xc6, 0x7c, 0xc6, 0xc6, 0x39, 0xc6, 0x29,
0xc6, 0x29, 0xc6, 0x29, 0xc6, 0x39, 0x7c, 0xc6,
0x00, 0x7c, 0xfc, 0x06, 0xc6, 0x39, 0xc6, 0x29,
0xc6, 0x39, 0xfc, 0x06, 0xc0, 0x3c, 0xc0, 0x20,
0x00, 0xc0, 0x7c, 0x82, 0xc6, 0xbb, 0xc6, 0x29,
0xc6, 0x29, 0xc6, 0x29, 0xce, 0x31, 0x7e, 0xc1,
0x00, 0x7e, 0xfc, 0x06, 0xc6, 0x39, 0xc6, 0x39,
0xfc, 0x06, 0xc6, 0x39, 0xc6, 0x29, 0xc6, 0x29,
0x00, 0xc6, 0x7e, 0xc1, 0xc0, 0x3e, 0xc0, 0x3c,
0x7c, 0xc6, 0x06, 0x79, 0x06, 0xf9, 0xfc, 0x06,
0x00, 0xfc, 0xfe, 0x01, 0x18, 0xe6, 0x18, 0x24,
0x18, 0x24, 0x18, 0x24, 0x18, 0x24, 0x18, 0x24,
0x00, 0x18, 0xc6, 0x29, 0xc6, 0x29, 0xc6, 0x29,
0xc6, 0x29, 0xc6, 0x29, 0xc6, 0x39, 0x7c, 0xc6,
0x00, 0x7c, 0xc6, 0x29, 0xc6, 0x29, 0xc6, 0x29,
0xc6, 0x29, 0x66, 0x99, 0x36, 0x49, 0x1e, 0x21,
0x00, 0x1f, 0xc6, 0x29, 0xc6, 0x29, 0xc6, 0x39,
0xd6, 0x29, 0xd6, 0x29, 0xd6, 0x29, 0x6e, 0xd1,
0x00, 0x6e, 0xc6, 0x29, 0xc6, 0x29, 0xc6, 0x39,
0x7c, 0xc6, 0xc6, 0x39, 0xc6, 0x29, 0xc6, 0x29,
0x00, 0xc6, 0xc6, 0x29, 0xc6, 0x29, 0xc6, 0x39,
0x7e, 0xc1, 0x06, 0x79, 0x06, 0xf9, 0xfc, 0x06,
0x00, 0xfc, 0xfe, 0x01, 0x06, 0xf9, 0x06, 0x79,
0x7c, 0xc6, 0xc0, 0x3c, 0xc0, 0x3e, 0xfe, 0x01,
0x00, 0xfe, 0x3c, 0x42, 0x30, 0x4c, 0x30, 0x48,
0x30, 0x48, 0x30, 0x48, 0x30, 0x4c, 0x3c, 0x42,
0x00, 0x3c, 0xc0, 0x20, 0x60, 0x90, 0x30, 0x48,
0x18, 0x24, 0x0c, 0x12, 0x06, 0x09, 0x03, 0x04,
0x00, 0x03, 0x3c, 0x42, 0x0c, 0x32, 0x0c, 0x12,
0x0c, 0x12, 0x0c, 0x12, 0x0c, 0x32, 0x3c, 0x42,
0x00, 0x3c, 0x18, 0x24, 0x3c, 0x66, 0x66, 0x99,
0x00, 0x66, 0x5b, 0x00, 0x13, 0x7e, 0x7e, 0x81,
0x00, 0x7e, 0x30, 0x48, 0x18, 0x24, 0x18, 0x24,
0x00, 0x18, 0x5b, 0x00, 0x0b, 0x7c, 0x7c, 0x86,
0x06, 0x79, 0x7e, 0xc1, 0xc6, 0x39, 0x7e, 0xc1,
0x00, 0x7e, 0xc0, 0x20, 0xc0, 0x3c, 0xfc, 0x06,
0xc6, 0x39, 0xc6, 0x29, 0xc6, 0x39, 0xfc, 0x06,
0x00, 0xfc, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0xc1,
0xc0, 0x3e, 0xc0, 0x20, 0xc0, 0x3e, 0x7e, 0xc1,
0x00, 0x7e, 0x06, 0x09, 0x06, 0x79, 0x7e, 0xc1,
0xc6, 0x39, 0xc6, 0x29, 0xc6, 0x39, 0x7e, 0xc1,
0x00, 0x7f, 0x00, 0x00, 0x00, 0x7c, 0x7c, 0xc6,
0xc6, 0x39, 0xfe, 0x01, 0xc0, 0x3e, 0x7e, 0xc3,
0x00, 0x7e, 0x1e, 0x21, 0x30, 0x6e, 0x30, 0x4c,
0x3c, 0x42, 0x30, 0x4c, 0x30, 0x48, 0x30, 0x48,
0x30, 0x48, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0xc1,
0xc6, 0x39, 0xc6, 0x39, 0x7e, 0xc1, 0x06, 0x79,
0x7c, 0x86, 0xc0, 0x20, 0xc0, 0x3c, 0xfc, 0x06,
0xc6, 0x39, 0xc6, 0x29, 0xc6, 0x29, 0xc6, 0x29,
0x00, 0xc6, 0x00, 0x18, 0x18, 0x24, 0x00, 0x18,
0x18, 0x24, 0x18, 0x24, 0x18, 0x24, 0x18, 0x24,
0x00, 0x18, 0x00, 0x18, 0x18, 0x24, 0x00, 0x18,
0x18, 0x24, 0x18, 0x24, 0x18, 0x24, 0x18, 0x2c,
0x30, 0x48, 0xc0, 0x20, 0xc0, 0x26, 0xc6, 0x29,
0xc6, 0x2b, 0xfc, 0x06, 0xc6, 0x2b, 0xc6, 0x29,
0x00, 0xc7, 0x30, 0x48, 0x30, 0x48, 0x30, 0x48,
0x30, 0x48, 0x30, 0x48, 0x30, 0x68, 0x18, 0x24,
0x00, 0x1c, 0x00, 0x00, 0x00, 0xec, 0xec, 0x16,
0xd6, 0x29, 0xd6, 0x29, 0xd6, 0x29, 0xc6, 0x39,
0x00, 0xc7, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x06,
0xc6, 0x39, 0xc6, 0x29, 0xc6, 0x29, 0xc6, 0x29,
0x00, 0xc6, 0x00, 0x00, 0x00, 0x7c, 0x7c, 0xc6,
0xc6, 0x39, 0xc6, 0x29, 0xc6, 0x39, 0x7c, 0xc6,
0x00, 0x7c, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x06,
0xc6, 0x39, 0xc6, 0x39, 0xfc, 0x06, 0xc0, 0x3c,
0xc0, 0x20, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0xc1,
0xc6, 0x39, 0xc6, 0x39, 0x7e, 0xc1, 0x06, 0x79,
0x06, 0x09, 0x00, 0x00, 0x00, 0x7c, 0x7c, 0xc2,
0xc0, 0x3c, 0xc0, 0x20, 0xc0, 0x20, 0xc0, 0x20,
0x00, 0xc0, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0xc1,
0xc0, 0x3e, 0x7c, 0xc6, 0x06, 0xf9, 0xfc, 0x06,
0x00, 0xfc, 0x30, 0x48, 0x30, 0x4c, 0x3c, 0x42,
0x30, 0x4c, 0x30, 0x48, 0x30, 0x4e, 0x1e, 0x31,
0x00, 0x1e, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0x29,
0xc6, 0x29, 0xc6, 0x29, 0xc6, 0x39, 0x7c, 0xc6,
0x00, 0x7c, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0x29,
0xc6, 0x29, 0x66, 0x99, 0x36, 0x49, 0x1e, 0x21,
0x00, 0x1e, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0x39,
0xd6, 0x29, 0xd6, 0x29, 0xd6, 0x29, 0x6e, 0xd1,
0x00, 0x6e, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0x29,
0xc6, 0x39, 0x7c, 0xc6, 0xc6, 0x39, 0xc6, 0x29,
0x00, 0xc6, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0x29,
0xc6, 0x39, 0x7e, 0xc1, 0x06, 0x79, 0x06, 0xf9,
0xfc, 0x06, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x01,
0x06, 0xf9, 0x7c, 0xc6, 0xc0, 0x3e, 0xfe, 0x01,
0x00, 0xfe, 0x18, 0x24, 0x30, 0x48, 0x30, 0x48,
0x70, 0x88, 0x30, 0x48, 0x30, 0x48, 0x18, 0x24,
0x00, 0x18, 0x18, 0x24, 0x18, 0x24, 0x18, 0x24,
0x00, 0x18, 0x18, 0x24, 0x18, 0x24, 0x18, 0x24,
0x00, 0x18, 0x30, 0x48, 0x18, 0x24, 0x18, 0x24,
0x1c, 0x22, 0x18, 0x24, 0x18, 0x24, 0x30, 0x48,
0x00, 0x30, 0x00, 0x00, 0x00, 0x72, 0x72, 0x9d,
0xfe, 0x01, 0x9c, 0x72, 0x00, 0x9c, 0x5b, 0x00,
0x14, 0x42, 0x08, 0xff, 0x7f, 0x00, 0x00, 0x9c,
0x73, 0x42, 0x08, 0xff, 0x43, 0x00, 0x00, 0x18,
0x63, 0xc2, 0x30, 0xad, 0x00, 0x00, 0x29, 0xff,
0x00, 0x0a, 0x18, 0x69, 0x00, 0xb0, 0x8d, 0x09,
0x00, 0xad, 0x02, 0x00, 0x29, 0xff, 0x00, 0x5b,
0x0a, 0x06, 0x18, 0x6d, 0x09, 0x00, 0x8f, 0x81,
0x21, 0x00, 0xe2, 0x20, 0xa9, 0x7f, 0x8f, 0x83,
0x21, 0x00, 0xae, 0x04, 0x00, 0xad, 0x06, 0x00,
0x48, 0xab, 0xbd, 0x00, 0x00, 0xf0, 0x11, 0x8f,
0x80, 0x21, 0x00, 0xa9, 0x00, 0x69, 0x00, 0x09,
0x20, 0x8f, 0x80, 0x21, 0x00, 0xe8, 0x80, 0xea,
0xa9, 0x00, 0x48, 0xab, 0x60, 0xff, 0xc2, 0x10,
0xe2, 0x20, 0xad, 0x15, 0x00, 0x8d, 0x00, 0x43,
0xad, 0x12, 0x00, 0x8d, 0x01, 0x43, 0xad, 0x0f,
0x00, 0xae, 0x10, 0x00, 0x8e, 0x02, 0x43, 0x8d,
0x04, 0x43, 0xae, 0x13, 0x00, 0x8e, 0x05, 0x43,
0xa9, 0x01, 0x8d, 0x0b, 0x42, 0x60, 0xe2, 0x20,
0xc2, 0x10, 0x9c, 0x0b, 0x42, 0x9c, 0x0c, 0x42,
0x9c, 0x00, 0x42, 0x60, 0x77, 0x00, 0xee, 0xf2,
0x78, 0x18, 0xfb, 0x5c, 0x3b, 0x00, 0xc0, 0x08,
0xc2, 0x30, 0x48, 0xda, 0x5a, 0x0b, 0x8b, 0x22,
0x35, 0x00, 0xc0, 0xc2, 0x30, 0xab, 0x2b, 0x7a,
0xfa, 0x68, 0x28, 0x40, 0x08, 0xc2, 0x30, 0x48,
0xda, 0x5a, 0x0b, 0x8b, 0x22, 0x00, 0x00, 0xc0,
0xc2, 0x30, 0xab, 0x2b, 0x7a, 0xfa, 0x68, 0x28,
0x40, 0xcb, 0xaf, 0xef, 0xcd, 0xab, 0x80, 0xf9,
0x5b, 0x20, 0x1c, 0x76, 0x30, 0x2e, 0x31, 0x00,
0x00, 0x00, 0x5b, 0x20, 0x41, 0x00, 0x20, 0x3c,
0x64, 0x69, 0x72, 0x3e, 0x5b, 0x00, 0x0d, 0x4d,
0x52, 0x42, 0x4f, 0x4f, 0x54, 0x5b, 0x00, 0x0a,
0x53, 0x44, 0x32, 0x53, 0x4e, 0x45, 0x53, 0x20,
0x42, 0x4f, 0x4f, 0x54, 0x5b, 0x20, 0x09, 0x31,
0x02, 0x06, 0x03, 0x09, 0x33, 0x00, 0x4f, 0x87,
0xb0, 0x78, 0x5b, 0x00, 0x04, 0x31, 0xff, 0x31,
0xff, 0x31, 0xff, 0x1c, 0xff, 0x00, 0x00, 0x07,
0xff, 0x5b, 0x00, 0x04, 0x31, 0xff, 0x00, 0x00,
0x31, 0xff, 0x31, 0xff, 0x00, 0xff, 0x31, 0xff};
0xE2, 0x20, 0xC2, 0x10, 0xA9, 0x00, 0x48, 0xAB, 0xAD,
0x10, 0x42, 0xA2, 0x00, 0x58, 0x8E, 0x16, 0x21, 0xA9,
0x01, 0x8D, 0x15, 0x00, 0xA2, 0x00, 0xB0, 0xA9, 0x7F,
0x8E, 0x10, 0x00, 0x8D, 0x0F, 0x00, 0xA2, 0x00, 0x09,
0x8E, 0x13, 0x00, 0xA9, 0x18, 0x8D, 0x12, 0x00, 0x20,
0xDC, 0x0B, 0xA9, 0x01, 0x8D, 0x16, 0x00, 0x6B, 0xE2,
0x20, 0xAD, 0x11, 0x42, 0x6B, 0xE2, 0x20, 0xC2, 0x10,
0x78, 0x9C, 0x00, 0x42, 0x20, 0x2A, 0x01, 0xA9, 0x01,
0x8D, 0x0D, 0x42, 0x20, 0x84, 0x02, 0x20, 0x93, 0x01,
0x20, 0x8B, 0x01, 0x20, 0x04, 0x0C, 0x20, 0x57, 0x02,
0xA2, 0x41, 0x00, 0xA9, 0x00, 0xCA, 0x9F, 0x00, 0x70,
0x30, 0xD0, 0xF9, 0xA9, 0x7E, 0xA2, 0x1B, 0x00, 0x8D,
0x83, 0x21, 0x8E, 0x81, 0x21, 0xA9, 0x00, 0x8D, 0x15,
0x00, 0xA2, 0xBC, 0x00, 0xA9, 0xC0, 0x8E, 0x10, 0x00,
0x8D, 0x0F, 0x00, 0xA2, 0x6F, 0x00, 0x8E, 0x13, 0x00,
0xA9, 0x80, 0x8D, 0x12, 0x00, 0x20, 0xDC, 0x0B, 0xA9,
0x7E, 0xA2, 0x8B, 0x00, 0x8D, 0x83, 0x21, 0x8E, 0x81,
0x21, 0xA9, 0x00, 0x8D, 0x15, 0x00, 0xA2, 0x8C, 0x0B,
0xA9, 0xC0, 0x8E, 0x10, 0x00, 0x8D, 0x0F, 0x00, 0xA2,
0x4F, 0x00, 0x8E, 0x13, 0x00, 0xA9, 0x80, 0x8D, 0x12,
0x00, 0x20, 0xDC, 0x0B, 0x22, 0x1B, 0x00, 0x7E, 0xC2,
0x10, 0xE2, 0x20, 0xA9, 0x00, 0x8F, 0x00, 0x00, 0x7E,
0xA9, 0x0D, 0x8F, 0x02, 0x00, 0x7E, 0xA9, 0x30, 0x8F,
0x06, 0x00, 0x7E, 0xC2, 0x20, 0xA9, 0x00, 0x70, 0x8F,
0x04, 0x00, 0x7E, 0xE2, 0x20, 0xA9, 0x00, 0x8F, 0x07,
0x00, 0x7E, 0x20, 0x8B, 0x00, 0xC2, 0x20, 0xA9, 0x00,
0x58, 0x8D, 0x16, 0x21, 0xE2, 0x20, 0xA9, 0x01, 0x8D,
0x00, 0x43, 0xA9, 0x18, 0x8D, 0x01, 0x43, 0xA9, 0x7F,
0x8D, 0x04, 0x43, 0xA2, 0x00, 0xB0, 0x8E, 0x02, 0x43,
0xA2, 0x00, 0x09, 0x8E, 0x05, 0x43, 0xAF, 0x12, 0x42,
0x00, 0x29, 0x80, 0xD0, 0xF8, 0xAF, 0x12, 0x42, 0x00,
0x29, 0x80, 0xF0, 0xF8, 0xA9, 0x01, 0x8D, 0x0B, 0x42,
0x80, 0x9A, 0x58, 0x9C, 0x00, 0x42, 0x5C, 0x19, 0x00,
0x7E, 0x9C, 0x0B, 0x42, 0x9C, 0x0C, 0x42, 0x9C, 0x10,
0x43, 0x9C, 0x11, 0x43, 0x9C, 0x12, 0x43, 0x9C, 0x13,
0x43, 0x9C, 0x14, 0x43, 0x9C, 0x20, 0x43, 0x9C, 0x21,
0x43, 0x9C, 0x22, 0x43, 0x9C, 0x23, 0x43, 0x9C, 0x24,
0x43, 0x9C, 0x30, 0x43, 0x9C, 0x31, 0x43, 0x9C, 0x32,
0x43, 0x9C, 0x33, 0x43, 0x9C, 0x34, 0x43, 0x9C, 0x40,
0x43, 0x9C, 0x41, 0x43, 0x9C, 0x42, 0x43, 0x9C, 0x43,
0x43, 0x9C, 0x44, 0x43, 0x9C, 0x50, 0x43, 0x9C, 0x51,
0x43, 0x9C, 0x52, 0x43, 0x9C, 0x53, 0x43, 0x9C, 0x54,
0x43, 0x60, 0xAD, 0x12, 0x42, 0x29, 0x80, 0xD0, 0xF9,
0xAD, 0x12, 0x42, 0x29, 0x80, 0xF0, 0xF9, 0x60, 0xE2,
0x20, 0xC2, 0x10, 0x9C, 0x30, 0x21, 0x60, 0xE2, 0x20,
0xC2, 0x10, 0x9C, 0x00, 0x42, 0x9C, 0x0B, 0x42, 0x9C,
0x0C, 0x42, 0xA2, 0x00, 0xB0, 0x8E, 0x81, 0x21, 0xA9,
0x01, 0x8D, 0x83, 0x21, 0xA9, 0x08, 0x8D, 0x15, 0x00,
0xA2, 0x59, 0xFF, 0xA9, 0xC0, 0x8E, 0x10, 0x00, 0x8D,
0x0F, 0x00, 0xA2, 0x40, 0x07, 0x8E, 0x13, 0x00, 0xA9,
0x80, 0x8D, 0x12, 0x00, 0x20, 0xDC, 0x0B, 0xA2, 0x00,
0x00, 0x8E, 0x16, 0x21, 0xA9, 0x01, 0x8D, 0x15, 0x00,
0xA2, 0x7C, 0x03, 0xA9, 0xC0, 0x8E, 0x10, 0x00, 0x8D,
0x0F, 0x00, 0xA2, 0x00, 0x08, 0x8E, 0x13, 0x00, 0xA9,
0x18, 0x8D, 0x12, 0x00, 0x20, 0xDC, 0x0B, 0xA2, 0x00,
0x58, 0x8E, 0x16, 0x21, 0xA9, 0x09, 0x8D, 0x15, 0x00,
0xA2, 0x59, 0xFF, 0xA9, 0xC0, 0x8E, 0x10, 0x00, 0x8D,
0x0F, 0x00, 0xA2, 0x40, 0x07, 0x8E, 0x13, 0x00, 0xA9,
0x18, 0x8D, 0x12, 0x00, 0x20, 0xDC, 0x0B, 0xA2, 0x00,
0x00, 0x8E, 0x02, 0x21, 0xA9, 0x08, 0x8D, 0x15, 0x00,
0xA2, 0x59, 0xFF, 0xA9, 0xC0, 0x8E, 0x10, 0x00, 0x8D,
0x0F, 0x00, 0xA2, 0x20, 0x02, 0x8E, 0x13, 0x00, 0xA9,
0x04, 0x8D, 0x12, 0x00, 0x20, 0xDC, 0x0B, 0x9C, 0x21,
0x21, 0xA9, 0x00, 0x8D, 0x15, 0x00, 0xA2, 0x7C, 0x0B,
0xA9, 0xC0, 0x8E, 0x10, 0x00, 0x8D, 0x0F, 0x00, 0xA2,
0x10, 0x00, 0x8E, 0x13, 0x00, 0xA9, 0x22, 0x8D, 0x12,
0x00, 0x20, 0xDC, 0x0B, 0x60, 0xE2, 0x20, 0xC2, 0x10,
0xA9, 0x00, 0x8D, 0x05, 0x21, 0xA9, 0x58, 0x09, 0x02,
0x8D, 0x07, 0x21, 0xA9, 0x40, 0x8D, 0x0B, 0x21, 0xA9,
0x01, 0x8D, 0x2C, 0x21, 0xA9, 0x01, 0x8D, 0x2D, 0x21,
0xA9, 0x00, 0x8D, 0x30, 0x21, 0x9C, 0x21, 0x21, 0xA9,
0x0F, 0x8D, 0x00, 0x21, 0x60, 0xE2, 0x20, 0xC2, 0x10,
0x9C, 0x00, 0x42, 0xA9, 0xFF, 0x8D, 0x01, 0x42, 0x9C,
0x02, 0x42, 0x9C, 0x03, 0x42, 0x9C, 0x04, 0x42, 0x9C,
0x05, 0x42, 0x9C, 0x06, 0x42, 0x9C, 0x07, 0x42, 0x9C,
0x08, 0x42, 0x9C, 0x09, 0x42, 0x9C, 0x0A, 0x42, 0x9C,
0x0B, 0x42, 0x9C, 0x0C, 0x42, 0xA9, 0x00, 0x8D, 0x0D,
0x42, 0xA9, 0x8F, 0x8D, 0x00, 0x21, 0xA9, 0x03, 0x8D,
0x01, 0x21, 0x9C, 0x02, 0x21, 0x9C, 0x03, 0x21, 0x9C,
0x05, 0x21, 0x9C, 0x06, 0x21, 0x9C, 0x07, 0x21, 0x9C,
0x08, 0x21, 0x9C, 0x09, 0x21, 0x9C, 0x0A, 0x21, 0x9C,
0x0B, 0x21, 0x9C, 0x0C, 0x21, 0x9C, 0x0D, 0x21, 0x9C,
0x0D, 0x21, 0x9C, 0x0E, 0x21, 0x9C, 0x0E, 0x21, 0x9C,
0x0F, 0x21, 0x9C, 0x0F, 0x21, 0xA9, 0x05, 0x8D, 0x10,
0x21, 0x9C, 0x10, 0x21, 0x9C, 0x11, 0x21, 0x9C, 0x11,
0x21, 0x9C, 0x12, 0x21, 0x9C, 0x12, 0x21, 0x9C, 0x13,
0x21, 0x9C, 0x13, 0x21, 0x9C, 0x14, 0x21, 0x9C, 0x14,
0x21, 0xA9, 0x80, 0x8D, 0x15, 0x21, 0x9C, 0x16, 0x21,
0x9C, 0x17, 0x21, 0x9C, 0x1A, 0x21, 0x9C, 0x1B, 0x21,
0xA9, 0x01, 0x8D, 0x1B, 0x21, 0x9C, 0x1C, 0x21, 0x9C,
0x1C, 0x21, 0x9C, 0x1D, 0x21, 0x9C, 0x1D, 0x21, 0x9C,
0x1E, 0x21, 0x8D, 0x1E, 0x21, 0x9C, 0x1F, 0x21, 0x9C,
0x1F, 0x21, 0x9C, 0x20, 0x21, 0x9C, 0x20, 0x21, 0x9C,
0x21, 0x21, 0x9C, 0x23, 0x21, 0x9C, 0x24, 0x21, 0x9C,
0x25, 0x21, 0x9C, 0x26, 0x21, 0x9C, 0x27, 0x21, 0x9C,
0x28, 0x21, 0x9C, 0x29, 0x21, 0x9C, 0x2A, 0x21, 0x9C,
0x2B, 0x21, 0x9C, 0x2C, 0x21, 0x9C, 0x2D, 0x21, 0x9C,
0x2E, 0x21, 0xA9, 0x30, 0x8D, 0x30, 0x21, 0x9C, 0x31,
0x21, 0xA9, 0xE0, 0x8D, 0x32, 0x21, 0x9C, 0x33, 0x21,
0x60, 0x77, 0x00, 0x11, 0x02, 0x30, 0x30, 0x48, 0x30,
0x48, 0x30, 0x48, 0x20, 0x58, 0x00, 0x30, 0x30, 0x48,
0x00, 0x30, 0x00, 0x6C, 0x6C, 0x92, 0x24, 0x5A, 0x00,
0x36, 0x5B, 0x00, 0x09, 0x6C, 0x6C, 0x92, 0xFE, 0x01,
0x6C, 0x92, 0xFE, 0x01, 0x6C, 0x92, 0x00, 0x6C, 0x00,
0x00, 0x10, 0x6C, 0x7C, 0xC6, 0xC6, 0x39, 0xF0, 0x0E,
0x1E, 0xE1, 0xC6, 0x39, 0x7C, 0xC6, 0x10, 0x6C, 0x42,
0xA5, 0xA4, 0x5A, 0x48, 0xB4, 0x10, 0x6C, 0x24, 0x5A,
0x4A, 0xB5, 0x84, 0x4A, 0x00, 0x84, 0x70, 0xC8, 0xC0,
0x34, 0xC4, 0x2E, 0x6E, 0xDB, 0xC4, 0x2A, 0xC4, 0x3A,
0x7C, 0xC6, 0x00, 0x7C, 0x00, 0x18, 0x18, 0x24, 0x10,
0x28, 0x00, 0x10, 0x5B, 0x00, 0x08, 0x18, 0x24, 0x30,
0x68, 0x30, 0x48, 0x30, 0x48, 0x30, 0x48, 0x30, 0x68,
0x18, 0x24, 0x00, 0x18, 0x30, 0x48, 0x18, 0x2C, 0x18,
0x24, 0x18, 0x24, 0x18, 0x24, 0x18, 0x2C, 0x30, 0x48,
0x00, 0x30, 0x00, 0x6C, 0x6C, 0x92, 0x38, 0x44, 0x7C,
0x82, 0x38, 0x44, 0x6C, 0x92, 0x00, 0x6C, 0x00, 0x00,
0x00, 0x18, 0x18, 0x24, 0x18, 0x66, 0x7E, 0x81, 0x18,
0x66, 0x18, 0x24, 0x00, 0x18, 0x5B, 0x00, 0x0B, 0x18,
0x18, 0x24, 0x18, 0x24, 0x10, 0x28, 0x5B, 0x00, 0x05,
0x7E, 0x7E, 0x81, 0x00, 0x7E, 0x5B, 0x00, 0x0F, 0x18,
0x18, 0x24, 0x18, 0x24, 0x00, 0x18, 0x03, 0x04, 0x06,
0x09, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x90,
0xC0, 0x20, 0x00, 0xC0, 0x7C, 0xC6, 0xE6, 0x39, 0xC6,
0x29, 0xC6, 0x29, 0xC6, 0x29, 0xCE, 0x39, 0x7C, 0xC6,
0x00, 0x7C, 0x18, 0x34, 0x18, 0x24, 0x18, 0x24, 0x18,
0x24, 0x18, 0x24, 0x18, 0x24, 0x18, 0x24, 0x00, 0x18,
0xFC, 0x06, 0x06, 0xF9, 0x06, 0x79, 0x7C, 0x86, 0xC0,
0xBC, 0xC0, 0x3E, 0xFE, 0x01, 0x00, 0xFE, 0xFC, 0x06,
0x06, 0xF9, 0x06, 0x39, 0x3C, 0x46, 0x06, 0x39, 0x06,
0xF9, 0xFC, 0x06, 0x00, 0xFC, 0xC6, 0x29, 0xC6, 0x29,
0xC6, 0x39, 0x7E, 0xC1, 0x06, 0x79, 0x06, 0x09, 0x06,
0x09, 0x00, 0x06, 0xFE, 0x01, 0xC0, 0x3E, 0xC0, 0x3C,
0xFC, 0x06, 0x06, 0xF9, 0x06, 0xF9, 0xFC, 0x06, 0x00,
0xF8, 0x7C, 0xC2, 0xC0, 0x3C, 0xC0, 0x3C, 0xFC, 0x06,
0xC6, 0x39, 0xC6, 0x39, 0x7C, 0xC6, 0x00, 0x7C, 0xFC,
0x06, 0x06, 0xF9, 0x06, 0x09, 0x06, 0x09, 0x06, 0x09,
0x06, 0x09, 0x06, 0x09, 0x00, 0x06, 0x7C, 0xC6, 0xC6,
0x39, 0xC6, 0x39, 0x7C, 0xC6, 0xC6, 0x39, 0xC6, 0x39,
0x7C, 0xC6, 0x00, 0x7C, 0x7C, 0xC6, 0xC6, 0x39, 0xC6,
0x39, 0x7E, 0xC1, 0x06, 0x79, 0x06, 0x79, 0x7C, 0x86,
0x00, 0x7C, 0x00, 0x00, 0x00, 0x30, 0x30, 0x48, 0x00,
0x30, 0x00, 0x30, 0x30, 0x48, 0x00, 0x30, 0x5B, 0x00,
0x05, 0x30, 0x30, 0x48, 0x00, 0x30, 0x00, 0x30, 0x30,
0x48, 0x20, 0x50, 0x00, 0x20, 0x00, 0x18, 0x18, 0x24,
0x30, 0x48, 0x60, 0x90, 0x30, 0x48, 0x18, 0x24, 0x00,
0x18, 0x5B, 0x00, 0x05, 0x3C, 0x3C, 0x42, 0x00, 0x3C,
0x00, 0x3C, 0x3C, 0x42, 0x00, 0x3C, 0x00, 0x00, 0x00,
0x30, 0x30, 0x48, 0x18, 0x24, 0x0C, 0x12, 0x18, 0x24,
0x30, 0x48, 0x00, 0x30, 0x00, 0x00, 0xF8, 0x0C, 0x0C,
0xF2, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x00, 0x30,
0x30, 0x48, 0x00, 0x30, 0x7C, 0xC6, 0xC6, 0x39, 0xC6,
0x39, 0xDE, 0x21, 0xDE, 0x21, 0xC0, 0x3E, 0x7E, 0xC1,
0x00, 0x7E, 0x7C, 0xC6, 0xC6, 0x39, 0xC6, 0x39, 0xDE,
0x21, 0xC6, 0x39, 0xC6, 0x29, 0xC6, 0x29, 0x00, 0xC6,
0xFC, 0x06, 0xC6, 0x39, 0xC6, 0x39, 0xDC, 0x26, 0xC6,
0x39, 0xC6, 0x39, 0xFC, 0x06, 0x00, 0xFC, 0x7E, 0xC1,
0xC0, 0x3E, 0xC0, 0x20, 0xC0, 0x20, 0xC0, 0x20, 0xC0,
0x3E, 0x7E, 0xC1, 0x00, 0x7E, 0xFC, 0x02, 0xC6, 0x3B,
0xC6, 0x29, 0xC6, 0x29, 0xC6, 0x29, 0xC6, 0x3B, 0xFC,
0x02, 0x00, 0xFC, 0xFE, 0x01, 0xC0, 0x3E, 0xC0, 0x38,
0xF8, 0x04, 0xC0, 0x38, 0xC0, 0x3E, 0xFE, 0x01, 0x00,
0xFE, 0xFE, 0x01, 0xC0, 0x3E, 0xC0, 0x38, 0xF8, 0x04,
0xC0, 0x38, 0xC0, 0x20, 0xC0, 0x20, 0x00, 0xC0, 0x7E,
0xC1, 0xC0, 0x3E, 0xC0, 0x2E, 0xCE, 0x33, 0xC6, 0x29,
0xC6, 0x39, 0x7C, 0xC6, 0x00, 0x7C, 0xC6, 0x29, 0xC6,
0x29, 0xC6, 0x39, 0xFE, 0x01, 0xC6, 0x39, 0xC6, 0x29,
0xC6, 0x29, 0x00, 0xC6, 0x18, 0x24, 0x18, 0x24, 0x18,
0x24, 0x18, 0x24, 0x18, 0x24, 0x18, 0x24, 0x18, 0x24,
0x00, 0x18, 0x0C, 0x12, 0x0C, 0x12, 0x0C, 0x12, 0x0C,
0x12, 0x0C, 0x12, 0x0C, 0xF6, 0xF8, 0x06, 0x00, 0xFC,
0xC6, 0x29, 0xC6, 0x29, 0xC6, 0x38, 0xFC, 0x06, 0xC6,
0x39, 0xC6, 0x29, 0xC6, 0x29, 0x00, 0xC7, 0xC0, 0x20,
0xC0, 0x20, 0xC0, 0x20, 0xC0, 0x20, 0xC0, 0x20, 0xC0,
0x3C, 0xFC, 0x02, 0x00, 0xFC, 0xEC, 0x16, 0xD6, 0x29,
0xD6, 0x29, 0xD6, 0x29, 0xC6, 0x39, 0xC6, 0x29, 0xC6,
0x29, 0x00, 0xC7, 0xFC, 0x06, 0xC6, 0x39, 0xC6, 0x29,
0xC6, 0x29, 0xC6, 0x29, 0xC6, 0x29, 0xC6, 0x29, 0x00,
0xC6, 0x7C, 0xC6, 0xC6, 0x39, 0xC6, 0x29, 0xC6, 0x29,
0xC6, 0x29, 0xC6, 0x39, 0x7C, 0xC6, 0x00, 0x7C, 0xFC,
0x06, 0xC6, 0x39, 0xC6, 0x29, 0xC6, 0x39, 0xFC, 0x06,
0xC0, 0x3C, 0xC0, 0x20, 0x00, 0xC0, 0x7C, 0x82, 0xC6,
0xBB, 0xC6, 0x29, 0xC6, 0x29, 0xC6, 0x29, 0xCE, 0x31,
0x7E, 0xC1, 0x00, 0x7E, 0xFC, 0x06, 0xC6, 0x39, 0xC6,
0x39, 0xFC, 0x06, 0xC6, 0x39, 0xC6, 0x29, 0xC6, 0x29,
0x00, 0xC6, 0x7E, 0xC1, 0xC0, 0x3E, 0xC0, 0x3C, 0x7C,
0xC6, 0x06, 0x79, 0x06, 0xF9, 0xFC, 0x06, 0x00, 0xFC,
0xFE, 0x01, 0x18, 0xE6, 0x18, 0x24, 0x18, 0x24, 0x18,
0x24, 0x18, 0x24, 0x18, 0x24, 0x00, 0x18, 0xC6, 0x29,
0xC6, 0x29, 0xC6, 0x29, 0xC6, 0x29, 0xC6, 0x29, 0xC6,
0x39, 0x7C, 0xC6, 0x00, 0x7C, 0xC6, 0x29, 0xC6, 0x29,
0xC6, 0x29, 0xC6, 0x29, 0x66, 0x99, 0x36, 0x49, 0x1E,
0x21, 0x00, 0x1F, 0xC6, 0x29, 0xC6, 0x29, 0xC6, 0x39,
0xD6, 0x29, 0xD6, 0x29, 0xD6, 0x29, 0x6E, 0xD1, 0x00,
0x6E, 0xC6, 0x29, 0xC6, 0x29, 0xC6, 0x39, 0x7C, 0xC6,
0xC6, 0x39, 0xC6, 0x29, 0xC6, 0x29, 0x00, 0xC6, 0xC6,
0x29, 0xC6, 0x29, 0xC6, 0x39, 0x7E, 0xC1, 0x06, 0x79,
0x06, 0xF9, 0xFC, 0x06, 0x00, 0xFC, 0xFE, 0x01, 0x06,
0xF9, 0x06, 0x79, 0x7C, 0xC6, 0xC0, 0x3C, 0xC0, 0x3E,
0xFE, 0x01, 0x00, 0xFE, 0x3C, 0x42, 0x30, 0x4C, 0x30,
0x48, 0x30, 0x48, 0x30, 0x48, 0x30, 0x4C, 0x3C, 0x42,
0x00, 0x3C, 0xC0, 0x20, 0x60, 0x90, 0x30, 0x48, 0x18,
0x24, 0x0C, 0x12, 0x06, 0x09, 0x03, 0x04, 0x00, 0x03,
0x3C, 0x42, 0x0C, 0x32, 0x0C, 0x12, 0x0C, 0x12, 0x0C,
0x12, 0x0C, 0x32, 0x3C, 0x42, 0x00, 0x3C, 0x18, 0x24,
0x3C, 0x66, 0x66, 0x99, 0x00, 0x66, 0x5B, 0x00, 0x13,
0x7E, 0x7E, 0x81, 0x00, 0x7E, 0x30, 0x48, 0x18, 0x24,
0x18, 0x24, 0x00, 0x18, 0x5B, 0x00, 0x0B, 0x7C, 0x7C,
0x86, 0x06, 0x79, 0x7E, 0xC1, 0xC6, 0x39, 0x7E, 0xC1,
0x00, 0x7E, 0xC0, 0x20, 0xC0, 0x3C, 0xFC, 0x06, 0xC6,
0x39, 0xC6, 0x29, 0xC6, 0x39, 0xFC, 0x06, 0x00, 0xFC,
0x00, 0x00, 0x00, 0x7E, 0x7E, 0xC1, 0xC0, 0x3E, 0xC0,
0x20, 0xC0, 0x3E, 0x7E, 0xC1, 0x00, 0x7E, 0x06, 0x09,
0x06, 0x79, 0x7E, 0xC1, 0xC6, 0x39, 0xC6, 0x29, 0xC6,
0x39, 0x7E, 0xC1, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x7C,
0x7C, 0xC6, 0xC6, 0x39, 0xFE, 0x01, 0xC0, 0x3E, 0x7E,
0xC3, 0x00, 0x7E, 0x1E, 0x21, 0x30, 0x6E, 0x30, 0x4C,
0x3C, 0x42, 0x30, 0x4C, 0x30, 0x48, 0x30, 0x48, 0x30,
0x48, 0x00, 0x00, 0x00, 0x7E, 0x7E, 0xC1, 0xC6, 0x39,
0xC6, 0x39, 0x7E, 0xC1, 0x06, 0x79, 0x7C, 0x86, 0xC0,
0x20, 0xC0, 0x3C, 0xFC, 0x06, 0xC6, 0x39, 0xC6, 0x29,
0xC6, 0x29, 0xC6, 0x29, 0x00, 0xC6, 0x00, 0x18, 0x18,
0x24, 0x00, 0x18, 0x18, 0x24, 0x18, 0x24, 0x18, 0x24,
0x18, 0x24, 0x00, 0x18, 0x00, 0x18, 0x18, 0x24, 0x00,
0x18, 0x18, 0x24, 0x18, 0x24, 0x18, 0x24, 0x18, 0x2C,
0x30, 0x48, 0xC0, 0x20, 0xC0, 0x26, 0xC6, 0x29, 0xC6,
0x2B, 0xFC, 0x06, 0xC6, 0x2B, 0xC6, 0x29, 0x00, 0xC7,
0x30, 0x48, 0x30, 0x48, 0x30, 0x48, 0x30, 0x48, 0x30,
0x48, 0x30, 0x68, 0x18, 0x24, 0x00, 0x1C, 0x00, 0x00,
0x00, 0xEC, 0xEC, 0x16, 0xD6, 0x29, 0xD6, 0x29, 0xD6,
0x29, 0xC6, 0x39, 0x00, 0xC7, 0x00, 0x00, 0x00, 0xFC,
0xFC, 0x06, 0xC6, 0x39, 0xC6, 0x29, 0xC6, 0x29, 0xC6,
0x29, 0x00, 0xC6, 0x00, 0x00, 0x00, 0x7C, 0x7C, 0xC6,
0xC6, 0x39, 0xC6, 0x29, 0xC6, 0x39, 0x7C, 0xC6, 0x00,
0x7C, 0x00, 0x00, 0x00, 0xFC, 0xFC, 0x06, 0xC6, 0x39,
0xC6, 0x39, 0xFC, 0x06, 0xC0, 0x3C, 0xC0, 0x20, 0x00,
0x00, 0x00, 0x7E, 0x7E, 0xC1, 0xC6, 0x39, 0xC6, 0x39,
0x7E, 0xC1, 0x06, 0x79, 0x06, 0x09, 0x00, 0x00, 0x00,
0x7C, 0x7C, 0xC2, 0xC0, 0x3C, 0xC0, 0x20, 0xC0, 0x20,
0xC0, 0x20, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x7E, 0x7E,
0xC1, 0xC0, 0x3E, 0x7C, 0xC6, 0x06, 0xF9, 0xFC, 0x06,
0x00, 0xFC, 0x30, 0x48, 0x30, 0x4C, 0x3C, 0x42, 0x30,
0x4C, 0x30, 0x48, 0x30, 0x4E, 0x1E, 0x31, 0x00, 0x1E,
0x00, 0x00, 0x00, 0xC6, 0xC6, 0x29, 0xC6, 0x29, 0xC6,
0x29, 0xC6, 0x39, 0x7C, 0xC6, 0x00, 0x7C, 0x00, 0x00,
0x00, 0xC6, 0xC6, 0x29, 0xC6, 0x29, 0x66, 0x99, 0x36,
0x49, 0x1E, 0x21, 0x00, 0x1E, 0x00, 0x00, 0x00, 0xC6,
0xC6, 0x39, 0xD6, 0x29, 0xD6, 0x29, 0xD6, 0x29, 0x6E,
0xD1, 0x00, 0x6E, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0x29,
0xC6, 0x39, 0x7C, 0xC6, 0xC6, 0x39, 0xC6, 0x29, 0x00,
0xC6, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0x29, 0xC6, 0x39,
0x7E, 0xC1, 0x06, 0x79, 0x06, 0xF9, 0xFC, 0x06, 0x00,
0x00, 0x00, 0xFE, 0xFE, 0x01, 0x06, 0xF9, 0x7C, 0xC6,
0xC0, 0x3E, 0xFE, 0x01, 0x00, 0xFE, 0x18, 0x24, 0x30,
0x48, 0x30, 0x48, 0x70, 0x88, 0x30, 0x48, 0x30, 0x48,
0x18, 0x24, 0x00, 0x18, 0x18, 0x24, 0x18, 0x24, 0x18,
0x24, 0x00, 0x18, 0x18, 0x24, 0x18, 0x24, 0x18, 0x24,
0x00, 0x18, 0x30, 0x48, 0x18, 0x24, 0x18, 0x24, 0x1C,
0x22, 0x18, 0x24, 0x18, 0x24, 0x30, 0x48, 0x00, 0x30,
0x00, 0x00, 0x00, 0x72, 0x72, 0x9D, 0xFE, 0x01, 0x9C,
0x72, 0x00, 0x9C, 0x5B, 0x00, 0x14, 0x42, 0x08, 0xFF,
0x7F, 0x00, 0x00, 0x9C, 0x73, 0x42, 0x08, 0xFF, 0x43,
0x00, 0x00, 0x18, 0x63, 0xC2, 0x30, 0xAD, 0x00, 0x00,
0x29, 0xFF, 0x00, 0x0A, 0x18, 0x69, 0x00, 0xB0, 0x8D,
0x09, 0x00, 0xAD, 0x02, 0x00, 0x29, 0xFF, 0x00, 0x5B,
0x0A, 0x06, 0x18, 0x6D, 0x09, 0x00, 0x8F, 0x81, 0x21,
0x00, 0xE2, 0x20, 0xA9, 0x7F, 0x8F, 0x83, 0x21, 0x00,
0xAE, 0x04, 0x00, 0xAD, 0x06, 0x00, 0x48, 0xAB, 0xBD,
0x00, 0x00, 0xF0, 0x11, 0x8F, 0x80, 0x21, 0x00, 0xA9,
0x00, 0x69, 0x00, 0x09, 0x20, 0x8F, 0x80, 0x21, 0x00,
0xE8, 0x80, 0xEA, 0xA9, 0x00, 0x48, 0xAB, 0x60, 0xFF,
0xC2, 0x10, 0xE2, 0x20, 0xAD, 0x15, 0x00, 0x8D, 0x00,
0x43, 0xAD, 0x12, 0x00, 0x8D, 0x01, 0x43, 0xAD, 0x0F,
0x00, 0xAE, 0x10, 0x00, 0x8E, 0x02, 0x43, 0x8D, 0x04,
0x43, 0xAE, 0x13, 0x00, 0x8E, 0x05, 0x43, 0xA9, 0x01,
0x8D, 0x0B, 0x42, 0x60, 0xE2, 0x20, 0xC2, 0x10, 0x9C,
0x0B, 0x42, 0x9C, 0x0C, 0x42, 0x9C, 0x00, 0x42, 0x60,
0x77, 0x00, 0xEE, 0xF2, 0x78, 0x18, 0xFB, 0x5C, 0x3B,
0x00, 0xC0, 0x08, 0xC2, 0x30, 0x48, 0xDA, 0x5A, 0x0B,
0x8B, 0x22, 0x35, 0x00, 0xC0, 0xC2, 0x30, 0xAB, 0x2B,
0x7A, 0xFA, 0x68, 0x28, 0x40, 0x08, 0xC2, 0x30, 0x48,
0xDA, 0x5A, 0x0B, 0x8B, 0x22, 0x00, 0x00, 0xC0, 0xC2,
0x30, 0xAB, 0x2B, 0x7A, 0xFA, 0x68, 0x28, 0x40, 0xCB,
0xAF, 0xEF, 0xCD, 0xAB, 0x80, 0xF9, 0x5B, 0x20, 0x1C,
0x76, 0x30, 0x2E, 0x31, 0x00, 0x00, 0x00, 0x5B, 0x20,
0x41, 0x00, 0x20, 0x3C, 0x64, 0x69, 0x72, 0x3E, 0x5B,
0x00, 0x0D, 0x4D, 0x52, 0x42, 0x4F, 0x4F, 0x54, 0x5B,
0x00, 0x0A, 0x53, 0x44, 0x32, 0x53, 0x4E, 0x45, 0x53,
0x20, 0x42, 0x4F, 0x4F, 0x54, 0x5B, 0x20, 0x09, 0x31,
0x02, 0x06, 0x03, 0x09, 0x33, 0x00, 0x4F, 0x87, 0xB0,
0x78, 0x5B, 0x00, 0x04, 0x31, 0xFF, 0x31, 0xFF, 0x31,
0xFF, 0x1C, 0xFF, 0x00, 0x00, 0x07, 0xFF, 0x5B, 0x00,
0x04, 0x31, 0xFF, 0x00, 0x00, 0x31, 0xFF, 0x31, 0xFF,
0x00, 0xFF, 0x31, 0xFF, 0xFF,
};

View File

@ -7,120 +7,163 @@
#include "memory.h"
#include "sort.h"
/*
heap sort algorithm for data located outside RAM
/*
heap sort algorithm for data located outside RAM
addr: start address of pointer table
i: index (in 32-bit elements)
heapsize: size of heap (in 32-bit elements)
*/
uint32_t stat_getstring = 0;
static char sort_str1[SORT_STRLEN+1], sort_str2[SORT_STRLEN+1];
static char sort_str1[SORT_STRLEN + 1], sort_str2[SORT_STRLEN + 1];
uint32_t ptrcache[QSORT_MAXELEM] IN_AHBRAM;
/* get element from pointer table in external RAM*/
uint32_t sort_get_elem(uint32_t base, unsigned int index) {
return sram_readlong(base+4*index);
uint32_t sort_get_elem( uint32_t base, unsigned int index )
{
return sram_readlong( base + 4 * index );
}
/* put element from pointer table in external RAM */
void sort_put_elem(uint32_t base, unsigned int index, uint32_t elem) {
sram_writelong(elem, base+4*index);
void sort_put_elem( uint32_t base, unsigned int index, uint32_t elem )
{
sram_writelong( elem, base + 4 * index );
}
/* compare strings pointed to by elements of pointer table */
int sort_cmp_idx(uint32_t base, unsigned int index1, unsigned int index2) {
uint32_t elem1, elem2;
elem1 = sort_get_elem(base, index1);
elem2 = sort_get_elem(base, index2);
return sort_cmp_elem((void*)&elem1, (void*)&elem2);
int sort_cmp_idx( uint32_t base, unsigned int index1, unsigned int index2 )
{
uint32_t elem1, elem2;
elem1 = sort_get_elem( base, index1 );
elem2 = sort_get_elem( base, index2 );
return sort_cmp_elem( ( void * )&elem1, ( void * )&elem2 );
}
int sort_cmp_elem(const void* elem1, const void* elem2) {
uint32_t el1 = *(uint32_t*)elem1;
uint32_t el2 = *(uint32_t*)elem2;
sort_getstring_for_dirent(sort_str1, el1);
sort_getstring_for_dirent(sort_str2, el2);
/*printf("i1=%d i2=%d elem1=%lx elem2=%lx ; compare %s --- %s\n", index1, index2, elem1, elem2, sort_str1, sort_str2); */
int sort_cmp_elem( const void *elem1, const void *elem2 )
{
uint32_t el1 = *( uint32_t * )elem1;
uint32_t el2 = *( uint32_t * )elem2;
sort_getstring_for_dirent( sort_str1, el1 );
sort_getstring_for_dirent( sort_str2, el2 );
/*printf("i1=%d i2=%d elem1=%lx elem2=%lx ; compare %s --- %s\n", index1, index2, elem1, elem2, sort_str1, sort_str2); */
if ((el1 & 0x80000000) && !(el2 & 0x80000000)) {
return -1;
}
if ( ( el1 & 0x80000000 ) && !( el2 & 0x80000000 ) )
{
return -1;
}
if (!(el1 & 0x80000000) && (el2 & 0x80000000)) {
return 1;
}
if ( !( el1 & 0x80000000 ) && ( el2 & 0x80000000 ) )
{
return 1;
}
if (*sort_str1 == '.') return -1;
if (*sort_str2 == '.') return 1;
if ( *sort_str1 == '.' )
{
return -1;
}
/* Do not compare trailing slashes of directory names */
if ((el1 & 0x80000000) && (el2 & 0x80000000)) {
char *str1_slash = strrchr(sort_str1, '/');
char *str2_slash = strrchr(sort_str2, '/');
if(str1_slash != NULL) *str1_slash = 0;
if(str2_slash != NULL) *str2_slash = 0;
}
if ( *sort_str2 == '.' )
{
return 1;
}
return strcasecmp(sort_str1, sort_str2);
/* Do not compare trailing slashes of directory names */
if ( ( el1 & 0x80000000 ) && ( el2 & 0x80000000 ) )
{
char *str1_slash = strrchr( sort_str1, '/' );
char *str2_slash = strrchr( sort_str2, '/' );
if ( str1_slash != NULL )
{
*str1_slash = 0;
}
if ( str2_slash != NULL )
{
*str2_slash = 0;
}
}
return strcasecmp( sort_str1, sort_str2 );
}
/* get truncated string from database */
void sort_getstring_for_dirent(char *ptr, uint32_t addr) {
uint8_t leaf_offset;
if(addr & 0x80000000) {
/* is directory link, name offset 4 */
leaf_offset = sram_readbyte(addr + 4 + SRAM_MENU_ADDR);
sram_readstrn(ptr, addr + 5 + leaf_offset + SRAM_MENU_ADDR, SORT_STRLEN);
} else {
/* is file link, name offset 6 */
leaf_offset = sram_readbyte(addr + 6 + SRAM_MENU_ADDR);
sram_readstrn(ptr, addr + 7 + leaf_offset + SRAM_MENU_ADDR, SORT_STRLEN);
}
}
void sort_heapify(uint32_t addr, unsigned int i, unsigned int heapsize)
void sort_getstring_for_dirent( char *ptr, uint32_t addr )
{
while(1) {
unsigned int l = 2*i+1;
unsigned int r = 2*i+2;
unsigned int largest = (l < heapsize && sort_cmp_idx(addr, i, l) < 0) ? l : i;
uint8_t leaf_offset;
if(r < heapsize && sort_cmp_idx(addr, largest, r) < 0)
largest = r;
if(largest != i) {
uint32_t tmp = sort_get_elem(addr, i);
sort_put_elem(addr, i, sort_get_elem(addr, largest));
sort_put_elem(addr, largest, tmp);
i = largest;
if ( addr & 0x80000000 )
{
/* is directory link, name offset 4 */
leaf_offset = sram_readbyte( addr + 4 + SRAM_MENU_ADDR );
sram_readstrn( ptr, addr + 5 + leaf_offset + SRAM_MENU_ADDR, SORT_STRLEN );
}
else
{
/* is file link, name offset 6 */
leaf_offset = sram_readbyte( addr + 6 + SRAM_MENU_ADDR );
sram_readstrn( ptr, addr + 7 + leaf_offset + SRAM_MENU_ADDR, SORT_STRLEN );
}
else break;
}
}
void sort_dir(uint32_t addr, unsigned int size)
void sort_heapify( uint32_t addr, unsigned int i, unsigned int heapsize )
{
stat_getstring=0;
if(size > QSORT_MAXELEM) {
printf("more than %d dir entries, doing slower in-place sort\n", QSORT_MAXELEM);
ext_heapsort(addr, size);
} else {
/* retrieve, sort, and store dir table */
sram_readblock(ptrcache, addr, size*4);
qsort((void*)ptrcache, size, 4, sort_cmp_elem);
sram_writeblock(ptrcache, addr, size*4);
}
while ( 1 )
{
unsigned int l = 2 * i + 1;
unsigned int r = 2 * i + 2;
unsigned int largest = ( l < heapsize && sort_cmp_idx( addr, i, l ) < 0 ) ? l : i;
if ( r < heapsize && sort_cmp_idx( addr, largest, r ) < 0 )
{
largest = r;
}
if ( largest != i )
{
uint32_t tmp = sort_get_elem( addr, i );
sort_put_elem( addr, i, sort_get_elem( addr, largest ) );
sort_put_elem( addr, largest, tmp );
i = largest;
}
else
{
break;
}
}
}
void ext_heapsort(uint32_t addr, unsigned int size) {
for(unsigned int i = size/2; i > 0;) sort_heapify(addr, --i, size);
void sort_dir( uint32_t addr, unsigned int size )
{
stat_getstring = 0;
for(unsigned int i = size-1; i>0; --i) {
uint32_t tmp = sort_get_elem(addr, 0);
sort_put_elem(addr, 0, sort_get_elem(addr, i));
sort_put_elem(addr, i, tmp);
sort_heapify(addr, 0, i);
}
if ( size > QSORT_MAXELEM )
{
printf( "more than %d dir entries, doing slower in-place sort\n", QSORT_MAXELEM );
ext_heapsort( addr, size );
}
else
{
/* retrieve, sort, and store dir table */
sram_readblock( ptrcache, addr, size * 4 );
qsort( ( void * )ptrcache, size, 4, sort_cmp_elem );
sram_writeblock( ptrcache, addr, size * 4 );
}
}
void ext_heapsort( uint32_t addr, unsigned int size )
{
for ( unsigned int i = size / 2; i > 0; )
{
sort_heapify( addr, --i, size );
}
for ( unsigned int i = size - 1; i > 0; --i )
{
uint32_t tmp = sort_get_elem( addr, 0 );
sort_put_elem( addr, 0, sort_get_elem( addr, i ) );
sort_put_elem( addr, i, tmp );
sort_heapify( addr, 0, i );
}
}

View File

@ -3,13 +3,13 @@
#include <arm/NXP/LPC17xx/LPC17xx.h>
uint32_t sort_get_elem(uint32_t base, unsigned int index);
void sort_put_elem(uint32_t base, unsigned int index, uint32_t elem);
int sort_cmp_idx(uint32_t base, unsigned int index1, unsigned int index2);
int sort_cmp_elem(const void* elem1, const void* elem2);
void sort_getstring_for_dirent(char *ptr, uint32_t addr);
void sort_getlong_for_dirent(uint32_t* ptr, uint32_t addr);
void sort_heapify(uint32_t addr, unsigned int i, unsigned int heapsize);
void sort_dir(uint32_t addr, unsigned int size);
void ext_heapsort(uint32_t addr, unsigned int size);
uint32_t sort_get_elem( uint32_t base, unsigned int index );
void sort_put_elem( uint32_t base, unsigned int index, uint32_t elem );
int sort_cmp_idx( uint32_t base, unsigned int index1, unsigned int index2 );
int sort_cmp_elem( const void *elem1, const void *elem2 );
void sort_getstring_for_dirent( char *ptr, uint32_t addr );
void sort_getlong_for_dirent( uint32_t *ptr, uint32_t addr );
void sort_heapify( uint32_t addr, unsigned int i, unsigned int heapsize );
void sort_dir( uint32_t addr, unsigned int size );
void ext_heapsort( uint32_t addr, unsigned int size );
#endif

288
src/spi.c
View File

@ -30,154 +30,176 @@
#include "spi.h"
#include "uart.h"
void spi_preinit() {
/* Set clock prescaler to 1:1 */
BITBAND(LPC_SC->SSP_PCLKREG, SSP_PCLKBIT) = 1;
void spi_preinit()
{
/* Set clock prescaler to 1:1 */
BITBAND( LPC_SC->SSP_PCLKREG, SSP_PCLKBIT ) = 1;
}
void spi_init() {
void spi_init()
{
/* configure data format - 8 bits, SPI, CPOL=0, CPHA=0, 1 clock per bit */
SSP_REGS->CR0 = (8-1);
/* configure data format - 8 bits, SPI, CPOL=0, CPHA=0, 1 clock per bit */
SSP_REGS->CR0 = ( 8 - 1 );
/* set clock prescaler */
SSP_REGS->CPSR = SSP_CLK_DIVISOR;
/* set clock prescaler */
SSP_REGS->CPSR = SSP_CLK_DIVISOR;
/* Enable SSP */
SSP_REGS->CR1 = BV(1);
/* Enable SSP */
SSP_REGS->CR1 = BV( 1 );
/* Enable DMA controller, little-endian mode */
BITBAND(LPC_SC->PCONP, 29) = 1;
LPC_GPDMA->DMACConfig = 1;
/* Enable DMA controller, little-endian mode */
BITBAND( LPC_SC->PCONP, 29 ) = 1;
LPC_GPDMA->DMACConfig = 1;
}
void spi_tx_sync() {
/* Wait until TX fifo is flushed */
while (BITBAND(SSP_REGS->SR, SSP_BSY)) ;
void spi_tx_sync()
{
/* Wait until TX fifo is flushed */
while ( BITBAND( SSP_REGS->SR, SSP_BSY ) ) ;
}
void spi_tx_byte(uint8_t data) {
/* Wait until TX fifo can accept data */
while (!BITBAND(SSP_REGS->SR, SSP_TNF)) ;
void spi_tx_byte( uint8_t data )
{
/* Wait until TX fifo can accept data */
while ( !BITBAND( SSP_REGS->SR, SSP_TNF ) ) ;
/* Send byte */
SSP_REGS->DR = data;
/* Send byte */
SSP_REGS->DR = data;
}
uint8_t spi_txrx_byte(uint8_t data) {
/* Wait until SSP is not busy */
while (BITBAND(SSP_REGS->SR, SSP_BSY)) ;
uint8_t spi_txrx_byte( uint8_t data )
{
/* Wait until SSP is not busy */
while ( BITBAND( SSP_REGS->SR, SSP_BSY ) ) ;
/* Clear RX fifo */
while (BITBAND(SSP_REGS->SR, SSP_RNE))
(void) SSP_REGS->DR;
/* Transmit a single byte */
SSP_REGS->DR = data;
/* Wait until answer has been received */
while (!BITBAND(SSP_REGS->SR, SSP_RNE)) ;
return SSP_REGS->DR;
}
uint8_t spi_rx_byte() {
/* Wait until SSP is not busy */
while (BITBAND(SSP_REGS->SR, SSP_BSY)) ;
/* Clear RX fifo */
while (BITBAND(SSP_REGS->SR, SSP_RNE))
(void) SSP_REGS->DR;
/* Transmit a single dummy byte */
SSP_REGS->DR = 0xff;
/* Wait until answer has been received */
while (!BITBAND(SSP_REGS->SR, SSP_RNE)) ;
return SSP_REGS->DR;
}
void spi_tx_block(const void *ptr, unsigned int length) {
const uint8_t *data = (const uint8_t *)ptr;
while (length--) {
/* Wait until TX fifo can accept data */
while (!BITBAND(SSP_REGS->SR, SSP_TNF)) ;
SSP_REGS->DR = *data++;
}
}
void spi_rx_block(void *ptr, unsigned int length) {
uint8_t *data = (uint8_t *)ptr;
unsigned int txlen = length;
/* Wait until SSP is not busy */
while (BITBAND(SSP_REGS->SR, SSP_BSY)) ;
/* Clear RX fifo */
while (BITBAND(SSP_REGS->SR, SSP_RNE))
(void) SSP_REGS->DR;
if ((length & 3) != 0 || ((uint32_t)ptr & 3) != 0) {
/* Odd length or unaligned buffer */
while (length > 0) {
/* Wait until TX or RX FIFO are ready */
while (txlen > 0 && !BITBAND(SSP_REGS->SR, SSP_TNF) &&
!BITBAND(SSP_REGS->SR, SSP_RNE)) ;
/* Try to receive data */
while (length > 0 && BITBAND(SSP_REGS->SR, SSP_RNE)) {
*data++ = SSP_REGS->DR;
length--;
}
/* Send dummy data until TX full or RX ready */
while (txlen > 0 && BITBAND(SSP_REGS->SR, SSP_TNF) && !BITBAND(SSP_REGS->SR, SSP_RNE)) {
txlen--;
SSP_REGS->DR = 0xff;
}
}
} else {
/* Clear interrupt flags of DMA channels 0 */
LPC_GPDMA->DMACIntTCClear = BV(0);
LPC_GPDMA->DMACIntErrClr = BV(0);
/* Set up RX DMA channel */
SSP_DMACH->DMACCSrcAddr = (uint32_t)&SSP_REGS->DR;
SSP_DMACH->DMACCDestAddr = (uint32_t)ptr;
SSP_DMACH->DMACCLLI = 0; // no linked list
SSP_DMACH->DMACCControl = length
| (0 << 12) // source burst size 1 (FIXME: Check if larger possible/useful)
| (0 << 15) // destination burst size 1
| (0 << 18) // source transfer width 1 byte
| (2 << 21) // destination transfer width 4 bytes
| (0 << 26) // source address not incremented
| (1 << 27) // destination address incremented
;
SSP_DMACH->DMACCConfig = 1 // enable channel
| (SSP_DMAID_RX << 1) // data source SSP RX
| (2 << 11) // transfer from peripheral to memory
;
/* Enable RX FIFO DMA */
SSP_REGS->DMACR = 1;
/* Write <length> bytes into TX FIFO */
// FIXME: Any value in doing this using DMA too?
while (txlen > 0) {
while (txlen > 0 && BITBAND(SSP_REGS->SR, SSP_TNF)) {
txlen--;
SSP_REGS->DR = 0xff;
}
/* Clear RX fifo */
while ( BITBAND( SSP_REGS->SR, SSP_RNE ) )
{
( void ) SSP_REGS->DR;
}
/* Wait until DMA channel disables itself */
while (SSP_DMACH->DMACCConfig & 1) ;
/* Transmit a single byte */
SSP_REGS->DR = data;
/* Disable RX FIFO DMA */
SSP_REGS->DMACR = 0;
}
/* Wait until answer has been received */
while ( !BITBAND( SSP_REGS->SR, SSP_RNE ) ) ;
return SSP_REGS->DR;
}
uint8_t spi_rx_byte()
{
/* Wait until SSP is not busy */
while ( BITBAND( SSP_REGS->SR, SSP_BSY ) ) ;
/* Clear RX fifo */
while ( BITBAND( SSP_REGS->SR, SSP_RNE ) )
{
( void ) SSP_REGS->DR;
}
/* Transmit a single dummy byte */
SSP_REGS->DR = 0xff;
/* Wait until answer has been received */
while ( !BITBAND( SSP_REGS->SR, SSP_RNE ) ) ;
return SSP_REGS->DR;
}
void spi_tx_block( const void *ptr, unsigned int length )
{
const uint8_t *data = ( const uint8_t * )ptr;
while ( length-- )
{
/* Wait until TX fifo can accept data */
while ( !BITBAND( SSP_REGS->SR, SSP_TNF ) ) ;
SSP_REGS->DR = *data++;
}
}
void spi_rx_block( void *ptr, unsigned int length )
{
uint8_t *data = ( uint8_t * )ptr;
unsigned int txlen = length;
/* Wait until SSP is not busy */
while ( BITBAND( SSP_REGS->SR, SSP_BSY ) ) ;
/* Clear RX fifo */
while ( BITBAND( SSP_REGS->SR, SSP_RNE ) )
{
( void ) SSP_REGS->DR;
}
if ( ( length & 3 ) != 0 || ( ( uint32_t )ptr & 3 ) != 0 )
{
/* Odd length or unaligned buffer */
while ( length > 0 )
{
/* Wait until TX or RX FIFO are ready */
while ( txlen > 0 && !BITBAND( SSP_REGS->SR, SSP_TNF ) &&
!BITBAND( SSP_REGS->SR, SSP_RNE ) ) ;
/* Try to receive data */
while ( length > 0 && BITBAND( SSP_REGS->SR, SSP_RNE ) )
{
*data++ = SSP_REGS->DR;
length--;
}
/* Send dummy data until TX full or RX ready */
while ( txlen > 0 && BITBAND( SSP_REGS->SR, SSP_TNF ) && !BITBAND( SSP_REGS->SR, SSP_RNE ) )
{
txlen--;
SSP_REGS->DR = 0xff;
}
}
}
else
{
/* Clear interrupt flags of DMA channels 0 */
LPC_GPDMA->DMACIntTCClear = BV( 0 );
LPC_GPDMA->DMACIntErrClr = BV( 0 );
/* Set up RX DMA channel */
SSP_DMACH->DMACCSrcAddr = ( uint32_t )&SSP_REGS->DR;
SSP_DMACH->DMACCDestAddr = ( uint32_t )ptr;
SSP_DMACH->DMACCLLI = 0; // no linked list
SSP_DMACH->DMACCControl = length
| ( 0 << 12 ) // source burst size 1 (FIXME: Check if larger possible/useful)
| ( 0 << 15 ) // destination burst size 1
| ( 0 << 18 ) // source transfer width 1 byte
| ( 2 << 21 ) // destination transfer width 4 bytes
| ( 0 << 26 ) // source address not incremented
| ( 1 << 27 ) // destination address incremented
;
SSP_DMACH->DMACCConfig = 1 // enable channel
| ( SSP_DMAID_RX << 1 ) // data source SSP RX
| ( 2 << 11 ) // transfer from peripheral to memory
;
/* Enable RX FIFO DMA */
SSP_REGS->DMACR = 1;
/* Write <length> bytes into TX FIFO */
// FIXME: Any value in doing this using DMA too?
while ( txlen > 0 )
{
while ( txlen > 0 && BITBAND( SSP_REGS->SR, SSP_TNF ) )
{
txlen--;
SSP_REGS->DR = 0xff;
}
}
/* Wait until DMA channel disables itself */
while ( SSP_DMACH->DMACCConfig & 1 ) ;
/* Disable RX FIFO DMA */
SSP_REGS->DMACR = 0;
}
}

Some files were not shown because too many files have changed in this diff Show More