Skip to content

Commit 05cca7c

Browse files
committed
MEGA65: fix raster IRQ in V400 mode #418
Raster interrupt position in V400 modes are bad. My idea back to then was wrong: raster IRQs (and reading back current raster) is in "physical rasters", so different in V200/V400 modes. However according to my tests on MEGA65, it seems, raster bars do not change position at all, while toggling between V400/V200 mode. So clearly they are measured in "VIC-II rasters" always, also called "logical raster". The same seems to apply to reading current raster as well, can be easily tested with the BASIC65 `VSYNC` command. Introduced in branch "next".
1 parent 1d2f6b0 commit 05cca7c

File tree

2 files changed

+30
-25
lines changed

2 files changed

+30
-25
lines changed

targets/mega65/vic4.c

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,16 @@ static const Uint8 reverse_byte_table[] = {
149149
};
150150

151151

152+
static inline void vic4_reset_display_counters ( void )
153+
{
154+
xcounter = 0;
155+
display_row = 0;
156+
char_row = 0;
157+
ycounter = 0;
158+
logical_raster = 0;
159+
}
160+
161+
152162
void vic_reset ( void )
153163
{
154164
vic_frame_counter = 0;
@@ -174,15 +184,8 @@ void vic_reset ( void )
174184
// turn off possible remained sprite collision info
175185
vic_registers[0x1E] = 0;
176186
vic_registers[0x1F] = 0;
177-
}
178-
179-
180-
static inline void vic4_reset_display_counters ( void )
181-
{
182-
xcounter = 0;
183-
display_row = 0;
184-
char_row = 0;
185-
ycounter = 0;
187+
vic4_reset_display_counters();
188+
SET_PHYSICAL_RASTER(0);
186189
}
187190

188191

@@ -513,7 +516,7 @@ static inline void check_raster_interrupt ( int nraster )
513516
interrupt_status |= 1;
514517
else
515518
interrupt_status &= 0xFE;
516-
interrupt_checker();
519+
// NOTE: previous versions used interrupt_checker() here. For reasons, I had to remove this, so calling check_raster_interrupt() does not do interrupt_checker() as its own anymore!!
517520
}
518521

519522

@@ -1581,21 +1584,14 @@ static XEMU_INLINE void vic4_render_char_raster ( void )
15811584
}
15821585

15831586

1584-
int vic4_render_scanline ( void )
1587+
bool vic4_render_scanline ( void )
15851588
{
15861589
// Work this first. DO NOT OPTIMIZE EARLY.
15871590

15881591
used_palette = palette; // may be overriden later by GOTOX token!
1589-
xcounter = 0;
15901592
current_pixel = pixel_start + ycounter * TEXTURE_WIDTH;
15911593
pixel_raster_start = current_pixel;
15921594

1593-
SET_PHYSICAL_RASTER(ycounter);
1594-
logical_raster = ycounter >> (EFFECTIVE_V400 ? 0 : 1);
1595-
1596-
// FIXME: this is probably a bad fix ... Trying to remedy that in V400, no raster interrupts seems to work ... XXX
1597-
if (!(ycounter & 1) || EFFECTIVE_V400) // VIC2 raster source: shall we check FNRST?
1598-
check_raster_interrupt(logical_raster);
15991595
// "Double-scan hack"
16001596
// FIXME: is this really correct? ie even sprites cannot be set to Y pos finer than V200 or ...
16011597
// ... having resolution finer than V200 with some "VIC4 magic"?
@@ -1652,23 +1648,32 @@ int vic4_render_scanline ( void )
16521648
interrupt_status |= 2;
16531649
else
16541650
interrupt_status &= 255 - 2;
1655-
// I don't call interrupt_checker() as it will be on the next call of the current function.
1656-
// That check then is part of function check_raster_interrupt. Yes a bit confusing and messy ... - LGB
16571651
}
16581652

16591653
ycounter++;
16601654
// End of frame?
1661-
if (ycounter == max_rasters) {
1662-
vic4_reset_display_counters();
1655+
bool end_of_frame = false;
1656+
if (XEMU_UNLIKELY(ycounter == max_rasters)) {
1657+
vic4_reset_display_counters(); // this will also set logical_raster and xcounter to zero
16631658
static int blink_frame_counter = 0;
16641659
blink_frame_counter++;
16651660
if (blink_frame_counter == VIC4_BLINK_INTERVAL) {
16661661
blink_frame_counter = 0;
16671662
blink_phase = !blink_phase;
16681663
}
1669-
return 1;
1664+
end_of_frame = true;
1665+
} else {
1666+
logical_raster = ycounter >> 1;
1667+
xcounter = 0;
16701668
}
1671-
return 0;
1669+
SET_PHYSICAL_RASTER(ycounter);
1670+
// VIC2 raster source: shall we check FNRST?
1671+
// This check was at the beginning of this function. The reason of the modification, that Xemu uses
1672+
// scanline based emulation, thus it's better this way as eg raster bars don't seem to be lagged by one raster this way.
1673+
if (!(ycounter & 1))
1674+
check_raster_interrupt(logical_raster);
1675+
interrupt_checker(); // manage possible IRQs (sprite collision, raster IRQ): was part of check_raster_interrupt(), now it's a separate stuff!
1676+
return end_of_frame;
16721677
}
16731678

16741679

targets/mega65/vic4.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ extern void vic_init ( void );
262262
extern void vic_reset ( void );
263263
extern void vic_write_reg ( unsigned int addr, Uint8 data );
264264
extern Uint8 vic_read_reg ( unsigned int addr );
265-
extern int vic4_render_scanline ( void );
265+
extern bool vic4_render_scanline ( void );
266266
extern void vic4_open_frame_access ( void );
267267
extern void vic4_close_frame_access ( void );
268268
extern void vic4_set_videostd ( const int mode, const char *comment );

0 commit comments

Comments
 (0)