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 "Cart3E.hxx"
19#include "PopUpWidget.hxx"
20#include "Cart3EWidget.hxx"
21
22// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
23Cartridge3EWidget::Cartridge3EWidget(
24 GuiObject* boss, const GUI::Font& lfont, const GUI::Font& nfont,
25 int x, int y, int w, int h, Cartridge3E& cart)
26 : CartDebugWidget(boss, lfont, nfont, x, y, w, h),
27 myCart(cart),
28 myNumRomBanks(uInt32(cart.mySize >> 11)),
29 myNumRamBanks(32)
30{
31 size_t size = cart.mySize;
32
33 ostringstream info;
34 info << "3E cartridge - (3F + RAM)\n"
35 << " 2-256 2K ROM (currently " << myNumRomBanks << "), 32 1K RAM\n"
36 << "First 2K (ROM) selected by writing to $3F\n"
37 "First 2K (RAM) selected by writing to $3E\n"
38 " $F000 - $F3FF (R), $F400 - $F7FF (W)\n"
39 "Last 2K always points to last 2K of ROM\n";
40 if(cart.startBank() < myNumRomBanks)
41 info << "Startup bank = " << cart.startBank() << " (ROM)\n";
42 else
43 info << "Startup bank = " << (cart.startBank()-myNumRomBanks) << " (RAM)\n";
44
45 // Eventually, we should query this from the debugger/disassembler
46 uInt16 start = (cart.myImage[size-3] << 8) | cart.myImage[size-4];
47 start -= start % 0x1000;
48 info << "Bank RORG" << " = $" << Common::Base::HEX4 << start << "\n";
49
50 int xpos = 2,
51 ypos = addBaseInformation(size, "TigerVision", info.str()) + myLineHeight;
52
53 VariantList romitems;
54 for(uInt32 i = 0; i < myNumRomBanks; ++i)
55 VarList::push_back(romitems, i);
56 VarList::push_back(romitems, "Inactive", "");
57
58 VariantList ramitems;
59 for(uInt32 i = 0; i < myNumRamBanks; ++i)
60 VarList::push_back(ramitems, i);
61 VarList::push_back(ramitems, "Inactive", "");
62
63 ostringstream label;
64 label << "Set bank ($" << Common::Base::HEX4 << start << " - $"
65 << (start+0x7FF) << "): ";
66
67 new StaticTextWidget(_boss, _font, xpos, ypos, _font.getStringWidth(label.str()),
68 myFontHeight, label.str(), TextAlign::Left);
69 ypos += myLineHeight + 8;
70
71 xpos += 40;
72 myROMBank =
73 new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("0 ($3E) "),
74 myLineHeight, romitems, "ROM ($3F) ",
75 _font.getStringWidth("ROM ($3F) "), kROMBankChanged);
76 myROMBank->setTarget(this);
77 addFocusWidget(myROMBank);
78
79 xpos += myROMBank->getWidth() + 20;
80 myRAMBank =
81 new PopUpWidget(boss, _font, xpos, ypos-2, _font.getStringWidth("0 ($3E) "),
82 myLineHeight, ramitems, "RAM ($3E) ",
83 _font.getStringWidth("RAM ($3E) "), kRAMBankChanged);
84 myRAMBank->setTarget(this);
85 addFocusWidget(myRAMBank);
86}
87
88// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
89void Cartridge3EWidget::saveOldState()
90{
91 myOldState.internalram.clear();
92
93 for(uInt32 i = 0; i < internalRamSize(); ++i)
94 myOldState.internalram.push_back(myCart.myRAM[i]);
95
96 myOldState.bank = myCart.myCurrentBank;
97}
98
99// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
100void Cartridge3EWidget::loadConfig()
101{
102 if(myCart.myCurrentBank < 256)
103 {
104 myROMBank->setSelectedIndex(myCart.myCurrentBank % myNumRomBanks, myOldState.bank != myCart.myCurrentBank);
105 myRAMBank->setSelectedMax(myOldState.bank >= 256);
106 }
107 else
108 {
109 myROMBank->setSelectedMax(myOldState.bank < 256);
110 myRAMBank->setSelectedIndex(myCart.myCurrentBank - 256, myOldState.bank != myCart.myCurrentBank);
111 }
112
113 CartDebugWidget::loadConfig();
114}
115
116// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
117void Cartridge3EWidget::handleCommand(CommandSender* sender,
118 int cmd, int data, int id)
119{
120 uInt16 bank = 0;
121
122 if(cmd == kROMBankChanged)
123 {
124 if(myROMBank->getSelected() < int(myNumRomBanks))
125 {
126 bank = myROMBank->getSelected();
127 myRAMBank->setSelectedMax();
128 }
129 else
130 {
131 bank = 256; // default to first RAM bank
132 myRAMBank->setSelectedIndex(0);
133 }
134 }
135 else if(cmd == kRAMBankChanged)
136 {
137 if(myRAMBank->getSelected() < int(myNumRamBanks))
138 {
139 myROMBank->setSelectedMax();
140 bank = myRAMBank->getSelected() + 256;
141 }
142 else
143 {
144 bank = 0; // default to first ROM bank
145 myROMBank->setSelectedIndex(0);
146 }
147 }
148
149 myCart.unlockBank();
150 myCart.bank(bank);
151 myCart.lockBank();
152 invalidate();
153}
154
155// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
156string Cartridge3EWidget::bankState()
157{
158 ostringstream& buf = buffer();
159
160 uInt16& bank = myCart.myCurrentBank;
161 if(bank < 256)
162 buf << "ROM bank #" << std::dec << bank % myNumRomBanks << ", RAM inactive";
163 else
164 buf << "ROM inactive, RAM bank #" << std::dec << bank % myNumRomBanks;
165
166 return buf.str();
167}
168
169// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
170uInt32 Cartridge3EWidget::internalRamSize()
171{
172 return 32*1024;
173}
174
175// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
176uInt32 Cartridge3EWidget::internalRamRPort(int start)
177{
178 return 0x0000 + start;
179}
180
181// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
182string Cartridge3EWidget::internalRamDescription()
183{
184 ostringstream desc;
185 desc << "Accessible 1K at a time via:\n"
186 << " $F000 - $F3FF used for Read Access\n"
187 << " $F400 - $F7FF used for Write Access";
188
189 return desc.str();
190}
191
192// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
193const ByteArray& Cartridge3EWidget::internalRamOld(int start, int count)
194{
195 myRamOld.clear();
196 for(int i = 0; i < count; i++)
197 myRamOld.push_back(myOldState.internalram[start + i]);
198 return myRamOld;
199}
200
201// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
202const ByteArray& Cartridge3EWidget::internalRamCurrent(int start, int count)
203{
204 myRamCurrent.clear();
205 for(int i = 0; i < count; i++)
206 myRamCurrent.push_back(myCart.myRAM[start + i]);
207 return myRamCurrent;
208}
209
210// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
211void Cartridge3EWidget::internalRamSetValue(int addr, uInt8 value)
212{
213 myCart.myRAM[addr] = value;
214}
215
216// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
217uInt8 Cartridge3EWidget::internalRamGetValue(int addr)
218{
219 return myCart.myRAM[addr];
220}
221