Prev: 05E3 Up: Map Next: 07CB
0605: 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.
Input
Output
SAVE_ETC 0605 POP AF Drop the address - SCAN_LOOP.
0606 LD A,($5C74) Reduce T-ADDR-lo by +E0, giving +00 for SAVE, +01 for LOAD, +02 for VERIFY and +03 for MERGE.
0609 SUB $E0
060B LD ($5C74),A
060E CALL CLASS_0A Pass the parameters of the 'name' to the calculator stack.
0611 CALL SYNTAX_Z Jump forward if checking syntax.
0614 JR Z,SA_DATA
0616 LD BC,$0011 Allow seventeen locations for the header of a SAVE (T-ADDR-lo=+00) but thirty four for the other commands.
0619 LD A,($5C74)
061C AND A
061D JR Z,SA_SPACE
061F LD C,$22
SA_SPACE 0621 RST $30 The required amount of space is made in the work space.
0622 PUSH DE Copy the start address to the IX register pair.
0623 POP IX
0625 LD B,$0B A program name can have up to ten characters but first enter eleven space characters into the prepared area.
0627 LD A," "
SA_BLANK 0629 LD (DE),A
062A INC DE
062B DJNZ SA_BLANK
062D LD (IX+$01),$FF A null name is +FF only.
0631 CALL STK_FETCH The parameters of the name are fetched and its length is tested.
0634 LD HL,$FFF6 This is '-10'.
0637 DEC BC In effect jump forward if the length of the name is not too long (i.e. no more than ten characters).
0638 ADD HL,BC
0639 INC BC
063A JR NC,SA_NAME
063C LD A,($5C74) But allow for the LOADing, VERIFYing and MERGEing of programs (T-ADDR-lo>+00) with 'null' names or extra long names.
063F AND A
0640 JR NZ,SA_NULL
Report F - Invalid file name.
0642 RST $08 Call the error handling routine.
0643 DEFB $0E
Continue to handle the name of the program.
SA_NULL 0644 LD A,B Jump forward if the name has a 'null' length.
0645 OR C
0646 JR Z,SA_DATA
0648 LD BC,$000A But truncate longer names.
The name is now transferred to the work space (second location onwards).
SA_NAME 064B PUSH IX Copy the start address to the HL register pair.
064D POP HL
064E INC HL Step to the second location.
064F EX DE,HL Switch the pointers over and copy the name.
0650 LDIR
The many different parameters, if any, that follow the command are now considered. Start by handling 'xxx "name" DATA'.
SA_DATA 0652 RST $18 Is the present code the token 'DATA'?
0653 CP $E4
0655 JR NZ,SA_SCR Jump if not.
0657 LD A,($5C74) However it is not possible to have 'MERGE name DATA' (T-ADDR-lo=+03).
065A CP $03
065C JP Z,REPORT_C
065F RST $20 Advance CH-ADD.
0660 CALL LOOK_VARS Look in the variables area for the array.
0663 SET 7,C Set bit 7 of the array's name.
0665 JR NC,SA_V_OLD Jump if handling an existing array.
0667 LD HL,$0000 Signal 'using a new array'.
066A LD A,($5C74) Consider the value in T-ADDR-lo and give an error if trying to SAVE or VERIFY a new array.
066D DEC A
066E JR Z,SA_V_NEW
Report 2 - Variable not found.
0670 RST $08 Call the error handling routine.
0671 DEFB $01
Continue with the handling of an existing array.
SA_V_OLD 0672 JP NZ,REPORT_C Note: this fails to exclude simple strings.
0675 CALL SYNTAX_Z Jump forward if checking syntax.
0678 JR Z,SA_DATA_1
067A INC HL Point to the 'low length' of the variable.
067B LD A,(HL) The low length byte goes into the work space, followed by the high length byte.
067C LD (IX+$0B),A
067F INC HL
0680 LD A,(HL)
0681 LD (IX+$0C),A
0684 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 0685 LD (IX+$0E),C Copy the array's name.
0688 LD A,$01 Assume an array of numbers.
068A BIT 6,C Jump if it is so.
068C JR Z,SA_V_TYPE
068E INC A It is an array of characters.
SA_V_TYPE 068F LD (IX+$00),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 0692 EX DE,HL Save the pointer in DE.
0693 RST $20 Is the next character a ')'?
0694 CP ")"
0696 JR NZ,SA_V_OLD Give report C if it is not.
0698 RST $20 Advance CH-ADD.
0699 CALL CHECK_END Move on to the next statement if checking syntax.
069C 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.)
069D JP SA_ALL
Now consider 'SCREEN$'.
SA_SCR 06A0 CP $AA Is the present code the token SCREEN$?
06A2 JR NZ,SA_CODE Jump if not.
06A4 LD A,($5C74) However it is not possible to have 'MERGE name SCREEN$' (T-ADDR-lo=+03).
06A7 CP $03
06A9 JP Z,REPORT_C
06AC RST $20 Advance CH-ADD.
06AD CALL CHECK_END Move on to the next statement if checking syntax.
06B0 LD (IX+$0B),$00 The display area and the attribute area occupy +1B00 locations and these locations start at +4000; these details are passed to the header area in the work space.
06B4 LD (IX+$0C),$1B
06B8 LD HL,$4000
06BB LD (IX+$0D),L
06BE LD (IX+$0E),H
06C1 JR SA_TYPE_3 Jump forward.
Now consider 'CODE'.
SA_CODE 06C3 CP $AF Is the present code the token 'CODE'?
06C5 JR NZ,SA_LINE Jump if not.
06C7 LD A,($5C74) However it is not possible to have 'MERGE name CODE' (T-ADDR-lo=+03).
06CA CP $03
06CC JP Z,REPORT_C
06CF RST $20 Advance CH-ADD.
06D0 CALL PR_ST_END Jump forward if the statement has not finished.
06D3 JR NZ,SA_CODE_1
06D5 LD A,($5C74) However it is not possible to have 'SAVE name CODE' (T-ADDR-lo=+00) by itself.
06D8 AND A
06D9 JP Z,REPORT_C
06DC CALL USE_ZERO Put a zero on the calculator stack - for the 'start'.
06DF JR SA_CODE_2 Jump forward.
Look for a 'starting address'.
SA_CODE_1 06E1 CALL CLASS_06 Fetch the first number.
06E4 RST $18 Is the present character a comma?
06E5 CP ","
06E7 JR Z,SA_CODE_3 Jump if it is - the number was a 'starting address'.
06E9 LD A,($5C74) However refuse 'SAVE name CODE' that does not have a 'start' and a 'length' (T-ADDR-lo=+00).
06EC AND A
06ED JP Z,REPORT_C
SA_CODE_2 06F0 CALL USE_ZERO Put a zero on the calculator stack - for the 'length'.
06F3 JR SA_CODE_4 Jump forward.
Fetch the 'length' as it was specified.
SA_CODE_3 06F5 RST $20 Advance CH-ADD.
06F6 CALL CLASS_06 Fetch the 'length'.
The parameters are now stored in the header area of the work space.
SA_CODE_4 06F9 CALL CHECK_END But move on to the next statement now if checking syntax.
06FC CALL FIND_INT2 Compress the 'length' into the BC register pair and store it.
06FF LD (IX+$0B),C
0702 LD (IX+$0C),B
0705 CALL FIND_INT2 Compress the 'starting address' into the BC register pair and store it.
0708 LD (IX+$0D),C
070B LD (IX+$0E),B
070E LD H,B Transfer the 'pointer' to the HL register pair as usual.
070F LD L,C
'SCREEN$' and 'CODE' are both of type 3.
SA_TYPE_3 0710 LD (IX+$00),$03 Enter the 'type' number.
0714 JR SA_ALL Rejoin the other pathways.
Now consider 'LINE' and 'no further parameters'.
SA_LINE 0716 CP $CA Is the present code the token 'LINE'?
0718 JR Z,SA_LINE_1 Jump if it is.
071A CALL CHECK_END Move on to the next statement if checking syntax.
071D LD (IX+$0E),$80 When there are no further parameters, +80 is entered.
0721 JR SA_TYPE_0 Jump forward.
Fetch the 'line number' that must follow 'LINE'.
SA_LINE_1 0723 LD A,($5C74) However only allow 'SAVE name LINE number' (T-ADDR-lo=+00).
0726 AND A
0727 JP NZ,REPORT_C
072A RST $20 Advance CH-ADD.
072B CALL CLASS_06 Pass the number to the calculator stack.
072E CALL CHECK_END Move on to the next statement if checking syntax.
0731 CALL FIND_INT2 Compress the 'line number' into the BC register pair and store it.
0734 LD (IX+$0D),C
0737 LD (IX+$0E),B
'LINE' and 'no further parameters' are both of type 0.
SA_TYPE_0 073A LD (IX+$00),$00 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.
073E LD HL,($5C59) The pointer to the end of the variables area (E-LINE).
0741 LD DE,($5C53) The pointer to the start of the BASIC program (PROG).
0745 SCF Now perform the subtraction to find the length of the 'program + variables'; store the result.
0746 SBC HL,DE
0748 LD (IX+$0B),L
074B LD (IX+$0C),H
074E LD HL,($5C4B) Repeat the operation but this time storing the length of the 'program' only (VARS-PROG).
0751 SBC HL,DE
0753 LD (IX+$0F),L
0756 LD (IX+$10),H
0759 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+$00' holds the type number.
  • Locations 'IX+$01 to IX+$0A' hold the name (+FF in 'IX+$01' if null).
  • Locations 'IX+$0B and IX+$0C' hold the number of bytes that are to be found in the 'data block'.
  • Locations 'IX+$0D to IX+$10' 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 075A LD A,($5C74) Jump forward when handling a SAVE command (T-ADDR-lo=+00).
