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 "Random.hxx"
19#include "System.hxx"
20#include "CartF4.hxx"
21
22// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
23CartridgeF4::CartridgeF4(const ByteBuffer& image, size_t size,
24 const string& md5, const Settings& settings)
25 : Cartridge(settings, md5),
26 myBankOffset(0)
27{
28 // Copy the ROM image into my buffer
29 std::copy_n(image.get(), std::min(myImage.size(), size), myImage.begin());
30 createCodeAccessBase(myImage.size());
31}
32
33// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
34void CartridgeF4::reset()
35{
36 // Upon reset we switch to the startup bank
37 initializeStartBank(0);
38 bank(startBank());
39}
40
41// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
42void CartridgeF4::install(System& system)
43{
44 mySystem = &system;
45
46 // Install pages for the startup bank
47 bank(startBank());
48}
49
50// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
51uInt8 CartridgeF4::peek(uInt16 address)
52{
53 address &= 0x0FFF;
54
55 // Switch banks if necessary
56 if((address >= 0x0FF4) && (address <= 0x0FFB))
57 {
58 bank(address - 0x0FF4);
59 }
60
61 return myImage[myBankOffset + address];
62}
63
64// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
65bool CartridgeF4::poke(uInt16 address, uInt8)
66{
67 address &= 0x0FFF;
68
69 // Switch banks if necessary
70 if((address >= 0x0FF4) && (address <= 0x0FFB))
71 {
72 bank(address - 0x0FF4);
73 }
74
75 return false;
76}
77
78// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
79bool CartridgeF4::bank(uInt16 bank)
80{
81 if(bankLocked()) return false;
82
83 // Remember what bank we're in
84 myBankOffset = bank << 12;
85
86 System::PageAccess access(this, System::PageAccessType::READ);
87
88 // Set the page accessing methods for the hot spots
89 for(uInt16 addr = (0x1FF4 & ~System::PAGE_MASK); addr < 0x2000;
90 addr += System::PAGE_SIZE)
91 {
92 access.codeAccessBase = &myCodeAccessBase[myBankOffset + (addr & 0x0FFF)];
93 mySystem->setPageAccess(addr, access);
94 }
95
96 // Setup the page access methods for the current bank
97 for(uInt16 addr = 0x1000; addr < (0x1FF4U & ~System::PAGE_MASK);
98 addr += System::PAGE_SIZE)
99 {
100 access.directPeekBase = &myImage[myBankOffset + (addr & 0x0FFF)];
101 access.codeAccessBase = &myCodeAccessBase[myBankOffset + (addr & 0x0FFF)];
102 mySystem->setPageAccess(addr, access);
103 }
104 return myBankChanged = true;
105}
106
107// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
108uInt16 CartridgeF4::getBank(uInt16) const
109{
110 return myBankOffset >> 12;
111}
112
113// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
114uInt16 CartridgeF4::bankCount() const
115{
116 return 8;
117}
118
119// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
120bool CartridgeF4::patch(uInt16 address, uInt8 value)
121{
122 myImage[myBankOffset + (address & 0x0FFF)] = value;
123 return myBankChanged = true;
124}
125
126// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
127const uInt8* CartridgeF4::getImage(size_t& size) const
128{
129 size = myImage.size();
130 return myImage.data();
131}
132
133// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
134bool CartridgeF4::save(Serializer& out) const
135{
136 try
137 {
138 out.putShort(myBankOffset);
139 }
140 catch(...)
141 {
142 cerr << "ERROR: CartridgeF4::save" << endl;
143 return false;
144 }
145
146 return true;
147}
148
149// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
150bool CartridgeF4::load(Serializer& in)
151{
152 try
153 {
154 myBankOffset = in.getShort();
155 }
156 catch(...)
157 {
158 cerr << "ERROR: CartridgeF4::load" << endl;
159 return false;
160 }
161
162 // Remember what bank we were in
163 bank(myBankOffset >> 12);
164
165 return true;
166}
167