/**********************************************************************/
/**                                                                  **/
/**                                                                  **/
/**     DESCRIPTION:                                                 **/
/**     -----------                                                  **/
/**     This  routine  is  the output  routine  for  use   MCC68K    **/  
/**     on HP 64000 .  It will,  depending  upon   the device code   **/
/**     given it, output an ascii string to either   the line        **/
/**     printer (code=1), the display (code=2), or a disc   file     **/
/**     (code=3).  All other device codes are illegal and may        **/
/**     cause strange errors to occur in emulation.                  **/
/**                                                                  **/
/**                                                                  **/
/**     note: check HP manual                                        **/
/**           "68000/68008 Emulation with Internal Analsys"          **/
/**           chapter 9 to 13 for more details                       **/
/**								     **/ 
/**********************************************************************/
  
  
#define TRUE 1
#define FALSE 0 
#define PRINTER 1     /*  PRINTER   */
#define DISPLAY 2     /*  DISPLAY   */
#define DISC 3        /*  DISK      */
#define KEYBOARD 4    /*  KEYBOARD  */
#define BUFSIZE 80    /*  BUFFER FOR DISPLAY  */
  
/************************************/
/*DECLARATIONS OF EXTERNAL VARIABLES*/
/************************************/
  
/*THE FOLLOWING ARE FLAGS INDICATING WHETHER FILES*/
/*ARE OPEN FOR DISC ,PRINTER, OR DISPLAY.*/ 
  
extern char DSC_CNTL_0,         /*DEFINE CONTROL ADDRESSES FOR DISC, PRINTER,*/ 
            DSC_CNTL_1[],       /*AND DISPLAY FOR SIMULATED I/O*/ 
            DSC_TYPE,DISC_NO, 
            NO_WORDS; 
  
extern int RECORD_NUMBER; 
  
extern char PRT_CNTL_0,         /*  PRINTER  */ 
            PRT_CNTL_1[], 
            DSP_CNTL_0,         /*  DISPLAY  */ 
            DSP_CNTL_1[], 
	    KEY_CNTL_0,         /*  KEYBOARD */
	    KEY_CNTL_1[];
  
  
static int DSCFILE_OPEN = FALSE;
static int PFILE_OPEN = FALSE;
static int DFILE_OPEN = FALSE;
  
  
/*******************************************************************/ 
/*                                                                 */ 
/*    WaIt (DEV) : Wait for sim I/O reponse. This procedure will,  */ 
/*                 depending upon the device number (DEV), wait    */ 
/*                 for 64000 response to a simulated I/O control   */ 
/*                 code.                                           */ 
/*                                                                 */ 
/*******************************************************************/ 
  
  
void WaIt( DEV )  
int  DEV; 
{ 
     switch( DEV )  
     {
        case PRINTER:                /*DEVICE IS PRINTER*/  
             while(PRT_CNTL_0 !=0);  /*CHECK FOR 64000 RESPONSE*/ 
             break;                  /*END DEVICE IS PRINTER*/
        case DISPLAY:                /*DEVICE IS DISPLAY*/  
             while(DSP_CNTL_0 !=0);  /*CHECK FOR 64000 RESPONSE*/ 
             break;                  /*END DEVICE IS PRINTER*/
        case DISC:                   /*DEVICE IS DISC*/ 
             while((DSC_CNTL_0 !=0) 
                  && (DSC_CNTL_0 !=1) 
                  && (DSC_CNTL_0 !=4));   /*CHECK FOR 64000 RESPONSE*/  
             break;                       /*END DEVICE  IS DISC*/ 
	case KEYBOARD:		     /* KEYBOARD INPUT */
             while(KEY_CNTL_0 != 0); /* CHECK FOR RESPONSE */ 
  	     break;
        default:  
             break; 
     }  
}                                    /*END OF FUNCTION WaIt*/ 
  
/********************************************************/
/*                                                      */
/*   OPEN_DISC_FILE(): Open the DISC file               */
/*                                                      */
/********************************************************/
  
  
static void OPEN_DISC_FILE() /*OPEN DISC FILE*/ 
{ 
     DSCFILE_OPEN = TRUE;    /*SET FLAG TRUE*/
                             /*OPEN DISC FILE TO BE USED FOR THIS ROUTINE*/ 
     DSC_TYPE = 2;
     DISC_NO = 0; 
     DSC_CNTL_0 = 0x80; 
     WaIt(DISC);  
     if (DSC_CNTL_0 == 0x4) 
     {                       /*FILE ALREADY EXISTS, OPEN AND PAGE TO END*/
        DSC_TYPE = 2; 
        DISC_NO = 0;  
        DSC_CNTL_0 = 0x81;
        WaIt(DISC); 
        for(RECORD_NUMBER = 1; DSC_CNTL_0 != 1; RECORD_NUMBER++)  
        { 
           DSC_CNTL_0 = 0x86; 
           WaIt(DISC);
        } 
      }                      /*END OF FILE EXISTS, OPEN AND PAGE TO END*/ 
}                            /*END OF OPEN DISC FILE*/  
  
  
  
