32 #define CLOCKS_PER_FRAME (CPU_CLOCK / 50)
33 #define VIRTUAL_SHIFT_POS 0x63
41 static Uint8 io_port_values[0x100];
42 static int colour_mode;
43 static int keyboard_row;
44 static int interrupt_active;
61 0xFF , 0xFF , 0xFF , 0xFF , 0x7F , 0x1F ,
62 0x7F , 0x7F , 0xFF , 0x1F , 0x7F , 0x1F ,
63 0x3F , 0xFF , 0x3F , 0xFF , 0xFF , 0xFF
72 static Uint32 tvc_palette_rgb[16];
73 static Uint32 tvc_palette_bw [16];
75 static Uint32 palette_col16_pixel1[0x100];
76 static Uint32 palette_col16_pixel2[0x100];
77 static Uint32 border_colour;
93 return tvc_palette_rgb[(c & 1) | ((c >> 1) & 2) | ((c >> 2) & 4) | ((c >> 3) & 8)];
97 static void crtc_write_register (
int reg,
Uint8 data )
101 DEBUG(
"CRTC: register %02Xh is written with data %02Xh" NL, reg,
data);
102 crtc.registers[reg] =
data;
107 static Uint8 crtc_read_register (
int reg )
110 return crtc.registers[reg];
120 static Uint8 memcbrd_ram_u0 (
int addr ) {
return mem.user_ram[
addr ]; }
121 static Uint8 memcbrd_ram_u1 (
int addr ) {
return mem.user_ram[
addr + 0x4000]; }
122 static Uint8 memcbrd_ram_u2 (
int addr ) {
return mem.user_ram[
addr + 0x8000]; }
123 static Uint8 memcbrd_ram_u3 (
int addr ) {
return mem.user_ram[
addr + 0xC000]; }
125 static Uint8 memcbrd_ram_video (
int addr ) {
return mem.vmem[
addr]; }
126 static Uint8 memcbrd_rom_sys (
int addr ) {
return mem.sys_rom[
addr]; }
127 static Uint8 memcbrd_rom_ext (
int addr ) {
return mem.ext_rom[
addr]; }
130 #ifdef CONFIG_SDEXT_SUPPORT
131 #define memcbrd_rom_cart sdext_read_cart
132 #define memcbwr_rom_cart sdext_write_cart
134 static Uint8 memcbrd_rom_cart (
int addr ) {
return 0xFF; }
138 static const memcbrd_type memory_rd_selectors_for_page3[4] = { memcbrd_rom_cart, memcbrd_rom_sys, memcbrd_ram_u3, memcbrd_rom_ext };
139 static const memcbwr_type memory_wr_selectors_for_page3[4] = { memcbwr_rom_cart, memcbwr_nowrite, memcbwr_ram_u3, memcbwr_nowrite };
140 static const memcbrd_type memory_rd_selectors_for_page0[4] = { memcbrd_rom_sys, memcbrd_rom_cart, memcbrd_ram_u0, memcbrd_ram_u3 };
141 static const memcbwr_type memory_wr_selectors_for_page0[4] = { memcbwr_nowrite, memcbwr_rom_cart, memcbwr_ram_u0, memcbwr_ram_u3 };
147 return (mem.rd_selector[
addr >> 14])(
addr & 0x3FFF);
162 DEBUG(
"IO: reading I/O port %02Xh" NL, port16);
164 case 0x58:
case 0x5C:
165 DEBUG(
"Reading keyboard (row=%d, result=$%02X)!" NL, keyboard_row,
kbd_matrix[keyboard_row]);
166 return keyboard_row < 10 ?
kbd_matrix[keyboard_row] : 0xFF;
167 case 0x59:
case 0x5D:
168 return interrupt_active ? 0xEF: 0xFF;
172 return crtc_read_register(crtc.regsel);
182 io_port_values[port16] =
value;
184 DEBUG(
"IO: writing I/O port %02Xh with data %02Xh" NL, port16,
value);
187 border_colour = TVC_COLOUR_BYTE_TO_SDL(
value >> 1);
191 mem.rd_selector[3] = memory_rd_selectors_for_page3[
value >> 6];
192 mem.wr_selector[3] = memory_wr_selectors_for_page3[
value >> 6];
195 mem.rd_selector[2] = memcbrd_ram_u2;
196 mem.wr_selector[2] = memcbwr_ram_u2;
198 mem.rd_selector[2] = memcbrd_ram_video;
199 mem.wr_selector[2] = memcbwr_ram_video;
202 mem.rd_selector[0] = memory_rd_selectors_for_page0[(
value >> 3) & 3];
203 mem.wr_selector[0] = memory_wr_selectors_for_page0[(
value >> 3) & 3];
206 mem.rd_selector[1] = memcbrd_ram_u1;
207 mem.wr_selector[1] = memcbwr_ram_u1;
209 mem.rd_selector[1] = memcbrd_ram_video;
210 mem.wr_selector[1] = memcbwr_ram_video;
215 keyboard_row =
value & 0xF;
218 DEBUG(
"Enabled_SoundIT=%d Enabled_CursorIT=%d" NL,
value & 32 ? 1 : 0,
value & 16 ? 1 : 0);
221 colour_mode =
value & 3;
222 if (colour_mode == 3)
224 DEBUG(
"VIDEO: colour mode is %d" NL, colour_mode);
228 interrupt_active = 0;
230 case 0x0C:
case 0x0D:
case 0x0E:
case 0x0F:
231 crtc.vmem = mem.video_ram + ((
value & 0x30) << 10);
232 mem.vmem = mem.video_ram + ((
value & 0x03) << 14);
234 case 0x60:
case 0x61:
case 0x62:
case 0x63:
case 0x64:
case 0x65:
case 0x66:
case 0x67:
235 case 0x68:
case 0x69:
case 0x6A:
case 0x6B:
case 0x6C:
case 0x6D:
case 0x6E:
case 0x6F:
238 case 0x70:
case 0x72:
case 0x74:
case 0x76:
case 0x78:
case 0x7A:
case 0x7C:
case 0x7E:
239 crtc.regsel =
value & 31;
241 case 0x71:
case 0x73:
case 0x75:
case 0x77:
case 0x79:
case 0x7B:
case 0x7D:
case 0x7F:
242 crtc_write_register(crtc.regsel,
value);
270 static inline void render_tvc_screen (
void )
274 int ma = (crtc.registers[12] << 8) | crtc.registers[13];
276 int start_line, limit_line, start_cpos, limit_cpos;
280 start_line = (
SCREEN_HEIGHT - (crtc.registers[6] * (crtc.registers[9] + 1))) >> 1;
282 start_cpos = ((
SCREEN_WIDTH >> 3) - crtc.registers[1]) >> 1;
286 if (
y >= start_line &&
y < limit_line) {
287 int addr = (ma & 63) | (ra << 6) | ((ma & 0xFC0) << 2);
289 if (
x >= start_cpos &&
x < limit_cpos) {
291 switch (colour_mode) {
293 pix[0] =
palette[(b >> 7) & 1];
294 pix[1] =
palette[(b >> 6) & 1];
295 pix[2] =
palette[(b >> 5) & 1];
296 pix[3] =
palette[(b >> 4) & 1];
297 pix[4] =
palette[(b >> 3) & 1];
298 pix[5] =
palette[(b >> 2) & 1];
299 pix[6] =
palette[(b >> 1) & 1];
303 pix[0] = pix[1] =
palette[((b & 0x80) >> 7) | ((b & 0x08) >> 2)];
304 pix[2] = pix[3] =
palette[((b & 0x40) >> 6) | ((b & 0x04) >> 1)];
305 pix[4] = pix[5] =
palette[((b & 0x20) >> 5) | (b & 0x02) ];
306 pix[6] = pix[7] =
palette[((b & 0x10) >> 4) | ((b & 0x01) << 1)];
309 pix[0] = pix[1] = pix[2] = pix[3] = palette_col16_pixel1[b];
310 pix[4] = pix[5] = pix[6] = pix[7] = palette_col16_pixel2[b];
314 pix[0] = pix[1] = pix[2] = pix[3] = pix[4] = pix[5] = pix[6] = pix[7] = border_colour;
317 if (ra == crtc.registers[9]) {
319 ma += crtc.registers[1];
324 *pix++ = border_colour;
340 static void update_emulator (
void )
346 if (io_port_values[5] & 16) {
347 interrupt_active = 1;
359 static void init_tvc (
void )
363 for (a = 0; a < 16; a++) {
364 int red = (a & 2) ? ((a & 8) ? 0xFF : 0x80) : 0;
365 int green = (a & 4) ? ((a & 8) ? 0xFF : 0x80) : 0;
366 int blue = (a & 1) ? ((a & 8) ? 0xFF : 0x80) : 0;
367 int y = 0.299 * red + 0.587 * green + 0.114 * blue;
368 tvc_palette_rgb[a] = SDL_MapRGBA(
sdl_pix_fmt, red, green, blue, 0xFF);
377 for (a = 0; a < 256; a++) {
378 palette_col16_pixel1[a] = TVC_COLOUR_BYTE_TO_SDL(a >> 1);
379 palette_col16_pixel2[a] = TVC_COLOUR_BYTE_TO_SDL(a);
382 memset(&mem, 0xFF,
sizeof mem);
383 memset(&io_port_values, 0x00, 0x100);
384 memset(crtc.registers, 0x00,
sizeof crtc.registers);
385 for (a = 0; a < 0x100; a++)
387 for (a = 0; a <
sizeof crtc.registers; a++)
388 crtc_write_register(a, 0);
389 if (
xemu_load_file(
"#tvc22_d6_64k.rom", mem.sys_rom + 0x0000, 0x2000, 0x2000, NULL) < 0 ||
390 xemu_load_file(
"#tvc22_d4_64k.rom", mem.sys_rom + 0x2000, 0x2000, 0x2000, NULL) < 0 ||
391 xemu_load_file(
"#tvc22_d7_64k.rom", mem.ext_rom + 0x2000, 0x2000, 0x2000, NULL) < 0
393 FATAL(
"Cannot load ROM(s).");
394 #ifdef CONFIG_SDEXT_SUPPORT
404 static void emulation_loop (
void )
407 if (interrupt_active) {
425 int main (
int argc,
char **argv )
428 #ifdef CONFIG_SDEXT_SUPPORT
464 interrupt_active = 0;