Skip to content

Commit 90db64d

Browse files
committed
MEGA65: preliminary VIC4 CHARY16 (TCR) impl. #424
CHARY16 (or TCR meaning Tall ChaRacter) is a (so far relatively unknown) mega65-core feature has become popular recently :) It works, by fetching glyph information shifted by 2048 at every second raster in V200 mode instead of the same. So it needs a special layout for the chargen info if the mode is enabled (bit 4 of $D07A): GS $D07A.4 VIC-IV:CHARY16 Alternate char ROM bank on alternate raster lines in V200 This is a bit problematic for Xemu, as it has an (otherwise not so correct) infrastructure that in V200 it renders only every second line and basically "clone" the previous one. This must be changed at some point for sure, but now, probably an ugly hack will be done, to take an exception of that rule if this mode is enabled. **THIS IS AN UGLY HACK** Probably the longer term solution would be to render all scanlines in all modes, this is already a problem in other contexts as well!
1 parent 9cc69c3 commit 90db64d

File tree

1 file changed

+19
-4
lines changed

1 file changed

+19
-4
lines changed

targets/mega65/vic4.c

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ static Uint8 sprite_is_being_rendered[8];
8383
#endif
8484
static Uint8 bug_compat_vic_iii_d016_delta = 2;
8585
static bool bug_compat_char_attr = true;
86+
static bool chary16 = false;
8687

8788
// --- these things are altered by vic4_open_frame_access() ONLY at every fame ONLY based on PAL or NTSC selection
8889
Uint8 videostd_id = 0xFF; // 0=PAL, 1=NTSC [give some insane value by default to force the change at the fist frame after starting Xemu]
@@ -186,6 +187,7 @@ void vic_reset ( void )
186187
vic_registers[0x1F] = 0;
187188
vic4_reset_display_counters();
188189
SET_PHYSICAL_RASTER(0);
190+
chary16 = false;
189191
}
190192

191193

@@ -1417,6 +1419,14 @@ static XEMU_INLINE void vic4_render_char_raster ( void )
14171419
enable_bg_paint = 1;
14181420
draw_mask = 0xFF; // initialize draw mask being $FF initially (glyph row is not masked out)
14191421
const Uint8 *row_data_base_addr = get_charset_effective_addr(); // FIXME: is it OK that I moved here, before the loop?
1422+
// CHARY16 feature - 16 pixel tall font in character mode
1423+
bool increment_row = true; // by default, every raster rendering needs to increment the character row counter
1424+
if (chary16) {
1425+
if ((ycounter & 1))
1426+
row_data_base_addr += 2048;
1427+
else
1428+
increment_row = false; // not incrementing the character row counter though when CHARY16 mode is active and we're in even numbered raster
1429+
}
14201430
// If this line is inside the vertical borders, mark all pixels as border color
14211431
if (ycounter < BORDER_Y_TOP || ycounter >= BORDER_Y_BOTTOM) {
14221432
for (int i = 0; i < TEXTURE_WIDTH; i++)
@@ -1573,9 +1583,11 @@ static XEMU_INLINE void vic4_render_char_raster ( void )
15731583
line_char_index++;
15741584
}
15751585
}
1576-
if (++char_row > 7) {
1577-
char_row = 0;
1578-
display_row++;
1586+
if (increment_row) { // in CHARY16 mode, I don't increment at every raster! See the beginning of this function
1587+
if (++char_row > 7) {
1588+
char_row = 0;
1589+
display_row++;
1590+
}
15791591
}
15801592
// Fill screen color after chargen phase
15811593
while (xcounter++ < border_x_right)
@@ -1591,10 +1603,13 @@ bool vic4_render_scanline ( void )
15911603
current_pixel = pixel_start + ycounter * TEXTURE_WIDTH;
15921604
pixel_raster_start = current_pixel;
15931605

1606+
// CHARY16 feature (only valid if it's SET and character mode is used at all and we're in V200 mode)
1607+
chary16 = (vic_registers[0x7A] & 0x10) && !(vic_registers[0x31] & 0x10) && !EFFECTIVE_V400;
1608+
15941609
// "Double-scan hack"
15951610
// FIXME: is this really correct? ie even sprites cannot be set to Y pos finer than V200 or ...
15961611
// ... having resolution finer than V200 with some "VIC4 magic"?
1597-
if (!EFFECTIVE_V400 && (ycounter & 1)) {
1612+
if (!EFFECTIVE_V400 && (ycounter & 1) && !chary16) {
15981613
if (XEMU_UNLIKELY(configdb.show_scanlines)) {
15991614
for (int i = 0; i < TEXTURE_WIDTH; i++, current_pixel++)
16001615
*current_pixel = ((*(current_pixel - TEXTURE_WIDTH) >> 1) & 0x7F7F7F7FU) | black_colour; // "| black_colour" is used to correct the messed-up alpha channel to $FF

0 commit comments

Comments
 (0)