Exemple #1
0
/*
 * 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;
}