1//============================================================================
2//
3// SSSS tt lll lll
4// SS SS tt ll ll
5// SS tttttt eeee ll ll aaaa
6// SSSS tt ee ee ll ll aa
7// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
8// SS SS tt ee ll ll aa aa
9// SSSS ttt eeeee llll llll aaaaa
10//
11// Copyright (c) 1995-2019 by Bradford W. Mott, Stephen Anthony
12// and the Stella Team
13//
14// See the file "License.txt" for information on usage and redistribution of
15// this file, and for a DISCLAIMER OF ALL WARRANTIES.
16//============================================================================
17
18#include "System.hxx"
19#include "CartEF.hxx"
20
21// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
22CartridgeEF::CartridgeEF(const ByteBuffer& image, size_t size,
23 const string& md5, const Settings& settings)
24 : Cartridge(settings, md5),
25 myBankOffset(0)
26{
27 // Copy the ROM image into my buffer
28 std::copy_n(image.get(), std::min(myImage.size(), size), myImage.begin());
29 createCodeAccessBase(myImage.size());
30}
31
32// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
33void CartridgeEF::reset()
34{
35 initializeStartBank(1);
36
37 // Upon reset we switch to the startup bank
38 bank(startBank());
39}
40
41// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
42void CartridgeEF::install(System& system)
43{
44 mySystem = &system;
45
46 // Install pages for the startup bank
47 bank(startBank());
48}
49
50// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
51uInt8 CartridgeEF::peek(uInt16 address)
52{
53 address &= 0x0FFF;
54
55 // Switch banks if necessary
56 if((address >= 0x0FE0) && (address <= 0x0FEF))
57 bank(address - 0x0FE0);
58
59 return myImage[myBankOffset + address];
60}
61
62// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
63bool CartridgeEF::poke(uInt16 address, uInt8)
64{
65 address &= 0x0FFF;
66
67 // Switch banks if necessary
68 if((address >= 0x0FE0) && (address <= 0x0FEF))
69 bank(address - 0x0FE0);
70
71 return false;
72}
73
74// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
75bool CartridgeEF::bank(uInt16 bank)
76{
77 if(bankLocked()) return false;
78
79 // Remember what bank we're in
80 myBankOffset = bank << 12;
81
82 System::PageAccess access(this, System::PageAccessType::READ);
83
84 // Set the page accessing methods for the hot spots
85 for(uInt16 addr = (0x1FE0 & ~System::PAGE_MASK); addr < 0x2000;
86 addr += System::PAGE_SIZE)
87 {
88 access.codeAccessBase = &myCodeAccessBase[myBankOffset + (addr & 0x0FFF)];
89 mySystem->setPageAccess(addr, access);
90 }
91
92 // Setup the page access methods for the current bank
93 for(uInt16 addr = 0x1000; addr < (0x1FE0U & ~System::PAGE_MASK);
94 addr += System::PAGE_SIZE)
95 {
96 access.directPeekBase = &myImage[myBankOffset + (addr & 0x0FFF)];
97 access.codeAccessBase = &myCodeAccessBase[myBankOffset + (addr & 0x0FFF)];
98 mySystem->setPageAccess(addr, access);
99 }
100 return myBankChanged = true;
101}
102
103// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
104uInt16 CartridgeEF::getBank(uInt16) const
105{
106 return myBankOffset >> 12;
107}
108
109// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
110uInt16 CartridgeEF::bankCount() const
111{
112 return 16;
113}
114
115// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
116bool CartridgeEF::patch(uInt16 address, uInt8 value)
117{
118 myImage[myBankOffset + (address & 0x0FFF)] = value;
119 return myBankChanged = true;
120}
121
122// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
123const uInt8* CartridgeEF::getImage(size_t& size) const
124{
125 size = myImage.size();
126 return myImage.data();
127}
128
129// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
130bool CartridgeEF::save(Serializer& out) const
131{
132 try
133 {
134 out.putShort(myBankOffset);
135 }
136 catch(...)
137 {
138 cerr << "ERROR: CartridgeEF::save" << endl;
139 return false;
140 }
141
142 return true;
143}
144
145// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
146bool CartridgeEF::load(Serializer& in)
147{
148 try
149 {
150 myBankOffset = in.getShort();
151 }
152 catch(...)
153 {
154 cerr << "ERROR: CartridgeEF::load" << endl;
155 return false;
156 }
157
158 // Remember what bank we were in
159 bank(myBankOffset >> 12);
160
161 return true;
162}
163