diff options
Diffstat (limited to 'private/mvdm/softpc.new/host/src/nt_wcom.c')
-rw-r--r-- | private/mvdm/softpc.new/host/src/nt_wcom.c | 438 |
1 files changed, 438 insertions, 0 deletions
diff --git a/private/mvdm/softpc.new/host/src/nt_wcom.c b/private/mvdm/softpc.new/host/src/nt_wcom.c new file mode 100644 index 000000000..05d476cf1 --- /dev/null +++ b/private/mvdm/softpc.new/host/src/nt_wcom.c @@ -0,0 +1,438 @@ +#include <windows.h> +#include <conapi.h> +#include "ptypes32.h" +#include "insignia.h" +#include "host_def.h" + +/* + * Author : D.A.Bartlett + * Purpose: + * + * + * Handle UART I/O's under windows + * + * + * + */ + +/*::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: Include files */ + +#include "xt.h" +#include "rs232.h" +#include "error.h" +#include "config.h" +#include "host_com.h" +#include "host_trc.h" +#include "host_rrr.h" +#include "debug.h" +#include "idetect.h" +#include "nt_com.h" +#include "nt_graph.h" +#include "nt_uis.h" + +#include <stdlib.h> +#include <string.h> +#include <stdio.h> + + +/*:::::::::::::::::::::::::::::::::::::::::::::::::::::: Global Data */ +GCHfn GetCommHandle; +GCSfn GetCommShadowMSR; + + +/*::::::::::::::::::::::::::::::::::::::::::::: Internal function protocols */ + +#ifndef PROD +void DisplayPortAccessError(int PortOffset, BOOL ReadAccess, BOOL PortOpen); +#endif + +BOOL SetupBaudRate(HANDLE FileHandle, DIVISOR_LATCH divisor_latch); +BOOL SetupLCRData(HANDLE FileHandle, LINE_CONTROL_REG LCR_reg); +BOOL SyncLineSettings(HANDLE FileHandle, DCB *pdcb, + DIVISOR_LATCH *divisor_latch, + LINE_CONTROL_REG *LCR_reg); + +/*::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: IMPORTS */ + + +/*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: UART state */ + +static struct ADAPTER_STATE +{ + DIVISOR_LATCH divisor_latch; + INT_ENABLE_REG int_enable_reg; + INT_ID_REG int_id_reg; + LINE_CONTROL_REG line_control_reg; + MODEM_CONTROL_REG modem_control_reg; + LINE_STATUS_REG line_status_reg; + MODEM_STATUS_REG modem_status_reg; + half_word scratch; /* scratch register */ + +} adapter_state[NUM_SERIAL_PORTS]; + +/*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::: WOW inb function */ + +void wow_com_inb(io_addr port, half_word *value) +{ + int adapter = adapter_for_port(port); + struct ADAPTER_STATE *asp = &adapter_state[adapter]; + BOOL Invalid_port_access = FALSE; + HANDLE FileH; + + + /*........................................... Communications port open ? */ + + if (GetCommHandle == NULL) { + com_inb(port,value); + return; + } + + FileH = (HANDLE)(*GetCommHandle)((WORD)adapter); +#ifndef PROD + if( FileH== NULL) + DisplayPortAccessError(port & 0x7, TRUE, FALSE); +#endif + + /*.................................................... Process port read */ + + switch(port & 0x7) + { + //Process read to RX register + case RS232_TX_RX: + + if(asp->line_control_reg.bits.DLAB == 0) + Invalid_port_access = TRUE; + else + { + if(SyncLineSettings(FileH,NULL,&asp->divisor_latch,&asp->line_control_reg)) + *value = (half_word) asp->divisor_latch.byte.LSByte; + else + Invalid_port_access = TRUE; + } + break; + + + //Process IER read + case RS232_IER: + + if(asp->line_control_reg.bits.DLAB == 0) + Invalid_port_access = TRUE; + else + { + if(SyncLineSettings(FileH,NULL,&asp->divisor_latch,&asp->line_control_reg)) + *value = (half_word) asp->divisor_latch.byte.MSByte; + else + Invalid_port_access = TRUE; + } + break; + + + //Process IIR, LSR and MCR reads + case RS232_IIR: + case RS232_LSR: + case RS232_MCR: + + Invalid_port_access = TRUE; + break; + + case RS232_LCR: + + if(SyncLineSettings(FileH,NULL,&asp->divisor_latch,&asp->line_control_reg)) + *value = asp->line_control_reg.all; + else + Invalid_port_access = TRUE; + + break; + + //Process MSR read + case RS232_MSR: + + *value = (half_word) (*GetCommShadowMSR)((WORD)adapter); + break; + + // Process access to Scratch register + case RS232_SCRATCH: + *value = asp->scratch; + break; + } + + /*.......................................... Handle invalid port accesses */ + +#ifndef PROD + if(Invalid_port_access) + DisplayPortAccessError(port & 0x7, TRUE, TRUE); +#endif + + +} + +/*::::::::::::::::::::::::::::::::::::::::::::::::::::::::: WOW outb function */ + +void wow_com_outb(io_addr port, half_word value) +{ + int adapter = adapter_for_port(port); + struct ADAPTER_STATE *asp = &adapter_state[adapter]; + BOOL Invalid_port_access = FALSE; + LINE_CONTROL_REG newLCR; + HANDLE FileH; + + /*........................................... Communications port open ? */ + + if (GetCommHandle == NULL) { + com_outb(port,value); + return; + } + + FileH = (HANDLE)(*GetCommHandle)((WORD)adapter); +#ifndef PROD + if(FileH == NULL) + DisplayPortAccessError(port & 0x7, FALSE, FALSE); +#endif + + /*.................................................... Process port write */ + + switch(port & 0x7) + { + //Process write to TX register + case RS232_TX_RX: + + if(asp->line_control_reg.bits.DLAB == 0) + Invalid_port_access = TRUE; + else + asp->divisor_latch.byte.LSByte= value; + + break; + + //Process write to IER register + case RS232_IER: + + if(asp->line_control_reg.bits.DLAB == 0) + Invalid_port_access = TRUE; + else + asp->divisor_latch.byte.MSByte = value; + + break; + + //Proces write to IIR, MCR, LSR amd MSR + + case RS232_IIR: + case RS232_MCR: + case RS232_LSR: + case RS232_MSR: + + Invalid_port_access = TRUE; + break; + + case RS232_LCR: + + newLCR.all = value; + if(asp->line_control_reg.bits.DLAB == 1 && newLCR.bits.DLAB == 0) + { + if(!SetupBaudRate(FileH,asp->divisor_latch)) + Invalid_port_access = TRUE; + } + + if(!Invalid_port_access && !SetupLCRData(FileH,newLCR)) + Invalid_port_access = TRUE; + + asp->line_control_reg.all = newLCR.all; + break; + + //Scratch register write + + case RS232_SCRATCH: + asp->scratch = value; + break; + } + + /*.......................................... Handle invalid port accesses */ + +#ifndef PROD + if(Invalid_port_access) + DisplayPortAccessError(port & 0x7, FALSE, TRUE); +#endif + +} + + +/*:::::::::::::::: Synchronise Baud/Parity/Stop bits/Data bits with real UART */ + +BOOL SyncLineSettings(HANDLE FileHandle, + DCB *pdcb, + DIVISOR_LATCH *divisor_latch, + LINE_CONTROL_REG *LCR_reg ) +{ + DCB dcb; //State of real UART + register DCB *dcb_ptr; + + + //Get current state of the real UART + + if(pdcb == NULL && !GetCommState(FileHandle, &dcb)) + { + always_trace0("ntvdm : GetCommState failed on open\n"); + return(FALSE); + } + + dcb_ptr = pdcb ? pdcb : &dcb; + + // Convert BAUD rate to divisor latch setting + divisor_latch->all = (unsigned short)(115200/dcb_ptr->BaudRate); + + //Setup parity value + LCR_reg->bits.parity_enabled = PARITYENABLE_ON; //Default parity on + + switch(dcb_ptr->Parity) + { + case EVENPARITY : + LCR_reg->bits.even_parity = EVENPARITY_EVEN; + break; + + case NOPARITY : + LCR_reg->bits.parity_enabled = PARITYENABLE_OFF; + break; + + case ODDPARITY : + LCR_reg->bits.even_parity = EVENPARITY_ODD; + break; + + case SPACEPARITY: + LCR_reg->bits.stick_parity = PARITY_STICK; + LCR_reg->bits.even_parity = EVENPARITY_EVEN; + break; + + case MARKPARITY : + LCR_reg->bits.stick_parity = PARITY_STICK; + LCR_reg->bits.even_parity = EVENPARITY_ODD; + break; + } + + //Setup stop bits + LCR_reg->bits.no_of_stop_bits = dcb_ptr->StopBits == ONESTOPBIT ? 0 : 1; + + //Setup data byte size + LCR_reg->bits.word_length = dcb_ptr->ByteSize-5; + + return(TRUE); +} + + +/*::::::::::::::::::::::::::::::::::::::::::::::::::: Setup Line control data */ + +BOOL SetupLCRData(HANDLE FileHandle, LINE_CONTROL_REG LCR_reg) +{ + DCB dcb; //State of real UART + + //Get current state of the real UART + + if(!GetCommState(FileHandle, &dcb)) + { + always_trace0("ntvdm : GetCommState failed on open\n"); + return(FALSE); + } + + //Setup data bits + dcb.ByteSize = LCR_reg.bits.word_length+5; + + //Setup stop bits + if(LCR_reg.bits.no_of_stop_bits == 0) + dcb.StopBits = LCR_reg.bits.word_length == 0 ? ONE5STOPBITS:TWOSTOPBITS; + else + dcb.StopBits = ONESTOPBIT; + + //Setup parity + if(LCR_reg.bits.parity_enabled == PARITYENABLE_ON) + { + if(LCR_reg.bits.stick_parity == PARITY_STICK) + { + dcb.Parity = LCR_reg.bits.even_parity == EVENPARITY_ODD ? + MARKPARITY : SPACEPARITY; + + } + else + { + dcb.Parity = LCR_reg.bits.even_parity == EVENPARITY_ODD ? + ODDPARITY :EVENPARITY; + } + } + else + dcb.Parity = NOPARITY; + + //Sent the new line setting values to the serial driver + if(!SetCommState(FileHandle, &dcb)) + { + always_trace0("ntvdm : GetCommState failed on open\n"); + return(FALSE); + } + + return(TRUE); +} + +/*:::::::::::::::::::::::::::::::::::::::::::::::::::::: Set up the baud rate */ + +BOOL SetupBaudRate(HANDLE FileHandle, DIVISOR_LATCH divisor_latch) +{ + DCB dcb; + + //Setup the baud rate + + if(!GetCommState(FileHandle, &dcb)) + { + always_trace0("ntvdm : GetCommState failed on open\n"); + return(FALSE); + } + + dcb.BaudRate = divisor_latch.all ? 115200/divisor_latch.all : 115200; + + if(!SetCommState(FileHandle, &dcb)) + { + always_trace0("ntvdm : GetCommState failed on open\n"); + return(FALSE); + } + + return(TRUE); +} + + +/*::::::::::::::::::::::::::::::::::::::::::::::::: Display port access error */ + + +#ifndef PROD +/* + * user warnings are not needed here, return errors and let the + * app handle it. message boxes are also not permitted, because + * it can kill WOW. 20-Feb-1993 Jonle + */ +void DisplayPortAccessError(int PortOffset, BOOL ReadAccess, BOOL PortOpen) +{ + static char *PortInError; + static char ErrorMessage[250]; + int rtn; + + // Identify port in error + + switch(PortOffset) + { + case RS232_TX_RX: PortInError = ReadAccess ? "RX" : "TX" ; break; + case RS232_IER: PortInError = "IER" ; break; + case RS232_IIR: PortInError = "IIR" ; break; + case RS232_MCR: PortInError = "MCR" ; break; + case RS232_LSR: PortInError = "LSR" ; break; + case RS232_MSR: PortInError = "MSR" ; break; + case RS232_LCR: PortInError = "LCR" ; break; + case RS232_SCRATCH: PortInError = "Scratch" ; break; + default: PortInError = "Unidentified"; break; + } + + //Construct Error message + + sprintf(ErrorMessage, "The Application attempted to %s the %s register", + ReadAccess ? "read" : "write", PortInError); + + if(!PortOpen) + strcat(ErrorMessage,", however the comm port has not yet been opened"); + + //Display message box + printf("WOW Communication Port Access Error\n%s\n",ErrorMessage); +} +#endif |