2 SHARP MZ-2500 Emulator 'EmuZ-2500'
4 Author : Takeda.Toshiya
10 #include "interrupt.h"
12 //#define SUPPURT_CHILD_DEVICE
14 void INTERRUPT::reset()
16 for(int ch = 0; ch < 4; ch++) {
17 irq[ch].enb_intr = false;
18 irq[ch].req_intr = false;
19 irq[ch].in_service = false;
26 void INTERRUPT::write_io8(uint32 addr, uint32 data)
30 irq[0].enb_intr = ((data & 8) != 0);
31 irq[1].enb_intr = ((data & 4) != 0);
32 irq[2].enb_intr = ((data & 2) != 0);
33 irq[3].enb_intr = ((data & 1) != 0);
39 irq[0].vector = data; // crtc
42 irq[1].vector = data; // i8253
45 irq[2].vector = data; // printer
48 irq[3].vector = data; // rp5c15
54 void INTERRUPT::write_signal(int id, uint32 data, uint32 mask)
56 if(id == SIG_INTERRUPT_CRTC) {
57 bool next = ((data & mask) != 0);
58 if(next != irq[0].req_intr) {
59 irq[0].req_intr = next;
62 } else if(id == SIG_INTERRUPT_I8253) {
63 bool next = ((data & mask) != 0);
64 if(next != irq[1].req_intr) {
65 irq[1].req_intr = next;
68 } else if(id == SIG_INTERRUPT_PRINTER) {
69 bool next = ((data & mask) != 0);
70 if(next != irq[2].req_intr) {
71 irq[2].req_intr = next;
74 } else if(id == SIG_INTERRUPT_RP5C15) {
75 bool next = ((data & mask) != 0);
76 if(next != irq[3].req_intr) {
77 irq[3].req_intr = next;
83 void INTERRUPT::set_intr_iei(bool val)
91 #define set_intr_oei(val) { \
95 d_child->set_intr_iei(oei); \
100 void INTERRUPT::update_intr()
102 #ifdef SUPPURT_CHILD_DEVICE
107 for(int ch = 0; ch < 4; ch++) {
108 if(irq[ch].in_service) {
119 for(int ch = 0; ch < 4; ch++) {
120 if(irq[ch].in_service) {
123 if(irq[ch].enb_intr && irq[ch].req_intr) {
129 if(req_intr_ch != -1) {
130 d_cpu->set_intr_line(true, true, intr_bit);
132 d_cpu->set_intr_line(false, true, intr_bit);
136 uint32 INTERRUPT::get_intr_ack()
139 if(req_intr_ch != -1) {
140 int ch = req_intr_ch;
141 irq[ch].req_intr = false;
142 irq[ch].in_service = true;
143 #ifdef SUPPURT_CHILD_DEVICE
146 return irq[ch].vector;
148 #ifdef SUPPURT_CHILD_DEVICE
150 return d_child->get_intr_ack();
156 void INTERRUPT::notify_intr_reti()
159 for(int ch = 0; ch < 4; ch++) {
160 if(irq[ch].in_service) {
161 irq[ch].in_service = false;
166 #ifdef SUPPURT_CHILD_DEVICE
168 d_child->notify_intr_reti();
173 #define STATE_VERSION 1
175 void INTERRUPT::save_state(FILEIO* state_fio)
177 state_fio->FputUint32(STATE_VERSION);
178 state_fio->FputInt32(this_device_id);
180 state_fio->FputUint8(select);
181 state_fio->Fwrite(irq, sizeof(irq), 1);
182 state_fio->FputInt32(req_intr_ch);
183 state_fio->FputBool(iei);
184 state_fio->FputBool(oei);
185 state_fio->FputUint32(intr_bit);
188 bool INTERRUPT::load_state(FILEIO* state_fio)
190 if(state_fio->FgetUint32() != STATE_VERSION) {
193 if(state_fio->FgetInt32() != this_device_id) {
196 select = state_fio->FgetUint8();
197 state_fio->Fread(irq, sizeof(irq), 1);
198 req_intr_ch = state_fio->FgetInt32();
199 iei = state_fio->FgetBool();
200 oei = state_fio->FgetBool();
201 intr_bit = state_fio->FgetUint32();