libsidplayfp 1.8.8
SystemROMBanks.h
1/*
2 * This file is part of libsidplayfp, a SID player engine.
3 *
4 * Copyright 2012-2013 Leandro Nini <drfiemost@users.sourceforge.net>
5 * Copyright 2010 Antti Lankila
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 */
21
22#ifndef SYSTEMROMBANKS_H
23#define SYSTEMROMBANKS_H
24
25#include <stdint.h>
26#include <cstring>
27
28#include "Bank.h"
29#include "c64/CPU/opcodes.h"
30
35template <int N>
36class romBank : public Bank
37{
38protected:
40 uint8_t rom[N];
41
42protected:
46 void setVal(uint_least16_t address, uint8_t val) { rom[address & (N-1)]=val; }
47
51 uint8_t getVal(uint_least16_t address) const { return rom[address & (N-1)]; }
52
56 void* getPtr(uint_least16_t address) const { return (void*)&rom[address & (N-1)]; }
57
58public:
62 void set(const uint8_t* source) { if (source) memcpy(rom, source, N); }
63
67 void poke(uint_least16_t address SID_UNUSED, uint8_t value SID_UNUSED) {}
68
69 uint8_t peek(uint_least16_t address) { return rom[address & (N-1)]; }
70};
71
77class KernalRomBank : public romBank<0x2000>
78{
79private:
80 uint8_t resetVectorLo; // 0xfffc
81 uint8_t resetVectorHi; // 0xfffd
82
83public:
84 void set(const uint8_t* kernal)
85 {
87
88 if (kernal)
89 {
90 // Apply Kernal hacks
91 // FIXME these are tailored to the original kernals
92 // may not work as intended on other roms
93 setVal(0xfd69, 0x9f); // Bypass memory check
94 setVal(0xe55f, 0x00); // Bypass screen clear
95 setVal(0xfdc4, 0xea); // Ignore sid volume reset to avoid DC
96 setVal(0xfdc5, 0xea); // click (potentially incompatibility)!!
97 setVal(0xfdc6, 0xea);
98 }
99 else
100 {
101 // Normal IRQ interrupt
102 setVal(0xea31, LDAa); // Ack IRQs
103 setVal(0xea32, 0x0D);
104 setVal(0xea33, 0xDC);
105 setVal(0xea34, PLAn); // Restore regs
106 setVal(0xea35, TAYn);
107 setVal(0xea36, PLAn);
108 setVal(0xea37, TAXn);
109 setVal(0xea38, PLAn);
110 setVal(0xea39, RTIn); // Return
111
112 // Hardware setup routine
113 setVal(0xff84, LDAa); // Set CIA 1 Timer A
114 setVal(0xff85, 0xa6);
115 setVal(0xff86, 0x02);
116 setVal(0xff87, BEQr);
117 setVal(0xff88, 0x06);
118 setVal(0xff89, LDAb); // PAL
119 setVal(0xff8a, 0x25);
120 setVal(0xff8b, LDXb);
121 setVal(0xff8c, 0x40);
122 setVal(0xff8d, BNEr);
123 setVal(0xff8e, 0x04);
124 setVal(0xff8f, LDAb); // NTSC
125 setVal(0xff90, 0x95);
126 setVal(0xff91, LDXb);
127 setVal(0xff92, 0x42);
128 setVal(0xff93, STAa);
129 setVal(0xff94, 0x04);
130 setVal(0xff95, 0xdc);
131 setVal(0xff96, STXa);
132 setVal(0xff97, 0x05);
133 setVal(0xff98, 0xdc);
134 setVal(0xff99, LDAb); // Set SID to maximum volume
135 setVal(0xff9a, 0x0f);
136 setVal(0xff9b, STAa);
137 setVal(0xff9c, 0x18);
138 setVal(0xff9d, 0xd4);
139 setVal(0xff9e, RTSn);
140
141 // IRQ entry point
142 setVal(0xffa0, PHAn); // Save regs
143 setVal(0xffa1, TXAn);
144 setVal(0xffa2, PHAn);
145 setVal(0xffa3, TYAn);
146 setVal(0xffa4, PHAn);
147 setVal(0xffa5, JMPi); // Jump to IRQ routine
148 setVal(0xffa6, 0x14);
149 setVal(0xffa7, 0x03);
150
151 // Hardware vectors
152 setVal(0xfffa, 0x39); // NMI vector
153 setVal(0xfffb, 0xea);
154 setVal(0xfffc, 0x39); // RESET vector
155 setVal(0xfffd, 0xea);
156 setVal(0xfffe, 0xa0); // IRQ/BRK vector
157 setVal(0xffff, 0xff);
158 }
159
160 // Backup Reset Vector
161 resetVectorLo = getVal(0xfffc);
162 resetVectorHi = getVal(0xfffd);
163 }
164
165 void reset()
166 {
167 // Restore original Reset Vector
168 setVal(0xfffc, resetVectorLo);
169 setVal(0xfffd, resetVectorHi);
170 }
171
177 void installResetHook(uint_least16_t addr)
178 {
179 setVal(0xfffc, endian_16lo8(addr));
180 setVal(0xfffd, endian_16hi8(addr));
181 }
182};
183
189class BasicRomBank : public romBank<0x2000>
190{
191private:
192 uint8_t trap[3];
193 uint8_t subTune[11];
194
195public:
196 void set(const uint8_t* basic)
197 {
199
200 // Backup BASIC Warm Start
201 memcpy(trap, getPtr(0xa7ae), 3);
202
203 memcpy(subTune, getPtr(0xbf53), 11);
204 }
205
206 void reset()
207 {
208 // Restore original BASIC Warm Start
209 memcpy(getPtr(0xa7ae), trap, 3);
210
211 memcpy(getPtr(0xbf53), subTune, 11);
212 }
213
219 void installTrap(uint_least16_t addr)
220 {
221 setVal(0xa7ae, JMPw);
222 setVal(0xa7af, endian_16lo8(addr));
223 setVal(0xa7b0, endian_16hi8(addr));
224 }
225
226 void setSubtune(uint8_t tune)
227 {
228 setVal(0xbf53, LDAb);
229 setVal(0xbf54, tune);
230 setVal(0xbf55, STAa);
231 setVal(0xbf56, 0x0c);
232 setVal(0xbf57, 0x03);
233 setVal(0xbf58, JSRw);
234 setVal(0xbf59, 0x2c);
235 setVal(0xbf5a, 0xa8);
236 setVal(0xbf5b, JMPw);
237 setVal(0xbf5c, 0xb1);
238 setVal(0xbf5d, 0xa7);
239 }
240};
241
247class CharacterRomBank : public romBank<0x1000> {};
248
249#endif
Definition: Bank.h:33
Definition: SystemROMBanks.h:190
void installTrap(uint_least16_t addr)
Definition: SystemROMBanks.h:219
Definition: SystemROMBanks.h:247
Definition: SystemROMBanks.h:78
void installResetHook(uint_least16_t addr)
Definition: SystemROMBanks.h:177
Definition: SystemROMBanks.h:37
void * getPtr(uint_least16_t address) const
Definition: SystemROMBanks.h:56
uint8_t rom[N]
The ROM array.
Definition: SystemROMBanks.h:40
void setVal(uint_least16_t address, uint8_t val)
Definition: SystemROMBanks.h:46
void poke(uint_least16_t address SID_UNUSED, uint8_t value SID_UNUSED)
Definition: SystemROMBanks.h:67
void set(const uint8_t *source)
Definition: SystemROMBanks.h:62
uint8_t getVal(uint_least16_t address) const
Definition: SystemROMBanks.h:51
uint8_t peek(uint_least16_t address)
Definition: SystemROMBanks.h:69