10 Commits

136 changed files with 11598 additions and 10211 deletions

View File

@@ -38,59 +38,3 @@ v0.1.3
* Some FPGA configuration error detection (mainly useful for hardware diag) * Some FPGA configuration error detection (mainly useful for hardware diag)
* Fixes: * Fixes:
- FPGA-side SD clock pullup (increases reliability with some cards) - FPGA-side SD clock pullup (increases reliability with some cards)
v0.1.4
======
* SPC Player (contributed by necronomfive/blargg)
* System Information screen now shows CPU/PPU revision (contributed by necronomfive)
* Satellaview: basic data transmission packet support (makes some more games boot, thanks to LuigiBlood for assistance and sample data packets)
* Number of supported files increased to 50000 per card / 16380 per directory
* Slight speedup of menu text rendering
* Reduce load time of menu
* Adjust Cx4 timing to be more faithful
(Mega Man now defeats the boss in attract mode in Mega Man X2)
* adapt ROM mirroring size to file size if header information is invalid
(fixes Super Noah's Ark 3D, possibly others)
* MSU1 interface changes suggested by byuu:
- Data offset 0 and audio track 0 are automatically requested on reset.
This causes the busy flags to become 0 shortly after reset/startup.
- $2000 bit 3 is now "audio error", becomes valid after "audio busy" -> 0
set when an error occurred while preparing playback of the requested audio track
* write LED stays on when SRAM content changes constantly
* Fixes:
- fix empty save files on FAT16 / incorrect free cluster count on FAT32
- correct directory sorting (force parent directory at top of list)
- fix text corruption when entering a directory with a scrollable name
- fix files/dirs count in system information
- make 'sd2snes' directory hiding case-insensitive
- improve DAC I²S timing
- fix occasional palette corruption in menu
- fix SD clock glitch on ROM loading (occasional glitches/crashes)
- fix memory write timing on ROM loading (occasional glitches/crashes)
- fix SPI timing (ROMs not loading; System Information not working)
- properly synchronize SNES control signals (occasional glitches/crashes)
- fix floating IRQ output (occasional glitches/slowdowns)
v0.1.4a (bugfix release)
========================
* Fix DMA initialization in the menu (could cause sprite corruption in some games)
v0.1.5
======
* Sort directories by entire file name instead of first 20 characters only
* Correctly map SRAM larger than 8192 bytes (HiROM) / 32768 bytes (LoROM)
(fixes Dezaemon, Ongaku Tsukuuru - Kanadeeru)
* SPC player: fix soft fade-in (first note cut off) on S-APU consoles
(1CHIP / some Jr.)
* More accurate BS-X memory map
* Ignore input from non-standard controllers (Super Scope, Mouse etc.)
* Fixes:
- minor memory access timing tweaks
(should help with occasional glitches on some systems)

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
update=Sat 25 Feb 2012 11:51:50 PM CET update=ven. 20 avril 2012 18:26:30 CEST
version=1 version=1
last_client=pcbnew last_client=pcbnew
[general] [general]
@@ -87,6 +87,7 @@ PadDrlX=0
PadDimH=197 PadDimH=197
PadDimV=276 PadDimV=276
BoardThickness=630 BoardThickness=630
SgPcb45=1
TxtPcbV=800 TxtPcbV=800
TxtPcbH=600 TxtPcbH=600
TxtModV=600 TxtModV=600

View File

@@ -1,4 +1,4 @@
OBJS = header.ips reset.o65 main.o65 font.o65 palette.o65 data.o65 const.o65 logo.o65 logospr.o65 text.o65 dma.o65 filesel.o65 pad.o65 time.o65 mainmenu.o65 sysinfo.o65 spc700.o65 spcplay.o65 # gfx.o65 # vars.o65 OBJS = header.ips reset.o65 main.o65 font.o65 palette.o65 data.o65 const.o65 logo.o65 logospr.o65 text.o65 dma.o65 menu.o65 pad.o65 time.o65 mainmenu.o65 sysinfo.o65 # 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

@@ -168,24 +168,4 @@ text_mm_vmode_game .byt "Game video mode", 0
text_mm_sysinfo .byt "System Information", 0 text_mm_sysinfo .byt "System Information", 0
text_statusbar_keys .byt "A:Select B:Back X:Menu", 0 text_statusbar_keys .byt "A:Select B:Back X:Menu", 0
text_last .byt "Run previous ROM: Press Start again to confirm", 0 text_last .byt "Run previous ROM: Press Start again to confirm", 0
text_system .byt "CPU Rev.: x PPU1 Rev.: y PPU2 Rev.: z",0
text_spcplay .byt "SPC Music Player", 0
spcplay_win_x .byt 15
spcplay_win_y .byt 15
spcplay_win_w .byt 33
spcplay_win_h .byt 5
text_spcload .byt "Loading SPC data to SPC700...", 0
text_spcstarta .byt "**** Now playing SPC tune ****", 0
text_spcstartb .byt "Name: ",0
text_spcstartc .byt "Song: ",0
text_spcstartd .byt "Artist:",0
spcstart_win_x .byt 10
spcstart_win_y .byt 13
spcstart_win_w .byt 44
spcstart_win_h .byt 9
text_spcid .byt "SNES-SPC700"

View File

@@ -16,7 +16,7 @@ dirend_onscreen .byt 0
dirlog_idx .byt 0,0,0 ; long ptr dirlog_idx .byt 0,0,0 ; long ptr
direntry_fits_idx direntry_fits_idx
.byt 0,0 .byt 0,0
longptr .byt 0,0,0 ; general purpose long ptr
;----------parameters for text output---------- ;----------parameters for text output----------
print_x .byt 0 ;x coordinate print_x .byt 0 ;x coordinate
.byt 0 .byt 0
@@ -26,8 +26,8 @@ print_src .word 0 ;source data address
print_bank .byt 0 ;source data bank print_bank .byt 0 ;source data bank
print_pal .word 0 ;palette number for text output print_pal .word 0 ;palette number for text output
print_temp .word 0 ;work variable print_temp .word 0 ;work variable
print_ptr .byt 0,0,0 ;read pointer print_count .byt 0 ;how many characters may be printed?
print_count .word 0 ;how many characters may be printed? print_count_tmp .byt 0 ;work variable
print_done .word 0 ;how many characters were printed? print_done .word 0 ;how many characters were printed?
print_over .byt 0 ;was the string printed incompletely? print_over .byt 0 ;was the string printed incompletely?
;----------parameters for dma---------- ;----------parameters for dma----------
@@ -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
filesel_state .byt 0 ; menu state (0=file select) menu_state .byt 0 ; menu state (0=file select)
filesel_dirty .byt 0 ; menu dirty (e.g. after state change or when redraw is needed) menu_dirty .byt 0 ; menu dirty (e.g. after state change or when redraw is needed)
filesel_sel .word 0 ; selected item # menu_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,8 +96,6 @@ 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
@@ -186,17 +184,4 @@ direntry_xscroll
direntry_xscroll_wait direntry_xscroll_wait
.word 0 .word 0
infloop .byt 0,0 ; to be filled w/ 80 FE infloop .byt 0,0 ; to be filled w/ 80 FE
tgt_bright
.byt 0
cur_bright
.byt 0
;------------------------
saved_sp
.word 0
warm_signature
.word 0
snes_system_config
.word 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
wram_fadeloop .byt 0 wram_fadeloop .byt 0

View File

@@ -1,4 +1,21 @@
dma0:
rep #$10 : .xl
sep #$20 : .as
lda dma_mode
sta $4300
lda dma_b_reg
sta $4301
lda dma_a_bank
ldx dma_a_addr
stx $4302
sta $4304
ldx dma_len
stx $4305
lda #$01
sta $420b
rts
setup_hdma: setup_hdma:
sep #$20 : .as sep #$20 : .as
rep #$10 : .xl rep #$10 : .xl
@@ -50,11 +67,8 @@ setup_hdma:
sty $4352 sty $4352
sta $4354 sta $4354
lda #$3a ; lda #$06
sta $420c ;enable HDMA ch. 1+3+4+5 ; sta $420c ;enable HDMA ch. 1+2
jsr waitblank
lda #$3e
sta $420c ;enable HDMA ch. 2 too
lda #$81 ;VBlank NMI + Auto Joypad Read lda #$81 ;VBlank NMI + Auto Joypad Read
sta $4200 ;enable V-BLANK NMI sta $4200 ;enable V-BLANK NMI
rts rts

View File

@@ -1,22 +1,13 @@
#define hash #
#define f(x) x
#define imm(a) f(hash)a
#define DMA0(mode, len, a_bank, a_addr, b_reg)\ #define DMA0(mode, len, a_bank, a_addr, b_reg)\
php \ lda mode \
: sep imm($20) : .as \ : sta dma_mode \
: rep imm($10) : .xl \
: lda mode \
: sta $4300 \
: ldx a_addr \ : ldx a_addr \
: lda a_bank \ : lda a_bank \
: stx $4302 \ : stx dma_a_addr \
: sta $4304 \ : sta dma_a_bank \
: ldx len \ : ldx len \
: stx $4305 \ : stx dma_len \
: lda b_reg \ : lda b_reg \
: sta $4301 \ : sta dma_b_reg \
: lda imm($01) \ : jsr dma0
: sta $420b \
: plp

View File

@@ -4,179 +4,78 @@
GAME_MAIN: GAME_MAIN:
sep #$20 : .as sep #$20 : .as
lda #$00 lda #$00
sta @MCU_CMD ; clear MCU command register sta @AVR_CMD
rep #$20 : .al rep #$20 : .al
lda #$0000 lda #$0000
sta @MCU_PARAM ; clear MCU command parameters sta @AVR_PARAM
sta @MCU_PARAM+2 sta @AVR_PARAM+2
sep #$20 : .as sep #$20 : .as
stz $4200 ; inhibit VBlank NMI stz $4200 ; inhibit VBlank NMI
rep #$20 : .al jsr killdma
lda @warm_signature ; Was CMD_RESET issued before reset?
cmp #$fa50 ; If yes, then perform warm boot procedure
bne coldboot
lda #$0000
sta @warm_signature
lda @saved_sp ; Restore previous stack pointer
tcs
sep #$20 : .as
; jsr killdma ; The following initialization processes must not touch memory
jsr waitblank ; structures used by the file selector !
jsr snes_init
cli
lda #$01
sta $420d ; fast cpu
jsr setup_gfx
jsr colortest
jsr video_init
jsr setup_hdma
lda #$0f
sta cur_bright
sta tgt_bright
sta $2100
jmp @set_bank ; Set bios bank, just to be sure
set_bank:
plp ; Restore processor state
rts ; Jump to the routine which called the sub-routine issuing CMD_RESET
coldboot: ; Regular, cold-start init
sep #$20 : .as
; 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 filesel_init
jsr video_init
jsr setup_hdma jsr setup_hdma
jsr screen_on jsr menu_init
jsr tests
sep #$20 : .as sep #$20 : .as
lda @RTC_STATUS lda @RTC_STATUS
beq + beq +
jsl time_init jsl time_init
+ +
jsr fileselloop jsr menuloop
cli cli
stz $4200 stz $4200
jmp @infloop ;infinite loop in WRAM jmp @infloop ;infinite loop in WRAM
killdma: killdma:
stz $4300 stz $420b
stz $4301 stz $420c
stz $4302
stz $4303
stz $4304
stz $4305
stz $4306
stz $4307
stz $4308
stz $4309
stz $430a
stz $430b
stz $4310 stz $4310
stz $4311 stz $4311
stz $4312 stz $4312
stz $4313 stz $4313
stz $4314 stz $4314
stz $4315
stz $4316
stz $4317
stz $4318
stz $4319
stz $431a
stz $431b
stz $4320 stz $4320
stz $4321 stz $4321
stz $4322 stz $4322
stz $4323 stz $4323
stz $4324 stz $4324
stz $4325
stz $4326
stz $4327
stz $4328
stz $4329
stz $432a
stz $432b
stz $4330 stz $4330
stz $4331 stz $4331
stz $4332 stz $4332
stz $4333 stz $4333
stz $4334 stz $4334
stz $4335
stz $4336
stz $4337
stz $4338
stz $4339
stz $433a
stz $433b
stz $4340 stz $4340
stz $4341 stz $4341
stz $4342 stz $4342
stz $4343 stz $4343
stz $4344 stz $4344
stz $4345
stz $4346
stz $4347
stz $4348
stz $4349
stz $434a
stz $434b
stz $4350 stz $4350
stz $4351 stz $4351
stz $4352 stz $4352
stz $4353 stz $4353
stz $4354 stz $4354
stz $4355
stz $4356
stz $4357
stz $4358
stz $4359
stz $435a
stz $435b
stz $4360 stz $4360
stz $4361 stz $4361
stz $4362 stz $4362
stz $4363 stz $4363
stz $4364 stz $4364
stz $4365
stz $4366
stz $4367
stz $4368
stz $4369
stz $436a
stz $436b
stz $4370
stz $4371
stz $4372
stz $4373
stz $4374
stz $4375
stz $4376
stz $4377
stz $4378
stz $4379
stz $437a
stz $437b
stz $420b
stz $420c
rts rts
waitblank: waitblank:
php
sep #$30 : .as : .xs
- lda $4212 - lda $4212
and #$80 and #$80
bne - bne -
- lda $4212 - lda $4212
and #$80 and #$80
beq - beq -
plp
rts rts
colortest: colortest:
@@ -192,11 +91,11 @@ setup_gfx:
stz $420b stz $420b
stz $420c stz $420c
;clear tilemap buffers ;clear tilemap buffers
ldx #$8000 ldx #$0000
stx $2181 stx $2181
lda #$00 lda #$01
sta $2183 sta $2183
DMA0(#$08, #$8000, #^zero, #!zero, #$80) DMA0(#$08, #0, #^zero, #!zero, #$80)
;generate fonts ;generate fonts
jsr genfonts jsr genfonts
@@ -214,7 +113,7 @@ setup_gfx:
;clear OAM tables ;clear OAM tables
ldx #$0000 ldx #$0000
stx $2102 stx $2102
DMA0(#$08, #$220, #^zero, #!zero, #$04) DMA0(#$08, #$544, #^zero, #!zero, #$04)
;copy logo tiles ;copy logo tiles
ldx #$2000 ldx #$2000
@@ -247,7 +146,6 @@ setup_gfx:
;set palette ;set palette
stz $2121 stz $2121
DMA0(#$00, #$200, #^palette, #!palette, #$22) DMA0(#$00, #$200, #^palette, #!palette, #$22)
stz $2121
;copy hdma tables so we can work "without" the cartridge ;copy hdma tables so we can work "without" the cartridge
;palette ;palette
@@ -297,10 +195,10 @@ setup_gfx:
DMA0(#$00, #$6C, #^fadeloop, #!fadeloop, #$80); DMA0(#$00, #$6C, #^fadeloop, #!fadeloop, #$80);
rts rts
video_init: tests:
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 :D
sta $2105 sta $2105
lda #$58 ;Tilemap addr 0xB000 lda #$58 ;Tilemap addr 0xB000
ora #$02 ;SC size 32x64 ora #$02 ;SC size 32x64
@@ -326,17 +224,11 @@ video_init:
lda #$1f lda #$1f
sta $212e sta $212e
sta $212f sta $212f
; stz $2121 stz $2121
lda #8
sta bar_yl
stz cur_bright
stz tgt_bright
rts
screen_on:
stz $2100 ;screen on, 0% brightness
lda #$0f lda #$0f
sta tgt_bright sta $2100 ;screen on, full brightness
lda #9
sta bar_yl
rts rts
snes_init: snes_init:
@@ -356,7 +248,6 @@ snes_init:
stz $420a ; stz $420a ;
stz $420b ; stz $420b ;
stz $420c ; stz $420c ;
stz $420d ;
lda #$8f lda #$8f
sta $2100 ;INIDISP: force blank sta $2100 ;INIDISP: force blank
lda #$03 ; 8x8+16x16; name=0; base=3 lda #$03 ; 8x8+16x16; name=0; base=3
@@ -448,7 +339,7 @@ snes_init:
fadeloop: fadeloop:
sep #$30 : .as : .xs sep #$30 : .as : .xs
ldx cur_bright ldx #$0f
and #$00 and #$00
pha pha
plb plb

View File

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

View File

@@ -6,24 +6,19 @@
/* These must be defined as constants, because they're used /* These must be defined as constants, because they're used
* in calculation that is sent to PPU as parameters */ * in calculation that is sent to PPU as parameters */
#define APUIO0 $2140
#define APUIO1 $2141
#define APUIO2 $2142
#define APUIO3 $2143
#define BG1_TILE_BASE $5800 #define BG1_TILE_BASE $5800
#define BG2_TILE_BASE $5000 #define BG2_TILE_BASE $5000
#define OAM_TILE_BASE $6000 #define OAM_TILE_BASE $6000
#define BG1_TILE_BUF $7EB000 #define BG1_TILE_BUF $7FB000
#define BG2_TILE_BUF $7EA000 #define BG2_TILE_BUF $7FA000
#define BG1_TILE_BAK $7E9000 #define BG1_TILE_BAK $7F9000
#define BG2_TILE_BAK $7E8000 #define BG2_TILE_BAK $7F8000
#define MCU_CMD $307000 #define AVR_CMD $307000
#define MCU_PARAM $307004 #define AVR_PARAM $307004
#define RTC_STATUS $307100 #define RTC_STATUS $307100
#define LAST_STATUS $307101 #define LAST_STATUS $307101
#define SYSINFO_BLK $307200 #define SYSINFO_BLK $307200
@@ -32,9 +27,3 @@
#define ROOT_DIR $C10000 #define ROOT_DIR $C10000
#define CMD_SYSINFO $03 #define CMD_SYSINFO $03
#define CMD_LOADSPC $05
#define CMD_RESET $06
#define SPC_DATA $FD0000
#define SPC_HEADER $FE0000
#define SPC_DSP_REGS $FE0100

View File

@@ -1,7 +1,7 @@
#include "memmap.i65" #include "memmap.i65"
#include "dma.i65" #include "dma.i65"
filesel_init: menu_init:
sep #$20 : .as sep #$20 : .as
rep #$10 : .xl rep #$10 : .xl
lda #^ROOT_DIR lda #^ROOT_DIR
@@ -10,7 +10,7 @@ filesel_init:
stx dirptr_addr stx dirptr_addr
sta dirstart_bank sta dirstart_bank
stx dirstart_addr stx dirstart_addr
stz filesel_state stz menu_state
stz dirend_onscreen stz dirend_onscreen
lda #$02 lda #$02
sta cursor_x sta cursor_x
@@ -22,11 +22,11 @@ filesel_init:
sta bar_wl sta bar_wl
ldx #$0000 ldx #$0000
stx dirptr_idx stx dirptr_idx
stx filesel_sel stx menu_sel
stx direntry_xscroll stx direntry_xscroll
stx direntry_xscroll_state stx direntry_xscroll_state
lda #$01 lda #$01
sta filesel_dirty sta menu_dirty
rep #$20 : .al rep #$20 : .al
lda #!dirlog lda #!dirlog
sta dirlog_idx sta dirlog_idx
@@ -35,39 +35,40 @@ filesel_init:
sta dirlog_idx+2 sta dirlog_idx+2
rts rts
fileselloop: menuloop:
fileselloop_s1 menuloop_s1
sep #$20 : .as sep #$20 : .as
rep #$10 : .xl rep #$10 : .xl
lda isr_done lda isr_done
lsr lsr
bcc fileselloop_s1 bcc menuloop_s1
stz isr_done stz isr_done
jsr printtime jsr printtime
jsr filesel_updates ;update stuff, check keys etc jsr menu_updates ;update stuff, check keys etc
lda filesel_dirty ;is there ANY reason to redraw the menu? lda menu_dirty ;is there ANY reason to redraw the menu?
cmp #$01 cmp #$01
beq fileselloop_redraw ;then do beq menuloop_redraw ;then do
jsr scroll_direntry jsr scroll_direntry
bra fileselloop_s1 bra menuloop_s1
fileselloop_redraw menuloop_redraw
stz filesel_dirty stz menu_dirty
jsr filesel_statusbar jsr menu_statusbar
jsr filesel_redraw jsr menu_redraw
jsr filesel_cleanup ;update phase 2 jsr menu_cleanup ;update phase 2
bra fileselloop_s1 bra menuloop_s1
rts rts
filesel_cleanup: menu_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 filesel_cleanup_out ; beq menu_cleanup_out ;
lda dirend_idx lda dirend_idx
lsr lsr
lsr lsr
pha pha
filesel_cleanup_loop ;pad rest of screen with empty lines menu_cleanup_loop ;pad rest of screen with empty lines
cmp listdisp ;end of screen reached? cmp listdisp ;end of screen reached?
beq + ;then leave beq + ;then leave
pha pha
@@ -86,24 +87,24 @@ filesel_cleanup_loop ;pad rest of screen with empty lines
jsr hiprint jsr hiprint
pla pla
inc inc
bra filesel_cleanup_loop bra menu_cleanup_loop
+ +
pla pla
cmp filesel_sel cmp menu_sel
beq filesel_cleanup_out beq menu_cleanup_out
bpl filesel_cleanup_out bpl menu_cleanup_out
sta filesel_sel sta menu_sel
filesel_cleanup_out menu_cleanup_out
rts rts
filesel_updates: menu_updates:
;update selection, scroll etc ;update selection, scroll etc
lda filesel_sel lda menu_sel
asl asl
asl asl
sta dirptr_idx sta dirptr_idx
lda filesel_sel lda menu_sel
clc clc
adc #$08 adc #$08
sta bar_yl sta bar_yl
@@ -140,47 +141,47 @@ filesel_updates:
lda #$40 lda #$40
and pad1trig and pad1trig
bne key_x bne key_x
bra fileselupd_out bra menuupd_out
key_down key_down
jsr filesel_key_down jsr menu_key_down
bra fileselupd_out bra menuupd_out
key_up key_up
jsr filesel_key_up jsr menu_key_up
bra fileselupd_out bra menuupd_out
key_right key_right
jsr filesel_key_right jsr menu_key_right
bra fileselupd_out bra menuupd_out
key_left key_left
jsr filesel_key_left jsr menu_key_left
bra fileselupd_out bra menuupd_out
key_b key_b
jsr filesel_key_b jsr menu_key_b
bra fileselupd_out bra menuupd_out
key_a key_a
jsr filesel_key_a jsr menu_key_a
bra fileselupd_out bra menuupd_out
key_x key_x
jsr filesel_key_x jsr menu_key_x
bra fileselupd_out bra menuupd_out
key_select key_select
jsr filesel_key_select jsr menu_key_select
bra fileselupd_out bra menuupd_out
key_start key_start
jsr filesel_key_start jsr menu_key_start
bra fileselupd_out bra menuupd_out
fileselupd_out menuupd_out
lda #$09 lda #$09
sta cursor_y sta cursor_y
rts rts
filesel_redraw: menu_redraw:
lda filesel_state lda menu_state
beq redraw_filelist beq redraw_filelist
; cmp 1 ; cmp 1
; beq redraw_main ; beq redraw_main
filesel_redraw_out menu_redraw_out
rts rts
redraw_filelist redraw_filelist
@@ -236,7 +237,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 filesel_redraw_out brl menu_redraw_out
print_direntry: print_direntry:
lda cursor_y lda cursor_y
@@ -271,10 +272,6 @@ dirent_is_file
lda #$0000 lda #$0000
bra dirent_type_cont bra dirent_type_cont
+ +
cmp #$0003 ;SPC -> palette 2
bne +
lda #$0002
bra dirent_type_cont
cmp #$0004 ;IPS -> palette 2 (green) cmp #$0004 ;IPS -> palette 2 (green)
bne + bne +
lda #$0002 lda #$0002
@@ -355,14 +352,14 @@ dirent_type_cont_2
rts rts
filesel_key_down: menu_key_down:
jsr scroll_direntry_clean jsr scroll_direntry_clean
lda listdisp lda listdisp
dec dec
cmp filesel_sel cmp menu_sel
bne down_noscroll bne down_noscroll
lda #$01 lda #$01
sta filesel_dirty sta menu_dirty
lda dirend_onscreen lda dirend_onscreen
bne down_out bne down_out
rep #$20 : .al rep #$20 : .al
@@ -380,21 +377,21 @@ down_noscroll
lda dirend_idx lda dirend_idx
lsr lsr
lsr lsr
cmp filesel_sel cmp menu_sel
beq fileselupd_lastcursor beq menuupd_lastcursor
bcc fileselupd_lastcursor bcc menuupd_lastcursor
+ lda filesel_sel + lda menu_sel
inc inc
sta filesel_sel sta menu_sel
down_out down_out
rts rts
filesel_key_up: menu_key_up:
jsr scroll_direntry_clean jsr scroll_direntry_clean
lda filesel_sel lda menu_sel
bne up_noscroll bne up_noscroll
lda #$01 lda #$01
sta filesel_dirty sta menu_dirty
rep #$20 : .al rep #$20 : .al
lda dirptr_addr lda dirptr_addr
cmp dirstart_addr cmp dirstart_addr
@@ -407,25 +404,25 @@ filesel_key_up:
bra up_out bra up_out
up_noscroll up_noscroll
dec dec
sta filesel_sel sta menu_sel
up_out up_out
sep #$20 : .as sep #$20 : .as
rts rts
fileselupd_lastcursor menuupd_lastcursor
jsr scroll_direntry_clean jsr scroll_direntry_clean
lda dirend_idx lda dirend_idx
lsr lsr
lsr lsr
sta filesel_sel sta menu_sel
rts rts
; go back one page ; go back one page
filesel_key_left: menu_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 filesel_dirty sta menu_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 +441,18 @@ filesel_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 filesel_sel ; reset the selection cursor too stz menu_sel ; reset the selection cursor too
bra - bra -
; go forth one page ; go forth one page
filesel_key_right: menu_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 fileselupd_lastcursor bne menuupd_lastcursor
lda #$01 lda #$01
sta filesel_dirty sta menu_dirty
rep #$20 : .al rep #$20 : .al
lda listdisp lda listdisp
asl asl
@@ -466,18 +463,18 @@ filesel_key_right:
sep #$20 : .as sep #$20 : .as
rts rts
filesel_key_a: menu_key_a:
jsr select_item jsr select_item
rts rts
filesel_key_select: menu_key_select:
rts rts
filesel_key_start: menu_key_start:
jsr select_last_file jsr select_last_file
rts rts
filesel_key_b: menu_key_b:
stz direntry_xscroll stz direntry_xscroll
stz direntry_xscroll_state stz direntry_xscroll_state
rep #$20 : .al rep #$20 : .al
@@ -485,7 +482,7 @@ filesel_key_b:
beq skip_key_b beq skip_key_b
sta dirptr_addr sta dirptr_addr
lda #$0000 lda #$0000
sta filesel_sel sta menu_sel
bra select_item bra select_item
skip_key_b skip_key_b
sep #$20 : .as sep #$20 : .as
@@ -493,7 +490,7 @@ skip_key_b
select_item: select_item:
rep #$20 : .al rep #$20 : .al
lda filesel_sel lda menu_sel
and #$00ff and #$00ff
asl asl
asl asl
@@ -505,8 +502,6 @@ select_item:
lda [dirptr_addr], y lda [dirptr_addr], y
cmp #$01 cmp #$01
beq sel_is_file beq sel_is_file
cmp #$03
beq sel_is_spc
cmp #$04 cmp #$04
beq sel_is_file beq sel_is_file
cmp #$80 cmp #$80
@@ -524,28 +519,25 @@ sel_is_parent
sel_is_dir sel_is_dir
jsr select_dir jsr select_dir
bra select_item_cont bra select_item_cont
sel_is_spc
jsr select_spc
bra select_item_cont
select_file: select_file:
; have MCU load the rom ; have avr load the rom
dey dey
rep #$20 : .al rep #$20 : .al
lda [dirptr_addr], y lda [dirptr_addr], y
and #$00ff and #$00ff
sta @MCU_PARAM+2 sta @AVR_PARAM+2
dey dey
dey dey
lda [dirptr_addr], y lda [dirptr_addr], y
sta @MCU_PARAM sta @AVR_PARAM
sep #$20 : .as sep #$20 : .as
lda #$01
sta @AVR_CMD
select_file_fade:
lda #$00 lda #$00
sta @$4200 sta @$4200
sei sei
lda #$01
sta @MCU_CMD
select_file_fade:
jsl @wram_fadeloop jsl @wram_fadeloop
rts rts
@@ -568,7 +560,7 @@ select_dir:
lda @dirptr_bank lda @dirptr_bank
sta [dirlog_idx], y sta [dirlog_idx], y
iny iny
lda @filesel_sel lda @menu_sel
sta [dirlog_idx], y sta [dirlog_idx], y
lda @dirlog_idx lda @dirlog_idx
clc clc
@@ -604,12 +596,10 @@ select_dir:
sta @dirptr_addr sta @dirptr_addr
sta @dirstart_addr sta @dirstart_addr
lda #$0000 lda #$0000
sta @filesel_sel sta @menu_sel
sta @direntry_xscroll
sta @direntry_xscroll_state
sep #$20 : .as sep #$20 : .as
lda #$01 lda #$01
sta @filesel_dirty sta @menu_dirty
plb plb
rts rts
@@ -638,35 +628,14 @@ select_parent:
sta @dirptr_bank sta @dirptr_bank
iny iny
rep #$20 : .al rep #$20 : .al
lda [dirlog_idx], y ; load filesel_sel lda [dirlog_idx], y ; load menu_sel
sta @filesel_sel sta @menu_sel
sep #$20 : .as sep #$20 : .as
lda #$01 lda #$01
sta @filesel_dirty sta @menu_dirty
rts rts
select_spc: menu_key_x:
dey
rep #$20 : .al
lda [dirptr_addr], y
and #$00ff
sta @MCU_PARAM+2
dey
dey
lda [dirptr_addr], y
sta @MCU_PARAM
sep #$20 : .as
lda #CMD_LOADSPC
sta @MCU_CMD
wait_spc:
lda @MCU_CMD
cmp #$00
bne wait_spc
jsr spcplayer
jsr restore_screen
rts
filesel_key_x:
jsr mainmenu jsr mainmenu
rts rts
@@ -676,11 +645,11 @@ setup_224:
lda #18 lda #18
sta listdisp sta listdisp
dec dec
cmp filesel_sel cmp menu_sel
bmi setup_224_adjsel bmi setup_224_adjsel
bra + bra +
setup_224_adjsel setup_224_adjsel
sta filesel_sel sta menu_sel
+ +
lda #18*64 lda #18*64
sta textdmasize sta textdmasize
@@ -699,7 +668,7 @@ setup_224_adjsel
sta hdma_math_selection sta hdma_math_selection
stz vidmode stz vidmode
lda #$01 lda #$01
sta filesel_dirty sta menu_dirty
lda #^space64 lda #^space64
ldx #!space64 ldx #!space64
sta print_bank sta print_bank
@@ -719,7 +688,7 @@ setup_224_adjsel
plp plp
rts rts
filesel_statusbar menu_statusbar
pha pha
phx phx
php php
@@ -805,7 +774,7 @@ select_last_file:
and pad1trig+1 and pad1trig+1
beq - beq -
lda #$04 lda #$04
sta @MCU_CMD sta @AVR_CMD
jmp select_file_fade jmp select_file_fade
+ jsr restore_screen + jsr restore_screen
plp plp
@@ -822,7 +791,7 @@ scroll_direntry_clean:
rts rts
scroll_direntry: scroll_direntry:
ldy filesel_sel ldy menu_sel
lda direntry_xscroll_state lda direntry_xscroll_state
bne + bne +
lda direntry_fits, y lda direntry_fits, y
@@ -852,7 +821,7 @@ scroll_direntry_scrollfast
lda #$02 lda #$02
sta cursor_x sta cursor_x
rep #$20 : .al rep #$20 : .al
lda filesel_sel lda menu_sel
asl asl
asl asl
tay tay
@@ -869,7 +838,7 @@ scroll_direntry_scrollfast
lda [dirptr_addr], y lda [dirptr_addr], y
iny iny
sta @dirent_type sta @dirent_type
ldy filesel_sel ldy menu_sel
sty direntry_fits_idx sty direntry_fits_idx
phy phy
jsr print_direntry jsr print_direntry
@@ -881,7 +850,6 @@ scroll_direntry_scrollfast
lda #$28 lda #$28
sta direntry_xscroll_wait sta direntry_xscroll_wait
+ lda direntry_xscroll_state + lda direntry_xscroll_state
clc
adc direntry_xscroll adc direntry_xscroll
sta direntry_xscroll sta direntry_xscroll
bne + bne +

View File

@@ -4,15 +4,7 @@ read_pad:
read_pad1 read_pad1
ldx pad1mem ;byetUDLRaxlriiii ldx pad1mem ;byetUDLRaxlriiii
lda $4218 lda $4218
and #$000f ora $421a
bne +
lda $4218
+ sta pad1mem
lda $421a
and #$000f
bne +
lda $421a
+ ora pad1mem
sta pad1mem sta pad1mem
and #$0f00 and #$0f00
bne read_pad1_count bne read_pad1_count

View File

@@ -84,29 +84,9 @@ math_cont
clc clc
adc bar_x ; + X start coord adc bar_x ; + X start coord
sta $2127 ; window 1 right sta $2127 ; window 1 right
; lda #$3e ; ch. 1-5 lda #$3e ; ch. 1-5
; sta @$420c ; trigger HDMA sta @$420c ; trigger HDMA
lda #$01
lda cur_bright
cmp tgt_bright
beq +
bpl bright_down
bright_up
inc
sta cur_bright
lda $2100
and #$f0
ora cur_bright
sta $2100
bra +
bright_down
dec
sta cur_bright
lda $2100
and #$f0
ora cur_bright
sta $2100
+ lda #$01
sta isr_done sta isr_done
rtl rtl

View File

@@ -1,61 +0,0 @@
; All SPC700 routines in SPC700 machine code
; SPC loader & transfer routines by Shay Green <gblargg@gmail.com>
loader ; .org $0002
.byt $F8,$21 ; mov x,@loader_data
.byt $BD ; mov sp,x
.byt $CD,$22 ; mov x,#@loader_data+1
; Push PC and PSW from SPC header
.byt $BF ; mov a,(x)+
.byt $2D ; push a
.byt $BF ; mov a,(x)+
.byt $2D ; push a
.byt $BF ; mov a,(x)+
.byt $2D ; push a
; Set FLG to $60 rather than value from SPC
.byt $E8,$60 ; mov a,#$60
.byt $D4,$6C ; mov FLG+x,a
; Restore DSP registers
.byt $8D,$00 ; mov y,#0
.byt $BF ; next: mov a,(x)+
.byt $CB,$F2 ; mov $F2,y
.byt $C4,$F3 ; mov $F3,a
.byt $FC ; inc y
.byt $10,-8 ; bpl next
.byt $8F,$6C,$F2 ; mov $F2,#FLG ; set for later
; Rerun loader
.byt $5F,$C0,$FF ; jmp $FFC0
;---------------------------------------
transfer ; .org $0002
.byt $CD,$FE ; mov x,#$FE ; transfer 254 pages
; Transfer four-byte chunks
.byt $8D,$3F ; page: mov y,#$3F
.byt $E4,$F4 ; quad: mov a,$F4
.byt $D6,$00,$02 ; mov0: mov !$0200+y,a
.byt $E4,$F5 ; mov a,$F5
.byt $D6,$40,$02 ; mov1: mov !$0240+y,a
.byt $E4,$F6 ; mov a,$F6
.byt $D6,$80,$02 ; mov2: mov !$0280+y,a
.byt $E4,$F7 ; mov a,$F7 ; tell S-CPU we're ready for more
.byt $CB,$F7 ; mov $F7,Y
.byt $D6,$C0,$02 ; mov3: mov !$02C0+y,a
.byt $DC ; dec y
.byt $10,-25 ; bpl quad
; Increment MSBs of addresses
.byt $AB,$0A ; inc mov0+2
.byt $AB,$0F ; inc mov1+2
.byt $AB,$14 ; inc mov2+2
.byt $AB,$1B ; inc mov3+2
.byt $1D ; dec x
.byt $D0,-38 ; bne page
; Rerun loader
.byt $5F,$C0,$FF ; jmp $FFC0

View File

@@ -1,676 +0,0 @@
#include "memmap.i65"
; SPC Player
; SPC700 transfer and IO routines by Shay Green <gblargg@gmail.com>
spcplayer:
php
sep #$30 : .as : .xs
ldx #$0a ; Check if SPC header is present
-
lda @SPC_HEADER,x
cmp @text_spcid,x
beq +
jmp spc_exit
+
dey
bne -
rep #$10 : .xl ; Now draw lots of stuff
stz bar_wl
dec bar_wl
stz bar_xl
dec bar_xl
stz bar_yl
dec bar_yl
jsr backup_screen
lda #^text_spcplay ; Loading window
sta window_tbank
ldx #!text_spcplay
stx window_taddr
lda @spcplay_win_x
sta window_x
lda @spcplay_win_y
sta window_y
lda @spcplay_win_w
sta window_w
lda @spcplay_win_h
sta window_h
jsr draw_window
lda #^text_spcload ; Loading text
ldx #!text_spcload
sta print_bank
stx print_src
stz print_pal
lda #29
sta print_count
lda #17
sta print_y
lda #17
sta print_x
jsr hiprint
stz isr_done
-
lda isr_done ; Wait until text is being printed...
beq -
jsr spc700_load ; Load SPC into SPC700
lda #^text_spcplay
sta window_tbank
ldx #!text_spcplay
stx window_taddr
lda @spcstart_win_x
sta window_x
lda @spcstart_win_y
sta window_y
lda @spcstart_win_w
sta window_w
lda @spcstart_win_h
sta window_h
jsr draw_window
lda #^text_spcstarta
ldx #!text_spcstarta
sta print_bank
stx print_src
lda #$01
sta print_pal
lda #30
sta print_count
lda #15
sta print_y
lda #17
sta print_x
jsr hiprint
lda #^text_spcstartb
ldx #!text_spcstartb
sta print_bank
stx print_src
lda #$01
sta print_pal
lda #07
sta print_count
lda #17
sta print_y
lda #12
sta print_x
jsr hiprint
lda #$fe
ldx #$004e
sta print_bank
stx print_src
stz print_pal
lda #32
sta print_count
lda #17
sta print_y
lda #20
sta print_x
jsr hiprint
lda #^text_spcstartc
ldx #!text_spcstartc
sta print_bank
stx print_src
lda #$01
sta print_pal
lda #07
sta print_count
lda #18
sta print_y
lda #12
sta print_x
jsr hiprint
lda #$fe
ldx #$002e
sta print_bank
stx print_src
stz print_pal
lda #32
sta print_count
lda #18
sta print_y
lda #20
sta print_x
jsr hiprint
lda #^text_spcstartd
ldx #!text_spcstartd
sta print_bank
stx print_src
lda #$01
sta print_pal
lda #07
sta print_count
lda #19
sta print_y
lda #12
sta print_x
jsr hiprint
lda #$fe
ldx #$00b0
sta longptr+2
sta print_bank
stx longptr
ldy #$00
lda [longptr], y
cmp #$41
bpl +
inx
+ stx print_src
stz print_pal
lda #32
sta print_count
lda #19
sta print_y
lda #20
sta print_x
jsr hiprint
spc_playloop:
lda isr_done ; SPC player loop
lsr
bcc spc_playloop
jsr printtime
stz isr_done
jsr read_pad
lda #$80
and pad1trig+1
bne spc_key_b
bra spc_playloop
spc_key_b:
rep #$20 : .al
tsc
sta saved_sp ; Save SP for later re-entry
lda #$fa50 ; Write reset signature
sta @warm_signature
sep #$20 : .as
sei ; Blank screen & issue CMD_RESET command to Microcontroller...
stz $2100 ; ...this is required, because there is no other way to stop S-SMP & S-DSP
lda #CMD_RESET
sta @MCU_CMD
-
bra - ; At this point, the SNES waits for an external reset from the Microcontroller
spc_exit: ; Return from player in case of wrong SPC file data
plp
rts
;---------------------------------------
spc700_load:
php
sep #$20 : .as
rep #$10 : .xl
sei ; Disable NMI & IRQ
stz $4200 ; The SPC player code is really timing sensitive ;)
jsr upload_dsp_regs ; Upload S-DSP registers
jsr upload_high_ram ; Upload 63.5K of SPC700 ram
jsr upload_low_ram ; Upload rest of ram
jsr restore_final ; Restore SPC700 state & start execution
lda #$81 ; VBlank NMI + Auto Joypad Read
sta $4200 ; enable V-BLANK NMI
cli
plp
rts
;---------------------------------------
; Uploads DSP registers and some other setup code
upload_dsp_regs:
; ---- Begin upload
ldy #$0002
jsr spc_begin_upload
; ---- Upload loader
ldx #$0000
-
lda @loader,x
jsr spc_upload_byte
inx
cpy #31 ; size of loader
bne -
; ---- Upload SP, PC & PSW
lda @SPC_HEADER+43
jsr spc_upload_byte
lda @SPC_HEADER+38
jsr spc_upload_byte
lda @SPC_HEADER+37
jsr spc_upload_byte
lda @SPC_HEADER+42
jsr spc_upload_byte
; ---- Upload DSP registers
ldx #$0000
-
; initialize FLG and KON ($6c/$4c) to avoid artifacts
cpx #$4C
bne +
lda #$00
bra upload_skip_load
+
cpx #$6C
bne +
lda #$E0
bra upload_skip_load
+
lda @SPC_DSP_REGS,x
upload_skip_load
jsr spc_upload_byte
inx
cpx #128
bne -
; --- Upload fixed values for $F1-$F3
ldy #$00F1
jsr spc_next_upload
lda #$80 ; stop timers
jsr spc_upload_byte
lda #$6c ; get dspaddr set for later
jsr spc_upload_byte
lda #$60
jsr spc_upload_byte
; ---- Upload $f8-$1ff
ldy #$00F8
jsr spc_next_upload
ldx #$00F8
-
lda @SPC_DATA,x
jsr spc_upload_byte
inx
cpx #$200
bne -
; ---- Execute loader
ldy #$0002
jsr spc_execute
rts
;---------------------------------------
upload_high_ram:
ldy #$0002
jsr spc_begin_upload
; ---- Upload transfer routine
ldx #$0000
-
lda @transfer,x
jsr spc_upload_byte
inx
cpy #43 ; size of transfer routine
bne -
ldx #$023f ; prepare transfer address
; ---- Execute transfer routine
ldy #$0002
sty APUIO2
stz APUIO1
lda APUIO0
inc
inc
sta APUIO0
; Wait for acknowledgement
-
cmp APUIO0
bne -
; ---- Burst transfer of 63.5K using custom routine
outer_transfer_loop:
ldy #$003f ; 3
inner_transfer_loop:
lda @SPC_DATA,x ; 5 |
sta APUIO0 ; 4 |
lda @SPC_DATA+$40,x ; 5 |
sta APUIO1 ; 4 |
lda @SPC_DATA+$80,x ; 5 |
sta APUIO2 ; 4 |
lda @SPC_DATA+$C0,x ; 5 |
sta APUIO3 ; 4 |
tya ; 2 >> 38 cycles
-
cmp APUIO3 ; 4 |
bne - ; 3 |
dex ; 2 |
dey ; 2 |
bpl inner_transfer_loop ; 3 >> 14 cycles
rep #$21 : .al ; 3 |
txa ; 2 |
adc #$140 ; 3 |
tax ; 2 |
sep #$20 : .as ; 3 |
cpx #$003f ; 3 |
bne outer_transfer_loop ; 3 >> 19 cycles
rts
;---------------------------------------
upload_low_ram:
; ---- Upload $0002-$00EF using IPL
ldy #$0002
jsr spc_begin_upload
ldx #$0002
-
lda @SPC_DATA,x
jsr spc_upload_byte
inx
cpx #$00F0
bne -
rts
;---------------------------------------
; Executes final restoration code
restore_final:
jsr start_exec_io ; prepare execution from I/O registers
stz $420d ; SPC700 I/O code requires SLOW timing
; ---- Restore first two bytes of RAM
lda @SPC_DATA
xba
lda #$e8 ; MOV A,#@SPC_DATA
tax
jsr exec_instr
ldx #$00C4 ; MOV $00,A
jsr exec_instr
lda @SPC_DATA+1
xba
lda #$e8 ; MOV A,#@SPC_DATA+1
tax
jsr exec_instr
ldx #$01C4 ; MOV $01,A
jsr exec_instr
; ---- Restore SP
lda @SPC_HEADER+43
sec
sbc #3
xba
lda #$cd ; MOV X,#@SPC_HEADER+43
tax
jsr exec_instr
ldx #$bd ; MOV SP,X
jsr exec_instr
; ---- Restore X
lda @SPC_HEADER+40
xba
lda #$cd ; MOV X,#@SPC_HEADER+40
tax
jsr exec_instr
; ---- Restore Y
lda @SPC_HEADER+41
xba
lda #$8d ; MOV Y,#@SPC_HEADER+41
tax
jsr exec_instr
; ---- Restore DSP FLG register
lda @SPC_DSP_REGS+$6c
xba
lda #$e8 ; MOV A,#@SPC_DSP_REGS+$6c
tax
jsr exec_instr
ldx #$f3C4 ; MOV $f3,A -> $f2 has been set-up before by SPC700 loader
jsr exec_instr
; ---- wait a bit (the newer S-APU takes its time to ramp up the volume)
lda #$10
- pha
jsr waitblank
pla
dec
bne -
; ---- Restore DSP KON register
lda #$4C
xba
lda #$e8 ; MOV A,#$4c
tax
jsr exec_instr
ldx #$f2C4 ; MOV $f2,A
jsr exec_instr
lda @SPC_DSP_REGS+$4C
xba
lda #$e8 ; MOV A,#@SPC_DSP_REGS+$4c
tax
jsr exec_instr
ldx #$f3C4 ; MOV $f3,A
jsr exec_instr
; ---- Restore DSP register address
lda @SPC_DATA+$F2
xba
lda #$e8 ; MOV A,#@SPC_DATA+$F2
tax
jsr exec_instr
ldx #$f2C4 ; MOV dest,A
jsr exec_instr
; ---- Restore CONTROL register
lda @SPC_DATA+$F1
and #$CF ; don't clear input ports
xba
lda #$e8 ; MOV A,#@SPC_DATA+$F1
tax
jsr exec_instr
ldx #$f1C4 ; MOV $F1,A
jsr exec_instr
;---- Restore A
lda @SPC_HEADER+39
xba
lda #$e8 ; MOV A,#@SPC_HEADER+39
tax
jsr exec_instr
;---- Restore PSW and PC
ldx #$7F00 ; NOP; RTI
stx APUIO0
lda #$FC ; Patch loop to execute instruction just written
sta APUIO3
;---- restore IO ports $f4 - $f7
rep #$20 : .al
lda @SPC_DATA+$F4
tax
lda @SPC_DATA+$F6
sta APUIO2
stx APUIO0 ; last to avoid overwriting RETI before run
sep #$20 : .as
lda #$01
sta $420d ; restore FAST CPU operation
rts
;---------------------------------------
spc_begin_upload:
sty APUIO2 ; Set address
ldy #$BBAA ; Wait for SPC
-
cpy APUIO0
bne -
lda #$CC ; Send acknowledgement
sta APUIO1
sta APUIO0
- ; Wait for acknowledgement
cmp APUIO0
bne -
ldy #0 ; Initialize index
rts
;---------------------------------------
spc_upload_byte:
sta APUIO1
tya ; Signal it's ready
sta APUIO0
- ; Wait for acknowledgement
cmp APUIO0
bne -
iny
rts
;---------------------------------------
spc_next_upload:
sty APUIO2
; Send command
; Special case operation has been fully tested.
lda APUIO0
inc
inc
bne +
inc
+
sta APUIO1
sta APUIO0
; Wait for acknowledgement
-
cmp APUIO0
bne -
ldy #0
rts
;---------------------------------------
spc_execute:
sty APUIO2
stz APUIO1
lda APUIO0
inc
inc
sta APUIO0
; Wait for acknowledgement
-
cmp APUIO0
bne -
rts
;---------------------------------------
start_exec_io:
; Set execution address
ldx #$00F5
stx APUIO2
stz APUIO1 ; NOP
ldx #$FE2F ; BRA *-2
; Signal to SPC that we're ready
lda APUIO0
inc
inc
sta APUIO0
; Wait for acknowledgement
-
cmp APUIO0
bne -
; Quickly write branch
stx APUIO2
rts
;---------------------------------------
exec_instr:
; Replace instruction
stx APUIO0
lda #$FC
sta APUIO3 ; 30
; SPC BRA loop takes 4 cycles, so it reads
; the branch offset every 4 SPC cycles (84 master).
; We must handle the case where it read just before
; the write above, and when it reads just after it.
; If it reads just after, we have at least 7 SPC
; cycles (147 master) to change restore the branch
; offset.
; 48 minimum, 90 maximum
ora #0
ora #0
ora #0
nop
nop
nop
; 66 delay, about the middle of the above limits
phd ;4
pld ;5
; Give plenty of extra time if single execution
; isn't needed, as this avoids such tight timing
; requirements.
; phd ;4
; pld ;5
; phd ;4
; pld ;5
; Patch loop to skip first two bytes
lda #$FE ; 16
sta APUIO3 ; 30
; 38 minimum (assuming 66 delay above)
phd ; 4
pld ; 5
; Give plenty of extra time if single execution
; isn't needed, as this avoids such tight timing
; requirements.
phd
pld
phd
pld
rts

View File

@@ -35,19 +35,11 @@ show_sysinfo:
sta window_h sta window_h
jsr draw_window jsr draw_window
stz print_pal stz print_pal
ldx #38
copy_snes_system_text:
lda @text_system,x
sta @snes_system_config,x
dex
bpl copy_snes_system_text
sysinfo_printloop: sysinfo_printloop:
sep #$20 : .as sep #$20 : .as
rep #$10 : .xl rep #$10 : .xl
lda #CMD_SYSINFO lda #CMD_SYSINFO
sta @MCU_CMD sta @AVR_CMD
lda #^SYSINFO_BLK lda #^SYSINFO_BLK
ldx #!SYSINFO_BLK ldx #!SYSINFO_BLK
sta print_bank sta print_bank
@@ -59,7 +51,7 @@ sysinfo_printloop:
sta print_x sta print_x
lda #40 lda #40
sta print_count sta print_count
lda #12 lda #13
- pha - pha
jsr hiprint jsr hiprint
inc print_y inc print_y
@@ -72,41 +64,6 @@ sysinfo_printloop:
pla pla
dec dec
bne - bne -
ldx #24
lda $213e
and #$0f
clc
adc #$30
sta @snes_system_config,x
ldx #38
lda $213f
and #$0f
clc
adc #$30
sta @snes_system_config,x
ldx #10
lda $4210
and #$0f
clc
adc #$30
sta @snes_system_config,x
lda #^snes_system_config ; System text
ldx #!snes_system_config
sta print_bank
stx print_src
stz print_pal
lda #39
sta print_count
lda #23
sta print_y
lda #12
sta print_x
jsr hiprint
- lda isr_done - lda isr_done
lsr lsr
bcc - bcc -
@@ -130,5 +87,5 @@ sysinfo_printloop:
+ plp + plp
jsr restore_screen jsr restore_screen
lda #$00 lda #$00
sta @MCU_CMD sta @AVR_CMD
rtl rtl

View File

@@ -1,95 +1,146 @@
.text .text
#include "memmap.i65" #include "memmap.i65"
.byt "===HIPRINT===" .byt "===HIPRINT==="
; input:
; print_count
; print_x
; print_y
; print_src
; print_bank
; print_pal
;
; output:
; print_done (# of chars printed)
; print_over (char after print_count)
hiprint: hiprint:
php
sep #$20 : .as sep #$20 : .as
rep #$10 : .xl
ldx print_src
stx print_ptr
lda print_bank
sta print_ptr+2
phb
lda #$7e
pha
plb
rep #$30 : .al : .xl
lda print_pal
and #$00ff
xba
asl
asl
ora #$2000
sta print_temp
lda print_count lda print_count
and #$00ff sta print_count_tmp
beq hiprint_end stz print_over
tay rep #$30 : .xl : .al
stz print_done
lda print_x lda print_x
and #$00ff and #$00ff
sta print_x lsr
lda print_y bcs print_bg1
ldx #!BG1_TILE_BUF ; for 2nd loop
phx
ldx #!BG2_TILE_BUF ; for 1st loop
phx
bra print_bg_cont
print_bg1
ldx #!BG2_TILE_BUF+2 ; for 2nd loop
phx
ldx #!BG1_TILE_BUF ; for 1st loop da whoop
phx
bra print_bg_cont
print_bg_cont
sta !print_temp
lda !print_y
and #$00ff and #$00ff
asl asl
asl asl
asl asl
asl asl
asl asl
asl
clc clc
adc print_x adc !print_temp
and #$fffe asl ; double the offset for WRAM addressing
tax tay ; zonday
lda print_x plx
lsr phy ; offset from tilemap start
bcs hiprint_bg1 stx !print_temp
hiprint_bg2 clc
lda [print_ptr] adc !print_temp
and #$00ff ; we need to transfer to WRAM and from there to VRAM via DMA during VBLANK
beq hiprint_end ; because VRAM can only be accessed during VBLANK and forced blanking.
inc print_ptr sta $2181
asl
ora print_temp
sta !BG2_TILE_BUF, x
dey
beq hiprint_end
hiprint_bg1
lda [print_ptr]
and #$00ff
beq hiprint_end
inc print_ptr
asl
ora print_temp
sta !BG1_TILE_BUF, x
inx
inx
dey
beq hiprint_end
bra hiprint_bg2
hiprint_end
plb
sep #$20 : .as sep #$20 : .as
lda [print_ptr] lda #$7f ;we really only need bit 0. full bank given for clarity
sta print_over sta $2183
tya print_loop
sec ldx !print_src
sbc print_count lda !print_bank
eor #$ff pha
plb
phx ; source addr
print_loop_inner
lda !0,x
bne +
jmp print_end2
+ asl
sta @$2180
lda @print_pal
asl
asl
adc #$00
ora #$20
sta @$2180
lda @print_done
inc inc
sta print_done sta @print_done
plp inx
lda !0,x
beq print_loop2
inx
lda !0,x
beq print_loop2
lda @print_count_tmp
dec
dec
sta @print_count_tmp
beq print_loop2
bmi print_loop2
bra print_loop_inner
print_loop2
lda @print_count
dec
sta @print_count_tmp
beq print_end2
lda #$00
pha
plb
rep #$30 : .al : .xl
ply ; source addr
iny
pla ; offset from tilemap start
plx ; other tilemap addr
stx !print_temp
clc
adc !print_temp ; tilemap+offset
sta $2181
tyx
sep #$20 : .as
lda print_bank
pha
plb
print_loop2_inner
lda !0,x
bne +
jmp print_end
+ asl
sta @$2180
lda @print_pal
asl
asl
adc #$00
ora #$20
sta @$2180
lda @print_done
inc
sta @print_done
inx
lda !0,x
beq print_end
lda @print_count_tmp
dec
dec
sta @print_count_tmp
beq print_end
bmi print_end
inx
lda !0,x
beq print_end
bra print_loop2_inner
print_end2 ; clean up the stack (6 bytes)
ply
ply
ply
print_end
lda !0,x
sta @print_over
lda #$00
pha
plb
rts rts
@@ -239,7 +290,6 @@ draw_window:
sta print_count sta print_count
jsr hiprint jsr hiprint
lda print_done lda print_done
clc
adc print_x adc print_x
sta print_x sta print_x
lda #^window_tr lda #^window_tr

View File

@@ -499,8 +499,6 @@ time_dec_y1_normal
rts rts
gettime gettime
php
sep #$20 : .as
lda #$0d lda #$0d
sta $2801 sta $2801
lda $2800 lda $2800
@@ -528,7 +526,6 @@ gettime
sta time_y10 sta time_y10
lda $2800 lda $2800
sta time_y100 sta time_y100
plp
rts rts
rendertime rendertime
@@ -680,31 +677,31 @@ is_leapyear_400th
settime settime
lda time_y100 lda time_y100
sta @MCU_PARAM sta @AVR_PARAM
lda time_y10 lda time_y10
sta @MCU_PARAM+1 sta @AVR_PARAM+1
lda time_y1 lda time_y1
sta @MCU_PARAM+2 sta @AVR_PARAM+2
lda time_mon lda time_mon
sta @MCU_PARAM+3 sta @AVR_PARAM+3
lda time_d10 lda time_d10
sta @MCU_PARAM+4 sta @AVR_PARAM+4
lda time_d1 lda time_d1
sta @MCU_PARAM+5 sta @AVR_PARAM+5
lda time_h10 lda time_h10
sta @MCU_PARAM+6 sta @AVR_PARAM+6
lda time_h1 lda time_h1
sta @MCU_PARAM+7 sta @AVR_PARAM+7
lda time_m10 lda time_m10
sta @MCU_PARAM+8 sta @AVR_PARAM+8
lda time_m1 lda time_m1
sta @MCU_PARAM+9 sta @AVR_PARAM+9
lda time_s10 lda time_s10
sta @MCU_PARAM+10 sta @AVR_PARAM+10
lda time_s1 lda time_s1
sta @MCU_PARAM+11 sta @AVR_PARAM+11
lda #$02 ; set clock lda #$02 ; set clock
sta @MCU_CMD sta @AVR_CMD
rts rts
printtime: printtime:

View File

@@ -75,7 +75,7 @@ ASRC = startup.S crc.S
# (Note: 3 is not always the best optimization level. See avr-libc FAQ.) # (Note: 3 is not always the best optimization level. See avr-libc FAQ.)
# Use s -mcall-prologues when you really need size... # Use s -mcall-prologues when you really need size...
#OPT = 2 #OPT = 2
OPT = s OPT = 2
# Debugging format. # Debugging format.
DEBUG = dwarf-2 DEBUG = dwarf-2
@@ -117,6 +117,7 @@ endif
# CC must be defined here to generate the correct CFLAGS # CC must be defined here to generate the correct CFLAGS
SHELL = sh SHELL = sh
CC = $(ARCH)-gcc CC = $(ARCH)-gcc
#CC = clang
OBJCOPY = $(ARCH)-objcopy OBJCOPY = $(ARCH)-objcopy
OBJDUMP = $(ARCH)-objdump OBJDUMP = $(ARCH)-objdump
SIZE = $(ARCH)-size SIZE = $(ARCH)-size
@@ -124,8 +125,6 @@ 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
@@ -139,8 +138,10 @@ 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 -Werror CFLAGS += -Wall -Wstrict-prototypes
#-Werror
CFLAGS += -Wa,-adhlns=$(OBJDIR)/$(<:.c=.lst) CFLAGS += -Wa,-adhlns=$(OBJDIR)/$(<:.c=.lst)
#CFLAGS += -I/opt/arm-none-eabi-4.6.2/arm-none-eabi/include/
CFLAGS += -I$(OBJDIR) CFLAGS += -I$(OBJDIR)
CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS)) CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
CFLAGS += $(CSTANDARD) CFLAGS += $(CSTANDARD)
@@ -198,7 +199,7 @@ ALL_ASFLAGS = -I. -x assembler-with-cpp $(ASFLAGS) $(CDEFS)
# Default target. # Default target.
all: build all: build
build: elf bin hex cfgware.h 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
@@ -231,13 +232,6 @@ 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) $< $@
$(OBJDIR)/fpga_rle.bit: sd2sneslite.bit
$(E) " RLE $@"
$(Q) $(RLE) $< $@
# Generate autoconf.h from config # Generate autoconf.h from config
.PRECIOUS : $(OBJDIR)/autoconf.h .PRECIOUS : $(OBJDIR)/autoconf.h
@@ -310,7 +304,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,7 +17,6 @@ b) Cortex M3 toolchain
- texinfo - texinfo
- libmpfr-dev - libmpfr-dev
- libgmp3-dev - libgmp3-dev
- libmpc-dev
- gawk - gawk
- bison - bison
- recode - recode
@@ -26,7 +25,6 @@ b) Cortex M3 toolchain
- libexpat-dev - libexpat-dev
- make - make
- gcc - gcc
Package names may differ for your distribution.
Newer gccs complain when compiling binutils, so you may have to add Newer gccs complain when compiling binutils, so you may have to add
'--disable-werror' to the compiler options for binutils in the Makefile. '--disable-werror' to the compiler options for binutils in the Makefile.
The Makefile will install immediately so make sure you can write to the The Makefile will install immediately so make sure you can write to the

