1 /*****************************************************************************
2  *
3  *	 ops09.h
4  *
5  *	 Copyright (c) 2000 Peter Trauner, all rights reserved.
6  *   documentation by michael steil mist@c64.org
7  *   available at ftp://ftp.funet.fi/pub/cbm/c65
8  *
9  *	 - This source code is released as freeware for non-commercial purposes.
10  *	 - You are free to use and redistribute this code in modified or
11  *	   unmodified form, provided you list me in the credits.
12  *	 - If you modify this source code, you must add a notice to each modified
13  *	   source file that it has been changed.  If you're a nice person, you
14  *	   will clearly mark each change too.  :)
15  *	 - If you wish to use this for commercial purposes, please contact me at
16  *	   pullmoll@t-online.de
17  *	 - The author of this copywritten work reserves the right to change the
18  *     terms of its usage and license at any time, including retroactively
19  *   - This entire notice must remain in the source code.
20  *
21  *****************************************************************************/
22 
23 #define m6502 m6509
24 #define m6502_ICount m6509_ICount
25 
26 #define ZPWH	m6509.zp.w.h
27 
28 #define EAWH	m6509.ea.w.h
29 
30 #define PBWH	m6509.pc_bank.w.h
31 #define PB		m6509.pc_bank.d
32 
33 #define IBWH	m6509.ind_bank.w.h
34 #define IB		m6509.ind_bank.d
35 
36 #undef CHANGE_PC
37 #define CHANGE_PC change_pc20(PCD|PB)
38 
39 /***************************************************************
40  *  RDOP    read an opcode
41  ***************************************************************/
42 #undef RDOP
43 #define RDOP() cpu_readop((PCW++)|PB)
44 
45 /***************************************************************
46  *  RDOPARG read an opcode argument
47  ***************************************************************/
48 #undef RDOPARG
49 #define RDOPARG() cpu_readop_arg((PCW++)|PB)
50 
51 /***************************************************************
52  *  RDMEM   read memory
53  ***************************************************************/
54 #undef RDMEM
55 #define RDMEM(addr) cpu_readmem20(addr)
56 
57 /***************************************************************
58  *  WRMEM   write memory
59  ***************************************************************/
60 #undef WRMEM
61 #define WRMEM(addr,data) cpu_writemem20(addr,data)
62 
63 /***************************************************************
64  * push a register onto the stack
65  ***************************************************************/
66 #undef PUSH
67 #define PUSH(Rg) WRMEM(SPD|PB, Rg); S--
68 
69 /***************************************************************
70  * pull a register from the stack
71  ***************************************************************/
72 #undef PULL
73 #define PULL(Rg) S++; Rg = RDMEM(SPD|PB)
74 
75 
76 /***************************************************************
77  *  EA = zero page address
78  ***************************************************************/
79 #undef EA_ZPG
80 #define EA_ZPG													\
81 	ZPL = RDOPARG();											\
82 	ZPWH = PBWH;												\
83     EAD = ZPD
84 
85 /***************************************************************
86  *  EA = zero page address + X
87  ***************************************************************/
88 #undef EA_ZPX
89 #define EA_ZPX													\
90 	ZPL = RDOPARG() + X;										\
91 	ZPWH = PBWH;												\
92     EAD = ZPD
93 
94 /***************************************************************
95  *  EA = zero page address + Y
96  ***************************************************************/
97 #undef EA_ZPY
98 #define EA_ZPY													\
99 	ZPL = RDOPARG() + Y;										\
100 	ZPWH = PBWH;												\
101     EAD = ZPD
102 
103 /***************************************************************
104  *  EA = absolute address
105  ***************************************************************/
106 #undef EA_ABS
107 #define EA_ABS													\
108 	EAL = RDOPARG();											\
109 	EAH = RDOPARG();											\
110     EAWH = PBWH
111 
112 /***************************************************************
113  *  EA = zero page + X indirect (pre indexed)
114  ***************************************************************/
115 #undef EA_IDX
116 #define EA_IDX													\
117 	ZPL = RDOPARG() + X;										\
118 	ZPWH=PBWH;													\
119 	EAL = RDMEM(ZPD);											\
120 	ZPL++;														\
121 	EAH = RDMEM(ZPD);											\
122     EAWH = PBWH
123 
124 /***************************************************************
125  *  EA = zero page indirect + Y (post indexed)
126  *	subtract 1 cycle if page boundary is crossed
127  ***************************************************************/
128 #undef EA_IDY
129 #define EA_IDY													\
130 	ZPL = RDOPARG();											\
131 	ZPWH = PBWH;												\
132 	EAL = RDMEM(ZPD);											\
133 	ZPL++;														\
134 	EAH = RDMEM(ZPD);											\
135 	EAWH = PBWH;												\
136     if (EAL + Y > 0xff)                                         \
137 		m6509_ICount--; 										\
138 	EAW += Y
139 
140 
141 /***************************************************************
142  *  EA = zero page indirect + Y (post indexed)
143  *	subtract 1 cycle if page boundary is crossed
144  ***************************************************************/
145 #define EA_IDY_6509 											\
146 	ZPL = RDOPARG();											\
147 	ZPWH = PBWH;												\
148 	EAL = RDMEM(ZPD);											\
149 	ZPL++;														\
150 	EAH = RDMEM(ZPD);											\
151 	EAWH = IBWH;												\
152     if (EAL + Y > 0xff)                                         \
153 		m6509_ICount--; 										\
154 	EAW += Y
155 
156 /***************************************************************
157  *	EA = indirect (only used by JMP)
158  ***************************************************************/
159 #undef EA_IND
160 #define EA_IND													\
161 	EA_ABS; 													\
162 	tmp = RDMEM(EAD);											\
163 	EAL++;	/* booby trap: stay in same page! ;-) */			\
164 	EAH = RDMEM(EAD);											\
165 	EAL = tmp;
166 /*	EAWH = PBWH */
167 
168 #define RD_IDY_6509	EA_IDY_6509; tmp = RDMEM(EAD)
169 #define WR_IDY_6509	EA_IDY_6509; WRMEM(EAD, tmp)
170 
171 /***************************************************************
172  *	BRA  branch relative
173  *	extra cycle if page boundary is crossed
174  ***************************************************************/
175 #undef BRA
176 #define BRA(cond)                                               \
177 	if (cond)													\
178 	{															\
179 		tmp = RDOPARG();										\
180 		EAW = PCW + (signed char)tmp;							\
181 		m6509_ICount -= (PCH == EAH) ? 3 : 4;					\
182 		PCD = EAD|PB;											\
183 		CHANGE_PC;												\
184 	}															\
185 	else														\
186 	{															\
187 		PCW++;													\
188 		m6509_ICount -= 2;										\
189 	}
190 
191 /* 6502 ********************************************************
192  *	JSR Jump to subroutine
193  *	decrement PC (sic!) push PC hi, push PC lo and set
194  *	PC to the effective address
195  ***************************************************************/
196 #undef JSR
197 #define JSR 													\
198 	EAL = RDOPARG();											\
199 	PUSH(PCH);													\
200 	PUSH(PCL);													\
201 	EAH = RDOPARG();											\
202 	EAWH = PBWH;												\
203 	PCD = EAD;													\
204 	CHANGE_PC
205 
206 /* 6510 ********************************************************
207  *	KIL Illegal opcode
208  * processor haltet, no hardware interrupt will help
209  * only reset
210  ***************************************************************/
211 #undef KIL
212 #define KIL 													\
213 	PCW--;