Commit graph

44 commits

Author SHA1 Message Date
fd76319cb3 Add Linux build artifacts to .gitignore
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 18:37:03 -06:00
ae2aef0119 Add remote forms system: DFM converter, server library, and client engine
Text-based protocol for serving Delphi-designed forms over serial.
dfm2form converts binary DFM (TPF0) to protocol commands on Linux.
formsrv loads .form files and sends/receives via pluggable transport.
formcli creates native Win 3.1 controls and routes events back to server.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 18:35:54 -06:00
9a735c6adf Rename delphi/ to ansibbs/ in preparation for another module
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 17:37:00 -06:00
8c8a42af36 Removed unused files. 2026-03-04 17:33:52 -06:00
ec6eebb2a5 Add TrueType font support with 4-tier font selection and documentation
Replace the inherited Font property with a FontSize property that drives
a multi-tier font selection strategy for pixel-perfect OEM rendering:
Terminal raster (exact size) > Perfect DOS VGA 437 (multiples of 8px) >
Terminal raster (nearest) > stock OEM fallback.  Add DxBuf uniform
character spacing to ExtTextOut for correct TrueType monospace rendering.
Bundle the Perfect DOS VGA 437 font (cmap converted from format 6 to
format 0 for Win 3.1 compatibility).  Size the test form dynamically
from terminal dimensions.  Add component documentation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 17:15:11 -06:00
d898e73213 Move form sizing to after Show so font metrics are fully realized
Sizing the form in the constructor via HandleNeeded was unreliable --
RecalcCellSize runs again during Show with different font metrics,
shrinking FAnsi while the form keeps its stale size.  Move the
ClientWidth/ClientHeight assignment into Run after Show, when handles
are fully created and RecalcCellSize has settled.  Restore constructor
Width/Height defaults in TKPAnsi for reasonable pre-handle dimensions.
Remove CP437 box-drawing diagnostic from the terminal.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 17:36:53 -06:00
3c5b57c6b5 Size form dynamically from terminal dimensions; fix signed/unsigned mismatch
Expose CellWidth/CellHeight properties on TKPAnsi and remove hardcoded
Width/Height from both the TKPAnsi constructor and TMainForm constructor.
TESTMAIN now computes form size from FAnsi.Width/Height after handle
allocation triggers RecalcCellSize.  Fix bytesRead in reccom() from
int16_t to uint16_t to match avail/chunk types.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 17:30:34 -06:00
eebcf100ad Fix hard lockup on COM port open from stale UART interrupt
Clear IER and read IIR/LSR/MSR/RBR before hookIsr unmasks the PIC.
A pending interrupt from a previous session would fire immediately,
but the ISR skipped dispatch (isOpen still FALSE), leaving the IRQ
asserted on level-triggered ISA -- infinite ISR loop.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 17:18:31 -06:00
fd56c8003d Increase default font size from 9 to 12 for 800x600 displays
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 17:09:57 -06:00
9102dd1938 Fix cursor ghost at end of lines when cursor changes rows
WriteDeferredBuf now dirties the old cursor row before the render
loop so the reverse-video cursor block is erased.  FlipToScreen's
ghost cleanup was ineffective because FLastCursorRow was already
updated by WriteDeferredBuf.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 16:58:56 -06:00
cb2018dff4 Split parsing from rendering to avoid GDI/CPU cache thrashing
ParseDataBuf is now pure CPU work with no GDI calls -- the parsing
loop stays cache-hot in the 486 L1.  WriteDeferredBuf parses first,
then renders all dirty rows in one batch.  Removes ~105 lines of
inline FLiveDC rendering from 8 methods.  Also fixes missing DC
local variable in Paint.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 16:53:18 -06:00
3fc2b410ba Render characters immediately during parsing, not in deferred pass
WriteDeferredBuf now acquires a screen DC and renders each character
run via ExtTextOut as it arrives, eliminating the per-row deferred
dirty scan.  FlushPendingScrolls coalesces scroll-ups into a single
ScrollDC call.  FlipToScreen becomes a lightweight blink/fallback pass.

Removed 50ms render throttle from TESTMAIN -- no longer needed since
characters appear on screen as they are parsed.

