/* * Recalculate the interrupt masks from scratch. * We could code special registry and deregistry versions of this function that * would be faster, but the code would be nastier, and we don't expect this to * happen very much anyway. */ void intr_calculatemasks(void) { int irq, level, unusedirqs; struct intrhand *q; /* First, figure out which levels each IRQ uses. */ unusedirqs = 0xffff; for (irq = 0; irq < ICU_LEN; irq++) { int levels = 0; for (q = intrhand[irq]; q; q = q->ih_next) levels |= 1 << IPL(q->ih_level); intrlevel[irq] = levels; if (levels) unusedirqs &= ~(1 << irq); } /* Then figure out which IRQs use each level. */ for (level = 0; level < NIPL; level++) { int irqs = 0; for (irq = 0; irq < ICU_LEN; irq++) if (intrlevel[irq] & (1 << level)) irqs |= 1 << irq; imask[level] = irqs | unusedirqs; } /* * Initialize soft interrupt masks to block themselves. */ IMASK(IPL_SOFTAST) |= 1 << SIR_AST; IMASK(IPL_SOFTCLOCK) |= 1 << SIR_CLOCK; IMASK(IPL_SOFTNET) |= 1 << SIR_NET; IMASK(IPL_SOFTTTY) |= 1 << SIR_TTY; /* * Enforce a hierarchy that gives slow devices a better chance at not * dropping data. */ for (level = 0; level < NIPL - 1; level++) imask[level + 1] |= imask[level]; /* And eventually calculate the complete masks. */ for (irq = 0; irq < ICU_LEN; irq++) { int irqs = 1 << irq; int minlevel = IPL_NONE; int maxlevel = IPL_NONE; if (intrhand[irq] == NULL) { maxlevel = IPL_HIGH; irqs = IMASK(IPL_HIGH); } else { for (q = intrhand[irq]; q; q = q->ih_next) { irqs |= IMASK(q->ih_level); if (minlevel == IPL_NONE || q->ih_level < minlevel) minlevel = q->ih_level; if (q->ih_level > maxlevel) maxlevel = q->ih_level; } } if (irqs != IMASK(maxlevel)) panic("irq %d level %x mask mismatch: %x vs %x", irq, maxlevel, irqs, IMASK(maxlevel)); intrmask[irq] = irqs; iminlevel[irq] = minlevel; imaxlevel[irq] = maxlevel; #if 0 printf("irq %d: level %x, mask 0x%x (%x)\n", irq, imaxlevel[irq], intrmask[irq], IMASK(imaxlevel[irq])); #endif } /* Lastly, determine which IRQs are actually in use. */ { int irqs = 0; for (irq = 0; irq < ICU_LEN; irq++) if (intrhand[irq]) irqs |= 1 << irq; if (irqs >= 0x100) /* any IRQs >= 8 in use */ irqs |= 1 << IRQ_SLAVE; imen = ~irqs; SET_ICUS(); } /* For speed of splx, provide the inverse of the interrupt masks. */ for (irq = 0; irq < ICU_LEN; irq++) iunmask[irq] = ~imask[irq]; }
int main() { int i,k,ipl_mode=1; //UINT r; // Initialize Disk I/F and ROM System_Initialize(); /* Event loop never exits. */ while (1){ // IPL if(ipl_mode==1){ // System Program Load IPL(); // Start MZ MZ_release(); ipl_mode=0; } // CMT Control if((z80_sts.status&S_CMT)==S_CMT){ z80_sts.status&=~S_CMT; // Eject and Set Tape if((IORD_8DIRECT(REG_BASE, MZ_CMT_STATUS)&C_OPEN)==C_OPEN){ IOWR_8DIRECT(REG_BASE, MZ_CMT_STATUS, C_OPEN); tape_unmount(); fname[0]='\0'; key0(settape); z80_sts.status|=S_FBTN; // Set Flag MZ_Brequest(); menu_process(); MZ_Brelease(); z80_sts.status&=~S_FBTN; // Clear Flag } // Load if((IORD_8DIRECT(REG_BASE, MZ_CMT_STATUS)&C_PLAY)==C_PLAY){ IOWR_8DIRECT(REG_BASE, MZ_CMT_STATUS, C_PLAY); IOWR_8DIRECT(REG_BASE, MZ_CMT_CTRL, C_MTON+C_TAPE); // Motor On cmtload(); } // Rewind if((IORD_8DIRECT(REG_BASE, MZ_CMT_STATUS)&C_REW)==C_REW){ if((IORD_8DIRECT(REG_BASE, MZ_CMT_STATUS)&C_APSS)==C_APSS){ apss_r(); } else { tape_rewind(); IOWR_8DIRECT(REG_BASE, MZ_CMT_STATUS, C_REW); } } // F.Forward if((IORD_8DIRECT(REG_BASE, MZ_CMT_STATUS)&C_FF)==C_FF){ if((IORD_8DIRECT(REG_BASE, MZ_CMT_STATUS)&C_APSS)==C_APSS){ apss_f(); } else { IOWR_8DIRECT(REG_BASE, MZ_CMT_STATUS, C_FF); } } } // Function Button if((z80_sts.status&S_FBTN)==S_FBTN){ MZ_Brequest(); menu_process(); MZ_Brelease(); z80_sts.status&=~S_FBTN; } // BST check if((IORD_8DIRECT(REG_BASE, MZ_SYS_STATUS)&S_BST)==S_BST){ ipl_mode=1; } // Quick Load/Save // if((z80_sts.status&0x02)==0x02){ // if(IORD(CMT_0_BASE, 3)==0x0f){ // CMD is Load // IOWR(CMT_0_BASE, 2, 0x80); // set STAT busy // Wait for confirm busy by Z80 // while(IORD(CMT_0_BASE, 3)!=0); // if(tname[0]=='\0'){ // if tape file is empty // z80_sts.status=0x03; // // Z80-Bus request // MZ_Brequest(); // key0(settape); // k=menu(0,0,0); // Root menu // // Z80-Bus release // MZ_Brelease(); // z80_sts.status=0x02; // if(k!=10){ // z80_sts.status=0; // IOWR(CMT_0_BASE, 2, 0xff); // set STAT error // continue; // } // //keybuf_clear(); // strcpy(tname, fname); // IOWR(CMT_0_BASE, 1, 1); // ql_pt=0; // } // quick_load(); // IOWR(CMT_0_BASE, 2, 0); // set STAT free // z80_sts.status&=0xfffffffd; // } // if(IORD(CMT_0_BASE, 3)==0xf0){ // CMD is Save // IOWR(CMT_0_BASE, 2, 0x80); // set STAT busy // // Wait for confirm busy by Z80 // while(IORD(CMT_0_BASE, 3)!=0); // if(tname[0]=='\0'){ // if tape file is empty // // Z80-Bus request // MZ_Brequest(); // i=input_file_name(); // // Z80-Bus release // MZ_Brelease(); // if(tname[0]=='\0'||i<0){ // z80_sts.status=0; // IOWR(CMT_0_BASE, 2, 0xff); // set STAT error // continue; // } // keybuf_clear(); // IOWR(CMT_0_BASE, 1, 1); // } // if(quick_save()!=FR_OK) // IOWR(CMT_0_BASE, 2, 0xff); // set STAT error // else // IOWR(CMT_0_BASE, 2, 0); // set STAT free // z80_sts.status&=0xfffffffd; // } // } } return 0; }