diff options
Diffstat (limited to '6502.h')
-rw-r--r-- | 6502.h | 229 |
1 files changed, 229 insertions, 0 deletions
@@ -0,0 +1,229 @@ +/* + + 6502 - 6502 emulation + + Copyright (C) 2025 Ian Cowburn <ianc@noddybox.co.uk> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see <http://www.gnu.org/licenses/> + + ------------------------------------------------------------------------- + +*/ + +#ifndef C6502_H +#define C6502_H + +#include <stdio.h> + +/* ---------------------------------------- TYPES +*/ + +/* Large unsigned type +*/ +typedef unsigned long C6502Val; + + +/* 8-bit type. The emulation will exit with code 2 if this isn't 8 bits. +*/ +typedef unsigned char C6502Byte; + + +/* 8-bit signed type. The emulation will exit with code 2 if this isn't 8 bits. + We assume this is 2's complemnt. +*/ +typedef signed char C6502Relative; + + +/* 16-bit type. The emulation will exit with code 2 if this isn't 16 bits. +*/ +typedef unsigned short C6502Word; + + +/* The processor +*/ +struct C6502Private; + +typedef struct +{ + C6502Word PC; + + C6502Byte A; + C6502Byte X; + C6502Byte Y; + C6502Byte SP; + C6502Byte SR; + + struct C6502Private *priv; +} C6502; + + +/* Interfaces used to handle memory +*/ +typedef C6502Byte (*C6502ReadMemory)(C6502 *cpu, C6502Word address); +typedef void (*C6502WriteMemory)(C6502 *cpu, + C6502Word address, + C6502Byte value); + + + +/* Callback. Callback should return TRUE for processing to continue. +*/ +typedef int (*C6502Callback)(C6502 *cpu, C6502Val current_cycles); + + +/* Callback reasons + + eC6502_Instruction Called before the initial fetch for an instruction + (called just to once no matter how many bytes the + instruction is made up of). + + eC6502_BRK Called when a BRK is executed. + + eC6502_JAM Called when the CPU hits an opcode that jams the CPU. + + eC6502_RTI Called when the RTI instruction is executed +*/ +typedef enum +{ + eC6502_Instruction, + eC6502_BRK, + eC6502_JAM, + eC6502_RTI, + eC6502_NO_CALLBACK +} C6502CallbackReason; + +/* Defines cycle timers +*/ +typedef enum +{ + C6502_TIMER_1, + C6502_TIMER_2, + C6502_TIMER_3, + C6502_NO_TIMERS +} C6502Timer; + + +/* Flags in the F register +*/ +typedef enum +{ + eC6502_Carry =0x01, + eC6502_Neg =0x02, + eC6502_PV =0x04, + eC6502_Hidden3 =0x08, + eC6502_HalfCarry =0x10, + eC6502_Hidden5 =0x20, + eC6502_Zero =0x40, + eC6502_Sign =0x80 +} C6502FlagRegister; + + +/* Disassembly label -- only useful if ENABLE_DISASSEMBLER is set. + Labels are stored as an array, where a NULL in the label field marks + the end of the list. +*/ +typedef struct +{ + C6502Word address; + const char *label; +} C6502Label; + + +/* ---------------------------------------- INTERFACES +*/ + + +/* Initialises the processor. +*/ +#ifdef ENABLE_ARRAY_MEMORY +C6502 *C6502Init(void); +#else +C6502 *C6502Init(C6502ReadMemory read_memory, + C6502WriteMemory write_memory, + C6502ReadMemory read_for_disassem); +#endif + + +/* Resets the processor. +*/ +void C6502Reset(C6502 *cpu); + + +/* Lodge a callback to be invoked after special events. Returns FALSE + if the callback couldn't be lodged (there is a max of 10 callbacks per + reason). +*/ +int C6502LodgeCallback(C6502 *cpu, + C6502CallbackReason reason, + C6502Callback callback); + + +/* Remove a callback. Does nothing if reason was not lodged with + C6502LodgeCallback() +*/ +void C6502RemoveCallback(C6502 *cpu, + C6502CallbackReason reason, + C6502Callback callback); + + +/* Cause an interrupt before the next opcode. +*/ +void C6502Interrupt(C6502 *cpu); + + +/* Cause an NMI +*/ +void C6502NMI(C6502 *cpu); + + +/* Execute a single instruction. Returns FALSE if any callback returned + FALSE. +*/ +int C6502SingleStep(C6502 *cpu); + + +/* Executes until a callback returns FALSE (never returns otherwise) +*/ +void C6502Exec(C6502 *cpu); + + +/* Manipulate the cylce count of the C6502 +*/ +C6502Val C6502Cycles(C6502 *cpu); +void C6502ResetCycles(C6502 *cpu, C6502Val cycles); + +/* Timers that count in cycle counts +*/ +C6502Val C6502GetTimer(C6502 *cpu, C6502Timer timer); +void C6502SetTimer(C6502 *cpu, C6502Timer timer, C6502Val cycles); + + +/* Set address to label mappings for the disassembler +*/ +void C6502SetLabels(C6502Label labels[]); + + +/* Simple disassembly of memory accessed through read_for_disassem, or + C6502_MEMORY as appropriate. addr is updated on exit. +*/ +const char *C6502Disassemble(C6502 *cpu, C6502Word *addr); + +/* Allows the CPU state to be saved/loaded from a stream +*/ +void C6502SaveSnapshot(C6502 *cpu, FILE *fp); +void C6502LoadSnapshot(C6502 *cpu, FILE *fp); + +#endif + +/* END OF FILE */ |