From 1dfc36f3111dcf2126ebebdb5f23bb0801b84f28 Mon Sep 17 00:00:00 2001
From: Thomas Harte <thomas.harte@gmail.com>
Date: Sun, 26 Sep 2021 18:15:32 -0400
Subject: [PATCH] Flip loop, add modulo mappings.

---
 .../Clock SignalTests/AmigaBlitterTests.mm    | 189 +++++++++---------
 1 file changed, 100 insertions(+), 89 deletions(-)

diff --git a/OSBindings/Mac/Clock SignalTests/AmigaBlitterTests.mm b/OSBindings/Mac/Clock SignalTests/AmigaBlitterTests.mm
index 21eee0eae..0b1c1bf48 100644
--- a/OSBindings/Mac/Clock SignalTests/AmigaBlitterTests.mm	
+++ b/OSBindings/Mac/Clock SignalTests/AmigaBlitterTests.mm	
@@ -23,7 +23,7 @@ struct Chipset {};
 @implementation AmigaBlitterTests
 
 - (void)testWorkbench13BootLogo {
-	uint16_t ram[512 * 1024]{};
+	uint16_t ram[256 * 1024]{};
 	Amiga::Chipset nonChipset;
 	Amiga::Blitter blitter(nonChipset, ram, 256 * 1024);
 
@@ -45,119 +45,130 @@ struct Chipset {};
 	} state = State::AwaitingWrites;
 
 	std::vector<std::pair<uint32_t, uint16_t>> writes;
