Well over due commit with lots of updates..

Have separate lua modules now in scripts/app folder
Dictionary calls are now their own lua module
firmware now capable of calling multiple different dictionaries
have firmware & lua io and nes dictionaries, able to detect
NES and famicom carts.  Created expansion port abstraction so most kazzo
versions behave identically.
Created separate make file for stm adapter and inl6
added PURPLE_KAZZO and GREEN_KAZZO defines back in.  They work well enough
for sensing NES vs famicom carts so far.  GREEN_KAZZO requires
PURPLE_KAZZO to also be defined.  GREEN_KAZZO is also only compatible with
AVR_CORE due to software_AHL/AXL functions specifically written for AVR.
I think things will work if a STM_ADAPTER is placed on a PURPLE_KAZZO and
both those defines are made as only real difference is software tying of
AXL and X_OE.  But haven't tested this aside from ensuring it compiles.
Have correction to pinport_al.h that will commit immediately after this.
This commit is contained in:
Paul Molloy 2017-08-05 16:04:59 -05:00
parent ec725f7e33
commit 8b5650b75f
27 changed files with 2442 additions and 1486 deletions

View File

@ -65,8 +65,8 @@ CFLAGS+= $(DEFINE) $(INCLUDE)
SOURCES=$(wildcard source/*.c source_stm_only/*.c)
OBJECTS=$(patsubst %.c,%.o,$(SOURCES))
#all: dir $(BUILD)/$(PROJ).axf $(BUILD)/$(PROJ).elf $(BUILD)/$(PROJ).hex $(BUILD)/$(PROJ).bin size
all: dir $(BUILD)/$(PROJ).elf $(BUILD)/$(PROJ).hex $(BUILD)/$(PROJ).bin size
#all: dir shared $(BUILD)/$(PROJ).axf $(BUILD)/$(PROJ).elf $(BUILD)/$(PROJ).hex $(BUILD)/$(PROJ).bin size
all: dir shared $(BUILD)/$(PROJ).elf $(BUILD)/$(PROJ).hex $(BUILD)/$(PROJ).bin size
#build axf file output (basically elf with DWARF debug info)
# $@ is shortcut for the target, $^ is shortcut for prereqs
@ -86,6 +86,10 @@ $(BUILD)/$(PROJ).bin: $(BUILD)/$(PROJ).elf
dir:
mkdir -p $(BUILD)
#copy shared .h files which are used in host and firmware
shared:
cp -r ../shared/* source/
size: $(BUILD)/$(PROJ).elf
$(SIZE) -t $^

104
firmware/Make_stm_inl6 Normal file
View File

@ -0,0 +1,104 @@
#Build directory
BUILD = build_stm
#project name
#doesn't need to be associated with any file names
PROJ = inlretro_stm
# Selecting Core
CORTEX_M=0
# Use newlib-nano. To disable it, specify USE_NANO=
#USE_NANO=--specs=nano.specs
USE_NANO=
# Use seimhosting or not
USE_SEMIHOST=--specs=rdimon.specs
USE_NOHOST=--specs=nosys.specs
CORE=CM$(CORTEX_M)
BASE=.
# Compiler & Linker
CC=arm-none-eabi-gcc
CXX=arm-none-eabi-g++
OBJCOPY=arm-none-eabi-objcopy
SIZE=arm-none-eabi-size
# Options for specific architecture
ARCH_FLAGS=-mthumb -mcpu=cortex-m$(CORTEX_M)
# Startup code
STARTUP=$(BASE)/include_stm/startup_ARM$(CORE).S
# -Os -flto -ffunction-sections -fdata-sections to compile for code size
CFLAGS=$(ARCH_FLAGS) $(STARTUP_DEFS) -Os -flto -ffunction-sections -fdata-sections -g
CXXFLAGS=$(CFLAGS)
# Link for code size
GC=-Wl,--gc-sections
# Create map file
MAP=-Wl,-Map=$(BUILD)/$(PROJ).map
STARTUP_DEFS=-D__STARTUP_CLEAR_BSS -D__START=main -D__NO_SYSTEM_INIT
LDSCRIPTS=-L. -L$(BASE)/include_stm -T nokeep.ld
LFLAGS=$(USE_NANO) $(USE_NOHOST) $(LDSCRIPTS) $(GC) $(MAP)
DEFINE+=\
-DSTM32F070x6 \
-DF_CPU=16000000 \
-DSTM_CORE \
-DSTM_INL6 #inlretro 6connector
# -DSTM_ADAPTER #stm32 to kazzo adapter board
# -DSTM32F072x8 \ #64KB version of all packages (LQFP-48,64,100)
# -DSTM32F070xB \ #128KB version of both packages (LQFP-48,64)
# -DSTM32F070x6 \ #32KB version of both packages (TSSOP-20,LQFP-48)
# -DF_CPU=8000000
INCLUDE=-I ./include_stm
CFLAGS+= $(DEFINE) $(INCLUDE)
#SOURCES=$(wildcard source/**/*.c source/*.c)
SOURCES=$(wildcard source/*.c source_stm_only/*.c)
OBJECTS=$(patsubst %.c,%.o,$(SOURCES))
#all: dir shared $(BUILD)/$(PROJ).axf $(BUILD)/$(PROJ).elf $(BUILD)/$(PROJ).hex $(BUILD)/$(PROJ).bin size
all: dir shared $(BUILD)/$(PROJ).elf $(BUILD)/$(PROJ).hex $(BUILD)/$(PROJ).bin size
#build axf file output (basically elf with DWARF debug info)
# $@ is shortcut for the target, $^ is shortcut for prereqs
# TARGET: PREREQS
$(BUILD)/$(PROJ).axf: $(STARTUP) $(OBJECTS)
$(CC) $^ $(CFLAGS) $(LFLAGS) -o $@
$(BUILD)/$(PROJ).elf: $(STARTUP) $(OBJECTS)
$(CC) $^ $(CFLAGS) $(LFLAGS) -o $@
$(BUILD)/$(PROJ).hex: $(BUILD)/$(PROJ).elf
$(OBJCOPY) -O ihex $^ $@
$(BUILD)/$(PROJ).bin: $(BUILD)/$(PROJ).elf
$(OBJCOPY) -O binary $^ $@
dir:
mkdir -p $(BUILD)
#copy shared .h files which are used in host and firmware
shared:
cp -r ../shared/* source/
size: $(BUILD)/$(PROJ).elf
$(SIZE) -t $^
program: all
ST-LINK_CLI.exe -c -P $(BUILD)\$(PROJ).hex 0x08000000 -Rst
disassm: all
arm-none-eabi-objdump $(BUILD)\$(PROJ).elf -d -g
clean:
rm -rf $(BUILD)
rm -f $(OBJECTS)

View File

@ -7,5 +7,7 @@ all:
avr:
make -f Make_avr clean program
stm:
make -f Make_stm clean program
stm6:
make -f Make_stm_inl6 clean program
stmad:
make -f Make_stm_adapter clean program

View File

@ -1,3 +1,7 @@
#ifndef _avr_gpio_h
#define _avr_gpio_h
#include <avr/io.h>
#define __IO volatile /*!< Defines 'read / write' permissions */
@ -30,3 +34,4 @@ typedef struct
//#define GPIO_MODER_MODER0_Msk (0x3U << GPIO_MODER_MODER0_Pos) /*!< 0x00000003 */
//#define GPIO_MODER_MODER0 GPIO_MODER_MODER0_Msk
#endif

226
firmware/source/io.c Normal file
View File

@ -0,0 +1,226 @@
#include "io.h"
//=================================================================================================
//
// I/O operations
// This file includes all the io functions possible to be called from the io dictionary.
//
// See description of the commands contained here in shared/shared_dictionaries.h
//
//=================================================================================================
/* Desc:Function takes an opcode which was transmitted via USB
* then decodes it to call designated function.
* shared_dict_io.h is used in both host and fw to ensure opcodes/names align
* Pre: Macros must be defined in firmware pinport.h
* opcode must be defined in shared_dict_io.h
* Post:function call complete.
* Rtn: SUCCESS if opcode found, error if opcode not present or other problem.
*/
uint8_t io_call( uint8_t opcode, uint8_t miscdata, uint16_t operand, uint8_t *rdata )
{
switch (opcode) {
case IO_RESET: io_reset(); break;
case NES_INIT: nes_init(); break;
// case SNES_INIT: snes_init(); break;
// case EXP0_PULLUP_TEST: exp0_pullup_test(data); break;
default:
//opcode doesn't exist
return ERR_UNKN_IO_OPCODE;
}
return SUCCESS;
}
//pullup as many cart pins as possible
//goal to be safe state for all hardware
//doesn't currently contain any checks to report error/success from
//this is intended to be the "reset" safest condition for the kazzo
void io_reset()
{
#ifdef STM_CORE
//reset GPIO perif blocks to default state
RCC->AHBRSTR |= ( RCC_AHBRSTR_GPIOARST | RCC_AHBRSTR_GPIOBRST | RCC_AHBRSTR_GPIOCRST | RCC_AHBRSTR_GPIODRST | RCC_AHBRSTR_GPIOFRST );
RCC->AHBRSTR &= ~( RCC_AHBRSTR_GPIOARST | RCC_AHBRSTR_GPIOBRST | RCC_AHBRSTR_GPIOCRST | RCC_AHBRSTR_GPIODRST | RCC_AHBRSTR_GPIOFRST );
#endif
//pull up addr[7:0] bus
ADDR_ENABLE();
ADDR_IP();
ADDR_PU();
//pull up data bus
DATA_ENABLE();
DATA_IP_PU();
//pull up control port
CTL_ENABLE();
MCO_IP_PU();
ROMSEL_IP_PU();
PRGRW_IP_PU();
CSRD_IP_PU();
CSWR_IP_PU();
CICE_IP_PU();
IRQ_IP_PU();
CIA10_IP_PU();
#ifndef C3nodef
FREE_IP_PU();
#endif
//pull up on FF /OE should disable FF ouput
#ifndef C7nodef
AHL_IP_PU();
#endif
#ifndef C13nodef
EXP_DISABLE();
#endif
#ifndef C19nodef
AFL_IP_PU();
#endif
//EXP0 input no pullup
//Lots of possibilities, ~safe bet it will have it's own pull-up/down if needed.
//SNES /RESET pin disables SRAM on first few pcb versions
//NES PRG-ROM /OE (with pulldown) on old INL-ROM v1 boards w/pulldown
//NED PRG-ROM /WE (with pullup) on INL-ROM v3 boards w/pullup
//NES CPLD JTAG TDO non-5v tolerant
//Famicom carts have APU sound (EXP6) shorted to RF sound (EXP0)
// -enabling EXP FF output will drive EXP0 to value of A21/EXP6
EXP0_IP_FL();
//LED LAST displaying complete..
//planning to have LED DIM at power on to signify kazzo is in default
//mostly all pins pulled up state.
//gives some insight to current state of kazzo since it doesn't reset itself
//or if kazzo does reset itself due to WDT dim LED can help detect that.
LED_IP_PU(); //DIM pulled up
}
//NES cartridge interfacing setup
//set outputs as required
//latch address of $0000
//disable NES cart memories
void nes_init()
{
//start with a reset
//expecting user to do this but just to be sure
io_reset();
//enable control outputs and disable memories
//PRG-ROM
ROMSEL_OP();
ROMSEL_HI();
//WRAM (and state of m2 during first half of CPU cycle)
MCO_OP();
MCO_LO();
//CPU RD
PRGRW_OP();
PRGRW_HI();
//other control pins are inputs, leave as IP pullup from reset
//disable any CHR/VRAM memories with CHR /RD /WR
//prior to setting PPU A13 & /A13 which are /CE pins
//doing this helps ensure data bus is clear before
//using it for AHL clocking
CSRD_OP();
CSRD_HI();
CSWR_OP();
CSWR_HI();
//memories are now disabled Data bus should be clear
//now meet conditions to call other macros
//setup address $0000
ADDR_ENABLE();
ADDR_SET(0x0000);
}
/*
//SNES cartridge interfacing setup
//set outputs as required
//latch address of $000000
//disable cart memories
//reset high disables SRAM and puts INL carts in PRGM mode
//Excersize extreme caution calling this while NES/FC cart inserted
//probably won't work if FC inserted due to EXP0-EXP6 short due to audio jumper on cart
void snes_init()
{
//start with a reset
//expecting user to do this but just to be sure
io_reset();
//enable control outputs and disable memories
//ROM
ROMSEL_OP();
ROMSEL_HI();
CSRD_OP();
CSRD_HI();
CSWR_OP();
CSWR_HI();
//disable SRAM and put cart in PRGM mode
EXP0_OP();
EXP0_HI();
//other control pins are inputs or unused, leave as IP pullup from reset
//memories are now disabled Data bus should be clear
//setup AHL FF
AHL_OP();
AHL_CLK();
//setup AXL FF
AXL_OP();
AXL_CLK();
//now meet conditions to call other macros
//setup address $000000
ADDR_SET(0x0000);
ADDRX_SET(0x00);
}
//Test starts by verifying EXP0 can be driven low, if not, will return one byte of AUX_PIN
//followed by alternating 0xAA, 0x55, 0xAA...
//This test pulls up EXP0 and then reads AUX_PIN 6 times in rapid succession returning error code
//plus 6 bytes of read data. If pull up works but is just slow, should see that in return data.
//data[0] marks bit where EXP0 resisdes to provide host with bitmask for EXP0
void exp0_pullup_test(uint8_t *data)
{
//first verify EXP0 can be driven low
_EXP0_LO(); //sets O/P and low
NOP(); //give some time to settle
data[1] = AUX_IN; //port where EXP0 resides
_EXP0_FLT(); //sets I/P w/o pullup
if ( (data[1] & data[0]) == data[0]) {
//EXP0 was high, couldn't drive EXP0 low
data[2] = data[4] = data[6] = 0xAA;
data[3] = data[5] = 0x55;
//return this signature as indication EXP0 failed to drive low
return;
}
//Driving EXP0 low was successful, now pullup and read back
_EXP0_PU();
data[1] = AUX_IN;
data[2] = AUX_IN;
data[3] = AUX_IN;
data[4] = AUX_IN;
data[5] = AUX_IN;
data[6] = AUX_IN;
//return EXP0 to floating
_EXP0_FLT();
}
*/

15
firmware/source/io.h Normal file
View File

@ -0,0 +1,15 @@
#ifndef _io_h
#define _io_h
#include "pinport.h"
#include "shared_dictionaries.h"
#include "shared_errors.h"
uint8_t io_call( uint8_t opcode, uint8_t miscdata, uint16_t operand, uint8_t *rdata );
void io_reset();
void nes_init();
//void snes_init();
//void exp0_pullup_test(uint8_t *data);
#endif

View File

@ -1,5 +1,6 @@
#include "usb.h"
#include "io.h"
#ifdef AVR_CORE
#include <avr/interrupt.h>
@ -44,8 +45,6 @@ int main(void)
//reconnect to host
usbDeviceConnect();
//intialize i/o and LED to pullup state
// io_reset();
//enable interrupts
sei();
@ -75,6 +74,8 @@ int main(void)
//Initialize board/system
#endif
//intialize i/o and LED to pullup state
io_reset();
//=================
//MAIN LOOP

483
firmware/source/pinport.c Normal file
View File

@ -0,0 +1,483 @@
#include "pinport.h"
//This file was created based on pinport.h
//the close relationship between these two files must be kept in mind when making changes.
//This file is also very dependent on shared_dict_pinport.h
//the shared_dict_pinport.h was generated from this file, so any changes here must be forwarded.
/* Desc:Decode pinport dictionary calls transmitted via USB and call requested operation
* shared_dict_pinport.h is used in both host and fw to ensure opcodes/names align
* Pre: Macros must be defined in firmware pinport.h
* opcode must be defined in shared_dict_pinport.h
* Post:opcode command complete, return data & length stored if used.
* Rtn: SUCCESS if opcode found and completed, error code if not.
*/
uint8_t pinport_call( uint8_t opcode, uint8_t miscdata, uint16_t operand, uint8_t *rdata )
{
#define RD_LEN 0
#define RD0 1
#define RD1 2
#define BYTE_LEN 1
#define HWORD_LEN 2
//create pointer to first two bytes of return data array
uint16_t *ret_hword = (uint16_t*) &rdata[RD0];
switch (opcode) {
//============================
//CONTROL PORT INDIVIDUAL PIN ACCESS
//opcode: type of pin operation
//operand: pin number to act on
//============================
case CTL_ENABLE_: CTL_ENABLE(); break;
case CTL_IP_PU_:
switch ( operand ) {
case 0: CTL_IP_PU(C0bank, C0); break;
case 1: CTL_IP_PU(C1bank, C1); break;
case 2: CTL_IP_PU(C2bank, C2); break;
#ifndef C3nodef
case 3: CTL_IP_PU(C3bank, C3); break;
#endif
case 4: CTL_IP_PU(C4bank, C4); break;
case 5: CTL_IP_PU(C5bank, C5); break;
case 6: CTL_IP_PU(C6bank, C6); break;
#ifndef C7nodef
case 7: CTL_IP_PU(C7bank, C7); break;
#endif
case 8: CTL_IP_PU(C8bank, C8); break;
case 9: CTL_IP_PU(C9bank, C9); break;
case 10: CTL_IP_PU(C10bank,C10); break;
case 11: CTL_IP_PU(C11bank,C11); break;
#ifndef C12nodef
case 12: CTL_IP_PU(C12bank,C12); break;
#endif
#ifndef C13nodef
case 13: CTL_IP_PU(C13bank,C13);
#ifdef PURPLE_KAZZO
CTL_IP_PU(C3bank,C3);
#endif
break;
#endif
#ifndef C14nodef
case 14: CTL_IP_PU(C14bank,C14); break;
#endif
#ifndef C15nodef
case 15: CTL_IP_PU(C15bank,C15); break;
#endif
#ifndef C16nodef
case 16: CTL_IP_PU(C16bank,C16); break;
#endif
#ifndef C17nodef
case 17: CTL_IP_PU(C17bank,C17); break;
#endif
#ifndef C18nodef
case 18: CTL_IP_PU(C18bank,C18); break;
#endif
#ifndef C19nodef
case 19: CTL_IP_PU(C19bank,C19); break;
#endif
#ifndef C20nodef
case 20: CTL_IP_PU(C20bank,C20); break;
#endif
case 21: CTL_IP_PU(C21bank,C21); break;
default: return ERR_CTL_PIN_NOT_PRESENT;
}
break;
case CTL_IP_FL_:
switch ( operand ) {
case 0: CTL_IP_FL(C0bank, C0); break;
case 1: CTL_IP_FL(C1bank, C1); break;
case 2: CTL_IP_FL(C2bank, C2); break;
#ifndef C3nodef
case 3: CTL_IP_FL(C3bank, C3); break;
#endif
case 4: CTL_IP_FL(C4bank, C4); break;
case 5: CTL_IP_FL(C5bank, C5); break;
case 6: CTL_IP_FL(C6bank, C6); break;
#ifndef C7nodef
case 7: CTL_IP_FL(C7bank, C7); break;
#endif
case 8: CTL_IP_FL(C8bank, C8); break;
case 9: CTL_IP_FL(C9bank, C9); break;
case 10: CTL_IP_FL(C10bank,C10); break;
case 11: CTL_IP_FL(C11bank,C11); break;
#ifndef C12nodef
case 12: CTL_IP_FL(C12bank,C12); break;
#endif
#ifndef C13nodef
case 13: CTL_IP_FL(C13bank,C13);
#ifdef PURPLE_KAZZO
CTL_IP_FL(C3bank,C3);
#endif
break;
#endif
#ifndef C14nodef
case 14: CTL_IP_FL(C14bank,C14); break;
#endif
#ifndef C15nodef
case 15: CTL_IP_FL(C15bank,C15); break;
#endif
#ifndef C16nodef
case 16: CTL_IP_FL(C16bank,C16); break;
#endif
#ifndef C17nodef
case 17: CTL_IP_FL(C17bank,C17); break;
#endif
#ifndef C18nodef
case 18: CTL_IP_FL(C18bank,C18); break;
#endif
#ifndef C19nodef
case 19: CTL_IP_FL(C19bank,C19); break;
#endif
#ifndef C20nodef
case 20: CTL_IP_FL(C20bank,C20); break;
#endif
case 21: CTL_IP_FL(C21bank,C21); break;
default: return ERR_CTL_PIN_NOT_PRESENT;
}
break;
case CTL_OP_:
switch ( operand ) {
case 0: CTL_OP(C0bank, C0); break;
case 1: CTL_OP(C1bank, C1); break;
case 2: CTL_OP(C2bank, C2); break;
#ifndef C3nodef
case 3: CTL_OP(C3bank, C3); break;
#endif
case 4: CTL_OP(C4bank, C4); break;
case 5: CTL_OP(C5bank, C5); break;
case 6: CTL_OP(C6bank, C6); break;
#ifndef C7nodef
case 7: CTL_OP(C7bank, C7); break;
#endif
case 8: CTL_OP(C8bank, C8); break;
case 9: CTL_OP(C9bank, C9); break;
case 10: CTL_OP(C10bank,C10); break;
case 11: CTL_OP(C11bank,C11); break;
#ifndef C12nodef
case 12: CTL_OP(C12bank,C12); break;
#endif
#ifndef C13nodef
case 13: CTL_OP(C13bank,C13);
#ifdef PURPLE_KAZZO
CTL_OP(C3bank,C3);
#endif
break;
#endif
#ifndef C14nodef
case 14: CTL_OP(C14bank,C14); break;
#endif
#ifndef C15nodef
case 15: CTL_OP(C15bank,C15); break;
#endif
#ifndef C16nodef
case 16: CTL_OP(C16bank,C16); break;
#endif
#ifndef C17nodef
case 17: CTL_OP(C17bank,C17); break;
#endif
#ifndef C18nodef
case 18: CTL_OP(C18bank,C18); break;
#endif
#ifndef C19nodef
case 19: CTL_OP(C19bank,C19); break;
#endif
#ifndef C20nodef
case 20: CTL_OP(C20bank,C20); break;
#endif
case 21: CTL_OP(C21bank,C21); break;
default: return ERR_CTL_PIN_NOT_PRESENT;
}
break;
case CTL_SET_LO_:
switch ( operand ) {
case 0: CTL_SET_LO(C0bank, C0); break;
case 1: CTL_SET_LO(C1bank, C1); break;
case 2: CTL_SET_LO(C2bank, C2); break;
#ifndef C3nodef
case 3: CTL_SET_LO(C3bank, C3); break;
#endif
case 4: CTL_SET_LO(C4bank, C4); break;
case 5: CTL_SET_LO(C5bank, C5); break;
case 6: CTL_SET_LO(C6bank, C6); break;
#ifndef C7nodef
case 7: CTL_SET_LO(C7bank, C7); break;
#endif
case 8: CTL_SET_LO(C8bank, C8); break;
case 9: CTL_SET_LO(C9bank, C9); break;
case 10: CTL_SET_LO(C10bank,C10); break;
case 11: CTL_SET_LO(C11bank,C11); break;
#ifndef C12nodef
case 12: CTL_SET_LO(C12bank,C12); break;
#endif
#ifndef C13nodef
case 13: CTL_SET_LO(C13bank,C13);
#ifdef PURPLE_KAZZO
CTL_SET_LO(C3bank,C3);
#endif
break;
#endif
#ifndef C14nodef
case 14: CTL_SET_LO(C14bank,C14); break;
#endif
#ifndef C15nodef
case 15: CTL_SET_LO(C15bank,C15); break;
#endif
#ifndef C16nodef
case 16: CTL_SET_LO(C16bank,C16); break;
#endif
#ifndef C17nodef
case 17: CTL_SET_LO(C17bank,C17); break;
#endif
#ifndef C18nodef
case 18: CTL_SET_LO(C18bank,C18); break;
#endif
#ifndef C19nodef
case 19: CTL_SET_LO(C19bank,C19); break;
#endif
#ifndef C20nodef
case 20: CTL_SET_LO(C20bank,C20); break;
#endif
case 21: CTL_SET_LO(C21bank,C21); break;
default: return ERR_CTL_PIN_NOT_PRESENT;
}
break;
case CTL_SET_HI_:
switch ( operand ) {
case 0: CTL_SET_HI(C0bank, C0); break;
case 1: CTL_SET_HI(C1bank, C1); break;
case 2: CTL_SET_HI(C2bank, C2); break;
#ifndef C3nodef
case 3: CTL_SET_HI(C3bank, C3); break;
#endif
case 4: CTL_SET_HI(C4bank, C4); break;
case 5: CTL_SET_HI(C5bank, C5); break;
case 6: CTL_SET_HI(C6bank, C6); break;
#ifndef C7nodef
case 7: CTL_SET_HI(C7bank, C7); break;
#endif
case 8: CTL_SET_HI(C8bank, C8); break;
case 9: CTL_SET_HI(C9bank, C9); break;
case 10: CTL_SET_HI(C10bank,C10); break;
case 11: CTL_SET_HI(C11bank,C11); break;
#ifndef C12nodef
case 12: CTL_SET_HI(C12bank,C12); break;
#endif
#ifndef C13nodef
case 13: CTL_SET_HI(C13bank,C13);
#ifdef PURPLE_KAZZO
CTL_SET_HI(C3bank,C3);
#endif
break;
#endif
#ifndef C14nodef
case 14: CTL_SET_HI(C14bank,C14); break;
#endif
#ifndef C15nodef
case 15: CTL_SET_HI(C15bank,C15); break;
#endif
#ifndef C16nodef
case 16: CTL_SET_HI(C16bank,C16); break;
#endif
#ifndef C17nodef
case 17: CTL_SET_HI(C17bank,C17); break;
#endif
#ifndef C18nodef
case 18: CTL_SET_HI(C18bank,C18); break;
#endif
#ifndef C19nodef
case 19: CTL_SET_HI(C19bank,C19); break;
#endif
#ifndef C20nodef
case 20: CTL_SET_HI(C20bank,C20); break;
#endif
case 21: CTL_SET_HI(C21bank,C21); break;
default: return ERR_CTL_PIN_NOT_PRESENT;
}
break;
case CTL_RD_:
rdata[RD_LEN] = HWORD_LEN;
switch ( operand ) {
case 0: CTL_RD(C0bank, C0, *ret_hword); break;
case 1: CTL_RD(C1bank, C1, *ret_hword); break;
case 2: CTL_RD(C2bank, C2, *ret_hword); break;
#ifndef C3nodef
case 3: CTL_RD(C3bank, C3, *ret_hword); break;
#endif
case 4: CTL_RD(C4bank, C4, *ret_hword); break;
case 5: CTL_RD(C5bank, C5, *ret_hword); break;
case 6: CTL_RD(C6bank, C6, *ret_hword); break;
#ifndef C7nodef
case 7: CTL_RD(C7bank, C7, *ret_hword); break;
#endif
case 8: CTL_RD(C8bank, C8, *ret_hword); break;
case 9: CTL_RD(C9bank, C9, *ret_hword); break;
case 10: CTL_RD(C10bank,C10, *ret_hword); break;
case 11: CTL_RD(C11bank,C11, *ret_hword); break;
#ifndef C12nodef
case 12: CTL_RD(C12bank,C12, *ret_hword); break;
#endif
#ifndef C13nodef
case 13: CTL_RD(C13bank,C13, *ret_hword); break;
#endif
#ifndef C14nodef
case 14: CTL_RD(C14bank,C14, *ret_hword); break;
#endif
#ifndef C15nodef
case 15: CTL_RD(C15bank,C15, *ret_hword); break;
#endif
#ifndef C16nodef
case 16: CTL_RD(C16bank,C16, *ret_hword); break;
#endif
#ifndef C17nodef
case 17: CTL_RD(C17bank,C17, *ret_hword); break;
#endif
#ifndef C18nodef
case 18: CTL_RD(C18bank,C18, *ret_hword); break;
#endif
#ifndef C19nodef
case 19: CTL_RD(C19bank,C19, *ret_hword); break;
#endif
#ifndef C20nodef
case 20: CTL_RD(C20bank,C20, *ret_hword); break;
#endif
case 21: CTL_RD(C21bank,C21, *ret_hword); break;
default: rdata[RD_LEN] = 0;
return ERR_CTL_PIN_NOT_PRESENT;
}
break;
//============================
//DATA PORT BYTE WIDE ACCESS
//opcode: type of operation
//operand: value to place on bus
//============================
case DATA_ENABLE_: DATA_ENABLE(); break;
case DATA_IP_PU_: DATA_IP_PU(); break;
case DATA_IP_: DATA_IP(); break;
case DATA_OP_: DATA_OP(); break;
case DATA_SET_: DATA_SET(operand); break;
case DATA_RD_: DATA_RD(rdata[RD0]);
rdata[RD_LEN] = 1; break;
//============================
//ADDR PORT 16bit WIDE ACCESS
//opcode: type of operation
//operand: value to place on bus
//============================
case ADDR_ENABLE_: ADDR_ENABLE(); break;
case ADDR_PU_: ADDR_PU(); break;
case ADDR_IP_: ADDR_IP(); break;
case ADDR_OP_: ADDR_OP(); break;
case ADDR_SET_: ADDR_SET(operand); break;
//============================
//EXP PORT 8bit ACCESS (bits1-8)
//opcode: type of operation
//operand: value to place on bus
//============================
case EXP_ENABLE_: EXP_ENABLE(); break;
case EXP_DISABLE_: EXP_DISABLE(); break;
case EXP_SET_: EXP_SET(operand); break;
default:
//macro doesn't exist or isn't on this PCB version
return ERR_UNKN_PP_OPCODE;
}
return SUCCESS;
}
#ifdef GREEN_KAZZO
/* Desc:
* other board versions have PORTB "DATA" feed into both FF's
* this board feeds EXP FF with PORTA "ADDR" instead
* goal is to make board versions 'identical'
* to do this we assume higher level functions will have already
* placed desired latch value on PORTB "Dbank->PORT"
* we need to juggle this data around and not stomp on anything
* Pre: DATA_OP() set
* curAHLaddr set by software_AHL_CLK
* Dbank->PORT contains desired value to be latched by EXP FF
* AXHL might not be set as O/P
* AXHL might not be low ready for AXHL_CLK
* Post:Both FF's have desired value latched
* ADDR_OP() left set
* curAXLaddr updated for use by software_AHL_CLK
* Dbank->PORT and ALbank->PORT replaced with original values
* AXHL left as O/P and ready for subsequent CLK
*/
//these variables are updated each time the FF's are clocked
//that way we can retain the value of other FF as both must be clocked at once
static uint8_t curAHLaddr;
static uint8_t curAXLaddr;
void software_AXL_CLK()
{
//first store current DATA & ADDR values
curAXLaddr = Dbank->PORT; //This is desired AXL value
uint8_t orig_addr = ALbank->PORT; //PORTA
//Put current AHL latched value on DATA as that's where it'll be relatched
//software_AHL_CLK function is one to maintain this value
Dbank->PORT = curAHLaddr;
//set ADDR as O/P and place desired value on bus
ADDR_OP(); //prob already be set, but in case not
ALbank->PORT = curAXLaddr;
//Clock both latches
AHL_OP(); //can't be sure "AHL" is OP as assumption is AXL will be used as latch
AHL_LO(); //can't be sure it's low either
//_AXHL_CLK(); //clock values
CTL_SET_HI(AHLbank, AHL); CTL_SET_LO(AHLbank, AHL);
//finally restore original DATA & ADDR values
Dbank->PORT = curAXLaddr;
ALbank->PORT = orig_addr;
}
/* Desc: Same premise as software_AXL_CLK above.
* this is a little simpler as data has already been feed with AHL value.
* just need to make sure AXL latch doesn't get corrupted.
* Pre: DATA_OP() set
* curAXLaddr set by software_AXL_CLK
* Dbank->PORT contains desired value to be latched by ADDRMID FF
* AXHL is already set to O/P
* AXHL already low ready for AXHL_CLK
* Post:Both FF's have desired value latched
* curAHLaddr updated for use by software_AXL_CLK
* Dbank->PORT and ALbank->PORT replaced with original values
* AXHL left as O/P and ready for subsequent CLK
*/
void software_AHL_CLK()
{
//first store current DATA & ADDR values
curAHLaddr = Dbank->PORT; //This is desired AHL value (store it for other function's use)
uint8_t orig_addr = ALbank->PORT; //PORTA
//Desired AHL latch value should have already been placed on Dbank->PORT.
//set ADDR as O/P and place curAXLaddr on bus other function should have updated it last latch
ADDR_OP(); //should already be set, but in case not
ALbank->PORT = curAXLaddr;
//Clock both latches
//Can assume AHL is OP as other versions would require it to latch AHL
//Can also assume it was left low, if not causes issues in all board versions
//_AXHL_CLK(); //clock values
CTL_SET_HI(AHLbank, AHL); CTL_SET_LO(AHLbank, AHL);
//finally restore original DATA & ADDR values
//never changed: Dbank->PORT = curAHLaddr;
ALbank->PORT = orig_addr;
}
#endif //GREEN_KAZZO

164
firmware/source/pinport.h Normal file
View File

@ -0,0 +1,164 @@
#ifndef _pinport_h
#define _pinport_h
#include "pinport_al.h"
#include "shared_errors.h"
#include "shared_dict_pinport.h"
uint8_t pinport_call( uint8_t opcode, uint8_t miscdata, uint16_t operand, uint8_t *rdata );
// used for a very short delay
//#define NOP() do { __asm__ __volatile__ ("nop"); } while (0)
//PIN MACROS
// PC0 "MCO"
#define MCO_IP_PU() CTL_IP_PU(MCObank, MCO)
#define MCO_IP_FL() CTL_IP_FL(MCObank, MCO)
#define MCO_OP() CTL_OP(MCObank, MCO)
#define MCO_LO() CTL_SET_LO(MCObank, MCO)
#define MCO_HI() CTL_SET_HI(MCObank, MCO)
#define MCO_RD(val) CTL_RD(MCObank, MCO, val)
// PC1 "ROMSEL"
#define ROMSEL_IP_PU() CTL_IP_PU(ROMSELbank, ROMSEL)
#define ROMSEL_IP_FL() CTL_IP_FL(ROMSELbank, ROMSEL)
#define ROMSEL_OP() CTL_OP(ROMSELbank, ROMSEL)
#define ROMSEL_LO() CTL_SET_LO(ROMSELbank, ROMSEL)
#define ROMSEL_HI() CTL_SET_HI(ROMSELbank, ROMSEL)
#define ROMSEL_RD(val) CTL_RD(ROMSELbank, ROMSEL, val)
// PC2 "PRGRW"
#define PRGRW_IP_PU() CTL_IP_PU(PRGRWbank, PRGRW)
#define PRGRW_IP_FL() CTL_IP_FL(PRGRWbank, PRGRW)
#define PRGRW_OP() CTL_OP(PRGRWbank, PRGRW)
#define PRGRW_LO() CTL_SET_LO(PRGRWbank, PRGRW)
#define PRGRW_HI() CTL_SET_HI(PRGRWbank, PRGRW)
#define PRGRW_RD(val) CTL_RD(PRGRWbank, PRGRW, val)
// PC3 "FREE"
#ifndef C3nodef
#define FREE_IP_PU() CTL_IP_PU(FREEbank, FREE)
#define FREE_IP_FL() CTL_IP_FL(FREEbank, FREE)
#define FREE_OP() CTL_OP(FREEbank, FREE)
#define FREE_LO() CTL_SET_LO(FREEbank, FREE)
#define FREE_HI() CTL_SET_HI(FREEbank, FREE)
#define FREE_RD(val) CTL_RD(FREEbank, FREE, val)
#endif
// PC4 "CSRD"
#define CSRD_IP_PU() CTL_IP_PU(CSRDbank, CSRD)
#define CSRD_IP_FL() CTL_IP_FL(CSRDbank, CSRD)
#define CSRD_OP() CTL_OP(CSRDbank, CSRD)
#define CSRD_LO() CTL_SET_LO(CSRDbank, CSRD)
#define CSRD_HI() CTL_SET_HI(CSRDbank, CSRD)
#define CSRD_RD(val) CTL_RD(CSRDbank, CSRD, val)
// PC5 "CSWR"
#define CSWR_IP_PU() CTL_IP_PU(CSWRbank, CSWR)
#define CSWR_IP_FL() CTL_IP_FL(CSWRbank, CSWR)
#define CSWR_OP() CTL_OP(CSWRbank, CSWR)
#define CSWR_LO() CTL_SET_LO(CSWRbank, CSWR)
#define CSWR_HI() CTL_SET_HI(CSWRbank, CSWR)
#define CSWR_RD(val) CTL_RD(CSWRbank, CSWR, val)
// PC6 "CICE"
#define CICE_IP_PU() CTL_IP_PU(CICEbank, CICE)
#define CICE_IP_FL() CTL_IP_FL(CICEbank, CICE)
#define CICE_OP() CTL_OP(CICEbank, CICE)
#define CICE_LO() CTL_SET_LO(CICEbank, CICE)
#define CICE_HI() CTL_SET_HI(CICEbank, CICE)
#define CICE_RD(val) CTL_RD(CICEbank, CICE, val)
// PC7 "AHL"
#ifndef C7nodef
#define AHL_IP_PU() CTL_IP_PU(AHLbank, AHL)
#define AHL_IP_FL() CTL_IP_FL(AHLbank, AHL)
#define AHL_OP() CTL_OP(AHLbank, AHL)
#define AHL_LO() CTL_SET_LO(AHLbank, AHL)
#define AHL_HI() CTL_SET_HI(AHLbank, AHL)
#define AHL_RD(val) CTL_RD(AHLbank, AHL, val)
#endif
// PC8 "EXP0"
#define EXP0_IP_PU() CTL_IP_PU(EXP0bank, EXP0)
#define EXP0_IP_FL() CTL_IP_FL(EXP0bank, EXP0)
#define EXP0_OP() CTL_OP(EXP0bank, EXP0)
#define EXP0_LO() CTL_SET_LO(EXP0bank, EXP0)
#define EXP0_HI() CTL_SET_HI(EXP0bank, EXP0)
#define EXP0_RD(val) CTL_RD(EXP0bank, EXP0, val)
// PC9 "LED"
#define LED_IP_PU() CTL_IP_PU(LEDbank, LED)
#define LED_IP_FL() CTL_IP_FL(LEDbank, LED)
#define LED_OP() CTL_OP(LEDbank, LED)
#define LED_LO() CTL_SET_LO(LEDbank, LED)
#define LED_HI() CTL_SET_HI(LEDbank, LED)
#define LED_RD(val) CTL_RD(LEDbank, LED, val)
// PC10 "IRQ"
#define IRQ_IP_PU() CTL_IP_PU(IRQbank, IRQ)
#define IRQ_IP_FL() CTL_IP_FL(IRQbank, IRQ)
#define IRQ_OP() CTL_OP(IRQbank, IRQ)
#define IRQ_LO() CTL_SET_LO(IRQbank, IRQ)
#define IRQ_HI() CTL_SET_HI(IRQbank, IRQ)
#define IRQ_RD(val) CTL_RD(IRQbank, IRQ, val)
// PC11 "CIA10"
#define CIA10_IP_PU() CTL_IP_PU(CIA10bank, CIA10)
#define CIA10_IP_FL() CTL_IP_FL(CIA10bank, CIA10)
#define CIA10_OP() CTL_OP(CIA10bank, CIA10)
#define CIA10_LO() CTL_SET_LO(CIA10bank, CIA10)
#define CIA10_HI() CTL_SET_HI(CIA10bank, CIA10)
#define CIA10_RD(val) CTL_RD(CIA10bank, CIA10, val
// PC12 "BL"
// PC13 "AXL"
#ifndef C13nodef
#ifdef PURPLE_KAZZO //tie two pins together via software
#define AXL_IP_PU() CTL_IP_PU(AXLbank, AXL) CTL_IP_PU(FREEbank, FREE)
#define AXL_IP_FL() CTL_IP_FL(AXLbank, AXL) CTL_IP_FL(FREEbank, FREE)
#define AXL_OP() CTL_OP(AXLbank, AXL) CTL_OP(FREEbank, FREE)
#define AXL_LO() CTL_SET_LO(AXLbank, AXL) CTL_SET_LO(FREEbank, FREE)
#define AXL_HI() CTL_SET_HI(AXLbank, AXL) CTL_SET_HI(FREEbank, FREE)
#define AXL_RD(val) CTL_RD(AXLbank, AXL, val)
#else //not PURPLE_KAZZO
#define AXL_IP_PU() CTL_IP_PU(AXLbank, AXL)
#define AXL_IP_FL() CTL_IP_FL(AXLbank, AXL)
#define AXL_OP() CTL_OP(AXLbank, AXL)
#define AXL_LO() CTL_SET_LO(AXLbank, AXL)
#define AXL_HI() CTL_SET_HI(AXLbank, AXL)
#define AXL_RD(val) CTL_RD(AXLbank, AXL, val)
#endif
#endif
// PC14 "AUDL"
// PC15 "AUDR"
// PC16 "CIN"
// PC17 "SWD"
// PC18 "SWC"
// PC19 "AFL"
#ifndef C19nodef
#define AFL_IP_PU() CTL_IP_PU(AFLbank, AFL)
#define AFL_IP_FL() CTL_IP_FL(AFLbank, AFL)
#define AFL_OP() CTL_OP(AFLbank, AFL)
#define AFL_LO() CTL_SET_LO(AFLbank, AFL)
#define AFL_HI() CTL_SET_HI(AFLbank, AFL)
#define AFL_RD(val) CTL_RD(AFLbank, AFL, val)
#endif
// PC20 "COUT"
// PC21 "FCAPU"
#endif

View File

@ -12,6 +12,206 @@
#include <stm32f0xx.h>
#endif
//This file contains pinout translations from AVR names to "kazzo" names
//this file also works to make all kazzo versions compatible and "alike"
//There are defines for kazzo version, turns out unique early versions
//can be differentiated by solder mask color.
//Final version is default and doesn't need any defines
//#define PURPLE_KAZZO
//#define GREEN_KAZZO //GREEN needs PURPLE defined at same time
#ifdef GREEN_KAZZO
void software_AHL_CLK();
void software_AXL_CLK();
#endif
//=======================================================
//History of PCB revsisions produced by InfiniteNesLives
//=======================================================
//
// uncomment define if buiding for either of the first two versions
//#define PURPLE_KAZZO
// First printed circuit board version
// only handful made (less than 10?)
// Purple solder mask
// Labeled "Kazzo PCB rev 3.0"
// Dated 8/22/2011
// * Only contained NES and Famicom connectors
// * Had bug where USB data lines mixed up
// -manually fixed during component assembly
// * Naruko determined this should have still been v1 board
// -due to it's overall design and conflicting with someother v3 board
// * This was my first ever PCB design and one of the first
// times designing something for the NES/FC. Looking
// back at the design there were some very noob decisions...
// * INPUT/OUTPUT differences:
// EXP9 - PD1/LED jumper
// when closed, PD1 controls NES EXP9 and LED
// when open, EXP9 is floating PD1 only controls LED
// NES EXP9 was connected to GND pin #16 on FC
// -I must have thought that GND pin could serve
// different purpose..
// -Result is PD1 is shorted to GND when FC cart inserted
// and jumper closed..
// Believe I closed this jumper on units I shipped
// prob should have left it open..
// Suggested fix: leave open and ground EXP9
// -prevents issue with LED when FC cart inserted
// -minor draw back no access to EXP9
// ALOG - EXP6 - DIGI jumper
// another noob jumper decision...
// ALOG is the MCU AREF pin which should be tied to VCC
// -I thought it was an analog in apparently...
// DIGI is EXP flip flop Q6 output
// Best position for this jumper is EXP6-DIGI
// ALOG pad should be tied to VCC with jumper..
// Doing that would make it similar to future designs.
// Don't think I shipped any with ALOG jumper closed
// NES EXP6 is tied to Famicom pin 46 (Sound to RF)
// Expansion port FlipFlop /OE - CLK
// Aside from lame jumper design above, biggest difference
// between this PCB version and future ones.
// -EXP FF /OE controlled by MCU PD7
// -EXP FF CLK controlled by MCU PC3
// Future versions control both /OE and CLK with PD7
// -this frees PC3 for user use
// Both FlipFlops D i/p are driven by Data bus (PORT B)
//
//
// Second printed circuit board version
// only handful made (about a dozen?)
// Purple solder mask
// Labeled "Kazzo PCB rev 1.1"
// Dated 8/22/2011
// * Only contained NES and Famicom connectors
// * Identical to version above aside from the following
// * Corrected bug where USB data lines mixed up
// * Changed silkscreen to v1.1 as suggested by naruko
// * INPUT/OUTPUT differences:
// -Same as version above as far as I know.
//
//
// uncomment define if buiding for this versions
//#define GREEN_KAZZO
//
// Third printed circuit board version
// only handful made (about ten?) used primarily as SNES prototype
// Green solder mask
// Labeled "Retro programmer/dumper v1.2" "Kazzo 1.x"
// Dated Apr 2013
// * First version to add SNES connector along with NES & FC
// * Removed noob jumpers from purple versions above.
// -grouned FC pin16 as it should have been.
// * INPUT/OUTPUT differences:
// -EXP FF /OE still controlled by MCU PD7
// -MCU PC7 controls both CLK on both FF's.
// -EXP FF D inputs are PORTA
// all other versions are driven by PORTB
// This means you always have to clock both flipflops
// Place desired value on PORTA/B respectively and clock with PD7
// -PC3 is free for user use.
// -SNES /RESET pin not controlled by PD0 (EXP0)
// instead it's controlled by A20 (EXPFF Q4)
// prevents putting INL SNES boards in program mode unless A20 is also low
// pretty much makes flashing SNES boards a royal PITA/impossible
// Suggested fix is to have PD0 (EXP0) control SNES /RESET
// would have to free /RESET and wire to EXP0/PD0 to permit flashing/reading INL SNES board.
//
//
// Fourth printed circuit board version
// First volume PCB run ~300 copies
// Yellow solder mask
// Labeled "Retro programmer/dumper v1.2b" "Kazzo 1.x"
// Dated May 2013
// * Includes NES, Famicom, & SNES connector
// * SNES board must be removed from case and slid all the way to right
// * Pitch offset on SNES connector makes it difficult to connect with original SNES boards.
// -Connector designed to only provide support for INL SNES Hi/Lo-ROM boards.
// * Care must be excersized not to insert SNES board backwards applying reverse power.
// * Effectively Final circuit design after lessons learned on small batches that preceeded.
// * INPUT/OUTPUT differences:
// -EXP FF /OE & CLK controlled by MCU PD7
// -MCU PC7 only controls CLK on ADDR HIGH FF.
// -EXP & ADDRHI FF D inputs both on Data bus PORTB
// -PC3 is free for user use.
// -SNES /RESET pin controlled by PD0 (EXP0)
// -Retains prev ver fixes, nothing funny going on with jumpers FC GND pin #16
//
//
// Fifth printed circuit board version
// Second volume PCB run ~500 copies
// Yellow solder mask
// Labeled "Retro programmer/dumper v1.2b" "Kazzo 1.x"
// Dated OCT 2014
// * Includes NES, Famicom, & SNES connector
// * SNES connector setup/cautions just like the prev version.
// * No significant changes from previous version.
// -Changed MCU clock to Crystal instead of resonator in prev ver.
// -Added screw mount holes, although not very well placed.
// * INPUT/OUTPUT differences:
// -None from previous version
//
//
// Sixth printed circuit board version
// Third volume PCB run in production as of 1NOV2016
// Orange solder mask
// Labeled "Retro programmer/dumper v1.4" "Kazzo 1.x"
// Dated OCT 2016
// Addition of fancy INL logo for first time
// * Includes NES, Famicom, & SNES connector
// * SNES connector improvement to correct pitch issue with prev ver.
// * Addition of PCT resettable fuse on incoming power.
// -Provides protection to SNES boards inserted backwards.
// * Rearrangement of BL/RUN switch and screw holes for better case design.
// * Cut out buzzer pads (PD6) from under MCU which was never developed.
// * INPUT/OUTPUT differences:
// -None from previous version
//
//
// STM32F070C6T6 KAZZO USB 2.0 ADAPTER board prototype
// designed to retrofit all previous kazzo versions
// updates to arm cortex M0 core and hardware USB 2.0
// Green solder mask
// Labeled "KAZZO USB 2.0 ADAPTER" "V1.P"
// Dated JAN 2017
// Pins out to all DIP-40 pins:
// AVR reset -> STM reset
// AVR BOOTLOADn -> STM BOOT0 (not sure if this actually works...)
// AVR XTAL1/2 -> STM oscOUT/IN (PF1/0)
//
// ascii art board connections setup:
//AVR PIN #40<. .-> AVR PIN #20
// __|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|_
// | O O O O O O O O O O O O O O O O O O O O|
// | "KAZZO USB 2.0 ADAPTER" |
// kazzo | programming header /\ 6pin extra port | kazzo
// rst butn | O- /RESET / \ EMPTY -O O- PA6 | AVR PA6 "FREE"
// CIRAM_A10| O- SWD (PA13) CIRAM A10 /STM \ EMPTY -O O- PC15 | nc
// GND | O- GND \ 32 / 3v3 -O O- PC14 | nc
// nc | O- SWC (PA14) \ ./ GND -O O- PA1 | nc
// nc | O- 3v3 \/ 5v -O O- PA0 | EXP0
// | |
// | O O O O O O O O O O O O O O O O O O O O|
// -------------------------------------------------------------
// | | | | | | | | | | | | | | | | | | | |
//AVR PIN #1<-` `-> AVR PIN #19
//
//
//
// STM32F070RBT6 "INL RETRO 6" prototype
// completely new design with 6 connectors:
// GBA/DMG, SNES/SFC, NES, N64, Sega gen, Famicom
// updates to arm cortex M0 core and hardware USB 2.0
// Green solder mask
// Labeled "INL RETRO PROGRAMMER DUMPER V2.0P"
// Dated MAY 2017
// Unlike all previous version above this has direct access to most pins
// Only exception is one Flipflop for SegaGen A17-18, 20-23, #LO_MEM, & #TIME
// flipflop also drives SNES PA0-7
//=============================================================================================
//
// PINPORT ABSTRACTION LAYER
@ -77,9 +277,10 @@
// This ends up being a little cleaner than AVR i/o interfacing
// Can probably just enable pull-ups on everything and leave it like that
// -only exception being USB pins (PA11/12) better leave those floating
//#define PUPDR_FLT 0x00
//#define PUPDR_FL 0x00
#define PUPDR_PU 0x01
#define PUPDR_PD 0x10
#define PUPDR_PU_ALL 0x55555555
//
// GPIOx->IDR 16bit register used to read current input level on pin
// this register is read only
@ -141,12 +342,22 @@
// Read/Input: Bit access only, returned byte/word will be zero if clear, non-zero if set
//
// PORT C pin definitions
// Don't assign one mcu pin to more than one pin in this port!
// Try not to assign one mcu pin to more than one pin in this port.
// mcu pin can be assigned in other ports, as initializing
// those ports will 'disable' the pin in this port.
// if the pin has multiple purposes and would like to give
// it different names based on the cart inserted, just create
// multiple defines/names for the one PCn pin.
// If a ctl pin is needed that's mapped to different mcu pins based on the board,
// create a new control port pin and violate the first rule with caution.
//
// Creation of new signals:
// 1) Create PC# -> mcupin assignment below
// 2) map pin name to PC# which follows assignments below
// 3) add applicable macro calls to pinport.c
// 4) add pin name to shared_dict_pinport.h operands for simple calling from host
// 5) add shortcut macros to pinport.h if desired
// 6) ensure CTL PORT ENABLE macro enables new pin adequately
//
// ---------------------------------------------------------------------------------------
@ -164,8 +375,9 @@
#define C2bank GPIOA
#define C2 (1U)
// PC3 "PAXL"
// Not defined
// PC3 "FREE"
// Not defined
#define C3nodef
// PC4 "CSRD" mcupinA2
#define C4bank GPIOA
@ -181,6 +393,7 @@
// PC7 "AHL"
// Not defined
#define C7nodef
// PC8 "EXP0" mcupinA6
#define C8bank GPIOA
@ -200,9 +413,11 @@
// PC12 "BL"
// Not defined
#define C12nodef
// PC13 "AXL"
// Not defined
#define C13nodef
// PC14 "AUDL" mcupinA4
#define C14bank GPIOA
@ -232,10 +447,14 @@
#define C20bank GPIOD
#define C20 (2U)
// PC21 "FCAPU" double mapping of AUDR
#define C21bank C15bank
#define C21 C15
/* NEED MORE UNIQUE names for these pins to not conflict with Data port definitions...
// PC21 "D8" mcupinB10
#define C21bank GPIOB
#define C21 (10U)
// PCxx "D8" mcupinB10
#define Cxxbank GPIOB
#define Cxx (10U)
// PC22 "D9" mcupinB11
#define C22bank GPIOB
@ -258,10 +477,11 @@
#define C26 (15U)
*/
#define IOP_LED_EN RCC_AHBENR_GPIOBEN
#define RCC_AHBENR_CTL (RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOBEN | RCC_AHBENR_GPIODEN)
#define RCC_AHBENR_ADDR RCC_AHBENR_GPIOCEN
#define RCC_AHBENR_DATA RCC_AHBENR_GPIOBEN
#define RCC_AHBENR_EXP (RCC_AHBENR_GPIOBEN | RCC_AHBENR_GPIOBEN)
#endif //STM_INL6
@ -280,8 +500,12 @@
#define C2bank GPIOA
#define C2 (5U)
// PC3 "PAXL"
// Not defined
// PC3 "FREE" mcupinA6
#define C3bank GPIOA
#define C3 (6U)
#ifdef PURPLE_KAZZO
#define C3nodef //assigned to PAXL instead which is tied to AXL /OE in software
#endif
// PC4 "CSRD" mcupinA7
#define C4bank GPIOA
@ -317,6 +541,7 @@
// PC12 "BL"
// Not defined
#define C12nodef
// PC13 "AXL" mcupinA2
#define C13bank GPIOA
@ -324,15 +549,19 @@
// PC14 "AUDL"
// Not defined
#define C14nodef
// PC15 "AUDR"
// Not defined
#define C15nodef
// PC16 "CIN"
// Not defined
#define C16nodef
// PC17 "SWD" mcupinA13
// Not defined due to shared with CIRAM A10
#define C17nodef
// PC18 "SWC" mcupinA14
#define C18bank GPIOA
@ -340,29 +569,20 @@
// PC19 "AFL"
// Not defined
#define C19nodef
// PC20 "COUT"
// Not defined
#define C20nodef
// PC21 "D8"
// Not defined
// PC21 "FCAPU" double mapping of EXP0
#define C21bank C8bank
#define C21 C8
// PC22 "D9"
// Not defined
// PC23 "D10"
// Not defined
// PC24 "D11"
// Not defined
// PC25 "D12"
// Not defined
// PC26 "D13"
// Not defined
#define IOP_LED_EN RCC_AHBENR_GPIOCEN
#define RCC_AHBENR_CTL (RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOBEN | RCC_AHBENR_GPIOCEN)
#define RCC_AHBENR_ADDR (RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOBEN)
#define RCC_AHBENR_DATA RCC_AHBENR_GPIOBEN
#endif //STM_ADAPTER
@ -381,8 +601,12 @@
#define C2bank GPIOC
#define C2 (2U)
// PC3 "PAXL" mcupinC3
// Not defined
// PC3 "FREE" mcupinC3
#define C3bank GPIOC
#define C3 (3U)
#ifdef PURPLE_KAZZO
#define C3nodef //assigned to PAXL instead which is tied to AXL /OE in software
#endif
// PC4 "CSRD" mcupinC4
#define C4bank GPIOC
@ -420,48 +644,42 @@
#define C12bank GPIOD
#define C12 (6U)
// PC13 "AXL" mcupinD7
// PC13 "AXL" mcupinD7 //PURPLE KAZZO uses this for /OE only
#define C13bank GPIOD
#define C13 (7U)
// PC14 "AUDL"
// not defined
#define C14nodef
// PC15 "AUDR"
// not defined
#define C15nodef
// PC16 "CIN"
// not defined
#define C16nodef
// PC17 "SWD"
// not defined
#define C17nodef
// PC18 "SWC"
// not defined
#define C18nodef
// PC19 "AFL"
// not defined
#define C19nodef
// PC20 "COUT"
// not defined
#define C20nodef
// PC21 "D8"
// not defined
// PC21 "FCAPU" double mapping of EXP0
#define C21bank C8bank
#define C21 C8
// PC22 "D9"
// not defined
// PC23 "D10"
// not defined
// PC24 "D11"
// not defined
// PC25 "D12"
// not defined
// PC26 "D13"
// not defined
#endif //AVR_KAZZO
@ -474,8 +692,6 @@
// PC0 "MCO" mcu clock out M2/phi2, Sysclk, etc
#define MCO C0
#define MCObank C0bank
#define M2 C0
#define M2bank C0bank
// PC1 "ROMSEL" Cartridge rom enable
#define ROMSEL C1
@ -485,9 +701,9 @@
#define PRGRW C2
#define PRGRWbank C2bank
// PC3 "PAXL" purple kazzo EXP flipflop latch, FREE on most kazzos
#define PAXL C3
#define PAXLbank C3bank
// PC3 "FREE" purple kazzo EXP flipflop latch, FREE on most kazzos
#define FREE C3
#define FREEbank C3bank
// PC4 "CSRD" NES CHR/SNES /RD
#define CSRD C4
@ -505,7 +721,7 @@
#define AHL C7
#define AHLbank C7bank
// PC8 "EXP0" NES EXP0, cart-console /RESET
// PC8 "EXP0" NES EXP0, FC APU sound, cart-console /RESET
#define EXP0 C8
#define EXP0bank C8bank
@ -558,11 +774,15 @@
#define COUT C20
#define COUTbank C20bank
// PC21 "FCAPU" cart audio in
#define FCAPU C21
#define FCAPUbank C21bank
// INLretro6 gains direct control over NES EXP port and is used for N64 control pins:
/*
// PC21 "D8"
#define D8 C21
#define D8bank C21bank
// PCxx "D8"
#define D8 Cxx
#define D8bank Cxxbank
// PC22 "D9"
#define D9 C22
@ -594,22 +814,28 @@
#ifdef STM_CORE
#define CTL_IP_PU(bank, pin) bank->MODER &= ~(MODER_OP<<(pin*2)); bank->PUPDR |= (PUPDR_PU<<(pin*2))
#define CTL_IP_FLT(bank, pin) bank->MODER &= ~(MODER_OP<<(pin*2)); bank->PUPDR &= ~(PUPDR_PU<<(pin*2))
#define CTL_IP_FL(bank, pin) bank->MODER &= ~(MODER_OP<<(pin*2)); bank->PUPDR &= ~(PUPDR_PU<<(pin*2))
#define CTL_OP(bank, pin) bank->MODER |= (MODER_OP<<(pin*2))
#define CTL_READ(bank, pin, val) val = (bank->IDR & (1<<pin))
#define CTL_SET_HI(bank, pin) bank->BSRR = 1<<pin
#define CTL_SET_LO(bank, pin) bank->BRR = 1<<pin
#define CTL_SET_HI(bank, pin) bank->BSRR = 1<<pin
#define CTL_RD(bank, pin, val) val = (bank->IDR & (1<<pin))
//NOTE: STM registers are 16bit "halfwords" so must provide a 16bit val
#define CTL_ENABLE() RCC->AHBENR |= RCC_AHBENR_CTL
#endif //STM_CORE
#ifdef AVR_CORE
#define CTL_IP_PU(bank, pin) bank->DDR &= ~(1<<pin); bank->PORT |= (1<<pin)
#define CTL_IP_FLT(bank, pin) bank->DDR &= ~(1<<pin); bank->PORT &= ~(1<<pin)
#define CTL_IP_FL(bank, pin) bank->DDR &= ~(1<<pin); bank->PORT &= ~(1<<pin)
#define CTL_OP(bank, pin) bank->DDR |= (1<<pin)
#define CTL_READ(bank, pin, val) val = (bank->PIN & (1<<pin))
#define CTL_SET_HI(bank, pin) bank->PORT |= (1<<pin)
#define CTL_SET_LO(bank, pin) bank->PORT &= ~(1<<pin)
#define CTL_SET_HI(bank, pin) bank->PORT |= (1<<pin)
#define CTL_RD(bank, pin, val) val = (bank->PIN & (1<<pin))
#define CTL_ENABLE() //nothing to be done for AVR
#endif //AVR_CORE
@ -617,8 +843,19 @@
// CONTROL PORT MACROS to simplify flipflop operations
//
#define _AHL_CLK() CTL_SET_HI(AHLbank, AHL); CTL_SET_LO(AHLbank, AHL)
#define _AXL_CLK() CTL_SET_HI(AXLbank, AXL); CTL_SET_LO(AXLbank, AXL)
#ifndef STM_INL6
#ifdef GREEN_KAZZO
#define AHL_CLK() software_AHL_CLK()
#define AXL_CLK() software_AXL_CLK()
#elif PURPLE_KAZZO
#define AHL_CLK() CTL_SET_HI(AHLbank, AHL); CTL_SET_LO(AHLbank, AHL)
#define AXL_CLK() CTL_SET_HI(FREEbank, FREE); CTL_SET_LO(FREEbank, FREE)
#else
#define AHL_CLK() CTL_SET_HI(AHLbank, AHL); CTL_SET_LO(AHLbank, AHL)
#define AXL_CLK() CTL_SET_HI(AXLbank, AXL); CTL_SET_LO(AXLbank, AXL)
#endif
#endif
// ---------------------------------------------------------------------------------------
// DATA PORT 8bit
@ -628,6 +865,8 @@
// Driver: All pins are push-pull, and unknown floating/pull-up when input
// main reason to be unknown is AVR uses PORT for pull-up enable
// don't want to require re-enabling pullups for every data access
// STM32 are default to pull-up, AVR requires manually pulling up
// by calling DATA_IP_PU() if pullups required, otherwise unknown
// Write/Output: Byte access only, no bit accesses. Must be returned to input after read!
// Read/Input: Default condition, byte access only
//
@ -645,24 +884,35 @@
#define Dbank GPIOB
//IP and OP assume MODER[1] is clear (ie not set to Alt Func)
#define _DATA_IP() Dbank->MODER &= ~(MODER_OP_ALL & 0x000FFFF0)
#define _DATA_OP() Dbank->MODER |= (MODER_OP_ALL & 0x000FFFF0)
#define _DATA_SET(data) Dbank->ODR = (Dbank->ODR & 0xFC03) | (data<<2)
#define _DATA_RD(data) data = (Dbank->IDR>>2) & 0x00FF
//also assume PUPDR is reset default floating
#define DATA_IP_PU() Dbank->MODER &= ~(MODER_OP_ALL & 0x000FFFF0); Dbank->PUPDR |= (PUPDR_PU_ALL & 0x000FFFF0)
#define DATA_IP() Dbank->MODER &= ~(MODER_OP_ALL & 0x000FFFF0)
#define DATA_OP() Dbank->MODER |= (MODER_OP_ALL & 0x000FFFF0)
#define DATA_SET(data) Dbank->ODR = (Dbank->ODR & 0xFC03) | (data<<2)
#define DATA_RD(data) data = (Dbank->IDR>>2) & 0x00FF
#define DATA_EN_CLK() RCC->AHBENR |= RCC_AHBENR_DATA
#define DATA_ENABLE() DATA_EN_CLK(); DATA_IP_PU();
#endif //STM_INL6
#ifdef STM_ADAPTER
//All 8bits are on GPIOB inorder, but mapped to bits15-8
//All 8bits are on GPIOB in order, but mapped to bits15-8
#define Dbank GPIOB
//IP and OP assume MODER[1] is clear (ie not set to Alt Func)
#define _DATA_IP() Dbank->MODER &= ~(MODER_OP_ALL & 0xFFFF0000)
#define _DATA_OP() Dbank->MODER |= (MODER_OP_ALL & 0xFFFF0000)
//also assume PUPDR is reset default floating
#define DATA_IP_PU() Dbank->MODER &= ~(MODER_OP_ALL & 0xFFFF0000); Dbank->PUPDR |= (PUPDR_PU_ALL & 0xFFFF0000)
#define DATA_IP() Dbank->MODER &= ~(MODER_OP_ALL & 0xFFFF0000)
#define DATA_OP() Dbank->MODER |= (MODER_OP_ALL & 0xFFFF0000)
//TODO create byte wide port structs to grant byte accesses so doesn't need shifted
#define _DATA_SET(data) Dbank->ODR = (Dbank->ODR & 0x00FF) | (data<<8)
#define _DATA_RD(data) data = (Dbank->IDR>>8) & 0x00FF
#define DATA_SET(data) Dbank->ODR = (Dbank->ODR & 0x00FF) | (data<<8)
#define DATA_RD(data) data = (Dbank->IDR>>8) & 0x00FF
#define DATA_EN_CLK() RCC->AHBENR |= RCC_AHBENR_DATA
#define DATA_ENABLE() DATA_EN_CLK(); DATA_IP_PU()
#endif //STM_ADAPTER
@ -671,11 +921,13 @@
//All 8bits are on GPIOB aligned perfectly
#define Dbank GPIOB
#define _DATA_IP() Dbank->DDR = 0x00
#define _DATA_OP() Dbank->DDR = 0xFF
#define _DATA_SET(data) Dbank->PORT = data
#define _DATA_RD(data) data = Dbank->PIN
#define DATA_SET(data) Dbank->PORT = data
#define DATA_IP_PU() Dbank->DDR = 0x00; DATA_SET(0xFF)
#define DATA_IP() Dbank->DDR = 0x00
#define DATA_OP() Dbank->DDR = 0xFF
#define DATA_RD(data) data = Dbank->PIN
#define DATA_ENABLE() DATA_IP_PU()
#endif //AVR_KAZZO
@ -696,11 +948,15 @@
//All 16bits are on GPIOC in perfect alignment
#define Abank GPIOC
#define _ADDR_IP() Abank->MODER &= ~MODER_OP_ALL
#define _ADDR_OP() Abank->MODER |= MODER_OP_ALL
#define _ADDRL(low) Abank->ODR = (Abank->ODR & 0xFF00) | low
#define _ADDRH(high) Abank->ODR = (Abank->ODR & 0x00FF) | (high<<8)
#define _ADDR(hword) Abank->ODR = hword
#define ADDR_PU() Abank->PUPDR |= PUPDR_PU_ALL
#define ADDR_IP() Abank->MODER &= ~MODER_OP_ALL
#define ADDR_OP() Abank->MODER |= MODER_OP_ALL
#define ADDRL(low) Abank->ODR = (Abank->ODR & 0xFF00) | low
#define ADDRH(high) Abank->ODR = (Abank->ODR & 0x00FF) | (high<<8)
#define ADDR_SET(hword) Abank->ODR = hword
#define ADDR_EN_CLK() RCC->AHBENR |= RCC_AHBENR_ADDR
#define ADDR_ENABLE() ADDR_EN_CLK(); ADDR_OP()
#endif //STM_INL6
@ -712,12 +968,17 @@
#define A76bank GPIOA
#define A50bank GPIOB
#define _ADDR_IP() A76bank->MODER &= ~(MODER_OP_ALL & 0x000F0000); A50bank->MODER &= ~(MODER_OP_ALL & 0x0000FFF0)
#define _ADDR_OP() A76bank->MODER |= (MODER_OP_ALL & 0x000F0000); A50bank->MODER |= (MODER_OP_ALL & 0x0000FFF0)
#define _ADDRL(low) A76bank->ODR = (A76bank->ODR & 0xFCFF) | ((low & 0xC0)<<2);A50bank->ODR = (A50bank->ODR & 0xFF03) | ((low & 0x3F)<<2)
#define ADDR_PU() A76bank->PUPDR |= (PUPDR_PU_ALL & 0x000F0000); A50bank->PUPDR |= (PUPDR_PU_ALL & 0x0000FFF0)
#define ADDR_IP() A76bank->MODER &= ~(MODER_OP_ALL & 0x000F0000); A50bank->MODER &= ~(MODER_OP_ALL & 0x0000FFF0)
#define ADDR_OP() A76bank->MODER |= (MODER_OP_ALL & 0x000F0000); A50bank->MODER |= (MODER_OP_ALL & 0x0000FFF0)
#define ADDRL(low) A76bank->ODR = (A76bank->ODR & 0xFCFF) | ((low & 0xC0)<<2);A50bank->ODR = (A50bank->ODR & 0xFF03) | ((low & 0x3F)<<2)
//clocks must be initialized, Data bus clear
#define _ADDRH(high) _DATA_OP(); _DATA_SET(high); _AHL_CLK(); _DATA_IP();
#define _ADDR(hword) ADDRL(hword); _ADDRH(hword>>8)
#define ADDRH(high) DATA_OP(); DATA_SET(high); AHL_CLK(); DATA_IP()
#define ADDR_SET(hword) ADDRL(hword); ADDRH(hword>>8)
#define ADDR_EN_CLK() RCC->AHBENR |= RCC_AHBENR_ADDR
#define ADDR_EN_FF() CTL_OP(AHLbank, AHL); CTL_SET_LO(AHLbank, AHL)
#define ADDR_ENABLE() ADDR_EN_CLK(); ADDR_EN_FF(); ADDR_OP()
#endif //STM_ADAPTER
@ -725,16 +986,86 @@
// A15-8 are behind AHL flipflop
// A7-0 are on GPIOA perfectly aligned
#define _ALbank GPIOA
#define ALbank GPIOA
#define _ADDRL(low) GPIOA->PORT = low
#define ADDR_PU() ALbank->PORT = 0xFF
#define ADDR_IP() ALbank->DDR = 0x00
#define ADDR_OP() ALbank->DDR = 0xFF
#define ADDRL(low) GPIOA->PORT = low
//clocks must be initialized, Data bus clear
#define _ADDRH(high) _DATA_OP(); _DATA_SET(high); _AHL_CLK(); _DATA_IP();
#define _ADDR(hword) ADDRL(hword); _ADDRH(hword>>8)
#define ADDRH(high) DATA_OP(); DATA_SET(high); AHL_CLK(); DATA_IP();
#define ADDR_SET(hword) ADDRL(hword); ADDRH(hword>>8)
#define ADDR_EN_FF() CTL_OP(AHLbank, AHL); CTL_SET_LO(AHLbank, AHL)
#define ADDR_ENABLE() ADDR_EN_FF(); ADDR_OP();
#endif //AVR_KAZZO
// ---------------------------------------------------------------------------------------
// EXPANSION PORT 8bit pins #1-8
//
// This port is present on all devices but implemented differently.
// This port is primarily targeted as a NES cartridge port to connect to EXP1-8
// EXP0 has it's own dedicated pin in CTL PORT, EXP9 is dual purposed with LED on AVR/adapters
// AVR & ADAPTER connect EXP6 to Famicom RF audio (cart output)
// INL6 dual purposes EXP6, 8, & 9 with CLT PORT AUDL, SWCLK, & AUDR respectively
// Need some sort of interlock to ensure CTL PORT & EXP PORT don't stop on eachother's shared pins
// Extra macros are needed to make this port compatible on early versions of AVR KAZZO
// AVR & Adapter have access via 8x Flipflop
// -these devices also map these pins to A16-23
// INL6 has direct pin access
// -these pins also act as Data8-15 for Sega Genesis
// -has separate pins dedicated to A16-23
// Directionality: All pins are forced output, or tristate. This maintains compatability
// between all devices
// Driver: All pins are push-pull, AVR & STM ADAPTER drive with 5v signals, INL6 drives with 3.3v
// Write/Output: Byte access only, no bit accesses
// Read/Input: Not supported
//
// ---------------------------------------------------------------------------------------
#ifdef STM_INL6
//pins1-5 = GPIOB10-14 (D8-12), pin6 = GPIOA4 (AUDL), pin7 = GPIOB15 (D13), pin8 = GPIOA14 (SWCLK)
//these defines are quite the mess currently due to pins all over the place
//there is no real benefit to defining this port as byte wide but defining them this way 'degrades'
//them to the same quality as AVR making all devices mostly compatible.
//These can be redefined as CONTROL PORT for simpler pin granuarity access
#define E157bank GPIOB
#define E68bank GPIOA
#define EXP_PU() E157bank->PUPDR |= (PUPDR_PU_ALL & 0xFFF00000); E68bank->PUPDR |= (PUPDR_PU_ALL & 0x30000300)
#define EXP_IP() E157bank->MODER &=~(MODER_OP_ALL & 0xFFF00000); E68bank->MODER &=~(MODER_OP_ALL & 0x30000300)
#define EXP_OP() E157bank->MODER |= (MODER_OP_ALL & 0xFFF00000); E68bank->MODER |= (MODER_OP_ALL & 0x30000300)
//not sure these bit shift accesses will work if the value passed in is a uint8_t variable...
#define EXP_SET(val) E157bank->ODR = ((E157bank->ODR & 0x03FF) | (val<<10 & 0x7C00) | (val<<9 & 0x8000)); E68bank->ODR = ((E68bank->ODR & 0xBFEF) | (val>>1 & 0x0010) | (val<<7 & 0x4000))
#define EXP_EN_CLK() RCC->AHBENR |= RCC_AHBENR_EXP
#define EXP_ENABLE() ADDR_EN_CLK(); EXP_OP()
#define EXP_DISABLE() EXP_PU(); EXP_IP()
//STM_INL6
#else //AVR_KAZZO or STM_ADAPTER
// EXP1-8 are behind AXL flipflop
//clocks must be initialized, Data bus clear
#define EXP_SET(val) DATA_OP(); DATA_SET(val); AXL_CLK(); DATA_IP()
#ifdef PURPLE_KAZZO
#define EXP_EN_FF() CTL_OP(AXLbank, AXL); CTL_SET_LO(AXLbank, AXL); CTL_OP(FREEbank, FREE); CTL_SET_LO(FREEbank, FREE);
#define EXP_DISABLE() CTL_IP_PU(AXLbank, AXL); CTL_IP_PU(FREEbank, FREE)
#else
#define EXP_EN_FF() CTL_OP(AXLbank, AXL); CTL_SET_LO(AXLbank, AXL)
#define EXP_DISABLE() CTL_IP_PU(AXLbank, AXL)
#endif
#define EXP_ENABLE() DATA_ENABLE(); CTL_ENABLE(); EXP_EN_FF()
#endif //AVR_KAZZO or STM_ADAPTER
#endif

View File

@ -1,581 +0,0 @@
#ifndef _pinport_h
#define _pinport_h
#include "logic.h"
#include "shared_errors.h"
#include "shared_dict_pinport.h"
uint8_t pinport_opcode_only( uint8_t opcode );
uint8_t pinport_opcode_8b_operand( uint8_t opcode, uint8_t operand );
uint8_t pinport_opcode_16b_operand( uint8_t opcode, uint8_t operandMSB, uint8_t operandLSB );
uint8_t pinport_opcode_24b_operand( uint8_t opcode, uint8_t operandMSB, uint8_t operandMID, uint8_t operandLSB );
uint8_t pinport_opcode_8b_return( uint8_t opcode, uint8_t *rvalue );
void software_AHL_CLK();
void software_AXL_CLK();
//This file contains pinout translations from AVR names to "kazzo" names
//this file also works to make all kazzo versions compatible and "alike"
//There are defines for kazzo version, turns out unique early versions
//can be differentiated by solder mask color.
//Final version is default and doesn't need any defines
//#define PURPLE_KAZZO
//#define GREEN_KAZZO
//=======================================================
//History of PCB revsisions produced by InfiniteNesLives
//=======================================================
//
// uncomment define if buiding for either of the first two versions
//#define PURPLE_KAZZO
// First printed circuit board version
// only handful made (less than 10?)
// Purple solder mask
// Labeled "Kazzo PCB rev 3.0"
// Dated 8/22/2011
// * Only contained NES and Famicom connectors
// * Had bug where USB data lines mixed up
// -manually fixed during component assembly
// * Naruko determined this should have still been v1 board
// -due to it's overall design and conflicting with someother v3 board
// * This was my first ever PCB design and one of the first
// times designing something for the NES/FC. Looking
// back at the design there were some very noob decisions...
// * INPUT/OUTPUT differences:
// EXP9 - PD1/LED jumper
// when closed, PD1 controls NES EXP9 and LED
// when open, EXP9 is floating PD1 only controls LED
// NES EXP9 was connected to GND pin #16 on FC
// -I must have thought that GND pin could serve
// different purpose..
// -Result is PD1 is shorted to GND when FC cart inserted
// and jumper closed..
// Believe I closed this jumper on units I shipped
// prob should have left it open..
// Suggested fix: leave open and ground EXP9
// -prevents issue with LED when FC cart inserted
// -minor draw back no access to EXP9
// ALOG - EXP6 - DIGI jumper
// another noob jumper decision...
// ALOG is the MCU AREF pin which should be tied to VCC
// -I thought it was an analog in apparently...
// DIGI is EXP flip flop Q6 output
// Best position for this jumper is EXP6-DIGI
// ALOG pad should be tied to VCC with jumper..
// Doing that would make it similar to future designs.
// Don't think I shipped any with ALOG jumper closed
// NES EXP6 is tied to Famicom pin 46 (Sound to RF)
// Expansion port FlipFlop /OE - CLK
// Aside from lame jumper design above, biggest difference
// between this PCB version and future ones.
// -EXP FF /OE controlled by MCU PD7
// -EXP FF CLK controlled by MCU PC3
// Future versions control both /OE and CLK with PD7
// -this frees PC3 for user use
// Both FlipFlops D i/p are driven by Data bus (PORT B)
//
//
// Second printed circuit board version
// only handful made (about a dozen?)
// Purple solder mask
// Labeled "Kazzo PCB rev 1.1"
// Dated 8/22/2011
// * Only contained NES and Famicom connectors
// * Identical to version above aside from the following
// * Corrected bug where USB data lines mixed up
// * Changed silkscreen to v1.1 as suggested by naruko
// * INPUT/OUTPUT differences:
// -Same as version above as far as I know.
//
//
// uncomment define if buiding for this versions
//#define GREEN_KAZZO
//
// Third printed circuit board version
// only handful made (about ten?) used primarily as SNES prototype
// Green solder mask
// Labeled "Retro programmer/dumper v1.2" "Kazzo 1.x"
// Dated Apr 2013
// * First version to add SNES connector along with NES & FC
// * Removed noob jumpers from purple versions above.
// -grouned FC pin16 as it should have been.
// * INPUT/OUTPUT differences:
// -EXP FF /OE still controlled by MCU PD7
// -MCU PC7 controls both CLK on both FF's.
// -EXP FF D inputs are PORTA
// all other versions are driven by PORTB
// This means you always have to clock both flipflops
// Place desired value on PORTA/B respectively and clock with PD7
// -PC3 is free for user use.
// -SNES /RESET pin not controlled by PD0 (EXP0)
// instead it's controlled by A20 (EXPFF Q4)
// prevents putting INL SNES boards in program mode unless A20 is also low
// pretty much makes flashing SNES boards a royal PITA/impossible
// Suggested fix is to have PD0 (EXP0) control SNES /RESET
// would have to free /RESET and wire to EXP0/PD0 to permit flashing/reading INL SNES board.
//
//
// Fourth printed circuit board version
// First volume PCB run ~300 copies
// Yellow solder mask
// Labeled "Retro programmer/dumper v1.2b" "Kazzo 1.x"
// Dated May 2013
// * Includes NES, Famicom, & SNES connector
// * SNES board must be removed from case and slid all the way to right
// * Pitch offset on SNES connector makes it difficult to connect with original SNES boards.
// -Connector designed to only provide support for INL SNES Hi/Lo-ROM boards.
// * Care must be excersized not to insert SNES board backwards applying reverse power.
// * Effectively Final circuit design after lessons learned on small batches that preceeded.
// * INPUT/OUTPUT differences:
// -EXP FF /OE & CLK controlled by MCU PD7
// -MCU PC7 only controls CLK on ADDR HIGH FF.
// -EXP & ADDRHI FF D inputs both on Data bus PORTB
// -PC3 is free for user use.
// -SNES /RESET pin controlled by PD0 (EXP0)
// -Retains prev ver fixes, nothing funny going on with jumpers FC GND pin #16
//
//
// Fifth printed circuit board version
// Second volume PCB run ~500 copies
// Yellow solder mask
// Labeled "Retro programmer/dumper v1.2b" "Kazzo 1.x"
// Dated OCT 2014
// * Includes NES, Famicom, & SNES connector
// * SNES connector setup/cautions just like the prev version.
// * No significant changes from previous version.
// -Changed MCU clock to Crystal instead of resonator in prev ver.
// -Added screw mount holes, although not very well placed.
// * INPUT/OUTPUT differences:
// -None from previous version
//
//
// Sixth printed circuit board version
// Third volume PCB run in production as of 1NOV2016
// Orange solder mask
// Labeled "Retro programmer/dumper v1.4" "Kazzo 1.x"
// Dated OCT 2016
// Addition of fancy INL logo for first time
// * Includes NES, Famicom, & SNES connector
// * SNES connector improvement to correct pitch issue with prev ver.
// * Addition of PCT resettable fuse on incoming power.
// -Provides protection to SNES boards inserted backwards.
// * Rearrangement of BL/RUN switch and screw holes for better case design.
// * Cut out buzzer pads (PD6) from under MCU which was never developed.
// * INPUT/OUTPUT differences:
// -None from previous version
//
//
// STM32F070C6T6 KAZZO USB 2.0 ADAPTER board
// designed to retrofit all previous kazzo versions
// updates to arm cortex M0 core and hardware USB 2.0
// Green solder mask
// Labeled "KAZZO USB 2.0 ADAPTER" "V1.P"
// Dated JAN 2017
// Pins out to all DIP-40 pins:
// AVR reset -> STM reset
// AVR BOOTLOADn -> STM BOOT0 (not sure if this actually works...)
// AVR XTAL1/2 -> STM oscOUT/IN (PF1/0)
//
// ascii art board connections setup:
//AVR PIN #40<. .-> AVR PIN #20
// __|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|_
// | O O O O O O O O O O O O O O O O O O O O|
// | "KAZZO USB 2.0 ADAPTER" |
// kazzo | programming header /\ 6pin extra port | kazzo
// rst butn | O- /RESET / \ EMPTY -O O- PA6 | AVR PA6 "FREE"
// CIRAM_A10| O- SWD (PA13) CIRAM A10 /STM \ EMPTY -O O- PC15 | nc
// GND | O- GND \ 32 / 3v3 -O O- PC14 | nc
// nc | O- SWC (PA14) \ ./ GND -O O- PA1 | nc
// nc | O- 3v3 \/ 5v -O O- PA0 | EXP0
// | |
// | O O O O O O O O O O O O O O O O O O O O|
// -------------------------------------------------------------
// | | | | | | | | | | | | | | | | | | | |
//AVR PIN #1<-` `-> AVR PIN #19
// STM32 GPIO registers are quite different than AVR style
// they are more flexible/capable, but a little tricky to interface with
// some features present on STM32 pins, but not AVR
// - PULL-DOWN ability (and PULL-UP like AVR)
// - Speed/Slew rate selection
// - Open drain outputs (and push/pull like AVR)
// - Bit set/reset registers to remove necessity of RMW operations
// - Lockability to keep port config bits from changing until reset
// - GPIO blocks must be provided a clock and enabled to "turn on"
// failing to do so will cause hard faults when accessing registers!!
//
// All GPIO registers can be accessed in byte, halfword, or 32bit full words
// unless otherwise noted
//
// GPIOx->MODER[1:0] 32bit registers control direction/type of driver
// 00- Input (default reset state, except SWC-PA15 & SWD-PA13 default AF)
// 01- Gen Purp Output
// 10- Alternate func (SPI, I2C, etc)
// 11- reserved
// MODER[1] typically leave clear unless using AltFunc
// MODER[0] becomes equivalent of AVR DDR
//
// GPIOx->OTYPER 16bit registers control driver type
// 0- Push Pull (default reset state)
// 1- Open Drain
// N/A when MODER is set to "00" INPUT
// we can generally just ignore this register and use pushpull as AVR does
//
// GPIOx->OSPEEDR[1:0] 32bit registers control pin driver speed/slew
// x0- Low speed (default reset state, except SWD-PA13 default High Spd)
// 01- Medium speed
// 11- High speed
// N/A when MODER is set to "00" INPUT
// we can generally just ignore this register and use slow speed
//
// GPIOx->PUPDR[1:0] 32bit registers control pull-up/down resistors
// this register is in effect even when alternate functions are enabled
// 00- floating/disabled, no pull-up/down (default for most pins except below)
// 01- Pull-up enabled (default SWD-PA13) also CIRAM A10
// 10- Pull-down enabled (default SWC-PA14)
// 11- Reserved, don't use (prob enables both which would be bad...)
// PUPDR[0] is kinda like AVR PORT when DDR is set to INPUT, and PUPDR[1]=0
// This ends up being a little cleaner than AVR i/o interfacing
// Can probably just enable pull-ups on everything and leave it like that
// -only exception being USB pins (PA11/12) better leave those floating
//
// GPIOx->IDR 16bit register used to read current input level on pin
// this register is read only
//
// GPIOx->ODR 16bit register used to set output of pin if enabled by MODER
// this register is read/writeable
//
// GPIOx->BSSR 32bit register to only set/clear pins
// BR[31:16] upper halfword is will reset/clear pin if written to '1' value
// BS[15:00] lower halfword is will set pin if written to '1' value
// writing 0 to any bit has no effect
// if setting both BS register has priority (bit will be set)
// this register is write only!
//
// GPIO->BRR 16bit register equivalent to upper word of BSSR register above
// provides convinent separate BR register that doesn't need shifted
//
// GPIOx->LCKR 17bit register MUST BE ACCESSED in 32bit full words!!!
// complex sequence needed to set, but once done lock config/altfunc
// bits for that GPIO. I interpret this to mean the registers above
// with exception of IDR, ODR, BSSR registers, plus AF registers
// Good to use this for things than we don't want to accidentally change:
// - USB & XTAL pins come to mind as good candidates
//
// GPIOx->AFRL/H 2 sets of 32bit registers to determine alternate function
// of GPIO if enabled with MODER registers. Default is AF0 at reset
//
// Following macros are written to be supported on all yellow/orange silk kazzos
// includes rev 1.2b & 1.4 Dated May 2013 and later
// 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
////============================
////PORT DEFN
//#define ADDR_OUT PORTA
//#define ADDR_IN PINA
//#define ADDR_DDR DDRA
////DDR-PORT MACROS
//#define _ADDR_IP() ADDR_DDR = IP
//#define _ADDR_OP() ADDR_DDR = OP
//#define _ADDR_LO() ADDR_OUT = LO
//#define _ADDR_HI() ADDR_OUT = HI
//
//Need to rethink these macros.. Curently AVR uses them as values
//But for the stm32 it makes more sense to create function macros
//function macros could be made compatible with AVR as well
//ADDR_OUT = addrL; data[i] = DATA_IN;
//would become:
//ADDR_OUT(addrL); DATA_IN(data[i]);
//
//The port wide HI/LO IP/OP macros don't work either as we can't define values
//
//Firmware macro "functions" have underscore prefix
//opcode macros have identical name but without the prefix
//Haven't decided if PIN/PORT macros should be given underscore as well.
// Good chance I will want them with _ when writing read functions
// Easier to add them than take them out maybe..?
//Current rule is _ goes with () type macro
//Thinking this may as well change too since doing away with value macros...
//Or perhaps leading underscore denotes macros w/o operands
//PORT wide set/clear
#define AVR_LO 0x00
#define AVR_HI 0xFF
//DDR values
#define AVR_IP 0x00
#define AVR_OP 0xFF
//============================
//ADDR[7:0] PORTA
//============================
//PORT DEFN
#define ADDR_OUT(op) (PORTA = op)
#define ADDR_IN(op) (op = PINA)
#define ADDR_DDR(op) (DDRA = op)
//AND/OR functions
#define ADDR_OUT_OR(op) (PORTA |= op)
#define ADDR_OUT_AND(op) (PORTA &= op)
//DDR-PORT MACROS
#define ADDR_IP() ADDR_DDR = AVR_IP
#define ADDR_OP() ADDR_DDR = AVR_OP
#define ADDR_LO() ADDR_OUT = AVR_LO
#define ADDR_HI() ADDR_OUT = AVR_HI
//============================
//DATA[7:0] PORTB
//============================
//PORT DEFN
#define DATA_OUT PORTB
#define DATA_IN PINB
#define DATA_DDR DDRB
//DDR-PORT MACROS
#define _DATA_IP() DATA_DDR = IP
#define _DATA_OP() DATA_DDR = OP
#define _DATA_LO() DATA_OUT = LO
#define _DATA_HI() DATA_OUT = HI
//============================
//CTL PORTC
//============================
//PORT DEFN
#define CTL_OUT PORTC
#define CTL_IN PINC
#define CTL_DDR DDRC
//DDR-PORT MACROS
#define _CTL_IP() CTL_DDR = IP
// No CTL_OP() macro as some of these are inputs or bidir, best to individually assert as output
#define _CTL_LO() CTL_OUT = LO
#define _CTL_HI() CTL_OUT = HI
//PIN DEFN
#define M2 PC0 //NES, FC, & SNES (SYSCLK)
#define ROMSEL PC1 //(aka PRG/CE) NES, FC, & SNES
#define PRGRW PC2 //PRG R/W on NES & FC
#ifdef PURPLE_KAZZO
#define p_AXL PC3 //EXP FF CLK on purple boards
#else
#define FREE PC3 //Free pin on all other boards
#endif
#define CSRD PC4 //NES & FC CHR /RD, SNES /RD
#define CSWR PC5 //NES & FC CHR /WR, SNES /WR
#define CICE 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 PC7 //Both ADDR_MID & EXP/ADDRHI FF CLK on green prototype
#else
#define AHL PC7 //ADDR MID FF CLK per orig kazzo design
#endif
//PIN MACROS
#define _M2_IP() CTL_DDR &= ~(1<<M2)
#define _M2_OP() CTL_DDR |= (1<<M2)
#define _M2_LO() CTL_OUT &= ~(1<<M2)
#define _M2_HI() CTL_OUT |= (1<<M2)
//TODO read M2 PIN as input
#define _ROMSEL_IP() CTL_DDR &= ~(1<<ROMSEL)
#define _ROMSEL_OP() CTL_DDR |= (1<<ROMSEL)
#define _ROMSEL_LO() CTL_OUT &= ~(1<<ROMSEL)
#define _ROMSEL_HI() CTL_OUT |= (1<<ROMSEL)
#define _PRGRW_IP() CTL_DDR &= ~(1<<PRGRW)
#define _PRGRW_OP() CTL_DDR |= (1<<PRGRW)
#define _PRGRW_WR() CTL_OUT &= ~(1<<PRGRW) //LO for writes
#define _PRGRW_RD() CTL_OUT |= (1<<PRGRW) //HI for reads
#ifdef PURPLE_KAZZO
#define _p_AXL_ip() CTL_DDR &= ~(1<<p_AXL) //Don't use these, use software tied together versions instead.
#define _p_AXL_op() CTL_DDR |= (1<<p_AXL) //Increases compatibility between versions
#define _p_AXL_lo() CTL_OUT &= ~(1<<p_AXL) //Don't recommend calling lo/hi, use CLK instead
#define _p_AXL_hi() CTL_OUT |= (1<<p_AXL)
//_AXL_CLK assumes AXL was previously left in default low state
#define _AXL_CLK() _p_AXL_hi(); _p_AXL_lo(); //same name and convention on final design
#else //Green and final design
#define _FREE_IP() CTL_DDR &= ~(1<<FREE)
#define _FREE_OP() CTL_DDR |= (1<<FREE)
#define _FREE_LO() CTL_OUT &= ~(1<<FREE)
#define _FREE_HI() CTL_OUT |= (1<<FREE)
#endif
#define _CSRD_IP() CTL_DDR &= ~(1<<CSRD)
#define _CSRD_OP() CTL_DDR |= (1<<CSRD)
#define _CSRD_LO() CTL_OUT &= ~(1<<CSRD)
#define _CSRD_HI() CTL_OUT |= (1<<CSRD)
#define _CSWR_IP() CTL_DDR &= ~(1<<CSWR)
#define _CSWR_OP() CTL_DDR |= (1<<CSWR)
#define _CSWR_LO() CTL_OUT &= ~(1<<CSWR)
#define _CSWR_HI() CTL_OUT |= (1<<CSWR)
#define _CICE_IP() CTL_DDR &= ~(1<<CICE)
#define _CICE_OP() CTL_DDR |= (1<<CICE)
#define _CICE_LO() CTL_OUT &= ~(1<<CICE)
#define _CICE_HI() CTL_OUT |= (1<<CICE)
#ifdef GREEN_KAZZO
#define _g_AXHL_IP() CTL_DDR &= ~(1<<g_AXHL)
#define _g_AXHL_OP() CTL_DDR |= (1<<g_AXHL)
#define _g_AXHL_lo() CTL_OUT &= ~(1<<g_AXHL) //Don't recommend calling these as AXHL should be left low
#define _g_AXHL_hi() CTL_OUT |= (1<<g_AXHL) //That way _AXHL_CLK(); is always effective
#define _AXHL_CLK() _g_AXHL_hi(); _g_AXHL_lo();
#define _AHL_CLK() software_AHL_CLK();
#define _AXL_CLK() software_AXL_CLK();
//can ~safely consider this pin as if it were only AHL due to software AHL/AXL CLK
#define _AHL_IP() _g_AXHL_IP();
#define _AHL_OP() _g_AXHL_OP();
#define _AHL_lo() _g_AXHL_lo();
#define _AHL_hi() _g_AXHL_hi();
#else //purple and final design
#define _AHL_IP() CTL_DDR &= ~(1<<AHL)
#define _AHL_OP() CTL_DDR |= (1<<AHL)
#define _AHL_lo() CTL_OUT &= ~(1<<AHL) //Don't recommend calling these as AHL should be left low
#define _AHL_hi() CTL_OUT |= (1<<AHL) //That way _AHL_CLK(); is always effective
#define _AHL_CLK() _AHL_hi(); _AHL_lo();
#endif
//green board software AXL & AHL are separated in software in pinport.c
//============================
//AUX PORTD
//============================
//PORT DEFN
#define AUX_OUT PORTD
#define AUX_IN PIND
#define AUX_DDR DDRD
//DDR-PORT MACROS
#define _AUX_IP() AUX_DDR &= ((1<<USBP) | (1<<USBM)) //Don't touch USB pins!!!
// No AUX_OP() macro as many of these are inputs or bidir, best to individually assert as output
#define _AUX_LO() AUX_OUT &= ((1<<USBP) | (1<<USBM))
#define _AUX_HI() AUX_OUT |= ~((1<<USBP) | (1<<USBM))
//PIN DEFN
#define EXP0 PD0 //NES EXP0 controls a number of varying flash cart features...
#define FC_APU PD0 //FC Audio in cart from 2A03 APU
#define TDO PD0 //CPLD JTAG on INL-ROM NES/FC boards released after ~Oct2016
#define SRST PD0 //SNES /RESET pin used for CPLD prgm/play mode and SRAM CE
#define LED PD1 //LED on INL retro prog-dumper
#define EXP9 PD1 //NES dual purposed pin
#define USBP PD2 //USB D+ don't touch this pin!
#define IRQ PD3 //Connected to NES, FC, & SNES
#define USBM PD4 //USB D- don't touch this pin!
#define CIA10 PD5 //NES & FC CIRAM A10 (aka VRAM A10)
#define BL PD6 //Bootloader switch BL->GND, RUN->float
#ifdef PURPLE_KAZZO
#define pg_XOE PD7 //EXP/ADDRHI FF /OE pin on purple and green boards
#endif
#ifdef GREEN_KAZZO
#define pg_XOE PD7 //EXP/ADDRHI FF /OE pin on purple and green boards
#endif
#ifndef pg_XOE //FINAL_DESIGN
#define AXLOE PD7 //EXP/ADDRHI FF CLK & /OE pin on final board versions
#endif
//PIN MACROS
//lower case aren't meant to be called unless certain pin is 5v tolerant
#define _EXP0_ip() AUX_DDR &= ~(1<<EXP0)
#define _EXP0_op() AUX_DDR |= (1<<EXP0)
#define _EXP0_lo() AUX_OUT &= ~(1<<EXP0) //Don't call this assuming EXP0 DDR is set to o/p
#define _EXP0_hi() AUX_OUT |= (1<<EXP0) //Don't call this unless you're certain pin is 5v tolerant
//User options pull up, force low, and float
#define _EXP0_LO() _EXP0_lo(); _EXP0_op(); //Sets low then DDR to o/p
#define _EXP0_PU() _EXP0_ip(); _EXP0_hi(); //maybe add some NOP() to allow time for pull up
#define _EXP0_FLT() _EXP0_ip(); _EXP0_lo(); //Set to i/p w/o pullup
//SNES /RESET versions, more permissible for driving EXP0 to 5v as NES cart shouldn't be inserted
#define _SRST_IP() _EXP0_ip()
#define _SRST_OP() _EXP0_op()
#define _SRST_LO() _EXP0_lo()
#define _SRST_HI() _EXP0_hi()
#define _LED_IP() AUX_DDR &= ~(1<<LED)
#define _LED_OP() AUX_DDR |= (1<<LED)
#define _LED_OFF() AUX_OUT &= ~(1<<LED)
#define _LED_ON() AUX_OUT |= (1<<LED)
#define _IRQ_IP() AUX_DDR &= ~(1<<IRQ)
#define _IRQ_OP() AUX_DDR |= (1<<IRQ)
#define _IRQ_LO() AUX_OUT &= ~(1<<IRQ)
#define _IRQ_HI() AUX_OUT |= (1<<IRQ)
#define _CIA10_IP() AUX_DDR &= ~(1<<CIA10)
#define _CIA10_OP() AUX_DDR |= (1<<CIA10)
#define _CIA10_LO() AUX_OUT &= ~(1<<CIA10)
#define _CIA10_HI() AUX_OUT |= (1<<CIA10)
#define _BL_IP() AUX_DDR &= ~(1<<BL)
#define _BL_OP() AUX_DDR |= (1<<BL)
#define _BL_LO() AUX_OUT &= ~(1<<BL)
#define _BL_HI() AUX_OUT |= (1<<BL)
//purple and green versions
#if ( (defined(PURPLE_KAZZO)) || (defined(GREEN_KAZZO)) )
#define _XOE_ip() AUX_DDR &= ~(1<<pg_XOE) //don't use these, use software tied together AXLOE instead
#define _XOE_op() AUX_DDR |= (1<<pg_XOE)
#define _XOE_lo() AUX_OUT &= ~(1<<pg_XOE) //FF /OE pin low->enable o/p
#define _XOE_hi() AUX_OUT |= (1<<pg_XOE) //FF /OE pin high->disable o/p
#else //FINAL_DESIGN
#define _AXLOE_IP() AUX_DDR &= ~(1<<AXLOE)
#define _AXLOE_OP() AUX_DDR |= (1<<AXLOE)
#define _EXPFF_OP() AUX_OUT &= ~(1<<AXLOE) //FF /OE pin low->enable o/p
#define _EXPFF_FLT() AUX_OUT |= (1<<AXLOE) //FF /OE pin high->disable o/p
//Caution _AXL_CLK() relies on _EXPFF_OP() to be called beforehand
// Think of it like you must enable the output before you can clock it.
// Floating EXPFF also happens to clock it. Think of it like it looses it's value if disabled.
#define _AXL_CLK() _EXPFF_FLT(); _EXPFF_OP(); //same name and convention as purple
#endif
//Final version ties XOEn and AXL to same pin, we can do this in software to make other ver behave similarly
#ifdef PURPLE_KAZZO
#define _AXLOE_IP() _XOE_ip(); _p_AXL_ip();
#define _AXLOE_OP() _XOE_op(); _p_AXL_op();
#define _EXPFF_OP() _XOE_lo(); _p_AXL_lo();
#define _EXPFF_FLT() _XOE_hi(); _p_AXL_hi();
#endif
#ifdef GREEN_KAZZO //green can't tie AXL, just don't worry about clocking effect while enabling/disabling
#define _AXLOE_IP() _XOE_ip(); //run risk that AHL isn't O/P because AXL was made O/P instead
#define _AXLOE_OP() _XOE_op(); //sofware AXL/AHL clock covers this case though.
#define _EXPFF_OP() _XOE_lo();
#define _EXPFF_FLT() _XOE_hi();
#endif
//clocks must be initialized, Data bus clear
#define _ADDRH_SET(oper) _DATA_OP(); DATA_OUT = oper; _AHL_CLK(); _DATA_IP();
#define _ADDRX_SET(oper) _DATA_OP(); DATA_OUT = oper; _AXL_CLK(); _DATA_IP();
//PPU A13 is ADDRH bit 5
#define PPU_A13 0x20
//PPU /A13 is ADDRH bit 7
#define PPU_A13N 0x80
//PPU and CPU
#define A10 0x04
#define A11 0x08
#endif

View File

@ -6,8 +6,7 @@ typedef struct setup_packet{
uint8_t bRequest; //designates dictionary of opcode
uint8_t opcode; //wValueLSB (little endian)
uint8_t miscdata; //wValueMSB
uint8_t operandLSB; //wIndexLSB
uint8_t operandMSB; //wIndexMSB
uint16_t operand; //16bit operand "wIndex"
uint16_t wLength;
}setup_packet;

View File

@ -77,16 +77,6 @@ uint16_t usbFunctionSetup(uint8_t data[8]) {
//now it's the opcode's responsiblity to update these values
//rv[RETURN_DATA] start of return data
//fake some return data
rv[RETURN_ERR_IDX] = SUCCESS;
rv[RETURN_LEN_IDX] = 3;
rv[RETURN_DATA] = 0xAA;
rv[RETURN_DATA+1] = 0xDE;
rv[RETURN_DATA+2] = 0xAD;
rv[RETURN_DATA+3] = 0xBE;
rv[RETURN_DATA+4] = 0xEF;
rv[RETURN_DATA+5] = 0xCC;
/* (1) Set the global pointer 'usbMsgPtr' to the base of the static RAM data
* block and return the length of the data in 'usbFunctionSetup()'. The driver
* will handle the rest. Or (2) return USB_NO_MSG in 'usbFunctionSetup()'. The
@ -96,10 +86,7 @@ uint16_t usbFunctionSetup(uint8_t data[8]) {
//buffer. If no return data requested from host rlen = 0, so this wouldn't matter
//Some dictionaries/opcodes that want to return larger buffers though
//this function will set usbMsgPtr to point to that larger buffer when supported
//works on avr, broke on stm:
usbMsgPtr = (usbMsgPtr_t)rv;
//usbMsgPtr = rv;
#if USB_CFG_LONG_TRANSFERS
@ -115,48 +102,14 @@ uint16_t usbFunctionSetup(uint8_t data[8]) {
switch(spacket->bRequest) {
case DICT_PINPORT:
//Turn on LED
#ifdef STM_CORE
RCC->AHBENR |= (IOP_LED_EN);
#endif
// PCb_OP_EN(LEDbank, LED);
// PCb_SET_HI(LEDbank, LED);
CTL_IP_PU(LEDbank, LED);
switch (spacket->opcode) {
/*
case PP_OPCODE_ONLY_MIN ... PP_OPCODE_ONLY_MAX:
rv[RV_ERR_IDX] = pinport_opcode_only( spacket->opcode );
break;
case PP_OPCODE_8BOP_MIN ... PP_OPCODE_8BOP_MAX:
rv[RV_ERR_IDX] = pinport_opcode_8b_operand(
spacket->opcode, spacket->operandLSB );
break;
case PP_OPCODE_16BOP_MIN ... PP_OPCODE_16BOP_MAX:
rv[RV_ERR_IDX] = pinport_opcode_16b_operand(
spacket->opcode, spacket->operandMSB, spacket->operandLSB );
break;
case PP_OPCODE_24BOP_MIN ... PP_OPCODE_24BOP_MAX:
rv[RV_ERR_IDX] = pinport_opcode_24b_operand( spacket->opcode,
spacket->miscdata, spacket->operandMSB, spacket->operandLSB );
break;
case PP_OPCODE_8BRV_MIN ... PP_OPCODE_8BRV_MAX:
rv[RV_ERR_IDX] = pinport_opcode_8b_return( spacket->opcode, &rv[RV_DATA0_IDX]);
rlen ++;
break;
default: //pinport opcode min/max definition error
rv[RETURN_ERR_IDX] = ERR_BAD_PP_OP_MINMAX;
*/
}
rv[RETURN_ERR_IDX] = pinport_call( spacket->opcode, spacket->miscdata, spacket->operand, &rv[RETURN_LEN_IDX] );
break; //end of PINPORT
/*
case DICT_IO:
//break; //end of IO
rv[RETURN_ERR_IDX] = io_call( spacket->opcode, spacket->miscdata, spacket->operand, &rv[RETURN_LEN_IDX] );
break; //end of IO
/*
case DICT_NES:
//break; //end of NES

View File

@ -4,24 +4,16 @@
//Define the target core, only define one of these
//these defines are made in Makefile
//#define AVR_CORE
//#define STM_CORE
//== AVR CORE == AVR CORE == AVR CORE == AVR CORE == AVR CORE
#ifdef AVR_CORE
// #include <avr/io.h>
#include "usbdrv.h"
#endif
//end AVR CORE
//== STM CORE == STM CORE == STM CORE == STM CORE == STM CORE
#ifdef STM_CORE
#include "..\source_stm_only\usbstm.h"
#endif
//end STM CORE
#include "pinport_al.h"
#include "pinport.h"
#include "io.h"
#include "types.h"
#include "shared_usb.h"
#include "shared_errors.h"
@ -29,8 +21,6 @@
/*
#include "logic.h"
#include "pinport.h"
#include "io.h"
#include "nes.h"
#include "snes.h"
#include "buffer.h"

View File

@ -0,0 +1,26 @@
-- create the module's table
local blank = {}
-- import required modules
local dict = require "scripts.app.dict"
-- file constants
-- local functions
local function func()
end
-- global variables so other modules can use them
-- call functions desired to run when script is called/imported
-- functions other modules are able to call
blank.func = func
-- return the module's table
return blank

109
host/scripts/app/cart.lua Normal file
View File

@ -0,0 +1,109 @@
-- create the module's table
local cart = {}
-- import required modules
local dict = require "scripts.app.dict"
local nes = require "scripts.app.nes"
-- file constants
-- local functions
local function detect( debug )
print("attempting to detect cartridge...");
-- //always start with resetting i/o
dict.io("IO_RESET")
-- //TODO check if can detect a cart inserted backwards before continuing
-- //check if NES/Famicom cart
dict.io("NES_INIT")
-- //if PPU /A13 is tied to CIRAM /CE we know it's NES/Famicom
if nes.jumper_ciramce_ppuA13n(debug) then
-- //NES with 2 screen mirroring
if debug then print("CIRAM /CE is jumpered to PPU /A13") end
-- cart->console = NES_CART;
elseif nes.ciramce_inv_ppuA13(debug) then
-- //some boards including INLXO-ROM boards drive CIRAM /CE with inverse of PPU A13
if debug then print("CIRAM /CE is inverse of PPU A13") end
-- cart->console = NES_CART;
end
-- 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 nes.jumper_famicom_sound(debug) then
if debug then print("Famicom audio jumper found") end
-- cart->console = FC_CART;
end
-- //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 );
--
-- 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");
-- //TODO detection not yet implemented need to look over connector pinouts
-- break;
-- case UNKNOWN: printf("Unable to detect cartridge...\n");
-- //TODO error out properly
-- break;
-- default:
-- sentinel("cartridge console element got set to something unsupported.");
-- }
--
-- return SUCCESS;
--
--error:
-- //always end with resetting i/o
-- io_reset( transfer );
-- return -1;
--
--}
end
-- global variables so other modules can use them
-- call functions desired to run when script is called/imported
-- functions other modules are able to call
cart.detect = detect
-- return the module's table
return cart

297
host/scripts/app/dict.lua Normal file
View File

@ -0,0 +1,297 @@
-- dictionary module
-- creates tables with dictionary entries from shared\shared_dict*.h files
-- performs usb transfer when making dictionary call and returns device data
-- create the module's table
local dict = {}
-- file constants
local USB_IN = 0x80 --device to host
local USB_OUT = 0x00 --host to device
-- read all the C shared_dict*.h files and create tables with all values
-- This isn't 'Nam there are rules!
-- dictionary #define that start with underscore are skipped this skips over header and special cases
-- currently only finds lowercase #define statements (seems C does too!)
-- multiline comments /* comment */ are not permitted, will throw error!
-- #define statements must have a numeric value such as: #define FOO 4
-- #define without number will error like this: "#define FOO BAR" or "#define FOO BAR - 100" is bad too!
-- fills passed in table with keys and values to be used for making usb dictionary calls
-- accepts decimal or hex when 0x00 format
-- trailing underscores are trimmed, this allows firmware macro defines to match dictionary defines
-- sets "opcode_rlen" when RL=<number> (ie RL = 5) in the comments following the opcode
local function create_dict_tables( table, file )
assert(io.input(file, "r"))
local count = 0
local define = 0
local define_end = 0
local slash = 0
local line
local comment
for line in io.lines() do
count = count + 1
comment = nil --needs cleared for each pass
--search for multiline comment opening, starting at index 1, plain search = true
if string.find( line, "/*", 1, true) then
print("\n\n!!!ERROR!!!\nmultiline comment found line number", count)
print("while parsing file:", file, "\nonly inline comments are permitted!!!\n")
error("multiline comments not allowed in dictionary files!")
end
define, define_end = string.find( line, "#define")
if define then
slash = string.find(line, "//")
--check for comment following define, if present cut out comment
if slash and (slash>define) then
--store comment contents for later parsing
comment = string.sub(line, slash, -1)
line = string.sub(line, 1, slash-1 )
end
--check for comment prior to define, skip if present
if not (slash and (slash<define)) then
--print( count, define, line)
line = string.sub(line, define_end+1, -1)
--match alpha and any trailing printable chars besides white space
--this doesn't match guarded header/footer that starts with underscore
local key = string.match( line, "%s%a%g+" )
if key then
-- print ("\n\n",line)
--key found, trim key from line
local key_start, key_end
key_start, key_end = string.find( line, key )
line = string.sub( line, key_end+1, -1)
--trim preceeding space needed to filter out underscore
key = string.match( key, "%a%g+" )
--trim any trailing underscore, trick that allows firmware to call macro with "same" macro
if( (key:sub(-1,-1)) == '_' ) then
key = key:sub(1,-2)
end
--match the number
if string.match( line, "[^%s0-9a-fxA-F]+") then
print("\n\n!!!ERROR!!!\ndictionary file #define parsing problem line:", count)
print("while parsing file:", file, "\n", line, "is not a number!!!\n")
error("dictionary #define statements must end with a number")
end
local number = string.match( line, "%s+[0-9a-fxA-F]+")
if number then
number = string.match( number, "%s+[0-9a-fxA-F]+")
end
-- print (number)
--at this point we have the key and value, just convert from string
number = tonumber( number )
-- print("key/val:", key, number)
-- print("key type:", type(key), "value type:", type(number))
--add the key and value pair to the table
table[key] = number
--now process comment to find extra dictionary values stored in comments
-- print(comment)
if comment then
--return length "rlen" is set by RL=number (ie RL=10, RL=-0x100, etc)
--positive RL denotes endpoint IN, negative denotes endpoint OUT
--first match positive values
local rlen = string.match( comment, "%s*RL%s*=%s*[0-9a-fA-Fx]+")
if (rlen) then
--trim RL= portion
rlen = string.match( rlen, "[0-9a-fA-Fx]+")
rlen = tonumber( rlen )
--add return length to table
table[key.."rlen"] = rlen;
end
--next check for negative values
rlen = string.match( comment, "%s*RL%s*=%s*-%s*[0-9a-fA-Fx]+")
if (rlen) then
--trim RL=- portion
rlen = string.match( rlen, "[0-9a-fA-Fx]+")
rlen = - tonumber( rlen )
--add return length to table
table[key.."rlen"] = rlen;
end
end
-- print(key, ": val/rlen:", table[key], table[key.."rlen"], "\n\n")
end
end
end
end
end
--determine endpoint & wLength for usb transfer
--default is ep=IN, rlen=1 if different than those values it must be defined in dictionary
--positive values are associated with ep IN, negative ep OUT
local function default_rlen_1_in( rlen )
local ep
if rlen then
--RL defined in dictionary
if rlen < 1 then
ep = USB_OUT
rlen = -rlen
else
ep = USB_IN
end
else --RL not defined, assume default
ep = USB_IN
rlen = 1
end
return rlen, ep
end
-- TODO look closer at binary data packing/unpacking functions
local function string_to_int( string, numbytes)
local i = 0
local rv = 0
while i < numbytes do
rv = rv | (string:byte(i+1) << 8*i)
i = i+1
end
return rv
end
RETURN_ERR_IDX = 1
RETURN_LEN_IDX = 2
RETURN_DATA = 3
-- external call for pinport dictionary
local function pinport( opcode, operand, misc, data )
if not op_pinport[opcode] then
print("ERROR undefined opcode:", opcode, "must be defined in shared_dict_pinport.h")
return nil
end
if not operand then
operand = 0
elseif type(operand) == "string" then
if not op_pinport[operand] then
print("ERROR undefined operand:", operand, "must be defined in shared_dict_pinport.h")
return nil
end
--decode string operands into
operand = op_pinport[operand]
end
if not misc then misc = 0 end
local wLength, ep = default_rlen_1_in(op_pinport[opcode.."rlen"])
local count
count, data = usb_vend_xfr(
-- ep, dictionary wValue[misc:opcode] wIndex wLength data
ep, dict["DICT_PINPORT"], ( misc<<8 | op_pinport[opcode]), operand, wLength, data)
--print(count)
local error_code, data_len
if ep == USB_IN then
error_code = data:byte(RETURN_ERR_IDX)
data_len = data:byte(RETURN_LEN_IDX)
end
--print("error:", error_code, "data_len:", data_len)
if error_code ~= err_codes["SUCCESS"] then
print("ERROR!!! device error code:", error_code)
end
if data_len and data_len ~= (wLength - RETURN_LEN_IDX) then
print("WARNING!! Device's return data length:", data_len, "did not match expected:", wLength-RETURN_LEN_IDX)
end
--process the return data string and return it to calling function
if data_len then
return string_to_int( data:sub(RETURN_DATA, data_len+RETURN_DATA), data_len)
else
return nil
end
end
-- external call for io dictionary
local function io( opcode, operand, misc, data )
if not op_io[opcode] then
print("ERROR undefined opcode:", opcode, "must be defined in shared_dict_io.h")
return nil
end
if not operand then
operand = 0
elseif type(operand) == "string" then
if not op_io[operand] then
print("ERROR undefined operand:", operand, "must be defined in shared_dict_io.h")
return nil
end
--decode string operands into
operand = op_io[operand]
end
if not misc then misc = 0 end
local wLength, ep = default_rlen_1_in(op_io[opcode.."rlen"])
local count
count, data = usb_vend_xfr(
-- ep, dictionary wValue[misc:opcode] wIndex wLength data
ep, dict["DICT_IO"], ( misc<<8 | op_io[opcode]), operand, wLength, data)
--print(count)
local error_code, data_len
if ep == USB_IN then
error_code = data:byte(RETURN_ERR_IDX)
data_len = data:byte(RETURN_LEN_IDX)
end
--print("error:", error_code, "data_len:", data_len)
if error_code ~= err_codes["SUCCESS"] then
print("ERROR!!! device error code:", error_code)
end
if data_len and data_len ~= (wLength - RETURN_LEN_IDX) then
print("WARNING!! Device's return data length:", data_len, "did not match expected:", wLength-RETURN_LEN_IDX)
end
--process the return data string and return it to calling function
if data_len then
return string_to_int( data:sub(RETURN_DATA, data_len+RETURN_DATA), data_len)
else
return nil
end
end
-- Dictionary table definitions
-- global so other modules can use them
dict = {}
op_pinport = {}
op_buffer = {}
op_io = {}
op_operation = {}
op_nes = {}
op_snes = {}
err_codes = {}
-- Dictionary table definitions initialized by calling parser
-- call functions desired to run when script is called
create_dict_tables( dict, "../shared/shared_dictionaries.h")
create_dict_tables( op_pinport, "../shared/shared_dict_pinport.h")
--create_dict_tables( op_buffer, "../shared/shared_dict_buffer.h")
create_dict_tables( op_io, "../shared/shared_dict_io.h")
--create_dict_tables( op_operation, "../shared/shared_dict_operation.h")
create_dict_tables( op_nes, "../shared/shared_dict_nes.h")
--create_dict_tables( op_snes, "../shared/shared_dict_snes.h")
create_dict_tables( err_codes, "../shared/shared_errors.h")
-- functions other modules are able to call
dict.pinport = pinport
dict.io = io
-- return the module's table
return dict