Simplified: removed ClearLine (duplicate of AllocLine), DirtyAll,
DirtyRow, GetCursorCol/Row (dead code), FTextBlinkOn (always equal
to FBlinkOn), ParseData (inlined), ETO_CLIPPED (unused), redundant
zero-initializations in constructor.  Write and WriteDeferred now
delegate to WriteDeferredBuf.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 16:18:33 -06:00
a9e25ec67f Re-select OEM font into DC before every render pass
Relying on CS_OWNDC to retain the font between frames is fragile --
Delphi's Canvas infrastructure can deselect it during paint cycles.
Without the OEM font, ExtTextOut renders with SYSTEM_FONT (ANSI_CHARSET),
causing CP437 box-drawing glyphs to display as accented letters, cell
metrics to mismatch (lines clipped), and cursor position to drift.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 19:23:22 -06:00
78753a65d8 Render ExtTextOut directly to screen DC, eliminating memory DC intermediate
The MemDC + BitBlt approach wrote every pixel twice (ExtTextOut to system
memory, then BitBlt to video memory).  Now ExtTextOut renders directly to
the CS_OWNDC screen DC, letting the display driver write text straight
into the framebuffer via its optimized raster font path.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 19:17:18 -06:00
a7780c8030 Replace DIB pixel rendering with ExtTextOut + memory DC BitBlt
The 8bpp DIB pipeline (font atlas, nibble lookup table, inline ASM glyph
expansion, SetDIBitsToDevice) is replaced with GDI text output: ExtTextOut
per color run into a memory DC, then BitBlt per row to the screen.

The memory bitmap is in native device format, so BitBlt is a raw copy with
no 8bpp-to-device color conversion.  ExtTextOut goes through the display
driver's optimized text path instead of software pixel expansion.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 19:00:58 -06:00
40dabea161 Fix Ofs() syntax: GMEM_FIXED offset is always 0
Delphi 1.0 Ofs() rejects dereferenced pointer expressions.
GMEM_FIXED allocations always have offset 0, so hardcode it.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 18:26:35 -06:00
4bbc382070 Fix Ofs() call: use intermediate variable for typed pointer cast
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 18:25:16 -06:00
e7454f87d1 Fix LES instruction: Delphi 1.0 inline ASM can't resolve object fields
Replace 'les di, FGlyphBuf' with explicit GlyphBase/GlyphSeg locals
that are extracted in Pascal before the ASM block.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 18:23:22 -06:00
c378abc9e5 Inline CSI parsing, ASM nibble table, cursor dedup, reccom block copy
Four performance optimizations targeting the hottest paths:

- Parse CSI params (P1/P2) as integers during scan-ahead loop,
  eliminating ParseParamBuf call from ExecuteCSI (~200 cycles/seq)
- Replace 16-iteration Pascal nibble table rebuild (64 branch+store)
  with 32 straight-line MOV word using precomputed BGBG/BGFG/FGBG/FGFG
- Integrate cursor FG/BG swap into main RenderRow column loop,
  removing duplicate nibble rebuild + ASM glyph expansion overlay pass
- Replace byte-at-a-time reccom loop with _fmemcpy block copy split
  at ring buffer wrap point, reducing far pointer overhead from O(n) to O(1)

Also includes previously uncommitted space fast-path in RenderRow and
inlined escape sequence handling in ParseDataBuf.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 18:20:51 -06:00
8e3bad86e3 Bypass 255-byte string limit and batch plain text runs in parser
Add ReadInputBuf to TKPComm for direct PChar reads up to 2048 bytes,
eliminating short string allocation and 8x fewer ReadComm API calls.
Add ParseDataBuf to TKPAnsi with run batching: scans ahead for printable
text runs, computes colors once per run, fills cells in tight loop
without per-character state/wrap checks.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 17:15:35 -06:00
64b3962c59 Add render throttle to decouple parse throughput from GDI overhead
During bulk serial data flow, renders are capped at ~20fps (50ms interval)
so the ANSI parser can run at full speed without blocking on FlipToScreen.
When idle, renders immediately for interactive responsiveness.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 17:02:01 -06:00
75d598c4c5 Eliminate heap allocs in ANSI parser, add ScrollDC for scroll rendering
Replace FParamStr string with fixed char buffer (FParamBuf/FParamLen)
to eliminate per-character heap allocations during CSI escape sequence
parsing. Replace ParseParams (Copy + StrToIntDef per token) with
ParseParamBuf that parses integers directly from the char buffer with
zero allocations.

