Pub - beta

Various works which are, to my knowledge, no longer copyrighted

User Tools

Site Tools


wearmouth:version_2

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

wearmouth:version_2 [2022/03/22 09:24] – created evertwearmouth:version_2 [2022/03/22 09:33] (current) – external edit 127.0.0.1
Line 1: Line 1:
-2+<HTML> 
 +<pre> 
 +; Disassembly of the file "C:\lab\if1-2.rom" 
 +
 +; CPU Type: Z80 
 +
 +; Created with dZ80 1.50 
 +
 +; on Sunday, 28 of April 2002 at 12:35 PM 
 +
 + 
 +; ------------------------ 
 +; last updated 14-JAN-2004 
 +; ------------------------ 
 + 
 +#define DEFB .BYTE 
 +#define DEFW .WORD 
 +#define DEFM .TEXT 
 +#define EQU  .EQU 
 +#define ORG  .ORG 
 + 
 +        ORG     $0000 
 + 
 +; --------------------------------------- 
 +; FLAGS3 System Variable - IY+$7C ($5CB6) 
 +; --------------------------------------- 
 +; Bit 0 - set when executing an extended command. 
 +; Bit 1 - set during CRT-VARS and CLEAR #, CLOSE etc. 
 +; Bit 2 - settable by User to force the ERR_SP routine to handle errors. 
 +; Bit 3 - set when networking. 
 +; Bit 4 - set during LOAD and MOVE 
 +; Bit 5 - set during SAVE 
 +; Bit 6 - set during MERGE 
 +; Bit 7 - set during VERIFY 
 +
 +; <font color=#9900FF>Note.</font> before initialization of FLAGS_3, this is considered to be the first 
 +; byte of channels and so PEEK 23734 gives 244 decimal (%11110100) the high 
 +; order byte of the Main ROM address PRINT-OUT - $09F4. 
 +
 +; ------------------------------------------- 
 + 
 +; -------------------------------- 
 +; THE <b><font color=#333388>'RETURN TO MAIN ROM'</font></b> ROUTINE 
 +; -------------------------------- 
 +;   The system is initialized by the Main ROM so this address is accessed  
 +;   solely by a RST 00H instruction.  It is used from five locations to return  
 +;   to the Main ROM. 
 + 
 +<a name="L0000"></a>;; <b>MAIN-ROM</b> 
 +L0000:  POP     HL              ; discard the return address in this ROM. 
 +        LD      (IY+$7C),$00    ; reset all the bits of FLAGS_3. 
 +        JP      <A href="#L0700">L0700</a>           ; jump forward to UNPAGE address. 
 + 
 +; ------------------- 
 +; THE <b><font color=#333388>'START'</font></b> ROUTINE 
 +; ------------------- 
 +;   An instruction fetch on address $0008 pages in this ROM. 
 +;   The three-byte instruction at this location must exist on both sides of 
 +;   the looking-glass.  The value fetched is immediately discarded. 
 +;   It follows that this restart should never be invoked from this ROM. 
 + 
 +<a name="L0008"></a>;; <b>ST-SHADOW</b> 
 +L0008:  LD      HL,($5C5D)      ; fetch character address from CH_ADD. 
 +        POP     HL              ; pop return address to HL register. 
 +        PUSH    HL              ; and save again on machine stack. 
 + 
 +        JP      <A href="#L009A">L009A</a>           ; jump forward to continue at START-2. 
 + 
 +; ----------------------------- 
 +; THE <b><font color=#333388>'CALL A MAIN ROM'</font></b> ROUTINE 
 +; ----------------------------- 
 +;   Call an address in the main ROM. The address follows the restart so this 
 +;   is as convenient and as brief as a CALL instruction. 
 +;   The SBRT routine within the system variables area reads 
 +
 +;   L5CB9         LD      HL,value 
 +;   L5C5C         CALL    addr 
 +;   L5C5F         LD      (L5CB9+1),HL 
 +;   L5CC2         RET 
 +
 +;   By immediately placing the current value of HL in the subroutine, then 
 +;   all registers before the call are as they were before the RST 
 +;   instruction.  The value of HL after the call is stored immediately in 
 +;   this now redundant location so that, after this ROM is paged back in, 
 +;   the registers, after the RST instruction has executed, are as they were 
 +;   immediately after the CALL. 
 +;   see START-2. 
 + 
 +<a name="L0010"></a>;; <b>CALBAS</b> 
 +L0010:  LD      ($5CBA),HL      ; insert the current value of HL in the 
 +                                ; Z80 code to be picked up later. 
 + 
 +        POP     HL              ; drop the return address - the location 
 +                                ; of address to be called. 
 +        PUSH    DE              ; preserve the DE register contents. 
 + 
 +        JR      <A href="#L0081">L0081</a>           ; forward to continue at CALBAS-2. 
 + 
 +        DEFB    $FF             ; unused. 
 + 
 +; --------------------------------------------- 
 +; THE <b><font color=#333388>'TEST IF SYNTAX IS BEING CHECKED'</font></b> ROUTINE 
 +; --------------------------------------------- 
 +;   On the ZX80, testing the syntax flag was done with the 4-byte 
 +;   instruction that tests the System Variable FLAGS.  On the ZX81 and 
 +;   ZX Spectrum, a call to SYNTAX-Z reduced the invocation to a three-byte 
 +;   CALL.   Here it is reduced to a one-byte restart. 
 + 
 +<a name="L0018"></a>;; <b>CHKSYNTAX</b> 
 +L0018:  BIT     7,(IY+$01)      ; test most significant bit of FLAGS 
 +        RET                     ; return the result. 
 +                                ; (Z = Syntax, NZ = Run-time) 
 + 
 +        DEFB    $FF             ; unused. 
 +        DEFB    $FF             ; unused. 
 +        DEFB    $FF             ; unused. 
 + 
 +; -------------------------- 
 +; THE <b><font color=#333388>'SHADOW-ERROR'</font></b> ROUTINE 
 +; -------------------------- 
 +;   This is similar to the Main ROM error handler and the following byte  
 +;   indicates the type of error and in runtime the message that should be 
 +;   printed.  If checking syntax then the error pointer is set before a 
 +;   return is made to the Main ROM. 
 + 
 +<a name="L0020"></a>;; <b>SH-ERR</b> 
 +L0020:  RST     18H             ; checking syntax ? 
 +        JR      Z,<A href="#L0068">L0068</a>         ; forward, if so, to ST-ERROR 
 + 
 +        JR      <A href="#L003A">L003A</a>           ; forward, in run-time, to TEST-SP, 
 +                                ; and then REP-MSG 
 + 
 +        DEFB    $FF             ; unused. 
 +        DEFB    $FF             ; unused. 
 +        DEFB    $FF             ; unused. 
 + 
 +; ------------------------------------ 
 +; THE <b><font color=#333388>'MAIN ROM ERROR RESTART'</font></b> ROUTINE 
 +; ------------------------------------ 
 +;   This restart invokes the error handler of the Main 16K ROM.  The required  
 +;   error number is usually first placed in the System Variable ERR_NR.  In  
 +;   some cases the error code is already present and this restart is used when  
 +;   the error situations handled by this ROM have been eliminated. 
 +;   Since the exit from this point is by manipulating the stack, the return  
 +;   address is of no importance as that route is never taken.  There are also 
 +;   three conditional jumps back to this point. 
 + 
 +<a name="L0028"></a>;; <b>ROMERR</b> 
 +L0028:  RES     3,(IY+$02)      ; update TV_FLAG - signal no change in mode. 
 +        JR      <A href="#L0040">L0040</a>           ; forward to RMERR-2. 
 + 
 +        DEFB    $FF             ; unused. 
 +        DEFB    $FF             ; unused. 
 + 
 +; ------------------------------------------------- 
 +; THE <b><font color=#333388>'CREATE NEW SYSTEM VARIABLES RESTART'</font></b> ROUTINE 
 +; ------------------------------------------------- 
 +;    This restart is used the first time that that the ROM is paged in to 
 +;    create the System Variables.  This will be either by an instruction 
 +;    fetch on $0008 or $1708. 
 + 
 +<a name="L0030"></a>;; <b>NEWVARS</b> 
 +L0030:  JP      <A href="#L01F7">L01F7</a>           ; jump to CRT-VARS 
 + 
 +        DEFB    $FF             ; unused. 
 +        DEFB    $FF             ; unused. 
 +        DEFB    $FF             ; unused. 
 +        DEFB    $FF             ; unused. 
 +        DEFB    $FF             ; unused. 
 + 
 +; -------------------------------- 
 +; THE <b><font color=#333388>'MASKABLE INTERRUPT'</font></b> ROUTINE 
 +; -------------------------------- 
 +;   There is no service routine but should the routine be called either 
 +;   directly or by straying into a RST $38 instruction, then interrupts are 
 +;   enabled. 
 + 
 +<a name="L0038"></a>;; <b>INT-SERV</b> 
 +L0038:  EI                      ; Enable Interrupts 
 +        RET                     ; return. 
 + 
 + 
 +; ------------------------ 
 +; THE <b><font color=#333388>'TEST SYSTEM'</font></b> BRANCH 
 +; ------------------------ 
 +;   This branch allows the user to trap errors before this ROM is used to print 
 +;   the error report.  
 + 
 +<a name="L003A"></a>;; <b>TEST-SP</b> 
 +L003A:  CALL    <A href="#L0077">L0077</a>           ; routine CHECK-SP 
 +                                ; usually returns. 
 +        JP      <A href="#L0260">L0260</a>           ; jump to REP-MSG 
 + 
 +; ---------------------------- 
 +; THE <b><font color=#333388>'MAIN ROM ERROR'</font></b> ROUTINE 
 +; ---------------------------- 
 +;   a continuation of RST 28H. 
 +;   This ROM has inserted a Main ROM error code into ERR_NR and the routine in  
 +;   the Main ROM is now invoked. 
 +;   First a check is made to see if the user wishes to trap errors using a  
 +;   custom routine in ERR_SP.  This will be used in the syntax path anyway. 
 +;  
 + 
 +<a name="L0040"></a>;; <b>RMERR-2</b> 
 +L0040:  RST     18H             ; checking syntax ? 
 +        JR      Z,<A href="#L0068">L0068</a>         ; forward, if so, to ST-ERROR. 
 + 
 +        CALL    <A href="#L0077">L0077</a>           ; routine CHECK-SP allows the user to trap  
 +                                ; run-time errors at this point but normally  
 +                                ; returns here. 
 + 
 +        CALL    <A href="#L17B7">L17B7</a>           ; routine RCL-T-CH reclaims any temporary 
 +                                ; channels and stops all microdrive motors. 
 + 
 +        BIT     1,(IY+$7C)      ; test FLAGS_3. 
 +        JR      Z,<A href="#L0068">L0068</a>         ; forward, if executing CLOSE, to ST-ERROR. 
 + 
 +        BIT     4,(IY+$7C)      ; test FLAGS_3 - loading filename 'run'
 +        JR      Z,<A href="#L0068">L0068</a>         ; forward, if not, to ST-ERROR. 
 + 
 +;   As a security measure, the file 'run' can not be hacked. 
 + 
 +        LD      A,(IY+$00)      ; fetch error number from the System Variable 
 +                                ; ERR_NR. 
 +        CP      $14             ; is it "CODE error" ? 
 +        JR      NZ,<A href="#L0068">L0068</a>        ; forward, if not, to ST-ERROR. 
 + 
 +;   The user has pressed BREAK while trying to load the program 'run'
 + 
 +        LD      HL,$0000        ; cause a system reset. 
 +        PUSH    HL              ; place address zero on machine stack. 
 +        RST     00H             ; switch to MAIN-ROM. 
 + 
 +
 + 
 +        DEFB    $FF             ; unused 
 +        DEFB    $FF             ; unused 
 +        DEFB    $FF             ; unused 
 +        DEFB    $FF             ; unused 
 +        DEFB    $FF             ; unused 
 + 
 +; ------------------------------------ 
 +; THE <b><font color=#333388>'NON-MASKABLE INTERRUPT'</font></b> ROUTINE 
 +; ------------------------------------ 
 +;   There is no NMI functionality. 
 + 
 +<a name="L0066"></a>;; <b>NMINT-SRV</b> 
 +L0066:  RETN                    ; return to previous interrupt state. 
 + 
 + 
 +; -------------------------- 
 +; THE <b><font color=#333388>'SYNTAX ERROR'</font></b> ROUTINE 
 +; -------------------------- 
 +;   An error has occurred during syntax checking so the position must be  
 +;   highlighted when a return is made to the Editor in the Main ROM. 
 + 
 +<a name="L0068"></a>;; <b>ST-ERROR</b> 
 +L0068:  LD      HL,($5C5D)      ; fetch character address from CH_ADD. 
 +        LD      ($5C5F),HL      ; set X_PTR to same to position error cursor. 
 + 
 +        LD      SP,($5C3D)      ; set the Stack Pointer from ERR_SP. 
 + 
 +        LD      HL,$16C5        ; prepare address of main SET-STK. 
 +        PUSH    HL              ; push on the machine stack. 
 + 
 +        RST     00H             ; switch to MAIN-ROM where SET-STK will clean up  
 +                                ; the work areas before returning to the Error  
 +                                ; Routine obtained from ERR_SP. 
 + 
 +; --------------------------------------- 
 +; THE <b><font color=#333388>'CHECK ERROR STACK POINTER'</font></b> ROUTINE 
 +; --------------------------------------- 
 +;   This allows the user's software to trap any errors at this point by setting  
 +;   the otherwise unused bit 2 of FLAGS_3 after inserting a custom error  
 +;   handler in the System Variable ERR_SP. 
 +;   Both Shadow ROM situations and Main ROM situations can be trapped and the  
 +;   routine is called from BOTH RST 20H and RST 28H. 
 + 
 +<a name="L0077"></a>;; <b>CHECK-SP</b> 
 +L0077:  BIT     2,(IY+$7C)      ; test FLAGS_3 has the user set up a custom 
 +                                ; error handler in Main RAM ? 
 +        RET                   ; return if not. 
 + 
 +;   Otherwise the user, or the third party software, has set up a custom routine 
 +;   in the system variable ERR_SP and set bit 2 of FLAGS_3 so that it is invoked 
 +;   at this point. 
 + 
 +        LD      SP,($5C3D)      ; set stack pointer from ERR_SP. 
 +        RST     00H             ; switch to MAIN-ROM. 
 + 
 +; ---------------------- 
 +; THE <b><font color=#333388>'CALBAS-2'</font></b> ROUTINE 
 +; ---------------------- 
 +;   A continuation of the code at $0010. 
 +;   Continue by picking up the address to be called, located after the RST 
 +;   instruction and placing after the CALL instruction in the SBRT sequence. 
 + 
 +<a name="L0081"></a>;; <b>CALBAS-2</b> 
 +L0081:  LD      E,(HL)          ; fetch low byte of called address 
 +        INC     HL              ; advance pointer. 
 +        LD      D,(HL)          ; fetch high byte. 
 + 
 +        LD      ($5CBD),DE      ; place in the Z80 code SBRT 
 +        INC     HL              ; increment pointer. 
 + 
 +        EX      (SP),HL         ; transfer continuation address to machine 
 +                                ; stack - and the stack value (was DE) to HL. 
 + 
 +        EX      DE,HL           ; original DE value now restored. 
 + 
 +        LD      HL,$0000        ; signal CALBAS routine in use. 
 +        PUSH    HL              ; place on stack. 
 + 
 +        LD      HL,$0008        ; address of main ERROR restart 
 +        PUSH    HL              ; place on stack 
 + 
 +        LD      HL,$5CB9        ; address of calling SBRT subroutine. 
 +        PUSH    HL              ; place on stack. 
 + 
 +        JP      <A href="#L0700">L0700</a>           ; jump to UNPAGE 
 + 
 +; --------------------- 
 +; THE <b><font color=#333388>'CONTROL'</font></b> ROUTINE 
 +; --------------------- 
 +;   A continuation of code at L0008. The return address has been dropped off 
 +;   the machine stack into HL. 
 +
 +;   First see if this ROM was paged in as a result of the $0008 address 
 +;   stacked during the CALBAS routine. (see above) 
 + 
 +<a name="L009A"></a>;; <b>START-2</b> 
 +L009A:  PUSH    AF              ; preserve accumulator and status flags. 
 + 
 +        LD      A,H             ; test HL for zero - the CALBAS 
 +        OR      L               ; indicator value. 
 +        JR      NZ,<A href="#L00A5">L00A5</a>        ; forward, if not, to START-3. 
 + 
 +        POP     AF              ; restore accumulator and flags. 
 + 
 +        POP     HL              ; discard address stacked by RST 08. 
 +        LD      HL,($5CBA)      ; pick up post-CALL HL value from SBRT. 
 +        RET                     ; return. 
 + 
 +;------------------------------------------------------------------------------ 
 +;   Now consider that the address $0008 may have been an input or output 
 +;   routine that precedes the letter of one of the new channels.  These 
 +;   paging addresses ensure that this ROM is paged in so that the real 
 +;   input/output addresses can be read from the locations after the 
 +;   channel's letter. In this case, the return address is towards the end 
 +;   of the CALL-SUB routine in the Main ROM, i.e. 
 +;   L15FB         CALL    $162C   ; routine CALL-JUMP (a JP (HL) instr.) 
 +;   L15FE         POP     HL      ; return address 
 +;------------------------------------------------------------------------------ 
 + 
 +<a name="L00A5"></a>;; <b>START-3</b> 
 +L00A5:  PUSH    DE              ; preserve DE. 
 +        LD      DE,$15FE        ; test against possible return address 0x15FE 
 +        SBC     HL,DE           ; subtract (carry is clear) 
 +        POP     DE              ; restore DE. 
 +        JR      NZ,<A href="#L00BC">L00BC</a>        ; forward with no match to START-4. 
 + 
 +;   This ROM has been paged by an attempt to use a stream. 
 + 
 +        POP     AF              ; restore accumulator. 
 + 
 +        LD      HL,<A href="#L0700">L0700</a>        ; stack the address UNPAGE to switch to  
 +        PUSH    HL              ; the Main ROM afterwards. 
 + 
 +        LD      HL,$0004        ; the shadow routine is 4 bytes forward 
 +        ADD     HL,DE           ; adjust input/output address pointer. 
 +        LD      E,(HL)          ; pick up low-order byte of I/O routine. 
 +        INC     HL              ; bump pointer. 
 +        LD      D,(HL)          ; pick up high-order byte of routine. 
 +        EX      DE,HL           ; transfer I/O address to HL. 
 + 
 +        JP      (HL)            ; jump to routine and then to UNPAGE 
 + 
 +; --- 
 + 
 +;   By elimination, the address $0008 has been reached as a result of a 
 +;   RST 08 instruction in the Main ROM.  This may be the very first time 
 +;   that this ROM has been paged in after startup or NEW. 
 + 
 +<a name="L00BC"></a>;; <b>START-4</b> 
 +L00BC:  RST     30H             ; create new system variables if first time. 
 + 
 +        LD      A,$01           ; %00000001 
 +        OUT     ($F7),        ; 
 + 
 +        LD      A,$EE           ; %11101110 
 +        OUT     ($EF),        ; 
 + 
 +        POP     AF              ; temporarily drop the accumulator. 
 +        POP     HL              ; fetch address of error code/hook code to HL. 
 +        PUSH    AF              ; save accumulator again. 
 + 
 +;   <font color=#9900FF>Note.</font> the address of the code could be anywhere in the 64K address space 
 +;   but it is not in this ROM.  Luckily in the Main ROM at $007B is the 
 +;   sequence ld a,(hl) ; ret which will fetch the unknown error code from 
 +;   the known address. 
 + 
 +        RST     10H             ; CALBAS 
 +        DEFW    $007B           ; main TEMP-PTR3 
 + 
 +        LD      ($5C3A),      ; place the error code in sysvar ERR_NR 
 + 
 +;   The error code at this stage is one less than actual code. 
 + 
 +        CP      $FF             ; is it 'OK' 
 +        JR      NZ,<A href="#L00E9">L00E9</a>        ; forward, if not, to TEST-CODE 
 + 
 +        BIT     1,(IY+$7C)      ; test FLAGS_3  - first time ? 
 +        JR      Z,<A href="#L00E7">L00E7</a>         ; forward, if not, to NREPORT-2 
 +                                ; 'Program finished' 
 + 
 +        BIT     7,(IY+$0C)      ; test PPC_hi - a direct command ? 
 +        JR      Z,<A href="#L00E7">L00E7</a>         ; forward, if not, to NREPORT-2 
 + 
 +        LD      HL,($5C59)      ; use E_LINE to address the first character of  
 +                                ; the edit buffer. 
 +        LD      A,(HL)          ; searching for RUN without whitespace. 
 + 
 +        CP      $F7             ; is character the token 'RUN'
 +        JP      Z,<A href="#L0A99">L0A99</a>         ; jump forward, if so, to LOAD-RUN 
 + 
 +<a name="L0663"></a>;; <b>NREPORT-2</b> 
 +L00E7:  RST     20H             ; Shadow Error Restart 
 +        DEFB    $FF             ; 'Program finished' 
 + 
 +; --- 
 + 
 +;   Continue to consider the error code.  This may have occurred after the 
 +;   Error RESTART in the Main ROM - range $00 (NEXT without FOR) to 
 +;   $1A (Tape Loading Error) or a RESTART in RAM which could also include 
 +;   the Hook Codes. 
 + 
 +<a name="L00E9"></a>;; <b>TEST-CODE</b> 
 +L00E9:  SUB     $1B             ; subtract lowest Hook Code (PAUSE) 
 +        JP      NC,<A href="#L1E71">L1E71</a>        ; jump, if same or higher, to HOOK-CODE 
 + 
 +        CP      $F0             ; was it $0B 'Nonsense in basic' 
 +        JR      Z,<A href="#L00FB">L00FB</a>         ; forward to COPYCHADD 
 + 
 +        CP      $F3             ; was it $0D 'Invalid file name' 
 +        JR      Z,<A href="#L00FB">L00FB</a>         ; forward to COPYCHADD 
 + 
 +        CP      $FC             ; was it $17 'Invalid stream' 
 +        JP      NZ,<A href="#L0028">L0028</a>        ; jump, if not, to ROMERR 
 + 
 +;   If one of the above three reports, then this is possibly an extended 
 +;   command and further investigation is required. A number of situations 
 +;   may apply. The error could have occurred - 
 +
 +;   1) In INPUT - just pass control back to Main ROM. This is just a normal 
 +;      Nonsense in BASIC and will not be due to anything new. 
 +;   2) While already investigating an error. Too much - just use Main ROM. 
 +;   3) While entering a new or modified line and syntax failed. 
 +;   4) While running the program and an error was encountered. 
 +
 +;   The character address CH_ADD is not much use as that is the place 
 +;   after the command where the standard ROM encountered an error. 
 +;   It will be required by the Main ROM if control is passed back so, in 
 +;   order that the Main ROM parsing routines can be used, make a copy of the 
 +;   error character position. We will have to work forward from the 
 +;   beginning of the line if checking syntax or from the start of the 
 +;   program in run-time so that the errant command can be found. It may also 
 +;   be necessary to remove hidden characters from the BASIC line. 
 + 
 +<a name="L00FB"></a>;; <b>COPYCHADD</b> 
 +L00FB:  LD      HL,($5C5D)      ; fetch character address from CH_ADD and 
 +        LD      ($5CCB),HL      ; store in shadow system variable CHADD_ 
 + 
 +        POP     AF              ; restore accumulator. 
 + 
 +        BIT     5,(IY+$37)      ; test FLAGX - in INPUT mode ? 
 + 
 +        JP      NZ,<A href="#L0028">L0028</a>        ; jump back, if so, to ROMERR 
 + 
 +;   Continue if in Editing or Run-time Mode. 
 + 
 +        BIT     0,(IY+$7C)      ; test FLAGS_3 - already extended command ? 
 +        JP      NZ,<A href="#L0028">L0028</a>        ; jump, if so, to ROMERR 
 + 
 +;   else signal - handling an extended command - so that such a double error 
 +;   can be trapped. 
 + 
 +        SET     0,(IY+$7C)      ; update FLAGS_3 - signal executing an 
 +                                ; extended command. 
 + 
 +        RST     18H             ; checking syntax ? 
 + 
 +        JR      NZ,<A href="#L011B">L011B</a>        ; skip forward, if not, to RUNTIME 
 + 
 +        LD      (IY+$0C),$FF    ; set bit 7 of PPC_hi to indicate a line 
 +                                ; entry situation. 
 + 
 +;    In both cases, load B with the statement number where the error was 
 +;    encountered.  Previous validated statements are not to be disturbed. 
 + 
 +<a name="L011B"></a>;; <b>RUNTIME</b> 
 +L011B:  LD      B,(IY+$0D)      ; load B with statement number from SUBPPC 
 +        LD      C,$00           ; and set C to zero for a quotes flag. 
 + 
 +        BIT     7,(IY+$0C)      ; test PPC_hi - line entry ? 
 +        JR      Z,<A href="#L0130">L0130</a>         ; forward, if not, to PROG-LINE 
 + 
 +;   An edit line may have a line number at start and whitespace. We need to 
 +;   set CH_ADD at the first command. 
 + 
 +        PUSH    BC              ; save BC 
 + 
 +        RST     10H             ; CALBAS 
 +        DEFW    $19FB           ; main E-LINE-NO fetches any line number to 
 +                                ; BC, setting CH_ADD at the command token. 
 + 
 +        POP     BC              ; restore BC - discarding line number. 
 + 
 +        RST     10H             ; CALBAS 
 +        DEFW    $0018           ; main GET-CHAR gets first command of the 
 +                                ; first statement of the errant line. 
 + 
 +        JR      <A href="#L016F">L016F</a>           ; forward to statement loop - S-STAT to find 
 +                                ; the errant statement. 
 + 
 +; --- 
 + 
 +<a name="L0130"></a>;; <b>PROG-LINE</b> 
 +L0130:  LD      HL,($5C53)      ; set pointer to start of program from PROG. 
 + 
 +<a name="L0133"></a>;; <b>SC-L-LOOP</b> 
 +L0133:  LD      A,($5C46)       ; fetch high byte of errant line from PPC_hi 
 +        CP      (HL)            ; compare with tested high byte. 
 +        JR      NC,<A href="#L013B">L013B</a>        ; forward, if errant line higher or same, 
 +                                ; to TEST-LOW 
 + 
 +; else, unusually, the current line is not there so let Main ROM handle. 
 + 
 +<a name="L0139"></a>;; <b>NREPORT-1</b> 
 +L0139:  RST     20H             ; Shadow Error Restart 
 +        DEFB    $00             ; Nonsense in BASIC 
 + 
 +; --- 
 + 
 +<a name="L013B"></a>;; <b>TEST-LOW</b> 
 +L013B:  INC     HL              ; increment program pointer to address low byte. 
 +        JR      NZ,<A href="#L0144">L0144</a>        ; forward, if high bytes not same, to LINE-LEN 
 + 
 +        LD      A,($5C45)       ; fetch low byte of current line from PPC_lo 
 +        CP      (HL)            ; compare to addressed byte. 
 +        JR      C,<A href="#L0139">L0139</a>         ; back, if not in program area, to NREPORT-1 
 + 
 + 
 +<a name="L0144"></a>;; <b>LINE-LEN</b> 
 +L0144:  INC     HL              ; increment program 
 +        LD      E,(HL)          ; pointer and 
 +        INC     HL              ; pick up the 
 +        LD      D,(HL)          ; length of the BASIC line 
 +        INC     HL              ; resting at the first character. 
 + 
 +        JR      Z,<A href="#L016F">L016F</a>         ; forward, if line numbers matched, to S-STAT 
 +                                ; the mid-entry point of the statement loop. 
 + 
 +        ADD     HL,DE           ; else add length to current address. 
 +        JR      <A href="#L0133">L0133</a>           ; loop back to SC-L-LOOP 
 + 
 +; -------------------- 
 +; THE <b><font color=#333388>'STATEMENT LOOP'</font></b> 
 +; -------------------- 
 +;    Entered at mid-point S-STAT with statement counter in B and a quotes 
 +;    counter, C, set at an even zero. 
 + 
 +<a name="L014E"></a>;; <b>SKIP-NUM</b> 
 +L014E:  LD      DE,$0006        ; a hidden floating point number has six bytes. 
 +        ADD     HL,DE           ; add to skip to next character. 
 + 
 +; -&gt; The Looping Point. 
 + 
 +<a name="L0152"></a>;; <b>EACH-ST</b> 
 +L0152:  LD      A,(HL)          ; fetch addressed BASIC character. 
 +        CP      $0E             ; is it the hidden number indicator ? 
 +        JR      Z,<A href="#L014E">L014E</a>         ; back to SKIP-NUM to ignore. 
 + 
 +        INC     HL              ; else increase pointer. 
 + 
 +        CP      $22             ; is it quotes character '"'
 +        JR      NZ,<A href="#L015D">L015D</a>        ; skip forward, if not, to CHKEND 
 + 
 +        DEC                   ; decrement quotes counter. 
 + 
 +<a name="L015D"></a>;; <b>CHKEND</b> 
 +L015D:  CP      $3A             ; is character ':'
 +        JR      Z,<A href="#L0165">L0165</a>         ; skip forward to CHKEVEN 
 + 
 +        CP      $CB             ; is character 'THEN'
 +        JR      NZ,<A href="#L0169">L0169</a>        ; skip forward to CHKEND-L 
 + 
 + 
 +<a name="L0165"></a>;; <b>CHKEVEN</b> 
 +L0165:  BIT     0,            ; are quotes balanced ? 
 +        JR      Z,<A href="#L016F">L016F</a>         ; forward, if so, to S-STAT 
 +                                ; for next statement. 
 + 
 +;   A carriage return must not appear within quotes. 
 + 
 +<a name="L0169"></a>;; <b>CHKEND-L</b> 
 +L0169:  CP      $0D             ; carriage return ? 
 +        JR      NZ,<A href="#L0152">L0152</a>        ; back, if not, to EACH-ST 
 + 
 +        JR      <A href="#L0139">L0139</a>           ; back to NREPORT-1 
 +                                ; 'Nonsense in BASIC' 
 + 
 + 
 +;    The Statement Loop Entry Point --&gt; 
 + 
 +<a name="L016F"></a>;; <b>S-STAT</b> 
 +L016F:  DJNZ    <A href="#L0152">L0152</a>           ; decrement statement counter and loop back 
 +                                ; to EACH-ST. 
 + 
 +;    The errant statement has been located and CH_ADD is set to start. 
 + 
 +        DEC     HL              ; point to start or ':' 
 + 
 +        LD      ($5C5D),HL      ; set the Main ROM system variable CH_ADD 
 + 
 +        RST     18H             ; checking syntax ? 
 + 
 +        JR      NZ,<A href="#L01AA">L01AA</a>        ; forward, if not, to CL-WORK 
 + 
 +        BIT     7,(IY+$0C)      ; test PPC_hi - is it an Edit Line ? 
 +        JP      Z,<A href="#L01F0">L01F0</a>         ; jump forward, if not, to ERR-6. 
 + 
 +        DEC     HL              ; prepare to enter loop below. 
 + 
 +        LD      C,$00           ; ?? 
 + 
 +;   It is well to reflect on what has been achieved up to this point.  At 
 +;   each statement, the first attempt at validation is made by the Main ROM. 
 +;   Then if that should encounter something not to its liking, this ROM has 
 +;   a bash.  There could be ten or more statements before this one and each 
 +;   will have been validated by the Main ROM or by this routine.  As part of 
 +;   that validation process, when a number is parsed, then the integer or 
 +;   floating point form of the number is inserted after the digits, rendered 
 +;   invisible by a CHR$(14). 
 +
 +;   Once a statement has passed validation by either ROM, then it is not 
 +;   undone.  If, say, the Main ROM has failed on the third statement of 
 +
 +;   10 PRINT "Hi :" : LET vat = 15 : OPEN# 7, "T" : LET tax = cost * (vat/100) 
 +
 +;   then it will have already inserted six bytes after the '7' before raising 
 +;   the error 'Invalid stream' This ROM has located the separator before 
 +;   the command but needs to remove the hidden numbers before parsing the 
 +;   statement as the latter process will put them back in and we can'
 +;   double up.  The easiest way to do this is to search for hidden numbers 
 +;   right to the end of the line.  There won't be any after this statement 
 +;   but stopping at a CHR$(13) is easier than considering end of statement 
 +;   markers in quotes.  It seems that this neat solution was not arrived at 
 +;   immediately and the instruction, above, sets C to the quotes flag again 
 +;   and it is needlessly preserved on the stack. 
 +
 +;   The end-user is oblivious to this elegant toing and froing between ROMS 
 +;   and the unseen error code generation and cancellation. All that is 
 +;   apparent is that when the RETURN key is pressed, the line simply enters 
 +;   the program. 
 + 
 +<a name="L0182"></a>;; <b>RCLM-NUM</b> 
 +L0182:  INC     HL              ; increment character pointer 
 +        LD      A,(HL)          ; fetch the character. 
 + 
 +        CP      $0E             ; is it the number marker ? 
 +        JR      NZ,<A href="#L01A5">L01A5</a>        ; forward, if not, to NEXTNUM 
 + 
 +        PUSH    BC              ; preserve BC (zero) 
 + 
 +        LD      BC,$0006        ; six bytes to reclaim. 
 + 
 +        RST     10H             ; CALBAS 
 +        DEFW    $19E8           ; main RECLAIM-2 
 + 
 +        PUSH    HL              ; preserve character pointer. 
 + 
 +        LD      DE,($5CCB)      ; fetch error pointer from CHADD_ 
 +        AND                   ; prepare for true subtraction. 
 +        SBC     HL,DE           ; test if character position less than error. 
 +        JR      NC,<A href="#L01A3">L01A3</a>        ; forward, if not, to NXT-1 
 + 
 +        EX      DE,HL           ; transfer CHADD_ value to HL. 
 +        LD      BC,$0006        ;  
 +        AND                   ; 
 +        SBC     HL,BC           ; reduce by six. 
 +        LD      ($5CCB),HL      ; store back in system variable CHADD_ 
 + 
 +<a name="L01A3"></a>;; <b>NXT-1</b> 
 +L01A3:  POP     HL              ; restore character pointer. 
 +        POP     BC              ; and restore BC (zero) 
 + 
 +<a name="L01A5"></a>;; <b>NEXTNUM</b> 
 +L01A5:  LD      A,(HL)          ; fetch character. 
 +        CP      $0D             ; carriage return ? 
 +        JR      NZ,<A href="#L0182">L0182</a>        ; loop back, if not, to RCLM-NUM 
 + 
 +;  The run-time path rejoins here 
 + 
 +<a name="L01AA"></a>;; <b>CL-WORK</b> 
 +L01AA:  RST     10H             ; CALBAS 
 +        DEFW    $16BF           ; main SET-WORK 
 + 
 +        CALL    <A href="#L0255">L0255</a>           ; routine RES-VARS sets new system variables 
 +                                ; from that following CHADD_ to that preceding 
 +                                ; COPIES to the value $FF. 
 + 
 +        RST     10H             ; CALBAS 
 +        DEFW    $0020           ; main NEXT-CHAR advances CH_ADD and fetches 
 +                                ; the command character. 
 + 
 +        SUB     $CE             ; reduce tokens - why? 
 + 
 +        CP      $01             ; 'CAT'
 +        JP      Z,<A href="#L0486">L0486</a>         ; jump to CAT-SYN 
 + 
 +        CP      $02             ; 'FORMAT'
 +        JP      Z,<A href="#L04B4">L04B4</a>         ; jump to FRMT-SYN 
 + 
 +        CP      $03             ; 'MOVE'
 +        JP      Z,<A href="#L053D">L053D</a>         ; jump to MOVE-SYN 
 + 
 +        CP      $04             ; 'ERASE'
 +        JP      Z,<A href="#L0531">L0531</a>         ; jump to ERASE-SYN 
 + 
 +        CP      $05             ; 'OPEN #' ? 
 +        JP      Z,<A href="#L04ED">L04ED</a>         ; jump to OPEN-SYN 
 + 
 +        CP      $2A             ; 'SAVE'
 +        JP      Z,<A href="#L082F">L082F</a>         ; jump to SAVE-SYN 
 + 
 +        CP      $21             ; 'LOAD'
 +        JP      Z,<A href="#L0898">L0898</a>         ; jump to LOAD-SYN 
 + 
 +        CP      $08             ; 'VERIFY'
 +        JP      Z,<A href="#L08A2">L08A2</a>         ; jump to VERIF-SYN 
 + 
 +        CP      $07             ; 'MERGE'
 +        JP      Z,<A href="#L08AC">L08AC</a>         ; jump to MRG-SYN 
 + 
 +        CP      $2D             ; 'CLS'
 +        JP      Z,<A href="#L0559">L0559</a>         ; jump to CLS#-SYN 
 + 
 +        CP      $2F             ; 'CLEAR'
 +        JP      Z,<A href="#L057F">L057F</a>         ; jump to CLR#-SYN 
 + 
 +;   If none of the new extended commands then load HL from the VECTOR 
 +;   system variable which normally points to the error routine below. 
 +;   However the user, or a third party software publisher, may have 
 +;   altered the vector to point to their own extended BASIC routines. 
 + 
 +<a name="L01EC"></a>;; <b>ERR-V</b> 
 +L01EC:  LD      HL,($5CB7)      ; fetch address from system variable VECTOR 
 +        JP      (HL)            ; jump to address. 
 + 
 +; --- 
 + 
 +<a name="L01F0"></a>;; <b>ERR-6</b> 
 +L01F0:  LD      HL,($5CCB)      ; fetch original character address from 
 +                                ; CHADD_ 
 +        LD      ($5C5D),HL      ; and place in standard CH_ADD 
 +        RST     28H             ; Error Main ROM. 
 + 
 +; ----------------------------------------- 
 +; THE <b><font color=#333388>'CREATE NEW SYSTEM VARIABLES'</font></b> ROUTINE 
 +; ----------------------------------------- 
 +;   A continuation of the restart code at $0030. A check is made to see if 
 +;   the 58 variables already exist and the stack is set up to create the 
 +;   room using the main ROM routine. If there isn't 58 free bytes available 
 +;   then an 'Out of memory' report is generated by the Main ROM. 
 + 
 +<a name="L01F7"></a>;; <b>CRT-VARS</b> 
 +L01F7:  LD      HL,($5C4F)      ; system variable CHANS normally   $5CB6. 
 +        LD      DE,$A349        ; add test value                   $A349. 
 +                                ;                                   ---- 
 +        ADD     HL,DE           ; add - if uninitialized will give $FFFF. 
 +        JR      C,<A href="#L023D">L023D</a>         ; forward, if higher, to VAR-EXIST 
 + 
 +        LD      HL,<A href="#L0224">L0224</a>        ; prepare address of DEFAULT routine 
 +        PUSH    HL              ; push on machine stack 
 + 
 +        LD      HL,($5C63)      ; use system variable STKBOT 
 +        LD      ($5C65),HL      ; to set system variable STKEND 
 + 
 +        LD      HL,$5C92        ; use system variable MEMBOT 
 +        LD      ($5C68),HL      ; to set system variable MEM 
 + 
 +        LD      HL,$5CB5        ; the last standard system variable. 
 +                                ; P-RAMT_hi - the location before new area. 
 +        LD      BC,<A href="#L003A">L003A</a>        ; 58 bytes to allocate. 
 + 
 +;   Now call MAKE-ROOM in the Main ROM by placing a sequence of addresses 
 +;   on the machine stack as it is not possible to use the CALBAS routine yet. 
 + 
 +        LD      DE,$0000        ; indicator - signals Main ROM has been used. 
 +        PUSH    DE              ; stack word. 
 + 
 +        LD      E,$08           ; form address $0008 in Main ROM. 
 +        PUSH    DE              ; stack word. 
 + 
 +        LD      DE,$1655        ; the Main ROM address MAKE-ROOM. 
 +        PUSH    DE              ; stack word. 
 + 
 +;   The machine stack now has the hierarchy DEFAULT; $0000; ERROR-1; 
 +;   MAKE-ROOM which will be handled in reverse order. 
 + 
 +        JP      <A href="#L0700">L0700</a>           ; jump to UNPAGE. 
 + 
 +;   After creating room and paging this ROM back in, 'return' to the next 
 +;   address which was the first in the sequence pushed on machine stack 
 +;   earlier. 
 + 
 +<a name="L0224"></a>;; <b>DEFAULT</b> 
 +L0224:  LD      HL,<A href="#L0242">L0242</a>        ; default system variable values. 
 +        LD      BC,$0013        ; nineteen bytes to move. 
 +        LD      DE,$5CB6        ; old CHANS area, new sysvar FLAGS_3. 
 +        LDIR                    ; copy the bytes. 
 + 
 +;   <font color=#9900FF>Note.</font> So far the value in the accumulator, which may be the number of a 
 +;   stream to close, has not been altered.  This next instruction is worded  
 +;   wrongly and  
 +
 +;   OPEN #7,"s" : CLOSE #7  
 +
 +;   may not work. 
 +;   The fix would be to use 'ld hl $5cef ; ld (hl), $01' (5 bytes) 
 +;   or even 'dec h ; ld ($5cee),hl' (4 bytes) 
 +;   The next pair of instructions would have been better if executed using 
 +;   the HL register pair also. 
 + 
 +        LD      A,$01           ; set accumulator to 1. 
 +        LD      ($5CEF),      ; set system variable COPIES. 
 + 
 +        LD      (IY+$77),$50    ; set NMI_ADD_hi to eighty. 
 +        LD      (IY+$76),$00    ; set NMI_ADD_lo to zero. 
 + 
 +        RET                     ; return. 
 + 
 +; --- 
 + 
 +;   The extended System Variables already exist. 
 + 
 +<a name="L023D"></a>;; <b>VAR-EXIST</b> 
 +L023D:  RES     1,(IY+$7C)      ; reset indicator in FLAGS_3. 
 +        RET                     ; return. 
 + 
 + 
 +; ------------------------------------------- 
 +; THE <b><font color=#333388>'SYSTEM VARIABLES DEFAULT VALUES'</font></b> TABLE 
 +; ------------------------------------------- 
 +;   These are the initial values of the first section of the extended System 
 +;   Variables that are copied, once only, to a newly opened area following 
 +;   the standard 48K Spectrum System Variables.  The memory area that was at 
 +;   this location (CHANS) is moved upwards to make room. 
 +;   The first new location (which was the first byte of CHANS) is now 
 +;   FLAGS_3, accessible by the IY register, and normally zero when the Main 
 +;   ROM becomes active again.  Bit 1 is set when a CLEAR# is active and also 
 +;   by the copy itself. 
 + 
 +<a name="L0242"></a>;; <b>SV-DEFS</b> 
 +L0242:  DEFB    $02             ; FLAGS3 (with bit 1 already set). 
 +        DEFW    $01F0           ; VECTOR 
 + 
 +        LD      HL,$0000        ; SBRT located at $5CB9 
 +        CALL    $0000           ; 
 +        LD      ($5CBA),HL      ; 
 +        RET                     ; 
 + 
 +        DEFW    $000C           ; BAUD 
 +        DEFB    $01             ; NTSTAT 
 +        DEFB    $00             ; IOBORD - black. 
 +        DEFW    $0000           ; SER_FL 
 + 
 + 
 +; ---------------------------------------- 
 +; THE <b><font color=#333388>'RESET NEW SYSTEM VARIABLES'</font></b> ROUTINE 
 +; ---------------------------------------- 
 +;   The central area is filled with $FF bytes. 
 +;   This occurs whenever a new extended command is invoked. 
 + 
 +<a name="L0255"></a>;; <b>RES-VARS</b> 
 +L0255:  LD      HL,$5CCD        ; set pointer to NTRESP - start of area. 
 +        LD      B,$22           ; thirty four bytes to fill. 
 + 
 +<a name="L025A"></a>;; <b>EACH-VAR</b> 
 +L025A:  LD      (HL),$FF        ; insert a default $FF value. 
 +        INC     HL              ; bump the pointer. 
 +        DJNZ    <A href="#L025A">L025A</a>           ; loop back to EACH-VAR. 
 + 
 +        RET                     ; return. 
 + 
 +; ------------------------------------ 
 +; THE <b><font color=#333388>'SHADOW REPORT PRINTING'</font></b> ROUTINE 
 +; ------------------------------------ 
 +;   This routine prints the error reports of the Shadow ROM. 
 +;   These relate to the code that follows a RST 20H restart.  The error code 
 +;   is not printed as it would conflict with Main ROM reports.  The text of 
 +;   the message is printed and then the Main ROM routine is used to print a 
 +;   comma and then the line number and statement.  For example, 
 +;   Program finished, 0:1 
 +;   The code is similar to that at MAIN-4 in the Main ROM.  Some improvements 
 +;   have been made but at least one slight error has been replicated. 
 + 
 +<a name="L0260"></a>;; <b>REP-MSG</b> 
 +L0260:  LD      (IY+$7C),$00    ; clear FLAGS_3 in preparation for leaving  
 +                                ; this ROM. 
 + 
 +        EI                      ; Enable Interrupts. 
 + 
 +        HALT                    ; wait for the first interrupt. 
 + 
 +        CALL    <A href="#L17B7">L17B7</a>           ; routine RCL-T-CH reclaims any temporary 
 +                                ; channels and stops any running drive motor. 
 + 
 +        RES     5,(IY+$01)      ; update FLAGS - 'Ready for new key'
 +        BIT     1,(IY+$30)      ; test FLAGS2 - is printer buffer empty ? 
 +        JR      Z,<A href="#L0276">L0276</a>         ; forward, if so, to FETCH-ERR 
 + 
 +        RST     10H             ; CALBAS - call a Base ROM routine. 
 +        DEFW    $0ECD           ; main routine - COPY-BUFF 
 +                                ; <font color=#9900FF>Note.</font> the programmer has neglected to 
 +                                ; set bit 1 of FLAGS first. 
 + 
 +<a name="L0276"></a>;; <b>FETCH-ERR</b> 
 +L0276:  POP     HL              ; drop the return address - after RST. 
 +        LD      A,(HL)          ; fetch the error code. 
 +        LD      (IY+$00),     ; place in system variable ERR_NR. 
 +        INC                   ; increment setting zero if was $FF. 
 +        PUSH    AF              ; save actual code and status flags. 
 + 
 +        LD      HL,$0000        ; prepare to blank some system variables. 
 +        LD      (IY+$37),     ; clear all the bits of FLAGX. 
 +        LD      (IY+$26),     ; blank X_PTR_hi to suppress error marker. 
 +        LD      ($5C0B),HL      ; blank DEFADD to signal that no defined 
 +                                ; function is being evaluated. 
 + 
 +        INC                   ; select offset of 1 (explicit in main ROM ). 
 +        LD      ($5C16),HL      ; update STRMS_00 - inputs from keyboard. 
 + 
 +        RST     10H             ; CALBAS 
 +        DEFW    $16B0           ; main SET-MIN clears workspace etc. 
 + 
 +        RES     5,(IY+$37)      ; update FLAGX - signal in EDIT mode 
 +                                ; not INPUT mode. 
 +                                ; <font color=#9900FF>Note.</font> all the bits were reset earlier. 
 + 
 +        RST     10H             ; CALBAS 
 +        DEFW    $0D6E           ; main CLS-LOWER 
 + 
 +        SET     5,(IY+$02)      ; update TV_FLAG - signal lower screen 
 +                                ; requires clearing. 
 +        RES     3,(IY+$02)      ; update TV_FLAG - no change in mode. 
 + 
 +        POP     AF              ; restore the incremented error code. 
 +        LD      HL,<A href="#L02BF">L02BF</a>        ; start search at REP-MSGS table below. 
 +        LD      B,$04           ; roughly ensure that BC does not limit 
 +                                ; search area as code must be found. 
 +        CPIR                    ; search for code $00 - $17 skipping 
 +                                ; all ASCII text. 
 + 
 +;   At this point HL addresses first character of message. 
 + 
 +<a name="L02A7"></a>;; <b>PR-REP-LP</b> 
 +L02A7:  LD      A,(HL)          ; fetch each character in turn. 
 +        CP      $20             ; compare to space. 
 +        JR      C,<A href="#L02B4">L02B4</a>         ; forward if less to END-PR-MS 
 + 
 +        PUSH    HL              ; save the character pointer 
 +        RST     10H             ; CALBAS 
 +        DEFW    $0010           ; main PRINT-A 
 + 
 +        POP     HL              ; restore pointer 
 +        INC     HL              ; and increment. 
 +        JR      <A href="#L02A7">L02A7</a>           ; loop back to PR-REP-LP 
 + 
 +; --- 
 + 
 +<a name="L02B4"></a>;; <b>END-PR-MS</b> 
 +L02B4:  LD      SP,($5C3D)      ; set machine stack pointer from ERR_SP 
 +        INC     SP              ; prepare to overwrite the MAIN-4 
 +        INC     SP              ; address $1303. 
 +        LD      HL,$1349        ; substitute with the part that prints 
 +                                ; the comma and line statement. 
 +        PUSH    HL              ; push address to base of stack. 
 +        RST     00H             ; return to MAIN-ROM. 
 + 
 +;   <font color=#9900FF>Note.</font> at this stage we have, say, "Program finished" on the screen and 
 +;   the Main ROM routine at $1349 will complete the ", 0:1" part looping 
 +;   back to MAIN-2 to put $1303 on the stack again. 
 + 
 +; ------------------------------------ 
 +; THE <b><font color=#333388>'SHADOW REPORT MESSAGES'</font></b> ROUTINE 
 +; ------------------------------------ 
 +;   These are the Shadow Error Reports.  <font color=#9900FF>Note.</font> that the never used 
 +;   "Header mismatch error" has been largely reclaimed.  Each error code, 
 +;   which must be less than a space, serves to delimit the preceding text. 
 +;   The final delimiter might just as well be $18. 
 + 
 +<a name="L02BF"></a>;; <b>REP-MSGS</b> 
 +L02BF   DEFB    $00 
 +        DEFM    "Program finished" 
 +        DEFB    $01 
 +        DEFM    "Nonsense in BASIC"     ; Duplicate of a Main ROM error 
 +        DEFB    $02 
 +        DEFM    "Invalid stream number" 
 +        DEFB    $03 
 +        DEFM    "Invalid device expression" 
 +        DEFB    $04 
 +        DEFM    "Invalid name" 
 +        DEFB    $05 
 +        DEFM    "Invalid drive number" 
 +        DEFB    $06 
 +        DEFM    "Invalid station number" 
 +        DEFB    $07 
 +        DEFM    "Missing name" 
 +        DEFB    $08 
 +        DEFM    "Missing station number" 
 +        DEFB    $09 
 +        DEFM    "Missing drive number" 
 +        DEFB    $0A 
 +        DEFM    "Missing baud rate" 
 +        DEFB    $0B 
 +        DEFM    "er mismatch e"         ; <font color=#9900FF>Note.</font> remnants of unused text. 
 +        DEFB    $0C 
 +        DEFM    "Stream already open" 
 +        DEFB    $0D 
 +        DEFM    "Writing to a 'read' file" 
 +        DEFB    $0E 
 +        DEFM    "Reading a 'write' file" 
 +        DEFB    $0F 
 +        DEFM    "Drive 'write' protected" 
 +        DEFB    $10 
 +        DEFM    "Microdrive full" 
 +        DEFB    $11 
 +        DEFM    "Microdrive not present" 
 +        DEFB    $12 
 +        DEFM    "File not found" 
 +        DEFB    $13 
 +        DEFM    "Hook code error"       ; not listed in manual. 
 +        DEFB    $14 
 +        DEFM    "CODE error" 
 +        DEFB    $15 
 +        DEFM    "MERGE error" 
 +        DEFB    $16 
 +        DEFM    "Verification has failed" 
 +        DEFB    $17 
 +        DEFM    "Wrong file type" 
 +        DEFB    $18                     ; end-marker 
 + 
 +; ********************************************* 
 +; **  T H E   S Y N T A X   R O U T I N E S  ** 
 +; ********************************************* 
 + 
 +; -------------------------------- 
 +; THE <b><font color=#333388>'CAT COMMAND SYNTAX'</font></b> ROUTINE 
 +; -------------------------------- 
 +;   e.g. CAT 3 
 +;   Without the syntax tables of the Main ROM, checking syntax is quite 
 +;   laborious.  Although the Main ROM allowed CAT without a parameter, a 
 +;   single expression in the range 1 - 8 is now required.  By default, CAT 
 +;   outputs to the upper screen but output may be directed to any stream in 
 +;   the range 0 to 15 decimal.  The subroutines used to evaluate the numeric 
 +;   expressions use the SCANNING routine, in Main ROM, which inserts the 
 +;   hidden five-byte numbers after any numeric arguments. 
 + 
 +<a name="L0486"></a>;; <b>CAT-SYN</b> 
 +L0486:  LD      HL,$5CD8        ; address system variable S_STR1. 
 +        LD      (HL),$02        ; default to stream 2 the screen. 
 + 
 +        RST     10H             ; CALBAS 
 +        DEFW    $0020           ; main NEXT-CHAR 
 + 
 +        CP      $0D             ; carriage return ? 
 +        JR      Z,<A href="#L0494">L0494</a>         ; forward, if so, to MISSING-D 
 + 
 +        CP      $3A             ; is character ':'
 + 
 +<a name="L0494"></a>;; <b>MISSING-D</b> 
 +L0494:  JP      Z,<A href="#L0683">L0683</a>         ; jump if no parameter to NREPORT-9 
 + 
 +        CP      $23             ; is character '#'
 +        JR      NZ,<A href="#L04A6">L04A6</a>        ; forward to CAT-SCRN 
 + 
 +;   Output is directed at a specific stream. 
 + 
 +        CALL    <A href="#L064E">L064E</a>           ; routine EXPT-STRM checks for number in range. 
 +        CALL    <A href="#L05B1">L05B1</a>           ; routine SEPARATOR checks for ',' or ';'
 +        JR      NZ,<A href="#L04B2">L04B2</a>        ; forward, if not present, to OREPORT-1 
 +                                ; 'Nonsense in BASIC' 
 + 
 +        RST     10H             ; CALBAS 
 +        DEFW    $0020           ; main NEXT-CHAR 
 + 
 +<a name="L04A6"></a>;; <b>CAT-SCRN</b> 
 +L04A6:  CALL    <A href="#L061E">L061E</a>           ; routine EXPT-NUM 
 +        CALL    <A href="#L05B7">L05B7</a>           ; routine ST-END 
 +        CALL    <A href="#L066D">L066D</a>           ; routine CHECK-M-2 checks that drive is in  
 +                                ; range 1 - 8. 
 + 
 +        JP      <A href="#L1AB5">L1AB5</a>           ; jump forward to CAT-RUN 
 + 
 +; --- 
 + 
 +<a name="L04B2"></a>;; <b>OREPORT-1</b> 
 +L04B2:  RST     20H             ; Shadow Error Restart 
 +        DEFB    $00             ; Nonsense in BASIC 
 + 
 +; ----------------------------------- 
 +; THE <b><font color=#333388>'FORMAT COMMAND SYNTAX'</font></b> ROUTINE 
 +; ----------------------------------- 
 +;   e.g. 
 + 
 +<a name="L04B4"></a>;; <b>FRMT-SYN</b> 
 +L04B4:  CALL    <A href="#L05F2">L05F2</a>           ; routine EXPT-SPEC 
 +        CALL    <A href="#L05B1">L05B1</a>           ; routine SEPARATOR 
 +        JR      NZ,<A href="#L04BF">L04BF</a>        ; forward to NO-FOR-M 
 + 
 +        CALL    <A href="#L062F">L062F</a>           ; routine EXPT-NAME 
 + 
 +<a name="L04BF"></a>;; <b>NO-FOR-M</b> 
 +L04BF:  CALL    <A href="#L05B7">L05B7</a>           ; routine ST-END 
 +        LD      A,($5CD9)       ; sv L_STR1 device letter. 
 +        CP      $54             ; is character  "T"
 +        JR      Z,<A href="#L04CD">L04CD</a>         ; forward to FOR-B-T 
 + 
 +        CP      $42             ; is character  "B"
 +        JR      NZ,<A href="#L04D3">L04D3</a>        ; forward to NOT-FOR-B 
 + 
 + 
 +<a name="L04CD"></a>;; <b>FOR-B-T</b> 
 +L04CD:  CALL    <A href="#L06B0">L06B0</a>           ; routine TEST-BAUD 
 +        JP      <A href="#L0ACD">L0ACD</a>           ; jump to SET-BAUD 
 + 
 +<a name="L04D3"></a>;; <b>NOT-FOR-B</b> 
 +L04D3:  CP      $4E             ; is character "N"
 +        JR      NZ,<A href="#L04E7">L04E7</a>        ; forward to FOR-M 
 + 
 +        CALL    <A href="#L068F">L068F</a>           ; routine TEST-STAT 
 +        LD      A,($5CD6)       ; sv D_STR1 drive number 
 +        AND     A 
 +        JP      Z,<A href="#L069F">L069F</a>         ; jump to NREPORT-6 
 +        LD      ($5CC5),      ; sv NTSTAT 
 +        JP      <A href="#L05C1">L05C1</a>           ; jump to END1 
 + 
 +<a name="L04E7"></a>;; <b>FOR-M</b> 
 +L04E7:  CALL    <A href="#L0685">L0685</a>           ; routine TEST-MNAM 
 +        JP      <A href="#L1ABA">L1ABA</a>           ; jump to FOR-RUN 
 + 
 +; --------------------------------- 
 +; THE <b><font color=#333388>'OPEN COMMAND SYNTAX'</font></b> ROUTINE 
 +; --------------------------------- 
 +
 + 
 +<a name="L04ED"></a>;; <b>OPEN-SYN</b> 
 +L04ED:  CALL    <A href="#L064E">L064E</a>           ; routine EXPT-STRM 
 +        CALL    <A href="#L05B1">L05B1</a>           ; routine SEPARATOR 
 +        JR      NZ,<A href="#L04B2">L04B2</a>        ; back to OREPORT-1 
 +                                ; 'Nonsense in BASIC' 
 + 
 +        CALL    <A href="#L05F2">L05F2</a>           ; routine EXPT-SPEC 
 +        CALL    <A href="#L05B1">L05B1</a>           ; routine SEPARATOR 
 +        JR      NZ,<A href="#L0500">L0500</a>        ; forward to NOT-OP-M 
 + 
 +        CALL    <A href="#L062F">L062F</a>           ; routine EXPT-NAME 
 + 
 +<a name="L0500"></a>;; <b>NOT-OP-M</b> 
 +L0500:  CALL    <A href="#L05B7">L05B7</a>           ; routine ST-END 
 +        LD      A,($5CD8)       ; sv D_STR1 
 + 
 +        RST     10H             ; CALBAS 
 +        DEFW    $1727           ; main STR-DATA1 
 + 
 +        LD      HL,$0011        ; 
 +        AND                   ; 
 +        SBC     HL,BC           ; 
 +        JR      C,<A href="#L052F">L052F</a>         ; forward to NREPORT-C 
 + 
 +        LD      A,($5CD9)       ; sv L_STR1 device letter. 
 +        CP      $54             ; "T"
 +        JR      Z,<A href="#L051C">L051C</a>         ; forward to OPEN-RS 
 + 
 +        CP      $42             ; "B"
 +        JR      NZ,<A href="#L051F">L051F</a>        ; forward to NOT-OP-B 
 + 
 + 
 +<a name="L051C"></a>;; <b>OPEN-RS</b> 
 +L051C:  JP      <A href="#L0B4E">L0B4E</a>           ; jump to OP-RSCHAN 
 + 
 +; --- 
 + 
 +<a name="L051F"></a>;; <b>NOT-OP-B</b> 
 +L051F:  CP      $4E             ; is character "N"
 +        JR      NZ,<A href="#L0529">L0529</a>        ; forward to OP-M-C 
 + 
 +        CALL    <A href="#L068F">L068F</a>           ; routine TEST-STAT 
 +        JP      <A href="#L0F40">L0F40</a>           ; jump to OPEN-N-ST 
 + 
 +; --- 
 + 
 +<a name="L0529"></a>;; <b>OP-M-C</b> 
 +L0529:  CALL    <A href="#L0685">L0685</a>           ; routine TEST-MNAM 
 +        JP      <A href="#L1ABF">L1ABF</a>           ; jump to OP-RUN 
 + 
 +; --- 
 + 
 +<a name="L052F"></a>;; <b>NREPORT-C</b> 
 +L052F:  RST     20H             ; Shadow Error Restart 
 +        DEFB    $0B             ; Stream already open 
 + 
 +; ---------------------------------- 
 +; THE <b><font color=#333388>'ERASE COMMAND SYNTAX'</font></b> ROUTINE 
 +; ---------------------------------- 
 +
 + 
 +<a name="L0531"></a>;; <b>ERASE-SYN</b> 
 +L0531:  CALL    <A href="#L06A3">L06A3</a>           ; routine EXPT-EXPR 
 +        CALL    <A href="#L05B7">L05B7</a>           ; routine ST-END 
 +        CALL    <A href="#L0685">L0685</a>           ; routine TEST-MNAM 
 +        JP      <A href="#L1AAB">L1AAB</a>           ; jump to ERASE-RUN 
 + 
 +; --------------------------------- 
 +; THE <b><font color=#333388>'MOVE COMMAND SYNTAX'</font></b> ROUTINE 
 +; --------------------------------- 
 +
 + 
 +<a name="L053D"></a>;; <b>MOVE-SYN</b> 
 +L053D:  CALL    <A href="#L06B9">L06B9</a>           ; routine EXPT-EXP1 
 +        CALL    <A href="#L059F">L059F</a>           ; routine EX-D-STR 
 +        RST     10H             ; CALBAS 
 +        DEFW    $0018           ; main GET-CHAR 
 + 
 +        CP      $CC             ; 'TO'
 +        JR      NZ,<A href="#L0584">L0584</a>        ; forward to NONSENSE 
 + 
 +        CALL    <A href="#L06B9">L06B9</a>           ; routine EXPT-EXP1 
 +        CALL    <A href="#L059F">L059F</a>           ; routine EX-D-STR 
 +        RST     10H             ; CALBAS 
 +        DEFW    $0018           ; main GET-CHAR 
 + 
 +        CALL    <A href="#L05B7">L05B7</a>           ; routine ST-END 
 +        JP      <A href="#L1AB0">L1AB0</a>           ; jump to MOVE-RUN 
 + 
 +; -------------------------- 
 +; THE <b><font color=#333388>'CLS# COMMAND'</font></b> ROUTINE 
 +; -------------------------- 
 +
 + 
 +<a name="L0559"></a>;; <b>CLS#-SYN</b> 
 +L0559:  RST     10H             ; CALBAS 
 +        DEFW    $0020           ; main NEXT-CHAR 
 + 
 +        CP      $23             ; is the character '#'
 +        JR      NZ,<A href="#L0584">L0584</a>        ; forward, if not, to NONSENSE 
 + 
 +        RST     10H             ; CALBAS 
 +        DEFW    $0020           ; main NEXT-CHAR 
 + 
 +        CALL    <A href="#L05B7">L05B7</a>           ; routine ST-END 
 + 
 +        LD      HL,<A href="#L0038">L0038</a>        ; prepare a zero and black ink on white paper. 
 +        LD      ($5C8D),HL      ; set system variables ATTR_P and MASK_P. 
 +        LD      ($5C8F),HL      ; set system variables ATTR_T and MASK_T. 
 +                                ; <font color=#9900FF>Note.</font> not really necessary as done by CLS. 
 +        LD      (IY+$0E),     ; set system variable BORDCR to colour scheme. 
 +        LD      (IY+$57),     ; set system variable P_FLAG to zero. 
 + 
 +        LD      A,$07           ; load A with white. 
 +        OUT     ($FE),        ; directly change border colour. 
 + 
 +        RST     10H             ; CALBAS 
 +        DEFW    $0D6B           ; main CLS clears screen and sets colours. 
 + 
 +        JP      <A href="#L05C1">L05C1</a>           ; jump forward to END1. 
 + 
 +; ---------------------------- 
 +; THE <b><font color=#333388>'CLEAR# COMMAND'</font></b> ROUTINE 
 +; ---------------------------- 
 +
 + 
 +<a name="L057F"></a>;; <b>CLR#-SYN</b> 
 +L057F:  RST     10H             ; CALBAS 
 +        DEFW    $0020           ; main NEXT-CHAR 
 + 
 + 
 +        CP      $23             ; '#'
 + 
 +<a name="L0584"></a>;; <b>NONSENSE</b> 
 +L0584:  JP      NZ,<A href="#L04B2">L04B2</a>        ; jump to OREPORT-1 
 +                                ; 'Nonsense in BASIC' 
 + 
 +        RST     10H             ; CALBAS 
 +        DEFW    $0020           ; main NEXT-CHAR 
 + 
 + 
 +        CALL    <A href="#L05B7">L05B7</a>           ; routine ST-END 
 + 
 + 
 +        XOR                   ; 
 + 
 +<a name="L058E"></a>;; <b>ALL-STRMS</b> 
 +L058E:  PUSH    AF              ; 
 +        SET     1,(IY+$7C)      ; sv FLAGS_3 
 +        CALL    <A href="#L1718">L1718</a>           ; routine CLOSE 
 +        POP     AF              ; 
 +        INC                   ; 
 +        CP      $10             ; 
 +        JR      C,<A href="#L058E">L058E</a>         ; back to ALL-STRMS 
 + 
 +        JP      <A href="#L05C1">L05C1</a>           ; jump to END1 
 + 
 + 
 +; ----------------------------------------------------- 
 +; THE <b><font color=#333388>'EXCHANGE FILE SPECIFIERS DSTRI AND STR2'</font></b> ROUTINE 
 +; ----------------------------------------------------- 
 +;   This routine is used by the MOVE routines to bring one of the two 8-byte 
 +;   file specifiers into context.  There were two similar routines in the 
 +;   first Interface 1 ROM and this, the most efficient, has survived. 
 + 
 +<a name="L059F"></a>;; <b>EX-D-STR</b> 
 +L059F:  LD      HL,$5CD6        ; sv D_STR1. drive number 
 +        LD      DE,$5CDE        ; sv D_STR2. 
 +        LD      B,$08           ; eight bytes to swap. 
 + 
 +<a name="L05A7"></a>;; <b>ALL-BYTES</b> 
 +L05A7:  LD      A,(DE)          ; fetch byte 1. 
 +        LD      C,(HL)          ; fetch byte 2. 
 +        LD      (HL),         ; place byte 1. 
 +        LD      A,C             ; byte 2 to accumulator. 
 +        LD      (DE),         ; place byte 2. 
 + 
 +        INC     HL              ; increment the 
 +        INC     DE              ; two pointers. 
 +        DJNZ    <A href="#L05A7">L05A7</a>           ; loop back, for all eight, to ALL-BYTES. 
 + 
 +        RET                     ; return. 
 + 
 + 
 +; ----------------------- 
 +; THE <b><font color=#333388>'SEPARATOR'</font></b> ROUTINE 
 +; ----------------------- 
 +;   This routine returns with zero flag set if the current character is 
 +;   either a comma or semi-colon. 
 + 
 +<a name="L05B1"></a>;; <b>SEPARATOR</b> 
 +L05B1:  CP      $2C             ; is character ','
 +        RET                   ; return with zero set if so. 
 + 
 +        CP      $3B             ; is character ';'
 +        RET                     ; return. 
 + 
 +; ------------------------------ 
 +; THE <b><font color=#333388>'END OF STATEMENT'</font></b> ROUTINE 
 +; ------------------------------ 
 +
 + 
 +<a name="L05B7"></a>;; <b>ST-END</b> 
 +L05B7:  CP      $0D             ; is character carriage return ? 
 +        JR      Z,<A href="#L05BF">L05BF</a>         ; forward, if so, to TEST-RET 
 + 
 +        CP      $3A             ; is character a ':'
 +        JR      NZ,<A href="#L0584">L0584</a>        ; back, if not, to NONSENSE 
 + 
 + 
 +<a name="L05BF"></a>;; <b>TEST-RET</b> 
 +L05BF:  RST     18H             ; checking syntax ? 
 +        RET     NZ              ; return if not. 
 + 
 + 
 +; -------------------------------------------- 
 +; THE <b><font color=#333388>'RETURN TO THE MAIN INTERPRETER'</font></b> ROUTINE 
 +; -------------------------------------------- 
 +
 + 
 +<a name="L05C1"></a>;; <b>END1</b> 
 +L05C1:  LD      SP,($5C3D)      ; sv ERR_SP 
 +        LD      (IY+$00),$FF    ; sv ERR_NR 
 + 
 +        LD      HL,$1BF4        ; Main ROM address STMT-NEXT 
 + 
 +        RST     18H             ; checking syntax ? 
 +        JR      Z,<A href="#L05E0">L05E0</a>         ; forward, if so, to RETAD-SYN 
 + 
 +        LD      A,$7F           ; 
 +        IN      A,($FE)         ; 
 +        RRA                     ; 
 +        JR      C,<A href="#L05DD">L05DD</a>         ; forward to RETAD-RUN 
 + 
 +        LD      A,$FE           ; 
 +        IN      A,($FE)         ; 
 +        RRA                     ; 
 +        JR      NC,<A href="#L05E2">L05E2</a>        ; forward to BREAK-PGM 
 + 
 + 
 +<a name="L05DD"></a>;; <b>RETAD-RUN</b> 
 +L05DD:  LD      HL,$1B7D        ; Main ROM address STMT-R-1 
 + 
 +<a name="L05E0"></a>;; <b>RETAD-SYN</b> 
 +L05E0:  PUSH    HL              ; 
 +        RST     00H             ; to MAIN-ROM 
 + 
 +; --- 
 + 
 +<a name="L05E2"></a>;; <b>BREAK-PGM</b> 
 +L05E2:  LD      (IY+$00),$14    ; insert error code in system variable ERR_NR. 
 +        RST     28H             ; Error Main ROM  
 +                                ; 'BREAK into program' 
 + 
 +; ---------------------------------------- 
 +; THE <b><font color=#333388>'EVALUATE STRING EXPRESSION'</font></b> ROUTINE 
 +; ---------------------------------------- 
 +
 + 
 +<a name="L05E7"></a>;; <b>EXPT-STR</b> 
 +L05E7:  RST     10H             ; CALBAS 
 +        DEFW    $1C8C           ; main EXPT-EXP 
 +        RST     18H             ; checking syntax ? 
 +        RET     Z 
 + 
 +        PUSH    AF 
 +        RST     10H             ; CALBAS 
 +        DEFW    $2BF1           ; main STK-FETCH 
 +        POP     AF 
 +        RET 
 + 
 + 
 +; ----------------------------------------- 
 +; THE <b><font color=#333388>'EVALUATE CHANNEL EXPRESSION'</font></b> ROUTINE 
 +; ----------------------------------------- 
 +
 + 
 +<a name="L05F2"></a>;; <b>EXPT-SPEC</b> 
 +L05F2:  RST     10H             ; CALBAS 
 +        DEFW    $0020           ; main NEXT-CHAR 
 + 
 + 
 +<a name="L05F5"></a>;; <b>EXP-SPEC2</b> 
 +L05F5   CALL    <A href="#L05E7">L05E7</a>           ; routine EXPT-STR evaluates a string e.g. "m" 
 +                                ; start in DE, length in BC. 
 + 
 +; one of the main tenets of Sinclair BASIC is that a value can be replaced  
 +; by an expression of the same type at any time, so this routine must allow 
 +; something like "tomato"(3) as well as the more conventional "m" specifier. 
 +; Only in runtime when the expression is evaluated can a single character be 
 +; insisted upon. 
 + 
 +        JR      Z,<A href="#L060C">L060C</a>         ; forward, if checking syntax, to TEST-NEXT. 
 + 
 +        PUSH    AF              ; save following character. 
 + 
 +        LD      A,C             ; in runtime check  
 +        DEC                   ; immediately for  
 +        OR      B               ; a single character. 
 + 
 +        JR      NZ,<A href="#L062D">L062D</a>        ; forward, if not, to NREPORT-3 
 +                                ; 'Invalid device expression' 
 + 
 +        LD      A,(DE)          ; fetch the addressed character. 
 + 
 +        RST     10H             ; CALBAS 
 +        DEFW    $2C8D           ; main ALPHA 
 + 
 +        JR      NC,<A href="#L062D">L062D</a>        ; forward, if not alphabetic, to NREPORT-3 
 + 
 +        AND     $DF             ; convert to uppercase with 'AND %11011111' 
 + 
 +        LD      ($5CD9),      ; place in system variable L_STR1 device letter. 
 + 
 +        POP     AF              ; restore the following character. 
 + 
 +<a name="L060C"></a>;; <b>TEST-NEXT</b> 
 +L060C:  CP      $0D             ; test for carriage return. 
 +        RET                   ; return if so. 
 + 
 +        CP      $3A             ; is character ':'
 +        RET                   ; return if so. 
 + 
 +        CP      $A5             ; RND 
 +        RET     NC              ; return with a token?? 
 + 
 +        CALL    <A href="#L05B1">L05B1</a>           ; routine SEPARATOR tests for both ';' and ','
 + 
 +        JP      NZ,<A href="#L04B2">L04B2</a>        ; jump back, if not, to OREPORT-1 
 +                                ; 'Nonsense in BASIC' 
 + 
 +        RST     10H             ; CALBAS 
 +        DEFW    $0020           ; main NEXT-CHAR 
 + 
 +; ----------------------------------------------- 
 +; THE <b><font color=#333388>'EVALUATE NUMERIC DRIVE EXPRESSION'</font></b> ROUTINE 
 +; ----------------------------------------------- 
 +;   This routine is called once only to evaluate the numeric expression 
 +;   following a 'CAT' command token or is used from above to check a numeric  
 +;   expression following for example "M";
 + 
 +<a name="L061E"></a>;; <b>EXPT-NUM</b> 
 +L061E:  RST     10H             ; CALBAS 
 +        DEFW    $1C82           ; main EXPT-1NUM 
 +        RST     18H             ; checking syntax ? 
 +        RET                   ; return if checking syntax. 
 + 
 +        PUSH    AF              ; save NZ not syntax flag 
 + 
 +        RST     10H             ; CALBAS 
 +        DEFW    $1E99           ; main FIND-INT2 
 + 
 +        LD      ($5CD6),BC      ; set system variable D_STR1 drive number 
 + 
 +        POP     AF              ; restore NZ not syntax flag 
 + 
 +        RET                     ; return. 
 + 
 +; --- 
 + 
 +<a name="L062D"></a>;; <b>NREPORT-3</b> 
 +L062D:  RST     20H             ; Shadow Error Restart 
 +        DEFB    $02             ; 'Invalid device expression' 
 + 
 +; ------------------------------- 
 +; THE <b><font color=#333388>'EVALUATE FILENAME'</font></b> ROUTINE 
 +; ------------------------------- 
 +
 + 
 +<a name="L062F"></a>;; <b>EXPT-NAME</b> 
 +L062F:  RST     10H             ; CALBAS 
 +        DEFW    $0020           ; main NEXT-CHAR 
 + 
 + 
 +        CALL    <A href="#L05E7">L05E7</a>           ; routine EXPT-STR 
 +        RET     Z 
 + 
 +        PUSH    AF 
 +        LD      A,C 
 +        OR      B 
 +        JR      Z,<A href="#L064C">L064C</a>         ; forward to NREPORT-4 
 + 
 +        LD      HL,$000A 
 +        SBC     HL,BC 
 +        JR      C,<A href="#L064C">L064C</a>         ; forward to NREPORT-4 
 + 
 +        LD      ($5CDA),BC      ; sv N_STR1 
 +        LD      ($5CDC),DE      ; sv D_STR1 
 +        POP     AF 
 +        RET 
 + 
 +; --- 
 + 
 +<a name="L064C"></a>;; <b>NREPORT-4</b> 
 +L064C:  RST     20H             ; Shadow Error Restart 
 +        DEFB    $03             ; Invalid name 
 + 
 +; ------------------------------------ 
 +; THE <b><font color=#333388>'EVALUATE STREAM NUMBER'</font></b> ROUTINE 
 +; ------------------------------------ 
 +
 + 
 +<a name="L064E"></a>;; <b>EXPT-STRM</b> 
 +L064E:  RST     10H             ; CALBAS 
 +        DEFW    $0020           ; main NEXT-CHAR 
 + 
 + 
 +        RST     10H             ; CALBAS 
 +        DEFW    $1C82           ; main EXPT-1NUM 
 +        RST     18H             ; checking syntax ? 
 +        RET                   ; 
 + 
 +        PUSH    AF              ; 
 +        RST     10H             ; CALBAS 
 +        DEFW    $1E94           ; main FIND-INT1 
 +        CP      $10             ; 
 +        JR      NC,<A href="#L0663">L0663</a>        ; forward to NREPORT-2 
 + 
 +        LD      ($5CD8),      ; sv D_STR1 
 +        POP     AF              ; 
 +        RET                     ; 
 + 
 +; --- 
 + 
 +<a name="L0663"></a>;; <b>NREPORT-2</b> 
 +L0663:  RST     20H             ; Shadow Error Restart 
 +        DEFB    $01             ; Invalid stream number 
 + 
 + 
 +; ---------------------------------- 
 +; THE <b><font color=#333388>'CHECK "M" PARAMETERS'</font></b> ROUTINE 
 +; ---------------------------------- 
 +; called once from TEST-MNAM 
 + 
 +<a name="L0665"></a>;; <b>CHECK-M</b> 
 +L0665:  LD      A,($5CD9)       ; fetch system variable L_STR1 device letter. 
 +        CP      $4D             ; is character "M"
 +        JP      NZ,<A href="#L062D">L062D</a>        ; jump back, if not, to NREPORT-3 
 +                                ; Error: 'Invalid device expression'
 + 
 +<a name="L066D"></a>;; <b>CHECK-M-2</b> 
 +L066D:  LD      DE,($5CD6)      ; fetch system variable D_STR1 drive number. 
 +        LD      A,E             ; test for 
 +        OR      D               ; zero. 
 +        JR      Z,<A href="#L0681">L0681</a>         ; forward, if so, to NREPORT-5 
 +                                ; 'Invalid drive number' 
 + 
 +        INC     DE              ; also test that 
 +        LD      A,E             ; location does not hold 
 +        OR      D               ; the default $FFFF value. 
 +        JR      Z,<A href="#L0683">L0683</a>         ; forward, if so, to NREPORT-9 
 +                                ; 'Missing drive number'
 + 
 +        DEC     DE              ; restore to initial value. 
 +        LD      HL,<A href="#L0008">L0008</a>        ; and test that 
 +        SBC     HL,DE           ; drive is in range 1 - 8. 
 +        RET     NC              ; return if so. 
 + 
 + 
 +<a name="L0681"></a>;; <b>NREPORT-5</b> 
 +L0681:  RST     20H             ; Shadow Error Restart 
 +        DEFB    $04             ; Invalid drive number 
 +; --- 
 + 
 +<a name="L0683"></a>;; <b>NREPORT-9</b> 
 +L0683:  RST     20H             ; Shadow Error Restart 
 +        DEFB    $08             ; Missing drive number 
 + 
 +; ----------------------------------------------- 
 +; THE <b><font color=#333388>'CHECK "M" PARAMETERS AND FILENAME'</font></b> ROUTINE 
 +; ----------------------------------------------- 
 +; This routine checks that the device expression is "M", that the drive is in 
 +; the range 1 - 8 and that the filename is not null. 
 + 
 +<a name="L0685"></a>;; <b>TEST-MNAM</b> 
 +L0685:  CALL    <A href="#L0665">L0665</a>           ; routine CHECK-M checks for "M" and valid  
 +                                ; drive number. 
 + 
 +        LD      A,($5CDB)       ; load A with D_STR1 the high byte of length 
 +                                ; of filename. 
 +        AND                   ; test for zero. 
 +        RET                   ; return if so. 
 + 
 +; else system default $FF. 
 + 
 +        RST     20H             ; Shadow Error Restart 
 +        DEFB    $06             ; Missing name 
 + 
 + 
 +; ---------------------------------- 
 +; THE <b><font color=#333388>'CHECK STATION NUMBER'</font></b> ROUTINE 
 +; ---------------------------------- 
 +
 + 
 +<a name="L068F"></a>;; <b>TEST-STAT</b> 
 +L068F:  LD      DE,($5CD6)      ; sv D_STR1 drive number 
 +        INC     DE 
 +        LD      A,E 
 +        OR      D 
 +        JR      Z,<A href="#L06A1">L06A1</a>         ; forward to NREPORT-8 
 + 
 +        DEC     DE 
 +        LD      HL,L0040 
 +        SBC     HL,DE 
 +        RET     NC 
 + 
 + 
 +<a name="L069F"></a>;; <b>NREPORT-6</b> 
 +L069F:  RST     20H             ; Shadow Error Restart 
 +        DEFB    $05             ; Invalid station number 
 + 
 +<a name="L06A1"></a>;; <b>NREPORT-8</b> 
 +L06A1:  RST     20H             ; Shadow Error Restart 
 +        DEFB    $07             ; Missing station number 
 + 
 +; ----------------------------------- 
 +; THE <b><font color=#333388>'EVALUATE "X";N;"NAME"'</font></b> ROUTINE 
 +; ----------------------------------- 
 +
 + 
 +<a name="L06A3"></a>;; <b>EXPT-EXPR</b> 
 +L06A3:  CALL    <A href="#L05F2">L05F2</a>           ; routine EXPT-SPEC 
 +        CALL    <A href="#L05B1">L05B1</a>           ; routine SEPARATOR 
 +        JP      NZ,<A href="#L04B2">L04B2</a>        ; jump to OREPORT-1 
 +                                ; 'Nonsense in BASIC' 
 + 
 +        CALL    <A href="#L062F">L062F</a>           ; routine EXPT-NAME 
 +        RET                     ; return... 
 + 
 + 
 +; ----------------------------- 
 +; THE <b><font color=#333388>'CHECK BAUD RATE'</font></b> ROUTINE 
 +; ----------------------------- 
 +
 + 
 +<a name="L06B0"></a>;; <b>TEST-BAUD</b> 
 +L06B0:  LD      HL,($5CD6)      ; sv D_STR1 drive number 
 +        INC     HL 
 +        LD      A,L 
 +        OR      H 
 +        RET     NZ 
 + 
 +        RST     20H             ; Shadow Error Restart 
 +        DEFB    $09             ; Missing baud rate 
 + 
 +; ------------------------------------------- 
 +; THE <b><font color=#333388>'EVALUATE STREAM OR EXPRESSION'</font></b> ROUTINE 
 +; ------------------------------------------- 
 +
 + 
 +<a name="L06B9"></a>;; <b>EXPT-EXP1</b> 
 +L06B9:  RST     10H             ; CALBAS 
 +        DEFW    $0020           ; main NEXT-CHAR 
 + 
 + 
 +        CP      $23             ; is character '#'
 +        JP      Z,<A href="#L064E">L064E</a>         ; jump to EXPT-STRM 
 + 
 +        CALL    <A href="#L05F5">L05F5</a>           ; routine EXP-SPEC2 
 +        CALL    <A href="#L05B1">L05B1</a>           ; routine SEPARATOR 
 +        JR      NZ,<A href="#L06CC">L06CC</a>        ; forward to ENDHERE 
 + 
 +        CALL    <A href="#L062F">L062F</a>           ; routine EXPT-NAME 
 + 
 +<a name="L06CC"></a>;; <b>ENDHERE</b> 
 +L06CC:  RST     18H             ; checking syntax ? 
 +        RET     Z 
 + 
 +        LD      A,($5CD9)       ; sv L_STR1 device letter. 
 +        CP      $54             ; is character "T"
 +        RET                   ; 
 + 
 +        CP      $42             ; is character "B"
 +        RET                   ; 
 + 
 +        CP      $4E             ; is character "N"
 +        JP      Z,<A href="#L068F">L068F</a>         ; jump, if so, to TEST-STAT 
 + 
 +        JP      <A href="#L0685">L0685</a>           ; jump to TEST-MNAM 
 + 
 +; --- 
 + 
 +        DEFB    $FF 
 +        DEFB    $FF 
 +        DEFB    $FF 
 +        DEFB    $FF 
 +        DEFB    $FF 
 +        DEFB    $FF 
 +        DEFB    $FF 
 +        DEFB    $FF 
 +        DEFB    $FF 
 +        DEFB    $FF 
 +        DEFB    $FF 
 +        DEFB    $FF 
 +        DEFB    $FF 
 +        DEFB    $FF 
 +        DEFB    $FF 
 +        DEFB    $FF 
 +        DEFB    $FF 
 +        DEFB    $FF 
 +        DEFB    $FF 
 +        DEFB    $FF 
 +        DEFB    $FF 
 +        DEFB    $FF 
 +        DEFB    $FF 
 +        DEFB    $FF 
 +        DEFB    $FF 
 +        DEFB    $FF 
 +        DEFB    $FF 
 +        DEFB    $FF 
 +        DEFB    $FF 
 +        DEFB    $FF 
 +        DEFB    $FF 
 +        DEFB    $FF 
 +        DEFB    $FF 
 + 
 +; -------------------- 
 +; THE <b><font color=#333388>'UNPAGE'</font></b> ROUTINE 
 +; -------------------- 
 +
 + 
 +<a name="L0700"></a>;; <b>UNPAGE</b> 
 +L0700:  RET 
 + 
 + 
 +; --------------------------------- 
 +; THE <b><font color=#333388>'EVALUATE PARAMETERS'</font></b> ROUTINE 
 +; --------------------------------- 
 +
 + 
 +<a name="L0701"></a>;; <b>EXPT-PRMS</b> 
 +L0701:  RST     10H             ; CALBAS 
 +        DEFW    $0020           ; main NEXT-CHAR 
 + 
 + 
 +        CP      $2A             ; is character '*' 
 +        JR      NZ,<A href="#L073C">L073C</a>        ; forward, if not, to OREP-1-2 
 + 
 +        RST     10H             ; CALBAS 
 +        DEFW    $0020           ; main NEXT-CHAR 
 + 
 + 
 +        CALL    <A href="#L05F5">L05F5</a>           ; routine EXP-SPEC2 
 +        CALL    <A href="#L05B1">L05B1</a>           ; routine SEPARATOR 
 +        JR      NZ,<A href="#L0716">L0716</a>        ; forward to NO-NAME 
 + 
 +        CALL    <A href="#L062F">L062F</a>           ; routine EXPT-NAME 
 + 
 +<a name="L0716"></a>;; <b>NO-NAME</b> 
 +L0716:  PUSH    AF 
 +        LD      A,($5CD9)       ; sv L_STR1 device letter. 
 + 
 +        CP      $4E             ; is character "N"
 +        JR      NZ,<A href="#L0722">L0722</a>        ; forward, if not, to NOT-NET 
 + 
 +        SET     3,(IY+$7C)      ; update FLAGS_3 signal networking. 
 + 
 +<a name="L0722"></a>;; <b>NOT-NET</b> 
 +L0722:  POP     AF 
 +        CP      $0D             ; is character carriage return ? 
 +        JR      Z,<A href="#L0750">L0750</a>         ; forward to END-EXPT 
 + 
 +        CP      $3A             ; is character ':'
 +        JR      Z,<A href="#L0750">L0750</a>         ; forward to END-EXPT 
 + 
 +        CP      $AA             ; is character the token 'SCREEN$'
 +        JR      Z,<A href="#L0771">L0771</a>         ; forward to SCREEN$ 
 + 
 +        CP      $AF             ; is character the token 'CODE'
 +        JR      Z,<A href="#L0789">L0789</a>         ; forward to CODE 
 + 
 +        CP      $CA             ; is character the token 'LINE'
 +        JR      Z,<A href="#L073E">L073E</a>         ; forward to LINE 
 + 
 +        CP      $E4             ; is character the token 'DATA'
 +        JP      Z,<A href="#L07D2">L07D2</a>         ; jump to DATA 
 + 
 +<a name="L073C"></a>;; <b>OREP-1-2</b> 
 +L073C:  RST     20H             ; Shadow Error Restart 
 +        DEFB    $00             ; Nonsense in BASIC 
 + 
 +; --- 
 + 
 +<a name="L073E"></a>;; <b>LINE</b> 
 +L073E:  RST     10H             ; CALBAS 
 +        DEFW    $0020           ; main NEXT-CHAR 
 + 
 +        RST     10H             ; CALBAS 
 +        DEFW    $1C82           ; main EXPT-1NUM 
 + 
 +        CALL    <A href="#L05B7">L05B7</a>           ; routine ST-END 
 + 
 +        RST     10H             ; CALBAS 
 +        DEFW    $1E99           ; main FIND-INT2 
 + 
 +        LD      ($5CED),BC      ; sv HD_11 
 +        JR      <A href="#L0753">L0753</a>           ; forward to PROG 
 + 
 +; --- 
 + 
 +<a name="L0750"></a>;; <b>END-EXPT</b> 
 +L0750:  CALL    <A href="#L05B7">L05B7</a>           ; routine ST-END 
 + 
 +; the 'PROGRAM' SUBROUTINE is used when loading 'run'
 + 
 +<a name="L0753"></a>;; <b>PROG</b> 
 +L0753:  XOR                   ; 
 +        LD      ($5CE6),      ; sv HD_00 
 +        LD      HL,($5C59)      ; sv E_LINE 
 +        LD      DE,($5C53)      ; sv PROG 
 +        LD      ($5CE9),DE      ; sv HD_0D 
 +        SCF                     ; 
 +        SBC     HL,DE           ; 
 +        LD      ($5CE7),HL      ; sv HD_0B 
 +        LD      HL,($5C4B)      ; sv VARS 
 +        SBC     HL,DE           ; 
 +        LD      ($5CEB),HL      ; sv HD_0F 
 +        RET 
 + 
 +; --- 
 + 
 +<a name="L0771"></a>;; <b>SCREEN$</b> 
 +L0771:  RST     10H             ; CALBAS 
 +        DEFW    $0020           ; main NEXT-CHAR 
 + 
 +        CALL    <A href="#L05B7">L05B7</a>           ; routine ST-END 
 +        LD      HL,$1B00 
 +        LD      ($5CE7),HL      ; sv HD_0B 
 +        LD      HL,$4000 
 +        LD      ($5CE9),HL      ; sv HD_0D 
 +        LD      A,$03 
 +        LD      ($5CE6),      ; sv HD_00 
 +        RET 
 + 
 +; --- 
 + 
 +<a name="L0789"></a>;; <b>CODE</b> 
 +L0789:  RST     10H             ; CALBAS 
 +        DEFW    $0020           ; main NEXT-CHAR 
 + 
 +        CP      $0D             ; is character a carriage return ? 
 +        JR      Z,<A href="#L079A">L079A</a>         ; forward to DEFLT-0 
 + 
 +        CP      $3A             ; is character a ':'
 +        JR      NZ,<A href="#L079F">L079F</a>        ; forward to PAR-1 
 + 
 +        BIT     5,(IY+$7C)      ; sv FLAGS_3 
 +        JR      NZ,<A href="#L073C">L073C</a>        ; back to OREP-1-2 
 + 
 + 
 +<a name="L079A"></a>;; <b>DEFLT-0</b> 
 +L079A:  RST     10H             ; CALBAS 
 +        DEFW    $1CE6           ; main USE-ZERO 
 +        JR      <A href="#L07A7">L07A7</a>           ; forward to TEST-SAVE 
 + 
 +; --- 
 + 
 +<a name="L079F"></a>;; <b>PAR-1</b> 
 +L079F:  RST     10H             ; CALBAS 
 +        DEFW    $1C82           ; main EXPT-1NUM 
 +        CALL    <A href="#L05B1">L05B1</a>           ; routine SEPARATOR 
 +        JR      Z,<A href="#L07B2">L07B2</a>         ; forward to PAR-2 
 + 
 + 
 +<a name="L07A7"></a>;; <b>TEST-SAVE</b> 
 +L07A7:  BIT     5,(IY+$7C)      ; sv FLAGS_3 
 +        JR      NZ,<A href="#L073C">L073C</a>        ; back to OREP-1-2 
 + 
 +        RST     10H             ; CALBAS 
 +        DEFW    $1CE6           ; main USE-ZERO 
 +        JR      <A href="#L07B8">L07B8</a>           ; forward to END-CODE 
 + 
 +; --- 
 + 
 +<a name="L07B2"></a>;; <b>PAR-2</b> 
 +L07B2:  RST     10H             ; CALBAS 
 +        DEFW    $0020           ; main NEXT-CHAR 
 + 
 + 
 +        RST     10H             ; CALBAS 
 +        DEFW    $1C82           ; main EXPT-1NUM 
 + 
 +<a name="L07B8"></a>;; <b>END-CODE</b> 
 +L07B8:  RST     10H             ; CALBAS 
 +        DEFW    $0018           ; main GET-CHAR 
 + 
 +        CALL    <A href="#L05B7">L05B7</a>           ; routine ST-END 
 + 
 +        RST     10H             ; CALBAS 
 +        DEFW    $1E99           ; main FIND-INT2 
 +        LD      ($5CE7),BC      ; sv HD_0B 
 + 
 +        RST     10H             ; CALBAS 
 +        DEFW    $1E99           ; main FIND-INT2 
 +        LD      ($5CE9),BC      ; sv HD_0D 
 + 
 +        LD      A,$03 
 +        LD      ($5CE6),      ; sv HD_00 
 +        RET                     ; return. 
 + 
 +; --- 
 +
 +; --- 
 + 
 + 
 +<a name="L07D2"></a>;; <b>DATA</b> 
 +L07D2:  BIT     6,(IY+$7C)      ; sv FLAGS_3 
 +        JR      Z,<A href="#L07DA">L07DA</a>         ; forward to NO-M-ARR 
 + 
 +        RST     20H             ; Shadow Error Restart 
 +        DEFB    $14             ; MERGE error 
 + 
 +<a name="L07DA"></a>;; <b>NO-M-ARR</b> 
 +L07DA:  RST     10H             ; CALBAS 
 +        DEFW    $0020           ; main NEXT-CHAR 
 + 
 + 
 +        RST     10H             ; CALBAS 
 +        DEFW    $28B2           ; main LOOK-VARS 
 + 
 +        SET     7,C 
 +        JR      NC,<A href="#L07F2">L07F2</a>        ; forward to EXISTING 
 + 
 +        LD      HL,$0000 
 +        BIT     4,(IY+$7C)      ; sv FLAGS_3 
 +        JR      NZ,<A href="#L080E">L080E</a>        ; forward to LD-DATA 
 + 
 +        LD      (IY+$00),$01    ; sv ERR_NR to '2 Variable not found' 
 +        RST     28H             ; Error Main ROM 
 + 
 +; --- 
 + 
 +<a name="L07F2"></a>;; <b>EXISTING</b> 
 +L07F2:  JR      Z,<A href="#L07F6">L07F6</a>         ; forward to G-TYPE 
 + 
 + 
 +<a name="L07F4"></a>;; <b>NONS-BSC</b> 
 +L07F4:  RST     20H             ; Shadow Error Restart 
 +        DEFB    $00             ; Nonsense in BASIC 
 + 
 +; --- 
 + 
 +<a name="L07F6"></a>;; <b>G-TYPE</b> 
 +L07F6:  RST     18H             ; checking syntax ? 
 +        JR      Z,<A href="#L081C">L081C</a>         ; forward to END-DATA 
 + 
 +        BIT     5,(IY+$7C)      ; sv FLAGS_3 
 +        JR      Z,<A href="#L0803">L0803</a>         ; forward to VR-DATA 
 + 
 +        BIT     7,(HL) 
 +        JR      Z,<A href="#L07F4">L07F4</a>         ; back to NONS-BSC 
 + 
 + 
 +<a name="L0803"></a>;; <b>VR-DATA</b> 
 +L0803:  INC     HL 
 +        LD      A,(HL) 
 +        LD      ($5CE7),      ; sv HD_0B 
 +        INC     HL 
 +        LD      A,(HL) 
 +        LD      ($5CE8),      ; sv HD_0B_hi 
 +        INC     HL 
 + 
 +<a name="L080E"></a>;; <b>LD-DATA</b> 
 +L080E:  LD      A,C 
 +        LD      ($5CEB),      ; sv HD_0F 
 +        LD      A,$01 
 +        BIT     6,C 
 +        JR      Z,<A href="#L0819">L0819</a>         ; forward to NUM-ARR 
 + 
 +        INC     A 
 + 
 +<a name="L0819"></a>;; <b>NUM-ARR</b> 
 +L0819:  LD      ($5CE6),      ; sv HD_00 
 + 
 +<a name="L081C"></a>;; <b>END-DATA</b> 
 +L081C:  EX      DE,HL 
 +        RST     10H             ; CALBAS 
 +        DEFW    $0020           ; main NEXT-CHAR 
 + 
 + 
 +        CP      $29             ; is character ')'
 +        JR      NZ,<A href="#L07F4">L07F4</a>        ; back to NONS-BSC 
 + 
 +        RST     10H             ; CALBAS 
 +        DEFW    $0020           ; main NEXT-CHAR 
 + 
 + 
 +        CALL    <A href="#L05B7">L05B7</a>           ; routine ST-END 
 +        LD      ($5CE9),DE      ; sv HD_0D 
 +        RET                     ; return. 
 + 
 + 
 +; --------------------------------- 
 +; THE <b><font color=#333388>'SAVE COMMAND SYNTAX'</font></b> ROUTINE 
 +; --------------------------------- 
 +
 + 
 +<a name="L082F"></a>;; <b>SAVE-SYN</b> 
 +L082F:  SET     5,(IY+$7C)      ; sv FLAGS_3 
 +        CALL    <A href="#L0701">L0701</a>           ; routine EXPT-PRMS 
 + 
 +        LD      A,($5CD9)       ; sv L_STR1 device letter. 
 + 
 +        CP      $42             ; is character 'B'
 +        JR      Z,<A href="#L084F">L084F</a>         ; forward to SA-HEADER 
 + 
 +        CP      $4E             ; is character 'N'
 +        JR      NZ,<A href="#L0849">L0849</a>        ; forward to SAVE-M 
 + 
 +        CALL    <A href="#L068F">L068F</a>           ; routine TEST-STAT 
 +        CALL    <A href="#L0F46">L0F46</a>           ; routine OP-TEMP-N 
 +        JR      <A href="#L084F">L084F</a>           ; forward to SA-HEADER 
 + 
 +; --- 
 + 
 +<a name="L0849"></a>;; <b>SAVE-M</b> 
 +L0849:  CALL    <A href="#L0685">L0685</a>           ; routine TEST-MNAM 
 +        JP      <A href="#L1AC4">L1AC4</a>           ; jump to SAVE-RUN 
 + 
 +; --- 
 + 
 +<a name="L084F"></a>;; <b>SA-HEADER</b> 
 +L084F:  LD      B,$09 
 +        LD      HL,$5CE6        ; sv HD_00 
 + 
 +<a name="L0854"></a>;; <b>HD-LOOP</b> 
 +L0854:  CALL    <A href="#L0884">L0884</a>           ; routine SA-BYTE 
 +        INC     HL 
 +        DJNZ    <A href="#L0854">L0854</a>           ; back to HD-LOOP 
 + 
 +        LD      HL,($5CE9)      ; sv HD_0D 
 +        BIT     3,(IY+$7C)      ; sv FLAGS_3 
 +        JR      Z,<A href="#L086E">L086E</a>         ; forward to SA-BLOCK 
 + 
 +        LD      A,($5CE6)       ; sv HD_00 
 +        CP      $03             ; compare with three - type CODE 
 +        JR      NC,<A href="#L086E">L086E</a>        ; forward to SA-BLOCK 
 + 
 +        LD      DE,$0114        ; 
 +        ADD     HL,DE           ; 
 + 
 +<a name="L086E"></a>;; <b>SA-BLOCK</b> 
 +L086E:  LD      BC,($5CE7)      ; sv HD_0B 
 + 
 +<a name="L0872"></a>;; <b>SA-BLK-LP</b> 
 +L0872:  LD      A,C             ; 
 +        OR      B               ; 
 +        JR      Z,<A href="#L0881">L0881</a>         ; forward to S-BLK-END 
 + 
 +        PUSH    IX              ;;; 
 + 
 +        CALL    <A href="#L0884">L0884</a>           ; routine SA-BYTE 
 + 
 +        POP     IX              ;;; 
 + 
 +        DEC     BC              ; 
 +        INC     HL              ; 
 +        JR      <A href="#L0872">L0872</a>           ; back to SA-BLK-LP 
 + 
 +; --- 
 + 
 +<a name="L0881"></a>;; <b>S-BLK-END</b> 
 +L0881:  JP      <A href="#L098C">L098C</a>           ; jump to TST-MR-M 
 + 
 +; -------------------------------------------------- 
 +; THE <b><font color=#333388>'SAVE A BYTE TO NETWORK OR RS232 LINK'</font></b> ROUTINE 
 +; -------------------------------------------------- 
 +
 + 
 +<a name="L0884"></a>;; <b>SA-BYTE</b> 
 +L0884:  PUSH    HL              ; 
 +        PUSH    BC              ; 
 +        BIT     3,(IY+$7C)      ; sv FLAGS_3 
 +        LD      A,(HL)          ; 
 +        JR      NZ,<A href="#L0892">L0892</a>        ; forward to SA-NET 
 + 
 +        CALL    <A href="#L0D07">L0D07</a>           ; routine BCHAN-OUT 
 +        JR      <A href="#L0895">L0895</a>           ; forward to SA-B-END 
 + 
 +; --- 
 + 
 +<a name="L0892"></a>;; <b>SA-NET</b> 
 +L0892:  CALL    <A href="#L0E09">L0E09</a>           ; routine NCHAN-OUT 
 + 
 +<a name="L0895"></a>;; <b>SA-B-END</b> 
 +L0895:  POP     BC              ; 
 +        POP     HL              ; 
 +        RET                     ; 
 + 
 + 
 +; --------------------------------- 
 +; THE <b><font color=#333388>'LOAD COMMAND SYNTAX'</font></b> ROUTINE 
 +; --------------------------------- 
 +
 + 
 +<a name="L0898"></a>;; <b>LOAD-SYN</b> 
 +L0898:  SET     4,(IY+$7C)      ; sv FLAGS_3 
 +        CALL    <A href="#L0701">L0701</a>           ; routine EXPT-PRMS 
 +        JP      <A href="#L08B3">L08B3</a>           ; jump to LD-VF-MR 
 + 
 +; ----------------------------------- 
 +; THE <b><font color=#333388>'VERIFY COMMAND SYNTAX'</font></b> ROUTINE 
 +; ----------------------------------- 
 +
 + 
 +<a name="L08A2"></a>;; <b>VERIF-SYN</b> 
 +L08A2:  SET     7,(IY+$7C)      ; sv FLAGS_3 
 +        CALL    <A href="#L0701">L0701</a>           ; routine EXPT-PRMS 
 +        JP      <A href="#L08B3">L08B3</a>           ; jump to LD-VF-MR 
 + 
 +; ---------------------------------- 
 +; THE <b><font color=#333388>'MERGE COMMAND SYNTAX'</font></b> ROUTINE 
 +; ---------------------------------- 
 +
 + 
 +<a name="L08AC"></a>;; <b>MRG-SYN</b> 
 +L08AC:  SET     6,(IY+$7C)      ; sv FLAGS_3 
 +        CALL    <A href="#L0701">L0701</a>           ; routine EXPT-PRMS 
 + 
 +; ---------------------------------------- 
 +; THE <b><font color=#333388>'LOAD-VERIFY-MERGE COMMANDS'</font></b> ROUTINE 
 +; ---------------------------------------- 
 +
 + 
 +<a name="L08B3"></a>;; <b>LD-VF-MR</b> 
 +L08B3:  LD      HL,$5CE6        ; set source to HD_00 
 +        LD      DE,$5CDE        ; set destination to D_STR2 
 +        LD      BC,$0007        ; seven bytes to copy. 
 +        LDIR                    ; copy type, start, length, length of program. 
 + 
 +        LD      A,($5CD9)       ; sv L_STR1 device letter. 
 + 
 +        CP      $4E             ; "N"
 + 
 +        JR      Z,<A href="#L08D1">L08D1</a>         ; forward to TS-L-NET 
 + 
 +        CP      $42             ; "B"
 + 
 +        JR      Z,<A href="#L08D7">L08D7</a>         ; forward to TS-L-RS 
 + 
 +; proceed with Microdrive device. 
 + 
 +        CALL    <A href="#L0685">L0685</a>           ; routine TEST-MNAM return without error if 
 +                                ; device is "M" and drive and filename are OK. 
 + 
 +        CALL    <A href="#L1971">L1971</a>           ; routine F-M-HEAD loads the header type 
 +                                ; record for the above filename and populates 
 +                                ; the locations HD_00 to HD_11. 
 + 
 +        JR      <A href="#L08F6">L08F6</a>           ; forward to TEST-TYPE which tests that file 
 +                                ; types agree and then loads rest of records. 
 + 
 +; --- 
 + 
 +<a name="L08D1"></a>;; <b>TS-L-NET</b> 
 +L08D1:  CALL    <A href="#L068F">L068F</a>           ; routine TEST-STAT 
 +        CALL    <A href="#L0F46">L0F46</a>           ; routine OP-TEMP-N 
 + 
 +<a name="L08D7"></a>;; <b>TS-L-RS</b> 
 +L08D7:  LD      HL,$5CE6        ; sv HD_00 
 +        LD      B,$09           ; 
 + 
 +<a name="L08DC"></a>;; <b>LD-HEADER</b> 
 +L08DC:  PUSH    HL 
 +        PUSH    BC 
 +        BIT     3,(IY+$7C)      ; sv FLAGS_3 
 +        JR      Z,<A href="#L08EB">L08EB</a>         ; forward to LD-HD-RS 
 + 
 + 
 +<a name="L08E4"></a>;; <b>LD-HD-NET</b> 
 +L08E4:  CALL    <A href="#L0DAF">L0DAF</a>           ; routine NCHAN-IN 
 +        JR      NC,<A href="#L08E4">L08E4</a>        ; back to LD-HD-NET 
 + 
 +        JR      <A href="#L08F0">L08F0</a>           ; forward to LD-HDR-2 
 + 
 +; --- 
 + 
 +<a name="L08EB"></a>;; <b>LD-HD-RS</b> 
 +L08EB:  CALL    <A href="#L0B88">L0B88</a>           ; routine BCHAN-IN 
 +        JR      NC,<A href="#L08EB">L08EB</a>        ; back to LD-HD-RS 
 + 
 + 
 +<a name="L08F0"></a>;; <b>LD-HDR-2</b> 
 +L08F0:  POP     BC 
 +        POP     HL 
 +        LD      (HL),A 
 +        INC     HL 
 +        DJNZ    <A href="#L08DC">L08DC</a>           ; back to LD-HEADER 
 + 
 +; --&gt; 
 + 
 +<a name="L08F6"></a>;; <b>TEST-TYPE</b> 
 +L08F6:  LD      A,($5CDE)       ; sv D_STR2 
 +        LD      B,A 
 +        LD      A,($5CE6)       ; sv HD_00 
 +        CP      B 
 +        JR      NZ,<A href="#L0906">L0906</a>        ; forward to NREPORT-N 
 + 
 +        CP      $03             ; compare with three - type CODE 
 +        JR      Z,<A href="#L0915">L0915</a>         ; forward to T-M-CODE 
 + 
 +        JR      C,<A href="#L0908">L0908</a>         ; forward to TST-MERGE 
 + 
 +<a name="L0906"></a>;; <b>NREPORT-N</b> 
 +L0906:  RST     20H             ; Shadow Error Restart 
 +        DEFB    $16             ; Wrong file type 
 + 
 +; --- 
 + 
 +<a name="L0908"></a>;; <b>TST-MERGE</b> 
 +L0908:  BIT     6,(IY+$7C)      ; sv FLAGS_3 
 +        JR      NZ,<A href="#L096B">L096B</a>        ; forward to MERGE-BLK 
 + 
 +        BIT     7,(IY+$7C)      ; sv FLAGS_3 
 +        JP      Z,<A href="#L09A7">L09A7</a>         ; jump to LD-PR-AR 
 + 
 +<a name="L0915"></a>;; <b>T-M-CODE</b> 
 +L0915:  BIT     6,(IY+$7C)      ; sv FLAGS_3 
 +        JR      Z,<A href="#L091D">L091D</a>         ; forward to LD-BLOCK 
 + 
 +        RST     20H             ; Shadow Error Restart 
 +        DEFB    $14             ; MERGE error 
 + 
 +; --- 
 + 
 +<a name="L091D"></a>;; <b>LD-BLOCK</b> 
 +L091D:  LD      HL,($5CDF)      ; sv D_STR2 (+1) length of data 
 +        LD      DE,($5CE7)      ; sv HD_0B 
 +        LD      A,H             ; 
 +        OR      L               ; 
 +        JR      Z,<A href="#L0936">L0936</a>         ; forward to LD-BLK-2 
 + 
 +        SBC     HL,DE           ; 
 +        JR      NC,<A href="#L0936">L0936</a>        ; forward to LD-BLK-2 
 + 
 +        BIT     4,(IY+$7C)      ; sv FLAGS_3 
 +        JR      Z,<A href="#L0934">L0934</a>         ; forward to NREPORT-L 
 + 
 +        RST     20H             ; Shadow Error Restart 
 +        DEFB    $13             ; Code Error 
 + 
 +; --- 
 + 
 +<a name="L0934"></a>;; <b>NREPORT-L</b> 
 +L0934:  RST     20H             ; Shadow Error Restart 
 +        DEFB    $15             ; Verification has failed 
 + 
 +; --- 
 + 
 +<a name="L0936"></a>;; <b>LD-BLK-2</b> 
 +L0936:  LD      HL,($5CE1)      ; sv L_STR2 
 +        LD      A,(IX+$04)      ; channel letter 
 +        CP      $CD             ; 'M' +$80 ? 
 +        JR      NZ,<A href="#L0945">L0945</a>        ; forward to LD-BLK-3 
 + 
 +        LD      HL,($5CE4)      ; sv D_STR2             ******** 
 +        JR      <A href="#L0956">L0956</a>           ; forward to LD-BLK-4 
 + 
 +; --- 
 + 
 +<a name="L0945"></a>;; <b>LD-BLK-3</b> 
 +L0945:  BIT     3,(IY+$7C)      ; sv FLAGS_3 
 +        JR      Z,<A href="#L0956">L0956</a>         ; forward to LD-BLK-4 
 + 
 +        LD      A,($5CE6)       ; sv HD_00 
 +        CP      $03             ; compare with three - type CODE 
 +        JR      Z,<A href="#L0956">L0956</a>         ; forward to LD-BLK-4 
 + 
 +        LD      BC,$0114        ; 
 +        ADD     HL,BC           ; 
 + 
 +<a name="L0956"></a>;; <b>LD-BLK-4</b> 
 +L0956:  LD      A,H             ; 
 +        OR      L               ; 
 +        JR      NZ,<A href="#L095D">L095D</a>        ; forward to LD-BLK-5 
 + 
 +        LD      HL,($5CE9)      ; sv HD_0D 
 + 
 +<a name="L095D"></a>;; <b>LD-BLK-5</b> 
 +L095D:  LD      A,($5CE6)       ; sv HD_00 
 +        AND                   ; 
 +        JR      NZ,<A href="#L0966">L0966</a>        ; forward to LD-NO-PGM 
 + 
 +        LD      HL,($5C53)      ; sv PROG 
 + 
 +<a name="L0966"></a>;; <b>LD-NO-PGM</b> 
 +L0966:  CALL    <A href="#L0A60">L0A60</a>           ; routine LV-ANY 
 +        JR      <A href="#L098C">L098C</a>           ; forward to TST-MR-M 
 + 
 +; --- 
 + 
 + 
 +<a name="L096B"></a>;; <b>MERGE-BLK</b> 
 +L096B:  LD      A,($5CEE)       ; sv HD_11_hi 
 +        AND     $C0             ; 
 +        JR      NZ,<A href="#L0977">L0977</a>        ; forward to NO-AUTOST 
 + 
 +        CALL    <A href="#L17B7">L17B7</a>           ; routine RCL-T-CH 
 + 
 + 
 +        RST     20H             ; Shadow Error Restart 
 +        DEFB    $14             ; MERGE error 
 + 
 +; --- 
 + 
 +<a name="L0977"></a>;; <b>NO-AUTOST</b> 
 +L0977:  LD      BC,($5CE7)      ; sv HD_0B 
 +        PUSH    BC              ; 
 +        INC     BC              ; 
 + 
 +        RST     10H             ; CALBAS 
 +        DEFW    $0030           ; main BC-SPACES 
 + 
 +        LD      (HL),$80        ; 
 +        EX      DE,HL           ; 
 +        POP     DE              ; 
 +        PUSH    HL              ; 
 +        CALL    <A href="#L0A60">L0A60</a>           ; routine LV-ANY 
 +        POP     HL              ; 
 + 
 +        RST     10H             ; CALBAS 
 +        DEFW    $08CE           ; main ME-CTRLX 
 + 
 +; --- 
 + 
 +<a name="L098C"></a>;; <b>TST-MR-M</b> 
 +L098C:  LD      A,(IX+$04)      ; channel letter 
 +        CP      $CD             ; 'M' + $80 ? 
 +        JR      NZ,<A href="#L0998">L0998</a>        ; forward to TST-MR-N 
 + 
 +        CALL    <A href="#L138E">L138E</a>           ; routine CLOSE-M2 
 +        JR      <A href="#L09A4">L09A4</a>           ; forward to MERGE-END 
 + 
 +; --- 
 + 
 +<a name="L0998"></a>;; <b>TST-MR-N</b> 
 +L0998:  BIT     3,(IY+$7C)      ; sv FLAGS_3 
 +        JR      Z,<A href="#L09A4">L09A4</a>         ; forward to MERGE-END 
 + 
 +        CALL    <A href="#L0FAE">L0FAE</a>           ; routine SEND-NEOF 
 +        CALL    <A href="#L17B7">L17B7</a>           ; routine RCL-T-CH 
 + 
 +<a name="L09A4"></a>;; <b>MERGE-END</b> 
 +L09A4:  JP      <A href="#L05C1">L05C1</a>           ; jump to END1 
 + 
 +; --- 
 + 
 +<a name="L09A7"></a>;; <b>LD-PR-AR</b> 
 +L09A7:  LD      DE,($5CE7)      ; sv HD_0B 
 +        LD      HL,($5CE1)      ; sv L_STR2 
 +        PUSH    HL              ; 
 +        LD      A,H             ; 
 +        OR      L               ; 
 +        JR      NZ,<A href="#L09B9">L09B9</a>        ; forward to LD-PROG 
 + 
 +        INC     DE              ; 
 +        INC     DE              ; 
 +        INC     DE              ; 
 +        EX      DE,HL           ; 
 +        JR      <A href="#L09C2">L09C2</a>           ; forward to TST-SPACE 
 + 
 +; --- 
 + 
 + 
 +<a name="L09B9"></a>;; <b>LD-PROG</b> 
 +L09B9:  LD      HL,($5CDF)      ; sv D_STR2 (+1) length of data 
 +        EX      DE,HL           ; 
 +        SCF                     ; 
 +        SBC     HL,DE           ; 
 +        JR      C,<A href="#L09CB">L09CB</a>         ; forward to TST-TYPE 
 + 
 + 
 +<a name="L09C2"></a>;; <b>TST-SPACE</b> 
 +L09C2:  LD      DE,$0005        ; 
 +        ADD     HL,DE           ; 
 +        LD      B,H             ; 
 +        LD      C,L             ; 
 + 
 +        RST     10H             ; CALBAS 
 +        DEFW    $1F05           ; main TEST-ROOM 
 + 
 +;   <font color=#9900FF>Note.</font> that before the above call, interrupts are disabled and the motor 
 +;   of the microdrive is running.  If there should be insufficient room, 
 +;   then the processor stops at the HALT instruction at address $1303 
 +;   (MAIN-4), in the main ROM, while trying to output the "Out of Memory" 
 +;   report.  This could be corrected by replacing the above 3 bytes to a 
 +;   call to a 6-byte subroutine which carries out the same instructions 
 +;   between an EI/DI pair.  In the production of the "Out of Memory" report 
 +;   this ROM will be paged again by the instruction fetch at 0008. The 
 +;   motors are stopped at START-4 and then Control will then pass to the 
 +;   other ROM to execute the "LD A,(HL)", then back to this ROM to eliminate 
 +;   the "OK" message before a final switch to the Main ROM for the actual 
 +;   message text. 
 + 
 +<a name="L09CB"></a>;; <b>TST-TYPE</b> 
 +L09CB:  POP     HL 
 +        LD      A,($5CE6)       ; sv HD_00 
 +        AND     A 
 +        JR      Z,<A href="#L0A19">L0A19</a>         ; forward to SET-PROG 
 + 
 +        LD      A,H 
 +        OR      L 
 +        JR      Z,<A href="#L09F7">L09F7</a>         ; forward to CRT-NEW 
 + 
 +        LD      A,(IX+$04)      ; channel letter 
 +        CP      $CD             ; is character an inverted "M"
 +        JR      NZ,<A href="#L09E2">L09E2</a>        ; forward to T-LD-NET 
 + 
 +        LD      HL,($5CE4)      ; sv D_STR2 
 +        JR      <A href="#L09EC">L09EC</a>           ; forward to RCLM-OLD 
 + 
 +; --- 
 + 
 +<a name="L09E2"></a>;; <b>T-LD-NET</b> 
 +L09E2:  BIT     3,(IY+$7C)      ; sv FLAGS_3 
 +        JR      Z,<A href="#L09EC">L09EC</a>         ; forward to RCLM-OLD 
 + 
 +        LD      DE,$0114 
 +        ADD     HL,DE 
 + 
 +<a name="L09EC"></a>;; <b>RCLM-OLD</b> 
 +L09EC:  DEC     HL 
 +        LD      B,(HL) 
 +        DEC     HL 
 +        LD      C,(HL) 
 +        DEC     HL 
 +        INC     BC 
 +        INC     BC 
 +        INC     BC 
 +        RST     10H             ; CALBAS 
 +        DEFW    $19E8           ; main RECLAIM-2 
 + 
 +<a name="L09F7"></a>;; <b>CRT-NEW</b> 
 +L09F7:  LD      HL,($5C59)      ; sv E_LINE 
 +        DEC     HL 
 +        LD      BC,($5CE7)      ; sv HD_0B 
 +        PUSH    BC 
 +        INC     BC 
 +        INC     BC 
 +        INC     BC 
 +        LD      A,($5CE3)       ; sv D_STR2 
 +        PUSH    AF 
 +        RST     10H             ; CALBAS 
 +        DEFW    $1655           ; main MAKE-ROOM 
 +        INC     HL 
 +        POP     AF 
 +        LD      (HL),A 
 +        POP     DE 
 +        INC     HL 
 +        LD      (HL),E 
 +        INC     HL 
 +        LD      (HL),D 
 +        INC     HL 
 + 
 +<a name="L0A13"></a>;; <b>END-LD-PR</b> 
 +L0A13:  CALL    <A href="#L0A60">L0A60</a>           ; routine LV-ANY 
 + 
 +        JP      <A href="#L098C">L098C</a>           ; jump to TST-MR-M 
 + 
 +; --- 
 + 
 +<a name="L0A19"></a>;; <b>SET-PROG</b> 
 +L0A19:  RES     1,(IY+$7C)      ; sv FLAGS_3 
 +        LD      DE,($5C53)      ; sv PROG 
 +        LD      HL,($5C59)      ; sv E_LINE 
 +        DEC     HL 
 +        RST     10H             ; CALBAS 
 +        DEFW    $19E5           ; main RECLAIM-1 
 +        LD      BC,($5CE7)      ; sv HD_0B 
 +        LD      HL,($5C53)      ; sv PROG 
 +        RST     10H             ; CALBAS 
 +        DEFW    $1655           ; main MAKE-ROOM 
 +        INC     HL 
 +        LD      BC,($5CEB)      ; sv HD_0F 
 +        ADD     HL,BC 
 +        LD      ($5C4B),HL      ; sv VARS 
 +        LD      A,($5CEE)       ; sv HD_11_hi 
 +        LD      H,A 
 +        AND     $C0 
 +        JR      NZ,<A href="#L0A52">L0A52</a>        ; forward to NO-AUTO 
 + 
 +        SET     1,(IY+$7C)      ; sv FLAGS_3 
 +        LD      A,($5CED)       ; sv HD_11 
 +        LD      L,A 
 +        LD      ($5C42),HL      ; sv NEWPPC 
 +        LD      (IY+$0A),$00    ; sv NSPPC 
 + 
 +<a name="L0A52"></a>;; <b>NO-AUTO</b> 
 +L0A52:  LD      HL,($5C53)      ; sv PROG 
 +        LD      DE,($5CE7)      ; sv HD_0B 
 +        DEC     HL 
 +        LD      ($5C57),HL      ; sv DATADD 
 +        INC     HL 
 +        JR      <A href="#L0A13">L0A13</a>           ; back to END-LD-PR 
 + 
 + 
 +; ---------------------------- 
 +; THE <b><font color=#333388>'LOAD OR VERIFY'</font></b> ROUTINE 
 +; ---------------------------- 
 +;   This routine is able to either LOAD or VERIFY a block of bytes, from any  
 +;   of the three possible binary sources, A Microdrive cartridge, the Binary 
 +;   "B" RS232 channel or the Network "N" channel. 
 +;   The block could be a program, code bytes or an array and the first  
 +;   receiving location is in HL and the length in DE. 
 + 
 +<a name="L0A60"></a>;; <b>LV-ANY</b> 
 +L0A60:  LD      A,D             ; test the length 
 +        OR      E               ; for zero. 
 +        RET                   ; return if so. 
 + 
 +        LD      A,(IX+$04)      ; fetch channel letter 
 +        CP      $CD             ; is letter "M" + $80 ? 
 + 
 +        JR      NZ,<A href="#L0A6E">L0A6E</a>        ; forward, if not, to LV-BN to load from  
 +                                ; the B channel or network. 
 + 
 +; else is a temporary "M" channel so load or verify and then return. 
 + 
 +        CALL    <A href="#L199A">L199A</a>           ; routine LV-MCH loads or verifies a block 
 +                                ; of code from microdrive. 
 + 
 +        RET                     ; return after called routine. 
 + 
 +; --- 
 + 
 +; Load or Verify from B channel or Network. 
 + 
 +<a name="L0A6E"></a>;; <b>LV-BN</b> 
 +L0A6E:  PUSH    HL              ; save address. 
 +        PUSH    DE              ; save byte count. 
 +        BIT     3,(IY+$7C)      ; test FLAGS_3 - using network ? 
 +        JR      Z,<A href="#L0A7D">L0A7D</a>         ; forward, if not, to LV-B 
 + 
 +; Load or Verify from "N" channel. 
 + 
 +<a name="L0A76"></a>;; <b>LV-N</b> 
 +L0A76:  CALL    <A href="#L0DAF">L0DAF</a>           ; routine NCHAN-IN 
 +        JR      NC,<A href="#L0A76">L0A76</a>        ; back to LV-N 
 + 
 +        JR      <A href="#L0A82">L0A82</a>           ; forward to LV-BN-E 
 + 
 +; --- 
 + 
 +; Load or Verify from "B" channel. 
 + 
 +<a name="L0A7D"></a>;; <b>LV-B</b> 
 +L0A7D:  CALL    <A href="#L0B88">L0B88</a>           ; routine BCHAN-IN 
 +        JR      NC,<A href="#L0A7D">L0A7D</a>        ; back to LV-B 
 + 
 +; Load or Verify "B","N" end test. 
 + 
 +<a name="L0A82"></a>;; <b>LV-BN-E</b> 
 +L0A82:  POP     DE              ; restore code length. 
 +        DEC     DE              ; and decrement. 
 +        POP     HL              ; restore load address. 
 + 
 +        BIT     7,(IY+$7C)      ; test FLAGS_3 - verify operation. 
 +        JR      NZ,<A href="#L0A8E">L0A8E</a>        ; forward, if so missing load, to VR-BN 
 + 
 +        LD      (HL),         ; load the byte into memory. 
 +        JR      <A href="#L0A93">L0A93</a>           ; forward to LVBN-END 
 + 
 +; --- 
 + 
 +; Verify "B" or "N" bytes. 
 + 
 +<a name="L0A8E"></a>;; <b>VR-BN</b> 
 +L0A8E:  CP      (HL)            ; compare the received byte with the byte in 
 +                                ; memory. 
 +        JR      Z,<A href="#L0A93">L0A93</a>         ; forward, with match, to LVBN-END. 
 + 
 +        RST     20H             ; Shadow Error Restart 
 +        DEFB    $15             ; 'Verification has failed' 
 + 
 +; --- 
 + 
 +; Load or Verify "B","N" end. 
 + 
 +<a name="L0A93"></a>;; <b>LVBN-END</b> 
 +L0A93:  INC     HL              ; increment the address. 
 +        LD      A,E             ; test the byte  
 +        OR      D               ; counter for zero. 
 +        JR      NZ,<A href="#L0A6E">L0A6E</a>        ; back, if not, to LV-BN 
 + 
 +        RET                     ; return. 
 + 
 + 
 +; -------------------------------- 
 +; THE <b><font color=#333388>'LOAD "RUN" PROGRAM'</font></b> ROUTINE 
 +; -------------------------------- 
 +
 + 
 +<a name="L0A99"></a>;; <b>LOAD-RUN</b> 
 +L0A99:  LD      BC,$0001        ; set drive to one. 
 +        LD      ($5CD6),BC      ; update D_STR1 drive number. 
 + 
 +        LD      BC,$0003        ; length of "run" is three. 
 +        LD      ($5CDA),BC      ; update N_STR1 length of filename. 
 + 
 +        LD      BC,<A href="#L0ACA">L0ACA</a>        ; addr: NAME-RUN (below) 
 +        LD      ($5CDC),BC      ; update A_STR1 - address of filename. 
 + 
 +        SET     4,(IY+$7C)      ; update FLAGS_3 signal a LOAD operation. 
 + 
 +        CALL    <A href="#L0753">L0753</a>           ; routine PROG sets up the first seven header  
 +                                ; bytes for a program. 
 + 
 +        LD      HL,$5CE6        ; set start to HD_00 
 +        LD      DE,$5CDE        ; set destination to D_STR2 
 +        LD      BC,$0009        ; nine bytes are copied. 
 +                                ; <font color=#9900FF>Note.</font> should be seven but is mostly harmless. 
 + 
 +        LDIR                    ; block copy. 
 + 
 +        SET     7,(IY+$0A)      ; update Main NSPPC - signal no jump to be made. 
 + 
 +        CALL    <A href="#L1971">L1971</a>           ; routine F-M-HEAD loads the header type  
 +                                ; record for the 'run' file and populates 
 +                                ; the nine locations HD_00 to HD_11. 
 + 
 +        JP      <A href="#L08F6">L08F6</a>           ; jump back to TEST-TYPE to test that type is 
 +                                ; 'program' and load the rest. 
 + 
 +; --- 
 + 
 +<a name="L0ACA"></a>;; <b>NAME-RUN</b> 
 +L0ACA:  DEFM    "run"           ; the filename "run" 
 + 
 +; ******************************************* 
 +; **  T H E   R S 2 3 2   R O U T I N E S  ** 
 +; ******************************************* 
 + 
 +; ---------------------------------------- 
 +; THE <b><font color=#333388>'SET "BAUD" SYSTEM VARIABLE'</font></b> ROUTINE 
 +; ---------------------------------------- 
 +
 + 
 +<a name="L0ACD"></a>;; <b>SET-BAUD</b> 
 +L0ACD:  LD      BC,($5CD6)      ; sv D_STR1 drive number 
 +        LD      HL,<A href="#L0AF3">L0AF3</a>        ; RS-CONSTS 
 + 
 +<a name="L0AD4"></a>;; <b>NXT-ENTRY</b> 
 +L0AD4:  LD      E,(HL) 
 +        INC     HL 
 +        LD      D,(HL) 
 +        INC     HL 
 +        EX      DE,HL 
 +        LD      A,H 
 +        CP      $4B             ; 
 +        JR      NC,<A href="#L0AE8">L0AE8</a>        ; forward to END-SET 
 + 
 +        AND     A 
 +        SBC     HL,BC 
 +        JR      NC,<A href="#L0AE8">L0AE8</a>        ; forward to END-SET 
 + 
 +        EX      DE,HL 
 +        INC     HL 
 +        INC     HL 
 +        JR      <A href="#L0AD4">L0AD4</a>           ; loop back to NXT-ENTRY 
 + 
 +; --- 
 + 
 +<a name="L0AE8"></a>;; <b>END-SET</b> 
 +L0AE8:  EX      DE,HL 
 +        LD      E,(HL) 
 +        INC     HL 
 +        LD      D,(HL) 
 +        LD      ($5CC3),DE      ; sv BAUD 
 +        JP      <A href="#L05C1">L05C1</a>           ; jump to END1 
 + 
 +; ------------------------------------ 
 +; THE <b><font color=#333388>'RS232 TIMING CONSTANTS'</font></b> ROUTINE 
 +; ------------------------------------ 
 +
 + 
 +<a name="L0AF3"></a>;; <b>RS-CONSTS</b> 
 +L0AF3:  DEFW    $0032           ; 
 +        DEFW    $0A82           ; 
 +        DEFW    $006E           ; 
 +        DEFW    $04C5           ; 
 +        DEFW    $012C           ; 
 +        DEFW    $01BE           ; 
 +        DEFW    $0258           ; 
 +        DEFW    $00DE           ; 
 +        DEFW    $04B0           ; 
 +        DEFW    $006E           ; 
 +        DEFW    $0960           ; 
 +        DEFW    $0036           ; 
 +        DEFW    $12C0           ; 
 +        DEFW    $001A           ; 
 +        DEFW    $2580           ; 
 +        DEFW    $000C           ; 
 +        DEFW    $4B00           ; 
 +        DEFW    $0005           ; 
 + 
 + 
 +; ---------------------------------------------- 
 +; THE <b><font color=#333388>'OPEN RS232 CHANNEL IN CHANS AREA'</font></b> ROUTINE 
 +; ---------------------------------------------- 
 +
 + 
 +<a name="L0B17"></a>;; <b>OP-RS-CH</b> 
 +L0B17:  LD      HL,($5C53)      ; use system variable PROG to address the 
 +                                ; location following the Channels area. 
 +        DEC     HL              ; step back to the end-marker. 
 +        LD      BC,$000B        ; eleven bytes of room required. 
 +        PUSH    BC              ; save bytes 
 + 
 +        RST     10H             ; CALBAS 
 +        DEFW    $1655           ; main routine MAKE-ROOM opens up the space. 
 +                                ; register HL points to location before room. 
 + 
 +        POP     BC              ; bring back the eleven bytes. 
 + 
 +        PUSH    DE              ; save DE briefly 
 +        CALL    <A href="#L1A82">L1A82</a>           ; routine REST-N-AD adjusts the dynamic memory 
 +                                ; pointers to filenames in D_STR1 and D_STR2. 
 +        POP     DE              ; restore DE. 
 + 
 +        LD      HL,<A href="#L0B76">L0B76</a> - 1    ; last byte of T-Channel info. 
 +        LD      BC,$000B        ; eleven bytes to copy. 
 +        LDDR                    ; block copy downwards. 
 + 
 +        INC     DE              ; 
 +        LD      A,($5CD9)       ; sv L_STR1 device letter. 
 +        CP      $42             ; is it "B"
 +        RET     NZ              ; return as must be "T"
 + 
 +; but if this is to be a binary channel then overwrite the letter and the output 
 +; and input routines. 
 + 
 +        PUSH    DE              ; 
 + 
 +        LD      HL,$0004        ; 
 +        ADD     HL,DE           ; 
 + 
 +        LD      (HL),$42        ; 'B' 
 +        INC     HL              ; 
 + 
 +        LD      DE,<A href="#L0D07">L0D07</a>        ; address B-CHAN-OUT 
 +        LD      (HL),         ; 
 +        INC     HL              ; 
 +        LD      (HL),         ; 
 +        INC     HL              ; 
 + 
 +        LD      DE,<A href="#L0B7C">L0B7C</a>        ; address B-INPUT 
 +        LD      (HL),         ; 
 +        INC     HL              ; 
 +        LD      (HL),         ; 
 + 
 +        POP     DE              ; 
 +        RET                     ; return. 
 + 
 + 
 +; ---------------------------------------- 
 +; THE <b><font color=#333388>'ATTACH CHANNEL TO A STREAM'</font></b> ROUTINE 
 +; ---------------------------------------- 
 +
 + 
 +<a name="L0B4E"></a>;; <b>OP-RSCHAN</b> 
 +L0B4E:  CALL    <A href="#L0B17">L0B17</a>           ; routine OP-RS-CH 
 + 
 +<a name="L0B51"></a>;; <b>OP-STREAM</b> 
 +L0B51:  LD      HL,($5C4F)      ; sv CHANS 
 +        DEC     HL 
 +        EX      DE,HL 
 +        AND     A 
 +        SBC     HL,DE 
 +        EX      DE,HL 
 +        LD      HL,$5C16        ; sv STRMS_00 
 +        LD      A,($5CD8)       ; sv D_STR1 
 +        RLCA 
 +        LD      C,A 
 +        LD      B,$00 
 +        ADD     HL,BC 
 +        LD      (HL),E 
 +        INC     HL 
 +        LD      (HL),D 
 +        JP      <A href="#L05C1">L05C1</a>           ; jump to END1 
 + 
 +; ---------------------- 
 +; THE <b><font color=#333388>'"T" CHANNEL DATA'</font></b> 
 +; ---------------------- 
 +; the eleven-byte "T" CHANNEL descriptor. 
 + 
 +<a name="L0B6B"></a>;; <b>TCHAN-DAT</b> 
 +L0B6B:  DEFW    $0008           ; main ERROR-1 
 +        DEFW    $0008           ; main ERROR-1 
 +        DEFB    $54             ; character "T" 
 +        DEFW    <A href="#L0C3A">L0C3A</a>           ; TCHAN-OUT 
 +        DEFW    <A href="#L0B76">L0B76</a>           ; T-INPUT 
 +        DEFW    $000B           ; channel length - 11 bytes. 
 + 
 +; ------------------------------- 
 +; THE <b><font color=#333388>'"T" CHANNEL INPUT'</font></b> ROUTINE 
 +; ------------------------------- 
 +
 + 
 +<a name="L0B76"></a>;; <b>T-INPUT</b> 
 +L0B76:  LD      HL,<A href="#L0B82">L0B82</a>        ; address of routine TCHAN-IN 
 +        JP      <A href="#L0D5A">L0D5A</a>           ; jump to CALL-INP 
 + 
 +; ------------------------------- 
 +; THE <b><font color=#333388>'"B" CHANNEL INPUT'</font></b> ROUTINE 
 +; ------------------------------- 
 +
 + 
 +<a name="L0B7C"></a>;; <b>B-INPUT</b> 
 +L0B7C:  LD      HL,<A href="#L0B88">L0B88</a>        ; address of routine BCHAN-IN 
 +        JP      <A href="#L0D5A">L0D5A</a>           ; jump to CALL-INP 
 + 
 +; --------------------------------------- 
 +; THE <b><font color=#333388>'"T" CHANNEL INPUT SERVICE'</font></b> ROUTINE 
 +; --------------------------------------- 
 +
 + 
 +<a name="L0B82"></a>;; <b>TCHAN-IN</b> 
 +L0B82:  CALL    <A href="#L0B88">L0B88</a>           ; routine BCHAN-IN 
 +        RES     7,A 
 +        RET 
 + 
 + 
 +; --------------------------------------- 
 +; THE <b><font color=#333388>'"B" CHANNEL INPUT SERVICE'</font></b> ROUTINE 
 +; --------------------------------------- 
 +; <font color=#339933>(Hook Code: $1D)</font> 
 + 
 +<a name="L0B88"></a>;; <b>BCHAN-IN</b> 
 +L0B88:  LD      HL,$5CC7        ; sv SER_FL 
 +        LD      A,(HL)          ; 
 +        AND                   ; 
 +        JR      Z,<A href="#L0B95">L0B95</a>         ; forward to REC-BYTE 
 + 
 +        LD      (HL),$00        ; 
 +        INC     HL              ; 
 +        LD      A,(HL)          ; 
 +        SCF                     ; 
 + 
 +        RET                     ; Return. 
 + 
 +; --- 
 + 
 +<a name="L0B95"></a>;; <b>REC-BYTE</b> 
 +L0B95:  CALL    <A href="#L163E">L163E</a>           ; routine TEST-BRK 
 + 
 +        DI                      ; Disable Interrupts 
 + 
 +        LD      A,($5CC6)       ; sv IOBORD 
 +        OUT     ($FE),
 + 
 +        LD      DE,($5CC3)      ; sv BAUD 
 +        LD      HL,$0320        ; 800d. 
 +        LD      B,D             ; 
 +        LD      C,E             ; 
 +        SRL                   ; 
 +        RR      C               ; 
 +        LD      A,$FE           ; 
 +        OUT     ($EF),        ; 
 + 
 +<a name="L0BAF"></a>;; <b>READ-RS</b> 
 +L0BAF:  IN      A,($F7)         ; bit 7 is input serial data (txdata) 
 +        RLCA                    ; 
 +        JR      NC,<A href="#L0BC3">L0BC3</a>        ; forward to TST-AGAIN 
 + 
 +        IN      A,($F7)         ; 
 +        RLCA                    ; 
 +        JR      NC,<A href="#L0BC3">L0BC3</a>        ; forward to TST-AGAIN 
 + 
 +        IN      A,($F7)         ; 
 +        RLCA                    ; 
 +        JR      NC,<A href="#L0BC3">L0BC3</a>        ; forward to TST-AGAIN 
 + 
 +        IN      A,($F7)         ; 
 +        RLCA                    ; 
 +        JR      C,<A href="#L0BCF">L0BCF</a>         ; forward to START-BIT 
 + 
 + 
 +<a name="L0BC3"></a>;; <b>TST-AGAIN</b> 
 +L0BC3:  DEC     HL              ; 
 +        LD      A,H             ; 
 +        OR      L               ; 
 +        JR      NZ,<A href="#L0BAF">L0BAF</a>        ; back to READ-RS 
 + 
 +        PUSH    AF              ; 
 +        LD      A,$EE           ; 
 +        OUT     ($EF),        ; 
 +        JR      <A href="#L0BEE">L0BEE</a>           ; forward to WAIT-1 
 + 
 +; --- 
 + 
 +<a name="L0BCF"></a>;; <b>START-BIT</b> 
 +L0BCF:  LD      H,B             ; Load HL with halved BAUD value. 
 +        LD      L,C             ; 
 + 
 +        LD      B,$80           ; Load B with the start bit. 
 + 
 +        DEC     HL              ; Reduce the counter by the time for the four 
 +        DEC     HL              ; tests. 
 +        DEC     HL              ; 
 + 
 +<a name="L0BD6"></a>;; <b>SERIAL-IN</b> 
 +L0BD6:  ADD     HL,DE           ; Add the BAUD value. 
 +        NOP                     ; (4) a timing value. 
 + 
 +<a name="L0BD8"></a>;; <b>BD-DELAY</b> 
 +L0BD8:  DEC     HL              ; (6) Delay for 26 * BAUD 
 +        LD      A,H             ; (4) 
 +        OR      L               ; (4) 
 +        JR      NZ,<A href="#L0BD8">L0BD8</a>        ; (12) back to BD-DELAY 
 + 
 +        ADD     A,$00           ; (7) wait 
 +        IN      A,($F7)         ; Read a bit. 
 +        RLCA                    ; Rotate bit 7 to carry. 
 +        RR      B               ; pick up carry in B 
 +        JR      NC,<A href="#L0BD6">L0BD6</a>        ; back , if no start bit, to SERIAL-IN 
 + 
 +        LD      A,$EE           ; Send CTS line low  (comms data 0 also) 
 +        OUT     ($EF),        ; send to serial port 
 + 
 +        LD      A,B             ; Transfer the received byte to A. 
 +        CPL                     ; Complement. 
 +        SCF                     ; Set Carry to signal success. 
 +        PUSH    AF              ; (*) push the success flag. 
 + 
 +;   The success and failure (time out) paths converge here with the HL register 
 +;   holding zero. 
 + 
 +<a name="L0BEE"></a>;; <b>WAIT-1</b> 
 +L0BEE:  ADD     HL,DE           ; (11) transfer DE (BAUD) to HL. 
 + 
 +<a name="L0BEF"></a>;; <b>WAIT-2</b> 
 +L0BEF:  DEC     HL              ; ( 6) delay for stop bit. 
 +        LD      A,L             ; ( 4) 
 +        OR      H               ; ( 4) 
 +        JR      NZ,<A href="#L0BEF">L0BEF</a>        ; (12/7) back to WAIT-2 
 + 
 +;   Register HL is now zero again. 
 + 
 +        ADD     HL,DE           ; HL = 0 + BAUD 
 +        ADD     HL,DE           ; HL = 2 * BAUD 
 +        ADD     HL,DE           ; HL = 3 * BAUD 
 + 
 +;   The device at the other end of the cable (not a Spectrum) may send a  
 +;   second byte even though CTS (Clear To Send) is low. 
 + 
 +<a name="L0BF7"></a>;; <b>T-FURTHER</b> 
 +L0BF7:  DEC     HL              ; Decrement counter. 
 +        LD      A,L             ; Test for 
 +        OR      H               ; zero. 
 +        JR      Z,<A href="#L0C34">L0C34</a>         ; forward, if no second byte, to END-RS-IN 
 + 
 +        IN      A,($F7)         ; Read TXdata. 
 +        RLCA                    ; test the bit read. 
 +        JR      NC,<A href="#L0BF7">L0BF7</a>        ; back, if none,  to T-FURTHER 
 + 
 +;   As with first byte, TXdata must be high four four tests. 
 + 
 +        IN      A,($F7)         ; 
 +        RLCA                    ; 
 +        JR      NC,<A href="#L0BF7">L0BF7</a>        ; back to T-FURTHER 
 + 
 +        IN      A,($F7)         ; 
 +        RLCA                    ; 
 +        JR      NC,<A href="#L0BF7">L0BF7</a>        ; back to T-FURTHER 
 + 
 +        IN      A,($F7)         ; 
 +        RLCA                    ; 
 +        JR      NC,<A href="#L0BF7">L0BF7</a>        ; back to T-FURTHER 
 + 
 + 
 +;   A second byte is on its way and is received exactly as before. 
 + 
 +        LD      H,D             ; 
 +        LD      L,E             ; 
 +        SRL                   ; 
 +        RR      L               ; 
 +        LD      B,$80           ; 
 +        DEC     HL              ; 
 +        DEC     HL              ; 
 +        DEC     HL              ; 
 + 
 +<a name="L0C1B"></a>;; <b>SER-IN-2</b> 
 +L0C1B:  ADD     HL,DE           ; 
 +        NOP                     ; timing. 
 + 
 +<a name="L0C1D"></a>;; <b>BD-DELAY2</b> 
 +L0C1D:  DEC     HL              ; 
 +        LD      A,H             ; 
 +        OR      L               ; 
 +        JR      NZ,<A href="#L0C1D">L0C1D</a>        ; back to BD-DELAY2 
 + 
 +        ADD     A,$00           ; 
 +        IN      A,($F7)         ; 
 +        RLCA                    ; 
 +        RR      B               ; 
 +        JR      NC,<A href="#L0C1B">L0C1B</a>        ; back to SER-IN-2 
 + 
 +;  The start bit has been pushed out and B contains the second received byte. 
 + 
 +        LD      HL,$5CC7        ; Address the SER_FL System Variable. 
 + 
 +        LD      (HL),$01        ; Signal there is a byte in the next location. 
 +        INC     HL              ; Address that location. 
 +        LD      A,B             ; Transfer the byte to A. 
 +        CPL                     ; Complement 
 +        LD      (HL),         ; and insert in the second byte of serial flag. 
 + 
 +<a name="L0C34"></a>;; <b>END-RS-IN</b> 
 +L0C34:  CALL    <A href="#L0D4D">L0D4D</a>           ; routine BORD-REST 
 + 
 +        POP     AF              ; ( either 0 and NC or the first received byte 
 +                                ;   and the carry flag set )  
 + 
 +        EI                      ; Enable Interrupts 
 + 
 +        RET                     ; Return. 
 + 
 +; -------------------------------- 
 +; THE <b><font color=#333388>'"T" CHANNEL OUTPUT'</font></b> ROUTINE 
 +; -------------------------------- 
 +;   The text channel output routine is able to list programs and, when  
 +;   printing, takes correct action with TAB values etc. 
 + 
 +<a name="L0C3A"></a>;; <b>TCHAN-OUT</b> 
 +L0C3A:  CP      $A5             ; 'RND' - first token 
 +        JR      C,<A href="#L0C44">L0C44</a>         ; forward, if less, to NOT-TOKEN 
 + 
 +        SUB     $A5             ; reduce to range $00-5A 
 +        RST     10H             ; CALBAS 
 +        DEFW    $0C10           ; main PO-TOKENS 
 +        RET                     ; return. 
 + 
 +; --- 
 + 
 +<a name="L0C44"></a>;; <b>NOT-TOKEN</b> 
 +L0C44:  LD      HL,$5C3B        ; Address the FLAGS System Variable. 
 +        RES     0,(HL)          ; update FLAGS - allow for leading space. 
 +        CP      $20             ; compare to space 
 +        JR      NZ,<A href="#L0C4F">L0C4F</a>        ; forward, if not, to NOT-LEAD 
 + 
 +        SET     0,(HL)          ; update FLAGS - signal suppress leading space. 
 + 
 +<a name="L0C4F"></a>;; <b>NOT-LEAD</b> 
 +L0C4F:  CP      $7F             ; compare to copyright symbol. (DEL in ASCII) 
 +        JR      C,<A href="#L0C55">L0C55</a>         ; forward, if less, to NOT-GRAPH 
 + 
 +        LD      A,$3F           ; output CHR$(127) and graphics as '?' 
 + 
 +<a name="L0C55"></a>;; <b>NOT-GRAPH</b> 
 +L0C55:  CP      $20             ; compare against space. 
 +        JR      C,<A href="#L0C70">L0C70</a>         ; forward to CTRL-CD 
 + 
 +        PUSH    AF              ; Preserve character. 
 + 
 +        INC     (IY+$76)        ; Increment width         NMI_ADD_lo 
 +        LD      A,($5CB1)       ; Load A with limit from  NMI_ADD_hi 
 +        CP      (IY+$76)        ; Compare to width        NMI_ADD_lo 
 + 
 +        JR      NC,<A href="#L0C6C">L0C6C</a>        ; forward, if less or equal, to EMIT-CH 
 + 
 +        CALL    <A href="#L0C74">L0C74</a>           ; routine TAB-SETZ emits CR/LF. 
 + 
 +        LD      (IY+$76),$01    ; Set width to one        NMI_ADD_lo 
 + 
 +<a name="L0C6C"></a>;; <b>EMIT-CH</b> 
 +L0C6C:  POP     AF              ; Restore the unprinted character. 
 + 
 +        JP      <A href="#L0D07">L0D07</a>           ; jump to BCHAN-OUT 
 + 
 +; --- 
 + 
 +<a name="L0C70"></a>;; <b>CTRL-CD</b> 
 +L0C70:  CP      $0D             ; carriage return ? 
 +        JR      NZ,<A href="#L0C82">L0C82</a>        ; forward to NOT-CR 
 + 
 + 
 +<a name="L0C74"></a>;; <b>TAB-SETZ</b> 
 +L0C74:  LD      (IY+$76),$00    ; sv NMI_ADD_lo 
 +        LD      A,$0D           ; output a CR carriage return. 
 +        CALL    <A href="#L0D07">L0D07</a>           ; routine BCHAN-OUT 
 +        LD      A,$0A           ; output a LF line feed. 
 +        JP      <A href="#L0D07">L0D07</a>           ; jump to BCHAN-OUT 
 + 
 +; --- 
 + 
 +<a name="L0C82"></a>;; <b>NOT-CR</b> 
 +L0C82:  CP      $06             ; 
 +        JR      NZ,<A href="#L0CA5">L0CA5</a>        ; forward to NOT-CMM 
 + 
 +        LD      BC,($5CB0)      ; sv NMI_ADD 
 +        LD      E,$00           ; 
 + 
 +<a name="L0C8C"></a>;; <b>SPC-COUNT</b> 
 +L0C8C:  INC     E 
 +        INC     C 
 +        LD      A,C 
 +        CP      B 
 +        JR      Z,<A href="#L0C9A">L0C9A</a>         ; forward to CMM-LP2 
 + 
 + 
 +<a name="L0C92"></a>;; <b>CMM-LOOP</b> 
 +L0C92:  SUB     $08 
 +        JR      Z,<A href="#L0C9A">L0C9A</a>         ; forward to CMM-LP2 
 + 
 +        JR      NC,<A href="#L0C92">L0C92</a>        ; back to CMM-LOOP 
 + 
 +        JR      <A href="#L0C8C">L0C8C</a>           ; back to SPC-COUNT 
 + 
 + 
 +<a name="L0C9A"></a>;; <b>CMM-LP2</b> 
 +L0C9A:  PUSH    DE 
 +        LD      A,$20 
 +        CALL    <A href="#L0C3A">L0C3A</a>           ; routine TCHAN-OUT 
 +        POP     DE 
 +        DEC     E 
 +        RET     Z 
 + 
 +        JR      <A href="#L0C9A">L0C9A</a>           ; back to CMM-LP2 
 + 
 +; --- 
 + 
 +<a name="L0CA5"></a>;; <b>NOT-CMM</b> 
 +L0CA5:  CP      $16 
 +        JR      Z,<A href="#L0CB5">L0CB5</a>         ; forward to TAB-PROC 
 + 
 +        CP      $17 
 +        JR      Z,<A href="#L0CB5">L0CB5</a>         ; forward to TAB-PROC 
 + 
 +        CP      $10 
 +        RET     C 
 + 
 +        LD      DE,$0CD0 
 +        JR      <A href="#L0CB8">L0CB8</a>           ; forward to STORE-COD 
 + 
 +; --- 
 + 
 +<a name="L0CB5"></a>;; <b>TAB-PROC</b> 
 +L0CB5:  LD      DE,<A href="#L0CC8">L0CC8</a>        ; addr: TAB-SERV 
 + 
 +<a name="L0CB8"></a>;; <b>STORE-COD</b> 
 +L0CB8:  LD      ($5C0E),      ; sv TVDATA 
 + 
 +<a name="L0CBB"></a>;; <b>ALTER-OUT</b> 
 +L0CBB:  LD      HL,($5C51)      ; sv CURCHL 
 +        PUSH    DE 
 +        LD      DE,$0005 
 +        ADD     HL,DE 
 +        POP     DE 
 +        LD      (HL),E 
 +        INC     HL 
 +        LD      (HL),D 
 +        RET 
 + 
 +; --- 
 + 
 +<a name="L0CC8"></a>;; <b>TAB-SERV</b> 
 +L0CC8:  LD      DE,<A href="#L0CD0">L0CD0</a>        ; addr: TAB-SERV2 
 +        LD      ($5C0F),      ; sv TVDATA 
 +        JR      <A href="#L0CBB">L0CBB</a>           ; back to ALTER-OUT 
 + 
 +; --- 
 + 
 +<a name="L0CD0"></a>;; <b>TAB-SERV2</b> 
 +L0CD0:  LD      DE,<A href="#L0C3A">L0C3A</a>        ; addr: TCHAN-OUT 
 +        CALL    <A href="#L0CBB">L0CBB</a>           ; routine ALTER-OUT 
 +        LD      D,A 
 +        LD      A,($5C0E)       ; sv TVDATA 
 +        CP      $16             ; AT control code ? 
 +        JR      Z,<A href="#L0CE6">L0CE6</a>         ; forward to TST-WIDTH 
 + 
 +        CP      $17             ; TAB control code ? 
 +        CCF 
 +        RET     NZ 
 + 
 +        LD      A,($5C0F)       ; sv TVDATA 
 +        LD      D,A 
 + 
 +<a name="L0CE6"></a>;; <b>TST-WIDTH</b> 
 +L0CE6:  LD      A,($5CB1)       ; sv NMI_ADD 
 +        CP      D 
 +        JR      Z,<A href="#L0CEE">L0CEE</a>         ; forward to TAB-MOD 
 + 
 +        JR      NC,<A href="#L0CF4">L0CF4</a>        ; forward to TABZERO 
 + 
 + 
 +<a name="L0CEE"></a>;; <b>TAB-MOD</b> 
 +L0CEE:  LD      B,A 
 +        LD      A,D 
 +        SUB     B 
 +        LD      D,A 
 +        JR      <A href="#L0CE6">L0CE6</a>           ; back to TST-WIDTH 
 + 
 +; --- 
 + 
 +<a name="L0CF4"></a>;; <b>TABZERO</b> 
 +L0CF4:  LD      A,D 
 +        OR      A 
 +        JP      Z,<A href="#L0C74">L0C74</a>         ; jump to TAB-SETZ 
 + 
 +<a name="L0CF9"></a>;; <b>TABLOOP</b> 
 +L0CF9:  LD      A,($5CB0)       ; sv NMI_ADD_lo 
 +        CP      D               ; 
 +        RET                   ; 
 + 
 +        PUSH    DE              ; 
 +        LD      A,$20           ; 
 +        CALL    <A href="#L0C3A">L0C3A</a>           ; routine TCHAN-OUT 
 +        POP     DE              ; 
 +        JR      <A href="#L0CF9">L0CF9</a>           ; back to TABLOOP 
 + 
 + 
 +; -------------------------------- 
 +; THE <b><font color=#333388>'"B" CHANNEL OUTPUT'</font></b> ROUTINE 
 +; -------------------------------- 
 +; <font color=#339933>(Hook Code: $1E)</font> 
 +;   The bits of a byte are sent inverted. They are fixed in length and heralded 
 +;   by a start bit and followed by two stop bits. 
 + 
 +<a name="L0D07"></a>;; <b>BCHAN-OUT</b> 
 +L0D07:  LD      B,$0B           ; Set bit count to eleven - 1 + 8 + 2. 
 + 
 +        CPL                     ; Invert the bits of the character. 
 +        LD      C,A             ; Copy the character to C. 
 + 
 +        LD      A,($5CC6)       ; Load A from System Variable IOBORD 
 +        OUT     ($FE),        ; Change the border colour. 
 + 
 +        LD      A,$EF           ; Set to %11101111 
 +        OUT     ($EF),        ; Make CTS (Clear to Send) low. 
 + 
 +        CPL                     ; reset bit 0 (other bits of no importance) 
 +        OUT     ($F7),        ; Make RXdata low. %00010000 
 + 
 +        LD      HL,($5CC3)      ; Fetch value from BAUD System Variable. 
 +        LD      D,H             ; Copy BAUD value to DE for count. 
 +        LD      E,L             ; 
 + 
 +<a name="L0D1C"></a>;; <b>BD-DEL-1</b> 
 +L0D1C:  DEC     DE              ; ( 6) Wait 26 * BAUD cycles 
 +        LD      A,D             ; ( 4)  
 +        OR      E               ; ( 4) 
 +        JR      NZ,<A href="#L0D1C">L0D1C</a>        ; (12) back to BD-DEL-1 
 + 
 +<a name="L0D21"></a>;; <b>TEST-DTR</b> 
 +L0D21:  CALL    <A href="#L163E">L163E</a>           ; routine TEST-BRK allows user to stop. 
 +        IN      A,($EF)         ; Read the communication port. 
 +        AND     $08             ; isolate DTR (Data Terminal Ready) bit. 
 +        JR      Z,<A href="#L0D21">L0D21</a>         ; back, until DTR found high, to TEST-DTR 
 + 
 +        SCF                     ; Set carry flag as the start bit. 
 +        DI                      ; Disable Interrupts. 
 + 
 +<a name="L0D2C"></a>;; <b>SER-OUT-L</b> 
 +L0D2C:  ADC     A,$00           ; Set bit 0            76543210 &lt;- C   
 +        OUT     ($F7),        ; Send RXdata the start bit. 
 + 
 +        LD      D,H             ; Transfer the BAUD value to DE for count. 
 +        LD      E,L             ; 
 + 
 +<a name="L0D32"></a>;; <b>BD-DEL-2</b> 
 +L0D32:  DEC     DE              ; ( 6) Wait for 26 * BAUD 
 +        LD      A,D             ; ( 4) 
 +        OR      E               ; ( 4) 
 +        JR      NZ,<A href="#L0D32">L0D32</a>        ; (12) back to BD-DEL-2 
 + 
 +        DEC     DE              ; ( 6)  
 +        XOR                   ; ( 4) clear rxdata bit 
 +        SRL                   ;      shift a bit of output byte to carry. 
 +        DJNZ    <A href="#L0D2C">L0D2C</a>           ; back for 11 bits to SER-OUT-L 
 + 
 +;   Note the last two bits will have been sent reset as C is exhausted. 
 + 
 +        EI                      ; Enable Interrupts. 
 + 
 +        LD      A,$01           ; Set RXdata 
 + 
 +        LD      C,$EF           ; prepare port address. 
 +        LD      B,$EE           ; prepare value %11101110 
 +        OUT     ($F7),        ; Send RXdata high. 
 +        OUT     (C),          ; Send CTS and comms data low - switch off RS232 
 + 
 +<a name="L0D48"></a>;; <b>BD-DEL-3</b> 
 +L0D48:  DEC     HL              ; ( 6) The final 26 * BAUD delay 
 +        LD      A,L             ; ( 4)  
 +        OR      H               ; ( 4)  
 +        JR      NZ,<A href="#L0D48">L0D48</a>        ; (12) back to BD-DEL-3 
 + 
 + 
 +; ----------------------------------- 
 +; THE <b><font color=#333388>'BORDER COLOUR RESTORE'</font></b> ROUTINE 
 +; ----------------------------------- 
 +
 + 
 +<a name="L0D4D"></a>;; <b>BORD-REST</b> 
 +L0D4D:  PUSH    AF              ; Preserve the accumulator value throughout. 
 + 
 +        LD      A,($5C48)       ; Fetch System Variable BORDCR 
 +        AND     $38             ; Mask off the paper bits. 
 +        RRCA                    ; Rotate to the range 0 - 7 
 +        RRCA                    ; 
 +        RRCA                    ; 
 +        OUT     ($FE),        ; Change the border colour. 
 + 
 +        POP     AF              ; Restore accumulator and flags. 
 + 
 +        RET                     ; Return. 
 + 
 + 
 +; ---------------------- 
 +; THE <b><font color=#333388>'CALL-INP'</font></b> ROUTINE 
 +; ---------------------- 
 +;   If the extended streams e.g. #7 are being used for input then this ROM 
 +;   will be paged in as a result of the $0008 address in the normal INPUT 
 +;   channel position. Since 'INPUT #7' or 'INKEYS #7' could have been used  
 +;   it is the purpose of this routine to determine which has been used. 
 +;   Note also that 'MOVE #7 TO #2' could also invoke this routine and that MOVE 
 +;   operations are further differentiated in the INKEY$ branch. 
 + 
 +<a name="L0D5A"></a>;; <b>CALL-INP</b> 
 +L0D5A:  RES     3,(IY+$02)      ; update TV_FLAG - The mode is to be considered  
 +                                ; unchanged. 
 +                                ; <font color=#9900FF>Note.</font> this should have been done by the Main 
 +                                ; ROM before entering the EDITOR. 
 + 
 +        PUSH    HL              ; (*) Preserve HL the address of the actual  
 +                                ; service routine - either NCHAN_IN, MCHAN_IN, 
 +                                ; BCHAN_IN ot T_CHAN_IN. 
 + 
 +        LD      HL,($5C3D)      ; Fetch address of Error Stack Pointer ERR_SP 
 + 
 +        LD      E,(HL)          ; Extract the address of the error handler 
 +        INC     HL              ; If INPUT is being used this will be 
 +        LD      D,(HL)          ; address $107F in the Main ROM. 
 + 
 +        AND                   ; Prepare to subtract. 
 + 
 +        LD      HL,$107F        ; address of ED-ERROR in the Main ROM 
 + 
 +        SBC     HL,DE           ; subtract from test value. 
 + 
 +        JR      NZ,<A href="#L0D98">L0D98</a>        ; forward if not in EDITOR to INKEY$ 
 + 
 +;   continue to handle INPUT from a stream. 
 + 
 +        POP     HL              ; (*) POP service routine to HL e.g. NCHAN_IN 
 + 
 +        LD      SP,($5C3D)      ; set Stack Pointer from System Variable ERR_SP 
 +        POP     DE              ; discard the known ED-ERROR address $107F. 
 +        POP     DE              ; POP the next value in hierarchy - MAIN-4 
 +                                ; (usually). 
 +        LD      ($5C3D),DE      ; and set the system variable ERR_SP 
 + 
 +<a name="L0D78"></a>;; <b>IN-AGAIN.</b> 
 +L0D78:  PUSH    HL              ; Push the address of the service routine 
 +                                ; e.g. NCHAN_IN on the machine stack. 
 + 
 +        LD      DE,<A href="#L0D7E">L0D7E</a>        ; addr: IN-AG-RET (below) 
 +        PUSH    DE              ; push this address  
 + 
 +        JP      (HL)            ; jump to the service routine either MCHAN_IN, 
 +                                ; NCHAN_IN, BCHAN_IN or TCHAN_IN and then return 
 +                                ; to the next address IN-AG-RET. 
 + 
 +; --- 
 + 
 +<a name="L0D7E"></a>;; <b>IN-AG-RET</b> 
 +L0D7E   JR      C,<A href="#L0D8A">L0D8A</a>         ; forward with acceptable codes to ACC-CODE 
 + 
 +        JR      Z,<A href="#L0D87">L0D87</a>         ; forward with time-out to NO-READ 
 + 
 +;   Otherwise Iris has closed her channel or the microdrive file was exhausted. 
 + 
 +<a name="L0D82"></a>;; <b>OREPORT-8</b> 
 +L0D82:  LD      (IY+$00),$07    ; set ERR_NR to  '8 End of file' 
 +        RST     28H             ; Error Main ROM. 
 + 
 +; --- 
 + 
 +<a name="L0D87"></a>;; <b>NO-READ</b> 
 +L0D87:  POP     HL              ; Retrieve the address of teh service routine 
 +                                ; and try again as always for INPUT. 
 +        JR      <A href="#L0D78">L0D78</a>           ; back to IN-AGAIN. 
 + 
 +; --- 
 + 
 +<a name="L0D8A"></a>;; <b>ACC-CODE</b> 
 +L0D8A:  CP      $0D             ; Is the acceptable code ENTER? 
 +        JR      Z,<A href="#L0D94">L0D94</a>         ; forward, if so, to END-INPUT 
 + 
 +        RST     10H             ; CALBAS - Call the Base ROM. 
 +        DEFW    $0F85           ; main ADD-CHRX  
 +                                ; A special entry point within ADD-CHAR to add 
 +                                ; the character to WORKSPACE. 
 + 
 +        POP     HL              ; Retrieve the address of the saved service  
 +                                ; routine. 
 +        JR      <A href="#L0D78">L0D78</a>           ; back for another character to IN-AGAIN. 
 + 
 +; --- 
 + 
 +<a name="L0D94"></a>;; <b>END-INPUT</b> 
 +L0D94:  POP     HL              ; Discard the service routine. 
 +        JP      <A href="#L0700">L0700</a>           ; jump to UNPAGE 
 + 
 +; ------------------- 
 +; THE <b><font color=#333388>'INKEY$'</font></b> BRANCH 
 +; ------------------- 
 + 
 +<a name="L0D98"></a>;; <b>INKEY$</b> 
 +L0D98:  POP     HL              ; (*) POP service routine to HL e.g. NCHAN_IN 
 +        LD      DE,<A href="#L0D9E">L0D9E</a>        ; ret addr. INK-RET (below) 
 +        PUSH    DE              ; push this address for the return address. 
 + 
 +        JP      (HL)            ; jump to the service routine either MCHAN_IN, 
 +                                ; NCHAN_IN, BCHAN_IN or TCHAN_IN and then return 
 +                                ; to the next address IN-AG-RET. 
 + 
 +; --- 
 + 
 +<a name="L0D9E"></a>;; <b>INK-RET</b> 
 +L0D9E   RET                   ; Return with acceptable character. 
 + 
 +        RET                   ; Return with no character. 
 + 
 +        BIT     4,(IY+$7C)      ; sv FLAGS_3               MOVE? 
 +        JR      Z,<A href="#L0D82">L0D82</a>         ; back to OREPORT-8 
 + 
 +        OR      $01             ; 
 +        RET                     ; return with zero and carry reset. 
 + 
 + 
 +; *********************************************** 
 +; **  T H E   N E T W O R K   R O U T I N E S  ** 
 +; *********************************************** 
 + 
 +; ------------------------------- 
 +; THE <b><font color=#333388>'"N" CHANNEL INPUT'</font></b> ROUTINE 
 +; ------------------------------- 
 +
 + 
 +<a name="L0DA9"></a>;; <b>N-INPUT</b> 
 +L0DA9:  LD      HL,<A href="#L0DAF">L0DAF</a>        ; Address: NCHAN-IN 
 +        JP      <A href="#L0D5A">L0D5A</a>           ; jump to CALL-INP 
 + 
 +; --------------------------------------- 
 +; THE <b><font color=#333388>'"N" CHANNEL INPUT SERVICE'</font></b> ROUTINE 
 +; --------------------------------------- 
 +
 + 
 +<a name="L0DAF"></a>;; <b>NCHAN-IN</b> 
 +L0DAF:  LD      IX,($5C51)      ; sv CURCHL 
 +        LD      A,(IX+$10)      ; NCOBL 
 +        AND     A 
 +        JR      Z,<A href="#L0DBB">L0DBB</a>         ; forward to TEST-BUFF 
 + 
 +        RST     20H             ; Shadow Error Restart 
 +        DEFB    $0D             ; Reading a 'write' file 
 + 
 +; --- 
 + 
 +<a name="L0DBB"></a>;; <b>TEST-BUFF</b> 
 +L0DBB:  LD      A,(IX+$14)      ; NCIBL 
 +        AND     A 
 +        JR      Z,<A href="#L0DD5">L0DD5</a>         ; forward to TST-N-EOF 
 + 
 +        LD      E,(IX+$13)      ; NCCUR 
 +        DEC     A 
 +        SUB     E 
 +        JR      C,<A href="#L0DD5">L0DD5</a>         ; forward to TST-N-EOF 
 + 
 +        LD      D,$00 
 +        INC     E 
 +        LD      (IX+$13),     ; NCCUR 
 +        ADD     IX,DE 
 +        LD      A,(IX+$14)      ; 
 +        SCF 
 +        RET 
 + 
 +; --- 
 + 
 +<a name="L0DD5"></a>;; <b>TST-N-EOF</b> 
 +L0DD5:  LD      A,(IX+$0F)      ; NCTYPE 
 +        AND     A 
 +        JR      Z,<A href="#L0DDC">L0DDC</a>         ; forward to GET-N-BUF 
 + 
 +        RET 
 + 
 +; --- 
 + 
 +<a name="L0DDC"></a>;; <b>GET-N-BUF</b> 
 +L0DDC:  LD      A,($5CC6)       ; sv IOBORD 
 +        OUT     ($FE),
 +        DI 
 + 
 +<a name="L0DE2"></a>;; <b>TRY-AGAIN</b> 
 +L0DE2:  CALL    <A href="#L0FD3">L0FD3</a>           ; routine WT-SC-E 
 +        JR      NC,<A href="#L0DFC">L0DFC</a>        ; forward to TIME-OUT 
 + 
 +        CALL    <A href="#L0EB5">L0EB5</a>           ; routine GET-NBLK 
 +        JR      NZ,<A href="#L0DFC">L0DFC</a>        ; forward to TIME-OUT 
 + 
 +        EI 
 + 
 +        CALL    <A href="#L0D4D">L0D4D</a>           ; routine BORD-REST 
 + 
 +        LD      (IX+$13),$00    ; NCCUR 
 +        LD      A,($5CD2)       ; sv NTTYPE 
 +        LD      (IX+$0F),     ; NCTYPE 
 +        JR      <A href="#L0DBB">L0DBB</a>           ; back to TEST-BUFF 
 + 
 +; --- 
 + 
 +<a name="L0DFC"></a>;; <b>TIME-OUT</b> 
 +L0DFC:  LD      A,(IX+$0B)      ; NCIRIS 
 +        AND                   ; 
 +        JR      Z,<A href="#L0DE2">L0DE2</a>         ; back to TRY-AGAIN 
 + 
 +        EI                      ; 
 +        CALL    <A href="#L0D4D">L0D4D</a>           ; routine BORD-REST 
 +        AND     $00             ; 
 +        RET                     ; 
 + 
 + 
 +; -------------------------------- 
 +; THE <b><font color=#333388>'"N" CHANNEL OUTPUT'</font></b> ROUTINE 
 +; -------------------------------- 
 +
 + 
 +<a name="L0E09"></a>;; <b>NCHAN-OUT</b> 
 +L0E09:  LD      IX,($5C51)      ; sv CURCHL 
 +        LD      B,A 
 +        LD      A,(IX+$14)      ; NCIBL 
 +        AND     A 
 +        LD      A,B 
 +        JR      Z,<A href="#L0E17">L0E17</a>         ; forward to TEST-OUT 
 + 
 +        RST     20H             ; Shadow Error Restart 
 +        DEFB    $0C             ; Writing to a 'read' file 
 + 
 +<a name="L0E17"></a>;; <b>TEST-OUT</b> 
 +L0E17:  LD      E,(IX+$10)      ; NCOBL 
 +        INC                   ; 
 +        JR      NZ,<A href="#L0E25">L0E25</a>        ; forward to ST-BF-LEN 
 + 
 +        PUSH    AF              ; 
 +        XOR                   ; 
 +        CALL    <A href="#L0E48">L0E48</a>           ; routine S-PACK-1 
 +        POP     AF              ; 
 +        LD      E,$01           ; 
 + 
 +<a name="L0E25"></a>;; <b>ST-BF-LEN</b> 
 +L0E25:  LD      (IX+$10),     ; NCOBL 
 +        LD      D,$00           ; 
 +        ADD     IX,DE           ; 
 +        LD      (IX+$14),     ; NCIBL 
 +        RET                     ; 
 + 
 + 
 +; ----------------------- 
 +; THE <b><font color=#333388>'OUT-BLK-N'</font></b> ROUTINE 
 +; ----------------------- 
 +
 + 
 +<a name="L0E30"></a>;; <b>OUT-BLK-N</b> 
 +L0E30:  CALL    <A href="#L1082">L1082</a>           ; routine OUTPAK 
 +        LD      A,(IX+$0B)      ; NCIRIS 
 +        AND                   ; 
 +        RET                   ; 
 + 
 +        LD      HL,$5CCD        ; sv NTRESP 
 +        LD      (HL),$00        ; 
 +        LD      E,$01           ; 
 +        CALL    <A href="#L104F">L104F</a>           ; routine INPAK 
 +        RET     NZ              ; 
 + 
 +        LD      A,($5CCD)       ; sv NTRESP 
 +        DEC                   ; 
 +        RET                     ; 
 + 
 + 
 +; ---------------------- 
 +; THE <b><font color=#333388>'S-PACK-1'</font></b> ROUTINE 
 +; ---------------------- 
 +
 + 
 +<a name="L0E48"></a>;; <b>S-PACK-1</b> 
 +L0E48:  CALL    <A href="#L0E4F">L0E4F</a>           ; routine SEND-PACK 
 +        RET     NZ              ; 
 + 
 +        JP      <A href="#L0EAC">L0EAC</a>           ; jump to BR-DELAY 
 + 
 +; ----------------------- 
 +; THE <b><font color=#333388>'SEND-PACK'</font></b> ROUTINE 
 +; ----------------------- 
 +; <font color=#339933>(Hook Code: $30)</font> 
 + 
 +<a name="L0E4F"></a>;; <b>SEND-PACK</b> 
 +L0E4F:  LD      (IX+$0F),     ; NCTYPE 
 +        LD      B,(IX+$10)      ; NCOBL 
 +        LD      A,($5CC6)       ; sv IOBORD 
 +        OUT     ($FE),        ; 
 + 
 +        PUSH    IX              ; 
 +        POP     DE              ; 
 + 
 +        LD      HL,$0015        ; 
 +        ADD     HL,DE           ; 
 +        XOR                   ; 
 + 
 +<a name="L0E62"></a>;; <b>CHKS1</b> 
 +L0E62:  ADD     A,(HL)          ; 
 +        INC     HL              ; 
 +        DJNZ    <A href="#L0E62">L0E62</a>           ; back to CHKS1 
 + 
 +        LD      (IX+$11),     ; NCDCS 
 +        LD      HL,$000B        ; 
 +        ADD     HL,DE           ; 
 +        PUSH    HL              ; 
 +        LD      B,$07           ; 
 +        XOR                   ; 
 + 
 +<a name="L0E71"></a>;; <b>CHKS2</b> 
 +L0E71:  ADD     A,(HL)          ; 
 +        INC     HL              ; 
 +        DJNZ    <A href="#L0E71">L0E71</a>           ; back to CHKS2 
 + 
 +        LD      (HL),         ; 
 +        DI                      ; 
 + 
 +<a name="L0E77"></a>;; <b>SENDSCOUT</b> 
 +L0E77:  CALL    <A href="#L101E">L101E</a>           ; routine SEND-SC 
 +        POP     HL              ; 
 +        PUSH    HL              ; 
 +        LD      E,$08           ; 
 +        CALL    <A href="#L0E30">L0E30</a>           ; routine OUT-BLK-N 
 +        JR      NZ,<A href="#L0E77">L0E77</a>        ; back to SENDSCOUT 
 + 
 +        PUSH    IX              ; 
 +        POP     HL              ; 
 + 
 +        LD      DE,$0015        ; 
 +        ADD     HL,DE           ; 
 +        LD      E,(IX+$10)      ; NCOBL 
 +        LD      A,E             ; 
 +        AND                   ; 
 +        JR      Z,<A href="#L0E9A">L0E9A</a>         ; forward to INC-BLKN 
 + 
 +        LD      B,$20           ; 
 + 
 +<a name="L0E93"></a>;; <b>SP-DL-1</b> 
 +L0E93:  DJNZ    <A href="#L0E93">L0E93</a>           ; back to SP-DL-1 
 + 
 +        CALL    <A href="#L0E30">L0E30</a>           ; routine OUT-BLK-N 
 +        JR      NZ,<A href="#L0E77">L0E77</a>        ; back to SENDSCOUT 
 + 
 + 
 +<a name="L0E9A"></a>;; <b>INC-BLKN</b> 
 +L0E9A:  INC     (IX+$0D)        ; NCNUMB 
 +        JR      NZ,<A href="#L0EA2">L0EA2</a>        ; forward to SP-N-END 
 + 
 +        INC     (IX+$0E)        ; NCNUMB_hi 
 + 
 +<a name="L0EA2"></a>;; <b>SP-N-END</b> 
 +L0EA2:  POP     HL              ; 
 +        CALL    <A href="#L0D4D">L0D4D</a>           ; routine BORD-REST 
 +        EI                      ; 
 +        LD      A,(IX+$0B)      ; NCIRIS 
 +        AND                   ; 
 +        RET                     ; 
 + 
 + 
 +; ---------------------- 
 +; THE <b><font color=#333388>'BR-DELAY'</font></b> ROUTINE 
 +; ---------------------- 
 +
 + 
 +<a name="L0EAC"></a>;; <b>BR-DELAY</b> 
 +L0EAC:  LD      DE,$1500        ; 
 + 
 +<a name="L0EAF"></a>;; <b>DL-LOOP</b> 
 +L0EAF:  DEC     DE              ; 
 +        LD      A,E             ; 
 +        OR      D               ; 
 +        JR      NZ,<A href="#L0EAF">L0EAF</a>        ; back to DL-LOOP 
 + 
 +        RET                     ; 
 + 
 + 
 +; --------------------------------------------- 
 +; THE <b><font color=#333388>'HEADER AND DATA BLOCK RECEIVING'</font></b> ROUTINE 
 +; --------------------------------------------- 
 +
 + 
 +<a name="L0EB5"></a>;; <b>GET-NBLK</b> 
 +L0EB5:  LD      HL,$5CCE        ; sv NTDEST 
 +        LD      E,$08 
 +        CALL    <A href="#L104F">L104F</a>           ; routine INPAK 
 +        RET     NZ 
 + 
 +        LD      HL,$5CCE        ; sv NTDEST 
 +        XOR     A 
 +        LD      B,$07 
 + 
 +<a name="L0EC4"></a>;; <b>CHKS3</b> 
 +L0EC4:  ADD     A,(HL) 
 +        INC     HL 
 +        DJNZ    <A href="#L0EC4">L0EC4</a>           ; back to CHKS3 
 + 
 +        CP      (HL) 
 +        RET     NZ 
 + 
 +        LD      A,($5CCE)       ; sv NTDEST 
 +        AND     A 
 +        JR      Z,<A href="#L0EDD">L0EDD</a>         ; forward to BRCAST 
 + 
 +        CP      (IX+$0C)        ; NCSELF 
 +        RET     NZ 
 + 
 +        LD      A,($5CCF)       ; sv NTSRCE 
 +        CP      (IX+$0B)        ; NCIRIS 
 +        RET     NZ 
 + 
 +        JR      <A href="#L0EE2">L0EE2</a>           ; forward to TEST-BLKN 
 + 
 +; --- 
 + 
 +<a name="L0EDD"></a>;; <b>BRCAST</b> 
 +L0EDD:  LD      A,(IX+$0B)      ; NCIRIS 
 +        OR      A 
 +        RET     NZ 
 + 
 + 
 +<a name="L0EE2"></a>;; <b>TEST-BLKN</b> 
 +L0EE2:  LD      HL,($5CD0)      ; sv NTNUMB 
 +        LD      E,(IX+$0D)      ; NCNUMB_lo 
 +        LD      D,(IX+$0E)      ; NCNUMB_hi 
 +        AND     A 
 +        SBC     HL,DE 
 +        JR      Z,<A href="#L0F02">L0F02</a>         ; forward to GET-NBUFF 
 + 
 +        DEC     HL 
 +        LD      A,H 
 +        OR      L 
 +        RET     NZ 
 + 
 +;   <font color=#9900FF>Note.</font> The return status of the next routine should really be checked. 
 + 
 +        CALL    <A href="#L0F02">L0F02</a>           ; routine GET-NBUFF 
 + 
 +;   <font color=#9900FF>Note.</font> The DEC instruction does not affect the carry flag. 
 + 
 +        DEC     (IX+$0D)        ; NCNUMB_lo 
 +        JR      NC,<A href="#L0EFF">L0EFF</a>        ; forward, with no carry, to GETNB-END !! 
 + 
 +        DEC     (IX+$0E)        ; NCNUMB_hi 
 + 
 +<a name="L0EFF"></a>;; <b>GETNB-END</b> 
 +L0EFF:  OR      $01 
 +        RET 
 + 
 + 
 +<a name="L0F02"></a>;; <b>GET-NBUFF</b> 
 +L0F02:  LD      A,($5CCE)       ; sv NTDEST 
 +        OR      A 
 +        CALL    NZ,<A href="#L107B">L107B</a>        ; routine SEND-RESP 
 +        LD      A,($5CD3)       ; sv NTLEN 
 +        AND     A 
 +        JR      Z,<A href="#L0F30">L0F30</a>         ; forward to STORE-LEN 
 + 
 +        PUSH    IX 
 +        POP     HL 
 + 
 +        LD      DE,$0015 
 +        ADD     HL,DE 
 +        PUSH    HL 
 +        LD      E,A 
 +        CALL    <A href="#L104F">L104F</a>           ; routine INPAK 
 +        POP     HL 
 +        RET     NZ 
 + 
 +        LD      A,($5CD3)       ; sv NTLEN 
 +        LD      B,A 
 +        LD      A,($5CD4)       ; sv NTDCS 
 + 
 +<a name="L0F24"></a>;; <b>CHKS4</b> 
 +L0F24:  SUB     (HL) 
 +        INC     HL 
 +        DJNZ    <A href="#L0F24">L0F24</a>           ; back to CHKS4 
 + 
 +        RET     NZ 
 + 
 +        LD      A,($5CCE)       ; sv NTDEST 
 +        AND     A 
 +        CALL    NZ,<A href="#L107B">L107B</a>        ; routine SEND-RESP 
 + 
 +<a name="L0F30"></a>;; <b>STORE-LEN</b> 
 +L0F30:  LD      A,($5CD3)       ; sv NTLEN 
 +        LD      (IX+$14),     ; NCIBL 
 +        INC     (IX+$0D)        ; NCNUMB_lo 
 +        JR      NZ,<A href="#L0F3E">L0F3E</a>        ; forward to GETBF-END 
 + 
 +        INC     (IX+$0E)        ; NCNUMB_hi 
 + 
 +<a name="L0F3E"></a>;; <b>GETBF-END</b> 
 +L0F3E:  CP      A 
 +        RET 
 + 
 + 
 +; -------------------------------------- 
 +; THE <b><font color=#333388>'OPEN "N" CHANNEL COMMAND'</font></b> ROUTINE 
 +; -------------------------------------- 
 +
 + 
 +<a name="L0F40"></a>;; <b>OPEN-N-ST</b> 
 +L0F40:  CALL    <A href="#L0F52">L0F52</a>           ; routine OP-PERM-N 
 +        JP      <A href="#L0B51">L0B51</a>           ; jump to OP-STREAM 
 + 
 +; ---------------------------------------- 
 +; THE <b><font color=#333388>'OPEN TEMPORARY "N" CHANNEL'</font></b> ROUTINE 
 +; ---------------------------------------- 
 +; <font color=#339933>(Hook Code: $2D)</font> 
 +
 + 
 +<a name="L0F46"></a>;; <b>OP-TEMP-N</b> 
 +L0F46:  CALL    <A href="#L0F52">L0F52</a>           ; routine OP-PERM-N 
 +        LD      IX,($5C51)      ; sv CURCHL 
 +        SET     7,(IX+$04)      ; channel letter 
 +        RET 
 + 
 + 
 +; ---------------------------------------- 
 +; THE <b><font color=#333388>'OPEN PERMANENT "N" CHANNEL'</font></b> ROUTINE 
 +; ---------------------------------------- 
 +
 + 
 +<a name="L0F52"></a>;; <b>OP-PERM-N</b> 
 +L0F52:  LD      HL,($5C53)      ; sv PROG 
 +        DEC     HL 
 + 
 +        LD      BC,$0114 
 +        PUSH    BC 
 +        PUSH    HL 
 +        PUSH    BC 
 +        LD      HL,($5C65)      ; sv STKEND 
 +        ADD     HL,BC 
 +        JP      C,<A href="#L0F9E">L0F9E</a>         ; jump to OUTMEM 
 + 
 +        LD      BC,$0050 
 +        ADD     HL,BC 
 +        JP      C,<A href="#L0F9E">L0F9E</a>         ; jump to OUTMEM 
 + 
 +        SBC     HL,SP 
 +        JP      NC,<A href="#L0F9E">L0F9E</a>        ; jump to OUTMEM 
 + 
 +        POP     BC 
 +        POP     HL 
 + 
 +        RST     10H             ; CALBAS 
 +        DEFW    $1655           ; main MAKE-ROOM 
 + 
 +        INC     HL 
 +        POP     BC 
 +        CALL    <A href="#L1A82">L1A82</a>           ; routine REST-N-AD 
 +        LD      ($5C51),HL      ; sv CURCHL 
 + 
 +        EX      DE,HL           ; 
 +        LD      HL,<A href="#L0FA3">L0FA3</a>        ; NCHAN-DAT 
 +        LD      BC,$000B        ; eleven bytes. 
 +        LDIR                    ; 
 + 
 +        LD      A,($5CD6)       ; sv D_STR1 drive number 
 +        LD      (DE),A 
 +        INC     DE 
 +        LD      A,($5CC5)       ; sv NTSTAT 
 +        LD      (DE),A 
 +        INC     DE 
 +        XOR     A 
 +        LD      (DE),A 
 +        LD      H,D 
 +        LD      L,E 
 +        INC     DE 
 +        LD      BC,$0106 
 +        LDIR 
 +        LD      DE,($5C51)      ; sv CURCHL 
 +        RET 
 + 
 +; --- 
 + 
 + 
 +<a name="L0F9E"></a>;; <b>OUTMEM</b> 
 +L0F9E:  LD      (IY+$00),$03    ; sv ERR_NR 
 +        RST     28H             ; Error Main ROM 
 + 
 + 
 +; ------------------------------ 
 +; THE <b><font color=#333388>'"N" CHANNEL DATA'</font></b> ROUTINE 
 +; ------------------------------ 
 +
 + 
 +<a name="L0FA3"></a>;; <b>NCHAN_DAT</b> 
 +L0FA3:  DEFW    $0008           ; main ERROR-1 
 +        DEFW    $0008           ; main ERROR-1 
 +        DEFB    $4E             ; character "N" 
 +        DEFW    <A href="#L0E09">L0E09</a>           ; NCHAN-OUT 
 +        DEFW    <A href="#L0DA9">L0DA9</a>           ; N-INPUT 
 +        DEFW    $0114           ; length 
 + 
 + 
 +; --------------------------------------- 
 +; THE <b><font color=#333388>'SEND EOF BLOCK TO NETWORK'</font></b> ROUTINE 
 +; --------------------------------------- 
 +
 + 
 +<a name="L0FAE"></a>;; <b>SEND-NEOF</b> 
 +L0FAE:  LD      IX,($5C51)      ; sv CURCHL 
 +        LD      A,(IX+$10)      ; NCOBL 
 +        AND                   ; 
 +        RET                   ; 
 + 
 +        LD      A,$01           ; 
 +        JP      <A href="#L0E48">L0E48</a>           ; jump to S-PACK-1 
 + 
 +; --------------------------- 
 +; THE <b><font color=#333388>'NETWORK STATE'</font></b> ROUTINE 
 +; --------------------------- 
 +
 + 
 +<a name="L0FBC"></a>;; <b>NET-STATE</b> 
 +L0FBC:  LD      A,R             ; 
 +        OR      $C0             ; 
 +        LD      B,A             ; 
 +        CALL    <A href="#L0FC7">L0FC7</a>           ; routine CHK-REST 
 +        JR      C,<A href="#L0FBC">L0FBC</a>         ; back to NET-STATE 
 + 
 +        RET                     ; 
 + 
 + 
 +; --------------------------- 
 +; THE <b><font color=#333388>'CHECK-RESTING'</font></b> ROUTINE 
 +; --------------------------- 
 +
 + 
 +<a name="L0FC7"></a>;; <b>CHK-REST</b> 
 +L0FC7:  CALL    <A href="#L163E">L163E</a>           ; routine TEST-BRK 
 + 
 +<a name="L0FCA"></a>;; <b>MAKESURE</b> 
 +L0FCA:  PUSH    BC              ; 
 +        POP     BC              ; 
 +        IN      A,($F7)         ; 
 +        RRCA                    ; 
 +        RET                   ; 
 + 
 +        DJNZ    <A href="#L0FCA">L0FCA</a>           ; back to MAKESURE 
 + 
 +        RET                     ; 
 + 
 + 
 +; ------------------------ 
 +; THE <b><font color=#333388>'WAIT-SCOUT'</font></b> ROUTINE 
 +; ------------------------ 
 +
 + 
 +<a name="L0FD3"></a>;; <b>WT-SC-E</b> 
 +L0FD3:  CALL    <A href="#L163E">L163E</a>           ; routine TEST-BRK 
 +        LD      HL,$01C2        ; 
 + 
 +<a name="L0FD9"></a>;; <b>CLAIMED</b> 
 +L0FD9:  LD      B,$80           ; 
 +        CALL    <A href="#L0FC7">L0FC7</a>           ; routine CHK-REST 
 +        JR      NC,<A href="#L0FED">L0FED</a>        ; forward to WT-SYNC 
 + 
 +        DEC     HL              ; 
 +        DEC     HL              ; 
 +        LD      A,H             ; 
 +        OR      L               ; 
 +        JR      NZ,<A href="#L0FD9">L0FD9</a>        ; back to CLAIMED 
 + 
 +        LD      A,(IX+$0B)      ; NCIRIS 
 +        AND                   ; 
 +        JR      Z,<A href="#L0FD9">L0FD9</a>         ; back to CLAIMED 
 + 
 +        RET                     ; 
 + 
 + 
 +<a name="L0FED"></a>;; <b>WT-SYNC</b> 
 +L0FED:  IN      A,($F7)         ; 
 +        RRCA                    ; 
 +        JR      C,<A href="#L1013">L1013</a>         ; forward to SCOUT-END 
 + 
 +        LD      A,$7F           ; 
 +        IN      A,($FE)         ; 
 +        OR      $FE             ; 
 +        IN      A,($FE)         ; 
 +        RRA                     ; 
 +        CALL    NC,<A href="#L163E">L163E</a>        ; routine TEST-BRK 
 +        DEC     HL              ; 
 +        LD      A,H             ; 
 +        OR      L               ; 
 +        JR      NZ,<A href="#L0FED">L0FED</a>        ; back to WT-SYNC 
 + 
 +        LD      A,(IX+$0B)      ; NCIRIS 
 +        AND                   ; 
 +        JR      Z,<A href="#L0FED">L0FED</a>         ; back to WT-SYNC 
 + 
 +        RET                     ; 
 + 
 + 
 +; -------------------------------------- 
 +; THE <b><font color=#333388>'BREAK INTO I/O OPERATION'</font></b> ROUTINE 
 +; -------------------------------------- 
 +; <font color=#9900FF>Note.</font> an obsolete duplicate. 
 + 
 +<a name="L100A"></a>;; <b>E-READ-N</b> 
 +L100A:  EI                      ; 
 +        CALL    <A href="#L0D4D">L0D4D</a>           ; routine BORD-REST 
 +        LD      (IY+$00),$14    ; sv ERR_NR 
 +        RST     28H             ; Error Main ROM 
 + 
 +; ---------------------- 
 +; THE <b><font color=#333388>'SCOUT END'</font></b> BRANCH 
 +; ---------------------- 
 +
 + 
 +<a name="L1013"></a>;; <b>SCOUT-END</b> 
 +L1013:  LD      L,$09 
 + 
 +<a name="L1015"></a>;; <b>LP-SCOUT</b> 
 +L1015:  DEC     L 
 +        SCF 
 +        RET     Z 
 + 
 +        LD      B,$0E 
 + 
 +<a name="L101A"></a>;; <b>DELAY-SC</b> 
 +L101A:  DJNZ    <A href="#L101A">L101A</a>           ; back to DELAY-SC 
 + 
 +        JR      <A href="#L1015">L1015</a>           ; back to LP-SCOUT 
 + 
 + 
 +; ------------------------ 
 +; THE <b><font color=#333388>'SEND-SCOUT'</font></b> ROUTINE 
 +; ------------------------ 
 +
 + 
 +<a name="L101E"></a>;; <b>SEND-SC</b> 
 +L101E:  CALL    <A href="#L0FBC">L0FBC</a>           ; routine NET-STATE 
 +        LD      C,$F7 
 +        LD      HL,$0009 
 +        LD      A,($5CC5)       ; sv NTSTAT 
 +        LD      E,A 
 +        IN      A,($F7) 
 +        RRCA 
 +        JR      C,<A href="#L101E">L101E</a>         ; back to SEND-SC 
 + 
 + 
 +<a name="L102F"></a>;; <b>ALL-BITS</b> 
 +L102F:  OUT     (C),
 +        LD      D,H 
 +        LD      H,$00 
 +        RLC     E 
 +        RL      H 
 + 
 + 
 +        LD      B,$08 
 + 
 +<a name="L103A"></a>;; <b>S-SC-DEL</b> 
 +L103A:  DJNZ    <A href="#L103A">L103A</a>           ; back to S-SC-DEL 
 + 
 +        IN      A,($F7) 
 +        AND     $01 
 +        CP      D 
 +        JR      Z,<A href="#L101E">L101E</a>         ; back to SEND-SC 
 + 
 +        DEC     L 
 +        JR      NZ,<A href="#L102F">L102F</a>        ; back to ALL-BITS 
 + 
 +        LD      A,$01 
 +        OUT     ($F7),
 +        LD      B,$0E 
 + 
 +<a name="L104C"></a>;; <b>END-S-DEL</b> 
 +L104C:  DJNZ    <A href="#L104C">L104C</a>           ; back to END-S-DEL 
 + 
 +        RET 
 + 
 + 
 +; ------------------- 
 +; THE <b><font color=#333388>'INPAK'</font></b> ROUTINE 
 +; ------------------- 
 +
 + 
 +<a name="L104F"></a>;; <b>INPAK</b> 
 +L104F:  LD      B,$FF 
 + 
 +<a name="L1051"></a>;; <b>N-ACTIVE</b> 
 +L1051:  IN      A,($F7) 
 +        RRA 
 +        JR      C,<A href="#L105A">L105A</a>         ; forward to INPAK-2 
 + 
 +        DJNZ    <A href="#L1051">L1051</a>           ; back to N-ACTIVE 
 + 
 +        INC     B 
 +        RET 
 + 
 +; --- 
 + 
 +<a name="L105A"></a>;; <b>INPAK-2</b> 
 +L105A:  LD      B,E 
 + 
 +<a name="L105B"></a>;; <b>INPAK-L</b> 
 +L105B:  LD      E,$80 
 +        LD      A,$CE 
 +        OUT     ($EF),
 +        NOP 
 +        NOP 
 +        INC     IX 
 +        DEC     IX 
 +        INC     IX 
 +        DEC     IX 
 + 
 +<a name="L106B"></a>;; <b>UNTIL-MK</b> 
 +L106B:  LD      A,$00 
 +        IN      A,($F7) 
 +        RRA 
 +        RR      E 
 +        JP      NC,<A href="#L106B">L106B</a>        ; jump to UNTIL-MK 
 +        LD      (HL),E 
 +        INC     HL 
 +        DJNZ    <A href="#L105B">L105B</a>           ; back to INPAK-L 
 + 
 +        CP      A 
 +        RET 
 + 
 + 
 +; -------------------------------- 
 +; THE <b><font color=#333388>'SEND RESPONSE BYTE'</font></b> ROUTINE 
 +; -------------------------------- 
 +
 + 
 +<a name="L107B"></a>;; <b>SEND-RESP</b> 
 +L107B:  LD      A,$01 
 +        LD      HL,$5CCD        ; sv NTRESP 
 +        LD      (HL),A 
 +        LD      E,A 
 + 
 +; -------------------- 
 +; THE <b><font color=#333388>'OUTPAK'</font></b> ROUTINE 
 +; -------------------- 
 +
 + 
 +<a name="L1082"></a>;; <b>OUTPAK</b> 
 +L1082:  XOR     A 
 +        OUT     ($F7),
 +        LD      B,$04 
 + 
 +<a name="L1087"></a>;; <b>DEL-0-1</b> 
 +L1087:  DJNZ    <A href="#L1087">L1087</a>           ; back to DEL-0-1 
 + 
 + 
 +<a name="L1089"></a>;; <b>OUTPAK-L</b> 
 +L1089:  LD      A,(HL) 
 +        CPL 
 +        SCF 
 +        RLA 
 +        LD      B,$0A 
 + 
 +<a name="L108F"></a>;; <b>UNT-MARK</b> 
 +L108F:  OUT     ($F7),
 +        RRA 
 +        AND     A 
 +        DEC     B 
 +        LD      D,$00 
 +        JP      NZ,<A href="#L108F">L108F</a>        ; jump to UNT-MARK 
 +        INC     HL 
 +        DEC     E 
 +        PUSH    HL 
 +        POP     HL 
 +        JP      NZ,<A href="#L1089">L1089</a>        ; jump to OUTPAK-L 
 +        LD      A,$01 
 +        OUT     ($F7),
 +        RET 
 + 
 +; ***************************************************** 
 +; **  T H E   M I C R O D R I V E   R O U T I N E S  ** 
 +; ***************************************************** 
 +; The shadow ROM uses the alternate HL register solely in connection with the 
 +; microdrive maps. This does not conflict with the Main ROM use in the 
 +; calculator.  When used as a Hook Codes, then the calculator is implicitly in 
 +; use by the user and so HL' should be preserved throughout. 
 + 
 +; ----------------------------------------- 
 +; THE <b><font color=#333388>'SET A TEMPORARY "M" CHANNEL'</font></b> ROUTINE 
 +; ----------------------------------------- 
 +; <font color=#339933>(Hook Code: $2B)</font> 
 +; This routine is used to create all microdrive channels. The routine that  
 +; creates a permanent channel (as used by a print file) uses this routine and 
 +; then converts the temporary channel to a permanent one. 
 +; Temporary channels are created by LOAD, SAVE, CAT etc. and last just as long 
 +; as required. They are deleted before returning to the Main ROM by the next  
 +; routine DEL-M-BUF. 
 + 
 +<a name="L10A5"></a>;; <b>SET-T-MCH</b> 
 +L10A5:  EXX                     ; exx 
 +        LD      HL,$0000        ; set HL' to zero as the default no-map-exists 
 +                                ; condition. 
 +        EXX                     ; exx 
 + 
 +        LD      IX,($5C4F)      ; set IX from system variable CHANS. 
 +        LD      DE,$0014        ; skip over the twenty bytes of the standard 
 +        ADD     IX,DE           ; channels to point to the next or end-marker. 
 + 
 +; now enter a search of existing "M" channels to see if any use the same drive. 
 + 
 +<a name="L10B3"></a>;; <b>CHK-LOOP</b> 
 +L10B3:  LD      A,(IX+$00)      ; fetch the next byte. 
 +        CP      $80             ; compare to end-marker. 
 +        JR      Z,<A href="#L10F1">L10F1</a>         ; forward, if so, to CHAN-SPC. 
 + 
 +        LD      A,(IX+$04)      ; fetch the letter of the extended channel. 
 +        AND     $7F             ; reset bit 7. 
 +        CP      $4D             ; is it character 'M'
 +        JR      NZ,<A href="#L10E7">L10E7</a>        ; forward, if not, to NEXT-CHAN. 
 + 
 +; an existing Microdrive Channel has been found. 
 + 
 +        LD      A,($5CD6)       ; fetch drive number from system variable D_STR1 
 +        CP      (IX+$19)        ; compare to CHDRIV the drive associated with 
 +                                ; this channel. 
 +        JR      NZ,<A href="#L10E7">L10E7</a>        ; forward, if not the same, to NEXT-CHAN. 
 + 
 +; a Microdrive Channel has been found that matches the current drive. 
 +; It will not be necessary to create a new map for the temporary channel. 
 + 
 +        EXX                     ; - 
 +        LD      L,(IX+$1A)      ; load address of the associated microdrive. 
 +        LD      H,(IX+$1B)      ; map into the HL' register. 
 +        EXX                     ; - 
 + 
 +        LD      BC,($5CDA)      ; load BC with length of filename from N_STR1. 
 +        LD      HL,($5CDC)      ; load HL with address of filename. 
 + 
 +        CALL    <A href="#L1403">L1403</a>           ; routine CHK-NAME checks name in channel 
 +                                ; against name addressed by HL. 
 + 
 +        JR      NZ,<A href="#L10E7">L10E7</a>        ; forward, with name mismatch, to NEXT-CHAN. 
 + 
 +        BIT     0,(IX+$18)      ; test CHFLAG. 
 +        JR      Z,<A href="#L10E7">L10E7</a>         ; forward to NEXT-CHAN. 
 + 
 +        RST     20H             ; Shadow Error Restart. 
 +        DEFB    $0D             ; Reading a 'write' file. 
 + 
 +<a name="L10E7"></a>;; <b>NEXT-CHAN</b> 
 +L10E7:  LD      E,(IX+$09)      ; fetch length of channel. 
 +        LD      D,(IX+$0A)      ; to the DE register pair. 
 +        ADD     IX,DE           ; add to point to the following location. 
 +        JR      <A href="#L10B3">L10B3</a>           ; loop back to CHK-LOOP until end-marker found. 
 + 
 +; --- 
 + 
 +; Now create the space for the channel. 
 + 
 +<a name="L10F1"></a>;; <b>CHAN-SPC</b> 
 +L10F1:  LD      HL,($5C53)      ; set pointer from system variable PROG. 
 +        DEC     HL              ; now points to channels end-marker (as does IX) 
 + 
 +        PUSH    HL              ; * save a copy of new location. 
 +        LD      BC,$0253        ; set amount of bytes required. 
 + 
 +;   <font color=#9900FF>Note.</font> interrupts are disabled so on the original shadow ROM, which launched  
 +;   straight into the MAKE-ROOM routine, the system hung if there was  
 +;   insufficient free memory, at the HALT instruction in the Main error report. 
 +;   The solution here is to perform the same checks that will be performed by  
 +;   the Main MAKE-ROOM routine. 
 + 
 +        PUSH    HL              ; save first location 
 +        PUSH    BC              ; and amount while free memory is checked. 
 + 
 +        LD      HL,($5C65)      ; fetch start of free memory from STKEND 
 +        ADD     HL,BC           ; add bytes required producing carry if 
 +                                ; result is higher than 65535 
 +        JP      C,<A href="#L119A">L119A</a>         ; jump, if so, to OUTMEM2 
 + 
 +        LD      BC,$0050        ; now allow for overhead of eighty bytes. 
 +        ADD     HL,BC           ; and perform same test. 
 +        JP      C,<A href="#L119A">L119A</a>         ; jump, if too high, to OUTMEM2 
 + 
 +        SBC     HL,SP           ; finally test that result is less than the 
 +                                ; stack pointer at the other side of free memory. 
 +        JP      NC,<A href="#L119A">L119A</a>        ; jump, if higher, to OUTMEM2. 
 + 
 +        POP     BC              ; restore the new room 
 +        POP     HL              ; parameters. 
 + 
 +; now call the MAKE-ROOM routine in the certain knowledge that nothing can 
 +; go wrong. 
 + 
 +        RST     10H             ; CALBAS 
 +        DEFW    $1655           ; main MAKE-ROOM 
 + 
 +        POP     DE              ; * restore pointer to first new location. 
 +        PUSH    DE              ; * and save on machine stack again. 
 + 
 +        LD      HL,<A href="#L14B1">L14B1</a>        ; the default "M" CHANNEL DATA. 
 +        LD      BC,$0019        ; twenty five bytes to copy including blank 
 +        LDIR                    ; filename to start of new channel. 
 + 
 +        LD      A,($5CD6)       ; fetch drive number from D_STR1. 
 +        LD      (IX+$19),     ; insert at CHDRIV. 
 + 
 +        LD      BC,$0253        ; set BC to amount of room that was created. 
 + 
 +        PUSH    IX              ; move start of channel 
 +        POP     HL              ; to HL register. 
 + 
 +        CALL    <A href="#L1A82">L1A82</a>           ; routine REST-N-AD corrects filename pointers 
 +                                ; leaving DE at first filename D_STR1. 
 + 
 +        EX      DE,HL           ; transfer filename pointer to HL. 
 + 
 +        LD      BC,($5CDA)      ; set BC to length of filename from N_STR1. 
 + 
 +        BIT     7,            ; test for the default $FF bytes. 
 +        JR      NZ,<A href="#L1143">L1143</a>        ; forward, with no name, to TEST-MAP 
 + 
 +; now enter a loop to transfer the filename to CHNAME, counting BC down to zero. 
 +; The filename could be in ROM with <b><font color=#333388>'run'</font></b> or more usually in string workspace 
 +; with its parameters on the calculator stack as with  
 +; LOAD * "m";1;"crapgame" 
 +; SAVE * "M";7; CHR$0 + "secret"
 + 
 + 
 +<a name="L1135"></a>;; <b>T-CH-NAME</b> 
 +L1135:  LD      A,B             ; check length 
 +        OR      C               ; for zero. 
 +        JR      Z,<A href="#L1143">L1143</a>         ; forward, if so, to TEST-MAP. 
 + 
 +        LD      A,(HL)          ; fetch character of filename. 
 +        LD      (IX+$0E),     ; transfer to same position in CHNAME. 
 + 
 +        INC     HL              ; increment 
 +        INC     IX              ; both pointers. 
 +        DEC     BC              ; decrement length. 
 +        JR      <A href="#L1135">L1135</a>           ; loop back to T-CH-NAME. 
 + 
 +; --- 
 + 
 +<a name="L1143"></a>;; <b>TEST-MAP</b> 
 +L1143:  POP     IX              ; * restore pointer to first location of channel. 
 + 
 +        EXX                     ; exchange set - no need now to keep balanced. 
 +        LD      A,H             ; test map address for zero . 
 +        OR      L               ; indicating that this drive has no map. 
 +        JR      NZ,<A href="#L1168">L1168</a>        ; forward, if map exists, to ST-MAP-AD. 
 + 
 +; a microdrive map is now created for this drive. 
 + 
 +        LD      HL,($5C4F)      ; set pointer from system variable CHANS. 
 +        PUSH    HL              ; save this pointer to the new area. 
 +        DEC     HL              ; set HL to location before new room. 
 +        LD      BC,$0020        ; thirty two bytes are required. 
 + 
 +        RST     10H             ; CALBAS 
 +        DEFW    $1655           ; main MAKE-ROOM. 
 + 
 +; now handle dynamic pointers outside the control of the Main ROM 
 + 
 +        POP     HL              ; restore pointer to first location. 
 +        LD      BC,$0020        ; thirty two bytes were created. 
 +        ADD     IX,BC           ; channel was moved up so adjust that pointer. 
 + 
 +        CALL    <A href="#L1A82">L1A82</a>           ; routine REST-N-AD corrects filename pointers. 
 + 
 +; fill map with $FF bytes 
 + 
 +        LD      A,$FF           ; the fill byte. 
 +        LD      B,$20           ; thirty two locations. 
 +        PUSH    HL              ; save map address pointer. 
 + 
 +<a name="L1163"></a>;; <b>FILL-MAP</b> 
 +L1163:  LD      (HL),         ; insert the byte 
 +        INC     HL              ; next location. 
 +        DJNZ    <A href="#L1163">L1163</a>           ; loop back to FILL-MAP 
 + 
 +        POP     HL              ; restore address. 
 + 
 +<a name="L1168"></a>;; <b>ST-MAP-AD</b> 
 +L1168:  LD      (IX+$1A),     ; place map address in 
 +        LD      (IX+$1B),     ; channel at CHMAP. 
 + 
 +; now make DE point to IX+$19 the header preamble and copy ROM preamble bytes. 
 + 
 +        PUSH    IX              ; push start of channel 
 +        POP     HL              ; pop to HL 
 + 
 +        LD      DE,$001C        ; the offset is $1C 
 +        ADD     HL,DE           ; add to point to start of header preamble. 
 +        EX      DE,HL           ; transfer this destination to DE. 
 + 
 +        LD      HL,<A href="#L14CA">L14CA</a>        ; point HL to PREAMBLE data in this ROM. 
 +        LD      BC,$000C        ; twelve bytes to copy to channel. 
 +        LDIR                    ; in they go. 
 + 
 +; now use the same technique to copy the same 12 bytes of ROM preamble 
 +; to IX+$37, the data block preamble in the channel. 
 +; A little long-winded as the destination only requires adjustment. 
 + 
 +        PUSH    IX              ; 
 +        POP     HL              ; 
 +        LD      DE,$0037        ; 
 +        LD      BC,$000C        ; 
 + 
 +        ADD     HL,DE           ; 
 +        EX      DE,HL           ; 
 +        LD      HL,<A href="#L14CA">L14CA</a>        ; the PREAMBLE data. 
 +        LDIR                    ; 
 + 
 +; now form the offset from CHANS to this channel for a return value to be 
 +; inserted in the STRMS area. 
 + 
 +        PUSH    IX              ; transfer 
 +        POP     HL              ; pointer. 
 + 
 +        LD      DE,($5C4F)      ; fetch start of CHANS area from CHANS 
 +        OR      A               ; clear carry for subtraction. 
 +        SBC     HL,DE           ; the true offset. 
 + 
 +        INC     HL              ; add one as the offset is to second location. 
 + 
 +        RET                     ; return.               &gt;&gt;&gt; 
 + 
 +; --- 
 + 
 +<a name="L119A"></a>;; <b>OUTMEM2</b> 
 +L119A:  LD      (IY+$00),$03    ; set ERR_NR for '4 Out of memory' 
 +        RST     28H             ; Error Main ROM 
 + 
 +; --------------------------------- 
 +; THE <b><font color=#333388>'RECLAIM "M" CHANNEL'</font></b> ROUTINE 
 +; --------------------------------- 
 +; <font color=#339933>(Hook Code: $2C)</font> 
 +; This routine is used to reclaim a temporary "M" channel such as that created  
 +; by the routine above and to reclaim a permanent "M" channel by the CLOSE 
 +; command routines. 
 + 
 +<a name="L119F"></a>;; <b>DEL-M-BUF</b> 
 +L119F:  LD      L,(IX+$1A)      ; fetch map address. 
 +        LD      H,(IX+$1B)      ; from CHMAP. 
 +        PUSH    HL              ; and save. 
 +        LD      A,(IX+$19)      ; fetch drive number from CHDRIV. 
 +        PUSH    AF              ; and save also. 
 + 
 +        PUSH    IX              ; transfer channel base address 
 +        POP     HL              ; to the HL register pair. 
 + 
 +        LD      BC,$0253        ; set BC to bytes to reclaim. 
 + 
 +        RST     10H             ; CALBAS 
 +        DEFW    $19E8           ; main RECLAIM-2 reclaims the channel. 
 + 
 +        PUSH    IX              ; transfer channel 
 +        POP     HL              ; base address again. 
 + 
 +        LD      DE,($5C4F)      ; set DE to start of channels from CHANS 
 +        OR      A               ; clear carry. 
 +        SBC     HL,DE           ; subtract to form the offset. 
 +        INC     HL              ; add 1 as points to second byte. 
 + 
 +        LD      BC,$0253        ; set the number of bytes reclaimed. 
 + 
 +        CALL    <A href="#L1444">L1444</a>           ; routine REST-STRM corrects all stream offsets 
 +                                ; in the standard systems variables area 
 +                                ; reducing them if they followed the deleted 
 +                                ; channel. 
 + 
 +        POP     AF              ; restore drive number 
 +        POP     HL              ; and old map address. 
 + 
 +; now consider deleting the map if it was used only by the reclaimed channel. 
 + 
 +        LD      B,A             ; transfer drive to B 
 +        LD      IX,($5C4F)      ; set IX from CHANS 
 +        LD      DE,$0014        ; prepare to step over the twenty standard bytes 
 +        ADD     IX,DE           ; to address next channel or end-marker. 
 + 
 +<a name="L11D0"></a>;; <b>TEST-MCHL</b> 
 +L11D0:  LD      A,(IX+$00)      ; fetch current byte. 
 +        CP      $80             ; compare to end-marker. 
 +        JR      Z,<A href="#L11EF">L11EF</a>         ; forward, with match, to RCLM-MAP 
 + 
 +        LD      A,(IX+$04)      ; fetch the channel letter. 
 +        AND     $7F             ; cancel any inverted bit. 
 +        CP      $4D             ; is character "M"
 +        JR      NZ,<A href="#L11E5">L11E5</a>        ; forward, if not, to NXTCHAN 
 + 
 +        LD      A,(IX+$19)      ; fetch this channel drive number. 
 +        CP      B               ; compare to that of deleted channel. 
 +        RET                   ; return with match - the microdrive map is 
 +                                ; still in use.                              &gt;&gt; 
 + 
 +; else continue search. 
 + 
 +<a name="L11E5"></a>;; <b>NXTCHAN</b> 
 +L11E5:  LD      E,(IX+$09)      ; fetch length of channel 
 +        LD      D,(IX+$0A)      ; to DE register. 
 +        ADD     IX,DE           ; add to address next channel. 
 +        JR      <A href="#L11D0">L11D0</a>           ; loop back to TEST-MCHL 
 + 
 +; --- 
 + 
 +; the branch was here when the end-marker was encountered without finding a 
 +; channel that uses the map. 
 + 
 +<a name="L11EF"></a>;; <b>RCLM-MAP</b> 
 +L11EF:  LD      BC,$0020        ; thirty two bytes to reclaim. 
 +        PUSH    HL              ; save pointer to start. 
 +        PUSH    BC              ; save the 32 bytes. 
 + 
 +        RST     10H             ; CALBAS 
 +        DEFW    $19E8           ; main RECLAIM-2 reclaims the microdrive map. 
 + 
 +        POP     BC              ; restore 32 counter. 
 +        POP     HL              ; restore map address. 
 + 
 +        CALL    <A href="#L1476">L1476</a>           ; routine REST-MAP adjusts all channel map 
 +                                ; addresses. 
 + 
 +        RET                     ; return. 
 + 
 +; ------------------------------- 
 +; THE <b><font color=#333388>'"M" CHANNEL INPUT'</font></b> ROUTINE 
 +; ------------------------------- 
 +
 + 
 +<a name="L11FD"></a>;; <b>M-INPUT</b> 
 +L11FD:  LD      IX,($5C51)      ; sv CURCHL 
 +        LD      HL,<A href="#L1207">L1207</a>        ; addr: MCHAN-IN 
 +        JP      <A href="#L0D5A">L0D5A</a>           ; jump to CALL-INP 
 + 
 +; --------------------------------------- 
 +; THE <b><font color=#333388>'"M" CHANNEL INPUT SERVICE'</font></b> ROUTINE 
 +; --------------------------------------- 
 +
 + 
 +<a name="L1207"></a>;; <b>MCHAN-IN</b> 
 +L1207:  BIT     0,(IX+$18)      ; test CHFLAG 
 +        JR      Z,<A href="#L120F">L120F</a>         ; forward, if reset, to TEST-M-BF 
 + 
 +<a name="L120D"></a>;; <b>rwf-err</b> 
 +L120D:  RST     20H             ; Shadow Error Restart 
 +        DEFB    $0D             ; Reading a 'write' file 
 + 
 +; --- 
 + 
 +<a name="L120F"></a>;; <b>TEST-M-BF</b> 
 +L120F:  LD      E,(IX+$0B)      ; load DE with the offset from CHDATA of the 
 +        LD      D,(IX+$0C)      ; next byte to be received from CHBYTE. 
 + 
 +        LD      L,(IX+$45)      ; load HL with the number of data bytes 
 +        LD      H,(IX+$46)      ; in CHDATA from RECLEN. 
 + 
 +        SCF                     ; set carry to include 
 +        SBC     HL,DE           ; subtract the two relative positions. 
 +        JR      C,<A href="#L1233">L1233</a>         ; forward to CHK-M-EOF 
 + 
 +        INC     DE              ; else increment pointer. 
 +        LD      (IX+$0B),     ; store back 
 +        LD      (IX+$0C),     ; in CHBYTE. 
 +        DEC     DE              ; decrement pointer. 
 + 
 +        PUSH    IX              ; save start of channel. 
 +        ADD     IX,DE           ; add the offset within CHDATA first. 
 +        LD      A,(IX+$52)      ; now apply offset of CHDATA from start of 
 +                                ; channel to character. 
 +        POP     IX              ; restore channel start. 
 +        SCF                     ; set carry flag. 
 +        RET                     ; return. 
 + 
 +; --- 
 + 
 +<a name="L1233"></a>;; <b>CHK-M-EOF</b> 
 +L1233:  BIT     1,(IX+$43)      ; bit 1 of RECFLG is set if this is the last 
 +                                ; record in this file. 
 +        JR      Z,<A href="#L123D">L123D</a>         ; forward, if not EOF, to NEW-BUFF. 
 + 
 +        XOR                   ; set accumulator to zero. 
 +        ADD     A,$0D           ; add to carriage return clearing the 
 +                                ; carry flag and resetting the zero flag. 
 +        RET                     ; return. 
 + 
 +; --- 
 + 
 +<a name="L123D"></a>;; <b>NEW-BUFF</b> 
 +L123D:  LD      DE,$0000        ; set next byte offset to zero. 
 +        LD      (IX+$0B),     ; and update the 
 +        LD      (IX+$0C),     ; pointer CHBYTE. 
 + 
 +        INC     (IX+$0D)        ; increment record number CHREC. 
 +        CALL    <A href="#L1252">L1252</a>           ; routine GET-RECD gets the record specified 
 +                                ; by CHREQ matching filename CHNAME from the  
 +                                ; cartridge in the drive CHDRIV which is  
 +                                ; started. 
 + 
 +        XOR                   ; signal stop all motors. 
 +        CALL    <A href="#L1532">L1532</a>           ; routine SEL-DRIVE. 
 + 
 +        JR      <A href="#L120F">L120F</a>           ; back to TEST-M-BF. 
 + 
 +; -------------------------- 
 +; THE <b><font color=#333388>'GET A RECORD'</font></b> ROUTINE 
 +; -------------------------- 
 +;   This routine is used to read a specific record from a PRINT type file. 
 +;   It is called twice - 
 +;   1) From the "M" input routine when the current record is exhausted and the  
 +;      next record is to be read in. 
 +;   2) From Hook Code $27 READ-RANDOM. 
 + 
 +<a name="L1252"></a>;; <b>GET-RECD</b> 
 +L1252:  LD      A,(IX+$19)      ; get drive number from CHDRIV. 
 +        CALL    <A href="#L1532">L1532</a>           ; routine SEL-DRIVE starts the motor. 
 + 
 +; -&gt; 
 + 
 +<a name="L1258"></a>;; <b>GET-R-2</b> 
 +L1258:  LD      BC,$04FB        ; set sector counter to 1275 = 255*5 
 +        LD      ($5CC9),BC      ; update system variable SECTOR 
 + 
 +<a name="L125F"></a>;; <b>GET-R-LP</b> 
 +L125F:  CALL    <A href="#L1280">L1280</a>           ; routine G-HD-RC reads in the next header and 
 +                                ; matching record to pass the tape head. 
 + 
 +        JR      C,<A href="#L1279">L1279</a>         ; forward, with name mismatch, to NXT-SCT 
 + 
 +        JR      Z,<A href="#L1279">L1279</a>         ; forward, if not in use, to NXT-SCT 
 + 
 +        LD      A,(IX+$44)      ; fetch the record number 0-n from RECNUM 
 +        CP      (IX+$0D)        ; compare with that required in CHREC 
 +        JR      NZ,<A href="#L1279">L1279</a>        ; forward, if no number match, to NXT-SCT 
 + 
 +        PUSH    IX              ; transfer address of Microdrive channel 
 +        POP     HL              ; from the IX to HL registers. 
 + 
 +        LD      DE,$0052        ; offset to CHDATA 
 +        ADD     HL,DE           ; add to form address of start of 512 byte data 
 +        CALL    <A href="#L142B">L142B</a>           ; routine CHKS-BUFF 
 +        RET                   ; return if checksums match. 
 + 
 + 
 +<a name="L1279"></a>;; <b>NXT-SCT</b> 
 +L1279:  CALL    <A href="#L13F7">L13F7</a>           ; routine DEC-SECT 
 +        JR      NZ,<A href="#L125F">L125F</a>        ; loop back, if not zero, to GET-R-LP 
 + 
 +; else produce the Error Report. 
 + 
 +        RST     20H             ; Shadow Error Restart 
 +        DEFB    $11             ; File not found 
 + 
 + 
 +; --------------------------------------- 
 +; THE <b><font color=#333388>'GET HEADER AND DATA BLOCK'</font></b> ROUTINE 
 +; --------------------------------------- 
 +; This routine fetches at random a header and matching record and sets the 
 +; flags to indicate three possible outcomes. 
 +;  
 +; Zero flag set - record is not in use. 
 +; Carry flag set - name does not match required 
 +; Both flags reset - the name matches required. 
 + 
 +<a name="L1280"></a>;; <b>G-HD-RC</b> 
 +L1280:  CALL    <A href="#L13A9">L13A9</a>           ; routine GET-M-HD2 reads in and checksums 
 +                                ; the next 14 byte header to pass tape heads. 
 + 
 +        LD      DE,$001B        ; prepare the offset from header to RECFLG and 
 +        ADD     HL,DE           ; add to address the start of 528 byte RECORD 
 + 
 +        CALL    <A href="#L15EB">L15EB</a>           ; routine GET-M-BUF reads in the record  
 +                                ; descriptor and data. 
 +                                ; register HL addresses RECFLG 
 + 
 +        CALL    <A href="#L1426">L1426</a>           ; routine CHKS-HD-R checksums the 14 bytes 
 +                                ; of the record descriptor. 
 + 
 +        JR      NZ,<A href="#L12B1">L12B1</a>        ; forward, with error, to G-REC-ERR 
 + 
 +        BIT     0,(IX+$43)      ; check RECFLG - should be reset. 
 +        JR      NZ,<A href="#L12B1">L12B1</a>        ; forward, if not, to G-REC-ERR 
 + 
 +; now test descriptor for an unused record. 
 + 
 +        LD      A,(IX+$43)      ; load A with RECFLG - bit 1 indicates EOF 
 +        OR      (IX+$46)        ; combine with RECLEN_hi bit 1 set if full. 
 +        AND     $02             ; test for either full record or EOF. 
 +        RET                   ; return if not with zero set and carry reset 
 +                                ; signaling that record is unused. 
 + 
 +; the record is a contender for a header record. 
 + 
 +        PUSH    IX              ; transfer start of channel 
 +        POP     HL              ; to the HL register pair. 
 + 
 +        LD      DE,$0047        ; offset to 10 characters of filename. 
 +        ADD     HL,DE           ; add so HL addresses the start of RECNAM. 
 +        LD      BC,$000A        ; ten bytes to compare against required CHNAME. 
 + 
 +        CALL    <A href="#L1403">L1403</a>           ; routine CHK-NAME 
 + 
 +        JR      NZ,<A href="#L12B1">L12B1</a>        ; forward, with name mismatch, to G-REC-ERR 
 + 
 +; else set flags to signal success before returning. 
 + 
 +        LD      A,$FF           ; prepare to reset zero flag 
 +        OR      A               ; also reset carry 
 +        RET                     ; return with zero reset and carry reset. 
 + 
 +; --- 
 + 
 +; else set carry to signal names do not match. 
 + 
 +<a name="L12B1"></a>;; <b>G-REC-ERR</b> 
 +L12B1:  SCF                     ; set carry flag to signal failure and  
 +                                ; instigate another search. 
 +        RET                     ; return with zero reset and carry set. 
 + 
 + 
 +; -------------------------------- 
 +; THE <b><font color=#333388>'"M" CHANNEL OUTPUT'</font></b> ROUTINE 
 +; -------------------------------- 
 +; labeled MWRCH in source code. 
 + 
 +<a name="L12B3"></a>;; <b>MCHAN-OUT</b> 
 +L12B3:  LD      IX,$FFFA 
 +        ADD     IX,DE 
 +        BIT     0,(IX+$18)      ; ???? CHFLAG 
 +        JR      NZ,<A href="#L12C1">L12C1</a>        ; forward to NOREAD 
 + 
 +        RST     20H             ; Shadow Error Restart 
 +        DEFB    $0C             ; Writing to a 'read' file 
 + 
 +<a name="L12C1"></a>;; <b>NOREAD</b> 
 +L12C1:  LD      E,(IX+$0B)      ; CHBYTE 
 + 
 + 
 +        LD      D,(IX+$0C)      ; CHBYTE_hi 
 +        PUSH    IX 
 +        ADD     IX,DE 
 +        LD      (IX+$52),     ; indexed 
 +        POP     IX 
 +        INC     DE 
 +        LD      (IX+$0B),     ; CHBYTE 
 +        LD      (IX+$0C),     ; CHBYTE_hi 
 +        BIT     1,            ; is CHBYTE the maximum $0200 ? 
 +        RET                   ; return if not. 
 + 
 + 
 +; ------------------------------------------ 
 +; THE <b><font color=#333388>'WRITE RECORD ONTO MICRODRIVE'</font></b> ROUTINE 
 +; ------------------------------------------ 
 +; <font color=#339933>(Hook Code: $26)</font> 
 +
 + 
 +<a name="L12DA"></a>;; <b>WR-RECD</b> 
 +L12DA:  LD      A,(IX+$19)      ; fetch drive number. 
 +        CALL    <A href="#L1532">L1532</a>           ; routine SEL-DRIVE 
 + 
 +        LD      BC,$32C8        ; set BC to 13000 decimal 
 +        CALL    <A href="#L1652">L1652</a>           ; routine DELAY-BC 
 + 
 +        CALL    <A href="#L12EE">L12EE</a>           ; routine WRITE-PRC 
 + 
 +        XOR                   ; signal stop motor 
 +        CALL    <A href="#L1532">L1532</a>           ; routine SEL-DRIVE 
 + 
 +        RET                     ; return. 
 + 
 +; ----------------------------- 
 +; THE <b><font color=#333388>'WRITE RECORD'</font></b> SUBROUTINE 
 +; ----------------------------- 
 +
 +
 + 
 +<a name="L12EE"></a>;; <b>WRITE-PRC</b> 
 +L12EE:  CALL    <A href="#L1349">L1349</a>           ; routine CHK-FULL. 
 + 
 +        JR      NZ,<A href="#L12FC">L12FC</a>        ; forward, if not, to NOFULL. 
 + 
 +        CALL    <A href="#L119F">L119F</a>           ; routine DEL-M-BUF reclaims the buffer. 
 + 
 +        XOR                   ; set accumulator to zero. 
 +        CALL    <A href="#L1532">L1532</a>           ; routine SEL-DRIVE stops the motor. 
 + 
 +        RST     20H             ; Shadow Error Restart. 
 +        DEFB    $0F             ; 'Microdrive full' 
 + 
 +; --- 
 + 
 +<a name="L12FC"></a>;; <b>NOFULL</b> 
 +L12FC:  PUSH    IX              ; save the pointer to channel base. 
 +        LD      B,$0A           ; count ten characters. 
 + 
 +<a name="L1300"></a>;; <b>CP-NAME</b> 
 +L1300:  LD      A,(IX+$0E)      ; copy a character of CHNAME 
 +        LD      (IX+$47),     ; to RECNAM 
 +        INC     IX              ; increment the index pointer. 
 +        DJNZ    <A href="#L1300">L1300</a>           ; loop back for all ten characters to CP-NAME 
 + 
 +        POP     IX              ; restore base of "M" channel. 
 + 
 +        LD      C,(IX+$0B)      ; fetch  CHBYTE_lo 
 +        LD      (IX+$45),     ; update RECLEN_lo 
 + 
 +        LD      A,(IX+$0C)      ; fetch  CHBYTE_hi 
 +        LD      (IX+$46),     ; update RECLEN_hi 
 + 
 +        LD      A,(IX+$0D)      ; fetch  CHREC 
 +        LD      (IX+$44),     ; update RECNUM 
 + 
 +        RES     0,(IX+$43)      ; reset RECFLG indicating a record. 
 + 
 +        PUSH    IX              ; transfer channel base address  
 +        POP     HL              ; to the HL register. 
 + 
 +        LD      DE,$0043        ; prepare offset to point to RECFLG 
 +        ADD     HL,DE           ; and add to address the record descriptor. 
 + 
 +        CALL    <A href="#L1426">L1426</a>           ; routine CHKS-HD-R checksums the 14 bytes. 
 + 
 +        LD      DE,$000F        ; add extra offset to CHDATA 
 +        ADD     HL,DE           ; the 512 bytes of data. 
 + 
 +        CALL    <A href="#L142B">L142B</a>           ; routine CHKS-BUFF checksums the buffer. 
 + 
 +        PUSH    IX              ; <font color=#9900FF>Note.</font> this code is redundant and erroneous. 
 +        POP     HL              ; the three registers are set up properly 
 +        LD      DE,$0047        ; in the next routine. 
 + 
 +        CALL    <A href="#L135A">L135A</a>           ; routine SEND-BLK writes block to microdrive 
 +                                ; cartridge as indicated my microdrive map  
 +                                ; which is updated. 
 + 
 +; now prepare channel for next record. accumulator could be used to set CHBYTE. 
 + 
 +        LD      DE,$0000        ; set DE to zero. 
 +        LD      (IX+$0B),     ; set CHBYTE_lo to zero 
 +        LD      (IX+$0C),     ; set CHBYTE_hi to zero 
 +        INC     (IX+$0D)        ; increment the record counter CHREC 
 + 
 +        RET                     ; return. 
 + 
 + 
 +; ---------------------- 
 +; THE <b><font color=#333388>'CHK-FULL'</font></b> ROUTINE 
 +; ---------------------- 
 +; Check the thirty two bytes of a microdrive map for a reset bit. 
 + 
 +<a name="L1349"></a>;; <b>CHK-FULL</b> 
 +L1349:  LD      L,(IX+$1A)      ; load the address of the microdrive map 
 +        LD      H,(IX+$1B)      ; from CHMAP to HL. 
 +        LD      B,$20           ; set counter to thirty two. 
 + 
 +<a name="L1351"></a>;; <b>NXT-B-MAP</b> 
 +L1351:  LD      A,(HL)          ; fetch each byte in turn. 
 +        CP      $FF             ; compare to the all-full indicator. 
 +        RET     NZ              ; return if there is a spare sector       &gt;&gt; 
 + 
 +        INC     HL              ; next address. 
 +        DJNZ    <A href="#L1351">L1351</a>           ; loop back to NXT-B-MAP 
 + 
 +        XOR                   ; set the zero flag for failure. 
 +        RET                     ; return. 
 + 
 + 
 +; ---------------------- 
 +; THE <b><font color=#333388>'SEND-BLK'</font></b> ROUTINE 
 +; ---------------------- 
 +;   This important routine is called from the FORMAT routine and the WRITE-PRC 
 +;   routine to write the record to the cartridge at the next available free 
 +;   sector as indicated by the microdrive map.  
 + 
 +<a name="L135A"></a>;; <b>SEND-BLK</b> 
 +L135A:  PUSH    IX              ; transfer the channel 
 +        POP     HL              ; address to HL. 
 + 
 +        LD      DE,$0037        ; offset to data preamble. 
 +        ADD     HL,DE           ; add to address using HL 
 +        PUSH    HL              ; save pointer to data block 
 + 
 +; now enter a loop to find the header of an available record on microdrive. 
 +; This SEND-BLK routine is only called when there is known to be a record 
 +; available on the tape. 
 + 
 +<a name="L1362"></a>;; <b>FAILED</b> 
 +L1362:  CALL    <A href="#L13A9">L13A9</a>           ; routine GET-M-HD2 gets any old header. 
 +        CALL    <A href="#L13C4">L13C4</a>           ; routine CHECK-MAP checks if sector is free  
 +                                ; on the microdrive map. 
 +        JR      NZ,<A href="#L1362">L1362</a>        ; back, if not, to FAILED. 
 + 
 +; A usable sector has been found on the drive. HL addresses byte within map. 
 + 
 +        EX      (SP),HL         ; map address to stack, bring back data pointer. 
 +        PUSH    BC              ; preserve B the map byte mask. 
 + 
 +        IN      A,($EF)         ; test the drive. 
 +        AND     $01             ; examine 'write protect' bit. 
 +        JR      NZ,<A href="#L1374">L1374</a>        ; forward, if not protected, to NO-PRT. 
 + 
 +        RST     20H             ; Shadow Error Restart. 
 +        DEFB    $0E             ; Drive 'write' protected 
 + 
 +<a name="L1374"></a>;; <b>NO-PRT</b> 
 +L1374:  LD      A,$E6           ;      xx100110 
 +        OUT     ($EF),        ; enable writing. 
 + 
 +        LD      BC,$0168        ; a delay value of 360 decimal. 
 +        CALL    <A href="#L1652">L1652</a>           ; routine DELAY-BC pauses briefly as the  
 +                                ; record now approaches the tape heads. 
 + 
 +        CALL    <A href="#L15B3">L15B3</a>           ; routine OUT-M-BUF writes descriptor and 
 +                                ; data buffer. 
 + 
 +        LD      A,$EE           ;       xx101110 
 +        OUT     ($EF),        ; disable writing. 
 + 
 +        POP     BC              ; restore the map bit. 
 +        POP     HL              ; and the address of the byte within microdrive 
 +                                ; map. 
 +        LD      A,B             ; transfer masked bit to A. 
 +        OR      (HL)            ; combine with status of other 7 sectors. 
 +        LD      (HL),         ; update the map to show this sector is now  
 +                                ; used. 
 + 
 +        RET                     ; return. 
 + 
 + 
 +; ------------------------ 
 +; THE <b><font color=#333388>'CLOSE FILE'</font></b> ROUTINE 
 +; ------------------------ 
 +; <font color=#9900FF>Note.</font> The first entry point is not used. 
 + 
 +<a name="L138B"></a>;; <b>close-m</b> 
 +L138B:  PUSH    HL              ; 
 +        POP     IX              ; 
 + 
 +; <font color=#339933>(Hook Code: $23)</font> 
 + 
 +<a name="L138E"></a>;; <b>CLOSE-M2</b> 
 +L138E:  BIT     0,(IX+$18)      ; CHFLAG 
 +        JR      Z,<A href="#L139B">L139B</a>         ; forward to NOEMP 
 + 
 +        SET     1,(IX+$43)      ; RECFLG 
 +        CALL    <A href="#L12DA">L12DA</a>           ; routine WR-RECD 
 + 
 +<a name="L139B"></a>;; <b>NOEMP</b> 
 +L139B:  XOR                   ; 
 +        CALL    <A href="#L1532">L1532</a>           ; routine SEL-DRIVE 
 +        CALL    <A href="#L119F">L119F</a>           ; routine DEL-M-BUF 
 +        RET                     ; return after subroutine. 
 + 
 +; ------------------------------------------ 
 +; THE <b><font color=#333388>'MAIN ERROR RESTART EMULATION'</font></b> ROUTINE 
 +; ------------------------------------------ 
 + 
 +<a name="L13A3"></a>;; <b>ERR-RS</b> 
 +L13A3:  POP     HL              ; 
 +        LD      A,(HL)          ; 
 +        LD      ($5C3A),      ; sv ERR_NR 
 +        RST     28H             ; Error Main ROM 
 + 
 +; ------------------------------------------ 
 +; THE <b><font color=#333388>'FETCH HEADER FROM MICRODRIVE'</font></b> ROUTINE 
 +; ------------------------------------------ 
 +;   This routine fetches the next valid 14-byte header to pass the tape heads  
 +;   ensuring that it is a header as opposed to a record descriptor. 
 + 
 +<a name="L13A9"></a>;; <b>GET-M-HD2</b> 
 +L13A9:  PUSH    IX              ; transfer start of channel 
 +        POP     HL              ; to the HL register pair. 
 + 
 +        LD      DE,$0028        ; offset to HDFLAG 
 +        ADD     HL,DE           ; add to form first receiving location. 
 + 
 +        CALL    <A href="#L15E2">L15E2</a>           ; routine GET-M-HD reads 15 bytes from 
 +                                ; microdrive - last is a checksum byte. 
 + 
 +        CALL    <A href="#L1426">L1426</a>           ; routine CHKS-HD-R checksums the bytes. 
 + 
 +        JR      NZ,<A href="#L13A9">L13A9</a>        ; back, with error, to GET-M-HD2 
 + 
 +        BIT     0,(IX+$28)      ; test HDFLAG should be set. 
 +        JR      Z,<A href="#L13A9">L13A9</a>         ; back, if not a header, to GET-M-HD2 
 + 
 +        RET                     ; return - with HL addressing start of header. 
 + 
 + 
 +; --------------------------------- 
 +; THE <b><font color=#333388>'CHECK MAP BIT STATE'</font></b> ROUTINE 
 +; --------------------------------- 
 +
 + 
 +<a name="L13BF"></a>;; <b>CHK-MAP-2</b> 
 +L13BF:  LD      E,(IX+$44)      ; pick up record from RECNUM 
 +        JR      <A href="#L13C7">L13C7</a>           ; forward to ENTRY 
 + 
 +; --- 
 + 
 +<a name="L13C4"></a>;; <b>CHECK-MAP</b> 
 +L13C4:  LD      E,(IX+$29)      ; pick up sector from HDNUMB 
 + 
 +; -&gt; 
 + 
 +<a name="L13C7"></a>;; <b>ENTRY</b> 
 +L13C7:  LD      L,(IX+$1A)      ; fetch address of associated 
 +        LD      H,(IX+$1B)      ; microdrive map from CHMAP 
 + 
 +; the pseudo-map routine enters here with a temporary map address. 
 + 
 +<a name="L13CD"></a>;; <b>ENTRY-2</b> 
 +L13CD:  XOR                   ; clear accumulator is one way to 
 +        LD      D,A             ; clear D in preparation for addition. 
 +        LD      A,E             ; transfer sector to A. 
 +        AND     $07             ; and mask off lower 8 bits for later 
 + 
 +        SRL                   ; returning to E, 
 +        SRL                   ; divide the 
 +        SRL                   ; sector or record by eight. 
 +        ADD     HL,DE           ; add to map base to give address of map bit. 
 +        LD      B,A             ; now load sector mod 8 to B and 
 +        INC                   ; increment to form counter 1 - 8. 
 + 
 +        XOR                   ; clear A 
 +        SCF                     ; and set carry bit ready to rotate in. 
 + 
 +<a name="L13DD"></a>;; <b>ROTATE</b> 
 +L13DD:  RLA                     ; rotate left A 
 +        DJNZ    <A href="#L13DD">L13DD</a>           ; back, while counter not zero, to ROTATE 
 + 
 +        LD      B,A             ; return sector bit in B. 
 +        AND     (HL)            ; AND accumulator with map sector byte. 
 +        RET                     ; return - Z = free, NZ = occupied. 
 + 
 + 
 +; ----------------------------------- 
 +; THE <b><font color=#333388>'RESET BIT IN MAP AREA'</font></b> ROUTINE 
 +; ----------------------------------- 
 +;   This routine is called when opening a channel and by FORMAT, CAT and ERASE 
 +;   to mark a map bit representing a sector as available. 
 + 
 +<a name="L13E3"></a>;; <b>RES-B-MAP</b> 
 +L13E3:  CALL    <A href="#L13C4">L13C4</a>           ; routine CHECK-MAP fetches bit mask for map 
 +                                ; location addressed by HL into B register. 
 + 
 +        LD      A,B             ; fetch sector mask with one bit set. 
 +        CPL                     ; complement - seven bits set and one bit reset. 
 +        AND     (HL)            ; combine with other sector bits. 
 +        LD      (HL),         ; and update map byte resetting the bit. 
 +        RET                     ; return. 
 + 
 + 
 +; ------------------------------------------ 
 +; THE <b><font color=#333388>'CHECK '</font></b>PSEUDO-MAP' BIT STATE' ROUTINE 
 +; ------------------------------------------ 
 +
 + 
 +<a name="L13EB"></a>;; <b>TEST-PMAP</b> 
 +L13EB:  PUSH    IX              ; 
 +        POP     HL              ; 
 + 
 +        LD      DE,$0052        ; 
 +        ADD     HL,DE           ; 
 +        LD      E,(IX+$29)      ; HDNUMB 
 +        JR      <A href="#L13CD">L13CD</a>           ; back to ENTRY-2 
 + 
 + 
 +; ------------------------------------- 
 +; THE <b><font color=#333388>'DECREASE SECTOR COUNTER'</font></b> ROUTINE 
 +; ------------------------------------- 
 +
 + 
 +<a name="L13F7"></a>;; <b>DEC-SECT</b> 
 +L13F7:  LD      BC,($5CC9)      ; sv SECTOR 
 +        DEC     BC              ; 
 +        LD      ($5CC9),BC      ; sv SECTOR 
 +        LD      A,B             ; 
 +        OR      C               ; 
 +        RET                     ; 
 + 
 + 
 +; ------------------------ 
 +; THE <b><font color=#333388>'CHECK-NAME'</font></b> ROUTINE 
 +; ------------------------ 
 +
 + 
 +<a name="L1403"></a>;; <b>CHK-NAME</b> 
 +L1403:  PUSH    IX              ; preserve original channel base address. 
 + 
 +        LD      B,$0A           ; 
 + 
 +<a name="L1407"></a>;; <b>ALL-CHARS</b> 
 +L1407:  LD      A,(HL)          ; 
 +        CP      (IX+$0E)        ; CHNAME 
 +        JR      NZ,<A href="#L1423">L1423</a>        ; forward to CKNAM-END 
 + 
 +        INC     HL              ; 
 +        INC     IX              ; 
 +        DEC                   ; 
 +        DEC                   ; 
 +        JR      NZ,<A href="#L1407">L1407</a>        ; back to ALL-CHARS 
 + 
 +        LD      A,B             ; 
 +        OR      A               ; 
 +        JR      Z,<A href="#L1423">L1423</a>         ; forward to CKNAM-END 
 + 
 + 
 +<a name="L1418"></a>;; <b>ALLCHR-2</b> 
 +L1418:  LD      A,(IX+$0E)      ; CHNAME 
 +        CP      $20             ; 
 +        JR      NZ,<A href="#L1423">L1423</a>        ; forward to CKNAM-END 
 + 
 +        INC     IX              ; 
 +        DJNZ    <A href="#L1418">L1418</a>           ; back to ALLCHR-2 
 + 
 + 
 +<a name="L1423"></a>;; <b>CKNAM-END</b> 
 +L1423:  POP     IX              ; 
 +        RET                     ; 
 + 
 + 
 +; ----------------------------------------- 
 +; THE <b><font color=#333388>'CALCULATE/COMPARE CHECKSUMS'</font></b> ROUTINE 
 +; ----------------------------------------- 
 +; Used for microdrive channels only. 
 +; While the two checksums within a Network buffer are simple 8-bit sums of 
 +; the data, the algorithm used for the microdrive channels is a little more 
 +; sophisticated as it avoids the formation of the result $FF. While across the 
 +; network a byte is as good as its neighbour, with microdrives the value $FF 
 +; might arise as a result of a failed read. 
 +; The same routine is used both to prepare the checksum prior to saving and to 
 +; calculate and compare the checksum after reading. 
 +; The first entry point is used for the 14 bytes of HDCHK and DESCHK 
 +; and the second entry point is used for the 512 bytes of DCHK. 
 + 
 +<a name="L1426"></a>;; <b>CHKS-HD-R</b> 
 +L1426:  LD      BC,$000E        ; fourteen bytes 
 +        JR      <A href="#L142E">L142E</a>           ; forward to CHKS-ALL 
 + 
 +; --- 
 +; -&gt; 
 + 
 +<a name="L142B"></a>;; <b>CHKS-BUFF</b> 
 +L142B:  LD      BC,$0200        ; 512 bytes. 
 + 
 +; common code. 
 + 
 +<a name="L142E"></a>;; <b>CHKS-ALL</b> 
 +L142E:  PUSH    HL              ; save pointer to first address. 
 +        LD      E,$00           ; initialize checksum to zero 
 + 
 +<a name="L1431"></a>;; <b>NXT-BYTE</b> 
 +L1431:  LD      A,E             ; fetch running sum 
 +        ADD     A,(HL)          ; add to current location. 
 +        INC     HL              ; point to next location. 
 + 
 + 
 +        ADC     A,$01           ; avoid the value $FF. 
 +        JR      Z,<A href="#L1439">L1439</a>         ; forward to STCHK 
 + 
 +        DEC                   ; decrement. 
 + 
 +<a name="L1439"></a>;; <b>STCHK</b> 
 +L1439:  LD      E,A             ; update the 8-bit sum. 
 + 
 +        DEC     BC              ; reduce counter 
 +        LD      A,B             ; and check 
 +        OR      C               ; for zero. 
 +        JR      NZ,<A href="#L1431">L1431</a>        ; back, if not, to NXT-BYTE 
 + 
 +        LD      A,E             ; fetch running sum 
 +        CP      (HL)            ; compare to checksum contents 
 +        LD      (HL),         ; before inserting the byte. 
 + 
 +        POP     HL              ; restore pointer to first address. 
 +        RET                     ; return - with zero flag set if sums agree. 
 + 
 + 
 +; --------------------------------- 
 +; THE <b><font color=#333388>'RESTORE STREAM DATA'</font></b> ROUTINE 
 +; --------------------------------- 
 +; When a channel is deleted, then the streams that point to channels beyond 
 +; that one have to have their offsets reduced by the deleted amount. 
 +; Also a stream that exactly matches the offset to the deleted channel, and 
 +; there could be several, will have its entry set to zero. 
 +; On entry, HL = offset, BC = $0253 
 + 
 +<a name="L1444"></a>;; <b>REST-STRM</b> 
 +L1444:  PUSH    HL              ; save the offset 
 +        LD      A,$10           ; maximum streams + 1 
 +        LD      HL,$5C16        ; the start of the user streams area STRMS_00 
 + 
 +<a name="L144A"></a>;; <b>NXT-STRM</b> 
 +L144A:  LD      ($5C5F),HL      ; save stream pointer temporarily in X_PTR 
 + 
 +        LD      E,(HL)          ; fetch low byte of offset. 
 +        INC     HL              ; bump address. 
 +        LD      D,(HL)          ; fetch high byte of streams offset. 
 + 
 +        POP     HL              ; retrieve the 
 +        PUSH    HL              ; supplied offset. 
 + 
 +        OR      A               ; clear carry. 
 +        SBC     HL,DE           ; subtract looking for an exact match 
 +        JR      NZ,<A href="#L145C">L145C</a>        ; forward, if not, to NOTRIGHT 
 + 
 +        LD      DE,$0000        ; else set displacement to zero. 
 +        JR      <A href="#L1463">L1463</a>           ; forward to STO-DISP to close the stream. 
 + 
 +; --- 
 + 
 +<a name="L145C"></a>;; <b>NOTRIGHT</b> 
 +L145C:  JR      NC,<A href="#L1469">L1469</a>        ; forward, if entry lower, to UPD-POINT -&gt; 
 + 
 +; else this stream entry is to be reduced by $0253 bytes. 
 + 
 +        EX      DE,HL           ; streams offset to HL 
 +        OR      A               ; clear carry 
 +        SBC     HL,BC           ; reduce by 595 decimal bytes 
 +        EX      DE,HL           ; transfer reduced entry to DE. 
 + 
 +<a name="L1463"></a>;; <b>STO-DISP</b> 
 +L1463:  LD      HL,($5C5F)      ; fetch stream address from X_PTR 
 +        LD      (HL),         ; and insert 
 +        INC     HL              ; the updated 
 +        LD      (HL),         ; offset. 
 + 
 +; -&gt; 
 + 
 +<a name="L1469"></a>;; <b>UPD-POINT</b> 
 +L1469:  LD      HL,($5C5F)      ; fetch stream address from X_PTR. 
 +        INC     HL              ; bump - each stream entry 
 +        INC     HL              ; is two bytes. 
 +        DEC                   ; decrement the loop counter. 
 +        JR      NZ,<A href="#L144A">L144A</a>        ; back, if not zero, to NXT-STRM 
 + 
 +; else clean up and return. 
 + 
 +        LD      ($5C5F),      ; set X_PTR_hi to zero resting value. 
 +        POP     HL              ; balance stack. 
 +        RET                     ; return. 
 + 
 + 
 +; ----------------------------------- 
 +; THE <b><font color=#333388>'RESTORE MAP ADDRESSES'</font></b> ROUTINE 
 +; ----------------------------------- 
 +; When a microdrive map is reclaimed, then all the addresses of the microdrive 
 +; maps in the "M" channels are examined and if higher than the deleted map, the 
 +; address is reduced by thirty two bytes. 
 +; On entry, HL = map address, BC = $0020. 
 + 
 +<a name="L1476"></a>;; <b>REST-MAP</b> 
 +L1476:  LD      BC,$0020        ; set BC to thirty two. Already done. 
 +        LD      IX,($5C4F)      ; load IX from system variable CHANS. 
 +        LD      DE,$0014        ; there are 20 bytes of the standard 4 channels 
 +        ADD     IX,DE           ; add to skip these. 
 + 
 +; now enter a loop. 
 + 
 +<a name="L1482"></a>;; <b>LCHAN</b> 
 +L1482:  LD      A,(IX+$00)      ; fetch first byte. 
 +        CP      $80             ; is it the channels area end-marker ? 
 +        RET                   ; return if so - all maps adjusted.       &gt;&gt; 
 + 
 +        PUSH    HL              ; save map address. 
 +        LD      A,(IX+$04)      ; fetch channel letter. 
 +        AND     $7F             ; reset bit 7. 
 +        CP      $4D             ; compare to "M" 
 +        JR      NZ,<A href="#L14A6">L14A6</a>        ; forward, if not, to LPEND 
 + 
 +; a microdrive channel has been found so compare the address of the map. 
 + 
 +        LD      E,(IX+$1A)      ; fetch address of the microdrive 
 +        LD      D,(IX+$1B)      ; map for this channel from CHMAP. 
 +        SBC     HL,DE           ; subtract from that of deleted map. 
 +        JR      NC,<A href="#L14A6">L14A6</a>        ; forward, if is lower, to LPEND 
 + 
 +; address of this microdrive map is higher than the one deleted. 
 + 
 +        EX      DE,HL           ; transfer address to HL. 
 +        OR      A               ; clear carry. 
 +        SBC     HL,BC           ; subtract thirty two. 
 +        LD      (IX+$1A),     ; and place back 
 +        LD      (IX+$1B),     ; in CHMAP. 
 + 
 +<a name="L14A6"></a>;; <b>LPEND</b> 
 +L14A6:  POP     HL              ; restore address of deleted map. 
 +        LD      E,(IX+$09)      ; fetch length of channel 
 +        LD      D,(IX+$0A)      ; to DE. 
 +        ADD     IX,DE           ; add to address next channel. 
 +        JR      <A href="#L1482">L1482</a>           ; loop back to LCHAN. 
 + 
 +; ------------------------------ 
 +; THE <b><font color=#333388>'"M" CHANNEL DEFAULT'</font></b> DATA 
 +; ------------------------------ 
 +
 + 
 +<a name="L14B1"></a>;; <b>MCH-DAT</b> 
 +L14B1:  DEFW    $0008           ; main ERROR-1 
 +        DEFW    $0008           ; main ERROR-1 
 +        DEFB    $CD             ; inverted "M" character 
 +        DEFW    <A href="#L12B3">L12B3</a>           ; MCHAN-OUT 
 +        DEFW    <A href="#L11FD">L11FD</a>           ; M-INPUT 
 +        DEFW    $0253           ; length 
 +        DEFW    $0000           ; 
 +        DEFB    $00             ; 
 +        DEFM    "          "    ; 10 spaces 
 +        DEFB    $FF             ; CHFLAG 
 + 
 +; ------------------- 
 +; THE <b><font color=#333388>'PREAMBLE DATA'</font></b> 
 +; ------------------- 
 +;   The PREAMBLE consists of twelve distinctive bytes that are saved to a 
 +;   microdrive cartridge before the data.  They are not read back but allow  
 +;   the ULA of the microdrive to recognize the start of a saved data block. 
 + 
 +<a name="L14CA"></a>;; <b>PREAMBLE</b> 
 +L14CA:  DEFB    $00, $00, $00 
 +        DEFB    $00, $00, $00 
 +        DEFB    $00, $00, $00 
 +        DEFB    $00, $FF, $FF 
 + 
 +; ------------------------------- 
 +; THE <b><font color=#333388>'NOT-USED TOOLKIT'</font></b> ROUTINES 
 +; ------------------------------- 
 +; The following four routines are for debugging 
 +; purposes during development. 
 + 
 +; ---------------------- 
 +; THE <b><font color=#333388>'DISP-HEX'</font></b> ROUTINE 
 +; ---------------------- 
 +;   display a byte as two hex characters. 
 + 
 +<a name="L14D6"></a>;; <b>DISP-HEX</b> 
 +L14D6:  PUSH    AF              ; 
 +        RRA                     ; 
 +        RRA                     ; 
 +        RRA                     ; 
 +        RRA                     ; 
 +        CALL    <A href="#L14DF">L14DF</a>           ; routine DISP-NIB 
 +        POP     AF              ; 
 + 
 +<a name="L14DF"></a>;; <b>DISP-NIB</b> 
 +L14DF:  AND     $0F             ; 
 + 
 +        CP      $0A             ; 
 + 
 +        JR      C,<A href="#L14E7">L14E7</a>         ; forward to CONV-1 
 + 
 +        ADD     A,$07           ; 
 + 
 +<a name="L14E7"></a>;; <b>CONV-1</b> 
 +L14E7:  ADD     A,$30           ; 
 + 
 +        CALL    <A href="#L14F8">L14F8</a>           ; routine DISP-CH 
 +        RET                     ; 
 + 
 + 
 +; ----------------------- 
 +; THE <b><font color=#333388>'DISP-HEX2'</font></b> ROUTINE 
 +; ----------------------- 
 +;   display a byte in hexadecimal followed by a space 
 + 
 +<a name="L14ED"></a>;; <b>DISP-HEX2</b> 
 +L14ED:  PUSH    AF              ; 
 +        CALL    <A href="#L14D6">L14D6</a>           ; routine DISP-HEX 
 +        LD      A,$20           ; 
 +        CALL    <A href="#L14F8">L14F8</a>           ; routine DISP-CH 
 +        POP     AF              ; 
 +        RET                     ; 
 + 
 + 
 +; --------------------- 
 +; THE <b><font color=#333388>'DISP-CH'</font></b> ROUTINE 
 +; --------------------- 
 +
 + 
 +<a name="L14F8"></a>;; <b>DISP-CH</b> 
 +L14F8:  PUSH    HL              ; 
 +        PUSH    DE              ; 
 +        PUSH    BC              ; 
 +        PUSH    AF              ; 
 +        EXX                     ; 
 +        PUSH    HL              ; 
 +        PUSH    DE              ; 
 +        PUSH    BC              ; 
 +        PUSH    AF              ; 
 +        LD      HL,($5C51)      ; sv CURCHL 
 +        PUSH    HL              ; 
 +        PUSH    AF              ; 
 +        LD      A,$02           ; 
 +        RST     10H             ; CALBAS 
 +        DEFW    $1601           ; main CHAN-OPEN 
 +        POP     AF              ; 
 +        RST     10H             ; CALBAS 
 +        DEFW    $0010           ; main PRINT-A 
 + 
 + 
 +        POP     HL              ; 
 +        LD      ($5C51),HL      ; sv CURCHL 
 +        POP     AF              ; 
 +        POP     BC              ; 
 +        POP     DE              ; 
 +        POP     HL              ; 
 +        EXX                     ; 
 +        POP     AF              ; 
 +        POP     BC              ; 
 +        POP     DE              ; 
 +        POP     HL              ; 
 +        RET                     ; 
 + 
 + 
 +; ---------------------- 
 +; THE <b><font color=#333388>'HEX-LINE'</font></b> ROUTINE 
 +; ---------------------- 
 +;   The Master routine which displays ten bytes of memory, addressed by HL,  
 +;   in Hexadecimal followed by a CR.  The thirty output characters sit  
 +;   comfortably within the 32 character display of the Spectrum. 
 + 
 +<a name="L151D"></a>;; <b>HEX-LINE</b> 
 +L151D:  PUSH    HL              ; 
 +        PUSH    BC              ; 
 +        PUSH    AF              ; 
 +        LD      B,$0A           ; 
 + 
 +<a name="L1522"></a>;; <b>HEX-LINE2</b> 
 +L1522:  LD      A,(HL)          ; 
 +        CALL    <A href="#L14ED">L14ED</a>           ; routine DISP-HEX2 
 +        INC     HL              ; 
 +        DJNZ    <A href="#L1522">L1522</a>           ; back to HEX-LINE2 
 + 
 +        LD      A,$0D           ; 
 +        CALL    <A href="#L14F8">L14F8</a>           ; routine DISP-CH 
 +        POP     AF              ; 
 +        POP     BC              ; 
 +        POP     HL              ; 
 +        RET                     ; return. 
 + 
 + 
 +; -------------------------------- 
 +; THE <b><font color=#333388>'SELECT DRIVE MOTOR'</font></b> ROUTINE 
 +; -------------------------------- 
 +; <font color=#339933>(Hook Code: $21)</font> 
 +;   This important routine is called on over twenty occasions to activate a 
 +;   microdrive whose number is in the accumulator, or with a parameter of 
 +;   zero, to stop all motors.  It is the sole means of controlling the real 
 +;   or virtual bank of eight microdrives. 
 +;   It is called with interrupts disabled and this condition should be in 
 +;   force when the Hook Code is used. 
 + 
 +<a name="L1532"></a>;; <b>SEL-DRIVE</b> 
 +L1532:  PUSH    HL              ; preserve the original HL value throughout. 
 + 
 +        CP      $00             ; is the parameter zero ? 
 +        JR      NZ,<A href="#L153D">L153D</a>        ; forward, if not, to TURN-ON. 
 + 
 +;   The requirement is to ensure that all eight drives are switched off. 
 + 
 +        CALL    <A href="#L1565">L1565</a>           ; routine SW-MOTOR with A holding zero. 
 + 
 +        EI                      ; Enable Interrupts. 
 + 
 +        POP     HL              ; restore original HL value. 
 +        RET                     ; return.                               &gt;&gt; 
 + 
 + 
 +; -------------------- 
 +; THE <b><font color=#333388>'TURN ON'</font></b> BRANCH 
 +; -------------------- 
 +;   This route turns on a drive in the range 1 - 8.  If the Hook Code has 
 +;   been erroneously invoked with a higher value, then this will be treated 
 +;   in much the same way as with zero.  See later. 
 + 
 +<a name="L153D"></a>;; <b>TURN-ON</b> 
 +L153D:  DI                      ; Disable Interrupts. 
 + 
 +        CALL    <A href="#L1565">L1565</a>           ; routine SW-MOTOR 
 + 
 +        LD      HL,$1388        ; prepare decimal 5,000 delay value. 
 + 
 +<a name="L1544"></a>;; <b>TON-DELAY</b> 
 +L1544:  DEC     HL              ; a simple 
 +        LD      A,H             ; delay loop to 
 +        OR      L               ; let things settle down. 
 +        JR      NZ,<A href="#L1544">L1544</a>        ; back, if not zero, to TON-DELAY 
 + 
 +        LD      HL,$1388        ; load with five thousand again. 
 + 
 +; Now enter another 5000 loop testing for break and searching for a GAP on 
 +; the tape at each iteration. 
 + 
 +<a name="L154C"></a>;; <b>REPTEST</b> 
 +L154C:  LD      B,$06           ; six consecutive reads required to register 
 +                                ; as a gap. 
 + 
 +<a name="L154E"></a>;; <b>CHK-PRES</b> 
 +L154E:  CALL    <A href="#L163E">L163E</a>           ; routine TEST-BRK allows the user to stop. 
 + 
 +        IN      A,($EF)         ; read the microdrive port. 
 +        AND     $04             ; test for the gap bit 
 +        JR      NZ,<A href="#L155B">L155B</a>        ; forward, if not, to NOPRES 
 + 
 +        DJNZ    <A href="#L154E">L154E</a>           ; loop back six times to CHK-PRES 
 + 
 +; A gap has been found - a formatted cartridge is in the drive. 
 + 
 +        POP     HL              ; restore original HL value. 
 +        RET                     ; return with motor running, interrupts 
 +                                ; disabled.                               &gt;&gt; 
 + 
 +; ------------------- 
 +; THE <b><font color=#333388>'NO GAP'</font></b> BRANCH 
 +; ------------------- 
 +;   If no gap signal found on drive so far then continue counting down from 
 +;   5000 and looping back to test for six gaps. 
 + 
 +<a name="L155B"></a>;; <b>NOPRES</b> 
 +L155B:  DEC     HL              ; decrement the counter 
 +        LD      A,H             ; test for 
 +        OR      L               ; zero. 
 +        JR      NZ,<A href="#L154C">L154C</a>        ; back, if not, to REPTEST 
 + 
 +        CALL    <A href="#L1532">L1532</a>           ; routine SEL-DRIVE with accumulator zero 
 +                                ; stops the drive motor. 
 + 
 +        RST     20H             ; Shadow Error Restart 
 +        DEFB    $10             ; 'Microdrive not present' 
 + 
 +; ----------------------------- 
 +; THE <b><font color=#333388>'SWITCH MOTOR'</font></b> SUBROUTINE 
 +; ----------------------------- 
 +;   The main developer of the microdrives and acknowledged co-inventor was 
 +;   the late Ben Cheese, 14-Jul-1954 - 15-Jan-2001. 
 +
 +;   This ROM software always handles the switching of microdrives as if 
 +;   there were eight drives connected.  There is no short cut to directly 
 +;   switch on a drive and they must be handled as an array of eight devices. 
 +;   Each microdrive includes a D-flip flop, capable of holding logic state 
 +;   one or zero.  When the flip-flop is set at logic one then the 
 +;   recording/playback device is switched on. 
 +
 +;   The first microdrive has the D-input terminal of the flip-flop connected 
 +;   to the comms data line of the Interface 1 and the clock-input terminal 
 +;   connected to the clock-output terminal of Interface 1.  Subsequent 
 +;   microdrives have the D-input terminal connected to the Q-output terminal 
 +;   of the next innermost drive/flip-flop and the CLOCK-input terminal 
 +;   connected to the CLOCK-input terminal of the same adjacent 
 +;   drive/flip-flop. 
 +
 +;   The eight microdrives thus behave as a shift register allowing a logic 1 
 +;   condition, originating at the Interface 1 control device, to be loaded 
 +;   into the first flip-flop by a single clock pulse and to be shifted out 
 +;   to the appropriate flip-flop by a series of further clock pulses. 
 +
 +;   As eight pulses will be required, then the logic state of drive eight is 
 +;   considered first and drive one is the last to be considered. 
 +
 +;   By negating the drive number and adding nine, the routine below begins 
 +;   by effecting this reversal and, by converting zero to nine, it ensures 
 +;   that eight logic zeros are shifted out for this case and for the case 
 +;   of any out-of-range parameter, which can arise in the case of a User 
 +;   experimenting with Hook Codes. 
 +;   The limit of eight microdrives is set in the routine below and not in 
 +;   hardware. 
 +
 +;   As Ben pointed out on his patent from which some of these details are 
 +;   taken, "it will be appreciated that the control device may be used to 
 +;   select associated devices other than recording/playback devices and that 
 +;   any number of associated devices may be accommodated by use of the 
 +;   technique described." 
 + 
 +<a name="L1565"></a>;; <b>SW-MOTOR</b> 
 +L1565:  PUSH    DE              ; preserve the original DE value throughout. 
 + 
 +        LD      DE,$0100        ; load DE with the constants logic one and 
 +                                ; logic zero. 
 + 
 +        NEG                     ; negate the supplied drive number 0 - n 
 +        ADD     A,$09           ; add 9 so that 0 = 9, -1 = 8, -8 = 1, -10 = -1 
 +        LD      C,A             ; place the reversed parameter in C. 
 +        LD      B,$08           ; set clock shift counter to eight. 
 + 
 +<a name="L1570"></a>;; <b>ALL-MOTRS</b> 
 +L1570:  DEC                   ; decrement the drive selector. 
 +        JR      NZ,<A href="#L1586">L1586</a>        ; forward, if not in position, to OFF-MOTOR. 
 + 
 +; The time has come to send out a signal to start this drive. 
 + 
 +        LD      A,D             ; select logic one. 
 +        OUT     ($F7),        ; output to data port. 
 + 
 +        LD      A,$EE           ; select comms clock 1, comms data 0 
 +        OUT     ($EF),        ; output to D-flip flop. 
 + 
 +        CALL    <A href="#L15A2">L15A2</a>           ; routine DEL-S-1 holds for a millisecond. 
 + 
 +        LD      A,$EC           ; select comms clock 0, comms data 0 
 +        OUT     ($EF),        ; output to D-flip flops. 
 + 
 +        CALL    <A href="#L15A2">L15A2</a>           ; routine DEL-S-1 holds for a millisecond. 
 + 
 +        JR      <A href="#L1597">L1597</a>           ; forward to NXT-MOTOR 
 + 
 +; --- 
 + 
 +<a name="L1586"></a>;; <b>OFF-MOTOR</b> 
 +L1586:  LD      A,$EF           ; select comms clock 1, comms data 1 
 +        OUT     ($EF),        ; output to D-flip flop. 
 + 
 +        LD      A,E             ; select logic 0. 
 +        OUT     ($F7),        ; output to data port. 
 + 
 +        CALL    <A href="#L15A2">L15A2</a>           ; routine DEL-S-1 holds for a millisecond. 
 + 
 +        LD      A,$ED           ; select comms clock 0, comms data 1 
 +        OUT     ($EF),        ; output to microdrive port. 
 + 
 +        CALL    <A href="#L15A2">L15A2</a>           ; routine DEL-S-1 holds for a millisecond. 
 + 
 +<a name="L1597"></a>;; <b>NXT-MOTOR</b> 
 +L1597:  DJNZ    <A href="#L1570">L1570</a>           ; back, for all eight drives, to ALL-MOTRS. 
 + 
 +        LD      A,D             ; select logic one. 
 +        OUT     ($F7),        ; output to data port. 
 +        LD      A,$EE           ; select comms clock 1, comms data 0. 
 +        OUT     ($EF),        ; output to microdrive port. 
 + 
 +        POP     DE              ; restore original DE value. 
 +        RET                     ; return. 
 + 
 + 
 +; --------------------------------- 
 +; THE <b><font color=#333388>'1 MILLISECOND DELAY'</font></b> ROUTINE 
 +; --------------------------------- 
 +;   This subroutine is used to time the transitions of the Delay-flip-flops 
 +;   used, above, to control the array of microdrives attached to Interface 1. 
 +;   Delay flip flops become unstable if transitions are too close together 
 +;   and this routine provides a 1 millisecond delay between clock pulses. 
 + 
 +<a name="L15A2"></a>;; <b>DEL-S-1</b> 
 +L15A2:  PUSH    BC              ; preserve counters. 
 +        PUSH    AF              ; 
 + 
 +        LD      BC,$0087        ; 135 decimal. 
 +        CALL    <A href="#L1652">L1652</a>           ; routine DELAY-BC 
 + 
 +        POP     AF              ; 
 +        POP     BC              ; restore counters 
 + 
 +        RET                     ; return. 
 + 
 + 
 +; --------------------------------------------- 
 +; THE <b><font color=#333388>'SEND HEADER BLOCK TO MICRODRIVE'</font></b> ROUTINE 
 +; --------------------------------------------- 
 +;   Routine is called once from the FORMAT routine. 
 + 
 +<a name="L15AD"></a>;; <b>OUT-M-HD</b> 
 +L15AD:  PUSH    HL              ; 
 +        LD      DE,$001E        ; 30 bytes. 
 +        JR      <A href="#L15B7">L15B7</a>           ; forward to OUT-M-BLK -&gt; 
 + 
 +; ------------------------------------------- 
 +; THE <b><font color=#333388>'SEND DATA BLOCK TO MICRODRIVE'</font></b> ROUTINE 
 +; ------------------------------------------- 
 +
 + 
 +<a name="L15B3"></a>;; <b>OUT-M-BUF</b> 
 +L15B3:  PUSH    HL              ; 
 +        LD      DE,$021F        ; 543 bytes. 
 + 
 +; -&gt; Common code. 
 + 
 +<a name="L15B7"></a>;; <b>OUT-M-BLK</b> 
 +L15B7:  IN      A,($EF)         ; 
 +        AND     $01             ; isolate write prot. bit. 
 +        JR      NZ,<A href="#L15BF">L15BF</a>        ; forward to NOT-PROT 
 + 
 +        RST     20H             ; Shadow Error Restart 
 +        DEFB    $0E             ; Drive 'write' protected 
 + 
 +; --- 
 + 
 +<a name="L15BF"></a>;; <b>NOT-PROT</b> 
 +L15BF:  LD      A,($5CC6)       ; sv IOBORD 
 +        OUT     ($FE),        ; 
 +        LD      A,$E2           ; 
 +        OUT     ($EF),        ; 
 +        INC                   ; 
 +        LD      A,D             ; 
 +        LD      B,E             ; 
 +        LD      C,$E7           ; 
 + 
 +        NOP                     ; 
 +        NOP                     ; 
 +        NOP                     ; 
 + 
 +<a name="L15D0"></a>;; <b>OUT-M-BYT</b> 
 +L15D0:  OTIR                    ; 
 +        DEC                   ; 
 +        JR      NZ,<A href="#L15D0">L15D0</a>        ; back to OUT-M-BYT 
 + 
 +        LD      A,$E6           ; 
 +        OUT     ($EF),        ; 
 +        CALL    <A href="#L0D4D">L0D4D</a>           ; routine BORD-REST 
 +        POP     HL              ; 
 +        RET                     ; return. 
 + 
 +; ----------------------------- 
 +; THE <b><font color=#333388>'SIGNAL ERROR'</font></b> EXIT POINT 
 +; ----------------------------- 
 +;   This exit point is used  twice from the next routines when the required 
 +;   header or record block is not found within the requisite time. 
 + 
 +<a name="L15DE"></a>;; <b>SIGN-ERR</b> 
 +L15DE:  POP     BC              ; balance the stack. 
 +        POP     HL              ; first byte of destination. 
 +        INC     (HL)            ; increment RECFLG or HDFLAG. 
 +        RET                     ; return. 
 + 
 + 
 +; -------------------------------------------------- 
 +; THE <b><font color=#333388>'RECEIVE BLOCK FROM MICRODRIVE HEADER'</font></b> ROUTINE 
 +; -------------------------------------------------- 
 +
 + 
 +<a name="L15E2"></a>;; <b>GET-M-HD</b> 
 +L15E2:  PUSH    HL              ; save destination 
 +        LD      DE,$000F        ; set fifteen bytes to load. 
 +        LD      HL,$0000        ; set large delay when waiting for a header. 
 +        JR      <A href="#L15F2">L15F2</a>           ; forward to GET-M-BLK 
 + 
 +; -------------------------------------------------- 
 +; THE <b><font color=#333388>'RECEIVE BLOCK FROM MICRODRIVE RECORD'</font></b> ROUTINE 
 +; -------------------------------------------------- 
 +
 + 
 +<a name="L15EB"></a>;; <b>GET-M-BUF</b> 
 +L15EB:  PUSH    HL              ; save destination. 
 +        LD      DE,$0210        ; set 528d bytes to load. 
 +        LD      HL,$01F4        ; set delay counter to 500d. 
 + 
 +; --&gt; 
 + 
 +<a name="L15F2"></a>;; <b>GET-M-BLK</b> 
 +L15F2:  LD      B,E             ; load B register for first INIR load. 
 +        LD      C,D             ; load C register with count of further loads. 
 +        INC                   ; adjust to count down to zero. 
 +        PUSH    BC              ; save the INIR counters. 
 + 
 +
 + 
 +<a name="L15F6"></a>;; <b>CHK-AGAIN</b> 
 +L15F6:  LD      B,$08           ; set gap counter to eight. 
 + 
 +        DEC     HL              ; 
 +        LD      A,H             ; 
 +        OR      L               ; 
 + 
 +        JR      Z,<A href="#L15DE">L15DE</a>         ; back to SIGN-ERR 
 + 
 +<a name="L15FD"></a>;; <b>CHKLOOP</b> 
 +L15FD:  CALL    <A href="#L163E">L163E</a>           ; routine TEST-BRK 
 + 
 +        IN      A,($EF)         ; 
 +        AND     $04             ; isolate gap bit. 
 +        JR      Z,<A href="#L15F6">L15F6</a>         ; back to CHK-AGAIN 
 + 
 +        DJNZ    <A href="#L15FD">L15FD</a>           ; back to CHKLOOP 
 + 
 +<a name="L1608"></a>;; <b>CHK-AG-2</b> 
 +L1608:  LD      B,$06           ; 
 +        DEC     HL              ; 
 +        LD      A,H             ; 
 +        OR      L               ; 
 +        JR      Z,<A href="#L15DE">L15DE</a>         ; back to SIGN-ERR 
 + 
 + 
 +<a name="L160F"></a>;; <b>CHK-LP-2</b> 
 +L160F:  CALL    <A href="#L163E">L163E</a>           ; routine TEST-BRK 
 +        IN      A,($EF)         ; 
 +        AND     $04             ; isolate gap bit. 
 +        JR      NZ,<A href="#L1608">L1608</a>        ; back to CHK-AG-2 
 + 
 +        DJNZ    <A href="#L160F">L160F</a>           ; back to CHK-LP-2 
 + 
 +        LD      A,$EE           ; 
 +        OUT     ($EF),        ; 
 + 
 +        LD      B,$3C           ; set count 60 decimal. 
 + 
 +<a name="L1620"></a>;; <b>DR-READY</b> 
 +L1620:  IN      A,($EF)         ; 
 +        AND     $02             ; isolate sync bit. 
 +        JR      Z,<A href="#L162A">L162A</a>         ; forward to READY-RE 
 + 
 +        DJNZ    <A href="#L1620">L1620</a>           ; back to DR-READY 
 + 
 +        JR      <A href="#L15F6">L15F6</a>           ; back to CHK-AGAIN 
 + 
 +; --- 
 + 
 +<a name="L162A"></a>;; <b>READY-RE</b> 
 +L162A:  POP     BC              ; retrieve counters from the stack. 
 +        POP     HL              ; retrieve the destination 
 +        PUSH    HL              ; and stack again. 
 +        CALL    <A href="#L163E">L163E</a>           ; routine TEST-BRK. 
 +        LD      A,C             ; transfer repeat counter to A. 
 +        LD      C,$E7           ; set port to $E7. 
 + 
 +;   Now the INIR (INput to memory Increment and Repeat) instruction is used. 
 + 
 +<a name="L1633"></a>;; <b>IN-M-BLK</b> 
 +L1633:  INIR                    ; read B bytes from port C to destination HL. 
 + 
 +;   B (zero) will now count 256 bytes if first block was not the total. 
 + 
 +        DEC                   ; decrement repeat counter. 
 +        JR      NZ,<A href="#L1633">L1633</a>        ; back, if not zero, to IN-M-BLK 
 + 
 +;   All bytes, 15 or 528 have now been read. 
 + 
 +        LD      A,$EE           ; 
 +        OUT     ($EF),        ; 
 + 
 +        POP     HL              ; restore pointer to first byte. 
 +        RET                     ; return. 
 + 
 +; ---------------------- 
 +; THE <b><font color=#333388>'TEST-BRK'</font></b> ROUTINE 
 +; ---------------------- 
 +;   <font color=#9900FF>Note.</font> used more consistently in this ROM. 
 + 
 +<a name="L163E"></a>;; <b>TEST-BRK</b> 
 +L163E:  LD      A,$7F           ; read port $7FFE - keys B, N, M, SYM, SPACE. 
 +        IN      A,($FE)         ; 
 +        RRA                     ; test for SPACE key. 
 +        RET                   ; return if not pressed. 
 + 
 +        LD      A,$FE           ; read port $FEFE - keys SHIFT, Z, X, C, V. 
 +        IN      A,($FE)         ; 
 +        RRA                     ; test for SHIFT key. 
 +        RET                   ; return if not pressed. 
 + 
 +        CALL    <A href="#L0D4D">L0D4D</a>           ; routine BORD-REST. 
 + 
 +        LD      (IY+$00),$14    ; set ERR_NR to main 'L BREAK into program' 
 +        RST     28H             ; invoke the Main ROM error routine. 
 + 
 +; ---------------------- 
 +; THE <b><font color=#333388>'DELAY-BC'</font></b> ROUTINE 
 +; ---------------------- 
 +
 + 
 +<a name="L1652"></a>;; <b>DELAY-BC</b> 
 +L1652:  PUSH    AF              ; 
 + 
 +<a name="L1653"></a>;; <b>DELAY-BC1</b> 
 +L1653:  DEC     BC              ; 
 +        LD      A,B             ; 
 +        OR      C               ; 
 +        JR      NZ,<A href="#L1653">L1653</a>        ; back to DELAY-BC1 
 + 
 +        POP     AF              ; 
 +        RET                     ; 
 + 
 +; ------------------------ 
 +; THE <b><font color=#333388>'READ BLOCK'</font></b> ROUTINE 
 +; ------------------------ 
 +;   <font color=#9900FF>Note.</font> new in this ROM. 
 +;   Used by format routine. 
 + 
 +<a name="L165A"></a>;; <b>READ-BLK</b> 
 +L165A:  PUSH    HL 
 +        PUSH    BC 
 + 
 +<a name="L165C"></a>;; <b>RDLOOP1</b> 
 +L165C:  LD      B,$08 
 + 
 +<a name="L165E"></a>;; <b>RDLOOP2</b> 
 +L165E:  CALL    <A href="#L163E">L163E</a>           ; routine TEST-BRK 
 + 
 +        IN      A,($EF) 
 +        AND     $04             ; isolate gap bit. 
 + 
 +        JR      Z,<A href="#L165C">L165C</a>         ; back to RDLOOP1 
 + 
 +        DJNZ    <A href="#L165E">L165E</a>           ; back to RDLOOP2 
 + 
 + 
 +<a name="L1669"></a>;; <b>RDLOOP3</b> 
 +L1669:  LD      B,$06 
 + 
 +<a name="L166B"></a>;; <b>RDLOOP4</b> 
 +L166B:  CALL    <A href="#L163E">L163E</a>           ; routine TEST-BRK 
 + 
 +        IN      A,($EF) 
 +        AND     $04             ; isolate gap bit. 
 + 
 +        JR      NZ,<A href="#L1669">L1669</a>        ; back to RDLOOP3 
 + 
 +        DJNZ    <A href="#L166B">L166B</a>           ; back to RDLOOP4 
 + 
 +        LD      A,$EE 
 +        OUT     ($EF),
 + 
 +        LD      B,$3C           ; set counter to 60d. 
 + 
 +<a name="L167C"></a>;; <b>SYNC-RD</b> 
 +L167C:  IN      A,($EF) 
 +        AND     $02             ; isolate sync bit. 
 +        JR      Z,<A href="#L1686">L1686</a>         ; forward to READY-R2 
 + 
 +        DJNZ    <A href="#L167C">L167C</a>           ; back to SYNC-RD 
 + 
 +        JR      <A href="#L165C">L165C</a>           ; back to RDLOOP1 
 + 
 +; --- 
 + 
 + 
 +<a name="L1686"></a>;; <b>READY-R2</b> 
 +L1686:  POP     BC 
 +        POP     HL 
 +        PUSH    HL 
 +        CALL    <A href="#L163E">L163E</a>           ; routine TEST-BRK 
 + 
 +        LD      C,$E7           ; port 
 +        LD      E,$FC           ; required test byte 
 +        LD      B,$0F           ; initial counter. 
 +        LD      D,$64           ; final counter. 
 +        INIR 
 + 
 +<a name="L1696"></a>;; <b>RD-BYT-1</b> 
 +L1696:  IN      A,(C) 
 +        CP      E 
 +        JR      NZ,<A href="#L16AD">L16AD</a>        ; forward to ENDRD 
 + 
 +        DJNZ    <A href="#L1696">L1696</a>           ; back to RD-BYT-1 
 + 
 + 
 +<a name="L169D"></a>;; <b>RD-BYT-2</b> 
 +L169D:  IN      A,(C) 
 +        CP      E 
 +        JR      NZ,<A href="#L16AD">L16AD</a>        ; forward to ENDRD 
 + 
 +        DJNZ    <A href="#L169D">L169D</a>           ; back to RD-BYT-2 
 + 
 +        LD      B,D             ; final counter is $64 
 + 
 +<a name="L16A5"></a>;; <b>RD-BYT-3</b> 
 +L16A5:  IN      A,(C) 
 +        CP      E 
 +        JR      NZ,<A href="#L16AD">L16AD</a>        ; forward to ENDRD 
 + 
 +        DJNZ    <A href="#L16A5">L16A5</a>           ; back to RD-BYT-3 
 + 
 +        XOR                   ; set zero flag to signal successful read 
 + 
 +<a name="L16AD"></a>;; <b>ENDRD</b> 
 +L16AD:  POP     HL 
 +        RET                     ; return. 
 + 
 +; ------------------------- 
 +; THE <b><font color=#333388>'WRITE BLOCK'</font></b> ROUTINE 
 +; ------------------------- 
 +;   <font color=#9900FF>Note.</font> new in this ROM. 
 +;   Called once from the FORMAT routine. 
 + 
 +<a name="L16AF"></a>;; <b>WR-BLK</b> 
 +L16AF:  PUSH    HL              ; preserve HL throughout. 
 + 
 +        LD      A,($5CC6)       ; fetch the value of IOBORD 
 +        OUT     ($FE),        ; and change the border colour. 
 + 
 +        LD      A,$E2 
 +        OUT     ($EF),        ; enable writing 
 + 
 +        LD      E,$66 
 +        LD      C,$E7 
 +        LD      B,$1B 
 +        LD      A,$FC           ; test byte written 
 +        NOP                     ; 
 +        OTIR                    ; 
 + 
 +<a name="L16C4"></a>;; <b>WR-BYT-1</b> 
 +L16C4:  OUT     (C),
 +        DJNZ    <A href="#L16C4">L16C4</a>           ; back to WR-BYT-1 
 + 
 + 
 +<a name="L16C8"></a>;; <b>WR-BYT-2</b> 
 +L16C8:  OUT     (C),
 +        DJNZ    <A href="#L16C8">L16C8</a>           ; back to WR-BYT-2 
 + 
 +        LD      B,E             ; load counter with $66 
 + 
 +<a name="L16CD"></a>;; <b>WR-BYT-3</b> 
 +L16CD:  OUT     (C),
 +        DJNZ    <A href="#L16CD">L16CD</a>           ; back to WR-BYT-3 
 + 
 +        LD      A,$E6 
 +        OUT     ($EF),
 + 
 +        CALL    <A href="#L0D4D">L0D4D</a>           ; routine BORD-REST 
 + 
 +        POP     HL              ; restore initial HL value. 
 + 
 +        RET                     ; return. 
 + 
 +; -------------------- 
 +; THE <b><font color=#333388>'UNUSED'</font></b> SECTION 
 +; -------------------- 
 +;   Contains copyright holder and initials of the main programmer.  The rest 
 +;   is set to $FF.  This section is situated before the fixed-position CLOSE 
 +;   rectification routine. 
 + 
 +        DEFB    $7F             ; copyright  &copy;  
 +        DEFM    " 1983 Sinclair" 
 +        DEFM    " Research Ltd" 
 +        DEFM    " MJB "         ; Martin Brennan 
 + 
 +        DEFB    $FF 
 +        DEFB    $FF 
 +        DEFB    $FF 
 +        DEFB    $FF 
 +        DEFB    $FF 
 +        DEFB    $FF 
 +        DEFB    $FF 
 +        DEFB    $FF 
 +        DEFB    $FF 
 +        DEFB    $FF 
 +        DEFB    $FF 
 +        DEFB    $FF 
 +        DEFB    $FF 
 + 
 +; -------------------------- 
 +; THE <b><font color=#333388>'CLOSE STREAM'</font></b> ROUTINE 
 +; -------------------------- 
 +;   <font color=#9900FF>Note.</font> An instruction fetch on main address L1708 pages in this ROM. 
 + 
 +<a name="L1708"></a>;; <b>CLOSE-CH</b> 
 +L1708:  INC     HL              ; Same instruction as in Main ROM 
 + 
 +        RST     30H             ; Create the new system variables 
 + 
 +;   <font color=#9900FF>Note.</font> If extra System Variables were created then the accumulator will  
 +;   now hold the value 1 from the setting of COPIES. 
 +;   A command like       OPEN #7,"s" : CLOSE #7      will not work. 
 +;   If the system variables were already created then it is possible to  
 +;   derive the stream from the accumulator by reversing the operations  
 +;   that were performed on the value in the main ROM. 
 + 
 + 
 +        SRL                   ; Shift Right Logical halves the value 
 +        SUB     $03             ; Subtraction produced the original stream. 
 + 
 +        RES     1,(IY+$7C)      ; set FLAGS_3 to indicate a CLOSE operation. 
 + 
 +        CALL    <A href="#L1718">L1718</a>           ; routine CLOSE (below) 
 + 
 +        JP      <A href="#L05C1">L05C1</a>           ; jump back to normal command exit at END1 
 + 
 +; --------------------------- 
 +; THE <b><font color=#333388>'CLOSE COMMAND'</font></b> ROUTINE 
 +; --------------------------- 
 +;   This command is called from above and also from ALL-STRMS as part of the 
 +;   CLEAR # command execution. 
 + 
 +<a name="L1718"></a>;; <b>CLOSE</b> 
 +L1718:  RST     10H             ; CALBAS 
 +        DEFW    $1727           ; main STR-DATA1 
 + 
 +;   Now perform the check that should have taken place in the original ROM. 
 + 
 +        LD      A,C             ; Test offset for zero. 
 +        OR      B               ; 
 +        RET                   ; Return if the stream is already closed. 
 + 
 +        PUSH    BC              ; 
 +        PUSH    HL              ; 
 + 
 +        LD      HL,($5C4F)      ; sv CHANS 
 +        DEC     HL              ; 
 +        ADD     HL,BC           ; 
 +        EX      (SP),HL         ; 
 +        RST     10H             ; CALBAS 
 +        DEFW    $16EB           ; main CLOSEX 
 +        LD      HL,($5C4F)      ; sv CHANS 
 +        LD      DE,$0014        ; 
 +        ADD     HL,DE           ; 
 + 
 +        POP     DE              ; 
 +        SCF                     ; 
 +        SBC     HL,DE           ; 
 +        POP     BC              ; 
 + 
 + 
 +        RET     NC              ; 
 + 
 +        PUSH    BC              ; 
 +        PUSH    DE              ; 
 +        EX      DE,HL           ; 
 +        LD      ($5C51),HL      ; sv CURCHL 
 +        INC     HL              ; 
 + 
 + 
 +        INC     HL              ; 
 +        INC     HL              ; 
 +        INC     HL              ; 
 + 
 +        LD      A,(HL)          ; fetch the letter. 
 + 
 +;   Now mark the channel as temporary so that if anything goes wrong, such 
 +;   as the user pressing BREAK, then the channel can be reclaimed by CLEAR #. 
 + 
 +L1741:  SET     7,(HL)          ; As suggested by Andrew Pennell 1983. 
 + 
 +        LD      DE,$0005        ; 
 +        ADD     HL,DE           ; 
 +        LD      E,(HL)          ; 
 +        INC     HL              ; 
 +        LD      D,(HL)          ; 
 +        PUSH    DE              ; 
 +        CP      $54             ; compare to "T" 
 +        JR      NZ,<A href="#L175C">L175C</a>        ; forward to CL-N-CH 
 + 
 +        BIT     1,(IY+$7C)      ; sv FLAGS_3 
 +        JR      NZ,<A href="#L177D">L177D</a>        ; forward to RCLM-CH 
 + 
 +        LD      A,$0D 
 +        CALL    <A href="#L0D07">L0D07</a>           ; routine BCHAN-OUT 
 +        JR      <A href="#L177D">L177D</a>           ; forward to RCLM-CH 
 + 
 +; --- 
 + 
 +<a name="L175C"></a>;; <b>CL-N-CH</b> 
 +L175C:  CP      $4E             ; character "N"
 +        JR      NZ,<A href="#L176B">L176B</a>        ; forward to CL-M-CH 
 + 
 +        BIT     1,(IY+$7C)      ; sv FLAGS_3 
 +        JR      NZ,<A href="#L177D">L177D</a>        ; forward to RCLM-CH 
 + 
 +        CALL    <A href="#L0FAE">L0FAE</a>           ; routine SEND-NEOF 
 +        JR      <A href="#L177D">L177D</a>           ; forward to RCLM-CH 
 + 
 +; --- 
 + 
 + 
 +<a name="L176B"></a>;; <b>CL-M-CH</b> 
 +L176B:  CP      $4D             ; character "M" 
 +        JR      NZ,<A href="#L177D">L177D</a>        ; forward to RCLM-CH 
 + 
 +        POP     DE              ; 
 +        POP     IX              ; 
 +        POP     DE              ; 
 +        BIT     1,(IY+$7C)      ; sv FLAGS_3 
 +        JP      Z,<A href="#L138E">L138E</a>         ; jump to CLOSE-M2 
 + 
 +        JP      <A href="#L119F">L119F</a>           ; jump to DEL-M-BUF 
 + 
 +; --- 
 + 
 +<a name="L177D"></a>;; <b>RCLM-CH</b> 
 +L177D:  POP     BC              ; 
 +        POP     HL              ; 
 +        PUSH    BC              ; 
 +        RST     10H             ; CALBAS 
 +        DEFW    $19E8           ; main RECLAIM-2 
 +        XOR                   ; 
 +        LD      HL,$5C16        ; sv STRMS_00 
 + 
 +<a name="L1787"></a>;; <b>UPD-STRM</b> 
 +L1787:  LD      E,(HL)          ; 
 +        INC     HL              ; 
 +        LD      D,(HL)          ; 
 +        DEC     HL              ; 
 +        LD      ($5C5F),HL      ; sv X_PTR 
 +        POP     BC              ; 
 +        POP     HL              ; 
 +        PUSH    HL              ; 
 +        PUSH    BC              ; 
 +        AND                   ; 
 +        SBC     HL,DE           ; 
 +        JR      NC,<A href="#L17A2">L17A2</a>        ; forward to UPD-NXT-S 
 + 
 +        EX      DE,HL           ; 
 +        AND                   ; 
 +        SBC     HL,BC           ; 
 +        EX      DE,HL           ; 
 +        LD      HL,($5C5F)      ; sv X_PTR 
 +        LD      (HL),         ; 
 +        INC     HL              ; 
 +        LD      (HL),         ; 
 + 
 +<a name="L17A2"></a>;; <b>UPD-NXT-S</b> 
 +L17A2:  LD      HL,($5C5F)      ; sv X_PTR 
 +        INC     HL              ; 
 +        INC     HL              ; 
 +        INC                   ; 
 +        CP      $10             ; 
 +        JR      C,<A href="#L1787">L1787</a>         ; back to UPD-STRM 
 + 
 +        LD      (IY+$26),$00    ; sv X_PTR_hi 
 +        POP     HL              ; 
 +        POP     HL              ; 
 +        RES     1,(IY+$7C)      ; sv FLAGS_3 
 +        RET                     ; return. 
 + 
 +; ---------------------------------------- 
 +; THE <b><font color=#333388>'RECLAIM TEMPORARY CHANNELS'</font></b> ROUTINE 
 +; ---------------------------------------- 
 +
 + 
 +<a name="L17B7"></a>;; <b>RCL-T-CH</b> 
 +L17B7:  LD      IX,($5C4F)      ; sv CHANS 
 +        LD      DE,$0014 
 +        ADD     IX,DE 
 + 
 +<a name="L17C0"></a>;; <b>EX-CHANS</b> 
 +L17C0:  LD      A,(IX+$00)      ; first character of channel 
 +        CP      $80             ; is it the end-marker ? 
 +        JR      NZ,<A href="#L17D0">L17D0</a>        ; forward to CHK-TEMPM 
 + 
 +        LD      A,$EE 
 +        OUT     ($EF),
 + 
 +        XOR     A 
 +        JP      <A href="#L1532">L1532</a>           ; jump to SEL-DRIVE 
 + 
 +; --- 
 + 
 +        RET                     ; unused - the above JP was probably once a CALL. 
 + 
 +; --- 
 + 
 +<a name="L17D0"></a>;; <b>CHK-TEMPM</b> 
 +L17D0:  LD      A,(IX+$04)      ; channel letter 
 +        CP      $CD             ; is it an inverted "M"
 +        JR      NZ,<A href="#L17DC">L17DC</a>        ; forward to CHK-TEMPN 
 + 
 +        CALL    <A href="#L119F">L119F</a>           ; routine DEL-M-BUF 
 +        JR      <A href="#L17B7">L17B7</a>           ; back to RCL-T-CH 
 + 
 + 
 +<a name="L17DC"></a>;; <b>CHK-TEMPN</b> 
 +L17DC:  CP      $CE             ; is channel letter an inverted "N"
 +        JR      NZ,<A href="#L17EB">L17EB</a>        ; forward to PT-N-CHAN 
 + 
 +        LD      BC,$0114 
 +        PUSH    IX 
 +        POP     HL 
 +        RST     10H             ; CALBAS 
 +        DEFW    $19E8           ; main RECLAIM-2 
 +        JR      <A href="#L17B7">L17B7</a>           ; back to RCL-T-CH 
 + 
 + 
 +<a name="L17EB"></a>;; <b>PT-N-CHAN</b> 
 +L17EB:  LD      E,(IX+$09)      ; length of 
 +        LD      D,(IX+$0A)      ; channel 
 +        ADD     IX,DE 
 +        JR      <A href="#L17C0">L17C0</a>           ; back to EX-CHANS 
 + 
 + 
 +; -------------------------- 
 +; THE <b><font color=#333388>'MOVE COMMAND'</font></b> ROUTINE 
 +; -------------------------- 
 +
 + 
 +<a name="L17F5"></a>;; <b>MOVE</b> 
 +L17F5:  SET     4,(IY+$7C)      ; update FLAGS_3 to indicate a MOVE is in  
 +                                ; progress - see INKEY$  
 + 
 +        CALL    <A href="#L1859">L1859</a>           ; routine OP-STRM 
 +        LD      HL,($5C4F)      ; sv CHANS 
 +        PUSH    HL 
 +        CALL    <A href="#L059F">L059F</a>           ; routine EX-D-STR 
 +        CALL    <A href="#L1859">L1859</a>           ; routine OP-STRM 
 +        CALL    <A href="#L059F">L059F</a>           ; routine EX-D-STR 
 +        POP     DE 
 +        LD      HL,($5C4F)      ; sv CHANS 
 +        OR      A 
 +        SBC     HL,DE 
 +        LD      DE,($5CDA)      ; sv N_STR1 
 +        ADD     HL,DE 
 +        LD      ($5CDA),HL      ; sv N_STR1 
 + 
 +<a name="L1818"></a>;; <b>M-AGAIN</b> 
 +L1818:  LD      HL,($5CDA)      ; sv N_STR1 
 +        LD      ($5C51),HL      ; sv CURCHL 
 + 
 +<a name="L181E"></a>;; <b>I-AGAIN</b> 
 +L181E:  RST     10H             ; CALBAS 
 +        DEFW    $15E6           ; main INPUT-AD 
 +        JR      C,<A href="#L1827">L1827</a>         ; forward to MOVE-OUT 
 + 
 +        JR      Z,<A href="#L181E">L181E</a>         ; back to I-AGAIN 
 + 
 +        JR      <A href="#L1832">L1832</a>           ; forward to MOVE-EOF 
 + 
 + 
 +<a name="L1827"></a>;; <b>MOVE-OUT</b> 
 +L1827:  LD      HL,($5CE2)      ; sv D_STR2 
 +        LD      ($5C51),HL      ; sv CURCHL 
 +        RST     10H             ; CALBAS 
 +        DEFW    $0010           ; main PRINT-A 
 + 
 +        JR      <A href="#L1818">L1818</a>           ; back to M-AGAIN 
 + 
 +<a name="L1832"></a>;; <b>MOVE-EOF</b> 
 +L1832:  RES     4,(IY+$7C)      ; sv FLAGS_3 
 +        LD      HL,($5C4F)      ; sv CHANS 
 +        PUSH    HL 
 +        CALL    <A href="#L059F">L059F</a>           ; routine EX-D-STR 
 +        CALL    <A href="#L18A8">L18A8</a>           ; routine CL-CHAN 
 +        CALL    <A href="#L059F">L059F</a>           ; routine EX-D-STR 
 +        POP     DE 
 +        LD      HL,($5C4F)      ; sv CHANS 
 +        OR      A 
 +        SBC     HL,DE 
 +        LD      DE,($5CDA)      ; sv N_STR1 
 +        ADD     HL,DE 
 +        LD      ($5CDA),HL      ; sv N_STR1 
 +        CALL    <A href="#L18A8">L18A8</a>           ; routine CL-CHAN 
 +        CALL    <A href="#L17B7">L17B7</a>           ; routine RCL-T-CH 
 + 
 +        RET                     ; RETURN 
 + 
 + 
 +; --------------------------------------------- 
 +; THE <b><font color=#333388>'USE STREAM OR TEMPORARY CHANNEL'</font></b> ROUTINE 
 +; --------------------------------------------- 
 +
 + 
 +<a name="L1859"></a>;; <b>OP-STRM</b> 
 +L1859:  LD      A,($5CD8)       ; sv D_STR1 
 +        INC     A 
 +        JR      Z,<A href="#L186A">L186A</a>         ; forward to OP-CHAN 
 + 
 +        DEC     A 
 +        RST     10H             ; CALBAS 
 +        DEFW    $1601           ; main CHAN-OPEN 
 +        LD      HL,($5C51)      ; sv CURCHL 
 +        LD      ($5CDA),HL      ; sv N_STR1 
 +        RET 
 + 
 + 
 +<a name="L186A"></a>;; <b>OP-CHAN</b> 
 +L186A:  LD      A,($5CD9)       ; sv L_STR1 device letter. 
 + 
 +        CP      $4D             ; is character "M"
 +        JR      NZ,<A href="#L1883">L1883</a>        ; forward to CHECK-N 
 + 
 +        CALL    <A href="#L1B05">L1B05</a>           ; routine OP-TEMP-M creates a temporary 
 +                                ; microdrive channel, starts motor, and  
 +                                ; fetches record zero of named file. 
 +        XOR     A 
 +        CALL    <A href="#L1532">L1532</a>           ; routine SEL-DRIVE 
 +        LD      ($5CDA),IX      ; sv N_STR1 
 +        BIT     2,(IX+$43)      ; RECFLG 
 +        RET     Z 
 + 
 +        RST     20H             ; Shadow Error Restart 
 +        DEFB    $16             ; Wrong file type 
 + 
 + 
 +<a name="L1883"></a>;; <b>CHECK-N</b> 
 +L1883:  CP      $4E             ; is character "N"
 +        JR      NZ,<A href="#L188F">L188F</a>        ; forward to CHECK-R 
 + 
 +        CALL    <A href="#L0F46">L0F46</a>           ; routine OP-TEMP-N 
 +        LD      ($5CDA),IX      ; sv N_STR1 
 +        RET 
 + 
 +; --- 
 + 
 +;   Finally, check for the RS232 channel before producing an error. 
 + 
 +<a name="L188F"></a>;; <b>CHECK-R</b> 
 +L188F:  CP      $54             ; is character "T"
 +        JR      Z,<A href="#L1899">L1899</a>         ; forward to USE-R 
 + 
 +        CP      $42             ; is character "B"
 +        JR      Z,<A href="#L1899">L1899</a>         ; forward to USE-R 
 + 
 +        RST     20H             ; Shadow Error Restart 
 +        DEFB    $00             ; Nonsense in BASIC 
 + 
 +; --- 
 + 
 +<a name="L1899"></a>;; <b>USE-R</b> 
 +L1899:  CALL    <A href="#L0B17">L0B17</a>           ; routine OP-RS-CH 
 +        LD      ($5CDA),DE      ; sv N_STR1 
 +        PUSH    DE              ; 
 +        POP     IX              ; 
 +        SET     7,(IX+$04)      ; channel letter 
 +        RET                     ; return. 
 + 
 + 
 +; ---------------------------------- 
 +; THE <b><font color=#333388>'CLOSE '</font></b>MOVE' CHANNEL' ROUTINE 
 +; ---------------------------------- 
 +
 + 
 +<a name="L18A8"></a>;; <b>CL-CHAN</b> 
 +L18A8:  LD      A,($5CD8)       ; sv D_STR1 
 +        INC     A 
 +        RET     NZ 
 + 
 +        LD      A,($5CD9)       ; sv L_STR1 device letter. 
 +        CP      $4D             ; is character "M"
 +        JR      NZ,<A href="#L18BC">L18BC</a>        ; forward to CL-CHK-N 
 + 
 +        LD      IX,($5CDA)      ; sv N_STR1 
 +        CALL    <A href="#L138E">L138E</a>           ; routine CLOSE-M2 
 +        RET                     ; 
 + 
 + 
 +<a name="L18BC"></a>;; <b>CL-CHK-N</b> 
 +L18BC:  CP      $4E             ; is character "N"
 +        RET     NZ              ; 
 + 
 +        LD      IX,($5CDA)      ; sv N_STR1 
 +        LD      ($5C51),IX      ; sv CURCHL 
 +        CALL    <A href="#L0FAE">L0FAE</a>           ; routine SEND-NEOF 
 +        RET 
 + 
 + 
 +; --------------------------------------------- 
 +; THE <b><font color=#333388>'SAVE DATA BLOCK INTO MICRODRIVE'</font></b> ROUTINE 
 +; --------------------------------------------- 
 +
 + 
 +<a name="L18CB"></a>;; <b>SA-DRIVE</b> 
 +L18CB:  LD      A,($5CD6)       ; fetch drive number from D_STR1 
 +        CALL    <A href="#L1532">L1532</a>           ; routine SEL-DRIVE starts motor. 
 + 
 +        IN      A,($EF)         ; read microdrive port. 
 +        AND     $01             ; isolate 'write protect' bit. 
 +        JR      NZ,<A href="#L18D9">L18D9</a>        ; forward, if not low, to STAR-SA 
 + 
 +        RST     20H             ; Shadow Error Restart 
 +        DEFB    $0E             ; 'Drive 'write' protected' 
 + 
 +; --- 
 + 
 +<a name="L18D9"></a>;; <b>STAR-SA</b> 
 +L18D9:  LD      HL,($5CE9)      ; sv HD_0D 
 +        LD      ($5CE4),HL      ; sv D_STR2 
 + 
 +        CALL    <A href="#L1B05">L1B05</a>           ; routine OP-TEMP-M creates a temporary 
 +                                ; microdrive channel, starts motor, and  
 +                                ; attempts to fetch record zero of named file. 
 + 
 +        BIT     0,(IX+$18)      ; test CHFLAG 
 +        JR      NZ,<A href="#L18ED">L18ED</a>        ; forward, with no existing file, to NEW-NAME 
 + 
 +        CALL    <A href="#L138E">L138E</a>           ; routine CLOSE-M2 closes temporary channel 
 +                                ; and stops the motor. 
 + 
 +        RST     20H             ; Shadow Error Restart 
 +        DEFB    $0C             ; Writing to a 'read' file 
 + 
 +; --- 
 + 
 +<a name="L18ED"></a>;; <b>NEW-NAME</b> 
 +L18ED:  SET     2,(IX+$43)      ; update RECFLG signal not a PRINT type file. 
 + 
 +;   <font color=#9900FF>Note.</font> the microdrive motor has been left running by OP-TEMP-M so the next 
 +;   two lines are not necessary.  Redundant code elsewhere suggests that  
 +;   OP-TEMP-M once stopped the drive. 
 + 
 +        LD      A,(IX+$19)      ; fetch drive from CHDRIV. 
 +        CALL    <A href="#L1532">L1532</a>           ; routine SEL-DRIVE stops and then restarts the  
 +                                ; motor. 
 + 
 +        PUSH    IX              ; transfer the channel base address 
 +        POP     HL              ; to the HL register pair. 
 + 
 +        LD      DE,$0052        ; prepare offset to data buffer. 
 +        ADD     HL,DE           ; add to address start of data. 
 +        EX      DE,HL           ; transfer this destination to DE. 
 + 
 +        LD      HL,$5CE6        ; set source to the nine byte header at HD_00 
 +        LD      BC,$0009        ; nine bytes to copy. 
 +        LD      (IX+$0B),     ; update CHBYTE_lo with length saved so far. 
 + 
 +        LDIR                    ; block move the header info into the buffer. 
 + 
 +        PUSH    DE              ; save destination. 
 + 
 +;   Now calculate the number of sectors required using a similar method to 
 +;   the one used for calculating the number of records to load.    
 +;   <font color=#9900FF>Note.</font> there is an error in the calculation as one byte should be subtracted 
 +;   from the total bytes to ensure that there is at least one byte in the EOF 
 +;   record. The next instruction should be to load HL with eight. 
 + 
 +L190B:  LD      HL,$0009        ; start with the nine header bytes. ?? 
 +        LD      BC,($5CE7)      ; fetch data length from HD_0B. 
 +        ADD     HL,BC           ; add to give total size of block. 
 + 
 +        SRL                   ; halve MSB to convert to 512 byte chunks. 
 +        INC                   ; increment to include EOF block. Wrong. 
 + 
 +;   <font color=#9900FF>Note.</font>  
 +;   511  bytes = 502 bytes + 9 header = $01FF, SRL=$00, INC=$01 sectors OK. 
 +;   512  bytes = 503 bytes + 9 header = $0200, SRL=$01, INC=$02 sectors WRONG!! 
 +;   513  bytes = 504 bytes + 9 header = $0201, SRL=$01, INC=$02 sectors OK. 
 + 
 + 
 +        PUSH    HL              ; preserve register H the sector counter. 
 + 
 +        CALL    <A href="#L1D43">L1D43</a>           ; routine FREESECT calculates free sectors on 
 +                                ; cartridge. 
 + 
 +        POP     HL              ; bring back the sector estimate in H. 
 +        LD      A,E             ; load accumulator with actual sectors. 
 +        CP      H               ; compare with estimate 
 +        JR      NC,<A href="#L1921">L1921</a>        ; forward, if equal or greater, to SA-DRI-2 
 + 
 +        RST     20H             ; Shadow Error Restart 
 +        DEFB    $0F             ; 'Microdrive full' 
 + 
 +; --- 
 + 
 +<a name="L1921"></a>;; <b>SA-DRI-2</b> 
 +L1921:  POP     DE              ; bring back destination. 
 +        LD      HL,($5CE4)      ; fetch start from D_STR2 
 +        LD      BC,($5CE7)      ; fetch data length from HD_0B 
 + 
 +<a name="L1929"></a>;; <b>SA-DRI-3</b> 
 +L1929:  LD      A,B             ; test for  
 +        OR      C               ; zero bytes. 
 +        JR      Z,<A href="#L194F">L194F</a>         ; forward, if all chunks saved, to SA-DRI-4 
 + 
 +        LD      A,(IX+$0C)      ; fetch high byte of byte counter from CHBYTE_hi 
 +        CP      $02             ; compare to 2 which would indicate 512 bytes. 
 +        JR      NZ,<A href="#L1943">L1943</a>        ; forward, if less, to SA-DRI-WR 
 + 
 +; a sector is written to microdrive. 
 + 
 +        PUSH    HL              ; preserve start of data. 
 +        PUSH    BC              ; preserve length. 
 + 
 +        CALL    <A href="#L12EE">L12EE</a>           ; routine WRITE-PRC. 
 + 
 +        POP     BC              ; restore length. 
 + 
 +        PUSH    IX              ; transfer the channel base address 
 +        POP     HL              ; to the HL register pair. 
 + 
 +        LD      DE,$0052        ; add offset to 
 +        ADD     HL,DE           ; point to data buffer. 
 +        EX      DE,HL           ; transfer this destination to DE. 
 + 
 +        POP     HL              ; restore the start of data. 
 + 
 +<a name="L1943"></a>;; <b>SA-DRI-WR</b> 
 +L1943:  LDI                     ; transfer one byte at a time decrementing BC 
 +                                ; the total byte counter. 
 + 
 +;   now increment the channel byte counter which started at zero and has a  
 +;   limit of 512 bytes. 
 + 
 +        INC     (IX+$0B)        ; increment CHBYTE_lo 
 +        JR      NZ,<A href="#L1929">L1929</a>        ; back, if not 256, to SA-DRI-3 
 + 
 +        INC     (IX+$0C)        ; increment CHBYTE_hi 
 +        JR      <A href="#L1929">L1929</a>           ; back to SA-DRI-3 to check high byte. 
 + 
 +; --- 
 + 
 +<a name="L194F"></a>;; <b>SA-DRI-4</b> 
 +L194F:  SET     1,(IX+$43)      ; update RECFLG mark this as EOF record. 
 + 
 +        CALL    <A href="#L12EE">L12EE</a>           ; routine WRITE-PRC writes last record in set. 
 + 
 +        LD      A,($5CEF)       ; fetch user-alterable system variable COPIES 
 +        DEC                   ; decrement 
 +        JR      Z,<A href="#L196A">L196A</a>         ; forward, if zero, to END-SA-DR 
 + 
 +        LD      ($5CEF),      ; place decremented value back in COPIES 
 + 
 +        RES     1,(IX+$43)      ; update RECFLG - signal not the EOF record. 
 +        LD      A,$00           ; prepare to start saving at record zero again. 
 +        LD      (IX+$0D),     ; update the channel record counter CHREC. 
 + 
 +        JR      <A href="#L18ED">L18ED</a>           ; back to NEW-NAME 
 + 
 +; --- 
 + 
 +<a name="L196A"></a>;; <b>END-SA-DR</b> 
 +L196A:  XOR                   ; set accumulator to zero. 
 +        CALL    <A href="#L1532">L1532</a>           ; routine SEL-DRIVE stops the motor. 
 + 
 +        JP      <A href="#L119F">L119F</a>           ; jump to DEL-M-BUF 
 + 
 +; ---------------------------------------------------- 
 +; THE <b><font color=#333388>'GET HEADER INFORMATION FROM MICRODRIVE'</font></b> ROUTINE 
 +; ---------------------------------------------------- 
 +; this routine extracts the nine bytes of global header information that 
 +; is prepended to the data saved on microdrive. This relates to the type - 
 +; Basic, Code and length etc. and is the equivalent of a tape header without 
 +; the name which, in contrast, does have to be saved to every record. 
 +; It is obtained therefore from the start of data at record zero. 
 +
 +; <font color=#9900FF>Note.</font> the destination for this data, (program area or variable location),  
 +; has already been calculated and since opening a channel will move this 
 +; destination up in memory, the "Start of data" is transferred to the D_STR2 
 +; location, otherwise used for the second filename during moves, so that its 
 +; value is adjusted by REST-N-AD during OP-TEMP-M. 
 + 
 +<a name="L1971"></a>;; <b>F-M-HEAD</b> 
 +L1971:  LD      HL,($5CE1)      ; copy start of data from D_STR2(+3) 
 +        LD      ($5CE4),HL      ; to dynamic location D_STR2(+6) 
 + 
 +        CALL    <A href="#L1B05">L1B05</a>           ; routine OP-TEMP-M creates a temporary 
 +                                ; microdrive channel, starts motor, and  
 +                                ; fetches record zero of named file. 
 + 
 +        BIT     0,(IX+$18)      ; test CHFLAG for valid first record. 
 +        JR      Z,<A href="#L1982">L1982</a>         ; forward, if OK, to F-HD-2 
 + 
 +        RST     20H             ; Shadow Error Restart 
 +        DEFB    $11             ; 'File not found' 
 + 
 +; --- 
 + 
 +<a name="L1982"></a>;; <b>F-HD-2</b> 
 +L1982:  BIT     2,(IX+$43)      ; test RECFLG is it a print file 
 +        JR      NZ,<A href="#L198A">L198A</a>        ; forward, if not, to F-HD-3 
 + 
 +        RST     20H             ; Shadow Error Restart 
 +        DEFB    $16             ; 'Wrong file type' 
 + 
 +; --- 
 + 
 +<a name="L198A"></a>;; <b>F-HD-3</b> 
 +L198A:  PUSH    IX              ; transfer the channel base address 
 +        POP     HL              ; to the HL register pair. 
 + 
 +        LD      DE,$0052        ; offset to CHDATA 
 +        ADD     HL,DE           ; add to address start of data. 
 +        LD      DE,$5CE6        ; set destination to nine system variables 
 +                                ; starting at location HD_00. 
 +        LD      BC,$0009        ; nine bytes to copy. 
 + 
 +        LDIR                    ; block move to HD_00 - HD_11. 
 + 
 +        RET                     ; return. 
 + 
 +; -------------------------------------------------- 
 +; THE <b><font color=#333388>'LOAD OR VERIFY BLOCK FROM MICRODRIVE'</font></b> ROUTINE 
 +; -------------------------------------------------- 
 +;   This subroutine is called once only from LV-ANY to load a block of code,  
 +;   previously SAVED to a number of sectors, from microdrive. 
 +;   At this stage a temporary channel has already been created and it holds 
 +;   the first 512 byte record containing at the start the nine header bytes. 
 +;   There will be an accurate microdrive map for the drive which has its     
 +;   motor running. 
 +;   The block could be a program, code bytes or an array and the first  
 +;   receiving location is in HL and the length in DE. 
 + 
 +<a name="L199A"></a>;; <b>LV-MCH</b> 
 +L199A:  LD      ($5CE9),HL      ; save start in system variable HD_0D 
 + 
 +;   now directly read the header values at the start of the data buffer. 
 + 
 +        LD      E,(IX+$53)      ; directly read the saved length  
 +        LD      D,(IX+$54)      ; from the data buffer into DE. 
 + 
 +;   now calculate how many 512 byte microdrive records need to be read in 
 +;   by taking the total minus one to ensure an EOF record. 
 +;   e.g. 
 +;   1023 bytes = 1014 bytes + 9 header - 1 = $03FE, SRL=$01, INC=$02 sectors 
 +;   1024 bytes = 1015 bytes + 9 header - 1 = $03FF, SRL=$01, INC=$02 sectors 
 +;   1025 bytes = 1016 bytes + 9 header - 1 = $0400, SRL=$02, INC=$03 sectors 
 + 
 +        LD      HL,$0008        ; add eight in effect +9 for header -1. 
 +        ADD     HL,DE           ; add the program/code length.  
 + 
 +;   the MSB is the number of 256 chunks. 
 + 
 +        SRL                   ; shift right to halve and give 512 byte  
 +                                ; chunks. 
 +        INC                   ; increment to include the extra sector. 
 + 
 +        LD      A,H             ; use accumulator to store record count 
 +        LD      ($5CE7),      ; in the temporary system variable HD_0B 
 + 
 +;   the microdrive map is now saved on the machine stack, for later recall, 
 +;   and at the same time the current map locations are all set to zero. 
 +;   The new map is to be used for records rather than sectors. 
 + 
 +        CALL    <A href="#L1A04">L1A04</a>           ; routine SA-MAP saves the thirty two bytes 
 +                                ; of the map on the machine stack safely  
 +                                ; dipping into the 80 bytes of spare memory. 
 + 
 +;   now, since this is record zero, subtract the nine header bytes from the  
 +;   current record length and put back. 
 + 
 +        LD      DE,$0009        ; 
 + 
 +        LD      L,(IX+$45)      ; RECLEN_lo 
 +        LD      H,(IX+$46)      ; RECLEN_hi 
 + 
 +        OR      A               ; clear carry 
 + 
 +        SBC     HL,DE           ; 
 + 
 +        LD      (IX+$45),     ; RECLEN_lo 
 +        LD      (IX+$46),     ; RECLEN_hi 
 + 
 +;  
 + 
 +        PUSH    IX              ; transfer the channel base address 
 +        POP     HL              ; to the HL register pair. 
 + 
 +        LD      DE,$005B        ; prepare offset $0052 to data and then an 
 +        ADD     HL,DE           ; extra nine bytes. Add to skip the header. 
 + 
 +        LD      DE,($5CE9)      ; set destination from HD_0D 
 + 
 +        JR      <A href="#L19EA">L19EA</a>           ; forward to LOOK-MAP to enter the record 
 +                                ; loading loop at the mid-point as record 
 +                                ; zero is already in the channel. 
 + 
 +; --- 
 + 
 +;   The record loading loop loads records in random order.  Consider that  
 +;   multiple copies of a filename may have been saved so there may be several  
 +;   sectors with the same record number. 
 + 
 +<a name="L19D0"></a>;; <b>USE-REC</b> 
 +L19D0:  CALL    <A href="#L1A5D">L1A5D</a>           ; routine F-REC2 fetches only a header and 
 +                                ; record that matches the name specified  
 +                                ; in CHNAME and only if the map bit is reset 
 +                                ; indicating no sector with this record number 
 +                                ; has already been loaded. 
 + 
 +        LD      A,(IX+$44)      ; re-fetch record number from RECNUM. 
 + 
 +; <font color=#9900FF>Note.</font> the next test is a nonsense as a record zero has already been marked  
 +; so no sector with record zero could be reloaded. 
 + 
 +        OR      A               ; test for a record zero. 
 +        JR      Z,<A href="#L19D0">L19D0</a>         ; back, if so, to USE-REC. 
 + 
 +; now calculate the destination if this 512 byte sector. 
 + 
 +        RLA                     ; double recnum to give 512 byte chunks 
 +        DEC                   ; decrement to adjust for nine bytes of header. 
 +        LD      D,A             ; place in MSB of offset 
 + 
 +        LD      E,$F7           ; set LSB of offset to $00 - $09 for header. 
 +        LD      HL,($5CE9)      ; fetch start of data from HD_0D 
 + 
 +        ADD     HL,DE           ; add to calculate destination for this sector.  
 +        EX      DE,HL           ; transfer destination to DE. 
 + 
 +        PUSH    IX              ; transfer the channel base address 
 +        POP     HL              ; to the HL register pair. 
 + 
 +        LD      BC,$0052        ; prepare offset to start of 512 byte buffer 
 +        ADD     HL,BC           ; add so that HL addresses start of data. 
 + 
 +; -&gt; The mid loop entry point. 
 + 
 +<a name="L19EA"></a>;; <b>LOOK-MAP</b> 
 +L19EA:  EXX                     ; preserve HL and DE by using alternate  
 +                                ; registers. 
 + 
 +        CALL    <A href="#L13BF">L13BF</a>           ; routine CHK-MAP-2 sets HL to the map byte  
 +                                ; and B to the mask. 
 + 
 +; <font color=#9900FF>Note.</font> the routine also resets the zero flag if this record has previously 
 +; been loaded but this is not possible. 
 + 
 +        JR      NZ,<A href="#L19D0">L19D0</a>        ; back, if already loaded, to USE-REC. 
 + 
 +;   since this is the first time for this record mark so that not loaded again. 
 + 
 +        LD      A,(HL)          ; mark the record bit  
 +        OR      B               ; by setting it so that it is not  
 +        LD      (HL),         ; considered for loading again. 
 + 
 +        EXX                     ; restore HL (source) and DE (destination). 
 + 
 +        CALL    <A href="#L1A39">L1A39</a>           ; routine LD-VE-M loads or verifies a 
 +                                ; data record. 
 + 
 +;   now decrement the record count which is beyond reach of IY register. 
 + 
 +        LD      A,($5CE7)       ; fetch count of records to be loaded HD_0B 
 +        DEC                   ; decrement  
 +        LD      ($5CE7),      ; and place back in system variable HD_0B 
 + 
 +        JR      NZ,<A href="#L19D0">L19D0</a>        ; back, if not finished to USE-REC 
 + 
 +;   the block is loaded  
 + 
 +        CALL    <A href="#L1A1E">L1A1E</a>           ; routine RE-MAP restores the true microdrive  
 +                                ; map from the stack. 
 + 
 +        RET                     ; return.  
 + 
 + 
 +; ------------------------------------------ 
 +; THE <b><font color=#333388>'SAVE MICRODRIVE MAP CONTENTS'</font></b> ROUTINE 
 +; ------------------------------------------ 
 +;   This routine saves the sector-mapped microdrive map on the machine stack 
 +;   at the same time setting each of the 32 vacated locations to zero. 
 + 
 +<a name="L1A04"></a>;; <b>SA-MAP</b> 
 +L1A04:  POP     HL              ; drop the return address into HL 
 +        LD      ($5CC9),HL      ; and save in unused system variable SECTOR 
 + 
 +        LD      L,(IX+$1A)      ; fetch address of microdrive map from CHMAP 
 +        LD      H,(IX+$1B)      ; fetch address of microdrive map from CHMAP 
 +        LD      BC,$1000        ; set word counter B to sixteen and C to zero. 
 + 
 +;   now enter a loop stacking two bytes at a time. 
 + 
 +<a name="L1A11"></a>;; <b>SA-MAP-LP</b> 
 +L1A11:  LD      E,(HL)          ; fetch first byte to E.  
 +        LD      (HL),         ; set location to zero. 
 +        INC     HL              ; bump address. 
 +        LD      D,(HL)          ; fetch second byte to D. 
 +        LD      (HL),         ; set location to zero. 
 +        INC     HL              ; bump address. 
 + 
 +        PUSH    DE              ; save DE on machine stack. 
 + 
 +        DJNZ    <A href="#L1A11">L1A11</a>           ; back, for 16 pairs, to SA-MAP-LP 
 + 
 +        LD      HL,($5CC9)      ; restore return address from SECTOR 
 +        JP      (HL)            ; and jump to location. 
 + 
 +; --------------------------------------------- 
 +; THE <b><font color=#333388>'RESTORE MICRODRIVE MAP CONTENTS'</font></b> ROUTINE 
 +; --------------------------------------------- 
 +;   This routine is the opposite of the above and restores the sector-mapped 
 +;   microdrive map from the machine stack back to its original location  
 +;   overwriting the now redundant record-indicating map.  
 + 
 +<a name="L1A1E"></a>;; <b>RE-MAP</b> 
 +L1A1E:  POP     HL              ; drop the subroutine return address. 
 +        LD      ($5CC9),HL      ; store in the multi-purpose variable SECTOR. 
 + 
 +        LD      L,(IX+$1A)      ; fetch address of microdrive map from CHMAP. 
 +        LD      H,(IX+$1B)      ; fetch address of microdrive map from CHMAP. 
 +        LD      DE,$001F        ; thirty one locations are added. 
 +        ADD     HL,DE           ; to address the last location. 
 +        LD      B,$10           ; set the pop counter to sixteen. 
 + 
 +<a name="L1A2E"></a>;; <b>RE-MAP-LP</b> 
 +L1A2E:  POP     DE              ; pop two bytes of the map from the stack. 
 + 
 +        LD      (HL),         ; insert a map byte. 
 +        DEC     HL              ; decrement the address. 
 +        LD      (HL),         ; insert second map byte. 
 +        DEC     HL              ; decrement the address again. 
 + 
 +        DJNZ    <A href="#L1A2E">L1A2E</a>           ; back, sixteen times, to RE-MAP-LP. 
 + 
 +        LD      HL,($5CC9)      ; restore the return address from SECTOR. 
 +        JP      (HL)            ; and jump to address. 
 + 
 +; --------------------- 
 +; THE <b><font color=#333388>'LD-VE-M'</font></b> ROUTINE 
 +; --------------------- 
 +;   The Load or Verify from Microdrive routine. 
 +;   This routine loads or verifies up to 512 bytes of data currently in the 
 +;   microdrive channel data buffer. 
 + 
 +<a name="L1A39"></a>;; <b>LD-VE-M</b> 
 +L1A39:  LD      C,(IX+$45)      ; RECLEN_lo 
 +        LD      B,(IX+$46)      ; RECLEN_hi 
 + 
 +; now test if a VERIFY operation by performing the equivalent of bit 7,(iy+$7c) 
 + 
 +        LD      A,($5CB6)       ; load system variable FLAGS_3 to accumulator. 
 +        BIT     7,            ; test FLAGS_3 value - performing VERIFY ? 
 + 
 +        JR      NZ,<A href="#L1A49">L1A49</a>        ; forward, if so, to VE-M-E 
 + 
 +;   the operation is a LOAD. 
 + 
 +        LDIR                    ; block copy the bytes. 
 +        RET                     ; return. 
 + 
 +; --- 
 + 
 +;   the operation is a VERIFY. 
 + 
 +<a name="L1A49"></a>;; <b>VE-M-E</b> 
 +L1A49:  LD      A,(DE)          ; fetch a byte from the destination. 
 +        CP      (HL)            ; compare to that of source 
 +        JR      NZ,<A href="#L1A55">L1A55</a>        ; forward, with mismatch, to VE-FAIL 
 + 
 +        INC     HL              ; increment source address. 
 +        INC     DE              ; increment destination address. 
 +        DEC     BC              ; decrement byte count. 
 +        LD      A,B             ; test for 
 +        OR      C               ; zero. 
 +        JR      NZ,<A href="#L1A49">L1A49</a>        ; back, if not, to VE-M-E 
 + 
 +        RET                     ; return. 
 + 
 +; --- 
 + 
 +<a name="L1A55"></a>;; <b>VE-FAIL</b> 
 +L1A55:  RST     20H             ; Shadow Error Restart 
 +        DEFB    $15             ; 'Verification has failed' 
 + 
 +; ------------------------------------------ 
 +; THE <b><font color=#333388>'FETCH RECORD FROM MICRODRIVE'</font></b> ROUTINE 
 +; ------------------------------------------ 
 +;   Entered at F-REC2, 
 +;   <font color=#9900FF>Note.</font> the first entry point f-rec1 is unused. 
 + 
 +<a name="L1A57"></a>;; <b>f-rec1</b> 
 +L1A57:  LD      A,(IX+$19)      ; fetch drive number. 
 +        CALL    <A href="#L1532">L1532</a>           ; routine SEL-DRIVE starts motor. 
 + 
 +; --&gt; 
 + 
 +<a name="L1A5D"></a>;; <b>F-REC2</b> 
 +L1A5D:  LD      BC,$04FB        ; Set sector counter to 5 * 255 = 1275 
 +        LD      ($5CC9),BC      ; Update System Variable SECTOR 
 + 
 +<a name="L1A64"></a>;; <b>UNTILFIVE</b> 
 +L1A64:  CALL    <A href="#L1280">L1280</a>           ; routine G-HD-RC fetches the next header and  
 +                                ; matching record to pass tape head. 
 + 
 +        JR      C,<A href="#L1A7B">L1A7B</a>         ; forward, with name mismatch, to F-ERROR 
 + 
 +        JR      Z,<A href="#L1A7B">L1A7B</a>         ; forward, with unused record, to F-ERROR 
 + 
 +        CALL    <A href="#L13BF">L13BF</a>           ; routine CHK-MAP-2  checks RECORD. 
 + 
 +        JR      NZ,<A href="#L1A7B">L1A7B</a>        ; forward, if already loaded, to F-ERROR 
 + 
 +        PUSH    IX              ; transfer the channel base address 
 +        POP     HL              ; to the HL register pair. 
 + 
 +        LD      DE,$0052        ; 
 +        ADD     HL,DE           ; 
 +        CALL    <A href="#L142B">L142B</a>           ; routine CHKS-BUFF 
 +        RET                   ; 
 + 
 + 
 +<a name="L1A7B"></a>;; <b>F-ERROR</b> 
 +L1A7B:  CALL    <A href="#L13F7">L13F7</a>           ; routine DEC-SECT 
 +        JR      NZ,<A href="#L1A64">L1A64</a>        ; back to UNTILFIVE 
 + 
 +        RST     20H             ; Shadow Error Restart 
 +        DEFB    $11             ; File not found 
 + 
 + 
 +; ----------------------------------------- 
 +; THE <b><font color=#333388>'RESTORE ADDRESS OF FILENAME'</font></b> ROUTINE 
 +; ----------------------------------------- 
 +;   This subroutine performs a similar function to the Main ROM POINTERS routine 
 +;   by adjusting the extra system variables that point to filenames within 
 +;   the sliding, dynamic areas. 
 +;   On entry HL points to the start of the New Room and BC holds the number of 
 +;   bytes created. 
 + 
 +<a name="L1A82"></a>;; <b>REST-N-AD</b> 
 +L1A82:  PUSH    HL              ; Preserve HL throughout. 
 + 
 +        PUSH    HL              ; Preserve HL for second call. 
 + 
 +        LD      DE,($5CE4)      ; Fetch D_STR2 - start of 2nd filename. 
 +        CALL    <A href="#L1A9D">L1A9D</a>           ; routine TST-PLACE may adjust fetched value. 
 +        LD      ($5CE4),DE      ; Store in System Variable  D_STR2 
 + 
 +        POP     HL              ; Restore HL for second call. 
 + 
 +        LD      DE,($5CDC)      ; Fetch D_STR1 - start of 1st filename. 
 +        CALL    <A href="#L1A9D">L1A9D</a>           ; routine TST-PLACE 
 +        LD      ($5CDC),DE      ; Store in System Variable D_STR1 
 + 
 +        POP     HL              ; Restore original HL value. 
 + 
 +        RET                     ; return. 
 + 
 +; --------------------------- 
 +; THE <b><font color=#333388>'TEST PLACE'</font></b> SUBROUTINE 
 +; --------------------------- 
 +;   This subroutine is used twice from above to test if the filename address 
 +;   is within the Spectrum's dynamic RAM area. 
 +;   HL = location before new room. 
 +;   DE = address of filename. 
 +;   BC = amount of room just created. 
 + 
 +<a name="L1A9D"></a>;; <b>TST-PLACE</b> 
 +L1A9D:  SCF                     ; adjust for one before. 
 +        SBC     HL,DE           ; subtract filename address from start of room 
 +        RET     NC              ; and if before new room then return. 
 + 
 +        LD      HL,($5C65)      ; fetch STKEND and if the filename is above 
 +        SBC     HL,DE           ; then it is not in dynamic memory. 
 +        RET                   ; 
 + 
 +        EX      DE,HL           ; add the number of bytes created 
 +        ADD     HL,BC           ; to the filename address 
 +        EX      DE,HL           ; to bring it into line. 
 + 
 +        RET                     ; return. 
 + 
 + 
 +; ----------------------------------- 
 +; THE <b><font color=#333388>'CALLS TO THE COMMANDS'</font></b> ROUTINE 
 +; ----------------------------------- 
 +
 + 
 +<a name="L1AAB"></a>;; <b>ERASE-RUN</b> 
 +L1AAB:  CALL    <A href="#L1D79">L1D79</a>           ; routine ERASE 
 +        JR      <A href="#L1AC9">L1AC9</a>           ; forward to ENDC 
 + 
 +; --- 
 + 
 +<a name="L1AB0"></a>;; <b>MOVE-RUN</b> 
 +L1AB0:  CALL    <A href="#L17F5">L17F5</a>           ; routine MOVE 
 +        JR      <A href="#L1AC9">L1AC9</a>           ; forward to ENDC 
 + 
 +; --- 
 + 
 +<a name="L1AB5"></a>;; <b>CAT-RUN</b> 
 +L1AB5:  CALL    <A href="#L1C52">L1C52</a>           ; routine CAT 
 +        JR      <A href="#L1AC9">L1AC9</a>           ; forward to ENDC 
 + 
 +; --- 
 + 
 +<a name="L1ABA"></a>;; <b>FOR-RUN</b> 
 +L1ABA:  CALL    <A href="#L1B5D">L1B5D</a>           ; routine FORMAT 
 +        JR      <A href="#L1AC9">L1AC9</a>           ; forward to ENDC 
 + 
 +; --- 
 + 
 +<a name="L1ABF"></a>;; <b>OP-RUN</b> 
 +L1ABF:  CALL    <A href="#L1ACC">L1ACC</a>           ; routine OP-M-STRM 
 +        JR      <A href="#L1AC9">L1AC9</a>           ; forward to ENDC 
 + 
 +; --- 
 + 
 +<a name="L1AC4"></a>;; <b>SAVE-RUN</b> 
 +L1AC4:  CALL    <A href="#L18CB">L18CB</a>           ; routine SA-DRIVE 
 +        JR      <A href="#L1AC9">L1AC9</a>           ; forward to ENDC 
 + 
 +; --- 
 + 
 +<a name="L1AC9"></a>;; <b>ENDC</b> 
 +L1AC9:  JP      <A href="#L05C1">L05C1</a>           ; jump to END1 
 + 
 +; ------------------------------------------ 
 +; THE <b><font color=#333388>'OPEN A PERMANENT "M" CHANNEL'</font></b> ROUTINE 
 +; ------------------------------------------ 
 +
 + 
 +<a name="L1ACC"></a>;; <b>OP-M-STRM</b> 
 +L1ACC:  LD      A,($5CD8)       ; sv D_STR1 
 +        ADD     A,            ; 
 +        LD      HL,$5C16        ; sv STRMS_00 
 +        LD      E,A             ; 
 +        LD      D,$00           ; 
 +        ADD     HL,DE           ; 
 +        PUSH    HL              ; 
 +        CALL    <A href="#L1B05">L1B05</a>           ; routine OP-TEMP-M creates a temporary 
 +                                ; microdrive channel, starts motor, and  
 +                                ; fetches record zero of named file. 
 +        BIT     0,(IX+$18)      ; CHFLAG 
 +        JR      Z,<A href="#L1AE9">L1AE9</a>         ; forward to MAKE-PERM 
 + 
 +        IN      A,($EF)         ; 
 +        AND     $01             ; isolate write prot. 
 +        JR      NZ,<A href="#L1AE9">L1AE9</a>        ; forward to MAKE-PERM 
 + 
 +        RST     20H             ; Shadow Error Restart 
 +        DEFB    $0E             ; Drive 'write' protected 
 + 
 +; --- 
 + 
 +<a name="L1AE9"></a>;; <b>MAKE-PERM</b> 
 +L1AE9:  RES     7,(IX+$04)      ; channel letter 
 +        XOR                   ; 
 +        CALL    <A href="#L1532">L1532</a>           ; routine SEL-DRIVE 
 +        BIT     0,(IX+$18)      ; CHFLAG 
 +        JR      NZ,<A href="#L1AFF">L1AFF</a>        ; forward to STORE-DSP 
 + 
 +        BIT     2,(IX+$43)      ; RECFLG 
 +        JR      Z,<A href="#L1AFF">L1AFF</a>         ; forward to STORE-DSP 
 + 
 +        RST     20H             ; Shadow Error Restart 
 +        DEFB    $16             ; Wrong file type 
 + 
 +; --- 
 + 
 +<a name="L1AFF"></a>;; <b>STORE-DSP</b> 
 +L1AFF:  EX      DE,HL           ; 
 +        POP     HL              ; 
 +        LD      (HL),         ; 
 +        INC     HL              ; 
 +        LD      (HL),         ; 
 +        RET                     ; 
 + 
 + 
 +; ------------------------------------------ 
 +; THE <b><font color=#333388>'OPEN A TEMPORARY "M" CHANNEL'</font></b> ROUTINE 
 +; ------------------------------------------ 
 +; <font color=#339933>(Hook Code: $22)</font> 
 +
 + 
 +<a name="L1B05"></a>;; <b>OP-TEMP-M</b> 
 +L1B05:  CALL    <A href="#L10A5">L10A5</a>           ; routine SET-T-MCH creates a temporary channel 
 +                                ; using either an existing microdrive map from 
 +                                ; a channel also using this drive or allocating 
 +                                ; a new one initialized to $FF bytes. 
 +                                ; fields CHREC etc. are set to zero. 
 + 
 +        PUSH    HL              ; preserve the offset to this channel from CHANS 
 + 
 +        LD      A,(IX+$19)      ; fetch drive number 1 - 8 from CHDRIV 
 +        CALL    <A href="#L1532">L1532</a>           ; routine SEL-DRIVE starts motor and disables 
 +                                ; interrupts. 
 + 
 +        LD      BC,$0032        ; now set temporary unused  
 +        LD      ($5CC9),BC      ; system variable SECTOR_lo to fifty 
 +                                ; and set SECTOR_hi to zero. 
 + 
 +; now enter a loop  
 + 
 +<a name="L1B16"></a>;; <b>OP-F-L</b> 
 +L1B16:  CALL    <A href="#L1280">L1280</a>           ; routine G-HD-RC fetches any header and  
 +                                ; matching record 
 + 
 +        PUSH    AF              ; preserve return status flags. 
 + 
 +; maintain the 'maximum sectors to visit' so only one rotation of tape occurs. 
 + 
 +        LD      A,(IX+$29)      ; fetch sector from HDNUMB 
 +        ADD     A,$03           ; add 3 
 +        LD      HL,$5CC9        ; address current (max+3) in SECTOR_lo 
 +        CP      (HL)            ; compare 
 +        JR      C,<A href="#L1B26">L1B26</a>         ; forward, if less, to OP-F-X 
 + 
 +        LD      (HL),         ; update with new max sectors to visit. 
 + 
 +<a name="L1B26"></a>;; <b>OP-F-X</b> 
 +L1B26:  POP     AF              ; restore status flags. 
 + 
 +        JR      C,<A href="#L1B49">L1B49</a>         ; forward, with no name match, to OP-F-4 
 + 
 +        JR      Z,<A href="#L1B46">L1B46</a>         ; forward, if unused, to OP-F-3 
 +                                ; to reset map bit. 
 + 
 +; the fetched record is one from the file named in CHNAME 
 + 
 +        RES     0,(IX+$18)      ; update CHFLAG to indicate success. 
 + 
 +        LD      A,(IX+$44)      ; fetch the record number within file RECNUM 
 +        OR      A               ; test for zero - first record. 
 +        JR      NZ,<A href="#L1B41">L1B41</a>        ; forward, if not, to OP-F-2 
 + 
 +        PUSH    IX              ; transfer the channel base address 
 +        POP     HL              ; to the HL register pair. 
 + 
 +        LD      DE,$0052        ; prepare offset to data and 
 +        ADD     HL,DE           ; add to address start of the 512 byte buffer 
 + 
 +        CALL    <A href="#L142B">L142B</a>           ; routine CHKS-BUFF checks that checksum agrees. 
 +        JR      Z,<A href="#L1B5B">L1B5B</a>         ; forward, if OK, to DP-F-5 
 + 
 +<a name="L1B41"></a>;; <b>OP-F-2</b> 
 +L1B41:  CALL    <A href="#L1258">L1258</a>           ; routine GET-R-2 repeatedly calls the  
 +                                ; subroutine G-HD-RC (as at start of loop) 
 +                                ; until the validated record matching CHREC  
 +                                ; (zero) is loaded. 
 + 
 +        JR      <A href="#L1B5B">L1B5B</a>           ; forward, with success, to DP-F-5. 
 + 
 +; --- 
 + 
 +<a name="L1B46"></a>;; <b>OP-F-3</b> 
 +L1B46:  CALL    <A href="#L13E3">L13E3</a>           ; routine RES-B-MAP resets bit for unused  
 +                                ; sectors. 
 + 
 +; the branch was here  
 + 
 +<a name="L1B49"></a>;; <b>OP-F-4</b> 
 +L1B49:  LD      HL,$5CCA        ; address visited sector count SECTOR_hi 
 + 
 +        LD      A,(HL)          ; fetch sector counter. 
 +        INC                   ; increment 
 +        LD      (HL),         ; and put back in SECTOR_hi. 
 +        DEC     HL              ; address the max sector value. 
 +        CP      (HL)            ; compare. 
 +        JR      C,<A href="#L1B16">L1B16</a>         ; back, if less than one revolution, to OP-F-L 
 + 
 +; else a full revolution occurred without finding the record. 
 + 
 +        RES     1,(IX+$43)      ; RECFLG 
 +        RES     2,(IX+$43)      ; RECFLG 
 + 
 +; the branch was here with record zero of named file. 
 + 
 +<a name="L1B5B"></a>;; <b>DP-F-5</b> 
 +L1B5B:  POP     HL              ; restore the offset from CHANS. 
 + 
 +        RET                     ; return. 
 + 
 +; -------------------------------- 
 +; THE <b><font color=#333388>'FORMAT "M" COMMAND'</font></b> ROUTINE 
 +; -------------------------------- 
 +; e.g. FORMAT "m";1;"demos" 
 + 
 + 
 +<a name="L1B5D"></a>;; <b>FORMAT</b> 
 +L1B5D:  CALL    <A href="#L10A5">L10A5</a>           ; routine SET-T-MCH creates a temporary  
 +                                ; microdrive channel with name of cartridge. 
 + 
 +        LD      A,(IX+$19)      ; fetch drive number from CHDRIV 
 +        CALL    <A href="#L1565">L1565</a>           ; routine SW-MOTOR starts the motor. 
 + 
 +        LD      BC,$32C8        ; decimal 1300 
 +        CALL    <A href="#L1652">L1652</a>           ; routine DELAY-BC 
 + 
 +        DI                      ; Disable Interrupts. 
 + 
 +        IN      A,($EF)         ; read microdrive port. 
 +        AND     $01             ; isolate write prot. bit. 
 +        JR      NZ,<A href="#L1B75">L1B75</a>        ; forward, if not low, to FORMAT-1 
 + 
 +        RST     20H             ; Shadow Error Restart 
 +        DEFB    $0E             ; Drive 'write' protected 
 + 
 +; --- 
 + 
 +<a name="L1B75"></a>;; <b>FORMAT-1</b> 
 +L1B75:  LD      A,$E6           ; enable writing. 
 +        OUT     ($EF),        ; update microdrive port. 
 + 
 +        LD      BC,$00FF        ; assume 255 sectors will fit on a tape. 
 +        LD      ($5CC9),BC      ; set system variable SECTOR. 
 + 
 +        PUSH    IX              ; transfer the channel base address 
 +        POP     HL              ; to the HL register pair. 
 + 
 +        LD      DE,$002C        ; offset to HDNAME 
 +        ADD     HL,DE           ; 
 +        EX      DE,HL           ; make destination HDNAME 
 +        LD      HL,$FFE2        ; 
 +        ADD     HL,DE           ; make source CHNAME 
 + 
 +        LD      BC,$000A        ; ten bytes to copy. 
 +        LDIR                    ; copy - C is now zero. 
 + 
 +; now prepare an 'unusable' record. 
 + 
 +        XOR                   ; make accumulator zero. 
 + 
 +        LD      (IX+$47),     ; set first character of RECNAM to zero. 
 +        SET     0,(IX+$28)      ; mark HDFLAG indicate a header. 
 +        RES     0,(IX+$43)      ; mark RECFLG indicate a record. 
 +        SET     1,(IX+$43)      ; mark RECFLG indicate an EOF record. 
 + 
 +        PUSH    IX              ; transfer the channel base address 
 +        POP     DE              ; to the DE register pair for a change. 
 + 
 +        LD      HL,$0043        ; offset to RECFLG - start of record descriptor. 
 +        ADD     HL,DE           ; add offset to start of record descriptor. 
 + 
 +        CALL    <A href="#L1426">L1426</a>           ; routine CHKS-HD-R inserts 14 byte checksum. 
 + 
 +;   Now enter a loop to write the blocks to the cartridge 
 + 
 +<a name="L1BAB"></a>;; <b>WR-F-TEST</b> 
 +L1BAB:  CALL    <A href="#L13F7">L13F7</a>           ; routine DEC-SECT decrements sector originally 
 +                                ; set to $FF 
 +        JR      Z,<A href="#L1BDF">L1BDF</a>         ; forward, if BC is zero, to TEST-SCT  -&gt; 
 + 
 +        LD      (IX+$29),     ; insert reduced sector number in HDNUMB 
 + 
 +        PUSH    IX              ; transfer the base channel address 
 +        POP     HL              ; to the HL register pair. 
 + 
 +        LD      DE,<A href="#L0028">L0028</a>        ; offset to the header 
 +        ADD     HL,DE           ; add to address HDFLAG. 
 + 
 +        CALL    <A href="#L1426">L1426</a>           ; routine CHKS-HD-R inserts 14 byte checksum 
 +                                ; preserving the HL value. 
 + 
 +        LD      DE,$FFF4        ; subtract twelve  
 +        ADD     HL,DE           ; to address the header PREAMBLE. 
 + 
 +        CALL    <A href="#L15AD">L15AD</a>           ; routine OUT-M-HD writes the header to tape. 
 + 
 +        LD      BC,$01B2        ; set timer for gap - 434 decimal. 
 +        CALL    <A href="#L1652">L1652</a>           ; routine DELAY-BC 
 + 
 +        PUSH    IX              ; transfer start of channel 
 +        POP     HL              ; to HL register pair. 
 + 
 +        LD      DE,$0037        ; adjust HL to point to PREAMBLE at 
 +        ADD     HL,DE           ; start of record descriptor. 
 +        CALL    <A href="#L16AF">L16AF</a>           ; routine WR-BLK writes record to tape. 
 + 
 +        LD      BC,$0100        ; a short delay. 
 +        CALL    <A href="#L1652">L1652</a>           ; routine DELAY-BC 
 + 
 +        CALL    <A href="#L163E">L163E</a>           ; routine TEST-BRK 
 + 
 +        JR      <A href="#L1BAB">L1BAB</a>           ; loop back to WR-F-TEST for sectors 254 - 1. 
 + 
 +; --- 
 + 
 +; -&gt; the branch was to here when all sectors from 254 down to 1 have been  
 +;    written. 
 + 
 +<a name="L1BDF"></a>;; <b>TEST-SCT</b> 
 +L1BDF:  LD      BC,$0087        ; use value 35 decimal. 
 +        CALL    <A href="#L1652">L1652</a>           ; routine DELAY-BC 
 + 
 +        LD      A,$EE           ; signal disable writing. 
 +        OUT     ($EF),        ; output to microdrive port. 
 + 
 +        LD      A,(IX+$19)      ; select drive number from CHDRIV. 
 +        CALL    <A href="#L1532">L1532</a>           ; routine SEL-DRIVE. 
 + 
 +        LD      BC,$0032        ; set max sector to fifty, read sectors to zero. 
 +        LD      ($5CC9),BC      ; insert both values in SECTOR 
 + 
 +<a name="L1BF6"></a>;; <b>CHK-SCT</b> 
 +L1BF6:  CALL    <A href="#L13A9">L13A9</a>           ; routine GET-M-HD2 reads the next valid header 
 +                                ; to pass the tape head. 
 +        LD      A,(IX+$29)      ; fetch the unique sector number from HDNUMB 
 +        ADD     A,$03           ; add three to value. 
 +        LD      HL,$5CC9        ; address system variable SECTOR 
 +        CP      (HL)            ; and compare to total of sectors to visit. 
 +        JR      C,<A href="#L1C05">L1C05</a>         ; forward if less to CHK-SCT2 
 + 
 +        LD      (HL),         ; else insert new value for sectors to visit. 
 + 
 +<a name="L1C05"></a>;; <b>CHK-SCT2</b> 
 +L1C05:  CALL    <A href="#L13C4">L13C4</a>           ; routine CHECK-MAP checks if sector is free  
 +                                ; on the microdrive map. 
 +        JR      Z,<A href="#L1C1E">L1C1E</a>         ; forward, if so, to CHK-NSECT 
 + 
 +        PUSH    IX              ; transfer channel base address 
 +        POP     HL              ; to the HL register pair. 
 + 
 +        LD      DE,$0043        ; offset to the start of record descriptor. 
 +        ADD     HL,DE           ; add to address RECFLG. 
 + 
 +        CALL    <A href="#L165A">L165A</a>           ; routine READ-BLK reads in a block. 
 + 
 +        JR      NZ,<A href="#L1C1E">L1C1E</a>        ; forward, with bad read, to CHK-NSECT 
 +                                ; leaving map bit set. 
 + 
 +        CALL    <A href="#L1426">L1426</a>           ; routine CHKS-HD-R check the header checksum 
 +        JR      NZ,<A href="#L1C1E">L1C1E</a>        ; forward, with error, to CHK-NSECT 
 + 
 +        CALL    <A href="#L13E3">L13E3</a>           ; routine RES-B-MAP resets the map bit marking 
 +                                ; the sector as usable. 
 + 
 +<a name="L1C1E"></a>;; <b>CHK-NSECT</b> 
 +L1C1E:  LD      HL,$5CCA        ; address SECTOR_hi the visited sector counter. 
 +        LD      A,(HL)          ; fetch the value. 
 +        INC                   ; increment 
 +        LD      (HL),         ; and place back. 
 + 
 +        DEC     HL              ; decrement to address max sectors to visit. 
 +        CP      (HL)            ; compare counter to limit. 
 +        JR      C,<A href="#L1BF6">L1BF6</a>         ; back, if counter is less, to CHK-SCT 
 + 
 +        LD      L,(IX+$1A)      ; load L from CHMAP_lo 
 +        LD      H,(IX+$1B)      ; load H from CHMAP_hi 
 + 
 +;   Register HL now addresses the microdrive maps which at this stage have 
 +;   sectors 0 and 255 marked as unusable. If as is usual, the lower numbered 
 +;   sectors have overwritten the higher numbered sectors then typically  
 +;   the top seventy sectors, or so, will be marked as unusable though not on an  
 +;   emulated machine which at this stage will only have 0 and 255 marked  
 +;   unusable. On a real machine the splice will show up as an unusable sector 
 +;   and there may be some other sectors unusable due to dirt on the recording  
 +;   film. 
 +;   What happens next is unique to this ROM and is no doubt due to extensive  
 +;   testing and analysis of the microdrives by Sinclair Research. 
 +;   Microdrive sectors are encountered in descending order, as they are  
 +;   written, and the following routine marks any sector following a bad sector  
 +;   as bad also.  One can conclude that Sinclair Research's test programme  
 +;   revealed that the first sectors to fail were those adjacent to contaminated 
 +;   or damaged sectors.   
 +;   This perhaps explains why my use of the microdrives with ROM 2 has been  
 +;   more reliable than early reviews, no doubt with ROM 1, suggested. 
 + 
 +        LD      DE,$001F        ; add thirty one to start at the end of the map 
 +        ADD     HL,DE           ; - the byte that refers to sector 255. 
 +        LD      B,$20           ; count the thirty two bytes of a map. 
 + 
 +        SCF                     ; set carry flag to ensure that sector 255  
 +                                ; is unusable - but it is already marked so ?? 
 + 
 +<a name="L1C35"></a>;; <b>PREP-MARK</b> 
 +L1C35:  LD      A,(HL)          ; fetch a byte representing eight sectors. 
 + 
 +        LD      C,A             ; and store it in C - <font color=#9900FF>Note.</font> unnecessary. 
 + 
 +        RRA                     ; rotate right accumulator  C-&gt;76543210-&gt;
 + 
 +        OR      C               ; combine with original value. Why not OR (HL) ? 
 + 
 +        LD      (HL),         ; store the modified byte back in the map. 
 + 
 +        DEC     HL              ; point to the next byte for lower-numbered  
 +                                ; sectors. 
 + 
 +L1C3B:  DJNZ    <A href="#L1C35">L1C35</a>           ; loop back to PREP-MARK for all 32 map bytes. 
 + 
 +;   <font color=#9900FF>Note.</font> the above routine is untidy.  There is no need to set the carry flag  
 +;   and no need to store the original value in C.  While it achieves it's aims, 
 +;   if sector one is bad it has no effect on the next sector to be encountered. 
 +;   That would be hard to implement but the first sector that is marked bad, 
 +;   the highest numbered sector, is marked so solely because it is adjacent to  
 +;   the overwritten section. 
 + 
 +;   <font color=#9900FF>Note.</font> from details of addresses Andrew Pennell gave in the magazine "Your  
 +;   Sinclair" it can be deduced that the unpublished ROM 3 had two extra  
 +;   instruction bytes at this point and together with a cleanup, this may have  
 +;   addressed the above issue. 
 + 
 +;   Now prepare to overwrite the unusable sectors (which are mapped as usable) 
 +;   with record descriptors which are usable. 
 + 
 +        CALL    <A href="#L1E49">L1E49</a>           ; routine IN-CHK marks the channel record  
 +                                ; descriptor fields as usable by blanking 
 +                                ; both RECFLG and RECLEN and then inserting 
 +                                ; the descriptor checksum. 
 + 
 +;   A loop is now entered to write usable datablocks to every sector indicated 
 +;   as usable in the microdrive map. 
 + 
 +<a name="L1C40"></a>;; <b>MARK-FREE</b> 
 +L1C40:  CALL    <A href="#L1349">L1349</a>           ; routine CHK-FULL checks if there is still a 
 +                                ; usable sector on the cartridge. 
 +        JR      NZ,<A href="#L1C4D">L1C4D</a>        ; forward, if so, to MK-BLK. 
 + 
 +;   The FORMAT operation is now complete. 
 + 
 +        XOR                   ; select no motor 
 +        CALL    <A href="#L1532">L1532</a>           ; routine SEL-DRIVE stops the microdrive motor. 
 + 
 +        CALL    <A href="#L119F">L119F</a>           ; routine DEL-M-BUF deletes the microdrive  
 +                                ; buffer and the microdrive map. 
 + 
 +        RET                     ; return.                          &gt;&gt;&gt;&gt;&gt;&gt;&gt; 
 + 
 +; --- 
 + 
 +<a name="L1C4D"></a>;; <b>MK-BLK</b> 
 +L1C4D:  CALL    <A href="#L135A">L135A</a>           ; routine SEND-BLK writes block to microdrive 
 +                                ; cartridge as indicated by the microdrive map  
 +                                ; which is then updated by the routine. 
 + 
 +        JR      <A href="#L1C40">L1C40</a>           ; loop back to MARK-FREE 
 + 
 + 
 +; ------------------------- 
 +; THE <b><font color=#333388>'CAT COMMAND'</font></b> ROUTINE 
 +; ------------------------- 
 +
 + 
 +<a name="L1C52"></a>;; <b>CAT</b> 
 +L1C52:  LD      A,($5CD8)       ; fetch output stream from S_STR1 
 + 
 +        RST     10H             ; CALBAS 
 +        DEFW    $1601           ; main CHAN-OPEN 
 + 
 +        CALL    <A href="#L10A5">L10A5</a>           ; routine SET-T-MCH sets a temporary channel. 
 + 
 +        LD      A,(IX+$19)      ; fetch drive number from CHDRIV. 
 +        CALL    <A href="#L1532">L1532</a>           ; routine SEL-DRIVE starts the motor. 
 + 
 +        LD      BC,$0032        ; set maximum sector to 50 and initialize 
 +                                ; value of sectors read to zero. 
 +        LD      ($5CC9),BC      ; update system variable SECTOR 
 + 
 +;   On the original Interface 1 ROM operations like CAT and ERASE were quite  
 +;   slow as the routines assumed the theoretical maximum number of sectors was  
 +;   256.  In reality, the maximum number of sectors on a microdrive is  
 +;   approximately 180, so the original routines spent the last 3 seconds  
 +;   reading about 75 sectors for the second time.  The improved algorithm above 
 +;   is to keep a record of the maximum sector + 3 and when the number of  
 +;   visited sectors is equal to this number then a complete revolution of the  
 +;   tape has been made and the operation can cease. The overhead of three is  
 +;   to ensure that bad sectors or the tape splice do not cause the operation to 
 +;   end prematurely. 
 +;   Happily, this algorithm also works with emulators which usually provide the 
 +;   full 256 sectors. 
 + 
 +<a name="L1C68"></a>;; <b>CAT-LP</b> 
 +L1C68:  CALL    <A href="#L13A9">L13A9</a>           ; routine GET-M-HD2 reads in 14 byte header. 
 + 
 +        LD      A,(IX+$29)      ; fetch value of sector from HDNUMB 
 + 
 +        ADD     A,$03           ; add 3 to value. 
 + 
 +        LD      HL,$5CC9        ; address system variable SECTOR_lo 
 +        CP      (HL)            ; compare to contents 
 +        JR      C,<A href="#L1C77">L1C77</a>         ; forward if A is less to CAT-LP-E 
 + 
 +        LD      (HL),         ; else update SECTOR_lo with higher value. 
 + 
 +<a name="L1C77"></a>;; <b>CAT-LP-E</b> 
 +L1C77:  CALL    <A href="#L1E5E">L1E5E</a>           ; routine G-RDES loads only a 
 +                                ; 14 byte record descriptor. 
 +        JR      NZ,<A href="#L1C68">L1C68</a>        ; back, with error or mismatch, to CAT-LP 
 + 
 +; a record can be considered in use if either the RECLEN is maximum $0200 or 
 +; the RECFLG indicates that it is the seldom full EOF record. 
 + 
 +        LD      A,(IX+$43)      ; RECFLG 
 +        OR      (IX+$46)        ; RECLEN_hi 
 +        AND     $02             ; 
 +        JR      NZ,<A href="#L1C8B">L1C8B</a>        ; forward, if used, to IN-NAME 
 + 
 +; else mark sector free in microdrive map and find next sector. 
 + 
 +        CALL    <A href="#L13E3">L13E3</a>           ; routine RES-B-MAP 
 +        JR      <A href="#L1CF4">L1CF4</a>           ; forward to F-N-SCT 
 + 
 +; a name is to be inserted in the 512 byte data buffer workspace, if it is not 
 +; there already. Secret files are not listed. 
 + 
 +<a name="L1C8B"></a>;; <b>IN-NAME</b> 
 +L1C8B:  LD      A,(IX+$47)      ; take first character of RECNAM 
 +        OR      A               ; test for zero. 
 +        JR      Z,<A href="#L1CF4">L1CF4</a>         ; forward, if CHR$ 0, to F-N-SCT 
 + 
 +        PUSH    IX              ; transfer base address 
 +        POP     HL              ; to HL register. 
 + 
 +        LD      DE,$0052        ; offset to start of data buffer. 
 +        ADD     HL,DE           ; add to address names. 
 +        LD      DE,$000A        ; set DE to ten, the length of a name. 
 +        LD      B,$00           ; set high byte to zero. 
 +        LD      C,(IX+$0D)      ; fetch name total from CHREC initially zero. 
 + 
 +<a name="L1CA0"></a>;; <b>SE-NAME</b> 
 +L1CA0:  LD      A,C             ; test name count for zero 
 +        OR      A               ; 
 +        JR      Z,<A href="#L1CDA">L1CDA</a>         ; forward, with first name, to INS-NAME 
 + 
 +        PUSH    HL              ; save buffer address. 
 +        PUSH    IX              ; save channel base address. 
 +        PUSH    BC              ; save name total. 
 + 
 +        LD      B,$0A           ; set character counter to ten. 
 + 
 +<a name="L1CAA"></a>;; <b>T-NA-1</b> 
 +L1CAA:  LD      A,(HL)          ; take letter of buffered name. 
 +        CP      (IX+$47)        ; compare to that in RECNAM 
 +        JR      NZ,<A href="#L1CB5">L1CB5</a>        ; forward, with mismatch, to T-NA-2 
 + 
 +        INC     HL              ; increment  
 +        INC     IX              ; both pointers. 
 +        DJNZ    <A href="#L1CAA">L1CAA</a>           ; back, for all ten, to T-NA-1 
 + 
 + 
 +<a name="L1CB5"></a>;; <b>T-NA-2</b> 
 +L1CB5:  POP     BC              ; restore 
 +        POP     IX              ; all 
 +        POP     HL              ; pointers. 
 + 
 +; if all ten characters match then find next sector. 
 + 
 +        JR      Z,<A href="#L1CF4">L1CF4</a>         ; forward to F-N-SCT 
 + 
 +; if buffered name is higher than new name then re-order to create a slot. 
 + 
 +        JR      NC,<A href="#L1CC1">L1CC1</a>        ; forward to ORD-NAM 
 + 
 +; else add ten to buffer address and compare with following name performing 
 +; a simple insert if the end of the list is reached. 
 + 
 +        ADD     HL,DE           ; add ten to address. 
 +        DEC                   ; decrement name counter. 
 +        JR      <A href="#L1CA0">L1CA0</a>           ; back to SE-NAME 
 + 
 +; --- 
 + 
 + 
 +<a name="L1CC1"></a>;; <b>ORD-NAM</b> 
 +L1CC1:  PUSH    HL              ; save pointer to start of name slot. 
 +        PUSH    DE              ; save the value ten. 
 +        PUSH    BC              ; save the buffered name counter. 
 + 
 +        PUSH    HL              ; save address of name slot again. 
 +        SLA                   ; double name count. 
 +        LD      H,B             ; set H to zero. 
 +        LD      L,C             ; HL = 2 * count 
 +        ADD     HL,BC           ; HL = 4 * count 
 +        ADD     HL,BC           ; HL = 6 * count        <font color=#9900FF>Note.</font> add hl,hl doubles. 
 +        ADD     HL,BC           ; HL = 8 * count        c.f. Main ROM 
 +        ADD     HL,BC           ; HL = 10 * count 
 + 
 +        LD      B,H             ; transfer number of bytes 
 +        LD      C,L             ; to be moved to BC register. 
 + 
 +        POP     HL              ; restore address of insertion point. 
 +        DEC     HL              ; decrement and then add 
 +        ADD     HL,BC           ; bytes to be moved to point to end of block. 
 + 
 +        EX      DE,HL           ; now make DE 
 +        ADD     HL,DE           ; the destination 
 +        EX      DE,HL           ; ten bytes higher. 
 + 
 +        LDDR                    ; slide the block of higher names upwards. 
 + 
 +        POP     BC              ; restore name count. 
 +        POP     DE              ; restore ten value. 
 +        POP     HL              ; restore insertion point. 
 + 
 +<a name="L1CDA"></a>;; <b>INS-NAME</b> 
 +L1CDA:  PUSH    IX              ; save channel base address. 
 +        LD      B,$0A           ; set character count to ten. 
 + 
 +<a name="L1CDE"></a>;; <b>MOVE-NA</b> 
 +L1CDE:  LD      A,(IX+$47)      ; fetch a character from new name at RECNAM 
 +        LD      (HL),         ; insert into buffer. 
 +        INC     IX              ; increment both 
 +        INC     HL              ; pointers. 
 +        DJNZ    <A href="#L1CDE">L1CDE</a>           ; loop back to MOVE-NA 
 + 
 +        POP     IX              ; restore channel base address. 
 + 
 +        LD      A,(IX+$0D)      ; fetch count of names from CHREC 
 +        INC                   ; increment 
 +        LD      (IX+$0D),     ; and store back in CHREC 
 + 
 +        CP      $32             ; compare to maximum of 50. 
 +        JR      Z,<A href="#L1CFF">L1CFF</a>         ; forward, if buffer filled, to BF-FILLED 
 + 
 + 
 +<a name="L1CF4"></a>;; <b>F-N-SCT</b> 
 +L1CF4:  LD      HL,$5CCA        ; sv SECTOR_hi 
 +        LD      A,(HL)          ; fetch actual count of used sectors. 
 +        INC                   ; and increment. 
 +        LD      (HL),         ; update SECTOR_hi 
 +        DEC     HL              ; address system variable SECTOR_lo 
 +        CP      (HL)            ; compare  
 +        JP      C,<A href="#L1C68">L1C68</a>         ; jump to CAT-LP 
 + 
 +<a name="L1CFF"></a>;; <b>BF-FILLED</b> 
 +L1CFF:  PUSH    IX              ; 
 + 
 +        XOR                   ; clear accumulator 
 +        CALL    <A href="#L1532">L1532</a>           ; routine SEL-DRIVE stops the motor. 
 + 
 +        PUSH    IX              ; transfer the channel base address 
 +        POP     HL              ; to the HL register pair. 
 + 
 +        LD      DE,$002C        ; offset to cartridge name HDNAME. 
 +        ADD     HL,DE           ; add the offset to address the name. 
 + 
 +        CALL    <A href="#L1D5B">L1D5B</a>           ; routine PRNAME prints name and a carriage  
 +                                ; return. 
 + 
 +        LD      A,$0D           ; prepare an extra carriage return. 
 +        CALL    <A href="#L1D71">L1D71</a>           ; routine PRCHAR outputs it. 
 + 
 +        PUSH    IX              ; 
 +        POP     HL              ; 
 + 
 +        LD      DE,$0052        ; offset to CHDATA - the 512 byte data buffer. 
 +        ADD     HL,DE           ; add to address list of up to fifty names. 
 + 
 +        LD      B,(IX+$0D)      ; load B with count of names from CHREC 
 +        LD      A,B             ; test for 
 +        OR      A               ; zero. 
 +        JR      Z,<A href="#L1D27">L1D27</a>         ; forward, if so, to NONAMES 
 + 
 + 
 +<a name="L1D22"></a>;; <b>OT-NAMS</b> 
 +L1D22:  CALL    <A href="#L1D5B">L1D5B</a>           ; routine PRNAME 
 +        DJNZ    <A href="#L1D22">L1D22</a>           ; loop back to OT-NAMS 
 + 
 + 
 +<a name="L1D27"></a>;; <b>NONAMES</b> 
 +L1D27:  CALL    <A href="#L1D43">L1D43</a>           ; routine FREESECT 
 + 
 +        LD      A,E             ; 
 +        SRL                   ; 
 + 
 +        RST     10H             ; CALBAS 
 +        DEFW    $2D28           ; main STACK-A 
 + 
 +        LD      A,$0D           ; 
 +        CALL    <A href="#L1D71">L1D71</a>           ; routine PRCHAR 
 + 
 +        RST     10H             ; CALBAS 
 +        DEFW    $2DE3           ; main PRINT-FP 
 + 
 +        LD      A,$0D           ; 
 +        CALL    <A href="#L1D71">L1D71</a>           ; routine PRCHAR 
 + 
 +        POP     IX              ; 
 + 
 +        CALL    <A href="#L119F">L119F</a>           ; routine DEL-M-BUF 
 + 
 +        RET                     ; return. 
 + 
 + 
 +; ---------------------- 
 +; THE <b><font color=#333388>'FREESECT'</font></b> ROUTINE 
 +; ---------------------- 
 +;   This routine is called from SAVE and CAT to calculate the number of free  
 +;   sectors that are present on a microdrive from the map information. 
 +;   The count of free sectors is returned in the E register. 
 + 
 +<a name="L1D43"></a>;; <b>FREESECT</b> 
 +L1D43:  LD      L,(IX+$1A)      ; address of microdrive map. 
 +        LD      H,(IX+$1B)      ; for channel transferred to HL. 
 + 
 +        LD      E,$00           ; initialize sector count to zero. 
 +        LD      C,$20           ; there are thirty two bytes to examine. 
 + 
 +<a name="L1D4D"></a>;; <b>FR-SC-LP</b> 
 +L1D4D:  LD      A,(HL)          ; fetch a byte from the map. 
 +        INC     HL              ; address next map location. 
 + 
 +        LD      B,$08           ; count eight bits. 
 + 
 +<a name="L1D51"></a>;; <b>FR-S-LPB</b> 
 +L1D51:  RRA                     ; rotate right. 
 +        JR      C,<A href="#L1D55">L1D55</a>         ; forward, with carry, to FR-S-RES. 
 + 
 +        INC                   ; increment the free sector count. 
 + 
 +<a name="L1D55"></a>;; <b>FR-S-RES</b> 
 +L1D55:  DJNZ    <A href="#L1D51">L1D51</a>           ; loop back for all eight bits to FR-S-LPB. 
 + 
 +        DEC                   ; decrement byte count. 
 +        JR      NZ,<A href="#L1D4D">L1D4D</a>        ; loop back for thirty two bytes to FR-SC-LP. 
 + 
 +        RET                     ; return. 
 + 
 +; -------------------- 
 +; THE <b><font color=#333388>'PRNAME'</font></b> ROUTINE 
 +; -------------------- 
 +;   This routine outputs a ten character name, followed by a carriage return, 
 +;   and is used by the CAT command to first print the cartridge name and then  
 +;   the filenames on the cartridge.   
 +;   <font color=#9900FF>Note.</font> For a routine that can output to any stream, it seems straightforward 
 +;   until one notices the call to TEMPS at the end.  This applies the permanent  
 +;   colour screen attributes to the temporary set and has been placed within  
 +;   the routine as a security measure to ensure that if the cartridge name  
 +;   or filename contains a string of colour control codes that render filenames 
 +;   invisible then their effect does not last beyond the current name. 
 +
 +;   On the other hand, colour control codes can be used in the cartridge name 
 +;   without affecting the cartridge contents display. 
 + 
 +<a name="L1D5B"></a>;; <b>PRNAME</b> 
 +L1D5B:  PUSH    BC              ; preserve name count. 
 + 
 +        LD      B,$0A           ; ten characters per name. 
 + 
 +<a name="L1D5E"></a>;; <b>PRNM-LP</b> 
 +L1D5E:  LD      A,(HL)          ; fetch a character. 
 + 
 +        CALL    <A href="#L1D71">L1D71</a>           ; routine PRCHAR 
 + 
 +        INC     HL              ; point to next character. 
 +        DJNZ    <A href="#L1D5E">L1D5E</a>           ; loop back for all ten to PRNM-LP 
 + 
 +        LD      A,$0D           ; prepare a carriage return. 
 +        CALL    <A href="#L1D71">L1D71</a>           ; routine PRCHAR 
 + 
 +        PUSH    HL              ; preserve character address. 
 + 
 +        RST     10H             ; CALBAS 
 +        DEFW    $0D4D           ; main TEMPS restores temporary colours from 
 +                                ; the permanent colours after each name. 
 + 
 +        POP     HL              ; restore character address. 
 +        POP     BC              ; restore name count. 
 + 
 +        RET                     ; return. 
 + 
 + 
 +; -------------------- 
 +; THE <b><font color=#333388>'PRCHAR'</font></b> ROUTINE 
 +; -------------------- 
 +;   The PRINT CHARACTER routine utilizes the output restart in the main ROM 
 +;   which outputs to any stream and so a stream such as the "T" channel 
 +;   could be sent output. The IX register has therefore to be preserved. 
 + 
 +<a name="L1D71"></a>;; <b>PRCHAR</b> 
 +L1D71:  PUSH    IX              ; preserve this ad hoc channel address. 
 + 
 +        RST     10H             ; CALBAS 
 +        DEFW    $0010           ; main PRINT-A 
 + 
 +        POP     IX              ; restore this channel address. 
 + 
 +        RET                     ; return. 
 + 
 + 
 +; --------------------------- 
 +; THE <b><font color=#333388>'ERASE COMMAND'</font></b> ROUTINE 
 +; --------------------------- 
 +; <font color=#339933>(Hook Code: $24)</font> 
 +;   The ERASE command is in two stages and uses the first 32 bytes of the  
 +;   otherwise unused data buffer to map out the sectors to be marked clear. 
 +;   The first stage performs this mapping and in one revolution of the tape 
 +;   it should find all sectors that have the specified name.  It should also 
 +;   find the EOF record, which all files have, and which contains in the  
 +;   RECNUM field the maximum record number. For example with four records the 
 +;   numbers will be 0, 1, 2, 3.                 
 +;   Once the number of marked records equals the max record plus one then the 
 +;   second stage can begin which is to mark free all the records. 
 +
 +;   There are two circumstances under which the procedure might not be so  
 +;   straightforward. 
 +;   The first is if the user has pressed BREAK during a previous ERASE  
 +;   operation after a few records were marked free. 
 +;   The second is if the file has been saved with the System Variable COPIES 
 +;   holding a value larger than 1. For example with a value of 5, there will 
 +;   be five EOF records and five records with RECNUM equal to zero etc. 
 +;  
 +;   For the first case the command will make five revolutions of the tape 
 +;   before marking all found sectors free. 
 +;   This may happen in the second case also if more multi records were found 
 +;   before the first EOF record was encountered. 
 +;   It is more likely that the ERASE command will have to be invoked several  
 +;   times to erase the file.  It is simpler to issue the command within a  
 +;   loop.  Multiple copy files are usually saved as part of a well-considered 
 +;   scheme and are seldom subsequently erased. 
 + 
 +<a name="L1D79"></a>;; <b>ERASE</b> 
 +L1D79:  CALL    <A href="#L10A5">L10A5</a>           ; routine SET-T-MCH creates a temporary channel 
 +                                ; using either an existing microdrive map from 
 +                                ; a channel also using this drive or allocating 
 +                                ; a new one initialized to $FF bytes. 
 + 
 +        LD      A,(IX+$19)      ; fetch drive number from CHDRIV. 
 +        CALL    <A href="#L1532">L1532</a>           ; routine SEL-DRIVE starts motor. 
 + 
 +        IN      A,($EF)         ; read microdrive port. 
 +        AND     $01             ; isolate 'write prot.' bit. 
 +        JR      NZ,<A href="#L1D8A">L1D8A</a>        ; forward, if not zero, to ERASE-1 
 + 
 +        RST     20H             ; Shadow Error Restart 
 +        DEFB    $0E             ; Drive 'write' protected 
 + 
 + 
 +<a name="L1D8A"></a>;; <b>ERASE-1</b> 
 +L1D8A:  PUSH    IX              ; transfer address of start of channel. 
 +        POP     HL              ; to the HL register. 
 + 
 +        LD      DE,$0052        ; prepare offset to data buffer. 
 +        ADD     HL,DE           ; add to address start. 
 + 
 +;   A pseudo microdrive map will also be created within the buffer conserving  
 +;   memory.  This is initialized to $00 bytes. 
 + 
 +        PUSH    HL              ; transfer buffer address 
 +        POP     DE              ; from HL to DE register 
 +        INC     DE              ; and increment address. 
 + 
 +        LD      BC,$001F        ; set counter to 31 and B to zero. 
 +        XOR                   ; set A to zero. 
 +        LD      (HL),         ; insert zero in first location. 
 +        LDIR                    ; copy to other 31 addresses 
 + 
 +        LD      A,$FF           ; prepare, as a default, to examine every sector. 
 +        LD      (IX+$0D),     ; update CHREC with max record number. 
 + 
 +        LD      BC,$04FB        ; prepare decimal 1275 (5+ revolutions) 
 +        LD      ($5CC9),BC      ; update system variable SECTOR 
 + 
 +;   <font color=#9900FF>Note.</font> if the EOF record is not found, or if the number of found sectors 
 +;   doesn't equal the maximum record then 5+ revolutions of the tape will 
 +;   occur after which all mapped sectors will be erased. Normally with a  
 +;   simple file it's all over in less than two revolutions. 
 + 
 +<a name="L1DA7"></a>;; <b>ERASE-LP</b> 
 +L1DA7:  CALL    <A href="#L13F7">L13F7</a>           ; routine DEC-SECT decrements the 1275 counter. 
 +        JR      Z,<A href="#L1E03">L1E03</a>         ; forward, if zero, to ERASE-MK 
 + 
 +        CALL    <A href="#L13A9">L13A9</a>           ; routine GET-M-HD2 reads the next 14-byte  
 +                                ; header to pass the tape heads. 
 + 
 +        CALL    <A href="#L1E5E">L1E5E</a>           ; routine G-RDES reads the corresponding  
 +                                ; 14-byte record descriptor for this sector. 
 + 
 +        JR      NZ,<A href="#L1DE5">L1DE5</a>        ; forward, with read error, to TST-NUM 
 + 
 +;   now check if sector is in use.  Considered it so if next position is  
 +;   at $0200 or if it is the EOF record. 
 + 
 +        LD      A,(IX+$43)      ; RECFLG 
 +        OR      (IX+$46)        ; RECLEN_hi 
 +        AND     $02 
 +        JR      NZ,<A href="#L1DC3">L1DC3</a>        ; forward, if in use, to ERASE-2  
 +                                ; to consider for erasure. 
 + 
 +; the sector is not used so reset the REAL microdrive map bit. 
 + 
 +        CALL    <A href="#L13E3">L13E3</a>           ; routine RES-B-MAP resets sector bit on  
 +                                ; the REAL microdrive map. 
 + 
 +        JR      <A href="#L1DE5">L1DE5</a>           ; forward to TST-NUM 
 + 
 +; --- 
 + 
 +;   consider for erasure if filename matches. 
 + 
 +<a name="L1DC3"></a>;; <b>ERASE-2</b> 
 +L1DC3:  PUSH    IX              ; transfer channel base address 
 +        POP     HL              ; to the HL register. 
 + 
 +        LD      DE,$0047        ; offset to 10 characters of filename. 
 +        ADD     HL,DE           ; add so HL addresses the start of RECNAM. 
 +        LD      BC,$000A        ; ten bytes to compare against required CHNAME. 
 + 
 +        CALL    <A href="#L1403">L1403</a>           ; routine CHK-NAME 
 + 
 +        JR      NZ,<A href="#L1DE5">L1DE5</a>        ; forward, with no match, to TST-NUM 
 + 
 +; the name matches so sector is marked free. 
 + 
 +        CALL    <A href="#L13EB">L13EB</a>           ; routine TEST-PMAP obtains address of sector  
 +                                ; bit in HL and bit mask in B. 
 + 
 +        LD      A,B             ; transfer mask to B 
 +        OR      (HL)            ; combine with addressed byte 
 +        LD      (HL),         ; and update setting the sector bit. 
 + 
 +        BIT     1,(IX+$43)      ; test RECFLG is this an EOF record. 
 +        JR      Z,<A href="#L1DE5">L1DE5</a>         ; forward, if not, to TST-NUM 
 + 
 +; All files should have an EOF record and, if this is it, then the endpoint  
 +; can be reduced from $FF to record number plus one as range starts at 1. 
 + 
 +        LD      A,(IX+$44)      ; fetch record number from RECNUM 
 +        INC                   ; increment as CHREC value starts at one not  
 +                                ; zero. 
 +        LD      (IX+$0D),     ; update the endpoint CHREC 
 + 
 +<a name="L1DE5"></a>;; <b>TST-NUM</b> 
 +L1DE5:  PUSH    IX              ; transfer the channel base address 
 +        POP     HL              ; to the HL register. 
 + 
 +        LD      DE,$0052        ; add offset to data 
 +        ADD     HL,DE           ; to address the pseudomap. 
 + 
 +        LD      E,$00           ; initialize E to zero. 
 +        LD      C,$20           ; and C counter to thirty two. 
 + 
 +<a name="L1DF0"></a>;; <b>LP-P-MAP</b> 
 +L1DF0:  LD      A,(HL)          ; fetch a byte from pseudomap 
 +        INC     HL              ; and increment the address. 
 + 
 +        LD      B,$08           ; set bit counter to eight. 
 + 
 +<a name="L1DF4"></a>;; <b>LP-B-MAP</b> 
 +L1DF4:  RRA                     ; rotate end bit to carry. 
 +        JR      NC,<A href="#L1DF8">L1DF8</a>        ; forward, with no carry, to NOINC-C 
 + 
 +        INC                   ; increment recno 
 + 
 +<a name="L1DF8"></a>;; <b>NOINC-C</b> 
 +L1DF8:  DJNZ    <A href="#L1DF4">L1DF4</a>           ; back to LP-B-MAP for all eight bits. 
 + 
 +        DEC                   ; decrement byte counter. 
 +        JR      NZ,<A href="#L1DF0">L1DF0</a>        ; back to LP-P-MAP for all 32 bytes. 
 + 
 +; now E holds the number of records marked for erasure in range 1 to NR. 
 + 
 +        LD      A,(IX+$0D)      ; fetch records to be erased from CHREC 
 +        CP      E               ; compare to records marked for erasure. 
 +        JR      NZ,<A href="#L1DA7">L1DA7</a>        ; back, if not exact match, to ERASE-LP 
 + 
 +;   Now the second stage begins. Since the pseudomap has a representation of 
 +;   all the records to be erased we can load the headers one by one, and  
 +;   rewrite the corresponding records with a clear one in the channel. 
 +;   The same record is written after all the appropriate headers. Fields 
 +;   like RECNUM only have relevance when the record is in use. 
 +;  
 +;   First prepare a clear record descriptor.  The actual data buffer does not  
 +;   have to be clear and in fact contains the pseudomap. Note also that the 
 +;   checksum for the data need not be calculated but the checksum for the  
 +;   record descriptor is required to be accurate. 
 + 
 +<a name="L1E03"></a>;; <b>ERASE-MK</b> 
 +L1E03:  CALL    <A href="#L1E49">L1E49</a>           ; routine IN-CHK marks the channel record  
 +                                ; descriptor fields as usable by blanking 
 +                                ; both RECFLG and RECLEN and then inserting 
 +                                ; the descriptor checksum. 
 + 
 +; now enter a loop for all marked records. 
 + 
 +<a name="L1E06"></a>;; <b>ERASE-MK2</b> 
 +L1E06:  CALL    <A href="#L13A9">L13A9</a>           ; routine GET-M-HD2 reads the next header  
 +                                ; to pass the tape heads. 
 +        CALL    <A href="#L13EB">L13EB</a>           ; routine TEST-PMAP checks if the sector, 
 +                                ; (in HDNUMB) is marked to be erased in the 
 +                                ; pseudomap. 
 +        JR      Z,<A href="#L1E31">L1E31</a>         ; forward, if not, to T-OTHER 
 + 
 +; this record is marked for erasure. 
 + 
 +        PUSH    HL              ; save pseudomap sector bit address. 
 +        PUSH    BC              ; save pseudomap bit mask which has one set bit. 
 + 
 +        LD      A,$E6           ; enable writing. 
 +        OUT     ($EF),        ; output to microdrive port. 
 + 
 +        LD      BC,$0168        ; set counter to 360 decimal. 
 +        CALL    <A href="#L1652">L1652</a>           ; routine DELAY-BC pauses briefly as the  
 +                                ; record now approaches the tape heads. 
 + 
 +        PUSH    IX              ; transfer channel base address 
 +        POP     HL              ; to the HL register pair. 
 + 
 +        LD      DE,$0037        ; offset to record PREAMBLE. 
 +        ADD     HL,DE           ; add to form start of save address. 
 + 
 +        CALL    <A href="#L15B3">L15B3</a>           ; routine OUT-M-BUF rewrites descriptor and 
 +                                ; data buffer. The descriptor is checksummed, 
 +                                ; the data is not. 
 + 
 +        LD      A,$EE           ; disable writing 
 +        OUT     ($EF),        ; output to microdrive port 
 + 
 +; now update bit the real microdrive map and the pseudomap. 
 + 
 +        CALL    <A href="#L13E3">L13E3</a>           ; routine RES-B-MAP resets appropriate bit 
 +                                ; for the now free sector in the REAL  
 +                                ; microdrive map. 
 + 
 +        POP     BC              ; restore the pseudomap bit mask. 
 +        POP     HL              ; restore the pseudomap sector bit address. 
 + 
 +        LD      A,B             ; transfer bitmask to B. 
 +        CPL                     ; the set bit is now reset and the other seven  
 +                                ; bits are set. 
 +        AND     (HL)            ; reset the bit in the pseudomap 
 +        LD      (HL),         ; and update. 
 + 
 +; now check if there are any more sectors to do. 
 + 
 +<a name="L1E31"></a>;; <b>T-OTHER</b> 
 +L1E31:  PUSH    IX              ; transfer channel base address  
 +        POP     HL              ; to the HL register. 
 + 
 +        LD      DE,$0052        ; prepare offset to the pseudomap 
 +        ADD     HL,DE           ; and add to address start of map. 
 + 
 +        LD      B,$20           ; set byte count to thirty two. 
 + 
 +<a name="L1E3A"></a>;; <b>CHK-W-MAP</b> 
 +L1E3A:  LD      A,(HL)          ; fetch a byte representing eight sectors. 
 +        OR      A               ; test for zero. 
 +        JR      NZ,<A href="#L1E06">L1E06</a>        ; back, if a byte is not zero, to ERASE-MK2 
 + 
 +        INC     HL              ; increment the map address 
 +        DJNZ    <A href="#L1E3A">L1E3A</a>           ; loop back to CHK-W-MAP for all 32 bytes. 
 + 
 +; at this point all records have been erased and it only remains to clear up. 
 + 
 +        XOR                   ; select no motor 
 +        CALL    <A href="#L1532">L1532</a>           ; routine SEL-DRIVE stops the motor. 
 + 
 +        CALL    <A href="#L119F">L119F</a>           ; routine DEL-M-BUF deletes the adhoc buffer. 
 + 
 +        RET                     ; return. 
 + 
 + 
 +; ----------------------------------- 
 +; THE <b><font color=#333388>'PREPARE '</font></b>FREE SECTOR'' ROUTINE 
 +; ----------------------------------- 
 +;   The two indicators within the current channel are marked clear and the  
 +;   RECORD DESCRIPTOR is checksumed in preparation for writing to each sector 
 +;   to be marked free. 
 + 
 +<a name="L1E49"></a>;; <b>IN-CHK</b> 
 +L1E49:  XOR                   ; clear accumulator A. 
 +        LD      (IX+$43),     ; blank RECFLG. 
 +        LD      (IX+$45),     ; blank RECLEN_lo. 
 +        LD      (IX+$46),     ; blank RECLEN_hi. 
 + 
 +        PUSH    IX              ; transfer the start of channel 
 +        POP     HL              ; to the HL register pair. 
 + 
 +        LD      DE,$0043        ; prepare the offset to RECFLG. 
 +        ADD     HL,DE           ; add to form start of record descriptor. 
 + 
 +        CALL    <A href="#L1426">L1426</a>           ; routine CHKS-HD-R inserts 14-byte checksum. 
 + 
 +        RET                     ; return. 
 + 
 +; -------------------------------------- 
 +; THE <b><font color=#333388>'OBTAIN RECORD DESCRIPTOR'</font></b> ROUTINE 
 +; -------------------------------------- 
 +; This routine is used by CAT, ERASE and the GET-DESC Hook Code $33. 
 +; It loads and verifies the 14 byte record descriptor from RECFLG to RECNAM. 
 +; This is normally loaded with the following data block 
 +; or with the header block. 
 +; The Zero Flag is set upon successful completion. 
 + 
 +<a name="L1E5E"></a>;; <b>G-RDES</b> 
 +L1E5E:  PUSH    IX              ; transfer channel address 
 +        POP     HL              ; to HL register. 
 + 
 +        LD      DE,$0043        ; offset to RECFLG 
 +        ADD     HL,DE           ; add to form first receiving location. 
 +        CALL    <A href="#L15E2">L15E2</a>           ; routine GET-M-HD reads in 15 bytes. 
 +        CALL    <A href="#L1426">L1426</a>           ; routine CHKS-HD-R checksums the first 14 bytes 
 +        RET     NZ              ; return with checksum error. 
 + 
 +        BIT     0,(IX+$43)      ; test bit 0 of RECFLAG - should be zero 
 +        RET                     ; return. 
 + 
 +; ----------------------- 
 +; THE <b><font color=#333388>'HOOK-CODE'</font></b> ROUTINE 
 +; ----------------------- 
 +; This accesses the twenty six hook codes now reduced to the range $00 - $19. 
 + 
 +<a name="L1E71"></a>;; <b>HOOK-CODE</b> 
 +L1E71:  CP      $1A             ; compare to upper limit. 
 +        JR      C,<A href="#L1E77">L1E77</a>         ; forward, if valid, to CLR-ERR. 
 + 
 +        RST     20H             ; Shadow Error Restart. 
 +        DEFB    $12             ; Hook code error. 
 + 
 +; --- 
 + 
 +<a name="L1E77"></a>;; <b>CLR-ERR</b> 
 +L1E77:  LD      (IY+$00),$FF    ; set ERR_NR to one less than zero - no error. 
 + 
 +        SET     2,(IY+$01)      ; update FLAGS signal 'L' mode. 
 + 
 +        INC     HL              ; step past the hook code location in RAM. 
 +        EX      (SP),HL         ; make this the return address. 
 +        PUSH    HL              ; push back what was at stack pointer - the 
 +                                ; preserved value of AF on entry. 
 + 
 +        ADD     A,            ; double the code. 
 +        LD      D,$00           ; set D to zero for indexing. 
 +        LD      E,A             ; transfer the code to E. 
 + 
 +        LD      HL,<A href="#L1E99">L1E99</a>        ; address: HOOK-TAB the base of the Hook Codes. 
 +        ADD     HL,DE           ; index into this table. 
 + 
 +        LD      E,(HL)          ; low byte to E. 
 +        INC     HL              ; increment pointer. 
 +        LD      D,(HL)          ; high byte to D. 
 + 
 +        POP     AF              ; restore AF from machine stack. 
 + 
 +        LD      HL,<A href="#L0700">L0700</a>        ; push the address UNPAGE 
 +        PUSH    HL              ; on the machine stack. 
 + 
 +        EX      DE,HL           ; transfer address to HL. 
 +        JP      (HL)            ; jump to Hook Code routine. 
 + 
 + 
 +; --------------------------- 
 +; THE <b><font color=#333388>'HOOK CODE +32'</font></b> ROUTINE 
 +; --------------------------- 
 +; <font color=#339933>(Hook Code: $32)</font> 
 +;   This allows the user to call any address in the shadow ROM. 
 + 
 +<a name="L1E94"></a>;; <b>HOOK-32</b> 
 +L1E94:  LD      HL,($5CED)      ; sv HD_11 
 +        JP      (HL)            ; jump to routine. 
 + 
 + 
 +; --------------------------- 
 +; THE <b><font color=#333388>'HOOK CODE +31'</font></b> ROUTINE 
 +; --------------------------- 
 +; <font color=#339933>(Hook Code: $31)</font> 
 +; This Hook Code ensures that the extra System Variables are created. Since 
 +; this has already occurred, as is the case with all Hook Codes, then all that 
 +; remains to do is to return to the address on the stack - the UNPAGE location. 
 + 
 +<a name="L1E98"></a>;; <b>HOOK-31</b> 
 +L1E98:  RET                     ; return. 
 + 
 + 
 +; ------------------------------- 
 +; THE <b><font color=#333388>'HOOK CODE ADDRESSES'</font></b> TABLE 
 +; ------------------------------- 
 +;   The addresses of the Hook Codes.  The last two are new to this ROM. 
 + 
 +<a name="L1E99"></a>;; <b>HOOK-TAB</b> 
 +L1E99:  DEFW    <A href="#L1ECD">L1ECD</a>           ; $1B - CONS-IN 
 +        DEFW    <A href="#L1EE0">L1EE0</a>           ; $1C - CONS-OUT 
 +        DEFW    <A href="#L0B88">L0B88</a>           ; $1D - BCHAN-IN 
 +        DEFW    <A href="#L0D07">L0D07</a>           ; $1E - BCHAN-OUT 
 +        DEFW    <A href="#L1EF0">L1EF0</a>           ; $1F - PRT-OUT 
 +        DEFW    <A href="#L1EF5">L1EF5</a>           ; $20 - KBD-TEST 
 +        DEFW    <A href="#L1532">L1532</a>           ; $21 - SEL-DRIVE 
 +        DEFW    <A href="#L1B05">L1B05</a>           ; $22 - OP-TEMP-M 
 +        DEFW    <A href="#L138E">L138E</a>           ; $23 - CLOSE-M2 
 +        DEFW    <A href="#L1D79">L1D79</a>           ; $24 - ERASE 
 +        DEFW    <A href="#L1EFD">L1EFD</a>           ; $25 - READ-SEQ 
 +        DEFW    <A href="#L12DA">L12DA</a>           ; $26 - WR-RECD 
 +        DEFW    <A href="#L1F0B">L1F0B</a>           ; $27 - RD-RANDOM 
 +        DEFW    <A href="#L1F3F">L1F3F</a>           ; $28 - RD-SECTOR 
 +        DEFW    <A href="#L1F7A">L1F7A</a>           ; $29 - RD-NEXT 
 +        DEFW    <A href="#L1F85">L1F85</a>           ; $2A - WR-SECTOR 
 +        DEFW    <A href="#L10A5">L10A5</a>           ; $2B - SET-T-MCH 
 +        DEFW    <A href="#L119F">L119F</a>           ; $2C - DEL-M-BUF 
 +        DEFW    <A href="#L0F46">L0F46</a>           ; $2D - OP-TEMP-N 
 +        DEFW    <A href="#L1F18">L1F18</a>           ; $2E - CLOSE-NET 
 +        DEFW    <A href="#L1F25">L1F25</a>           ; $2F - GET-PACK 
 +        DEFW    <A href="#L0E4F">L0E4F</a>           ; $30 - SEND-PACK 
 +        DEFW    <A href="#L1E98">L1E98</a>           ; $31 - HOOK-31 
 +        DEFW    <A href="#L1E94">L1E94</a>           ; $32 - HOOK-32 
 + 
 +        DEFW    <A href="#L1FE4">L1FE4</a>           ; $33 - GET-DESC 
 +        DEFW    <A href="#L1FF6">L1FF6</a>           ; $34 - OP-B-CHAN 
 + 
 + 
 +; --------------------------- 
 +; THE <b><font color=#333388>'CONSOLE INPUT'</font></b> ROUTINE 
 +; --------------------------- 
 +; <font color=#339933>(Hook Code: $1B)</font> 
 + 
 +<a name="L1ECD"></a>;; <b>CONS-IN</b> 
 +L1ECD:  EI                      ; enable interrupts. 
 +        RES     5,(IY+$01)      ; update FLAGS signal no new key pressed. 
 + 
 +<a name="L1ED2"></a>;; <b>WTKEY</b> 
 +L1ED2:  HALT                    ; wait for an interrupt. 
 + 
 +        RST     10H             ; CALBAS 
 +        DEFW    $02BF           ; main KEYBOARD 
 + 
 +        BIT     5,(IY+$01)      ; test FLAGS - new key ? 
 +        JR      Z,<A href="#L1ED2">L1ED2</a>         ; loop back, if not, to WTKEY 
 + 
 +        LD      A,($5C08)       ; place decoded key in system variable LASTK 
 +        RET                     ; return. 
 + 
 + 
 +; ---------------------------- 
 +; THE <b><font color=#333388>'CONSOLE OUTPUT'</font></b> ROUTINE 
 +; ---------------------------- 
 +; <font color=#339933>(Hook Code: $1C)</font> 
 +;   outputs a character to the unalterable system stream for the console. 
 + 
 +<a name="L1EE0"></a>;; <b>CONS-OUT</b> 
 +L1EE0:  PUSH    AF              ; save character to be output. 
 +        LD      A,$FE           ; use system stream $FE - upper screen. 
 + 
 +; -&gt; 
 + 
 +<a name="L1EE3"></a>;; <b>OUT-CODE</b> 
 +L1EE3:  LD      HL,$5C8C        ; address system variable SCR_CT. 
 +        LD      (HL),$FF        ; load with a high number to suppress scroll 
 +                                ; prompt. 
 + 
 +        RST     10H             ; CALBAS 
 +        DEFW    $1601           ; main CHAN-OPEN opens selected stream. 
 + 
 +        POP     AF              ; fetch the preserved print character. 
 + 
 +        RST     10H             ; CALBAS 
 +        DEFW    $0010           ; main PRINT-A prints character in accumulator. 
 + 
 + 
 +        RET                     ; return. 
 + 
 + 
 +; ---------------------------- 
 +; THE <b><font color=#333388>'PRINTER OUTPUT'</font></b> ROUTINE 
 +; ---------------------------- 
 +; <font color=#339933>(Hook code: $1D)</font> 
 +;   outputs a character to stream 3. 
 + 
 +<a name="L1EF0"></a>;; <b>PRT-OUT</b> 
 +L1EF0:  PUSH    AF              ; preserve character to be printed 
 +        LD      A,$03           ; select stream 3 
 +        JR      <A href="#L1EE3">L1EE3</a>           ; back to OUT-CODE 
 + 
 + 
 +; --------------------------- 
 +; THE <b><font color=#333388>'KEYBOARD TEST'</font></b> ROUTINE 
 +; --------------------------- 
 +; ( Hook Code: $20 ) 
 +; Normally a single reset bit in A determines which half row is read but by 
 +; resetting all bits the entire keyboard is read.  A pressed key will cause 
 +; a bit to be reset.  Routine returns with zero flag set if no keys pressed, 
 +; NZ otherwise. 
 + 
 +<a name="L1EF5"></a>;; <b>KBD-TEST</b> 
 +L1EF5:  XOR                   ; reset all eight high-order bits. 
 +        IN      A,($FE)         ; read the entire keyboard. 
 +        AND     $1F             ; retain any unpressed keys - will be $1F if 
 +                                ; no key. 
 +        SUB     $1F             ; subtract to give zero if no keys. 
 +        RET                     ; return. 
 + 
 + 
 +; ------------------------------- 
 +; THE <b><font color=#333388>'READ SEQUENTIAL'</font></b> HOOK CODE 
 +; ------------------------------- 
 +; <font color=#339933>(Hook Code: $25)</font> 
 +
 + 
 +<a name="L1EFD"></a>;; <b>READ-SEQ</b> 
 +L1EFD:  BIT     1,(IX+$43)      ; RECFLG 
 +        JR      Z,<A href="#L1F08">L1F08</a>         ; forward to INCREC 
 + 
 +        LD      (IY+$00),$07    ; set ERR_NR to '8 End of file' 
 +        RST     28H             ; Error Main ROM 
 + 
 +; --- 
 + 
 +<a name="L1F08"></a>;; <b>INCREC</b> 
 +L1F08:  INC     (IX+$0D)        ; increment the required record in CHREC 
 +                                ; and continue into next routine... 
 + 
 +; --------------------------- 
 +; THE <b><font color=#333388>'READ RANDOM'</font></b> HOOK CODE 
 +; --------------------------- 
 +; <font color=#339933>(Hook Code: $27)</font> 
 +;   reads a PRINT record randomly. 
 + 
 +<a name="L1F0B"></a>;; <b>RD-RANDOM</b> 
 +L1F0B:  CALL    <A href="#L1252">L1252</a>           ; routine GET-RECD gets the record specified 
 +                                ; by CHREQ matching filename CHNAME from the  
 +                                ; cartridge in the drive CHDRIV which is  
 +                                ; started. 
 + 
 +        BIT     2,(IX+$43)      ; test RECFLG - is it a PRINT type file. 
 +        RET                   ; return if so. 
 + 
 +        CALL    <A href="#L119F">L119F</a>           ; routine DEL-M-BUF reclaims the permanent  
 +                                ; channel thus losing the buffer contents. 
 + 
 +        RST     20H             ; Shadow Error Restart 
 +        DEFB    $16             ; 'Wrong file type' 
 + 
 +; ------------------------------------- 
 +; THE <b><font color=#333388>'CLOSE NETWORK CHANNEL'</font></b> HOOK CODE 
 +; ------------------------------------- 
 +; <font color=#339933>(Hook Code: $2E)</font> 
 +; Hook Code Only 
 + 
 +<a name="L1F18"></a>;; <b>CLOSE-NET</b> 
 +L1F18:  CALL    <A href="#L0FAE">L0FAE</a>           ; routine SEND-NEOF 
 + 
 +        PUSH    IX              ; pick up start address 
 +        POP     HL              ; of the channel. 
 + 
 +        LD      BC,$0114        ; bytes to reclaim. 
 + 
 +        RST     10H             ; CALBAS. 
 +        DEFW    $19E8           ; main RECLAIM-2. 
 + 
 +        RET                     ; return. 
 + 
 + 
 +; ------------------------------------- 
 +; THE <b><font color=#333388>'GET PACKET FROM NETWORK'</font></b> ROUTINE 
 +; ------------------------------------- 
 +; <font color=#339933>(Hook Code: $2F)</font> 
 + 
 +<a name="L1F25"></a>;; <b>GET-PACK</b> 
 +L1F25:  LD      A,($5CC6)       ; sv IOBORD 
 +        OUT     ($FE),        ; 
 +        DI 
 +        CALL    <A href="#L0FD3">L0FD3</a>           ; routine WT-SC-E 
 +        JR      NC,<A href="#L1F3A">L1F3A</a>        ; forward to GP-ERROR 
 + 
 +        CALL    <A href="#L0EB5">L0EB5</a>           ; routine GET-NBLK 
 +        JR      NZ,<A href="#L1F3A">L1F3A</a>        ; forward to GP-ERROR 
 + 
 +        EI                      ; 
 +        AND                   ; 
 +        JP      <A href="#L0D4D">L0D4D</a>           ; jump to BORD-REST 
 + 
 +; --- 
 + 
 +<a name="L1F3A"></a>;; <b>GP-ERROR</b> 
 +L1F3A:  SCF                     ; 
 +        EI                      ; 
 +        JP      <A href="#L0D4D">L0D4D</a>           ; jump to BORD-REST 
 + 
 + 
 +; --------------------------- 
 +; THE <b><font color=#333388>'READ SECTOR'</font></b> HOOK CODE 
 +; --------------------------- 
 +; <font color=#339933>(Hook Code: $28)</font> 
 +; fetches header from sector specified by CHREC. 
 +; If the sector is from a PRINT type file then it returns with success. 
 +; Otherwise if a program or code file the data area is 'cleared'
 + 
 +<a name="L1F3F"></a>;; <b>RD-SECTOR</b> 
 +L1F3F:  LD      HL,$00FF        ; ensure every sector is tried. 
 +                                ; <font color=#9900FF>Note.</font> was $F0 (240) in original ROM which 
 +                                ; would not be compatible with emulators. 
 +        LD      ($5CC9),HL      ; update temporary variable SECTOR 
 + 
 +<a name="L1F45"></a>;; <b>NO-GOOD</b> 
 +L1F45:  CALL    <A href="#L13A9">L13A9</a>           ; routine GET-M-HD2 reads the next header  
 +                                ; to pass the tape heads. 
 + 
 +        LD      A,(IX+$29)      ; fetch sector number from HDNUMB 
 +        CP      (IX+$0D)        ; compare with required sector in CHREC 
 +        JR      Z,<A href="#L1F57">L1F57</a>         ; forward, with match, to USE-C-RC 
 + 
 +        CALL    <A href="#L13F7">L13F7</a>           ; routine DEC-SECT decrements the counter. 
 +        JR      NZ,<A href="#L1F45">L1F45</a>        ; loop back, if not zero, to NO-GOOD 
 + 
 +        RST     20H             ; Shadow Error Restart 
 +        DEFB    $11             ; 'File not found' 
 + 
 +; --- 
 + 
 +<a name="L1F57"></a>;; <b>USE-C-RC</b> 
 +L1F57:  PUSH    IX              ; transfer channel base address 
 +        POP     HL              ; to the HL register. 
 + 
 +        LD      DE,$0043        ; offset to RECFLG  
 +        ADD     HL,DE           ; add to address start of record descriptor. 
 + 
 +        CALL    <A href="#L15EB">L15EB</a>           ; routine GET-M-BUF reads in the record  
 +                                ; descriptor and the 512 bytes of data. 
 + 
 +        CALL    <A href="#L1426">L1426</a>           ; routine CHKS-HD-R checksums the descriptor. 
 +  
 +        JR      NZ,<A href="#L1F75">L1F75</a>        ; forward, with error, to DEL-B-CT 
 + 
 +        LD      DE,$000F        ; additional offset to data. 
 +        ADD     HL,DE           ; add to address data. 
 + 
 +        CALL    <A href="#L142B">L142B</a>           ; routine CHKS-BUFF checksums the data buffer. 
 +        JR      NZ,<A href="#L1F75">L1F75</a>        ; forward, with error, to DEL-B-CT 
 + 
 +        OR      A               ; clear carry 
 +        BIT     2,(IX+$43)      ; test RECFLG - is this a PRINT file ? 
 +        RET                   ; return if so. 
 + 
 +<a name="L1F75"></a>;; <b>DEL-B-CT</b> 
 +L1F75:  CALL    <A href="#L1FD4">L1FD4</a>           ; routine CLR-BUFF sets descriptor and data 
 +                                ; contents to same values. 
 +        SCF                     ; signal error. 
 +        RET                     ; return from hook-code. 
 + 
 + 
 +; -------------------------------- 
 +; THE <b><font color=#333388>'READ NEXT SECTOR'</font></b> HOOK CODE 
 +; -------------------------------- 
 +; <font color=#339933>(Hook Code: $29)</font> 
 +; This hook code just reads the next header to pass the tape head and then, 
 +; without further qualification, reads the corresponding data using the  
 +; routine above. If not a PRINT file then the data is cleared. 
 +; It needlessly sets up a sector counter in the System Variable SECTOR. 
 + 
 +<a name="L1F7A"></a>;; <b>RD-NEXT</b> 
 +L1F7A:  LD      HL,$00FF        ; set count to 255. <font color=#9900FF>Note.</font> not used. 
 +        LD      ($5CC9),HL      ; insert in system variable SECTOR. 
 + 
 +        CALL    <A href="#L13A9">L13A9</a>           ; routine GET-M-HD2 reads the next header  
 +                                ; to pass the tape heads. 
 + 
 +        JR      <A href="#L1F57">L1F57</a>           ; back to USE-C-RC to read and validate the  
 +                                ; corresponding descriptor and data. 
 + 
 +; ---------------------------- 
 +; THE <b><font color=#333388>'WRITE SECTOR'</font></b> HOOK CODE 
 +; ---------------------------- 
 +; <font color=#339933>(Hook Code: $2A)</font> 
 +; writes to microdrive the sector in CHREC. 
 + 
 +<a name="L1F85"></a>;; <b>WR-SECTOR</b> 
 +L1F85:  LD      HL,$00FF        ; set counter to ensure at least one revolution  
 +        LD      ($5CC9),HL      ; of the tape and update SECTOR 
 + 
 +        PUSH    IX              ; transfer base address 
 +        POP     HL              ; of channel to HL. 
 + 
 +        LD      DE,$0037        ; offset to header preamble 
 +        ADD     HL,DE           ; add and 
 +        PUSH    HL              ; preserve location on machine stack. 
 + 
 +        LD      DE,$000C        ; offset past preamble to  RECFLG 
 +        ADD     HL,DE           ; the start of the record descriptor. 
 + 
 +        CALL    <A href="#L1426">L1426</a>           ; routine CHKS-HD-R insert checksum byte. 
 + 
 +        LD      DE,$000F        ; 15 byte offset to start  of data. 
 +        ADD     HL,DE           ; add to address first of 512 bytes. 
 +        CALL    <A href="#L142B">L142B</a>           ; routine CHKS-BUFF inserts buffer checksum. 
 + 
 +<a name="L1FA1"></a>;; <b>WR-S-1</b> 
 +L1FA1:  CALL    <A href="#L13A9">L13A9</a>           ; routine GET-M-HD2 reads any header. 
 +        LD      A,(IX+$29)      ; fetch sector from HDNUMB 
 +        CP      (IX+$0D)        ; compare to required sector in CHREC 
 +        JR      Z,<A href="#L1FB3">L1FB3</a>         ; forward, with match, to WR-S-2 
 + 
 +        CALL    <A href="#L13F7">L13F7</a>           ; routine DEC-SECT decrements the counter 
 +        JR      NZ,<A href="#L1FA1">L1FA1</a>        ; back, if not zero, to WR-S-1 
 + 
 +; else the header was not found after a complete tape revolution. 
 + 
 +        RST     20H             ; Shadow Error Restart 
 +        DEFB    $11             ; File not found 
 + 
 +; --- 
 + 
 +<a name="L1FB3"></a>;; <b>WR-S-2</b> 
 +L1FB3:  IN      A,($EF)         ; read microdrive port. 
 +        AND     $01             ; isolate 'write prot.' bit. 
 +        JR      NZ,<A href="#L1FBB">L1FBB</a>        ; forward, if not, to WR-S-3 
 + 
 +        RST     20H             ; Shadow Error Restart 
 +        DEFB    $0E             ; Drive 'write' protected 
 + 
 +; --- 
 + 
 +<a name="L1FBB"></a>;; <b>WR-S-3</b> 
 +L1FBB:  LD      A,$E6           ; enable writing 
 +        OUT     ($EF),        ; output to port. 
 + 
 +        LD      BC,$0168        ; set delay to 360 
 +        CALL    <A href="#L1652">L1652</a>           ; routine DELAY-BC pauses briefly as the  
 +                                ; record now approaches the tape heads. 
 + 
 +        POP     HL              ; restore pointer to RECFLG 
 +        CALL    <A href="#L15B3">L15B3</a>           ; routine OUT-M-BUF writes descriptor and 
 +                                ; data buffer. 
 + 
 +        LD      A,$EE           ; disable writing 
 +        OUT     ($EF),        ; output to port. 
 + 
 +        CALL    <A href="#L13C4">L13C4</a>           ; routine CHECK-MAP fetches bit mask for map 
 +                                ; location addressed by HL into B register. 
 + 
 +        LD      A,B             ; transfer mask to accumulator 
 +        OR      (HL)            ; combine with any set bits already there. 
 +        LD      (HL),         ; update map marking sector used. 
 + 
 +        RET                     ; return. 
 + 
 +; ----------------------------------- 
 +; THE <b><font color=#333388>'CLEAR BUFFER CONTENTS'</font></b> ROUTINE 
 +; ----------------------------------- 
 +; This routine sets the contents of the 14 byte record descriptor and  
 +; the 512 byte data buffer to the same value so that they are unreadable. 
 +; This is invoked when the possibility that a secret file, whose name begins 
 +; with CHR$ 0 has been read. 
 + 
 +<a name="L1FD4"></a>;; <b>CLR-BUFF</b> 
 +L1FD4:  PUSH    IX              ; transfer the channel base 
 +        POP     HL              ; address to HL. 
 + 
 +        LD      DE,$0028        ; offset to HDFLAG. 
 +        ADD     HL,DE           ; add to base address. 
 + 
 +        LD      D,H             ; transfer same 
 +        LD      E,L             ; address to DE and 
 +        INC     DE              ; make one higher. 
 + 
 +        LD      BC,$0229        ; set counter to 553 bytes. 
 +        LDIR                    ; fill with HDFLAG contents. 
 + 
 +        RET                     ; return. 
 + 
 +; --------------------------------------- 
 +; THE <b><font color=#333388>'FETCH RECORD DESCRIPTOR'</font></b> HOOK CODE 
 +; --------------------------------------- 
 +; <font color=#339933>(Hook Code: $33)</font> 
 +; <font color=#9900FF>Note.</font> new in this ROM. 
 +; This Hook Code reads the next header and corresponding record descriptor 
 +; returning with carry flag set with header mismatch or if the name starts  
 +; with CHR$ 0 and should therefore be secret. 
 + 
 +<a name="L1FE4"></a>;; <b>GET-DESC</b> 
 +L1FE4:  CALL    <A href="#L13A9">L13A9</a>           ; routine GET-M-HD2 reads the next 14-byte  
 +                                ; header to pass the tape heads. 
 +        CALL    <A href="#L1E5E">L1E5E</a>           ; routine G-RDES reads the corresponding  
 +                                ; 14-byte record descriptor for this sector. 
 +        JR      NZ,<A href="#L1FF1">L1FF1</a>        ; forward, with checksum error, to NOT-RECV 
 + 
 +; a valid header and matching descriptor has been read.  
 + 
 +        LD      A,(IX+$47)      ; fetch first character of RECNAM. 
 +        OR      A               ; test for CHR$ 0. 
 +        RET     NZ              ; return if not a secret file. 
 + 
 +; but if a secret file then ensure that the 14 descriptor bytes (read) and  
 +; the 512 buffer bytes (not read) are cleared to the same value. 
 + 
 +<a name="L1FF1"></a>;; <b>NOT-RECV</b> 
 +L1FF1:  CALL    <A href="#L1FD4">L1FD4</a>           ; routine CLR-BUFF (above). 
 +        SCF                     ; signal error. 
 +        RET                     ; return from hook code. 
 + 
 +; -------------------------------- 
 +; THE <b><font color=#333388>'OPEN "B" CHANNEL'</font></b> HOOK CODE 
 +; -------------------------------- 
 +; <font color=#339933>(Hook Code: $34)</font> 
 +; New in this ROM. 
 + 
 +<a name="L1FF6"></a>;; <b>OP-B-CHAN</b> 
 +L1FF6:  LD      A,$42           ; letter "B" 
 +        LD      ($5CD9),      ; place in system variable L_STR1 
 +        CALL    <A href="#L0B17">L0B17</a>           ; routine OP-RS-CH opens an RS232 channel. 
 +        RET                     ; return. 
 + 
 +; --- 
 + 
 +        DEFB    $FF             ; spare 
 + 
 +; --- 
 + 
 +.end 
 + 
 +; ----------------------------- 
 +; THE <b><font color=#333388>'SHADOW'</font></b> SYSTEM VARIABLES 
 +; ----------------------------- 
 +
 +; X1  23734 $5CB6  FLAGS3                 ; IY+$7C - Flags 
 +; X2  23735 $5CB7  VECTOR                 ; Address used to extend BASIC. 
 +; X10 23737 $5CB9  SBRT                   ; 10 bytes of Z80 code to Page ROM. 
 +; 2   23747 $5CC3  BAUD                   ; BAUD=(3500000/(26*baud rate)) -2 
 +; 1   23749 $5CC5  NTSTAT                 ; Own network station number. 
 +; 1   23750 $5CC6  IOBORD                 ; Border colour during I/O 
 +; N2  23751 $5CC7  SER_FL                 ; 2 byte workspace used by RS232 
 +; N2  23753 $5CC9  SECTOR                 ; 2 byte workspace used by Microdrive. 
 +; N2  23755 $5CCB  CHADD_                 ; Temporary store for CH_ADD 
 +; 1   23757 $5CCC  NTRESP                 ; Store for network response code. 
 +; --  ----- -----  ------                 ; --------------------------------- 
 +; 1   23758 $5CCD  NTDEST                 ;  Destination station number 0 - 64. 
 +; 1   23759 $5CCE  NTSRCE                 ;  Source station number. 
 +; X2  23760 $5CD0  NTNUMB                 ;  Network block number 0 - 65535 
 +; N1  23762 $5CD2  NTTYPE                 ;  Header type block. 
 +; X1  23763 $5CD3  NTLEN                  ;  Data block length 0 - 255. 
 +; N1  23764 $5CD4  NTDCS                  ;  Data block checksum. 
 +; N1  23765 $5CD5  NTHDS                  ;  Header block checksum. 
 +; --  ----- -----  ------                 ; --------------------------------- 
 +; N2  23766 $5CD6  D_STR1                 ; 2 byte drive number 1 - 8. 
 +; N1  23768 $5CD8  S_STR1                 ; Stream number 1 - 15. [ also 0 ] 
 +; N1  23769 $5CD9  L_STR1                 ; Device type "M", "N", "T" or "B" 
 +; N2  23770 $5CDA  N-STR1                 ; Length of filename. 
 +; N2  23772 $5CDC             (dynamic)   ; Address of filename. 
 +; --  ----- -----  ------                 ; --------------------------------- 
 +; N1  23774 $5CDE  D_STR2                 ; 2 byte drive   ; File type. 
 +; N1  23775 $5CDF                         ; number.        ; Length of   
 +; N1  23776 $5CE0  S_STR2                 ; Stream number. ; Data. 
 +; N1  23777 $5CE1  L_STR2                 ; Device type.   ; Start of         
 +; N1  23778 $5CE2  N-STR2                 ; Length of      ; data.   \ 
 +; N1  23779 $5CE3                         ; filename.      ; Program  \  
 +; N1  23780 $5CE4             (dynamic)   ; Address of     ; length. ; Start of 
 +; N1  23781 $5CE5             (dynamic)   ; filename       ;         ; data. 
 +; --  ----- -----  ------                 ; --------------------------------- 
 +; N1  23782 $5CE6  HD_00                  ; File type .      _   
 +; N2  23783 $5CE7  HD_0B                  ; Length of data.   /\ 
 +; N2  23785 $5CE9  HD_0D                  ; Start of data.   / 
 +; N2  23787 $5CEB  HD_0F                  ; Program length. / 
 +; N2  23789 $5CED  HD_11                  ; Line number. 
 +; --  ----- -----  ------                 ; --------------------------------- 
 +; 1   23791 $5CEF  COPIES                 ; Number of copies made by SAVE. 
 +; --  ----- -----  ------                 ; --------------------------------- 
 + 
 +; <font color=#9900FF>Note.</font> the System Variables HD_00 to HD_11 take their names from their 
 +; position in the standard audio tape header. The ten bytes HD_01 to HD_0A 
 +; would be the tape filename and are not held within the above area. 
 +; The area D_STR2 is multipurpose and sometimes the HD_?? variables are        
 +; copied to this region and sometimes the D_STR1 variables are copied there. 
 + 
 +; ---------------------------- 
 +; THE <b><font color=#333388>'MICRODRIVE MAPS'</font></b> FORMAT 
 +; ---------------------------- 
 +
 +; The creation of the extra system variables moves the start of CHANS up to 
 +; address 23792.  It is at this location that the first of a possible eight 
 +; Microdrive Maps will be created.  Each map is 32 bytes in size containing 
 +; 256 bits for each possible sector and as each map is created, CHANS moves 
 +; up by another 32 bytes. 
 + 
 +; 10000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
 +; 00000000 00000000 00000000 00000000 00010101 01010100 00000000 00000000 
 +; 00000000 01100000 00000000 00000000 00000000 00000000 00000111 11111111 
 +; 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 
 + 
 +; <font color=#9900FF>Note.</font> The continuous loop tape is formatted in such a way that sector $FE 
 +; is written first and sector $01 is the last to be written. Sectors $00 and 
 +; $FF are therefore always unavailable.  As there is only room for about 180  
 +; sectors on a 100 foot long tape, the higher numbered sectors are later  
 +; overwritten by the lower numbered sectors. 
 +; Where the tape is spliced together one or two bad sectors will appear.  
 +; When saving bytes there isn't enough time to copy the next 512 bytes from  
 +; the program/code area to the buffer between sectors so a program or  
 +; code/data block is written to alternating sectors as with the 3K example 
 +; above.  As the tape cartridge fills up it becomes more difficult to find  
 +; usable sectors and LOAD/SAVE operations take longer. 
 +; A growing number of Spectrum emulators feature the microdrives and they  
 +; usually make available all 254 sectors so a typical cartridge will hold 126  
 +; Kilobytes compared to say 92 K on real hardware. 
 +
 +; During a LOAD operation the entire sector map is pushed on the machine stack 
 +; and the microdrive map is used to map loaded records after which the previous 
 +; map is 'popped' of the stack and reverts to mapping sectors again. 
 +
 +; ------------------------------ 
 +; THE <b><font color=#333388>'STANDARD CHANNELS'</font></b> FORMAT 
 +; ------------------------------ 
 +; The twenty bytes of the standard channels as set up my Main ROM. 
 +
 +; CHANS                   $09F4           ; PRINT-OUT 
 +;                         $10A8           ; KEY-INPUT 
 +;                         $4B             ; 'K' 
 +
 +;                         $09F4           ; PRINT-OUT 
 +;                         $15C4           ; REPORT-J 
 +;                         $53             ; 'S' 
 +
 +;                         $0F81           ; ADD-CHAR 
 +;                         $15C4           ; REPORT-J 
 +;                         $52             ; 'R' 
 +
 +;                         $09F4           ; PRINT-OUT 
 +;                         $15C4           ; REPORT-J 
 +;                         $50             ; 'P' 
 +
 +;                         $80             ; End Marker 
 + 
 +; ------------------------------- 
 +; THE <b><font color=#333388>'MICRODRIVE CHANNEL'</font></b> FORMAT 
 +; ------------------------------- 
 +
 +;   2 IX+$00              $0008           ; main ERROR-1 
 +;   2 IX+$02              $0008           ; main ERROR-1 
 +;   1 IX+$04              $CD             ; inverted or regular "M" character 
 +;   2 IX+$05              $12B3           ; MCHAN-OUT 
 +;   2 IX+$07              $11FD           ; M-INPUT 
 +;   2 IX+$09              $0253           ; length of channel. 
 +;   2 IX+$0B  CHBYTE      $0000           ; position of next byte rec'd/stored 
 +;   1 IX+$0D  CHREC       $00             ; record number, also temporary sector 
 +;  10 IX+$0E  CHNAME      "          "    ; filename with trailing spaces. 
 +;   1 IX+$18  CHFLAG      %0000000x       ; bit 0 used 
 +;   1 IX+$19  CHDRIV                      ; drive number 0 - 7. 
 +;   2 IX+$1A  CHMAP                       ; address of MAP for this microdrive. 
 +; ------------------------------------------------------------------------------ 
 +;  12 IX+$1C                              ; 12 bytes of header preamble 
 +; ------------------------------------------------------------------------------ 
 +;   1 IX+$28  HDFLAG                      ; Flag byte. 
 +;                                         ; bit 0 set indicates a header. 
 +;   1 IX+$29  HDNUMB                      ; Sector number. [1-254] 
 +;   2 IX+$2A                              ; Two unused bytes. 
 +;  10 IX+$2C  HDNAME                      ; Cartridge name with trailing spaces. 
 +;   1 IX+$36  HDCHK                       ; Header checksum. 
 +; ------------------------------------------------------------------------------ 
 +;  12 IX+$37                              ; 12 bytes of data block preamble. 
 +; ------------------------------------------------------------------------------ 
 +;   1 IX+$43  RECFLG                      ; Flag byte.  
 +;                                         ; bit 0 reset indicates a record. 
 +;                                         ; bit 1 reset no EOF, set EOF 
 +;                                         ; bit 2 reset indicates a PRINT FILE 
 +;   1 IX+$44  RECNUM                      ; Record number in the range 0-255 
 +;   2 IX+$45  RECLEN                      ; Number of databytes in record 0-512. 
 +;  10 IX+$47  RECNAM                      ; Filename with trailing spaces. 
 +;   1 IX+$51  DESCHK                      ; Checksum of the preceding 14 bytes 
 +; ------------------------------------------------------------------------------ 
 +; 512 IX+$52  CHDATA                      ; the 512 bytes of data. 
 +;   1 +$0252  DCHK                        ; Checksum of preceding 512 bytes. 
 + 
 +; ---------------------------- 
 +; THE <b><font color=#333388>'NETWORK CHANNEL'</font></b> FORMAT 
 +; ---------------------------- 
 +
 +;   2 IX+$00              $0008           ; main ERROR-1 
 +;   2 IX+$02              $0008           ; main ERROR-1 
 +;   1 IX+$04              $4E             ; "N" character 
 +;   2 IX+$05              $0E09           ; NCHAN-OUT 
 +;   2 IX+$07              $0DA9           ; N-INPUT 
 +;   2 IX+$09              $0114           ; Length of channel 276 bytes. 
 +;   1 IX+$0B NCIRIS                       ; The destination station number. 
 +;   1 IX+$0C NCSELF                       ; This Spectrum's station number. 
 +;   2 IX+$0D NCNUMB                       ; The block number. 
 +;   1 IX+$0F NCTYPE                       ; The packet type code . 0 data, 1 EOF 
 +;   1 IX+$10 NCOBL                        ; Number of bytes in data block. 
 +;   1 IX+$11 NCDCS                        ; The data checksum. 
 +;   1 IX+$12 NCHCS                        ; The header checksum. 
 +;   1 IX+$13 NCCUR                        ; The position of last buffer char taken 
 +;   1 IX+$14 NCIBL                        ; Number of bytes in the input buffer. 
 +;   1 IX+$15 NCB                          ; A 255 byte data buffer. 
 + 
 +; ------------------------------ 
 +; THE <b><font color=#333388>'RS232 "T" CHANNEL'</font></b> FORMAT 
 +; ------------------------------ 
 +
 +;   2 IX+$00              $0008           ; main ERROR-1 
 +;   2 IX+$02              $0008           ; main ERROR-1 
 +;   1 IX+$04              $54             ; "T" character 
 +;   2 IX+$05              $0C3A           ; TCHAN-OUT 
 +;   2 IX+$07              $0B76           ; T-INPUT 
 +;   2 IX+$09              $000B           ; length of channel. 
 + 
 +; ------------------------------ 
 +; THE <b><font color=#333388>'RS232 "B" CHANNEL'</font></b> FORMAT 
 +; ------------------------------ 
 +; created by overwriting a "T" channel 
 +
 +;   2 IX+$00              $0008           ; main ERROR-1 
 +;   2 IX+$02              $0008           ; main ERROR-1 
 +;   1 IX+$04              $42             ; "B" character 
 +;   2 IX+$05              $0D07           ; BCHAN-OUT 
 +;   2 IX+$07              $0B7C           ; B-INPUT 
 +;   2 IX+$09              $000B           ; length of channel. 
 + 
 + 
 +; Acknowledgements 
 +; ---------------- 
 +; Dr Ian Logan          for main ROM labels ( and half on Interface 1) 
 +; Dr Frank O'Hara       for main ROM labels. 
 +; Gianluca Carri        for Interface 1 v1.2 labels 
 + 
 +; Credits 
 +; ------- 
 +; Jonathan Needle       for requesting said labels on comp.sys.sinclair 
 +;                       thereby kick-starting this project. 
 +;                       Also for the Interface1-aware Spectaculator emulator  
 +;                       and help with PORTS. 
 +; Paul Dunn             for help with PORTS and the SPIN emulator. 
 +; Chris Born            for documentation. 
 +</PRE> 
 +</HTML> 
wearmouth/version_2.1647941050.txt.gz · Last modified: 2022/03/22 09:24 by evert