31 #define SCREEN_HEIGHT (SCREEN_LAST_VISIBLE_SCANLINE - SCREEN_FIRST_VISIBLE_SCANLINE + 1)
32 #define SCREEN_WIDTH (SCREEN_LAST_VISIBLE_DOTPOS - SCREEN_FIRST_VISIBLE_DOTPOS + 1)
35 static const char *rom_fatal_msg =
"This is one of the selected ROMs. Without it, Xemu won't work.\nInstall it, or use -romXXX CLI switches to specify another path, see the -h output for help.";
39 static const Uint8 init_vic_palette_rgb[16 * 3] = {
57 static Uint8 dummy_vic_access[1024];
59 static char *emufile_p;
60 static int emufile_size;
62 static int nmi_level = 0;
65 static Uint8 is_kpage_writable[64] = {
81 static Uint8 *vic_address_space_hi4[16] = {
87 static Uint8 *vic_address_space_lo8[16] = {
89 dummy_vic_access, dummy_vic_access, dummy_vic_access, dummy_vic_access,
90 memory, dummy_vic_access, dummy_vic_access, dummy_vic_access,
106 #define VIRTUAL_SHIFT_POS 0x31
109 { SDL_SCANCODE_1, 0x00 },
110 { SDL_SCANCODE_3, 0x01 },
111 { SDL_SCANCODE_5, 0x02 },
112 { SDL_SCANCODE_7, 0x03 },
113 { SDL_SCANCODE_9, 0x04 },
116 { SDL_SCANCODE_BACKSPACE, 0x07 },
118 { SDL_SCANCODE_W, 0x11 },
119 { SDL_SCANCODE_R, 0x12 },
120 { SDL_SCANCODE_Y, 0x13 },
121 { SDL_SCANCODE_I, 0x14 },
122 { SDL_SCANCODE_P, 0x15 },
124 { SDL_SCANCODE_RETURN, 0x17 },
125 { SDL_SCANCODE_LCTRL, 0x20 },
126 { SDL_SCANCODE_A, 0x21 },
127 { SDL_SCANCODE_D, 0x22 },
128 { SDL_SCANCODE_G, 0x23 },
129 { SDL_SCANCODE_J, 0x24 },
130 { SDL_SCANCODE_L, 0x25 },
131 { SDL_SCANCODE_SEMICOLON, 0x26 },
132 { SDL_SCANCODE_RIGHT, 0x27 }, { SDL_SCANCODE_LEFT, 0x27 | 8 },
133 { SDL_SCANCODE_END, 0x30 },
134 { SDL_SCANCODE_LSHIFT, 0x31 },
135 { SDL_SCANCODE_X, 0x32 },
136 { SDL_SCANCODE_V, 0x33 },
137 { SDL_SCANCODE_N, 0x34 },
138 { SDL_SCANCODE_COMMA, 0x35 },
139 { SDL_SCANCODE_SLASH, 0x36 },
140 { SDL_SCANCODE_DOWN, 0x37 }, { SDL_SCANCODE_UP, 0x37 | 8 },
141 { SDL_SCANCODE_SPACE, 0x40 },
142 { SDL_SCANCODE_Z, 0x41 },
143 { SDL_SCANCODE_C, 0x42 },
144 { SDL_SCANCODE_B, 0x43 },
145 { SDL_SCANCODE_M, 0x44 },
146 { SDL_SCANCODE_PERIOD, 0x45 },
147 { SDL_SCANCODE_RSHIFT, 0x46 },
148 { SDL_SCANCODE_F1, 0x47 }, { SDL_SCANCODE_F2, 0x47 | 8 },
149 { SDL_SCANCODE_LALT, 0x50 }, { SDL_SCANCODE_RALT, 0x50 },
150 { SDL_SCANCODE_S, 0x51 },
151 { SDL_SCANCODE_F, 0x52 },
152 { SDL_SCANCODE_H, 0x53 },
153 { SDL_SCANCODE_K, 0x54 },
154 { SDL_SCANCODE_APOSTROPHE, 0x55 },
155 { SDL_SCANCODE_EQUALS, 0x56 },
156 { SDL_SCANCODE_F3, 0x57 }, { SDL_SCANCODE_F4, 0x57 | 8 },
157 { SDL_SCANCODE_Q, 0x60 },
158 { SDL_SCANCODE_E, 0x61 },
159 { SDL_SCANCODE_T, 0x62 },
160 { SDL_SCANCODE_U, 0x63 },
161 { SDL_SCANCODE_O, 0x64 },
164 { SDL_SCANCODE_F5, 0x67 }, { SDL_SCANCODE_F6, 0x67 | 8 },
165 { SDL_SCANCODE_2, 0x70 },
166 { SDL_SCANCODE_4, 0x71 },
167 { SDL_SCANCODE_6, 0x72 },
168 { SDL_SCANCODE_8, 0x73 },
169 { SDL_SCANCODE_0, 0x74 },
170 { SDL_SCANCODE_MINUS, 0x75 },
171 { SDL_SCANCODE_HOME, 0x76 },
172 { SDL_SCANCODE_F7, 0x77 }, { SDL_SCANCODE_F8, 0x77 | 8 },
183 static inline void __mark_ram (
int start_k,
int size_k )
185 printf(
"MEM: adding RAM $%04X-%04X" NL, start_k << 10, ((start_k + size_k) << 10) - 1);
187 is_kpage_writable[start_k++] = 1;
191 static char *vic20_get_memconfig_string (
void )
193 static char result[40];
194 sprintf(result,
"%c1 %c8 %c16 %c24 %c40",
195 is_kpage_writable[1] ?
'+' :
'-',
196 is_kpage_writable[8] ?
'+' :
'-',
197 is_kpage_writable[16] ?
'+' :
'-',
198 is_kpage_writable[24] ?
'+' :
'-',
199 is_kpage_writable[40] ?
'+' :
'-'
205 static void emuprint (
const char *str )
208 (
char*)memory + (memory[0xA017] | (memory[0xA018] << 8)),
209 memory[0xA019] | (memory[0xA01A] << 8),
216 #define EMUPRINTF(...) do { \
217 char __buffer_for_conv__[8192]; \
218 snprintf(__buffer_for_conv__, sizeof __buffer_for_conv__, __VA_ARGS__); \
219 emuprint(__buffer_for_conv__); \
224 static void execute_monitor_command (
void )
242 static Uint8 inject_prg (
void )
247 addr = emufile_p[0] | (emufile_p[1] << 8);
248 printf(
"LOAD: injecting program into the memory from $%04X" NL,
addr);
249 memcpy(memory +
addr, emufile_p + 2, emufile_size - 2);
253 addr += emufile_size - 2;
261 static int is_our_rom (
void )
263 if (memcmp(memory + 0xA00C,
"LGBXVIC20", 9))
275 if (is_our_rom() < 0)
276 FATAL(
"Unknown ROM/RAM code at $%04X caused trap!", cpu65.pc - 1);
279 cpu65.a = inject_prg();
280 EMUPRINTF(
"\rMONITOR: SYS %d\r", 0xA009);
283 EMUPRINTF(
"** XVIC20 MONITOR/LGB\rBM=$%04X-%04X S=$%04X\rEXP %s\r",
287 vic20_get_memconfig_string()
293 execute_monitor_command();
296 FATAL(
"Unknown CPU trap (%d) at $%04X", trap, cpu65.pc - 1);
307 ERROR_WINDOW(
"Unemulated NMOS 6502 opcode $%02X at PC=$%04X", cpu65.op, cpu65.pc - 1);
331 if ((
addr & 0xFF00) == 0x9000) {
335 if ((
addr & 0xFFF0) == 0x9110) {
339 if ((
addr & 0xFFF0) == 0x9120) {
371 if ((
addr & 0xFFF0) == 0x9000)
373 if ((
addr & 0xFFF0) == 0x9110)
375 if ((
addr & 0xFFF0) == 0x9120)
377 if ((
addr & 0xFC00) == 0x9400)
392 static void update_emulator (
void )
410 static void via1_setint (
int level )
412 if (nmi_level != level) {
413 printf(
"VIA-1: NMI edge: %d->%d" NL, nmi_level, level);
421 static void via2_setint (
int level )
423 cpu65.irqLevel = level;
467 static void emulation_loop (
void )
493 int main (
int argc,
char **argv )
497 {
"bootmon",
"Boot into monitor", &
configdb.bootmon },
499 {
"syscon",
"Keep system console open (Windows-specific effect only)", &
configdb.
syscon }
503 {
"ramexp", NULL,
"Comma separated list of installed RAM expansions at Kbyte(s)", &
configdb.ramexp },
515 "INFO: CPU clock frequency (calculated) %d Hz (wanted: %d Hz)" NL
516 "INFO: Texture resolution is %dx%d" NL
517 "INFO: Defined visible area is (%d,%d)-(%d,%d)" NL NL,
533 init_vic_palette_rgb,
548 if (emufile_size < 0) {
558 FATAL(
"Invalid memory expansion list (not comma separated list, more than 5 elements, etc) syntax given with -ramexp");
561 switch (explist[
r]) {
576 INFO_WINDOW(
"Warning, RAM from 40K (at $A000) is defined.\nThis may collide with the loaded EMU ROM there!");
579 FATAL(
"Unknown memory expansion element %d in -ramexp %s", explist[
r],
configdb.ramexp);
585 memset(dummy_vic_access, 0xFF,
sizeof dummy_vic_access);
594 if (is_our_rom() < -1) {
626 vic_init(vic_address_space_lo8, vic_address_space_hi4);