void UPD765A::write_signal(int id, uint32 data, uint32 mask) { if(id == SIG_UPD765A_RESET) { bool next = ((data & mask) != 0); if(!reset_signal && next) { reset(); } reset_signal = next; } else if(id == SIG_UPD765A_TC) { #ifdef SDL // phase==PHASE_EXEC support (for Xanadu Scenario II) if(phase == PHASE_READ || phase == PHASE_WRITE || phase == PHASE_SCAN || (phase == PHASE_RESULT && count == 7) || (phase == PHASE_EXEC)) { #else if(phase == PHASE_READ || phase == PHASE_WRITE || phase == PHASE_SCAN || (phase == PHASE_RESULT && count == 7)) { #endif // SDL if(data & mask) { prevphase = phase; phase = PHASE_TC; process_cmd(command & 0x1f); } } } else if(id == SIG_UPD765A_MOTOR) { motor_on = ((data & mask) != 0); } else if(id == SIG_UPD765A_MOTOR_NEG) { motor_on = ((data & mask) == 0); #ifdef UPD765A_EXT_DRVSEL } else if(id == SIG_UPD765A_DRVSEL) { hdu = (hdu & 4) | (data & DRIVE_MASK); write_signals(&outputs_hdu, hdu); #endif } else if(id == SIG_UPD765A_IRQ_MASK) { if(!(irq_masked = ((data & mask) != 0))) { write_signals(&outputs_irq, 0); } } else if(id == SIG_UPD765A_DRQ_MASK) { if(!(drq_masked = ((data & mask) != 0))) { write_signals(&outputs_drq, 0); } } else if(id == SIG_UPD765A_FREADY) { // for NEC PC-98x1 series force_ready = ((data & mask) != 0); } } uint32 UPD765A::read_signal(int ch) { // get access status uint32 stat = 0; for(int i = 0; i < 4; i++) { if(fdc[i].access) { stat |= 1 << i; } fdc[i].access = false; } return stat; }
void UPD765A::set_drq(bool val) { #ifdef _FDC_DEBUG_LOG // emu->out_debug_log("FDC: DRQ=%d\n", val ? 1 : 0); #endif // cancel next drq and data lost events if(drq_id != -1) { cancel_event(this, drq_id); } if(lost_id != -1) { cancel_event(this, lost_id); } drq_id = lost_id = -1; // register data lost event if data exists if(val) { #ifdef UPD765A_DMA_MODE // EPSON QC-10 CP/M Plus dma_data_lost = true; #else if((command & 0x1f) != 0x0d) { #ifdef SDL // for customized event manager + 2HD disk register_event(this, EVENT_LOST, 30000, false, &lost_id); #else register_event(this, EVENT_LOST, disk[hdu & DRIVE_MASK]->get_usec_per_bytes(1), false, &lost_id); #endif // SDL } else { // FIXME: write id register_event(this, EVENT_LOST, 30000, false, &lost_id); } #endif } if(no_dma_mode) { write_signals(&outputs_irq, (val && !irq_masked) ? 0xffffffff : 0); } else { write_signals(&outputs_drq, (val && !drq_masked) ? 0xffffffff : 0); #ifdef UPD765A_DMA_MODE // EPSON QC-10 CP/M Plus if(val && dma_data_lost) { #ifdef _FDC_DEBUG_LOG emu->out_debug_log("FDC: DATA LOST (DMA)\n"); #endif result = ST1_OR; write_signals(&outputs_drq, 0); shift_to_result7(); } #endif } }
void MC6820::write_io8(uint32 addr, uint32 data) { int ch = (addr & 2) >> 1; switch(addr & 3) { case 0: case 2: if(port[ch].ctrl & 4) { if(port[ch].wreg != data || port[ch].first) { write_signals(&port[ch].outputs, data); port[ch].wreg = data; port[ch].first = false; } } else { port[ch].ddr = data; } break; case 1: case 3; if(data & 0x20) { port[ch].ctrl &= ~0x40; } port[ch].ctrl = (port[ch].ctrl & 0xc0) | (data & 0x3f); break; } }
void I8255::write_io8(uint32 addr, uint32 data) { int ch = addr & 3; switch(ch) { case 0: case 1: case 2: if(port[ch].wreg != data || port[ch].first) { write_signals(&port[ch].outputs, data); port[ch].wreg = data; port[ch].first = false; } break; case 3: if(data & 0x80) { port[0].rmask = (data & 0x10) ? 0xff : 0; port[0].mode = (data >> 5) & 3; port[1].rmask = (data & 2) ? 0xff : 0; port[1].mode = (data >> 2) & 1; port[2].rmask = ((data & 8) ? 0xf0 : 0) | ((data & 1) ? 0xf : 0); // clear ports if(clear_ports_by_cmdreg) { write_io8(0, 0); write_io8(1, 0); write_io8(2, 0); } } else {
void UPD765A::set_irq(bool val) { #ifdef _FDC_DEBUG_LOG // emu->out_debug_log("FDC: IRQ=%d\n", val ? 1 : 0); #endif write_signals(&outputs_irq, (val && !irq_masked) ? 0xffffffff : 0); }
void UPD765A::set_hdu(uint8 val) { #ifdef UPD765A_EXT_DRVSEL hdu = (hdu & 3) | (val & 4); #else hdu = val; #endif write_signals(&outputs_hdu, hdu); }
void MC6820::write_signal(int id, uint32 data, uint32 mask) { bool signal = ((data & mask) != 0); int ch = id & 1; switch(id) { case SIG_MC6820_PORT_A: case SIG_MC6820_PORT_B: port[ch].rreg = (port[ch].rreg & ~mask) | (data & mask); break; case SIG_MC6820_C1_A: case SIG_MC6820_C1_B: if(((port[ch].ctrl & 2) && !port[ch].c1 && signal) || (!(port[ch].ctrl & 2) && port[ch].c1 && !signal)) { if(port[ch].ctrl & 1) { write_signals(&port[ch].outputs_irq, 0xffffffff); } port[ch].ctrl |= 0x80; } port[ch].c1 = signal; break; case SIG_MC6820_C2_A: case SIG_MC6820_C2_B: if(port[ch].ctrl & 0x20) { // c2 is output break; } if(((port[ch].ctrl & 0x10) && !port[ch].c2 && signal) || (!(port[ch].ctrl & 0x10) && port[ch].c2 && !signal)) { if(port[ch].ctrl & 8) { write_signals(&port[ch].outputs_irq, 0xffffffff); } port[ch].ctrl |= 0x40; } port[ch].c2 = signal; break; } }
void UPD765A::event_callback(int event_id, int err) { #ifdef SDL request_single_exec(); #endif // SDL if(event_id == EVENT_PHASE) { phase_id = -1; phase = event_phase; process_cmd(command & 0x1f); } else if(event_id == EVENT_DRQ) { drq_id = -1; status |= S_RQM; int drv = hdu & DRIVE_MASK; fdc[drv].cur_position = (fdc[drv].cur_position + 1) % disk[drv]->get_track_size(); fdc[drv].prev_clock = prev_drq_clock = current_clock(); set_drq(true); } else if(event_id == EVENT_LOST) { #ifdef _FDC_DEBUG_LOG emu->out_debug_log("FDC: DATA LOST\n"); #endif lost_id = -1; result = ST1_OR; set_drq(false); shift_to_result7(); } else if(event_id == EVENT_RESULT7) { result7_id = -1; shift_to_result7_event(); } else if(event_id == EVENT_INDEX) { int drv = hdu & DRIVE_MASK; bool now_index = (disk[drv]->inserted && get_cur_position(drv) == 0); if(prev_index != now_index) { write_signals(&outputs_index, now_index ? 0xffffffff : 0); prev_index = now_index; } } else if(event_id >= EVENT_SEEK && event_id < EVENT_SEEK + 4) { int drv = event_id - EVENT_SEEK; seek_id[drv] = -1; seek_event(drv); } }
uint32 MC6820::read_io8(uint32 addr) { int ch = (addr & 2) >> 1; switch(addr & 3) { case 0: case 2: if(port[ch].ctrl & 4) { write_signals(&port[ch].outputs_irq, 0); port[ch].ctrl &= ~0xc0; return (port[ch].rreg & ~port[ch].ddr) | (port[ch].wreg & port[ch].ddr); } else { return port[ch].ddr; } case 1: case 3; return port[ch].ctrl; } return 0xff; }
static int write_header() { FILE *out = stil_out; if (out == 0) { return 1; } if (header_written == 1){ return 0; } int i; int e; if ( (e = arrange_pins( jtag_pins_inorder, jtag_pins, jtag_pin_count )) != 0 ) { return e; } if ( write_signals() ) { return 1; } else if ( write_signalGroups() ) { return 1; } if ( fprintf (out, "Pattern {\n") < 0 ) { close_delete_file(); return 1; } if ( fprintf (out, "\tW %s;\n", wft_name) < 0 ) { close_delete_file(); return 1; } header_written = 1; //Write whatever comment there is before writing the first vector //After writing the header. char *comment = (char *) dequeue_linklist(&initial_comments); while (comment) { writeComment(comment); comment = dequeue_linklist(&initial_comments); } return 0; }
void RP5C01::write_io8(uint32 addr, uint32 data) { addr &= 0x0f; if(addr <= 0x0c) { #ifndef HAS_RP5C15 switch(regs[0x0d] & 3) { #else switch(regs[0x0d] & 1) { #endif case 0: if(time[addr] != data) { time[addr] = data; write_to_cur_time(); } return; #ifndef HAS_RP5C15 case 2: ram[addr] = data; return; case 3: ram[addr + 13] = data; return; #endif } } uint8 tmp = regs[addr] ^ data; regs[addr] = data; if(addr == 0x0a) { if(tmp & 1) { // am/pm is changed read_from_cur_time(); } } else if(addr == 0x0f) { #ifndef HAS_RP5C15 switch(regs[0x0d] & 3) { #else switch(regs[0x0d] & 1) { #endif case 0: if(data & 3) { // timer reset } break; case 1: #ifndef HAS_RP5C15 case 2: case 3: #endif if(data & 2) { // timer reset } if(data & 1) { if(alarm) { alarm = false; update_pulse(); } } break; } } } uint32 RP5C01::read_io8(uint32 addr) { addr &= 0x0f; if(addr <= 0x0c) { #ifndef HAS_RP5C15 switch(regs[0x0d] & 3) { #else switch(regs[0x0d] & 1) { #endif case 0: return time[addr]; #ifndef HAS_RP5C15 case 2: return ram[addr]; case 3: return ram[addr + 13]; #endif } } if(addr == 0x0b) { for(int i = 0; i < 3; i++) { if(LEAP_YEAR(cur_time.year - i)) { return i; } } return 3; } return regs[addr]; } void RP5C01::event_callback(int event_id, int err) { if(event_id == EVENT_1SEC) { if(cur_time.initialized) { cur_time.increment(); } else { emu->get_host_time(&cur_time); // resync cur_time.initialized = true; } if(regs[0x0d] & 8) { read_from_cur_time(); if(regs[0x0d] & 4) { update_pulse(); } } } else if(event_id == EVENT_16HZ) { bool update = false; // 1Hz if(++count_16hz == 16) { pulse_1hz = !pulse_1hz; if(!(regs[0x0f] & 8)) { update = true; } count_16hz = 0; } // 16Hz pulse_16hz = !pulse_16hz; if(!(regs[0x0f] & 4)) { update = true; } if(update) { update_pulse(); } } // update signal } void RP5C01::update_pulse() { bool pulse = false; if(regs[0x0d] & 4) { pulse |= alarm; } if(!(regs[0x0f] & 8)) { pulse |= pulse_1hz; } if(!(regs[0x0f] & 4)) { pulse |= pulse_16hz; } write_signals(&outputs_pulse, pulse ? 0 : 0xffffffff); } #define MODE_12H !(regs[0x0a] & 1) void RP5C01::read_from_cur_time() { int hour = MODE_12H ? (cur_time.hour % 12) : cur_time.hour; int ampm = (MODE_12H && cur_time.hour >= 12) ? 2 : 0; time[ 0] = TO_BCD_LO(cur_time.second); time[ 1] = TO_BCD_HI(cur_time.second); time[ 2] = TO_BCD_LO(cur_time.minute); time[ 3] = TO_BCD_HI(cur_time.minute); time[ 4] = TO_BCD_LO(hour); time[ 5] = TO_BCD_HI(hour) | ampm; time[ 6] = cur_time.day_of_week; time[ 7] = TO_BCD_LO(cur_time.day); time[ 8] = TO_BCD_HI(cur_time.day); time[ 9] = TO_BCD_LO(cur_time.month); time[10] = TO_BCD_HI(cur_time.month); time[11] = TO_BCD_LO(cur_time.year); time[12] = TO_BCD_HI(cur_time.year); // check alarm static uint8 mask[9] = {0, 0, 0x0f, 0x07, 0x0f, 0x03, 0x07, 0x0f, 0x03}; bool tmp = true; for(int i = 3; i < 9; i++) { if((time[i] & mask[i]) != (regs[i] & mask[i])) { tmp = false; break; } } if(tmp) { alarm = true; } }
void LS244::write_io8(uint32_t addr, uint32_t data) { write_signals(&outputs, data); }