Skip to content

Commit

Permalink
Passing tests sprdma18 and sprdma20
Browse files Browse the repository at this point in the history
  • Loading branch information
dirkwhoffmann committed Jan 13, 2024
1 parent 69acf02 commit fa07bd6
Show file tree
Hide file tree
Showing 8 changed files with 200 additions and 213 deletions.
7 changes: 5 additions & 2 deletions Emulator/Components/Agnus/Agnus.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,7 @@ Agnus::executeFirstSpriteCycle()
if (sprdma()) {

auto value = doSpriteDmaRead<nr>();
agnus.pokeSPRxPOS<nr>(value);
agnus.pokeSPRxPOS<nr, ACCESSOR_AGNUS>(value);
denise.pokeSPRxPOS<nr>(value);

} else {
Expand Down Expand Up @@ -547,7 +547,7 @@ Agnus::executeSecondSpriteCycle()

// Read in the next control word (CTL part)
auto value = doSpriteDmaRead<nr>();
agnus.pokeSPRxCTL<nr>(value);
agnus.pokeSPRxCTL<nr, ACCESSOR_AGNUS>(value);
denise.pokeSPRxCTL<nr>(value);

} else {
Expand Down Expand Up @@ -648,6 +648,9 @@ Agnus::eolHandler()
// Clear the bus usage table
for (isize i = 0; i < HPOS_CNT; i++) busOwner[i] = BUS_NONE;

// Clear other variables
for (isize i = 0; i < 8; i++) lastCtlWrite[i] = 0xFF;

// Schedule the first BPL and DAS events
scheduleFirstBplEvent();
scheduleFirstDasEvent();
Expand Down
11 changes: 7 additions & 4 deletions Emulator/Components/Agnus/Agnus.h
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,9 @@ class Agnus : public SubComponent {
// Recorded DMA usage for all cycles in the current rasterline
BusOwner busOwner[HPOS_CNT] = { };


// Remembers the last write to SPRxCTL (EXPERIMENTAL)
u8 lastCtlWrite[8] = { };

//
// Signals from other components
//
Expand Down Expand Up @@ -277,7 +279,8 @@ class Agnus : public SubComponent {

<< busValue
<< busOwner

<< lastCtlWrite

<< audxDR
<< audxDSR
<< bls
Expand Down Expand Up @@ -542,10 +545,10 @@ class Agnus : public SubComponent {
void pokeBPL2MOD(u16 value);
void setBPL2MOD(u16 value);

template <int x> void pokeSPRxPOS(u16 value);
template <int x, Accessor> void pokeSPRxPOS(u16 value);
template <int x> void setSPRxPOS(u16 value);

template <int x> void pokeSPRxCTL(u16 value);
template <int x, Accessor> void pokeSPRxCTL(u16 value);
template <int x> void setSPRxCTL(u16 value);

void pokeBEAMCON0(u16 value);
Expand Down
127 changes: 72 additions & 55 deletions Emulator/Components/Agnus/AgnusRegs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -438,10 +438,22 @@ Agnus::setBPL2MOD(u16 value)
bpl2mod = (i16)(value & 0xFFFE);
}

template <int x> void
template <int x, Accessor s> void
Agnus::pokeSPRxPOS(u16 value)
{
trace(SPRREG_DEBUG, "pokeSPR%dPOS(%04x)\n", x, value);
trace(SPRREG_DEBUG, "pokeSPR%dPOS<%s>(%04x)\n", x, AccessorEnum::key(s), value);

// setSPRxPOS<x>(value);
// return;

// Hypothesis (test cases Sprites/sprdma/intefere):
// DMA cycle is dropped when the register was written one cycle earlier.
if (lastCtlWrite[x] + 1 == pos.h && (pos.h % 2) == 1) {

xfiles("pokeSPR%dPOS(%04x) dropped\n", x, value);
return;
}

recordRegisterChange(DMA_CYCLES(2), SET_SPR0POS + x, value);
}

Expand All @@ -451,7 +463,8 @@ Agnus::setSPRxPOS(u16 value)
trace(SPRREG_DEBUG, "setSPR%dPOS(%04x)\n", x, value);

// Compute the value of the vertical counter that is seen here
i16 v = (i16)(pos.h < 0xDF ? pos.v : (pos.v + 1));
// i16 v = (i16)(pos.h < 0xDF ? pos.v : (pos.v + 1));
i16 v = (i16)(pos.h < 0xE1 ? pos.v : (pos.v + 1));

// Compute the new vertical start position
sprVStrt[x] = ((value & 0xFF00) >> 8) | (sprVStrt[x] & 0x0100);
Expand All @@ -461,10 +474,22 @@ Agnus::setSPRxPOS(u16 value)
if (sprVStop[x] == v) sprDmaState[x] = SPR_DMA_IDLE;
}

template <int x> void
template <int x, Accessor s> void
Agnus::pokeSPRxCTL(u16 value)
{
trace(SPRREG_DEBUG, "pokeSPR%dCTL(%04x)\n", x, value);

// setSPRxCTL<x>(value);
// return;

// Hypothesis (test cases Sprites/sprdma/intefere):
// DMA cycle is dropped when the register was written one cycle earlier.
if (lastCtlWrite[x] + 1 == pos.h && (pos.h % 2) == 1) {

xfiles("pokeSPR%dCTL(%04x) dropped\n", x, value);
return;
}

recordRegisterChange(DMA_CYCLES(2), SET_SPR0CTL + x, value);
}

Expand All @@ -473,20 +498,26 @@ Agnus::setSPRxCTL(u16 value)
{
trace(SPRREG_DEBUG, "setSPR%dCTL(%04x)\n", x, value);

// Remember the write cycle (checked in pokeSPRxCTL)
lastCtlWrite[x] = u8(pos.h);

// Compute the value of the vertical counter that is seen here
i16 v = (i16)(pos.h < 0xDF ? pos.v : (pos.v + 1));
// i16 v = (i16)(pos.h < 0xDF ? pos.v : (pos.v + 1));
i16 v = (i16)(pos.h < 0xE1 ? pos.v : (pos.v + 1));

// Compute the new vertical start and stop position
sprVStrt[x] = (i16)((value & 0b100) << 6 | (sprVStrt[x] & 0x00FF));
sprVStop[x] = (i16)((value & 0b010) << 7 | (value >> 8));

// ECS Agnus supports an additional position bit (encoded in 'unused' area)
// ECS Agnus supports additional position bits (encoded in 'unused' area)
if (GET_BIT(value, 6)) {
xfiles("pokeSPRxCTL: Extended VSTRT bit set\n");

xfiles("setSPR%dCTL: Extended VSTRT bit set\n", x);
if (isECS()) sprVStrt[x] |= 0x0200;
}
if (GET_BIT(value, 5)) {
xfiles("pokeSPRxCTL: Extended VSTOP bit set\n");

xfiles("setSPR%dCTL: Extended VSTOP bit set\n", x);
if (isECS()) sprVStop[x] |= 0x0200;
}

Expand Down Expand Up @@ -691,8 +722,11 @@ Agnus::dropWrite(BusOwner owner)
//

#define DECLARE(x) \
template void Agnus::x<ACCESSOR_CPU>(u16 value); \
template void Agnus::x<ACCESSOR_AGNUS>(u16 value);
DECLAREA(x,ACCESSOR_CPU) \
DECLAREA(x,ACCESSOR_AGNUS)

#define DECLAREA(x,y) \
template void Agnus::x<y>(u16 value);

DECLARE(pokeDSKPTH)
DECLARE(pokeDSKPTL)
Expand All @@ -702,63 +736,48 @@ DECLARE(pokeDIWSTRT)
DECLARE(pokeDIWSTOP)
DECLARE(pokeDIWHIGH)

#undef DECLARE
#undef DECLAREA

#define DECLARE(x) \
template void Agnus::x<0,ACCESSOR_CPU>(u16 value); \
template void Agnus::x<1,ACCESSOR_CPU>(u16 value); \
template void Agnus::x<2,ACCESSOR_CPU>(u16 value); \
template void Agnus::x<3,ACCESSOR_CPU>(u16 value); \
template void Agnus::x<0,ACCESSOR_AGNUS>(u16 value); \
template void Agnus::x<1,ACCESSOR_AGNUS>(u16 value); \
template void Agnus::x<2,ACCESSOR_AGNUS>(u16 value); \
template void Agnus::x<3,ACCESSOR_AGNUS>(u16 value);
#define DECLAREA(x,y) \
template void Agnus::x<0,y>(u16 value); \
template void Agnus::x<1,y>(u16 value); \
template void Agnus::x<2,y>(u16 value); \
template void Agnus::x<3,y>(u16 value);

DECLARE(pokeAUDxLCH);
DECLARE(pokeAUDxLCL);

#undef DECLARE
#undef DECLAREA

#define DECLARE(x) \
template void Agnus::x<1,ACCESSOR_CPU>(u16 value); \
template void Agnus::x<2,ACCESSOR_CPU>(u16 value); \
template void Agnus::x<3,ACCESSOR_CPU>(u16 value); \
template void Agnus::x<4,ACCESSOR_CPU>(u16 value); \
template void Agnus::x<5,ACCESSOR_CPU>(u16 value); \
template void Agnus::x<6,ACCESSOR_CPU>(u16 value); \
template void Agnus::x<1,ACCESSOR_AGNUS>(u16 value); \
template void Agnus::x<2,ACCESSOR_AGNUS>(u16 value); \
template void Agnus::x<3,ACCESSOR_AGNUS>(u16 value); \
template void Agnus::x<4,ACCESSOR_AGNUS>(u16 value); \
template void Agnus::x<5,ACCESSOR_AGNUS>(u16 value); \
template void Agnus::x<6,ACCESSOR_AGNUS>(u16 value);
#define DECLAREA(x,y) \
template void Agnus::x<1,y>(u16 value); \
template void Agnus::x<2,y>(u16 value); \
template void Agnus::x<3,y>(u16 value); \
template void Agnus::x<4,y>(u16 value); \
template void Agnus::x<5,y>(u16 value); \
template void Agnus::x<6,y>(u16 value);

DECLARE(pokeBPLxPTH)
DECLARE(pokeBPLxPTL)

#undef DECLARE
#undef DECLAREA

#define DECLARE(x) \
template void Agnus::x<0,ACCESSOR_CPU>(u16 value); \
template void Agnus::x<1,ACCESSOR_CPU>(u16 value); \
template void Agnus::x<2,ACCESSOR_CPU>(u16 value); \
template void Agnus::x<3,ACCESSOR_CPU>(u16 value); \
template void Agnus::x<4,ACCESSOR_CPU>(u16 value); \
template void Agnus::x<5,ACCESSOR_CPU>(u16 value); \
template void Agnus::x<6,ACCESSOR_CPU>(u16 value); \
template void Agnus::x<7,ACCESSOR_CPU>(u16 value); \
template void Agnus::x<0,ACCESSOR_AGNUS>(u16 value); \
template void Agnus::x<1,ACCESSOR_AGNUS>(u16 value); \
template void Agnus::x<2,ACCESSOR_AGNUS>(u16 value); \
template void Agnus::x<3,ACCESSOR_AGNUS>(u16 value); \
template void Agnus::x<4,ACCESSOR_AGNUS>(u16 value); \
template void Agnus::x<5,ACCESSOR_AGNUS>(u16 value); \
template void Agnus::x<6,ACCESSOR_AGNUS>(u16 value); \
template void Agnus::x<7,ACCESSOR_AGNUS>(u16 value);
#define DECLAREA(x,y) \
template void Agnus::x<0,y>(u16 value); \
template void Agnus::x<1,y>(u16 value); \
template void Agnus::x<2,y>(u16 value); \
template void Agnus::x<3,y>(u16 value); \
template void Agnus::x<4,y>(u16 value); \
template void Agnus::x<5,y>(u16 value); \
template void Agnus::x<6,y>(u16 value); \
template void Agnus::x<7,y>(u16 value);

DECLARE(pokeSPRxPOS)
DECLARE(pokeSPRxCTL)
DECLARE(pokeSPRxPTH)
DECLARE(pokeSPRxPTL)

#undef DECLAREA
#undef DECLARE

#define DECLARE(x) \
Expand All @@ -784,12 +803,10 @@ template void Agnus::x<5>(u16 value); \
template void Agnus::x<6>(u16 value); \
template void Agnus::x<7>(u16 value);

DECLARE(pokeSPRxPOS)
DECLARE(pokeSPRxCTL)

DECLARE(setSPRxPTH)
DECLARE(setSPRxPTL)
DECLARE(setSPRxPOS)
DECLARE(setSPRxCTL)

#undef DECLARE
}
3 changes: 2 additions & 1 deletion Emulator/Components/Agnus/Sequencer/SequencerDas.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ Sequencer::initDasEventTable()
p[0x33] = DAS_S7_2;
}

p[0xDF] = DAS_SDMA;
// p[0xDF] = DAS_SDMA;
p[0xE1] = DAS_SDMA;
p[0x66] = DAS_TICK;

// p[0x10] = DAS_HSYNC; // Same cycle as A2
Expand Down
2 changes: 1 addition & 1 deletion Emulator/Components/Denise/Denise.h
Original file line number Diff line number Diff line change
Expand Up @@ -625,7 +625,7 @@ class Denise : public SubComponent {
template <isize x> void pokeSPRxDATA(u16 value);
template <isize x> void pokeSPRxDATB(u16 value);

template <Accessor s, isize xx> void pokeCOLORxx(u16 value);
template <isize xx, Accessor s> void pokeCOLORxx(u16 value);


//
Expand Down
5 changes: 0 additions & 5 deletions Emulator/Components/Denise/DeniseDebugger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -172,11 +172,6 @@ DeniseDebugger::vsyncHandler()

// Notify the GUI if the last message was sent a while ago
if (abs(agnus.clock - vpMsgSent) > MSEC(200)) {

printf("Sending viewport: %d %d %d %d\n", i16(latchedMaxViewPort.hstrt),
i16(latchedMaxViewPort.vstrt),
i16(latchedMaxViewPort.hstop),
i16(latchedMaxViewPort.vstop));

msgQueue.put(MSG_VIEWPORT, ViewportMsg {
i16(latchedMaxViewPort.hstrt),
Expand Down
Loading

0 comments on commit fa07bd6

Please sign in to comment.