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>
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>
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>
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>
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>
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>
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>
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>