ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/SIDPlayer/src/cpu.cpp
Revision: 1.4
Committed: 2003-10-21T16:56:19Z (21 years ago) by cebix
Branch: MAIN
Changes since 1.3: +2 -2 lines
Log Message:
- play_adr is updated from the IRQ vector every time before the replay routine
  is called if it was 0 in the PSID header (this makes some tunes play
  correctly now)
- f(void) -> f() (this is C++, dammit!)

File Contents

# Content
1 /*
2 * cpu.cpp - 6510 CPU emulation
3 *
4 * SIDPlayer (C) Copyright 1996-2003 Christian Bauer
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21 #include "sys.h"
22
23 #include "mem.h"
24 #include "sid.h"
25
26 #define DEBUG 0
27 #include "debug.h"
28
29
30 // Memory access functions
31 typedef uint32 (*mem_read_func)(uint32, cycle_t);
32 typedef void (*mem_write_func)(uint32, uint32, cycle_t, bool);
33
34 static mem_read_func mem_read_table[256]; // Table of read/write functions for 256 pages
35 static mem_write_func mem_write_table[256];
36
37
38 // Memory access function prototypes
39 static uint32 ram_read(uint32 adr, cycle_t now);
40 static void ram_write(uint32 adr, uint32 byte, cycle_t now, bool rmw);
41 static void cia_write(uint32 adr, uint32 byte, cycle_t now, bool rmw);
42
43
44 /*
45 * Init CPU emulation
46 */
47
48 static void set_memory_funcs(uint16 from, uint16 to, mem_read_func r, mem_write_func w)
49 {
50 for (int page = (from >> 8); page <= (to >> 8); page++) {
51 mem_read_table[page] = r;
52 mem_write_table[page] = w;
53 }
54 }
55
56 void CPUInit()
57 {
58 // Set up memory access tables
59 set_memory_funcs(0x0000, 0xffff, ram_read, ram_write);
60 set_memory_funcs(0xd400, 0xd7ff, sid_read, sid_write);
61 set_memory_funcs(0xdc00, 0xdcff, ram_read, cia_write);
62 }
63
64
65 /*
66 * Exit CPU emulation
67 */
68
69 void CPUExit()
70 {
71 }
72
73
74 /*
75 * Memory access functions
76 */
77
78 static uint32 ram_read(uint32 adr, cycle_t now)
79 {
80 return ram[adr];
81 }
82
83 static void ram_write(uint32 adr, uint32 byte, cycle_t now, bool rmw)
84 {
85 ram[adr] = byte;
86 }
87
88 static void cia_write(uint32 adr, uint32 byte, cycle_t now, bool rmw)
89 {
90 if (adr == 0xdc04)
91 cia_tl_write(byte);
92 else if (adr == 0xdc05)
93 cia_th_write(byte);
94 else
95 ram[adr] = byte;
96 }
97
98
99 /*
100 * CPU emulation loop
101 */
102
103 void CPUExecute(uint16 startadr, uint8 init_ra, uint8 init_rx, uint8 init_ry, cycle_t max_cycles)
104 {
105 // 6510 registers
106 register uint8 a = init_ra, x = init_rx, y = init_ry;
107 register uint8 n_flag = 0, z_flag = 0;
108 uint8 sp = 0xff, pflags = 0;
109
110 // Program counter
111 register uint8 *pc;
112
113 // Temporary address storage
114 uint16 adr;
115
116 // Phi 2 cycle counter
117 register cycle_t current_cycle = 0;
118
119 // Flag: last branch instruction delays IRQ/NMI by 1 cycle (unused)
120 bool branch_delays_int = false;
121
122 #define RA a
123 #define RX x
124 #define RY y
125 #define RSP sp
126 #define RPC (pc - ram)
127 #define N_FLAG n_flag
128 #define Z_FLAG z_flag
129 #define PFLAGS pflags
130 #define ADR adr
131
132 #define read_byte(adr) \
133 mem_read_table[(adr) >> 8](adr, current_cycle)
134 #define read_zp(adr) \
135 ram[adr]
136
137 #define write_byte(adr, byte) \
138 mem_write_table[(adr) >> 8](adr, byte, current_cycle, false)
139 #define write_byte_rmw(adr, byte) \
140 mem_write_table[(adr) >> 8](adr, byte, current_cycle, true)
141 #define write_zp(adr, byte) \
142 ram[adr] = (byte)
143
144 #define read_idle(adr)
145 #define read_idle_zp(adr)
146 #define read_idle_stack(sp)
147
148 #define read_opcode \
149 (*pc)
150 #define read_idle_opcode
151
152 #define push_byte(byte) \
153 { \
154 if (sp == 0) \
155 quit = true; \
156 (ram + 0x100)[sp--] = (byte); \
157 }
158 #define pop_byte \
159 (sp == 0xff ? (quit = true, 0) : (ram + 0x100)[++sp])
160
161 #define jump(adr) \
162 pc = ram + (adr)
163 #define inc_pc \
164 pc++
165
166 #define next_cycle \
167 current_cycle++
168
169 #include "cpu_macros.h"
170
171 // Jump to specified start address
172 jump(startadr);
173
174 // Main loop: execute opcodes until stack under-/overflow, RTI, illegal opcode, or max_cycles reached
175 bool quit = false;
176 while (current_cycle < max_cycles && !quit) {
177
178 // Fetch opcode
179 uint8 opcode = read_opcode; inc_pc; next_cycle;
180
181 // Execute opcode
182 switch (opcode) {
183 #include "cpu_opcodes.h"
184 case 0xf2:
185 default:
186 illegal_op: quit = true;
187 break;
188 }
189 }
190 }