KAPKIT 1000

Products: KAPKIT 1000
Developer(s): Charles Peterson
Date: 1987
Type: Program
Platform(s): TS 1000

KAPKIT 1000 is a machine language toolkit stored in REM lines that provides a suite of Z80 utility routines callable from BASIC. The package includes routines for REM line generation, line deletion, memory copy (LDIR and LDDR), line address lookup, line length calculation, IN/OUT port access, RAMTOP adjustment, and RAM save/load operations. Each routine is invoked via USR calls with arguments passed using the exponentiation operator as a parameter-passing idiom. The main menu allows the user to list the documentation, save the program, or relocate the entire machine code block to a new address using the built-in LDIR copy routine. A supplementary section at line 3000 computes the hexadecimal offset between two addresses and prints the corresponding Z80 LD HL and CALL opcodes in decimal form for manual patching.


Program Analysis

Program Structure

The program is divided into four logical sections:

  1. Lines 1–2: REM lines storing the machine code payload. Line 1 contains 597 bytes of Z80 opcodes; line 2 is an empty separator.
  2. Lines 100–910: Pure REM documentation describing each routine’s offset, calling convention, and parameter syntax.
  3. Lines 1000–1310: The interactive menu — list docs, save, or relocate the code block and display a formatted routine address table.
  4. Lines 2000–2050 and 3000–3150: A SAVE subroutine and a decimal-offset calculator for manual Z80 patching.

Machine Code Storage

All 597 bytes of Z80 machine code are stored in the body of REM line 1, beginning at address 16514 (the standard location immediately after the system variables on a 1K/16K machine). The comment at line 130 confirms S = 16514 as the canonical base address. Each routine is referenced by an offset from S, documented in lines 250–910 and printed dynamically in lines 1190–1300.

Routine Entry Points

RoutineOffset from SUSR Address (default)
REM Generator+15816672
Delete Line(s)+24316757
LDIR (copy bottom-up)+30916823
LDDR (copy top-down)+32716841
Line Address+34516859
Line Length+35816872
IN+40216916
OUT+41416928
Change RAMTOP+42616940
RAMSAVE+46516979
RAMLOAD+52917043

Parameter-Passing Idiom

Parameters are passed to machine code routines using the exponentiation operator (**, SHIFT-H), noted in lines 210–230. For example, RAND USR 16823**SOURCE**DEST**NO. OF BYTES chains multiple numeric arguments. The Z80 routines retrieve these from the BASIC calculator stack. This is a well-established technique for passing multiple values to USR routines without needing additional PEEK/POKE setup.

Self-Relocation

Line 1090 uses the LDIR routine itself to copy the 597-byte code block to a new user-supplied address S:

RAND USR 16823**16514**S**597

After relocation, lines 1190–1300 compute and display the new absolute USR addresses by adding the documented offsets to S at runtime, using expressions like S+158, S+243, etc. This makes the toolkit fully position-independent from the user’s perspective.

Menu and Display Logic

Line 1005 clears the screen; line 1015 switches to SLOW mode before printing the menu. The key-polling loop at lines 1030–1050 uses INKEY$ in a tight loop rather than INPUT, allowing instant response without an ENTER keypress. The address table printed from line 1190 uses TAB C with C=25 to right-align USR addresses in a fixed column, producing a neat two-column layout despite the limited display width.

SAVE Routine

Lines 2000–2050 prompt the user, pause, save the program, then immediately RUN to restart. The SAVE filename at line 2040 uses inverse-video characters for the letters KK, which serves as an auto-run marker.

Decimal Offset Calculator (Lines 3000–3150)

This standalone utility helps users manually patch Z80 code after relocation. It accepts two addresses, computes their difference as OFFSET = A - B, and applies a two’s-complement correction at line 3090:

LET OFFSET=OFFSET+(65536 AND SGN OFFSET=-1)

This idiom adds 65536 if the offset is negative, yielding the correct unsigned 16-bit representation. Lines 3120–3140 then print the corresponding Z80 opcode bytes in decimal: LD HL, offset (opcode 33 followed by low and high bytes peeked from system variables 16434–16435 after RAND OFFSET loads the value), followed by opcode 9 (ADD HL, BC) and the three-byte sequence for CALL 2762 which is the ROM’s JP (HL) dispatch. The use of RAND OFFSET at line 3110 to load the offset value into the BASIC random-number register is a side-effect trick to make the low/high byte split available via PEEK on system variable addresses 16434–16435.

