TRS-80 DOS - TRSDOS v1.3 - SYS12/SYS Disassembled

General:

SYS12/SYS is a Level II BASIC overlay loaded by the BASIC interpreter when the user issues either the CMD"C" command (compress a BASIC program by removing remarks and excess whitespace) or the NAME-with-no-arguments family of commands that resolves to RENUM (renumber the lines of a BASIC program). It is loaded into memory at 4E00H and overlays the full address range 4E00H–5200H. The overlay shares its load region with several other BASIC overlays; the entry routine START at 4E00H first masks the system byte and dispatches to either the RENUM handler at REN (4E07H) or the COMPRESS handler at CMPRES (5093H).

The overlay was assembled from the Tandy source file SYS12.SRC against the equate file BASIC.GBL (which provides addresses for the Level II BASIC interpreter's ROM routines and workspace variables) and BMAC.EQU (which provides the standard BASIC parser macros GETCHR, SYNCHK, COMPAR, and GETYPE). The emitted code occupies 4E00H–51ADH (942 bytes); the residual 5 bytes between 51AEH and 51B2H are the two DEFS 2 reservations for the local workspace pointers BUFPNT and TEMPX.

Memory Map

Address RangeLabel / RegionDescription
4E00HSTARTCommon entry point; masks system number and dispatches to RENUM or COMPRESS.
4E07H–4F1AHREN through SCNPOPRENUM command handler and its supporting subroutines (line-number conversion, link-field walking, range and increment validation).
4F1BH–4F29HLINMStatic "Undefined line" message storage area (fifteen-byte ASCII string used by the RENUM error path when a referenced line number does not exist).
4F2AH–4F8AHSCNPT2 through LPSPCIPointer-to-line-number conversion logic, used to display BASIC programs with their original line numbers after RENUM.
4F8BH–4F96HTOKLSTTwelve-byte BASIC-token table (TOKLEN = 0CH) listing the keyword tokens whose argument needs line-number conversion: AUTO, DELETE, EDIT, RESUME, ERL, RUN, LIST, LLIST, GOTO, THEN, GOSUB, ELSE.
4F97H–5092HLINSCN through LINDSPLine-number reference scanner (called once per direction by SCCALL); makes a single pass through the entire program text and converts every line-number constant or pointer it finds in the appropriate direction.
5093H–50AAHCMPRES through SWTABCOMPRESS command entry; sets up working pointers and dispatches via the switch table at SWTAB.
50ABH–50B0HSWTABSix-byte dispatch table mapping COMPRESS sub-functions (BOTH, REMARK, SPACES) to their handler addresses.
50B1H–511CHBOTH and REMARKCOMPRESS — remove remarks (full REM tokens and standalone ' apostrophe-comments).
511DH–5158HSKQUOT through CLEARYShared utility routines: skip-quoted-strings scanner, skip-spaces, line-link cleanup, and the move-program-down loop helpers.
5159H–516BHMOVPGMSubroutine to slide the BASIC program down (HL)→(BC) when bytes are removed during compression.
516CH–51ADHSPACES through SPACE4COMPRESS — remove redundant spaces and tabs, except inside quoted strings or after FIELD statements.
51AEH–51B1HBUFPNT, TEMPXTwo 2-byte local workspace pointers used by the COMPRESS routines to hold the current buffer position and a temporary scratch pointer. Reserved with DEFS 2 at end of overlay; not initialised by the overlay loader, so callers must assume the values are undefined until set.

Local Variables and Workspace

The overlay defines two local 2-byte storage cells past the end of its emitted code; both are scratch pointers used only by the COMPRESS subroutines and have no defined value at overlay entry. No self-modifying code locations are present in this overlay.

AddressLabelDescription
51AEHBUFPNTDEFS 2 — current pointer into the BASIC program buffer for the COMPRESS routines. Set by CMPRES at 5096H to (TXTTAB) and updated as compression proceeds.
51B0HTEMPXDEFS 2 — scratch pointer used by the REMARK subroutines (REMAR4–REMAR7) to remember where the move-down operation should resume after a remark is excised.

External References (BASIC Interpreter Workspace)

The overlay reads and writes several BASIC interpreter workspace cells. All of these are defined in BASIC.GBL, but be aware that the actual addresses emitted by the assembler (and shown in the disassembly) do not match the values in the BASIC.GBL upload available at the time of writing — the binary uses 63B7H/63B8H/63BAH for PTRFLG/LINE1/CONTXT, while the BASIC.GBL we have lists 649FH/64A0H/64A2H. This is consistent with the overlay having been assembled against an earlier (or different-platform) build of Level II BASIC. The symbolic names below are the ones the source uses; the addresses shown are the ones present in the emitted binary, which is what readers will see when single-stepping through the overlay in an emulator or on hardware.

AddressLabelPurpose
40A4HTXTTABBASIC interpreter pointer to the start of the BASIC program in RAM.
40F9HVARTABBASIC interpreter pointer to the end of the program (= start of the variable table).
40FBHARYTABBASIC interpreter pointer to the start of the array table.
40FDHSTRENDBASIC interpreter pointer to the end of strings.
63B7HPTRFLGOne-byte flag set by SCCLIN/SCCPTR to indicate the current direction of conversion (00H = pointers in program, non-zero = line numbers in program).
63B8HLINE1Two-byte starting line number for RENUM (the "first line to renumber" or NN argument).
63BAHCONTXTTwo-byte general-purpose context pointer used by RENUM to remember the current position in the program when stepping through link fields.

Major Routine List

AddressLabelDescription
4E00HSTARTCommon entry point. Masks the system number byte and either jumps to CMPRES if VECT10 (90H) was requested, or falls through to REN.
4E07HRENRENUM command handler. Parses the optional RESEQ NN,MM,INC arguments, defaulting to NN=10 and INC=10 if omitted.
4E25HEATCOMSkip the comma between RESEQ arguments.
4E3EHRESNNRENUM continuation; arguments parsed, ready to begin the renumbering pass.
4E5AH / 4E68HNXTRSC / NXTRSLInner-loop body of the RENUM line-walking pass. Bumps the line-number accumulator by INC and steps to the next link field. These two entry points are reached in opposite orders to save bytes (NXTRSL is the natural fall-through; NXTRSC is the back-edge from the bottom of the loop).
4E79HRESSD1End-of-renumber processing: convert all references in the renumbered program back to line numbers.
4E8BHRESNX1Per-line renumbering inner loop after the first line.
4EA0HSCCALLSet up the BASIC READY-prompt return on the stack and fall through to SCCLIN/SCCPTR.
4EA5H / 4EA6HSCCLIN / SCCPTRTwin entry points for converting line-number references to/from in-program pointers. These two labels share the same code via the OR-n opcode-swallow trick (see Cross-references below). SCCLIN converts line numbers to pointers (used before RUN); SCCPTR converts pointers to line numbers (used during RENUM and after EDIT).
4EAAHSCNPGMBegin a full-program scan from the start of TXTTAB.
4EAEH / 4EB7H / 4EB8HSCNPLN / SCNEXT / SCNEX2Per-line scan loop: advance through one BASIC program line, calling LINSCN on each token to convert any line-number references it contains.
4EBBHSCNEXXCommon scan-loop exit; tests for end-of-program and falls through to NTERRG or returns.
4EEAHNTERRGContinue scanning after determining we are not processing an ON ERROR GOTO 0 (which would otherwise leave the 0 alone).
4EF3HCHGPTRPerform the actual swap of a line-number constant for a pointer (or vice-versa) in place.
4F15H / 4F16HSCNPOP / SCNEX3Restore the saved scan position from the stack and continue.
4F1BHLINM"Undefined line" error message storage (15 bytes including trailing terminator).
4F2AHSCNPT2Continuation of the pointer-to-line-number scanner; emits the actual ASCII line-number digits into the program text.
4F4AHLPLINIInner formatting loop for line-number-as-ASCII output during pointer→line conversion.
4F54H / 4F59HNINDON / MAKPTRConvert one line-number-constant token to a pointer. Sets the token byte to PTRCON (0DH) and writes the resulting two-byte address.
4F5DH / 4F60HCONCHG / CONCH2Helper that locates the target line by number (via FNDLIN) and either inserts the pointer or jumps to LPSPCI on a missing-line error.
4F69HNSPCFLNon-Fast-RENUM space-fill: pads the in-place line-number ASCII field with spaces so the program text length does not change.
4F71HLINGT3Get-line-from-text helper: extract the next two-byte LINK FIELD into DE and advance HL.
4F7DH / 4F83HSPCOTL / LPSPCIOutput-spaces loop: writes B SPACE characters at (HL) and increments HL.
4F8BHTOKLSTTwelve-byte BASIC-token table; see Memory Map.
4F97HLINSCNPer-token entry point used by the SCNPLN loop. Tests whether the current token is one of the dozen TOKLST entries (line-number-bearing keywords) or a bare line-number constant; if so, dispatches to MAKPTR or its dual.
4F9AH / 4FA2H / 4FAAHPNXTLN / PNXTCH / ISTOKNInner steps of the per-token scan: PNXTLN moves to the next BASIC program line; PNXTCH advances to the next character within a line; ISTOKN tests whether (HL) currently holds a token from TOKLST.
4FB0H / 4FCAHLOPTKS / LOPCMLThe TOKLST search loop body and its CP-and-loop continuation.
4FD7H / 4FDBHNOILEN / DOCNVRExits from the LINSCN test: NOILEN bails when the token doesn't match anything we care about; DOCNVR enters the conversion path proper.
4FDFH / 4FEAHLCHEAD / LZLOOPLeading-character header copy and zero-fill loop used to initialise the working buffer for one converted line.
4FF9HTWOINXTwo-byte INC HL helper (literally INC HL twice) for stepping past a two-byte line-number constant's value.
4FFDH / 4FFEHLINFL1 / LINFOLContinuation when a non-numeric character has been found following the token; LINFL1 is the one-byte-earlier alternate entry used to consume an immediately-preceding character first.
5003H / 500CH / 500FHLOKLF / NOLF / CLRLFLook-for / Not-Linked-Field / Clear-Linked-Field helpers used while walking the link-field chain.
5032H / 503FHMOVPR2 / SPCPURMove-program-up secondary entry and space-purge: when the converted form is shorter than the original (e.g., RENUM produced a smaller line number), slide the rest of the program down to close the gap.
5044H / 5045HSNOLIN / NOLINThe "no such line" error path: print the LINM ("Undefined line") message and resume the surrounding scan rather than aborting.
5064HGOPNXT"Go to next" jump-to-end-of-current-line helper used by both the RENUM and pointer-conversion loops.
5067HCLEARZZero out the array, string, and end-of-program pointers (ARYTAB, STREND) by copying VARTAB into them.
5071H / 5080HMOVPRG / LOPMVPMove-program-up. Slides A bytes of the BASIC program starting at (HL) up by one position, used when LINSCN needs to grow the program text to fit a longer line-number constant.
5088HLINDSPConvert HL (a binary integer) to its ASCII-decimal representation in place using the Level II ROM FOUINI / FOUT2 / INPRT floating-output helpers.
5093HCMPRESCOMPRESS command entry point. Initialises BUFPNT to (TXTTAB) and dispatches via the SWTAB jump table to BOTH (the default), or by pre-set fall-through to REMARK or SPACES individually.
50ABHSWTABSix-byte dispatch table (3 entries × 2 bytes each) used by CMPRES to vector to BOTH/REMARK/SPACES.
50B1HBOTH"Both" COMPRESS handler: invoke REMARK first, then SPACES.
50BAH–510CHREMARK and REMAR1–REMAR7The remark-removal subroutines. Walk the program looking for REM tokens (or apostrophe-comments after a colon) and excise everything from the token to the end of line.
511DH / 5124HSKQUOT / SKQUO1Skip-quoted-string scanner: advance HL past a string literal, including handling embedded doubled-quotes.
5129HSKIPSPSkip-spaces scanner: advance HL past any run of SPACE or TAB characters.
5136H / 513AH / 5144H / 514FHDOCLN / LDHEAD / LJLOOP / CLEARYEnd-of-compress fixup: rewrite the line-link chain after lines have been shortened, then update VARTAB and clear the variable storage.
5159HMOVPGMMove-program-down (the larger sibling of MOVPRG). Closes the gap left by REMARK or SPACES by sliding the rest of the program down to (BC) starting from (HL). Updates VARTAB to reflect the new end-of-program.
516CHSPACESSPACES COMPRESS handler entry: walk the program removing redundant SPACE and TAB bytes, except inside quoted strings or following a FIELD statement.
5179H–51A1HSPACE1–SPACE4 and DOSKIPSPACES inner-loop body: scan one character, dispatch on whether it's a quote/space/tab/end-of-line, and either remove it or step past it.

Jump Table: SWTAB at 50ABH

IndexBytes (LE)Target AddressHandler
0B1 5050B1HBOTH — remove both remarks and spaces (default for CMD"C" with no argument).
1BA 5050BAHREMARK — remove only remarks.
26C 51516CHSPACES — remove only redundant spaces and tabs.

BASIC Token Table: TOKLST at 4F8BH

Each byte in this table is a Level II BASIC keyword token. When LINSCN is walking through a BASIC program, it tests every byte it reads against this table; if the byte is one of these tokens, the byte that follows it in the program is treated as a line-number reference (or a line-number constant) that must be converted. The length of the table is held by the assembler-time constant TOKLEN (= 0CH = 12).

AddressByteTokenMeaning
4F8BHB7HAUTOAutomatic line numbering.
4F8CHB6HDELETEDelete a range of lines.
4F8DH9DHEDITEdit a line.
4F8EH9FHRESUMEResume after error.
4F8FHC2HERLError-line variable (used in RESUME ERL).
4F90H8EHRUNRun a program (with optional starting line).
4F91HB4HLISTList a range of lines.
4F92HB5HLLISTList a range of lines to printer.
4F93H8DHGOTOGoto a line.
4F94HCAHTHENThen-clause (followed by line number = implicit GOTO).
4F95H91HGOSUBGosub to a line.
4F96H95HELSEElse-clause (followed by line number = implicit GOTO).

Disassembly:

 
ORG 4E00H
4E00START
AND 0F0H
MASK off the SYSTEM NUMBER from the byte passed to this OVERLAY by masking against F0H (1111 0000). This has the effect of turning off bits 3, 2, 1, 0, leaving only bits 7, 6, 5, 4 active.
Original Source Code Comment: MASK OFF SYSTEM NUMBER
4E02
CP 90HCP VECT10
Compare the remainder of Register A against 90H, which would be the "COMPRESS" function call. If the masked value is 90H, then the COMPRESS function is being requested so ...
Original Source Code Comment: COMPRESS?
4E04
... do it via a JUMP to 5093H.
Original Source Code Comment: YES, DO IT

4E07H - REN - "RENUMBER" Function.

This routine can take up to 3 parameters: RESEQ (NN(,MM(,INC)))

  • NN = Starting line number to use in renumbering
  • MM = Starting line to renumber (lines below do not get renumbered)
  • INC = Increment (default = 10).
4E07REN
Clear all BASIC variables and pointers via a GOSUB to the Model III ROM Routine at 1B61H.
4E0A
LD BC,1D1EHLD BC,NEWSTT
Let Register Pair BC equal 1D1EH, which is the MODEL III ROM routine for the Level II BASIC Interpreter. This is the JUMP POINT for when the routine ends.
4E0D
DEC HL
HL was set to be the current value of the BASIC program pointer in that CALL. DECrement the value stored in Register Pair HL by 1 to prepare for a RST 10H which advances HL.
4E0E
RST 10H
Get a character from the BASIC program in RAM (which is the command line calling for the RENUMBER) via a call the EXAMINE NEXT SYMBOL routine at RST 10H.
NOTE:
  • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY FLAG if it is alphabetic, or sets it if is alphanumeric.
  • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
  • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
  • The string must be terminated by a byte of zeros.
4E0F
PUSH BC
Save the pointer to Level II BASIC Interpreter (held in Register Pair BC) to the top of the stack. Stack = this.
4E10
LD BC,000AHLD BC,CODE+10
As a default, set BC to be a default starting line of 10 (i.e., the base number plus a default of 10 as "INC").
Original Source Code Comment: ASSUME INC=10
4E13
PUSH BC
Save the default starting line number (held in Register Pair BC) to the top of the stack. Stack = INC, Level II Jump Point.
Original Source Code Comment: SAVE ON STACK
4E14
LD D,B
Since BC is 000AH, B = 00H. As a default, set DE (to zero) so that "NN" (starting line number) is zero, to renumber ALL lines.
Original Source Code Comment: RESEQ ALL LINES BY SETTING (DE)=0
4E15
LD E,B
Register B is still zero, so set Register E = 0 by copying the contents of Register B into Register E.
4E16
If there was no character found in the RST 10H (meaning that the user just entered RENUM without any parameters), then JUMP to 4E3EH to process with "ALL LINES" starting with line 10.
Original Source Code Comment: IF JUST 'RESEQ' RESEQ 10 BY 10
4E18
CP 2CH
We know the user included some parameter when calling RENUM, so first check for a first character of "," by comparing the value held in Register A against 2CH (ASCII: ,). If the character is a "," then the user did not designate a "first line to process" ...
Original Source Code Comment: COMMA
4E1A
... so JUMP to 4E25H to process that.
Original Source Code Comment: DONT USE STARTING # IF ZERO
4E1C
PUSH DE
Save "NN" (i.e., the first line number to be resquenced) held in Register Pair DE to the top of the stack, as it is about to get overwritten by the next instruction. Stack = NN, INC, Level II Jump Point
Original Source Code Comment: SAVE (DE)
4E1D
Get the new NN by evaluating the line number at the location of the current BASIC program pointer in register pair HL and return with the line number's binary value in register pair DE via a GOSUB to 1E4FH.
Original Source Code Comment: GET NEW NN
4E20
4E21
LD B,D
LD C,E
DE now holds the new "NN". Let Register Pair BC = the new NN.
Original Source Code Comment: GET IN (BC) WHERE IT BELONGS
4E22
POP DE
Restore "NN" (i.e., the first line number to be resquenced) from the top of the STACK into Register Pair DE, and then remove the entry from the stack. Stack = INC, Level II Jump Point. BC = New NN, DE = Old NN, HL = Pointer on the command line calling for the RENUM.
Original Source Code Comment: GET BACK (DE)
4E23
If the Z FLAG (Zero) has been set then we have no more command line to process, so JUMP to 4E3EH.
Original Source Code Comment: IF EOS, DONE
4E25EATCOM
RST 08H ⇒ 2C
RST 08H is used to look for expected characters (in this case, a ,) in a string and then return with (HL) pointing to the next non-blank character.

It is a COMPARE SYMBOL routine which comparess the symbol in the input string pointed to by HL register to the value in the location following the RST 08 call.

If there is a match, control is returned to address of the RST 08 instruction 2 with the next symbol in the A register and HL incremented by one. If the two characters do not match, a syntax error message is given.
Original Source Code Comment: EXPECT COMMA

The prior instruction found a "," meaning that we have a parameter to interpret. So the next instruction converts the parameter from ASCII to Decimal.

4E27
Get new MM by converting the ASCII character at (HL) to binary with the result in DE via GOSUB to the Model III ROM routine at 1E4FH. Returns with Z FLAG set if it finds a 00H or a :. Stack = INC, Level II Jump Point. BC = New NN, DE = New MM, HL = Pointer on the command line calling for the RENUM.
Original Source Code Comment: GET NEW MM
4E2A
If the Z FLAG (Zero) has been set, JUMP to 4E3EH.
Original Source Code Comment: IF EOS, DONE
4E2C
POP AF
Discard the value held at the top of the STACK (which was the old "INC", put into the stack at 4E13H). Stack = Level II Jump Point. BC = New NN, DE = New MM, HL = Pointer on the command line calling for the RENUM, AF = Old INC.
Original Source Code Comment: GET RID OF OLD INC
4E2D
RST 08H ⇒ 2C
RST 08H is used to look for expected characters (in this case, a ,) in a string and then return with (HL) pointing to the next non-blank character.

It is a COMPARE SYMBOL routine which comparess the symbol in the input string pointed to by HL register to the value in the location following the RST 08 call.

If there is a match, control is returned to address of the RST 08 instruction 2 with the next symbol in the A register and HL incremented by one. If the two characters do not match, a syntax error message is given.
Original Source Code Comment: EXPECT COMMA
4E2F
PUSH DE
Save the "MM" to the top of the stack. Stack = MM, Level II Jump Point. BC = New NN, DE = New MM, HL = Pointer on the command line calling for the RENUM.
Original Source Code Comment: SAVE MM

Next, we process a new "INC" value.

4E30
Convert the ASCII string pointed to by HL (which should be the new "INC") to an integer deposited into DE via a GOSUB to the Model III ROM routine at 1E5AH. After execution HL points to the delimiter and the A register contains the delimiter value. The Z flag is set if the delimiter equals 00 or 3A. Z is reset if any other delimiter is used. If the routine finds a non-numerical character, the conversion is stopped.

Stack = MM, Level II Jump Point. BC = New NN, DE = INC, HL = Pointer on the command line calling for the RENUM.
Original Source Code Comment: GET NEW INC
4E33
If the routine at 1E5AH returns with the NZ FLAG (Not Zero) set, abort with a "SYNTAX ERROR" via a JUMP to the Model III ROM Routine at 1997H.
Original Source Code Comment: YES,SHOULD HAVE TERMINATED

We now need to check to see if the new INC is a 0, which would be illegal.

4E36
4E37
LD A,D
OR E
Since the Z-80 cannot test Register Pair DE against zero, the common trick is to set Register A to equal to Register D, and then OR A against Register E. Only if both Register D and Register E were zero can the Z FLAG be set.
Original Source Code Comment: SEE IF INC=0 (ILLEGAL)
4E38
If the new "INC" is 0, the Z FLAG (Zero) will have set, so we JUMP to the Model III ROM Routine at 1E4AH to abort with a ?FC ERROR message.
Original Source Code Comment: YES,BLOW HIM UP NOW
4E3B
EX DE,HL
EXchange the value stored in Register Pair HL with the value stored in Register Pair DE (currently, the "INC").

Stack = MM, Level II Jump Point. BC = New NN, HL= INC, DE = Pointer on the command line calling for the RENUM.
Original Source Code Comment: FLIP NEW INC & (HL)
4E3C
EX (SP),HL
EXchange the "INC" (now stored in Register Pair HL) with the value stored in Register Pair SP (i.e., "MM" as pushed in 4E2FH).

Stack = INC, Level II Jump Point. BC = New NN, HL= MM, DE = Pointer on the command line calling for the RENUM.
Original Source Code Comment: NEW INC ONTO STACK
4E3D
EX DE,HL
Restore HL and DE to what they were.

Stack = INC, Level II Jump Point. BC = New NN, DE= MM, HL = Pointer on the command line calling for the RENUM.
Original Source Code Comment: GET (HL) BACK, ORG (DE) BACK

4E3EH - RESNN - Still in the Renumber Function, finished parsing the command line.

4E3ERESNN
PUSH BC
Save "NN" (held in Register Pair BC) to the top of the stack.

Stack = NN, INC, Level II Jump Point. BC = New NN, DE= MM, HL = Pointer on the command line calling for the RENUM.
Original Source Code Comment: SAVE NN ON STACK
4E3F
LD (63B8H),DELD (LINE1),DE
Store "MM" (held in Register Pair DE) into memory location 63B8H.
Original Source Code Comment: SAVE TO FIND LATER ON
4E43
Search RAM for line "MM" (held in DE) via a GOSUB to the Model III ROM Routine at 1B2CH. Returns C/Z with the line found in BC, NC/Z with line number is too large and HL/BC having the next available location, or NC/NZ with line number not found, and BC has the first available one after that.

Stack = NN, INC, Level II Jump Point. BC = RAM location where line MM is to be found, DE= MM, HL = Pointer on the command line calling for the RENUM.
Original Source Code Comment: FIND MM LINE
4E46
POP DE
Put the value held at the top of the STACK into Register Pair DE, and then remove the entry from the stack.

Stack = INC, Level II Jump Point. BC = RAM location where line MM is to be found, DE= NN, HL = Pointer on the command line calling for the RENUM. Why is MM gone? Since MM is the lowest line to work from, and BC now has that location, we no longer need to keep track of MM.
Original Source Code Comment: GET NN OFF STACK
4E47
PUSH DE
Save the contents of Register Pair DE to the top of the stack.

Stack = NN, INC, Level II Jump Point. BC = RAM location where line MM is to be found, DE= NN, HL = Pointer on the command line calling for the RENUM.
Original Source Code Comment: SAVE NN BACK
4E48
PUSH BC
Save the contents of Register Pair BC to the top of the stack.

Stack = RAM location where line MM is to be found, NN, INC, Level II Jump Point. BC = RAM location where line MM is to be found, DE= NN, HL = Pointer on the command line calling for the RENUM.
Original Source Code Comment: SAVE POINTER TO MM LINE
4E49
Search RAM for line "NN" (held in DE) via a GOSUB to the Model III ROM Routine at 1B2CH. Returns C/Z with the line found in BC, NC/Z with line number is too large and HL/BC having the next available location, or NC/NZ with line number not found, and BC has the first available one after that.

Stack = RAM location where line MM is to be found, NN, INC, Level II Jump Point. BC = RAM location where line NN is to be found, DE= NN, HL = Pointer on the command line calling for the RENUM.
Original Source Code Comment: FIND FIRST LINE TO RESEQ.
4E4C
4E4D
LD H,B
LD L,C
Let HL = BC.

Stack = RAM location where line MM is to be found, NN, INC, Level II Jump Point. BC = RAM location where line NN is to be found, DE= NN, HL = RAM location where line NN is to be found. What happened to HL? We don't need to parse the RENUM command line anymore, and that's what HL was pointing to.
Original Source Code Comment: GET PTR TO THIS INE IN (HL)
4E4E
POP DE
Put the value held at the top of the STACK into Register Pair DE, and then remove the entry from the stack.

Stack = NN, INC, Level II Jump Point. BC = RAM location where line NN is to be found, DE= RAM location where line MM is to be found, HL = RAM location where line NN is to be found. What happened to HL? We don't need to parse the RENUM command line anymore, and that's what HL was pointing to.
Original Source Code Comment: GET LINE PTD TO BY MM
4E4F
RST 18H
RST 18 to see if the variable address in HL (RAM location where line NN is to be found) is the same as in DE (RAM location where line MM is to be found), so we call the COMPARE DE:HL routine, which numerically compares DE and HL. Uses the A-register only. The result of the comparison is returned in the status register as: CARRY SET=HL<DE; NO CARRY=HL>DE; NZ=Unequal; Z=Equal).
Original Source Code Comment: COMPARE TO FIRST LINE RESEQ'ED
4E50
EX DE,HL
EXchange the value stored in Register Pair HL with the value stored in Register Pair DE.

Stack = NN, INC, Level II Jump Point. BC = RAM location where line NN is to be found, HL= RAM location where line MM is to be found, DE = RAM location where line NN is to be found.
Original Source Code Comment: GET PTR TO MM LINE IN (HL)
4E51
If RAM location where line NN is to be found (HL) < RAM location where line MM is to be found (DE), which will have set the CARRY FLAG, then we cannot proceed because the program will be renumbered on top of itself. With this, we JUMP to the Model III ROM Routine at 1E4AH to abort with a ?FC ERROR message.
Original Source Code Comment: CANT ALLOW PROGRAM TO BE RESEQUED
4E54
POP DE
Put the value held at the top of the STACK (i.e., NN) into Register Pair DE, and then remove the entry from the stack.

Stack = INC, Level II Jump Point. BC = RAM location where line NN is to be found, HL= RAM location where line MM is to be found, DE = NN.
Original Source Code Comment: GET NN BACK
4E55
POP BC
Put the value held at the top of the STACK (i.e., INC) into Register Pair BC, and then remove the entry from the stack.

Stack = Level II Jump Point. BC = INC, HL= RAM location where line MM is to be found, DE = NN.
Original Source Code Comment: GET INC IN (BC)
4E56
POP AF
Put the value held at the top of the STACK into Register Pair AF, and then remove the entry from the stack.

Stack = EMPTY. BC = INC, HL= RAM location where line MM is to be found, DE = NN, AF = Level II Jump Point.
Original Source Code Comment: GET RID OF NEWSTT
4E57
PUSH DE
Save the contents of Register Pair DE (i.e, NN) to the top of the stack.

Stack = NN. BC = INC, HL= RAM location where line MM is to be found, DE = NN, AF = Level II Jump Point.
Original Source Code Comment: SAVE NN ON STACK
4E58
JUMP to 4E68H.

4E5AH - NXTRSC - Bump the line number by the INC. This routine is not in order. It is jumped to by 4E77, but ultimately would flow down the 4E68H so this was a RAM saver.

4E5ANXTRSC
ADD HL,BC
LET Register Pair HL (i.e., the LINE NUMBER ACCUMULATOR) = Register Pair HL + Register BC (i.e., INC).
Original Source Code Comment: ADD INCREMENT INTO
4E5B
If that addition caused the line number to go above 65529, the C FLAG (Carry) will have been set, and we JUMP to the Model III ROM Routine at 1E4AH to abort with a ?FC ERROR message.
Original Source Code Comment: UH OH, HIS INC WAS TOO LARGE
4E5E
EX DE,HL
EXchange the value stored in Register Pair HL (i.e., the LINE NUMBER ACCUMULATOR) with the value stored in Register Pair DE (i.e., the LINK FIELD).
Original Source Code Comment: FLIP LINK FIELD , ACCUM
4E5F
PUSH HL
Save the contents of Register Pair HL (i.e., the LINK FIELD) to the top of the stack.
Original Source Code Comment: SAVE LINK FIELD
4E60
LD HL,0FFF9HLD HL,CODE+65529
Let Register Pair HL equal 0FFF9H to see if the LINK FIELD will exceed the highest possibleline number of 65529.
Original Source Code Comment: TEST FOR TOO LARGE LINE
4E63
RST 18H
RST 18 to see if the variable address in HL is the same as in DE, so we call the COMPARE DE:HL routine, which numerically compares DE and HL. Will not work for signed integers (except positive ones). Uses the A-register only. The result of the comparison is returned in the status register as: CARRY SET=HL<DE; NO CARRY=HL>DE; NZ=Unequal; Z=Equal).
Original Source Code Comment: COMPARE TO CURRENT #
4E64
POP HL
Put the value held at the top of the STACK (i.e., the LINK FIELD) into Register Pair HL, and then remove the entry from the stack.
Original Source Code Comment: RESTORE LINK FIELD
4E65
If the C FLAG (Carry) has been set then the "INC" was too large and resulted in an invalid line number. With this we JUMP to the Model III ROM Routine at 1E4AH to abort with a ?FC ERROR message.
Original Source Code Comment: HIS INC WAS TOO LARGE

