Prev: 01507 Up: Map Next: 01995
01541: THE 'SAVE, LOAD, VERIFY and MERGE' COMMAND ROUTINES
Used by the routine at CLASS_0B.
This entry point is used for all four commands. The value held in T-ADDR, however, distinguishes between the four commands. The first part of the following routine is concerned with the construction of the 'header information' in the work space.
SAVE_ETC 01541 POP AF Drop the address - SCAN_LOOP.
01542 LD A,(23668) Reduce T-ADDR-lo by 224, giving 0 for SAVE, 1 for LOAD, 2 for VERIFY and 3 for MERGE.
01545 SUB 224
01547 LD (23668),A
01550 CALL CLASS_0A Pass the parameters of the 'name' to the calculator stack.
01553 CALL SYNTAX_Z Jump forward if checking syntax.
01556 JR Z,SA_DATA
01558 LD BC,17 Allow seventeen locations for the header of a SAVE (T-ADDR-lo=0) but thirty four for the other commands.
01561 LD A,(23668)
01564 AND A
01565 JR Z,SA_SPACE
01567 LD C,34
SA_SPACE 01569 RST 48 The required amount of space is made in the work space.
01570 PUSH DE Copy the start address to the IX register pair.
01571 POP IX
01573 LD B,11 A program name can have up to ten characters but first enter eleven space characters into the prepared area.
01575 LD A," "
SA_BLANK 01577 LD (DE),A
01578 INC DE
01579 DJNZ SA_BLANK
01581 LD (IX+1),255 A null name is 255 only.
01585 CALL STK_FETCH The parameters of the name are fetched and its length is tested.
01588 LD HL,65526 This is '-10'.
01591 DEC BC In effect jump forward if the length of the name is not too long (i.e. no more than ten characters).
01592 ADD HL,BC
01593 INC BC
01594 JR NC,SA_NAME
01596 LD A,(23668) But allow for the LOADing, VERIFYing and MERGEing of programs (T-ADDR-lo>0) with 'null' names or extra long names.
01599 AND A
01600 JR NZ,SA_NULL
Report F - Invalid file name.
01602 RST 8 Call the error handling routine.
01603 DEFB 14
Continue to handle the name of the program.
SA_NULL 01604 LD A,B Jump forward if the name has a 'null' length.
01605 OR C
01606 JR Z,SA_DATA
01608 LD BC,10 But truncate longer names.
The name is now transferred to the work space (second location onwards).
SA_NAME 01611 PUSH IX Copy the start address to the HL register pair.
01613 POP HL
01614 INC HL Step to the second location.
01615 EX DE,HL Switch the pointers over and copy the name.
01616 LDIR
The many different parameters, if any, that follow the command are now considered. Start by handling 'xxx "name" DATA'.
SA_DATA 01618 RST 24 Is the present code the token 'DATA'?
01619 CP 228
01621 JR NZ,SA_SCR Jump if not.
01623 LD A,(23668) However it is not possible to have 'MERGE name DATA' (T-ADDR-lo=3).
01626 CP 3
01628 JP Z,REPORT_C
01631 RST 32 Advance CH-ADD.
01632 CALL LOOK_VARS Look in the variables area for the array.
01635 SET 7,C Set bit 7 of the array's name.
01637 JR NC,SA_V_OLD Jump if handling an existing array.
01639 LD HL,0 Signal 'using a new array'.
01642 LD A,(23668) Consider the value in T-ADDR-lo and give an error if trying to SAVE or VERIFY a new array.
01645 DEC A
01646 JR Z,SA_V_NEW
Report 2 - Variable not found.
01648 RST 8 Call the error handling routine.
01649 DEFB 1
Continue with the handling of an existing array.
SA_V_OLD 01650 JP NZ,REPORT_C Note: this fails to exclude simple strings.
01653 CALL SYNTAX_Z Jump forward if checking syntax.
01656 JR Z,SA_DATA_1
01658 INC HL Point to the 'low length' of the variable.
01659 LD A,(HL) The low length byte goes into the work space, followed by the high length byte.
01660 LD (IX+11),A
01663 INC HL
01664 LD A,(HL)
01665 LD (IX+12),A
01668 INC HL Step past the length bytes.
The next part is common to both 'old' and 'new' arrays. Note: syntax path error.
SA_V_NEW 01669 LD (IX+14),C Copy the array's name.
01672 LD A,1 Assume an array of numbers.
01674 BIT 6,C Jump if it is so.
01676 JR Z,SA_V_TYPE
01678 INC A It is an array of characters.
SA_V_TYPE 01679 LD (IX+0),A Save the 'type' in the first location of the header area.
The last part of the statement is examined before joining the other pathways.
SA_DATA_1 01682 EX DE,HL Save the pointer in DE.
01683 RST 32 Is the next character a ')'?
01684 CP ")"
01686 JR NZ,SA_V_OLD Give report C if it is not.
01688 RST 32 Advance CH-ADD.
01689 CALL CHECK_END Move on to the next statement if checking syntax.
01692 EX DE,HL Return the pointer to the HL register pair before jumping forward. (The pointer indicates the start of an existing array's contents.)
01693 JP SA_ALL
Now consider 'SCREEN$'.
SA_SCR 01696 CP 170 Is the present code the token SCREEN$?
01698 JR NZ,SA_CODE Jump if not.
01700 LD A,(23668) However it is not possible to have 'MERGE name SCREEN$' (T-ADDR-lo=3).
01703 CP 3
01705 JP Z,REPORT_C
01708 RST 32 Advance CH-ADD.
01709 CALL CHECK_END Move on to the next statement if checking syntax.
01712 LD (IX+11),0 The display area and the attribute area occupy 6912 locations and these locations start at 16384; these details are passed to the header area in the work space.
01716 LD (IX+12),27
01720 LD HL,16384
01723 LD (IX+13),L
01726 LD (IX+14),H
01729 JR SA_TYPE_3 Jump forward.
Now consider 'CODE'.
SA_CODE 01731 CP 175 Is the present code the token 'CODE'?
01733 JR NZ,SA_LINE Jump if not.
01735 LD A,(23668) However it is not possible to have 'MERGE name CODE' (T-ADDR-lo=3).
01738 CP 3
01740 JP Z,REPORT_C
01743 RST 32 Advance CH-ADD.
01744 CALL PR_ST_END Jump forward if the statement has not finished.
01747 JR NZ,SA_CODE_1
01749 LD A,(23668) However it is not possible to have 'SAVE name CODE' (T-ADDR-lo=0) by itself.
01752 AND A
01753 JP Z,REPORT_C
01756 CALL USE_ZERO Put a zero on the calculator stack - for the 'start'.
01759 JR SA_CODE_2 Jump forward.
Look for a 'starting address'.
SA_CODE_1 01761 CALL CLASS_06 Fetch the first number.
01764 RST 24 Is the present character a comma?
01765 CP ","
01767 JR Z,SA_CODE_3 Jump if it is - the number was a 'starting address'.
01769 LD A,(23668) However refuse 'SAVE name CODE' that does not have a 'start' and a 'length' (T-ADDR-lo=0).
01772 AND A
01773 JP Z,REPORT_C
SA_CODE_2 01776 CALL USE_ZERO Put a zero on the calculator stack - for the 'length'.
01779 JR SA_CODE_4 Jump forward.
Fetch the 'length' as it was specified.
SA_CODE_3 01781 RST 32 Advance CH-ADD.
01782 CALL CLASS_06 Fetch the 'length'.
The parameters are now stored in the header area of the work space.
SA_CODE_4 01785 CALL CHECK_END But move on to the next statement now if checking syntax.
01788 CALL FIND_INT2 Compress the 'length' into the BC register pair and store it.
01791 LD (IX+11),C
01794 LD (IX+12),B
01797 CALL FIND_INT2 Compress the 'starting address' into the BC register pair and store it.
01800 LD (IX+13),C
01803 LD (IX+14),B
01806 LD H,B Transfer the 'pointer' to the HL register pair as usual.
01807 LD L,C
'SCREEN$' and 'CODE' are both of type 3.
SA_TYPE_3 01808 LD (IX+0),3 Enter the 'type' number.
01812 JR SA_ALL Rejoin the other pathways.
Now consider 'LINE' and 'no further parameters'.
SA_LINE 01814 CP 202 Is the present code the token 'LINE'?
01816 JR Z,SA_LINE_1 Jump if it is.
01818 CALL CHECK_END Move on to the next statement if checking syntax.
01821 LD (IX+14),128 When there are no further parameters, 128 is entered.
01825 JR SA_TYPE_0 Jump forward.
Fetch the 'line number' that must follow 'LINE'.
SA_LINE_1 01827 LD A,(23668) However only allow 'SAVE name LINE number' (T-ADDR-lo=0).
01830 AND A
01831 JP NZ,REPORT_C
01834 RST 32 Advance CH-ADD.
01835 CALL CLASS_06 Pass the number to the calculator stack.
01838 CALL CHECK_END Move on to the next statement if checking syntax.
01841 CALL FIND_INT2 Compress the 'line number' into the BC register pair and store it.
01844 LD (IX+13),C
01847 LD (IX+14),B
'LINE' and 'no further parameters' are both of type 0.
SA_TYPE_0 01850 LD (IX+0),0 Enter the 'type' number.
The parameters that describe the program, and its variables, are found and stored in the header area of the work space.
01854 LD HL,(23641) The pointer to the end of the variables area (E-LINE).
01857 LD DE,(23635) The pointer to the start of the BASIC program (PROG).
01861 SCF Now perform the subtraction to find the length of the 'program + variables'; store the result.
01862 SBC HL,DE
01864 LD (IX+11),L
01867 LD (IX+12),H
01870 LD HL,(23627) Repeat the operation but this time storing the length of the 'program' only (VARS-PROG).
01873 SBC HL,DE
01875 LD (IX+15),L
01878 LD (IX+16),H
01881 EX DE,HL Transfer the 'pointer' to the HL register pair as usual.
In all cases the header information has now been prepared.
  • The location 'IX+0' holds the type number.
  • Locations 'IX+1 to IX+10' hold the name (255 in 'IX+1' if null).
  • Locations 'IX+11 and IX+12' hold the number of bytes that are to be found in the 'data block'.
  • Locations 'IX+13 to IX+16' hold a variety of parameters whose exact interpretation depends on the 'type'.
The routine continues with the first task being to separate SAVE from LOAD, VERIFY and MERGE.
SA_ALL 01882 LD A,(23668) Jump forward when handling a SAVE command (T-ADDR-lo=0).
01885 AND A
01886 JP Z,SA_CONTRL
In the case of a LOAD, VERIFY or MERGE command the first seventeen bytes of the 'header area' in the work space hold the prepared information, as detailed above; and it is now time to fetch a 'header' from the tape.
01889 PUSH HL Save the 'destination' pointer.
01890 LD BC,17 Form in the IX register pair the base address of the 'second header area'.
01893 ADD IX,BC
Now enter a loop, leaving it only when a 'header' has been LOADed.
LD_LOOK_H 01895 PUSH IX Make a copy of the base address.
01897 LD DE,17 LOAD seventeen bytes.
01900 XOR A Signal 'header'.
01901 SCF Signal 'LOAD'.
01902 CALL LD_BYTES Now look for a header.
01905 POP IX Retrieve the base address.
01907 JR NC,LD_LOOK_H Go round the loop until successful.
The new 'header' is now displayed on the screen but the routine will only proceed if the 'new' header matches the 'old' header.
01909 LD A,254 Ensure that channel 'S' is open.
01911 CALL CHAN_OPEN
01914 LD (IY+82),3 Set the scroll counter (SCR-CT).
01918 LD C,128 Signal 'names do not match'.
01920 LD A,(IX+0) Compare the 'new' type against the 'old' type.
01923 CP (IX-17)
01926 JR NZ,LD_TYPE Jump if the 'types' do not match.
01928 LD C,246 But if they do, signal 'ten characters are to match'.
LD_TYPE 01930 CP 4 Clearly the 'header' is nonsense if 'type 4 or more'.
01932 JR NC,LD_LOOK_H
The appropriate message - 'Program: ', 'Number array: ', 'Character array: ' or 'Bytes: ' is printed.
01934 LD DE,2496 The base address of the message block.
01937 PUSH BC Save the C register whilst the appropriate message is printed.
01938 CALL PO_MSG
01941 POP BC
The 'new name' is printed and as this is done the 'old' and the 'new' names are compared.
01942 PUSH IX Make the DE register pair point to the 'new name' and the HL register pair to the 'old name'.
01944 POP DE
01945 LD HL,65520
01948 ADD HL,DE
01949 LD B,10 Ten characters are to be considered.
01951 LD A,(HL) Jump forward if the match is to be against an actual name.
01952 INC A
01953 JR NZ,LD_NAME
01955 LD A,C But if the 'old name' is 'null' then signal 'ten characters already match'.
01956 ADD A,B
01957 LD C,A
A loop is entered to print the characters of the 'new name'. The name will be accepted if the 'counter' reaches zero, at least.
LD_NAME 01958 INC DE Consider each character of the 'new name' in turn.
01959 LD A,(DE)
01960 CP (HL) Match it against the appropriate character of the 'old name'.
01961 INC HL
01962 JR NZ,LD_CH_PR Do not count it if it does not does not match.
01964 INC C
LD_CH_PR 01965 RST 16 Print the 'new' character.
01966 DJNZ LD_NAME Loop for ten characters.
01968 BIT 7,C Accept the name only if the counter has reached zero.
01970 JR NZ,LD_LOOK_H
01972 LD A,13 Follow the 'new name' with a 'carriage return'.
01974 RST 16
The correct header has been found and the time has come to consider the three commands LOAD, VERIFY, and MERGE separately.
01975 POP HL Fetch the pointer.
01976 LD A,(IX+0) 'SCREEN$' and 'CODE' are handled with VERIFY.
01979 CP 3
01981 JR Z,VR_CONTRL
01983 LD A,(23668) Jump forward if using a LOAD command (T-ADDR-lo=1).
01986 DEC A
01987 JP Z,LD_CONTRL
01990 CP 2 Jump forward if using a MERGE command; continue into VR_CONTRL with a VERIFY command.
01992 JP Z,ME_CONTRL
Prev: 01507 Up: Map Next: 01995