Replace FAllDirty in DoScrollUp with FPendingScrolls counter. In
FlipToScreen, coalesce pending scrolls into a single ScrollDC call
that shifts on-screen pixels, then only render the newly exposed
bottom rows. Reduces per-scroll GDI cost from 25 SetDIBitsToDevice
calls to 1-3.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 16:03:45 -06:00
02e01848d6 Batch serial reads before rendering to improve ANSI throughput
Drain all available serial data before calling FlipToScreen so
overlapping screen changes collapse into a single GDI render pass.
Messages are checked between chunks to keep keyboard responsive.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 15:30:51 -06:00
c8ccedf569 Change default FIFO trigger from 8 to 1, yield CPU when idle
Default RX FIFO trigger level of 8 (FCR_TRIG_8) caused exactly 8
characters to buffer in hardware before the ISR fired. Change default
to 1 (FCR_TRIG_1) for responsive single-character interrupts while
keeping the 16-byte FIFO enabled as a safety buffer. COMnRxTRIGGER
SYSTEM.INI key still allows override.

The PM_NOYIELD polling loop never yielded the CPU timeslice, starving
other Windows applications. Add Yield call when no serial data is
flowing so other apps get CPU time. During bulk data flow HasData
stays true and the loop runs at full speed.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 20:44:14 -06:00
fbf4ed7c40 Fix input lag: add PM_NOYIELD, skip idle GetDC, eliminate redundant renders
PeekMessage without PM_NOYIELD surrenders the timeslice on every empty
queue check (~55ms per yield in Win16).  Adding pm_NoYield keeps the
polling loop hot so keystrokes and serial echoes are processed without
scheduler delays.

FlipToScreen was calling GetDC/ReleaseDC on every loop iteration even
with zero dirty rows.  Added early-exit scan before acquiring a DC.

TickBlink was calling FlipToScreen redundantly (main loop also calls it).
Removed the FlipToScreen from TickBlink and reordered the main loop to
TickBlink (dirty only) then FlipToScreen (single render pass).

Also: removed FBlinkOn := True reset from ParseData (was dirtying the
cursor row on every incoming chunk), added WriteDeferred for parse-only
without render, moved FlipToScreen from private to public, added Show
call before entering the polling loop.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 19:28:56 -06:00
ec0ec8f074 Replace event-driven WM_COMMNOTIFY architecture with polling main loop
The ISR still fills the ring buffer (mandatory for 115200 baud), but the
app now polls ReadComm directly via a PeekMessage loop instead of waiting
for WM_COMMNOTIFY.  Blink uses GetTickCount instead of WM_TIMER.  This
eliminates all Windows message overhead from the data path while keeping
the message loop alive for keyboard, paint, and scrollbar.

Removed from KPCOMM.PAS: NotifyWndProc, hidden notification window,
RegisterClass/CreateWindow, EnableCommNotification, SetCommEventMask,
DoCommEvent, Process*Notify methods, OnComm/CommEvent/RThreshold/
SThreshold properties, modem shadow state (CTS/DSR/CD).

Removed from KPANSI.PAS: WM_TIMER handler, SetTimer/KillTimer, replaced
with public TickBlink method using GetTickCount at 500ms intervals.

Removed from drv/isr.c: checkNotify function and its call from
isrDispatch.  Removed from drv/commdrv.c: pfnPostMessage, all
rxNotifySent/txNotifySent edge-trigger bookkeeping, gutted
enableNotification to a no-op API-compat stub.  Removed from
drv/commdrv.h: rxNotifySent/txNotifySent fields (shifts struct layout),
PostMessageProcT typedef, pfnPostMessage extern.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 19:01:40 -06:00
acf1a6b691 Remove BeginUpdate/EndUpdate, fix rendering starvation, add variable docs
Remove BeginUpdate/EndUpdate batching from TKPAnsi entirely -- Write now
renders immediately via FlipToScreen after every ParseData call.  Remove
FPendingScroll (caused rendering deadlock: EndUpdate refused to call
FlipToScreen while FPendingScroll > 0, but only FlipToScreen cleared it).
DoScrollUp simplified to set FAllDirty directly.

CommEvent drain loop retained (required by edge-triggered CN_RECEIVE) but
each chunk renders immediately -- no deferred batching.  Edge-triggered
notifications verified starvation-free at all levels: ISR, driver, KPCOMM
dispatch, terminal rendering, and keyboard output path.

Add comprehensive variable comments to all project files: TKPAnsi (44
fields), TKPComm (23 fields), TMainForm (9 fields), PortStateT, and
driver globals.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 18:34:19 -06:00
5dd464eb18 Fix hang on second COM port open: CLI deadlock, MOVEABLE buffers, stale UART
setque (called by USER.EXE after every inicom) was running GlobalAlloc and
GlobalFree with interrupts disabled.  On the second open the global heap
could need compaction or DPMI selector work, deadlocking under CLI.
Restructured to allocate new buffers first, swap pointers under CLI, then
free old buffers after STI.