80
src/bootldr/baudcalc.c Normal file
View File

@@ -0,0 +1,80 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include "config.h"
static uint8_t uart_lookupratio(float f_fr) {
uint16_t errors[72]={0,67,71,77,83,91,100,111,125,
133,143,154,167,182,200,214,222,231,
250,267,273,286,300,308,333,357,364,
375,385,400,417,429,444,455,462,467,
500,533,538,545,556,571,583,600,615,
625,636,643,667,692,700,714,727,733,
750,769,778,786,800,818,833,846,857,
867,875,889,900,909,917,923,929,933};
uint8_t ratios[72]={0x10,0xf1,0xe1,0xd1,0xc1,0xb1,0xa1,0x91,0x81,
0xf2,0x71,0xd2,0x61,0xb2,0x51,0xe3,0x92,0xd3,
0x41,0xf4,0xb3,0x72,0xa3,0xd4,0x31,0xe5,0xb4,
0x83,0xd5,0x52,0xc5,0x73,0x94,0xb5,0xd6,0xf7,
0x21,0xf8,0xd7,0xb6,0x95,0x74,0xc7,0x53,0xd8,
0x85,0xb7,0xe9,0x32,0xd9,0xa7,0x75,0xb8,0xfb,
0x43,0xda,0x97,0xeb,0x54,0xb9,0x65,0xdb,0x76,
0xfd,0x87,0x98,0xa9,0xba,0xcb,0xdc,0xed,0xfe};
int fr = (f_fr-1)*1000;
int i=0, i_result=0;
int err=0, lasterr=1000;
for(i=0; i<72; i++) {
if(fr<errors[i]) {
err=errors[i]-fr;
} else {
err=fr-errors[i];
}
if(err<lasterr) {
i_result=i;
lasterr=err;
}
}
return ratios[i_result];
}
static uint32_t baud2divisor(unsigned int baudrate) {
uint32_t int_ratio;
uint32_t error;
uint32_t dl=0;
float f_ratio;
float f_fr;
float f_dl;
float f_pclk = (float)CONFIG_CPU_FREQUENCY / CONFIG_UART_PCLKDIV;
uint8_t fract_ratio;
f_ratio=(f_pclk / 16 / baudrate);
int_ratio = (int)f_ratio;
error=(f_ratio*1000)-(int_ratio*1000);
if(error>990) {
int_ratio++;
} else if(error>10) {
f_fr=1.5;
f_dl=f_pclk / (16 * baudrate * (f_fr));
dl = (int)f_dl;
f_fr=f_pclk / (16 * baudrate * dl);
fract_ratio = uart_lookupratio(f_fr);
}
if(!dl) {
return int_ratio;
} else {
return ((fract_ratio<<16)&0xff0000) | dl;
}
}
int main(int argc, char *argv[])
{
if (argc != 2)
{
printf("usage: %s baud\n", argv[0]);
return -1;
}
printf("Baud %d : 0x%X\n", atoi(argv[1]), baud2divisor(atoi(argv[1])));
return 0;
}

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 " strftime() "\n" \ print "// autoconf.h generated from " ARGV[1] " at TODAY \n" \
"#ifndef AUTOCONF_H\n" \ "#ifndef AUTOCONF_H\n" \
"#define AUTOCONF_H" "#define AUTOCONF_H"
} }

View File

@@ -55,8 +55,8 @@
//#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_BAUDRATE 115200
#define CONFIG_UART_DEADLOCKABLE #define CONFIG_UART_DEADLOCKABLE
#define SSP_CLK_DIVISOR_FAST 2 #define SSP_CLK_DIVISOR_FAST 2

View File

@@ -31,7 +31,9 @@
enum filestates { FILE_OK=0, FILE_ERR, FILE_EOF }; enum filestates { FILE_OK=0, FILE_ERR, FILE_EOF };
BYTE file_buf[512] __attribute__((aligned(4))); #define GCC_ALIGN_WORKAROUND __attribute__ ((aligned(4)))
BYTE file_buf[512] GCC_ALIGN_WORKAROUND;
FATFS fatfs; FATFS fatfs;
FIL file_handle; FIL file_handle;
FRESULT file_res; FRESULT file_res;

View File

@@ -189,7 +189,7 @@ FLASH_RES flash_file(uint8_t *filename) {
} }
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); DBG_BL 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;
} }

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

@@ -52,12 +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;

2429
src/cfgware.h Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -58,8 +58,8 @@ 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\0"; "cd\0reset\0sreset\0dir\0ls\0test\0resume\0loadrom\0loadraw\0saveraw\0put\0rm\0d4\0vmode\0mapper\0settime\0time\0setfeature\0hexdump\0w8\0w16\0stramtest\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 }; enum { CMD_CD = 0, CMD_RESET, CMD_SRESET, CMD_DIR, CMD_LS, CMD_TEST, CMD_RESUME, CMD_LOADROM, CMD_LOADRAW, CMD_SAVERAW, CMD_PUT, CMD_RM, CMD_D4, CMD_VMODE, CMD_MAPPER, CMD_SETTIME, CMD_TIME, CMD_SETFEATURE, CMD_HEXDUMP, CMD_W8, CMD_W16, CMD_SRAMTEST };
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
/* Parse functions */ /* Parse functions */
@@ -104,11 +104,11 @@ static int32_t parse_unsigned(uint32_t lower, uint32_t upper, uint8_t base) {
/* 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 == '?') {
@@ -128,7 +128,7 @@ static int8_t parse_wordlist(char *wordlist) {
} }
while (1) { while (1) {
cur = (unsigned char *)curchar; cur = curchar;
matched = 1; matched = 1;
c = *ptr; c = *ptr;
do { do {
@@ -138,9 +138,9 @@ static int8_t parse_wordlist(char *wordlist) {
return -1; return -1;
} }
if (tolower((int)c) != tolower((int)*cur)) { if (tolower(c) != tolower(*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 {
@@ -156,7 +156,7 @@ static int8_t parse_wordlist(char *wordlist) {
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()) {
@@ -269,7 +269,7 @@ static void cmd_show_directory(void) {
strlwr((char *)name); strlwr((char *)name);
} }
printf("%s [%s] (%ld)",finfo.lfname, finfo.fname, finfo.fsize); printf("%s",name);
/* Directory indicator (Unix-style) */ /* Directory indicator (Unix-style) */
if (finfo.fattrib & AM_DIR) if (finfo.fattrib & AM_DIR)
@@ -294,7 +294,6 @@ static void cmd_loadraw(void) {
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)
save_sram((uint8_t*)curchar, length, address); save_sram((uint8_t*)curchar, length, address);
} }
@@ -349,11 +348,6 @@ void cmd_rm(void) {
if(res) printf("Error %d removing %s\n", res, curchar); if(res) printf("Error %d removing %s\n", res, curchar);
} }
void cmd_mkdir(void) {
FRESULT res = f_mkdir(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);
@@ -367,7 +361,9 @@ void cmd_sreset(void) {
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(1);
delay_ms(20);
snes_reset(0);
} }
} }
void cmd_settime(void) { void cmd_settime(void) {
@@ -420,11 +416,8 @@ void cmd_w16(void) {
sram_writeshort(val, offset); sram_writeshort(val, offset);
} }
void cmd_memset(void) { void cmd_sramtest(void) {
uint32_t offset = parse_unsigned(0, 16777215, 16); sram_memtest();
uint32_t len = parse_unsigned(0, 16777216, 16);
uint8_t val = parse_unsigned(0, 255, 16);
sram_memset(offset, len, val);
} }
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
@@ -435,7 +428,7 @@ void cli_init(void) {
} }
void cli_entrycheck() { void cli_entrycheck() {
if(uart_gotc() && uart_getc() == 27) { if(uart_gotc() && ((uart_getc() == 27) || (uart_getc() == 13))) {
printf("*** BREAK\n"); printf("*** BREAK\n");
cli_loop(); cli_loop();
} }
@@ -509,7 +502,7 @@ void cli_loop(void) {
cmd_show_directory(); cmd_show_directory();
break; break;
case CMD_EXIT: case CMD_RESUME:
return; return;
break; break;
@@ -529,10 +522,6 @@ void cli_loop(void) {
cmd_rm(); cmd_rm();
break; break;
case CMD_MKDIR:
cmd_mkdir();
break;
case CMD_D4: case CMD_D4:
cmd_d4(); cmd_d4();
break; break;
@@ -577,10 +566,9 @@ void cli_loop(void) {
cmd_w16(); cmd_w16();
break; break;
case CMD_MEMSET: case CMD_SRAMTEST:
cmd_memset(); cmd_sramtest();
break; break;
} }
} }
} }

View File

@@ -27,7 +27,7 @@ void clock_init() {
-> FPGA freq = 11289473.7Hz -> FPGA freq = 11289473.7Hz
First, disable and disconnect PLL0. First, disable and disconnect PLL0.
*/ */
clock_disconnect(); // clock_disconnect();
/* PLL is disabled and disconnected. setup PCLK NOW as it cannot be changed /* PLL is disabled and disconnected. setup PCLK NOW as it cannot be changed
reliably with PLL0 connected. reliably with PLL0 connected.
@@ -48,19 +48,12 @@ void clock_init() {
*/ */
enableMainOsc(); enableMainOsc();
setClkSrc(CLKSRC_MAINOSC); setClkSrc(CLKSRC_MAINOSC);
setPLL0MultPrediv(22, 1); // XXX setPLL0MultPrediv(429, 19);
// XXX setPLL0MultPrediv(23, 2);
setPLL0MultPrediv(12, 1);
enablePLL0(); enablePLL0();
setCCLKDiv(6); setCCLKDiv(3);
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) {
@@ -93,32 +86,6 @@ void disconnectPLL0() {
PLL0feed(); PLL0feed();
} }
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) { void setCCLKDiv(uint8_t div) {
LPC_SC->CCLKCFG=CCLK_DIV(div); LPC_SC->CCLKCFG=CCLK_DIV(div);
} }
@@ -137,11 +104,6 @@ void PLL0feed() {
LPC_SC->PLL0FEED=0x55; LPC_SC->PLL0FEED=0x55;
} }
void PLL1feed() {
LPC_SC->PLL1FEED=0xaa;
LPC_SC->PLL1FEED=0x55;
}
void setClkSrc(uint8_t src) { void setClkSrc(uint8_t src) {
LPC_SC->CLKSRCSEL=src; LPC_SC->CLKSRCSEL=src;
} }

