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 "Cart4A50.hxx"
19#include "PopUpWidget.hxx"
20#include "Cart4A50Widget.hxx"
21
22// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
23Cartridge4A50Widget::Cartridge4A50Widget(
24 GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
25 int x, int y, int w, int h, Cartridge4A50& cart)
26 : CartDebugWidget(boss, lfont, nfont, x, y, w, h),
27 myCart(cart)
28{
29 string info =
30 "4A50 cartridge - 128K ROM and 32K RAM, split in various bank configurations\n"
31 "Multiple hotspots, see documentation for further details\n"
32 "Lower bank region (2K) : $F000 - $F7FF\n"
33 "Middle bank region (1.5K): $F800 - $FDFF\n"
34 "High bank region (256B) : $FE00 - $FEFF\n"
35 "Fixed (last 256B of ROM) : $FF00 - $FFFF\n";
36
37 int xpos = 2,
38 ypos = addBaseInformation(cart.mySize, "John Payson / Supercat", info) +
39 myLineHeight;
40
41 VariantList items16, items32, items128, items256;
42 for(uInt32 i = 0; i < 16; ++i)
43 VarList::push_back(items16, i);
44 VarList::push_back(items16, "Inactive", "");
45
46 for(uInt32 i = 0; i < 32; ++i)
47 VarList::push_back(items32, i);
48 VarList::push_back(items32, "Inactive", "");
49
50 for(uInt32 i = 0; i < 128; ++i)
51 VarList::push_back(items128, i);
52 VarList::push_back(items128, "Inactive", "");
53
54 for(uInt32 i = 0; i < 256; ++i)
55 VarList::push_back(items256, i);
56 VarList::push_back(items256, "Inactive", "");
57
58 string lowerlabel = "Set lower 2K region ($F000 - $F7FF): ";
59 string middlelabel = "Set middle 1.5K region ($F800 - $FDFF): ";
60 string highlabel = "Set high 256B region ($FE00 - $FEFF): ";
61 const int lwidth = _font.getStringWidth(middlelabel),
62 fwidth = _font.getStringWidth("Inactive"),
63 flwidth = _font.getStringWidth("ROM ");
64
65 // Lower bank/region configuration
66 xpos = 2;
67 new StaticTextWidget(_boss, _font, xpos, ypos, lwidth,
68 myFontHeight, lowerlabel, TextAlign::Left);
69 ypos += myLineHeight + 8;
70
71 xpos += 40;
72 myROMLower =
73 new PopUpWidget(boss, _font, xpos, ypos-2, fwidth, myLineHeight,
74 items32, "ROM ", flwidth, kROMLowerChanged);
75 myROMLower->setTarget(this);
76 addFocusWidget(myROMLower);
77
78 xpos += myROMLower->getWidth() + 20;
79 myRAMLower =
80 new PopUpWidget(boss, _font, xpos, ypos-2, fwidth, myLineHeight,
81 items16, "RAM ", flwidth, kRAMLowerChanged);
82 myRAMLower->setTarget(this);
83 addFocusWidget(myRAMLower);
84
85 // Middle bank/region configuration
86 xpos = 2; ypos += myLineHeight + 14;
87 new StaticTextWidget(_boss, _font, xpos, ypos, lwidth,
88 myFontHeight, middlelabel, TextAlign::Left);
89 ypos += myLineHeight + 8;
90
91 xpos += 40;
92 myROMMiddle =
93 new PopUpWidget(boss, _font, xpos, ypos-2, fwidth, myLineHeight,
94 items32, "ROM ", flwidth, kROMMiddleChanged);
95 myROMMiddle->setTarget(this);
96 addFocusWidget(myROMMiddle);
97
98 xpos += myROMMiddle->getWidth() + 20;
99 myRAMMiddle =
100 new PopUpWidget(boss, _font, xpos, ypos-2, fwidth, myLineHeight,
101 items16, "RAM ", flwidth, kRAMMiddleChanged);
102 myRAMMiddle->setTarget(this);
103 addFocusWidget(myRAMMiddle);
104
105 // High bank/region configuration
106 xpos = 2; ypos += myLineHeight + 14;
107 new StaticTextWidget(_boss, _font, xpos, ypos, lwidth,
108 myFontHeight, highlabel, TextAlign::Left);
109 ypos += myLineHeight + 8;
110
111 xpos += 40;
112 myROMHigh =
113 new PopUpWidget(boss, _font, xpos, ypos-2, fwidth, myLineHeight,
114 items256, "ROM ", flwidth, kROMHighChanged);
115 myROMHigh->setTarget(this);
116 addFocusWidget(myROMHigh);
117
118 xpos += myROMHigh->getWidth() + 20;
119 myRAMHigh =
120 new PopUpWidget(boss, _font, xpos, ypos-2, fwidth, myLineHeight,
121 items128, "RAM ", flwidth, kRAMHighChanged);
122 myRAMHigh->setTarget(this);
123 addFocusWidget(myRAMHigh);
124}
125
126// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
127void Cartridge4A50Widget::loadConfig()
128{
129 // Lower bank
130 if(myCart.myIsRomLow) // ROM active
131 {
132 myROMLower->setSelectedIndex((myCart.mySliceLow >> 11) & 0x1F);
133 myRAMLower->setSelectedMax();
134 }
135 else // RAM active
136 {
137 myROMLower->setSelectedMax();
138 myRAMLower->setSelectedIndex((myCart.mySliceLow >> 11) & 0x0F);
139 }
140
141 // Middle bank
142 if(myCart.myIsRomMiddle) // ROM active
143 {
144 myROMMiddle->setSelectedIndex((myCart.mySliceMiddle >> 11) & 0x1F);
145 myRAMMiddle->setSelectedMax();
146 }
147 else // RAM active
148 {
149 myROMMiddle->setSelectedMax();
150 myRAMMiddle->setSelectedIndex((myCart.mySliceMiddle >> 11) & 0x0F);
151 }
152
153 // High bank
154 if(myCart.myIsRomHigh) // ROM active
155 {
156 myROMHigh->setSelectedIndex((myCart.mySliceHigh >> 11) & 0xFF);
157 myRAMHigh->setSelectedMax();
158 }
159 else // RAM active
160 {
161 myROMHigh->setSelectedMax();
162 myRAMHigh->setSelectedIndex((myCart.mySliceHigh >> 11) & 0x7F);
163 }
164
165 CartDebugWidget::loadConfig();
166}
167
168// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
169void Cartridge4A50Widget::handleCommand(CommandSender* sender,
170 int cmd, int data, int id)
171{
172 myCart.unlockBank();
173
174 switch(cmd)
175 {
176 case kROMLowerChanged:
177 if(myROMLower->getSelected() < 32)
178 {
179 myCart.bankROMLower(myROMLower->getSelected());
180 myRAMLower->setSelectedMax();
181 }
182 else
183 {
184 // default to first RAM bank
185 myRAMLower->setSelectedIndex(0);
186 myCart.bankRAMLower(0);
187 }
188 break;
189
190 case kRAMLowerChanged:
191 if(myRAMLower->getSelected() < 16)
192 {
193 myROMLower->setSelectedMax();
194 myCart.bankRAMLower(myRAMLower->getSelected());
195 }
196 else
197 {
198 // default to first ROM bank
199 myROMLower->setSelectedIndex(0);
200 myCart.bankROMLower(0);
201 }
202 break;
203
204 case kROMMiddleChanged:
205 if(myROMMiddle->getSelected() < 32)
206 {
207 myCart.bankROMMiddle(myROMMiddle->getSelected());
208 myRAMMiddle->setSelectedMax();
209 }
210 else
211 {
212 // default to first RAM bank
213 myRAMMiddle->setSelectedIndex(0);
214 myCart.bankRAMMiddle(0);
215 }
216 break;
217
218 case kRAMMiddleChanged:
219 if(myRAMMiddle->getSelected() < 16)
220 {
221 myROMMiddle->setSelectedMax();
222 myCart.bankRAMMiddle(myRAMMiddle->getSelected());
223 }
224 else
225 {
226 // default to first ROM bank
227 myROMMiddle->setSelectedIndex(0);
228 myCart.bankROMMiddle(0);
229 }
230 break;
231
232 case kROMHighChanged:
233 if(myROMHigh->getSelected() < 256)
234 {
235 myCart.bankROMHigh(myROMHigh->getSelected());
236 myRAMHigh->setSelectedMax();
237 }
238 else
239 {
240 // default to first RAM bank
241 myRAMHigh->setSelectedIndex(0);
242 myCart.bankRAMHigh(0);
243 }
244 break;
245
246 case kRAMHighChanged:
247 if(myRAMHigh->getSelected() < 128)
248 {
249 myROMHigh->setSelectedMax();
250 myCart.bankRAMHigh(myRAMHigh->getSelected());
251 }
252 else
253 {
254 // default to first ROM bank
255 myROMHigh->setSelectedIndex(0);
256 myCart.bankROMHigh(0);
257 }
258 break;
259 }
260
261 myCart.lockBank();
262 invalidate();
263}
264
265// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
266string Cartridge4A50Widget::bankState()
267{
268 ostringstream& buf = buffer();
269
270 buf << "L/M/H = " << std::dec;
271 if(myCart.myIsRomLow)
272 buf << "ROM bank " << ((myCart.mySliceLow >> 11) & 0x1F) << " / ";
273 else
274 buf << "RAM bank " << ((myCart.mySliceLow >> 11) & 0x0F) << " / ";
275 if(myCart.myIsRomMiddle)
276 buf << "ROM bank " << ((myCart.mySliceMiddle >> 11) & 0x1F) << " / ";
277 else
278 buf << "RAM bank " << ((myCart.mySliceMiddle >> 11) & 0x0F) << " / ";
279 if(myCart.myIsRomHigh)
280 buf << "ROM bank " << ((myCart.mySliceHigh >> 11) & 0xFF);
281 else
282 buf << "RAM bank " << ((myCart.mySliceHigh >> 11) & 0x7F);
283
284 return buf.str();
285}
286