1 |
|
/* |
2 |
|
* CPUC64_SC.cpp - Single-cycle 6510 (C64) emulation |
3 |
|
* |
4 |
< |
* Frodo (C) 1994-1997,2002-2003 Christian Bauer |
4 |
> |
* Frodo Copyright (C) Christian Bauer |
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 |
103 |
|
dfff_byte = 0x55; |
104 |
|
BALow = false; |
105 |
|
first_irq_cycle = first_nmi_cycle = 0; |
106 |
+ |
opflags = 0; |
107 |
|
} |
108 |
|
|
109 |
|
|
180 |
|
|
181 |
|
ddr = s->ddr; |
182 |
|
pr = s->pr; |
183 |
+ |
pr_out = 0; // FIXME: should be saved in MOS6510State |
184 |
|
new_config(); |
185 |
|
|
186 |
|
pc = s->pc; |
203 |
|
|
204 |
|
void MOS6510::new_config(void) |
205 |
|
{ |
206 |
< |
uint8 port = ~ddr | pr; |
206 |
> |
pr_out = (pr_out & ~ddr) | (pr & ddr); |
207 |
> |
uint8 port = pr | ~ddr; |
208 |
|
|
209 |
|
basic_in = (port & 3) == 3; |
210 |
|
kernal_in = port & 2; |
282 |
|
uint8 MOS6510::read_byte(uint16 adr) |
283 |
|
{ |
284 |
|
if (adr < 0xa000) { |
285 |
< |
if (adr >= 2) |
285 |
> |
if (adr >= 2) { |
286 |
|
return ram[adr]; |
287 |
< |
else if (adr == 0) |
287 |
> |
} else if (adr == 0) { |
288 |
|
return ddr; |
289 |
< |
else |
290 |
< |
return (ddr & pr) | (~ddr & 0x17); |
289 |
> |
} else { |
290 |
> |
uint8 byte = (pr | ~ddr) & (pr_out | 0x17); |
291 |
> |
if (!(ddr & 0x20)) |
292 |
> |
byte &= 0xdf; |
293 |
> |
return byte; |
294 |
> |
} |
295 |
|
} else |
296 |
|
return read_byte_io(adr); |
297 |
|
} |
301 |
|
* $dfa0-$dfff: Emulator identification |
302 |
|
*/ |
303 |
|
|
304 |
< |
const char frodo_id[0x5c] = "FRODO\r(C) 1994-1997 CHRISTIAN BAUER"; |
304 |
> |
const char frodo_id[0x5c] = "FRODO\r(C) CHRISTIAN BAUER"; |
305 |
|
|
306 |
|
uint8 MOS6510::read_emulator_id(uint16 adr) |
307 |
|
{ |
553 |
|
ram[0x8004] = 0; |
554 |
|
|
555 |
|
// Initialize extra 6510 registers and memory configuration |
556 |
< |
ddr = pr = 0; |
556 |
> |
ddr = pr = pr_out = 0; |
557 |
|
new_config(); |
558 |
|
|
559 |
|
// Clear all interrupt lines |
560 |
|
interrupt.intr_any = 0; |
561 |
|
nmi_state = false; |
562 |
+ |
opflags = 0; |
563 |
|
|
564 |
|
// Read reset vector |
565 |
|
pc = read_word(0xfffc); |
604 |
|
|
605 |
|
// Any pending interrupts in state 0 (opcode fetch)? |
606 |
|
if (!state && interrupt.intr_any) { |
607 |
< |
if (interrupt.intr[INT_RESET]) |
607 |
> |
if (interrupt.intr[INT_RESET]) { |
608 |
|
Reset(); |
609 |
< |
else if (interrupt.intr[INT_NMI] && (the_c64->CycleCounter-first_nmi_cycle >= 2)) { |
610 |
< |
interrupt.intr[INT_NMI] = false; // Simulate an edge-triggered input |
611 |
< |
state = 0x0010; |
612 |
< |
} else if ((interrupt.intr[INT_VICIRQ] || interrupt.intr[INT_CIAIRQ]) && (the_c64->CycleCounter-first_irq_cycle >= 2) && !i_flag) |
613 |
< |
state = 0x0008; |
609 |
> |
} else if (interrupt.intr[INT_NMI]) { |
610 |
> |
uint32 int_delay = (opflags & OPFLAG_INT_DELAYED) ? 1 : 0; // Taken branches to the same page delay the NMI |
611 |
> |
if (the_c64->CycleCounter - first_nmi_cycle - int_delay >= 2) { |
612 |
> |
interrupt.intr[INT_NMI] = false; // Simulate an edge-triggered input |
613 |
> |
state = 0x0010; |
614 |
> |
opflags = 0; |
615 |
> |
} |
616 |
> |
} else if ((interrupt.intr[INT_VICIRQ] || interrupt.intr[INT_CIAIRQ]) && |
617 |
> |
(!i_flag || (opflags & OPFLAG_IRQ_DISABLED)) && !(opflags & OPFLAG_IRQ_ENABLED)) { |
618 |
> |
uint32 int_delay = (opflags & OPFLAG_INT_DELAYED) ? 1 : 0; // Taken branches to the same page delay the IRQ |
619 |
> |
if (the_c64->CycleCounter - first_irq_cycle - int_delay >= 2) { |
620 |
> |
state = 0x0008; |
621 |
> |
opflags = 0; |
622 |
> |
} |
623 |
> |
} |
624 |
|
} |
625 |
|
|
626 |
|
#include "CPU_emulcycle.h" |
648 |
|
pc = 0xedac; |
649 |
|
Last; |
650 |
|
case 0x03: |
651 |
< |
ram[0x90] |= TheIEC->In(&a); |
651 |
> |
ram[0x90] |= TheIEC->In(a); |
652 |
|
set_nz(a); |
653 |
|
c_flag = false; |
654 |
|
pc = 0xedac; |