From 66635b15e742a0d40e176f936dd655f605b6c5b1 Mon Sep 17 00:00:00 2001 From: paul eeepc Date: Wed, 7 Dec 2016 18:08:31 -0600 Subject: [PATCH] Making progress on main program flow with detection in preparation for dumping/writing operations. Prepended DICT_ to dictionary names to prevent using those defines for something else accidentally "NES/SNES" etc could be used in a lot of places, don't want to use wrong enum/define in wrong place. created enums.h to list out all enums/defines for cartridge and memory elements in one location. separate file.c/h file for getting data in/out of a files, and opening/closing them. adding test roms to roms folder so they can be used for various testing. --- firmware/source/buffer.c | 7 ++++ firmware/source/buffer.h | 7 ---- firmware/source/logic.h | 11 ------ firmware/source/pinport.h | 8 ++++ firmware/source/usb.c | 19 ++++++--- host/source/cartridge.c | 52 ++++++++++++++++++++++++ host/source/cartridge.h | 14 +++---- host/source/dictionary.c | 12 +++--- host/source/enums.h | 23 +++++++++++ host/source/erase.c | 69 +++++++++++++++++--------------- host/source/erase.h | 1 + host/source/file.c | 71 +++++++++++++++------------------ host/source/file.h | 4 +- host/source/inlprog.c | 59 ++++++++++++++++++++-------- host/source/io.c | 50 +++++++++++++++++++++-- host/source/io.h | 1 + host/source/memory.c | 14 +++++++ host/source/memory.h | 39 ++++++++++++++++++ host/source/nes.c | 36 ++++++++--------- host/source/snes.c | 20 +++++----- host/source/test.c | 74 +++++++++++++++++------------------ host/source/types.h | 19 --------- roms/M10_P128K_C64K_W8K.nes | Bin 0 -> 196624 bytes roms/M118_P128K_C64K.nes | Bin 0 -> 196624 bytes roms/M180_P128K_H.nes | Bin 0 -> 131088 bytes roms/M1_P128K_C128K_W8K.nes | Bin 0 -> 262160 bytes roms/M28_P512K.nes | Bin 0 -> 524304 bytes roms/M2_P128K_V.nes | Bin 0 -> 131088 bytes roms/M34_P128K_H.nes | Bin 0 -> 131088 bytes roms/M3_P32K_C32K_H.nes | Bin 0 -> 65552 bytes roms/M4_P256K_C256K.nes | Bin 0 -> 524304 bytes roms/M66_P64K_C16K_V.nes | Bin 0 -> 81936 bytes roms/M69_P128K_C64K_W8K.nes | Bin 0 -> 196624 bytes roms/M78.3_P128K_C64K.nes | Bin 0 -> 196624 bytes roms/M7_P128K.nes | Bin 0 -> 131088 bytes roms/M9_P128K_C64K.nes | Bin 0 -> 196624 bytes shared/shared_dictionaries.h | 12 +++--- shared/shared_errors.h | 2 + 38 files changed, 404 insertions(+), 220 deletions(-) create mode 100644 host/source/enums.h create mode 100644 host/source/memory.c create mode 100644 host/source/memory.h delete mode 100644 host/source/types.h create mode 100644 roms/M10_P128K_C64K_W8K.nes create mode 100644 roms/M118_P128K_C64K.nes create mode 100644 roms/M180_P128K_H.nes create mode 100644 roms/M1_P128K_C128K_W8K.nes create mode 100644 roms/M28_P512K.nes create mode 100644 roms/M2_P128K_V.nes create mode 100644 roms/M34_P128K_H.nes create mode 100644 roms/M3_P32K_C32K_H.nes create mode 100644 roms/M4_P256K_C256K.nes create mode 100644 roms/M66_P64K_C16K_V.nes create mode 100644 roms/M69_P128K_C64K_W8K.nes create mode 100644 roms/M78.3_P128K_C64K.nes create mode 100644 roms/M7_P128K.nes create mode 100644 roms/M9_P128K_C64K.nes diff --git a/firmware/source/buffer.c b/firmware/source/buffer.c index 70e857c..daf8ba1 100644 --- a/firmware/source/buffer.c +++ b/firmware/source/buffer.c @@ -1,5 +1,12 @@ #include "buffer.h" +//used to communicate to usbFunctionWrite which buffer object +//it should be filling +buffer *cur_usb_load_buff; +//used to determine number of bytes left to finish current +//OUT transfer utilized by usbFunctionWrite +//uint16_t incoming_bytes_remain; +uint8_t incoming_bytes_remain; //min define of two buffers static buffer buff0; diff --git a/firmware/source/buffer.h b/firmware/source/buffer.h index 3da2194..871ad00 100644 --- a/firmware/source/buffer.h +++ b/firmware/source/buffer.h @@ -31,12 +31,5 @@ uint8_t * buffer_payload( setup_packet *spacket, buffer *buff, uint8_t hostsetbu void update_buffers(); -//used to communicate to usbFunctionWrite which buffer object -//it should be filling -buffer *cur_usb_load_buff; -//used to determine number of bytes left to finish current -//OUT transfer utilized by usbFunctionWrite -//uint16_t incoming_bytes_remain; -uint8_t incoming_bytes_remain; #endif diff --git a/firmware/source/logic.h b/firmware/source/logic.h index 3c9a268..40cefcd 100644 --- a/firmware/source/logic.h +++ b/firmware/source/logic.h @@ -1,17 +1,6 @@ #ifndef _logic_h #define _logic_h -#define LO 0x00 -#define HI 0xFF -//DDR values -#define IP 0x00 -#define OP 0xFF - -#define FALSE 0x00 -//TRUE is any value besides zero - -//used to indicate when intentionally passing zero because option not used -#define NILL 0x00 #endif diff --git a/firmware/source/pinport.h b/firmware/source/pinport.h index f77aac1..e49a397 100644 --- a/firmware/source/pinport.h +++ b/firmware/source/pinport.h @@ -177,6 +177,14 @@ void software_AXL_CLK(); // used for a very short delay #define NOP() do { __asm__ __volatile__ ("nop"); } while (0) +//PORT wide set/clear +#define LO 0x00 +#define HI 0xFF + +//DDR values +#define IP 0x00 +#define OP 0xFF + //============================ //ADDR[7:0] PORTA //============================ diff --git a/firmware/source/usb.c b/firmware/source/usb.c index 46949fa..10a3d6c 100644 --- a/firmware/source/usb.c +++ b/firmware/source/usb.c @@ -44,6 +44,9 @@ static uint8_t usbWrite_status; USB_PUBLIC usbMsgLen_t usbFunctionSetup(uchar data[8]) { + //defined and controled by buffer.c + extern buffer *cur_usb_load_buff; + //cast incoming data into the the usb setup packet it is setup_packet *spacket = (void *)data; @@ -93,7 +96,7 @@ USB_PUBLIC usbMsgLen_t usbFunctionSetup(uchar data[8]) { switch(spacket->bRequest) { - case PINPORT: + case DICT_PINPORT: switch (spacket->opcode) { case PP_OPCODE_ONLY_MIN ... PP_OPCODE_ONLY_MAX: rv[RV_ERR_IDX] = pinport_opcode_only( spacket->opcode ); @@ -119,7 +122,7 @@ USB_PUBLIC usbMsgLen_t usbFunctionSetup(uchar data[8]) { } break; //end of PINPORT - case IO: + case DICT_IO: switch (spacket->opcode) { case IO_OPCODE_ONLY_MIN ... IO_OPCODE_ONLY_MAX: rv[RV_ERR_IDX] = io_opcode_only( spacket->opcode ); @@ -134,7 +137,7 @@ USB_PUBLIC usbMsgLen_t usbFunctionSetup(uchar data[8]) { } break; //end of IO - case NES: + case DICT_NES: switch (spacket->opcode) { case NES_OPCODE_24BOP_MIN ... NES_OPCODE_24BOP_MAX: rv[RV_ERR_IDX] = nes_opcode_24b_operand( spacket->opcode, @@ -150,7 +153,7 @@ USB_PUBLIC usbMsgLen_t usbFunctionSetup(uchar data[8]) { } break; //end of NES - case SNES: + case DICT_SNES: switch (spacket->opcode) { case SNES_OPCODE_24BOP_MIN ... SNES_OPCODE_24BOP_MAX: rv[RV_ERR_IDX] = snes_opcode_24b_operand( spacket->opcode, @@ -166,12 +169,12 @@ USB_PUBLIC usbMsgLen_t usbFunctionSetup(uchar data[8]) { } break; //end of SNES - case BUFFER: + case DICT_BUFFER: //just give buffer.c the setup packet and let it figure things out for itself usbMsgPtr = (usbMsgPtr_t)buffer_usb_call( spacket, rv, &rlen ); break; //end of BUFFER - case USB: + case DICT_USB: //currently just a simple way to read back usbFunctionWrite status SUCCESS/ERROR //if there are future status' to read back may have to create some functions rv[RV_ERR_IDX] = SUCCESS; @@ -266,6 +269,10 @@ USB_PUBLIC usbMsgLen_t usbFunctionSetup(uchar data[8]) { //#define MAKECHECKS 0 USB_PUBLIC uchar usbFunctionWrite(uchar *data, uchar len) { + + //defined and controled by buffer.c + extern buffer *cur_usb_load_buff; + extern uint8_t incoming_bytes_remain; uint8_t data_cur = 0; //current incoming byte to copy uint8_t buf_cur = cur_usb_load_buff->cur_byte; //current buffer byte diff --git a/host/source/cartridge.c b/host/source/cartridge.c index 88ce426..eb12a7d 100644 --- a/host/source/cartridge.c +++ b/host/source/cartridge.c @@ -1,5 +1,43 @@ #include "cartridge.h" +//init all cart elements to UNKNOWN +//allocate memory for memory elements +int init_cart_elements( cartridge *cart ) +{ + cart->console = UNKNOWN; + cart->mapper = UNKNOWN; + cart->submap = UNKNOWN; + cart->mapvariant = UNKNOWN; + cart->manf = UNKNOWN; + cart->product = UNKNOWN; + cart->mirroring = UNKNOWN; + cart->sound = UNKNOWN; + + cart->pri_rom = malloc( sizeof(memory)); + check_mem(cart->pri_rom); + init_memory_elements(cart->pri_rom); + + cart->sec_rom = malloc( sizeof(memory)); + check_mem(cart->sec_rom); + init_memory_elements(cart->sec_rom); + + cart->save_mem = malloc( sizeof(memory)); + check_mem(cart->save_mem); + init_memory_elements(cart->save_mem); + + cart->aux_mem = malloc( sizeof(memory)); + check_mem(cart->aux_mem); + init_memory_elements(cart->aux_mem); + + cart->logic_mem = malloc( sizeof(memory)); + check_mem(cart->logic_mem); + init_memory_elements(cart->logic_mem); + + return SUCCESS; +error: + return ~SUCCESS; +} + int detect_console( cartridge *cart, USBtransfer *transfer ) { printf("attempting to detect cartridge...\n"); @@ -92,3 +130,17 @@ error: //INL SNES boards memory mapping is controlled by /RESET pin //roms are still visible when /RESET low, but SRAM isn't + +int detect_mirroring( cartridge *cart, USBtransfer *transfer ) +{ + + if ( cart->console == NES_CART ) { + //For now just assume mirroring is fixed until start adding support for other mappers + cart->mirroring = MIR_FIXED; + } + + return SUCCESS; + +//error: +// return -1; +} diff --git a/host/source/cartridge.h b/host/source/cartridge.h index 2a61e25..f60a51e 100644 --- a/host/source/cartridge.h +++ b/host/source/cartridge.h @@ -6,7 +6,6 @@ #include #include #include -#include //include prior to other file includes //that way DEBUG can be turned on/off for this file alone @@ -19,11 +18,12 @@ #include "shared_errors.h" #include "shared_dictionaries.h" #include "dictionary.h" -#include "types.h" +#include "enums.h" #include "io.h" #include "nes.h" #include "snes.h" +#include "memory.h" //cartridge object/struct typedef struct cartridge{ @@ -39,17 +39,13 @@ typedef struct cartridge{ 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 + memory *logic_mem; //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 init_cart_elements( cartridge *cart ); int detect_console( cartridge *cart, USBtransfer *transfer ); +int detect_mirroring( cartridge *cart, USBtransfer *transfer ); #endif diff --git a/host/source/dictionary.c b/host/source/dictionary.c index ed4a3cb..e7c3d43 100644 --- a/host/source/dictionary.c +++ b/host/source/dictionary.c @@ -68,7 +68,7 @@ int dictionary_call_print_option( int print_debug, USBtransfer *transfer, uint8_ dictionary, opcode, opcode, addr, miscdata); } switch (dictionary) { - case PINPORT: debug("dict: PINPORT"); + case DICT_PINPORT: debug("dict: PINPORT"); //transfer->wLength = 1; switch (opcode) { case PP_OPCODE_ONLY_MIN ... PP_OPCODE_ONLY_MAX: @@ -92,7 +92,7 @@ int dictionary_call_print_option( int print_debug, USBtransfer *transfer, uint8_ } break; //end of PINPORT - case IO: debug("dict: IO"); + case DICT_IO: debug("dict: IO"); // transfer->wLength = 1; switch (opcode) { case IO_OPCODE_ONLY_MIN ... IO_OPCODE_ONLY_MAX: @@ -107,7 +107,7 @@ int dictionary_call_print_option( int print_debug, USBtransfer *transfer, uint8_ } break; //end of IO - case NES: debug("dict: NES"); + case DICT_NES: debug("dict: NES"); // transfer->wLength = 1; switch (opcode) { case NES_OPCODE_24BOP_MIN ... NES_OPCODE_24BOP_MAX: @@ -122,7 +122,7 @@ int dictionary_call_print_option( int print_debug, USBtransfer *transfer, uint8_ } break; //end of NES - case SNES: debug("dict: SNES"); + case DICT_SNES: debug("dict: SNES"); // transfer->wLength = 1; switch (opcode) { case SNES_OPCODE_24BOP_MIN ... SNES_OPCODE_24BOP_MAX: @@ -137,14 +137,14 @@ int dictionary_call_print_option( int print_debug, USBtransfer *transfer, uint8_ } break; //end of SNES - case BUFFER: debug("dict: BUFFER"); + case DICT_BUFFER: debug("dict: BUFFER"); // transfer->wLength = length; if (buffer != NULL) { transfer->data = (unsigned char *)buffer; } break; //end of BUFF - case USB: debug("dict: USB"); + case DICT_USB: debug("dict: USB"); // transfer->wLength = length; break; diff --git a/host/source/enums.h b/host/source/enums.h new file mode 100644 index 0000000..1fba389 --- /dev/null +++ b/host/source/enums.h @@ -0,0 +1,23 @@ +#ifndef _enums_h +#define _enums_h + +//One concise place to list all enums used for setting cartridge and memory elements + +//used to denote when any cartridge element is not known +#define UNKNOWN -1 + +//console options +#define NES_CART 'N' +#define FC_CART 'F' +#define SNES_CART 'S' +#define BKWD_CART 'B' + +enum mirroring { + MIR_FIXED = 10, + MIR_ANROM, + MIR_MMC1, + MIR_MMC3 +}; + + +#endif diff --git a/host/source/erase.c b/host/source/erase.c index 0c256f9..8fa7c87 100644 --- a/host/source/erase.c +++ b/host/source/erase.c @@ -2,39 +2,45 @@ int erase_nes( USBtransfer *transfer ) { + //uint8_t rv[8]; + //int i = 0; - debug("erasing"); + debug("erasing_nrom"); + + io_reset(transfer); + + //for NROM flashing first verify EXP0 pull up will clock /WE properly + check( !exp0_pullup_test(transfer), "EXP0 pullup test failed can't erase PRG-ROM" ); + + nes_init(transfer); - dictionary_call( transfer, IO, IO_RESET, 0, 0, USB_IN, NULL, 1); - dictionary_call( transfer, IO, NES_INIT, 0, 0, USB_IN, NULL, 1); - dictionary_call( transfer, IO, EXP0_PULLUP_TEST,0, 0, USB_IN, NULL, 1); - dictionary_call( transfer, NES, DISCRETE_EXP0_PRGROM_WR, 0x5555, 0xAA, USB_IN, NULL, 1); - dictionary_call( transfer, NES, DISCRETE_EXP0_PRGROM_WR, 0x2AAA, 0x55, USB_IN, NULL, 1); - dictionary_call( transfer, NES, DISCRETE_EXP0_PRGROM_WR, 0x5555, 0x80, USB_IN, NULL, 1); - dictionary_call( transfer, NES, DISCRETE_EXP0_PRGROM_WR, 0x5555, 0xAA, USB_IN, NULL, 1); - dictionary_call( transfer, NES, DISCRETE_EXP0_PRGROM_WR, 0x2AAA, 0x55, USB_IN, NULL, 1); - dictionary_call( transfer, NES, DISCRETE_EXP0_PRGROM_WR, 0x5555, 0x10, USB_IN, NULL, 1); - dictionary_call( transfer, NES, NES_CPU_RD, 0x8000, 0, USB_IN, NULL, 2); - dictionary_call( transfer, NES, NES_CPU_RD, 0x8000, 0, USB_IN, NULL, 2); - dictionary_call( transfer, NES, NES_CPU_RD, 0x8000, 0, USB_IN, NULL, 2); - dictionary_call( transfer, NES, NES_CPU_RD, 0x8000, 0, USB_IN, NULL, 2); - dictionary_call( transfer, NES, NES_CPU_RD, 0x8000, 0, USB_IN, NULL, 2); - dictionary_call( transfer, NES, NES_CPU_RD, 0x8000, 0, USB_IN, NULL, 2); - dictionary_call( transfer, NES, NES_CPU_RD, 0x8000, 0, USB_IN, NULL, 2); - dictionary_call( transfer, NES, NES_CPU_RD, 0x8000, 0, USB_IN, NULL, 2); - dictionary_call( transfer, NES, NES_CPU_RD, 0x8000, 0, USB_IN, NULL, 2); - dictionary_call( transfer, NES, NES_CPU_RD, 0x8000, 0, USB_IN, NULL, 2); - dictionary_call( transfer, NES, NES_CPU_RD, 0x8000, 0, USB_IN, NULL, 2); - dictionary_call( transfer, NES, NES_CPU_RD, 0x8000, 0, USB_IN, NULL, 2); - dictionary_call( transfer, NES, NES_CPU_RD, 0x8000, 0, USB_IN, NULL, 2); - dictionary_call( transfer, NES, NES_CPU_RD, 0x8000, 0, USB_IN, NULL, 2); - dictionary_call( transfer, NES, NES_CPU_RD, 0x8000, 0, USB_IN, NULL, 2); - dictionary_call( transfer, NES, NES_CPU_RD, 0x8000, 0, USB_IN, NULL, 2); - dictionary_call( transfer, NES, NES_CPU_RD, 0x8000, 0, USB_IN, NULL, 2); - dictionary_call( transfer, NES, NES_CPU_RD, 0x8000, 0, USB_IN, NULL, 2); - dictionary_call( transfer, NES, NES_CPU_RD, 0x8000, 0, USB_IN, NULL, 2); - dictionary_call( transfer, NES, NES_CPU_RD, 0x8000, 0, USB_IN, NULL, 2); + dictionary_call_debug( transfer, DICT_NES, DISCRETE_EXP0_PRGROM_WR, 0x5555, 0xAA, USB_IN, NULL, 1); + dictionary_call_debug( transfer, DICT_NES, DISCRETE_EXP0_PRGROM_WR, 0x2AAA, 0x55, USB_IN, NULL, 1); + dictionary_call_debug( transfer, DICT_NES, DISCRETE_EXP0_PRGROM_WR, 0x5555, 0x80, USB_IN, NULL, 1); + dictionary_call_debug( transfer, DICT_NES, DISCRETE_EXP0_PRGROM_WR, 0x5555, 0xAA, USB_IN, NULL, 1); + dictionary_call_debug( transfer, DICT_NES, DISCRETE_EXP0_PRGROM_WR, 0x2AAA, 0x55, USB_IN, NULL, 1); + dictionary_call_debug( transfer, DICT_NES, DISCRETE_EXP0_PRGROM_WR, 0x5555, 0x10, USB_IN, NULL, 1); + dictionary_call_debug( transfer, DICT_NES, NES_CPU_RD, 0x8000, 0, USB_IN, NULL, 2); + dictionary_call_debug( transfer, DICT_NES, NES_CPU_RD, 0x8000, 0, USB_IN, NULL, 2); + dictionary_call_debug( transfer, DICT_NES, NES_CPU_RD, 0x8000, 0, USB_IN, NULL, 2); + dictionary_call_debug( transfer, DICT_NES, NES_CPU_RD, 0x8000, 0, USB_IN, NULL, 2); + dictionary_call_debug( transfer, DICT_NES, NES_CPU_RD, 0x8000, 0, USB_IN, NULL, 2); + dictionary_call_debug( transfer, DICT_NES, NES_CPU_RD, 0x8000, 0, USB_IN, NULL, 2); + dictionary_call_debug( transfer, DICT_NES, NES_CPU_RD, 0x8000, 0, USB_IN, NULL, 2); + dictionary_call_debug( transfer, DICT_NES, NES_CPU_RD, 0x8000, 0, USB_IN, NULL, 2); + dictionary_call_debug( transfer, DICT_NES, NES_CPU_RD, 0x8000, 0, USB_IN, NULL, 2); + dictionary_call_debug( transfer, DICT_NES, NES_CPU_RD, 0x8000, 0, USB_IN, NULL, 2); + dictionary_call_debug( transfer, DICT_NES, NES_CPU_RD, 0x8000, 0, USB_IN, NULL, 2); + dictionary_call_debug( transfer, DICT_NES, NES_CPU_RD, 0x8000, 0, USB_IN, NULL, 2); + dictionary_call_debug( transfer, DICT_NES, NES_CPU_RD, 0x8000, 0, USB_IN, NULL, 2); + dictionary_call_debug( transfer, DICT_NES, NES_CPU_RD, 0x8000, 0, USB_IN, NULL, 2); + dictionary_call_debug( transfer, DICT_NES, NES_CPU_RD, 0x8000, 0, USB_IN, NULL, 2); + dictionary_call_debug( transfer, DICT_NES, NES_CPU_RD, 0x8000, 0, USB_IN, NULL, 2); + dictionary_call_debug( transfer, DICT_NES, NES_CPU_RD, 0x8000, 0, USB_IN, NULL, 2); + dictionary_call_debug( transfer, DICT_NES, NES_CPU_RD, 0x8000, 0, USB_IN, NULL, 2); + dictionary_call_debug( transfer, DICT_NES, NES_CPU_RD, 0x8000, 0, USB_IN, NULL, 2); + dictionary_call_debug( transfer, DICT_NES, NES_CPU_RD, 0x8000, 0, USB_IN, NULL, 2); //dictionary_call( transfer, IO, IO_RESET, 0, 0); //dictionary_call( transfer, IO, NES_INIT, 0, 0); @@ -90,5 +96,6 @@ int erase_nes( USBtransfer *transfer ) return 0; - +error: + return -1; } diff --git a/host/source/erase.h b/host/source/erase.h index a8d1c03..0f9b799 100644 --- a/host/source/erase.h +++ b/host/source/erase.h @@ -19,6 +19,7 @@ #include "shared_errors.h" #include "shared_dictionaries.h" #include "dictionary.h" +#include "io.h" int erase_nes( USBtransfer *transfer ); diff --git a/host/source/file.c b/host/source/file.c index 76796db..fab6976 100644 --- a/host/source/file.c +++ b/host/source/file.c @@ -4,44 +4,47 @@ #define SIZE_PRG_BANK 16384 #define SIZE_CHR_BANK 8192 -int detect_file( rom_image *rom_info, char *filename ) +//Need to pass in pointer to a filepointer to properly pass by reference +//the OS/stdio creates a FILE struct and returns the address of that struct +//so when this function opens a file it's setting the value of a pointer +//for the calling function. To set a pointer we must have a pointer to that pointer.. +int open_file( FILE **fptr, char *filename ) +{ + //first open file + *fptr = fopen( filename, "rb"); + //returns file ptr on success, NULL on fail + check( *fptr, "Unable to open file: %s in read binary mode", filename); + + return SUCCESS; +error: + return -1; +} + +int detect_file( rom_image *rom ) { int rv = 0; -// int index = 0; - FILE *fileptr = NULL; -//warn uint8_t data[128]; - - //first open file - fileptr = fopen( filename, "rb"); - //returns file ptr on success, NULL on fail - check( fileptr, "Unable to open file: %s in read binary mode", filename); - - //then determine file type uint8_t header[SIZE_NES_HEADER]; - //size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream); - rv = fread( header, sizeof(header[0]), (sizeof(header)/sizeof(header[0])), fileptr); - check( rv = sizeof(header), "Unable to read NES header"); - //for ( index = 0; index < SIZE_NES_HEADER; index++ ) { - // debug("header byte #%d = h%x c%c", index, header[index], header[index]); - //} + //size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream); + rv = fread( header, sizeof(header[0]), (sizeof(header)/sizeof(header[0])), rom->fileptr); + check( rv = sizeof(header), "Unable to read NES header"); //0-3: Constant $4E $45 $53 $1A ("NES" followed by MS-DOS end-of-file) if ( (header[0]=='N') && (header[1]=='E') && (header[2]=='S') && (header[3]==0x1A) ) { debug("detected ines header"); - rom_info->console = NES_CART; + rom->console = NES_CART; } else { debug("only ines files currently accepted as input"); goto error; } //4: Size of PRG ROM in 16 KB units - rom_info->prg_size = header[4] * SIZE_PRG_BANK; - debug("PRG ROM size= %d", rom_info->prg_size); + rom->prg_size = header[4] * SIZE_PRG_BANK; + debug("PRG ROM size= %d", rom->prg_size); //5: Size of CHR ROM in 8 KB units (Value 0 means the board uses CHR RAM) - rom_info->chr_size = header[5] * SIZE_CHR_BANK; - debug("CHR ROM size= %d", rom_info->chr_size); + rom->chr_size = header[5] * SIZE_CHR_BANK; + debug("CHR ROM size= %d", rom->chr_size); //6: Flags 6 // 76543210 @@ -52,11 +55,12 @@ int detect_file( rom_image *rom_info, char *filename ) // |||| |+-- 1: Cartridge contains battery-backed PRG RAM ($6000-7FFF) or other persistent memory // |||| +--- 1: 512-byte trainer at $7000-$71FF (stored before PRG data) // ++++----- Lower nybble of mapper number - rom_info->mapper = (header[6]>>4); - rom_info->mapper |= (header[7] & 0xF0); - debug("mapper #%d", rom_info->mapper); - rom_info->mirroring = header[6] & 0x09; //0b0000 1001 - debug("mirroring:%x", rom_info->mirroring); + rom->mapper = (header[6]>>4); + rom->mapper |= (header[7] & 0xF0); + debug("mapper #%d", rom->mapper); + rom->mirroring = header[6] & 0x09; //0b0000 1001 + debug("mirroring:%x", rom->mirroring); + //7: Flags 7 // 76543210 // |||||||| @@ -70,18 +74,7 @@ int detect_file( rom_image *rom_info, char *filename ) //10: Flags 10 (unofficial) //11-15: Zero filled - //close file - check( fclose(fileptr) == SUCCESS, "Unable to close file"); - fileptr = NULL; - - return 0; - + return SUCCESS; error: - - if (fileptr) { - fclose(fileptr); - } - return -1; - } diff --git a/host/source/file.h b/host/source/file.h index 21febb8..4d9ca7c 100644 --- a/host/source/file.h +++ b/host/source/file.h @@ -27,8 +27,10 @@ typedef struct rom_image{ int ram_size; int battery; int mirroring; + FILE *fileptr; } rom_image; -int detect_file( rom_image *rom_info, char *filename ); +int open_file( FILE **fptr, char *filename ); +int detect_file( rom_image *rom ); #endif diff --git a/host/source/inlprog.c b/host/source/inlprog.c index 6be8cb7..395765f 100644 --- a/host/source/inlprog.c +++ b/host/source/inlprog.c @@ -19,6 +19,7 @@ #include "test.h" #include "cartridge.h" #include "file.h" +#include "enums.h" int main(int argc, char *argv[]) @@ -147,12 +148,18 @@ int main(int argc, char *argv[]) //create USBtransfer struct to hold all transfer info USBtransfer *transfer = malloc( sizeof(USBtransfer)); - check_mem(transfer); - //create usb device handle pointer to interact with retro-prog //libusb_device_handle *rprog_handle = NULL; transfer->handle = NULL; + //create file object/struct + rom_image *rom = malloc( sizeof(rom_image)); + rom->fileptr = NULL; + + check_mem(transfer); + check_mem(rom); + + //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 @@ -182,29 +189,37 @@ int main(int argc, char *argv[]) cartridge *cart = malloc( sizeof(cartridge)); check_mem(cart); - //attempt to detect board inserted in device - cart->console = UNKNOWN; + //set all cart elements to UNKNOWN + init_cart_elements(cart); + // -x flag turns off all autodection if (!x_flag) { + //attempt to detect board inserted in device check(!detect_console( cart, transfer ), "Problem detecting cartridge."); + + //detect mapper as much as possible + //TODO first step is mirroring for NES boards + check(!detect_mirroring( cart, transfer ), "Problem detecting cart mirroring."); + + //TODO first step for SNES is mapping mode + + //By this point we know a lot about the cartridge but for things like NES discrete + //mappers we'll have to play around with the memory to determine exact mapper + //detect board manufacturer/flash memories as much as possible + + //detect rom sizes as much as possible + } else { printf("auto-detection turned off\n"); } - //detect mapper as much as possible - - //detect board manufacturer/flash memories as much as possible - - //detect rom sizes as much as possible - //read in user files/args that glean info about expected board - //create file object/struct - rom_image *rom_info = malloc( sizeof(rom_image)); - check_mem(rom_info); + //for now just assume user file/args are correct if ( p_value != NULL ) { //program file provided at commandline - detect_file( rom_info, p_value ); + check( !open_file( &rom->fileptr, p_value ), "Problem opening file %s", p_value); + detect_file( rom ); } //compare detections to user args and get permission to continue if there are discrepencies @@ -214,7 +229,7 @@ int main(int argc, char *argv[]) //erase required sectors of flash //forced to erase board regardless of current status - if (e_flag) { + if (e_flag || p_value) { erase_nes( transfer ); } @@ -248,7 +263,7 @@ int main(int argc, char *argv[]) } printf("\n"); transfer->endpoint = USB_IN; - transfer->request = PINPORT; + transfer->request = DICT_PINPORT; if (o_flag) transfer->wValueLSB = LED_ON; if (n_flag) transfer->wValueLSB = LED_OFF; transfer->data = rbuf; @@ -268,11 +283,21 @@ int main(int argc, char *argv[]) close: close_usb( context, transfer->handle); + + if(rom->fileptr != NULL){ + //close file + fclose(rom->fileptr); + } return 0; error: - printf("main program went to error\n"); +// printf("main program went to error\n"); +// +// close_usb( context, transfer->handle); +// if(rom->fileptr != NULL){ +// fclose(rom->fileptr); +// } return 1; diff --git a/host/source/io.c b/host/source/io.c index 266f2f8..b82b01d 100644 --- a/host/source/io.c +++ b/host/source/io.c @@ -7,7 +7,7 @@ */ void io_reset( USBtransfer *transfer ) { - dictionary_call( transfer, IO, IO_RESET, 0, 0, + dictionary_call( transfer, DICT_IO, IO_RESET, 0, 0, USB_IN, NULL, 1); } @@ -18,7 +18,7 @@ void io_reset( USBtransfer *transfer ) */ void nes_init( USBtransfer *transfer ) { - dictionary_call( transfer, IO, NES_INIT, 0, 0, + dictionary_call( transfer, DICT_IO, NES_INIT, 0, 0, USB_IN, NULL, 1); } @@ -30,8 +30,52 @@ void nes_init( USBtransfer *transfer ) */ void snes_init( USBtransfer *transfer ) { - dictionary_call( transfer, IO, SNES_INIT, 0, 0, + dictionary_call( transfer, DICT_IO, SNES_INIT, 0, 0, USB_IN, NULL, 1); } +/* Desc:test EXP0 pullup and determine now many avr cpu cycles it takes to go high + * Pre: io_reset + * Post:EXP0 left as pullup + * Rtn: number of extra AVR cpu cycles it took to pullup EXP0 + * SUCCESS = 0 which means pullup was immediate + * returns negative number on error + */ +int exp0_pullup_test( USBtransfer *transfer ) +{ + uint8_t rv[RETURN_BUFF_SIZE]; + int i = 0; + + //call EXP0 test command + dictionary_call( transfer, DICT_IO, EXP0_PULLUP_TEST, NILL, NILL, USB_IN, + rv, RETURN_BUFF_SIZE); + //return value first gives error/succes of opcode call + //data first gives mask for EXP0 pin + //then gives result of successive byte wide reads to be masked + check( (rv[RV_ERR_IDX] == SUCCESS), "Device error calling EXP0 pullup test opcode" ) + + if ( rv[RV_DATA0_IDX] & rv[RV_DATA0_IDX+1] ) { + //mask out EXP0 bit, and EXP0 was set on first read after pullup + return SUCCESS; + } else if ( (rv[RV_DATA0_IDX] & rv[RV_DATA_MAX_IDX]) == 0 ) { + //last read didn't have EXP0 high fail + return GEN_FAIL; + }else { + //determine how many cycles it took for EXP0 to go high + for( i=RV_DATA0_IDX+2; i<=RV_DATA_MAX_IDX; i++) { + //debug("index %d", i); + if ( rv[RV_DATA0_IDX] & rv[RV_DATA0_IDX+i] ) { + return i-1; + } + } + } + + //shouldn't be here.. + sentinel("EXP0 test failed to check results proplerly"); + +error: + return -1; + +} + diff --git a/host/source/io.h b/host/source/io.h index 4a809aa..77bf2e9 100644 --- a/host/source/io.h +++ b/host/source/io.h @@ -22,5 +22,6 @@ void io_reset( USBtransfer *transfer ); void nes_init( USBtransfer *transfer ); void snes_init( USBtransfer *transfer ); +int exp0_pullup_test( USBtransfer *transfer ); #endif diff --git a/host/source/memory.c b/host/source/memory.c new file mode 100644 index 0000000..cdb48ee --- /dev/null +++ b/host/source/memory.c @@ -0,0 +1,14 @@ +#include "memory.h" + +void init_memory_elements( memory *mem ) +{ + mem->manf = UNKNOWN; + mem->part = UNKNOWN; + mem->volatility = UNKNOWN; + mem->size = UNKNOWN; + mem->addr_size = UNKNOWN; + mem->width = UNKNOWN; + mem->protocol = UNKNOWN; + mem->sector_size = UNKNOWN; +} + diff --git a/host/source/memory.h b/host/source/memory.h new file mode 100644 index 0000000..55db6f0 --- /dev/null +++ b/host/source/memory.h @@ -0,0 +1,39 @@ +#ifndef _memory_h +#define _memory_h + +#include +#include +#include +#include +#include + +//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 "enums.h" + + +//memory object/struct +typedef struct memory{ + int manf; + int part; + int volatility; //sram no batt vs batt, mask rom, erasability, etc + int size; //size of the actual memory excluding grounded address pins etc + int addr_size; //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; + +void init_memory_elements( memory *mem ); + + +#endif diff --git a/host/source/nes.c b/host/source/nes.c index b9edb93..6bd2123 100644 --- a/host/source/nes.c +++ b/host/source/nes.c @@ -11,10 +11,10 @@ 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, + dictionary_call( transfer, DICT_PINPORT, ADDRH_SET, 0, 0, USB_IN, NULL, 1); //read CIRAM /CE pin - dictionary_call( transfer, PINPORT, CICE_RD, 0, 0, + dictionary_call( transfer, DICT_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] @@ -26,10 +26,10 @@ int jumper_ciramce_ppuA13n( USBtransfer *transfer ) } //set PPU /A13 high - dictionary_call( transfer, PINPORT, ADDRH_SET, PPU_A13N_MSK, 0, + dictionary_call( transfer, DICT_PINPORT, ADDRH_SET, PPU_A13N_MSK, 0, USB_IN, NULL, 1); //read CIRAM /CE pin - dictionary_call( transfer, PINPORT, CICE_RD, 0, 0, + dictionary_call( transfer, DICT_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] @@ -58,10 +58,10 @@ 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, + dictionary_call( transfer, DICT_PINPORT, ADDRH_SET, 0, 0, USB_IN, NULL, 1); //read CIRAM /CE pin - dictionary_call( transfer, PINPORT, CICE_RD, 0, 0, + dictionary_call( transfer, DICT_PINPORT, CICE_RD, 0, 0, USB_IN, rv, RV_DATA0_IDX+1); // CIRAM /CE should be high if inverted A13 is what drives it @@ -72,10 +72,10 @@ int ciramce_inv_ppuA13( USBtransfer *transfer ) } //check that we can clear CIRAM /CE with PPU /A13 high - dictionary_call( transfer, PINPORT, ADDRH_SET, PPU_A13_MSK, 0, + dictionary_call( transfer, DICT_PINPORT, ADDRH_SET, PPU_A13_MSK, 0, USB_IN, NULL, 1); //read CIRAM /CE pin - dictionary_call( transfer, PINPORT, CICE_RD, 0, 0, + dictionary_call( transfer, DICT_PINPORT, CICE_RD, 0, 0, USB_IN, rv, RV_DATA0_IDX+1); // CIRAM /CE should be low if inverted A13 is what drives it @@ -120,41 +120,41 @@ int famicom_sound( USBtransfer *transfer ) //but don't leave it enabled before exiting function //set AXLOE to output - dictionary_call( transfer, PINPORT, AXLOE_OP, 0, 0, + dictionary_call( transfer, DICT_PINPORT, AXLOE_OP, 0, 0, USB_IN, NULL, 1); //enable EXP FF - dictionary_call( transfer, PINPORT, EXPFF_OP, 0, 0, + dictionary_call( transfer, DICT_PINPORT, EXPFF_OP, 0, 0, USB_IN, NULL, 1); //Latch low first - dictionary_call( transfer, PINPORT, ADDRX_SET, 0, 0, + dictionary_call( transfer, DICT_PINPORT, ADDRX_SET, 0, 0, USB_IN, NULL, 1); //read EXP0 Famicom APU audio pin - dictionary_call( transfer, PINPORT, FC_APU_RD, 0, 0, + dictionary_call( transfer, DICT_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, + dictionary_call( transfer, DICT_PINPORT, EXPFF_FLT, 0, 0, USB_IN, NULL, 1); //retun AXLOE to input - dictionary_call( transfer, PINPORT, AXLOE_IP, 0, 0, + dictionary_call( transfer, DICT_PINPORT, AXLOE_IP, 0, 0, USB_IN, NULL, 1); return FALSE; } //Latch pin high - dictionary_call( transfer, PINPORT, ADDRX_SET, FC_RF_MSK, 0, + dictionary_call( transfer, DICT_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, + dictionary_call( transfer, DICT_PINPORT, FC_APU_RD, 0, 0, USB_IN, rv, RV_DATA0_IDX+1); //disable EXP FF - dictionary_call( transfer, PINPORT, EXPFF_FLT, 0, 0, + dictionary_call( transfer, DICT_PINPORT, EXPFF_FLT, 0, 0, USB_IN, NULL, 1); //retun AXLOE to input - dictionary_call( transfer, PINPORT, AXLOE_IP, 0, 0, + dictionary_call( transfer, DICT_PINPORT, AXLOE_IP, 0, 0, USB_IN, NULL, 1); //mask pin from byte diff --git a/host/source/snes.c b/host/source/snes.c index f62b401..1c49d21 100644 --- a/host/source/snes.c +++ b/host/source/snes.c @@ -10,13 +10,13 @@ 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, + dictionary_call( transfer, DICT_PINPORT, ADDR24_SET, addr, bank, USB_IN, NULL, 1); //ensure data bus is pulled up - dictionary_call( transfer, PINPORT, DATA_HI, 0, 0, + dictionary_call( transfer, DICT_PINPORT, DATA_HI, 0, 0, USB_IN, NULL, 1); //read data bus - dictionary_call_debug( transfer, PINPORT, DATA_RD, 0, 0, + dictionary_call_debug( transfer, DICT_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"); @@ -24,21 +24,21 @@ int snes_mem_visible( USBtransfer *transfer, uint8_t bank, uint16_t addr ) } //enable rom control signals - dictionary_call( transfer, PINPORT, SRST_HI, 0, 0, + dictionary_call( transfer, DICT_PINPORT, SRST_HI, 0, 0, USB_IN, NULL, 1); - dictionary_call( transfer, PINPORT, CSRD_LO, 0, 0, + dictionary_call( transfer, DICT_PINPORT, CSRD_LO, 0, 0, USB_IN, NULL, 1); - dictionary_call( transfer, PINPORT, ROMSEL_LO, 0, 0, + dictionary_call( transfer, DICT_PINPORT, ROMSEL_LO, 0, 0, USB_IN, NULL, 1); //read data bus - dictionary_call_debug( transfer, PINPORT, DATA_RD, 0, 0, + dictionary_call_debug( transfer, DICT_PINPORT, DATA_RD, 0, 0, USB_IN, rv, RV_DATA0_IDX+1); //clear data bus - dictionary_call( transfer, PINPORT, SRST_LO, 0, 0, + dictionary_call( transfer, DICT_PINPORT, SRST_LO, 0, 0, USB_IN, NULL, 1); - dictionary_call( transfer, PINPORT, CSRD_HI, 0, 0, + dictionary_call( transfer, DICT_PINPORT, CSRD_HI, 0, 0, USB_IN, NULL, 1); - dictionary_call( transfer, PINPORT, ROMSEL_HI, 0, 0, + dictionary_call( transfer, DICT_PINPORT, ROMSEL_HI, 0, 0, USB_IN, NULL, 1); if ( rv[RV_DATA0_IDX] != 0xFF ) { debug("Found memory with SNES control signals"); diff --git a/host/source/test.c b/host/source/test.c index 2696e4a..77d746f 100644 --- a/host/source/test.c +++ b/host/source/test.c @@ -4,36 +4,36 @@ int test_function( USBtransfer *transfer ) { debug("testing"); - dictionary_call( transfer, IO, IO_RESET, 0, 0, USB_IN, NULL, 1); - dictionary_call( transfer, IO, NES_INIT, 0, 0, USB_IN, NULL, 1); - dictionary_call( transfer, IO, EXP0_PULLUP_TEST, 0, 0, USB_IN, NULL, 8); + dictionary_call( transfer, DICT_IO, IO_RESET, 0, 0, USB_IN, NULL, 1); + dictionary_call( transfer, DICT_IO, NES_INIT, 0, 0, USB_IN, NULL, 1); + dictionary_call( transfer, DICT_IO, EXP0_PULLUP_TEST, 0, 0, USB_IN, NULL, 8); //dict opcode addr/index miscdata endpoint *buffer length debug("reset butters"); - dictionary_call( transfer, BUFFER, RAW_BUFFER_RESET, 0, 0, USB_IN, NULL, 1); - dictionary_call( transfer, BUFFER, RAW_BANK_STATUS, 0, 0, USB_IN, NULL, 2); + dictionary_call( transfer, DICT_BUFFER, RAW_BUFFER_RESET, 0, 0, USB_IN, NULL, 1); + dictionary_call( transfer, DICT_BUFFER, RAW_BANK_STATUS, 0, 0, USB_IN, NULL, 2); debug("get pri"); //id:basebank num32B banks - dictionary_call( transfer, BUFFER, GET_PRI_ELEMENTS, 0, 0, USB_IN, NULL, 8); - dictionary_call( transfer, BUFFER, GET_PRI_ELEMENTS, 0, 1, USB_IN, NULL, 8); + dictionary_call( transfer, DICT_BUFFER, GET_PRI_ELEMENTS, 0, 0, USB_IN, NULL, 8); + dictionary_call( transfer, DICT_BUFFER, GET_PRI_ELEMENTS, 0, 1, USB_IN, NULL, 8); // debug("get nonexistent 7"); //id:basebank num32B banks // dictionary_call( transfer, BUFFER, GET_PRI_ELEMENTS, 0, 7, USB_IN, NULL, 8); // dictionary_call( transfer, BUFFER, ALLOCATE_BUFFER7, 0x7008, 8, USB_IN, NULL, 1); // debug("get nonexistent 8"); //id:basebank num32B banks // dictionary_call( transfer, BUFFER, GET_PRI_ELEMENTS, 0, 8, USB_IN, NULL, 8); debug("allocate buff0 256B"); //id:basebank num32B banks - dictionary_call( transfer, BUFFER, ALLOCATE_BUFFER0, 0x1000, 8, USB_IN, NULL, 1); + dictionary_call( transfer, DICT_BUFFER, ALLOCATE_BUFFER0, 0x1000, 8, USB_IN, NULL, 1); debug("allocate buff2 0B"); //id:basebank num32B banks - dictionary_call( transfer, BUFFER, ALLOCATE_BUFFER1, 0x2008, 0, USB_IN, NULL, 1); + dictionary_call( transfer, DICT_BUFFER, ALLOCATE_BUFFER1, 0x2008, 0, USB_IN, NULL, 1); debug("allocate buff1 256B"); //id:basebank num32B banks - dictionary_call( transfer, BUFFER, ALLOCATE_BUFFER1, 0x2008, 8, USB_IN, NULL, 1); + dictionary_call( transfer, DICT_BUFFER, ALLOCATE_BUFFER1, 0x2008, 8, USB_IN, NULL, 1); debug("status"); //id:basebank num32B banks - dictionary_call( transfer, BUFFER, RAW_BANK_STATUS, 0, 0, USB_IN, NULL, 2); - dictionary_call( transfer, BUFFER, RAW_BANK_STATUS, 8, 0, USB_IN, NULL, 2); + dictionary_call( transfer, DICT_BUFFER, RAW_BANK_STATUS, 0, 0, USB_IN, NULL, 2); + dictionary_call( transfer, DICT_BUFFER, RAW_BANK_STATUS, 8, 0, USB_IN, NULL, 2); debug("get pri"); //id:basebank num32B banks - dictionary_call( transfer, BUFFER, GET_PRI_ELEMENTS, 0, 0, USB_IN, NULL, 8); - dictionary_call( transfer, BUFFER, GET_PRI_ELEMENTS, 0, 1, USB_IN, NULL, 8); + dictionary_call( transfer, DICT_BUFFER, GET_PRI_ELEMENTS, 0, 0, USB_IN, NULL, 8); + dictionary_call( transfer, DICT_BUFFER, GET_PRI_ELEMENTS, 0, 1, USB_IN, NULL, 8); debug("get sec"); //id:basebank num32B banks - dictionary_call( transfer, BUFFER, GET_SEC_ELEMENTS, 0, 0, USB_IN, NULL, 8); - dictionary_call( transfer, BUFFER, GET_SEC_ELEMENTS, 0, 1, USB_IN, NULL, 8); + dictionary_call( transfer, DICT_BUFFER, GET_SEC_ELEMENTS, 0, 0, USB_IN, NULL, 8); + dictionary_call( transfer, DICT_BUFFER, GET_SEC_ELEMENTS, 0, 1, USB_IN, NULL, 8); uint8_t load_in[256]; uint8_t load_out[256]; @@ -48,7 +48,7 @@ int test_function( USBtransfer *transfer ) printf("\n"); debug("read payload0 uninitialized"); - dictionary_call( transfer, BUFFER, BUFF_PAYLOAD0, 0, 0, USB_IN, load_in, 254); + dictionary_call( transfer, DICT_BUFFER, BUFF_PAYLOAD0, 0, 0, USB_IN, load_in, 254); //print load printf("load_in data:"); @@ -70,10 +70,10 @@ int test_function( USBtransfer *transfer ) printf("\n"); debug("send payload0"); - dictionary_call( transfer, BUFFER, BUFF_PAYLOAD0, 0, 0, USB_OUT, load_out, 254); + dictionary_call( transfer, DICT_BUFFER, BUFF_PAYLOAD0, 0, 0, USB_OUT, load_out, 254); debug("read payload0"); - dictionary_call( transfer, BUFFER, BUFF_PAYLOAD0, 0, 0, USB_IN, load_in, 254); + dictionary_call( transfer, DICT_BUFFER, BUFF_PAYLOAD0, 0, 0, USB_IN, load_in, 254); //print load printf("load_in data:"); @@ -82,13 +82,13 @@ int test_function( USBtransfer *transfer ) } printf("\n"); - dictionary_call( transfer, USB, 0, 0, 0, USB_IN, NULL, 3); + dictionary_call( transfer, DICT_USB, 0, 0, 0, USB_IN, NULL, 3); debug("send payload0"); - dictionary_call( transfer, BUFFER, BUFF_OUT_PAYLOAD_2B_INSP, 0xa5c3, 0, USB_OUT, &load_out[2], 254); + dictionary_call( transfer, DICT_BUFFER, BUFF_OUT_PAYLOAD_2B_INSP, 0xa5c3, 0, USB_OUT, &load_out[2], 254); debug("read payload0"); - dictionary_call( transfer, BUFFER, BUFF_PAYLOAD0, 0, 0, USB_IN, load_in, 254); + dictionary_call( transfer, DICT_BUFFER, BUFF_PAYLOAD0, 0, 0, USB_IN, load_in, 254); printf("load_in data:"); for (i=0; i<254; i++) { @@ -118,15 +118,15 @@ int test_function( USBtransfer *transfer ) //dict opcode addr/index miscdata endpoint *buffer length debug("set func"); - dictionary_call( transfer, BUFFER, SET_FUNCTION, DUMPING, 0, USB_IN, NULL, 1); + dictionary_call( transfer, DICT_BUFFER, SET_FUNCTION, DUMPING, 0, USB_IN, NULL, 1); debug("get sec"); - dictionary_call( transfer, BUFFER, GET_SEC_ELEMENTS, 0, 0, USB_IN, NULL, 8); - dictionary_call( transfer, BUFFER, GET_SEC_ELEMENTS, 0, 1, USB_IN, NULL, 8); + dictionary_call( transfer, DICT_BUFFER, GET_SEC_ELEMENTS, 0, 0, USB_IN, NULL, 8); + dictionary_call( transfer, DICT_BUFFER, GET_SEC_ELEMENTS, 0, 1, USB_IN, NULL, 8); debug("read payload0"); - dictionary_call( transfer, BUFFER, BUFF_PAYLOAD0, 0, 0, USB_IN, load_in, 254); + dictionary_call( transfer, DICT_BUFFER, BUFF_PAYLOAD0, 0, 0, USB_IN, load_in, 254); - dictionary_call( transfer, BUFFER, SET_FUNCTION, 0, 0, USB_IN, NULL, 1); + dictionary_call( transfer, DICT_BUFFER, SET_FUNCTION, 0, 0, USB_IN, NULL, 1); printf("load_in data:"); for (i=0; i<254; i++) { printf(" %x",load_in[i]); @@ -140,17 +140,17 @@ int test_function( USBtransfer *transfer ) printf("\n"); debug("send payload0"); - dictionary_call( transfer, BUFFER, BUFF_OUT_PAYLOAD_2B_INSP, 0xa5c3, 0, USB_OUT, &load_out[2], 254); + dictionary_call( transfer, DICT_BUFFER, BUFF_OUT_PAYLOAD_2B_INSP, 0xa5c3, 0, USB_OUT, &load_out[2], 254); debug("set func"); - dictionary_call( transfer, BUFFER, SET_FUNCTION, FLASHING, 0, USB_IN, NULL, 1); + dictionary_call( transfer, DICT_BUFFER, SET_FUNCTION, FLASHING, 0, USB_IN, NULL, 1); debug("get sec"); - dictionary_call( transfer, BUFFER, GET_SEC_ELEMENTS, 0, 0, USB_IN, NULL, 8); - dictionary_call( transfer, BUFFER, GET_SEC_ELEMENTS, 0, 1, USB_IN, NULL, 8); + dictionary_call( transfer, DICT_BUFFER, GET_SEC_ELEMENTS, 0, 0, USB_IN, NULL, 8); + dictionary_call( transfer, DICT_BUFFER, GET_SEC_ELEMENTS, 0, 1, USB_IN, NULL, 8); debug("read payload0"); - dictionary_call( transfer, BUFFER, BUFF_PAYLOAD0, 0, 0, USB_IN, load_in, 254); + dictionary_call( transfer, DICT_BUFFER, BUFF_PAYLOAD0, 0, 0, USB_IN, load_in, 254); printf("load_in data:"); for (i=0; i<254; i++) { @@ -158,13 +158,13 @@ int test_function( USBtransfer *transfer ) } printf("\n"); debug("set func"); - dictionary_call( transfer, BUFFER, SET_FUNCTION, DUMPING, 0, USB_IN, NULL, 1); + dictionary_call( transfer, DICT_BUFFER, SET_FUNCTION, DUMPING, 0, USB_IN, NULL, 1); debug("get sec"); - dictionary_call( transfer, BUFFER, GET_SEC_ELEMENTS, 0, 0, USB_IN, NULL, 8); - dictionary_call( transfer, BUFFER, GET_SEC_ELEMENTS, 0, 1, USB_IN, NULL, 8); + dictionary_call( transfer, DICT_BUFFER, GET_SEC_ELEMENTS, 0, 0, USB_IN, NULL, 8); + dictionary_call( transfer, DICT_BUFFER, GET_SEC_ELEMENTS, 0, 1, USB_IN, NULL, 8); debug("read payload0"); - dictionary_call( transfer, BUFFER, BUFF_PAYLOAD0, 0, 0, USB_IN, load_in, 254); + dictionary_call( transfer, DICT_BUFFER, BUFF_PAYLOAD0, 0, 0, USB_IN, load_in, 254); printf("load_in data:"); for (i=0; i<254; i++) { @@ -172,7 +172,7 @@ int test_function( USBtransfer *transfer ) } printf("\n"); - dictionary_call( transfer, IO, IO_RESET, 0, 0, USB_IN, NULL, 1); + dictionary_call( transfer, DICT_IO, IO_RESET, 0, 0, USB_IN, NULL, 1); // dictionary_call( transfer, BUFFER, ALLOCATE_BUFFER2, 0x3508, 4); // dictionary_call( transfer, BUFFER, ALLOCATE_BUFFER3, 0x4A0C, 4); diff --git a/host/source/types.h b/host/source/types.h deleted file mode 100644 index 048aa45..0000000 --- a/host/source/types.h +++ /dev/null @@ -1,19 +0,0 @@ -#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 diff --git a/roms/M10_P128K_C64K_W8K.nes b/roms/M10_P128K_C64K_W8K.nes new file mode 100644 index 0000000000000000000000000000000000000000..b820ca86e05d6b7ea83fa0b332263486b7f017b3 GIT binary patch literal 196624 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 literal 0 HcmV?d00001 diff --git a/roms/M118_P128K_C64K.nes b/roms/M118_P128K_C64K.nes new file mode 100644 index 0000000000000000000000000000000000000000..c19a667125196d61c2f1f11564c89de94fde6599 GIT binary patch literal 196624 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 CGM&x< literal 0 HcmV?d00001 diff --git a/roms/M1_P128K_C128K_W8K.nes b/roms/M1_P128K_C128K_W8K.nes new file mode 100644 index 0000000000000000000000000000000000000000..2960271de469edf0488c59ed620acd2ff2a5f14f GIT binary patch literal 262160 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 literal 0 HcmV?d00001 diff --git a/roms/M28_P512K.nes b/roms/M28_P512K.nes new file mode 100644 index 0000000000000000000000000000000000000000..260858e646703958422cbebb4d98205f2043ece9 GIT binary patch literal 524304 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 GB>R8NcL4kV literal 0 HcmV?d00001 diff --git a/roms/M2_P128K_V.nes b/roms/M2_P128K_V.nes new file mode 100644 index 0000000000000000000000000000000000000000..89c2d87933b026285021a4d62bc54779fedc6807 GIT binary patch literal 131088 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 DJc^wE literal 0 HcmV?d00001 diff --git a/roms/M34_P128K_H.nes b/roms/M34_P128K_H.nes new file mode 100644 index 0000000000000000000000000000000000000000..408545c83a5e5579760af34f1583ec71aa964c89 GIT binary patch literal 131088 zcmeI)eSB0`nFsK5@7#IG5Hb^zkO2~MTIFSs)@WOrr4c4TAW0`7Ch42i?d{sm5{lNB zT^4skk}9_wvl%+o?Uq)ncSo*r&}i5#y1Hdep`=N)?Zwg;rM0oHY{1$M(DKq!W}kB> zNn>^GKUv{X0Gj}-8y+d7P<7^+}3mIcx`eSMQKmY;|fB*y_009U<00Izz z00ba#-U?vmf8KU28U_IfKmY;|fB*y_009U<00Iyg6HsvHf6M|a5P$##AOHafKmY;| zfB*y_0D<#WKpmO?>qn19Z`Q&dhPo*u@A5QJKZ}V|lp`Wa~48>%-*nZXa z^{K(<1WTzxF-in8xO0B@nRH6gMSGlaQO|qQqJv({96pqe)@WHyPCAuCzi%(6rl#hd z%Q4v&-gU06zboDLPQ`s#J74Wa3Wh_=g` zZ%VSQjBizVQeCX_;2VR%)AtK4UJ%Jlr$6=k)9J6J{Z*!xP|azgC+>@gE93r%VDV`Y znrnCYB3;vDvcibzqV08l`$^MlrT3>(XFKdu`r&kBjEbdQ>}Yz!k5hOGV9W$75P$## zAOHafKmY;|fB*y_0D*T;V4~*#8qNRP)0qFidp(PsApijgKmY;|fB*y_009U<00M6b zOw|0}jrspuoq#n6KmY;|fB*y_009U<00Izzz`HCkQS*Nf=Kt?<&mwyWKmY;|fB*y_ z009U<00I!WPz5H__y4{4{{MwK4AE`~KmY;|fB*y_009U<00I!00D+0R|L?>7{|V@A z6bS(cKmY;|fB*y_009U<00I}Pz(mdevoQa^P=_4a4FL#100Izz00bZa0SG_<0uvxG zQS*O4=KmAW+b9wO5P$##AOHafKmY;|fB*z81cAx){r_qB{{MwA|8&g%FNEQR zHbMXb5P$##AOHafKmY;|fWRaXn5g-G4(9)pWCWlZ5P$##AOHafKmY;|fB*y_aJ~sl zrtkj;@csYuZFr$Q5P$##AOHafKmY;|fB*y_Fo^{w>i&Na_x~sHs6f>q009U<00Izz z00bZa0SG|gd=r?c`F}3v|L5CKLVF+p0SG_<0uX=z1Rwwb2tZ&G3ry7fe+K6NlXz61 zY7l?`1Rwwb2tWV=5P$##ATX5$Ce!!-^YH!usXUZWcL+cL0uX=z1Rwwb2tWV=5SU^D z6LtSTANT*K*hoQjApijgKmY;|fB*y_009U_fB*y_009U<00Izz00hnhfr+~RAHx0r^I-I#2@rq)1Rwwb2tWV=5P$##ATU(~ zCTjja3-kY}GDJ{M2tWV=5P$##AOHafKmY;|I1dCSYW_caWd5%oJsQ1P6Q>Qlwr3%F;5zOGu`Q2yIDMc6UamGbG z?@5aedNFhOP&!(pWjQ(NR1W>Vy_}kwns+Y8WLtRGxwihUblW=>_hIck7!qg#1Rwwb z2tWV=5P$##AOHafOmTt9^!@)iBj5i|GVboT3ixmOcziFva=+-MiTy7P&OI7G_OM{w zrSUm?g=Wm;-o4HgpH41)w8~;Ux_4bxY23>fdpR%YGt@1vce9UL6APo}~T z&9(QG*jpII50qVOV39q;QcH6viRCJF(ZW=1)nvSRFNG2mt1#58%vb!*ufeD|zHzUx z&8PUs_tJ({WarY>uV{-FM`#gE^;*T0hC&nulR0G0e?gvcz;u6eZc3wN7HwK{QeH~* zx;!FFnl-K@DsNn2$LSPPu|g@;40L(9m`=5HGMhb?nRGZ{&XC!bkb%YNC9^L~`)G|k zl8jz4l;k{VG)QIMEH(ABHY|ZSq!D+Mj=H(ni=h}iUt(H66&qRa$|1F z#SipR)m{9tJ}PQlidphF)lqnPN1ru2b0Vjm{N6{YnCRmVTj~Aj)LFseE-ut~ek93E zCOXQZ1^vn8TRl`idfCHlYTfV!W&%1%-bp?5>qo_V zXqSk{my#r>bc6Qm;v&N(K2JfT1Ljix+eh>&YDf*gZtuEqAggp>X+mx8qZ4&Q*+Ql7 zVkuvEIc@jbuj>5PN0Zua)piZqXLhU3C>ji&)ScmGvMvv&UlQ#0^6GSEixQ6QuJv*w z#Pc5^f+$tarP0gh_N9t45vYYS0+o_4=2#f&z+P*Xp<1dO&Cl-}Vs?OPIug%1;>5Gk z#%!J6_=quEl*Y3oyl7uE{}ItXT9+i>=G6T4LHksu8e)r#c0EG_?|`9fbIvoQ+Abzf z?B$7*+d{W8gL?C@VyU6#-~dnj{7A`wJMpAbOF7}w0+w){Dul`{!2c29V zcXILTBCQ)N>FxBFEs}k6mR>sDvJQj6-|9jc-Iu{MSlDax-#?pSZJ>`{RctPgXg7vd+}EP>6A?r~L`F+S_lxc324>qln`#w#!t@|70p^ zhC~aEBt1b%U!kN=ZFhA9I|Xx`lq9>8SuQfMWLJfnxuH`3xRP>k2K#O5ssVrMm(C~+ zzN9C;dkUX?fZaS8Je67h7`xea4+dY8*)h&EzF@zMgjOrY9I-Q=)@#$c?HAW%)>3Y| z)D%&$L zyPJ(P`y@5{I5qo)x5WNvf&*+!>QzdTq9o5tse3b0R#7TTDBI`sD(i18ruX;)8s<+L zikN56<(dM)1@>kAR^b7bSlmxrg^79n)-2kZE4OAP3i~bB0haQF+o%{n?W>}{9qV+9 zg_?btcSN6Re_ynZTrfKN=z`(jDYT*B`Z$YF`<2L^wFl#BWKaFUxGQ32M~Bi$)qJRn zMND6p5_#zMgI#Kb#tR)&=^{E9{I%Ib2X*rc^m+0{;ii#7a)QTc$c1F$1<&7pFm;jh zsg$`$B;=5FV%4FsaeJ(9&!-L=Y|p0;%6Rt{l|J-b$v1bgyVZXC%wgrQYuG-ndzgm} z^e5CK{qxztEwsFami4r(r{zLgE~I5XE%Rwfy>i4qpGFHeyh+W>DYMv_`wr5DNIA3P zV8TP6M5@8&dpi<`E$=<52pZl&`;f&9RkwnMX5|`gzVA`FZ7GI}R+GwZ_7r_)-V@xd zRj02A-ZNt`_&a)+8%lg;q=x>wXGX%V0cAexF3hYbiI?=z>wPjsmxZz4LHk%T(&b#o z_0I6wog)1JQ-|rtKBaGU^DZ}+*C%R$m>XBPKE?m(h3Z290uX=z1SXZhMBV={8h!r1 ztc;HbQO9r4dfkn7Wv#tpjjepy&N6MS+uryi`bV8zWY`yPu)Q%`{fzzKCVS1IhPAb< zM!xcet7|JSxiZYE)<$pOtE#W9Y+x16;T3iAq-&gY=anzK^77KMFsrVMUgD&zxZ<)f zYs}f+iZ@j@Ht~ka#%rQY zOF3H|t!S*`)vHGLjBB3Er?#Tb-?VmZl&@af;H0FY`09$<>XmD2-(OeR=wDgU(9}@9 zYE30yv9_XN6|ZP)tgKxTy}`e7ZGFR~{DY+*xQwr&^DFB34V4WI)hn;|^Kn1dU3cB3 z_0@Hi)oZGnE~Px3gK}qe-RkPP>ZVF6BTCkd@*qpKw6wIwJbFwnVy$|J#g>(2hZrkw znOk1YvP;XCwJroyD%- z5Nc&C=2@c0LZMJh*Y(hbm*rVcmxn?ul-}T@MRu7-_ryZ2o}DeRmR676+R_qoPN$NW zhRUfL<*}A>R+`0FGq&rx=a&I*QFTSKApmh5GW6@69a9MeCkZwQr_mu54@ zW>fh-7Sr2eG3JyX3vGBhw!stIAk(w-657j3Lmp4aLlup*wCJ(&R?39VZS_$4mZjNL zM0u;HygZa$8XIZ--GNo(S048{$CbP+=eUyRrzPc-H_chH zylm%uB`-&5YolWG3X~FBYIz||mdEl{&B;ICt(CONZ4WIe|9mek10{FlPji+mKik=_ z=UvnxyJNAc%vbjr=2wvo~W==>k&U7L4i#^W>EW-OiYM(zu_-_C8x zZOC1oTa^1|@WtTIg705`(+bve@wy)Gx*p};r?iheyYVB>R-XKM-R48;=0gu|K2-FB zgIRUY_~|!)Vf`)r2|jF_5$XY|9sMXSmp4$dpzf>kv8Bs3if=KVZ0DcWjFMz8E&T41 zk>`@=VWfJ0oVANPXoVgdV(mIj7+HNdAXo2Hw@|2&q7*Ewru>#t$-;{5HJGK;%vUW| zQxkUWwA4!FL!Zzp6OTxL6EMp>C9TQsMPF4o?a8=;5`t4{{* zbZ=$tme24G^jfa%8egvY{qqWUnymAHC*=}~K5Tg@CS-WSrS?nTq?p3v+qI71Zp&46 zL<=Tq5*~K>qf5rxcPP`oLz(vRW=%Gef{Hh}4W10r!tdtvES7J3VQ(a%X8CA3ZMx&k ztm&}N=yI)hY;9<4t=(Cpuqr*eMS&`QlSWaAYp6_Kp(WeJZE>b=WkZiKohnShz!Ex^ zY~Mp)U5Sr6ouGh zX-Bl49;tV>*VmI3K0VY+8k*jl-QykV?NP(My0fR;X>g~%*`%085tVMuDqBQBWVhj| zsWIJmGm?3|GfOcjuxM%HLTHwUVoak|(5PHP3uoKUS#IjKo?a?g4$C5qFP8nq?&L`q zU$4ook-<$GjXl&8Su{fII2+RCvv9)PUeN2eRf@V(WQ79gOi)v|GIN+BDXvUOu93#> zR})7q*JG#Ci9=M9?6N(~ZBQ^I4sIKNUi)ykuKefDY2x)uow}-hPVhA7CkWpDWs;Q4C^8 zZDx8;uRS#U?C`USlA9a7Op9J6JGO)vuG9SUODK@Wy>2;nc~p+v0RM(Y;c>+oy@SDH zdU$zOdt5PfYLR@i(t3NAE7YG^YgT&Qi4*#suV~do*lwQdQrew03AyL%8c`HVMN6%r zbe0l+g*u-G2}!E5sx;2~)aWLSBBmbi>NR(L?}_hqhP^u|a7uMhtAo@VZN1teL-}D^ zqafQUsv3o(+DCkMP-zw;h*70&^AxvAQ1-N5meM++Pf$~dL1#==HIL6v9}kMWWKk^b z3c6S*X7V=ieR_Y;`^H{i_R{$D+_QTEL3)GacWZ7_KO%?#}wU6g1%{ZHRg|L%x7DPKZ? zLn@Lk^(Ni&IMepnnKnBt=v`oT%Z;=h5^b4{0awB&n3<-0iP%0VxP4qi?3ab~{cOfJ zIh`sX+i7+&K1}PhCKpNh?sN_&@378YPaEcM`cuCB=Tc{S&-KuCZIhn-iFK~uesef= zoc5j^I-58u*e0^CqPs~{L8&M|G0b%ldAazkChmG~K~NP>P@t7Y^7zMaN1u+BZ*0Hc z?UGkPXE@8}aOo;Qol4K)I?u*fdD{AKrm+g?C-eQ1-`UG^NhgOgdO=cvW>k@bM>ir(lE*)k_e zZ;mBhBJYWrnWT$kNzS@El}jP{*ApyurN+w6m1UDOtJ+k^O zy0_O}^R_>yqGPp8F3zm>Q;nS?B3MOxhN%t1i|O(IZu+ZPw49%K7r>J;t z3BTy#_q=!B`~?fci{7{Rl1txT`hgE#cKH=ct}OeDrB{`IXxZ{e#fp`yDp#+ms;;>@ zT3ffa{=*H8P1js|-Sszo@RQ9Z~m)~-*Rj0uh%uNziq=OK6(46KK+@`{>|TR z{JTw``}==r+1%RJe#hs(u*JCZA3MI-`A=Q(t#>8v{?eEK`JR8dciVmUf90zWeC_Mz zzb3!2-TLOYc8Hzd{!aIIzt^+t-~Ro<-QWMgfBf)A|M}3K|N3$7!+ZBVvcK=q{(-@t z{PeNMpRf=7?8$>qJ^jqHKmWy{=br!N3q!wp@z?+To5TMzeB|hFU;5q4ucVG0Kk@2o zCr_O|^ZFZS-#nL&jJ^A}1|x&_FIM?t>hDOrFyeeugtmiknCw}3uTP}tUL~XNTF8fz zzaZW;w9JFa+Q@^+hc)}<&U@If{f3i@9xpcv_=_i^tXJMpD6BpG%79{rELwSCK(zyM zXu9=8iv2G^ CLY*D} literal 0 HcmV?d00001 diff --git a/roms/M3_P32K_C32K_H.nes b/roms/M3_P32K_C32K_H.nes new file mode 100644 index 0000000000000000000000000000000000000000..d7f7e92c1ef6cb683f9dc98f594c83a0d27384e0 GIT binary patch literal 65552 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 literal 0 HcmV?d00001 diff --git a/roms/M69_P128K_C64K_W8K.nes b/roms/M69_P128K_C64K_W8K.nes new file mode 100644 index 0000000000000000000000000000000000000000..8ed1e751369fa1953b733dd5c212d0610d0ad6e8 GIT binary patch literal 196624 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 literal 0 HcmV?d00001 diff --git a/roms/M7_P128K.nes b/roms/M7_P128K.nes new file mode 100644 index 0000000000000000000000000000000000000000..826959f47a532fcdad4e8bbdda2e5b19fc9de95d GIT binary patch literal 131088 zcmeI)eSB0`nFsK5@7#IG5Hb^zkO2~MTIFSs)@WOrr4c4TAW0`7Ch42i?d{sm5{kC! zE{nS%Nh`M-vl*J|c1x?(yCYXQXf*5=UEQ)yp`=N)?Zwg;rM0oHY{1$M(DKq3W}kB> zNn>^GKUv{X0Gj}-8y+d7P<7^+h&Bqw?(jQCX2Lcd)00bZa0SG_<0uX=z z1Rwx`b5;N||8ur$(J%-=00Izz00bZa0SG_<0uX?}n1F&i|6>+dfdB*`009U<00Izz z00bZa0SKI{0_w>8Uq5;@dZQ*z8?5Ja+E7J0ekyIL{%~r?eVdQd3jJi=Whf@w#rCVV zuTKp=Cs;}qicun%!JYGa&ZJX{F52Uai+bLh79I3r=J26(v_{Kva?+_B`h90PH8nNw zUXIDO@UF9M{axv{cPs9r+PT_aXcq(^009U<00Izz00bZa0SHVTflXu6S68(4M6_Mj zd{csLWqhl`6Y64>2j3VBp1xmb@q$QZI(^&kPp7|@_E(u&w`xuky>VYeTpssF1dC6L z&|JIA7wMWNlNClx7j3We+fSNaE4@FRdb7hmr5{d5#;91@#g3*o{5XZD0LDzP0s#m> z00Izz00bZa0SG_<0uXrb1SV?!uhIO!J&pPQd)Kqb83GW100bZa0SG_<0uX=z1R(IX zz(mde-I)Ks-3eHO00bZa0SG_<0uX=z1Rwwb2)xGv6E*+$VE+Fe_bjr900bZa0SG_< z0uX=z1Rwx`^HpFnegEH!@Bg2#!w~I;00bZa0SG_<0uX=z1Rwx`2@sg5`~N=N|DS-~ zMv)MJ00bZa0SG_<0uX=z1R!v}3QW}eKMV8!^L5Cf-4K8P1Rwwb2tWV=5P$##ATR*} z6E*+$WBxw@y^SIv009U<00Izz00bZa0SG|gd=QvS-~XS6@Bg0L zss;fFKmY;|fB*y_009U<00L84U^0FGKM&vkpUOiCb%y{1AOHafKmY;|fB*y_0D&nc zFj4pa^Kt)wij5Rh7XlD~00bZa0SG_<0uX=z1g5gUM9u#TF#n&*!v=MS00bZa0SG_< z0uX=z1Rwx`DJC#c^Z%Kc|4*@zg6cv50uX=z1Rwwb2tWV=5P-l`5tvNh|1ZS%|EJ2Z zK|LV=0SG_<0uX=z1Rwwb2teQ*5SXa@{~_G}KLXGxGia1mo_0tAPKekH`1&%lC^UP3(VZaPHCgv4;iY zE{)IGD>P#!_wIG3_;hmVqg58;(Y@=kO5*volApP_DXB^Fo(&llS%@8IB|eKHk( zXs*4d#NNUvexU4P1B>h#mRg!aNi0{Xix#G8t0v>kdnuHlScRcxWxnEfeho&&@r`?h zZ9c_6xtBJqB0HD1ennffI6{kPDrpr{8VXSuOy-a|{{?x*0n`1>xhaj7S+r@*NqH&J z>+*;!Y1X)ssJwB79j8-F#R{cVGtlMbVmj5*$!zvmX42t+IYVY!LIxJ6m(0E}?V~mF zNHBWYeE}UA9`bdcaFF>k4~sy&Ai{U_5#i=O%3>%jHwq~V(#&X&RWzUo)~()LEH~z+ zT>L;ERo%rO>!YH^rI;m;Qyqnucl24aGbeJ|$?tuXiitk{u$A7QPQ58u+{J|&&yOUS z$wWt4w4gt+e5;4*M=yJrO|2Uq;@z+5*382*%hs=7ANTO};h`**mYIM~f_G96{rXYy zKH4QB@}(rfDczv`y12k_i90B0biiE7fBT4DMGdLp*X&&v4rG-MEbUgC`{+d7P_|I% zyI9H>UQXNn_NzL-`O$>7TeV$-_L<$PGl~X-Cv|7InXJph>6Zk1yu3P{*`kDFyKBAN z2=V+!h#*Rpb7}PQ`F*LPOayA7j6kL2i#ZmCIdR`eb7FYsfO4hqg~I?z&l_l+nn?+f_Ad6Am)rAXF0cM!E(e`l z9(Qu_>msciEaC0+mo1Wg^CrD?x@8>(gTK{Q=}u5G97s@{yP2qxTozx3A9^d_|Ou0*+$ukj^sPCz4~>%N`+IW0o#_G};|bv$HEF z(iMo9-Yu?e{_15UEc@e!B~Mm4eX`Efw@`?2tf&3mYPGlDe(kUlJVp`6Uu>7DmjB6A z)C`Fh8cBMBlD)GdntzPN?QX zT`Xeyx|GO6w;t?LBQ##PD3sv6EArF)`O`F zoKL09MWR~{StnK<8XLFA`u5y*&|rH$b5O>+x2W`?=SsY_i`}jE+h-0dhh4+=aoxi_ zY@okeJ<>m)4ctV_n`l{2%X(Taq~$_d=F>8tmeeap{PStFaKoF>%$zcdow@HIU5J!3 zI}Ubx=#xk_*nDqC_hHL>k1B$OchEj$F+&w2_oD@ylE`snpOk)q4O*zcfyED`B) zuH$-V_|2Un{Qy&k>Bl~$Z*}u7H<#BZYJr#=SGYdK|LKM5LjVF0fB*z0mB2*Z|1TPS z{=ck@j|Wl5Z_s+(^>$^gy<&~6eA&)2ZLP=N_#^s9on2(u7jCe&9hRVjP zqD@OVTOF-vtm4(HM)!iBh)4Gq;Ruk`bAKi6Dy z&BgWAb(Pg?s+umQJe`AbXLa4`>bmNtN-85t){XKYOSQDLw8lJoOfF)rdWglAm1Tz* zD{q-wUe2;h%a^q-3&r}%%a_IaVnt;vv?LZP4KYusrM0!3v6lN|F`d$HjKxB+ayp&G zuH6u7Wh~}dqQ^p^P)yhL(1w@gSx=XTLM)Wt;G;!$nMe1;Lam;iEwPqXkKWqS5^_$b zl9z_csT$?6mU32_-Kw{II<)C*jJD5Gc8tynhFV)gq4JjOWsDVlRpuPiKdo;Fm6w-h zGsb39`92oY+hQ^1lphOicsjPh6Wbuuv-A?$%SuBYPsl?RjkL7rvGP{RgwAdCQ2Lgo z*;GV%tEap?lwBGdY5$Uz@(rP)vUF%ej1n_FL=`Ugu~1{h)s?F%nkp1k^96aNeTCOc zdF05Y;$p6x6@dU#*mU2DKnZg(Z;nb!#tL%O<;&$V@ZiYygCpBsuRN~gc%5w}aG`Tt z%~1jY#jE5g&XVP+w4|K#Tnd%rWqEF;WVu{=Xi4ewXs1^m_c_Ovye#LqlIN!-<&-zg zS+cxr=X@nEM`>%LV)F`=5?X3`Ax)OY@>R{rKi{pDw8?D`Eh+zeFD(Nlx93lDmMlNp z*{|g1INM5oUgdHshxxNBOXx@O=WTS#&7ZcB(go=JALm`2cV@=pGumb>o$*HQ3%TFU zZOLuOU7lN%`&RJ9;Lm~|TzpkzVaSLI_%mueK>Vm#5#Kcg8Xi6kxj z?vjz`lIUTidVid?i`!|19vfoqI!zc^eK;Uj?^L%?sF9)+EUc#dmQu;WitRO+rPRz< zEml(#cI~v(O64P;(kc~Qp+Y<9DJUQ3@<}O=C^uYYJ7q>$nI&5^r;IMv-jy4nhzqMv z1nzWiW$l*F@D3y`*LICB*Zlr@g*#2wdBBr$2}K{ayc82Myx~&&rEgM9;qmQSM{u|0 zDm$VD6Eq1AyZq55W9>VXY2Tqt`*^b^n@K^%8{7s@1Zm-Sb9xrbx4keK=~lCRG@Ulx zac0(Z*k^RPmK<9f8e403)+nq>k8V+*ir=77RN^WslUHboc5zFb>08;*V@#(CQ!ucE zjwRZ+(qz^->lS$+i_Q^2iXJf$q*QWhEh8gxZF|Ues?)0q=Twh~$nz{ZAzK#ZoKH`k ziEKlY+sts+)KrCK-s{5hpyejFW$t-}hDX}djNI~2R6*h$_E?J4Q%LWq4eq-_1zo_0BBCpunP~jSHb!9*QxIRzah34K18)KWDkA+j^5!upE{}8ec5?i`~f+ zF1}uqT_b~=G#Y!UC$eaS*l{+b%V*()xxFCiw^fR|Q)Gn#=uA*kw=#2>A}Ov+Nv@H` z?pM2yTCT@Vr@IePNwUlKFtOOQj~~d z+7$NH+|(qBmzgEBm08`c(y9|Yr2SL~weq5ESphmoXIGbIPI~7lwts-7+>toFEK>eM3nW~KG^ELW&Mv(~I6-Q6ejJzvqPiLl)~+oiNSYZ7wL*EOOjl!}&G zL+LCf{0enG4HA-6WmRdM_o>lM8bwS!-qmaF`rZ@Y>kNB$P~ep6pjHQ|H`KK+Bui->(I=>>#Go^#s+z~=r;i6kUa}~b zb{SnP6f<#)_&&Wq=zU`^Fq5={-b-?$n3}4Xw3Z4w=Vjh>c9zU8NTDNLMD&qxe$+^b zFB`{%+c+-#6qOMjGDgGV6sw_8c9z2PEE!kmcj($oicNG-;nvw|SBk<*`r)&2Hbh4w z(Tm6R&DznvIpADZ_)OV1UjD$?$PJfdB`NSm{lT2R31vEmnaxUnl5TJ4rcYcE${g>f zZp!XH(V68VJEv#v`@NoF=Ks|*8)eVjO5Gx3*#?sr(9F=@(M5^I)Bp5s_3w_Tlk!Cr zIHV%!Qg6~Nk27tLooTbfg5CvYkK9PxA<>rE7;ts_1T)i=FA>`(1-Flji2bsVzMsqZ zCZDEYiYy$O@GR_|7_|^@@y|%*EZ>ipIB%6?YD+g z$7%1$p*Opa3bu*ttLSbLRZuF*PYiQiL|!gFr-{4XUl3Hq6BKBrkv#q}+|j3F7D1Ib6C5P^Z#!xX$yjC)1RPo7!|L{U;vB{kZo2f>N26KPw;~yhT{=9n&3b zLg3FTFj4dW;?ep4pS86p3<3~<00bZa0SG_<0uX=z1R!vJ3QW}ef9}ZqUxp*=DPBr} zNs38k?v%;fYV{(AC*Ay@o4@QHaN7&$t`BX}y33wJcW^T6^c=OAKC&LLUD4}3B3tG} z>CLgEOXNKK1Q?^@VMQc2n_U2GQV<%DDO1hJ23O`dt+~Pr5 zSufpzQt1(9`adBks7$q_R;1!jACMbvaUq=|R_ImE@pW|XgL<*&^w$S8k=3mVdNe&C zZ#_CU9EIZCkEGjb-^u)65y3=h^jRuFdHDr13q!MJ&nYUN zTf#56@O|%}H-Evx@S+bazUbl)mVW5Nmt1<;lFQ5fV(As-A6d3MQn6y?s>;=Cs;Xu=fcsZZZ}+h;!exxe|_ zjeoc4^MC&jEt^~0+Hb$(3tNmk|FPqXo&VGo-+EW~-Cz3hKi~5&_inrI{;z!XfvUj{=szFY^ItzsKD>9|Bm4Uv?H?HY z$xk19{0aNO&z?N^)YH#A`}1EMdhYpOzA*Hw7k~ZVzd8Ir!$*$(_NCvw{7UNB@e{AU zcJkEeGq1n#=38gek+FCG)?j4t{>3U^O#K~+7e<_KiqLlO4U;`9@AZik-K%8uT?_e8 z@)yKghL(9SSsQsU`LJfc+<6Zhw%>44(c|St0e|sClqKa2g~Hm?uM8-5$fA`O22?vB zSDv7b_Kd$-P(|Zv-2dI-dG-9fB%{?3fB*y_009U<00I#Be-W5W-~TUBj;32rq}cxg DNaCGN literal 0 HcmV?d00001 diff --git a/roms/M9_P128K_C64K.nes b/roms/M9_P128K_C64K.nes new file mode 100644 index 0000000000000000000000000000000000000000..8172da6b2df53d693d55af057a99bada1c0f8da9 GIT binary patch literal 196624 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 literal 0 HcmV?d00001 diff --git a/shared/shared_dictionaries.h b/shared/shared_dictionaries.h index 2417aaf..10b6533 100644 --- a/shared/shared_dictionaries.h +++ b/shared/shared_dictionaries.h @@ -27,7 +27,7 @@ //============================================================================================= //============================================================================================= -#define PINPORT 1 +#define DICT_PINPORT 1 #include "shared_dict_pinport.h" //pinport dictionary has various commands giving low and mid level access to retro prog's i/o pins. //It also contains internal avr registers associated with the avr's io. @@ -72,7 +72,7 @@ //============================================================================================= //============================================================================================= -#define IO 2 +#define DICT_IO 2 #include "shared_dict_io.h" //io dictionary contains commands //Scope of functions contained is intended to be general and generic not specific @@ -88,7 +88,7 @@ //============================================================================================= //============================================================================================= -#define NES 3 +#define DICT_NES 3 #include "shared_dict_nes.h" //nes dictionary contains commands //These commands rely on io initialization from io dictionary prior to calling @@ -99,7 +99,7 @@ //============================================================================================= //============================================================================================= -#define SNES 4 +#define DICT_SNES 4 #include "shared_dict_snes.h" //snes dictionary contains commands //These commands rely on io initialization from io dictionary prior to calling @@ -110,7 +110,7 @@ //============================================================================================= //============================================================================================= -#define BUFFER 5 +#define DICT_BUFFER 5 #include "shared_dict_buffer.h" //mcu buffer dictionary commands //This library is intended to contain all buffer related opcodes/commands @@ -121,7 +121,7 @@ //============================================================================================= //============================================================================================= -#define USB 6 +#define DICT_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. diff --git a/shared/shared_errors.h b/shared/shared_errors.h index 29b2522..cfd8a62 100644 --- a/shared/shared_errors.h +++ b/shared/shared_errors.h @@ -2,7 +2,9 @@ #define _error_codes_h #define SUCCESS 0 +#define GEN_FAIL 0xFF #define FALSE 0 +#define NILL 0 //greater than 128 are possible avr return codes #define ERR_UNKN_DICTIONARY 128