402
host/scripts/app/nes.lua Normal file
View File

@ -0,0 +1,402 @@
-- create the module's table
local nes = {}
-- import required modules
local dict = require "scripts.app.dict"
-- file constants
local PPU_A13N_HI = 0x8000 --PPU /A13 is connected to mcu A15
local PPU_A13_HI = 0x2000 --PPU /A13 is connected to mcu A15
local FC_RF_HI = 0x20 --FC RF audio pin is EXP6 (bit5)
-- local functions
-- 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: true if jumper is set
local function jumper_ciramce_ppuA13n( debug )
--check that we can clear CIRAM /CE with PPU /A13
dict.pinport( "ADDR_SET", 0x0000 )
--read CIRAM /CE pin
if dict.pinport( "CTL_RD", "CICE" ) ~= 0 then
if debug then print("CIRAM /CE high when /A13 low ") end
return false
end
--set PPU /A13 high
dict.pinport( "ADDR_SET", PPU_A13N_HI )
--read CIRAM /CE pin
if dict.pinport( "CTL_RD", "CICE" ) == 0 then
if debug then print("CIRAM /CE low when /A13 high") end
return false
end
--CICE low jumper appears to be present
if debug then print("CIRAM /CE <- PPU /A13 jumper present") end
return true
end
-- 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: true if inverted PPU A13 drives CIRAM /CE
local function ciramce_inv_ppuA13 (debug)
--set PPU A13 low
dict.pinport( "ADDR_SET", 0x0000 )
-- CIRAM /CE should be high if inverted A13 is what drives it
if dict.pinport( "CTL_RD", "CICE" ) == 0 then
if debug then print("CIRAM /CE low when A13 low") end
return false
end
--check that we can clear CIRAM /CE with PPU A13 high
dict.pinport( "ADDR_SET", PPU_A13_HI )
-- CIRAM /CE should be low if inverted A13 is what drives it
if dict.pinport( "CTL_RD", "CICE" ) ~= 0 then
if debug then print("CIRAM /CE high when A13 high") end
return false
end
--CICE low jumper appears to be present
if debug then print("CIRAM /CE <- inverse PPU A13") end
return true
end
-- 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 old avr 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: true if jumper/connection is present
-- Test:Works on non-expansion sound carts obviously
-- Works on VRC6 and VRC7
-- Others untested
local function jumper_famicom_sound (debug)
--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
dict.pinport("EXP_ENABLE")
--Latch low first
dict.pinport("EXP_SET", 0x00)
-- pull up FCAPU
dict.pinport("CTL_IP_PU", "FCAPU")
--read EXP0 Famicom APU audio pin
if dict.pinport( "CTL_RD", "FCAPU" ) ~= 0 then
if debug then print("RF audio out (EXP6) didn't drive APU audio in (EXP0) low") end
dict.pinport("EXP_DISABLE")
dict.pinport("CTL_IP_FL", "EXP0")
return false
end
--Latch RF audio sound pin high
dict.pinport("EXP_SET", FC_RF_HI)
--read Famicom APU audio pin
if dict.pinport( "CTL_RD", "FCAPU" ) == 0 then
if debug then print("RF audio out (EXP6) didn't drive APU audio in (EXP0) high") end
dict.pinport("EXP_DISABLE")
dict.pinport("CTL_IP_FL", "EXP0")
return false
end
--Famicom audio jumper appears to be present
if debug then print("RF audio out (EXP6) is connected to APU audio in") end
--disable EXP PORT and return EXP0 to floating if it was used
dict.pinport("EXP_DISABLE")
dict.pinport("CTL_IP_FL", "EXP0")
return true
end
-- global variables so other modules can use them
-- call functions desired to run when script is called/imported
-- functions other modules are able to call
nes.jumper_ciramce_ppuA13n = jumper_ciramce_ppuA13n
nes.ciramce_inv_ppuA13 = ciramce_inv_ppuA13
nes.jumper_famicom_sound = jumper_famicom_sound
-- return the module's table
return nes
-- old C file:
--
--/* Desc:PRG-ROM flash manf/prod ID sense test
-- * Using EXP0 /WE writes
-- * Only senses SST flash ID's
-- * Assumes that isn't getting tricked by having manf/prodID at $8000/8001
-- * could add check and increment read address to ensure doesn't get tricked..
-- * Pre: nes_init() been called to setup i/o
-- * exp0 pullup test must pass
-- * if ROM A14 is mapper controlled it must be low when CPU A14 is low
-- * controlling A14 outside of this function acts as a means of bank size detection
-- * Post:memory manf/prod ID set to read values if passed
-- * memory wr_dict and wr_opcode set if successful
-- * Software mode exited if entered successfully
-- * Rtn: SUCCESS if flash sensed, GEN_FAIL if not, neg if error
-- */
--int read_flashID_prgrom_exp0( USBtransfer *transfer, memory *flash ) {
--
-- uint8_t rv[RV_DATA0_IDX];
--
--enter software mode
--ROMSEL controls PRG-ROM /OE which needs to be low for flash writes
--So unlock commands need to be addressed below $8000
--DISCRETE_EXP0_PRGROM_WR doesn't toggle /ROMSEL by definition though, so A15 is unused
-- 15 14 13 12
-- 0x5 = 0b 0 1 0 1 -> $5555
-- 0x2 = 0b 0 0 1 0 -> $2AAA
-- dictionary_call( transfer, DICT_NES, DISCRETE_EXP0_PRGROM_WR, 0x5555, 0xAA,
-- USB_IN, NULL, 1);
-- dictionary_call( transfer, DICT_NES, DISCRETE_EXP0_PRGROM_WR, 0x2AAA, 0x55,
-- USB_IN, NULL, 1);
-- dictionary_call( transfer, DICT_NES, DISCRETE_EXP0_PRGROM_WR, 0x5555, 0x90,
-- USB_IN, NULL, 1);
--read manf ID
-- dictionary_call( transfer, DICT_NES, NES_CPU_RD, 0x8000, NILL,
-- USB_IN, rv, RV_DATA0_IDX+1);
-- debug("manf id: %x", rv[RV_DATA0_IDX]);
-- if ( rv[RV_DATA0_IDX] != SST_MANF_ID ) {
-- return GEN_FAIL;
-- //no need for software exit since failed to enter
-- }
--
--read prod ID
-- dictionary_call( transfer, DICT_NES, NES_CPU_RD, 0x8001, NILL,
-- USB_IN, rv, RV_DATA0_IDX+1);
-- debug("prod id: %x", rv[RV_DATA0_IDX]);
-- if ( (rv[RV_DATA0_IDX] == SST_PROD_128)
-- || (rv[RV_DATA0_IDX] == SST_PROD_256)
-- || (rv[RV_DATA0_IDX] == SST_PROD_512) ) {
-- //found expected manf and prod ID
-- flash->manf = SST_MANF_ID;
-- flash->part = rv[RV_DATA0_IDX];
-- flash->wr_dict = DICT_NES;
-- flash->wr_opcode = DISCRETE_EXP0_PRGROM_WR;
-- }
--
--exit software
-- dictionary_call( transfer, DICT_NES, DISCRETE_EXP0_PRGROM_WR, 0x8000, 0xF0,
-- USB_IN, NULL, 1);
--
--verify exited
--dictionary_call( transfer, DICT_NES, NES_CPU_RD, 0x8000, NILL,
-- USB_IN, rv, RV_DATA0_IDX+1);
--debug("prod id: %x", rv[RV_DATA0_IDX]);
--
-- return SUCCESS;
--}
--
--
--/* Desc:PRG-ROM flash manf/prod ID sense test
-- * Using mapper 30 defined PRG-ROM flash writes
-- * Only senses SST flash ID's
-- * Assumes that isn't getting tricked by having manf/prodID at $8000/8001
-- * could add check and increment read address to ensure doesn't get tricked..
-- * Pre: nes_init() been called to setup i/o
-- * Post:memory manf/prod ID set to read values if passed
-- * memory wr_dict and wr_opcode set if successful
-- * Software mode exited if entered successfully
-- * Rtn: SUCCESS if flash sensed, GEN_FAIL if not, neg if error
-- */
--int read_flashID_prgrom_map30( USBtransfer *transfer, memory *flash ) {
--
-- uint8_t rv[RV_DATA0_IDX];
--
--enter software mode
--$8000-BFFF writes to flash
--$C000-FFFF writes to mapper
-- 15 14 13 12
-- 0x5 = 0b 0 1 0 1 -> $9555
-- 0x2 = 0b 0 0 1 0 -> $2AAA
--set A14 in mapper reg for $5555 command
-- dictionary_call( transfer, DICT_NES, NES_CPU_WR, 0xC000, 0x01,
-- USB_IN, NULL, 1);
--write $5555 0xAA
-- dictionary_call( transfer, DICT_NES, NES_CPU_WR, 0x9555, 0xAA,
-- USB_IN, NULL, 1);
--clear A14 in mapper reg for $2AAA command
-- dictionary_call( transfer, DICT_NES, NES_CPU_WR, 0xC000, 0x00,
-- USB_IN, NULL, 1);
--write $2AAA 0x55
-- dictionary_call( transfer, DICT_NES, NES_CPU_WR, 0xAAAA, 0x55,
-- USB_IN, NULL, 1);
--set A14 in mapper reg for $5555 command
-- dictionary_call( transfer, DICT_NES, NES_CPU_WR, 0xC000, 0x01,
-- USB_IN, NULL, 1);
--write $5555 0x90 for software mode
-- dictionary_call( transfer, DICT_NES, NES_CPU_WR, 0x9555, 0x90,
-- USB_IN, NULL, 1);
--
--read manf ID
-- dictionary_call( transfer, DICT_NES, NES_CPU_RD, 0x8000, NILL,
-- USB_IN, rv, RV_DATA0_IDX+1);
-- debug("manf id: %x", rv[RV_DATA0_IDX]);
-- if ( rv[RV_DATA0_IDX] != SST_MANF_ID ) {
-- return GEN_FAIL;
-- //no need for software exit since failed to enter
-- }
--
--read prod ID
-- dictionary_call( transfer, DICT_NES, NES_CPU_RD, 0x8001, NILL,
-- USB_IN, rv, RV_DATA0_IDX+1);
-- debug("prod id: %x", rv[RV_DATA0_IDX]);
-- if ( (rv[RV_DATA0_IDX] == SST_PROD_128)
-- || (rv[RV_DATA0_IDX] == SST_PROD_256)
-- || (rv[RV_DATA0_IDX] == SST_PROD_512) ) {
-- //found expected manf and prod ID
-- flash->manf = SST_MANF_ID;
-- flash->part = rv[RV_DATA0_IDX];
-- flash->wr_dict = DICT_NES;
-- flash->wr_opcode = NES_CPU_WR;
-- }
--
--exit software
-- dictionary_call( transfer, DICT_NES, NES_CPU_WR, 0x8000, 0xF0,
-- USB_IN, NULL, 1);
--
--verify exited
-- dictionary_call( transfer, DICT_NES, NES_CPU_RD, 0x8000, NILL,
-- USB_IN, rv, RV_DATA0_IDX+1);
-- debug("prod id: %x", rv[RV_DATA0_IDX]);
--
-- return SUCCESS;
--}
--
--
--/* Desc:CHR-ROM flash manf/prod ID sense test
-- * Only senses SST flash ID's
-- * Does not make CHR bank writes so A14-A13 must be made valid outside of this funciton
-- * An NROM board does this by tieing A14:13 to A12:11
-- * Other mappers will pass this function if PT0 has A14:13=01, PT1 has A14:13=10
-- * Assumes that isn't getting tricked by having manf/prodID at $0000/0001
-- * could add check and increment read address to ensure doesn't get tricked..
-- * Pre: nes_init() been called to setup i/o
-- * Post:memory manf/prod ID set to read values if passed
-- * memory wr_dict and wr_opcode set if successful
-- * Software mode exited if entered successfully
-- * Rtn: SUCCESS if flash sensed, GEN_FAIL if not, neg if error
-- */
--int read_flashID_chrrom_8K( USBtransfer *transfer, memory *flash ) {
--
-- uint8_t rv[RV_DATA0_IDX];
--
--enter software mode
--NROM has A13 tied to A11, and A14 tied to A12.
--So only A0-12 needs to be valid
--A13 needs to be low to address CHR-ROM
-- 15 14 13 12
-- 0x5 = 0b 0 1 0 1 -> $1555
-- 0x2 = 0b 0 0 1 0 -> $0AAA
-- dictionary_call( transfer, DICT_NES, NES_PPU_WR, 0x1555, 0xAA,
-- USB_IN, NULL, 1);
-- dictionary_call( transfer, DICT_NES, NES_PPU_WR, 0x0AAA, 0x55,
-- USB_IN, NULL, 1);
-- dictionary_call( transfer, DICT_NES, NES_PPU_WR, 0x1555, 0x90,
-- USB_IN, NULL, 1);
--read manf ID
-- dictionary_call( transfer, DICT_NES, NES_PPU_RD, 0x0000, NILL,
-- USB_IN, rv, RV_DATA0_IDX+1);
-- debug("manf id: %x", rv[RV_DATA0_IDX]);
-- if ( rv[RV_DATA0_IDX] != SST_MANF_ID ) {
-- return GEN_FAIL;
-- //no need for software exit since failed to enter
-- }
--
--read prod ID
-- dictionary_call( transfer, DICT_NES, NES_PPU_RD, 0x0001, NILL,
-- USB_IN, rv, RV_DATA0_IDX+1);
-- debug("prod id: %x", rv[RV_DATA0_IDX]);
-- if ( (rv[RV_DATA0_IDX] == SST_PROD_128)
-- || (rv[RV_DATA0_IDX] == SST_PROD_256)
-- || (rv[RV_DATA0_IDX] == SST_PROD_512) ) {
-- //found expected manf and prod ID
-- flash->manf = SST_MANF_ID;
-- flash->part = rv[RV_DATA0_IDX];
-- flash->wr_dict = DICT_NES;
-- flash->wr_opcode = NES_PPU_WR;
-- }
--
--exit software
-- dictionary_call( transfer, DICT_NES, NES_PPU_WR, 0x0000, 0xF0,
-- USB_IN, NULL, 1);
--
--verify exited
--dictionary_call( transfer, DICT_NES, NES_PPU_RD, 0x0000, NILL,
-- USB_IN, rv, RV_DATA0_IDX+1);
--debug("prod id: %x", rv[RV_DATA0_IDX]);
--
-- return SUCCESS;
--}
--
--/* Desc:Simple CHR-RAM sense test
-- * A more thourough test should be implemented in firmware
-- * This one simply tests one address in PPU address space
-- * Pre: nes_init() been called to setup i/o
-- * Post:
-- * Rtn: SUCCESS if ram sensed, GEN_FAIL if not, neg if error
-- */
--int ppu_ram_sense( USBtransfer *transfer, uint16_t addr ) {
--
-- uint8_t rv[RV_DATA0_IDX];
--
--write 0xAA to addr
-- dictionary_call( transfer, DICT_NES, NES_PPU_WR, addr, 0xAA,
-- USB_IN, NULL, 1);
--try to read it back
-- dictionary_call( transfer, DICT_NES, NES_PPU_RD, addr, NILL,
-- USB_IN, rv, RV_DATA0_IDX+1);
-- debug("reading back 0xAA: %x", rv[RV_DATA0_IDX]);
-- if ( rv[RV_DATA0_IDX] != 0xAA ) {
-- return GEN_FAIL;
-- }
--
--write 0x55 to addr
-- dictionary_call( transfer, DICT_NES, NES_PPU_WR, addr, 0x55,
-- USB_IN, NULL, 1);
--try to read it back
-- dictionary_call( transfer, DICT_NES, NES_PPU_RD, addr, NILL,
-- USB_IN, rv, RV_DATA0_IDX+1);
-- debug("reading back 0x55: %x", rv[RV_DATA0_IDX]);
-- if ( rv[RV_DATA0_IDX] != 0x55 ) {
-- return GEN_FAIL;
-- }
--
-- return SUCCESS;
--}
--
--
--/* Desc:Just calls CIRAM_A10_MIRROR opcode and returns result.
-- * result will be return value of opcode
-- * Pre: nes_init() been called to setup i/o
-- * Post:address bus left assigned
-- * Rtn: VERT/HORIZ/1SCNA/1SCNB
-- */
--int ciram_A10_mirroring( USBtransfer *transfer )
--{
-- uint8_t rv[RV_DATA0_IDX];
--
-- dictionary_call( transfer, DICT_NES, CIRAM_A10_MIRROR, NILL, NILL,
-- USB_IN, rv, RV_DATA0_IDX+1);
-- debug("mirroring detected: %x", rv[RV_DATA0_IDX]);
-- return rv[RV_DATA0_IDX];
--}

