Previous Next Contents Index
The BASIC command execution routines I

THE 'COPY FILE(S)' ROUTINE
This routine handles the copying of files. It is executed as soon as the 'EXPT_PARMS'
routine at #AEF finds a 'TO' keyword. The return address to the routine which called
'EXPT_PARMS' is dropped at #0708.

0702 TO         CALL #0A0F,TEST_SAVE
0705            JP   Z,#2920,REP_0       Give error if not SAVEing.
0708            POP  HL                  Drop return address to SAVE routine.
0709            CALL #0AA2,SWAP_UFIAS    Swap the UFIAS.
070C            RST  #28,NEXT_C_RAM
070D            AND  #DF                 Drop lower case bit.
070F            CP   "D"
0711            JP   NZ,#2920,REP_0      Jump if 2nd device isn't "D".
0714            LD   (#1E04),A           Store it in DEV_TYPE1.
0717            CALL #0A5E,EXPT_DEVN     Evaluate drive number, store it in UFIA1.
071A            CALL #0A1E,SEPARATOR     Test for a separator, jump if one
071D            JR   Z,#0722,TO_1        found, i.e. a 2nd name is given.
071F            CALL #09E2,SIGN_LOAD     Used here to signal 'use source filename
                                         for destination file'.
0722 TO_1       CALL Z,#0ABC,EXP_F_NAME  Evaluate filename if there was a
                                         separator.
0725            CALL #0AA2,SWAP_UFIAS    Swap the UFIAS again.
0728            CALL #0409,ST_END_RAM    Confirm end of statement and exit
                                         during syntax checking.
072B            LD   HL,#1E1E            Copy the second filename and directory
072E            LD   DE,#1E32            description.
0731            LD   BC,11
0734            LDIR
0736            LD   HL,#0001            Track 0 sector 1.
0739            LD   (#1DED),HL
073C            LD   HL,#0000            Disk buffer offset #0000.
073F            LD   (#1DEB),HL
0742 TO_2       CALL #2984,JTEST_DRV     Is the drive defined?
0745            CALL #07E6,TO_SEARCH     Search for a file to be copied.
0748            JP   NZ,#07B9,TO_EXIT    Jump if there are no files left.
074B            CALL #299F,JLOAD_1ST     Copy file description (directory
                                         description and filename) to UFIA2 and
                                         load the first sector of the file into
                                         the disk buffer.
074E            LD   A,(#1E1E)           Get directory description.
0751            CP   5
0753            JR   Z,#0742,TO_2        Jump with 'Snapshot 48K'.
0755            CP   6
0757            JR   Z,#0742,TO_2        Jump with 'Microdrive file'.
0759            CP   9
075B            JR   Z,#0742,TO_2        Jump with 'Snapshot 128K'.
075D            CP   10
075F            JR   Z,#0742,TO_2        Jump with 'Opentype file'.
0761            CP   11
0763            JR   Z,#0742,TO_2        Jump with 'Execute file'.
                                         These five file types can't be copied
                                         with the 'SAVE .. TO ..' command.

Now the file is going to be copied.
NOTE: The file to be copied will destroy everything above 'start of BASIC'+256 and
no checks are made if the file fits in memory and if the stack isn't overwritten.

0765            CALL #0DE1,LOAD_HEAD2    Copy the file header (the 9 bytes
                                         consisting of filetype, length, etc.)
                                         to UFIA2.
0768            LD   HL,(23635)          Fetch start of BASIC program (PROG).
076B            INC  H                   Add 256 to it.
076C            LD   DE,(#1E2A)          Fetch length of file (LENGTH2_1).
0770            CALL #29A5,JLOAD_FILE    Load DE bytes, starting at address HL.
0773            CALL #07C5,TO_MSG        Print the message "CHANGE disc ...." if
                                         source drive is destination drive.
0776            CALL #0AA2,SWAP_UFIAS    Swap the UFIA's again. The header of
                                         the loaded file is now held in UFIA1.
0779            CALL #0A0A,TEST_LOAD     Used here to test whether a 2nd
077C            JR   NZ,#0794,TO_5       filename was given. Jump if not.
077E            LD   HL,#1E33            Here the 2nd filename was stored.
0781            LD   DE,#1E06            Start of filename of loaded file.
0784            LD   B,10                Filename length.

Now the characters from the filename of the loaded file are replaced by the characters
of the 2nd filename. Except when the wildcard characters '*' and '?' were used in the
2nd name. With '*' all next characters are left unchanged, with '?' the current
character isn't changed.

0786 TO_3       LD   A,(HL)
0787            CP   "*"                 With a '*' don't replace the remaining
0789            JR   Z,#0794,TO_5        characters.
078B            CP   "?"                 With a '?' in name 2 don't replace this
078D            JR   Z,#0790,TO_4        character.
078F            LD   (DE),A              Store this character.
0790 TO_4       INC  HL
0791            INC  DE
0792            DJNZ #0786,TO_3          Repeat for all 'normal' characters.
0794 TO_5       CALL #2984,JTEST_DRV
0797            CALL #29A8,JOFSM_2       Open the file for SAVEing.
079A            JR   NZ,#07AD,TO_6       Jump if file existed already and the
                                         user didn't want to overwrite it.
079C            CALL #0D2F,SAVE_HEAD1    SAVE the 9 header bytes to the file.
079F            LD   HL,(23635)          Fetch start of BASIC (PROG), and add
07A2            INC  H                   256 to it. (here the file was loaded)
07A3            LD   DE,(#1E11)          Length of file.
07A7            CALL #29C9,JHSVBK_2      Save the file.
07AA            CALL #2981,JCFSM         Close the file.
07AD TO_6       CALL #0AA2,SWAP_UFIAS    Swap the UFIA's again.
07B0            CALL #09CE,SIGN_1HAND    Signal 'at least one file has been
                                         copied'
07B3            CALL #07C5,TO_MSG        Print message "CHANGE ..." if necessary.
07B6            JP   #0742,TO_2          Repeat until no more files have to be
                                         copied.

07B9 TO_EXIT    CALL #09F6,TEST_1HAND    Give error if there isn't one file
07BC            JP   Z,#2954,REP_26      copied.
07BF            LD   HL,#11B7            Otherwise jump to the appropriate 'NEW'
07C2            JP   #160D,TO_NEW        routine (128K or 48K).

THE 'PRINT "CHANGE DISC"' SUBROUTINE
This subroutine tests whether source and destination drives are equal. If they are
the message "CHANGE disc ..press SPACE" is printed.

07C5 TO_MSG     LD   A,(#1E01)           Fetch source drive.
07C8            LD   B,A
07C9            LD   A,(#1E1A)           Fetch destination drive.
07CC            CP   B
07CD            RET  NZ                  Return if they aren't equal.
07CE            RST  #10,CALBAS          Otherwise clear lower screen area.
07CF            DEFW #0D6E,CLS_LOWER
07D1            SET  5,(IY+2)            Signal 'lower screen has to be cleared'.
07D5            CALL #19E3,MSG_4         Print "CHANGE disc ..." message.
07D8            CALL #297E,JDISC_BEEP    Give a beep.
07DB TO_SPC_KEY LD   A,#7F               Keyboard row B-SPACE address.
07DD            IN   A,(254)
07DF            RRA
07E0            JR   C,#07DB,TO_SPC_KEY  Jump unless the SPACE key is pressed.
07E2            RST  #10,CALBAS          Clear lower screen.
07E3            DEFW #0D6E,CLS_LOWER
07E5            RET                      Finished.

THE 'SEARCH FILES' SUBROUTINE
This subroutine searches for files which have to be copied. It returns with the Zero
flag set if the current file is to be copied, if the complete directory is searched
the routine returns with Zero reset.

07E6 TO_SEARCH  LD   DE,(#1DED)          Track & sector to DE.
07EA            LD   A,D
07EB            CP   4                   Jump if not reached track 4, i.e.
07ED            JR   NZ,#07F2,TO_SEARCH1 directory hasn't been read completely.
07EF            CP   0                   Reset Zero flag.
07F1            RET

The directory isn't finished yet, so read sector and test the file(s).

07F2 TO_SEARCH1 CALL #29BD,JRSAD         Read sector E from track D.
07F5 TO_SEARCH2 CALL #082D,TO_COPY       Check if this file is to be copied.
07F8            PUSH AF                  Store result (Zero flag).
07F9            LD   HL,(#1DEB)          Disk buffer offset to HL.
07FC            LD   A,H
07FD            CP   1
07FF            JR   Z,#0812,TO_NXT_SEC  Jump if second entry.
0801            LD   A,(#1DDA)           Fetch current control port status.
0804            AND  #04
0806            JR   NZ,#0812,TO_NXT_SEC Jump with single density.
0808            LD   HL,256              Otherwise offset is for second entry.
080B            LD   (#1DEB),HL
080E            POP  AF                  Restore Zero flag.
080F            RET  Z                   Return if this file is to be copied.
0810            JR   #07F5,TO_SEARCH2    Otherwise next file.

The file entries of the current sector have been tested so point to the next sector.

0812 TO_NXT_SEC LD   HL,0                Offset is for first entry.
0815            LD   DE,(#1DED)          Fetch track and sector.
0819            INC  E                   Next sector.
081A            LD   A,E
081B            CP   11
081D            JR   NZ,#0822,TO_NXT1    Jump if not last sector on this track.
081F            LD   E,1                 Start with sector 1.
0821            INC  D                   Next track.
0822 TO_NXT1    LD   (#1DED),DE          Store track & sector.
0826            LD   (#1DEB),HL          Store disk buffer offset.
0829            POP  AF                  Restore Zero flag.
082A            RET  Z                   Return if previous file is to be
082B            JR   #07E6,TO_SEARCH     copied. Otherwise jump.

THE 'COPY THIS FILE ?' SUBROUTINE
This subroutine checks if the 'current' filename is to be  copied. The routine returns
with the Zero flag set to signal yes and RPT pointing to the directory description of
the file to be copied.

082D TO_COPY    LD   HL,#1BD6            Point to start of sector.
0830            LD   DE,(#1DEB)          Offset to DE.
0834            LD   (IX+14),D           Update RPT (RAM PoinTer (?)).
0837            ADD  HL,DE               Update HL.
0838            LD   A,(HL)              Fetch directory description.
0839            AND  A
083A            JR   NZ,#083E,TO_FILE    Jump if the file isn't ERASEd.
083C            INC  A                   Reset Zero flag to signal 'do not copy
083D            RET                      this file' and exit.
083E TO_FILE    INC  HL                  Step past directory descriptor.
083F            LD   DE,#1E06            DE now points to FILE_NAME1.
0842            LD   B,10                A filename is 10 characters long.
0844 TO_COPY_L  LD   A,(DE)              Fetch character.
0845            CP   "*"                 If it was a '*' all other characters
0847            RET  Z                   don't matter. Signal 'copy this one'.
0848            CP   "?"                 If it was a '?' this character doesn't
084A            JR   Z,#0850,TO_COPY1    matter.
084C            XOR  (HL)
084D            AND  #DF                 Upper and lower case? don't bother.
084F            RET  NZ                  Exit if characters are unequal.
0850 TO_COPY1   INC  DE                  Check next character.
0851            INC  HL
0852            DJNZ #0844,TO_COPY_L
0854            RET                      Finished.

THE 'CAT' COMMAND SYNTAX ROUTINE
This routine checks that the command is in the form CAT <#s;>d<<;>n$><!>.

0855 CAT        LD   IX,#1AC3            Point to the DISCiPLE workspace.
0859            CALL #09FB,TEST_SERV     Check if a 'pupil' requested a CAT.
085C            JP   NZ,#089F,DO_CAT     Jump if serving a 'pupil'.
085F            LD   HL,#1E06            "*" is the default name of the files
0862            LD   (HL),#2A            being CATted.
0864            LD   HL,#1E03            Just like #2 is the default output
0867            LD   (HL),#02            stream.
0869            RST  #28,NEXT_C_RAM      Get next character.
086A            CP   13                  Give an error if an 'end of line' (CR)
086C            JP   Z,#2924,REP_2       is found right after "CAT".
086F            CP   ":"
0871            JP   Z,#2924,REP_2       Same error for ":".
0874            CP   "#"                 Jump if no stream specified, use
0876            JR   NZ,#0881,CAT_DRV    default stream #2.
0878            CALL #109D,EXPT_#_NR     Evaluate stream number.
087B            CALL #0A1E,SEPARATOR     Check if there is a separator.
087E            JP   NZ,#2920,REP_0      Give an error if no separator found.
0881 CAT_DRV    CALL #0A76,EXPT_DEVN2    Evaluate drive number.
0884            CALL #0A1E,SEPARATOR     Evaluate filename if there is a
0887            CALL Z,#0ABC,EXP_F_NAME  separator.
088A            CP   "!"                 If there is no "!" then an extended
088C            JR   NZ,#0899,EXT_CAT    catalogue is given.
088E            RST  #28,NEXT_C_RAM      Next character.
088F            CALL #0409,ST_END_RAM    Confirm end of statement and exit when
                                         syntax checking.
0892            CALL #2984,JTEST_DRV     See if drive is defined.
0895            LD   A,#02               Signal 'small' CAT.
0897            JR   #08A4,DO_CAT1

0899 EXT_CAT    CALL #0409,ST_END_RAM    Confirm end of statement and exit
                                         during syntax time.
089C            RST  #10,CALBAS          Clear the screen by calling 'main' ROM
089D            DEFW #0DAF,CL_ALL        routine.
089F DO_CAT     CALL #2984,JTEST_DRV     See if drive is defined.
08A2            LD   A,#04               Signal extended CAT.
08A4 DO_CAT1    CALL #08B5,CAT_RUN       Give the CAT.
08A7            JP   #0419,END           Finished.

THE 'CAT' COMMAND ROUTINE
This routine makes a catalogue of the disk inserted in the specified drive, by
calling the DISCiPLE ROM routine 'SCAN_CAT'. It has two entry points: #08AA for the
command code 67, and #08B5 for the BASIC 'CAT' command. The first entry point was
somewhat changed in 'Sys 3d' to make the command code work.

08AA PCAT       CALL #2984,JTEST_DRV     Drive defined?
08AD            LD   A,(#1E10)           Get 'CAT' type.
08B0            NOP
08B1            NOP
08B2            NOP
08B3            NOP
08B4            NOP
08B5 CAT_RUN    PUSH AF
08B6            CALL #09FB,TEST_SERV     Serving the network?
08B9            CALL NZ,#0924,OPEN_N_CH  Open the "N" channel if so.
08BC            LD   A,(#1E03)
08BF            RST  #10,CALBAS          Open the desired stream by calling
08C0            DEFW #1601,CHAN_OPEN     'CHAN_OPEN' in the 'main' ROM.
08C2            LD   A,13
08C4            CALL #29AE,JPRT_A        Printing starts on the next line.
08C7            CALL #1979,MSG_0         Print the 1st part of "DIR"-message.
08CA            LD   A,(#1ACE)           Fetch current drive, 0=2, 1=1.
08CD            AND  #01                 Only bit0.
08CF            XOR  49                  Make ASCII "1" or "2".
08D1            INC  A
08D2            CALL #29AE,JPRT_A        Print drive number.
08D5            CALL #198F,MSG_1         Print the 2nd part of "DIR"-message.
08D8            LD   HL,#0000            Reset 'total number of sectors'
08DB            LD   (#1DD8),HL          occupied.
08DE            POP  AF                  Restore 'CAT' type.
08DF            CALL #2993,JSCAN_CAT     Print the CAT entries.
08E2            CALL #19A0,MSG_2         Print "Free ..." message.
08E5            CALL #29CC,JDRV_CAP      Get drive capacity in A register.

The 'Sys 3b' system couldn't cope with non 40, 80 tracks drives (both single and double
sided), the amount of free space was calculated as if it was an 80 tracks double sided
drive. In 'Sys 3c' this was cured.

08E8            PUSH BC
08E9            BIT  7,A
08EB            JR   Z,#08EE,CAT_RUN1    Jump if drive is single sided.
08ED            ADD  A,A                 Otherwise double the number of tracks and
                                         get rid of the side bit.
08EE CAT_RUN1   SUB  4                   Subtract number of catalogue tracks.
08F0            LD   HL,0
08F3            LD   B,10                Each track has 10 sectors.
08F5            LD   D,0                 Number of tracks to DE.
08F7            LD   E,A
08F8 NO_SECTORS ADD  HL,DE               Calculate total number of sectors.
08F9            DJNZ #08F8,NO_SECTORS
08FB            POP  BC
08FC            NOP                      New code is two bytes shorter.
08FD            NOP
08FE            LD   DE,(#1DD8)          Get number of used sectors.
0902            XOR  A                   Clear carry.
0903            SBC  HL,DE               Calculate number of free sectors.
0905            SRL  H                   Divide it by two to get number of free
0907            RR   L                   K-bytes.
0909            LD   A,(#1DDA)           Fetch current control port status.
090C            AND  #04
090E            JR   Z,#0914,CAT_RUN2    Jump with double density drive.
0910            SRL  H                   Otherwise divide by two, SD sectors
                                         contain 256 bytes.
0912            RR   L
0914 CAT_RUN2   XOR  A
0915            CALL #29B1,JPRT_NUM      Print the number.
0918            LD   A,13
091A            CALL #29AE,JPRT_A        Print a newline.
091D            CALL #09FB,TEST_SERV
0920            RET  Z                   Return if not serving.
0921            JP   #2975,JSEND_NEOF    Otherwise send the EOF block over the
                                         network.

THE 'OPEN A NETWORK CHANNEL' ROUTINE
This subroutine is used to send the data, requested by a pupil, over the network.

0924 OPEN_N_CH  PUSH IX
0926            LD   A,(#1DFE)           Fetch pupil's station number.
0929            LD   (#1E01),A
092C            CALL #2960,JOPEN_N       Open the "n" channel.
092F            POP  IX
0931            RET

THE 'ERASE' COMMAND SYNTAX ROUTINE
This routine checks that the command is in the form ERASE *n$ to erase a file or
ERASE *n1$ TO n2$ to rename a file. The '*' stands for DISCiPLE syntax ('d'd<;>) or
Microdrive syntax ('"m"';d;).
NOTE: The routine starts with testing if it was a pupil requested ERASE command, the
'NET_SERVER' routine (at #0369) however doesn't allow pupils ERASEing files.

0932 ERASE      CALL #09FB,TEST_SERV
0935            JP   NZ,#0954,ERASE1     Jump if serving.
0938            RST  #28,NEXT_C_RAM      Get next character.
0939            LD   (#1E04),A           Store the device descriptor.
093C            CP   """                 Test for Microdrive syntax if it was a
093E            CALL Z,#0A3E,MD_SYNTAX1  quote.
0941            CALL #0A5E,EXPT_DEVN     Evaluate the drive number.
0944            CALL #0A1E,SEPARATOR     Test for a separator.
0947            JP   NZ,#2920,REP_0      Give error if none found.
094A            CALL #0ABC,EXPT_F_NAME   Evaluate filename.
094D            CP   204                 Is the filename followed by "TO"?
094F            JR   Z,#098D,RENAME      Jump if so, rename is wanted.
0951            CALL #0409,ST_END_RAM    Confirm end of statement and exit
                                         during syntax checking.
0954 ERASE1     LD   A,(#1E04)           Fetch device descriptor.
0957            AND  #DF                 Drop lower case bit.
0959            CP   "D"
095B            JR   Z,#0962,ERASE_RUN   Jump if it was "D".
095D            CP   "M"
095F            JP   NZ,#2934,REP_10     Give error if it wasn't "M".

THE 'ERASE A FILE' ROUTINE
This routine deletes the specified file(s) on the specified drive. First it calls the
routine 'FIND_FILE' to find a matching name, then it marks the file ERASEd by setting
the directory description to 0, the dir. entry is then SAVEd back to disc.

0962 ERASE_RUN  CALL #2984,JTEST_DRV     See if drive is defined.
0965 ERASE_LOOP CALL #0985,FIND_FILE     Find the file.
0968            JR   NZ,#0974,NOT_FOUND  Jump if not found.
096A            LD   (HL),0              Directory description 0 means ERASEd.
096C            CALL #29CF,JWSAD         Write sector DE.
096F            CALL #09CE,SIGN_1HAND    Signal 'at least one file ERASEd'.
0972            JR   #0965,ERASE_LOOP    ERASE all files with this filename.

The file wasn't found, an error is given if no file was ERASEd at all.

0974 NOT_FOUND  CALL #09F6,TEST_1HAND    Give an error if there wasn't at least
0977            JP   Z,#2954,REP_26      one file ERASEd.
097A EXIT_ERASE LD   A,(#1E04)
097D            CP   "D"                 If the device descriptor was a (capital)
097F            CALL Z,#08AA,PCAT        "D", then give a CATalogue.

Note: This doesn't work anymore because 'CAT'-type, filename and stream don't make
sense. This option was lost when the routine for command code 67 was repaired.
The following happens:
'STRM_NUM1' holds stream number -1 (=#FF, see #065A), which is attached to the
Spectrum "R"-channel (the "R"-channel is used to print characters into Spectrum
workspaces). When the CAT routine is called, the output is stored at the address
held in the Spectrum system variable 'K_CUR', which points to the edit line. Because
the filename is that of the just ERASEd file, the CAT consists only of the
'DISC .. DIRECTORY' message and the 'Free K-bytes' message.

0982            JP   #0419,END           Finished.

THE 'FIND A FILE' SUBROUTINE
This routine searches the directory for a matching filename by calling the DISCiPLE
ROM routine 'SCAN_CAT', it returns with HL pointing to the directory description of
the matching file. This routine is also called by command code 65 routine.

0985 FIND_FILE  LD   A,#10               Scan the CATalogue for a matching
0987            CALL #2993,JSCAN_CAT     filename.
098A            JP   #29B4,JRPT_HL       Make HL point to the start of the dir.
                                         entry buffer and exit.

THE 'RENAME A FILE' ROUTINE
This routine renames a file by replacing its filename, given first, by the filename
given second. It first tests whether the 'new' name isn't used already. If not, a check
is made whether the file to be renamed exists.

098D RENAME     RST  #28,NEXT_C_RAM      Get next character.
098E            CALL #0A1E,SEPARATOR     Check if there is a separator.
0991            JP   NZ,#2920,REP_0      Give an error if none found.
0994            CALL #0A9C,EXP_F_NAM2    Evaluate 2nd filename.
0997            CALL #0409,ST_END_RAM    Confirm end of statement and exit when
                                         synatx checking.
099A            LD   A,(#1E04)           Fetch device descriptor.
099D            AND  #DF                 Drop lower case bit.
099F            CP   "D"
09A1            JR   Z,#09A8,RENAME_RUN  Jump if it was a "D".
09A3            CP   "M"
09A5            JP   NZ,#2934,REP_10     Give error if it wasn't a "M".
09A8 RENAME_RUN CALL #2984,JTEST_DRV     See if the drive is defined.
09AB            CALL #0AA2,SWAP_UFIAS    Swap UFIA 1 & 2 in the DFCA.
09AE            CALL #0985,FIND_FILE     Give an error if the 2nd filename
09B1            JP   Z,#2958,REP_28      already exists.
09B4            CALL #0AA2,SWAP_UFIAS    Swap UFIA 1 & 2 in the DFCA.
09B7            CALL #0985,FIND_FILE     Give an error if the 1st filename
09BA            JP   NZ,#2954,REP_26     doesn't exist.
09BD            INC  HL
09BE            PUSH DE
09BF            LD   DE,#1E1F            Rename the file by copying the 2nd to
09C2            EX   DE,HL               the 1st name.
09C3            LD   BC,10
09C6            LDIR
09C8            POP  DE
09C9            CALL #29CF,JWSAD         Write the CATalogue sector.
09CC            JR   #097A,EXIT_ERASE    Exit via 'EXIT_ERASE'.
Previous Next Contents Index