4E68H - NXTRSL - Continuation of RENUM from 4E58H (with BC = INC, HL= RAM location where line MM is to be found, DE = NN) -or- pass through from 4E5AH (from 4E77H) with HL holding the LINK FIELD and DE holding the current LINE NUMBER ACCUMULATOR.


4E68NXTRSL
PUSH DE
Save the contents of Register Pair DE (i.e., the current LINE NUMBER ACCUMULATOR, which would be NN on the first run if passed through) to the top of the stack.
Original Source Code Comment: SAVE CURRENT LINE ACCUM
4E69
LD E,(HL)
Fetch the LSB of the value held in the memory location pointed to by Register Pair HL (i.e., the RAM location of the first line to renumber on the first pass, or the LINK FIELD for all other passes) and store it into Register E. This puts the LINK FIELD into (DE).
Original Source Code Comment: GET LINK FIELD INTO (DE)
4E6A
LD A,E
Prepare to test for a zero. First copy the contents of Register E into Register A.
Original Source Code Comment: GET LOW PART INTO K(A) FOR ZERO TEST
4E6B
INC HL
INCrement the Register Pair HL by 1.
4E6C
LD D,(HL)
Fetch the MSB of the LINK FIELD (held in the memory location pointed to by Register Pair HL) and store it into Register D.
Original Source Code Comment: GET HIGH PART OF LINK
4E6D
OR D
OR Register D against Register A (which is Register E). The results are stored in Register A.
Original Source Code Comment: SET CC'S ON LINK FIELD
4E6E
EX DE,HL
EXchange the value stored in Register Pair HL (i.e., the LINK FIELD) with the value stored in Register Pair DE (i.e., the value of the next link field)
Original Source Code Comment: SEE IF NEXT LINK ZERO
4E6F
POP DE
Put the LINE NUMBER ACCUMULATOR (held at the top of the STACK) into Register Pair DE, and then remove the entry from the stack.
Original Source Code Comment: GET BACK ACCUM LINE #
4E70
If the next link is 0, then the Z FLAG (Zero) will have been set, and we are done. JUMP to 4E79H.
Original Source Code Comment: ZERO, DONE
4E72
LD A,(HL)
Fetch the first byte of the link (held in the memory location pointed to by Register Pair HL) and store it into Register A.
Original Source Code Comment: GET FIRST BYTE OF LINK
4E73
INC HL
INCrement the value stored in Register Pair HL by 1 to point to the character after the one we just fetched into Register A.
Original Source Code Comment: INCPOINTER
4E74
OR (HL)
Test to see if the next character is 00H by OR'ing Register A against the value of the next character in the program. If that next character was 00H then Register A will be unchanged, and the Z Flag will be set.
Original Source Code Comment: SET CC'S
4E75
DEC HL
DECrement the pointer (stored in Register Pair HL) by 1.
Original Source Code Comment: MOVE POINTER BACK
4E76
EX DE,HL
Put the pointer into Register Pair DE.
Original Source Code Comment: BACK IN (DE)
4E77
If the NZ FLAG (Not Zero) has been set then we are good to process, so JUMP to 4E5AH to increment the line number accumulator.
Original Source Code Comment: INC COUNT
4E79RESSD1
PUSH BC
Save the INC (held in Register Pair BC) to the top of the stack.
Original Source Code Comment: SAVE INC
4E7A
Convert all line number references via a GOSUB to 4F97H.
Original Source Code Comment: CONVERT ALL LINE REFS TO LINCON LOW HIGH
4E7D
Scan the program, converting lines to pointers via a GOSUB to 4EA5H.
Original Source Code Comment: SCAN PROGRAM CONVERTING LINES TO PTRS.
4E80
LD HL,(63B8H)LD HL,(LINE1)
Fetch the starting line number position (held in memory location 63B8H) and store it into Register Pair HL.
Original Source Code Comment: FIND START PLACE TO RESEQUENCE
4E83
EX DE,HL
Put the starting line number position into Register Pair DE.
Original Source Code Comment: BY GETTING START LINE INTO (DE)
4E84
Search RAM for the starting line number (held in DE) via a GOSUB to the Model III ROM Routine at 1B2CH. Returns C/Z with the line found in BC, NC/Z with line number is too large and HL/BC having the next available location, or NC/NZ with line number not found, and BC has the first available one after that.
Original Source Code Comment: SINCE LINSCN MAY HAVE MOVED ITS POSITION
4E87
4E88
LD H,B
LD L,C
Copy BC (i.e., the location of the found line) into HL.
Original Source Code Comment: WANT RESULT IN (HL)
4E89
POP BC
Put "INC" (held at the top of the STACK) into Register Pair BC, and then remove the entry from the stack.
Original Source Code Comment: GET BACK INC
4E8A
POP DE
Put "NN" a/k/a LINE NUMBER (held at the top of the STACK) into Register Pair DE, and then remove the entry from the stack.
Original Source Code Comment: GET NN
4E8BRESNX1
PUSH DE
Save the LINE NUMBER (held in Register Pair DE) to the top of the stack.
Original Source Code Comment: SAVE CURRENT LINE
4E8C
LD E,(HL)
Now we need to process and review the LINK FIELD. First, fetch the LSB of the location in RAM of the line number we were looking for (held in the memory location pointed to by Register Pair HL) and store it into Register E.
Original Source Code Comment: GET LINK FIELD
4E8D
LD A,E
Prepare for a test against 0 by copying the contents of Register E into Register A.
Original Source Code Comment: PREPARE FOR ZERO LINK FIELD TEST
4E8E
INC HL
INCrement the value stored in Register Pair HL by 1 to point to the MSB of the location in RAM of the line number we were looking for.
4E8F
LD D,(HL)
Fetch the MSB of the location in RAM of the line number we were looking for (held in the memory location pointed to by Register Pair HL) and store it into Register E.
4E90
OR D
OR the MSB (Register D) against the LSB (Register A). The results are stored in Register A.
4E91
If the location in RAM of the line number we were looking for is ZERO, then we are at the end of the program, so JUMP to 4EA0H.
Original Source Code Comment: STOP RESEQING WHEN SEE END OF PGM
4E93
EX DE,HL
EXchange the value stored in Register Pair HL (i.e., the LINE POINTER) with the value stored in Register Pair DE (i.e., the LINK FIELD).
Original Source Code Comment: FLIP LINE PTR, LINE FIELD
4E94
EX (SP),HL
EXchange the value stored in Register Pair HL (i.e., the LINK FIELD) with the value stored at the top of the stack (i.e., the NEW LINE NUMBER).
Original Source Code Comment: PUT LINK ON STACK, GET NEW LINE # OFF
4E95
EX DE,HL
EXchange the value stored in Register Pair HL (i.e., the NEW LINE NUMBER) with the value stored in Register Pair DE (i.e., the LINE POINTER).
Original Source Code Comment: PUT NEW LINE# IN (DE) , THIS LINE
4E96
INC HL
INCrement the value stored in Register Pair HL by 1 to point to the line number field.
Original Source Code Comment: POINT TO LINE # FOELD
4E97
LD (HL),E
We now need to move the new line number (held in DE) into the HL pointer memory location. Store the LSB of the line number (held in Register E) into the memory location pointed to by Register Pair HL.
Original Source Code Comment: CHANGE TO NEW LINE#
4E98
INC HL
INCrement the value stored in Register Pair HL by 1.
4E99
LD (HL),D
Store the MSB of the line number (held in Register E) into the memory location pointed to by Register Pair HL.
4E9A
EX DE,HL
Put the new line number into HL.
Original Source Code Comment: GET THIS LINE# IN (HL)
4E9B
ADD HL,BC
LET Register Pair HL = Register Pair HL + Register BC (i.e., the "INC").
Original Source Code Comment: ADD INC
4E9C
EX DE,HL
Put the new line number back into DE.
Original Source Code Comment: GET NEW LINE # BACK IN (DE)
4E9D
POP HL
Put the pointer to the next line (held at the top of the STACK) into Register Pair HL, and then remove the entry from the stack.
Original Source Code Comment: GET PTR TO NEXT LINE
4E9E
Continue renumbering via a JUMP BACK to 4E8BH.
Original Source Code Comment: KEEP RESEQING