075D AND A
075E 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.
0761 PUSH HL Save the 'destination' pointer.
0762 LD BC,$0011 Form in the IX register pair the base address of the 'second header area'.
0765 ADD IX,BC
Now enter a loop, leaving it only when a 'header' has been LOADed.
LD_LOOK_H 0767 PUSH IX Make a copy of the base address.
0769 LD DE,$0011 LOAD seventeen bytes.
076C XOR A Signal 'header'.
076D SCF Signal 'LOAD'.
076E CALL LD_BYTES Now look for a header.
0771 POP IX Retrieve the base address.
0773 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.
0775 LD A,$FE Ensure that channel 'S' is open.
0777 CALL CHAN_OPEN
077A LD (IY+$52),$03 Set the scroll counter (SCR-CT).
077E LD C,$80 Signal 'names do not match'.
0780 LD A,(IX+$00) Compare the 'new' type against the 'old' type.
0783 CP (IX-$11)
0786 JR NZ,LD_TYPE Jump if the 'types' do not match.
0788 LD C,$F6 But if they do, signal 'ten characters are to match'.
LD_TYPE 078A CP $04 Clearly the 'header' is nonsense if 'type 4 or more'.
078C JR NC,LD_LOOK_H
The appropriate message - 'Program: ', 'Number array: ', 'Character array: ' or 'Bytes: ' is printed.
078E LD DE,$09C0 The base address of the message block.
0791 PUSH BC Save the C register whilst the appropriate message is printed.
0792 CALL PO_MSG
0795 POP BC
The 'new name' is printed and as this is done the 'old' and the 'new' names are compared.
0796 PUSH IX Make the DE register pair point to the 'new name' and the HL register pair to the 'old name'.
0798 POP DE
0799 LD HL,$FFF0
079C ADD HL,DE
079D LD B,$0A Ten characters are to be considered.
079F LD A,(HL) Jump forward if the match is to be against an actual name.
07A0 INC A
07A1 JR NZ,LD_NAME
07A3 LD A,C But if the 'old name' is 'null' then signal 'ten characters already match'.
07A4 ADD A,B
07A5 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 07A6 INC DE Consider each character of the 'new name' in turn.
07A7 LD A,(DE)
07A8 CP (HL) Match it against the appropriate character of the 'old name'.
07A9 INC HL
07AA JR NZ,LD_CH_PR Do not count it if it does not does not match.
07AC INC C
LD_CH_PR 07AD RST $10 Print the 'new' character.
07AE DJNZ LD_NAME Loop for ten characters.
07B0 BIT 7,C Accept the name only if the counter has reached zero.
07B2 JR NZ,LD_LOOK_H
07B4 LD A,$0D Follow the 'new name' with a 'carriage return'.
07B6 RST $10
The correct header has been found and the time has come to consider the three commands LOAD, VERIFY, and MERGE separately.
07B7 POP HL Fetch the pointer.
07B8 LD A,(IX+$00) 'SCREEN$' and 'CODE' are handled with VERIFY.
07BB CP $03
07BD JR Z,VR_CONTRL
07BF LD A,($5C74) Jump forward if using a LOAD command (T-ADDR-lo=+01).
07C2 DEC A
07C3 JP Z,LD_CONTRL
07C6 CP $02 Jump forward if using a MERGE command; continue into VR_CONTRL with a VERIFY command.
07C8 JP Z,ME_CONTRL
Prev: 05E3 Up: Map Next: 07CB