28 #define C64_BASIC_LOAD_ADDR 0x0801
29 #define C65_BASIC_LOAD_ADDR 0x2001
33 static void *inject_ready_userdata;
34 static void (*inject_ready_callback)(
void*);
42 static Uint8 *under_ready_p;
55 static void _cbm_screen_write (
Uint8 *p,
const char *s )
60 else if (*s >=
'a' && *s <=
'z')
62 else if (*s >=
'A' && *s <=
'Z')
71 #define CBM_SCREEN_PRINTF(scrp, ...) do { \
72 char __buffer__[80]; \
73 sprintf(__buffer__, ##__VA_ARGS__); \
74 _cbm_screen_write(scrp, __buffer__); \
78 static void prg_inject_callback (
void *unused )
80 DEBUGPRINT(
"INJECT: hit 'READY.' trigger, about to inject %d bytes from $%04X." NL,
prg.size,
prg.load_addr);
99 under_ready_p[get_screen_width()] = 0x20;
110 static void allow_disk_access_callback (
void *unused )
112 DEBUGPRINT(
"INJECT: re-enable disk access on READY. prompt" NL);
120 DEBUGPRINT(
"WARNING: INJECT: cannot register 'READY.' event, already having one in progress!" NL);
123 DEBUGPRINT(
"INJECT: registering 'READY.' event: %s" NL, debug_msg);
124 inject_ready_userdata = userdata;
125 inject_ready_callback = callback;
127 memset(
memory + 1024, 0, 1024 * 3);
143 prg.size =
xemu_load_file(prg_fn, NULL, 3, 0xFFFF,
"Cannot load PRG to be injected");
148 prg.load_addr =
prg.stream[0] + (
prg.stream[1] << 8);
150 memmove(
prg.stream,
prg.stream + 2,
prg.size);
152 if (
prg.load_addr +
prg.size > 0xFFFF) {
153 ERROR_WINDOW(
"Program to be injected is too large (%d bytes, load address: $%04X)\nFile: %s",
170 snprintf(msg,
sizeof msg,
"PRG to load: %s\nCannot detect C64/C65 mode for non-BASIC (load address: $%04X) PRG, please specify:", prg_fn,
prg.load_addr);
172 if (
prg.c64_mode != 0 &&
prg.c64_mode != 1)
189 DEBUGPRINT(
"INJECT: prepare for C6%c mode, %s program, $%04X load address, %d bytes from file: %s" NL,
190 prg.c64_mode ?
'4' :
'5',
191 prg.run_it ?
"BASIC (RUNable)" :
"ML (SYSable)",
212 static const Uint8 ready_msg[] = { 0x12, 0x05, 0x01, 0x04, 0x19, 0x2E };
215 static int is_ready_on_screen (
void )
217 int width = get_screen_width();
220 int start = (width == 80) ? 2048 : 1024;
223 for (
int i = 1; i < 23; i++) {
225 under_ready_p =
memory + start + i * width;
227 if (*under_ready_p == 0xA0 && !memcmp(under_ready_p - width, ready_msg,
sizeof ready_msg))
239 if (is_ready_on_screen())
245 int width = get_screen_width();
246 if (under_ready_p[width] == 0x00 || memcmp(under_ready_p - width, ready_msg,
sizeof ready_msg)) {
249 DEBUGPRINT(
"INJECT: clearing keyboard status on '@' trigger." NL);
253 inject_ready_callback(inject_ready_userdata);