00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef SYSTEMROMBANKS_H
00023 #define SYSTEMROMBANKS_H
00024
00025 #include <string.h>
00026 #include <stdint.h>
00027
00028 #include "Bank.h"
00029 #include "sidplayfp/c64/CPU/opcodes.h"
00030
00035 template <int N>
00036 class romBank : public Bank
00037 {
00038 protected:
00040 uint8_t rom[N];
00041
00042 protected:
00044 void setVal(uint_least16_t address, uint8_t val) { rom[address & (N-1)]=val; }
00045
00047 uint8_t getVal(uint_least16_t address) const { return rom[address & (N-1)]; }
00048
00050 void* getPtr(uint_least16_t address) const { return (void*)&rom[address & (N-1)]; }
00051
00052 public:
00054 void set(const uint8_t* source) { if (source) memcpy(rom, source, N); }
00055
00057 void poke(uint_least16_t address SID_UNUSED, uint8_t value SID_UNUSED) {}
00058
00059 uint8_t peek(uint_least16_t address) { return rom[address & (N-1)]; }
00060 };
00061
00065 class KernalRomBank : public romBank<0x2000>
00066 {
00067 private:
00068 uint8_t resetVectorLo;
00069 uint8_t resetVectorHi;
00070
00071 public:
00072 void set(const uint8_t* kernal)
00073 {
00074 romBank<0x2000>::set(kernal);
00075
00076 if (kernal)
00077 {
00078
00079 setVal(0xfd69, 0x9f);
00080 setVal(0xe55f, 0x00);
00081 setVal(0xfdc4, 0xea);
00082 setVal(0xfdc5, 0xea);
00083 setVal(0xfdc6, 0xea);
00084 }
00085 else
00086 {
00087
00088 setVal(0xea31, LDAa);
00089 setVal(0xea32, 0x0D);
00090 setVal(0xea33, 0xDC);
00091 setVal(0xea34, PLAn);
00092 setVal(0xea35, TAYn);
00093 setVal(0xea36, PLAn);
00094 setVal(0xea37, TAXn);
00095 setVal(0xea38, PLAn);
00096 setVal(0xea39, RTIn);
00097
00098
00099 setVal(0xff84, LDAa);
00100 setVal(0xff85, 0xa6);
00101 setVal(0xff86, 0x02);
00102 setVal(0xff87, BEQr);
00103 setVal(0xff88, 0x06);
00104 setVal(0xff89, LDAb);
00105 setVal(0xff8a, 0x25);
00106 setVal(0xff8b, LDXb);
00107 setVal(0xff8c, 0x40);
00108 setVal(0xff8d, BNEr);
00109 setVal(0xff8e, 0x04);
00110 setVal(0xff8f, LDAb);
00111 setVal(0xff90, 0x95);
00112 setVal(0xff91, LDXb);
00113 setVal(0xff92, 0x42);
00114 setVal(0xff93, STAa);
00115 setVal(0xff94, 0x04);
00116 setVal(0xff95, 0xdc);
00117 setVal(0xff96, STXa);
00118 setVal(0xff97, 0x05);
00119 setVal(0xff98, 0xdc);
00120 setVal(0xff99, LDAb);
00121 setVal(0xff9a, 0x0f);
00122 setVal(0xff9b, STAa);
00123 setVal(0xff9c, 0x18);
00124 setVal(0xff9d, 0xd4);
00125 setVal(0xff9e, RTSn);
00126
00127
00128 setVal(0xffa0, PHAn);
00129 setVal(0xffa1, TXAn);
00130 setVal(0xffa2, PHAn);
00131 setVal(0xffa3, TYAn);
00132 setVal(0xffa4, PHAn);
00133 setVal(0xffa5, JMPi);
00134 setVal(0xffa6, 0x14);
00135 setVal(0xffa7, 0x03);
00136
00137
00138 setVal(0xfffa, 0x39);
00139 setVal(0xfffb, 0xea);
00140 setVal(0xfffc, 0x39);
00141 setVal(0xfffd, 0xea);
00142 setVal(0xfffe, 0xa0);
00143 setVal(0xffff, 0xff);
00144 }
00145
00146
00147 resetVectorLo = getVal(0xfffc);
00148 resetVectorHi = getVal(0xfffd);
00149 }
00150
00151 void reset()
00152 {
00153
00154 setVal(0xfffc, resetVectorLo);
00155 setVal(0xfffd, resetVectorHi);
00156 }
00157
00163 void installResetHook(uint_least16_t addr)
00164 {
00165 setVal(0xfffc, endian_16lo8(addr));
00166 setVal(0xfffd, endian_16hi8(addr));
00167 }
00168 };
00169
00173 class BasicRomBank : public romBank<0x2000>
00174 {
00175 private:
00176 uint8_t trap[3];
00177 uint8_t subTune[11];
00178
00179 public:
00180 void set(const uint8_t* basic)
00181 {
00182 romBank<0x2000>::set(basic);
00183
00184
00185 memcpy(trap, getPtr(0xa7ae), 3);
00186
00187 memcpy(subTune, getPtr(0xbf53), 11);
00188 }
00189
00190 void reset()
00191 {
00192
00193 memcpy(getPtr(0xa7ae), trap, 3);
00194
00195 memcpy(getPtr(0xbf53), subTune, 11);
00196 }
00197
00203 void installTrap(uint_least16_t addr)
00204 {
00205 setVal(0xa7ae, JMPw);
00206 setVal(0xa7af, endian_16lo8(addr));
00207 setVal(0xa7b0, endian_16hi8(addr));
00208 }
00209
00210 void setSubtune(uint8_t tune)
00211 {
00212 setVal(0xbf53, LDAb);
00213 setVal(0xbf54, tune);
00214 setVal(0xbf55, STAa);
00215 setVal(0xbf56, 0x0c);
00216 setVal(0xbf57, 0x03);
00217 setVal(0xbf58, JSRw);
00218 setVal(0xbf59, 0x2c);
00219 setVal(0xbf5a, 0xa8);
00220 setVal(0xbf5b, JMPw);
00221 setVal(0xbf5c, 0xb1);
00222 setVal(0xbf5d, 0xa7);
00223 }
00224 };
00225
00229 class CharacterRomBank : public romBank<0x1000> {};
00230
00231 #endif