Compare commits

..

32 Commits

Author SHA1 Message Date
Maximilian Rehkopf
3cc8af1753 Menu: rename menu labels to "filesel", minor tweaks/fixes 2013-10-18 15:35:41 +02:00
Maximilian Rehkopf
c8b24a9618 Firmware: fix loading of partial-size BS dumps 2013-10-18 15:32:42 +02:00
Maximilian Rehkopf
c380ce9503 Adjust OpenOCD configuration for more recent versions 2013-10-18 15:31:25 +02:00
Maximilian Rehkopf
a734ae1ec5 pamper the compiler 2013-10-18 15:30:08 +02:00
Maximilian Rehkopf
f7d393451a Firmware: timeouts for FPGA configuration; LED flash codes for various FPGA related errors 2013-10-18 14:43:02 +02:00
Maximilian Rehkopf
28949ac307 Firmware: preparations for USB 2013-10-18 14:40:20 +02:00
Maximilian Rehkopf
4ff823078f Bootloader: fix flash buffer alignment 2013-10-18 14:37:36 +02:00
Maximilian Rehkopf
988d84954b Bootloader: change baud rate from 921600 to more common 115200 2013-10-18 14:37:12 +02:00
Maximilian Rehkopf
3f2e4e37db menu: rename menu.a65 to filesel.a65; add required library to README 2013-10-18 14:20:19 +02:00
Maximilian Rehkopf
39b07df47e Correct LoROM SRAM mapping for smaller ROMs
SRAM is sometimes mapped not just to 70:0000-7fff but also to
70:8000-ffff if ROM size permits it (i.e. the ROM is small enough
to avoid overlap).
Map SRAM to 8000-ffff if the ROM mask denotes a ROM <= 16 MBits.
2013-06-30 23:42:28 +02:00
Maximilian Rehkopf
78beed80d7 FPGA: fix BSX PSRAM mapping 2013-06-26 10:44:57 +02:00
Maximilian Rehkopf
f7aa9832c6 update changelog 2012-11-18 21:01:39 +01:00
Maximilian Rehkopf
7233278db2 Firmware: fix FPGA DMA call 2012-11-18 20:12:19 +01:00
Maximilian Rehkopf
443f7b138c Firmware: update version number to 0.1.5 2012-11-18 20:11:46 +01:00
Maximilian Rehkopf
e92ad06f38 FPGA/Cx4: slow down bus timing 2012-11-18 20:10:29 +01:00
Maximilian Rehkopf
fa1e09d867 FPGA: fix large SRAM mapping 2012-11-18 17:18:26 +01:00
Maximilian Rehkopf
e504079e5d FPGA: slow down bus timing 2012-11-07 22:32:33 +01:00
Maximilian Rehkopf
1f5af01bc0 FPGA: add BS-X "hole" (regs 09-0b) 2012-11-07 22:31:28 +01:00
Maximilian Rehkopf
648569d900 Firmware: fix big SRAM handling 2012-11-07 22:29:38 +01:00
Maximilian Rehkopf
b91b598758 Firmware: fix MSU1 main loop behaviour 2012-11-07 11:06:56 +01:00
Maximilian Rehkopf
04c3cbc7a2 Firmware: [debug] log file size after loading 2012-11-07 11:06:29 +01:00
Maximilian Rehkopf
c204aa9a0b Firmware/FPGA: replace magic numbers with constants 2012-11-07 11:03:58 +01:00
Maximilian Rehkopf
605fc2dfb1 Firmware: remove unused file sdcard.h 2012-11-07 09:54:30 +01:00
Maximilian Rehkopf
b67e2a5c77 Firmware: clean up clock/timer init 2012-11-07 09:44:50 +01:00
Maximilian Rehkopf
fee97e5016 Firmware/CLI: list short file name and file size in ls command; print file name when saving SRAM 2012-11-07 09:31:33 +01:00
Maximilian Rehkopf
ce23ff6954 Firmware/CLI: add memset command, rename 'resume' to 'exit' 2012-11-07 09:27:00 +01:00
Maximilian Rehkopf
83b18cc447 Firmware: fix compile errors with newer gccs 2012-11-07 09:23:50 +01:00
Maximilian Rehkopf
e33fbdf77f menu: Ignore input from non-standard controllers (resolve #29) 2012-09-30 00:24:48 +02:00
Maximilian Rehkopf
9287d637d1 FPGA: properly map large SRAM (LoROM > 32kB, HiROM > 8kB) 2012-09-24 22:52:05 +02:00
Maximilian Rehkopf
13c24bea9d FPGA: more accurate BS-X memory map 2012-09-24 22:49:54 +02:00
Maximilian Rehkopf
791b688f40 menu: fix #26: first note cut off on S-APU SNESes 2012-09-24 22:37:39 +02:00
Maximilian Rehkopf
5939b6e581 Firmware: sort by entire filename, not just first 20 characters 2012-08-25 19:36:24 +02:00
135 changed files with 16631 additions and 20918 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 menu.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 filesel.o65 pad.o65 time.o65 mainmenu.o65 sysinfo.o65 spc700.o65 spcplay.o65 # gfx.o65 # vars.o65
all: clean menu.bin map all: clean menu.bin map

View File

@ -2,8 +2,7 @@ version .byt " v0.1",0
zero .word 0 zero .word 0
bg2tile .byt $20 bg2tile .byt $20
space64 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
.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

@ -26,8 +26,7 @@ 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 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 .byt 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
@ -35,8 +34,7 @@ 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
loprint_wram 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 .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

@ -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_y .byt 0 ; pixel y position of select bar
bar_w .byt 0 ; bar width bar_w .byt 0 ; bar width
bar_wl .byt 0 ; bar width bar_wl .byt 0 ; bar width
menu_state .byt 0 ; menu state (0=file select) filesel_state .byt 0 ; menu state (0=file select)
menu_dirty .byt 0 ; menu dirty (e.g. after state change or when redraw is needed) filesel_dirty .byt 0 ; menu dirty (e.g. after state change or when redraw is needed)
menu_sel .word 0 ; selected item # filesel_sel .word 0 ; selected item #
cursor_x .byt 0 ; current cursor position (x) cursor_x .byt 0 ; current cursor position (x)
cursor_y .byt 0 ; current cursor position (y) cursor_y .byt 0 ; current cursor position (y)
fd_addr .word 0 ; address of current "file descriptor" fd_addr .word 0 ; address of current "file descriptor"
@ -96,6 +96,8 @@ barstep .byt 0 ; step size for bar
;-misc ;-misc
testvar .word 0,0,0,0 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 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 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 .byt 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

View File

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

View File

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

View File

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

View File

@ -55,7 +55,7 @@ TARGET = $(OBJDIR)/sd2snes
# List C source files here. (C dependencies are automatically generated.) # 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 tests.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
# usbcontrol.c usb_hid.c usbhw_lpc.c usbinit.c usbstdreq.c # usbcontrol.c usb_hid.c usbhw_lpc.c usbinit.c usbstdreq.c
@ -124,8 +124,7 @@ NM = $(ARCH)-nm
REMOVE = rm -f REMOVE = rm -f
COPY = cp COPY = cp
AWK = awk AWK = awk
RLE = ../utils/rle
BIN2H = utils/bin2h
#---------------- Compiler Options ---------------- #---------------- Compiler Options ----------------
# -g*: generate debugging information # -g*: generate debugging information
@ -198,7 +197,7 @@ ALL_ASFLAGS = -I. -x assembler-with-cpp $(ASFLAGS) $(CDEFS)
# Default target. # Default target.
all: build all: build
build: snesboot.h cfgware.h elf bin hex build: elf bin hex
$(E) " SIZE $(TARGET).elf" $(E) " SIZE $(TARGET).elf"
$(Q)$(ELFSIZE)|grep -v debug $(Q)$(ELFSIZE)|grep -v debug
cp $(TARGET).bin $(OBJDIR)/firmware.img cp $(TARGET).bin $(OBJDIR)/firmware.img
@ -218,37 +217,19 @@ sym: $(TARGET).sym
program: build program: build
utils/lpcchksum $(TARGET).bin utils/lpcchksum $(TARGET).bin
openocd -f interface/olimex-arm-usb-ocd.cfg -f lpc1754.cfg -f flash.cfg openocd -f openocd-usb.cfg -f lpc1754.cfg -f flash.cfg
debug: build debug: build
openocd -f interface/olimex-arm-usb-ocd.cfg -f lpc1754.cfg openocd -f openocd-usb.cfg -f lpc1754.cfg
reset: reset:
openocd -f interface/olimex-arm-usb-ocd.cfg -f lpc1754.cfg -f reset.cfg openocd -f openocd-usb.cfg -f lpc1754.cfg -f reset.cfg
# Display size of file. # Display size of file.
HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex
ELFSIZE = $(SIZE) -A $(TARGET).elf 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 # Generate autoconf.h from config
.PRECIOUS : $(OBJDIR)/autoconf.h .PRECIOUS : $(OBJDIR)/autoconf.h
@ -321,7 +302,6 @@ clean_list :
$(Q)$(REMOVE) $(TARGET).sym $(Q)$(REMOVE) $(TARGET).sym
$(Q)$(REMOVE) $(TARGET).lss $(Q)$(REMOVE) $(TARGET).lss
$(Q)$(REMOVE) $(OBJ) $(Q)$(REMOVE) $(OBJ)
$(Q)$(REMOVE) cfgware.h
$(Q)$(REMOVE) $(OBJDIR)/autoconf.h $(Q)$(REMOVE) $(OBJDIR)/autoconf.h
$(Q)$(REMOVE) $(OBJDIR)/*.bin $(Q)$(REMOVE) $(OBJDIR)/*.bin
$(Q)$(REMOVE) $(LST) $(Q)$(REMOVE) $(LST)

View File

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

View File

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

View File

@ -31,8 +31,7 @@
#if _CODE_PAGE == 437 #if _CODE_PAGE == 437
#define _TBLDEF 1 #define _TBLDEF 1
static static
const WCHAR Tbl[] = /* CP437(0x80-0xFF) to Unicode conversion table */ const WCHAR Tbl[] = { /* CP437(0x80-0xFF) to Unicode conversion table */
{
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
@ -54,8 +53,7 @@ const WCHAR Tbl[] = /* CP437(0x80-0xFF) to Unicode conversion table */
#elif _CODE_PAGE == 720 #elif _CODE_PAGE == 720
#define _TBLDEF 1 #define _TBLDEF 1
static static
const WCHAR Tbl[] = /* CP720(0x80-0xFF) to Unicode conversion table */ const WCHAR Tbl[] = { /* CP720(0x80-0xFF) to Unicode conversion table */
{
0x0000, 0x0000, 0x00E9, 0x00E2, 0x0000, 0x00E0, 0x0000, 0x00E7, 0x0000, 0x0000, 0x00E9, 0x00E2, 0x0000, 0x00E0, 0x0000, 0x00E7,
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0000, 0x0000, 0x0000, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0000, 0x0000, 0x0000,
0x0000, 0x0651, 0x0652, 0x00F4, 0x00A4, 0x0640, 0x00FB, 0x00F9, 0x0000, 0x0651, 0x0652, 0x00F4, 0x00A4, 0x0640, 0x00FB, 0x00F9,
@ -77,8 +75,7 @@ const WCHAR Tbl[] = /* CP720(0x80-0xFF) to Unicode conversion table */
#elif _CODE_PAGE == 737 #elif _CODE_PAGE == 737
#define _TBLDEF 1 #define _TBLDEF 1
static static
const WCHAR Tbl[] = /* CP737(0x80-0xFF) to Unicode conversion table */ const WCHAR Tbl[] = { /* CP737(0x80-0xFF) to Unicode conversion table */
{
0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398,
0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, 0x03A0, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, 0x03A0,
0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9, 0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9,
@ -100,8 +97,7 @@ const WCHAR Tbl[] = /* CP737(0x80-0xFF) to Unicode conversion table */
#elif _CODE_PAGE == 775 #elif _CODE_PAGE == 775
#define _TBLDEF 1 #define _TBLDEF 1
static static
const WCHAR Tbl[] = /* CP775(0x80-0xFF) to Unicode conversion table */ const WCHAR Tbl[] = { /* CP775(0x80-0xFF) to Unicode conversion table */
{
0x0106, 0x00FC, 0x00E9, 0x0101, 0x00E4, 0x0123, 0x00E5, 0x0107, 0x0106, 0x00FC, 0x00E9, 0x0101, 0x00E4, 0x0123, 0x00E5, 0x0107,
0x0142, 0x0113, 0x0156, 0x0157, 0x012B, 0x0179, 0x00C4, 0x00C5, 0x0142, 0x0113, 0x0156, 0x0157, 0x012B, 0x0179, 0x00C4, 0x00C5,
0x00C9, 0x00E6, 0x00C6, 0x014D, 0x00F6, 0x0122, 0x00A2, 0x015A, 0x00C9, 0x00E6, 0x00C6, 0x014D, 0x00F6, 0x0122, 0x00A2, 0x015A,
@ -123,8 +119,7 @@ const WCHAR Tbl[] = /* CP775(0x80-0xFF) to Unicode conversion table */
#elif _CODE_PAGE == 850 #elif _CODE_PAGE == 850
#define _TBLDEF 1 #define _TBLDEF 1
static static
const WCHAR Tbl[] = /* CP850(0x80-0xFF) to Unicode conversion table */ const WCHAR Tbl[] = { /* CP850(0x80-0xFF) to Unicode conversion table */
{
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
@ -146,8 +141,7 @@ const WCHAR Tbl[] = /* CP850(0x80-0xFF) to Unicode conversion table */
#elif _CODE_PAGE == 852 #elif _CODE_PAGE == 852
#define _TBLDEF 1 #define _TBLDEF 1
static static
const WCHAR Tbl[] = /* CP852(0x80-0xFF) to Unicode conversion table */ const WCHAR Tbl[] = { /* CP852(0x80-0xFF) to Unicode conversion table */
{
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x016F, 0x0107, 0x00E7, 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x016F, 0x0107, 0x00E7,
0x0142, 0x00EB, 0x0150, 0x0151, 0x00EE, 0x0179, 0x00C4, 0x0106, 0x0142, 0x00EB, 0x0150, 0x0151, 0x00EE, 0x0179, 0x00C4, 0x0106,
0x00C9, 0x0139, 0x013A, 0x00F4, 0x00F6, 0x013D, 0x013E, 0x015A, 0x00C9, 0x0139, 0x013A, 0x00F4, 0x00F6, 0x013D, 0x013E, 0x015A,
@ -169,8 +163,7 @@ const WCHAR Tbl[] = /* CP852(0x80-0xFF) to Unicode conversion table */
#elif _CODE_PAGE == 855 #elif _CODE_PAGE == 855
#define _TBLDEF 1 #define _TBLDEF 1
static static
const WCHAR Tbl[] = /* CP855(0x80-0xFF) to Unicode conversion table */ const WCHAR Tbl[] = { /* CP855(0x80-0xFF) to Unicode conversion table */
{
0x0452, 0x0402, 0x0453, 0x0403, 0x0451, 0x0401, 0x0454, 0x0404, 0x0452, 0x0402, 0x0453, 0x0403, 0x0451, 0x0401, 0x0454, 0x0404,
0x0455, 0x0405, 0x0456, 0x0406, 0x0457, 0x0407, 0x0458, 0x0408, 0x0455, 0x0405, 0x0456, 0x0406, 0x0457, 0x0407, 0x0458, 0x0408,
0x0459, 0x0409, 0x045A, 0x040A, 0x045B, 0x040B, 0x045C, 0x040C, 0x0459, 0x0409, 0x045A, 0x040A, 0x045B, 0x040B, 0x045C, 0x040C,
@ -192,8 +185,7 @@ const WCHAR Tbl[] = /* CP855(0x80-0xFF) to Unicode conversion table */
#elif _CODE_PAGE == 857 #elif _CODE_PAGE == 857
#define _TBLDEF 1 #define _TBLDEF 1
static static
const WCHAR Tbl[] = /* CP857(0x80-0xFF) to Unicode conversion table */ const WCHAR Tbl[] = { /* CP857(0x80-0xFF) to Unicode conversion table */
{
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0131, 0x00C4, 0x00C5, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0131, 0x00C4, 0x00C5,
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
@ -215,8 +207,7 @@ const WCHAR Tbl[] = /* CP857(0x80-0xFF) to Unicode conversion table */
#elif _CODE_PAGE == 858 #elif _CODE_PAGE == 858
#define _TBLDEF 1 #define _TBLDEF 1
static static
const WCHAR Tbl[] = /* CP858(0x80-0xFF) to Unicode conversion table */ const WCHAR Tbl[] = { /* CP858(0x80-0xFF) to Unicode conversion table */
{
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
@ -238,8 +229,7 @@ const WCHAR Tbl[] = /* CP858(0x80-0xFF) to Unicode conversion table */
#elif _CODE_PAGE == 862 #elif _CODE_PAGE == 862
#define _TBLDEF 1 #define _TBLDEF 1
static static
const WCHAR Tbl[] = /* CP862(0x80-0xFF) to Unicode conversion table */ const WCHAR Tbl[] = { /* CP862(0x80-0xFF) to Unicode conversion table */
{
0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7, 0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7,
0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF, 0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,
0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7, 0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7,
@ -261,8 +251,7 @@ const WCHAR Tbl[] = /* CP862(0x80-0xFF) to Unicode conversion table */
#elif _CODE_PAGE == 866 #elif _CODE_PAGE == 866
#define _TBLDEF 1 #define _TBLDEF 1
static static
const WCHAR Tbl[] = /* CP866(0x80-0xFF) to Unicode conversion table */ const WCHAR Tbl[] = { /* CP866(0x80-0xFF) to Unicode conversion table */
{
0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
@ -284,8 +273,7 @@ const WCHAR Tbl[] = /* CP866(0x80-0xFF) to Unicode conversion table */
#elif _CODE_PAGE == 874 #elif _CODE_PAGE == 874
#define _TBLDEF 1 #define _TBLDEF 1
static static
const WCHAR Tbl[] = /* CP874(0x80-0xFF) to Unicode conversion table */ const WCHAR Tbl[] = { /* CP874(0x80-0xFF) to Unicode conversion table */
{
0x20AC, 0x0000, 0x0000, 0x0000, 0x0000, 0x2026, 0x0000, 0x0000, 0x20AC, 0x0000, 0x0000, 0x0000, 0x0000, 0x2026, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
@ -307,8 +295,7 @@ const WCHAR Tbl[] = /* CP874(0x80-0xFF) to Unicode conversion table */
#elif _CODE_PAGE == 1250 #elif _CODE_PAGE == 1250
#define _TBLDEF 1 #define _TBLDEF 1
static static
const WCHAR Tbl[] = /* CP1250(0x80-0xFF) to Unicode conversion table */ const WCHAR Tbl[] = { /* CP1250(0x80-0xFF) to Unicode conversion table */
{
0x20AC, 0x0000, 0x201A, 0x0000, 0x201E, 0x2026, 0x2020, 0x2021, 0x20AC, 0x0000, 0x201A, 0x0000, 0x201E, 0x2026, 0x2020, 0x2021,
0x0000, 0x2030, 0x0160, 0x2039, 0x015A, 0x0164, 0x017D, 0x0179, 0x0000, 0x2030, 0x0160, 0x2039, 0x015A, 0x0164, 0x017D, 0x0179,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
@ -330,8 +317,7 @@ const WCHAR Tbl[] = /* CP1250(0x80-0xFF) to Unicode conversion table */
#elif _CODE_PAGE == 1251 #elif _CODE_PAGE == 1251
#define _TBLDEF 1 #define _TBLDEF 1
static static
const WCHAR Tbl[] = /* CP1251(0x80-0xFF) to Unicode conversion table */ const WCHAR Tbl[] = { /* CP1251(0x80-0xFF) to Unicode conversion table */
{
0x0402, 0x0403, 0x201A, 0x0453, 0x201E, 0x2026, 0x2020, 0x2021, 0x0402, 0x0403, 0x201A, 0x0453, 0x201E, 0x2026, 0x2020, 0x2021,
0x20AC, 0x2030, 0x0409, 0x2039, 0x040A, 0x040C, 0x040B, 0x040F, 0x20AC, 0x2030, 0x0409, 0x2039, 0x040A, 0x040C, 0x040B, 0x040F,
0x0452, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x0452, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
@ -353,8 +339,7 @@ const WCHAR Tbl[] = /* CP1251(0x80-0xFF) to Unicode conversion table */
#elif _CODE_PAGE == 1252 #elif _CODE_PAGE == 1252
#define _TBLDEF 1 #define _TBLDEF 1
static static
const WCHAR Tbl[] = /* CP1252(0x80-0xFF) to Unicode conversion table */ const WCHAR Tbl[] = { /* CP1252(0x80-0xFF) to Unicode conversion table */
{
0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, 0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x017D, 0x0000, 0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x017D, 0x0000,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
@ -376,8 +361,7 @@ const WCHAR Tbl[] = /* CP1252(0x80-0xFF) to Unicode conversion table */
#elif _CODE_PAGE == 1253 #elif _CODE_PAGE == 1253
#define _TBLDEF 1 #define _TBLDEF 1
static static
const WCHAR Tbl[] = /* CP1253(0x80-0xFF) to Unicode conversion table */ const WCHAR Tbl[] = { /* CP1253(0x80-0xFF) to Unicode conversion table */
{
0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, 0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
0x0000, 0x2030, 0x0000, 0x2039, 0x000C, 0x0000, 0x0000, 0x0000, 0x0000, 0x2030, 0x0000, 0x2039, 0x000C, 0x0000, 0x0000, 0x0000,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
@ -399,8 +383,7 @@ const WCHAR Tbl[] = /* CP1253(0x80-0xFF) to Unicode conversion table */
#elif _CODE_PAGE == 1254 #elif _CODE_PAGE == 1254
#define _TBLDEF 1 #define _TBLDEF 1
static static
const WCHAR Tbl[] = /* CP1254(0x80-0xFF) to Unicode conversion table */ const WCHAR Tbl[] = { /* CP1254(0x80-0xFF) to Unicode conversion table */
{
0x20AC, 0x0000, 0x210A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, 0x20AC, 0x0000, 0x210A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x0000, 0x0000, 0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x0000, 0x0000,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
@ -422,8 +405,7 @@ const WCHAR Tbl[] = /* CP1254(0x80-0xFF) to Unicode conversion table */
#elif _CODE_PAGE == 1255 #elif _CODE_PAGE == 1255
#define _TBLDEF 1 #define _TBLDEF 1
static static
const WCHAR Tbl[] = /* CP1255(0x80-0xFF) to Unicode conversion table */ const WCHAR Tbl[] = { /* CP1255(0x80-0xFF) to Unicode conversion table */
{
0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, 0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
0x02C6, 0x2030, 0x0000, 0x2039, 0x0000, 0x0000, 0x0000, 0x0000, 0x02C6, 0x2030, 0x0000, 0x2039, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
@ -445,8 +427,7 @@ const WCHAR Tbl[] = /* CP1255(0x80-0xFF) to Unicode conversion table */
#elif _CODE_PAGE == 1256 #elif _CODE_PAGE == 1256
#define _TBLDEF 1 #define _TBLDEF 1
static static
const WCHAR Tbl[] = /* CP1256(0x80-0xFF) to Unicode conversion table */ const WCHAR Tbl[] = { /* CP1256(0x80-0xFF) to Unicode conversion table */
{
0x20AC, 0x067E, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, 0x20AC, 0x067E, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
0x02C6, 0x2030, 0x0679, 0x2039, 0x0152, 0x0686, 0x0698, 0x0688, 0x02C6, 0x2030, 0x0679, 0x2039, 0x0152, 0x0686, 0x0698, 0x0688,
0x06AF, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x06AF, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
@ -468,8 +449,7 @@ const WCHAR Tbl[] = /* CP1256(0x80-0xFF) to Unicode conversion table */
#elif _CODE_PAGE == 1257 #elif _CODE_PAGE == 1257
#define _TBLDEF 1 #define _TBLDEF 1
static static
const WCHAR Tbl[] = /* CP1257(0x80-0xFF) to Unicode conversion table */ const WCHAR Tbl[] = { /* CP1257(0x80-0xFF) to Unicode conversion table */
{
0x20AC, 0x0000, 0x201A, 0x0000, 0x201E, 0x2026, 0x2020, 0x2021, 0x20AC, 0x0000, 0x201A, 0x0000, 0x201E, 0x2026, 0x2020, 0x2021,
0x0000, 0x2030, 0x0000, 0x2039, 0x0000, 0x00A8, 0x02C7, 0x00B8, 0x0000, 0x2030, 0x0000, 0x2039, 0x0000, 0x00A8, 0x02C7, 0x00B8,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
@ -491,8 +471,7 @@ const WCHAR Tbl[] = /* CP1257(0x80-0xFF) to Unicode conversion table */
#elif _CODE_PAGE == 1258 #elif _CODE_PAGE == 1258
#define _TBLDEF 1 #define _TBLDEF 1
static static
const WCHAR Tbl[] = /* CP1258(0x80-0xFF) to Unicode conversion table */ const WCHAR Tbl[] = { /* CP1258(0x80-0xFF) to Unicode conversion table */
{
0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, 0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
0x02C6, 0x2030, 0x0000, 0x2039, 0x0152, 0x0000, 0x0000, 0x0000, 0x02C6, 0x2030, 0x0000, 0x2039, 0x0152, 0x0000, 0x0000, 0x0000,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
@ -527,28 +506,17 @@ WCHAR ff_convert ( /* Converted character, Returns zero on error */
WCHAR c; WCHAR c;
if ( src < 0x80 ) /* ASCII */ if (src < 0x80) { /* ASCII */
{
c = src; c = src;
} } else {
else if (dir) { /* OEMCP to Unicode */
{
if ( dir ) /* OEMCP to Unicode */
{
c = (src >= 0x100) ? 0 : Tbl[src - 0x80]; c = (src >= 0x100) ? 0 : Tbl[src - 0x80];
} else { /* Unicode to OEMCP */
for (c = 0; c < 0x80; c++) {
if (src == Tbl[c]) break;
} }
else /* Unicode to OEMCP */
{
for ( c = 0; c < 0x80; c++ )
{
if ( src == Tbl[c] )
{
break;
}
}
c = (c + 0x80) & 0xFF; c = (c + 0x80) & 0xFF;
} }
} }

View File

@ -7,14 +7,12 @@
#include "bits.h" #include "bits.h"
#include "uart.h" #include "uart.h"
void clock_disconnect() void clock_disconnect() {
{
disconnectPLL0(); disconnectPLL0();
disablePLL0(); disablePLL0();
} }
void clock_init() void clock_init() {
{
/* set flash access time to 6 clks (safe setting) */ /* set flash access time to 6 clks (safe setting) */
setFlashAccessTime(6); setFlashAccessTime(6);
@ -56,67 +54,54 @@ void clock_init()
connectPLL0(); connectPLL0();
} }
void setFlashAccessTime( uint8_t clocks ) void setFlashAccessTime(uint8_t clocks) {
{
LPC_SC->FLASHCFG=FLASHTIM(clocks); LPC_SC->FLASHCFG=FLASHTIM(clocks);
} }
void setPLL0MultPrediv( uint16_t mult, uint8_t prediv ) void setPLL0MultPrediv(uint16_t mult, uint8_t prediv) {
{
LPC_SC->PLL0CFG=PLL_MULT(mult) | PLL_PREDIV(prediv); LPC_SC->PLL0CFG=PLL_MULT(mult) | PLL_PREDIV(prediv);
PLL0feed(); PLL0feed();
} }
void enablePLL0() void enablePLL0() {
{
LPC_SC->PLL0CON |= PLLE0; LPC_SC->PLL0CON |= PLLE0;
PLL0feed(); PLL0feed();
} }
void disablePLL0() void disablePLL0() {
{
LPC_SC->PLL0CON &= ~PLLE0; LPC_SC->PLL0CON &= ~PLLE0;
PLL0feed(); PLL0feed();
} }
void connectPLL0() void connectPLL0() {
{
while(!(LPC_SC->PLL0STAT&PLOCK0)); while(!(LPC_SC->PLL0STAT&PLOCK0));
LPC_SC->PLL0CON |= PLLC0; LPC_SC->PLL0CON |= PLLC0;
PLL0feed(); PLL0feed();
} }
void disconnectPLL0() void disconnectPLL0() {
{
LPC_SC->PLL0CON &= ~PLLC0; LPC_SC->PLL0CON &= ~PLLC0;
PLL0feed(); PLL0feed();
} }
void setCCLKDiv( uint8_t div ) void setCCLKDiv(uint8_t div) {
{
LPC_SC->CCLKCFG=CCLK_DIV(div); LPC_SC->CCLKCFG=CCLK_DIV(div);
} }
void enableMainOsc() void enableMainOsc() {
{
LPC_SC->SCS=OSCEN; LPC_SC->SCS=OSCEN;
while(!(LPC_SC->SCS&OSCSTAT)); while(!(LPC_SC->SCS&OSCSTAT));
} }
void disableMainOsc() void disableMainOsc() {
{
LPC_SC->SCS=0; LPC_SC->SCS=0;
} }
void PLL0feed() void PLL0feed() {
{
LPC_SC->PLL0FEED=0xaa; LPC_SC->PLL0FEED=0xaa;
LPC_SC->PLL0FEED=0x55; LPC_SC->PLL0FEED=0x55;
} }
void setClkSrc( uint8_t src ) void setClkSrc(uint8_t src) {
{
LPC_SC->CLKSRCSEL=src; LPC_SC->CLKSRCSEL=src;
} }

View File

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

View File

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

View File

@ -32,13 +32,11 @@ uint32_t crc_reflect( uint32_t data, size_t data_len )
uint32_t ret; uint32_t ret;
ret = data & 0x01; ret = data & 0x01;
for (i = 1; i < data_len; i++) for (i = 1; i < data_len; i++)
{ {
data >>= 1; data >>= 1;
ret = (ret << 1) | (data & 0x01); ret = (ret << 1) | (data & 0x01);
} }
return ret; return ret;
} }
@ -58,24 +56,16 @@ uint32_t crc32_update( uint32_t crc, const unsigned char data )
unsigned char c; unsigned char c;
c = data; c = data;
for (i = 0x01; i & 0xff; i <<= 1) {
for ( i = 0x01; i & 0xff; i <<= 1 )
{
bit = crc & 0x80000000; bit = crc & 0x80000000;
if (c & i) {
if ( c & i )
{
bit = !bit; bit = !bit;
} }
crc <<= 1; crc <<= 1;
if (bit) {
if ( bit )
{
crc ^= 0x04c11db7; crc ^= 0x04c11db7;
} }
} }
return crc & 0xffffffff; return crc & 0xffffffff;
} }

View File

@ -16,8 +16,7 @@
typedef BYTE DSTATUS; typedef BYTE DSTATUS;
/* Results of Disk Functions */ /* Results of Disk Functions */
typedef enum typedef enum {
{
RES_OK = 0, /* 0: Successful */ RES_OK = 0, /* 0: Successful */
RES_ERROR, /* 1: R/W Error */ RES_ERROR, /* 1: R/W Error */
RES_WRPRT, /* 2: Write Protected */ RES_WRPRT, /* 2: Write Protected */
@ -36,8 +35,7 @@ typedef enum
* This is the struct returned in the data buffer when disk_getinfo * This is the struct returned in the data buffer when disk_getinfo
* is called with page=0. * is called with page=0.
*/ */
typedef struct typedef struct {
{
uint8_t validbytes; uint8_t validbytes;
uint8_t maxpage; uint8_t maxpage;
uint8_t disktype; uint8_t disktype;

View File

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

@ -229,8 +229,7 @@ extern "C" {
#if _MULTI_PARTITION /* Multiple partition configuration */ #if _MULTI_PARTITION /* Multiple partition configuration */
#define LD2PD(vol) (VolToPart[vol].pd) /* Get physical drive# */ #define LD2PD(vol) (VolToPart[vol].pd) /* Get physical drive# */
#define LD2PT(vol) (VolToPart[vol].pt) /* Get partition# */ #define LD2PT(vol) (VolToPart[vol].pt) /* Get partition# */
typedef struct typedef struct {
{
BYTE pd; /* Physical drive# */ BYTE pd; /* Physical drive# */
BYTE pt; /* Partition # (0-3) */ BYTE pt; /* Partition # (0-3) */
} PARTITION; } PARTITION;
@ -269,8 +268,7 @@ typedef char TCHAR;
/* File system object structure (FATFS) */ /* File system object structure (FATFS) */
typedef struct typedef struct {
{
BYTE fs_type; /* FAT sub-type (0:Not mounted) */ BYTE fs_type; /* FAT sub-type (0:Not mounted) */
BYTE drv; /* Physical drive number */ BYTE drv; /* Physical drive number */
BYTE csize; /* Sectors per cluster (1,2,4...128) */ BYTE csize; /* Sectors per cluster (1,2,4...128) */
@ -306,8 +304,7 @@ typedef struct
/* File object structure (FIL) */ /* File object structure (FIL) */
typedef struct typedef struct {
{
FATFS* fs; /* Pointer to the owner file system object */ FATFS* fs; /* Pointer to the owner file system object */
WORD id; /* Owner file system mount ID */ WORD id; /* Owner file system mount ID */
BYTE flag; /* File status flags */ BYTE flag; /* File status flags */
@ -336,8 +333,7 @@ typedef struct
/* Directory object structure (DIR) */ /* Directory object structure (DIR) */
typedef struct typedef struct {
{
FATFS* fs; /* Pointer to the owner file system object */ FATFS* fs; /* Pointer to the owner file system object */
WORD id; /* Owner file system mount ID */ WORD id; /* Owner file system mount ID */
WORD index; /* Current read/write index number */ WORD index; /* Current read/write index number */
@ -356,8 +352,7 @@ typedef struct
/* File status structure (FILINFO) */ /* File status structure (FILINFO) */
typedef struct typedef struct {
{
DWORD fsize; /* File size */ DWORD fsize; /* File size */
WORD fdate; /* Last modified date */ WORD fdate; /* Last modified date */
WORD ftime; /* Last modified time */ WORD ftime; /* Last modified time */
@ -374,8 +369,7 @@ typedef struct
/* File function return code (FRESULT) */ /* File function return code (FRESULT) */
typedef enum typedef enum {
{
FR_OK = 0, /* (0) Succeeded */ FR_OK = 0, /* (0) Succeeded */
FR_DISK_ERR, /* (1) A hard error occured in the low level disk I/O layer */ FR_DISK_ERR, /* (1) A hard error occured in the low level disk I/O layer */
FR_INT_ERR, /* (2) Assertion failed */ FR_INT_ERR, /* (2) Assertion failed */
@ -403,8 +397,7 @@ typedef enum
/* FatFs module application interface */ /* FatFs module application interface */
/* Low Level functions */ /* Low Level functions */
FRESULT l_openfilebycluster( FATFS *fs, FIL *fp, 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 */
DWORD fsize ); /* Open a file by its start cluster using supplied file size */
/* application level functions */ /* application level functions */
FRESULT f_mount (BYTE, FATFS*); /* Mount/Unmount a logical drive */ FRESULT f_mount (BYTE, FATFS*); /* Mount/Unmount a logical drive */

View File

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

View File

@ -31,14 +31,13 @@
enum filestates { FILE_OK=0, FILE_ERR, FILE_EOF }; enum filestates { FILE_OK=0, FILE_ERR, FILE_EOF };
#define GCC_ALIGN_WORKAROUND __attribute__ ((aligned(4))) BYTE file_buf[512] __attribute__((aligned(4)));
extern BYTE file_buf[512]; FATFS fatfs;
extern FATFS fatfs; FIL file_handle;
extern FIL file_handle; FRESULT file_res;
extern FRESULT file_res; uint8_t file_lfn[258];
extern uint8_t file_lfn[258]; uint16_t file_block_off, file_block_max;
extern uint16_t file_block_off, file_block_max; enum filestates file_status;
extern enum filestates file_status;
void file_init(void); void file_init(void);
void file_open(uint8_t* filename, BYTE flags); void file_open(uint8_t* filename, BYTE flags);

View File

@ -14,103 +14,75 @@ 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 ) uint32_t calc_flash_crc(uint32_t start, uint32_t len) {
{
DBG_BL printf("calc_flash_crc(%08lx, %08lx) {\n", start, len); DBG_BL printf("calc_flash_crc(%08lx, %08lx) {\n", start, len);
uint32_t end = start + len; uint32_t end = start + len;
if(end > 0x20000) {
if ( end > 0x20000 )
{
len = 0x1ffff - start; len = 0x1ffff - start;
end = 0x20000; end = 0x20000;
} }
uint32_t crc = 0xffffffff; uint32_t crc = 0xffffffff;
uint32_t s = start; uint32_t s = start;
while(s < end) {
while ( s < end )
{
crc = crc32_update(crc, *(const unsigned char*)(s)); crc = crc32_update(crc, *(const unsigned char*)(s));
s++; s++;
} }
crc = crc_finalize(crc); crc = crc_finalize(crc);
DBG_BL printf(" crc generated. result=%08lx\n", crc); DBG_BL printf(" crc generated. result=%08lx\n", crc);
DBG_BL printf("} //calc_flash_crc\n"); DBG_BL printf("} //calc_flash_crc\n");
return crc; return crc;
} }
void test_iap() void test_iap() {
{
iap_cmd[0]=54; iap_cmd[0]=54;
iap_entry(iap_cmd, iap_res); iap_entry(iap_cmd, iap_res);
DBG_BL printf("Part ID=%08lx\n", iap_res[1]); DBG_BL printf("Part ID=%08lx\n", iap_res[1]);
} }
void print_header( sd2snes_fw_header *header ) 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", 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->magic, header->version, header->size,
header->crc, header->crcc); header->crc, header->crcc);
} }
int check_header( sd2snes_fw_header *header, uint32_t crc ) int check_header(sd2snes_fw_header *header, uint32_t crc) {
{
if((header->magic != FW_MAGIC) if((header->magic != FW_MAGIC)
|| (header->size < 0x200) || (header->size < 0x200)
|| (header->size > (0x1ffff - FW_START)) || (header->size > (0x1ffff - FW_START))
|| ( ( header->crc ^ header->crcc ) != 0xffffffff ) ) || ((header->crc ^ header->crcc) != 0xffffffff)) {
{
return ERR_FLASHHD; return ERR_FLASHHD;
} }
if(header->crc != crc) {
if ( header->crc != crc )
{
return ERR_FLASHCRC; return ERR_FLASHCRC;
} }
return ERR_OK; return ERR_OK;
} }
FLASH_RES check_flash() FLASH_RES check_flash() {
{
sd2snes_fw_header *fw_header = (sd2snes_fw_header*) FW_START; sd2snes_fw_header *fw_header = (sd2snes_fw_header*) FW_START;
uint32_t flash_addr = FW_START; uint32_t flash_addr = FW_START;
if(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);
{
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; return ERR_HW;
} }
DBG_BL printf("Current flash contents:\n"); DBG_BL printf("Current flash contents:\n");
DBG_BL print_header(fw_header); DBG_BL print_header(fw_header);
uint32_t crc = calc_flash_crc(flash_addr + 0x100, (fw_header->size & 0x1ffff)); uint32_t crc = calc_flash_crc(flash_addr + 0x100, (fw_header->size & 0x1ffff));
return check_header(fw_header, crc); return check_header(fw_header, crc);
} }
IAP_RES iap_wrap( uint32_t *iap_cmd, uint32_t *iap_res ) IAP_RES iap_wrap(uint32_t *iap_cmd, uint32_t *iap_res) {
{
// NVIC_DisableIRQ(RIT_IRQn); // NVIC_DisableIRQ(RIT_IRQn);
// NVIC_DisableIRQ(UART_IRQ); // NVIC_DisableIRQ(UART_IRQ);
for(volatile int i=0; i<2048; i++); for(volatile int i=0; i<2048; i++);
iap_entry(iap_cmd, iap_res); iap_entry(iap_cmd, iap_res);
for(volatile int i=0; i<2048; i++); for(volatile int i=0; i<2048; i++);
// NVIC_EnableIRQ(UART_IRQ); // NVIC_EnableIRQ(UART_IRQ);
return iap_res[0]; return iap_res[0];
} }
IAP_RES iap_prepare_for_write( uint32_t start, uint32_t end ) IAP_RES iap_prepare_for_write(uint32_t start, uint32_t end) {
{ if(start < (FW_START / 0x1000)) return INVALID_SECTOR;
if ( start < ( FW_START / 0x1000 ) )
{
return INVALID_SECTOR;
}
iap_cmd[0] = 50; iap_cmd[0] = 50;
iap_cmd[1] = start; iap_cmd[1] = start;
iap_cmd[2] = end; iap_cmd[2] = end;
@ -118,13 +90,8 @@ IAP_RES iap_prepare_for_write( uint32_t start, uint32_t end )
return iap_res[0]; return iap_res[0];
} }
IAP_RES iap_erase( uint32_t start, uint32_t end ) IAP_RES iap_erase(uint32_t start, uint32_t end) {
{ if(start < (FW_START / 0x1000)) return INVALID_SECTOR;
if ( start < ( FW_START / 0x1000 ) )
{
return INVALID_SECTOR;
}
iap_cmd[0] = 52; iap_cmd[0] = 52;
iap_cmd[1] = start; iap_cmd[1] = start;
iap_cmd[2] = end; iap_cmd[2] = end;
@ -133,8 +100,7 @@ IAP_RES iap_erase( uint32_t start, uint32_t end )
return iap_res[0]; return iap_res[0];
} }
IAP_RES iap_ram2flash( uint32_t tgt, uint8_t *src, int num ) IAP_RES iap_ram2flash(uint32_t tgt, uint8_t *src, int num) {
{
iap_cmd[0] = 51; iap_cmd[0] = 51;
iap_cmd[1] = tgt; iap_cmd[1] = tgt;
iap_cmd[2] = (uint32_t)src; iap_cmd[2] = (uint32_t)src;
@ -144,67 +110,43 @@ IAP_RES iap_ram2flash( uint32_t tgt, uint8_t *src, int num )
return iap_res[0]; return iap_res[0];
} }
FLASH_RES flash_file( uint8_t *filename ) FLASH_RES flash_file(uint8_t *filename) {
{
sd2snes_fw_header *fw_header = (sd2snes_fw_header*) FW_START; sd2snes_fw_header *fw_header = (sd2snes_fw_header*) FW_START;
uint32_t flash_addr = FW_START; uint32_t flash_addr = FW_START;
uint32_t file_crc = 0xffffffff; uint32_t file_crc = 0xffffffff;
uint16_t count; uint16_t count;
sd2snes_fw_header file_header; sd2snes_fw_header file_header;
UINT bytes_read; UINT bytes_read;
if(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);
{
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; return ERR_HW;
} }
file_open(filename, FA_READ); file_open(filename, FA_READ);
if(file_res) {
if ( file_res )
{
DBG_BL printf("file_open: error %d\n", file_res); DBG_BL printf("file_open: error %d\n", file_res);
return ERR_FS; return ERR_FS;
} }
DBG_BL printf("firmware image found. file size: %ld\n", file_handle.fsize); DBG_BL printf("firmware image found. file size: %ld\n", file_handle.fsize);
DBG_BL printf("reading header...\n"); DBG_BL printf("reading header...\n");
f_read(&file_handle, &file_header, 32, &bytes_read); f_read(&file_handle, &file_header, 32, &bytes_read);
DBG_BL print_header(&file_header); 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) {
if ( check_flash() || file_header.version != fw_header->version || file_header.version == FW_MAGIC
|| fw_header->version == FW_MAGIC )
{
DBG_UART uart_putc('F'); DBG_UART uart_putc('F');
f_read(&file_handle, file_buf, 0xe0, &bytes_read); f_read(&file_handle, file_buf, 0xe0, &bytes_read);
for(;;) {
for ( ;; )
{
bytes_read = file_read(); bytes_read = file_read();
if(file_res || !bytes_read) break;
if ( file_res || !bytes_read ) for(count = 0; count < bytes_read; count++) {
{
break;
}
for ( count = 0; count < bytes_read; count++ )
{
file_crc = crc32_update(file_crc, file_buf[count]); file_crc = crc32_update(file_crc, file_buf[count]);
} }
} }
file_crc = crc_finalize(file_crc); file_crc = crc_finalize(file_crc);
DBG_BL printf("file crc=%08lx\n", file_crc); DBG_BL printf("file crc=%08lx\n", file_crc);
if(check_header(&file_header, file_header.crc) != ERR_OK) {
if ( check_header( &file_header, file_header.crc ) != ERR_OK )
{
DBG_BL printf("Invalid firmware file (header corrupted).\n"); DBG_BL printf("Invalid firmware file (header corrupted).\n");
return ERR_FILEHD; return ERR_FILEHD;
} }
if(file_header.crc != file_crc) {
if ( file_header.crc != file_crc )
{
DBG_BL printf("Firmware file checksum error.\n"); DBG_BL printf("Firmware file checksum error.\n");
return ERR_FILECHK; return ERR_FILECHK;
} }
@ -214,82 +156,53 @@ FLASH_RES flash_file( uint8_t *filename )
writeled(1); writeled(1);
DBG_BL printf("erasing flash...\n"); DBG_BL printf("erasing flash...\n");
DBG_UART uart_putc('P'); DBG_UART uart_putc('P');
if((res = iap_prepare_for_write(FW_START / 0x1000, FLASH_SECTORS)) != CMD_SUCCESS) {
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_BL printf("error %ld while preparing for erase\n", res);
DBG_UART uart_putc('X'); DBG_UART uart_putc('X');
return ERR_FLASHPREP; return ERR_FLASHPREP;
}; };
DBG_UART uart_putc('E'); DBG_UART uart_putc('E');
if((res = iap_erase(FW_START / 0x1000, FLASH_SECTORS)) != CMD_SUCCESS) {
if ( ( res = iap_erase( FW_START / 0x1000, FLASH_SECTORS ) ) != CMD_SUCCESS )
{
DBG_BL printf("error %ld while erasing\n", res); DBG_BL printf("error %ld while erasing\n", res);
DBG_UART uart_putc('X'); DBG_UART uart_putc('X');
return ERR_FLASHERASE; return ERR_FLASHERASE;
} }
DBG_BL printf("writing... @%08lx\n", flash_addr); DBG_BL printf("writing... @%08lx\n", flash_addr);
file_close(); file_close();
file_open(filename, FA_READ); file_open(filename, FA_READ);
uint8_t current_sec; uint8_t current_sec;
uint32_t total_read = 0; uint32_t total_read = 0;
for(flash_addr = FW_START; flash_addr < 0x00020000; flash_addr += 0x200) {
for ( flash_addr = FW_START; flash_addr < 0x00020000; flash_addr += 0x200 )
{
total_read += (bytes_read = file_read()); total_read += (bytes_read = file_read());
if(file_res || !bytes_read) break;
if ( file_res || !bytes_read )
{
break;
}
current_sec = flash_addr & 0x10000 ? (16 + ((flash_addr >> 15) & 1)) current_sec = flash_addr & 0x10000 ? (16 + ((flash_addr >> 15) & 1))
: (flash_addr >> 12); : (flash_addr >> 12);
DBG_BL printf("current_sec=%d flash_addr=%08lx\n", current_sec, flash_addr); DBG_BL printf("current_sec=%d flash_addr=%08lx\n", current_sec, flash_addr);
DBG_UART uart_putc('.'); DBG_UART uart_putc('.');
if(current_sec < (FW_START / 0x1000)) return ERR_FLASH;
if ( current_sec < ( FW_START / 0x1000 ) )
{
return ERR_FLASH;
}
DBG_UART uart_putc(current_sec["0123456789ABCDEFGH"]); DBG_UART uart_putc(current_sec["0123456789ABCDEFGH"]);
DBG_UART uart_putc('p'); DBG_UART uart_putc('p');
if((res = iap_prepare_for_write(current_sec, current_sec)) != CMD_SUCCESS) {
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_BL printf("error %ld while preparing sector %d for write\n", res, current_sec);
DBG_UART uart_putc('X'); DBG_UART uart_putc('X');
return ERR_FLASH; return ERR_FLASH;
} }
DBG_UART uart_putc('w'); DBG_UART uart_putc('w');
if((res = iap_ram2flash(flash_addr, file_buf, 512)) != CMD_SUCCESS) {
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);
{
//printf("error %ld while writing to address %08lx (sector %d)\n", res, flash_addr, current_sec);
DBG_UART uart_putc('X'); DBG_UART uart_putc('X');
return ERR_FLASH; return ERR_FLASH;
} }
} }
if(total_read != (file_header.size + 0x100)) {
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_BL printf("wrote less data than expected! (%08lx vs. %08lx)\n", total_read, file_header.size);
// DBG_UART uart_putc('X'); // DBG_UART uart_putc('X');
return ERR_FILECHK; return ERR_FILECHK;
} }
writeled(0); writeled(0);
} } else {
else
{
DBG_UART uart_putc('n'); DBG_UART uart_putc('n');
DBG_BL printf("flash content is ok, no version mismatch, no forced upgrade. No need to flash\n"); DBG_BL printf("flash content is ok, no version mismatch, no forced upgrade. No need to flash\n");
} }
return ERR_OK; return ERR_OK;
} }

View File

@ -6,8 +6,7 @@ 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 {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 typedef enum {
{
/* 0*/ CMD_SUCCESS = 0, /* 0*/ CMD_SUCCESS = 0,
/* 1*/ INVALID_COMMAND, /* 1*/ INVALID_COMMAND,
/* 2*/ SRC_ADDR_ERROR, /* 2*/ SRC_ADDR_ERROR,
@ -24,8 +23,7 @@ typedef enum
#define FW_MAGIC (0x44534E53) #define FW_MAGIC (0x44534E53)
typedef struct typedef struct {
{
uint32_t magic; uint32_t magic;
uint32_t version; uint32_t version;
uint32_t size; uint32_t size;

View File

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

View File

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

View File

@ -20,24 +20,14 @@
int i; 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; volatile enum diskstates disk_state;
extern volatile tick_t ticks; extern volatile tick_t ticks;
int (*chain)(void); int (*chain)(void);
int main( void ) int main(void) {
{
SNES_CIC_PAIR_REG->FIODIR = BV(SNES_CIC_PAIR_BIT); SNES_CIC_PAIR_REG->FIODIR = BV(SNES_CIC_PAIR_BIT);
BITBANG( SNES_CIC_PAIR_REG->FIOSET, SNES_CIC_PAIR_BIT ) = 1; BITBAND(SNES_CIC_PAIR_REG->FIOSET, SNES_CIC_PAIR_BIT) = 1;
/* LPC_GPIO2->FIODIR = BV(0) | BV(1) | BV(2); */ /* LPC_GPIO2->FIODIR = BV(0) | BV(1) | BV(2); */
// LPC_GPIO0->FIODIR = BV(16); // LPC_GPIO0->FIODIR = BV(16);
@ -62,16 +52,8 @@ int main( void )
clock_init(); clock_init();
// LPC_PINCON->PINSEL0 |= BV(20) | BV(21); /* MAT3.0 (FPGA clock) */ // LPC_PINCON->PINSEL0 |= BV(20) | BV(21); /* MAT3.0 (FPGA clock) */
sdn_init(); sdn_init();
for ( i = 0; i < 20; i++ )
{
uart_putc( '-' );
}
uart_putc( '\n' );
DBG_BL printf("chksum=%08lx\n", *(uint32_t*)28); 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("\n\nsd2snes mk.2 bootloader\nver.: " VER "\ncpu clock: %ld Hz\n", CONFIG_CPU_FREQUENCY);
DBG_BL printf("PCONP=%lx\n", LPC_SC->PCONP); DBG_BL printf("PCONP=%lx\n", LPC_SC->PCONP);
/* setup timer (fpga clk) */ /* setup timer (fpga clk) */
LPC_TIM3->CTCR=0; LPC_TIM3->CTCR=0;
@ -82,35 +64,24 @@ int main( void )
NVIC->ICER[0] = 0xffffffff; NVIC->ICER[0] = 0xffffffff;
NVIC->ICER[1] = 0xffffffff; NVIC->ICER[1] = 0xffffffff;
FLASH_RES res = flash_file((uint8_t*)"/sd2snes/firmware.img"); FLASH_RES res = flash_file((uint8_t*)"/sd2snes/firmware.img");
if(res == ERR_FLASHPREP || res == ERR_FLASHERASE || res == ERR_FLASH) {
if ( res == ERR_FLASHPREP || res == ERR_FLASHERASE || res == ERR_FLASH )
{
rdyled(0); rdyled(0);
writeled(1); writeled(1);
} }
if(res == ERR_FILEHD || res == ERR_FILECHK) {
if ( res == ERR_FILEHD || res == ERR_FILECHK )
{
rdyled(0); rdyled(0);
readled(1); readled(1);
} }
DBG_BL printf("flash result = %d\n", res); DBG_BL printf("flash result = %d\n", res);
if(res != ERR_OK) {
if ( res != ERR_OK ) if((res = check_flash()) != ERR_OK) {
{
if ( ( res = check_flash() ) != ERR_OK )
{
DBG_BL printf("check_flash() failed with error %d, not booting.\n", res); DBG_BL printf("check_flash() failed with error %d, not booting.\n", res);
while(1) {
while ( 1 )
{
toggle_rdy_led(); toggle_rdy_led();
delay_ms(500); delay_ms(500);
} }
} }
} }
NVIC_DisableIRQ(RIT_IRQn); NVIC_DisableIRQ(RIT_IRQn);
NVIC_DisableIRQ(UART_IRQ); NVIC_DisableIRQ(UART_IRQ);
@ -126,7 +97,6 @@ int main( void )
uart_putc("0123456789abcdef"[((uint32_t)chain)&15]); uart_putc("0123456789abcdef"[((uint32_t)chain)&15]);
uart_putc('\n'); uart_putc('\n');
chain(); chain();
while(1); while(1);
} }

View File

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

View File

@ -15,8 +15,7 @@
* USB [enabled via usb_init] * USB [enabled via usb_init]
* PWM1 * PWM1
*/ */
void power_init() void power_init() {
{
LPC_SC->PCONP = BV(PCSSP0) LPC_SC->PCONP = BV(PCSSP0)
| BV(PCTIM3) | BV(PCTIM3)
| BV(PCRTC) | BV(PCRTC)

View File

@ -62,10 +62,8 @@ static char *outptr;
static int maxlen; static int maxlen;
/* printf */ /* printf */
static void outchar( char x ) static void outchar(char x) {
{ if (maxlen) {
if ( maxlen )
{
maxlen--; maxlen--;
outfunc(x); outfunc(x);
outlength++; outlength++;
@ -73,18 +71,15 @@ static void outchar( char x )
} }
/* sprintf */ /* sprintf */
static void outstr( char x ) static void outstr(char x) {
{ if (maxlen) {
if ( maxlen )
{
maxlen--; maxlen--;
*outptr++ = x; *outptr++ = x;
outlength++; outlength++;
} }
} }
static int internal_nprintf( void ( *output_function )( char c ), const char *fmt, va_list ap ) static int internal_nprintf(void (*output_function)(char c), const char *fmt, va_list ap) {
{
unsigned int width; unsigned int width;
unsigned int flags; unsigned int flags;
unsigned int base = 0; unsigned int base = 0;
@ -92,24 +87,16 @@ static int internal_nprintf( void ( *output_function )( char c ), const char *fm
outlength = 0; outlength = 0;
while ( *fmt ) while (*fmt) {
{ while (1) {
while ( 1 )
{
if (*fmt == 0) if (*fmt == 0)
{
goto end; goto end;
}
if ( *fmt == '%' ) if (*fmt == '%') {
{
fmt++; fmt++;
if (*fmt != '%') if (*fmt != '%')
{
break; break;
} }
}
output_function(*fmt++); output_function(*fmt++);
} }
@ -118,12 +105,9 @@ static int internal_nprintf( void ( *output_function )( char c ), const char *fm
width = 0; width = 0;
/* read all flags */ /* read all flags */
do do {
{ if (flags < FLAG_WIDTH) {
if ( flags < FLAG_WIDTH ) switch (*fmt) {
{
switch ( *fmt )
{
case '0': case '0':
flags |= FLAG_ZEROPAD; flags |= FLAG_ZEROPAD;
continue; continue;
@ -142,10 +126,8 @@ static int internal_nprintf( void ( *output_function )( char c ), const char *fm
} }
} }
if ( flags < FLAG_LONG ) if (flags < FLAG_LONG) {
{ if (*fmt >= '0' && *fmt <= '9') {
if ( *fmt >= '0' && *fmt <= '9' )
{
unsigned char tmp = *fmt - '0'; unsigned char tmp = *fmt - '0';
width = 10*width + tmp; width = 10*width + tmp;
flags |= FLAG_WIDTH; flags |= FLAG_WIDTH;
@ -153,26 +135,20 @@ static int internal_nprintf( void ( *output_function )( char c ), const char *fm
} }
if (*fmt == 'h') if (*fmt == 'h')
{
continue; continue;
}
if ( *fmt == 'l' ) if (*fmt == 'l') {
{
flags |= FLAG_LONG; flags |= FLAG_LONG;
continue; continue;
} }
} }
break; break;
} } while (*fmt++);
while ( *fmt++ );
/* Strings */ /* Strings */
if ( *fmt == 'c' || *fmt == 's' ) if (*fmt == 'c' || *fmt == 's') {
{ switch (*fmt) {
switch ( *fmt )
{
case 'c': case 'c':
buffer[0] = va_arg(ap, int); buffer[0] = va_arg(ap, int);
ptr = buffer; ptr = buffer;
@ -187,11 +163,9 @@ static int internal_nprintf( void ( *output_function )( char c ), const char *fm
} }
/* Numbers */ /* Numbers */
switch ( *fmt ) switch (*fmt) {
{
case 'u': case 'u':
flags |= FLAG_UNSIGNED; flags |= FLAG_UNSIGNED;
case 'd': case 'd':
base = 10; base = 10;
break; break;
@ -205,7 +179,6 @@ static int internal_nprintf( void ( *output_function )( char c ), const char *fm
output_function('0'); output_function('0');
output_function('x'); output_function('x');
width -= 2; width -= 2;
case 'x': case 'x':
case 'X': case 'X':
base = 16; base = 16;
@ -215,89 +188,59 @@ static int internal_nprintf( void ( *output_function )( char c ), const char *fm
unsigned int num; unsigned int num;
if ( !( flags & FLAG_UNSIGNED ) ) if (!(flags & FLAG_UNSIGNED)) {
{
int tmp = va_arg(ap, int); int tmp = va_arg(ap, int);
if (tmp < 0) {
if ( tmp < 0 )
{
num = -tmp; num = -tmp;
flags |= FLAG_NEGATIVE; flags |= FLAG_NEGATIVE;
} } else
else
{
num = tmp; num = tmp;
} } else {
}
else
{
num = va_arg(ap, unsigned int); num = va_arg(ap, unsigned int);
} }
/* Convert number into buffer */ /* Convert number into buffer */
ptr = buffer + sizeof(buffer); ptr = buffer + sizeof(buffer);
*--ptr = 0; *--ptr = 0;
do {
do
{
*--ptr = hexdigits[num % base]; *--ptr = hexdigits[num % base];
num /= base; num /= base;
} } while (num != 0);
while ( num != 0 );
/* Sign */ /* Sign */
if ( flags & FLAG_NEGATIVE ) if (flags & FLAG_NEGATIVE) {
{
output_function('-'); output_function('-');
width--; width--;
} } else if (flags & FLAG_FORCESIGN) {
else if ( flags & FLAG_FORCESIGN )
{
output_function('+'); output_function('+');
width--; width--;
} } else if (flags & FLAG_BLANK) {
else if ( flags & FLAG_BLANK )
{
output_function(' '); output_function(' ');
width--; width--;
} }
output: output:
/* left padding */ /* left padding */
if ( ( flags & FLAG_WIDTH ) && !( flags & FLAG_LEFTADJ ) ) if ((flags & FLAG_WIDTH) && !(flags & FLAG_LEFTADJ)) {
{ while (strlen(ptr) < width) {
while ( strlen( ptr ) < width )
{
if (flags & FLAG_ZEROPAD) if (flags & FLAG_ZEROPAD)
{
output_function('0'); output_function('0');
}
else else
{
output_function(' '); output_function(' ');
}
width--; width--;
} }
} }
/* data */ /* data */
while ( *ptr ) while (*ptr) {
{
output_function(*ptr++); output_function(*ptr++);
if (width) if (width)
{
width--; width--;
} }
}
/* right padding */ /* right padding */
if ( flags & FLAG_WIDTH ) if (flags & FLAG_WIDTH) {
{ while (width) {
while ( width )
{
output_function(' '); output_function(' ');
width--; width--;
} }
@ -310,8 +253,7 @@ end:
return outlength; return outlength;
} }
int printf( const char *format, ... ) int printf(const char *format, ...) {
{
va_list ap; va_list ap;
int res; int res;
@ -322,8 +264,7 @@ int printf( const char *format, ... )
return res; return res;
} }
int snprintf( char *str, size_t size, const char *format, ... ) int snprintf(char *str, size_t size, const char *format, ...) {
{
va_list ap; va_list ap;
int res; int res;
@ -332,43 +273,28 @@ int snprintf( char *str, size_t size, const char *format, ... )
va_start(ap, format); va_start(ap, format);
res = internal_nprintf(outstr, format, ap); res = internal_nprintf(outstr, format, ap);
va_end(ap); va_end(ap);
if (res < size) if (res < size)
{
str[res] = 0; str[res] = 0;
}
return res; return res;
} }
/* Required for gcc compatibility */ /* Required for gcc compatibility */
int puts( const char *str ) int puts(const char *str) {
{
uart_puts(str); uart_puts(str);
uart_putc('\n'); uart_putc('\n');
return 0; return 0;
} }
#undef putchar #undef putchar
int putchar( int c ) int putchar(int c) {
{
uart_putc(c); uart_putc(c);
return 0; return 0;
} }
#else #else
int printf( const char *format, ... ) int printf(const char *format, ...) { return 0; }
{ int snprintf(char *str, size_t size, const char *format, ...) { return 0; }
return 0; int puts(const char *str) { return 0; }
}
//int snprintf(char *str, size_t size, const char *format, ...) { return 0; }
int puts( const char *str )
{
return 0;
}
#undef putchar #undef putchar
int putchar( int c ) int putchar(int c) { return 0; }
{
return 0;
}
#endif #endif

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -13,8 +13,7 @@ extern volatile tick_t ticks;
* *
* This inline function returns the current system tick count. * This inline function returns the current system tick count.
*/ */
static inline tick_t getticks( void ) static inline tick_t getticks(void) {
{
return ticks; return ticks;
} }

View File

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

View File

@ -31,8 +31,7 @@
#if _CODE_PAGE == 437 #if _CODE_PAGE == 437
#define _TBLDEF 1 #define _TBLDEF 1
static static
const WCHAR Tbl[] = /* CP437(0x80-0xFF) to Unicode conversion table */ const WCHAR Tbl[] = { /* CP437(0x80-0xFF) to Unicode conversion table */
{
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
@ -54,8 +53,7 @@ const WCHAR Tbl[] = /* CP437(0x80-0xFF) to Unicode conversion table */
#elif _CODE_PAGE == 720 #elif _CODE_PAGE == 720
#define _TBLDEF 1 #define _TBLDEF 1
static static
const WCHAR Tbl[] = /* CP720(0x80-0xFF) to Unicode conversion table */ const WCHAR Tbl[] = { /* CP720(0x80-0xFF) to Unicode conversion table */
{
0x0000, 0x0000, 0x00E9, 0x00E2, 0x0000, 0x00E0, 0x0000, 0x00E7, 0x0000, 0x0000, 0x00E9, 0x00E2, 0x0000, 0x00E0, 0x0000, 0x00E7,
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0000, 0x0000, 0x0000, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0000, 0x0000, 0x0000,
0x0000, 0x0651, 0x0652, 0x00F4, 0x00A4, 0x0640, 0x00FB, 0x00F9, 0x0000, 0x0651, 0x0652, 0x00F4, 0x00A4, 0x0640, 0x00FB, 0x00F9,
@ -77,8 +75,7 @@ const WCHAR Tbl[] = /* CP720(0x80-0xFF) to Unicode conversion table */
#elif _CODE_PAGE == 737 #elif _CODE_PAGE == 737
#define _TBLDEF 1 #define _TBLDEF 1
static static
const WCHAR Tbl[] = /* CP737(0x80-0xFF) to Unicode conversion table */ const WCHAR Tbl[] = { /* CP737(0x80-0xFF) to Unicode conversion table */
{
0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398,
0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, 0x03A0, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, 0x03A0,
0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9, 0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9,
@ -100,8 +97,7 @@ const WCHAR Tbl[] = /* CP737(0x80-0xFF) to Unicode conversion table */
#elif _CODE_PAGE == 775 #elif _CODE_PAGE == 775
#define _TBLDEF 1 #define _TBLDEF 1
static static
const WCHAR Tbl[] = /* CP775(0x80-0xFF) to Unicode conversion table */ const WCHAR Tbl[] = { /* CP775(0x80-0xFF) to Unicode conversion table */
{
0x0106, 0x00FC, 0x00E9, 0x0101, 0x00E4, 0x0123, 0x00E5, 0x0107, 0x0106, 0x00FC, 0x00E9, 0x0101, 0x00E4, 0x0123, 0x00E5, 0x0107,
0x0142, 0x0113, 0x0156, 0x0157, 0x012B, 0x0179, 0x00C4, 0x00C5, 0x0142, 0x0113, 0x0156, 0x0157, 0x012B, 0x0179, 0x00C4, 0x00C5,
0x00C9, 0x00E6, 0x00C6, 0x014D, 0x00F6, 0x0122, 0x00A2, 0x015A, 0x00C9, 0x00E6, 0x00C6, 0x014D, 0x00F6, 0x0122, 0x00A2, 0x015A,
@ -123,8 +119,7 @@ const WCHAR Tbl[] = /* CP775(0x80-0xFF) to Unicode conversion table */
#elif _CODE_PAGE == 850 #elif _CODE_PAGE == 850
#define _TBLDEF 1 #define _TBLDEF 1
static static
const WCHAR Tbl[] = /* CP850(0x80-0xFF) to Unicode conversion table */ const WCHAR Tbl[] = { /* CP850(0x80-0xFF) to Unicode conversion table */
{
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
@ -146,8 +141,7 @@ const WCHAR Tbl[] = /* CP850(0x80-0xFF) to Unicode conversion table */
#elif _CODE_PAGE == 852 #elif _CODE_PAGE == 852
#define _TBLDEF 1 #define _TBLDEF 1
static static
const WCHAR Tbl[] = /* CP852(0x80-0xFF) to Unicode conversion table */ const WCHAR Tbl[] = { /* CP852(0x80-0xFF) to Unicode conversion table */
{
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x016F, 0x0107, 0x00E7, 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x016F, 0x0107, 0x00E7,
0x0142, 0x00EB, 0x0150, 0x0151, 0x00EE, 0x0179, 0x00C4, 0x0106, 0x0142, 0x00EB, 0x0150, 0x0151, 0x00EE, 0x0179, 0x00C4, 0x0106,
0x00C9, 0x0139, 0x013A, 0x00F4, 0x00F6, 0x013D, 0x013E, 0x015A, 0x00C9, 0x0139, 0x013A, 0x00F4, 0x00F6, 0x013D, 0x013E, 0x015A,
@ -169,8 +163,7 @@ const WCHAR Tbl[] = /* CP852(0x80-0xFF) to Unicode conversion table */
#elif _CODE_PAGE == 855 #elif _CODE_PAGE == 855
#define _TBLDEF 1 #define _TBLDEF 1
static static
const WCHAR Tbl[] = /* CP855(0x80-0xFF) to Unicode conversion table */ const WCHAR Tbl[] = { /* CP855(0x80-0xFF) to Unicode conversion table */
{
0x0452, 0x0402, 0x0453, 0x0403, 0x0451, 0x0401, 0x0454, 0x0404, 0x0452, 0x0402, 0x0453, 0x0403, 0x0451, 0x0401, 0x0454, 0x0404,
0x0455, 0x0405, 0x0456, 0x0406, 0x0457, 0x0407, 0x0458, 0x0408, 0x0455, 0x0405, 0x0456, 0x0406, 0x0457, 0x0407, 0x0458, 0x0408,
0x0459, 0x0409, 0x045A, 0x040A, 0x045B, 0x040B, 0x045C, 0x040C, 0x0459, 0x0409, 0x045A, 0x040A, 0x045B, 0x040B, 0x045C, 0x040C,
@ -192,8 +185,7 @@ const WCHAR Tbl[] = /* CP855(0x80-0xFF) to Unicode conversion table */
#elif _CODE_PAGE == 857 #elif _CODE_PAGE == 857
#define _TBLDEF 1 #define _TBLDEF 1
static static
const WCHAR Tbl[] = /* CP857(0x80-0xFF) to Unicode conversion table */ const WCHAR Tbl[] = { /* CP857(0x80-0xFF) to Unicode conversion table */
{
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0131, 0x00C4, 0x00C5, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0131, 0x00C4, 0x00C5,
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
@ -215,8 +207,7 @@ const WCHAR Tbl[] = /* CP857(0x80-0xFF) to Unicode conversion table */
#elif _CODE_PAGE == 858 #elif _CODE_PAGE == 858
#define _TBLDEF 1 #define _TBLDEF 1
static static
const WCHAR Tbl[] = /* CP858(0x80-0xFF) to Unicode conversion table */ const WCHAR Tbl[] = { /* CP858(0x80-0xFF) to Unicode conversion table */
{
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
@ -238,8 +229,7 @@ const WCHAR Tbl[] = /* CP858(0x80-0xFF) to Unicode conversion table */
#elif _CODE_PAGE == 862 #elif _CODE_PAGE == 862
#define _TBLDEF 1 #define _TBLDEF 1
static static
const WCHAR Tbl[] = /* CP862(0x80-0xFF) to Unicode conversion table */ const WCHAR Tbl[] = { /* CP862(0x80-0xFF) to Unicode conversion table */
{
0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7, 0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7,
0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF, 0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,
0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7, 0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7,
@ -261,8 +251,7 @@ const WCHAR Tbl[] = /* CP862(0x80-0xFF) to Unicode conversion table */
#elif _CODE_PAGE == 866 #elif _CODE_PAGE == 866
#define _TBLDEF 1 #define _TBLDEF 1
static static
const WCHAR Tbl[] = /* CP866(0x80-0xFF) to Unicode conversion table */ const WCHAR Tbl[] = { /* CP866(0x80-0xFF) to Unicode conversion table */
{
0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
@ -284,8 +273,7 @@ const WCHAR Tbl[] = /* CP866(0x80-0xFF) to Unicode conversion table */
#elif _CODE_PAGE == 874 #elif _CODE_PAGE == 874
#define _TBLDEF 1 #define _TBLDEF 1
static static
const WCHAR Tbl[] = /* CP874(0x80-0xFF) to Unicode conversion table */ const WCHAR Tbl[] = { /* CP874(0x80-0xFF) to Unicode conversion table */
{
0x20AC, 0x0000, 0x0000, 0x0000, 0x0000, 0x2026, 0x0000, 0x0000, 0x20AC, 0x0000, 0x0000, 0x0000, 0x0000, 0x2026, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
@ -307,8 +295,7 @@ const WCHAR Tbl[] = /* CP874(0x80-0xFF) to Unicode conversion table */
#elif _CODE_PAGE == 1250 #elif _CODE_PAGE == 1250
#define _TBLDEF 1 #define _TBLDEF 1
static static
const WCHAR Tbl[] = /* CP1250(0x80-0xFF) to Unicode conversion table */ const WCHAR Tbl[] = { /* CP1250(0x80-0xFF) to Unicode conversion table */
{
0x20AC, 0x0000, 0x201A, 0x0000, 0x201E, 0x2026, 0x2020, 0x2021, 0x20AC, 0x0000, 0x201A, 0x0000, 0x201E, 0x2026, 0x2020, 0x2021,
0x0000, 0x2030, 0x0160, 0x2039, 0x015A, 0x0164, 0x017D, 0x0179, 0x0000, 0x2030, 0x0160, 0x2039, 0x015A, 0x0164, 0x017D, 0x0179,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
@ -330,8 +317,7 @@ const WCHAR Tbl[] = /* CP1250(0x80-0xFF) to Unicode conversion table */
#elif _CODE_PAGE == 1251 #elif _CODE_PAGE == 1251
#define _TBLDEF 1 #define _TBLDEF 1
static static
const WCHAR Tbl[] = /* CP1251(0x80-0xFF) to Unicode conversion table */ const WCHAR Tbl[] = { /* CP1251(0x80-0xFF) to Unicode conversion table */
{
0x0402, 0x0403, 0x201A, 0x0453, 0x201E, 0x2026, 0x2020, 0x2021, 0x0402, 0x0403, 0x201A, 0x0453, 0x201E, 0x2026, 0x2020, 0x2021,
0x20AC, 0x2030, 0x0409, 0x2039, 0x040A, 0x040C, 0x040B, 0x040F, 0x20AC, 0x2030, 0x0409, 0x2039, 0x040A, 0x040C, 0x040B, 0x040F,
0x0452, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x0452, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
@ -353,8 +339,7 @@ const WCHAR Tbl[] = /* CP1251(0x80-0xFF) to Unicode conversion table */
#elif _CODE_PAGE == 1252 #elif _CODE_PAGE == 1252
#define _TBLDEF 1 #define _TBLDEF 1
static static
const WCHAR Tbl[] = /* CP1252(0x80-0xFF) to Unicode conversion table */ const WCHAR Tbl[] = { /* CP1252(0x80-0xFF) to Unicode conversion table */
{
0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, 0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x017D, 0x0000, 0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x017D, 0x0000,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
@ -376,8 +361,7 @@ const WCHAR Tbl[] = /* CP1252(0x80-0xFF) to Unicode conversion table */
#elif _CODE_PAGE == 1253 #elif _CODE_PAGE == 1253
#define _TBLDEF 1 #define _TBLDEF 1
static static
const WCHAR Tbl[] = /* CP1253(0x80-0xFF) to Unicode conversion table */ const WCHAR Tbl[] = { /* CP1253(0x80-0xFF) to Unicode conversion table */
{
0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, 0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
0x0000, 0x2030, 0x0000, 0x2039, 0x000C, 0x0000, 0x0000, 0x0000, 0x0000, 0x2030, 0x0000, 0x2039, 0x000C, 0x0000, 0x0000, 0x0000,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
@ -399,8 +383,7 @@ const WCHAR Tbl[] = /* CP1253(0x80-0xFF) to Unicode conversion table */
#elif _CODE_PAGE == 1254 #elif _CODE_PAGE == 1254
#define _TBLDEF 1 #define _TBLDEF 1
static static
const WCHAR Tbl[] = /* CP1254(0x80-0xFF) to Unicode conversion table */ const WCHAR Tbl[] = { /* CP1254(0x80-0xFF) to Unicode conversion table */
{
0x20AC, 0x0000, 0x210A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, 0x20AC, 0x0000, 0x210A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x0000, 0x0000, 0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x0000, 0x0000,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
@ -422,8 +405,7 @@ const WCHAR Tbl[] = /* CP1254(0x80-0xFF) to Unicode conversion table */
#elif _CODE_PAGE == 1255 #elif _CODE_PAGE == 1255
#define _TBLDEF 1 #define _TBLDEF 1
static static
const WCHAR Tbl[] = /* CP1255(0x80-0xFF) to Unicode conversion table */ const WCHAR Tbl[] = { /* CP1255(0x80-0xFF) to Unicode conversion table */
{
0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, 0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
0x02C6, 0x2030, 0x0000, 0x2039, 0x0000, 0x0000, 0x0000, 0x0000, 0x02C6, 0x2030, 0x0000, 0x2039, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
@ -445,8 +427,7 @@ const WCHAR Tbl[] = /* CP1255(0x80-0xFF) to Unicode conversion table */
#elif _CODE_PAGE == 1256 #elif _CODE_PAGE == 1256
#define _TBLDEF 1 #define _TBLDEF 1
static static
const WCHAR Tbl[] = /* CP1256(0x80-0xFF) to Unicode conversion table */ const WCHAR Tbl[] = { /* CP1256(0x80-0xFF) to Unicode conversion table */
{
0x20AC, 0x067E, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, 0x20AC, 0x067E, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
0x02C6, 0x2030, 0x0679, 0x2039, 0x0152, 0x0686, 0x0698, 0x0688, 0x02C6, 0x2030, 0x0679, 0x2039, 0x0152, 0x0686, 0x0698, 0x0688,
0x06AF, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x06AF, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
@ -468,8 +449,7 @@ const WCHAR Tbl[] = /* CP1256(0x80-0xFF) to Unicode conversion table */
#elif _CODE_PAGE == 1257 #elif _CODE_PAGE == 1257
#define _TBLDEF 1 #define _TBLDEF 1
static static
const WCHAR Tbl[] = /* CP1257(0x80-0xFF) to Unicode conversion table */ const WCHAR Tbl[] = { /* CP1257(0x80-0xFF) to Unicode conversion table */
{
0x20AC, 0x0000, 0x201A, 0x0000, 0x201E, 0x2026, 0x2020, 0x2021, 0x20AC, 0x0000, 0x201A, 0x0000, 0x201E, 0x2026, 0x2020, 0x2021,
0x0000, 0x2030, 0x0000, 0x2039, 0x0000, 0x00A8, 0x02C7, 0x00B8, 0x0000, 0x2030, 0x0000, 0x2039, 0x0000, 0x00A8, 0x02C7, 0x00B8,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
@ -491,8 +471,7 @@ const WCHAR Tbl[] = /* CP1257(0x80-0xFF) to Unicode conversion table */
#elif _CODE_PAGE == 1258 #elif _CODE_PAGE == 1258
#define _TBLDEF 1 #define _TBLDEF 1
static static
const WCHAR Tbl[] = /* CP1258(0x80-0xFF) to Unicode conversion table */ const WCHAR Tbl[] = { /* CP1258(0x80-0xFF) to Unicode conversion table */
{
0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, 0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
0x02C6, 0x2030, 0x0000, 0x2039, 0x0152, 0x0000, 0x0000, 0x0000, 0x02C6, 0x2030, 0x0000, 0x2039, 0x0152, 0x0000, 0x0000, 0x0000,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
@ -527,28 +506,17 @@ WCHAR ff_convert ( /* Converted character, Returns zero on error */
WCHAR c; WCHAR c;
if ( src < 0x80 ) /* ASCII */ if (src < 0x80) { /* ASCII */
{
c = src; c = src;
} } else {
else if (dir) { /* OEMCP to Unicode */
{
if ( dir ) /* OEMCP to Unicode */
{
c = (src >= 0x100) ? 0 : Tbl[src - 0x80]; c = (src >= 0x100) ? 0 : Tbl[src - 0x80];
} else { /* Unicode to OEMCP */
for (c = 0; c < 0x80; c++) {
if (src == Tbl[c]) break;
} }
else /* Unicode to OEMCP */
{
for ( c = 0; c < 0x80; c++ )
{
if ( src == Tbl[c] )
{
break;
}
}
c = (c + 0x80) & 0xFF; c = (c + 0x80) & 0xFF;
} }
} }

View File

@ -3,8 +3,7 @@
#include "uart.h" #include "uart.h"
#include "fileops.h" #include "fileops.h"
cfg_t CFG = cfg_t CFG = {
{
.cfg_ver_maj = 1, .cfg_ver_maj = 1,
.cfg_ver_min = 0, .cfg_ver_min = 0,
.last_game_valid = 0, .last_game_valid = 0,
@ -15,36 +14,27 @@ cfg_t CFG =
.bsx_time = 0x0619970301180530LL .bsx_time = 0x0619970301180530LL
}; };
int cfg_save() int cfg_save() {
{
int err = 0; int err = 0;
file_open(CFG_FILE, FA_CREATE_ALWAYS | FA_WRITE); file_open(CFG_FILE, FA_CREATE_ALWAYS | FA_WRITE);
if(file_writeblock(&CFG, 0, sizeof(CFG)) < sizeof(CFG)) {
if ( file_writeblock( &CFG, 0, sizeof( CFG ) ) < sizeof( CFG ) )
{
err = file_res; err = file_res;
} }
file_close(); file_close();
return err; return err;
} }
int cfg_load() int cfg_load() {
{
int err = 0; int err = 0;
file_open(CFG_FILE, FA_READ); file_open(CFG_FILE, FA_READ);
if(file_readblock(&CFG, 0, sizeof(CFG)) < sizeof(CFG)) {
if ( file_readblock( &CFG, 0, sizeof( CFG ) ) < sizeof( CFG ) )
{
err = file_res; err = file_res;
} }
file_close(); file_close();
return err; return err;
} }
int cfg_save_last_game( uint8_t *fn ) int cfg_save_last_game(uint8_t *fn) {
{
int err = 0; int err = 0;
file_open(LAST_FILE, FA_CREATE_ALWAYS | FA_WRITE); file_open(LAST_FILE, FA_CREATE_ALWAYS | FA_WRITE);
err = f_puts((const TCHAR*)fn, &file_handle); err = f_puts((const TCHAR*)fn, &file_handle);
@ -52,8 +42,7 @@ int cfg_save_last_game( uint8_t *fn )
return err; return err;
} }
int cfg_get_last_game( uint8_t *fn ) int cfg_get_last_game(uint8_t *fn) {
{
int err = 0; int err = 0;
file_open(LAST_FILE, FA_READ); file_open(LAST_FILE, FA_READ);
f_gets((TCHAR*)fn, 255, &file_handle); f_gets((TCHAR*)fn, 255, &file_handle);
@ -61,12 +50,10 @@ int cfg_get_last_game( uint8_t *fn )
return err; return err;
} }
void cfg_set_last_game_valid( uint8_t valid ) void cfg_set_last_game_valid(uint8_t valid) {
{
CFG.last_game_valid = valid; CFG.last_game_valid = valid;
} }
uint8_t cfg_is_last_game_valid() uint8_t cfg_is_last_game_valid() {
{
return CFG.last_game_valid; return CFG.last_game_valid;
} }

View File

@ -6,15 +6,13 @@
#define CFG_FILE ((const uint8_t*)"/sd2snes/sd2snes.cfg") #define CFG_FILE ((const uint8_t*)"/sd2snes/sd2snes.cfg")
#define LAST_FILE ((const uint8_t*)"/sd2snes/lastgame.cfg") #define LAST_FILE ((const uint8_t*)"/sd2snes/lastgame.cfg")
typedef enum typedef enum {
{
VIDMODE_AUTO = 0, VIDMODE_AUTO = 0,
VIDMODE_60, VIDMODE_60,
VIDMODE_50 VIDMODE_50
} cfg_vidmode_t; } cfg_vidmode_t;
typedef struct _cfg_block typedef struct _cfg_block {
{
uint8_t cfg_ver_maj; uint8_t cfg_ver_maj;
uint8_t cfg_ver_min; uint8_t cfg_ver_min;
uint8_t last_game_valid; uint8_t last_game_valid;

2541
src/cfgware.h Normal file

File diff suppressed because it is too large Load Diff

View File

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

351
src/cli.c
View File

@ -42,7 +42,6 @@
#include "fileops.h" #include "fileops.h"
#include "memory.h" #include "memory.h"
#include "snes.h" #include "snes.h"
#include "tests.h"
#include "fpga.h" #include "fpga.h"
#include "fpga_spi.h" #include "fpga_spi.h"
#include "cic.h" #include "cic.h"
@ -59,42 +58,35 @@ static char *curchar;
/* Word lists */ /* Word lists */
static char command_words[] = static char command_words[] =
"cd\0reset\0sreset\0dir\0ls\0test\0exit\0loadrom\0loadraw\0saveraw\0put\0rm\0mkdir\0d4\0vmode\0mapper\0settime\0time\0setfeature\0hexdump\0w8\0w16\0memset\0memtest\0"; "cd\0reset\0sreset\0dir\0ls\0test\0exit\0loadrom\0loadraw\0saveraw\0put\0rm\0mkdir\0d4\0vmode\0mapper\0settime\0time\0setfeature\0hexdump\0w8\0w16\0memset\0";
enum { CMD_CD = 0, CMD_RESET, CMD_SRESET, CMD_DIR, CMD_LS, CMD_TEST, CMD_EXIT, CMD_LOADROM, CMD_LOADRAW, CMD_SAVERAW, CMD_PUT, CMD_RM, CMD_MKDIR, CMD_D4, CMD_VMODE, CMD_MAPPER, CMD_SETTIME, CMD_TIME, CMD_SETFEATURE, CMD_HEXDUMP, CMD_W8, CMD_W16, CMD_MEMSET, CMD_MEMTEST }; enum { CMD_CD = 0, CMD_RESET, CMD_SRESET, CMD_DIR, CMD_LS, CMD_TEST, CMD_EXIT, CMD_LOADROM, CMD_LOADRAW, CMD_SAVERAW, CMD_PUT, CMD_RM, CMD_MKDIR, CMD_D4, CMD_VMODE, CMD_MAPPER, CMD_SETTIME, CMD_TIME, CMD_SETFEATURE, CMD_HEXDUMP, CMD_W8, CMD_W16, CMD_MEMSET };
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
/* Parse functions */ /* Parse functions */
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
/* Skip spaces at curchar */ /* Skip spaces at curchar */
static uint8_t skip_spaces( void ) static uint8_t skip_spaces(void) {
{
uint8_t res = (*curchar == ' ' || *curchar == 0); uint8_t res = (*curchar == ' ' || *curchar == 0);
while (*curchar == ' ') while (*curchar == ' ')
{
curchar++; curchar++;
}
return res; return res;
} }
/* Parse the string in curchar for an integer with bounds [lower,upper] */ /* Parse the string in curchar for an integer with bounds [lower,upper] */
static int32_t parse_unsigned( uint32_t lower, uint32_t upper, uint8_t base ) static int32_t parse_unsigned(uint32_t lower, uint32_t upper, uint8_t base) {
{
char *end; char *end;
uint32_t result; uint32_t result;
if ( strlen( curchar ) == 1 && *curchar == '?' ) if (strlen(curchar) == 1 && *curchar == '?') {
{
printf("Number between %ld[0x%lx] and %ld[0x%lx] expected\n",lower,lower,upper,upper); printf("Number between %ld[0x%lx] and %ld[0x%lx] expected\n",lower,lower,upper,upper);
return -2; return -2;
} }
result = strtoul(curchar, &end, base); result = strtoul(curchar, &end, base);
if ((*end != ' ' && *end != 0) || errno != 0) {
if ( ( *end != ' ' && *end != 0 ) || errno != 0 )
{
printf("Invalid numeric argument\n"); printf("Invalid numeric argument\n");
return -1; return -1;
} }
@ -102,8 +94,7 @@ static int32_t parse_unsigned( uint32_t lower, uint32_t upper, uint8_t base )
curchar = end; curchar = end;
skip_spaces(); skip_spaces();
if ( result < lower || result > upper ) if (result < lower || result > upper) {
{
printf("Numeric argument out of range (%ld..%ld)\n",lower,upper); printf("Numeric argument out of range (%ld..%ld)\n",lower,upper);
return -1; return -1;
} }
@ -111,157 +102,112 @@ static int32_t parse_unsigned( uint32_t lower, uint32_t upper, uint8_t base )
return result; return result;
} }
/* Parse the string starting with curchar for a word in wordlist */ /* Parse the string starting with curchar for a word in wordlist */
static int8_t parse_wordlist( char *wordlist ) static int8_t parse_wordlist(char *wordlist) {
{
uint8_t i, matched; uint8_t i, matched;
unsigned char *cur, *ptr; char *cur, *ptr;
unsigned char c; char c;
i = 0; i = 0;
ptr = ( unsigned char * )wordlist; ptr = wordlist;
// Command list on "?" // Command list on "?"
if ( strlen( curchar ) == 1 && *curchar == '?' ) if (strlen(curchar) == 1 && *curchar == '?') {
{
printf("Commands available: \n "); printf("Commands available: \n ");
while (1) {
while ( 1 )
{
c = *ptr++; c = *ptr++;
if (c == 0) {
if ( c == 0 ) if (*ptr == 0) {
{
if ( *ptr == 0 )
{
printf("\n"); printf("\n");
return -2; return -2;
} } else {
else
{
printf("\n "); printf("\n ");
} }
} } else
else
{
uart_putc(c); uart_putc(c);
} }
} }
}
while ( 1 ) while (1) {
{ cur = curchar;
cur = ( unsigned char * )curchar;
matched = 1; matched = 1;
c = *ptr; c = *ptr;
do {
do
{
// If current word list character is \0: No match found // If current word list character is \0: No match found
if ( c == 0 ) if (c == 0) {
{
printf("Unknown word: %s\n(use ? for help)",curchar); printf("Unknown word: %s\n(use ? for help)",curchar);
return -1; return -1;
} }
if ( tolower( ( int )c ) != tolower( ( int )*cur ) ) if (tolower((int)c) != tolower((int)*cur)) {
{
// Check for end-of-word // Check for end-of-word
if ( cur != ( unsigned char * )curchar && ( *cur == ' ' || *cur == 0 ) ) if (cur != curchar && (*cur == ' ' || *cur == 0)) {
{
// Partial match found, return that // Partial match found, return that
break; break;
} } else {
else
{
matched = 0; matched = 0;
break; break;
} }
} }
ptr++; ptr++;
cur++; cur++;
c = *ptr; c = *ptr;
} } while (c != 0);
while ( c != 0 );
if ( matched ) if (matched) {
{
char *tmp = curchar; char *tmp = curchar;
curchar = ( char * )cur; curchar = cur;
// Return match only if whitespace or end-of-string follows // Return match only if whitespace or end-of-string follows
// (avoids mismatching partial words) // (avoids mismatching partial words)
if ( skip_spaces() ) if (skip_spaces()) {
{
return i; return i;
} } else {
else
{
printf("Unknown word: %s\n(use ? for help)\n",tmp); printf("Unknown word: %s\n(use ? for help)\n",tmp);
return -1; return -1;
} }
} } else {
else
{
// Try next word in list // Try next word in list
i++; i++;
while (*ptr++ != 0) ; while (*ptr++ != 0) ;
} }
} }
} }
/* Read a line from serial, uses cmdbuffer as storage */ /* Read a line from serial, uses cmdbuffer as storage */
static char *getline( char *prompt ) static char *getline(char *prompt) {
{
int i=0; int i=0;
char c; char c;
printf("\n%s",prompt); printf("\n%s",prompt);
memset(cmdbuffer,0,sizeof(cmdbuffer)); memset(cmdbuffer,0,sizeof(cmdbuffer));
while ( 1 ) while (1) {
{
c = uart_getc(); c = uart_getc();
if (c == 13) if (c == 13)
{
break; break;
}
if ( c == 27 || c == 3 ) if (c == 27 || c == 3) {
{
printf("\\\n%s",prompt); printf("\\\n%s",prompt);
i = 0; i = 0;
memset(cmdbuffer,0,sizeof(cmdbuffer)); memset(cmdbuffer,0,sizeof(cmdbuffer));
continue; continue;
} }
if ( c == 127 || c == 8 ) if (c == 127 || c == 8) {
{ if (i > 0) {
if ( i > 0 )
{
i--; i--;
uart_putc(8); // backspace uart_putc(8); // backspace
uart_putc(' '); // erase character uart_putc(' '); // erase character
uart_putc(8); // backspace uart_putc(8); // backspace
} } else
else
{
continue; continue;
} } else {
} if (i < sizeof(cmdbuffer)-1) {
else
{
if ( i < sizeof( cmdbuffer ) - 1 )
{
cmdbuffer[i++] = c; cmdbuffer[i++] = c;
uart_putc(c); uart_putc(c);
} }
} }
} }
cmdbuffer[i] = 0; cmdbuffer[i] = 0;
return cmdbuffer; return cmdbuffer;
} }
@ -272,8 +218,7 @@ static char *getline( char *prompt )
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
/* Reset */ /* Reset */
static void cmd_reset( void ) static void cmd_reset(void) {
{
/* force watchdog reset */ /* force watchdog reset */
LPC_WDT->WDTC = 256; // minimal timeout LPC_WDT->WDTC = 256; // minimal timeout
LPC_WDT->WDCLKSEL = BV(31); // internal RC, lock register LPC_WDT->WDCLKSEL = BV(31); // internal RC, lock register
@ -283,8 +228,7 @@ static void cmd_reset( void )
} }
/* Show the contents of the current directory */ /* Show the contents of the current directory */
static void cmd_show_directory( void ) static void cmd_show_directory(void) {
{
FRESULT res; FRESULT res;
DIR dh; DIR dh;
FILINFO finfo; FILINFO finfo;
@ -293,9 +237,7 @@ static void cmd_show_directory( void )
f_getcwd((TCHAR*)file_lfn, 255); f_getcwd((TCHAR*)file_lfn, 255);
res = f_opendir(&dh, (TCHAR*)file_lfn); res = f_opendir(&dh, (TCHAR*)file_lfn);
if (res != FR_OK) {
if ( res != FR_OK )
{
printf("f_opendir failed, result %d\n",res); printf("f_opendir failed, result %d\n",res);
return; return;
} }
@ -303,36 +245,26 @@ static void cmd_show_directory( void )
finfo.lfname = (TCHAR*)file_lfn; finfo.lfname = (TCHAR*)file_lfn;
finfo.lfsize = 255; finfo.lfsize = 255;
do do {
{
/* Read the next entry */ /* Read the next entry */
res = f_readdir(&dh, &finfo); res = f_readdir(&dh, &finfo);
if (res != FR_OK) {
if ( res != FR_OK )
{
printf("f_readdir failed, result %d\n",res); printf("f_readdir failed, result %d\n",res);
return; return;
} }
/* Abort if none was found */ /* Abort if none was found */
if (!finfo.fname[0]) if (!finfo.fname[0])
{
break; break;
}
/* Skip volume labels */ /* Skip volume labels */
if (finfo.fattrib & AM_VOL) if (finfo.fattrib & AM_VOL)
{
continue; continue;
}
/* Select between LFN and 8.3 name */ /* Select between LFN and 8.3 name */
if (finfo.lfname[0]) if (finfo.lfname[0])
{
name = (uint8_t*)finfo.lfname; name = (uint8_t*)finfo.lfname;
} else {
else
{
name = (uint8_t*)finfo.fname; name = (uint8_t*)finfo.fname;
strlwr((char *)name); strlwr((char *)name);
} }
@ -341,165 +273,108 @@ static void cmd_show_directory( void )
/* Directory indicator (Unix-style) */ /* Directory indicator (Unix-style) */
if (finfo.fattrib & AM_DIR) if (finfo.fattrib & AM_DIR)
{
uart_putc('/'); uart_putc('/');
}
printf("\n"); printf("\n");
} } while (finfo.fname[0]);
while ( finfo.fname[0] );
} }
static void cmd_loadrom( void ) static void cmd_loadrom(void) {
{
uint32_t address = 0; uint32_t address = 0;
uint8_t flags = LOADROM_WITH_SRAM | LOADROM_WITH_RESET; uint8_t flags = LOADROM_WITH_SRAM | LOADROM_WITH_RESET;
load_rom((uint8_t*)curchar, address, flags); load_rom((uint8_t*)curchar, address, flags);
} }
static void cmd_loadraw( void ) static void cmd_loadraw(void) {
{
uint32_t address = parse_unsigned(0,16777216,16); uint32_t address = parse_unsigned(0,16777216,16);
load_sram((uint8_t*)curchar, address); load_sram((uint8_t*)curchar, address);
} }
static void cmd_saveraw( void ) static void cmd_saveraw(void) {
{
uint32_t address = parse_unsigned(0,16777216,16); uint32_t address = parse_unsigned(0,16777216,16);
uint32_t length = parse_unsigned(0,16777216,16); uint32_t length = parse_unsigned(0,16777216,16);
if(address != -1 && length != -1) if(address != -1 && length != -1)
{
save_sram((uint8_t*)curchar, length, address); save_sram((uint8_t*)curchar, length, address);
} }
}
static void cmd_d4( void ) static void cmd_d4(void) {
{
int32_t hz; int32_t hz;
if ( get_cic_state() != CIC_PAIR ) if(get_cic_state() != CIC_PAIR) {
{
printf("not in pair mode\n"); printf("not in pair mode\n");
} } else {
else
{
hz = parse_unsigned(50,60,10); hz = parse_unsigned(50,60,10);
if(hz==50) {
if ( hz == 50 )
{
cic_d4(CIC_PAL); cic_d4(CIC_PAL);
} } else {
else
{
cic_d4(CIC_NTSC); cic_d4(CIC_NTSC);
} }
printf("ok\n"); printf("ok\n");
} }
} }
static void cmd_vmode( void ) static void cmd_vmode(void) {
{
int32_t hz; int32_t hz;
if(get_cic_state() != CIC_PAIR) {
if ( get_cic_state() != CIC_PAIR )
{
printf("not in pair mode\n"); printf("not in pair mode\n");
} } else {
else
{
hz = parse_unsigned(50,60,10); hz = parse_unsigned(50,60,10);
if(hz==50) {
if ( hz == 50 )
{
cic_videomode(CIC_PAL); cic_videomode(CIC_PAL);
} } else {
else
{
cic_videomode(CIC_NTSC); cic_videomode(CIC_NTSC);
} }
printf("ok\n"); printf("ok\n");
} }
} }
void cmd_put( void ) void cmd_put(void) {
{ if(*curchar != 0) {
if ( *curchar != 0 )
{
file_open((uint8_t*)curchar, FA_CREATE_ALWAYS | FA_WRITE); file_open((uint8_t*)curchar, FA_CREATE_ALWAYS | FA_WRITE);
if(file_res) {
if ( file_res )
{
printf("FAIL: error opening file %s\n", curchar); printf("FAIL: error opening file %s\n", curchar);
} } else {
else
{
printf("OK, start xmodem transfer now.\n"); printf("OK, start xmodem transfer now.\n");
xmodem_rxfile(&file_handle); xmodem_rxfile(&file_handle);
} }
file_close(); file_close();
} } else {
else
{
printf("Usage: put <filename>\n"); printf("Usage: put <filename>\n");
} }
} }
void cmd_rm( void ) void cmd_rm(void) {
{
FRESULT res = f_unlink(curchar); FRESULT res = f_unlink(curchar);
if(res) printf("Error %d removing %s\n", res, curchar);
if ( res )
{
printf( "Error %d removing %s\n", res, curchar );
}
} }
void cmd_mkdir( void ) void cmd_mkdir(void) {
{
FRESULT res = f_mkdir(curchar); FRESULT res = f_mkdir(curchar);
if(res) printf("Error %d creating directory %s\n", res, curchar);
if ( res )
{
printf( "Error %d creating directory %s\n", res, curchar );
}
} }
void cmd_mapper( void ) void cmd_mapper(void) {
{
int32_t mapper; int32_t mapper;
mapper = parse_unsigned(0,7,10); mapper = parse_unsigned(0,7,10);
set_mapper((uint8_t)mapper & 0x7); set_mapper((uint8_t)mapper & 0x7);
printf("mapper set to %ld\n", mapper); printf("mapper set to %ld\n", mapper);
} }
void cmd_sreset( void ) void cmd_sreset(void) {
{ if(*curchar != 0) {
if ( *curchar != 0 )
{
int32_t resetstate; int32_t resetstate;
resetstate = parse_unsigned(0,1,10); resetstate = parse_unsigned(0,1,10);
snes_reset(resetstate); snes_reset(resetstate);
} } else {
else
{
snes_reset_pulse(); snes_reset_pulse();
} }
} }
void cmd_settime( void ) void cmd_settime(void) {
{
struct tm time; struct tm time;
if(strlen(curchar) != 4+2+2 + 2+2+2) {
if ( strlen( curchar ) != 4 + 2 + 2 + 2 + 2 + 2 )
{
printf("invalid time format (need YYYYMMDDhhmmss)\n"); printf("invalid time format (need YYYYMMDDhhmmss)\n");
} } else {
else
{
time.tm_sec = atoi(curchar+4+2+2+2+2); time.tm_sec = atoi(curchar+4+2+2+2+2);
curchar[4+2+2+2+2] = 0; curchar[4+2+2+2+2] = 0;
time.tm_min = atoi(curchar+4+2+2+2); time.tm_min = atoi(curchar+4+2+2+2);
@ -515,43 +390,37 @@ void cmd_settime( void )
} }
} }
void cmd_time( void ) void cmd_time(void) {
{
struct tm time; struct tm time;
read_rtc(&time); read_rtc(&time);
printf("%04d-%02d-%02d %02d:%02d:%02d\n", time.tm_year, time.tm_mon, 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); time.tm_mday, time.tm_hour, time.tm_min, time.tm_sec);
} }
void cmd_setfeature( void ) void cmd_setfeature(void) {
{
uint8_t feat = parse_unsigned(0, 255, 16); uint8_t feat = parse_unsigned(0, 255, 16);
fpga_set_features(feat); fpga_set_features(feat);
} }
void cmd_hexdump( void ) void cmd_hexdump(void) {
{
uint32_t offset = parse_unsigned(0, 16777215, 16); uint32_t offset = parse_unsigned(0, 16777215, 16);
uint32_t len = parse_unsigned(0, 16777216, 16); uint32_t len = parse_unsigned(0, 16777216, 16);
sram_hexdump(offset, len); sram_hexdump(offset, len);
} }
void cmd_w8( void ) void cmd_w8(void) {
{
uint32_t offset = parse_unsigned(0, 16777215, 16); uint32_t offset = parse_unsigned(0, 16777215, 16);
uint8_t val = parse_unsigned(0, 255, 16); uint8_t val = parse_unsigned(0, 255, 16);
sram_writebyte(val, offset); sram_writebyte(val, offset);
} }
void cmd_w16( void ) void cmd_w16(void) {
{
uint32_t offset = parse_unsigned(0, 16777215, 16); uint32_t offset = parse_unsigned(0, 16777215, 16);
uint16_t val = parse_unsigned(0, 65535, 16); uint16_t val = parse_unsigned(0, 65535, 16);
sram_writeshort(val, offset); sram_writeshort(val, offset);
} }
void cmd_memset( void ) void cmd_memset(void) {
{
uint32_t offset = parse_unsigned(0, 16777215, 16); uint32_t offset = parse_unsigned(0, 16777215, 16);
uint32_t len = parse_unsigned(0, 16777216, 16); uint32_t len = parse_unsigned(0, 16777216, 16);
uint8_t val = parse_unsigned(0, 255, 16); uint8_t val = parse_unsigned(0, 255, 16);
@ -562,101 +431,71 @@ void cmd_memset( void )
/* CLI interface functions */ /* CLI interface functions */
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
void cli_init( void ) void cli_init(void) {
{
} }
void cli_entrycheck() void cli_entrycheck() {
{ if(uart_gotc() && uart_getc() == 27) {
if ( uart_gotc() && uart_getc() == 27 )
{
printf("*** BREAK\n"); printf("*** BREAK\n");
cli_loop(); cli_loop();
} }
} }
void cli_loop( void ) void cli_loop(void) {
{ while (1) {
while ( 1 )
{
curchar = getline(">"); curchar = getline(">");
printf("\n"); printf("\n");
/* Process medium changes before executing the command */ /* Process medium changes before executing the command */
if ( disk_state != DISK_OK && disk_state != DISK_REMOVED ) if (disk_state != DISK_OK && disk_state != DISK_REMOVED) {
{
FRESULT res; FRESULT res;
printf("Medium changed... "); printf("Medium changed... ");
res = f_mount(0,&fatfs); res = f_mount(0,&fatfs);
if (res != FR_OK) {
if ( res != FR_OK )
{
printf("Failed to mount new medium, result %d\n",res); printf("Failed to mount new medium, result %d\n",res);
} } else {
else
{
printf("Ok\n"); printf("Ok\n");
} }
} }
/* Remove whitespace */ /* Remove whitespace */
while ( *curchar == ' ' ) while (*curchar == ' ') curchar++;
{
curchar++;
}
while (strlen(curchar) > 0 && curchar[strlen(curchar)-1] == ' ') while (strlen(curchar) > 0 && curchar[strlen(curchar)-1] == ' ')
{
curchar[strlen(curchar)-1] = 0; curchar[strlen(curchar)-1] = 0;
}
/* Ignore empty lines */ /* Ignore empty lines */
if (strlen(curchar) == 0) if (strlen(curchar) == 0)
{
continue; continue;
}
/* Parse command */ /* Parse command */
int8_t command = parse_wordlist(command_words); int8_t command = parse_wordlist(command_words);
if (command < 0) if (command < 0)
{
continue; continue;
}
FRESULT res; FRESULT res;
switch (command) {
switch ( command )
{
case CMD_CD: case CMD_CD:
#if _FS_RPATH #if _FS_RPATH
if ( strlen( curchar ) == 0 ) if (strlen(curchar) == 0) {
{
f_getcwd((TCHAR*)file_lfn, 255); f_getcwd((TCHAR*)file_lfn, 255);
printf("%s\n",file_lfn); printf("%s\n",file_lfn);
break; break;
} }
res = f_chdir((const TCHAR *)curchar); res = f_chdir((const TCHAR *)curchar);
if (res != FR_OK) {
if ( res != FR_OK )
{
printf("chdir %s failed with result %d\n",curchar,res); printf("chdir %s failed with result %d\n",curchar,res);
} } else {
else
{
printf("Ok.\n"); printf("Ok.\n");
} }
#else #else
printf("cd not supported.\n"); printf("cd not supported.\n");
res; res;
#endif #endif
break; break;
case CMD_RESET: case CMD_RESET:
cmd_reset(); cmd_reset();
break; break;
@ -742,10 +581,6 @@ void cli_loop( void )
cmd_memset(); cmd_memset();
break; break;
case CMD_MEMTEST:
test_mem();
break;
} }
} }
} }

View File

@ -7,14 +7,12 @@
#include "bits.h" #include "bits.h"
#include "uart.h" #include "uart.h"
void clock_disconnect() void clock_disconnect() {
{
disconnectPLL0(); disconnectPLL0();
disablePLL0(); disablePLL0();
} }
void clock_init() void clock_init() {
{
/* set flash access time to 5 clks (80<f<=100MHz) */ /* set flash access time to 5 clks (80<f<=100MHz) */
setFlashAccessTime(5); setFlashAccessTime(5);
@ -54,69 +52,96 @@ void clock_init()
enablePLL0(); enablePLL0();
setCCLKDiv(6); setCCLKDiv(6);
connectPLL0(); connectPLL0();
/* configure PLL1 for USB operation */
disconnectPLL1();
disablePLL1();
LPC_SC->PLL1CFG = 0x23;
enablePLL1();
connectPLL1();
} }
void setFlashAccessTime( uint8_t clocks ) void setFlashAccessTime(uint8_t clocks) {
{
LPC_SC->FLASHCFG=FLASHTIM(clocks); LPC_SC->FLASHCFG=FLASHTIM(clocks);
} }
void setPLL0MultPrediv( uint16_t mult, uint8_t prediv ) void setPLL0MultPrediv(uint16_t mult, uint8_t prediv) {
{
LPC_SC->PLL0CFG=PLL_MULT(mult) | PLL_PREDIV(prediv); LPC_SC->PLL0CFG=PLL_MULT(mult) | PLL_PREDIV(prediv);
PLL0feed(); PLL0feed();
} }
void enablePLL0() void enablePLL0() {
{
LPC_SC->PLL0CON |= PLLE0; LPC_SC->PLL0CON |= PLLE0;
PLL0feed(); PLL0feed();
} }
void disablePLL0() void disablePLL0() {
{
LPC_SC->PLL0CON &= ~PLLE0; LPC_SC->PLL0CON &= ~PLLE0;
PLL0feed(); PLL0feed();
} }
void connectPLL0() void connectPLL0() {
{
while(!(LPC_SC->PLL0STAT & PLOCK0)); while(!(LPC_SC->PLL0STAT & PLOCK0));
LPC_SC->PLL0CON |= PLLC0; LPC_SC->PLL0CON |= PLLC0;
PLL0feed(); PLL0feed();
} }
void disconnectPLL0() void disconnectPLL0() {
{
LPC_SC->PLL0CON &= ~PLLC0; LPC_SC->PLL0CON &= ~PLLC0;
PLL0feed(); PLL0feed();
} }
void setCCLKDiv( uint8_t div ) void setPLL1MultPrediv(uint16_t mult, uint8_t prediv) {
{ LPC_SC->PLL1CFG=PLL_MULT(mult) | PLL_PREDIV(prediv);
PLL1feed();
}
void enablePLL1() {
LPC_SC->PLL1CON |= PLLE1;
PLL1feed();
}
void disablePLL1() {
LPC_SC->PLL1CON &= ~PLLE1;
PLL1feed();
}
void connectPLL1() {
while(!(LPC_SC->PLL1STAT & PLOCK1));
LPC_SC->PLL1CON |= PLLC1;
PLL1feed();
}
void disconnectPLL1() {
LPC_SC->PLL1CON &= ~PLLC1;
PLL1feed();
}
void setCCLKDiv(uint8_t div) {
LPC_SC->CCLKCFG=CCLK_DIV(div); LPC_SC->CCLKCFG=CCLK_DIV(div);
} }
void enableMainOsc() void enableMainOsc() {
{
LPC_SC->SCS=OSCEN; LPC_SC->SCS=OSCEN;
while(!(LPC_SC->SCS&OSCSTAT)); while(!(LPC_SC->SCS&OSCSTAT));
} }
void disableMainOsc() void disableMainOsc() {
{
LPC_SC->SCS=0; LPC_SC->SCS=0;
} }
void PLL0feed() void PLL0feed() {
{
LPC_SC->PLL0FEED=0xaa; LPC_SC->PLL0FEED=0xaa;
LPC_SC->PLL0FEED=0x55; LPC_SC->PLL0FEED=0x55;
} }
void setClkSrc( uint8_t src ) void PLL1feed() {
{ LPC_SC->PLL1FEED=0xaa;
LPC_SC->PLL1FEED=0x55;
}
void setClkSrc(uint8_t src) {
LPC_SC->CLKSRCSEL=src; LPC_SC->CLKSRCSEL=src;
} }

View File

@ -8,6 +8,9 @@
#define PLLE0 (1<<0) #define PLLE0 (1<<0)
#define PLLC0 (1<<1) #define PLLC0 (1<<1)
#define PLOCK0 (1<<26) #define PLOCK0 (1<<26)
#define PLLE1 (1<<0)
#define PLLC1 (1<<1)
#define PLOCK1 (1<<10)
#define OSCEN (1<<5) #define OSCEN (1<<5)
#define OSCSTAT (1<<6) #define OSCSTAT (1<<6)
#define FLASHTIM(x) (((x-1)<<12)|0x3A) #define FLASHTIM(x) (((x-1)<<12)|0x3A)
@ -56,14 +59,18 @@ 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 PLL0feed(void);
void setPLL1MultPrediv(uint16_t mult, uint8_t prediv);
void enablePLL1(void);
void disablePLL1(void);
void connectPLL1(void);
void disconnectPLL1(void);
void PLL1feed(void);
void setCCLKDiv(uint8_t div); void setCCLKDiv(uint8_t div);
@ -71,7 +78,5 @@ void enableMainOsc( void );
void disableMainOsc(void); void disableMainOsc(void);
void PLL0feed( void );
void setClkSrc(uint8_t src); void setClkSrc(uint8_t src);
#endif #endif

View File

@ -96,4 +96,7 @@
#define SD_DAT (LPC_GPIO2->FIOPIN0) #define SD_DAT (LPC_GPIO2->FIOPIN0)
#define USB_CONNREG LPC_GPIO4
#define USB_CONNBIT 28
#endif #endif

View File

@ -20,8 +20,7 @@
/** /**
* Static table used for the table_driven implementation. * 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, 0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241,
0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440, 0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440,
0xcc01, 0x0cc0, 0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40, 0xcc01, 0x0cc0, 0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40,

View File

@ -22,8 +22,7 @@
/** /**
* Static table used for the table_driven implementation. * Static table used for the table_driven implementation.
*****************************************************************************/ *****************************************************************************/
static const uint32_t crc32_table[256] = static const uint32_t crc32_table[256] = {
{
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,

View File

@ -16,8 +16,7 @@
typedef BYTE DSTATUS; typedef BYTE DSTATUS;
/* Results of Disk Functions */ /* Results of Disk Functions */
typedef enum typedef enum {
{
RES_OK = 0, /* 0: Successful */ RES_OK = 0, /* 0: Successful */
RES_ERROR, /* 1: R/W Error */ RES_ERROR, /* 1: R/W Error */
RES_WRPRT, /* 2: Write Protected */ RES_WRPRT, /* 2: Write Protected */
@ -36,8 +35,7 @@ typedef enum
* This is the struct returned in the data buffer when disk_getinfo * This is the struct returned in the data buffer when disk_getinfo
* is called with page=0. * is called with page=0.
*/ */
typedef struct typedef struct {
{
uint8_t validbytes; uint8_t validbytes;
uint8_t maxpage; uint8_t maxpage;
uint8_t disktype; uint8_t disktype;

View File

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

3221
src/ff.c

File diff suppressed because it is too large Load Diff

View File

@ -229,8 +229,7 @@ extern "C" {
#if _MULTI_PARTITION /* Multiple partition configuration */ #if _MULTI_PARTITION /* Multiple partition configuration */
#define LD2PD(vol) (VolToPart[vol].pd) /* Get physical drive# */ #define LD2PD(vol) (VolToPart[vol].pd) /* Get physical drive# */
#define LD2PT(vol) (VolToPart[vol].pt) /* Get partition# */ #define LD2PT(vol) (VolToPart[vol].pt) /* Get partition# */
typedef struct typedef struct {
{
BYTE pd; /* Physical drive# */ BYTE pd; /* Physical drive# */
BYTE pt; /* Partition # (0-3) */ BYTE pt; /* Partition # (0-3) */
} PARTITION; } PARTITION;
@ -269,8 +268,7 @@ typedef char TCHAR;
/* File system object structure (FATFS) */ /* File system object structure (FATFS) */
typedef struct typedef struct {
{
BYTE fs_type; /* FAT sub-type (0:Not mounted) */ BYTE fs_type; /* FAT sub-type (0:Not mounted) */
BYTE drv; /* Physical drive number */ BYTE drv; /* Physical drive number */
BYTE csize; /* Sectors per cluster (1,2,4...128) */ BYTE csize; /* Sectors per cluster (1,2,4...128) */
@ -306,8 +304,7 @@ typedef struct
/* File object structure (FIL) */ /* File object structure (FIL) */
typedef struct typedef struct {
{
FATFS* fs; /* Pointer to the owner file system object */ FATFS* fs; /* Pointer to the owner file system object */
WORD id; /* Owner file system mount ID */ WORD id; /* Owner file system mount ID */
BYTE flag; /* File status flags */ BYTE flag; /* File status flags */
@ -336,8 +333,7 @@ typedef struct
/* Directory object structure (DIR) */ /* Directory object structure (DIR) */
typedef struct typedef struct {
{
FATFS* fs; /* Pointer to the owner file system object */ FATFS* fs; /* Pointer to the owner file system object */
WORD id; /* Owner file system mount ID */ WORD id; /* Owner file system mount ID */
WORD index; /* Current read/write index number */ WORD index; /* Current read/write index number */
@ -356,8 +352,7 @@ typedef struct
/* File status structure (FILINFO) */ /* File status structure (FILINFO) */
typedef struct typedef struct {
{
DWORD fsize; /* File size */ DWORD fsize; /* File size */
WORD fdate; /* Last modified date */ WORD fdate; /* Last modified date */
WORD ftime; /* Last modified time */ WORD ftime; /* Last modified time */
@ -374,8 +369,7 @@ typedef struct
/* File function return code (FRESULT) */ /* File function return code (FRESULT) */
typedef enum typedef enum {
{
FR_OK = 0, /* (0) Succeeded */ FR_OK = 0, /* (0) Succeeded */
FR_DISK_ERR, /* (1) A hard error occured in the low level disk I/O layer */ FR_DISK_ERR, /* (1) A hard error occured in the low level disk I/O layer */
FR_INT_ERR, /* (2) Assertion failed */ FR_INT_ERR, /* (2) Assertion failed */
@ -403,8 +397,7 @@ typedef enum
/* FatFs module application interface */ /* FatFs module application interface */
/* Low Level functions */ /* Low Level functions */
FRESULT l_openfilebycluster( FATFS *fs, FIL *fp, 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 */
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_opendirbycluster (FATFS *fs, DIR *dj, const TCHAR *path, DWORD clust);
/* application level functions */ /* application level functions */

View File

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

View File

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

View File

@ -37,8 +37,7 @@
#define FS_MAX_DEPTH (10) #define FS_MAX_DEPTH (10)
#define SYS_DIR_NAME ((const char*)"sd2snes") #define SYS_DIR_NAME ((const char*)"sd2snes")
typedef enum typedef enum {
{
TYPE_UNKNOWN = 0, /* 0 */ TYPE_UNKNOWN = 0, /* 0 */
TYPE_SMC, /* 1 */ TYPE_SMC, /* 1 */
TYPE_SRM, /* 2 */ TYPE_SRM, /* 2 */

View File

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

View File

@ -142,14 +142,12 @@
#include "timer.h" #include "timer.h"
#include "sdnative.h" #include "sdnative.h"
void fpga_spi_init( void ) void fpga_spi_init(void) {
{
spi_init(); spi_init();
BITBAND(FPGA_MCU_RDY_REG->FIODIR, FPGA_MCU_RDY_BIT) = 0; BITBAND(FPGA_MCU_RDY_REG->FIODIR, FPGA_MCU_RDY_BIT) = 0;
} }
void set_msu_addr( uint16_t address ) void set_msu_addr(uint16_t address) {
{
FPGA_SELECT(); FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_SETADDR | FPGA_TGT_MSUBUF); FPGA_TX_BYTE(FPGA_CMD_SETADDR | FPGA_TGT_MSUBUF);
FPGA_TX_BYTE((address>>8)&0xff); FPGA_TX_BYTE((address>>8)&0xff);
@ -157,8 +155,7 @@ void set_msu_addr( uint16_t address )
FPGA_DESELECT(); FPGA_DESELECT();
} }
void set_dac_addr( uint16_t address ) void set_dac_addr(uint16_t address) {
{
FPGA_SELECT(); FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_SETADDR | FPGA_TGT_DACBUF); FPGA_TX_BYTE(FPGA_CMD_SETADDR | FPGA_TGT_DACBUF);
FPGA_TX_BYTE((address>>8)&0xff); FPGA_TX_BYTE((address>>8)&0xff);
@ -166,8 +163,7 @@ void set_dac_addr( uint16_t address )
FPGA_DESELECT(); FPGA_DESELECT();
} }
void set_mcu_addr( uint32_t address ) void set_mcu_addr(uint32_t address) {
{
FPGA_SELECT(); FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_SETADDR | FPGA_TGT_MEM); FPGA_TX_BYTE(FPGA_CMD_SETADDR | FPGA_TGT_MEM);
FPGA_TX_BYTE((address>>16)&0xff); FPGA_TX_BYTE((address>>16)&0xff);
@ -176,8 +172,7 @@ void set_mcu_addr( uint32_t address )
FPGA_DESELECT(); FPGA_DESELECT();
} }
void set_saveram_mask( uint32_t mask ) void set_saveram_mask(uint32_t mask) {
{
FPGA_SELECT(); FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_SETRAMMASK); FPGA_TX_BYTE(FPGA_CMD_SETRAMMASK);
FPGA_TX_BYTE((mask>>16)&0xff); FPGA_TX_BYTE((mask>>16)&0xff);
@ -186,8 +181,7 @@ void set_saveram_mask( uint32_t mask )
FPGA_DESELECT(); FPGA_DESELECT();
} }
void set_rom_mask( uint32_t mask ) void set_rom_mask(uint32_t mask) {
{
FPGA_SELECT(); FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_SETROMMASK); FPGA_TX_BYTE(FPGA_CMD_SETROMMASK);
FPGA_TX_BYTE((mask>>16)&0xff); FPGA_TX_BYTE((mask>>16)&0xff);
@ -196,15 +190,13 @@ void set_rom_mask( uint32_t mask )
FPGA_DESELECT(); FPGA_DESELECT();
} }
void set_mapper( uint8_t val ) void set_mapper(uint8_t val) {
{
FPGA_SELECT(); FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_SETMAPPER(val)); FPGA_TX_BYTE(FPGA_CMD_SETMAPPER(val));
FPGA_DESELECT(); FPGA_DESELECT();
} }
uint8_t fpga_test() uint8_t fpga_test() {
{
FPGA_SELECT(); FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_TEST); FPGA_TX_BYTE(FPGA_CMD_TEST);
uint8_t result = FPGA_RX_BYTE(); uint8_t result = FPGA_RX_BYTE();
@ -212,8 +204,7 @@ uint8_t fpga_test()
return result; return result;
} }
uint16_t fpga_status() uint16_t fpga_status() {
{
FPGA_SELECT(); FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_GETSTATUS); FPGA_TX_BYTE(FPGA_CMD_GETSTATUS);
uint16_t result = (FPGA_RX_BYTE()) << 8; uint16_t result = (FPGA_RX_BYTE()) << 8;
@ -222,9 +213,7 @@ uint16_t fpga_status()
return result; return result;
} }
void fpga_set_sddma_range( uint16_t start, uint16_t end ) void fpga_set_sddma_range(uint16_t start, uint16_t end) {
{
printf( "%s %08X -> %08X\n", __func__, start, end );
FPGA_SELECT(); FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_SDDMA_RANGE); FPGA_TX_BYTE(FPGA_CMD_SDDMA_RANGE);
FPGA_TX_BYTE(start>>8); FPGA_TX_BYTE(start>>8);
@ -234,11 +223,7 @@ void fpga_set_sddma_range( uint16_t start, uint16_t end )
FPGA_DESELECT(); FPGA_DESELECT();
} }
void fpga_sddma( uint8_t tgt, uint8_t partial ) 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; BITBAND(SD_CLKREG->FIODIR, SD_CLKPIN) = 0;
FPGA_SELECT(); FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_SDDMA | (tgt & 3) | (partial ? FPGA_SDDMA_PARTIAL : 0)); FPGA_TX_BYTE(FPGA_CMD_SDDMA | (tgt & 3) | (partial ? FPGA_SDDMA_PARTIAL : 0));
@ -247,35 +232,29 @@ void fpga_sddma( uint8_t tgt, uint8_t partial )
FPGA_SELECT(); FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_GETSTATUS); FPGA_TX_BYTE(FPGA_CMD_GETSTATUS);
DBG_SD printf("FPGA DMA request sent, wait for completion..."); DBG_SD printf("FPGA DMA request sent, wait for completion...");
while(FPGA_RX_BYTE() & 0x80) {
while ( FPGA_RX_BYTE() & 0x80 )
{
FPGA_RX_BYTE(); /* eat the 2nd status byte */ FPGA_RX_BYTE(); /* eat the 2nd status byte */
} }
DBG_SD printf("...complete\n"); DBG_SD printf("...complete\n");
FPGA_DESELECT(); FPGA_DESELECT();
BITBAND(SD_CLKREG->FIODIR, SD_CLKPIN) = 1; BITBAND(SD_CLKREG->FIODIR, SD_CLKPIN) = 1;
} }
void dac_play() void dac_play() {
{
FPGA_SELECT(); FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_DACPLAY); FPGA_TX_BYTE(FPGA_CMD_DACPLAY);
FPGA_TX_BYTE(0x00); /* latch reset */ FPGA_TX_BYTE(0x00); /* latch reset */
FPGA_DESELECT(); FPGA_DESELECT();
} }
void dac_pause() void dac_pause() {
{
FPGA_SELECT(); FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_DACPAUSE); FPGA_TX_BYTE(FPGA_CMD_DACPAUSE);
FPGA_TX_BYTE(0x00); /* latch reset */ FPGA_TX_BYTE(0x00); /* latch reset */
FPGA_DESELECT(); FPGA_DESELECT();
} }
void dac_reset() void dac_reset() {
{
FPGA_SELECT(); FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_DACRESETPTR); FPGA_TX_BYTE(FPGA_CMD_DACRESETPTR);
FPGA_TX_BYTE(0x00); /* latch reset */ FPGA_TX_BYTE(0x00); /* latch reset */
@ -283,8 +262,7 @@ void dac_reset()
FPGA_DESELECT(); FPGA_DESELECT();
} }
void msu_reset( uint16_t address ) void msu_reset(uint16_t address) {
{
FPGA_SELECT(); FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_MSUSETPTR); FPGA_TX_BYTE(FPGA_CMD_MSUSETPTR);
FPGA_TX_BYTE((address>>8) & 0xff); /* address hi */ FPGA_TX_BYTE((address>>8) & 0xff); /* address hi */
@ -294,8 +272,7 @@ void msu_reset( uint16_t address )
FPGA_DESELECT(); FPGA_DESELECT();
} }
void set_msu_status( uint8_t set, uint8_t reset ) void set_msu_status(uint8_t set, uint8_t reset) {
{
FPGA_SELECT(); FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_MSUSETBITS); FPGA_TX_BYTE(FPGA_CMD_MSUSETBITS);
FPGA_TX_BYTE(set); FPGA_TX_BYTE(set);
@ -304,8 +281,7 @@ void set_msu_status( uint8_t set, uint8_t reset )
FPGA_DESELECT(); FPGA_DESELECT();
} }
uint16_t get_msu_track() uint16_t get_msu_track() {
{
FPGA_SELECT(); FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_MSUGETTRACK); FPGA_TX_BYTE(FPGA_CMD_MSUGETTRACK);
uint16_t result = (FPGA_RX_BYTE()) << 8; uint16_t result = (FPGA_RX_BYTE()) << 8;
@ -314,8 +290,7 @@ uint16_t get_msu_track()
return result; return result;
} }
uint32_t get_msu_offset() uint32_t get_msu_offset() {
{
FPGA_SELECT(); FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_MSUGETADDR); FPGA_TX_BYTE(FPGA_CMD_MSUGETADDR);
uint32_t result = (FPGA_RX_BYTE()) << 24; uint32_t result = (FPGA_RX_BYTE()) << 24;
@ -326,8 +301,7 @@ uint32_t get_msu_offset()
return result; return result;
} }
uint32_t get_snes_sysclk() uint32_t get_snes_sysclk() {
{
FPGA_SELECT(); FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_GETSYSCLK); FPGA_TX_BYTE(FPGA_CMD_GETSYSCLK);
FPGA_TX_BYTE(0x00); /* dummy (copy current sysclk count to register) */ FPGA_TX_BYTE(0x00); /* dummy (copy current sysclk count to register) */
@ -339,8 +313,7 @@ uint32_t get_snes_sysclk()
return result; return result;
} }
void set_bsx_regs( uint8_t set, uint8_t reset ) void set_bsx_regs(uint8_t set, uint8_t reset) {
{
FPGA_SELECT(); FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_BSXSETBITS); FPGA_TX_BYTE(FPGA_CMD_BSXSETBITS);
FPGA_TX_BYTE(set); FPGA_TX_BYTE(set);
@ -349,8 +322,7 @@ void set_bsx_regs( uint8_t set, uint8_t reset )
FPGA_DESELECT(); FPGA_DESELECT();
} }
void set_fpga_time( uint64_t time ) void set_fpga_time(uint64_t time) {
{
FPGA_SELECT(); FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_RTCSET); FPGA_TX_BYTE(FPGA_CMD_RTCSET);
FPGA_TX_BYTE((time >> 48) & 0xff); FPGA_TX_BYTE((time >> 48) & 0xff);
@ -364,8 +336,7 @@ void set_fpga_time( uint64_t time )
FPGA_DESELECT(); FPGA_DESELECT();
} }
void fpga_reset_srtc_state() void fpga_reset_srtc_state() {
{
FPGA_SELECT(); FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_SRTCRESET); FPGA_TX_BYTE(FPGA_CMD_SRTCRESET);
FPGA_TX_BYTE(0x00); FPGA_TX_BYTE(0x00);
@ -373,8 +344,7 @@ void fpga_reset_srtc_state()
FPGA_DESELECT(); FPGA_DESELECT();
} }
void fpga_reset_dspx_addr() void fpga_reset_dspx_addr() {
{
FPGA_SELECT(); FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_DSPRESETPTR); FPGA_TX_BYTE(FPGA_CMD_DSPRESETPTR);
FPGA_TX_BYTE(0x00); FPGA_TX_BYTE(0x00);
@ -382,8 +352,7 @@ void fpga_reset_dspx_addr()
FPGA_DESELECT(); FPGA_DESELECT();
} }
void fpga_write_dspx_pgm( uint32_t data ) void fpga_write_dspx_pgm(uint32_t data) {
{
FPGA_SELECT(); FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_DSPWRITEPGM); FPGA_TX_BYTE(FPGA_CMD_DSPWRITEPGM);
FPGA_TX_BYTE((data>>16)&0xff); FPGA_TX_BYTE((data>>16)&0xff);
@ -394,8 +363,7 @@ void fpga_write_dspx_pgm( uint32_t data )
FPGA_DESELECT(); FPGA_DESELECT();
} }
void fpga_write_dspx_dat( uint16_t data ) void fpga_write_dspx_dat(uint16_t data) {
{
FPGA_SELECT(); FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_DSPWRITEDAT); FPGA_TX_BYTE(FPGA_CMD_DSPWRITEDAT);
FPGA_TX_BYTE((data>>8)&0xff); FPGA_TX_BYTE((data>>8)&0xff);
@ -405,16 +373,14 @@ void fpga_write_dspx_dat( uint16_t data )
FPGA_DESELECT(); FPGA_DESELECT();
} }
void fpga_dspx_reset( uint8_t reset ) void fpga_dspx_reset(uint8_t reset) {
{
FPGA_SELECT(); FPGA_SELECT();
FPGA_TX_BYTE(reset ? FPGA_CMD_DSPRESET : FPGA_CMD_DSPUNRESET); FPGA_TX_BYTE(reset ? FPGA_CMD_DSPRESET : FPGA_CMD_DSPUNRESET);
FPGA_TX_BYTE(0x00); FPGA_TX_BYTE(0x00);
FPGA_DESELECT(); FPGA_DESELECT();
} }
void fpga_set_features( uint8_t feat ) void fpga_set_features(uint8_t feat) {
{
printf("set features: %02x\n", feat); printf("set features: %02x\n", feat);
FPGA_SELECT(); FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_SETFEATURE); FPGA_TX_BYTE(FPGA_CMD_SETFEATURE);
@ -422,8 +388,7 @@ void fpga_set_features( uint8_t feat )
FPGA_DESELECT(); FPGA_DESELECT();
} }
void fpga_set_213f( uint8_t data ) void fpga_set_213f(uint8_t data) {
{
printf("set 213f: %d\n", data); printf("set 213f: %d\n", data);
FPGA_SELECT(); FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_SET213F); FPGA_TX_BYTE(FPGA_CMD_SET213F);

View File

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

View File

@ -22,68 +22,48 @@ int led_pwmstate = 0;
write red P1.23 PWM1[4] write red P1.23 PWM1[4]
*/ */
void rdyled( unsigned int state ) void rdyled(unsigned int state) {
{ if(led_pwmstate) {
if ( led_pwmstate )
{
rdybright(state?15:0); rdybright(state?15:0);
} } else {
else
{
BITBAND(LPC_GPIO2->FIODIR, 4) = state; BITBAND(LPC_GPIO2->FIODIR, 4) = state;
} }
led_rdyledstate = state; led_rdyledstate = state;
} }
void readled( unsigned int state ) void readled(unsigned int state) {
{ if(led_pwmstate) {
if ( led_pwmstate )
{
readbright(state?15:0); readbright(state?15:0);
} } else {
else
{
BITBAND(LPC_GPIO2->FIODIR, 5) = state; BITBAND(LPC_GPIO2->FIODIR, 5) = state;
} }
led_readledstate = state; led_readledstate = state;
} }
void writeled( unsigned int state ) void writeled(unsigned int state) {
{ if(led_pwmstate) {
if ( led_pwmstate )
{
writebright(state?15:0); writebright(state?15:0);
} } else {
else
{
BITBAND(LPC_GPIO1->FIODIR, 23) = state; BITBAND(LPC_GPIO1->FIODIR, 23) = state;
} }
led_writeledstate = state; led_writeledstate = state;
} }
void rdybright( uint8_t bright ) void rdybright(uint8_t bright) {
{
LPC_PWM1->MR5 = led_bright[(bright & 15)]; LPC_PWM1->MR5 = led_bright[(bright & 15)];
BITBAND(LPC_PWM1->LER, 5) = 1; BITBAND(LPC_PWM1->LER, 5) = 1;
} }
void readbright( uint8_t bright ) void readbright(uint8_t bright) {
{
LPC_PWM1->MR6 = led_bright[(bright & 15)]; LPC_PWM1->MR6 = led_bright[(bright & 15)];
BITBAND(LPC_PWM1->LER, 6) = 1; BITBAND(LPC_PWM1->LER, 6) = 1;
} }
void writebright( uint8_t bright ) void writebright(uint8_t bright) {
{
LPC_PWM1->MR4 = led_bright[(bright & 15)]; LPC_PWM1->MR4 = led_bright[(bright & 15)];
BITBAND(LPC_PWM1->LER, 4) = 1; BITBAND(LPC_PWM1->LER, 4) = 1;
} }
void led_clkout32( uint32_t val ) void led_clkout32(uint32_t val) {
{ while(1) {
while ( 1 )
{
rdyled(1); rdyled(1);
delay_ms(400); delay_ms(400);
readled((val & BV(31))>>31); readled((val & BV(31))>>31);
@ -93,30 +73,24 @@ void led_clkout32( uint32_t val )
} }
} }
void toggle_rdy_led() void toggle_rdy_led() {
{
rdyled(~led_rdyledstate); rdyled(~led_rdyledstate);
} }
void toggle_read_led() void toggle_read_led() {
{
readled(~led_readledstate); readled(~led_readledstate);
} }
void toggle_write_led() void toggle_write_led() {
{
writeled(~led_writeledstate); writeled(~led_writeledstate);
} }
void led_panic() void led_panic(uint8_t led_states) {
{
led_std(); led_std();
while(1) {
while ( 1 ) rdyled((led_states >> 2) & 1);
{ readled((led_states >> 1) & 1);
rdyled( 1 ); writeled(led_states & 1);
readled( 1 );
writeled( 1 );
delay_ms(100); delay_ms(100);
rdyled(0); rdyled(0);
readled(0); readled(0);
@ -126,8 +100,7 @@ void led_panic()
} }
} }
void led_pwm() void led_pwm() {
{
/* Rev.C P2.4, P2.5, P1.23 */ /* Rev.C P2.4, P2.5, P1.23 */
BITBAND(LPC_PINCON->PINSEL4, 9) = 0; BITBAND(LPC_PINCON->PINSEL4, 9) = 0;
BITBAND(LPC_PINCON->PINSEL4, 8) = 1; BITBAND(LPC_PINCON->PINSEL4, 8) = 1;
@ -145,8 +118,7 @@ void led_pwm()
led_pwmstate = 1; led_pwmstate = 1;
} }
void led_std() void led_std() {
{
BITBAND(LPC_PINCON->PINSEL4, 9) = 0; BITBAND(LPC_PINCON->PINSEL4, 9) = 0;
BITBAND(LPC_PINCON->PINSEL4, 8) = 0; BITBAND(LPC_PINCON->PINSEL4, 8) = 0;
@ -163,8 +135,7 @@ void led_std()
led_pwmstate = 0; led_pwmstate = 0;
} }
void led_init() void led_init() {
{
/* power is already connected by default */ /* power is already connected by default */
/* set PCLK divider to 8 */ /* set PCLK divider to 8 */
BITBAND(LPC_SC->PCLKSEL0, 13) = 1; BITBAND(LPC_SC->PCLKSEL0, 13) = 1;

View File

@ -3,6 +3,12 @@
#ifndef _LED_H #ifndef _LED_H
#define _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 readbright(uint8_t bright);
void writebright(uint8_t bright); void writebright(uint8_t bright);
void rdybright(uint8_t bright); void rdybright(uint8_t bright);
@ -13,7 +19,7 @@ void led_clkout32(uint32_t val);
void toggle_rdy_led(void); void toggle_rdy_led(void);
void toggle_read_led(void); void toggle_read_led(void);
void toggle_write_led(void); void toggle_write_led(void);
void led_panic(void); void led_panic(uint8_t led_states);
void led_pwm(void); void led_pwm(void);
void led_std(void); void led_std(void);
void led_init(void); void led_init(void);

View File

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

View File

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

View File

@ -49,21 +49,16 @@ char *hex = "0123456789ABCDEF";
extern snes_romprops_t romprops; extern snes_romprops_t romprops;
void sram_hexdump( uint32_t addr, uint32_t len ) void sram_hexdump(uint32_t addr, uint32_t len) {
{
static uint8_t buf[16]; static uint8_t buf[16];
uint32_t ptr; uint32_t ptr;
for(ptr=0; ptr < len; ptr += 16) {
for ( ptr = 0; ptr < len; ptr += 16 )
{
sram_readblock((void*)buf, ptr+addr, 16); sram_readblock((void*)buf, ptr+addr, 16);
uart_trace( buf, 0, 16, addr ); uart_trace(buf, 0, 16);
} }
} }
void sram_writebyte( uint8_t val, uint32_t addr ) void sram_writebyte(uint8_t val, uint32_t addr) {
{
//printf("WriteB %8Xh @%08lXh\n", val, addr);
set_mcu_addr(addr); set_mcu_addr(addr);
FPGA_SELECT(); FPGA_SELECT();
FPGA_TX_BYTE(0x98); /* WRITE */ FPGA_TX_BYTE(0x98); /* WRITE */
@ -72,21 +67,17 @@ void sram_writebyte( uint8_t val, uint32_t addr )
FPGA_DESELECT(); FPGA_DESELECT();
} }
uint8_t sram_readbyte( uint32_t addr ) uint8_t sram_readbyte(uint32_t addr) {
{
set_mcu_addr(addr); set_mcu_addr(addr);
FPGA_SELECT(); FPGA_SELECT();
FPGA_TX_BYTE(0x88); /* READ */ FPGA_TX_BYTE(0x88); /* READ */
FPGA_WAIT_RDY(); FPGA_WAIT_RDY();
uint8_t val = FPGA_RX_BYTE(); uint8_t val = FPGA_RX_BYTE();
FPGA_DESELECT(); FPGA_DESELECT();
//printf(" ReadB %8Xh @%08lXh\n", val, addr);
return val; return val;
} }
void sram_writeshort( uint16_t val, uint32_t addr ) void sram_writeshort(uint16_t val, uint32_t addr) {
{
//printf("WriteS %8Xh @%08lXh\n", val, addr);
set_mcu_addr(addr); set_mcu_addr(addr);
FPGA_SELECT(); FPGA_SELECT();
FPGA_TX_BYTE(0x98); /* WRITE */ FPGA_TX_BYTE(0x98); /* WRITE */
@ -97,9 +88,7 @@ void sram_writeshort( uint16_t val, uint32_t addr )
FPGA_DESELECT(); FPGA_DESELECT();
} }
void sram_writelong( uint32_t val, uint32_t addr ) void sram_writelong(uint32_t val, uint32_t addr) {
{
//printf("WriteL %8lXh @%08lXh\n", val, addr);
set_mcu_addr(addr); set_mcu_addr(addr);
FPGA_SELECT(); FPGA_SELECT();
FPGA_TX_BYTE(0x98); /* WRITE */ FPGA_TX_BYTE(0x98); /* WRITE */
@ -114,8 +103,7 @@ void sram_writelong( uint32_t val, uint32_t addr )
FPGA_DESELECT(); FPGA_DESELECT();
} }
uint16_t sram_readshort( uint32_t addr ) uint16_t sram_readshort(uint32_t addr) {
{
set_mcu_addr(addr); set_mcu_addr(addr);
FPGA_SELECT(); FPGA_SELECT();
FPGA_TX_BYTE(0x88); FPGA_TX_BYTE(0x88);
@ -124,12 +112,10 @@ uint16_t sram_readshort( uint32_t addr )
FPGA_WAIT_RDY(); FPGA_WAIT_RDY();
val |= ((uint32_t)FPGA_RX_BYTE()<<8); val |= ((uint32_t)FPGA_RX_BYTE()<<8);
FPGA_DESELECT(); FPGA_DESELECT();
//printf(" ReadS %8lXh @%08lXh\n", val, addr);
return val; return val;
} }
uint32_t sram_readlong( uint32_t addr ) uint32_t sram_readlong(uint32_t addr) {
{
set_mcu_addr(addr); set_mcu_addr(addr);
FPGA_SELECT(); FPGA_SELECT();
FPGA_TX_BYTE(0x88); FPGA_TX_BYTE(0x88);
@ -142,19 +128,15 @@ uint32_t sram_readlong( uint32_t addr )
FPGA_WAIT_RDY(); FPGA_WAIT_RDY();
val |= ((uint32_t)FPGA_RX_BYTE()<<24); val |= ((uint32_t)FPGA_RX_BYTE()<<24);
FPGA_DESELECT(); FPGA_DESELECT();
//printf(" ReadL %8lXh @%08lXh\n", val, addr);
return val; return val;
} }
void sram_readlongblock( uint32_t *buf, uint32_t addr, uint16_t count ) void sram_readlongblock(uint32_t* buf, uint32_t addr, uint16_t count) {
{
set_mcu_addr(addr); set_mcu_addr(addr);
FPGA_SELECT(); FPGA_SELECT();
FPGA_TX_BYTE(0x88); FPGA_TX_BYTE(0x88);
uint16_t i=0; uint16_t i=0;
while(i<count) {
while ( i < count )
{
FPGA_WAIT_RDY(); FPGA_WAIT_RDY();
uint32_t val = (uint32_t)FPGA_RX_BYTE()<<24; uint32_t val = (uint32_t)FPGA_RX_BYTE()<<24;
FPGA_WAIT_RDY(); FPGA_WAIT_RDY();
@ -165,127 +147,89 @@ void sram_readlongblock( uint32_t *buf, uint32_t addr, uint16_t count )
val |= FPGA_RX_BYTE(); val |= FPGA_RX_BYTE();
buf[i++] = val; buf[i++] = val;
} }
FPGA_DESELECT(); FPGA_DESELECT();
} }
void sram_readblock( void *buf, uint32_t addr, uint16_t size ) void sram_readblock(void* buf, uint32_t addr, uint16_t size) {
{
uint16_t count=size; uint16_t count=size;
uint8_t* tgt = buf; uint8_t* tgt = buf;
set_mcu_addr(addr); set_mcu_addr(addr);
FPGA_SELECT(); FPGA_SELECT();
FPGA_TX_BYTE(0x88); /* READ */ FPGA_TX_BYTE(0x88); /* READ */
while(count--) {
while ( count-- )
{
FPGA_WAIT_RDY(); FPGA_WAIT_RDY();
*(tgt++) = FPGA_RX_BYTE(); *(tgt++) = FPGA_RX_BYTE();
} }
FPGA_DESELECT(); FPGA_DESELECT();
} }
void sram_readstrn( void *buf, uint32_t addr, uint16_t size ) void sram_readstrn(void* buf, uint32_t addr, uint16_t size) {
{
uint16_t count=size; uint16_t count=size;
uint8_t* tgt = buf; uint8_t* tgt = buf;
set_mcu_addr(addr); set_mcu_addr(addr);
FPGA_SELECT(); FPGA_SELECT();
FPGA_TX_BYTE(0x88); /* READ */ FPGA_TX_BYTE(0x88); /* READ */
while(count--) {
while ( count-- )
{
FPGA_WAIT_RDY(); FPGA_WAIT_RDY();
if(!(*(tgt++) = FPGA_RX_BYTE())) break;
if ( !( *( tgt++ ) = FPGA_RX_BYTE() ) )
{
break;
} }
}
FPGA_DESELECT(); FPGA_DESELECT();
} }
void sram_writeblock( void *buf, uint32_t addr, uint16_t size ) void sram_writeblock(void* buf, uint32_t addr, uint16_t size) {
{
//printf("WriteZ %08lX -> %08lX [%d]\n", addr, addr+size, size);
uint16_t count=size; uint16_t count=size;
uint8_t* src = buf; uint8_t* src = buf;
set_mcu_addr(addr); set_mcu_addr(addr);
FPGA_SELECT(); FPGA_SELECT();
FPGA_TX_BYTE(0x98); /* WRITE */ FPGA_TX_BYTE(0x98); /* WRITE */
while(count--) {
while ( count-- )
{
FPGA_TX_BYTE(*src++); FPGA_TX_BYTE(*src++);
FPGA_WAIT_RDY(); FPGA_WAIT_RDY();
} }
FPGA_DESELECT(); FPGA_DESELECT();
} }
uint32_t load_rom( uint8_t *filename, uint32_t base_addr, uint8_t flags ) uint32_t load_rom(uint8_t* filename, uint32_t base_addr, uint8_t flags) {
{
UINT bytes_read; UINT bytes_read;
DWORD filesize, read_size = 0; DWORD filesize;
UINT count=0; UINT count=0;
tick_t ticksstart, ticks_total=0; tick_t ticksstart, ticks_total=0;
ticksstart=getticks(); ticksstart=getticks();
printf("%s\n", filename); printf("%s\n", filename);
file_open(filename, FA_READ); file_open(filename, FA_READ);
if(file_res) {
if ( file_res )
{
uart_putc('?'); uart_putc('?');
uart_putc(0x30+file_res); uart_putc(0x30+file_res);
return 0; return 0;
} }
filesize = file_handle.fsize; filesize = file_handle.fsize;
smc_id(&romprops); smc_id(&romprops);
file_close(); file_close();
/* reconfigure FPGA if necessary */ /* reconfigure FPGA if necessary */
if ( romprops.fpga_conf ) if(romprops.fpga_conf) {
{
printf("reconfigure FPGA with %s...\n", romprops.fpga_conf); printf("reconfigure FPGA with %s...\n", romprops.fpga_conf);
fpga_pgm((uint8_t*)romprops.fpga_conf); fpga_pgm((uint8_t*)romprops.fpga_conf);
} }
set_mcu_addr(base_addr + romprops.load_address);
set_mcu_addr( base_addr );
file_open(filename, FA_READ); file_open(filename, FA_READ);
ff_sd_offload=1; ff_sd_offload=1;
sd_offload_tgt=0; sd_offload_tgt=0;
f_lseek(&file_handle, romprops.offset); f_lseek(&file_handle, romprops.offset);
for(;;) {
for ( ;; )
{
ff_sd_offload=1; ff_sd_offload=1;
sd_offload_tgt=0; sd_offload_tgt=0;
bytes_read = file_read(); bytes_read = file_read();
read_size += bytes_read; if (file_res || !bytes_read) break;
if(!(count++ % 512)) {
if ( file_res || !bytes_read )
{
break;
}
if ( !( count++ % 512 ) )
{
uart_putc('.'); uart_putc('.');
} }
} }
file_close(); file_close();
printf( "Read %ld [%08lX] bytes...\n", read_size, read_size );
set_mapper(romprops.mapper_id); set_mapper(romprops.mapper_id);
printf("rom header map: %02x; mapper id: %d\n", romprops.header.map, romprops.mapper_id); printf("rom header map: %02x; mapper id: %d\n", romprops.header.map, romprops.mapper_id);
ticks_total=getticks()-ticksstart; ticks_total=getticks()-ticksstart;
printf("%u ticks total\n", ticks_total); printf("%u ticks total\n", ticks_total);
if(romprops.mapper_id==3) {
if ( romprops.mapper_id == 3 )
{
printf("BSX Flash cart image\n"); printf("BSX Flash cart image\n");
printf("attempting to load BSX BIOS /sd2snes/bsxbios.bin...\n"); printf("attempting to load BSX BIOS /sd2snes/bsxbios.bin...\n");
load_sram_offload((uint8_t*)"/sd2snes/bsxbios.bin", 0x800000); load_sram_offload((uint8_t*)"/sd2snes/bsxbios.bin", 0x800000);
@ -294,97 +238,63 @@ uint32_t load_rom( uint8_t *filename, uint32_t base_addr, uint8_t flags )
printf("Type: %02x\n", romprops.header.destcode); printf("Type: %02x\n", romprops.header.destcode);
set_bsx_regs(0xc0, 0x3f); set_bsx_regs(0xc0, 0x3f);
uint16_t rombase; uint16_t rombase;
if(romprops.header.ramsize & 1) {
if ( romprops.header.ramsize & 1 )
{
rombase = 0xff00; rombase = 0xff00;
// set_bsx_regs(0x36, 0xc9); // set_bsx_regs(0x36, 0xc9);
} } else {
else
{
rombase = 0x7f00; rombase = 0x7f00;
// set_bsx_regs(0x34, 0xcb); // set_bsx_regs(0x34, 0xcb);
} }
sram_writebyte(0x33, rombase+0xda); sram_writebyte(0x33, rombase+0xda);
sram_writebyte(0x00, rombase+0xd4); sram_writebyte(0x00, rombase+0xd4);
sram_writebyte(0xfc, rombase+0xd5); sram_writebyte(0xfc, rombase+0xd5);
set_fpga_time(0x0220110301180530LL); set_fpga_time(0x0220110301180530LL);
} }
if(romprops.has_dspx || romprops.has_cx4) {
if ( romprops.has_dspx || romprops.has_cx4 )
{
printf("DSPx game. Loading firmware image %s...\n", romprops.dsp_fw); printf("DSPx game. Loading firmware image %s...\n", romprops.dsp_fw);
load_dspx(romprops.dsp_fw, romprops.fpga_features); load_dspx(romprops.dsp_fw, romprops.fpga_features);
/* fallback to DSP1B firmware if DSP1.bin is not present */ /* fallback to DSP1B firmware if DSP1.bin is not present */
if ( file_res && romprops.dsp_fw == DSPFW_1 ) if(file_res && romprops.dsp_fw == DSPFW_1) {
{
load_dspx(DSPFW_1B, romprops.fpga_features); load_dspx(DSPFW_1B, romprops.fpga_features);
} }
if(file_res) {
if ( file_res )
{
snes_menu_errmsg(MENU_ERR_NODSP, (void*)romprops.dsp_fw); snes_menu_errmsg(MENU_ERR_NODSP, (void*)romprops.dsp_fw);
} }
} }
uint32_t rammask; uint32_t rammask;
uint32_t rommask; uint32_t rommask;
while ( filesize > ( romprops.romsize_bytes + romprops.offset ) ) while(filesize > (romprops.romsize_bytes + romprops.offset)) {
{
romprops.romsize_bytes <<= 1; romprops.romsize_bytes <<= 1;
} }
if ( romprops.header.ramsize == 0 ) if(romprops.header.ramsize == 0) {
{
rammask = 0; rammask = 0;
} } else {
else
{
rammask = romprops.ramsize_bytes - 1; rammask = romprops.ramsize_bytes - 1;
} }
rommask = romprops.romsize_bytes - 1; rommask = romprops.romsize_bytes - 1;
printf("ramsize=%x rammask=%lx\nromsize=%x rommask=%lx\n", romprops.header.ramsize, rammask, romprops.header.romsize, rommask);
if ( rommask >= SRAM_SAVE_ADDR )
{
rommask = SRAM_SAVE_ADDR - 1;
}
printf( "ramsize=%x rammask=%lx\nromsize=%x rommask=%lx\n", romprops.header.ramsize, rammask, romprops.header.romsize,
rommask );
set_saveram_mask(rammask); set_saveram_mask(rammask);
set_rom_mask(rommask); set_rom_mask(rommask);
readled(0); readled(0);
if(flags & LOADROM_WITH_SRAM) {
if ( flags & LOADROM_WITH_SRAM ) if(romprops.ramsize_bytes) {
{
if ( romprops.ramsize_bytes )
{
strcpy(strrchr((char*)filename, (int)'.'), ".srm"); strcpy(strrchr((char*)filename, (int)'.'), ".srm");
printf("SRM file: %s\n", filename); printf("SRM file: %s\n", filename);
load_sram(filename, SRAM_SAVE_ADDR); load_sram(filename, SRAM_SAVE_ADDR);
} } else {
else
{
printf("No SRAM\n"); printf("No SRAM\n");
} }
} }
printf("check MSU..."); printf("check MSU...");
if(msu1_check(filename)) {
if ( msu1_check( filename ) )
{
romprops.fpga_features |= FEAT_MSU1; romprops.fpga_features |= FEAT_MSU1;
romprops.has_msu1 = 1; romprops.has_msu1 = 1;
} } else {
else
{
romprops.has_msu1 = 0; romprops.has_msu1 = 0;
} }
printf("done\n"); printf("done\n");
romprops.fpga_features |= FEAT_SRTC; romprops.fpga_features |= FEAT_SRTC;
@ -393,8 +303,7 @@ uint32_t load_rom( uint8_t *filename, uint32_t base_addr, uint8_t flags )
fpga_set_213f(romprops.region); fpga_set_213f(romprops.region);
fpga_set_features(romprops.fpga_features); fpga_set_features(romprops.fpga_features);
if ( flags & LOADROM_WITH_RESET ) if(flags & LOADROM_WITH_RESET) {
{
fpga_dspx_reset(1); fpga_dspx_reset(1);
snes_reset_pulse(); snes_reset_pulse();
fpga_dspx_reset(0); fpga_dspx_reset(0);
@ -403,8 +312,7 @@ uint32_t load_rom( uint8_t *filename, uint32_t base_addr, uint8_t flags )
return (uint32_t)filesize; return (uint32_t)filesize;
} }
uint32_t load_spc( uint8_t *filename, uint32_t spc_data_addr, uint32_t spc_header_addr ) uint32_t load_spc(uint8_t* filename, uint32_t spc_data_addr, uint32_t spc_header_addr) {
{
DWORD filesize; DWORD filesize;
UINT bytes_read; UINT bytes_read;
uint8_t data; uint8_t data;
@ -413,16 +321,9 @@ uint32_t load_spc( uint8_t *filename, uint32_t spc_data_addr, uint32_t spc_heade
printf("%s\n", filename); printf("%s\n", filename);
file_open(filename, FA_READ); /* Open SPC file */ file_open(filename, FA_READ); /* Open SPC file */
if(file_res) return 0;
if ( file_res )
{
return 0;
}
filesize = file_handle.fsize; filesize = file_handle.fsize;
if (filesize < 65920) { /* At this point, we care about filesize only */
if ( filesize < 65920 ) /* At this point, we care about filesize only */
{
file_close(); /* since SNES decides if it is an SPC file */ file_close(); /* since SNES decides if it is an SPC file */
sram_writebyte(0, spc_header_addr); /* If file is too small, destroy previous SPC header */ sram_writebyte(0, spc_header_addr); /* If file is too small, destroy previous SPC header */
return 0; return 0;
@ -431,24 +332,15 @@ uint32_t load_spc( uint8_t *filename, uint32_t spc_data_addr, uint32_t spc_heade
set_mcu_addr(spc_data_addr); set_mcu_addr(spc_data_addr);
f_lseek(&file_handle, 0x100L); /* Load 64K data segment */ f_lseek(&file_handle, 0x100L); /* Load 64K data segment */
for ( ;; ) for(;;) {
{
bytes_read = file_read(); bytes_read = file_read();
if (file_res || !bytes_read) break;
if ( file_res || !bytes_read )
{
break;
}
FPGA_SELECT(); FPGA_SELECT();
FPGA_TX_BYTE(0x98); FPGA_TX_BYTE(0x98);
for(j=0; j<bytes_read; j++) {
for ( j = 0; j < bytes_read; j++ )
{
FPGA_TX_BYTE(file_buf[j]); FPGA_TX_BYTE(file_buf[j]);
FPGA_WAIT_RDY(); FPGA_WAIT_RDY();
} }
FPGA_DESELECT(); FPGA_DESELECT();
} }
@ -460,14 +352,11 @@ uint32_t load_spc( uint8_t *filename, uint32_t spc_data_addr, uint32_t spc_heade
FPGA_SELECT(); FPGA_SELECT();
FPGA_TX_BYTE(0x98); FPGA_TX_BYTE(0x98);
for (j = 0; j < 256; j++) {
for ( j = 0; j < 256; j++ )
{
data = file_getc(); data = file_getc();
FPGA_TX_BYTE(data); FPGA_TX_BYTE(data);
FPGA_WAIT_RDY(); FPGA_WAIT_RDY();
} }
FPGA_DESELECT(); FPGA_DESELECT();
file_close(); file_close();
@ -478,14 +367,11 @@ uint32_t load_spc( uint8_t *filename, uint32_t spc_data_addr, uint32_t spc_heade
FPGA_SELECT(); FPGA_SELECT();
FPGA_TX_BYTE(0x98); FPGA_TX_BYTE(0x98);
for (j = 0; j < 128; j++) {
for ( j = 0; j < 128; j++ )
{
data = file_getc(); data = file_getc();
FPGA_TX_BYTE(data); FPGA_TX_BYTE(data);
FPGA_WAIT_RDY(); FPGA_WAIT_RDY();
} }
FPGA_DESELECT(); FPGA_DESELECT();
file_close(); /* Done ! */ file_close(); /* Done ! */
@ -493,9 +379,7 @@ uint32_t load_spc( uint8_t *filename, uint32_t spc_data_addr, uint32_t spc_heade
uint8_t esa = sram_readbyte(spc_header_addr+0x100+0x6d); uint8_t esa = sram_readbyte(spc_header_addr+0x100+0x6d);
uint8_t edl = sram_readbyte(spc_header_addr+0x100+0x7d); uint8_t edl = sram_readbyte(spc_header_addr+0x100+0x7d);
uint8_t flg = sram_readbyte(spc_header_addr+0x100+0x6c); uint8_t flg = sram_readbyte(spc_header_addr+0x100+0x6c);
if(!(flg & 0x20) && (edl & 0x0f)) {
if ( !( flg & 0x20 ) && ( edl & 0x0f ) )
{
int echo_start = esa << 8; int echo_start = esa << 8;
int echo_length = (edl & 0x0f) << 11; int echo_length = (edl & 0x0f) << 11;
printf("clearing echo buffer %04x-%04x...\n", echo_start, echo_start+echo_length-1); printf("clearing echo buffer %04x-%04x...\n", echo_start, echo_start+echo_length-1);
@ -505,110 +389,69 @@ uint32_t load_spc( uint8_t *filename, uint32_t spc_data_addr, uint32_t spc_heade
return (uint32_t)filesize; return (uint32_t)filesize;
} }
uint32_t load_sram_offload( uint8_t *filename, uint32_t base_addr ) uint32_t load_sram_offload(uint8_t* filename, uint32_t base_addr) {
{
set_mcu_addr(base_addr); set_mcu_addr(base_addr);
UINT bytes_read; UINT bytes_read;
DWORD filesize; DWORD filesize;
file_open(filename, FA_READ); file_open(filename, FA_READ);
filesize = file_handle.fsize; filesize = file_handle.fsize;
if(file_res) return 0;
if ( file_res ) for(;;) {
{
return 0;
}
for ( ;; )
{
ff_sd_offload=1; ff_sd_offload=1;
sd_offload_tgt=0; sd_offload_tgt=0;
bytes_read = file_read(); bytes_read = file_read();
if (file_res || !bytes_read) break;
if ( file_res || !bytes_read )
{
break;
} }
}
file_close(); file_close();
return (uint32_t)filesize; return (uint32_t)filesize;
} }
uint32_t load_sram( uint8_t *filename, uint32_t base_addr ) uint32_t load_sram(uint8_t* filename, uint32_t base_addr) {
{
set_mcu_addr(base_addr); set_mcu_addr(base_addr);
UINT bytes_read; UINT bytes_read;
DWORD filesize; DWORD filesize;
file_open(filename, FA_READ); file_open(filename, FA_READ);
filesize = file_handle.fsize; filesize = file_handle.fsize;
if(file_res) {
if ( file_res )
{
printf("load_sram: could not open %s, res=%d\n", filename, file_res); printf("load_sram: could not open %s, res=%d\n", filename, file_res);
return 0; return 0;
} }
for(;;) {
for ( ;; )
{
bytes_read = file_read(); bytes_read = file_read();
if (file_res || !bytes_read) break;
if ( file_res || !bytes_read )
{
break;
}
FPGA_SELECT(); FPGA_SELECT();
FPGA_TX_BYTE(0x98); FPGA_TX_BYTE(0x98);
for(int j=0; j<bytes_read; j++) {
for ( int j = 0; j < bytes_read; j++ )
{
FPGA_TX_BYTE(file_buf[j]); FPGA_TX_BYTE(file_buf[j]);
FPGA_WAIT_RDY(); FPGA_WAIT_RDY();
} }
FPGA_DESELECT(); FPGA_DESELECT();
} }
file_close(); file_close();
return (uint32_t)filesize; return (uint32_t)filesize;
} }
uint32_t load_sram_rle( uint8_t *filename, uint32_t base_addr ) uint32_t load_sram_rle(uint8_t* filename, uint32_t base_addr) {
{
uint8_t data; uint8_t data;
set_mcu_addr(base_addr); set_mcu_addr(base_addr);
DWORD filesize; DWORD filesize;
file_open(filename, FA_READ); file_open(filename, FA_READ);
filesize = file_handle.fsize; filesize = file_handle.fsize;
if(file_res) return 0;
if ( file_res )
{
return 0;
}
FPGA_SELECT(); FPGA_SELECT();
FPGA_TX_BYTE(0x98); FPGA_TX_BYTE(0x98);
for(;;) {
for ( ;; )
{
data = rle_file_getc(); data = rle_file_getc();
if (file_res || file_status) break;
if ( file_res || file_status )
{
break;
}
FPGA_TX_BYTE(data); FPGA_TX_BYTE(data);
FPGA_WAIT_RDY(); FPGA_WAIT_RDY();
} }
FPGA_DESELECT(); FPGA_DESELECT();
file_close(); file_close();
return (uint32_t)filesize; return (uint32_t)filesize;
} }
uint32_t load_bootrle( uint32_t base_addr ) uint32_t load_bootrle(uint32_t base_addr) {
{
uint8_t data; uint8_t data;
set_mcu_addr(base_addr); set_mcu_addr(base_addr);
DWORD filesize = 0; DWORD filesize = 0;
@ -616,67 +459,46 @@ uint32_t load_bootrle( uint32_t base_addr )
FPGA_SELECT(); FPGA_SELECT();
FPGA_TX_BYTE(0x98); FPGA_TX_BYTE(0x98);
for(;;) {
for ( ;; )
{
data = rle_mem_getc(); data = rle_mem_getc();
if(rle_state) break;
if ( rle_state )
{
break;
}
FPGA_TX_BYTE(data); FPGA_TX_BYTE(data);
FPGA_WAIT_RDY(); FPGA_WAIT_RDY();
filesize++; filesize++;
} }
FPGA_DESELECT(); FPGA_DESELECT();
return (uint32_t)filesize; return (uint32_t)filesize;
} }
void save_sram( uint8_t *filename, uint32_t sram_size, uint32_t base_addr ) void save_sram(uint8_t* filename, uint32_t sram_size, uint32_t base_addr) {
{
uint32_t count = 0; uint32_t count = 0;
//uint32_t num = 0;
FPGA_DESELECT(); FPGA_DESELECT();
file_open(filename, FA_CREATE_ALWAYS | FA_WRITE); file_open(filename, FA_CREATE_ALWAYS | FA_WRITE);
if(file_res) {
if ( file_res )
{
uart_putc(0x30+file_res); uart_putc(0x30+file_res);
} }
while(count<sram_size) {
while ( count < sram_size )
{
set_mcu_addr(base_addr+count); set_mcu_addr(base_addr+count);
FPGA_SELECT(); FPGA_SELECT();
FPGA_TX_BYTE(0x88); /* read */ FPGA_TX_BYTE(0x88); /* read */
for(int j=0; j<sizeof(file_buf); j++) {
for ( int j = 0; j < sizeof( file_buf ); j++ )
{
FPGA_WAIT_RDY(); FPGA_WAIT_RDY();
file_buf[j] = FPGA_RX_BYTE(); file_buf[j] = FPGA_RX_BYTE();
count++; count++;
} }
FPGA_DESELECT(); FPGA_DESELECT();
/*num = */file_write(); file_write();
if(file_res) {
if ( file_res )
{
uart_putc(0x30+file_res); uart_putc(0x30+file_res);
} }
} }
file_close(); file_close();
} }
uint32_t calc_sram_crc( uint32_t base_addr, uint32_t size ) uint32_t calc_sram_crc(uint32_t base_addr, uint32_t size) {
{
uint8_t data; uint8_t data;
uint32_t count; uint32_t count;
uint32_t crc; uint32_t crc;
@ -685,31 +507,23 @@ uint32_t calc_sram_crc( uint32_t base_addr, uint32_t size )
set_mcu_addr(base_addr); set_mcu_addr(base_addr);
FPGA_SELECT(); FPGA_SELECT();
FPGA_TX_BYTE(0x88); FPGA_TX_BYTE(0x88);
for(count=0; count<size; count++) {
for ( count = 0; count < size; count++ )
{
FPGA_WAIT_RDY(); FPGA_WAIT_RDY();
data = FPGA_RX_BYTE(); data = FPGA_RX_BYTE();
if(get_snes_reset()) {
if ( get_snes_reset() )
{
crc_valid = 0; crc_valid = 0;
break; break;
} }
crc += crc32_update(crc, data); crc += crc32_update(crc, data);
} }
FPGA_DESELECT(); FPGA_DESELECT();
return crc; return crc;
} }
uint8_t sram_reliable() uint8_t sram_reliable() {
{
uint16_t score=0; uint16_t score=0;
uint32_t val; uint32_t val;
uint8_t result = 0; uint8_t result = 0;
/*while(score<SRAM_RELIABILITY_SCORE) { /*while(score<SRAM_RELIABILITY_SCORE) {
if(sram_readlong(SRAM_SCRATCHPAD)==val) { if(sram_readlong(SRAM_SCRATCHPAD)==val) {
score++; score++;
@ -718,90 +532,67 @@ uint8_t sram_reliable()
score=0; score=0;
} }
} */ } */
for ( uint16_t i = 0; i < SRAM_RELIABILITY_SCORE; i++ ) for(uint16_t i = 0; i < SRAM_RELIABILITY_SCORE; i++) {
{
val=sram_readlong(SRAM_SCRATCHPAD); val=sram_readlong(SRAM_SCRATCHPAD);
if(val==0x12345678) {
if ( val == 0x12345678 )
{
score++; score++;
} //else { } else {
printf("i=%d val=%08lX\n", i, val);
//printf("i=%d val=%08lX\n", i, val);
//}
} }
}
if ( score < SRAM_RELIABILITY_SCORE ) if(score<SRAM_RELIABILITY_SCORE) {
{
result = 0; result = 0;
/* dprintf("score=%d\n", score); */ /* dprintf("score=%d\n", score); */
} } else {
else
{
result = 1; result = 1;
} }
rdyled(result); rdyled(result);
return result; return result;
} }
void sram_memset( uint32_t base_addr, uint32_t len, uint8_t val ) void sram_memset(uint32_t base_addr, uint32_t len, uint8_t val) {
{
set_mcu_addr(base_addr); set_mcu_addr(base_addr);
FPGA_SELECT(); FPGA_SELECT();
FPGA_TX_BYTE(0x98); FPGA_TX_BYTE(0x98);
for(uint32_t i=0; i<len; i++) {
for ( uint32_t i = 0; i < len; i++ )
{
FPGA_TX_BYTE(val); FPGA_TX_BYTE(val);
FPGA_WAIT_RDY(); FPGA_WAIT_RDY();
} }
FPGA_DESELECT(); FPGA_DESELECT();
} }
uint64_t sram_gettime( uint32_t base_addr ) uint64_t sram_gettime(uint32_t base_addr) {
{
set_mcu_addr(base_addr); set_mcu_addr(base_addr);
FPGA_SELECT(); FPGA_SELECT();
FPGA_TX_BYTE(0x88); FPGA_TX_BYTE(0x88);
uint8_t data; uint8_t data;
uint64_t result = 0LL; uint64_t result = 0LL;
/* 1st nibble is the century - 10 (binary) /* 1st nibble is the century - 10 (binary)
4th nibble is the month (binary) 4th nibble is the month (binary)
all other fields are BCD */ all other fields are BCD */
for ( int i = 0; i < 12; i++ ) for(int i=0; i<12; i++) {
{
FPGA_WAIT_RDY(); FPGA_WAIT_RDY();
data = FPGA_RX_BYTE(); data = FPGA_RX_BYTE();
data &= 0xf; data &= 0xf;
switch(i) {
switch ( i )
{
case 0: case 0:
result = (result << 4) | ((data / 10) + 1); result = (result << 4) | ((data / 10) + 1);
result = (result << 4) | (data % 10); result = (result << 4) | (data % 10);
break; break;
case 3: case 3:
result = (result << 4) | ((data / 10)); result = (result << 4) | ((data / 10));
result = (result << 4) | (data % 10); result = (result << 4) | (data % 10);
break; break;
default: default:
result = (result << 4) | data; result = (result << 4) | data;
} }
} }
FPGA_DESELECT(); FPGA_DESELECT();
return result & 0x00ffffffffffffffLL; return result & 0x00ffffffffffffffLL;
} }
void load_dspx( const uint8_t *filename, uint8_t coretype ) void load_dspx(const uint8_t *filename, uint8_t coretype) {
{
UINT bytes_read; UINT bytes_read;
//DWORD filesize;
uint16_t word_cnt; uint16_t word_cnt;
uint8_t wordsize_cnt = 0; uint8_t wordsize_cnt = 0;
uint16_t sector_remaining = 0; uint16_t sector_remaining = 0;
@ -811,53 +602,38 @@ void load_dspx( const uint8_t *filename, uint8_t coretype )
uint32_t pgmdata = 0; uint32_t pgmdata = 0;
uint16_t datdata = 0; uint16_t datdata = 0;
if ( coretype & FEAT_ST0010 ) if(coretype & FEAT_ST0010) {
{
datsize = 1536; datsize = 1536;
pgmsize = 2048; pgmsize = 2048;
} } else if (coretype & FEAT_DSPX) {
else if ( coretype & FEAT_DSPX )
{
datsize = 1024; datsize = 1024;
pgmsize = 2048; pgmsize = 2048;
} } else if (coretype & FEAT_CX4) {
else if ( coretype & FEAT_CX4 )
{
datsize = 0; datsize = 0;
pgmsize = 1024; /* Cx4 data ROM */ pgmsize = 1024; /* Cx4 data ROM */
} } else {
else
{
printf("load_dspx: unknown core (%02x)!\n", coretype); printf("load_dspx: unknown core (%02x)!\n", coretype);
} }
file_open((uint8_t*)filename, FA_READ); file_open((uint8_t*)filename, FA_READ);
if(file_res) {
/*filesize = file_handle.fsize;*/
if ( file_res )
{
printf("Could not read %s: error %d\n", filename, file_res); printf("Could not read %s: error %d\n", filename, file_res);
return; return;
} }
fpga_reset_dspx_addr(); fpga_reset_dspx_addr();
for ( word_cnt = 0; word_cnt < pgmsize; ) for(word_cnt = 0; word_cnt < pgmsize;) {
{ if(!sector_remaining) {
if ( !sector_remaining )
{
bytes_read = file_read(); bytes_read = file_read();
sector_remaining = bytes_read; sector_remaining = bytes_read;
sector_cnt = 0; sector_cnt = 0;
} }
pgmdata = (pgmdata << 8) | file_buf[sector_cnt]; pgmdata = (pgmdata << 8) | file_buf[sector_cnt];
sector_cnt++; sector_cnt++;
wordsize_cnt++; wordsize_cnt++;
sector_remaining--; sector_remaining--;
if(wordsize_cnt == 3){
if ( wordsize_cnt == 3 )
{
wordsize_cnt = 0; wordsize_cnt = 0;
word_cnt++; word_cnt++;
fpga_write_dspx_pgm(pgmdata); fpga_write_dspx_pgm(pgmdata);
@ -865,29 +641,22 @@ void load_dspx( const uint8_t *filename, uint8_t coretype )
} }
wordsize_cnt = 0; wordsize_cnt = 0;
if(coretype & FEAT_ST0010) {
if ( coretype & FEAT_ST0010 )
{
file_seek(0xc000); file_seek(0xc000);
sector_remaining = 0; sector_remaining = 0;
} }
for ( word_cnt = 0; word_cnt < datsize; ) for(word_cnt = 0; word_cnt < datsize;) {
{ if(!sector_remaining) {
if ( !sector_remaining )
{
bytes_read = file_read(); bytes_read = file_read();
sector_remaining = bytes_read; sector_remaining = bytes_read;
sector_cnt = 0; sector_cnt = 0;
} }
datdata = (datdata << 8) | file_buf[sector_cnt]; datdata = (datdata << 8) | file_buf[sector_cnt];
sector_cnt++; sector_cnt++;
wordsize_cnt++; wordsize_cnt++;
sector_remaining--; sector_remaining--;
if(wordsize_cnt == 2){
if ( wordsize_cnt == 2 )
{
wordsize_cnt = 0; wordsize_cnt = 0;
word_cnt++; word_cnt++;
fpga_write_dspx_dat(datdata); fpga_write_dspx_dat(datdata);

View File

@ -30,49 +30,25 @@
#include <arm/NXP/LPC17xx/LPC17xx.h> #include <arm/NXP/LPC17xx/LPC17xx.h>
#include "smc.h" #include "smc.h"
#define MASK_BITS (0x000000) #define SRAM_ROM_ADDR (0x000000L)
#if 0 #define SRAM_SAVE_ADDR (0xE00000L)
#define SRAM_ROM_ADDR ((0x000000L) & ~MASK_BITS)
#define SRAM_SAVE_ADDR ((0x400000L) & ~MASK_BITS)
#define SRAM_MENU_ADDR ((0x7A0000L) & ~MASK_BITS) #define SRAM_MENU_ADDR (0xC00000L)
#define SRAM_DIR_ADDR ((0x410000L) & ~MASK_BITS) #define SRAM_DIR_ADDR (0xC10000L)
#define SRAM_DB_ADDR ((0x420000L) & ~MASK_BITS) #define SRAM_DB_ADDR (0xC80000L)
#define SRAM_SPC_DATA_ADDR ((0x430000L) & ~MASK_BITS) #define SRAM_SPC_DATA_ADDR (0xFD0000L)
#define SRAM_SPC_HEADER_ADDR ((0x440000L) & ~MASK_BITS) #define SRAM_SPC_HEADER_ADDR (0xFE0000L)
#define SRAM_MENU_SAVE_ADDR ((0x7F0000L) & ~MASK_BITS) #define SRAM_MENU_SAVE_ADDR (0xFF0000L)
#define SRAM_CMD_ADDR ((0x7F1000L) & ~MASK_BITS) #define SRAM_CMD_ADDR (0xFF1000L)
#define SRAM_PARAM_ADDR ((0x7F1004L) & ~MASK_BITS) #define SRAM_PARAM_ADDR (0xFF1004L)
#define SRAM_STATUS_ADDR ((0x7F1100L) & ~MASK_BITS) #define SRAM_STATUS_ADDR (0xFF1100L)
#define SRAM_SYSINFO_ADDR ((0x7F1200L) & ~MASK_BITS) #define SRAM_SYSINFO_ADDR (0xFF1200L)
#define SRAM_LASTGAME_ADDR ((0x7F1420L) & ~MASK_BITS) #define SRAM_LASTGAME_ADDR (0xFF1420L)
#define SRAM_SCRATCHPAD ((0x7FFF00L) & ~MASK_BITS) #define SRAM_SCRATCHPAD (0xFFFF00L)
#define SRAM_DIRID ((0x7FFFF0L) & ~MASK_BITS) #define SRAM_DIRID (0xFFFFF0L)
#define SRAM_RELIABILITY_SCORE (0x100) #define SRAM_RELIABILITY_SCORE (0x100)
#else
#define SRAM_ROM_ADDR ((0x000000L) & ~MASK_BITS)
#define SRAM_SAVE_ADDR ((0x600000L) & ~MASK_BITS)
#define SRAM_MENU_ADDR ((0x500000L) & ~MASK_BITS)
#define SRAM_DIR_ADDR ((0x510000L) & ~MASK_BITS)
#define SRAM_DB_ADDR ((0x580000L) & ~MASK_BITS)
#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_SRAM (1)
#define LOADROM_WITH_RESET (2) #define LOADROM_WITH_RESET (2)
@ -92,6 +68,7 @@ void sram_writebyte( uint8_t val, uint32_t addr );
void sram_writeshort(uint16_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_writelong(uint32_t val, uint32_t addr);
void sram_readblock(void* buf, uint32_t addr, uint16_t size); 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_readlongblock(uint32_t* buf, uint32_t addr, uint16_t count);
void sram_writeblock(void* buf, uint32_t addr, uint16_t size); 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); void save_sram(uint8_t* filename, uint32_t sram_size, uint32_t base_addr);
@ -99,5 +76,5 @@ uint32_t calc_sram_crc( uint32_t base_addr, uint32_t size );
uint8_t sram_reliable(void); uint8_t sram_reliable(void);
void sram_memset(uint32_t base_addr, uint32_t len, uint8_t val); void sram_memset(uint32_t base_addr, uint32_t len, uint8_t val);
uint64_t sram_gettime(uint32_t base_addr); uint64_t sram_gettime(uint32_t base_addr);
void sram_readstrn( void *buf, uint32_t addr, uint16_t size );
#endif #endif

View File

@ -29,8 +29,7 @@ uint16_t fpga_status_now;
enum msu_reset_state { MSU_RESET_NONE = 0, MSU_RESET_SHORT, MSU_RESET_LONG }; enum msu_reset_state { MSU_RESET_NONE = 0, MSU_RESET_SHORT, MSU_RESET_LONG };
void prepare_audio_track( uint16_t msu_track ) void prepare_audio_track(uint16_t msu_track) {
{
/* open file, fill buffer */ /* open file, fill buffer */
char suffix[11]; char suffix[11];
f_close(&file_handle); f_close(&file_handle);
@ -38,9 +37,7 @@ void prepare_audio_track( uint16_t msu_track )
strcpy((char*)file_buf, (char*)file_lfn); strcpy((char*)file_buf, (char*)file_lfn);
strcpy(strrchr((char*)file_buf, (int)'.'), suffix); strcpy(strrchr((char*)file_buf, (int)'.'), suffix);
DBG_MSU1 printf("filename: %s\n", file_buf); DBG_MSU1 printf("filename: %s\n", file_buf);
if(f_open(&file_handle, (const TCHAR*)file_buf, FA_READ) == FR_OK) {
if ( f_open( &file_handle, ( const TCHAR * )file_buf, FA_READ ) == FR_OK )
{
file_handle.cltbl = pcm_cltbl; file_handle.cltbl = pcm_cltbl;
pcm_cltbl[0] = CLTBL_SIZE; pcm_cltbl[0] = CLTBL_SIZE;
f_lseek(&file_handle, CREATE_LINKMAP); f_lseek(&file_handle, CREATE_LINKMAP);
@ -58,24 +55,18 @@ void prepare_audio_track( uint16_t msu_track )
f_read(&file_handle, file_buf, MSU_DAC_BUFSIZE, &msu_audio_bytes_read); f_read(&file_handle, file_buf, MSU_DAC_BUFSIZE, &msu_audio_bytes_read);
/* clear busy bit */ /* clear busy bit */
set_msu_status(0x00, 0x28); /* set no bits, reset audio_busy + audio_error */ set_msu_status(0x00, 0x28); /* set no bits, reset audio_busy + audio_error */
} } else {
else
{
f_close(&file_handle); f_close(&file_handle);
set_msu_status(0x08, 0x20); /* reset audio_busy, set audio_error */ set_msu_status(0x08, 0x20); /* reset audio_busy, set audio_error */
} }
} }
void prepare_data( uint32_t msu_offset ) 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);
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) if( ((msu_offset < msu_page1_start)
|| (msu_offset >= msu_page1_start + msu_page_size)) || (msu_offset >= msu_page1_start + msu_page_size))
&& ((msu_offset < msu_page2_start) && ((msu_offset < msu_page2_start)
|| ( msu_offset >= msu_page2_start + msu_page_size ) ) ) || (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, 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); msu_page1_start+msu_page_size-1, msu_page2_start, msu_page2_start+msu_page_size-1);
/* "cache miss" */ /* "cache miss" */
@ -93,16 +84,11 @@ void prepare_data( uint32_t msu_offset )
msu_reset(0x0); msu_reset(0x0);
msu_page1_start = msu_offset; msu_page1_start = msu_offset;
msu_page2_start = msu_offset + msu_page_size; msu_page2_start = msu_offset + msu_page_size;
} } else {
else if (msu_offset >= msu_page1_start && msu_offset <= msu_page1_start + msu_page_size) {
{
if ( msu_offset >= msu_page1_start && msu_offset <= msu_page1_start + msu_page_size )
{
msu_reset(0x0000 + msu_offset - msu_page1_start); msu_reset(0x0000 + msu_offset - msu_page1_start);
DBG_MSU1 printf("inside page1, new offset: %08lx\n", 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)) {
if ( !( msu_page2_start == msu_page1_start + msu_page_size ) )
{
set_msu_addr(0x2000); set_msu_addr(0x2000);
sd_offload_tgt=2; sd_offload_tgt=2;
ff_sd_offload=1; ff_sd_offload=1;
@ -111,14 +97,10 @@ void prepare_data( uint32_t msu_offset )
msu_page2_start = msu_page1_start + msu_page_size; msu_page2_start = msu_page1_start + msu_page_size;
DBG_MSU1 printf("%08lx)\n", msu_page2_start); DBG_MSU1 printf("%08lx)\n", msu_page2_start);
} }
} } else if (msu_offset >= msu_page2_start && msu_offset <= msu_page2_start + msu_page_size) {
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); DBG_MSU1 printf("inside page2, new offset: %08lx\n", 0x2000 + msu_offset-msu_page2_start);
msu_reset(0x2000 + msu_offset - msu_page2_start); msu_reset(0x2000 + msu_offset - msu_page2_start);
if(!(msu_page1_start == msu_page2_start + msu_page_size)) {
if ( !( msu_page1_start == msu_page2_start + msu_page_size ) )
{
set_msu_addr(0x0); set_msu_addr(0x0);
sd_offload_tgt=2; sd_offload_tgt=2;
ff_sd_offload=1; ff_sd_offload=1;
@ -127,13 +109,8 @@ void prepare_data( uint32_t msu_offset )
msu_page1_start = msu_page2_start + msu_page_size; msu_page1_start = msu_page2_start + msu_page_size;
DBG_MSU1 printf("%08lx)\n", msu_page1_start); DBG_MSU1 printf("%08lx)\n", msu_page1_start);
} }
} else printf("!!!WATWATWAT!!!\n");
} }
else
{
printf( "!!!WATWATWAT!!!\n" );
}
}
/* clear bank bit to mask bank reset artifact */ /* clear bank bit to mask bank reset artifact */
fpga_status_now &= ~0x2000; fpga_status_now &= ~0x2000;
fpga_status_prev &= ~0x2000; fpga_status_prev &= ~0x2000;
@ -141,71 +118,50 @@ void prepare_data( uint32_t msu_offset )
set_msu_status(0x00, 0x10); set_msu_status(0x00, 0x10);
} }
int msu1_check_reset( void ) int msu1_check_reset(void) {
{
static tick_t rising_ticks; static tick_t rising_ticks;
static uint8_t resbutton=0, resbutton_prev=0; static uint8_t resbutton=0, resbutton_prev=0;
int result = MSU_RESET_NONE; int result = MSU_RESET_NONE;
resbutton = get_snes_reset(); resbutton = get_snes_reset();
if(resbutton && !resbutton_prev) { /* push */
if ( resbutton && !resbutton_prev ) /* push */
{
rising_ticks = getticks(); rising_ticks = getticks();
} } else if(resbutton && resbutton_prev) { /* hold */
else if ( resbutton && resbutton_prev ) /* hold */ if(getticks() > rising_ticks + 99) {
{
if ( getticks() > rising_ticks + 99 )
{
result = MSU_RESET_LONG; result = MSU_RESET_LONG;
} }
} } else if(!resbutton && resbutton_prev) { /* release */
else if ( !resbutton && resbutton_prev ) /* release */ if(getticks() < rising_ticks + 99) {
{
if ( getticks() < rising_ticks + 99 )
{
result = MSU_RESET_SHORT; result = MSU_RESET_SHORT;
} }
} } else {
else
{
result = MSU_RESET_NONE; result = MSU_RESET_NONE;
} }
resbutton_prev = resbutton; resbutton_prev = resbutton;
return result; return result;
} }
int msu1_check( uint8_t *filename ) int msu1_check(uint8_t* filename) {
{
/* open MSU file */ /* open MSU file */
strcpy((char*)file_buf, (char*)filename); strcpy((char*)file_buf, (char*)filename);
strcpy(strrchr((char*)file_buf, (int)'.'), ".msu"); strcpy(strrchr((char*)file_buf, (int)'.'), ".msu");
printf("MSU datafile: %s\n", file_buf); printf("MSU datafile: %s\n", file_buf);
if(f_open(&msufile, (const TCHAR*)file_buf, FA_READ) != FR_OK) {
if ( f_open( &msufile, ( const TCHAR * )file_buf, FA_READ ) != FR_OK )
{
printf("MSU datafile not found\n"); printf("MSU datafile not found\n");
return 0; return 0;
} }
msufile.cltbl = msu_cltbl; msufile.cltbl = msu_cltbl;
msu_cltbl[0] = CLTBL_SIZE; msu_cltbl[0] = CLTBL_SIZE;
if(f_lseek(&msufile, CREATE_LINKMAP)) {
if ( f_lseek( &msufile, CREATE_LINKMAP ) )
{
printf("Error creating FF linkmap for MSU file!\n"); printf("Error creating FF linkmap for MSU file!\n");
} }
romprops.fpga_features |= FEAT_MSU1; romprops.fpga_features |= FEAT_MSU1;
return 1; return 1;
} }
int msu1_loop() int msu1_loop() {
{
/* it is assumed that the MSU file is already opened by calling msu1_check(). */ /* it is assumed that the MSU file is already opened by calling msu1_check(). */
while(fpga_status() & 0x4000); while(fpga_status() & 0x4000);
uint16_t dac_addr = 0; uint16_t dac_addr = 0;
uint16_t msu_addr = 0; uint16_t msu_addr = 0;
uint8_t msu_repeat = 0; uint8_t msu_repeat = 0;
@ -239,29 +195,21 @@ int msu1_loop()
prepare_audio_track(0); prepare_audio_track(0);
prepare_data(0); prepare_data(0);
/* audio_start, data_start, 0, audio_ctrl[1:0], ctrl_start */ /* audio_start, data_start, 0, audio_ctrl[1:0], ctrl_start */
while ( ( msu_res = msu1_check_reset() ) == MSU_RESET_NONE ) while((msu_res = msu1_check_reset()) == MSU_RESET_NONE){
{
cli_entrycheck(); cli_entrycheck();
fpga_status_now = fpga_status(); fpga_status_now = fpga_status();
/* Data buffer refill */ /* Data buffer refill */
if ( ( fpga_status_now & 0x2000 ) != ( fpga_status_prev & 0x2000 ) ) if((fpga_status_now & 0x2000) != (fpga_status_prev & 0x2000)) {
{
DBG_MSU1 printf("data\n"); DBG_MSU1 printf("data\n");
if(fpga_status_now & 0x2000) {
if ( fpga_status_now & 0x2000 )
{
msu_addr = 0x0; msu_addr = 0x0;
msu_page1_start = msu_page2_start + msu_page_size; msu_page1_start = msu_page2_start + msu_page_size;
} } else {
else
{
msu_addr = 0x2000; msu_addr = 0x2000;
msu_page2_start = msu_page1_start + msu_page_size; msu_page2_start = msu_page1_start + msu_page_size;
} }
set_msu_addr(msu_addr); set_msu_addr(msu_addr);
sd_offload_tgt=2; sd_offload_tgt=2;
ff_sd_offload=1; ff_sd_offload=1;
@ -270,25 +218,19 @@ int msu1_loop()
} }
/* Audio buffer refill */ /* Audio buffer refill */
if ( ( fpga_status_now & 0x4000 ) != ( fpga_status_prev & 0x4000 ) ) if((fpga_status_now & 0x4000) != (fpga_status_prev & 0x4000)) {
{ if(fpga_status_now & 0x4000) {
if ( fpga_status_now & 0x4000 )
{
dac_addr = 0; dac_addr = 0;
} } else {
else
{
dac_addr = MSU_DAC_BUFSIZE/2; dac_addr = MSU_DAC_BUFSIZE/2;
} }
set_dac_addr(dac_addr); set_dac_addr(dac_addr);
sd_offload_tgt=1; sd_offload_tgt=1;
ff_sd_offload=1; ff_sd_offload=1;
f_read(&file_handle, file_buf, MSU_DAC_BUFSIZE/2, &msu_audio_bytes_read); f_read(&file_handle, file_buf, MSU_DAC_BUFSIZE/2, &msu_audio_bytes_read);
} }
if ( fpga_status_now & 0x0020 ) if(fpga_status_now & 0x0020) {
{
/* get trackno */ /* get trackno */
msu_track = get_msu_track(); msu_track = get_msu_track();
DBG_MSU1 printf("Audio requested! Track=%d\n", msu_track); DBG_MSU1 printf("Audio requested! Track=%d\n", msu_track);
@ -296,36 +238,28 @@ int msu1_loop()
prepare_audio_track(msu_track); prepare_audio_track(msu_track);
} }
if ( fpga_status_now & 0x0010 ) if(fpga_status_now & 0x0010) {
{
/* get address */ /* get address */
msu_offset=get_msu_offset(); msu_offset=get_msu_offset();
prepare_data(msu_offset); prepare_data(msu_offset);
} }
if ( fpga_status_now & 0x0001 ) if(fpga_status_now & 0x0001) {
{ if(fpga_status_now & 0x0004) {
if ( fpga_status_now & 0x0004 )
{
msu_repeat = 1; msu_repeat = 1;
set_msu_status(0x04, 0x01); /* set bit 2, reset bit 0 */ set_msu_status(0x04, 0x01); /* set bit 2, reset bit 0 */
DBG_MSU1 printf("Repeat set!\n"); DBG_MSU1 printf("Repeat set!\n");
} } else {
else
{
msu_repeat = 0; msu_repeat = 0;
set_msu_status(0x00, 0x05); /* set no bits, reset bit 0+2 */ set_msu_status(0x00, 0x05); /* set no bits, reset bit 0+2 */
DBG_MSU1 printf("Repeat clear!\n"); DBG_MSU1 printf("Repeat clear!\n");
} }
if ( fpga_status_now & 0x0002 ) if(fpga_status_now & 0x0002) {
{
DBG_MSU1 printf("PLAY!\n"); DBG_MSU1 printf("PLAY!\n");
set_msu_status(0x02, 0x01); /* set bit 0, reset bit 1 */ set_msu_status(0x02, 0x01); /* set bit 0, reset bit 1 */
dac_play(); dac_play();
} } else {
else
{
DBG_MSU1 printf("PAUSE!\n"); DBG_MSU1 printf("PAUSE!\n");
set_msu_status(0x00, 0x03); /* set no bits, reset bit 1+0 */ set_msu_status(0x00, 0x03); /* set no bits, reset bit 1+0 */
dac_pause(); dac_pause();
@ -335,13 +269,10 @@ int msu1_loop()
fpga_status_prev = fpga_status_now; fpga_status_prev = fpga_status_now;
/* handle loop / end */ /* handle loop / end */
if ( msu_audio_bytes_read < MSU_DAC_BUFSIZE / 2 ) if(msu_audio_bytes_read < MSU_DAC_BUFSIZE / 2) {
{
ff_sd_offload=0; ff_sd_offload=0;
sd_offload=0; sd_offload=0;
if(msu_repeat) {
if ( msu_repeat )
{
DBG_MSU1 printf("loop\n"); DBG_MSU1 printf("loop\n");
ff_sd_offload=1; ff_sd_offload=1;
sd_offload_tgt=1; sd_offload_tgt=1;
@ -349,27 +280,20 @@ int msu1_loop()
ff_sd_offload=1; ff_sd_offload=1;
sd_offload_tgt=1; sd_offload_tgt=1;
f_read(&file_handle, file_buf, (MSU_DAC_BUFSIZE / 2) - msu_audio_bytes_read, &msu_audio_bytes_read); f_read(&file_handle, file_buf, (MSU_DAC_BUFSIZE / 2) - msu_audio_bytes_read, &msu_audio_bytes_read);
} } else {
else
{
set_msu_status(0x00, 0x02); /* clear play bit */ set_msu_status(0x00, 0x02); /* clear play bit */
dac_pause(); dac_pause();
} }
msu_audio_bytes_read = MSU_DAC_BUFSIZE; msu_audio_bytes_read = MSU_DAC_BUFSIZE;
} }
} }
f_close(&file_handle); f_close(&file_handle);
DBG_MSU1 printf("Reset "); DBG_MSU1 printf("Reset ");
if(msu_res == MSU_RESET_LONG) {
if ( msu_res == MSU_RESET_LONG )
{
f_close(&msufile); f_close(&msufile);
DBG_MSU1 printf("to menu\n"); DBG_MSU1 printf("to menu\n");
return 1; return 1;
} }
DBG_MSU1 printf("game\n"); DBG_MSU1 printf("game\n");
return 0; return 0;
} }

View File

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

View File

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

View File

@ -61,10 +61,8 @@ static char *outptr;
static int maxlen; static int maxlen;
/* printf */ /* printf */
static void outchar( char x ) static void outchar(char x) {
{ if (maxlen) {
if ( maxlen )
{
maxlen--; maxlen--;
outfunc(x); outfunc(x);
outlength++; outlength++;
@ -72,18 +70,15 @@ static void outchar( char x )
} }
/* sprintf */ /* sprintf */
static void outstr( char x ) static void outstr(char x) {
{ if (maxlen) {
if ( maxlen )
{
maxlen--; maxlen--;
*outptr++ = x; *outptr++ = x;
outlength++; outlength++;
} }
} }
static int internal_nprintf( void ( *output_function )( char c ), const char *fmt, va_list ap ) static int internal_nprintf(void (*output_function)(char c), const char *fmt, va_list ap) {
{
unsigned int width; unsigned int width;
unsigned int flags; unsigned int flags;
unsigned int base = 0; unsigned int base = 0;
@ -91,24 +86,16 @@ static int internal_nprintf( void ( *output_function )( char c ), const char *fm
outlength = 0; outlength = 0;
while ( *fmt ) while (*fmt) {
{ while (1) {
while ( 1 )
{
if (*fmt == 0) if (*fmt == 0)
{
goto end; goto end;
}
if ( *fmt == '%' ) if (*fmt == '%') {
{
fmt++; fmt++;
if (*fmt != '%') if (*fmt != '%')
{
break; break;
} }
}
output_function(*fmt++); output_function(*fmt++);
} }
@ -117,12 +104,9 @@ static int internal_nprintf( void ( *output_function )( char c ), const char *fm
width = 0; width = 0;
/* read all flags */ /* read all flags */
do do {
{ if (flags < FLAG_WIDTH) {
if ( flags < FLAG_WIDTH ) switch (*fmt) {
{
switch ( *fmt )
{
case '0': case '0':
flags |= FLAG_ZEROPAD; flags |= FLAG_ZEROPAD;
continue; continue;
@ -141,10 +125,8 @@ static int internal_nprintf( void ( *output_function )( char c ), const char *fm
} }
} }
if ( flags < FLAG_LONG ) if (flags < FLAG_LONG) {
{ if (*fmt >= '0' && *fmt <= '9') {
if ( *fmt >= '0' && *fmt <= '9' )
{
unsigned char tmp = *fmt - '0'; unsigned char tmp = *fmt - '0';
width = 10*width + tmp; width = 10*width + tmp;
flags |= FLAG_WIDTH; flags |= FLAG_WIDTH;
@ -152,26 +134,20 @@ static int internal_nprintf( void ( *output_function )( char c ), const char *fm
} }
if (*fmt == 'h') if (*fmt == 'h')
{
continue; continue;
}
if ( *fmt == 'l' ) if (*fmt == 'l') {
{
flags |= FLAG_LONG; flags |= FLAG_LONG;
continue; continue;
} }
} }
break; break;
} } while (*fmt++);
while ( *fmt++ );
/* Strings */ /* Strings */
if ( *fmt == 'c' || *fmt == 's' ) if (*fmt == 'c' || *fmt == 's') {
{ switch (*fmt) {
switch ( *fmt )
{
case 'c': case 'c':
buffer[0] = va_arg(ap, int); buffer[0] = va_arg(ap, int);
ptr = buffer; ptr = buffer;
@ -186,11 +162,9 @@ static int internal_nprintf( void ( *output_function )( char c ), const char *fm
} }
/* Numbers */ /* Numbers */
switch ( *fmt ) switch (*fmt) {
{
case 'u': case 'u':
flags |= FLAG_UNSIGNED; flags |= FLAG_UNSIGNED;
case 'd': case 'd':
base = 10; base = 10;
break; break;
@ -204,7 +178,6 @@ static int internal_nprintf( void ( *output_function )( char c ), const char *fm
output_function('0'); output_function('0');
output_function('x'); output_function('x');
width -= 2; width -= 2;
case 'x': case 'x':
case 'X': case 'X':
base = 16; base = 16;
@ -214,89 +187,59 @@ static int internal_nprintf( void ( *output_function )( char c ), const char *fm
unsigned int num; unsigned int num;
if ( !( flags & FLAG_UNSIGNED ) ) if (!(flags & FLAG_UNSIGNED)) {
{
int tmp = va_arg(ap, int); int tmp = va_arg(ap, int);
if (tmp < 0) {
if ( tmp < 0 )
{
num = -tmp; num = -tmp;
flags |= FLAG_NEGATIVE; flags |= FLAG_NEGATIVE;
} } else
else
{
num = tmp; num = tmp;
} } else {
}
else
{
num = va_arg(ap, unsigned int); num = va_arg(ap, unsigned int);
} }
/* Convert number into buffer */ /* Convert number into buffer */
ptr = buffer + sizeof(buffer); ptr = buffer + sizeof(buffer);
*--ptr = 0; *--ptr = 0;
do {
do
{
*--ptr = hexdigits[num % base]; *--ptr = hexdigits[num % base];
num /= base; num /= base;
} } while (num != 0);
while ( num != 0 );
/* Sign */ /* Sign */
if ( flags & FLAG_NEGATIVE ) if (flags & FLAG_NEGATIVE) {
{
output_function('-'); output_function('-');
width--; width--;
} } else if (flags & FLAG_FORCESIGN) {
else if ( flags & FLAG_FORCESIGN )
{
output_function('+'); output_function('+');
width--; width--;
} } else if (flags & FLAG_BLANK) {
else if ( flags & FLAG_BLANK )
{
output_function(' '); output_function(' ');
width--; width--;
} }
output: output:
/* left padding */ /* left padding */
if ( ( flags & FLAG_WIDTH ) && !( flags & FLAG_LEFTADJ ) ) if ((flags & FLAG_WIDTH) && !(flags & FLAG_LEFTADJ)) {
{ while (strlen(ptr) < width) {
while ( strlen( ptr ) < width )
{
if (flags & FLAG_ZEROPAD) if (flags & FLAG_ZEROPAD)
{
output_function('0'); output_function('0');
}
else else
{
output_function(' '); output_function(' ');
}
width--; width--;
} }
} }
/* data */ /* data */
while ( *ptr ) while (*ptr) {
{
output_function(*ptr++); output_function(*ptr++);
if (width) if (width)
{
width--; width--;
} }
}
/* right padding */ /* right padding */
if ( flags & FLAG_WIDTH ) if (flags & FLAG_WIDTH) {
{ while (width) {
while ( width )
{
output_function(' '); output_function(' ');
width--; width--;
} }
@ -309,8 +252,7 @@ end:
return outlength; return outlength;
} }
int printf( const char *format, ... ) int printf(const char *format, ...) {
{
va_list ap; va_list ap;
int res; int res;
@ -321,8 +263,7 @@ int printf( const char *format, ... )
return res; return res;
} }
int snprintf( char *str, size_t size, const char *format, ... ) int snprintf(char *str, size_t size, const char *format, ...) {
{
va_list ap; va_list ap;
int res; int res;
@ -331,26 +272,20 @@ int snprintf( char *str, size_t size, const char *format, ... )
va_start(ap, format); va_start(ap, format);
res = internal_nprintf(outstr, format, ap); res = internal_nprintf(outstr, format, ap);
va_end(ap); va_end(ap);
if (res < size) if (res < size)
{
str[res] = 0; str[res] = 0;
}
return res; return res;
} }
/* Required for gcc compatibility */ /* Required for gcc compatibility */
int puts( const char *str ) int puts(const char *str) {
{
uart_puts(str); uart_puts(str);
uart_putc('\n'); uart_putc('\n');
return 0; return 0;
} }
#undef putchar #undef putchar
int putchar( int c ) int putchar(int c) {
{
uart_putc(c); uart_putc(c);
return 0; return 0;
} }

View File

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

View File

@ -11,32 +11,23 @@ rtcstate_t rtc_state;
#define CLKEN 0 #define CLKEN 0
#define CTCRST 1 #define CTCRST 1
uint8_t rtc_isvalid( void ) uint8_t rtc_isvalid(void) {
{ if(LPC_RTC->GPREG0 == RTC_MAGIC) {
if ( LPC_RTC->GPREG0 == RTC_MAGIC )
{
return RTC_OK; return RTC_OK;
} }
return RTC_INVALID; return RTC_INVALID;
} }
void rtc_init( void ) void rtc_init(void) {
{ if (LPC_RTC->CCR & BV(CLKEN)) {
if ( LPC_RTC->CCR & BV( CLKEN ) )
{
rtc_state = RTC_OK; rtc_state = RTC_OK;
} } else {
else
{
rtc_state = RTC_INVALID; rtc_state = RTC_INVALID;
} }
} }
void read_rtc( struct tm *time ) void read_rtc(struct tm *time) {
{ do {
do
{
time->tm_sec = LPC_RTC->SEC; time->tm_sec = LPC_RTC->SEC;
time->tm_min = LPC_RTC->MIN; time->tm_min = LPC_RTC->MIN;
time->tm_hour = LPC_RTC->HOUR; time->tm_hour = LPC_RTC->HOUR;
@ -44,33 +35,24 @@ void read_rtc( struct tm *time )
time->tm_mon = LPC_RTC->MONTH; time->tm_mon = LPC_RTC->MONTH;
time->tm_year = LPC_RTC->YEAR; time->tm_year = LPC_RTC->YEAR;
time->tm_wday = LPC_RTC->DOW; time->tm_wday = LPC_RTC->DOW;
} } while (time->tm_sec != LPC_RTC->SEC);
while ( time->tm_sec != LPC_RTC->SEC );
} }
uint8_t calc_weekday( struct tm *time ) uint8_t calc_weekday(struct tm *time) {
{
int month = time->tm_mon; int month = time->tm_mon;
int year = time->tm_year; int year = time->tm_year;
int day = time->tm_mday; int day = time->tm_mday;
/* Variation of Sillke for the Gregorian calendar. /* Variation of Sillke for the Gregorian calendar.
* http://www.mathematik.uni-bielefeld.de/~sillke/ALGORITHMS/calendar/weekday.c */ * http://www.mathematik.uni-bielefeld.de/~sillke/ALGORITHMS/calendar/weekday.c */
if ( month <= 2 ) if (month <= 2) {
{
month += 10; month += 10;
year--; year--;
} } else month -= 2;
else
{
month -= 2;
}
return (83*month/32 + day + year + year/4 - year/100 + year/400) % 7; return (83*month/32 + day + year + year/4 - year/100 + year/400) % 7;
} }
void set_rtc( struct tm *time ) void set_rtc(struct tm *time) {
{
LPC_RTC->CCR = BV(CTCRST); LPC_RTC->CCR = BV(CTCRST);
LPC_RTC->SEC = time->tm_sec; LPC_RTC->SEC = time->tm_sec;
LPC_RTC->MIN = time->tm_min; LPC_RTC->MIN = time->tm_min;
@ -83,13 +65,11 @@ void set_rtc( struct tm *time )
LPC_RTC->GPREG0 = RTC_MAGIC; LPC_RTC->GPREG0 = RTC_MAGIC;
} }
void invalidate_rtc() void invalidate_rtc() {
{
LPC_RTC->GPREG0 = 0; LPC_RTC->GPREG0 = 0;
} }
uint32_t get_fattime( void ) uint32_t get_fattime(void) {
{
struct tm time; struct tm time;
read_rtc(&time); read_rtc(&time);
@ -101,8 +81,7 @@ uint32_t get_fattime( void )
((uint32_t)time.tm_sec) >> 1; ((uint32_t)time.tm_sec) >> 1;
} }
uint64_t get_bcdtime( void ) uint64_t get_bcdtime(void) {
{
struct tm time; struct tm time;
read_rtc(&time); read_rtc(&time);
uint16_t year = time.tm_year; uint16_t year = time.tm_year;
@ -124,8 +103,7 @@ uint64_t get_bcdtime( void )
|(time.tm_sec % 10); |(time.tm_sec % 10);
} }
void set_bcdtime( uint64_t btime ) void set_bcdtime(uint64_t btime) {
{
struct tm time; struct tm time;
time.tm_sec = (btime & 0xf) + ((btime >> 4) & 0xf) * 10; time.tm_sec = (btime & 0xf) + ((btime >> 4) & 0xf) * 10;
time.tm_min = ((btime >> 8) & 0xf) + ((btime >> 12) & 0xf) * 10; time.tm_min = ((btime >> 8) & 0xf) + ((btime >> 12) & 0xf) * 10;
@ -138,14 +116,12 @@ void set_bcdtime( uint64_t btime )
set_rtc(&time); set_rtc(&time);
} }
void printtime( struct tm *time ) void printtime(struct tm *time) {
{
printf("%04d-%02d-%02d %02d:%02d:%02d\n", time->tm_year, time->tm_mon, 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); time->tm_mday, time->tm_hour, time->tm_min, time->tm_sec);
} }
void testbattery() void testbattery() {
{
printf("%lx\n", LPC_RTC->GPREG0); printf("%lx\n", LPC_RTC->GPREG0);
LPC_RTC->GPREG0 = RTC_MAGIC; LPC_RTC->GPREG0 = RTC_MAGIC;
printf("%lx\n", LPC_RTC->GPREG0); printf("%lx\n", LPC_RTC->GPREG0);

View File

@ -29,15 +29,13 @@
#include <stdint.h> #include <stdint.h>
typedef enum typedef enum {
{
RTC_NOT_FOUND, /* No RTC present */ RTC_NOT_FOUND, /* No RTC present */
RTC_INVALID, /* RTC present, but contents invalid */ RTC_INVALID, /* RTC present, but contents invalid */
RTC_OK /* RTC present and working */ RTC_OK /* RTC present and working */
} rtcstate_t; } rtcstate_t;
struct tm struct tm {
{
uint8_t tm_sec; // 0..59 uint8_t tm_sec; // 0..59
uint8_t tm_min; // 0..59 uint8_t tm_min; // 0..59
uint8_t tm_hour; // 0..23 uint8_t tm_hour; // 0..23

File diff suppressed because it is too large Load Diff

235
src/smc.c
View File

@ -35,66 +35,47 @@ snes_romprops_t romprops;
uint32_t hdr_addr[6] = {0xffb0, 0x101b0, 0x7fb0, 0x81b0, 0x40ffb0, 0x4101b0}; uint32_t hdr_addr[6] = {0xffb0, 0x101b0, 0x7fb0, 0x81b0, 0x40ffb0, 0x4101b0};
uint8_t isFixed( uint8_t *data, int size, uint8_t value ) uint8_t isFixed(uint8_t* data, int size, uint8_t value) {
{
uint8_t res = 1; uint8_t res = 1;
do {
do
{
size--; size--;
if(data[size] != value) {
if ( data[size] != value )
{
res = 0; res = 0;
} }
} } while (size);
while ( size );
return res; return res;
} }
uint8_t checkChksum( uint16_t cchk, uint16_t chk ) uint8_t checkChksum(uint16_t cchk, uint16_t chk) {
{
uint32_t sum = cchk + chk; uint32_t sum = cchk + chk;
uint8_t res = 0; uint8_t res = 0;
if(sum==0x0000ffff) {
if ( sum == 0x0000ffff )
{
res = 1; res = 1;
} }
return res; return res;
} }
void smc_id( snes_romprops_t *props ) void smc_id(snes_romprops_t* props) {
{
uint8_t score, maxscore=1, score_idx=2; /* assume LoROM */ uint8_t score, maxscore=1, score_idx=2; /* assume LoROM */
snes_header_t* header = &(props->header); snes_header_t* header = &(props->header);
props->load_address = 0;
props->has_dspx = 0; props->has_dspx = 0;
props->has_st0010 = 0; props->has_st0010 = 0;
props->has_cx4 = 0; props->has_cx4 = 0;
props->fpga_features = 0; props->fpga_features = 0;
props->fpga_conf = NULL; props->fpga_conf = NULL;
for(uint8_t num = 0; num < 6; num++) {
for ( uint8_t num = 0; num < 6; num++ )
{
score = smc_headerscore(hdr_addr[num], header); score = smc_headerscore(hdr_addr[num], header);
printf("%d: offset = %lX; score = %d\n", num, hdr_addr[num], score); // */ printf("%d: offset = %lX; score = %d\n", num, hdr_addr[num], score); // */
if(score>=maxscore) {
if ( score >= maxscore )
{
score_idx=num; score_idx=num;
maxscore=score; maxscore=score;
} }
} }
if(score_idx & 1) {
if ( score_idx & 1 )
{
props->offset = 0x200; props->offset = 0x200;
} } else {
else
{
props->offset = 0; props->offset = 0;
} }
@ -102,17 +83,12 @@ void smc_id( snes_romprops_t *props )
/*dprintf("winner is %d\n", score_idx); */ /*dprintf("winner is %d\n", score_idx); */
file_readblock(header, hdr_addr[score_idx], sizeof(snes_header_t)); file_readblock(header, hdr_addr[score_idx], sizeof(snes_header_t));
if ( header->name[0x13] == 0x00 || header->name[0x13] == 0xff ) if(header->name[0x13] == 0x00 || header->name[0x13] == 0xff) {
{ if(header->name[0x14] == 0x00) {
if ( header->name[0x14] == 0x00 )
{
const uint8_t n15 = header->map; const uint8_t n15 = header->map;
if(n15 == 0x00 || n15 == 0x80 || n15 == 0x84 || n15 == 0x9c if(n15 == 0x00 || n15 == 0x80 || n15 == 0x84 || n15 == 0x9c
|| n15 == 0xbc || n15 == 0xfc ) || n15 == 0xbc || n15 == 0xfc) {
{ if(header->licensee == 0x33 || header->licensee == 0xff) {
if ( header->licensee == 0x33 || header->licensee == 0xff )
{
props->mapper_id = 0; props->mapper_id = 0;
/*XXX do this properly */ /*XXX do this properly */
props->ramsize_bytes = 0x8000; props->ramsize_bytes = 0x8000;
@ -120,80 +96,67 @@ void smc_id( snes_romprops_t *props )
props->expramsize_bytes = 0; props->expramsize_bytes = 0;
props->mapper_id = 3; /* BS-X Memory Map */ props->mapper_id = 3; /* BS-X Memory Map */
props->region = 0; /* BS-X only existed in Japan */ 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; return;
} }
} }
} }
} }
switch(header->map & 0xef) {
switch ( header->map & 0xef )
{
case 0x21: /* HiROM */ case 0x21: /* HiROM */
props->mapper_id = 0; props->mapper_id = 0;
if(header->map == 0x31 && (header->carttype == 0x03 || header->carttype == 0x05)) {
if ( header->map == 0x31 && ( header->carttype == 0x03 || header->carttype == 0x05 ) )
{
props->has_dspx = 1; props->has_dspx = 1;
props->dsp_fw = DSPFW_1B; props->dsp_fw = DSPFW_1B;
props->fpga_features |= FEAT_DSPX; props->fpga_features |= FEAT_DSPX;
} }
break; break;
case 0x20: /* LoROM */ case 0x20: /* LoROM */
props->mapper_id = 1; props->mapper_id = 1;
if (header->map == 0x20 && header->carttype == 0xf3) {
if ( header->map == 0x20 && header->carttype == 0xf3 )
{
props->has_cx4 = 1; props->has_cx4 = 1;
props->dsp_fw = CX4FW; props->dsp_fw = CX4FW;
props->fpga_conf = FPGA_CX4; props->fpga_conf = FPGA_CX4;
props->fpga_features |= FEAT_CX4; props->fpga_features |= FEAT_CX4;
} }
else if ((header->map == 0x20 && header->carttype == 0x03) || else if ((header->map == 0x20 && header->carttype == 0x03) ||
( header->map == 0x30 && header->carttype == 0x05 && header->licensee != 0xb2 ) ) (header->map == 0x30 && header->carttype == 0x05 && header->licensee != 0xb2)) {
{
props->has_dspx = 1; props->has_dspx = 1;
props->fpga_features |= FEAT_DSPX; props->fpga_features |= FEAT_DSPX;
/* Pilotwings uses DSP1 instead of DSP1B */ /* Pilotwings uses DSP1 instead of DSP1B */
if ( !memcmp( header->name, "PILOTWINGS", 10 ) ) if(!memcmp(header->name, "PILOTWINGS", 10)) {
{
props->dsp_fw = DSPFW_1; props->dsp_fw = DSPFW_1;
} } else {
else
{
props->dsp_fw = DSPFW_1B; props->dsp_fw = DSPFW_1B;
} }
} } else if (header->map == 0x20 && header->carttype == 0x05) {
else if ( header->map == 0x20 && header->carttype == 0x05 )
{
props->has_dspx = 1; props->has_dspx = 1;
props->dsp_fw = DSPFW_2; props->dsp_fw = DSPFW_2;
props->fpga_features |= FEAT_DSPX; props->fpga_features |= FEAT_DSPX;
} } else if (header->map == 0x30 && header->carttype == 0x05 && header->licensee == 0xb2) {
else if ( header->map == 0x30 && header->carttype == 0x05 && header->licensee == 0xb2 )
{
props->has_dspx = 1; props->has_dspx = 1;
props->dsp_fw = DSPFW_3; props->dsp_fw = DSPFW_3;
props->fpga_features |= FEAT_DSPX; props->fpga_features |= FEAT_DSPX;
} } else if (header->map == 0x30 && header->carttype == 0x03) {
else if ( header->map == 0x30 && header->carttype == 0x03 )
{
props->has_dspx = 1; props->has_dspx = 1;
props->dsp_fw = DSPFW_4; props->dsp_fw = DSPFW_4;
props->fpga_features |= FEAT_DSPX; props->fpga_features |= FEAT_DSPX;
} } else if (header->map == 0x30 && header->carttype == 0xf6 && header->romsize >= 0xa) {
else if ( header->map == 0x30 && header->carttype == 0xf6 && header->romsize >= 0xa )
{
props->has_dspx = 1; props->has_dspx = 1;
props->has_st0010 = 1; props->has_st0010 = 1;
props->dsp_fw = DSPFW_ST0010; props->dsp_fw = DSPFW_ST0010;
props->fpga_features |= FEAT_ST0010; props->fpga_features |= FEAT_ST0010;
header->ramsize = 2; header->ramsize = 2;
} }
break; break;
case 0x25: /* ExHiROM */ case 0x25: /* ExHiROM */
@ -201,159 +164,91 @@ void smc_id( snes_romprops_t *props )
break; break;
case 0x22: /* ExLoROM */ case 0x22: /* ExLoROM */
if ( file_handle.fsize > 0x400200 ) if(file_handle.fsize > 0x400200) {
{
props->mapper_id = 6; /* SO96 */ props->mapper_id = 6; /* SO96 */
} } else {
else
{
props->mapper_id = 1; props->mapper_id = 1;
} }
break; break;
default: /* invalid/unsupported mapper, use header location */ default: /* invalid/unsupported mapper, use header location */
switch ( score_idx ) switch(score_idx) {
{
case 0: case 0:
case 1: case 1:
props->mapper_id = 0; props->mapper_id = 0;
break; break;
case 2: case 2:
case 3: case 3:
if ( file_handle.fsize > 0x800200 ) if(file_handle.fsize > 0x800200) {
{
props->mapper_id = 6; /* SO96 interleaved */ props->mapper_id = 6; /* SO96 interleaved */
} } else if(file_handle.fsize > 0x400200) {
else if ( file_handle.fsize > 0x400200 )
{
props->mapper_id = 1; /* ExLoROM */ props->mapper_id = 1; /* ExLoROM */
} } else {
else
{
props->mapper_id = 1; /* LoROM */ props->mapper_id = 1; /* LoROM */
} }
break; break;
case 4: case 4:
case 5: case 5:
props->mapper_id = 2; props->mapper_id = 2;
break; break;
default: default:
props->mapper_id = 1; // whatever props->mapper_id = 1; // whatever
} }
} }
if(header->romsize == 0 || header->romsize > 13) {
if ( header->romsize == 0 || header->romsize > 13 )
{
props->romsize_bytes = 1024; props->romsize_bytes = 1024;
header->romsize = 0; header->romsize = 0;
if(file_handle.fsize >= 1024) {
if ( file_handle.fsize >= 1024 ) while(props->romsize_bytes < file_handle.fsize-1) {
{
while ( props->romsize_bytes < file_handle.fsize - 1 )
{
header->romsize++; header->romsize++;
props->romsize_bytes <<= 1; props->romsize_bytes <<= 1;
} }
} }
} }
props->ramsize_bytes = (uint32_t)1024 << header->ramsize; props->ramsize_bytes = (uint32_t)1024 << header->ramsize;
props->romsize_bytes = (uint32_t)1024 << header->romsize; props->romsize_bytes = (uint32_t)1024 << header->romsize;
props->expramsize_bytes = (uint32_t)1024 << header->expramsize; props->expramsize_bytes = (uint32_t)1024 << header->expramsize;
/*dprintf("ramsize_bytes: %ld\n", props->ramsize_bytes); */
//dprintf("ramsize_bytes: %ld\n", props->ramsize_bytes); if(props->ramsize_bytes < 2048) {
if ( props->ramsize_bytes > 32768 || props->ramsize_bytes < 2048 )
{
props->ramsize_bytes = 0; props->ramsize_bytes = 0;
} }
props->region = (header->destcode <= 1 || header->destcode >= 13) ? 0 : 1; props->region = (header->destcode <= 1 || header->destcode >= 13) ? 0 : 1;
/*dprintf("ramsize_bytes: %ld\n", props->ramsize_bytes); */ /*dprintf("ramsize_bytes: %ld\n", props->ramsize_bytes); */
} }
uint8_t smc_headerscore( uint32_t addr, snes_header_t *header ) uint8_t smc_headerscore(uint32_t addr, snes_header_t* header) {
{
int score=0; int score=0;
uint8_t reset_inst; uint8_t reset_inst;
uint16_t header_offset; uint16_t header_offset;
if((addr & 0xfff) == 0x1b0) {
if ( ( addr & 0xfff ) == 0x1b0 )
{
header_offset = 0x200; header_offset = 0x200;
} } else {
else
{
header_offset = 0; header_offset = 0;
} }
if((file_readblock(header, addr, sizeof(snes_header_t)) < sizeof(snes_header_t)) if((file_readblock(header, addr, sizeof(snes_header_t)) < sizeof(snes_header_t))
|| file_res ) || file_res) {
{
return 0; return 0;
} }
uint8_t mapper = header->map & ~0x10; uint8_t mapper = header->map & ~0x10;
uint16_t resetvector = header->vect_reset; /* not endian safe! */ uint16_t resetvector = header->vect_reset; /* not endian safe! */
uint32_t file_addr = (((addr - header_offset) & ~0x7fff) | (resetvector & 0x7fff)) + header_offset; uint32_t file_addr = (((addr - header_offset) & ~0x7fff) | (resetvector & 0x7fff)) + header_offset;
if(resetvector < 0x8000) return 0;
if ( resetvector < 0x8000 )
{
return 0;
}
score += 2*isFixed(&header->licensee, sizeof(header->licensee), 0x33); score += 2*isFixed(&header->licensee, sizeof(header->licensee), 0x33);
score += 4*checkChksum(header->cchk, header->chk); 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 ( header->carttype < 0x08 ) if((addr-header_offset) == 0x007fc0 && mapper == 0x20) score += 2;
{ if((addr-header_offset) == 0x00ffc0 && mapper == 0x21) score += 2;
score++; if((addr-header_offset) == 0x007fc0 && mapper == 0x22) score += 2;
} if((addr-header_offset) == 0x40ffc0 && mapper == 0x25) score += 2;
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); file_readblock(&reset_inst, file_addr, 1);
switch(reset_inst) {
switch ( reset_inst )
{
case 0x78: /* sei */ case 0x78: /* sei */
case 0x18: /* clc */ case 0x18: /* clc */
case 0x38: /* sec */ case 0x38: /* sec */
@ -395,16 +290,8 @@ uint8_t smc_headerscore( uint32_t addr, snes_header_t *header )
break; break;
} }
if ( score && addr > 0x400000 ) if(score && addr > 0x400000) score += 4;
{ if(score < 0) score = 0;
score += 4;
}
if ( score < 0 )
{
score = 0;
}
return score; return score;
} }

View File

@ -37,8 +37,7 @@
#define FPGA_CX4 ((const uint8_t*)"/sd2snes/fpga_cx4.bit") #define FPGA_CX4 ((const uint8_t*)"/sd2snes/fpga_cx4.bit")
typedef struct _snes_header typedef struct _snes_header {
{
uint8_t maker[2]; /* 0xB0 */ uint8_t maker[2]; /* 0xB0 */
uint8_t gamecode[4]; /* 0xB2 */ uint8_t gamecode[4]; /* 0xB2 */
uint8_t fixed_00[7]; /* 0xB6 */ uint8_t fixed_00[7]; /* 0xB6 */
@ -70,8 +69,7 @@ typedef struct _snes_header
uint16_t vect_brk8; /* 0xFE */ uint16_t vect_brk8; /* 0xFE */
} snes_header_t; } snes_header_t;
typedef struct _snes_romprops typedef struct _snes_romprops {
{
uint16_t offset; /* start of actual ROM image */ uint16_t offset; /* start of actual ROM image */
uint8_t mapper_id; /* FPGA mapper */ uint8_t mapper_id; /* FPGA mapper */
uint8_t pad1; /* for alignment */ uint8_t pad1; /* for alignment */
@ -86,6 +84,7 @@ typedef struct _snes_romprops
uint8_t has_cx4; /* CX4 presence flag */ uint8_t has_cx4; /* CX4 presence flag */
uint8_t fpga_features; /* feature/peripheral enable bits*/ uint8_t fpga_features; /* feature/peripheral enable bits*/
uint8_t region; /* game region (derived from destination code) */ 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 */ snes_header_t header; /* original header from ROM image */
} snes_romprops_t; } snes_romprops_t;

View File

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

View File

@ -38,7 +38,7 @@
#define MENU_ERR_NODSP (1) #define MENU_ERR_NODSP (1)
#define MENU_ERR_NOBSX (2) #define MENU_ERR_NOBSX (2)
#define SNES_RESET_PULSELEN_MS (100) #define SNES_RESET_PULSELEN_MS (1)
uint8_t crc_valid; uint8_t crc_valid;

View File

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

View File

@ -19,87 +19,60 @@ static char sort_str1[SORT_STRLEN + 1], sort_str2[SORT_STRLEN + 1];
uint32_t ptrcache[QSORT_MAXELEM] IN_AHBRAM; uint32_t ptrcache[QSORT_MAXELEM] IN_AHBRAM;
/* get element from pointer table in external RAM*/ /* get element from pointer table in external RAM*/
uint32_t sort_get_elem( uint32_t base, unsigned int index ) uint32_t sort_get_elem(uint32_t base, unsigned int index) {
{
return sram_readlong(base+4*index); return sram_readlong(base+4*index);
} }
/* put element from pointer table in external RAM */ /* put element from pointer table in external RAM */
void sort_put_elem( uint32_t base, unsigned int index, uint32_t elem ) void sort_put_elem(uint32_t base, unsigned int index, uint32_t elem) {
{
sram_writelong(elem, base+4*index); sram_writelong(elem, base+4*index);
} }
/* compare strings pointed to by elements of pointer table */ /* compare strings pointed to by elements of pointer table */
int sort_cmp_idx( uint32_t base, unsigned int index1, unsigned int index2 ) int sort_cmp_idx(uint32_t base, unsigned int index1, unsigned int index2) {
{
uint32_t elem1, elem2; uint32_t elem1, elem2;
elem1 = sort_get_elem(base, index1); elem1 = sort_get_elem(base, index1);
elem2 = sort_get_elem(base, index2); elem2 = sort_get_elem(base, index2);
return sort_cmp_elem((void*)&elem1, (void*)&elem2); return sort_cmp_elem((void*)&elem1, (void*)&elem2);
} }
int sort_cmp_elem( const void *elem1, const void *elem2 ) int sort_cmp_elem(const void* elem1, const void* elem2) {
{
uint32_t el1 = *(uint32_t*)elem1; uint32_t el1 = *(uint32_t*)elem1;
uint32_t el2 = *(uint32_t*)elem2; uint32_t el2 = *(uint32_t*)elem2;
sort_getstring_for_dirent(sort_str1, el1); sort_getstring_for_dirent(sort_str1, el1);
sort_getstring_for_dirent(sort_str2, el2); 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); */ /*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 ) ) if ((el1 & 0x80000000) && !(el2 & 0x80000000)) {
{
return -1; return -1;
} }
if ( !( el1 & 0x80000000 ) && ( el2 & 0x80000000 ) ) if (!(el1 & 0x80000000) && (el2 & 0x80000000)) {
{
return 1; return 1;
} }
if ( *sort_str1 == '.' ) if (*sort_str1 == '.') return -1;
{ if (*sort_str2 == '.') return 1;
return -1;
}
if ( *sort_str2 == '.' )
{
return 1;
}
/* Do not compare trailing slashes of directory names */ /* Do not compare trailing slashes of directory names */
if ( ( el1 & 0x80000000 ) && ( el2 & 0x80000000 ) ) if ((el1 & 0x80000000) && (el2 & 0x80000000)) {
{
char *str1_slash = strrchr(sort_str1, '/'); char *str1_slash = strrchr(sort_str1, '/');
char *str2_slash = strrchr(sort_str2, '/'); char *str2_slash = strrchr(sort_str2, '/');
if(str1_slash != NULL) *str1_slash = 0;
if ( str1_slash != NULL ) if(str2_slash != NULL) *str2_slash = 0;
{
*str1_slash = 0;
}
if ( str2_slash != NULL )
{
*str2_slash = 0;
}
} }
return strcasecmp(sort_str1, sort_str2); return strcasecmp(sort_str1, sort_str2);
} }
/* get truncated string from database */ /* get truncated string from database */
void sort_getstring_for_dirent( char *ptr, uint32_t addr ) void sort_getstring_for_dirent(char *ptr, uint32_t addr) {
{
uint8_t leaf_offset; uint8_t leaf_offset;
if(addr & 0x80000000) {
if ( addr & 0x80000000 )
{
/* is directory link, name offset 4 */ /* is directory link, name offset 4 */
leaf_offset = sram_readbyte(addr + 4 + SRAM_MENU_ADDR); leaf_offset = sram_readbyte(addr + 4 + SRAM_MENU_ADDR);
sram_readstrn(ptr, addr + 5 + leaf_offset + SRAM_MENU_ADDR, SORT_STRLEN); sram_readstrn(ptr, addr + 5 + leaf_offset + SRAM_MENU_ADDR, SORT_STRLEN);
} } else {
else
{
/* is file link, name offset 6 */ /* is file link, name offset 6 */
leaf_offset = sram_readbyte(addr + 6 + SRAM_MENU_ADDR); leaf_offset = sram_readbyte(addr + 6 + SRAM_MENU_ADDR);
sram_readstrn(ptr, addr + 7 + leaf_offset + SRAM_MENU_ADDR, SORT_STRLEN); sram_readstrn(ptr, addr + 7 + leaf_offset + SRAM_MENU_ADDR, SORT_STRLEN);
@ -108,42 +81,31 @@ void sort_getstring_for_dirent( char *ptr, uint32_t addr )
void sort_heapify(uint32_t addr, unsigned int i, unsigned int heapsize) void sort_heapify(uint32_t addr, unsigned int i, unsigned int heapsize)
{ {
while ( 1 ) while(1) {
{
unsigned int l = 2*i+1; unsigned int l = 2*i+1;
unsigned int r = 2*i+2; unsigned int r = 2*i+2;
unsigned int largest = (l < heapsize && sort_cmp_idx(addr, i, l) < 0) ? l : i; unsigned int largest = (l < heapsize && sort_cmp_idx(addr, i, l) < 0) ? l : i;
if(r < heapsize && sort_cmp_idx(addr, largest, r) < 0) if(r < heapsize && sort_cmp_idx(addr, largest, r) < 0)
{
largest = r; largest = r;
}
if ( largest != i ) if(largest != i) {
{
uint32_t tmp = sort_get_elem(addr, i); uint32_t tmp = sort_get_elem(addr, i);
sort_put_elem(addr, i, sort_get_elem(addr, largest)); sort_put_elem(addr, i, sort_get_elem(addr, largest));
sort_put_elem(addr, largest, tmp); sort_put_elem(addr, largest, tmp);
i = largest; i = largest;
} }
else else break;
{
break;
}
} }
} }
void sort_dir(uint32_t addr, unsigned int size) void sort_dir(uint32_t addr, unsigned int size)
{ {
stat_getstring=0; stat_getstring=0;
if(size > QSORT_MAXELEM) {
if ( size > QSORT_MAXELEM )
{
printf("more than %d dir entries, doing slower in-place sort\n", QSORT_MAXELEM); printf("more than %d dir entries, doing slower in-place sort\n", QSORT_MAXELEM);
ext_heapsort(addr, size); ext_heapsort(addr, size);
} } else {
else
{
/* retrieve, sort, and store dir table */ /* retrieve, sort, and store dir table */
sram_readblock(ptrcache, addr, size*4); sram_readblock(ptrcache, addr, size*4);
qsort((void*)ptrcache, size, 4, sort_cmp_elem); qsort((void*)ptrcache, size, 4, sort_cmp_elem);
@ -151,15 +113,10 @@ void sort_dir( uint32_t addr, unsigned int size )
} }
} }
void ext_heapsort( uint32_t addr, unsigned int size ) 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 / 2; i > 0; )
{
sort_heapify( addr, --i, size );
}
for ( unsigned int i = size - 1; i > 0; --i ) for(unsigned int i = size-1; i>0; --i) {
{
uint32_t tmp = sort_get_elem(addr, 0); uint32_t tmp = sort_get_elem(addr, 0);
sort_put_elem(addr, 0, sort_get_elem(addr, i)); sort_put_elem(addr, 0, sort_get_elem(addr, i));
sort_put_elem(addr, i, tmp); sort_put_elem(addr, i, tmp);

View File

@ -30,14 +30,13 @@
#include "spi.h" #include "spi.h"
#include "uart.h" #include "uart.h"
void spi_preinit() void spi_preinit() {
{
/* Set clock prescaler to 1:1 */ /* Set clock prescaler to 1:1 */
BITBAND(LPC_SC->SSP_PCLKREG, SSP_PCLKBIT) = 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 */ /* configure data format - 8 bits, SPI, CPOL=0, CPHA=0, 1 clock per bit */
SSP_REGS->CR0 = (8-1); SSP_REGS->CR0 = (8-1);
@ -53,14 +52,12 @@ void spi_init()
LPC_GPDMA->DMACConfig = 1; LPC_GPDMA->DMACConfig = 1;
} }
void spi_tx_sync() void spi_tx_sync() {
{
/* Wait until TX fifo is flushed */ /* Wait until TX fifo is flushed */
while (BITBAND(SSP_REGS->SR, SSP_BSY)) ; while (BITBAND(SSP_REGS->SR, SSP_BSY)) ;
} }
void spi_tx_byte( uint8_t data ) void spi_tx_byte(uint8_t data) {
{
/* Wait until TX fifo can accept data */ /* Wait until TX fifo can accept data */
while (!BITBAND(SSP_REGS->SR, SSP_TNF)) ; while (!BITBAND(SSP_REGS->SR, SSP_TNF)) ;
@ -68,16 +65,13 @@ void spi_tx_byte( uint8_t data )
SSP_REGS->DR = data; SSP_REGS->DR = data;
} }
uint8_t spi_txrx_byte( uint8_t data ) uint8_t spi_txrx_byte(uint8_t data) {
{
/* Wait until SSP is not busy */ /* Wait until SSP is not busy */
while (BITBAND(SSP_REGS->SR, SSP_BSY)) ; while (BITBAND(SSP_REGS->SR, SSP_BSY)) ;
/* Clear RX fifo */ /* Clear RX fifo */
while (BITBAND(SSP_REGS->SR, SSP_RNE)) while (BITBAND(SSP_REGS->SR, SSP_RNE))
{
(void) SSP_REGS->DR; (void) SSP_REGS->DR;
}
/* Transmit a single byte */ /* Transmit a single byte */
SSP_REGS->DR = data; SSP_REGS->DR = data;
@ -88,16 +82,13 @@ uint8_t spi_txrx_byte( uint8_t data )
return SSP_REGS->DR; return SSP_REGS->DR;
} }
uint8_t spi_rx_byte() uint8_t spi_rx_byte() {
{
/* Wait until SSP is not busy */ /* Wait until SSP is not busy */
while (BITBAND(SSP_REGS->SR, SSP_BSY)) ; while (BITBAND(SSP_REGS->SR, SSP_BSY)) ;
/* Clear RX fifo */ /* Clear RX fifo */
while (BITBAND(SSP_REGS->SR, SSP_RNE)) while (BITBAND(SSP_REGS->SR, SSP_RNE))
{
(void) SSP_REGS->DR; (void) SSP_REGS->DR;
}
/* Transmit a single dummy byte */ /* Transmit a single dummy byte */
SSP_REGS->DR = 0xff; SSP_REGS->DR = 0xff;
@ -108,12 +99,10 @@ uint8_t spi_rx_byte()
return SSP_REGS->DR; return SSP_REGS->DR;
} }
void spi_tx_block( const void *ptr, unsigned int length ) void spi_tx_block(const void *ptr, unsigned int length) {
{
const uint8_t *data = (const uint8_t *)ptr; const uint8_t *data = (const uint8_t *)ptr;
while ( length-- ) while (length--) {
{
/* Wait until TX fifo can accept data */ /* Wait until TX fifo can accept data */
while (!BITBAND(SSP_REGS->SR, SSP_TNF)) ; while (!BITBAND(SSP_REGS->SR, SSP_TNF)) ;
@ -121,8 +110,7 @@ void spi_tx_block( const void *ptr, unsigned int length )
} }
} }
void spi_rx_block( void *ptr, unsigned int length ) void spi_rx_block(void *ptr, unsigned int length) {
{
uint8_t *data = (uint8_t *)ptr; uint8_t *data = (uint8_t *)ptr;
unsigned int txlen = length; unsigned int txlen = length;
@ -131,36 +119,28 @@ void spi_rx_block( void *ptr, unsigned int length )
/* Clear RX fifo */ /* Clear RX fifo */
while (BITBAND(SSP_REGS->SR, SSP_RNE)) while (BITBAND(SSP_REGS->SR, SSP_RNE))
{
(void) SSP_REGS->DR; (void) SSP_REGS->DR;
}
if ( ( length & 3 ) != 0 || ( ( uint32_t )ptr & 3 ) != 0 ) if ((length & 3) != 0 || ((uint32_t)ptr & 3) != 0) {
{
/* Odd length or unaligned buffer */ /* Odd length or unaligned buffer */
while ( length > 0 ) while (length > 0) {
{
/* Wait until TX or RX FIFO are ready */ /* Wait until TX or RX FIFO are ready */
while (txlen > 0 && !BITBAND(SSP_REGS->SR, SSP_TNF) && while (txlen > 0 && !BITBAND(SSP_REGS->SR, SSP_TNF) &&
!BITBAND(SSP_REGS->SR, SSP_RNE)) ; !BITBAND(SSP_REGS->SR, SSP_RNE)) ;
/* Try to receive data */ /* Try to receive data */
while ( length > 0 && BITBAND( SSP_REGS->SR, SSP_RNE ) ) while (length > 0 && BITBAND(SSP_REGS->SR, SSP_RNE)) {
{
*data++ = SSP_REGS->DR; *data++ = SSP_REGS->DR;
length--; length--;
} }
/* Send dummy data until TX full or RX ready */ /* Send dummy data until TX full or RX ready */
while ( txlen > 0 && BITBAND( SSP_REGS->SR, SSP_TNF ) && !BITBAND( SSP_REGS->SR, SSP_RNE ) ) while (txlen > 0 && BITBAND(SSP_REGS->SR, SSP_TNF) && !BITBAND(SSP_REGS->SR, SSP_RNE)) {
{
txlen--; txlen--;
SSP_REGS->DR = 0xff; SSP_REGS->DR = 0xff;
} }
} }
} } else {
else
{
/* Clear interrupt flags of DMA channels 0 */ /* Clear interrupt flags of DMA channels 0 */
LPC_GPDMA->DMACIntTCClear = BV(0); LPC_GPDMA->DMACIntTCClear = BV(0);
LPC_GPDMA->DMACIntErrClr = BV(0); LPC_GPDMA->DMACIntErrClr = BV(0);
@ -187,10 +167,8 @@ void spi_rx_block( void *ptr, unsigned int length )
/* Write <length> bytes into TX FIFO */ /* Write <length> bytes into TX FIFO */
// FIXME: Any value in doing this using DMA too? // FIXME: Any value in doing this using DMA too?
while ( txlen > 0 ) while (txlen > 0) {
{ while (txlen > 0 && BITBAND(SSP_REGS->SR, SSP_TNF)) {
while ( txlen > 0 && BITBAND( SSP_REGS->SR, SSP_TNF ) )
{
txlen--; txlen--;
SSP_REGS->DR = 0xff; SSP_REGS->DR = 0xff;
} }

View File

@ -18,20 +18,16 @@
static uint32_t sd_tacc_max, sd_tacc_avg; static uint32_t sd_tacc_max, sd_tacc_avg;
void sysinfo_loop() void sysinfo_loop() {
{
sd_tacc_max = 0; sd_tacc_max = 0;
sd_tacc_avg = 0; sd_tacc_avg = 0;
while(sram_readbyte(SRAM_CMD_ADDR) != 0x00) {
while ( sram_readbyte( SRAM_CMD_ADDR ) != 0x00 )
{
write_sysinfo(); write_sysinfo();
delay_ms(100); delay_ms(100);
} }
} }
void write_sysinfo() void write_sysinfo() {
{
uint32_t sram_addr = SRAM_SYSINFO_ADDR; uint32_t sram_addr = SRAM_SYSINFO_ADDR;
char linebuf[40]; char linebuf[40];
int len; int len;
@ -53,9 +49,7 @@ void write_sysinfo()
sram_writeblock(linebuf, sram_addr, 40); sram_writeblock(linebuf, sram_addr, 40);
sram_memset(sram_addr+len, 40-len, 0x20); sram_memset(sram_addr+len, 40-len, 0x20);
sram_addr += 40; sram_addr += 40;
if(disk_state == DISK_REMOVED) {
if ( disk_state == DISK_REMOVED )
{
sd_tacc_max = 0; sd_tacc_max = 0;
sd_tacc_avg = 0; sd_tacc_avg = 0;
len = snprintf(linebuf, sizeof(linebuf), " "); len = snprintf(linebuf, sizeof(linebuf), " ");
@ -75,40 +69,28 @@ void write_sysinfo()
sram_memset(sram_addr+len, 40-len, 0x20); sram_memset(sram_addr+len, 40-len, 0x20);
sram_addr += 40; sram_addr += 40;
sd_ok = 0; sd_ok = 0;
} } else {
else
{
len = snprintf(linebuf, sizeof(linebuf), "SD Maker/OEM: 0x%02x, \"%c%c\"", sd_cid[1], sd_cid[2], sd_cid[3]); len = snprintf(linebuf, sizeof(linebuf), "SD Maker/OEM: 0x%02x, \"%c%c\"", sd_cid[1], sd_cid[2], sd_cid[3]);
sram_writeblock(linebuf, sram_addr, 40); sram_writeblock(linebuf, sram_addr, 40);
sram_memset(sram_addr+len, 40-len, 0x20); sram_memset(sram_addr+len, 40-len, 0x20);
sram_addr += 40; sram_addr += 40;
len = snprintf( linebuf, sizeof( linebuf ), "SD Product Name: \"%c%c%c%c%c\", Rev. %d.%d", sd_cid[4], sd_cid[5], len = snprintf(linebuf, sizeof(linebuf), "SD Product Name: \"%c%c%c%c%c\", Rev. %d.%d", sd_cid[4], sd_cid[5], sd_cid[6], sd_cid[7], sd_cid[8], sd_cid[9]>>4, sd_cid[9]&15);
sd_cid[6], sd_cid[7], sd_cid[8], sd_cid[9] >> 4, sd_cid[9] & 15 );
sram_writeblock(linebuf, sram_addr, 40); sram_writeblock(linebuf, sram_addr, 40);
sram_memset(sram_addr+len, 40-len, 0x20); sram_memset(sram_addr+len, 40-len, 0x20);
sram_addr += 40; sram_addr += 40;
len = snprintf( linebuf, sizeof( linebuf ), "SD Serial No.: %02x%02x%02x%02x, Mfd. %d/%02d", sd_cid[10], sd_cid[11], len = snprintf(linebuf, sizeof(linebuf), "SD Serial No.: %02x%02x%02x%02x, Mfd. %d/%02d", sd_cid[10], sd_cid[11], sd_cid[12], sd_cid[13], 2000+((sd_cid[14]&15)<<4)+(sd_cid[15]>>4), sd_cid[15]&15);
sd_cid[12], sd_cid[13], 2000 + ( ( sd_cid[14] & 15 ) << 4 ) + ( sd_cid[15] >> 4 ), sd_cid[15] & 15 );
sram_writeblock(linebuf, sram_addr, 40); sram_writeblock(linebuf, sram_addr, 40);
sram_memset(sram_addr+len, 40-len, 0x20); sram_memset(sram_addr+len, 40-len, 0x20);
sram_addr += 40; sram_addr += 40;
if(sd_tacc_max) if(sd_tacc_max)
{ len = snprintf(linebuf, sizeof(linebuf), "SD acc. time: %ld.%03ld / %ld.%03ld ms avg/max", sd_tacc_avg_int, sd_tacc_avg_frac, sd_tacc_max_int, sd_tacc_max_frac);
len = snprintf( linebuf, sizeof( linebuf ), "SD acc. time: %ld.%03ld / %ld.%03ld ms avg/max", sd_tacc_avg_int,
sd_tacc_avg_frac, sd_tacc_max_int, sd_tacc_max_frac );
}
else else
{
len = snprintf(linebuf, sizeof(linebuf), "SD acc. time: measuring... "); len = snprintf(linebuf, sizeof(linebuf), "SD acc. time: measuring... ");
}
sram_writeblock(linebuf, sram_addr, 40); sram_writeblock(linebuf, sram_addr, 40);
sram_memset(sram_addr+len, 40-len, 0x20); sram_memset(sram_addr+len, 40-len, 0x20);
sram_addr += 40; sram_addr += 40;
sd_ok = 1; sd_ok = 1;
} }
len = snprintf(linebuf, sizeof(linebuf), " "); len = snprintf(linebuf, sizeof(linebuf), " ");
sram_writeblock(linebuf, sram_addr, 40); sram_writeblock(linebuf, sram_addr, 40);
sram_memset(sram_addr+len, 40-len, 0x20); sram_memset(sram_addr+len, 40-len, 0x20);
@ -117,16 +99,10 @@ void write_sysinfo()
sram_writeblock(linebuf, sram_addr, 40); sram_writeblock(linebuf, sram_addr, 40);
sram_memset(sram_addr+len, 40-len, 0x20); sram_memset(sram_addr+len, 40-len, 0x20);
sram_addr += 40; sram_addr += 40;
if(sysclk == -1) if(sysclk == -1)
{
len = snprintf(linebuf, sizeof(linebuf), "SNES master clock: measuring..."); len = snprintf(linebuf, sizeof(linebuf), "SNES master clock: measuring...");
}
else else
{
len = snprintf(linebuf, sizeof(linebuf), "SNES master clock: %ldHz ", get_snes_sysclk()); len = snprintf(linebuf, sizeof(linebuf), "SNES master clock: %ldHz ", get_snes_sysclk());
}
sram_writeblock(linebuf, sram_addr, 40); sram_writeblock(linebuf, sram_addr, 40);
sram_memset(sram_addr+len, 40-len, 0x20); sram_memset(sram_addr+len, 40-len, 0x20);
sram_addr += 40; sram_addr += 40;
@ -146,10 +122,6 @@ void write_sysinfo()
sram_writeblock(linebuf, sram_addr, 40); sram_writeblock(linebuf, sram_addr, 40);
sram_memset(sram_addr+len, 40-len, 0x20); sram_memset(sram_addr+len, 40-len, 0x20);
sram_hexdump(SRAM_SYSINFO_ADDR, 13*40); sram_hexdump(SRAM_SYSINFO_ADDR, 13*40);
if(sysclk != -1 && sd_ok)sdn_gettacc(&sd_tacc_max, &sd_tacc_avg);
if ( sysclk != -1 && sd_ok )
{
sdn_gettacc( &sd_tacc_max, &sd_tacc_avg );
}
} }

View File

@ -7,6 +7,5 @@ void test_sdbench_local(char *filename);
void test_rom_rw(void); void test_rom_rw(void);
void test_fpga_echo(void); void test_fpga_echo(void);
int test_mem(void);
#endif #endif

View File

@ -138,8 +138,7 @@ CFLAGS += $(CDEFS) $(CINCS)
CFLAGS += -O$(OPT) CFLAGS += -O$(OPT)
CFLAGS += $(CPUFLAGS) -nostartfiles CFLAGS += $(CPUFLAGS) -nostartfiles
#CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums #CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
CFLAGS += -Wall -Wstrict-prototypes CFLAGS += -Wall -Wstrict-prototypes -Werror
# -Werror
CFLAGS += -Wa,-adhlns=$(OBJDIR)/$(<:.c=.lst) CFLAGS += -Wa,-adhlns=$(OBJDIR)/$(<:.c=.lst)
CFLAGS += -I$(OBJDIR) CFLAGS += -I$(OBJDIR)
CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS)) CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))

View File

@ -138,7 +138,7 @@ static int8_t parse_wordlist(char *wordlist) {
return -1; return -1;
} }
if (tolower(c) != tolower(*cur)) { if (tolower((int)c) != tolower((int)*cur)) {
// Check for end-of-word // Check for end-of-word
if (cur != curchar && (*cur == ' ' || *cur == 0)) { if (cur != curchar && (*cur == ' ' || *cur == 0)) {
// Partial match found, return that // Partial match found, return that

View File

@ -38,8 +38,7 @@
//#define CONFIG_CPU_FREQUENCY 46000000 //#define CONFIG_CPU_FREQUENCY 46000000
#define CONFIG_UART_PCLKDIV 1 #define CONFIG_UART_PCLKDIV 1
#define CONFIG_UART_TX_BUF_SHIFT 8 #define CONFIG_UART_TX_BUF_SHIFT 8
//#define CONFIG_UART_BAUDRATE 921600 #define CONFIG_UART_BAUDRATE 921600
#define CONFIG_UART_BAUDRATE 115200
#define CONFIG_UART_DEADLOCKABLE #define CONFIG_UART_DEADLOCKABLE
#define SSP_CLK_DIVISOR_FAST 2 #define SSP_CLK_DIVISOR_FAST 2

View File

@ -101,9 +101,9 @@ led_pwm();
testresults[TEST_SD] = test_sd(); testresults[TEST_SD] = test_sd();
//testresults[TEST_USB] = test_usb(); //testresults[TEST_USB] = test_usb();
//testresults[TEST_RTC] = test_rtc(); testresults[TEST_RTC] = test_rtc();
delay_ms(209); delay_ms(209);
// testresults[TEST_CIC] = test_cic(); testresults[TEST_CIC] = test_cic();
testresults[TEST_FPGA] = test_fpga(); testresults[TEST_FPGA] = test_fpga();
testresults[TEST_RAM] = test_mem(); testresults[TEST_RAM] = test_mem();
printf("Loading SNES test ROM\n=====================\n"); printf("Loading SNES test ROM\n=====================\n");

View File

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

View File

@ -152,178 +152,74 @@ int test_fpga() {
return PASSED; return PASSED;
} }
/*************************************************************************************/ int test_mem() {
/*************************************************************************************/ printf("RAM test\n========\n");
printf("Testing RAM0 (128Mbit) - writing RAM -");
typedef struct memory_test uint32_t addr;
{
char name[20];
int a_len;
int d_len;
unsigned int (*read)(unsigned int addr);
void (*write)(unsigned int addr, unsigned int data);
void (*open)(void);
void (*close)(void);
} memory_test;
/*************************************************************************************/
void rom_open(void)
{
snes_reset(1); snes_reset(1);
fpga_select_mem(0); fpga_select_mem(0);
set_mcu_addr(0);
FPGA_DESELECT(); FPGA_DESELECT();
delay_ms(1); delay_ms(1);
FPGA_SELECT(); FPGA_SELECT();
delay_ms(1); delay_ms(1);
FPGA_TX_BYTE(0x98);
for(addr=0; addr < 16777216; addr++) {
if((addr&0xffff) == 0)printf("\x8%c", PROGRESS[(addr>>16)&3]);
FPGA_TX_BYTE((addr)+(addr>>8)+(addr>>16));
FPGA_WAIT_RDY();
} }
void rom_close(void) FPGA_DESELECT();
{ printf(" verifying RAM -");
} uint8_t data, expect, error=0, failed=0;
set_mcu_addr(0);
unsigned int rom_read(unsigned int addr) FPGA_SELECT();
{ FPGA_TX_BYTE(0x88);
return sram_readbyte(addr); for(addr=0; addr < 16777216; addr++) {
} if((addr&0xffff) == 0)printf("\x8%c", PROGRESS[(addr>>16)&3]);
FPGA_WAIT_RDY();
void rom_write(unsigned int addr, unsigned int data) data = FPGA_RX_BYTE();
{ expect = (addr)+(addr>>8)+(addr>>16);
sram_writebyte(data, addr); if(data != expect) {
} printf("error @0x%06lx: expected 0x%02x, got 0x%02x\n", addr, expect, data);
error++;
memory_test rom = { failed=1;
.name = "RAM0 (128Mbit)", if(error>20) {
.a_len = 22, printf("too many errors, aborting\n");
.d_len = 8,
.read = rom_read,
.write = rom_write,
.open = rom_open,
.close = rom_close,
};
/*************************************************************************************/
void sram_open(void)
{
snes_reset(1);
fpga_select_mem(1);
}
void sram_close(void)
{
}
unsigned int sram_read(unsigned int addr)
{
return sram_readbyte(addr);
}
void sram_write(unsigned int addr, unsigned int data)
{
sram_writebyte(data, addr);
}
memory_test sram =
{
.name = "RAM1(4Mbit)",
.a_len = 19,
.d_len = 8,
.read = sram_read,
.write = sram_write,
.open = sram_open,
.close = sram_close,
};
int do_test(memory_test *test)
{
int i, j, read, want;
int ret = 0;
int a_mask = (1 << test->a_len) - 1;
int d_mask = (1 << test->d_len) - 1;
test->open();
printf("-- Will test %s\n", test->name);
printf("---- Fill with AA55 ");
test->write(0, 0xAA);
for (i = 1; i < a_mask; i++)
{
if((i&0xffff) == 0)printf("\x8%c", PROGRESS[(i>>16)&3]);
want = (i&1)?0x55:0xAA;
test->write(i, want);
want = ((i-1)&1)?0x55:0xAA;
read = test->read(i-1);
if (read != want)
{
printf("Failed [@%8X Want: %02X Get: %02X]", i-1, want, read);
ret |= 1;
break; break;
} }
} }
printf("Ok \n---- Fill with 00 ");
for (i = 0; i < a_mask; i++)
{
if((i&0xffff) == 0)printf("\x8%c", PROGRESS[(i>>16)&3]);
test->write(i, 0);
} }
FPGA_DESELECT();
printf("Ok \n---- Check data lines...\n" if(error) printf("RAM0 FAILED\n");
"----- "); else printf("RAM0 PASSED\n");
for (i = 0; i < test->d_len; i++) printf("%X", i); printf("Testing RAM1 (4Mbit) - writing RAM - ");
printf("\n"); snes_reset(1);
/* Check on 4 addresses, taken evenly */ fpga_select_mem(1);
#define TEST_NUM (10) for(addr=0; addr < 524288; addr++) {
sram_writebyte((addr)+(addr>>8)+(addr>>16), addr);
for (j = 0; j < TEST_NUM; j ++)
{
printf("----- %8X [", j * a_mask/TEST_NUM);
for (i = 0; i < test->d_len; i++)
{
read = test->read(j * a_mask/TEST_NUM);
if ((test->read(j * a_mask/TEST_NUM) & (1<<i)) != 0)
{
printf("1", read);
ret |= 2;
goto next_data;
} }
test->write(j * a_mask/TEST_NUM, (1<<i)); printf("verifying RAM...");
read = test->read(j * a_mask/TEST_NUM); error = 0;
if (read == 0) for(addr=0; addr < 524288; addr++) {
{ data = sram_readbyte(addr);
printf("0"); expect = (addr)+(addr>>8)+(addr>>16);
ret |= 4; if(data != expect) {
goto next_data; printf("error @0x%05lx: expected 0x%02x, got 0x%02x\n", addr, expect, data);
error++;
failed=1;
if(error>20) {
printf("too many errors, aborting\n");
break;
} }
printf("x");
next_data:
test->write(j * a_mask/4, 0);
} }
printf("]\n");
} }
if(error) printf("RAM1 FAILED\n\n\n");
else printf("RAM1 PASSED\n\n\n");
test->close(); if(failed) return FAILED;
return ret;
}
int test_mem()
{
int ret = PASSED;
printf("RAM test\n========\n");
if (do_test(&rom) != 0)
ret = FAILED;
if (do_test(&sram) != 0);
ret = FAILED;
return PASSED; return PASSED;
} }
int test_clk() { int test_clk() {
uint32_t sysclk[4]; uint32_t sysclk[4];
int32_t diff, max_diff = 0; int32_t diff, max_diff = 0;

View File

@ -73,8 +73,7 @@ void RIT_IRQHandler(void) {
RIT_Hook(); RIT_Hook();
} }
void timer_init(void) void timer_init(void) {
{
/* turn on power to RIT */ /* turn on power to RIT */
BITBAND(LPC_SC->PCONP, PCRIT) = 1; BITBAND(LPC_SC->PCONP, PCRIT) = 1;
@ -88,8 +87,7 @@ void timer_init(void)
SysTick_Config((SysTick->CALIB & SysTick_CALIB_TENMS_Msk)); SysTick_Config((SysTick->CALIB & SysTick_CALIB_TENMS_Msk));
} }
void delay_us(unsigned int time) void delay_us(unsigned int time) {
{
/* Prepare RIT */ /* Prepare RIT */
LPC_RIT->RICOUNTER = 0; LPC_RIT->RICOUNTER = 0;
LPC_RIT->RICOMPVAL = (CONFIG_CPU_FREQUENCY / 1000000) * time; LPC_RIT->RICOMPVAL = (CONFIG_CPU_FREQUENCY / 1000000) * time;

View File

@ -18,50 +18,39 @@ extern volatile int reset_pressed;
volatile tick_t ticks; volatile tick_t ticks;
volatile int wokefromrit; volatile int wokefromrit;
void __attribute__( ( weak, noinline ) ) SysTick_Hook( void ) void __attribute__((weak,noinline)) SysTick_Hook(void) {
{
/* Empty function for hooking the systick handler */ /* Empty function for hooking the systick handler */
} }
/* Systick interrupt handler */ /* Systick interrupt handler */
void SysTick_Handler( void ) void SysTick_Handler(void) {
{
ticks++; ticks++;
static uint16_t sdch_state = 0; static uint16_t sdch_state = 0;
static uint16_t reset_state = 0; static uint16_t reset_state = 0;
sdch_state = (sdch_state << 1) | SDCARD_DETECT | 0xe000; sdch_state = (sdch_state << 1) | SDCARD_DETECT | 0xe000;
if((sdch_state == 0xf000) || (sdch_state == 0xefff)) {
if ( ( sdch_state == 0xf000 ) || ( sdch_state == 0xefff ) )
{
sd_changed = 1; sd_changed = 1;
} }
reset_state = (reset_state << 1) | get_snes_reset() | 0xe000; reset_state = (reset_state << 1) | get_snes_reset() | 0xe000;
if((reset_state == 0xf000) || (reset_state == 0xefff)) {
if ( ( reset_state == 0xf000 ) || ( reset_state == 0xefff ) )
{
reset_pressed = (reset_state == 0xf000); reset_pressed = (reset_state == 0xf000);
reset_changed = 1; reset_changed = 1;
} }
sdn_changed(); sdn_changed();
SysTick_Hook(); SysTick_Hook();
} }
void __attribute__( ( weak, noinline ) ) RIT_Hook( void ) void __attribute__((weak,noinline)) RIT_Hook(void) {
{
} }
void RIT_IRQHandler( void ) void RIT_IRQHandler(void) {
{
LPC_RIT->RICTRL = BV(RITINT); LPC_RIT->RICTRL = BV(RITINT);
NVIC_ClearPendingIRQ(RIT_IRQn); NVIC_ClearPendingIRQ(RIT_IRQn);
wokefromrit = 1; wokefromrit = 1;
RIT_Hook(); RIT_Hook();
} }
void timer_init( void ) void timer_init(void) {
{
/* turn on power to RIT */ /* turn on power to RIT */
BITBAND(LPC_SC->PCONP, PCRIT) = 1; BITBAND(LPC_SC->PCONP, PCRIT) = 1;
@ -83,8 +72,7 @@ void timer_init( void )
SysTick_Config((SysTick->CALIB & SysTick_CALIB_TENMS_Msk)); SysTick_Config((SysTick->CALIB & SysTick_CALIB_TENMS_Msk));
} }
void delay_us( unsigned int time ) void delay_us(unsigned int time) {
{
/* Prepare RIT */ /* Prepare RIT */
LPC_RIT->RICOUNTER = 0; LPC_RIT->RICOUNTER = 0;
LPC_RIT->RICOMPVAL = (CONFIG_CPU_FREQUENCY / 1000000) * time; LPC_RIT->RICOMPVAL = (CONFIG_CPU_FREQUENCY / 1000000) * time;
@ -97,8 +85,7 @@ void delay_us( unsigned int time )
LPC_RIT->RICTRL = 0; LPC_RIT->RICTRL = 0;
} }
void delay_ms( unsigned int time ) void delay_ms(unsigned int time) {
{
/* Prepare RIT */ /* Prepare RIT */
LPC_RIT->RICOUNTER = 0; LPC_RIT->RICOUNTER = 0;
LPC_RIT->RICOMPVAL = (CONFIG_CPU_FREQUENCY / 1000) * time; LPC_RIT->RICOMPVAL = (CONFIG_CPU_FREQUENCY / 1000) * time;
@ -111,8 +98,7 @@ void delay_ms( unsigned int time )
LPC_RIT->RICTRL = 0; LPC_RIT->RICTRL = 0;
} }
void sleep_ms( unsigned int time ) void sleep_ms(unsigned int time) {
{
wokefromrit = 0; wokefromrit = 0;
/* Prepare RIT */ /* Prepare RIT */
@ -123,11 +109,9 @@ void sleep_ms( unsigned int time )
/* Wait until RIT signals an interrupt */ /* Wait until RIT signals an interrupt */
//uart_putc(';'); //uart_putc(';');
while ( !wokefromrit ) while(!wokefromrit) {
{
__WFI(); __WFI();
} }
NVIC_DisableIRQ(RIT_IRQn); NVIC_DisableIRQ(RIT_IRQn);
/* Disable RIT */ /* Disable RIT */
LPC_RIT->RICTRL = BV(RITINT); LPC_RIT->RICTRL = BV(RITINT);

View File

@ -42,8 +42,7 @@
#else #else
# error CONFIG_UART_NUM is not set or has an invalid value! # error CONFIG_UART_NUM is not set or has an invalid value!
#endif #endif
static uint8_t uart_lookupratio( float f_fr ) static uint8_t uart_lookupratio(float f_fr) {
{
uint16_t errors[72]={0,67,71,77,83,91,100,111,125, uint16_t errors[72]={0,67,71,77,83,91,100,111,125,
133,143,154,167,182,200,214,222,231, 133,143,154,167,182,200,214,222,231,
250,267,273,286,300,308,333,357,364, 250,267,273,286,300,308,333,357,364,
@ -51,8 +50,7 @@ static uint8_t uart_lookupratio( float f_fr )
500,533,538,545,556,571,583,600,615, 500,533,538,545,556,571,583,600,615,
625,636,643,667,692,700,714,727,733, 625,636,643,667,692,700,714,727,733,
750,769,778,786,800,818,833,846,857, 750,769,778,786,800,818,833,846,857,
867, 875, 889, 900, 909, 917, 923, 929, 933 867,875,889,900,909,917,923,929,933};
};
uint8_t ratios[72]={0x10,0xf1,0xe1,0xd1,0xc1,0xb1,0xa1,0x91,0x81, uint8_t ratios[72]={0x10,0xf1,0xe1,0xd1,0xc1,0xb1,0xa1,0x91,0x81,
0xf2,0x71,0xd2,0x61,0xb2,0x51,0xe3,0x92,0xd3, 0xf2,0x71,0xd2,0x61,0xb2,0x51,0xe3,0x92,0xd3,
@ -61,36 +59,26 @@ static uint8_t uart_lookupratio( float f_fr )
0x21,0xf8,0xd7,0xb6,0x95,0x74,0xc7,0x53,0xd8, 0x21,0xf8,0xd7,0xb6,0x95,0x74,0xc7,0x53,0xd8,
0x85,0xb7,0xe9,0x32,0xd9,0xa7,0x75,0xb8,0xfb, 0x85,0xb7,0xe9,0x32,0xd9,0xa7,0x75,0xb8,0xfb,
0x43,0xda,0x97,0xeb,0x54,0xb9,0x65,0xdb,0x76, 0x43,0xda,0x97,0xeb,0x54,0xb9,0x65,0xdb,0x76,
0xfd, 0x87, 0x98, 0xa9, 0xba, 0xcb, 0xdc, 0xed, 0xfe 0xfd,0x87,0x98,0xa9,0xba,0xcb,0xdc,0xed,0xfe};
};
int fr = (f_fr-1)*1000; int fr = (f_fr-1)*1000;
int i=0, i_result=0; int i=0, i_result=0;
int err=0, lasterr=1000; int err=0, lasterr=1000;
for(i=0; i<72; i++) {
for ( i = 0; i < 72; i++ ) if(fr<errors[i]) {
{
if ( fr < errors[i] )
{
err=errors[i]-fr; err=errors[i]-fr;
} } else {
else
{
err=fr-errors[i]; err=fr-errors[i];
} }
if(err<lasterr) {
if ( err < lasterr )
{
i_result=i; i_result=i;
lasterr=err; lasterr=err;
} }
} }
return ratios[i_result]; return ratios[i_result];
} }
static uint32_t baud2divisor( unsigned int baudrate ) static uint32_t baud2divisor(unsigned int baudrate) {
{
uint32_t int_ratio; uint32_t int_ratio;
uint32_t error; uint32_t error;
uint32_t dl=0; uint32_t dl=0;
@ -102,26 +90,18 @@ static uint32_t baud2divisor( unsigned int baudrate )
f_ratio=(f_pclk / 16 / baudrate); f_ratio=(f_pclk / 16 / baudrate);
int_ratio = (int)f_ratio; int_ratio = (int)f_ratio;
error=(f_ratio*1000)-(int_ratio*1000); error=(f_ratio*1000)-(int_ratio*1000);
if(error>990) {
if ( error > 990 )
{
int_ratio++; int_ratio++;
} } else if(error>10) {
else if ( error > 10 )
{
f_fr=1.5; f_fr=1.5;
f_dl=f_pclk / (16 * baudrate * (f_fr)); f_dl=f_pclk / (16 * baudrate * (f_fr));
dl = (int)f_dl; dl = (int)f_dl;
f_fr=f_pclk / (16 * baudrate * dl); f_fr=f_pclk / (16 * baudrate * dl);
fract_ratio = uart_lookupratio(f_fr); fract_ratio = uart_lookupratio(f_fr);
} }
if(!dl) {
if ( !dl )
{
return int_ratio; return int_ratio;
} } else {
else
{
return ((fract_ratio<<16)&0xff0000) | dl; return ((fract_ratio<<16)&0xff0000) | dl;
} }
} }
@ -129,40 +109,29 @@ static uint32_t baud2divisor( unsigned int baudrate )
static char txbuf[1 << CONFIG_UART_TX_BUF_SHIFT]; 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_HANDLER( void ) void UART_HANDLER(void) {
{
int iir = UART_REGS->IIR; int iir = UART_REGS->IIR;
if (!(iir & 1)) {
if ( !( iir & 1 ) )
{
/* Interrupt is pending */ /* Interrupt is pending */
switch ( iir & 14 ) switch (iir & 14) {
{
#if CONFIG_UART_NUM == 1 #if CONFIG_UART_NUM == 1
case 0: /* modem status */ case 0: /* modem status */
(void) UART_REGS->MSR; // dummy read to clear (void) UART_REGS->MSR; // dummy read to clear
break; break;
#endif #endif
case 2: /* THR empty - send */ case 2: /* THR empty - send */
if ( read_idx != write_idx ) if (read_idx != write_idx) {
{
int maxchars = 16; int maxchars = 16;
while (read_idx != write_idx && --maxchars > 0) {
while ( read_idx != write_idx && --maxchars > 0 )
{
UART_REGS->THR = (unsigned char)txbuf[read_idx]; UART_REGS->THR = (unsigned char)txbuf[read_idx];
read_idx = (read_idx+1) & (sizeof(txbuf)-1); read_idx = (read_idx+1) & (sizeof(txbuf)-1);
} }
if (read_idx == write_idx) {
if ( read_idx == write_idx )
{
/* buffer empty - turn off THRE interrupt */ /* buffer empty - turn off THRE interrupt */
BITBAND(UART_REGS->IER, 1) = 0; BITBAND(UART_REGS->IER, 1) = 0;
} }
} }
break; break;
case 12: /* RX timeout */ case 12: /* RX timeout */
@ -178,26 +147,18 @@ void UART_HANDLER( void )
} }
} }
void uart_putc( char c ) void uart_putc(char c) {
{
if (c == '\n') if (c == '\n')
{
uart_putc('\r'); uart_putc('\r');
}
unsigned int tmp = (write_idx+1) & (sizeof(txbuf)-1) ; unsigned int tmp = (write_idx+1) & (sizeof(txbuf)-1) ;
if ( read_idx == write_idx && ( BITBAND( UART_REGS->LSR, 5 ) ) ) if (read_idx == write_idx && (BITBAND(UART_REGS->LSR, 5))) {
{
/* buffer empty, THR empty -> send immediately */ /* buffer empty, THR empty -> send immediately */
UART_REGS->THR = (unsigned char)c; UART_REGS->THR = (unsigned char)c;
} } else {
else
{
#ifdef CONFIG_UART_DEADLOCKABLE #ifdef CONFIG_UART_DEADLOCKABLE
while (tmp == read_idx) ; while (tmp == read_idx) ;
#endif #endif
BITBAND(UART_REGS->IER, 1) = 0; // turn off UART interrupt BITBAND(UART_REGS->IER, 1) = 0; // turn off UART interrupt
txbuf[write_idx] = c; txbuf[write_idx] = c;
@ -207,45 +168,34 @@ void uart_putc( char c )
} }
/* Polling version only */ /* Polling version only */
unsigned char uart_getc( void ) unsigned char uart_getc(void) {
{
/* wait for character */ /* wait for character */
while (!(BITBAND(UART_REGS->LSR, 0))) ; while (!(BITBAND(UART_REGS->LSR, 0))) ;
return UART_REGS->RBR; return UART_REGS->RBR;
} }
/* Returns true if a char is ready */ /* Returns true if a char is ready */
unsigned char uart_gotc( void ) unsigned char uart_gotc(void) {
{
return BITBAND(UART_REGS->LSR, 0); return BITBAND(UART_REGS->LSR, 0);
} }
void uart_init( void ) void uart_init(void) {
{
uint32_t div; uint32_t div;
/* Turn on power to UART */ /* Turn on power to UART */
BITBAND(LPC_SC->PCONP, UART_PCONBIT) = 1; BITBAND(LPC_SC->PCONP, UART_PCONBIT) = 1;
/* UART clock = CPU clock - this block is reduced at compile-time */ /* UART clock = CPU clock - this block is reduced at compile-time */
if ( CONFIG_UART_PCLKDIV == 1 ) if (CONFIG_UART_PCLKDIV == 1) {
{
BITBAND(LPC_SC->UART_PCLKREG, UART_PCLKBIT ) = 1; BITBAND(LPC_SC->UART_PCLKREG, UART_PCLKBIT ) = 1;
BITBAND(LPC_SC->UART_PCLKREG, UART_PCLKBIT+1) = 0; BITBAND(LPC_SC->UART_PCLKREG, UART_PCLKBIT+1) = 0;
} } else if (CONFIG_UART_PCLKDIV == 2) {
else if ( CONFIG_UART_PCLKDIV == 2 )
{
BITBAND(LPC_SC->UART_PCLKREG, UART_PCLKBIT ) = 0; BITBAND(LPC_SC->UART_PCLKREG, UART_PCLKBIT ) = 0;
BITBAND(LPC_SC->UART_PCLKREG, UART_PCLKBIT+1) = 1; BITBAND(LPC_SC->UART_PCLKREG, UART_PCLKBIT+1) = 1;
} } else if (CONFIG_UART_PCLKDIV == 4) {
else if ( CONFIG_UART_PCLKDIV == 4 )
{
BITBAND(LPC_SC->UART_PCLKREG, UART_PCLKBIT ) = 0; BITBAND(LPC_SC->UART_PCLKREG, UART_PCLKBIT ) = 0;
BITBAND(LPC_SC->UART_PCLKREG, UART_PCLKBIT+1) = 0; BITBAND(LPC_SC->UART_PCLKREG, UART_PCLKBIT+1) = 0;
} } else { // Fallback: Divide by 8
else // Fallback: Divide by 8
{
BITBAND(LPC_SC->UART_PCLKREG, UART_PCLKBIT ) = 1; BITBAND(LPC_SC->UART_PCLKREG, UART_PCLKBIT ) = 1;
BITBAND(LPC_SC->UART_PCLKREG, UART_PCLKBIT+1) = 1; BITBAND(LPC_SC->UART_PCLKREG, UART_PCLKBIT+1) = 1;
} }
@ -258,8 +208,7 @@ void uart_init( void )
UART_REGS->DLM = (div >> 8) & 0xff; UART_REGS->DLM = (div >> 8) & 0xff;
BITBAND(UART_REGS->LCR, 7) = 0; BITBAND(UART_REGS->LCR, 7) = 0;
if ( div & 0xff0000 ) if (div & 0xff0000) {
{
UART_REGS->FDR = (div >> 16) & 0xff; UART_REGS->FDR = (div >> 16) & 0xff;
} }
@ -274,102 +223,67 @@ void uart_init( void )
} }
/* --- generic code below --- */ /* --- generic code below --- */
void uart_puthex( uint8_t num ) void uart_puthex(uint8_t num) {
{
uint8_t tmp; uint8_t tmp;
tmp = (num & 0xf0) >> 4; tmp = (num & 0xf0) >> 4;
if (tmp < 10) if (tmp < 10)
{
uart_putc('0'+tmp); uart_putc('0'+tmp);
}
else else
{
uart_putc('a'+tmp-10); uart_putc('a'+tmp-10);
}
tmp = num & 0x0f; tmp = num & 0x0f;
if (tmp < 10) if (tmp < 10)
{
uart_putc('0'+tmp); uart_putc('0'+tmp);
}
else else
{
uart_putc('a'+tmp-10); uart_putc('a'+tmp-10);
} }
}
void uart_trace( void *ptr, uint16_t start, uint16_t len, uint32_t addr ) void uart_trace(void *ptr, uint16_t start, uint16_t len) {
{
uint16_t i; uint16_t i;
uint8_t j; uint8_t j;
uint8_t ch; uint8_t ch;
uint8_t *data = ptr; uint8_t *data = ptr;
data+=start; data+=start;
for(i=0;i<len;i+=16) {
for ( i = 0; i < len; i += 16 ) uart_puthex(start>>8);
{ uart_puthex(start&0xff);
uart_puthex( ( addr + start ) >> 16 );
uart_puthex( ( ( addr + start ) >> 8 ) & 0xff );
uart_puthex( ( addr + start ) & 0xff );
uart_putc('|'); uart_putc('|');
uart_putc(' '); uart_putc(' ');
for(j=0;j<16;j++) {
for ( j = 0; j < 16; j++ ) if(i+j<len) {
{
if ( i + j < len )
{
ch=*(data + j); ch=*(data + j);
uart_puthex(ch); uart_puthex(ch);
} } else {
else
{
uart_putc(' '); uart_putc(' ');
uart_putc(' '); uart_putc(' ');
} }
uart_putc(' '); uart_putc(' ');
} }
uart_putc('|'); uart_putc('|');
for(j=0;j<16;j++) {
for ( j = 0; j < 16; j++ ) if(i+j<len) {
{
if ( i + j < len )
{
ch=*(data++); ch=*(data++);
if(ch<32 || ch>0x7e) if(ch<32 || ch>0x7e)
{
ch='.'; ch='.';
}
uart_putc(ch); uart_putc(ch);
} } else {
else
{
uart_putc(' '); uart_putc(' ');
} }
} }
uart_putc('|'); uart_putc('|');
uart_putcrlf(); uart_putcrlf();
start+=16; start+=16;
} }
} }
void uart_flush( void ) void uart_flush(void) {
{
while (read_idx != write_idx) ; while (read_idx != write_idx) ;
} }
void uart_puts( const char *text ) void uart_puts(const char *text) {
{ while (*text) {
while ( *text )
{
uart_putc(*text++); uart_putc(*text++);
} }
} }

View File

@ -26,7 +26,7 @@ unsigned char uart_gotc(void);
void uart_putc(char c); void uart_putc(char c);
void uart_puts(const char *str); void uart_puts(const char *str);
void uart_puthex(uint8_t num); void uart_puthex(uint8_t num);
void uart_trace(void *ptr, uint16_t start, uint16_t len, uint32_t addr); void uart_trace(void *ptr, uint16_t start, uint16_t len);
void uart_flush(void); void uart_flush(void);
int printf(const char *fmt, ...); int printf(const char *fmt, ...);
int snprintf(char *str, size_t size, const char *format, ...); int snprintf(char *str, size_t size, const char *format, ...);

View File

@ -1,16 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include "cfgware.h"
int main( int argc, char *argv[] )
{
int i;
for ( i = 0; i < sizeof( cfgware ); i++ )
{
printf( "%c", cfgware[i] );
}
return 0;
}

View File

@ -2,14 +2,11 @@
CC = gcc CC = gcc
CFLAGS = -Wall -Wstrict-prototypes -Werror CFLAGS = -Wall -Wstrict-prototypes -Werror
all: lpcchksum genhdr bin2h all: lpcchksum genhdr
genhdr: genhdr.o genhdr: genhdr.o
$(CC) $(CFLAGS) $^ --output $@ $(CC) $(CFLAGS) $^ --output $@
bin2h: bin2h.o
$(CC) $(CFLAGS) $^ --output $@
lpcchksum: lpcchksum.o lpcchksum: lpcchksum.o
$(CC) $(CFLAGS) $^ --output $@ $(CC) $(CFLAGS) $^ --output $@

View File

@ -1,77 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
int main( int argc, char *argv[] )
{
char var_name[30] = "cfgware";
FILE *fpIn = NULL, *fpOut = NULL;
unsigned char buffer[5], i;
printf( "argc: %d\n", argc );
if ( argc == 4 )
{
fpIn = fopen( argv[1], "rb" );
fpOut = fopen( argv[2], "wt" );
sprintf( var_name, "%s", argv[3] );
}
else if ( argc == 3 )
{
fpIn = fopen( argv[1], "rb" );
fpOut = fopen( argv[2], "wt" );
}
else if ( argc == 2 )
{
fpIn = fopen( argv[1], "rb" );
fpOut = stdout;
}
else if ( argc == 1 )
{
fpIn = stdin;
fpOut = stdout;
}
else
{
fprintf( stderr, "usage: %s [infile] [outfile] [name]\n", argv[0] );
return -1;
}
// if (argc > 1)
// sprintf()
if ( fpIn == NULL )
{
fprintf( stderr, "Can't open '%s`: Aborting.", argv[1] );
return -1;
}
if ( fpOut == NULL )
{
fprintf( stderr, "Can't open '%s`: Aborting.", argv[2] );
return -1;
}
fprintf( fpOut, "const uint8_t %s[] = {\n", var_name );
i = 0;
while ( !feof( fpIn ) )
{
fread( buffer, 1, 1, fpIn );
fprintf( fpOut, "0x%02X, ", buffer[0] );
i++;
if ( i > 8 )
{
fprintf( fpOut, "\n" );
i = 0;
}
}
if ( i > 0 )
{
fprintf( fpOut, "\n" );
}
fprintf( fpOut, "};" );
fclose( fpOut ); fclose( fpIn );
return 0;
}

View File

@ -18,56 +18,41 @@ uint32_t crc_reflect( uint32_t data, size_t data_len )
uint32_t ret; uint32_t ret;
ret = data & 0x01; ret = data & 0x01;
for (i = 1; i < data_len; i++) for (i = 1; i < data_len; i++)
{ {
data >>= 1; data >>= 1;
ret = (ret << 1) | (data & 0x01); ret = (ret << 1) | (data & 0x01);
} }
return ret; return ret;
} }
uint32_t crc_update( uint32_t crc, const uint8_t *buf, uint32_t len ) uint32_t crc_update(uint32_t crc, const uint8_t *buf, uint32_t len) {
{
unsigned int i; unsigned int i;
uint32_t bit; uint32_t bit;
uint8_t c; uint8_t c;
while ( len-- ) while (len--) {
{
c = *buf++; c = *buf++;
for (i = 0x01; i & 0xff; i <<= 1) {
for ( i = 0x01; i & 0xff; i <<= 1 )
{
bit = crc & 0x80000000; bit = crc & 0x80000000;
if (c & i) {
if ( c & i )
{
bit = bit ? 0 : 1; bit = bit ? 0 : 1;
} }
crc <<= 1; crc <<= 1;
if (bit) {
if ( bit )
{
crc ^= 0x04c11db7; crc ^= 0x04c11db7;
} }
} }
crc &= 0xffffffff; crc &= 0xffffffff;
} }
return crc & 0xffffffff; return crc & 0xffffffff;
} }
int main( int argc, char **argv ) int main(int argc, char **argv) {
{
FILE *f; FILE *f;
size_t flen; size_t flen;
if ( argc < 3 ) if(argc < 3) {
{
printf("Usage: genhdr <input file> <signature> <version>\n" printf("Usage: genhdr <input file> <signature> <version>\n"
" input file: file to be headered\n" " input file: file to be headered\n"
" signature : magic value at start of header (4-char string)\n" " signature : magic value at start of header (4-char string)\n"
@ -75,45 +60,33 @@ int main( int argc, char **argv )
"Output is written in place.\n"); "Output is written in place.\n");
return 1; return 1;
} }
if((f=fopen(argv[1], "rb+"))==NULL) {
if ( ( f = fopen( argv[1], "rb+" ) ) == NULL )
{
printf("Unable to open input file %s", argv[1]); printf("Unable to open input file %s", argv[1]);
perror(""); perror("");
return 1; return 1;
} }
fseek(f,0,SEEK_END); fseek(f,0,SEEK_END);
flen=ftell(f); flen=ftell(f);
if ( flen + 256 < flen ) if(flen+256 < flen) {
{
printf("File too large ;)\n"); printf("File too large ;)\n");
return 1; return 1;
} }
char *remaining = NULL; char *remaining = NULL;
uint32_t version = (uint32_t)strtol(argv[3], &remaining, 0); uint32_t version = (uint32_t)strtol(argv[3], &remaining, 0);
if(*remaining) {
if ( *remaining )
{
printf("could not parse version number (remaining portion: %s)\n", remaining); printf("could not parse version number (remaining portion: %s)\n", remaining);
fclose(f); fclose(f);
return 1; return 1;
} }
if ( strlen( argv[2] ) > 4 ) if(strlen(argv[2]) > 4) {
{
printf("Magic string '%s' too long. Truncated to 4 characters.\n", argv[2]); printf("Magic string '%s' too long. Truncated to 4 characters.\n", argv[2]);
} }
uint8_t *buf = malloc(flen+256); uint8_t *buf = malloc(flen+256);
if(!buf) {
if ( !buf )
{
perror("malloc"); perror("malloc");
} }
memset(buf, 0xff, 256); memset(buf, 0xff, 256);
fseek(f, 0, SEEK_SET); fseek(f, 0, SEEK_SET);
fread(buf+256, 1, flen, f); fread(buf+256, 1, flen, f);

BIN
src/utils/lpcchksum Executable file

Binary file not shown.

View File

@ -7,35 +7,30 @@
#include <stdint.h> #include <stdint.h>
uint32_t getu32( uint8_t *buffer ) uint32_t getu32(uint8_t *buffer) {
{
return buffer[0]+(buffer[1]<<8)+(buffer[2]<<16)+(buffer[3]<<24); return buffer[0]+(buffer[1]<<8)+(buffer[2]<<16)+(buffer[3]<<24);
} }
void putu32( uint8_t *buffer, uint32_t data ) void putu32(uint8_t *buffer, uint32_t data) {
{
buffer[0]=(uint8_t)(data&0xff); buffer[0]=(uint8_t)(data&0xff);
buffer[1]=(uint8_t)((data>>8)&0xff); buffer[1]=(uint8_t)((data>>8)&0xff);
buffer[2]=(uint8_t)((data>>16)&0xff); buffer[2]=(uint8_t)((data>>16)&0xff);
buffer[3]=(uint8_t)((data>>24)&0xff); buffer[3]=(uint8_t)((data>>24)&0xff);
} }
int main( int argc, char **argv ) int main(int argc, char **argv) {
{
FILE *bin; FILE *bin;
uint32_t data; uint32_t data;
size_t len; size_t len;
int count; int count;
uint8_t *buffer; uint8_t *buffer;
if ( argc < 2 ) if(argc<2) {
{
fprintf(stderr, "Usage: %s <binfile>\nThe original file will be modified!\n", argv[0]); fprintf(stderr, "Usage: %s <binfile>\nThe original file will be modified!\n", argv[0]);
return 1; return 1;
} }
if ( ( bin = fopen( argv[1], "rb" ) ) == NULL ) if((bin=fopen(argv[1], "rb"))==NULL) {
{
perror("could not open input file"); perror("could not open input file");
return 1; return 1;
} }
@ -43,29 +38,22 @@ int main( int argc, char **argv )
fseek(bin, 0, SEEK_END); fseek(bin, 0, SEEK_END);
len=ftell(bin); len=ftell(bin);
fseek(bin, 0, SEEK_SET); fseek(bin, 0, SEEK_SET);
if((buffer=malloc(len))==NULL) {
if ( ( buffer = malloc( len ) ) == NULL )
{
perror("could not reserve memory"); perror("could not reserve memory");
fclose(bin); fclose(bin);
return 1; return 1;
} }
fread(buffer, len, 1, bin); fread(buffer, len, 1, bin);
fclose(bin); fclose(bin);
data=0; data=0;
for(count=0; count<7; count++) {
for ( count = 0; count < 7; count++ )
{
data+=getu32(buffer+4*count); data+=getu32(buffer+4*count);
} }
printf("data=%x chksum=%x\n", data, ~data+1); printf("data=%x chksum=%x\n", data, ~data+1);
putu32(buffer+28,~data+1); putu32(buffer+28,~data+1);
if ( ( bin = fopen( argv[1], "wb" ) ) == NULL ) if((bin=fopen(argv[1], "wb"))==NULL) {
{
perror("could not open output file"); perror("could not open output file");
return 1; return 1;
} }

BIN
src/utils/lpcchksum.o Normal file

Binary file not shown.

View File

@ -5,46 +5,33 @@
#include "ff.h" #include "ff.h"
#include "xmodem.h" #include "xmodem.h"
void xmodem_rxfile( FIL *fil ) void xmodem_rxfile(FIL* fil) {
{ uint8_t rxbuf[XMODEM_BLKSIZE], sum=0/*, sender_sum*/;
uint8_t rxbuf[XMODEM_BLKSIZE], sum = 0, sender_sum; /* uint8_t blknum, blknum2;*/
uint8_t blknum, blknum2;
uint8_t count; uint8_t count;
uint32_t totalbytes = 0; uint32_t totalbytes = 0;
uint32_t totalwritten = 0; uint32_t totalwritten = 0;
UINT written; UINT written;
FRESULT res; FRESULT res;
uart_flush(); uart_flush();
do {
do
{
delay_ms(3000); delay_ms(3000);
uart_putc(ASC_NAK); uart_putc(ASC_NAK);
} } while (uart_getc() != ASC_SOH);
while ( uart_getc() != ASC_SOH ); do {
/*blknum=*/uart_getc();
do /*blknum2=*/uart_getc();
{ for(count=0; count<XMODEM_BLKSIZE; count++) {
blknum = uart_getc();
blknum2 = uart_getc();
for ( count = 0; count < XMODEM_BLKSIZE; count++ )
{
sum += rxbuf[count] = uart_getc(); sum += rxbuf[count] = uart_getc();
totalbytes++; totalbytes++;
} }
/*sender_sum =*/ uart_getc(); /*sender_sum =*/ uart_getc();
res=f_write(fil, rxbuf, XMODEM_BLKSIZE, &written); res=f_write(fil, rxbuf, XMODEM_BLKSIZE, &written);
totalwritten += written; totalwritten += written;
uart_putc(ASC_ACK); uart_putc(ASC_ACK);
} } while (uart_getc() != ASC_EOT);
while ( uart_getc() != ASC_EOT );
uart_putc(ASC_ACK); uart_putc(ASC_ACK);
uart_flush(); uart_flush();
sleep_ms(1000); sleep_ms(1000);
sender_sum = blknum + blknum2;
printf( "%x:%x:%x\n", blknum, blknum2, sender_sum );
printf("received %ld bytes, wrote %ld bytes. last res = %d\n", totalbytes, totalwritten, res); printf("received %ld bytes, wrote %ld bytes. last res = %d\n", totalbytes, totalwritten, res);
} }

View File

@ -72,66 +72,33 @@ wire [23:0] SRAM_SNES_ADDR;
assign IS_ROM = ((!SNES_ADDR[22] & SNES_ADDR[15]) assign IS_ROM = ((!SNES_ADDR[22] & SNES_ADDR[15])
|(SNES_ADDR[22])); |(SNES_ADDR[22]));
/* HiROM SRAM is 8K end at 0x8000 and is at bank 0x20 and 0xA0 */
assign IS_SAVERAM_HIROM = ((SNES_ADDR[22:21] == 2'b01)
& SNES_ADDR[15:13] == 3'b011)
/* LoROM: SRAM @ Bank 0x70-0x7d, 0xf0-0xfd Offset 0000-7fff
TODO: 0000-ffff for small ROMs? */
assign IS_SAVERAM_LOROM = SNES_ADDR[22:16] == 7'b111
( &SNES_ADDR[22:20]
& (SNES_ADDR[19:16] < 4'b1110)
& !SNES_ADDR[15] )
assign IS_SAVERAM_EXHIROM = (!SNES_ADDR[22]
& SNES_ADDR[21]
& &SNES_ADDR[14:13]
& !SNES_ADDR[15])
assign IS_SAVERAM_BSX = ( (SNES_ADDR[23:19] == 5'b00010)
& (SNES_ADDR[15:12] == 4'b0101)
)
assign IS_SAVERAM_STARTOCEAN = (!SNES_ADDR[22]
& SNES_ADDR[21]
& &SNES_ADDR[14:13]
& !SNES_ADDR[15])
assign IS_SAVERAM_MENU = (!SNES_ADDR[22]
& SNES_ADDR[21]
& &SNES_ADDR[14:13]
& !SNES_ADDR[15])
assign IS_SAVERAM = SAVERAM_MASK[0] assign IS_SAVERAM = SAVERAM_MASK[0]
&(featurebits[FEAT_ST0010] &(featurebits[FEAT_ST0010]
?((SNES_ADDR[22:19] == 4'b1101) ?((SNES_ADDR[22:19] == 4'b1101)
& &(~SNES_ADDR[15:12]) & &(~SNES_ADDR[15:12])
& SNES_ADDR[11]) & SNES_ADDR[11])
:( :((MAPPER == 3'b000
( MAPPER == 3'b000
|| MAPPER == 3'b010 || MAPPER == 3'b010
|| MAPPER == 3'b110 || MAPPER == 3'b110
|| MAPPER == 3'b111) || MAPPER == 3'b111)
? (!SNES_ADDR[22] ? (!SNES_ADDR[22]
& SNES_ADDR[21] & SNES_ADDR[21]
& &SNES_ADDR[14:13] & &SNES_ADDR[14:13]
& !SNES_ADDR[15]) & !SNES_ADDR[15]
/* LoROM: SRAM @ Bank 0x70-0x7d, 0xf0-0xfd Offset 0000-7fff )
TODO: 0000-ffff for small ROMs? */ /* LoROM: SRAM @ Bank 0x70-0x7d, 0xf0-0xfd
* Offset 0000-7fff for ROM >= 32 MBit, otherwise 0000-ffff */
:(MAPPER == 3'b001) :(MAPPER == 3'b001)
? (&SNES_ADDR[22:20] ? (&SNES_ADDR[22:20]
& (SNES_ADDR[19:16] < 4'b1110) & (SNES_ADDR[19:16] < 4'b1110)
& !SNES_ADDR[15] & (~SNES_ADDR[15] | ~ROM_MASK[21])
) )
/* BS-X: SRAM @ Bank 0x10-0x17 Offset 5000-5fff */ /* BS-X: SRAM @ Bank 0x10-0x17 Offset 5000-5fff */
:(MAPPER == 3'b011) :(MAPPER == 3'b011)
? ((SNES_ADDR[23:19] == 5'b00010) ? ((SNES_ADDR[23:19] == 5'b00010)
& (SNES_ADDR[15:12] == 4'b0101) & (SNES_ADDR[15:12] == 4'b0101)
) )
: 1'b0 : 1'b0));
)
);
/* BS-X has 4 MBits of extra RAM that can be mapped to various places */ /* BS-X has 4 MBits of extra RAM that can be mapped to various places */
@ -180,51 +147,37 @@ wire [23:0] BSX_ADDR = bsx_regs[2] ? {1'b0, SNES_ADDR[22:0]}
assign SRAM_SNES_ADDR = ((MAPPER == 3'b000) assign SRAM_SNES_ADDR = ((MAPPER == 3'b000)
?(IS_SAVERAM ?(IS_SAVERAM
? 24'h600000 + ((SNES_ADDR[14:0] - 15'h6000) ? 24'hE00000 + ({SNES_ADDR[20:16], SNES_ADDR[12:0]}
& SAVERAM_MASK) & SAVERAM_MASK)
: ({1'b0, SNES_ADDR[22:0]} & ROM_MASK)) : ({1'b0, SNES_ADDR[22:0]} & ROM_MASK))
:(MAPPER == 3'b001) :(MAPPER == 3'b001)
?(IS_SAVERAM ?(IS_SAVERAM
? 24'h600000 + (SNES_ADDR[14:0] & SAVERAM_MASK) ? 24'hE00000 + ({SNES_ADDR[20:16], SNES_ADDR[14:0]}
& SAVERAM_MASK)
: ({2'b00, SNES_ADDR[22:16], SNES_ADDR[14:0]} : ({2'b00, SNES_ADDR[22:16], SNES_ADDR[14:0]}
& ROM_MASK)) & ROM_MASK))
:(MAPPER == 3'b010) :(MAPPER == 3'b010)
?(IS_SAVERAM ?(IS_SAVERAM
? 24'h600000 + ((SNES_ADDR[14:0] - 15'h6000) ? 24'hE00000 + ({SNES_ADDR[20:16], SNES_ADDR[12:0]}
& SAVERAM_MASK) & SAVERAM_MASK)
: ({1'b0, !SNES_ADDR[23], SNES_ADDR[21:0]} : ({1'b0, !SNES_ADDR[23], SNES_ADDR[21:0]}
& ROM_MASK)) & ROM_MASK))
:(MAPPER == 3'b011) :(MAPPER == 3'b011)
?( IS_SAVERAM ?( IS_SAVERAM
? 24'h600000 + {SNES_ADDR[18:16], SNES_ADDR[11:0]} ? 24'hE00000 + {SNES_ADDR[18:16], SNES_ADDR[11:0]}
: IS_WRITABLE : BSX_IS_CARTROM
? (24'h400000 + (SNES_ADDR & 24'h07FFFF)) ? (24'h800000 + ({SNES_ADDR[22:16], SNES_ADDR[14:0]} & 24'h0fffff))
: BSX_IS_PSRAM
? (24'h400000 + (BSX_ADDR & 24'h07FFFF))
: bs_page_enable : bs_page_enable
? (24'h900000 + {bs_page,bs_page_offset}) ? (24'h900000 + {bs_page,bs_page_offset})
:((bsx_regs[7] && SNES_ADDR[23:21] == 3'b000) : (BSX_ADDR & 24'h0fffff)
|(bsx_regs[8] && SNES_ADDR[23:21] == 3'b100))
?(24'h800000
+ ({1'b0, SNES_ADDR[23:16], SNES_ADDR[14:0]}
& 24'h0FFFFF)
)
:((bsx_regs[1]
? 24'h400000
: 24'h000000
)
+ bsx_regs[2]
?({2'b00, SNES_ADDR[21:0]}
& (ROM_MASK /* >> bsx_regs[1] */)
)
:({1'b0, SNES_ADDR[23:16], SNES_ADDR[14:0]}
& (ROM_MASK /* >> bsx_regs[1] */)
)
)
) )
:(MAPPER == 3'b110) :(MAPPER == 3'b110)
?(IS_SAVERAM ?(IS_SAVERAM
? 24'h600000 + ((SNES_ADDR[14:0] - 15'h6000) ? 24'hE00000 + ((SNES_ADDR[14:0] - 15'h6000)
& SAVERAM_MASK) & SAVERAM_MASK)
:(SNES_ADDR[15] :(SNES_ADDR[15]
?({1'b0, SNES_ADDR[23:16], SNES_ADDR[14:0]}) ?({1'b0, SNES_ADDR[23:16], SNES_ADDR[14:0]})
@ -237,7 +190,7 @@ assign SRAM_SNES_ADDR = ((MAPPER == 3'b000)
) )
:(MAPPER == 3'b111) :(MAPPER == 3'b111)
?(IS_SAVERAM ?(IS_SAVERAM
? 24'h7F0000 + ((SNES_ADDR[14:0] - 15'h6000) ? 24'hFF0000 + ((SNES_ADDR[14:0] - 15'h6000)
& SAVERAM_MASK) & SAVERAM_MASK)
: (({1'b0, SNES_ADDR[22:0]} & ROM_MASK) : (({1'b0, SNES_ADDR[22:0]} & ROM_MASK)
+ 24'hC00000) + 24'hC00000)

View File

@ -534,12 +534,8 @@ initial ROM_SAr = 1'b1;
//wire ROM_SA = SNES_FAKE_CLK | ((STATE == ST_IDLE) ^ (~RQ_MCU_RDYr & SNES_cycle_end)); //wire ROM_SA = SNES_FAKE_CLK | ((STATE == ST_IDLE) ^ (~RQ_MCU_RDYr & SNES_cycle_end));
wire ROM_SA = ROM_SAr; wire ROM_SA = ROM_SAr;
//assign ROM_ADDR = (SD_DMA_TO_ROM) ? MCU_ADDR[23:1] : (ROM_SA) ? MAPPED_SNES_ADDR[23:1] : ROM_ADDRr[23:1]; assign ROM_ADDR = (SD_DMA_TO_ROM) ? MCU_ADDR[23:1] : (ROM_SA) ? MAPPED_SNES_ADDR[23:1] : ROM_ADDRr[23:1];
//assign ROM_ADDR0 = (SD_DMA_TO_ROM) ? MCU_ADDR[0] : (ROM_SA) ? MAPPED_SNES_ADDR[0] : ROM_ADDRr[0]; assign ROM_ADDR0 = (SD_DMA_TO_ROM) ? MCU_ADDR[0] : (ROM_SA) ? MAPPED_SNES_ADDR[0] : ROM_ADDRr[0];
//WARNING DUE TO BAD SOLDER WE LOST HALF OF THE PSRAM!!!
assign ROM_ADDR = (SD_DMA_TO_ROM) ? MCU_ADDR[22:0] : (ROM_SA) ? MAPPED_SNES_ADDR[22:0] : ROM_ADDRr[22:0];
assign ROM_ADDR0 = 1'b0; //(SD_DMA_TO_ROM) ? MCU_ADDR[0] : (ROM_SA) ? MAPPED_SNES_ADDR[0] : ROM_ADDRr[0];
reg ROM_WEr; reg ROM_WEr;
initial ROM_WEr = 1'b1; initial ROM_WEr = 1'b1;
@ -655,7 +651,7 @@ always @(posedge CLK2) begin
else STATE <= ST_MCU_RD_WAIT; else STATE <= ST_MCU_RD_WAIT;
end end
ST_MCU_RD_END: begin ST_MCU_RD_END: begin
MCU_DINr <= ROM_DATA[7:0] | ROM_DATA[15:8]; /*ROM_ADDRr[0] ? ROM_DATA[7:0] : ROM_DATA[15:8];*/ MCU_DINr <= ROM_ADDRr[0] ? ROM_DATA[7:0] : ROM_DATA[15:8];
STATE <= ST_IDLE; STATE <= ST_IDLE;
end end
@ -711,25 +707,18 @@ always @(posedge CLK2) begin
MCU_WRITE_1<= MCU_WRITE; MCU_WRITE_1<= MCU_WRITE;
end end
/*
assign ROM_DATA[7:0] = ROM_ADDR0 assign ROM_DATA[7:0] = ROM_ADDR0
?(SD_DMA_TO_ROM ? (!MCU_WRITE_1 ? MCU_DOUT : 8'bZ) ?(SD_DMA_TO_ROM ? (!MCU_WRITE_1 ? MCU_DOUT : 8'bZ)
//: ((~SNES_WRITE & (IS_WRITABLE | IS_FLASHWR)) ? SNES_DATA /*: ((~SNES_WRITE & (IS_WRITABLE | IS_FLASHWR)) ? SNES_DATA */
: (ROM_DOUT_ENr ? ROM_DOUTr : 8'bZ) //) : (ROM_DOUT_ENr ? ROM_DOUTr : 8'bZ) //)
) )
:8'bZ; :8'bZ;
assign ROM_DATA[15:8] = ROM_ADDR0 ? 8'bZ assign ROM_DATA[15:8] = ROM_ADDR0 ? 8'bZ
:(SD_DMA_TO_ROM ? (!MCU_WRITE_1 ? MCU_DOUT : 8'bZ) :(SD_DMA_TO_ROM ? (!MCU_WRITE_1 ? MCU_DOUT : 8'bZ)
//: ((~SNES_WRITE & (IS_WRITABLE | IS_FLASHWR)) ? SNES_DATA /*: ((~SNES_WRITE & (IS_WRITABLE | IS_FLASHWR)) ? SNES_DATA */
: (ROM_DOUT_ENr ? ROM_DOUTr : 8'bZ) //) : (ROM_DOUT_ENr ? ROM_DOUTr : 8'bZ) //)
); );
*/
assign ROM_DATA[7:0] = SD_DMA_TO_ROM ? (!MCU_WRITE_1 ? MCU_DOUT : 8'bZ)
: (ROM_DOUT_ENr ? ROM_DOUTr : 8'bZ);
assign ROM_DATA[15:8] = SD_DMA_TO_ROM ? (!MCU_WRITE_1 ? MCU_DOUT : 8'bZ)
: (ROM_DOUT_ENr ? ROM_DOUTr : 8'bZ);
assign ROM_WE = SD_DMA_TO_ROM assign ROM_WE = SD_DMA_TO_ROM
?MCU_WRITE ?MCU_WRITE
@ -740,8 +729,8 @@ assign ROM_OE = 1'b0;
assign ROM_CE = 1'b0; assign ROM_CE = 1'b0;
assign ROM_BHE = 1'b0; ///*(~SD_DMA_TO_ROM & ~ROM_WE & ~ROM_SA) ?*/ ROM_ADDR0 /*: 1'b0*/; assign ROM_BHE = /*(~SD_DMA_TO_ROM & ~ROM_WE & ~ROM_SA) ?*/ ROM_ADDR0 /*: 1'b0*/;
assign ROM_BLE = 1'b0; ///*(~SD_DMA_TO_ROM & ~ROM_WE & ~ROM_SA) ?*/ !ROM_ADDR0 /*: 1'b0*/; assign ROM_BLE = /*(~SD_DMA_TO_ROM & ~ROM_WE & ~ROM_SA) ?*/ !ROM_ADDR0 /*: 1'b0*/;
assign SNES_DATABUS_OE = (dspx_enable | dspx_dp_enable) ? 1'b0 : assign SNES_DATABUS_OE = (dspx_enable | dspx_dp_enable) ? 1'b0 :
msu_enable ? 1'b0 : msu_enable ? 1'b0 :
@ -762,7 +751,7 @@ assign SNES_DATABUS_DIR = (!SNES_READr[0] | (!SNES_PARD & (r213f_enable | snescm
assign SNES_IRQ = 1'b0; assign SNES_IRQ = 1'b0;
assign p113_out = 1'b1; assign p113_out = 1'b0;
/* /*
wire [35:0] CONTROL0; wire [35:0] CONTROL0;

View File

@ -12,7 +12,7 @@
<!-- Copyright (c) 1995-2012 Xilinx, Inc. All rights reserved. --> <!-- Copyright (c) 1995-2012 Xilinx, Inc. All rights reserved. -->
</header> </header>
<version xil_pn:ise_version="14.2" xil_pn:schema_version="2"/> <version xil_pn:ise_version="14.1" xil_pn:schema_version="2"/>
<files> <files>
<file xil_pn:name="address.v" xil_pn:type="FILE_VERILOG"> <file xil_pn:name="address.v" xil_pn:type="FILE_VERILOG">

View File

@ -1,7 +1,7 @@
############################################################## ##############################################################
# #
# Xilinx Core Generator version 13.4 # Xilinx Core Generator version 13.2
# Date: Fri Aug 17 17:03:15 2012 # Date: Fri Dec 9 20:36:25 2011
# #
############################################################## ##############################################################
# #
@ -99,7 +99,7 @@ CSET write_width_a=8
CSET write_width_b=8 CSET write_width_b=8
# END Parameters # END Parameters
# BEGIN Extra information # BEGIN Extra information
MISC pkg_timestamp=2011-03-11T08:24:14Z MISC pkg_timestamp=2011-03-11T08:24:14.000Z
# END Extra information # END Extra information
GENERATE GENERATE
# CRC: 370f2518 # CRC: 213d12c4

View File

@ -12,7 +12,7 @@
<!-- Copyright (c) 1995-2011 Xilinx, Inc. All rights reserved. --> <!-- Copyright (c) 1995-2011 Xilinx, Inc. All rights reserved. -->
</header> </header>
<version xil_pn:ise_version="13.4" xil_pn:schema_version="2"/> <version xil_pn:ise_version="13.2" xil_pn:schema_version="2"/>
<files> <files>
<file xil_pn:name="PA.ngc" xil_pn:type="FILE_NGC"> <file xil_pn:name="PA.ngc" xil_pn:type="FILE_NGC">

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