View File

@@ -8,9 +8,6 @@
#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)
@@ -59,18 +56,14 @@ 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 disablePLL0(void);
void connectPLL0(void);
void disconnectPLL0(void);
void PLL0feed(void);
void setPLL1MultPrediv(uint16_t mult, uint8_t prediv); void enablePLL0(void);
void enablePLL1(void);
void disablePLL1(void); void disablePLL0(void);
void connectPLL1(void);
void disconnectPLL1(void); void connectPLL0(void);
void PLL1feed(void);
void disconnectPLL0(void);
void setCCLKDiv(uint8_t div); void setCCLKDiv(uint8_t div);
@@ -78,5 +71,9 @@ 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

@@ -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 " strftime() "\n" \ print "// autoconf.h generated from " ARGV[1] " at TODAY\n" \
"#ifndef AUTOCONF_H\n" \ "#ifndef AUTOCONF_H\n" \
"#define AUTOCONF_H" "#define AUTOCONF_H"
} }

View File

@@ -1,4 +1,4 @@
CONFIG_VERSION="0.1.5" CONFIG_VERSION="0.1.30"
#FWVER=00010300 #FWVER=00010300
CONFIG_FWVER=0x00010500 CONFIG_FWVER=66305
CONFIG_MCU_FOSC=12000000 CONFIG_MCU_FOSC=12000000

View File

@@ -35,7 +35,7 @@
#define CONFIG_UART_NUM 3 #define CONFIG_UART_NUM 3
// #define CONFIG_CPU_FREQUENCY 90315789 // #define CONFIG_CPU_FREQUENCY 90315789
#define CONFIG_CPU_FREQUENCY 88000000 #define CONFIG_CPU_FREQUENCY 96000000
//#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
@@ -43,7 +43,11 @@
#define CONFIG_UART_BAUDRATE 115200 #define CONFIG_UART_BAUDRATE 115200
#define CONFIG_UART_DEADLOCKABLE #define CONFIG_UART_DEADLOCKABLE
#define SSP_CLK_DIVISOR 2 #define SSP_CLK_DIVISOR_FAST 2
#define SSP_CLK_DIVISOR_SLOW 250
#define SSP_CLK_DIVISOR_FPGA_FAST 6
#define SSP_CLK_DIVISOR_FPGA_SLOW 20
#define SNES_RESET_REG LPC_GPIO1 #define SNES_RESET_REG LPC_GPIO1
#define SNES_RESET_BIT 26 #define SNES_RESET_BIT 26
@@ -64,11 +68,7 @@
#define FPGA_MCU_RDY_BIT 9 #define FPGA_MCU_RDY_BIT 9
#define QSORT_MAXELEM 2048 #define QSORT_MAXELEM 2048
#define SORT_STRLEN 256
#define CLTBL_SIZE 100 #define CLTBL_SIZE 100
#define DIR_FILE_MAX 16380
#define SSP_REGS LPC_SSP0 #define SSP_REGS LPC_SSP0
#define SSP_PCLKREG PCLKSEL1 #define SSP_PCLKREG PCLKSEL1
// 1: PCLKSEL0 // 1: PCLKSEL0
@@ -96,7 +96,4 @@
#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

@@ -55,7 +55,7 @@ DRESULT disk_read (BYTE, BYTE*, DWORD, BYTE);
#if _READONLY == 0 #if _READONLY == 0
DRESULT disk_write (BYTE, const BYTE*, DWORD, BYTE); DRESULT disk_write (BYTE, const BYTE*, DWORD, BYTE);
#endif #endif
DRESULT disk_ioctl (BYTE, BYTE, void*); #define disk_ioctl(a,b,c) RES_OK
void disk_init(void); void disk_init(void);

View File

@@ -3644,7 +3644,6 @@ TCHAR* f_gets (
*p++ = c; *p++ = c;
n++; n++;
if (c == '\n') break; /* Break on EOL */ if (c == '\n') break; /* Break on EOL */
if (c == 0) break; /* Break on NUL */
} }
*p = 0; *p = 0;
return n ? buff : 0; /* When no data read (eof or error), return with error. */ return n ? buff : 0; /* When no data read (eof or error), return with error. */

View File

@@ -31,7 +31,7 @@
#include "ff.h" #include "ff.h"
#include "smc.h" #include "smc.h"
#include "fileops.h" #include "fileops.h"
#include "crc.h" #include "crc32.h"
#include "memory.h" #include "memory.h"
#include "led.h" #include "led.h"
#include "sort.h" #include "sort.h"
@@ -60,16 +60,15 @@ uint32_t scan_dir(char* path, FILINFO* fno_param, char mkdb, uint32_t this_dir_t
uint8_t len; uint8_t len;
TCHAR* fn; TCHAR* fn;
static unsigned char depth = 0; static unsigned char depth = 0;
static uint32_t crc, fncrc; static uint32_t crc;
static uint32_t db_tgt; static uint32_t db_tgt;
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;
uint32_t switched_dir_tgt = 0;
uint16_t numentries; uint16_t numentries;
uint32_t dirsize; uint32_t dirsize;
uint8_t pass = 0; uint8_t pass = 0;
@@ -77,7 +76,6 @@ uint32_t scan_dir(char* path, FILINFO* fno_param, char mkdb, uint32_t this_dir_t
char *size_units[3] = {" ", "k", "M"}; char *size_units[3] = {" ", "k", "M"};
uint32_t entry_fsize; uint32_t entry_fsize;
uint8_t entry_unit_idx; uint8_t entry_unit_idx;
uint16_t entrycnt;
dir_tgt = this_dir_tgt; dir_tgt = this_dir_tgt;
if(depth==0) { if(depth==0) {
@@ -93,18 +91,10 @@ uint32_t scan_dir(char* path, FILINFO* fno_param, char mkdb, uint32_t this_dir_t
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 < 2; pass++) {
if(pass) { if(pass) {
num_dirs_total++;
dirsize = 4*(numentries); dirsize = 4*(numentries);
if(((next_subdir_tgt + dirsize + 8) & 0xff0000) > (next_subdir_tgt & 0xff0000)) {
printf("switchdir! old=%lX ", next_subdir_tgt + dirsize + 4);
next_subdir_tgt &= 0xffff0000;
next_subdir_tgt += 0x00010004;
printf("new=%lx\n", next_subdir_tgt);
dir_tgt &= 0xffff0000;
dir_tgt += 0x00010004;
}
switched_dir_tgt = dir_tgt;
next_subdir_tgt += dirsize + 4; next_subdir_tgt += dirsize + 4;
if(parent_tgt) next_subdir_tgt += 4; if(parent_tgt) next_subdir_tgt += 4;
if(next_subdir_tgt > dir_end) { if(next_subdir_tgt > dir_end) {
@@ -112,7 +102,6 @@ uint32_t scan_dir(char* path, FILINFO* fno_param, char mkdb, uint32_t this_dir_t
} }
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, parent_tgt, next_subdir_tgt);
if(mkdb) { if(mkdb) {
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);
} }
@@ -141,30 +130,27 @@ uint32_t scan_dir(char* path, FILINFO* fno_param, char mkdb, uint32_t this_dir_t
dir_tgt += 4; dir_tgt += 4;
} }
len = strlen((char*)path); len = strlen((char*)path);
/* scan at most DIR_FILE_MAX entries per directory */ for (;;) {
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 == '.') || !(memcmp(fn, SYS_DIR_NAME, sizeof(SYS_DIR_NAME)))) continue;
if (fno.fattrib & AM_DIR) { if (fno.fattrib & AM_DIR) {
depth++; depth++;
if(depth < FS_MAX_DEPTH) { if(depth < FS_MAX_DEPTH) {
numentries++; numentries++;
if(pass && mkdb) { if(pass) {
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;
uint32_t old_db_tgt = 0;
if(mkdb) { if(mkdb) {
pathlen = strlen(path); uint16_t pathlen = strlen(path);
DBG_FS printf("d=%d Saving %lx to Address %lx [dir]\n", depth, db_tgt, dir_tgt); // 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 */
@@ -174,31 +160,22 @@ uint32_t scan_dir(char* path, FILINFO* fno_param, char mkdb, uint32_t this_dir_t
db_tgt += 0x00010000; db_tgt += 0x00010000;
printf("new=%lx\n", db_tgt); printf("new=%lx\n", db_tgt);
} }
// printf(" Saving dir descriptor to %lx tgt=%lx, path=%s\n", db_tgt, next_subdir_tgt, path);
/* 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:
- path name - path name
- pointer to sub dir structure - pointer to sub dir structure */
moved below */ sram_writelong((next_subdir_tgt-SRAM_MENU_ADDR), db_tgt);
old_db_tgt = db_tgt; sram_writebyte(len+1, db_tgt+sizeof(next_subdir_tgt));
sram_writeblock(path, db_tgt+sizeof(next_subdir_tgt)+sizeof(len), pathlen);
sram_writeblock("/\0", db_tgt + sizeof(next_subdir_tgt) + sizeof(len) + pathlen, 2);
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 */
uint32_t corrected_subdir_tgt = scan_dir(path, &fno, mkdb, next_subdir_tgt);
if(mkdb) {
DBG_FS printf(" Saving dir descriptor to %lx tgt=%lx, path=%s\n", old_db_tgt, corrected_subdir_tgt, path);
sram_writelong((corrected_subdir_tgt-SRAM_MENU_ADDR), old_db_tgt);
sram_writebyte(len+1, old_db_tgt+sizeof(next_subdir_tgt));
sram_writeblock(path, old_db_tgt+sizeof(next_subdir_tgt)+sizeof(len), pathlen);
sram_writeblock("/\0", old_db_tgt + sizeof(next_subdir_tgt) + sizeof(len) + pathlen, 2);
}
dir_tgt += 4;
/* was_empty = 0;*/
} else if(!mkdb) {
path[len]='/';
strncpy(path+len+1, (char*)fn, sizeof(fs_path)-len);
scan_dir(path, &fno, mkdb, next_subdir_tgt); scan_dir(path, &fno, mkdb, next_subdir_tgt);
dir_tgt += 4;
was_empty = 0;
} }
} }
depth--; depth--;
@@ -206,10 +183,10 @@ uint32_t scan_dir(char* path, FILINFO* fno_param, char mkdb, uint32_t this_dir_t
} else { } else {
SNES_FTYPE type = determine_filetype((char*)fn); SNES_FTYPE type = determine_filetype((char*)fn);
if(type != TYPE_UNKNOWN) { if(type != TYPE_UNKNOWN) {
num_files_total++;
numentries++; numentries++;
if(pass) { if(pass) {
if(mkdb) { if(mkdb) {
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);
@@ -217,7 +194,13 @@ uint32_t scan_dir(char* path, FILINFO* fno_param, char mkdb, uint32_t this_dir_t
switch(type) { switch(type) {
case TYPE_IPS: case TYPE_IPS:
case TYPE_SMC: case TYPE_SMC:
case TYPE_SPC: /* file_open_by_filinfo(&fno);
if(file_res){
printf("ZOMG NOOOO %d\n", file_res);
}
smc_id(&romprops);
file_close(); */
/* 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)) {
@@ -257,14 +240,14 @@ uint32_t scan_dir(char* path, FILINFO* fno_param, char mkdb, uint32_t this_dir_t
} }
} else { } else {
TCHAR* fn2 = fn; TCHAR* fn2 = fn;
fncrc = 0;
while(*fn2 != 0) { while(*fn2 != 0) {
fncrc += crc_xmodem_update(fncrc, *((unsigned char*)fn2++)); crc += crc32_update(crc, *((unsigned char*)fn2++));
}
crc += fncrc;
} }
} }
} }
/* printf("%s/%s\n", path, fn);
_delay_ms(50); */
}
} }
} else uart_putc(0x30+res); } else uart_putc(0x30+res);
} }
@@ -273,9 +256,7 @@ uint32_t scan_dir(char* path, FILINFO* fno_param, char mkdb, uint32_t this_dir_t
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; return crc;
else return switched_dir_tgt;
return was_empty; // tricky!
} }
@@ -290,14 +271,18 @@ SNES_FTYPE determine_filetype(char* filename) {
) { ) {
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")) {
return TYPE_SPC;
} }
/* later
if(!strcasecmp_P(ext+1, PSTR("SRM"))) {
return TYPE_SRM;
}
if(!strcasecmp_P(ext+1, PSTR("SPC"))) {
return TYPE_SPC;
}*/
return TYPE_UNKNOWN; return TYPE_UNKNOWN;
} }

View File

@@ -36,7 +36,7 @@
#include "ff.h" #include "ff.h"
#define FS_MAX_DEPTH (10) #define FS_MAX_DEPTH (10)
#define SYS_DIR_NAME ((const char*)"sd2snes") #define SYS_DIR_NAME ((const uint8_t*)"sd2snes")
typedef enum { typedef enum {
TYPE_UNKNOWN = 0, /* 0 */ TYPE_UNKNOWN = 0, /* 0 */
TYPE_SMC, /* 1 */ TYPE_SMC, /* 1 */

View File

@@ -98,44 +98,38 @@ void fpga_pgm(uint8_t* filename) {
uint8_t data; uint8_t data;
int i; int i;
tick_t timeout; tick_t timeout;
/* open configware file */
file_open(filename, FA_READ);
if(file_res) {
uart_putc('?');
uart_putc(0x30+file_res);
return;
}
do { do {
i=0; 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; timeout = getticks() + 100;
fpga_set_prog_b(0);
if(BITBAND(PROGBREG->FIOPIN, PROGBBIT)) {
printf("PROGB is stuck high!\n");
led_panic();
}
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_FPGA_NO_INITB); led_panic();
} }
}; };
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_FPGA_DONE_STUCK); led_panic();
}
} }
LPC_GPIO2->FIOMASK1 = ~(BV(0)); LPC_GPIO2->FIOMASK1 = ~(BV(0));
uart_putc('p'); //uart_putc('p');
uart_putc('C');
/* open configware file */
file_open(filename, FA_READ);
if(file_res) {
//uart_putc('?');
//uart_putc(0x30+file_res);
return;
}
//uart_putc('C');
for (;;) { for (;;) {
data = rle_file_getc(); data = rle_file_getc();
@@ -143,16 +137,16 @@ void fpga_pgm(uint8_t* filename) {
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("%s: %d bytes programmed\n", __func__, 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_FPGA_NOCONF); led_panic();
} }
printf("FPGA configured\n"); printf("%s: FPGA configured\n", __func__);
fpga_postinit(); fpga_postinit();
} }
@@ -166,42 +160,39 @@ void fpga_rompgm() {
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_FPGA_NO_INITB); led_panic();
} }
}; };
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_FPGA_DONE_STUCK); led_panic();
}
} }
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("%s: %d bytes programmed\n", __func__, 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_FPGA_NOCONF); led_panic();
} }
printf("FPGA configured\n"); printf("%s: FPGA configured\n", __func__);
fpga_postinit(); fpga_postinit();
} }

View File