/************************************************************/
/*                                                          */
/*   HPflush(DEVICE,OUTPUT,LEN)                             */
/*          Output to DEVICE from buffer OUTPUT with length */
/*          LEN.                                            */
/*                                                          */
/************************************************************/
  
  
static void HPflush(DEVICE,OUTPUT,LEN)  
int DEVICE;       /*   DEVICE TO FLUSH  */
char OUTPUT[];    /*  OUTPUT BUFFER */
int  LEN;         /*  BUFFER LENGTH */
{                           
int i;  
  
     switch ( DEVICE )  
     {  
        case PRINTER:                   /*PRINTER WRITE*/ 
             if (PFILE_OPEN == FALSE) 
             {                          /*OPEN PRINTER FILE*/ 
                PFILE_OPEN  = TRUE;     /*SET FILE OPEN FLAG TRUE*/ 
                PRT_CNTL_0  = 0x80;     /*TELL 64000 TO OPEN FILE*/ 
             }                          /*END OPEN PRINTER FILE*/ 
             WaIt(PRINTER);             /*WaIt FOR 64000 RESPONSE*/ 
             for (i=0; i<LEN; i++)
                 PRT_CNTL_1[i+1] = OUTPUT[i]; 
             PRT_CNTL_1[0] = i;         /*SET UP OUTPUT FOR PRINTER*/ 
             PRT_CNTL_0 = 0x82;         /*GO AHEAD AND PRINT*/
             WaIt(PRINTER); 
             break;                     /*END OF PRINTER WRITE*/
        case DISPLAY:                   /*DISPLAY WRITE*/ 
             if (DFILE_OPEN == FALSE) 
             {                          /*OPEN DISPLAY FILE*/ 
                DFILE_OPEN = TRUE;      /*SET FILE OPEN FLAG TRUE*/ 
		DSP_CNTL_1[0] = 1;	/* write only option */
		DSP_CNTL_1[1] = 18;	/* set devicename length */
		strcpy(&DSP_CNTL_1[2],"/dev/simio/display");
                DSP_CNTL_0 = 0x90;      /*TELL 64000 TO OPEN FILE*/ 
                WaIt(DISPLAY);          /*WaIt FOR 64000 RESPONSE*/ 
             }                          /*END OPEN DISPLAY FILE*/ 
             for (i=0; i<LEN; i++)
                 DSP_CNTL_1[i+2] = OUTPUT[i]; 
             DSP_CNTL_1[1] = i;         /*SET UP OUTPUT FOR DISPLAY*/ 
             DSP_CNTL_0 = 0x93;         /*GO AHEAD AND DISPLAY*/
             WaIt(DISPLAY); 
             break;                     /*END OF DISPLAY WRITE*/
        case DISC:                      /*DISC WRITE*/  
             if (DSCFILE_OPEN == FALSE) 
                OPEN_DISC_FILE(); 
             for (i=0; i<LEN; i++)
                 DSC_CNTL_1[i+1] = OUTPUT[i]; 
                                        /*DIVIDE NUMBER OF BYTES IN THE */
                                        /*STRING BY 2 TO GET THE NUMBER */
                                        /*OF WORDS.*/ 
             DSC_CNTL_1[++i] = ' '; 
             DSC_CNTL_1[0] = i/2;       /*SET UP NUMBER OF WORDS*/  
                                        /*TELL 64000 TO WRITE TO DISC FILE.*/ 
             DSC_CNTL_0 = 0x89; 
             WaIt(DISC);  
             break;                     /*END OF DISC WRITE*/ 
        default:  
             HPflush(DISPLAY, 
                    "**ERROR IN CALL TO  PRINTF, INVALID DEVICE** ",46);  
             break; 
      }                                 /*END OF SWITCH*/ 
}                                       /*END OF FUNCTION  PRINTF*/ 
  
  
/*******************************************************************/ 
/*                                                                 */ 
/*    OUTCHR(C) : Output routine which called by WRITE in CSYS68K  */ 
/*                it buffers to BUFSIZE characters and flush to HP */ 
/*                device by HPflush                                */ 
/*                                                                 */ 
/*******************************************************************/ 
  
  
static char outchrbuf[BUFSIZE];    /*  OUTPUT BUFFER  */
static int  bufpos = 0;            /*  CURRENT BUFFER POSITION  */
  
void OUTCHR(c)
char c;                            /*  OUTPUT CHARACTER  */ 
{ 
     if (c != '\r')                /*  SKIP CARRIAGE RETURN  */ 
        outchrbuf[bufpos++] = c;
     if ((bufpos == BUFSIZE) || (c == '\r')) /*  FLUSH WHEN BUFFER IS FILLED */ 
     {                                       /*  OR CARRIAGE RETURN          */ 
        if ((bufpos % 2) == 1)               /*  OUTPUT EVEN NUMBER OF CHAR  */ 
           outchrbuf[bufpos++] = ' '; 
        HPflush(DISPLAY, outchrbuf, bufpos); /*  FLUSH */ 
        bufpos = 0; 
     }      
} 
  
  