4EA0H - SCCALL - Convert all line numbers to pointers and back again; excluding "ON ERROR GOTO 0" which is left untouched.

4EA0SCCALL
LD BC,1A18HLD BC,STPRDY
Let Register Pair BC equal 1A18H, which is the Model III ROM Routine to POP BC and then return to BASIC's READY prompt.
Original Source Code Comment: WHERE TO GO WHEN DONE
4EA3
PUSH BC
Save the return address in BC to the top of the stack.
Original Source Code Comment: SAVE ON STACK
4EA4
4EA5SCCLIN
CP 0F6H
This is the classic Z-80 OR n opcode-swallow trick. The source defines two bytes back-to-back: DEFB 0FEH at 4EA4H followed by SCCLIN: DEFB 0F6H at 4EA5H. When execution falls through from above (i.e., after the PUSH BC at 4EA3H), the CPU sees the bytes FE F6 and decodes them as CP 0F6H — a 2-byte no-op that just clobbers the flags. When the routine is entered via CALL SCCLIN (i.e., a JUMP to 4EA5H), the CPU instead sees F6 AF and decodes them as OR 0AFH, which consumes the XOR A opcode (AFH) at 4EA6H as immediate data. In both paths the next instruction executed is LD (PTRFLG),A at 4EA7H, but the value of the A register and flags differs. This is how a single block of code serves both the SCCLIN (line# → pointer) and SCCPTR (pointer → line#) directions.
Original Source Code Comment: CALL SCCPTR
4EA6SCCPTR
XOR A
Set Register A to ZERO.
Original Source Code Comment: SET A=0
4EA7
LD (63B7H),ALD (PTRFLG),A
Store the value held in Register A into memory location 63B7H which is used to denote if we want LINE NUMBERS or POINTERS.
Original Source Code Comment: SET TO SAY WHETHER LINES OR PTRS EXTENT
4EAASCNPGM
LD HL,(40A4H)LD HL,(TXTTAB)
Fetch the 2 byte RAM location for the beginning of the BASIC Program from 40A4H.
Original Source Code Comment: GET PTR TO ASSTART OF PGM
4EAD
DEC HL
Back up to 1 byte before the BASIC program, since the next instruction is the start of a loop that BUMPS HL by 1.
Original Source Code Comment: NOP NEXT INC
4EAESCNPLN
INC HL
INCrement the value stored in Register Pair HL by 1 so as to point to the start of the next line in the program in RAM.
Original Source Code Comment: POINT TO BYTE AFTER ZERO AT END OF LINE
4EAF
LD A,(HL)
Fetch the value held in the memory location pointed to by Register Pair HL (i.e., the LINK FIELD) and store it into Register A.
Original Source Code Comment: GE LINK FIELD INTO (DE)
4EB0
INC HL
INCrement the value stored in Register Pair HL by 1 to point to the character after the one we just fetched into Register A.
4EB1
OR (HL)
Test to see if the next character is 00H by OR'ing Register A against the value of the next character in the program. If that next character was 00H then Register A will be unchanged, and the Z Flag will be set.
Original Source Code Comment: SET CC'S
4EB2
RET Z
If the Z FLAG (Zero) has been set then we are all done with the renumbering, so RETurn to the caller.
Original Source Code Comment: RETURN IF ALL DONE
4EB3
INC HL
IF we didn't return, then INCrement the value stored in Register Pair HL by 1 to go 1 byte past the line number.
Original Source Code Comment: POINT PAST LINE#
4EB4
LD E,(HL)
Fetch the LSB of the line number (memory location pointed to by Register Pair HL) and store it into Register E.
Original Source Code Comment: GET ;PW BYTE OF LINE #
4EB5
INC HL
INCrement the value stored in Register Pair HL by 1.
4EB6
LD D,(HL)
Fetch the MSB of the line number (memory location pointed to by Register Pair HL) and store it into Register D.
Original Source Code Comment: GET HIGH BYTE OF LINE #
4EB7SCNEXT
RST 10H
Call the EXAMINE NEXT SYMBOL routine at RST 10H.
NOTE:
  • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY FLAG if it is alphabetic, or sets it if is alphanumeric.
  • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
  • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
  • The string must be terminated by a byte of zeros.

Original Source Code Comment: GET NEXT CHAR FROM LINE
4EB8SCNEX2
OR A
Test to see if we are at the end of the line by setting the flags based on Register A as returned from the RST 10H call.
Original Source Code Comment: END OF LINE
4EB9
If the Z FLAG (Zero) has been set then we are at the end of the program line, so JUMP to 4EAEH to process the next line.
Original Source Code Comment: SCAN NEXT LINE
4EBBSCNEXX
LD C,A
Save the character returned from the RST 10H operation into Register C.
Original Source Code Comment: SAVE (A)
4EBC
LD A,(63B7H)LD A,(PTRFLG)
Fetch the value held in memory location 63B7H and store it into Register A to see whether we are converting to/from LINE NUMBERS and POINTERS.
Original Source Code Comment: CHANGE LINE TOKENS WHICH WAY?
4EBF
OR A
Since a LD command does not set any FLAGS, Set FLAGS based on the contents of Register A (and, in all events, clear the CARRY FLAG).
Original Source Code Comment: SET CC'S
4EC0
LD A,C
Put the character returned from the RST 10H operation back into Register A.
Original Source Code Comment: GET BACK CURRENT CHAR
4EC1
If the Z FLAG (Zero) has been set, then we are changing POINTERS into LINE NUMBERS. JUMP to 4F2AH.
Original Source Code Comment: CHANGING POINTERS TO #'S

This routine will convert LINE NUMBERS into POINTERS.

4EC4
CP 9EHCP ERROR1
Compare the value held in Register A against 9EH (BASIC Token: ERROR). If the current character is not the BASIC TOKEN for ERROR, the NZ FLAG will be set ...
Original Source Code Comment: IS IT ERROR TOKEN
4EC6
... so JUMP to 4EEAH to process it. Otherwise, we need to keep checking for the ON ERROR GOTO 0.
Original Source Code Comment: NO
4EC8
RST 10H
We next need to see if we have a "GOTO" token. Call the EXAMINE NEXT SYMBOL routine at RST 10H.
NOTE:
  • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY FLAG if it is alphabetic, or sets it if is alphanumeric.
  • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
  • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
  • The string must be terminated by a byte of zeros.

Original Source Code Comment: SCAN NEXT CHAR
4EC9
CP 8DHCP GOTO
Compare the value held in Register A against 8DH (BASIC Token: GOTO). If the current character is not the BASIC TOKEN for GOTO, the NZ FLAG will be set ...
Original Source Code Comment: ERROR GOTO?
4ECB
... JUMP to 4EB8H to process it. Otherwise, we need to keep checking for the ON ERROR GOTO 0.
Original Source Code Comment: GET NEXT ONE
4ECD
RST 10H
We next need to see what line number may be next, as we already have "ERROR GOTO". Call the EXAMINE NEXT SYMBOL routine at RST 10H.
NOTE:
  • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY FLAG if it is alphabetic, or sets it if is alphanumeric.
  • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
  • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
  • The string must be terminated by a byte of zeros.

Original Source Code Comment: GET NEXT CHAR
4ECE
CP 0EHCP LINCON
Compare the value held in Register A against 0EH, which is the LINE NUMBER CONSTANT. If the current character is not a LINE NUMBER CONSTANT, the NZ FLAG will be set ...
Original Source Code Comment: LINE # CONSTANT
4ED0
... JUMP to 4EB8H to process it.
Original Source Code Comment: NO , IGNORE.

If we are here then we have found "ERROR GOTO" and a line number constant. Need to see if this is the special case of a "0" or some other line number.

4ED2
PUSH DE
Save the contents of Register Pair DE to the top of the stack, as it is about to get used.
Original Source Code Comment: SAVE (DE)
4ED3
Get the line number after the "ERROR GOTO" and put it into Register Pair DE via a GOSUB to 4F71H.
Original Source Code Comment: GET IT
4ED6
4ED6
LD A,D
OR E
Since the Z-80 cannot test Register Pair DE against zero, the common trick is to set Register A to equal to Register D, and then OR A against Register E. Only if both Register D and Register E were zero can the Z FLAG be set.
Original Source Code Comment: IS IT LINE # ZERO
4ED8
If the NZ FLAG (Not Zero) has been set, then the line number is not 0; so we will want to change it to a pointer since we will be renumbering it. To do so, JUMP to 4EF3H.
Original Source Code Comment: CHANGE IT TO A POINTER
4EDA
PUSH HL
Save the contents of Register Pair HL to the top of the stack because we're about to use HL. Will POP it back at the end.
4EDB
LD HL,(CONTXT)
Fetch the value held in memory location 63BAH and store it into Register Pair HL.
Note: 63BAH is used in this Overlay to hold the current pointer in the BASIC Program.
Original Source Code Comment: GO BACK AND CHANGE TO ASCII '0'
4EDE
DEC HL
DECrement the value stored in Register Pair HL by 1.
Original Source Code Comment: LINE REFERENCE
4EDF
LD (HL),20H
Store a SPACE into the memory location pointed to by Register Pair HL.
4EE1
DEC HL
DECrement the value stored in Register Pair HL by 1.
Original Source Code Comment: SINCE LEAVING LINCON IN IS BAD
4EE2
LD (HL),20H
Store a SPACE into the memory location pointed to by Register Pair HL.
4EE4
DEC HL
DECrement the value stored in Register Pair HL by 1.
4EE5
LD (HL),30H
Store a 0 into the memory location pointed to by Register Pair HL.
4EE7
POP HL
Restore HL from the top of the STACK into Register Pair HL, and then remove the entry from the stack.
4EE8
Continue processing via a JUMP to 4F16H.
Original Source Code Comment: YES,CONT CHANGE IT

4EEAH - NTERRG - Continue converting LINE NUMBERS into POINTERS now that we know that we are not dealing with an ON ERROR.

4EEANTERRG
CP 0EHCP LINCON
Compare the value held in Register A against 0EH, which is the LINE NUMBER CONSTANT. If the current character is not a LINE NUMBER CONSTANT, the NZ FLAG will be set ...
Original Source Code Comment: LINE # CONSTANT
4EEC
... and we keep scanning by a JUMP BACK to 4EB7H.
Original Source Code Comment: NOT, KEEP SCANNING
4EEF
PUSH DE
If it WAS a line number constant, save the contents of Register Pair DE to the top of the stack.
Original Source Code Comment: SAVE (DE)
4EF0
Get the line number and put it into Register Pair DE via a GOSUB to 4F71H.
Original Source Code Comment: GET LINE#
4EF3CHGPTR
PUSH HL
Save the text pointer (held in Register Pair HL) to the top of the stack.
Original Source Code Comment: SAVE (HL)
4EF4
Search RAM for the starting line number (held in DE) via a GOSUB to the Model III ROM Routine at 1B2CH. Returns C/Z with the line found in BC, NC/Z with line number is too large and HL/BC having the next available location, or NC/NZ with line number not found, and BC has the first available one after that.
Original Source Code Comment: TRY TO FIND LINE IN PGM.
4EF7
DEC BC
DECrement the value stored in Register Pair BC (i.e., the found line nunber in RAM) by 1, so now BC will point to the 00H terminating the prior line.
Original Source Code Comment: POINT TO ZERO AT END OF PREVIOUS LINE
4EF8
LD A,0DHLD A,PTRCON
Let Register A equal 0DH to denote a POINTER instead of a LINE NUMBER CONSTANT.
Original Source Code Comment: CHANGE LINE # TO PTR
4EFA
If the C FLAG (Carry) has been set then the routine at 1B2CH found the line number, so we JUMP to 4F59H to change the LINE NUMBER to a POINTER.
Original Source Code Comment: IF LINE FOUND CHANGE # TO PTR
4EFD
If we are here, then 1B2CH didn't find the line number, which is a bad thing and we are going to error out. First, GOSUB to the Model III ROM Routine at 20F9H to see if we need to move to the next line on the screen, and if so, do it.
Original Source Code Comment: PRINT CRLF IF REQUIRED
4F00
LD HL,4F1BHLD HL,LINM
Let Register Pair HL equal 4F1BH to point to the "UNDEFINED LINE" error message.
Original Source Code Comment: PRINT "UNDEFINED LINE" MESSAGE
4F03
PUSH DE
Save the contents of Register Pair DE (i.e., the line number at issue) to the top of the stack.
Original Source Code Comment: SAVE LINE #
4F04
We want to do more than just display the error message. The routine at 28A7 in the Model III ROM will display the message pointed to by HL onto the current output device, BUT, if that message ends in an 0DH, the program takes the DOS exit at 41D0H.
Original Source Code Comment: POINT IT
4F07
POP HL
Put line number at issue (held at the top of the STACK) into Register Pair HL, and then remove the entry from the stack.
Original Source Code Comment: GET LINE # IN (HL)
4F08
Convert the value held in HL to ASCII and display that value via a GOSUB to the Model III ROM Routine at 0FAFH.
Original Source Code Comment: PRINT IT
4F0B
POP BC
Put the text pointer (held at the top of the STACK) into Register Pair BC, and then remove the entry from the stack.
Original Source Code Comment: GET TEXT PTR OFF STACK
4F0C
Replace the line number reference with 5 spaces via a GOSUB to 4F7DH.
Original Source Code Comment: SPACE OUT THE LINE REF
4F0F
POP HL
Put the current line number (held at the top of the STACK) into Register Pair HL, and then remove the entry from the stack.
Original Source Code Comment: GET CURRENT LINE#
4F10
PUSH HL
Put the current line number (held in Register Pair HL) to the top of the stack.
Original Source Code Comment: SAVE BACK
4F11
PUSH BC
Save the text pointer (held in Register Pair BC) to the top of the stack.
Original Source Code Comment: SAVE BACK TEXT PTR
4F12
Display the word "IN" and then the line number via a GOSUB to the Model III ROM Routine at 0FA7H.
Original Source Code Comment: PRINT IT
4F15SCNPOP
POP HL
Put the current text pointer (held at the top of the STACK) into Register Pair HL, and then remove the entry from the stack.
Original Source Code Comment: POP OFF CURRENT TEXT POINTER
4F16SCNEX3
POP DE
Put the current line number (held held at the top of the STACK) into Register Pair DE, and then remove the entry from the stack.
Original Source Code Comment: GET BACK CURRENT LINE#
4F17
DEC HL
Back up the current text pointer by 1 by DECrementing the value stored in Register Pair HL by 1.
Original Source Code Comment: BACKUP POINTER
4F18
Skip the scanning by JUMPing to 4EB7H.
Original Source Code Comment: SKIP SCANNING

4F1BH - LINM - "RENUM" Message Storage Area.

4F1BLINM
DEFM "Undefined line" + 00H

4F2AH - SCNPT2 - "RENUM" - Change POINTERS into LINE NUMBERS.

4F2ASCNPT2
CP 0DHCP PTRCON
Check to see if Register A equals 0DH to denote a POINTER instead of a LINE NUMBER CONSTANT.
Original Source Code Comment: POINTER
4F2C
If Register A did NOT designate a POINTER, then the NZ FLAG (Not Zero) will have been set, and we are NOT going to process this line. Instead JUMP to 4EB7H.
Original Source Code Comment: NO,SKIP SCANNING
4F2F
PUSH DE
Save the CURRENT LINE NUMBER (held in Register Pair DE) to the top of the stack.
Original Source Code Comment: SAVE CURRENT LINE #
4F30
Get the line number and put it into Register Pair DE via a GOSUB to 4F71H.
Original Source Code Comment: GET#
4F33
EX DE,HL
EXchange the value stored in Register Pair HL (i.e., the CURRENT TEXT POINTER) with the value stored in Register Pair DE (i.e., the LINE NUMBER).
Original Source Code Comment: FLIP CURRENT TEXT PTR & PTR
4F34
4F35
4F36
INC HL
INC HL
INC HL
Point HL to the line number field by INCrementing the value stored in Register Pair HL by 3.
4F37
LD C,(HL)
Fetch the LSB of the line number (held in the memory location pointed to by Register Pair HL) and store it into Register C.
Original Source Code Comment: PICK UP LINE #
4F38
INC HL
INCrement the value stored in Register Pair HL by 1 to point to the MSB of the line number.
Original Source Code Comment: POINT TO HIGH PART'
4F39
LD B,(HL)
Fetch the LSB of the line number (held in the memory location pointed to by Register Pair HL) and store it into Register B.
4F3A
EX DE,HL
Put the TEXT POINTER into DE.
Original Source Code Comment: GET POINTER TO TEXT BACK IN (HL)
4F3B
4F3C
LD H,B
LD L,C
Let HL = BC (i.e., the line number).
4F3D
Convert the value held in Register Pair HL into INTEGER and then into ASCII (held in Register Pair HL) via a GOSUB to 5088H.
Original Source Code Comment: OUTPUT INTO FBUFFER
4F40
EX DE,HL
Put the STRING NUMBER POINTER into Register Pair DE.
Original Source Code Comment: PUT STRING NUMBER POINTER IN (DE)
4F41
INC DE
INCrement the value stored in Register Pair DE by 1 to skip over the sign.
Original Source Code Comment: SKIP SIGN
4F42
LD HL,(CONTXT)
Fetch the pointer after the pointer (held in memory location 63BAH) and store it into Register Pair HL
Note: 63BAH is used in this Overlay to hold the current pointer in the BASIC Program.
Original Source Code Comment: GET POINTER AFTER POINTER
4F45
DEC HL
DECrement the value stored in Register Pair HL by 1 (now DE points to the LSB).
Original Source Code Comment: POINT AT LOW
4F46
DEC HL
DECrement the value stored in Register Pair HL by 1 (now DE points to the MSB).
Original Source Code Comment: POINT AT HIGH
4F47
DEC HL
DECrement the value stored in Register Pair HL by 1 (now DE points to the character before).
4F48
LD C,05H
We need to fill 5 characters so set Register C to 05H.
Original Source Code Comment: NUMBER OF CHARS TO FILL
4F4ALPLINI
LD A,(DE)
Top of a loop. Fetch the value held in the memory location pointed to by Register Pair DE and store it into Register A.
Original Source Code Comment: GET CHAR
4F4B
OR A
Since a LD command does not set any FLAGS, Set FLAGS based on the contents of Register A (and, in all events, clear the CARRY FLAG).
Original Source Code Comment: END OF LINE NUMBER
4F4C
If that character was 0, then we are at the end of the line, so JUMP to 4F69H to put in a space.
Original Source Code Comment: PUT SPACE IN
4F4E
LD (HL),A
Store the value held in Register A into the memory location pointed to by Register Pair HL.
Original Source Code Comment: STUFF LINE#
4F4F
INC HL
INCrement the value stored in Register Pair HL by 1.
4F50
INC DE
INCrement the value stored in Register Pair DE by 1.
4F51
DEC C
DECrement the value stored in Register C by 1.
4F52
If the NZ FLAG (Not Zero) has been set (meaning we still have more characters to process), LOOP BACK to 4F4AH.
4F54NINDON
POP DE
Put the line number (held at the top of the STACK) into Register Pair DE, and then remove the entry from the stack.
Original Source Code Comment: GET BACK THE LINE NUMBER
4F55
DEC HL
DECrement the value stored in Register Pair HL by 1.
Original Source Code Comment: AND CONTINUE SCAN
4F56
Continue scanning by JUMPing BACK to 4EB7H.

4F59H - MAKPTR - Change a LINE NUMBER to a POINTER.

4F59MAKPTR
LD HL,4F15HLD HL,SCNPOP
Let Register Pair HL equal 4F15H which will act as the RETURN JUMP POINT.
Original Source Code Comment: PLACE TO RETURN TO AFTER CHANGING CONSTANT
4F5C
PUSH HL
Save the return jump point to the top of the stack.
Original Source Code Comment: SAVE ON STACK
4F5DCONCHG
LD HL,(63BAH)LD HL,(CONTXT)
Fetch the value held in memory location 63BAH and store it into Register Pair HL
Note: 63BAH is used in this Overlay to hold the current pointer in the BASIC Program to the character after a constant.
Original Source Code Comment: GET TXT PTR AFTER CONSTANT IN (HL)
4F60CONCH2
PUSH HL
Save the contents of Register Pair HL to the top of the stack.
Original Source Code Comment: SAVE PTR TO END OF CONSTANT
4F61
DEC HL
DECrement the value stored in Register Pair HL by 1.
4F62
LD (HL),B
Store the MSB of the pointer (held in Register B) into the memory location pointed to by Register Pair HL.
4F63
DEC HL
DECrement the value stored in Register Pair HL by 1.
4F64
LD (HL),C
Store the LSB of the pointer (held in Register C) into the memory location pointed to by Register Pair HL.
4F65
DEC HL
DECrement the value stored in Register Pair HL by 1 to now point to the constant.
Original Source Code Comment: CHANGE TO VALUE IN (BC)
4F66
LD (HL),A
Change the constant to the value held in Register A.
Original Source Code Comment: CHANGE TO VALUE IN (A)
4F67
POP HL
Restore the pointer to the character after the constant from the top of the STACK into Register Pair HL, and then remove the entry from the stack.
Original Source Code Comment: RESTORE POINTER TO AFTER CONSTANT
4F68
RET
RETurn to the caller.

4F69H - NSPCFL - Non-Fast RENUM. Fills C characters of (HL) with a SPACE and then JUMPs to NSPCFL.

4F69NSPCFL
LD (HL),20H
Top of a loop. Store a SPACE into the memory location pointed to by Register Pair HL.
Original Source Code Comment: FILL OUTLINE NUMBER WITH SPACES
4F6B
INC HL
INCrement the value stored in Register Pair HL by 1.
4F6C
DEC C
DECrement the value stored in Register C by 1.
4F6D
If the counter in C has not yet hit zero, LOOP BACK to 4F69H.
4F6F
JUMP BACK to 4F54H.

4F71H - LINGT3 - Get the line number pointed to by Register Pair HL - 1 and put it into Register Pair DE and then run a RST 10H to get the next character into Register A.

4F71LINGT3
INC HL
INCrement Register Pair HL by 1 to point to the next character in the BASIC program, which will be the LSB of the line number.
Original Source Code Comment: PICK UP THE LINE NUMBER
4F72
LD E,(HL)
Fetch the LSB of the line number pointed to by Register Pair HL and store it into Register E.
4F73
INC HL
INCrement Register Pair HL by 1 to point to the next character in the BASIC program, which will be the MSB of the line number.
4F74
LD D,(HL)
Fetch the MSB of the line number pointed to by Register Pair HL and store it into Register D.
4F75
INC HL
INCrement Register Pair HL by 1 to point to the next character in the BASIC program.
Original Source Code Comment: SET UP TEXT POINTER AFTER
4F76
LD (63BAH),HLLD (CONTXT),HL
Store the current pointer in the BASIC Program (held in Register Pair HL) into memory location 63BAH
Note: 63BAH is used in this Overlay to hold the current pointer in the BASIC Program.
4F79
DEC HL
Back up the pointer held in HL in preparation for the RST 10H.
4F7A
JUMP to 1D78H to get a character from the BASIC program in RAM (which is the command line calling for the RENUMBER) via a call the EXAMINE NEXT SYMBOL routine at RST 10H. Since this ia JUMP, the RET at the end of the RST 10H will RETurn from this subroutine.

4F7DH - SPCOTL - Fill (BC), which points to the line number in the program, with 5 SPACES.

4F7DSPCOTL
PUSH DE
Save the contents of Register Pair DE to the top of the stack.
Original Source Code Comment: FILL NXM WITH SPACES
4F7E
PUSH BC
Save the contents of Register Pair BC (which is the text pointer) to the top of the stack.
4F7F
LD A,20H
Let Register A equal SPACE.
4F81
LD E,05H
Set up for a loop of 5 iterations by setting Register E to 05H.
4F83LPSPCI
DEC BC
Top of a loop of 5 iterations. DECrement the value stored in Register Pair BC by 1.
4F84
LD (BC),A
Store the value held in Register A into the memory location pointed to by Register Pair BC.
4F85
DEC E
DECrement the value stored in Register E by 1.
4F86
If E hasn't counted down fully from 5, LOOP BACK to 4F83H.
4F88
POP BC
Restore BC from the stach.
4F89
POP DE
Restore DE from the stach.
4F8A
RET
RETurn to the caller.

4F8BH - TOKLST - RENUM Token List.

4F8BTOKLST
DEFB B7H
Token for AUTO command.
4F8C
DEFB B6H
Token for DELETE command.
4F8D
DEFB 9DH
Token for EDIT command.
4F8E
DEFB 9FH
Token for RESUME command.
4F8F
DEFB C2H
Token for ERL command.
4F90
DEFB 8EH
Token for RUN command.
4F91
DEFB B4H
Token for LIST command.
4F92
DEFB B5H
Token for LLIST command.
4F93
DEFB 8DH
Token for GOTO command.
4F94
DEFB CAH
Token for THEN command.
4F95
DEFB 91H
Token for GOSUB command.
4F96
DEFB 95H
Token for ELSE command.

4F97H - LINSCN - Convert all line number references to a binary line number + 2 spaces

4F97LINSCN
LD HL,(40A4H)LD HL,(TXTTAB)
Fetch the 2 byte RAM location for the beginning of the BASIC Program from 40A4H.
Original Source Code Comment: START AT THE START AND CONVERT ALL LINE REFS
4F9APNXTLN
LD A,(HL)
Fetch a character in the BASIC PROGRAM (at the memory memory location pointed to by Register Pair HL) and store it into Register A.
Original Source Code Comment: TO LINCON BINARY LINE NUMBER AND 2 SPACES
4F9B
INC HL
INCrement the value stored in Register Pair HL by 1 to point to the character after the one we just fetched into Register A.
4F9C
OR (HL)
Test to see if the next character is 00H by OR'ing Register A against the value of the next character in the program. If that next character was 00H then Register A will be unchanged, and the Z Flag will be set.
4F9D
If the next character in the program is a 00H then we are done, so JUMP to 4FDBH.
Original Source Code Comment: DONE,JUST CLEAN UP
4F9F
4FA0
4FA1
INC HL
INC HL
INC HL
INCrement the value stored in Register Pair HL by 3 to point to the first character after the line number.
Original Source Code Comment: SKIP LINE NUMBER
4FA2PNXTCH
LD A,(HL)
Fetch a character in the BASIC PROGRAM (at the memory memory location pointed to by Register Pair HL) and store it into Register A.
4FA3
OR A
Since a LD command does not set any FLAGS, Set FLAGS based on the contents of Register A (and, in all events, clear the CARRY FLAG).
Original Source Code Comment: END OF LINE?
4FA4
INC HL
INCrement the value stored in Register Pair HL by 1 to point to the character after the one we just fetched into Register A.
4FA5
If the Z FLAG (Zero) has been set, JUMP to 4F9AH to process the next line in the program.
Original Source Code Comment: GO TO THE NEXT LINE
4FA7
If the P FLAG has SET, LOOP BACK 5 instructions to 4FA2H to process the next character.
4FAAISTOKN
DEC HL
Back up HL to point to the prior character by DECrementing the value stored in Register Pair HL by 1.
4FAB
LD DE,TOKLST
Let Register Pair DE point to the TOKEN LIST at 4F8BH.
Original Source Code Comment: CHECK TOKEN LIST
4FAE
LD C,0CHLD C,TOKLEN
The TOKEN LIST is 12 long so set Register C equal 0CH.
4FB0LOPTKS
LD A,(DE)
Top of a loop to examine the tokens. First, fetch a token (i.e., the value held in the memory location pointed to by Register Pair DE) and store it into Register A.
Original Source Code Comment: GET A TOKEN
4FB1
CP (HL)
Compare the token from the list agains the token in the program as pointed to by (HL). Results: If Register A equals the value held in Register HL, the Z FLAG is set; otherwise the NZ FLAG is set.
4FB2
If the Z FLAG (Zero) has been set, JUMP to 4FFEH.
4FB4
INC DE
If they didn't match, then move to the next token in the list by INCrementing the value stored in Register Pair DE by 1.
4FB5
DEC C
Reduce the loop counter by DECrementing the value stored in Register C by 1.
4FB6
If we haven't parsed all 12 token in the token list then LOOP BACK to 4FB0H.
4FB8
LD A,(HL)
Fetch a character in the BASIC PROGRAM (at the memory memory location pointed to by Register Pair HL) and store it into Register A.
4FB9
CP 89HCP INPUT
Compare that character against the token for the INPUT command.
4FBB
INC HL
INCrement the value stored in Register Pair HL by 1 to point to the next character in the BASIC Program.
Original Source Code Comment: NOT A SPECIAL CHAR -- GO TO NEXT
4FBC
If the NZ FLAG (Not Zero) has been set, then we didn't have an INPUT, so JUMP to 4FA2H to process the next character.

If we're here, then we got an INPUT, but now we need to check to see if it was INPUT # or not.

4FBE
PUSH HL
Save the location of the character in the BASIC Program being examined in case it turns out not to be a INPUT # LEN <FORMULA>, <LINE NUMBER>; command and we need to process what we thought might have been the #.
Original Source Code Comment: SAVE TEXT IN CASE OF NOT UNPUT # LINE
4FBF
DEC HL
Move back 1 character in the BASIC program by DECrementing the value stored in Register Pair HL by 1.
Original Source Code Comment: CHECK FOR ALL THE STUFF
4FC0
RST 10H
Call the EXAMINE NEXT SYMBOL routine at RST 10H.
NOTE:
  • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY FLAG if it is alphabetic, or sets it if is alphanumeric.
  • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
  • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
  • The string must be terminated by a byte of zeros.
4FC1
CP 23H
Compare the value held in Register A against 23H (ASCII: #). If the character following the INPUT wasn't a # ...
4FC3
... JUMP to 4FD7H to restore HL to after the INPUT token and continue processing the BASIC program line.
Original Source Code Comment: NOT INPUT #LEN <FORMULA>,<LINE#>;

If we're here, then we got an INPUT #, but now we need to check to see if it was INPUT # LEN or not.

4FC5
RST 10H
Call the EXAMINE NEXT SYMBOL routine at RST 10H.
NOTE:
  • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY FLAG if it is alphabetic, or sets it if is alphanumeric.
  • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
  • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
  • The string must be terminated by a byte of zeros.
4FC6
CP 0F3HCP LEN
Compare the value held in Register A against 0F3H (BASIC Token: LEN). If the character following the INPUT # wasn't a LEN ...
4FC8
... JUMP to 4FD7H to restore HL to after the INPUT token and continue processing the BASIC program line.

If we're here, then we got an INPUT # LEN, but now we need to check to see if it was INPUT # LEN , or not.

4FCALOPCML
RST 10H
Call the EXAMINE NEXT SYMBOL routine at RST 10H.
NOTE:
  • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY FLAG if it is alphabetic, or sets it if is alphanumeric.
  • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
  • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
  • The string must be terminated by a byte of zeros.
4FCB
If there was no next character, and we ended with INPUT # LEN, JUMP to 4FD7H to restore HL to after the INPUT token and continue processing the BASIC program line.
4FCE
CP 2CH
Compare the value held in Register A against 2CH (ASCII: ,). If the character following INPUT # LEN was NOT a , ...
4FD0
... JUMP to 4FCAH.
4FD3
POP AF
Get rid of the location of the character in the BASIC Program being examined held at the top of the stack, because we don't need it, as we have found INPUT #LEN ,, which would need to be followed by a line number.
Original Source Code Comment: GET RID OF SAVED TEX POINTER SINCE WE FOUND
4FD4
JUMP to LINFOL to process that line number.
Original Source Code Comment: INPUT #LEN< FRM>,<LINE#> GO SCAN THE LINE #

4FD7H - NOILEN - This is an exit to the prior routine where we ultimately figured out we were not going to be processing a "INPUT #LEN <FORMULA>, <LINE NUMBER>" command.

4FD7NOILEN
POP HL
Restore the pointer to the location of the character in the BASIC Program into Register Pair HL. This would be the character after the span class="code">INPUT token.
Original Source Code Comment: GET POINTER AT INPUT BACK
4FD8
JUMP to 4FA2H to process the next character in the BASIC program.

4FDBH - DOCNVR - Part of the "Convert all line number references to a binary line number + 2 spaces" routine if we have determined that the next character is the end of the program.

4FDBDOCNVR
LD HL,(40A4H)LD HL,(TXTTAB)
Fetch the 2 byte RAM location for the beginning of the BASIC Program from 40A4H.
Original Source Code Comment: GET START
4FDE
EX DE,HL
EXchange the value stored in Register Pair HL (i.e., the start of the BASIC program) with the value stored in Register Pair DE.
4FDFLCHEAD
4FE0
LD H,D
LD L,E
Let HL = DE.
4FE1
LD A,(HL)
Fetch a byte of the BASIC program (held in the memory location pointed to by Register Pair HL) and store it into Register A.
4FE2
INC HL
INCrement the value stored in Register Pair HL by 1 to point to the character after the one we just fetched into Register A.
4FE3
OR (HL)
Test to see if the next character is 00H by OR'ing Register A against the value of the next character in the program. If that next character was 00H then Register A will be unchanged, and the Z Flag will be set.
4FE4
If the Z FLAG (Zero) has been set, JUMP to 5067H to zero out the ARRAY variable table and RETurn.
4FE7
4FE8
4FE9
INC HL
INC HL
INC HL
INCrement the value stored in Register Pair HL by 3 to point to the first character after the line number.
4FEALZLOOP
LD A,(HL)
Top of a loop. Fetch a byte of the BASIC program (held in the memory location pointed to by Register Pair HL) and store it into Register A.
4FEB
INC HL
INCrement the pointer in the BASIC program (stored in Register Pair HL) by 1.
4FEC
CP 0EHCP LINCON
Compare the value held in Register A against 0EH, which is the LINE NUMBER CONSTANT. If the current character is a LINE NUMBER CONSTANT, the Z FLAG will be set ...
4FEE
... so JUMP to the next routine at 4FF9H to skip over the 2 bytes of the line number and continue the loop.
4FF0
OR A
Set FLAGS based on the contents of Register A (and, in all events, clear the CARRY FLAG).
4FF1
If the NZ FLAG (Not Zero) has been set, JUMP to the top of this loop at 4FEAH.

The next instructions swap out the line number with the binary version.

4FF3
EX DE,HL
EXchange the value stored in Register Pair HL (i.e., the pointer in the BASIC Program) with the value stored in Register Pair DE.
4FF4
LD (HL),E
Store the value held in Register E into the memory location pointed to by Register Pair HL.
4FF5
INC HL
INCrement the value stored in Register Pair HL by 1.
4FF6
LD (HL),D
Store the value held in Register D into the memory location pointed to by Register Pair HL.
4FF7
LOOP back to 4FDFH.

4FF9H - TWOINX - Part of the "Convert all line number references to a binary line number + 2 spaces" routine if the chararacter in the BASIC program was a LINE NUMBER CONSTANT.

4FF9TWOINX
4FFA
INC HL
INC HL
INCrement the value stored in Register Pair HL by 2 to move the pointer in the BASIC program (held in Register Pair HL) past that line number constant.
4FFB
Continue processing by re-entering the loop at 4FEAH.

4FFDH - LINFL1 - Routine is out of sequence and is only called by 5049H if we determine the the character in A is not numeric

4FFDLINFL1
DEC HL
Back up the pointer in the BASIC program (stored in Register Pair HL) by 1 in preparation for the RST 10H command which advances HL.
4FFELINFOL
RST 10H
We are still looking for a line number. Call the EXAMINE NEXT SYMBOL routine at RST 10H.
NOTE:
  • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY FLAG if it is alphabetic, or sets it if is alphanumeric.
  • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
  • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
  • The string must be terminated by a byte of zeros.

Original Source Code Comment: GET CANDIDATE FOR LINE NUMBER
4FFF
PUSH HL
Save the pointer in the BASIC Program (stored in Register Pair HL) to the top of the stack.
5000
OR A
Set FLAGS based on the contents of Register A to see if we are at end of line (00H) or not. If we are at the end of the line ...
5001
... JUMP to 500CH since we don't need to check for a LINE FEED.

The LOKLF routine looks for a LINE FEED character.

5003LOKLF
INC HL
INCrement the pointer in the BASIC program (stored in Register Pair HL) by 1.
Original Source Code Comment: GO LOOK FOR A LINE FEED
5004
LD A,(HL)
Fetch a byte of the BASIC program (held in the memory location pointed to by Register Pair HL) and store it into Register A.
Original Source Code Comment: GET THE CHAR
5005
CP 0AH
Compare the value held in Register A against 0AH (ASCII: LINE FEED). If the current character in the BASIC program is a LINE FEED ...
Original Source Code Comment: CHECK FOR LINE FEED
5007
... replace it with a "*" and continue via a JUMP to 500FH.
5009
OR A
Set FLAGS based on the contents of Register A. If it is not end of line (i.e., 00H) ....
500A
LOOP back to the top of the LOKLF routine and keep looking for the LINE FEED.

Next we are going to put a "*" wherever there was a LINE FEED. If (HL) is not a line feed, then a dummy HL of 4121H is offered as the sacrificial location to put the "*".

500CNOLF
LD HL,4121HLD HL,FACLO
If (HL) wasn't pointing to a LINE FEED we don't want the next line to overwrite that character with a *, so let Register Pair HL equal 4121H as a dummy location to put the *.
500FCLRLF
LD (HL),2AH
Store a * into the memory location pointed to by Register Pair HL (which is either the dummy location if there wasn't a LINE FEED there, or to overwrite a LINE FEED if it was there).
5011
EX DE,HL
Put the value stored in Register Pair HL (which could be either 4121H or the position in the BASIC program AFTER searching for the LINE FEED) into DE. HL is discarded so it doesn't matter what was in DE.
5012
POP HL
Restore the pointer in the BASIC Program (before searching for the LF) held at the top of the STACK into Register Pair HL, and then remove the entry from the stack.
5013
PUSH HL
Save the pointer in the BASIC Program (before searching for the LF) to the top of the stack.
Original Source Code Comment: GET BACK START (HL)
5014
PUSH DE
Save the contents of Register Pair DE (which could be either 4121H or the position in the BASIC program AFTER searching for the LINE FEED) to the top of the stack.
5015
Convert the ASCII string pointed to by HL to an integer deposited into DE via a GOSUB to the Model III ROM routine at 1E5AH. After execution HL points to the delimiter and the A register contains the delimiter value. The Z flag is set if the delimiter equals 00 or 3A. Z is reset if any other delimiter is used. If the routine finds a non-numerical character, the conversion is stopped
5018
LD A,0AH
Let Register A equal 0AH (ASCII: LINE FEED.
501A
POP BC
Put the value held at the top of the STACK which could be either 4121H or the position in the BASIC program AFTER searching for the LINE FEED) into Register Pair BC, and then remove the entry from the stack.
501B
LD (BC),A
Restore the LINE FEED into the memory location pointed to by Register Pair BC.
Original Source Code Comment: RESTORE LINE FEED

Next we need to check to see if we advanced in the BASIC program.

501C
POP BC
Restore the pointer in the BASIC Program (before searching for the LF) held at the top of the STACK into Register Pair BC, and then remove the entry from the stack.
Original Source Code Comment: SEE IF ADVANCED
501D
LD A,L
Copy the contents of Register L (i.e., the current location in the program) into Register A.
Original Source Code Comment: CURRENT
501E
SUB C
Subtract the LSB from the program before searching for the LF from the LSB of the current location of the program, to see if we have moved. If this is NZ, there was a Line Feed.
Original Source Code Comment: MINUS PREVIOUS
501F
If the Z FLAG (Zero) has been set, go back to whence we came and continue processing characters via a JUMP to 5045H.
Original Source Code Comment: IF NON ZERO THERE WAS A LINE
5021
PUSH DE
Otherwise, save the LINE NUMBER (held in Register Pair DE) to the top of the stack.
Original Source Code Comment: SAVE THE LINE NUMBER

The next steps calculate the number of SPACES we need to add.

5022
LD E,A
Copy the contents of Register A into Register E.
Original Source Code Comment: CALCULATE SIZE LINE# - 5
5023
LD A,02H
Assume we want TWO spaces, so set Register A to 02H.
Original Source Code Comment: ASSUME PUT IN 2 SPACES
5025
PUSH AF
Save the contents of Register Pair AF to the top of the stack.
5026
LD A,05H
Let Register A equal 05H.
5028
SUB E
LET Register A = Register A - Register E. Register A now holds the number of spaces we need to insert to make room for a hard line number.
Original Source Code Comment: INTO (A)
5029
If the number spaces is still positive, JUMP to 5032H to move the program to make room for the line number.
502B
CPL
If, however, the number of spaces went negative because the line number was more than 5 characters including zeros and spaces, we need to make even more room. First, reverse each bit in Register A (which is the same as NOT) to become positive.
Original Source Code Comment: SINCE LINE # CAN BE
502C
INC A
INCrement the value stored in Register A by 1.
Original Source Code Comment: GREATER THAN FIVE CHARS. WITH LEADING ZEROS
502D
POP DE
Put the value held at the top of the STACK (which should be 02H) into Register Pair DE, and then remove the entry from the stack.
Original Source Code Comment: AND TRAILING SPACES WE MAY NEED EXTRA SPACES
502E
ADD A,02H
Add two assumed spaces by letting Register A = Register A + 02H.
Original Source Code Comment: PLUS THE ASSUMED 2
5030
PUSH AF
Save the space count (held in Register Pair AF) to the top of the stack.
Original Source Code Comment: SAVE SPACE COUNT
5031
XOR A
Set Register A to ZERO and clear all Flags.

Next we make room for the hard line number, put in the hard line number indicator byte, the line number, and then spaces to fill the remainder.

5032MOVPR2
PUSH BC
Save the location that the LINE VALUE CONSTANT is going to be placed (held in Register Pair BC) to the top of the stack.
Original Source Code Comment: SAVE START OF PUT PLACE
5033
If the NZ FLAG (Not Zero) has been set, ??? move (HL) for (A) bytes via a GOSUB to 5071H.
Original Source Code Comment: MOVE AT (HL) FOR (A) BYTES
5036
POP HL
Restore the pointer to the to the BASIC program (held at the top of the Stack) into Register Pair HL). This should be the 5 bytes that need to be replaced with an actual hard line number.
Original Source Code Comment: GET START OF 5 BYTES
5037
LD (HL),0EHLD (HL),LINCON
Store the flag for a LINE VALUE CONSTANT into the memory location pointed to by Register Pair HL.
5039
INC HL
INCrement the pointer to the BASIC program (held in Register Pair HL) by 1.
503A
POP BC
Restore the space count into Register B from the top of the STACK, as B acts as the counter of a DJNZ loop.
Original Source Code Comment: GET SPACE COUNT INTO (B)
503B
POP DE
Restore the LINE VALUE CONSTANT (held at the top of the STACK) into Register Pair DE, and then remove the entry from the stack.
Original Source Code Comment: GET BACK THE LINE NUMBER
503C
LD (HL),E
Store the LSB of LINE VALUE CONSTANT (held in Register E) into the BASIC Program at the memory location pointed to by Register Pair HL.
503D
INC HL
INCrement the pointer to the BASIC program (held in Register Pair HL) by 1.
503E
LD (HL),D
Store the MSB of LINE VALUE CONSTANT (held in Register D) into the BASIC Program at the memory location pointed to by Register Pair HL.
503FSPCPUR
INC HL
Top of a DJNZ loop. INCrement the pointer to the BASIC program (held in Register Pair HL) by 1.
5040
LD (HL),20H
Store a SPACE into the BASIC Program at the memory location pointed to by Register Pair HL.
5042
LOOP back to 503FH, reducing Register B each time, and continue to LOOP until Register B has been reduced to ZERO, in which case, continue with the next instruction.

The line number and spaces are now present. If passing through, we need to bump HL because the routine starts off by reducing it because the RST 10H needs it to be HL-1.

5044SNOLIN
INC HL
INCrement the value stored in Register Pair HL by 1.
5045NOLIN
DEC HL
DECrement the value stored in Register Pair HL by 1.
5046
RST 10H
Call the EXAMINE NEXT SYMBOL routine at RST 10H.
NOTE:
  • The RST 10H routine loads the next character from the string pointed to by the HL register into the A-register and clears the CARRY FLAG if it is alphabetic, or sets it if is alphanumeric.
  • Blanks and control codes 09H and 0BH are ignored causing the following character to be loaded and tested.
  • The HL register will be incremented before loading any character therfore on the first call the HL register should contain the string address minus one.
  • The string must be terminated by a byte of zeros.
5047
5048
INC A
DEC A
Set the Z or NZ flag based on the character in Register A.
5049
If the C FLAG (Carry) has been set then the character is alphabetic (and not alphanumeric), so JUMP to 4FFDH.
504B
INC HL
INCrement the pointer to the BASIC program (held in Register Pair HL) by 1.
504C
If the Z FLAG (Zero) has been set then the RST 10H returned a 0, which is end of line. With this, we need to move to process the next line via a JUMP to 4F9AH.

If we are here, we know that the character held in Register A is alphanumeric and not a 00H EOL marker.

504F
DEC HL
In preparation for the next set of tests which would need such thing, we do a one time DECrement the pointer to the BASIC program (held in Register Pair HL) by 1.
5050
CP 20H
Compare the value held in Register A against 20H (ASCII: SPACE) since we want to skip any between line separators. If there is a SPACE there ...
Original Source Code Comment: SKIP SEPERATORS OK BETWEEN LINES
5052
... push HL to point to the next character in the BASIC Program via a JUMP to 5044H.
5054
CP 2CH
Compare the value held in Register A against 2CH (ASCII: ,). If it is a , ...
5056
... push HL to point to the next character in the BASIC Program via a JUMP to 5044H.
5058
CP 0CEHCP MINUTK
Compare the value held in Register A against CEH (Decimal: 206). Results: If Register A equals 0CEH ...
505A
... push HL to point to the next character in the BASIC Program via a JUMP to 5044H.
505C
CP 0D4HCP GREATK
Compare the value held in Register A against D4H (Decimal: 212). If A < D4H, the CARRY FLAG will be set ...
505E
If the C FLAG (Carry) has been set, JUMP to 5064H to zero out the array variable table and RETurn.
5060
CP 0D7HCP LESSTK+1
Compare the value held in Register A against 0D7H (Decimal: 215). If A < 0D7H ...
5062
... push HL to point to the next character in the BASIC Program via a JUMP to 5044H.
5064GOPNXT
JUMP to 4FA2H to process the next character in the BASIC program.

5067H - CLEARZ - Zero out the ARRAY variable table and RETurn.

5067CLEARZ
LD HL,(40F9H)LD HL,(VARTAB)
Fetch the value held in memory location 40F9H and store it into Register Pair HL. 40F9H is commonly used to determine the location of the end of a BASIC program in RAM as it holds the starting address of the simple variables list table which is also one higher than the last of the three zero bytes marking the end of the BASIC program.
506A
LD (40FBH),HLLD (ARYTAB),HL
Store the END OF BASIC PROGRAM + 1 (held in Register Pair HL) into memory location 40FBH, which is the starting address of the ARRAY VARIABLE TABLE.
506D
LD (40FDH),HLLD (STREND),HL
Store the END OF BASIC PROGRAM + 1 (held in Register Pair HL) into memory location 40FDH, which is the ending address of the ARRAY VARIABLE TABLE (a/k/a start of free memory pointer).
5070
RET
RETurn to the caller.

5071H - MOVPRG - Routine to make room for line numbers. Moves the BASIC program down (A) bytes starting at (HL).

5071MOVPRG
PUSH HL
Save the pointer to the BASIC program (held in Register Pair HL) to the top of the stack.
Original Source Code Comment: SAVE STOP POINT
5072
LD HL,(40F9H)LD HL,(VARTAB)
Fetch the value held in memory location 40F9H and store it into Register Pair HL. 40F9H is commonly used to determine the location of the end of a BASIC program in RAM as it holds the starting address of the simple variables list table which is also one higher than the last of the three zero bytes marking the end of the BASIC program.
Original Source Code Comment: GET LAST TO MOVE'
5075
EX DE,HL
EXchange the value stored in Register Pair HL (i.e., the END OF BASIC PROGRAM pointer) with the value stored in Register Pair DE.
Original Source Code Comment: INTO (DE)
5076
5078
LD H,00H
LD L,A
Let Register Pair HL = the number of bytes to move the BASIC Program down (held in Register A).
Original Source Code Comment: CALCULATE TARGET FOR LAST
5079
ADD HL,DE
LET Register Pair HL = the offset (held in Register Pair HL) + the end of the BASIC Program in RAM (held in Register DE).
507A
LD (40F9H),HLLD (VARTAB),HL
Store the new end of the BASIC program in RAM into memory location 40F9H which houses that very information.
Original Source Code Comment: UPDATE VARTAB WITH NEWLENGTH
507D
507E
LD B,H
LD C,L
Let BC = the new end of the BASIC program in RAM (held in Register Pair HL).
Original Source Code Comment: (BC)=TARGET
507F
POP HL
Restore the currently being worked on pointer to the BASIC program (held at the top of the stack) into Register Pair HL, and then remove the entry from the stack.
Original Source Code Comment: GET BACK STOP POINT
5080LOPMVP
LD A,(DE)
Top of a loop that will ony exit if the variable address in DE and the variable address in HL are equal. Fetch a character from the BASIC program from the old end of the BASIC program in RAM (held in the memory location pointed to by Register Pair DE) and store it into Register A.
Original Source Code Comment: FETCH PROGRAM FROM ORIGINAL POS
5081
LD (BC),A
Store that character at the new end of the BASIC program (at the memory location pointed to by Register Pair BC).
5082
RST 18H
RST 18 to see if the variable address in HL is the same as in DE, so we call the COMPARE DE:HL routine, which numerically compares DE and HL. Will not work for signed integers (except positive ones). Uses the A-register only. The result of the comparison is returned in the status register as: CARRY SET=HL<DE; NO CARRY=HL>DE; NZ=Unequal; Z=Equal).
5083
RET Z
If the variable address in DE and the variable address in HL are equal, RETurn to the caller.
5084
5085
DEC DE
DEC BC
If the variable address in DE and the variable address in HL are NOT the same, DECrement the value stored in Register Pair DE and BC each by 1.
5086
LOOP BACK to 5080H.

5088H - LINDSP - Convert the value held in Register Pair HL into INTEGER and then into ASCII (held in Register Pair HL).

5088LINDSP
GOSUB to 0A9AH in the Model III ROM routine to put the value in HL into the single precision number storage area of 4121H and is flagged as an INTEGER.
508B
XOR A
Set Register A to ZERO.
508C
GOSUB to 1034H to turn off the EDIT flag and initialize the 4130H input buffer for a FLOATING POINT to ASCII conversion by putting a SPACE into 4130H.
508F
OR (HL)
Set the flags by merging the value held in Register A against the byte of the program pointed to by Register Pair HL.
5090
JUMP to 0FD9H in the Model III ROM to convert the integer value in 4124H to an ASCII string pointed to by Register Pair HL.

5093H - CMPRES - "COMPRESS" a BASIC Program Routine.

5093CMPRES
LD HL,(40A4H)LD HL,(TXTTAB)
Fetch the 2 byte RAM location for the beginning of the BASIC Program from 40A4H.
Original Source Code Comment: GET THE BEGINNING POINTER TO PGM
5096
LD (BUFPNT),HL
Store begining pointer to the BASIC program (held in Register Pair HL) into memory location 51AEH.
Original Source Code Comment: SAVE IT
5099
LD A,(HL)
Fetch the value held at the beginning of the BASIC program and store it into Register A.
Original Source Code Comment: SEE IF ANY PROGRAM HERE
509A
INC HL
INCrement the pointer to the BASIC program (held in Register Pair HL) by 1.
509B
OR (HL)
Set the flags by merging the first byte of the program (held in Register A) against the second byte of the program (in the memory location pointed to by Register Pair HL)
509C
RET Z
If the Z FLAG (Zero) has been set based on that OR, then there is no program present; so RETurn to the caller.
Original Source Code Comment: NO, EXIT

509DH - Continuation of "COMPRESS". We at least know that there is a program in RAM.

509D
LD A,E
Test to see if there are spaces, REMs, or both via the next few instructions. First, copy the contents of Register E into Register A. I have no idea how E is loaded, but if E is 0, it will handle SPACES, if E is 1, it will handle REMarks, and if E is 2, it will handle both.
Original Source Code Comment: SEE IF SPACES, REMARKS, OR BOTH
509E
ADD A,A
LET Register A = Register E * 2, as the SWITCH TABLE is a table of 2 byte addresses.
Original Source Code Comment: TIMES 2
509F
50A0
LD E,A
LD D,00H
Let Register Pair DE = old Register E * 2. This will serve as an offset in the SWITCH TABLE.
Original Source Code Comment: INTO DE
50A2
LD HL,SWTAB
Let Register Pair HL equal 50ABH which is a SWITCH TABLE.
Original Source Code Comment: HL => SWITCH TABLE
50A5
ADD HL,DE
LET Register Pair HL = the SWITCH TABLE (held in Register Pair HL) + and offset of either 0, 2, or 4 (held in Register Pair DE).
Original Source Code Comment: HL => THE OPTION(S)
50A6
LD E,(HL)
Fetch the LSB of the address from the SWITCH TABLE into Register E.
Original Source Code Comment: GET THE ADDRESS
50A7
INC HL
INCrement to the next byte of the SWITCH TABLE.
50A8
LD D,(HL)
Fetch the MSB of the address from the SWITCH TABLE into Register D.
50A9
EX DE,HL
Since there is no JP (DE) comment in the Z-80, we need to EXchange the value stored in Register Pair HL (i.e., the pointer to the MSB in the SWITCH TABLE) with the value stored in Register Pair DE (i.e., the address from the SWITCH TABLE).
Original Source Code Comment: INTO HL
50AA
JP (HL)
   [HL])