@@ -1,6 +1,6 @@
/* sd2snes - SD card based universal cartridge for the SNES /* sd2snes - SD card based universal cartridge for the SNES
Copyright (C) 2009-2012 Maximilian Rehkopf <otakon@gmx.net> Copyright (C) 2009-2010 Maximilian Rehkopf <otakon@gmx.net>
uC firmware portion AVR firmware portion
Inspired by and based on code from sd2iec, written by Ingo Korb et al. Inspired by and based on code from sd2iec, written by Ingo Korb et al.
See sdcard.c|h, config.h. See sdcard.c|h, config.h.
@@ -143,13 +143,13 @@
#include "sdnative.h" #include "sdnative.h"
void fpga_spi_init(void) { void fpga_spi_init(void) {
spi_init(); spi_init(SPI_SPEED_FAST);
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(0x02);
FPGA_TX_BYTE((address>>8)&0xff); FPGA_TX_BYTE((address>>8)&0xff);
FPGA_TX_BYTE((address)&0xff); FPGA_TX_BYTE((address)&0xff);
FPGA_DESELECT(); FPGA_DESELECT();
@@ -157,7 +157,7 @@ void set_msu_addr(uint16_t address) {
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(0x01);
FPGA_TX_BYTE((address>>8)&0xff); FPGA_TX_BYTE((address>>8)&0xff);
FPGA_TX_BYTE((address)&0xff); FPGA_TX_BYTE((address)&0xff);
FPGA_DESELECT(); FPGA_DESELECT();
@@ -165,7 +165,7 @@ void set_dac_addr(uint16_t address) {
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(0x00);
FPGA_TX_BYTE((address>>16)&0xff); FPGA_TX_BYTE((address>>16)&0xff);
FPGA_TX_BYTE((address>>8)&0xff); FPGA_TX_BYTE((address>>8)&0xff);
FPGA_TX_BYTE((address)&0xff); FPGA_TX_BYTE((address)&0xff);
@@ -174,7 +174,7 @@ void set_mcu_addr(uint32_t address) {
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(0x20);
FPGA_TX_BYTE((mask>>16)&0xff); FPGA_TX_BYTE((mask>>16)&0xff);
FPGA_TX_BYTE((mask>>8)&0xff); FPGA_TX_BYTE((mask>>8)&0xff);
FPGA_TX_BYTE((mask)&0xff); FPGA_TX_BYTE((mask)&0xff);
@@ -183,7 +183,7 @@ void set_saveram_mask(uint32_t mask) {
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(0x10);
FPGA_TX_BYTE((mask>>16)&0xff); FPGA_TX_BYTE((mask>>16)&0xff);
FPGA_TX_BYTE((mask>>8)&0xff); FPGA_TX_BYTE((mask>>8)&0xff);
FPGA_TX_BYTE((mask)&0xff); FPGA_TX_BYTE((mask)&0xff);
@@ -192,13 +192,14 @@ void set_rom_mask(uint32_t mask) {
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(0x30 | (val & 0x0f));
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(0xF0); /* TEST */
FPGA_TX_BYTE(0x00); /* dummy */
uint8_t result = FPGA_RX_BYTE(); uint8_t result = FPGA_RX_BYTE();
FPGA_DESELECT(); FPGA_DESELECT();
return result; return result;
@@ -206,7 +207,8 @@ uint8_t fpga_test() {
uint16_t fpga_status() { uint16_t fpga_status() {
FPGA_SELECT(); FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_GETSTATUS); FPGA_TX_BYTE(0xF1); /* STATUS */
FPGA_TX_BYTE(0x00); /* dummy */
uint16_t result = (FPGA_RX_BYTE()) << 8; uint16_t result = (FPGA_RX_BYTE()) << 8;
result |= FPGA_RX_BYTE(); result |= FPGA_RX_BYTE();
FPGA_DESELECT(); FPGA_DESELECT();
@@ -214,50 +216,65 @@ uint16_t fpga_status() {
} }
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(0x60); /* DMA_RANGE */
FPGA_TX_BYTE(start>>8); FPGA_TX_BYTE(start>>8);
FPGA_TX_BYTE(start&0xff); FPGA_TX_BYTE(start&0xff);
FPGA_TX_BYTE(end>>8); FPGA_TX_BYTE(end>>8);
FPGA_TX_BYTE(end&0xff); FPGA_TX_BYTE(end&0xff);
//if(tgt==1 && (test=FPGA_RX_BYTE()) != 0x41) printf("!!!!!!!!!!!!!!! -%02x- \n", test);
FPGA_DESELECT(); FPGA_DESELECT();
} }
void fpga_sddma(uint8_t tgt, uint8_t partial) { void fpga_sddma(uint8_t tgt, uint8_t 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(0x40 | (tgt & 0x3) | ((partial & 1) << 2) ); /* DO DMA */
FPGA_TX_BYTE(0x00); /* dummy for falling DMA_EN edge */ FPGA_TX_BYTE(0x00); /* dummy for falling DMA_EN edge */
//if(tgt==1 && (test=FPGA_RX_BYTE()) != 0x41) printf("!!!!!!!!!!!!!!! -%02x- \n", test);
FPGA_DESELECT(); FPGA_DESELECT();
FPGA_SELECT(); FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_GETSTATUS); FPGA_TX_BYTE(0xF1); /* STATUS */
FPGA_TX_BYTE(0x00); /* dummy */
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((status=FPGA_RX_BYTE()) & 0x80) {
FPGA_RX_BYTE(); /* eat the 2nd status byte */ FPGA_RX_BYTE(); /* eat the 2nd status byte */
test++;
} }
DBG_SD printf("...complete\n"); DBG_SD printf("...complete\n");
FPGA_DESELECT(); FPGA_DESELECT();
// if(test<5)printf("loopy: %ld %02x\n", test, status);
BITBAND(SD_CLKREG->FIODIR, SD_CLKPIN) = 1; BITBAND(SD_CLKREG->FIODIR, SD_CLKPIN) = 1;
} }
void set_dac_vol(uint8_t volume) {
FPGA_SELECT();
FPGA_TX_BYTE(0x50);
FPGA_TX_BYTE(volume);
FPGA_TX_BYTE(0x00); /* latch rise */
FPGA_TX_BYTE(0x00); /* latch fall */
FPGA_DESELECT();
}
void dac_play() { void dac_play() {
FPGA_SELECT(); FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_DACPLAY); FPGA_TX_BYTE(0xe2);
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(0xe1);
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(0xe3);
FPGA_TX_BYTE(0x00); /* latch reset */ FPGA_TX_BYTE(0x00); /* latch reset */
FPGA_TX_BYTE(0x00); /* latch reset */ FPGA_TX_BYTE(0x00); /* latch reset */
FPGA_DESELECT(); FPGA_DESELECT();
@@ -265,7 +282,7 @@ void dac_reset() {
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(0xe4);
FPGA_TX_BYTE((address>>8) & 0xff); /* address hi */ FPGA_TX_BYTE((address>>8) & 0xff); /* address hi */
FPGA_TX_BYTE(address & 0xff); /* address lo */ FPGA_TX_BYTE(address & 0xff); /* address lo */
FPGA_TX_BYTE(0x00); /* latch reset */ FPGA_TX_BYTE(0x00); /* latch reset */
@@ -275,16 +292,26 @@ void msu_reset(uint16_t address) {
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(0xe0);
FPGA_TX_BYTE(set); FPGA_TX_BYTE(set);
FPGA_TX_BYTE(reset); FPGA_TX_BYTE(reset);
FPGA_TX_BYTE(0x00); /* latch reset */ FPGA_TX_BYTE(0x00); /* latch reset */
FPGA_DESELECT(); FPGA_DESELECT();
} }
uint8_t get_msu_volume() {
FPGA_SELECT();
FPGA_TX_BYTE(0xF4); /* MSU_VOLUME */
FPGA_TX_BYTE(0x00); /* dummy */
uint8_t result = FPGA_RX_BYTE();
FPGA_DESELECT();
return result;
}
uint16_t get_msu_track() { uint16_t get_msu_track() {
FPGA_SELECT(); FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_MSUGETTRACK); FPGA_TX_BYTE(0xF3); /* MSU_TRACK */
FPGA_TX_BYTE(0x00); /* dummy */
uint16_t result = (FPGA_RX_BYTE()) << 8; uint16_t result = (FPGA_RX_BYTE()) << 8;
result |= FPGA_RX_BYTE(); result |= FPGA_RX_BYTE();
FPGA_DESELECT(); FPGA_DESELECT();
@@ -293,7 +320,8 @@ uint16_t get_msu_track() {
uint32_t get_msu_offset() { uint32_t get_msu_offset() {
FPGA_SELECT(); FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_MSUGETADDR); FPGA_TX_BYTE(0xF2); /* MSU_OFFSET */
FPGA_TX_BYTE(0x00); /* dummy */
uint32_t result = (FPGA_RX_BYTE()) << 24; uint32_t result = (FPGA_RX_BYTE()) << 24;
result |= (FPGA_RX_BYTE()) << 16; result |= (FPGA_RX_BYTE()) << 16;
result |= (FPGA_RX_BYTE()) << 8; result |= (FPGA_RX_BYTE()) << 8;
@@ -304,8 +332,9 @@ uint32_t get_msu_offset() {
uint32_t get_snes_sysclk() { uint32_t get_snes_sysclk() {
FPGA_SELECT(); FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_GETSYSCLK); FPGA_TX_BYTE(0xFE); /* GET_SYSCLK */
FPGA_TX_BYTE(0x00); /* dummy (copy current sysclk count to register) */ FPGA_TX_BYTE(0x00); /* dummy */
FPGA_TX_BYTE(0x00); /* dummy */
uint32_t result = (FPGA_RX_BYTE()) << 24; uint32_t result = (FPGA_RX_BYTE()) << 24;
result |= (FPGA_RX_BYTE()) << 16; result |= (FPGA_RX_BYTE()) << 16;
result |= (FPGA_RX_BYTE()) << 8; result |= (FPGA_RX_BYTE()) << 8;
@@ -316,7 +345,7 @@ uint32_t get_snes_sysclk() {
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(0xe6);
FPGA_TX_BYTE(set); FPGA_TX_BYTE(set);
FPGA_TX_BYTE(reset); FPGA_TX_BYTE(reset);
FPGA_TX_BYTE(0x00); /* latch reset */ FPGA_TX_BYTE(0x00); /* latch reset */
@@ -325,7 +354,7 @@ void set_bsx_regs(uint8_t set, uint8_t reset) {
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(0xe5);
FPGA_TX_BYTE((time >> 48) & 0xff); FPGA_TX_BYTE((time >> 48) & 0xff);
FPGA_TX_BYTE((time >> 40) & 0xff); FPGA_TX_BYTE((time >> 40) & 0xff);
FPGA_TX_BYTE((time >> 32) & 0xff); FPGA_TX_BYTE((time >> 32) & 0xff);
@@ -339,7 +368,7 @@ void set_fpga_time(uint64_t time) {
void fpga_reset_srtc_state() { void fpga_reset_srtc_state() {
FPGA_SELECT(); FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_SRTCRESET); FPGA_TX_BYTE(0xe7);
FPGA_TX_BYTE(0x00); FPGA_TX_BYTE(0x00);
FPGA_TX_BYTE(0x00); FPGA_TX_BYTE(0x00);
FPGA_DESELECT(); FPGA_DESELECT();
@@ -347,7 +376,7 @@ void fpga_reset_srtc_state() {
void fpga_reset_dspx_addr() { void fpga_reset_dspx_addr() {
FPGA_SELECT(); FPGA_SELECT();
FPGA_TX_BYTE(FPGA_CMD_DSPRESETPTR); FPGA_TX_BYTE(0xe8);
FPGA_TX_BYTE(0x00); FPGA_TX_BYTE(0x00);
FPGA_TX_BYTE(0x00); FPGA_TX_BYTE(0x00);
FPGA_DESELECT(); FPGA_DESELECT();
@@ -355,7 +384,7 @@ void fpga_reset_dspx_addr() {
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(0xe9);
FPGA_TX_BYTE((data>>16)&0xff); FPGA_TX_BYTE((data>>16)&0xff);
FPGA_TX_BYTE((data>>8)&0xff); FPGA_TX_BYTE((data>>8)&0xff);
FPGA_TX_BYTE((data)&0xff); FPGA_TX_BYTE((data)&0xff);
@@ -366,7 +395,7 @@ void fpga_write_dspx_pgm(uint32_t data) {
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(0xea);
FPGA_TX_BYTE((data>>8)&0xff); FPGA_TX_BYTE((data>>8)&0xff);
FPGA_TX_BYTE((data)&0xff); FPGA_TX_BYTE((data)&0xff);
FPGA_TX_BYTE(0x00); FPGA_TX_BYTE(0x00);
@@ -376,7 +405,7 @@ void fpga_write_dspx_dat(uint16_t data) {
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 ? 0xeb : 0xec);
FPGA_TX_BYTE(0x00); FPGA_TX_BYTE(0x00);
FPGA_DESELECT(); FPGA_DESELECT();
} }
@@ -384,7 +413,7 @@ void fpga_dspx_reset(uint8_t reset) {
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(0xed);
FPGA_TX_BYTE(feat); FPGA_TX_BYTE(feat);
FPGA_DESELECT(); FPGA_DESELECT();
} }
@@ -392,7 +421,7 @@ void fpga_set_features(uint8_t feat) {
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(0xee);
FPGA_TX_BYTE(data); FPGA_TX_BYTE(data);
FPGA_DESELECT(); FPGA_DESELECT();
} }

View File

@@ -47,6 +47,9 @@
#define FPGA_TX_BLOCK(x,y) spi_tx_block(x,y) #define FPGA_TX_BLOCK(x,y) spi_tx_block(x,y)
#define FPGA_RX_BLOCK(x,y) spi_rx_block(x,y) #define FPGA_RX_BLOCK(x,y) spi_rx_block(x,y)
#define FPGA_SPI_FAST() spi_set_speed(SPI_SPEED_FPGA_FAST)
#define FPGA_SPI_SLOW() spi_set_speed(SPI_SPEED_FPGA_SLOW)
#define FEAT_213F (1 << 4) #define FEAT_213F (1 << 4)
#define FEAT_MSU1 (1 << 3) #define FEAT_MSU1 (1 << 3)
#define FEAT_SRTC (1 << 2) #define FEAT_SRTC (1 << 2)
@@ -57,44 +60,6 @@
#define FPGA_WAIT_RDY() do {while(BITBAND(SSP_REGS->SR, SSP_BSY)); while(!BITBAND(FPGA_MCU_RDY_REG->FIOPIN, FPGA_MCU_RDY_BIT));} while (0) #define FPGA_WAIT_RDY() do {while(BITBAND(SSP_REGS->SR, SSP_BSY)); while(!BITBAND(FPGA_MCU_RDY_REG->FIOPIN, FPGA_MCU_RDY_BIT));} while (0)
/* command parameters */
#define FPGA_MEM_AUTOINC (0x8)
#define FPGA_SDDMA_PARTIAL (0x4)
#define FPGA_TGT_MEM (0x0)
#define FPGA_TGT_DACBUF (0x1)
#define FPGA_TGT_MSUBUF (0x2)
/* commands */
#define FPGA_CMD_SETADDR (0x00)
#define FPGA_CMD_SETROMMASK (0x10)
#define FPGA_CMD_SETRAMMASK (0x20)
#define FPGA_CMD_SETMAPPER(x) (0x30 | (x & 15))
#define FPGA_CMD_SDDMA (0x40)
#define FPGA_CMD_SDDMA_RANGE (0x60)
#define FPGA_CMD_READMEM (0x80)
#define FPGA_CMD_WRITEMEM (0x90)
#define FPGA_CMD_MSUSETBITS (0xe0)
#define FPGA_CMD_DACPAUSE (0xe1)
#define FPGA_CMD_DACPLAY (0xe2)
#define FPGA_CMD_DACRESETPTR (0xe3)
#define FPGA_CMD_MSUSETPTR (0xe4)
#define FPGA_CMD_RTCSET (0xe5)
#define FPGA_CMD_BSXSETBITS (0xe6)
#define FPGA_CMD_SRTCRESET (0xe7)
#define FPGA_CMD_DSPRESETPTR (0xe8)
#define FPGA_CMD_DSPWRITEPGM (0xe9)
#define FPGA_CMD_DSPWRITEDAT (0xea)
#define FPGA_CMD_DSPRESET (0xeb)
#define FPGA_CMD_DSPUNRESET (0xec)
#define FPGA_CMD_SETFEATURE (0xed)
#define FPGA_CMD_SET213F (0xee)
#define FPGA_CMD_TEST (0xf0)
#define FPGA_CMD_GETSTATUS (0xf1)
#define FPGA_CMD_MSUGETADDR (0xf2)
#define FPGA_CMD_MSUGETTRACK (0xf3)
#define FPGA_CMD_GETSYSCLK (0xfe)
#define FPGA_CMD_ECHO (0xff)
void fpga_spi_init(void); void fpga_spi_init(void);
uint8_t fpga_test(void); uint8_t fpga_test(void);
uint16_t fpga_status(void); uint16_t fpga_status(void);
@@ -103,6 +68,7 @@ void spi_sd(void);
void spi_none(void); void spi_none(void);
void set_mcu_addr(uint32_t); void set_mcu_addr(uint32_t);
void set_dac_addr(uint16_t); void set_dac_addr(uint16_t);
void set_dac_vol(uint8_t);
void dac_play(void); void dac_play(void);
void dac_pause(void); void dac_pause(void);
void dac_reset(void); void dac_reset(void);
@@ -114,6 +80,7 @@ void set_rom_mask(uint32_t);
void set_mapper(uint8_t val); void set_mapper(uint8_t val);
void fpga_sddma(uint8_t tgt, uint8_t partial); void fpga_sddma(uint8_t tgt, uint8_t partial);
void fpga_set_sddma_range(uint16_t start, uint16_t end); void fpga_set_sddma_range(uint16_t start, uint16_t end);
uint8_t get_msu_volume(void);
uint16_t get_msu_track(void); uint16_t get_msu_track(void);
uint32_t get_msu_offset(void); uint32_t get_msu_offset(void);
uint32_t get_snes_sysclk(void); uint32_t get_snes_sysclk(void);

View File

@@ -85,12 +85,12 @@ void toggle_write_led() {
writeled(~led_writeledstate); writeled(~led_writeledstate);
} }
void led_panic(uint8_t led_states) { void led_panic() {
led_std(); led_std();
while(1) { while(1) {
rdyled((led_states >> 2) & 1); rdyled(1);
readled((led_states >> 1) & 1); readled(1);
writeled(led_states & 1); writeled(1);
delay_ms(100); delay_ms(100);
rdyled(0); rdyled(0);
readled(0); readled(0);

View File

@@ -3,12 +3,6 @@
#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);
@@ -19,7 +13,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(uint8_t led_states); void led_panic(void);
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 "adapter_nsrst_delay" replace it with: #if your OpenOCD version rejects "jtag_nsrst_delay" replace it with:
#jtag_nsrst_delay 200 #adapter_nsrst_delay 200
adapter_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
@@ -39,7 +39,7 @@ 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_m -chain-position $_TARGETNAME -event reset-init 0 target create $_TARGETNAME cortex_m3 -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)
# and 16K more on AHB, in the ARMv7-M "SRAM" area, (at 0x2007c000). # and 16K more on AHB, in the ARMv7-M "SRAM" area, (at 0x2007c000).
@@ -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

@@ -48,14 +48,14 @@ 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)
{ {
/* Start by initial configuration, needed in all cases */
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;
@@ -71,46 +71,66 @@ int main(void)
LPC_PINCON->PINMODE0 = BV(0) | BV(1) | BV(2) | BV(3); LPC_PINCON->PINMODE0 = BV(0) | BV(1) | BV(2) | BV(3);
clock_disconnect(); clock_disconnect();
/* First init all SNES functions */
snes_init(); snes_init();
snes_reset(1); snes_reset(1); /* Maintain RESET UP, to prevent SNES to start */
/* Init all other parts */
power_init(); power_init();
timer_init(); timer_init();
uart_init(); uart_init();
fpga_spi_init(); fpga_spi_init();
spi_preinit(); spi_preinit();
led_init(); 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();
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();
sdn_init(); sdn_init();
printf("\n\nsd2snes mk.2\n============\nfw ver.: " CONFIG_VERSION "\ncpu clock: %d Hz\n", CONFIG_CPU_FREQUENCY);
/* Banner */
printf("\n\nsd2snes mk.2\n============\nfw ver.: " CONFIG_VERSION "\nfwver: %d\ncpu clock: %d Hz\n", CONFIG_FWVER, CONFIG_CPU_FREQUENCY);
printf("PCONP=%lx\n", LPC_SC->PCONP); printf("PCONP=%lx\n", LPC_SC->PCONP);
file_init(); file_init();
cic_init(0); cic_init(0);
/* FPGA Initialisation */
/* setup timer (fpga clk) */ /* setup timer (fpga clk) */
LPC_TIM3->TCR=2;
LPC_TIM3->CTCR = 0; LPC_TIM3->CTCR = 0;
LPC_TIM3->PR=0;
LPC_TIM3->EMR = EMC0TOGGLE; LPC_TIM3->EMR = EMC0TOGGLE;
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) {
if(disk_state == DISK_CHANGED) { /* Should test SRAM here */
while(1)
{
if(disk_state == DISK_CHANGED)
{
sdn_init(); sdn_init();
newcard = 1; newcard = 1;
} }
load_bootrle(SRAM_MENU_ADDR); load_bootrle(SRAM_MENU_ADDR);
set_saveram_mask(0x1fff); set_saveram_mask(0x1fff);
set_rom_mask(0x3fffff); set_rom_mask(0x3fffff);
set_mapper(0x7); set_mapper(0x7);
/* Unlock SNES */
snes_reset(0); snes_reset(0);
while(get_cic_state() == CIC_FAIL) {
/* Check CIC status */
while(get_cic_state() == CIC_FAIL)
{
rdyled(0); rdyled(0);
readled(0); readled(0);
writeled(0); writeled(0);
@@ -120,9 +140,14 @@ printf("PCONP=%lx\n", LPC_SC->PCONP);
writeled(1); writeled(1);
delay_ms(500); delay_ms(500);
} }
fpga_pgm((uint8_t*)"/sd2snes/fpga_base.bit");
sram_memtest();
/* some sanity checks */ /* some sanity checks */
uint8_t card_go = 0; uint8_t card_go = 0;
while(!card_go) { while(!card_go)
{
if(disk_status(0) & (STA_NOINIT|STA_NODISK)) if(disk_status(0) & (STA_NOINIT|STA_NODISK))
{ {
snes_bootprint(" No SD Card found! \0"); snes_bootprint(" No SD Card found! \0");
@@ -130,6 +155,7 @@ printf("PCONP=%lx\n", LPC_SC->PCONP);
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");
@@ -142,73 +168,85 @@ printf("PCONP=%lx\n", LPC_SC->PCONP);
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);
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; uint32_t saved_dir_id;
get_db_id(&saved_dir_id); get_db_id(&saved_dir_id);
uint32_t mem_dir_id = sram_readlong(SRAM_DIRID); uint32_t mem_dir_id = sram_readlong(SRAM_DIRID);
uint32_t 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) if((get_db_id(&saved_dir_id) != FR_OK) || saved_dir_id != curr_dir_id)
|| saved_dir_id != curr_dir_id) { {
/* 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...");
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; 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("endaddr: 0x%lX dirend: 0x%lX\n", endaddr, direndaddr);
printf("sorting database...");
snes_bootprint(" sorting database ... \0"); snes_bootprint(" sorting database ... \0");
sort_all_dir(direndaddr); sort_all_dir(direndaddr);
printf("done\n"); printf("done\n");
snes_bootprint(" saving database ... \0"); snes_bootprint(" saving database ... \0");
save_sram((uint8_t*)"/sd2snes/sd2snes.db", endaddr-SRAM_DB_ADDR, SRAM_DB_ADDR); save_sram((uint8_t*)"/sd2snes/sd2snes.db", endaddr-SRAM_DB_ADDR, SRAM_DB_ADDR);
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");
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"); load_sram((uint8_t*)"/sd2snes/sd2snes.db", SRAM_DB_ADDR);
load_sram_offload((uint8_t*)"/sd2snes/sd2snes.db", SRAM_DB_ADDR); load_sram((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"); snes_bootprint(" same card, loading db... \0");
printf("same card, loading db...\n"); printf("same card, loading db...\n");
fpga_pgm((uint8_t*)"/sd2snes/fpga_base.bit"); load_sram((uint8_t*)"/sd2snes/sd2snes.db", SRAM_DB_ADDR);
load_sram_offload((uint8_t*)"/sd2snes/sd2snes.db", SRAM_DB_ADDR); load_sram((uint8_t*)"/sd2snes/sd2snes.dir", SRAM_DIR_ADDR);
load_sram_offload((uint8_t*)"/sd2snes/sd2snes.dir", SRAM_DIR_ADDR);
} }
/* cli_loop(); */
/* load menu */
#if 1
cli_loop();
#endif
/* load menu */
fpga_pgm((uint8_t*)"/sd2snes/fpga_base.bit");
fpga_dspx_reset(1); fpga_dspx_reset(1);
uart_putc('('); uart_putc('(');
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 */
@@ -219,13 +257,16 @@ printf("PCONP=%lx\n", LPC_SC->PCONP);
sram_writebyte(0, SRAM_CMD_ADDR); sram_writebyte(0, SRAM_CMD_ADDR);
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(0x20110401000000LL);
set_fpga_time(0x20120701000000LL); set_fpga_time(0x20110401000000LL);
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());
@@ -233,28 +274,33 @@ printf("PCONP=%lx\n", LPC_SC->PCONP);
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);
fpga_reset_srtc_state(); delay_ms(1);
delay_ms(SNES_RESET_PULSELEN_MS);
sram_writebyte(32, SRAM_CMD_ADDR);
snes_reset(0); snes_reset(0);
uint8_t cmd = 0; uint8_t cmd = 0;
uint64_t btime = 0; uint64_t btime = 0;
uint32_t filesize=0; uint32_t filesize=0;
sram_writebyte(32, SRAM_CMD_ADDR);
printf("test sram\n"); printf("test sram\n");
while(!sram_reliable()) cli_entrycheck(); while(!sram_reliable()) cli_entrycheck();
printf("ok\n"); printf("ok\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('-'); 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);
@@ -262,8 +308,8 @@ printf("PCONP=%lx\n", LPC_SC->PCONP);
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);
@@ -272,40 +318,30 @@ printf("PCONP=%lx\n", LPC_SC->PCONP);
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:
/* load SPC file */
get_selected_name(file_lfn);
printf("Selected name: %s\n", file_lfn);
filesize = load_spc(file_lfn, SRAM_SPC_DATA_ADDR, SRAM_SPC_HEADER_ADDR);
cmd=0; /* stay in menu loop */
break;
case SNES_CMD_RESET:
/* process RESET request from SNES */
printf("RESET requested by SNES\n");
snes_reset_pulse();
cmd=0; /* stay in menu loop */
break;
case SNES_CMD_LOADLAST: 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("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 && msu1_loop())
while(!msu1_loop()); {
prepare_reset(); prepare_reset();
continue; continue;
} }
@@ -346,20 +382,25 @@ printf("PCONP=%lx\n", LPC_SC->PCONP);
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

@@ -54,12 +54,11 @@ void sram_hexdump(uint32_t addr, uint32_t len) {
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 */
@@ -75,12 +74,10 @@ uint8_t sram_readbyte(uint32_t addr) {
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 */
@@ -92,7 +89,6 @@ 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) {
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 */
@@ -116,7 +112,6 @@ 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;
} }
@@ -133,7 +128,6 @@ 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;
} }
@@ -169,21 +163,7 @@ void sram_readblock(void* buf, uint32_t addr, uint16_t size) {
FPGA_DESELECT(); FPGA_DESELECT();
} }
void sram_readstrn(void* buf, uint32_t addr, uint16_t size) {
uint16_t count=size;
uint8_t* tgt = buf;
set_mcu_addr(addr);
FPGA_SELECT();
FPGA_TX_BYTE(0x88); /* READ */
while(count--) {
FPGA_WAIT_RDY();
if(!(*(tgt++) = FPGA_RX_BYTE())) break;
}
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);
@@ -198,11 +178,11 @@ void sram_writeblock(void* buf, uint32_t addr, uint16_t size) {
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("Loading: %s\n", filename);
file_open(filename, FA_READ); file_open(filename, FA_READ);
if(file_res) { if(file_res) {
uart_putc('?'); uart_putc('?');
@@ -217,23 +197,19 @@ uint32_t load_rom(uint8_t* filename, uint32_t base_addr, uint8_t flags) {
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;
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 (file_res || !bytes_read) break;
if(!(count++ % 512)) { 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;
@@ -242,8 +218,6 @@ uint32_t load_rom(uint8_t* filename, uint32_t base_addr, uint8_t flags) {
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);
printf("attempting to load BS data file /sd2snes/bsxpage.bin...\n");
load_sram_offload((uint8_t*)"/sd2snes/bsxpage.bin", 0x900000);
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;
@@ -283,9 +257,6 @@ uint32_t load_rom(uint8_t* filename, uint32_t base_addr, uint8_t flags) {
rammask = romprops.ramsize_bytes - 1; rammask = romprops.ramsize_bytes - 1;
} }
rommask = romprops.romsize_bytes - 1; rommask = romprops.romsize_bytes - 1;
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); 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);
@@ -317,90 +288,15 @@ uint32_t load_rom(uint8_t* filename, uint32_t base_addr, uint8_t flags) {
if(flags & LOADROM_WITH_RESET) { if(flags & LOADROM_WITH_RESET) {
fpga_dspx_reset(1); fpga_dspx_reset(1);
snes_reset_pulse(); snes_reset(1);
delay_ms(10);
snes_reset(0);
fpga_dspx_reset(0); fpga_dspx_reset(0);
} }
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) {
DWORD filesize;
UINT bytes_read;
uint8_t data;
UINT j;
printf("%s\n", filename);
file_open(filename, FA_READ); /* Open SPC file */
if(file_res) return 0;
filesize = file_handle.fsize;
if (filesize < 65920) { /* At this point, we care about filesize only */
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 */
return 0;
}
set_mcu_addr(spc_data_addr);
f_lseek(&file_handle, 0x100L); /* Load 64K data segment */
for(;;) {
bytes_read = file_read();
if (file_res || !bytes_read) break;
FPGA_SELECT();
FPGA_TX_BYTE(0x98);
for(j=0; j<bytes_read; j++) {
FPGA_TX_BYTE(file_buf[j]);
FPGA_WAIT_RDY();
}
FPGA_DESELECT();
}
file_close();
file_open(filename, FA_READ); /* Reopen SPC file to reset file_getc state*/
set_mcu_addr(spc_header_addr);
f_lseek(&file_handle, 0x0L); /* Load 256 bytes header */
FPGA_SELECT();
FPGA_TX_BYTE(0x98);
for (j = 0; j < 256; j++) {
data = file_getc();
FPGA_TX_BYTE(data);
FPGA_WAIT_RDY();
}
FPGA_DESELECT();
file_close();
file_open(filename, FA_READ); /* Reopen SPC file to reset file_getc state*/
set_mcu_addr(spc_header_addr+0x100);
f_lseek(&file_handle, 0x10100L); /* Load 128 DSP registers */
FPGA_SELECT();
FPGA_TX_BYTE(0x98);
for (j = 0; j < 128; j++) {
data = file_getc();
FPGA_TX_BYTE(data);
FPGA_WAIT_RDY();
}
FPGA_DESELECT();
file_close(); /* Done ! */
/* clear echo buffer to avoid artifacts */
uint8_t esa = sram_readbyte(spc_header_addr+0x100+0x6d);
uint8_t edl = sram_readbyte(spc_header_addr+0x100+0x7d);
uint8_t flg = sram_readbyte(spc_header_addr+0x100+0x6c);
if(!(flg & 0x20) && (edl & 0x0f)) {
int echo_start = esa << 8;
int echo_length = (edl & 0x0f) << 11;
printf("clearing echo buffer %04x-%04x...\n", echo_start, echo_start+echo_length-1);
sram_memset(spc_data_addr+echo_start, echo_length, 0);
}
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;
@@ -485,6 +381,7 @@ uint32_t load_bootrle(uint32_t base_addr) {
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);
@@ -501,7 +398,7 @@ void save_sram(uint8_t* filename, uint32_t sram_size, uint32_t base_addr) {
count++; count++;
} }
FPGA_DESELECT(); FPGA_DESELECT();
file_write(); num = file_write();
if(file_res) { if(file_res) {
uart_putc(0x30+file_res); uart_putc(0x30+file_res);
} }
@@ -548,9 +445,9 @@ uint8_t sram_reliable() {
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;
@@ -573,6 +470,99 @@ void sram_memset(uint32_t base_addr, uint32_t len, uint8_t val) {
FPGA_DESELECT(); FPGA_DESELECT();
} }
/* memtest functions */
uint8_t memtest_checkvalue(uint8_t value)
{
uint8_t ret = 0;
uint32_t idx, lasterr = 0, errwas = 0, errcount = 0;
uint8_t data;
set_saveram_mask(0x0);
set_rom_mask(0x0);
printf("%s: Set memory to 0x%02X...\n", __func__, value);
sram_memset(0x00000, 0x1000000, value);
printf("Checking... [");
set_mcu_addr(0x0);
FPGA_SELECT();
FPGA_WAIT_RDY();
FPGA_TX_BYTE(0x88);
for(idx = 0; idx < 0x1000000; idx++)
{
FPGA_WAIT_RDY();
data = FPGA_RX_BYTE();
if ((idx % 0x100000) == 0)
uart_putc('.');
if ((idx % 0x10000) == 0)
toggle_read_led();
if (data != value)
{
//printf("%06x [%02x],", idx, data);
lasterr = idx;
errwas = data;
errcount++;
writeled(1);
ret = 0xFF;
}
}
printf("]\n");
if (errcount > 0)
printf("Found %d error(s) - last @ %x [%02x]\n", errcount, lasterr, errwas);
FPGA_DESELECT();
return ret;
}
uint8_t fpga_check(uint8_t value)
{
uint8_t ret = 0, read;
FPGA_SELECT();
FPGA_WAIT_RDY();
FPGA_TX_BYTE(0xFF);
FPGA_TX_BYTE(value);
FPGA_TX_BYTE(value);
read = FPGA_RX_BYTE();
if (read != value)
{
printf("%02x != %02x!!\n", value, read);
ret = 0xFF;
}
FPGA_DESELECT();
return ret;
}
uint8_t sram_memtest(void)
{
uint32_t ret;
printf("%s: Start memory test...\n", __func__);
writeled(0);
printf("Check FPGA Communication..\n");
printf("fpga_test = %02X\n", fpga_test());
printf("fpga_status = %04X\n", fpga_status());
ret = fpga_check(0x00);
ret |= fpga_check(0xFF);
ret |= fpga_check(0xAA);
ret |= fpga_check(0x55);
if (ret != 0x00)
{
printf("Error communicating with FPGA...\n");
//return ret;
}
ret = memtest_checkvalue(0x00);
ret |= memtest_checkvalue(0xFF);
ret |= memtest_checkvalue(0xAA);
ret |= memtest_checkvalue(0x55);
return ret;
}
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();
@@ -605,6 +595,7 @@ uint64_t sram_gettime(uint32_t base_addr) {
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;
@@ -628,6 +619,7 @@ void load_dspx(const uint8_t *filename, uint8_t coretype) {
} }
file_open((uint8_t*)filename, FA_READ); file_open((uint8_t*)filename, FA_READ);
filesize = file_handle.fsize;
if(file_res) { 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;

View File

@@ -30,33 +30,26 @@
#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)
#define SRAM_SAVE_ADDR (0xE00000L)
#define SRAM_ROM_ADDR ((0x000000L) & ~MASK_BITS) #define SRAM_MENU_ADDR (0xE00000L)
#define SRAM_SAVE_ADDR ((0x600000L) & ~MASK_BITS) #define SRAM_DB_ADDR (0xE40000L)
#define SRAM_DIR_ADDR (0xE10000L)
#define SRAM_MENU_ADDR ((0x500000L) & ~MASK_BITS) #define SRAM_CMD_ADDR (0xFF1000L)
#define SRAM_DIR_ADDR ((0x510000L) & ~MASK_BITS) #define SRAM_PARAM_ADDR (0xFF1004L)
#define SRAM_DB_ADDR ((0x580000L) & ~MASK_BITS) #define SRAM_STATUS_ADDR (0xFF1100L)
#define SRAM_SYSINFO_ADDR (0xFF1200L)
#define SRAM_SPC_DATA_ADDR ((0x7D0000L) & ~MASK_BITS) #define SRAM_LASTGAME_ADDR (0xFF1420L)
#define SRAM_SPC_HEADER_ADDR ((0x7E0000L) & ~MASK_BITS) #define SRAM_MENU_SAVE_ADDR (0xFF0000L)
#define SRAM_SCRATCHPAD (0xFFFF00L)
#define SRAM_MENU_SAVE_ADDR ((0x7F0000L) & ~MASK_BITS) #define SRAM_DIRID (0xFFFFF0L)
#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) #define SRAM_RELIABILITY_SCORE (0x100)
#define LOADROM_WITH_SRAM (1) #define LOADROM_WITH_SRAM (1)
#define LOADROM_WITH_RESET (2) #define LOADROM_WITH_RESET (2)
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);
uint32_t load_spc(uint8_t* filename, uint32_t spc_data_addr, uint32_t spc_header_addr);
uint32_t load_sram(uint8_t* filename, uint32_t base_addr); uint32_t load_sram(uint8_t* filename, uint32_t base_addr);
uint32_t load_sram_offload(uint8_t* filename, uint32_t base_addr); uint32_t load_sram_offload(uint8_t* filename, uint32_t base_addr);
uint32_t load_sram_rle(uint8_t* filename, uint32_t base_addr); uint32_t load_sram_rle(uint8_t* filename, uint32_t base_addr);
@@ -70,7 +63,6 @@ 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);
@@ -79,4 +71,6 @@ 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);
uint8_t sram_memtest(void);
#endif #endif

View File

@@ -13,132 +13,25 @@
#include "smc.h" #include "smc.h"
FIL msufile; FIL msufile;
FRESULT msu_res;
DWORD msu_cltbl[CLTBL_SIZE] IN_AHBRAM; DWORD msu_cltbl[CLTBL_SIZE] IN_AHBRAM;
DWORD pcm_cltbl[CLTBL_SIZE] IN_AHBRAM; DWORD pcm_cltbl[CLTBL_SIZE] IN_AHBRAM;
UINT msu_audio_bytes_read = 1024;
UINT msu_data_bytes_read = 1;
extern snes_romprops_t romprops; extern snes_romprops_t romprops;
uint32_t msu_loop_point = 0;
uint32_t msu_page1_start = 0x0000;
uint32_t msu_page2_start = 0x2000;
uint32_t msu_page_size = 0x2000;
uint16_t fpga_status_prev;
uint16_t fpga_status_now;
enum msu_reset_state { MSU_RESET_NONE = 0, MSU_RESET_SHORT, MSU_RESET_LONG };
void prepare_audio_track(uint16_t msu_track) {
/* open file, fill buffer */
char suffix[11];
f_close(&file_handle);
snprintf(suffix, sizeof(suffix), "-%d.pcm", msu_track);
strcpy((char*)file_buf, (char*)file_lfn);
strcpy(strrchr((char*)file_buf, (int)'.'), suffix);
DBG_MSU1 printf("filename: %s\n", file_buf);
if(f_open(&file_handle, (const TCHAR*)file_buf, FA_READ) == FR_OK) {
file_handle.cltbl = pcm_cltbl;
pcm_cltbl[0] = CLTBL_SIZE;
f_lseek(&file_handle, CREATE_LINKMAP);
f_lseek(&file_handle, 4L);
f_read(&file_handle, &msu_loop_point, 4, &msu_audio_bytes_read);
DBG_MSU1 printf("loop point: %ld samples\n", msu_loop_point);
ff_sd_offload=1;
sd_offload_tgt=1;
f_lseek(&file_handle, 8L);
set_dac_addr(0);
dac_pause();
dac_reset();
ff_sd_offload=1;
sd_offload_tgt=1;
f_read(&file_handle, file_buf, MSU_DAC_BUFSIZE, &msu_audio_bytes_read);
/* clear busy bit */
set_msu_status(0x00, 0x28); /* set no bits, reset audio_busy + audio_error */
} else {
f_close(&file_handle);
set_msu_status(0x08, 0x20); /* reset audio_busy, set audio_error */
}
}
void prepare_data(uint32_t msu_offset) {
DBG_MSU1 printf("Data requested! Offset=%08lx page1=%08lx page2=%08lx\n", msu_offset, msu_page1_start, msu_page2_start);
if( ((msu_offset < msu_page1_start)
|| (msu_offset >= msu_page1_start + msu_page_size))
&& ((msu_offset < msu_page2_start)
|| (msu_offset >= msu_page2_start + msu_page_size))) {
DBG_MSU1 printf("offset %08lx out of range (%08lx-%08lx, %08lx-%08lx), reload\n", msu_offset, msu_page1_start,
msu_page1_start+msu_page_size-1, msu_page2_start, msu_page2_start+msu_page_size-1);
/* "cache miss" */
/* fill buffer */
set_msu_addr(0x0);
sd_offload_tgt=2;
ff_sd_offload=1;
msu_res = f_lseek(&msufile, msu_offset);
DBG_MSU1 printf("seek to %08lx, res = %d\n", msu_offset, msu_res);
sd_offload_tgt=2;
ff_sd_offload=1;
msu_res = f_read(&msufile, file_buf, 16384, &msu_data_bytes_read);
DBG_MSU1 printf("read res = %d\n", msu_res);
DBG_MSU1 printf("read %d bytes\n", msu_data_bytes_read);
msu_reset(0x0);
msu_page1_start = msu_offset;
msu_page2_start = msu_offset + msu_page_size;
} else {
if (msu_offset >= msu_page1_start && msu_offset <= msu_page1_start + msu_page_size) {
msu_reset(0x0000 + msu_offset - msu_page1_start);
DBG_MSU1 printf("inside page1, new offset: %08lx\n", 0x0000 + msu_offset-msu_page1_start);
if(!(msu_page2_start == msu_page1_start + msu_page_size)) {
set_msu_addr(0x2000);
sd_offload_tgt=2;
ff_sd_offload=1;
f_read(&msufile, file_buf, 8192, &msu_data_bytes_read);
DBG_MSU1 printf("next page dirty (was: %08lx), loaded page2 (start now: ", msu_page2_start);
msu_page2_start = msu_page1_start + msu_page_size;
DBG_MSU1 printf("%08lx)\n", msu_page2_start);
}
} else if (msu_offset >= msu_page2_start && msu_offset <= msu_page2_start + msu_page_size) {
DBG_MSU1 printf("inside page2, new offset: %08lx\n", 0x2000 + msu_offset-msu_page2_start);
msu_reset(0x2000 + msu_offset - msu_page2_start);
if(!(msu_page1_start == msu_page2_start + msu_page_size)) {
set_msu_addr(0x0);
sd_offload_tgt=2;
ff_sd_offload=1;
f_read(&msufile, file_buf, 8192, &msu_data_bytes_read);
DBG_MSU1 printf("next page dirty (was: %08lx), loaded page1 (start now: ", msu_page1_start);
msu_page1_start = msu_page2_start + msu_page_size;
DBG_MSU1 printf("%08lx)\n", msu_page1_start);
}
} else printf("!!!WATWATWAT!!!\n");
}
/* clear bank bit to mask bank reset artifact */
fpga_status_now &= ~0x2000;
fpga_status_prev &= ~0x2000;
/* clear busy bit */
set_msu_status(0x00, 0x10);
}
int msu1_check_reset(void) { 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;
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; return 1;
} }
} else if(!resbutton && resbutton_prev) { /* release */
if(getticks() < rising_ticks + 99) {
result = MSU_RESET_SHORT;
}
} else {
result = MSU_RESET_NONE;
} }
resbutton_prev = resbutton; resbutton_prev = resbutton;
return result; return 0;
} }
int msu1_check(uint8_t* filename) { int msu1_check(uint8_t* filename) {
@@ -161,28 +54,23 @@ int msu1_check(uint8_t* filename) {
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(). */
UINT bytes_read = 1024;
UINT bytes_read2 = 1;
FRESULT res;
set_dac_vol(0x00);
while(fpga_status() & 0x4000); while(fpga_status() & 0x4000);
uint16_t fpga_status_prev = fpga_status();
uint16_t fpga_status_now = fpga_status();
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;
uint16_t msu_track = 0; uint16_t msu_track = 0;
uint32_t msu_offset = 0; uint32_t msu_offset = 0;
fpga_status_prev = fpga_status(); uint32_t msu_loop_point = 0;
fpga_status_now = fpga_status();
int msu_res;
/* set_msu_addr(0x0); uint32_t msu_page1_start = 0x0000;
msu_reset(0x0); uint32_t msu_page2_start = 0x2000;
ff_sd_offload=1; uint32_t msu_page_size = 0x2000;
sd_offload_tgt=2;
f_lseek(&msufile, 0L);
ff_sd_offload=1;
sd_offload_tgt=2;
f_read(&msufile, file_buf, 16384, &msu_data_bytes_read);
*/
set_dac_addr(dac_addr);
dac_pause();
dac_reset();
set_msu_addr(0x0); set_msu_addr(0x0);
msu_reset(0x0); msu_reset(0x0);
@@ -191,30 +79,34 @@ int msu1_loop() {
f_lseek(&msufile, 0L); f_lseek(&msufile, 0L);
ff_sd_offload=1; ff_sd_offload=1;
sd_offload_tgt=2; sd_offload_tgt=2;
f_read(&msufile, file_buf, 16384, &msu_data_bytes_read); f_read(&msufile, file_buf, 16384, &bytes_read2);
prepare_audio_track(0); set_dac_addr(dac_addr);
prepare_data(0); dac_pause();
dac_reset();
/* 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(1){
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");
uint8_t pageno = 0;
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;
pageno = 1;
} 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;
pageno = 2;
} }
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;
msu_res = f_read(&msufile, file_buf, 8192, &msu_data_bytes_read); res = f_read(&msufile, file_buf, 8192, &bytes_read2);
DBG_MSU1 printf("data buffer refilled. page=%d res=%d page1=%08lx page2=%08lx\n", pageno, msu_res, msu_page1_start, msu_page2_start); DBG_MSU1 printf("data buffer refilled. res=%d page1=%08lx page2=%08lx\n", res, msu_page1_start, msu_page2_start);
} }
/* Audio buffer refill */ /* Audio buffer refill */
@@ -227,21 +119,101 @@ int msu1_loop() {
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, &bytes_read);
} }
if(fpga_status_now & 0x0020) { if(fpga_status_now & 0x0020) {
char suffix[11];
/* 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);
prepare_audio_track(msu_track); /* open file, fill buffer */
f_close(&file_handle);
snprintf(suffix, sizeof(suffix), "-%d.pcm", msu_track);
strcpy((char*)file_buf, (char*)file_lfn);
strcpy(strrchr((char*)file_buf, (int)'.'), suffix);
DBG_MSU1 printf("filename: %s\n", file_buf);
f_open(&file_handle, (const TCHAR*)file_buf, FA_READ);
file_handle.cltbl = pcm_cltbl;
pcm_cltbl[0] = CLTBL_SIZE;
f_lseek(&file_handle, CREATE_LINKMAP);
f_lseek(&file_handle, 4L);
f_read(&file_handle, &msu_loop_point, 4, &bytes_read);
DBG_MSU1 printf("loop point: %ld samples\n", msu_loop_point);
ff_sd_offload=1;
sd_offload_tgt=1;
f_lseek(&file_handle, 8L);
set_dac_addr(0);
dac_pause();
dac_reset();
ff_sd_offload=1;
sd_offload_tgt=1;
f_read(&file_handle, file_buf, MSU_DAC_BUFSIZE, &bytes_read);
/* clear busy bit */
set_msu_status(0x00, 0x20); /* set no bits, reset bit 5 */
} }
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); DBG_MSU1 printf("Data requested! Offset=%08lx page1=%08lx page2=%08lx\n", msu_offset, msu_page1_start, msu_page2_start);
if( ((msu_offset < msu_page1_start)
|| (msu_offset >= msu_page1_start + msu_page_size))
&& ((msu_offset < msu_page2_start)
|| (msu_offset >= msu_page2_start + msu_page_size))) {
DBG_MSU1 printf("offset %08lx out of range (%08lx-%08lx, %08lx-%08lx), reload\n", msu_offset, msu_page1_start,
msu_page1_start+msu_page_size-1, msu_page2_start, msu_page2_start+msu_page_size-1);
/* "cache miss" */
/* fill buffer */
set_msu_addr(0x0);
sd_offload_tgt=2;
ff_sd_offload=1;
res = f_lseek(&msufile, msu_offset);
DBG_MSU1 printf("seek to %08lx, res = %d\n", msu_offset, res);
sd_offload_tgt=2;
ff_sd_offload=1;
res = f_read(&msufile, file_buf, 16384, &bytes_read2);
DBG_MSU1 printf("read res = %d\n", res);
DBG_MSU1 printf("read %d bytes\n", bytes_read2);
msu_reset(0x0);
msu_page1_start = msu_offset;
msu_page2_start = msu_offset + msu_page_size;
} else {
if (msu_offset >= msu_page1_start && msu_offset <= msu_page1_start + msu_page_size) {
msu_reset(0x0000 + msu_offset - msu_page1_start);
DBG_MSU1 printf("inside page1, new offset: %08lx\n", 0x0000 + msu_offset-msu_page1_start);
if(!(msu_page2_start == msu_page1_start + msu_page_size)) {
set_msu_addr(0x2000);
sd_offload_tgt=2;
ff_sd_offload=1;
f_read(&msufile, file_buf, 8192, &bytes_read2);
DBG_MSU1 printf("next page dirty (was: %08lx), loaded page2 (start now: ", msu_page2_start);
msu_page2_start = msu_page1_start + msu_page_size;
DBG_MSU1 printf("%08lx)\n", msu_page2_start);
}
} else if (msu_offset >= msu_page2_start && msu_offset <= msu_page2_start + msu_page_size) {
DBG_MSU1 printf("inside page2, new offset: %08lx\n", 0x2000 + msu_offset-msu_page2_start);
msu_reset(0x2000 + msu_offset - msu_page2_start);
if(!(msu_page1_start == msu_page2_start + msu_page_size)) {
set_msu_addr(0x0);
sd_offload_tgt=2;
ff_sd_offload=1;
f_read(&msufile, file_buf, 8192, &bytes_read2);
DBG_MSU1 printf("next page dirty (was: %08lx), loaded page1 (start now: ", msu_page1_start);
msu_page1_start = msu_page2_start + msu_page_size;
DBG_MSU1 printf("%08lx)\n", msu_page1_start);
}
} else printf("!!!WATWATWAT!!!\n");
}
/* clear bank bit to mask bank reset artifact */
fpga_status_now &= ~0x2000;
fpga_status_prev &= ~0x2000;
/* clear busy bit */
set_msu_status(0x00, 0x10);
} }
if(fpga_status_now & 0x0001) { if(fpga_status_now & 0x0001) {
@@ -269,7 +241,7 @@ 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(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) {
@@ -279,22 +251,18 @@ int msu1_loop() {
f_lseek(&file_handle, 8L+msu_loop_point*4); f_lseek(&file_handle, 8L+msu_loop_point*4);
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) - bytes_read, &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; bytes_read = MSU_DAC_BUFSIZE;
} }
} if(msu1_check_reset()) {
f_close(&file_handle);
DBG_MSU1 printf("Reset ");
if(msu_res == MSU_RESET_LONG) {
f_close(&msufile); f_close(&msufile);
DBG_MSU1 printf("to menu\n"); f_close(&file_handle);
return 1; return 1;
} }
DBG_MSU1 printf("game\n"); }
return 0;
} }
/* END OF MSU1 STUFF */ /* END OF MSU1 STUFF */

View File

@@ -21,6 +21,6 @@ void power_init() {
| BV(PCRTC) | BV(PCRTC)
| BV(PCGPIO) | BV(PCGPIO)
| BV(PCPWM1) | BV(PCPWM1)
| BV(PCUSB) // | BV(PCUSB)
; ;
} }

46
src/sdcard.h Normal file
View File

@@ -0,0 +1,46 @@
/* sd2iec - SD/MMC to Commodore serial bus interface/controller
Copyright (C) 2007-2010 Ingo Korb <ingo@akana.de>
Inspiration and low-level SD/MMC access based on code from MMC2IEC
by Lars Pontoppidan et al., see sdcard.c|h and config.h.
FAT filesystem access based on code from ChaN and Jim Brain, see ff.c|h.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License only.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
sdcard.h: Definitions for the SD/MMC access routines
*/
#ifndef SDCARD_H
#define SDCARD_H
#include "diskio.h"
#define SD_TX_BYTE(x) spi_tx_byte(x, SPI_SD);
#define SD_RX_BYTE(x) spi_rx_byte(x, SPI_SD);
#define SD_TX_BLOCK(x,y) spi_tx_block(x,y, SPI_SD);
#define SD_RX_BLOCK(x,y) spi_rx_block(x,y, SPI_SD);
/* These functions are weak-aliased to disk_... */
void sd_init(void);
DSTATUS sd_status(BYTE drv);
DSTATUS sd_initialize(BYTE drv);
DRESULT sd_read(BYTE drv, BYTE *buffer, DWORD sector, BYTE count);
DRESULT sd_write(BYTE drv, const BYTE *buffer, DWORD sector, BYTE count);
DRESULT sd_getinfo(BYTE drv, BYTE page, void *buffer);
void sd_changed(void);
#endif

View File

@@ -857,38 +857,10 @@ void write_block(uint32_t address, uint8_t* buf) {
} }
} }
/* send STOP_TRANSMISSION after multiple block write
* and reset during_blocktrans status */
void flush_write(void) {
cmd_fast(STOP_TRANSMISSION, 0, 0x61, NULL, rsp);
wait_busy();
during_blocktrans = TRANS_NONE;
}
// //
// Public functions // Public functions
// //
DRESULT sdn_ioctl(BYTE drv, BYTE cmd, void *buffer) {
DRESULT res;
if(drv >= MAX_CARDS) {
res = STA_NOINIT|STA_NODISK;
} else {
switch(cmd) {
case CTRL_SYNC:
flush_write();
res = RES_OK;
break;
default:
res = RES_PARERR;
}
}
return res;
}
DRESULT disk_ioctl(BYTE drv, BYTE cmd, void *buffer) __attribute__ ((weak, alias("sdn_ioctl")));
DRESULT sdn_read(BYTE drv, BYTE *buffer, DWORD sector, BYTE count) { DRESULT sdn_read(BYTE drv, BYTE *buffer, DWORD sector, BYTE count) {
uint8_t sec; uint8_t sec;
if(drv >= MAX_CARDS) { if(drv >= MAX_CARDS) {
@@ -904,7 +876,7 @@ DRESULT sdn_read(BYTE drv, BYTE *buffer, DWORD sector, BYTE count) {
} }
DRESULT disk_read(BYTE drv, BYTE *buffer, DWORD sector, BYTE count) __attribute__ ((weak, alias("sdn_read"))); DRESULT disk_read(BYTE drv, BYTE *buffer, DWORD sector, BYTE count) __attribute__ ((weak, alias("sdn_read")));
DSTATUS sdn_initialize(BYTE drv) { DRESULT sdn_initialize(BYTE drv) {
uint8_t rsp[17]; /* space for response */ uint8_t rsp[17]; /* space for response */
int rsplen; int rsplen;
@@ -933,7 +905,7 @@ DSTATUS sdn_initialize(BYTE drv) {
if((rsplen=cmd_slow(SEND_IF_COND, 0x000001aa, 0x87, NULL, rsp))) { if((rsplen=cmd_slow(SEND_IF_COND, 0x000001aa, 0x87, NULL, rsp))) {
DBG_SD printf("CMD8 response:\n"); DBG_SD printf("CMD8 response:\n");
DBG_SD uart_trace(rsp, 0, rsplen, 0); DBG_SD uart_trace(rsp, 0, rsplen);
hcs=1; hcs=1;
} }
while(1) { while(1) {

View File

@@ -22,7 +22,6 @@ DSTATUS sdn_initialize(BYTE drv);
DRESULT sdn_read(BYTE drv, BYTE *buffer, DWORD sector, BYTE count); DRESULT sdn_read(BYTE drv, BYTE *buffer, DWORD sector, BYTE count);
DRESULT sdn_write(BYTE drv, const BYTE *buffer, DWORD sector, BYTE count); DRESULT sdn_write(BYTE drv, const BYTE *buffer, DWORD sector, BYTE count);
DRESULT sdn_getinfo(BYTE drv, BYTE page, void *buffer); DRESULT sdn_getinfo(BYTE drv, BYTE page, void *buffer);
DRESULT sdn_ioctl(BYTE drv, BYTE cmd, void *buffer);
void sdn_changed(void); void sdn_changed(void);
uint8_t* sdn_getcid(void); uint8_t* sdn_getcid(void);

View File

@@ -59,7 +59,6 @@ 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;
@@ -95,15 +94,6 @@ void smc_id(snes_romprops_t* props) {
props->romsize_bytes = 0x100000; props->romsize_bytes = 0x100000;
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 */
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;
} }
} }
@@ -196,19 +186,12 @@ void smc_id(snes_romprops_t* props) {
} }
} }
if(header->romsize == 0 || header->romsize > 13) { if(header->romsize == 0 || header->romsize > 13) {
props->romsize_bytes = 1024; header->romsize = 13;
header->romsize = 0;
if(file_handle.fsize >= 1024) {
while(props->romsize_bytes < file_handle.fsize-1) {
header->romsize++;
props->romsize_bytes <<= 1;
}
}
} }
props->ramsize_bytes = (uint32_t)1024 << header->ramsize; props->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 > 32768 || props->ramsize_bytes < 2048) { if(props->ramsize_bytes > 32768 || props->ramsize_bytes < 2048) {
props->ramsize_bytes = 0; props->ramsize_bytes = 0;
} }

View File

@@ -84,7 +84,6 @@ 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

@@ -48,7 +48,7 @@ volatile int reset_pressed;
void prepare_reset() { void prepare_reset() {
snes_reset(1); snes_reset(1);
delay_ms(SNES_RESET_PULSELEN_MS); delay_ms(1);
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);
@@ -71,22 +71,12 @@ void snes_init() {
snes_reset(1); snes_reset(1);
} }
void snes_reset_pulse() {
snes_reset(1);
delay_ms(SNES_RESET_PULSELEN_MS);
snes_reset(0);
}
/* /*
* sets the SNES reset state. * sets the SNES reset state.
* *
* 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) {
if (state == 0)
printf("Releasing SNES RESET\n");
else
printf("Pull SNES RESET\n");
BITBAND(SNES_RESET_REG->FIODIR, SNES_RESET_BIT) = state; BITBAND(SNES_RESET_REG->FIODIR, SNES_RESET_BIT) = state;
} }
@@ -127,7 +117,7 @@ void snes_main_loop() {
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\n", saveram_crc);
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);
@@ -139,7 +129,7 @@ void snes_main_loop() {
writeled(1); writeled(1);
save_sram(file_lfn, romprops.ramsize_bytes, SRAM_SAVE_ADDR); save_sram(file_lfn, romprops.ramsize_bytes, SRAM_SAVE_ADDR);
didnotsave=0; didnotsave=0;
writeled(1); writeled(0);
} }
saveram_crc_old = saveram_crc; saveram_crc_old = saveram_crc;
} }
@@ -174,15 +164,12 @@ void get_selected_name(uint8_t* fn) {
sram_readblock(fn, addr + 7 + SRAM_MENU_ADDR, 256); sram_readblock(fn, addr + 7 + SRAM_MENU_ADDR, 256);
} }
void snes_bootprint(void* msg) void snes_bootprint(void* msg) {
{ printf("snes_boot: %s\n",msg);
printf("%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

@@ -31,20 +31,15 @@
#define SNES_CMD_SETRTC (2) #define SNES_CMD_SETRTC (2)
#define SNES_CMD_SYSINFO (3) #define SNES_CMD_SYSINFO (3)
#define SNES_CMD_LOADLAST (4) #define SNES_CMD_LOADLAST (4)
#define SNES_CMD_LOADSPC (5)
#define SNES_CMD_RESET (6)
#define MENU_ERR_OK (0) #define MENU_ERR_OK (0)
#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 (1)
uint8_t crc_valid; uint8_t crc_valid;
void prepare_reset(void); void prepare_reset(void);
void snes_init(void); void snes_init(void);
void snes_reset_pulse(void);
void snes_reset(int state); void snes_reset(int state);
uint8_t get_snes_reset(void); uint8_t get_snes_reset(void);
void snes_main_loop(void); void snes_main_loop(void);

View File

@@ -15,7 +15,7 @@
*/ */
uint32_t stat_getstring = 0; uint32_t stat_getstring = 0;
static char sort_str1[SORT_STRLEN+1], sort_str2[SORT_STRLEN+1]; static char sort_str1[21], sort_str2[21];
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*/
@@ -50,18 +50,13 @@ int sort_cmp_elem(const void* elem1, const void* elem2) {
if (!(el1 & 0x80000000) && (el2 & 0x80000000)) { if (!(el1 & 0x80000000) && (el2 & 0x80000000)) {
return 1; return 1;
} }
/*
if (*sort_str1 == '.') return -1; uint16_t cmp_i;
if (*sort_str2 == '.') return 1; for(cmp_i=0; cmp_i<8 && sort_long1[cmp_i] == sort_long2[cmp_i]; cmp_i++);
if(cmp_i==8) {
/* Do not compare trailing slashes of directory names */ return 0;
if ((el1 & 0x80000000) && (el2 & 0x80000000)) {
char *str1_slash = strrchr(sort_str1, '/');
char *str2_slash = strrchr(sort_str2, '/');
if(str1_slash != NULL) *str1_slash = 0;
if(str2_slash != NULL) *str2_slash = 0;
} }
return sort_long1[cmp_i]-sort_long2[cmp_i]; */
return strcasecmp(sort_str1, sort_str2); return strcasecmp(sort_str1, sort_str2);
} }
@@ -71,12 +66,13 @@ void sort_getstring_for_dirent(char *ptr, uint32_t addr) {
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_readblock(ptr, addr + 5 + leaf_offset + SRAM_MENU_ADDR, 20);
} 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_readblock(ptr, addr + 7 + leaf_offset + SRAM_MENU_ADDR, 20);
} }
ptr[20]=0;
} }
void sort_heapify(uint32_t addr, unsigned int i, unsigned int heapsize) void sort_heapify(uint32_t addr, unsigned int i, unsigned int heapsize)

