Skip to content

Commit 51ba782

Browse files
committed
Merge branch 'dev'
2 parents cc3d76a + c5e3222 commit 51ba782

24 files changed

+408
-182
lines changed

Amiga/Amiga.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -534,6 +534,10 @@ Amiga::reset()
534534
void
535535
Amiga::_initialize()
536536
{
537+
/*
538+
ChangeRecorder<16> r;
539+
r.test();
540+
*/
537541
}
538542

539543
void
@@ -1009,9 +1013,10 @@ Amiga::runLoop()
10091013
cpu.recordInstruction();
10101014
}
10111015

1012-
// Are we requestes to check for breakpoints?
1016+
// Are we requested to check for breakpoints?
10131017
if (runLoopCtrl & RL_ENABLE_BREAKPOINTS) {
10141018
if (cpu.bpManager.shouldStop()) {
1019+
inspect();
10151020
putMessage(MSG_BREAKPOINT_REACHED);
10161021
debug(RUNLOOP_DEBUG, "BREAKPOINT_REACHED\n");
10171022
break;

Amiga/Computer/Agnus/Agnus.cpp

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,8 @@ Agnus::_inspect()
210210
{
211211
// Prevent external access to variable 'info'
212212
pthread_mutex_lock(&lock);
213-
213+
214+
info.bplcon0 = bplcon0;
214215
info.dmacon = dmacon;
215216
info.diwstrt = diwstrt;
216217
info.diwstop = diwstop;
@@ -219,7 +220,7 @@ Agnus::_inspect()
219220

220221
info.bpl1mod = bpl1mod;
221222
info.bpl2mod = bpl2mod;
222-
info.numBpls = denise->enabledChannels();
223+
info.bpu = bpu();
223224

224225
info.dskpt = dskpt;
225226
for (unsigned i = 0; i < 4; i++) info.audlc[i] = audlc[i];
@@ -250,10 +251,10 @@ Agnus::_dump()
250251
dumpBplEventTable();
251252
}
252253

253-
DMAInfo
254+
AgnusInfo
254255
Agnus::getInfo()
255256
{
256-
DMAInfo result;
257+
AgnusInfo result;
257258

258259
pthread_mutex_lock(&lock);
259260
result = info;
@@ -302,9 +303,9 @@ bool
302303
Agnus::inBplDmaLine(uint16_t dmacon, uint16_t bplcon0) {
303304

304305
return
305-
ddfVFlop // Outside VBLANK, inside DIW
306-
&& Denise::enabledChannels(bplcon0) // At least one bitplane enabled
307-
&& bplDMA(dmacon); // Bitplane DMA enabled
306+
ddfVFlop // Outside VBLANK, inside DIW
307+
&& bpu(bplcon0) // At least one bitplane enabled
308+
&& bplDMA(dmacon); // Bitplane DMA enabled
308309
}
309310

310311
Cycle
@@ -575,7 +576,7 @@ Agnus::allocateBplSlots(uint16_t dmacon, uint16_t bplcon0, int first, int last)
575576
{
576577
assert(first >= 0 && last < HPOS_MAX);
577578

578-
int channels = Denise::enabledChannels(bplcon0);
579+
int channels = bpu(bplcon0);
579580
bool hires = Denise::hires(bplcon0);
580581

581582
// Set number of bitplanes to 0 if we are not in a bitplane DMA line
@@ -609,7 +610,7 @@ Agnus::switchBitplaneDmaOn()
609610
int16_t stop;
610611

611612
bool hires = denise->hires();
612-
int activeBitplanes = denise->enabledChannels();
613+
int activeBitplanes = bpu();
613614

614615
// Determine the range that is covered by fetch units
615616
if (hires) {
@@ -1502,6 +1503,20 @@ Agnus::setBPLCON0(uint16_t oldValue, uint16_t newValue)
15021503
bplcon0 = newValue;
15031504
}
15041505

1506+
int
1507+
Agnus::bpu(uint16_t v)
1508+
{
1509+
// Extract the three BPU bits and check for hires mode
1510+
int bpu = (v >> 12) & 0b111;
1511+
bool hires = GET_BIT(v, 15);
1512+
1513+
if (hires) {
1514+
return bpu < 5 ? bpu : 0; // Disable all channels if value is invalid
1515+
} else {
1516+
return bpu < 7 ? bpu : 4; // Enable four channels if value is invalid
1517+
}
1518+
}
1519+
15051520
void
15061521
Agnus::execute()
15071522
{

Amiga/Computer/Agnus/Agnus.h

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "Blitter.h"
1616
#include "DmaDebugger.h"
1717
#include "Beam.h"
18+
#include "Event.h"
1819

1920
// Bit plane indices
2021
#define PLANE1 0
@@ -51,7 +52,6 @@
5152
#define VPOS(x) ((x) >> 8)
5253
#define HPOS(x) ((x) & 0xFF)
5354

54-
5555
class Agnus : public HardwareComponent
5656
{
5757
// Quick-access references
@@ -63,7 +63,7 @@ class Agnus : public HardwareComponent
6363
class Paula *paula;
6464

6565
// Information shown in the GUI inspector panel
66-
DMAInfo info;
66+
AgnusInfo info;
6767
EventInfo eventInfo;
6868

6969

@@ -366,6 +366,9 @@ class Agnus : public HardwareComponent
366366
// Registers
367367
//
368368

369+
// Ringbuffer for managing register change delays
370+
ChangeRecorder<8> changeRecorder;
371+
369372
// A copy of BPLCON0 (Denise has another copy)
370373
uint16_t bplcon0;
371374
uint16_t bplcon0New;
@@ -505,8 +508,7 @@ class Agnus : public HardwareComponent
505508
& hsyncActions
506509
& clock
507510
& frame
508-
& pos.v
509-
& pos.h
511+
& pos
510512
& frameInfo.nr
511513
& frameInfo.interlaced
512514
& frameInfo.numLines
@@ -539,6 +541,7 @@ class Agnus : public HardwareComponent
539541
& dmaStopHires
540542
& dmaStrtLoresShift
541543

544+
& changeRecorder
542545
& bplcon0
543546
& bplcon0New
544547
& bplcon0AtDDFStrt
@@ -601,7 +604,7 @@ class Agnus : public HardwareComponent
601604
public:
602605

603606
// Returns the latest recorded internal state
604-
DMAInfo getInfo();
607+
AgnusInfo getInfo();
605608
EventInfo getEventInfo();
606609
EventSlotInfo getEventSlotInfo(int nr);
607610

@@ -612,10 +615,6 @@ class Agnus : public HardwareComponent
612615

613616
public:
614617

615-
// Returns the current position of the video beam
616-
// int16_t vpos() { return pos.v; }
617-
// int16_t hpos() { return pos.h; }
618-
619618
// Indicates if the current frame is a long or a short frame
620619
bool isLongFrame() { return frameInfo.numLines == 313; }
621620
bool isShortFrame() { return frameInfo.numLines == 312; }
@@ -849,6 +848,15 @@ class Agnus : public HardwareComponent
849848
void pokeBPLCON0(uint16_t value);
850849
void setBPLCON0(uint16_t oldValue, uint16_t newValue);
851850

851+
/* Returns the Agnus view of the BPU bits.
852+
* The value determines the number of enabled DMA channels. It is computed
853+
* out of the three BPU bits stored in BPLCON0, but not identical with them.
854+
* The value differs if the BPU bits reflect an invalid bit pattern.
855+
* Compare with Denise::bpu() which returns the Denise view of the BPU bits.
856+
*/
857+
static int bpu(uint16_t v);
858+
int bpu() { return bpu(bplcon0); }
859+
852860
// BPLxPTL, BPLxPTH
853861
template <int x, PokeSource s> void pokeBPLxPTH(uint16_t value);
854862
template <int x, PokeSource s> void pokeBPLxPTL(uint16_t value);

Amiga/Computer/Agnus/AgnusTypes.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ DMADebuggerInfo;
145145

146146
typedef struct
147147
{
148+
uint16_t bplcon0;
148149
uint16_t dmacon;
149150
uint16_t diwstrt;
150151
uint16_t diwstop;
@@ -153,14 +154,14 @@ typedef struct
153154

154155
int16_t bpl1mod;
155156
int16_t bpl2mod;
156-
uint8_t numBpls;
157+
uint8_t bpu;
157158

158159
uint32_t dskpt;
159160
uint32_t audlc[4];
160161
uint32_t bplpt[6];
161162
uint32_t sprpt[8];
162163
}
163-
DMAInfo;
164+
AgnusInfo;
164165

165166
typedef struct
166167
{

Amiga/Computer/Agnus/Blitter.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -741,7 +741,6 @@ Blitter::terminate()
741741
bbusy = false;
742742

743743
// Trigger the Blitter interrupt
744-
// agnus->scheduleRel<IRQ_BLIT_SLOT>(0, IRQ_SET);
745744
paula->raiseIrq(INT_BLIT);
746745

747746
// Clear the Blitter slot

Amiga/Computer/Agnus/EventHandler.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,16 @@ Agnus::inspectEventSlot(EventSlot nr)
6060

6161
switch ((EventSlot)nr) {
6262

63+
case REG_SLOT:
64+
switch (slot[nr].id) {
65+
66+
case 0: i->eventName = "none"; break;
67+
case REG_CHANGE: i->eventName = "REG_CHANGE"; break;
68+
case REG_HSYNC: i->eventName = "REG_HSYNC"; break;
69+
default: i->eventName = "*** INVALID ***"; break;
70+
}
71+
break;
72+
6373
case AGN_SLOT:
6474
switch (slot[nr].id) {
6575

@@ -354,6 +364,9 @@ Agnus::executeEventsUntil(Cycle cycle) {
354364
// Check primary slots
355365
//
356366

367+
if (isDue<REG_SLOT>(cycle)) {
368+
serviceREGEvent();
369+
}
357370
if (isDue<AGN_SLOT>(cycle)) {
358371
serviceAGNEvent();
359372
}
@@ -446,6 +459,14 @@ Agnus::serviceCIAEvent()
446459
}
447460
}
448461

462+
void
463+
Agnus::serviceREGEvent()
464+
{
465+
assert(checkTriggeredEvent(REG_SLOT));
466+
467+
// Schedule next event
468+
}
469+
449470
void
450471
Agnus::serviceAGNEvent()
451472
{
@@ -760,6 +781,14 @@ Agnus::checkScheduledEvent(EventSlot s)
760781
}
761782

762783
switch (s) {
784+
case REG_SLOT:
785+
if (!isRegEvent(id)) {
786+
_dump();
787+
panic("Invalid REG event ID.");
788+
return false;
789+
}
790+
break;
791+
763792
case AGN_SLOT:
764793
if (!isAgnEvent(id)) {
765794
_dump();
@@ -826,6 +855,12 @@ Agnus::checkTriggeredEvent(EventSlot s)
826855
{
827856
switch (s) {
828857

858+
case REG_SLOT:
859+
if (slot[s].id != REG_HSYNC) {
860+
assert(pos.h == 0xE3); return false;
861+
}
862+
break;
863+
829864
case AGN_SLOT:
830865
if (slot[s].id != AGN_ACTIONS) {
831866
assert(false); return false;

Amiga/Computer/Agnus/EventHandler.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,7 @@ void executeEventsUntil(Cycle cycle);
229229

230230
// Event handlers for specific slots
231231
template <int nr> void serviceCIAEvent();
232+
void serviceREGEvent();
232233
void serviceAGNEvent();
233234
void serviceBPLEvent();
234235
void serviceDASEvent();

Amiga/Computer/Agnus/EventHandlerTypes.h

Lines changed: 9 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@
2323
typedef enum : long
2424
{
2525
// Primary slots
26-
AGN_SLOT = 0, // Agnus
26+
REG_SLOT = 0, // Register changes and HSYNC
27+
AGN_SLOT, // Agnus (DEPRECATED, WILL BE REPLACED BY REG_SLOT)
2728
CIAA_SLOT, // CIA A execution
2829
CIAB_SLOT, // CIA B execution
2930
BPL_SLOT, // Bitplane DMA
@@ -53,6 +54,7 @@ static inline bool isSecondarySlot(long s) { return s > SEC_SLOT && s < SLOT_COU
5354
inline const char *slotName(EventSlot nr)
5455
{
5556
switch (nr) {
57+
case REG_SLOT: return "Registers";
5658
case AGN_SLOT: return "Agnus";
5759
case CIAA_SLOT: return "CIA A";
5860
case CIAB_SLOT: return "CIA B";
@@ -85,6 +87,11 @@ typedef enum : long
8587
// Events in the primary event table
8688
//
8789

90+
// REG slot
91+
REG_CHANGE = 1,
92+
REG_HSYNC,
93+
REG_EVENT_COUNT,
94+
8895
// AGN slot
8996
AGN_ACTIONS = 1,
9097
AGN_EVENT_COUNT,
@@ -173,22 +180,8 @@ typedef enum : long
173180

174181
// IRQ slots
175182
IRQ_CHECK = 1,
176-
IRQ_SET, // DEPRECATED
177-
IRQ_CLEAR, // DEPRECATED
178183
IRQ_EVENT_COUNT,
179184

180-
// REG slots
181-
REG_DMACON = 1,
182-
REG_DIWSTRT,
183-
REG_DIWSTOP,
184-
REG_BPLCON1,
185-
REG_BPLCON2,
186-
REG_BPL1MOD,
187-
REG_BPL2MOD,
188-
REG_BPLxPTH,
189-
REG_BPLxPTL,
190-
REG_EVENT_COUNT,
191-
192185
// Keyboard
193186
KBD_SELFTEST = 1,
194187
KBD_SYNC,
@@ -226,6 +219,7 @@ typedef enum : long
226219

227220
} EventID;
228221

222+
static inline bool isRegEvent(EventID id) { return id < REG_EVENT_COUNT; }
229223
static inline bool isAgnEvent(EventID id) { return id < AGN_EVENT_COUNT; }
230224
static inline bool isCiaEvent(EventID id) { return id < CIA_EVENT_COUNT; }
231225
static inline bool isBplEvent(EventID id) { return id < BPL_EVENT_COUNT; }
@@ -332,17 +326,4 @@ typedef struct
332326
}
333327
EventInfo;
334328

335-
struct Event
336-
{
337-
// Indicates when the event is due.
338-
Cycle triggerCycle;
339-
340-
// Identifier of the scheduled event.
341-
EventID id;
342-
343-
// Optional data value
344-
// Can be used to pass additional information to the event handler.
345-
int64_t data;
346-
};
347-
348329
#endif

0 commit comments

Comments
 (0)