Xemu [doxygen]  hyppo 0a42be3a057156924bc1b626a687bd6e27349c45 @ Sat 19 Mar 02:15:11 CET 2022
commander_x16.c
Go to the documentation of this file.
1 /* Part of the Xemu project, please visit: https://github.com/lgblgblgb/xemu
2  Copyright (C)2016-2021 LGB (Gábor Lénárt) <lgblgblgb@gmail.com>
3 
4  This is the Commander X16 emulation. Note: the source is overcrowded with comments by intent :)
5  That it can useful for other people as well, or someone wants to contribute, etc ...
6 
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11 
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
20 
21 #include "xemu/emutools.h"
22 #include "xemu/emutools_files.h"
23 #include "xemu/emutools_hid.h"
24 #include "xemu/emutools_config.h"
25 #include "commander_x16.h"
26 #include "xemu/cpu65.h"
27 #include "xemu/via65c22.h"
28 #include "vera.h"
29 #include "input_devices.h"
30 
31 
32 //#define IODEBUGPRINT DEBUGPRINT
33 #define IODEBUGPRINT DEBUG
34 //#define IODEBUGPRINT(...)
35 
36 #define SCREEN_WIDTH 640
37 #define SCREEN_HEIGHT 480
38 
39 
40 // TODO: kill these
41 //#define LAST_SCANLINE 325
42 #define CYCLES_PER_SCANLINE 254
43 
44 static Uint8 lo_ram[0x9F00];
45 static Uint8 hi_ram[256 * 8192]; // 2M
46 static Uint8 rom[0x20000]; // 128K
47 static int hi_ram_banks;
48 static int hi_ram_access_offset;
49 static int hi_rom_access_offset;
50 
51 static int frameskip = 0;
52 static struct Via65c22 via1, via2; // VIA-1 and VIA-2 emulation structures
53 
54 
55 #define VIRTUAL_SHIFT_POS 0x31
56 
57 
58 static const struct KeyMappingDefault x16_key_map[] = {
60  // **** this must be the last line: end of mapping table ****
61  { 0, -1 }
62 };
63 
64 static struct {
67  char *rom;
68 } configdb;
69 
70 
71 
72 
73 
74 
75 // Called by CPU emulation code when any kind of memory byte must be written.
77 {
78  /**** 0000-9EFF: low RAM (fixed RAM) area ****/
79  if (addr < 0x9F00) {
80  lo_ram[addr] = data;
81  return;
82  }
83  /**** 9F00-9FFF: I/O area ****/
84  if (addr < 0xA000) {
85  switch ((addr >> 4) & 0xF) {
86  case 0x0:
87  case 0x1:
88  IODEBUGPRINT("IO_W: writing to reg $%04X (data=$%02X), audio controller @ PC=$%04X" NL, addr, data, cpu65.old_pc);
89  break;
90  case 0x2:
91  case 0x3:
92  IODEBUGPRINT("IO_W: writing to reg $%04X (data=$%02X), VERA video controller @ PC=$%04X" NL, addr, data, cpu65.old_pc);
93  vera_write_cpu_register(addr, data); // VERA masks the addr bits, so it's OK.
94  break;
95  case 0x6:
96  IODEBUGPRINT("IO_W: writing to reg $%04X (data=$%02X), VIA-1 @ PC=$%04X" NL, addr, data, cpu65.old_pc);
97  via_write(&via1, addr & 0xF, data);
98  break;
99  case 0x7:
100  IODEBUGPRINT("IO_W: writing to reg $%04X (data=$%02X), VIA-2 @ PC=$%04X" NL, addr, data, cpu65.old_pc);
101  via_write(&via2, addr & 0xF, data);
102  break;
103  case 0x8:
104  case 0x9:
105  IODEBUGPRINT("IO_W: writing to reg $%04X (data=$%02X), RTC @ PC=$%04X" NL, addr, data, cpu65.old_pc);
106  break;
107  default:
108  IODEBUGPRINT("IO_W: writing to reg $%04X (data=$%02X), UNKNOWN/RESERVED @ PC=$%04X" NL, addr, data, cpu65.old_pc);
109  break;
110  }
111  return;
112  }
113  /**** A000-BFFF: 8K pageable RAM area, "hi-RAM" ****/
114  if (XEMU_LIKELY(addr < 0xC000)) {
115  hi_ram[hi_ram_access_offset + addr - 0xA000] = data;
116  return;
117  }
118  // Others (ROM) can be ignored, since it's ROM (not writable anyway) ...
119 }
120 
121 
122 
123 
124 // Called by CPU emulation code when any kind of memory byte must be read.
126 {
127  /**** 0000-9EFF: low RAM (fixed RAM) area ****/
128  if (addr < 0x9F00)
129  return lo_ram[addr];
130  /**** 9F00-9FFF: I/O area ****/
131  if (addr < 0xA000) {
132  Uint8 data = 0xFF;
133  switch ((addr >> 4) & 0xF) {
134  case 0x0:
135  case 0x1:
136  IODEBUGPRINT("IO_R: reading from reg $%04X (data=$%02X), audio controller @ PC=$%04X" NL, addr, data, cpu65.old_pc);
137  break;
138  case 0x2:
139  case 0x3:
140  data = vera_read_cpu_register(addr); // VERA masks the addr bits, so it's OK
141  IODEBUGPRINT("IO_R: reading from reg $%04X (data=$%02X), VERA video controller @ PC=$%04X" NL, addr, data, cpu65.old_pc);
142  break;
143  case 0x6:
144  data = via_read(&via1, addr & 0xF);
145  IODEBUGPRINT("IO_R: reading from reg $%04X (data=$%02X), VIA-1 @ PC=$%04X" NL, addr, data, cpu65.old_pc);
146  break;
147  case 0x7:
148  data = via_read(&via2, addr & 0xF);
149  IODEBUGPRINT("IO_R: reading from reg $%04X (data=$%02X), VIA-2 @ PC=$%04X" NL, addr, data, cpu65.old_pc);
150  break;
151  case 0x8:
152  case 0x9:
153  IODEBUGPRINT("IO_R: reading from reg $%04X (data=$%02X), RTC @ PC=$%04X" NL, addr, data, cpu65.old_pc);
154  break;
155  default:
156  IODEBUGPRINT("IO_R: reading from reg $%04X (data=$%02X), UNKNOWN/RESERVED @ PC=$%04X" NL, addr, data, cpu65.old_pc);
157  break;
158  }
159  return data;
160  }
161  /**** A000-BFFF: 8K pageable RAM area, "hi-RAM" ****/
162  if (addr < 0xC000)
163  return hi_ram[hi_ram_access_offset + addr - 0xA000];
164  /**** C000-FFFF: the rest, 16K pagable ROM area ****/
165  return rom[hi_rom_access_offset + addr - 0xC000];
166 }
167 
168 
169 static XEMU_INLINE void set_rom_bank ( Uint8 bank )
170 {
171  bank &= 7;
172  hi_rom_access_offset = bank << 14;
173  //DEBUGPRINT("HI-ROM access offset set to $%05X, BANK=%d @ PC=$%04X" NL, hi_rom_access_offset, bank, cpu65.old_pc);
174 }
175 
176 static XEMU_INLINE void set_ram_bank ( Uint8 bank )
177 {
178  hi_ram_access_offset = (bank % hi_ram_banks) << 13;
179  //DEBUGPRINT("HI-RAM access offset set to $%06X, BANK=%d @ PC=$%04X" NL, hi_ram_access_offset, bank, cpu65.old_pc);
180 }
181 
182 
183 
184 static int load_rom ( const char *fn )
185 {
186  if (xemu_load_file(fn, rom, sizeof rom, sizeof rom, "Cannot load ROM") != sizeof rom)
187  return 1;
188  set_rom_bank(0);
189  return 0;
190 }
191 
192 
193 static void init_ram ( int hi_ram_size )
194 {
195  if (hi_ram_size > 2048)
196  hi_ram_size = 2048;
197  if (hi_ram_size < 0)
198  hi_ram_size = 0;
199  hi_ram_banks = hi_ram_size >> 3;
200  DEBUGPRINT("Setting (hi-)RAM size memtop to %dK, %d banks." NL, hi_ram_size, hi_ram_banks);
201  memset(lo_ram, 0, sizeof lo_ram);
202  memset(hi_ram, 0xFF, sizeof hi_ram);
203  set_ram_bank(0xFF);
204 }
205 
206 
207 
208 /* VIA emulation callbacks, called by VIA core. See main() near to via_init() calls for further information */
209 
210 static void via1_outa_ram_bank ( Uint8 mask, Uint8 data )
211 {
212  //DEBUGPRINT("VIA OUTA (RAM BANK) SET mask=%d data=%d" NL, (int)mask, (int)data);
213  set_ram_bank(data);
214 }
215 
216 static Uint8 via1_ina_ram_bank ( Uint8 mask )
217 {
218  //DEBUGPRINT("READING VIA1-A (RAM BANK): $%02X" NL, via1.ORA);
219  return via1.ORA;
220 }
221 
222 static void via1_outb_rom_bank ( Uint8 mask, Uint8 data )
223 {
224  //DEBUGPRINT("VIA OUTB (ROM BANK) SET mask=%d data=%d" NL, (int)mask, (int)data);
225  set_rom_bank(data);
226 }
227 
228 static Uint8 via1_inb_rom_bank ( Uint8 mask )
229 {
230  //DEBUGPRINT("READING VIA1-B (ROM BANK): $%02X" NL, via1.ORB);
231  return via1.ORB;
232 }
233 
234 
235 
236 static void via1_setint ( int level )
237 {
238  if (level)
239  cpu65.irqLevel |= 0x100;
240  else
241  cpu65.irqLevel &= ~0x100;
242 }
243 
244 
245 static void via2_setint ( int level )
246 {
247  if (level)
248  cpu65.irqLevel |= 0x200;
249  else
250  cpu65.irqLevel &= ~0x200;
251 }
252 
253 
254 static Uint8 via2_ina ( Uint8 mask )
255 {
256  //DEBUGPRINT("READING VIA2-A, DDR mask is: $%02X output register is $%02X" NL, via2.DDRA, via2.ORA);
257  return read_ps2_port() | (0xFF - 3);
258 }
259 
260 
261 static void update_emulator ( void )
262 {
263  if (!frameskip) {
264  // First: update screen ...
266  // Second: we must handle SDL events waiting for us in the event queue ...
268  // Third: Sleep ... Please read emutools.c source about this madness ... 40000 is (PAL) microseconds for a full frame to be produced
270  }
271  //vic_vsync(!frameskip); // prepare for the next frame!
272 }
273 
274 
275 
276 static int cycles;
277 Uint64 all_virt_cycles = 0;
278 
279 
280 static void emulation_loop ( void )
281 {
282  for (;;) { // our emulation loop ...
283  int opcyc;
284  //printf("PC=%04X OPC=%02X\n", cpu65.pc, cpu65_read_callback(cpu65.pc));
285  opcyc = cpu65_step(); // execute one opcode (or accept IRQ, etc), return value is the used clock cycles
286  via_tick(&via1, opcyc); // run VIA-1 tasks for the same amount of cycles as the CPU
287  via_tick(&via2, opcyc); // -- "" -- the same for VIA-2
288  //opcyc <<= speed_shifter;
289  cycles += opcyc;
290  all_virt_cycles += opcyc; // FIXME: should be scaled for different CPU speeds, but then also CYCLES_PER_SECOND should be altered for the desired CPU speed!!!
291  if (cycles >= CYCLES_PER_SCANLINE) {
292  if (!frameskip) {
293  }
294  if (vera_render_line() == 0) { // start of a new frame that is ...
295  update_emulator();
296  //vera_vsync();
297  frameskip = !frameskip;
298  return;
299  }
300  cycles -= CYCLES_PER_SCANLINE;
301  }
302  }
303 }
304 
305 
306 
307 int dump_stuff ( const char *fn, void *mem, int size )
308 {
309  DEBUGPRINT("DUMPMEM: dumping %d bytes at %p into file %s" NL, size, mem, fn);
310  FILE *f = fopen(fn, "w");
311  if (f) {
312  int r = fwrite(mem, size, 1, f) != 1;
313  fclose(f);
314  if (r) {
315  DEBUGPRINT("DUMPMEM: cannot write file" NL);
316  unlink(fn);
317  }
318  return r;
319  }
320  DEBUGPRINT("DUMPMEM: cannot create file" NL);
321  return 1;
322 }
323 
324 
325 static void emulator_shutdown ( void )
326 {
327  if (configdb.dumpmem) {
328  vera_dump_vram("vram.dump");
329  dump_stuff("loram.dump", lo_ram, sizeof lo_ram);
330  if (hi_ram_banks)
331  dump_stuff("hiram.dump", hi_ram, hi_ram_banks << 13);
332  }
333 }
334 
335 
336 int main ( int argc, char **argv )
337 {
338  xemu_pre_init(APP_ORG, TARGET_NAME, "The Surprising Commander X16 emulator from LGB");
339  xemucfg_define_switch_option("fullscreen", "Start in fullscreen mode", &configdb.fullscreen);
340  xemucfg_define_str_option("rom", ROM_NAME, "Sets character ROM to use", &configdb.rom);
341  xemucfg_define_num_option("hiramsize", 2048, "Size of high-RAM in Kbytes", &configdb.hiramsize, 0, 2048);
342  xemucfg_define_num_option("clock", 8, "CPU frequency in MHz [1..8]", &configdb.clock, 1, 8);
343  xemucfg_define_switch_option("syscon", "Keep system console open (Windows-specific effect only)", &configdb.syscon);
344  xemucfg_define_switch_option("dumpmem", "Dump memory states on exit into files", &configdb.dumpmem);
345  xemucfg_define_num_option("sdlrenderquality", RENDER_SCALE_QUALITY, "Setting SDL hint for scaling method/quality on rendering (0, 1, 2)", &configdb.sdlrenderquality, 0, 2 );
346  if (xemucfg_parse_all(argc, argv))
347  return 1;
348  /* Initiailize SDL - note, it must be before loading ROMs, as it depends on path info from SDL! */
349  if (xemu_post_init(
350  TARGET_DESC APP_DESC_APPEND, // window title
351  1, // resizable window
352  SCREEN_WIDTH, SCREEN_HEIGHT, // texture sizes
353  SCREEN_WIDTH, SCREEN_HEIGHT, // logical size
354  SCREEN_WIDTH, SCREEN_HEIGHT, // window size
355  SCREEN_FORMAT, // pixel format
356  0, // we have 16 colours
357  NULL, // initialize palette from this constant array
358  NULL, // initialize palette into this stuff
359  configdb.sdlrenderquality, // render scaling quality
360  USE_LOCKED_TEXTURE, // 1 = locked texture access
361  emulator_shutdown // shutdown function
362  ))
363  return 1;
364  hid_init(
365  x16_key_map,
367  SDL_ENABLE // enable HID joy events
368  );
369  // --- memory initialization ---
370  init_ram(configdb.hiramsize);
371  memset(rom, 0, sizeof rom);
372  if (
373  load_rom(configdb.rom)
374  )
375  return 1;
376  // Continue with initializing ...
377  vera_init();
378  clear_emu_events(); // also resets the keyboard
379  cpu65_reset(); // reset CPU: it must be AFTER kernal is loaded at least, as reset also fetches the reset vector into PC ...
380  // Initiailize VIAs.
381  // Note: this is my unfinished VIA emulation skeleton, for my Commodore LCD emulator originally, ported from my JavaScript code :)
382  // it uses callback functions, which must be registered here, NULL values means unused functionality
383  via_init(&via1, "VIA-1",
384  via1_outa_ram_bank, // outa
385  via1_outb_rom_bank, // outb
386  NULL, // outsr
387  via1_ina_ram_bank, // ina
388  via1_inb_rom_bank, // inb
389  NULL, // insr
390  via1_setint
391  );
392  via_init(&via2, "VIA-2",
393  NULL, // outa [reg 1]
394  NULL, //via2_kbd_set_scan, // outb [reg 0], we wire port B as output to set keyboard scan, HOWEVER, we use ORB directly in get scan!
395  NULL, // outsr
396  via2_ina, // ina [reg 1], we wire port A as input to get the scan result, which was selected with port-A
397  NULL, //via2_inb,
398  NULL, // insr
399  via2_setint
400  );
401  // Without these, the first DDR register writes would cause problems, since not OR* (Output Register) is written first ...
402  //via1.ORA = 0xFF;
403  //via1.ORB = 0xFF;
404  //via2.ORA = 0xFF;
405  //via2.ORB = 0xFF;
406  cycles = 0;
408  if (!configdb.syscon)
409  sysconsole_close(NULL);
410  xemu_timekeeping_start(); // we must call this once, right before the start of the emulation
411  //vera_vsync();
412 #ifdef __EMSCRIPTEN__
413  // http://xemu-dist.lgb.hu/dist/x16/xemu-xcx16-sample.html?t=11
414  close(1);
415  close(2);
416 #endif
417  DEBUGPRINT("CPU: starting exection at $%04X" NL, cpu65.pc);
418  XEMU_MAIN_LOOP(emulation_loop, 30, 1);
419  return 0;
420 }
xemu_pre_init
void xemu_pre_init(const char *app_organization, const char *app_name, const char *slogan)
Definition: emutools.c:651
commander_x16.h
CYCLES_PER_SCANLINE
#define CYCLES_PER_SCANLINE
Definition: commander_x16.c:42
xemucfg_define_str_option
void xemucfg_define_str_option(const char *optname, const char *defval, const char *help, char **storage)
hiramsize
int hiramsize
Definition: commander_x16.c:66
vera.h
USE_LOCKED_TEXTURE
#define USE_LOCKED_TEXTURE
Definition: commodore_65.h:26
via_tick
void via_tick(struct Via65c22 *via, int ticks)
Definition: via65c22.c:224
TARGET_DESC
#define TARGET_DESC
Definition: xemu-target.h:2
xemu_timekeeping_delay
void xemu_timekeeping_delay(int td_em)
Definition: emutools.c:405
emutools.h
sysconsole_close
void sysconsole_close(const char *waitmsg)
Definition: emutools.c:1393
dumpmem
int dumpmem
Definition: commander_x16.c:65
XEMU_MAIN_LOOP
#define XEMU_MAIN_LOOP(func, p1, p2)
Definition: emutools.h:58
configdb_st::clock
double clock
Definition: configdb.h:37
xemucfg_define_num_option
void xemucfg_define_num_option(const char *optname, const int defval, const char *help, int *storage, int min, int max)
xemu_update_screen
void xemu_update_screen(void)
Definition: emutools.c:1184
via65c22.h
configdb_st::rom
char * rom
Definition: configdb.h:32
vera_dump_vram
int vera_dump_vram(const char *fn)
Definition: vera.c:524
addr
int addr
Definition: dma65.c:81
vera_render_line
int vera_render_line(void)
Definition: vera.c:603
IODEBUGPRINT
#define IODEBUGPRINT
Definition: commander_x16.c:33
fn
const char * fn
Definition: roms.c:42
hid_handle_all_sdl_events
void hid_handle_all_sdl_events(void)
Definition: emutools_hid.c:613
xemucfg_parse_all
int xemucfg_parse_all(int argc, char **argv)
syscon
int syscon
Definition: commander_x16.c:65
cpu65_read_callback
Uint8 cpu65_read_callback(Uint16 addr)
Definition: commander_x16.c:125
XEMU_INLINE
#define XEMU_INLINE
Definition: emutools_basicdefs.h:126
m65-memcontent-generator.data
data
Definition: m65-memcontent-generator.py:119
read_ps2_port
int read_ps2_port(void)
Definition: input_devices.c:71
dump_stuff
int dump_stuff(const char *fn, void *mem, int size)
Definition: commander_x16.c:307
hid_init
void hid_init(const struct KeyMappingDefault *key_map_in, Uint8 virtual_shift_pos_in, int joy_enable)
Definition: emutools_hid.c:300
Via65c22
Definition: via65c22.h:21
Uint8
uint8_t Uint8
Definition: fat32.c:51
xemu_set_full_screen
void xemu_set_full_screen(int setting)
Definition: emutools.c:311
configdb_st::sdlrenderquality
int sdlrenderquality
Definition: configdb.h:35
TARGET_NAME
#define TARGET_NAME
Definition: xemu-target.h:1
emutools_files.h
APP_ORG
#define APP_ORG
Definition: emutools.h:50
STD_XEMU_SPECIAL_KEYS
#define STD_XEMU_SPECIAL_KEYS
Definition: emutools_hid.h:108
via_init
void via_init(struct Via65c22 *via, const char *name, void(*outa)(Uint8 mask, Uint8 data), void(*outb)(Uint8 mask, Uint8 data), void(*outsr)(Uint8 data), Uint8(*ina)(Uint8 mask), Uint8(*inb)(Uint8 mask), Uint8(*insr)(void), void(*setint)(int level))
Definition: via65c22.c:77
DEBUGPRINT
#define DEBUGPRINT(...)
Definition: emutools_basicdefs.h:171
SCREEN_HEIGHT
#define SCREEN_HEIGHT
Definition: commander_x16.c:37
ROM_NAME
#define ROM_NAME
Definition: commander_x16.h:32
input_devices.h
XEMU_LIKELY
#define XEMU_LIKELY(__x__)
Definition: emutools_basicdefs.h:124
vera_init
void vera_init(void)
Definition: vera.c:746
NL
#define NL
Definition: fat32.c:37
emutools_config.h
configdb
struct configdb_st configdb
Definition: configdb.c:34
compress_sd_image.r
def r
Definition: compress_sd_image.py:76
KeyMappingDefault
Definition: emutools_hid.h:24
xemu_post_init
int xemu_post_init(const char *window_title, int is_resizable, int texture_x_size, int texture_y_size, int logical_x_size, int logical_y_size, int win_x_size, int win_y_size, Uint32 pixel_format, int n_colours, const Uint8 *colours, Uint32 *store_palette, int render_scale_quality, int locked_texture_update, void(*shutdown_callback)(void))
Definition: emutools.c:908
xemu_load_file
int xemu_load_file(const char *filename, void *store_to, int min_size, int max_size, const char *cry)
Definition: emutools_files.c:674
cpu65.h
vera_read_cpu_register
Uint8 vera_read_cpu_register(int reg)
Definition: vera.c:490
clock
int clock
Definition: commander_x16.c:66
sdlrenderquality
int sdlrenderquality
Definition: commander_x16.c:65
xemu_timekeeping_start
void xemu_timekeeping_start(void)
Definition: emutools.c:1122
via_read
Uint8 via_read(struct Via65c22 *via, int addr)
Definition: via65c22.c:177
FULL_FRAME_USECS
#define FULL_FRAME_USECS
Definition: commodore_vic20.h:25
configdb_st::syscon
int syscon
Definition: configdb.h:34
size
int size
Definition: inject.c:37
clear_emu_events
void clear_emu_events(void)
Definition: commodore_65.c:193
cpu65_reset
void cpu65_reset(void)
Definition: cpu65.c:353
configdb_st::fullscreen
int fullscreen
Definition: configdb.h:34
SCREEN_FORMAT
#define SCREEN_FORMAT
Definition: commodore_65.h:25
cpu65_write_callback
void cpu65_write_callback(Uint16 addr, Uint8 data)
Definition: commander_x16.c:76
RENDER_SCALE_QUALITY
#define RENDER_SCALE_QUALITY
Definition: commodore_65.h:27
fullscreen
int fullscreen
Definition: commander_x16.c:65
VIRTUAL_SHIFT_POS
#define VIRTUAL_SHIFT_POS
Definition: commander_x16.c:55
mask
int mask
Definition: dma65.c:83
APP_DESC_APPEND
#define APP_DESC_APPEND
Definition: emutools.h:52
Uint16
uint16_t Uint16
Definition: fat32.c:50
emutools_hid.h
SCREEN_WIDTH
#define SCREEN_WIDTH
Definition: commander_x16.c:36
via_write
void via_write(struct Via65c22 *via, int addr, Uint8 data)
Definition: via65c22.c:99
all_virt_cycles
Uint64 all_virt_cycles
Definition: commander_x16.c:277
xemucfg_define_switch_option
void xemucfg_define_switch_option(const char *optname, const char *help, int *storage)
cpu65_step
int cpu65_step(void)
Definition: cpu65.c:796
configdb_st::dumpmem
char * dumpmem
Definition: configdb.h:32
main
int main(int argc, char **argv)
Definition: commander_x16.c:336
vera_write_cpu_register
void vera_write_cpu_register(int reg, Uint8 data)
Definition: vera.c:448
frameskip
int frameskip
Definition: vic3.c:75