View File

@@ -36,13 +36,21 @@ void spi_preinit() {
BITBAND(LPC_SC->SSP_PCLKREG, SSP_PCLKBIT) = 1; BITBAND(LPC_SC->SSP_PCLKREG, SSP_PCLKBIT) = 1;
} }
void spi_init() { void spi_init(spi_speed_t speed) {
/* 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);
/* set clock prescaler */ /* set clock prescaler */
SSP_REGS->CPSR = SSP_CLK_DIVISOR; if (speed == SPI_SPEED_FAST) {
SSP_REGS->CPSR = SSP_CLK_DIVISOR_FAST;
} else if (speed == SPI_SPEED_SLOW) {
SSP_REGS->CPSR = SSP_CLK_DIVISOR_SLOW;
} else if (speed == SPI_SPEED_FPGA_FAST) {
SSP_REGS->CPSR = SSP_CLK_DIVISOR_FPGA_FAST;
} else {
SSP_REGS->CPSR = SSP_CLK_DIVISOR_FPGA_SLOW;
}
/* Enable SSP */ /* Enable SSP */
SSP_REGS->CR1 = BV(1); SSP_REGS->CR1 = BV(1);
@@ -181,3 +189,25 @@ void spi_rx_block(void *ptr, unsigned int length) {
SSP_REGS->DMACR = 0; SSP_REGS->DMACR = 0;
} }
} }
void spi_set_speed(spi_speed_t speed) {
/* Wait until TX fifo is empty */
while (!BITBAND(SSP_REGS->SR, 0)) ;
/* Disable SSP (FIXME: Is this required?) */
SSP_REGS->CR1 = 0;
/* Change clock divisor */
if (speed == SPI_SPEED_FAST) {
SSP_REGS->CPSR = SSP_CLK_DIVISOR_FAST;
} else if (speed == SPI_SPEED_SLOW) {
SSP_REGS->CPSR = SSP_CLK_DIVISOR_SLOW;
} else if (speed == SPI_SPEED_FPGA_FAST) {
SSP_REGS->CPSR = SSP_CLK_DIVISOR_FPGA_FAST;
} else {
SSP_REGS->CPSR = SSP_CLK_DIVISOR_FPGA_SLOW;
}
/* Enable SSP */
SSP_REGS->CR1 = BV(1);
}

View File

@@ -42,7 +42,7 @@ typedef enum { SPI_SPEED_FAST, SPI_SPEED_SLOW, SPI_SPEED_FPGA_FAST, SPI_SPEED_FP
void spi_preinit(void); void spi_preinit(void);
/* Initialize SPI interface */ /* Initialize SPI interface */
void spi_init(void); void spi_init(spi_speed_t speed);
/* Transmit a single byte */ /* Transmit a single byte */
void spi_tx_byte(uint8_t data); void spi_tx_byte(uint8_t data);
@@ -59,6 +59,9 @@ uint8_t spi_rx_byte(void);
/* Receive a data block */ /* Receive a data block */
void spi_rx_block(void *data, unsigned int length); void spi_rx_block(void *data, unsigned int length);
/* Switch speed of SPI interface */
void spi_set_speed(spi_speed_t speed);
/* wait for SPI TX FIFO to become empty */ /* wait for SPI TX FIFO to become empty */
void spi_tx_sync(void); void spi_tx_sync(void);

View File

@@ -138,7 +138,7 @@ static int8_t parse_wordlist(char *wordlist) {
return -1; return -1;
} }
if (tolower((int)c) != tolower((int)*cur)) { if (tolower(c) != tolower(*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

@@ -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

@@ -1,366 +0,0 @@
/* ___DISCLAIMER___ */
#include <arm/NXP/LPC17xx/LPC17xx.h>
#include "bits.h"
#include "config.h"
#include "uart.h"
#include "timer.h"
#include "led.h"
#include "cli.h"
#include "fpga.h"
#include "fpga_spi.h"
#include "ff.h"
#include "fileops.h"
#include "crc32.h"
#include "diskio.h"
#include "cic.h"
#include "rtc.h"
#include "memory.h"
#include "snes.h"
#include "cli.h"
#include "tests.h"
#define PROGRESS ("-\\|/")
int test_sd() {
printf("SD test... please insert card\n=============================\n");
while(disk_status(0) & (STA_NOINIT|STA_NODISK)) cli_entrycheck();
file_open((uint8_t*)"/sd2snes/testfile.bin", FA_WRITE | FA_CREATE_ALWAYS);
if(file_res) {
printf("could not open /sd2snes/testfile.bin: Error %d\n", file_res);
printf("FAILED\n\n\n");
return FAILED;
}
uint32_t testval = 0x55AA55AA;
uint32_t crc = 0;
uint32_t count, blkcount;
for(count=0; count < 8192; count++) {
for(blkcount=0; blkcount < 512; blkcount++) {
file_buf[blkcount] = testval&0xff;
crc=crc32_update(crc, testval&0xff);
testval ^= (crc * (count + blkcount + 7)) - 1;
}
file_write();
}
printf("crc1 = %08lx ", crc);
file_close();
file_open((uint8_t*)"/sd2snes/testfile.bin", FA_READ);
uint32_t crc2 = 0;
for(count=0; count < 8192; count++) {
file_read();
for(blkcount=0; blkcount < 512; blkcount++) {
testval = file_buf[blkcount];
crc2 = crc32_update(crc2, testval&0xff);
}
}
file_close();
printf("crc2 = %08lx ", crc2);
if(crc==crc2) {
printf(" PASSED\n\n\n");
return PASSED;
} else {
printf(" FAILED\n\n\n");
return FAILED;
}
}
int test_cic() {
int cic_state = get_cic_state();
printf("CIC Test:\n=========\n");
printf("Current CIC state: %s\n", get_cic_statename(cic_state));
if(cic_state == CIC_FAIL) {
printf("CIC reports error, push reset...\n");
while((cic_state = get_cic_state()) == CIC_FAIL);
}
if(cic_state == CIC_OK) {
printf("CIC reports OK; no pair mode available. Provoking CIC error...\n");
cic_pair(1,1);
delay_ms(200);
cic_init(0);
printf("new CIC state: %s\n", get_cic_statename(get_cic_state()));
if(get_cic_state() == CIC_FAIL) {
printf("***Please reset SNES***\n");
int failcount=2;
while(failcount--) {
while(get_cic_state() == CIC_FAIL);
delay_ms(200);
}
if(get_cic_state() != CIC_FAIL) {
printf("PASSED\n\n\n");
return PASSED;
}
printf("CIC did not recover properly.\nFAILED\n");
return FAILED;
}
printf("FAILED\n\n\n");
return FAILED;
}
if(cic_state == CIC_SCIC) {
printf("CIC reports OK; pair mode available. Switching to pair mode...\n");
cic_init(1);
delay_ms(100);
cic_pair(0,0);
delay_ms(1000);
printf("new CIC state: %s\n", get_cic_statename(cic_state = get_cic_state()));
if(get_cic_state() != CIC_PAIR) {
printf("FAILED to switch to pair mode!!!\n");
return FAILED;
}
}
if(cic_state == CIC_PAIR) {
cic_init(1);
cic_pair(0,0);
printf("cycling modes, observe power LED color\n");
for(cic_state = 0; cic_state < 17; cic_state++) {
cic_videomode(cic_state & 1);
delay_ms(200);
}
}
printf("PASSED\n\n\n");
return PASSED;
}
int test_rtc() {
struct tm time;
printf("RTC Test\n========\n");
printf("setting clock to 2011-01-01 00:00:00\n");
set_bcdtime(0x20110101000000LL);
printf("waiting 5 seconds\n");
delay_ms(5000);
// uint64_t newtime = get_bcdtime();
printf("new time: ");
read_rtc(&time);
printtime(&time);
if((get_bcdtime() & 0xffffffffffffff) >= 0x20110101000004LL) {
printf("PASSED\n\n\n");
return PASSED;
} else printf("FAILED\n\n\n");
return FAILED;
}
int test_fpga() {
printf("FPGA test\n=========\n");
printf("configuring fpga...\n");
fpga_pgm((uint8_t*)"/sd2snes/test.bit");
printf("basic communication test...");
if(fpga_test() != FPGA_TEST_TOKEN) {
printf("FAILED\n\n\n");
return FAILED;
} else printf("PASSED\n\n\n");
return PASSED;
}
/*************************************************************************************/
/*************************************************************************************/
typedef struct memory_test
{
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);
fpga_select_mem(0);
FPGA_DESELECT();
delay_ms(1);
FPGA_SELECT();
delay_ms(1);
}
void rom_close(void)
{
}
unsigned int rom_read(unsigned int addr)
{
return sram_readbyte(addr);
}
void rom_write(unsigned int addr, unsigned int data)
{
sram_writebyte(data, addr);
}
memory_test rom = {
.name = "RAM0 (128Mbit)",
.a_len = 22,
.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;
}
}
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);
}
printf("Ok \n---- Check data lines...\n"
"----- ");
for (i = 0; i < test->d_len; i++) printf("%X", i);
printf("\n");
/* Check on 4 addresses, taken evenly */
#define TEST_NUM (10)
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));
read = test->read(j * a_mask/TEST_NUM);
if (read == 0)
{
printf("0");
ret |= 4;
goto next_data;
}
printf("x");
next_data:
test->write(j * a_mask/4, 0);
}
printf("]\n");
}
test->close();
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;
}
int test_clk() {
uint32_t sysclk[4];
int32_t diff, max_diff = 0;
int i, error=0;
printf("sysclk test\n===========\n");
printf("measuring SNES clock...\n");
for(i=0; i<4; i++) {
sysclk[i]=get_snes_sysclk();
if(sysclk[i] < 21000000 || sysclk[i] > 22000000) error = 1;
printf("%lu Hz ", sysclk[i]);
if(i) {
diff = sysclk[i] - sysclk[i-1];
if(diff < 0) diff = -diff;
if(diff > max_diff) max_diff = diff;
printf("diff = %ld max = %ld", diff, max_diff);
}
printf("\n");
delay_ms(1010);
}
if(error) {
printf("clock frequency out of range!\n");
}
if(diff > 1000000) {
printf("clock variation too great!\n");
error = 1;
}
printf(" CPUCLK: %lu\n", get_snes_cpuclk());
printf(" READCLK: %lu\n", get_snes_readclk());
printf(" WRITECLK: %lu\n", get_snes_writeclk());
printf(" PARDCLK: %lu\n", get_snes_pardclk());
printf(" PAWRCLK: %lu\n", get_snes_pawrclk());
printf(" REFRCLK: %lu\n", get_snes_refreshclk());
printf("ROMSELCLK: %lu\n", get_snes_romselclk());
if(error) {
printf("FAILED\n\n\n");
return FAILED;
}
printf("PASSED\n\n\n");
return PASSED;
}

View File

@@ -57,17 +57,9 @@ void timer_init(void) {
/* clear RIT mask */ /* clear RIT mask */
LPC_RIT->RIMASK = 0; /*xffffffff;*/ LPC_RIT->RIMASK = 0; /*xffffffff;*/
/* PCLK_RIT = CCLK */ /* PCLK = CCLK */
BITBAND(LPC_SC->PCLKSEL1, 27) = 0;
BITBAND(LPC_SC->PCLKSEL1, 26) = 1; BITBAND(LPC_SC->PCLKSEL1, 26) = 1;
/* PCLK_TIMER3 = CCLK/4 */
BITBAND(LPC_SC->PCLKSEL1, 15) = 0;
BITBAND(LPC_SC->PCLKSEL1, 14) = 0;
/* enable timer 3 */
BITBAND(LPC_SC->PCLKSEL1, PCLK_TIMER3) = 1; BITBAND(LPC_SC->PCLKSEL1, PCLK_TIMER3) = 1;
/* enable SysTick */ /* enable SysTick */
SysTick_Config((SysTick->CALIB & SysTick_CALIB_TENMS_Msk)); SysTick_Config((SysTick->CALIB & SysTick_CALIB_TENMS_Msk));
} }

View File