+	BOOL hasFailed = NO;
 
 	for(NSArray *const event in trace) {
+		if(hasFailed) break;
+
 		NSString *const type = event[0];
 		const NSInteger param1 = [event[1] integerValue];
 
-		if([type isEqualToString:@"bltcon0"]) {
-			blitter.set_control(0, param1);
-			state = State::AwaitingWrites;
+		if([type isEqualToString:@"cread"] || [type isEqualToString:@"bread"] || [type isEqualToString:@"aread"]) {
+			ram[param1 >> 1] = [event[2] integerValue];
+			state = State::LoggingWrites;
 			continue;
 		}
-		if([type isEqualToString:@"bltcon1"]) {
-			blitter.set_control(1, param1);
-			state = State::AwaitingWrites;
-			continue;
-		}
-
-		if([type isEqualToString:@"bltsize"]) {
-			blitter.set_size(param1);
-			state = State::AwaitingWrites;
-			continue;
-		}
-
-		if([type isEqualToString:@"bltafwm"]) {
-			blitter.set_first_word_mask(param1);
-			state = State::AwaitingWrites;
-			continue;
-		}
-		if([type isEqualToString:@"bltalwm"]) {
-			blitter.set_last_word_mask(param1);
-			state = State::AwaitingWrites;
-			continue;
-		}
-
-		if([type isEqualToString:@"bltadat"]) {
-			blitter.set_data(0, param1);
-			state = State::AwaitingWrites;
-			continue;
-		}
-		if([type isEqualToString:@"bltbdat"]) {
-			blitter.set_data(1, param1);
-			state = State::AwaitingWrites;
-			continue;
-		}
-		if([type isEqualToString:@"bltcdat"]) {
-			blitter.set_data(2, param1);
-			state = State::AwaitingWrites;
-			continue;
-		}
-
-		if([type isEqualToString:@"bltaptl"]) {
-			blitter.set_pointer<0, 0>(param1);
-			state = State::AwaitingWrites;
-			continue;
-		}
-		if([type isEqualToString:@"bltbptl"]) {
-			blitter.set_pointer<1, 0>(param1);
-			state = State::AwaitingWrites;
-			continue;
-		}
-		if([type isEqualToString:@"bltcptl"]) {
-			blitter.set_pointer<2, 0>(param1);
-			state = State::AwaitingWrites;
-			continue;
-		}
-		if([type isEqualToString:@"bltdptl"]) {
-			blitter.set_pointer<3, 0>(param1);
-			state = State::AwaitingWrites;
-			continue;
-		}
-
-		if([type isEqualToString:@"bltapth"]) {
-			blitter.set_pointer<0, 16>(param1);
-			state = State::AwaitingWrites;
-			continue;
-		}
-		if([type isEqualToString:@"bltbpth"]) {
-			blitter.set_pointer<1, 16>(param1);
-			state = State::AwaitingWrites;
-			continue;
-		}
-		if([type isEqualToString:@"bltcpth"]) {
-			blitter.set_pointer<2, 16>(param1);
-			state = State::AwaitingWrites;
-			continue;
-		}
-		if([type isEqualToString:@"bltdpth"]) {
-			blitter.set_pointer<3, 16>(param1);
-			state = State::AwaitingWrites;
+		if([type isEqualToString:@"write"]) {
+			writes.push_back(std::make_pair(uint32_t(param1), uint16_t([event[2] integerValue])));
+			state = State::LoggingWrites;
 			continue;
 		}
 
 		// Hackaround for testing my magical all-at-once Blitter is here.
-		if(state == State::AwaitingWrites) {
+		if(state == State::LoggingWrites) {
+			// Run for however much time the Blitter wants.
+			while(blitter.get_status()) {
+				blitter.advance();
+			}
+
 			for(const auto &write: writes) {
 				XCTAssertEqual(ram[write.first >> 1], write.second, @"Didn't find %04x at address %08x; found %04x instead", write.second, write.first, ram[write.first >> 1]);
 
 				// For now, indicate only the first failure.
 				if(ram[write.first >> 1] != write.second) {
-					break;
+					hasFailed = YES;
 				}
 			}
 			writes.clear();
-			state = State::LoggingWrites;
+			state = State::AwaitingWrites;
 		}
 		// Hack ends here.
 
-		if([type isEqualToString:@"cread"] || [type isEqualToString:@"bread"] || [type isEqualToString:@"aread"]) {
-			ram[param1 >> 1] = [event[2] integerValue];
+
+		if([type isEqualToString:@"bltcon0"]) {
+			blitter.set_control(0, param1);
+			continue;
+		}
+		if([type isEqualToString:@"bltcon1"]) {
+			blitter.set_control(1, param1);
 			continue;
 		}
 
-		if([type isEqualToString:@"write"]) {
-			writes.push_back(std::make_pair(uint32_t(param1), uint16_t([event[2] integerValue])));
+		if([type isEqualToString:@"bltsize"]) {
+			blitter.set_size(param1);
+			continue;
+		}
+
+		if([type isEqualToString:@"bltafwm"]) {
+			blitter.set_first_word_mask(param1);
+			continue;
+		}
+		if([type isEqualToString:@"bltalwm"]) {
+			blitter.set_last_word_mask(param1);
+			continue;
+		}
+
+		if([type isEqualToString:@"bltadat"]) {
+			blitter.set_data(0, param1);
+			continue;
+		}
+		if([type isEqualToString:@"bltbdat"]) {
+			blitter.set_data(1, param1);
+			continue;
+		}
+		if([type isEqualToString:@"bltcdat"]) {
+			blitter.set_data(2, param1);
+			continue;
+		}
+
+		if([type isEqualToString:@"bltamod"]) {
+			blitter.set_modulo(0, param1);
+			continue;
+		}
+		if([type isEqualToString:@"bltbmod"]) {
+			blitter.set_modulo(1, param1);
+			continue;
+		}
+		if([type isEqualToString:@"bltcmod"]) {
+			blitter.set_modulo(2, param1);
+			continue;
+		}
+		if([type isEqualToString:@"bltdmod"]) {
+			blitter.set_modulo(3, param1);
+			continue;
+		}
+
+		if([type isEqualToString:@"bltaptl"]) {
+			blitter.set_pointer<0, 0>(param1);
+			continue;
+		}
+		if([type isEqualToString:@"bltbptl"]) {
+			blitter.set_pointer<1, 0>(param1);
+			continue;
+		}
+		if([type isEqualToString:@"bltcptl"]) {
+			blitter.set_pointer<2, 0>(param1);
+			continue;
+		}
+		if([type isEqualToString:@"bltdptl"]) {
+			blitter.set_pointer<3, 0>(param1);
+			continue;
+		}
+
+		if([type isEqualToString:@"bltapth"]) {
+			blitter.set_pointer<0, 16>(param1);
+			continue;
+		}
+		if([type isEqualToString:@"bltbpth"]) {
+			blitter.set_pointer<1, 16>(param1);
+			continue;
+		}
+		if([type isEqualToString:@"bltcpth"]) {
+			blitter.set_pointer<2, 16>(param1);
+			continue;
+		}
+		if([type isEqualToString:@"bltdpth"]) {
+			blitter.set_pointer<3, 16>(param1);
 			continue;
 		}