Notable Anomaly

Line 3020 contains a double-I typo: PRINT "IIS STARTING ADDRESS? ". This appears to be a BASIC listing artifact where an intended prompt string was entered with an accidental leading I, likely a keystroke error. It does not affect functionality since the line is purely a PRINT statement.

Key BASIC Idioms Summary

  • USR addr**arg1**arg2 — multi-parameter USR call via exponentiation chaining
  • INKEY$ polling loop — non-blocking single-key menu selection
  • 65536 AND SGN x=-1 — two’s-complement unsigned wrap for 16-bit arithmetic
  • RAND value then PEEK 16434/16435 — extract low/high bytes of a 16-bit value via the random seed system variable
  • TAB C with a pre-set constant — consistent column alignment in tabular output

Content

Appears On

Related Products

Machine language utility. Routines included are REM line generator, delete lines, line address, line length, string address, copy (LDIR and...

Related Articles

Related Content

Image Gallery

Source Code

   1 REM 2A1A40E5DF23E5FED82060D6624FE7CDB47221640B9284FED820F27923D1CD17AE5F7E1EDB02BBE2861B1223E518DCCF777571E1E1221640DFFE2DD5202C16415E7D61C3822FE10301ECB4228CA7CB17CB17CB17CB175F18E683CB4A2834718DE4FE7D1BA289CFDCD92DCDA7ED1E71CCB53206C5BA28F718BC2A2402B3EABE20FA3EC62BBE20F53E102BBE20EF2336C323360D1E1C9CDE722162FF9CDCAAE5C5EB21F0D819302CFBEBCDD892BC133C53333CD9E9C1D12323E5722373237123702336EABB2336078B120F83675342A740CB74282262823CDD89222940CD72C1C9CDE7221DFF9CDCAAEB21F0D89385ED4219302CFB6069CD17A38FB13D5CDD89D1E5EBCDD89D1CD5DA2A740CB74282262823CDD89222940CD72C9CDE7221CBFE9CDCAAEDB0D5CD72C1C9CDE7221B9FE9CDCAAEDB8D5CD72C1C921A7FE9CDCAACDD89444DC9219AFE9CDCAAEB21F0D89385ED4219302CFB6069CD17A38FB13D5CDD89D1E5EBCDD89D1CD17AC9216EFE9CDCAAED4860C92162FE9CDCAA444DED59C92156FE9CDCAA2A440A7ED72E5C12A440EB22440ED42F9EBED42EDB01B1B1B1BED53240C9CDE72DFFED8282CFDE72A1440FE352051194018AFE3B282CFEED5B1040D5ED52E5F5E7212FFE9CDCAAF17723C171237023EBE1EDB0D5CD72C1C9CDE72DFFED8282CFDE7F5E721EFFD9CDCAAF1FE35208BE20C1194018DFE3B203BE282CFEED5B1040234E234623E5D5EBCDC8ED1E1EDB0ED531440C35B0
   2 REM 
 100 REM .....KAPKIT (KK).....
 110 REM 
 120 REM S = KK STARTING ADDRESS
 130 REM S = 16514
 140 REM 
 150 REM ADDR = ADDRESS
 160 REM SOURCE = SOURCE ADDR
 170 REM DEST = DESTINATION ADDR
 180 REM 
 190 REM KK TOTAL BYTES = 597
 200 REM 
 210 REM DOUBLE ASTERISKS (**)
 220 REM ARE "RAISED TO THE
 230 REM POWER OF" (SHIFT-"H")
 235 REM 
 240 REM ...HOW TO USE KK...
 245 REM 
 250 REM --REM GEN-- (S + 158)
 260 REM 
 270 REM LET ADDR=5+USR 16672**
 280 REM LINE NO.**SPACES
 290 REM 
 300 REM --DELETE-- (S + 243)
 310 REM 
 320 REM RAND USR 16757**LINE
 330 REM NO.
 340 REM 
 350 REM RAND USR 16757**1ST
 360 REM LINE NO.**2ND LINE NO.
 370 REM 
 380 REM --LDIR-- (S + 309)
 390 REM 
 400 REM RAND USR 16823**SOURCE
 410 REM **DEST**NO. OF BYTES
 420 REM 
 430 REM --LDDR-- (S + 327)
 440 REM 
 450 REM RAND USR 16841**SOURCE
 460 REM **DEST**NO. OF BYTES
 470 REM 
 480 REM --LINADDR-- (S + 345)
 490 REM 
 500 REM LET ADDR=USR 16859**
 510 REM LINE NO.
 520 REM 
 530 REM --LINLEN-- (S + 358)
 540 REM 
 550 REM LET LENGTH=USR 16872**
 560 REM LINE NO.
 570 REM 
 580 REM LET LENGTH=USR 16872**
 590 REM 1ST LINE NO.**2ND LINE
 600 REM NO.
 610 REM 
 620 REM --IN-- (S + 402)
 630 REM 
 640 REM LET A=USR 16916**PORT
 650 REM 
 660 REM --OUT-- (S + 414)
 670 REM 
 680 REM RAND USR 16928**PORT**
 690 REM DATA
 700 REM 
 710 REM --RAMTOP-- (S + 426)
 720 REM 
 730 REM RAND USR 16940**NEW
 740 REM RAMTOP
 750 REM 
 760 REM --RAMSAVE-- (S + 465)
 770 REM 
 780 REM (PROGRAM): RAND USR
 790 REM 16979**P**DEST
 800 REM 
 810 REM (VARIABLES): RAND USR
 820 REM 16979**V**DEST
 830 REM 
 840 REM --RAMLOAD-- (S + 529)
 850 REM 
 860 REM (PROGRAM): RAND USR
 870 REM 17043**P**SOURCE
 880 REM 
 890 REM (VARIABLES): RAND USR
 900 REM 17043**V**SOURCE
 910 REM 
 1000 REM ..LIST/SAVE/RELOCATE..
 1005 CLS 
 1010 PRINT TAB 11;"KAPKIT 1000",,,
 1015 SLOW 
 1020 PRINT "1. LIST",,,,"2. SAVE",,,,"3. RELOCATE",,,,
 1030 LET A$=INKEY$
 1040 IF A$="1" THEN LIST 100
 1045 IF A$="2" THEN GOTO 2000
 1050 IF A$<>"3" THEN GOTO 1030
 1060 PRINT AT 21,3;"INPUT NEW STARTING ADDRESS"
 1070 INPUT S
 1080 FAST 
 1090 RAND USR 16823**16514**S**597
 1100 LET C=25
 1110 CLS 
 1190 PRINT "R O U T I N E";TAB C;"U S R"
 1200 PRINT ,,"REM GENERATOR";TAB C;S+158
 1210 PRINT ,,"DELETE LINE(S)";TAB C;S+243
 1220 PRINT ,,"LDIR (COPY BOTTOM-UP)";TAB C;S+309
 1230 PRINT "LDDR (COPY TOP-DOWN)";TAB C;S+327
 1240 PRINT ,,"LINE ADDRESS";TAB C;S+345
 1250 PRINT ,,"LINE(S) LENGTH";TAB C;S+358
 1260 PRINT ,,"IN";TAB C;S+402
 1270 PRINT "OUT";TAB C;S+414
 1280 PRINT ,,"CHANGE RAMTOP";TAB C;S+426
 1290 PRINT ,,"RAMSAVE";TAB C;S+465
 1300 PRINT "RAMLOAD";TAB C;S+529
 1310 STOP 
 2000 REM ......SAVE......
 2010 CLS 
 2020 PRINT "PRESS ANY KEY TO SAVE ""KK"""
 2030 PAUSE 4E4
 2040 SAVE "K%K"
 2050 RUN 
 3000 REM ...DECIMAL OFFSET...
 3010 REM 
 3020 PRINT "IIS STARTING ADDRESS? ";
 3030 INPUT A
 3040 PRINT A
 3050 PRINT ,,"ROUTINES STARTING ADDRESS? ";
 3060 INPUT B
 3070 PRINT B
 3080 LET OFFSET=A-B
 3090 LET OFFSET=OFFSET+(65536 AND SGN OFFSET=-1)
 3100 PRINT ,,"OFFSET = ";OFFSET
 3110 RAND OFFSET
 3120 PRINT ,,"33,";PEEK 16434;",";PEEK 16435,"LD HL, ";OFFSET
 3130 PRINT "9","ADD HL,BC"
 3140 PRINT "205,202,10","CALL 2762;JP(HL)"
 3150 STOP 

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

Scroll to Top