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 #2665 finds a 'TO' keyword. The return address to the routine which called
'EXPT_PARMS' is dropped at #230E.
2308 TO CALL #3108,TEST_SAVE
230B JP Z,#1644,REP_0 Give error if not SAVEing.
230E POP HL Drop return address to SAVE routine.
230F CALL #2626,SWAP_UFIAS Swap the UFIAS.
2312 RST #28,NEXT_C
2313 AND #DF Drop lower case bit.
2315 CP 68,"D"
2317 JP NZ,#1644,REP_0 Jump if 2nd device isn't "D".
231A LD (#3E04),A Store it in DEV_TYPE1.
231D CALL #25E2,EXPT_DEVN Evaluate drive num., store it in UFIA1.
2320 CALL #25A2,SEPARATOR Test for a separator, jump if one
2323 JR Z,#2328,TO_1 found, i.e. a 2nd name is given.
2325 CALL #1608,SIGN_4 Used here to signal 'use source
filename for destination file'.
2328 TO_1 CALL Z,#2640,EXPT_FNAME Evaluate filename if there was a
232B CALL #2626,SWAP_UFIAS Swap the UFIAS again.
232E CALL #3148,ST_END_RAM Confirm end of statement and exit
during syntax checking.
2331 LD HL,#3E1E Copy the second filename and directory
2334 LD DE,#3E32 description.
2337 LD BC,11
233C LD HL,#0001 Track 0 sector 1.
233F LD (#3DED),HL
2342 LD HL,#0000 Disk buffer offset #0000.
2345 LD (#3DEB),HL
2348 TO_2 CALL #0702,TEST_DRV Is the drive defined?
234B CALL #23EC,TO_SEARCH Search for a file to be copied.
234E JP NZ,#23BF,TO_EXIT Jump if there are no files left.
2351 CALL #0C04,LOAD_1ST Copy file description (directory
description and filename) to UFIA2 and
load the first sector of the file into
the disk buffer.
2354 LD A,(#3E1E) Get directory description.
2357 CP 5
2359 JR Z,#2348,TO_2 Jump with 'Snapshot 48K'.
235B CP 6
235D JR Z,#2348,TO_2 Jump with 'Microdrive file'.
235F CP 9
2361 JR Z,#2348,TO_2 Jump with 'Snapshot 128K'.
2363 CP 10
2365 JR Z,#2348,TO_2 Jump with 'Opentype file'.
2367 CP 11
2369 JR Z,#2348,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.
236B CALL #28CD,LOAD_HEAD2 Copy the file header (the 9 bytes
consisting of filetype, length, etc.)
236E LD HL,(23635) Fetch start of BASIC program (PROG).
2371 INC H Add 256 to it.
2372 LD DE,(#3E2A) Fetch length of file (LENGTH2_1).
2376 CALL #079E,LOAD_FILE Load DE bytes, starting at address HL.
2379 CALL #23CB,TO_MSG Print the message "CHANGE disc ...." if
source drive is destination drive.
237C CALL #2626,SWAP_UFIAS Swap the UFIA's again. The header of
the loaded file is now held in UFIA1.
237F CALL #1630,TEST_4 Used here to test whether a 2nd
2382 JR NZ,#239A,TO_5 filename was given. Jump if not.
2384 LD HL,#3E33 Here the 2nd filename was stored.
2387 LD DE,#3E06 Start of filename of loaded file.
238A 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
238C TO_3 LD A,(HL)
238D CP 42,"*" With a '*' don't replace the remaining
238F JR Z,#239A,TO_5 characters.
2391 CP 63,"?" With a '?' in name 2 don't replace this
2393 JR Z,#2396,TO_4 character.
2395 LD (DE),A Store this character.
2396 TO_4 INC HL
2397 INC DE
2398 DJNZ #238C,TO_3 Repeat for all 'normal' characters.
239A TO_5 CALL #0702,TEST_DRV
239D CALL #0AD9,OFSM_2 Open the file for SAVEing.
23A0 JR NZ,#23B3,TO_6 Jump if file existed already and the
user didn't want to overwrite it.
23A2 CALL #2879,SAVE_HEAD1 SAVE the 9 header bytes to the file.
23A5 LD HL,(23635) Fetch start of BASIC (PROG), and add
23A8 INC H 256 to it. (here the file was loaded)
23A9 LD DE,(#3E11) Length of file.
23AD CALL #0850,HSVBK_2 Save the file.
23B0 CALL #0B89,CFSM Close the file.
23B3 TO_6 CALL #2626,SWAP_UFIAS Swap the UFIA's again.
23B6 CALL #15F4,SIGN_0 Signal 'at least one file has been
23B9 CALL #23CB,TO_MSG Print message "Input ..." if necessary
23BC JP #2348,TO_2 Repeat until no more files have to be
23BF TO_EXIT CALL #161C,TEST_0 Give error if there isn't one file
23C2 JP Z,#1678,REP_26 copied.
23C5 LD HL,#11B7,NEW Otherwise jump to the appropriate 'NEW'
23C8 JP #3137,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
messages "Insert SOURCE disc - press SPACE" and "Insert TARGET disc - press SPACE" are
printed in turn.
23CB TO_MSG LD A,(#3E01) Fetch source drive.
23CE LD B,A
23CF LD A,(#3E1A) Fetch destination drive.
23D2 CP B
23D3 RET NZ Return if they aren't equal.
23D4 RST #10,CALBAS Otherwise clear lower screen area.
23D5 DEFW #0D6E,CLS_LOWER
23D7 SET 5,(IY+2) Signal 'lower screen has to be cleared'
23DB CALL #30B5,TO_MSG1 Print "Input ... disc" message.
23DE CALL #0B75,BEEP Give a beep.
23E1 TO_WSPC LD A,#7F Keyboard row B-SPACE address.
23E3 IN A,(254)
23E6 JR C,#23E1,TO_WSPC Jump unless the SPACE key is pressed.
23E8 RST #10,CALBAS Clear lower screen.
23E9 DEFW #0D6E,CLS_LOWER
23EB 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.
23EC TO_SEARCH LD DE,(#3DED) Track & sector to DE.
23F0 LD A,D
23F1 CP 4 Jump if not reached track 4, i.e.
23F3 JR NZ,#23F8,TO_SEARCH1 directory hasn't been read completely.
23F5 CP 0 Reset Zero flag.
The directory isn't finished yet, so read sector and test the file(s).
23F8 TO_SEARCH1 CALL #05CC,RSAD Read sector E from track D.
23FB TO_SEARCH2 CALL #2433,TO_COPY Check if this file is to be copied.
23FE PUSH AF Store result (Zero flag).
23FF LD HL,(#3DEB) Disk buffer offset to HL.
2402 LD A,H
2403 CP 1
2405 JR Z,#2418,TO_NXTSEC Jump if second entry.
2407 LD A,(#3DDA) Fetch current control port status.
240A AND #04
240C JR NZ,#2418,TO_NXTSEC Jump with single density.
240E LD HL,256 Otherwise offset is for second entry.
2411 LD (#3DEB),HL
2414 POP AF Restore Zero flag.
2415 RET Z Return if this file is to be copied.
2416 JR #23FB,TO_SEARCH2 Otherwise next file.
The file entries of the current sector have been tested so point to the next sector.
2418 TO_NXTSEC LD HL,0 Offset is for first entry.
241B LD DE,(#3DED) Fetch track and sector.
241F INC E Next sector.
2420 LD A,E
2421 CP 11
2423 JR NZ,#2428,TO_NXT1 Jump if not last sector on this track.
2425 LD E,1 Start with sector 1.
2427 INC D Next track.
2428 TO_NXT1 LD (#3DED),DE Store track & sector.
242C LD (#3DEB),HL Store disk buffer offset.
242F POP AF Restore Zero flag.
2430 RET Z Return if previous file is to be
2431 JR #23F8,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.
2433 TO_COPY LD HL,#3BD6 Point to start of sector.
2436 LD DE,(#3DEB) Offset to DE.
243A LD (IX+14),D Update RPT (RAM PoinTer (?)).
243D ADD HL,DE Update HL.
243E LD A,(HL) Fetch directory description.
243F AND A
2440 JR NZ,#2444,TO_COPY1 Jump if the file isn't ERASEd.
2442 INC A Reset Zero flag to signal 'do not copy
2443 RET this file' and exit.
2444 TO_COPY1 INC HL Step past directory descriptor.
2445 LD DE,#3E06 DE now points to FILE_NAME1.
2448 LD B,10 A filename is 10 characters long.
244A TO_COPY2 LD A,(DE) Fetch character.
244B CP 42,"*" If it was a '*' all other characters
244D RET Z don't matter. Signal 'copy this one'.
244E CP 63,"?" If it was a '?' this character doesn't
2450 JR Z,#2456,TO_COPY3 matter.
2452 XOR (HL)
2453 AND #DF Upper and lower case? don't bother.
2455 RET NZ Exit if characters are unequal.
2456 TO_COPY3 INC DE Check next character.
2457 INC HL
2458 DJNZ #244A,TO_COPY2
245A RET Finished.
THE 'CAT' COMMAND SYNTAX ROUTINE
This routine checks that the command is in the form CAT <#s;>d<<;>n$>.
245B CAT LD IX,#3AC3 Point to the +D workspace.
245F LD HL,#3E06 "*" is the default name of the files
2462 LD (HL),42,"*" being CATted.
2464 LD HL,#3E03 Just like #2 is the default output
2467 LD (HL),2 stream.
2469 RST #28,NEXT_C Get next character.
246A CP 13 Give an error if an 'end of line' (CR)
246C JP Z,#1648,REP_2 is found right after "CAT".
246F CP 58,":"
2471 JP Z,#1648,REP_2 Same error for ":".
2474 CP 35,"#" Jump if no stream specified, use
2476 JR NZ,#2481,CAT_DRV default stream #2.
2478 CALL #2AEF,EXPT_#NR Evaluate stream number.
247B CALL #25A2,SEPARATOR Check if there is a separator.
247E JP NZ,#1644,REP_0 Give an error if no separator found.
2481 CAT_DRV CALL #25FA,EXPT_DEVN2 Evaluate drive number.
2484 CALL #25A2,SEPARATOR Evaluate filename if there is a
2487 CALL Z,#2640,EXPT_FNAME separator.
248A CP 33,"!" If there is no "!" then an extended
248C JR NZ,#2499,EXT_CAT catalogue is given.
248E RST #28,NEXT_C Next character.
248F CALL #3148,ST_END_RAM Confirm end of statement and exit when
2492 CALL #0702,TEST_DRV See if drive is defined.
2495 LD A,%00000010 Signal 'small' CAT.
2497 JR #24A4,DO_CAT1
2499 EXT_CAT CALL #3148,ST_END_RAM Confirm end of statement and exit
during syntax time.
249C RST #10,CALBAS Clear the screen by calling 'main' ROM
249D DEFW #0DAF,CL_ALL routine.
249F DO_CAT CALL #0702,TEST_DRV See if drive is defined.
24A2 LD A,%00000100 Signal extended CAT.
24A4 DO_CAT1 CALL #24B5,CAT_RUN Give the CAT.
24A7 JP #047C,END Finished.
THE 'CAT' COMMAND ROUTINE
This routine makes a catalogue of the disk inserted in the specified drive, by calling
the +D ROM routine 'SCAN_CAT'.
24AA CAT_1 LD HL,#3E06 Point to name.
24AD LD (HL),42,"*" All files.
24AF LD HL,#3E03 Point to stream number.
24B2 LD A,2 Make it stream 2.
24B4 LD (HL),A
24B5 CAT_RUN PUSH AF
24B6 LD A,(#3E03)
24B9 RST #10,CALBAS Open the desired stream by calling
24BA DEFW #1601,CHAN_OPEN 'CHAN_OPEN' in the 'main' ROM.
24BC LD A,13
24BE CALL #1799,PRT_A Printing starts on the next line.
24C1 CALL #304B,MSG_0 Print the 1st part of "DIR"-message.
24C4 LD A,(#3ACE) Fetch current drive.
24C7 AND #03 Only bits 0&1.
24C9 OR #30 Make ASCII "1" or "2".
24CB CALL #1799,PRT_A Print drive number.
24CE CALL #3061,MSG_1 Print the 2nd part of "DIR"-message.
24D1 LD HL,0 Reset 'total number of sectors'
24D4 LD (#3DD8),HL occupied.
24D7 POP AF Restore 'CAT' type.
24D8 CALL #09A5,SCAN_CAT Print the CAT entries.
24DB CALL #3072,MSG_2 Print "Free ..." message.
24DE CALL #0985,DRV_CAP Get drive capacity in A register.
24E1 PUSH BC
24E2 BIT 7,A
24E4 JR Z,#24E7,CAT_RUN1 Jump if drive is single sided.
24E6 ADD A,A Otherwise double the number of tracks
and get rid of the side bit.
24E7 CAT_RUN1 SUB 4 Subtract number of catalogue tracks.
24E9 LD HL,0
24EC LD B,10 Each track has 10 sectors.
24EE LD D,0 Number of tracks to DE.
24F0 LD E,A
24F1 CAT_RUN2 ADD HL,DE Calculate total number of sectors.
24F2 DJNZ #24F1,CAT_RUN2
24F4 POP BC
24F5 NOP New code is two bytes shorter.
24F7 LD DE,(#3DD8) Get number of used sectors.
24FB XOR A Clear carry.
24FC SBC HL,DE Calculate number of free sectors.
24FE SRL H Divide it by two to get number of free
2500 RR L K-bytes.
2502 XOR A
2503 CALL #174C,PRT_N1000 Print the number.
2506 LD A,13
2508 CALL #1799,PRT_A Print a newline.
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 +D syntax ('d'd<;>) or Microdrive syntax
250C ERASE RST #28,NEXT_C Get next character.
250D LD (#3E04),A Store the device descriptor.
2510 CP 34,""" Test for Microdrive syntax if it was a
2512 CALL Z,#25C2,MD_SYN1 quote.
2515 CALL #25E2,EXPT_DEVN Evaluate the drive number.
2518 CALL #25A2,SEPARATOR Test for a separator.
251B JP NZ,#1644,REP_0 Give error if none found.
251E CALL #2640,EXPT_FNAME Evaluate filename.
2521 CP 204,"TO" Is the filename followed by "TO"?
2523 JR Z,#2561,RENAME Jump if so, rename is wanted.
2525 CALL #3148,ST_END_RAM Confirm end of statement and exit
during syntax checking.
2528 LD A,(#3E04) Fetch device descriptor.
252B AND #DF Drop lower case bit.
252D CP 68,"D"
252F JR Z,#2536,ERASE_RUN Jump if it was "D".
2531 CP 77,"M"
2533 JP NZ,#1658,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.
2536 ERASE_RUN CALL #0702,TEST_DRV See if drive is defined.
2539 ERASE_LOOP CALL #2559,FIND_FILE Find the file.
253C JR NZ,#2548,NOT_FOUND Jump if not found.
253E LD (HL),0 Directory description 0 means ERASEd.
2540 CALL #0584,WSAD Write sector DE.
2543 CALL #15F4,SIGN_0 Signal 'at least one file ERASEd'.
2546 JR #2539,ERASE_LOOP ERASE all files with this filename.
2548 NOT_FOUND CALL #161C,TEST_0 Give an error if there wasn't at least
254B JP Z,#1678,REP_26 one file ERASEd.
254E ERASE_EXIT LD A,(#3E04)
2551 CP 68,"D" If the device descriptor was a
2553 CALL Z,#24AA,CAT_1 (capital) "D", then give a CATalogue.
2556 JP #047C,END Finished.
THE 'FIND A FILE' SUBROUTINE
This routine searches the directory for a matching filename by calling the +D 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.
2559 FIND_FILE LD A,%00010000 Scan the CATalogue for a matching
255B CALL #09A5,SCAN_CAT filename.
255E JP #0D93,RPT_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.
2561 RENAME RST #28,NEXT_C Get next character.
2562 CALL #25A2,SEPARATOR Check if there is a separator.
2565 JP NZ,#1644,REP_0 Give an error if none found.
2568 CALL #2620,EXPT_2FNAM Evaluate 2nd filename.
256B CALL #3148,ST_END_RAM Confirm end of statement and exit when
256E LD A,(#3E04) Fetch device descriptor.
2571 AND #DF Drop lower case bit.
2573 CP 68,"D"
2575 JR Z,#257C,RENAME_RUN Jump if it was a "D".
2577 CP 77,"M"
2579 JP NZ,#1658,REP_10 Give error if it wasn't a "M".
257C RENAME_RUN CALL #0702,TEST_DRV See if the drive is defined.
257F CALL #2626,SWAP_UFIAS Swap UFIA 1 & 2 in the DFCA.
2582 CALL #2559,FIND_FILE Give an error if the 2nd filename
2585 JP Z,#167C,REP_28 already exists.
2588 CALL #2626,SWAP_UFIAS Swap UFIA 1 & 2 in the DFCA.
258B CALL #2559,FIND_FILE Give an error if the 1st filename
258E JP NZ,#1678,REP_26 doesn't exist.
2591 INC HL
2592 PUSH DE
2593 LD DE,#3E1F Rename the file by copying the 2nd to
2596 EX DE,HL the 1st name.
2597 LD BC,10
259C POP DE
259D CALL #0584,WSAD Write the CATalogue sector.
25A0 JR #254E,ERASE_EXIT Exit via 'ERASE_EXIT'.