WinComm/vbx/serial.h
Scott Duensing d68405550d Fix COMM.DRV calling conventions and add ComDEB compatibility
Resolve GPFs in both USER.EXE and COMMTASK.DLL by correcting RETF
sizes for SETCOM and GETDCB, confirmed by disassembling CyberCom.DRV.
Add stock-compatible ComDEB structure so third-party code (ProComm
COMMTASK.DLL) can safely access internal fields at known offsets per
Microsoft KB Q101417.

COMM.DRV changes:
- SETCOM (ord 2): RETF 4, takes DCB FAR * only (not commId + DCB*)
- GETDCB (ord 15): RETF 2, takes commId, returns DCB FAR * in DX:AX
- Add 40-byte ComDebT matching stock COMM.DRV internal layout
  (evtWord at +0, MSR shadow at +35, queue counts at +8/+18)
- cevt returns pointer to ComDebT for third-party compatibility
- Sync ComDEB fields in ISR dispatch, reccom, sndcom, cflush, setque
- Move WEP to ordinal 16, add ordinal 101 stub (match stock/CyberCom)
- Default DBG_ENABLED to 0 (set to 1 to re-enable debug logging)

VBX control fixes:
- Fix SETBREAK/CLRBREAK constants (use numeric 8/9, not undefined macros)
- Fix serialEnableNotify return type (BOOL, not int16_t)
- Fix mscomm.h to work with RC compiler (#ifndef RC_INVOKED)
- Fix vbapi.h USHORT typedef and MODEL.flWndStyle type
- Add vbapi.lib dependency to makefile

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 20:03:34 -06:00

110 lines
4.2 KiB
C

// serial.h - Serial port abstraction header
//
// Wraps Windows 3.1 comm API (OpenComm, ReadComm, WriteComm, etc.)
// for use by the MSComm VBX control.
#ifndef SERIAL_H
#define SERIAL_H
#include <windows.h>
// -----------------------------------------------------------------------
// stdint types for MSVC 1.52 (no stdint.h available)
// -----------------------------------------------------------------------
#ifndef _STDINT_DEFINED
typedef short int16_t;
typedef unsigned short uint16_t;
typedef long int32_t;
typedef unsigned long uint32_t;
typedef unsigned char uint8_t;
typedef signed char int8_t;
#define _STDINT_DEFINED
#endif
// -----------------------------------------------------------------------
// Handshaking modes
// -----------------------------------------------------------------------
#define HANDSHAKE_NONE 0
#define HANDSHAKE_XONXOFF 1
#define HANDSHAKE_RTSCTS 2
#define HANDSHAKE_BOTH 3
// -----------------------------------------------------------------------
// Flush queue selectors
// -----------------------------------------------------------------------
#define FLUSH_RX 0
#define FLUSH_TX 1
// -----------------------------------------------------------------------
// Escape function constants (mirrors EscapeCommFunction values)
//
// SETDTR through RESETDEV are defined by windows.h.
// SETBREAK/CLRBREAK are not in windows.h (SetCommBreak/ClearCommBreak
// are separate API functions), so we define numeric values directly.
// -----------------------------------------------------------------------
#define SERIAL_SETDTR SETDTR
#define SERIAL_CLRDTR CLRDTR
#define SERIAL_SETRTS SETRTS
#define SERIAL_CLRRTS CLRRTS
#define SERIAL_SETBREAK 8
#define SERIAL_CLRBREAK 9
// -----------------------------------------------------------------------
// Function prototypes
// -----------------------------------------------------------------------
// Open a COM port with specified buffer sizes.
// Returns comm ID (>= 0) on success, negative on error.
int16_t serialOpen(int16_t port, int16_t inBufSize, int16_t outBufSize);
// Close an open comm port. Drops DTR and RTS before closing.
// Returns 0 on success, negative on error.
int16_t serialClose(int16_t commId);
// Configure baud, parity, data bits, stop bits from a settings string.
// settings format: "baud,parity,data,stop" (e.g., "9600,N,8,1")
// Returns 0 on success, negative on error.
int16_t serialConfigure(int16_t commId, int16_t port, const char FAR *settings);
// Apply handshaking mode to an open port.
// mode: HANDSHAKE_NONE, HANDSHAKE_XONXOFF, HANDSHAKE_RTSCTS, HANDSHAKE_BOTH
// Returns 0 on success, negative on error.
int16_t serialSetHandshaking(int16_t commId, int16_t mode);
// Apply null-discard and parity-replace settings to an open port.
// Returns 0 on success, negative on error.
int16_t serialSetOptions(int16_t commId, BOOL nullDiscard, const char FAR *parityReplace);
// Read data from receive buffer.
// Returns number of bytes read, or negative on error.
int16_t serialRead(int16_t commId, char FAR *buf, int16_t len);
// Write data to transmit buffer.
// Returns number of bytes written, or negative on error.
int16_t serialWrite(int16_t commId, const char FAR *buf, int16_t len);
// Get comm error status and buffer counts. Clears the error state.
// Returns error flags, fills stat with buffer counts.
int16_t serialGetStatus(int16_t commId, COMSTAT FAR *stat);
// Execute an escape function (DTR, RTS, break control).
// func: SERIAL_SETDTR, SERIAL_CLRDTR, SERIAL_SETRTS, etc.
// Returns 0 on success, negative on error.
int16_t serialEscape(int16_t commId, int16_t func);
// Get modem status lines via GetCommEventMask.
// Returns event mask bits (EV_CTS, EV_DSR, EV_RLSD, EV_RING).
UINT serialGetEventMask(int16_t commId, UINT mask);
// Enable WM_COMMNOTIFY messages to the specified window.
// rxThreshold: fire CN_RECEIVE when this many bytes available (-1=disable)
// txThreshold: fire CN_TRANSMIT when this much space free (-1=disable)
// Returns TRUE on success.
BOOL serialEnableNotify(int16_t commId, HWND hwnd, int16_t rxThreshold, int16_t txThreshold);
// Flush receive and/or transmit buffers.
// queue: FLUSH_RX or FLUSH_TX
// Returns 0 on success, negative on error.
int16_t serialFlush(int16_t commId, int16_t queue);
#endif // SERIAL_H