Compare commits
21 Commits
mem_compac
...
v46
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
764c0dd2c1 | ||
|
|
a1763efe21 | ||
|
|
b3d930b143 | ||
|
|
3063b354e7 | ||
|
|
571737d59b | ||
|
|
09198f5099 | ||
|
|
8e877d38d4 | ||
|
|
7a878eab39 | ||
|
|
091b82a7ef | ||
|
|
1c30d3db56 | ||
|
|
9cf6eae076 | ||
|
|
67a25941a7 | ||
|
|
aedc6dab5b | ||
|
|
c40b9c32b6 | ||
|
|
59aad4c7a8 | ||
|
|
af48032798 | ||
|
|
d481bd5061 | ||
|
|
96c273fe89 | ||
|
|
25c1f38aed | ||
|
|
0693dbc933 | ||
|
|
500e6326c1 |
@@ -1,18 +0,0 @@
|
|||||||
--- !ditz.rubyforge.org,2008-03-06/issue
|
|
||||||
title: Test
|
|
||||||
desc: Test
|
|
||||||
type: :bugfix
|
|
||||||
component: snesram
|
|
||||||
release:
|
|
||||||
reporter: David <david@optixx.org>
|
|
||||||
status: :unstarted
|
|
||||||
disposition:
|
|
||||||
creation_time: 2009-04-20 18:13:29.104365 Z
|
|
||||||
references: []
|
|
||||||
|
|
||||||
id: 33e57a7c3ac89afc2e37880441fe0eeec05e2b3f
|
|
||||||
log_events:
|
|
||||||
- - 2009-04-20 18:13:33.543384 Z
|
|
||||||
- David <david@optixx.org>
|
|
||||||
- created
|
|
||||||
- nope
|
|
||||||
@@ -182,7 +182,7 @@ AVRDUDE_PROGRAMMER = stk500v2
|
|||||||
|
|
||||||
# com1 = serial port. Use lpt1 to connect to parallel port.
|
# com1 = serial port. Use lpt1 to connect to parallel port.
|
||||||
|
|
||||||
AVRDUDE_PORT = /dev/tty.PL2303-00001124
|
AVRDUDE_PORT =/dev/tty.PL2303-00001124
|
||||||
|
|
||||||
AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex
|
AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ extern FILE uart_stdout;
|
|||||||
#define RAM_REG PINA
|
#define RAM_REG PINA
|
||||||
|
|
||||||
#define CTRL_PORT PORTB
|
#define CTRL_PORT PORTB
|
||||||
#define CTR_DIR DDRB
|
#define CTRL_DIR DDRB
|
||||||
#define LATCH_PORT PORTB
|
#define LATCH_PORT PORTB
|
||||||
#define LATCH_DIR DDRB
|
#define LATCH_DIR DDRB
|
||||||
|
|
||||||
@@ -42,10 +42,10 @@ extern FILE uart_stdout;
|
|||||||
//#define FILENAME "sprite.raw" //ok
|
//#define FILENAME "sprite.raw" //ok
|
||||||
//#define FILENAME "ascii.smc" //ok
|
//#define FILENAME "ascii.smc" //ok
|
||||||
//#define FILENAME "rom.smc" //ok
|
//#define FILENAME "rom.smc" //ok
|
||||||
//#define FILENAME "supert.smc"
|
//#define FILENAME "supert.smc" //ok
|
||||||
//#define FILENAME "vortex.smc"
|
//#define FILENAME "vortex.smc" //failed
|
||||||
//#define FILENAME "mrdo.smc"
|
//#define FILENAME "mrdo.smc" //failed
|
||||||
//#define FILENAME "spacei.smc"
|
//#define FILENAME "spacei.smc" //ok ntsc
|
||||||
//#define FILENAME "bank01.smc" //ok
|
//#define FILENAME "bank01.smc" //ok
|
||||||
//#define FILENAME "bank02.smc" //ok
|
//#define FILENAME "bank02.smc" //ok
|
||||||
//#define FILENAME "bank03.smc" //ok
|
//#define FILENAME "bank03.smc" //ok
|
||||||
@@ -56,9 +56,14 @@ extern FILE uart_stdout;
|
|||||||
//#define FILENAME "banklo.smc" //ok
|
//#define FILENAME "banklo.smc" //ok
|
||||||
//#define FILENAME "bankhi.smc" //ok
|
//#define FILENAME "bankhi.smc" //ok
|
||||||
//#define FILENAME "vram2.smc" //ok
|
//#define FILENAME "vram2.smc" //ok
|
||||||
//#define FILENAME "super02.smc"
|
//#define FILENAME "super02.smc" //ok
|
||||||
#define FILENAME "crc.smc"
|
//#define FILENAME "super01.smc"//ok
|
||||||
//#define FILENAME "banks.smc"
|
//#define FILENAME "crc.smc" //ok
|
||||||
|
//#define FILENAME "banks.smc" //ok
|
||||||
|
//#define FILENAME "hungry.smc" //ok
|
||||||
|
//#define FILENAME "arkanoid.smc"//ok
|
||||||
|
//#define FILENAME "eric.smc"
|
||||||
|
#define FILENAME "turrican.smc"
|
||||||
|
|
||||||
#define ROMSIZE 4
|
#define ROMSIZE 4
|
||||||
#define DUMPNAME "dump256.smc"
|
#define DUMPNAME "dump256.smc"
|
||||||
@@ -233,18 +238,28 @@ void sram_init(void){
|
|||||||
RAM_DIR = 0x00;
|
RAM_DIR = 0x00;
|
||||||
RAM_PORT = 0x00;
|
RAM_PORT = 0x00;
|
||||||
|
|
||||||
CTR_DIR |= ((1<<R_WR) | (1<<R_RD));
|
CTRL_DIR |= ((1<<R_WR) | (1<<R_RD));
|
||||||
CTRL_PORT |= (1<<R_RD);
|
CTRL_PORT |= (1<<R_RD);
|
||||||
CTRL_PORT |= (1<<R_WR);
|
CTRL_PORT |= (1<<R_WR);
|
||||||
|
|
||||||
LED_PORT |= (1<<D_LED0);
|
LED_PORT |= (1<<D_LED0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sram_snes_mode(void){
|
void sram_snes_mode01(void){
|
||||||
CTRL_PORT |= (1<<R_WR);
|
CTRL_PORT |= (1<<R_WR);
|
||||||
CTRL_PORT &= ~(1<<R_RD);
|
CTRL_PORT &= ~(1<<R_RD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sram_snes_mode02(void){
|
||||||
|
CTRL_DIR |= (1<<R_WR);
|
||||||
|
CTRL_PORT |= (1<<R_WR);
|
||||||
|
//CTRL_PORT &= ~(1<<R_RD);
|
||||||
|
CTRL_DIR &= ~(1<<R_RD);
|
||||||
|
CTRL_PORT &= ~(1<<R_RD);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void sram_clear(uint32_t addr, uint32_t len){
|
void sram_clear(uint32_t addr, uint32_t len){
|
||||||
|
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
@@ -426,8 +441,17 @@ int main(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
sram_snes_mode();
|
#if 0
|
||||||
printf("\nEnter Snes mode\n");
|
sram_snes_mode01();
|
||||||
|
printf("\nEnter Snes mode 02\n");
|
||||||
|
#endif
|
||||||
|
#if 0
|
||||||
|
sram_snes_mode02();
|
||||||
|
printf("\nEnter Snes mode 02\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
printf("\nUpload done.\n");
|
||||||
|
|
||||||
while(1);
|
while(1);
|
||||||
return 0 ;
|
return 0 ;
|
||||||
|
|
||||||
|
|||||||
168
poc/avr_usbload/Makefile
Normal file
168
poc/avr_usbload/Makefile
Normal file
@@ -0,0 +1,168 @@
|
|||||||
|
# Name: Makefile
|
||||||
|
# Project: custom-class example
|
||||||
|
# Author: Christian Starkjohann
|
||||||
|
# Creation Date: 2008-04-07
|
||||||
|
# Tabsize: 4
|
||||||
|
# Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
|
||||||
|
# License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
||||||
|
# This Revision: $Id: Makefile 692 2008-11-07 15:07:40Z cs $
|
||||||
|
|
||||||
|
DEVICE = atmega16
|
||||||
|
F_CPU = 16000000 # in Hz
|
||||||
|
FUSE_L = # see below for fuse values for particular devices
|
||||||
|
FUSE_H =
|
||||||
|
AVRDUDE = avrdude -c stk500v2 -p $(DEVICE) -P /dev/tty.PL2303-00002006
|
||||||
|
#AVRDUDE = avrdude -c stk500v2 -p $(DEVICE) -P /dev/tty.PL2303-00001424
|
||||||
|
|
||||||
|
CFLAGS = -Iusbdrv -I. -DDEBUG_LEVEL=0
|
||||||
|
#-std=gnu99
|
||||||
|
OBJECTS = usbdrv/usbdrv.o usbdrv/usbdrvasm.o usbdrv/oddebug.o main.o uart.o fifo.o sram.o crc.o debug.o
|
||||||
|
|
||||||
|
COMPILE = avr-gcc -Wall -Os -DF_CPU=$(F_CPU) $(CFLAGS) -mmcu=$(DEVICE)
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
# Fuse values for particular devices
|
||||||
|
##############################################################################
|
||||||
|
# If your device is not listed here, go to
|
||||||
|
# http://palmavr.sourceforge.net/cgi-bin/fc.cgi
|
||||||
|
# and choose options for external crystal clock and no clock divider
|
||||||
|
#
|
||||||
|
################################## ATMega8 ##################################
|
||||||
|
# ATMega8 FUSE_L (Fuse low byte):
|
||||||
|
# 0x9f = 1 0 0 1 1 1 1 1
|
||||||
|
# ^ ^ \ / \--+--/
|
||||||
|
# | | | +------- CKSEL 3..0 (external >8M crystal)
|
||||||
|
# | | +--------------- SUT 1..0 (crystal osc, BOD enabled)
|
||||||
|
# | +------------------ BODEN (BrownOut Detector enabled)
|
||||||
|
# +-------------------- BODLEVEL (2.7V)
|
||||||
|
# ATMega8 FUSE_H (Fuse high byte):
|
||||||
|
# 0xc9 = 1 1 0 0 1 0 0 1 <-- BOOTRST (boot reset vector at 0x0000)
|
||||||
|
# ^ ^ ^ ^ ^ ^ ^------ BOOTSZ0
|
||||||
|
# | | | | | +-------- BOOTSZ1
|
||||||
|
# | | | | + --------- EESAVE (don't preserve EEPROM over chip erase)
|
||||||
|
# | | | +-------------- CKOPT (full output swing)
|
||||||
|
# | | +---------------- SPIEN (allow serial programming)
|
||||||
|
# | +------------------ WDTON (WDT not always on)
|
||||||
|
# +-------------------- RSTDISBL (reset pin is enabled)
|
||||||
|
#
|
||||||
|
############################## ATMega48/88/168 ##############################
|
||||||
|
# ATMega*8 FUSE_L (Fuse low byte):
|
||||||
|
# 0xdf = 1 1 0 1 1 1 1 1
|
||||||
|
# ^ ^ \ / \--+--/
|
||||||
|
# | | | +------- CKSEL 3..0 (external >8M crystal)
|
||||||
|
# | | +--------------- SUT 1..0 (crystal osc, BOD enabled)
|
||||||
|
# | +------------------ CKOUT (if 0: Clock output enabled)
|
||||||
|
# +-------------------- CKDIV8 (if 0: divide by 8)
|
||||||
|
# ATMega*8 FUSE_H (Fuse high byte):
|
||||||
|
# 0xde = 1 1 0 1 1 1 1 0
|
||||||
|
# ^ ^ ^ ^ ^ \-+-/
|
||||||
|
# | | | | | +------ BODLEVEL 0..2 (110 = 1.8 V)
|
||||||
|
# | | | | + --------- EESAVE (preserve EEPROM over chip erase)
|
||||||
|
# | | | +-------------- WDTON (if 0: watchdog always on)
|
||||||
|
# | | +---------------- SPIEN (allow serial programming)
|
||||||
|
# | +------------------ DWEN (debug wire enable)
|
||||||
|
# +-------------------- RSTDISBL (reset pin is enabled)
|
||||||
|
#
|
||||||
|
############################## ATTiny25/45/85 ###############################
|
||||||
|
# ATMega*5 FUSE_L (Fuse low byte):
|
||||||
|
# 0xef = 1 1 1 0 1 1 1 1
|
||||||
|
# ^ ^ \+/ \--+--/
|
||||||
|
# | | | +------- CKSEL 3..0 (clock selection -> crystal @ 12 MHz)
|
||||||
|
# | | +--------------- SUT 1..0 (BOD enabled, fast rising power)
|
||||||
|
# | +------------------ CKOUT (clock output on CKOUT pin -> disabled)
|
||||||
|
# +-------------------- CKDIV8 (divide clock by 8 -> don't divide)
|
||||||
|
# ATMega*5 FUSE_H (Fuse high byte):
|
||||||
|
# 0xdd = 1 1 0 1 1 1 0 1
|
||||||
|
# ^ ^ ^ ^ ^ \-+-/
|
||||||
|
# | | | | | +------ BODLEVEL 2..0 (brownout trigger level -> 2.7V)
|
||||||
|
# | | | | +---------- EESAVE (preserve EEPROM on Chip Erase -> not preserved)
|
||||||
|
# | | | +-------------- WDTON (watchdog timer always on -> disable)
|
||||||
|
# | | +---------------- SPIEN (enable serial programming -> enabled)
|
||||||
|
# | +------------------ DWEN (debug wire enable)
|
||||||
|
# +-------------------- RSTDISBL (disable external reset -> enabled)
|
||||||
|
#
|
||||||
|
################################ ATTiny2313 #################################
|
||||||
|
# ATTiny2313 FUSE_L (Fuse low byte):
|
||||||
|
# 0xef = 1 1 1 0 1 1 1 1
|
||||||
|
# ^ ^ \+/ \--+--/
|
||||||
|
# | | | +------- CKSEL 3..0 (clock selection -> crystal @ 12 MHz)
|
||||||
|
# | | +--------------- SUT 1..0 (BOD enabled, fast rising power)
|
||||||
|
# | +------------------ CKOUT (clock output on CKOUT pin -> disabled)
|
||||||
|
# +-------------------- CKDIV8 (divide clock by 8 -> don't divide)
|
||||||
|
# ATTiny2313 FUSE_H (Fuse high byte):
|
||||||
|
# 0xdb = 1 1 0 1 1 0 1 1
|
||||||
|
# ^ ^ ^ ^ \-+-/ ^
|
||||||
|
# | | | | | +---- RSTDISBL (disable external reset -> enabled)
|
||||||
|
# | | | | +-------- BODLEVEL 2..0 (brownout trigger level -> 2.7V)
|
||||||
|
# | | | +-------------- WDTON (watchdog timer always on -> disable)
|
||||||
|
# | | +---------------- SPIEN (enable serial programming -> enabled)
|
||||||
|
# | +------------------ EESAVE (preserve EEPROM on Chip Erase -> not preserved)
|
||||||
|
# +-------------------- DWEN (debug wire enable)
|
||||||
|
|
||||||
|
|
||||||
|
# symbolic targets:
|
||||||
|
help:
|
||||||
|
@echo "This Makefile has no default rule. Use one of the following:"
|
||||||
|
@echo "make hex ....... to build main.hex"
|
||||||
|
@echo "make program ... to flash fuses and firmware"
|
||||||
|
@echo "make fuse ...... to flash the fuses"
|
||||||
|
@echo "make flash ..... to flash the firmware (use this on metaboard)"
|
||||||
|
@echo "make clean ..... to delete objects and hex file"
|
||||||
|
|
||||||
|
all: hex
|
||||||
|
|
||||||
|
hex: main.hex
|
||||||
|
|
||||||
|
program: flash fuse
|
||||||
|
|
||||||
|
# rule for programming fuse bits:
|
||||||
|
fuse:
|
||||||
|
@[ "$(FUSE_H)" != "" -a "$(FUSE_L)" != "" ] || \
|
||||||
|
{ echo "*** Edit Makefile and choose values for FUSE_L and FUSE_H!"; exit 1; }
|
||||||
|
$(AVRDUDE) -U hfuse:w:$(FUSE_H):m -U lfuse:w:$(FUSE_L):m
|
||||||
|
|
||||||
|
# rule for uploading firmware:
|
||||||
|
flash: main.hex
|
||||||
|
$(AVRDUDE) -U flash:w:main.hex:i
|
||||||
|
|
||||||
|
# rule for deleting dependent files (those which can be built by Make):
|
||||||
|
clean:
|
||||||
|
rm -f main.hex main.lst main.obj main.cof main.list main.map main.eep.hex main.elf *.o usbdrv/*.o main.s usbdrv/oddebug.s usbdrv/usbdrv.s
|
||||||
|
|
||||||
|
# Generic rule for compiling C files:
|
||||||
|
.c.o:
|
||||||
|
$(COMPILE) -c $< -o $@
|
||||||
|
|
||||||
|
# Generic rule for assembling Assembler source files:
|
||||||
|
.S.o:
|
||||||
|
$(COMPILE) -x assembler-with-cpp -c $< -o $@
|
||||||
|
# "-x assembler-with-cpp" should not be necessary since this is the default
|
||||||
|
# file type for the .S (with capital S) extension. However, upper case
|
||||||
|
# characters are not always preserved on Windows. To ensure WinAVR
|
||||||
|
# compatibility define the file type manually.
|
||||||
|
|
||||||
|
# Generic rule for compiling C to assembler, used for debugging only.
|
||||||
|
.c.s:
|
||||||
|
$(COMPILE) -S $< -o $@
|
||||||
|
|
||||||
|
# file targets:
|
||||||
|
|
||||||
|
# Since we don't want to ship the driver multipe times, we copy it into this project:
|
||||||
|
usbdrv:
|
||||||
|
cp -r ../../../usbdrv .
|
||||||
|
|
||||||
|
main.elf: usbdrv $(OBJECTS) # usbdrv dependency only needed because we copy it
|
||||||
|
$(COMPILE) -o main.elf $(OBJECTS)
|
||||||
|
|
||||||
|
main.hex: main.elf
|
||||||
|
rm -f main.hex main.eep.hex
|
||||||
|
avr-objcopy -j .text -j .data -O ihex main.elf main.hex
|
||||||
|
avr-size main.hex
|
||||||
|
|
||||||
|
# debugging targets:
|
||||||
|
|
||||||
|
disasm: main.elf
|
||||||
|
avr-objdump -d main.elf
|
||||||
|
|
||||||
|
cpp:
|
||||||
|
$(COMPILE) -E main.c
|
||||||
35
poc/avr_usbload/checksize
Normal file
35
poc/avr_usbload/checksize
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# Name: checksize
|
||||||
|
# Project: PowerSwitch/AVR-USB
|
||||||
|
# Author: Christian Starkjohann
|
||||||
|
# Creation Date: 2004-12-29
|
||||||
|
# Tabsize: 4
|
||||||
|
# Copyright: (c) 2005 OBJECTIVE DEVELOPMENT Software GmbH.
|
||||||
|
# Revision: $Id: checksize 83 2006-01-05 22:20:53Z cs $
|
||||||
|
|
||||||
|
error=0
|
||||||
|
codelimit=16384 # default value
|
||||||
|
datalimit=992 # default value; leave 32 bytes for stack
|
||||||
|
|
||||||
|
if [ $# -gt 1 ]; then
|
||||||
|
codelimit="$2"
|
||||||
|
fi
|
||||||
|
if [ $# -gt 2 ]; then
|
||||||
|
datalimit="$3"
|
||||||
|
fi
|
||||||
|
|
||||||
|
set -- `avr-size -d "$1" | awk '/[0-9]/ {print $1 + $2, $2 + $3, $2}'`
|
||||||
|
if [ $1 -gt $codelimit ]; then
|
||||||
|
echo "*** code size $1 exceeds limit of $codelimit"
|
||||||
|
error=1
|
||||||
|
else
|
||||||
|
echo "ROM: $1 bytes (data=$3)"
|
||||||
|
fi
|
||||||
|
if [ $2 -gt $datalimit ]; then
|
||||||
|
echo "*** data size $2 exceeds limit of $datalimit"
|
||||||
|
error=1
|
||||||
|
else
|
||||||
|
echo "RAM: $2 bytes"
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit $error
|
||||||
48
poc/avr_usbload/commandline/Makefile
Normal file
48
poc/avr_usbload/commandline/Makefile
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
# Name: Makefile
|
||||||
|
# Project: custom-class example
|
||||||
|
# Author: Christian Starkjohann
|
||||||
|
# Creation Date: 2008-04-06
|
||||||
|
# Tabsize: 4
|
||||||
|
# Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
|
||||||
|
# License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
||||||
|
# This Revision: $Id: Makefile 692 2008-11-07 15:07:40Z cs $
|
||||||
|
|
||||||
|
|
||||||
|
# Concigure the following definitions according to your system.
|
||||||
|
# This Makefile has been tested on Mac OS X, Linux and Windows.
|
||||||
|
|
||||||
|
# Use the following 3 lines on Unix (uncomment the framework on Mac OS X):
|
||||||
|
USBFLAGS = `libusb-config --cflags`
|
||||||
|
USBLIBS = `libusb-config --libs`
|
||||||
|
EXE_SUFFIX =
|
||||||
|
|
||||||
|
# Use the following 3 lines on Windows and comment out the 3 above. You may
|
||||||
|
# have to change the include paths to where you installed libusb-win32
|
||||||
|
#USBFLAGS = -I/usr/local/include
|
||||||
|
#USBLIBS = -L/usr/local/lib -lusb
|
||||||
|
#EXE_SUFFIX = .exe
|
||||||
|
|
||||||
|
NAME = snesuploader
|
||||||
|
|
||||||
|
OBJECTS = opendevice.o $(NAME).o
|
||||||
|
|
||||||
|
CC = gcc
|
||||||
|
CFLAGS = $(CPPFLAGS) $(USBFLAGS) -O -g -Wall
|
||||||
|
LIBS = $(USBLIBS)
|
||||||
|
|
||||||
|
PROGRAM = $(NAME)$(EXE_SUFFIX)
|
||||||
|
|
||||||
|
|
||||||
|
all: $(PROGRAM)
|
||||||
|
|
||||||
|
.c.o:
|
||||||
|
$(CC) $(CFLAGS) -c $<
|
||||||
|
|
||||||
|
$(PROGRAM): $(OBJECTS)
|
||||||
|
$(CC) -o $(PROGRAM) $(OBJECTS) $(LIBS)
|
||||||
|
|
||||||
|
strip: $(PROGRAM)
|
||||||
|
strip $(PROGRAM)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f *.o $(PROGRAM)
|
||||||
285
poc/avr_usbload/commandline/opendevice.c
Normal file
285
poc/avr_usbload/commandline/opendevice.c
Normal file
@@ -0,0 +1,285 @@
|
|||||||
|
/*
|
||||||
|
* Name: opendevice.c Project: V-USB host-side library Author: Christian
|
||||||
|
* Starkjohann Creation Date: 2008-04-10 Tabsize: 4 Copyright: (c) 2008 by
|
||||||
|
* OBJECTIVE DEVELOPMENT Software GmbH License: GNU GPL v2 (see License.txt),
|
||||||
|
* GNU GPL v3 or proprietary (CommercialLicense.txt) This Revision: $Id:
|
||||||
|
* opendevice.c 740 2009-04-13 18:23:31Z cs $
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* General Description: The functions in this module can be used to find and
|
||||||
|
* open a device based on libusb or libusb-win32.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "opendevice.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define MATCH_SUCCESS 1
|
||||||
|
#define MATCH_FAILED 0
|
||||||
|
#define MATCH_ABORT -1
|
||||||
|
|
||||||
|
/*
|
||||||
|
* private interface: match text and p, return MATCH_SUCCESS, MATCH_FAILED, or
|
||||||
|
* MATCH_ABORT.
|
||||||
|
*/
|
||||||
|
static int _shellStyleMatch(char *text, char *p)
|
||||||
|
{
|
||||||
|
int last,
|
||||||
|
matched,
|
||||||
|
reverse;
|
||||||
|
|
||||||
|
for (; *p; text++, p++) {
|
||||||
|
if (*text == 0 && *p != '*')
|
||||||
|
return MATCH_ABORT;
|
||||||
|
switch (*p) {
|
||||||
|
case '\\':
|
||||||
|
/*
|
||||||
|
* Literal match with following character.
|
||||||
|
*/
|
||||||
|
p++;
|
||||||
|
/*
|
||||||
|
* FALLTHROUGH
|
||||||
|
*/
|
||||||
|
default:
|
||||||
|
if (*text != *p)
|
||||||
|
return MATCH_FAILED;
|
||||||
|
continue;
|
||||||
|
case '?':
|
||||||
|
/*
|
||||||
|
* Match anything.
|
||||||
|
*/
|
||||||
|
continue;
|
||||||
|
case '*':
|
||||||
|
while (*++p == '*')
|
||||||
|
/*
|
||||||
|
* Consecutive stars act just like one.
|
||||||
|
*/
|
||||||
|
continue;
|
||||||
|
if (*p == 0)
|
||||||
|
/*
|
||||||
|
* Trailing star matches everything.
|
||||||
|
*/
|
||||||
|
return MATCH_SUCCESS;
|
||||||
|
while (*text)
|
||||||
|
if ((matched = _shellStyleMatch(text++, p)) != MATCH_FAILED)
|
||||||
|
return matched;
|
||||||
|
return MATCH_ABORT;
|
||||||
|
case '[':
|
||||||
|
reverse = p[1] == '^';
|
||||||
|
if (reverse) /* Inverted character class. */
|
||||||
|
p++;
|
||||||
|
matched = MATCH_FAILED;
|
||||||
|
if (p[1] == ']' || p[1] == '-')
|
||||||
|
if (*++p == *text)
|
||||||
|
matched = MATCH_SUCCESS;
|
||||||
|
for (last = *p; *++p && *p != ']'; last = *p)
|
||||||
|
if (*p == '-' && p[1] != ']' ? *text <= *++p
|
||||||
|
&& *text >= last : *text == *p)
|
||||||
|
matched = MATCH_SUCCESS;
|
||||||
|
if (matched == reverse)
|
||||||
|
return MATCH_FAILED;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return *text == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* public interface for shell style matching: returns 0 if fails, 1 if matches
|
||||||
|
*/
|
||||||
|
static int shellStyleMatch(char *text, char *pattern)
|
||||||
|
{
|
||||||
|
if (pattern == NULL) /* NULL pattern is synonymous to "*" */
|
||||||
|
return 1;
|
||||||
|
return _shellStyleMatch(text, pattern) == MATCH_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
int usbGetStringAscii(usb_dev_handle * dev, int index, char *buf, int buflen)
|
||||||
|
{
|
||||||
|
char buffer[256];
|
||||||
|
int rval,
|
||||||
|
i;
|
||||||
|
|
||||||
|
if ((rval = usb_get_string_simple(dev, index, buf, buflen)) >= 0) /* use
|
||||||
|
* libusb
|
||||||
|
* version
|
||||||
|
* if
|
||||||
|
* it
|
||||||
|
* works
|
||||||
|
*/
|
||||||
|
return rval;
|
||||||
|
if ((rval =
|
||||||
|
usb_control_msg(dev, USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR,
|
||||||
|
(USB_DT_STRING << 8) + index, 0x0409, buffer,
|
||||||
|
sizeof(buffer), 5000)) < 0)
|
||||||
|
return rval;
|
||||||
|
if (buffer[1] != USB_DT_STRING) {
|
||||||
|
*buf = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if ((unsigned char) buffer[0] < rval)
|
||||||
|
rval = (unsigned char) buffer[0];
|
||||||
|
rval /= 2;
|
||||||
|
/*
|
||||||
|
* lossy conversion to ISO Latin1:
|
||||||
|
*/
|
||||||
|
for (i = 1; i < rval; i++) {
|
||||||
|
if (i > buflen) /* destination buffer overflow */
|
||||||
|
break;
|
||||||
|
buf[i - 1] = buffer[2 * i];
|
||||||
|
if (buffer[2 * i + 1] != 0) /* outside of ISO Latin1 range */
|
||||||
|
buf[i - 1] = '?';
|
||||||
|
}
|
||||||
|
buf[i - 1] = 0;
|
||||||
|
return i - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
int usbOpenDevice(usb_dev_handle ** device, int vendorID,
|
||||||
|
char *vendorNamePattern, int productID,
|
||||||
|
char *productNamePattern, char *serialNamePattern,
|
||||||
|
FILE * printMatchingDevicesFp, FILE * warningsFp)
|
||||||
|
{
|
||||||
|
struct usb_bus *bus;
|
||||||
|
struct usb_device *dev;
|
||||||
|
usb_dev_handle *handle = NULL;
|
||||||
|
int errorCode = USBOPEN_ERR_NOTFOUND;
|
||||||
|
|
||||||
|
usb_find_busses();
|
||||||
|
usb_find_devices();
|
||||||
|
for (bus = usb_get_busses(); bus; bus = bus->next) {
|
||||||
|
for (dev = bus->devices; dev; dev = dev->next) { /* iterate over
|
||||||
|
* all devices
|
||||||
|
* on all
|
||||||
|
* busses */
|
||||||
|
if ((vendorID == 0 || dev->descriptor.idVendor == vendorID)
|
||||||
|
&& (productID == 0 || dev->descriptor.idProduct == productID)) {
|
||||||
|
char vendor[256],
|
||||||
|
product[256],
|
||||||
|
serial[256];
|
||||||
|
int len;
|
||||||
|
handle = usb_open(dev); /* we need to open the device in order
|
||||||
|
* to query strings */
|
||||||
|
if (!handle) {
|
||||||
|
errorCode = USBOPEN_ERR_ACCESS;
|
||||||
|
if (warningsFp != NULL)
|
||||||
|
fprintf(warningsFp,
|
||||||
|
"Warning: cannot open VID=0x%04x PID=0x%04x: %s\n",
|
||||||
|
dev->descriptor.idVendor,
|
||||||
|
dev->descriptor.idProduct, usb_strerror());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* now check whether the names match:
|
||||||
|
*/
|
||||||
|
len = vendor[0] = 0;
|
||||||
|
if (dev->descriptor.iManufacturer > 0) {
|
||||||
|
len =
|
||||||
|
usbGetStringAscii(handle, dev->descriptor.iManufacturer,
|
||||||
|
vendor, sizeof(vendor));
|
||||||
|
}
|
||||||
|
if (len < 0) {
|
||||||
|
errorCode = USBOPEN_ERR_ACCESS;
|
||||||
|
if (warningsFp != NULL)
|
||||||
|
fprintf(warningsFp,
|
||||||
|
"Warning: cannot query manufacturer for VID=0x%04x PID=0x%04x: %s\n",
|
||||||
|
dev->descriptor.idVendor,
|
||||||
|
dev->descriptor.idProduct, usb_strerror());
|
||||||
|
} else {
|
||||||
|
errorCode = USBOPEN_ERR_NOTFOUND;
|
||||||
|
/*
|
||||||
|
* printf("seen device from vendor ->%s<-\n", vendor);
|
||||||
|
*/
|
||||||
|
if (shellStyleMatch(vendor, vendorNamePattern)) {
|
||||||
|
len = product[0] = 0;
|
||||||
|
if (dev->descriptor.iProduct > 0) {
|
||||||
|
len =
|
||||||
|
usbGetStringAscii(handle,
|
||||||
|
dev->descriptor.iProduct,
|
||||||
|
product, sizeof(product));
|
||||||
|
}
|
||||||
|
if (len < 0) {
|
||||||
|
errorCode = USBOPEN_ERR_ACCESS;
|
||||||
|
if (warningsFp != NULL)
|
||||||
|
fprintf(warningsFp,
|
||||||
|
"Warning: cannot query product for VID=0x%04x PID=0x%04x: %s\n",
|
||||||
|
dev->descriptor.idVendor,
|
||||||
|
dev->descriptor.idProduct,
|
||||||
|
usb_strerror());
|
||||||
|
} else {
|
||||||
|
errorCode = USBOPEN_ERR_NOTFOUND;
|
||||||
|
/*
|
||||||
|
* printf("seen product ->%s<-\n", product);
|
||||||
|
*/
|
||||||
|
if (shellStyleMatch(product, productNamePattern)) {
|
||||||
|
len = serial[0] = 0;
|
||||||
|
if (dev->descriptor.iSerialNumber > 0) {
|
||||||
|
len =
|
||||||
|
usbGetStringAscii(handle,
|
||||||
|
dev->descriptor.
|
||||||
|
iSerialNumber, serial,
|
||||||
|
sizeof(serial));
|
||||||
|
}
|
||||||
|
if (len < 0) {
|
||||||
|
errorCode = USBOPEN_ERR_ACCESS;
|
||||||
|
if (warningsFp != NULL)
|
||||||
|
fprintf(warningsFp,
|
||||||
|
"Warning: cannot query serial for VID=0x%04x PID=0x%04x: %s\n",
|
||||||
|
dev->descriptor.idVendor,
|
||||||
|
dev->descriptor.idProduct,
|
||||||
|
usb_strerror());
|
||||||
|
}
|
||||||
|
if (shellStyleMatch(serial, serialNamePattern)) {
|
||||||
|
if (printMatchingDevicesFp != NULL) {
|
||||||
|
if (serial[0] == 0) {
|
||||||
|
fprintf(printMatchingDevicesFp,
|
||||||
|
"VID=0x%04x PID=0x%04x vendor=\"%s\" product=\"%s\"\n",
|
||||||
|
dev->descriptor.idVendor,
|
||||||
|
dev->descriptor.idProduct,
|
||||||
|
vendor, product);
|
||||||
|
} else {
|
||||||
|
fprintf(printMatchingDevicesFp,
|
||||||
|
"VID=0x%04x PID=0x%04x vendor=\"%s\" product=\"%s\" serial=\"%s\"\n",
|
||||||
|
dev->descriptor.idVendor,
|
||||||
|
dev->descriptor.idProduct,
|
||||||
|
vendor, product, serial);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
usb_close(handle);
|
||||||
|
handle = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (handle) /* we have found a deice */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (handle != NULL) {
|
||||||
|
errorCode = 0;
|
||||||
|
*device = handle;
|
||||||
|
}
|
||||||
|
if (printMatchingDevicesFp != NULL) /* never return an error for listing
|
||||||
|
* only */
|
||||||
|
errorCode = 0;
|
||||||
|
return errorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
/* Name: opendevice.h
|
/* Name: opendevice.h
|
||||||
* Project: AVR-USB host-side library
|
* Project: V-USB host-side library
|
||||||
* Author: Christian Starkjohann
|
* Author: Christian Starkjohann
|
||||||
* Creation Date: 2008-04-10
|
* Creation Date: 2008-04-10
|
||||||
* Tabsize: 4
|
* Tabsize: 4
|
||||||
* Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
|
* Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
|
||||||
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
||||||
* This Revision: $Id: opendevice.h 692 2008-11-07 15:07:40Z cs $
|
* This Revision: $Id: opendevice.h 740 2009-04-13 18:23:31Z cs $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
244
poc/avr_usbload/commandline/snesuploader.c
Normal file
244
poc/avr_usbload/commandline/snesuploader.c
Normal file
@@ -0,0 +1,244 @@
|
|||||||
|
/*
|
||||||
|
* Name: set-led.c Project: custom-class, a basic USB example Author:
|
||||||
|
* Christian Starkjohann Creation Date: 2008-04-10 Tabsize: 4 Copyright: (c)
|
||||||
|
* 2008 by OBJECTIVE DEVELOPMENT Software GmbH License: GNU GPL v2 (see
|
||||||
|
* License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) This
|
||||||
|
* Revision: $Id: set-led.c 692 2008-11-07 15:07:40Z cs $
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* General Description: This is the host-side driver for the custom-class
|
||||||
|
* example device. It searches the USB for the LEDControl device and sends the
|
||||||
|
* requests understood by this device. This program must be linked with libusb
|
||||||
|
* on Unix and libusb-win32 on Windows. See http://libusb.sourceforge.net/ or
|
||||||
|
* http://libusb-win32.sourceforge.net/ respectively.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#define READ_BUFFER_SIZE 1024
|
||||||
|
#define SEND_BUFFER_SIZE 128
|
||||||
|
#define BUFFER_CRC (1024 * 32)
|
||||||
|
#define BANK_SIZE (1<<15)
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <usb.h> /* this is libusb */
|
||||||
|
#include "opendevice.h" /* common code moved to separate module */
|
||||||
|
|
||||||
|
#include "../requests.h" /* custom request numbers */
|
||||||
|
#include "../usbconfig.h" /* device's VID/PID and names */
|
||||||
|
|
||||||
|
|
||||||
|
void dump_packet(uint32_t addr, uint32_t len, uint8_t * packet)
|
||||||
|
{
|
||||||
|
uint16_t i,
|
||||||
|
j;
|
||||||
|
uint16_t sum = 0;
|
||||||
|
uint8_t clear = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < len; i += 16) {
|
||||||
|
|
||||||
|
sum = 0;
|
||||||
|
for (j = 0; j < 16; j++) {
|
||||||
|
sum += packet[i + j];
|
||||||
|
}
|
||||||
|
if (!sum) {
|
||||||
|
clear = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (clear) {
|
||||||
|
printf("*\n");
|
||||||
|
clear = 0;
|
||||||
|
}
|
||||||
|
printf("%08x:", addr + i);
|
||||||
|
for (j = 0; j < 16; j++) {
|
||||||
|
printf(" %02x", packet[i + j]);
|
||||||
|
}
|
||||||
|
printf(" |");
|
||||||
|
for (j = 0; j < 16; j++) {
|
||||||
|
if (packet[i + j] >= 33 && packet[i + j] <= 126)
|
||||||
|
printf("%c", packet[i + j]);
|
||||||
|
else
|
||||||
|
printf(".");
|
||||||
|
}
|
||||||
|
printf("|\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t crc_xmodem_update(uint16_t crc, uint8_t data)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
crc = crc ^ ((uint16_t) data << 8);
|
||||||
|
for (i = 0; i < 8; i++) {
|
||||||
|
if (crc & 0x8000)
|
||||||
|
crc = (crc << 1) ^ 0x1021;
|
||||||
|
else
|
||||||
|
crc <<= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return crc;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t do_crc(uint8_t * data, uint16_t size)
|
||||||
|
{
|
||||||
|
uint16_t crc = 0;
|
||||||
|
uint16_t i;
|
||||||
|
for (i = 0; i < size; i++) {
|
||||||
|
crc = crc_xmodem_update(crc, data[i]);
|
||||||
|
}
|
||||||
|
return crc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t do_crc_update(uint16_t crc, uint8_t * data, uint16_t size)
|
||||||
|
{
|
||||||
|
uint16_t i;
|
||||||
|
for (i = 0; i < size; i++)
|
||||||
|
crc = crc_xmodem_update(crc, data[i]);
|
||||||
|
return crc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void usage(char *name)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "usage:\n");
|
||||||
|
fprintf(stderr, " %s upload filename.. upload\n", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
usb_dev_handle *handle = NULL;
|
||||||
|
const unsigned char rawVid[2] = { USB_CFG_VENDOR_ID }, rawPid[2] = {
|
||||||
|
USB_CFG_DEVICE_ID};
|
||||||
|
char vendor[] = { USB_CFG_VENDOR_NAME, 0 }, product[] = {
|
||||||
|
USB_CFG_DEVICE_NAME, 0};
|
||||||
|
int cnt,
|
||||||
|
vid,
|
||||||
|
pid;
|
||||||
|
int cnt_crc = 0;
|
||||||
|
uint8_t *read_buffer;
|
||||||
|
uint8_t *crc_buffer;
|
||||||
|
uint32_t addr = 0;
|
||||||
|
uint16_t addr_lo = 0;
|
||||||
|
uint16_t addr_hi = 0;
|
||||||
|
uint16_t step = 0;
|
||||||
|
uint16_t crc = 0;
|
||||||
|
uint8_t bank = 0;
|
||||||
|
FILE *fp;
|
||||||
|
|
||||||
|
usb_init();
|
||||||
|
if (argc < 2) { /* we need at least one argument */
|
||||||
|
usage(argv[0]);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* compute VID/PID from usbconfig.h so that there is a central source
|
||||||
|
* of information
|
||||||
|
*/
|
||||||
|
vid = rawVid[1] * 256 + rawVid[0];
|
||||||
|
pid = rawPid[1] * 256 + rawPid[0];
|
||||||
|
/*
|
||||||
|
* The following function is in opendevice.c:
|
||||||
|
*/
|
||||||
|
if (usbOpenDevice(&handle, vid, vendor, pid, product, NULL, NULL, NULL) !=
|
||||||
|
0) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Could not find USB device \"%s\" with vid=0x%x pid=0x%x\n",
|
||||||
|
product, vid, pid);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
printf("Open USB device \"%s\" with vid=0x%x pid=0x%x\n", product, vid,
|
||||||
|
pid);
|
||||||
|
if (strcasecmp(argv[1], "upload") == 0) {
|
||||||
|
if (argc < 3) { /* we need at least one argument */
|
||||||
|
usage(argv[0]);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
fp = fopen(argv[2], "r");
|
||||||
|
if (fp == NULL) {
|
||||||
|
fprintf(stderr, "Cannot open file %s ", argv[2]);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
read_buffer = (unsigned char *) malloc(READ_BUFFER_SIZE);
|
||||||
|
crc_buffer = (unsigned char *) malloc(BUFFER_CRC);
|
||||||
|
memset(crc_buffer, 0, BUFFER_CRC);
|
||||||
|
addr = 0x000000;
|
||||||
|
|
||||||
|
usb_control_msg(handle,
|
||||||
|
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_OUT,
|
||||||
|
USB_UPLOAD_INIT, 0, 0, NULL, 0, 5000);
|
||||||
|
|
||||||
|
|
||||||
|
while ((cnt = fread(read_buffer, READ_BUFFER_SIZE, 1, fp)) > 0) {
|
||||||
|
for (step = 0; step < READ_BUFFER_SIZE; step += SEND_BUFFER_SIZE) {
|
||||||
|
addr_lo = addr & 0xffff;
|
||||||
|
addr_hi = (addr >> 16) & 0xff;
|
||||||
|
usb_control_msg(handle,
|
||||||
|
USB_TYPE_VENDOR | USB_RECIP_DEVICE |
|
||||||
|
USB_ENDPOINT_OUT, USB_UPLOAD_ADDR, addr_hi,
|
||||||
|
addr_lo, (char *) read_buffer + step,
|
||||||
|
SEND_BUFFER_SIZE, 5000);
|
||||||
|
#if 0
|
||||||
|
dump_packet(addr, SEND_BUFFER_SIZE, read_buffer + step);
|
||||||
|
#endif
|
||||||
|
addr += SEND_BUFFER_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(crc_buffer + cnt_crc, read_buffer, READ_BUFFER_SIZE);
|
||||||
|
cnt_crc += READ_BUFFER_SIZE;
|
||||||
|
if (cnt_crc >= BANK_SIZE) {
|
||||||
|
crc = do_crc(crc_buffer, BANK_SIZE);
|
||||||
|
printf
|
||||||
|
("Addr: 0x%06x Bank: 0x%02x HiAddr: 0x%02x LoAddr: 0x%04x Crc: 0x%04x\n",
|
||||||
|
addr, bank, addr_hi, addr_lo, crc);
|
||||||
|
memset(crc_buffer, 0, BUFFER_CRC);
|
||||||
|
bank++;
|
||||||
|
cnt_crc = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cnt = usb_control_msg(handle,
|
||||||
|
USB_TYPE_VENDOR | USB_RECIP_DEVICE |
|
||||||
|
USB_ENDPOINT_OUT, USB_CRC, addr_hi, addr_lo, NULL,
|
||||||
|
0, 5000);
|
||||||
|
|
||||||
|
|
||||||
|
if (cnt < 1) {
|
||||||
|
if (cnt < 0) {
|
||||||
|
fprintf(stderr, "USB error: %s\n", usb_strerror());
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "only %d bytes received.\n", cnt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (strcasecmp(argv[1], "crc") == 0) {
|
||||||
|
/*
|
||||||
|
* if(argc < 2){ usage(argv[0]); exit(1); }
|
||||||
|
*/
|
||||||
|
addr = 0x000000;
|
||||||
|
addr_lo = addr & 0xffff;
|
||||||
|
addr_hi = (addr >> 16) & 0xff;
|
||||||
|
printf("Request CRC for Addr: 0x%06x\n", addr);
|
||||||
|
|
||||||
|
cnt = usb_control_msg(handle,
|
||||||
|
USB_TYPE_VENDOR | USB_RECIP_DEVICE |
|
||||||
|
USB_ENDPOINT_OUT, USB_CRC_ADDR, addr_hi, addr_lo,
|
||||||
|
NULL, (1 << 15) / 4, 5000);
|
||||||
|
|
||||||
|
if (cnt < 1) {
|
||||||
|
if (cnt < 0) {
|
||||||
|
fprintf(stderr, "USB error: %s\n", usb_strerror());
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "only %d bytes received.\n", cnt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
usage(argv[0]);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
usb_close(handle);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
41
poc/avr_usbload/crc.c
Normal file
41
poc/avr_usbload/crc.c
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "crc.h"
|
||||||
|
#include "uart.h"
|
||||||
|
|
||||||
|
extern FILE uart_stdout;
|
||||||
|
|
||||||
|
uint16_t crc_xmodem_update(uint16_t crc, uint8_t data)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
crc = crc ^ ((uint16_t) data << 8);
|
||||||
|
for (i = 0; i < 8; i++) {
|
||||||
|
if (crc & 0x8000)
|
||||||
|
crc = (crc << 1) ^ 0x1021;
|
||||||
|
else
|
||||||
|
crc <<= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return crc;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t do_crc(uint8_t * data, uint16_t size)
|
||||||
|
{
|
||||||
|
uint16_t crc = 0;
|
||||||
|
uint16_t i;
|
||||||
|
for (i = 0; i < size; i++) {
|
||||||
|
crc = crc_xmodem_update(crc, data[i]);
|
||||||
|
// printf("%x : %x\n",crc,data[i]);
|
||||||
|
}
|
||||||
|
return crc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t do_crc_update(uint16_t crc, uint8_t * data, uint16_t size)
|
||||||
|
{
|
||||||
|
uint16_t i;
|
||||||
|
for (i = 0; i < size; i++)
|
||||||
|
crc = crc_xmodem_update(crc, data[i]);
|
||||||
|
return crc;
|
||||||
|
}
|
||||||
7
poc/avr_usbload/crc.h
Normal file
7
poc/avr_usbload/crc.h
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t crc_xmodem_update (uint16_t crc, uint8_t data);
|
||||||
|
uint16_t do_crc(uint8_t * data,uint16_t size);
|
||||||
|
uint16_t do_crc_update(uint16_t crc,uint8_t * data,uint16_t size);
|
||||||
44
poc/avr_usbload/debug.c
Normal file
44
poc/avr_usbload/debug.c
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "debug.h"
|
||||||
|
#include "uart.h"
|
||||||
|
|
||||||
|
|
||||||
|
extern FILE uart_stdout;
|
||||||
|
|
||||||
|
void dump_packet(uint32_t addr, uint32_t len, uint8_t * packet)
|
||||||
|
{
|
||||||
|
uint16_t i,
|
||||||
|
j;
|
||||||
|
uint16_t sum = 0;
|
||||||
|
uint8_t clear = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < len; i += 16) {
|
||||||
|
|
||||||
|
sum = 0;
|
||||||
|
for (j = 0; j < 16; j++) {
|
||||||
|
sum += packet[i + j];
|
||||||
|
}
|
||||||
|
if (!sum) {
|
||||||
|
clear = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (clear) {
|
||||||
|
printf("*\n");
|
||||||
|
clear = 0;
|
||||||
|
}
|
||||||
|
printf("%08lx:", addr + i);
|
||||||
|
for (j = 0; j < 16; j++) {
|
||||||
|
printf(" %02x", packet[i + j]);
|
||||||
|
}
|
||||||
|
printf(" |");
|
||||||
|
for (j = 0; j < 16; j++) {
|
||||||
|
if (packet[i + j] >= 33 && packet[i + j] <= 126)
|
||||||
|
printf("%c", packet[i + j]);
|
||||||
|
else
|
||||||
|
printf(".");
|
||||||
|
}
|
||||||
|
printf("|\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
5
poc/avr_usbload/debug.h
Normal file
5
poc/avr_usbload/debug.h
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
void dump_packet(uint32_t addr,uint32_t len,uint8_t *packet);
|
||||||
|
|
||||||
28
poc/avr_usbload/fifo.c
Normal file
28
poc/avr_usbload/fifo.c
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#include "fifo.h"
|
||||||
|
|
||||||
|
void fifo_init(fifo_t * f, uint8_t * buffer, const uint8_t size)
|
||||||
|
{
|
||||||
|
f->count = 0;
|
||||||
|
f->pread = f->pwrite = buffer;
|
||||||
|
f->read2end = f->write2end = f->size = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t fifo_put(fifo_t * f, const uint8_t data)
|
||||||
|
{
|
||||||
|
return _inline_fifo_put(f, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t fifo_get_wait(fifo_t * f)
|
||||||
|
{
|
||||||
|
while (!f->count);
|
||||||
|
|
||||||
|
return _inline_fifo_get(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
int fifo_get_nowait(fifo_t * f)
|
||||||
|
{
|
||||||
|
if (!f->count)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return (int) _inline_fifo_get(f);
|
||||||
|
}
|
||||||
69
poc/avr_usbload/fifo.h
Normal file
69
poc/avr_usbload/fifo.h
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
#ifndef _FIFO_H_
|
||||||
|
#define _FIFO_H_
|
||||||
|
|
||||||
|
#include <avr/io.h>
|
||||||
|
#include <avr/interrupt.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t volatile count; // # Zeichen im Puffer
|
||||||
|
uint8_t size; // Puffer-Größe
|
||||||
|
uint8_t *pread; // Lesezeiger
|
||||||
|
uint8_t *pwrite; // Schreibzeiger
|
||||||
|
uint8_t read2end, write2end; // # Zeichen bis zum Überlauf Lese-/Schreibzeiger
|
||||||
|
} fifo_t;
|
||||||
|
|
||||||
|
extern void fifo_init(fifo_t *, uint8_t * buf, const uint8_t size);
|
||||||
|
extern uint8_t fifo_put(fifo_t *, const uint8_t data);
|
||||||
|
extern uint8_t fifo_get_wait(fifo_t *);
|
||||||
|
extern int fifo_get_nowait(fifo_t *);
|
||||||
|
|
||||||
|
static inline uint8_t _inline_fifo_put(fifo_t * f, const uint8_t data)
|
||||||
|
{
|
||||||
|
if (f->count >= f->size)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
uint8_t *pwrite = f->pwrite;
|
||||||
|
|
||||||
|
*(pwrite++) = data;
|
||||||
|
|
||||||
|
uint8_t write2end = f->write2end;
|
||||||
|
|
||||||
|
if (--write2end == 0) {
|
||||||
|
write2end = f->size;
|
||||||
|
pwrite -= write2end;
|
||||||
|
}
|
||||||
|
|
||||||
|
f->write2end = write2end;
|
||||||
|
f->pwrite = pwrite;
|
||||||
|
|
||||||
|
uint8_t sreg = SREG;
|
||||||
|
cli();
|
||||||
|
f->count++;
|
||||||
|
SREG = sreg;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint8_t _inline_fifo_get(fifo_t * f)
|
||||||
|
{
|
||||||
|
uint8_t *pread = f->pread;
|
||||||
|
uint8_t data = *(pread++);
|
||||||
|
uint8_t read2end = f->read2end;
|
||||||
|
|
||||||
|
if (--read2end == 0) {
|
||||||
|
read2end = f->size;
|
||||||
|
pread -= read2end;
|
||||||
|
}
|
||||||
|
|
||||||
|
f->pread = pread;
|
||||||
|
f->read2end = read2end;
|
||||||
|
|
||||||
|
uint8_t sreg = SREG;
|
||||||
|
cli();
|
||||||
|
f->count--;
|
||||||
|
SREG = sreg;
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* _FIFO_H_ */
|
||||||
213
poc/avr_usbload/main.c
Normal file
213
poc/avr_usbload/main.c
Normal file
@@ -0,0 +1,213 @@
|
|||||||
|
#include <avr/io.h>
|
||||||
|
#include <avr/wdt.h>
|
||||||
|
#include <avr/interrupt.h> /* for sei() */
|
||||||
|
#include <util/delay.h> /* for _delay_ms() */
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <avr/pgmspace.h> /* required by usbdrv.h */
|
||||||
|
|
||||||
|
#include "usbdrv.h"
|
||||||
|
#include "oddebug.h" /* This is also an example for using debug
|
||||||
|
* macros */
|
||||||
|
#include "requests.h" /* The custom request numbers we use */
|
||||||
|
#include "uart.h"
|
||||||
|
#include "sram.h"
|
||||||
|
#include "debug.h"
|
||||||
|
#include "crc.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define REQ_IDLE 0
|
||||||
|
#define REQ_UPLOAD 1
|
||||||
|
#define RES_CRC 2
|
||||||
|
#define BUFFER_SIZE 256
|
||||||
|
|
||||||
|
extern FILE uart_stdout;
|
||||||
|
|
||||||
|
uint8_t read_buffer[BUFFER_SIZE];
|
||||||
|
uint32_t req_addr = 0;
|
||||||
|
uint32_t req_size;
|
||||||
|
uint8_t req_bank;
|
||||||
|
uint32_t req_bank_size;
|
||||||
|
uint8_t req_state = REQ_IDLE;
|
||||||
|
uint8_t rx_remaining = 0;
|
||||||
|
uint8_t tx_remaining = 0;
|
||||||
|
uint16_t sync_errors = 0;
|
||||||
|
uint8_t tx_buffer[32];
|
||||||
|
uint8_t data_buffer[4];
|
||||||
|
uint32_t addr;
|
||||||
|
|
||||||
|
void crc_check_memory(uint32_t top_addr)
|
||||||
|
{
|
||||||
|
uint16_t crc = 0;
|
||||||
|
uint32_t addr;
|
||||||
|
req_bank = 0;
|
||||||
|
for (addr = 0x000000; addr < top_addr; addr += BUFFER_SIZE) {
|
||||||
|
sram_read_buffer(addr, read_buffer, BUFFER_SIZE);
|
||||||
|
crc = do_crc_update(crc, read_buffer, BUFFER_SIZE);
|
||||||
|
if (addr && addr % 32768 == 0) {
|
||||||
|
printf("crc_check_memory: req_bank: 0x%x Addr: 0x%lx CRC: %x\n",
|
||||||
|
req_bank, addr, crc);
|
||||||
|
req_bank++;
|
||||||
|
crc = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void crc_check_memory_
|
||||||
|
range(uint32_t start_addr, uint32_t size)
|
||||||
|
{
|
||||||
|
uint16_t crc = 0;
|
||||||
|
uint32_t addr;
|
||||||
|
req_bank = 0;
|
||||||
|
for (addr = start_addr; addr < start_addr + size; addr += BUFFER_SIZE) {
|
||||||
|
sram_read_buffer(addr, read_buffer, BUFFER_SIZE);
|
||||||
|
crc = do_crc_update(crc, read_buffer, BUFFER_SIZE);
|
||||||
|
}
|
||||||
|
tx_buffer[0] = crc & 0xff;
|
||||||
|
tx_buffer[1] = (crc >> 8) & 0xff;
|
||||||
|
printf("crc_check_memory_range: Addr: 0x%lx CRC: %x\n", addr, crc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
usbMsgLen_t usbFunctionSetup(uchar data[8])
|
||||||
|
{
|
||||||
|
|
||||||
|
usbRequest_t *rq = (void *) data;
|
||||||
|
uint8_t ret_len = 0;
|
||||||
|
if (rq->bRequest == USB_UPLOAD_INIT) {
|
||||||
|
req_bank = 0;
|
||||||
|
rx_remaining = 0;
|
||||||
|
req_bank_size = 1 << rq->wValue.word;
|
||||||
|
sync_errors = 0;
|
||||||
|
printf("USB_UPLOAD_INIT: bank size %li\n", req_bank_size);
|
||||||
|
} else if (rq->bRequest == USB_UPLOAD_ADDR) { /* echo -- used for
|
||||||
|
* reliability tests */
|
||||||
|
req_state = REQ_UPLOAD;
|
||||||
|
req_addr = rq->wValue.word;
|
||||||
|
req_addr = req_addr << 16;
|
||||||
|
req_addr = req_addr | rq->wIndex.word;
|
||||||
|
if (rx_remaining) {
|
||||||
|
sync_errors++;
|
||||||
|
printf
|
||||||
|
("USB_UPLOAD_ADDR: Out of sync Addr=0x%lx remain=%i packet=%i sync_error=%i\n",
|
||||||
|
req_addr, rx_remaining, rq->wLength.word, sync_errors);
|
||||||
|
ret_len = 0;
|
||||||
|
}
|
||||||
|
rx_remaining = rq->wLength.word;
|
||||||
|
ret_len = 0xff;
|
||||||
|
if (req_addr && req_addr % req_bank_size == 0) {
|
||||||
|
printf("USB_UPLOAD_ADDR: req_bank: 0x%x Addr: 0x%08lx \n",
|
||||||
|
req_bank, req_addr);
|
||||||
|
req_bank++;
|
||||||
|
}
|
||||||
|
ret_len = 0xff;
|
||||||
|
} else if (rq->bRequest == USB_DOWNLOAD_INIT) {
|
||||||
|
printf("USB_DOWNLOAD_INIT\n");
|
||||||
|
} else if (rq->bRequest == USB_DOWNLOAD_ADDR) {
|
||||||
|
printf("USB_DOWNLOAD_ADDR\n");
|
||||||
|
} else if (rq->bRequest == USB_CRC) {
|
||||||
|
req_addr = rq->wValue.word;
|
||||||
|
req_addr = req_addr << 16;
|
||||||
|
req_addr = req_addr | rq->wIndex.word;
|
||||||
|
printf("USB_CRC: Addr 0x%lx \n", req_addr);
|
||||||
|
cli();
|
||||||
|
crc_check_memory(req_addr);
|
||||||
|
sei();
|
||||||
|
} else if (rq->bRequest == USB_CRC_ADDR) {
|
||||||
|
req_addr = rq->wValue.word;
|
||||||
|
req_addr = req_addr << 16;
|
||||||
|
req_addr = req_addr | rq->wIndex.word;
|
||||||
|
printf("USB_CRC_ADDR: Addr: 0x%lx Size: %i\n", req_addr,
|
||||||
|
rq->wLength.word);
|
||||||
|
req_size = rq->wLength.word;
|
||||||
|
req_size = req_size << 2;
|
||||||
|
tx_remaining = 2;
|
||||||
|
printf("USB_CRC_ADDR: Addr: 0x%lx Size: %li\n", req_addr, req_size);
|
||||||
|
cli();
|
||||||
|
// crc_check_memory_range(req_addr,req_size);
|
||||||
|
sei();
|
||||||
|
ret_len = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
usbMsgPtr = data_buffer;
|
||||||
|
return ret_len; /* default for not implemented requests: return
|
||||||
|
* no data back to host */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t usbFunctionWrite(uint8_t * data, uint8_t len)
|
||||||
|
{
|
||||||
|
if (len > rx_remaining) {
|
||||||
|
printf("usbFunctionWrite more data than expected remain: %i len: %i\n",
|
||||||
|
rx_remaining, len);
|
||||||
|
len = rx_remaining;
|
||||||
|
}
|
||||||
|
if (req_state == REQ_UPLOAD) {
|
||||||
|
|
||||||
|
rx_remaining -= len;
|
||||||
|
#if 1
|
||||||
|
printf("usbFunctionWrite addr: 0x%08lx len: %i rx_remaining=%i\n",
|
||||||
|
req_addr, len, rx_remaining);
|
||||||
|
#endif
|
||||||
|
cli();
|
||||||
|
sram_copy(req_addr, data, len);
|
||||||
|
sei();
|
||||||
|
req_addr += len;
|
||||||
|
}
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t usbFunctionRead(uint8_t * data, uint8_t len)
|
||||||
|
{
|
||||||
|
uint8_t i;
|
||||||
|
if (len > tx_remaining)
|
||||||
|
len = tx_remaining;
|
||||||
|
tx_remaining -= len;
|
||||||
|
#if 1
|
||||||
|
printf("usbFunctionRead len=%i tx_remaining=%i \n", len, tx_remaining);
|
||||||
|
#endif
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
*data = tx_buffer[len];
|
||||||
|
data++;
|
||||||
|
}
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
uint8_t i;
|
||||||
|
wdt_enable(WDTO_1S);
|
||||||
|
uart_init();
|
||||||
|
stdout = &uart_stdout;
|
||||||
|
sram_init();
|
||||||
|
printf("SRAM Init\n");
|
||||||
|
spi_init();
|
||||||
|
printf("SPI Init\n");
|
||||||
|
usbInit();
|
||||||
|
printf("USB Init\n");
|
||||||
|
usbDeviceDisconnect(); /* enforce re-enumeration, do this while
|
||||||
|
* interrupts are disabled! */
|
||||||
|
printf("USB disconnect\n");
|
||||||
|
i = 10;
|
||||||
|
while (--i) { /* fake USB disconnect for > 250 ms */
|
||||||
|
wdt_reset();
|
||||||
|
_delay_ms(1);
|
||||||
|
}
|
||||||
|
usbDeviceConnect();
|
||||||
|
printf("USB connect\n");
|
||||||
|
sei();
|
||||||
|
printf("USB poll\n");
|
||||||
|
for (;;) { /* main event loop */
|
||||||
|
wdt_reset();
|
||||||
|
usbPoll();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
26
poc/avr_usbload/requests.h
Normal file
26
poc/avr_usbload/requests.h
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
/* Name: requests.h
|
||||||
|
* Project: custom-class, a basic USB example
|
||||||
|
* Author: Christian Starkjohann
|
||||||
|
* Creation Date: 2008-04-09
|
||||||
|
* Tabsize: 4
|
||||||
|
* Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
|
||||||
|
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
||||||
|
* This Revision: $Id: requests.h 692 2008-11-07 15:07:40Z cs $
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* This header is shared between the firmware and the host software. It
|
||||||
|
* defines the USB request numbers (and optionally data types) used to
|
||||||
|
* communicate between the host and the device.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __REQUESTS_H_INCLUDED__
|
||||||
|
#define __REQUESTS_H_INCLUDED__
|
||||||
|
|
||||||
|
#define USB_UPLOAD_INIT 0
|
||||||
|
#define USB_UPLOAD_ADDR 1
|
||||||
|
#define USB_DOWNLOAD_INIT 2
|
||||||
|
#define USB_DOWNLOAD_ADDR 3
|
||||||
|
#define USB_CRC 4
|
||||||
|
#define USB_CRC_ADDR 5
|
||||||
|
|
||||||
|
#endif /* __REQUESTS_H_INCLUDED__ */
|
||||||
172
poc/avr_usbload/sram.c
Normal file
172
poc/avr_usbload/sram.c
Normal file
@@ -0,0 +1,172 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <avr/io.h>
|
||||||
|
|
||||||
|
#include "sram.h"
|
||||||
|
#include "uart.h"
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
|
void spi_init(void)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Set MOSI and SCK output, all others input
|
||||||
|
*/
|
||||||
|
SPI_DIR |= ((1 << S_MOSI) | (1 << S_SCK) | (1 << S_LATCH));
|
||||||
|
SPI_DIR &= ~(1 << S_MISO);
|
||||||
|
SPI_PORT |= (1 << S_MISO);
|
||||||
|
/*
|
||||||
|
* Enable SPI, Master
|
||||||
|
*/
|
||||||
|
SPCR = ((1 << SPE) | (1 << MSTR));
|
||||||
|
}
|
||||||
|
|
||||||
|
void spi_master_transmit(unsigned char cData)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Start transmission
|
||||||
|
*/
|
||||||
|
SPDR = cData;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wait for transmission complete
|
||||||
|
*/
|
||||||
|
while (!(SPSR & (1 << SPIF)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void sram_set_addr(uint32_t addr)
|
||||||
|
{
|
||||||
|
spi_master_transmit((uint8_t) (addr >> 16));
|
||||||
|
spi_master_transmit((uint8_t) (addr >> 8));
|
||||||
|
spi_master_transmit((uint8_t) (addr >> 0));
|
||||||
|
|
||||||
|
LATCH_PORT |= (1 << S_LATCH);
|
||||||
|
LATCH_PORT &= ~(1 << S_LATCH);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t sram_read(uint32_t addr)
|
||||||
|
{
|
||||||
|
uint8_t byte;
|
||||||
|
|
||||||
|
RAM_DIR = 0x00;
|
||||||
|
RAM_PORT = 0xff;
|
||||||
|
|
||||||
|
CTRL_PORT |= (1 << R_RD);
|
||||||
|
CTRL_PORT |= (1 << R_WR);
|
||||||
|
|
||||||
|
spi_master_transmit((uint8_t) (addr >> 16));
|
||||||
|
spi_master_transmit((uint8_t) (addr >> 8));
|
||||||
|
spi_master_transmit((uint8_t) (addr >> 0));
|
||||||
|
|
||||||
|
LATCH_PORT |= (1 << S_LATCH);
|
||||||
|
LATCH_PORT &= ~(1 << S_LATCH);
|
||||||
|
CTRL_PORT &= ~(1 << R_RD);
|
||||||
|
|
||||||
|
asm volatile ("nop");
|
||||||
|
asm volatile ("nop");
|
||||||
|
asm volatile ("nop");
|
||||||
|
asm volatile ("nop");
|
||||||
|
asm volatile ("nop");
|
||||||
|
asm volatile ("nop");
|
||||||
|
asm volatile ("nop");
|
||||||
|
asm volatile ("nop");
|
||||||
|
|
||||||
|
byte = RAM_REG;
|
||||||
|
CTRL_PORT |= (1 << R_RD);
|
||||||
|
RAM_DIR = 0x00;
|
||||||
|
RAM_PORT = 0x00;
|
||||||
|
return byte;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sram_write(uint32_t addr, uint8_t data)
|
||||||
|
{
|
||||||
|
RAM_DIR = 0xff;
|
||||||
|
|
||||||
|
CTRL_PORT |= (1 << R_RD);
|
||||||
|
CTRL_PORT |= (1 << R_WR);
|
||||||
|
|
||||||
|
spi_master_transmit((uint8_t) (addr >> 16));
|
||||||
|
spi_master_transmit((uint8_t) (addr >> 8));
|
||||||
|
spi_master_transmit((uint8_t) (addr >> 0));
|
||||||
|
|
||||||
|
LATCH_PORT |= (1 << S_LATCH);
|
||||||
|
LATCH_PORT &= ~(1 << S_LATCH);
|
||||||
|
|
||||||
|
|
||||||
|
CTRL_PORT &= ~(1 << R_WR);
|
||||||
|
|
||||||
|
RAM_PORT = data;
|
||||||
|
CTRL_PORT |= (1 << R_WR);
|
||||||
|
|
||||||
|
RAM_DIR = 0x00;
|
||||||
|
RAM_PORT = 0x00;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sram_init(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
RAM_DIR = 0x00;
|
||||||
|
RAM_PORT = 0x00;
|
||||||
|
|
||||||
|
CTRL_DIR |= ((1 << R_WR) | (1 << R_RD));
|
||||||
|
CTRL_PORT |= (1 << R_RD);
|
||||||
|
CTRL_PORT |= (1 << R_WR);
|
||||||
|
|
||||||
|
LED_PORT |= (1 << D_LED0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sram_snes_mode01(void)
|
||||||
|
{
|
||||||
|
CTRL_PORT |= (1 << R_WR);
|
||||||
|
CTRL_PORT &= ~(1 << R_RD);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sram_snes_mode02(void)
|
||||||
|
{
|
||||||
|
CTRL_DIR |= (1 << R_WR);
|
||||||
|
CTRL_PORT |= (1 << R_WR);
|
||||||
|
// CTRL_PORT &= ~(1<<R_RD);
|
||||||
|
CTRL_DIR &= ~(1 << R_RD);
|
||||||
|
CTRL_PORT &= ~(1 << R_RD);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void sram_clear(uint32_t addr, uint32_t len)
|
||||||
|
{
|
||||||
|
|
||||||
|
uint32_t i;
|
||||||
|
for (i = addr; i < (addr + len); i++) {
|
||||||
|
if (0 == i % 0xfff)
|
||||||
|
printf("sram_clear %lx\n\r", i);
|
||||||
|
sram_write(i, 0x00);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void sram_copy(uint32_t addr, uint8_t * src, uint32_t len)
|
||||||
|
{
|
||||||
|
|
||||||
|
uint32_t i;
|
||||||
|
uint8_t *ptr = src;
|
||||||
|
for (i = addr; i < (addr + len); i++)
|
||||||
|
sram_write(i, *ptr++);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sram_read_buffer(uint32_t addr, uint8_t * dst, uint32_t len)
|
||||||
|
{
|
||||||
|
|
||||||
|
uint32_t i;
|
||||||
|
uint8_t *ptr = dst;
|
||||||
|
for (i = addr; i < (addr + len); i++) {
|
||||||
|
*ptr = sram_read(i);
|
||||||
|
ptr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
uint8_t sram_check(uint8_t * buffer, uint32_t len)
|
||||||
|
{
|
||||||
|
uint16_t cnt;
|
||||||
|
for (cnt = 0; cnt < len; cnt++)
|
||||||
|
if (buffer[cnt])
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
51
poc/avr_usbload/sram.h
Normal file
51
poc/avr_usbload/sram.h
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <avr/io.h>
|
||||||
|
|
||||||
|
|
||||||
|
//SREG defines
|
||||||
|
#define S_MOSI PB5
|
||||||
|
#define S_MISO PB6
|
||||||
|
#define S_SCK PB7
|
||||||
|
#define S_LATCH PB4
|
||||||
|
|
||||||
|
//DEBUG defines
|
||||||
|
#define D_LED0 PD6
|
||||||
|
|
||||||
|
//SRAM defines
|
||||||
|
#define R_WR PB1
|
||||||
|
#define R_RD PB0
|
||||||
|
|
||||||
|
#define RAM_PORT PORTA
|
||||||
|
#define RAM_DIR DDRA
|
||||||
|
#define RAM_REG PINA
|
||||||
|
|
||||||
|
#define CTRL_PORT PORTB
|
||||||
|
#define CTRL_DIR DDRB
|
||||||
|
#define LATCH_PORT PORTB
|
||||||
|
#define LATCH_DIR DDRB
|
||||||
|
|
||||||
|
#define SPI_PORT PORTB
|
||||||
|
#define SPI_DIR DDRB
|
||||||
|
|
||||||
|
#define LED_PORT PORTD
|
||||||
|
#define LED_DIR DDRD
|
||||||
|
|
||||||
|
#define ROMSIZE 4
|
||||||
|
#define BLOCKS (ROMSIZE << 8)
|
||||||
|
#define MEMSIZE 0x80000
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void spi_init(void);
|
||||||
|
void spi_master_transmit(unsigned char cData);
|
||||||
|
void sram_set_addr(uint32_t addr);
|
||||||
|
uint8_t sram_read(uint32_t addr);
|
||||||
|
void sram_write(uint32_t addr, uint8_t data);
|
||||||
|
void sram_init(void);
|
||||||
|
void sram_snes_mode01(void);
|
||||||
|
void sram_snes_mode02(void);
|
||||||
|
void sram_clear(uint32_t addr, uint32_t len);
|
||||||
|
void sram_copy(uint32_t addr,uint8_t *src, uint32_t len);
|
||||||
|
void sram_read_buffer(uint32_t addr,uint8_t *dst, uint32_t len);
|
||||||
|
uint8_t sram_check(uint8_t *buffer, uint32_t len);
|
||||||
77
poc/avr_usbload/uart.c
Normal file
77
poc/avr_usbload/uart.c
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
#include <avr/io.h>
|
||||||
|
#include <avr/interrupt.h>
|
||||||
|
#include <avr/pgmspace.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "uart.h"
|
||||||
|
#include "fifo.h"
|
||||||
|
|
||||||
|
volatile struct {
|
||||||
|
uint8_t tmr_int:1;
|
||||||
|
uint8_t adc_int:1;
|
||||||
|
uint8_t rx_int:1;
|
||||||
|
} intflags;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* * Last character read from the UART.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
volatile char rxbuff;
|
||||||
|
|
||||||
|
|
||||||
|
FILE uart_stdout = FDEV_SETUP_STREAM(uart_stream, NULL, _FDEV_SETUP_WRITE);
|
||||||
|
|
||||||
|
void uart_init(void)
|
||||||
|
{
|
||||||
|
UCSRA = _BV(U2X); /* improves baud rate error @ F_CPU = 1 MHz */
|
||||||
|
UCSRB = _BV(TXEN) | _BV(RXEN) | _BV(RXCIE); /* tx/rx enable, rx complete
|
||||||
|
* intr */
|
||||||
|
UBRRL = (F_CPU / (8 * 115200UL)) - 1; /* 9600 Bd */
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ISR(USART_RXC_vect)
|
||||||
|
{
|
||||||
|
uint8_t c;
|
||||||
|
c = UDR;
|
||||||
|
if (bit_is_clear(UCSRA, FE)) {
|
||||||
|
rxbuff = c;
|
||||||
|
intflags.rx_int = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void uart_putc(uint8_t c)
|
||||||
|
{
|
||||||
|
loop_until_bit_is_set(UCSRA, UDRE);
|
||||||
|
UDR = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void uart_puts(const char *s)
|
||||||
|
{
|
||||||
|
do {
|
||||||
|
uart_putc(*s);
|
||||||
|
}
|
||||||
|
while (*s++);
|
||||||
|
}
|
||||||
|
|
||||||
|
void uart_puts_P(PGM_P s)
|
||||||
|
{
|
||||||
|
while (1) {
|
||||||
|
unsigned char c = pgm_read_byte(s);
|
||||||
|
s++;
|
||||||
|
if ('\0' == c)
|
||||||
|
break;
|
||||||
|
uart_putc(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int uart_stream(char c, FILE * stream)
|
||||||
|
{
|
||||||
|
if (c == '\n')
|
||||||
|
uart_putc('\r');
|
||||||
|
loop_until_bit_is_set(UCSRA, UDRE);
|
||||||
|
UDR = c;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
18
poc/avr_usbload/uart.h
Normal file
18
poc/avr_usbload/uart.h
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
#ifndef _UART_H_
|
||||||
|
#define _UART_H_
|
||||||
|
|
||||||
|
#define CR "\r\n"
|
||||||
|
|
||||||
|
|
||||||
|
#include <avr/io.h>
|
||||||
|
#include <avr/pgmspace.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
void uart_init(void);
|
||||||
|
void uart_putc(const uint8_t);
|
||||||
|
void uart_puts(const char *s);
|
||||||
|
void uart_puts_P(PGM_P s);
|
||||||
|
static int uart_stream(char c, FILE *stream);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* _UART_H_ */
|
||||||
351
poc/avr_usbload/usbconfig.h
Normal file
351
poc/avr_usbload/usbconfig.h
Normal file
@@ -0,0 +1,351 @@
|
|||||||
|
/* Name: usbconfig.h
|
||||||
|
* Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
|
||||||
|
* Author: Christian Starkjohann
|
||||||
|
* Creation Date: 2005-04-01
|
||||||
|
* Tabsize: 4
|
||||||
|
* Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
|
||||||
|
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
||||||
|
* This Revision: $Id: usbconfig-prototype.h 740 2009-04-13 18:23:31Z cs $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __usbconfig_h_included__
|
||||||
|
#define __usbconfig_h_included__
|
||||||
|
|
||||||
|
/*
|
||||||
|
General Description:
|
||||||
|
This file is an example configuration (with inline documentation) for the USB
|
||||||
|
driver. It configures V-USB for USB D+ connected to Port D bit 2 (which is
|
||||||
|
also hardware interrupt 0 on many devices) and USB D- to Port D bit 4. You may
|
||||||
|
wire the lines to any other port, as long as D+ is also wired to INT0 (or any
|
||||||
|
other hardware interrupt, as long as it is the highest level interrupt, see
|
||||||
|
section at the end of this file).
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* ---------------------------- Hardware Config ---------------------------- */
|
||||||
|
|
||||||
|
#define USB_CFG_IOPORTNAME D
|
||||||
|
/* This is the port where the USB bus is connected. When you configure it to
|
||||||
|
* "B", the registers PORTB, PINB and DDRB will be used.
|
||||||
|
*/
|
||||||
|
#define USB_CFG_DMINUS_BIT 4
|
||||||
|
/* This is the bit number in USB_CFG_IOPORT where the USB D- line is connected.
|
||||||
|
* This may be any bit in the port.
|
||||||
|
*/
|
||||||
|
#define USB_CFG_DPLUS_BIT 2
|
||||||
|
/* This is the bit number in USB_CFG_IOPORT where the USB D+ line is connected.
|
||||||
|
* This may be any bit in the port. Please note that D+ must also be connected
|
||||||
|
* to interrupt pin INT0! [You can also use other interrupts, see section
|
||||||
|
* "Optional MCU Description" below, or you can connect D- to the interrupt, as
|
||||||
|
* it is required if you use the USB_COUNT_SOF feature. If you use D- for the
|
||||||
|
* interrupt, the USB interrupt will also be triggered at Start-Of-Frame
|
||||||
|
* markers every millisecond.]
|
||||||
|
*/
|
||||||
|
#define USB_CFG_CLOCK_KHZ (F_CPU/1000)
|
||||||
|
/* Clock rate of the AVR in kHz. Legal values are 12000, 12800, 15000, 16000,
|
||||||
|
* 16500 and 20000. The 12.8 MHz and 16.5 MHz versions of the code require no
|
||||||
|
* crystal, they tolerate +/- 1% deviation from the nominal frequency. All
|
||||||
|
* other rates require a precision of 2000 ppm and thus a crystal!
|
||||||
|
* Default if not specified: 12 MHz
|
||||||
|
*/
|
||||||
|
#define USB_CFG_CHECK_CRC 0
|
||||||
|
/* Define this to 1 if you want that the driver checks integrity of incoming
|
||||||
|
* data packets (CRC checks). CRC checks cost quite a bit of code size and are
|
||||||
|
* currently only available for 18 MHz crystal clock. You must choose
|
||||||
|
* USB_CFG_CLOCK_KHZ = 18000 if you enable this option.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* ----------------------- Optional Hardware Config ------------------------ */
|
||||||
|
|
||||||
|
#define USB_CFG_PULLUP_IOPORTNAME D
|
||||||
|
/* If you connect the 1.5k pullup resistor from D- to a port pin instead of
|
||||||
|
* V+, you can connect and disconnect the device from firmware by calling
|
||||||
|
* the macros usbDeviceConnect() and usbDeviceDisconnect() (see usbdrv.h).
|
||||||
|
* This constant defines the port on which the pullup resistor is connected.
|
||||||
|
*/
|
||||||
|
#define USB_CFG_PULLUP_BIT 6
|
||||||
|
/* This constant defines the bit number in USB_CFG_PULLUP_IOPORT (defined
|
||||||
|
* above) where the 1.5k pullup resistor is connected. See description
|
||||||
|
* above for details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* --------------------------- Functional Range ---------------------------- */
|
||||||
|
|
||||||
|
#define USB_CFG_HAVE_INTRIN_ENDPOINT 0
|
||||||
|
/* Define this to 1 if you want to compile a version with two endpoints: The
|
||||||
|
* default control endpoint 0 and an interrupt-in endpoint (any other endpoint
|
||||||
|
* number).
|
||||||
|
*/
|
||||||
|
#define USB_CFG_HAVE_INTRIN_ENDPOINT3 0
|
||||||
|
/* Define this to 1 if you want to compile a version with three endpoints: The
|
||||||
|
* default control endpoint 0, an interrupt-in endpoint 3 (or the number
|
||||||
|
* configured below) and a catch-all default interrupt-in endpoint as above.
|
||||||
|
* You must also define USB_CFG_HAVE_INTRIN_ENDPOINT to 1 for this feature.
|
||||||
|
*/
|
||||||
|
#define USB_CFG_EP3_NUMBER 3
|
||||||
|
/* If the so-called endpoint 3 is used, it can now be configured to any other
|
||||||
|
* endpoint number (except 0) with this macro. Default if undefined is 3.
|
||||||
|
*/
|
||||||
|
/* #define USB_INITIAL_DATATOKEN USBPID_DATA1 */
|
||||||
|
/* The above macro defines the startup condition for data toggling on the
|
||||||
|
* interrupt/bulk endpoints 1 and 3. Defaults to USBPID_DATA1.
|
||||||
|
* Since the token is toggled BEFORE sending any data, the first packet is
|
||||||
|
* sent with the oposite value of this configuration!
|
||||||
|
*/
|
||||||
|
#define USB_CFG_IMPLEMENT_HALT 0
|
||||||
|
/* Define this to 1 if you also want to implement the ENDPOINT_HALT feature
|
||||||
|
* for endpoint 1 (interrupt endpoint). Although you may not need this feature,
|
||||||
|
* it is required by the standard. We have made it a config option because it
|
||||||
|
* bloats the code considerably.
|
||||||
|
*/
|
||||||
|
#define USB_CFG_SUPPRESS_INTR_CODE 1
|
||||||
|
/* Define this to 1 if you want to declare interrupt-in endpoints, but don't
|
||||||
|
* want to send any data over them. If this macro is defined to 1, functions
|
||||||
|
* usbSetInterrupt() and usbSetInterrupt3() are omitted. This is useful if
|
||||||
|
* you need the interrupt-in endpoints in order to comply to an interface
|
||||||
|
* (e.g. HID), but never want to send any data. This option saves a couple
|
||||||
|
* of bytes in flash memory and the transmit buffers in RAM.
|
||||||
|
*/
|
||||||
|
#define USB_CFG_INTR_POLL_INTERVAL 10
|
||||||
|
/* If you compile a version with endpoint 1 (interrupt-in), this is the poll
|
||||||
|
* interval. The value is in milliseconds and must not be less than 10 ms for
|
||||||
|
* low speed devices.
|
||||||
|
*/
|
||||||
|
#define USB_CFG_IS_SELF_POWERED 0
|
||||||
|
/* Define this to 1 if the device has its own power supply. Set it to 0 if the
|
||||||
|
* device is powered from the USB bus.
|
||||||
|
*/
|
||||||
|
#define USB_CFG_MAX_BUS_POWER 40
|
||||||
|
/* Set this variable to the maximum USB bus power consumption of your device.
|
||||||
|
* The value is in milliamperes. [It will be divided by two since USB
|
||||||
|
* communicates power requirements in units of 2 mA.]
|
||||||
|
*/
|
||||||
|
#define USB_CFG_IMPLEMENT_FN_WRITE 1
|
||||||
|
/* Set this to 1 if you want usbFunctionWrite() to be called for control-out
|
||||||
|
* transfers. Set it to 0 if you don't need it and want to save a couple of
|
||||||
|
* bytes.
|
||||||
|
*/
|
||||||
|
#define USB_CFG_IMPLEMENT_FN_READ 0
|
||||||
|
/* Set this to 1 if you need to send control replies which are generated
|
||||||
|
* "on the fly" when usbFunctionRead() is called. If you only want to send
|
||||||
|
* data from a static buffer, set it to 0 and return the data from
|
||||||
|
* usbFunctionSetup(). This saves a couple of bytes.
|
||||||
|
*/
|
||||||
|
#define USB_CFG_IMPLEMENT_FN_WRITEOUT 0
|
||||||
|
/* Define this to 1 if you want to use interrupt-out (or bulk out) endpoints.
|
||||||
|
* You must implement the function usbFunctionWriteOut() which receives all
|
||||||
|
* interrupt/bulk data sent to any endpoint other than 0. The endpoint number
|
||||||
|
* can be found in 'usbRxToken'.
|
||||||
|
*/
|
||||||
|
#define USB_CFG_HAVE_FLOWCONTROL 0
|
||||||
|
/* Define this to 1 if you want flowcontrol over USB data. See the definition
|
||||||
|
* of the macros usbDisableAllRequests() and usbEnableAllRequests() in
|
||||||
|
* usbdrv.h.
|
||||||
|
*/
|
||||||
|
#define USB_CFG_LONG_TRANSFERS 0
|
||||||
|
/* Define this to 1 if you want to send/receive blocks of more than 254 bytes
|
||||||
|
* in a single control-in or control-out transfer. Note that the capability
|
||||||
|
* for long transfers increases the driver size.
|
||||||
|
*/
|
||||||
|
/* #define USB_RX_USER_HOOK(data, len) if(usbRxToken == (uchar)USBPID_SETUP) blinkLED(); */
|
||||||
|
/* This macro is a hook if you want to do unconventional things. If it is
|
||||||
|
* defined, it's inserted at the beginning of received message processing.
|
||||||
|
* If you eat the received message and don't want default processing to
|
||||||
|
* proceed, do a return after doing your things. One possible application
|
||||||
|
* (besides debugging) is to flash a status LED on each packet.
|
||||||
|
*/
|
||||||
|
/* #define USB_RESET_HOOK(resetStarts) if(!resetStarts){hadUsbReset();} */
|
||||||
|
/* This macro is a hook if you need to know when an USB RESET occurs. It has
|
||||||
|
* one parameter which distinguishes between the start of RESET state and its
|
||||||
|
* end.
|
||||||
|
*/
|
||||||
|
/* #define USB_SET_ADDRESS_HOOK() hadAddressAssigned(); */
|
||||||
|
/* This macro (if defined) is executed when a USB SET_ADDRESS request was
|
||||||
|
* received.
|
||||||
|
*/
|
||||||
|
#define USB_COUNT_SOF 0
|
||||||
|
/* define this macro to 1 if you need the global variable "usbSofCount" which
|
||||||
|
* counts SOF packets. This feature requires that the hardware interrupt is
|
||||||
|
* connected to D- instead of D+.
|
||||||
|
*/
|
||||||
|
/* #ifdef __ASSEMBLER__
|
||||||
|
* macro myAssemblerMacro
|
||||||
|
* in YL, TCNT0
|
||||||
|
* sts timer0Snapshot, YL
|
||||||
|
* endm
|
||||||
|
* #endif
|
||||||
|
* #define USB_SOF_HOOK myAssemblerMacro
|
||||||
|
* This macro (if defined) is executed in the assembler module when a
|
||||||
|
* Start Of Frame condition is detected. It is recommended to define it to
|
||||||
|
* the name of an assembler macro which is defined here as well so that more
|
||||||
|
* than one assembler instruction can be used. The macro may use the register
|
||||||
|
* YL and modify SREG. If it lasts longer than a couple of cycles, USB messages
|
||||||
|
* immediately after an SOF pulse may be lost and must be retried by the host.
|
||||||
|
* What can you do with this hook? Since the SOF signal occurs exactly every
|
||||||
|
* 1 ms (unless the host is in sleep mode), you can use it to tune OSCCAL in
|
||||||
|
* designs running on the internal RC oscillator.
|
||||||
|
* Please note that Start Of Frame detection works only if D- is wired to the
|
||||||
|
* interrupt, not D+. THIS IS DIFFERENT THAN MOST EXAMPLES!
|
||||||
|
*/
|
||||||
|
#define USB_CFG_CHECK_DATA_TOGGLING 0
|
||||||
|
/* define this macro to 1 if you want to filter out duplicate data packets
|
||||||
|
* sent by the host. Duplicates occur only as a consequence of communication
|
||||||
|
* errors, when the host does not receive an ACK. Please note that you need to
|
||||||
|
* implement the filtering yourself in usbFunctionWriteOut() and
|
||||||
|
* usbFunctionWrite(). Use the global usbCurrentDataToken and a static variable
|
||||||
|
* for each control- and out-endpoint to check for duplicate packets.
|
||||||
|
*/
|
||||||
|
#define USB_CFG_HAVE_MEASURE_FRAME_LENGTH 0
|
||||||
|
/* define this macro to 1 if you want the function usbMeasureFrameLength()
|
||||||
|
* compiled in. This function can be used to calibrate the AVR's RC oscillator.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* -------------------------- Device Description --------------------------- */
|
||||||
|
|
||||||
|
#define USB_CFG_VENDOR_ID 0xc0, 0x16
|
||||||
|
/* USB vendor ID for the device, low byte first. If you have registered your
|
||||||
|
* own Vendor ID, define it here. Otherwise you use one of obdev's free shared
|
||||||
|
* VID/PID pairs. Be sure to read USBID-License.txt for rules!
|
||||||
|
*/
|
||||||
|
#define USB_CFG_DEVICE_ID 0xdc, 0x05
|
||||||
|
/* This is the ID of the product, low byte first. It is interpreted in the
|
||||||
|
* scope of the vendor ID. If you have registered your own VID with usb.org
|
||||||
|
* or if you have licensed a PID from somebody else, define it here. Otherwise
|
||||||
|
* you use obdev's free shared VID/PID pair. Be sure to read the rules in
|
||||||
|
* USBID-License.txt!
|
||||||
|
*/
|
||||||
|
#define USB_CFG_DEVICE_VERSION 0x00, 0x01
|
||||||
|
/* Version number of the device: Minor number first, then major number.
|
||||||
|
*/
|
||||||
|
#define USB_CFG_VENDOR_NAME 'o', 'p', 't', 'i', 'x', 'x', '.', 'o', 'r', 'g'
|
||||||
|
#define USB_CFG_VENDOR_NAME_LEN 10
|
||||||
|
/* These two values define the vendor name returned by the USB device. The name
|
||||||
|
* must be given as a list of characters under single quotes. The characters
|
||||||
|
* are interpreted as Unicode (UTF-16) entities.
|
||||||
|
* If you don't want a vendor name string, undefine these macros.
|
||||||
|
* ALWAYS define a vendor name containing your Internet domain name if you use
|
||||||
|
* obdev's free shared VID/PID pair. See the file USBID-License.txt for
|
||||||
|
* details.
|
||||||
|
*/
|
||||||
|
#define USB_CFG_DEVICE_NAME 'S', 'N', 'E', 'S', 'R', 'A', 'M'
|
||||||
|
#define USB_CFG_DEVICE_NAME_LEN 7
|
||||||
|
/* Same as above for the device name. If you don't want a device name, undefine
|
||||||
|
* the macros. See the file USBID-License.txt before you assign a name if you
|
||||||
|
* use a shared VID/PID.
|
||||||
|
*/
|
||||||
|
/*#define USB_CFG_SERIAL_NUMBER 'N', 'o', 'n', 'e' */
|
||||||
|
/*#define USB_CFG_SERIAL_NUMBER_LEN 0 */
|
||||||
|
/* Same as above for the serial number. If you don't want a serial number,
|
||||||
|
* undefine the macros.
|
||||||
|
* It may be useful to provide the serial number through other means than at
|
||||||
|
* compile time. See the section about descriptor properties below for how
|
||||||
|
* to fine tune control over USB descriptors such as the string descriptor
|
||||||
|
* for the serial number.
|
||||||
|
*/
|
||||||
|
#define USB_CFG_DEVICE_CLASS 0xff /* set to 0 if deferred to interface */
|
||||||
|
#define USB_CFG_DEVICE_SUBCLASS 0
|
||||||
|
/* See USB specification if you want to conform to an existing device class.
|
||||||
|
* Class 0xff is "vendor specific".
|
||||||
|
*/
|
||||||
|
#define USB_CFG_INTERFACE_CLASS 0 /* define class here if not at device level */
|
||||||
|
#define USB_CFG_INTERFACE_SUBCLASS 0
|
||||||
|
#define USB_CFG_INTERFACE_PROTOCOL 0
|
||||||
|
/* See USB specification if you want to conform to an existing device class or
|
||||||
|
* protocol. The following classes must be set at interface level:
|
||||||
|
* HID class is 3, no subclass and protocol required (but may be useful!)
|
||||||
|
* CDC class is 2, use subclass 2 and protocol 1 for ACM
|
||||||
|
*/
|
||||||
|
#define USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH 0
|
||||||
|
|
||||||
|
/* Define this to the length of the HID report descriptor, if you implement
|
||||||
|
* an HID device. Otherwise don't define it or define it to 0.
|
||||||
|
* If you use this define, you must add a PROGMEM character array named
|
||||||
|
* "usbHidReportDescriptor" to your code which contains the report descriptor.
|
||||||
|
* Don't forget to keep the array and this define in sync!
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* #define USB_PUBLIC static */
|
||||||
|
/* Use the define above if you #include usbdrv.c instead of linking against it.
|
||||||
|
* This technique saves a couple of bytes in flash memory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* ------------------- Fine Control over USB Descriptors ------------------- */
|
||||||
|
/* If you don't want to use the driver's default USB descriptors, you can
|
||||||
|
* provide our own. These can be provided as (1) fixed length static data in
|
||||||
|
* flash memory, (2) fixed length static data in RAM or (3) dynamically at
|
||||||
|
* runtime in the function usbFunctionDescriptor(). See usbdrv.h for more
|
||||||
|
* information about this function.
|
||||||
|
* Descriptor handling is configured through the descriptor's properties. If
|
||||||
|
* no properties are defined or if they are 0, the default descriptor is used.
|
||||||
|
* Possible properties are:
|
||||||
|
* + USB_PROP_IS_DYNAMIC: The data for the descriptor should be fetched
|
||||||
|
* at runtime via usbFunctionDescriptor(). If the usbMsgPtr mechanism is
|
||||||
|
* used, the data is in FLASH by default. Add property USB_PROP_IS_RAM if
|
||||||
|
* you want RAM pointers.
|
||||||
|
* + USB_PROP_IS_RAM: The data returned by usbFunctionDescriptor() or found
|
||||||
|
* in static memory is in RAM, not in flash memory.
|
||||||
|
* + USB_PROP_LENGTH(len): If the data is in static memory (RAM or flash),
|
||||||
|
* the driver must know the descriptor's length. The descriptor itself is
|
||||||
|
* found at the address of a well known identifier (see below).
|
||||||
|
* List of static descriptor names (must be declared PROGMEM if in flash):
|
||||||
|
* char usbDescriptorDevice[];
|
||||||
|
* char usbDescriptorConfiguration[];
|
||||||
|
* char usbDescriptorHidReport[];
|
||||||
|
* char usbDescriptorString0[];
|
||||||
|
* int usbDescriptorStringVendor[];
|
||||||
|
* int usbDescriptorStringDevice[];
|
||||||
|
* int usbDescriptorStringSerialNumber[];
|
||||||
|
* Other descriptors can't be provided statically, they must be provided
|
||||||
|
* dynamically at runtime.
|
||||||
|
*
|
||||||
|
* Descriptor properties are or-ed or added together, e.g.:
|
||||||
|
* #define USB_CFG_DESCR_PROPS_DEVICE (USB_PROP_IS_RAM | USB_PROP_LENGTH(18))
|
||||||
|
*
|
||||||
|
* The following descriptors are defined:
|
||||||
|
* USB_CFG_DESCR_PROPS_DEVICE
|
||||||
|
* USB_CFG_DESCR_PROPS_CONFIGURATION
|
||||||
|
* USB_CFG_DESCR_PROPS_STRINGS
|
||||||
|
* USB_CFG_DESCR_PROPS_STRING_0
|
||||||
|
* USB_CFG_DESCR_PROPS_STRING_VENDOR
|
||||||
|
* USB_CFG_DESCR_PROPS_STRING_PRODUCT
|
||||||
|
* USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER
|
||||||
|
* USB_CFG_DESCR_PROPS_HID
|
||||||
|
* USB_CFG_DESCR_PROPS_HID_REPORT
|
||||||
|
* USB_CFG_DESCR_PROPS_UNKNOWN (for all descriptors not handled by the driver)
|
||||||
|
*
|
||||||
|
* Note about string descriptors: String descriptors are not just strings, they
|
||||||
|
* are Unicode strings prefixed with a 2 byte header. Example:
|
||||||
|
* int serialNumberDescriptor[] = {
|
||||||
|
* USB_STRING_DESCRIPTOR_HEADER(6),
|
||||||
|
* 'S', 'e', 'r', 'i', 'a', 'l'
|
||||||
|
* };
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define USB_CFG_DESCR_PROPS_DEVICE 0
|
||||||
|
#define USB_CFG_DESCR_PROPS_CONFIGURATION 0
|
||||||
|
#define USB_CFG_DESCR_PROPS_STRINGS 0
|
||||||
|
#define USB_CFG_DESCR_PROPS_STRING_0 0
|
||||||
|
#define USB_CFG_DESCR_PROPS_STRING_VENDOR 0
|
||||||
|
#define USB_CFG_DESCR_PROPS_STRING_PRODUCT 0
|
||||||
|
#define USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER 0
|
||||||
|
#define USB_CFG_DESCR_PROPS_HID 0
|
||||||
|
#define USB_CFG_DESCR_PROPS_HID_REPORT 0
|
||||||
|
#define USB_CFG_DESCR_PROPS_UNKNOWN 0
|
||||||
|
|
||||||
|
/* ----------------------- Optional MCU Description ------------------------ */
|
||||||
|
|
||||||
|
/* The following configurations have working defaults in usbdrv.h. You
|
||||||
|
* usually don't need to set them explicitly. Only if you want to run
|
||||||
|
* the driver on a device which is not yet supported or with a compiler
|
||||||
|
* which is not fully supported (such as IAR C) or if you use a differnt
|
||||||
|
* interrupt than INT0, you may have to define some of these.
|
||||||
|
*/
|
||||||
|
/* #define USB_INTR_CFG MCUCR */
|
||||||
|
/* #define USB_INTR_CFG_SET ((1 << ISC00) | (1 << ISC01)) */
|
||||||
|
/* #define USB_INTR_CFG_CLR 0 */
|
||||||
|
/* #define USB_INTR_ENABLE GIMSK */
|
||||||
|
/* #define USB_INTR_ENABLE_BIT INT0 */
|
||||||
|
/* #define USB_INTR_PENDING GIFR */
|
||||||
|
/* #define USB_INTR_PENDING_BIT INTF0 */
|
||||||
|
/* #define USB_INTR_VECTOR SIG_INTERRUPT0 */
|
||||||
|
|
||||||
|
#endif /* __usbconfig_h_included__ */
|
||||||
@@ -268,3 +268,10 @@ Scroll down to the bottom to see the most recent changes.
|
|||||||
- Integrated a module with CRC checks at 18 MHz by Lukas Schrittwieser.
|
- Integrated a module with CRC checks at 18 MHz by Lukas Schrittwieser.
|
||||||
|
|
||||||
* Release 2009-03-23
|
* Release 2009-03-23
|
||||||
|
|
||||||
|
- Hid-mouse example used settings from hid-data example, fixed that.
|
||||||
|
- Renamed project to V-USB due to a trademark issue with Atmel(r).
|
||||||
|
- Changed CommercialLicense.txt and USBID-License.txt to make the
|
||||||
|
background of USB ID registration clearer.
|
||||||
|
|
||||||
|
* Release 2009-04-15
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
AVR-USB Driver Software License Agreement
|
V-USB Driver Software License Agreement
|
||||||
Version 2008-10-07
|
Version 2009-04-14
|
||||||
|
|
||||||
THIS LICENSE AGREEMENT GRANTS YOU CERTAIN RIGHTS IN A SOFTWARE. YOU CAN
|
THIS LICENSE AGREEMENT GRANTS YOU CERTAIN RIGHTS IN A SOFTWARE. YOU CAN
|
||||||
ENTER INTO THIS AGREEMENT AND ACQUIRE THE RIGHTS OUTLINED BELOW BY PAYING
|
ENTER INTO THIS AGREEMENT AND ACQUIRE THE RIGHTS OUTLINED BELOW BY PAYING
|
||||||
@@ -13,8 +13,8 @@ Grosse Schiffgasse 1A/7, 1020 Wien, AUSTRIA.
|
|||||||
|
|
||||||
1.2 "You" shall mean the Licensee.
|
1.2 "You" shall mean the Licensee.
|
||||||
|
|
||||||
1.3 "AVR-USB" shall mean all files included in the package distributed under
|
1.3 "V-USB" shall mean all files included in the package distributed under
|
||||||
the name "avrusb" by OBJECTIVE DEVELOPMENT (http://www.obdev.at/avrusb/)
|
the name "vusb" by OBJECTIVE DEVELOPMENT (http://www.obdev.at/vusb/)
|
||||||
unless otherwise noted. This includes the firmware-only USB device
|
unless otherwise noted. This includes the firmware-only USB device
|
||||||
implementation for Atmel AVR microcontrollers, some simple device examples
|
implementation for Atmel AVR microcontrollers, some simple device examples
|
||||||
and host side software examples and libraries.
|
and host side software examples and libraries.
|
||||||
@@ -23,21 +23,22 @@ and host side software examples and libraries.
|
|||||||
2 LICENSE GRANTS
|
2 LICENSE GRANTS
|
||||||
|
|
||||||
2.1 Source Code. OBJECTIVE DEVELOPMENT shall furnish you with the source
|
2.1 Source Code. OBJECTIVE DEVELOPMENT shall furnish you with the source
|
||||||
code of AVR-USB.
|
code of V-USB.
|
||||||
|
|
||||||
2.2 Distribution and Use. OBJECTIVE DEVELOPMENT grants you the
|
2.2 Distribution and Use. OBJECTIVE DEVELOPMENT grants you the
|
||||||
non-exclusive right to use, copy and distribute AVR-USB with your hardware
|
non-exclusive right to use, copy and distribute V-USB with your hardware
|
||||||
product(s), restricted by the limitations in section 3 below.
|
product(s), restricted by the limitations in section 3 below.
|
||||||
|
|
||||||
2.3 Modifications. OBJECTIVE DEVELOPMENT grants you the right to modify
|
2.3 Modifications. OBJECTIVE DEVELOPMENT grants you the right to modify
|
||||||
the source code and your copy of AVR-USB according to your needs.
|
the source code and your copy of V-USB according to your needs.
|
||||||
|
|
||||||
2.4 USB IDs. OBJECTIVE DEVELOPMENT grants you the exclusive rights to use
|
2.4 USB IDs. OBJECTIVE DEVELOPMENT furnishes you with one or two USB Product
|
||||||
USB Product ID(s) sent to you in e-mail after receiving your payment in
|
ID(s), sent to you in e-mail. These Product IDs are reserved exclusively for
|
||||||
conjunction with USB Vendor ID 5824. OBJECTIVE DEVELOPMENT has acquired an
|
you. They have been obtained from Wouter van Ooijen (www.voti.nl), who has
|
||||||
exclusive license for this pair of USB identifiers from Wouter van Ooijen
|
reserved the Vendor ID 5824 (decimal) at the USB Implementers Forum, Inc.
|
||||||
(www.voti.nl), who has licensed the VID from the USB Implementers Forum,
|
(www.usb.org). This mechanism ensures that there are no Product ID conflicts,
|
||||||
Inc. (www.usb.org).
|
but you cannot become USB certified (enter into the USB-IF Trademark License
|
||||||
|
Agreement) as you would need your own Vendor ID for that.
|
||||||
|
|
||||||
|
|
||||||
3 LICENSE RESTRICTIONS
|
3 LICENSE RESTRICTIONS
|
||||||
@@ -46,21 +47,21 @@ Inc. (www.usb.org).
|
|||||||
applicable. Which one is determined by the amount you pay to OBJECTIVE
|
applicable. Which one is determined by the amount you pay to OBJECTIVE
|
||||||
DEVELOPMENT, see section 4 ("Payment") below.
|
DEVELOPMENT, see section 4 ("Payment") below.
|
||||||
|
|
||||||
Hobby License: You may use AVR-USB according to section 2 above in no more
|
Hobby License: You may use V-USB according to section 2 above in no more
|
||||||
than 5 hardware units. These units must not be sold for profit.
|
than 5 hardware units. These units must not be sold for profit.
|
||||||
|
|
||||||
Entry Level License: You may use AVR-USB according to section 2 above in no
|
Entry Level License: You may use V-USB according to section 2 above in no
|
||||||
more than 150 hardware units.
|
more than 150 hardware units.
|
||||||
|
|
||||||
Professional License: You may use AVR-USB according to section 2 above in
|
Professional License: You may use V-USB according to section 2 above in
|
||||||
any number of hardware units, except for large scale production ("unlimited
|
any number of hardware units, except for large scale production ("unlimited
|
||||||
fair use"). Quantities below 10,000 units are not considered large scale
|
fair use"). Quantities below 10,000 units are not considered large scale
|
||||||
production. If your reach quantities which are obviously large scale
|
production. If your reach quantities which are obviously large scale
|
||||||
production, you must pay a license fee of 0.10 EUR per unit for all units
|
production, you must pay a license fee of 0.10 EUR per unit for all units
|
||||||
above 10,000.
|
above 10,000.
|
||||||
|
|
||||||
3.2 Rental. You may not rent, lease, or lend AVR-USB or otherwise encumber
|
3.2 Rental. You may not rent, lease, or lend V-USB or otherwise encumber
|
||||||
any copy of AVR-USB, or any of the rights granted herein.
|
any copy of V-USB, or any of the rights granted herein.
|
||||||
|
|
||||||
3.3 Transfer. You may not transfer your rights under this Agreement to
|
3.3 Transfer. You may not transfer your rights under this Agreement to
|
||||||
another party without OBJECTIVE DEVELOPMENT's prior written consent. If
|
another party without OBJECTIVE DEVELOPMENT's prior written consent. If
|
||||||
@@ -78,7 +79,7 @@ non-exclusive.
|
|||||||
by third parties. In particular, you are not allowed to use the USB logo or
|
by third parties. In particular, you are not allowed to use the USB logo or
|
||||||
other trademarks owned by the USB Implementers Forum, Inc. without their
|
other trademarks owned by the USB Implementers Forum, Inc. without their
|
||||||
consent. Since such consent depends on USB certification, it should be
|
consent. Since such consent depends on USB certification, it should be
|
||||||
noted that AVR-USB will not pass certification because it does not
|
noted that V-USB will not pass certification because it does not
|
||||||
implement checksum verification and the microcontroller ports do not meet
|
implement checksum verification and the microcontroller ports do not meet
|
||||||
the electrical specifications.
|
the electrical specifications.
|
||||||
|
|
||||||
@@ -88,15 +89,15 @@ the electrical specifications.
|
|||||||
The payment amount depends on the variation of this agreement (according to
|
The payment amount depends on the variation of this agreement (according to
|
||||||
section 3.1) into which you want to enter. Concrete prices are listed on
|
section 3.1) into which you want to enter. Concrete prices are listed on
|
||||||
OBJECTIVE DEVELOPMENT's web site, usually at
|
OBJECTIVE DEVELOPMENT's web site, usually at
|
||||||
http://www.obdev.at/avrusb/license.html. You agree to pay the amount listed
|
http://www.obdev.at/vusb/license.html. You agree to pay the amount listed
|
||||||
there to OBJECTIVE DEVELOPMENT or OBJECTIVE DEVELOPMENT's payment processor
|
there to OBJECTIVE DEVELOPMENT or OBJECTIVE DEVELOPMENT's payment processor
|
||||||
or reseller.
|
or reseller.
|
||||||
|
|
||||||
|
|
||||||
5 COPYRIGHT AND OWNERSHIP
|
5 COPYRIGHT AND OWNERSHIP
|
||||||
|
|
||||||
AVR-USB is protected by copyright laws and international copyright
|
V-USB is protected by copyright laws and international copyright
|
||||||
treaties, as well as other intellectual property laws and treaties. AVR-USB
|
treaties, as well as other intellectual property laws and treaties. V-USB
|
||||||
is licensed, not sold.
|
is licensed, not sold.
|
||||||
|
|
||||||
|
|
||||||
@@ -112,12 +113,12 @@ and limitation of liability shall survive termination of this agreement.
|
|||||||
|
|
||||||
7 DISCLAIMER OF WARRANTY AND LIABILITY
|
7 DISCLAIMER OF WARRANTY AND LIABILITY
|
||||||
|
|
||||||
LIMITED WARRANTY. AVR-USB IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
LIMITED WARRANTY. V-USB IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||||
KIND. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, OBJECTIVE
|
KIND. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, OBJECTIVE
|
||||||
DEVELOPMENT AND ITS SUPPLIERS HEREBY DISCLAIM ALL WARRANTIES, EITHER
|
DEVELOPMENT AND ITS SUPPLIERS HEREBY DISCLAIM ALL WARRANTIES, EITHER
|
||||||
EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND
|
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND
|
||||||
NON-INFRINGEMENT, WITH REGARD TO AVR-USB, AND THE PROVISION OF OR FAILURE
|
NON-INFRINGEMENT, WITH REGARD TO V-USB, AND THE PROVISION OF OR FAILURE
|
||||||
TO PROVIDE SUPPORT SERVICES. THIS LIMITED WARRANTY GIVES YOU SPECIFIC LEGAL
|
TO PROVIDE SUPPORT SERVICES. THIS LIMITED WARRANTY GIVES YOU SPECIFIC LEGAL
|
||||||
RIGHTS. YOU MAY HAVE OTHERS, WHICH VARY FROM STATE/JURISDICTION TO
|
RIGHTS. YOU MAY HAVE OTHERS, WHICH VARY FROM STATE/JURISDICTION TO
|
||||||
STATE/JURISDICTION.
|
STATE/JURISDICTION.
|
||||||
@@ -127,11 +128,11 @@ IN NO EVENT SHALL OBJECTIVE DEVELOPMENT OR ITS SUPPLIERS BE LIABLE FOR ANY
|
|||||||
SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES WHATSOEVER
|
SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES WHATSOEVER
|
||||||
(INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS,
|
(INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS,
|
||||||
BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR ANY OTHER PECUNIARY
|
BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR ANY OTHER PECUNIARY
|
||||||
LOSS) ARISING OUT OF THE USE OF OR INABILITY TO USE AVR-USB OR THE
|
LOSS) ARISING OUT OF THE USE OF OR INABILITY TO USE V-USB OR THE
|
||||||
PROVISION OF OR FAILURE TO PROVIDE SUPPORT SERVICES, EVEN IF OBJECTIVE
|
PROVISION OF OR FAILURE TO PROVIDE SUPPORT SERVICES, EVEN IF OBJECTIVE
|
||||||
DEVELOPMENT HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. IN ANY
|
DEVELOPMENT HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. IN ANY
|
||||||
CASE, OBJECTIVE DEVELOPMENT'S ENTIRE LIABILITY UNDER ANY PROVISION OF THIS
|
CASE, OBJECTIVE DEVELOPMENT'S ENTIRE LIABILITY UNDER ANY PROVISION OF THIS
|
||||||
AGREEMENT SHALL BE LIMITED TO THE AMOUNT ACTUALLY PAID BY YOU FOR AVR-USB.
|
AGREEMENT SHALL BE LIMITED TO THE AMOUNT ACTUALLY PAID BY YOU FOR V-USB.
|
||||||
|
|
||||||
|
|
||||||
8 MISCELLANEOUS TERMS
|
8 MISCELLANEOUS TERMS
|
||||||
@@ -1,18 +1,18 @@
|
|||||||
OBJECTIVE DEVELOPMENT GmbH's AVR-USB driver software is distributed under the
|
OBJECTIVE DEVELOPMENT GmbH's V-USB driver software is distributed under the
|
||||||
terms and conditions of the GNU GPL version 2 or the GNU GPL version 3. It is
|
terms and conditions of the GNU GPL version 2 or the GNU GPL version 3. It is
|
||||||
your choice whether you apply the terms of version 2 or version 3. The full
|
your choice whether you apply the terms of version 2 or version 3. The full
|
||||||
text of GPLv2 is included below. In addition to the requirements in the GPL,
|
text of GPLv2 is included below. In addition to the requirements in the GPL,
|
||||||
we STRONGLY ENCOURAGE you to do the following:
|
we STRONGLY ENCOURAGE you to do the following:
|
||||||
|
|
||||||
(1) Publish your entire project on a web site and drop us a note with the URL.
|
(1) Publish your entire project on a web site and drop us a note with the URL.
|
||||||
Use the form at http://www.obdev.at/avrusb/feedback.html for your submission.
|
Use the form at http://www.obdev.at/vusb/feedback.html for your submission.
|
||||||
|
|
||||||
(2) Adhere to minimum publication standards. Please include AT LEAST:
|
(2) Adhere to minimum publication standards. Please include AT LEAST:
|
||||||
- a circuit diagram in PDF, PNG or GIF format
|
- a circuit diagram in PDF, PNG or GIF format
|
||||||
- full source code for the host software
|
- full source code for the host software
|
||||||
- a Readme.txt file in ASCII format which describes the purpose of the
|
- a Readme.txt file in ASCII format which describes the purpose of the
|
||||||
project and what can be found in which directories and which files
|
project and what can be found in which directories and which files
|
||||||
- a reference to http://www.obdev.at/avrusb/
|
- a reference to http://www.obdev.at/vusb/
|
||||||
|
|
||||||
(3) If you improve the driver firmware itself, please give us a free license
|
(3) If you improve the driver firmware itself, please give us a free license
|
||||||
to your modifications for our commercial license offerings.
|
to your modifications for our commercial license offerings.
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
This is the Readme file to Objective Development's firmware-only USB driver
|
This is the Readme file to Objective Development's firmware-only USB driver
|
||||||
for Atmel AVR microcontrollers. For more information please visit
|
for Atmel AVR microcontrollers. For more information please visit
|
||||||
http://www.obdev.at/avrusb/
|
http://www.obdev.at/vusb/
|
||||||
|
|
||||||
This directory contains the USB firmware only. Copy it as-is to your own
|
This directory contains the USB firmware only. Copy it as-is to your own
|
||||||
project and add all .c and .S files to your project (these files are marked
|
project and add all .c and .S files to your project (these files are marked
|
||||||
@@ -53,7 +53,7 @@ actual clock rate must be configured in usbdrv.h unless you use the default
|
|||||||
12 MHz.
|
12 MHz.
|
||||||
|
|
||||||
12 MHz Clock
|
12 MHz Clock
|
||||||
This is the traditional clock rate of AVR-USB because it's the lowest clock
|
This is the traditional clock rate of V-USB because it's the lowest clock
|
||||||
rate where the timing constraints of the USB spec can be met.
|
rate where the timing constraints of the USB spec can be met.
|
||||||
|
|
||||||
15 MHz Clock
|
15 MHz Clock
|
||||||
@@ -78,7 +78,7 @@ oscillator can reach 16.5 MHz with the RC oscillator. This includes the very
|
|||||||
popular ATTiny25, ATTiny45, ATTiny85 series as well as the ATTiny26. Almost
|
popular ATTiny25, ATTiny45, ATTiny85 series as well as the ATTiny26. Almost
|
||||||
all AVRs can reach 12.8 MHz, although this is outside the specified range.
|
all AVRs can reach 12.8 MHz, although this is outside the specified range.
|
||||||
|
|
||||||
See the EasyLogger example at http://www.obdev.at/avrusb/easylogger.html for
|
See the EasyLogger example at http://www.obdev.at/vusb/easylogger.html for
|
||||||
code which calibrates the RC oscillator based on the USB frame clock.
|
code which calibrates the RC oscillator based on the USB frame clock.
|
||||||
|
|
||||||
18 MHz Clock
|
18 MHz Clock
|
||||||
@@ -108,14 +108,14 @@ and hobbyists, we provide some VID/PID pairs for free. See the file
|
|||||||
USBID-License.txt for details.
|
USBID-License.txt for details.
|
||||||
|
|
||||||
Objective Development also has some license offerings which include product
|
Objective Development also has some license offerings which include product
|
||||||
IDs. See http://www.obdev.at/avrusb/ for details.
|
IDs. See http://www.obdev.at/vusb/ for details.
|
||||||
|
|
||||||
|
|
||||||
DEVELOPMENT SYSTEM
|
DEVELOPMENT SYSTEM
|
||||||
==================
|
==================
|
||||||
This driver has been developed and optimized for the GNU compiler version 3
|
This driver has been developed and optimized for the GNU compiler version 3
|
||||||
(gcc 3). It does work well with gcc 4, but with bigger code size. We recommend
|
(gcc 3). It does work well with gcc 4, but with bigger code size. We recommend
|
||||||
that you use the GNU compiler suite because it is freely available. AVR-USB
|
that you use the GNU compiler suite because it is freely available. V-USB
|
||||||
has also been ported to the IAR compiler and assembler. It has been tested
|
has also been ported to the IAR compiler and assembler. It has been tested
|
||||||
with IAR 4.10B/W32 and 4.12A/W32 on an ATmega8 with the "small" and "tiny"
|
with IAR 4.10B/W32 and 4.12A/W32 on an ATmega8 with the "small" and "tiny"
|
||||||
memory model. Not every release is tested with IAR CC and the driver may
|
memory model. Not every release is tested with IAR CC and the driver may
|
||||||
@@ -123,8 +123,8 @@ therefore fail to compile with IAR. Please note that gcc is more efficient for
|
|||||||
usbdrv.c because this module has been deliberately optimized for gcc.
|
usbdrv.c because this module has been deliberately optimized for gcc.
|
||||||
|
|
||||||
|
|
||||||
USING AVR-USB FOR FREE
|
USING V-USB FOR FREE
|
||||||
======================
|
====================
|
||||||
The AVR firmware driver is published under the GNU General Public License
|
The AVR firmware driver is published under the GNU General Public License
|
||||||
Version 2 (GPL2) and the GNU General Public License Version 3 (GPL3). It is
|
Version 2 (GPL2) and the GNU General Public License Version 3 (GPL3). It is
|
||||||
your choice whether you apply the terms of version 2 or version 3.
|
your choice whether you apply the terms of version 2 or version 3.
|
||||||
@@ -133,26 +133,26 @@ If you decide for the free GPL2 or GPL3, we STRONGLY ENCOURAGE you to do the
|
|||||||
following things IN ADDITION to the obligations from the GPL:
|
following things IN ADDITION to the obligations from the GPL:
|
||||||
|
|
||||||
(1) Publish your entire project on a web site and drop us a note with the URL.
|
(1) Publish your entire project on a web site and drop us a note with the URL.
|
||||||
Use the form at http://www.obdev.at/avrusb/feedback.html for your submission.
|
Use the form at http://www.obdev.at/vusb/feedback.html for your submission.
|
||||||
If you don't have a web site, you can publish the project in obdev's
|
If you don't have a web site, you can publish the project in obdev's
|
||||||
documentation wiki at
|
documentation wiki at
|
||||||
http://www.obdev.at/goto.php?t=avrusb-wiki&p=hosted-projects.
|
http://www.obdev.at/goto.php?t=vusb-wiki&p=hosted-projects.
|
||||||
|
|
||||||
(2) Adhere to minimum publication standards. Please include AT LEAST:
|
(2) Adhere to minimum publication standards. Please include AT LEAST:
|
||||||
- a circuit diagram in PDF, PNG or GIF format
|
- a circuit diagram in PDF, PNG or GIF format
|
||||||
- full source code for the host software
|
- full source code for the host software
|
||||||
- a Readme.txt file in ASCII format which describes the purpose of the
|
- a Readme.txt file in ASCII format which describes the purpose of the
|
||||||
project and what can be found in which directories and which files
|
project and what can be found in which directories and which files
|
||||||
- a reference to http://www.obdev.at/avrusb/
|
- a reference to http://www.obdev.at/vusb/
|
||||||
|
|
||||||
(3) If you improve the driver firmware itself, please give us a free license
|
(3) If you improve the driver firmware itself, please give us a free license
|
||||||
to your modifications for our commercial license offerings.
|
to your modifications for our commercial license offerings.
|
||||||
|
|
||||||
|
|
||||||
COMMERCIAL LICENSES FOR AVR-USB
|
COMMERCIAL LICENSES FOR V-USB
|
||||||
===============================
|
=============================
|
||||||
If you don't want to publish your source code under the terms of the GPL,
|
If you don't want to publish your source code under the terms of the GPL,
|
||||||
you can simply pay money for AVR-USB. As an additional benefit you get
|
you can simply pay money for V-USB. As an additional benefit you get
|
||||||
USB PIDs for free, licensed exclusively to you. See the file
|
USB PIDs for free, reserved exclusively to you. See the file
|
||||||
"CommercialLicense.txt" for details.
|
"CommercialLicense.txt" for details.
|
||||||
|
|
||||||
@@ -1,10 +1,17 @@
|
|||||||
Royalty-Free Non-Exclusive License USB Product-ID
|
Royalty-Free Non-Exclusive Use of USB Product-IDs
|
||||||
=================================================
|
=================================================
|
||||||
|
|
||||||
Version 2008-04-07
|
Version 2009-04-13
|
||||||
|
|
||||||
|
Strictly speaking, this is not a license. You can't give a license to use
|
||||||
|
a simple number (such as e.g. 1500) for any purpose. This is a set of rules
|
||||||
|
which should make it possible to build USB devices without the requirement
|
||||||
|
for individual USB IDs. If you break one of the rules, you will run into
|
||||||
|
technical problems sooner or later, but you don't risk legal trouble.
|
||||||
|
|
||||||
|
|
||||||
OBJECTIVE DEVELOPMENT Software GmbH hereby grants you the non-exclusive
|
OBJECTIVE DEVELOPMENT Software GmbH hereby grants you the non-exclusive
|
||||||
right to use three USB.org vendor-ID (VID) / product-ID (PID) pairs with
|
right to use four USB.org vendor-ID (VID) / product-ID (PID) pairs with
|
||||||
products based on Objective Development's firmware-only USB driver for
|
products based on Objective Development's firmware-only USB driver for
|
||||||
Atmel AVR microcontrollers:
|
Atmel AVR microcontrollers:
|
||||||
|
|
||||||
@@ -27,10 +34,11 @@ used by many companies and individuals for different products. To avoid
|
|||||||
conflicts, your device and host driver software MUST adhere to the rules
|
conflicts, your device and host driver software MUST adhere to the rules
|
||||||
outlined below.
|
outlined below.
|
||||||
|
|
||||||
OBJECTIVE DEVELOPMENT Software GmbH has licensed these VID/PID pairs from
|
OBJECTIVE DEVELOPMENT Software GmbH has obtained these VID/PID pairs from
|
||||||
Wouter van Ooijen (see www.voti.nl), who has licensed the VID from the USB
|
Wouter van Ooijen (see www.voti.nl) for exclusive disposition. Wouter van
|
||||||
Implementers Forum, Inc. (see www.usb.org). The VID is registered for the
|
Ooijen has obtained the VID from the USB Implementers Forum, Inc.
|
||||||
company name "Van Ooijen Technische Informatica".
|
(see www.usb.org). The VID is registered for the company name
|
||||||
|
"Van Ooijen Technische Informatica".
|
||||||
|
|
||||||
|
|
||||||
RULES AND RESTRICTIONS
|
RULES AND RESTRICTIONS
|
||||||
@@ -44,7 +52,7 @@ MUST be available at least in USB language 0x0409 (English/US).
|
|||||||
domain name (e.g. "mycompany.com") registered and owned by you, or an
|
domain name (e.g. "mycompany.com") registered and owned by you, or an
|
||||||
e-mail address under your control (e.g. "myname@gmx.net"). You can embed
|
e-mail address under your control (e.g. "myname@gmx.net"). You can embed
|
||||||
the domain name or e-mail address in any string you like, e.g. "Objective
|
the domain name or e-mail address in any string you like, e.g. "Objective
|
||||||
Development http://www.obdev.at/avrusb/".
|
Development http://www.obdev.at/vusb/".
|
||||||
|
|
||||||
(3) You are responsible for retaining ownership of the domain or e-mail
|
(3) You are responsible for retaining ownership of the domain or e-mail
|
||||||
address for as long as any of your products are in use.
|
address for as long as any of your products are in use.
|
||||||
@@ -142,5 +150,5 @@ violates the USB specification. If you do it, you do it at your own risk.
|
|||||||
|
|
||||||
To avoid possible incompatibilities, we highly recommend that you get your
|
To avoid possible incompatibilities, we highly recommend that you get your
|
||||||
own VID/PID pair if you intend to sell your product. Objective
|
own VID/PID pair if you intend to sell your product. Objective
|
||||||
Development's commercial licenses for AVR-USB include a PID for
|
Development's commercial licenses for V-USB include a PID for
|
||||||
unrestricted exclusive use.
|
unrestricted exclusive use.
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Name: asmcommon.inc
|
/* Name: asmcommon.inc
|
||||||
* Project: AVR USB driver
|
* Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
|
||||||
* Author: Christian Starkjohann
|
* Author: Christian Starkjohann
|
||||||
* Creation Date: 2007-11-05
|
* Creation Date: 2007-11-05
|
||||||
* Tabsize: 4
|
* Tabsize: 4
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
/* Name: usbconfig.h
|
/* Name: usbconfig.h
|
||||||
* Project: AVR USB driver
|
* Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
|
||||||
* Author: Christian Starkjohann
|
* Author: Christian Starkjohann
|
||||||
* Creation Date: 2005-04-01
|
* Creation Date: 2005-04-01
|
||||||
* Tabsize: 4
|
* Tabsize: 4
|
||||||
* Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
|
* Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
|
||||||
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
||||||
* This Revision: $Id: usbconfig-prototype.h 734 2009-03-23 11:10:07Z cs $
|
* This Revision: $Id: usbconfig-prototype.h 740 2009-04-13 18:23:31Z cs $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __usbconfig_h_included__
|
#ifndef __usbconfig_h_included__
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
/*
|
/*
|
||||||
General Description:
|
General Description:
|
||||||
This file is an example configuration (with inline documentation) for the USB
|
This file is an example configuration (with inline documentation) for the USB
|
||||||
driver. It configures AVR-USB for USB D+ connected to Port D bit 2 (which is
|
driver. It configures V-USB for USB D+ connected to Port D bit 2 (which is
|
||||||
also hardware interrupt 0 on many devices) and USB D- to Port D bit 4. You may
|
also hardware interrupt 0 on many devices) and USB D- to Port D bit 4. You may
|
||||||
wire the lines to any other port, as long as D+ is also wired to INT0 (or any
|
wire the lines to any other port, as long as D+ is also wired to INT0 (or any
|
||||||
other hardware interrupt, as long as it is the highest level interrupt, see
|
other hardware interrupt, as long as it is the highest level interrupt, see
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
/* Name: usbdrv.c
|
/* Name: usbdrv.c
|
||||||
* Project: AVR USB driver
|
* Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
|
||||||
* Author: Christian Starkjohann
|
* Author: Christian Starkjohann
|
||||||
* Creation Date: 2004-12-29
|
* Creation Date: 2004-12-29
|
||||||
* Tabsize: 4
|
* Tabsize: 4
|
||||||
* Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
|
* Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
|
||||||
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
||||||
* This Revision: $Id: usbdrv.c 721 2009-03-16 19:03:19Z cs $
|
* This Revision: $Id: usbdrv.c 740 2009-04-13 18:23:31Z cs $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "usbportability.h"
|
#include "usbportability.h"
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
/* Name: usbdrv.h
|
/* Name: usbdrv.h
|
||||||
* Project: AVR USB driver
|
* Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
|
||||||
* Author: Christian Starkjohann
|
* Author: Christian Starkjohann
|
||||||
* Creation Date: 2004-12-29
|
* Creation Date: 2004-12-29
|
||||||
* Tabsize: 4
|
* Tabsize: 4
|
||||||
* Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
|
* Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
|
||||||
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
||||||
* This Revision: $Id: usbdrv.h 738 2009-03-23 11:13:24Z cs $
|
* This Revision: $Id: usbdrv.h 748 2009-04-15 15:05:07Z cs $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __usbdrv_h_included__
|
#ifndef __usbdrv_h_included__
|
||||||
@@ -122,7 +122,7 @@ USB messages, even if they address another (low-speed) device on the same bus.
|
|||||||
/* --------------------------- Module Interface ---------------------------- */
|
/* --------------------------- Module Interface ---------------------------- */
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
#define USBDRV_VERSION 20090323
|
#define USBDRV_VERSION 20090415
|
||||||
/* This define uniquely identifies a driver version. It is a decimal number
|
/* This define uniquely identifies a driver version. It is a decimal number
|
||||||
* constructed from the driver's release date in the form YYYYMMDD. If the
|
* constructed from the driver's release date in the form YYYYMMDD. If the
|
||||||
* driver's behavior or interface changes, you can use this constant to
|
* driver's behavior or interface changes, you can use this constant to
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
/* Name: usbdrvasm.S
|
/* Name: usbdrvasm.S
|
||||||
* Project: AVR USB driver
|
* Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
|
||||||
* Author: Christian Starkjohann
|
* Author: Christian Starkjohann
|
||||||
* Creation Date: 2007-06-13
|
* Creation Date: 2007-06-13
|
||||||
* Tabsize: 4
|
* Tabsize: 4
|
||||||
* Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH
|
* Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH
|
||||||
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
||||||
* Revision: $Id: usbdrvasm.S 722 2009-03-16 19:03:57Z cs $
|
* Revision: $Id: usbdrvasm.S 740 2009-04-13 18:23:31Z cs $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Name: usbdrvasm.asm
|
/* Name: usbdrvasm.asm
|
||||||
* Project: AVR USB driver
|
* Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
|
||||||
* Author: Christian Starkjohann
|
* Author: Christian Starkjohann
|
||||||
* Creation Date: 2006-03-01
|
* Creation Date: 2006-03-01
|
||||||
* Tabsize: 4
|
* Tabsize: 4
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
/* Name: usbdrvasm12.inc
|
/* Name: usbdrvasm12.inc
|
||||||
* Project: AVR USB driver
|
* Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
|
||||||
* Author: Christian Starkjohann
|
* Author: Christian Starkjohann
|
||||||
* Creation Date: 2004-12-29
|
* Creation Date: 2004-12-29
|
||||||
* Tabsize: 4
|
* Tabsize: 4
|
||||||
* Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH
|
* Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH
|
||||||
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
||||||
* This Revision: $Id: usbdrvasm12.inc 692 2008-11-07 15:07:40Z cs $
|
* This Revision: $Id: usbdrvasm12.inc 740 2009-04-13 18:23:31Z cs $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Do not link this file! Link usbdrvasm.S instead, which includes the
|
/* Do not link this file! Link usbdrvasm.S instead, which includes the
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
/* Name: usbdrvasm128.inc
|
/* Name: usbdrvasm128.inc
|
||||||
* Project: AVR USB driver
|
* Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
|
||||||
* Author: Christian Starkjohann
|
* Author: Christian Starkjohann
|
||||||
* Creation Date: 2008-10-11
|
* Creation Date: 2008-10-11
|
||||||
* Tabsize: 4
|
* Tabsize: 4
|
||||||
* Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
|
* Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
|
||||||
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
||||||
* This Revision: $Id: usbdrvasm128.inc 692 2008-11-07 15:07:40Z cs $
|
* This Revision: $Id: usbdrvasm128.inc 740 2009-04-13 18:23:31Z cs $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Do not link this file! Link usbdrvasm.S instead, which includes the
|
/* Do not link this file! Link usbdrvasm.S instead, which includes the
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
/* Name: usbdrvasm15.inc
|
/* Name: usbdrvasm15.inc
|
||||||
* Project: AVR USB driver
|
* Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
|
||||||
* Author: contributed by V. Bosch
|
* Author: contributed by V. Bosch
|
||||||
* Creation Date: 2007-08-06
|
* Creation Date: 2007-08-06
|
||||||
* Tabsize: 4
|
* Tabsize: 4
|
||||||
* Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH
|
* Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH
|
||||||
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
||||||
* Revision: $Id: usbdrvasm15.inc 692 2008-11-07 15:07:40Z cs $
|
* Revision: $Id: usbdrvasm15.inc 740 2009-04-13 18:23:31Z cs $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Do not link this file! Link usbdrvasm.S instead, which includes the
|
/* Do not link this file! Link usbdrvasm.S instead, which includes the
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
/* Name: usbdrvasm16.inc
|
/* Name: usbdrvasm16.inc
|
||||||
* Project: AVR USB driver
|
* Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
|
||||||
* Author: Christian Starkjohann
|
* Author: Christian Starkjohann
|
||||||
* Creation Date: 2007-06-15
|
* Creation Date: 2007-06-15
|
||||||
* Tabsize: 4
|
* Tabsize: 4
|
||||||
* Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH
|
* Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH
|
||||||
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
||||||
* Revision: $Id: usbdrvasm16.inc 692 2008-11-07 15:07:40Z cs $
|
* Revision: $Id: usbdrvasm16.inc 740 2009-04-13 18:23:31Z cs $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Do not link this file! Link usbdrvasm.S instead, which includes the
|
/* Do not link this file! Link usbdrvasm.S instead, which includes the
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
/* Name: usbdrvasm165.inc
|
/* Name: usbdrvasm165.inc
|
||||||
* Project: AVR USB driver
|
* Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
|
||||||
* Author: Christian Starkjohann
|
* Author: Christian Starkjohann
|
||||||
* Creation Date: 2007-04-22
|
* Creation Date: 2007-04-22
|
||||||
* Tabsize: 4
|
* Tabsize: 4
|
||||||
* Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH
|
* Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH
|
||||||
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
||||||
* Revision: $Id: usbdrvasm165.inc 692 2008-11-07 15:07:40Z cs $
|
* Revision: $Id: usbdrvasm165.inc 740 2009-04-13 18:23:31Z cs $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Do not link this file! Link usbdrvasm.S instead, which includes the
|
/* Do not link this file! Link usbdrvasm.S instead, which includes the
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
/* Name: usbdrvasm18.inc
|
/* Name: usbdrvasm18.inc
|
||||||
* Project: AVR USB driver
|
* Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
|
||||||
* Author: Lukas Schrittwieser (based on 20 MHz usbdrvasm20.inc by Jeroen Benschop)
|
* Author: Lukas Schrittwieser (based on 20 MHz usbdrvasm20.inc by Jeroen Benschop)
|
||||||
* Creation Date: 2009-01-20
|
* Creation Date: 2009-01-20
|
||||||
* Tabsize: 4
|
* Tabsize: 4
|
||||||
* Copyright: (c) 2008 by Lukas Schrittwieser and OBJECTIVE DEVELOPMENT Software GmbH
|
* Copyright: (c) 2008 by Lukas Schrittwieser and OBJECTIVE DEVELOPMENT Software GmbH
|
||||||
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
||||||
* Revision: $Id: usbdrvasm18-crc.inc 734 2009-03-23 11:10:07Z cs $
|
* Revision: $Id: usbdrvasm18-crc.inc 740 2009-04-13 18:23:31Z cs $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Do not link this file! Link usbdrvasm.S instead, which includes the
|
/* Do not link this file! Link usbdrvasm.S instead, which includes the
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
/* Name: usbdrvasm20.inc
|
/* Name: usbdrvasm20.inc
|
||||||
* Project: AVR USB driver
|
* Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
|
||||||
* Author: Jeroen Benschop
|
* Author: Jeroen Benschop
|
||||||
* Based on usbdrvasm16.inc from Christian Starkjohann
|
* Based on usbdrvasm16.inc from Christian Starkjohann
|
||||||
* Creation Date: 2008-03-05
|
* Creation Date: 2008-03-05
|
||||||
* Tabsize: 4
|
* Tabsize: 4
|
||||||
* Copyright: (c) 2008 by Jeroen Benschop and OBJECTIVE DEVELOPMENT Software GmbH
|
* Copyright: (c) 2008 by Jeroen Benschop and OBJECTIVE DEVELOPMENT Software GmbH
|
||||||
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
||||||
* Revision: $Id: usbdrvasm20.inc 692 2008-11-07 15:07:40Z cs $
|
* Revision: $Id: usbdrvasm20.inc 740 2009-04-13 18:23:31Z cs $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Do not link this file! Link usbdrvasm.S instead, which includes the
|
/* Do not link this file! Link usbdrvasm.S instead, which includes the
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
/* Name: usbportability.h
|
/* Name: usbportability.h
|
||||||
* Project: AVR USB driver
|
* Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
|
||||||
* Author: Christian Starkjohann
|
* Author: Christian Starkjohann
|
||||||
* Creation Date: 2008-06-17
|
* Creation Date: 2008-06-17
|
||||||
* Tabsize: 4
|
* Tabsize: 4
|
||||||
* Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
|
* Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
|
||||||
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
|
||||||
* This Revision: $Id: usbportability.h 692 2008-11-07 15:07:40Z cs $
|
* This Revision: $Id: usbportability.h 740 2009-04-13 18:23:31Z cs $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
BIN
roms/arkanoid.smc
Normal file
BIN
roms/arkanoid.smc
Normal file
Binary file not shown.
BIN
roms/eric.smc
Normal file
BIN
roms/eric.smc
Normal file
Binary file not shown.
BIN
roms/kirby.smc
Normal file
BIN
roms/kirby.smc
Normal file
Binary file not shown.
BIN
roms/super01.smc
Normal file
BIN
roms/super01.smc
Normal file
Binary file not shown.
BIN
roms/super02.smc
Normal file
BIN
roms/super02.smc
Normal file
Binary file not shown.
BIN
roms/turrican.smc
Normal file
BIN
roms/turrican.smc
Normal file
Binary file not shown.
1206
snesram.tmproj
1206
snesram.tmproj
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
142
tools/bsnes/.cproject
Normal file
142
tools/bsnes/.cproject
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<?fileVersion 4.0.0?>
|
||||||
|
|
||||||
|
<cproject>
|
||||||
|
<storageModule moduleId="org.eclipse.cdt.core.settings">
|
||||||
|
<cconfiguration id="cdt.managedbuild.toolchain.gnu.macosx.base.1958627876">
|
||||||
|
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.toolchain.gnu.macosx.base.1958627876" moduleId="org.eclipse.cdt.core.settings" name="MacOSX GCC">
|
||||||
|
<externalSettings/>
|
||||||
|
<extensions>
|
||||||
|
<extension id="org.eclipse.cdt.core.MachO" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||||
|
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||||
|
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||||
|
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||||
|
<extension id="org.eclipse.cdt.core.MakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||||
|
</extensions>
|
||||||
|
</storageModule>
|
||||||
|
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||||
|
<configuration artifactName="bsnes" buildProperties="" id="cdt.managedbuild.toolchain.gnu.macosx.base.1958627876" name="MacOSX GCC" parent="org.eclipse.cdt.build.core.emptycfg">
|
||||||
|
<folderInfo id="cdt.managedbuild.toolchain.gnu.macosx.base.1958627876.81319156" name="/" resourcePath="">
|
||||||
|
<toolChain id="cdt.managedbuild.toolchain.gnu.macosx.base.1621265583" name="cdt.managedbuild.toolchain.gnu.macosx.base" superClass="cdt.managedbuild.toolchain.gnu.macosx.base">
|
||||||
|
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.MachO" id="cdt.managedbuild.target.gnu.platform.macosx.base.980966539" name="Debug Platform" osList="macosx" superClass="cdt.managedbuild.target.gnu.platform.macosx.base"/>
|
||||||
|
<builder id="cdt.managedbuild.target.gnu.builder.macosx.base.1148816406" managedBuildOn="false" name="Gnu Make Builder.MacOSX GCC" superClass="cdt.managedbuild.target.gnu.builder.macosx.base"/>
|
||||||
|
<tool id="cdt.managedbuild.tool.macosx.c.linker.macosx.base.18412343" name="MacOS X C Linker" superClass="cdt.managedbuild.tool.macosx.c.linker.macosx.base"/>
|
||||||
|
<tool id="cdt.managedbuild.tool.macosx.cpp.linker.macosx.base.951081191" name="MacOS X C++ Linker" superClass="cdt.managedbuild.tool.macosx.cpp.linker.macosx.base"/>
|
||||||
|
<tool id="cdt.managedbuild.tool.gnu.assembler.macosx.base.672073602" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.macosx.base"/>
|
||||||
|
<tool id="cdt.managedbuild.tool.gnu.archiver.macosx.base.1929224322" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.macosx.base"/>
|
||||||
|
<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.macosx.base.430483384" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.macosx.base"/>
|
||||||
|
<tool id="cdt.managedbuild.tool.gnu.c.compiler.macosx.base.773198848" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.macosx.base"/>
|
||||||
|
</toolChain>
|
||||||
|
</folderInfo>
|
||||||
|
</configuration>
|
||||||
|
</storageModule>
|
||||||
|
<storageModule moduleId="scannerConfiguration">
|
||||||
|
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile"/>
|
||||||
|
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
|
||||||
|
<buildOutputProvider>
|
||||||
|
<openAction enabled="true" filePath=""/>
|
||||||
|
<parser enabled="true"/>
|
||||||
|
</buildOutputProvider>
|
||||||
|
<scannerInfoProvider id="specsFile">
|
||||||
|
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
|
||||||
|
<parser enabled="true"/>
|
||||||
|
</scannerInfoProvider>
|
||||||
|
</profile>
|
||||||
|
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
|
||||||
|
<buildOutputProvider>
|
||||||
|
<openAction enabled="true" filePath=""/>
|
||||||
|
<parser enabled="true"/>
|
||||||
|
</buildOutputProvider>
|
||||||
|
<scannerInfoProvider id="makefileGenerator">
|
||||||
|
<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
|
||||||
|
<parser enabled="true"/>
|
||||||
|
</scannerInfoProvider>
|
||||||
|
</profile>
|
||||||
|
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
|
||||||
|
<buildOutputProvider>
|
||||||
|
<openAction enabled="true" filePath=""/>
|
||||||
|
<parser enabled="true"/>
|
||||||
|
</buildOutputProvider>
|
||||||
|
<scannerInfoProvider id="specsFile">
|
||||||
|
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
|
||||||
|
<parser enabled="true"/>
|
||||||
|
</scannerInfoProvider>
|
||||||
|
</profile>
|
||||||
|
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
|
||||||
|
<buildOutputProvider>
|
||||||
|
<openAction enabled="true" filePath=""/>
|
||||||
|
<parser enabled="true"/>
|
||||||
|
</buildOutputProvider>
|
||||||
|
<scannerInfoProvider id="specsFile">
|
||||||
|
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
|
||||||
|
<parser enabled="true"/>
|
||||||
|
</scannerInfoProvider>
|
||||||
|
</profile>
|
||||||
|
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
|
||||||
|
<buildOutputProvider>
|
||||||
|
<openAction enabled="true" filePath=""/>
|
||||||
|
<parser enabled="true"/>
|
||||||
|
</buildOutputProvider>
|
||||||
|
<scannerInfoProvider id="specsFile">
|
||||||
|
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
|
||||||
|
<parser enabled="true"/>
|
||||||
|
</scannerInfoProvider>
|
||||||
|
</profile>
|
||||||
|
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
|
||||||
|
<buildOutputProvider>
|
||||||
|
<openAction enabled="true" filePath=""/>
|
||||||
|
<parser enabled="true"/>
|
||||||
|
</buildOutputProvider>
|
||||||
|
<scannerInfoProvider id="specsFile">
|
||||||
|
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
|
||||||
|
<parser enabled="true"/>
|
||||||
|
</scannerInfoProvider>
|
||||||
|
</profile>
|
||||||
|
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
|
||||||
|
<buildOutputProvider>
|
||||||
|
<openAction enabled="true" filePath=""/>
|
||||||
|
<parser enabled="true"/>
|
||||||
|
</buildOutputProvider>
|
||||||
|
<scannerInfoProvider id="specsFile">
|
||||||
|
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
|
||||||
|
<parser enabled="true"/>
|
||||||
|
</scannerInfoProvider>
|
||||||
|
</profile>
|
||||||
|
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
|
||||||
|
<buildOutputProvider>
|
||||||
|
<openAction enabled="true" filePath=""/>
|
||||||
|
<parser enabled="true"/>
|
||||||
|
</buildOutputProvider>
|
||||||
|
<scannerInfoProvider id="specsFile">
|
||||||
|
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
|
||||||
|
<parser enabled="true"/>
|
||||||
|
</scannerInfoProvider>
|
||||||
|
</profile>
|
||||||
|
<profile id="de.innot.avreclipse.core.AVRGCCManagedMakePerProjectProfileC">
|
||||||
|
<buildOutputProvider>
|
||||||
|
<openAction enabled="true" filePath=""/>
|
||||||
|
<parser enabled="true"/>
|
||||||
|
</buildOutputProvider>
|
||||||
|
<scannerInfoProvider id="specsFile">
|
||||||
|
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="avr-gcc" useDefault="true"/>
|
||||||
|
<parser enabled="true"/>
|
||||||
|
</scannerInfoProvider>
|
||||||
|
</profile>
|
||||||
|
<profile id="de.innot.avreclipse.core.AVRGCCManagedMakePerProjectProfileCPP">
|
||||||
|
<buildOutputProvider>
|
||||||
|
<openAction enabled="true" filePath=""/>
|
||||||
|
<parser enabled="true"/>
|
||||||
|
</buildOutputProvider>
|
||||||
|
<scannerInfoProvider id="specsFile">
|
||||||
|
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="avr-g++" useDefault="true"/>
|
||||||
|
<parser enabled="true"/>
|
||||||
|
</scannerInfoProvider>
|
||||||
|
</profile>
|
||||||
|
</storageModule>
|
||||||
|
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||||
|
</cconfiguration>
|
||||||
|
</storageModule>
|
||||||
|
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||||
|
<project id="bsnes2.null.2078314739" name="bsnes2"/>
|
||||||
|
</storageModule>
|
||||||
|
</cproject>
|
||||||
78
tools/bsnes/.project
Normal file
78
tools/bsnes/.project
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<projectDescription>
|
||||||
|
<name>bsnes</name>
|
||||||
|
<comment></comment>
|
||||||
|
<projects>
|
||||||
|
</projects>
|
||||||
|
<buildSpec>
|
||||||
|
<buildCommand>
|
||||||
|
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
|
||||||
|
<triggers>clean,full,incremental,</triggers>
|
||||||
|
<arguments>
|
||||||
|
<dictionary>
|
||||||
|
<key>?name?</key>
|
||||||
|
<value></value>
|
||||||
|
</dictionary>
|
||||||
|
<dictionary>
|
||||||
|
<key>org.eclipse.cdt.make.core.append_environment</key>
|
||||||
|
<value>true</value>
|
||||||
|
</dictionary>
|
||||||
|
<dictionary>
|
||||||
|
<key>org.eclipse.cdt.make.core.autoBuildTarget</key>
|
||||||
|
<value>all</value>
|
||||||
|
</dictionary>
|
||||||
|
<dictionary>
|
||||||
|
<key>org.eclipse.cdt.make.core.buildArguments</key>
|
||||||
|
<value></value>
|
||||||
|
</dictionary>
|
||||||
|
<dictionary>
|
||||||
|
<key>org.eclipse.cdt.make.core.buildCommand</key>
|
||||||
|
<value>make</value>
|
||||||
|
</dictionary>
|
||||||
|
<dictionary>
|
||||||
|
<key>org.eclipse.cdt.make.core.cleanBuildTarget</key>
|
||||||
|
<value>clean</value>
|
||||||
|
</dictionary>
|
||||||
|
<dictionary>
|
||||||
|
<key>org.eclipse.cdt.make.core.contents</key>
|
||||||
|
<value>org.eclipse.cdt.make.core.activeConfigSettings</value>
|
||||||
|
</dictionary>
|
||||||
|
<dictionary>
|
||||||
|
<key>org.eclipse.cdt.make.core.enableAutoBuild</key>
|
||||||
|
<value>false</value>
|
||||||
|
</dictionary>
|
||||||
|
<dictionary>
|
||||||
|
<key>org.eclipse.cdt.make.core.enableCleanBuild</key>
|
||||||
|
<value>true</value>
|
||||||
|
</dictionary>
|
||||||
|
<dictionary>
|
||||||
|
<key>org.eclipse.cdt.make.core.enableFullBuild</key>
|
||||||
|
<value>true</value>
|
||||||
|
</dictionary>
|
||||||
|
<dictionary>
|
||||||
|
<key>org.eclipse.cdt.make.core.fullBuildTarget</key>
|
||||||
|
<value>all</value>
|
||||||
|
</dictionary>
|
||||||
|
<dictionary>
|
||||||
|
<key>org.eclipse.cdt.make.core.stopOnError</key>
|
||||||
|
<value>true</value>
|
||||||
|
</dictionary>
|
||||||
|
<dictionary>
|
||||||
|
<key>org.eclipse.cdt.make.core.useDefaultBuildCmd</key>
|
||||||
|
<value>true</value>
|
||||||
|
</dictionary>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
<buildCommand>
|
||||||
|
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
</buildSpec>
|
||||||
|
<natures>
|
||||||
|
<nature>org.eclipse.cdt.core.cnature</nature>
|
||||||
|
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
|
||||||
|
<nature>org.eclipse.cdt.core.ccnature</nature>
|
||||||
|
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
|
||||||
|
</natures>
|
||||||
|
</projectDescription>
|
||||||
@@ -1,110 +1,109 @@
|
|||||||
include lib/nall/Makefile.string
|
include lib/nall/Makefile
|
||||||
prefix = /usr/local
|
|
||||||
ui = ui_qt
|
ui = ui_qt
|
||||||
|
|
||||||
|
|
||||||
|
platform=mac
|
||||||
|
compiler=gcc
|
||||||
|
enable_gzip=false
|
||||||
|
|
||||||
################
|
################
|
||||||
### compiler ###
|
### compiler ###
|
||||||
################
|
################
|
||||||
|
|
||||||
ifneq ($(findstring gcc,$(compiler)),) # GCC family
|
c := $(compiler)
|
||||||
flags = -O3 -fomit-frame-pointer -Ilib
|
cpp := $(subst cc,++,$(compiler))
|
||||||
# note: libco *requires* -fomit-frame-pointer on i386 arch
|
flags := -ggdb3 -O3 -fomit-frame-pointer -Ilib
|
||||||
libcoflags := $(flags) -static
|
|
||||||
c = $(compiler)
|
link :=
|
||||||
cpp = $(subst cc,++,$(compiler))
|
|
||||||
obj = o
|
################
|
||||||
rule = -c $< -o $@
|
### platform ###
|
||||||
link = -s
|
################
|
||||||
mkbin = -o$1
|
|
||||||
mkdef = -D$1
|
ifeq ($(platform),mac)
|
||||||
mkincpath = -I$1
|
flags +=-I/Developer/SDKs/Qt/include \
|
||||||
mklib = -l$1
|
-I/Developer/SDKs/Qt/include/QtCore \
|
||||||
mklibpath = -L$1
|
-I/Developer/SDKs/Qt/include/QtGui \
|
||||||
|
-I/System/Library/Frameworks/OpenGL.framework/Versions/A/Headers \
|
||||||
|
-I/System/Library/Frameworks/AGL.framework/Headers \
|
||||||
|
-I/System/Library/Frameworks/OpenAL.framework/Versions/A/Headers \
|
||||||
|
-I/usr/X11R6/include \
|
||||||
|
-I/opt/local/include
|
||||||
|
|
||||||
|
link += -lz \
|
||||||
|
-lm \
|
||||||
|
-lao \
|
||||||
|
-framework ApplicationServices \
|
||||||
|
-framework OpenGL \
|
||||||
|
-framework OpenAL \
|
||||||
|
-framework AGL \
|
||||||
|
-L/opt/local/lib \
|
||||||
|
-lSDL -Wl,-framework,Cocoa \
|
||||||
|
-lXext \
|
||||||
|
-lgl \
|
||||||
|
-lX11
|
||||||
|
#ruby := video.glx video.sdl
|
||||||
|
#ruby += audio.openal audio.ao
|
||||||
|
#ruby += input.sdl
|
||||||
|
#-DVIDEO_GLX -DVIDEO_XV -DVIDEO_SDL -DAUDIO_ALS
|
||||||
|
#-DAUDIO_OPENAL -DAUDIO_OSS -DAUDIO_PULSEAUDIO
|
||||||
|
#-DAUDIO_AO -DINPUT_SDL -DINPUT_X
|
||||||
|
flags += -DVIDEO_SDL -DINPUT_SDL -DVIDEO_GLX -DAUDIO_AO -DAUDIO_OPENAL
|
||||||
|
|
||||||
# profile-guided optimization:
|
|
||||||
# flags += -fprofile-generate
|
|
||||||
# link += -lgcov
|
|
||||||
# flags += -fprofile-use
|
|
||||||
else ifeq ($(compiler),cl) # Visual C++
|
|
||||||
flags = /nologo /wd4355 /wd4805 /wd4996 /Ox /GL /EHsc /Ilib
|
|
||||||
libcoflags = $(flags)
|
|
||||||
c = cl
|
|
||||||
cpp = cl
|
|
||||||
obj = obj
|
|
||||||
rule = /c $< /Fo$@
|
|
||||||
link = /link
|
|
||||||
mkbin = /Fe$1
|
|
||||||
mkdef = /D$1
|
|
||||||
mkincpath = /I$1
|
|
||||||
mklib = $1.lib
|
|
||||||
mklibpath = /L$1
|
|
||||||
else
|
|
||||||
unknown_compiler: help;
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
##########
|
ifeq ($(platform),x)
|
||||||
### os ###
|
ruby := video.glx video.xv video.sdl
|
||||||
##########
|
ruby += audio.alsa audio.openal audio.oss audio.pulseaudio audio.ao
|
||||||
|
ruby += input.sdl input.x
|
||||||
|
else ifeq ($(platform),win)
|
||||||
|
ruby := video.direct3d video.wgl video.directdraw video.gdi
|
||||||
|
ruby += audio.directsound
|
||||||
|
ruby += input.rawinput input.directinput
|
||||||
|
|
||||||
ifeq ($(platform),x) # X11
|
link += -mwindows
|
||||||
ruby = video.glx video.xv video.sdl audio.alsa audio.openal audio.oss audio.pulseaudio audio.ao input.sdl input.x
|
link += -luuid -lkernel32 -luser32 -lgdi32 -lshell32
|
||||||
delete = rm -f $1
|
# statically link Qt for Windows build
|
||||||
else ifeq ($(platform),win) # Windows
|
link += -enable-stdcall-fixup -Wl,-s -Wl,-enable-auto-import -Wl,-enable-runtime-pseudo-reloc
|
||||||
mingw_link_flags = -mwindows
|
|
||||||
# mingw_links_flags = -mconsole
|
|
||||||
|
|
||||||
# enable static linking to Qt for Windows build
|
|
||||||
mingw_link_flags += -enable-stdcall-fixup -Wl,-s -Wl,-enable-auto-import -Wl,-enable-runtime-pseudo-reloc
|
|
||||||
|
|
||||||
ruby = video.direct3d video.wgl video.directdraw video.gdi audio.directsound input.rawinput input.directinput
|
|
||||||
delete = $(if $(findstring i586-mingw-gcc,$(compiler)),rm -f $1,del $(subst /,\,$1))
|
|
||||||
link += $(if $(findstring mingw,$(compiler)),$(mingw_link_flags))
|
|
||||||
link += $(call mklib,uuid)
|
|
||||||
link += $(call mklib,kernel32)
|
|
||||||
link += $(call mklib,user32)
|
|
||||||
link += $(call mklib,gdi32)
|
|
||||||
link += $(call mklib,shell32)
|
|
||||||
else
|
|
||||||
unknown_platform: help;
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
############
|
############
|
||||||
### ruby ###
|
### ruby ###
|
||||||
############
|
############
|
||||||
|
|
||||||
rubyflags = $(if $(findstring .sdl,$(ruby)),`sdl-config --cflags`)
|
rubyflags = $(call ifhas,.sdl,$(ruby),`sdl-config --cflags`)
|
||||||
link += $(if $(findstring .sdl,$(ruby)),`sdl-config --libs`)
|
|
||||||
|
|
||||||
link += $(if $(findstring video.direct3d,$(ruby)),$(call mklib,d3d9))
|
link += $(call ifhas,.sdl,$(ruby),`sdl-config --libs`)
|
||||||
link += $(if $(findstring video.directdraw,$(ruby)),$(call mklib,ddraw))
|
link += $(call ifhas,video.direct3d,$(ruby),-ld3d9)
|
||||||
link += $(if $(findstring video.glx,$(ruby)),$(call mklib,GL))
|
link += $(call ifhas,video.directdraw,$(ruby),-lddraw)
|
||||||
link += $(if $(findstring video.wgl,$(ruby)),$(call mklib,opengl32))
|
link += $(call ifhas,video.glx,$(ruby),-lGL)
|
||||||
link += $(if $(findstring video.xv,$(ruby)),$(call mklib,Xv))
|
link += $(call ifhas,video.wgl,$(ruby),-lopengl32)
|
||||||
link += $(if $(findstring audio.alsa,$(ruby)),$(call mklib,asound))
|
link += $(call ifhas,video.xv,$(ruby),-lXv)
|
||||||
link += $(if $(findstring audio.ao,$(ruby)),$(call mklib,ao))
|
link += $(call ifhas,audio.alsa,$(ruby),-lasound)
|
||||||
link += $(if $(findstring audio.directsound,$(ruby)),$(call mklib,dsound))
|
link += $(call ifhas,audio.ao,$(ruby),-lao)
|
||||||
link += $(if $(findstring audio.openal,$(ruby)),$(if $(call streq,$(platform),x),$(call mklib,openal),$(call mklib,openal32)))
|
link += $(call ifhas,audio.directsound,$(ruby),-ldsound)
|
||||||
link += $(if $(findstring audio.pulseaudio,$(ruby)),$(call mklib,pulse-simple))
|
link += $(call ifhas,audio.openal,$(ruby),$(if $(call streq,$(platform),x),-lopenal,-lopenal32))
|
||||||
link += $(if $(findstring input.directinput,$(ruby)),$(call mklib,dinput8) $(call mklib,dxguid))
|
link += $(call ifhas,audio.pulseaudio,$(ruby),-lpulse-simple)
|
||||||
link += $(if $(findstring input.rawinput,$(ruby)),$(call mklib,xinput) $(call mklib,dinput8) $(call mklib,dxguid))
|
link += $(call ifhas,input.directinput,$(ruby),-ldinput8 -ldxguid)
|
||||||
|
link += $(call ifhas,input.rawinput,$(ruby),-lxinput -ldinput8 -ldxguid)
|
||||||
|
|
||||||
####################
|
####################
|
||||||
### core objects ###
|
### core objects ###
|
||||||
####################
|
####################
|
||||||
|
|
||||||
objects = libco ruby libfilter string \
|
objects = libco ruby libreader libfilter string \
|
||||||
reader cart cheat \
|
system cartridge cheat \
|
||||||
memory smemory cpu scpu smp ssmp sdsp ppu bppu snes \
|
memory smemory cpu cpucore scpu smp smpcore ssmp sdsp ppu bppu \
|
||||||
bsx srtc sdd1 spc7110 cx4 dsp1 dsp2 dsp3 dsp4 obc1 st010
|
sgb sa1 bsx srtc sdd1 spc7110 cx4 dsp1 dsp2 dsp3 dsp4 obc1 st010
|
||||||
|
|
||||||
ifeq ($(enable_gzip),true)
|
ifeq ($(enable_gzip),true)
|
||||||
objects += adler32 compress crc32 deflate gzio inffast inflate inftrees ioapi trees unzip zip zutil
|
objects += adler32 compress crc32 deflate gzio inffast inflate inftrees ioapi trees unzip zip zutil
|
||||||
flags += $(call mkdef,GZIP_SUPPORT)
|
flags += -DGZIP_SUPPORT
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(enable_jma),true)
|
ifeq ($(enable_jma),true)
|
||||||
objects += jma jcrc32 lzmadec 7zlzma iiostrm inbyte lzma winout
|
objects += jma jcrc32 lzmadec 7zlzma iiostrm inbyte lzma winout
|
||||||
flags += $(call mkdef,JMA_SUPPORT)
|
flags += -DJMA_SUPPORT
|
||||||
endif
|
endif
|
||||||
|
|
||||||
######################
|
######################
|
||||||
@@ -114,134 +113,137 @@ endif
|
|||||||
compile = \
|
compile = \
|
||||||
$(strip \
|
$(strip \
|
||||||
$(if $(filter %.c,$<), \
|
$(if $(filter %.c,$<), \
|
||||||
$(c) $(flags) $1 $(rule), \
|
$(c) $(flags) $1 -c $< -o $@, \
|
||||||
$(if $(filter %.cpp,$<), \
|
$(if $(filter %.cpp,$<), \
|
||||||
$(cpp) $(flags) $1 $(rule) \
|
$(cpp) $(flags) $1 -c $< -o $@ \
|
||||||
) \
|
) \
|
||||||
) \
|
) \
|
||||||
)
|
)
|
||||||
|
|
||||||
%.$(obj): $<; $(call compile)
|
%.o: $<; $(call compile)
|
||||||
|
|
||||||
all: build;
|
all: build;
|
||||||
|
|
||||||
include $(ui)/Makefile
|
include $(ui)/Makefile
|
||||||
objects := $(patsubst %,obj/%.$(obj),$(objects))
|
objects := $(patsubst %,obj/%.o,$(objects))
|
||||||
rubydef := $(foreach c,$(subst .,_,$(call strupper,$(ruby))),$(call mkdef,$c))
|
rubydef := $(foreach c,$(subst .,_,$(call strupper,$(ruby))),-D$c)
|
||||||
|
|
||||||
#################
|
#################
|
||||||
### libraries ###
|
### libraries ###
|
||||||
#################
|
#################
|
||||||
|
|
||||||
obj/ruby.$(obj): lib/ruby/ruby.cpp lib/ruby/* lib/ruby/video/* lib/ruby/audio/* lib/ruby/input/*
|
obj/ruby.o: lib/ruby/ruby.cpp $(call rwildcard,lib/ruby/*)
|
||||||
$(call compile,$(rubydef) $(rubyflags))
|
$(call compile,$(rubydef) $(rubyflags))
|
||||||
obj/libco.$(obj): lib/libco/libco.c lib/libco/*
|
obj/libco.o: lib/libco/libco.c lib/libco/*
|
||||||
$(c) $(libcoflags) $(rule)
|
$(c) -O3 -fomit-frame-pointer -static -Ilib -c $< -o $@
|
||||||
obj/libfilter.$(obj): lib/libfilter/libfilter.cpp lib/libfilter/*
|
obj/libreader.o: lib/libreader/libreader.cpp lib/libreader/*
|
||||||
obj/string.$(obj): lib/nall/string.cpp lib/nall/*
|
obj/libfilter.o: lib/libfilter/libfilter.cpp lib/libfilter/*
|
||||||
|
obj/string.o: lib/nall/string.cpp lib/nall/*
|
||||||
|
|
||||||
#################
|
#################
|
||||||
### utilities ###
|
### utilities ###
|
||||||
#################
|
#################
|
||||||
|
|
||||||
obj/reader.$(obj): reader/reader.cpp reader/*
|
obj/cartridge.o: cartridge/cartridge.cpp cartridge/*
|
||||||
obj/cart.$(obj) : cart/cart.cpp cart/*
|
obj/cheat.o : cheat/cheat.cpp cheat/*
|
||||||
obj/cheat.$(obj) : cheat/cheat.cpp cheat/*
|
|
||||||
|
|
||||||
##############
|
##############
|
||||||
### memory ###
|
### memory ###
|
||||||
##############
|
##############
|
||||||
|
|
||||||
obj/memory.$(obj) : memory/memory.cpp memory/*
|
obj/memory.o : memory/memory.cpp memory/*
|
||||||
obj/smemory.$(obj): memory/smemory/smemory.cpp memory/smemory/* memory/smemory/mapper/*
|
obj/smemory.o: memory/smemory/smemory.cpp $(call rwildcard,memory/smemory/)
|
||||||
|
|
||||||
###########
|
###########
|
||||||
### cpu ###
|
### cpu ###
|
||||||
###########
|
###########
|
||||||
|
|
||||||
obj/cpu.$(obj) : cpu/cpu.cpp cpu/*
|
obj/cpu.o : cpu/cpu.cpp cpu/*
|
||||||
obj/scpu.$(obj): cpu/scpu/scpu.cpp cpu/scpu/* cpu/scpu/core/* cpu/scpu/dma/* cpu/scpu/memory/* cpu/scpu/mmio/* cpu/scpu/timing/*
|
obj/cpucore.o: cpu/core/core.cpp $(call rwildcard,cpu/core/)
|
||||||
|
obj/scpu.o : cpu/scpu/scpu.cpp $(call rwildcard,cpu/scpu/)
|
||||||
|
|
||||||
###########
|
###########
|
||||||
### smp ###
|
### smp ###
|
||||||
###########
|
###########
|
||||||
|
|
||||||
obj/smp.$(obj) : smp/smp.cpp smp/*
|
obj/smp.o : smp/smp.cpp smp/*
|
||||||
obj/ssmp.$(obj): smp/ssmp/ssmp.cpp smp/ssmp/* smp/ssmp/core/* smp/ssmp/memory/* smp/ssmp/timing/*
|
obj/smpcore.o: smp/core/core.cpp $(call rwildcard,smp/core/)
|
||||||
|
obj/ssmp.o : smp/ssmp/ssmp.cpp $(call rwildcard,smp/ssmp/)
|
||||||
|
|
||||||
###########
|
###########
|
||||||
### dsp ###
|
### dsp ###
|
||||||
###########
|
###########
|
||||||
|
|
||||||
obj/adsp.$(obj): dsp/adsp/adsp.cpp dsp/adsp/*
|
obj/adsp.o: dsp/adsp/adsp.cpp dsp/adsp/*
|
||||||
obj/sdsp.$(obj): dsp/sdsp/sdsp.cpp dsp/sdsp/*
|
obj/sdsp.o: dsp/sdsp/sdsp.cpp dsp/sdsp/*
|
||||||
|
|
||||||
###########
|
###########
|
||||||
### ppu ###
|
### ppu ###
|
||||||
###########
|
###########
|
||||||
|
|
||||||
obj/ppu.$(obj) : ppu/ppu.cpp ppu/*
|
obj/ppu.o : ppu/ppu.cpp ppu/*
|
||||||
obj/bppu.$(obj): ppu/bppu/bppu.cpp ppu/bppu/*
|
obj/bppu.o: ppu/bppu/bppu.cpp ppu/bppu/*
|
||||||
|
|
||||||
############
|
##############
|
||||||
### snes ###
|
### system ###
|
||||||
############
|
##############
|
||||||
|
|
||||||
obj/snes.$(obj): snes/snes.cpp snes/* snes/scheduler/* snes/video/* snes/audio/* snes/input/*
|
obj/system.o: system/system.cpp $(call rwildcard,system/)
|
||||||
|
|
||||||
#####################
|
#####################
|
||||||
### special chips ###
|
### special chips ###
|
||||||
#####################
|
#####################
|
||||||
|
|
||||||
obj/bsx.$(obj) : chip/bsx/bsx.cpp chip/bsx/*
|
obj/sgb.o : chip/sgb/sgb.cpp $(call rwildcard,chip/sgb/)
|
||||||
obj/srtc.$(obj) : chip/srtc/srtc.cpp chip/srtc/*
|
obj/sa1.o : chip/sa1/sa1.cpp $(call rwildcard,chip/sa1/)
|
||||||
obj/sdd1.$(obj) : chip/sdd1/sdd1.cpp chip/sdd1/*
|
obj/bsx.o : chip/bsx/bsx.cpp chip/bsx/*
|
||||||
obj/spc7110.$(obj): chip/spc7110/spc7110.cpp chip/spc7110/*
|
obj/srtc.o : chip/srtc/srtc.cpp chip/srtc/*
|
||||||
obj/cx4.$(obj) : chip/cx4/cx4.cpp chip/cx4/*
|
obj/sdd1.o : chip/sdd1/sdd1.cpp chip/sdd1/*
|
||||||
obj/dsp1.$(obj) : chip/dsp1/dsp1.cpp chip/dsp1/*
|
obj/spc7110.o: chip/spc7110/spc7110.cpp chip/spc7110/*
|
||||||
obj/dsp2.$(obj) : chip/dsp2/dsp2.cpp chip/dsp2/*
|
obj/cx4.o : chip/cx4/cx4.cpp chip/cx4/*
|
||||||
obj/dsp3.$(obj) : chip/dsp3/dsp3.cpp chip/dsp3/*
|
obj/dsp1.o : chip/dsp1/dsp1.cpp chip/dsp1/*
|
||||||
obj/dsp4.$(obj) : chip/dsp4/dsp4.cpp chip/dsp4/*
|
obj/dsp2.o : chip/dsp2/dsp2.cpp chip/dsp2/*
|
||||||
obj/obc1.$(obj) : chip/obc1/obc1.cpp chip/obc1/*
|
obj/dsp3.o : chip/dsp3/dsp3.cpp chip/dsp3/*
|
||||||
obj/st010.$(obj) : chip/st010/st010.cpp chip/st010/*
|
obj/dsp4.o : chip/dsp4/dsp4.cpp chip/dsp4/*
|
||||||
|
obj/obc1.o : chip/obc1/obc1.cpp chip/obc1/*
|
||||||
|
obj/st010.o : chip/st010/st010.cpp chip/st010/*
|
||||||
|
|
||||||
############
|
############
|
||||||
### zlib ###
|
### zlib ###
|
||||||
############
|
############
|
||||||
|
|
||||||
obj/adler32.$(obj) : reader/zlib/adler32.c reader/zlib/*
|
obj/adler32.o : lib/zlib/adler32.c lib/zlib/*
|
||||||
obj/compress.$(obj): reader/zlib/compress.c reader/zlib/*
|
obj/compress.o: lib/zlib/compress.c lib/zlib/*
|
||||||
obj/crc32.$(obj) : reader/zlib/crc32.c reader/zlib/*
|
obj/crc32.o : lib/zlib/crc32.c lib/zlib/*
|
||||||
obj/deflate.$(obj) : reader/zlib/deflate.c reader/zlib/*
|
obj/deflate.o : lib/zlib/deflate.c lib/zlib/*
|
||||||
obj/gzio.$(obj) : reader/zlib/gzio.c reader/zlib/*
|
obj/gzio.o : lib/zlib/gzio.c lib/zlib/*
|
||||||
obj/inffast.$(obj) : reader/zlib/inffast.c reader/zlib/*
|
obj/inffast.o : lib/zlib/inffast.c lib/zlib/*
|
||||||
obj/inflate.$(obj) : reader/zlib/inflate.c reader/zlib/*
|
obj/inflate.o : lib/zlib/inflate.c lib/zlib/*
|
||||||
obj/inftrees.$(obj): reader/zlib/inftrees.c reader/zlib/*
|
obj/inftrees.o: lib/zlib/inftrees.c lib/zlib/*
|
||||||
obj/ioapi.$(obj) : reader/zlib/ioapi.c reader/zlib/*
|
obj/ioapi.o : lib/zlib/ioapi.c lib/zlib/*
|
||||||
obj/trees.$(obj) : reader/zlib/trees.c reader/zlib/*
|
obj/trees.o : lib/zlib/trees.c lib/zlib/*
|
||||||
obj/unzip.$(obj) : reader/zlib/unzip.c reader/zlib/*
|
obj/unzip.o : lib/zlib/unzip.c lib/zlib/*
|
||||||
obj/zip.$(obj) : reader/zlib/zip.c reader/zlib/*
|
obj/zip.o : lib/zlib/zip.c lib/zlib/*
|
||||||
obj/zutil.$(obj) : reader/zlib/zutil.c reader/zlib/*
|
obj/zutil.o : lib/zlib/zutil.c lib/zlib/*
|
||||||
|
|
||||||
###########
|
##############
|
||||||
### jma ###
|
### libjma ###
|
||||||
###########
|
##############
|
||||||
|
|
||||||
obj/jma.$(obj) : reader/jma/jma.cpp reader/jma/*
|
obj/jma.o : lib/libjma/jma.cpp lib/libjma/*
|
||||||
obj/jcrc32.$(obj) : reader/jma/jcrc32.cpp reader/jma/*
|
obj/jcrc32.o : lib/libjma/jcrc32.cpp lib/libjma/*
|
||||||
obj/lzmadec.$(obj): reader/jma/lzmadec.cpp reader/jma/*
|
obj/lzmadec.o: lib/libjma/lzmadec.cpp lib/libjma/*
|
||||||
obj/7zlzma.$(obj) : reader/jma/7zlzma.cpp reader/jma/*
|
obj/7zlzma.o : lib/libjma/7zlzma.cpp lib/libjma/*
|
||||||
obj/iiostrm.$(obj): reader/jma/iiostrm.cpp reader/jma/*
|
obj/iiostrm.o: lib/libjma/iiostrm.cpp lib/libjma/*
|
||||||
obj/inbyte.$(obj) : reader/jma/inbyte.cpp reader/jma/*
|
obj/inbyte.o : lib/libjma/inbyte.cpp lib/libjma/*
|
||||||
obj/lzma.$(obj) : reader/jma/lzma.cpp reader/jma/*
|
obj/lzma.o : lib/libjma/lzma.cpp lib/libjma/*
|
||||||
obj/winout.$(obj) : reader/jma/winout.cpp reader/jma/*
|
obj/winout.o : lib/libjma/winout.cpp lib/libjma/*
|
||||||
|
|
||||||
###############
|
###############
|
||||||
### targets ###
|
### targets ###
|
||||||
###############
|
###############
|
||||||
|
|
||||||
build: ui_build $(objects)
|
build: ui_build $(objects)
|
||||||
$(strip $(cpp) $(call mkbin,../bsnes) $(objects) $(link))
|
$(strip g++ -o bsnes $(objects) $(link))
|
||||||
|
|
||||||
install:
|
install:
|
||||||
install -D -m 755 ../bsnes $(DESTDIR)$(prefix)/bin/bsnes
|
install -D -m 755 ../bsnes $(DESTDIR)$(prefix)/bin/bsnes
|
||||||
@@ -249,13 +251,7 @@ install:
|
|||||||
install -D -m 644 data/bsnes.desktop $(DESTDIR)$(prefix)/share/applications/bsnes.desktop
|
install -D -m 644 data/bsnes.desktop $(DESTDIR)$(prefix)/share/applications/bsnes.desktop
|
||||||
|
|
||||||
clean: ui_clean
|
clean: ui_clean
|
||||||
-@$(call delete,obj/*.$(obj))
|
rm obj/*.o
|
||||||
-@$(call delete,*.res)
|
|
||||||
-@$(call delete,*.pgd)
|
|
||||||
-@$(call delete,*.pgc)
|
|
||||||
-@$(call delete,*.ilk)
|
|
||||||
-@$(call delete,*.pdb)
|
|
||||||
-@$(call delete,*.manifest)
|
|
||||||
|
|
||||||
help:
|
help:
|
||||||
@echo "Usage: $(MAKE) platform=(os) compiler=(cc) [options]"
|
@echo "Usage: $(MAKE) platform=(os) compiler=(cc) [options]"
|
||||||
@@ -268,7 +264,6 @@ help:
|
|||||||
@echo " gcc - GCC compiler"
|
@echo " gcc - GCC compiler"
|
||||||
@echo " mingw32-gcc - MinGW compiler"
|
@echo " mingw32-gcc - MinGW compiler"
|
||||||
@echo " i586-mingw32-gcc - MinGW cross compiler"
|
@echo " i586-mingw32-gcc - MinGW cross compiler"
|
||||||
@echo " cl - Visual C++"
|
|
||||||
@echo ""
|
@echo ""
|
||||||
@echo "Available options:"
|
@echo "Available options:"
|
||||||
@echo " enable_gzip=[true|false] - Enable ZIP / GZ support (default=false)"
|
@echo " enable_gzip=[true|false] - Enable ZIP / GZ support (default=false)"
|
||||||
@@ -276,3 +271,4 @@ help:
|
|||||||
@echo ""
|
@echo ""
|
||||||
@echo "Example: $(MAKE) platform=x compiler=gcc enable_gzip=true"
|
@echo "Example: $(MAKE) platform=x compiler=gcc enable_gzip=true"
|
||||||
@echo ""
|
@echo ""
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#define BSNES_VERSION "0.042"
|
#define BSNES_VERSION "0.046"
|
||||||
#define BSNES_TITLE "bsnes v" BSNES_VERSION
|
#define BSNES_TITLE "bsnes v" BSNES_VERSION
|
||||||
|
|
||||||
#define BUSCORE sBus
|
#define BUSCORE sBus
|
||||||
@@ -9,12 +9,7 @@
|
|||||||
|
|
||||||
//S-DSP can be encapsulated into a state machine using #define magic
|
//S-DSP can be encapsulated into a state machine using #define magic
|
||||||
//this avoids ~2.048m co_switch() calls per second (~5% speedup)
|
//this avoids ~2.048m co_switch() calls per second (~5% speedup)
|
||||||
#define USE_STATE_MACHINE
|
#define DSP_STATE_MACHINE
|
||||||
|
|
||||||
//FAST_FRAMESKIP disables calculation of RTO during frameskip
|
|
||||||
//frameskip offers near-zero speedup if RTO is calculated
|
|
||||||
//accuracy is not affected by this define when frameskipping is off
|
|
||||||
#define FAST_FRAMESKIP
|
|
||||||
|
|
||||||
//game genie + pro action replay code support (~2% speed hit)
|
//game genie + pro action replay code support (~2% speed hit)
|
||||||
#define CHEAT_SYSTEM
|
#define CHEAT_SYSTEM
|
||||||
@@ -25,8 +20,9 @@
|
|||||||
#include <nall/array.hpp>
|
#include <nall/array.hpp>
|
||||||
#include <nall/bit.hpp>
|
#include <nall/bit.hpp>
|
||||||
#include <nall/detect.hpp>
|
#include <nall/detect.hpp>
|
||||||
|
#include <nall/dl.hpp>
|
||||||
#include <nall/endian.hpp>
|
#include <nall/endian.hpp>
|
||||||
#include <nall/file.hpp>
|
#include <nall/function.hpp>
|
||||||
#include <nall/moduloarray.hpp>
|
#include <nall/moduloarray.hpp>
|
||||||
#include <nall/new.hpp>
|
#include <nall/new.hpp>
|
||||||
#include <nall/platform.hpp>
|
#include <nall/platform.hpp>
|
||||||
@@ -40,10 +36,9 @@ using namespace nall;
|
|||||||
typedef int8_t int8;
|
typedef int8_t int8;
|
||||||
typedef int16_t int16;
|
typedef int16_t int16;
|
||||||
typedef int32_t int32;
|
typedef int32_t int32;
|
||||||
typedef int64_t int64;
|
|
||||||
typedef uint8_t uint8;
|
typedef uint8_t uint8;
|
||||||
typedef uint16_t uint16;
|
typedef uint16_t uint16;
|
||||||
typedef uint32_t uint32;
|
typedef uint32_t uint32;
|
||||||
typedef uint64_t uint64;
|
|
||||||
|
|
||||||
#include "interface.hpp"
|
#include "interface.hpp"
|
||||||
|
|
||||||
|
|||||||
@@ -1,234 +0,0 @@
|
|||||||
#include <../base.hpp>
|
|
||||||
#include <../chip/chip.hpp>
|
|
||||||
#include <../reader/reader.hpp>
|
|
||||||
#define CART_CPP
|
|
||||||
|
|
||||||
#include <nall/crc32.hpp>
|
|
||||||
#include <nall/ups.hpp>
|
|
||||||
|
|
||||||
#include "cart.hpp"
|
|
||||||
#include "cart_file.cpp"
|
|
||||||
#include "cart_header.cpp"
|
|
||||||
#include "cart_loader.cpp"
|
|
||||||
|
|
||||||
namespace memory {
|
|
||||||
MappedRAM cartrom, cartram, cartrtc;
|
|
||||||
MappedRAM bscram;
|
|
||||||
MappedRAM stArom, stAram;
|
|
||||||
MappedRAM stBrom, stBram;
|
|
||||||
};
|
|
||||||
|
|
||||||
Cartridge cartridge;
|
|
||||||
|
|
||||||
void Cartridge::load_begin(Mode cartridge_mode) {
|
|
||||||
cart.rom = cart.ram = cart.rtc = 0;
|
|
||||||
bs.ram = 0;
|
|
||||||
stA.rom = stA.ram = 0;
|
|
||||||
stB.rom = stB.ram = 0;
|
|
||||||
|
|
||||||
cart.rom_size = cart.ram_size = cart.rtc_size = 0;
|
|
||||||
bs.ram_size = 0;
|
|
||||||
stA.rom_size = stA.ram_size = 0;
|
|
||||||
stB.rom_size = stB.ram_size = 0;
|
|
||||||
|
|
||||||
set(loaded, false);
|
|
||||||
set(bsx_flash_loaded, false);
|
|
||||||
set(patched, false);
|
|
||||||
set(mode, cartridge_mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Cartridge::load_end() {
|
|
||||||
memory::cartrom.map(cart.rom, cart.rom_size);
|
|
||||||
memory::cartram.map(cart.ram, cart.ram_size);
|
|
||||||
memory::cartrtc.map(cart.rtc, cart.rtc_size);
|
|
||||||
memory::bscram.map(bs.ram, bs.ram_size);
|
|
||||||
memory::stArom.map(stA.rom, stA.rom_size);
|
|
||||||
memory::stAram.map(stA.ram, stA.ram_size);
|
|
||||||
memory::stBrom.map(stB.rom, stB.rom_size);
|
|
||||||
memory::stBram.map(stB.ram, stB.ram_size);
|
|
||||||
|
|
||||||
memory::cartrom.write_protect(true);
|
|
||||||
memory::cartram.write_protect(false);
|
|
||||||
memory::bscram.write_protect(true);
|
|
||||||
memory::stArom.write_protect(true);
|
|
||||||
memory::stAram.write_protect(false);
|
|
||||||
memory::stBrom.write_protect(true);
|
|
||||||
memory::stBram.write_protect(false);
|
|
||||||
|
|
||||||
string cheat_file = get_filename(cart.filename, "cht", snes.config.path.cheat);
|
|
||||||
if(file::exists(cheat_file)) {
|
|
||||||
cheat.clear();
|
|
||||||
cheat.load(cheat_file);
|
|
||||||
}
|
|
||||||
|
|
||||||
bus.load_cart();
|
|
||||||
set(loaded, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Cartridge::unload() {
|
|
||||||
if(loaded() == false) return;
|
|
||||||
bus.unload_cart();
|
|
||||||
|
|
||||||
switch(mode()) {
|
|
||||||
case ModeNormal: unload_normal(); break;
|
|
||||||
case ModeBsxSlotted: unload_bsx_slotted(); break;
|
|
||||||
case ModeBsx: unload_bsx(); break;
|
|
||||||
case ModeSufamiTurbo: unload_sufami_turbo(); break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(cart.rom) { delete[] cart.rom; cart.rom = 0; }
|
|
||||||
if(cart.ram) { delete[] cart.ram; cart.ram = 0; }
|
|
||||||
if(cart.rtc) { delete[] cart.rtc; cart.rtc = 0; }
|
|
||||||
if(bs.ram) { delete[] bs.ram; bs.ram = 0; }
|
|
||||||
if(stA.rom) { delete[] stA.rom; stA.rom = 0; }
|
|
||||||
if(stA.ram) { delete[] stA.ram; stA.ram = 0; }
|
|
||||||
if(stB.rom) { delete[] stB.rom; stB.rom = 0; }
|
|
||||||
if(stB.ram) { delete[] stB.ram; stB.ram = 0; }
|
|
||||||
|
|
||||||
string cheat_file = get_filename(cart.filename, "cht", snes.config.path.cheat);
|
|
||||||
if(cheat.count() > 0 || file::exists(cheat_file)) {
|
|
||||||
cheat.save(cheat_file);
|
|
||||||
cheat.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
set(loaded, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
Cartridge::Cartridge() {
|
|
||||||
set(loaded, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
Cartridge::~Cartridge() {
|
|
||||||
if(loaded() == true) unload();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Cartridge::set_cartinfo(const Cartridge::cartinfo_t &source) {
|
|
||||||
set(region, source.region);
|
|
||||||
set(mapper, source.mapper);
|
|
||||||
set(dsp1_mapper, source.dsp1_mapper);
|
|
||||||
|
|
||||||
set(has_bsx_slot, source.bsx_slot);
|
|
||||||
set(has_superfx, source.superfx);
|
|
||||||
set(has_sa1, source.sa1);
|
|
||||||
set(has_srtc, source.srtc);
|
|
||||||
set(has_sdd1, source.sdd1);
|
|
||||||
set(has_spc7110, source.spc7110);
|
|
||||||
set(has_spc7110rtc, source.spc7110rtc);
|
|
||||||
set(has_cx4, source.cx4);
|
|
||||||
set(has_dsp1, source.dsp1);
|
|
||||||
set(has_dsp2, source.dsp2);
|
|
||||||
set(has_dsp3, source.dsp3);
|
|
||||||
set(has_dsp4, source.dsp4);
|
|
||||||
set(has_obc1, source.obc1);
|
|
||||||
set(has_st010, source.st010);
|
|
||||||
set(has_st011, source.st011);
|
|
||||||
set(has_st018, source.st018);
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========
|
|
||||||
//cartinfo_t
|
|
||||||
//==========
|
|
||||||
|
|
||||||
void Cartridge::cartinfo_t::reset() {
|
|
||||||
type = TypeUnknown;
|
|
||||||
mapper = LoROM;
|
|
||||||
dsp1_mapper = DSP1Unmapped;
|
|
||||||
region = NTSC;
|
|
||||||
|
|
||||||
rom_size = 0;
|
|
||||||
ram_size = 0;
|
|
||||||
|
|
||||||
bsx_slot = false;
|
|
||||||
superfx = false;
|
|
||||||
sa1 = false;
|
|
||||||
srtc = false;
|
|
||||||
sdd1 = false;
|
|
||||||
spc7110 = false;
|
|
||||||
spc7110rtc = false;
|
|
||||||
cx4 = false;
|
|
||||||
dsp1 = false;
|
|
||||||
dsp2 = false;
|
|
||||||
dsp3 = false;
|
|
||||||
dsp4 = false;
|
|
||||||
obc1 = false;
|
|
||||||
st010 = false;
|
|
||||||
st011 = false;
|
|
||||||
st018 = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Cartridge::cartinfo_t::cartinfo_t() {
|
|
||||||
reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
//=======
|
|
||||||
//utility
|
|
||||||
//=======
|
|
||||||
|
|
||||||
//ensure file path is absolute (eg resolve relative paths)
|
|
||||||
string Cartridge::filepath(const char *filename, const char *pathname) {
|
|
||||||
//if no pathname, return filename as-is
|
|
||||||
string file(filename);
|
|
||||||
file.replace("\\", "/");
|
|
||||||
|
|
||||||
string path = (!pathname || !*pathname) ? (const char*)snes.config.path.current : pathname;
|
|
||||||
//ensure path ends with trailing '/'
|
|
||||||
path.replace("\\", "/");
|
|
||||||
if(!strend(path, "/")) path.append("/");
|
|
||||||
|
|
||||||
//replace relative path with absolute path
|
|
||||||
if(strbegin(path, "./")) {
|
|
||||||
ltrim(path, "./");
|
|
||||||
path = string() << snes.config.path.base << path;
|
|
||||||
}
|
|
||||||
|
|
||||||
//remove folder part of filename
|
|
||||||
lstring part;
|
|
||||||
part.split("/", file);
|
|
||||||
return path << part[part.size() - 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
//remove directory information and file extension ("/foo/bar.ext" -> "bar")
|
|
||||||
string Cartridge::basename(const char *filename) {
|
|
||||||
string name(filename);
|
|
||||||
|
|
||||||
//remove extension
|
|
||||||
for(signed i = strlen(name) - 1; i >= 0; i--) {
|
|
||||||
if(name[i] == '.') {
|
|
||||||
name[i] = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//remove directory information
|
|
||||||
for(signed i = strlen(name) - 1; i >= 0; i--) {
|
|
||||||
if(name[i] == '/' || name[i] == '\\') {
|
|
||||||
i++;
|
|
||||||
char *output = name();
|
|
||||||
while(true) {
|
|
||||||
*output++ = name[i];
|
|
||||||
if(!name[i]) break;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
//remove filename and return path only ("/foo/bar.ext" -> "/foo/bar/")
|
|
||||||
string Cartridge::basepath(const char *filename) {
|
|
||||||
string path(filename);
|
|
||||||
path.replace("\\", "/");
|
|
||||||
|
|
||||||
//remove filename
|
|
||||||
for(signed i = strlen(path) - 1; i >= 0; i--) {
|
|
||||||
if(path[i] == '/') {
|
|
||||||
path[i] = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!strend(path, "/")) path.append("/");
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
@@ -1,178 +0,0 @@
|
|||||||
class Cartridge : public property {
|
|
||||||
public:
|
|
||||||
enum Mode {
|
|
||||||
ModeNormal,
|
|
||||||
ModeBsxSlotted,
|
|
||||||
ModeBsx,
|
|
||||||
ModeSufamiTurbo,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum Type {
|
|
||||||
TypeNormal,
|
|
||||||
TypeBsxSlotted,
|
|
||||||
TypeBsxBios,
|
|
||||||
TypeBsx,
|
|
||||||
TypeSufamiTurboBios,
|
|
||||||
TypeSufamiTurbo,
|
|
||||||
TypeUnknown,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum Region {
|
|
||||||
NTSC,
|
|
||||||
PAL,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum MemoryMapper {
|
|
||||||
LoROM,
|
|
||||||
HiROM,
|
|
||||||
ExLoROM,
|
|
||||||
ExHiROM,
|
|
||||||
SPC7110ROM,
|
|
||||||
BSCLoROM,
|
|
||||||
BSCHiROM,
|
|
||||||
BSXROM,
|
|
||||||
STROM,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum DSP1MemoryMapper {
|
|
||||||
DSP1Unmapped,
|
|
||||||
DSP1LoROM1MB,
|
|
||||||
DSP1LoROM2MB,
|
|
||||||
DSP1HiROM,
|
|
||||||
};
|
|
||||||
|
|
||||||
//properties can be read via operator(), eg "if(cartridge.loaded() == true)";
|
|
||||||
//warning: if loaded() == false, no other property is considered valid!
|
|
||||||
|
|
||||||
property_t<bool> loaded; //is a base cartridge inserted?
|
|
||||||
property_t<bool> bsx_flash_loaded; //is a BS-X flash cart connected?
|
|
||||||
property_t<bool> patched; //has a UPS patch been applied?
|
|
||||||
property_t<string> name; //display name (filename sans path and extension)
|
|
||||||
|
|
||||||
property_t<Mode> mode;
|
|
||||||
property_t<Region> region;
|
|
||||||
property_t<MemoryMapper> mapper;
|
|
||||||
property_t<DSP1MemoryMapper> dsp1_mapper;
|
|
||||||
|
|
||||||
property_t<bool> has_bsx_slot;
|
|
||||||
property_t<bool> has_superfx;
|
|
||||||
property_t<bool> has_sa1;
|
|
||||||
property_t<bool> has_srtc;
|
|
||||||
property_t<bool> has_sdd1;
|
|
||||||
property_t<bool> has_spc7110, has_spc7110rtc;
|
|
||||||
property_t<bool> has_cx4;
|
|
||||||
property_t<bool> has_dsp1, has_dsp2, has_dsp3, has_dsp4;
|
|
||||||
property_t<bool> has_obc1;
|
|
||||||
property_t<bool> has_st010, has_st011, has_st018;
|
|
||||||
|
|
||||||
//main interface
|
|
||||||
bool load_normal (const char *base);
|
|
||||||
bool load_bsx_slotted (const char *base, const char *slot = "");
|
|
||||||
bool load_bsx (const char *base, const char *slot = "");
|
|
||||||
bool load_sufami_turbo(const char *base, const char *slotA = "", const char *slotB = "");
|
|
||||||
void unload();
|
|
||||||
|
|
||||||
//utility functions
|
|
||||||
static string filepath(const char *filename, const char *pathname); //"./bar.ext" -> "/foo/bar.ext"
|
|
||||||
static string basename(const char *filename); //"/foo/bar.ext" -> "bar"
|
|
||||||
static string basepath(const char *filename); //"/foo/bar.ext" -> "/foo/bar/"
|
|
||||||
//this function will load 'filename', decompress it if needed, and determine what type of
|
|
||||||
//image file 'filename' refers to (eg normal cart, BS-X flash cart, Sufami Turbo cart, etc.)
|
|
||||||
//warning: this operation is very expensive, use sparingly!
|
|
||||||
Type detect_image_type(const char *filename) const;
|
|
||||||
|
|
||||||
Cartridge();
|
|
||||||
~Cartridge();
|
|
||||||
|
|
||||||
private:
|
|
||||||
void load_begin(Mode);
|
|
||||||
void load_end();
|
|
||||||
void unload_normal();
|
|
||||||
void unload_bsx_slotted();
|
|
||||||
void unload_bsx();
|
|
||||||
void unload_sufami_turbo();
|
|
||||||
|
|
||||||
struct cartinfo_t {
|
|
||||||
Type type;
|
|
||||||
Region region;
|
|
||||||
MemoryMapper mapper;
|
|
||||||
DSP1MemoryMapper dsp1_mapper;
|
|
||||||
unsigned rom_size, ram_size;
|
|
||||||
|
|
||||||
bool bsx_slot;
|
|
||||||
bool superfx;
|
|
||||||
bool sa1;
|
|
||||||
bool srtc;
|
|
||||||
bool sdd1;
|
|
||||||
bool spc7110, spc7110rtc;
|
|
||||||
bool cx4;
|
|
||||||
bool dsp1, dsp2, dsp3, dsp4;
|
|
||||||
bool obc1;
|
|
||||||
bool st010, st011, st018;
|
|
||||||
|
|
||||||
void reset();
|
|
||||||
cartinfo_t();
|
|
||||||
};
|
|
||||||
|
|
||||||
enum HeaderField {
|
|
||||||
CartName = 0x00,
|
|
||||||
Mapper = 0x15,
|
|
||||||
RomType = 0x16,
|
|
||||||
RomSize = 0x17,
|
|
||||||
RamSize = 0x18,
|
|
||||||
CartRegion = 0x19,
|
|
||||||
Company = 0x1a,
|
|
||||||
Version = 0x1b,
|
|
||||||
Complement = 0x1c, //inverse checksum
|
|
||||||
Checksum = 0x1e,
|
|
||||||
ResetVector = 0x3c,
|
|
||||||
};
|
|
||||||
|
|
||||||
void read_header(cartinfo_t &info, const uint8_t *data, unsigned size) const;
|
|
||||||
unsigned find_header(const uint8_t *data, unsigned size) const;
|
|
||||||
unsigned score_header(const uint8_t *data, unsigned size, unsigned addr) const;
|
|
||||||
void set_cartinfo(const cartinfo_t&);
|
|
||||||
|
|
||||||
bool load_image(const char *filename, uint8_t *&data, unsigned &size, bool &patched) const;
|
|
||||||
bool load_ram (const char *filename, uint8_t *&data, unsigned size, uint8_t init_value) const;
|
|
||||||
|
|
||||||
enum CompressionMode {
|
|
||||||
CompressionNone, //always load without compression
|
|
||||||
CompressionInspect, //use file header inspection
|
|
||||||
CompressionAuto, //use file extension or file header inspection (configured by user)
|
|
||||||
};
|
|
||||||
|
|
||||||
bool load_file(const char *fn, uint8 *&data, unsigned &size, CompressionMode compression = CompressionNone) const;
|
|
||||||
bool save_file(const char *fn, uint8 *data, unsigned size) const;
|
|
||||||
bool apply_patch(const uint8_t *pdata, unsigned psize, uint8_t *&data, unsigned &size) const;
|
|
||||||
|
|
||||||
string modify_extension(const char *filename, const char *extension) const;
|
|
||||||
string get_filename(const char *source, const char *extension, const char *path) const;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
string filename;
|
|
||||||
uint8_t *rom, *ram, *rtc;
|
|
||||||
unsigned rom_size, ram_size, rtc_size;
|
|
||||||
} cart;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
string filename;
|
|
||||||
uint8_t *ram;
|
|
||||||
unsigned ram_size;
|
|
||||||
} bs;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
string filename;
|
|
||||||
uint8_t *rom, *ram;
|
|
||||||
unsigned rom_size, ram_size;
|
|
||||||
} stA, stB;
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace memory {
|
|
||||||
extern MappedRAM cartrom, cartram, cartrtc;
|
|
||||||
extern MappedRAM bscram;
|
|
||||||
extern MappedRAM stArom, stAram;
|
|
||||||
extern MappedRAM stBrom, stBram;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern Cartridge cartridge;
|
|
||||||
@@ -1,109 +0,0 @@
|
|||||||
#ifdef CART_CPP
|
|
||||||
|
|
||||||
#include "../reader/filereader.hpp"
|
|
||||||
|
|
||||||
#if defined(GZIP_SUPPORT)
|
|
||||||
#include "../reader/gzreader.hpp"
|
|
||||||
#include "../reader/zipreader.hpp"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(JMA_SUPPORT)
|
|
||||||
#include "../reader/jmareader.hpp"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
string Cartridge::modify_extension(const char *filename_, const char *extension) const {
|
|
||||||
string filename = filename_;
|
|
||||||
int i;
|
|
||||||
for(i = strlen(filename); i >= 0; i--) {
|
|
||||||
if(filename[i] == '.') break;
|
|
||||||
if(filename[i] == '/') break;
|
|
||||||
if(filename[i] == '\\') break;
|
|
||||||
}
|
|
||||||
if(i > 0 && filename[i] == '.') filename[i] = 0;
|
|
||||||
return filename << "." << extension;
|
|
||||||
}
|
|
||||||
|
|
||||||
string Cartridge::get_filename(const char *source, const char *extension, const char *path) const {
|
|
||||||
return filepath(modify_extension(source, extension), path);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Cartridge::load_file(const char *fn, uint8 *&data, unsigned &size, CompressionMode compression) const {
|
|
||||||
if(file::exists(fn) == false) return false;
|
|
||||||
|
|
||||||
Reader::Type filetype = Reader::Normal;
|
|
||||||
if(compression == CompressionInspect) filetype = Reader::detect(fn, true);
|
|
||||||
if(compression == CompressionAuto) filetype = Reader::detect(fn, snes.config.file.autodetect_type);
|
|
||||||
|
|
||||||
switch(filetype) { default:
|
|
||||||
case Reader::Normal: {
|
|
||||||
FileReader ff(fn);
|
|
||||||
if(!ff.ready()) return false;
|
|
||||||
size = ff.size();
|
|
||||||
data = ff.read();
|
|
||||||
} break;
|
|
||||||
|
|
||||||
#ifdef GZIP_SUPPORT
|
|
||||||
case Reader::GZIP: {
|
|
||||||
GZReader gf(fn);
|
|
||||||
if(!gf.ready()) return false;
|
|
||||||
size = gf.size();
|
|
||||||
data = gf.read();
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case Reader::ZIP: {
|
|
||||||
ZipReader zf(fn);
|
|
||||||
if(!zf.ready()) return false;
|
|
||||||
size = zf.size();
|
|
||||||
data = zf.read();
|
|
||||||
} break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef JMA_SUPPORT
|
|
||||||
case Reader::JMA: {
|
|
||||||
try {
|
|
||||||
JMAReader jf(fn);
|
|
||||||
size = jf.size();
|
|
||||||
data = jf.read();
|
|
||||||
} catch(JMA::jma_errors jma_error) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Cartridge::apply_patch(const uint8_t *pdata, const unsigned psize, uint8_t *&data, unsigned &size) const {
|
|
||||||
uint8_t *outdata = 0;
|
|
||||||
unsigned outsize;
|
|
||||||
ups patcher;
|
|
||||||
ups::result result = patcher.apply(pdata, psize, data, size, outdata, outsize);
|
|
||||||
|
|
||||||
bool apply = false;
|
|
||||||
if(result == ups::ok) apply = true;
|
|
||||||
if(snes.config.file.bypass_patch_crc32 == true) {
|
|
||||||
if(result == ups::input_crc32_invalid) apply = true;
|
|
||||||
if(result == ups::output_crc32_invalid) apply = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//if patch application was successful, replace old data, size with new data, size
|
|
||||||
if(apply == true) {
|
|
||||||
delete[] data;
|
|
||||||
data = new uint8_t[size = outsize];
|
|
||||||
memcpy(data, outdata, outsize);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(outdata) delete[] outdata;
|
|
||||||
return apply;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Cartridge::save_file(const char *fn, uint8 *data, unsigned size) const {
|
|
||||||
file fp;
|
|
||||||
if(!fp.open(fn, file::mode_write)) return false;
|
|
||||||
fp.write(data, size);
|
|
||||||
fp.close();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,244 +0,0 @@
|
|||||||
#ifdef CART_CPP
|
|
||||||
|
|
||||||
//================
|
|
||||||
//Normal cartridge
|
|
||||||
//================
|
|
||||||
|
|
||||||
bool Cartridge::load_normal(const char *base) {
|
|
||||||
uint8_t *data;
|
|
||||||
unsigned size;
|
|
||||||
bool patch_applied;
|
|
||||||
cart.filename = base;
|
|
||||||
|
|
||||||
load_begin(ModeNormal);
|
|
||||||
if(load_image(base, data, size, patch_applied) == false) return false;
|
|
||||||
|
|
||||||
snes.config.path.current = basepath(cart.filename);
|
|
||||||
if(patch_applied) set(patched, true);
|
|
||||||
|
|
||||||
cartinfo_t cartinfo;
|
|
||||||
read_header(cartinfo, cart.rom = data, cart.rom_size = size);
|
|
||||||
set_cartinfo(cartinfo);
|
|
||||||
|
|
||||||
if(cartinfo.ram_size > 0) {
|
|
||||||
load_ram(get_filename(base, "srm", snes.config.path.save), cart.ram, cart.ram_size = cartinfo.ram_size, 0xff);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(cartinfo.srtc || cartinfo.spc7110rtc) {
|
|
||||||
load_ram(get_filename(base, "rtc", snes.config.path.save), cart.rtc, cart.rtc_size = 20, 0x00);
|
|
||||||
}
|
|
||||||
|
|
||||||
load_end();
|
|
||||||
set(name, basename(base));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Cartridge::unload_normal() {
|
|
||||||
if(cart.ram) save_file(get_filename(cart.filename, "srm", snes.config.path.save), cart.ram, cart.ram_size);
|
|
||||||
if(cart.rtc) save_file(get_filename(cart.filename, "rtc", snes.config.path.save), cart.rtc, cart.rtc_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
//======================
|
|
||||||
//BS-X slotted cartridge
|
|
||||||
//======================
|
|
||||||
|
|
||||||
bool Cartridge::load_bsx_slotted(const char *base, const char *slot) {
|
|
||||||
uint8_t *data;
|
|
||||||
unsigned size;
|
|
||||||
bool patch_applied;
|
|
||||||
cart.filename = base;
|
|
||||||
bs.filename = slot;
|
|
||||||
|
|
||||||
load_begin(ModeBsxSlotted);
|
|
||||||
if(load_image(base, data, size, patch_applied) == false) return false;
|
|
||||||
|
|
||||||
snes.config.path.current = basepath(cart.filename);
|
|
||||||
if(patch_applied) set(patched, true);
|
|
||||||
|
|
||||||
cartinfo_t cartinfo;
|
|
||||||
read_header(cartinfo, cart.rom = data, cart.rom_size = size);
|
|
||||||
set_cartinfo(cartinfo);
|
|
||||||
|
|
||||||
if(load_image(slot, data, size, patch_applied) == true) {
|
|
||||||
set(bsx_flash_loaded, true);
|
|
||||||
if(patch_applied) set(patched, true);
|
|
||||||
bs.ram = data;
|
|
||||||
bs.ram_size = size;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(cartinfo.ram_size > 0) {
|
|
||||||
load_ram(get_filename(base, "srm", snes.config.path.save), cart.ram, cart.ram_size = cartinfo.ram_size, 0xff);
|
|
||||||
}
|
|
||||||
|
|
||||||
load_end();
|
|
||||||
string filename = basename(base);
|
|
||||||
if(*slot) filename << " + " << basename(slot);
|
|
||||||
set(name, filename);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Cartridge::unload_bsx_slotted() {
|
|
||||||
if(cart.ram) save_file(get_filename(cart.filename, "srm", snes.config.path.save), cart.ram, cart.ram_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
//====================
|
|
||||||
//BS-X flash cartridge
|
|
||||||
//====================
|
|
||||||
|
|
||||||
bool Cartridge::load_bsx(const char *base, const char *slot) {
|
|
||||||
uint8_t *data;
|
|
||||||
unsigned size;
|
|
||||||
bool patch_applied;
|
|
||||||
cart.filename = base;
|
|
||||||
bs.filename = slot;
|
|
||||||
|
|
||||||
load_begin(ModeBsx);
|
|
||||||
if(load_image(base, data, size, patch_applied) == false) return false;
|
|
||||||
|
|
||||||
snes.config.path.current = basepath(cart.filename);
|
|
||||||
if(patch_applied) set(patched, true);
|
|
||||||
|
|
||||||
cartinfo_t cartinfo;
|
|
||||||
read_header(cartinfo, cart.rom = data, cart.rom_size = size);
|
|
||||||
set_cartinfo(cartinfo);
|
|
||||||
|
|
||||||
cart.ram = 0;
|
|
||||||
cart.ram_size = 0;
|
|
||||||
|
|
||||||
memset(bsxcart.sram.handle (), 0x00, bsxcart.sram.size ());
|
|
||||||
memset(bsxcart.psram.handle(), 0x00, bsxcart.psram.size());
|
|
||||||
|
|
||||||
if(load_file(get_filename(base, "srm", snes.config.path.save), data, size, CompressionNone) == true) {
|
|
||||||
memcpy(bsxcart.sram.handle (), data, min(bsxcart.sram.size (), size));
|
|
||||||
delete[] data;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(load_file(get_filename(base, "psr", snes.config.path.save), data, size, CompressionNone) == true) {
|
|
||||||
memcpy(bsxcart.psram.handle(), data, min(bsxcart.psram.size(), size));
|
|
||||||
delete[] data;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(load_image(slot, data, size, patch_applied) == true) {
|
|
||||||
set(bsx_flash_loaded, true);
|
|
||||||
if(patch_applied) set(patched, true);
|
|
||||||
bs.ram = data;
|
|
||||||
bs.ram_size = size;
|
|
||||||
}
|
|
||||||
|
|
||||||
load_end();
|
|
||||||
set(name, !*slot ? basename(base) : basename(slot));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Cartridge::unload_bsx() {
|
|
||||||
save_file(get_filename(cart.filename, "srm", snes.config.path.save), bsxcart.sram.handle (), bsxcart.sram.size ());
|
|
||||||
save_file(get_filename(cart.filename, "psr", snes.config.path.save), bsxcart.psram.handle(), bsxcart.psram.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================
|
|
||||||
//Sufami Turbo flash cartridge
|
|
||||||
//============================
|
|
||||||
|
|
||||||
bool Cartridge::load_sufami_turbo(const char *base, const char *slotA, const char *slotB) {
|
|
||||||
uint8_t *data;
|
|
||||||
unsigned size;
|
|
||||||
bool patch_applied;
|
|
||||||
cart.filename = base;
|
|
||||||
stA.filename = slotA;
|
|
||||||
stB.filename = slotB;
|
|
||||||
|
|
||||||
load_begin(ModeSufamiTurbo);
|
|
||||||
if(load_image(base, data, size, patch_applied) == false) return false;
|
|
||||||
|
|
||||||
snes.config.path.current = basepath(cart.filename);
|
|
||||||
if(patch_applied) set(patched, true);
|
|
||||||
|
|
||||||
cartinfo_t cartinfo;
|
|
||||||
read_header(cartinfo, cart.rom = data, cart.rom_size = size);
|
|
||||||
set_cartinfo(cartinfo);
|
|
||||||
|
|
||||||
if(load_image(slotA, data, size, patch_applied) == true) {
|
|
||||||
if(patch_applied) set(patched, true);
|
|
||||||
stA.rom = new(zeromemory) uint8_t[stA.rom_size = 0x100000];
|
|
||||||
memcpy(stA.rom, data, min(size, stA.rom_size));
|
|
||||||
delete[] data;
|
|
||||||
|
|
||||||
load_ram(get_filename(slotA, "srm", snes.config.path.save), stA.ram, stA.ram_size = 0x020000, 0xff);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(load_image(slotB, data, size, patch_applied) == true) {
|
|
||||||
if(patch_applied) set(patched, true);
|
|
||||||
stB.rom = new(zeromemory) uint8_t[stB.rom_size = 0x100000];
|
|
||||||
memcpy(stB.rom, data, min(size, stB.rom_size));
|
|
||||||
delete[] data;
|
|
||||||
|
|
||||||
load_ram(get_filename(slotB, "srm", snes.config.path.save), stB.ram, stB.ram_size = 0x020000, 0xff);
|
|
||||||
}
|
|
||||||
|
|
||||||
load_end();
|
|
||||||
string filename;
|
|
||||||
if(!*slotA && !*slotB) filename << basename(base);
|
|
||||||
else if( *slotA && !*slotB) filename << basename(slotA);
|
|
||||||
else if(!*slotA && *slotB) filename << basename(slotB);
|
|
||||||
else filename << basename(slotA) << " + " << basename(slotB);
|
|
||||||
set(name, filename);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Cartridge::unload_sufami_turbo() {
|
|
||||||
if(stA.ram) save_file(get_filename(stA.filename, "srm", snes.config.path.save), stA.ram, stA.ram_size);
|
|
||||||
if(stB.ram) save_file(get_filename(stB.filename, "srm", snes.config.path.save), stB.ram, stB.ram_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
//=================
|
|
||||||
//utility functions
|
|
||||||
//=================
|
|
||||||
|
|
||||||
Cartridge::Type Cartridge::detect_image_type(const char *filename) const {
|
|
||||||
uint8_t *data;
|
|
||||||
unsigned size;
|
|
||||||
bool patch_applied;
|
|
||||||
if(!load_image(filename, data, size, patch_applied)) return TypeUnknown;
|
|
||||||
|
|
||||||
cartinfo_t info;
|
|
||||||
read_header(info, data, size);
|
|
||||||
delete[] data;
|
|
||||||
return info.type;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Cartridge::load_image(const char *filename, uint8_t *&data, unsigned &size, bool &patched) const {
|
|
||||||
if(!filename || !*filename) return false;
|
|
||||||
if(!load_file(filename, data, size, CompressionAuto)) return false;
|
|
||||||
|
|
||||||
if((size & 0x7fff) == 512) {
|
|
||||||
//remove 512-byte header
|
|
||||||
memmove(data, data + 512, size -= 512);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t *pdata;
|
|
||||||
unsigned psize;
|
|
||||||
if(load_file(get_filename(filename, "ups", snes.config.path.patch), pdata, psize, CompressionInspect) == true) {
|
|
||||||
apply_patch(pdata, psize, data, size);
|
|
||||||
delete[] pdata;
|
|
||||||
patched = true;
|
|
||||||
} else {
|
|
||||||
patched = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Cartridge::load_ram(const char *filename, uint8_t *&data, unsigned size, uint8_t init) const {
|
|
||||||
data = new uint8_t[size];
|
|
||||||
memset(data, init, size);
|
|
||||||
|
|
||||||
uint8_t *savedata;
|
|
||||||
unsigned savesize;
|
|
||||||
if(load_file(filename, savedata, savesize, CompressionNone) == false) return false;
|
|
||||||
|
|
||||||
memcpy(data, savedata, min(size, savesize));
|
|
||||||
delete[] savedata;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
157
tools/bsnes/cartridge/cartridge.cpp
Executable file
157
tools/bsnes/cartridge/cartridge.cpp
Executable file
@@ -0,0 +1,157 @@
|
|||||||
|
#include <../base.hpp>
|
||||||
|
|
||||||
|
#define CARTRIDGE_CPP
|
||||||
|
namespace SNES {
|
||||||
|
|
||||||
|
#include "header.cpp"
|
||||||
|
|
||||||
|
namespace memory {
|
||||||
|
MappedRAM cartrom, cartram, cartrtc;
|
||||||
|
MappedRAM bsxflash, bsxram, bsxpram;
|
||||||
|
MappedRAM stArom, stAram;
|
||||||
|
MappedRAM stBrom, stBram;
|
||||||
|
MappedRAM gbrom, gbram;
|
||||||
|
};
|
||||||
|
|
||||||
|
Cartridge cartridge;
|
||||||
|
|
||||||
|
void Cartridge::load(Mode cartridge_mode) {
|
||||||
|
cartinfo_t cartinfo;
|
||||||
|
read_header(cartinfo, memory::cartrom.data(), memory::cartrom.size());
|
||||||
|
set_cartinfo(cartinfo);
|
||||||
|
|
||||||
|
set(mode, cartridge_mode);
|
||||||
|
|
||||||
|
if(cartinfo.ram_size > 0) {
|
||||||
|
memory::cartram.map(new(zeromemory) uint8_t[cartinfo.ram_size], cartinfo.ram_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(cartinfo.srtc || cartinfo.spc7110rtc) {
|
||||||
|
memory::cartrtc.map(new(zeromemory) uint8_t[20], 20);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(mode() == ModeBsx) {
|
||||||
|
memory::bsxram.map (new(zeromemory) uint8_t[ 32 * 1024], 32 * 1024);
|
||||||
|
memory::bsxpram.map(new(zeromemory) uint8_t[512 * 1024], 512 * 1024);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(mode() == ModeSufamiTurbo) {
|
||||||
|
if(memory::stArom.data()) memory::stAram.map(new(zeromemory) uint8_t[128 * 1024], 128 * 1024);
|
||||||
|
if(memory::stBrom.data()) memory::stBram.map(new(zeromemory) uint8_t[128 * 1024], 128 * 1024);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(mode() == ModeSuperGameBoy) {
|
||||||
|
if(memory::gbrom.data()) memory::gbram.map(new(zeromemory) uint8_t[64 * 1024], 64 * 1024);
|
||||||
|
}
|
||||||
|
|
||||||
|
memory::cartrom.write_protect(true);
|
||||||
|
memory::cartram.write_protect(false);
|
||||||
|
memory::cartrtc.write_protect(false);
|
||||||
|
memory::bsxflash.write_protect(true);
|
||||||
|
memory::bsxram.write_protect(false);
|
||||||
|
memory::bsxpram.write_protect(false);
|
||||||
|
memory::stArom.write_protect(true);
|
||||||
|
memory::stAram.write_protect(false);
|
||||||
|
memory::stBrom.write_protect(true);
|
||||||
|
memory::stBram.write_protect(false);
|
||||||
|
memory::gbrom.write_protect(true);
|
||||||
|
memory::gbram.write_protect(false);
|
||||||
|
|
||||||
|
bus.load_cart();
|
||||||
|
set(loaded, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Cartridge::unload() {
|
||||||
|
memory::cartrom.reset();
|
||||||
|
memory::cartram.reset();
|
||||||
|
memory::cartrtc.reset();
|
||||||
|
memory::bsxflash.reset();
|
||||||
|
memory::bsxram.reset();
|
||||||
|
memory::bsxpram.reset();
|
||||||
|
memory::stArom.reset();
|
||||||
|
memory::stAram.reset();
|
||||||
|
memory::stBrom.reset();
|
||||||
|
memory::stBram.reset();
|
||||||
|
memory::gbrom.reset();
|
||||||
|
memory::gbram.reset();
|
||||||
|
|
||||||
|
if(loaded() == false) return;
|
||||||
|
bus.unload_cart();
|
||||||
|
set(loaded, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
Cartridge::Type Cartridge::detect_image_type(uint8_t *data, unsigned size) const {
|
||||||
|
cartinfo_t info;
|
||||||
|
read_header(info, data, size);
|
||||||
|
return info.type;
|
||||||
|
}
|
||||||
|
|
||||||
|
Cartridge::Cartridge() {
|
||||||
|
set(loaded, false);
|
||||||
|
unload();
|
||||||
|
}
|
||||||
|
|
||||||
|
Cartridge::~Cartridge() {
|
||||||
|
unload();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Cartridge::set_cartinfo(const Cartridge::cartinfo_t &source) {
|
||||||
|
set(region, source.region);
|
||||||
|
set(mapper, source.mapper);
|
||||||
|
set(dsp1_mapper, source.dsp1_mapper);
|
||||||
|
|
||||||
|
set(has_bsx_slot, source.bsx_slot);
|
||||||
|
set(has_superfx, source.superfx);
|
||||||
|
set(has_sa1, source.sa1);
|
||||||
|
set(has_srtc, source.srtc);
|
||||||
|
set(has_sdd1, source.sdd1);
|
||||||
|
set(has_spc7110, source.spc7110);
|
||||||
|
set(has_spc7110rtc, source.spc7110rtc);
|
||||||
|
set(has_cx4, source.cx4);
|
||||||
|
set(has_dsp1, source.dsp1);
|
||||||
|
set(has_dsp2, source.dsp2);
|
||||||
|
set(has_dsp3, source.dsp3);
|
||||||
|
set(has_dsp4, source.dsp4);
|
||||||
|
set(has_obc1, source.obc1);
|
||||||
|
set(has_st010, source.st010);
|
||||||
|
set(has_st011, source.st011);
|
||||||
|
set(has_st018, source.st018);
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========
|
||||||
|
//cartinfo_t
|
||||||
|
//==========
|
||||||
|
|
||||||
|
void Cartridge::cartinfo_t::reset() {
|
||||||
|
type = TypeUnknown;
|
||||||
|
mapper = LoROM;
|
||||||
|
dsp1_mapper = DSP1Unmapped;
|
||||||
|
region = NTSC;
|
||||||
|
|
||||||
|
rom_size = 0;
|
||||||
|
ram_size = 0;
|
||||||
|
|
||||||
|
bsx_slot = false;
|
||||||
|
superfx = false;
|
||||||
|
sa1 = false;
|
||||||
|
srtc = false;
|
||||||
|
sdd1 = false;
|
||||||
|
spc7110 = false;
|
||||||
|
spc7110rtc = false;
|
||||||
|
cx4 = false;
|
||||||
|
dsp1 = false;
|
||||||
|
dsp2 = false;
|
||||||
|
dsp3 = false;
|
||||||
|
dsp4 = false;
|
||||||
|
obc1 = false;
|
||||||
|
st010 = false;
|
||||||
|
st011 = false;
|
||||||
|
st018 = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Cartridge::cartinfo_t::cartinfo_t() {
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
130
tools/bsnes/cartridge/cartridge.hpp
Executable file
130
tools/bsnes/cartridge/cartridge.hpp
Executable file
@@ -0,0 +1,130 @@
|
|||||||
|
class Cartridge : public property {
|
||||||
|
public:
|
||||||
|
enum Mode {
|
||||||
|
ModeNormal,
|
||||||
|
ModeBsxSlotted,
|
||||||
|
ModeBsx,
|
||||||
|
ModeSufamiTurbo,
|
||||||
|
ModeSuperGameBoy,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum Type {
|
||||||
|
TypeNormal,
|
||||||
|
TypeBsxSlotted,
|
||||||
|
TypeBsxBios,
|
||||||
|
TypeBsx,
|
||||||
|
TypeSufamiTurboBios,
|
||||||
|
TypeSufamiTurbo,
|
||||||
|
TypeSuperGameBoyBios,
|
||||||
|
TypeGameBoy,
|
||||||
|
TypeUnknown,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum Region {
|
||||||
|
NTSC,
|
||||||
|
PAL,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum MemoryMapper {
|
||||||
|
LoROM,
|
||||||
|
HiROM,
|
||||||
|
ExLoROM,
|
||||||
|
ExHiROM,
|
||||||
|
SA1ROM,
|
||||||
|
SPC7110ROM,
|
||||||
|
BSCLoROM,
|
||||||
|
BSCHiROM,
|
||||||
|
BSXROM,
|
||||||
|
STROM,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum DSP1MemoryMapper {
|
||||||
|
DSP1Unmapped,
|
||||||
|
DSP1LoROM1MB,
|
||||||
|
DSP1LoROM2MB,
|
||||||
|
DSP1HiROM,
|
||||||
|
};
|
||||||
|
|
||||||
|
//properties can be read via operator(), eg "if(cartridge.loaded() == true)";
|
||||||
|
//warning: if loaded() == false, no other property is considered valid!
|
||||||
|
|
||||||
|
property_t<bool> loaded; //is a base cartridge inserted?
|
||||||
|
|
||||||
|
property_t<Mode> mode;
|
||||||
|
property_t<Region> region;
|
||||||
|
property_t<MemoryMapper> mapper;
|
||||||
|
property_t<DSP1MemoryMapper> dsp1_mapper;
|
||||||
|
|
||||||
|
property_t<bool> has_bsx_slot;
|
||||||
|
property_t<bool> has_superfx;
|
||||||
|
property_t<bool> has_sa1;
|
||||||
|
property_t<bool> has_srtc;
|
||||||
|
property_t<bool> has_sdd1;
|
||||||
|
property_t<bool> has_spc7110, has_spc7110rtc;
|
||||||
|
property_t<bool> has_cx4;
|
||||||
|
property_t<bool> has_dsp1, has_dsp2, has_dsp3, has_dsp4;
|
||||||
|
property_t<bool> has_obc1;
|
||||||
|
property_t<bool> has_st010, has_st011, has_st018;
|
||||||
|
|
||||||
|
//main interface
|
||||||
|
void load(Mode);
|
||||||
|
//void read();
|
||||||
|
//void load();
|
||||||
|
void unload();
|
||||||
|
Type detect_image_type(uint8_t *data, unsigned size) const;
|
||||||
|
|
||||||
|
Cartridge();
|
||||||
|
~Cartridge();
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct cartinfo_t {
|
||||||
|
Type type;
|
||||||
|
Region region;
|
||||||
|
MemoryMapper mapper;
|
||||||
|
DSP1MemoryMapper dsp1_mapper;
|
||||||
|
unsigned rom_size, ram_size;
|
||||||
|
|
||||||
|
bool bsx_slot;
|
||||||
|
bool superfx;
|
||||||
|
bool sa1;
|
||||||
|
bool srtc;
|
||||||
|
bool sdd1;
|
||||||
|
bool spc7110, spc7110rtc;
|
||||||
|
bool cx4;
|
||||||
|
bool dsp1, dsp2, dsp3, dsp4;
|
||||||
|
bool obc1;
|
||||||
|
bool st010, st011, st018;
|
||||||
|
|
||||||
|
void reset();
|
||||||
|
cartinfo_t();
|
||||||
|
};
|
||||||
|
|
||||||
|
enum HeaderField {
|
||||||
|
CartName = 0x00,
|
||||||
|
Mapper = 0x15,
|
||||||
|
RomType = 0x16,
|
||||||
|
RomSize = 0x17,
|
||||||
|
RamSize = 0x18,
|
||||||
|
CartRegion = 0x19,
|
||||||
|
Company = 0x1a,
|
||||||
|
Version = 0x1b,
|
||||||
|
Complement = 0x1c, //inverse checksum
|
||||||
|
Checksum = 0x1e,
|
||||||
|
ResetVector = 0x3c,
|
||||||
|
};
|
||||||
|
|
||||||
|
void read_header(cartinfo_t &info, const uint8_t *data, unsigned size) const;
|
||||||
|
unsigned find_header(const uint8_t *data, unsigned size) const;
|
||||||
|
unsigned score_header(const uint8_t *data, unsigned size, unsigned addr) const;
|
||||||
|
void set_cartinfo(const cartinfo_t&);
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace memory {
|
||||||
|
extern MappedRAM cartrom, cartram, cartrtc;
|
||||||
|
extern MappedRAM bsxflash, bsxram, bsxpram;
|
||||||
|
extern MappedRAM stArom, stAram;
|
||||||
|
extern MappedRAM stBrom, stBram;
|
||||||
|
extern MappedRAM gbrom, gbram;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern Cartridge cartridge;
|
||||||
@@ -1,8 +1,35 @@
|
|||||||
#ifdef CART_CPP
|
#ifdef CARTRIDGE_CPP
|
||||||
|
|
||||||
void Cartridge::read_header(cartinfo_t &info, const uint8_t *data, unsigned size) const {
|
void Cartridge::read_header(cartinfo_t &info, const uint8_t *data, unsigned size) const {
|
||||||
info.reset();
|
info.reset();
|
||||||
unsigned index = find_header(data, size);
|
|
||||||
|
//=====================
|
||||||
|
//detect Game Boy carts
|
||||||
|
//=====================
|
||||||
|
|
||||||
|
if(size >= 0x0140) {
|
||||||
|
if(data[0x0104] == 0xce && data[0x0105] == 0xed && data[0x0106] == 0x66 && data[0x0107] == 0x66
|
||||||
|
&& data[0x0108] == 0xcc && data[0x0109] == 0x0d && data[0x010a] == 0x00 && data[0x010b] == 0x0b) {
|
||||||
|
info.type = TypeGameBoy;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const unsigned index = find_header(data, size);
|
||||||
|
const uint8 mapper = data[index + Mapper];
|
||||||
|
const uint8 rom_type = data[index + RomType];
|
||||||
|
const uint8 rom_size = data[index + RomSize];
|
||||||
|
const uint8 company = data[index + Company];
|
||||||
|
const uint8 region = data[index + CartRegion] & 0x7f;
|
||||||
|
|
||||||
|
if(data[index + RamSize] & 7) {
|
||||||
|
info.ram_size = 1024 << (data[index + RamSize] & 7);
|
||||||
|
} else {
|
||||||
|
info.ram_size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//0, 1, 13 = NTSC; 2 - 12 = PAL
|
||||||
|
info.region = (region <= 1 || region >= 13) ? NTSC : PAL;
|
||||||
|
|
||||||
//=======================
|
//=======================
|
||||||
//detect BS-X flash carts
|
//detect BS-X flash carts
|
||||||
@@ -37,16 +64,19 @@ void Cartridge::read_header(cartinfo_t &info, const uint8_t *data, unsigned size
|
|||||||
return; //RAM size handled internally by load_cart_st();
|
return; //RAM size handled internally by load_cart_st();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================
|
||||||
|
//detect Super Game Boy BIOS
|
||||||
|
//==========================
|
||||||
|
|
||||||
|
if(!memcmp(data + index, "Super GAMEBOY", 13)) {
|
||||||
|
info.type = TypeSuperGameBoyBios;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//=====================
|
//=====================
|
||||||
//detect standard carts
|
//detect standard carts
|
||||||
//=====================
|
//=====================
|
||||||
|
|
||||||
const uint8 mapper = data[index + Mapper];
|
|
||||||
const uint8 rom_type = data[index + RomType];
|
|
||||||
const uint8 rom_size = data[index + RomSize];
|
|
||||||
const uint8 company = data[index + Company];
|
|
||||||
const uint8 region = data[index + CartRegion] & 0x7f;
|
|
||||||
|
|
||||||
//detect presence of BS-X flash cartridge connector (reads extended header information)
|
//detect presence of BS-X flash cartridge connector (reads extended header information)
|
||||||
if(data[index - 14] == 'Z') {
|
if(data[index - 14] == 'Z') {
|
||||||
if(data[index - 11] == 'J') {
|
if(data[index - 11] == 'J') {
|
||||||
@@ -91,8 +121,9 @@ void Cartridge::read_header(cartinfo_t &info, const uint8_t *data, unsigned size
|
|||||||
info.superfx = true;
|
info.superfx = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(mapper == 0x23 && (rom_type == 0x34 || rom_type == 0x35)) {
|
if(mapper == 0x23 && (rom_type == 0x32 || rom_type == 0x34 || rom_type == 0x35)) {
|
||||||
info.sa1 = true;
|
info.sa1 = true;
|
||||||
|
info.mapper = SA1ROM;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(mapper == 0x35 && rom_type == 0x55) {
|
if(mapper == 0x35 && rom_type == 0x55) {
|
||||||
@@ -162,15 +193,6 @@ void Cartridge::read_header(cartinfo_t &info, const uint8_t *data, unsigned size
|
|||||||
if(mapper == 0x30 && rom_type == 0xf5) {
|
if(mapper == 0x30 && rom_type == 0xf5) {
|
||||||
info.st018 = true;
|
info.st018 = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(data[index + RamSize] & 7) {
|
|
||||||
info.ram_size = 1024 << (data[index + RamSize] & 7);
|
|
||||||
} else {
|
|
||||||
info.ram_size = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//0, 1, 13 = NTSC; 2 - 12 = PAL
|
|
||||||
info.region = (region <= 1 || region >= 13) ? NTSC : PAL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned Cartridge::find_header(const uint8_t *data, unsigned size) const {
|
unsigned Cartridge::find_header(const uint8_t *data, unsigned size) const {
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
::@mingw32-make platform=win compiler=mingw32-gcc
|
|
||||||
@mingw32-make platform=win compiler=mingw32-gcc enable_gzip=true enable_jma=true
|
|
||||||
@pause
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
make platform=x compiler=gcc
|
|
||||||
#make platform=x compiler=gcc enable_gzip=true enable_jma=true
|
|
||||||
@@ -1,4 +1,7 @@
|
|||||||
#include <../base.hpp>
|
#include <../base.hpp>
|
||||||
|
|
||||||
|
#define CHEAT_CPP
|
||||||
|
namespace SNES {
|
||||||
|
|
||||||
Cheat cheat;
|
Cheat cheat;
|
||||||
|
|
||||||
@@ -178,9 +181,7 @@ void Cheat::disable(unsigned i) {
|
|||||||
//...
|
//...
|
||||||
//===============================
|
//===============================
|
||||||
|
|
||||||
bool Cheat::load(const char *fn) {
|
void Cheat::load(string data) {
|
||||||
string data;
|
|
||||||
if(!data.readfile(fn)) return false;
|
|
||||||
data.replace("\r\n", "\n");
|
data.replace("\r\n", "\n");
|
||||||
data.qreplace(" ", "");
|
data.qreplace(" ", "");
|
||||||
|
|
||||||
@@ -193,21 +194,16 @@ bool Cheat::load(const char *fn) {
|
|||||||
trim(part[0], "\"");
|
trim(part[0], "\"");
|
||||||
add(part[1] == "enabled", /* code = */ part[2], /* desc = */ part[0]);
|
add(part[1] == "enabled", /* code = */ part[2], /* desc = */ part[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Cheat::save(const char *fn) const {
|
string Cheat::save() const {
|
||||||
file fp;
|
string data;
|
||||||
if(!fp.open(fn, file::mode_write)) return false;
|
for(unsigned i = 0; i < code.size(); i++) {
|
||||||
for(unsigned i = 0; i < code.size(); i++) {
|
data << "\"" << code[i].desc << "\", "
|
||||||
fp.print(string()
|
<< (code[i].enabled ? "enabled, " : "disabled, ")
|
||||||
<< "\"" << code[i].desc << "\", "
|
<< code[i].code << "\r\n";
|
||||||
<< (code[i].enabled ? "enabled, " : "disabled, ")
|
}
|
||||||
<< code[i].code << "\r\n");
|
return data;
|
||||||
}
|
|
||||||
fp.close();
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cheat::clear() {
|
void Cheat::clear() {
|
||||||
@@ -390,3 +386,6 @@ string& Cheat::decode_description(string &desc) const {
|
|||||||
desc.replace("\\n", "\n");
|
desc.replace("\\n", "\n");
|
||||||
return desc;
|
return desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -38,8 +38,8 @@ public:
|
|||||||
void enable(unsigned i);
|
void enable(unsigned i);
|
||||||
void disable(unsigned i);
|
void disable(unsigned i);
|
||||||
|
|
||||||
bool load(const char *fn);
|
void load(string data);
|
||||||
bool save(const char *fn) const;
|
string save() const;
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
Cheat();
|
Cheat();
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
#include <../base.hpp>
|
#include <../base.hpp>
|
||||||
#include <../cart/cart.hpp>
|
|
||||||
#define BSX_CPP
|
#define BSX_CPP
|
||||||
|
namespace SNES {
|
||||||
|
|
||||||
#include "bsx.hpp"
|
|
||||||
#include "bsx_base.cpp"
|
#include "bsx_base.cpp"
|
||||||
#include "bsx_cart.cpp"
|
#include "bsx_cart.cpp"
|
||||||
#include "bsx_flash.cpp"
|
#include "bsx_flash.cpp"
|
||||||
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -32,16 +32,10 @@ public:
|
|||||||
uint8 mmio_read(unsigned addr);
|
uint8 mmio_read(unsigned addr);
|
||||||
void mmio_write(unsigned addr, uint8 data);
|
void mmio_write(unsigned addr, uint8 data);
|
||||||
|
|
||||||
MappedRAM sram;
|
|
||||||
MappedRAM psram;
|
|
||||||
|
|
||||||
BSXCart();
|
BSXCart();
|
||||||
~BSXCart();
|
~BSXCart();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint8 *sram_data; //256kbit SRAM
|
|
||||||
uint8 *psram_data; // 4mbit PSRAM
|
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
uint8 r[16];
|
uint8 r[16];
|
||||||
} regs;
|
} regs;
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
#ifdef BSX_CPP
|
#ifdef BSX_CPP
|
||||||
|
|
||||||
|
BSXBase bsxbase;
|
||||||
|
|
||||||
void BSXBase::init() {
|
void BSXBase::init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,3 +137,4 @@ void BSXBase::mmio_write(unsigned addr, uint8 data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
#ifdef BSX_CPP
|
#ifdef BSX_CPP
|
||||||
|
|
||||||
|
BSXCart bsxcart;
|
||||||
|
|
||||||
void BSXCart::init() {
|
void BSXCart::init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -20,7 +22,7 @@ void BSXCart::reset() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void BSXCart::update_memory_map() {
|
void BSXCart::update_memory_map() {
|
||||||
Memory &cart = (regs.r[0x01] & 0x80) == 0x00 ? (Memory&)bsxflash : (Memory&)psram;
|
Memory &cart = (regs.r[0x01] & 0x80) == 0x00 ? (Memory&)bsxflash : (Memory&)memory::bsxpram;
|
||||||
|
|
||||||
if((regs.r[0x02] & 0x80) == 0x00) {
|
if((regs.r[0x02] & 0x80) == 0x00) {
|
||||||
//LoROM mapping
|
//LoROM mapping
|
||||||
@@ -35,16 +37,16 @@ void BSXCart::update_memory_map() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(regs.r[0x03] & 0x80) {
|
if(regs.r[0x03] & 0x80) {
|
||||||
bus.map(Bus::MapLinear, 0x60, 0x6f, 0x0000, 0xffff, psram);
|
bus.map(Bus::MapLinear, 0x60, 0x6f, 0x0000, 0xffff, memory::bsxpram);
|
||||||
//bus.map(Bus::MapLinear, 0x70, 0x77, 0x0000, 0xffff, psram);
|
//bus.map(Bus::MapLinear, 0x70, 0x77, 0x0000, 0xffff, memory::bsxpram);
|
||||||
}
|
}
|
||||||
|
|
||||||
if((regs.r[0x05] & 0x80) == 0x00) {
|
if((regs.r[0x05] & 0x80) == 0x00) {
|
||||||
bus.map(Bus::MapLinear, 0x40, 0x4f, 0x0000, 0xffff, psram);
|
bus.map(Bus::MapLinear, 0x40, 0x4f, 0x0000, 0xffff, memory::bsxpram);
|
||||||
}
|
}
|
||||||
|
|
||||||
if((regs.r[0x06] & 0x80) == 0x00) {
|
if((regs.r[0x06] & 0x80) == 0x00) {
|
||||||
bus.map(Bus::MapLinear, 0x50, 0x5f, 0x0000, 0xffff, psram);
|
bus.map(Bus::MapLinear, 0x50, 0x5f, 0x0000, 0xffff, memory::bsxpram);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(regs.r[0x07] & 0x80) {
|
if(regs.r[0x07] & 0x80) {
|
||||||
@@ -55,8 +57,8 @@ void BSXCart::update_memory_map() {
|
|||||||
bus.map(Bus::MapLinear, 0x80, 0x9f, 0x8000, 0xffff, memory::cartrom);
|
bus.map(Bus::MapLinear, 0x80, 0x9f, 0x8000, 0xffff, memory::cartrom);
|
||||||
}
|
}
|
||||||
|
|
||||||
bus.map(Bus::MapShadow, 0x20, 0x3f, 0x6000, 0x7fff, psram);
|
bus.map(Bus::MapShadow, 0x20, 0x3f, 0x6000, 0x7fff, memory::bsxpram);
|
||||||
bus.map(Bus::MapLinear, 0x70, 0x77, 0x0000, 0xffff, psram);
|
bus.map(Bus::MapLinear, 0x70, 0x77, 0x0000, 0xffff, memory::bsxpram);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 BSXCart::mmio_read(unsigned addr) {
|
uint8 BSXCart::mmio_read(unsigned addr) {
|
||||||
@@ -66,7 +68,7 @@ uint8 BSXCart::mmio_read(unsigned addr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if((addr & 0xf8f000) == 0x105000) { //$[10-17]:[5000-5fff] SRAM
|
if((addr & 0xf8f000) == 0x105000) { //$[10-17]:[5000-5fff] SRAM
|
||||||
return sram.read(((addr >> 16) & 7) * 0x1000 + (addr & 0xfff));
|
return memory::bsxram.read(((addr >> 16) & 7) * 0x1000 + (addr & 0xfff));
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0x00;
|
return 0x00;
|
||||||
@@ -81,21 +83,15 @@ void BSXCart::mmio_write(unsigned addr, uint8 data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if((addr & 0xf8f000) == 0x105000) { //$[10-17]:[5000-5fff] SRAM
|
if((addr & 0xf8f000) == 0x105000) { //$[10-17]:[5000-5fff] SRAM
|
||||||
return sram.write(((addr >> 16) & 7) * 0x1000 + (addr & 0xfff), data);
|
return memory::bsxram.write(((addr >> 16) & 7) * 0x1000 + (addr & 0xfff), data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BSXCart::BSXCart() {
|
BSXCart::BSXCart() {
|
||||||
sram_data = new uint8_t[ 32 * 1024];
|
|
||||||
psram_data = new uint8_t[512 * 1024];
|
|
||||||
|
|
||||||
sram.map (sram_data, 32 * 1024);
|
|
||||||
psram.map(psram_data, 512 * 1024);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BSXCart::~BSXCart() {
|
BSXCart::~BSXCart() {
|
||||||
delete[] sram_data;
|
|
||||||
delete[] psram_data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
#ifdef BSX_CPP
|
#ifdef BSX_CPP
|
||||||
|
|
||||||
|
BSXFlash bsxflash;
|
||||||
|
|
||||||
void BSXFlash::init() {}
|
void BSXFlash::init() {}
|
||||||
void BSXFlash::enable() {}
|
void BSXFlash::enable() {}
|
||||||
|
|
||||||
@@ -15,10 +17,11 @@ void BSXFlash::reset() {
|
|||||||
regs.flash_enable = false;
|
regs.flash_enable = false;
|
||||||
regs.read_enable = false;
|
regs.read_enable = false;
|
||||||
regs.write_enable = false;
|
regs.write_enable = false;
|
||||||
|
memory::bsxflash.write_protect(!regs.write_enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned BSXFlash::size() const {
|
unsigned BSXFlash::size() const {
|
||||||
return memory::bscram.size();
|
return memory::bsxflash.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 BSXFlash::read(unsigned addr) {
|
uint8 BSXFlash::read(unsigned addr) {
|
||||||
@@ -45,7 +48,7 @@ uint8 BSXFlash::read(unsigned addr) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return memory::bscram.read(addr);
|
return memory::bsxflash.read(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BSXFlash::write(unsigned addr, uint8 data) {
|
void BSXFlash::write(unsigned addr, uint8 data) {
|
||||||
@@ -64,11 +67,11 @@ void BSXFlash::write(unsigned addr, uint8 data) {
|
|||||||
regs.write_new = data;
|
regs.write_new = data;
|
||||||
|
|
||||||
if(regs.write_enable && regs.write_old == regs.write_new) {
|
if(regs.write_enable && regs.write_old == regs.write_new) {
|
||||||
return memory::bscram.write(addr, data);
|
return memory::bsxflash.write(addr, data);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(regs.write_enable) {
|
if(regs.write_enable) {
|
||||||
return memory::bscram.write(addr, data);
|
return memory::bsxflash.write(addr, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,7 +110,10 @@ void BSXFlash::write(unsigned addr, uint8 data) {
|
|||||||
regs.read_enable = false;
|
regs.read_enable = false;
|
||||||
regs.write_enable = false;
|
regs.write_enable = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
memory::bsxflash.write_protect(!regs.write_enable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
#include "sgb/sgb.hpp"
|
||||||
|
#include "sa1/sa1.hpp"
|
||||||
#include "bsx/bsx.hpp"
|
#include "bsx/bsx.hpp"
|
||||||
#include "srtc/srtc.hpp"
|
#include "srtc/srtc.hpp"
|
||||||
#include "sdd1/sdd1.hpp"
|
#include "sdd1/sdd1.hpp"
|
||||||
|
|||||||
@@ -6,9 +6,12 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <../base.hpp>
|
#include <../base.hpp>
|
||||||
#define CX4_CPP
|
|
||||||
|
#define CX4_CPP
|
||||||
|
namespace SNES {
|
||||||
|
|
||||||
|
Cx4 cx4;
|
||||||
|
|
||||||
#include "cx4.hpp"
|
|
||||||
#include "cx4data.cpp"
|
#include "cx4data.cpp"
|
||||||
#include "cx4fn.cpp"
|
#include "cx4fn.cpp"
|
||||||
#include "cx4oam.cpp"
|
#include "cx4oam.cpp"
|
||||||
@@ -30,8 +33,8 @@ uint16 addr = 0x0080 + (r * 3);
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Cx4::mul(uint32 x, uint32 y, uint32 &rl, uint32 &rh) {
|
void Cx4::mul(uint32 x, uint32 y, uint32 &rl, uint32 &rh) {
|
||||||
int64 rx = x & 0xffffff;
|
int64_t rx = x & 0xffffff;
|
||||||
int64 ry = y & 0xffffff;
|
int64_t ry = y & 0xffffff;
|
||||||
if(rx & 0x800000)rx |= ~0x7fffff;
|
if(rx & 0x800000)rx |= ~0x7fffff;
|
||||||
if(ry & 0x800000)ry |= ~0x7fffff;
|
if(ry & 0x800000)ry |= ~0x7fffff;
|
||||||
|
|
||||||
@@ -195,3 +198,5 @@ void Cx4::reset() {
|
|||||||
memset(ram, 0, 0x0c00);
|
memset(ram, 0, 0x0c00);
|
||||||
memset(reg, 0, 0x0100);
|
memset(reg, 0, 0x0100);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
#include <../base.hpp>
|
#include <../base.hpp>
|
||||||
#include <../cart/cart.hpp>
|
|
||||||
#define DSP1_CPP
|
#define DSP1_CPP
|
||||||
|
namespace SNES {
|
||||||
|
|
||||||
|
DSP1 dsp1;
|
||||||
|
|
||||||
#include "dsp1.hpp"
|
|
||||||
#include "dsp1emu.cpp"
|
#include "dsp1emu.cpp"
|
||||||
|
|
||||||
void DSP1::init() {}
|
void DSP1::init() {}
|
||||||
@@ -57,3 +59,5 @@ void DSP1::write(unsigned addr, uint8 data) {
|
|||||||
dsp1.setDr(data);
|
dsp1.setDr(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
#include <../base.hpp>
|
#include <../base.hpp>
|
||||||
#define DSP2_CPP
|
|
||||||
|
#define DSP2_CPP
|
||||||
|
namespace SNES {
|
||||||
|
|
||||||
|
DSP2 dsp2;
|
||||||
|
|
||||||
#include "dsp2.hpp"
|
|
||||||
#include "dsp2_op.cpp"
|
#include "dsp2_op.cpp"
|
||||||
|
|
||||||
void DSP2::init() {}
|
void DSP2::init() {}
|
||||||
@@ -134,3 +137,5 @@ void DSP2::write(unsigned addr, uint8 data) {
|
|||||||
|
|
||||||
DSP2::DSP2() {}
|
DSP2::DSP2() {}
|
||||||
DSP2::~DSP2() {}
|
DSP2::~DSP2() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
#include <../base.hpp>
|
#include <../base.hpp>
|
||||||
#define DSP3_CPP
|
|
||||||
|
#define DSP3_CPP
|
||||||
|
namespace SNES {
|
||||||
|
|
||||||
|
DSP3 dsp3;
|
||||||
|
|
||||||
#include "dsp3.hpp"
|
|
||||||
namespace DSP3i {
|
namespace DSP3i {
|
||||||
#define bool8 uint8
|
#define bool8 uint8
|
||||||
#include "dsp3emu.c"
|
#include "dsp3emu.c"
|
||||||
@@ -33,3 +36,5 @@ void DSP3::write(unsigned addr, uint8 data) {
|
|||||||
DSP3i::dsp3_byte = data;
|
DSP3i::dsp3_byte = data;
|
||||||
DSP3i::DSP3SetByte();
|
DSP3i::DSP3SetByte();
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
#include <../base.hpp>
|
#include <../base.hpp>
|
||||||
#define DSP4_CPP
|
|
||||||
|
#define DSP4_CPP
|
||||||
|
namespace SNES {
|
||||||
|
|
||||||
|
DSP4 dsp4;
|
||||||
|
|
||||||
#include "dsp4.hpp"
|
|
||||||
namespace DSP4i {
|
namespace DSP4i {
|
||||||
inline uint16 READ_WORD(uint8 *addr) {
|
inline uint16 READ_WORD(uint8 *addr) {
|
||||||
return (addr[0]) + (addr[1] << 8);
|
return (addr[0]) + (addr[1] << 8);
|
||||||
@@ -53,3 +56,5 @@ void DSP4::write(unsigned addr, uint8 data) {
|
|||||||
DSP4i::DSP4SetByte();
|
DSP4i::DSP4SetByte();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
#include <../base.hpp>
|
#include <../base.hpp>
|
||||||
#include <../cart/cart.hpp>
|
|
||||||
#include "obc1.hpp"
|
#define OBC1_CPP
|
||||||
|
namespace SNES {
|
||||||
|
|
||||||
|
OBC1 obc1;
|
||||||
|
|
||||||
void OBC1::init() {}
|
void OBC1::init() {}
|
||||||
void OBC1::enable() {}
|
void OBC1::enable() {}
|
||||||
@@ -21,7 +24,7 @@ uint8 OBC1::read(unsigned addr) {
|
|||||||
addr &= 0x1fff;
|
addr &= 0x1fff;
|
||||||
if((addr & 0x1ff8) != 0x1ff0) return ram_read(addr);
|
if((addr & 0x1ff8) != 0x1ff0) return ram_read(addr);
|
||||||
|
|
||||||
switch(addr) { default: //never used, avoids compiler warning
|
switch(addr) { default: //never used, avoids compiler warning
|
||||||
case 0x1ff0: return ram_read(status.baseptr + (status.address << 2) + 0);
|
case 0x1ff0: return ram_read(status.baseptr + (status.address << 2) + 0);
|
||||||
case 0x1ff1: return ram_read(status.baseptr + (status.address << 2) + 1);
|
case 0x1ff1: return ram_read(status.baseptr + (status.address << 2) + 1);
|
||||||
case 0x1ff2: return ram_read(status.baseptr + (status.address << 2) + 2);
|
case 0x1ff2: return ram_read(status.baseptr + (status.address << 2) + 2);
|
||||||
@@ -69,4 +72,7 @@ void OBC1::ram_write(unsigned addr, uint8 data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
OBC1::OBC1() {}
|
OBC1::OBC1() {}
|
||||||
OBC1::~OBC1() {}
|
OBC1::~OBC1() {}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|||||||
164
tools/bsnes/chip/sa1/bus/bus.cpp
Executable file
164
tools/bsnes/chip/sa1/bus/bus.cpp
Executable file
@@ -0,0 +1,164 @@
|
|||||||
|
#ifdef SA1_CPP
|
||||||
|
|
||||||
|
SA1Bus sa1bus;
|
||||||
|
|
||||||
|
namespace memory {
|
||||||
|
VectorSelectionPage vectorsp;
|
||||||
|
StaticRAM iram(2048);
|
||||||
|
MappedRAM &bwram = memory::cartram;
|
||||||
|
CC1BWRAM cc1bwram;
|
||||||
|
BitmapRAM bitmapram;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SA1Bus::init() {
|
||||||
|
for(uint32_t i = 0x0000; i <= 0xffff; i++) {
|
||||||
|
map(i << 8, memory::memory_unmapped, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(uint16_t i = 0x2200; i <= 0x23ff; i++) {
|
||||||
|
memory::mmio.map(i, sa1);
|
||||||
|
}
|
||||||
|
|
||||||
|
map(MapLinear, 0x00, 0x3f, 0x0000, 0x07ff, memory::iram);
|
||||||
|
map(MapDirect, 0x00, 0x3f, 0x2200, 0x23ff, memory::mmio);
|
||||||
|
map(MapLinear, 0x00, 0x3f, 0x3000, 0x37ff, memory::iram);
|
||||||
|
map(MapLinear, 0x00, 0x3f, 0x6000, 0x7fff, memory::bwram);
|
||||||
|
map(MapLinear, 0x00, 0x3f, 0x8000, 0xffff, memory::cartrom);
|
||||||
|
map(MapLinear, 0x40, 0x4f, 0x0000, 0xffff, memory::bwram);
|
||||||
|
map(MapLinear, 0x60, 0x6f, 0x0000, 0xffff, memory::bitmapram);
|
||||||
|
map(MapLinear, 0x80, 0xbf, 0x0000, 0x07ff, memory::iram);
|
||||||
|
map(MapDirect, 0x80, 0xbf, 0x2200, 0x23ff, memory::mmio);
|
||||||
|
map(MapLinear, 0x80, 0xbf, 0x3000, 0x37ff, memory::iram);
|
||||||
|
map(MapLinear, 0x80, 0xbf, 0x6000, 0x7fff, memory::bwram);
|
||||||
|
map(MapLinear, 0x80, 0xbf, 0x8000, 0xffff, memory::cartrom);
|
||||||
|
map(MapLinear, 0xc0, 0xff, 0x0000, 0xffff, memory::cartrom);
|
||||||
|
|
||||||
|
bus.map(MapLinear, 0x00, 0x3f, 0x3000, 0x37ff, memory::iram);
|
||||||
|
bus.map(MapLinear, 0x00, 0x3f, 0x6000, 0x7fff, memory::cc1bwram);
|
||||||
|
bus.map(MapLinear, 0x00, 0x3f, 0x8000, 0xffff, memory::cartrom);
|
||||||
|
bus.map(MapLinear, 0x40, 0x4f, 0x0000, 0xffff, memory::cc1bwram);
|
||||||
|
bus.map(MapLinear, 0x80, 0xbf, 0x3000, 0x37ff, memory::iram);
|
||||||
|
bus.map(MapLinear, 0x80, 0xbf, 0x6000, 0x7fff, memory::cc1bwram);
|
||||||
|
bus.map(MapLinear, 0x80, 0xbf, 0x8000, 0xffff, memory::cartrom);
|
||||||
|
bus.map(MapLinear, 0xc0, 0xff, 0x0000, 0xffff, memory::cartrom);
|
||||||
|
|
||||||
|
memory::vectorsp.sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
//===================
|
||||||
|
//VectorSelectionPage
|
||||||
|
//===================
|
||||||
|
|
||||||
|
//this class maps $00:[ff00-ffff] for the purpose of supporting:
|
||||||
|
//$2209.d6 IVSW (S-CPU IRQ vector selection) (0 = cart, 1 = SA-1)
|
||||||
|
//$2209.d4 NVSW (S-CPU NMI vector selection) (0 = cart, 1 = SA-1)
|
||||||
|
//when set, vector addresses are over-ridden with SA-1 register settings:
|
||||||
|
//SIV = S-CPU IRQ vector address override
|
||||||
|
//SNV = S-CPU NMI vector address override
|
||||||
|
//
|
||||||
|
//$00:[ffea-ffeb|ffee-ffef] are special cased on read;
|
||||||
|
//all other addresses return original mapped data.
|
||||||
|
|
||||||
|
uint8_t VectorSelectionPage::read(unsigned addr) {
|
||||||
|
switch(0xff00 | (addr & 0xff)) {
|
||||||
|
case 0xffea: case 0xffeb: {
|
||||||
|
if(sa1.mmio.cpu_nvsw == true) return (sa1.mmio.snv >> ((addr & 1) << 3));
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case 0xffee: case 0xffef: {
|
||||||
|
if(sa1.mmio.cpu_ivsw == true) return (sa1.mmio.siv >> ((addr & 1) << 3));
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return access->read(addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VectorSelectionPage::write(unsigned addr, uint8_t data) {
|
||||||
|
return access->write(addr, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
//call this whenever bus is remapped.
|
||||||
|
//note: S-CPU and SA-1 bus always share $00:[ff00-ffff] as cartridge ROM data;
|
||||||
|
//the SA-1 MMC does not allow mapping these independently between processors.
|
||||||
|
//this allows this class to be shared for both, caching only ones' access class.
|
||||||
|
void VectorSelectionPage::sync() {
|
||||||
|
if(bus.page[0x00ff00 >> 8].access != this) {
|
||||||
|
//bus was re-mapped, hook access routine
|
||||||
|
access = bus.page[0x00ff00 >> 8].access;
|
||||||
|
bus.page[0x00ff00 >> 8].access = this;
|
||||||
|
sa1bus.page[0x00ff00 >> 8].access = this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//========
|
||||||
|
//CC1BWRAM
|
||||||
|
//========
|
||||||
|
|
||||||
|
unsigned CC1BWRAM::size() const {
|
||||||
|
return memory::cartram.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t CC1BWRAM::read(unsigned addr) {
|
||||||
|
if(dma) return sa1.dma_cc1_read(addr);
|
||||||
|
return memory::cartram.read(addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CC1BWRAM::write(unsigned addr, uint8_t data) {
|
||||||
|
memory::cartram.write(addr, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
//=========
|
||||||
|
//BitmapRAM
|
||||||
|
//=========
|
||||||
|
|
||||||
|
unsigned BitmapRAM::size() const {
|
||||||
|
return 0x100000;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t BitmapRAM::read(unsigned addr) {
|
||||||
|
if(sa1.mmio.bbf == 0) {
|
||||||
|
//4bpp
|
||||||
|
unsigned shift = addr & 1;
|
||||||
|
addr = (addr >> 1) & (memory::cartram.size() - 1);
|
||||||
|
switch(shift) {
|
||||||
|
case 0: return (memory::cartram.read(addr) >> 0) & 15;
|
||||||
|
case 1: return (memory::cartram.read(addr) >> 4) & 15;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//2bpp
|
||||||
|
unsigned shift = addr & 3;
|
||||||
|
addr = (addr >> 2) & (memory::cartram.size() - 1);
|
||||||
|
switch(shift) {
|
||||||
|
case 0: return (memory::cartram.read(addr) >> 0) & 3;
|
||||||
|
case 1: return (memory::cartram.read(addr) >> 2) & 3;
|
||||||
|
case 2: return (memory::cartram.read(addr) >> 4) & 3;
|
||||||
|
case 3: return (memory::cartram.read(addr) >> 6) & 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BitmapRAM::write(unsigned addr, uint8_t data) {
|
||||||
|
if(sa1.mmio.bbf == 0) {
|
||||||
|
//4bpp
|
||||||
|
uint8_t shift = addr & 1;
|
||||||
|
addr = (addr >> 1) & (memory::cartram.size() - 1);
|
||||||
|
switch(shift) {
|
||||||
|
case 0: data = (memory::cartram.read(addr) & 0xf0) | ((data & 15) << 0); break;
|
||||||
|
case 1: data = (memory::cartram.read(addr) & 0x0f) | ((data & 15) << 4); break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//2bpp
|
||||||
|
uint8_t shift = addr & 3;
|
||||||
|
addr = (addr >> 2) & (memory::cartram.size() - 1);
|
||||||
|
switch(shift) {
|
||||||
|
case 0: data = (memory::cartram.read(addr) & 0xfc) | ((data & 3) << 0); break;
|
||||||
|
case 1: data = (memory::cartram.read(addr) & 0xf3) | ((data & 3) << 2); break;
|
||||||
|
case 2: data = (memory::cartram.read(addr) & 0xcf) | ((data & 3) << 4); break;
|
||||||
|
case 3: data = (memory::cartram.read(addr) & 0x3f) | ((data & 3) << 6); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
memory::cartram.write(addr, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
31
tools/bsnes/chip/sa1/bus/bus.hpp
Executable file
31
tools/bsnes/chip/sa1/bus/bus.hpp
Executable file
@@ -0,0 +1,31 @@
|
|||||||
|
struct SA1Bus : Bus {
|
||||||
|
void init();
|
||||||
|
};
|
||||||
|
|
||||||
|
struct VectorSelectionPage : Memory {
|
||||||
|
alwaysinline uint8_t read(unsigned);
|
||||||
|
alwaysinline void write(unsigned, uint8_t);
|
||||||
|
void sync();
|
||||||
|
Memory *access;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CC1BWRAM : Memory {
|
||||||
|
unsigned size() const;
|
||||||
|
alwaysinline uint8_t read(unsigned);
|
||||||
|
alwaysinline void write(unsigned, uint8_t);
|
||||||
|
bool dma;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BitmapRAM : Memory {
|
||||||
|
unsigned size() const;
|
||||||
|
alwaysinline uint8_t read(unsigned);
|
||||||
|
alwaysinline void write(unsigned, uint8_t);
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace memory {
|
||||||
|
extern VectorSelectionPage vectorsp;
|
||||||
|
extern StaticRAM iram;
|
||||||
|
extern MappedRAM &bwram;
|
||||||
|
extern CC1BWRAM cc1bwram;
|
||||||
|
extern BitmapRAM bitmapram;
|
||||||
|
}
|
||||||
139
tools/bsnes/chip/sa1/dma/dma.cpp
Executable file
139
tools/bsnes/chip/sa1/dma/dma.cpp
Executable file
@@ -0,0 +1,139 @@
|
|||||||
|
#ifdef SA1_CPP
|
||||||
|
|
||||||
|
//====================
|
||||||
|
//direct data transfer
|
||||||
|
//====================
|
||||||
|
|
||||||
|
void SA1::dma_normal() {
|
||||||
|
while(mmio.dtc--) {
|
||||||
|
uint8_t data = regs.mdr;
|
||||||
|
uint32_t dsa = mmio.dsa++;
|
||||||
|
uint32_t dda = mmio.dda++;
|
||||||
|
|
||||||
|
//source and destination cannot be the same
|
||||||
|
if(mmio.sd == DMA::SourceBWRAM && mmio.dd == DMA::DestBWRAM) continue;
|
||||||
|
if(mmio.sd == DMA::SourceIRAM && mmio.dd == DMA::DestIRAM ) continue;
|
||||||
|
|
||||||
|
switch(mmio.sd) {
|
||||||
|
case DMA::SourceROM: {
|
||||||
|
if((dsa & 0x408000) == 0x008000 || (dsa & 0xc00000) == 0xc00000) {
|
||||||
|
data = sa1bus.read(dsa);
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case DMA::SourceBWRAM: {
|
||||||
|
if((dsa & 0x40e000) == 0x006000 || (dsa & 0xf00000) == 0x400000) {
|
||||||
|
data = sa1bus.read(dsa);
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case DMA::SourceIRAM: {
|
||||||
|
data = memory::iram.read(dsa & 0x07ff);
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(mmio.dd) {
|
||||||
|
case DMA::DestBWRAM: {
|
||||||
|
if((dda & 0x40e000) == 0x006000 || (dda & 0xf00000) == 0x400000) {
|
||||||
|
sa1bus.write(dda, data);
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case DMA::DestIRAM: {
|
||||||
|
memory::iram.write(dda & 0x07ff, data);
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mmio.dma_irqfl = true;
|
||||||
|
if(mmio.dma_irqen) mmio.dma_irqcl = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//((byte & 6) << 3) + (byte & 1) explanation:
|
||||||
|
//transforms a byte index (0-7) into a planar index:
|
||||||
|
//result[] = { 0, 1, 16, 17, 32, 33, 48, 49 };
|
||||||
|
//works for 2bpp, 4bpp and 8bpp modes
|
||||||
|
|
||||||
|
//===========================
|
||||||
|
//type-1 character conversion
|
||||||
|
//===========================
|
||||||
|
|
||||||
|
void SA1::dma_cc1() {
|
||||||
|
memory::cc1bwram.dma = true;
|
||||||
|
mmio.chdma_irqfl = true;
|
||||||
|
if(mmio.chdma_irqen) {
|
||||||
|
mmio.chdma_irqcl = 0;
|
||||||
|
cpu.regs.irq = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t SA1::dma_cc1_read(unsigned addr) {
|
||||||
|
//16 bytes/char (2bpp); 32 bytes/char (4bpp); 64 bytes/char (8bpp)
|
||||||
|
unsigned charmask = (1 << (6 - mmio.dmacb)) - 1;
|
||||||
|
|
||||||
|
if((addr & charmask) == 0) {
|
||||||
|
//buffer next character to I-RAM
|
||||||
|
unsigned bpp = 2 << (2 - mmio.dmacb);
|
||||||
|
unsigned bpl = (8 << mmio.dmasize) >> mmio.dmacb;
|
||||||
|
unsigned bwmask = memory::bwram.size() - 1;
|
||||||
|
unsigned tile = ((addr - mmio.dsa) & bwmask) >> (6 - mmio.dmacb);
|
||||||
|
unsigned ty = (tile >> mmio.dmasize);
|
||||||
|
unsigned tx = tile & ((1 << mmio.dmasize) - 1);
|
||||||
|
unsigned bwaddr = mmio.dsa + ty * 8 * bpl + tx * bpp;
|
||||||
|
|
||||||
|
for(unsigned y = 0; y < 8; y++) {
|
||||||
|
uint64_t data = 0;
|
||||||
|
for(unsigned byte = 0; byte < bpp; byte++) {
|
||||||
|
data |= (uint64_t)memory::bwram.read((bwaddr + byte) & bwmask) << (byte << 3);
|
||||||
|
}
|
||||||
|
bwaddr += bpl;
|
||||||
|
|
||||||
|
uint8_t out[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||||
|
for(unsigned x = 0; x < 8; x++) {
|
||||||
|
out[0] |= (data & 1) << (7 - x); data >>= 1;
|
||||||
|
out[1] |= (data & 1) << (7 - x); data >>= 1;
|
||||||
|
if(mmio.dmacb == 2) continue;
|
||||||
|
out[2] |= (data & 1) << (7 - x); data >>= 1;
|
||||||
|
out[3] |= (data & 1) << (7 - x); data >>= 1;
|
||||||
|
if(mmio.dmacb == 1) continue;
|
||||||
|
out[4] |= (data & 1) << (7 - x); data >>= 1;
|
||||||
|
out[5] |= (data & 1) << (7 - x); data >>= 1;
|
||||||
|
out[6] |= (data & 1) << (7 - x); data >>= 1;
|
||||||
|
out[7] |= (data & 1) << (7 - x); data >>= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(unsigned byte = 0; byte < bpp; byte++) {
|
||||||
|
unsigned p = mmio.dda + (y << 1) + ((byte & 6) << 3) + (byte & 1);
|
||||||
|
memory::iram.write(p & 0x07ff, out[byte]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return memory::iram.read((mmio.dda + (addr & charmask)) & 0x07ff);
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================
|
||||||
|
//type-2 character conversion
|
||||||
|
//===========================
|
||||||
|
|
||||||
|
void SA1::dma_cc2() {
|
||||||
|
//select register file index (0-7 or 8-15)
|
||||||
|
const uint8_t *brf = &mmio.brf[(dma.line & 1) << 3];
|
||||||
|
unsigned bpp = 2 << (2 - mmio.dmacb);
|
||||||
|
unsigned addr = mmio.dda & 0x07ff;
|
||||||
|
addr &= ~((1 << (7 - mmio.dmacb)) - 1);
|
||||||
|
addr += (dma.line & 8) * bpp;
|
||||||
|
addr += (dma.line & 7) * 2;
|
||||||
|
|
||||||
|
for(unsigned byte = 0; byte < bpp; byte++) {
|
||||||
|
uint8_t output = 0;
|
||||||
|
for(unsigned bit = 0; bit < 8; bit++) {
|
||||||
|
output |= ((brf[bit] >> byte) & 1) << (7 - bit);
|
||||||
|
}
|
||||||
|
memory::iram.write(addr + ((byte & 6) << 3) + (byte & 1), output);
|
||||||
|
}
|
||||||
|
|
||||||
|
dma.line = (dma.line + 1) & 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
11
tools/bsnes/chip/sa1/dma/dma.hpp
Executable file
11
tools/bsnes/chip/sa1/dma/dma.hpp
Executable file
@@ -0,0 +1,11 @@
|
|||||||
|
struct DMA {
|
||||||
|
enum CDEN { DmaNormal = 0, DmaCharConversion = 1 };
|
||||||
|
enum SD { SourceROM = 0, SourceBWRAM = 1, SourceIRAM = 2 };
|
||||||
|
enum DD { DestIRAM = 0, DestBWRAM = 1 };
|
||||||
|
unsigned line;
|
||||||
|
} dma;
|
||||||
|
|
||||||
|
void dma_normal();
|
||||||
|
void dma_cc1();
|
||||||
|
uint8_t dma_cc1_read(unsigned addr);
|
||||||
|
void dma_cc2();
|
||||||
39
tools/bsnes/chip/sa1/memory/memory.cpp
Executable file
39
tools/bsnes/chip/sa1/memory/memory.cpp
Executable file
@@ -0,0 +1,39 @@
|
|||||||
|
#ifdef SA1_CPP
|
||||||
|
|
||||||
|
//==========================
|
||||||
|
//SA-1 opcode core functions
|
||||||
|
//==========================
|
||||||
|
|
||||||
|
void SA1::op_io() {
|
||||||
|
tick();
|
||||||
|
if(regs.wai) scheduler.sync_copcpu();
|
||||||
|
}
|
||||||
|
|
||||||
|
//ROM, I-RAM and MMIO registers are accessed at ~10.74MHz (2 clock ticks)
|
||||||
|
//BW-RAM is accessed at ~5.37MHz (4 clock ticks)
|
||||||
|
//tick() == 2 clock ticks
|
||||||
|
//note: bus conflict delays are not emulated at this time
|
||||||
|
|
||||||
|
#define is_bwram(addr) (\
|
||||||
|
((addr & 0x40e000) == 0x006000) \
|
||||||
|
|| ((addr & 0xf00000) == 0x400000) \
|
||||||
|
|| ((addr & 0xf00000) == 0x600000) \
|
||||||
|
)
|
||||||
|
|
||||||
|
uint8_t SA1::op_read(unsigned addr) {
|
||||||
|
tick();
|
||||||
|
if(is_bwram(addr)) tick();
|
||||||
|
scheduler.sync_copcpu();
|
||||||
|
return sa1bus.read(addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SA1::op_write(unsigned addr, uint8_t data) {
|
||||||
|
tick();
|
||||||
|
if(is_bwram(addr)) tick();
|
||||||
|
scheduler.sync_copcpu();
|
||||||
|
sa1bus.write(addr, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef is_bwram
|
||||||
|
|
||||||
|
#endif
|
||||||
4
tools/bsnes/chip/sa1/memory/memory.hpp
Executable file
4
tools/bsnes/chip/sa1/memory/memory.hpp
Executable file
@@ -0,0 +1,4 @@
|
|||||||
|
alwaysinline void op_io();
|
||||||
|
alwaysinline uint8_t op_read(unsigned addr);
|
||||||
|
alwaysinline void op_write(unsigned addr, uint8_t data);
|
||||||
|
alwaysinline unsigned bus_speed(unsigned addr);
|
||||||
631
tools/bsnes/chip/sa1/mmio/mmio.cpp
Executable file
631
tools/bsnes/chip/sa1/mmio/mmio.cpp
Executable file
@@ -0,0 +1,631 @@
|
|||||||
|
#ifdef SA1_CPP
|
||||||
|
|
||||||
|
//BS-X flash carts, when present, are mapped to 0x400000+
|
||||||
|
Memory& SA1::mmio_access(unsigned &addr) {
|
||||||
|
if(!memory::bsxflash.data()) return memory::cartrom;
|
||||||
|
if(addr < 0x400000) return memory::cartrom;
|
||||||
|
addr &= 0x3fffff;
|
||||||
|
return bsxflash;
|
||||||
|
}
|
||||||
|
|
||||||
|
//(CCNT) SA-1 control
|
||||||
|
void SA1::mmio_w2200(uint8_t data) {
|
||||||
|
if(mmio.sa1_resb && !(data & 0x80)) {
|
||||||
|
//reset SA-1 CPU
|
||||||
|
regs.pc.w = mmio.crv;
|
||||||
|
regs.pc.b = 0x00;
|
||||||
|
}
|
||||||
|
|
||||||
|
mmio.sa1_irq = (data & 0x80);
|
||||||
|
mmio.sa1_rdyb = (data & 0x40);
|
||||||
|
mmio.sa1_resb = (data & 0x20);
|
||||||
|
mmio.sa1_nmi = (data & 0x10);
|
||||||
|
mmio.smeg = (data & 0x0f);
|
||||||
|
|
||||||
|
if(mmio.sa1_irq) {
|
||||||
|
mmio.sa1_irqfl = true;
|
||||||
|
if(mmio.sa1_irqen) mmio.sa1_irqcl = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(mmio.sa1_nmi) {
|
||||||
|
mmio.sa1_nmifl = true;
|
||||||
|
if(mmio.sa1_nmien) mmio.sa1_nmicl = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//(SIE) S-CPU interrupt enable
|
||||||
|
void SA1::mmio_w2201(uint8_t data) {
|
||||||
|
if(!mmio.cpu_irqen && (data & 0x80)) {
|
||||||
|
if(mmio.cpu_irqfl) {
|
||||||
|
mmio.cpu_irqcl = 0;
|
||||||
|
cpu.regs.irq = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!mmio.chdma_irqen && (data & 0x20)) {
|
||||||
|
if(mmio.chdma_irqfl) {
|
||||||
|
mmio.chdma_irqcl = 0;
|
||||||
|
cpu.regs.irq = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mmio.cpu_irqen = (data & 0x80);
|
||||||
|
mmio.chdma_irqen = (data & 0x20);
|
||||||
|
}
|
||||||
|
|
||||||
|
//(SIC) S-CPU interrupt clear
|
||||||
|
void SA1::mmio_w2202(uint8_t data) {
|
||||||
|
mmio.cpu_irqcl = (data & 0x80);
|
||||||
|
mmio.chdma_irqcl = (data & 0x20);
|
||||||
|
|
||||||
|
if(mmio.cpu_irqcl ) mmio.cpu_irqfl = false;
|
||||||
|
if(mmio.chdma_irqcl) mmio.chdma_irqfl = false;
|
||||||
|
|
||||||
|
if(!mmio.cpu_irqfl && !mmio.chdma_irqfl) cpu.regs.irq = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//(CRV) SA-1 reset vector
|
||||||
|
void SA1::mmio_w2203(uint8_t data) { mmio.crv = (mmio.crv & 0xff00) | data; }
|
||||||
|
void SA1::mmio_w2204(uint8_t data) { mmio.crv = (data << 8) | (mmio.crv & 0xff); }
|
||||||
|
|
||||||
|
//(CNV) SA-1 NMI vector
|
||||||
|
void SA1::mmio_w2205(uint8_t data) { mmio.cnv = (mmio.cnv & 0xff00) | data; }
|
||||||
|
void SA1::mmio_w2206(uint8_t data) { mmio.cnv = (data << 8) | (mmio.cnv & 0xff); }
|
||||||
|
|
||||||
|
//(CIV) SA-1 IRQ vector
|
||||||
|
void SA1::mmio_w2207(uint8_t data) { mmio.civ = (mmio.civ & 0xff00) | data; }
|
||||||
|
void SA1::mmio_w2208(uint8_t data) { mmio.civ = (data << 8) | (mmio.civ & 0xff); }
|
||||||
|
|
||||||
|
//(SCNT) S-CPU control
|
||||||
|
void SA1::mmio_w2209(uint8_t data) {
|
||||||
|
mmio.cpu_irq = (data & 0x80);
|
||||||
|
mmio.cpu_ivsw = (data & 0x40);
|
||||||
|
mmio.cpu_nvsw = (data & 0x10);
|
||||||
|
mmio.cmeg = (data & 0x0f);
|
||||||
|
|
||||||
|
if(mmio.cpu_irq) {
|
||||||
|
mmio.cpu_irqfl = true;
|
||||||
|
if(mmio.cpu_irqen) {
|
||||||
|
mmio.cpu_irqcl = 0;
|
||||||
|
cpu.regs.irq = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//(CIE) SA-1 interrupt enable
|
||||||
|
void SA1::mmio_w220a(uint8_t data) {
|
||||||
|
if(!mmio.sa1_irqen && (data & 0x80) && mmio.sa1_irqfl ) mmio.sa1_irqcl = 0;
|
||||||
|
if(!mmio.timer_irqen && (data & 0x40) && mmio.timer_irqfl) mmio.timer_irqcl = 0;
|
||||||
|
if(!mmio.dma_irqen && (data & 0x20) && mmio.dma_irqfl ) mmio.dma_irqcl = 0;
|
||||||
|
if(!mmio.sa1_nmien && (data & 0x10) && mmio.sa1_nmifl ) mmio.sa1_nmicl = 0;
|
||||||
|
|
||||||
|
mmio.sa1_irqen = (data & 0x80);
|
||||||
|
mmio.timer_irqen = (data & 0x40);
|
||||||
|
mmio.dma_irqen = (data & 0x20);
|
||||||
|
mmio.sa1_nmien = (data & 0x10);
|
||||||
|
}
|
||||||
|
|
||||||
|
//(CIC) SA-1 interrupt clear
|
||||||
|
void SA1::mmio_w220b(uint8_t data) {
|
||||||
|
mmio.sa1_irqcl = (data & 0x80);
|
||||||
|
mmio.timer_irqcl = (data & 0x40);
|
||||||
|
mmio.dma_irqcl = (data & 0x20);
|
||||||
|
mmio.sa1_nmicl = (data & 0x10);
|
||||||
|
|
||||||
|
if(mmio.sa1_irqcl) mmio.sa1_irqfl = false;
|
||||||
|
if(mmio.timer_irqcl) mmio.timer_irqfl = false;
|
||||||
|
if(mmio.dma_irqcl) mmio.dma_irqfl = false;
|
||||||
|
if(mmio.sa1_nmicl) mmio.sa1_nmifl = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//(SNV) S-CPU NMI vector
|
||||||
|
void SA1::mmio_w220c(uint8_t data) { mmio.snv = (mmio.snv & 0xff00) | data; }
|
||||||
|
void SA1::mmio_w220d(uint8_t data) { mmio.snv = (data << 8) | (mmio.snv & 0xff); }
|
||||||
|
|
||||||
|
//(SIV) S-CPU IRQ vector
|
||||||
|
void SA1::mmio_w220e(uint8_t data) { mmio.siv = (mmio.siv & 0xff00) | data; }
|
||||||
|
void SA1::mmio_w220f(uint8_t data) { mmio.siv = (data << 8) | (mmio.siv & 0xff); }
|
||||||
|
|
||||||
|
//(TMC) H/V timer control
|
||||||
|
void SA1::mmio_w2210(uint8_t data) {
|
||||||
|
mmio.hvselb = (data & 0x80);
|
||||||
|
mmio.ven = (data & 0x02);
|
||||||
|
mmio.hen = (data & 0x01);
|
||||||
|
}
|
||||||
|
|
||||||
|
//(CTR) SA-1 timer restart
|
||||||
|
void SA1::mmio_w2211(uint8_t data) {
|
||||||
|
status.vcounter = 0;
|
||||||
|
status.hcounter = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//(HCNT) H-count
|
||||||
|
void SA1::mmio_w2212(uint8_t data) { mmio.hcnt = (mmio.hcnt & 0xff00) | (data << 0); }
|
||||||
|
void SA1::mmio_w2213(uint8_t data) { mmio.hcnt = (mmio.hcnt & 0x00ff) | (data << 8); }
|
||||||
|
|
||||||
|
//(VCNT) V-count
|
||||||
|
void SA1::mmio_w2214(uint8_t data) { mmio.vcnt = (mmio.vcnt & 0xff00) | (data << 0); }
|
||||||
|
void SA1::mmio_w2215(uint8_t data) { mmio.vcnt = (mmio.vcnt & 0x00ff) | (data << 8); }
|
||||||
|
|
||||||
|
//(CXB) Super MMC bank C
|
||||||
|
void SA1::mmio_w2220(uint8_t data) {
|
||||||
|
mmio.cbmode = (data & 0x80);
|
||||||
|
mmio.cb = (data & 0x07);
|
||||||
|
|
||||||
|
unsigned addr = mmio.cb << 20;
|
||||||
|
Memory &access = mmio_access(addr);
|
||||||
|
|
||||||
|
if(mmio.cbmode == 0) {
|
||||||
|
bus.map(Bus::MapLinear, 0x00, 0x1f, 0x8000, 0xffff, memory::cartrom, 0x000000);
|
||||||
|
sa1bus.map(Bus::MapLinear, 0x00, 0x1f, 0x8000, 0xffff, memory::cartrom, 0x000000);
|
||||||
|
} else {
|
||||||
|
bus.map(Bus::MapLinear, 0x00, 0x1f, 0x8000, 0xffff, access, addr);
|
||||||
|
sa1bus.map(Bus::MapLinear, 0x00, 0x1f, 0x8000, 0xffff, access, addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
bus.map(Bus::MapLinear, 0xc0, 0xcf, 0x0000, 0xffff, access, addr);
|
||||||
|
sa1bus.map(Bus::MapLinear, 0xc0, 0xcf, 0x0000, 0xffff, access, addr);
|
||||||
|
|
||||||
|
memory::vectorsp.sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
//(DXB) Super MMC bank D
|
||||||
|
void SA1::mmio_w2221(uint8_t data) {
|
||||||
|
mmio.dbmode = (data & 0x80);
|
||||||
|
mmio.db = (data & 0x07);
|
||||||
|
|
||||||
|
unsigned addr = mmio.db << 20;
|
||||||
|
Memory &access = mmio_access(addr);
|
||||||
|
|
||||||
|
if(mmio.dbmode == 0) {
|
||||||
|
bus.map(Bus::MapLinear, 0x20, 0x3f, 0x8000, 0xffff, memory::cartrom, 0x100000);
|
||||||
|
sa1bus.map(Bus::MapLinear, 0x20, 0x3f, 0x8000, 0xffff, memory::cartrom, 0x100000);
|
||||||
|
} else {
|
||||||
|
bus.map(Bus::MapLinear, 0x20, 0x3f, 0x8000, 0xffff, access, addr);
|
||||||
|
sa1bus.map(Bus::MapLinear, 0x20, 0x3f, 0x8000, 0xffff, access, addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
bus.map(Bus::MapLinear, 0xd0, 0xdf, 0x0000, 0xffff, access, addr);
|
||||||
|
sa1bus.map(Bus::MapLinear, 0xd0, 0xdf, 0x0000, 0xffff, access, addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
//(EXB) Super MMC bank E
|
||||||
|
void SA1::mmio_w2222(uint8_t data) {
|
||||||
|
mmio.ebmode = (data & 0x80);
|
||||||
|
mmio.eb = (data & 0x07);
|
||||||
|
|
||||||
|
unsigned addr = mmio.eb << 20;
|
||||||
|
Memory &access = mmio_access(addr);
|
||||||
|
|
||||||
|
if(mmio.ebmode == 0) {
|
||||||
|
bus.map(Bus::MapLinear, 0x80, 0x9f, 0x8000, 0xffff, memory::cartrom, 0x200000);
|
||||||
|
sa1bus.map(Bus::MapLinear, 0x80, 0x9f, 0x8000, 0xffff, memory::cartrom, 0x200000);
|
||||||
|
} else {
|
||||||
|
bus.map(Bus::MapLinear, 0x80, 0x9f, 0x8000, 0xffff, access, addr);
|
||||||
|
sa1bus.map(Bus::MapLinear, 0x80, 0x9f, 0x8000, 0xffff, access, addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
bus.map(Bus::MapLinear, 0xe0, 0xef, 0x0000, 0xffff, access, addr);
|
||||||
|
sa1bus.map(Bus::MapLinear, 0xe0, 0xef, 0x0000, 0xffff, access, addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
//(FXB) Super MMC bank F
|
||||||
|
void SA1::mmio_w2223(uint8_t data) {
|
||||||
|
mmio.fbmode = (data & 0x80);
|
||||||
|
mmio.fb = (data & 0x07);
|
||||||
|
|
||||||
|
unsigned addr = mmio.fb << 20;
|
||||||
|
Memory &access = mmio_access(addr);
|
||||||
|
|
||||||
|
if(mmio.fbmode == 0) {
|
||||||
|
bus.map(Bus::MapLinear, 0xa0, 0xbf, 0x8000, 0xffff, memory::cartrom, 0x300000);
|
||||||
|
sa1bus.map(Bus::MapLinear, 0xa0, 0xbf, 0x8000, 0xffff, memory::cartrom, 0x300000);
|
||||||
|
} else {
|
||||||
|
bus.map(Bus::MapLinear, 0xa0, 0xbf, 0x8000, 0xffff, access, addr);
|
||||||
|
sa1bus.map(Bus::MapLinear, 0xa0, 0xbf, 0x8000, 0xffff, access, addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
bus.map(Bus::MapLinear, 0xf0, 0xff, 0x0000, 0xffff, access, addr);
|
||||||
|
sa1bus.map(Bus::MapLinear, 0xf0, 0xff, 0x0000, 0xffff, access, addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
//(BMAPS) S-CPU BW-RAM address mapping
|
||||||
|
void SA1::mmio_w2224(uint8_t data) {
|
||||||
|
mmio.sbm = (data & 0x1f);
|
||||||
|
|
||||||
|
bus.map(Bus::MapLinear, 0x00, 0x3f, 0x6000, 0x7fff, memory::cc1bwram, mmio.sbm * 0x2000, 0x2000);
|
||||||
|
bus.map(Bus::MapLinear, 0x80, 0xbf, 0x6000, 0x7fff, memory::cc1bwram, mmio.sbm * 0x2000, 0x2000);
|
||||||
|
}
|
||||||
|
|
||||||
|
//(BMAP) SA-1 BW-RAM address mapping
|
||||||
|
void SA1::mmio_w2225(uint8_t data) {
|
||||||
|
mmio.sw46 = (data & 0x80);
|
||||||
|
mmio.cbm = (data & 0x7f);
|
||||||
|
|
||||||
|
if(mmio.sw46 == 0) {
|
||||||
|
//$[40-43]:[0000-ffff] x 32 projection
|
||||||
|
sa1bus.map(Bus::MapLinear, 0x00, 0x3f, 0x6000, 0x7fff, memory::bwram, (mmio.cbm & 0x1f) * 0x2000, 0x2000);
|
||||||
|
sa1bus.map(Bus::MapLinear, 0x80, 0xbf, 0x6000, 0x7fff, memory::bwram, (mmio.cbm & 0x1f) * 0x2000, 0x2000);
|
||||||
|
} else {
|
||||||
|
//$[60-6f]:[0000-ffff] x 128 projection
|
||||||
|
sa1bus.map(Bus::MapLinear, 0x00, 0x3f, 0x6000, 0x7fff, memory::bitmapram, mmio.cbm * 0x2000, 0x2000);
|
||||||
|
sa1bus.map(Bus::MapLinear, 0x80, 0xbf, 0x6000, 0x7fff, memory::bitmapram, mmio.cbm * 0x2000, 0x2000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//(SWBE) S-CPU BW-RAM write enable
|
||||||
|
void SA1::mmio_w2226(uint8_t data) {
|
||||||
|
mmio.swen = (data & 0x80);
|
||||||
|
}
|
||||||
|
|
||||||
|
//(CWBE) SA-1 BW-RAM write enable
|
||||||
|
void SA1::mmio_w2227(uint8_t data) {
|
||||||
|
mmio.cwen = (data & 0x80);
|
||||||
|
}
|
||||||
|
|
||||||
|
//(BWPA) BW-RAM write-protected area
|
||||||
|
void SA1::mmio_w2228(uint8_t data) {
|
||||||
|
mmio.bwp = (data & 0x0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
//(SIWP) S-CPU I-RAM write protection
|
||||||
|
void SA1::mmio_w2229(uint8_t data) {
|
||||||
|
mmio.siwp = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
//(CIWP) SA-1 I-RAM write protection
|
||||||
|
void SA1::mmio_w222a(uint8_t data) {
|
||||||
|
mmio.ciwp = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
//(DCNT) DMA control
|
||||||
|
void SA1::mmio_w2230(uint8_t data) {
|
||||||
|
mmio.dmaen = (data & 0x80);
|
||||||
|
mmio.dprio = (data & 0x40);
|
||||||
|
mmio.cden = (data & 0x20);
|
||||||
|
mmio.cdsel = (data & 0x10);
|
||||||
|
mmio.dd = (data & 0x04);
|
||||||
|
mmio.sd = (data & 0x03);
|
||||||
|
|
||||||
|
if(mmio.dmaen == 0) dma.line = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//(CDMA) character conversion DMA parameters
|
||||||
|
void SA1::mmio_w2231(uint8_t data) {
|
||||||
|
mmio.chdend = (data & 0x80);
|
||||||
|
mmio.dmasize = (data >> 2) & 7;
|
||||||
|
mmio.dmacb = (data & 0x03);
|
||||||
|
|
||||||
|
if(mmio.chdend) memory::cc1bwram.dma = false;
|
||||||
|
if(mmio.dmasize > 5) mmio.dmasize = 5;
|
||||||
|
if(mmio.dmacb > 2) mmio.dmacb = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
//(SDA) DMA source device start address
|
||||||
|
void SA1::mmio_w2232(uint8_t data) { mmio.dsa = (mmio.dsa & 0xffff00) | (data << 0); }
|
||||||
|
void SA1::mmio_w2233(uint8_t data) { mmio.dsa = (mmio.dsa & 0xff00ff) | (data << 8); }
|
||||||
|
void SA1::mmio_w2234(uint8_t data) { mmio.dsa = (mmio.dsa & 0x00ffff) | (data << 16); }
|
||||||
|
|
||||||
|
//(DDA) DMA destination start address
|
||||||
|
void SA1::mmio_w2235(uint8_t data) {
|
||||||
|
mmio.dda = (mmio.dda & 0xffff00) | (data << 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SA1::mmio_w2236(uint8_t data) {
|
||||||
|
mmio.dda = (mmio.dda & 0xff00ff) | (data << 8);
|
||||||
|
|
||||||
|
if(mmio.dmaen == true) {
|
||||||
|
if(mmio.cden == 0 && mmio.dd == DMA::DestIRAM) {
|
||||||
|
dma_normal();
|
||||||
|
} else if(mmio.cden == 1 && mmio.cdsel == 1) {
|
||||||
|
dma_cc1();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SA1::mmio_w2237(uint8_t data) {
|
||||||
|
mmio.dda = (mmio.dda & 0x00ffff) | (data << 16);
|
||||||
|
|
||||||
|
if(mmio.dmaen == true) {
|
||||||
|
if(mmio.cden == 0 && mmio.dd == DMA::DestBWRAM) {
|
||||||
|
dma_normal();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//(DTC) DMA terminal counter
|
||||||
|
void SA1::mmio_w2238(uint8_t data) { mmio.dtc = (mmio.dtc & 0xff00) | (data << 0); }
|
||||||
|
void SA1::mmio_w2239(uint8_t data) { mmio.dtc = (mmio.dtc & 0x00ff) | (data << 8); }
|
||||||
|
|
||||||
|
//(BBF) BW-RAM bitmap format
|
||||||
|
void SA1::mmio_w223f(uint8_t data) {
|
||||||
|
mmio.bbf = (data & 0x80);
|
||||||
|
}
|
||||||
|
|
||||||
|
//(BRF) bitmap register files
|
||||||
|
void SA1::mmio_w2240(uint8_t data) { mmio.brf[ 0] = data; }
|
||||||
|
void SA1::mmio_w2241(uint8_t data) { mmio.brf[ 1] = data; }
|
||||||
|
void SA1::mmio_w2242(uint8_t data) { mmio.brf[ 2] = data; }
|
||||||
|
void SA1::mmio_w2243(uint8_t data) { mmio.brf[ 3] = data; }
|
||||||
|
void SA1::mmio_w2244(uint8_t data) { mmio.brf[ 4] = data; }
|
||||||
|
void SA1::mmio_w2245(uint8_t data) { mmio.brf[ 5] = data; }
|
||||||
|
void SA1::mmio_w2246(uint8_t data) { mmio.brf[ 6] = data; }
|
||||||
|
void SA1::mmio_w2247(uint8_t data) { mmio.brf[ 7] = data;
|
||||||
|
if(mmio.dmaen == true) {
|
||||||
|
if(mmio.cden == 1 && mmio.cdsel == 0) {
|
||||||
|
dma_cc2();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SA1::mmio_w2248(uint8_t data) { mmio.brf[ 8] = data; }
|
||||||
|
void SA1::mmio_w2249(uint8_t data) { mmio.brf[ 9] = data; }
|
||||||
|
void SA1::mmio_w224a(uint8_t data) { mmio.brf[10] = data; }
|
||||||
|
void SA1::mmio_w224b(uint8_t data) { mmio.brf[11] = data; }
|
||||||
|
void SA1::mmio_w224c(uint8_t data) { mmio.brf[12] = data; }
|
||||||
|
void SA1::mmio_w224d(uint8_t data) { mmio.brf[13] = data; }
|
||||||
|
void SA1::mmio_w224e(uint8_t data) { mmio.brf[14] = data; }
|
||||||
|
void SA1::mmio_w224f(uint8_t data) { mmio.brf[15] = data;
|
||||||
|
if(mmio.dmaen == true) {
|
||||||
|
if(mmio.cden == 1 && mmio.cdsel == 0) {
|
||||||
|
dma_cc2();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//(MCNT) arithmetic control
|
||||||
|
void SA1::mmio_w2250(uint8_t data) {
|
||||||
|
mmio.acm = (data & 0x02);
|
||||||
|
mmio.md = (data & 0x01);
|
||||||
|
|
||||||
|
if(mmio.acm) mmio.mr = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//(MAL) multiplicand / dividend low
|
||||||
|
void SA1::mmio_w2251(uint8_t data) {
|
||||||
|
mmio.ma = (mmio.ma & 0xff00) | data;
|
||||||
|
}
|
||||||
|
|
||||||
|
//(MAH) multiplicand / dividend high
|
||||||
|
void SA1::mmio_w2252(uint8_t data) {
|
||||||
|
mmio.ma = (data << 8) | (mmio.ma & 0x00ff);
|
||||||
|
}
|
||||||
|
|
||||||
|
//(MBL) multiplier / divisor low
|
||||||
|
void SA1::mmio_w2253(uint8_t data) {
|
||||||
|
mmio.mb = (mmio.mb & 0xff00) | data;
|
||||||
|
}
|
||||||
|
|
||||||
|
//(MBH) multiplier / divisor high
|
||||||
|
//multiplication / cumulative sum only resets MB
|
||||||
|
//division resets both MA and MB
|
||||||
|
void SA1::mmio_w2254(uint8_t data) {
|
||||||
|
mmio.mb = (data << 8) | (mmio.mb & 0x00ff);
|
||||||
|
|
||||||
|
if(mmio.acm == 0) {
|
||||||
|
if(mmio.md == 0) {
|
||||||
|
//signed multiplication
|
||||||
|
mmio.mr = (int16_t)mmio.ma * (int16_t)mmio.mb;
|
||||||
|
mmio.mb = 0;
|
||||||
|
} else {
|
||||||
|
//unsigned division
|
||||||
|
if(mmio.mb == 0) {
|
||||||
|
mmio.mr = 0;
|
||||||
|
} else {
|
||||||
|
int16_t quotient = (int16_t)mmio.ma / (uint16_t)mmio.mb;
|
||||||
|
uint16_t remainder = (int16_t)mmio.ma % (uint16_t)mmio.mb;
|
||||||
|
mmio.mr = (remainder << 16) | quotient;
|
||||||
|
}
|
||||||
|
mmio.ma = 0;
|
||||||
|
mmio.mb = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//sigma (accumulative multiplication)
|
||||||
|
mmio.mr += (int16_t)mmio.ma * (int16_t)mmio.mb;
|
||||||
|
mmio.overflow = (mmio.mr >= (1ULL << 40));
|
||||||
|
mmio.mr &= (1ULL << 40) - 1;
|
||||||
|
mmio.mb = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//(VBD) variable-length bit processing
|
||||||
|
void SA1::mmio_w2258(uint8_t data) {
|
||||||
|
mmio.hl = (data & 0x80);
|
||||||
|
mmio.vb = (data & 0x0f);
|
||||||
|
if(mmio.vb == 0) mmio.vb = 16;
|
||||||
|
|
||||||
|
if(mmio.hl == 0) {
|
||||||
|
//fixed mode
|
||||||
|
mmio.vbit += mmio.vb;
|
||||||
|
mmio.va += (mmio.vbit >> 3);
|
||||||
|
mmio.vbit &= 7;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//(VDA) variable-length bit game pak ROM start address
|
||||||
|
void SA1::mmio_w2259(uint8_t data) { mmio.va = (mmio.va & 0xffff00) | (data << 0); }
|
||||||
|
void SA1::mmio_w225a(uint8_t data) { mmio.va = (mmio.va & 0xff00ff) | (data << 8); }
|
||||||
|
void SA1::mmio_w225b(uint8_t data) { mmio.va = (mmio.va & 0x00ffff) | (data << 16); mmio.vbit = 0; }
|
||||||
|
|
||||||
|
//(SFR) S-CPU flag read
|
||||||
|
uint8_t SA1::mmio_r2300() {
|
||||||
|
uint8_t data;
|
||||||
|
data = mmio.cpu_irqfl << 7;
|
||||||
|
data |= mmio.cpu_ivsw << 6;
|
||||||
|
data |= mmio.chdma_irqfl << 5;
|
||||||
|
data |= mmio.cpu_nvsw << 4;
|
||||||
|
data |= mmio.cmeg;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
//(CFR) SA-1 flag read
|
||||||
|
uint8_t SA1::mmio_r2301() {
|
||||||
|
uint8_t data;
|
||||||
|
data = mmio.sa1_irqfl << 7;
|
||||||
|
data |= mmio.timer_irqfl << 6;
|
||||||
|
data |= mmio.dma_irqfl << 5;
|
||||||
|
data |= mmio.sa1_nmifl << 4;
|
||||||
|
data |= mmio.smeg;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
//(HCR) hcounter read
|
||||||
|
uint8_t SA1::mmio_r2302() {
|
||||||
|
//latch counters
|
||||||
|
mmio.hcr = status.hcounter >> 2;
|
||||||
|
mmio.vcr = status.vcounter;
|
||||||
|
return mmio.hcr >> 0; }
|
||||||
|
uint8_t SA1::mmio_r2303() { return mmio.hcr >> 8; }
|
||||||
|
|
||||||
|
//(VCR) vcounter read
|
||||||
|
uint8_t SA1::mmio_r2304() { return mmio.vcr >> 0; }
|
||||||
|
uint8_t SA1::mmio_r2305() { return mmio.vcr >> 8; }
|
||||||
|
|
||||||
|
//(MR) arithmetic result
|
||||||
|
uint8_t SA1::mmio_r2306() { return mmio.mr >> 0; }
|
||||||
|
uint8_t SA1::mmio_r2307() { return mmio.mr >> 8; }
|
||||||
|
uint8_t SA1::mmio_r2308() { return mmio.mr >> 16; }
|
||||||
|
uint8_t SA1::mmio_r2309() { return mmio.mr >> 24; }
|
||||||
|
uint8_t SA1::mmio_r230a() { return mmio.mr >> 32; }
|
||||||
|
|
||||||
|
//(OF) arithmetic overflow flag
|
||||||
|
uint8_t SA1::mmio_r230b() { return mmio.overflow << 7; }
|
||||||
|
|
||||||
|
//(VDPL) variable-length data read port low
|
||||||
|
uint8_t SA1::mmio_r230c() {
|
||||||
|
uint32_t data = (sa1bus.read(mmio.va + 0) << 0)
|
||||||
|
| (sa1bus.read(mmio.va + 1) << 8)
|
||||||
|
| (sa1bus.read(mmio.va + 2) << 16);
|
||||||
|
data >>= mmio.vbit;
|
||||||
|
return data >> 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//(VDPH) variable-length data read port high
|
||||||
|
uint8_t SA1::mmio_r230d() {
|
||||||
|
uint32_t data = (sa1bus.read(mmio.va + 0) << 0)
|
||||||
|
| (sa1bus.read(mmio.va + 1) << 8)
|
||||||
|
| (sa1bus.read(mmio.va + 2) << 16);
|
||||||
|
data >>= mmio.vbit;
|
||||||
|
|
||||||
|
if(mmio.hl == 1) {
|
||||||
|
//auto-increment mode
|
||||||
|
mmio.vbit += mmio.vb;
|
||||||
|
mmio.va += (mmio.vbit >> 3);
|
||||||
|
mmio.vbit &= 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
return data >> 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
//(VC) version code register
|
||||||
|
uint8_t SA1::mmio_r230e() {
|
||||||
|
return 0x01; //true value unknown
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t SA1::mmio_read(unsigned addr) {
|
||||||
|
addr &= 0xffff;
|
||||||
|
|
||||||
|
switch(addr) {
|
||||||
|
case 0x2300: return mmio_r2300();
|
||||||
|
case 0x2301: return mmio_r2301();
|
||||||
|
case 0x2302: return mmio_r2302();
|
||||||
|
case 0x2303: return mmio_r2303();
|
||||||
|
case 0x2304: return mmio_r2304();
|
||||||
|
case 0x2305: return mmio_r2305();
|
||||||
|
case 0x2306: return mmio_r2306();
|
||||||
|
case 0x2307: return mmio_r2307();
|
||||||
|
case 0x2308: return mmio_r2308();
|
||||||
|
case 0x2309: return mmio_r2309();
|
||||||
|
case 0x230a: return mmio_r230a();
|
||||||
|
case 0x230b: return mmio_r230b();
|
||||||
|
case 0x230c: return mmio_r230c();
|
||||||
|
case 0x230d: return mmio_r230d();
|
||||||
|
case 0x230e: return mmio_r230e();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0x00;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SA1::mmio_write(unsigned addr, uint8_t data) {
|
||||||
|
addr &= 0xffff;
|
||||||
|
|
||||||
|
switch(addr) {
|
||||||
|
case 0x2200: return mmio_w2200(data);
|
||||||
|
case 0x2201: return mmio_w2201(data);
|
||||||
|
case 0x2202: return mmio_w2202(data);
|
||||||
|
case 0x2203: return mmio_w2203(data);
|
||||||
|
case 0x2204: return mmio_w2204(data);
|
||||||
|
case 0x2205: return mmio_w2205(data);
|
||||||
|
case 0x2206: return mmio_w2206(data);
|
||||||
|
case 0x2207: return mmio_w2207(data);
|
||||||
|
case 0x2208: return mmio_w2208(data);
|
||||||
|
case 0x2209: return mmio_w2209(data);
|
||||||
|
case 0x220a: return mmio_w220a(data);
|
||||||
|
case 0x220b: return mmio_w220b(data);
|
||||||
|
case 0x220c: return mmio_w220c(data);
|
||||||
|
case 0x220d: return mmio_w220d(data);
|
||||||
|
case 0x220e: return mmio_w220e(data);
|
||||||
|
case 0x220f: return mmio_w220f(data);
|
||||||
|
|
||||||
|
case 0x2210: return mmio_w2210(data);
|
||||||
|
case 0x2211: return mmio_w2211(data);
|
||||||
|
case 0x2212: return mmio_w2212(data);
|
||||||
|
case 0x2213: return mmio_w2213(data);
|
||||||
|
case 0x2214: return mmio_w2214(data);
|
||||||
|
case 0x2215: return mmio_w2215(data);
|
||||||
|
|
||||||
|
case 0x2220: return mmio_w2220(data);
|
||||||
|
case 0x2221: return mmio_w2221(data);
|
||||||
|
case 0x2222: return mmio_w2222(data);
|
||||||
|
case 0x2223: return mmio_w2223(data);
|
||||||
|
case 0x2224: return mmio_w2224(data);
|
||||||
|
case 0x2225: return mmio_w2225(data);
|
||||||
|
case 0x2226: return mmio_w2226(data);
|
||||||
|
case 0x2227: return mmio_w2227(data);
|
||||||
|
case 0x2228: return mmio_w2228(data);
|
||||||
|
case 0x2229: return mmio_w2229(data);
|
||||||
|
case 0x222a: return mmio_w222a(data);
|
||||||
|
|
||||||
|
case 0x2230: return mmio_w2230(data);
|
||||||
|
case 0x2231: return mmio_w2231(data);
|
||||||
|
case 0x2232: return mmio_w2232(data);
|
||||||
|
case 0x2233: return mmio_w2233(data);
|
||||||
|
case 0x2234: return mmio_w2234(data);
|
||||||
|
case 0x2235: return mmio_w2235(data);
|
||||||
|
case 0x2236: return mmio_w2236(data);
|
||||||
|
case 0x2237: return mmio_w2237(data);
|
||||||
|
case 0x2238: return mmio_w2238(data);
|
||||||
|
case 0x2239: return mmio_w2239(data);
|
||||||
|
|
||||||
|
case 0x223f: return mmio_w223f(data);
|
||||||
|
case 0x2240: return mmio_w2240(data);
|
||||||
|
case 0x2241: return mmio_w2241(data);
|
||||||
|
case 0x2242: return mmio_w2242(data);
|
||||||
|
case 0x2243: return mmio_w2243(data);
|
||||||
|
case 0x2244: return mmio_w2244(data);
|
||||||
|
case 0x2245: return mmio_w2245(data);
|
||||||
|
case 0x2246: return mmio_w2246(data);
|
||||||
|
case 0x2247: return mmio_w2247(data);
|
||||||
|
case 0x2248: return mmio_w2248(data);
|
||||||
|
case 0x2249: return mmio_w2249(data);
|
||||||
|
case 0x224a: return mmio_w224a(data);
|
||||||
|
case 0x224b: return mmio_w224b(data);
|
||||||
|
case 0x224c: return mmio_w224c(data);
|
||||||
|
case 0x224d: return mmio_w224d(data);
|
||||||
|
case 0x224e: return mmio_w224e(data);
|
||||||
|
case 0x224f: return mmio_w224f(data);
|
||||||
|
|
||||||
|
case 0x2250: return mmio_w2250(data);
|
||||||
|
case 0x2251: return mmio_w2251(data);
|
||||||
|
case 0x2252: return mmio_w2252(data);
|
||||||
|
case 0x2253: return mmio_w2253(data);
|
||||||
|
case 0x2254: return mmio_w2254(data);
|
||||||
|
|
||||||
|
case 0x2258: return mmio_w2258(data);
|
||||||
|
case 0x2259: return mmio_w2259(data);
|
||||||
|
case 0x225a: return mmio_w225a(data);
|
||||||
|
case 0x225b: return mmio_w225b(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
256
tools/bsnes/chip/sa1/mmio/mmio.hpp
Executable file
256
tools/bsnes/chip/sa1/mmio/mmio.hpp
Executable file
@@ -0,0 +1,256 @@
|
|||||||
|
uint8_t mmio_read(unsigned addr);
|
||||||
|
void mmio_write(unsigned addr, uint8_t data);
|
||||||
|
Memory& mmio_access(unsigned &addr);
|
||||||
|
|
||||||
|
struct MMIO {
|
||||||
|
//$2200 CCNT
|
||||||
|
bool sa1_irq;
|
||||||
|
bool sa1_rdyb;
|
||||||
|
bool sa1_resb;
|
||||||
|
bool sa1_nmi;
|
||||||
|
uint8_t smeg;
|
||||||
|
|
||||||
|
//$2201 SIE
|
||||||
|
bool cpu_irqen;
|
||||||
|
bool chdma_irqen;
|
||||||
|
|
||||||
|
//$2202 SIC
|
||||||
|
bool cpu_irqcl;
|
||||||
|
bool chdma_irqcl;
|
||||||
|
|
||||||
|
//$2203,$2204 CRV
|
||||||
|
uint16_t crv;
|
||||||
|
|
||||||
|
//$2205,$2206 CNV
|
||||||
|
uint16_t cnv;
|
||||||
|
|
||||||
|
//$2207,$2208 CIV
|
||||||
|
uint16_t civ;
|
||||||
|
|
||||||
|
//$2209 SCNT
|
||||||
|
bool cpu_irq;
|
||||||
|
bool cpu_ivsw;
|
||||||
|
bool cpu_nvsw;
|
||||||
|
uint8_t cmeg;
|
||||||
|
|
||||||
|
//$220a CIE
|
||||||
|
bool sa1_irqen;
|
||||||
|
bool timer_irqen;
|
||||||
|
bool dma_irqen;
|
||||||
|
bool sa1_nmien;
|
||||||
|
|
||||||
|
//$220b CIC
|
||||||
|
bool sa1_irqcl;
|
||||||
|
bool timer_irqcl;
|
||||||
|
bool dma_irqcl;
|
||||||
|
bool sa1_nmicl;
|
||||||
|
|
||||||
|
//$220c,$220d SNV
|
||||||
|
uint16_t snv;
|
||||||
|
|
||||||
|
//$220e,$220f SIV
|
||||||
|
uint16_t siv;
|
||||||
|
|
||||||
|
//$2210 TMC
|
||||||
|
bool hvselb;
|
||||||
|
bool ven;
|
||||||
|
bool hen;
|
||||||
|
|
||||||
|
//$2212,$2213
|
||||||
|
uint16_t hcnt;
|
||||||
|
|
||||||
|
//$2214,$2215
|
||||||
|
uint16_t vcnt;
|
||||||
|
|
||||||
|
//$2220 CXB
|
||||||
|
bool cbmode;
|
||||||
|
uint8_t cb;
|
||||||
|
|
||||||
|
//$2221 DXB
|
||||||
|
bool dbmode;
|
||||||
|
uint8_t db;
|
||||||
|
|
||||||
|
//$2222 EXB
|
||||||
|
bool ebmode;
|
||||||
|
uint8_t eb;
|
||||||
|
|
||||||
|
//$2223 FXB
|
||||||
|
bool fbmode;
|
||||||
|
uint8_t fb;
|
||||||
|
|
||||||
|
//$2224 BMAPS
|
||||||
|
uint8_t sbm;
|
||||||
|
|
||||||
|
//$2225 BMAP
|
||||||
|
bool sw46;
|
||||||
|
uint8_t cbm;
|
||||||
|
|
||||||
|
//$2226 SBWE
|
||||||
|
bool swen;
|
||||||
|
|
||||||
|
//$2227 CBWE
|
||||||
|
bool cwen;
|
||||||
|
|
||||||
|
//$2228 BWPA
|
||||||
|
uint8_t bwp;
|
||||||
|
|
||||||
|
//$2229 SIWP
|
||||||
|
uint8_t siwp;
|
||||||
|
|
||||||
|
//$222a CIWP
|
||||||
|
uint8_t ciwp;
|
||||||
|
|
||||||
|
//$2230 DCNT
|
||||||
|
bool dmaen;
|
||||||
|
bool dprio;
|
||||||
|
bool cden;
|
||||||
|
bool cdsel;
|
||||||
|
bool dd;
|
||||||
|
uint8_t sd;
|
||||||
|
|
||||||
|
//$2231 CDMA
|
||||||
|
bool chdend;
|
||||||
|
uint8_t dmasize;
|
||||||
|
uint8_t dmacb;
|
||||||
|
|
||||||
|
//$2232-$2234 SDA
|
||||||
|
uint32_t dsa;
|
||||||
|
|
||||||
|
//$2235-$2237 DDA
|
||||||
|
uint32_t dda;
|
||||||
|
|
||||||
|
//$2238,$2239 DTC
|
||||||
|
uint16_t dtc;
|
||||||
|
|
||||||
|
//$223f BBF
|
||||||
|
bool bbf;
|
||||||
|
|
||||||
|
//$2240-224f BRF
|
||||||
|
uint8_t brf[16];
|
||||||
|
|
||||||
|
//$2250 MCNT
|
||||||
|
bool acm;
|
||||||
|
bool md;
|
||||||
|
|
||||||
|
//$2251,$2252 MA
|
||||||
|
uint16_t ma;
|
||||||
|
|
||||||
|
//$2253,$2254 MB
|
||||||
|
uint16_t mb;
|
||||||
|
|
||||||
|
//$2258 VBD
|
||||||
|
bool hl;
|
||||||
|
uint8_t vb;
|
||||||
|
|
||||||
|
//$2259-$225b VDA
|
||||||
|
uint32_t va;
|
||||||
|
uint8_t vbit;
|
||||||
|
|
||||||
|
//$2300 SFR
|
||||||
|
bool cpu_irqfl;
|
||||||
|
bool chdma_irqfl;
|
||||||
|
|
||||||
|
//$2301 CFR
|
||||||
|
bool sa1_irqfl;
|
||||||
|
bool timer_irqfl;
|
||||||
|
bool dma_irqfl;
|
||||||
|
bool sa1_nmifl;
|
||||||
|
|
||||||
|
//$2302,$2303 HCR
|
||||||
|
uint16_t hcr;
|
||||||
|
|
||||||
|
//$2304,$2305 VCR
|
||||||
|
uint16_t vcr;
|
||||||
|
|
||||||
|
//$2306-230a MR
|
||||||
|
uint64_t mr;
|
||||||
|
|
||||||
|
//$230b OF
|
||||||
|
bool overflow;
|
||||||
|
} mmio;
|
||||||
|
|
||||||
|
void mmio_w2200(uint8_t); //CCNT
|
||||||
|
void mmio_w2201(uint8_t); //SIE
|
||||||
|
void mmio_w2202(uint8_t); //SIC
|
||||||
|
void mmio_w2203(uint8_t); //CRVL
|
||||||
|
void mmio_w2204(uint8_t); //CRVH
|
||||||
|
void mmio_w2205(uint8_t); //CNVL
|
||||||
|
void mmio_w2206(uint8_t); //CNVH
|
||||||
|
void mmio_w2207(uint8_t); //CIVL
|
||||||
|
void mmio_w2208(uint8_t); //CIVH
|
||||||
|
void mmio_w2209(uint8_t); //SCNT
|
||||||
|
void mmio_w220a(uint8_t); //CIE
|
||||||
|
void mmio_w220b(uint8_t); //CIC
|
||||||
|
void mmio_w220c(uint8_t); //SNVL
|
||||||
|
void mmio_w220d(uint8_t); //SNVH
|
||||||
|
void mmio_w220e(uint8_t); //SIVL
|
||||||
|
void mmio_w220f(uint8_t); //SIVH
|
||||||
|
void mmio_w2210(uint8_t); //TMC
|
||||||
|
void mmio_w2211(uint8_t); //CTR
|
||||||
|
void mmio_w2212(uint8_t); //HCNTL
|
||||||
|
void mmio_w2213(uint8_t); //HCNTH
|
||||||
|
void mmio_w2214(uint8_t); //VCNTL
|
||||||
|
void mmio_w2215(uint8_t); //VCNTH
|
||||||
|
void mmio_w2220(uint8_t); //CXB
|
||||||
|
void mmio_w2221(uint8_t); //DXB
|
||||||
|
void mmio_w2222(uint8_t); //EXB
|
||||||
|
void mmio_w2223(uint8_t); //FXB
|
||||||
|
void mmio_w2224(uint8_t); //BMAPS
|
||||||
|
void mmio_w2225(uint8_t); //BMAP
|
||||||
|
void mmio_w2226(uint8_t); //SBWE
|
||||||
|
void mmio_w2227(uint8_t); //CBWE
|
||||||
|
void mmio_w2228(uint8_t); //BWPA
|
||||||
|
void mmio_w2229(uint8_t); //SIWP
|
||||||
|
void mmio_w222a(uint8_t); //CIWP
|
||||||
|
void mmio_w2230(uint8_t); //DCNT
|
||||||
|
void mmio_w2231(uint8_t); //CDMA
|
||||||
|
void mmio_w2232(uint8_t); //SDAL
|
||||||
|
void mmio_w2233(uint8_t); //SDAH
|
||||||
|
void mmio_w2234(uint8_t); //SDAB
|
||||||
|
void mmio_w2235(uint8_t); //DDAL
|
||||||
|
void mmio_w2236(uint8_t); //DDAH
|
||||||
|
void mmio_w2237(uint8_t); //DDAB
|
||||||
|
void mmio_w2238(uint8_t); //DTCL
|
||||||
|
void mmio_w2239(uint8_t); //DTCH
|
||||||
|
void mmio_w223f(uint8_t); //BBF
|
||||||
|
void mmio_w2240(uint8_t); //BRF0
|
||||||
|
void mmio_w2241(uint8_t); //BRF1
|
||||||
|
void mmio_w2242(uint8_t); //BRF2
|
||||||
|
void mmio_w2243(uint8_t); //BRF3
|
||||||
|
void mmio_w2244(uint8_t); //BRF4
|
||||||
|
void mmio_w2245(uint8_t); //BRF5
|
||||||
|
void mmio_w2246(uint8_t); //BRF6
|
||||||
|
void mmio_w2247(uint8_t); //BRF7
|
||||||
|
void mmio_w2248(uint8_t); //BRF8
|
||||||
|
void mmio_w2249(uint8_t); //BRF9
|
||||||
|
void mmio_w224a(uint8_t); //BRFA
|
||||||
|
void mmio_w224b(uint8_t); //BRFB
|
||||||
|
void mmio_w224c(uint8_t); //BRFC
|
||||||
|
void mmio_w224d(uint8_t); //BRFD
|
||||||
|
void mmio_w224e(uint8_t); //BRFE
|
||||||
|
void mmio_w224f(uint8_t); //BRFF
|
||||||
|
void mmio_w2250(uint8_t); //MCNT
|
||||||
|
void mmio_w2251(uint8_t); //MAL
|
||||||
|
void mmio_w2252(uint8_t); //MAH
|
||||||
|
void mmio_w2253(uint8_t); //MBL
|
||||||
|
void mmio_w2254(uint8_t); //MBH
|
||||||
|
void mmio_w2258(uint8_t); //VBD
|
||||||
|
void mmio_w2259(uint8_t); //VDAL
|
||||||
|
void mmio_w225a(uint8_t); //VDAH
|
||||||
|
void mmio_w225b(uint8_t); //VDAB
|
||||||
|
|
||||||
|
uint8_t mmio_r2300(); //SFR
|
||||||
|
uint8_t mmio_r2301(); //CFR
|
||||||
|
uint8_t mmio_r2302(); //HCRL
|
||||||
|
uint8_t mmio_r2303(); //HCRH
|
||||||
|
uint8_t mmio_r2304(); //VCRL
|
||||||
|
uint8_t mmio_r2305(); //VCRH
|
||||||
|
uint8_t mmio_r2306(); //MR [00-07]
|
||||||
|
uint8_t mmio_r2307(); //MR [08-15]
|
||||||
|
uint8_t mmio_r2308(); //MR [16-23]
|
||||||
|
uint8_t mmio_r2309(); //MR [24-31]
|
||||||
|
uint8_t mmio_r230a(); //MR [32-40]
|
||||||
|
uint8_t mmio_r230b(); //OF
|
||||||
|
uint8_t mmio_r230c(); //VDPL
|
||||||
|
uint8_t mmio_r230d(); //VDPH
|
||||||
|
uint8_t mmio_r230e(); //VC
|
||||||
318
tools/bsnes/chip/sa1/sa1.cpp
Executable file
318
tools/bsnes/chip/sa1/sa1.cpp
Executable file
@@ -0,0 +1,318 @@
|
|||||||
|
#include <../base.hpp>
|
||||||
|
|
||||||
|
#define SA1_CPP
|
||||||
|
namespace SNES {
|
||||||
|
|
||||||
|
SA1 sa1;
|
||||||
|
|
||||||
|
#include "bus/bus.cpp"
|
||||||
|
#include "dma/dma.cpp"
|
||||||
|
#include "memory/memory.cpp"
|
||||||
|
#include "mmio/mmio.cpp"
|
||||||
|
|
||||||
|
void SA1::enter() {
|
||||||
|
while(true) {
|
||||||
|
while(mmio.sa1_rdyb || mmio.sa1_resb) {
|
||||||
|
//SA-1 co-processor is asleep
|
||||||
|
tick();
|
||||||
|
scheduler.sync_copcpu();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(status.interrupt_pending) {
|
||||||
|
status.interrupt_pending = false;
|
||||||
|
interrupt(status.interrupt_vector);
|
||||||
|
}
|
||||||
|
|
||||||
|
(this->*opcode_table[op_readpc()])();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SA1::last_cycle() {
|
||||||
|
if(mmio.sa1_nmi && !mmio.sa1_nmicl) {
|
||||||
|
status.interrupt_pending = true;
|
||||||
|
status.interrupt_vector = mmio.cnv;
|
||||||
|
mmio.sa1_nmifl = true;
|
||||||
|
mmio.sa1_nmicl = 1;
|
||||||
|
regs.wai = false;
|
||||||
|
} else if(!regs.p.i) {
|
||||||
|
if(mmio.timer_irqen && !mmio.timer_irqcl) {
|
||||||
|
status.interrupt_pending = true;
|
||||||
|
status.interrupt_vector = mmio.civ;
|
||||||
|
mmio.timer_irqfl = true;
|
||||||
|
regs.wai = false;
|
||||||
|
} else if(mmio.dma_irqen && !mmio.dma_irqcl) {
|
||||||
|
status.interrupt_pending = true;
|
||||||
|
status.interrupt_vector = mmio.civ;
|
||||||
|
mmio.dma_irqfl = true;
|
||||||
|
regs.wai = false;
|
||||||
|
} else if(mmio.sa1_irq && !mmio.sa1_irqcl) {
|
||||||
|
status.interrupt_pending = true;
|
||||||
|
status.interrupt_vector = mmio.civ;
|
||||||
|
mmio.sa1_irqfl = true;
|
||||||
|
regs.wai = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SA1::interrupt(uint16_t vector) {
|
||||||
|
op_read(regs.pc.d);
|
||||||
|
op_io();
|
||||||
|
if(!regs.e) op_writestack(regs.pc.b);
|
||||||
|
op_writestack(regs.pc.h);
|
||||||
|
op_writestack(regs.pc.l);
|
||||||
|
op_writestack(regs.e ? (regs.p & ~0x10) : regs.p);
|
||||||
|
regs.pc.w = vector;
|
||||||
|
regs.pc.b = 0x00;
|
||||||
|
regs.p.i = 1;
|
||||||
|
regs.p.d = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SA1::interrupt_pending() {
|
||||||
|
return status.interrupt_pending;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SA1::tick() {
|
||||||
|
scheduler.addclocks_cop(2);
|
||||||
|
|
||||||
|
//adjust counters:
|
||||||
|
//note that internally, status counters are in clocks;
|
||||||
|
//whereas MMIO register counters are in dots (4 clocks = 1 dot)
|
||||||
|
if(mmio.hvselb == 0) {
|
||||||
|
//HV timer
|
||||||
|
status.hcounter += 2;
|
||||||
|
if(status.hcounter >= 1364) {
|
||||||
|
status.hcounter = 0;
|
||||||
|
if(++status.vcounter >= status.scanlines) status.vcounter = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//linear timer
|
||||||
|
status.hcounter += 2;
|
||||||
|
status.vcounter += (status.hcounter >> 11);
|
||||||
|
status.hcounter &= 0x07ff;
|
||||||
|
status.vcounter &= 0x01ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
//test counters for timer IRQ
|
||||||
|
switch((mmio.ven << 1) + (mmio.hen << 0)) {
|
||||||
|
case 0: break;
|
||||||
|
case 1: if(status.hcounter == (mmio.hcnt << 2)) trigger_irq(); break;
|
||||||
|
case 2: if(status.vcounter == mmio.vcnt && status.hcounter == 0) trigger_irq(); break;
|
||||||
|
case 3: if(status.vcounter == mmio.hcnt && status.hcounter == (mmio.hcnt << 2)) trigger_irq(); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SA1::trigger_irq() {
|
||||||
|
mmio.timer_irqfl = true;
|
||||||
|
if(mmio.timer_irqen) mmio.timer_irqcl = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SA1::init() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void SA1::enable() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void SA1::power() {
|
||||||
|
regs.a = regs.x = regs.y = 0x0000;
|
||||||
|
regs.s = 0x01ff;
|
||||||
|
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SA1::reset() {
|
||||||
|
memory::vectorsp.access = 0;
|
||||||
|
memory::cc1bwram.dma = false;
|
||||||
|
for(unsigned addr = 0; addr < memory::iram.size(); addr++) {
|
||||||
|
memory::iram.write(addr, 0x00);
|
||||||
|
}
|
||||||
|
sa1bus.init();
|
||||||
|
|
||||||
|
regs.pc.d = 0x000000;
|
||||||
|
regs.x.h = 0x00;
|
||||||
|
regs.y.h = 0x00;
|
||||||
|
regs.s.h = 0x01;
|
||||||
|
regs.d = 0x0000;
|
||||||
|
regs.db = 0x00;
|
||||||
|
regs.p = 0x34;
|
||||||
|
regs.e = 1;
|
||||||
|
regs.mdr = 0x00;
|
||||||
|
regs.wai = false;
|
||||||
|
update_table();
|
||||||
|
|
||||||
|
status.interrupt_pending = false;
|
||||||
|
status.interrupt_vector = 0x0000;
|
||||||
|
|
||||||
|
status.scanlines = (system.region() == System::NTSC ? 262 : 312);
|
||||||
|
status.vcounter = 0;
|
||||||
|
status.hcounter = 0;
|
||||||
|
|
||||||
|
dma.line = 0;
|
||||||
|
|
||||||
|
//$2200 CCNT
|
||||||
|
mmio.sa1_irq = false;
|
||||||
|
mmio.sa1_rdyb = false;
|
||||||
|
mmio.sa1_resb = true;
|
||||||
|
mmio.sa1_nmi = false;
|
||||||
|
mmio.smeg = 0;
|
||||||
|
|
||||||
|
//$2201 SIE
|
||||||
|
mmio.cpu_irqen = false;
|
||||||
|
mmio.chdma_irqen = false;
|
||||||
|
|
||||||
|
//$2202 SIC
|
||||||
|
mmio.cpu_irqcl = false;
|
||||||
|
mmio.chdma_irqcl = false;
|
||||||
|
|
||||||
|
//$2203,$2204 CRV
|
||||||
|
mmio.crv = 0x0000;
|
||||||
|
|
||||||
|
//$2205,$2206 CNV
|
||||||
|
mmio.cnv = 0x0000;
|
||||||
|
|
||||||
|
//$2207,$2208 CIV
|
||||||
|
mmio.civ = 0x0000;
|
||||||
|
|
||||||
|
//$2209 SCNT
|
||||||
|
mmio.cpu_irq = false;
|
||||||
|
mmio.cpu_ivsw = false;
|
||||||
|
mmio.cpu_nvsw = false;
|
||||||
|
mmio.cmeg = 0;
|
||||||
|
|
||||||
|
//$220a CIE
|
||||||
|
mmio.sa1_irqen = false;
|
||||||
|
mmio.timer_irqen = false;
|
||||||
|
mmio.dma_irqen = false;
|
||||||
|
mmio.sa1_nmien = false;
|
||||||
|
|
||||||
|
//$220b CIC
|
||||||
|
mmio.sa1_irqcl = false;
|
||||||
|
mmio.timer_irqcl = false;
|
||||||
|
mmio.dma_irqcl = false;
|
||||||
|
mmio.sa1_nmicl = false;
|
||||||
|
|
||||||
|
//$220c,$220d SNV
|
||||||
|
mmio.snv = 0x0000;
|
||||||
|
|
||||||
|
//$220e,$220f SIV
|
||||||
|
mmio.siv = 0x0000;
|
||||||
|
|
||||||
|
//$2210
|
||||||
|
mmio.hvselb = false;
|
||||||
|
mmio.ven = false;
|
||||||
|
mmio.hen = false;
|
||||||
|
|
||||||
|
//$2212,$2213 HCNT
|
||||||
|
mmio.hcnt = 0x0000;
|
||||||
|
|
||||||
|
//$2214,$2215 VCNT
|
||||||
|
mmio.vcnt = 0x0000;
|
||||||
|
|
||||||
|
//$2220-2223 CXB, DXB, EXB, FXB
|
||||||
|
mmio.cbmode = 0;
|
||||||
|
mmio.dbmode = 0;
|
||||||
|
mmio.ebmode = 0;
|
||||||
|
mmio.fbmode = 0;
|
||||||
|
|
||||||
|
mmio.cb = 0x00;
|
||||||
|
mmio.db = 0x01;
|
||||||
|
mmio.eb = 0x02;
|
||||||
|
mmio.fb = 0x03;
|
||||||
|
|
||||||
|
//$2224 BMAPS
|
||||||
|
mmio.sbm = 0x00;
|
||||||
|
|
||||||
|
//$2225 BMAP
|
||||||
|
mmio.sw46 = false;
|
||||||
|
mmio.cbm = 0x00;
|
||||||
|
|
||||||
|
//$2226 SWBE
|
||||||
|
mmio.swen = false;
|
||||||
|
|
||||||
|
//$2227 CWBE
|
||||||
|
mmio.cwen = false;
|
||||||
|
|
||||||
|
//$2228 BWPA
|
||||||
|
mmio.bwp = 0x0f;
|
||||||
|
|
||||||
|
//$2229 SIWP
|
||||||
|
mmio.siwp = 0x00;
|
||||||
|
|
||||||
|
//$222a CIWP
|
||||||
|
mmio.ciwp = 0x00;
|
||||||
|
|
||||||
|
//$2230 DCNT
|
||||||
|
mmio.dmaen = false;
|
||||||
|
mmio.dprio = false;
|
||||||
|
mmio.cden = false;
|
||||||
|
mmio.cdsel = false;
|
||||||
|
mmio.dd = 0;
|
||||||
|
mmio.sd = 0;
|
||||||
|
|
||||||
|
//$2231 CDMA
|
||||||
|
mmio.chdend = false;
|
||||||
|
mmio.dmasize = 0;
|
||||||
|
mmio.dmacb = 0;
|
||||||
|
|
||||||
|
//$2232-$2234 SDA
|
||||||
|
mmio.dsa = 0x000000;
|
||||||
|
|
||||||
|
//$2235-$2237 DDA
|
||||||
|
mmio.dda = 0x000000;
|
||||||
|
|
||||||
|
//$2238,$2239 DTC
|
||||||
|
mmio.dtc = 0x0000;
|
||||||
|
|
||||||
|
//$223f BBF
|
||||||
|
mmio.bbf = 0;
|
||||||
|
|
||||||
|
//$2240-$224f BRF
|
||||||
|
for(unsigned i = 0; i < 16; i++) {
|
||||||
|
mmio.brf[i] = 0x00;
|
||||||
|
}
|
||||||
|
|
||||||
|
//$2250 MCNT
|
||||||
|
mmio.acm = 0;
|
||||||
|
mmio.md = 0;
|
||||||
|
|
||||||
|
//$2251,$2252 MA
|
||||||
|
mmio.ma = 0x0000;
|
||||||
|
|
||||||
|
//$2253,$2254 MB
|
||||||
|
mmio.mb = 0x0000;
|
||||||
|
|
||||||
|
//$2258 VBD
|
||||||
|
mmio.hl = false;
|
||||||
|
mmio.vb = 16;
|
||||||
|
|
||||||
|
//$2259-$225b
|
||||||
|
mmio.va = 0x000000;
|
||||||
|
mmio.vbit = 0;
|
||||||
|
|
||||||
|
//$2300 SFR
|
||||||
|
mmio.cpu_irqfl = false;
|
||||||
|
mmio.chdma_irqfl = false;
|
||||||
|
|
||||||
|
//$2301 CFR
|
||||||
|
mmio.sa1_irqfl = false;
|
||||||
|
mmio.timer_irqfl = false;
|
||||||
|
mmio.dma_irqfl = false;
|
||||||
|
mmio.sa1_nmifl = false;
|
||||||
|
|
||||||
|
//$2302,$2303 HCR
|
||||||
|
mmio.hcr = 0x0000;
|
||||||
|
|
||||||
|
//$2304,$2305 VCR
|
||||||
|
mmio.vcr = 0x0000;
|
||||||
|
|
||||||
|
//$2306-$230a MR
|
||||||
|
mmio.mr = 0;
|
||||||
|
|
||||||
|
//$230b
|
||||||
|
mmio.overflow = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SA1::SA1() {
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
35
tools/bsnes/chip/sa1/sa1.hpp
Executable file
35
tools/bsnes/chip/sa1/sa1.hpp
Executable file
@@ -0,0 +1,35 @@
|
|||||||
|
#include "bus/bus.hpp"
|
||||||
|
|
||||||
|
class SA1 : public CPUcore, public MMIO {
|
||||||
|
public:
|
||||||
|
#include "dma/dma.hpp"
|
||||||
|
#include "memory/memory.hpp"
|
||||||
|
#include "mmio/mmio.hpp"
|
||||||
|
|
||||||
|
struct Status {
|
||||||
|
bool interrupt_pending;
|
||||||
|
uint16_t interrupt_vector;
|
||||||
|
|
||||||
|
uint16_t scanlines;
|
||||||
|
uint16_t vcounter;
|
||||||
|
uint16_t hcounter;
|
||||||
|
} status;
|
||||||
|
|
||||||
|
void enter();
|
||||||
|
void interrupt(uint16_t vector);
|
||||||
|
void tick();
|
||||||
|
|
||||||
|
alwaysinline void trigger_irq();
|
||||||
|
alwaysinline void last_cycle();
|
||||||
|
alwaysinline bool interrupt_pending();
|
||||||
|
|
||||||
|
void init();
|
||||||
|
void enable();
|
||||||
|
void power();
|
||||||
|
void reset();
|
||||||
|
|
||||||
|
SA1();
|
||||||
|
};
|
||||||
|
|
||||||
|
extern SA1 sa1;
|
||||||
|
extern SA1Bus sa1bus;
|
||||||
@@ -1,8 +1,10 @@
|
|||||||
#include <../base.hpp>
|
#include <../base.hpp>
|
||||||
#include <../cart/cart.hpp>
|
|
||||||
#define SDD1_CPP
|
#define SDD1_CPP
|
||||||
|
namespace SNES {
|
||||||
|
|
||||||
|
SDD1 sdd1;
|
||||||
|
|
||||||
#include "sdd1.hpp"
|
|
||||||
#include "sdd1emu.cpp"
|
#include "sdd1emu.cpp"
|
||||||
|
|
||||||
void SDD1::init() {}
|
void SDD1::init() {}
|
||||||
@@ -11,7 +13,7 @@ void SDD1::enable() {
|
|||||||
//hook S-CPU DMA MMIO registers to gather information for struct dma[];
|
//hook S-CPU DMA MMIO registers to gather information for struct dma[];
|
||||||
//buffer address and transfer size information for use in SDD1::read()
|
//buffer address and transfer size information for use in SDD1::read()
|
||||||
for(unsigned i = 0x4300; i <= 0x437f; i++) {
|
for(unsigned i = 0x4300; i <= 0x437f; i++) {
|
||||||
cpu_mmio[i & 0x7f] = memory::mmio.get(i);
|
cpu_mmio[i & 0x7f] = memory::mmio.mmio[i - 0x2000];
|
||||||
memory::mmio.map(i, *this);
|
memory::mmio.map(i, *this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,3 +158,5 @@ SDD1::SDD1() {
|
|||||||
SDD1::~SDD1() {
|
SDD1::~SDD1() {
|
||||||
delete[] buffer.data;
|
delete[] buffer.data;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|||||||
66
tools/bsnes/chip/sgb/sgb.cpp
Executable file
66
tools/bsnes/chip/sgb/sgb.cpp
Executable file
@@ -0,0 +1,66 @@
|
|||||||
|
#include <../base.hpp>
|
||||||
|
|
||||||
|
#define SGB_CPP
|
||||||
|
namespace SNES {
|
||||||
|
|
||||||
|
SuperGameBoy sgb;
|
||||||
|
|
||||||
|
void SuperGameBoy::enter() {
|
||||||
|
while(true) {
|
||||||
|
if(sgb_run) {
|
||||||
|
unsigned samples = sgb_run(samplebuffer, 16);
|
||||||
|
scheduler.addclocks_cop(samples * 10);
|
||||||
|
scheduler.sync_copcpu();
|
||||||
|
} else {
|
||||||
|
scheduler.addclocks_cop(64 * 1024 * 1024);
|
||||||
|
scheduler.sync_copcpu();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t SuperGameBoy::read(unsigned addr) {
|
||||||
|
addr &= 0xffff;
|
||||||
|
if(sgb_read) return sgb_read(addr);
|
||||||
|
return 0x00;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SuperGameBoy::write(unsigned addr, uint8_t data) {
|
||||||
|
addr &= 0xffff;
|
||||||
|
if(sgb_write) return sgb_write(addr, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SuperGameBoy::init() {
|
||||||
|
if(libsgb.open("SuperGameBoy")) {
|
||||||
|
sgb_init = libsgb.sym("sgb_init");
|
||||||
|
sgb_term = libsgb.sym("sgb_term");
|
||||||
|
sgb_power = libsgb.sym("sgb_power");
|
||||||
|
sgb_reset = libsgb.sym("sgb_reset");
|
||||||
|
sgb_read = libsgb.sym("sgb_read");
|
||||||
|
sgb_write = libsgb.sym("sgb_write");
|
||||||
|
sgb_run = libsgb.sym("sgb_run");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SuperGameBoy::enable() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void SuperGameBoy::power() {
|
||||||
|
bus.map(Bus::MapDirect, 0x00, 0x3f, 0x6000, 0x7fff, *this);
|
||||||
|
bus.map(Bus::MapDirect, 0x80, 0xbf, 0x6000, 0x7fff, *this);
|
||||||
|
|
||||||
|
if(sgb_init) {
|
||||||
|
sgb_init(SGB2,
|
||||||
|
memory::gbrom.data(), memory::gbrom.size(),
|
||||||
|
memory::gbram.data(), memory::gbram.size()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(sgb_power) sgb_power();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SuperGameBoy::reset() {
|
||||||
|
if(sgb_reset) sgb_reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
28
tools/bsnes/chip/sgb/sgb.hpp
Executable file
28
tools/bsnes/chip/sgb/sgb.hpp
Executable file
@@ -0,0 +1,28 @@
|
|||||||
|
class SuperGameBoy : public Memory {
|
||||||
|
public:
|
||||||
|
void enter();
|
||||||
|
|
||||||
|
uint8_t read(unsigned addr);
|
||||||
|
void write(unsigned addr, uint8_t data);
|
||||||
|
|
||||||
|
void init();
|
||||||
|
void enable();
|
||||||
|
void power();
|
||||||
|
void reset();
|
||||||
|
|
||||||
|
private:
|
||||||
|
library libsgb;
|
||||||
|
uint32_t samplebuffer[4096];
|
||||||
|
|
||||||
|
enum { SGB1 = 0, SGB2 = 1 };
|
||||||
|
function<bool (bool, uint8_t*, unsigned, uint8_t*, unsigned)> sgb_init;
|
||||||
|
function<void ()> sgb_term;
|
||||||
|
function<void ()> sgb_power;
|
||||||
|
function<void ()> sgb_reset;
|
||||||
|
function<uint8_t (unsigned)> sgb_read;
|
||||||
|
function<void (unsigned, uint8_t)> sgb_write;
|
||||||
|
function<unsigned (uint32_t*, unsigned)> sgb_run;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern SuperGameBoy sgb;
|
||||||
|
|
||||||
@@ -1,8 +1,10 @@
|
|||||||
#include <../base.hpp>
|
#include <../base.hpp>
|
||||||
#include <../cart/cart.hpp>
|
|
||||||
#define SPC7110_CPP
|
|
||||||
|
|
||||||
#include "spc7110.hpp"
|
#define SPC7110_CPP
|
||||||
|
namespace SNES {
|
||||||
|
|
||||||
|
SPC7110 spc7110;
|
||||||
|
|
||||||
#include "decomp.cpp"
|
#include "decomp.cpp"
|
||||||
|
|
||||||
const unsigned SPC7110::months[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
const unsigned SPC7110::months[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
||||||
@@ -670,3 +672,6 @@ void SPC7110::write(unsigned addr, uint8 data) {
|
|||||||
|
|
||||||
SPC7110::SPC7110() {
|
SPC7110::SPC7110() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
#include <../base.hpp>
|
#include <../base.hpp>
|
||||||
#include <../cart/cart.hpp>
|
|
||||||
#include "srtc.hpp"
|
#define SRTC_CPP
|
||||||
|
namespace SNES {
|
||||||
|
|
||||||
|
SRTC srtc;
|
||||||
|
|
||||||
const unsigned SRTC::months[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
const unsigned SRTC::months[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
||||||
|
|
||||||
@@ -224,3 +227,6 @@ void SRTC::mmio_write(unsigned addr, uint8 data) {
|
|||||||
|
|
||||||
SRTC::SRTC() {
|
SRTC::SRTC() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
#include <../base.hpp>
|
#include <../base.hpp>
|
||||||
|
|
||||||
#define ST010_CPP
|
#define ST010_CPP
|
||||||
|
namespace SNES {
|
||||||
|
|
||||||
|
ST010 st010;
|
||||||
|
|
||||||
#include "st010.hpp"
|
|
||||||
#include "st010_data.hpp"
|
#include "st010_data.hpp"
|
||||||
#include "st010_op.cpp"
|
#include "st010_op.cpp"
|
||||||
|
|
||||||
@@ -85,3 +88,5 @@ void ST010::write(unsigned addr, uint8 data) {
|
|||||||
ram[0x0021] &= ~0x80;
|
ram[0x0021] &= ~0x80;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
@mingw32-make platform=win compiler=mingw32-gcc clean
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
make platform=x compiler=gcc clean
|
|
||||||
3
tools/bsnes/cpu/core/bpp.sh
Executable file
3
tools/bsnes/cpu/core/bpp.sh
Executable file
@@ -0,0 +1,3 @@
|
|||||||
|
clear
|
||||||
|
bpp opcode_functions.cpp opcode_functions.bpp
|
||||||
|
bpp opcode_headers.hpp opcode_headers.bpp
|
||||||
51
tools/bsnes/cpu/core/core.cpp
Executable file
51
tools/bsnes/cpu/core/core.cpp
Executable file
@@ -0,0 +1,51 @@
|
|||||||
|
#include <../base.hpp>
|
||||||
|
|
||||||
|
#define CPUCORE_CPP
|
||||||
|
namespace SNES {
|
||||||
|
|
||||||
|
#include "opcode_algorithms.cpp"
|
||||||
|
#include "opcode_functions.cpp"
|
||||||
|
#include "opcode_tables.cpp"
|
||||||
|
#include "disasm/disasm.cpp"
|
||||||
|
|
||||||
|
//immediate, 2-cycle opcodes with I/O cycle will become bus read
|
||||||
|
//when an IRQ is to be triggered immediately after opcode completion.
|
||||||
|
//this affects the following opcodes:
|
||||||
|
// clc, cld, cli, clv, sec, sed, sei,
|
||||||
|
// tax, tay, txa, txy, tya, tyx,
|
||||||
|
// tcd, tcs, tdc, tsc, tsx, txs,
|
||||||
|
// inc, inx, iny, dec, dex, dey,
|
||||||
|
// asl, lsr, rol, ror, nop, xce.
|
||||||
|
alwaysinline void CPUcore::op_io_irq() {
|
||||||
|
if(interrupt_pending()) {
|
||||||
|
//modify I/O cycle to bus read cycle, do not increment PC
|
||||||
|
op_read(regs.pc.d);
|
||||||
|
} else {
|
||||||
|
op_io();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
alwaysinline void CPUcore::op_io_cond2() {
|
||||||
|
if(regs.d.l != 0x00) {
|
||||||
|
op_io();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
alwaysinline void CPUcore::op_io_cond4(uint16 x, uint16 y) {
|
||||||
|
if(!regs.p.x || (x & 0xff00) != (y & 0xff00)) {
|
||||||
|
op_io();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
alwaysinline void CPUcore::op_io_cond6(uint16 addr) {
|
||||||
|
if(regs.e && (regs.pc.w & 0xff00) != (addr & 0xff00)) {
|
||||||
|
op_io();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CPUcore::CPUcore() {
|
||||||
|
initialize_opcode_table();
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
@@ -1,54 +1,79 @@
|
|||||||
reg24_t aa, rd;
|
class CPUcore {
|
||||||
uint8_t dp, sp;
|
public:
|
||||||
|
#include "registers.hpp"
|
||||||
void op_irq();
|
#include "memory.hpp"
|
||||||
|
#include "opcode_headers.hpp"
|
||||||
inline bool in_opcode() { return status.in_opcode; }
|
#include "disasm/disasm.hpp"
|
||||||
|
|
||||||
//op_read
|
|
||||||
void op_adc_b();
|
|
||||||
void op_adc_w();
|
|
||||||
void op_and_b();
|
|
||||||
void op_and_w();
|
|
||||||
void op_bit_b();
|
|
||||||
void op_bit_w();
|
|
||||||
void op_cmp_b();
|
|
||||||
void op_cmp_w();
|
|
||||||
void op_cpx_b();
|
|
||||||
void op_cpx_w();
|
|
||||||
void op_cpy_b();
|
|
||||||
void op_cpy_w();
|
|
||||||
void op_eor_b();
|
|
||||||
void op_eor_w();
|
|
||||||
void op_lda_b();
|
|
||||||
void op_lda_w();
|
|
||||||
void op_ldx_b();
|
|
||||||
void op_ldx_w();
|
|
||||||
void op_ldy_b();
|
|
||||||
void op_ldy_w();
|
|
||||||
void op_ora_b();
|
|
||||||
void op_ora_w();
|
|
||||||
void op_sbc_b();
|
|
||||||
void op_sbc_w();
|
|
||||||
//op_rmw
|
|
||||||
void op_inc_b();
|
|
||||||
void op_inc_w();
|
|
||||||
void op_dec_b();
|
|
||||||
void op_dec_w();
|
|
||||||
void op_asl_b();
|
|
||||||
void op_asl_w();
|
|
||||||
void op_lsr_b();
|
|
||||||
void op_lsr_w();
|
|
||||||
void op_rol_b();
|
|
||||||
void op_rol_w();
|
|
||||||
void op_ror_b();
|
|
||||||
void op_ror_w();
|
|
||||||
void op_trb_b();
|
|
||||||
void op_trb_w();
|
|
||||||
void op_tsb_b();
|
|
||||||
void op_tsb_w();
|
|
||||||
|
|
||||||
void op_io_irq();
|
regs_t regs;
|
||||||
void op_io_cond2();
|
reg24_t aa, rd;
|
||||||
void op_io_cond4(uint16 x, uint16 y);
|
uint8_t sp, dp;
|
||||||
void op_io_cond6(uint16 addr);
|
|
||||||
|
virtual void op_io() = 0;
|
||||||
|
virtual uint8_t op_read(uint32_t addr) = 0;
|
||||||
|
virtual void op_write(uint32_t addr, uint8_t data) = 0;
|
||||||
|
virtual void last_cycle() = 0;
|
||||||
|
virtual bool interrupt_pending() = 0;
|
||||||
|
|
||||||
|
void op_io_irq();
|
||||||
|
void op_io_cond2();
|
||||||
|
void op_io_cond4(uint16 x, uint16 y);
|
||||||
|
void op_io_cond6(uint16 addr);
|
||||||
|
|
||||||
|
void op_adc_b();
|
||||||
|
void op_adc_w();
|
||||||
|
void op_and_b();
|
||||||
|
void op_and_w();
|
||||||
|
void op_bit_b();
|
||||||
|
void op_bit_w();
|
||||||
|
void op_cmp_b();
|
||||||
|
void op_cmp_w();
|
||||||
|
void op_cpx_b();
|
||||||
|
void op_cpx_w();
|
||||||
|
void op_cpy_b();
|
||||||
|
void op_cpy_w();
|
||||||
|
void op_eor_b();
|
||||||
|
void op_eor_w();
|
||||||
|
void op_lda_b();
|
||||||
|
void op_lda_w();
|
||||||
|
void op_ldx_b();
|
||||||
|
void op_ldx_w();
|
||||||
|
void op_ldy_b();
|
||||||
|
void op_ldy_w();
|
||||||
|
void op_ora_b();
|
||||||
|
void op_ora_w();
|
||||||
|
void op_sbc_b();
|
||||||
|
void op_sbc_w();
|
||||||
|
|
||||||
|
void op_inc_b();
|
||||||
|
void op_inc_w();
|
||||||
|
void op_dec_b();
|
||||||
|
void op_dec_w();
|
||||||
|
void op_asl_b();
|
||||||
|
void op_asl_w();
|
||||||
|
void op_lsr_b();
|
||||||
|
void op_lsr_w();
|
||||||
|
void op_rol_b();
|
||||||
|
void op_rol_w();
|
||||||
|
void op_ror_b();
|
||||||
|
void op_ror_w();
|
||||||
|
void op_trb_b();
|
||||||
|
void op_trb_w();
|
||||||
|
void op_tsb_b();
|
||||||
|
void op_tsb_w();
|
||||||
|
|
||||||
|
void (CPUcore::**opcode_table)();
|
||||||
|
void (CPUcore::*op_table[256 * 5])();
|
||||||
|
void initialize_opcode_table();
|
||||||
|
void update_table();
|
||||||
|
|
||||||
|
enum {
|
||||||
|
table_EM = 0, // 8-bit accumulator, 8-bit index (emulation mode)
|
||||||
|
table_MX = 256, // 8-bit accumulator, 8-bit index
|
||||||
|
table_Mx = 512, // 8-bit accumulator, 16-bit index
|
||||||
|
table_mX = 768, //16-bit accumulator, 8-bit index
|
||||||
|
table_mx = 1024, //16-bit accumulator, 16-bit index
|
||||||
|
};
|
||||||
|
|
||||||
|
CPUcore();
|
||||||
|
};
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user