Xemu [doxygen]  hyppo 0a42be3a057156924bc1b626a687bd6e27349c45 @ Sat 19 Mar 02:15:11 CET 2022
vic4.h
Go to the documentation of this file.
1 /* A work-in-progess MEGA65 (Commodore 65 clone origins) emulator
2  Part of the Xemu project, please visit: https://github.com/lgblgblgb/xemu
3  Copyright (C)2016-2022 LGB (Gábor Lénárt) <lgblgblgb@gmail.com>
4  Copyright (C)2020-2022 Hernán Di Pietro <hernan.di.pietro@gmail.com>
5 
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10 
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
19 
20 #ifndef XEMU_MEGA65_VIC4_H_INCLUDED
21 #define XEMU_MEGA65_VIC4_H_INCLUDED
22 
23 #define VIC2_IOMODE 0
24 #define VIC3_IOMODE 1
25 #define VIC_BAD_IOMODE 2
26 #define VIC4_IOMODE 3
27 
28 // Horizontal sync frequencies (in Hertz) for NTSC and PAL video output of MEGA65. Must be float.
29 #define PAL_LINE_FREQ 31250.0
30 #define NTSC_LINE_FREQ 31468.5
31 // Frame times (in microseconds) for NTSC and PAL video output of MEGA65. Must be integer.
32 #define PAL_FRAME_TIME 20000
33 #define NTSC_FRAME_TIME ((int)(16683.35))
34 
35 // Output window is fixed at 800x600 to support MegaPHONE, PAL-MEGA65
36 // and NTSC_MEGA65 modes. Internally, the VIC-IV chip draws 800-pixel
37 // wide buffers and traverses up to 526/624 physical rasters, as we do here.
38 // The user can select a clipped borders view (called "normal borders") which shows
39 // the real visible resolution of PAL (720x576) or NSTC(720x480).
40 
41 #define TEXTURE_WIDTH 800
42 #define TEXTURE_HEIGHT 625
43 
44 #define PHYSICAL_RASTERS_DEFAULT PHYSICAL_RASTERS_NTSC
45 #define SCREEN_HEIGHT_VISIBLE_DEFAULT SCREEN_HEIGHT_VISIBLE_NTSC
46 #define SCREEN_HEIGHT_VISIBLE_NTSC 480
47 #define SCREEN_HEIGHT_VISIBLE_PAL 576
48 #define PHYSICAL_RASTERS_NTSC 526
49 #define PHYSICAL_RASTERS_PAL 624
50 #define FRAME_H_FRONT 0
51 #define RASTER_CORRECTION 3
52 #define VIC4_BLINK_INTERVAL 30
53 
54 // Register defines
55 //
56 // Ref:
57 // https://github.com/MEGA65/mega65-core/blob/138-hdmi-audio-27mhz/iomap.txt
58 // ----------------------------------------------------
59 // _Un suffix indicates upper n bits of register
60 
61 #define REG_EBM (vic_registers[0x11] & 0x40)
62 #define REG_MCM (vic_registers[0x16] & 0x10)
63 #define REG_BMM (vic_registers[0x11] & 0x20)
64 #define REG_SPRITE_ENABLE vic_registers[0x15]
65 #define REG_BORDER_COLOR (vic_registers[0x20] & vic_color_register_mask)
66 #define REG_SCREEN_COLOR (vic_registers[0x21] & vic_color_register_mask)
67 #define REG_MULTICOLOR_1 (vic_registers[0x22] & vic_color_register_mask)
68 #define REG_MULTICOLOR_2 (vic_registers[0x23] & vic_color_register_mask)
69 //#define REG_MULTICOLOR_3 (vic_registers[0x24] & vic_color_register_mask)
70 #define REG_H640 (vic_registers[0x31] & 128)
71 #define REG_V400 (vic_registers[0x31] & 8)
72 #define REG_VICIII_ATTRIBS (vic_registers[0x31] & 0x20)
73 #define REG_RSEL (vic_registers[0x11] & 8)
74 #define REG_CSEL (vic_registers[0x16] & 8)
75 #define REG_DISPLAYENABLE (vic_registers[0x11] & 0x10)
76 #define REG_VIC2_XSCROLL (vic_registers[0x16] & 7)
77 #define REG_VIC2_YSCROLL (vic_registers[0x11] & 7)
78 //#define REG_CRAM2K (vic_registers[0x30] & 1)
79 #define REG_TBRDPOS (vic_registers[0x48])
80 #define REG_SPRBPMEN_0_3 (vic_registers[0x49] >> 4)
81 #define REG_SPRBPMEN_4_7 (vic_registers[0x4B] >> 4)
82 #define REG_TBRDPOS_U4 (vic_registers[0x49] & 0xF)
83 #define REG_BBRDPOS (vic_registers[0x4A])
84 #define REG_BBRDPOS_U4 (vic_registers[0x4B] & 0xF)
85 #define REG_TEXTXPOS (vic_registers[0x4C])
86 #define REG_TEXTXPOS_U4 (vic_registers[0x4D] & 0xF)
87 #define REG_SPRTILEN ((vic_registers[0x4D] >> 4) | (vic_registers[0x4F] & 0xF0))
88 #define REG_TEXTYPOS (vic_registers[0x4E])
89 #define REG_TEXTYPOS_U4 (vic_registers[0x4F] & 0xF)
90 //#define REG_XPOS (vic_registers[0x51])
91 //#define REG_XPOS_U6 (vic_registers[0x50] & 0x3F)
92 #define REG_FNRST (vic_registers[0x53] & 0x80)
93 #define REG_16BITCHARSET (vic_registers[0x54] & 1)
94 #define REG_FCLRLO (vic_registers[0x54] & 2)
95 #define REG_FCLRHI (vic_registers[0x54] & 4)
96 #define REG_SPR640 (vic_registers[0x54] & 0x10)
97 #define REG_SPRHGHT (vic_registers[0x56])
98 //#define REG_CHRXSCL (vic_registers[0x5A])
99 #define REG_CHRYSCL (vic_registers[0x5B])
100 #define REG_SIDBDRWD (vic_registers[0x5C])
101 #define REG_SIDBDRWD_U5 (vic_registers[0x5D] & 0x3F)
102 #define REG_HOTREG (vic_registers[0x5D] & 0x80)
103 #define REG_LINESTEP vic_registers[0x58]
104 #define REG_LINESTEP_U8 vic_registers[0x59]
105 #define REG_CHARXSCALE vic_registers[0x5A]
106 #define REG_CHRCOUNT vic_registers[0x5E]
107 #define REG_SCRNPTR_B0 vic_registers[0x60]
108 #define REG_SCRNPTR_B1 vic_registers[0x61]
109 #define REG_SCRNPTR_B2 vic_registers[0x62]
110 #define REG_SCRNPTR_B3 (vic_registers[0x63] & 0xF)
111 #define REG_COLPTR vic_registers[0x64]
112 #define REG_COLPTR_MSB vic_registers[0x65]
113 #define REG_CHARPTR_B0 vic_registers[0x68]
114 #define REG_CHARPTR_B1 vic_registers[0x69]
115 #define REG_CHARPTR_B2 vic_registers[0x6A]
116 #define REG_SPRPTR_B0 vic_registers[0x6C]
117 #define REG_SPRPTR_B1 vic_registers[0x6D]
118 #define REG_SPRPTR_B2 (vic_registers[0x6E] & 0x7F)
119 #define REG_SPRITE_Y_ADJUST vic_registers[0x72]
120 //#define REG_SCREEN_ROWS vic_registers[0x7B]
121 //#define REG_PAL_RED_BASE (vic_registers[0x100])
122 //#define REG_PAL_GREEN_BASE (vic_registers[0x200])
123 //#define REG_PAL_BLUE_BASE (vic_registers[0x300])
124 
125 // Helper macros for accessing multi-byte registers
126 // and other similar functionality for convenience
127 
128 //#define PHYS_RASTER_COUNT (videostd_id ? NTSC_PHYSICAL_RASTERS : PAL_PHYSICAL_RASTERS)
129 #define SINGLE_SIDE_BORDER (((Uint16)REG_SIDBDRWD) | (REG_SIDBDRWD_U5) << 8)
130 #define BORDER_Y_TOP (((Uint16)REG_TBRDPOS) | (REG_TBRDPOS_U4) << 8)
131 #define BORDER_Y_BOTTOM (((Uint16)REG_BBRDPOS) | (REG_BBRDPOS_U4) << 8)
132 #define CHARGEN_Y_START (((Uint16)REG_TEXTYPOS) | (REG_TEXTYPOS_U4) << 8)
133 #define CHARGEN_X_START (((Uint16)REG_TEXTXPOS) | (REG_TEXTXPOS_U4) << 8)
134 #define LINESTEP_BYTES (((Uint16)REG_LINESTEP) | (REG_LINESTEP_U8) << 8)
135 //#define SCREEN_RAM_ADDR_VIC (REG_SCREEN_ADDR * 1024)
136 #define SCREEN_ADDR ((Uint32)REG_SCRNPTR_B0 | (REG_SCRNPTR_B1<<8) | (REG_SCRNPTR_B2 <<16) | (REG_SCRNPTR_B3 << 24))
137 #define CHARSET_ADDR ((Uint32)REG_CHARPTR_B0 | (REG_CHARPTR_B1<<8) | (REG_CHARPTR_B2 <<16))
138 #define VIC2_BITMAP_ADDR ((CHARSET_ADDR) & 0xFFE000)
139 #define SPRITE_POINTER_ADDR ((Uint32)REG_SPRPTR_B0 | (REG_SPRPTR_B1<<8) | (REG_SPRPTR_B2 <<16))
140 #define COLOUR_RAM_OFFSET ((((Uint16)REG_COLPTR) | (REG_COLPTR_MSB) << 8))
141 //#define IS_NTSC_MODE (videostd_id)
142 //#define SCREEN_STEP (((Uint16)REG_LINESTEP) | (REG_LINESTEP_U8) << 8)
143 #define SPRITE_POS_Y(n) (((Uint16)vic_registers[1 + (n)*2]) | \
144  ( (vic_registers[0x77] & (1 << (n)) ? 0x100 : 0)) | \
145  ( (vic_registers[0x78] & (1 << (n)) ? 0x200 : 0)))
146 #define SPRITE_POS_X(n) (((Uint16)vic_registers[(n)*2]) | \
147  ( (vic_registers[0x10] & (1 << (n)) ? 0x100 : 0)) | \
148  ( (vic_registers[0x5f] & (1 << (n)) ? 0x200 : 0)))
149 #define SPRITE_COLOR(n) (vic_registers[0x27+(n)] & vic_color_register_mask)
150 #define SPRITE_COLOR_4BIT(n) (vic_registers[0x27+(n)] & 0xF)
151 #define SPRITE_MULTICOLOR_1 (vic_registers[0x25] & vic_color_register_mask)
152 #define SPRITE_MULTICOLOR_2 (vic_registers[0x26] & vic_color_register_mask)
153 #define SPRITE_IS_BACK(n) (vic_registers[0x1B] & (1 << (n)))
154 #define SPRITE_HORZ_2X(n) (vic_registers[0x1D] & (1 << (n)))
155 #define SPRITE_VERT_2X(n) (vic_registers[0x17] & (1 << (n)))
156 #define SPRITE_MULTICOLOR(n) (vic_registers[0x1C] & (1 << (n)))
157 #define SPRITE_16COLOR(n) (vic_registers[0x6B] & (1 << (n)))
158 #define SPRITE_EXTWIDTH(n) (SPRITE_16COLOR(n) | (vic_registers[0x57] & (1 << (n))))
159 #define SPRITE_EXTHEIGHT(n) (vic_registers[0x55] & (1 << (n)))
160 #define SPRITE_BITPLANE_ENABLE(n) (((REG_SPRBPMEN_4_7) << 4 | REG_SPRBPMEN_0_3) & (1 << (n)))
161 #define SPRITE_16BITPOINTER (vic_registers[0x6E] & 0x80)
162 #define SPRITE_V400(n) (vic_registers[0x76] & (1 << (n)))
163 //#define TEXT_MODE (!REG_BMM)
164 //#define HIRES_BITMAP_MODE (REG_BMM & !REG_MCM & !REG_EBM)
165 //#define MULTICOLOR_BITMAP_MODE (REG_BMM & REG_MCM & !REG_EBM)
166 #define VIC3_ATTR_BLINK(c) ((c) & 0x1)
167 #define VIC3_ATTR_REVERSE(c) ((c) & 0x2)
168 #define VIC3_ATTR_BOLD(c) ((c) & 0x4)
169 #define VIC3_ATTR_UNDERLINE(c) ((c) & 0x8)
170 #define CHAR_IS256_COLOR(ch) (REG_FCLRLO && (ch) < 0x100) || (REG_FCLRHI && (ch) > 0x0FF)
171 
172 // "Super-Extended character attributes" (see https://github.com/MEGA65/mega65-core/blob/master/docs/viciv-modes.md)
173 // cw is color-word (16-bit from Color RAM). sw is screen-ram-word (16bit from Screen RAM)
174 
175 #define SXA_TRIM_RIGHT_BITS012(sw) ((sw) >> 13)
176 #define SXA_VERTICAL_FLIP(cw) ((cw) & 0x8000)
177 #define SXA_HORIZONTAL_FLIP(cw) ((cw) & 0x4000)
178 //#define SXA_ALPHA_BLEND(cw) ((cw) & 0x2000)
179 #define SXA_GOTO_X(cw) ((cw) & 0x1000)
180 #define SXA_4BIT_PER_PIXEL(cw) ((cw) & 0x0800)
181 #define SXA_TRIM_RIGHT_BIT3(cw) ((cw) & 0x0400)
182 #define SXA_ATTR_BOLD(cw) ((cw) & 0x0040)
183 #define SXA_ATTR_REVERSE(cw) ((cw) & 0x0020)
184 //#define SXA_TRIM_TOP_BOTTOM(cw) (((cw) & 0x0300) >> 8)
185 
186 
187 // Multi-byte register write helpers
188 
189 #define SET_11BIT_REG(basereg,x) do { \
190  vic_registers[((basereg)+1)] = (Uint8) ((((Uint16)(x)) & 0x700) >> 8); \
191  vic_registers[(basereg)] = (Uint8) ((Uint16)(x)) & 0x00FF; \
192  } while(0)
193 #define SET_12BIT_REG(basereg,x) do { \
194  vic_registers[((basereg)+1)] = (Uint8) ((((Uint16)(x)) & 0xF00) >> 8); \
195  vic_registers[(basereg)] = (Uint8) ((Uint16)(x)) & 0x00FF; \
196  } while(0)
197 #define SET_14BIT_REG(basereg,x) do { \
198  vic_registers[((basereg)+1)] = (Uint8) ((((Uint16)(x)) & 0x3F00) >> 8); \
199  vic_registers[(basereg)] = (Uint8) ((Uint16)(x)) & 0x00FF; \
200  } while(0)
201 /* #define SET_14BIT_REGI(basereg,x) do { \
202  vic_registers[(basereg)] = (Uint8) ((((Uint16)(x)) & 0x3F00) >> 8); \
203  vic_registers[((basereg)+1)] = (Uint8) ((Uint16)(x)) & 0x00FF; \
204  } while(0) */
205 #define SET_16BIT_REG(basereg,x) do { \
206  vic_registers[((basereg) + 1)] = (Uint8) ((((Uint16)(x)) & 0xFF00) >> 8); \
207  vic_registers[(basereg)]= ((Uint16)(x)) & 0x00FF; \
208  } while(0)
209 
210 // 11-bit registers
211 
212 #define SET_PHYSICAL_RASTER(x) SET_11BIT_REG(0x52, (x))
213 //#define SET_RASTER_XPOS(x) SET_14BIT_REGI(0x50, (x))
214 
215 // 12-bit registers
216 
217 #define SET_BORDER_Y_TOP(x) SET_12BIT_REG(0x48, (x))
218 #define SET_BORDER_Y_BOTTOM(x) SET_12BIT_REG(0x4A, (x))
219 #define SET_CHARGEN_X_START(x) SET_12BIT_REG(0x4C, (x))
220 #define SET_CHARGEN_Y_START(x) SET_12BIT_REG(0x4E, (x))
221 
222 //16-bit registers
223 
224 #define SET_COLORRAM_BASE(x) SET_16BIT_REG(0x64,(x))
225 #define SET_LINESTEP_BYTES(x) SET_16BIT_REG(0x58,(x))
226 
227 // Base coordinates (from VICIV VHDL)
228 
229 #define SPRITE_FIRST_X 31
230 
231 // Current state
232 
233 extern int vic_iomode;
234 //extern int scanline;
235 extern Uint8 vic_registers[];
236 extern Uint8 c128_d030_reg;
237 
238 extern const char *videostd_name;
239 extern int videostd_frametime;
240 extern int videostd_changed;
241 extern Uint8 videostd_id;
243 extern int vic_readjust_sdl_viewport;
245 
247 
248 extern const char *iomode_names[4];
249 
250 extern void vic_init ( void );
251 extern void vic_reset ( void );
252 extern void vic_write_reg ( unsigned int addr, Uint8 data );
253 extern Uint8 vic_read_reg ( unsigned int addr );
254 extern int vic4_render_scanline ( void );
255 extern void vic4_open_frame_access ( void );
256 extern void vic4_close_frame_access (void );
257 
258 #ifdef XEMU_SNAPSHOT_SUPPORT
259 #include "xemu/emutools_snapshot.h"
260 extern int vic4_snapshot_load_state ( const struct xemu_snapshot_definition_st *def , struct xemu_snapshot_block_st *block );
261 extern int vic4_snapshot_save_state ( const struct xemu_snapshot_definition_st *def );
262 #endif
263 
264 #endif
vic4_open_frame_access
void vic4_open_frame_access(void)
Definition: vic4.c:373
iomode_names
const char * iomode_names[4]
Definition: vic4.c:37
c128_d030_reg
Uint8 c128_d030_reg
Definition: vic4.c:49
vic4_close_frame_access
void vic4_close_frame_access(void)
Definition: vic4.c:217
vic_read_reg
Uint8 vic_read_reg(unsigned int addr)
addr
int addr
Definition: dma65.c:81
vic_vidp_legacy
int vic_vidp_legacy
m65-memcontent-generator.data
data
Definition: m65-memcontent-generator.py:119
vic_registers
Uint8 vic_registers[]
Definition: vic4.c:43
Uint8
uint8_t Uint8
Definition: fat32.c:51
videostd_1mhz_cycles_per_scanline
float videostd_1mhz_cycles_per_scanline
Definition: vic4.c:85
block
Uint32 block
Definition: fat32.c:156
vic_reset
void vic_reset(void)
Definition: vic4.c:143
vic_sprp_legacy
int vic_sprp_legacy
Definition: vic4.h:246
vic_readjust_sdl_viewport
int vic_readjust_sdl_viewport
Definition: vic4.c:89
vic_write_reg
void vic_write_reg(unsigned int addr, Uint8 data)
Definition: vic4.c:539
videostd_frametime
int videostd_frametime
Definition: vic4.c:84
vic_chrp_legacy
int vic_chrp_legacy
Definition: vic4.h:246
videostd_id
Uint8 videostd_id
Definition: vic4.c:82
videostd_changed
int videostd_changed
Definition: vic4.c:86
vic_init
void vic_init(void)
Definition: vic4.c:173
vic4_render_scanline
int vic4_render_scanline(void)
Definition: vic4.c:1462
emutools_snapshot.h
videostd_name
const char * videostd_name
Definition: vic4.c:83
vic_iomode
int vic_iomode
Definition: vic4.c:44
vic4_disallow_video_std_change
int vic4_disallow_video_std_change
Definition: vic4.c:90