Previous Next Contents Index
The ROM control routine

This is the entry point for all 'new' BASIC commands and the channels supported by the
'pupil' system. This routine is executed in RAM (the first KEY_SCAN after a reset jumps
to the appropriate routine, which copies the first 2335 ROM bytes to RAM).

2086 ROM_START2 LD   (#1DD6),HL          DISCiPLE's CH_ADD (D_CH_ADD).
2089            LD   (#1DEA),A
208C            LD   A,(#1DE5)           Get CALBAS indicator.
208F            CP   #47
2091            JR   NZ,#20A0,ROM_START3 Jump if not executing a CALBAS.

The error occurred during CALBAS, so go to Spectrum error routine.

2093            XOR  A
2094            LD   (#1DE5),A           Clear the CALBAS flag.
2097            LD   (#1ACF),A           Clear FLAGS3.
209A            LD   HL,#0054            Address in the Spectrum error routine.
209D            EX   (SP),HL             Put new return address on the stack.
209E            JR   #2050,UNPAGE_1      Page out DISCiPLE and then return.

20A0 ROM_START3 POP  HL                  Get RETurn address (usually points to
20A1            PUSH HL                  the error code).
20A2            PUSH DE

Now see if a DISCiPLE's channel has been requested.

20A3            AND  A
20A4            LD   DE,#15FE            If a channel has been requested this is
                                         the RETurn address stored by the CALL
                                         #162C in the 'CALL_SUB' subroutine in
                                         the 'main' ROM.
20A7            SBC  HL,DE               Compare the addresses.
20A9            POP  DE
20AA            JR   NZ,#20CA,ROM_START4 No channels requested, so jump.

Now see if the channel requested is the "P" channel. The DISCiPLE's "P" channel has to
be handled seperately from "D" channels because it doesn't hold information about the
DISCiPLE systems in/out addresses.

20AC            LD   HL,#0050            This makes UNPAGE_1 the return address.
20AF            PUSH HL
20B0            PUSH BC
20B1            LD   HL,(23631)          Fetch CHANS.
20B4            LD   BC,16               Point to the "P" channel.
20B7            ADD  HL,BC
20B8            SBC  HL,DE               Compare "P" address with used address.
20BA            POP  BC
20BB            LD   A,(#1DEA)           Restore A.
20BE            JP   Z,#089F,PCHAN_OUT   Jump if DISCiPLE "P" channel was used.
20C1            LD   HL,4                DE holds address of routine pointer-4.
20C4            ADD  HL,DE               HL now points to the routine pointer.
20C5            LD   E,(HL)              Fetch routine address.
20C6            INC  HL
20C7            LD   D,(HL)
20C8            EX   DE,HL               HL now points to the routine.
20C9            JP   (HL)                Jump to the appropriate 'input' or
                                         'output' routine.

At this point the DISCiPLE has been paged-in by an error in the 'main' ROM (not during

20CA ROM_START4 POP  HL                  Fetch address of error code.
20CB            RST  #10,CALBAS          CALBAS in CH_ADD+1, this gets the byte
20CC            DEFW #007B               pointed by HL, i.e. the errorcode.
20CE            LD   (IY+0),A            Store it in ERR_NR.
20D1            CP   #FF                 Is the error 'OK'?
20D3            JR   Z,#20EB,TEST_INPUT  Jump if so.
20D5            SUB  27                  Adjust the range, error codes now below 0.
20D7            JP   NC,#0899,REPORT_17  Give 'Invalid CODE' error. Hook- and
                                         command codes are not supported.

Now the reduced error code is tested for the values wich might indicate DISCiPLE BASIC

20DA            CP   240                 Jump if the error is
20DC            JR   Z,#20EB,TEST_INPUT  'Nonsense in BASIC'.
20DE            CP   243
20E0            JR   Z,#20EB,TEST_INPUT  Also if it is 'Invalid file name'.
20E2            CP   252
20E4            JR   Z,#20EB,TEST_INPUT  Or 'Invalid stream'.
20E6            CP   230
20E8            JP   NZ,#0146,SPEC_ERR   Exit if not 'Variable not found'.

Now follows the infamous 'Backstepping' routine, from the address where the BASIC
interpreter failed a backward search is made for a character code larger or equal to
206, i.e. a keyword. There are many ways this algorithm can fail, e.g.:
-A number in a BASIC line is followed by a CHR$ 14 and the binary representation
 of the number, this could contain a byte >= 206.
-If there is no keyword on the line, searching continous within the line length,
 line number and then on to previous line(s).

20EB TEST_INPUT BIT  5,(IY+55)           Test FLAG_X.
20EF            JP   NZ,#0146,SPEC_ERR   Exit if in input mode.

20F2            LD   HL,(23645)          Get address reached by interpreter
20F5 FIND_COM   DEC  HL                  (CH_ADD).
20F6            LD   A,(HL)
20F7            CP   206                 See if character is a keyword (>=206,
                                         i.e. DEF FN, the first BASIC command).
20F9            JR   C,#20F5,FIND_COM    If not, repeat 'Backstepping.'
20FB            LD   (23645),HL          Update CH_ADD.
20FE            RST  #30,SYNTAX_Z
20FF            JR   NZ,#212E,RUNTIME    Jump during runtime.
2101            DEC  HL                  Compensate for increase at #2104.
2102            LD   C,0                 ???? C isn't used.

Now the routine removes numbers from the current BASIC line.

2105            LD   A,(HL)              Next character.
2106            CP   14
2108            JR   NZ,#2129,NO_NUM     Jump if it's not a 'number' marker.
210A            PUSH BC
210B            PUSH HL
210C            LD   BC,6                Reclaim the six bytes forming a number
210F            RST  #10,CALBAS          with it's marker.
2110            DEFW #19E8,RECLAIM_2
2112            POP  HL                  Retrieve address in line.
2113            PUSH HL                  But keep it on the stack also.
2114            LD   DE,(#1DD6)          Address reached by interpreter.
2118            AND  A                   Jump if the reclaimed bytes were after
2119            SBC  HL,DE               the character pointed to by D_CH_ADD.
211B            JR   NC,#2127,NEXT_1
211D            EX   DE,HL               Otherwise D_CH_ADD has to be updated.
211E            LD   BC,6
2121            AND  A                   The character pointed by D_CH_ADD has
2122            SBC  HL,BC               been moved '6' bytes down.
2124            LD   (#1DD6),HL          Update D_CH_ADD.
2127 NEXT_1     POP  HL
2128            POP  BC
2129 NO_NUM     LD   A,(HL)
212A            CP   13
212C            JR   NZ,#2104,RECLM_NUM  Repeat until 'end of line' is found.

Now clear the BASIC workspace and test if the Spectrum is a pupil in a network.

212E RUNTIME    RST  #10,CALBAS          CALL the Spectrum ROM routine SET_WORK
212F            DEFW #16BF,SET_WORK      to clear the workspace.
2131            LD   A,(#1DE4)
2134            CP   #78
2136            JP   Z,#0315,PUPIL       Jump if this is a PUPIL station.

If not a pupil and because the DISCiPLE isn't booted the only valid commands are FORMAT
(for network) and RUN (to boot).

2139            CALL #002C,GET_C_ROM     Get next character from line.
213C            CP   208
213E            JP   Z,#080C,NET_FORMAT  Jump with 'FORMAT' command.
2141            CP   247
2143            JP   Z,#01BC,RUN         Also jump with 'RUN'.

This routine must be entered with the error code in (ERR_NR), and does the same as the
'main' ROM 'ERROR' restart.

2146 SPEC_ERR   LD   HL,(#1DD6)          Get D_CH_ADD.
2149            LD   (23645),HL          Store it in CH_ADD and X_PTR.
214C            LD   (23647),HL
214F            LD   HL,#0058            Address in Spectrum error routine.
2152            JP   #004F,UNPAGE_HL     Jump to Spectrum error routine.
Previous Next Contents Index