View File

@ -1,235 +1,35 @@
-- main script that runs application logic and flow
USB_IN = 0x80 --device to host
USB_OUT = 0x00 --host to device
-- read all the C shared_dict*.h files and create tables with all values
-- This isn't 'Nam there are rules!
-- dictionary #define that start with underscore are skipped this skips over header and special cases
-- currently only finds lowercase #define statements (seems C does too!)
-- multiline comments /* comment */ are not permitted, will throw error!
-- #define statements must have a numeric value such as: #define FOO 4
-- #define without number will error like this: "#define FOO BAR" or "#define FOO BAR - 100" is bad too!
-- fills passed in table with keys and values to be used for making usb dictionary calls
-- accepts decimal or hex when 0x00 format
function create_dict_tables( table, file )
assert(io.input(file, "r"))
local count = 0
local define = 0
local define_end = 0
local slash = 0
local line
local comment
for line in io.lines() do
count = count + 1
--search for multiline comment opening, starting at index 1, plain search = true
if string.find( line, "/*", 1, true) then
print("\n\n!!!ERROR!!!\nmultiline comment found line number", count)
print("while parsing file:", file, "\nonly inline comments are permitted!!!\n")
error("multiline comments not allowed in dictionary files!")
end
define, define_end = string.find( line, "#define")
if define then
slash = string.find(line, "//")
--check for comment following define, if present cut out comment
if slash and (slash>define) then
--store comment contents for later parsing
comment = string.sub(line, slash, -1)
line = string.sub(line, 1, slash-1 )
end
--check for comment prior to define, skip if present
if not (slash and (slash<define)) then
--print( count, define, line)
line = string.sub(line, define_end+1, -1)
--match alpha and any trailing printable chars besides white space
--this doesn't match guarded header/footer that starts with underscore
local key = string.match( line, "%s%a%g+" )
if key then
-- print ("\n\n",line)
--key found, trim key from line
local key_start, key_end
key_start, key_end = string.find( line, key )
line = string.sub( line, key_end+1, -1)
--trim preceeding space needed to filter out underscore
key = string.match( key, "%a%g+" )
--trim any trailing underscore, trick that allows firmware to call macro with "same" macro
if( (key:sub(-1,-1)) == '_' ) then
key = key:sub(1,-2)
end
--match the number
if string.match( line, "[^%s0-9a-fxA-F]+") then
print("\n\n!!!ERROR!!!\ndictionary file #define parsing problem line:", count)
print("while parsing file:", file, "\n", line, "is not a number!!!\n")
error("dictionary #define statements must end with a number")
end
local number = string.match( line, "%s+[0-9a-fxA-F]+")
if number then
number = string.match( number, "%s+[0-9a-fxA-F]+")
end
-- print (number)
--at this point we have the key and value, just convert from string
number = tonumber( number )
-- print("key/val:", key, number)
-- print("key type:", type(key), "value type:", type(number))
--add the key and value pair to the table
table[key] = number
--now process comment to find extra dictionary values stored in comments
-- print(comment)
if comment then
--return length "rlen" is set by RL=number (ie RL=10, RL=-0x100, etc)
--positive RL denotes endpoint IN, negative denotes endpoint OUT
--first match positive values
local rlen = string.match( comment, "%s*RL%s*=%s*[0-9a-fA-Fx]+")
if (rlen) then
--trim RL= portion
rlen = string.match( rlen, "[0-9a-fA-Fx]+")
rlen = tonumber( rlen )
--add return length to table
table[key.."rlen"] = rlen;
end
--next check for negative values
rlen = string.match( comment, "%s*RL%s*=%s*-%s*[0-9a-fA-Fx]+")
if (rlen) then
--trim RL=- portion
rlen = string.match( rlen, "[0-9a-fA-Fx]+")
rlen = - tonumber( rlen )
--add return length to table
table[key.."rlen"] = rlen;
end
end
-- print(key, ": val/rlen:", table[key], table[key.."rlen"], "\n\n")
end
end
end
end
end
--determine endpoint & wLength for usb transfer
--default is ep=IN, rlen=1 if different than those values it must be defined in dictionary
--positive values are associated with ep IN, negative ep OUT
function default_rlen_1_in( rlen )
local ep
if rlen then
--RL defined in dictionary
if rlen < 1 then
ep = USB_OUT
rlen = -rlen
else
ep = USB_IN
end
else --RL not defined, assume default
ep = USB_IN
rlen = 1
end
return rlen, ep
end
function string_to_int( string, numbytes)
local i = 0
local rv = 0
while i < numbytes do
rv = rv | (string:byte(i+1) << 8*i)
i = i+1
end
return rv
end
RETURN_ERR_IDX = 1
RETURN_LEN_IDX = 2
RETURN_DATA = 3
function dict_pinport( opcode, operand, misc, data )
if not operand then operand = 0 end
if not misc then misc = 0 end
local wLength, ep = default_rlen_1_in(op_pinport[opcode.."rlen"])
local count
count, data = usb_vend_xfr(
-- ep, dictionary wValue[misc:opcode] wIndex wLength data
ep, dict["DICT_PINPORT"], ( misc<<8 | op_pinport[opcode]), operand, wLength, data)
--print(count)
local error_code = data:byte(RETURN_ERR_IDX)
local data_len = data:byte(RETURN_LEN_IDX)
--print("error:", error_code, "data_len:", data_len)
if error_code ~= err_codes["SUCCESS"] then
print("ERROR!!! device error code:", error_code)
end
if data_len and data_len ~= (wLength - RETURN_LEN_IDX) then
print("WARNING!! Device's return data length:", data_len, "did not match expected:", wLength-RETURN_LEN_IDX)
end
--process the return data string and return it to calling function
if data_len then
return string_to_int( data:sub(RETURN_DATA, data_len+RETURN_DATA), data_len)
else
return nil
end
end
-- initial function called from C main
function main ()
--check that dictionary files were found and parsed
--print(op_buffer)
--if not ( dict and op_pinport and op_buffer and op_io and op_operation and op_nes and op_snes ) then
-- print("ERROR: couldn't find/parse dictionary files in shared folder!")
--end
-- print dictionary opcode addr miscdata endpt buffer length
--print("dict_call ", dict_call( 1, dict["DICT_PINPORT"], op_pinport["LED_OFF"], 0, 0, USB_IN, nil, 8), "\n")
--
print("return len", op_pinport["LED_ONrlen"])
local rv = dict_pinport( "LED_ON" )
local dict = require "scripts.app.dict"
local cart = require "scripts.app.cart"
local rv
-- rv = dict.pinport( "CTL_ENABLE" )
-- rv = dict.pinport( "CTL_IP_PU", "LED" )
-- rv = dict.pinport( "CTL_RD", "LED" )
-- rv = dict.pinport( "CTL_OP", "LED" )
-- rv = dict.pinport( "CTL_SET_HI", "LED" )
-- rv = dict.pinport( "CTL_RD", "LED" )
-- rv = dict.pinport( "DATA_ENABLE" )
-- rv = dict.pinport( "DATA_RD" )
-- rv = dict.pinport( "DATA_OP" )
-- rv = dict.pinport( "DATA_SET", 0xAA )
-- rv = dict.pinport( "DATA_RD" )
-- rv = dict.io("IO_RESET")
if rv then
print(string.format("%X", rv))
end
--[[{i=0
while ( i < 8192 ) do
usb_vend_xfr( USB_IN, dict["DICT_PINPORT"], op_pinport["LED_ON"], 0, 128, "wowdata!!!!")
i = i+1
end
--]]
debug = true
rv = cart.detect(debug)
end
-- Dictionary table definitions
dict = {}
op_pinport = {}
op_buffer = {}
op_io = {}
op_operation = {}
op_nes = {}
op_snes = {}
err_codes = {}
-- Dictionary table definitions created by calling parser
-- call functions desired to run when script is called
create_dict_tables( dict, "../shared/shared_dictionaries.h")
create_dict_tables( op_pinport, "../shared/shared_dict_pinport.h")
create_dict_tables( op_buffer, "../shared/shared_dict_buffer.h")
create_dict_tables( op_io, "../shared/shared_dict_io.h")
create_dict_tables( op_operation, "../shared/shared_dict_operation.h")
create_dict_tables( op_nes, "../shared/shared_dict_nes.h")
create_dict_tables( op_snes, "../shared/shared_dict_snes.h")
create_dict_tables( err_codes, "../shared/shared_errors.h")
main ()

View File

@ -1,3 +0,0 @@
-- define window size
width = 2333300
height = 30089898

View File

@ -233,7 +233,7 @@ int main(int argc, char *argv[])
//lua script arg to set different LIBUSB debugging options
check( !(luaL_loadfile(L, "scripts/usb_device.lua") || lua_pcall(L, 0, 0, 0)),
check( !(luaL_loadfile(L, "scripts/app/usb_device.lua") || lua_pcall(L, 0, 0, 0)),
"cannot run config. file: %s", lua_tostring(L, -1));
int libusb_log = LIBUSB_LOG_LEVEL_NONE; // 0: default no msgs ever printed

View File

@ -360,14 +360,14 @@ typedef struct USBtransfer {
printf("ep %d, req %d\n", usb_xfr.endpoint, usb_xfr.request);
printf("wValue %d, wIndex %d\n", usb_xfr.wValue, usb_xfr.wIndex);
printf("wLength %d, \n", usb_xfr.wLength);
printf("predata: %d, %d, %d, %d, %d, %d \n", usb_xfr.data[0], usb_xfr.data[1],usb_xfr.data[2],usb_xfr.data[3],usb_xfr.data[4],usb_xfr.data[5]);
printf("wLength %d \n", usb_xfr.wLength);
printf("predata: %d, %d, %d, %d, %d, %d, %d, %d \n", usb_xfr.data[0], usb_xfr.data[1],usb_xfr.data[2],usb_xfr.data[3],usb_xfr.data[4],usb_xfr.data[5], usb_xfr.data[6], usb_xfr.data[7]);
check( lua_usb_handle != NULL, "usb device handle pointer not initialized.\n")
xfr_count = usb_vendor_transfer( &usb_xfr);
printf("postdata: %d, %d, %d, %d, %d, %d \n", usb_xfr.data[0], usb_xfr.data[1],usb_xfr.data[2],usb_xfr.data[3],usb_xfr.data[4],usb_xfr.data[5]);
printf("postdata: %d, %d, %d, %d, %d, %d, %d, %d \n", usb_xfr.data[0], usb_xfr.data[1],usb_xfr.data[2],usb_xfr.data[3],usb_xfr.data[4],usb_xfr.data[5], usb_xfr.data[6], usb_xfr.data[7]);
printf("bytes xfrd: %d\n", xfr_count);
lua_pushnumber(L, xfr_count); /* push first result */

View File

@ -17,82 +17,24 @@
//=============================================================================================
//=============================================================================================
// OPCODES with no operand and no return value besides SUCCESS/ERROR_CODE
//=============================================================================================
// 0x00-0xFF
// Detect this opcode/operand setup with opcode between the following defines:
#define IO_OPCODE_ONLY_MIN 0x00
#define IO_OPCODE_ONLY_MAX 0x7F
//
//=============================================================================================
//=============================================================================================
//pullup as many cart pins as possible
//goal to be safe state for all hardware
//doesn't currently contain any checks to report error/success from
//this is intended to be the "reset" safest condition for the kazzo
//LED is pulled up (DIM) to help indicate this io state
//EXP FF is disabled due to pull up on /OE
#define IO_RESET 0x00
//FFs are disabled due to pull up on /OE
#define IO_RESET 0
//NES cartridge interfacing setup
//set outputs as required
//latch address of $0000
//disable NES cart memories
#define NES_INIT 0x01
#define NES_INIT 1
//SNES cartridge interfacing setup
//set outputs as required
//latch address of $000000
//disable cart memories
//reset high disables SRAM and puts INL carts in PRGM mode
#define SNES_INIT 0x02
#define SNES_INIT 2
//=============================================================================================
// OPCODES with no operand but have RETRUN VALUE plus SUCCESS/ERROR_CODE
//=============================================================================================
// 0x00-0xFF
// Detect this opcode/operand setup with opcode between the following defines:
#define IO_OPCODE_RTN_MIN 0x80
#define IO_OPCODE_RTN_MAX 0xFF
//
//=============================================================================================
//=============================================================================================
//Test EXP0 drive with pull up
//This is an important test if reling on pulling up EXP0 pin to drive the cart's pin.
//EXP0 is used for various things and may have pull up/down of it's own or significant load
//Test that programmer can drive EXP0 with a pull up before reling on commands that only pullup
//If this fails, can resort to driving EXP0 with SNES /RESET commands but excersize caution
//as some NES cart's have CPLD JTAG TDO pin placed on EXP0 that may not be 5v tolerant.
//FC also has APU audio placed on EXP0, carts without exp sound short RF sound (EXP6) to EXP0
//So if EXP FF's output is enabled, driving the mcu EXP0 pin could cause damage to the pin.
//that's why it's best in general to only pull up EXP0 instead of driving it high.
//Have to drive it low however to get logic 0 most times. If famicom cart is inserted,
//it's probably safer to drive EXP0 through EXP6 sound jumper and leave EXP0 floating/pulledup.
//
//Test starts by verifying EXP0 can be driven low, if not, will return one byte of AUX_PIN
//followed by alternating 0xAA, 0x55, 0xAA...
//This test pulls up EXP0 and then reads AUX_PIN 6 times in rapid succession returning error code
//plus 6 bytes of read data. If pull up works but is just slow, should see that in return data.
//data[0] marks bit where EXP0 resisdes to provide host with bitmask for EXP0
#define EXP0_PULLUP_TEST 0x80
//testing results:
//without any cart inserted takes 5 cycles for EXP0 to settle high
//er: 0 rv: 1, b8, b8, b8, b8, b9, b9
//with discrete NROM board inserted (has pullup on EXP0) settled immediately
//er: 0 rv: 1, 99, 99, 99, 99, 99, 99
//SNES board inserted never settled
//er: 0 rv: 1, b8, b8, b8, b8, b8, b8
//famicom NROM choplifter cart inserted never settled
//er: 0 rv: 1, 98, 98, 98, 98, 98, 98
//INLXO-ROM board JTAG TDO (non-5v tolerant) tied to EXP0 settled immediately
//er: 0 rv: 1, 99, 99, 99, 99, 99, 99
#endif

View File

@ -20,420 +20,154 @@
//Don't recommend changing opcodes or anything here, change them in fw first then apply here.
//making this a shared file helps cut room for error as changing opcode numbers here will
//inherently get forwarded to both firmware and app at same time.
//
//Trailing underscores are trimmed from this file for the host application to allow direct
//between firmware and host software. Firmware only uses defines with trailing underscores
//for opcode/operand decoding.
//
//=============================================================================================
// OPCODES with no operand and no return value besides SUCCESS/ERROR_CODE
// OPCODES with
//=============================================================================================
// 0x00-0x7F
// 0-90: currently defined
// 19-22: unused due to accidentaly double defining CICE opcodes
// 91-127: not yet in use
//
// Current limit for these types of opcodes is 0-127
// This allows for the MSB to be used for decoding pinport opcode to this type
//
// Detect this opcode/operand setup with opcode between the following defines:
#define PP_OPCODE_ONLY_MIN 0x00
#define PP_OPCODE_ONLY_MAX 0x7F
//
//=============================================================================================
//=============================================================================================
//============================
//ADDR[7:0] PORTA
//CONTROL PORT INDIVIDUAL PIN ACCESS
//opcode: type of pin operation
//operand: pin to act on
//============================
//DDR-PORT MACROS
#define ADDR_IP 0
#define ADDR_OP 1
#define ADDR_LO 2
#define ADDR_HI 3
//opcodes
#define CTL_ENABLE_ 0
#define CTL_IP_PU_ 1
#define CTL_IP_FL_ 2
#define CTL_OP_ 3
#define CTL_SET_LO_ 4
#define CTL_SET_HI_ 5
#define CTL_RD_ 6 //RL=4 (error code, data length, LSB, MSB)
//operands
// PC0 "MCO" mcu clock out M2/phi2, Sysclk, etc
#define C0_ 0
#define MCO_ 0
// PC1 "ROMSEL" Cartridge rom enable
#define C1_ 1
#define ROMSEL_ 1
// PC2 "PRGRW" NES CPU R/W signal
#define C2_ 2
#define PRGRW_ 2
// PC3 "FREE" purple kazzo EXP flipflop latch, FREE on most AVR/adapter kazzos
#define C3_ 3
#define FREE_ 3
// PC4 "CSRD" NES CHR/SNES /RD
#define C4_ 4
#define CSRD_ 4
// PC5 "CSWR" NES CHR/SNES /WR
#define C5_ 5
#define CSWR_ 5
// PC6 "CICE" NES CIRAM /CE
#define C6_ 6
#define CICE_ 6
// PC7 "AHL" ADDR HI Latch
#define C7_ 7
#define AHL_ 7
// PC8 "EXP0" NES EXP0, cart-console /RESET
#define C8_ 8
#define EXP0_ 8
// PC9 "LED" kazzos tied this to NES EXP9, INL6 connects to CIC CLK
#define C9_ 9
#define LED_ 9
// PC10 "IRQ" console CPU interrupt from cart
#define C10_ 10
#define IRQ_ 10
// PC11 "CIA10" NES CIRAM A10
#define C11_ 11
#define CIA10_ 11
// PC12 "BL" Bootloader pin
#define C12_ 12
#define BL_ 12
// PC13 "AXL" EXP FF latch and /OE, purple kazzos this was only /OE
#define C13_ 13
#define AXL_ 13
// INLretro6 adds following pins
// PC14 "AUDL" cart audio
#define C14_ 14
#define AUDL_ 14
// PC15 "AUDR" cart audio
#define C15_ 15
#define AUDR_ 15
// PC16 "CIN" CIC data in
#define C16_ 16
#define CIN_ 16
// PC17 "SWD" mcu debug
#define C17_ 17
#define SWD_ 17
// PC18 "SWC" mcu debug
#define C18_ 18
// PC19 "AFL" flipflop addr expansion for FF0-7
#define C19_ 19
#define AFL_ 19
// PC20 "COUT" CIC data out
#define C20_ 20
#define COUT_ 20
// PC21 "FCAPU" cart audio in
#define C21_ 21
#define FCAPU_ 21
// INLretro6 gains direct control over NES EXP port and is used for N64 control pins:
// PCxx "D8"
// #define Cxx_ xx
// PC22 "D9"
#define C22_ 22
// PC23 "D10"
#define C23_ 23
// PC24 "D11"
#define C24_ 24
// PC25 "D12"
#define C25_ 25
// PC26 "D13"
#define C26_ 26
// PC27 "D14"
#define C27_ 27
// D15 & D16 are defined as CICE/CIA10 above
#define C28_ 28
#define C29_ 29
//============================
//DATA[7:0] PORTB
//DATA PORT BYTE WIDE ACCESS
//opcode: type of pin operation
//operand: value to place on bus
//============================
//DDR-PORT MACROS
#define DATA_IP 4
#define DATA_OP 5
#define DATA_LO 6
#define DATA_HI 7
#define DATA_ENABLE_ 7
#define DATA_IP_PU_ 8
#define DATA_IP_ 9
#define DATA_OP_ 10
#define DATA_SET_ 11
#define DATA_RD_ 12 //RL=3 (error code, data length, databyte)
//============================
//CTL PORTC
//ADDR PORT 16bit WIDE ACCESS
//opcode: type of operation
//operand: value to place on bus
//============================
//DDR-PORT MACROS
#define CTL_IP 8
// No CTL_OP() macro as some of these are inputs or bidir, best to individually assert as output
#define CTL_LO 9
#define CTL_HI 10
//PIN MACROS
#define M2_IP 11
#define M2_OP 12
#define M2_LO 13
#define M2_HI 14
#define ROMSEL_IP 15
#define ROMSEL_OP 16
#define ROMSEL_LO 17
#define ROMSEL_HI 18
#define ADDR_ENABLE_ 13
#define ADDR_PU_ 14
#define ADDR_IP_ 15
#define ADDR_OP_ 16
#define ADDR_SET_ 17
#define PRGRW_IP 23
#define PRGRW_OP 24
#define PRGRW_WR 25 //LO for writes
#define PRGRW_RD 26 //HI for reads
//give each def different version numbers to detect errors
//where command given to board which doesn't have that function
//#ifdef PURPLE_KAZZO //purple boards only
#define p_AXL_ip 27 //Don't use these, use software tied together versions instead.
#define p_AXL_op 28 //Increases compatibility between versions
#define p_AXL_lo 29 //Don't recommend calling lo/hi, use CLK instead
#define p_AXL_hi 30
//#else //Green and final design
#define FREE_IP 31
#define FREE_OP 32
#define FREE_LO 33
#define FREE_HI 34
//#endif
#define CSRD_IP 35
#define CSRD_OP 36
#define CSRD_LO 37
#define CSRD_HI 38
#define CSWR_IP 39
#define CSWR_OP 40
#define CSWR_LO 41
#define CSWR_HI 42
#define CICE_IP 43
#define CICE_OP 44
#define CICE_LO 45
#define CICE_HI 46
//#ifdef GREEN_KAZZO
#define g_AXHL_IP 47
#define g_AXHL_OP 48
#define g_AXHL_lo 49 //Don't recommend calling these as AXHL should be left low
#define g_AXHL_hi 50 //That way AXHL_CLK(); is always effective
//#endif
//purple and final design, safe to pretend green is similar due to software AHL/AXL CLK
#define AHL_IP 51
#define AHL_OP 52
#define AHL_lo 53 //Don't recommend calling these as AHL should be left low
#define AHL_hi 54 //That way AHL_CLK(); is always effective.
//also helps maintain validity of software AHL/AXL CLK
//============================
//AUX PORTD
//EXP PORT 8bit ACCESS (bits1-8)
//opcode: type of operation
//operand: value to place on bus
//============================
//DDR-PORT MACROS
#define AUX_IP 55 //Don't touch USB pins!!!
// No AUX_OP(); macro as many of these are inputs or bidir, best to individually assert as output
#define AUX_LO 56
#define AUX_HI 57
//PIN MACROS
//lower case aren't meant to be called unless certain pin is 5v tolerant
#define EXP0_ip 58
#define EXP0_op 59
#define EXP0_lo 60 //Don't call this assuming EXP0 DDR is set to o/p
#define EXP0_hi 61 //Don't call this unless you're certain pin is 5v tolerant
//SNES versions uppercase as assuming 5v tolerance without NES cart
#define SRST_IP 58
#define SRST_OP 59
#define SRST_LO 60
#define SRST_HI 61
//User options pull up, force low, and float
#define EXP0_LO 62 //Sets low then DDR to o/p
#define EXP0_PU 63 //maybe add some NOP(); to allow time for pull up
#define EXP0_FLT 64 //Set to i/p w/o pullup
#define EXP_ENABLE_ 18
#define EXP_DISABLE_ 19
#define EXP_SET_ 20
#define LED_IP 65
#define LED_OP 66
#define LED_OFF 67 // test outRL = 6whee!
#define LED_ON 68 // test outRL = 5whee!
#define IRQ_IP 69
#define IRQ_OP 70
#define IRQ_LO 71
#define IRQ_HI 72
#define CIA10_IP 73
#define CIA10_OP 74
#define CIA10_LO 75
#define CIA10_HI 76
#define BL_IP 77
#define BL_OP 78
#define BL_LO 79
#define BL_HI 80
//#ifndef pg_XOE //FINAL_DESIGN
//purple and green have versions of these which tie two pins together in software
#define AXLOE_IP 81
#define AXLOE_OP 82
//Caution AXL_CLK() relies on EXPFF_OP() to be called beforehand
// Think of it like you must enable the output before you can clock it.
// Floating EXPFF also happens to clock it. Think of it like it looses it's value if disabled.
//#ifdef PURPLE_KAZZO or GREEN_KAZZO //purple and green versions
#define XOE_ip 83 //Don't call these, use AXLOE instead
#define XOE_op 84
#define XOE_lo 85
#define XOE_hi 86
//#endif
//Same definition on all board versions
//Only need to be cognizant that AXL_CLK won't work if EXPFF_FLT was called beforehand
//This is only an issue on final design, so an error here should only cause probs on final design
//Net effect is it it works on final design should be fine on other versions which is the goal
#define EXPFF_OP 87 //FF /OE pin low->enable o/p
#define EXPFF_FLT 88 //FF /OE pin high->disable o/p
//AXL_CLK this is similar between purple and green versions, just on a different pin.
//green boards don't have an AXL_CLK nor a AHL_CLK, as the two are combined.
//green boards must resolve this in software storing value of FF's so can have the effect
//of only clocking one of them.
//#ifdef GREEN_KAZZO
//case XX: AXHL_CLK(); break; //don't want to call this as software AXL/AHL don't track
//case 87: software_AXL_CLK(); break;
//case 88: software_AHL_CLK(); break;
//#else
//these two cases covers all designs with macro calling sofware versions for green board.
#define AXL_CLK 89
#define AHL_CLK 90
//#endif
//these work fine in hardware for purple and final.
//green had to separate these two with software.
//=============================================================================================
//=============================================================================================
// CAUTION!!! CAUTION!!! CAUTION!!! CAUTION!!! CAUTION!!!
//
// The opcodes that follow operate under some rules that you must adhere to if calling
// 1) Data bus should be free and clear when possible
// -DATA_IP() is default state
// -Be cognizant if you're driving the data bus
// many of these opcodes use the data bus to function.
// -Many of these opcodes will end up driving the data bus
// know when that'll happen and free bus when data retreived
//
// -Flipflops must be initialized
// this primarily means CLK pin must be OP and LO ready for CLK command
// -output of FF must be enabled to actually feed latched value on cart
// final pcb version will enable EXP FF after clocking.
// early pcb versions have FF /OE on separate pin not so automatic.
//
// -control pins must be initialized
// -enable OP on pins necessary to perform desire of command
// ie M2 and /ROMSEL must be OP if you're trying to change them with a command.
//
// -be cognizant of what pins are inputs and which are outputs
// ie driving PPU /A13 will be fed back to CIRAM /CE so it needs to be IP
// -if in doubt, leave it as input with pull up, atleast that shouldn't break anything
//
// -ADDR_OP is default state, these opcodes assume it to be set as it shouldn't conflict
// -/ROMSEL & M2 expected to be set as outputs
//
//
//=============================================================================================
//=============================================================================================
//=============================================================================================
// OPCODES WITH OPERAND and no return value besides SUCCESS/ERROR_CODE
//=============================================================================================
//
#define PP_OPCODE_8BOP_MIN 0x80
#define PP_OPCODE_8BOP_MAX 0x9F
// 0x80-0x9F: opcodes with 8bit operand
// 0x80-8A are only ones currently in use
//
#define PP_OPCODE_16BOP_MIN 0xA0
#define PP_OPCODE_16BOP_MAX 0xAF
// 0xA0-0xAF: opcodes with 16bit operand
// 0xA0-A2 are only ones currently in use
//
#define PP_OPCODE_24BOP_MIN 0xB0
#define PP_OPCODE_24BOP_MAX 0xBF
// 0xB0-0xBF: opcodes with 24bit operand
// 0xA0 is currently only one in use
//
// Current limit for these types of opcodes is 128-191 (0x80-0xBF)
// This allows for the MSBs' to be used for decoding pinport opcode to this type
//
//
//=============================================================================================
//=============================================================================================
//=================================
//8bit operand
//=================================
//ADDR[7:0] PORTA
#define ADDR_SET 0x80
//DATA[7:0] PORTB
#define DATA_SET 0x81
//conveinent/safe yet slower function that sets ADDR as OP then sets value
#define DATA_OPnSET 0x82
//ADDR[15:8] FLIPFLOP
//NES CPU: ADDRH[6:0] -> CPU A[14:8]
// ADDRH[7] -> NC on CPU side
//NES PPU: ADDRH[5:0] -> PPU A[13:8]
// ADDRH[6] -> NC on PPU side
// ADDRH[7] -> PPU /A13 (which drives CIRAM /CE on most carts "2-screen mirroring")
//SNES: ADDRH[7:0] -> CPU A[15:8]
#define ADDRH_SET 0x83
//EXPANSION FLIPFLOP
//NES: ADDRX[7:0] -> EXP PORT [8:1]
//SNES: ADDRX[7:0] -> CPU A[23:16]
#define ADDRX_SET 0x84
//Set ADDR/DATA bus DDR registers with bit granularity
// OP() IP() macros affect entire 8bit port's direction
// Each pin can be controlled individually though
// This could be useful for advanced feature that doesn't treat DATA/ADDR as byte wide port.
#define ADDR_DDR_SET 0x85
#define DATA_DDR_SET 0x86
//Perhaps it will be useful to have this function on other ports as well
//But probably wouldn't be very useful if standard carts are plugged in..
//AUX port operations will shield USB pins from being affected
//defined as lower case because you shouldn't call these unless you *Really* know what you're doing..
#define ctl_ddr_set 0x87
#define aux_ddr_set 0x88
#define ctl_port_set 0x89
#define aux_port_set 0x8A
//=================================
//16bit operand
//=================================
//ADDR[15:0] (ADDRH:ADDR)
//Doesn't affect control signals
//bits[13:0] are applied to NES CPU, NES PPU, and SNES address bus
//bit[14] is only applied to CPU A14 on NES
//bit[15] is only applied to PPU /A13 on NES
//bit[15:14] are applied to SNES A[15:14]
#define ADDR16_SET 0xA0
//Set NES CPU ADDRESS BUS SET with /ROMSEL
//bit 15 is decoded to enable /ROMSEL properly (aka PRG /CE)
//bit15 is actually inverted then applied to /ROMSEL since /ROMSEL is low when NES CPU A15 is high
//NOTE! This does NOT affect M2 (aka phi2), so carts using M2 to decode things like WRAM is dependent on last value of M2
//This will also stop current value of PPU /A13 with bit15
#define NCPU_ADDR_ROMSEL 0xA1
//TODO consider opcode that preserves PPU /A13 instead of stomping it like the opcodes above.
//Can't think of why this would be useful so ignoring for now
//One reason might be to keep VRAM silent on a NES board with 4screen mirroring..
// But should be able to do this with CHR /RD in same manner CHR-ROM is kept silent..
//Set NES PPU ADDRESS BUS with /A13
//PPU address bus is 14bits wide A[13:0] so operand bits [15:14] are ignored.
//bit 13 is inverted and applied to PPU /A13
//PPU control signals CHR /RD and CHR /WR are unaffected
//Note: since PPU /A13 is tied to ADDRH[7] could perform this faster by using ADDR16_SET
// but this opcode is convienent and ensures PPU /A13 is always inverse of PPU A13
// This is important for NES carts with on board CHR-ROM and VRAM for 4screen mirroring.
#define NPPU_ADDR_SET 0xA2
//=================================
//24bit operand
//=================================
//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
//=============================================================================================
// OPCODES with NO OPERAND but have RETURN VALUE plus SUCCESS/ERROR_CODE
//=============================================================================================
//
#define PP_OPCODE_8BRV_MIN 0xC0
#define PP_OPCODE_8BRV_MAX 0xFF
// 0xC0-0xFF: opcodes with 8bit return value (plus SuCCESS/ERROR)
// 0xC0-CB are only ones currently in use
//
// 0x??-0xFF: larger return values perhaps?
//
//
// Current limit for these types of opcodes is 192-255 (0xC0-0xFF)
// This allows for the MSBs' to be used for decoding pinport opcode to this type
// Detect this opcode/operand setup with opcode between the following defines:
//
// Detect this opcode/operand setup with opcode between the following defines:
//
//=============================================================================================
//=============================================================================================
//READ MCU I/O PORT INPUT 'PIN' REGISTERS
//This is what's used to read bus after setting DDR register to input with IP() command/macro
//Current value of PORT Determines if pullups are activated or not, pull up with HI() macro, and float with LO() macro
//ADDR[7:0] PINA
#define ADDR_RD 0xC0
//DATA[7:0] PINB
#define DATA_RD 0xC1
//CTL PINC
//Should set pin of interest to input with IP with macros prior to reading
//you're still allowed to read value even if some/all pins are output though
#define CTL_RD 0xC2
//AUX PIND
//Should set pin of interest to input with IP with macros prior to reading
//you're still allowed to read value even if some/all pins are output though
#define AUX_RD 0xC3
//READ MCU I/O PORT OUTPUT 'PORT' REGISTERS
//Gives means to see what pins are currently being driven (or pulled up) to.
//ADDR[7:0] PORTA
#define ADDR_PORT_RD 0xC4
//DATA[7:0] PORTB
#define DATA_PORT_RD 0xC5
//CTL PORTC
#define CTL_PORT_RD 0xC6
//AUX PORTD
#define AUX_PORT_RD 0xC7
//READ MCU I/O PORT DIRECTION 'DDR' REGISTERS
//Gives means to see what pins are currently set to I/P or O/P.
//ADDR[7:0] DDRA
#define ADDR_DDR_RD 0xC8
//DATA[7:0] DDRB
#define DATA_DDR_RD 0xC9
//CTL DDRC
#define CTL_DDR_RD 0xCA
//AUX DDRD
#define AUX_DDR_RD 0xCB
//=============================================================================================
// OPCODES with OPERAND and RETURN VALUE plus SUCCESS/ERROR_CODE
//=============================================================================================
//Not sure if want these or not...
#endif

View File

@ -30,50 +30,16 @@
#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.
//Access to other internal avr registers should be placed in other associated dictionaries.
//The opcodes in this dictionary should not have any cyclic effect such as pulsing /ROMSEL
//low to read data and then disabling taking /ROMSEL high again. These commands are intended
//to appear as a single change/edge to cartridge hardware. Only potential exception to this
//is AHL/AXL clocking which is used to latch values to FF's, that effectively is only one
//state change for the cartridge hardware.
//
// Many of the opcodes in the second half of this dictionary have the following rules:
//
// The opcodes that follow operate under some rules that you must adhere to if calling
// 1) Data bus should be free and clear when possible
// -DATA_IP() is default state
// -Be cognizant if you're driving the data bus
// many of these opcodes use the data bus to function.
// -Many of these opcodes will end up driving the data bus
// know when that'll happen and free bus when data retreived
//
// -Flipflops must be initialized
// this primarily means CLK pin must be OP and LO ready for CLK command
// -output of FF must be enabled to actually feed latched value on cart
// final pcb version will enable EXP FF after clocking.
// early pcb versions have FF /OE on separate pin not so automatic.
//
// -control pins must be initialized
// -enable OP on pins necessary to perform desire of command
// ie M2 and /ROMSEL must be OP if you're trying to change them with a command.
//
// -be cognizant of what pins are inputs and which are outputs
// ie driving PPU /A13 will be fed back to CIRAM /CE so it needs to be IP
// -if in doubt, leave it as input with pull up, atleast that shouldn't break anything
//
// -ADDR_OP is default state, these opcodes assume it to be set as it shouldn't conflict
// -/ROMSEL & M2 expected to be set as outputs
//
//
//See abstraction layer port definitions in firmware pinport_al.h file for more details.
//An effort has been made to make opcodes in this dictionary hardware independent.
//=============================================================================================
//=============================================================================================
//=============================================================================================
//=============================================================================================
//#define DICT_IO 2
//#include "shared_dict_io.h"
#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
//to the cartridge inserted. The closest these operations get to being cart/system
@ -88,8 +54,8 @@
//=============================================================================================
//=============================================================================================
//#define DICT_NES 3
//#include "shared_dict_nes.h"
#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
//This library is intended to contain all NES related opcodes/commands

View File

@ -4,29 +4,16 @@
#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
#define ERR_BAD_PP_OP_MINMAX 129
#define ERR_BAD_IO_OP_MINMAX 130
#define ERR_BAD_NES_OP_MINMAX 131
#define ERR_BAD_SNES_OP_MINMAX 132
#define ERR_BAD_BUFF_OP_MINMAX 133
#define ERR_BUFN_DOES_NOT_EXIST 134
#define ERR_BAD_OPER_OP_MINMAX 135
//#define ERR_UNKN_PP_OPCODE_ONLY 140
//#define ERR_UNKN_PP_OPCODE_8BOP 141
//#define ERR_UNKN_PP_OPCODE_16BOP 142
//#define ERR_UNKN_PP_OPCODE_24BOP 143
//#define ERR_UNKN_PP_OPCODE_8BRV 144
//
//#define ERR_UNKN_IO_OPCODE_ONLY 150
//#define ERR_UNKN_IO_OPCODE_RTN 151
//
#define ERR_UNKN_PP_OPCODE 140
#define ERR_CTL_PIN_NOT_PRESENT 141
#define ERR_UNKN_IO_OPCODE 150
//#define ERR_UNKN_NES_OPCODE_24BOP 160
//#define ERR_UNKN_NES_OPCODE_16BOP_8BRV 161
//