JUMP to the address from the SWITCH TABLE (held in Register Pair HL).
Original Source Code Comment: DO IT

50ABH - SWTAB - "COMPRESS" - Switch Table.

50ABSWTAB
DEFW 6C 51H
For Spaces
Original Source Code Comment: FOR SPACES
50AD
DEFW BAH 50H
For Remarks
Original Source Code Comment: FOR REMARKS
50AF
DEFW B1H 50H
For BOTH
Original Source Code Comment: FOR BOTH

50B1H - BOTH - Continuation of "COMPRESS" - Jump Table Point for BOTH

50B1BOTH
Process the compression for SPACE via a GOSUB to 516CH.
Original Source Code Comment: DO THE SPACES
50B4
LD HL,(40A4H)LD HL,(TXTTAB)
Since we're now going to pass through to REM, the pointers are no longer what they would have been if we jumped, so we need to fix that. Fetch the 2 byte RAM location for the beginning of the BASIC Program from 40A4H.
Original Source Code Comment: RESET THE POINTER
50B7
LD (BUFPNT),HL
Store the value held in Register Pair HL into memory location 51AEH.
Original Source Code Comment: FOR 'REM'

50BAH - REMARK - Continuation of "COMPRESS" - Jump Table Point for REMARK

This routine will remove all REMarks from a BASIC program. If REM is the first token on a line, the comment is removed but the REM stays (as there may be GOTOs to those lines). Otherwise, the :, the REM, and the comment are all struck.

