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