@@ -111,7 +111,7 @@ fn opIllegalArithmetic(vx: u8, vy: u8) !ArithmeticOpcodeResult {
111
111
fn op00EX (self : Instruction , cpu : * Cpu ) ! ? u12 {
112
112
switch (self .opcode ) {
113
113
0x00E0 = > {
114
- cpu .display . setAll ( 0 );
114
+ @memset ( & cpu .display , 0 );
115
115
cpu .display_dirty = true ;
116
116
return null ;
117
117
},
@@ -131,10 +131,10 @@ test "00E0 clear screen" {
131
131
0x00 , 0xE0 ,
132
132
}, testing_seed , .{0 } ** 8 );
133
133
// fill screen
134
- cpu .display . setAll ( 1 );
134
+ @memset ( & cpu .display , 0xff );
135
135
try cpu .cycle ();
136
- for (0 .. cpu .display . len ) | i | {
137
- try std .testing .expectEqual (@as (u1 , 0 ), cpu . display . get ( i ) );
136
+ for (cpu .display ) | byte | {
137
+ try std .testing .expectEqual (@as (u8 , 0 ), byte );
138
138
}
139
139
try std .testing .expect (cpu .display_dirty );
140
140
}
@@ -639,6 +639,13 @@ test "CXNN random" {
639
639
try std .testing .expectEqual (@as (u8 , 0x00 ), cpu .V [0x0 ]);
640
640
}
641
641
642
+ export fn draw (ptr : ? * anyopaque , xReg : u8 , yReg : u8 , rows : u8 ) callconv (.C ) void {
643
+ const cpu : * Cpu = @alignCast (@ptrCast (ptr .? ));
644
+ const inst = Instruction .decode (0xd000 | (@as (u16 , xReg ) << 8 ) | (yReg << 4 ) | rows );
645
+ _ = inst .exec (cpu ) catch unreachable ;
646
+ cpu .pc +%= 2 ;
647
+ }
648
+
642
649
/// DXYN: draw an 8xN sprite from memory starting at I at (VX, VY); set VF to 1 if any pixel was
643
650
/// turned off, 0 otherwise
644
651
fn opDraw (self : Instruction , cpu : * Cpu ) ! ? u12 {
@@ -648,22 +655,19 @@ fn opDraw(self: Instruction, cpu: *Cpu) !?u12 {
648
655
const y_start = cpu .V [self .regY ] % Cpu .display_height ;
649
656
for (sprite , 0.. ) | row , y_sprite | {
650
657
for (0.. 8) | x_sprite | {
651
- const mask = @as ( u8 , 0b10000000 ) >> @as ( u3 , @ intCast (x_sprite ));
652
- const pixel = @intFromBool ( row & mask != 0 );
653
- const x = x_start + x_sprite ;
654
- const y = y_start + y_sprite ;
658
+ const pixel : u1 = @truncate ( row >> @intCast (7 - x_sprite ));
659
+
660
+ const x : u8 = @intCast ( x_start + x_sprite ) ;
661
+ const y : u8 = @intCast ( y_start + y_sprite ) ;
655
662
if (x >= Cpu .display_width or y >= Cpu .display_height ) {
656
663
continue ;
657
664
}
658
665
659
- const index = y * Cpu . display_width + x ;
660
- if ( pixel == 1 and cpu .display . get ( index ) == 1 ) {
661
- // pixel turned off
662
- cpu .V [ 0xF ] = 1 ;
666
+ if ( pixel == 1 ) {
667
+ if ( cpu .getPixel ( x , y ) == 1 ) cpu . V [ 0xF ] = 1 ;
668
+ cpu . invertPixel ( x , y );
669
+ cpu .display_dirty = true ;
663
670
}
664
- // draw using XOR
665
- cpu .display .set (index , @intFromBool (pixel != cpu .display .get (index )));
666
- cpu .display_dirty = cpu .display_dirty or pixel == 1 ;
667
671
}
668
672
}
669
673
return null ;
@@ -696,8 +700,7 @@ test "DXYN draw" {
696
700
for (sprites , 0.. ) | pixel , y | {
697
701
for (0.. 8) | x | {
698
702
const expected : u1 = @truncate (pixel >> @intCast (7 - x ));
699
- const actual_index = Cpu .display_width * (y + 17 ) + x + 8 ;
700
- try std .testing .expectEqual (expected , cpu .display .get (actual_index ));
703
+ try std .testing .expectEqual (expected , cpu .getPixel (@intCast (x + 8 ), @intCast (y + 17 )));
701
704
}
702
705
}
703
706
@@ -708,7 +711,7 @@ test "DXYN draw" {
708
711
try std .testing .expect (cpu .display_dirty );
709
712
// all off
710
713
for (0.. cpu .display .len ) | i | {
711
- try std .testing .expectEqual (@as (u1 , 0 ), cpu .display . get ( i ) );
714
+ try std .testing .expectEqual (@as (u8 , 0 ), cpu .display [ i ] );
712
715
}
713
716
}
714
717
@@ -965,7 +968,7 @@ test "FX55 store registers" {
965
968
/// FX65: load values from memory starting at I into registers [V0, VX]; set I to I + X + 1
966
969
fn opLoad (self : Instruction , cpu : * Cpu ) ! ? u12 {
967
970
for (0.. (@as (u8 , self .regX ) + 1 )) | offset | {
968
- cpu .V [offset ] = cpu .mem [cpu .I ];
971
+ cpu .V [offset ] = @as ([ * ] const u8 , @ptrCast ( & cpu .mem )) [cpu .I ];
969
972
cpu .I +%= 1 ;
970
973
}
971
974
return null ;
0 commit comments