示例#1
0
文件: icycle2.c 项目: jepace/ecs151a
 icycle()
{
int op,a1,a2,x1,x2,i1,i2,setting,setmask,onemask,oldmask;
int 	ecd;		/* Error Code	*/	

	/*  setjmp(svstck) to save stack for return	*/
	/*  from possible segment and page faults	*/
	if((ecd=setjmp(svstck)) != 0) 
		{
		goto except;
		}

	ir = pm[cmap(pc)];
	pc++;
	/*  extract instruction fields into op, a1, a2;	*/
	/*  generate the eff. virtual addresses v1, v2	*/
	/*  using the algorithm in the Reference Manual	*/
	op = extract(ir,24,6);

	a1 = extract(ir,12,10);
	a2 = extract(ir,0,10);
	x1 = extract(ir,22,1);
	x2 = extract(ir,10,1);
	i1 = extract(ir,23,1);
	i2 = extract(ir,11,1);
	
 	v1 = a1;
	v2 = a2;	/*  address field forms initial value 	*/
	if (i1 == 1) v1 = pm[dmap(v1)];	/*  if indirection, get ind. loc */
	if (i2 == 1) v2 = pm[dmap(v2)];	
	if (x1 == 1) v1 = v1 + xr;	/*  if indexing specified, add xr */		
	if (x2 == 1) v2 = v2 + xr;

	

	switch(op)
	{
case 1:	gr = pm[dmap(v1)];		/*  gr load		*/
	break;
case 2: pm[dmap(v1)] = gr;		/*  gr store		*/
	break;
case 3: xr = pm[dmap(v1)];		/* xr load		*/
	break;
case 4: pm[dmap(v1)] = xr;		/* xr store		*/
	break;
case 5: sr = pm[dmap(v1)];		/* sr load		*/
	break;
case 6: pm[dmap(v1)] = sr;		/* sr store		*/
	break;
case 8: pm[dmap(v2)] = pm[dmap(v1)];	/* copy			*/
	break;
case 9: pm[dmap(v2)] += pm[dmap(v1)];	/* add			*/
	break;
case 10: pm[dmap(v2)] -= pm[dmap(v1)];	/* subtract		*/
	break;
case 11: pm[dmap(v2)] *= pm[dmap(v1)];	/* multiply		*/
	break;
case 12:				/* Divide		*/  
	if (pm[dmap(v1)] == 0)
		{
		ecd = ARITFLT;
		printf ("\nDivide Fault\n");
		goto except;
		}
        else 
		pm[dmap(v2)] /= pm[dmap(v1)];
        break;
case 13: pm[dmap(v2)] &= pm[dmap(v1)];	/* and			*/
	break;
case 14: pm[dmap(v2)] |= pm[dmap(v1)];	/* or			*/
	break;
case 16: pc = v1;			/* go to		*/
	break;
case 17: if (pm[dmap(v1)] != pm[dmap(v2)]) pc++;  /* if =	*/
	break;
case 18:  if (pm[dmap(v1)] == pm[dmap(v2)]) pc++; /* if !=	*/
	break;
case 19:  if (pm[dmap(v1)] >= pm[dmap(v2)]) pc++; /* if <	*/
	break;
case 20: if (pm[dmap(v1)] < pm[dmap(v2)]) pc++;	  /* if >=	*/
	break;
case 21: xr++;				/*  loop		*/
	 if (xr < pm[dmap(v1)]) pc = v2;
	break;
case 22: sr = pc;
	 pc = v1;			/* call			*/
	 break;
case 23:  pc = sr + pm[dmap(v1)];	/* return		*/
	 break;
case 26: xr = v1;			/* xr set		*/
	 break;
case 27: pm[dmap(v2)] = v1;		/* vm set		*/
	 break;
case 28: pm[dmap(v2)] = extract(pm[dmap(v1 + gr/4)],(gr%4)*8,8);	/* get byte	*/
	 break;
case 29:  setting =  extract(pm[dmap(v2)],0, 8); 	/* set byte */
	 /* Byte want to set in pos with 0s other */
	 setmask = setting << (gr%4)*8;			
 	 onemask = 0xFFFFFFFF - (0xFF <<  (gr%4) * 8);  /* mask with ones 'cept 0's in pos. */
	 oldmask = pm[dmap(v1+(gr/4))] & onemask;	/* old value of word with 0's in pos */
	 pm[dmap(v1+(gr/4))] = oldmask | setmask;	/* new word to write to memory */
	 break;

case 31: ;				/* noop			*/
	 break;

case 32: hlt = TRUE;			/* halt			*/
	 break;

case 33:				/* error		*/
	hlt = TRUE;
	/* A1 serves as error code */
	printf("\n ERROR:  %x\n",a1);		
	break;

case 34:				/* PmVmCp -- Primary Mem V Mem copy */
	if (md < 0) goto illins;
	pm [dmap(v2)] = pm [v1];
	break;
case 35:				/* VmPmCp		*/
	if (md < 0) goto illins;
	pm [v2] = pm[dmap(v1)];
	break;

case 36:				/* Arm			*/
	if (md < 0) goto illins;
	ar |= pm [dmap(v1)];
	break;

case 37:				/* Disarm		*/
	if (md < 0) goto illins;
	ar &= (-1-pm[dmap(v1)]);
	break;

case 38:				/* OS Call		*/
	if (md > 0) goto illins;
	ie |= EBIT;		/* set exception */
	pm [sp+PSR_ECD] = a1;	/* OS Call Number */
	break;

case 40:				/* Floppy IO		*/
	if (md < 0) goto illins;
	if (pm[LCL_FCP] < 0) { hlt = TRUE; break; }
	floppy_io ();
	break;
	
case 41:				/* Disk IO		*/
	if (md < 0) goto illins;
	if (pm[LCL_DCP] < 0) { hlt = TRUE; break; }
	disk_io ();
	break;

case 42:				/* Print IO		*/
	/* Advance one line and printf pm[v1] */
	if (md < 0) goto illins;
	fprintf (printer,"\t%s\t%8x\n",LP_STR,pm[v1]);
	fflush(printer);
	break;

case 43:				/* Log			*/
	if (md < 0) goto illins;
	log (v1, v2);
	break;

/* Cases 44 and 45 not written yet */

case 44:				/* TTY IN		*/
	if (md < 0) goto illins;
	break;

case 45:				/* TTY Out		*/
	if (md < 0) goto illins;
	break;
/*********************************************/
	
case 48:				/* Head Record		*/
	if (moverec(v1,v2,pm[dmap(v1)]))
		pc++;
	break;

case 49:				/* Move Record		*/
	if (moverec (v1, v2, xr))
		pc++;
	break;	

case 50:				/* Insert Record	*/
	if (xr < 0) break;
	insrec (v1, pm[dmap(v2)], xr);
	pc++;	
	break;

case 51:				/* Find Record		*/
	while (((pm[dmap(v1)+1] & pm[dmap(v2)]) != gr) && (pm[dmap(v1)] > 0))
		{
			v1 = pm[dmap(v1)];
		}
	if ((pm[dmap(v1)+1] & pm[dmap(v2)]) == gr)	
	{
		xr = v1;
		pc++;
	}
	break;

case 53:				/* Allocate		*/	
	if (allocate(v1,v2,gr)) pc++; 	
	break;	

case 54:				/* DeAllocate		*/
	if (deallocate(v1,v2,gr)) pc++;	
	break;

case 56:				/* SP Load		*/
	if (md < 0) goto illins;
	sp = pm [dmap(v1)];
	break;

case 57:				/* Switch Process	*/
	if (md < 0) goto illins;
	swcontxt (v1, v2);
	break;
case 60:				/* Send Message		*/
	if (md < 0) goto illins;
	if (pm [LCL_MSF] > 0)
		send_mesg ();
	break;		

case 61:				/* Receive Message	*/
	if (md < 0) goto illins;
	
	if (pm[dmap(sp + PSR_MSQ)] > 0)
		recv_mesg ();
	else	
		{
		/* reset M bit and switch to scheduler */
		pc--;
		pm[dmap(sp + PSR_STW)] |= MBIT;
		swcontxt (pm[LCL_SCH], pc);
		} 			
	break;

default:  hlt = TRUE;			/* Unused Op		*/
	break;

	}	/* End Case */

	goto realtm ;	/* Ready for real time section */

/* Real Time Code */
realtm:
	pm [LCL_TOD]++;			/* Increment Time of Day */
	pm [LCL_ALM]++;			/* Increment Alarm */
	
	if (pm [LCL_ALM] == 0)
		ie |= ABIT;		/* Set the Alarm */
	if (sp > 0)
		pm [sp+PSR_CPT]++;	/* Increment CPU time */

	if (fbsyrd)			/* Floppy busy? Get 2 wrds */
		{
		/* Read two words */
		/* is it pointing to the correct place? */
		if (fread (&pm[ftx], WD_B, 2, floppy) != 2)
			{
			fbsyrd = 0;
			pc --;
			}
		else
			{
			ftx += 2;
			if (ftx == ftul)
				{  fbsyrd = 0; ie |= FBIT; md &= ~(1<<FBIT);  }
			}
		}

	if (dbsyrd)		/* Disk Busy Reading ? Get 2 Words */ 
		{
		recv (dmasock, &pm[dtx], 2*WD_B, 0);
		dtx += 2;
		if (dtx == dtul)
			{ dbsyrd = 0; ie |= DBIT; md &= ~(1<<DBIT); }
		}

	else 
	  if (dbsywr)		/* Disk Writing (and not reading) Send 2 words */
		{
		write (dmasock, &pm[dtx], 2*WD_B);
		dtx += 2;
		if (dtx == dtul)
			{ dbsywr = 0; ie |= DBIT; md &= ~(1<<DBIT); }
		}		

/* Interrupt Handling */
if (ie != 0 && ar < 0)
	{
	int intr;
	int md_sign;
	int md_val;

	/* If something else running and this is not a greater one ignore for now */
	if ((extract (md,0,WD_L-1) != 0) && (md <= ie)) return;		/* Go away */

	/* Get sign bit */
	md_sign = (extract (md,(WD_L-1),1)) << (WD_L-1) ;	

	/* Get the rightmost interrupt and make sure it can execute */
	for (i=0; i< LEV_N; i++)
		{
		if ( (intr = (ffs (ie)-1)) != -1)	/* Find the int */ 
		 if (extract (ar,intr,1))		/* Is it armed? */
		  {	
		  if (sp > 0) 
		  /* Set the "return to" value to SP */
			pm [LCL_ITV + (2*intr) +1] = sp;
		  else 
			{ hlt = TRUE ; break ; }
		  ie &= ~(1<<intr);			/* Clear the int */
		  swcontxt (pm[LCL_ITV+(2*intr)], pc);	/* Switch to it */
		  md = (1 << intr);			/* Set mode register */
/*		  md = ((1<<intr) | md_sign);		/* Set mode register */
		  break;
		  }
		}
	}		
return;

/* Illegal instruction */	
illins:
	ecd = INSTFLT;
printf ("\n\nIll Ins ECD : %x\n\n", ecd);
	goto except;

/* Exception */
except:
	ie |= EBIT;
printf ("\nException Handler ECD : %x\n", ecd);
	if (sp > 0)
		pm [sp+PSR_ECD] = ecd;
	else
		hlt = TRUE;
	return;
}
示例#2
0
void imsai_fif_out(BYTE data)
{
	static int fdstate = 0;		/* state of the fd */
	static int fdaddr[16];		/* address of disk descriptors */
	static int descno;		/* descriptor # */

	void disk_io(int);

	/*
	 * The controller understands these commands:
	 * 0x10: set address of a disk descriptor from the following two out's
	 * 0x00: do the work as setup in the disk descriptor
	 * 0x20: reset a drive to home position, the lower digit contains
	 *       the drive to reset, 0x2f for all drives
	 *
	 * The dd address only needs to be set once, the OS then can adjust
	 * the wanted I/O in the descriptor and send the 0x00 command
	 * multiple times for this descriptor.
	 *
	 * The commands 0x10 and 0x00 are OR'ed with a descriptor number
	 * 0x0 - 0xf, so there can be 16 different disk descriptors that
	 * need to be remembered.
	 */
	switch (fdstate) {
	case 0:	/* start of command phase */
		switch (data & 0xf0) {
		case 0x00:	/* do what disk descriptor says */
			descno = data & 0xf;
			disk_io(fdaddr[descno]);
			break;

		case 0x10:	/* next 2 is address of disk descriptor */
			descno = data & 0xf;
			fdstate++;
			break;
	
		case 0x20:	/* reset drive(s) */
			break;	/* no mechanical drives, so nothing to do */

		default:
			printf("FIF: unknown cmd %02x\r\n", data);
			return;
		}
		break;

	case 1: /* LSB of disk descriptor address */
		fdaddr[descno] = data;
		fdstate++;
		break;

	case 2: /* MSB of disk descriptor address */
		fdaddr[descno] += data << 8;
		fdstate = 0;
		break;

	default:
		printf("FIF: internal state error\r\n");
		cpu_error = IOERROR;
		cpu_state = STOPPED;
		break;
	}
}