Previous Next Contents Index
The BASIC command execution routines

THE 'SAVE' COMMAND SYNTAX ROUTINE
This routine deals with the SAVEing of a file. As with all PUPIL "disk" commands, a
command block is send over the network to the master or an assistant station. The
master or assistant than takes care of the SAVEing to disk.

2672 SAVE       CALL #03EF,SIGN_SAVE     Signal 'SAVEing'.
2675            CALL #04F3,EXPT_PARMS    Evaluate and store the parameters.
2678            CALL #08B1,REQ_SERV      Request service by a master or
                                         assistant station (if needed).
267B            CALL #04E6,TEST_STAT     Check if the destination station number
                                         is in range.
267E            CALL #39A9,OPEN_N        Open the "N" channel.
2681            CALL #068A,SAVE_NET      SAVE file and header over the network.
2684            CALL #39DF,SEND_NEOF     Send the EOF block.
2687            JP   #0165,END           Finished.

THE 'SEND HEADER AND FILE' SUBROUTINE
This subroutine sends the file header and the file itself over the network. The End
Of File block isn't send.

268A SAVE_NET   LD   DE,9                Length of the header.
268D            LD   HL,#1E10            Address of the header.
2690            CALL #069A,SAVE_NET1     Send the header over the network.
2693            LD   DE,(#1E11)          Fetch length of file.
2697            LD   HL,(#1E13)          Fetch address.
269A SAVE_NET1  LD   A,D
269B            OR   E
269C            RET  Z                   Return if no more bytes left.
269D            LD   A,(HL)              Fetch a byte.
269E            CALL #386D,N_OUTPUT      Send it over the network.
26A1            INC  HL                  Point to next byte.
26A2            DEC  DE                  One less.
26A3            JR   #269A,SAVE_NET1     Repeat for all bytes.

THE 'LOAD' COMMAND SYNTAX ROUTINE
The 'LOAD' flag is set and the routine continues into the 'LOAD_VERIFY_MERGE'
routine below.

26A5 LOAD       CALL #03EA,SIGN_LOAD     Signal 'LOADing'.
26A8            JR   #26B2,LD_VF_MR

THE 'VERIFY' COMMAND SYNTAX ROUTINE
The 'VERIFY' flag is set and again the 'LOAD_VERIFY_MERGE' routine handles the rest.

26AA VERIFY     CALL #03F9,SIGN_VERIF    Signal 'VERIFYing'.
26AD            JR   #26B2,LD_VF_MR

THE 'MERGE' COMMAND SYNTAX ROUTINE
The 'MERGE' flag is set and 'LOAD_VERIFY_MERGE' continues the syntax checking.

26AF MERGE      CALL #03F4,SIGN_MERGE    Signal 'MERGEing'.

THE 'LOAD_VERIFY_MERGE' COMMAND ROUTINE
This subroutine checks the syntax of the LOAD, VERIFY and MERGE commands and executes
them also.

26B2 LD_VF_MR   CALL #04F3,EXPT_PARMS    Evaluate and store the parameters.
26B5            CALL #08B1,REQ_SERV      Request service by a master or an
                                         assistant station (if needed).
26B8            CALL #04E6,TEST_STAT     Check if the destination station number
                                         is in range.
26BB            CALL #39A9,OPEN_N        Open the "N" channel.
26BE            LD   B,9                 Length of a header.
26C0            LD   HL,#1E29            Start of HEADER 2.
26C3 LD_ETC1    CALL #3808,N_INPUT       LOAD a byte from the network.
26C6            LD   (HL),A              Store it into UFIA2.
26C7            INC  HL
26C8            DJNZ #26C3,LD_ETC1       Repeat for all header bytes.
26CA            LD   A,(#1E10)           Fetch type of program to be LOADed.
26CD            LD   B,A
26CE            LD   A,(#1E29)
26D1            CP   B                   Fetch type of program found.
26D2            JP   NZ,#293A,REP_13     Give 'Wrong FILE type' if types are
                                         unequal.
26D5            CP   3
26D7            JR   Z,#26E7,LD_ETC2     Jump if it's a 'CODE' file.
26D9            JP   NC,#293A,REP_13     Give 'Wrong FILE type'
                                         if file type >= 4.
26DC            CALL #041C,TEST_MERGE
26DF            JR   NZ,#273D,MERGE_CTRL Jump if 'MERGEing'.
26E1            CALL #0421,TEST_VERIF
26E4            JP   Z,#0759,LOAD_CTRL   Jump if not 'VERIFYing' (i.e. doing a
26E7 LD_ETC2    CALL #041C,TEST_MERGE    LOAD).

Now deal with LOADing of all files with type 3, like 'CODE' and 'SCREEN$', or VERIFYing
of all file types.

26EA            JP   NZ,#293C,REP_14     Give 'MERGE error' if trying to MERGE a
                                         'CODE' file.
26ED            LD   HL,(#1E11)          Fetch length of requested file.
26F0            LD   DE,(#1E2A)          Fetch length of file found.
26F4            LD   A,H
26F5            OR   L
26F6            JR   Z,#2705,LD_ETC3     Jump if length unspecified.
26F8            SBC  HL,DE               Jump if file to be LOADed is shorter
26FA            JR   NC,#2705,LD_ETC3    than or of equal length as the
                                         requested file.
26FC            CALL #0412,TEST_LOAD
26FF            JP   Z,#2938,REP_12      'VERIFY failed' if not LOADing.
2702            JP   #293E,REP_15        Otherwise 'CODE error'.

2705 LD_ETC3    LD   HL,(#1E13)          Fetch startaddress from FILE_ADDR1.
2708            LD   A,H
2709            OR   L
270A            JR   NZ,#270F,LD_ETC4    Jump if a startaddress was specified.
270C            LD   HL,(#1E2C)          Otherwise use the startaddress of the
                                         found file.
270F LD_ETC4    LD   A,(#1E29)           But if the file is a BASIC program the
2712            AND  A                   startaddress is held in (PROG).
2713            JR   NZ,#2718,LD_ETC5    Jump if not a BASIC file.
2715            LD   HL,(23635)          Fetch 'start' from (PROG).
2718 LD_ETC5    CALL #07FE,LV_ANY        Load or verify the file.
271B            LD   HL,(#1E17)          Fetch execute address.
271E            CALL #072A,EXEC_CODE     Use it if it was specified.
2721            LD   HL,(#1E30)          Otherwise use the files execute
2724            CALL #072A,EXEC_CODE     address.
2727            JP   #0165,END           Finished.

THE 'EXECUTE CODE FILE' SUBROUTINE
This routine is supposed to jump to the address in the HL register pair (if it is valid)
but because of a mistake strange things can happen after the CODE file has been
'executed'. The mistake is made at #2737-#273A, now a return is made to 'STACK_BC' in
the 'main' ROM first and than the code file is executed. It had to be the other way
around. (See RAM disassembly from #0F23 onwards.)

272A EXEC_CODE  LD   A,H
272B            OR   L
272C            RET  Z                   Return if the execute address is zero.
272D            LD   A,H
272E            CP   #FF
2730            JR   NZ,#2736,EXEC_CODE1
2732            LD   A,L                 Also return when the execute address is
2733            CP   #FF                 #FFFF.
2735            RET  Z
2736 EXEC_CODE1 EX   (SP),HL             Place execute address onto the stack.
2737            LD   HL,#2D2B,STACK_BC
273A            JP   #004F,UNPAGE_HL

Now consider the MERGEing of a program.

273D MERGE_CTRL LD   BC,(#1E2A)          Fetch the length of the program to be
2741            PUSH BC                  MERGEd.
2742            INC  BC                  Extra location for the 'end marker'.
2743            RST  #10,CALBAS          Make the required room in workspace by
2744            DEFW #0030,BC_SPACES     calling 'BC_SPACES'.
2746            LD   (HL),128            Place the 'end marker'.
2748            EX   DE,HL               Move start pointer to HL.
2749            POP  DE                  Length to DE.
274A            PUSH HL
274B            CALL #07FE,LV_ANY        Load the file into workspace.
274E            POP  HL                  Fetch 'start' of new program.
274F            LD   DE,(23635)          Fetch 'start' of old program (PROG).
2753            RST  #10,CALBAS          Do the mergeing by calling the 'main'
2754            DEFW #08D2,ME_NEW_LP     ROM 'MERGE' routine.
2756            JP   #0165,END           Finished.

The final part of the routine deals with the LOADing of a program or an array.

2759 LOAD_CTRL  LD   DE,(#1E2A)          Fetch 'new' length.
275D            LD   HL,(#1E13)          Fetch 'old' start (=0 when loading a
                                         'new' array).
2760            PUSH HL
2761            LD   A,H
2762            OR   L
2763            JR   NZ,#276B,LD_CTRL1   Jump if not a 'new' array.
2765            INC  DE                  Increment length by 3, i.e. allows for
2766            INC  DE                  the insertion of the array name and the
2767            INC  DE                  two-byte length.
2768            EX   DE,HL               Move 'length' to HL.
2769            JR   #2774,LD_CTRL2      Jump forward.

The array to be loaded will replace an existing one.

276B LD_CTRL1   LD   HL,(#1E11)          Fetch 'old' length (i.e. length of
                                         existing program or array) from UFIA1.
276E            EX   DE,HL               Move 'new' length to HL.
276F            SCF                      Jump if the program or array to be
2770            SBC  HL,DE               loaded isn't longer than the existing
2772            JR   C,#277D,LD_CTRL3    one.
2774 LD_CTRL2   LD   DE,5                Otherwise a check must be made to
2777            ADD  HL,DE               ensure that there is sufficient space
2778            LD   B,H                 in memory for the program (or array) to
2779            LD   C,L                 be loaded.
277A            RST  #10,CALBAS          Make the check by calling the 'main'
277B            DEFW #1F05,TEST_ROOM     ROM 'TEST_ROOM' subroutine.
277D LD_CTRL3   POP  HL                  Restore 'old' start (#0000 when
                                         handling a 'new' array).
277E            LD   A,(#1E29)
2781            AND  A
2782            JR   Z,#27B5,LD_PROG     Jump if it's a BASIC program.
2784            LD   A,H
2785            OR   L                   Jump unless an 'old' array is to be
2786            JR   Z,#2793,LD_CTRL4    erased before loading the 'new' one.
2788            DEC  HL                  Points to high byte of 'array length'.
2789            LD   B,(HL)              Fetch the 'length'.
278A            DEC  HL
278B            LD   C,(HL)
278C            DEC  HL                  Now point to the 'array name'.
278D            INC  BC                  Include 'length' and 'name' in the
278E            INC  BC                  array length.
278F            INC  BC
2790            RST  #10,CALBAS          Call 'RECLAIM_2' to delete the array.
2791            DEFW #19E8,RECLAIM_2
2793 LD_CTRL4   LD   HL,(23641)          (E_LINE) points to the end of the
2796            DEC  HL                  variables area+1.
2797            LD   BC,(#1E2A)          Fetch length of array to be loaded.
279B            PUSH BC
279C            INC  BC                  Include in the length one byte for the
279D            INC  BC                  'array name' and two bytes for the
279E            INC  BC                  'array length'.
279F            LD   A,(#1E15)           Fetch the array name from 'LENGTH1_2'.
27A2            PUSH AF
27A3            RST  #10,CALBAS          Call 'MAKE_ROOM' to create the space
27A4            DEFW #1655,MAKE_ROOM     for the array.
27A6            INC  HL                  Point to first 'new' location inserted.
27A7            POP  AF
27A8            LD   (HL),A              Store array name into first location.
27A9            POP  DE
27AA            INC  HL                  Store array length into the following
27AB            LD   (HL),E              two locations.
27AC            INC  HL
27AD            LD   (HL),D
27AE            INC  HL
27AF            CALL #07FE,LV_ANY        Load the file.
27B2            JP   #0165,END           Finished.

Now deal with the LOADing of a BASIC program and its variables.

27B5 LD_PROG    LD   DE,(23635)          Fetch start of existing program (PROG).
27B9            LD   HL,(23641)          Fetch end of existing program, i.e.
27BC            DEC  HL                  (E_LINE)-1.
27BD            RST  #10,CALBAS          Delete the program by calling
27BE            DEFW #19E5,RECLAIM_1     'RECLAIM_1' in the 'main' ROM.
27C0            LD   BC,(#1E2A)          Fetch length of program and variables.
27C4            LD   HL,(23635)          Fetch (PROG), start of BASIC program.
27C7            RST  #10,CALBAS          Create the required space by calling
27C8            DEFW #1655,MAKE_ROOM     'MAKE_ROOM'.
27CA            INC  HL                  Point to the first location.
27CB            LD   BC,(#1E2E)          Fetch length without variables.
27CF            ADD  HL,BC               Calculate and store the start of the
27D0            LD   (23627),HL          variables area (VARS).
27D3            LD   A,(#1E31)           When no autostart line is given, this
27D6            LD   H,A                 ('AUTOSTART2-hi') holds #FF.
27D7            AND  #C0
27D9            JR   NZ,#27E6,LD_PROG1   Jump with no autostart line.
27DB            LD   A,(#1E30)           Otherwise store it into 'NEWPPC' and
27DE            LD   L,A                 clear 'NSPPC'.
27DF            LD   (23618),HL          These hold the line and the statement
27E2            LD   (IY+10),0           to be executed respectively.
27E6 LD_PROG1   LD   HL,(23635)          Fetch the start of the BASIC program.
27E9            LD   DE,(#1E2A)          Fetch the length.
27ED            DEC  HL                  Reset the DATA pointer 'DATADD' to the
27EE            LD   (23639),HL          beginning of the program.
27F1            INC  HL                  Balance the 'DEC HL'.
27F2            CALL #07FE,LV_ANY        Load the file.
27F5            JP   #0165,END           Finished.

THE 'LOAD OR VERIFY' SUBROUTINE
This subroutine is used to LOAD or VERIFY (signalled by FLAGS3) a block of bytes. It
must be entered with HL and DE holding 'start' and 'length'.

27F8 LV_VERIFY  CP   (HL)                The actual VERIFY, i.e. compare the
                                         fetched byte with that held in memory.
27F9            JP   NZ,#2938,REP_12     Give 'VERIFY failed' if they don't
                                         match.
27FC LV_NEXT    INC  HL                  Next memory address.
27FD            DEC  DE                  One byte less to go.
27FE LV_ANY     LD   A,D
27FF            OR   E
2800            RET  Z                   Exit if no more bytes left.
2801            CALL #3808,N_INPUT       Load one byte from the network.
2804            CALL #0421,TEST_VERIF
2807            JR   NZ,#27F8,LV_VERIFY  Jump if VERIFYing.
2809            LD   (HL),A              Otherwise store the byte.
280A            JR   #27FC,LV_NEXT       Repeat for all bytes in the file.

THE 'FORMAT' COMMAND SYNTAX ROUTINE
This routine tests if the command has the appropriate syntax and executes it during
runtime.

280C FORMAT     RST  #28,NEXT_C_ROM      Advance CH_ADD to next character.
280D            AND  #DF                 Only capitals.
280F            CP   "N"                 Give 'Nonsense in GNOS' if device isn't
2811            JP   NZ,#2922,REP_1      equal to "N".
2814            CALL #0465,EXPT_DEVN     Evaluate the station number.
2817            CALL #0155,ST_END_ROM    Confirm end of statement and exit
                                         during syntax checking.
281A            CALL #04E6,TEST_STAT     Check the station number.
281D            LD   A,(#1E01)
2820            AND  A                   Give 'Invalid STATION' error if station
2821            JP   Z,#2932,REP_9       number is 0.
2824            CP   10                  Give the error also if station number
2826            JP   C,#2932,REP_9       in the range 1..9.
2829            LD   (#029C),A           Store the station number.
282C            LD   A,(#1DE4)
282F            CP   #4E                 Finished if DISCiPLE was a PUPIL
2831            JP   Z,#0165,END         already.
2834            LD   A,#4E
2836            LD   (#1DE4),A           Otherwise signal 'PUPIL mode'.
2839            JP   #2940,REP_16        And report 'PUPIL set'.

THE 'CAT' COMMAND SYNTAX ROUTINE
This routine handles the syntax checking and the execution of the 'CAT' command.

283C CAT        LD   HL,#1E06            "*" is the default name of the files
283F            LD   (HL),"*"            being CATted.
2841            CALL #0465,EXPT_DEVN     Evaluate drive number.
2844            CALL #0426,SEPARATOR     Evaluate the filename if there is a
2847            CALL Z,#04C1,EXP_F_NAME  separator.
284A            CP   "!"                 If an "!" is present it is thrown away.
284C            JR   NZ,#284F,CAT1
284E            RST  #28,NEXT_C_ROM      Ignore "!".
284F CAT1       CALL #0155,ST_END_ROM    Confirm end of statement and exit if
                                         syntax checking.
2852            CALL #08B1,REQ_SERV      Request service by a master or an
                                         assistant station.
2855            RST  #10,CALBAS          Clear the screen.
2856            DEFW #0DAF,CL_ALL
2858            CALL #39A9,OPEN_N        Open the "N" channel.
285B CAT2       CALL #3819,NCHAN_IN      Read a byte from the network.
285E            JR   C,#2868,CAT3        Jump if acceptable byte.
2860            JR   Z,#285B,CAT2        Try again if no byte has been read.
2862            CALL #39DF,SEND_NEOF     ? Why send EOF block, it's a read
                                         channel.
2865            JP   #0165,END           Finished.

2868 CAT3       RST  #10,CALBAS          Print the received character on the
2869            DEFW #0010,PRINT_A_1     current stream.
286B            JR   #285B,CAT2

THE 'ERASE' COMMAND SYNTAX ROUTINE
The ERASE command can be given by a PUPIL but the 'NET_SERVER' routine in the system
file ignores it completely.

286D ERASE      RST  #28,NEXT_C_ROM      Advance CH_ADD.
286E            LD   (#1E04),A           Store the device descriptor.
2871            CP   """                 Test for Microdrive syntax if it was a
2873            CALL Z,#0445,MD_SYNTAX1  quote.
2876            CALL #0465,EXPT_DEVN     Evaluate the drive number.
2879            CALL #0426,SEPARATOR     A filename must be specified, give
287C            JP   NZ,#2922,REP_1      'Nonsense in GNOS' if no separator
                                         present.
287F            CALL #04C1,EXP_F_NAME    Evaluate filename.
2882            CALL #0155,ST_END_ROM    Confirm end of statement and exit
                                         during syntax checking.
2885            LD   A,(#1E04)           Fetch device descriptor.
2888            AND  #DF                 Drop lower case bit.
288A            CP   "D"
288C            JR   Z,#2893,ERASE1      Jump if it's "D".
288E            CP   "M"                 Give 'Invalid DEVICE' error if it isn't
2890            JP   NZ,#2934,REP_10     "M".
2893 ERASE1     CALL #08B1,REQ_SERV      Request service by a master or
2896            JP   #0165,END           assistant. Finished.

THE 'HOOKCODES NOT IMPLEMENTED' ROUTINE
A PUPIL system doesn't support hook and command codes so give an error.

2899 REPORT_17  JP   #2942,REP_17        Give 'Invalid CODE'.

THE 'COPY NOT IMPLEMENTED' ROUTINE
Making screendumps on the network printer isn't allowed.

289C COPY       JP   #2942,REP_17        Give 'Invalid CODE'.

THE '"P" CHANNEL OUTPUT' ROUTINE
This routine handles the PUPIL's "P" channel, the only thing it has to do is sending
a PRINT command block to the master.

289F PCHAN_OUT  PUSH AF
28A0            LD   A,1                 Destination station is the master
28A2            LD   (#1DFD),A           station.
28A5            LD   A,245               This is the 'PRINT' code.
28A7            LD   (#1DFF),A
28AA            POP  AF
28AB            LD   (#1E00),A           Store byte to be printed in command block.
28AE            JP   #08D2,REQ_SERV3     Send the command block and exit.

THE 'REQUEST SERVICE' SUBROUTINE
This routine handles the sending of a command block to the master or one of its
assistant stations. The station to which it is sended is determined by the drive
number. E.g. the 'CAT' command; when CAT n is given with n between 0 and 9 the command
block is send to the master station. Lies n within the range 20..29 then the command
block is send to station 2. So to select a certain destination station (within the
range 1..9), add it's station number times 10 to the drive number. (The master station
is selected when the range 0..19 is used.)

28B1 REQ_SERV   CALL #0403,TEST_SERV     Exit when serving the network (master
28B4            RET  NZ                  has given a F command).
28B5            CALL #040D,TEST_NET      Exit when using the network in the
28B8            RET  NZ                  'normal' way (with a N command).
28B9            LD   A,(#1E01)           Otherwise fetch drive number.
28BC            LD   B,1                 B holds destination station number.
28BE            SUB  10                  Use master station if drive number is
28B0            JR   C,#28C9,REQ_SERV2   in the range 0..9.
28C2 REQ_SERV1  SUB  10                  Now calculate destination station.
28C4            JR   C,#28C9,REQ_SERV2   1=0..19, 2=20..29, . . , 9=90..99.
28C6            INC  B
28C7            JR   #28C2,REQ_SERV1

28C9 REQ_SERV2  ADD  A,10                Balance last 'SUB 10'.
28CB            LD   (#1E01),A           Store real drive number.
28CE            LD   A,B                 Store destination station number.
28CF            LD   (#1DFD),A
28D2 REQ_SERV3  LD   A,(#029C)           Fetch own station number from NSTAT.
28D5            LD   (#1DFE),A           Store it also.
28D8            LD   A,3                 Default stream.
28DA            LD   (#1E03),A

Now the command block checksum is calculated. Then the block and its checksum are send
over the network. #28DD is also the entry point for the send command block routine of
System 3d.

28DD REQ_SERV4  LD   HL,#1DFD            Point to the data buffer.
28E0            LD   B,28                Calculate checksum for 28 bytes.
28E2            XOR  A                   Clear checksum.
28E3 REQ_SERV5  ADD  A,(HL)              Add this byte.
28E4            INC  HL
28E5            DJNZ #28E3,REQ_SERV5     Repeat for all bytes.
28E7            LD   (HL),A              Store the checksum in command block.
28E8 REQ_SERV6  CALL #39ED,NET_STATE     Wait until the network is resting.
28EB            LD   HL,1000             Make the network active for about 57000
28EE            LD   A,(#1DDA)           T cycles.
28F1            OR   #80
28F3            OUT  (31),A
28F5 REQ_SERV7  DEC  HL
28F6            LD   A,H
28F7            OR   L
28F8            JR   NZ,#28F5,REQ_SERV7
28FA            LD   A,(#1DDA)           Make the network inactive.
28FD            OUT  (31),A
28FF            LD   B,10                Wait for 125 T cycles.
2901 REQ_SERV8  DJNZ #2901,REQ_SERV8
2903            LD   HL,#1DFD            Start of command block.
2906            LD   E,29                Length.
2908            CALL #3ABC,OUTPAK        Send command block.
290B            LD   HL,#1DF4            Address to store network response code.
290E            LD   (HL),0
2910            LD   E,1                 A single byte is to be received.
2912            CALL #3A87,INPAK         Get response byte.
2915            JR   NZ,#28E8,REQ_SERV6  Send the command block until a response
                                         is received.
2917            LD   A,(#1DF4)
291A            CP   1                   The response byte must be '1'.
291C            JR   NZ,#28E8,REQ_SERV6  Resend the command block until a valid
                                         response byte is received.
291E            RET                      Finished.
291F            DEFB #00                 An unused location.
Previous Next Contents Index