Ring buffers changed from GMEM_MOVEABLE to GMEM_FIXED so addresses are
inherently stable at interrupt time.  Added rxBufH/txBufH handle fields
to PortStateT, eliminating the fragile GlobalHandle(SELECTOROF()) recovery
in freeBuffers.

trmcom now resets FIFOs and drains all pending UART conditions (LSR, MSR,
RBR, IIR) before unhooking the ISR, leaving hardware clean for reopen.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 20:06:04 -06:00
b6f08a3150 Remove render throttle and add smart blink dirty tracking
Data now hits the screen immediately when it arrives — no artificial
delay. The render throttle (RenderTickMs, FLastRenderTick) is removed
entirely. ParseData and EndUpdate call FlipToScreen unconditionally;
callers control batching via BeginUpdate/EndUpdate.

Blink toggle no longer calls DirtyAll. New DirtyBlinkRows method only
marks the cursor row and rows containing blink cells, reducing blink
overhead from ~63ms (25 rows) to ~3ms (1-3 rows) on a 486. Cursor
ghost handling in FlipToScreen dirties the old cursor row when the
cursor moves between rows.

Constant mini-frame values (Stride, CellH, PixSeg, GlyphSeg) are
pushed once before the column loop instead of per-cell, saving 320
push instructions per row.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 18:55:28 -06:00
c5d31ca930 Replace per-pixel branching with nibble lookup table and inline ASM
Rewrite RenderRow inner loop: split each glyph byte into two nibbles,
look up 4 pre-resolved palette bytes per nibble from a 64-byte table,
and write as word stores — zero branching in the hot path. Replace 25
per-row GlobalAlloc buffers with a single reusable buffer and move glyph
data into a GlobalAlloc'd block shared with the nibble table. All
arithmetic is 16-bit Word (no Longint). Uses mini-frame technique to
safely access local variables from inline ASM after DS/SI/DI clobber.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 18:33:59 -06:00
0ff633f605 Replace GDI rendering with font atlas and direct pixel writes
Build a monochrome font atlas at startup (BuildAtlas), then render
terminal cells by writing palette indices directly into 8bpp DIB row
buffers (RenderRow).  Each dirty row reaches the screen via a single
SetDIBitsToDevice call instead of ~12 GDI calls (TextOut, SetTextColor,
SetBkColor, BitBlt).  This reduces per-frame GDI overhead by ~10x,
targeting smooth playback of BBS door games on Win16.

Key changes:
- TTermCell FG/BG from TColor to Byte (palette index 0-15)
- Font atlas: render 256 CP437 glyphs into monochrome bitmap, extract
  per-glyph pixel masks via GetBitmapBits
- Per-row 8bpp DIB buffers via GlobalAlloc replace dual memory DCs
- RenderRow: zero-GDI atlas lookup + byte writes with cursor overlay
- FlipToScreen: ScrollDC on screen only, SetDIBitsToDevice per dirty row
- Text blink via FTextBlinkOn + re-render replaces dual-buffer phase swap
- Removed: CreateBuffers, DestroyBuffers, PaintLine, ClearBufRect,
  RedrawBuffers, DrawRow, FBufDC/FBufBmp/FBlinkPhase fields

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 23:21:22 -06:00
cd55adae4f Fix cursor artifacts and WM_TIMER starvation during high-speed data
Three fixes:

1. Cursor font mismatch: cursor overlay TextOut used the default DC
   font instead of FPaintFont (OEM_CHARSET). The wrong font size left
   residual pixels that buffer BitBlt didn't fully cover. Fix: select
   FPaintFont + OPAQUE BkMode into the CS_OWNDC screen DC once in
   RecalcCellSize, and re-assert before cursor TextOut in case VCL
   Paint altered the DC state.

2. WM_TIMER starvation: on Win16, WM_TIMER is lowest-priority and
   never dispatched while WM_COMMNOTIFY floods the queue. Fix: render
   from EndUpdate using GetTickCount throttle (no timer dependency).
   The timer remains as fallback for idle blink and trailing data.

3. Scroll performance: restore deferred ScrollDC at render time (not
   during parsing) so only newly-revealed rows need PaintLine instead
   of all 25. Dirty flags shift with each DoScrollUp to track the
   correct logical line positions after scroll.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 21:40:58 -06:00
