/*******************************************************************/ /* */ /* Advanced Communication Board Developer Toolkit */ /* (c)Copyright 1993-1995, Sealevel Systems Incorporated */ /* */ /*******************************************************************/ /* Please read the program abstract for details on this */ /* program. */ /* INT3.C */ /*******************************************************************/ #include #include #include #include "acb.h" #include "int.h" #include "Z8530.h" #include "ASCII.h" /* or EBCDIC.h for other character codes */ /*******************************************************************/ /* Things to make the program "compiler friendly"! */ /*******************************************************************/ #ifndef _BORLAND #define IN _inp #define OUT _outp #define FAR __far void __cdecl __interrupt FAR isr(void); #else #define IN inportb #define OUT outportb #define FAR far void __interrupt FAR isr(void); #endif /*******************************************************************/ #define PORT 0x238 /* Base Address of ACB card */ #define IRQ 0x05 /* interrupt request (IRQ 2-15) */ #define MAX_BUFFER 500 /* Size of Rx Buffer */ /*******************************************************************/ /* Z85x30 Init Values */ /*******************************************************************/ #define PRAM_COUNT 54 unsigned char init[PRAM_COUNT]= /*BISYNC initialization */ { WR0,NULL_CODE, /* MODES */ WR4, X1_CLOCK | SYNC_MODE_ENABLE | SYNC_16_BIT, WR1, WAIT_DMA_DISABLE | INT_DISABLE, WR2, 0x00, /* not used in polled mode */ WR3, RX_8_BITS | RX_CRC_ENABLE | SYNC_CHAR_LOAD_INHIBIT , WR5, TX_8_BITS | CRC_16 | TX_CRC_ENABLE, WR6, SYN, /* SYNC Flag Low*/ WR7, SYN, /* SYCN Flag High*/ WR9, MI_DISABLE, WR10, CRC_PRESET_TO_ZERO, WR11, TX_CLK_BRG | RX_CLK_RTXC_PIN | TRXC_IS_OUTPUT | TRXC_OUT_BRG, WR12, 0x7e, /*time constant-low byte 19.2K bps*/ WR13, 0x00, /*time constant-high byte */ WR14, BRG_SOURCE_PCLK | DPLL_NULL, WR14, BRG_SOURCE_PCLK | DPLL_NULL, WR14, BRG_SOURCE_PCLK | DPLL_NULL, WR14, BRG_ENABLE | BRG_SOURCE_PCLK | DPLL_NULL, /* ENABLES */ WR3, RX_8_BITS | SYNC_CHAR_LOAD_INHIBIT | RX_ENABLE, WR5, TX_8_BITS | CRC_16 | TX_ENABLE, WR0, RESET_TX_CRC, WR0, ERROR_RESET, WR1, WAIT_DMA_DISABLE | INT_DISABLE, WR15, NO_EXT_STAT_INT, /*INTERRUPT*/ WR0, RESET_EXT_STATUS_INT, WR0, RESET_EXT_STATUS_INT, WR1, WAIT_DMA_DISABLE | INT_DISABLE, WR9, MI_DISABLE }; /*******************************************************************/ /* end of init table, adjust variable PRAM_COUNT after modifying */ /*******************************************************************/ /*******************************************************************/ /* Function Prototypes */ /*******************************************************************/ int main(void); static void SCCB_TxBufferEmpty (void); static void SCCB_ExtStatChange (void); static void SCCB_RxCharAvail (void); static void SCCB_SpRxCondition (void); static void SCCA_TxBufferEmpty (void); static void SCCA_ExtStatChange (void); static void SCCA_RxCharAvail (void); static void SCCA_SpRxCondition (void); /*******************************************************************/ unsigned int rx_ptr = 0; /* Receive Buffer Pointer */ unsigned char RX_BUFFER[MAX_BUFFER]; unsigned int i; unsigned int Active = 0; /*******************************************************************/ int main(void) { void FAR *p; /* far void ptr*/ #ifndef _BORLAND void (__cdecl __interrupt FAR *fp)(void); /* far void function ptr */ #else void ( __interrupt FAR *fp)(void); /* far void function ptr */ #endif unsigned char c = 0; /*******************************************************************/ /* Verify Address of SCC (85x30) */ /*******************************************************************/ SCCout(PORT, WR2,0x55); /*write to WR2*/ if (SCCin(PORT, RR2)!=0x55) /*read back RR2*/ { printf("\nError: Device not found at address %x HEX.\n",PORT); return(1); /*return code 1 for ERROR*/ } else { printf("\nDevice verified at address %x HEX.\n",PORT); } /*******************************************************************/ /* Initialize ACB card */ /*******************************************************************/ SCCout(PORT, WR9, FORCE_HW_RESET); /*channel reset A and B*/ p = &init[0]; SCCInitEx(PORT ,p ,PRAM_COUNT); /*Initialize ACB */ /*******************************************************************/ /* Terminal */ /*******************************************************************/ printf("Type on the keyboard to send characters, press Esc to end the\n" \ "program and display the buffer contents.\n"); printf("\n"); /* For ACB-VI un-comment this line to enable on-board interrupts */ /* OUT(PORT+4, 0x40); */ SaveIRQMask(); /* Save the IRQ Mask*/ fp = isr; IRQSetupEx(IRQ ,fp); /*Save/Replace Interrupt Vector, etc. */ SCCout(PORT ,WR1 ,RX_INT_ALL_CHAR_SP_COND); /*Interrupt on all Rx Char*/ SCCout(PORT ,WR9 , MI_ENABLE); /*Master Interrupt Enable ON*/ do { if (_bios_keybrd(_KEYBRD_READY)) /*SW INT 16 hex function 1*/ { c = (unsigned char)(_bios_keybrd(_KEYBRD_READ)); if (c != ESC) { OUT(PORT, STX); /* Start of Text */ while (!(SCCin(PORT, RR0) & TX_BUFFER_EMPTY)) { } OUT(PORT, c); /* write character to data port */ while (!(SCCin(PORT, RR0) & TX_BUFFER_EMPTY)) { } OUT(PORT, ETX); /* End of Text or ETB*/ while (!(SCCin(PORT, RR0) & TX_BUFFER_EMPTY)) { } SCCout( PORT,WR3, RX_8_BITS | SYNC_CHAR_LOAD_INHIBIT | RX_ENABLE | ENTER_HUNT_MODE); } } } while (c != ESC); SCCout(PORT ,WR9 ,MI_DISABLE); /*Master Interrupt Enable OFF*/ SCCout(PORT ,WR1 ,INT_DISABLE); /*All Interrupt conditions OFF*/ IRQUnsetup(IRQ); /*Restore Interrupt Vector, etc. */ ReturnIRQMask(); /*Restore IRQ Mask */ RX_BUFFER[MAX_BUFFER] = 0; /* append NULL to buffer*/ /* Now print each byte of the buffer. This method will allow zeros */ /* to reside in the buffer. Otherwise, printf() will think it is a */ /* NUL terminated string. */ for (i = 0; i < MAX_BUFFER; i++) { printf("%c",RX_BUFFER[i]); /* Print buffer*/ } printf("\n"); return(0); } /*******************************************************************/ /* Interrupt Service Routine (ISR) */ /* This Routine is called when an interrupt is generated by the */ /* ACB adapter */ /*******************************************************************/ #ifndef _BORLAND void __cdecl __interrupt FAR isr(void) #else void __interrupt FAR isr(void) #endif { unsigned char isr_ptr, counter=0; static void (*sccisr[8])(void) = { SCCB_TxBufferEmpty, /* This is an array of routines */ SCCB_ExtStatChange, /* that are called when an */ SCCB_RxCharAvail, /* interrupt is pending on the */ SCCB_SpRxCondition, /* 85x30. */ SCCA_TxBufferEmpty, SCCA_ExtStatChange, SCCA_RxCharAvail, SCCA_SpRxCondition, }; while (SCCin(PORT, RR3)) /* While Interrupt is Pending*/ { isr_ptr = SCCin(PORT+2, RR2); /* Read Register 2 on Ch B */ isr_ptr >>= 1; /* Adjust interrupt pointer */ (*sccisr[isr_ptr])(); /* Call isr sub routine */ counter++; if (counter > 200) /* Time out just in case something*/ { break; /* goes wrong. */ } } counter = 0; /* Reset Time out counter */ #if (IRQ > 7) OUT(0xa0 ,0x20); /* AT PIC EOI */ #endif OUT(0x20, 0x20); /* XT PIC EOI */ } /*******************************************************************/ /* SCCB_TxBufferEmpty : called from ISR */ /* This routine is called when a Transmit Buffer Empty */ /* interrupt is pending on channel B of the SCC */ /*******************************************************************/ static void SCCB_TxBufferEmpty (void) { } /*******************************************************************/ /* SCCB_ExtStatChange : called from ISR */ /* This routine is called when a External Status Change */ /* interrupt is pending on channel B of the SCC */ /*******************************************************************/ static void SCCB_ExtStatChange (void) { } /*******************************************************************/ /* SCCB_RxCharAvail : called from ISR */ /* This routine will read all characters on channel B of the SCC */ /* at interrupt time */ /*******************************************************************/ static void SCCB_RxCharAvail (void) { } /*******************************************************************/ /* SCCB_SpRxCondition : called from ISR */ /* This routine is called when a Receive Special Condition */ /* interrupt is pending on channel B of the SCC */ /*******************************************************************/ static void SCCB_SpRxCondition (void) { } /*******************************************************************/ /* SCCA_TxBufferEmpty : called from ISR */ /* This routine is called when a Transmit Buffer Empty */ /* interrupt is pending on channel A of the SCC */ /*******************************************************************/ static void SCCA_TxBufferEmpty (void) { } /*******************************************************************/ /* SCCA_ExtStatChange : called from ISR */ /* This routine is called when a External Status Change */ /* interrupt is pending on channel A of the SCC */ /*******************************************************************/ static void SCCA_ExtStatChange (void) { } /*******************************************************************/ /* SCCA_RxCharAvail : called from ISR */ /* This routine will read all characters on channel A of the SCC */ /* at interrupt time */ /*******************************************************************/ static void SCCA_RxCharAvail (void) { unsigned char x, y; while ( RX_CHAR_AVAIL & (x = (SCCin(PORT, RR0)))) { y = (unsigned char) IN(PORT); /* Read Character */ switch(y) { case STX: Active = 1; break; case ETB: case ETX: Active = 0; SCCout( PORT,WR3, RX_8_BITS | SYNC_CHAR_LOAD_INHIBIT | RX_ENABLE | ENTER_HUNT_MODE); break; default: if (!Active) { break; } if (rx_ptr < MAX_BUFFER) /* if there is room in buffer */ { RX_BUFFER[rx_ptr] = y; /* put char in buffer */ rx_ptr++; /* inc buffer ptr */ } else /* if there is no room in the */ { rx_ptr = 0; /* wrap arround to the start */ RX_BUFFER[rx_ptr] = y; /* of the buffer */ rx_ptr++; } SCCout(PORT, WR0, ENABLE_INT_NEXT_RX_CHAR); break; } /* end switch case */ } } /*******************************************************************/ /* SCCA_SpRxCondition : called from ISR */ /* This routine is called when a Receive Special Condition */ /* interrupt is pending on channel A of the SCC */ /*******************************************************************/ static void SCCA_SpRxCondition (void) { unsigned char c; c = SCCin(PORT, RR1); c &= ( END_OF_FRAME | CRC_FRAMING_ERROR | RX_OVERRUN_ERROR | PARITY_ERROR); if (c & END_OF_FRAME) { SCCout(PORT, WR0, ERROR_RESET); } if (c & CRC_FRAMING_ERROR) { SCCout(PORT, WR0, ERROR_RESET); } if (c & RX_OVERRUN_ERROR) { SCCout(PORT, WR0, ERROR_RESET); } if (c & PARITY_ERROR) { SCCout(PORT, WR0, ERROR_RESET); } SCCout(PORT, WR0, RESET_HIGHEST_IUS); SCCout(PORT, WR0, RESET_RX_CRC); SCCout(PORT, WR0, ENABLE_INT_NEXT_RX_CHAR); } /*******************************************************************/ /* End of File */ /*******************************************************************/