50BAREMARK
LD HL,(BUFPNT)
Fetch the value held in memory location 51AEH and store it into Register Pair HL.
Original Source Code Comment: GET THE BUFFER POINTER
50BD
LD A,(HL)
Fetch a byte of the BASIC program (held in the memory location pointed to by Register Pair HL) and store it into Register A.
Original Source Code Comment: GET WHAT'S THERE
50BE
INC HL
INCrement the pointer to the BASIC program (held in Register Pair HL) by 1.
50BF
OR (HL)
Test to see if the next character is 00H by OR'ing Register A against the value of the next character in the program. If that next character was 00H then Register A will be unchanged, and the Z Flag will be set.
50C0
If the Z FLAG (Zero) has been set based on that OR, then there is no program present (or we are at the end of the program); so clean up (and return to BASIC) via a JUMP to 5136H.
Original Source Code Comment: END OF PGM. DO THE CLEAN UP
50C3
LD DE,0003H
Set up for an offset of 03 charagcters (Address of next line PLUS a line number) by setting Register Pair DE to 0003H.
Original Source Code Comment: ADDR OF NEXT LINE + LINE NUMBER
50C6
ADD HL,DE
LET Register Pair HL = the pointer to the BASIC program (held in Register Pair HL) + 03H (held in Register DE). HL now points to the first character of the line.
Original Source Code Comment: HL => 1ST CHAR OF LINE
50C7
LD E,00H
Prepare a counter by setting Register E to 00H.
Original Source Code Comment: SET A COUNTER
50C9REMAR1
LD A,(HL)
Fetch a byte of the BASIC program (held in the memory location pointed to by Register Pair HL) and store it into Register A.
Original Source Code Comment: GET THE CHAR
50CA
INC HL
INCrement the pointer to the BASIC program (held in Register Pair HL) by 1.
Original Source Code Comment: BUMP TO NEXT CHAR
50CB
OR A
Set FLAGS based on the contents of Register A to see if we are at the end of the line (Z) or not (NZ).
Original Source Code Comment: END OF LINE?
50CC
If we are not at the end of the program line yet JUMP to 50D3H to continue.
Original Source Code Comment: NO, CONTINUE
50CE
LD (BUFPNT),HL
If we are, however, at the end of the program line, then this program line is done; so set the buffer pointer (of 51AEH) to point to the next character of the program.
Original Source Code Comment: THIS LINE IS DONE. DO NEXT
50D1
JUMP to the top of this REMARK (at 50BAH) routine and keep processing, now with the new HL.