c565be8489 Decouple rendering from data processing with timer-based display
Data parsing (ProcessChar) is now purely memory operations. EndUpdate
and ParseData set FRenderPending instead of calling FlipToScreen.
A 55ms timer (~18 Hz, matching Win16 tick resolution) drives rendering:
dirty rows are painted and BitBlt'd to screen only on timer ticks.
Blink toggles every 9 ticks (~500ms). This prevents high-throughput
data (door games, file transfers) from saturating the CPU with GDI
calls — between timer ticks, data just accumulates in cell buffers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 21:28:14 -06:00
a96dbb3faa Fix scroll rendering artifacts by removing ScrollDC
ScrollDC shifted buffer pixels during parsing before dirty rows were
rendered, causing unrendered garbage to propagate into non-dirty rows
on successive scrolls. Replace with FAllDirty to repaint all rows from
cell data after any scroll. With batched TextOut this costs ~250 GDI
calls per scroll instead of the old 12,000, so the overhead is minimal.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 21:18:15 -06:00
ca99d1d21b Optimize TKPAnsi rendering with batched TextOut and dirty row tracking
Separate parsing from rendering to eliminate per-character GDI calls.
ProcessChar now only updates cell data in memory; rendering is deferred
to FlipToScreen which batches consecutive same-color cells into single
TextOut calls (~5-10 per row instead of 80). Partial BitBlt transfers
only the dirty row band to the screen. Non-blinking rows render to one
buffer and BitBlt to the second, halving GDI work for typical content.

Also removes redundant GetCommError from KPComm receive path and adds
BeginUpdate/EndUpdate batching in the test app's CommEvent handler.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 21:15:51 -06:00
be566a5767 Fix OEM font rendering and terminal responsiveness in TKPAnsi
Replace TBitmap back buffer with raw GDI memory DC to prevent Delphi's
TCanvas from overriding the OEM_CHARSET font selection. Add OUT_RASTER_PRECIS
to CreateFontIndirect to ensure Windows maps to a true CP437 raster font
instead of a TrueType substitution. Optimize paint loop with fixed char
array instead of string concatenation. Restore Update call in ParseData
so WM_PAINT is not starved by WM_COMMNOTIFY. Add text blink support via
timer-driven FG/BG toggling and store blink as cell attribute instead of
mapping to bright background.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 17:48:20 -06:00
a3c52e0817 Add terminal query responses for BBS ANSI detection
Handle ENQ (0x05), ESC[c (Device Attributes), ESC[5n (Device Status
Report), and ESC[6n (Cursor Position Report).  Responses are sent
back through OnKeyData so BBSes can detect ANSI terminal capability.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 00:06:39 -06:00
c3ae983a73 Add TKPAnsi ANSI BBS terminal emulation component for Delphi 1.0
TKPAnsi is a TCustomControl descendant providing a visual ANSI terminal
with 16-color palette, scrollback buffer, blinking cursor, and ANSI music.
Supports CSI sequences (cursor movement, erase, SGR colors/attributes,
insert/delete lines/chars, scroll), DEC private modes (wrap, cursor
visibility), and keyboard translation (arrows, function keys, etc.).

Test app (TESTMAIN.PAS) updated to wire TKPAnsi to TKPComm as a
full terminal: received data feeds the terminal display, keystrokes
are sent out the serial port.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 23:12:23 -06:00
c7dc74ecdc VBX does not work. Moving to Delphi. 2026-02-25 22:06:08 -06:00
dd8326d16a Add native Delphi 1.0 TKPComm serial communications component
VBX registration is non-functional in VB4 16-bit (VBRegisterModel is a
no-op, VBGetModelInfo never called). Native Delphi component avoids all
DLL/export/registration issues — compiles directly into the IDE.

TKPComm is a TComponent descendant calling the Windows 3.1 comm API
directly. Uses RegisterClass/CreateWindow for WM_COMMNOTIFY dispatch
with the component instance pointer stored in cbWndExtra. Includes a
test application (KPTEST) with send/receive UI built entirely in code.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 22:04:54 -06:00
bf5268ade8 Rename VBX control from MSComm to KPComCtl
Files: mscomm.{c,h,def,rc,bmp} -> kpcomctl.{c,h,def,rc,bmp}
Output: mscomm.vbx -> kpcomctl.vbx
Types: MsCommDataT -> KpComCtlDataT, MsCommCtlProc -> KpComCtlProc
LIBRARY name: MSCOMM -> KPCOMCTL
VB control name: MSComm -> KPComCtl

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 20:16:02 -06:00
4218da32eb Rename output from COMM.DRV to KPCOMM.DRV to avoid clashing with stock driver
LIBRARY name stays COMM for import resolution. Debug strings updated to KPCOMM.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 20:07:45 -06:00
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
f666825417 Initial commit. 2026-02-23 20:53:02 -06:00