1 /** M6502: portable 6502 emulator ****************************/ 2 /** **/ 3 /** M6502.h **/ 4 /** **/ 5 /** This file contains declarations relevant to emulation **/ 6 /** of 6502 CPU. **/ 7 /** **/ 8 /** Copyright (C) Marat Fayzullin 1996 **/ 9 /** Alex Krasivsky 1996 **/ 10 /** You are not allowed to distribute this software **/ 11 /** commercially. Please, notify me, if you make any **/ 12 /** changes to this file. **/ 13 /*************************************************************/ 14 #ifndef M6502_H 15 #define M6502_H 16 17 /* 18 * this file has been modified for use with the cal. 19 */ 20 21 /* $Id: m6502.h,v 1.6 1999/11/21 04:39:22 nyef Exp $ */ 22 23 #include "cal.h" 24 #include "mtypes.h" 25 26 /* Compilation options: */ 27 /* #define FAST_RDOP */ /* Separate Op6502()/Rd6502() */ 28 /* #define DEBUG */ /* Compile debugging version */ 29 /* #define LSB_FIRST */ /* Compile for low-endian CPU */ 30 31 /* Loop6502() returns: */ 32 #define INT_NONE 0xFFFF /* No interrupt required */ 33 #define INT_IRQ 0x0038 /* Standard IRQ interrupt */ 34 #define INT_NMI 0x0066 /* Non-maskable interrupt */ 35 #define INT_QUIT 0xFFFE /* Exit the emulation */ 36 37 /* 6502 status flags: */ 38 #define M6502_C_FLAG 0x01 /* 1: Carry occured */ 39 #define M6502_Z_FLAG 0x02 /* 1: Result is zero */ 40 #define M6502_I_FLAG 0x04 /* 1: Interrupts disabled */ 41 #define M6502_D_FLAG 0x08 /* 1: Decimal mode */ 42 #define M6502_B_FLAG 0x10 /* Break [0 on stk after int] */ 43 #define M6502_R_FLAG 0x20 /* Always 1 */ 44 #define M6502_V_FLAG 0x40 /* 1: Overflow occured */ 45 #define M6502_N_FLAG 0x80 /* 1: Result is negative */ 46 47 /** Simple Datatypes *****************************************/ 48 /** NOTICE: sizeof(byte)=1 and sizeof(word)=2 **/ 49 /*************************************************************/ 50 /* typedef unsigned char byte; */ 51 /* typedef unsigned short word; */ 52 /* typedef signed char offset; */ 53 54 /** Structured Datatypes *************************************/ 55 /** NOTICE: #define LSB_FIRST for machines where least **/ 56 /** signifcant byte goes first. **/ 57 /*************************************************************/ 58 /* typedef union */ 59 /* { */ 60 /* word W; */ 61 /* #ifdef LSB_FIRST */ 62 /* struct { byte l,h; } B; */ 63 /* #else */ 64 /* struct { byte h,l; } B; */ 65 /* #endif */ 66 /* } pair; */ 67 68 typedef struct M6502 69 { 70 byte A,P,X,Y,S; /* CPU registers and program counter */ 71 pair PC; 72 73 int IPeriod,ICount; /* Set IPeriod to number of CPU cycles */ 74 /* between calls to Loop6502() */ 75 word IRequest; /* Set to the INT_IRQ when pending IRQ */ 76 byte AfterCLI; /* Private, don't touch */ 77 int IBackup; /* Private, don't touch */ 78 cal_cpu User; /* Arbitrary user data (ID,RAM*,etc.) */ 79 byte TrapBadOps; /* Set to 1 to warn of illegal opcodes */ 80 word Trap; /* Set Trap to address to trace from */ 81 byte Trace; /* Set Trace=1 to start tracing */ 82 byte memshift; 83 word memmask; 84 memread8_t *readtable; 85 memwrite8_t *writetable; 86 ranged_mmu *mmu; 87 unsigned char *cur_ip; 88 unsigned short ip_left; 89 } M6502; 90 91 /** Reset6502() **********************************************/ 92 /** This function can be used to reset the registers before **/ 93 /** starting execution with Run6502(). It sets registers to **/ 94 /** their initial values. **/ 95 /*************************************************************/ 96 void Reset6502(register M6502 *R); 97 98 /** Int6502() ************************************************/ 99 /** This function will generate interrupt of a given type. **/ 100 /** INT_NMI will cause a non-maskable interrupt. INT_IRQ **/ 101 /** will cause a normal interrupt, unless M6502_I_FLAG set in R. **/ 102 /*************************************************************/ 103 void Int6502(register M6502 *R,register word Type); 104 105 /** Run6502() ************************************************/ 106 /** This function will run 6502 code until Loop6502() call **/ 107 /** returns INT_QUIT. It will return the PC at which **/ 108 /** emulation stopped, and current register values in R. **/ 109 /*************************************************************/ 110 word Run6502(register M6502 *R); 111 112 /** Debug6502() **********************************************/ 113 /** This function should exist if DEBUG is #defined. When **/ 114 /** Trace!=0, it is called after each command executed by **/ 115 /** the CPU, and given the 6502 registers. Emulation exits **/ 116 /** if Debug6502() returns 0. **/ 117 /*************************************************************/ 118 byte Debug6502(register M6502 *R); 119 120 /** Loop6502() ***********************************************/ 121 /** 6502 emulation calls this function periodically to **/ 122 /** check if the system hardware requires any interrupts. **/ 123 /** This function must return one of following values: **/ 124 /** INT_NONE, INT_IRQ, INT_NMI, or INT_QUIT to exit the **/ 125 /** emulation loop. **/ 126 /************************************ TO BE WRITTEN BY USER **/ 127 byte Loop6502(register M6502 *R); 128 129 #endif /* M6502_H */ 130 131 /* 132 * $Log: m6502.h,v $ 133 * Revision 1.6 1999/11/21 04:39:22 nyef 134 * added preliminary implementation of ranged mmu 135 * 136 * Revision 1.5 1999/08/07 16:19:25 nyef 137 * removed definition of LSB_FIRST 138 * 139 * Revision 1.4 1999/04/17 20:07:58 nyef 140 * fixed for new version of the CAL. 141 * 142 * Revision 1.3 1999/01/03 02:24:33 nyef 143 * modified interrupt handling to not conflict with mz80. 144 * moved type definitions out to mtypes.h. 145 * 146 * Revision 1.2 1998/12/22 04:56:55 nyef 147 * changed x_FLAG to M6502_x_FLAG. 148 * 149 * Revision 1.1 1998/12/16 03:50:26 nyef 150 * Initial revision 151 * 152 */ 153