Merge commit 'v0.1.2'
Conflicts: cic/supercic/supercic-key.asm pcb/kicad/RevE/fpga.sch pcb/kicad/RevE/mcu.sch pcb/kicad/RevE/memory.sch pcb/kicad/RevE/pwr_misc.sch pcb/kicad/RevE/sd2snes.brd pcb/kicad/RevE/sd2snes.net pcb/kicad/RevE/sd2snes.sch pcb/kicad/RevE/snesslot.sch pcb/kicad/libs/mypackages.mod pcb/kicad/libs/sdcard.bak pcb/kicad/libs/sdcard.mod snes/Makefile snes/const.a65 snes/data.a65 snes/header.a65 snes/mainmenu.a65 snes/memmap.i65 snes/menu.a65 snes/text.a65 snes/time.a65 src/Makefile src/bootldr/Makefile src/bootldr/clock.c src/bootldr/config.h src/bootldr/ffconf.h src/bootldr/iap.c src/bootldr/lpc1754boot.ld src/bootldr/main.c src/bootldr/timer.c src/bootldr/uart.c src/cic.c src/cic.h src/cli.c src/config src/config.h src/ff.c src/ff.h src/ffconf.h src/fileops.c src/fileops.h src/filetypes.c src/filetypes.h src/flash.script src/fpga_spi.c src/fpga_spi.h src/lpc1754.ld src/main.c src/memory.c src/memory.h src/msu1.c src/sdnative.c src/sdnative.h src/smc.c src/smc.h src/snes.h verilog/sd2snes/address.v verilog/sd2snes/main.ucf verilog/sd2snes/main.v verilog/sd2snes/mcu_cmd.v verilog/sd2snes/sd2snes.xise verilog/sd2snes/sd_dma.v
This commit is contained in:
commit
481237636c
24
CHANGELOG
Normal file
24
CHANGELOG
Normal file
@ -0,0 +1,24 @@
|
||||
v0.1.1
|
||||
======
|
||||
|
||||
* initial public release
|
||||
|
||||
|
||||
v0.1.1a (bugfix release)
|
||||
========================
|
||||
|
||||
* Fixes:
|
||||
- SuperCIC pair mode was erroneously enabled in firmware binary
|
||||
- SNES menu crashed on empty database
|
||||
|
||||
|
||||
v0.1.2
|
||||
======
|
||||
|
||||
* Auto region override (eliminate "This game pak is not designed..." messages)
|
||||
* Improved mapper detection (fixes Batman vs. Joker and many PD ROMs)
|
||||
* Improved data streaming performance
|
||||
(should reduce MSU1 errors with some cards)
|
||||
* A and B buttons swapped in menu to match common key mappings
|
||||
* Fixes:
|
||||
- MSU1: Stop audio playback on end of audio file
|
||||
747
cic/supercic/supercic-key.asm
Normal file
747
cic/supercic/supercic-key.asm
Normal file
@ -0,0 +1,747 @@
|
||||
#include <p12f629.inc>
|
||||
processor p12f629
|
||||
|
||||
; ---------------------------------------------------------------------
|
||||
; SNES CIC clone for PIC Microcontroller (key mode only)
|
||||
;
|
||||
; Copyright (C) 2010 by Maximilian Rehkopf (ikari_01) <otakon@gmx.net>
|
||||
; This software is part of the sd2snes project.
|
||||
;
|
||||
; 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
|
||||
;
|
||||
; ---------------------------------------------------------------------
|
||||
;
|
||||
; pin configuration: (cartridge pin) [key CIC pin]
|
||||
;
|
||||
; ,---_---.
|
||||
; +5V (27,58) [16] |1 8| GND (5,36) [8]
|
||||
; CIC clk (56) [6] |2 7| CIC data i/o 0 (55) [2]
|
||||
; status out |3 6| CIC data i/o 1 (24) [1]
|
||||
; /PAIR |4 5| CIC slave reset (25) [7]
|
||||
; `-------'
|
||||
;
|
||||
;
|
||||
; Status out can be connected to a LED. It indicates:
|
||||
;
|
||||
; state | output
|
||||
; -------------------------+----------------------------
|
||||
; OK or no lock CIC | high
|
||||
; error | low
|
||||
; SuperCIC pair mode | 148.75kHz / 50% duty cycle
|
||||
; SuperCIC host detected | scarce spikes (3.3us)
|
||||
; but pair mode disabled |
|
||||
;
|
||||
; In case lockout fails, the region is switched automatically and
|
||||
; will be used after the next reset.
|
||||
;
|
||||
; The /PAIR pin can be used to enable or disable SuperCIC pair mode.
|
||||
; It can be tied low or high to statically enable or disable pair mode
|
||||
; detection, or connected to a switch or MCU to dynamically enable pair
|
||||
; mode detection (it should then be connected to a pull-up resistor to
|
||||
; Vcc). Pair mode detection can be enabled during operation,
|
||||
; but pair mode cannot be left until the next power cycle.
|
||||
; See SuperCIC lock documentation for a more detailed description of
|
||||
; pair mode.
|
||||
;
|
||||
; memory usage:
|
||||
;
|
||||
; 0x20 buffer for seed calc and transfer
|
||||
; 0x21 - 0x2f seed area (lock seed)
|
||||
; 0x30 buffer for seed calc
|
||||
; 0x31 - 0x3f seed area (key seed; 0x31 filled in by lock)
|
||||
; 0x40 - 0x41 buffer for seed calc
|
||||
; 0x4d buffer for eeprom access
|
||||
; 0x4e loop variable for longwait
|
||||
; 0x4f loop variable for wait
|
||||
; 0x5c GPIO buffer variable for pair mode allow
|
||||
; 0x5d 0: SuperCIC pair mode available flag
|
||||
; 0x5e SuperCIC pair mode detect (phase 1)
|
||||
; 0x5f SuperCIC pair mode detect (phase 2)
|
||||
; ---------------------------------------------------------------------
|
||||
|
||||
|
||||
; -----------------------------------------------------------------------
|
||||
__CONFIG _EC_OSC & _WDT_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _CPD_OFF
|
||||
|
||||
; -----------------------------------------------------------------------
|
||||
; code memory
|
||||
org 0x0000
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
goto init
|
||||
isr
|
||||
org 0x0004
|
||||
bcf INTCON, 1 ; clear interrupt cause
|
||||
bcf GPIO, 0
|
||||
bcf GPIO, 1
|
||||
bsf GPIO, 4 ; LED on
|
||||
clrf 0x5e ; clear pair mode detect
|
||||
clrf 0x5f ; clear pair mode detect
|
||||
bsf 0x5f, 1 ;
|
||||
clrf 0x5d ; clear pair mode available
|
||||
clrf 0x5c ; clear pair mode allow buffer
|
||||
bsf 0x5c, 3 ; assume disallow
|
||||
bsf INTCON, 7 ; re-enable interrupts (ISR will continue as main)
|
||||
goto main
|
||||
init
|
||||
org 0x0010
|
||||
banksel GPIO
|
||||
clrf GPIO
|
||||
movlw 0x07 ; GPIO2..0 are digital I/O (not connected to comparator)
|
||||
movwf CMCON
|
||||
movlw 0x90 ; global enable interrupts + enable external interrupt
|
||||
movwf INTCON
|
||||
banksel TRISIO
|
||||
movlw 0x2d ; in out in in out in
|
||||
movwf TRISIO
|
||||
movlw 0x24 ; pullups for reset+clk to avoid errors when no CIC in host
|
||||
movwf WPU
|
||||
movlw 0x00 ; 0x80 for global pullup disable
|
||||
movwf OPTION_REG
|
||||
|
||||
banksel GPIO
|
||||
bsf GPIO, 4 ; LED on
|
||||
idle
|
||||
goto idle ; wait for interrupt from lock
|
||||
|
||||
main
|
||||
banksel TRISIO
|
||||
bsf TRISIO, 0
|
||||
bcf TRISIO, 1
|
||||
banksel GPIO
|
||||
; --------INIT LOCK SEED (what the lock sends)--------
|
||||
movlw 0xb
|
||||
movwf 0x21
|
||||
movlw 0x1
|
||||
movwf 0x22
|
||||
movlw 0x4
|
||||
movwf 0x23
|
||||
movlw 0xf
|
||||
movwf 0x24
|
||||
movlw 0x4
|
||||
movwf 0x25
|
||||
movlw 0xb
|
||||
movwf 0x26
|
||||
movlw 0x5
|
||||
movwf 0x27
|
||||
movlw 0x7
|
||||
movwf 0x28
|
||||
movlw 0xf
|
||||
movwf 0x29
|
||||
movlw 0xd
|
||||
movwf 0x2a
|
||||
movlw 0x6
|
||||
movwf 0x2b
|
||||
movlw 0x1
|
||||
movwf 0x2c
|
||||
movlw 0xe
|
||||
movwf 0x2d
|
||||
movlw 0x9
|
||||
movwf 0x2e
|
||||
movlw 0x8
|
||||
movwf 0x2f
|
||||
|
||||
; --------INIT KEY SEED (what we must send)--------
|
||||
banksel EEADR ; D/F411 and D/F413
|
||||
clrf EEADR ; differ in 2nd seed nibble
|
||||
bsf EECON1, RD ; of key stream,
|
||||
movf EEDAT, w ; restore saved nibble from EEPROM
|
||||
banksel GPIO
|
||||
movwf 0x32
|
||||
movlw 0xa
|
||||
movwf 0x33
|
||||
movlw 0x1
|
||||
movwf 0x34
|
||||
movlw 0x8
|
||||
movwf 0x35
|
||||
movlw 0x5
|
||||
movwf 0x36
|
||||
movlw 0xf
|
||||
movwf 0x37
|
||||
movlw 0x1
|
||||
movwf 0x38
|
||||
movwf 0x39
|
||||
movlw 0xe
|
||||
movwf 0x3a
|
||||
movlw 0x1
|
||||
movwf 0x3b
|
||||
movlw 0x0
|
||||
movwf 0x3c
|
||||
movlw 0xd
|
||||
movwf 0x3d
|
||||
movlw 0xe
|
||||
movwf 0x3e
|
||||
movlw 0xc
|
||||
movwf 0x3f
|
||||
|
||||
; --------wait for stream ID--------
|
||||
movlw 0xb5
|
||||
call wait
|
||||
clrf 0x31 ; clear lock stream ID
|
||||
|
||||
; --------lock sends stream ID. 15 cycles per bit--------
|
||||
; bsf GPIO, 0 ; (debug marker)
|
||||
; bcf GPIO, 0 ;
|
||||
btfsc GPIO, 0 ; check stream ID bit
|
||||
bsf 0x31, 3 ; copy to lock seed
|
||||
movlw 0x2 ; wait=3*W+5
|
||||
call wait ; burn 11 cycles
|
||||
nop
|
||||
nop
|
||||
|
||||
; bsf GPIO, 0
|
||||
; bcf GPIO, 0
|
||||
btfsc GPIO, 0 ; check stream ID bit
|
||||
bsf 0x31, 0 ; copy to lock seed
|
||||
movlw 0x2 ;
|
||||
call wait ; burn 11 cycles
|
||||
nop
|
||||
nop
|
||||
|
||||
; bsf GPIO, 0
|
||||
; bcf GPIO, 0
|
||||
btfsc GPIO, 0 ; check stream ID bit
|
||||
bsf 0x31, 1 ; copy to lock seed
|
||||
movlw 0x2 ;
|
||||
call wait ; burn 11 cycles
|
||||
nop
|
||||
nop
|
||||
|
||||
; bsf GPIO, 0
|
||||
; bcf GPIO, 0
|
||||
btfsc GPIO, 0 ; check stream ID bit
|
||||
bsf 0x31, 2 ; copy to lock seed
|
||||
banksel TRISIO
|
||||
bcf TRISIO, 0
|
||||
bsf TRISIO, 1
|
||||
banksel GPIO
|
||||
nop
|
||||
movlw 0x27 ; "wait" 1
|
||||
call wait ; wait 121
|
||||
; --------main loop--------
|
||||
loop
|
||||
movlw 0x1
|
||||
loop0
|
||||
addlw 0x30 ; key stream
|
||||
movwf FSR ; store in index reg
|
||||
loop1
|
||||
nop
|
||||
nop
|
||||
movf INDF, w ; load seed value
|
||||
movwf 0x20
|
||||
bcf 0x20, 1 ; clear bit 1
|
||||
btfsc 0x20, 0 ; copy from bit 0
|
||||
bsf 0x20, 1 ; (if set)
|
||||
bsf 0x20, 4 ; LED on
|
||||
movf 0x20, w
|
||||
movwf GPIO
|
||||
nop
|
||||
movlw 0x10
|
||||
movwf GPIO ; reset GPIO
|
||||
movlw 0x14
|
||||
call wait
|
||||
btfsc 0x5d, 0 ; pair mode available signal
|
||||
bcf GPIO, 4 ;
|
||||
nop
|
||||
nop
|
||||
bsf GPIO, 4 ;
|
||||
btfsc GPIO, 0 ; both pins must be low...
|
||||
goto die
|
||||
btfsc GPIO, 1 ; ...when no bit transfer takes place
|
||||
goto die ; if not -> lock cic error state -> die
|
||||
incf FSR, f ; next one
|
||||
movlw 0xf
|
||||
andwf FSR, w
|
||||
btfss STATUS, Z
|
||||
goto loop1
|
||||
call mangle
|
||||
call mangle
|
||||
call mangle
|
||||
movlw 0x2 ; wait 10
|
||||
call wait ;
|
||||
nop
|
||||
nop
|
||||
btfsc 0x37, 0
|
||||
goto swap
|
||||
banksel TRISIO
|
||||
bcf TRISIO, 0
|
||||
bsf TRISIO, 1
|
||||
goto swapskip
|
||||
swap
|
||||
banksel TRISIO
|
||||
bsf TRISIO, 0
|
||||
bcf TRISIO, 1
|
||||
nop
|
||||
swapskip
|
||||
banksel GPIO
|
||||
movf 0x37, w
|
||||
andlw 0xf
|
||||
btfss STATUS, Z
|
||||
goto loop0
|
||||
goto loop
|
||||
|
||||
; --------calculate new seeds--------
|
||||
; had to be unrolled because PIC has an inefficient way of handling
|
||||
; indirect access, no post increment, etc.
|
||||
mangle
|
||||
call mangle_lock
|
||||
movf GPIO, w ; buffer GPIO state
|
||||
movwf 0x5c ; for pair mode "transaction"
|
||||
mangle_key
|
||||
movf 0x2f, w
|
||||
movwf 0x20
|
||||
mangle_key_loop
|
||||
addlw 0x1
|
||||
addwf 0x21, f
|
||||
movf 0x22, w
|
||||
movwf 0x40
|
||||
movf 0x21, w
|
||||
addwf 0x22, f
|
||||
incf 0x22, f
|
||||
comf 0x22, f
|
||||
movf 0x23, w
|
||||
movwf 0x41 ; store 23 to 41
|
||||
movlw 0xf
|
||||
andwf 0x23, f
|
||||
movf 0x40, w ; add 40(22 old)+23+#1 and skip if carry
|
||||
andlw 0xf
|
||||
addwf 0x23, f
|
||||
incf 0x23, f
|
||||
btfsc 0x23, 4
|
||||
goto mangle_key_withskip
|
||||
mangle_key_withoutskip
|
||||
movf 0x41, w ; restore 23
|
||||
addwf 0x24, f ; add to 24
|
||||
movf 0x25, w
|
||||
movwf 0x40 ; save 25 to 40
|
||||
movf 0x24, w
|
||||
addwf 0x25, f
|
||||
movf 0x26, w
|
||||
movwf 0x41 ; save 26 to 41
|
||||
movf 0x40, w ; restore 25
|
||||
andlw 0xf ; mask nibble
|
||||
addlw 0x8 ; add #8 to HIGH nibble
|
||||
movwf 0x40
|
||||
btfss 0x40, 4 ; skip if carry to 5th bit
|
||||
addwf 0x26, w
|
||||
movwf 0x26
|
||||
|
||||
movf 0x41, w ; restore 26
|
||||
addlw 0x1 ; inc
|
||||
addwf 0x27, f ; add to 27
|
||||
|
||||
movf 0x27, w ;
|
||||
addlw 0x1 ; inc
|
||||
addwf 0x28, f ; add to 28
|
||||
|
||||
movf 0x28, w ;
|
||||
addlw 0x1 ; inc
|
||||
addwf 0x29, f ; add to 29
|
||||
|
||||
movf 0x29, w ;
|
||||
addlw 0x1 ; inc
|
||||
addwf 0x2a, f ; add to 2a
|
||||
|
||||
movf 0x2a, w ;
|
||||
addlw 0x1 ; inc
|
||||
addwf 0x2b, f ; add to 2b
|
||||
|
||||
movf 0x2b, w ;
|
||||
addlw 0x1 ; inc
|
||||
addwf 0x2c, f ; add to 2c
|
||||
|
||||
movf 0x2c, w ;
|
||||
addlw 0x1 ; inc
|
||||
addwf 0x2d, f ; add to 2d
|
||||
|
||||
movf 0x2d, w ;
|
||||
addlw 0x1 ; inc
|
||||
addwf 0x2e, f ; add to 2e
|
||||
|
||||
movf 0x2e, w ;
|
||||
addlw 0x1 ; inc
|
||||
addwf 0x2f, f ; add to 2f
|
||||
|
||||
movf 0x20, w ; restore original 0xf
|
||||
andlw 0xf
|
||||
addlw 0xf
|
||||
movwf 0x20
|
||||
|
||||
btfsc 0x5d, 0 ; pair mode available signal
|
||||
bcf GPIO, 4
|
||||
nop
|
||||
nop
|
||||
bsf GPIO, 4
|
||||
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
btfss 0x20, 4 ; skip if half-byte carry
|
||||
goto mangle_return ; +2 cycles in return
|
||||
nop
|
||||
goto mangle_key_loop
|
||||
; 69 when goto, 69 when return
|
||||
; CIC has 78 -> 9 nops
|
||||
|
||||
mangle_key_withskip
|
||||
movf 0x41, w ; restore 23
|
||||
addwf 0x23, f ; add to 23
|
||||
movf 0x24, w
|
||||
movwf 0x40 ; save 24 to 40
|
||||
movf 0x23, w
|
||||
addwf 0x24, f
|
||||
movf 0x25, w
|
||||
movwf 0x41 ; save 25 to 41
|
||||
movf 0x40, w ; restore 24
|
||||
andlw 0xf ; mask nibble
|
||||
addlw 0x8 ; add #8 to HIGH nibble
|
||||
movwf 0x40
|
||||
btfss 0x40, 4 ; skip if carry to 5th bit
|
||||
addwf 0x25, w
|
||||
movwf 0x25
|
||||
|
||||
movf 0x41, w ; restore 25
|
||||
addlw 0x1 ; inc
|
||||
addwf 0x26, f ; add to 26
|
||||
|
||||
movf 0x26, w ;
|
||||
addlw 0x1 ; inc
|
||||
addwf 0x27, f ; add to 27
|
||||
|
||||
movf 0x27, w ;
|
||||
addlw 0x1 ; inc
|
||||
addwf 0x28, f ; add to 28
|
||||
|
||||
movf 0x28, w ;
|
||||
addlw 0x1 ; inc
|
||||
addwf 0x29, f ; add to 29
|
||||
|
||||
movf 0x29, w ;
|
||||
addlw 0x1 ; inc
|
||||
addwf 0x2a, f ; add to 2a
|
||||
|
||||
movf 0x2a, w ;
|
||||
addlw 0x1 ; inc
|
||||
addwf 0x2b, f ; add to 2b
|
||||
|
||||
movf 0x2b, w ;
|
||||
addlw 0x1 ; inc
|
||||
addwf 0x2c, f ; add to 2c
|
||||
|
||||
movf 0x2c, w ;
|
||||
addlw 0x1 ; inc
|
||||
addwf 0x2d, f ; add to 2d
|
||||
|
||||
movf 0x2d, w ;
|
||||
addlw 0x1 ; inc
|
||||
addwf 0x2e, f ; add to 2e
|
||||
|
||||
movf 0x2e, w ;
|
||||
addlw 0x1 ; inc
|
||||
addwf 0x2f, f ; add to 2f
|
||||
|
||||
movf 0x20, w ; restore original 0xf
|
||||
andlw 0xf
|
||||
addlw 0xf
|
||||
movwf 0x20
|
||||
;-------pair mode code-------
|
||||
bcf GPIO, 0
|
||||
movf GPIO, w
|
||||
btfss 0x5c, 3
|
||||
bsf GPIO, 0
|
||||
movwf 0x5e
|
||||
movf GPIO, w
|
||||
movwf 0x5f
|
||||
bcf GPIO, 0
|
||||
|
||||
btfsc 0x5d, 0 ; pair mode available signal
|
||||
bcf GPIO, 4
|
||||
bsf GPIO, 4
|
||||
;-------end of pair mode code-------
|
||||
btfss 0x20, 4 ; skip if half-byte carry
|
||||
goto mangle_return ; +2 cycles in return
|
||||
movf 0x20, w ; restore w (previously destroyed)
|
||||
goto mangle_key_loop
|
||||
mangle_return
|
||||
return
|
||||
; 73 when goto, 73 when return
|
||||
; CIC has 84 -> 11 nops
|
||||
|
||||
mangle_lock
|
||||
movf 0x3f, w
|
||||
movwf 0x30
|
||||
mangle_lock_loop
|
||||
addlw 0x1
|
||||
addwf 0x31, f
|
||||
movf 0x32, w
|
||||
movwf 0x40
|
||||
movf 0x31, w
|
||||
addwf 0x32, f
|
||||
incf 0x32, f
|
||||
comf 0x32, f
|
||||
movf 0x33, w
|
||||
movwf 0x41 ; store 33 to 41
|
||||
movlw 0xf
|
||||
andwf 0x33, f
|
||||
movf 0x40, w ; add 40(32 old)+33+#1 and skip if carry
|
||||
andlw 0xf
|
||||
addwf 0x33, f
|
||||
incf 0x33, f
|
||||
btfsc 0x33, 4
|
||||
goto mangle_lock_withskip
|
||||
mangle_lock_withoutskip
|
||||
movf 0x41, w ; restore 33
|
||||
addwf 0x34, f ; add to 34
|
||||
movf 0x35, w
|
||||
movwf 0x40 ; save 35 to 40
|
||||
movf 0x34, w
|
||||
addwf 0x35, f
|
||||
movf 0x36, w
|
||||
movwf 0x41 ; save 36 to 41
|
||||
movf 0x40, w ; restore 35
|
||||
andlw 0xf ; mask nibble
|
||||
addlw 0x8 ; add #8 to HIGH nibble
|
||||
movwf 0x40
|
||||
btfss 0x40, 4 ; skip if carry to 5th bit
|
||||
addwf 0x36, w
|
||||
movwf 0x36
|
||||
|
||||
movf 0x41, w ; restore 36
|
||||
addlw 0x1 ; inc
|
||||
addwf 0x37, f ; add to 37
|
||||
|
||||
movf 0x37, w ;
|
||||
addlw 0x1 ; inc
|
||||
addwf 0x38, f ; add to 38
|
||||
|
||||
movf 0x38, w ;
|
||||
addlw 0x1 ; inc
|
||||
addwf 0x39, f ; add to 39
|
||||
|
||||
movf 0x39, w ;
|
||||
addlw 0x1 ; inc
|
||||
addwf 0x3a, f ; add to 3a
|
||||
|
||||
movf 0x3a, w ;
|
||||
addlw 0x1 ; inc
|
||||
addwf 0x3b, f ; add to 3b
|
||||
|
||||
movf 0x3b, w ;
|
||||
addlw 0x1 ; inc
|
||||
addwf 0x3c, f ; add to 3c
|
||||
|
||||
movf 0x3c, w ;
|
||||
addlw 0x1 ; inc
|
||||
addwf 0x3d, f ; add to 3d
|
||||
|
||||
movf 0x3d, w ;
|
||||
addlw 0x1 ; inc
|
||||
addwf 0x3e, f ; add to 3e
|
||||
|
||||
movf 0x3e, w ;
|
||||
addlw 0x1 ; inc
|
||||
addwf 0x3f, f ; add to 3f
|
||||
|
||||
movf 0x30, w ; restore original 0xf
|
||||
andlw 0xf
|
||||
addlw 0xf
|
||||
movwf 0x30
|
||||
|
||||
btfsc 0x5d, 0 ; pair mode available signal
|
||||
bcf GPIO, 4
|
||||
nop
|
||||
nop
|
||||
bsf GPIO, 4
|
||||
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
btfss 0x30, 4 ; skip if half-byte carry
|
||||
goto mangle_return
|
||||
nop
|
||||
goto mangle_lock_loop
|
||||
; 69 when goto, 69 when return
|
||||
; CIC has 78 -> 9 nops
|
||||
|
||||
mangle_lock_withskip
|
||||
movf 0x41, w ; restore 33
|
||||
addwf 0x33, f ; add to 33
|
||||
movf 0x34, w
|
||||
movwf 0x40 ; save 34 to 40
|
||||
movf 0x33, w
|
||||
addwf 0x34, f
|
||||
movf 0x35, w
|
||||
movwf 0x41 ; save 35 to 41
|
||||
movf 0x40, w ; restore 34
|
||||
andlw 0xf ; mask nibble
|
||||
addlw 0x8 ; add #8 to HIGH nibble
|
||||
movwf 0x40
|
||||
btfss 0x40, 4 ; skip if carry to 5th bit
|
||||
addwf 0x35, w
|
||||
movwf 0x35
|
||||
|
||||
movf 0x41, w ; restore 35
|
||||
addlw 0x1 ; inc
|
||||
addwf 0x36, f ; add to 36
|
||||
|
||||
movf 0x36, w ;
|
||||
addlw 0x1 ; inc
|
||||
addwf 0x37, f ; add to 37
|
||||
|
||||
movf 0x37, w ;
|
||||
addlw 0x1 ; inc
|
||||
addwf 0x38, f ; add to 38
|
||||
|
||||
movf 0x38, w ;
|
||||
addlw 0x1 ; inc
|
||||
addwf 0x39, f ; add to 39
|
||||
|
||||
movf 0x39, w ;
|
||||
addlw 0x1 ; inc
|
||||
addwf 0x3a, f ; add to 3a
|
||||
|
||||
movf 0x3a, w ;
|
||||
addlw 0x1 ; inc
|
||||
addwf 0x3b, f ; add to 3b
|
||||
|
||||
movf 0x3b, w ;
|
||||
addlw 0x1 ; inc
|
||||
addwf 0x3c, f ; add to 3c
|
||||
|
||||
movf 0x3c, w ;
|
||||
addlw 0x1 ; inc
|
||||
addwf 0x3d, f ; add to 3d
|
||||
|
||||
movf 0x3d, w ;
|
||||
addlw 0x1 ; inc
|
||||
addwf 0x3e, f ; add to 3e
|
||||
|
||||
movf 0x3e, w ;
|
||||
addlw 0x1 ; inc
|
||||
addwf 0x3f, f ; add to 3f
|
||||
|
||||
movf 0x30, w ; restore original 0xf
|
||||
andlw 0xf
|
||||
addlw 0xf
|
||||
movwf 0x30
|
||||
;-------pair mode code-------
|
||||
btfss 0x5e, 1
|
||||
goto scic_pair_skip1
|
||||
btfsc 0x5f, 1
|
||||
goto scic_pair_skip2
|
||||
btfsc 0x5c, 3
|
||||
goto scic_pair_skip3
|
||||
goto supercic_pairmode
|
||||
scic_pair_skip1
|
||||
nop
|
||||
nop
|
||||
scic_pair_skip2
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
goto scic_pair_skip4
|
||||
scic_pair_skip3
|
||||
bcf GPIO, 4
|
||||
bsf 0x5d, 0 ; set pair mode available
|
||||
nop
|
||||
bsf GPIO, 4
|
||||
|
||||
scic_pair_skip4
|
||||
;-------end of pair mode code-------
|
||||
btfss 0x30, 4 ; skip if half-byte carry
|
||||
goto mangle_return
|
||||
nop
|
||||
goto mangle_lock_loop
|
||||
; 73 when goto, 73 when return
|
||||
; CIC has 84 -> 11 nops
|
||||
|
||||
; --------wait: 3*(W-1)+7 cycles (including call+return). W=0 -> 256!--------
|
||||
wait
|
||||
movwf 0x4f
|
||||
wait0 decfsz 0x4f, f
|
||||
goto wait0
|
||||
return
|
||||
|
||||
; --------wait long: 8+(3*(w-1))+(772*w). W=0 -> 256!--------
|
||||
longwait
|
||||
movwf 0x4e
|
||||
clrw
|
||||
longwait0
|
||||
call wait
|
||||
decfsz 0x4e, f
|
||||
goto longwait0
|
||||
return
|
||||
|
||||
; --------change region in eeprom and die--------
|
||||
die
|
||||
movlw 0x3a ;wait 50ms before writing
|
||||
call longwait ;("error" might be due to power loss)
|
||||
banksel EEADR
|
||||
clrw
|
||||
movwf EEADR
|
||||
bsf EECON1, RD
|
||||
movf EEDAT, w
|
||||
banksel GPIO
|
||||
movwf 0x4d
|
||||
btfsc 0x4d, 0
|
||||
goto die_reg_6
|
||||
die_reg_9
|
||||
movlw 0x9 ; died with PAL, fall back to NTSC
|
||||
goto die_reg_cont
|
||||
die_reg_6
|
||||
movlw 0x6 ; died with NTSC, fall back to PAL
|
||||
die_reg_cont
|
||||
banksel EEADR
|
||||
movwf EEDAT
|
||||
bsf EECON1, WREN
|
||||
|
||||
die_intloop
|
||||
bcf INTCON, GIE
|
||||
btfsc INTCON, GIE
|
||||
goto die_intloop
|
||||
|
||||
movlw 0x55
|
||||
movwf EECON2
|
||||
movlw 0xaa
|
||||
movwf EECON2
|
||||
bsf EECON1, WR
|
||||
bsf INTCON, GIE
|
||||
|
||||
banksel GPIO
|
||||
bcf GPIO, 4
|
||||
; --------get caught up--------
|
||||
die_trap
|
||||
goto die_trap
|
||||
; -----------------------------------------------------------------------
|
||||
supercic_pairmode
|
||||
banksel TRISIO
|
||||
bsf TRISIO, 0
|
||||
bsf TRISIO, 1
|
||||
banksel GPIO
|
||||
bcf INTCON, GIE
|
||||
supercic_pairmode_loop
|
||||
bsf GPIO, 4
|
||||
nop
|
||||
nop
|
||||
bcf GPIO, 4
|
||||
goto supercic_pairmode_loop
|
||||
|
||||
; eeprom memory
|
||||
DEEPROM CODE
|
||||
de 0x09 ; D411 (NTSC)
|
||||
end
|
||||
1322
pcb/kicad/RevE/fpga.sch
Normal file
1322
pcb/kicad/RevE/fpga.sch
Normal file
File diff suppressed because it is too large
Load Diff
1194
pcb/kicad/RevE/mcu.sch
Normal file
1194
pcb/kicad/RevE/mcu.sch
Normal file
File diff suppressed because it is too large
Load Diff
807
pcb/kicad/RevE/memory.sch
Normal file
807
pcb/kicad/RevE/memory.sch
Normal file
@ -0,0 +1,807 @@
|
||||
EESchema Schematic File Version 2 date Fri 09 Dec 2011 10:46:05 PM CET
|
||||
LIBS:power
|
||||
LIBS:device
|
||||
LIBS:transistors
|
||||
LIBS:conn
|
||||
LIBS:linear
|
||||
LIBS:regul
|
||||
LIBS:74xx
|
||||
LIBS:cmos4000
|
||||
LIBS:adc-dac
|
||||
LIBS:memory
|
||||
LIBS:xilinx
|
||||
LIBS:special
|
||||
LIBS:microcontrollers
|
||||
LIBS:dsp
|
||||
LIBS:microchip
|
||||
LIBS:analog_switches
|
||||
LIBS:motorola
|
||||
LIBS:texas
|
||||
LIBS:intel
|
||||
LIBS:audio
|
||||
LIBS:interface
|
||||
LIBS:digital-audio
|
||||
LIBS:philips
|
||||
LIBS:display
|
||||
LIBS:cypress
|
||||
LIBS:siliconi
|
||||
LIBS:opto
|
||||
LIBS:atmel
|
||||
LIBS:contrib
|
||||
LIBS:valves
|
||||
LIBS:snescart
|
||||
LIBS:misc-74
|
||||
LIBS:vreg
|
||||
LIBS:lpc1754
|
||||
LIBS:sd_card
|
||||
LIBS:cy62148ev30
|
||||
LIBS:mt45w8mw16
|
||||
LIBS:cs4344
|
||||
LIBS:double_sch_kcom
|
||||
LIBS:usb_minib
|
||||
LIBS:mic23250
|
||||
LIBS:sd2snes-cache
|
||||
EELAYER 25 0
|
||||
EELAYER END
|
||||
$Descr A4 11700 8267
|
||||
encoding utf-8
|
||||
Sheet 3 6
|
||||
Title "sd2snes Mark II"
|
||||
Date "9 dec 2011"
|
||||
Rev "C"
|
||||
Comp "Maximilian Rehkopf"
|
||||
Comment1 ""
|
||||
Comment2 ""
|
||||
Comment3 ""
|
||||
Comment4 ""
|
||||
$EndDescr
|
||||
Text Label 7650 2000 0 50 ~ 0
|
||||
SRAM_Vcc
|
||||
Wire Wire Line
|
||||
7650 4750 7650 5000
|
||||
Wire Wire Line
|
||||
8350 5050 8350 5250
|
||||
Wire Wire Line
|
||||
8350 5250 8500 5250
|
||||
Connection ~ 9150 5250
|
||||
Wire Wire Line
|
||||
9150 5450 9150 5250
|
||||
Connection ~ 9600 2000
|
||||
Wire Wire Line
|
||||
9600 2000 9600 3350
|
||||
Wire Wire Line
|
||||
10500 2000 10350 2000
|
||||
Wire Wire Line
|
||||
8400 1400 8400 1600
|
||||
Wire Wire Line
|
||||
8400 1600 8050 1600
|
||||
Wire Wire Line
|
||||
6800 4350 6300 4350
|
||||
Wire Wire Line
|
||||
6800 4250 6300 4250
|
||||
Wire Wire Line
|
||||
6800 4150 6300 4150
|
||||
Wire Wire Line
|
||||
6800 4050 6300 4050
|
||||
Wire Wire Line
|
||||
6800 3950 6300 3950
|
||||
Wire Wire Line
|
||||
6800 3850 6300 3850
|
||||
Wire Wire Line
|
||||
6800 3750 6300 3750
|
||||
Wire Wire Line
|
||||
6800 3650 6300 3650
|
||||
Wire Wire Line
|
||||
6800 3550 6300 3550
|
||||
Wire Wire Line
|
||||
6800 3450 6300 3450
|
||||
Wire Wire Line
|
||||
6800 3350 6300 3350
|
||||
Wire Wire Line
|
||||
6800 3250 6300 3250
|
||||
Wire Wire Line
|
||||
6800 3150 6300 3150
|
||||
Wire Wire Line
|
||||
6800 3050 6300 3050
|
||||
Wire Wire Line
|
||||
6800 2950 6300 2950
|
||||
Wire Wire Line
|
||||
6800 2850 6300 2850
|
||||
Wire Wire Line
|
||||
6800 2750 6300 2750
|
||||
Wire Wire Line
|
||||
6800 2650 6300 2650
|
||||
Wire Wire Line
|
||||
6800 2550 6300 2550
|
||||
Wire Wire Line
|
||||
8500 3950 9000 3950
|
||||
Wire Wire Line
|
||||
4750 4750 4250 4750
|
||||
Wire Wire Line
|
||||
4250 4650 4750 4650
|
||||
Wire Wire Line
|
||||
4250 4350 4750 4350
|
||||
Wire Wire Line
|
||||
4250 4150 4750 4150
|
||||
Wire Wire Line
|
||||
4250 4050 4750 4050
|
||||
Wire Wire Line
|
||||
4250 3750 4750 3750
|
||||
Wire Wire Line
|
||||
4250 3650 4750 3650
|
||||
Wire Wire Line
|
||||
4250 3550 4750 3550
|
||||
Wire Wire Line
|
||||
4250 3450 4750 3450
|
||||
Wire Wire Line
|
||||
4250 3350 4750 3350
|
||||
Wire Wire Line
|
||||
4250 3250 4750 3250
|
||||
Wire Wire Line
|
||||
4250 3150 4750 3150
|
||||
Wire Wire Line
|
||||
4250 3050 4750 3050
|
||||
Wire Wire Line
|
||||
4250 2850 4750 2850
|
||||
Wire Wire Line
|
||||
4250 2750 4750 2750
|
||||
Wire Wire Line
|
||||
4250 2650 4750 2650
|
||||
Wire Wire Line
|
||||
4250 2550 4750 2550
|
||||
Wire Wire Line
|
||||
4250 2450 4750 2450
|
||||
Wire Wire Line
|
||||
4250 2350 4750 2350
|
||||
Wire Wire Line
|
||||
4250 2250 4750 2250
|
||||
Wire Wire Line
|
||||
4250 2150 4750 2150
|
||||
Wire Wire Line
|
||||
3550 6800 3550 6700
|
||||
Wire Wire Line
|
||||
3400 5400 3400 5300
|
||||
Wire Wire Line
|
||||
3300 5150 3300 5300
|
||||
Wire Wire Line
|
||||
3300 1750 3300 1550
|
||||
Connection ~ 7650 2000
|
||||
Wire Wire Line
|
||||
3500 1750 3500 1550
|
||||
Wire Wire Line
|
||||
3500 5150 3500 5300
|
||||
Wire Wire Line
|
||||
3500 5300 3300 5300
|
||||
Connection ~ 3400 5300
|
||||
Wire Wire Line
|
||||
3550 7200 3550 7300
|
||||
Wire Wire Line
|
||||
3250 7200 3250 7300
|
||||
Wire Wire Line
|
||||
3250 6700 3250 6800
|
||||
Wire Wire Line
|
||||
2550 2150 2050 2150
|
||||
Wire Wire Line
|
||||
2550 2250 2050 2250
|
||||
Wire Wire Line
|
||||
2550 2350 2050 2350
|
||||
Wire Wire Line
|
||||
2550 2450 2050 2450
|
||||
Wire Wire Line
|
||||
2550 2550 2050 2550
|
||||
Wire Wire Line
|
||||
2550 2650 2050 2650
|
||||
Wire Wire Line
|
||||
2550 2750 2050 2750
|
||||
Wire Wire Line
|
||||
2550 2850 2050 2850
|
||||
Wire Wire Line
|
||||
2550 2950 2050 2950
|
||||
Wire Wire Line
|
||||
2550 3050 2050 3050
|
||||
Wire Wire Line
|
||||
2550 3150 2050 3150
|
||||
Wire Wire Line
|
||||
2550 3250 2050 3250
|
||||
Wire Wire Line
|
||||
2550 3350 2050 3350
|
||||
Wire Wire Line
|
||||
2550 3450 2050 3450
|
||||
Wire Wire Line
|
||||
2550 3550 2050 3550
|
||||
Wire Wire Line
|
||||
2550 3650 2050 3650
|
||||
Wire Wire Line
|
||||
2550 3750 2050 3750
|
||||
Wire Wire Line
|
||||
2550 3850 2050 3850
|
||||
Wire Wire Line
|
||||
2550 3950 2050 3950
|
||||
Wire Wire Line
|
||||
2550 4050 2050 4050
|
||||
Wire Wire Line
|
||||
2550 4150 2050 4150
|
||||
Wire Wire Line
|
||||
2550 4250 2050 4250
|
||||
Wire Wire Line
|
||||
2550 4350 2050 4350
|
||||
Wire Wire Line
|
||||
2550 4650 2050 4650
|
||||
Wire Wire Line
|
||||
2550 4750 2050 4750
|
||||
Wire Wire Line
|
||||
2550 4550 2050 4550
|
||||
Wire Wire Line
|
||||
8500 4050 9000 4050
|
||||
Connection ~ 4750 4750
|
||||
Wire Wire Line
|
||||
4750 4350 4750 5400
|
||||
Connection ~ 4750 4650
|
||||
Wire Wire Line
|
||||
8500 2550 9000 2550
|
||||
Wire Wire Line
|
||||
8500 2650 9000 2650
|
||||
Wire Wire Line
|
||||
8500 2750 9000 2750
|
||||
Wire Wire Line
|
||||
8500 2850 9000 2850
|
||||
Wire Wire Line
|
||||
8500 2950 9000 2950
|
||||
Wire Wire Line
|
||||
8500 3050 9000 3050
|
||||
Wire Wire Line
|
||||
8500 3150 9000 3150
|
||||
Wire Wire Line
|
||||
8500 3250 9000 3250
|
||||
Wire Wire Line
|
||||
7250 1600 6900 1600
|
||||
Wire Wire Line
|
||||
6900 1600 6900 1400
|
||||
Wire Wire Line
|
||||
8500 3850 9600 3850
|
||||
Wire Wire Line
|
||||
9600 3850 9600 5050
|
||||
Wire Wire Line
|
||||
9000 5250 9300 5250
|
||||
Wire Wire Line
|
||||
9150 5950 9150 6050
|
||||
Wire Wire Line
|
||||
9150 6050 9600 6050
|
||||
Wire Wire Line
|
||||
9600 6350 9600 5450
|
||||
Connection ~ 9600 6050
|
||||
Wire Wire Line
|
||||
7650 2150 7650 1800
|
||||
Wire Wire Line
|
||||
9950 2000 7650 2000
|
||||
$Comp
|
||||
L CY62148EV30-ZSXI U511
|
||||
U 1 1 4D49598F
|
||||
P 7650 3450
|
||||
F 0 "U511" H 7650 3550 60 0000 C CNN
|
||||
F 1 "CY62148EV30-ZSXI" H 7700 3450 60 0000 C CNN
|
||||
1 7650 3450
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
Text Notes 7050 7000 0 250 ~ 50
|
||||
Memory
|
||||
Text Notes 7300 1300 0 50 ~ 0
|
||||
SRAM battery power
|
||||
Text Notes 9800 5300 0 50 ~ 0
|
||||
Battery power OE switch
|
||||
$Comp
|
||||
L +3.3V #PWR031
|
||||
U 1 1 4BF2FE97
|
||||
P 8350 5050
|
||||
F 0 "#PWR031" H 8350 5010 30 0001 C CNN
|
||||
F 1 "+3.3V" H 8350 5160 30 0000 C CNN
|
||||
1 8350 5050
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
$Comp
|
||||
L GND #PWR032
|
||||
U 1 1 4BF2FE7B
|
||||
P 9600 6350
|
||||
F 0 "#PWR032" H 9600 6350 30 0001 C CNN
|
||||
F 1 "GND" H 9600 6280 30 0001 C CNN
|
||||
1 9600 6350
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
$Comp
|
||||
L R R511
|
||||
U 1 1 4BF2FDAF
|
||||
P 9600 3600
|
||||
F 0 "R511" V 9680 3600 50 0000 C CNN
|
||||
F 1 "20k" V 9600 3600 50 0000 C CNN
|
||||
F 2 "SM0805_FIXEDMASK" H 9600 3600 60 0001 C CNN
|
||||
1 9600 3600
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
$Comp
|
||||
L R R513
|
||||
U 1 1 4BF2FDAC
|
||||
P 9150 5700
|
||||
F 0 "R513" V 9230 5700 50 0000 C CNN
|
||||
F 1 "100k" V 9150 5700 50 0000 C CNN
|
||||
F 2 "SM0805_FIXEDMASK" H 9150 5700 60 0001 C CNN
|
||||
1 9150 5700
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
$Comp
|
||||
L R R512
|
||||
U 1 1 4BF2FDA9
|
||||
P 8750 5250
|
||||
F 0 "R512" V 8830 5250 50 0000 C CNN
|
||||
F 1 "4k7" V 8750 5250 50 0000 C CNN
|
||||
F 2 "SM0805_FIXEDMASK" H 8750 5250 60 0001 C CNN
|
||||
1 8750 5250
|
||||
0 1 1 0
|
||||
$EndComp
|
||||
$Comp
|
||||
L NPN Q511
|
||||
U 1 1 4BF2FD9F
|
||||
P 9500 5250
|
||||
F 0 "Q511" H 9500 5100 50 0000 R CNN
|
||||
F 1 "2N2222A" H 9500 5400 50 0000 R CNN
|
||||
F 2 "SOT23EBC" H 9500 5250 60 0001 C CNN
|
||||
1 9500 5250
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
$Comp
|
||||
L GND #PWR033
|
||||
U 1 1 4BF1A006
|
||||
P 10500 2000
|
||||
F 0 "#PWR033" H 10500 2000 30 0001 C CNN
|
||||
F 1 "GND" H 10500 1930 30 0001 C CNN
|
||||
1 10500 2000
|
||||
0 -1 -1 0
|
||||
$EndComp
|
||||
$Comp
|
||||
L +BATT #PWR034
|
||||
U 1 1 4BF19EA4
|
||||
P 8400 1400
|
||||
F 0 "#PWR034" H 8400 1350 20 0001 C CNN
|
||||
F 1 "+BATT" H 8400 1500 30 0000 C CNN
|
||||
1 8400 1400
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
$Comp
|
||||
L +3.3V #PWR035
|
||||
U 1 1 4BF19E7A
|
||||
P 6900 1400
|
||||
F 0 "#PWR035" H 6900 1360 30 0001 C CNN
|
||||
F 1 "+3.3V" H 6900 1510 30 0000 C CNN
|
||||
1 6900 1400
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
$Comp
|
||||
L DOUBLE_SCH_KCOM2 D511
|
||||
U 1 1 4BF19DCA
|
||||
P 7650 1600
|
||||
F 0 "D511" H 7800 1475 60 0000 C CNN
|
||||
F 1 "BAT54C" H 7650 1750 60 0000 C CNN
|
||||
F 2 "SOT23EBC" H 7650 1600 60 0001 C CNN
|
||||
1 7650 1600
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
Text Label 8600 4050 0 50 ~ 0
|
||||
RAM_/WE
|
||||
Text Label 8600 3950 0 50 ~ 0
|
||||
RAM_/OE
|
||||
Text Label 8600 3850 0 50 ~ 0
|
||||
RAM_/CE
|
||||
Text Label 8600 3250 0 50 ~ 0
|
||||
RAM_DQ7
|
||||
Text Label 8600 3150 0 50 ~ 0
|
||||
RAM_DQ6
|
||||
Text Label 8600 3050 0 50 ~ 0
|
||||
RAM_DQ5
|
||||
Text Label 8600 2950 0 50 ~ 0
|
||||
RAM_DQ4
|
||||
Text Label 8600 2850 0 50 ~ 0
|
||||
RAM_DQ3
|
||||
Text Label 8600 2750 0 50 ~ 0
|
||||
RAM_DQ2
|
||||
Text Label 8600 2650 0 50 ~ 0
|
||||
RAM_DQ1
|
||||
Text Label 8600 2550 0 50 ~ 0
|
||||
RAM_DQ0
|
||||
Text Label 6400 4350 0 50 ~ 0
|
||||
RAM_A18
|
||||
Text Label 6400 4250 0 50 ~ 0
|
||||
RAM_A17
|
||||
Text Label 6400 4150 0 50 ~ 0
|
||||
RAM_A16
|
||||
Text Label 6400 4050 0 50 ~ 0
|
||||
RAM_A15
|
||||
Text Label 6400 3950 0 50 ~ 0
|
||||
RAM_A14
|
||||
Text Label 6400 3850 0 50 ~ 0
|
||||
RAM_A13
|
||||
Text Label 6400 3750 0 50 ~ 0
|
||||
RAM_A12
|
||||
Text Label 6400 3650 0 50 ~ 0
|
||||
RAM_A11
|
||||
Text Label 6400 3550 0 50 ~ 0
|
||||
RAM_A10
|
||||
Text Label 6400 3450 0 50 ~ 0
|
||||
RAM_A9
|
||||
Text Label 6400 3350 0 50 ~ 0
|
||||
RAM_A8
|
||||
Text Label 6400 3250 0 50 ~ 0
|
||||
RAM_A7
|
||||
Text Label 6400 3150 0 50 ~ 0
|
||||
RAM_A6
|
||||
Text Label 6400 3050 0 50 ~ 0
|
||||
RAM_A5
|
||||
Text Label 6400 2950 0 50 ~ 0
|
||||
RAM_A4
|
||||
Text Label 6400 2850 0 50 ~ 0
|
||||
RAM_A3
|
||||
Text Label 6400 2750 0 50 ~ 0
|
||||
RAM_A2
|
||||
Text Label 6400 2650 0 50 ~ 0
|
||||
RAM_A1
|
||||
Text Label 6400 2550 0 50 ~ 0
|
||||
RAM_A0
|
||||
Text Label 4350 4150 0 50 ~ 0
|
||||
ROM_/UB
|
||||
Text Label 4350 4050 0 50 ~ 0
|
||||
ROM_/LB
|
||||
Text Label 4350 3750 0 50 ~ 0
|
||||
ROM_DQ15
|
||||
Text Label 4350 3650 0 50 ~ 0
|
||||
ROM_DQ14
|
||||
Text Label 4350 3550 0 50 ~ 0
|
||||
ROM_DQ13
|
||||
Text Label 4350 3450 0 50 ~ 0
|
||||
ROM_DQ12
|
||||
Text Label 4350 3350 0 50 ~ 0
|
||||
ROM_DQ11
|
||||
Text Label 4350 3250 0 50 ~ 0
|
||||
ROM_DQ10
|
||||
Text Label 4350 3150 0 50 ~ 0
|
||||
ROM_DQ9
|
||||
Text Label 4350 3050 0 50 ~ 0
|
||||
ROM_DQ8
|
||||
Text Label 4350 2850 0 50 ~ 0
|
||||
ROM_DQ7
|
||||
Text Label 4350 2750 0 50 ~ 0
|
||||
ROM_DQ6
|
||||
Text Label 4350 2650 0 50 ~ 0
|
||||
ROM_DQ5
|
||||
Text Label 4350 2550 0 50 ~ 0
|
||||
ROM_DQ4
|
||||
Text Label 4350 2450 0 50 ~ 0
|
||||
ROM_DQ3
|
||||
Text Label 4350 2350 0 50 ~ 0
|
||||
ROM_DQ2
|
||||
Text Label 4350 2250 0 50 ~ 0
|
||||
ROM_DQ1
|
||||
Text Label 4350 2150 0 50 ~ 0
|
||||
ROM_DQ0
|
||||
Text Label 2100 4750 0 50 ~ 0
|
||||
ROM_/WE
|
||||
Text Label 2100 4650 0 50 ~ 0
|
||||
ROM_/OE
|
||||
Text Label 2100 4550 0 50 ~ 0
|
||||
ROM_/CE
|
||||
Text Label 2100 4350 0 50 ~ 0
|
||||
ROM_A22
|
||||
Text Label 2100 4250 0 50 ~ 0
|
||||
ROM_A21
|
||||
Text Label 2100 4150 0 50 ~ 0
|
||||
ROM_A20
|
||||
Text Label 2100 4050 0 50 ~ 0
|
||||
ROM_A19
|
||||
Text Label 2100 3950 0 50 ~ 0
|
||||
ROM_A18
|
||||
Text Label 2100 3850 0 50 ~ 0
|
||||
ROM_A17
|
||||
Text Label 2100 3750 0 50 ~ 0
|
||||
ROM_A16
|
||||
Text Label 2100 3650 0 50 ~ 0
|
||||
ROM_A15
|
||||
Text Label 2100 3550 0 50 ~ 0
|
||||
ROM_A14
|
||||
Text Label 2100 3450 0 50 ~ 0
|
||||
ROM_A13
|
||||
Text Label 2100 3350 0 50 ~ 0
|
||||
ROM_A12
|
||||
Text Label 2100 3250 0 50 ~ 0
|
||||
ROM_A11
|
||||
Text Label 2100 3150 0 50 ~ 0
|
||||
ROM_A10
|
||||
Text Label 2100 3050 0 50 ~ 0
|
||||
ROM_A9
|
||||
Text Label 2100 2950 0 50 ~ 0
|
||||
ROM_A8
|
||||
Text Label 2100 2850 0 50 ~ 0
|
||||
ROM_A7
|
||||
Text Label 2100 2750 0 50 ~ 0
|
||||
ROM_A6
|
||||
Text Label 2100 2650 0 50 ~ 0
|
||||
ROM_A5
|
||||
Text Label 2100 2550 0 50 ~ 0
|
||||
ROM_A4
|
||||
Text Label 2100 2450 0 50 ~ 0
|
||||
ROM_A3
|
||||
Text Label 2100 2350 0 50 ~ 0
|
||||
ROM_A2
|
||||
Text Label 2100 2250 0 50 ~ 0
|
||||
ROM_A1
|
||||
Text Label 2100 2150 0 50 ~ 0
|
||||
ROM_A0
|
||||
Text GLabel 2050 4550 0 50 Input ~ 0
|
||||
ROM_/CE
|
||||
Text GLabel 9000 4050 2 50 Input ~ 0
|
||||
RAM_/WE
|
||||
Text GLabel 9000 3950 2 50 Input ~ 0
|
||||
RAM_/OE
|
||||
Text GLabel 9000 3250 2 50 BiDi ~ 0
|
||||
RAM_DQ7
|
||||
Text GLabel 9000 3150 2 50 BiDi ~ 0
|
||||
RAM_DQ6
|
||||
Text GLabel 9000 3050 2 50 BiDi ~ 0
|
||||
RAM_DQ5
|
||||
Text GLabel 9000 2950 2 50 BiDi ~ 0
|
||||
RAM_DQ4
|
||||
Text GLabel 9000 2850 2 50 BiDi ~ 0
|
||||
RAM_DQ3
|
||||
Text GLabel 9000 2750 2 50 BiDi ~ 0
|
||||
RAM_DQ2
|
||||
Text GLabel 9000 2650 2 50 BiDi ~ 0
|
||||
RAM_DQ1
|
||||
Text GLabel 9000 2550 2 50 BiDi ~ 0
|
||||
RAM_DQ0
|
||||
Text GLabel 6300 4350 0 50 Input ~ 0
|
||||
RAM_A18
|
||||
Text GLabel 6300 4250 0 50 Input ~ 0
|
||||
RAM_A17
|
||||
Text GLabel 6300 4150 0 50 Input ~ 0
|
||||
RAM_A16
|
||||
Text GLabel 6300 4050 0 50 Input ~ 0
|
||||
RAM_A15
|
||||
Text GLabel 6300 3950 0 50 Input ~ 0
|
||||
RAM_A14
|
||||
Text GLabel 6300 3850 0 50 Input ~ 0
|
||||
RAM_A13
|
||||
Text GLabel 6300 3750 0 50 Input ~ 0
|
||||
RAM_A12
|
||||
Text GLabel 6300 3650 0 50 Input ~ 0
|
||||
RAM_A11
|
||||
Text GLabel 6300 3550 0 50 Input ~ 0
|
||||
RAM_A10
|
||||
Text GLabel 6300 3450 0 50 Input ~ 0
|
||||
RAM_A9
|
||||
Text GLabel 6300 3350 0 50 Input ~ 0
|
||||
RAM_A8
|
||||
Text GLabel 6300 3250 0 50 Input ~ 0
|
||||
RAM_A7
|
||||
Text GLabel 6300 3150 0 50 Input ~ 0
|
||||
RAM_A6
|
||||
Text GLabel 6300 3050 0 50 Input ~ 0
|
||||
RAM_A5
|
||||
Text GLabel 6300 2950 0 50 Input ~ 0
|
||||
RAM_A4
|
||||
Text GLabel 6300 2850 0 50 Input ~ 0
|
||||
RAM_A3
|
||||
Text GLabel 6300 2750 0 50 Input ~ 0
|
||||
RAM_A2
|
||||
Text GLabel 6300 2650 0 50 Input ~ 0
|
||||
RAM_A1
|
||||
Text GLabel 6300 2550 0 50 Input ~ 0
|
||||
RAM_A0
|
||||
Text GLabel 4750 4150 2 50 Input ~ 0
|
||||
ROM_/UB
|
||||
Text GLabel 4750 4050 2 50 Input ~ 0
|
||||
ROM_/LB
|
||||
Text GLabel 4750 3750 2 50 BiDi ~ 0
|
||||
ROM_DQ15
|
||||
Text GLabel 4750 3650 2 50 BiDi ~ 0
|
||||
ROM_DQ14
|
||||
Text GLabel 4750 3550 2 50 BiDi ~ 0
|
||||
ROM_DQ13
|
||||
Text GLabel 4750 3450 2 50 BiDi ~ 0
|
||||
ROM_DQ12
|
||||
Text GLabel 4750 3350 2 50 BiDi ~ 0
|
||||
ROM_DQ11
|
||||
Text GLabel 4750 3250 2 50 BiDi ~ 0
|
||||
ROM_DQ10
|
||||
Text GLabel 4750 3150 2 50 BiDi ~ 0
|
||||
ROM_DQ9
|
||||
Text GLabel 4750 3050 2 50 BiDi ~ 0
|
||||
ROM_DQ8
|
||||
Text GLabel 4750 2850 2 50 BiDi ~ 0
|
||||
ROM_DQ7
|
||||
Text GLabel 4750 2750 2 50 BiDi ~ 0
|
||||
ROM_DQ6
|
||||
Text GLabel 4750 2650 2 50 BiDi ~ 0
|
||||
ROM_DQ5
|
||||
Text GLabel 4750 2550 2 50 BiDi ~ 0
|
||||
ROM_DQ4
|
||||
Text GLabel 4750 2450 2 50 BiDi ~ 0
|
||||
ROM_DQ3
|
||||
Text GLabel 4750 2350 2 50 BiDi ~ 0
|
||||
ROM_DQ2
|
||||
Text GLabel 4750 2250 2 50 BiDi ~ 0
|
||||
ROM_DQ1
|
||||
Text GLabel 4750 2150 2 50 BiDi ~ 0
|
||||
ROM_DQ0
|
||||
Text GLabel 2050 4350 0 50 Input ~ 0
|
||||
ROM_A22
|
||||
Text GLabel 2050 4250 0 50 Input ~ 0
|
||||
ROM_A21
|
||||
Text GLabel 2050 4150 0 50 Input ~ 0
|
||||
ROM_A20
|
||||
Text GLabel 2050 4050 0 50 Input ~ 0
|
||||
ROM_A19
|
||||
Text GLabel 2050 3950 0 50 Input ~ 0
|
||||
ROM_A18
|
||||
Text GLabel 2050 3850 0 50 Input ~ 0
|
||||
ROM_A17
|
||||
Text GLabel 2050 3750 0 50 Input ~ 0
|
||||
ROM_A16
|
||||
Text GLabel 2050 3650 0 50 Input ~ 0
|
||||
ROM_A15
|
||||
Text GLabel 2050 3550 0 50 Input ~ 0
|
||||
ROM_A14
|
||||
Text GLabel 2050 3450 0 50 Input ~ 0
|
||||
ROM_A13
|
||||
Text GLabel 2050 3350 0 50 Input ~ 0
|
||||
ROM_A12
|
||||
Text GLabel 2050 3250 0 50 Input ~ 0
|
||||
ROM_A11
|
||||
Text GLabel 2050 3150 0 50 Input ~ 0
|
||||
ROM_A10
|
||||
Text GLabel 2050 3050 0 50 Input ~ 0
|
||||
ROM_A9
|
||||
Text GLabel 2050 2950 0 50 Input ~ 0
|
||||
ROM_A8
|
||||
Text GLabel 2050 2850 0 50 Input ~ 0
|
||||
ROM_A7
|
||||
Text GLabel 2050 2750 0 50 Input ~ 0
|
||||
ROM_A6
|
||||
Text GLabel 2050 2650 0 50 Input ~ 0
|
||||
ROM_A5
|
||||
Text GLabel 2050 2550 0 50 Input ~ 0
|
||||
ROM_A4
|
||||
Text GLabel 2050 2450 0 50 Input ~ 0
|
||||
ROM_A3
|
||||
Text GLabel 2050 2350 0 50 Input ~ 0
|
||||
ROM_A2
|
||||
Text GLabel 2050 2250 0 50 Input ~ 0
|
||||
ROM_A1
|
||||
Text GLabel 2050 2150 0 50 Input ~ 0
|
||||
ROM_A0
|
||||
NoConn ~ 4250 4550
|
||||
$Comp
|
||||
L GND #PWR036
|
||||
U 1 1 4BCA30BF
|
||||
P 4750 5400
|
||||
F 0 "#PWR036" H 4750 5400 30 0001 C CNN
|
||||
F 1 "GND" H 4750 5330 30 0001 C CNN
|
||||
1 4750 5400
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
Text GLabel 2050 4750 0 50 Input ~ 0
|
||||
ROM_/WE
|
||||
Text GLabel 2050 4650 0 50 Input ~ 0
|
||||
ROM_/OE
|
||||
$Comp
|
||||
L C C502
|
||||
U 1 1 4BAD3D55
|
||||
P 3550 7000
|
||||
F 0 "C502" H 3600 7100 50 0000 L CNN
|
||||
F 1 "100n" H 3600 6900 50 0000 L CNN
|
||||
F 2 "SM0805_FIXEDMASK" H 3550 7000 60 0001 C CNN
|
||||
1 3550 7000
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
$Comp
|
||||
L C C511
|
||||
U 1 1 4BAD3D53
|
||||
P 10150 2000
|
||||
F 0 "C511" H 10200 2100 50 0000 L CNN
|
||||
F 1 "100n" H 10200 1900 50 0000 L CNN
|
||||
F 2 "SM0805_FIXEDMASK" H 10150 2000 60 0001 C CNN
|
||||
1 10150 2000
|
||||
0 -1 1 0
|
||||
$EndComp
|
||||
$Comp
|
||||
L C C501
|
||||
U 1 1 4BAD3D47
|
||||
P 3250 7000
|
||||
F 0 "C501" H 3300 7100 50 0000 L CNN
|
||||
F 1 "100n" H 3300 6900 50 0000 L CNN
|
||||
F 2 "SM0805_FIXEDMASK" H 3250 7000 60 0001 C CNN
|
||||
1 3250 7000
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
$Comp
|
||||
L GND #PWR037
|
||||
U 1 1 4BAD3D2B
|
||||
P 3550 7300
|
||||
F 0 "#PWR037" H 3550 7300 30 0001 C CNN
|
||||
F 1 "GND" H 3550 7230 30 0001 C CNN
|
||||
1 3550 7300
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
$Comp
|
||||
L +1.8V #PWR038
|
||||
U 1 1 4BAD3D27
|
||||
P 3550 6700
|
||||
F 0 "#PWR038" H 3550 6840 20 0001 C CNN
|
||||
F 1 "+1.8V" H 3550 6810 30 0000 C CNN
|
||||
1 3550 6700
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
$Comp
|
||||
L GND #PWR039
|
||||
U 1 1 4BAD3D20
|
||||
P 3250 7300
|
||||
F 0 "#PWR039" H 3250 7300 30 0001 C CNN
|
||||
F 1 "GND" H 3250 7230 30 0001 C CNN
|
||||
1 3250 7300
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
$Comp
|
||||
L +3.3V #PWR040
|
||||
U 1 1 4BAD3D0B
|
||||
P 3250 6700
|
||||
F 0 "#PWR040" H 3250 6660 30 0001 C CNN
|
||||
F 1 "+3.3V" H 3250 6810 30 0000 C CNN
|
||||
1 3250 6700
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
$Comp
|
||||
L GND #PWR041
|
||||
U 1 1 4BAD33A7
|
||||
P 3400 5400
|
||||
F 0 "#PWR041" H 3400 5400 30 0001 C CNN
|
||||
F 1 "GND" H 3400 5330 30 0001 C CNN
|
||||
1 3400 5400
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
$Comp
|
||||
L GND #PWR042
|
||||
U 1 1 4BAD339F
|
||||
P 7650 5000
|
||||
F 0 "#PWR042" H 7650 5000 30 0001 C CNN
|
||||
F 1 "GND" H 7650 4930 30 0001 C CNN
|
||||
1 7650 5000
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
$Comp
|
||||
L +1.8V #PWR043
|
||||
U 1 1 4BAD32D2
|
||||
P 3300 1550
|
||||
F 0 "#PWR043" H 3300 1690 20 0001 C CNN
|
||||
F 1 "+1.8V" H 3300 1660 30 0000 C CNN
|
||||
1 3300 1550
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
$Comp
|
||||
L +3.3V #PWR044
|
||||
U 1 1 4BAD32BE
|
||||
P 3500 1550
|
||||
F 0 "#PWR044" H 3500 1510 30 0001 C CNN
|
||||
F 1 "+3.3V" H 3500 1660 30 0000 C CNN
|
||||
1 3500 1550
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
Text Notes 6300 5700 0 60 ~ 0
|
||||
4Mbits 45ns SRAM (battery RAM + custom chip work RAM)
|
||||
Text Notes 2650 5700 0 60 ~ 0
|
||||
128Mbits 70ns PSRAM (ROM area)
|
||||
$Comp
|
||||
L MT45W8MW16 U501
|
||||
U 1 1 4B868602
|
||||
P 3400 3450
|
||||
F 0 "U501" H 3400 3550 60 0000 C CNN
|
||||
F 1 "MT45W8MW16" H 3400 3450 60 0000 C CNN
|
||||
F 2 "VFBGA54" H 3400 3450 60 0001 C CNN
|
||||
1 3400 3450
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
$EndSCHEMATC
|
||||
1182
pcb/kicad/RevE/pwr_misc.sch
Normal file
1182
pcb/kicad/RevE/pwr_misc.sch
Normal file
File diff suppressed because it is too large
Load Diff
BIN
pcb/kicad/RevE/sd2snes-BOM-with-supplier.ods
Normal file
BIN
pcb/kicad/RevE/sd2snes-BOM-with-supplier.ods
Normal file
Binary file not shown.
BIN
pcb/kicad/RevE/sd2snes-components-back.png
Normal file
BIN
pcb/kicad/RevE/sd2snes-components-back.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 351 KiB |
BIN
pcb/kicad/RevE/sd2snes-components-front.png
Normal file
BIN
pcb/kicad/RevE/sd2snes-components-front.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 447 KiB |
34910
pcb/kicad/RevE/sd2snes.brd
Normal file
34910
pcb/kicad/RevE/sd2snes.brd
Normal file
File diff suppressed because it is too large
Load Diff
3216
pcb/kicad/RevE/sd2snes.net
Normal file
3216
pcb/kicad/RevE/sd2snes.net
Normal file
File diff suppressed because it is too large
Load Diff
94
pcb/kicad/RevE/sd2snes.sch
Normal file
94
pcb/kicad/RevE/sd2snes.sch
Normal file
@ -0,0 +1,94 @@
|
||||
EESchema Schematic File Version 2 date Fri 09 Dec 2011 10:46:05 PM CET
|
||||
LIBS:power
|
||||
LIBS:device
|
||||
LIBS:transistors
|
||||
LIBS:conn
|
||||
LIBS:linear
|
||||
LIBS:regul
|
||||
LIBS:74xx
|
||||
LIBS:cmos4000
|
||||
LIBS:adc-dac
|
||||
LIBS:memory
|
||||
LIBS:xilinx
|
||||
LIBS:special
|
||||
LIBS:microcontrollers
|
||||
LIBS:dsp
|
||||
LIBS:microchip
|
||||
LIBS:analog_switches
|
||||
LIBS:motorola
|
||||
LIBS:texas
|
||||
LIBS:intel
|
||||
LIBS:audio
|
||||
LIBS:interface
|
||||
LIBS:digital-audio
|
||||
LIBS:philips
|
||||
LIBS:display
|
||||
LIBS:cypress
|
||||
LIBS:siliconi
|
||||
LIBS:opto
|
||||
LIBS:atmel
|
||||
LIBS:contrib
|
||||
LIBS:valves
|
||||
LIBS:snescart
|
||||
LIBS:misc-74
|
||||
LIBS:vreg
|
||||
LIBS:lpc1754
|
||||
LIBS:sd_card
|
||||
LIBS:cy62148ev30
|
||||
LIBS:mt45w8mw16
|
||||
LIBS:cs4344
|
||||
LIBS:double_sch_kcom
|
||||
LIBS:usb_minib
|
||||
LIBS:mic23250
|
||||
LIBS:sd2snes-cache
|
||||
EELAYER 25 0
|
||||
EELAYER END
|
||||
$Descr A4 11700 8267
|
||||
encoding utf-8
|
||||
Sheet 1 6
|
||||
Title "sd2snes Mark II"
|
||||
Date "9 dec 2011"
|
||||
Rev "E"
|
||||
Comp "Maximilian Rehkopf"
|
||||
Comment1 ""
|
||||
Comment2 ""
|
||||
Comment3 ""
|
||||
Comment4 ""
|
||||
$EndDescr
|
||||
Wire Notes Line
|
||||
3650 4200 6150 4200
|
||||
Text Notes 3300 3250 0 100 ~ 0
|
||||
Changes from Rev.A / TODO:\n [x] remove FPGA from JTAG chain\n [x] remove SNES IRQ_DIR+IRQ, replace with IRQ_OE. IRQ is unidirectional cart -> console\n (replace 1gate w/ transistor)\n [x] disconnect P2.10 from FPGA, using a different GPIO for IRQ / INIT_B\n [x] add pullup to P2.10\n [ ] add JTAG pullups\n [x] add series resistor for CPU_CLK\n [x] add a jumper in PIC MCLR line to MCU\n [x] change PIC to DIP8 type for easier preprogramming\n [x] change "P1" to "P401" in pin description in silk screen\n [x] filter CIC data lines\n [x] rearrange SD card interface/LEDs on MCU\n [x] RAs for SNES signals?\n [x] reroute/add decoupling capacitors\n [x] filter SNES control signals (RD, WR, PARD, PAWR, CPU_CLK, IRQ)\n [x] replace 4Mbit SRAM with much cheaper TSOP-II type\n [x] add inverse polarity protection\n [x] separate GND plane for DAC\n [ ] separate JTAG pads for FPGA\n [x] add USE_BATT jumper\n [x] move PROG_B to P1.15
|
||||
$Sheet
|
||||
S 1250 1250 1700 1250
|
||||
U 4B6E16F2
|
||||
F0 "SNES Slot" 60
|
||||
F1 "snesslot.sch" 60
|
||||
$EndSheet
|
||||
Text Notes 750 7700 0 500 ~ 100
|
||||
sd2snes Mark II
|
||||
$Sheet
|
||||
S 1250 3300 1600 1150
|
||||
U 4BAA6ABD
|
||||
F0 "Memory" 60
|
||||
F1 "memory.sch" 60
|
||||
$EndSheet
|
||||
$Sheet
|
||||
S 8050 1250 1600 1250
|
||||
U 4B6ED75B
|
||||
F0 "MCU" 60
|
||||
F1 "mcu.sch" 60
|
||||
$EndSheet
|
||||
$Sheet
|
||||
S 5900 1250 1600 1250
|
||||
U 4B6EC9C3
|
||||
F0 "Power Supply / Misc." 60
|
||||
F1 "pwr_misc.sch" 60
|
||||
$EndSheet
|
||||
$Sheet
|
||||
S 3650 1250 1650 1250
|
||||
U 4B6E18FC
|
||||
F0 "FPGA" 60
|
||||
F1 "fpga.sch" 60
|
||||
$EndSheet
|
||||
$EndSCHEMATC
|
||||
2059
pcb/kicad/RevE/snesslot.sch
Normal file
2059
pcb/kicad/RevE/snesslot.sch
Normal file
File diff suppressed because it is too large
Load Diff
1321
pcb/kicad/RevE2/fpga.sch
Normal file
1321
pcb/kicad/RevE2/fpga.sch
Normal file
File diff suppressed because it is too large
Load Diff
1193
pcb/kicad/RevE2/mcu.sch
Normal file
1193
pcb/kicad/RevE2/mcu.sch
Normal file
File diff suppressed because it is too large
Load Diff
806
pcb/kicad/RevE2/memory.sch
Normal file
806
pcb/kicad/RevE2/memory.sch
Normal file
@ -0,0 +1,806 @@
|
||||
EESchema Schematic File Version 2 date Mon 26 Dec 2011 09:56:13 PM CET
|
||||
LIBS:power
|
||||
LIBS:device
|
||||
LIBS:transistors
|
||||
LIBS:conn
|
||||
LIBS:linear
|
||||
LIBS:regul
|
||||
LIBS:74xx
|
||||
LIBS:cmos4000
|
||||
LIBS:adc-dac
|
||||
LIBS:memory
|
||||
LIBS:xilinx
|
||||
LIBS:special
|
||||
LIBS:microcontrollers
|
||||
LIBS:dsp
|
||||
LIBS:microchip
|
||||
LIBS:analog_switches
|
||||
LIBS:motorola
|
||||
LIBS:texas
|
||||
LIBS:intel
|
||||
LIBS:audio
|
||||
LIBS:interface
|
||||
LIBS:digital-audio
|
||||
LIBS:philips
|
||||
LIBS:display
|
||||
LIBS:cypress
|
||||
LIBS:siliconi
|
||||
LIBS:opto
|
||||
LIBS:atmel
|
||||
LIBS:contrib
|
||||
LIBS:valves
|
||||
LIBS:snescart
|
||||
LIBS:misc-74
|
||||
LIBS:vreg
|
||||
LIBS:lpc1754
|
||||
LIBS:sd_card
|
||||
LIBS:cy62148ev30
|
||||
LIBS:mt45w8mw16
|
||||
LIBS:cs4344
|
||||
LIBS:double_sch_kcom
|
||||
LIBS:usb_minib
|
||||
LIBS:mic23250
|
||||
EELAYER 25 0
|
||||
EELAYER END
|
||||
$Descr A4 11700 8267
|
||||
encoding utf-8
|
||||
Sheet 3 6
|
||||
Title "sd2snes Mark II"
|
||||
Date "26 dec 2011"
|
||||
Rev "E2"
|
||||
Comp "Maximilian Rehkopf"
|
||||
Comment1 ""
|
||||
Comment2 ""
|
||||
Comment3 ""
|
||||
Comment4 ""
|
||||
$EndDescr
|
||||
Text Label 7650 2000 0 50 ~ 0
|
||||
SRAM_Vcc
|
||||
Wire Wire Line
|
||||
7650 4750 7650 5000
|
||||
Wire Wire Line
|
||||
8350 5050 8350 5250
|
||||
Wire Wire Line
|
||||
8350 5250 8500 5250
|
||||
Connection ~ 9150 5250
|
||||
Wire Wire Line
|
||||
9150 5450 9150 5250
|
||||
Connection ~ 9600 2000
|
||||
Wire Wire Line
|
||||
9600 2000 9600 3350
|
||||
Wire Wire Line
|
||||
10500 2000 10350 2000
|
||||
Wire Wire Line
|
||||
8400 1400 8400 1600
|
||||
Wire Wire Line
|
||||
8400 1600 8050 1600
|
||||
Wire Wire Line
|
||||
6800 4350 6300 4350
|
||||
Wire Wire Line
|
||||
6800 4250 6300 4250
|
||||
Wire Wire Line
|
||||
6800 4150 6300 4150
|
||||
Wire Wire Line
|
||||
6800 4050 6300 4050
|
||||
Wire Wire Line
|
||||
6800 3950 6300 3950
|
||||
Wire Wire Line
|
||||
6800 3850 6300 3850
|
||||
Wire Wire Line
|
||||
6800 3750 6300 3750
|
||||
Wire Wire Line
|
||||
6800 3650 6300 3650
|
||||
Wire Wire Line
|
||||
6800 3550 6300 3550
|
||||
Wire Wire Line
|
||||
6800 3450 6300 3450
|
||||
Wire Wire Line
|
||||
6800 3350 6300 3350
|
||||
Wire Wire Line
|
||||
6800 3250 6300 3250
|
||||
Wire Wire Line
|
||||
6800 3150 6300 3150
|
||||
Wire Wire Line
|
||||
6800 3050 6300 3050
|
||||
Wire Wire Line
|
||||
6800 2950 6300 2950
|
||||
Wire Wire Line
|
||||
6800 2850 6300 2850
|
||||
Wire Wire Line
|
||||
6800 2750 6300 2750
|
||||
Wire Wire Line
|
||||
6800 2650 6300 2650
|
||||
Wire Wire Line
|
||||
6800 2550 6300 2550
|
||||
Wire Wire Line
|
||||
8500 3950 9000 3950
|
||||
Wire Wire Line
|
||||
4750 4750 4250 4750
|
||||
Wire Wire Line
|
||||
4250 4650 4750 4650
|
||||
Wire Wire Line
|
||||
4250 4350 4750 4350
|
||||
Wire Wire Line
|
||||
4250 4150 4750 4150
|
||||
Wire Wire Line
|
||||
4250 4050 4750 4050
|
||||
Wire Wire Line
|
||||
4250 3750 4750 3750
|
||||
Wire Wire Line
|
||||
4250 3650 4750 3650
|
||||
Wire Wire Line
|
||||
4250 3550 4750 3550
|
||||
Wire Wire Line
|
||||
4250 3450 4750 3450
|
||||
Wire Wire Line
|
||||
4250 3350 4750 3350
|
||||
Wire Wire Line
|
||||
4250 3250 4750 3250
|
||||
Wire Wire Line
|
||||
4250 3150 4750 3150
|
||||
Wire Wire Line
|
||||
4250 3050 4750 3050
|
||||
Wire Wire Line
|
||||
4250 2850 4750 2850
|
||||
Wire Wire Line
|
||||
4250 2750 4750 2750
|
||||
Wire Wire Line
|
||||
4250 2650 4750 2650
|
||||
Wire Wire Line
|
||||
4250 2550 4750 2550
|
||||
Wire Wire Line
|
||||
4250 2450 4750 2450
|
||||
Wire Wire Line
|
||||
4250 2350 4750 2350
|
||||
Wire Wire Line
|
||||
4250 2250 4750 2250
|
||||
Wire Wire Line
|
||||
4250 2150 4750 2150
|
||||
Wire Wire Line
|
||||
3550 6800 3550 6700
|
||||
Wire Wire Line
|
||||
3400 5400 3400 5300
|
||||
Wire Wire Line
|
||||
3300 5150 3300 5300
|
||||
Wire Wire Line
|
||||
3300 1750 3300 1550
|
||||
Connection ~ 7650 2000
|
||||
Wire Wire Line
|
||||
3500 1750 3500 1550
|
||||
Wire Wire Line
|
||||
3500 5150 3500 5300
|
||||
Wire Wire Line
|
||||
3500 5300 3300 5300
|
||||
Connection ~ 3400 5300
|
||||
Wire Wire Line
|
||||
3550 7200 3550 7300
|
||||
Wire Wire Line
|
||||
3250 7200 3250 7300
|
||||
Wire Wire Line
|
||||
3250 6700 3250 6800
|
||||
Wire Wire Line
|
||||
2550 2150 2050 2150
|
||||
Wire Wire Line
|
||||
2550 2250 2050 2250
|
||||
Wire Wire Line
|
||||
2550 2350 2050 2350
|
||||
Wire Wire Line
|
||||
2550 2450 2050 2450
|
||||
Wire Wire Line
|
||||
2550 2550 2050 2550
|
||||
Wire Wire Line
|
||||
2550 2650 2050 2650
|
||||
Wire Wire Line
|
||||
2550 2750 2050 2750
|
||||
Wire Wire Line
|
||||
2550 2850 2050 2850
|
||||
Wire Wire Line
|
||||
2550 2950 2050 2950
|
||||
Wire Wire Line
|
||||
2550 3050 2050 3050
|
||||
Wire Wire Line
|
||||
2550 3150 2050 3150
|
||||
Wire Wire Line
|
||||
2550 3250 2050 3250
|
||||
Wire Wire Line
|
||||
2550 3350 2050 3350
|
||||
Wire Wire Line
|
||||
2550 3450 2050 3450
|
||||
Wire Wire Line
|
||||
2550 3550 2050 3550
|
||||
Wire Wire Line
|
||||
2550 3650 2050 3650
|
||||
Wire Wire Line
|
||||
2550 3750 2050 3750
|
||||
Wire Wire Line
|
||||
2550 3850 2050 3850
|
||||
Wire Wire Line
|
||||
2550 3950 2050 3950
|
||||
Wire Wire Line
|
||||
2550 4050 2050 4050
|
||||
Wire Wire Line
|
||||
2550 4150 2050 4150
|
||||
Wire Wire Line
|
||||
2550 4250 2050 4250
|
||||
Wire Wire Line
|
||||
2550 4350 2050 4350
|
||||
Wire Wire Line
|
||||
2550 4650 2050 4650
|
||||
Wire Wire Line
|
||||
2550 4750 2050 4750
|
||||
Wire Wire Line
|
||||
2550 4550 2050 4550
|
||||
Wire Wire Line
|
||||
8500 4050 9000 4050
|
||||
Connection ~ 4750 4750
|
||||
Wire Wire Line
|
||||
4750 4350 4750 5400
|
||||
Connection ~ 4750 4650
|
||||
Wire Wire Line
|
||||
8500 2550 9000 2550
|
||||
Wire Wire Line
|
||||
8500 2650 9000 2650
|
||||
Wire Wire Line
|
||||
8500 2750 9000 2750
|
||||
Wire Wire Line
|
||||
8500 2850 9000 2850
|
||||
Wire Wire Line
|
||||
8500 2950 9000 2950
|
||||
Wire Wire Line
|
||||
8500 3050 9000 3050
|
||||
Wire Wire Line
|
||||
8500 3150 9000 3150
|
||||
Wire Wire Line
|
||||
8500 3250 9000 3250
|
||||
Wire Wire Line
|
||||
7250 1600 6900 1600
|
||||
Wire Wire Line
|
||||
6900 1600 6900 1400
|
||||
Wire Wire Line
|
||||
8500 3850 9600 3850
|
||||
Wire Wire Line
|
||||
9600 3850 9600 5050
|
||||
Wire Wire Line
|
||||
9000 5250 9300 5250
|
||||
Wire Wire Line
|
||||
9150 5950 9150 6050
|
||||
Wire Wire Line
|
||||
9150 6050 9600 6050
|
||||
Wire Wire Line
|
||||
9600 6350 9600 5450
|
||||
Connection ~ 9600 6050
|
||||
Wire Wire Line
|
||||
7650 2150 7650 1800
|
||||
Wire Wire Line
|
||||
9950 2000 7650 2000
|
||||
$Comp
|
||||
L CY62148EV30-ZSXI U511
|
||||
U 1 1 4D49598F
|
||||
P 7650 3450
|
||||
F 0 "U511" H 7650 3550 60 0000 C CNN
|
||||
F 1 "CY62148EV30-ZSXI" H 7700 3450 60 0000 C CNN
|
||||
1 7650 3450
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
Text Notes 7050 7000 0 250 ~ 50
|
||||
Memory
|
||||
Text Notes 7300 1300 0 50 ~ 0
|
||||
SRAM battery power
|
||||
Text Notes 9800 5300 0 50 ~ 0
|
||||
Battery power OE switch
|
||||
$Comp
|
||||
L +3.3V #PWR031
|
||||
U 1 1 4BF2FE97
|
||||
P 8350 5050
|
||||
F 0 "#PWR031" H 8350 5010 30 0001 C CNN
|
||||
F 1 "+3.3V" H 8350 5160 30 0000 C CNN
|
||||
1 8350 5050
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
$Comp
|
||||
L GND #PWR032
|
||||
U 1 1 4BF2FE7B
|
||||
P 9600 6350
|
||||
F 0 "#PWR032" H 9600 6350 30 0001 C CNN
|
||||
F 1 "GND" H 9600 6280 30 0001 C CNN
|
||||
1 9600 6350
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
$Comp
|
||||
L R R511
|
||||
U 1 1 4BF2FDAF
|
||||
P 9600 3600
|
||||
F 0 "R511" V 9680 3600 50 0000 C CNN
|
||||
F 1 "20k" V 9600 3600 50 0000 C CNN
|
||||
F 2 "SM0805_FIXEDMASK" H 9600 3600 60 0001 C CNN
|
||||
1 9600 3600
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
$Comp
|
||||
L R R513
|
||||
U 1 1 4BF2FDAC
|
||||
P 9150 5700
|
||||
F 0 "R513" V 9230 5700 50 0000 C CNN
|
||||
F 1 "100k" V 9150 5700 50 0000 C CNN
|
||||
F 2 "SM0805_FIXEDMASK" H 9150 5700 60 0001 C CNN
|
||||
1 9150 5700
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
$Comp
|
||||
L R R512
|
||||
U 1 1 4BF2FDA9
|
||||
P 8750 5250
|
||||
F 0 "R512" V 8830 5250 50 0000 C CNN
|
||||
F 1 "4k7" V 8750 5250 50 0000 C CNN
|
||||
F 2 "SM0805_FIXEDMASK" H 8750 5250 60 0001 C CNN
|
||||
1 8750 5250
|
||||
0 1 1 0
|
||||
$EndComp
|
||||
$Comp
|
||||
L NPN Q511
|
||||
U 1 1 4BF2FD9F
|
||||
P 9500 5250
|
||||
F 0 "Q511" H 9500 5100 50 0000 R CNN
|
||||
F 1 "2N2222A" H 9500 5400 50 0000 R CNN
|
||||
F 2 "SOT23EBC" H 9500 5250 60 0001 C CNN
|
||||
1 9500 5250
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
$Comp
|
||||
L GND #PWR033
|
||||
U 1 1 4BF1A006
|
||||
P 10500 2000
|
||||
F 0 "#PWR033" H 10500 2000 30 0001 C CNN
|
||||
F 1 "GND" H 10500 1930 30 0001 C CNN
|
||||
1 10500 2000
|
||||
0 -1 -1 0
|
||||
$EndComp
|
||||
$Comp
|
||||
L +BATT #PWR034
|
||||
U 1 1 4BF19EA4
|
||||
P 8400 1400
|
||||
F 0 "#PWR034" H 8400 1350 20 0001 C CNN
|
||||
F 1 "+BATT" H 8400 1500 30 0000 C CNN
|
||||
1 8400 1400
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
$Comp
|
||||
L +3.3V #PWR035
|
||||
U 1 1 4BF19E7A
|
||||
P 6900 1400
|
||||
F 0 "#PWR035" H 6900 1360 30 0001 C CNN
|
||||
F 1 "+3.3V" H 6900 1510 30 0000 C CNN
|
||||
1 6900 1400
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
$Comp
|
||||
L DOUBLE_SCH_KCOM2 D511
|
||||
U 1 1 4BF19DCA
|
||||
P 7650 1600
|
||||
F 0 "D511" H 7800 1475 60 0000 C CNN
|
||||
F 1 "BAT54C" H 7650 1750 60 0000 C CNN
|
||||
F 2 "SOT23EBC" H 7650 1600 60 0001 C CNN
|
||||
1 7650 1600
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
Text Label 8600 4050 0 50 ~ 0
|
||||
RAM_/WE
|
||||
Text Label 8600 3950 0 50 ~ 0
|
||||
RAM_/OE
|
||||
Text Label 8600 3850 0 50 ~ 0
|
||||
RAM_/CE
|
||||
Text Label 8600 3250 0 50 ~ 0
|
||||
RAM_DQ7
|
||||
Text Label 8600 3150 0 50 ~ 0
|
||||
RAM_DQ6
|
||||
Text Label 8600 3050 0 50 ~ 0
|
||||
RAM_DQ5
|
||||
Text Label 8600 2950 0 50 ~ 0
|
||||
RAM_DQ4
|
||||
Text Label 8600 2850 0 50 ~ 0
|
||||
RAM_DQ3
|
||||
Text Label 8600 2750 0 50 ~ 0
|
||||
RAM_DQ2
|
||||
Text Label 8600 2650 0 50 ~ 0
|
||||
RAM_DQ1
|
||||
Text Label 8600 2550 0 50 ~ 0
|
||||
RAM_DQ0
|
||||
Text Label 6400 4350 0 50 ~ 0
|
||||
RAM_A18
|
||||
Text Label 6400 4250 0 50 ~ 0
|
||||
RAM_A17
|
||||
Text Label 6400 4150 0 50 ~ 0
|
||||
RAM_A16
|
||||
Text Label 6400 4050 0 50 ~ 0
|
||||
RAM_A15
|
||||
Text Label 6400 3950 0 50 ~ 0
|
||||
RAM_A14
|
||||
Text Label 6400 3850 0 50 ~ 0
|
||||
RAM_A13
|
||||
Text Label 6400 3750 0 50 ~ 0
|
||||
RAM_A12
|
||||
Text Label 6400 3650 0 50 ~ 0
|
||||
RAM_A11
|
||||
Text Label 6400 3550 0 50 ~ 0
|
||||
RAM_A10
|
||||
Text Label 6400 3450 0 50 ~ 0
|
||||
RAM_A9
|
||||
Text Label 6400 3350 0 50 ~ 0
|
||||
RAM_A8
|
||||
Text Label 6400 3250 0 50 ~ 0
|
||||
RAM_A7
|
||||
Text Label 6400 3150 0 50 ~ 0
|
||||
RAM_A6
|
||||
Text Label 6400 3050 0 50 ~ 0
|
||||
RAM_A5
|
||||
Text Label 6400 2950 0 50 ~ 0
|
||||
RAM_A4
|
||||
Text Label 6400 2850 0 50 ~ 0
|
||||
RAM_A3
|
||||
Text Label 6400 2750 0 50 ~ 0
|
||||
RAM_A2
|
||||
Text Label 6400 2650 0 50 ~ 0
|
||||
RAM_A1
|
||||
Text Label 6400 2550 0 50 ~ 0
|
||||
RAM_A0
|
||||
Text Label 4350 4150 0 50 ~ 0
|
||||
ROM_/UB
|
||||
Text Label 4350 4050 0 50 ~ 0
|
||||
ROM_/LB
|
||||
Text Label 4350 3750 0 50 ~ 0
|
||||
ROM_DQ15
|
||||
Text Label 4350 3650 0 50 ~ 0
|
||||
ROM_DQ14
|
||||
Text Label 4350 3550 0 50 ~ 0
|
||||
ROM_DQ13
|
||||
Text Label 4350 3450 0 50 ~ 0
|
||||
ROM_DQ12
|
||||
Text Label 4350 3350 0 50 ~ 0
|
||||
ROM_DQ11
|
||||
Text Label 4350 3250 0 50 ~ 0
|
||||
ROM_DQ10
|
||||
Text Label 4350 3150 0 50 ~ 0
|
||||
ROM_DQ9
|
||||
Text Label 4350 3050 0 50 ~ 0
|
||||
ROM_DQ8
|
||||
Text Label 4350 2850 0 50 ~ 0
|
||||
ROM_DQ7
|
||||
Text Label 4350 2750 0 50 ~ 0
|
||||
ROM_DQ6
|
||||
Text Label 4350 2650 0 50 ~ 0
|
||||
ROM_DQ5
|
||||
Text Label 4350 2550 0 50 ~ 0
|
||||
ROM_DQ4
|
||||
Text Label 4350 2450 0 50 ~ 0
|
||||
ROM_DQ3
|
||||
Text Label 4350 2350 0 50 ~ 0
|
||||
ROM_DQ2
|
||||
Text Label 4350 2250 0 50 ~ 0
|
||||
ROM_DQ1
|
||||
Text Label 4350 2150 0 50 ~ 0
|
||||
ROM_DQ0
|
||||
Text Label 2100 4750 0 50 ~ 0
|
||||
ROM_/WE
|
||||
Text Label 2100 4650 0 50 ~ 0
|
||||
ROM_/OE
|
||||
Text Label 2100 4550 0 50 ~ 0
|
||||
ROM_/CE
|
||||
Text Label 2100 4350 0 50 ~ 0
|
||||
ROM_A22
|
||||
Text Label 2100 4250 0 50 ~ 0
|
||||
ROM_A21
|
||||
Text Label 2100 4150 0 50 ~ 0
|
||||
ROM_A20
|
||||
Text Label 2100 4050 0 50 ~ 0
|
||||
ROM_A19
|
||||
Text Label 2100 3950 0 50 ~ 0
|
||||
ROM_A18
|
||||
Text Label 2100 3850 0 50 ~ 0
|
||||
ROM_A17
|
||||
Text Label 2100 3750 0 50 ~ 0
|
||||
ROM_A16
|
||||
Text Label 2100 3650 0 50 ~ 0
|
||||
ROM_A15
|
||||
Text Label 2100 3550 0 50 ~ 0
|
||||
ROM_A14
|
||||
Text Label 2100 3450 0 50 ~ 0
|
||||
ROM_A13
|
||||
Text Label 2100 3350 0 50 ~ 0
|
||||
ROM_A12
|
||||
Text Label 2100 3250 0 50 ~ 0
|
||||
ROM_A11
|
||||
Text Label 2100 3150 0 50 ~ 0
|
||||
ROM_A10
|
||||
Text Label 2100 3050 0 50 ~ 0
|
||||
ROM_A9
|
||||
Text Label 2100 2950 0 50 ~ 0
|
||||
ROM_A8
|
||||
Text Label 2100 2850 0 50 ~ 0
|
||||
ROM_A7
|
||||
Text Label 2100 2750 0 50 ~ 0
|
||||
ROM_A6
|
||||
Text Label 2100 2650 0 50 ~ 0
|
||||
ROM_A5
|
||||
Text Label 2100 2550 0 50 ~ 0
|
||||
ROM_A4
|
||||
Text Label 2100 2450 0 50 ~ 0
|
||||
ROM_A3
|
||||
Text Label 2100 2350 0 50 ~ 0
|
||||
ROM_A2
|
||||
Text Label 2100 2250 0 50 ~ 0
|
||||
ROM_A1
|
||||
Text Label 2100 2150 0 50 ~ 0
|
||||
ROM_A0
|
||||
Text GLabel 2050 4550 0 50 Input ~ 0
|
||||
ROM_/CE
|
||||
Text GLabel 9000 4050 2 50 Input ~ 0
|
||||
RAM_/WE
|
||||
Text GLabel 9000 3950 2 50 Input ~ 0
|
||||
RAM_/OE
|
||||
Text GLabel 9000 3250 2 50 BiDi ~ 0
|
||||
RAM_DQ7
|
||||
Text GLabel 9000 3150 2 50 BiDi ~ 0
|
||||
RAM_DQ6
|
||||
Text GLabel 9000 3050 2 50 BiDi ~ 0
|
||||
RAM_DQ5
|
||||
Text GLabel 9000 2950 2 50 BiDi ~ 0
|
||||
RAM_DQ4
|
||||
Text GLabel 9000 2850 2 50 BiDi ~ 0
|
||||
RAM_DQ3
|
||||
Text GLabel 9000 2750 2 50 BiDi ~ 0
|
||||
RAM_DQ2
|
||||
Text GLabel 9000 2650 2 50 BiDi ~ 0
|
||||
RAM_DQ1
|
||||
Text GLabel 9000 2550 2 50 BiDi ~ 0
|
||||
RAM_DQ0
|
||||
Text GLabel 6300 4350 0 50 Input ~ 0
|
||||
RAM_A18
|
||||
Text GLabel 6300 4250 0 50 Input ~ 0
|
||||
RAM_A17
|
||||
Text GLabel 6300 4150 0 50 Input ~ 0
|
||||
RAM_A16
|
||||
Text GLabel 6300 4050 0 50 Input ~ 0
|
||||
RAM_A15
|
||||
Text GLabel 6300 3950 0 50 Input ~ 0
|
||||
RAM_A14
|
||||
Text GLabel 6300 3850 0 50 Input ~ 0
|
||||
RAM_A13
|
||||
Text GLabel 6300 3750 0 50 Input ~ 0
|
||||
RAM_A12
|
||||
Text GLabel 6300 3650 0 50 Input ~ 0
|
||||
RAM_A11
|
||||
Text GLabel 6300 3550 0 50 Input ~ 0
|
||||
RAM_A10
|
||||
Text GLabel 6300 3450 0 50 Input ~ 0
|
||||
RAM_A9
|
||||
Text GLabel 6300 3350 0 50 Input ~ 0
|
||||
RAM_A8
|
||||
Text GLabel 6300 3250 0 50 Input ~ 0
|
||||
RAM_A7
|
||||
Text GLabel 6300 3150 0 50 Input ~ 0
|
||||
RAM_A6
|
||||
Text GLabel 6300 3050 0 50 Input ~ 0
|
||||
RAM_A5
|
||||
Text GLabel 6300 2950 0 50 Input ~ 0
|
||||
RAM_A4
|
||||
Text GLabel 6300 2850 0 50 Input ~ 0
|
||||
RAM_A3
|
||||
Text GLabel 6300 2750 0 50 Input ~ 0
|
||||
RAM_A2
|
||||
Text GLabel 6300 2650 0 50 Input ~ 0
|
||||
RAM_A1
|
||||
Text GLabel 6300 2550 0 50 Input ~ 0
|
||||
RAM_A0
|
||||
Text GLabel 4750 4150 2 50 Input ~ 0
|
||||
ROM_/UB
|
||||
Text GLabel 4750 4050 2 50 Input ~ 0
|
||||
ROM_/LB
|
||||
Text GLabel 4750 3750 2 50 BiDi ~ 0
|
||||
ROM_DQ15
|
||||
Text GLabel 4750 3650 2 50 BiDi ~ 0
|
||||
ROM_DQ14
|
||||
Text GLabel 4750 3550 2 50 BiDi ~ 0
|
||||
ROM_DQ13
|
||||
Text GLabel 4750 3450 2 50 BiDi ~ 0
|
||||
ROM_DQ12
|
||||
Text GLabel 4750 3350 2 50 BiDi ~ 0
|
||||
ROM_DQ11
|
||||
Text GLabel 4750 3250 2 50 BiDi ~ 0
|
||||
ROM_DQ10
|
||||
Text GLabel 4750 3150 2 50 BiDi ~ 0
|
||||
ROM_DQ9
|
||||
Text GLabel 4750 3050 2 50 BiDi ~ 0
|
||||
ROM_DQ8
|
||||
Text GLabel 4750 2850 2 50 BiDi ~ 0
|
||||
ROM_DQ7
|
||||
Text GLabel 4750 2750 2 50 BiDi ~ 0
|
||||
ROM_DQ6
|
||||
Text GLabel 4750 2650 2 50 BiDi ~ 0
|
||||
ROM_DQ5
|
||||
Text GLabel 4750 2550 2 50 BiDi ~ 0
|
||||
ROM_DQ4
|
||||
Text GLabel 4750 2450 2 50 BiDi ~ 0
|
||||
ROM_DQ3
|
||||
Text GLabel 4750 2350 2 50 BiDi ~ 0
|
||||
ROM_DQ2
|
||||
Text GLabel 4750 2250 2 50 BiDi ~ 0
|
||||
ROM_DQ1
|
||||
Text GLabel 4750 2150 2 50 BiDi ~ 0
|
||||
ROM_DQ0
|
||||
Text GLabel 2050 4350 0 50 Input ~ 0
|
||||
ROM_A22
|
||||
Text GLabel 2050 4250 0 50 Input ~ 0
|
||||
ROM_A21
|
||||
Text GLabel 2050 4150 0 50 Input ~ 0
|
||||
ROM_A20
|
||||
Text GLabel 2050 4050 0 50 Input ~ 0
|
||||
ROM_A19
|
||||
Text GLabel 2050 3950 0 50 Input ~ 0
|
||||
ROM_A18
|
||||
Text GLabel 2050 3850 0 50 Input ~ 0
|
||||
ROM_A17
|
||||
Text GLabel 2050 3750 0 50 Input ~ 0
|
||||
ROM_A16
|
||||
Text GLabel 2050 3650 0 50 Input ~ 0
|
||||
ROM_A15
|
||||
Text GLabel 2050 3550 0 50 Input ~ 0
|
||||
ROM_A14
|
||||
Text GLabel 2050 3450 0 50 Input ~ 0
|
||||
ROM_A13
|
||||
Text GLabel 2050 3350 0 50 Input ~ 0
|
||||
ROM_A12
|
||||
Text GLabel 2050 3250 0 50 Input ~ 0
|
||||
ROM_A11
|
||||
Text GLabel 2050 3150 0 50 Input ~ 0
|
||||
ROM_A10
|
||||
Text GLabel 2050 3050 0 50 Input ~ 0
|
||||
ROM_A9
|
||||
Text GLabel 2050 2950 0 50 Input ~ 0
|
||||
ROM_A8
|
||||
Text GLabel 2050 2850 0 50 Input ~ 0
|
||||
ROM_A7
|
||||
Text GLabel 2050 2750 0 50 Input ~ 0
|
||||
ROM_A6
|
||||
Text GLabel 2050 2650 0 50 Input ~ 0
|
||||
ROM_A5
|
||||
Text GLabel 2050 2550 0 50 Input ~ 0
|
||||
ROM_A4
|
||||
Text GLabel 2050 2450 0 50 Input ~ 0
|
||||
ROM_A3
|
||||
Text GLabel 2050 2350 0 50 Input ~ 0
|
||||
ROM_A2
|
||||
Text GLabel 2050 2250 0 50 Input ~ 0
|
||||
ROM_A1
|
||||
Text GLabel 2050 2150 0 50 Input ~ 0
|
||||
ROM_A0
|
||||
NoConn ~ 4250 4550
|
||||
$Comp
|
||||
L GND #PWR036
|
||||
U 1 1 4BCA30BF
|
||||
P 4750 5400
|
||||
F 0 "#PWR036" H 4750 5400 30 0001 C CNN
|
||||
F 1 "GND" H 4750 5330 30 0001 C CNN
|
||||
1 4750 5400
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
Text GLabel 2050 4750 0 50 Input ~ 0
|
||||
ROM_/WE
|
||||
Text GLabel 2050 4650 0 50 Input ~ 0
|
||||
ROM_/OE
|
||||
$Comp
|
||||
L C C502
|
||||
U 1 1 4BAD3D55
|
||||
P 3550 7000
|
||||
F 0 "C502" H 3600 7100 50 0000 L CNN
|
||||
F 1 "100n" H 3600 6900 50 0000 L CNN
|
||||
F 2 "SM0805_FIXEDMASK" H 3550 7000 60 0001 C CNN
|
||||
1 3550 7000
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
$Comp
|
||||
L C C511
|
||||
U 1 1 4BAD3D53
|
||||
P 10150 2000
|
||||
F 0 "C511" H 10200 2100 50 0000 L CNN
|
||||
F 1 "100n" H 10200 1900 50 0000 L CNN
|
||||
F 2 "SM0805_FIXEDMASK" H 10150 2000 60 0001 C CNN
|
||||
1 10150 2000
|
||||
0 -1 1 0
|
||||
$EndComp
|
||||
$Comp
|
||||
L C C501
|
||||
U 1 1 4BAD3D47
|
||||
P 3250 7000
|
||||
F 0 "C501" H 3300 7100 50 0000 L CNN
|
||||
F 1 "100n" H 3300 6900 50 0000 L CNN
|
||||
F 2 "SM0805_FIXEDMASK" H 3250 7000 60 0001 C CNN
|
||||
1 3250 7000
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
$Comp
|
||||
L GND #PWR037
|
||||
U 1 1 4BAD3D2B
|
||||
P 3550 7300
|
||||
F 0 "#PWR037" H 3550 7300 30 0001 C CNN
|
||||
F 1 "GND" H 3550 7230 30 0001 C CNN
|
||||
1 3550 7300
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
$Comp
|
||||
L +1.8V #PWR038
|
||||
U 1 1 4BAD3D27
|
||||
P 3550 6700
|
||||
F 0 "#PWR038" H 3550 6840 20 0001 C CNN
|
||||
F 1 "+1.8V" H 3550 6810 30 0000 C CNN
|
||||
1 3550 6700
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
$Comp
|
||||
L GND #PWR039
|
||||
U 1 1 4BAD3D20
|
||||
P 3250 7300
|
||||
F 0 "#PWR039" H 3250 7300 30 0001 C CNN
|
||||
F 1 "GND" H 3250 7230 30 0001 C CNN
|
||||
1 3250 7300
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
$Comp
|
||||
L +3.3V #PWR040
|
||||
U 1 1 4BAD3D0B
|
||||
P 3250 6700
|
||||
F 0 "#PWR040" H 3250 6660 30 0001 C CNN
|
||||
F 1 "+3.3V" H 3250 6810 30 0000 C CNN
|
||||
1 3250 6700
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
$Comp
|
||||
L GND #PWR041
|
||||
U 1 1 4BAD33A7
|
||||
P 3400 5400
|
||||
F 0 "#PWR041" H 3400 5400 30 0001 C CNN
|
||||
F 1 "GND" H 3400 5330 30 0001 C CNN
|
||||
1 3400 5400
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
$Comp
|
||||
L GND #PWR042
|
||||
U 1 1 4BAD339F
|
||||
P 7650 5000
|
||||
F 0 "#PWR042" H 7650 5000 30 0001 C CNN
|
||||
F 1 "GND" H 7650 4930 30 0001 C CNN
|
||||
1 7650 5000
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
$Comp
|
||||
L +1.8V #PWR043
|
||||
U 1 1 4BAD32D2
|
||||
P 3300 1550
|
||||
F 0 "#PWR043" H 3300 1690 20 0001 C CNN
|
||||
F 1 "+1.8V" H 3300 1660 30 0000 C CNN
|
||||
1 3300 1550
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
$Comp
|
||||
L +3.3V #PWR044
|
||||
U 1 1 4BAD32BE
|
||||
P 3500 1550
|
||||
F 0 "#PWR044" H 3500 1510 30 0001 C CNN
|
||||
F 1 "+3.3V" H 3500 1660 30 0000 C CNN
|
||||
1 3500 1550
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
Text Notes 6300 5700 0 60 ~ 0
|
||||
4Mbits 45ns SRAM (battery RAM + custom chip work RAM)
|
||||
Text Notes 2650 5700 0 60 ~ 0
|
||||
128Mbits 70ns PSRAM (ROM area)
|
||||
$Comp
|
||||
L MT45W8MW16 U501
|
||||
U 1 1 4B868602
|
||||
P 3400 3450
|
||||
F 0 "U501" H 3400 3550 60 0000 C CNN
|
||||
F 1 "MT45W8MW16" H 3400 3450 60 0000 C CNN
|
||||
F 2 "VFBGA54" H 3400 3450 60 0001 C CNN
|
||||
1 3400 3450
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
$EndSCHEMATC
|
||||
17
pcb/kicad/RevE2/padreduce.sh
Executable file
17
pcb/kicad/RevE2/padreduce.sh
Executable file
@ -0,0 +1,17 @@
|
||||
cp "$1" "$1".bak
|
||||
|
||||
sed -e 's/^%ADD\(..\)R/%ADD\1O/g' < "$1" > "$1".tmp1
|
||||
|
||||
grep ^%ADD..O "$1".tmp1 | while read ln; do LS=${ln:0:8}; X=${ln:8:8}; Y=${ln:17:8}; X2=`echo $X-.002 | bc -l`; Y2=`echo $Y-.002 | bc -l`; echo $LS`printf '%01.6f' $X2`X`printf '%01.6f' $Y2`*%; done > "$1".tmp2
|
||||
|
||||
grep ^%ADD..C "$1".tmp1 | while read ln; do LS=${ln:0:8}; X=${ln:8:8}; X2=`echo $X-.002 | bc -l`; echo $LS`printf '%01.6f' $X2`*%; done >> "$1".tmp2
|
||||
|
||||
while read ln; do echo "$ln" | grep '^%ADD' >/dev/null && break; echo "$ln"; done < "$1".tmp1 > "$1"
|
||||
|
||||
cat "$1".tmp2 >> "$1"
|
||||
|
||||
grep -A100000 'G04 APERTURE END LIST\*' "$1".tmp1 >> "$1"
|
||||
|
||||
rm "$1".tmp1 "$1".tmp2
|
||||
|
||||
|
||||
1246
pcb/kicad/RevE2/pwr_misc.sch
Normal file
1246
pcb/kicad/RevE2/pwr_misc.sch
Normal file
File diff suppressed because it is too large
Load Diff
35370
pcb/kicad/RevE2/sd2snes.brd
Normal file
35370
pcb/kicad/RevE2/sd2snes.brd
Normal file
File diff suppressed because it is too large
Load Diff
1067
pcb/kicad/RevE2/sd2snes.cmp
Normal file
1067
pcb/kicad/RevE2/sd2snes.cmp
Normal file
File diff suppressed because it is too large
Load Diff
3218
pcb/kicad/RevE2/sd2snes.net
Normal file
3218
pcb/kicad/RevE2/sd2snes.net
Normal file
File diff suppressed because it is too large
Load Diff
116
pcb/kicad/RevE2/sd2snes.pro
Normal file
116
pcb/kicad/RevE2/sd2snes.pro
Normal file
@ -0,0 +1,116 @@
|
||||
update=Tue 27 Dec 2011 01:22:01 AM CET
|
||||
version=1
|
||||
last_client=pcbnew
|
||||
[general]
|
||||
version=1
|
||||
[cvpcb]
|
||||
version=1
|
||||
NetIExt=net
|
||||
[cvpcb/libraries]
|
||||
EquName1=devcms
|
||||
[eeschema]
|
||||
version=1
|
||||
LibDir=../../kicad
|
||||
NetFmt=1
|
||||
HPGLSpd=20
|
||||
HPGLDm=15
|
||||
HPGLNum=1
|
||||
offX_A4=0
|
||||
offY_A4=0
|
||||
offX_A3=0
|
||||
offY_A3=0
|
||||
offX_A2=0
|
||||
offY_A2=0
|
||||
offX_A1=0
|
||||
offY_A1=0
|
||||
offX_A0=0
|
||||
offY_A0=0
|
||||
offX_A=0
|
||||
offY_A=0
|
||||
offX_B=0
|
||||
offY_B=0
|
||||
offX_C=0
|
||||
offY_C=0
|
||||
offX_D=0
|
||||
offY_D=0
|
||||
offX_E=0
|
||||
offY_E=0
|
||||
RptD_X=0
|
||||
RptD_Y=100
|
||||
RptLab=1
|
||||
LabSize=50
|
||||
[eeschema/libraries]
|
||||
LibName1=power
|
||||
LibName2=device
|
||||
LibName3=transistors
|
||||
LibName4=conn
|
||||
LibName5=linear
|
||||
LibName6=regul
|
||||
LibName7=74xx
|
||||
LibName8=cmos4000
|
||||
LibName9=adc-dac
|
||||
LibName10=memory
|
||||
LibName11=xilinx
|
||||
LibName12=special
|
||||
LibName13=microcontrollers
|
||||
LibName14=dsp
|
||||
LibName15=microchip
|
||||
LibName16=analog_switches
|
||||
LibName17=motorola
|
||||
LibName18=texas
|
||||
LibName19=intel
|
||||
LibName20=audio
|
||||
LibName21=interface
|
||||
LibName22=digital-audio
|
||||
LibName23=philips
|
||||
LibName24=display
|
||||
LibName25=cypress
|
||||
LibName26=siliconi
|
||||
LibName27=opto
|
||||
LibName28=atmel
|
||||
LibName29=contrib
|
||||
LibName30=valves
|
||||
LibName31=libs/snescart
|
||||
LibName32=libs/misc-74
|
||||
LibName33=libs/vreg
|
||||
LibName34=libs/lpc1754
|
||||
LibName35=libs/sd_card
|
||||
LibName36=libs/cy62148ev30
|
||||
LibName37=libs/mt45w8mw16
|
||||
LibName38=libs/cs4344
|
||||
LibName39=libs/double_sch_kcom
|
||||
LibName40=libs/usb_minib
|
||||
LibName41=libs/mic23250
|
||||
[pcbnew]
|
||||
version=1
|
||||
PadDrlX=400
|
||||
PadDimH=660
|
||||
PadDimV=660
|
||||
BoardThickness=630
|
||||
TxtPcbV=800
|
||||
TxtPcbH=600
|
||||
TxtModV=600
|
||||
TxtModH=600
|
||||
TxtModW=120
|
||||
VEgarde=40
|
||||
DrawLar=70
|
||||
EdgeLar=40
|
||||
TxtLar=120
|
||||
MSegLar=79
|
||||
LastNetListRead=sd2snes.net
|
||||
[pcbnew/libraries]
|
||||
LibDir=../../kicad
|
||||
LibName1=sockets
|
||||
LibName2=connect
|
||||
LibName3=discret
|
||||
LibName4=pin_array
|
||||
LibName5=divers
|
||||
LibName6=libcms
|
||||
LibName7=display
|
||||
LibName8=valves
|
||||
LibName9=led
|
||||
LibName10=dip_sockets
|
||||
LibName11=libs/mypackages
|
||||
LibName12=libs/hai
|
||||
LibName13=libs/snescart
|
||||
LibName14=libs/sdcard
|
||||
93
pcb/kicad/RevE2/sd2snes.sch
Normal file
93
pcb/kicad/RevE2/sd2snes.sch
Normal file
@ -0,0 +1,93 @@
|
||||
EESchema Schematic File Version 2 date Mon 26 Dec 2011 09:56:13 PM CET
|
||||
LIBS:power
|
||||
LIBS:device
|
||||
LIBS:transistors
|
||||
LIBS:conn
|
||||
LIBS:linear
|
||||
LIBS:regul
|
||||
LIBS:74xx
|
||||
LIBS:cmos4000
|
||||
LIBS:adc-dac
|
||||
LIBS:memory
|
||||
LIBS:xilinx
|
||||
LIBS:special
|
||||
LIBS:microcontrollers
|
||||
LIBS:dsp
|
||||
LIBS:microchip
|
||||
LIBS:analog_switches
|
||||
LIBS:motorola
|
||||
LIBS:texas
|
||||
LIBS:intel
|
||||
LIBS:audio
|
||||
LIBS:interface
|
||||
LIBS:digital-audio
|
||||
LIBS:philips
|
||||
LIBS:display
|
||||
LIBS:cypress
|
||||
LIBS:siliconi
|
||||
LIBS:opto
|
||||
LIBS:atmel
|
||||
LIBS:contrib
|
||||
LIBS:valves
|
||||
LIBS:snescart
|
||||
LIBS:misc-74
|
||||
LIBS:vreg
|
||||
LIBS:lpc1754
|
||||
LIBS:sd_card
|
||||
LIBS:cy62148ev30
|
||||
LIBS:mt45w8mw16
|
||||
LIBS:cs4344
|
||||
LIBS:double_sch_kcom
|
||||
LIBS:usb_minib
|
||||
LIBS:mic23250
|
||||
EELAYER 25 0
|
||||
EELAYER END
|
||||
$Descr A4 11700 8267
|
||||
encoding utf-8
|
||||
Sheet 1 6
|
||||
Title "sd2snes Mark II"
|
||||
Date "26 dec 2011"
|
||||
Rev "E2"
|
||||
Comp "Maximilian Rehkopf"
|
||||
Comment1 ""
|
||||
Comment2 ""
|
||||
Comment3 ""
|
||||
Comment4 ""
|
||||
$EndDescr
|
||||
Wire Notes Line
|
||||
3650 4200 6150 4200
|
||||
Text Notes 3300 3250 0 100 ~ 0
|
||||
Changes from Rev.A / TODO:\n [x] remove FPGA from JTAG chain\n [x] remove SNES IRQ_DIR+IRQ, replace with IRQ_OE. IRQ is unidirectional cart -> console\n (replace 1gate w/ transistor)\n [x] disconnect P2.10 from FPGA, using a different GPIO for IRQ / INIT_B\n [x] add pullup to P2.10\n [ ] add JTAG pullups\n [x] add series resistor for CPU_CLK\n [x] add a jumper in PIC MCLR line to MCU\n [x] change PIC to DIP8 type for easier preprogramming\n [x] change "P1" to "P401" in pin description in silk screen\n [x] filter CIC data lines\n [x] rearrange SD card interface/LEDs on MCU\n [x] RAs for SNES signals?\n [x] reroute/add decoupling capacitors\n [x] filter SNES control signals (RD, WR, PARD, PAWR, CPU_CLK, IRQ)\n [x] replace 4Mbit SRAM with much cheaper TSOP-II type\n [x] add inverse polarity protection\n [x] separate GND plane for DAC\n [ ] separate JTAG pads for FPGA\n [x] add USE_BATT jumper\n [x] move PROG_B to P1.15
|
||||
$Sheet
|
||||
S 1250 1250 1700 1250
|
||||
U 4B6E16F2
|
||||
F0 "SNES Slot" 60
|
||||
F1 "snesslot.sch" 60
|
||||
$EndSheet
|
||||
Text Notes 750 7700 0 500 ~ 100
|
||||
sd2snes Mark II
|
||||
$Sheet
|
||||
S 1250 3300 1600 1150
|
||||
U 4BAA6ABD
|
||||
F0 "Memory" 60
|
||||
F1 "memory.sch" 60
|
||||
$EndSheet
|
||||
$Sheet
|
||||
S 8050 1250 1600 1250
|
||||
U 4B6ED75B
|
||||
F0 "MCU" 60
|
||||
F1 "mcu.sch" 60
|
||||
$EndSheet
|
||||
$Sheet
|
||||
S 5900 1250 1600 1250
|
||||
U 4B6EC9C3
|
||||
F0 "Power Supply / Misc." 60
|
||||
F1 "pwr_misc.sch" 60
|
||||
$EndSheet
|
||||
$Sheet
|
||||
S 3650 1250 1650 1250
|
||||
U 4B6E18FC
|
||||
F0 "FPGA" 60
|
||||
F1 "fpga.sch" 60
|
||||
$EndSheet
|
||||
$EndSCHEMATC
|
||||
2058
pcb/kicad/RevE2/snesslot.sch
Normal file
2058
pcb/kicad/RevE2/snesslot.sch
Normal file
File diff suppressed because it is too large
Load Diff
6275
pcb/kicad/libs/mypackages.mod
Normal file
6275
pcb/kicad/libs/mypackages.mod
Normal file
File diff suppressed because it is too large
Load Diff
276
pcb/kicad/libs/sdcard.bak
Normal file
276
pcb/kicad/libs/sdcard.bak
Normal file
@ -0,0 +1,276 @@
|
||||
PCBNEW-LibModule-V1 Mon 26 Jul 2010 09:33:33 PM CEST
|
||||
$INDEX
|
||||
SD-RSMT-2-MQ-WF
|
||||
HRS-DM1AA
|
||||
$EndINDEX
|
||||
$MODULE SD-RSMT-2-MQ-WF
|
||||
Po 0 0 0 15 4C4D74E3 00000000 ~~
|
||||
Li SD-RSMT-2-MQ-WF
|
||||
Sc 00000000
|
||||
AR /4B6ED75B/4BAA6A9C
|
||||
Op 0 0 0
|
||||
T0 4900 -450 300 300 0 60 N V 21 N"J2"
|
||||
T1 0 6000 300 300 0 60 N V 21 N"SD_CARD"
|
||||
DS -5197 39 5827 39 70 21
|
||||
DS 5827 9803 5827 39 70 21
|
||||
DS -5197 12047 5827 12047 70 21
|
||||
DS 5827 12047 5827 11260 70 21
|
||||
DS -5197 11260 -5197 12047 70 21
|
||||
DS -5197 39 -5197 9803 70 21
|
||||
$PAD
|
||||
Sh "GND2" R 787 1181 0 0 0
|
||||
Dr 0 0 0
|
||||
At SMD N 00888000
|
||||
Ne 0 ""
|
||||
Po 6228 10531
|
||||
$EndPAD
|
||||
$PAD
|
||||
Sh "GND1" R 787 1181 0 0 0
|
||||
Dr 0 0 0
|
||||
At SMD N 00888000
|
||||
Ne 0 ""
|
||||
Po -5622 10531
|
||||
$EndPAD
|
||||
$PAD
|
||||
Sh "3" R 394 591 0 0 0
|
||||
Dr 0 0 0
|
||||
At SMD N 00888000
|
||||
Ne 0 ""
|
||||
Po 740 -394
|
||||
$EndPAD
|
||||
$PAD
|
||||
Sh "2" R 394 591 0 0 0
|
||||
Dr 0 0 0
|
||||
At SMD N 00888000
|
||||
Ne 0 ""
|
||||
Po 1724 -394
|
||||
$EndPAD
|
||||
$PAD
|
||||
Sh "1" R 394 591 0 0 0
|
||||
Dr 0 0 0
|
||||
At SMD N 00888000
|
||||
Ne 0 ""
|
||||
Po 2709 -394
|
||||
$EndPAD
|
||||
$PAD
|
||||
Sh "9" R 394 591 0 0 0
|
||||
Dr 0 0 0
|
||||
At SMD N 00888000
|
||||
Ne 0 ""
|
||||
Po 3693 -394
|
||||
$EndPAD
|
||||
$PAD
|
||||
Sh "DT" R 276 591 0 0 0
|
||||
Dr 0 0 0
|
||||
At SMD N 00888000
|
||||
Ne 0 ""
|
||||
Po -4350 -394
|
||||
$EndPAD
|
||||
$PAD
|
||||
Sh "8" R 394 591 0 0 0
|
||||
Dr 0 0 0
|
||||
At SMD N 00888000
|
||||
Ne 0 ""
|
||||
Po -3839 -394
|
||||
$EndPAD
|
||||
$PAD
|
||||
Sh "7" R 394 591 0 0 0
|
||||
Dr 0 0 0
|
||||
At SMD N 00888000
|
||||
Ne 0 ""
|
||||
Po -3169 -394
|
||||
$EndPAD
|
||||
$PAD
|
||||
Sh "5" R 394 591 0 0 0
|
||||
Dr 0 0 0
|
||||
At SMD N 00888000
|
||||
Ne 0 ""
|
||||
Po -1228 -394
|
||||
$EndPAD
|
||||
$PAD
|
||||
Sh "6" R 394 591 0 0 0
|
||||
Dr 0 0 0
|
||||
At SMD N 00888000
|
||||
Ne 0 ""
|
||||
Po -2213 -394
|
||||
$EndPAD
|
||||
$PAD
|
||||
Sh "4" R 394 591 0 0 0
|
||||
Dr 0 0 0
|
||||
At SMD N 00888000
|
||||
Ne 0 ""
|
||||
Po -244 -394
|
||||
$EndPAD
|
||||
$PAD
|
||||
Sh "WP" R 276 591 0 0 0
|
||||
Dr 0 0 0
|
||||
At SMD N 00888000
|
||||
Ne 0 ""
|
||||
Po -4823 -394
|
||||
$EndPAD
|
||||
$PAD
|
||||
Sh "" C 433 433 0 0 0
|
||||
Dr 433 0 0
|
||||
At STD N 00C0FFFF
|
||||
Ne 0 ""
|
||||
Po -4528 709
|
||||
$EndPAD
|
||||
$PAD
|
||||
Sh "" C 630 630 0 0 0
|
||||
Dr 630 0 0
|
||||
At STD N 00C0FFFF
|
||||
Ne 0 ""
|
||||
Po 3740 709
|
||||
$EndPAD
|
||||
$EndMODULE SD-RSMT-2-MQ-WF
|
||||
$MODULE HRS-DM1AA
|
||||
Po 0 0 0 15 4C4DE307 00000000 ~~
|
||||
Li HRS-DM1AA
|
||||
Sc 00000000
|
||||
AR
|
||||
Op 0 0 0
|
||||
T0 0 0 300 300 0 60 N V 21 N"HRS-DM1AA"
|
||||
T1 0 0 300 300 0 60 N V 21 N"VAL**"
|
||||
DS 4134 -5984 5512 -5984 120 21
|
||||
DS 5512 6024 -5512 6024 120 21
|
||||
DS -5512 -5984 -4685 -5984 120 21
|
||||
DS -5512 4685 -5512 6024 120 21
|
||||
DS 5511 6025 5511 4686 120 21
|
||||
DS 5511 -2637 5511 3584 120 21
|
||||
DS 5511 -5983 5511 -3779 120 21
|
||||
DS 4133 -5511 3779 -5511 120 21
|
||||
DS -4686 -5511 -4529 -5511 120 21
|
||||
DS -5512 2521 -5512 2796 120 21
|
||||
DS -5512 -983 -5512 1773 120 21
|
||||
DS -5512 -2637 -5512 -1731 120 21
|
||||
DS -5512 -5983 -5512 -3779 120 21
|
||||
DS -4686 -5983 -4686 -5511 120 21
|
||||
DS 4133 -5511 4133 -5983 120 21
|
||||
$PAD
|
||||
Sh "~" C 512 512 0 0 0
|
||||
Dr 512 0 0
|
||||
At STD N 00E0FFFF
|
||||
Ne 0 ""
|
||||
Po -4686 -4999
|
||||
$EndPAD
|
||||
$PAD
|
||||
Sh "~" C 512 512 0 0 0
|
||||
Dr 512 0 0
|
||||
At STD N 00E0FFFF
|
||||
Ne 0 ""
|
||||
Po 4133 -4999
|
||||
$EndPAD
|
||||
$PAD
|
||||
Sh "1" R 433 787 0 0 0
|
||||
Dr 0 0 0
|
||||
At SMD N 00888000
|
||||
Ne 0 ""
|
||||
Po 2391 -5865
|
||||
$EndPAD
|
||||
$PAD
|
||||
Sh "2" R 433 787 0 0 0
|
||||
Dr 0 0 0
|
||||
At SMD N 00888000
|
||||
Ne 0 ""
|
||||
Po 1407 -5865
|
||||
$EndPAD
|
||||
$PAD
|
||||
Sh "3" R 433 787 0 0 0
|
||||
Dr 0 0 0
|
||||
At SMD N 00888000
|
||||
Ne 0 ""
|
||||
Po 422 -5865
|
||||
$EndPAD
|
||||
$PAD
|
||||
Sh "4" R 433 787 0 0 0
|
||||
Dr 0 0 0
|
||||
At SMD N 00888000
|
||||
Ne 0 ""
|
||||
Po -562 -5865
|
||||
$EndPAD
|
||||
$PAD
|
||||
Sh "5" R 433 787 0 0 0
|
||||
Dr 0 0 0
|
||||
At SMD N 00888000
|
||||
Ne 0 ""
|
||||
Po -1546 -5865
|
||||
$EndPAD
|
||||
$PAD
|
||||
Sh "6" R 433 787 0 0 0
|
||||
Dr 0 0 0
|
||||
At SMD N 00888000
|
||||
Ne 0 ""
|
||||
Po -2530 -5865
|
||||
$EndPAD
|
||||
$PAD
|
||||
Sh "7" R 433 787 0 0 0
|
||||
Dr 0 0 0
|
||||
At SMD N 00888000
|
||||
Ne 0 ""
|
||||
Po -3485 -5865
|
||||
$EndPAD
|
||||
$PAD
|
||||
Sh "8" R 433 787 0 0 0
|
||||
Dr 0 0 0
|
||||
At SMD N 00888000
|
||||
Ne 0 ""
|
||||
Po -4155 -5865
|
||||
$EndPAD
|
||||
$PAD
|
||||
Sh "9" R 433 787 0 0 0
|
||||
Dr 0 0 0
|
||||
At SMD N 00888000
|
||||
Ne 0 ""
|
||||
Po 3375 -5865
|
||||
$EndPAD
|
||||
$PAD
|
||||
Sh "GND1" R 787 787 0 0 0
|
||||
Dr 0 0 0
|
||||
At SMD N 00888000
|
||||
Ne 0 ""
|
||||
Po 5708 -3208
|
||||
$EndPAD
|
||||
$PAD
|
||||
Sh "GND1" R 787 787 0 0 0
|
||||
Dr 0 0 0
|
||||
At SMD N 00888000
|
||||
Ne 0 ""
|
||||
Po 5708 4135
|
||||
$EndPAD
|
||||
$PAD
|
||||
Sh "GND1" R 787 787 0 0 0
|
||||
Dr 0 0 0
|
||||
At SMD N 00888000
|
||||
Ne 0 ""
|
||||
Po -5710 -3208
|
||||
$EndPAD
|
||||
$PAD
|
||||
Sh "GND1" R 787 787 0 0 0
|
||||
Dr 0 0 0
|
||||
At SMD N 00888000
|
||||
Ne 0 ""
|
||||
Po -5710 4135
|
||||
$EndPAD
|
||||
$PAD
|
||||
Sh "DT" R 787 394 0 0 0
|
||||
Dr 0 0 0
|
||||
At SMD N 00888000
|
||||
Ne 0 ""
|
||||
Po -5552 -1377
|
||||
$EndPAD
|
||||
$PAD
|
||||
Sh "WP" R 787 394 0 0 0
|
||||
Dr 0 0 0
|
||||
At SMD N 00888000
|
||||
Ne 0 ""
|
||||
Po -5552 2147
|
||||
$EndPAD
|
||||
$PAD
|
||||
Sh "GND2" R 787 394 0 0 0
|
||||
Dr 0 0 0
|
||||
At SMD N 00888000
|
||||
Ne 0 ""
|
||||
Po -5552 3170
|
||||
$EndPAD
|
||||
$EndMODULE HRS-DM1AA
|
||||
$EndLIBRARY
|
||||
277
pcb/kicad/libs/sdcard.mod
Normal file
277
pcb/kicad/libs/sdcard.mod
Normal file
@ -0,0 +1,277 @@
|
||||
PCBNEW-LibModule-V1 Tue 27 Dec 2011 01:25:51 AM CET
|
||||
# encoding utf-8
|
||||
$INDEX
|
||||
HRS-DM1AA
|
||||
SD-RSMT-2-MQ-WF
|
||||
$EndINDEX
|
||||
$MODULE SD-RSMT-2-MQ-WF
|
||||
Po 0 0 0 15 4C4D74E3 00000000 ~~
|
||||
Li SD-RSMT-2-MQ-WF
|
||||
Sc 00000000
|
||||
AR /4B6ED75B/4BAA6A9C
|
||||
Op 0 0 0
|
||||
T0 4900 -450 300 300 0 60 N V 21 N"J2"
|
||||
T1 0 6000 300 300 0 60 N V 21 N"SD_CARD"
|
||||
DS -5197 39 5827 39 70 21
|
||||
DS 5827 9803 5827 39 70 21
|
||||
DS -5197 12047 5827 12047 70 21
|
||||
DS 5827 12047 5827 11260 70 21
|
||||
DS -5197 11260 -5197 12047 70 21
|
||||
DS -5197 39 -5197 9803 70 21
|
||||
$PAD
|
||||
Sh "GND2" R 787 1181 0 0 0
|
||||
Dr 0 0 0
|
||||
At SMD N 00888000
|
||||
Ne 0 ""
|
||||
Po 6228 10531
|
||||
$EndPAD
|
||||
$PAD
|
||||
Sh "GND1" R 787 1181 0 0 0
|
||||
Dr 0 0 0
|
||||
At SMD N 00888000
|
||||
Ne 0 ""
|
||||
Po -5622 10531
|
||||
$EndPAD
|
||||
$PAD
|
||||
Sh "3" R 394 591 0 0 0
|
||||
Dr 0 0 0
|
||||
At SMD N 00888000
|
||||
Ne 0 ""
|
||||
Po 740 -394
|
||||
$EndPAD
|
||||
$PAD
|
||||
Sh "2" R 394 591 0 0 0
|
||||
Dr 0 0 0
|
||||
At SMD N 00888000
|
||||
Ne 0 ""
|
||||
Po 1724 -394
|
||||
$EndPAD
|
||||
$PAD
|
||||
Sh "1" R 394 591 0 0 0
|
||||
Dr 0 0 0
|
||||
At SMD N 00888000
|
||||
Ne 0 ""
|
||||
Po 2709 -394
|
||||
$EndPAD
|
||||
$PAD
|
||||
Sh "9" R 394 591 0 0 0
|
||||
Dr 0 0 0
|
||||
At SMD N 00888000
|
||||
Ne 0 ""
|
||||
Po 3693 -394
|
||||
$EndPAD
|
||||
$PAD
|
||||
Sh "DT" R 276 591 0 0 0
|
||||
Dr 0 0 0
|
||||
At SMD N 00888000
|
||||
Ne 0 ""
|
||||
Po -4350 -394
|
||||
$EndPAD
|
||||
$PAD
|
||||
Sh "8" R 394 591 0 0 0
|
||||
Dr 0 0 0
|
||||
At SMD N 00888000
|
||||
Ne 0 ""
|
||||
Po -3839 -394
|
||||
$EndPAD
|
||||
$PAD
|
||||
Sh "7" R 394 591 0 0 0
|
||||
Dr 0 0 0
|
||||
At SMD N 00888000
|
||||
Ne 0 ""
|
||||
Po -3169 -394
|
||||
$EndPAD
|
||||
$PAD
|
||||
Sh "5" R 394 591 0 0 0
|
||||
Dr 0 0 0
|
||||
At SMD N 00888000
|
||||
Ne 0 ""
|
||||
Po -1228 -394
|
||||
$EndPAD
|
||||
$PAD
|
||||
Sh "6" R 394 591 0 0 0
|
||||
Dr 0 0 0
|
||||
At SMD N 00888000
|
||||
Ne 0 ""
|
||||
Po -2213 -394
|
||||
$EndPAD
|
||||
$PAD
|
||||
Sh "4" R 394 591 0 0 0
|
||||
Dr 0 0 0
|
||||
At SMD N 00888000
|
||||
Ne 0 ""
|
||||
Po -244 -394
|
||||
$EndPAD
|
||||
$PAD
|
||||
Sh "WP" R 276 591 0 0 0
|
||||
Dr 0 0 0
|
||||
At SMD N 00888000
|
||||
Ne 0 ""
|
||||
Po -4823 -394
|
||||
$EndPAD
|
||||
$PAD
|
||||
Sh "" C 433 433 0 0 0
|
||||
Dr 433 0 0
|
||||
At STD N 00C0FFFF
|
||||
Ne 0 ""
|
||||
Po -4528 709
|
||||
$EndPAD
|
||||
$PAD
|
||||
Sh "" C 630 630 0 0 0
|
||||
Dr 630 0 0
|
||||
At STD N 00C0FFFF
|
||||
Ne 0 ""
|
||||
Po 3740 709
|
||||
$EndPAD
|
||||
$EndMODULE SD-RSMT-2-MQ-WF
|
||||
$MODULE HRS-DM1AA
|
||||
Po 0 0 0 15 4EF9108C 00000000 ~~
|
||||
Li HRS-DM1AA
|
||||
Sc 00000000
|
||||
AR HRS-DM1AA
|
||||
Op 0 0 0
|
||||
T0 0 0 300 300 0 60 N V 21 N "HRS-DM1AA"
|
||||
T1 0 0 300 300 0 60 N V 21 N "VAL**"
|
||||
DS 4134 -5984 5512 -5984 120 21
|
||||
DS 5512 6024 -5512 6024 120 21
|
||||
DS -5512 -5984 -4685 -5984 120 21
|
||||
DS -5512 4685 -5512 6024 120 21
|
||||
DS 5511 6025 5511 4686 120 21
|
||||
DS 5511 -2637 5511 3584 120 21
|
||||
DS 5511 -5983 5511 -3779 120 21
|
||||
DS 4133 -5511 3779 -5511 120 21
|
||||
DS -4686 -5511 -4529 -5511 120 21
|
||||
DS -5512 2521 -5512 2796 120 21
|
||||
DS -5512 -983 -5512 1773 120 21
|
||||
DS -5512 -2637 -5512 -1731 120 21
|
||||
DS -5512 -5983 -5512 -3779 120 21
|
||||
DS -4686 -5983 -4686 -5511 120 21
|
||||
DS 4133 -5511 4133 -5983 120 21
|
||||
$PAD
|
||||
Sh "~" C 510 510 0 0 0
|
||||
Dr 512 0 0
|
||||
At STD N 0000FFFF
|
||||
Ne 0 ""
|
||||
Po -4686 -4999
|
||||
$EndPAD
|
||||
$PAD
|
||||
Sh "~" C 510 510 0 0 0
|
||||
Dr 512 0 0
|
||||
At STD N 0000FFFF
|
||||
Ne 0 ""
|
||||
Po 4133 -4999
|
||||
$EndPAD
|
||||
$PAD
|
||||
Sh "1" R 433 787 0 0 0
|
||||
Dr 0 0 0
|
||||
At SMD N 00888000
|
||||
Ne 0 ""
|
||||
Po 2391 -5865
|
||||
$EndPAD
|
||||
$PAD
|
||||
Sh "2" R 433 787 0 0 0
|
||||
Dr 0 0 0
|
||||
At SMD N 00888000
|
||||
Ne 0 ""
|
||||
Po 1407 -5865
|
||||
$EndPAD
|
||||
$PAD
|
||||
Sh "3" R 433 787 0 0 0
|
||||
Dr 0 0 0
|
||||
At SMD N 00888000
|
||||
Ne 0 ""
|
||||
Po 422 -5865
|
||||
$EndPAD
|
||||
$PAD
|
||||
Sh "4" R 433 787 0 0 0
|
||||
Dr 0 0 0
|
||||
At SMD N 00888000
|
||||
Ne 0 ""
|
||||
Po -562 -5865
|
||||
$EndPAD
|
||||
$PAD
|
||||
Sh "5" R 433 787 0 0 0
|
||||
Dr 0 0 0
|
||||
At SMD N 00888000
|
||||
Ne 0 ""
|
||||
Po -1546 -5865
|
||||
$EndPAD
|
||||
$PAD
|
||||
Sh "6" R 433 787 0 0 0
|
||||
Dr 0 0 0
|
||||
At SMD N 00888000
|
||||
Ne 0 ""
|
||||
Po -2530 -5865
|
||||
$EndPAD
|
||||
$PAD
|
||||
Sh "7" R 433 787 0 0 0
|
||||
Dr 0 0 0
|
||||
At SMD N 00888000
|
||||
Ne 0 ""
|
||||
Po -3485 -5865
|
||||
$EndPAD
|
||||
$PAD
|
||||
Sh "8" R 433 787 0 0 0
|
||||
Dr 0 0 0
|
||||
At SMD N 00888000
|
||||
Ne 0 ""
|
||||
Po -4155 -5865
|
||||
$EndPAD
|
||||
$PAD
|
||||
Sh "9" R 433 787 0 0 0
|
||||
Dr 0 0 0
|
||||
At SMD N 00888000
|
||||
Ne 0 ""
|
||||
Po 3375 -5865
|
||||
$EndPAD
|
||||
$PAD
|
||||
Sh "GND1" R 787 787 0 0 0
|
||||
Dr 0 0 0
|
||||
At SMD N 00888000
|
||||
Ne 0 ""
|
||||
Po 5708 -3208
|
||||
$EndPAD
|
||||
$PAD
|
||||
Sh "GND1" R 787 787 0 0 0
|
||||
Dr 0 0 0
|
||||
At SMD N 00888000
|
||||
Ne 0 ""
|
||||
Po 5708 4135
|
||||
$EndPAD
|
||||
$PAD
|
||||
Sh "GND1" R 787 787 0 0 0
|
||||
Dr 0 0 0
|
||||
At SMD N 00888000
|
||||
Ne 0 ""
|
||||
Po -5710 -3208
|
||||
$EndPAD
|
||||
$PAD
|
||||
Sh "GND1" R 787 787 0 0 0
|
||||
Dr 0 0 0
|
||||
At SMD N 00888000
|
||||
Ne 0 ""
|
||||
Po -5710 4135
|
||||
$EndPAD
|
||||
$PAD
|
||||
Sh "DT" R 787 394 0 0 0
|
||||
Dr 0 0 0
|
||||
At SMD N 00888000
|
||||
Ne 0 ""
|
||||
Po -5552 -1377
|
||||
$EndPAD
|
||||
$PAD
|
||||
Sh "WP" R 787 394 0 0 0
|
||||
Dr 0 0 0
|
||||
At SMD N 00888000
|
||||
Ne 0 ""
|
||||
Po -5552 2147
|
||||
$EndPAD
|
||||
$PAD
|
||||
Sh "GND2" R 787 394 0 0 0
|
||||
Dr 0 0 0
|
||||
At SMD N 00888000
|
||||
Ne 0 ""
|
||||
Po -5552 3170
|
||||
$EndPAD
|
||||
$EndMODULE HRS-DM1AA
|
||||
$EndLIBRARY
|
||||
23
snes/Makefile
Normal file
23
snes/Makefile
Normal file
@ -0,0 +1,23 @@
|
||||
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
|
||||
|
||||
smc: menu.bin
|
||||
cat menu.bin sd2snes.rom > menu.smc
|
||||
|
||||
map: menu.bin
|
||||
utils/mkmap.sh $(OBJS)
|
||||
|
||||
menu.bin: $(OBJS)
|
||||
sneslink -fsmc -o $@ $^ 2>&1 | tee link.log
|
||||
|
||||
# Generic rule to create .o65 out from .a65
|
||||
%.o65: %.a65
|
||||
snescom -J -Wall -o $@ $< 2>&1 | tee $@.log
|
||||
|
||||
# Generic rule to create .ips out from .a65
|
||||
%.ips: %.a65
|
||||
snescom -I -J -Wall -o $@ $< 2>&1 | tee $@.log
|
||||
|
||||
clean:
|
||||
rm -f *.ips *.o65 *~ menu.bin
|
||||
164
snes/const.a65
Normal file
164
snes/const.a65
Normal file
@ -0,0 +1,164 @@
|
||||
version .byt " v0.1",0
|
||||
zero .word 0
|
||||
bg2tile .byt $20
|
||||
hdma_pal_src .byt 44
|
||||
.byt $60, $2d
|
||||
.byt 14
|
||||
.byt $00, $00
|
||||
.byt 2
|
||||
.byt $60, $2d
|
||||
.byt 11
|
||||
.byt $00, $00
|
||||
.byt 11
|
||||
.byt $20, $04
|
||||
.byt 11
|
||||
.byt $40, $08
|
||||
.byt 11
|
||||
.byt $60, $0c
|
||||
.byt 11
|
||||
.byt $80, $10
|
||||
.byt 11
|
||||
.byt $a0, $14
|
||||
.byt 11
|
||||
.byt $c0, $18
|
||||
.byt 11
|
||||
.byt $e0, $1c
|
||||
.byt 11
|
||||
.byt $00, $21
|
||||
.byt 11
|
||||
.byt $20, $25
|
||||
.byt 11
|
||||
.byt $40, $29
|
||||
.byt 31
|
||||
.byt $60, $2d
|
||||
.byt 2
|
||||
.byt $20, $04
|
||||
.byt 1
|
||||
.byt $60, $2d
|
||||
.byt $00
|
||||
|
||||
hdma_cg_addr_src
|
||||
.byt $f0
|
||||
.byt $00, $00, $00, $00, $00, $00, $00, $00
|
||||
.byt $00, $00, $00, $00, $00, $00, $00, $00
|
||||
.byt $00, $00, $00, $00, $00, $00, $00, $00
|
||||
.byt $00, $00, $00, $00, $00, $00, $00, $00
|
||||
.byt $00, $00, $00, $00, $00, $00, $00, $00
|
||||
.byt $00, $00, $00, $00, $00, $00, $00, $00
|
||||
.byt $00, $00, $00, $00, $00, $00, $00, $00
|
||||
.byt $00, $00, $00, $00, $00, $00, $00, $00
|
||||
.byt $00, $00, $00, $00, $00, $00, $00, $00
|
||||
.byt $00, $00, $00, $00, $00, $00, $00, $00
|
||||
.byt $00, $00, $00, $00, $00, $00, $00, $00
|
||||
.byt $00, $00, $00, $00, $00, $00, $00, $00
|
||||
.byt $00, $00, $00, $00, $00, $00, $00, $00
|
||||
.byt $00, $00, $00, $00, $00, $00, $00, $00
|
||||
.byt $f0
|
||||
.byt $00, $00, $00, $00, $00, $00, $00, $00
|
||||
.byt $00, $00, $00, $00, $00, $00, $00, $00
|
||||
.byt $00, $00, $00, $00, $00, $00, $00, $00
|
||||
.byt $00, $00, $00, $00, $00, $00, $00, $00
|
||||
.byt $00, $00, $00, $00, $00, $00, $00, $00
|
||||
.byt $00, $00, $00, $00, $00, $00, $00, $00
|
||||
.byt $00, $00, $00, $00, $00, $00, $00, $00
|
||||
.byt $00, $00, $00, $00, $00, $00, $00, $00
|
||||
.byt $00, $00, $00, $00, $00, $00, $00, $00
|
||||
.byt $00, $00, $00, $00, $00, $00, $00, $00
|
||||
.byt $00, $00, $00, $00, $00, $00, $00, $00
|
||||
.byt $00, $00, $00, $00, $00, $00, $00, $00
|
||||
.byt $00, $00, $00, $00, $00, $00, $00, $00
|
||||
.byt $00, $00, $00, $00, $00, $00, $00, $00
|
||||
.byt $00
|
||||
hdma_mode_src .byt 64, $03, $01, $05, $00
|
||||
hdma_scroll_src .byt 64
|
||||
.byt $00, $00, $ff, $0f
|
||||
.byt $01
|
||||
.byt $fc, $00, $05, $00
|
||||
.byt $00
|
||||
; colors:
|
||||
; upper border: + #547fff -> 10,15,31
|
||||
; selection bar:+ #5400ff -> 10,0,31
|
||||
; lower border: 1/2 #5400ff
|
||||
hdma_math_src .byt 1 ; these are filled in...
|
||||
.byt $00, $2a
|
||||
.byt 1 ; ...to move the color bar
|
||||
.byt $00, $9f
|
||||
.byt 1
|
||||
.byt $33, $4f
|
||||
.byt 8
|
||||
.byt $33, $40
|
||||
.byt 1
|
||||
.byt $73, $00
|
||||
.byt 1
|
||||
.byt $00, $e0
|
||||
.byt 0
|
||||
|
||||
oam_data_l .byt 75, 56, 31, $0e
|
||||
.byt 83, 56, 1, $0e
|
||||
.byt 91, 56, 2, $0e
|
||||
.byt 99, 56, 3, $0e
|
||||
.byt 107, 56, 4, $0e
|
||||
.byt 115, 56, 5, $0e
|
||||
.byt 123, 56, 6, $0e
|
||||
.byt 131, 56, 7, $0e
|
||||
.byt 75, 64, 8, $0e
|
||||
.byt 83, 64, 9, $0e
|
||||
.byt 91, 64, 10, $0e
|
||||
.byt 99, 64, 11, $0e
|
||||
.byt 107, 64, 12, $0e
|
||||
.byt 115, 64, 13, $0e
|
||||
.byt 123, 64, 14, $0e
|
||||
.byt 131, 64, 15, $0e
|
||||
.byt 75, 72, 16, $0e
|
||||
.byt 83, 72, 17, $0e
|
||||
.byt 91, 72, 18, $0e
|
||||
.byt 99, 72, 19, $0e
|
||||
.byt 75, 80, 24, $0e
|
||||
.byt 83, 80, 25, $0e
|
||||
.byt 91, 80, 26, $0e
|
||||
oam_data_h .byt 0, 0, 0, 0, 0, 0, 0, 0
|
||||
|
||||
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
|
||||
.byt $00
|
||||
text_dirmark .byt " <dir>", 0
|
||||
window_nw .byt 20
|
||||
window_ne .byt 21
|
||||
window_sw .byt 22
|
||||
window_se .byt 23
|
||||
window_nh .byt 24
|
||||
window_sh .byt 25
|
||||
window_wv .byt 26
|
||||
window_ev .byt 27
|
||||
window_tl .byt 28
|
||||
window_tr .byt 29
|
||||
text_clkset .byt "Please set the clock.", 0
|
||||
text_buttonB .byt "Dpad: sel/chg, A: OK", 0
|
||||
time_win_x .byt 18
|
||||
time_win_y .byt 15
|
||||
time_win_w .byt 27
|
||||
time_win_h .byt 7
|
||||
main_win_x .byt 18
|
||||
main_win_y .byt 11
|
||||
main_win_w .byt 27
|
||||
main_win_h .byt 13
|
||||
text_mainmenu .byt "Main Menu", 0
|
||||
sysinfo_win_x .byt 10
|
||||
sysinfo_win_y .byt 9
|
||||
sysinfo_win_w .byt 43
|
||||
sysinfo_win_h .byt 17
|
||||
|
||||
text_mm_file .byt "File Browser", 0
|
||||
text_mm_last .byt "Run last game", 0
|
||||
text_mm_time .byt "Set Clock", 0
|
||||
text_mm_scic .byt "Enable SuperCIC", 0
|
||||
text_mm_vmode_menu .byt "Menu video mode", 0
|
||||
text_mm_vmode_game .byt "Game video mode", 0
|
||||
text_mm_sysinfo .byt "System Information", 0
|
||||
text_statusbar_keys .byt "A:Select B:Back X:Menu", 0
|
||||
175
snes/data.a65
Normal file
175
snes/data.a65
Normal file
@ -0,0 +1,175 @@
|
||||
*=$7E0000
|
||||
.data
|
||||
;don't anger the stack!
|
||||
dirptr_addr .word 0
|
||||
dirptr_bank .word 0
|
||||
dirstart_addr .word 0
|
||||
dirstart_bank .word 0
|
||||
dirend_addr .word 0
|
||||
dirend_bank .word 0
|
||||
dirend_idx .word 0
|
||||
dirptr_idx .word 0
|
||||
dirent_addr .word 0
|
||||
dirent_bank .word 0
|
||||
dirent_type .byt 0
|
||||
dirend_onscreen .byt 0
|
||||
dirlog_idx .byt 0,0,0 ; long ptr
|
||||
|
||||
;----------parameters for text output----------
|
||||
print_x .byt 0 ;x coordinate
|
||||
.byt 0
|
||||
print_y .byt 0 ;y coordinate
|
||||
.byt 0
|
||||
print_src .word 0 ;source data address
|
||||
print_bank .byt 0 ;source data bank
|
||||
print_pal .word 0 ;palette number for text output
|
||||
print_temp .word 0 ;work variable
|
||||
print_count .byt 0 ;how many characters may be printed?
|
||||
print_count_tmp .byt 0 ;work variable
|
||||
print_done .word 0 ;how many characters were printed?
|
||||
;----------parameters for dma----------
|
||||
dma_a_bank .byt 0
|
||||
dma_a_addr .word 0
|
||||
dma_b_reg .byt 0
|
||||
dma_len .word 0
|
||||
dma_mode .byt 0
|
||||
|
||||
;----------state information----------
|
||||
isr_done .byt 0 ; isr done flag
|
||||
bar_xl .byt 0 ; logical x position of select bar
|
||||
bar_yl .byt 0 ; logical y position of select bar
|
||||
bar_x .byt 0 ; pixel x position of select bar
|
||||
bar_y .byt 0 ; pixel y position of select bar
|
||||
bar_w .byt 0 ; bar width
|
||||
bar_wl .byt 0 ; bar width
|
||||
menu_state .byt 0 ; menu state (0=file select)
|
||||
menu_dirty .byt 0 ; menu dirty (e.g. after state change or when redraw is needed)
|
||||
menu_sel .word 0 ; selected item #
|
||||
cursor_x .byt 0 ; current cursor position (x)
|
||||
cursor_y .byt 0 ; current cursor position (y)
|
||||
fd_addr .word 0 ; address of current "file descriptor"
|
||||
fd_bank .byt 0 ; bank of current "file descriptor"
|
||||
fd_fnoff .word 0 ; offset of filename in file descriptor
|
||||
pad1mem .word 0
|
||||
pad1trig .word 0
|
||||
pad1delay .word 0
|
||||
window_x .byt 0
|
||||
window_y .byt 0
|
||||
window_w .byt 0
|
||||
window_h .byt 0
|
||||
window_tmp .word 0
|
||||
window_tbank .byt 0
|
||||
window_taddr .word 0
|
||||
stringbuf .word 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
.word 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
.word 0
|
||||
;----------dialog specific data
|
||||
time_s1 .byt 0
|
||||
time_s10 .byt 0
|
||||
time_m1 .byt 0
|
||||
time_m10 .byt 0
|
||||
time_h1 .byt 0
|
||||
time_h10 .byt 0
|
||||
time_d1 .byt 0
|
||||
time_d10 .byt 0
|
||||
time_mon .byt 0
|
||||
time_y1 .byt 0
|
||||
time_y10 .byt 0
|
||||
time_y100 .byt 0
|
||||
time_sel .byt 0
|
||||
time_exit .byt 0
|
||||
time_cancel .byt 0
|
||||
time_ptr .byt 0
|
||||
time_tmp .byt 0
|
||||
;--
|
||||
mm_tmp .byt 0
|
||||
mm_sel .byt 0
|
||||
mm_refresh .byt 0
|
||||
;----------menu layout/system constants (224/448)
|
||||
vidmode .byt 0 ; 0=224, 1=448
|
||||
listdisp .word 0 ; number of displayable list entries
|
||||
textdmasize .word 0 ; number of bytes to copy each frame
|
||||
barstep .byt 0 ; step size for bar
|
||||
|
||||
;-misc
|
||||
testvar .word 0,0,0,0
|
||||
;----------hdma tables in WRAM (must be stable when cartridge is cut off)
|
||||
hdma_pal .byt 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
.byt 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
.byt 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
.byt 0,0,0,0
|
||||
hdma_cg_addr .byt 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
|
||||
.byt 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
|
||||
.byt 0
|
||||
hdma_mode .byt 0,0,0,0,0
|
||||
hdma_scroll .byt 0
|
||||
.byt 0,0,0,0
|
||||
.byt 0
|
||||
.byt 0,0,0,0
|
||||
.byt 0
|
||||
hdma_math .byt 0
|
||||
.byt 0,0
|
||||
.byt 0
|
||||
.byt 0,0
|
||||
hdma_math_upperborder
|
||||
.byt 0
|
||||
.byt 0,0
|
||||
hdma_math_selection
|
||||
.byt 0
|
||||
.byt 0,0
|
||||
hdma_math_lowerborder
|
||||
.byt 0
|
||||
.byt 0,0
|
||||
.byt 0
|
||||
.byt 0,0
|
||||
.byt 0
|
||||
.byt 0,0
|
||||
.byt 0
|
||||
|
||||
hdma_window .byt 0
|
||||
.byt 0,0
|
||||
.byt 0
|
||||
.byt 0,0
|
||||
.byt 0
|
||||
.byt 0,0
|
||||
.byt 0
|
||||
.byt 0,0
|
||||
.byt 0
|
||||
.byt 0,0
|
||||
.byt 0
|
||||
.byt 0,0
|
||||
.byt 0
|
||||
.byt 0,0
|
||||
.byt 0
|
||||
.byt 0,0
|
||||
.byt 0
|
||||
; dirlog format:
|
||||
; dirstart_addr 2
|
||||
; dirstart_bank 1
|
||||
; dirptr_addr 2
|
||||
; dirptr_bank 1
|
||||
; menu_sel 2
|
||||
; total 8 bytes
|
||||
dirlog .word 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
.word 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
.word 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
.word 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
.word 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
.word 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
|
||||
infloop .byt 0,0 ; to be filled w/ 80 FE
|
||||
wram_fadeloop .byt 0
|
||||
89
snes/header.a65
Normal file
89
snes/header.a65
Normal file
@ -0,0 +1,89 @@
|
||||
; This file is a modified version of the header.a65 file from:
|
||||
; snescom-asm demo - a demo of how to build a SNES program.
|
||||
; See http://bisqwit.iki.fi/source/snescom.html for details.
|
||||
|
||||
; fill whole area beforehand so the linker does not create multiple
|
||||
; objects from it. (necessary for map creation)
|
||||
|
||||
*= $C0FF00
|
||||
.word 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
.word 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
.word 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
.word 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
|
||||
; Begin assembling to this address.
|
||||
*= $C0FF00
|
||||
|
||||
RESET:
|
||||
sei
|
||||
clc
|
||||
xce
|
||||
rep #$20 : .al
|
||||
lda #$1fff
|
||||
tcs
|
||||
jmp @GAME_MAIN
|
||||
|
||||
NMI_16bit:
|
||||
php
|
||||
rep #$30 : .al : .xl
|
||||
pha: phx: phy: phd: phb
|
||||
jsl @NMI_ROUTINE
|
||||
rep #$30 : .al : .xl
|
||||
int_exit:
|
||||
plb: pld: ply: plx: pla
|
||||
plp
|
||||
rti
|
||||
|
||||
IRQ_16bit:
|
||||
php
|
||||
rep #$30 : .al : .xl
|
||||
pha: phx: phy: phd: phb
|
||||
jsl @IRQ_ROUTINE
|
||||
rep #$30 : .al : .xl
|
||||
bra int_exit
|
||||
|
||||
;error vectors
|
||||
ABT_8bit: ABT_16bit:
|
||||
BRK_8bit: BRK_16bit:
|
||||
COP_8bit: COP_16bit:
|
||||
IRQ_8bit:
|
||||
NMI_8bit:
|
||||
- wai: lda $ABCDEF : bra -
|
||||
|
||||
*= $C0FFB0
|
||||
; Zero the area from $FFB0 - $FFFF
|
||||
; to ensure that the linker won't get clever
|
||||
; and fill it with small pieces of code.
|
||||
.word 0,0,0,0, 0,0,0,0
|
||||
.word 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0
|
||||
.word 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0
|
||||
|
||||
*= $C0FFB0
|
||||
|
||||
.byt "MR" ;2 bytes - company id
|
||||
.byt "SNSD" ;4 bytes - rom id
|
||||
|
||||
*= $C0FFC0
|
||||
.byt "SD2SNES MAIN MENU "
|
||||
;123456789012345678901; - max 21 chars
|
||||
|
||||
*= $C0FFD5 .byt $31 ;rom speed
|
||||
*= $C0FFD6 .byt $02 ;rom type
|
||||
*= $C0FFD7 .byt $06 ;rom size 64 kByte
|
||||
*= $C0FFD8 .byt $03 ;sram size 8 kBit
|
||||
*= $C0FFD9 .byt $09 ;rom region 4 = Finland
|
||||
*= $C0FFDA .byt $33 ;company id flag
|
||||
|
||||
*= $C0FFDC .word 0,0 ;checksums
|
||||
|
||||
*= $C0FFE4 .word COP_16bit
|
||||
*= $C0FFE6 .word BRK_16bit
|
||||
*= $C0FFE8 .word ABT_16bit
|
||||
*= $C0FFEA .word NMI_16bit
|
||||
*= $C0FFEE .word IRQ_16bit
|
||||
*= $C0FFF4 .word COP_8bit
|
||||
*= $C0FFF8 .word ABT_8bit
|
||||
*= $C0FFFA .word NMI_8bit
|
||||
*= $C0FFFC .word RESET
|
||||
*= $C0FFFE .word BRK_8bit
|
||||
*= $C0FFFE .word IRQ_8bit
|
||||
196
snes/mainmenu.a65
Normal file
196
snes/mainmenu.a65
Normal file
@ -0,0 +1,196 @@
|
||||
#include "memmap.i65"
|
||||
;number of menu entries
|
||||
main_entries .byt 2
|
||||
;menu entry data
|
||||
main_enttab ;Set Clock
|
||||
.word !text_mm_time
|
||||
.byt ^text_mm_time
|
||||
.word !time_init-1
|
||||
.byt ^time_init
|
||||
.byt 1, 0
|
||||
;System Information
|
||||
.word !text_mm_sysinfo
|
||||
.byt ^text_mm_sysinfo
|
||||
.word !show_sysinfo-1
|
||||
.byt ^show_sysinfo
|
||||
;SuperCIC
|
||||
.word !text_mm_scic
|
||||
.byt ^text_mm_scic
|
||||
.word !time_init
|
||||
.byt ^time_init
|
||||
.byt 1, 0
|
||||
;Menu vmode
|
||||
.word !text_mm_vmode_menu
|
||||
.byt ^text_mm_vmode_menu
|
||||
.word !time_init
|
||||
.byt ^time_init
|
||||
.byt 1, 0
|
||||
;Game vmode
|
||||
.word !text_mm_vmode_game
|
||||
.byt ^text_mm_vmode_game
|
||||
.word !time_init
|
||||
.byt ^time_init
|
||||
.byt 1, 0
|
||||
|
||||
mainmenu:
|
||||
php
|
||||
sep #$20 : .as
|
||||
stz mm_sel
|
||||
mm_redraw
|
||||
stz mm_tmp
|
||||
jsr backup_screen
|
||||
lda #^text_mainmenu
|
||||
sta window_tbank
|
||||
ldx #!text_mainmenu
|
||||
stx window_taddr
|
||||
lda @main_win_x
|
||||
sta window_x
|
||||
lda @main_win_y
|
||||
sta window_y
|
||||
lda @main_win_w
|
||||
sta window_w
|
||||
lda @main_win_h
|
||||
sta window_h
|
||||
jsr draw_window
|
||||
jsr mm_do_refresh
|
||||
stz print_pal
|
||||
ldx #!main_enttab
|
||||
mm_entloop
|
||||
lda #^main_enttab
|
||||
phb
|
||||
pha
|
||||
plb
|
||||
lda !0, x
|
||||
sta @print_src
|
||||
lda !1, x
|
||||
sta @print_src+1
|
||||
lda !2, x
|
||||
sta @print_bank
|
||||
lda @mm_tmp
|
||||
asl
|
||||
clc
|
||||
adc @main_win_y
|
||||
inc
|
||||
inc
|
||||
sta @print_y
|
||||
lda @main_win_x
|
||||
inc
|
||||
inc
|
||||
sta @print_x
|
||||
plb
|
||||
phx
|
||||
jsr hiprint
|
||||
plx
|
||||
inx
|
||||
inx
|
||||
inx
|
||||
inx
|
||||
inx
|
||||
inx
|
||||
inx
|
||||
inx
|
||||
inc mm_tmp
|
||||
lda mm_tmp
|
||||
cmp @main_entries
|
||||
bne mm_entloop
|
||||
stz mm_tmp
|
||||
stz mm_refresh
|
||||
mm_menuloop
|
||||
lda isr_done
|
||||
lsr
|
||||
bcc mm_menuloop
|
||||
jsr printtime
|
||||
stz isr_done
|
||||
lda mm_refresh
|
||||
beq +
|
||||
jsr mm_do_refresh
|
||||
stz mm_refresh
|
||||
+
|
||||
jsr read_pad
|
||||
lda #$80
|
||||
and pad1trig
|
||||
bne mmkey_a
|
||||
lda #$04
|
||||
and pad1trig+1
|
||||
bne mmkey_down
|
||||
lda #$08
|
||||
and pad1trig+1
|
||||
bne mmkey_up
|
||||
lda #$80
|
||||
and pad1trig+1
|
||||
bne mmkey_b
|
||||
bra mm_menuloop
|
||||
mmkey_b
|
||||
jsr restore_screen
|
||||
plp
|
||||
rts
|
||||
|
||||
mmkey_a
|
||||
jsr mmkey_a_2
|
||||
jmp mm_redraw
|
||||
|
||||
mmkey_down
|
||||
jsr mmkey_down_2
|
||||
bra mm_menuloop
|
||||
|
||||
mmkey_up
|
||||
jsr mmkey_up_2
|
||||
bra mm_menuloop
|
||||
|
||||
mmkey_down_2
|
||||
lda @main_entries
|
||||
dec
|
||||
cmp mm_sel
|
||||
beq +
|
||||
inc mm_sel
|
||||
inc mm_refresh
|
||||
+
|
||||
rts
|
||||
|
||||
mmkey_up_2
|
||||
lda mm_sel
|
||||
beq +
|
||||
dec mm_sel
|
||||
dec bar_yl
|
||||
dec bar_yl
|
||||
+
|
||||
rts
|
||||
|
||||
mmkey_a_2
|
||||
jsr restore_screen
|
||||
phk ; push return bank for subroutine
|
||||
per mmkey_a_2_return-1 ; push return addr for subroutine
|
||||
xba
|
||||
lda #$00
|
||||
xba
|
||||
lda mm_sel
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
tax
|
||||
lda @main_enttab+5, x
|
||||
pha ; push subroutine bank
|
||||
rep #$20 : .al
|
||||
lda @main_enttab+3, x
|
||||
pha ; push subroutine addr
|
||||
sep #$20 : .as
|
||||
rtl ; jump to subroutine
|
||||
mmkey_a_2_return
|
||||
rts
|
||||
|
||||
mm_do_refresh
|
||||
lda mm_sel
|
||||
asl
|
||||
clc
|
||||
adc @main_win_y
|
||||
inc
|
||||
sta bar_yl
|
||||
lda @main_win_x
|
||||
inc
|
||||
inc
|
||||
sta bar_xl
|
||||
lda @main_win_w
|
||||
sec
|
||||
sbc #$04
|
||||
sta bar_wl
|
||||
rts
|
||||
27
snes/memmap.i65
Normal file
27
snes/memmap.i65
Normal file
@ -0,0 +1,27 @@
|
||||
#if 0 /* #if0'd because it's #included, and those don't get parsed properly by snescom */
|
||||
; This file is part of the snescom-asm demo - a demo of how to build a SNES program.
|
||||
; See http://bisqwit.iki.fi/source/snescom.html for details.
|
||||
#endif
|
||||
|
||||
/* These must be defined as constants, because they're used
|
||||
* in calculation that is sent to PPU as parameters */
|
||||
|
||||
#define BG1_TILE_BASE $5800
|
||||
#define BG2_TILE_BASE $5000
|
||||
|
||||
#define OAM_TILE_BASE $6000
|
||||
|
||||
#define BG1_TILE_BUF $7FB000
|
||||
#define BG2_TILE_BUF $7FA000
|
||||
|
||||
#define BG1_TILE_BAK $7F9000
|
||||
#define BG2_TILE_BAK $7F8000
|
||||
|
||||
#define AVR_CMD $307000
|
||||
#define AVR_PARAM $307004
|
||||
#define RTC_STATUS $307100
|
||||
#define SYSINFO_BLK $307110
|
||||
|
||||
#define ROOT_DIR $C10000
|
||||
|
||||
#define CMD_SYSINFO $03
|
||||
725
snes/menu.a65
Normal file
725
snes/menu.a65
Normal file
@ -0,0 +1,725 @@
|
||||
#include "memmap.i65"
|
||||
#include "dma.i65"
|
||||
|
||||
menu_init:
|
||||
sep #$20 : .as
|
||||
rep #$10 : .xl
|
||||
lda #^ROOT_DIR
|
||||
ldx #!ROOT_DIR
|
||||
sta dirptr_bank
|
||||
stx dirptr_addr
|
||||
sta dirstart_bank
|
||||
stx dirstart_addr
|
||||
stz menu_state
|
||||
stz dirend_onscreen
|
||||
lda #$02
|
||||
sta cursor_x
|
||||
lda #$09
|
||||
sta cursor_y
|
||||
lda #$01
|
||||
sta bar_xl
|
||||
lda #$3e
|
||||
sta bar_wl
|
||||
ldx #$0000
|
||||
stx dirptr_idx
|
||||
stx menu_sel
|
||||
lda #$01
|
||||
sta menu_dirty
|
||||
rep #$20 : .al
|
||||
lda #!dirlog
|
||||
sta dirlog_idx
|
||||
sep #$20 : .as
|
||||
lda #^dirlog
|
||||
sta dirlog_idx+2
|
||||
rts
|
||||
|
||||
menuloop:
|
||||
menuloop_s1
|
||||
sep #$20 : .as
|
||||
rep #$10 : .xl
|
||||
lda isr_done
|
||||
lsr
|
||||
bcc menuloop_s1
|
||||
|
||||
stz isr_done
|
||||
jsr printtime
|
||||
jsr menu_updates ;update stuff, check keys etc
|
||||
lda menu_dirty ;is there ANY reason to redraw the menu?
|
||||
cmp #$01
|
||||
beq menuloop_redraw ;then do
|
||||
bra menuloop_s1
|
||||
menuloop_redraw
|
||||
stz menu_dirty
|
||||
jsr menu_statusbar
|
||||
jsr menu_redraw
|
||||
jsr menu_cleanup ;update phase 2
|
||||
bra menuloop_s1
|
||||
rts
|
||||
|
||||
menu_cleanup:
|
||||
sep #$20 : .as
|
||||
rep #$10 : .xl
|
||||
lda dirend_onscreen ;end of file list on screen?
|
||||
beq menu_cleanup_out ;
|
||||
lda dirend_idx
|
||||
lsr
|
||||
lsr
|
||||
pha
|
||||
menu_cleanup_loop ;pad rest of screen with empty lines
|
||||
cmp listdisp ;end of screen reached?
|
||||
beq + ;then leave
|
||||
pha
|
||||
clc
|
||||
adc #$09 ;first line in text area
|
||||
inc
|
||||
sta print_y
|
||||
stz print_x
|
||||
lda #^space64
|
||||
ldx #!space64
|
||||
sta print_bank
|
||||
stx print_src
|
||||
stz print_pal
|
||||
lda #64
|
||||
sta print_count
|
||||
jsr hiprint
|
||||
pla
|
||||
inc
|
||||
bra menu_cleanup_loop
|
||||
+
|
||||
pla
|
||||
cmp menu_sel
|
||||
beq menu_cleanup_out
|
||||
bpl menu_cleanup_out
|
||||
sta menu_sel
|
||||
menu_cleanup_out
|
||||
rts
|
||||
|
||||
|
||||
menu_updates:
|
||||
;update selection, scroll etc
|
||||
lda menu_sel
|
||||
asl
|
||||
asl
|
||||
sta dirptr_idx
|
||||
lda menu_sel
|
||||
clc
|
||||
adc #$08
|
||||
sta bar_yl
|
||||
lda #$3e
|
||||
sta bar_wl
|
||||
lda #$01
|
||||
sta bar_xl
|
||||
;get input
|
||||
jsr read_pad
|
||||
lda #$04
|
||||
and pad1trig+1
|
||||
bne key_down
|
||||
lda #$08
|
||||
and pad1trig+1
|
||||
bne key_up
|
||||
lda #$01
|
||||
and pad1trig+1
|
||||
bne key_right
|
||||
lda #$02
|
||||
and pad1trig+1
|
||||
bne key_left
|
||||
lda #$80
|
||||
and pad1trig+1
|
||||
bne key_b
|
||||
lda #$20
|
||||
and pad1trig+1
|
||||
bne key_select
|
||||
lda #$80
|
||||
and pad1trig
|
||||
bne key_a
|
||||
lda #$40
|
||||
and pad1trig
|
||||
bne key_x
|
||||
bra menuupd_out
|
||||
key_down
|
||||
jsr menu_key_down
|
||||
bra menuupd_out
|
||||
key_up
|
||||
jsr menu_key_up
|
||||
bra menuupd_out
|
||||
key_right
|
||||
jsr menu_key_right
|
||||
bra menuupd_out
|
||||
key_left
|
||||
jsr menu_key_left
|
||||
bra menuupd_out
|
||||
key_b
|
||||
jsr menu_key_b
|
||||
bra menuupd_out
|
||||
key_a
|
||||
jsr menu_key_a
|
||||
bra menuupd_out
|
||||
key_x
|
||||
jsr menu_key_x
|
||||
bra menuupd_out
|
||||
|
||||
key_select
|
||||
jsr menu_key_select
|
||||
bra menuupd_out
|
||||
|
||||
menuupd_out
|
||||
lda #$09
|
||||
sta cursor_y
|
||||
rts
|
||||
|
||||
|
||||
menu_redraw:
|
||||
lda menu_state
|
||||
beq redraw_filelist
|
||||
; cmp 1
|
||||
; beq redraw_main
|
||||
menu_redraw_out
|
||||
rts
|
||||
|
||||
redraw_filelist
|
||||
ldy #$0000
|
||||
sty dirptr_idx
|
||||
stz dirend_idx
|
||||
stz dirend_onscreen
|
||||
redraw_filelist_loop
|
||||
ldy dirptr_idx
|
||||
tya
|
||||
lsr
|
||||
lsr
|
||||
cmp listdisp
|
||||
beq redraw_filelist_last
|
||||
rep #$20 : .al
|
||||
lda [dirptr_addr], y
|
||||
sta @dirent_addr
|
||||
iny
|
||||
iny
|
||||
sep #$20 : .as
|
||||
lda [dirptr_addr], y ; load fileinfo bank
|
||||
clc
|
||||
adc #$c0 ; add $C0 for memory map
|
||||
sta @dirent_bank ; store as current bank
|
||||
cmp #$c0 ; if bank was 0 -> dirend entry in DB
|
||||
beq redraw_filelist_dirend ; handle dirend
|
||||
iny
|
||||
lda [dirptr_addr], y
|
||||
iny
|
||||
sta @dirent_type
|
||||
sty dirptr_idx
|
||||
jsr print_direntry
|
||||
bra redraw_filelist_loop
|
||||
redraw_filelist_dirend
|
||||
dey ; recover last valid direntry number
|
||||
dey ; (we had 2x iny of the direntry pointer above,
|
||||
beq +
|
||||
dey ; so account for those too)
|
||||
dey
|
||||
dey
|
||||
dey
|
||||
+ sty dirend_idx ; dirend_idx <- last valid directory entry.
|
||||
lda #$01 ; encountered during redraw, so must be on screen
|
||||
sta dirend_onscreen
|
||||
bra redraw_filelist_out
|
||||
redraw_filelist_last ;check if next offscreen item is end of dir
|
||||
iny
|
||||
iny
|
||||
lda [dirptr_addr], y
|
||||
beq redraw_filelist_dirend
|
||||
redraw_filelist_out
|
||||
ldx #$0000
|
||||
stx dirptr_idx
|
||||
brl menu_redraw_out
|
||||
|
||||
print_direntry:
|
||||
lda cursor_y
|
||||
sta print_y
|
||||
inc
|
||||
sta cursor_y
|
||||
|
||||
lda dirent_bank
|
||||
ldx dirent_addr
|
||||
|
||||
phb
|
||||
pha
|
||||
plb
|
||||
|
||||
lda @dirent_type
|
||||
and #$f0
|
||||
cmp #$80
|
||||
rep #$20 : .al
|
||||
bne dirent_is_file
|
||||
dirent_is_dir
|
||||
lda #$04 ;skip dir tgt
|
||||
sta @fd_fnoff
|
||||
lda #$01 ;different color for dirs
|
||||
bra dirent_type_cont
|
||||
dirent_is_file
|
||||
lda #$06 ;skip size string
|
||||
sta @fd_fnoff
|
||||
lda @dirent_type
|
||||
and #$00ff
|
||||
cmp #$0001 ;SMC -> palette 0 (white)
|
||||
bne +
|
||||
lda #$0000
|
||||
bra dirent_type_cont
|
||||
+
|
||||
cmp #$0004 ;IPS -> palette 2 (green)
|
||||
bne +
|
||||
lda #$0002
|
||||
bra dirent_type_cont
|
||||
+
|
||||
lda #$0000 ;default -> palette 0
|
||||
dirent_type_cont
|
||||
sta @print_pal
|
||||
rep #$20 : .al
|
||||
txa
|
||||
clc
|
||||
adc @fd_fnoff
|
||||
tax
|
||||
sep #$20 : .as
|
||||
lda !0, x ;load offset of leaf (file) name
|
||||
inc
|
||||
rep #$20 : .al
|
||||
and #$00ff ;kill hi byte
|
||||
sta @fd_fnoff
|
||||
txa
|
||||
clc
|
||||
adc @fd_fnoff
|
||||
sta @fd_fnoff
|
||||
plb
|
||||
|
||||
lda cursor_x
|
||||
sta print_x
|
||||
|
||||
sep #$20 : .as
|
||||
ldx fd_fnoff
|
||||
lda #54
|
||||
sta print_count
|
||||
stx print_src
|
||||
lda dirent_bank
|
||||
sta print_bank
|
||||
jsr hiprint
|
||||
|
||||
lda cursor_x
|
||||
clc
|
||||
adc print_done
|
||||
sta print_x
|
||||
|
||||
lda #54
|
||||
sec
|
||||
sbc print_done
|
||||
sta print_count
|
||||
lda #^space64
|
||||
ldx #!space64
|
||||
sta print_bank
|
||||
stx print_src
|
||||
jsr hiprint
|
||||
|
||||
sep #$20 : .as
|
||||
lda dirent_type
|
||||
and #$f0
|
||||
cmp #$80
|
||||
bne dirent_is_file_2
|
||||
lda #^text_dirmark
|
||||
ldx #!text_dirmark
|
||||
sta print_bank
|
||||
stx print_src
|
||||
bra dirent_type_cont_2
|
||||
dirent_is_file_2
|
||||
lda dirent_bank
|
||||
ldx dirent_addr
|
||||
sta print_bank
|
||||
stx print_src
|
||||
dirent_type_cont_2
|
||||
lda #56
|
||||
sta print_x
|
||||
lda #6
|
||||
sta print_count
|
||||
jsr hiprint
|
||||
|
||||
rts
|
||||
|
||||
menu_key_down:
|
||||
lda listdisp
|
||||
dec
|
||||
cmp menu_sel
|
||||
bne down_noscroll
|
||||
lda #$01
|
||||
sta menu_dirty
|
||||
lda dirend_onscreen
|
||||
bne down_out
|
||||
rep #$20 : .al
|
||||
lda dirptr_addr
|
||||
clc
|
||||
adc #$04
|
||||
bcc +
|
||||
inc dirptr_bank
|
||||
+ sta dirptr_addr
|
||||
sep #$20 : .as
|
||||
rts
|
||||
down_noscroll
|
||||
lda dirend_onscreen
|
||||
beq +
|
||||
lda dirend_idx
|
||||
lsr
|
||||
lsr
|
||||
cmp menu_sel
|
||||
beq menuupd_lastcursor
|
||||
bcc menuupd_lastcursor
|
||||
+ lda menu_sel
|
||||
inc
|
||||
sta menu_sel
|
||||
down_out
|
||||
rts
|
||||
|
||||
menu_key_up:
|
||||
lda menu_sel
|
||||
bne up_noscroll
|
||||
lda #$01
|
||||
sta menu_dirty
|
||||
rep #$20 : .al
|
||||
lda dirptr_addr
|
||||
cmp dirstart_addr
|
||||
beq up_out
|
||||
sec
|
||||
sbc #$04
|
||||
bcs +
|
||||
dec dirptr_bank
|
||||
+ sta dirptr_addr
|
||||
bra up_out
|
||||
up_noscroll
|
||||
dec
|
||||
sta menu_sel
|
||||
up_out
|
||||
sep #$20 : .as
|
||||
rts
|
||||
|
||||
menuupd_lastcursor
|
||||
lda dirend_idx
|
||||
lsr
|
||||
lsr
|
||||
sta menu_sel
|
||||
rts
|
||||
|
||||
; go back one page
|
||||
menu_key_left:
|
||||
lda #$01 ; must redraw afterwards
|
||||
sta menu_dirty
|
||||
rep #$20 : .al
|
||||
lda dirptr_addr ; get current direntry pointer
|
||||
beq + ; special case: if 0, we are at the first entry in memory
|
||||
lsr
|
||||
lsr ; make comparable to listdisp
|
||||
cmp listdisp ; if there's less or equal previous entries...
|
||||
beq + ; ...than display lines, reset to directory start
|
||||
bcc +
|
||||
sec
|
||||
sbc listdisp ; subtract one screen page's worth of entries
|
||||
asl
|
||||
asl ; make comparable to dirstart_addr again
|
||||
cmp dirstart_addr ; check whether calculated offset is before...
|
||||
bcc + ; ...start of directory
|
||||
- sta dirptr_addr ; store new selected entry
|
||||
sep #$20 : .as
|
||||
rts
|
||||
+ lda dirstart_addr ; reset pointer to start of directory
|
||||
stz menu_sel ; reset the selection cursor too
|
||||
bra -
|
||||
|
||||
; go forth one page
|
||||
menu_key_right:
|
||||
sep #$20 : .as
|
||||
lda dirend_onscreen
|
||||
bne menuupd_lastcursor
|
||||
lda #$01
|
||||
sta menu_dirty
|
||||
rep #$20 : .al
|
||||
lda listdisp
|
||||
asl
|
||||
asl
|
||||
clc
|
||||
adc dirptr_addr
|
||||
sta dirptr_addr
|
||||
sep #$20 : .as
|
||||
rts
|
||||
|
||||
menu_key_a:
|
||||
jsr select_item
|
||||
rts
|
||||
|
||||
menu_key_select:
|
||||
lda barstep
|
||||
beq do_setup448
|
||||
do_setup224
|
||||
jsr setup_224
|
||||
rts
|
||||
do_setup448
|
||||
jsr setup_448
|
||||
rts
|
||||
|
||||
menu_key_b:
|
||||
rep #$20 : .al
|
||||
lda dirstart_addr
|
||||
beq skip_key_b
|
||||
sta dirptr_addr
|
||||
lda #$0000
|
||||
sta menu_sel
|
||||
bra select_item
|
||||
skip_key_b
|
||||
sep #$20 : .as
|
||||
rts
|
||||
|
||||
select_item:
|
||||
rep #$20 : .al
|
||||
lda menu_sel
|
||||
and #$00ff
|
||||
asl
|
||||
asl
|
||||
tay
|
||||
sep #$20 : .as
|
||||
iny
|
||||
iny
|
||||
iny
|
||||
lda [dirptr_addr], y
|
||||
cmp #$01
|
||||
beq sel_is_file
|
||||
cmp #$04
|
||||
beq sel_is_file
|
||||
cmp #$80
|
||||
beq sel_is_dir
|
||||
cmp #$81
|
||||
beq sel_is_parent
|
||||
select_item_cont
|
||||
rts
|
||||
sel_is_file
|
||||
jsr select_file
|
||||
bra select_item_cont
|
||||
sel_is_parent
|
||||
jsr select_parent
|
||||
bra select_item_cont
|
||||
sel_is_dir
|
||||
jsr select_dir
|
||||
bra select_item_cont
|
||||
|
||||
select_file:
|
||||
; have avr load the rom
|
||||
dey
|
||||
rep #$20 : .al
|
||||
lda [dirptr_addr], y
|
||||
and #$00ff
|
||||
sta @AVR_PARAM+2
|
||||
dey
|
||||
dey
|
||||
lda [dirptr_addr], y
|
||||
sta @AVR_PARAM
|
||||
sep #$20 : .as
|
||||
lda #$01
|
||||
sta @AVR_CMD
|
||||
lda #$00
|
||||
sta @$4200
|
||||
sei
|
||||
jsl @wram_fadeloop
|
||||
rts
|
||||
|
||||
select_dir:
|
||||
tyx
|
||||
; save old dir position
|
||||
rep #$20 : .al
|
||||
ldy #$0000
|
||||
lda @dirstart_addr
|
||||
sta [dirlog_idx], y
|
||||
iny
|
||||
iny
|
||||
lda @dirstart_bank
|
||||
sta [dirlog_idx], y
|
||||
iny
|
||||
lda @dirptr_addr
|
||||
sta [dirlog_idx], y
|
||||
iny
|
||||
iny
|
||||
lda @dirptr_bank
|
||||
sta [dirlog_idx], y
|
||||
iny
|
||||
lda @menu_sel
|
||||
sta [dirlog_idx], y
|
||||
lda @dirlog_idx
|
||||
clc
|
||||
adc #$0008
|
||||
sta @dirlog_idx
|
||||
sep #$20 : .as
|
||||
;---
|
||||
; y = direntry ptr
|
||||
txy
|
||||
dey
|
||||
lda [dirptr_addr], y
|
||||
clc
|
||||
adc #$c0
|
||||
sta @dirent_bank
|
||||
dey
|
||||
dey
|
||||
rep #$20 : .al
|
||||
lda [dirptr_addr], y
|
||||
sta @dirent_addr
|
||||
tax
|
||||
sep #$20 : .as
|
||||
lda @dirent_bank
|
||||
phb
|
||||
pha
|
||||
plb
|
||||
lda !2, x ; load linked dir start bank
|
||||
clc
|
||||
adc #$c0
|
||||
sta @dirptr_bank
|
||||
sta @dirstart_bank
|
||||
rep #$20 : .al
|
||||
lda !0, x ; load linked dir start address
|
||||
sta @dirptr_addr
|
||||
sta @dirstart_addr
|
||||
lda #$0000
|
||||
sta @menu_sel
|
||||
sep #$20 : .as
|
||||
lda #$01
|
||||
sta @menu_dirty
|
||||
plb
|
||||
rts
|
||||
|
||||
select_parent:
|
||||
rep #$20 : .al
|
||||
lda @dirlog_idx
|
||||
sec
|
||||
sbc #$0008
|
||||
sta @dirlog_idx
|
||||
ldy #$0000
|
||||
lda [dirlog_idx], y ; load dirstart_addr
|
||||
sta @dirstart_addr
|
||||
iny
|
||||
iny
|
||||
sep #$20 : .as
|
||||
lda [dirlog_idx], y ; load dirstart_bank
|
||||
sta @dirstart_bank
|
||||
iny
|
||||
rep #$20 : .al
|
||||
lda [dirlog_idx], y ; load dirptr_addr
|
||||
sta @dirptr_addr
|
||||
iny
|
||||
iny
|
||||
sep #$20 : .as
|
||||
lda [dirlog_idx], y ; load dirptr_bank
|
||||
sta @dirptr_bank
|
||||
iny
|
||||
rep #$20 : .al
|
||||
lda [dirlog_idx], y ; load menu_sel
|
||||
sta @menu_sel
|
||||
sep #$20 : .as
|
||||
lda #$01
|
||||
sta @menu_dirty
|
||||
rts
|
||||
|
||||
menu_key_x:
|
||||
jsr mainmenu
|
||||
rts
|
||||
|
||||
setup_224:
|
||||
php
|
||||
rep #$30 : .xl : .al
|
||||
lda #18
|
||||
sta listdisp
|
||||
dec
|
||||
cmp menu_sel
|
||||
bmi setup_224_adjsel
|
||||
bra +
|
||||
setup_224_adjsel
|
||||
sta menu_sel
|
||||
+
|
||||
lda #18*64
|
||||
sta textdmasize
|
||||
lda #$0007
|
||||
sta hdma_scroll+8
|
||||
sep #$20 : .as
|
||||
lda #$07
|
||||
sta $2110
|
||||
lda #$00
|
||||
sta $2110
|
||||
lda #$00
|
||||
sta barstep
|
||||
ora #$08
|
||||
sta $2133
|
||||
lda #$08
|
||||
sta hdma_math_selection
|
||||
stz vidmode
|
||||
lda #$01
|
||||
sta menu_dirty
|
||||
lda #^space64
|
||||
ldx #!space64
|
||||
sta print_bank
|
||||
stx print_src
|
||||
stz print_pal
|
||||
lda #64
|
||||
sta print_count
|
||||
lda #27
|
||||
sta print_y
|
||||
stz print_x
|
||||
jsr hiprint
|
||||
lda #28
|
||||
sta print_y
|
||||
jsr hiprint
|
||||
jsr hiprint
|
||||
|
||||
plp
|
||||
rts
|
||||
|
||||
setup_448:
|
||||
php
|
||||
rep #$30 : .xl : .al
|
||||
lda #36
|
||||
sta listdisp
|
||||
lda #36*64
|
||||
sta textdmasize
|
||||
lda #$ffc6
|
||||
sta hdma_scroll+8
|
||||
sep #$20 : .as
|
||||
lda #$c6
|
||||
sta $2110
|
||||
lda #$ff
|
||||
sta $2110
|
||||
lda #$01
|
||||
sta barstep
|
||||
ora #$08
|
||||
sta $2133
|
||||
lda #$04
|
||||
sta hdma_math_selection
|
||||
lda #$01
|
||||
sta vidmode
|
||||
sta menu_dirty
|
||||
plp
|
||||
rts
|
||||
|
||||
menu_statusbar
|
||||
pha
|
||||
phx
|
||||
php
|
||||
sep #$20 : .as
|
||||
rep #$10 : .xl
|
||||
lda #^text_statusbar_keys
|
||||
sta @print_bank
|
||||
rep #$20 : .al
|
||||
lda #!text_statusbar_keys
|
||||
sta @print_src
|
||||
sep #$20 : .as
|
||||
lda #$00
|
||||
sta @print_pal
|
||||
lda #$02
|
||||
sta @print_x
|
||||
lda #$40
|
||||
sta @print_count
|
||||
lda listdisp
|
||||
clc
|
||||
adc #$0a
|
||||
clc
|
||||
adc vidmode
|
||||
sta @print_y
|
||||
jsr hiprint
|
||||
plp
|
||||
plx
|
||||
pla
|
||||
rts
|
||||
|
||||
17
snes/tests/Makefile
Normal file
17
snes/tests/Makefile
Normal file
@ -0,0 +1,17 @@
|
||||
OBJS = header.ips reset.o65 tests.o65
|
||||
|
||||
all: test.bin
|
||||
|
||||
test.bin: $(OBJS)
|
||||
sneslink -fsmc -o $@ $^
|
||||
|
||||
# Generic rule to create .o65 out from .a65
|
||||
%.o65: %.a65
|
||||
snescom -J -Wall -o $@ $<
|
||||
|
||||
# Generic rule to create .ips out from .a65
|
||||
%.ips: %.a65
|
||||
snescom -I -J -Wall -o $@ $<
|
||||
|
||||
clean:
|
||||
rm -f *.ips *.o65 *~ test.bin
|
||||
121
snes/tests/header.a65
Normal file
121
snes/tests/header.a65
Normal file
@ -0,0 +1,121 @@
|
||||
; This file is part of the snescom-asm demo - a demo of how to build a SNES program.
|
||||
; See http://bisqwit.iki.fi/source/snescom.html for details.
|
||||
|
||||
; Begin assembling to this address.
|
||||
*= $C0F000
|
||||
LINETEST:
|
||||
sei
|
||||
clc
|
||||
xce
|
||||
- lda $0000
|
||||
lda $2100
|
||||
sta $2100
|
||||
bra -
|
||||
|
||||
*= $C0F100
|
||||
IRQTEST:
|
||||
sei
|
||||
clc
|
||||
xce
|
||||
cli
|
||||
sep #$20 : .as
|
||||
rep #$10 : .xl
|
||||
lda #$0f
|
||||
sta $2100
|
||||
lda #$ff
|
||||
sta $4209
|
||||
lda #$ff
|
||||
sta $420a
|
||||
lda #$ff
|
||||
sta $4200
|
||||
lda #$01
|
||||
- sta @$002222
|
||||
bra -
|
||||
|
||||
*= $C0F200
|
||||
BANKTEST:
|
||||
sei
|
||||
clc
|
||||
xce
|
||||
sep #$20 : .as
|
||||
lda #$01
|
||||
sta @$0055aa
|
||||
- bra -
|
||||
|
||||
*= $C0FF00
|
||||
|
||||
RESET:
|
||||
sei
|
||||
clc
|
||||
xce
|
||||
rep #$20 : .al
|
||||
lda #$1fff
|
||||
tcs
|
||||
lda #$00
|
||||
sta @$003333
|
||||
jmp @GAME_MAIN
|
||||
|
||||
NMI_16bit:
|
||||
php
|
||||
rep #$30 : .al : .xl
|
||||
pha: phx: phy: phd: phb
|
||||
jsl @NMI_ROUTINE
|
||||
rep #$30 : .al : .xl
|
||||
int_exit:
|
||||
plb: pld: ply: plx: pla
|
||||
plp
|
||||
rti
|
||||
|
||||
IRQ_16bit:
|
||||
ABT_8bit: ABT_16bit:
|
||||
php
|
||||
rep #$30 : .al : .xl
|
||||
pha: phx: phy: phd: phb
|
||||
jsl @IRQ_ROUTINE
|
||||
rep #$30 : .al : .xl
|
||||
bra int_exit
|
||||
|
||||
;error vectors
|
||||
BRK_8bit: BRK_16bit:
|
||||
COP_8bit: COP_16bit:
|
||||
IRQ_8bit:
|
||||
NMI_8bit:
|
||||
- wai: lda $ABCDEF : bra -
|
||||
|
||||
*= $C0FFB0
|
||||
; Zero the area from $FFB0 - $FFFF
|
||||
; to ensure that the linker won't get clever
|
||||
; and fill it with small pieces of code.
|
||||
.word 0,0,0,0, 0,0,0,0
|
||||
.word 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0
|
||||
.word 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0
|
||||
|
||||
*= $C0FFB0
|
||||
|
||||
.byt "MR" ;2 bytes - company id
|
||||
.byt "TEST" ;4 bytes - rom id
|
||||
|
||||
*= $C0FFC0
|
||||
.byt "SD2SNES TESTS "
|
||||
;123456789012345678901; - max 21 chars
|
||||
|
||||
*= $C0FFD5 .byt $31 ;rom speed
|
||||
*= $C0FFD6 .byt $02 ;rom type
|
||||
*= $C0FFD7 .byt $06 ;rom size 64 kByte
|
||||
*= $C0FFD8 .byt $03 ;sram size 8 kBit
|
||||
*= $C0FFD9 .byt $09 ;rom region 4 = Finland
|
||||
*= $C0FFDA .byt $33 ;company id flag
|
||||
|
||||
*= $C0FFDC .word 0,0 ;checksums
|
||||
|
||||
*= $C0FFE4 .word COP_16bit
|
||||
*= $C0FFE6 .word BRK_16bit
|
||||
*= $C0FFE8 .word ABT_16bit
|
||||
*= $C0FFEA .word NMI_16bit
|
||||
*= $C0FFEE .word IRQ_16bit
|
||||
*= $C0FFF4 .word COP_8bit
|
||||
*= $C0FFF8 .word ABT_8bit
|
||||
*= $C0FFFA .word NMI_8bit
|
||||
*= $C0FFFC .word RESET
|
||||
*= $C0FFFE .word BRK_8bit
|
||||
*= $C0FFFE .word IRQ_8bit
|
||||
29
snes/tests/reset.a65
Normal file
29
snes/tests/reset.a65
Normal file
@ -0,0 +1,29 @@
|
||||
; This file is part of the snescom-asm demo - a demo of how to build a SNES program.
|
||||
; See http://bisqwit.iki.fi/source/snescom.html for details.
|
||||
|
||||
; NMI - called on VBlank
|
||||
NMI_ROUTINE:
|
||||
sep #$20 : .as
|
||||
rep #$10 : .xl
|
||||
lda #$00
|
||||
pha
|
||||
plb
|
||||
|
||||
lda $4210 ; ack interrupt
|
||||
|
||||
rtl
|
||||
|
||||
; IRQ - called when triggered
|
||||
IRQ_ROUTINE:
|
||||
sep #$20 : .as
|
||||
lda $4211 ;Acknowledge irq
|
||||
lda #$00
|
||||
sta @$002121
|
||||
lda #$ff
|
||||
sta @$002122
|
||||
lda #$01
|
||||
sta @$002122
|
||||
lda #$5A
|
||||
sta @$F00000
|
||||
rtl
|
||||
|
||||
564
snes/tests/tests.a65
Normal file
564
snes/tests/tests.a65
Normal file
@ -0,0 +1,564 @@
|
||||
GAME_MAIN:
|
||||
sep #$20 : .as
|
||||
stz $4200 ; inhibit VBlank NMI
|
||||
lda #$01
|
||||
sta $420d ; fast cpu
|
||||
jsr killdma
|
||||
jsr waitblank
|
||||
lda #$00
|
||||
sta @$f00000
|
||||
sta @$f00001
|
||||
sta @$f00002
|
||||
sta @$f00003
|
||||
lda #$00
|
||||
sta @$f01fff
|
||||
jsr snes_init
|
||||
jsr video_init
|
||||
jsr linetest
|
||||
jsr batest
|
||||
jsr snes_init
|
||||
jsr video_init
|
||||
jsr copy_memtest
|
||||
jsr irqtest
|
||||
jsl $7e1800
|
||||
- bra -
|
||||
|
||||
copy_memtest:
|
||||
rep #$30 : .al : .xl
|
||||
lda #$0300
|
||||
ldx #!memtest
|
||||
ldy #$1800
|
||||
mvn $7e, ^memtest
|
||||
rts
|
||||
|
||||
linetest
|
||||
sep #$20 : .as
|
||||
lda #$00
|
||||
pha
|
||||
plb
|
||||
- lda $0000
|
||||
lda $2100
|
||||
sta $21ff
|
||||
lda @$f01fff
|
||||
cmp #$01
|
||||
bne -
|
||||
rts
|
||||
|
||||
irqtest:
|
||||
cli
|
||||
sep #$20 : .as
|
||||
rep #$10 : .xl
|
||||
lda #$0f
|
||||
sta $2100
|
||||
lda #$ff
|
||||
sta $4209
|
||||
lda #$ff
|
||||
sta $420a
|
||||
lda #$ff
|
||||
sta $4200
|
||||
sta @$f00000
|
||||
lda #$01
|
||||
sta @$002222
|
||||
rts
|
||||
|
||||
batest:
|
||||
sei
|
||||
sep #$20 : .as
|
||||
rep #$10 : .xl
|
||||
lda #$00
|
||||
ldx #$2100
|
||||
- sta !$0, x
|
||||
inx
|
||||
inc
|
||||
bne -
|
||||
lda #$e0
|
||||
pha
|
||||
plb
|
||||
lda #$00
|
||||
ldx #$0000
|
||||
- cmp !$0, x
|
||||
bne batest_fail
|
||||
inx
|
||||
inc
|
||||
bne -
|
||||
lda #$5a
|
||||
sta @$f00002
|
||||
lda #$00
|
||||
pha
|
||||
plb
|
||||
rts
|
||||
batest_fail:
|
||||
lda #$ff
|
||||
sta @$f00002
|
||||
lda #$00
|
||||
pha
|
||||
plb
|
||||
rts
|
||||
|
||||
memtest:
|
||||
; test 4 areas: 00-3f:8000-ffff
|
||||
; 40-7d:0000-ffff
|
||||
; 80-bf:8000-ffff
|
||||
; 80-ff:0000-ffff
|
||||
sep #$20 : .as
|
||||
rep #$10 : .xl
|
||||
|
||||
lda #$01
|
||||
sta @$003333 ; switch to linear memory mode
|
||||
ldx #$8000
|
||||
stx $00
|
||||
ldx #$8000
|
||||
stx $10
|
||||
lda #$00
|
||||
sta $03 ; bank no.
|
||||
mem0_writeloop0:
|
||||
; switch bank
|
||||
pha
|
||||
plb
|
||||
lda #$01
|
||||
sta @$003333
|
||||
- lda $03
|
||||
clc
|
||||
adc $01
|
||||
clc
|
||||
adc $00
|
||||
sta !$0000, x
|
||||
inx
|
||||
stx $00
|
||||
bne -
|
||||
ldx $10
|
||||
inc $03
|
||||
lda #$00
|
||||
sta @$003333
|
||||
lda $03
|
||||
sta @$f00003
|
||||
cmp #$40
|
||||
bne mem0_writeloop0
|
||||
|
||||
ldx #$0000
|
||||
stx $10
|
||||
mem0_writeloop1:
|
||||
; switch bank
|
||||
lda #$01
|
||||
sta @$003333
|
||||
lda $03
|
||||
pha
|
||||
plb
|
||||
- lda $03
|
||||
clc
|
||||
adc $01
|
||||
clc
|
||||
adc $00
|
||||
sta !$0000, x
|
||||
inx
|
||||
stx $00
|
||||
bne -
|
||||
ldx $10
|
||||
inc $03
|
||||
lda #$00
|
||||
sta @$003333
|
||||
lda $03
|
||||
sta @$f00003
|
||||
cmp #$7e
|
||||
bne mem0_writeloop1
|
||||
|
||||
ldx #$8000
|
||||
stx $10
|
||||
lda #$80
|
||||
sta $03 ; bank no.
|
||||
mem0_writeloop2:
|
||||
; switch bank
|
||||
lda #$01
|
||||
sta @$003333
|
||||
lda $03
|
||||
pha
|
||||
plb
|
||||
- lda $03
|
||||
clc
|
||||
adc $01
|
||||
clc
|
||||
adc $00
|
||||
sta !$0000, x
|
||||
inx
|
||||
stx $00
|
||||
bne -
|
||||
ldx $10
|
||||
inc $03
|
||||
lda #$00
|
||||
sta @$003333
|
||||
lda $03
|
||||
sta @$f00003
|
||||
cmp #$c0
|
||||
bne mem0_writeloop2
|
||||
ldx #$0000
|
||||
stx $10
|
||||
mem0_writeloop3:
|
||||
; switch bank
|
||||
lda #$01
|
||||
sta @$003333
|
||||
lda $03
|
||||
pha
|
||||
plb
|
||||
- lda $03
|
||||
clc
|
||||
adc $01
|
||||
clc
|
||||
adc $00
|
||||
sta !$0000, x
|
||||
inx
|
||||
stx $00
|
||||
bne -
|
||||
ldx $10
|
||||
inc $03
|
||||
lda #$00
|
||||
sta @$003333
|
||||
lda $03
|
||||
sta @$f00003
|
||||
bne mem0_writeloop3
|
||||
|
||||
lda #$00
|
||||
sta @$002121
|
||||
lda #$ff
|
||||
sta @$002122
|
||||
lda #$03
|
||||
sta @$002122
|
||||
|
||||
ldx #$8000
|
||||
stx $00
|
||||
ldx #$8000
|
||||
stx $10
|
||||
lda #$00
|
||||
sta $03 ; bank no.
|
||||
mem0_verifyloop0:
|
||||
; switch bank
|
||||
lda #$01
|
||||
sta @$f00001
|
||||
lda #$01
|
||||
sta @$003333
|
||||
lda $03
|
||||
pha
|
||||
plb
|
||||
- lda $03
|
||||
clc
|
||||
adc $01
|
||||
clc
|
||||
adc $00
|
||||
cmp !$0000, x
|
||||
bne mem0_fail
|
||||
inx
|
||||
stx $00
|
||||
bne -
|
||||
ldx $10
|
||||
inc $03
|
||||
lda #$00
|
||||
sta @$003333
|
||||
lda $03
|
||||
sta @$f00003
|
||||
cmp #$40
|
||||
bne mem0_verifyloop0
|
||||
|
||||
ldx #$0000
|
||||
stx $10
|
||||
mem0_verifyloop1:
|
||||
; switch bank
|
||||
lda #$01
|
||||
sta @$003333
|
||||
lda $03
|
||||
pha
|
||||
plb
|
||||
- lda $03
|
||||
clc
|
||||
adc $01
|
||||
clc
|
||||
adc $00
|
||||
cmp !$0000, x
|
||||
bne mem0_fail
|
||||
inx
|
||||
stx $00
|
||||
bne -
|
||||
ldx $10
|
||||
inc $03
|
||||
lda #$00
|
||||
sta @$003333
|
||||
lda $03
|
||||
sta @$f00003
|
||||
cmp #$7e
|
||||
bne mem0_verifyloop1
|
||||
|
||||
ldx #$8000
|
||||
stx $10
|
||||
lda #$80
|
||||
sta $03 ; bank no.
|
||||
bra mem0_verifyloop2
|
||||
mem0_fail:
|
||||
lda #$00
|
||||
pha
|
||||
plb
|
||||
sta @$003333
|
||||
rep #$20 : .al
|
||||
lda $00
|
||||
sta @$f00004
|
||||
sep #$20 : .as
|
||||
lda $03
|
||||
sta @$f00006
|
||||
lda #$ff
|
||||
sta @$f00001
|
||||
rtl
|
||||
mem0_verifyloop2:
|
||||
; switch bank
|
||||
lda #$01
|
||||
sta @$003333
|
||||
lda $03
|
||||
pha
|
||||
plb
|
||||
- lda $03
|
||||
clc
|
||||
adc $01
|
||||
clc
|
||||
adc $00
|
||||
cmp !$0000, x
|
||||
bne mem0_fail
|
||||
inx
|
||||
stx $00
|
||||
bne -
|
||||
ldx $10
|
||||
inc $03
|
||||
lda #$00
|
||||
sta @$003333
|
||||
lda $03
|
||||
sta @$f00003
|
||||
cmp #$c0
|
||||
bne mem0_verifyloop2
|
||||
|
||||
ldx #$0000
|
||||
stx $10
|
||||
mem0_verifyloop3:
|
||||
; switch bank
|
||||
lda #$01
|
||||
sta @$003333
|
||||
lda $03
|
||||
pha
|
||||
plb
|
||||
- lda $03
|
||||
clc
|
||||
adc $01
|
||||
clc
|
||||
adc $00
|
||||
cmp !$0000, x
|
||||
bne mem0_fail
|
||||
inx
|
||||
stx $00
|
||||
bne -
|
||||
ldx $10
|
||||
inc $03
|
||||
lda #$00
|
||||
sta @$003333
|
||||
lda $03
|
||||
sta @$f00003
|
||||
bne mem0_verifyloop3
|
||||
|
||||
lda #$00
|
||||
sta @$002121
|
||||
lda #$e0
|
||||
sta @$002122
|
||||
lda #$03
|
||||
sta @$002122
|
||||
|
||||
lda #$00
|
||||
pha
|
||||
plb
|
||||
sta @$003333
|
||||
lda #$5a
|
||||
sta @$f00001
|
||||
rtl
|
||||
rtl
|
||||
rtl
|
||||
rtl
|
||||
rtl
|
||||
rtl
|
||||
|
||||
killdma:
|
||||
stz $420b
|
||||
stz $420c
|
||||
stz $4310
|
||||
stz $4311
|
||||
stz $4312
|
||||
stz $4313
|
||||
stz $4314
|
||||
stz $4320
|
||||
stz $4321
|
||||
stz $4322
|
||||
stz $4323
|
||||
stz $4324
|
||||
stz $4330
|
||||
stz $4331
|
||||
stz $4332
|
||||
stz $4333
|
||||
stz $4334
|
||||
stz $4340
|
||||
stz $4341
|
||||
stz $4342
|
||||
stz $4343
|
||||
stz $4344
|
||||
stz $4350
|
||||
stz $4351
|
||||
stz $4352
|
||||
stz $4353
|
||||
stz $4354
|
||||
stz $4360
|
||||
stz $4361
|
||||
stz $4362
|
||||
stz $4363
|
||||
stz $4364
|
||||
rts
|
||||
|
||||
|
||||
|
||||
|
||||
waitblank:
|
||||
- lda $4212
|
||||
and #$80
|
||||
bne -
|
||||
- lda $4212
|
||||
and #$80
|
||||
beq -
|
||||
rts
|
||||
|
||||
video_init:
|
||||
sep #$20 : .as ;8-bit accumulator
|
||||
rep #$10 : .xl ;16-bit index
|
||||
lda #$03 ;mode 3, mode 5 via HDMA :D
|
||||
sta $2105
|
||||
lda #$58 ;Tilemap addr 0xB000
|
||||
ora #$02 ;SC size 32x64
|
||||
sta $2107 ;for BG1
|
||||
lda #$50 ;Tilemap addr 0xA000
|
||||
ora #$02 ;SC size 32x64
|
||||
sta $2108 ;for BG2
|
||||
lda #$40 ;chr base addr:
|
||||
sta $210b ;BG1=0x0000, BG2=0x8000
|
||||
lda #$01 ;cut off leftmost subscreen pixel garbage
|
||||
sta $2126
|
||||
lda #$fe
|
||||
sta $2127
|
||||
lda #$10
|
||||
sta $2130
|
||||
lda #$1f
|
||||
sta $212e
|
||||
sta $212f
|
||||
stz $2121
|
||||
lda #$0f
|
||||
sta $2100 ;screen on, full brightness
|
||||
stz $2121
|
||||
lda #$1f ;red background
|
||||
sta $2122
|
||||
stz $2122
|
||||
rts
|
||||
|
||||
snes_init:
|
||||
sep #$20 : .as ;8-bit accumulator
|
||||
rep #$10 : .xl ;16-bit index
|
||||
stz $4200 ;
|
||||
lda #$ff
|
||||
sta $4201 ;
|
||||
stz $4202 ;
|
||||
stz $4203 ;
|
||||
stz $4204 ;
|
||||
stz $4205 ;
|
||||
stz $4206 ;
|
||||
stz $4207 ;
|
||||
stz $4208 ;
|
||||
stz $4209 ;
|
||||
stz $420a ;
|
||||
stz $420b ;
|
||||
stz $420c ;
|
||||
lda #$8f
|
||||
sta $2100 ;INIDISP: force blank
|
||||
lda #$03 ; 8x8+16x16; name=0; base=3
|
||||
sta $2101 ;
|
||||
stz $2102 ;
|
||||
stz $2103 ;
|
||||
; stz $2104 ; (OAM Data?!)
|
||||
; stz $2104 ; (OAM Data?!)
|
||||
stz $2105 ;
|
||||
stz $2106 ;
|
||||
stz $2107 ;
|
||||
stz $2108 ;
|
||||
stz $2109 ;
|
||||
stz $210a ;
|
||||
stz $210b ;
|
||||
stz $210c ;
|
||||
stz $210d ;
|
||||
stz $210d ;
|
||||
stz $210e ;
|
||||
stz $210e ;
|
||||
stz $210f ;
|
||||
stz $210f ;
|
||||
lda #$05
|
||||
sta $2110 ;
|
||||
stz $2110 ;
|
||||
stz $2111 ;
|
||||
stz $2111 ;
|
||||
stz $2112 ;
|
||||
stz $2112 ;
|
||||
stz $2113 ;
|
||||
stz $2113 ;
|
||||
stz $2114 ;
|
||||
stz $2114 ;
|
||||
lda #$80
|
||||
sta $2115 ;
|
||||
stz $2116 ;
|
||||
stz $2117 ;
|
||||
; stz $2118 ;(VRAM Data?!)
|
||||
; stz $2119 ;(VRAM Data?!)
|
||||
stz $211a ;
|
||||
stz $211b ;
|
||||
lda #$01
|
||||
sta $211b ;
|
||||
stz $211c ;
|
||||
stz $211c ;
|
||||
stz $211d ;
|
||||
stz $211d ;
|
||||
stz $211e ;
|
||||
sta $211e ;
|
||||
stz $211f ;
|
||||
stz $211f ;
|
||||
stz $2120 ;
|
||||
stz $2120 ;
|
||||
stz $2121 ;
|
||||
; stz $2122 ; (CG Data?!)
|
||||
; stz $2122 ; (CG Data?!)
|
||||
stz $2123 ;
|
||||
stz $2124 ;
|
||||
stz $2125 ;
|
||||
stz $2126 ;
|
||||
stz $2127 ;
|
||||
stz $2128 ;
|
||||
stz $2129 ;
|
||||
stz $212a ;
|
||||
stz $212b ;
|
||||
stz $212c ;
|
||||
stz $212d ;
|
||||
stz $212e ;
|
||||
stz $212f ;
|
||||
lda #$30
|
||||
sta $2130 ;
|
||||
stz $2131 ;
|
||||
lda #$e0
|
||||
sta $2132 ;
|
||||
stz $2133 ;
|
||||
;clear WRAM lower page
|
||||
; ldx #$0200
|
||||
; stx $2181
|
||||
; lda #$00
|
||||
; sta $2183
|
||||
; DMA0(#$08, #$FF00, #^zero, #!zero, #$80)
|
||||
; ldx #$0000
|
||||
; stx $2181
|
||||
; lda #$00
|
||||
; sta $2183
|
||||
; DMA0(#$08, #$1e0, #^zero, #!zero, #$80)
|
||||
|
||||
rts
|
||||
|
||||
|
||||
373
snes/text.a65
Normal file
373
snes/text.a65
Normal file
@ -0,0 +1,373 @@
|
||||
.text
|
||||
#include "memmap.i65"
|
||||
.byt "===HIPRINT==="
|
||||
hiprint:
|
||||
sep #$20 : .as
|
||||
lda print_count
|
||||
sta print_count_tmp
|
||||
rep #$30 : .xl : .al
|
||||
stz print_done
|
||||
lda print_x
|
||||
and #$00ff
|
||||
lsr
|
||||
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
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
clc
|
||||
adc !print_temp
|
||||
asl ; double the offset for WRAM addressing
|
||||
tay ; zonday
|
||||
plx
|
||||
phy ; offset from tilemap start
|
||||
stx !print_temp
|
||||
clc
|
||||
adc !print_temp
|
||||
; we need to transfer to WRAM and from there to VRAM via DMA during VBLANK
|
||||
; because VRAM can only be accessed during VBLANK and forced blanking.
|
||||
sta $2181
|
||||
sep #$20 : .as
|
||||
lda #$7f ;we really only need bit 0. full bank given for clarity
|
||||
sta $2183
|
||||
print_loop
|
||||
ldx !print_src
|
||||
lda !print_bank
|
||||
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
|
||||
sta @print_done
|
||||
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
|
||||
inx
|
||||
lda !0,x
|
||||
beq print_end
|
||||
lda @print_count_tmp
|
||||
dec
|
||||
dec
|
||||
sta @print_count_tmp
|
||||
beq print_end
|
||||
bmi print_end
|
||||
bra print_loop2_inner
|
||||
print_end2 ; clean up the stack (6 bytes)
|
||||
ply
|
||||
ply
|
||||
ply
|
||||
print_end
|
||||
lda #$00
|
||||
pha
|
||||
plb
|
||||
rts
|
||||
|
||||
|
||||
loprint:
|
||||
rep #$30 : .xl : .al
|
||||
lda !print_x
|
||||
and #$00ff
|
||||
asl ;double the offset for WRAM addressing
|
||||
clc
|
||||
adc #!BG2_TILE_BUF
|
||||
sta !print_temp
|
||||
lda !print_y
|
||||
and #$00ff
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
asl ;double the offset for WRAM addressing
|
||||
clc
|
||||
adc !print_temp
|
||||
; we need to transfer to WRAM and from there to VRAM via DMA during VBLANK
|
||||
; because VRAM can only be accessed during VBLANK and forced blanking.
|
||||
sta $2181
|
||||
sep #$20 : .as
|
||||
lda #$7f ;we really only need bit 0. full bank given for clarity
|
||||
sta $2183
|
||||
ldx !print_src
|
||||
lda !print_bank
|
||||
pha
|
||||
plb
|
||||
loprint_loop_inner
|
||||
lda !0,x
|
||||
beq loprint_end
|
||||
sta @$2180
|
||||
lda #$00
|
||||
adc #$00
|
||||
ora #$20
|
||||
sta @$2180
|
||||
inx
|
||||
bra loprint_loop_inner
|
||||
loprint_end
|
||||
lda #$00
|
||||
pha
|
||||
plb
|
||||
rts
|
||||
|
||||
backup_screen:
|
||||
; MVN: X=source, Y=dest, A=count
|
||||
; imm1=srcbk, imm2=dstbk
|
||||
phb
|
||||
php
|
||||
rep #$30 : .xl : .al
|
||||
ldx #!BG1_TILE_BUF+64*9
|
||||
ldy #!BG1_TILE_BAK+64*9
|
||||
lda @textdmasize
|
||||
mvn ^BG1_TILE_BUF, ^BG1_TILE_BAK
|
||||
ldx #!BG2_TILE_BUF+64*9
|
||||
ldy #!BG2_TILE_BAK+64*9
|
||||
lda @textdmasize
|
||||
mvn ^BG2_TILE_BUF, ^BG2_TILE_BAK
|
||||
plp
|
||||
plb
|
||||
rts
|
||||
|
||||
restore_screen:
|
||||
; MVN: X=source, Y=dest, A=count
|
||||
; imm1=srcbk, imm2=dstbk
|
||||
phb
|
||||
php
|
||||
rep #$30 : .xl : .al
|
||||
ldx #!BG1_TILE_BAK+64*9
|
||||
ldy #!BG1_TILE_BUF+64*9
|
||||
lda @textdmasize
|
||||
mvn ^BG1_TILE_BAK, ^BG1_TILE_BUF
|
||||
ldx #!BG2_TILE_BAK+64*9
|
||||
ldy #!BG2_TILE_BUF+64*9
|
||||
lda @textdmasize
|
||||
mvn ^BG2_TILE_BAK, ^BG2_TILE_BUF
|
||||
plp
|
||||
plb
|
||||
rts
|
||||
|
||||
draw_window:
|
||||
phb
|
||||
php
|
||||
sep #$20 : .as
|
||||
|
||||
; draw upper border
|
||||
; upper left corner
|
||||
lda @window_nw
|
||||
sta stringbuf
|
||||
ldx #!stringbuf
|
||||
inx
|
||||
lda window_w
|
||||
sta window_tmp
|
||||
stz window_tmp+1
|
||||
ldy window_tmp
|
||||
dey
|
||||
dey
|
||||
; upper edge
|
||||
-
|
||||
lda @window_nh
|
||||
sta !0,x
|
||||
inx
|
||||
dey
|
||||
cpy #$0000
|
||||
bne -
|
||||
|
||||
; upper right corner
|
||||
lda @window_ne
|
||||
sta !0,x
|
||||
|
||||
; print to text buffer
|
||||
lda #$01
|
||||
sta print_pal
|
||||
lda window_x
|
||||
sta print_x
|
||||
lda window_y
|
||||
sta print_y
|
||||
lda #^stringbuf
|
||||
sta print_bank
|
||||
ldx #!stringbuf
|
||||
stx print_src
|
||||
lda window_w
|
||||
sta print_count
|
||||
jsr hiprint
|
||||
|
||||
; print window title
|
||||
lda print_x
|
||||
pha
|
||||
inc print_x
|
||||
inc print_x
|
||||
lda #^window_tl
|
||||
sta print_bank
|
||||
ldx #!window_tl
|
||||
stx print_src
|
||||
lda #$01
|
||||
sta print_count
|
||||
jsr hiprint
|
||||
inc print_x
|
||||
lda window_tbank
|
||||
sta print_bank
|
||||
ldx window_taddr
|
||||
stx print_src
|
||||
lda window_w
|
||||
sta print_count
|
||||
jsr hiprint
|
||||
lda print_done
|
||||
adc print_x
|
||||
sta print_x
|
||||
lda #^window_tr
|
||||
sta print_bank
|
||||
ldx #!window_tr
|
||||
stx print_src
|
||||
lda #$01
|
||||
sta print_count
|
||||
jsr hiprint
|
||||
lda window_w
|
||||
sta print_count
|
||||
pla
|
||||
sta print_x
|
||||
; draw left+right borders + space inside window
|
||||
lda #^stringbuf
|
||||
sta print_bank
|
||||
ldx #!stringbuf
|
||||
stx print_src
|
||||
lda @window_wv
|
||||
sta stringbuf
|
||||
ldx #!stringbuf
|
||||
inx
|
||||
lda window_w
|
||||
sta window_tmp
|
||||
stz window_tmp+1
|
||||
ldy window_tmp
|
||||
dey
|
||||
dey
|
||||
-
|
||||
lda @space64
|
||||
sta !0,x
|
||||
inx
|
||||
dey
|
||||
cpy #$0000
|
||||
bne -
|
||||
|
||||
lda @window_ev
|
||||
sta !0,x
|
||||
|
||||
; print to text buffer multiple times
|
||||
lda window_h
|
||||
sta window_tmp
|
||||
stz window_tmp+1
|
||||
ldy window_tmp
|
||||
dey
|
||||
dey
|
||||
-
|
||||
inc print_y
|
||||
phy
|
||||
jsr hiprint
|
||||
ply
|
||||
dey
|
||||
cpy #$0000
|
||||
bne -
|
||||
|
||||
; draw lower window border
|
||||
; lower left corner
|
||||
lda @window_sw
|
||||
sta stringbuf
|
||||
ldx #!stringbuf
|
||||
inx
|
||||
lda window_w
|
||||
sta window_tmp
|
||||
stz window_tmp+1
|
||||
ldy window_tmp
|
||||
dey
|
||||
dey
|
||||
; lower edge
|
||||
-
|
||||
lda @window_sh
|
||||
sta !0,x
|
||||
inx
|
||||
dey
|
||||
cpy #$0000
|
||||
bne -
|
||||
; lower right corner
|
||||
lda @window_se
|
||||
sta !0,x
|
||||
; print to text buffer
|
||||
inc print_y
|
||||
jsr hiprint
|
||||
plp
|
||||
plb
|
||||
rts
|
||||
726
snes/time.a65
Normal file
726
snes/time.a65
Normal file
@ -0,0 +1,726 @@
|
||||
#include "memmap.i65"
|
||||
#include "dma.i65"
|
||||
|
||||
timebox_data
|
||||
; string offset, selection width, bcdtime offset
|
||||
.byt 0, 4, 9
|
||||
.byt 5, 2, 8
|
||||
.byt 8, 2, 6
|
||||
.byt 11, 2, 4
|
||||
.byt 14, 2, 2
|
||||
.byt 17, 2, 0
|
||||
|
||||
time_month
|
||||
.byt 3, 1
|
||||
.byt 2, 8
|
||||
.byt 3, 1
|
||||
.byt 3, 0
|
||||
.byt 3, 1
|
||||
.byt 3, 0
|
||||
.byt 3, 1
|
||||
.byt 3, 1
|
||||
.byt 3, 0
|
||||
.byt 3, 1
|
||||
.byt 3, 0
|
||||
.byt 3, 1
|
||||
|
||||
time_init:
|
||||
php
|
||||
sep #$20 : .as
|
||||
; save text area
|
||||
jsr backup_screen
|
||||
; draw window + current time setting
|
||||
lda #^text_clkset
|
||||
sta window_tbank
|
||||
ldx #!text_clkset
|
||||
stx window_taddr
|
||||
lda @time_win_x
|
||||
sta window_x
|
||||
lda @time_win_w
|
||||
sta window_w
|
||||
lda @time_win_y
|
||||
sta window_y
|
||||
lda @time_win_h
|
||||
sta window_h
|
||||
jsr draw_window
|
||||
jsr gettime
|
||||
stz time_sel
|
||||
stz time_exit
|
||||
stz time_cancel
|
||||
lda #^text_buttonB
|
||||
sta print_bank
|
||||
ldx #!text_buttonB
|
||||
stx print_src
|
||||
lda @time_win_x
|
||||
inc
|
||||
inc
|
||||
sta print_x
|
||||
lda @time_win_y
|
||||
clc
|
||||
adc #$5
|
||||
sta print_y
|
||||
lda #$01
|
||||
sta print_pal
|
||||
jsr hiprint
|
||||
time_update
|
||||
jsr rendertime
|
||||
lda #^stringbuf
|
||||
sta print_bank
|
||||
ldx #!stringbuf
|
||||
stx print_src
|
||||
lda @time_win_x
|
||||
clc
|
||||
adc #$04
|
||||
sta print_x
|
||||
lda @time_win_y
|
||||
clc
|
||||
adc #$03
|
||||
sta print_y
|
||||
stz print_pal
|
||||
jsr hiprint
|
||||
lda time_sel
|
||||
asl
|
||||
clc
|
||||
adc time_sel
|
||||
xba
|
||||
lda #$00
|
||||
xba
|
||||
tax
|
||||
lda !timebox_data, x
|
||||
clc
|
||||
adc #$04
|
||||
adc @time_win_x
|
||||
sta bar_xl
|
||||
lda @time_win_y
|
||||
adc #$02
|
||||
sta bar_yl
|
||||
inx
|
||||
lda !timebox_data, x
|
||||
sta bar_wl
|
||||
inx
|
||||
lda !timebox_data, x
|
||||
sta time_ptr
|
||||
timeloop1
|
||||
lda isr_done
|
||||
lsr
|
||||
bcc timeloop1
|
||||
stz isr_done
|
||||
jsr read_pad
|
||||
lda #$01
|
||||
and pad1trig+1
|
||||
bne tkey_right
|
||||
lda #$02
|
||||
and pad1trig+1
|
||||
bne tkey_left
|
||||
lda #$04
|
||||
and pad1trig+1
|
||||
bne tkey_down
|
||||
lda #$08
|
||||
and pad1trig+1
|
||||
bne tkey_up
|
||||
lda #$80
|
||||
and pad1trig+1
|
||||
bne tkey_b
|
||||
lda #$80
|
||||
and pad1trig
|
||||
bne tkey_a
|
||||
; do stuff
|
||||
lda time_exit
|
||||
bne timesave
|
||||
; set clock
|
||||
lda time_cancel
|
||||
bne timenosave
|
||||
beq timeloop1
|
||||
timesave
|
||||
jsr settime
|
||||
timenosave
|
||||
; restore text area
|
||||
jsr restore_screen
|
||||
plp
|
||||
rtl
|
||||
|
||||
tkey_b
|
||||
inc time_cancel
|
||||
jmp time_update
|
||||
|
||||
tkey_a
|
||||
inc time_exit
|
||||
jmp time_update
|
||||
|
||||
tkey_left
|
||||
jsr time_key_left
|
||||
jmp time_update
|
||||
|
||||
tkey_right
|
||||
jsr time_key_right
|
||||
jmp time_update
|
||||
|
||||
tkey_up
|
||||
jsr time_key_up
|
||||
jmp time_update
|
||||
|
||||
tkey_down
|
||||
jsr time_key_down
|
||||
jmp time_update
|
||||
|
||||
time_key_left
|
||||
lda time_sel
|
||||
beq +
|
||||
dec time_sel
|
||||
+
|
||||
rts
|
||||
|
||||
time_key_right
|
||||
lda time_sel
|
||||
cmp #5
|
||||
beq +
|
||||
inc time_sel
|
||||
+
|
||||
rts
|
||||
|
||||
time_key_up
|
||||
lda time_ptr
|
||||
cmp #4
|
||||
beq time_inc_hour_jmp
|
||||
cmp #6
|
||||
beq time_inc_day_jmp
|
||||
cmp #8
|
||||
beq time_inc_mon_jmp
|
||||
cmp #9
|
||||
beq time_inc_year_jmp
|
||||
xba
|
||||
lda #$00
|
||||
xba
|
||||
tax
|
||||
lda !time_s1, x
|
||||
inc
|
||||
cmp #$0a
|
||||
bmi time_inc_minsec1_normal
|
||||
stz !time_s1, x
|
||||
lda !time_s10, x
|
||||
inc
|
||||
cmp #$06
|
||||
bmi time_inc_minsec10_normal
|
||||
stz !time_s10, x
|
||||
bra +
|
||||
time_inc_minsec10_normal
|
||||
sta !time_s10, x
|
||||
bra +
|
||||
time_inc_minsec1_normal
|
||||
sta !time_s1, x
|
||||
+
|
||||
rts
|
||||
|
||||
time_inc_hour_jmp
|
||||
jsr time_inc_hour
|
||||
rts
|
||||
|
||||
time_inc_day_jmp
|
||||
jsr time_inc_day
|
||||
rts
|
||||
|
||||
time_inc_mon_jmp
|
||||
jsr time_inc_mon
|
||||
rts
|
||||
|
||||
time_inc_year_jmp
|
||||
jsr time_inc_year
|
||||
lda time_mon
|
||||
jsr time_adjust_mon
|
||||
rts
|
||||
|
||||
time_inc_hour
|
||||
lda time_h10
|
||||
cmp #$02
|
||||
bne time_inc_hour_normal
|
||||
lda time_h1
|
||||
inc
|
||||
cmp #$04
|
||||
bmi +
|
||||
stz time_h1
|
||||
stz time_h10
|
||||
rts
|
||||
+
|
||||
sta time_h1
|
||||
rts
|
||||
time_inc_hour_normal
|
||||
lda time_h1
|
||||
inc
|
||||
cmp #$0a
|
||||
bmi +
|
||||
stz time_h1
|
||||
inc time_h10
|
||||
rts
|
||||
+
|
||||
sta time_h1
|
||||
rts
|
||||
|
||||
time_inc_day
|
||||
lda time_mon
|
||||
dec
|
||||
asl
|
||||
xba
|
||||
lda #$00
|
||||
xba
|
||||
tax
|
||||
lda !time_month, x
|
||||
cmp time_d10
|
||||
bne time_inc_day_normal
|
||||
inx
|
||||
jsr is_leapyear_feb
|
||||
lda !time_month, x
|
||||
dec
|
||||
adc #$00
|
||||
cmp time_d1
|
||||
bpl +
|
||||
stz time_d1
|
||||
stz time_d10
|
||||
+
|
||||
inc time_d1
|
||||
rts
|
||||
time_inc_day_normal
|
||||
lda time_d1
|
||||
inc
|
||||
cmp #$0a
|
||||
bmi +
|
||||
stz time_d1
|
||||
inc time_d10
|
||||
rts
|
||||
+
|
||||
sta time_d1
|
||||
rts
|
||||
|
||||
time_inc_mon
|
||||
lda time_mon
|
||||
inc
|
||||
cmp #13
|
||||
bmi +
|
||||
lda #$01
|
||||
+
|
||||
jsr time_adjust_mon
|
||||
rts
|
||||
|
||||
time_adjust_mon
|
||||
sta time_mon
|
||||
dec
|
||||
asl
|
||||
xba
|
||||
lda #$00
|
||||
xba
|
||||
tax
|
||||
lda time_d10
|
||||
cmp !time_month, x
|
||||
bcs time_mon_adjust
|
||||
rts
|
||||
time_mon_adjust
|
||||
php
|
||||
inx
|
||||
lda !time_month, x
|
||||
pha
|
||||
jsr is_leapyear_feb ; c=1 -> a leapyear february
|
||||
pla
|
||||
adc #$00
|
||||
plp
|
||||
bne time_mon_doadjust
|
||||
cmp time_d1
|
||||
bcs +
|
||||
time_mon_doadjust
|
||||
sta time_d1
|
||||
dex
|
||||
lda !time_month, x
|
||||
sta time_d10
|
||||
+
|
||||
rts
|
||||
|
||||
time_inc_year
|
||||
lda time_y1
|
||||
inc
|
||||
cmp #$0a
|
||||
bmi time_inc_y1_normal
|
||||
stz time_y1
|
||||
lda time_y10
|
||||
inc
|
||||
cmp #$0a
|
||||
bmi time_inc_y10_normal
|
||||
stz time_y10
|
||||
inc time_y100
|
||||
rts
|
||||
time_inc_y10_normal
|
||||
sta time_y10
|
||||
rts
|
||||
time_inc_y1_normal
|
||||
sta time_y1
|
||||
rts
|
||||
|
||||
|
||||
time_key_down
|
||||
lda time_ptr
|
||||
cmp #4
|
||||
beq time_dec_hour_jmp
|
||||
cmp #6
|
||||
beq time_dec_day_jmp
|
||||
cmp #8
|
||||
beq time_dec_mon_jmp
|
||||
cmp #9
|
||||
beq time_dec_year_jmp
|
||||
xba
|
||||
lda #$00
|
||||
xba
|
||||
tax
|
||||
lda !time_s1, x
|
||||
dec
|
||||
cmp #$ff
|
||||
bne time_dec_minsec1_normal
|
||||
lda #$09
|
||||
sta !time_s1, x
|
||||
lda !time_s10, x
|
||||
dec
|
||||
cmp #$ff
|
||||
bne time_dec_minsec10_normal
|
||||
lda #$05
|
||||
sta !time_s10, x
|
||||
bra +
|
||||
time_dec_minsec10_normal
|
||||
sta !time_s10, x
|
||||
bra +
|
||||
time_dec_minsec1_normal
|
||||
sta !time_s1, x
|
||||
+
|
||||
rts
|
||||
|
||||
time_dec_hour_jmp
|
||||
jsr time_dec_hour
|
||||
rts
|
||||
|
||||
time_dec_day_jmp
|
||||
jsr time_dec_day
|
||||
rts
|
||||
|
||||
time_dec_mon_jmp
|
||||
jsr time_dec_mon
|
||||
rts
|
||||
|
||||
time_dec_year_jmp
|
||||
jsr time_dec_year
|
||||
lda time_mon
|
||||
jsr time_adjust_mon
|
||||
rts
|
||||
|
||||
time_dec_hour
|
||||
lda time_h1
|
||||
dec
|
||||
cmp #$ff
|
||||
bne time_dec_h1_normal
|
||||
lda time_h10
|
||||
bne time_dec_h10_normal
|
||||
lda #$02
|
||||
sta time_h10
|
||||
lda #$03
|
||||
sta time_h1
|
||||
rts
|
||||
time_dec_h10_normal
|
||||
lda #$09
|
||||
sta time_h1
|
||||
dec time_h10
|
||||
rts
|
||||
time_dec_h1_normal
|
||||
sta time_h1
|
||||
rts
|
||||
|
||||
time_dec_day
|
||||
lda time_d10
|
||||
beq +
|
||||
lda time_d1
|
||||
dec
|
||||
cmp #$ff
|
||||
bne time_dec_d1_normal
|
||||
bra time_dec_cont
|
||||
+ lda time_d1
|
||||
dec
|
||||
bne time_dec_d1_normal
|
||||
time_dec_cont
|
||||
lda time_d10
|
||||
bne time_dec_d10_normal
|
||||
lda time_mon
|
||||
dec
|
||||
asl
|
||||
ldx #$0000
|
||||
tax
|
||||
lda !time_month, x
|
||||
sta time_d10
|
||||
inx
|
||||
lda !time_month, x
|
||||
pha
|
||||
jsr is_leapyear_feb
|
||||
pla
|
||||
adc #$00
|
||||
sta time_d1
|
||||
rts
|
||||
time_dec_d10_normal
|
||||
lda #$09
|
||||
sta time_d1
|
||||
dec time_d10
|
||||
rts
|
||||
time_dec_d1_normal
|
||||
sta time_d1
|
||||
rts
|
||||
|
||||
time_dec_mon
|
||||
lda time_mon
|
||||
dec
|
||||
bne +
|
||||
lda #12
|
||||
+
|
||||
jsr time_adjust_mon
|
||||
rts
|
||||
|
||||
time_dec_year
|
||||
lda time_y1
|
||||
dec
|
||||
cmp #$ff
|
||||
bne time_dec_y1_normal
|
||||
lda #$09
|
||||
sta time_y1
|
||||
lda time_y10
|
||||
dec
|
||||
cmp #$ff
|
||||
bne time_dec_y10_normal
|
||||
lda #$09
|
||||
sta time_y10
|
||||
dec time_y100
|
||||
rts
|
||||
time_dec_y10_normal
|
||||
sta time_y10
|
||||
rts
|
||||
time_dec_y1_normal
|
||||
sta time_y1
|
||||
rts
|
||||
|
||||
rts
|
||||
|
||||
gettime
|
||||
lda #$0d
|
||||
sta $2801
|
||||
lda $2800
|
||||
lda $2800
|
||||
sta time_s1
|
||||
lda $2800
|
||||
sta time_s10
|
||||
lda $2800
|
||||
sta time_m1
|
||||
lda $2800
|
||||
sta time_m10
|
||||
lda $2800
|
||||
sta time_h1
|
||||
lda $2800
|
||||
sta time_h10
|
||||
lda $2800
|
||||
sta time_d1
|
||||
lda $2800
|
||||
sta time_d10
|
||||
lda $2800
|
||||
sta time_mon
|
||||
lda $2800
|
||||
sta time_y1
|
||||
lda $2800
|
||||
sta time_y10
|
||||
lda $2800
|
||||
sta time_y100
|
||||
rts
|
||||
|
||||
rendertime
|
||||
ldx #!stringbuf
|
||||
lda time_y100
|
||||
and #$0f
|
||||
cmp #$0a
|
||||
bpl y_skip1
|
||||
clc
|
||||
adc #$30
|
||||
sta !1,x
|
||||
lda #$31
|
||||
sta !0,x
|
||||
bra y_skip2
|
||||
y_skip1
|
||||
clc
|
||||
adc #$26
|
||||
sta !1,x
|
||||
lda #$32
|
||||
sta !0,x
|
||||
y_skip2
|
||||
inx
|
||||
inx
|
||||
lda time_y10
|
||||
and #$0f
|
||||
clc
|
||||
adc #$30
|
||||
sta !0,x
|
||||
inx
|
||||
lda time_y1
|
||||
and #$0f
|
||||
clc
|
||||
adc #$30
|
||||
sta !0,x
|
||||
inx
|
||||
lda #$2d
|
||||
sta !0,x
|
||||
inx
|
||||
lda time_mon
|
||||
and #$0f
|
||||
cmp #$0a
|
||||
bpl mon_skip1
|
||||
clc
|
||||
adc #$30
|
||||
sta !1,x
|
||||
lda #$30
|
||||
sta !0,x
|
||||
bra mon_skip2
|
||||
mon_skip1
|
||||
clc
|
||||
adc #$26
|
||||
sta !1,x
|
||||
lda #$31
|
||||
sta !0,x
|
||||
mon_skip2
|
||||
inx
|
||||
inx
|
||||
lda #$2d
|
||||
sta !0,x
|
||||
inx
|
||||
lda time_d10
|
||||
clc
|
||||
adc #$30
|
||||
sta !0,x
|
||||
inx
|
||||
lda time_d1
|
||||
clc
|
||||
adc #$30
|
||||
sta !0,x
|
||||
inx
|
||||
lda #$20
|
||||
sta !0,x
|
||||
inx
|
||||
lda time_h10
|
||||
clc
|
||||
adc #$30
|
||||
sta !0,x
|
||||
inx
|
||||
lda time_h1
|
||||
clc
|
||||
adc #$30
|
||||
sta !0,x
|
||||
inx
|
||||
lda #$3a
|
||||
sta !0,x
|
||||
inx
|
||||
lda time_m10
|
||||
clc
|
||||
adc #$30
|
||||
sta !0,x
|
||||
inx
|
||||
lda time_m1
|
||||
clc
|
||||
adc #$30
|
||||
sta !0,x
|
||||
inx
|
||||
lda #$3a
|
||||
sta !0,x
|
||||
inx
|
||||
lda time_s10
|
||||
clc
|
||||
adc #$30
|
||||
sta !0,x
|
||||
inx
|
||||
lda time_s1
|
||||
clc
|
||||
adc #$30
|
||||
sta !0,x
|
||||
stz !1,x
|
||||
rts
|
||||
|
||||
is_leapyear_feb
|
||||
lda time_mon
|
||||
cmp #$02
|
||||
bne is_leapyear_feb_no
|
||||
lda time_y10
|
||||
asl
|
||||
sta time_tmp
|
||||
asl
|
||||
asl
|
||||
clc
|
||||
adc time_tmp
|
||||
clc
|
||||
adc time_y1
|
||||
sta time_tmp
|
||||
and #$03
|
||||
beq is_leapyear_4th ; every 4th year
|
||||
is_leapyear_feb_no
|
||||
clc
|
||||
rts
|
||||
|
||||
is_leapyear_4th ; leapyear candidate
|
||||
lda time_tmp ; year=00?
|
||||
beq + ; then check century
|
||||
sec ; else it's always a leapyear
|
||||
rts
|
||||
+
|
||||
lda time_y100 ; century divisible by 4?
|
||||
clc
|
||||
adc #10
|
||||
and #$03
|
||||
beq is_leapyear_400th
|
||||
clc
|
||||
rts
|
||||
|
||||
is_leapyear_400th
|
||||
sec
|
||||
rts
|
||||
|
||||
settime
|
||||
lda time_y100
|
||||
sta @AVR_PARAM
|
||||
lda time_y10
|
||||
sta @AVR_PARAM+1
|
||||
lda time_y1
|
||||
sta @AVR_PARAM+2
|
||||
lda time_mon
|
||||
sta @AVR_PARAM+3
|
||||
lda time_d10
|
||||
sta @AVR_PARAM+4
|
||||
lda time_d1
|
||||
sta @AVR_PARAM+5
|
||||
lda time_h10
|
||||
sta @AVR_PARAM+6
|
||||
lda time_h1
|
||||
sta @AVR_PARAM+7
|
||||
lda time_m10
|
||||
sta @AVR_PARAM+8
|
||||
lda time_m1
|
||||
sta @AVR_PARAM+9
|
||||
lda time_s10
|
||||
sta @AVR_PARAM+10
|
||||
lda time_s1
|
||||
sta @AVR_PARAM+11
|
||||
lda #$02 ; set clock
|
||||
sta @AVR_CMD
|
||||
rts
|
||||
|
||||
printtime:
|
||||
jsr gettime
|
||||
jsr rendertime
|
||||
lda listdisp
|
||||
clc
|
||||
adc #$0a
|
||||
clc
|
||||
adc vidmode
|
||||
sta print_y
|
||||
lda #$2b
|
||||
sta print_x
|
||||
lda #$40
|
||||
sta print_count
|
||||
lda #^stringbuf
|
||||
sta print_bank
|
||||
ldx #!stringbuf
|
||||
stx print_src
|
||||
stz print_pal
|
||||
jsr hiprint
|
||||
rts
|
||||
24
snes/utils/mkmap.sh
Executable file
24
snes/utils/mkmap.sh
Executable file
@ -0,0 +1,24 @@
|
||||
#!/bin/bash
|
||||
|
||||
args=("$@")
|
||||
objcount=0
|
||||
|
||||
grep object_ link.log | \
|
||||
sed -e 's/object_//g; s/_code//g; s/_data//g' | \
|
||||
while read obj; do
|
||||
objcount=$((objcount+1))
|
||||
read base idx <<< "$obj"
|
||||
base="0x${base}"
|
||||
fn=${args[$idx-1]}
|
||||
echo ======$fn, base=$base====== > ${fn%%.*}.map
|
||||
sed -e '/^Externs/,$d;/^Labels/d' < $fn.log | \
|
||||
while read line; do
|
||||
read addr label <<< "$line"
|
||||
addr="0x$addr"
|
||||
decaddr=`printf "%d" $addr`
|
||||
[ "$decaddr" -gt "65535" ] && base=0
|
||||
ea=`printf "%X" $((base+addr))`
|
||||
echo $ea $label >> ${fn%%.*}.map
|
||||
done
|
||||
done
|
||||
|
||||
318
src/Makefile
Normal file
318
src/Makefile
Normal file
@ -0,0 +1,318 @@
|
||||
# Hey Emacs, this is a -*- makefile -*-
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# WinAVR Makefile Template written by Eric B. Weddington, Joerg Wunsch, et al.
|
||||
#
|
||||
# Released to the Public Domain
|
||||
#
|
||||
# Additional material for this makefile was written by:
|
||||
# Peter Fleury
|
||||
# Tim Henigan
|
||||
# Colin O'Flynn
|
||||
# Reiner Patommel
|
||||
# Markus Pfaff
|
||||
# Sander Pool
|
||||
# Frederik Rouleau
|
||||
# Carlos Lamas
|
||||
#
|
||||
#
|
||||
# Extensively modified for sd2iec and later adapted for ARM by Ingo Korb
|
||||
#
|
||||
# To rebuild project do "make clean" then "make all".
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
# Read configuration file
|
||||
ifdef CONFIG
|
||||
CONFIGSUFFIX = $(CONFIG:config%=%)
|
||||
else
|
||||
CONFIG = config
|
||||
CONFIGSUFFIX =
|
||||
endif
|
||||
|
||||
# Enable verbose compilation with "make V=1"
|
||||
ifdef V
|
||||
Q :=
|
||||
E := @:
|
||||
else
|
||||
Q := @
|
||||
E := @echo
|
||||
endif
|
||||
|
||||
# Include the configuration file
|
||||
include $(CONFIG)
|
||||
|
||||
# Directory for all generated files
|
||||
OBJDIR := obj$(CONFIGSUFFIX)
|
||||
|
||||
# Output format. (can be srec, ihex, binary)
|
||||
FORMAT = binary
|
||||
|
||||
# Linker script
|
||||
LINKERSCRIPT = lpc1754.ld
|
||||
|
||||
# Target file name (without extension).
|
||||
TARGET = $(OBJDIR)/sd2snes
|
||||
|
||||
|
||||
# List C source files here. (C dependencies are automatically generated.)
|
||||
SRC = main.c ff.c ccsbcs.c clock.c uart.c power.c led.c timer.c printf.c spi.c fileops.c rtc.c fpga.c fpga_spi.c snes.c smc.c memory.c filetypes.c faulthandler.c sort.c crc32.c cic.c cli.c xmodem.c irq.c rle.c sdnative.c msu1.c crc16.c sysinfo.c
|
||||
|
||||
# usbcontrol.c usb_hid.c usbhw_lpc.c usbinit.c usbstdreq.c
|
||||
|
||||
|
||||
# List Assembler source files here.
|
||||
# Make them always end in a capital .S. Files ending in a lowercase .s
|
||||
# will not be considered source files but generated files (assembler
|
||||
# output from the compiler), and will be deleted upon "make clean"!
|
||||
# Even though the DOS/Win* filesystem matches both .s and .S the same,
|
||||
# it will preserve the spelling of the filenames, and gcc itself does
|
||||
# care about how the name is spelled on its command-line.
|
||||
ASRC = startup.S crc.S
|
||||
|
||||
|
||||
# Optimization level, can be [0, 1, 2, 3, s].
|
||||
# 0 = turn off optimization. s = optimize for size.
|
||||
# (Note: 3 is not always the best optimization level. See avr-libc FAQ.)
|
||||
# Use s -mcall-prologues when you really need size...
|
||||
#OPT = 2
|
||||
OPT = 2
|
||||
|
||||
# Debugging format.
|
||||
DEBUG = dwarf-2
|
||||
|
||||
|
||||
# List any extra directories to look for include files here.
|
||||
# Each directory must be seperated by a space.
|
||||
# Use forward slashes for directory separators.
|
||||
# For a directory that has spaces, enclose it in quotes.
|
||||
EXTRAINCDIRS =
|
||||
|
||||
|
||||
# Compiler flag to set the C Standard level.
|
||||
# c89 = "ANSI" C
|
||||
# gnu89 = c89 plus GCC extensions
|
||||
# c99 = ISO C99 standard (not yet fully implemented)
|
||||
# gnu99 = c99 plus GCC extensions
|
||||
CSTANDARD = -std=gnu99
|
||||
|
||||
|
||||
# Place -D or -U options here
|
||||
CDEFS = -DF_OSC=$(CONFIG_MCU_FOSC)UL
|
||||
|
||||
|
||||
# Place -I options here
|
||||
CINCS =
|
||||
|
||||
|
||||
# CPU-specific flags
|
||||
ifndef CPUFLAGS
|
||||
CPUFLAGS := -mthumb -mcpu=cortex-m3
|
||||
endif
|
||||
|
||||
ifndef ARCH
|
||||
ARCH := arm-none-eabi
|
||||
endif
|
||||
|
||||
# Define programs and commands.
|
||||
# CC must be defined here to generate the correct CFLAGS
|
||||
SHELL = sh
|
||||
CC = $(ARCH)-gcc
|
||||
OBJCOPY = $(ARCH)-objcopy
|
||||
OBJDUMP = $(ARCH)-objdump
|
||||
SIZE = $(ARCH)-size
|
||||
NM = $(ARCH)-nm
|
||||
REMOVE = rm -f
|
||||
COPY = cp
|
||||
AWK = awk
|
||||
|
||||
|
||||
#---------------- Compiler Options ----------------
|
||||
# -g*: generate debugging information
|
||||
# -O*: optimization level
|
||||
# -f...: tuning, see GCC manual and avr-libc documentation
|
||||
# -Wall...: warning level
|
||||
# -Wa,...: tell GCC to pass this to the assembler.
|
||||
# -adhlns...: create assembler listing
|
||||
CFLAGS = -g$(DEBUG)
|
||||
CFLAGS += $(CDEFS) $(CINCS)
|
||||
CFLAGS += -O$(OPT)
|
||||
CFLAGS += $(CPUFLAGS) -nostartfiles
|
||||
#CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
|
||||
CFLAGS += -Wall -Wstrict-prototypes -Werror
|
||||
CFLAGS += -Wa,-adhlns=$(OBJDIR)/$(<:.c=.lst)
|
||||
CFLAGS += -I$(OBJDIR)
|
||||
CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
|
||||
CFLAGS += $(CSTANDARD)
|
||||
CFLAGS += -ffunction-sections -fdata-sections
|
||||
|
||||
|
||||
#---------------- Assembler Options ----------------
|
||||
# -Wa,...: tell GCC to pass this to the assembler.
|
||||
# -ahlms: create listing
|
||||
# -gstabs: have the assembler create line number information; note that
|
||||
# for use in COFF files, additional information about filenames
|
||||
# and function names needs to be present in the assembler source
|
||||
# files -- see avr-libc docs [FIXME: not yet described there]
|
||||
ASFLAGS = $(CPUFLAGS) -Wa,-adhlns=$(OBJDIR)/$(<:.S=.lst),-gstabs -I$(OBJDIR)
|
||||
|
||||
|
||||
#---------------- Linker Options ----------------
|
||||
# -Wl,...: tell GCC to pass this to linker.
|
||||
# -Map: create map file
|
||||
# --cref: add cross reference to map file
|
||||
LDFLAGS = -Wl,-Map=$(TARGET).map,--cref
|
||||
LDFLAGS += -T$(LINKERSCRIPT)
|
||||
LDFLAGS += -Wl,--gc-sections
|
||||
ifeq ($(CONFIG_LINKER_RELAX),y)
|
||||
LDFLAGS += -Wl,-O9,--relax
|
||||
endif
|
||||
|
||||
|
||||
#============================================================================
|
||||
|
||||
|
||||
# De-dupe the list of C source files
|
||||
CSRC := $(sort $(SRC))
|
||||
|
||||
# Define all object files.
|
||||
OBJ := $(patsubst %,$(OBJDIR)/%,$(CSRC:.c=.o) $(ASRC:.S=.o))
|
||||
|
||||
# Define all listing files.
|
||||
LST := $(patsubst %,$(OBJDIR)/%,$(CSRC:.c=.lst) $(ASRC:.S=.lst))
|
||||
|
||||
|
||||
# Compiler flags to generate dependency files.
|
||||
GENDEPFLAGS = -MMD -MP -MF .dep/$(@F).d
|
||||
|
||||
|
||||
# Combine all necessary flags and optional flags.
|
||||
# Add target processor to flags.
|
||||
ALL_CFLAGS = -I. $(CFLAGS) $(GENDEPFLAGS)
|
||||
ALL_ASFLAGS = -I. -x assembler-with-cpp $(ASFLAGS) $(CDEFS)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# Default target.
|
||||
all: build
|
||||
|
||||
build: elf bin hex
|
||||
$(E) " SIZE $(TARGET).elf"
|
||||
$(Q)$(ELFSIZE)|grep -v debug
|
||||
cp $(TARGET).bin $(OBJDIR)/firmware.img
|
||||
utils/genhdr $(OBJDIR)/firmware.img SNSD $(CONFIG_FWVER)
|
||||
|
||||
elf: $(TARGET).elf
|
||||
bin: $(TARGET).bin
|
||||
hex: $(TARGET).hex
|
||||
eep: $(TARGET).eep
|
||||
lss: $(TARGET).lss
|
||||
sym: $(TARGET).sym
|
||||
|
||||
# # A little helper target for the maintainer =)
|
||||
# copy2card:
|
||||
# cp $(TARGET).bin /mbed/hw_LPC1768.bin
|
||||
|
||||
|
||||
program: build
|
||||
utils/lpcchksum $(TARGET).bin
|
||||
openocd -f openocd-usb.cfg -f lpc1754.cfg -f flash.cfg
|
||||
|
||||
debug: build
|
||||
openocd -f openocd-usb.cfg -f lpc1754.cfg
|
||||
|
||||
reset:
|
||||
openocd -f openocd-usb.cfg -f lpc1754.cfg -f reset.cfg
|
||||
|
||||
# Display size of file.
|
||||
HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex
|
||||
ELFSIZE = $(SIZE) -A $(TARGET).elf
|
||||
|
||||
|
||||
|
||||
# Generate autoconf.h from config
|
||||
.PRECIOUS : $(OBJDIR)/autoconf.h
|
||||
$(OBJDIR)/autoconf.h: $(CONFIG) | $(OBJDIR)
|
||||
$(E) " CONF2H $(CONFIG)"
|
||||
$(Q)$(AWK) -f conf2h.awk $(CONFIG) > $(OBJDIR)/autoconf.h
|
||||
|
||||
# Create final output files from ELF output file.
|
||||
$(OBJDIR)/%.bin: $(OBJDIR)/%.elf
|
||||
$(E) " BIN $@"
|
||||
$(Q)$(OBJCOPY) -O binary $< $@
|
||||
|
||||
$(OBJDIR)/%.hex: $(OBJDIR)/%.elf
|
||||
$(E) " HEX $@"
|
||||
$(Q)$(OBJCOPY) -O $(FORMAT) $< $@
|
||||
|
||||
# Create extended listing file from ELF output file.
|
||||
$(OBJDIR)/%.lss: $(OBJDIR)/%.elf
|
||||
$(E) " LSS $<"
|
||||
$(Q)$(OBJDUMP) -h -S $< > $@
|
||||
|
||||
# Create a symbol table from ELF output file.
|
||||
$(OBJDIR)/%.sym: $(OBJDIR)/%.elf
|
||||
$(E) " SYM $<"
|
||||
$(E)$(NM) -n $< > $@
|
||||
|
||||
|
||||
# Link: create ELF output file from object files.
|
||||
.SECONDARY : $(TARGET).elf
|
||||
.PRECIOUS : $(OBJ)
|
||||
$(TARGET).elf : $(OBJ)
|
||||
$(E) " LINK $@"
|
||||
$(Q)$(CC) $(ALL_CFLAGS) $^ --output $@ $(LDFLAGS)
|
||||
|
||||
|
||||
# Compile: create object files from C source files.
|
||||
$(OBJDIR)/%.o : %.c | $(OBJDIR) $(OBJDIR)/autoconf.h
|
||||
$(E) " CC $<"
|
||||
$(Q)$(CC) -c $(ALL_CFLAGS) $< -o $@
|
||||
|
||||
|
||||
# Compile: create assembler files from C source files.
|
||||
$(OBJDIR)/%.s : %.c | $(OBJDIR) $(OBJDIR)/autoconf.h
|
||||
$(CC) -S $(ALL_CFLAGS) $< -o $@
|
||||
|
||||
|
||||
# Assemble: create object files from assembler source files.
|
||||
$(OBJDIR)/%.o : %.S | $(OBJDIR) $(OBJDIR)/autoconf.h
|
||||
$(E) " AS $<"
|
||||
$(Q)$(CC) -c $(ALL_ASFLAGS) $< -o $@
|
||||
|
||||
# Create preprocessed source for use in sending a bug report.
|
||||
$(OBJDIR)/%.i : %.c | $(OBJDIR) $(OBJDIR)/autoconf.h
|
||||
$(CC) -E -mmcu=$(MCU) -I. $(CFLAGS) $< -o $@
|
||||
|
||||
# Create the output directory
|
||||
$(OBJDIR) :
|
||||
$(E) " MKDIR $(OBJDIR)"
|
||||
$(Q)mkdir $(OBJDIR)
|
||||
|
||||
# Target: clean project.
|
||||
clean: begin clean_list end
|
||||
|
||||
clean_list :
|
||||
$(E) " CLEAN"
|
||||
$(Q)$(REMOVE) $(TARGET).hex
|
||||
$(Q)$(REMOVE) $(TARGET).bin
|
||||
$(Q)$(REMOVE) $(TARGET).elf
|
||||
$(Q)$(REMOVE) $(TARGET).map
|
||||
$(Q)$(REMOVE) $(TARGET).sym
|
||||
$(Q)$(REMOVE) $(TARGET).lss
|
||||
$(Q)$(REMOVE) $(OBJ)
|
||||
$(Q)$(REMOVE) $(OBJDIR)/autoconf.h
|
||||
$(Q)$(REMOVE) $(OBJDIR)/*.bin
|
||||
$(Q)$(REMOVE) $(LST)
|
||||
$(Q)$(REMOVE) $(CSRC:.c=.s)
|
||||
$(Q)$(REMOVE) $(CSRC:.c=.d)
|
||||
$(Q)$(REMOVE) .dep/*
|
||||
-$(Q)rmdir $(OBJDIR)
|
||||
|
||||
# Include the dependency files.
|
||||
-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*)
|
||||
|
||||
# Listing of phony targets.
|
||||
.PHONY : all begin finish end sizebefore sizeafter \
|
||||
build elf hex lss sym clean clean_list
|
||||
85
src/README
Normal file
85
src/README
Normal file
@ -0,0 +1,85 @@
|
||||
How to build:
|
||||
|
||||
a) Build requirements
|
||||
* make
|
||||
* Cortex M3 toolchain
|
||||
* snescom/sneslink
|
||||
* Xilinx FPGA synthesis tool (e.g. ISE WebPack)
|
||||
* PIC assembler
|
||||
|
||||
b) Cortex M3 toolchain
|
||||
* obtain the cm3-toolchain builder:
|
||||
git clone http://snowcat.de/toolchain-cm3.git/
|
||||
* build the cm3-toolchain. Some tools, libraries, and headers are required,
|
||||
including but probably not limited to:
|
||||
- libz-dev
|
||||
- libcloog-ppl-dev
|
||||
- texinfo
|
||||
- libmpfr-dev
|
||||
- libgmp3-dev
|
||||
- gawk
|
||||
- bison
|
||||
- recode
|
||||
- flex
|
||||
- libncurses5-dev
|
||||
- libexpat-dev
|
||||
- make
|
||||
- gcc
|
||||
Newer gccs complain when compiling binutils, so you may have to add
|
||||
'--disable-werror' to the compiler options for binutils in the Makefile.
|
||||
The Makefile will install immediately so make sure you can write to the
|
||||
installation directory.
|
||||
|
||||
c) snescom/sneslink
|
||||
* http://bisqwit.iki.fi/source/snescom.html
|
||||
|
||||
d) ISE WebPack
|
||||
* http://www.xilinx.com/products/design-tools/ise-design-suite/ise-webpack.htm
|
||||
|
||||
e) PIC assembler
|
||||
* e.g. GPUTILS, http://gputils.sourceforge.net/
|
||||
|
||||
f) general order of operations
|
||||
1) program the PIC (cic/supercic/supercic-key.asm)
|
||||
2) build and program the bootloader.
|
||||
3) build the firmware and copy it to the memory card
|
||||
4) build the snes menu and copy it to the memory card
|
||||
5) build and compress the FPGA configuration and copy it to the memory card
|
||||
6) insert memory card, power on; the bootloader should begin flashing the
|
||||
firmware and boot it
|
||||
|
||||
1) Programming the PIC
|
||||
Use a PIC assembler + programmer of your choice and program a PIC12F629 with
|
||||
cic/supercic/supercic-key.asm. Make sure that the clock source is set to
|
||||
EC_OSC and MCLRE is disabled.
|
||||
After programming you can solder the PIC to the board and short JP401.
|
||||
Open JP401 in case you need to reprogram the PIC on board.
|
||||
|
||||
2) Building & programming the bootloader
|
||||
The Makefile is prepared for JTAG programming using OpenOCD 0.4 and an FT2232
|
||||
based USB-JTAG adapter.
|
||||
Connect a JTAG cable to J401 (14-pin header). The pinout is printed on the
|
||||
board. cd to src/bootldr and make && make program.
|
||||
|
||||
3) Building the firmware
|
||||
cd to src/utils and make.
|
||||
cd to src/ and make.
|
||||
You should obtain a firmware file called obj/firmware.img. Copy this file to
|
||||
<sdcard>/sd2snes/firmware.img.
|
||||
|
||||
4) Building the SNES menu
|
||||
snescom is required.
|
||||
cd to snes/ and make.
|
||||
Copy the resulting file menu.bin to <sdcard>/sd2snes/menu.bin.
|
||||
|
||||
5) Building the FPGA configuration
|
||||
Compile the RLE compressor in utils/rle.c:
|
||||
$ gcc -Wall -o rle rle.c
|
||||
|
||||
Load verilog/sd2snes/sd2snes.xise in Xilinx ISE (or create your own project).
|
||||
Target is a XC3S400-4PQ208.
|
||||
Generate the programming file and compress it using utils/rle.c:
|
||||
$ rle main.bit fpga_base.bit
|
||||
|
||||
Copy fpga_base.bit to <sdcard>/sd2snes/fpga_base.bit
|
||||
|
||||
320
src/bootldr/Makefile
Normal file
320
src/bootldr/Makefile
Normal file
@ -0,0 +1,320 @@
|
||||
# Hey Emacs, this is a -*- makefile -*-
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# WinAVR Makefile Template written by Eric B. Weddington, Joerg Wunsch, et al.
|
||||
#
|
||||
# Released to the Public Domain
|
||||
#
|
||||
# Additional material for this makefile was written by:
|
||||
# Peter Fleury
|
||||
# Tim Henigan
|
||||
# Colin O'Flynn
|
||||
# Reiner Patommel
|
||||
# Markus Pfaff
|
||||
# Sander Pool
|
||||
# Frederik Rouleau
|
||||
# Carlos Lamas
|
||||
#
|
||||
#
|
||||
# Extensively modified for sd2iec and later adapted for ARM by Ingo Korb
|
||||
#
|
||||
# To rebuild project do "make clean" then "make all".
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
# Read configuration file
|
||||
ifdef CONFIG
|
||||
CONFIGSUFFIX = $(CONFIG:config%=%)
|
||||
else
|
||||
CONFIG = config
|
||||
CONFIGSUFFIX =
|
||||
endif
|
||||
|
||||
# Enable verbose compilation with "make V=1"
|
||||
ifdef V
|
||||
Q :=
|
||||
E := @:
|
||||
else
|
||||
Q := @
|
||||
E := @echo
|
||||
endif
|
||||
|
||||
# Include the configuration file
|
||||
include $(CONFIG)
|
||||
|
||||
# Directory for all generated files
|
||||
OBJDIR := obj$(CONFIGSUFFIX)
|
||||
|
||||
# Output format. (can be srec, ihex, binary)
|
||||
FORMAT = binary
|
||||
|
||||
# Linker script
|
||||
LINKERSCRIPT = lpc1754boot.ld
|
||||
|
||||
# Target file name (without extension).
|
||||
TARGET = $(OBJDIR)/sd2snes_bootldr
|
||||
|
||||
|
||||
# List C source files here. (C dependencies are automatically generated.)
|
||||
SRC = timer.c main.c ff.c clock.c uart.c power.c led.c faulthandler.c crc32.c sdnative.c fileops.c iap.c printf.c
|
||||
|
||||
# usbcontrol.c usb_hid.c usbhw_lpc.c usbinit.c usbstdreq.c
|
||||
|
||||
|
||||
# List Assembler source files here.
|
||||
# Make them always end in a capital .S. Files ending in a lowercase .s
|
||||
# will not be considered source files but generated files (assembler
|
||||
# output from the compiler), and will be deleted upon "make clean"!
|
||||
# Even though the DOS/Win* filesystem matches both .s and .S the same,
|
||||
# it will preserve the spelling of the filenames, and gcc itself does
|
||||
# care about how the name is spelled on its command-line.
|
||||
ASRC = startup.S crc.S
|
||||
|
||||
|
||||
# Optimization level, can be [0, 1, 2, 3, s].
|
||||
# 0 = turn off optimization. s = optimize for size.
|
||||
# (Note: 3 is not always the best optimization level. See avr-libc FAQ.)
|
||||
#OPT = 2
|
||||
OPT = s
|
||||
|
||||
# Debugging format.
|
||||
DEBUG = dwarf-2
|
||||
|
||||
|
||||
# List any extra directories to look for include files here.
|
||||
# Each directory must be seperated by a space.
|
||||
# Use forward slashes for directory separators.
|
||||
# For a directory that has spaces, enclose it in quotes.
|
||||
EXTRAINCDIRS =
|
||||
|
||||
|
||||
# Compiler flag to set the C Standard level.
|
||||
# c89 = "ANSI" C
|
||||
# gnu89 = c89 plus GCC extensions
|
||||
# c99 = ISO C99 standard (not yet fully implemented)
|
||||
# gnu99 = c99 plus GCC extensions
|
||||
CSTANDARD = -std=gnu99
|
||||
|
||||
|
||||
# Place -D or -U options here
|
||||
CDEFS = -DF_OSC=$(CONFIG_MCU_FOSC)UL
|
||||
|
||||
|
||||
# Place -I options here
|
||||
CINCS =
|
||||
|
||||
|
||||
# CPU-specific flags
|
||||
ifndef CPUFLAGS
|
||||
CPUFLAGS := -mthumb -mcpu=cortex-m3
|
||||
endif
|
||||
|
||||
ifndef ARCH
|
||||
ARCH := arm-none-eabi
|
||||
endif
|
||||
|
||||
# Define programs and commands.
|
||||
# CC must be defined here to generate the correct CFLAGS
|
||||
SHELL = sh
|
||||
CC = $(ARCH)-gcc
|
||||
OBJCOPY = $(ARCH)-objcopy
|
||||
OBJDUMP = $(ARCH)-objdump
|
||||
SIZE = $(ARCH)-size
|
||||
NM = $(ARCH)-nm
|
||||
REMOVE = rm -f
|
||||
COPY = cp
|
||||
AWK = awk
|
||||
|
||||
|
||||
#---------------- Compiler Options ----------------
|
||||
# -g*: generate debugging information
|
||||
# -O*: optimization level
|
||||
# -f...: tuning, see GCC manual and avr-libc documentation
|
||||
# -Wall...: warning level
|
||||
# -Wa,...: tell GCC to pass this to the assembler.
|
||||
# -adhlns...: create assembler listing
|
||||
CFLAGS = -g$(DEBUG)
|
||||
CFLAGS += $(CDEFS) $(CINCS)
|
||||
CFLAGS += -O$(OPT)
|
||||
CFLAGS += $(CPUFLAGS) -nostartfiles
|
||||
#CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
|
||||
CFLAGS += -Wall -Wstrict-prototypes -Werror
|
||||
CFLAGS += -Wa,-adhlns=$(OBJDIR)/$(<:.c=.lst)
|
||||
CFLAGS += -I$(OBJDIR)
|
||||
CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
|
||||
CFLAGS += $(CSTANDARD)
|
||||
CFLAGS += -ffunction-sections -fdata-sections
|
||||
|
||||
|
||||
#---------------- Assembler Options ----------------
|
||||
# -Wa,...: tell GCC to pass this to the assembler.
|
||||
# -ahlms: create listing
|
||||
# -gstabs: have the assembler create line number information; note that
|
||||
# for use in COFF files, additional information about filenames
|
||||
# and function names needs to be present in the assembler source
|
||||
# files -- see avr-libc docs [FIXME: not yet described there]
|
||||
ASFLAGS = $(CPUFLAGS) -Wa,-adhlns=$(OBJDIR)/$(<:.S=.lst),-gstabs -I$(OBJDIR)
|
||||
|
||||
|
||||
#---------------- Linker Options ----------------
|
||||
# -Wl,...: tell GCC to pass this to linker.
|
||||
# -Map: create map file
|
||||
# --cref: add cross reference to map file
|
||||
LDFLAGS = -Wl,-Map=$(TARGET).map,--cref
|
||||
LDFLAGS += -T$(LINKERSCRIPT)
|
||||
LDFLAGS += -Wl,--gc-sections
|
||||
ifeq ($(CONFIG_LINKER_RELAX),y)
|
||||
LDFLAGS += -Wl,-O9,--relax
|
||||
endif
|
||||
|
||||
|
||||
#============================================================================
|
||||
|
||||
|
||||
# De-dupe the list of C source files
|
||||
CSRC := $(sort $(SRC))
|
||||
|
||||
# Define all object files.
|
||||
OBJ := $(patsubst %,$(OBJDIR)/%,$(CSRC:.c=.o) $(ASRC:.S=.o))
|
||||
|
||||
# Define all listing files.
|
||||
LST := $(patsubst %,$(OBJDIR)/%,$(CSRC:.c=.lst) $(ASRC:.S=.lst))
|
||||
|
||||
|
||||
# Compiler flags to generate dependency files.
|
||||
GENDEPFLAGS = -MMD -MP -MF .dep/$(@F).d
|
||||
|
||||
|
||||
# Combine all necessary flags and optional flags.
|
||||
# Add target processor to flags.
|
||||
ALL_CFLAGS = -I. $(CFLAGS) $(GENDEPFLAGS)
|
||||
ALL_ASFLAGS = -I. -x assembler-with-cpp $(ASFLAGS) $(CDEFS)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# Default target.
|
||||
all: build
|
||||
|
||||
build: elf bin hex
|
||||
$(E) " SIZE $(TARGET).elf"
|
||||
$(Q)$(ELFSIZE)|grep -v debug
|
||||
|
||||
elf: $(TARGET).elf
|
||||
bin: $(TARGET).bin
|
||||
hex: $(TARGET).hex
|
||||
eep: $(TARGET).eep
|
||||
lss: $(TARGET).lss
|
||||
sym: $(TARGET).sym
|
||||
|
||||
# # A little helper target for the maintainer =)
|
||||
# copy2card:
|
||||
# cp $(TARGET).bin /mbed/hw_LPC1768.bin
|
||||
|
||||
|
||||
# utils/lpcchksum $(TARGET).bin
|
||||
fresh: erase program
|
||||
|
||||
program: bin
|
||||
openocd -f openocd-usb.cfg -f lpc1754.cfg -f flash.cfg
|
||||
|
||||
debug: bin
|
||||
openocd -f openocd-usb.cfg -f lpc1754.cfg
|
||||
|
||||
reset:
|
||||
openocd -f openocd-usb.cfg -f lpc1754.cfg -f reset.cfg
|
||||
|
||||
erase:
|
||||
openocd -f openocd-usb.cfg -f lpc1754.cfg -f erase.cfg
|
||||
|
||||
# Display size of file.
|
||||
HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex
|
||||
ELFSIZE = $(SIZE) -A $(TARGET).elf
|
||||
|
||||
|
||||
|
||||
# Generate autoconf.h from config
|
||||
.PRECIOUS : $(OBJDIR)/autoconf.h
|
||||
$(OBJDIR)/autoconf.h: $(CONFIG) | $(OBJDIR)
|
||||
$(E) " CONF2H $(CONFIG)"
|
||||
$(Q)$(AWK) -f conf2h.awk $(CONFIG) > $(OBJDIR)/autoconf.h
|
||||
|
||||
# Create final output files from ELF output file.
|
||||
$(OBJDIR)/%.bin: $(OBJDIR)/%.elf
|
||||
$(E) " BIN $@"
|
||||
$(Q)$(OBJCOPY) -O binary $< $@
|
||||
|
||||
$(OBJDIR)/%.hex: $(OBJDIR)/%.elf
|
||||
$(E) " HEX $@"
|
||||
$(Q)$(OBJCOPY) -O $(FORMAT) $< $@
|
||||
|
||||
# Create extended listing file from ELF output file.
|
||||
$(OBJDIR)/%.lss: $(OBJDIR)/%.elf
|
||||
$(E) " LSS $<"
|
||||
$(Q)$(OBJDUMP) -h -S $< > $@
|
||||
|
||||
# Create a symbol table from ELF output file.
|
||||
$(OBJDIR)/%.sym: $(OBJDIR)/%.elf
|
||||
$(E) " SYM $<"
|
||||
$(E)$(NM) -n $< > $@
|
||||
|
||||
|
||||
# Link: create ELF output file from object files.
|
||||
.SECONDARY : $(TARGET).elf
|
||||
.PRECIOUS : $(OBJ)
|
||||
$(TARGET).elf : $(OBJ)
|
||||
$(E) " LINK $@"
|
||||
$(Q)$(CC) $(ALL_CFLAGS) $^ --output $@ $(LDFLAGS)
|
||||
|
||||
|
||||
# Compile: create object files from C source files.
|
||||
$(OBJDIR)/%.o : %.c | $(OBJDIR) $(OBJDIR)/autoconf.h
|
||||
$(E) " CC $<"
|
||||
$(Q)$(CC) -c $(ALL_CFLAGS) $< -o $@
|
||||
|
||||
|
||||
# Compile: create assembler files from C source files.
|
||||
$(OBJDIR)/%.s : %.c | $(OBJDIR) $(OBJDIR)/autoconf.h
|
||||
$(CC) -S $(ALL_CFLAGS) $< -o $@
|
||||
|
||||
|
||||
# Assemble: create object files from assembler source files.
|
||||
$(OBJDIR)/%.o : %.S | $(OBJDIR) $(OBJDIR)/autoconf.h
|
||||
$(E) " AS $<"
|
||||
$(Q)$(CC) -c $(ALL_ASFLAGS) $< -o $@
|
||||
|
||||
# Create preprocessed source for use in sending a bug report.
|
||||
$(OBJDIR)/%.i : %.c | $(OBJDIR) $(OBJDIR)/autoconf.h
|
||||
$(CC) -E -mmcu=$(MCU) -I. $(CFLAGS) $< -o $@
|
||||
|
||||
# Create the output directory
|
||||
$(OBJDIR) :
|
||||
$(E) " MKDIR $(OBJDIR)"
|
||||
$(Q)mkdir $(OBJDIR)
|
||||
|
||||
# Target: clean project.
|
||||
clean: begin clean_list end
|
||||
|
||||
clean_list :
|
||||
$(E) " CLEAN"
|
||||
$(Q)$(REMOVE) $(TARGET).hex
|
||||
$(Q)$(REMOVE) $(TARGET).bin
|
||||
$(Q)$(REMOVE) $(TARGET).elf
|
||||
$(Q)$(REMOVE) $(TARGET).map
|
||||
$(Q)$(REMOVE) $(TARGET).sym
|
||||
$(Q)$(REMOVE) $(TARGET).lss
|
||||
$(Q)$(REMOVE) $(OBJ)
|
||||
$(Q)$(REMOVE) $(OBJDIR)/autoconf.h
|
||||
$(Q)$(REMOVE) $(OBJDIR)/*.bin
|
||||
$(Q)$(REMOVE) $(LST)
|
||||
$(Q)$(REMOVE) $(CSRC:.c=.s)
|
||||
$(Q)$(REMOVE) $(CSRC:.c=.d)
|
||||
$(Q)$(REMOVE) .dep/*
|
||||
-$(Q)rmdir $(OBJDIR)
|
||||
|
||||
# Include the dependency files.
|
||||
-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*)
|
||||
|
||||
# Listing of phony targets.
|
||||
.PHONY : all begin finish end sizebefore sizeafter \
|
||||
build elf hex lss sym clean clean_list
|
||||
107
src/bootldr/clock.c
Normal file
107
src/bootldr/clock.c
Normal file
@ -0,0 +1,107 @@
|
||||
/* ___DISCLAIMER___ */
|
||||
|
||||
/* clock.c: PLL, CCLK, PCLK controls */
|
||||
|
||||
#include <arm/NXP/LPC17xx/LPC17xx.h>
|
||||
#include "clock.h"
|
||||
#include "bits.h"
|
||||
#include "uart.h"
|
||||
|
||||
void clock_disconnect() {
|
||||
disconnectPLL0();
|
||||
disablePLL0();
|
||||
}
|
||||
|
||||
void clock_init() {
|
||||
|
||||
/* set flash access time to 6 clks (safe setting) */
|
||||
setFlashAccessTime(6);
|
||||
|
||||
/* setup PLL0 for ~44100*256*8 Hz
|
||||
Base clock: 12MHz
|
||||
Multiplier: 429
|
||||
Pre-Divisor: 19
|
||||
Divisor: 6
|
||||
(want: 90316800, get: 90315789.47)
|
||||
-> DAC freq = 44099.5 Hz
|
||||
-> FPGA freq = 11289473.7Hz
|
||||
First, disable and disconnect PLL0.
|
||||
*/
|
||||
// clock_disconnect();
|
||||
|
||||
/* PLL is disabled and disconnected. setup PCLK NOW as it cannot be changed
|
||||
reliably with PLL0 connected.
|
||||
see:
|
||||
http://ics.nxp.com/support/documents/microcontrollers/pdf/errata.lpc1754.pdf
|
||||
*/
|
||||
|
||||
|
||||
/* continue with PLL0 setup:
|
||||
enable the xtal oscillator and wait for it to become stable
|
||||
set the oscillator as clk source for PLL0
|
||||
set PLL0 multiplier+predivider
|
||||
enable PLL0
|
||||
set CCLK divider
|
||||
wait for PLL0 to lock
|
||||
connect PLL0
|
||||
done
|
||||
*/
|
||||
enableMainOsc();
|
||||
setClkSrc(CLKSRC_MAINOSC);
|
||||
setPLL0MultPrediv(12, 1);
|
||||
enablePLL0();
|
||||
setCCLKDiv(3);
|
||||
connectPLL0();
|
||||
}
|
||||
|
||||
void setFlashAccessTime(uint8_t clocks) {
|
||||
LPC_SC->FLASHCFG=FLASHTIM(clocks);
|
||||
}
|
||||
|
||||
void setPLL0MultPrediv(uint16_t mult, uint8_t prediv) {
|
||||
LPC_SC->PLL0CFG=PLL_MULT(mult) | PLL_PREDIV(prediv);
|
||||
PLL0feed();
|
||||
}
|
||||
|
||||
void enablePLL0() {
|
||||
LPC_SC->PLL0CON |= PLLE0;
|
||||
PLL0feed();
|
||||
}
|
||||
|
||||
void disablePLL0() {
|
||||
LPC_SC->PLL0CON &= ~PLLE0;
|
||||
PLL0feed();
|
||||
}
|
||||
|
||||
void connectPLL0() {
|
||||
while(!(LPC_SC->PLL0STAT&PLOCK0));
|
||||
LPC_SC->PLL0CON |= PLLC0;
|
||||
PLL0feed();
|
||||
}
|
||||
|
||||
void disconnectPLL0() {
|
||||
LPC_SC->PLL0CON &= ~PLLC0;
|
||||
PLL0feed();
|
||||
}
|
||||
|
||||
void setCCLKDiv(uint8_t div) {
|
||||
LPC_SC->CCLKCFG=CCLK_DIV(div);
|
||||
}
|
||||
|
||||
void enableMainOsc() {
|
||||
LPC_SC->SCS=OSCEN;
|
||||
while(!(LPC_SC->SCS&OSCSTAT));
|
||||
}
|
||||
|
||||
void disableMainOsc() {
|
||||
LPC_SC->SCS=0;
|
||||
}
|
||||
|
||||
void PLL0feed() {
|
||||
LPC_SC->PLL0FEED=0xaa;
|
||||
LPC_SC->PLL0FEED=0x55;
|
||||
}
|
||||
|
||||
void setClkSrc(uint8_t src) {
|
||||
LPC_SC->CLKSRCSEL=src;
|
||||
}
|
||||
111
src/bootldr/config.h
Normal file
111
src/bootldr/config.h
Normal file
@ -0,0 +1,111 @@
|
||||
#ifndef _CONFIG_H
|
||||
#define _CONFIG_H
|
||||
|
||||
//#define DEBUG_BL
|
||||
// #define DEBUG_SD
|
||||
// #define DEBUG_IRQ
|
||||
|
||||
#define DEBUG_UART
|
||||
|
||||
#ifdef DEBUG_UART
|
||||
#define DBG_UART
|
||||
#else
|
||||
#define DBG_UART while(0)
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_BL
|
||||
#define DBG_BL
|
||||
#else
|
||||
#define DBG_BL while(0)
|
||||
#endif
|
||||
|
||||
#define FW_START (0x00002000L)
|
||||
#define FLASH_SECTORS (17)
|
||||
|
||||
|
||||
#define VER "0.0.1(NSFW)"
|
||||
#define IN_AHBRAM __attribute__ ((section(".ahbram")))
|
||||
|
||||
#define SD_DT_INT_SETUP() do {\
|
||||
BITBAND(LPC_GPIOINT->IO2IntEnR, SD_DT_BIT) = 1;\
|
||||
BITBAND(LPC_GPIOINT->IO2IntEnF, SD_DT_BIT) = 1;\
|
||||
} while(0)
|
||||
|
||||
#define SD_CHANGE_DETECT (BITBAND(LPC_GPIOINT->IO2IntStatR, SD_DT_BIT)\
|
||||
|BITBAND(LPC_GPIOINT->IO2IntStatF, SD_DT_BIT))
|
||||
|
||||
#define SD_CHANGE_CLR() do {LPC_GPIOINT->IO2IntClr = BV(SD_DT_BIT);} while(0)
|
||||
|
||||
#define SD_DT_REG LPC_GPIO0
|
||||
#define SD_DT_BIT 8
|
||||
#define SD_WP_REG LPC_GPIO0
|
||||
#define SD_WP_BIT 6
|
||||
|
||||
#define SDCARD_DETECT (!(BITBAND(SD_DT_REG->FIOPIN, SD_DT_BIT)))
|
||||
#define SDCARD_WP (BITBAND(SD_WP_REG->FIOPIN, SD_WP_BIT))
|
||||
#define SD_SUPPLY_VOLTAGE (1L<<21) /* 3.3V - 3.4V */
|
||||
#define CONFIG_SD_BLOCKTRANSFER 1
|
||||
#define CONFIG_SD_AUTO_RETRIES 10
|
||||
// #define SD_CHANGE_VECT
|
||||
#define CONFIG_SD_DATACRC 1
|
||||
|
||||
#define CONFIG_UART_NUM 3
|
||||
// #define CONFIG_CPU_FREQUENCY 90315789
|
||||
#define CONFIG_CPU_FREQUENCY (96000000L)
|
||||
//#define CONFIG_CPU_FREQUENCY 46000000
|
||||
#define CONFIG_UART_PCLKDIV 1
|
||||
#define CONFIG_UART_TX_BUF_SHIFT 8
|
||||
#define CONFIG_UART_BAUDRATE 921600
|
||||
#define CONFIG_UART_DEADLOCKABLE
|
||||
|
||||
#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_BIT 26
|
||||
|
||||
#define SNES_CIC_D0_REG LPC_GPIO0
|
||||
#define SNES_CIC_D0_BIT 1
|
||||
|
||||
#define SNES_CIC_D1_REG LPC_GPIO0
|
||||
#define SNES_CIC_D1_BIT 0
|
||||
|
||||
#define SNES_CIC_STATUS_REG LPC_GPIO1
|
||||
#define SNES_CIC_STATUS_BIT 29
|
||||
|
||||
#define SNES_CIC_PAIR_REG LPC_GPIO1
|
||||
#define SNES_CIC_PAIR_BIT 25
|
||||
|
||||
#define QSORT_MAXELEM 1024
|
||||
|
||||
#define SSP_REGS LPC_SSP0
|
||||
#define SSP_PCLKREG PCLKSEL1
|
||||
// 1: PCLKSEL0
|
||||
#define SSP_PCLKBIT 10
|
||||
// 1: 20
|
||||
#define SSP_DMAID_TX 0
|
||||
// 1: 2
|
||||
#define SSP_DMAID_RX 1
|
||||
// 1: 3
|
||||
#define SSP_DMACH LPC_GPDMACH0
|
||||
|
||||
#define SD_CLKREG LPC_GPIO0
|
||||
#define SD_CMDREG LPC_GPIO0
|
||||
#define SD_DAT0REG LPC_GPIO2
|
||||
#define SD_DAT1REG LPC_GPIO2
|
||||
#define SD_DAT2REG LPC_GPIO2
|
||||
#define SD_DAT3REG LPC_GPIO2
|
||||
|
||||
#define SD_CLKPIN (7)
|
||||
#define SD_CMDPIN (9)
|
||||
#define SD_DAT0PIN (0)
|
||||
#define SD_DAT1PIN (1)
|
||||
#define SD_DAT2PIN (2)
|
||||
#define SD_DAT3PIN (3)
|
||||
|
||||
#define SD_DAT (LPC_GPIO2->FIOPIN & 0xf)
|
||||
|
||||
#endif
|
||||
188
src/bootldr/ffconf.h
Normal file
188
src/bootldr/ffconf.h
Normal file
@ -0,0 +1,188 @@
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ FatFs - FAT file system module configuration file R0.08a (C)ChaN, 2010
|
||||
/----------------------------------------------------------------------------/
|
||||
/
|
||||
/ CAUTION! Do not forget to make clean the project after any changes to
|
||||
/ the configuration options.
|
||||
/
|
||||
/----------------------------------------------------------------------------*/
|
||||
#ifndef _FFCONF
|
||||
#define _FFCONF 8255 /* Revision ID */
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Function and Buffer Configurations
|
||||
/----------------------------------------------------------------------------*/
|
||||
|
||||
#define _FS_TINY 1 /* 0:Normal or 1:Tiny */
|
||||
/* When _FS_TINY is set to 1, FatFs uses the sector buffer in the file system
|
||||
/ object instead of the sector buffer in the individual file object for file
|
||||
/ data transfer. This reduces memory consumption 512 bytes each file object. */
|
||||
|
||||
|
||||
#define _FS_READONLY 1 /* 0:Read/Write or 1:Read only */
|
||||
/* Setting _FS_READONLY to 1 defines read only configuration. This removes
|
||||
/ writing functions, f_write, f_sync, f_unlink, f_mkdir, f_chmod, f_rename,
|
||||
/ f_truncate and useless f_getfree. */
|
||||
|
||||
|
||||
#define _FS_MINIMIZE 3 /* 0 to 3 */
|
||||
/* The _FS_MINIMIZE option defines minimization level to remove some functions.
|
||||
/
|
||||
/ 0: Full function.
|
||||
/ 1: f_stat, f_getfree, f_unlink, f_mkdir, f_chmod, f_truncate and f_rename
|
||||
/ are removed.
|
||||
/ 2: f_opendir and f_readdir are removed in addition to 1.
|
||||
/ 3: f_lseek is removed in addition to 2. */
|
||||
|
||||
|
||||
#define _USE_STRFUNC 0 /* 0:Disable or 1/2:Enable */
|
||||
/* To enable string functions, set _USE_STRFUNC to 1 or 2. */
|
||||
|
||||
|
||||
#define _USE_MKFS 0 /* 0:Disable or 1:Enable */
|
||||
/* To enable f_mkfs function, set _USE_MKFS to 1 and set _FS_READONLY to 0 */
|
||||
|
||||
|
||||
#define _USE_FORWARD 0 /* 0:Disable or 1:Enable */
|
||||
/* To enable f_forward function, set _USE_FORWARD to 1 and set _FS_TINY to 1. */
|
||||
|
||||
|
||||
#define _USE_FASTSEEK 0 /* 0:Disable or 1:Enable */
|
||||
/* To enable fast seek feature, set _USE_FASTSEEK to 1. */
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Locale and Namespace Configurations
|
||||
/----------------------------------------------------------------------------*/
|
||||
|
||||
#define _CODE_PAGE 1
|
||||
/* The _CODE_PAGE specifies the OEM code page to be used on the target system.
|
||||
/ Incorrect setting of the code page can cause a file open failure.
|
||||
/
|
||||
/ 932 - Japanese Shift-JIS (DBCS, OEM, Windows)
|
||||
/ 936 - Simplified Chinese GBK (DBCS, OEM, Windows)
|
||||
/ 949 - Korean (DBCS, OEM, Windows)
|
||||
/ 950 - Traditional Chinese Big5 (DBCS, OEM, Windows)
|
||||
/ 1250 - Central Europe (Windows)
|
||||
/ 1251 - Cyrillic (Windows)
|
||||
/ 1252 - Latin 1 (Windows)
|
||||
/ 1253 - Greek (Windows)
|
||||
/ 1254 - Turkish (Windows)
|
||||
/ 1255 - Hebrew (Windows)
|
||||
/ 1256 - Arabic (Windows)
|
||||
/ 1257 - Baltic (Windows)
|
||||
/ 1258 - Vietnam (OEM, Windows)
|
||||
/ 437 - U.S. (OEM)
|
||||
/ 720 - Arabic (OEM)
|
||||
/ 737 - Greek (OEM)
|
||||
/ 775 - Baltic (OEM)
|
||||
/ 850 - Multilingual Latin 1 (OEM)
|
||||
/ 858 - Multilingual Latin 1 + Euro (OEM)
|
||||
/ 852 - Latin 2 (OEM)
|
||||
/ 855 - Cyrillic (OEM)
|
||||
/ 866 - Russian (OEM)
|
||||
/ 857 - Turkish (OEM)
|
||||
/ 862 - Hebrew (OEM)
|
||||
/ 874 - Thai (OEM, Windows)
|
||||
/ 1 - ASCII only (Valid for non LFN cfg.)
|
||||
*/
|
||||
|
||||
|
||||
#define _USE_LFN 0 /* 0 to 3 */
|
||||
#define _MAX_LFN 255 /* Maximum LFN length to handle (12 to 255) */
|
||||
/* The _USE_LFN option switches the LFN support.
|
||||
/
|
||||
/ 0: Disable LFN feature. _MAX_LFN and _LFN_UNICODE have no effect.
|
||||
/ 1: Enable LFN with static working buffer on the BSS. Always NOT reentrant.
|
||||
/ 2: Enable LFN with dynamic working buffer on the STACK.
|
||||
/ 3: Enable LFN with dynamic working buffer on the HEAP.
|
||||
/
|
||||
/ The LFN working buffer occupies (_MAX_LFN + 1) * 2 bytes. To enable LFN,
|
||||
/ Unicode handling functions ff_convert() and ff_wtoupper() must be added
|
||||
/ to the project. When enable to use heap, memory control functions
|
||||
/ ff_memalloc() and ff_memfree() must be added to the project. */
|
||||
|
||||
|
||||
#define _LFN_UNICODE 0 /* 0:ANSI/OEM or 1:Unicode */
|
||||
/* To switch the character code set on FatFs API to Unicode,
|
||||
/ enable LFN feature and set _LFN_UNICODE to 1. */
|
||||
|
||||
|
||||
#define _FS_RPATH 0 /* 0 to 2 */
|
||||
/* The _FS_RPATH option configures relative path feature.
|
||||
/
|
||||
/ 0: Disable relative path feature and remove related functions.
|
||||
/ 1: Enable relative path. f_chdrive() and f_chdir() are available.
|
||||
/ 2: f_getcwd() is available in addition to 1.
|
||||
/
|
||||
/ Note that output of the f_readdir fnction is affected by this option. */
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Physical Drive Configurations
|
||||
/----------------------------------------------------------------------------*/
|
||||
|
||||
#define _VOLUMES 1
|
||||
/* Number of volumes (logical drives) to be used. */
|
||||
|
||||
|
||||
#define _MAX_SS 512 /* 512, 1024, 2048 or 4096 */
|
||||
/* Maximum sector size to be handled.
|
||||
/ Always set 512 for memory card and hard disk but a larger value may be
|
||||
/ required for floppy disk (512/1024) and optical disk (512/2048).
|
||||
/ When _MAX_SS is larger than 512, GET_SECTOR_SIZE command must be implememted
|
||||
/ to the disk_ioctl function. */
|
||||
|
||||
|
||||
#define _MULTI_PARTITION 0 /* 0:Single partition or 1:Multiple partition */
|
||||
/* When set to 0, each volume is bound to the same physical drive number and
|
||||
/ it can mount only first primaly partition. When it is set to 1, each volume
|
||||
/ is tied to the partitions listed in VolToPart[]. */
|
||||
|
||||
|
||||
#define _USE_ERASE 0 /* 0:Disable or 1:Enable */
|
||||
/* To enable sector erase feature, set _USE_ERASE to 1. */
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ System Configurations
|
||||
/----------------------------------------------------------------------------*/
|
||||
|
||||
#define _WORD_ACCESS 0 /* 0 or 1 */
|
||||
/* Set 0 first and it is always compatible with all platforms. The _WORD_ACCESS
|
||||
/ option defines which access method is used to the word data on the FAT volume.
|
||||
/
|
||||
/ 0: Byte-by-byte access.
|
||||
/ 1: Word access. Do not choose this unless following condition is met.
|
||||
/
|
||||
/ When the byte order on the memory is big-endian or address miss-aligned word
|
||||
/ access results incorrect behavior, the _WORD_ACCESS must be set to 0.
|
||||
/ If it is not the case, the value can also be set to 1 to improve the
|
||||
/ performance and code size. */
|
||||
|
||||
|
||||
/* Include a header file here to define sync object types on the O/S */
|
||||
/* #include <windows.h>, <ucos_ii.h.h>, <semphr.h> or ohters. */
|
||||
|
||||
#define _FS_REENTRANT 0 /* 0:Disable or 1:Enable */
|
||||
#define _FS_TIMEOUT 1000 /* Timeout period in unit of time ticks */
|
||||
#define _SYNC_t HANDLE /* O/S dependent type of sync object. e.g. HANDLE, OS_EVENT*, ID and etc.. */
|
||||
|
||||
/* The _FS_REENTRANT option switches the reentrancy of the FatFs module.
|
||||
/
|
||||
/ 0: Disable reentrancy. _SYNC_t and _FS_TIMEOUT have no effect.
|
||||
/ 1: Enable reentrancy. Also user provided synchronization handlers,
|
||||
/ ff_req_grant, ff_rel_grant, ff_del_syncobj and ff_cre_syncobj
|
||||
/ function must be added to the project. */
|
||||
|
||||
|
||||
#define _FS_SHARE 0 /* 0:Disable or >=1:Enable */
|
||||
/* To enable file shareing feature, set _FS_SHARE to 1 or greater. The value
|
||||
defines how many files can be opened simultaneously. */
|
||||
|
||||
|
||||
#endif /* _FFCONFIG */
|
||||
208
src/bootldr/iap.c
Normal file
208
src/bootldr/iap.c
Normal file
@ -0,0 +1,208 @@
|
||||
#include <arm/NXP/LPC17xx/LPC17xx.h>
|
||||
#include <string.h>
|
||||
#include "bits.h"
|
||||
#include "iap.h"
|
||||
#include "config.h"
|
||||
#include "uart.h"
|
||||
#include "fileops.h"
|
||||
#include "crc32.h"
|
||||
#include "led.h"
|
||||
|
||||
uint32_t iap_cmd[5];
|
||||
uint32_t iap_res[5];
|
||||
uint32_t flash_sig[4];
|
||||
|
||||
IAP iap_entry = (IAP) IAP_LOCATION;
|
||||
|
||||
uint32_t calc_flash_crc(uint32_t start, uint32_t len) {
|
||||
DBG_BL printf("calc_flash_crc(%08lx, %08lx) {\n", start, len);
|
||||
uint32_t end = start + len;
|
||||
if(end > 0x20000) {
|
||||
len = 0x1ffff - start;
|
||||
end = 0x20000;
|
||||
}
|
||||
uint32_t crc = 0xffffffff;
|
||||
uint32_t s = start;
|
||||
while(s < end) {
|
||||
crc = crc32_update(crc, *(const unsigned char*)(s));
|
||||
s++;
|
||||
}
|
||||
crc = crc_finalize(crc);
|
||||
DBG_BL printf(" crc generated. result=%08lx\n", crc);
|
||||
DBG_BL printf("} //calc_flash_crc\n");
|
||||
return crc;
|
||||
}
|
||||
|
||||
void test_iap() {
|
||||
iap_cmd[0]=54;
|
||||
iap_entry(iap_cmd, iap_res);
|
||||
DBG_BL printf("Part ID=%08lx\n", iap_res[1]);
|
||||
}
|
||||
|
||||
void print_header(sd2snes_fw_header *header) {
|
||||
DBG_BL printf(" magic = %08lx\n version = %08lx\n size = %08lx\n crc = %08lx\n ~crc = %08lx\n",
|
||||
header->magic, header->version, header->size,
|
||||
header->crc, header->crcc);
|
||||
}
|
||||
|
||||
int check_header(sd2snes_fw_header *header, uint32_t crc) {
|
||||
if((header->magic != FW_MAGIC)
|
||||
|| (header->size < 0x200)
|
||||
|| (header->size > (0x1ffff - FW_START))
|
||||
|| ((header->crc ^ header->crcc) != 0xffffffff)) {
|
||||
return ERR_FLASHHD;
|
||||
}
|
||||
if(header->crc != crc) {
|
||||
return ERR_FLASHCRC;
|
||||
}
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
FLASH_RES check_flash() {
|
||||
sd2snes_fw_header *fw_header = (sd2snes_fw_header*) FW_START;
|
||||
uint32_t flash_addr = FW_START;
|
||||
if(flash_addr != FW_START) {
|
||||
DBG_BL printf("address sanity check failed. expected 0x%08lx, got 0x%08lx.\nSomething is terribly wrong.\nBailing out to avoid bootldr self-corruption.\n", FW_START, flash_addr);
|
||||
return ERR_HW;
|
||||
}
|
||||
DBG_BL printf("Current flash contents:\n");
|
||||
DBG_BL print_header(fw_header);
|
||||
uint32_t crc = calc_flash_crc(flash_addr + 0x100, (fw_header->size & 0x1ffff));
|
||||
return check_header(fw_header, crc);
|
||||
}
|
||||
|
||||
IAP_RES iap_wrap(uint32_t *iap_cmd, uint32_t *iap_res) {
|
||||
// NVIC_DisableIRQ(RIT_IRQn);
|
||||
// NVIC_DisableIRQ(UART_IRQ);
|
||||
for(volatile int i=0; i<2048; i++);
|
||||
iap_entry(iap_cmd, iap_res);
|
||||
for(volatile int i=0; i<2048; i++);
|
||||
// NVIC_EnableIRQ(UART_IRQ);
|
||||
return iap_res[0];
|
||||
}
|
||||
|
||||
IAP_RES iap_prepare_for_write(uint32_t start, uint32_t end) {
|
||||
if(start < (FW_START / 0x1000)) return INVALID_SECTOR;
|
||||
iap_cmd[0] = 50;
|
||||
iap_cmd[1] = start;
|
||||
iap_cmd[2] = end;
|
||||
iap_wrap(iap_cmd, iap_res);
|
||||
return iap_res[0];
|
||||
}
|
||||
|
||||
IAP_RES iap_erase(uint32_t start, uint32_t end) {
|
||||
if(start < (FW_START / 0x1000)) return INVALID_SECTOR;
|
||||
iap_cmd[0] = 52;
|
||||
iap_cmd[1] = start;
|
||||
iap_cmd[2] = end;
|
||||
iap_cmd[3] = CONFIG_CPU_FREQUENCY / 1000L;
|
||||
iap_wrap(iap_cmd, iap_res);
|
||||
return iap_res[0];
|
||||
}
|
||||
|
||||
IAP_RES iap_ram2flash(uint32_t tgt, uint8_t *src, int num) {
|
||||
iap_cmd[0] = 51;
|
||||
iap_cmd[1] = tgt;
|
||||
iap_cmd[2] = (uint32_t)src;
|
||||
iap_cmd[3] = num;
|
||||
iap_cmd[4] = CONFIG_CPU_FREQUENCY / 1000L;
|
||||
iap_wrap(iap_cmd, iap_res);
|
||||
return iap_res[0];
|
||||
}
|
||||
|
||||
FLASH_RES flash_file(uint8_t *filename) {
|
||||
sd2snes_fw_header *fw_header = (sd2snes_fw_header*) FW_START;
|
||||
uint32_t flash_addr = FW_START;
|
||||
uint32_t file_crc = 0xffffffff;
|
||||
uint16_t count;
|
||||
sd2snes_fw_header file_header;
|
||||
UINT bytes_read;
|
||||
if(flash_addr != FW_START) {
|
||||
DBG_BL printf("address sanity check failed. expected 0x%08lx, got 0x%08lx.\nSomething is terribly wrong.\nBailing out to avoid bootldr self-corruption.\n", FW_START, flash_addr);
|
||||
return ERR_HW;
|
||||
}
|
||||
file_open(filename, FA_READ);
|
||||
if(file_res) {
|
||||
DBG_BL printf("file_open: error %d\n", file_res);
|
||||
return ERR_FS;
|
||||
}
|
||||
DBG_BL printf("firmware image found. file size: %ld\n", file_handle.fsize);
|
||||
DBG_BL printf("reading header...\n");
|
||||
f_read(&file_handle, &file_header, 32, &bytes_read);
|
||||
DBG_BL print_header(&file_header);
|
||||
if(check_flash() || file_header.version != fw_header->version || file_header.version == FW_MAGIC || fw_header->version == FW_MAGIC) {
|
||||
DBG_UART uart_putc('F');
|
||||
f_read(&file_handle, file_buf, 0xe0, &bytes_read);
|
||||
for(;;) {
|
||||
bytes_read = file_read();
|
||||
if(file_res || !bytes_read) break;
|
||||
for(count = 0; count < bytes_read; count++) {
|
||||
file_crc = crc32_update(file_crc, file_buf[count]);
|
||||
}
|
||||
}
|
||||
file_crc = crc_finalize(file_crc);
|
||||
DBG_BL printf("file crc=%08lx\n", file_crc);
|
||||
if(check_header(&file_header, file_header.crc) != ERR_OK) {
|
||||
DBG_BL printf("Invalid firmware file (header corrupted).\n");
|
||||
return ERR_FILEHD;
|
||||
}
|
||||
if(file_header.crc != file_crc) {
|
||||
DBG_BL printf("Firmware file checksum error.\n");
|
||||
return ERR_FILECHK;
|
||||
}
|
||||
|
||||
uint32_t res;
|
||||
|
||||
writeled(1);
|
||||
DBG_BL printf("erasing flash...\n");
|
||||
DBG_UART uart_putc('P');
|
||||
if((res = iap_prepare_for_write(FW_START / 0x1000, FLASH_SECTORS)) != CMD_SUCCESS) {
|
||||
DBG_BL printf("error %ld while preparing for erase\n", res);
|
||||
DBG_UART uart_putc('X');
|
||||
return ERR_FLASHPREP;
|
||||
};
|
||||
DBG_UART uart_putc('E');
|
||||
if((res = iap_erase(FW_START / 0x1000, FLASH_SECTORS)) != CMD_SUCCESS) {
|
||||
DBG_BL printf("error %ld while erasing\n", res);
|
||||
DBG_UART uart_putc('X');
|
||||
return ERR_FLASHERASE;
|
||||
}
|
||||
DBG_BL printf("writing... @%08lx\n", flash_addr);
|
||||
file_close();
|
||||
file_open(filename, FA_READ);
|
||||
uint8_t current_sec;
|
||||
uint32_t total_read = 0;
|
||||
for(flash_addr = FW_START; flash_addr < 0x00020000; flash_addr += 0x200) {
|
||||
total_read += (bytes_read = file_read());
|
||||
if(file_res || !bytes_read) break;
|
||||
current_sec = flash_addr & 0x10000 ? (16 + ((flash_addr >> 15) & 1))
|
||||
: (flash_addr >> 12);
|
||||
DBG_BL printf("current_sec=%d flash_addr=%08lx\n", current_sec, flash_addr);
|
||||
DBG_UART uart_putc('.');
|
||||
if(current_sec < (FW_START / 0x1000)) return ERR_FLASH;
|
||||
DBG_UART uart_putc(current_sec["0123456789ABCDEFGH"]);
|
||||
DBG_UART uart_putc('p');
|
||||
if((res = iap_prepare_for_write(current_sec, current_sec)) != CMD_SUCCESS) {
|
||||
DBG_BL printf("error %ld while preparing sector %d for write\n", res, current_sec);
|
||||
DBG_UART uart_putc('X');
|
||||
return ERR_FLASH;
|
||||
}
|
||||
DBG_UART uart_putc('w');
|
||||
if((res = iap_ram2flash(flash_addr, file_buf, 512)) != CMD_SUCCESS) {
|
||||
DBG_BL printf("error %ld while writing to address %08lx (sector %d)\n", res, flash_addr, current_sec);
|
||||
DBG_UART uart_putc('X');
|
||||
return ERR_FLASH;
|
||||
}
|
||||
}
|
||||
if(total_read != (file_header.size + 0x100)) {
|
||||
DBG_BL printf("wrote less data than expected! (%08lx vs. %08lx)\n", total_read, file_header.size);
|
||||
// DBG_UART uart_putc('X');
|
||||
return ERR_FILECHK;
|
||||
}
|
||||
writeled(0);
|
||||
} else {
|
||||
DBG_UART uart_putc('n');
|
||||
DBG_BL printf("flash content is ok, no version mismatch, no forced upgrade. No need to flash\n");
|
||||
}
|
||||
return ERR_OK;
|
||||
}
|
||||
131
src/bootldr/lpc1754boot.ld
Normal file
131
src/bootldr/lpc1754boot.ld
Normal file
@ -0,0 +1,131 @@
|
||||
/* Linker script for LPC1754
|
||||
*
|
||||
* Written 2010 by Ingo Korb
|
||||
*
|
||||
* Partially based on the linker scripts of avr-libc
|
||||
*/
|
||||
|
||||
OUTPUT_FORMAT(elf32-littlearm)
|
||||
ENTRY(_start)
|
||||
|
||||
MEMORY
|
||||
{
|
||||
flash (rx) : ORIGIN = 0x00000000, LENGTH = 0x02000
|
||||
ram (rwx) : ORIGIN = 0x10000000, LENGTH = 0x03fe0 /* leave room for IAP */
|
||||
ahbram (rwx) : ORIGIN = 0x2007C000, LENGTH = 0x04000
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.text :
|
||||
{
|
||||
KEEP(*(.vectors))
|
||||
KEEP(*(.init))
|
||||
*(.text)
|
||||
*(.text.*)
|
||||
*(.gnu.linkonce.t.*)
|
||||
|
||||
/* C++ con-/destructors */
|
||||
__ctors_start = . ;
|
||||
*(.ctors)
|
||||
__ctors_end = . ;
|
||||
__dtors_start = . ;
|
||||
*(.dtors)
|
||||
__dtors_end = . ;
|
||||
KEEP(SORT(*)(.ctors))
|
||||
KEEP(SORT(*)(.dtors))
|
||||
|
||||
KEEP(*(.fini))
|
||||
|
||||
__text_end = .;
|
||||
} > flash
|
||||
|
||||
/* .ARM.exidx is sorted, so has to go in its own output section. */
|
||||
__exidx_start = .;
|
||||
.ARM.exidx :
|
||||
{
|
||||
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
|
||||
} >flash
|
||||
__exidx_end = .;
|
||||
|
||||
/* I hope this does what I think it does */
|
||||
.rodata : AT (ALIGN(__exidx_end,4))
|
||||
{
|
||||
*(.rodata)
|
||||
*(.rodata.*)
|
||||
*(.gnu.linkonce.r.*)
|
||||
__rodata_end = .;
|
||||
} > flash
|
||||
|
||||
/* Data section */
|
||||
.data : AT (ALIGN(__rodata_end,4))
|
||||
{
|
||||
__data_start = .;
|
||||
*(.data)
|
||||
*(.data.*)
|
||||
*(.gnu.linkonce.d.*)
|
||||
__data_end = .;
|
||||
} > ram
|
||||
|
||||
/* Addresses of in-rom data section */
|
||||
__data_load_start = LOADADDR(.data);
|
||||
__data_load_end = __data_load_start + SIZEOF(.data);
|
||||
|
||||
. = ALIGN(4);
|
||||
|
||||
/* BSS */
|
||||
.bss :
|
||||
{
|
||||
__bss_start__ = .;
|
||||
*(.bss)
|
||||
*(.bss.*)
|
||||
*(COMMON)
|
||||
__bss_end__ = .;
|
||||
} > ram
|
||||
|
||||
/* second BSS in AHB ram */
|
||||
.ahbram (NOLOAD) :
|
||||
{
|
||||
__ahbram_start__ = .;
|
||||
*(.ahbram)
|
||||
*(.ahbram.*)
|
||||
__ahbram_end__ = .;
|
||||
} > ahbram
|
||||
|
||||
__heap_start = ALIGN(__bss_end__, 4);
|
||||
|
||||
/* Default stack starts at end of ram */
|
||||
PROVIDE(__stack = ORIGIN(ram) + LENGTH(ram)) ;
|
||||
|
||||
|
||||
/* Everyone seems to copy the stuff below straight from somewhere else, so I'll do that too */
|
||||
|
||||
/* Stabs debugging sections. */
|
||||
.stab 0 : { *(.stab) }
|
||||
.stabstr 0 : { *(.stabstr) }
|
||||
.stab.excl 0 : { *(.stab.excl) }
|
||||
.stab.exclstr 0 : { *(.stab.exclstr) }
|
||||
.stab.index 0 : { *(.stab.index) }
|
||||
.stab.indexstr 0 : { *(.stab.indexstr) }
|
||||
.comment 0 : { *(.comment) }
|
||||
/* DWARF debug sections.
|
||||
Symbols in the DWARF debugging sections are relative to the beginning
|
||||
of the section so we begin them at 0. */
|
||||
/* DWARF 1 */
|
||||
.debug 0 : { *(.debug) }
|
||||
.line 0 : { *(.line) }
|
||||
/* GNU DWARF 1 extensions */
|
||||
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||
/* DWARF 1.1 and DWARF 2 */
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
/* DWARF 2 */
|
||||
.debug_info 0 : { *(.debug_info) *(.gnu.linkonce.wi.*) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_line 0 : { *(.debug_line) }
|
||||
.debug_frame 0 : { *(.debug_frame) }
|
||||
.debug_str 0 : { *(.debug_str) }
|
||||
.debug_loc 0 : { *(.debug_loc) }
|
||||
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||
}
|
||||
92
src/bootldr/main.c
Normal file
92
src/bootldr/main.c
Normal file
@ -0,0 +1,92 @@
|
||||
#include <arm/NXP/LPC17xx/LPC17xx.h>
|
||||
#include <string.h>
|
||||
#include "config.h"
|
||||
#include "obj/autoconf.h"
|
||||
#include "clock.h"
|
||||
#include "uart.h"
|
||||
#include "bits.h"
|
||||
#include "power.h"
|
||||
#include "timer.h"
|
||||
#include "ff.h"
|
||||
#include "diskio.h"
|
||||
#include "led.h"
|
||||
#include "sdnative.h"
|
||||
#include "crc.h"
|
||||
#include "fileops.h"
|
||||
#include "iap.h"
|
||||
|
||||
#define EMC0TOGGLE (3<<4)
|
||||
#define MR0R (1<<1)
|
||||
|
||||
int i;
|
||||
|
||||
volatile enum diskstates disk_state;
|
||||
extern volatile tick_t ticks;
|
||||
|
||||
int (*chain)(void) = (void*)(FW_START+0x000001c5);
|
||||
|
||||
int main(void) {
|
||||
SNES_CIC_PAIR_REG->FIODIR = BV(SNES_CIC_PAIR_BIT);
|
||||
BITBAND(SNES_CIC_PAIR_REG->FIOSET, SNES_CIC_PAIR_BIT) = 1;
|
||||
/* LPC_GPIO2->FIODIR = BV(0) | BV(1) | BV(2); */
|
||||
// LPC_GPIO0->FIODIR = BV(16);
|
||||
|
||||
/* connect UART3 on P0[25:26] + SSP0 on P0[15:18] + MAT3.0 on P0[10] */
|
||||
LPC_PINCON->PINSEL1 = BV(18) | BV(19) | BV(20) | BV(21) /* UART3 */
|
||||
| BV(3) | BV(5); /* SSP0 (FPGA) except SS */
|
||||
LPC_PINCON->PINSEL0 = BV(31); /* SSP0 */
|
||||
/* | BV(13) | BV(15) | BV(17) | BV(19) SSP1 (SD) */
|
||||
|
||||
/* pull-down CIC data lines */
|
||||
LPC_PINCON->PINMODE0 = BV(0) | BV(1) | BV(2) | BV(3);
|
||||
|
||||
clock_disconnect();
|
||||
power_init();
|
||||
timer_init();
|
||||
DBG_UART uart_init();
|
||||
led_init();
|
||||
readled(0);
|
||||
rdyled(1);
|
||||
writeled(0);
|
||||
/* do this last because the peripheral init()s change PCLK dividers */
|
||||
clock_init();
|
||||
// LPC_PINCON->PINSEL0 |= BV(20) | BV(21); /* MAT3.0 (FPGA clock) */
|
||||
sdn_init();
|
||||
DBG_BL printf("chksum=%08lx\n", *(uint32_t*)28);
|
||||
DBG_BL printf("\n\nsd2snes mk.2 bootloader\nver.: " VER "\ncpu clock: %ld Hz\n", CONFIG_CPU_FREQUENCY);
|
||||
DBG_BL printf("PCONP=%lx\n", LPC_SC->PCONP);
|
||||
/* setup timer (fpga clk) */
|
||||
LPC_TIM3->CTCR=0;
|
||||
LPC_TIM3->EMR=EMC0TOGGLE;
|
||||
LPC_TIM3->MCR=MR0R;
|
||||
LPC_TIM3->MR0=1;
|
||||
LPC_TIM3->TCR=1;
|
||||
NVIC->ICER[0] = 0xffffffff;
|
||||
NVIC->ICER[1] = 0xffffffff;
|
||||
FLASH_RES res = flash_file((uint8_t*)"/sd2snes/firmware.img");
|
||||
if(res == ERR_FLASHPREP || res == ERR_FLASHERASE || res == ERR_FLASH) {
|
||||
rdyled(0);
|
||||
writeled(1);
|
||||
}
|
||||
if(res == ERR_FILEHD || res == ERR_FILECHK) {
|
||||
rdyled(0);
|
||||
readled(1);
|
||||
}
|
||||
DBG_BL printf("flash result = %d\n", res);
|
||||
if(res != ERR_OK) {
|
||||
if((res = check_flash()) != ERR_OK) {
|
||||
DBG_BL printf("check_flash() failed with error %d, not booting.\n", res);
|
||||
while(1) {
|
||||
toggle_rdy_led();
|
||||
delay_ms(500);
|
||||
}
|
||||
}
|
||||
}
|
||||
NVIC_DisableIRQ(RIT_IRQn);
|
||||
NVIC_DisableIRQ(UART_IRQ);
|
||||
|
||||
SCB->VTOR=FW_START+0x00000100;
|
||||
chain();
|
||||
while(1);
|
||||
}
|
||||
|
||||
58
src/bootldr/timer.c
Normal file
58
src/bootldr/timer.c
Normal file
@ -0,0 +1,58 @@
|
||||
/* ___INGO___ */
|
||||
|
||||
#include <arm/NXP/LPC17xx/LPC17xx.h>
|
||||
#include "bits.h"
|
||||
#include "config.h"
|
||||
#include "timer.h"
|
||||
#include "clock.h"
|
||||
#include "uart.h"
|
||||
#include "sdnative.h"
|
||||
|
||||
/* bit definitions */
|
||||
#define RITINT 0
|
||||
#define RITEN 3
|
||||
|
||||
#define PCRIT 16
|
||||
|
||||
extern volatile int sd_changed;
|
||||
volatile tick_t ticks;
|
||||
volatile int wokefromrit;
|
||||
|
||||
void timer_init(void) {
|
||||
/* turn on power to RIT */
|
||||
BITBAND(LPC_SC->PCONP, PCRIT) = 1;
|
||||
|
||||
/* clear RIT mask */
|
||||
LPC_RIT->RIMASK = 0; /*xffffffff;*/
|
||||
|
||||
/* PCLK = CCLK */
|
||||
BITBAND(LPC_SC->PCLKSEL1, 26) = 1;
|
||||
BITBAND(LPC_SC->PCLKSEL1, PCLK_TIMER3) = 1;
|
||||
}
|
||||
|
||||
void delay_us(unsigned int time) {
|
||||
/* Prepare RIT */
|
||||
LPC_RIT->RICOUNTER = 0;
|
||||
LPC_RIT->RICOMPVAL = (CONFIG_CPU_FREQUENCY / 1000000) * time;
|
||||
LPC_RIT->RICTRL = BV(RITEN) | BV(RITINT);
|
||||
|
||||
/* Wait until RIT signals an interrupt */
|
||||
while (!(BITBAND(LPC_RIT->RICTRL, RITINT))) ;
|
||||
|
||||
/* Disable RIT */
|
||||
LPC_RIT->RICTRL = 0;
|
||||
}
|
||||
|
||||
void delay_ms(unsigned int time) {
|
||||
/* Prepare RIT */
|
||||
LPC_RIT->RICOUNTER = 0;
|
||||
LPC_RIT->RICOMPVAL = (CONFIG_CPU_FREQUENCY / 1000) * time;
|
||||
LPC_RIT->RICTRL = BV(RITEN) | BV(RITINT);
|
||||
|
||||
/* Wait until RIT signals an interrupt */
|
||||
while (!(BITBAND(LPC_RIT->RICTRL, RITINT))) ;
|
||||
|
||||
/* Disable RIT */
|
||||
LPC_RIT->RICTRL = 0;
|
||||
}
|
||||
|
||||
202
src/bootldr/uart.c
Normal file
202
src/bootldr/uart.c
Normal file
@ -0,0 +1,202 @@
|
||||
/*
|
||||
|
||||
uart.c: UART access routines
|
||||
|
||||
*/
|
||||
|
||||
#include <arm/NXP/LPC17xx/LPC17xx.h>
|
||||
#include "bits.h"
|
||||
#include "config.h"
|
||||
#include "uart.h"
|
||||
#include "led.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;
|
||||
}
|
||||
}
|
||||
*/
|
||||
//static char txbuf[1 << CONFIG_UART_TX_BUF_SHIFT];
|
||||
static volatile unsigned int read_idx,write_idx;
|
||||
|
||||
void uart_putc(char c) {
|
||||
if (c == '\n')
|
||||
uart_putc('\r');
|
||||
while(!(UART_REGS->LSR & (0x20)));
|
||||
UART_REGS->THR = c;
|
||||
}
|
||||
|
||||
/* Polling version only */
|
||||
unsigned char uart_getc(void) {
|
||||
/* wait for character */
|
||||
while (!(BITBAND(UART_REGS->LSR, 0))) ;
|
||||
return UART_REGS->RBR;
|
||||
}
|
||||
|
||||
/* Returns true if a char is ready */
|
||||
unsigned char uart_gotc(void) {
|
||||
return BITBAND(UART_REGS->LSR, 0);
|
||||
}
|
||||
|
||||
void uart_init(void) {
|
||||
uint32_t div;
|
||||
|
||||
/* Turn on power to UART */
|
||||
BITBAND(LPC_SC->PCONP, UART_PCONBIT) = 1;
|
||||
|
||||
/* UART clock = CPU clock - this block is reduced at compile-time */
|
||||
if (CONFIG_UART_PCLKDIV == 1) {
|
||||
BITBAND(LPC_SC->UART_PCLKREG, UART_PCLKBIT ) = 1;
|
||||
BITBAND(LPC_SC->UART_PCLKREG, UART_PCLKBIT+1) = 0;
|
||||
} else if (CONFIG_UART_PCLKDIV == 2) {
|
||||
BITBAND(LPC_SC->UART_PCLKREG, UART_PCLKBIT ) = 0;
|
||||
BITBAND(LPC_SC->UART_PCLKREG, UART_PCLKBIT+1) = 1;
|
||||
} else if (CONFIG_UART_PCLKDIV == 4) {
|
||||
BITBAND(LPC_SC->UART_PCLKREG, UART_PCLKBIT ) = 0;
|
||||
BITBAND(LPC_SC->UART_PCLKREG, UART_PCLKBIT+1) = 0;
|
||||
} else { // Fallback: Divide by 8
|
||||
BITBAND(LPC_SC->UART_PCLKREG, UART_PCLKBIT ) = 1;
|
||||
BITBAND(LPC_SC->UART_PCLKREG, UART_PCLKBIT+1) = 1;
|
||||
}
|
||||
|
||||
/* set baud rate - no fractional stuff for now */
|
||||
UART_REGS->LCR = BV(7) | 3; // always 8n1
|
||||
div = 0x850004; // baud2divisor(CONFIG_UART_BAUDRATE);
|
||||
|
||||
UART_REGS->DLL = div & 0xff;
|
||||
UART_REGS->DLM = (div >> 8) & 0xff;
|
||||
BITBAND(UART_REGS->LCR, 7) = 0;
|
||||
|
||||
if (div & 0xff0000) {
|
||||
UART_REGS->FDR = (div >> 16) & 0xff;
|
||||
}
|
||||
|
||||
/* reset and enable FIFO */
|
||||
UART_REGS->FCR = BV(0);
|
||||
|
||||
UART_REGS->THR = '?';
|
||||
}
|
||||
|
||||
/* --- generic code below --- */
|
||||
void uart_puthex(uint8_t num) {
|
||||
uint8_t tmp;
|
||||
tmp = (num & 0xf0) >> 4;
|
||||
if (tmp < 10)
|
||||
uart_putc('0'+tmp);
|
||||
else
|
||||
uart_putc('a'+tmp-10);
|
||||
|
||||
tmp = num & 0x0f;
|
||||
if (tmp < 10)
|
||||
uart_putc('0'+tmp);
|
||||
else
|
||||
uart_putc('a'+tmp-10);
|
||||
}
|
||||
|
||||
void uart_trace(void *ptr, uint16_t start, uint16_t len) {
|
||||
uint16_t i;
|
||||
uint8_t j;
|
||||
uint8_t ch;
|
||||
uint8_t *data = ptr;
|
||||
|
||||
data+=start;
|
||||
for(i=0;i<len;i+=16) {
|
||||
|
||||
uart_puthex(start>>8);
|
||||
uart_puthex(start&0xff);
|
||||
uart_putc('|');
|
||||
uart_putc(' ');
|
||||
for(j=0;j<16;j++) {
|
||||
if(i+j<len) {
|
||||
ch=*(data + j);
|
||||
uart_puthex(ch);
|
||||
} else {
|
||||
uart_putc(' ');
|
||||
uart_putc(' ');
|
||||
}
|
||||
uart_putc(' ');
|
||||
}
|
||||
uart_putc('|');
|
||||
for(j=0;j<16;j++) {
|
||||
if(i+j<len) {
|
||||
ch=*(data++);
|
||||
if(ch<32 || ch>0x7e)
|
||||
ch='.';
|
||||
uart_putc(ch);
|
||||
} else {
|
||||
uart_putc(' ');
|
||||
}
|
||||
}
|
||||
uart_putc('|');
|
||||
uart_putcrlf();
|
||||
start+=16;
|
||||
}
|
||||
}
|
||||
|
||||
void uart_flush(void) {
|
||||
while (read_idx != write_idx) ;
|
||||
}
|
||||
|
||||
void uart_puts(const char *text) {
|
||||
while (*text) {
|
||||
uart_putc(*text++);
|
||||
}
|
||||
}
|
||||
80
src/cic.c
Normal file
80
src/cic.c
Normal file
@ -0,0 +1,80 @@
|
||||
#include <arm/NXP/LPC17xx/LPC17xx.h>
|
||||
#include "bits.h"
|
||||
#include "config.h"
|
||||
#include "uart.h"
|
||||
#include "cic.h"
|
||||
|
||||
char *cicstatenames[4] = { "CIC_OK", "CIC_FAIL", "CIC_PAIR", "CIC_SCIC" };
|
||||
char *cicstatefriendly[4] = {"Original or no CIC", "Original CIC(failed)", "SuperCIC enhanced", "SuperCIC detected, not used"};
|
||||
|
||||
void print_cic_state() {
|
||||
printf("CIC state: %s\n", get_cic_statename(get_cic_state()));
|
||||
}
|
||||
|
||||
inline char *get_cic_statefriendlyname(enum cicstates state) {
|
||||
return cicstatefriendly[state];
|
||||
}
|
||||
|
||||
inline char *get_cic_statename(enum cicstates state) {
|
||||
return cicstatenames[state];
|
||||
}
|
||||
|
||||
enum cicstates get_cic_state() {
|
||||
uint32_t count;
|
||||
uint32_t togglecount = 0;
|
||||
uint8_t state, state_old;
|
||||
|
||||
state_old = BITBAND(SNES_CIC_STATUS_REG->FIOPIN, SNES_CIC_STATUS_BIT);
|
||||
/* this loop samples at ~10MHz */
|
||||
for(count=0; count<CIC_SAMPLECOUNT; count++) {
|
||||
state = BITBAND(SNES_CIC_STATUS_REG->FIOPIN, SNES_CIC_STATUS_BIT);
|
||||
if(state != state_old) {
|
||||
togglecount++;
|
||||
}
|
||||
state_old = state;
|
||||
}
|
||||
printf("%ld\n", togglecount);
|
||||
/* CIC_TOGGLE_THRESH_PAIR > CIC_TOGGLE_THRESH_SCIC */
|
||||
if(togglecount > CIC_TOGGLE_THRESH_PAIR) {
|
||||
return CIC_PAIR;
|
||||
} else if(togglecount > CIC_TOGGLE_THRESH_SCIC) {
|
||||
return CIC_SCIC;
|
||||
} else if(state) {
|
||||
return CIC_OK;
|
||||
} else return CIC_FAIL;
|
||||
}
|
||||
|
||||
void cic_init(int allow_pairmode) {
|
||||
BITBAND(SNES_CIC_PAIR_REG->FIODIR, SNES_CIC_PAIR_BIT) = 1;
|
||||
if(allow_pairmode) {
|
||||
BITBAND(SNES_CIC_PAIR_REG->FIOCLR, SNES_CIC_PAIR_BIT) = 1;
|
||||
} else {
|
||||
BITBAND(SNES_CIC_PAIR_REG->FIOSET, SNES_CIC_PAIR_BIT) = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* prepare GPIOs for pair mode + set initial modes */
|
||||
void cic_pair(int init_vmode, int init_d4) {
|
||||
cic_videomode(init_vmode);
|
||||
cic_d4(init_d4);
|
||||
|
||||
BITBAND(SNES_CIC_D0_REG->FIODIR, SNES_CIC_D0_BIT) = 1;
|
||||
BITBAND(SNES_CIC_D1_REG->FIODIR, SNES_CIC_D1_BIT) = 1;
|
||||
}
|
||||
|
||||
void cic_videomode(int value) {
|
||||
if(value) {
|
||||
BITBAND(SNES_CIC_D0_REG->FIOSET, SNES_CIC_D0_BIT) = 1;
|
||||
} else {
|
||||
BITBAND(SNES_CIC_D0_REG->FIOCLR, SNES_CIC_D0_BIT) = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void cic_d4(int value) {
|
||||
if(value) {
|
||||
BITBAND(SNES_CIC_D1_REG->FIOSET, SNES_CIC_D1_BIT) = 1;
|
||||
} else {
|
||||
BITBAND(SNES_CIC_D1_REG->FIOCLR, SNES_CIC_D1_BIT) = 1;
|
||||
}
|
||||
}
|
||||
|
||||
24
src/cic.h
Normal file
24
src/cic.h
Normal file
@ -0,0 +1,24 @@
|
||||
#ifndef _CIC_H
|
||||
#define _CIC_H
|
||||
|
||||
#define CIC_SAMPLECOUNT (100000)
|
||||
#define CIC_TOGGLE_THRESH_PAIR (2500)
|
||||
#define CIC_TOGGLE_THRESH_SCIC (10)
|
||||
|
||||
#include <arm/NXP/LPC17xx/LPC17xx.h>
|
||||
#include "bits.h"
|
||||
|
||||
enum cicstates { CIC_OK = 0, CIC_FAIL, CIC_PAIR, CIC_SCIC };
|
||||
enum cic_region { CIC_NTSC = 0, CIC_PAL };
|
||||
|
||||
void print_cic_state(void);
|
||||
char *get_cic_statename(enum cicstates state);
|
||||
char *get_cic_statefriendlyname(enum cicstates state);
|
||||
enum cicstates get_cic_state(void);
|
||||
void cic_init(int allow_pairmode);
|
||||
|
||||
void cic_pair(int init_vmode, int init_d4);
|
||||
void cic_videomode(int value);
|
||||
void cic_d4(int value);
|
||||
|
||||
#endif
|
||||
567
src/cli.c
Normal file
567
src/cli.c
Normal file
@ -0,0 +1,567 @@
|
||||
/* tapplay - TAP file playback for sd2iec hardware
|
||||
Copyright (C) 2009 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
|
||||
|
||||
|
||||
cli.c: The command line interface
|
||||
|
||||
*/
|
||||
|
||||
#include <arm/NXP/LPC17xx/LPC17xx.h>
|
||||
#include <arm/bits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include "config.h"
|
||||
#include "diskio.h"
|
||||
#include "ff.h"
|
||||
#include "timer.h"
|
||||
#include "uart.h"
|
||||
#include "fileops.h"
|
||||
#include "memory.h"
|
||||
#include "snes.h"
|
||||
#include "fpga.h"
|
||||
#include "fpga_spi.h"
|
||||
#include "cic.h"
|
||||
#include "xmodem.h"
|
||||
#include "rtc.h"
|
||||
|
||||
#include "cli.h"
|
||||
|
||||
#define MAX_LINE 250
|
||||
|
||||
/* Variables */
|
||||
static char cmdbuffer[MAX_LINE+1];
|
||||
static char *curchar;
|
||||
|
||||
/* Word lists */
|
||||
static char command_words[] =
|
||||
"cd\0reset\0sreset\0dir\0ls\0test\0resume\0loadrom\0loadraw\0saveraw\0put\0rm\0d4\0vmode\0mapper\0settime\0time\0setfeature\0hexdump\0w8\0w16\0";
|
||||
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 };
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* Parse functions */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/* Skip spaces at curchar */
|
||||
static uint8_t skip_spaces(void) {
|
||||
uint8_t res = (*curchar == ' ' || *curchar == 0);
|
||||
|
||||
while (*curchar == ' ')
|
||||
curchar++;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Parse the string in curchar for an integer with bounds [lower,upper] */
|
||||
static int32_t parse_unsigned(uint32_t lower, uint32_t upper, uint8_t base) {
|
||||
char *end;
|
||||
uint32_t result;
|
||||
|
||||
if (strlen(curchar) == 1 && *curchar == '?') {
|
||||
printf("Number between %ld[0x%lx] and %ld[0x%lx] expected\n",lower,lower,upper,upper);
|
||||
return -2;
|
||||
}
|
||||
|
||||
result = strtoul(curchar, &end, base);
|
||||
if ((*end != ' ' && *end != 0) || errno != 0) {
|
||||
printf("Invalid numeric argument\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
curchar = end;
|
||||
skip_spaces();
|
||||
|
||||
if (result < lower || result > upper) {
|
||||
printf("Numeric argument out of range (%ld..%ld)\n",lower,upper);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
/* Parse the string starting with curchar for a word in wordlist */
|
||||
static int8_t parse_wordlist(char *wordlist) {
|
||||
uint8_t i, matched;
|
||||
char *cur, *ptr;
|
||||
char c;
|
||||
|
||||
i = 0;
|
||||
ptr = wordlist;
|
||||
|
||||
// Command list on "?"
|
||||
if (strlen(curchar) == 1 && *curchar == '?') {
|
||||
printf("Commands available: \n ");
|
||||
while (1) {
|
||||
c = *ptr++;
|
||||
if (c == 0) {
|
||||
if (*ptr == 0) {
|
||||
printf("\n");
|
||||
return -2;
|
||||
} else {
|
||||
printf("\n ");
|
||||
}
|
||||
} else
|
||||
uart_putc(c);
|
||||
}
|
||||
}
|
||||
|
||||
while (1) {
|
||||
cur = curchar;
|
||||
matched = 1;
|
||||
c = *ptr;
|
||||
do {
|
||||
// If current word list character is \0: No match found
|
||||
if (c == 0) {
|
||||
printf("Unknown word: %s\n(use ? for help)",curchar);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (tolower(c) != tolower(*cur)) {
|
||||
// Check for end-of-word
|
||||
if (cur != curchar && (*cur == ' ' || *cur == 0)) {
|
||||
// Partial match found, return that
|
||||
break;
|
||||
} else {
|
||||
matched = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ptr++;
|
||||
cur++;
|
||||
c = *ptr;
|
||||
} while (c != 0);
|
||||
|
||||
if (matched) {
|
||||
char *tmp = curchar;
|
||||
|
||||
curchar = cur;
|
||||
// Return match only if whitespace or end-of-string follows
|
||||
// (avoids mismatching partial words)
|
||||
if (skip_spaces()) {
|
||||
return i;
|
||||
} else {
|
||||
printf("Unknown word: %s\n(use ? for help)\n",tmp);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
// Try next word in list
|
||||
i++;
|
||||
while (*ptr++ != 0) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Read a line from serial, uses cmdbuffer as storage */
|
||||
static char *getline(char *prompt) {
|
||||
int i=0;
|
||||
char c;
|
||||
|
||||
printf("\n%s",prompt);
|
||||
memset(cmdbuffer,0,sizeof(cmdbuffer));
|
||||
|
||||
while (1) {
|
||||
c = uart_getc();
|
||||
if (c == 13)
|
||||
break;
|
||||
|
||||
if (c == 27 || c == 3) {
|
||||
printf("\\\n%s",prompt);
|
||||
i = 0;
|
||||
memset(cmdbuffer,0,sizeof(cmdbuffer));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c == 127 || c == 8) {
|
||||
if (i > 0) {
|
||||
i--;
|
||||
uart_putc(8); // backspace
|
||||
uart_putc(' '); // erase character
|
||||
uart_putc(8); // backspace
|
||||
} else
|
||||
continue;
|
||||
} else {
|
||||
if (i < sizeof(cmdbuffer)-1) {
|
||||
cmdbuffer[i++] = c;
|
||||
uart_putc(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
cmdbuffer[i] = 0;
|
||||
return cmdbuffer;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* Command functions */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/* Reset */
|
||||
static void cmd_reset(void) {
|
||||
/* force watchdog reset */
|
||||
LPC_WDT->WDTC = 256; // minimal timeout
|
||||
LPC_WDT->WDCLKSEL = BV(31); // internal RC, lock register
|
||||
LPC_WDT->WDMOD = BV(0) | BV(1); // enable watchdog and reset-by-watchdog
|
||||
LPC_WDT->WDFEED = 0xaa;
|
||||
LPC_WDT->WDFEED = 0x55; // initial feed to really enable WDT
|
||||
}
|
||||
|
||||
/* Show the contents of the current directory */
|
||||
static void cmd_show_directory(void) {
|
||||
FRESULT res;
|
||||
DIR dh;
|
||||
FILINFO finfo;
|
||||
uint8_t *name;
|
||||
|
||||
f_getcwd((TCHAR*)file_lfn, 255);
|
||||
|
||||
res = f_opendir(&dh, (TCHAR*)file_lfn);
|
||||
if (res != FR_OK) {
|
||||
printf("f_opendir failed, result %d\n",res);
|
||||
return;
|
||||
}
|
||||
|
||||
finfo.lfname = (TCHAR*)file_lfn;
|
||||
finfo.lfsize = 255;
|
||||
|
||||
do {
|
||||
/* Read the next entry */
|
||||
res = f_readdir(&dh, &finfo);
|
||||
if (res != FR_OK) {
|
||||
printf("f_readdir failed, result %d\n",res);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Abort if none was found */
|
||||
if (!finfo.fname[0])
|
||||
break;
|
||||
|
||||
/* Skip volume labels */
|
||||
if (finfo.fattrib & AM_VOL)
|
||||
continue;
|
||||
|
||||
/* Select between LFN and 8.3 name */
|
||||
if (finfo.lfname[0])
|
||||
name = (uint8_t*)finfo.lfname;
|
||||
else {
|
||||
name = (uint8_t*)finfo.fname;
|
||||
strlwr((char *)name);
|
||||
}
|
||||
|
||||
printf("%s",name);
|
||||
|
||||
/* Directory indicator (Unix-style) */
|
||||
if (finfo.fattrib & AM_DIR)
|
||||
uart_putc('/');
|
||||
|
||||
printf("\n");
|
||||
} while (finfo.fname[0]);
|
||||
}
|
||||
|
||||
|
||||
static void cmd_loadrom(void) {
|
||||
uint32_t address = 0;
|
||||
uint8_t flags = LOADROM_WITH_SRAM | LOADROM_WITH_RESET;
|
||||
load_rom((uint8_t*)curchar, address, flags);
|
||||
}
|
||||
|
||||
static void cmd_loadraw(void) {
|
||||
uint32_t address = parse_unsigned(0,16777216,16);
|
||||
load_sram((uint8_t*)curchar, address);
|
||||
}
|
||||
|
||||
static void cmd_saveraw(void) {
|
||||
uint32_t address = parse_unsigned(0,16777216,16);
|
||||
uint32_t length = parse_unsigned(0,16777216,16);
|
||||
save_sram((uint8_t*)curchar, length, address);
|
||||
}
|
||||
|
||||
static void cmd_d4(void) {
|
||||
int32_t hz;
|
||||
|
||||
if(get_cic_state() != CIC_PAIR) {
|
||||
printf("not in pair mode\n");
|
||||
} else {
|
||||
hz = parse_unsigned(50,60,10);
|
||||
if(hz==50) {
|
||||
cic_d4(CIC_PAL);
|
||||
} else {
|
||||
cic_d4(CIC_NTSC);
|
||||
}
|
||||
printf("ok\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void cmd_vmode(void) {
|
||||
int32_t hz;
|
||||
if(get_cic_state() != CIC_PAIR) {
|
||||
printf("not in pair mode\n");
|
||||
} else {
|
||||
hz = parse_unsigned(50,60,10);
|
||||
if(hz==50) {
|
||||
cic_videomode(CIC_PAL);
|
||||
} else {
|
||||
cic_videomode(CIC_NTSC);
|
||||
}
|
||||
printf("ok\n");
|
||||
}
|
||||
}
|
||||
|
||||
void cmd_put(void) {
|
||||
if(*curchar != 0) {
|
||||
file_open((uint8_t*)curchar, FA_CREATE_ALWAYS | FA_WRITE);
|
||||
if(file_res) {
|
||||
printf("FAIL: error opening file %s\n", curchar);
|
||||
} else {
|
||||
printf("OK, start xmodem transfer now.\n");
|
||||
xmodem_rxfile(&file_handle);
|
||||
}
|
||||
file_close();
|
||||
} else {
|
||||
printf("Usage: put <filename>\n");
|
||||
}
|
||||
}
|
||||
|
||||
void cmd_rm(void) {
|
||||
FRESULT res = f_unlink(curchar);
|
||||
if(res) printf("Error %d removing %s\n", res, curchar);
|
||||
}
|
||||
|
||||
void cmd_mapper(void) {
|
||||
int32_t mapper;
|
||||
mapper = parse_unsigned(0,7,10);
|
||||
set_mapper((uint8_t)mapper & 0x7);
|
||||
printf("mapper set to %ld\n", mapper);
|
||||
}
|
||||
|
||||
void cmd_sreset(void) {
|
||||
if(*curchar != 0) {
|
||||
int32_t resetstate;
|
||||
resetstate = parse_unsigned(0,1,10);
|
||||
snes_reset(resetstate);
|
||||
} else {
|
||||
snes_reset(1);
|
||||
delay_ms(20);
|
||||
snes_reset(0);
|
||||
}
|
||||
}
|
||||
void cmd_settime(void) {
|
||||
struct tm time;
|
||||
if(strlen(curchar) != 4+2+2 + 2+2+2) {
|
||||
printf("invalid time format (need YYYYMMDDhhmmss)\n");
|
||||
} else {
|
||||
time.tm_sec = atoi(curchar+4+2+2+2+2);
|
||||
curchar[4+2+2+2+2] = 0;
|
||||
time.tm_min = atoi(curchar+4+2+2+2);
|
||||
curchar[4+2+2+2] = 0;
|
||||
time.tm_hour = atoi(curchar+4+2+2);
|
||||
curchar[4+2+2] = 0;
|
||||
time.tm_mday = atoi(curchar+4+2);
|
||||
curchar[4+2] = 0;
|
||||
time.tm_mon = atoi(curchar+4);
|
||||
curchar[4] = 0;
|
||||
time.tm_year = atoi(curchar);
|
||||
set_rtc(&time);
|
||||
}
|
||||
}
|
||||
|
||||
void cmd_time(void) {
|
||||
struct tm time;
|
||||
read_rtc(&time);
|
||||
printf("%04d-%02d-%02d %02d:%02d:%02d\n", time.tm_year, time.tm_mon,
|
||||
time.tm_mday, time.tm_hour, time.tm_min, time.tm_sec);
|
||||
}
|
||||
|
||||
void cmd_setfeature(void) {
|
||||
uint8_t feat = parse_unsigned(0, 255, 16);
|
||||
fpga_set_features(feat);
|
||||
}
|
||||
|
||||
void cmd_hexdump(void) {
|
||||
uint32_t offset = parse_unsigned(0, 16777215, 16);
|
||||
uint32_t len = parse_unsigned(0, 16777216, 16);
|
||||
sram_hexdump(offset, len);
|
||||
}
|
||||
|
||||
void cmd_w8(void) {
|
||||
uint32_t offset = parse_unsigned(0, 16777215, 16);
|
||||
uint8_t val = parse_unsigned(0, 255, 16);
|
||||
sram_writebyte(val, offset);
|
||||
}
|
||||
|
||||
void cmd_w16(void) {
|
||||
uint32_t offset = parse_unsigned(0, 16777215, 16);
|
||||
uint16_t val = parse_unsigned(0, 65535, 16);
|
||||
sram_writeshort(val, offset);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* CLI interface functions */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
void cli_init(void) {
|
||||
}
|
||||
|
||||
void cli_entrycheck() {
|
||||
if(uart_gotc() && uart_getc() == 27) {
|
||||
printf("*** BREAK\n");
|
||||
cli_loop();
|
||||
}
|
||||
}
|
||||
|
||||
void cli_loop(void) {
|
||||
while (1) {
|
||||
curchar = getline(">");
|
||||
printf("\n");
|
||||
|
||||
/* Process medium changes before executing the command */
|
||||
if (disk_state != DISK_OK && disk_state != DISK_REMOVED) {
|
||||
FRESULT res;
|
||||
|
||||
printf("Medium changed... ");
|
||||
res = f_mount(0,&fatfs);
|
||||
if (res != FR_OK) {
|
||||
printf("Failed to mount new medium, result %d\n",res);
|
||||
} else {
|
||||
printf("Ok\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Remove whitespace */
|
||||
while (*curchar == ' ') curchar++;
|
||||
while (strlen(curchar) > 0 && curchar[strlen(curchar)-1] == ' ')
|
||||
curchar[strlen(curchar)-1] = 0;
|
||||
|
||||
/* Ignore empty lines */
|
||||
if (strlen(curchar) == 0)
|
||||
continue;
|
||||
|
||||
/* Parse command */
|
||||
int8_t command = parse_wordlist(command_words);
|
||||
if (command < 0)
|
||||
continue;
|
||||
|
||||
|
||||
FRESULT res;
|
||||
switch (command) {
|
||||
case CMD_CD:
|
||||
#if _FS_RPATH
|
||||
if (strlen(curchar) == 0) {
|
||||
f_getcwd((TCHAR*)file_lfn, 255);
|
||||
printf("%s\n",file_lfn);
|
||||
break;
|
||||
}
|
||||
|
||||
res = f_chdir((const TCHAR *)curchar);
|
||||
if (res != FR_OK) {
|
||||
printf("chdir %s failed with result %d\n",curchar,res);
|
||||
} else {
|
||||
printf("Ok.\n");
|
||||
}
|
||||
#else
|
||||
printf("cd not supported.\n");
|
||||
res;
|
||||
#endif
|
||||
break;
|
||||
case CMD_RESET:
|
||||
cmd_reset();
|
||||
break;
|
||||
|
||||
case CMD_SRESET:
|
||||
cmd_sreset();
|
||||
break;
|
||||
|
||||
case CMD_DIR:
|
||||
case CMD_LS:
|
||||
cmd_show_directory();
|
||||
break;
|
||||
|
||||
case CMD_RESUME:
|
||||
return;
|
||||
break;
|
||||
|
||||
case CMD_LOADROM:
|
||||
cmd_loadrom();
|
||||
break;
|
||||
|
||||
case CMD_LOADRAW:
|
||||
cmd_loadraw();
|
||||
break;
|
||||
|
||||
case CMD_SAVERAW:
|
||||
cmd_saveraw();
|
||||
break;
|
||||
|
||||
case CMD_RM:
|
||||
cmd_rm();
|
||||
break;
|
||||
|
||||
case CMD_D4:
|
||||
cmd_d4();
|
||||
break;
|
||||
|
||||
case CMD_VMODE:
|
||||
cmd_vmode();
|
||||
break;
|
||||
|
||||
case CMD_PUT:
|
||||
cmd_put();
|
||||
break;
|
||||
|
||||
case CMD_MAPPER:
|
||||
cmd_mapper();
|
||||
break;
|
||||
|
||||
case CMD_SETTIME:
|
||||
cmd_settime();
|
||||
break;
|
||||
|
||||
case CMD_TIME:
|
||||
cmd_time();
|
||||
break;
|
||||
|
||||
case CMD_TEST:
|
||||
testbattery();
|
||||
break;
|
||||
|
||||
case CMD_SETFEATURE:
|
||||
cmd_setfeature();
|
||||
break;
|
||||
|
||||
case CMD_HEXDUMP:
|
||||
cmd_hexdump();
|
||||
break;
|
||||
|
||||
case CMD_W8:
|
||||
cmd_w8();
|
||||
break;
|
||||
|
||||
case CMD_W16:
|
||||
cmd_w16();
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
4
src/config
Normal file
4
src/config
Normal file
@ -0,0 +1,4 @@
|
||||
CONFIG_VERSION="0.1.2"
|
||||
#FWVER=00010200
|
||||
CONFIG_FWVER=66048
|
||||
CONFIG_MCU_FOSC=12000000
|
||||
98
src/config.h
Normal file
98
src/config.h
Normal file
@ -0,0 +1,98 @@
|
||||
#ifndef _CONFIG_H
|
||||
#define _CONFIG_H
|
||||
|
||||
#include "autoconf.h"
|
||||
|
||||
// #define DEBUG_FS
|
||||
// #define DEBUG_SD
|
||||
// #define DEBUG_IRQ
|
||||
// #define DEBUG_MSU1
|
||||
|
||||
#define IN_AHBRAM __attribute__ ((section(".ahbram")))
|
||||
|
||||
#define SD_DT_INT_SETUP() do {\
|
||||
BITBAND(LPC_GPIOINT->IO2IntEnR, SD_DT_BIT) = 1;\
|
||||
BITBAND(LPC_GPIOINT->IO2IntEnF, SD_DT_BIT) = 1;\
|
||||
} while(0)
|
||||
|
||||
#define SD_CHANGE_DETECT (BITBAND(LPC_GPIOINT->IO2IntStatR, SD_DT_BIT)\
|
||||
|BITBAND(LPC_GPIOINT->IO2IntStatF, SD_DT_BIT))
|
||||
|
||||
#define SD_CHANGE_CLR() do {LPC_GPIOINT->IO2IntClr = BV(SD_DT_BIT);} while(0)
|
||||
|
||||
#define SD_DT_REG LPC_GPIO0
|
||||
#define SD_DT_BIT 8
|
||||
#define SD_WP_REG LPC_GPIO0
|
||||
#define SD_WP_BIT 6
|
||||
|
||||
#define SDCARD_DETECT (!(BITBAND(SD_DT_REG->FIOPIN, SD_DT_BIT)))
|
||||
#define SDCARD_WP (BITBAND(SD_WP_REG->FIOPIN, SD_WP_BIT))
|
||||
#define SD_SUPPLY_VOLTAGE (1L<<21) /* 3.3V - 3.4V */
|
||||
#define CONFIG_SD_BLOCKTRANSFER 1
|
||||
#define CONFIG_SD_AUTO_RETRIES 10
|
||||
// #define SD_CHANGE_VECT
|
||||
// #define CONFIG_SD_DATACRC 1
|
||||
|
||||
#define CONFIG_UART_NUM 3
|
||||
// #define CONFIG_CPU_FREQUENCY 90315789
|
||||
#define CONFIG_CPU_FREQUENCY 96000000
|
||||
//#define CONFIG_CPU_FREQUENCY 46000000
|
||||
#define CONFIG_UART_PCLKDIV 1
|
||||
#define CONFIG_UART_TX_BUF_SHIFT 8
|
||||
#define CONFIG_UART_BAUDRATE 921600
|
||||
#define CONFIG_UART_DEADLOCKABLE
|
||||
|
||||
#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_BIT 26
|
||||
|
||||
#define SNES_CIC_D0_REG LPC_GPIO0
|
||||
#define SNES_CIC_D0_BIT 1
|
||||
|
||||
#define SNES_CIC_D1_REG LPC_GPIO0
|
||||
#define SNES_CIC_D1_BIT 0
|
||||
|
||||
#define SNES_CIC_STATUS_REG LPC_GPIO1
|
||||
#define SNES_CIC_STATUS_BIT 29
|
||||
|
||||
#define SNES_CIC_PAIR_REG LPC_GPIO1
|
||||
#define SNES_CIC_PAIR_BIT 25
|
||||
|
||||
#define FPGA_MCU_RDY_REG LPC_GPIO2
|
||||
#define FPGA_MCU_RDY_BIT 9
|
||||
|
||||
#define QSORT_MAXELEM 2048
|
||||
#define CLTBL_SIZE 100
|
||||
#define SSP_REGS LPC_SSP0
|
||||
#define SSP_PCLKREG PCLKSEL1
|
||||
// 1: PCLKSEL0
|
||||
#define SSP_PCLKBIT 10
|
||||
// 1: 20
|
||||
#define SSP_DMAID_TX 0
|
||||
// 1: 2
|
||||
#define SSP_DMAID_RX 1
|
||||
// 1: 3
|
||||
#define SSP_DMACH LPC_GPDMACH0
|
||||
|
||||
#define SD_CLKREG LPC_GPIO0
|
||||
#define SD_CMDREG LPC_GPIO0
|
||||
#define SD_DAT0REG LPC_GPIO2
|
||||
#define SD_DAT1REG LPC_GPIO2
|
||||
#define SD_DAT2REG LPC_GPIO2
|
||||
#define SD_DAT3REG LPC_GPIO2
|
||||
|
||||
#define SD_CLKPIN (7)
|
||||
#define SD_CMDPIN (9)
|
||||
#define SD_DAT0PIN (0)
|
||||
#define SD_DAT1PIN (1)
|
||||
#define SD_DAT2PIN (2)
|
||||
#define SD_DAT3PIN (3)
|
||||
|
||||
#define SD_DAT (LPC_GPIO2->FIOPIN0)
|
||||
|
||||
#endif
|
||||
547
src/ff.h
Normal file
547
src/ff.h
Normal file
@ -0,0 +1,547 @@
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ FatFs - FAT file system module include file R0.08a (C)ChaN, 2010
|
||||
/----------------------------------------------------------------------------/
|
||||
/ FatFs module is a generic FAT file system module for small embedded systems.
|
||||
/ This is a free software that opened for education, research and commercial
|
||||
/ developments under license policy of following trems.
|
||||
/
|
||||
/ Copyright (C) 2010, ChaN, all right reserved.
|
||||
/
|
||||
/ * The FatFs module is a free software and there is NO WARRANTY.
|
||||
/ * No restriction on use. You can use, modify and redistribute it for
|
||||
/ personal, non-profit or commercial product UNDER YOUR RESPONSIBILITY.
|
||||
/ * Redistributions of source code must retain the above copyright notice.
|
||||
/
|
||||
/----------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _FATFS
|
||||
#define _FATFS 8255 /* Revision ID */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "integer.h" /* Basic integer types */
|
||||
#include "ffconf.h" /* FatFs configuration options */
|
||||
|
||||
#if _FATFS != _FFCONF
|
||||
#error Wrong configuration file (ffconf.h).
|
||||
#endif
|
||||
|
||||
|
||||
/* DBCS code ranges and SBCS extend char conversion table */
|
||||
|
||||
#if _CODE_PAGE == 932 /* Japanese Shift-JIS */
|
||||
#define _DF1S 0x81 /* DBC 1st byte range 1 start */
|
||||
#define _DF1E 0x9F /* DBC 1st byte range 1 end */
|
||||
#define _DF2S 0xE0 /* DBC 1st byte range 2 start */
|
||||
#define _DF2E 0xFC /* DBC 1st byte range 2 end */
|
||||
#define _DS1S 0x40 /* DBC 2nd byte range 1 start */
|
||||
#define _DS1E 0x7E /* DBC 2nd byte range 1 end */
|
||||
#define _DS2S 0x80 /* DBC 2nd byte range 2 start */
|
||||
#define _DS2E 0xFC /* DBC 2nd byte range 2 end */
|
||||
|
||||
#elif _CODE_PAGE == 936 /* Simplified Chinese GBK */
|
||||
#define _DF1S 0x81
|
||||
#define _DF1E 0xFE
|
||||
#define _DS1S 0x40
|
||||
#define _DS1E 0x7E
|
||||
#define _DS2S 0x80
|
||||
#define _DS2E 0xFE
|
||||
|
||||
#elif _CODE_PAGE == 949 /* Korean */
|
||||
#define _DF1S 0x81
|
||||
#define _DF1E 0xFE
|
||||
#define _DS1S 0x41
|
||||
#define _DS1E 0x5A
|
||||
#define _DS2S 0x61
|
||||
#define _DS2E 0x7A
|
||||
#define _DS3S 0x81
|
||||
#define _DS3E 0xFE
|
||||
|
||||
#elif _CODE_PAGE == 950 /* Traditional Chinese Big5 */
|
||||
#define _DF1S 0x81
|
||||
#define _DF1E 0xFE
|
||||
#define _DS1S 0x40
|
||||
#define _DS1E 0x7E
|
||||
#define _DS2S 0xA1
|
||||
#define _DS2E 0xFE
|
||||
|
||||
#elif _CODE_PAGE == 437 /* U.S. (OEM) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x9A,0x90,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x49,0x49,0x49,0x8E,0x8F,0x90,0x92,0x92,0x4F,0x99,0x4F,0x55,0x55,0x59,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
|
||||
0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 720 /* Arabic (OEM) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x81,0x45,0x41,0x84,0x41,0x86,0x43,0x45,0x45,0x45,0x49,0x49,0x8D,0x8E,0x8F,0x90,0x92,0x92,0x93,0x94,0x95,0x49,0x49,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
|
||||
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 737 /* Greek (OEM) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x92,0x92,0x93,0x94,0x95,0x96,0x97,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87, \
|
||||
0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0xAA,0x92,0x93,0x94,0x95,0x96,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0x97,0xEA,0xEB,0xEC,0xE4,0xED,0xEE,0xE7,0xE8,0xF1,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 775 /* Baltic (OEM) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x9A,0x91,0xA0,0x8E,0x95,0x8F,0x80,0xAD,0xED,0x8A,0x8A,0xA1,0x8D,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0x95,0x96,0x97,0x97,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \
|
||||
0xA0,0xA1,0xE0,0xA3,0xA3,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xB5,0xB6,0xB7,0xB8,0xBD,0xBE,0xC6,0xC7,0xA5,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE3,0xE8,0xE8,0xEA,0xEA,0xEE,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 850 /* Multilingual Latin 1 (OEM) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0xDE,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x59,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \
|
||||
0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE7,0xE9,0xEA,0xEB,0xED,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 852 /* Latin 2 (OEM) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xDE,0x8F,0x80,0x9D,0xD3,0x8A,0x8A,0xD7,0x8D,0x8E,0x8F,0x90,0x91,0x91,0xE2,0x99,0x95,0x95,0x97,0x97,0x99,0x9A,0x9B,0x9B,0x9D,0x9E,0x9F, \
|
||||
0xB5,0xD6,0xE0,0xE9,0xA4,0xA4,0xA6,0xA6,0xA8,0xA8,0xAA,0x8D,0xAC,0xB8,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBD,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC6,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD2,0xD3,0xD2,0xD5,0xD6,0xD7,0xB7,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xE0,0xE1,0xE2,0xE3,0xE3,0xD5,0xE6,0xE6,0xE8,0xE9,0xE8,0xEB,0xED,0xED,0xDD,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xEB,0xFC,0xFC,0xFE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 855 /* Cyrillic (OEM) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x81,0x81,0x83,0x83,0x85,0x85,0x87,0x87,0x89,0x89,0x8B,0x8B,0x8D,0x8D,0x8F,0x8F,0x91,0x91,0x93,0x93,0x95,0x95,0x97,0x97,0x99,0x99,0x9B,0x9B,0x9D,0x9D,0x9F,0x9F, \
|
||||
0xA1,0xA1,0xA3,0xA3,0xA5,0xA5,0xA7,0xA7,0xA9,0xA9,0xAB,0xAB,0xAD,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB6,0xB6,0xB8,0xB8,0xB9,0xBA,0xBB,0xBC,0xBE,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD3,0xD3,0xD5,0xD5,0xD7,0xD7,0xDD,0xD9,0xDA,0xDB,0xDC,0xDD,0xE0,0xDF, \
|
||||
0xE0,0xE2,0xE2,0xE4,0xE4,0xE6,0xE6,0xE8,0xE8,0xEA,0xEA,0xEC,0xEC,0xEE,0xEE,0xEF,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF8,0xFA,0xFA,0xFC,0xFC,0xFD,0xFE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 857 /* Turkish (OEM) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0x98,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x98,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9E, \
|
||||
0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA6,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xDE,0x59,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 858 /* Multilingual Latin 1 + Euro (OEM) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0xDE,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x59,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \
|
||||
0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE7,0xE9,0xEA,0xEB,0xED,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 862 /* Hebrew (OEM) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
|
||||
0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 866 /* Russian (OEM) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
|
||||
0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0x90,0x91,0x92,0x93,0x9d,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,0xF0,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 874 /* Thai (OEM, Windows) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
|
||||
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 1250 /* Central Europe (Windows) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x8D,0x8E,0x8F, \
|
||||
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xA3,0xB4,0xB5,0xB6,0xB7,0xB8,0xA5,0xAA,0xBB,0xBC,0xBD,0xBC,0xAF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 1251 /* Cyrillic (Windows) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x81,0x82,0x82,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x80,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x8D,0x8E,0x8F, \
|
||||
0xA0,0xA2,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB2,0xA5,0xB5,0xB6,0xB7,0xA8,0xB9,0xAA,0xBB,0xA3,0xBD,0xBD,0xAF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF}
|
||||
|
||||
#elif _CODE_PAGE == 1252 /* Latin 1 (Windows) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0xAd,0x9B,0x8C,0x9D,0xAE,0x9F, \
|
||||
0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x9F}
|
||||
|
||||
#elif _CODE_PAGE == 1253 /* Greek (Windows) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
|
||||
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xA2,0xB8,0xB9,0xBA, \
|
||||
0xE0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xF2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xFB,0xBC,0xFD,0xBF,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 1254 /* Turkish (Windows) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x9D,0x9E,0x9F, \
|
||||
0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x9F}
|
||||
|
||||
#elif _CODE_PAGE == 1255 /* Hebrew (Windows) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
|
||||
0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 1256 /* Arabic (Windows) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x8C,0x9D,0x9E,0x9F, \
|
||||
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0x41,0xE1,0x41,0xE3,0xE4,0xE5,0xE6,0x43,0x45,0x45,0x45,0x45,0xEC,0xED,0x49,0x49,0xF0,0xF1,0xF2,0xF3,0x4F,0xF5,0xF6,0xF7,0xF8,0x55,0xFA,0x55,0x55,0xFD,0xFE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 1257 /* Baltic (Windows) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
|
||||
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xA8,0xB9,0xAA,0xBB,0xBC,0xBD,0xBE,0xAF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 1258 /* Vietnam (OEM, Windows) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0xAC,0x9D,0x9E,0x9F, \
|
||||
0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xEC,0xCD,0xCE,0xCF,0xD0,0xD1,0xF2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xFE,0x9F}
|
||||
|
||||
#elif _CODE_PAGE == 1 /* ASCII (for only non-LFN cfg) */
|
||||
#define _DF1S 0
|
||||
|
||||
#else
|
||||
#error Unknown code page
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Definitions of volume management */
|
||||
|
||||
#if _MULTI_PARTITION /* Multiple partition configuration */
|
||||
#define LD2PD(vol) (VolToPart[vol].pd) /* Get physical drive# */
|
||||
#define LD2PT(vol) (VolToPart[vol].pt) /* Get partition# */
|
||||
typedef struct {
|
||||
BYTE pd; /* Physical drive# */
|
||||
BYTE pt; /* Partition # (0-3) */
|
||||
} PARTITION;
|
||||
extern const PARTITION VolToPart[]; /* Volume - Physical location resolution table */
|
||||
|
||||
#else /* Single partition configuration */
|
||||
#define LD2PD(vol) (vol) /* Logical drive# is bound to the same physical drive# */
|
||||
#define LD2PT(vol) 0 /* Always mounts the 1st partition */
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Type of path name strings on FatFs API */
|
||||
|
||||
#if _LFN_UNICODE /* Unicode string */
|
||||
#if !_USE_LFN
|
||||
#error _LFN_UNICODE must be 0 in non-LFN cfg.
|
||||
#endif
|
||||
#ifndef _INC_TCHAR
|
||||
typedef WCHAR TCHAR;
|
||||
#define _T(x) L ## x
|
||||
#define _TEXT(x) L ## x
|
||||
#endif
|
||||
|
||||
#else /* ANSI/OEM string */
|
||||
#ifndef _INC_TCHAR
|
||||
typedef char TCHAR;
|
||||
#define _T(x) x
|
||||
#define _TEXT(x) x
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* File system object structure (FATFS) */
|
||||
|
||||
typedef struct {
|
||||
BYTE fs_type; /* FAT sub-type (0:Not mounted) */
|
||||
BYTE drv; /* Physical drive number */
|
||||
BYTE csize; /* Sectors per cluster (1,2,4...128) */
|
||||
BYTE n_fats; /* Number of FAT copies (1,2) */
|
||||
BYTE wflag; /* win[] dirty flag (1:must be written back) */
|
||||
BYTE fsi_flag; /* fsinfo dirty flag (1:must be written back) */
|
||||
WORD id; /* File system mount ID */
|
||||
WORD n_rootdir; /* Number of root directory entries (FAT12/16) */
|
||||
#if _MAX_SS != 512
|
||||
WORD ssize; /* Bytes per sector (512,1024,2048,4096) */
|
||||
#endif
|
||||
#if _FS_REENTRANT
|
||||
_SYNC_t sobj; /* Identifier of sync object */
|
||||
#endif
|
||||
#if !_FS_READONLY
|
||||
DWORD last_clust; /* Last allocated cluster */
|
||||
DWORD free_clust; /* Number of free clusters */
|
||||
DWORD fsi_sector; /* fsinfo sector (FAT32) */
|
||||
#endif
|
||||
#if _FS_RPATH
|
||||
DWORD cdir; /* Current directory start cluster (0:root) */
|
||||
#endif
|
||||
DWORD n_fatent; /* Number of FAT entries (= number of clusters + 2) */
|
||||
DWORD fsize; /* Sectors per FAT */
|
||||
DWORD fatbase; /* FAT start sector */
|
||||
DWORD dirbase; /* Root directory start sector (FAT32:Cluster#) */
|
||||
DWORD database; /* Data start sector */
|
||||
DWORD winsect; /* Current sector appearing in the win[] */
|
||||
BYTE win[_MAX_SS]; /* Disk access window for Directory, FAT (and Data on tiny cfg) */
|
||||
} FATFS;
|
||||
|
||||
|
||||
|
||||
/* File object structure (FIL) */
|
||||
|
||||
typedef struct {
|
||||
FATFS* fs; /* Pointer to the owner file system object */
|
||||
WORD id; /* Owner file system mount ID */
|
||||
BYTE flag; /* File status flags */
|
||||
BYTE pad1;
|
||||
DWORD fptr; /* File read/write pointer (0 on file open) */
|
||||
DWORD fsize; /* File size */
|
||||
DWORD org_clust; /* File start cluster (0 when fsize==0) */
|
||||
DWORD curr_clust; /* Current cluster */
|
||||
DWORD dsect; /* Current data sector */
|
||||
#if !_FS_READONLY
|
||||
DWORD dir_sect; /* Sector containing the directory entry */
|
||||
BYTE* dir_ptr; /* Ponter to the directory entry in the window */
|
||||
#endif
|
||||
#if _USE_FASTSEEK
|
||||
DWORD* cltbl; /* Pointer to the cluster link map table (null on file open) */
|
||||
#endif
|
||||
#if _FS_SHARE
|
||||
UINT lockid; /* File lock ID (index of file semaphore table) */
|
||||
#endif
|
||||
#if !_FS_TINY
|
||||
BYTE buf[_MAX_SS]; /* File data read/write buffer */
|
||||
#endif
|
||||
} FIL;
|
||||
|
||||
|
||||
|
||||
/* Directory object structure (DIR) */
|
||||
|
||||
typedef struct {
|
||||
FATFS* fs; /* Pointer to the owner file system object */
|
||||
WORD id; /* Owner file system mount ID */
|
||||
WORD index; /* Current read/write index number */
|
||||
DWORD sclust; /* Table start cluster (0:Root dir) */
|
||||
DWORD clust; /* Current cluster */
|
||||
DWORD sect; /* Current sector */
|
||||
BYTE* dir; /* Pointer to the current SFN entry in the win[] */
|
||||
BYTE* fn; /* Pointer to the SFN (in/out) {file[8],ext[3],status[1]} */
|
||||
#if _USE_LFN
|
||||
WCHAR* lfn; /* Pointer to the LFN working buffer */
|
||||
WORD lfn_idx; /* Last matched LFN index number (0xFFFF:No LFN) */
|
||||
#endif
|
||||
} DIR;
|
||||
|
||||
|
||||
|
||||
/* File status structure (FILINFO) */
|
||||
|
||||
typedef struct {
|
||||
DWORD fsize; /* File size */
|
||||
WORD fdate; /* Last modified date */
|
||||
WORD ftime; /* Last modified time */
|
||||
BYTE fattrib; /* Attribute */
|
||||
TCHAR fname[13]; /* Short file name (8.3 format) */
|
||||
DWORD clust; /* start cluster */
|
||||
#if _USE_LFN
|
||||
TCHAR* lfname; /* Pointer to the LFN buffer */
|
||||
UINT lfsize; /* Size of LFN buffer in TCHAR */
|
||||
#endif
|
||||
} FILINFO;
|
||||
|
||||
|
||||
|
||||
/* File function return code (FRESULT) */
|
||||
|
||||
typedef enum {
|
||||
FR_OK = 0, /* (0) Succeeded */
|
||||
FR_DISK_ERR, /* (1) A hard error occured in the low level disk I/O layer */
|
||||
FR_INT_ERR, /* (2) Assertion failed */
|
||||
FR_NOT_READY, /* (3) The physical drive cannot work */
|
||||
FR_NO_FILE, /* (4) Could not find the file */
|
||||
FR_NO_PATH, /* (5) Could not find the path */
|
||||
FR_INVALID_NAME, /* (6) The path name format is invalid */
|
||||
FR_DENIED, /* (7) Acces denied due to prohibited access or directory full */
|
||||
FR_EXIST, /* (8) Acces denied due to prohibited access */
|
||||
FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */
|
||||
FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */
|
||||
FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */
|
||||
FR_NOT_ENABLED, /* (12) The volume has no work area */
|
||||
FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume on the physical drive */
|
||||
FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any parameter error */
|
||||
FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */
|
||||
FR_LOCKED, /* (16) The operation is rejected according to the file shareing policy */
|
||||
FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */
|
||||
FR_TOO_MANY_OPEN_FILES /* (18) Number of open files > _FS_SHARE */
|
||||
} FRESULT;
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* FatFs module application interface */
|
||||
|
||||
/* Low Level functions */
|
||||
FRESULT l_openfilebycluster(FATFS *fs, FIL *fp, const TCHAR *path, DWORD clust, DWORD fsize); /* Open a file by its start cluster using supplied file size */
|
||||
FRESULT l_opendirbycluster (FATFS *fs, DIR *dj, const TCHAR *path, DWORD clust);
|
||||
|
||||
/* application level functions */
|
||||
FRESULT f_mount (BYTE, FATFS*); /* Mount/Unmount a logical drive */
|
||||
FRESULT f_open (FIL*, const TCHAR*, BYTE); /* Open or create a file */
|
||||
FRESULT f_read (FIL*, void*, UINT, UINT*); /* Read data from a file */
|
||||
FRESULT f_lseek (FIL*, DWORD); /* Move file pointer of a file object */
|
||||
FRESULT f_close (FIL*); /* Close an open file object */
|
||||
FRESULT f_opendir (DIR*, const TCHAR*); /* Open an existing directory */
|
||||
FRESULT f_readdir (DIR*, FILINFO*); /* Read a directory item */
|
||||
FRESULT f_stat (const TCHAR*, FILINFO*); /* Get file status */
|
||||
|
||||
#if !_FS_READONLY
|
||||
FRESULT f_write (FIL*, const void*, UINT, UINT*); /* Write data to a file */
|
||||
FRESULT f_getfree (const TCHAR*, DWORD*, FATFS**); /* Get number of free clusters on the drive */
|
||||
FRESULT f_truncate (FIL*); /* Truncate file */
|
||||
FRESULT f_sync (FIL*); /* Flush cached data of a writing file */
|
||||
FRESULT f_unlink (const TCHAR*); /* Delete an existing file or directory */
|
||||
FRESULT f_mkdir (const TCHAR*); /* Create a new directory */
|
||||
FRESULT f_chmod (const TCHAR*, BYTE, BYTE); /* Change attriburte of the file/dir */
|
||||
FRESULT f_utime (const TCHAR*, const FILINFO*); /* Change timestamp of the file/dir */
|
||||
FRESULT f_rename (const TCHAR*, const TCHAR*); /* Rename/Move a file or directory */
|
||||
#endif
|
||||
|
||||
#if _USE_FORWARD
|
||||
FRESULT f_forward (FIL*, UINT(*)(const BYTE*,UINT), UINT, UINT*); /* Forward data to the stream */
|
||||
#endif
|
||||
|
||||
#if _USE_MKFS
|
||||
FRESULT f_mkfs (BYTE, BYTE, UINT); /* Create a file system on the drive */
|
||||
#endif
|
||||
|
||||
#if _FS_RPATH
|
||||
FRESULT f_chdrive (BYTE); /* Change current drive */
|
||||
FRESULT f_chdir (const TCHAR*); /* Change current directory */
|
||||
FRESULT f_getcwd (TCHAR*, UINT); /* Get current directory */
|
||||
#endif
|
||||
|
||||
#if _USE_STRFUNC
|
||||
int f_putc (TCHAR, FIL*); /* Put a character to the file */
|
||||
int f_puts (const TCHAR*, FIL*); /* Put a string to the file */
|
||||
int f_printf (FIL*, const TCHAR*, ...); /* Put a formatted string to the file */
|
||||
TCHAR* f_gets (TCHAR*, int, FIL*); /* Get a string from the file */
|
||||
#ifndef EOF
|
||||
#define EOF (-1)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define f_eof(fp) (((fp)->fptr == (fp)->fsize) ? 1 : 0)
|
||||
#define f_error(fp) (((fp)->flag & FA__ERROR) ? 1 : 0)
|
||||
#define f_tell(fp) ((fp)->fptr)
|
||||
#define f_size(fp) ((fp)->fsize)
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* Additional user defined functions */
|
||||
|
||||
/* RTC function */
|
||||
#if !_FS_READONLY
|
||||
DWORD get_fattime (void);
|
||||
#endif
|
||||
|
||||
/* Unicode support functions */
|
||||
#if _USE_LFN /* Unicode - OEM code conversion */
|
||||
WCHAR ff_convert (WCHAR, UINT); /* OEM-Unicode bidirectional conversion */
|
||||
WCHAR ff_wtoupper (WCHAR); /* Unicode upper-case conversion */
|
||||
#if _USE_LFN == 3 /* Memory functions */
|
||||
void* ff_memalloc (UINT); /* Allocate memory block */
|
||||
void ff_memfree (void*); /* Free memory block */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Sync functions */
|
||||
#if _FS_REENTRANT
|
||||
int ff_cre_syncobj (BYTE, _SYNC_t*);/* Create a sync object */
|
||||
int ff_del_syncobj (_SYNC_t); /* Delete a sync object */
|
||||
int ff_req_grant (_SYNC_t); /* Lock sync object */
|
||||
void ff_rel_grant (_SYNC_t); /* Unlock sync object */
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* Flags and offset address */
|
||||
|
||||
|
||||
/* File access control and file status flags (FIL.flag) */
|
||||
|
||||
#define FA_READ 0x01
|
||||
#define FA_OPEN_EXISTING 0x00
|
||||
#define FA__ERROR 0x80
|
||||
|
||||
#if !_FS_READONLY
|
||||
#define FA_WRITE 0x02
|
||||
#define FA_CREATE_NEW 0x04
|
||||
#define FA_CREATE_ALWAYS 0x08
|
||||
#define FA_OPEN_ALWAYS 0x10
|
||||
#define FA__WRITTEN 0x20
|
||||
#define FA__DIRTY 0x40
|
||||
#endif
|
||||
|
||||
|
||||
/* FAT sub type (FATFS.fs_type) */
|
||||
|
||||
#define FS_FAT12 1
|
||||
#define FS_FAT16 2
|
||||
#define FS_FAT32 3
|
||||
|
||||
|
||||
/* File attribute bits for directory entry */
|
||||
|
||||
#define AM_RDO 0x01 /* Read only */
|
||||
#define AM_HID 0x02 /* Hidden */
|
||||
#define AM_SYS 0x04 /* System */
|
||||
#define AM_VOL 0x08 /* Volume label */
|
||||
#define AM_LFN 0x0F /* LFN entry */
|
||||
#define AM_DIR 0x10 /* Directory */
|
||||
#define AM_ARC 0x20 /* Archive */
|
||||
#define AM_MASK 0x3F /* Mask of defined bits */
|
||||
|
||||
|
||||
/* Fast seek function */
|
||||
#define CREATE_LINKMAP 0xFFFFFFFF
|
||||
|
||||
|
||||
/*--------------------------------*/
|
||||
/* Multi-byte word access macros */
|
||||
|
||||
#if _WORD_ACCESS == 1 /* Enable word access to the FAT structure */
|
||||
#define LD_WORD(ptr) (WORD)(*(WORD*)(BYTE*)(ptr))
|
||||
#define LD_DWORD(ptr) (DWORD)(*(DWORD*)(BYTE*)(ptr))
|
||||
#define ST_WORD(ptr,val) *(WORD*)(BYTE*)(ptr)=(WORD)(val)
|
||||
#define ST_DWORD(ptr,val) *(DWORD*)(BYTE*)(ptr)=(DWORD)(val)
|
||||
#else /* Use byte-by-byte access to the FAT structure */
|
||||
#define LD_WORD(ptr) (WORD)(((WORD)*(BYTE*)((ptr)+1)<<8)|(WORD)*(BYTE*)(ptr))
|
||||
#define LD_DWORD(ptr) (DWORD)(((DWORD)*(BYTE*)((ptr)+3)<<24)|((DWORD)*(BYTE*)((ptr)+2)<<16)|((WORD)*(BYTE*)((ptr)+1)<<8)|*(BYTE*)(ptr))
|
||||
#define ST_WORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *(BYTE*)((ptr)+1)=(BYTE)((WORD)(val)>>8)
|
||||
#define ST_DWORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *(BYTE*)((ptr)+1)=(BYTE)((WORD)(val)>>8); *(BYTE*)((ptr)+2)=(BYTE)((DWORD)(val)>>16); *(BYTE*)((ptr)+3)=(BYTE)((DWORD)(val)>>24)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _FATFS */
|
||||
188
src/ffconf.h
Normal file
188
src/ffconf.h
Normal file
@ -0,0 +1,188 @@
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ FatFs - FAT file system module configuration file R0.08a (C)ChaN, 2010
|
||||
/----------------------------------------------------------------------------/
|
||||
/
|
||||
/ CAUTION! Do not forget to make clean the project after any changes to
|
||||
/ the configuration options.
|
||||
/
|
||||
/----------------------------------------------------------------------------*/
|
||||
#ifndef _FFCONF
|
||||
#define _FFCONF 8255 /* Revision ID */
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Function and Buffer Configurations
|
||||
/----------------------------------------------------------------------------*/
|
||||
|
||||
#define _FS_TINY 0 /* 0:Normal or 1:Tiny */
|
||||
/* When _FS_TINY is set to 1, FatFs uses the sector buffer in the file system
|
||||
/ object instead of the sector buffer in the individual file object for file
|
||||
/ data transfer. This reduces memory consumption 512 bytes each file object. */
|
||||
|
||||
|
||||
#define _FS_READONLY 0 /* 0:Read/Write or 1:Read only */
|
||||
/* Setting _FS_READONLY to 1 defines read only configuration. This removes
|
||||
/ writing functions, f_write, f_sync, f_unlink, f_mkdir, f_chmod, f_rename,
|
||||
/ f_truncate and useless f_getfree. */
|
||||
|
||||
|
||||
#define _FS_MINIMIZE 0 /* 0 to 3 */
|
||||
/* The _FS_MINIMIZE option defines minimization level to remove some functions.
|
||||
/
|
||||
/ 0: Full function.
|
||||
/ 1: f_stat, f_getfree, f_unlink, f_mkdir, f_chmod, f_truncate and f_rename
|
||||
/ are removed.
|
||||
/ 2: f_opendir and f_readdir are removed in addition to 1.
|
||||
/ 3: f_lseek is removed in addition to 2. */
|
||||
|
||||
|
||||
#define _USE_STRFUNC 0 /* 0:Disable or 1/2:Enable */
|
||||
/* To enable string functions, set _USE_STRFUNC to 1 or 2. */
|
||||
|
||||
|
||||
#define _USE_MKFS 0 /* 0:Disable or 1:Enable */
|
||||
/* To enable f_mkfs function, set _USE_MKFS to 1 and set _FS_READONLY to 0 */
|
||||
|
||||
|
||||
#define _USE_FORWARD 0 /* 0:Disable or 1:Enable */
|
||||
/* To enable f_forward function, set _USE_FORWARD to 1 and set _FS_TINY to 1. */
|
||||
|
||||
|
||||
#define _USE_FASTSEEK 1 /* 0:Disable or 1:Enable */
|
||||
/* To enable fast seek feature, set _USE_FASTSEEK to 1. */
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Locale and Namespace Configurations
|
||||
/----------------------------------------------------------------------------*/
|
||||
|
||||
#define _CODE_PAGE 1252
|
||||
/* The _CODE_PAGE specifies the OEM code page to be used on the target system.
|
||||
/ Incorrect setting of the code page can cause a file open failure.
|
||||
/
|
||||
/ 932 - Japanese Shift-JIS (DBCS, OEM, Windows)
|
||||
/ 936 - Simplified Chinese GBK (DBCS, OEM, Windows)
|
||||
/ 949 - Korean (DBCS, OEM, Windows)
|
||||
/ 950 - Traditional Chinese Big5 (DBCS, OEM, Windows)
|
||||
/ 1250 - Central Europe (Windows)
|
||||
/ 1251 - Cyrillic (Windows)
|
||||
/ 1252 - Latin 1 (Windows)
|
||||
/ 1253 - Greek (Windows)
|
||||
/ 1254 - Turkish (Windows)
|
||||
/ 1255 - Hebrew (Windows)
|
||||
/ 1256 - Arabic (Windows)
|
||||
/ 1257 - Baltic (Windows)
|
||||
/ 1258 - Vietnam (OEM, Windows)
|
||||
/ 437 - U.S. (OEM)
|
||||
/ 720 - Arabic (OEM)
|
||||
/ 737 - Greek (OEM)
|
||||
/ 775 - Baltic (OEM)
|
||||
/ 850 - Multilingual Latin 1 (OEM)
|
||||
/ 858 - Multilingual Latin 1 + Euro (OEM)
|
||||
/ 852 - Latin 2 (OEM)
|
||||
/ 855 - Cyrillic (OEM)
|
||||
/ 866 - Russian (OEM)
|
||||
/ 857 - Turkish (OEM)
|
||||
/ 862 - Hebrew (OEM)
|
||||
/ 874 - Thai (OEM, Windows)
|
||||
/ 1 - ASCII only (Valid for non LFN cfg.)
|
||||
*/
|
||||
|
||||
|
||||
#define _USE_LFN 1 /* 0 to 3 */
|
||||
#define _MAX_LFN 255 /* Maximum LFN length to handle (12 to 255) */
|
||||
/* The _USE_LFN option switches the LFN support.
|
||||
/
|
||||
/ 0: Disable LFN feature. _MAX_LFN and _LFN_UNICODE have no effect.
|
||||
/ 1: Enable LFN with static working buffer on the BSS. Always NOT reentrant.
|
||||
/ 2: Enable LFN with dynamic working buffer on the STACK.
|
||||
/ 3: Enable LFN with dynamic working buffer on the HEAP.
|
||||
/
|
||||
/ The LFN working buffer occupies (_MAX_LFN + 1) * 2 bytes. To enable LFN,
|
||||
/ Unicode handling functions ff_convert() and ff_wtoupper() must be added
|
||||
/ to the project. When enable to use heap, memory control functions
|
||||
/ ff_memalloc() and ff_memfree() must be added to the project. */
|
||||
|
||||
|
||||
#define _LFN_UNICODE 0 /* 0:ANSI/OEM or 1:Unicode */
|
||||
/* To switch the character code set on FatFs API to Unicode,
|
||||
/ enable LFN feature and set _LFN_UNICODE to 1. */
|
||||
|
||||
|
||||
#define _FS_RPATH 2 /* 0 to 2 */
|
||||
/* The _FS_RPATH option configures relative path feature.
|
||||
/
|
||||
/ 0: Disable relative path feature and remove related functions.
|
||||
/ 1: Enable relative path. f_chdrive() and f_chdir() are available.
|
||||
/ 2: f_getcwd() is available in addition to 1.
|
||||
/
|
||||
/ Note that output of the f_readdir fnction is affected by this option. */
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Physical Drive Configurations
|
||||
/----------------------------------------------------------------------------*/
|
||||
|
||||
#define _VOLUMES 1
|
||||
/* Number of volumes (logical drives) to be used. */
|
||||
|
||||
|
||||
#define _MAX_SS 512 /* 512, 1024, 2048 or 4096 */
|
||||
/* Maximum sector size to be handled.
|
||||
/ Always set 512 for memory card and hard disk but a larger value may be
|
||||
/ required for floppy disk (512/1024) and optical disk (512/2048).
|
||||
/ When _MAX_SS is larger than 512, GET_SECTOR_SIZE command must be implememted
|
||||
/ to the disk_ioctl function. */
|
||||
|
||||
|
||||
#define _MULTI_PARTITION 0 /* 0:Single partition or 1:Multiple partition */
|
||||
/* When set to 0, each volume is bound to the same physical drive number and
|
||||
/ it can mount only first primaly partition. When it is set to 1, each volume
|
||||
/ is tied to the partitions listed in VolToPart[]. */
|
||||
|
||||
|
||||
#define _USE_ERASE 0 /* 0:Disable or 1:Enable */
|
||||
/* To enable sector erase feature, set _USE_ERASE to 1. */
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ System Configurations
|
||||
/----------------------------------------------------------------------------*/
|
||||
|
||||
#define _WORD_ACCESS 0 /* 0 or 1 */
|
||||
/* Set 0 first and it is always compatible with all platforms. The _WORD_ACCESS
|
||||
/ option defines which access method is used to the word data on the FAT volume.
|
||||
/
|
||||
/ 0: Byte-by-byte access.
|
||||
/ 1: Word access. Do not choose this unless following condition is met.
|
||||
/
|
||||
/ When the byte order on the memory is big-endian or address miss-aligned word
|
||||
/ access results incorrect behavior, the _WORD_ACCESS must be set to 0.
|
||||
/ If it is not the case, the value can also be set to 1 to improve the
|
||||
/ performance and code size. */
|
||||
|
||||
|
||||
/* Include a header file here to define sync object types on the O/S */
|
||||
/* #include <windows.h>, <ucos_ii.h.h>, <semphr.h> or ohters. */
|
||||
|
||||
#define _FS_REENTRANT 0 /* 0:Disable or 1:Enable */
|
||||
#define _FS_TIMEOUT 1000 /* Timeout period in unit of time ticks */
|
||||
#define _SYNC_t HANDLE /* O/S dependent type of sync object. e.g. HANDLE, OS_EVENT*, ID and etc.. */
|
||||
|
||||
/* The _FS_REENTRANT option switches the reentrancy of the FatFs module.
|
||||
/
|
||||
/ 0: Disable reentrancy. _SYNC_t and _FS_TIMEOUT have no effect.
|
||||
/ 1: Enable reentrancy. Also user provided synchronization handlers,
|
||||
/ ff_req_grant, ff_rel_grant, ff_del_syncobj and ff_cre_syncobj
|
||||
/ function must be added to the project. */
|
||||
|
||||
|
||||
#define _FS_SHARE 0 /* 0:Disable or >=1:Enable */
|
||||
/* To enable file shareing feature, set _FS_SHARE to 1 or greater. The value
|
||||
defines how many files can be opened simultaneously. */
|
||||
|
||||
|
||||
#endif /* _FFCONFIG */
|
||||
117
src/fileops.c
Normal file
117
src/fileops.c
Normal file
@ -0,0 +1,117 @@
|
||||
/* sd2snes - SD card based universal cartridge for the SNES
|
||||
Copyright (C) 2009-2010 Maximilian Rehkopf <otakon@gmx.net>
|
||||
AVR firmware portion
|
||||
|
||||
Inspired by and based on code from sd2iec, written by Ingo Korb et al.
|
||||
See sdcard.c|h, config.h.
|
||||
|
||||
FAT file system access based on code by ChaN, Jim Brain, Ingo Korb,
|
||||
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
|
||||
|
||||
fileops.c: simple file access functions
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "uart.h"
|
||||
#include "ff.h"
|
||||
#include "fileops.h"
|
||||
#include "diskio.h"
|
||||
|
||||
/*
|
||||
WCHAR ff_convert(WCHAR w, UINT dir) {
|
||||
return w;
|
||||
}*/
|
||||
|
||||
int newcard;
|
||||
|
||||
void file_init() {
|
||||
file_res=f_mount(0, &fatfs);
|
||||
newcard = 0;
|
||||
}
|
||||
|
||||
void file_reinit(void) {
|
||||
disk_init();
|
||||
file_init();
|
||||
}
|
||||
|
||||
FRESULT dir_open_by_filinfo(DIR* dir, FILINFO* fno) {
|
||||
return l_opendirbycluster(&fatfs, dir, (TCHAR*)"", fno->clust);
|
||||
}
|
||||
|
||||
void file_open_by_filinfo(FILINFO* fno) {
|
||||
file_res = l_openfilebycluster(&fatfs, &file_handle, (TCHAR*)"", fno->clust, fno->fsize);
|
||||
}
|
||||
|
||||
void file_open(uint8_t* filename, BYTE flags) {
|
||||
if (disk_state == DISK_CHANGED) {
|
||||
file_reinit();
|
||||
newcard = 1;
|
||||
}
|
||||
file_res = f_open(&file_handle, (TCHAR*)filename, flags);
|
||||
file_block_off = sizeof(file_buf);
|
||||
file_block_max = sizeof(file_buf);
|
||||
file_status = file_res ? FILE_ERR : FILE_OK;
|
||||
}
|
||||
|
||||
void file_close() {
|
||||
file_res = f_close(&file_handle);
|
||||
}
|
||||
|
||||
void file_seek(uint32_t offset) {
|
||||
file_res = f_lseek(&file_handle, (DWORD)offset);
|
||||
}
|
||||
|
||||
UINT file_read() {
|
||||
UINT bytes_read;
|
||||
file_res = f_read(&file_handle, file_buf, sizeof(file_buf), &bytes_read);
|
||||
return bytes_read;
|
||||
}
|
||||
|
||||
UINT file_write() {
|
||||
UINT bytes_written;
|
||||
file_res = f_write(&file_handle, file_buf, sizeof(file_buf), &bytes_written);
|
||||
if(bytes_written < sizeof(file_buf)) {
|
||||
printf("wrote less than expected - card full?\n");
|
||||
}
|
||||
return bytes_written;
|
||||
}
|
||||
|
||||
UINT file_readblock(void* buf, uint32_t addr, uint16_t size) {
|
||||
UINT bytes_read;
|
||||
file_res = f_lseek(&file_handle, addr);
|
||||
if(file_handle.fptr != addr) {
|
||||
return 0;
|
||||
}
|
||||
file_res = f_read(&file_handle, buf, size, &bytes_read);
|
||||
return bytes_read;
|
||||
}
|
||||
|
||||
UINT file_writeblock(void* buf, uint32_t addr, uint16_t size) {
|
||||
UINT bytes_written;
|
||||
file_res = f_lseek(&file_handle, addr);
|
||||
if(file_res) return 0;
|
||||
file_res = f_write(&file_handle, buf, size, &bytes_written);
|
||||
return bytes_written;
|
||||
}
|
||||
|
||||
uint8_t file_getc() {
|
||||
if(file_block_off == file_block_max) {
|
||||
file_block_max = file_read();
|
||||
if(file_block_max == 0) file_status = FILE_EOF;
|
||||
file_block_off = 0;
|
||||
}
|
||||
return file_buf[file_block_off++];
|
||||
}
|
||||
54
src/fileops.h
Normal file
54
src/fileops.h
Normal file
@ -0,0 +1,54 @@
|
||||
/* sd2snes - SD card based universal cartridge for the SNES
|
||||
Copyright (C) 2009-2010 Maximilian Rehkopf <otakon@gmx.net>
|
||||
AVR firmware portion
|
||||
|
||||
Inspired by and based on code from sd2iec, written by Ingo Korb et al.
|
||||
See sdcard.c|h, config.h.
|
||||
|
||||
FAT file system access based on code by ChaN, Jim Brain, Ingo Korb,
|
||||
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
|
||||
|
||||
fileops.h: simple file access functions
|
||||
*/
|
||||
|
||||
#ifndef FILEOPS_H
|
||||
#define FILEOPS_H
|
||||
#include <arm/NXP/LPC17xx/LPC17xx.h>
|
||||
#include "ff.h"
|
||||
|
||||
enum filestates { FILE_OK=0, FILE_ERR, FILE_EOF };
|
||||
|
||||
BYTE file_buf[512];
|
||||
FATFS fatfs;
|
||||
FIL file_handle;
|
||||
FRESULT file_res;
|
||||
uint8_t file_lfn[258];
|
||||
uint16_t file_block_off, file_block_max;
|
||||
enum filestates file_status;
|
||||
|
||||
void file_init(void);
|
||||
void file_open(uint8_t* filename, BYTE flags);
|
||||
FRESULT dir_open_by_filinfo(DIR* dir, FILINFO* fno_param);
|
||||
void file_open_by_filinfo(FILINFO* fno);
|
||||
void file_close(void);
|
||||
void file_seek(uint32_t offset);
|
||||
UINT file_read(void);
|
||||
UINT file_write(void);
|
||||
UINT file_readblock(void* buf, uint32_t addr, uint16_t size);
|
||||
UINT file_writeblock(void* buf, uint32_t addr, uint16_t size);
|
||||
|
||||
uint8_t file_getc(void);
|
||||
#endif
|
||||
321
src/filetypes.c
Normal file
321
src/filetypes.c
Normal file
@ -0,0 +1,321 @@
|
||||
/* sd2snes - SD card based universal cartridge for the SNES
|
||||
Copyright (C) 2009-2010 Maximilian Rehkopf <otakon@gmx.net>
|
||||
AVR firmware portion
|
||||
|
||||
Inspired by and based on code from sd2iec, written by Ingo Korb et al.
|
||||
See sdcard.c|h, config.h.
|
||||
|
||||
FAT file system access based on code by ChaN, Jim Brain, Ingo Korb,
|
||||
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
|
||||
|
||||
filetypes.c: directory scanning and file type detection
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "config.h"
|
||||
#include "uart.h"
|
||||
#include "filetypes.h"
|
||||
#include "ff.h"
|
||||
#include "smc.h"
|
||||
#include "fileops.h"
|
||||
#include "crc32.h"
|
||||
#include "memory.h"
|
||||
#include "led.h"
|
||||
#include "sort.h"
|
||||
|
||||
uint16_t scan_flat(const char* path) {
|
||||
DIR dir;
|
||||
FRESULT res;
|
||||
FILINFO fno;
|
||||
fno.lfname = NULL;
|
||||
res = f_opendir(&dir, (TCHAR*)path);
|
||||
uint16_t numentries = 0;
|
||||
if (res == FR_OK) {
|
||||
for (;;) {
|
||||
res = f_readdir(&dir, &fno);
|
||||
if(res != FR_OK || fno.fname[0] == 0)break;
|
||||
numentries++;
|
||||
}
|
||||
}
|
||||
return numentries;
|
||||
}
|
||||
|
||||
uint32_t scan_dir(char* path, FILINFO* fno_param, char mkdb, uint32_t this_dir_tgt) {
|
||||
DIR dir;
|
||||
FILINFO fno;
|
||||
FRESULT res;
|
||||
uint8_t len;
|
||||
TCHAR* fn;
|
||||
static unsigned char depth = 0;
|
||||
static uint32_t crc;
|
||||
static uint32_t db_tgt;
|
||||
static uint32_t next_subdir_tgt;
|
||||
static uint32_t parent_tgt;
|
||||
static uint32_t dir_end = 0;
|
||||
static uint8_t was_empty = 0;
|
||||
static uint16_t num_files_total = 0;
|
||||
static uint16_t num_dirs_total = 0;
|
||||
uint32_t dir_tgt;
|
||||
uint16_t numentries;
|
||||
uint32_t dirsize;
|
||||
uint8_t pass = 0;
|
||||
char buf[7];
|
||||
char *size_units[3] = {" ", "k", "M"};
|
||||
uint32_t entry_fsize;
|
||||
uint8_t entry_unit_idx;
|
||||
|
||||
dir_tgt = this_dir_tgt;
|
||||
if(depth==0) {
|
||||
crc = 0;
|
||||
db_tgt = SRAM_DB_ADDR+0x10;
|
||||
dir_tgt = SRAM_DIR_ADDR;
|
||||
next_subdir_tgt = SRAM_DIR_ADDR;
|
||||
this_dir_tgt = SRAM_DIR_ADDR;
|
||||
parent_tgt = 0;
|
||||
printf("root dir @%lx\n", dir_tgt);
|
||||
}
|
||||
|
||||
fno.lfsize = 255;
|
||||
fno.lfname = (TCHAR*)file_lfn;
|
||||
numentries=0;
|
||||
for(pass = 0; pass < 2; pass++) {
|
||||
if(pass) {
|
||||
num_dirs_total++;
|
||||
dirsize = 4*(numentries);
|
||||
next_subdir_tgt += dirsize + 4;
|
||||
if(parent_tgt) next_subdir_tgt += 4;
|
||||
if(next_subdir_tgt > dir_end) {
|
||||
dir_end = next_subdir_tgt;
|
||||
}
|
||||
// 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) {
|
||||
// printf("d=%d Saving %lx to Address %lx [end]\n", depth, 0L, next_subdir_tgt - 4);
|
||||
sram_writelong(0L, next_subdir_tgt - 4);
|
||||
}
|
||||
}
|
||||
if(fno_param) {
|
||||
res = dir_open_by_filinfo(&dir, fno_param);
|
||||
} else {
|
||||
res = f_opendir(&dir, path);
|
||||
}
|
||||
if (res == FR_OK) {
|
||||
if(pass && parent_tgt && mkdb) {
|
||||
/* write backlink to parent dir
|
||||
switch to next bank if record does not fit in current bank */
|
||||
if((db_tgt&0xffff) > ((0x10000-(sizeof(next_subdir_tgt)+sizeof(len)+4))&0xffff)) {
|
||||
printf("switch! old=%lx ", db_tgt);
|
||||
db_tgt &= 0xffff0000;
|
||||
db_tgt += 0x00010000;
|
||||
printf("new=%lx\n", db_tgt);
|
||||
}
|
||||
// printf("writing link to parent, %lx to address %lx [../]\n", parent_tgt-SRAM_MENU_ADDR, db_tgt);
|
||||
sram_writelong((parent_tgt-SRAM_MENU_ADDR), db_tgt);
|
||||
sram_writebyte(0, db_tgt+sizeof(next_subdir_tgt));
|
||||
sram_writeblock("../\0", db_tgt+sizeof(next_subdir_tgt)+sizeof(len), 4);
|
||||
sram_writelong((db_tgt-SRAM_MENU_ADDR)|((uint32_t)0x81<<24), dir_tgt);
|
||||
db_tgt += sizeof(next_subdir_tgt)+sizeof(len)+4;
|
||||
dir_tgt += 4;
|
||||
}
|
||||
len = strlen((char*)path);
|
||||
for (;;) {
|
||||
// toggle_read_led();
|
||||
res = f_readdir(&dir, &fno);
|
||||
if (res != FR_OK || fno.fname[0] == 0) {
|
||||
if(pass) {
|
||||
if(!numentries) was_empty=1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
fn = *fno.lfname ? fno.lfname : fno.fname;
|
||||
if ((*fn == '.') || !(memcmp(fn, SYS_DIR_NAME, sizeof(SYS_DIR_NAME)))) continue;
|
||||
if (fno.fattrib & AM_DIR) {
|
||||
depth++;
|
||||
if(depth < FS_MAX_DEPTH) {
|
||||
numentries++;
|
||||
if(pass) {
|
||||
path[len]='/';
|
||||
strncpy(path+len+1, (char*)fn, sizeof(fs_path)-len);
|
||||
if(mkdb) {
|
||||
uint16_t pathlen = strlen(path);
|
||||
// printf("d=%d Saving %lx to Address %lx [dir]\n", depth, db_tgt, dir_tgt);
|
||||
/* save element:
|
||||
- path name
|
||||
- pointer to sub dir structure */
|
||||
if((db_tgt&0xffff) > ((0x10000-(sizeof(next_subdir_tgt) + sizeof(len) + pathlen + 2))&0xffff)) {
|
||||
printf("switch! old=%lx ", db_tgt);
|
||||
db_tgt &= 0xffff0000;
|
||||
db_tgt += 0x00010000;
|
||||
printf("new=%lx\n", db_tgt);
|
||||
}
|
||||
// printf(" Saving dir descriptor to %lx tgt=%lx, path=%s\n", db_tgt, next_subdir_tgt, path);
|
||||
/* write element pointer to current dir structure */
|
||||
sram_writelong((db_tgt-SRAM_MENU_ADDR)|((uint32_t)0x80<<24), dir_tgt);
|
||||
/* save element:
|
||||
- path name
|
||||
- pointer to sub dir structure */
|
||||
sram_writelong((next_subdir_tgt-SRAM_MENU_ADDR), 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;
|
||||
}
|
||||
parent_tgt = this_dir_tgt;
|
||||
scan_dir(path, &fno, mkdb, next_subdir_tgt);
|
||||
dir_tgt += 4;
|
||||
was_empty = 0;
|
||||
}
|
||||
}
|
||||
depth--;
|
||||
path[len]=0;
|
||||
} else {
|
||||
SNES_FTYPE type = determine_filetype((char*)fn);
|
||||
if(type != TYPE_UNKNOWN) {
|
||||
num_files_total++;
|
||||
numentries++;
|
||||
if(pass) {
|
||||
if(mkdb) {
|
||||
/* snes_romprops_t romprops; */
|
||||
path[len]='/';
|
||||
strncpy(path+len+1, (char*)fn, sizeof(fs_path)-len);
|
||||
uint16_t pathlen = strlen(path);
|
||||
switch(type) {
|
||||
case TYPE_IPS:
|
||||
case TYPE_SMC:
|
||||
/* 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 */
|
||||
DBG_FS printf("d=%d Saving %lX to Address %lX [file %s]\n", depth, db_tgt, dir_tgt, path);
|
||||
if((db_tgt&0xffff) > ((0x10000-(sizeof(len) + pathlen + sizeof(buf)-1 + 1))&0xffff)) {
|
||||
printf("switch! old=%lx ", db_tgt);
|
||||
db_tgt &= 0xffff0000;
|
||||
db_tgt += 0x00010000;
|
||||
printf("new=%lx\n", db_tgt);
|
||||
}
|
||||
sram_writelong((db_tgt-SRAM_MENU_ADDR) | ((uint32_t)type << 24), dir_tgt);
|
||||
dir_tgt += 4;
|
||||
/* save element:
|
||||
- index of last slash character
|
||||
- file name
|
||||
- file size */
|
||||
/* sram_writeblock((uint8_t*)&romprops, db_tgt, sizeof(romprops)); */
|
||||
entry_fsize = fno.fsize;
|
||||
entry_unit_idx = 0;
|
||||
while(entry_fsize > 9999) {
|
||||
entry_fsize >>= 10;
|
||||
entry_unit_idx++;
|
||||
}
|
||||
snprintf(buf, sizeof(buf), "% 5ld", entry_fsize);
|
||||
strncat(buf, size_units[entry_unit_idx], 1);
|
||||
sram_writeblock(buf, db_tgt, sizeof(buf)-1);
|
||||
sram_writebyte(len+1, db_tgt + sizeof(buf)-1);
|
||||
sram_writeblock(path, db_tgt + sizeof(len) + sizeof(buf)-1, pathlen + 1);
|
||||
// sram_writelong(fno.fsize, db_tgt + sizeof(len) + pathlen + 1);
|
||||
db_tgt += sizeof(len) + pathlen + sizeof(buf)-1 + 1;
|
||||
break;
|
||||
case TYPE_UNKNOWN:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
path[len]=0;
|
||||
/* printf("%s ", path);
|
||||
_delay_ms(30); */
|
||||
}
|
||||
} else {
|
||||
TCHAR* fn2 = fn;
|
||||
while(*fn2 != 0) {
|
||||
crc += crc32_update(crc, *((unsigned char*)fn2++));
|
||||
}
|
||||
}
|
||||
}
|
||||
/* printf("%s/%s\n", path, fn);
|
||||
_delay_ms(50); */
|
||||
}
|
||||
}
|
||||
} else uart_putc(0x30+res);
|
||||
}
|
||||
// printf("db_tgt=%lx dir_end=%lx\n", db_tgt, dir_end);
|
||||
sram_writelong(db_tgt, SRAM_DB_ADDR+4);
|
||||
sram_writelong(dir_end, SRAM_DB_ADDR+8);
|
||||
sram_writeshort(num_files_total, SRAM_DB_ADDR+12);
|
||||
sram_writeshort(num_dirs_total, SRAM_DB_ADDR+14);
|
||||
return crc;
|
||||
}
|
||||
|
||||
|
||||
SNES_FTYPE determine_filetype(char* filename) {
|
||||
char* ext = strrchr(filename, '.');
|
||||
if(ext == NULL)
|
||||
return TYPE_UNKNOWN;
|
||||
if( (!strcasecmp(ext+1, "SMC"))
|
||||
||(!strcasecmp(ext+1, "SFC"))
|
||||
||(!strcasecmp(ext+1, "FIG"))
|
||||
||(!strcasecmp(ext+1, "BS"))
|
||||
) {
|
||||
return TYPE_SMC;
|
||||
}
|
||||
if( (!strcasecmp(ext+1, "IPS"))
|
||||
||(!strcasecmp(ext+1, "UPS"))
|
||||
) {
|
||||
return TYPE_IPS;
|
||||
}
|
||||
/* later
|
||||
if(!strcasecmp_P(ext+1, PSTR("SRM"))) {
|
||||
return TYPE_SRM;
|
||||
}
|
||||
if(!strcasecmp_P(ext+1, PSTR("SPC"))) {
|
||||
return TYPE_SPC;
|
||||
}*/
|
||||
return TYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
FRESULT get_db_id(uint32_t* id) {
|
||||
file_open((uint8_t*)"/sd2snes/sd2snes.db", FA_READ);
|
||||
if(file_res == FR_OK) {
|
||||
file_readblock(id, 0, 4);
|
||||
/* XXX */// *id=0xdead;
|
||||
file_close();
|
||||
} else {
|
||||
*id=0xdeadbeef;
|
||||
}
|
||||
return file_res;
|
||||
}
|
||||
|
||||
int get_num_dirent(uint32_t addr) {
|
||||
int result = 0;
|
||||
while(sram_readlong(addr+result*4)) {
|
||||
result++;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void sort_all_dir(uint32_t endaddr) {
|
||||
uint32_t entries = 0;
|
||||
uint32_t current_base = SRAM_DIR_ADDR;
|
||||
while(current_base<(endaddr)) {
|
||||
while(sram_readlong(current_base+entries*4)) {
|
||||
entries++;
|
||||
}
|
||||
printf("sorting dir @%lx, entries: %ld\n", current_base, entries);
|
||||
sort_dir(current_base, entries);
|
||||
current_base += 4*entries + 4;
|
||||
entries = 0;
|
||||
}
|
||||
}
|
||||
58
src/filetypes.h
Normal file
58
src/filetypes.h
Normal file
@ -0,0 +1,58 @@
|
||||
/* sd2snes - SD card based universal cartridge for the SNES
|
||||
Copyright (C) 2009-2010 Maximilian Rehkopf <otakon@gmx.net>
|
||||
AVR firmware portion
|
||||
|
||||
Inspired by and based on code from sd2iec, written by Ingo Korb et al.
|
||||
See sdcard.c|h, config.h.
|
||||
|
||||
FAT file system access based on code by ChaN, Jim Brain, Ingo Korb,
|
||||
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
|
||||
|
||||
filetypes.h: directory scanning and file type detection
|
||||
*/
|
||||
|
||||
#ifndef FILETYPES_H
|
||||
#define FILETYPES_H
|
||||
|
||||
#ifdef DEBUG_FS
|
||||
#define DBG_FS
|
||||
#else
|
||||
#define DBG_FS while(0)
|
||||
#endif
|
||||
|
||||
#include "ff.h"
|
||||
|
||||
#define FS_MAX_DEPTH (10)
|
||||
#define SYS_DIR_NAME ((const uint8_t*)"sd2snes")
|
||||
typedef enum {
|
||||
TYPE_UNKNOWN = 0, /* 0 */
|
||||
TYPE_SMC, /* 1 */
|
||||
TYPE_SRM, /* 2 */
|
||||
TYPE_SPC, /* 3 */
|
||||
TYPE_IPS /* 4 */
|
||||
} SNES_FTYPE;
|
||||
|
||||
|
||||
char fs_path[256];
|
||||
SNES_FTYPE determine_filetype(char* filename);
|
||||
//uint32_t scan_fs();
|
||||
uint16_t scan_flat(const char* path);
|
||||
uint32_t scan_dir(char* path, FILINFO* fno_param, char mkdb, uint32_t this_subdir_tgt);
|
||||
FRESULT get_db_id(uint32_t*);
|
||||
int get_num_dirent(uint32_t addr);
|
||||
void sort_all_dir(uint32_t endaddr);
|
||||
|
||||
#endif
|
||||
12
src/flash.script
Normal file
12
src/flash.script
Normal file
@ -0,0 +1,12 @@
|
||||
# mthomas 4/2008, tested with OpenOCD SVN555
|
||||
|
||||
#flash probe 0
|
||||
#flash erase_check 0
|
||||
#flash protect_check 0
|
||||
#flash info 0
|
||||
|
||||
reset init
|
||||
flash write_image erase unlock obj/firmware.img 8192
|
||||
reset run
|
||||
shutdown
|
||||
|
||||
428
src/fpga_spi.c
Normal file
428
src/fpga_spi.c
Normal file
@ -0,0 +1,428 @@
|
||||
/* sd2snes - SD card based universal cartridge for the SNES
|
||||
Copyright (C) 2009-2010 Maximilian Rehkopf <otakon@gmx.net>
|
||||
AVR firmware portion
|
||||
|
||||
Inspired by and based on code from sd2iec, written by Ingo Korb et al.
|
||||
See sdcard.c|h, config.h.
|
||||
|
||||
FAT file system access based on code by ChaN, Jim Brain, Ingo Korb,
|
||||
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
|
||||
|
||||
fpga_spi.h: functions for SPI ctrl, SRAM interfacing and feature configuration
|
||||
*/
|
||||
/*
|
||||
|
||||
SPI commands
|
||||
|
||||
cmd param function
|
||||
=============================================
|
||||
0t bbhhll set address to 0xbbhhll
|
||||
t = target
|
||||
target: 0 = RAM
|
||||
1 = MSU Audio buffer
|
||||
2 = MSU Data buffer
|
||||
targets 1 & 2 only require 2 address bytes to
|
||||
be written.
|
||||
|
||||
10 bbhhll set SNES input address mask to 0xbbhhll
|
||||
20 bbhhll set SRAM address mask to 0xbbhhll
|
||||
|
||||
3m - set mapper to m
|
||||
0=HiROM, 1=LoROM, 2=ExHiROM, 6=SF96, 7=Menu
|
||||
|
||||
4s - trigger SD DMA (512b from SD to memory)
|
||||
s: Bit 2 = partial, Bit 1:0 = target
|
||||
target: see above
|
||||
|
||||
60 xsssyeee set SD DMA partial transfer parameters
|
||||
x: 0 = read from sector start (skip until
|
||||
start offset reached)
|
||||
8 = assume mid-sector position and read
|
||||
immediately
|
||||
sss = start offset (msb first)
|
||||
y: 0 = skip rest of SD sector
|
||||
8 = stop mid-sector if end offset reached
|
||||
eee = end offset (msb first)
|
||||
|
||||
8p - read (RAM only)
|
||||
p: 0 = no increment after read
|
||||
8 = increment after read
|
||||
|
||||
9p {xx}* write xx
|
||||
p: i-tt
|
||||
tt = target (see above)
|
||||
i = increment (see above)
|
||||
|
||||
E0 ssrr set MSU-1 status register (=FPGA status [7:0])
|
||||
ss = bits to set in status register (1=set)
|
||||
rr = bits to reset in status register (1=reset)
|
||||
|
||||
E1 - pause DAC
|
||||
E2 - resume/play DAC
|
||||
E3 - reset DAC playback pointer (0)
|
||||
E4 hhll set MSU read pointer
|
||||
|
||||
E5 tt{7} set RTC (SPC7110 format + 1000s of year,
|
||||
nibbles packed)
|
||||
eg 0x20111210094816 is 2011-12-10, 9:48:16
|
||||
E6 ssrr set/reset BS-X status register [7:0]
|
||||
E7 - reset SRTC state
|
||||
E8 - reset DSP program and data ROM write pointers
|
||||
E9 hhmmllxxxx write+incr. DSP program ROM (xxxx=dummy writes)
|
||||
EA hhllxxxx write+incr. DSP data ROM (xxxx=dummy writes)
|
||||
EB - put DSP into reset
|
||||
EC - release DSP from reset
|
||||
ED - set feature enable bits (see below)
|
||||
EE - set $213f override value (0=NTSC, 1=PAL)
|
||||
F0 - receive test token (to see if FPGA is alive)
|
||||
F1 - receive status (16bit, MSB first), see below
|
||||
|
||||
F2 - get MSU data address (32bit, MSB first)
|
||||
F3 - get MSU audio track no. (16bit, MSB first)
|
||||
F4 - get MSU volume (8bit)
|
||||
|
||||
FE - get SNES master clock frequency (32bit, MSB first)
|
||||
measured 1x/sec
|
||||
FF {xx}* echo (returns the sent data in the next byte)
|
||||
|
||||
FPGA status word:
|
||||
bit function
|
||||
==========================================================================
|
||||
15 SD DMA busy (0=idle, 1=busy)
|
||||
14 DAC read pointer MSB
|
||||
13 MSU read pointer MSB
|
||||
12 reserved (0)
|
||||
11 reserved (0)
|
||||
10 reserved (0)
|
||||
9 reserved (0)
|
||||
8 reserved (0)
|
||||
7 reserved (0)
|
||||
6 reserved (0)
|
||||
5 MSU1 Audio request from SNES
|
||||
4 MSU1 Data request from SNES
|
||||
3 reserved (0)
|
||||
2 MSU1 Audio control status: 0=no repeat, 1=repeat
|
||||
1 MSU1 Audio control status: 0=pause, 1=play
|
||||
0 MSU1 Audio control request
|
||||
|
||||
FPGA feature enable bits:
|
||||
bit function
|
||||
==========================================================================
|
||||
7 -
|
||||
6 -
|
||||
5 -
|
||||
4 enable $213F override
|
||||
3 enable MSU1 registers
|
||||
2 enable SRTC registers
|
||||
1 enable ST0010 mapping
|
||||
0 enable DSPx mapping
|
||||
|
||||
*/
|
||||
|
||||
#include <arm/NXP/LPC17xx/LPC17xx.h>
|
||||
#include "bits.h"
|
||||
#include "fpga.h"
|
||||
#include "config.h"
|
||||
#include "uart.h"
|
||||
#include "spi.h"
|
||||
#include "fpga_spi.h"
|
||||
#include "timer.h"
|
||||
#include "sdnative.h"
|
||||
|
||||
void fpga_spi_init(void) {
|
||||
spi_init(SPI_SPEED_FAST);
|
||||
BITBAND(FPGA_MCU_RDY_REG->FIODIR, FPGA_MCU_RDY_BIT) = 0;
|
||||
}
|
||||
|
||||
void set_msu_addr(uint16_t address) {
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0x02);
|
||||
FPGA_TX_BYTE((address>>8)&0xff);
|
||||
FPGA_TX_BYTE((address)&0xff);
|
||||
FPGA_DESELECT();
|
||||
}
|
||||
|
||||
void set_dac_addr(uint16_t address) {
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0x01);
|
||||
FPGA_TX_BYTE((address>>8)&0xff);
|
||||
FPGA_TX_BYTE((address)&0xff);
|
||||
FPGA_DESELECT();
|
||||
}
|
||||
|
||||
void set_mcu_addr(uint32_t address) {
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0x00);
|
||||
FPGA_TX_BYTE((address>>16)&0xff);
|
||||
FPGA_TX_BYTE((address>>8)&0xff);
|
||||
FPGA_TX_BYTE((address)&0xff);
|
||||
FPGA_DESELECT();
|
||||
}
|
||||
|
||||
void set_saveram_mask(uint32_t mask) {
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0x20);
|
||||
FPGA_TX_BYTE((mask>>16)&0xff);
|
||||
FPGA_TX_BYTE((mask>>8)&0xff);
|
||||
FPGA_TX_BYTE((mask)&0xff);
|
||||
FPGA_DESELECT();
|
||||
}
|
||||
|
||||
void set_rom_mask(uint32_t mask) {
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0x10);
|
||||
FPGA_TX_BYTE((mask>>16)&0xff);
|
||||
FPGA_TX_BYTE((mask>>8)&0xff);
|
||||
FPGA_TX_BYTE((mask)&0xff);
|
||||
FPGA_DESELECT();
|
||||
}
|
||||
|
||||
void set_mapper(uint8_t val) {
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0x30 | (val & 0x0f));
|
||||
FPGA_DESELECT();
|
||||
}
|
||||
|
||||
uint8_t fpga_test() {
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0xF0); /* TEST */
|
||||
FPGA_TX_BYTE(0x00); /* dummy */
|
||||
uint8_t result = FPGA_RX_BYTE();
|
||||
FPGA_DESELECT();
|
||||
return result;
|
||||
}
|
||||
|
||||
uint16_t fpga_status() {
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0xF1); /* STATUS */
|
||||
FPGA_TX_BYTE(0x00); /* dummy */
|
||||
uint16_t result = (FPGA_RX_BYTE()) << 8;
|
||||
result |= FPGA_RX_BYTE();
|
||||
FPGA_DESELECT();
|
||||
return result;
|
||||
}
|
||||
|
||||
void fpga_set_sddma_range(uint16_t start, uint16_t end) {
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0x60); /* DMA_RANGE */
|
||||
FPGA_TX_BYTE(start>>8);
|
||||
FPGA_TX_BYTE(start&0xff);
|
||||
FPGA_TX_BYTE(end>>8);
|
||||
FPGA_TX_BYTE(end&0xff);
|
||||
//if(tgt==1 && (test=FPGA_RX_BYTE()) != 0x41) printf("!!!!!!!!!!!!!!! -%02x- \n", test);
|
||||
FPGA_DESELECT();
|
||||
}
|
||||
|
||||
void fpga_sddma(uint8_t tgt, uint8_t partial) {
|
||||
uint32_t test = 0;
|
||||
uint8_t status = 0;
|
||||
BITBAND(SD_CLKREG->FIODIR, SD_CLKPIN) = 0;
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0x40 | (tgt & 0x3) | ((partial & 1) << 2) ); /* DO DMA */
|
||||
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_SELECT();
|
||||
FPGA_TX_BYTE(0xF1); /* STATUS */
|
||||
FPGA_TX_BYTE(0x00); /* dummy */
|
||||
DBG_SD printf("FPGA DMA request sent, wait for completion...");
|
||||
while((status=FPGA_RX_BYTE()) & 0x80) {
|
||||
FPGA_RX_BYTE(); /* eat the 2nd status byte */
|
||||
test++;
|
||||
}
|
||||
DBG_SD printf("...complete\n");
|
||||
FPGA_DESELECT();
|
||||
// if(test<5)printf("loopy: %ld %02x\n", test, status);
|
||||
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() {
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0xe2);
|
||||
FPGA_TX_BYTE(0x00); /* latch reset */
|
||||
FPGA_DESELECT();
|
||||
}
|
||||
|
||||
void dac_pause() {
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0xe1);
|
||||
FPGA_TX_BYTE(0x00); /* latch reset */
|
||||
FPGA_DESELECT();
|
||||
}
|
||||
|
||||
void dac_reset() {
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0xe3);
|
||||
FPGA_TX_BYTE(0x00); /* latch reset */
|
||||
FPGA_TX_BYTE(0x00); /* latch reset */
|
||||
FPGA_DESELECT();
|
||||
}
|
||||
|
||||
void msu_reset(uint16_t address) {
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0xe4);
|
||||
FPGA_TX_BYTE((address>>8) & 0xff); /* address hi */
|
||||
FPGA_TX_BYTE(address & 0xff); /* address lo */
|
||||
FPGA_TX_BYTE(0x00); /* latch reset */
|
||||
FPGA_TX_BYTE(0x00); /* latch reset */
|
||||
FPGA_DESELECT();
|
||||
}
|
||||
|
||||
void set_msu_status(uint8_t set, uint8_t reset) {
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0xe0);
|
||||
FPGA_TX_BYTE(set);
|
||||
FPGA_TX_BYTE(reset);
|
||||
FPGA_TX_BYTE(0x00); /* latch reset */
|
||||
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() {
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0xF3); /* MSU_TRACK */
|
||||
FPGA_TX_BYTE(0x00); /* dummy */
|
||||
uint16_t result = (FPGA_RX_BYTE()) << 8;
|
||||
result |= FPGA_RX_BYTE();
|
||||
FPGA_DESELECT();
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32_t get_msu_offset() {
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0xF2); /* MSU_OFFSET */
|
||||
FPGA_TX_BYTE(0x00); /* dummy */
|
||||
uint32_t result = (FPGA_RX_BYTE()) << 24;
|
||||
result |= (FPGA_RX_BYTE()) << 16;
|
||||
result |= (FPGA_RX_BYTE()) << 8;
|
||||
result |= (FPGA_RX_BYTE());
|
||||
FPGA_DESELECT();
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32_t get_snes_sysclk() {
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0xFE); /* GET_SYSCLK */
|
||||
FPGA_TX_BYTE(0x00); /* dummy */
|
||||
FPGA_TX_BYTE(0x00); /* dummy */
|
||||
uint32_t result = (FPGA_RX_BYTE()) << 24;
|
||||
result |= (FPGA_RX_BYTE()) << 16;
|
||||
result |= (FPGA_RX_BYTE()) << 8;
|
||||
result |= (FPGA_RX_BYTE());
|
||||
FPGA_DESELECT();
|
||||
return result;
|
||||
}
|
||||
|
||||
void set_bsx_regs(uint8_t set, uint8_t reset) {
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0xe6);
|
||||
FPGA_TX_BYTE(set);
|
||||
FPGA_TX_BYTE(reset);
|
||||
FPGA_TX_BYTE(0x00); /* latch reset */
|
||||
FPGA_DESELECT();
|
||||
}
|
||||
|
||||
void set_fpga_time(uint64_t time) {
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0xe5);
|
||||
FPGA_TX_BYTE((time >> 48) & 0xff);
|
||||
FPGA_TX_BYTE((time >> 40) & 0xff);
|
||||
FPGA_TX_BYTE((time >> 32) & 0xff);
|
||||
FPGA_TX_BYTE((time >> 24) & 0xff);
|
||||
FPGA_TX_BYTE((time >> 16) & 0xff);
|
||||
FPGA_TX_BYTE((time >> 8) & 0xff);
|
||||
FPGA_TX_BYTE(time & 0xff);
|
||||
FPGA_TX_BYTE(0x00);
|
||||
FPGA_DESELECT();
|
||||
}
|
||||
|
||||
void fpga_reset_srtc_state() {
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0xe7);
|
||||
FPGA_TX_BYTE(0x00);
|
||||
FPGA_TX_BYTE(0x00);
|
||||
FPGA_DESELECT();
|
||||
}
|
||||
|
||||
void fpga_reset_dspx_addr() {
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0xe8);
|
||||
FPGA_TX_BYTE(0x00);
|
||||
FPGA_TX_BYTE(0x00);
|
||||
FPGA_DESELECT();
|
||||
}
|
||||
|
||||
void fpga_write_dspx_pgm(uint32_t data) {
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0xe9);
|
||||
FPGA_TX_BYTE((data>>16)&0xff);
|
||||
FPGA_TX_BYTE((data>>8)&0xff);
|
||||
FPGA_TX_BYTE((data)&0xff);
|
||||
FPGA_TX_BYTE(0x00);
|
||||
FPGA_TX_BYTE(0x00);
|
||||
FPGA_DESELECT();
|
||||
}
|
||||
|
||||
void fpga_write_dspx_dat(uint16_t data) {
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0xea);
|
||||
FPGA_TX_BYTE((data>>8)&0xff);
|
||||
FPGA_TX_BYTE((data)&0xff);
|
||||
FPGA_TX_BYTE(0x00);
|
||||
FPGA_TX_BYTE(0x00);
|
||||
FPGA_DESELECT();
|
||||
}
|
||||
|
||||
void fpga_dspx_reset(uint8_t reset) {
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(reset ? 0xeb : 0xec);
|
||||
FPGA_TX_BYTE(0x00);
|
||||
FPGA_DESELECT();
|
||||
}
|
||||
|
||||
void fpga_set_features(uint8_t feat) {
|
||||
printf("set features: %02x\n", feat);
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0xed);
|
||||
FPGA_TX_BYTE(feat);
|
||||
FPGA_DESELECT();
|
||||
}
|
||||
|
||||
void fpga_set_213f(uint8_t data) {
|
||||
printf("set 213f: %d\n", data);
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0xee);
|
||||
FPGA_TX_BYTE(data);
|
||||
FPGA_DESELECT();
|
||||
}
|
||||
|
||||
96
src/fpga_spi.h
Normal file
96
src/fpga_spi.h
Normal file
@ -0,0 +1,96 @@
|
||||
/* sd2snes - SD card based universal cartridge for the SNES
|
||||
Copyright (C) 2009-2010 Maximilian Rehkopf <otakon@gmx.net>
|
||||
uC firmware portion
|
||||
|
||||
Inspired by and based on code from sd2iec, written by Ingo Korb et al.
|
||||
See sdcard.c|h, config.h.
|
||||
|
||||
FAT file system access based on code by ChaN, Jim Brain, Ingo Korb,
|
||||
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
|
||||
|
||||
fpga_spi.h: functions for SPI ctrl, SRAM interfacing and feature configuration
|
||||
*/
|
||||
|
||||
#ifndef _FPGA_SPI_H
|
||||
#define _FPGA_SPI_H
|
||||
|
||||
#include <arm/NXP/LPC17xx/LPC17xx.h>
|
||||
#include "bits.h"
|
||||
#include "spi.h"
|
||||
#include "config.h"
|
||||
|
||||
#define FPGA_SS_BIT 16
|
||||
#define FPGA_SS_REG LPC_GPIO0
|
||||
|
||||
#define FPGA_SELECT() do {FPGA_TX_SYNC(); BITBAND(FPGA_SS_REG->FIOCLR, FPGA_SS_BIT) = 1;} while (0)
|
||||
#define FPGA_SELECT_ASYNC() do {BITBAND(FPGA_SS_REG->FIOCLR, FPGA_SS_BIT) = 1;} while (0)
|
||||
#define FPGA_DESELECT() do {FPGA_TX_SYNC(); BITBAND(FPGA_SS_REG->FIOSET, FPGA_SS_BIT) = 1;} while (0)
|
||||
#define FPGA_DESELECT_ASYNC() do {BITBAND(FPGA_SS_REG->FIOSET, FPGA_SS_BIT) = 1;} while (0)
|
||||
|
||||
#define FPGA_TX_SYNC() spi_tx_sync()
|
||||
#define FPGA_TX_BYTE(x) spi_tx_byte(x)
|
||||
#define FPGA_RX_BYTE() spi_rx_byte()
|
||||
#define FPGA_TXRX_BYTE(x) spi_txrx_byte(x)
|
||||
#define FPGA_TX_BLOCK(x,y) spi_tx_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_MSU1 (1 << 3)
|
||||
#define FEAT_SRTC (1 << 2)
|
||||
#define FEAT_ST0010 (1 << 1)
|
||||
#define FEAT_DSPX (1 << 0)
|
||||
|
||||
#define FEAT_CX4 (1 << 4)
|
||||
|
||||
#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)
|
||||
|
||||
void fpga_spi_init(void);
|
||||
uint8_t fpga_test(void);
|
||||
uint16_t fpga_status(void);
|
||||
void spi_fpga(void);
|
||||
void spi_sd(void);
|
||||
void spi_none(void);
|
||||
void set_mcu_addr(uint32_t);
|
||||
void set_dac_addr(uint16_t);
|
||||
void set_dac_vol(uint8_t);
|
||||
void dac_play(void);
|
||||
void dac_pause(void);
|
||||
void dac_reset(void);
|
||||
void msu_reset(uint16_t);
|
||||
void set_msu_addr(uint16_t);
|
||||
void set_msu_status(uint8_t set, uint8_t reset);
|
||||
void set_saveram_mask(uint32_t);
|
||||
void set_rom_mask(uint32_t);
|
||||
void set_mapper(uint8_t val);
|
||||
void fpga_sddma(uint8_t tgt, uint8_t partial);
|
||||
void fpga_set_sddma_range(uint16_t start, uint16_t end);
|
||||
uint8_t get_msu_volume(void);
|
||||
uint16_t get_msu_track(void);
|
||||
uint32_t get_msu_offset(void);
|
||||
uint32_t get_snes_sysclk(void);
|
||||
void set_bsx_regs(uint8_t set, uint8_t reset);
|
||||
void set_fpga_time(uint64_t time);
|
||||
void fpga_reset_srtc_state(void);
|
||||
void fpga_reset_dspx_addr(void);
|
||||
void fpga_write_dspx_pgm(uint32_t data);
|
||||
void fpga_write_dspx_dat(uint16_t data);
|
||||
void fpga_dspx_reset(uint8_t reset);
|
||||
void fpga_set_features(uint8_t feat);
|
||||
void fpga_set_213f(uint8_t data);
|
||||
#endif
|
||||
131
src/lpc1754.ld
Normal file
131
src/lpc1754.ld
Normal file
@ -0,0 +1,131 @@
|
||||
/* Linker script for LPC1754
|
||||
*
|
||||
* Written 2010 by Ingo Korb
|
||||
*
|
||||
* Partially based on the linker scripts of avr-libc
|
||||
*/
|
||||
|
||||
OUTPUT_FORMAT(elf32-littlearm)
|
||||
ENTRY(_start)
|
||||
|
||||
MEMORY
|
||||
{
|
||||
flash (rx) : ORIGIN = 0x00002100, LENGTH = 0x1df00 /* leave room for bootldr + metadata */
|
||||
ram (rwx) : ORIGIN = 0x10000000, LENGTH = 0x04000
|
||||
ahbram (rwx) : ORIGIN = 0x2007C000, LENGTH = 0x04000
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.text :
|
||||
{
|
||||
KEEP(*(.vectors))
|
||||
KEEP(*(.init))
|
||||
*(.text)
|
||||
*(.text.*)
|
||||
*(.gnu.linkonce.t.*)
|
||||
|
||||
/* C++ con-/destructors */
|
||||
__ctors_start = . ;
|
||||
*(.ctors)
|
||||
__ctors_end = . ;
|
||||
__dtors_start = . ;
|
||||
*(.dtors)
|
||||
__dtors_end = . ;
|
||||
KEEP(SORT(*)(.ctors))
|
||||
KEEP(SORT(*)(.dtors))
|
||||
|
||||
KEEP(*(.fini))
|
||||
|
||||
__text_end = .;
|
||||
} > flash
|
||||
|
||||
/* .ARM.exidx is sorted, so has to go in its own output section. */
|
||||
__exidx_start = .;
|
||||
.ARM.exidx :
|
||||
{
|
||||
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
|
||||
} >flash
|
||||
__exidx_end = .;
|
||||
|
||||
/* I hope this does what I think it does */
|
||||
.rodata : AT (ALIGN(__exidx_end,4))
|
||||
{
|
||||
*(.rodata)
|
||||
*(.rodata.*)
|
||||
*(.gnu.linkonce.r.*)
|
||||
__rodata_end = .;
|
||||
} > flash
|
||||
|
||||
/* Data section */
|
||||
.data : AT (ALIGN(__rodata_end,4))
|
||||
{
|
||||
__data_start = .;
|
||||
*(.data)
|
||||
*(.data.*)
|
||||
*(.gnu.linkonce.d.*)
|
||||
__data_end = .;
|
||||
} > ram
|
||||
|
||||
/* Addresses of in-rom data section */
|
||||
__data_load_start = LOADADDR(.data);
|
||||
__data_load_end = __data_load_start + SIZEOF(.data);
|
||||
|
||||
. = ALIGN(4);
|
||||
|
||||
/* BSS */
|
||||
.bss :
|
||||
{
|
||||
__bss_start__ = .;
|
||||
*(.bss)
|
||||
*(.bss.*)
|
||||
*(COMMON)
|
||||
__bss_end__ = .;
|
||||
} > ram
|
||||
|
||||
/* second BSS in AHB ram */
|
||||
.ahbram (NOLOAD) :
|
||||
{
|
||||
__ahbram_start__ = .;
|
||||
*(.ahbram)
|
||||
*(.ahbram.*)
|
||||
__ahbram_end__ = .;
|
||||
} > ahbram
|
||||
|
||||
__heap_start = ALIGN(__bss_end__, 4);
|
||||
|
||||
/* Default stack starts at end of ram */
|
||||
PROVIDE(__stack = ORIGIN(ram) + LENGTH(ram)) ;
|
||||
|
||||
|
||||
/* Everyone seems to copy the stuff below straight from somewhere else, so I'll do that too */
|
||||
|
||||
/* Stabs debugging sections. */
|
||||
.stab 0 : { *(.stab) }
|
||||
.stabstr 0 : { *(.stabstr) }
|
||||
.stab.excl 0 : { *(.stab.excl) }
|
||||
.stab.exclstr 0 : { *(.stab.exclstr) }
|
||||
.stab.index 0 : { *(.stab.index) }
|
||||
.stab.indexstr 0 : { *(.stab.indexstr) }
|
||||
.comment 0 : { *(.comment) }
|
||||
/* DWARF debug sections.
|
||||
Symbols in the DWARF debugging sections are relative to the beginning
|
||||
of the section so we begin them at 0. */
|
||||
/* DWARF 1 */
|
||||
.debug 0 : { *(.debug) }
|
||||
.line 0 : { *(.line) }
|
||||
/* GNU DWARF 1 extensions */
|
||||
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||
/* DWARF 1.1 and DWARF 2 */
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
/* DWARF 2 */
|
||||
.debug_info 0 : { *(.debug_info) *(.gnu.linkonce.wi.*) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_line 0 : { *(.debug_line) }
|
||||
.debug_frame 0 : { *(.debug_frame) }
|
||||
.debug_str 0 : { *(.debug_str) }
|
||||
.debug_loc 0 : { *(.debug_loc) }
|
||||
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||
}
|
||||
315
src/main.c
Normal file
315
src/main.c
Normal file
@ -0,0 +1,315 @@
|
||||
#include <arm/NXP/LPC17xx/LPC17xx.h>
|
||||
#include <string.h>
|
||||
#include "config.h"
|
||||
#include "obj/autoconf.h"
|
||||
#include "clock.h"
|
||||
#include "uart.h"
|
||||
#include "bits.h"
|
||||
#include "power.h"
|
||||
#include "timer.h"
|
||||
#include "ff.h"
|
||||
#include "diskio.h"
|
||||
#include "spi.h"
|
||||
#include "fileops.h"
|
||||
#include "fpga.h"
|
||||
#include "fpga_spi.h"
|
||||
#include "filetypes.h"
|
||||
#include "memory.h"
|
||||
#include "snes.h"
|
||||
#include "led.h"
|
||||
#include "sort.h"
|
||||
#include "cic.h"
|
||||
#include "tests.h"
|
||||
#include "cli.h"
|
||||
#include "sdnative.h"
|
||||
#include "crc.h"
|
||||
#include "smc.h"
|
||||
#include "msu1.h"
|
||||
#include "rtc.h"
|
||||
#include "sysinfo.h"
|
||||
|
||||
#define EMC0TOGGLE (3<<4)
|
||||
#define MR0R (1<<1)
|
||||
|
||||
int i;
|
||||
|
||||
int sd_offload = 0, ff_sd_offload = 0, sd_offload_tgt = 0;
|
||||
int sd_offload_partial = 0;
|
||||
int sd_offload_start_mid = 0;
|
||||
int sd_offload_end_mid = 0;
|
||||
uint16_t sd_offload_partial_start = 0;
|
||||
uint16_t sd_offload_partial_end = 0;
|
||||
|
||||
volatile enum diskstates disk_state;
|
||||
extern volatile tick_t ticks;
|
||||
extern snes_romprops_t romprops;
|
||||
extern volatile int reset_changed;
|
||||
|
||||
enum system_states {
|
||||
SYS_RTC_STATUS = 0
|
||||
};
|
||||
|
||||
int main(void) {
|
||||
LPC_GPIO2->FIODIR = BV(4) | BV(5);
|
||||
LPC_GPIO1->FIODIR = BV(23) | BV(SNES_CIC_PAIR_BIT);
|
||||
BITBAND(SNES_CIC_PAIR_REG->FIOSET, SNES_CIC_PAIR_BIT) = 1;
|
||||
LPC_GPIO0->FIODIR = BV(16);
|
||||
|
||||
/* connect UART3 on P0[25:26] + SSP0 on P0[15:18] + MAT3.0 on P0[10] */
|
||||
LPC_PINCON->PINSEL1 = BV(18) | BV(19) | BV(20) | BV(21) /* UART3 */
|
||||
| BV(3) | BV(5); /* SSP0 (FPGA) except SS */
|
||||
LPC_PINCON->PINSEL0 = BV(31); /* SSP0 */
|
||||
/* | BV(13) | BV(15) | BV(17) | BV(19) SSP1 (SD) */
|
||||
|
||||
/* pull-down CIC data lines */
|
||||
LPC_PINCON->PINMODE0 = BV(0) | BV(1) | BV(2) | BV(3);
|
||||
|
||||
clock_disconnect();
|
||||
snes_init();
|
||||
snes_reset(1);
|
||||
power_init();
|
||||
timer_init();
|
||||
uart_init();
|
||||
fpga_spi_init();
|
||||
spi_preinit();
|
||||
led_init();
|
||||
/* do this last because the peripheral init()s change PCLK dividers */
|
||||
clock_init();
|
||||
LPC_PINCON->PINSEL0 |= BV(20) | BV(21); /* MAT3.0 (FPGA clock) */
|
||||
led_pwm();
|
||||
sdn_init();
|
||||
printf("\n\nsd2snes mk.2\n============\nfw ver.: " CONFIG_VERSION "\ncpu clock: %d Hz\n", CONFIG_CPU_FREQUENCY);
|
||||
printf("PCONP=%lx\n", LPC_SC->PCONP);
|
||||
|
||||
file_init();
|
||||
cic_init(0);
|
||||
/* setup timer (fpga clk) */
|
||||
LPC_TIM3->CTCR=0;
|
||||
LPC_TIM3->EMR=EMC0TOGGLE;
|
||||
LPC_TIM3->MCR=MR0R;
|
||||
LPC_TIM3->MR0=1;
|
||||
LPC_TIM3->TCR=1;
|
||||
fpga_init();
|
||||
fpga_rompgm();
|
||||
sram_writebyte(0, SRAM_CMD_ADDR);
|
||||
while(1) {
|
||||
if(disk_state == DISK_CHANGED) {
|
||||
sdn_init();
|
||||
newcard = 1;
|
||||
}
|
||||
load_bootrle(SRAM_MENU_ADDR);
|
||||
set_saveram_mask(0x1fff);
|
||||
set_rom_mask(0x3fffff);
|
||||
set_mapper(0x7);
|
||||
snes_reset(0);
|
||||
while(get_cic_state() == CIC_FAIL) {
|
||||
rdyled(0);
|
||||
readled(0);
|
||||
writeled(0);
|
||||
delay_ms(500);
|
||||
rdyled(1);
|
||||
readled(1);
|
||||
writeled(1);
|
||||
delay_ms(500);
|
||||
}
|
||||
/* some sanity checks */
|
||||
uint8_t card_go = 0;
|
||||
while(!card_go) {
|
||||
if(disk_status(0) & (STA_NOINIT|STA_NODISK)) {
|
||||
snes_bootprint(" No SD Card found! \0");
|
||||
while(disk_status(0) & (STA_NOINIT|STA_NODISK));
|
||||
delay_ms(200);
|
||||
}
|
||||
file_open((uint8_t*)"/sd2snes/menu.bin", FA_READ);
|
||||
if(file_status != FILE_OK) {
|
||||
snes_bootprint(" /sd2snes/menu.bin not found! \0");
|
||||
while(disk_status(0) == RES_OK);
|
||||
} else {
|
||||
card_go = 1;
|
||||
}
|
||||
file_close();
|
||||
}
|
||||
snes_bootprint(" Loading ... \0");
|
||||
if(get_cic_state() == CIC_PAIR) {
|
||||
printf("PAIR MODE ENGAGED!\n");
|
||||
cic_pair(CIC_NTSC, CIC_NTSC);
|
||||
}
|
||||
rdyled(1);
|
||||
readled(0);
|
||||
writeled(0);
|
||||
|
||||
*fs_path=0;
|
||||
uint32_t saved_dir_id;
|
||||
get_db_id(&saved_dir_id);
|
||||
|
||||
uint32_t mem_dir_id = sram_readlong(SRAM_DIRID);
|
||||
uint32_t mem_magic = sram_readlong(SRAM_SCRATCHPAD);
|
||||
printf("mem_magic=%lx mem_dir_id=%lx saved_dir_id=%lx\n", mem_magic, mem_dir_id, saved_dir_id);
|
||||
if((mem_magic != 0x12345678) || (mem_dir_id != saved_dir_id) || (newcard)) {
|
||||
newcard = 0;
|
||||
/* generate fs footprint (interesting files only) */
|
||||
uint32_t curr_dir_id = scan_dir(fs_path, NULL, 0, 0);
|
||||
printf("curr dir id = %lx\n", curr_dir_id);
|
||||
/* files changed or no database found? */
|
||||
if((get_db_id(&saved_dir_id) != FR_OK)
|
||||
|| saved_dir_id != curr_dir_id) {
|
||||
/* rebuild database */
|
||||
printf("saved dir id = %lx\n", saved_dir_id);
|
||||
printf("rebuilding database...");
|
||||
snes_bootprint(" rebuilding database ... \0");
|
||||
curr_dir_id = scan_dir(fs_path, NULL, 1, 0);
|
||||
sram_writeblock(&curr_dir_id, SRAM_DB_ADDR, 4);
|
||||
uint32_t endaddr, direndaddr;
|
||||
sram_readblock(&endaddr, SRAM_DB_ADDR+4, 4);
|
||||
sram_readblock(&direndaddr, SRAM_DB_ADDR+8, 4);
|
||||
printf("%lx %lx\n", endaddr, direndaddr);
|
||||
printf("sorting database...");
|
||||
snes_bootprint(" sorting database ... \0");
|
||||
sort_all_dir(direndaddr);
|
||||
printf("done\n");
|
||||
snes_bootprint(" saving database ... \0");
|
||||
save_sram((uint8_t*)"/sd2snes/sd2snes.db", endaddr-SRAM_DB_ADDR, SRAM_DB_ADDR);
|
||||
save_sram((uint8_t*)"/sd2snes/sd2snes.dir", direndaddr-(SRAM_DIR_ADDR), SRAM_DIR_ADDR);
|
||||
printf("done\n");
|
||||
} else {
|
||||
printf("saved dir id = %lx\n", saved_dir_id);
|
||||
printf("different card, consistent db, loading db...\n");
|
||||
load_sram((uint8_t*)"/sd2snes/sd2snes.db", SRAM_DB_ADDR);
|
||||
load_sram((uint8_t*)"/sd2snes/sd2snes.dir", SRAM_DIR_ADDR);
|
||||
}
|
||||
sram_writelong(curr_dir_id, SRAM_DIRID);
|
||||
sram_writelong(0x12345678, SRAM_SCRATCHPAD);
|
||||
} else {
|
||||
snes_bootprint(" same card, loading db... \0");
|
||||
printf("same card, loading db...\n");
|
||||
load_sram((uint8_t*)"/sd2snes/sd2snes.db", SRAM_DB_ADDR);
|
||||
load_sram((uint8_t*)"/sd2snes/sd2snes.dir", SRAM_DIR_ADDR);
|
||||
}
|
||||
/* cli_loop(); */
|
||||
/* load menu */
|
||||
|
||||
fpga_pgm((uint8_t*)"/sd2snes/fpga_base.bit");
|
||||
fpga_dspx_reset(1);
|
||||
uart_putc('(');
|
||||
load_rom((uint8_t*)"/sd2snes/menu.bin", SRAM_MENU_ADDR, 0);
|
||||
/* force memory size + mapper */
|
||||
set_rom_mask(0x3fffff);
|
||||
set_mapper(0x7);
|
||||
uart_putc(')');
|
||||
uart_putcrlf();
|
||||
|
||||
sram_writebyte(0, SRAM_CMD_ADDR);
|
||||
|
||||
if((rtc_state = rtc_isvalid()) != RTC_OK) {
|
||||
printf("RTC invalid!\n");
|
||||
sram_writebyte(0xff, SRAM_STATUS_ADDR+SYS_RTC_STATUS);
|
||||
set_bcdtime(0x20110401000000LL);
|
||||
set_fpga_time(0x20110401000000LL);
|
||||
invalidate_rtc();
|
||||
} else {
|
||||
printf("RTC valid!\n");
|
||||
sram_writebyte(0x00, SRAM_STATUS_ADDR+SYS_RTC_STATUS);
|
||||
set_fpga_time(get_bcdtime());
|
||||
}
|
||||
sram_memset(SRAM_SYSINFO_ADDR, 13*40, 0x20);
|
||||
printf("SNES GO!\n");
|
||||
snes_reset(1);
|
||||
delay_ms(1);
|
||||
snes_reset(0);
|
||||
|
||||
uint8_t cmd = 0;
|
||||
uint64_t btime = 0;
|
||||
uint32_t filesize=0;
|
||||
sram_writebyte(32, SRAM_CMD_ADDR);
|
||||
printf("test sram\n");
|
||||
while(!sram_reliable()) cli_entrycheck();
|
||||
printf("ok\n");
|
||||
//while(1) {
|
||||
// delay_ms(1000);
|
||||
// printf("Estimated SNES master clock: %ld Hz\n", get_snes_sysclk());
|
||||
//}
|
||||
//sram_hexdump(SRAM_DB_ADDR, 0x200);
|
||||
//sram_hexdump(SRAM_MENU_ADDR, 0x400);
|
||||
while(!cmd) {
|
||||
cmd=menu_main_loop();
|
||||
printf("cmd: %d\n", cmd);
|
||||
uart_putc('-');
|
||||
switch(cmd) {
|
||||
case SNES_CMD_LOADROM:
|
||||
get_selected_name(file_lfn);
|
||||
printf("Selected name: %s\n", file_lfn);
|
||||
filesize = load_rom(file_lfn, SRAM_ROM_ADDR, LOADROM_WITH_SRAM | LOADROM_WITH_RESET);
|
||||
break;
|
||||
case SNES_CMD_SETRTC:
|
||||
/* get time from RAM */
|
||||
btime = sram_gettime(SRAM_PARAM_ADDR);
|
||||
/* set RTC */
|
||||
set_bcdtime(btime);
|
||||
set_fpga_time(btime);
|
||||
cmd=0; /* stay in menu loop */
|
||||
break;
|
||||
case SNES_CMD_SYSINFO:
|
||||
/* go to sysinfo loop */
|
||||
sysinfo_loop();
|
||||
cmd=0; /* stay in menu loop */
|
||||
break;
|
||||
default:
|
||||
printf("unknown cmd: %d\n", cmd);
|
||||
cmd=0; /* unknown cmd: stay in loop */
|
||||
break;
|
||||
}
|
||||
}
|
||||
printf("cmd was %x, going to snes main loop\n", cmd);
|
||||
|
||||
if(romprops.has_msu1 && msu1_loop()) {
|
||||
prepare_reset();
|
||||
continue;
|
||||
}
|
||||
|
||||
cmd=0;
|
||||
uint8_t snes_reset_prev=0, snes_reset_now=0, snes_reset_state=0;
|
||||
uint16_t reset_count=0;
|
||||
while(fpga_test() == FPGA_TEST_TOKEN) {
|
||||
cli_entrycheck();
|
||||
sleep_ms(250);
|
||||
sram_reliable();
|
||||
printf("%s ", get_cic_statename(get_cic_state()));
|
||||
if(reset_changed) {
|
||||
printf("reset\n");
|
||||
reset_changed = 0;
|
||||
fpga_reset_srtc_state();
|
||||
}
|
||||
snes_reset_now=get_snes_reset();
|
||||
if(snes_reset_now) {
|
||||
if(!snes_reset_prev) {
|
||||
printf("RESET BUTTON DOWN\n");
|
||||
snes_reset_state=1;
|
||||
reset_count=0;
|
||||
}
|
||||
} else {
|
||||
if(snes_reset_prev) {
|
||||
printf("RESET BUTTON UP\n");
|
||||
snes_reset_state=0;
|
||||
}
|
||||
}
|
||||
if(snes_reset_state) {
|
||||
reset_count++;
|
||||
} else {
|
||||
sram_reliable();
|
||||
snes_main_loop();
|
||||
}
|
||||
if(reset_count>4) {
|
||||
reset_count=0;
|
||||
prepare_reset();
|
||||
break;
|
||||
}
|
||||
snes_reset_prev = snes_reset_now;
|
||||
}
|
||||
/* fpga test fail: panic */
|
||||
if(fpga_test() != FPGA_TEST_TOKEN){
|
||||
led_panic();
|
||||
}
|
||||
/* else reset */
|
||||
}
|
||||
}
|
||||
|
||||
581
src/memory.c
Normal file
581
src/memory.c
Normal file
@ -0,0 +1,581 @@
|
||||
/* sd2snes - SD card based universal cartridge for the SNES
|
||||
Copyright (C) 2009-2010 Maximilian Rehkopf <otakon@gmx.net>
|
||||
AVR firmware portion
|
||||
|
||||
Inspired by and based on code from sd2iec, written by Ingo Korb et al.
|
||||
See sdcard.c|h, config.h.
|
||||
|
||||
FAT file system access based on code by ChaN, Jim Brain, Ingo Korb,
|
||||
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
|
||||
|
||||
memory.c: RAM operations
|
||||
*/
|
||||
|
||||
|
||||
#include "config.h"
|
||||
#include "uart.h"
|
||||
#include "fpga.h"
|
||||
#include "crc.h"
|
||||
#include "crc32.h"
|
||||
#include "ff.h"
|
||||
#include "fileops.h"
|
||||
#include "spi.h"
|
||||
#include "fpga_spi.h"
|
||||
#include "led.h"
|
||||
#include "smc.h"
|
||||
#include "memory.h"
|
||||
#include "snes.h"
|
||||
#include "timer.h"
|
||||
#include "rle.h"
|
||||
#include "diskio.h"
|
||||
#include "snesboot.h"
|
||||
#include "msu1.h"
|
||||
|
||||
#include <string.h>
|
||||
char* hex = "0123456789ABCDEF";
|
||||
|
||||
extern snes_romprops_t romprops;
|
||||
|
||||
void sram_hexdump(uint32_t addr, uint32_t len) {
|
||||
static uint8_t buf[16];
|
||||
uint32_t ptr;
|
||||
for(ptr=0; ptr < len; ptr += 16) {
|
||||
sram_readblock((void*)buf, ptr+addr, 16);
|
||||
uart_trace(buf, 0, 16);
|
||||
}
|
||||
}
|
||||
|
||||
void sram_writebyte(uint8_t val, uint32_t addr) {
|
||||
set_mcu_addr(addr);
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0x98); /* WRITE */
|
||||
FPGA_TX_BYTE(val);
|
||||
FPGA_WAIT_RDY();
|
||||
FPGA_DESELECT();
|
||||
}
|
||||
|
||||
uint8_t sram_readbyte(uint32_t addr) {
|
||||
set_mcu_addr(addr);
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0x88); /* READ */
|
||||
FPGA_WAIT_RDY();
|
||||
uint8_t val = FPGA_RX_BYTE();
|
||||
FPGA_DESELECT();
|
||||
return val;
|
||||
}
|
||||
|
||||
void sram_writeshort(uint16_t val, uint32_t addr) {
|
||||
set_mcu_addr(addr);
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0x98); /* WRITE */
|
||||
FPGA_TX_BYTE(val&0xff);
|
||||
FPGA_WAIT_RDY();
|
||||
FPGA_TX_BYTE((val>>8)&0xff);
|
||||
FPGA_WAIT_RDY();
|
||||
FPGA_DESELECT();
|
||||
}
|
||||
|
||||
void sram_writelong(uint32_t val, uint32_t addr) {
|
||||
set_mcu_addr(addr);
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0x98); /* WRITE */
|
||||
FPGA_TX_BYTE(val&0xff);
|
||||
FPGA_WAIT_RDY();
|
||||
FPGA_TX_BYTE((val>>8)&0xff);
|
||||
FPGA_WAIT_RDY();
|
||||
FPGA_TX_BYTE((val>>16)&0xff);
|
||||
FPGA_WAIT_RDY();
|
||||
FPGA_TX_BYTE((val>>24)&0xff);
|
||||
FPGA_WAIT_RDY();
|
||||
FPGA_DESELECT();
|
||||
}
|
||||
|
||||
uint16_t sram_readshort(uint32_t addr) {
|
||||
set_mcu_addr(addr);
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0x88);
|
||||
FPGA_WAIT_RDY();
|
||||
uint32_t val = FPGA_RX_BYTE();
|
||||
FPGA_WAIT_RDY();
|
||||
val |= ((uint32_t)FPGA_RX_BYTE()<<8);
|
||||
FPGA_DESELECT();
|
||||
return val;
|
||||
}
|
||||
|
||||
uint32_t sram_readlong(uint32_t addr) {
|
||||
set_mcu_addr(addr);
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0x88);
|
||||
FPGA_WAIT_RDY();
|
||||
uint32_t val = FPGA_RX_BYTE();
|
||||
FPGA_WAIT_RDY();
|
||||
val |= ((uint32_t)FPGA_RX_BYTE()<<8);
|
||||
FPGA_WAIT_RDY();
|
||||
val |= ((uint32_t)FPGA_RX_BYTE()<<16);
|
||||
FPGA_WAIT_RDY();
|
||||
val |= ((uint32_t)FPGA_RX_BYTE()<<24);
|
||||
FPGA_DESELECT();
|
||||
return val;
|
||||
}
|
||||
|
||||
void sram_readlongblock(uint32_t* buf, uint32_t addr, uint16_t count) {
|
||||
set_mcu_addr(addr);
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0x88);
|
||||
uint16_t i=0;
|
||||
while(i<count) {
|
||||
FPGA_WAIT_RDY();
|
||||
uint32_t val = (uint32_t)FPGA_RX_BYTE()<<24;
|
||||
FPGA_WAIT_RDY();
|
||||
val |= ((uint32_t)FPGA_RX_BYTE()<<16);
|
||||
FPGA_WAIT_RDY();
|
||||
val |= ((uint32_t)FPGA_RX_BYTE()<<8);
|
||||
FPGA_WAIT_RDY();
|
||||
val |= FPGA_RX_BYTE();
|
||||
buf[i++] = val;
|
||||
}
|
||||
FPGA_DESELECT();
|
||||
}
|
||||
|
||||
void sram_readblock(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();
|
||||
*(tgt++) = FPGA_RX_BYTE();
|
||||
}
|
||||
FPGA_DESELECT();
|
||||
}
|
||||
|
||||
void sram_writeblock(void* buf, uint32_t addr, uint16_t size) {
|
||||
uint16_t count=size;
|
||||
uint8_t* src = buf;
|
||||
set_mcu_addr(addr);
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0x98); /* WRITE */
|
||||
while(count--) {
|
||||
FPGA_TX_BYTE(*src++);
|
||||
FPGA_WAIT_RDY();
|
||||
}
|
||||
FPGA_DESELECT();
|
||||
}
|
||||
|
||||
uint32_t load_rom(uint8_t* filename, uint32_t base_addr, uint8_t flags) {
|
||||
UINT bytes_read;
|
||||
DWORD filesize;
|
||||
UINT count=0;
|
||||
tick_t ticksstart, ticks_total=0;
|
||||
ticksstart=getticks();
|
||||
printf("%s\n", filename);
|
||||
file_open(filename, FA_READ);
|
||||
if(file_res) {
|
||||
uart_putc('?');
|
||||
uart_putc(0x30+file_res);
|
||||
return 0;
|
||||
}
|
||||
filesize = file_handle.fsize;
|
||||
smc_id(&romprops);
|
||||
file_close();
|
||||
/* reconfigure FPGA if necessary */
|
||||
if(romprops.fpga_conf) {
|
||||
printf("reconfigure FPGA with %s...\n", romprops.fpga_conf);
|
||||
fpga_pgm((uint8_t*)romprops.fpga_conf);
|
||||
}
|
||||
set_mcu_addr(base_addr);
|
||||
file_open(filename, FA_READ);
|
||||
f_lseek(&file_handle, romprops.offset);
|
||||
for(;;) {
|
||||
ff_sd_offload=1;
|
||||
sd_offload_tgt=0;
|
||||
bytes_read = file_read();
|
||||
if (file_res || !bytes_read) break;
|
||||
if(!(count++ % 512)) {
|
||||
uart_putc('.');
|
||||
}
|
||||
}
|
||||
file_close();
|
||||
set_mapper(romprops.mapper_id);
|
||||
printf("rom header map: %02x; mapper id: %d\n", romprops.header.map, romprops.mapper_id);
|
||||
ticks_total=getticks()-ticksstart;
|
||||
printf("%u ticks total\n", ticks_total);
|
||||
if(romprops.mapper_id==3) {
|
||||
printf("BSX Flash cart image\n");
|
||||
printf("attempting to load BSX BIOS /sd2snes/bsxbios.bin...\n");
|
||||
load_sram_offload((uint8_t*)"/sd2snes/bsxbios.bin", 0x800000);
|
||||
printf("Type: %02x\n", romprops.header.destcode);
|
||||
set_bsx_regs(0xc0, 0x3f);
|
||||
uint16_t rombase;
|
||||
if(romprops.header.ramsize & 1) {
|
||||
rombase = 0xff00;
|
||||
// set_bsx_regs(0x36, 0xc9);
|
||||
} else {
|
||||
rombase = 0x7f00;
|
||||
// set_bsx_regs(0x34, 0xcb);
|
||||
}
|
||||
sram_writebyte(0x33, rombase+0xda);
|
||||
sram_writebyte(0x00, rombase+0xd4);
|
||||
sram_writebyte(0xfc, rombase+0xd5);
|
||||
set_fpga_time(0x0220110301180530LL);
|
||||
}
|
||||
if(romprops.has_dspx || romprops.has_cx4) {
|
||||
printf("DSPx game. Loading firmware image %s...\n", romprops.dsp_fw);
|
||||
load_dspx(romprops.dsp_fw, romprops.fpga_features);
|
||||
/* fallback to DSP1B firmware if DSP1.bin is not present */
|
||||
if(file_res && romprops.dsp_fw == DSPFW_1) {
|
||||
load_dspx(DSPFW_1B, romprops.fpga_features);
|
||||
}
|
||||
if(file_res) {
|
||||
snes_menu_errmsg(MENU_ERR_NODSP, (void*)romprops.dsp_fw);
|
||||
}
|
||||
}
|
||||
uint32_t rammask;
|
||||
uint32_t rommask;
|
||||
|
||||
while(filesize > (romprops.romsize_bytes + romprops.offset)) {
|
||||
romprops.romsize_bytes <<= 1;
|
||||
}
|
||||
|
||||
if(romprops.header.ramsize == 0) {
|
||||
rammask = 0;
|
||||
} else {
|
||||
rammask = romprops.ramsize_bytes - 1;
|
||||
}
|
||||
rommask = romprops.romsize_bytes - 1;
|
||||
printf("ramsize=%x rammask=%lx\nromsize=%x rommask=%lx\n", romprops.header.ramsize, rammask, romprops.header.romsize, rommask);
|
||||
set_saveram_mask(rammask);
|
||||
set_rom_mask(rommask);
|
||||
readled(0);
|
||||
if(flags & LOADROM_WITH_SRAM) {
|
||||
if(romprops.ramsize_bytes) {
|
||||
strcpy(strrchr((char*)filename, (int)'.'), ".srm");
|
||||
printf("SRM file: %s\n", filename);
|
||||
load_sram(filename, SRAM_SAVE_ADDR);
|
||||
} else {
|
||||
printf("No SRAM\n");
|
||||
}
|
||||
}
|
||||
|
||||
printf("check MSU...");
|
||||
if(msu1_check(filename)) {
|
||||
romprops.fpga_features |= FEAT_MSU1;
|
||||
romprops.has_msu1 = 1;
|
||||
} else {
|
||||
romprops.has_msu1 = 0;
|
||||
}
|
||||
printf("done\n");
|
||||
|
||||
romprops.fpga_features |= FEAT_SRTC;
|
||||
romprops.fpga_features |= FEAT_213F;
|
||||
|
||||
fpga_set_213f(romprops.region);
|
||||
fpga_set_features(romprops.fpga_features);
|
||||
|
||||
if(flags & LOADROM_WITH_RESET) {
|
||||
fpga_dspx_reset(1);
|
||||
snes_reset(1);
|
||||
delay_ms(10);
|
||||
snes_reset(0);
|
||||
fpga_dspx_reset(0);
|
||||
}
|
||||
|
||||
return (uint32_t)filesize;
|
||||
}
|
||||
|
||||
uint32_t load_sram_offload(uint8_t* filename, uint32_t base_addr) {
|
||||
set_mcu_addr(base_addr);
|
||||
UINT bytes_read;
|
||||
DWORD filesize;
|
||||
file_open(filename, FA_READ);
|
||||
filesize = file_handle.fsize;
|
||||
if(file_res) return 0;
|
||||
for(;;) {
|
||||
ff_sd_offload=1;
|
||||
sd_offload_tgt=0;
|
||||
bytes_read = file_read();
|
||||
if (file_res || !bytes_read) break;
|
||||
}
|
||||
file_close();
|
||||
return (uint32_t)filesize;
|
||||
}
|
||||
|
||||
uint32_t load_sram(uint8_t* filename, uint32_t base_addr) {
|
||||
set_mcu_addr(base_addr);
|
||||
UINT bytes_read;
|
||||
DWORD filesize;
|
||||
file_open(filename, FA_READ);
|
||||
filesize = file_handle.fsize;
|
||||
if(file_res) {
|
||||
printf("load_sram: could not open %s, res=%d\n", filename, file_res);
|
||||
return 0;
|
||||
}
|
||||
for(;;) {
|
||||
bytes_read = file_read();
|
||||
if (file_res || !bytes_read) break;
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0x98);
|
||||
for(int j=0; j<bytes_read; j++) {
|
||||
FPGA_TX_BYTE(file_buf[j]);
|
||||
FPGA_WAIT_RDY();
|
||||
}
|
||||
FPGA_DESELECT();
|
||||
}
|
||||
file_close();
|
||||
return (uint32_t)filesize;
|
||||
}
|
||||
|
||||
uint32_t load_sram_rle(uint8_t* filename, uint32_t base_addr) {
|
||||
uint8_t data;
|
||||
set_mcu_addr(base_addr);
|
||||
DWORD filesize;
|
||||
file_open(filename, FA_READ);
|
||||
filesize = file_handle.fsize;
|
||||
if(file_res) return 0;
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0x98);
|
||||
for(;;) {
|
||||
data = rle_file_getc();
|
||||
if (file_res || file_status) break;
|
||||
FPGA_TX_BYTE(data);
|
||||
FPGA_WAIT_RDY();
|
||||
}
|
||||
FPGA_DESELECT();
|
||||
file_close();
|
||||
return (uint32_t)filesize;
|
||||
}
|
||||
|
||||
uint32_t load_bootrle(uint32_t base_addr) {
|
||||
uint8_t data;
|
||||
set_mcu_addr(base_addr);
|
||||
DWORD filesize = 0;
|
||||
rle_mem_init(bootrle, sizeof(bootrle));
|
||||
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0x98);
|
||||
for(;;) {
|
||||
data = rle_mem_getc();
|
||||
if(rle_state) break;
|
||||
FPGA_TX_BYTE(data);
|
||||
FPGA_WAIT_RDY();
|
||||
filesize++;
|
||||
}
|
||||
FPGA_DESELECT();
|
||||
return (uint32_t)filesize;
|
||||
}
|
||||
|
||||
|
||||
void save_sram(uint8_t* filename, uint32_t sram_size, uint32_t base_addr) {
|
||||
uint32_t count = 0;
|
||||
uint32_t num = 0;
|
||||
|
||||
FPGA_DESELECT();
|
||||
file_open(filename, FA_CREATE_ALWAYS | FA_WRITE);
|
||||
if(file_res) {
|
||||
uart_putc(0x30+file_res);
|
||||
}
|
||||
while(count<sram_size) {
|
||||
set_mcu_addr(base_addr+count);
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0x88); /* read */
|
||||
for(int j=0; j<sizeof(file_buf); j++) {
|
||||
FPGA_WAIT_RDY();
|
||||
file_buf[j] = FPGA_RX_BYTE();
|
||||
count++;
|
||||
}
|
||||
FPGA_DESELECT();
|
||||
num = file_write();
|
||||
if(file_res) {
|
||||
uart_putc(0x30+file_res);
|
||||
}
|
||||
}
|
||||
file_close();
|
||||
}
|
||||
|
||||
|
||||
uint32_t calc_sram_crc(uint32_t base_addr, uint32_t size) {
|
||||
uint8_t data;
|
||||
uint32_t count;
|
||||
uint32_t crc;
|
||||
crc=0;
|
||||
crc_valid=1;
|
||||
set_mcu_addr(base_addr);
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0x88);
|
||||
for(count=0; count<size; count++) {
|
||||
FPGA_WAIT_RDY();
|
||||
data = FPGA_RX_BYTE();
|
||||
if(get_snes_reset()) {
|
||||
crc_valid = 0;
|
||||
break;
|
||||
}
|
||||
crc += crc32_update(crc, data);
|
||||
}
|
||||
FPGA_DESELECT();
|
||||
return crc;
|
||||
}
|
||||
|
||||
uint8_t sram_reliable() {
|
||||
uint16_t score=0;
|
||||
uint32_t val;
|
||||
uint8_t result = 0;
|
||||
/*while(score<SRAM_RELIABILITY_SCORE) {
|
||||
if(sram_readlong(SRAM_SCRATCHPAD)==val) {
|
||||
score++;
|
||||
} else {
|
||||
set_pwr_led(0);
|
||||
score=0;
|
||||
}
|
||||
} */
|
||||
for(uint16_t i = 0; i < SRAM_RELIABILITY_SCORE; i++) {
|
||||
val=sram_readlong(SRAM_SCRATCHPAD);
|
||||
if(val==0x12345678) {
|
||||
score++;
|
||||
} else {
|
||||
printf("i=%d val=%08lX\n", i, val);
|
||||
}
|
||||
}
|
||||
if(score<SRAM_RELIABILITY_SCORE) {
|
||||
result = 0;
|
||||
/* dprintf("score=%d\n", score); */
|
||||
} else {
|
||||
result = 1;
|
||||
}
|
||||
rdyled(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
void sram_memset(uint32_t base_addr, uint32_t len, uint8_t val) {
|
||||
set_mcu_addr(base_addr);
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0x98);
|
||||
for(uint32_t i=0; i<len; i++) {
|
||||
FPGA_TX_BYTE(val);
|
||||
FPGA_WAIT_RDY();
|
||||
}
|
||||
FPGA_DESELECT();
|
||||
}
|
||||
|
||||
uint64_t sram_gettime(uint32_t base_addr) {
|
||||
set_mcu_addr(base_addr);
|
||||
FPGA_SELECT();
|
||||
FPGA_TX_BYTE(0x88);
|
||||
uint8_t data;
|
||||
uint64_t result = 0LL;
|
||||
/* 1st nibble is the century - 10 (binary)
|
||||
4th nibble is the month (binary)
|
||||
all other fields are BCD */
|
||||
for(int i=0; i<12; i++) {
|
||||
FPGA_WAIT_RDY();
|
||||
data = FPGA_RX_BYTE();
|
||||
data &= 0xf;
|
||||
switch(i) {
|
||||
case 0:
|
||||
result = (result << 4) | ((data / 10) + 1);
|
||||
result = (result << 4) | (data % 10);
|
||||
break;
|
||||
case 3:
|
||||
result = (result << 4) | ((data / 10));
|
||||
result = (result << 4) | (data % 10);
|
||||
break;
|
||||
default:
|
||||
result = (result << 4) | data;
|
||||
}
|
||||
}
|
||||
FPGA_DESELECT();
|
||||
return result & 0x00ffffffffffffffLL;
|
||||
}
|
||||
|
||||
void load_dspx(const uint8_t *filename, uint8_t coretype) {
|
||||
UINT bytes_read;
|
||||
DWORD filesize;
|
||||
uint16_t word_cnt;
|
||||
uint8_t wordsize_cnt = 0;
|
||||
uint16_t sector_remaining = 0;
|
||||
uint16_t sector_cnt = 0;
|
||||
uint16_t pgmsize = 0;
|
||||
uint16_t datsize = 0;
|
||||
uint32_t pgmdata = 0;
|
||||
uint16_t datdata = 0;
|
||||
|
||||
if(coretype & FEAT_ST0010) {
|
||||
datsize = 1536;
|
||||
pgmsize = 2048;
|
||||
} else if (coretype & FEAT_DSPX) {
|
||||
datsize = 1024;
|
||||
pgmsize = 2048;
|
||||
} else if (coretype & FEAT_CX4) {
|
||||
datsize = 0;
|
||||
pgmsize = 1024; /* Cx4 data ROM */
|
||||
} else {
|
||||
printf("load_dspx: unknown core (%02x)!\n", coretype);
|
||||
}
|
||||
|
||||
file_open((uint8_t*)filename, FA_READ);
|
||||
filesize = file_handle.fsize;
|
||||
if(file_res) {
|
||||
printf("Could not read %s: error %d\n", filename, file_res);
|
||||
return;
|
||||
}
|
||||
|
||||
fpga_reset_dspx_addr();
|
||||
|
||||
for(word_cnt = 0; word_cnt < pgmsize;) {
|
||||
if(!sector_remaining) {
|
||||
bytes_read = file_read();
|
||||
sector_remaining = bytes_read;
|
||||
sector_cnt = 0;
|
||||
}
|
||||
pgmdata = (pgmdata << 8) | file_buf[sector_cnt];
|
||||
sector_cnt++;
|
||||
wordsize_cnt++;
|
||||
sector_remaining--;
|
||||
if(wordsize_cnt == 3){
|
||||
wordsize_cnt = 0;
|
||||
word_cnt++;
|
||||
fpga_write_dspx_pgm(pgmdata);
|
||||
}
|
||||
}
|
||||
|
||||
wordsize_cnt = 0;
|
||||
if(coretype & FEAT_ST0010) {
|
||||
file_seek(0xc000);
|
||||
sector_remaining = 0;
|
||||
}
|
||||
|
||||
for(word_cnt = 0; word_cnt < datsize;) {
|
||||
if(!sector_remaining) {
|
||||
bytes_read = file_read();
|
||||
sector_remaining = bytes_read;
|
||||
sector_cnt = 0;
|
||||
}
|
||||
datdata = (datdata << 8) | file_buf[sector_cnt];
|
||||
sector_cnt++;
|
||||
wordsize_cnt++;
|
||||
sector_remaining--;
|
||||
if(wordsize_cnt == 2){
|
||||
wordsize_cnt = 0;
|
||||
word_cnt++;
|
||||
fpga_write_dspx_dat(datdata);
|
||||
}
|
||||
}
|
||||
|
||||
fpga_reset_dspx_addr();
|
||||
|
||||
file_close();
|
||||
|
||||
}
|
||||
73
src/memory.h
Normal file
73
src/memory.h
Normal file
@ -0,0 +1,73 @@
|
||||
/* sd2snes - SD card based universal cartridge for the SNES
|
||||
Copyright (C) 2009-2010 Maximilian Rehkopf <otakon@gmx.net>
|
||||
AVR firmware portion
|
||||
|
||||
Inspired by and based on code from sd2iec, written by Ingo Korb et al.
|
||||
See sdcard.c|h, config.h.
|
||||
|
||||
FAT file system access based on code by ChaN, Jim Brain, Ingo Korb,
|
||||
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
|
||||
|
||||
memory.h: RAM operations
|
||||
*/
|
||||
|
||||
#ifndef MEMORY_H
|
||||
#define MEMORY_H
|
||||
|
||||
#include <arm/NXP/LPC17xx/LPC17xx.h>
|
||||
#include "smc.h"
|
||||
|
||||
#define SRAM_ROM_ADDR (0x000000L)
|
||||
#define SRAM_SAVE_ADDR (0xE00000L)
|
||||
|
||||
#define SRAM_MENU_ADDR (0xE00000L)
|
||||
#define SRAM_DB_ADDR (0xE40000L)
|
||||
#define SRAM_DIR_ADDR (0xE10000L)
|
||||
#define SRAM_CMD_ADDR (0xFF1000L)
|
||||
#define SRAM_PARAM_ADDR (0xFF1004L)
|
||||
#define SRAM_STATUS_ADDR (0xFF1100L)
|
||||
#define SRAM_SYSINFO_ADDR (0xFF1110L)
|
||||
#define SRAM_MENU_SAVE_ADDR (0xFF0000L)
|
||||
#define SRAM_SCRATCHPAD (0xFFFF00L)
|
||||
#define SRAM_DIRID (0xFFFFF0L)
|
||||
#define SRAM_RELIABILITY_SCORE (0x100)
|
||||
|
||||
#define LOADROM_WITH_SRAM (1)
|
||||
#define LOADROM_WITH_RESET (2)
|
||||
|
||||
uint32_t load_rom(uint8_t* filename, uint32_t base_addr, uint8_t flags);
|
||||
uint32_t load_sram(uint8_t* filename, uint32_t base_addr);
|
||||
uint32_t load_sram_offload(uint8_t* filename, uint32_t base_addr);
|
||||
uint32_t load_sram_rle(uint8_t* filename, uint32_t base_addr);
|
||||
uint32_t load_bootrle(uint32_t base_addr);
|
||||
void load_dspx(const uint8_t* filename, uint8_t st0010);
|
||||
void sram_hexdump(uint32_t addr, uint32_t len);
|
||||
uint8_t sram_readbyte(uint32_t addr);
|
||||
uint16_t sram_readshort(uint32_t addr);
|
||||
uint32_t sram_readlong(uint32_t addr);
|
||||
void sram_writebyte(uint8_t val, uint32_t addr);
|
||||
void sram_writeshort(uint16_t val, uint32_t addr);
|
||||
void sram_writelong(uint32_t val, uint32_t addr);
|
||||
void sram_readblock(void* buf, uint32_t addr, uint16_t size);
|
||||
void sram_readlongblock(uint32_t* buf, uint32_t addr, uint16_t count);
|
||||
void sram_writeblock(void* buf, uint32_t addr, uint16_t size);
|
||||
void save_sram(uint8_t* filename, uint32_t sram_size, uint32_t base_addr);
|
||||
uint32_t calc_sram_crc(uint32_t base_addr, uint32_t size);
|
||||
uint8_t sram_reliable(void);
|
||||
void sram_memset(uint32_t base_addr, uint32_t len, uint8_t val);
|
||||
uint64_t sram_gettime(uint32_t base_addr);
|
||||
|
||||
#endif
|
||||
268
src/msu1.c
Normal file
268
src/msu1.c
Normal file
@ -0,0 +1,268 @@
|
||||
#include <string.h>
|
||||
#include "config.h"
|
||||
#include "uart.h"
|
||||
#include "ff.h"
|
||||
#include "diskio.h"
|
||||
#include "spi.h"
|
||||
#include "fpga_spi.h"
|
||||
#include "cli.h"
|
||||
#include "fileops.h"
|
||||
#include "msu1.h"
|
||||
#include "snes.h"
|
||||
#include "timer.h"
|
||||
#include "smc.h"
|
||||
|
||||
FIL msufile;
|
||||
DWORD msu_cltbl[CLTBL_SIZE] IN_AHBRAM;
|
||||
DWORD pcm_cltbl[CLTBL_SIZE] IN_AHBRAM;
|
||||
|
||||
extern snes_romprops_t romprops;
|
||||
|
||||
int msu1_check_reset(void) {
|
||||
static tick_t rising_ticks;
|
||||
|
||||
static uint8_t resbutton=0, resbutton_prev=0;
|
||||
resbutton = get_snes_reset();
|
||||
if(resbutton && !resbutton_prev) { /* push */
|
||||
rising_ticks = getticks();
|
||||
} else if(resbutton && resbutton_prev) { /* hold */
|
||||
if(getticks() > rising_ticks + 99) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
resbutton_prev = resbutton;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int msu1_check(uint8_t* filename) {
|
||||
/* open MSU file */
|
||||
strcpy((char*)file_buf, (char*)filename);
|
||||
strcpy(strrchr((char*)file_buf, (int)'.'), ".msu");
|
||||
printf("MSU datafile: %s\n", file_buf);
|
||||
if(f_open(&msufile, (const TCHAR*)file_buf, FA_READ) != FR_OK) {
|
||||
printf("MSU datafile not found\n");
|
||||
return 0;
|
||||
}
|
||||
msufile.cltbl = msu_cltbl;
|
||||
msu_cltbl[0] = CLTBL_SIZE;
|
||||
if(f_lseek(&msufile, CREATE_LINKMAP)) {
|
||||
printf("Error creating FF linkmap for MSU file!\n");
|
||||
}
|
||||
romprops.fpga_features |= FEAT_MSU1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int msu1_loop() {
|
||||
/* it is assumed that the MSU file is already opened by calling msu1_check(). */
|
||||
UINT bytes_read = 1024;
|
||||
UINT bytes_read2 = 1;
|
||||
FRESULT res;
|
||||
set_dac_vol(0x00);
|
||||
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 msu_addr = 0;
|
||||
uint8_t msu_repeat = 0;
|
||||
uint16_t msu_track = 0;
|
||||
uint32_t msu_offset = 0;
|
||||
uint32_t msu_loop_point = 0;
|
||||
|
||||
uint32_t msu_page1_start = 0x0000;
|
||||
uint32_t msu_page2_start = 0x2000;
|
||||
uint32_t msu_page_size = 0x2000;
|
||||
|
||||
set_msu_addr(0x0);
|
||||
msu_reset(0x0);
|
||||
ff_sd_offload=1;
|
||||
sd_offload_tgt=2;
|
||||
f_lseek(&msufile, 0L);
|
||||
ff_sd_offload=1;
|
||||
sd_offload_tgt=2;
|
||||
f_read(&msufile, file_buf, 16384, &bytes_read2);
|
||||
|
||||
set_dac_addr(dac_addr);
|
||||
dac_pause();
|
||||
dac_reset();
|
||||
/* audio_start, data_start, 0, audio_ctrl[1:0], ctrl_start */
|
||||
while(1){
|
||||
cli_entrycheck();
|
||||
fpga_status_now = fpga_status();
|
||||
|
||||
/* Data buffer refill */
|
||||
if((fpga_status_now & 0x2000) != (fpga_status_prev & 0x2000)) {
|
||||
DBG_MSU1 printf("data\n");
|
||||
uint8_t pageno = 0;
|
||||
if(fpga_status_now & 0x2000) {
|
||||
msu_addr = 0x0;
|
||||
msu_page1_start = msu_page2_start + msu_page_size;
|
||||
pageno = 1;
|
||||
} else {
|
||||
msu_addr = 0x2000;
|
||||
msu_page2_start = msu_page1_start + msu_page_size;
|
||||
pageno = 2;
|
||||
}
|
||||
set_msu_addr(msu_addr);
|
||||
sd_offload_tgt=2;
|
||||
ff_sd_offload=1;
|
||||
res = f_read(&msufile, file_buf, 8192, &bytes_read2);
|
||||
DBG_MSU1 printf("data buffer refilled. res=%d page1=%08lx page2=%08lx\n", res, msu_page1_start, msu_page2_start);
|
||||
}
|
||||
|
||||
/* Audio buffer refill */
|
||||
if((fpga_status_now & 0x4000) != (fpga_status_prev & 0x4000)) {
|
||||
if(fpga_status_now & 0x4000) {
|
||||
dac_addr = 0;
|
||||
} else {
|
||||
dac_addr = MSU_DAC_BUFSIZE/2;
|
||||
}
|
||||
set_dac_addr(dac_addr);
|
||||
sd_offload_tgt=1;
|
||||
ff_sd_offload=1;
|
||||
f_read(&file_handle, file_buf, MSU_DAC_BUFSIZE/2, &bytes_read);
|
||||
}
|
||||
|
||||
if(fpga_status_now & 0x0020) {
|
||||
char suffix[11];
|
||||
|
||||
/* get trackno */
|
||||
msu_track = get_msu_track();
|
||||
DBG_MSU1 printf("Audio requested! Track=%d\n", 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) {
|
||||
/* get address */
|
||||
msu_offset=get_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 & 0x0004) {
|
||||
msu_repeat = 1;
|
||||
set_msu_status(0x04, 0x01); /* set bit 2, reset bit 0 */
|
||||
DBG_MSU1 printf("Repeat set!\n");
|
||||
} else {
|
||||
msu_repeat = 0;
|
||||
set_msu_status(0x00, 0x05); /* set no bits, reset bit 0+2 */
|
||||
DBG_MSU1 printf("Repeat clear!\n");
|
||||
}
|
||||
|
||||
if(fpga_status_now & 0x0002) {
|
||||
DBG_MSU1 printf("PLAY!\n");
|
||||
set_msu_status(0x02, 0x01); /* set bit 0, reset bit 1 */
|
||||
dac_play();
|
||||
} else {
|
||||
DBG_MSU1 printf("PAUSE!\n");
|
||||
set_msu_status(0x00, 0x03); /* set no bits, reset bit 1+0 */
|
||||
dac_pause();
|
||||
}
|
||||
}
|
||||
|
||||
fpga_status_prev = fpga_status_now;
|
||||
|
||||
/* handle loop / end */
|
||||
if(bytes_read < MSU_DAC_BUFSIZE / 2) {
|
||||
ff_sd_offload=0;
|
||||
sd_offload=0;
|
||||
if(msu_repeat) {
|
||||
DBG_MSU1 printf("loop\n");
|
||||
ff_sd_offload=1;
|
||||
sd_offload_tgt=1;
|
||||
f_lseek(&file_handle, 8L+msu_loop_point*4);
|
||||
ff_sd_offload=1;
|
||||
sd_offload_tgt=1;
|
||||
f_read(&file_handle, file_buf, (MSU_DAC_BUFSIZE / 2) - bytes_read, &bytes_read);
|
||||
} else {
|
||||
set_msu_status(0x00, 0x02); /* clear play bit */
|
||||
dac_pause();
|
||||
}
|
||||
bytes_read = MSU_DAC_BUFSIZE;
|
||||
}
|
||||
if(msu1_check_reset()) {
|
||||
f_close(&msufile);
|
||||
f_close(&file_handle);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* END OF MSU1 STUFF */
|
||||
1058
src/sdnative.c
Normal file
1058
src/sdnative.c
Normal file
File diff suppressed because it is too large
Load Diff
30
src/sdnative.h
Normal file
30
src/sdnative.h
Normal file
@ -0,0 +1,30 @@
|
||||
/* DISCLAIMER */
|
||||
|
||||
#ifndef SDNATIVE_H
|
||||
#define SDNATIVE_H
|
||||
|
||||
#ifdef DEBUG_SD
|
||||
#define DBG_SD
|
||||
#else
|
||||
#define DBG_SD while(0)
|
||||
#endif
|
||||
|
||||
#include "diskio.h"
|
||||
|
||||
#define CRC_ERROR (0xf000)
|
||||
|
||||
extern int sd_offload;
|
||||
|
||||
/* These functions are weak-aliased to disk_... */
|
||||
void sdn_init(void);
|
||||
DSTATUS sdn_status(BYTE drv);
|
||||
DSTATUS sdn_initialize(BYTE drv);
|
||||
DRESULT sdn_read(BYTE drv, BYTE *buffer, DWORD sector, BYTE count);
|
||||
DRESULT sdn_write(BYTE drv, const BYTE *buffer, DWORD sector, BYTE count);
|
||||
DRESULT sdn_getinfo(BYTE drv, BYTE page, void *buffer);
|
||||
|
||||
void sdn_changed(void);
|
||||
uint8_t* sdn_getcid(void);
|
||||
|
||||
#endif
|
||||
|
||||
280
src/smc.c
Normal file
280
src/smc.c
Normal file
@ -0,0 +1,280 @@
|
||||
/* sd2snes - SD card based universal cartridge for the SNES
|
||||
Copyright (C) 2009-2010 Maximilian Rehkopf <otakon@gmx.net>
|
||||
AVR firmware portion
|
||||
|
||||
Inspired by and based on code from sd2iec, written by Ingo Korb et al.
|
||||
See sdcard.c|h, config.h.
|
||||
|
||||
FAT file system access based on code by ChaN, Jim Brain, Ingo Korb,
|
||||
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
|
||||
|
||||
smc.c: SMC file related operations
|
||||
*/
|
||||
|
||||
#include "fileops.h"
|
||||
#include "config.h"
|
||||
#include "uart.h"
|
||||
#include "smc.h"
|
||||
#include "string.h"
|
||||
#include "fpga_spi.h"
|
||||
|
||||
snes_romprops_t romprops;
|
||||
|
||||
uint32_t hdr_addr[6] = {0xffb0, 0x101b0, 0x7fb0, 0x81b0, 0x40ffb0, 0x4101b0};
|
||||
|
||||
uint8_t isFixed(uint8_t* data, int size, uint8_t value) {
|
||||
uint8_t res = 1;
|
||||
do {
|
||||
size--;
|
||||
if(data[size] != value) {
|
||||
res = 0;
|
||||
}
|
||||
} while (size);
|
||||
return res;
|
||||
}
|
||||
|
||||
uint8_t checkChksum(uint16_t cchk, uint16_t chk) {
|
||||
uint32_t sum = cchk + chk;
|
||||
uint8_t res = 0;
|
||||
if(sum==0x0000ffff) {
|
||||
res = 1;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void smc_id(snes_romprops_t* props) {
|
||||
uint8_t score, maxscore=1, score_idx=2; /* assume LoROM */
|
||||
snes_header_t* header = &(props->header);
|
||||
|
||||
props->has_dspx = 0;
|
||||
props->has_st0010 = 0;
|
||||
props->has_cx4 = 0;
|
||||
props->fpga_features = 0;
|
||||
props->fpga_conf = NULL;
|
||||
for(uint8_t num = 0; num < 6; num++) {
|
||||
score = smc_headerscore(hdr_addr[num], header);
|
||||
printf("%d: offset = %lX; score = %d\n", num, hdr_addr[num], score); // */
|
||||
if(score>=maxscore) {
|
||||
score_idx=num;
|
||||
maxscore=score;
|
||||
}
|
||||
}
|
||||
if(score_idx & 1) {
|
||||
props->offset = 0x200;
|
||||
} else {
|
||||
props->offset = 0;
|
||||
}
|
||||
|
||||
/* restore the chosen one */
|
||||
/*dprintf("winner is %d\n", score_idx); */
|
||||
file_readblock(header, hdr_addr[score_idx], sizeof(snes_header_t));
|
||||
|
||||
if(header->name[0x13] == 0x00 || header->name[0x13] == 0xff) {
|
||||
if(header->name[0x14] == 0x00) {
|
||||
const uint8_t n15 = header->map;
|
||||
if(n15 == 0x00 || n15 == 0x80 || n15 == 0x84 || n15 == 0x9c
|
||||
|| n15 == 0xbc || n15 == 0xfc) {
|
||||
if(header->licensee == 0x33 || header->licensee == 0xff) {
|
||||
props->mapper_id = 0;
|
||||
/*XXX do this properly */
|
||||
props->ramsize_bytes = 0x8000;
|
||||
props->romsize_bytes = 0x100000;
|
||||
props->expramsize_bytes = 0;
|
||||
props->mapper_id = 3; /* BS-X Memory Map */
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
switch(header->map & 0xef) {
|
||||
|
||||
case 0x21: /* HiROM */
|
||||
props->mapper_id = 0;
|
||||
if(header->map == 0x31 && (header->carttype == 0x03 || header->carttype == 0x05)) {
|
||||
props->has_dspx = 1;
|
||||
props->dsp_fw = DSPFW_1B;
|
||||
props->fpga_features |= FEAT_DSPX;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x20: /* LoROM */
|
||||
props->mapper_id = 1;
|
||||
if (header->map == 0x20 && header->carttype == 0xf3) {
|
||||
props->has_cx4 = 1;
|
||||
props->dsp_fw = CX4FW;
|
||||
props->fpga_conf = FPGA_CX4;
|
||||
props->fpga_features |= FEAT_CX4;
|
||||
}
|
||||
else if ((header->map == 0x20 && header->carttype == 0x03) ||
|
||||
(header->map == 0x30 && header->carttype == 0x05 && header->licensee != 0xb2)) {
|
||||
props->has_dspx = 1;
|
||||
props->fpga_features |= FEAT_DSPX;
|
||||
/* Pilotwings uses DSP1 instead of DSP1B */
|
||||
if(!memcmp(header->name, "PILOTWINGS", 10)) {
|
||||
props->dsp_fw = DSPFW_1;
|
||||
} else {
|
||||
props->dsp_fw = DSPFW_1B;
|
||||
}
|
||||
} else if (header->map == 0x20 && header->carttype == 0x05) {
|
||||
props->has_dspx = 1;
|
||||
props->dsp_fw = DSPFW_2;
|
||||
props->fpga_features |= FEAT_DSPX;
|
||||
} else if (header->map == 0x30 && header->carttype == 0x05 && header->licensee == 0xb2) {
|
||||
props->has_dspx = 1;
|
||||
props->dsp_fw = DSPFW_3;
|
||||
props->fpga_features |= FEAT_DSPX;
|
||||
} else if (header->map == 0x30 && header->carttype == 0x03) {
|
||||
props->has_dspx = 1;
|
||||
props->dsp_fw = DSPFW_4;
|
||||
props->fpga_features |= FEAT_DSPX;
|
||||
} else if (header->map == 0x30 && header->carttype == 0xf6 && header->romsize >= 0xa) {
|
||||
props->has_dspx = 1;
|
||||
props->has_st0010 = 1;
|
||||
props->dsp_fw = DSPFW_ST0010;
|
||||
props->fpga_features |= FEAT_ST0010;
|
||||
header->ramsize = 2;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x25: /* ExHiROM */
|
||||
props->mapper_id = 2;
|
||||
break;
|
||||
|
||||
case 0x22: /* ExLoROM */
|
||||
if(file_handle.fsize > 0x400200) {
|
||||
props->mapper_id = 6; /* SO96 */
|
||||
} else {
|
||||
props->mapper_id = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
default: /* invalid/unsupported mapper, use header location */
|
||||
switch(score_idx) {
|
||||
case 0:
|
||||
case 1:
|
||||
props->mapper_id = 0;
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
if(file_handle.fsize > 0x800200) {
|
||||
props->mapper_id = 6; /* SO96 interleaved */
|
||||
} else if(file_handle.fsize > 0x400200) {
|
||||
props->mapper_id = 1; /* ExLoROM */
|
||||
} else {
|
||||
props->mapper_id = 1; /* LoROM */
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
case 5:
|
||||
props->mapper_id = 2;
|
||||
break;
|
||||
default:
|
||||
props->mapper_id = 1; // whatever
|
||||
}
|
||||
}
|
||||
if(header->romsize == 0 || header->romsize > 13) {
|
||||
header->romsize = 13;
|
||||
}
|
||||
props->ramsize_bytes = (uint32_t)1024 << header->ramsize;
|
||||
props->romsize_bytes = (uint32_t)1024 << header->romsize;
|
||||
props->expramsize_bytes = (uint32_t)1024 << header->expramsize;
|
||||
/*dprintf("ramsize_bytes: %ld\n", props->ramsize_bytes); */
|
||||
if(props->ramsize_bytes > 32768 || props->ramsize_bytes < 2048) {
|
||||
props->ramsize_bytes = 0;
|
||||
}
|
||||
props->region = (header->destcode <= 1 || header->destcode >= 13) ? 0 : 1;
|
||||
|
||||
/*dprintf("ramsize_bytes: %ld\n", props->ramsize_bytes); */
|
||||
}
|
||||
|
||||
uint8_t smc_headerscore(uint32_t addr, snes_header_t* header) {
|
||||
int score=0;
|
||||
uint8_t reset_inst;
|
||||
uint16_t header_offset;
|
||||
if((addr & 0xfff) == 0x1b0) {
|
||||
header_offset = 0x200;
|
||||
} else {
|
||||
header_offset = 0;
|
||||
}
|
||||
if((file_readblock(header, addr, sizeof(snes_header_t)) < sizeof(snes_header_t))
|
||||
|| file_res) {
|
||||
return 0;
|
||||
}
|
||||
uint8_t mapper = header->map & ~0x10;
|
||||
uint16_t resetvector = header->vect_reset; /* not endian safe! */
|
||||
uint32_t file_addr = (((addr - header_offset) & ~0x7fff) | (resetvector & 0x7fff)) + header_offset;
|
||||
if(resetvector < 0x8000) return 0;
|
||||
|
||||
score += 2*isFixed(&header->licensee, sizeof(header->licensee), 0x33);
|
||||
score += 4*checkChksum(header->cchk, header->chk);
|
||||
if(header->carttype < 0x08) score++;
|
||||
if(header->romsize < 0x10) score++;
|
||||
if(header->ramsize < 0x08) score++;
|
||||
if(header->destcode < 0x0e) score++;
|
||||
|
||||
if((addr-header_offset) == 0x007fc0 && mapper == 0x20) score += 2;
|
||||
if((addr-header_offset) == 0x00ffc0 && mapper == 0x21) score += 2;
|
||||
if((addr-header_offset) == 0x007fc0 && mapper == 0x22) score += 2;
|
||||
if((addr-header_offset) == 0x40ffc0 && mapper == 0x25) score += 2;
|
||||
|
||||
file_readblock(&reset_inst, file_addr, 1);
|
||||
switch(reset_inst) {
|
||||
case 0x78: /* sei */
|
||||
case 0x18: /* clc */
|
||||
case 0x38: /* sec */
|
||||
case 0x9c: /* stz abs */
|
||||
case 0x4c: /* jmp abs */
|
||||
case 0x5c: /* jml abs */
|
||||
score += 8;
|
||||
break;
|
||||
|
||||
case 0xc2: /* rep */
|
||||
case 0xe2: /* sep */
|
||||
case 0xad: /* lda abs */
|
||||
case 0xae: /* ldx abs */
|
||||
case 0xac: /* ldy abs */
|
||||
case 0xaf: /* lda abs long */
|
||||
case 0xa9: /* lda imm */
|
||||
case 0xa2: /* ldx imm */
|
||||
case 0xa0: /* ldy imm */
|
||||
case 0x20: /* jsr abs */
|
||||
case 0x22: /* jsl abs */
|
||||
score += 4;
|
||||
break;
|
||||
|
||||
case 0x40: /* rti */
|
||||
case 0x60: /* rts */
|
||||
case 0x6b: /* rtl */
|
||||
case 0xcd: /* cmp abs */
|
||||
case 0xec: /* cpx abs */
|
||||
case 0xcc: /* cpy abs */
|
||||
score -= 4;
|
||||
break;
|
||||
|
||||
case 0x00: /* brk */
|
||||
case 0x02: /* cop */
|
||||
case 0xdb: /* stp */
|
||||
case 0x42: /* wdm */
|
||||
case 0xff: /* sbc abs long indexed */
|
||||
score -= 8;
|
||||
break;
|
||||
}
|
||||
|
||||
if(score && addr > 0x400000) score += 4;
|
||||
if(score < 0) score = 0;
|
||||
return score;
|
||||
}
|
||||
|
||||
93
src/smc.h
Normal file
93
src/smc.h
Normal file
@ -0,0 +1,93 @@
|
||||
/* sd2snes - SD card based universal cartridge for the SNES
|
||||
Copyright (C) 2009-2010 Maximilian Rehkopf <otakon@gmx.net>
|
||||
AVR firmware portion
|
||||
|
||||
Inspired by and based on code from sd2iec, written by Ingo Korb et al.
|
||||
See sdcard.c|h, config.h.
|
||||
|
||||
FAT file system access based on code by ChaN, Jim Brain, Ingo Korb,
|
||||
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
|
||||
|
||||
smc.h: SMC file structures
|
||||
*/
|
||||
|
||||
#ifndef SMC_H
|
||||
#define SMC_H
|
||||
|
||||
#define DSPFW_1 ((const uint8_t*)"/sd2snes/dsp1.bin")
|
||||
#define DSPFW_2 ((const uint8_t*)"/sd2snes/dsp2.bin")
|
||||
#define DSPFW_3 ((const uint8_t*)"/sd2snes/dsp3.bin")
|
||||
#define DSPFW_4 ((const uint8_t*)"/sd2snes/dsp4.bin")
|
||||
#define DSPFW_1B ((const uint8_t*)"/sd2snes/dsp1b.bin")
|
||||
#define DSPFW_ST0010 ((const uint8_t*)"/sd2snes/st0010.bin")
|
||||
#define CX4FW ((const uint8_t*)"/sd2snes/cx4.bin")
|
||||
|
||||
#define FPGA_CX4 ((const uint8_t*)"/sd2snes/fpga_cx4.bit")
|
||||
|
||||
typedef struct _snes_header {
|
||||
uint8_t maker[2]; /* 0xB0 */
|
||||
uint8_t gamecode[4]; /* 0xB2 */
|
||||
uint8_t fixed_00[7]; /* 0xB6 */
|
||||
uint8_t expramsize; /* 0xBD */
|
||||
uint8_t specver; /* 0xBE */
|
||||
uint8_t carttype2; /* 0xBF */
|
||||
uint8_t name[21]; /* 0xC0 */
|
||||
uint8_t map; /* 0xD5 */
|
||||
uint8_t carttype; /* 0xD6 */
|
||||
uint8_t romsize; /* 0xD7 */
|
||||
uint8_t ramsize; /* 0xD8 */
|
||||
uint8_t destcode; /* 0xD9 */
|
||||
uint8_t licensee; /* 0xDA */
|
||||
uint8_t ver; /* 0xDB */
|
||||
uint16_t cchk; /* 0xDC */
|
||||
uint16_t chk; /* 0xDE */
|
||||
uint32_t pad1; /* 0xE0 */
|
||||
uint16_t vect_cop16; /* 0xE4 */
|
||||
uint16_t vect_brk16; /* 0xE6 */
|
||||
uint16_t vect_abt16; /* 0xE8 */
|
||||
uint16_t vect_nmi16; /* 0xEA */
|
||||
uint16_t vect_irq16; /* 0xEE */
|
||||
uint16_t pad2; /* 0xF0 */
|
||||
uint16_t vect_cop8; /* 0xF4 */
|
||||
uint32_t pad3; /* 0xF6 */
|
||||
uint16_t vect_abt8; /* 0xF8 */
|
||||
uint16_t vect_nmi8; /* 0xFA */
|
||||
uint16_t vect_reset; /* 0xFC */
|
||||
uint16_t vect_brk8; /* 0xFE */
|
||||
} snes_header_t;
|
||||
|
||||
typedef struct _snes_romprops {
|
||||
uint16_t offset; /* start of actual ROM image */
|
||||
uint8_t mapper_id; /* FPGA mapper */
|
||||
uint8_t pad1; /* for alignment */
|
||||
uint32_t expramsize_bytes; /* ExpRAM size in bytes */
|
||||
uint32_t ramsize_bytes; /* CartRAM size in bytes */
|
||||
uint32_t romsize_bytes; /* ROM size in bytes (rounded up) */
|
||||
const uint8_t* dsp_fw; /* DSP (NEC / Hitachi) ROM filename */
|
||||
const uint8_t* fpga_conf; /* FPGA config file to load (default: base) */
|
||||
uint8_t has_dspx; /* DSP[1-4] presence flag */
|
||||
uint8_t has_st0010; /* st0010 presence flag (additional to dspx) */
|
||||
uint8_t has_msu1; /* MSU1 presence flag */
|
||||
uint8_t has_cx4; /* CX4 presence flag */
|
||||
uint8_t fpga_features; /* feature/peripheral enable bits*/
|
||||
uint8_t region; /* game region (derived from destination code) */
|
||||
snes_header_t header; /* original header from ROM image */
|
||||
} snes_romprops_t;
|
||||
|
||||
void smc_id(snes_romprops_t*);
|
||||
uint8_t smc_headerscore(uint32_t addr, snes_header_t* header);
|
||||
|
||||
#endif
|
||||
49
src/snes.h
Normal file
49
src/snes.h
Normal file
@ -0,0 +1,49 @@
|
||||
/* sd2snes - SD card based universal cartridge for the SNES
|
||||
Copyright (C) 2009-2010 Maximilian Rehkopf <otakon@gmx.net>
|
||||
AVR firmware portion
|
||||
|
||||
Inspired by and based on code from sd2iec, written by Ingo Korb et al.
|
||||
See sdcard.c|h, config.h.
|
||||
|
||||
FAT file system access based on code by ChaN, Jim Brain, Ingo Korb,
|
||||
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
|
||||
|
||||
snes.h: SNES hardware control and monitoring
|
||||
*/
|
||||
|
||||
#ifndef SNES_H
|
||||
#define SNES_H
|
||||
|
||||
#define SNES_CMD_LOADROM (1)
|
||||
#define SNES_CMD_SETRTC (2)
|
||||
#define SNES_CMD_SYSINFO (3)
|
||||
|
||||
#define MENU_ERR_OK (0)
|
||||
#define MENU_ERR_NODSP (1)
|
||||
#define MENU_ERR_NOBSX (2)
|
||||
|
||||
uint8_t crc_valid;
|
||||
|
||||
void prepare_reset(void);
|
||||
void snes_init(void);
|
||||
void snes_reset(int state);
|
||||
uint8_t get_snes_reset(void);
|
||||
void snes_main_loop(void);
|
||||
uint8_t menu_main_loop(void);
|
||||
void get_selected_name(uint8_t* lfn);
|
||||
void snes_bootprint(void* msg);
|
||||
void snes_menu_errmsg(int err, void* msg);
|
||||
#endif
|
||||
318
src/tests/Makefile
Normal file
318
src/tests/Makefile
Normal file
@ -0,0 +1,318 @@
|
||||
# Hey Emacs, this is a -*- makefile -*-
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# WinAVR Makefile Template written by Eric B. Weddington, Joerg Wunsch, et al.
|
||||
#
|
||||
# Released to the Public Domain
|
||||
#
|
||||
# Additional material for this makefile was written by:
|
||||
# Peter Fleury
|
||||
# Tim Henigan
|
||||
# Colin O'Flynn
|
||||
# Reiner Patommel
|
||||
# Markus Pfaff
|
||||
# Sander Pool
|
||||
# Frederik Rouleau
|
||||
# Carlos Lamas
|
||||
#
|
||||
#
|
||||
# Extensively modified for sd2iec and later adapted for ARM by Ingo Korb
|
||||
#
|
||||
# To rebuild project do "make clean" then "make all".
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
# Read configuration file
|
||||
ifdef CONFIG
|
||||
CONFIGSUFFIX = $(CONFIG:config%=%)
|
||||
else
|
||||
CONFIG = config
|
||||
CONFIGSUFFIX =
|
||||
endif
|
||||
|
||||
# Enable verbose compilation with "make V=1"
|
||||
ifdef V
|
||||
Q :=
|
||||
E := @:
|
||||
else
|
||||
Q := @
|
||||
E := @echo
|
||||
endif
|
||||
|
||||
# Include the configuration file
|
||||
include $(CONFIG)
|
||||
|
||||
# Directory for all generated files
|
||||
OBJDIR := obj$(CONFIGSUFFIX)
|
||||
|
||||
# Output format. (can be srec, ihex, binary)
|
||||
FORMAT = binary
|
||||
|
||||
# Linker script
|
||||
LINKERSCRIPT = lpc1754.ld
|
||||
|
||||
# Target file name (without extension).
|
||||
TARGET = $(OBJDIR)/sd2snes
|
||||
|
||||
|
||||
# List C source files here. (C dependencies are automatically generated.)
|
||||
SRC = main.c ff.c ccsbcs.c clock.c uart.c power.c led.c timer.c printf.c spi.c fileops.c rtc.c fpga.c fpga_spi.c snes.c smc.c memory.c filetypes.c faulthandler.c sort.c crc32.c cic.c cli.c xmodem.c irq.c rle.c sdnative.c msu1.c tests.c
|
||||
|
||||
# usbcontrol.c usb_hid.c usbhw_lpc.c usbinit.c usbstdreq.c
|
||||
|
||||
|
||||
# List Assembler source files here.
|
||||
# Make them always end in a capital .S. Files ending in a lowercase .s
|
||||
# will not be considered source files but generated files (assembler
|
||||
# output from the compiler), and will be deleted upon "make clean"!
|
||||
# Even though the DOS/Win* filesystem matches both .s and .S the same,
|
||||
# it will preserve the spelling of the filenames, and gcc itself does
|
||||
# care about how the name is spelled on its command-line.
|
||||
ASRC = startup.S crc.S
|
||||
|
||||
|
||||
# Optimization level, can be [0, 1, 2, 3, s].
|
||||
# 0 = turn off optimization. s = optimize for size.
|
||||
# (Note: 3 is not always the best optimization level. See avr-libc FAQ.)
|
||||
# Use s -mcall-prologues when you really need size...
|
||||
#OPT = 2
|
||||
OPT = 2
|
||||
|
||||
# Debugging format.
|
||||
DEBUG = dwarf-2
|
||||
|
||||
|
||||
# List any extra directories to look for include files here.
|
||||
# Each directory must be seperated by a space.
|
||||
# Use forward slashes for directory separators.
|
||||
# For a directory that has spaces, enclose it in quotes.
|
||||
EXTRAINCDIRS =
|
||||
|
||||
|
||||
# Compiler flag to set the C Standard level.
|
||||
# c89 = "ANSI" C
|
||||
# gnu89 = c89 plus GCC extensions
|
||||
# c99 = ISO C99 standard (not yet fully implemented)
|
||||
# gnu99 = c99 plus GCC extensions
|
||||
CSTANDARD = -std=gnu99
|
||||
|
||||
|
||||
# Place -D or -U options here
|
||||
CDEFS = -DF_OSC=$(CONFIG_MCU_FOSC)UL
|
||||
|
||||
|
||||
# Place -I options here
|
||||
CINCS =
|
||||
|
||||
|
||||
# CPU-specific flags
|
||||
ifndef CPUFLAGS
|
||||
CPUFLAGS := -mthumb -mcpu=cortex-m3
|
||||
endif
|
||||
|
||||
ifndef ARCH
|
||||
ARCH := arm-none-eabi
|
||||
endif
|
||||
|
||||
# Define programs and commands.
|
||||
# CC must be defined here to generate the correct CFLAGS
|
||||
SHELL = sh
|
||||
CC = $(ARCH)-gcc
|
||||
OBJCOPY = $(ARCH)-objcopy
|
||||
OBJDUMP = $(ARCH)-objdump
|
||||
SIZE = $(ARCH)-size
|
||||
NM = $(ARCH)-nm
|
||||
REMOVE = rm -f
|
||||
COPY = cp
|
||||
AWK = awk
|
||||
|
||||
|
||||
#---------------- Compiler Options ----------------
|
||||
# -g*: generate debugging information
|
||||
# -O*: optimization level
|
||||
# -f...: tuning, see GCC manual and avr-libc documentation
|
||||
# -Wall...: warning level
|
||||
# -Wa,...: tell GCC to pass this to the assembler.
|
||||
# -adhlns...: create assembler listing
|
||||
CFLAGS = -g$(DEBUG)
|
||||
CFLAGS += $(CDEFS) $(CINCS)
|
||||
CFLAGS += -O$(OPT)
|
||||
CFLAGS += $(CPUFLAGS) -nostartfiles
|
||||
#CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
|
||||
CFLAGS += -Wall -Wstrict-prototypes -Werror
|
||||
CFLAGS += -Wa,-adhlns=$(OBJDIR)/$(<:.c=.lst)
|
||||
CFLAGS += -I$(OBJDIR)
|
||||
CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
|
||||
CFLAGS += $(CSTANDARD)
|
||||
CFLAGS += -ffunction-sections -fdata-sections
|
||||
|
||||
|
||||
#---------------- Assembler Options ----------------
|
||||
# -Wa,...: tell GCC to pass this to the assembler.
|
||||
# -ahlms: create listing
|
||||
# -gstabs: have the assembler create line number information; note that
|
||||
# for use in COFF files, additional information about filenames
|
||||
# and function names needs to be present in the assembler source
|
||||
# files -- see avr-libc docs [FIXME: not yet described there]
|
||||
ASFLAGS = $(CPUFLAGS) -Wa,-adhlns=$(OBJDIR)/$(<:.S=.lst),-gstabs -I$(OBJDIR)
|
||||
|
||||
|
||||
#---------------- Linker Options ----------------
|
||||
# -Wl,...: tell GCC to pass this to linker.
|
||||
# -Map: create map file
|
||||
# --cref: add cross reference to map file
|
||||
LDFLAGS = -Wl,-Map=$(TARGET).map,--cref
|
||||
LDFLAGS += -T$(LINKERSCRIPT)
|
||||
LDFLAGS += -Wl,--gc-sections
|
||||
ifeq ($(CONFIG_LINKER_RELAX),y)
|
||||
LDFLAGS += -Wl,-O9,--relax
|
||||
endif
|
||||
|
||||
|
||||
#============================================================================
|
||||
|
||||
|
||||
# De-dupe the list of C source files
|
||||
CSRC := $(sort $(SRC))
|
||||
|
||||
# Define all object files.
|
||||
OBJ := $(patsubst %,$(OBJDIR)/%,$(CSRC:.c=.o) $(ASRC:.S=.o))
|
||||
|
||||
# Define all listing files.
|
||||
LST := $(patsubst %,$(OBJDIR)/%,$(CSRC:.c=.lst) $(ASRC:.S=.lst))
|
||||
|
||||
|
||||
# Compiler flags to generate dependency files.
|
||||
GENDEPFLAGS = -MMD -MP -MF .dep/$(@F).d
|
||||
|
||||
|
||||
# Combine all necessary flags and optional flags.
|
||||
# Add target processor to flags.
|
||||
ALL_CFLAGS = -I. $(CFLAGS) $(GENDEPFLAGS)
|
||||
ALL_ASFLAGS = -I. -x assembler-with-cpp $(ASFLAGS) $(CDEFS)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# Default target.
|
||||
all: build
|
||||
|
||||
build: elf bin hex
|
||||
$(E) " SIZE $(TARGET).elf"
|
||||
$(Q)$(ELFSIZE)|grep -v debug
|
||||
cp $(TARGET).bin $(OBJDIR)/firmware.img
|
||||
utils/genhdr $(OBJDIR)/firmware.img SNSD $(CONFIG_FWVER)
|
||||
|
||||
elf: $(TARGET).elf
|
||||
bin: $(TARGET).bin
|
||||
hex: $(TARGET).hex
|
||||
eep: $(TARGET).eep
|
||||
lss: $(TARGET).lss
|
||||
sym: $(TARGET).sym
|
||||
|
||||
# # A little helper target for the maintainer =)
|
||||
# copy2card:
|
||||
# cp $(TARGET).bin /mbed/hw_LPC1768.bin
|
||||
|
||||
|
||||
program: build
|
||||
utils/lpcchksum $(TARGET).bin
|
||||
openocd -f openocd-usb.cfg -f lpc1754.cfg -f flash.cfg
|
||||
|
||||
debug: build
|
||||
openocd -f openocd-usb.cfg -f lpc1754.cfg
|
||||
|
||||
reset:
|
||||
openocd -f openocd-usb.cfg -f lpc1754.cfg -f reset.cfg
|
||||
|
||||
# Display size of file.
|
||||
HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex
|
||||
ELFSIZE = $(SIZE) -A $(TARGET).elf
|
||||
|
||||
|
||||
|
||||
# Generate autoconf.h from config
|
||||
.PRECIOUS : $(OBJDIR)/autoconf.h
|
||||
$(OBJDIR)/autoconf.h: $(CONFIG) | $(OBJDIR)
|
||||
$(E) " CONF2H $(CONFIG)"
|
||||
$(Q)$(AWK) -f conf2h.awk $(CONFIG) > $(OBJDIR)/autoconf.h
|
||||
|
||||
# Create final output files from ELF output file.
|
||||
$(OBJDIR)/%.bin: $(OBJDIR)/%.elf
|
||||
$(E) " BIN $@"
|
||||
$(Q)$(OBJCOPY) -O binary $< $@
|
||||
|
||||
$(OBJDIR)/%.hex: $(OBJDIR)/%.elf
|
||||
$(E) " HEX $@"
|
||||
$(Q)$(OBJCOPY) -O $(FORMAT) $< $@
|
||||
|
||||
# Create extended listing file from ELF output file.
|
||||
$(OBJDIR)/%.lss: $(OBJDIR)/%.elf
|
||||
$(E) " LSS $<"
|
||||
$(Q)$(OBJDUMP) -h -S $< > $@
|
||||
|
||||
# Create a symbol table from ELF output file.
|
||||
$(OBJDIR)/%.sym: $(OBJDIR)/%.elf
|
||||
$(E) " SYM $<"
|
||||
$(E)$(NM) -n $< > $@
|
||||
|
||||
|
||||
# Link: create ELF output file from object files.
|
||||
.SECONDARY : $(TARGET).elf
|
||||
.PRECIOUS : $(OBJ)
|
||||
$(TARGET).elf : $(OBJ)
|
||||
$(E) " LINK $@"
|
||||
$(Q)$(CC) $(ALL_CFLAGS) $^ --output $@ $(LDFLAGS)
|
||||
|
||||
|
||||
# Compile: create object files from C source files.
|
||||
$(OBJDIR)/%.o : %.c | $(OBJDIR) $(OBJDIR)/autoconf.h
|
||||
$(E) " CC $<"
|
||||
$(Q)$(CC) -c $(ALL_CFLAGS) $< -o $@
|
||||
|
||||
|
||||
# Compile: create assembler files from C source files.
|
||||
$(OBJDIR)/%.s : %.c | $(OBJDIR) $(OBJDIR)/autoconf.h
|
||||
$(CC) -S $(ALL_CFLAGS) $< -o $@
|
||||
|
||||
|
||||
# Assemble: create object files from assembler source files.
|
||||
$(OBJDIR)/%.o : %.S | $(OBJDIR) $(OBJDIR)/autoconf.h
|
||||
$(E) " AS $<"
|
||||
$(Q)$(CC) -c $(ALL_ASFLAGS) $< -o $@
|
||||
|
||||
# Create preprocessed source for use in sending a bug report.
|
||||
$(OBJDIR)/%.i : %.c | $(OBJDIR) $(OBJDIR)/autoconf.h
|
||||
$(CC) -E -mmcu=$(MCU) -I. $(CFLAGS) $< -o $@
|
||||
|
||||
# Create the output directory
|
||||
$(OBJDIR) :
|
||||
$(E) " MKDIR $(OBJDIR)"
|
||||
$(Q)mkdir $(OBJDIR)
|
||||
|
||||
# Target: clean project.
|
||||
clean: begin clean_list end
|
||||
|
||||
clean_list :
|
||||
$(E) " CLEAN"
|
||||
$(Q)$(REMOVE) $(TARGET).hex
|
||||
$(Q)$(REMOVE) $(TARGET).bin
|
||||
$(Q)$(REMOVE) $(TARGET).elf
|
||||
$(Q)$(REMOVE) $(TARGET).map
|
||||
$(Q)$(REMOVE) $(TARGET).sym
|
||||
$(Q)$(REMOVE) $(TARGET).lss
|
||||
$(Q)$(REMOVE) $(OBJ)
|
||||
$(Q)$(REMOVE) $(OBJDIR)/autoconf.h
|
||||
$(Q)$(REMOVE) $(OBJDIR)/*.bin
|
||||
$(Q)$(REMOVE) $(LST)
|
||||
$(Q)$(REMOVE) $(CSRC:.c=.s)
|
||||
$(Q)$(REMOVE) $(CSRC:.c=.d)
|
||||
$(Q)$(REMOVE) .dep/*
|
||||
-$(Q)rmdir $(OBJDIR)
|
||||
|
||||
# Include the dependency files.
|
||||
-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*)
|
||||
|
||||
# Listing of phony targets.
|
||||
.PHONY : all begin finish end sizebefore sizeafter \
|
||||
build elf hex lss sym clean clean_list
|
||||
21
src/tests/bits.h
Normal file
21
src/tests/bits.h
Normal file
@ -0,0 +1,21 @@
|
||||
#ifndef _ARM_BITS_H
|
||||
#define _ARM_BITS_H
|
||||
|
||||
/* The classic macro */
|
||||
#define BV(x) (1<<(x))
|
||||
|
||||
/* CM3 bit-band access macro - no error checks! */
|
||||
#define BITBAND(addr,bit) \
|
||||
(*((volatile unsigned long *)( \
|
||||
((unsigned long)&(addr) & 0x01ffffff)*32 + \
|
||||
(bit)*4 + 0x02000000 + ((unsigned long)&(addr) & 0xfe000000) \
|
||||
)))
|
||||
|
||||
#define BITBAND_OFF(addr,offset,bit) \
|
||||
(*((volatile unsigned long *)( \
|
||||
(((unsigned long)&(addr) + offset) & 0x01ffffff)*32 + \
|
||||
(bit)*4 + 0x02000000 + (((unsigned long)&(addr) + offset) & 0xfe000000) \
|
||||
)))
|
||||
|
||||
|
||||
#endif
|
||||
540
src/tests/ccsbcs.c
Normal file
540
src/tests/ccsbcs.c
Normal file
@ -0,0 +1,540 @@
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Unicode - Local code bidirectional converter (C)ChaN, 2009 */
|
||||
/* (SBCS code pages) */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* 437 U.S. (OEM)
|
||||
/ 720 Arabic (OEM)
|
||||
/ 1256 Arabic (Windows)
|
||||
/ 737 Greek (OEM)
|
||||
/ 1253 Greek (Windows)
|
||||
/ 1250 Central Europe (Windows)
|
||||
/ 775 Baltic (OEM)
|
||||
/ 1257 Baltic (Windows)
|
||||
/ 850 Multilingual Latin 1 (OEM)
|
||||
/ 852 Latin 2 (OEM)
|
||||
/ 1252 Latin 1 (Windows)
|
||||
/ 855 Cyrillic (OEM)
|
||||
/ 1251 Cyrillic (Windows)
|
||||
/ 866 Russian (OEM)
|
||||
/ 857 Turkish (OEM)
|
||||
/ 1254 Turkish (Windows)
|
||||
/ 858 Multilingual Latin 1 + Euro (OEM)
|
||||
/ 862 Hebrew (OEM)
|
||||
/ 1255 Hebrew (Windows)
|
||||
/ 874 Thai (OEM, Windows)
|
||||
/ 1258 Vietnam (OEM, Windows)
|
||||
*/
|
||||
|
||||
#include "../ff.h"
|
||||
|
||||
|
||||
#if _CODE_PAGE == 437
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP437(0x80-0xFF) to Unicode conversion table */
|
||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
|
||||
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
|
||||
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
|
||||
0x00FF, 0x00D6, 0x00DC, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
|
||||
0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
|
||||
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
|
||||
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4,
|
||||
0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
|
||||
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248,
|
||||
0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 720
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP720(0x80-0xFF) to Unicode conversion table */
|
||||
0x0000, 0x0000, 0x00E9, 0x00E2, 0x0000, 0x00E0, 0x0000, 0x00E7,
|
||||
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x0651, 0x0652, 0x00F4, 0x00A4, 0x0640, 0x00FB, 0x00F9,
|
||||
0x0621, 0x0622, 0x0623, 0x0624, 0x00A3, 0x0625, 0x0626, 0x0627,
|
||||
0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F,
|
||||
0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
|
||||
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
|
||||
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||
0x0636, 0x0637, 0x0638, 0x0639, 0x063A, 0x0641, 0x00B5, 0x0642,
|
||||
0x0643, 0x0644, 0x0645, 0x0646, 0x0647, 0x0648, 0x0649, 0x064A,
|
||||
0x2261, 0x064B, 0x064C, 0x064D, 0x064E, 0x064F, 0xO650, 0x2248,
|
||||
0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 737
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP737(0x80-0xFF) to Unicode conversion table */
|
||||
0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398,
|
||||
0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, 0x03A0,
|
||||
0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9,
|
||||
0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, 0x03B8,
|
||||
0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0,
|
||||
0x03C1, 0x03C3, 0x03C2, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
|
||||
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
|
||||
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||
0x03C9, 0x03AC, 0x03AD, 0x03AE, 0x03CA, 0x03AF, 0x03CC, 0x03CD,
|
||||
0x03CB, 0x03CE, 0x0386, 0x0388, 0x0389, 0x038A, 0x038C, 0x038E,
|
||||
0x038F, 0x00B1, 0x2265, 0x2264, 0x03AA, 0x03AB, 0x00F7, 0x2248,
|
||||
0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 775
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP775(0x80-0xFF) to Unicode conversion table */
|
||||
0x0106, 0x00FC, 0x00E9, 0x0101, 0x00E4, 0x0123, 0x00E5, 0x0107,
|
||||
0x0142, 0x0113, 0x0156, 0x0157, 0x012B, 0x0179, 0x00C4, 0x00C5,
|
||||
0x00C9, 0x00E6, 0x00C6, 0x014D, 0x00F6, 0x0122, 0x00A2, 0x015A,
|
||||
0x015B, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x00A4,
|
||||
0x0100, 0x012A, 0x00F3, 0x017B, 0x017C, 0x017A, 0x201D, 0x00A6,
|
||||
0x00A9, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x0141, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0104, 0x010C, 0x0118,
|
||||
0x0116, 0x2563, 0x2551, 0x2557, 0x255D, 0x012E, 0x0160, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0172, 0x016A,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x017D,
|
||||
0x0105, 0x010D, 0x0119, 0x0117, 0x012F, 0x0161, 0x0173, 0x016B,
|
||||
0x017E, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||
0x00D3, 0x00DF, 0x014C, 0x0143, 0x00F5, 0x00D5, 0x00B5, 0x0144,
|
||||
0x0136, 0x0137, 0x013B, 0x013C, 0x0146, 0x0112, 0x0145, 0x2019,
|
||||
0x00AD, 0x00B1, 0x201C, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x201E,
|
||||
0x00B0, 0x2219, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 850
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP850(0x80-0xFF) to Unicode conversion table */
|
||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
|
||||
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
|
||||
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
|
||||
0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
|
||||
0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0,
|
||||
0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
|
||||
0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x0131, 0x00CD, 0x00CE,
|
||||
0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580,
|
||||
0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE,
|
||||
0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4,
|
||||
0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8,
|
||||
0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 852
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP852(0x80-0xFF) to Unicode conversion table */
|
||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x016F, 0x0107, 0x00E7,
|
||||
0x0142, 0x00EB, 0x0150, 0x0151, 0x00EE, 0x0179, 0x00C4, 0x0106,
|
||||
0x00C9, 0x0139, 0x013A, 0x00F4, 0x00F6, 0x013D, 0x013E, 0x015A,
|
||||
0x015B, 0x00D6, 0x00DC, 0x0164, 0x0165, 0x0141, 0x00D7, 0x010D,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x0104, 0x0105, 0x017D, 0x017E,
|
||||
0x0118, 0x0119, 0x00AC, 0x017A, 0x010C, 0x015F, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x011A,
|
||||
0x015E, 0x2563, 0x2551, 0x2557, 0x255D, 0x017B, 0x017C, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0102, 0x0103,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
|
||||
0x0111, 0x0110, 0x010E, 0x00CB, 0x010F, 0x0147, 0x00CD, 0x00CE,
|
||||
0x011B, 0x2518, 0x250C, 0x2588, 0x2584, 0x0162, 0x016E, 0x2580,
|
||||
0x00D3, 0x00DF, 0x00D4, 0x0143, 0x0144, 0x0148, 0x0160, 0x0161,
|
||||
0x0154, 0x00DA, 0x0155, 0x0170, 0x00FD, 0x00DD, 0x0163, 0x00B4,
|
||||
0x00AD, 0x02DD, 0x02DB, 0x02C7, 0x02D8, 0x00A7, 0x00F7, 0x00B8,
|
||||
0x00B0, 0x00A8, 0x02D9, 0x0171, 0x0158, 0x0159, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 855
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP855(0x80-0xFF) to Unicode conversion table */
|
||||
0x0452, 0x0402, 0x0453, 0x0403, 0x0451, 0x0401, 0x0454, 0x0404,
|
||||
0x0455, 0x0405, 0x0456, 0x0406, 0x0457, 0x0407, 0x0458, 0x0408,
|
||||
0x0459, 0x0409, 0x045A, 0x040A, 0x045B, 0x040B, 0x045C, 0x040C,
|
||||
0x045E, 0x040E, 0x045F, 0x040F, 0x044E, 0x042E, 0x044A, 0x042A,
|
||||
0x0430, 0x0410, 0x0431, 0x0411, 0x0446, 0x0426, 0x0434, 0x0414,
|
||||
0x0435, 0x0415, 0x0444, 0x0424, 0x0433, 0x0413, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0445, 0x0425, 0x0438,
|
||||
0x0418, 0x2563, 0x2551, 0x2557, 0x255D, 0x0439, 0x0419, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x043A, 0x041A,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
|
||||
0x043B, 0x041B, 0x043C, 0x041C, 0x043D, 0x041D, 0x043E, 0x041E,
|
||||
0x043F, 0x2518, 0x250C, 0x2588, 0x2584, 0x041F, 0x044F, 0x2580,
|
||||
0x042F, 0x0440, 0x0420, 0x0441, 0x0421, 0x0442, 0x0422, 0x0443,
|
||||
0x0423, 0x0436, 0x0416, 0x0432, 0x0412, 0x044C, 0x042C, 0x2116,
|
||||
0x00AD, 0x044B, 0x042B, 0x0437, 0x0417, 0x0448, 0x0428, 0x044D,
|
||||
0x042D, 0x0449, 0x0429, 0x0447, 0x0427, 0x00A7, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 857
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP857(0x80-0xFF) to Unicode conversion table */
|
||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
|
||||
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0131, 0x00C4, 0x00C5,
|
||||
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
|
||||
0x0130, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x015E, 0x015F,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x011E, 0x011F,
|
||||
0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0,
|
||||
0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
|
||||
0x00BA, 0x00AA, 0x00CA, 0x00CB, 0x00C8, 0x0000, 0x00CD, 0x00CE,
|
||||
0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580,
|
||||
0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x0000,
|
||||
0x00D7, 0x00DA, 0x00DB, 0x00D9, 0x00EC, 0x00FF, 0x00AF, 0x00B4,
|
||||
0x00AD, 0x00B1, 0x0000, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8,
|
||||
0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 858
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP858(0x80-0xFF) to Unicode conversion table */
|
||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
|
||||
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
|
||||
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
|
||||
0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
|
||||
0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0,
|
||||
0x00A9, 0x2563, 0x2551, 0x2557, 0x2550, 0x00A2, 0x00A5, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
|
||||
0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x20AC, 0x00CD, 0x00CE,
|
||||
0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00C6, 0x00CC, 0x2580,
|
||||
0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE,
|
||||
0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4,
|
||||
0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8,
|
||||
0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 862
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP862(0x80-0xFF) to Unicode conversion table */
|
||||
0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7,
|
||||
0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,
|
||||
0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7,
|
||||
0x05E8, 0x05E9, 0x05EA, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
|
||||
0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
|
||||
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
|
||||
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4,
|
||||
0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
|
||||
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248,
|
||||
0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 866
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP866(0x80-0xFF) to Unicode conversion table */
|
||||
0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
|
||||
0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
|
||||
0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
|
||||
0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
|
||||
0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
|
||||
0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
|
||||
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
|
||||
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||
0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
|
||||
0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
|
||||
0x0401, 0x0451, 0x0404, 0x0454, 0x0407, 0x0457, 0x040E, 0x045E,
|
||||
0x00B0, 0x2219, 0x00B7, 0x221A, 0x2116, 0x00A4, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 874
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP874(0x80-0xFF) to Unicode conversion table */
|
||||
0x20AC, 0x0000, 0x0000, 0x0000, 0x0000, 0x2026, 0x0000, 0x0000,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x00A0, 0x0E01, 0x0E02, 0x0E03, 0x0E04, 0x0E05, 0x0E06, 0x0E07,
|
||||
0x0E08, 0x0E09, 0x0E0A, 0x0E0B, 0x0E0C, 0x0E0D, 0x0E0E, 0x0E0F,
|
||||
0x0E10, 0x0E11, 0x0E12, 0x0E13, 0x0E14, 0x0E15, 0x0E16, 0x0E17,
|
||||
0x0E18, 0x0E19, 0x0E1A, 0x0E1B, 0x0E1C, 0x0E1D, 0x0E1E, 0x0E1F,
|
||||
0x0E20, 0x0E21, 0x0E22, 0x0E23, 0x0E24, 0x0E25, 0x0E26, 0x0E27,
|
||||
0x0E28, 0x0E29, 0x0E2A, 0x0E2B, 0x0E2C, 0x0E2D, 0x0E2E, 0x0E2F,
|
||||
0x0E30, 0x0E31, 0x0E32, 0x0E33, 0x0E34, 0x0E35, 0x0E36, 0x0E37,
|
||||
0x0E38, 0x0E39, 0x0E3A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0E3F,
|
||||
0x0E40, 0x0E41, 0x0E42, 0x0E43, 0x0E44, 0x0E45, 0x0E46, 0x0E47,
|
||||
0x0E48, 0x0E49, 0x0E4A, 0x0E4B, 0x0E4C, 0x0E4D, 0x0E4E, 0x0E4F,
|
||||
0x0E50, 0x0E51, 0x0E52, 0x0E53, 0x0E54, 0x0E55, 0x0E56, 0x0E57,
|
||||
0x0E58, 0x0E59, 0x0E5A, 0x0E5B, 0x0000, 0x0000, 0x0000, 0x0000
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 1250
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP1250(0x80-0xFF) to Unicode conversion table */
|
||||
0x20AC, 0x0000, 0x201A, 0x0000, 0x201E, 0x2026, 0x2020, 0x2021,
|
||||
0x0000, 0x2030, 0x0160, 0x2039, 0x015A, 0x0164, 0x017D, 0x0179,
|
||||
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
||||
0x0000, 0x2122, 0x0161, 0x203A, 0x015B, 0x0165, 0x017E, 0x017A,
|
||||
0x00A0, 0x02C7, 0x02D8, 0x0141, 0x00A4, 0x0104, 0x00A6, 0x00A7,
|
||||
0x00A8, 0x00A9, 0x015E, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x017B,
|
||||
0x00B0, 0x00B1, 0x02DB, 0x0142, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
|
||||
0x00B8, 0x0105, 0x015F, 0x00BB, 0x013D, 0x02DD, 0x013E, 0x017C,
|
||||
0x0154, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0139, 0x0106, 0x00C7,
|
||||
0x010C, 0x00C9, 0x0118, 0x00CB, 0x011A, 0x00CD, 0x00CE, 0x010E,
|
||||
0x0110, 0x0143, 0x0147, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x00D7,
|
||||
0x0158, 0x016E, 0x00DA, 0x0170, 0x00DC, 0x00DD, 0x0162, 0x00DF,
|
||||
0x0155, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x013A, 0x0107, 0x00E7,
|
||||
0x010D, 0x00E9, 0x0119, 0x00EB, 0x011B, 0x00ED, 0x00EE, 0x010F,
|
||||
0x0111, 0x0144, 0x0148, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x00F7,
|
||||
0x0159, 0x016F, 0x00FA, 0x0171, 0x00FC, 0x00FD, 0x0163, 0x02D9
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 1251
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP1251(0x80-0xFF) to Unicode conversion table */
|
||||
0x0402, 0x0403, 0x201A, 0x0453, 0x201E, 0x2026, 0x2020, 0x2021,
|
||||
0x20AC, 0x2030, 0x0409, 0x2039, 0x040A, 0x040C, 0x040B, 0x040F,
|
||||
0x0452, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
||||
0x0000, 0x2111, 0x0459, 0x203A, 0x045A, 0x045C, 0x045B, 0x045F,
|
||||
0x00A0, 0x040E, 0x045E, 0x0408, 0x00A4, 0x0490, 0x00A6, 0x00A7,
|
||||
0x0401, 0x00A9, 0x0404, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x0407,
|
||||
0x00B0, 0x00B1, 0x0406, 0x0456, 0x0491, 0x00B5, 0x00B6, 0x00B7,
|
||||
0x0451, 0x2116, 0x0454, 0x00BB, 0x0458, 0x0405, 0x0455, 0x0457,
|
||||
0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
|
||||
0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
|
||||
0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
|
||||
0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
|
||||
0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
|
||||
0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
|
||||
0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
|
||||
0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 1252
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP1252(0x80-0xFF) to Unicode conversion table */
|
||||
0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
|
||||
0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x017D, 0x0000,
|
||||
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
||||
0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x0000, 0x017E, 0x0178,
|
||||
0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
|
||||
0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
|
||||
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
|
||||
0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
|
||||
0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
|
||||
0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
|
||||
0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
|
||||
0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF,
|
||||
0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
|
||||
0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
|
||||
0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
|
||||
0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 1253
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP1253(0x80-0xFF) to Unicode conversion table */
|
||||
0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
|
||||
0x0000, 0x2030, 0x0000, 0x2039, 0x000C, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
||||
0x0000, 0x2122, 0x0000, 0x203A, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x00A0, 0x0385, 0x0386, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
|
||||
0x00A8, 0x00A9, 0x0000, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x2015,
|
||||
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x0384, 0x00B5, 0x00B6, 0x00B7,
|
||||
0x0388, 0x0389, 0x038A, 0x00BB, 0x038C, 0x00BD, 0x038E, 0x038F,
|
||||
0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397,
|
||||
0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F,
|
||||
0x03A0, 0x03A1, 0x0000, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7,
|
||||
0x03A8, 0x03A9, 0x03AA, 0x03AD, 0x03AC, 0x03AD, 0x03AE, 0x03AF,
|
||||
0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7,
|
||||
0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF,
|
||||
0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7,
|
||||
0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, 0x0000
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 1254
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP1254(0x80-0xFF) to Unicode conversion table */
|
||||
0x20AC, 0x0000, 0x210A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
|
||||
0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
||||
0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x0000, 0x0000, 0x0178,
|
||||
0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
|
||||
0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
|
||||
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
|
||||
0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
|
||||
0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
|
||||
0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
|
||||
0x011E, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
|
||||
0x00D8, 0x00D9, 0x00DA, 0x00BD, 0x00DC, 0x0130, 0x015E, 0x00DF,
|
||||
0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
|
||||
0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
|
||||
0x011F, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
|
||||
0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x0131, 0x015F, 0x00FF
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 1255
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP1255(0x80-0xFF) to Unicode conversion table */
|
||||
0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
|
||||
0x02C6, 0x2030, 0x0000, 0x2039, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
||||
0x02DC, 0x2122, 0x0000, 0x203A, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
|
||||
0x00A8, 0x00A9, 0x00D7, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
|
||||
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
|
||||
0x00B8, 0x00B9, 0x00F7, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
|
||||
0x05B0, 0x05B1, 0x05B2, 0x05B3, 0x05B4, 0x05B5, 0x05B6, 0x05B7,
|
||||
0x05B8, 0x05B9, 0x0000, 0x05BB, 0x05BC, 0x05BD, 0x05BE, 0x05BF,
|
||||
0x05C0, 0x05C1, 0x05C2, 0x05C3, 0x05F0, 0x05F1, 0x05F2, 0x05F3,
|
||||
0x05F4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7,
|
||||
0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,
|
||||
0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7,
|
||||
0x05E8, 0x05E9, 0x05EA, 0x0000, 0x0000, 0x200E, 0x200F, 0x0000
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 1256
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP1256(0x80-0xFF) to Unicode conversion table */
|
||||
0x20AC, 0x067E, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
|
||||
0x02C6, 0x2030, 0x0679, 0x2039, 0x0152, 0x0686, 0x0698, 0x0688,
|
||||
0x06AF, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
||||
0x06A9, 0x2122, 0x0691, 0x203A, 0x0153, 0x200C, 0x200D, 0x06BA,
|
||||
0x00A0, 0x060C, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
|
||||
0x00A8, 0x00A9, 0x06BE, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
|
||||
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
|
||||
0x00B8, 0x00B9, 0x061B, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x061F,
|
||||
0x06C1, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627,
|
||||
0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F,
|
||||
0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x00D7,
|
||||
0x0637, 0x0638, 0x0639, 0x063A, 0x0640, 0x0640, 0x0642, 0x0643,
|
||||
0x00E0, 0x0644, 0x00E2, 0x0645, 0x0646, 0x0647, 0x0648, 0x00E7,
|
||||
0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x0649, 0x064A, 0x00EE, 0x00EF,
|
||||
0x064B, 0x064C, 0x064D, 0x064E, 0x00F4, 0x064F, 0x0650, 0x00F7,
|
||||
0x0651, 0x00F9, 0x0652, 0x00FB, 0x00FC, 0x200E, 0x200F, 0x06D2
|
||||
}
|
||||
|
||||
#elif _CODE_PAGE == 1257
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP1257(0x80-0xFF) to Unicode conversion table */
|
||||
0x20AC, 0x0000, 0x201A, 0x0000, 0x201E, 0x2026, 0x2020, 0x2021,
|
||||
0x0000, 0x2030, 0x0000, 0x2039, 0x0000, 0x00A8, 0x02C7, 0x00B8,
|
||||
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
||||
0x0000, 0x2122, 0x0000, 0x203A, 0x0000, 0x00AF, 0x02DB, 0x0000,
|
||||
0x00A0, 0x0000, 0x00A2, 0x00A3, 0x00A4, 0x0000, 0x00A6, 0x00A7,
|
||||
0x00D8, 0x00A9, 0x0156, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
|
||||
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
|
||||
0x00B8, 0x00B9, 0x0157, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00E6,
|
||||
0x0104, 0x012E, 0x0100, 0x0106, 0x00C4, 0x00C5, 0x0118, 0x0112,
|
||||
0x010C, 0x00C9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012A, 0x013B,
|
||||
0x0160, 0x0143, 0x0145, 0x00D3, 0x014C, 0x00D5, 0x00D6, 0x00D7,
|
||||
0x0172, 0x0141, 0x015A, 0x016A, 0x00DC, 0x017B, 0x017D, 0x00DF,
|
||||
0x0105, 0x012F, 0x0101, 0x0107, 0x00E4, 0x00E5, 0x0119, 0x0113,
|
||||
0x010D, 0x00E9, 0x017A, 0x0117, 0x0123, 0x0137, 0x012B, 0x013C,
|
||||
0x0161, 0x0144, 0x0146, 0x00F3, 0x014D, 0x00F5, 0x00F6, 0x00F7,
|
||||
0x0173, 0x014E, 0x015B, 0x016B, 0x00FC, 0x017C, 0x017E, 0x02D9
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 1258
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP1258(0x80-0xFF) to Unicode conversion table */
|
||||
0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
|
||||
0x02C6, 0x2030, 0x0000, 0x2039, 0x0152, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
||||
0x02DC, 0x2122, 0x0000, 0x203A, 0x0153, 0x0000, 0x0000, 0x0178,
|
||||
0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
|
||||
0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
|
||||
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
|
||||
0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
|
||||
0x00C0, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
|
||||
0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x0300, 0x00CD, 0x00CE, 0x00CF,
|
||||
0x0110, 0x00D1, 0x0309, 0x00D3, 0x00D4, 0x01A0, 0x00D6, 0x00D7,
|
||||
0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x01AF, 0x0303, 0x00DF,
|
||||
0x00E0, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
|
||||
0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x0301, 0x00ED, 0x00EE, 0x00EF,
|
||||
0x0111, 0x00F1, 0x0323, 0x00F3, 0x00F4, 0x01A1, 0x00F6, 0x00F7,
|
||||
0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x01B0, 0x20AB, 0x00FF
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#if !_TBLDEF || !_USE_LFN
|
||||
#error This file is not needed in current configuration. Remove from the project.
|
||||
#endif
|
||||
|
||||
|
||||
WCHAR ff_convert ( /* Converted character, Returns zero on error */
|
||||
WCHAR src, /* Character code to be converted */
|
||||
UINT dir /* 0: Unicode to OEMCP, 1: OEMCP to Unicode */
|
||||
)
|
||||
{
|
||||
WCHAR c;
|
||||
|
||||
|
||||
if (src < 0x80) { /* ASCII */
|
||||
c = src;
|
||||
|
||||
} else {
|
||||
if (dir) { /* OEMCP to Unicode */
|
||||
c = (src >= 0x100) ? 0 : Tbl[src - 0x80];
|
||||
|
||||
} else { /* Unicode to OEMCP */
|
||||
for (c = 0; c < 0x80; c++) {
|
||||
if (src == Tbl[c]) break;
|
||||
}
|
||||
c = (c + 0x80) & 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
WCHAR ff_wtoupper ( /* Upper converted character */
|
||||
WCHAR chr /* Input character */
|
||||
)
|
||||
{
|
||||
static const WCHAR tbl_lower[] = { 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0xA1, 0x00A2, 0x00A3, 0x00A5, 0x00AC, 0x00AF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0x0FF, 0x101, 0x103, 0x105, 0x107, 0x109, 0x10B, 0x10D, 0x10F, 0x111, 0x113, 0x115, 0x117, 0x119, 0x11B, 0x11D, 0x11F, 0x121, 0x123, 0x125, 0x127, 0x129, 0x12B, 0x12D, 0x12F, 0x131, 0x133, 0x135, 0x137, 0x13A, 0x13C, 0x13E, 0x140, 0x142, 0x144, 0x146, 0x148, 0x14B, 0x14D, 0x14F, 0x151, 0x153, 0x155, 0x157, 0x159, 0x15B, 0x15D, 0x15F, 0x161, 0x163, 0x165, 0x167, 0x169, 0x16B, 0x16D, 0x16F, 0x171, 0x173, 0x175, 0x177, 0x17A, 0x17C, 0x17E, 0x192, 0x3B1, 0x3B2, 0x3B3, 0x3B4, 0x3B5, 0x3B6, 0x3B7, 0x3B8, 0x3B9, 0x3BA, 0x3BB, 0x3BC, 0x3BD, 0x3BE, 0x3BF, 0x3C0, 0x3C1, 0x3C3, 0x3C4, 0x3C5, 0x3C6, 0x3C7, 0x3C8, 0x3C9, 0x3CA, 0x430, 0x431, 0x432, 0x433, 0x434, 0x435, 0x436, 0x437, 0x438, 0x439, 0x43A, 0x43B, 0x43C, 0x43D, 0x43E, 0x43F, 0x440, 0x441, 0x442, 0x443, 0x444, 0x445, 0x446, 0x447, 0x448, 0x449, 0x44A, 0x44B, 0x44C, 0x44D, 0x44E, 0x44F, 0x451, 0x452, 0x453, 0x454, 0x455, 0x456, 0x457, 0x458, 0x459, 0x45A, 0x45B, 0x45C, 0x45E, 0x45F, 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177, 0x2178, 0x2179, 0x217A, 0x217B, 0x217C, 0x217D, 0x217E, 0x217F, 0xFF41, 0xFF42, 0xFF43, 0xFF44, 0xFF45, 0xFF46, 0xFF47, 0xFF48, 0xFF49, 0xFF4A, 0xFF4B, 0xFF4C, 0xFF4D, 0xFF4E, 0xFF4F, 0xFF50, 0xFF51, 0xFF52, 0xFF53, 0xFF54, 0xFF55, 0xFF56, 0xFF57, 0xFF58, 0xFF59, 0xFF5A, 0 };
|
||||
static const WCHAR tbl_upper[] = { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x21, 0xFFE0, 0xFFE1, 0xFFE5, 0xFFE2, 0xFFE3, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0x178, 0x100, 0x102, 0x104, 0x106, 0x108, 0x10A, 0x10C, 0x10E, 0x110, 0x112, 0x114, 0x116, 0x118, 0x11A, 0x11C, 0x11E, 0x120, 0x122, 0x124, 0x126, 0x128, 0x12A, 0x12C, 0x12E, 0x130, 0x132, 0x134, 0x136, 0x139, 0x13B, 0x13D, 0x13F, 0x141, 0x143, 0x145, 0x147, 0x14A, 0x14C, 0x14E, 0x150, 0x152, 0x154, 0x156, 0x158, 0x15A, 0x15C, 0x15E, 0x160, 0x162, 0x164, 0x166, 0x168, 0x16A, 0x16C, 0x16E, 0x170, 0x172, 0x174, 0x176, 0x179, 0x17B, 0x17D, 0x191, 0x391, 0x392, 0x393, 0x394, 0x395, 0x396, 0x397, 0x398, 0x399, 0x39A, 0x39B, 0x39C, 0x39D, 0x39E, 0x39F, 0x3A0, 0x3A1, 0x3A3, 0x3A4, 0x3A5, 0x3A6, 0x3A7, 0x3A8, 0x3A9, 0x3AA, 0x410, 0x411, 0x412, 0x413, 0x414, 0x415, 0x416, 0x417, 0x418, 0x419, 0x41A, 0x41B, 0x41C, 0x41D, 0x41E, 0x41F, 0x420, 0x421, 0x422, 0x423, 0x424, 0x425, 0x426, 0x427, 0x428, 0x429, 0x42A, 0x42B, 0x42C, 0x42D, 0x42E, 0x42F, 0x401, 0x402, 0x403, 0x404, 0x405, 0x406, 0x407, 0x408, 0x409, 0x40A, 0x40B, 0x40C, 0x40E, 0x40F, 0x2160, 0x2161, 0x2162, 0x2163, 0x2164, 0x2165, 0x2166, 0x2167, 0x2168, 0x2169, 0x216A, 0x216B, 0x216C, 0x216D, 0x216E, 0x216F, 0xFF21, 0xFF22, 0xFF23, 0xFF24, 0xFF25, 0xFF26, 0xFF27, 0xFF28, 0xFF29, 0xFF2A, 0xFF2B, 0xFF2C, 0xFF2D, 0xFF2E, 0xFF2F, 0xFF30, 0xFF31, 0xFF32, 0xFF33, 0xFF34, 0xFF35, 0xFF36, 0xFF37, 0xFF38, 0xFF39, 0xFF3A, 0 };
|
||||
int i;
|
||||
|
||||
|
||||
for (i = 0; tbl_lower[i] && chr != tbl_lower[i]; i++) ;
|
||||
|
||||
return tbl_lower[i] ? tbl_upper[i] : chr;
|
||||
}
|
||||
76
src/tests/cic.c
Normal file
76
src/tests/cic.c
Normal file
@ -0,0 +1,76 @@
|
||||
#include <arm/NXP/LPC17xx/LPC17xx.h>
|
||||
#include "bits.h"
|
||||
#include "config.h"
|
||||
#include "uart.h"
|
||||
#include "cic.h"
|
||||
|
||||
char *cicstatenames[4] = { "CIC_OK", "CIC_FAIL", "CIC_PAIR", "CIC_SCIC" };
|
||||
|
||||
void print_cic_state() {
|
||||
printf("CIC state: %s\n", get_cic_statename(get_cic_state()));
|
||||
}
|
||||
|
||||
inline char *get_cic_statename(enum cicstates state) {
|
||||
return cicstatenames[state];
|
||||
}
|
||||
|
||||
enum cicstates get_cic_state() {
|
||||
uint32_t count;
|
||||
uint32_t togglecount = 0;
|
||||
uint8_t state, state_old;
|
||||
|
||||
state_old = BITBAND(SNES_CIC_STATUS_REG->FIOPIN, SNES_CIC_STATUS_BIT);
|
||||
/* this loop samples at ~10MHz */
|
||||
for(count=0; count<CIC_SAMPLECOUNT; count++) {
|
||||
state = BITBAND(SNES_CIC_STATUS_REG->FIOPIN, SNES_CIC_STATUS_BIT);
|
||||
if(state != state_old) {
|
||||
togglecount++;
|
||||
}
|
||||
state_old = state;
|
||||
}
|
||||
/* CIC_TOGGLE_THRESH_PAIR > CIC_TOGGLE_THRESH_SCIC */
|
||||
if(togglecount > CIC_TOGGLE_THRESH_PAIR) {
|
||||
return CIC_PAIR;
|
||||
} else if(togglecount > CIC_TOGGLE_THRESH_SCIC) {
|
||||
return CIC_SCIC;
|
||||
} else if(state) {
|
||||
return CIC_OK;
|
||||
} else return CIC_FAIL;
|
||||
}
|
||||
|
||||
void cic_init(int allow_pairmode) {
|
||||
BITBAND(SNES_CIC_PAIR_REG->FIODIR, SNES_CIC_PAIR_BIT) = 1;
|
||||
if(allow_pairmode) {
|
||||
BITBAND(SNES_CIC_PAIR_REG->FIOCLR, SNES_CIC_PAIR_BIT) = 1;
|
||||
} else {
|
||||
BITBAND(SNES_CIC_PAIR_REG->FIOSET, SNES_CIC_PAIR_BIT) = 1;
|
||||
}
|
||||
BITBAND(SNES_CIC_D0_REG->FIODIR, SNES_CIC_D0_BIT) = 0;
|
||||
BITBAND(SNES_CIC_D1_REG->FIODIR, SNES_CIC_D1_BIT) = 0;
|
||||
}
|
||||
|
||||
/* prepare GPIOs for pair mode + set initial modes */
|
||||
void cic_pair(int init_vmode, int init_d4) {
|
||||
cic_videomode(init_vmode);
|
||||
cic_d4(init_d4);
|
||||
|
||||
BITBAND(SNES_CIC_D0_REG->FIODIR, SNES_CIC_D0_BIT) = 1;
|
||||
BITBAND(SNES_CIC_D1_REG->FIODIR, SNES_CIC_D1_BIT) = 1;
|
||||
}
|
||||
|
||||
void cic_videomode(int value) {
|
||||
if(value) {
|
||||
BITBAND(SNES_CIC_D0_REG->FIOSET, SNES_CIC_D0_BIT) = 1;
|
||||
} else {
|
||||
BITBAND(SNES_CIC_D0_REG->FIOCLR, SNES_CIC_D0_BIT) = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void cic_d4(int value) {
|
||||
if(value) {
|
||||
BITBAND(SNES_CIC_D1_REG->FIOSET, SNES_CIC_D1_BIT) = 1;
|
||||
} else {
|
||||
BITBAND(SNES_CIC_D1_REG->FIOCLR, SNES_CIC_D1_BIT) = 1;
|
||||
}
|
||||
}
|
||||
|
||||
23
src/tests/cic.h
Normal file
23
src/tests/cic.h
Normal file
@ -0,0 +1,23 @@
|
||||
#ifndef _CIC_H
|
||||
#define _CIC_H
|
||||
|
||||
#define CIC_SAMPLECOUNT (100000)
|
||||
#define CIC_TOGGLE_THRESH_PAIR (2500)
|
||||
#define CIC_TOGGLE_THRESH_SCIC (10)
|
||||
|
||||
#include <arm/NXP/LPC17xx/LPC17xx.h>
|
||||
#include "bits.h"
|
||||
|
||||
enum cicstates { CIC_OK = 0, CIC_FAIL, CIC_PAIR, CIC_SCIC };
|
||||
enum cic_region { CIC_NTSC = 0, CIC_PAL };
|
||||
|
||||
void print_cic_state(void);
|
||||
char *get_cic_statename(enum cicstates state);
|
||||
enum cicstates get_cic_state(void);
|
||||
void cic_init(int allow_pairmode);
|
||||
|
||||
void cic_pair(int init_vmode, int init_d4);
|
||||
void cic_videomode(int value);
|
||||
void cic_d4(int value);
|
||||
|
||||
#endif
|
||||
576
src/tests/cli.c
Normal file
576
src/tests/cli.c
Normal file
@ -0,0 +1,576 @@
|
||||
/* tapplay - TAP file playback for sd2iec hardware
|
||||
Copyright (C) 2009 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
|
||||
|
||||
|
||||
cli.c: The command line interface
|
||||
|
||||
*/
|
||||
|
||||
#include <arm/NXP/LPC17xx/LPC17xx.h>
|
||||
#include <arm/bits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include "config.h"
|
||||
#include "diskio.h"
|
||||
#include "ff.h"
|
||||
#include "timer.h"
|
||||
#include "uart.h"
|
||||
#include "fileops.h"
|
||||
#include "memory.h"
|
||||
#include "snes.h"
|
||||
#include "fpga.h"
|
||||
#include "fpga_spi.h"
|
||||
#include "cic.h"
|
||||
#include "xmodem.h"
|
||||
#include "rtc.h"
|
||||
|
||||
#include "cli.h"
|
||||
|
||||
#define MAX_LINE 250
|
||||
|
||||
/* Variables */
|
||||
static char cmdbuffer[MAX_LINE+1];
|
||||
static char *curchar;
|
||||
|
||||
/* Word lists */
|
||||
static char command_words[] =
|
||||
"cd\0reset\0sreset\0dir\0ls\0test\0resume\0loadrom\0loadraw\0saveraw\0put\0rm\0d4\0vmode\0mapper\0settime\0time\0setfeature\0hexdump\0w8\0w16\0memsel\0";
|
||||
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_MEMSEL };
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* Parse functions */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/* Skip spaces at curchar */
|
||||
static uint8_t skip_spaces(void) {
|
||||
uint8_t res = (*curchar == ' ' || *curchar == 0);
|
||||
|
||||
while (*curchar == ' ')
|
||||
curchar++;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Parse the string in curchar for an integer with bounds [lower,upper] */
|
||||
static int32_t parse_unsigned(uint32_t lower, uint32_t upper, uint8_t base) {
|
||||
char *end;
|
||||
uint32_t result;
|
||||
|
||||
if (strlen(curchar) == 1 && *curchar == '?') {
|
||||
printf("Number between %ld[0x%lx] and %ld[0x%lx] expected\n",lower,lower,upper,upper);
|
||||
return -2;
|
||||
}
|
||||
|
||||
result = strtoul(curchar, &end, base);
|
||||
if ((*end != ' ' && *end != 0) || errno != 0) {
|
||||
printf("Invalid numeric argument\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
curchar = end;
|
||||
skip_spaces();
|
||||
|
||||
if (result < lower || result > upper) {
|
||||
printf("Numeric argument out of range (%ld..%ld)\n",lower,upper);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
/* Parse the string starting with curchar for a word in wordlist */
|
||||
static int8_t parse_wordlist(char *wordlist) {
|
||||
uint8_t i, matched;
|
||||
char *cur, *ptr;
|
||||
char c;
|
||||
|
||||
i = 0;
|
||||
ptr = wordlist;
|
||||
|
||||
// Command list on "?"
|
||||
if (strlen(curchar) == 1 && *curchar == '?') {
|
||||
printf("Commands available: \n ");
|
||||
while (1) {
|
||||
c = *ptr++;
|
||||
if (c == 0) {
|
||||
if (*ptr == 0) {
|
||||
printf("\n");
|
||||
return -2;
|
||||
} else {
|
||||
printf("\n ");
|
||||
}
|
||||
} else
|
||||
uart_putc(c);
|
||||
}
|
||||
}
|
||||
|
||||
while (1) {
|
||||
cur = curchar;
|
||||
matched = 1;
|
||||
c = *ptr;
|
||||
do {
|
||||
// If current word list character is \0: No match found
|
||||
if (c == 0) {
|
||||
printf("Unknown word: %s\n",curchar);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (tolower(c) != tolower(*cur)) {
|
||||
// Check for end-of-word
|
||||
if (cur != curchar && (*cur == ' ' || *cur == 0)) {
|
||||
// Partial match found, return that
|
||||
break;
|
||||
} else {
|
||||
matched = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ptr++;
|
||||
cur++;
|
||||
c = *ptr;
|
||||
} while (c != 0);
|
||||
|
||||
if (matched) {
|
||||
char *tmp = curchar;
|
||||
|
||||
curchar = cur;
|
||||
// Return match only if whitespace or end-of-string follows
|
||||
// (avoids mismatching partial words)
|
||||
if (skip_spaces()) {
|
||||
return i;
|
||||
} else {
|
||||
printf("Unknown word: %s\n(use ? for help)\n",tmp);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
// Try next word in list
|
||||
i++;
|
||||
while (*ptr++ != 0) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Read a line from serial, uses cmdbuffer as storage */
|
||||
static char *getline(char *prompt) {
|
||||
int i=0;
|
||||
char c;
|
||||
|
||||
printf("\n%s",prompt);
|
||||
memset(cmdbuffer,0,sizeof(cmdbuffer));
|
||||
|
||||
while (1) {
|
||||
c = uart_getc();
|
||||
if (c == 13)
|
||||
break;
|
||||
|
||||
if (c == 27 || c == 3) {
|
||||
printf("\\\n%s",prompt);
|
||||
i = 0;
|
||||
memset(cmdbuffer,0,sizeof(cmdbuffer));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c == 127 || c == 8) {
|
||||
if (i > 0) {
|
||||
i--;
|
||||
uart_putc(8); // backspace
|
||||
uart_putc(' '); // erase character
|
||||
uart_putc(8); // backspace
|
||||
} else
|
||||
continue;
|
||||
} else {
|
||||
if (i < sizeof(cmdbuffer)-1) {
|
||||
cmdbuffer[i++] = c;
|
||||
uart_putc(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
cmdbuffer[i] = 0;
|
||||
return cmdbuffer;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* Command functions */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/* Reset */
|
||||
static void cmd_reset(void) {
|
||||
/* force watchdog reset */
|
||||
LPC_WDT->WDTC = 256; // minimal timeout
|
||||
LPC_WDT->WDCLKSEL = BV(31); // internal RC, lock register
|
||||
LPC_WDT->WDMOD = BV(0) | BV(1); // enable watchdog and reset-by-watchdog
|
||||
LPC_WDT->WDFEED = 0xaa;
|
||||
LPC_WDT->WDFEED = 0x55; // initial feed to really enable WDT
|
||||
}
|
||||
|
||||
/* Show the contents of the current directory */
|
||||
static void cmd_show_directory(void) {
|
||||
FRESULT res;
|
||||
DIR dh;
|
||||
FILINFO finfo;
|
||||
uint8_t *name;
|
||||
|
||||
f_getcwd((TCHAR*)file_lfn, 255);
|
||||
|
||||
res = f_opendir(&dh, (TCHAR*)file_lfn);
|
||||
if (res != FR_OK) {
|
||||
printf("f_opendir failed, result %d\n",res);
|
||||
return;
|
||||
}
|
||||
|
||||
finfo.lfname = (TCHAR*)file_lfn;
|
||||
finfo.lfsize = 255;
|
||||
|
||||
do {
|
||||
/* Read the next entry */
|
||||
res = f_readdir(&dh, &finfo);
|
||||
if (res != FR_OK) {
|
||||
printf("f_readdir failed, result %d\n",res);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Abort if none was found */
|
||||
if (!finfo.fname[0])
|
||||
break;
|
||||
|
||||
/* Skip volume labels */
|
||||
if (finfo.fattrib & AM_VOL)
|
||||
continue;
|
||||
|
||||
/* Select between LFN and 8.3 name */
|
||||
if (finfo.lfname[0])
|
||||
name = (uint8_t*)finfo.lfname;
|
||||
else {
|
||||
name = (uint8_t*)finfo.fname;
|
||||
strlwr((char *)name);
|
||||
}
|
||||
|
||||
printf("%s",name);
|
||||
|
||||
/* Directory indicator (Unix-style) */
|
||||
if (finfo.fattrib & AM_DIR)
|
||||
uart_putc('/');
|
||||
|
||||
printf("\n");
|
||||
} while (finfo.fname[0]);
|
||||
}
|
||||
|
||||
|
||||
static void cmd_loadrom(void) {
|
||||
uint32_t address = 0;
|
||||
uint8_t flags = LOADROM_WITH_SRAM | LOADROM_WITH_RESET;
|
||||
load_rom((uint8_t*)curchar, address, flags);
|
||||
}
|
||||
|
||||
static void cmd_loadraw(void) {
|
||||
uint32_t address = parse_unsigned(0,16777216,16);
|
||||
load_sram((uint8_t*)curchar, address);
|
||||
}
|
||||
|
||||
static void cmd_saveraw(void) {
|
||||
uint32_t address = parse_unsigned(0,16777216,16);
|
||||
uint32_t length = parse_unsigned(0,16777216,16);
|
||||
save_sram((uint8_t*)curchar, length, address);
|
||||
}
|
||||
|
||||
static void cmd_d4(void) {
|
||||
int32_t hz;
|
||||
|
||||
if(get_cic_state() != CIC_PAIR) {
|
||||
printf("not in pair mode\n");
|
||||
} else {
|
||||
hz = parse_unsigned(50,60,10);
|
||||
if(hz==50) {
|
||||
cic_d4(CIC_PAL);
|
||||
} else {
|
||||
cic_d4(CIC_NTSC);
|
||||
}
|
||||
printf("ok\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void cmd_vmode(void) {
|
||||
int32_t hz;
|
||||
if(get_cic_state() != CIC_PAIR) {
|
||||
printf("not in pair mode\n");
|
||||
} else {
|
||||
hz = parse_unsigned(50,60,10);
|
||||
if(hz==50) {
|
||||
cic_videomode(CIC_PAL);
|
||||
} else {
|
||||
cic_videomode(CIC_NTSC);
|
||||
}
|
||||
printf("ok\n");
|
||||
}
|
||||
}
|
||||
|
||||
void cmd_put(void) {
|
||||
if(*curchar != 0) {
|
||||
file_open((uint8_t*)curchar, FA_CREATE_ALWAYS | FA_WRITE);
|
||||
if(file_res) {
|
||||
printf("FAIL: error opening file %s\n", curchar);
|
||||
} else {
|
||||
printf("OK, start xmodem transfer now.\n");
|
||||
xmodem_rxfile(&file_handle);
|
||||
}
|
||||
file_close();
|
||||
} else {
|
||||
printf("Usage: put <filename>\n");
|
||||
}
|
||||
}
|
||||
|
||||
void cmd_rm(void) {
|
||||
FRESULT res = f_unlink(curchar);
|
||||
if(res) printf("Error %d removing %s\n", res, curchar);
|
||||
}
|
||||
|
||||
void cmd_mapper(void) {
|
||||
int32_t mapper;
|
||||
mapper = parse_unsigned(0,7,10);
|
||||
set_mapper((uint8_t)mapper & 0x7);
|
||||
printf("mapper set to %ld\n", mapper);
|
||||
}
|
||||
|
||||
void cmd_sreset(void) {
|
||||
if(*curchar != 0) {
|
||||
int32_t resetstate;
|
||||
resetstate = parse_unsigned(0,1,10);
|
||||
snes_reset(resetstate);
|
||||
} else {
|
||||
snes_reset(1);
|
||||
delay_ms(20);
|
||||
snes_reset(0);
|
||||
}
|
||||
}
|
||||
void cmd_settime(void) {
|
||||
struct tm time;
|
||||
if(strlen(curchar) != 4+2+2 + 2+2+2) {
|
||||
printf("invalid time format (need YYYYMMDDhhmmss)\n");
|
||||
} else {
|
||||
time.tm_sec = atoi(curchar+4+2+2+2+2);
|
||||
curchar[4+2+2+2+2] = 0;
|
||||
time.tm_min = atoi(curchar+4+2+2+2);
|
||||
curchar[4+2+2+2] = 0;
|
||||
time.tm_hour = atoi(curchar+4+2+2);
|
||||
curchar[4+2+2] = 0;
|
||||
time.tm_mday = atoi(curchar+4+2);
|
||||
curchar[4+2] = 0;
|
||||
time.tm_mon = atoi(curchar+4);
|
||||
curchar[4] = 0;
|
||||
time.tm_year = atoi(curchar);
|
||||
set_rtc(&time);
|
||||
}
|
||||
}
|
||||
|
||||
void cmd_time(void) {
|
||||
struct tm time;
|
||||
read_rtc(&time);
|
||||
printf("%04d-%02d-%02d %02d:%02d:%02d\n", time.tm_year, time.tm_mon,
|
||||
time.tm_mday, time.tm_hour, time.tm_min, time.tm_sec);
|
||||
}
|
||||
|
||||
void cmd_setfeature(void) {
|
||||
uint8_t feat = parse_unsigned(0, 255, 16);
|
||||
fpga_set_features(feat);
|
||||
}
|
||||
|
||||
void cmd_hexdump(void) {
|
||||
uint32_t offset = parse_unsigned(0, 16777215, 16);
|
||||
uint32_t len = parse_unsigned(0, 16777216, 16);
|
||||
sram_hexdump(offset, len);
|
||||
}
|
||||
|
||||
void cmd_w8(void) {
|
||||
uint32_t offset = parse_unsigned(0, 16777215, 16);
|
||||
uint8_t val = parse_unsigned(0, 255, 16);
|
||||
sram_writebyte(val, offset);
|
||||
}
|
||||
|
||||
void cmd_w16(void) {
|
||||
uint32_t offset = parse_unsigned(0, 16777215, 16);
|
||||
uint16_t val = parse_unsigned(0, 65535, 16);
|
||||
sram_writeshort(val, offset);
|
||||
}
|
||||
|
||||
void cmd_memsel(void) {
|
||||
uint8_t unit = parse_unsigned(0,1,10);
|
||||
fpga_select_mem(unit);
|
||||
}
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* CLI interface functions */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
void cli_init(void) {
|
||||
}
|
||||
|
||||
void cli_entrycheck() {
|
||||
if(uart_gotc() && uart_getc() == 27) {
|
||||
printf("*** BREAK\n");
|
||||
cli_loop();
|
||||
}
|
||||
}
|
||||
|
||||
void cli_loop(void) {
|
||||
snes_reset(1);
|
||||
while (1) {
|
||||
curchar = getline(">");
|
||||
printf("\n");
|
||||
|
||||
/* Process medium changes before executing the command */
|
||||
if (disk_state != DISK_OK && disk_state != DISK_REMOVED) {
|
||||
FRESULT res;
|
||||
|
||||
printf("Medium changed... ");
|
||||
res = f_mount(0,&fatfs);
|
||||
if (res != FR_OK) {
|
||||
printf("Failed to mount new medium, result %d\n",res);
|
||||
} else {
|
||||
printf("Ok\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Remove whitespace */
|
||||
while (*curchar == ' ') curchar++;
|
||||
while (strlen(curchar) > 0 && curchar[strlen(curchar)-1] == ' ')
|
||||
curchar[strlen(curchar)-1] = 0;
|
||||
|
||||
/* Ignore empty lines */
|
||||
if (strlen(curchar) == 0)
|
||||
continue;
|
||||
|
||||
/* Parse command */
|
||||
int8_t command = parse_wordlist(command_words);
|
||||
if (command < 0)
|
||||
continue;
|
||||
|
||||
|
||||
FRESULT res;
|
||||
switch (command) {
|
||||
case CMD_CD:
|
||||
#if _FS_RPATH
|
||||
if (strlen(curchar) == 0) {
|
||||
f_getcwd((TCHAR*)file_lfn, 255);
|
||||
printf("%s\n",file_lfn);
|
||||
break;
|
||||
}
|
||||
|
||||
res = f_chdir((const TCHAR *)curchar);
|
||||
if (res != FR_OK) {
|
||||
printf("chdir %s failed with result %d\n",curchar,res);
|
||||
} else {
|
||||
printf("Ok.\n");
|
||||
}
|
||||
#else
|
||||
printf("cd not supported.\n");
|
||||
res;
|
||||
#endif
|
||||
break;
|
||||
case CMD_RESET:
|
||||
cmd_reset();
|
||||
break;
|
||||
|
||||
case CMD_SRESET:
|
||||
cmd_sreset();
|
||||
break;
|
||||
|
||||
case CMD_DIR:
|
||||
case CMD_LS:
|
||||
cmd_show_directory();
|
||||
break;
|
||||
|
||||
case CMD_RESUME:
|
||||
return;
|
||||
break;
|
||||
|
||||
case CMD_LOADROM:
|
||||
cmd_loadrom();
|
||||
break;
|
||||
|
||||
case CMD_LOADRAW:
|
||||
cmd_loadraw();
|
||||
break;
|
||||
|
||||
case CMD_SAVERAW:
|
||||
cmd_saveraw();
|
||||
break;
|
||||
|
||||
case CMD_RM:
|
||||
cmd_rm();
|
||||
break;
|
||||
|
||||
case CMD_D4:
|
||||
cmd_d4();
|
||||
break;
|
||||
|
||||
case CMD_VMODE:
|
||||
cmd_vmode();
|
||||
break;
|
||||
|
||||
case CMD_PUT:
|
||||
cmd_put();
|
||||
break;
|
||||
|
||||
case CMD_MAPPER:
|
||||
cmd_mapper();
|
||||
break;
|
||||
|
||||
case CMD_SETTIME:
|
||||
cmd_settime();
|
||||
break;
|
||||
|
||||
case CMD_TIME:
|
||||
cmd_time();
|
||||
break;
|
||||
|
||||
case CMD_TEST:
|
||||
testbattery();
|
||||
break;
|
||||
|
||||
case CMD_SETFEATURE:
|
||||
cmd_setfeature();
|
||||
break;
|
||||
|
||||
case CMD_HEXDUMP:
|
||||
cmd_hexdump();
|
||||
break;
|
||||
|
||||
case CMD_W8:
|
||||
cmd_w8();
|
||||
break;
|
||||
|
||||
case CMD_W16:
|
||||
cmd_w16();
|
||||
break;
|
||||
|
||||
case CMD_MEMSEL:
|
||||
cmd_memsel();
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
34
src/tests/cli.h
Normal file
34
src/tests/cli.h
Normal file
@ -0,0 +1,34 @@
|
||||
/* tapplay - TAP file playback for sd2iec hardware
|
||||
Copyright (C) 2009 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
|
||||
|
||||
|
||||
cli.h: Definitions for cli.c
|
||||
|
||||
*/
|
||||
|
||||
#ifndef CLI_H
|
||||
#define CLI_H
|
||||
|
||||
void cli_init(void);
|
||||
void cli_loop(void);
|
||||
void cli_entrycheck(void);
|
||||
|
||||
#endif
|
||||
109
src/tests/clock.c
Normal file
109
src/tests/clock.c
Normal file
@ -0,0 +1,109 @@
|
||||
/* ___DISCLAIMER___ */
|
||||
|
||||
/* clock.c: PLL, CCLK, PCLK controls */
|
||||
|
||||
#include <arm/NXP/LPC17xx/LPC17xx.h>
|
||||
#include "clock.h"
|
||||
#include "bits.h"
|
||||
#include "uart.h"
|
||||
|
||||
void clock_disconnect() {
|
||||
disconnectPLL0();
|
||||
disablePLL0();
|
||||
}
|
||||
|
||||
void clock_init() {
|
||||
|
||||
/* set flash access time to 5 clks (80<f<=100MHz) */
|
||||
setFlashAccessTime(5);
|
||||
|
||||
/* setup PLL0 for ~44100*256*8 Hz
|
||||
Base clock: 12MHz
|
||||
Multiplier: 429
|
||||
Pre-Divisor: 19
|
||||
Divisor: 6
|
||||
(want: 90316800, get: 90315789.47)
|
||||
-> DAC freq = 44099.5 Hz
|
||||
-> FPGA freq = 11289473.7Hz
|
||||
First, disable and disconnect PLL0.
|
||||
*/
|
||||
// clock_disconnect();
|
||||
|
||||
/* PLL is disabled and disconnected. setup PCLK NOW as it cannot be changed
|
||||
reliably with PLL0 connected.
|
||||
see:
|
||||
http://ics.nxp.com/support/documents/microcontrollers/pdf/errata.lpc1754.pdf
|
||||
*/
|
||||
|
||||
|
||||
/* continue with PLL0 setup:
|
||||
enable the xtal oscillator and wait for it to become stable
|
||||
set the oscillator as clk source for PLL0
|
||||
set PLL0 multiplier+predivider
|
||||
enable PLL0
|
||||
set CCLK divider
|
||||
wait for PLL0 to lock
|
||||
connect PLL0
|
||||
done
|
||||
*/
|
||||
enableMainOsc();
|
||||
setClkSrc(CLKSRC_MAINOSC);
|
||||
// XXX setPLL0MultPrediv(429, 19);
|
||||
// XXX setPLL0MultPrediv(23, 2);
|
||||
setPLL0MultPrediv(12, 1);
|
||||
enablePLL0();
|
||||
setCCLKDiv(3);
|
||||
connectPLL0();
|
||||
}
|
||||
|
||||
void setFlashAccessTime(uint8_t clocks) {
|
||||
LPC_SC->FLASHCFG=FLASHTIM(clocks);
|
||||
}
|
||||
|
||||
void setPLL0MultPrediv(uint16_t mult, uint8_t prediv) {
|
||||
LPC_SC->PLL0CFG=PLL_MULT(mult) | PLL_PREDIV(prediv);
|
||||
PLL0feed();
|
||||
}
|
||||
|
||||
void enablePLL0() {
|
||||
LPC_SC->PLL0CON |= PLLE0;
|
||||
PLL0feed();
|
||||
}
|
||||
|
||||
void disablePLL0() {
|
||||
LPC_SC->PLL0CON &= ~PLLE0;
|
||||
PLL0feed();
|
||||
}
|
||||
|
||||
void connectPLL0() {
|
||||
while(!(LPC_SC->PLL0STAT&PLOCK0));
|
||||
LPC_SC->PLL0CON |= PLLC0;
|
||||
PLL0feed();
|
||||
}
|
||||
|
||||
void disconnectPLL0() {
|
||||
LPC_SC->PLL0CON &= ~PLLC0;
|
||||
PLL0feed();
|
||||
}
|
||||
|
||||
void setCCLKDiv(uint8_t div) {
|
||||
LPC_SC->CCLKCFG=CCLK_DIV(div);
|
||||
}
|
||||
|
||||
void enableMainOsc() {
|
||||
LPC_SC->SCS=OSCEN;
|
||||
while(!(LPC_SC->SCS&OSCSTAT));
|
||||
}
|
||||
|
||||
void disableMainOsc() {
|
||||
LPC_SC->SCS=0;
|
||||
}
|
||||
|
||||
void PLL0feed() {
|
||||
LPC_SC->PLL0FEED=0xaa;
|
||||
LPC_SC->PLL0FEED=0x55;
|
||||
}
|
||||
|
||||
void setClkSrc(uint8_t src) {
|
||||
LPC_SC->CLKSRCSEL=src;
|
||||
}
|
||||
79
src/tests/clock.h
Normal file
79
src/tests/clock.h
Normal file
@ -0,0 +1,79 @@
|
||||
#ifndef _CLOCK_H
|
||||
#define _CLOCK_H
|
||||
|
||||
#define PLL_MULT(x) ((x-1)&0x7fff)
|
||||
#define PLL_PREDIV(x) (((x-1)<<16)&0xff0000)
|
||||
#define CCLK_DIV(x) ((x-1)&0xff)
|
||||
#define CLKSRC_MAINOSC (1)
|
||||
#define PLLE0 (1<<0)
|
||||
#define PLLC0 (1<<1)
|
||||
#define PLOCK0 (1<<26)
|
||||
#define OSCEN (1<<5)
|
||||
#define OSCSTAT (1<<6)
|
||||
#define FLASHTIM(x) (((x-1)<<12)|0x3A)
|
||||
|
||||
#define PCLK_CCLK(x) (1<<(x))
|
||||
#define PCLK_CCLK4(x) (0)
|
||||
#define PCLK_CCLK8(x) (3<<(x))
|
||||
#define PCLK_CCLK2(x) (2<<(x))
|
||||
|
||||
/* shift values for use with PCLKSEL0 */
|
||||
#define PCLK_WDT (0)
|
||||
#define PCLK_TIMER0 (2)
|
||||
#define PCLK_TIMER1 (4)
|
||||
#define PCLK_UART0 (6)
|
||||
#define PCLK_UART1 (8)
|
||||
#define PCLK_PWM1 (12)
|
||||
#define PCLK_I2C0 (14)
|
||||
#define PCLK_SPI (16)
|
||||
#define PCLK_SSP1 (20)
|
||||
#define PCLK_DAC (22)
|
||||
#define PCLK_ADC (24)
|
||||
#define PCLK_CAN1 (26)
|
||||
#define PCLK_CAN2 (28)
|
||||
#define PCLK_ACF (30)
|
||||
|
||||
/* shift values for use with PCLKSEL1 */
|
||||
#define PCLK_QEI (0)
|
||||
#define PCLK_GPIOINT (2)
|
||||
#define PCLK_PCB (4)
|
||||
#define PCLK_I2C1 (6)
|
||||
#define PCLK_SSP0 (10)
|
||||
#define PCLK_TIMER2 (12)
|
||||
#define PCLK_TIMER3 (14)
|
||||
#define PCLK_UART2 (16)
|
||||
#define PCLK_UART3 (18)
|
||||
#define PCLK_I2C2 (20)
|
||||
#define PCLK_I2S (22)
|
||||
#define PCLK_RIT (26)
|
||||
#define PCLK_SYSCON (28)
|
||||
#define PCLK_MC (30)
|
||||
|
||||
void clock_disconnect(void);
|
||||
|
||||
void clock_init(void);
|
||||
|
||||
void setFlashAccessTime(uint8_t clocks);
|
||||
|
||||
void setPLL0MultPrediv(uint16_t mult, uint8_t prediv);
|
||||
|
||||
void enablePLL0(void);
|
||||
|
||||
void disablePLL0(void);
|
||||
|
||||
void connectPLL0(void);
|
||||
|
||||
void disconnectPLL0(void);
|
||||
|
||||
void setCCLKDiv(uint8_t div);
|
||||
|
||||
void enableMainOsc(void);
|
||||
|
||||
void disableMainOsc(void);
|
||||
|
||||
void PLL0feed(void);
|
||||
|
||||
void setClkSrc(uint8_t src);
|
||||
|
||||
|
||||
#endif
|
||||
29
src/tests/conf2h.awk
Normal file
29
src/tests/conf2h.awk
Normal file
@ -0,0 +1,29 @@
|
||||
#! /usr/bin/gawk -f
|
||||
|
||||
# Trivial little script to convert from a makefile-style configuration
|
||||
# file to a C header. No copyright claimed.
|
||||
|
||||
BEGIN {
|
||||
print "// autoconf.h generated from " ARGV[1] " at " strftime() "\n" \
|
||||
"#ifndef AUTOCONF_H\n" \
|
||||
"#define AUTOCONF_H"
|
||||
}
|
||||
|
||||
/^#/ { sub(/^#/,"//") }
|
||||
|
||||
/^CONFIG_.*=/ {
|
||||
if (/=n$/) {
|
||||
sub(/^/,"// ");
|
||||
} else {
|
||||
sub(/^/,"#define ")
|
||||
if (/=y$/) {
|
||||
sub(/=.*$/,"")
|
||||
} else {
|
||||
sub(/=/," ")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{ print }
|
||||
|
||||
END { print "#endif" }
|
||||
4
src/tests/config
Normal file
4
src/tests/config
Normal file
@ -0,0 +1,4 @@
|
||||
CONFIG_VERSION=0.0.1
|
||||
CONFIG_FWVER=16777214
|
||||
#CONFIG_FWVER=1146310227
|
||||
CONFIG_MCU_FOSC=12000000
|
||||
97
src/tests/config.h
Normal file
97
src/tests/config.h
Normal file
@ -0,0 +1,97 @@
|
||||
#ifndef _CONFIG_H
|
||||
#define _CONFIG_H
|
||||
|
||||
// #define DEBUG_FS
|
||||
// #define DEBUG_SD
|
||||
// #define DEBUG_IRQ
|
||||
// #define DEBUG_MSU1
|
||||
|
||||
#define VER "0.0.1(NSFW)"
|
||||
#define IN_AHBRAM __attribute__ ((section(".ahbram")))
|
||||
|
||||
#define SD_DT_INT_SETUP() do {\
|
||||
BITBAND(LPC_GPIOINT->IO2IntEnR, SD_DT_BIT) = 1;\
|
||||
BITBAND(LPC_GPIOINT->IO2IntEnF, SD_DT_BIT) = 1;\
|
||||
} while(0)
|
||||
|
||||
#define SD_CHANGE_DETECT (BITBAND(LPC_GPIOINT->IO2IntStatR, SD_DT_BIT)\
|
||||
|BITBAND(LPC_GPIOINT->IO2IntStatF, SD_DT_BIT))
|
||||
|
||||
#define SD_CHANGE_CLR() do {LPC_GPIOINT->IO2IntClr = BV(SD_DT_BIT);} while(0)
|
||||
|
||||
#define SD_DT_REG LPC_GPIO0
|
||||
#define SD_DT_BIT 8
|
||||
#define SD_WP_REG LPC_GPIO0
|
||||
#define SD_WP_BIT 6
|
||||
|
||||
#define SDCARD_DETECT (!(BITBAND(SD_DT_REG->FIOPIN, SD_DT_BIT)))
|
||||
#define SDCARD_WP (BITBAND(SD_WP_REG->FIOPIN, SD_WP_BIT))
|
||||
#define SD_SUPPLY_VOLTAGE (1L<<21) /* 3.3V - 3.4V */
|
||||
#define CONFIG_SD_BLOCKTRANSFER 1
|
||||
#define CONFIG_SD_AUTO_RETRIES 10
|
||||
// #define SD_CHANGE_VECT
|
||||
// #define CONFIG_SD_DATACRC 1
|
||||
|
||||
#define CONFIG_UART_NUM 3
|
||||
// #define CONFIG_CPU_FREQUENCY 90315789
|
||||
#define CONFIG_CPU_FREQUENCY 96000000
|
||||
//#define CONFIG_CPU_FREQUENCY 46000000
|
||||
#define CONFIG_UART_PCLKDIV 1
|
||||
#define CONFIG_UART_TX_BUF_SHIFT 8
|
||||
#define CONFIG_UART_BAUDRATE 921600
|
||||
#define CONFIG_UART_DEADLOCKABLE
|
||||
|
||||
#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_BIT 26
|
||||
|
||||
#define SNES_CIC_D0_REG LPC_GPIO0
|
||||
#define SNES_CIC_D0_BIT 1
|
||||
|
||||
#define SNES_CIC_D1_REG LPC_GPIO0
|
||||
#define SNES_CIC_D1_BIT 0
|
||||
|
||||
#define SNES_CIC_STATUS_REG LPC_GPIO1
|
||||
#define SNES_CIC_STATUS_BIT 29
|
||||
|
||||
#define SNES_CIC_PAIR_REG LPC_GPIO1
|
||||
#define SNES_CIC_PAIR_BIT 25
|
||||
|
||||
#define FPGA_MCU_RDY_REG LPC_GPIO2
|
||||
#define FPGA_MCU_RDY_BIT 9
|
||||
|
||||
#define QSORT_MAXELEM 2048
|
||||
|
||||
#define SSP_REGS LPC_SSP0
|
||||
#define SSP_PCLKREG PCLKSEL1
|
||||
// 1: PCLKSEL0
|
||||
#define SSP_PCLKBIT 10
|
||||
// 1: 20
|
||||
#define SSP_DMAID_TX 0
|
||||
// 1: 2
|
||||
#define SSP_DMAID_RX 1
|
||||
// 1: 3
|
||||
#define SSP_DMACH LPC_GPDMACH0
|
||||
|
||||
#define SD_CLKREG LPC_GPIO0
|
||||
#define SD_CMDREG LPC_GPIO0
|
||||
#define SD_DAT0REG LPC_GPIO2
|
||||
#define SD_DAT1REG LPC_GPIO2
|
||||
#define SD_DAT2REG LPC_GPIO2
|
||||
#define SD_DAT3REG LPC_GPIO2
|
||||
|
||||
#define SD_CLKPIN (7)
|
||||
#define SD_CMDPIN (9)
|
||||
#define SD_DAT0PIN (0)
|
||||
#define SD_DAT1PIN (1)
|
||||
#define SD_DAT2PIN (2)
|
||||
#define SD_DAT3PIN (3)
|
||||
|
||||
#define SD_DAT (LPC_GPIO2->FIOPIN0)
|
||||
|
||||
#endif
|
||||
92
src/tests/crc.S
Normal file
92
src/tests/crc.S
Normal file
@ -0,0 +1,92 @@
|
||||
/* CRC-7/CRC-16 (XModem) implementation for Cortex M3
|
||||
*
|
||||
* Written 2010 by Ingo Korb
|
||||
*/
|
||||
|
||||
.syntax unified
|
||||
.section .text
|
||||
|
||||
/* uint8_t crc7update(uint8_t crc, const uint8_t data) */
|
||||
.global crc7update
|
||||
.thumb_func
|
||||
crc7update:
|
||||
mov r2, #8 // number of bits to process
|
||||
lsl r1, r1, #24 // pre-shift data byte to top of word
|
||||
|
||||
loop:
|
||||
lsl r0, r0, #1 // shift CRC
|
||||
lsls r1, r1, #1 // shift data byte (highest bit now in C)
|
||||
bcc 0f // jump if bit was 0
|
||||
eor r0, r0, #0x80 // invert top bit of CRC if not
|
||||
0: tst r0, #0x80 // test top bit of CRC
|
||||
beq 1f // skip if top bit is clear
|
||||
eor r0, r0, #0x09 // apply polinomial
|
||||
1: subs r2, r2, #1 // decrememt bit cointer
|
||||
bne loop // loop for next bit
|
||||
uxtb r0, r0 // clear top bits of result
|
||||
bx lr // return
|
||||
|
||||
|
||||
/* uint16_t crc_xmodem_block(uint16_t crc, uint8_t *data, uint32_t len) */
|
||||
.global crc_xmodem_block
|
||||
.thumb_func
|
||||
crc_xmodem_block:
|
||||
adr r12, crc_table // load address of crc table
|
||||
blockloop:
|
||||
ldrb.w r3, [r1], #1 // read data byte
|
||||
eor r3, r3, r0, lsr #8 // EOR data byte
|
||||
ldrh r3, [r12, r3, lsl #1] // load value from CRC table
|
||||
eor r0, r3, r0, lsl #8 // update CRC
|
||||
uxth r0, r0 // clear top bits of result
|
||||
subs r2, r2, #1 // decrement length
|
||||
bne blockloop // loop while length > 0
|
||||
bx lr // return
|
||||
|
||||
/* uint16_t crc_xmodem_block(uint16_t crc, uint8_t *data, uint32_t len) */
|
||||
.global crc_xmodem_update
|
||||
.thumb_func
|
||||
crc_xmodem_update:
|
||||
adr r2, crc_table // load address of crc table
|
||||
eor r1, r1, r0, lsr #8 // EOR data byte
|
||||
ldrh r3, [r2, r1, lsl #1] // load value from CRC table
|
||||
eor r0, r3, r0, lsl #8 // update CRC
|
||||
uxth r0, r0 // clear top bits of result
|
||||
bx lr // return
|
||||
|
||||
|
||||
crc_table:
|
||||
.short 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7
|
||||
.short 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef
|
||||
.short 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6
|
||||
.short 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de
|
||||
.short 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485
|
||||
.short 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d
|
||||
.short 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4
|
||||
.short 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc
|
||||
.short 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823
|
||||
.short 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b
|
||||
.short 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12
|
||||
.short 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a
|
||||
.short 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41
|
||||
.short 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49
|
||||
.short 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70
|
||||
.short 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78
|
||||
.short 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f
|
||||
.short 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067
|
||||
.short 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e
|
||||
.short 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256
|
||||
.short 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d
|
||||
.short 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405
|
||||
.short 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c
|
||||
.short 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634
|
||||
.short 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab
|
||||
.short 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3
|
||||
.short 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a
|
||||
.short 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92
|
||||
.short 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9
|
||||
.short 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1
|
||||
.short 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8
|
||||
.short 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
|
||||
|
||||
|
||||
.end
|
||||
11
src/tests/crc.h
Normal file
11
src/tests/crc.h
Normal file
@ -0,0 +1,11 @@
|
||||
#ifndef CRC_H
|
||||
#define CRC_H
|
||||
|
||||
uint8_t crc7update(uint8_t crc, uint8_t data);
|
||||
uint16_t crc_xmodem_update(uint16_t crc, uint8_t data);
|
||||
uint16_t crc_xmodem_block(uint16_t crc, const uint8_t *data, uint32_t length);
|
||||
|
||||
// AVR-libc compatibility
|
||||
#define _crc_xmodem_update(crc,data) crc_xmodem_update(crc,data)
|
||||
|
||||
#endif
|
||||
110
src/tests/crc32.c
Normal file
110
src/tests/crc32.c
Normal file
@ -0,0 +1,110 @@
|
||||
/**
|
||||
* \file crc32.c
|
||||
* Functions and types for CRC checks.
|
||||
*
|
||||
* Generated on Sat Sep 25 18:06:34 2010,
|
||||
* by pycrc v0.7.1, http://www.tty1.net/pycrc/
|
||||
* using the configuration:
|
||||
* Width = 32
|
||||
* Poly = 0x04c11db7
|
||||
* XorIn = 0xffffffff
|
||||
* ReflectIn = True
|
||||
* XorOut = 0xffffffff
|
||||
* ReflectOut = True
|
||||
* Algorithm = table-driven
|
||||
* Direct = True
|
||||
*****************************************************************************/
|
||||
#include "crc32.h"
|
||||
#include "config.h"
|
||||
#include <arm/NXP/LPC17xx/LPC17xx.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/**
|
||||
* Static table used for the table_driven implementation.
|
||||
*****************************************************************************/
|
||||
static const uint32_t crc32_table[256] = {
|
||||
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
|
||||
0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
|
||||
0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
|
||||
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
|
||||
0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
|
||||
0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
|
||||
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
|
||||
0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
|
||||
0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
|
||||
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
|
||||
0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
|
||||
0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
|
||||
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
|
||||
0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
|
||||
0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
|
||||
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
|
||||
0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
|
||||
0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
|
||||
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
|
||||
0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
|
||||
0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
|
||||
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
|
||||
0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
|
||||
0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
|
||||
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
|
||||
0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
|
||||
0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
|
||||
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
|
||||
0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
|
||||
0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
|
||||
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
|
||||
0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
|
||||
0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
|
||||
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
|
||||
0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
|
||||
0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
|
||||
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
|
||||
0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
|
||||
0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
|
||||
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
|
||||
0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
|
||||
0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
|
||||
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
|
||||
0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
|
||||
0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
|
||||
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
|
||||
0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
|
||||
0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
|
||||
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
|
||||
0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
|
||||
0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
|
||||
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
|
||||
0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
|
||||
0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
|
||||
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
|
||||
0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
|
||||
0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
|
||||
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
|
||||
0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
|
||||
0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
|
||||
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
|
||||
0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
|
||||
0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
|
||||
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
|
||||
};
|
||||
|
||||
/**
|
||||
* Update the crc value with new data.
|
||||
*
|
||||
* \param crc The current crc value.
|
||||
* \param data Pointer to a buffer of \a data_len bytes.
|
||||
* \param data_len Number of bytes in the \a data buffer.
|
||||
* \return The updated crc value.
|
||||
*****************************************************************************/
|
||||
uint32_t crc32_update(uint32_t crc, const unsigned char data)
|
||||
{
|
||||
unsigned int tbl_idx;
|
||||
|
||||
tbl_idx = (crc ^ data) & 0xff;
|
||||
crc = (crc32_table[tbl_idx] ^ (crc >> 8)) & 0xffffffff;
|
||||
|
||||
return crc & 0xffffffff;
|
||||
}
|
||||
|
||||
|
||||
68
src/tests/crc32.h
Normal file
68
src/tests/crc32.h
Normal file
@ -0,0 +1,68 @@
|
||||
/**
|
||||
* \file crc32.h
|
||||
* Functions and types for CRC checks.
|
||||
*
|
||||
* Generated on Sat Sep 25 18:06:37 2010,
|
||||
* by pycrc v0.7.1, http://www.tty1.net/pycrc/
|
||||
* using the configuration:
|
||||
* Width = 32
|
||||
* Poly = 0x04c11db7
|
||||
* XorIn = 0xffffffff
|
||||
* ReflectIn = True
|
||||
* XorOut = 0xffffffff
|
||||
* ReflectOut = True
|
||||
* Algorithm = table-driven
|
||||
* Direct = True
|
||||
*****************************************************************************/
|
||||
#ifndef __CRC___H__
|
||||
#define __CRC___H__
|
||||
|
||||
#include <arm/NXP/LPC17xx/LPC17xx.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The definition of the used algorithm.
|
||||
*****************************************************************************/
|
||||
#define CRC_ALGO_TABLE_DRIVEN 1
|
||||
|
||||
/**
|
||||
* Calculate the initial crc value.
|
||||
*
|
||||
* \return The initial crc value.
|
||||
*****************************************************************************/
|
||||
static inline uint32_t crc_init(void)
|
||||
{
|
||||
return 0xffffffff;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the crc value with new data.
|
||||
*
|
||||
* \param crc The current crc value.
|
||||
* \param data Pointer to a buffer of \a data_len bytes.
|
||||
* \param data_len Number of bytes in the \a data buffer.
|
||||
* \return The updated crc value.
|
||||
*****************************************************************************/
|
||||
uint32_t crc32_update(uint32_t crc, const unsigned char data);
|
||||
|
||||
/**
|
||||
* Calculate the final crc value.
|
||||
*
|
||||
* \param crc The current crc value.
|
||||
* \return The final crc value.
|
||||
*****************************************************************************/
|
||||
static inline uint32_t crc32_finalize(uint32_t crc)
|
||||
{
|
||||
return crc ^ 0xffffffff;
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* closing brace for extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* __CRC___H__ */
|
||||
118
src/tests/diskio.h
Normal file
118
src/tests/diskio.h
Normal file
@ -0,0 +1,118 @@
|
||||
/*-----------------------------------------------------------------------
|
||||
/ Low level disk interface modlue include file (C)ChaN, 2010
|
||||
/-----------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _DISKIO
|
||||
|
||||
#define _READONLY 0 /* 1: Remove write functions */
|
||||
#define _USE_IOCTL 1 /* 1: Use disk_ioctl fucntion */
|
||||
|
||||
#include <arm/NXP/LPC17xx/LPC17xx.h>
|
||||
|
||||
#include "integer.h"
|
||||
|
||||
|
||||
/* Status of Disk Functions */
|
||||
typedef BYTE DSTATUS;
|
||||
|
||||
/* Results of Disk Functions */
|
||||
typedef enum {
|
||||
RES_OK = 0, /* 0: Successful */
|
||||
RES_ERROR, /* 1: R/W Error */
|
||||
RES_WRPRT, /* 2: Write Protected */
|
||||
RES_NOTRDY, /* 3: Not Ready */
|
||||
RES_PARERR /* 4: Invalid Parameter */
|
||||
} DRESULT;
|
||||
|
||||
/**
|
||||
* struct diskinfo0_t - disk info data structure for page 0
|
||||
* @validbytes : Number of valid bytes in this struct
|
||||
* @maxpage : Highest diskinfo page supported
|
||||
* @disktype : type of the disk (DISK_TYPE_* values)
|
||||
* @sectorsize : sector size divided by 256
|
||||
* @sectorcount: number of sectors on the disk
|
||||
*
|
||||
* This is the struct returned in the data buffer when disk_getinfo
|
||||
* is called with page=0.
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t validbytes;
|
||||
uint8_t maxpage;
|
||||
uint8_t disktype;
|
||||
uint8_t sectorsize; /* divided by 256 */
|
||||
uint32_t sectorcount; /* 2 TB should be enough... (512 byte sectors) */
|
||||
} diskinfo0_t;
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------*/
|
||||
/* Prototypes for disk control functions */
|
||||
|
||||
int assign_drives (int, int);
|
||||
DSTATUS disk_initialize (BYTE);
|
||||
DSTATUS disk_status (BYTE);
|
||||
DRESULT disk_read (BYTE, BYTE*, DWORD, BYTE);
|
||||
#if _READONLY == 0
|
||||
DRESULT disk_write (BYTE, const BYTE*, DWORD, BYTE);
|
||||
#endif
|
||||
#define disk_ioctl(a,b,c) RES_OK
|
||||
|
||||
void disk_init(void);
|
||||
|
||||
/* Will be set to DISK_ERROR if any access on the card fails */
|
||||
enum diskstates { DISK_CHANGED = 0, DISK_REMOVED, DISK_OK, DISK_ERROR };
|
||||
|
||||
extern int sd_offload, ff_sd_offload, sd_offload_tgt, newcard;
|
||||
extern int sd_offload_partial;
|
||||
extern uint16_t sd_offload_partial_start;
|
||||
extern uint16_t sd_offload_partial_end;
|
||||
extern volatile enum diskstates disk_state;
|
||||
|
||||
/* Disk type - part of the external API except for ATA2! */
|
||||
#define DISK_TYPE_ATA 0
|
||||
#define DISK_TYPE_ATA2 1
|
||||
#define DISK_TYPE_SD 2
|
||||
#define DISK_TYPE_DF 3
|
||||
#define DISK_TYPE_NONE 7
|
||||
|
||||
|
||||
|
||||
/* Disk Status Bits (DSTATUS) */
|
||||
|
||||
#define STA_NOINIT 0x01 /* Drive not initialized */
|
||||
#define STA_NODISK 0x02 /* No medium in the drive */
|
||||
#define STA_PROTECT 0x04 /* Write protected */
|
||||
|
||||
|
||||
/* Command code for disk_ioctrl fucntion */
|
||||
|
||||
/* Generic command (defined for FatFs) */
|
||||
#define CTRL_SYNC 0 /* Flush disk cache (for write functions) */
|
||||
#define GET_SECTOR_COUNT 1 /* Get media size (for only f_mkfs()) */
|
||||
#define GET_SECTOR_SIZE 2 /* Get sector size (for multiple sector size (_MAX_SS >= 1024)) */
|
||||
#define GET_BLOCK_SIZE 3 /* Get erase block size (for only f_mkfs()) */
|
||||
#define CTRL_ERASE_SECTOR 4 /* Force erased a block of sectors (for only _USE_ERASE) */
|
||||
|
||||
/* Generic command */
|
||||
#define CTRL_POWER 5 /* Get/Set power status */
|
||||
#define CTRL_LOCK 6 /* Lock/Unlock media removal */
|
||||
#define CTRL_EJECT 7 /* Eject media */
|
||||
|
||||
/* MMC/SDC specific ioctl command */
|
||||
#define MMC_GET_TYPE 10 /* Get card type */
|
||||
#define MMC_GET_CSD 11 /* Get CSD */
|
||||
#define MMC_GET_CID 12 /* Get CID */
|
||||
#define MMC_GET_OCR 13 /* Get OCR */
|
||||
#define MMC_GET_SDSTAT 14 /* Get SD status */
|
||||
|
||||
/* ATA/CF specific ioctl command */
|
||||
#define ATA_GET_REV 20 /* Get F/W revision */
|
||||
#define ATA_GET_MODEL 21 /* Get model name */
|
||||
#define ATA_GET_SN 22 /* Get serial number */
|
||||
|
||||
/* NAND specific ioctl command */
|
||||
#define NAND_FORMAT 30 /* Create physical format */
|
||||
|
||||
|
||||
#define _DISKIO
|
||||
#endif
|
||||
20
src/tests/faulthandler.c
Normal file
20
src/tests/faulthandler.c
Normal file
@ -0,0 +1,20 @@
|
||||
#include <arm/NXP/LPC17xx/LPC17xx.h>
|
||||
#include "uart.h"
|
||||
|
||||
void HardFault_Handler(void) {
|
||||
printf("HFSR: %lx\n", SCB->HFSR);
|
||||
while (1) ;
|
||||
}
|
||||
|
||||
void MemManage_Handler(void) {
|
||||
printf("MemManage - CFSR: %lx; MMFAR: %lx\n", SCB->CFSR, SCB->MMFAR);
|
||||
}
|
||||
|
||||
void BusFault_Handler(void) {
|
||||
printf("BusFault - CFSR: %lx; BFAR: %lx\n", SCB->CFSR, SCB->BFAR);
|
||||
}
|
||||
|
||||
void UsageFault_Handler(void) {
|
||||
printf("UsageFault - CFSR: %lx; BFAR: %lx\n", SCB->CFSR, SCB->BFAR);
|
||||
}
|
||||
|
||||
3805
src/tests/ff.c
Normal file
3805
src/tests/ff.c
Normal file
File diff suppressed because it is too large
Load Diff
547
src/tests/ff.h
Normal file
547
src/tests/ff.h
Normal file
@ -0,0 +1,547 @@
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ FatFs - FAT file system module include file R0.08a (C)ChaN, 2010
|
||||
/----------------------------------------------------------------------------/
|
||||
/ FatFs module is a generic FAT file system module for small embedded systems.
|
||||
/ This is a free software that opened for education, research and commercial
|
||||
/ developments under license policy of following trems.
|
||||
/
|
||||
/ Copyright (C) 2010, ChaN, all right reserved.
|
||||
/
|
||||
/ * The FatFs module is a free software and there is NO WARRANTY.
|
||||
/ * No restriction on use. You can use, modify and redistribute it for
|
||||
/ personal, non-profit or commercial product UNDER YOUR RESPONSIBILITY.
|
||||
/ * Redistributions of source code must retain the above copyright notice.
|
||||
/
|
||||
/----------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _FATFS
|
||||
#define _FATFS 8255 /* Revision ID */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "integer.h" /* Basic integer types */
|
||||
#include "ffconf.h" /* FatFs configuration options */
|
||||
|
||||
#if _FATFS != _FFCONF
|
||||
#error Wrong configuration file (ffconf.h).
|
||||
#endif
|
||||
|
||||
|
||||
/* DBCS code ranges and SBCS extend char conversion table */
|
||||
|
||||
#if _CODE_PAGE == 932 /* Japanese Shift-JIS */
|
||||
#define _DF1S 0x81 /* DBC 1st byte range 1 start */
|
||||
#define _DF1E 0x9F /* DBC 1st byte range 1 end */
|
||||
#define _DF2S 0xE0 /* DBC 1st byte range 2 start */
|
||||
#define _DF2E 0xFC /* DBC 1st byte range 2 end */
|
||||
#define _DS1S 0x40 /* DBC 2nd byte range 1 start */
|
||||
#define _DS1E 0x7E /* DBC 2nd byte range 1 end */
|
||||
#define _DS2S 0x80 /* DBC 2nd byte range 2 start */
|
||||
#define _DS2E 0xFC /* DBC 2nd byte range 2 end */
|
||||
|
||||
#elif _CODE_PAGE == 936 /* Simplified Chinese GBK */
|
||||
#define _DF1S 0x81
|
||||
#define _DF1E 0xFE
|
||||
#define _DS1S 0x40
|
||||
#define _DS1E 0x7E
|
||||
#define _DS2S 0x80
|
||||
#define _DS2E 0xFE
|
||||
|
||||
#elif _CODE_PAGE == 949 /* Korean */
|
||||
#define _DF1S 0x81
|
||||
#define _DF1E 0xFE
|
||||
#define _DS1S 0x41
|
||||
#define _DS1E 0x5A
|
||||
#define _DS2S 0x61
|
||||
#define _DS2E 0x7A
|
||||
#define _DS3S 0x81
|
||||
#define _DS3E 0xFE
|
||||
|
||||
#elif _CODE_PAGE == 950 /* Traditional Chinese Big5 */
|
||||
#define _DF1S 0x81
|
||||
#define _DF1E 0xFE
|
||||
#define _DS1S 0x40
|
||||
#define _DS1E 0x7E
|
||||
#define _DS2S 0xA1
|
||||
#define _DS2E 0xFE
|
||||
|
||||
#elif _CODE_PAGE == 437 /* U.S. (OEM) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x9A,0x90,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x49,0x49,0x49,0x8E,0x8F,0x90,0x92,0x92,0x4F,0x99,0x4F,0x55,0x55,0x59,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
|
||||
0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 720 /* Arabic (OEM) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x81,0x45,0x41,0x84,0x41,0x86,0x43,0x45,0x45,0x45,0x49,0x49,0x8D,0x8E,0x8F,0x90,0x92,0x92,0x93,0x94,0x95,0x49,0x49,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
|
||||
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 737 /* Greek (OEM) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x92,0x92,0x93,0x94,0x95,0x96,0x97,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87, \
|
||||
0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0xAA,0x92,0x93,0x94,0x95,0x96,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0x97,0xEA,0xEB,0xEC,0xE4,0xED,0xEE,0xE7,0xE8,0xF1,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 775 /* Baltic (OEM) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x9A,0x91,0xA0,0x8E,0x95,0x8F,0x80,0xAD,0xED,0x8A,0x8A,0xA1,0x8D,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0x95,0x96,0x97,0x97,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \
|
||||
0xA0,0xA1,0xE0,0xA3,0xA3,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xB5,0xB6,0xB7,0xB8,0xBD,0xBE,0xC6,0xC7,0xA5,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE3,0xE8,0xE8,0xEA,0xEA,0xEE,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 850 /* Multilingual Latin 1 (OEM) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0xDE,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x59,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \
|
||||
0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE7,0xE9,0xEA,0xEB,0xED,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 852 /* Latin 2 (OEM) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xDE,0x8F,0x80,0x9D,0xD3,0x8A,0x8A,0xD7,0x8D,0x8E,0x8F,0x90,0x91,0x91,0xE2,0x99,0x95,0x95,0x97,0x97,0x99,0x9A,0x9B,0x9B,0x9D,0x9E,0x9F, \
|
||||
0xB5,0xD6,0xE0,0xE9,0xA4,0xA4,0xA6,0xA6,0xA8,0xA8,0xAA,0x8D,0xAC,0xB8,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBD,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC6,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD2,0xD3,0xD2,0xD5,0xD6,0xD7,0xB7,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xE0,0xE1,0xE2,0xE3,0xE3,0xD5,0xE6,0xE6,0xE8,0xE9,0xE8,0xEB,0xED,0xED,0xDD,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xEB,0xFC,0xFC,0xFE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 855 /* Cyrillic (OEM) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x81,0x81,0x83,0x83,0x85,0x85,0x87,0x87,0x89,0x89,0x8B,0x8B,0x8D,0x8D,0x8F,0x8F,0x91,0x91,0x93,0x93,0x95,0x95,0x97,0x97,0x99,0x99,0x9B,0x9B,0x9D,0x9D,0x9F,0x9F, \
|
||||
0xA1,0xA1,0xA3,0xA3,0xA5,0xA5,0xA7,0xA7,0xA9,0xA9,0xAB,0xAB,0xAD,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB6,0xB6,0xB8,0xB8,0xB9,0xBA,0xBB,0xBC,0xBE,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD3,0xD3,0xD5,0xD5,0xD7,0xD7,0xDD,0xD9,0xDA,0xDB,0xDC,0xDD,0xE0,0xDF, \
|
||||
0xE0,0xE2,0xE2,0xE4,0xE4,0xE6,0xE6,0xE8,0xE8,0xEA,0xEA,0xEC,0xEC,0xEE,0xEE,0xEF,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF8,0xFA,0xFA,0xFC,0xFC,0xFD,0xFE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 857 /* Turkish (OEM) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0x98,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x98,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9E, \
|
||||
0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA6,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xDE,0x59,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 858 /* Multilingual Latin 1 + Euro (OEM) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0xDE,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x59,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \
|
||||
0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE7,0xE9,0xEA,0xEB,0xED,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 862 /* Hebrew (OEM) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
|
||||
0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 866 /* Russian (OEM) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
|
||||
0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0x90,0x91,0x92,0x93,0x9d,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,0xF0,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 874 /* Thai (OEM, Windows) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
|
||||
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 1250 /* Central Europe (Windows) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x8D,0x8E,0x8F, \
|
||||
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xA3,0xB4,0xB5,0xB6,0xB7,0xB8,0xA5,0xAA,0xBB,0xBC,0xBD,0xBC,0xAF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 1251 /* Cyrillic (Windows) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x81,0x82,0x82,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x80,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x8D,0x8E,0x8F, \
|
||||
0xA0,0xA2,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB2,0xA5,0xB5,0xB6,0xB7,0xA8,0xB9,0xAA,0xBB,0xA3,0xBD,0xBD,0xAF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF}
|
||||
|
||||
#elif _CODE_PAGE == 1252 /* Latin 1 (Windows) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0xAd,0x9B,0x8C,0x9D,0xAE,0x9F, \
|
||||
0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x9F}
|
||||
|
||||
#elif _CODE_PAGE == 1253 /* Greek (Windows) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
|
||||
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xA2,0xB8,0xB9,0xBA, \
|
||||
0xE0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xF2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xFB,0xBC,0xFD,0xBF,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 1254 /* Turkish (Windows) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x9D,0x9E,0x9F, \
|
||||
0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x9F}
|
||||
|
||||
#elif _CODE_PAGE == 1255 /* Hebrew (Windows) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
|
||||
0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 1256 /* Arabic (Windows) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x8C,0x9D,0x9E,0x9F, \
|
||||
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0x41,0xE1,0x41,0xE3,0xE4,0xE5,0xE6,0x43,0x45,0x45,0x45,0x45,0xEC,0xED,0x49,0x49,0xF0,0xF1,0xF2,0xF3,0x4F,0xF5,0xF6,0xF7,0xF8,0x55,0xFA,0x55,0x55,0xFD,0xFE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 1257 /* Baltic (Windows) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
|
||||
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xA8,0xB9,0xAA,0xBB,0xBC,0xBD,0xBE,0xAF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 1258 /* Vietnam (OEM, Windows) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0xAC,0x9D,0x9E,0x9F, \
|
||||
0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xEC,0xCD,0xCE,0xCF,0xD0,0xD1,0xF2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xFE,0x9F}
|
||||
|
||||
#elif _CODE_PAGE == 1 /* ASCII (for only non-LFN cfg) */
|
||||
#define _DF1S 0
|
||||
|
||||
#else
|
||||
#error Unknown code page
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Definitions of volume management */
|
||||
|
||||
#if _MULTI_PARTITION /* Multiple partition configuration */
|
||||
#define LD2PD(vol) (VolToPart[vol].pd) /* Get physical drive# */
|
||||
#define LD2PT(vol) (VolToPart[vol].pt) /* Get partition# */
|
||||
typedef struct {
|
||||
BYTE pd; /* Physical drive# */
|
||||
BYTE pt; /* Partition # (0-3) */
|
||||
} PARTITION;
|
||||
extern const PARTITION VolToPart[]; /* Volume - Physical location resolution table */
|
||||
|
||||
#else /* Single partition configuration */
|
||||
#define LD2PD(vol) (vol) /* Logical drive# is bound to the same physical drive# */
|
||||
#define LD2PT(vol) 0 /* Always mounts the 1st partition */
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Type of path name strings on FatFs API */
|
||||
|
||||
#if _LFN_UNICODE /* Unicode string */
|
||||
#if !_USE_LFN
|
||||
#error _LFN_UNICODE must be 0 in non-LFN cfg.
|
||||
#endif
|
||||
#ifndef _INC_TCHAR
|
||||
typedef WCHAR TCHAR;
|
||||
#define _T(x) L ## x
|
||||
#define _TEXT(x) L ## x
|
||||
#endif
|
||||
|
||||
#else /* ANSI/OEM string */
|
||||
#ifndef _INC_TCHAR
|
||||
typedef char TCHAR;
|
||||
#define _T(x) x
|
||||
#define _TEXT(x) x
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* File system object structure (FATFS) */
|
||||
|
||||
typedef struct {
|
||||
BYTE fs_type; /* FAT sub-type (0:Not mounted) */
|
||||
BYTE drv; /* Physical drive number */
|
||||
BYTE csize; /* Sectors per cluster (1,2,4...128) */
|
||||
BYTE n_fats; /* Number of FAT copies (1,2) */
|
||||
BYTE wflag; /* win[] dirty flag (1:must be written back) */
|
||||
BYTE fsi_flag; /* fsinfo dirty flag (1:must be written back) */
|
||||
WORD id; /* File system mount ID */
|
||||
WORD n_rootdir; /* Number of root directory entries (FAT12/16) */
|
||||
#if _MAX_SS != 512
|
||||
WORD ssize; /* Bytes per sector (512,1024,2048,4096) */
|
||||
#endif
|
||||
#if _FS_REENTRANT
|
||||
_SYNC_t sobj; /* Identifier of sync object */
|
||||
#endif
|
||||
#if !_FS_READONLY
|
||||
DWORD last_clust; /* Last allocated cluster */
|
||||
DWORD free_clust; /* Number of free clusters */
|
||||
DWORD fsi_sector; /* fsinfo sector (FAT32) */
|
||||
#endif
|
||||
#if _FS_RPATH
|
||||
DWORD cdir; /* Current directory start cluster (0:root) */
|
||||
#endif
|
||||
DWORD n_fatent; /* Number of FAT entries (= number of clusters + 2) */
|
||||
DWORD fsize; /* Sectors per FAT */
|
||||
DWORD fatbase; /* FAT start sector */
|
||||
DWORD dirbase; /* Root directory start sector (FAT32:Cluster#) */
|
||||
DWORD database; /* Data start sector */
|
||||
DWORD winsect; /* Current sector appearing in the win[] */
|
||||
BYTE win[_MAX_SS]; /* Disk access window for Directory, FAT (and Data on tiny cfg) */
|
||||
} FATFS;
|
||||
|
||||
|
||||
|
||||
/* File object structure (FIL) */
|
||||
|
||||
typedef struct {
|
||||
FATFS* fs; /* Pointer to the owner file system object */
|
||||
WORD id; /* Owner file system mount ID */
|
||||
BYTE flag; /* File status flags */
|
||||
BYTE pad1;
|
||||
DWORD fptr; /* File read/write pointer (0 on file open) */
|
||||
DWORD fsize; /* File size */
|
||||
DWORD org_clust; /* File start cluster (0 when fsize==0) */
|
||||
DWORD curr_clust; /* Current cluster */
|
||||
DWORD dsect; /* Current data sector */
|
||||
#if !_FS_READONLY
|
||||
DWORD dir_sect; /* Sector containing the directory entry */
|
||||
BYTE* dir_ptr; /* Ponter to the directory entry in the window */
|
||||
#endif
|
||||
#if _USE_FASTSEEK
|
||||
DWORD* cltbl; /* Pointer to the cluster link map table (null on file open) */
|
||||
#endif
|
||||
#if _FS_SHARE
|
||||
UINT lockid; /* File lock ID (index of file semaphore table) */
|
||||
#endif
|
||||
#if !_FS_TINY
|
||||
BYTE buf[_MAX_SS]; /* File data read/write buffer */
|
||||
#endif
|
||||
} FIL;
|
||||
|
||||
|
||||
|
||||
/* Directory object structure (DIR) */
|
||||
|
||||
typedef struct {
|
||||
FATFS* fs; /* Pointer to the owner file system object */
|
||||
WORD id; /* Owner file system mount ID */
|
||||
WORD index; /* Current read/write index number */
|
||||
DWORD sclust; /* Table start cluster (0:Root dir) */
|
||||
DWORD clust; /* Current cluster */
|
||||
DWORD sect; /* Current sector */
|
||||
BYTE* dir; /* Pointer to the current SFN entry in the win[] */
|
||||
BYTE* fn; /* Pointer to the SFN (in/out) {file[8],ext[3],status[1]} */
|
||||
#if _USE_LFN
|
||||
WCHAR* lfn; /* Pointer to the LFN working buffer */
|
||||
WORD lfn_idx; /* Last matched LFN index number (0xFFFF:No LFN) */
|
||||
#endif
|
||||
} DIR;
|
||||
|
||||
|
||||
|
||||
/* File status structure (FILINFO) */
|
||||
|
||||
typedef struct {
|
||||
DWORD fsize; /* File size */
|
||||
WORD fdate; /* Last modified date */
|
||||
WORD ftime; /* Last modified time */
|
||||
BYTE fattrib; /* Attribute */
|
||||
TCHAR fname[13]; /* Short file name (8.3 format) */
|
||||
DWORD clust; /* start cluster */
|
||||
#if _USE_LFN
|
||||
TCHAR* lfname; /* Pointer to the LFN buffer */
|
||||
UINT lfsize; /* Size of LFN buffer in TCHAR */
|
||||
#endif
|
||||
} FILINFO;
|
||||
|
||||
|
||||
|
||||
/* File function return code (FRESULT) */
|
||||
|
||||
typedef enum {
|
||||
FR_OK = 0, /* (0) Succeeded */
|
||||
FR_DISK_ERR, /* (1) A hard error occured in the low level disk I/O layer */
|
||||
FR_INT_ERR, /* (2) Assertion failed */
|
||||
FR_NOT_READY, /* (3) The physical drive cannot work */
|
||||
FR_NO_FILE, /* (4) Could not find the file */
|
||||
FR_NO_PATH, /* (5) Could not find the path */
|
||||
FR_INVALID_NAME, /* (6) The path name format is invalid */
|
||||
FR_DENIED, /* (7) Acces denied due to prohibited access or directory full */
|
||||
FR_EXIST, /* (8) Acces denied due to prohibited access */
|
||||
FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */
|
||||
FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */
|
||||
FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */
|
||||
FR_NOT_ENABLED, /* (12) The volume has no work area */
|
||||
FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume on the physical drive */
|
||||
FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any parameter error */
|
||||
FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */
|
||||
FR_LOCKED, /* (16) The operation is rejected according to the file shareing policy */
|
||||
FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */
|
||||
FR_TOO_MANY_OPEN_FILES /* (18) Number of open files > _FS_SHARE */
|
||||
} FRESULT;
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* FatFs module application interface */
|
||||
|
||||
/* Low Level functions */
|
||||
FRESULT l_openfilebycluster(FATFS *fs, FIL *fp, const TCHAR *path, DWORD clust, DWORD fsize); /* Open a file by its start cluster using supplied file size */
|
||||
FRESULT l_opendirbycluster (FATFS *fs, DIR *dj, const TCHAR *path, DWORD clust);
|
||||
|
||||
/* application level functions */
|
||||
FRESULT f_mount (BYTE, FATFS*); /* Mount/Unmount a logical drive */
|
||||
FRESULT f_open (FIL*, const TCHAR*, BYTE); /* Open or create a file */
|
||||
FRESULT f_read (FIL*, void*, UINT, UINT*); /* Read data from a file */
|
||||
FRESULT f_lseek (FIL*, DWORD); /* Move file pointer of a file object */
|
||||
FRESULT f_close (FIL*); /* Close an open file object */
|
||||
FRESULT f_opendir (DIR*, const TCHAR*); /* Open an existing directory */
|
||||
FRESULT f_readdir (DIR*, FILINFO*); /* Read a directory item */
|
||||
FRESULT f_stat (const TCHAR*, FILINFO*); /* Get file status */
|
||||
|
||||
#if !_FS_READONLY
|
||||
FRESULT f_write (FIL*, const void*, UINT, UINT*); /* Write data to a file */
|
||||
FRESULT f_getfree (const TCHAR*, DWORD*, FATFS**); /* Get number of free clusters on the drive */
|
||||
FRESULT f_truncate (FIL*); /* Truncate file */
|
||||
FRESULT f_sync (FIL*); /* Flush cached data of a writing file */
|
||||
FRESULT f_unlink (const TCHAR*); /* Delete an existing file or directory */
|
||||
FRESULT f_mkdir (const TCHAR*); /* Create a new directory */
|
||||
FRESULT f_chmod (const TCHAR*, BYTE, BYTE); /* Change attriburte of the file/dir */
|
||||
FRESULT f_utime (const TCHAR*, const FILINFO*); /* Change timestamp of the file/dir */
|
||||
FRESULT f_rename (const TCHAR*, const TCHAR*); /* Rename/Move a file or directory */
|
||||
#endif
|
||||
|
||||
#if _USE_FORWARD
|
||||
FRESULT f_forward (FIL*, UINT(*)(const BYTE*,UINT), UINT, UINT*); /* Forward data to the stream */
|
||||
#endif
|
||||
|
||||
#if _USE_MKFS
|
||||
FRESULT f_mkfs (BYTE, BYTE, UINT); /* Create a file system on the drive */
|
||||
#endif
|
||||
|
||||
#if _FS_RPATH
|
||||
FRESULT f_chdrive (BYTE); /* Change current drive */
|
||||
FRESULT f_chdir (const TCHAR*); /* Change current directory */
|
||||
FRESULT f_getcwd (TCHAR*, UINT); /* Get current directory */
|
||||
#endif
|
||||
|
||||
#if _USE_STRFUNC
|
||||
int f_putc (TCHAR, FIL*); /* Put a character to the file */
|
||||
int f_puts (const TCHAR*, FIL*); /* Put a string to the file */
|
||||
int f_printf (FIL*, const TCHAR*, ...); /* Put a formatted string to the file */
|
||||
TCHAR* f_gets (TCHAR*, int, FIL*); /* Get a string from the file */
|
||||
#ifndef EOF
|
||||
#define EOF (-1)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define f_eof(fp) (((fp)->fptr == (fp)->fsize) ? 1 : 0)
|
||||
#define f_error(fp) (((fp)->flag & FA__ERROR) ? 1 : 0)
|
||||
#define f_tell(fp) ((fp)->fptr)
|
||||
#define f_size(fp) ((fp)->fsize)
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* Additional user defined functions */
|
||||
|
||||
/* RTC function */
|
||||
#if !_FS_READONLY
|
||||
DWORD get_fattime (void);
|
||||
#endif
|
||||
|
||||
/* Unicode support functions */
|
||||
#if _USE_LFN /* Unicode - OEM code conversion */
|
||||
WCHAR ff_convert (WCHAR, UINT); /* OEM-Unicode bidirectional conversion */
|
||||
WCHAR ff_wtoupper (WCHAR); /* Unicode upper-case conversion */
|
||||
#if _USE_LFN == 3 /* Memory functions */
|
||||
void* ff_memalloc (UINT); /* Allocate memory block */
|
||||
void ff_memfree (void*); /* Free memory block */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Sync functions */
|
||||
#if _FS_REENTRANT
|
||||
int ff_cre_syncobj (BYTE, _SYNC_t*);/* Create a sync object */
|
||||
int ff_del_syncobj (_SYNC_t); /* Delete a sync object */
|
||||
int ff_req_grant (_SYNC_t); /* Lock sync object */
|
||||
void ff_rel_grant (_SYNC_t); /* Unlock sync object */
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* Flags and offset address */
|
||||
|
||||
|
||||
/* File access control and file status flags (FIL.flag) */
|
||||
|
||||
#define FA_READ 0x01
|
||||
#define FA_OPEN_EXISTING 0x00
|
||||
#define FA__ERROR 0x80
|
||||
|
||||
#if !_FS_READONLY
|
||||
#define FA_WRITE 0x02
|
||||
#define FA_CREATE_NEW 0x04
|
||||
#define FA_CREATE_ALWAYS 0x08
|
||||
#define FA_OPEN_ALWAYS 0x10
|
||||
#define FA__WRITTEN 0x20
|
||||
#define FA__DIRTY 0x40
|
||||
#endif
|
||||
|
||||
|
||||
/* FAT sub type (FATFS.fs_type) */
|
||||
|
||||
#define FS_FAT12 1
|
||||
#define FS_FAT16 2
|
||||
#define FS_FAT32 3
|
||||
|
||||
|
||||
/* File attribute bits for directory entry */
|
||||
|
||||
#define AM_RDO 0x01 /* Read only */
|
||||
#define AM_HID 0x02 /* Hidden */
|
||||
#define AM_SYS 0x04 /* System */
|
||||
#define AM_VOL 0x08 /* Volume label */
|
||||
#define AM_LFN 0x0F /* LFN entry */
|
||||
#define AM_DIR 0x10 /* Directory */
|
||||
#define AM_ARC 0x20 /* Archive */
|
||||
#define AM_MASK 0x3F /* Mask of defined bits */
|
||||
|
||||
|
||||
/* Fast seek function */
|
||||
#define CREATE_LINKMAP 0xFFFFFFFF
|
||||
|
||||
|
||||
/*--------------------------------*/
|
||||
/* Multi-byte word access macros */
|
||||
|
||||
#if _WORD_ACCESS == 1 /* Enable word access to the FAT structure */
|
||||
#define LD_WORD(ptr) (WORD)(*(WORD*)(BYTE*)(ptr))
|
||||
#define LD_DWORD(ptr) (DWORD)(*(DWORD*)(BYTE*)(ptr))
|
||||
#define ST_WORD(ptr,val) *(WORD*)(BYTE*)(ptr)=(WORD)(val)
|
||||
#define ST_DWORD(ptr,val) *(DWORD*)(BYTE*)(ptr)=(DWORD)(val)
|
||||
#else /* Use byte-by-byte access to the FAT structure */
|
||||
#define LD_WORD(ptr) (WORD)(((WORD)*(BYTE*)((ptr)+1)<<8)|(WORD)*(BYTE*)(ptr))
|
||||
#define LD_DWORD(ptr) (DWORD)(((DWORD)*(BYTE*)((ptr)+3)<<24)|((DWORD)*(BYTE*)((ptr)+2)<<16)|((WORD)*(BYTE*)((ptr)+1)<<8)|*(BYTE*)(ptr))
|
||||
#define ST_WORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *(BYTE*)((ptr)+1)=(BYTE)((WORD)(val)>>8)
|
||||
#define ST_DWORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *(BYTE*)((ptr)+1)=(BYTE)((WORD)(val)>>8); *(BYTE*)((ptr)+2)=(BYTE)((DWORD)(val)>>16); *(BYTE*)((ptr)+3)=(BYTE)((DWORD)(val)>>24)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _FATFS */
|
||||
188
src/tests/ffconf.h
Normal file
188
src/tests/ffconf.h
Normal file
@ -0,0 +1,188 @@
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ FatFs - FAT file system module configuration file R0.08a (C)ChaN, 2010
|
||||
/----------------------------------------------------------------------------/
|
||||
/
|
||||
/ CAUTION! Do not forget to make clean the project after any changes to
|
||||
/ the configuration options.
|
||||
/
|
||||
/----------------------------------------------------------------------------*/
|
||||
#ifndef _FFCONF
|
||||
#define _FFCONF 8255 /* Revision ID */
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Function and Buffer Configurations
|
||||
/----------------------------------------------------------------------------*/
|
||||
|
||||
#define _FS_TINY 0 /* 0:Normal or 1:Tiny */
|
||||
/* When _FS_TINY is set to 1, FatFs uses the sector buffer in the file system
|
||||
/ object instead of the sector buffer in the individual file object for file
|
||||
/ data transfer. This reduces memory consumption 512 bytes each file object. */
|
||||
|
||||
|
||||
#define _FS_READONLY 0 /* 0:Read/Write or 1:Read only */
|
||||
/* Setting _FS_READONLY to 1 defines read only configuration. This removes
|
||||
/ writing functions, f_write, f_sync, f_unlink, f_mkdir, f_chmod, f_rename,
|
||||
/ f_truncate and useless f_getfree. */
|
||||
|
||||
|
||||
#define _FS_MINIMIZE 0 /* 0 to 3 */
|
||||
/* The _FS_MINIMIZE option defines minimization level to remove some functions.
|
||||
/
|
||||
/ 0: Full function.
|
||||
/ 1: f_stat, f_getfree, f_unlink, f_mkdir, f_chmod, f_truncate and f_rename
|
||||
/ are removed.
|
||||
/ 2: f_opendir and f_readdir are removed in addition to 1.
|
||||
/ 3: f_lseek is removed in addition to 2. */
|
||||
|
||||
|
||||
#define _USE_STRFUNC 0 /* 0:Disable or 1/2:Enable */
|
||||
/* To enable string functions, set _USE_STRFUNC to 1 or 2. */
|
||||
|
||||
|
||||
#define _USE_MKFS 0 /* 0:Disable or 1:Enable */
|
||||
/* To enable f_mkfs function, set _USE_MKFS to 1 and set _FS_READONLY to 0 */
|
||||
|
||||
|
||||
#define _USE_FORWARD 0 /* 0:Disable or 1:Enable */
|
||||
/* To enable f_forward function, set _USE_FORWARD to 1 and set _FS_TINY to 1. */
|
||||
|
||||
|
||||
#define _USE_FASTSEEK 1 /* 0:Disable or 1:Enable */
|
||||
/* To enable fast seek feature, set _USE_FASTSEEK to 1. */
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Locale and Namespace Configurations
|
||||
/----------------------------------------------------------------------------*/
|
||||
|
||||
#define _CODE_PAGE 1252
|
||||
/* The _CODE_PAGE specifies the OEM code page to be used on the target system.
|
||||
/ Incorrect setting of the code page can cause a file open failure.
|
||||
/
|
||||
/ 932 - Japanese Shift-JIS (DBCS, OEM, Windows)
|
||||
/ 936 - Simplified Chinese GBK (DBCS, OEM, Windows)
|
||||
/ 949 - Korean (DBCS, OEM, Windows)
|
||||
/ 950 - Traditional Chinese Big5 (DBCS, OEM, Windows)
|
||||
/ 1250 - Central Europe (Windows)
|
||||
/ 1251 - Cyrillic (Windows)
|
||||
/ 1252 - Latin 1 (Windows)
|
||||
/ 1253 - Greek (Windows)
|
||||
/ 1254 - Turkish (Windows)
|
||||
/ 1255 - Hebrew (Windows)
|
||||
/ 1256 - Arabic (Windows)
|
||||
/ 1257 - Baltic (Windows)
|
||||
/ 1258 - Vietnam (OEM, Windows)
|
||||
/ 437 - U.S. (OEM)
|
||||
/ 720 - Arabic (OEM)
|
||||
/ 737 - Greek (OEM)
|
||||
/ 775 - Baltic (OEM)
|
||||
/ 850 - Multilingual Latin 1 (OEM)
|
||||
/ 858 - Multilingual Latin 1 + Euro (OEM)
|
||||
/ 852 - Latin 2 (OEM)
|
||||
/ 855 - Cyrillic (OEM)
|
||||
/ 866 - Russian (OEM)
|
||||
/ 857 - Turkish (OEM)
|
||||
/ 862 - Hebrew (OEM)
|
||||
/ 874 - Thai (OEM, Windows)
|
||||
/ 1 - ASCII only (Valid for non LFN cfg.)
|
||||
*/
|
||||
|
||||
|
||||
#define _USE_LFN 1 /* 0 to 3 */
|
||||
#define _MAX_LFN 255 /* Maximum LFN length to handle (12 to 255) */
|
||||
/* The _USE_LFN option switches the LFN support.
|
||||
/
|
||||
/ 0: Disable LFN feature. _MAX_LFN and _LFN_UNICODE have no effect.
|
||||
/ 1: Enable LFN with static working buffer on the BSS. Always NOT reentrant.
|
||||
/ 2: Enable LFN with dynamic working buffer on the STACK.
|
||||
/ 3: Enable LFN with dynamic working buffer on the HEAP.
|
||||
/
|
||||
/ The LFN working buffer occupies (_MAX_LFN + 1) * 2 bytes. To enable LFN,
|
||||
/ Unicode handling functions ff_convert() and ff_wtoupper() must be added
|
||||
/ to the project. When enable to use heap, memory control functions
|
||||
/ ff_memalloc() and ff_memfree() must be added to the project. */
|
||||
|
||||
|
||||
#define _LFN_UNICODE 0 /* 0:ANSI/OEM or 1:Unicode */
|
||||
/* To switch the character code set on FatFs API to Unicode,
|
||||
/ enable LFN feature and set _LFN_UNICODE to 1. */
|
||||
|
||||
|
||||
#define _FS_RPATH 2 /* 0 to 2 */
|
||||
/* The _FS_RPATH option configures relative path feature.
|
||||
/
|
||||
/ 0: Disable relative path feature and remove related functions.
|
||||
/ 1: Enable relative path. f_chdrive() and f_chdir() are available.
|
||||
/ 2: f_getcwd() is available in addition to 1.
|
||||
/
|
||||
/ Note that output of the f_readdir fnction is affected by this option. */
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Physical Drive Configurations
|
||||
/----------------------------------------------------------------------------*/
|
||||
|
||||
#define _VOLUMES 1
|
||||
/* Number of volumes (logical drives) to be used. */
|
||||
|
||||
|
||||
#define _MAX_SS 512 /* 512, 1024, 2048 or 4096 */
|
||||
/* Maximum sector size to be handled.
|
||||
/ Always set 512 for memory card and hard disk but a larger value may be
|
||||
/ required for floppy disk (512/1024) and optical disk (512/2048).
|
||||
/ When _MAX_SS is larger than 512, GET_SECTOR_SIZE command must be implememted
|
||||
/ to the disk_ioctl function. */
|
||||
|
||||
|
||||
#define _MULTI_PARTITION 0 /* 0:Single partition or 1:Multiple partition */
|
||||
/* When set to 0, each volume is bound to the same physical drive number and
|
||||
/ it can mount only first primaly partition. When it is set to 1, each volume
|
||||
/ is tied to the partitions listed in VolToPart[]. */
|
||||
|
||||
|
||||
#define _USE_ERASE 0 /* 0:Disable or 1:Enable */
|
||||
/* To enable sector erase feature, set _USE_ERASE to 1. */
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ System Configurations
|
||||
/----------------------------------------------------------------------------*/
|
||||
|
||||
#define _WORD_ACCESS 0 /* 0 or 1 */
|
||||
/* Set 0 first and it is always compatible with all platforms. The _WORD_ACCESS
|
||||
/ option defines which access method is used to the word data on the FAT volume.
|
||||
/
|
||||
/ 0: Byte-by-byte access.
|
||||
/ 1: Word access. Do not choose this unless following condition is met.
|
||||
/
|
||||
/ When the byte order on the memory is big-endian or address miss-aligned word
|
||||
/ access results incorrect behavior, the _WORD_ACCESS must be set to 0.
|
||||
/ If it is not the case, the value can also be set to 1 to improve the
|
||||
/ performance and code size. */
|
||||
|
||||
|
||||
/* Include a header file here to define sync object types on the O/S */
|
||||
/* #include <windows.h>, <ucos_ii.h.h>, <semphr.h> or ohters. */
|
||||
|
||||
#define _FS_REENTRANT 0 /* 0:Disable or 1:Enable */
|
||||
#define _FS_TIMEOUT 1000 /* Timeout period in unit of time ticks */
|
||||
#define _SYNC_t HANDLE /* O/S dependent type of sync object. e.g. HANDLE, OS_EVENT*, ID and etc.. */
|
||||
|
||||
/* The _FS_REENTRANT option switches the reentrancy of the FatFs module.
|
||||
/
|
||||
/ 0: Disable reentrancy. _SYNC_t and _FS_TIMEOUT have no effect.
|
||||
/ 1: Enable reentrancy. Also user provided synchronization handlers,
|
||||
/ ff_req_grant, ff_rel_grant, ff_del_syncobj and ff_cre_syncobj
|
||||
/ function must be added to the project. */
|
||||
|
||||
|
||||
#define _FS_SHARE 0 /* 0:Disable or >=1:Enable */
|
||||
/* To enable file shareing feature, set _FS_SHARE to 1 or greater. The value
|
||||
defines how many files can be opened simultaneously. */
|
||||
|
||||
|
||||
#endif /* _FFCONFIG */
|
||||
117
src/tests/fileops.c
Normal file
117
src/tests/fileops.c
Normal file
@ -0,0 +1,117 @@
|
||||
/* sd2snes - SD card based universal cartridge for the SNES
|
||||
Copyright (C) 2009-2010 Maximilian Rehkopf <otakon@gmx.net>
|
||||
AVR firmware portion
|
||||
|
||||
Inspired by and based on code from sd2iec, written by Ingo Korb et al.
|
||||
See sdcard.c|h, config.h.
|
||||
|
||||
FAT file system access based on code by ChaN, Jim Brain, Ingo Korb,
|
||||
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
|
||||
|
||||
fileops.c: simple file access functions
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "uart.h"
|
||||
#include "ff.h"
|
||||
#include "fileops.h"
|
||||
#include "diskio.h"
|
||||
|
||||
/*
|
||||
WCHAR ff_convert(WCHAR w, UINT dir) {
|
||||
return w;
|
||||
}*/
|
||||
|
||||
int newcard;
|
||||
|
||||
void file_init() {
|
||||
file_res=f_mount(0, &fatfs);
|
||||
newcard = 0;
|
||||
}
|
||||
|
||||
void file_reinit(void) {
|
||||
disk_init();
|
||||
file_init();
|
||||
}
|
||||
|
||||
FRESULT dir_open_by_filinfo(DIR* dir, FILINFO* fno) {
|
||||
return l_opendirbycluster(&fatfs, dir, (TCHAR*)"", fno->clust);
|
||||
}
|
||||
|
||||
void file_open_by_filinfo(FILINFO* fno) {
|
||||
file_res = l_openfilebycluster(&fatfs, &file_handle, (TCHAR*)"", fno->clust, fno->fsize);
|
||||
}
|
||||
|
||||
void file_open(uint8_t* filename, BYTE flags) {
|
||||
if (disk_state == DISK_CHANGED) {
|
||||
file_reinit();
|
||||
newcard = 1;
|
||||
}
|
||||
file_res = f_open(&file_handle, (TCHAR*)filename, flags);
|
||||
file_block_off = sizeof(file_buf);
|
||||
file_block_max = sizeof(file_buf);
|
||||
file_status = file_res ? FILE_ERR : FILE_OK;
|
||||
}
|
||||
|
||||
void file_close() {
|
||||
file_res = f_close(&file_handle);
|
||||
}
|
||||
|
||||
void file_seek(uint32_t offset) {
|
||||
file_res = f_lseek(&file_handle, (DWORD)offset);
|
||||
}
|
||||
|
||||
UINT file_read() {
|
||||
UINT bytes_read;
|
||||
file_res = f_read(&file_handle, file_buf, sizeof(file_buf), &bytes_read);
|
||||
return bytes_read;
|
||||
}
|
||||
|
||||
UINT file_write() {
|
||||
UINT bytes_written;
|
||||
file_res = f_write(&file_handle, file_buf, sizeof(file_buf), &bytes_written);
|
||||
if(bytes_written < sizeof(file_buf)) {
|
||||
printf("wrote less than expected - card full?\n");
|
||||
}
|
||||
return bytes_written;
|
||||
}
|
||||
|
||||
UINT file_readblock(void* buf, uint32_t addr, uint16_t size) {
|
||||
UINT bytes_read;
|
||||
file_res = f_lseek(&file_handle, addr);
|
||||
if(file_handle.fptr != addr) {
|
||||
return 0;
|
||||
}
|
||||
file_res = f_read(&file_handle, buf, size, &bytes_read);
|
||||
return bytes_read;
|
||||
}
|
||||
|
||||
UINT file_writeblock(void* buf, uint32_t addr, uint16_t size) {
|
||||
UINT bytes_written;
|
||||
file_res = f_lseek(&file_handle, addr);
|
||||
if(file_res) return 0;
|
||||
file_res = f_write(&file_handle, buf, size, &bytes_written);
|
||||
return bytes_written;
|
||||
}
|
||||
|
||||
uint8_t file_getc() {
|
||||
if(file_block_off == file_block_max) {
|
||||
file_block_max = file_read();
|
||||
if(file_block_max == 0) file_status = FILE_EOF;
|
||||
file_block_off = 0;
|
||||
}
|
||||
return file_buf[file_block_off++];
|
||||
}
|
||||
54
src/tests/fileops.h
Normal file
54
src/tests/fileops.h
Normal file
@ -0,0 +1,54 @@
|
||||
/* sd2snes - SD card based universal cartridge for the SNES
|
||||
Copyright (C) 2009-2010 Maximilian Rehkopf <otakon@gmx.net>
|
||||
AVR firmware portion
|
||||
|
||||
Inspired by and based on code from sd2iec, written by Ingo Korb et al.
|
||||
See sdcard.c|h, config.h.
|
||||
|
||||
FAT file system access based on code by ChaN, Jim Brain, Ingo Korb,
|
||||
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
|
||||
|
||||
fileops.h: simple file access functions
|
||||
*/
|
||||
|
||||
#ifndef FILEOPS_H
|
||||
#define FILEOPS_H
|
||||
#include <arm/NXP/LPC17xx/LPC17xx.h>
|
||||
#include "ff.h"
|
||||
|
||||
enum filestates { FILE_OK=0, FILE_ERR, FILE_EOF };
|
||||
|
||||
BYTE file_buf[512];
|
||||
FATFS fatfs;
|
||||
FIL file_handle;
|
||||
FRESULT file_res;
|
||||
uint8_t file_lfn[258];
|
||||
uint16_t file_block_off, file_block_max;
|
||||
enum filestates file_status;
|
||||
|
||||
void file_init(void);
|
||||
void file_open(uint8_t* filename, BYTE flags);
|
||||
FRESULT dir_open_by_filinfo(DIR* dir, FILINFO* fno_param);
|
||||
void file_open_by_filinfo(FILINFO* fno);
|
||||
void file_close(void);
|
||||
void file_seek(uint32_t offset);
|
||||
UINT file_read(void);
|
||||
UINT file_write(void);
|
||||
UINT file_readblock(void* buf, uint32_t addr, uint16_t size);
|
||||
UINT file_writeblock(void* buf, uint32_t addr, uint16_t size);
|
||||
|
||||
uint8_t file_getc(void);
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user