Basic cartridge detection working. NES detected with CIRAM /CE and PPU /A13N jumper. Famicom detected with audio in/out connection. SNES detected by enabling control signals and reading reset vector looking for non 0xff data. Still need to add check that would pass with blank flash cart though reading flash ID's perhaps.
Removing bad logic where TRUE == 0x00 as that's 'false' in C so that was causing more confusions than solutions.
This commit is contained in:
parent
132360f305
commit
497e53378b
|
|
@ -81,7 +81,7 @@ uint8_t * buffer_usb_call( setup_packet *spacket, uint8_t *rv, uint8_t *rlen)
|
|||
|
||||
case BUFF_PAYLOADN_MIN ... BUFF_PAYLOADN_MAX:
|
||||
//designate what buffer to fill with miscdata byte
|
||||
rptr = buffer_payload( spacket, called_buff, TRUE, rlen);
|
||||
rptr = buffer_payload( spacket, called_buff, ~FALSE, rlen);
|
||||
//TODO
|
||||
break;
|
||||
|
||||
|
|
@ -94,7 +94,7 @@ uint8_t * buffer_usb_call( setup_packet *spacket, uint8_t *rv, uint8_t *rlen)
|
|||
|
||||
case BUFF_PAYLOAD_MIN ... BUFF_PAYLOAD_MAX:
|
||||
//let buffer.c decide what buffer to fill
|
||||
rptr = buffer_payload( spacket, called_buff, ~TRUE, rlen);
|
||||
rptr = buffer_payload( spacket, called_buff, FALSE, rlen);
|
||||
//TODO
|
||||
break;
|
||||
|
||||
|
|
@ -138,7 +138,7 @@ uint8_t * buffer_usb_call( setup_packet *spacket, uint8_t *rv, uint8_t *rlen)
|
|||
*rlen = (spacket->wLength);
|
||||
break;
|
||||
case BUFF_PAYLOAD0 ... BUFF_PAYLOAD7:
|
||||
rptr = buffer_payload( spacket, called_buff, TRUE, rlen);
|
||||
rptr = buffer_payload( spacket, called_buff, ~FALSE, rlen);
|
||||
break;
|
||||
default:
|
||||
rv[RV_ERR_IDX] = ERR_BAD_BUFF_OP_MINMAX;
|
||||
|
|
@ -296,7 +296,7 @@ uint8_t * buffer_payload( setup_packet *spacket, buffer *buff, uint8_t hostsetbu
|
|||
|
||||
//buffer in use depends on opcode which was decoded prior to calling into hostsetbuff
|
||||
//if buffer number not designated by host buffer.c gets to decide
|
||||
if ( hostsetbuff != TRUE ) {
|
||||
if ( hostsetbuff != ~FALSE ) {
|
||||
//buffer.c gets to decide buffer in use
|
||||
//TODO implement some fancy double buffering code
|
||||
//for now just designate buffer 0
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@
|
|||
#define IP 0x00
|
||||
#define OP 0xFF
|
||||
|
||||
#define TRUE 0x00
|
||||
//false is anything besides TRUE
|
||||
#define FALSE 0x00
|
||||
//TRUE is any value besides zero
|
||||
|
||||
//used to indicate when intentionally passing zero because option not used
|
||||
#define NILL 0x00
|
||||
|
|
|
|||
|
|
@ -21,13 +21,13 @@ uint8_t snes_opcode_24b_operand( uint8_t opcode, uint8_t addrH, uint8_t addrL, u
|
|||
{
|
||||
switch (opcode) {
|
||||
case SNES_A15_A0_PRGM_WR:
|
||||
snes_a15_a0_wr( PRGM, TRUE, addrH, addrL, data );
|
||||
snes_a15_a0_wr( PRGM, ~FALSE, addrH, addrL, data );
|
||||
break;
|
||||
case SNES_A15_A0_PLAY_WR:
|
||||
snes_a15_a0_wr( PLAY, TRUE, addrH, addrL, data );
|
||||
snes_a15_a0_wr( PLAY, ~FALSE, addrH, addrL, data );
|
||||
break;
|
||||
case SNES_A15_A0_NO_ROMSEL_PLAY_WR:
|
||||
snes_a15_a0_wr( PLAY, ~TRUE, addrH, addrL, data );
|
||||
snes_a15_a0_wr( PLAY, FALSE, addrH, addrL, data );
|
||||
break;
|
||||
default:
|
||||
//macro doesn't exist
|
||||
|
|
@ -52,13 +52,13 @@ uint8_t snes_opcode_24b_operand_8b_return(
|
|||
{
|
||||
switch (opcode) {
|
||||
case SNES_PRGM_RD:
|
||||
*data = snes_a15_a0_rd( PRGM, TRUE, addrX, addrH, addrL );
|
||||
*data = snes_a15_a0_rd( PRGM, ~FALSE, addrX, addrH, addrL );
|
||||
break;
|
||||
case SNES_PLAY_RD:
|
||||
*data = snes_a15_a0_rd( PLAY, TRUE, addrX, addrH, addrL );
|
||||
*data = snes_a15_a0_rd( PLAY, ~FALSE, addrX, addrH, addrL );
|
||||
break;
|
||||
case SNES_NO_ROMSEL_PLAY_RD:
|
||||
*data = snes_a15_a0_rd( PLAY, ~TRUE, addrX, addrH, addrL );
|
||||
*data = snes_a15_a0_rd( PLAY, FALSE, addrX, addrH, addrL );
|
||||
break;
|
||||
default:
|
||||
//macro doesn't exist
|
||||
|
|
@ -115,7 +115,7 @@ void snes_a15_a0_wr( uint8_t mode, uint8_t romsel, uint8_t addrH, uint8_t addrL,
|
|||
DATA_OUT = data;
|
||||
|
||||
//let higher level function/caller decide if /ROMSEL is active
|
||||
if ( romsel == TRUE ) {
|
||||
if ( romsel == ~FALSE ) {
|
||||
_ROMSEL_LO();
|
||||
}
|
||||
|
||||
|
|
@ -187,7 +187,7 @@ uint8_t snes_a15_a0_rd( uint8_t mode, uint8_t romsel, uint8_t addrX, uint8_t add
|
|||
_DATA_IP();
|
||||
|
||||
//let higher level function/caller decide if /ROMSEL is active
|
||||
if ( romsel == TRUE ) {
|
||||
if ( romsel == ~FALSE ) {
|
||||
_ROMSEL_LO();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,11 +26,6 @@
|
|||
#define PAYLD_DONE 1
|
||||
#define NOT_DONE 0
|
||||
|
||||
//TODO these should probably be in shared so host code and utilize them on the other side
|
||||
#define RETURN_BUFF_SIZE 8 //number of bytes in generic return buffer
|
||||
#define RV_ERR_IDX 0 //(first) index of buffer that contains SUCCESS/ERROR#
|
||||
#define RV_DATA0_IDX RV_ERR_IDX + 1 //first index of return data
|
||||
#define RV_DATA_MAX_IDX RETURN_BUFF_SIZE - 1 //last index available for return data
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -0,0 +1,76 @@
|
|||
#include "cartridge.h"
|
||||
|
||||
int detect_console( cartridge *cart, USBtransfer *transfer )
|
||||
{
|
||||
//always start with resetting i/o
|
||||
io_reset( transfer );
|
||||
|
||||
//TODO check if can detect a cart inserted backwards before continuing
|
||||
|
||||
//check if NES/Famicom cart
|
||||
nes_init( transfer );
|
||||
|
||||
//if PPU /A13 is tied to CIRAM /CE we know it's NES/Famicom
|
||||
if ( jumper_ciramce_ppuA13n( transfer ) ) {
|
||||
//NES with 2 screen mirroring
|
||||
debug("CIRAM /CE is jumpered to PPU /A13");
|
||||
cart->console = NES_CART;
|
||||
} else if ( ciramce_inv_ppuA13( transfer ) ) {
|
||||
//some boards including INLXO-ROM boards drive CIRAM /CE with inverse of PPU A13
|
||||
debug("CIRAM /CE is inverse of PPU A13");
|
||||
cart->console = NES_CART;
|
||||
} else {
|
||||
//TODO check if CIRAM on cartridge or NT CHR-ROM
|
||||
}
|
||||
|
||||
//if NES/FC determine which if possible
|
||||
//also possible that this could catch failed detections above which is current case with VRC6
|
||||
//Famicom has audio in and audio out pins connected to each other
|
||||
//For this to pass with a NES cart EXP6 would have to be jumpered to EXP0 for some strange reason
|
||||
//might fail if expansion audio mixing circuitry foils the check above
|
||||
//but worst case we detected NES when famicom which isn't big deal..
|
||||
if ( famicom_sound( transfer ) ) {
|
||||
debug("Famicom audio jumper found");
|
||||
cart->console = FC_CART;
|
||||
}
|
||||
|
||||
//if couldn't detect NES/FC check for SNES cartridge
|
||||
//want to keep from outputting on EXP bus if NES cart was found
|
||||
if ( cart->console == UNKNOWN ) {
|
||||
//only way I can think of is if memory is enabled by certain addresses and control signals
|
||||
snes_init( transfer );
|
||||
if ( snes_mem_visible( transfer, 0x00, 0xFFFC )) {
|
||||
//CHECK for memory visible near NES reset vector
|
||||
debug("SNES memories detected");
|
||||
cart->console = SNES_CART;
|
||||
}
|
||||
//now it's possible that rom is there, but data is 0xFF so above test would fail
|
||||
//one option would be to drive bus low for short period and see if bus can be
|
||||
//driven low. This could damage pin drivers though, best to create command in
|
||||
//firmware to perform this to limit to one CPU cycle instead of USB xfr times
|
||||
|
||||
//Prob best to check if able to read flash ID's if reset vector data is 0xFF
|
||||
//Since reset vector being 0xFF prob means it's blank flash cart..
|
||||
|
||||
//playable SNES carts should have data somewhere in reset vector...
|
||||
}
|
||||
|
||||
//always end with resetting i/o
|
||||
io_reset( transfer );
|
||||
|
||||
|
||||
return SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
|
||||
//Can detect INL discrete, XO, and possily others with pullup EXP0 test
|
||||
//These carts have pullups on EXP0 so rising edge is faster
|
||||
//Also detecting that CIRAM /CE is driven by inverted PPU A13 is good way to
|
||||
//detect INLX0-ROM boards.
|
||||
|
||||
//SNES /RESET pin should control whether memory is enabled on original boards
|
||||
//INL SNES boards memory mapping is controlled by /RESET pin
|
||||
//roms are still visible when /RESET low, but SRAM isn't
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
#ifndef _cartridge_h
|
||||
#define _cartridge_h
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <libusb.h>
|
||||
|
||||
//include prior to other file includes
|
||||
//that way DEBUG can be turned on/off for this file alone
|
||||
//uncomment to DEBUG this file alone
|
||||
#define DEBUG
|
||||
//"make debug" to get DEBUG msgs on entire program
|
||||
#include "dbg.h"
|
||||
|
||||
#include "usb_operations.h"
|
||||
#include "shared_errors.h"
|
||||
#include "shared_dictionaries.h"
|
||||
#include "dictionary.h"
|
||||
#include "types.h"
|
||||
|
||||
#include "io.h"
|
||||
#include "nes.h"
|
||||
#include "snes.h"
|
||||
|
||||
//cartridge object/struct
|
||||
typedef struct cartridge{
|
||||
int console; //console the cart plays in
|
||||
int mapper; //mapper number of the board
|
||||
int submap;
|
||||
int mapvariant;
|
||||
int manf;
|
||||
int product;
|
||||
int mirroring;
|
||||
int sound;
|
||||
memory *pri_rom; //main executable rom (PRG-ROM for NES)
|
||||
memory *sec_rom; //secondary rom if used (CHR-ROM for NES)
|
||||
memory *save_mem; //save data memory
|
||||
memory *aux_mem; //additional memory
|
||||
memory *logic; //programmable logic
|
||||
} cartridge;
|
||||
|
||||
//console options
|
||||
#define UNKNOWN 0
|
||||
#define NES_CART 'N'
|
||||
#define FC_CART 'F'
|
||||
#define SNES_CART 'S'
|
||||
#define BKWD_CART 'B'
|
||||
|
||||
int detect_console( cartridge *cart, USBtransfer *transfer );
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -16,21 +16,22 @@
|
|||
*/
|
||||
|
||||
//default call dictionary without print option
|
||||
int dictionary_call( USBtransfer *transfer, uint8_t dictionary, uint8_t opcode, uint16_t addr, uint8_t miscdata,
|
||||
uint8_t endpoint, uint8_t *buffer, uint16_t length)
|
||||
int dictionary_call( USBtransfer *transfer, uint8_t dictionary, uint8_t opcode, uint16_t addr,
|
||||
uint8_t miscdata, uint8_t endpoint, uint8_t *buffer, uint16_t length)
|
||||
{
|
||||
return dictionary_call_print_option( ~TRUE, transfer, dictionary, opcode, addr, miscdata, endpoint, buffer, length);
|
||||
return dictionary_call_print_option( FALSE, transfer, dictionary, opcode, addr, miscdata, endpoint, buffer, length);
|
||||
}
|
||||
|
||||
//debug call dictionary without print option
|
||||
int dictionary_call_debug( USBtransfer *transfer, uint8_t dictionary, uint8_t opcode, uint16_t addr, uint8_t miscdata,
|
||||
uint8_t endpoint, uint8_t *buffer, uint16_t length)
|
||||
int dictionary_call_debug( USBtransfer *transfer, uint8_t dictionary, uint8_t opcode, uint16_t addr,
|
||||
uint8_t miscdata, uint8_t endpoint, uint8_t *buffer, uint16_t length)
|
||||
{
|
||||
return dictionary_call_print_option( TRUE, transfer, dictionary, opcode, addr, miscdata, endpoint, buffer, length);
|
||||
return dictionary_call_print_option( ~FALSE, transfer, dictionary, opcode, addr, miscdata,
|
||||
endpoint, buffer, length);
|
||||
}
|
||||
|
||||
int dictionary_call_print_option( int print_debug, USBtransfer *transfer, uint8_t dictionary, uint8_t opcode, uint16_t addr, uint8_t miscdata,
|
||||
uint8_t endpoint, uint8_t *buffer, uint16_t length)
|
||||
int dictionary_call_print_option( int print_debug, USBtransfer *transfer, uint8_t dictionary, uint8_t opcode,
|
||||
uint16_t addr, uint8_t miscdata, uint8_t endpoint, uint8_t *buffer, uint16_t length)
|
||||
{
|
||||
transfer->request = dictionary;
|
||||
transfer->wValueMSB = miscdata;
|
||||
|
|
@ -48,21 +49,24 @@ int dictionary_call_print_option( int print_debug, USBtransfer *transfer, uint8_
|
|||
uint8_t rbuf[8];
|
||||
|
||||
if ( buffer == NULL ) {
|
||||
rbuf[0] = 0xA5;
|
||||
rbuf[1] = 0xC3;
|
||||
rbuf[2] = 0xA5;
|
||||
rbuf[3] = 0xC3;
|
||||
rbuf[4] = 0xA5;
|
||||
rbuf[5] = 0xC3;
|
||||
rbuf[6] = 0xA5;
|
||||
rbuf[7] = 0xC3;
|
||||
rbuf[0] = 0xee;
|
||||
rbuf[1] = 0xee;
|
||||
rbuf[2] = 0xee;
|
||||
rbuf[3] = 0xee;
|
||||
rbuf[4] = 0xee;
|
||||
rbuf[5] = 0xee;
|
||||
rbuf[6] = 0xee;
|
||||
rbuf[7] = 0xee;
|
||||
transfer->data = rbuf;
|
||||
} else {
|
||||
transfer->data = buffer;
|
||||
}
|
||||
|
||||
|
||||
debug("\ndictionary call dict:%d opcode:%d/%x addr:%x data:%x", dictionary, opcode, opcode, addr, miscdata);
|
||||
if (print_debug) {
|
||||
printf("\ndictionary call dict:%d opcode:%dd/%xh addr:%x data:%x\n",
|
||||
dictionary, opcode, opcode, addr, miscdata);
|
||||
}
|
||||
switch (dictionary) {
|
||||
case PINPORT: debug("dict: PINPORT");
|
||||
//transfer->wLength = 1;
|
||||
|
|
@ -154,13 +158,13 @@ int dictionary_call_print_option( int print_debug, USBtransfer *transfer, uint8_
|
|||
|
||||
xfr_cnt = usb_transfer( transfer );
|
||||
|
||||
if (print_debug == TRUE) {
|
||||
if (print_debug) {
|
||||
//print transfer details if small xfr
|
||||
if (xfr_cnt <= 8) {
|
||||
printf(" xf: %d er: %d rv:",xfr_cnt, rbuf[0]);
|
||||
printf(" xf: %d er: %d rv:",xfr_cnt, transfer->data[0]);
|
||||
int i ;
|
||||
for (i=1; i<xfr_cnt; i++){
|
||||
printf(" %x,", rbuf[i]);
|
||||
printf(" %x,", transfer->data[i]);
|
||||
}
|
||||
printf("\n");
|
||||
} else {
|
||||
|
|
@ -171,7 +175,7 @@ int dictionary_call_print_option( int print_debug, USBtransfer *transfer, uint8_
|
|||
}
|
||||
|
||||
if (xfr_cnt <= 8) {
|
||||
check(rbuf[0] == SUCCESS, "retro programmer had error: %d, dict:%d, opcode:%d/%x, addr:%x, data:%x",rbuf[0], dictionary, opcode, opcode, addr, miscdata)
|
||||
check(transfer->data[0] == SUCCESS, "retro programmer had error: %d, dict:%d, opcode:%d/%x, addr:%x, data:%x",transfer->data[0], dictionary, opcode, opcode, addr, miscdata)
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
|
|
|
|||
|
|
@ -20,14 +20,15 @@
|
|||
#include "shared_dictionaries.h"
|
||||
|
||||
//default call dictionary without print option
|
||||
int dictionary_call( USBtransfer *transfer, uint8_t dictionary, uint8_t opcode, uint16_t addr, uint8_t miscdata,
|
||||
uint8_t endpoint, uint8_t *buffer, uint16_t length);
|
||||
int dictionary_call( USBtransfer *transfer, uint8_t dictionary, uint8_t opcode, uint16_t addr,
|
||||
uint8_t miscdata, uint8_t endpoint, uint8_t *buffer, uint16_t length);
|
||||
|
||||
//debug call dictionary without print option
|
||||
int dictionary_call_debug( USBtransfer *transfer, uint8_t dictionary, uint8_t opcode, uint16_t addr, uint8_t miscdata,
|
||||
uint8_t endpoint, uint8_t *buffer, uint16_t length);
|
||||
int dictionary_call_debug( USBtransfer *transfer, uint8_t dictionary, uint8_t opcode, uint16_t addr,
|
||||
uint8_t miscdata, uint8_t endpoint, uint8_t *buffer, uint16_t length);
|
||||
|
||||
int dictionary_call_print_option( int print_debug, USBtransfer *transfer, uint8_t dictionary, uint8_t opcode, uint16_t addr, uint8_t miscdata,
|
||||
uint8_t endpoint, uint8_t *buffer, uint16_t length);
|
||||
int dictionary_call_print_option( int print_debug, USBtransfer *transfer, uint8_t dictionary,
|
||||
uint8_t opcode, uint16_t addr, uint8_t miscdata, uint8_t endpoint,
|
||||
uint8_t *buffer, uint16_t length);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -20,10 +20,6 @@
|
|||
#include "shared_dictionaries.h"
|
||||
#include "dictionary.h"
|
||||
|
||||
//uncomment to DEBUG this file alone
|
||||
#define DEBUG
|
||||
//"make debug" to get DEBUG msgs on entire program
|
||||
#include "dbg.h"
|
||||
|
||||
int erase_nes( USBtransfer *transfer );
|
||||
|
||||
|
|
|
|||
|
|
@ -12,11 +12,12 @@
|
|||
//"make debug" to get DEBUG msgs on entire program
|
||||
#include "dbg.h"
|
||||
|
||||
#include "shared_dictionaries.h"
|
||||
#include "usb_operations.h"
|
||||
#include "write_operations.h"
|
||||
#include "erase.h"
|
||||
#include "test.h"
|
||||
#include "shared_dictionaries.h"
|
||||
#include "cartridge.h"
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
|
|
@ -151,23 +152,30 @@ int main(int argc, char *argv[])
|
|||
//libusb_device_handle *rprog_handle = NULL;
|
||||
transfer->handle = NULL;
|
||||
|
||||
//open INL retro prog with firmware version 2.0 or greater
|
||||
//command line arg L_value to set different LIBUSB debugging options
|
||||
//any value > 0 also prints debug statements in open_usb_device function
|
||||
int libusb_log = LIBUSB_LOG_LEVEL_NONE; // 0: default no msgs ever printed
|
||||
if (L_value != NULL) {
|
||||
check( isdigit(L_value[0]), "Invalid LIBUSB_LOG_LEVEL: %s, only single digit allowed", L_value);
|
||||
check( strlen(L_value) == 1, "Invalid LIBUSB_LOG_LEVEL: %s, only single digit allowed", L_value);
|
||||
check( isdigit(L_value[0]),
|
||||
"Invalid LIBUSB_LOG_LEVEL: %s, only single digit allowed", L_value);
|
||||
check( strlen(L_value) == 1,
|
||||
"Invalid LIBUSB_LOG_LEVEL: %s, only single digit allowed", L_value);
|
||||
libusb_log = atoi(L_value);
|
||||
check( ((libusb_log >= LIBUSB_LOG_LEVEL_NONE) && (libusb_log <=LIBUSB_LOG_LEVEL_DEBUG)),
|
||||
"Invalid LIBUSB_LOG_LEVEL: %d, must be from 0 to 4", libusb_log );
|
||||
printf("setting LIBUSB_LOG_LEVEL to: %d\n", libusb_log);
|
||||
if (libusb_log == 0) { printf("\tNONE: default no messages ever printed by library\n"); }
|
||||
if (libusb_log == 1) { printf("\tERROR: error messages are printed to stderr\n"); }
|
||||
if (libusb_log == 2) { printf("\tWARNING: warning and error messages are printed to stderr\n"); }
|
||||
if (libusb_log == 3) { printf("\tINFO: informational, warning, & error messages are printed to stdout\n"); }
|
||||
if (libusb_log == 4) { printf("\tDEBUG: debug, info, warning, & error messages are printed to stdout\n"); }
|
||||
if (libusb_log == 0) {
|
||||
printf("\tNONE: default no messages ever printed by library\n"); }
|
||||
if (libusb_log == 1) {
|
||||
printf("\tERROR: error messages are printed to stderr\n"); }
|
||||
if (libusb_log == 2) {
|
||||
printf("\tWARNING: warning and error messages are printed to stderr\n"); }
|
||||
if (libusb_log == 3) {
|
||||
printf("\tINFO: informational, warning, & error messages are printed to stdout\n"); }
|
||||
if (libusb_log == 4) {
|
||||
printf("\tDEBUG: debug, info, warning, & error messages are printed to stdout\n"); }
|
||||
}
|
||||
//open INL retro prog with firmware version 2.0 or greater
|
||||
if (K_value != NULL) {
|
||||
//TODO take K_value option to connect to different version kazzo
|
||||
}
|
||||
|
|
@ -177,18 +185,44 @@ int main(int argc, char *argv[])
|
|||
//report successful connection to INL retro-prog
|
||||
printf("Successfully found and connected to INL retro-prog with firmware version 2.0\n");
|
||||
|
||||
//TEST flag for development use to provide means to only call test.c functions
|
||||
if (T_flag) {
|
||||
test_function( transfer );
|
||||
goto close;
|
||||
}
|
||||
|
||||
//create board object/struct
|
||||
cartridge *cart = malloc( sizeof(cartridge));
|
||||
check_mem(cart);
|
||||
|
||||
//attempt to detect board inserted in device
|
||||
cart->console = UNKNOWN;
|
||||
// -x flag turns off all autodection
|
||||
if (!x_flag) {
|
||||
printf("attempting to detect cartridge...\n");
|
||||
detect_console( cart, transfer );
|
||||
switch (cart->console) {
|
||||
case NES_CART: printf("NES cartridge detected!\n");
|
||||
break;
|
||||
case FC_CART: printf("Famicom cartridge detected!\n");
|
||||
break;
|
||||
case SNES_CART: printf("SNES cartridge detected!\n");
|
||||
break;
|
||||
case BKWD_CART: log_err("CARTRIDGE INSERTED BACKWARDS!!!\n");
|
||||
break;
|
||||
case UNKNOWN: printf("Unable to detect cartridge...\n");
|
||||
break;
|
||||
default:
|
||||
sentinel("cartridge console element got set to something unsupported.");
|
||||
}
|
||||
} else {
|
||||
printf("auto-detection turned off\n");
|
||||
}
|
||||
|
||||
if (e_flag) erase_nes( transfer );
|
||||
if (T_flag) test_function( transfer );
|
||||
//forced to erase board regardless of current status
|
||||
if (e_flag) {
|
||||
erase_nes( transfer );
|
||||
}
|
||||
|
||||
|
||||
//handle simple LED ON/OFF within main for now
|
||||
|
|
@ -224,7 +258,7 @@ int main(int argc, char *argv[])
|
|||
}
|
||||
|
||||
|
||||
|
||||
close:
|
||||
close_usb( context, transfer->handle);
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
#include "io.h"
|
||||
|
||||
/* Desc:disable all possible outputs and float EXP0
|
||||
* Pre:
|
||||
* Post:all memories disabled data bus clear
|
||||
* Rtn:
|
||||
*/
|
||||
void io_reset( USBtransfer *transfer )
|
||||
{
|
||||
dictionary_call( transfer, IO, IO_RESET, 0, 0,
|
||||
USB_IN, NULL, 1);
|
||||
}
|
||||
|
||||
/* Desc:initialize NES I/P and O/P
|
||||
* Pre:
|
||||
* Post:memories disabled data bus clear
|
||||
* Rtn:
|
||||
*/
|
||||
void nes_init( USBtransfer *transfer )
|
||||
{
|
||||
dictionary_call( transfer, IO, NES_INIT, 0, 0,
|
||||
USB_IN, NULL, 1);
|
||||
}
|
||||
|
||||
|
||||
/* Desc:initialize SNES I/P and O/P
|
||||
* Pre:
|
||||
* Post:memories disabled data bus clear
|
||||
* Rtn:
|
||||
*/
|
||||
void snes_init( USBtransfer *transfer )
|
||||
{
|
||||
dictionary_call( transfer, IO, SNES_INIT, 0, 0,
|
||||
USB_IN, NULL, 1);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
#ifndef _io_h
|
||||
#define _io_h
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <libusb.h>
|
||||
|
||||
//include prior to other file includes
|
||||
//that way DEBUG can be turned on/off for this file alone
|
||||
//uncomment to DEBUG this file alone
|
||||
#define DEBUG
|
||||
//"make debug" to get DEBUG msgs on entire program
|
||||
#include "dbg.h"
|
||||
|
||||
#include "shared_errors.h"
|
||||
#include "shared_dictionaries.h"
|
||||
#include "dictionary.h"
|
||||
|
||||
void io_reset( USBtransfer *transfer );
|
||||
void nes_init( USBtransfer *transfer );
|
||||
void snes_init( USBtransfer *transfer );
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,170 @@
|
|||
#include "nes.h"
|
||||
|
||||
/* Desc:check if PPU /A13 -> CIRAM /CE jumper present
|
||||
* Does NOT check if PPU A13 is inverted and then drives CIRAM /CE
|
||||
* Pre: nes_init() been called to setup i/o
|
||||
* Post:PPU /A13 left high (disabled), all other ADDRH signals low
|
||||
* Rtn: FALSE if jumper is not set
|
||||
*/
|
||||
int jumper_ciramce_ppuA13n( USBtransfer *transfer )
|
||||
{
|
||||
uint8_t rv[RV_DATA0_IDX+1];
|
||||
|
||||
//check that we can clear CIRAM /CE with PPU /A13
|
||||
dictionary_call( transfer, PINPORT, ADDRH_SET, 0, 0,
|
||||
USB_IN, NULL, 1);
|
||||
//read CIRAM /CE pin
|
||||
dictionary_call( transfer, PINPORT, CICE_RD, 0, 0,
|
||||
USB_IN, rv, RV_DATA0_IDX+1);
|
||||
|
||||
//CIRAM /CE's port PIN register contents are now in rv[RV_DATA_IDX]
|
||||
//need to mask out the CIRAM /CE pin
|
||||
if ( rv[RV_DATA0_IDX] & CICE_MSK ) {
|
||||
//CIRAM /CE pin was always high regardless of PPU /A13
|
||||
debug("CIRAM /CE high when /A13 low ");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//set PPU /A13 high
|
||||
dictionary_call( transfer, PINPORT, ADDRH_SET, PPU_A13N_MSK, 0,
|
||||
USB_IN, NULL, 1);
|
||||
//read CIRAM /CE pin
|
||||
dictionary_call( transfer, PINPORT, CICE_RD, 0, 0,
|
||||
USB_IN, rv, RV_DATA0_IDX+1);
|
||||
|
||||
//CIRAM /CE's port PIN register contents are now in rv[RV_DATA_IDX]
|
||||
//need to mask out the CIRAM /CE pin
|
||||
if ( (rv[RV_DATA0_IDX] & CICE_MSK) == 0 ) {
|
||||
//CICE jumper not present
|
||||
debug("CIRAM /CE low when /A13 high ");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//CICE low jumper appears to be present
|
||||
debug("CIRAM /CE <- PPU /A13 jumper present");
|
||||
return ~FALSE;
|
||||
|
||||
}
|
||||
|
||||
/* Desc:check if PPU A13 is inverted then drives CIRAM /CE
|
||||
* Some mappers may do this including INLXO-ROM boards
|
||||
* Does NOT check if PPU /A13 is drives CIRAM /CE
|
||||
* Pre: nes_init() been called to setup i/o
|
||||
* Post:PPU A13 left disabled (hi)
|
||||
* Rtn: FALSE if inverted PPU A13 doesn't drive CIRAM /CE
|
||||
*/
|
||||
int ciramce_inv_ppuA13( USBtransfer *transfer )
|
||||
{
|
||||
uint8_t rv[RV_DATA0_IDX+1];
|
||||
|
||||
//set PPU /A13 low
|
||||
dictionary_call( transfer, PINPORT, ADDRH_SET, 0, 0,
|
||||
USB_IN, NULL, 1);
|
||||
//read CIRAM /CE pin
|
||||
dictionary_call( transfer, PINPORT, CICE_RD, 0, 0,
|
||||
USB_IN, rv, RV_DATA0_IDX+1);
|
||||
|
||||
// CIRAM /CE should be high if inverted A13 is what drives it
|
||||
if ( (rv[RV_DATA0_IDX] & CICE_MSK) == 0 ) {
|
||||
//CICE jumper not present
|
||||
debug("CIRAM /CE low when /A13 low ");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//check that we can clear CIRAM /CE with PPU /A13 high
|
||||
dictionary_call( transfer, PINPORT, ADDRH_SET, PPU_A13_MSK, 0,
|
||||
USB_IN, NULL, 1);
|
||||
//read CIRAM /CE pin
|
||||
dictionary_call( transfer, PINPORT, CICE_RD, 0, 0,
|
||||
USB_IN, rv, RV_DATA0_IDX+1);
|
||||
|
||||
// CIRAM /CE should be low if inverted A13 is what drives it
|
||||
if ( rv[RV_DATA0_IDX] & CICE_MSK ) {
|
||||
//CIRAM /CE pin was always high regardless of PPU /A13
|
||||
debug("CIRAM /CE high when /A13 high ");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
//CICE low jumper appears to be present
|
||||
debug("CIRAM /CE <- inverse PPU /A13");
|
||||
return ~FALSE;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Desc:check for famicom audio in->out jumper
|
||||
* This drives EXP6 (RF out) -> EXP0 (APU in) which is backwards..
|
||||
* not much can do about that for current kazzo designs
|
||||
* There are probably caps/resistors for synth carts anyway
|
||||
* but to be safe only apply short pulses.
|
||||
* While we typically don't want to apply 5v to EXP port on NES carts,
|
||||
* this only does so for EXP6 which is safe on current designs.
|
||||
* All other EXP1-8 pins are only driven low.
|
||||
* Pre: nes_init() been called to setup i/o
|
||||
* which makes EXP0 floating i/p
|
||||
* Post:EXP FF left disabled and EXP0 floating
|
||||
* AXLOE pin returned to input with pullup
|
||||
* Rtn: FALSE if jumper/connection is not present
|
||||
* Test:Works on non-expansion sound carts obviously
|
||||
* Works on VRC6 and VRC7
|
||||
* Others untested
|
||||
*/
|
||||
int famicom_sound( USBtransfer *transfer )
|
||||
{
|
||||
uint8_t rv[RV_DATA0_IDX+1];
|
||||
|
||||
//EXP0 should be floating input
|
||||
//AXLOE pin needs to be set as output and
|
||||
//EXP FF needs enabled before we can clock it,
|
||||
//but don't leave it enabled before exiting function
|
||||
|
||||
//set AXLOE to output
|
||||
dictionary_call( transfer, PINPORT, AXLOE_OP, 0, 0,
|
||||
USB_IN, NULL, 1);
|
||||
//enable EXP FF
|
||||
dictionary_call( transfer, PINPORT, EXPFF_OP, 0, 0,
|
||||
USB_IN, NULL, 1);
|
||||
//Latch low first
|
||||
dictionary_call( transfer, PINPORT, ADDRX_SET, 0, 0,
|
||||
USB_IN, NULL, 1);
|
||||
//read EXP0 Famicom APU audio pin
|
||||
dictionary_call( transfer, PINPORT, FC_APU_RD, 0, 0,
|
||||
USB_IN, rv, RV_DATA0_IDX+1);
|
||||
|
||||
//need to mask out the pin
|
||||
if ( rv[RV_DATA0_IDX] & FC_APU_MSK ) {
|
||||
debug("RF audio out (EXP6) didn't drive APU audio in (EXP0) low");
|
||||
//disable EXP FF
|
||||
dictionary_call( transfer, PINPORT, EXPFF_FLT, 0, 0,
|
||||
USB_IN, NULL, 1);
|
||||
//retun AXLOE to input
|
||||
dictionary_call( transfer, PINPORT, AXLOE_IP, 0, 0,
|
||||
USB_IN, NULL, 1);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//Latch pin high
|
||||
dictionary_call( transfer, PINPORT, ADDRX_SET, FC_RF_MSK, 0,
|
||||
USB_IN, NULL, 1);
|
||||
//read EXP0 Famicom APU audio pin
|
||||
dictionary_call( transfer, PINPORT, FC_APU_RD, 0, 0,
|
||||
USB_IN, rv, RV_DATA0_IDX+1);
|
||||
//disable EXP FF
|
||||
dictionary_call( transfer, PINPORT, EXPFF_FLT, 0, 0,
|
||||
USB_IN, NULL, 1);
|
||||
//retun AXLOE to input
|
||||
dictionary_call( transfer, PINPORT, AXLOE_IP, 0, 0,
|
||||
USB_IN, NULL, 1);
|
||||
|
||||
//mask pin from byte
|
||||
if ( (rv[RV_DATA0_IDX] & FC_APU_MSK) == 0 ) {
|
||||
debug("RF audio out (EXP6) didn't drive APU audio in (EXP0) high");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//CICE low jumper appears to be present
|
||||
debug("RF audio out (EXP6) is connected to APU audio in (EXP0)");
|
||||
return ~FALSE;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
#ifndef _nes_h
|
||||
#define _nes_h
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
|
||||
//include prior to other file includes
|
||||
//that way DEBUG can be turned on/off for this file alone
|
||||
//uncomment to DEBUG this file alone
|
||||
//#define DEBUG
|
||||
//"make debug" to get DEBUG msgs on entire program
|
||||
#include "dbg.h"
|
||||
|
||||
#include "shared_errors.h"
|
||||
#include "shared_dictionaries.h"
|
||||
#include "dictionary.h"
|
||||
|
||||
#include "pindef.h"
|
||||
|
||||
int jumper_ciramce_ppuA13n( USBtransfer *transfer );
|
||||
int ciramce_inv_ppuA13( USBtransfer *transfer );
|
||||
int famicom_sound( USBtransfer *transfer );
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,135 @@
|
|||
#ifndef _pindef_h
|
||||
#define _pindef_h
|
||||
|
||||
//--------------------------------------------------
|
||||
// PIN and PORT Definitions
|
||||
// gives easier/more abstract access
|
||||
// to I/O reading on host
|
||||
// the dictionaries only provide access to
|
||||
// read a byte wide port for speed and simplicity
|
||||
// of code on firmware. The host must decode
|
||||
// these bytes to get desired pin data
|
||||
// these are copied from firmware pinport.h
|
||||
// then adjusted to work in host setting
|
||||
//--------------------------------------------------
|
||||
|
||||
//To utilize these macros first make a dictionary call and provide the <PIN>_RD opcode
|
||||
//This is effectively just using the CTL_RD/AUX_RD opcode but easier bc you don't have
|
||||
//to remember what pin is on which port.
|
||||
//Store the result of that dictionary call in a byte
|
||||
//This is currently the second byte returned as the first one is the error code
|
||||
//Then mask the return data byte with <PIN>_MSK
|
||||
//If result is 0 pin is low, if equal to <PIN>_MSK (not zero) pin is high
|
||||
|
||||
|
||||
//first make it so we don't have to remember what port the io resides on
|
||||
//these don't work if the ddr wasn't set to i/p before hand
|
||||
//these are simply macros to call the dictionary entry in shared_dict_pinport.h
|
||||
//these become new opcodes which the host can use to call the underlying PIN READ
|
||||
//they will return the byte wide PIN register which then must be masked to get
|
||||
//the specific io desired
|
||||
#define M2_RD CTL_RD
|
||||
#define ROMSEL_RD CTL_RD
|
||||
//#define PRGRW_RD CTL_RD broke due to redefine PRGRW_RD sets pin low
|
||||
#define FREE_RD CTL_RD
|
||||
#define CSRD_RD CTL_RD
|
||||
#define CSWR_RD CTL_RD
|
||||
#define CICE_RD CTL_RD
|
||||
#define AHL_RD CTL_RD
|
||||
|
||||
#define EXP0_RD AUX_RD
|
||||
#define FC_APU_RD AUX_RD
|
||||
#define TDO_RD AUX_RD
|
||||
#define SRST_RD AUX_RD
|
||||
#define LED_RD AUX_RD
|
||||
#define EXP9_RD AUX_RD
|
||||
#define IRQ_RD AUX_RD
|
||||
#define CIA10_RD AUX_RD
|
||||
#define BL_RD AUX_RD
|
||||
#define AXLOE_RD AUX_RD
|
||||
|
||||
|
||||
|
||||
//Now we need a mask for the io's place in the return byte
|
||||
//This was copied from firmware's pinport.h
|
||||
//then _MSK prefix to pin name to make the fact this is a mask obvious
|
||||
//in place of PC#/PD# which only makes sense to avr-gcc place the hex mask equivalent
|
||||
//============================
|
||||
//CTL PORTC
|
||||
//============================
|
||||
#define M2_MSK 0x01 //PC0 //NES, FC, & SNES (SYSCLK)
|
||||
#define ROMSEL_MSK 0x02 //PC1 //(aka PRG/CE) NES, FC, & SNES
|
||||
#define PRGRW_MSK 0x04 //PC2 //PRG R/W on NES & FC
|
||||
|
||||
//#ifdef PURPLE_KAZZO
|
||||
#define p_AXL_MSK 0x08 //PC3 //EXP FF CLK on purple boards
|
||||
//#else
|
||||
#define FREE_MSK 0x08 //PC3 //Free pin on all other boards
|
||||
//#endif
|
||||
|
||||
#define CSRD_MSK 0x10 //PC4 //NES & FC CHR /RD, SNES /RD
|
||||
#define CSWR_MSK 0x20 //PC5 //NES & FC CHR /WR, SNES /WR
|
||||
#define CICE_MSK 0x40 //PC6 //NES & FC CIRAM /CE, most carts are 2screen tying this to CHR /A13 making this an I/P
|
||||
|
||||
//#ifdef GREEN_KAZZO
|
||||
#define g_AXHL_MSK 0x80 //PC7 //Both ADDR_MID & EXP/ADDRHI FF CLK on green prototype
|
||||
//#else
|
||||
#define AHL_MSK 0x80 //PC7 //ADDR MID FF CLK per orig kazzo design
|
||||
//#endif
|
||||
|
||||
|
||||
|
||||
//============================
|
||||
//AUX PORTD
|
||||
//============================
|
||||
#define EXP0_MSK 0x01 //PD0 //NES EXP0 controls a number of varying flash cart features...
|
||||
#define FC_APU_MSK 0x01 //PD0 //FC Audio in cart from 2A03 APU
|
||||
#define TDO_MSK 0x01 //PD0 //CPLD JTAG on INL-ROM NES/FC boards released after ~Oct2016
|
||||
#define SRST_MSK 0x01 //PD0 //SNES /RESET pin used for CPLD prgm/play mode and SRAM CE
|
||||
|
||||
#define LED_MSK 0x02 //PD1 //LED on INL retro prog-dumper
|
||||
#define EXP9_MSK 0x02 //PD1 //NES dual purposed pin
|
||||
|
||||
#define USBP_MSK 0x04 //PD2 //USB D+ don't touch this pin!
|
||||
#define IRQ_MSK 0x08 //PD3 //Connected to NES, FC, & SNES
|
||||
#define USBM_MSK 0x10 //PD4 //USB D- don't touch this pin!
|
||||
#define CIA10_MSK 0x20 //PD5 //NES & FC CIRAM A10 (aka VRAM A10)
|
||||
#define BL_MSK 0x40 //PD6 //Bootloader switch BL->GND, RUN->float
|
||||
|
||||
//#ifdef PURPLE_KAZZO
|
||||
#define pg_XOE_MSK 0x80 //PD7 //EXP/ADDRHI FF /OE pin on purple and green boards
|
||||
//#endif
|
||||
//#ifdef GREEN_KAZZO
|
||||
#define pg_XOE_MSK 0x80 //PD7 //EXP/ADDRHI FF /OE pin on purple and green boards
|
||||
//#endif
|
||||
//#ifndef pg_XOE //FINAL_DESIGN
|
||||
#define AXLOE_MSK 0x80 //PD7 //EXP/ADDRHI FF CLK & /OE pin on final board versions
|
||||
//#endif
|
||||
|
||||
|
||||
|
||||
//The following macros help locate control signals behind flipflops
|
||||
//To set/clear these signals call the dictionary flipflop's opcode with this value
|
||||
//note all 8 pins get set at once must and/or in values to a host variable
|
||||
//if trying to maintain value of other signals
|
||||
|
||||
//pin masks for where signal resides on ADDRH flipflop
|
||||
#define PPU_A13N_MSK 0x80
|
||||
#define PPU_A13_MSK 0x20
|
||||
|
||||
//EXP FF connects D7:0 to EXP8:1 so everything is shifted one bit
|
||||
//0b8765 4321
|
||||
#define EXP8_MSK 0x80
|
||||
#define EXP7_MSK 0x40
|
||||
|
||||
#define FC_RF_MSK 0x20
|
||||
#define EXP6_MSK 0x20
|
||||
|
||||
#define EXP5_MSK 0x10
|
||||
#define EXP4_MSK 0x08
|
||||
#define EXP3_MSK 0x04
|
||||
#define EXP2_MSK 0x02
|
||||
#define EXP1_MSK 0x01
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
#include "snes.h"
|
||||
|
||||
/* Desc:check if ROM visible at provided address
|
||||
* Pre: snes_init() been called to setup i/o
|
||||
* Post:Address left on bus memories disabled
|
||||
* Rtn: FALSE if memory not found
|
||||
*/
|
||||
int snes_mem_visible( USBtransfer *transfer, uint8_t bank, uint16_t addr )
|
||||
{
|
||||
uint8_t rv[RV_DATA0_IDX+1];
|
||||
|
||||
//place address on bus
|
||||
dictionary_call( transfer, PINPORT, ADDR24_SET, addr, bank,
|
||||
USB_IN, NULL, 1);
|
||||
//ensure data bus is pulled up
|
||||
dictionary_call( transfer, PINPORT, DATA_HI, 0, 0,
|
||||
USB_IN, NULL, 1);
|
||||
//read data bus
|
||||
dictionary_call_debug( transfer, PINPORT, DATA_RD, 0, 0,
|
||||
USB_IN, rv, RV_DATA0_IDX+1);
|
||||
if ( rv[RV_DATA0_IDX] != 0xFF ) {
|
||||
debug("Can't pull up data bus in attempt to detect SNES cart");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//enable rom control signals
|
||||
dictionary_call( transfer, PINPORT, SRST_HI, 0, 0,
|
||||
USB_IN, NULL, 1);
|
||||
dictionary_call( transfer, PINPORT, CSRD_LO, 0, 0,
|
||||
USB_IN, NULL, 1);
|
||||
dictionary_call( transfer, PINPORT, ROMSEL_LO, 0, 0,
|
||||
USB_IN, NULL, 1);
|
||||
//read data bus
|
||||
dictionary_call_debug( transfer, PINPORT, DATA_RD, 0, 0,
|
||||
USB_IN, rv, RV_DATA0_IDX+1);
|
||||
//clear data bus
|
||||
dictionary_call( transfer, PINPORT, SRST_LO, 0, 0,
|
||||
USB_IN, NULL, 1);
|
||||
dictionary_call( transfer, PINPORT, CSRD_HI, 0, 0,
|
||||
USB_IN, NULL, 1);
|
||||
dictionary_call( transfer, PINPORT, ROMSEL_HI, 0, 0,
|
||||
USB_IN, NULL, 1);
|
||||
if ( rv[RV_DATA0_IDX] != 0xFF ) {
|
||||
debug("Found memory with SNES control signals");
|
||||
return ~FALSE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
#ifndef _snes_h
|
||||
#define _snes_h
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
|
||||
//include prior to other file includes
|
||||
//that way DEBUG can be turned on/off for this file alone
|
||||
//uncomment to DEBUG this file alone
|
||||
#define DEBUG
|
||||
//"make debug" to get DEBUG msgs on entire program
|
||||
#include "dbg.h"
|
||||
|
||||
#include "shared_errors.h"
|
||||
#include "shared_dictionaries.h"
|
||||
#include "dictionary.h"
|
||||
|
||||
#include "pindef.h"
|
||||
|
||||
int snes_mem_visible( USBtransfer *transfer, uint8_t bank, uint16_t addr );
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
#ifndef _types_h
|
||||
#define _types_h
|
||||
|
||||
//memory object/struct
|
||||
typedef struct memory{
|
||||
int manf;
|
||||
int partnum;
|
||||
int volatility; //sram no batt vs batt, mask rom, erasability, etc
|
||||
int size; //size of the actual memory excluding grounded address pins etc
|
||||
int addressable; //addressable size of the memory including grounded address pins etc
|
||||
int width; //width of data bus as configured
|
||||
int protocol; //parallel, SPI, I2C, JTAG, custom etc.
|
||||
int sector_size; //minimum eraseable size in bytes
|
||||
} memory;
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -1,6 +1,11 @@
|
|||
#ifndef _write_operations_h
|
||||
#define _write_operations_h
|
||||
|
||||
//uncomment to DEBUG this file alone
|
||||
#define DEBUG
|
||||
//"make debug" to get DEBUG msgs on entire program
|
||||
#include "dbg.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
|
@ -10,10 +15,6 @@
|
|||
|
||||
#include "usb_operations.h"
|
||||
|
||||
//uncomment to DEBUG this file alone
|
||||
#define DEBUG
|
||||
//"make debug" to get DEBUG msgs on entire program
|
||||
#include "dbg.h"
|
||||
|
||||
|
||||
int write_file( libusb_device_handle *usbhandle, char *filename, char *ines_mapper, char *board_config );
|
||||
|
|
|
|||
|
|
@ -361,6 +361,8 @@
|
|||
//ADDR[23:0] (ADDRX:ADDRH:ADDR) SNES full address bus
|
||||
//Sets SNES 24 bit address but to value of 24bit operand
|
||||
//No control signals are modified
|
||||
//wIndex contains lower 16bits
|
||||
//wValue upper (miscdata) contains upper 8bits
|
||||
#define ADDR24_SET 0xB0
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
#ifndef _shared_dict_usb_h
|
||||
#define _shared_dict_usb_h
|
||||
|
||||
//define dictionary's reference number in the shared_dictionaries.h file
|
||||
//then include this dictionary file in shared_dictionaries.h
|
||||
//The dictionary number is literally used as usb transfer request field
|
||||
//the opcodes and operands in this dictionary are fed directly into usb setup packet's wValue wIndex fields
|
||||
|
||||
#define RETURN_BUFF_SIZE 8 //number of bytes in generic return buffer
|
||||
#define RV_ERR_IDX 0 //(first) index of buffer that contains SUCCESS/ERROR#
|
||||
#define RV_DATA0_IDX RV_ERR_IDX + 1 //first index of return data
|
||||
#define RV_DATA_MAX_IDX RETURN_BUFF_SIZE - 1 //last index available for return data
|
||||
|
||||
//=============================================================================================
|
||||
//=============================================================================================
|
||||
// USB DICTIONARY
|
||||
//
|
||||
// opcodes contained in this dictionary must be implemented in firmware/source/io.c
|
||||
//
|
||||
//=============================================================================================
|
||||
//=============================================================================================
|
||||
|
||||
#endif
|
||||
|
|
@ -122,8 +122,10 @@
|
|||
//=============================================================================================
|
||||
//=============================================================================================
|
||||
#define USB 6
|
||||
#include "shared_dict_usb.h"
|
||||
//currently no actual dictionary as there are no opcodes.
|
||||
//just used to return status of usbfunctions in event of a transfer error.
|
||||
//contains definitions of data transactions between host and firmware
|
||||
//=============================================================================================
|
||||
//=============================================================================================
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#define _error_codes_h
|
||||
|
||||
#define SUCCESS 0
|
||||
#define FALSE 0
|
||||
|
||||
//greater than 128 are possible avr return codes
|
||||
#define ERR_UNKN_DICTIONARY 128
|
||||
|
|
|
|||
Loading…
Reference in New Issue