Previous Next Contents Index
The control routine 

This routine is called from 'START' at #0008, when the +D system is paged in. 
It has three main tasks:
- If a disc channel has been requested, it jumps to the required 'input' or
  'output' routine.
- If a hook/command code is used, it jumps to the required routine.
- If an error occurred in the 'main' ROM, it checks whether a +D command was
  used. If so the corresponding routine is called, otherwise a return is made to
  the 'main' ROM, except when the +D variable ONERR holds a non zero address.
  In that case a CALBAS to that address is made.

013B START_3    LD   (#3DD6),HL          +D's CH_ADD (D_CH_ADD).
013E            LD   (#3E4F),A
0141            POP  HL                  Get RETurn address (usually points to
0142            PUSH HL                  the error code).
0143            PUSH DE

Now see if a +D channel has been requested.

0144            AND  A
0145            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 Spectrum ROM.
0148            SBC  HL,DE
014A            POP  DE
014B            JR   NZ,#0168,START_4    Jump if no channels have been requested
014D            LD   HL,#0050,UNPAGE_1   Make UNPAGE_1 RETurn address
0150            PUSH HL

Now see if the channel requested is the "P" channel. The +D "P" channel differs only
from the Spectrum's in the 'input' and 'output' addresses. For the +D they both are
#0008. There is no information in the channel on what the +D system's in/output addresses
are (as with "D" channels). So it has to be handled separately.

0151            PUSH BC
0152            LD   HL,(23631)          Fetch CHANS.
0155            LD   BC,16               Point to "P" channel.
0158            ADD  HL,BC
0159            SBC  HL,DE               DE holds address of requested channel.
015B            POP  BC
015C            JP   Z,#1415,PCHAN_OUT   Jump if +D "P" channel was used.
015F            LD   HL,4                DE holds address of routine pointer-4.
                                         See #15EF in 'main' ROM.
0162            ADD  HL,DE               HL now holds address of routine pointer
0163            LD   E,(HL)
0164            INC  HL                  Fetch routine address.
0165            LD   D,(HL)
0166            EX   DE,HL               HL now points to the routine.
0167            JP   (HL)                Jump to the appropriate 'input' or
                                         'output' routine.

At this point, the +D has been paged-in by an error in the 'main' ROM or by a
hook/command code. When an error occurred during a CALBAS and D_ERR_SP isn't zero, the
error has to be handled by the 'main' ROM. If D_ERR_SP is zero, the error is reported to
the routine which executed a CALBAS.

0168 START_4    LD   A,(#3DE5)           Check if the +D CALLed a Spectrum
016B            CP   #47                 ROM routine.
016D            JR   NZ,#018C,START_5    Jump if it didn't.
016F            XOR  A
0170            LD   (#3ACF),A           Clear CALBAS executing.
0173            POP  HL                  Fetch RETurn address.
0174            RST  #10,CALBAS          This CALL's a LD A,(HL) in the Spectrum
0175            DEFW #007B               ROM, so the error code is fetched.
0177            LD   (23610),A           Store the error code in ERR_NR.
017A            LD   HL,(#2066)          Fetch D_ERR_SP.
017D            LD   A,H
017E            OR   L                   Jump if D_ERR_SP was zero, that is when
017F            JP   Z,#04F9,SPEC_ERR1   the 'main' ROM has to handle the error.
0182            SET  7,(IY+0)            Signal 'Spectrum error'.
0186            LD   A,(23610)           Copy error code in A register.
0189            LD   SP,HL               Clear stack.
018A            SCF                      Signal 'error and exit', someone else
018B            RET                      has to handle the error.

Now it is most likely that the +D has to handle the problem which the 'main' ROM
couldn't.

018C START_5    POP  HL                  Fetch address of error or hook/command
                                         code (the byte after RST #08).
018D            RST  #10,CALBAS          Fetch the byte.
018E            DEFW #007B
0190            LD   (23610),A           Store it in ERR_NR.
0193            CP   255
0195            JR   NZ,#01B1,START_7    Jump if the error isn't 'OK'.
0197            CALL #0527,SYSTEM_Z      System loaded?
019A            CALL Z,#045A,SYSTEM_OK   Yes, then check if it's OK.
019D            JR   Z,#01AE,START_6     Give 'OK G+DOS' message if so.
019F            BIT  7,(IY+12)           Give the message also if PPC-hi
01A3            JR   Z,#01AE,START_6     indicates line is not in editing area.
01A5            LD   HL,(23641)          Fetch the command from the editing area
01A8            LD   A,(HL)
01A9            CP   247,"RUN"           Load the system file if the command
01AB            JP   Z,#037B,RUN         is 'RUN'.
01AE START_6    JP   #166C,REP_20

The error code in the A register determines the task to be executed.

01B1 START_7    SUB  27                  Adjust range, hookcodes start at 0 now.
01B3            JR   C,#01CB,START_8     Jump if it isn't a hook or command code
01B5            CALL #0527,SYSTEM_Z      Jump to the system routine if the
01B8            JP   Z,#209E,JHOOK       system is loaded.
01BB            CP   44                  Give the error 'No G+DOS loaded' except
01BD            JP   NZ,#167E,REP_29     with command code 71.
01C0            LD   (IY+0),#FF          Clear the error.
01C4            SET  2,(IY+1)
01C8            INC  HL                  Advance return address past the code.
01C9            PUSH HL
01CA            RET

01CB START_8    CP   240                 Jump if the error is
01CD            JR   Z,#01DC,TEST_INPUT  'Nonsense in BASIC'.
01CF            CP   243
01D1            JR   Z,#01DC,TEST_INPUT  Also if it is 'Invalid filename'.
01D3            CP   252
01D5            JR   Z,#01DC,TEST_INPUT  Or 'Invalid stream'.
01D7            CP   230                 Jump to the 'main' ROM error handler if
01D9            JP   NZ,#04F9,SPEC_ERR1  it isn't 'Variable not found'.
01DC TEST_INPUT BIT  5,(IY+55)           Use 'main' ROM error handler also if in
01E0            JP   NZ,#04F9,SPEC_ERR1  INPUT mode.
01E3            RST  #30,SYNTAX_Z
01E4            JR   NZ,#01EA,RUNTIME    Jump during RUNtime.
01E6            LD   (IY+12),#FF         Signal 'syntax time' (PPC-hi).

Now a loop is entered to find the line that has produced the error. The routine used
here is copied from the IF1 and is way ahead of the DISCiPLE's backstepping routine.

01EA RUNTIME    LD   B,(IY+13)           Statement counter.
01ED            LD   C,0                 Counter of ' " ' characters.
01EF            BIT  7,(IY+12)           Jump forward if the line is in the
01F3            JR   Z,#01FF,PROG_LINE   program area.
01F5            PUSH BC                  Save counters.
01F6            RST  #10,CALBAS          Call main ROM 'E-LINE-NO' (it fetches
01F7            DEFW #19FB,E_LINE_NO     the number of the line in the editing
                                         area, but is actually used to update
                                         CH-ADD to the 1st char.in the line).
01F9            POP  BC                  Restore counters.
01FA            RST  #10,CALBAS          Update HL to the first character in
01FB            DEFW #0018,GET_CHAR      the line.
01FD            JR   #023F,S_STAT

01FF PROG_LINE  LD   HL,(23635)          (PROG), start of the program area.
0202 SC_L_LOOP  LD   A,(IY+12)           Give error if the current line number
0205            CP   (HL)                is greater than that of the line to be
0206            JP   C,#1644,REP_0       searched for.
0209            INC  HL                  Point to low byte of line number.
020A            JR   NZ,#0213,LINE_LEN   Jump if not at expected line.
020C            LD   A,(23621)           Compare also the low byte of the line
020F            CP   (HL)                numbers (PPC-lo).
0210            JP   C,#1644,REP_0       Give error if the line doesn't exist.
0213 LINE_LEN   INC  HL                  Fetch line length.
0214            LD   E,(HL)
0215            INC  HL
0216            LD   D,(HL)
0217            INC  HL
0218            JR   Z,#023F,S_STAT      Jump forward if the line is found.
021A            ADD  HL,DE
021B            JR   #0202,SC_L_LOOP     Next line.

021D SKIP_NUM   LD   DE,6                Length of a floating point number
0220            ADD  HL,DE               and marker.

This loop advances HL until it points to the start of the statement that has produced
the error.

0221 EACH_ST    LD   A,(HL)              Get a character from the line.
0222            CP   #0E
0224            JR   Z,#021D,SKIP_NUM    Skip over floating point numbers.
0226            INC  HL
0227            CP   34,"""
0229            JR   NZ,#022C,CHKEND
022B            DEC  C                   Decrement counter for each ' " '.
022C CHKEND     CP   58,":"
022E            JR   Z,#0234,CHKEVEN     A colon or the 'THEN' keyword mark
0230            CP   203,"THEN"          the beginning of a new statement, but
0232            JR   NZ,#0238,CHKEND_L   only if they occur out of a string.
0234 CHKEVEN    BIT  0,C                 I.e. the number of quotes found must
0236            JR   Z,#023F,S_STAT      be even.
0238 CHKEND_L   CP   13
023A            JR   NZ,#0221,EACH_ST    Repeat until 'end of line'.
023C            JP   #1644,REP_0         An uneven number of quotes is
                                         unacceptable.
023F S_STAT     DJNZ #0221,EACH_ST       Loop for every statement in the line.
0241            DEC  HL                  Update CH_ADD to the address of
0242            LD   (23645),HL          the statement found.
0245            RST  #30,SYNTAX_Z
0246            JR   NZ,#027A,CL_WORK    Jump forward during runtime.
0248            BIT  7,(IY+12)           Give an error if the line is not in the
024C            JP   Z,#04F0,SPEC_ERR    editing area.

The final loop is made during syntax checking, for removing all 6-byte floating point
numbers inserted in the line by the 'main' ROM interpreter.

024F            DEC  HL                  Balance the "INC HL" below.
0250            LD   C,0                 ???? C isn't used anymore.
0252 RCLM_NUM   INC  HL                  Point to next character.
0253            LD   A,(HL)
0254            CP   #0E                 Is it a 'number' marker ?
0256            JR   NZ,#0275,NEXT_NUM   Jump if not.
0258            PUSH BC                  ???? again.
0259            LD   BC,6
025C            RST  #10,CALBAS          Reclaim the 6 bytes forming a number
025D            DEFW #19E8,RECLAIM_2     and the 'number marker'.
025F            PUSH HL
0260            LD   DE,(#3DD6)          Fetch D_CH_ADD.
0264            AND  A                   Jump if the number bytes reclaimed were
0265            SBC  HL,DE               after the character pointed to by
0267            JR   NC,#0273,NXT_1      D_CH_ADD.
0269            EX   DE,HL               Otherwise D_CH_ADD has to be updated.
026A            LD   BC,6
026D            AND  A                   The character pointed by D_CH_ADD has
026E            SBC  HL,BC               been moved '6' bytes down.
0270            LD   (#3DD6),HL          Update D_CH_ADD.
0273 NXT_1      POP  HL
0274            POP  BC
0275 NEXT_NUM   LD   A,(HL)
0276            CP   13
0278            JR   NZ,#0252,RCLM_NUM   Again repeat until 'end of line'.

Now the working area is cleared. The two commands 'RUN' and 'POKE' are handled by the +D
ROM, the G+DOS system should handle all other commands.

027A CL_WORK    RST  #10,CALBAS          Clear Spectrum work areas by calling
027B            DEFW #16BF,SET_WORK      'SET_WORK' in 'main' ROM.
027D            RST  #28,NEXT_C
027E            CP   244,"POKE"
0280            JP   Z,#04C7,POKE@       Jump with 'POKE' command.
0283            CALL #0527,SYSTEM_Z      The system routine is called when 
0286            CALL Z,#20A4,JCTRL       present.
0289            JP   #04F0,SPEC_ERR      Otherwise give an error.

028C 2843            JR   Z,L82D1

Previous Next Contents Index