@@ -238,7 +238,7 @@ void uart_puthex(uint8_t num) {
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;
@@ -247,9 +247,8 @@ void uart_trace(void *ptr, uint16_t start, uint16_t len, uint32_t addr) {
data+=start; data+=start;
for(i=0;i<len;i+=16) { for(i=0;i<len;i+=16) {
uart_puthex((addr + start)>>16); uart_puthex(start>>8);
uart_puthex(((addr + start)>>8) & 0xff); uart_puthex(start&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++) {

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

@@ -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,49 +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;
if ( argc == 4 )
{
fpIn = fopen(argv[1], "rb");
fpOut = fopen(argv[2], "wt");
}
else if (argc == 3)
{
fpIn = fopen(argv[1], "rb");
fpOut = stdout;
}
else if ( argc == 2 )
{
fpIn = stdin;
fpOut = stdout;
}
else
{
fprintf(stderr, "usage: %s [infile] [outfile]\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

@@ -73,7 +73,7 @@ int main(int argc, char **argv) {
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, 10);
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);

BIN
src/utils/lpcchksum Executable file

Binary file not shown.

Binary file not shown.

View File

@@ -6,8 +6,8 @@
#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;
@@ -19,13 +19,13 @@ void xmodem_rxfile(FIL* fil) {
uart_putc(ASC_NAK); uart_putc(ASC_NAK);
} while (uart_getc() != ASC_SOH); } while (uart_getc() != ASC_SOH);
do { do {
/*blknum=*/uart_getc(); blknum=uart_getc();
/*blknum2=*/uart_getc(); blknum2=uart_getc();
for(count=0; count<XMODEM_BLKSIZE; count++) { 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);
@@ -33,7 +33,5 @@ void xmodem_rxfile(FIL* fil) {
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

@@ -33,17 +33,11 @@ module address(
output msu_enable, output msu_enable,
output srtc_enable, output srtc_enable,
output use_bsx, output use_bsx,
output bsx_tristate,
input [14:0] bsx_regs, input [14:0] bsx_regs,
output dspx_enable, output dspx_enable,
output dspx_dp_enable, output dspx_dp_enable,
output dspx_a0, output dspx_a0,
output r213f_enable, output r213f_enable
output snescmd_rd_enable,
output snescmd_wr_enable,
input [8:0] bs_page_offset,
input [9:0] bs_page,
input bs_page_enable
); );
parameter [2:0] parameter [2:0]
@@ -82,16 +76,16 @@ assign IS_SAVERAM = SAVERAM_MASK[0]
|| MAPPER == 3'b110 || MAPPER == 3'b110
|| MAPPER == 3'b111) || MAPPER == 3'b111)
? (!SNES_ADDR[22] ? (!SNES_ADDR[22]
& SNES_ADDR[21] & &SNES_ADDR[21:20]
& &SNES_ADDR[14:13] & &SNES_ADDR[14:13]
& !SNES_ADDR[15] & !SNES_ADDR[15]
) )
/* LoROM: SRAM @ Bank 0x70-0x7d, 0xf0-0xfd /* LoROM: SRAM @ Bank 0x70-0x7d, 0xf0-0xfd Offset 0000-7fff
* Offset 0000-7fff for ROM >= 32 MBit, otherwise 0000-ffff */ TODO: 0000-ffff for small ROMs? */
:(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] | ~ROM_MASK[21]) & !SNES_ADDR[15]
) )
/* BS-X: SRAM @ Bank 0x10-0x17 Offset 5000-5fff */ /* BS-X: SRAM @ Bank 0x10-0x17 Offset 5000-5fff */
:(MAPPER == 3'b011) :(MAPPER == 3'b011)
@@ -102,38 +96,17 @@ assign IS_SAVERAM = SAVERAM_MASK[0]
/* 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 */
wire [2:0] BSX_PSRAM_BANK = {bsx_regs[2], bsx_regs[6], bsx_regs[5]};
wire [23:0] BSX_CHKADDR = bsx_regs[2] ? SNES_ADDR : {SNES_ADDR[23], 1'b0, SNES_ADDR[22:16], SNES_ADDR[14:0]};
wire BSX_PSRAM_LOHI = (bsx_regs[3] & ~SNES_ADDR[23]) | (bsx_regs[4] & SNES_ADDR[23]);
wire BSX_IS_PSRAM = BSX_PSRAM_LOHI
& (( (BSX_CHKADDR[22:20] == BSX_PSRAM_BANK)
&(SNES_ADDR[15] | bsx_regs[2])
&(~(SNES_ADDR[19] & bsx_regs[2])))
| (bsx_regs[2]
? (SNES_ADDR[22:21] == 2'b01 & SNES_ADDR[15:13] == 3'b011)
: (&SNES_ADDR[22:20] & ~SNES_ADDR[15]))
);
wire BSX_IS_CARTROM = ((bsx_regs[7] & (SNES_ADDR[23:22] == 2'b00))
|(bsx_regs[8] & (SNES_ADDR[23:22] == 2'b10)))
& SNES_ADDR[15];
wire BSX_HOLE_LOHI = (bsx_regs[9] & ~SNES_ADDR[23]) | (bsx_regs[10] & SNES_ADDR[23]);
wire BSX_IS_HOLE = BSX_HOLE_LOHI
& (bsx_regs[2] ? (SNES_ADDR[21:20] == {bsx_regs[11], 1'b0})
: (SNES_ADDR[22:21] == {bsx_regs[11], 1'b0}));
assign bsx_tristate = (MAPPER == 3'b011) & ~BSX_IS_CARTROM & ~BSX_IS_PSRAM & BSX_IS_HOLE;
assign IS_WRITABLE = IS_SAVERAM assign IS_WRITABLE = IS_SAVERAM
|((MAPPER == 3'b011) |((MAPPER == 3'b011)
? BSX_IS_PSRAM ?((bsx_regs[3] && SNES_ADDR[23:20]==4'b0110)
|(!bsx_regs[5] && SNES_ADDR[23:20]==4'b0100)
|(!bsx_regs[6] && SNES_ADDR[23:20]==4'b0101)
|(SNES_ADDR[23:19] == 5'b01110)
|(SNES_ADDR[23:21] == 3'b001
&& SNES_ADDR[15:13] == 3'b011)
)
: 1'b0); : 1'b0);
wire [23:0] BSX_ADDR = bsx_regs[2] ? {1'b0, SNES_ADDR[22:0]}
: {2'b00, SNES_ADDR[22:16], SNES_ADDR[14:0]};
/* BSX regs: /* BSX regs:
Index Function Index Function
1 0=map flash to ROM area; 1=map PRAM to ROM area 1 0=map flash to ROM area; 1=map PRAM to ROM area
@@ -147,33 +120,45 @@ 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'hE00000 + ({SNES_ADDR[20:16], SNES_ADDR[12:0]} ? 24'hE00000 + ((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))
:(MAPPER == 3'b001) :(MAPPER == 3'b001)
?(IS_SAVERAM ?(IS_SAVERAM
? 24'hE00000 + ({SNES_ADDR[20:16], SNES_ADDR[14:0]} ? 24'hE00000 + (SNES_ADDR[14:0] & SAVERAM_MASK)
& 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'hE00000 + ({SNES_ADDR[20:16], SNES_ADDR[12:0]} ? 24'hE00000 + ((SNES_ADDR[14:0] - 15'h6000)
& 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'hE00000 + {SNES_ADDR[18:16], SNES_ADDR[11:0]} ? 24'hE00000 + {SNES_ADDR[18:16], SNES_ADDR[11:0]}
: BSX_IS_CARTROM : IS_WRITABLE
? (24'h800000 + ({SNES_ADDR[22:16], SNES_ADDR[14:0]} & 24'h0fffff)) ? (24'h400000 + (SNES_ADDR & 24'h07FFFF))
: BSX_IS_PSRAM : ((bsx_regs[7] && SNES_ADDR[23:21] == 3'b000)
? (24'h400000 + (BSX_ADDR & 24'h07FFFF)) |(bsx_regs[8] && SNES_ADDR[23:21] == 3'b100))
: bs_page_enable ?(24'h800000
? (24'h900000 + {bs_page,bs_page_offset}) + ({1'b0, SNES_ADDR[23:16], SNES_ADDR[14:0]}
: (BSX_ADDR & 24'h0fffff) & 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
@@ -193,7 +178,7 @@ assign SRAM_SNES_ADDR = ((MAPPER == 3'b000)
? 24'hFF0000 + ((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'hE00000)
) )
: 24'b0); : 24'b0);
@@ -202,19 +187,14 @@ assign ROM_ADDR = SRAM_SNES_ADDR;
assign ROM_SEL = 1'b0; assign ROM_SEL = 1'b0;
assign msu_enable_w = featurebits[FEAT_MSU1] & (!SNES_ADDR[22] && ((SNES_ADDR[15:0] & 16'hfff8) == 16'h2000)); assign msu_enable_w = featurebits[FEAT_MSU1] & (!SNES_ADDR[22] && ((SNES_ADDR[15:0] & 16'hfff8) == 16'h2000));
//reg [5:0] msu_enable_r; reg [5:0] msu_enable_r;
//initial msu_enable_r = 6'b000000; initial msu_enable_r = 6'b000000;
//always @(posedge CLK) msu_enable_r <= {msu_enable_r[4:0], msu_enable_w}; always @(posedge CLK) msu_enable_r <= {msu_enable_r[4:0], msu_enable_w};
assign msu_enable = msu_enable_w /*&msu_enable_r[5:2]*/; assign msu_enable = &msu_enable_r[5:2];
assign use_bsx = (MAPPER == 3'b011); assign use_bsx = (MAPPER == 3'b011);
assign srtc_enable_w = (!SNES_ADDR[22] && ((SNES_ADDR[15:0] & 16'hfffe) == 16'h2800)); assign srtc_enable = featurebits[FEAT_SRTC] & (!SNES_ADDR[22] && ((SNES_ADDR[15:0] & 16'hfffe) == 16'h2800));
//reg [5:0] srtc_enable_r;
//initial srtc_enable_r = 6'b000000;
//always @(posedge CLK) srtc_enable_r <= {srtc_enable_r[4:0], srtc_enable_w};
assign srtc_enable = srtc_enable_w /*&srtc_enable_r[3:0]*/ & featurebits[FEAT_SRTC];
// DSP1 LoROM: DR=30-3f:8000-bfff; SR=30-3f:c000-ffff // DSP1 LoROM: DR=30-3f:8000-bfff; SR=30-3f:c000-ffff
// or DR=60-6f:0000-3fff; SR=60-6f:4000-7fff // or DR=60-6f:0000-3fff; SR=60-6f:4000-7fff
@@ -248,27 +228,15 @@ assign dspx_a0 = featurebits[FEAT_DSPX]
assign dspx_dp_enable = dspx_dp_enable_w; assign dspx_dp_enable = dspx_dp_enable_w;
//reg [5:0] dspx_enable_r; reg [5:0] dspx_enable_r;
//initial dspx_enable_r = 6'b000000; initial dspx_enable_r = 6'b000000;
//always @(posedge CLK) dspx_enable_r <= {dspx_enable_r[4:0], dspx_enable_w}; always @(posedge CLK) dspx_enable_r <= {dspx_enable_r[4:0], dspx_enable_w};
assign dspx_enable = dspx_enable_w /*&dspx_enable_r[5:1]*/; assign dspx_enable = &dspx_enable_r[5:2];
wire r213f_enable_w = (SNES_PA == 8'h3f); wire r213f_enable_w = (SNES_PA == 8'h3f);
//reg [5:0] r213f_enable_r; reg [5:0] r213f_enable_r;
//initial r213f_enable_r = 6'b000000; initial r213f_enable_r = 6'b000000;
//always @(posedge CLK) r213f_enable_r <= {r213f_enable_r[4:0], r213f_enable_w}; always @(posedge CLK) r213f_enable_r <= {r213f_enable_r[4:0], r213f_enable_w};
assign r213f_enable = r213f_enable_w /*&r213f_enable_r[5:2]*/ & featurebits[FEAT_213F]; assign r213f_enable = &r213f_enable_r[5:2] & featurebits[FEAT_213F];
wire snescmd_rd_enable_w = (SNES_PA[7:4] == 4'b1111);
//reg [5:0] snescmd_rd_enable_r;
//initial snescmd_rd_enable_r = 6'b000000;
//always @(posedge CLK) snescmd_rd_enable_r <= {snescmd_rd_enable_r[4:0], snescmd_rd_enable_w};
assign snescmd_rd_enable = snescmd_rd_enable_w /*&snescmd_rd_enable_r[5:1]*/;
assign snescmd_wr_enable_w = (SNES_ADDR[23:4] == 20'hccccc);
//reg [5:0] snescmd_wr_enable_r;
//initial snescmd_wr_enable_r = 6'b000000;
//always @(posedge CLK) snescmd_wr_enable_r <= {snescmd_wr_enable_r[4:0], snescmd_wr_enable_w};
assign snescmd_wr_enable = snescmd_wr_enable_w /*&snescmd_wr_enable_r[5:1]*/;
endmodule endmodule

View File

@@ -32,10 +32,7 @@ module bsx(
input use_bsx, input use_bsx,
output data_ovr, output data_ovr,
output flash_writable, output flash_writable,
input [59:0] rtc_data, input [55:0] rtc_data
output [9:0] bs_page_out, // support only page 0000-03ff
output bs_page_enable,
output [8:0] bs_page_offset
); );
wire [3:0] reg_addr = snes_addr[19:16]; // 00-0f:5000-5fff wire [3:0] reg_addr = snes_addr[19:16]; // 00-0f:5000-5fff
@@ -70,44 +67,15 @@ assign flash_writable = (use_bsx)
&& flash_we_r && flash_we_r
&& !is_flash_special_address; && !is_flash_special_address;
assign data_ovr = (cart_enable | base_enable | flash_ovr) & ~bs_page_enable; assign data_ovr = cart_enable | base_enable | flash_ovr;
reg [9:0] bs_page0;
reg [9:0] bs_page1;
reg [8:0] bs_page0_offset;
reg [8:0] bs_page1_offset;
reg [4:0] bs_stb0_offset;
reg [4:0] bs_stb1_offset;
wire bs_sta0_en = base_addr == 5'h0a;
wire bs_stb0_en = base_addr == 5'h0b;
wire bs_page0_en = base_addr == 5'h0c;
wire bs_sta1_en = base_addr == 5'h10;
wire bs_stb1_en = base_addr == 5'h11;
wire bs_page1_en = base_addr == 5'h12;
assign bs_page_enable = base_enable & ((|bs_page0 & (bs_page0_en | bs_sta0_en | bs_stb0_en))
|(|bs_page1 & (bs_page1_en | bs_sta1_en | bs_stb1_en)));
assign bs_page_out = (bs_page0_en | bs_sta0_en | bs_stb0_en) ? bs_page0 : bs_page1;
assign bs_page_offset = bs_sta0_en ? 9'h032
: bs_stb0_en ? (9'h034 + bs_stb0_offset)
: bs_sta1_en ? 9'h032
: bs_stb1_en ? (9'h034 + bs_stb1_offset)
: (9'h048 + (bs_page0_en ? bs_page0_offset : bs_page1_offset));
reg [3:0] reg_oe_sreg; reg [3:0] reg_oe_sreg;
always @(posedge clkin) reg_oe_sreg <= {reg_oe_sreg[2:0], reg_oe}; always @(posedge clkin) reg_oe_sreg <= {reg_oe_sreg[2:0], reg_oe};
wire reg_oe_falling = (reg_oe_sreg[3:1] == 3'b100); wire reg_oe_falling = (reg_oe_sreg[3:0] == 4'b1000);
wire reg_oe_rising = (reg_oe_sreg[3:1] == 3'b001);
reg [2:0] reg_we_sreg; reg [1:0] reg_we_sreg;
always @(posedge clkin) reg_we_sreg <= {reg_we_sreg[1:0], reg_we}; always @(posedge clkin) reg_we_sreg <= {reg_we_sreg[0], reg_we};
wire reg_we_rising = (reg_we_sreg[2:1] == 2'b01); wire reg_we_rising = (reg_we_sreg[1:0] == 2'b01);
reg [1:0] pgm_we_sreg; reg [1:0] pgm_we_sreg;
always @(posedge clkin) pgm_we_sreg <= {pgm_we_sreg[0], pgm_we}; always @(posedge clkin) pgm_we_sreg <= {pgm_we_sreg[0], pgm_we};
@@ -128,40 +96,40 @@ wire [7:0] rtc_sec = rtc_data[3:0] + (rtc_data[7:4] << 3) + (rtc_data[7:4] << 1)
wire [7:0] rtc_min = rtc_data[11:8] + (rtc_data[15:12] << 3) + (rtc_data[15:12] << 1); wire [7:0] rtc_min = rtc_data[11:8] + (rtc_data[15:12] << 3) + (rtc_data[15:12] << 1);
wire [7:0] rtc_hour = rtc_data[19:16] + (rtc_data[23:20] << 3) + (rtc_data[23:20] << 1); wire [7:0] rtc_hour = rtc_data[19:16] + (rtc_data[23:20] << 3) + (rtc_data[23:20] << 1);
wire [7:0] rtc_day = rtc_data[27:24] + (rtc_data[31:28] << 3) + (rtc_data[31:28] << 1); wire [7:0] rtc_day = rtc_data[27:24] + (rtc_data[31:28] << 3) + (rtc_data[31:28] << 1);
/* The following signals are currently unused.
They are kept in case more Satellaview date registers are discovered. */
wire [7:0] rtc_month = rtc_data[35:32] + (rtc_data[39:36] << 3) + (rtc_data[39:36] << 1); wire [7:0] rtc_month = rtc_data[35:32] + (rtc_data[39:36] << 3) + (rtc_data[39:36] << 1);
wire [7:0] rtc_dow = {4'b0,rtc_data[59:56]};
wire [7:0] rtc_year1 = rtc_data[43:40] + (rtc_data[47:44] << 3) + (rtc_data[47:44] << 1); wire [7:0] rtc_year1 = rtc_data[43:40] + (rtc_data[47:44] << 3) + (rtc_data[47:44] << 1);
wire [7:0] rtc_year100 = rtc_data[51:48] + (rtc_data[55:52] << 3) + (rtc_data[55:52] << 1); wire [7:0] rtc_year100 = rtc_data[51:48] + (rtc_data[55:52] << 3) + (rtc_data[55:52] << 1);
wire [15:0] rtc_year = (rtc_year100 << 6) + (rtc_year100 << 5) + (rtc_year100 << 2) + rtc_year1;
initial begin initial begin
regs_tmpr <= 15'b000101111101100; regs_tmpr <= 15'b000000100000000;
regs_outr <= 15'b000101111101100; regs_outr <= 15'b000000100000000;
bsx_counter <= 0; bsx_counter <= 0;
base_regs[5'h08] <= 0; base_regs[8] <= 0;
base_regs[5'h09] <= 0; base_regs[9] <= 0;
base_regs[5'h0a] <= 8'h01; base_regs[10] <= 0;
base_regs[5'h0b] <= 0; base_regs[11] <= 8'h9f;
base_regs[5'h0c] <= 0; base_regs[12] <= 8'h10;
base_regs[5'h0d] <= 0; base_regs[13] <= 8'h9f;
base_regs[5'h0e] <= 0; base_regs[14] <= 0;
base_regs[5'h0f] <= 0; base_regs[15] <= 0;
base_regs[5'h10] <= 8'h01; base_regs[16] <= 0;
base_regs[5'h11] <= 0; base_regs[17] <= 8'h9f;
base_regs[5'h12] <= 0; base_regs[18] <= 8'h01;
base_regs[5'h13] <= 0; base_regs[19] <= 8'h9f;
base_regs[5'h14] <= 0; base_regs[20] <= 0;
base_regs[5'h15] <= 0; base_regs[21] <= 0;
base_regs[5'h16] <= 0; base_regs[22] <= 8'h02;
base_regs[5'h17] <= 0; base_regs[23] <= 8'hff;
base_regs[5'h18] <= 0; base_regs[24] <= 8'h80;
base_regs[5'h19] <= 0; base_regs[25] <= 8'h01;
base_regs[5'h1a] <= 0; base_regs[26] <= 0;
base_regs[5'h1b] <= 0; base_regs[27] <= 0;
base_regs[5'h1c] <= 0; base_regs[28] <= 0;
base_regs[5'h1d] <= 0; base_regs[29] <= 0;
base_regs[5'h1e] <= 0; base_regs[30] <= 0;
base_regs[5'h1f] <= 0; base_regs[31] <= 0;
flash_vendor_data[3'h0] <= 8'h4d; flash_vendor_data[3'h0] <= 8'h4d;
flash_vendor_data[3'h1] <= 8'h00; flash_vendor_data[3'h1] <= 8'h00;
flash_vendor_data[3'h2] <= 8'h50; flash_vendor_data[3'h2] <= 8'h50;
@@ -172,55 +140,39 @@ initial begin
flash_vendor_data[3'h7] <= 8'h00; flash_vendor_data[3'h7] <= 8'h00;
flash_ovr_r <= 1'b0; flash_ovr_r <= 1'b0;
flash_we_r <= 1'b0; flash_we_r <= 1'b0;
bs_page0 <= 10'h0;
bs_page1 <= 10'h0;
bs_page0_offset <= 9'h0;
bs_page1_offset <= 9'h0;
bs_stb0_offset <= 5'h00;
bs_stb1_offset <= 5'h00;
end end
always @(posedge clkin) begin always @(posedge clkin) begin
if(reg_oe_rising && base_enable) begin
case(base_addr)
5'h0b: begin
bs_stb0_offset <= bs_stb0_offset + 1;
base_regs[5'h0d] <= base_regs[5'h0d] | reg_data_in;
end
5'h0c: bs_page0_offset <= bs_page0_offset + 1;
5'h11: begin
bs_stb1_offset <= bs_stb1_offset + 1;
base_regs[5'h13] <= base_regs[5'h13] | reg_data_in;
end
5'h12: bs_page1_offset <= bs_page1_offset + 1;
endcase
end else
if(reg_oe_falling) begin if(reg_oe_falling) begin
if(cart_enable) if(cart_enable)
reg_data_outr <= {regs_outr[reg_addr], 7'b0}; reg_data_outr <= {regs_outr[reg_addr], 7'b0};
else if(base_enable) begin else if(base_enable) begin
case(base_addr) case(base_addr)
5'h0c, 5'h12: begin 5'b10010: begin
case (bs_page1_offset) if(bsx_counter < 18) begin
4: reg_data_outr <= 8'h3; bsx_counter <= bsx_counter + 1;
5: reg_data_outr <= 8'h1; case (bsx_counter)
6: reg_data_outr <= 8'h1; 5:
10: reg_data_outr <= rtc_sec; reg_data_outr <= 8'h1;
11: reg_data_outr <= rtc_min; 6:
12: reg_data_outr <= rtc_hour; reg_data_outr <= 8'h1;
13: reg_data_outr <= rtc_dow; 10:
14: reg_data_outr <= rtc_day; reg_data_outr <= rtc_sec;
15: reg_data_outr <= rtc_month; 11:
16: reg_data_outr <= rtc_year[7:0]; reg_data_outr <= rtc_min;
17: reg_data_outr <= rtc_hour; 12:
default: reg_data_outr <= 8'h0; reg_data_outr <= rtc_hour;
default:
reg_data_outr <= 8'h0;
endcase endcase
end else begin
reg_data_outr <= 8'h0;
bsx_counter <= 0;
end end
5'h0d, 5'h13: begin
reg_data_outr <= base_regs[base_addr];
base_regs[base_addr] <= 8'h00;
end end
5'b10011:
reg_data_outr <= base_regs[base_addr] & 8'h3f;
default: default:
reg_data_outr <= base_regs[base_addr]; reg_data_outr <= base_regs[base_addr];
endcase endcase
@@ -240,33 +192,22 @@ always @(posedge clkin) begin
regs_tmpr[8:1] <= (regs_tmpr[8:1] | reg_set_bits[7:0]) & ~reg_reset_bits[7:0]; regs_tmpr[8:1] <= (regs_tmpr[8:1] | reg_set_bits[7:0]) & ~reg_reset_bits[7:0];
regs_outr[8:1] <= (regs_outr[8:1] | reg_set_bits[7:0]) & ~reg_reset_bits[7:0]; regs_outr[8:1] <= (regs_outr[8:1] | reg_set_bits[7:0]) & ~reg_reset_bits[7:0];
end else if(reg_we_rising && cart_enable) begin end else if(reg_we_rising && cart_enable) begin
if(reg_addr == 4'he) if(reg_addr == 4'he && reg_data_in[7])
regs_outr <= regs_tmpr; regs_outr <= regs_tmpr | 15'b100000000000000;
else else
regs_tmpr[reg_addr] <= reg_data_in[7]; regs_tmpr[reg_addr] <= reg_data_in[7];
end else if(reg_we_rising && base_enable) begin end else if(reg_we_rising && base_enable) begin
case(base_addr) case(base_addr)
5'h09: begin
base_regs[8'h09] <= reg_data_in;
bs_page0 <= {reg_data_in[1:0], base_regs[8'h08]};
bs_page0_offset <= 9'h00;
end
5'h0b: begin
bs_stb0_offset <= 5'h00;
end
5'h0c: begin
bs_page0_offset <= 9'h00;
end
5'h0f: begin 5'h0f: begin
base_regs[8'h0f] <= reg_data_in; base_regs[base_addr-1] <= base_regs[base_addr]-(base_regs[base_addr-1] >> 1);
bs_page1 <= {reg_data_in[1:0], base_regs[8'h0e]}; base_regs[base_addr] <= base_regs[base_addr] >> 1;
bs_page1_offset <= 9'h00;
end end
5'h11: begin 5'h11: begin
bs_stb1_offset <= 5'h00; bsx_counter <= 0;
base_regs[base_addr] <= reg_data_in;
end end
5'h12: begin 5'h12: begin
bs_page1_offset <= 9'h00; base_regs[8'h10] <= 8'h80;
end end
default: default:
base_regs[base_addr] <= reg_data_in; base_regs[base_addr] <= reg_data_in;

View File

@@ -39,7 +39,7 @@ always @(posedge clk) sysclk_sreg <= {sysclk_sreg[0], sysclk};
wire sysclk_rising = (sysclk_sreg == 2'b01); wire sysclk_rising = (sysclk_sreg == 2'b01);
always @(posedge clk) begin always @(posedge clk) begin
if(sysclk_counter < 88000000) begin if(sysclk_counter < 96000000) begin
sysclk_counter <= sysclk_counter + 1; sysclk_counter <= sysclk_counter + 1;
if(sysclk_rising) sysclk_value <= sysclk_value + 1; if(sysclk_rising) sysclk_value <= sysclk_value + 1;
end else begin end else begin

View File

@@ -31,7 +31,6 @@ module dac(
output sdout, output sdout,
output lrck, output lrck,
output mclk, output mclk,
output sclk,
output DAC_STATUS output DAC_STATUS
); );
@@ -69,15 +68,14 @@ reg [15:0] smpshift;
assign mclk = cnt[2]; // mclk = clk/8 assign mclk = cnt[2]; // mclk = clk/8
assign lrck = cnt[8]; // lrck = mclk/128 assign lrck = cnt[8]; // lrck = mclk/128
assign sclk = cnt[3]; // sclk = lrck*32 wire sclk = cnt[3]; // sclk = lrck*32
reg [2:0] lrck_sreg; reg [2:0] lrck_sreg;
reg [2:0] sclk_sreg; reg [2:0] sclk_sreg;
wire lrck_rising = (lrck_sreg[1:0] == 2'b01); wire lrck_rising = ({lrck_sreg[2:1]} == 2'b01);
wire lrck_falling = (lrck_sreg[1:0] == 2'b10); wire lrck_falling = ({lrck_sreg[2:1]} == 2'b10);
wire sclk_rising = (sclk_sreg[1:0] == 2'b01); wire sclk_rising = ({sclk_sreg[2:1]} == 2'b01);
wire sclk_falling = (sclk_sreg[1:0] == 2'b10);
wire vol_latch_rising = (vol_latch_reg[1:0] == 2'b01); wire vol_latch_rising = (vol_latch_reg[1:0] == 2'b01);
reg sdout_reg; reg sdout_reg;
@@ -145,15 +143,15 @@ always @(posedge clkin) begin
end end
always @(posedge clkin) begin always @(posedge clkin) begin
if (sclk_falling) begin
smpcnt <= smpcnt + 1;
sdout_reg <= smpshift[15];
if (lrck_rising) begin // right channel if (lrck_rising) begin // right channel
smpshift <= (({16'h0, dac_data[31:16]^16'h8000} * vol_reg) >> 8) ^ 16'h8000; smpshift <= (({16'h0, dac_data[31:16]^16'h8000} * vol_reg) >> 8) ^ 16'h8000;
samples <= samples + 1; samples <= samples + 1;
end else if (lrck_falling) begin // left channel end else if (lrck_falling) begin // left channel
smpshift <= (({16'h0, dac_data[15:0]^16'h8000} * vol_reg) >> 8) ^ 16'h8000; smpshift <= (({16'h0, dac_data[15:0]^16'h8000} * vol_reg) >> 8) ^ 16'h8000;
end else begin end else begin
if (sclk_rising) begin
smpcnt <= smpcnt + 1;
sdout_reg <= smpshift[15];
smpshift <= {smpshift[14:0], 1'b0}; smpshift <= {smpshift[14:0], 1'b0};
end end
end end

View File

@@ -1,29 +1,28 @@
/******************************************************************************* /*******************************************************************************
* This file is owned and controlled by Xilinx and must be used * * This file is owned and controlled by Xilinx and must be used solely *
* solely for design, simulation, implementation and creation of * * for design, simulation, implementation and creation of design files *
* design files limited to Xilinx devices or technologies. Use * * limited to Xilinx devices or technologies. Use with non-Xilinx *
* with non-Xilinx devices or technologies is expressly prohibited * * devices or technologies is expressly prohibited and immediately *
* and immediately terminates your license. * * terminates your license. *
* * * *
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" * * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" SOLELY *
* SOLELY FOR USE IN DEVELOPING PROGRAMS AND SOLUTIONS FOR * * FOR USE IN DEVELOPING PROGRAMS AND SOLUTIONS FOR XILINX DEVICES. BY *
* XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION * * PROVIDING THIS DESIGN, CODE, OR INFORMATION AS ONE POSSIBLE *
* AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION * * IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD, XILINX IS *
* OR STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS * * MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE FROM ANY *
* IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT, * * CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING ANY *
* AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE * * RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY *
* FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY * * DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE *
* WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE *
* IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR * * IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR *
* REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF * * REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF *
* INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * * INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* FOR A PARTICULAR PURPOSE. * * PARTICULAR PURPOSE. *
* * * *
* Xilinx products are not intended for use in life support * * Xilinx products are not intended for use in life support appliances, *
* appliances, devices, or systems. Use in such applications are * * devices, or systems. Use in such applications are expressly *
* expressly prohibited. * * prohibited. *
* * * *
* (c) Copyright 1995-2011 Xilinx, Inc. * * (c) Copyright 1995-2012 Xilinx, Inc. *
* All rights reserved. * * All rights reserved. *
*******************************************************************************/ *******************************************************************************/
// You must compile the wrapper file dac_buf.v when simulating // You must compile the wrapper file dac_buf.v when simulating
@@ -57,7 +56,7 @@ output [31 : 0] doutb;
// synthesis translate_off // synthesis translate_off
BLK_MEM_GEN_V6_1 #( BLK_MEM_GEN_V6_3 #(
.C_ADDRA_WIDTH(11), .C_ADDRA_WIDTH(11),
.C_ADDRB_WIDTH(9), .C_ADDRB_WIDTH(9),
.C_ALGORITHM(1), .C_ALGORITHM(1),
@@ -69,6 +68,7 @@ output [31 : 0] doutb;
.C_DEFAULT_DATA("0"), .C_DEFAULT_DATA("0"),
.C_DISABLE_WARN_BHV_COLL(0), .C_DISABLE_WARN_BHV_COLL(0),
.C_DISABLE_WARN_BHV_RANGE(0), .C_DISABLE_WARN_BHV_RANGE(0),
.C_ENABLE_32BIT_ADDRESS(0),
.C_FAMILY("spartan3"), .C_FAMILY("spartan3"),
.C_HAS_AXI_ID(0), .C_HAS_AXI_ID(0),
.C_HAS_ENA(0), .C_HAS_ENA(0),

View File

@@ -1,7 +1,7 @@
############################################################## ##############################################################
# #
# Xilinx Core Generator version 13.1 # Xilinx Core Generator version 13.4
# Date: Mon Jun 13 22:11:22 2011 # Date: Tue May 15 16:23:22 2012
# #
############################################################## ##############################################################
# #
@@ -12,12 +12,16 @@
# #
############################################################## ##############################################################
# #
# Generated from component: xilinx.com:ip:blk_mem_gen:6.3
#
##############################################################
#
# BEGIN Project Options # BEGIN Project Options
SET addpads = false SET addpads = false
SET asysymbol = true SET asysymbol = true
SET busformat = BusFormatAngleBracketNotRipped SET busformat = BusFormatAngleBracketNotRipped
SET createndf = false SET createndf = false
SET designentry = Advanced SET designentry = Verilog
SET device = xc3s400 SET device = xc3s400
SET devicefamily = spartan3 SET devicefamily = spartan3
SET flowvendor = Foundation_ISE SET flowvendor = Foundation_ISE
@@ -29,10 +33,10 @@ SET removerpms = false
SET simulationfiles = Behavioral SET simulationfiles = Behavioral
SET speedgrade = -4 SET speedgrade = -4
SET verilogsim = true SET verilogsim = true
SET vhdlsim = true SET vhdlsim = false
# END Project Options # END Project Options
# BEGIN Select # BEGIN Select
SELECT Block_Memory_Generator xilinx.com:ip:blk_mem_gen:6.1 SELECT Block_Memory_Generator xilinx.com:ip:blk_mem_gen:6.3
# END Select # END Select
# BEGIN Parameters # BEGIN Parameters
CSET additional_inputs_for_power_estimation=false CSET additional_inputs_for_power_estimation=false
@@ -49,6 +53,7 @@ CSET disable_collision_warnings=false
CSET disable_out_of_range_warnings=false CSET disable_out_of_range_warnings=false
CSET ecc=false CSET ecc=false
CSET ecctype=No_ECC CSET ecctype=No_ECC
CSET enable_32bit_address=false
CSET enable_a=Always_Enabled CSET enable_a=Always_Enabled
CSET enable_b=Always_Enabled CSET enable_b=Always_Enabled
CSET error_injection_type=Single_Bit_Error_Injection CSET error_injection_type=Single_Bit_Error_Injection
@@ -95,7 +100,7 @@ CSET write_width_a=8
CSET write_width_b=32 CSET write_width_b=32
# END Parameters # END Parameters
# BEGIN Extra information # BEGIN Extra information
MISC pkg_timestamp=2011-02-03T22:20:43.000Z MISC pkg_timestamp=2011-10-21T13:54:23Z
# END Extra information # END Extra information
GENERATE GENERATE
# CRC: 70eef295 # CRC: e5078255

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.2" xil_pn:schema_version="2"/> <version xil_pn:ise_version="13.4" xil_pn:schema_version="2"/>
<files> <files>
<file xil_pn:name="dac_buf.ngc" xil_pn:type="FILE_NGC"> <file xil_pn:name="dac_buf.ngc" xil_pn:type="FILE_NGC">
@@ -26,13 +26,7 @@
<association xil_pn:name="PostRouteSimulation" xil_pn:seqID="5"/> <association xil_pn:name="PostRouteSimulation" xil_pn:seqID="5"/>
<association xil_pn:name="PostTranslateSimulation" xil_pn:seqID="5"/> <association xil_pn:name="PostTranslateSimulation" xil_pn:seqID="5"/>
</file> </file>
<file xil_pn:name="dac_buf.vhd" xil_pn:type="FILE_VHDL"> <file xil_pn:name="dac_buf.vhd" xil_pn:type="FILE_VHDL"/>
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="7"/>
<association xil_pn:name="Implementation" xil_pn:seqID="7"/>
<association xil_pn:name="PostMapSimulation" xil_pn:seqID="7"/>
<association xil_pn:name="PostRouteSimulation" xil_pn:seqID="7"/>
<association xil_pn:name="PostTranslateSimulation" xil_pn:seqID="7"/>
</file>
</files> </files>
<properties> <properties>

View File

@@ -1,29 +1,28 @@
/******************************************************************************* /*******************************************************************************
* This file is owned and controlled by Xilinx and must be used * * This file is owned and controlled by Xilinx and must be used solely *
* solely for design, simulation, implementation and creation of * * for design, simulation, implementation and creation of design files *
* design files limited to Xilinx devices or technologies. Use * * limited to Xilinx devices or technologies. Use with non-Xilinx *
* with non-Xilinx devices or technologies is expressly prohibited * * devices or technologies is expressly prohibited and immediately *
* and immediately terminates your license. * * terminates your license. *
* * * *
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" * * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" SOLELY *
* SOLELY FOR USE IN DEVELOPING PROGRAMS AND SOLUTIONS FOR * * FOR USE IN DEVELOPING PROGRAMS AND SOLUTIONS FOR XILINX DEVICES. BY *
* XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION * * PROVIDING THIS DESIGN, CODE, OR INFORMATION AS ONE POSSIBLE *
* AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION * * IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD, XILINX IS *
* OR STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS * * MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE FROM ANY *
* IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT, * * CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING ANY *
* AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE * * RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY *
* FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY * * DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE *
* WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE *
* IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR * * IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR *
* REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF * * REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF *
* INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * * INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* FOR A PARTICULAR PURPOSE. * * PARTICULAR PURPOSE. *
* * * *
* Xilinx products are not intended for use in life support * * Xilinx products are not intended for use in life support appliances, *
* appliances, devices, or systems. Use in such applications are * * devices, or systems. Use in such applications are expressly *
* expressly prohibited. * * prohibited. *
* * * *
* (c) Copyright 1995-2011 Xilinx, Inc. * * (c) Copyright 1995-2012 Xilinx, Inc. *
* All rights reserved. * * All rights reserved. *
*******************************************************************************/ *******************************************************************************/
// You must compile the wrapper file msu_databuf.v when simulating // You must compile the wrapper file msu_databuf.v when simulating
@@ -57,7 +56,7 @@ output [7 : 0] doutb;
// synthesis translate_off // synthesis translate_off
BLK_MEM_GEN_V6_1 #( BLK_MEM_GEN_V6_3 #(
.C_ADDRA_WIDTH(14), .C_ADDRA_WIDTH(14),
.C_ADDRB_WIDTH(14), .C_ADDRB_WIDTH(14),
.C_ALGORITHM(1), .C_ALGORITHM(1),
@@ -69,6 +68,7 @@ output [7 : 0] doutb;
.C_DEFAULT_DATA("0"), .C_DEFAULT_DATA("0"),
.C_DISABLE_WARN_BHV_COLL(0), .C_DISABLE_WARN_BHV_COLL(0),
.C_DISABLE_WARN_BHV_RANGE(0), .C_DISABLE_WARN_BHV_RANGE(0),
.C_ENABLE_32BIT_ADDRESS(0),
.C_FAMILY("spartan3"), .C_FAMILY("spartan3"),
.C_HAS_AXI_ID(0), .C_HAS_AXI_ID(0),
.C_HAS_ENA(0), .C_HAS_ENA(0),

View File

@@ -1,7 +1,7 @@
############################################################## ##############################################################
# #
# Xilinx Core Generator version 13.1 # Xilinx Core Generator version 13.4
# Date: Mon Jun 13 22:13:20 2011 # Date: Tue May 15 16:26:06 2012
# #
############################################################## ##############################################################
# #
@@ -12,12 +12,16 @@
# #
############################################################## ##############################################################
# #
# Generated from component: xilinx.com:ip:blk_mem_gen:6.3
#
##############################################################
#
# BEGIN Project Options # BEGIN Project Options
SET addpads = false SET addpads = false
SET asysymbol = true SET asysymbol = true
SET busformat = BusFormatAngleBracketNotRipped SET busformat = BusFormatAngleBracketNotRipped
SET createndf = false SET createndf = false
SET designentry = Advanced SET designentry = Verilog
SET device = xc3s400 SET device = xc3s400
SET devicefamily = spartan3 SET devicefamily = spartan3
SET flowvendor = Foundation_ISE SET flowvendor = Foundation_ISE
@@ -29,10 +33,10 @@ SET removerpms = false
SET simulationfiles = Behavioral SET simulationfiles = Behavioral
SET speedgrade = -4 SET speedgrade = -4
SET verilogsim = true SET verilogsim = true
SET vhdlsim = true SET vhdlsim = false
# END Project Options # END Project Options
# BEGIN Select # BEGIN Select
SELECT Block_Memory_Generator xilinx.com:ip:blk_mem_gen:6.1 SELECT Block_Memory_Generator xilinx.com:ip:blk_mem_gen:6.3
# END Select # END Select
# BEGIN Parameters # BEGIN Parameters
CSET additional_inputs_for_power_estimation=false CSET additional_inputs_for_power_estimation=false
@@ -49,6 +53,7 @@ CSET disable_collision_warnings=false
CSET disable_out_of_range_warnings=false CSET disable_out_of_range_warnings=false
CSET ecc=false CSET ecc=false
CSET ecctype=No_ECC CSET ecctype=No_ECC
CSET enable_32bit_address=false
CSET enable_a=Always_Enabled CSET enable_a=Always_Enabled
CSET enable_b=Always_Enabled CSET enable_b=Always_Enabled
CSET error_injection_type=Single_Bit_Error_Injection CSET error_injection_type=Single_Bit_Error_Injection
@@ -95,7 +100,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-02-03T22:20:43.000Z MISC pkg_timestamp=2011-10-21T13:54:23Z
# END Extra information # END Extra information
GENERATE GENERATE
# CRC: eabbe14d # CRC: cbebd26a

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.2" xil_pn:schema_version="2"/> <version xil_pn:ise_version="13.4" xil_pn:schema_version="2"/>
<files> <files>
<file xil_pn:name="msu_databuf.ngc" xil_pn:type="FILE_NGC"> <file xil_pn:name="msu_databuf.ngc" xil_pn:type="FILE_NGC">
@@ -26,13 +26,7 @@
<association xil_pn:name="PostRouteSimulation" xil_pn:seqID="5"/> <association xil_pn:name="PostRouteSimulation" xil_pn:seqID="5"/>
<association xil_pn:name="PostTranslateSimulation" xil_pn:seqID="5"/> <association xil_pn:name="PostTranslateSimulation" xil_pn:seqID="5"/>
</file> </file>
<file xil_pn:name="msu_databuf.vhd" xil_pn:type="FILE_VHDL"> <file xil_pn:name="msu_databuf.vhd" xil_pn:type="FILE_VHDL"/>
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="7"/>
<association xil_pn:name="Implementation" xil_pn:seqID="7"/>
<association xil_pn:name="PostMapSimulation" xil_pn:seqID="7"/>
<association xil_pn:name="PostRouteSimulation" xil_pn:seqID="7"/>
<association xil_pn:name="PostTranslateSimulation" xil_pn:seqID="7"/>
</file>
</files> </files>
<properties> <properties>

View File

@@ -1,29 +1,28 @@
/******************************************************************************* /*******************************************************************************
* This file is owned and controlled by Xilinx and must be used * * This file is owned and controlled by Xilinx and must be used solely *
* solely for design, simulation, implementation and creation of * * for design, simulation, implementation and creation of design files *
* design files limited to Xilinx devices or technologies. Use * * limited to Xilinx devices or technologies. Use with non-Xilinx *
* with non-Xilinx devices or technologies is expressly prohibited * * devices or technologies is expressly prohibited and immediately *
* and immediately terminates your license. * * terminates your license. *
* * * *
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" * * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" SOLELY *
* SOLELY FOR USE IN DEVELOPING PROGRAMS AND SOLUTIONS FOR * * FOR USE IN DEVELOPING PROGRAMS AND SOLUTIONS FOR XILINX DEVICES. BY *
* XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION * * PROVIDING THIS DESIGN, CODE, OR INFORMATION AS ONE POSSIBLE *
* AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION * * IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD, XILINX IS *
* OR STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS * * MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE FROM ANY *
* IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT, * * CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING ANY *
* AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE * * RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY *
* FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY * * DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE *
* WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE *
* IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR * * IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR *
* REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF * * REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF *
* INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * * INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* FOR A PARTICULAR PURPOSE. * * PARTICULAR PURPOSE. *
* * * *
* Xilinx products are not intended for use in life support * * Xilinx products are not intended for use in life support appliances, *
* appliances, devices, or systems. Use in such applications are * * devices, or systems. Use in such applications are expressly *
* expressly prohibited. * * prohibited. *
* * * *
* (c) Copyright 1995-2011 Xilinx, Inc. * * (c) Copyright 1995-2012 Xilinx, Inc. *
* All rights reserved. * * All rights reserved. *
*******************************************************************************/ *******************************************************************************/
// You must compile the wrapper file upd77c25_datram.v when simulating // You must compile the wrapper file upd77c25_datram.v when simulating
@@ -63,7 +62,7 @@ output [7 : 0] doutb;
// synthesis translate_off // synthesis translate_off
BLK_MEM_GEN_V6_1 #( BLK_MEM_GEN_V6_3 #(
.C_ADDRA_WIDTH(10), .C_ADDRA_WIDTH(10),
.C_ADDRB_WIDTH(11), .C_ADDRB_WIDTH(11),
.C_ALGORITHM(1), .C_ALGORITHM(1),
@@ -75,6 +74,7 @@ output [7 : 0] doutb;
.C_DEFAULT_DATA("0"), .C_DEFAULT_DATA("0"),
.C_DISABLE_WARN_BHV_COLL(0), .C_DISABLE_WARN_BHV_COLL(0),
.C_DISABLE_WARN_BHV_RANGE(0), .C_DISABLE_WARN_BHV_RANGE(0),
.C_ENABLE_32BIT_ADDRESS(0),
.C_FAMILY("spartan3"), .C_FAMILY("spartan3"),
.C_HAS_AXI_ID(0), .C_HAS_AXI_ID(0),
.C_HAS_ENA(0), .C_HAS_ENA(0),

View File

@@ -1,7 +1,7 @@
############################################################## ##############################################################
# #
# Xilinx Core Generator version 13.1 # Xilinx Core Generator version 13.4
# Date: Sun Jun 19 20:18:04 2011 # Date: Wed May 16 07:50:33 2012
# #
############################################################## ##############################################################
# #
@@ -12,12 +12,16 @@
# #
############################################################## ##############################################################
# #
# Generated from component: xilinx.com:ip:blk_mem_gen:6.3
#
##############################################################
#
# BEGIN Project Options # BEGIN Project Options
SET addpads = false SET addpads = false
SET asysymbol = true SET asysymbol = true
SET busformat = BusFormatAngleBracketNotRipped SET busformat = BusFormatAngleBracketNotRipped
SET createndf = false SET createndf = false
SET designentry = Advanced SET designentry = Verilog
SET device = xc3s400 SET device = xc3s400
SET devicefamily = spartan3 SET devicefamily = spartan3
SET flowvendor = Other SET flowvendor = Other
@@ -29,10 +33,10 @@ SET removerpms = false
SET simulationfiles = Behavioral SET simulationfiles = Behavioral
SET speedgrade = -4 SET speedgrade = -4
SET verilogsim = true SET verilogsim = true
SET vhdlsim = true SET vhdlsim = false
# END Project Options # END Project Options
# BEGIN Select # BEGIN Select
SELECT Block_Memory_Generator xilinx.com:ip:blk_mem_gen:6.1 SELECT Block_Memory_Generator xilinx.com:ip:blk_mem_gen:6.3
# END Select # END Select
# BEGIN Parameters # BEGIN Parameters
CSET additional_inputs_for_power_estimation=false CSET additional_inputs_for_power_estimation=false
@@ -49,6 +53,7 @@ CSET disable_collision_warnings=false
CSET disable_out_of_range_warnings=false CSET disable_out_of_range_warnings=false
CSET ecc=false CSET ecc=false
CSET ecctype=No_ECC CSET ecctype=No_ECC
CSET enable_32bit_address=false
CSET enable_a=Always_Enabled CSET enable_a=Always_Enabled
CSET enable_b=Always_Enabled CSET enable_b=Always_Enabled
CSET error_injection_type=Single_Bit_Error_Injection CSET error_injection_type=Single_Bit_Error_Injection
@@ -95,7 +100,7 @@ CSET write_width_a=16
CSET write_width_b=8 CSET write_width_b=8
# END Parameters # END Parameters
# BEGIN Extra information # BEGIN Extra information
MISC pkg_timestamp=2011-02-03T22:20:43.000Z MISC pkg_timestamp=2011-10-21T13:54:23Z
# END Extra information # END Extra information
GENERATE GENERATE
# CRC: 78e2bfe1 # CRC: 94c2e5cc

View File

@@ -12,12 +12,12 @@
<!-- 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.2" xil_pn:schema_version="2"/> <version xil_pn:ise_version="13.4" xil_pn:schema_version="2"/>
<files> <files>
<file xil_pn:name="upd77c25_datram.ngc" xil_pn:type="FILE_NGC"> <file xil_pn:name="upd77c25_datram.ngc" xil_pn:type="FILE_NGC">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="2"/> <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="2"/>
<association xil_pn:name="Implementation" xil_pn:seqID="0"/> <association xil_pn:name="Implementation" xil_pn:seqID="1"/>
</file> </file>
<file xil_pn:name="upd77c25_datram.v" xil_pn:type="FILE_VERILOG"> <file xil_pn:name="upd77c25_datram.v" xil_pn:type="FILE_VERILOG">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="0"/> <association xil_pn:name="BehavioralSimulation" xil_pn:seqID="0"/>
@@ -26,13 +26,7 @@
<association xil_pn:name="PostRouteSimulation" xil_pn:seqID="5"/> <association xil_pn:name="PostRouteSimulation" xil_pn:seqID="5"/>
<association xil_pn:name="PostTranslateSimulation" xil_pn:seqID="5"/> <association xil_pn:name="PostTranslateSimulation" xil_pn:seqID="5"/>
</file> </file>
<file xil_pn:name="upd77c25_datram.vhd" xil_pn:type="FILE_VHDL"> <file xil_pn:name="upd77c25_datram.vhd" xil_pn:type="FILE_VHDL"/>
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="1"/>
<association xil_pn:name="Implementation" xil_pn:seqID="1"/>
<association xil_pn:name="PostMapSimulation" xil_pn:seqID="7"/>
<association xil_pn:name="PostRouteSimulation" xil_pn:seqID="7"/>
<association xil_pn:name="PostTranslateSimulation" xil_pn:seqID="7"/>
</file>
</files> </files>
<properties> <properties>

View File

@@ -1,29 +1,28 @@
/******************************************************************************* /*******************************************************************************
* This file is owned and controlled by Xilinx and must be used * * This file is owned and controlled by Xilinx and must be used solely *
* solely for design, simulation, implementation and creation of * * for design, simulation, implementation and creation of design files *
* design files limited to Xilinx devices or technologies. Use * * limited to Xilinx devices or technologies. Use with non-Xilinx *
* with non-Xilinx devices or technologies is expressly prohibited * * devices or technologies is expressly prohibited and immediately *
* and immediately terminates your license. * * terminates your license. *
* * * *
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" * * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" SOLELY *
* SOLELY FOR USE IN DEVELOPING PROGRAMS AND SOLUTIONS FOR * * FOR USE IN DEVELOPING PROGRAMS AND SOLUTIONS FOR XILINX DEVICES. BY *
* XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION * * PROVIDING THIS DESIGN, CODE, OR INFORMATION AS ONE POSSIBLE *
* AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION * * IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD, XILINX IS *
* OR STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS * * MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE FROM ANY *
* IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT, * * CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING ANY *
* AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE * * RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY *
* FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY * * DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE *
* WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE *
* IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR * * IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR *
* REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF * * REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF *
* INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * * INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* FOR A PARTICULAR PURPOSE. * * PARTICULAR PURPOSE. *
* * * *
* Xilinx products are not intended for use in life support * * Xilinx products are not intended for use in life support appliances, *
* appliances, devices, or systems. Use in such applications are * * devices, or systems. Use in such applications are expressly *
* expressly prohibited. * * prohibited. *
* * * *
* (c) Copyright 1995-2011 Xilinx, Inc. * * (c) Copyright 1995-2012 Xilinx, Inc. *
* All rights reserved. * * All rights reserved. *
*******************************************************************************/ *******************************************************************************/
// You must compile the wrapper file upd77c25_datrom.v when simulating // You must compile the wrapper file upd77c25_datrom.v when simulating
@@ -57,7 +56,7 @@ output [15 : 0] doutb;
// synthesis translate_off // synthesis translate_off
BLK_MEM_GEN_V6_1 #( BLK_MEM_GEN_V6_3 #(
.C_ADDRA_WIDTH(11), .C_ADDRA_WIDTH(11),
.C_ADDRB_WIDTH(11), .C_ADDRB_WIDTH(11),
.C_ALGORITHM(1), .C_ALGORITHM(1),
@@ -69,6 +68,7 @@ output [15 : 0] doutb;
.C_DEFAULT_DATA("0"), .C_DEFAULT_DATA("0"),
.C_DISABLE_WARN_BHV_COLL(0), .C_DISABLE_WARN_BHV_COLL(0),
.C_DISABLE_WARN_BHV_RANGE(0), .C_DISABLE_WARN_BHV_RANGE(0),
.C_ENABLE_32BIT_ADDRESS(0),
.C_FAMILY("spartan3"), .C_FAMILY("spartan3"),
.C_HAS_AXI_ID(0), .C_HAS_AXI_ID(0),
.C_HAS_ENA(0), .C_HAS_ENA(0),

View File

@@ -1,7 +1,7 @@
############################################################## ##############################################################
# #
# Xilinx Core Generator version 13.1 # Xilinx Core Generator version 13.4
# Date: Wed Jun 22 21:30:01 2011 # Date: Wed May 16 07:43:52 2012
# #
############################################################## ##############################################################
# #
@@ -12,12 +12,16 @@
# #
############################################################## ##############################################################
# #
# Generated from component: xilinx.com:ip:blk_mem_gen:6.3
#
##############################################################
#
# BEGIN Project Options # BEGIN Project Options
SET addpads = false SET addpads = false
SET asysymbol = true SET asysymbol = true
SET busformat = BusFormatAngleBracketNotRipped SET busformat = BusFormatAngleBracketNotRipped
SET createndf = false SET createndf = false
SET designentry = Advanced SET designentry = Verilog
SET device = xc3s400 SET device = xc3s400
SET devicefamily = spartan3 SET devicefamily = spartan3
SET flowvendor = Other SET flowvendor = Other
@@ -29,10 +33,10 @@ SET removerpms = false
SET simulationfiles = Behavioral SET simulationfiles = Behavioral
SET speedgrade = -4 SET speedgrade = -4
SET verilogsim = true SET verilogsim = true
SET vhdlsim = true SET vhdlsim = false
# END Project Options # END Project Options
# BEGIN Select # BEGIN Select
SELECT Block_Memory_Generator xilinx.com:ip:blk_mem_gen:6.1 SELECT Block_Memory_Generator xilinx.com:ip:blk_mem_gen:6.3
# END Select # END Select
# BEGIN Parameters # BEGIN Parameters
CSET additional_inputs_for_power_estimation=false CSET additional_inputs_for_power_estimation=false
@@ -49,6 +53,7 @@ CSET disable_collision_warnings=false
CSET disable_out_of_range_warnings=false CSET disable_out_of_range_warnings=false
CSET ecc=false CSET ecc=false
CSET ecctype=No_ECC CSET ecctype=No_ECC
CSET enable_32bit_address=false
CSET enable_a=Always_Enabled CSET enable_a=Always_Enabled
CSET enable_b=Always_Enabled CSET enable_b=Always_Enabled
CSET error_injection_type=Single_Bit_Error_Injection CSET error_injection_type=Single_Bit_Error_Injection
@@ -95,7 +100,7 @@ CSET write_width_a=16
CSET write_width_b=16 CSET write_width_b=16
# END Parameters # END Parameters
# BEGIN Extra information # BEGIN Extra information
MISC pkg_timestamp=2011-02-03T22:20:43.000Z MISC pkg_timestamp=2011-10-21T13:54:23Z
# END Extra information # END Extra information
GENERATE GENERATE
# CRC: 7b2b203b # CRC: 4c89ee28

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.2" xil_pn:schema_version="2"/> <version xil_pn:ise_version="13.4" xil_pn:schema_version="2"/>
<files> <files>
<file xil_pn:name="upd77c25_datrom.ngc" xil_pn:type="FILE_NGC"> <file xil_pn:name="upd77c25_datrom.ngc" xil_pn:type="FILE_NGC">
@@ -26,13 +26,7 @@
<association xil_pn:name="PostRouteSimulation" xil_pn:seqID="5"/> <association xil_pn:name="PostRouteSimulation" xil_pn:seqID="5"/>
<association xil_pn:name="PostTranslateSimulation" xil_pn:seqID="5"/> <association xil_pn:name="PostTranslateSimulation" xil_pn:seqID="5"/>
</file> </file>
<file xil_pn:name="upd77c25_datrom.vhd" xil_pn:type="FILE_VHDL"> <file xil_pn:name="upd77c25_datrom.vhd" xil_pn:type="FILE_VHDL"/>
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="7"/>
<association xil_pn:name="Implementation" xil_pn:seqID="7"/>
<association xil_pn:name="PostMapSimulation" xil_pn:seqID="7"/>
<association xil_pn:name="PostRouteSimulation" xil_pn:seqID="7"/>
<association xil_pn:name="PostTranslateSimulation" xil_pn:seqID="7"/>
</file>
</files> </files>
<properties> <properties>

View File

@@ -1,29 +1,28 @@
/******************************************************************************* /*******************************************************************************
* This file is owned and controlled by Xilinx and must be used * * This file is owned and controlled by Xilinx and must be used solely *
* solely for design, simulation, implementation and creation of * * for design, simulation, implementation and creation of design files *
* design files limited to Xilinx devices or technologies. Use * * limited to Xilinx devices or technologies. Use with non-Xilinx *
* with non-Xilinx devices or technologies is expressly prohibited * * devices or technologies is expressly prohibited and immediately *
* and immediately terminates your license. * * terminates your license. *
* * * *
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" * * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" SOLELY *
* SOLELY FOR USE IN DEVELOPING PROGRAMS AND SOLUTIONS FOR * * FOR USE IN DEVELOPING PROGRAMS AND SOLUTIONS FOR XILINX DEVICES. BY *
* XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION * * PROVIDING THIS DESIGN, CODE, OR INFORMATION AS ONE POSSIBLE *
* AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION * * IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD, XILINX IS *
* OR STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS * * MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE FROM ANY *
* IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT, * * CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING ANY *
* AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE * * RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY *
* FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY * * DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE *
* WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE *
* IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR * * IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR *
* REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF * * REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF *
* INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * * INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* FOR A PARTICULAR PURPOSE. * * PARTICULAR PURPOSE. *
* * * *
* Xilinx products are not intended for use in life support * * Xilinx products are not intended for use in life support appliances, *
* appliances, devices, or systems. Use in such applications are * * devices, or systems. Use in such applications are expressly *
* expressly prohibited. * * prohibited. *
* * * *
* (c) Copyright 1995-2011 Xilinx, Inc. * * (c) Copyright 1995-2012 Xilinx, Inc. *
* All rights reserved. * * All rights reserved. *
*******************************************************************************/ *******************************************************************************/
// You must compile the wrapper file upd77c25_pgmrom.v when simulating // You must compile the wrapper file upd77c25_pgmrom.v when simulating
@@ -57,7 +56,7 @@ output [23 : 0] doutb;
// synthesis translate_off // synthesis translate_off
BLK_MEM_GEN_V6_1 #( BLK_MEM_GEN_V6_3 #(
.C_ADDRA_WIDTH(11), .C_ADDRA_WIDTH(11),
.C_ADDRB_WIDTH(11), .C_ADDRB_WIDTH(11),
.C_ALGORITHM(1), .C_ALGORITHM(1),
@@ -69,6 +68,7 @@ output [23 : 0] doutb;
.C_DEFAULT_DATA("0"), .C_DEFAULT_DATA("0"),
.C_DISABLE_WARN_BHV_COLL(0), .C_DISABLE_WARN_BHV_COLL(0),
.C_DISABLE_WARN_BHV_RANGE(0), .C_DISABLE_WARN_BHV_RANGE(0),
.C_ENABLE_32BIT_ADDRESS(0),
.C_FAMILY("spartan3"), .C_FAMILY("spartan3"),
.C_HAS_AXI_ID(0), .C_HAS_AXI_ID(0),
.C_HAS_ENA(0), .C_HAS_ENA(0),

View File

@@ -1,7 +1,7 @@
############################################################## ##############################################################
# #
# Xilinx Core Generator version 13.1 # Xilinx Core Generator version 13.4
# Date: Wed Jun 22 21:31:49 2011 # Date: Wed May 16 08:14:01 2012
# #
############################################################## ##############################################################
# #
@@ -12,12 +12,16 @@
# #
############################################################## ##############################################################
# #
# Generated from component: xilinx.com:ip:blk_mem_gen:6.3
#
##############################################################
#
# BEGIN Project Options # BEGIN Project Options
SET addpads = false SET addpads = false
SET asysymbol = true SET asysymbol = true
SET busformat = BusFormatAngleBracketNotRipped SET busformat = BusFormatAngleBracketNotRipped
SET createndf = false SET createndf = false
SET designentry = Advanced SET designentry = Verilog
SET device = xc3s400 SET device = xc3s400
SET devicefamily = spartan3 SET devicefamily = spartan3
SET flowvendor = Other SET flowvendor = Other
@@ -29,10 +33,10 @@ SET removerpms = false
SET simulationfiles = Behavioral SET simulationfiles = Behavioral
SET speedgrade = -4 SET speedgrade = -4
SET verilogsim = true SET verilogsim = true
SET vhdlsim = true SET vhdlsim = false
# END Project Options # END Project Options
# BEGIN Select # BEGIN Select
SELECT Block_Memory_Generator xilinx.com:ip:blk_mem_gen:6.1 SELECT Block_Memory_Generator xilinx.com:ip:blk_mem_gen:6.3
# END Select # END Select
# BEGIN Parameters # BEGIN Parameters
CSET additional_inputs_for_power_estimation=false CSET additional_inputs_for_power_estimation=false
@@ -49,6 +53,7 @@ CSET disable_collision_warnings=false
CSET disable_out_of_range_warnings=false CSET disable_out_of_range_warnings=false
CSET ecc=false CSET ecc=false
CSET ecctype=No_ECC CSET ecctype=No_ECC
CSET enable_32bit_address=false
CSET enable_a=Always_Enabled CSET enable_a=Always_Enabled
CSET enable_b=Always_Enabled CSET enable_b=Always_Enabled
CSET error_injection_type=Single_Bit_Error_Injection CSET error_injection_type=Single_Bit_Error_Injection
@@ -95,7 +100,7 @@ CSET write_width_a=24
CSET write_width_b=24 CSET write_width_b=24
# END Parameters # END Parameters
# BEGIN Extra information # BEGIN Extra information
MISC pkg_timestamp=2011-02-03T22:20:43.000Z MISC pkg_timestamp=2011-10-21T13:54:23Z
# END Extra information # END Extra information
GENERATE GENERATE
# CRC: b11006ad # CRC: 4fd43971

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.2" xil_pn:schema_version="2"/> <version xil_pn:ise_version="13.4" xil_pn:schema_version="2"/>
<files> <files>
<file xil_pn:name="upd77c25_pgmrom.ngc" xil_pn:type="FILE_NGC"> <file xil_pn:name="upd77c25_pgmrom.ngc" xil_pn:type="FILE_NGC">
@@ -26,13 +26,7 @@
<association xil_pn:name="PostRouteSimulation" xil_pn:seqID="5"/> <association xil_pn:name="PostRouteSimulation" xil_pn:seqID="5"/>
<association xil_pn:name="PostTranslateSimulation" xil_pn:seqID="5"/> <association xil_pn:name="PostTranslateSimulation" xil_pn:seqID="5"/>
</file> </file>
<file xil_pn:name="upd77c25_pgmrom.vhd" xil_pn:type="FILE_VHDL"> <file xil_pn:name="upd77c25_pgmrom.vhd" xil_pn:type="FILE_VHDL"/>
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="7"/>
<association xil_pn:name="Implementation" xil_pn:seqID="7"/>
<association xil_pn:name="PostMapSimulation" xil_pn:seqID="7"/>
<association xil_pn:name="PostRouteSimulation" xil_pn:seqID="7"/>
<association xil_pn:name="PostTranslateSimulation" xil_pn:seqID="7"/>
</file>
</files> </files>
<properties> <properties>

View File

@@ -1,5 +1,6 @@
NET "CLKIN" TNM_NET = "CLKIN"; NET "CLKIN" TNM_NET = "CLKIN";
TIMESPEC TS_CLKIN = PERIOD "CLKIN" 22.05 MHz HIGH 50 %; TIMESPEC TS_CLKIN = PERIOD "CLKIN" 24 MHz HIGH 50 %;
//TIMESPEC TS_CLKIN = PERIOD "CLKIN" 21.5 MHz HIGH 50 %;
NET "p113_out" IOSTANDARD = LVCMOS33; NET "p113_out" IOSTANDARD = LVCMOS33;
NET "p113_out" LOC = P113; NET "p113_out" LOC = P113;
@@ -7,7 +8,7 @@ NET "p113_out" LOC = P113;
NET "SPI_SCK" LOC = P71; NET "SPI_SCK" LOC = P71;
NET "SPI_SCK" CLOCK_DEDICATED_ROUTE = FALSE; NET "SPI_SCK" CLOCK_DEDICATED_ROUTE = FALSE;
NET "SPI_SCK" TNM_NET = "SPI_SCK"; NET "SPI_SCK" TNM_NET = "SPI_SCK";
TIMESPEC TS_SPI_SCK = PERIOD "SPI_SCK" 88.2MHz HIGH 50 %; TIMESPEC TS_SPI_SCK = PERIOD "SPI_SCK" 48MHz HIGH 50 %;
NET "SPI_SCK" IOSTANDARD = LVCMOS33; NET "SPI_SCK" IOSTANDARD = LVCMOS33;
NET "SPI_SCK" DRIVE = 8; NET "SPI_SCK" DRIVE = 8;
@@ -32,30 +33,30 @@ NET "ROM_CE" LOC = P172;
NET "ROM_CE" IOSTANDARD = LVCMOS33; NET "ROM_CE" IOSTANDARD = LVCMOS33;
NET "ROM_CE" DRIVE = 8; NET "ROM_CE" DRIVE = 8;
NET "SNES_ADDR_IN[0]" LOC = P119; NET "SNES_ADDR[0]" LOC = P119;
NET "SNES_ADDR_IN[10]" LOC = P146; NET "SNES_ADDR[10]" LOC = P146;
NET "SNES_ADDR_IN[11]" LOC = P148; NET "SNES_ADDR[11]" LOC = P148;
NET "SNES_ADDR_IN[12]" LOC = P147; NET "SNES_ADDR[12]" LOC = P147;
NET "SNES_ADDR_IN[13]" LOC = P144; NET "SNES_ADDR[13]" LOC = P144;
NET "SNES_ADDR_IN[14]" LOC = P141; NET "SNES_ADDR[14]" LOC = P141;
NET "SNES_ADDR_IN[15]" LOC = P139; NET "SNES_ADDR[15]" LOC = P139;
NET "SNES_ADDR_IN[16]" LOC = P137; NET "SNES_ADDR[16]" LOC = P137;
NET "SNES_ADDR_IN[17]" LOC = P133; NET "SNES_ADDR[17]" LOC = P133;
NET "SNES_ADDR_IN[18]" LOC = P131; NET "SNES_ADDR[18]" LOC = P131;
NET "SNES_ADDR_IN[19]" LOC = P128; NET "SNES_ADDR[19]" LOC = P128;
NET "SNES_ADDR_IN[1]" LOC = P122; NET "SNES_ADDR[1]" LOC = P122;
NET "SNES_ADDR_IN[20]" LOC = P125; NET "SNES_ADDR[20]" LOC = P125;
NET "SNES_ADDR_IN[21]" LOC = P123; NET "SNES_ADDR[21]" LOC = P123;
NET "SNES_ADDR_IN[22]" LOC = P120; NET "SNES_ADDR[22]" LOC = P120;
NET "SNES_ADDR_IN[23]" LOC = P117; NET "SNES_ADDR[23]" LOC = P117;
NET "SNES_ADDR_IN[2]" LOC = P124; NET "SNES_ADDR[2]" LOC = P124;
NET "SNES_ADDR_IN[3]" LOC = P126; NET "SNES_ADDR[3]" LOC = P126;
NET "SNES_ADDR_IN[4]" LOC = P130; NET "SNES_ADDR[4]" LOC = P130;
NET "SNES_ADDR_IN[5]" LOC = P132; NET "SNES_ADDR[5]" LOC = P132;
NET "SNES_ADDR_IN[6]" LOC = P135; NET "SNES_ADDR[6]" LOC = P135;
NET "SNES_ADDR_IN[7]" LOC = P138; NET "SNES_ADDR[7]" LOC = P138;
NET "SNES_ADDR_IN[8]" LOC = P140; NET "SNES_ADDR[8]" LOC = P140;
NET "SNES_ADDR_IN[9]" LOC = P143; NET "SNES_ADDR[9]" LOC = P143;
NET "SNES_DATA[0]" LOC = P107; NET "SNES_DATA[0]" LOC = P107;
NET "SNES_DATA[1]" LOC = P102; NET "SNES_DATA[1]" LOC = P102;
NET "SNES_DATA[2]" LOC = P100; NET "SNES_DATA[2]" LOC = P100;
@@ -378,54 +379,54 @@ NET "ROM_WE" LOC = P190;
NET "ROM_WE" IOSTANDARD = LVCMOS33; NET "ROM_WE" IOSTANDARD = LVCMOS33;
NET "ROM_WE" DRIVE = 8; NET "ROM_WE" DRIVE = 8;
NET "SNES_ADDR_IN[0]" IOSTANDARD = LVCMOS33; NET "SNES_ADDR[0]" IOSTANDARD = LVCMOS33;
NET "SNES_ADDR_IN[0]" DRIVE = 8; NET "SNES_ADDR[0]" DRIVE = 8;
NET "SNES_ADDR_IN[10]" IOSTANDARD = LVCMOS33; NET "SNES_ADDR[10]" IOSTANDARD = LVCMOS33;
NET "SNES_ADDR_IN[10]" DRIVE = 8; NET "SNES_ADDR[10]" DRIVE = 8;
NET "SNES_ADDR_IN[11]" IOSTANDARD = LVCMOS33; NET "SNES_ADDR[11]" IOSTANDARD = LVCMOS33;
NET "SNES_ADDR_IN[11]" DRIVE = 8; NET "SNES_ADDR[11]" DRIVE = 8;
NET "SNES_ADDR_IN[12]" IOSTANDARD = LVCMOS33; NET "SNES_ADDR[12]" IOSTANDARD = LVCMOS33;
NET "SNES_ADDR_IN[12]" DRIVE = 8; NET "SNES_ADDR[12]" DRIVE = 8;
NET "SNES_ADDR_IN[13]" IOSTANDARD = LVCMOS33; NET "SNES_ADDR[13]" IOSTANDARD = LVCMOS33;
NET "SNES_ADDR_IN[13]" DRIVE = 8; NET "SNES_ADDR[13]" DRIVE = 8;
NET "SNES_ADDR_IN[14]" IOSTANDARD = LVCMOS33; NET "SNES_ADDR[14]" IOSTANDARD = LVCMOS33;
NET "SNES_ADDR_IN[14]" DRIVE = 8; NET "SNES_ADDR[14]" DRIVE = 8;
NET "SNES_ADDR_IN[15]" IOSTANDARD = LVCMOS33; NET "SNES_ADDR[15]" IOSTANDARD = LVCMOS33;
NET "SNES_ADDR_IN[15]" DRIVE = 8; NET "SNES_ADDR[15]" DRIVE = 8;
NET "SNES_ADDR_IN[16]" IOSTANDARD = LVCMOS33; NET "SNES_ADDR[16]" IOSTANDARD = LVCMOS33;
NET "SNES_ADDR_IN[16]" DRIVE = 8; NET "SNES_ADDR[16]" DRIVE = 8;
NET "SNES_ADDR_IN[17]" IOSTANDARD = LVCMOS33; NET "SNES_ADDR[17]" IOSTANDARD = LVCMOS33;
NET "SNES_ADDR_IN[17]" DRIVE = 8; NET "SNES_ADDR[17]" DRIVE = 8;
NET "SNES_ADDR_IN[18]" IOSTANDARD = LVCMOS33; NET "SNES_ADDR[18]" IOSTANDARD = LVCMOS33;
NET "SNES_ADDR_IN[18]" DRIVE = 8; NET "SNES_ADDR[18]" DRIVE = 8;
NET "SNES_ADDR_IN[19]" IOSTANDARD = LVCMOS33; NET "SNES_ADDR[19]" IOSTANDARD = LVCMOS33;
NET "SNES_ADDR_IN[19]" DRIVE = 8; NET "SNES_ADDR[19]" DRIVE = 8;
NET "SNES_ADDR_IN[1]" IOSTANDARD = LVCMOS33; NET "SNES_ADDR[1]" IOSTANDARD = LVCMOS33;
NET "SNES_ADDR_IN[1]" DRIVE = 8; NET "SNES_ADDR[1]" DRIVE = 8;
NET "SNES_ADDR_IN[20]" IOSTANDARD = LVCMOS33; NET "SNES_ADDR[20]" IOSTANDARD = LVCMOS33;
NET "SNES_ADDR_IN[20]" DRIVE = 8; NET "SNES_ADDR[20]" DRIVE = 8;
NET "SNES_ADDR_IN[21]" IOSTANDARD = LVCMOS33; NET "SNES_ADDR[21]" IOSTANDARD = LVCMOS33;
NET "SNES_ADDR_IN[21]" DRIVE = 8; NET "SNES_ADDR[21]" DRIVE = 8;
NET "SNES_ADDR_IN[22]" IOSTANDARD = LVCMOS33; NET "SNES_ADDR[22]" IOSTANDARD = LVCMOS33;
NET "SNES_ADDR_IN[22]" DRIVE = 8; NET "SNES_ADDR[22]" DRIVE = 8;
NET "SNES_ADDR_IN[23]" IOSTANDARD = LVCMOS33; NET "SNES_ADDR[23]" IOSTANDARD = LVCMOS33;
NET "SNES_ADDR_IN[23]" DRIVE = 8; NET "SNES_ADDR[23]" DRIVE = 8;
NET "SNES_ADDR_IN[2]" IOSTANDARD = LVCMOS33; NET "SNES_ADDR[2]" IOSTANDARD = LVCMOS33;
NET "SNES_ADDR_IN[2]" DRIVE = 8; NET "SNES_ADDR[2]" DRIVE = 8;
NET "SNES_ADDR_IN[3]" IOSTANDARD = LVCMOS33; NET "SNES_ADDR[3]" IOSTANDARD = LVCMOS33;
NET "SNES_ADDR_IN[3]" DRIVE = 8; NET "SNES_ADDR[3]" DRIVE = 8;
NET "SNES_ADDR_IN[4]" IOSTANDARD = LVCMOS33; NET "SNES_ADDR[4]" IOSTANDARD = LVCMOS33;
NET "SNES_ADDR_IN[4]" DRIVE = 8; NET "SNES_ADDR[4]" DRIVE = 8;
NET "SNES_ADDR_IN[5]" IOSTANDARD = LVCMOS33; NET "SNES_ADDR[5]" IOSTANDARD = LVCMOS33;
NET "SNES_ADDR_IN[5]" DRIVE = 8; NET "SNES_ADDR[5]" DRIVE = 8;
NET "SNES_ADDR_IN[6]" IOSTANDARD = LVCMOS33; NET "SNES_ADDR[6]" IOSTANDARD = LVCMOS33;
NET "SNES_ADDR_IN[6]" DRIVE = 8; NET "SNES_ADDR[6]" DRIVE = 8;
NET "SNES_ADDR_IN[7]" IOSTANDARD = LVCMOS33; NET "SNES_ADDR[7]" IOSTANDARD = LVCMOS33;
NET "SNES_ADDR_IN[7]" DRIVE = 8; NET "SNES_ADDR[7]" DRIVE = 8;
NET "SNES_ADDR_IN[8]" IOSTANDARD = LVCMOS33; NET "SNES_ADDR[8]" IOSTANDARD = LVCMOS33;
NET "SNES_ADDR_IN[8]" DRIVE = 8; NET "SNES_ADDR[8]" DRIVE = 8;
NET "SNES_ADDR_IN[9]" IOSTANDARD = LVCMOS33; NET "SNES_ADDR[9]" IOSTANDARD = LVCMOS33;
NET "SNES_ADDR_IN[9]" DRIVE = 8; NET "SNES_ADDR[9]" DRIVE = 8;
NET "SNES_CPU_CLK" LOC = P95; NET "SNES_CPU_CLK" LOC = P95;

View File

@@ -23,7 +23,7 @@ module main(
input CLKIN, input CLKIN,
/* SNES signals */ /* SNES signals */
input [23:0] SNES_ADDR_IN, input [23:0] SNES_ADDR,
input SNES_READ, input SNES_READ,
input SNES_WRITE, input SNES_WRITE,
input SNES_CS, input SNES_CS,
@@ -76,17 +76,6 @@ module main(
/* debug */ /* debug */
output p113_out output p113_out
); );
wire CLK2;
reg [23:0] SNES_ADDR_r [2:0];
always @(posedge CLK2) begin
SNES_ADDR_r[2] <= SNES_ADDR_r[1];
SNES_ADDR_r[1] <= SNES_ADDR_r[0];
SNES_ADDR_r[0] <= SNES_ADDR_IN;
end
wire [23:0] SNES_ADDR = SNES_ADDR_r[2] & SNES_ADDR_r[1];
wire dspx_dp_enable; wire dspx_dp_enable;
wire [7:0] spi_cmd_data; wire [7:0] spi_cmd_data;
@@ -144,22 +133,6 @@ wire [7:0] featurebits;
wire [23:0] MAPPED_SNES_ADDR; wire [23:0] MAPPED_SNES_ADDR;
wire ROM_ADDR0; wire ROM_ADDR0;
wire [9:0] bs_page;
wire [8:0] bs_page_offset;
wire bs_page_enable;
wire [4:0] DBG_srtc_state;
wire DBG_srtc_we_rising;
wire [3:0] DBG_srtc_ptr;
wire [5:0] DBG_srtc_we_sreg;
wire [13:0] DBG_msu_address;
wire DBG_msu_reg_oe_rising;
wire DBG_msu_reg_oe_falling;
wire DBG_msu_reg_we_rising;
wire [2:0] SD_DMA_DBG_clkcnt;
wire [10:0] SD_DMA_DBG_cyclecnt;
sd_dma snes_sd_dma( sd_dma snes_sd_dma(
.CLK(CLK2), .CLK(CLK2),
.SD_DAT(SD_DAT), .SD_DAT(SD_DAT),
@@ -173,9 +146,7 @@ sd_dma snes_sd_dma(
.SD_DMA_PARTIAL_START(SD_DMA_PARTIAL_START), .SD_DMA_PARTIAL_START(SD_DMA_PARTIAL_START),
.SD_DMA_PARTIAL_END(SD_DMA_PARTIAL_END), .SD_DMA_PARTIAL_END(SD_DMA_PARTIAL_END),
.SD_DMA_START_MID_BLOCK(SD_DMA_START_MID_BLOCK), .SD_DMA_START_MID_BLOCK(SD_DMA_START_MID_BLOCK),
.SD_DMA_END_MID_BLOCK(SD_DMA_END_MID_BLOCK), .SD_DMA_END_MID_BLOCK(SD_DMA_END_MID_BLOCK)
.DBG_cyclecnt(SD_DMA_DBG_cyclecnt),
.DBG_clkcnt(SD_DMA_DBG_clkcnt)
); );
wire SD_DMA_TO_ROM = (SD_DMA_STATUS && (SD_DMA_TGT == 2'b00)); wire SD_DMA_TO_ROM = (SD_DMA_STATUS && (SD_DMA_TGT == 2'b00));
@@ -207,11 +178,7 @@ srtc snes_srtc (
.enable(srtc_enable), .enable(srtc_enable),
.rtc_data_out(srtc_rtc_data_out), .rtc_data_out(srtc_rtc_data_out),
.rtc_we(srtc_rtc_we), .rtc_we(srtc_rtc_we),
.reset(srtc_reset), .reset(srtc_reset)
.srtc_state(DBG_srtc_state),
.srtc_reg_we_rising(DBG_srtc_we_rising),
.srtc_rtc_ptr(DBG_srtc_ptr),
.srtc_we_sreg(DBG_srtc_we_sreg)
); );
rtc snes_rtc ( rtc snes_rtc (
@@ -243,12 +210,7 @@ msu snes_msu (
.status_set_bits(msu_status_set_bits), .status_set_bits(msu_status_set_bits),
.status_reset_we(msu_status_reset_we), .status_reset_we(msu_status_reset_we),
.msu_address_ext(msu_ptr_addr), .msu_address_ext(msu_ptr_addr),
.msu_address_ext_write(msu_addr_reset), .msu_address_ext_write(msu_addr_reset)
.DBG_msu_reg_oe_rising(DBG_msu_reg_oe_rising),
.DBG_msu_reg_oe_falling(DBG_msu_reg_oe_falling),
.DBG_msu_reg_we_rising(DBG_msu_reg_we_rising),
.DBG_msu_address(DBG_msu_address),
.DBG_msu_address_ext_write_rising(DBG_msu_address_ext_write_rising)
); );
bsx snes_bsx( bsx snes_bsx(
@@ -265,11 +227,7 @@ bsx snes_bsx(
.reg_set_bits(bsx_regs_set_bits), .reg_set_bits(bsx_regs_set_bits),
.data_ovr(bsx_data_ovr), .data_ovr(bsx_data_ovr),
.flash_writable(IS_FLASHWR), .flash_writable(IS_FLASHWR),
.rtc_data(rtc_data[59:0]), .rtc_data(rtc_data[55:0])
.bs_page_out(bs_page), // support only page 0000-03ff
.bs_page_enable(bs_page_enable),
.bs_page_offset(bs_page_offset)
); );
spi snes_spi( spi snes_spi(
@@ -372,8 +330,7 @@ mcu_cmd snes_mcu_cmd(
.mcu_rrq(MCU_RRQ), .mcu_rrq(MCU_RRQ),
.mcu_wrq(MCU_WRQ), .mcu_wrq(MCU_WRQ),
.mcu_rq_rdy(MCU_RDY), .mcu_rq_rdy(MCU_RDY),
.region_out(mcu_region), .region_out(mcu_region)
.DBG_mcu_nextaddr(DBG_mcu_nextaddr)
); );
wire [7:0] DCM_STATUS; wire [7:0] DCM_STATUS;
@@ -386,37 +343,33 @@ my_dcm snes_dcm(
.STATUS(DCM_STATUS) .STATUS(DCM_STATUS)
); );
my_dcm snes_dcm2(
.CLKIN(SNES_SYSCLK),
.CLKFX(SYSCLK2),
.RST(DCM_RST)
);
assign DCM_RST=0; assign DCM_RST=0;
reg [7:0] SNES_PARDr; reg [5:0] SNES_PARDr;
reg [7:0] SNES_PAWRr; reg [5:0] SNES_READr;
reg [7:0] SNES_READr; reg [5:0] SNES_WRITEr;
reg [7:0] SNES_WRITEr; reg [5:0] SNES_CPU_CLKr;
reg [7:0] SNES_CPU_CLKr;
wire SNES_FAKE_CLK = &SNES_CPU_CLKr[2:1]; wire SNES_PARD_start = (SNES_PARDr == 6'b111110);
//wire SNES_FAKE_CLK = ~(SNES_READ & SNES_WRITE); wire SNES_RD_start = (SNES_READr == 6'b111110);
wire SNES_WR_start = (SNES_WRITEr == 6'b111110);
wire SNES_cycle_start = (SNES_CPU_CLKr[5:0] == 6'b000001);
wire SNES_cycle_end = (SNES_CPU_CLKr[5:0] == 6'b111110);
reg SNES_DEADr; always @(posedge SYSCLK2) begin
initial SNES_DEADr = 0; SNES_PARDr <= {SNES_PARDr[4:0], SNES_PARD};
wire SNES_PARD_start = (SNES_PARDr[7:1] == 7'b1111110);
wire SNES_PAWR_start = (SNES_PAWRr[7:1] == 7'b0000001);
wire SNES_RD_start = (SNES_READr[7:1] == 7'b1111110);
wire SNES_WR_start = (SNES_WRITEr[7:1] == 7'b1111110);
wire SNES_WR_end = (SNES_WRITEr[7:1] == 7'b0000001);
wire SNES_cycle_start = ((SNES_CPU_CLKr[7:2] & SNES_CPU_CLKr[6:1]) == 6'b000001);
wire SNES_cycle_end = ((SNES_CPU_CLKr[7:2] & SNES_CPU_CLKr[6:1]) == 6'b111110);
always @(posedge CLK2) begin
SNES_PARDr <= {SNES_PARDr[6:0], SNES_PARD};
end end
always @(posedge CLK2) begin always @(posedge CLK2) begin
SNES_PAWRr <= {SNES_PAWRr[6:0], SNES_PAWR}; SNES_READr <= {SNES_READr[4:0], SNES_READ};
SNES_READr <= {SNES_READr[6:0], SNES_READ}; SNES_WRITEr <= {SNES_WRITEr[4:0], SNES_WRITE};
SNES_WRITEr <= {SNES_WRITEr[6:0], SNES_WRITE}; SNES_CPU_CLKr <= {SNES_CPU_CLKr[4:0], SNES_CPU_CLK};
SNES_CPU_CLKr <= {SNES_CPU_CLKr[6:0], SNES_CPU_CLK};
end end
address snes_addr( address snes_addr(
@@ -437,19 +390,13 @@ address snes_addr(
//BS-X //BS-X
.use_bsx(use_bsx), .use_bsx(use_bsx),
.bsx_regs(bsx_regs), .bsx_regs(bsx_regs),
.bs_page_offset(bs_page_offset),
.bs_page(bs_page),
.bs_page_enable(bs_page_enable),
.bsx_tristate(bsx_tristate),
//SRTC //SRTC
.srtc_enable(srtc_enable), .srtc_enable(srtc_enable),
//uPD77C25 //uPD77C25
.dspx_enable(dspx_enable), .dspx_enable(dspx_enable),
.dspx_dp_enable(dspx_dp_enable), .dspx_dp_enable(dspx_dp_enable),
.dspx_a0(DSPX_A0), .dspx_a0(DSPX_A0),
.r213f_enable(r213f_enable), .r213f_enable(r213f_enable)
.snescmd_rd_enable(snescmd_rd_enable),
.snescmd_wr_enable(snescmd_wr_enable)
); );
parameter MODE_SNES = 1'b0; parameter MODE_SNES = 1'b0;
@@ -473,27 +420,23 @@ parameter ST_MCU_WR_WAIT = 18'b000100000000000000;
parameter ST_MCU_WR_WAIT2 = 18'b001000000000000000; parameter ST_MCU_WR_WAIT2 = 18'b001000000000000000;
parameter ST_MCU_WR_END = 18'b010000000000000000; parameter ST_MCU_WR_END = 18'b010000000000000000;
parameter ROM_RD_WAIT = 4'h1; parameter ROM_RD_WAIT = 4'h4;
parameter ROM_RD_WAIT_MCU = 4'h6; parameter ROM_RD_WAIT_MCU = 4'h6;
parameter ROM_WR_WAIT = 4'h4; parameter ROM_WR_WAIT1 = 4'h2;
parameter ROM_WR_WAIT1 = 4'h3; parameter ROM_WR_WAIT2 = 4'h3;
parameter ROM_WR_WAIT2 = 4'h1; parameter ROM_WR_WAIT_MCU = 4'h6;
parameter ROM_WR_WAIT_MCU = 4'h5;
parameter SNES_DEAD_TIMEOUT = 17'd88000; // 1ms
reg [17:0] STATE; reg [17:0] STATE;
initial STATE = ST_IDLE; initial STATE = ST_IDLE;
reg [7:0] SNES_DINr;
reg [7:0] SNES_DOUTr;
reg [7:0] ROM_DOUTr;
assign DSPX_SNES_DATA_IN = SNES_DATA; assign DSPX_SNES_DATA_IN = SNES_DATA;
assign SRTC_SNES_DATA_IN = SNES_DATA[3:0]; assign SRTC_SNES_DATA_IN = SNES_DATA[3:0];
assign MSU_SNES_DATA_IN = SNES_DATA; assign MSU_SNES_DATA_IN = SNES_DATA;
assign BSX_SNES_DATA_IN = SNES_DATA; assign BSX_SNES_DATA_IN = SNES_DATA;
reg [7:0] SNES_DINr;
reg [7:0] ROM_DOUTr;
reg [7:0] r213fr; reg [7:0] r213fr;
reg r213f_forceread; reg r213f_forceread;
reg [2:0] r213f_delay; reg [2:0] r213f_delay;
@@ -503,17 +446,15 @@ initial r213f_forceread = 0;
initial r213f_state = 2'b01; initial r213f_state = 2'b01;
initial r213f_delay = 3'b011; initial r213f_delay = 3'b011;
reg[7:0] snescmd_regs[15:0];
assign SNES_DATA = (snescmd_rd_enable & ~SNES_PARD) ? snescmd_regs[SNES_ADDR[3:0]] assign SNES_DATA = (r213f_enable & (!SNES_PARD ^ r213f_forceread)) ? r213fr
:(r213f_enable & ~SNES_PARD & ~r213f_forceread) ? r213fr :(!SNES_READ ^ r213f_forceread)
:(~SNES_READ ^ (r213f_forceread & r213f_enable & ~SNES_PARD))
? (srtc_enable ? SRTC_SNES_DATA_OUT ? (srtc_enable ? SRTC_SNES_DATA_OUT
:dspx_enable ? DSPX_SNES_DATA_OUT :dspx_enable ? DSPX_SNES_DATA_OUT
:dspx_dp_enable ? DSPX_SNES_DATA_OUT :dspx_dp_enable ? DSPX_SNES_DATA_OUT
:msu_enable ? MSU_SNES_DATA_OUT :msu_enable ? MSU_SNES_DATA_OUT
:bsx_data_ovr ? BSX_SNES_DATA_OUT :bsx_data_ovr ? BSX_SNES_DATA_OUT
:SNES_DOUTr /*(ROM_ADDR0 ? ROM_DATA[7:0] : ROM_DATA[15:8])*/) : 8'bZ; :SNES_DINr /*(ROM_ADDR0 ? ROM_DATA[7:0] : ROM_DATA[15:8])*/) : 8'bZ;
reg [3:0] ST_MEM_DELAYr; reg [3:0] ST_MEM_DELAYr;
reg MCU_RD_PENDr; reg MCU_RD_PENDr;
@@ -525,39 +466,25 @@ always @(posedge CLK2) begin
else if(STATE & (ST_SNES_RD_END | ST_SNES_WR_END)) NEED_SNES_ADDRr <= 1'b0; else if(STATE & (ST_SNES_RD_END | ST_SNES_WR_END)) NEED_SNES_ADDRr <= 1'b0;
end end
reg RQ_MCU_RDYr; wire ASSERT_SNES_ADDR = SNES_CPU_CLK & NEED_SNES_ADDRr;
initial RQ_MCU_RDYr = 1'b1;
assign MCU_RDY = RQ_MCU_RDYr;
reg ROM_SAr; assign ROM_ADDR = (SD_DMA_TO_ROM) ? MCU_ADDR[23:1] : (ASSERT_SNES_ADDR) ? MAPPED_SNES_ADDR[23:1] : ROM_ADDRr[23:1];
initial ROM_SAr = 1'b1; assign ROM_ADDR0 = (SD_DMA_TO_ROM) ? MCU_ADDR[0] : (ASSERT_SNES_ADDR) ? MAPPED_SNES_ADDR[0] : ROM_ADDRr[0];
//wire ROM_SA = SNES_FAKE_CLK | ((STATE == ST_IDLE) ^ (~RQ_MCU_RDYr & SNES_cycle_end));
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_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;
reg ROM_DOUT_ENr;
initial ROM_DOUT_ENr = 1'b0;
reg[17:0] SNES_DEAD_CNTr; reg RQ_MCU_RDYr;
initial SNES_DEAD_CNTr = 0; initial RQ_MCU_RDYr = 1'b1;
assign MCU_RDY = RQ_MCU_RDYr;
always @(posedge CLK2) begin always @(posedge CLK2) begin
if(MCU_RRQ) begin if(MCU_RRQ) begin
MCU_RD_PENDr <= 1'b1; MCU_RD_PENDr <= 1'b1;
RQ_MCU_RDYr <= 1'b0; RQ_MCU_RDYr <= 1'b0;
ROM_ADDRr <= MCU_ADDR;
end else if(MCU_WRQ) begin end else if(MCU_WRQ) begin
MCU_WR_PENDr <= 1'b1; MCU_WR_PENDr <= 1'b1;
RQ_MCU_RDYr <= 1'b0; RQ_MCU_RDYr <= 1'b0;
ROM_ADDRr <= MCU_ADDR;
end else if(STATE & (ST_MCU_RD_END | ST_MCU_WR_END)) begin end else if(STATE & (ST_MCU_RD_END | ST_MCU_WR_END)) begin
MCU_RD_PENDr <= 1'b0; MCU_RD_PENDr <= 1'b0;
MCU_WR_PENDr <= 1'b0; MCU_WR_PENDr <= 1'b0;
@@ -565,127 +492,121 @@ always @(posedge CLK2) begin
end end
end end
always @(posedge CLK2) begin
if(~SNES_CPU_CLK) SNES_DEAD_CNTr <= SNES_DEAD_CNTr + 1;
else SNES_DEAD_CNTr <= 17'h0;
end
always @(posedge CLK2) begin
if(SNES_DEAD_CNTr > SNES_DEAD_TIMEOUT) SNES_DEADr <= 1'b1;
else if(SNES_CPU_CLK) SNES_DEADr <= 1'b0;
end
reg snes_wr_cycle; reg snes_wr_cycle;
always @(posedge CLK2) begin always @(posedge CLK2) begin
if(SNES_DEADr & SNES_CPU_CLK) STATE <= ST_IDLE; // interrupt+restart an ongoing MCU access when the SNES comes alive if(SNES_cycle_start & ~SNES_WR_start) begin
else STATE <= ST_SNES_RD_ADDR;
end else if(SNES_WR_start) begin
STATE <= ST_SNES_WR_ADDR;
end else begin
case(STATE) case(STATE)
ST_IDLE: begin ST_IDLE: begin
ROM_SAr <= 1'b1; ROM_ADDRr <= MAPPED_SNES_ADDR;
ROM_DOUT_ENr <= 1'b0; if(MCU_RD_PENDr) STATE <= ST_MCU_RD_ADDR;
if(SNES_cycle_start & ~SNES_WRITE) begin else if(MCU_WR_PENDr) STATE <= ST_MCU_WR_ADDR;
STATE <= ST_SNES_WR_ADDR; else STATE <= ST_IDLE;
if(IS_WRITABLE | (IS_FLASHWR & ~bsx_tristate)) begin
ROM_WEr <= 1'b0;
end
end else if(SNES_cycle_start) begin
STATE <= ST_SNES_RD_ADDR;
// STATE <= ST_SNES_RD_END;
end else if(SNES_DEADr & MCU_RD_PENDr) begin
STATE <= ST_MCU_RD_ADDR;
end else if(SNES_DEADr & MCU_WR_PENDr) begin
STATE <= ST_MCU_WR_ADDR;
end
end end
ST_SNES_RD_ADDR: begin ST_SNES_RD_ADDR: begin
ST_MEM_DELAYr <= ROM_RD_WAIT;
STATE <= ST_SNES_RD_WAIT; STATE <= ST_SNES_RD_WAIT;
ST_MEM_DELAYr <= ROM_RD_WAIT;
end end
ST_SNES_RD_WAIT: begin ST_SNES_RD_WAIT: begin
ST_MEM_DELAYr <= ST_MEM_DELAYr - 1; ST_MEM_DELAYr <= ST_MEM_DELAYr - 4'h1;
if(ST_MEM_DELAYr == 0) begin if(ST_MEM_DELAYr == 4'h0) STATE <= ST_SNES_RD_END;
STATE <= ST_SNES_RD_END;
SNES_DOUTr <= (ROM_ADDR0 ? ROM_DATA[7:0] : ROM_DATA[15:8]);
end
else STATE <= ST_SNES_RD_WAIT; else STATE <= ST_SNES_RD_WAIT;
if(ROM_ADDR0) SNES_DINr <= ROM_DATA[7:0];
else SNES_DINr <= ROM_DATA[15:8];
end
ST_SNES_RD_END: begin
STATE <= ST_IDLE;
if(ROM_ADDR0) SNES_DINr <= ROM_DATA[7:0];
else SNES_DINr <= ROM_DATA[15:8];
end end
ST_SNES_WR_ADDR: begin ST_SNES_WR_ADDR: begin
ROM_DOUT_ENr <= 1'b1; ROM_WEr <= (!IS_FLASHWR & !IS_WRITABLE);
ST_MEM_DELAYr <= ROM_WR_WAIT1; snes_wr_cycle <= 1'b1;
STATE <= ST_SNES_WR_WAIT1; STATE <= ST_SNES_WR_WAIT1;
ST_MEM_DELAYr <= ROM_WR_WAIT1;
end end
ST_SNES_WR_WAIT1: begin ST_SNES_WR_WAIT1: begin
ST_MEM_DELAYr <= ST_MEM_DELAYr - 1; ST_MEM_DELAYr <= ST_MEM_DELAYr - 4'h1;
if(ST_MEM_DELAYr == 0) begin if(ST_MEM_DELAYr == 4'h0) STATE <= ST_SNES_WR_DATA;
ST_MEM_DELAYr <= ROM_WR_WAIT2;
STATE <= ST_SNES_WR_WAIT2;
ROM_DOUTr <= SNES_DATA;
end
else STATE <= ST_SNES_WR_WAIT1; else STATE <= ST_SNES_WR_WAIT1;
end end
ST_SNES_WR_WAIT2: begin ST_SNES_WR_DATA: begin
ST_MEM_DELAYr <= ST_MEM_DELAYr - 1; ROM_DOUTr <= SNES_DATA;
if(ST_MEM_DELAYr == 0) begin ST_MEM_DELAYr <= ROM_WR_WAIT2;
STATE <= ST_SNES_WR_END; STATE <= ST_SNES_WR_WAIT2;
ROM_WEr <= 1'b1;
ROM_DOUT_ENr <= 1'b0;
end end
ST_SNES_WR_WAIT2: begin
ST_MEM_DELAYr <= ST_MEM_DELAYr - 4'h1;
if(ST_MEM_DELAYr == 4'h0) STATE <= ST_SNES_WR_END;
else STATE <= ST_SNES_WR_WAIT2; else STATE <= ST_SNES_WR_WAIT2;
end end
ST_SNES_RD_END, ST_SNES_WR_END: begin ST_SNES_WR_END: begin
// ROM_DOUT_ENr <= 1'b0; STATE <= ST_IDLE;
if(MCU_RD_PENDr) begin ROM_WEr <= 1'b1;
STATE <= ST_MCU_RD_ADDR; snes_wr_cycle <= 1'b0;
end else if(MCU_WR_PENDr) begin
STATE <= ST_MCU_WR_ADDR;
end else STATE <= ST_IDLE;
end end
ST_MCU_RD_ADDR: begin ST_MCU_RD_ADDR: begin
ROM_SAr <= 1'b0; ROM_ADDRr <= MCU_ADDR;
ST_MEM_DELAYr <= ROM_RD_WAIT_MCU;
STATE <= ST_MCU_RD_WAIT; STATE <= ST_MCU_RD_WAIT;
ST_MEM_DELAYr <= ROM_RD_WAIT_MCU;
end end
ST_MCU_RD_WAIT: begin ST_MCU_RD_WAIT: begin
ST_MEM_DELAYr <= ST_MEM_DELAYr - 1; ST_MEM_DELAYr <= ST_MEM_DELAYr - 4'h1;
if(ST_MEM_DELAYr == 0) begin if(ST_MEM_DELAYr == 4'h0) begin
STATE <= ST_MCU_RD_END; STATE <= ST_MCU_RD_WAIT2;
ST_MEM_DELAYr <= 4'h2;
end end
else STATE <= ST_MCU_RD_WAIT; else STATE <= ST_MCU_RD_WAIT;
if(ROM_ADDR0) MCU_DINr <= ROM_DATA[7:0];
else MCU_DINr <= ROM_DATA[15:8];
end
ST_MCU_RD_WAIT2: begin
ST_MEM_DELAYr <= ST_MEM_DELAYr - 4'h1;
if(ST_MEM_DELAYr == 4'h0) begin
STATE <= ST_MCU_RD_END;
end else STATE <= ST_MCU_RD_WAIT2;
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];*/
STATE <= ST_IDLE; STATE <= ST_IDLE;
end end
ST_MCU_WR_ADDR: begin ST_MCU_WR_ADDR: begin
ROM_DOUTr <= MCU_DOUT; ROM_ADDRr <= MCU_ADDR;
ROM_SAr <= 1'b0;
ST_MEM_DELAYr <= ROM_WR_WAIT_MCU;
STATE <= ST_MCU_WR_WAIT; STATE <= ST_MCU_WR_WAIT;
ST_MEM_DELAYr <= ROM_WR_WAIT_MCU;
ROM_DOUTr <= MCU_DOUT;
ROM_WEr <= 1'b0; ROM_WEr <= 1'b0;
end end
ST_MCU_WR_WAIT: begin ST_MCU_WR_WAIT: begin
ST_MEM_DELAYr <= ST_MEM_DELAYr - 1; ST_MEM_DELAYr <= ST_MEM_DELAYr - 4'h1;
ROM_DOUT_ENr <= 1'b1; if(ST_MEM_DELAYr == 4'h0) begin
if(ST_MEM_DELAYr == 0) begin
ROM_WEr <= 1'b1; ROM_WEr <= 1'b1;
STATE <= ST_MCU_WR_END; STATE <= ST_MCU_WR_WAIT2;
ST_MEM_DELAYr <= 4'h2;
end end
else STATE <= ST_MCU_WR_WAIT; else STATE <= ST_MCU_WR_WAIT;
end
ST_MCU_WR_WAIT2: begin
ST_MEM_DELAYr <= ST_MEM_DELAYr - 4'h1;
if(ST_MEM_DELAYr == 4'h0) begin
STATE <= ST_MCU_WR_END;
end else STATE <= ST_MCU_WR_WAIT2;
end end
ST_MCU_WR_END: begin ST_MCU_WR_END: begin
ROM_DOUT_ENr <= 1'b0;
STATE <= ST_IDLE; STATE <= ST_IDLE;
end end
endcase endcase
end end
end
always @(posedge CLK2) begin always @(posedge SYSCLK2) begin
if(SNES_cycle_end) r213f_forceread <= 1'b1; if(SNES_PARD_start & r213f_enable) begin
else if(SNES_PARD_start & r213f_enable) begin r213f_forceread <= 1'b1;
r213f_delay <= 3'b000; r213f_delay <= 3'b001;
r213f_state <= 2'b10; r213f_state <= 2'b10;
end else if(r213f_state == 2'b10) begin end else if(r213f_state == 2'b10) begin
r213f_delay <= r213f_delay - 1; r213f_delay <= r213f_delay - 1;
@@ -697,106 +618,46 @@ always @(posedge CLK2) begin
end end
end end
always @(posedge CLK2) begin
if(SNES_WR_end & snescmd_wr_enable) begin
snescmd_regs[SNES_ADDR[3:0]] <= SNES_DATA;
end
end
reg ROM_WE_1;
reg MCU_WRITE_1;
always @(posedge CLK2) begin
ROM_WE_1 <= ROM_WE;
MCU_WRITE_1<= MCU_WRITE;
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 ? MCU_DOUT : 8'bZ)
//: ((~SNES_WRITE & (IS_WRITABLE | IS_FLASHWR)) ? SNES_DATA : (!ROM_WE ? 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 ? MCU_DOUT : 8'bZ)
//: ((~SNES_WRITE & (IS_WRITABLE | IS_FLASHWR)) ? SNES_DATA : (!ROM_WE ? 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
:/*(SNES_FAKE_CLK & (IS_WRITABLE | IS_FLASHWR)) ? SNES_WRITE :*/ ROM_WEr; :ROM_WEr | (ASSERT_SNES_ADDR & ~snes_wr_cycle);
// OE always active. Overridden by WE when needed. // OE always active. Overridden by WE when needed.
assign ROM_OE = 1'b0; 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 = !ROM_WE ? ROM_ADDR0 : 1'b0;
assign ROM_BLE = 1'b0; ///*(~SD_DMA_TO_ROM & ~ROM_WE & ~ROM_SA) ?*/ !ROM_ADDR0 /*: 1'b0*/; assign ROM_BLE = !ROM_WE ? !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 :
bsx_data_ovr ? (SNES_READ & SNES_WRITE) : bsx_data_ovr ? (SNES_READ & SNES_WRITE) :
srtc_enable ? (SNES_READ & SNES_WRITE) : srtc_enable ? (SNES_READ & SNES_WRITE) :
bs_page_enable ? (SNES_READ) :
r213f_enable & !SNES_PARD ? 1'b0 : r213f_enable & !SNES_PARD ? 1'b0 :
(snescmd_wr_enable | snescmd_rd_enable) & !SNES_PARD ? 1'b0 :
((IS_ROM & SNES_CS) ((IS_ROM & SNES_CS)
|(!IS_ROM & !IS_SAVERAM & !IS_WRITABLE & !IS_FLASHWR) |(!IS_ROM & !IS_SAVERAM & !IS_WRITABLE & !IS_FLASHWR)
|(SNES_READr[0] & SNES_WRITEr[0]) |(SNES_READ & SNES_WRITE)
| bsx_tristate
); );
assign SNES_DATABUS_DIR = (!SNES_READr[0] | (!SNES_PARD & (r213f_enable | snescmd_rd_enable))) assign SNES_DATABUS_DIR = (!SNES_READ | (!SNES_PARD & r213f_enable))
? 1'b1 ^ (r213f_forceread & r213f_enable & ~SNES_PARD) ? 1'b1 ^ r213f_forceread
: 1'b0; : 1'b0;
assign SNES_IRQ = 1'b0; assign IRQ_DIR = 1'b0;
assign SNES_IRQ = 1'bZ;
assign p113_out = 1'b1; assign p113_out = 1'b0;
/*
wire [35:0] CONTROL0;
icon icon (
.CONTROL0(CONTROL0) // INOUT BUS [35:0]
);
ila_srtc ila (
.CONTROL(CONTROL0), // INOUT BUS [35:0]
.CLK(CLK2), // IN
.TRIG0(SNES_ADDR), // IN BUS [23:0]
.TRIG1(SNES_DATA), // IN BUS [7:0]
.TRIG2({SNES_READ, SNES_WRITE, SNES_CPU_CLK, SNES_cycle_start, SNES_cycle_end, SNES_DEADr, MCU_RRQ, MCU_WRQ, MCU_RDY, ROM_WEr, ROM_WE, ROM_DOUT_ENr, ROM_SA, DBG_mcu_nextaddr, SNES_DATABUS_DIR, SNES_DATABUS_OE}), // IN BUS [15:0]
.TRIG3({bsx_data_ovr, SPI_SCK, SPI_MISO, SPI_MOSI, spi_cmd_ready, spi_param_ready, spi_input_data, SD_DAT}), // IN BUS [17:0]
.TRIG4(ROM_ADDRr), // IN BUS [23:0]
.TRIG5(ROM_DATA), // IN BUS [15:0]
.TRIG6(MCU_DINr), // IN BUS [7:0]
.TRIG7(spi_byte_cnt[3:0])
);
*/
/*
ila_srtc ila (
.CONTROL(CONTROL0), // INOUT BUS [35:0]
.CLK(CLK2), // IN
.TRIG0(SD_DMA_DBG_cyclecnt), // IN BUS [23:0]
.TRIG1(SD_DMA_SRAM_DATA), // IN BUS [7:0]
.TRIG2({SPI_SCK, SPI_MOSI, SPI_MISO, spi_cmd_ready, SD_DMA_SRAM_WE, SD_DMA_EN, SD_CLK, SD_DAT, SD_DMA_NEXTADDR, SD_DMA_STATUS, 3'b000}), // IN BUS [15:0]
.TRIG3({spi_cmd_data, spi_param_data}), // IN BUS [17:0]
.TRIG4(ROM_ADDRr), // IN BUS [23:0]
.TRIG5(ROM_DATA), // IN BUS [15:0]
.TRIG6(MCU_DINr), // IN BUS [7:0]
.TRIG7(ST_MEM_DELAYr)
);
*/
endmodule endmodule

View File

@@ -97,10 +97,7 @@ module mcu_cmd(
output reg region_out, output reg region_out,
// SNES sync/clk // SNES sync/clk
input snes_sysclk, input snes_sysclk
// debug
output DBG_mcu_nextaddr
); );
initial begin initial begin
@@ -143,13 +140,12 @@ reg [55:0] rtc_data_out_buf;
reg rtc_pgm_we_buf; reg rtc_pgm_we_buf;
reg srtc_reset_buf; reg srtc_reset_buf;
initial srtc_reset_buf = 0;
reg [31:0] SNES_SYSCLK_FREQ_BUF; reg [31:0] SNES_SYSCLK_FREQ_BUF;
reg [7:0] MCU_DATA_OUT_BUF; reg [7:0] MCU_DATA_OUT_BUF;
reg [7:0] MCU_DATA_IN_BUF; reg [7:0] MCU_DATA_IN_BUF;
reg [2:0] mcu_nextaddr_buf; reg [1:0] mcu_nextaddr_buf;
wire mcu_nextaddr; wire mcu_nextaddr;
@@ -202,7 +198,7 @@ always @(posedge clk) begin
SD_DMA_PARTIALr <= cmd_data[2]; SD_DMA_PARTIALr <= cmd_data[2];
end end
4'h8: SD_DMA_TGTr <= 2'b00; 4'h8: SD_DMA_TGTr <= 2'b00;
4'h9: SD_DMA_TGTr <= 2'b00; // cmd_data[1:0]; // not implemented 4'h9: SD_DMA_TGTr <= cmd_data[1:0]; // not implemented
// 4'hE: // 4'hE:
// select memory unit // select memory unit
endcase endcase
@@ -414,9 +410,9 @@ end
// value fetch during last SPI bit // value fetch during last SPI bit
always @(posedge clk) begin always @(posedge clk) begin
if (cmd_data[7:4] == 4'h8 && mcu_nextaddr) if (cmd_data[7:4] == 4'h8 && mcu_nextaddr_buf == 2'b01)
MCU_DATA_IN_BUF <= mcu_data_in; MCU_DATA_IN_BUF <= mcu_data_in;
else if (cmd_ready | param_ready /* bit_cnt == 7 */) begin else if (spi_bit_cnt == 3'h7) begin
if (cmd_data[7:0] == 8'hF0) if (cmd_data[7:0] == 8'hF0)
MCU_DATA_IN_BUF <= 8'hA5; MCU_DATA_IN_BUF <= 8'hA5;
else if (cmd_data[7:0] == 8'hF1) else if (cmd_data[7:0] == 8'hF1)
@@ -466,7 +462,7 @@ end
// nextaddr pulse generation // nextaddr pulse generation
always @(posedge clk) begin always @(posedge clk) begin
mcu_nextaddr_buf <= {mcu_nextaddr_buf[1:0], mcu_rq_rdy}; mcu_nextaddr_buf <= {mcu_nextaddr_buf[0], mcu_rq_rdy};
end end
parameter ST_RQ = 2'b01; parameter ST_RQ = 2'b01;
@@ -549,5 +545,4 @@ assign mcu_mapper = MAPPER_BUF;
assign rom_mask_out = ROM_MASK; assign rom_mask_out = ROM_MASK;
assign saveram_mask_out = SAVERAM_MASK; assign saveram_mask_out = SAVERAM_MASK;
assign DBG_mcu_nextaddr = mcu_nextaddr;
endmodule endmodule

View File

@@ -38,13 +38,7 @@ module msu(
input [5:0] status_set_bits, input [5:0] status_set_bits,
input status_reset_we, input status_reset_we,
input [13:0] msu_address_ext, input [13:0] msu_address_ext,
input msu_address_ext_write, input msu_address_ext_write
output DBG_msu_reg_oe_rising,
output DBG_msu_reg_oe_falling,
output DBG_msu_reg_we_rising,
output [13:0] DBG_msu_address,
output DBG_msu_address_ext_write_rising
); );
reg [2:0] reg_addr_r [3:0]; reg [2:0] reg_addr_r [3:0];
@@ -62,15 +56,13 @@ wire status_reset_en = (status_reset_we_r == 2'b01);
reg [13:0] msu_address_r; reg [13:0] msu_address_r;
wire [13:0] msu_address = msu_address_r; wire [13:0] msu_address = msu_address_r;
initial msu_address_r = 13'b0;
wire [7:0] msu_data; wire [7:0] msu_data;
reg [7:0] msu_data_r;
reg [2:0] msu_address_ext_write_sreg; reg [1:0] msu_address_ext_write_sreg;
always @(posedge clkin) always @(posedge clkin)
msu_address_ext_write_sreg <= {msu_address_ext_write_sreg[1:0], msu_address_ext_write}; msu_address_ext_write_sreg <= {msu_address_ext_write_sreg[0], msu_address_ext_write};
wire msu_address_ext_write_rising = (msu_address_ext_write_sreg[2:1] == 2'b01); wire msu_address_ext_write_rising = (msu_address_ext_write_sreg[1:0] == 2'b01);
reg [4:0] reg_enable_sreg; reg [4:0] reg_enable_sreg;
initial reg_enable_sreg = 5'b11111; initial reg_enable_sreg = 5'b11111;
@@ -78,12 +70,11 @@ always @(posedge clkin) reg_enable_sreg <= {reg_enable_sreg[3:0], enable};
reg [5:0] reg_oe_sreg; reg [5:0] reg_oe_sreg;
always @(posedge clkin) reg_oe_sreg <= {reg_oe_sreg[4:0], reg_oe}; always @(posedge clkin) reg_oe_sreg <= {reg_oe_sreg[4:0], reg_oe};
wire reg_oe_rising = reg_enable_sreg[4] && (reg_oe_sreg[5:1] == 5'b00001); wire reg_oe_rising = reg_enable_sreg[4] && (reg_oe_sreg[5:0] == 6'b000001);
wire reg_oe_falling = reg_enable_sreg[1] && (reg_oe_sreg[5:1] == 5'b11110);
reg [5:0] reg_we_sreg; reg [5:0] reg_we_sreg;
always @(posedge clkin) reg_we_sreg <= {reg_we_sreg[4:0], reg_we}; always @(posedge clkin) reg_we_sreg <= {reg_we_sreg[4:0], reg_we};
wire reg_we_rising = reg_enable_sreg[4] && (reg_we_sreg[5:1] == 5'b00001); wire reg_we_rising = reg_enable_sreg[4] && (reg_we_sreg[5:0] == 6'b000001);
reg [31:0] addr_out_r; reg [31:0] addr_out_r;
assign addr_out = addr_out_r; assign addr_out = addr_out_r;
@@ -102,27 +93,14 @@ reg audio_busy_r;
reg data_start_r; reg data_start_r;
reg data_busy_r; reg data_busy_r;
reg ctrl_start_r; reg ctrl_start_r;
reg audio_error_r;
reg [1:0] audio_ctrl_r; reg [1:0] audio_ctrl_r;
reg [1:0] audio_status_r; reg [1:0] audio_status_r;
initial begin initial begin
audio_busy_r = 1'b1; audio_busy_r <= 1'b1;
data_busy_r = 1'b1; data_busy_r <= 1'b1;
audio_error_r = 1'b0;
volume_r = 8'h00;
addr_out_r = 32'h00000000;
track_out_r = 16'h0000;
data_start_r = 1'b0;
audio_start_r = 1'b0;
end end
assign DBG_msu_address = msu_address;
assign DBG_msu_reg_oe_rising = reg_oe_rising;
assign DBG_msu_reg_oe_falling = reg_oe_falling;
assign DBG_msu_reg_we_rising = reg_we_rising;
assign DBG_msu_address_ext_write_rising = msu_address_ext_write_rising;
assign status_out = {msu_address_r[13], // 6 assign status_out = {msu_address_r[13], // 6
audio_start_r, // 5 audio_start_r, // 5
data_start_r, // 4 data_start_r, // 4
@@ -146,8 +124,8 @@ reg [7:0] data_out_r;
assign reg_data_out = data_out_r; assign reg_data_out = data_out_r;
always @(posedge clkin) begin always @(posedge clkin) begin
case(reg_addr_r[1]) case(reg_addr_r[3])
3'h0: data_out_r <= {data_busy_r, audio_busy_r, audio_status_r, audio_error_r, 3'b001}; 3'h0: data_out_r <= {data_busy_r, audio_busy_r, audio_status_r, 4'b0001};
3'h1: data_out_r <= msu_data; 3'h1: data_out_r <= msu_data;
3'h2: data_out_r <= 8'h53; 3'h2: data_out_r <= 8'h53;
3'h3: data_out_r <= 8'h2d; 3'h3: data_out_r <= 8'h2d;
@@ -160,7 +138,7 @@ end
always @(posedge clkin) begin always @(posedge clkin) begin
if(reg_we_rising) begin if(reg_we_rising) begin
case(reg_addr_r[1]) case(reg_addr_r[3])
3'h0: addr_out_r[7:0] <= reg_data_in; 3'h0: addr_out_r[7:0] <= reg_data_in;
3'h1: addr_out_r[15:8] <= reg_data_in; 3'h1: addr_out_r[15:8] <= reg_data_in;
3'h2: addr_out_r[23:16] <= reg_data_in; 3'h2: addr_out_r[23:16] <= reg_data_in;
@@ -195,7 +173,7 @@ always @(posedge clkin) begin
data_busy_r <= (data_busy_r | status_set_bits[4]) & ~status_reset_bits[4]; data_busy_r <= (data_busy_r | status_set_bits[4]) & ~status_reset_bits[4];
if(status_reset_bits[4]) data_start_r <= 1'b0; if(status_reset_bits[4]) data_start_r <= 1'b0;
audio_error_r <= (audio_error_r | status_set_bits[3]) & ~status_reset_bits[3]; // volume_start_r <= (volume_start_r | status_set_bits[3]) & ~status_reset_bits[3];
audio_status_r <= (audio_status_r | status_set_bits[2:1]) & ~status_reset_bits[2:1]; audio_status_r <= (audio_status_r | status_set_bits[2:1]) & ~status_reset_bits[2:1];

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