Skip to content

Technical & development notes

Rob Hagemans edited this page Jul 30, 2022 · 2 revisions

OEM keywords

PeatSoft https://hwiegman.home.xs4all.nl/gw-man/ describes a GW-BASIC with OEM additions to support Japanese character sets

CDBL$
CSNG$
JIS$
KLEN
KPOS
KTN$

and changes to ASC and CHR$.

These may be similar to N88-BASIC used on NEC computers?

Drawing circles and ellipses

Circles and ellipses are drawn using the Bresenham algorithm. This is faithful to GW-BASIC in most cases.

The exception is the fully symmetric circle, where GW-BASIC appears to use a different algorithm. It is not yet clear which, perhaps the mid-point algorithm or a direct approach using the square root. One could hypothesise that the symmetric circle was the first being implemented, and when ellipses and aspect ratio were introduced the old algorithm was kept for that case for backward compatibility.

Bresenham's algorithm was well exposed at https://sites.google.com/site/ruslancray/lab/projects/bresenhamscircleellipsedrawingalgorithm/bresenham-s-circle-ellipse-drawing-algorithm but the site has been lost and I have not been able to find a mirror or archive.

Random number generation

GW-BASIC uses a linear congruential generator. Notes on LCGs and how to solve for the parameters:

Note how the Internet Archive once more saves the day as original sources have been lost.

PC-BASIC uses the parameters of GW-BASIC 3.23's LCG. Older BASICA versions 1, 2, and 3 used different parameters, but from 3.1 onwards the same parameters as the last GW-BASIC were used. Some information on this is in the comments of this abandonware site. Disk BASIC also used different parameters.

See also Marsaglia's classic paper on why this is a bad way to generate random numbers: G. Marsaglia, Proc Natl Acad Sci U S A. 1968 Sep; 61(1): 25–28.

Port communications

Serial ports - RS232

Notes on USB ports / using physical serial port on Linux

TTL serial ports on Windows - this should be addressed by the driver https://www.pololu.com/docs/0J39/9

More docs on serial communications:

Parallel communications - the Centronics protocol

DOSBox uses in-channel control signals to emulate serial port control signals. See https://www.vogons.org/viewtopic.php?f=31&t=51760, quote videogamer555:

Interesting how dosbox simulates serial port control signals over TCP/IP. It sends a 0xFF byte (acts as an "escape" character) followed by a byte with bit flags indicating the states of the serial port's 2 control output pins (RTS and DTR). If it actually has to send a 0xFF byte in the serial data streem, it sends a 0xFF byte followed by another 0xFF byte. All data bytes it sends other than the 0xFF data byte, are sent without the additional 0xFF "escape" byte preceding the data byte.

IOCTL reference

IOCTL relates to DOS interrupt 44h (see e.g. DOS 7 manual.pdf appendix C p.291)

  • IOCTL stat -> AL=03H (write to char device)
  • IOCTL$ -> AL=02H (read from char device)

References:

IME text entry

Windows has an IME text entry system. SDL2 prevents the candidate window from opening. The problem is described here: The workaround for SDL2 IME candidate window not showing under Windows SDL2 windows下输入法候选没有显示的解决方法

Google translation of the relevant quote from that page:

SDL2 under windows, can get input text, but the text window of the candidate can not be used. By tracking code, rendering himself suspected > SDL2 candidate window, but the windows did not show up. Its solution is to disable SDL2 own candidate window. SDL_windowskeyboard.c modify the code, locate the IME_Init (SDL2.0.4 333 lines) comment out this line. Recompilation.

The line to comment out is line 333, the one starting videodate->imeuiless.

Alternatively, can we force open the candidate window through a windll call?

NI_OPENCANDIDATE = 16 (?) http://fpc.sourcearchive.com/documentation/2.2.2/windres_8h-source.html

hnd = IMMGetContext(
ctypes.windll.imm32.IMMNotifyIME(hnd, NI_OPENCANDIDATE, 0, 0)
IMMReleaseContext(

This gets the candidate list, but structure is unclear. Candidates seemed to go at an offset of 500 bytes irrespective of what's in the struct:

import ctypes
from ctypes import wintypes, windll
class CANDIDATELIST(ctypes.Structure):
    _fields_ = (
        ('dwSize', DWORD),
        ('dwStyle', DWORD),
        ('dwCount', DWORD),
        ('dwSelection', DWORD),
        ('dwPagestart', DWORD),
        ('dwPageSize', DWORD),
        ('dwOffset', DWORD),
    )
whnd = windll.user32.GetActiveWindow()
hnd = windll.imm32.ImmGetContext(whnd)
size =  windll.imm32.ImmGetCandidateListW(hnd, ctypes.wintypes.DWORD(0),0,0)
buf = ctypes.create_string_buffer(size)
windll.imm32.ImmGetCandidateListW(hnd, ctypes.wintypes.DWORD(0),buf, size)

See http://hg.libsdl.org/SDL/file/e12c38730512/src/video/windows/SDL_windowskeyboard.c for how IMMNotifyIME is used in IME_ClearComposition.

Notes:

Building SDL2_gfx.dll on Windows

The SDL2_gfx plugin is needed if you want to use the SDL2 interface with smooth scaling. Most Linux distributions will include this with their sdl2 package. On Windows, you will need to compile from source. To compile from the command line with Microsoft Visual C++:

  1. Download and unpack the SDL2 development package for Visual C++ SDL2-devel-2.x.x-VC.zip and the SDL2_gfx source code archive.

  2. Compile with the following options (for 64-bit):

     cl /LD /D_WIN32 /DWINDOWS /D_USRDLL /DDLL_EXPORT /Ipath_to_unpacked_sdl2_archive\include *.c /link path_to_unpacked_sdl2_archive\lib\x64\sdl2.lib /OUT:SDL2_gfx.dll
    

    or for 32-bit:

     cl /LD /D_WIN32 /DWINDOWS /D_USRDLL /DDLL_EXPORT /Ipath_to_unpacked_sdl2_archive\include *.c /link path_to_unpacked_sdl2_archive\lib\x86\sdl2.lib /OUT:SDL2_gfx.dll
    

Those who prefer to use the MinGW GCC compiler, follow these steps:

  1. Download and unpack the SDL2 binary, the SDL2 development package for MinGW and the SDL2_gfx source code archive. Note that the SDL2 development package contains several subdirectories for different architectures. You'll need the 32-bit version in i686-w64-mingw32/

  2. Place SDL2.dll in the directory where you unpacked the SDL2_gfx source code.

  3. In the MinGW shell, run

     ./autogen.sh
     ./configure --with-sdl-prefix="/path/to/where/you/put/i686-w64-mingw32/"
     make
     gcc -shared -o SDL2_gfx.dll *.o SDL2.dll