50D3H - REMAR2 - Continuation of "COMPRESS" routine processing REMarks. Jumped here if we are not at the end of the line and still need to process it.

50D3REMAR2
INC E
INCrement the counter (stored in Register E) by 1.
Original Source Code Comment: INC THE COUNTER
50D4
CP 93HCP REMTOK
Compare the value held in Register A against 93H (BASIC TOKEN: REM). If the character in the BASIC program pointed to by HL is a REM token ...
Original Source Code Comment: IS THIS A REMARK TOKEN?
50D6
... JUMP to 50E5H.
Original Source Code Comment: YES, EXIT
50D8
CP 27H
Compare the value held in Register A against 27H (ASCII: '). If the character in the BASIC program pointed to by HL is a ' token ...
Original Source Code Comment: MARK FOR REM
50DA
... JUMP to 50E5H.
Original Source Code Comment: YES, EXIT
50DC
LD B,22HLD B,QUOTE
Let Register B equal 22H (ASCII: ").
Original Source Code Comment: TO COMPARE BY
50DE
CP 22HCP QUOTE
Compare the character in the BASIC Program (held in Register A) against a (ASCII: "). If Register A is a " ...
Original Source Code Comment: IS IT A QUOTE?
50E0
... skip over it via a GOSUB to 511DH ...
Original Source Code Comment: YES, SKIP OVER IT
50E3
... and then LOOP BACK to process the next character via a JUMP to 50C9H.
Original Source Code Comment: LOOP TO NEXT CHAR

50E5H - REMAR3 - Continuation of "COMPRESS" routine processing REMarks. See if the REMark is at the beginning of the line or not.

50E5REMAR3
LD A,E
Copy the counter (in Register E) into Register A.
Original Source Code Comment: GET THE COUNTER
50E6
CP 01H
Check to see if the REMark token or character was in first position. If not then ...
Original Source Code Comment: WAS REMARK IN 1ST POSITION?
50E8
See what is after that REMark token via a JUMP to 50F4H.
Original Source Code Comment: NO, FIND WHAT'S BEHIND IT
50EA
LD A,(HL)
If, however, the first character was not a REM, keep processing characters by fetching a byte of the BASIC program (held in the memory location pointed to by Register Pair HL) and store it into Register A.
Original Source Code Comment: GET NEXT CHAR ON THE LINE
50EB
OR A
Since a LD command does not set any FLAGS, Set FLAGS based on the contents of Register A (and, in all events, clear the CARRY FLAG).
Original Source Code Comment: END OF LINE?
50EC
If that byte was NOT a zero, then we are NOT at the end of the line, so JUMP to 50FCH to clear the rest of the line.
Original Source Code Comment: NO, FLUSH THE LINE
50EE
INC HL
INCrement the pointer to the BASIC program (held in Register Pair HL) by 1.
Original Source Code Comment: BUMP TO ADDRESS
50EF
LD (51AEH),HLLD (BUFPNT),HL
Store the current character into 51AEH to be the new pointer (thus erasing everything after it).
Original Source Code Comment: SET NEW POINTER
50F2
JUMP to 50BAH to keep looking for REMarks.
Original Source Code Comment: LOOK FOR NEXT REMARK

50F4H - REMAR4 - Continuation of "COMPRESS" routine processing REMarks; deal with whatever followed the REM token.

50F4REMAR4
50F5
DEC HL
DEC HL
Back up the pointer to the BASIC program (held in Register Pair HL) by 1 to get to the :.
Original Source Code Comment: BACK UP TO THE REMARK TOKEN
50F6
LD A,(HL)
Fetch a byte of the BASIC program (held in the memory location pointed to by Register Pair HL) and store it into Register A. This should be a :.
Original Source Code Comment: GET IT
50F7
CP 3AHCP COLON
Compare the value held in Register A against 3AH (ASCII: :). If Register A equals : ...
Original Source Code Comment: IS IT A COLON?
50F9
... JUMP to 50FCH to continue.
Original Source Code Comment: YES, CONTINUE
50FB
INC HL
If Register A was not the : we expected, we need to leave that character alone by INCrementing the pointer to the BASIC program (held in Register Pair HL) by 1.
Original Source Code Comment: NO, LEAVE IT ALONE
50FCREMAR5
LD (HL),00H
End the program line by putting a 00H into the position in the BASIC program pointed to by Register Pair HL.
Original Source Code Comment: MAKE IT THE END OF THE LINE
50FE
INC HL
INCrement the pointer to the BASIC program (held in Register Pair HL) by 1 to now be the character after the REM.
Original Source Code Comment: BUMP TO CHAR AFTER REM
50FF
LD (TEMPX),HL
Store the pointer into memory location 51B0H.
Original Source Code Comment: SAVE THE POINTER

The next instructions move us to the end of the line.

5102
LD E,00H
Prepare a counter by setting Register E to 00H.
Original Source Code Comment: SET A COUNTER
5104REMAR6
LD A,(HL)
Top of a loop. Fetch a byte of the BASIC program (held in the memory location pointed to by Register Pair HL) and store it into Register A.
Original Source Code Comment: GET A TOKEN/CHAR
5105
OR A
Since a LD command does not set any FLAGS, Set FLAGS based on the contents of Register A (and, in all events, clear the CARRY FLAG).
Original Source Code Comment: END OF LINE?
5106
If the Z FLAG (Zero) has been set, then we are at the end of the line, so exit via a JUMP to 510CH.
Original Source Code Comment: YES, EXIT
5108
INC E
If we are, however, not at the end of the line, we need to keep going. INCrement the counter (stored in Register E) by 1.
Original Source Code Comment: INC THE COUNTER
5109
INC HL
INCrement the pointer to the BASIC program (held in Register Pair HL) by 1.
Original Source Code Comment: NO, BUMP POINTER
510A
LOOP BACK 6 instructions until we hit the end of the line via a JUMP to 5104H.
Original Source Code Comment: LOOP TILL FOUND

510CH - REMAR7 - Continuation of "COMPRESS" routine processing REMarks; deal with the end of line.

510CREMAR7
LD A,E
Copy the counter (from Register E) into Register A.
Original Source Code Comment: SET AS A COUNTER
510D
LD BC,(51B0H)LD BC,(TEMPX)
Fetch the "move to" pointer (held in memory location 51B0H) and store it into Register Pair BC.
Original Source Code Comment: GET THE 'MOVE TO' POINTER
5111
INC HL
INCrement the "move from" pointer (held in Register Pair HL) by 1.
Original Source Code Comment: INC THE 'MOVE FROM' POINTER
5112
Move the program down via a GOSUB to 5159H.
Original Source Code Comment: MOVE THE PROGRAM DOWN
5115
LD HL,(51B0H)LD HL,(TEMPX)
Fetch the "move to" pointer (held in memory location 51B0H) and store it into Register Pair HL.
Original Source Code Comment: GET THE NEXT LINE TO DO
5118
LD (51AEH),HLLD (BUFPNT),HL
Store "move to" pointer (held in Register Pair HL) and put it as the current line (being tracked in memory location 51AEH).
Original Source Code Comment: MAKE IT THE CURRENT LINE
511B
Move to the next line and keep processing by a JUMP BACK to 50BAH.
Original Source Code Comment: DO THE NEXT LINE

511DH - SKQUOT - Continuation of "COMPRESS" routine processing REMarks. Subroutine to skip over a QUOTE mark.

511DSKQUOT
LD A,(HL)
Fetch a byte of the BASIC program (held in the memory location pointed to by Register Pair HL) and store it into Register A.
Original Source Code Comment: GET NEXT CHAR
511E
INC HL
INCrement the pointer to the BASIC program (held in Register Pair HL) by 1.
Original Source Code Comment: BUMP TO NEXT ONE
511F
OR A
Set FLAGS based on the contents of Register A (and, in all events, clear the CARRY FLAG).
Original Source Code Comment: END OF LINE?
5120
If the NZ FLAG (Not Zero) has been set, then we are NOT at the end of the line, so JUMP to 5124H to check.
Original Source Code Comment: NO, DO CHECK
5122
SCF
Otherwise, we are at the end of the line and since the CARRY FLAG is going to be important, turn the CARRY FLAG on.
Original Source Code Comment: SET THE CARRY FLAG
5123
RET
RETurn to the caller.

5124H - SKQUO1 - Continuation of "COMPRESS" routine processing REMarks. Continuation of the subroutine to skip over a QUOTE mark if we are NOT at the end of line.

5124SKQUO1
INC E
INCrement the counter (stored in Register E) by 1.
Original Source Code Comment: INC THE COUNTER
5125
CP B
Compare the value held in Register A against the value held in Register B (which is a (ASCII: "). If the current character is a " ...
Original Source Code Comment: MATCH COMPARE VALUE?
5126
RET Z
... RETurn to the caller.
Original Source Code Comment: YES, EXIT
5127
... otherwise ..., we need to keep looking for the close quote via a JUMP BACK to 511DH.
Original Source Code Comment: NO, KEEP LOOKING

5129H - SKIPSP - Continuation of "COMPRESS" routine, but called later in the program. This subroutine skips space and tabs.

5129SKIPSP
LD A,(HL)
Fetch a byte of the BASIC program (held in the memory location pointed to by Register Pair HL) and store it into Register A.
Original Source Code Comment: GET A CHARACTER
512A
INC HL
INCrement the pointer to the BASIC program (held in Register Pair HL) by 1.
Original Source Code Comment: BUMP TO NEXT CHAR
512B
CP 20H
Compare the value held in Register A against 20H (ASCII: SPACE). If the current character is a SPACE ...
Original Source Code Comment: SPACE?
512D
... skip over it by JUMPing to the top of this subroutine.
Original Source Code Comment: YES, SKIP IT
512F
CP 09H
Compare the value held in Register A against 09H (ASCII: TAB). If the current character is a TAB ...
Original Source Code Comment: TAB?
5131
... skip over it by JUMPing to the top of this subroutine.
Original Source Code Comment: YES, SKIP IT
5133
DEC HL
If we're here, then we are at a character in the BASIC program we don't want remove, so back up the pointer to the BASIC program (held in Register Pair HL) by 1.
Original Source Code Comment: BACK UP TO THE NON-SPACE CHAR
5134
OR A
Before we return, we want to set the flags to see if we are at the END OF LINE (i.e., 00H), so do an OR A to set the Z FLAG.
Original Source Code Comment: SET Z IF END OF LINE
5135
RET
RETurn to the caller.
Original Source Code Comment: EXIT

5136H - DOCLN - Continuation of "COMPRESS" routine. Jumped to when it is time to clean up the linked addresses and then exit.

5136DOCLN
LD DE,(40A4H)LD DE,(TXTTAB)
Fetch the 2 byte RAM location for the beginning of the BASIC Program from 40A4H into Register Pair DE.
Original Source Code Comment: GET THE START OF THE PROGRAM
513ALDHEAD
513B
LD H,D
LD L,E
Let HL = DE.
Original Source Code Comment: MIRROR THE ADDRESS TO HL
513C
LD A,(HL)
Fetch a byte of the BASIC program (held in the memory location pointed to by Register Pair HL) and store it into Register A. This byte should be a LINKED ADDRESS.
Original Source Code Comment: GET THE ADDRESS THERE
513D
INC HL
INCrement the pointer to the BASIC program (held in Register Pair HL) by 1.
513E
OR (HL)
Test to see if the next character is 00H by OR'ing Register A against the value of the next character in the program. If that next character was 00H then Register A will be unchanged, and the Z Flag will be set.
Original Source Code Comment: END OF THE PROGRAM?
513F
Set the new END OF PROGRAM and EXIT TO BASIC via a JUMP to 514FH.
Original Source Code Comment: YES, SET THE NEW END
5141
5142
5143
INC HL
INC HL
INC HL
Bump past the 3 characters for a line number by INCrementing the pointer to the BASIC program (held in Register Pair HL) by 3.
Original Source Code Comment: BUMP PAST LINE NUMBER
5144LJLOOP
LD A,(HL)
Top of a 4 instruction loop. Fetch a byte of the BASIC program (held in the memory location pointed to by Register Pair HL) and store it into Register A.
Original Source Code Comment: GET A CHAR/TOKEN
5145
INC HL
INCrement the pointer to the BASIC program (held in Register Pair HL) by 1.
Original Source Code Comment: BUMP TO NEXT ONE
5146
OR A
Check to see if that prior byte (held in A) is an END OF LINE (i.e., 00H), and if NOT ...
Original Source Code Comment: END OF THIS LINE?
5147
LOOP BACK to 5144H.
Original Source Code Comment: NO, LOOP TILL END
5149
EX DE,HL
At this point, we are at the END OF A LINE and HL holds the byte after the END OF LINE BYTE. Put the LINKED ADDRESS into Register Pair DE.
Original Source Code Comment: GET THE NEW ADDRESS INTO DE
514A
LD (HL),E
Store the LSB of the LINKED ADDRESS held in Register E into the memory location pointed to by Register Pair HL.
Original Source Code Comment: SET THE LINKED ADDRESS
514B
INC HL
INCrement the value stored in Register Pair HL by 1.
514C
LD (HL),D
Store the MSB of the LINKED ADDRESS held in Register D into the memory location pointed to by Register Pair HL.
514D
LOOP BACK to the 2nd line of this routine (513AH) to cycle through the entire BASIC program.
Original Source Code Comment: LOOP THROUGH THE PROGRAM

514FH - CLEARY - Continuation of "COMPRESS" routine. We are done so set the RAM Pointers to the new End of Program and then EXIT to BASIC.

514FCLEARY
LD HL,(40F9H)LD HL,(VARTAB)
Fetch the value held in memory location 40F9H and store it into Register Pair HL. 40F9H is commonly used to determine the location of the end of a BASIC program in RAM as it holds the starting address of the simple variables list table which is also one higher than the last of the three zero bytes marking the end of the BASIC program.
Original Source Code Comment: RESET THE END POINTERS
5152
LD (40FBH),HLLD (ARYTAB),HL
Store the END OF BASIC PROGRAM + 1 (held in Register Pair HL) into memory location 40FBH, which is the starting address of the ARRAY VARIABLE TABLE.
5155
LD (40FDH),HLLD (STREND),HL
Store the END OF BASIC PROGRAM + 1 (held in Register Pair HL) into memory location 40FDH, which is the ending address of the ARRAY VARIABLE TABLE (a/k/a start of free memory pointer).
5158
RET
RETurn to BASIC.
Original Source Code Comment: EXIT BACK TO BASIC

5159H - MOVPGM - Subroutine in the COMPRESS" routine. This routine moves the BASIC program down starting at (HL) into (BC).

5159MOVPGM
PUSH HL
Save the "move from" address (held in Register Pair HL) to the top of the stack.
Original Source Code Comment: SAVE START POINT
515A
LD DE,(40F9H)LD DE,(VARTAB)
Fetch the END OF BASIC PROGRAM pointer from memory location 40F9H and store it into Register Pair DE.
Original Source Code Comment: GET THE END OF THE PROGRAM
515E
EX DE,HL
Since DE will always be bigger than HL, and the Z-80 does not have an instruction to subtract against DE, swap them.
Original Source Code Comment: (VARTAB ALWAYS BIGGER)
515F
OR A
The CARRY FLAG will be important here so clear the CARRY FLAG.
Original Source Code Comment: CLEAR CARRY
5160
SBC HL,DE
Calculate the number of bytes to move by SUBtracting DE from HL.
Original Source Code Comment: HL = NUMBER OF BYTES TO MOVE

The next instructions move all the variables around so that they fit into the LDIR mold.

5162
EX (SP),HL
EXchange the value stored in Register Pair HL (i.e., the number of bytes to move) with the value stored at the top of the stack (i.e., the MOVE FROM address).
Original Source Code Comment: SP=MOVE COUNT, HL=START POINTER
5163
5164
PUSH BC
POP DE
Copy the "move to" address (held in Register Pair BC) to Register Pair DE.
Original Source Code Comment: MOVE 'TO' POINTER TO DE
5165
POP BC
Put the the number of bytes to move ( held at the top of the STACK) into Register Pair BC, and then remove the entry from the stack.
Original Source Code Comment: GET THE MOVE COUNT INTO BC
5166
LDIR
Transfers a byte of data from the memory location pointed to by HL to the memory location pointed to by DE. Then HL and DE are incremented and BC is decremented. If BC is not zero, this operation is repeated. Interrupts can trigger while this instruction is processing.
Original Source Code Comment: MOVE THE PROGRAM DOWN
5168
LD (40F9H),HLLD (VARTAB),HL
Set the END OF BASIC PROGRAM pointer in RAM to the end of the code we just moved (held in Register Pair HL).
Original Source Code Comment: SET NEW END OF PROGRAM
516B
RET
RETurn to the caller.

516CH - SPACES - - Continuation of "COMPRESS" - Jump Table Point for CLEAR SPACES processing. Routine will clear out SPACES and TABS except inside QUOTES and FIELD statements.

516CSPACES
LD HL,(51AEH)LD HL,(BUFPNT)
Fetch the location in the BASIC program to process (held in memory location 51AEH) and store it into Register Pair HL.
Original Source Code Comment: GET THE BUFFER POINTER
516F
LD A,(HL)
Fetch a byte of the BASIC program (held in the memory location pointed to by Register Pair HL) and store it into Register A.
Original Source Code Comment: WE DONE?
5170
INC HL
INCrement the value stored in Register Pair HL by 1 to point to the character after the one we just fetched into Register A.
5171
OR (HL)
Test to see if the next character is 00H by OR'ing Register A against the value of the next character in the program. If that next character was 00H then Register A will be unchanged, and the Z Flag will be set.
5172
If the Z FLAG (Zero) has been set, we are at the end of the program so clean up (and return to BASIC) via a JUMP to 5136H.
Original Source Code Comment: YES, END OF PGM. DO CLEAN UP
5175
LD DE,0003H
We want to skip over the 3 bytes of a line number and space so set Register Pair DE = 0003H.
Original Source Code Comment: ADDRESS + LINE NUMBER
5178
ADD HL,DE
Advance our BASIC Pointer by 3 by setting Register Pair HL = Register Pair HL + Register DE.
5179SPACE1
LD A,(HL)
Top of a Loop. Fetch a byte of the BASIC program (held in the memory location pointed to by Register Pair HL) and store it into Register A.
Original Source Code Comment: GET A TOKEN
517A
INC HL
INCrement the value stored in Register Pair HL by 1 to point to the character after the one we just fetched into Register A.
Original Source Code Comment: BUMP TO NEXT CHAR
517B
OR A
Set FLAGS based on the contents of Register A.
Original Source Code Comment: END OF LINE?
517C
If the character is not an END OF LINE, JUMP to 5183H.
Original Source Code Comment: NO, PROCESS THE LINE
517E
LD (51AEH),HLLD (BUFPNT),HL
Save our current poition as the new line pointer in memory location 51AEH.
Original Source Code Comment: SET NEW LINE POINTER
5181
LOOP BACK to the top of this routine (516CH) to keep processing via the next line.
Original Source Code Comment: AND DO NEXT LINE

5183H - SPACE2 - Continuation of CLEAR SPACES subroutine of the "COMPRESS" routine. Jumped to if we are past the line number + space and NOT at end of line.

5183SPACE2
LD B,22HLD B,QUOTE
Let Register B equal ".
Original Source Code Comment: SET FOR QUOTE IN CASE
5185
CP 22HCP QUOTE
Compare the current character in the BASIC program (held in Register A) against 22H (ASCII: "). If it is a " ...
Original Source Code Comment: IS THIS A QUOTE?
5187
... skip over processing it via a JUMP to 518FH because we aren't removing spaces from quoted text.
Original Source Code Comment: YES, BYPASS IT
5189
LD B,3AHLD B,COLON
Let Register B equal :.
Original Source Code Comment: SET FOR COLON IN CASE
518B
CP 0A3HCP FLDTOK
Compare the value held in Register A against 0A3H (BASIC Token: FIELD). If the character of the BASIC program was not a FIELD token ...
Original Source Code Comment: FIELD STATEMENT?
518D
... continue with the removing of the spaces by JUMPing to 5199H.
Original Source Code Comment: NO, CONTINUE

We are here either because we jumped here from 5187 because we are inside a quote, or because we passed through and we hit a FIELD token. Either way, we want to skip over deleting the spaces.

518FDOSKIP
Skip over the spaces (and don't delete them) via a GOSUB to 511DH.
Original Source Code Comment: WAS QUOTE OR FIELD. SKIP OVER IT
5192
If the NC FLAG (No Carry) has been set by that routine, then we are NOT at the END OF LINE, so LOOP BACK to 5179H to keep processing.
Original Source Code Comment: NOT END OF LINE. KEEP LOOKING
5194
LD (BUFPNT),HL
If we're here then that routine indicated we are at the end of a line, so save our current position as the new line pointer in memory location 51AEH.
Original Source Code Comment: SET NEW LINE
5197
LOOP BACK to the very top of the compress spaces routine at 516CH.
Original Source Code Comment: AND CONTINUE

5199H - SPACE3 - Continuation of CLEAR SPACES subroutine of the "COMPRESS" routine. Jumped here if we know that we are not within a QUOTE or in a FIELD statement.

5199SPACE3
CP 20HCP SPACE
Compare the value held in Register A against 20H (ASCII: SPACE). If we are at a SPACE) ...
Original Source Code Comment: IS THIS A SPACE CHAR?
519B
... eliminate it via a JUMP to 51A1H.
Original Source Code Comment: YES, ELIMINATE IT
519D
CP 09H
Compare the value held in Register A against 09H (ASCII: TAB). If we are NOT at a TAB) ...
Original Source Code Comment: TAB?
519F
... move to the next character in the BASIC program via a JUMP to 5179H.
Original Source Code Comment: NO, GET NEXT CHAR

Actually elimiate the TAB or SPACE character.

51A1SPACE4
DEC HL
Back up the pointer to the BASIC program to the character to be deleted.
Original Source Code Comment: BACK UP TO THE SPACE
51A2
LD B,H
LD C,L
Let BC = HL so that BC also points to the character being deleted.
Original Source Code Comment: MIRROR POINTER TO BC
51A4
Skip over spaces and tabs via a GOSUB to 5129H which will adjust HL to point to the first non-space and non-tab character (and set the Z flag if we are at the END OF LINE). BC is not modified by that routine.
Original Source Code Comment: GET POINTER TO LAST SPACE
51A7
PUSH BC
Save the pointer to the character being deleted (held in Register Pair BC) to the top of the stack.
Original Source Code Comment: SAVE THE POINTER
51A8
Compress the program to eliminate the SPACE/TAB byte via a GOSUB to 5159H.
Original Source Code Comment: SQUISH THE PROGRAM DOWN
51AB
POP HL
Restore the pointer to the character being deleted from the top of the STACK into Register Pair HL, and then remove the entry from the stack.
Original Source Code Comment: GET POINTER BACK
51AC
Continue by jumping back into the main routine at 5179H.
Original Source Code Comment: AND CONTINUE

51AEH - BUFPNT - "COMPRESS" routine MESSAGE and BYTE storage area.

51AEBUFPNT
DEFS 02
51B0TEMPX
DEFS 02
 
END 4E00H
That's it!