TITL RECOV:S"RECOVER PROGRAM * * This is the program to assemble for 'RECOVER'. 9/8/77 * By Michael Sherman. * **************************************************************** COPY RECOV:1S/1 This is the RECOVER program. **************************************************************** COPY RECOV:2S/1 The disk driver (similar to PTDOS driver). **************************************************************** * * * Library routines: * * * GETCI obtains the numbers of the CI's input * and output files and stores them in CIFILE * and COFILE, respectively. All registers except * BC are changed. * GETCI LHLD SYSGLO pointer to global area LXI D,GLCIF offset for CI's input file DAD D (H,L) now points to the input file's number MOV A,M STA CIFILE LHLD SYSGLO LXI D,GLCOF offset for CI's output file DAD D MOV A,M STA COFILE RET * * CIFILE DB 0 COFILE DB 1 * * * * GETCHR returns the next character from CIFILE * in register A. If the character is a CR, semicolon, * a NULL (ascii 0), or if EOF is encountered then the zero * flag is set on return. In the case of an EOF, the carry * flag is also set and the character returned in A is a CR. * No registers except A and flags are affected. * GETCHR PUSH B PUSH D PUSH H LDA CIFILE Get the file # of the CI input file. CALL RB JMP GETC1 Error--hopefully EOF. POP H POP D POP B ORA A Set flags, clear carry. RZ . Return if zero. CPI 0DH RZ . Return if CR. CPI ';' RZ . ORA A Just a regular character -- reset zero and carry. RET * * GETC1 CPI EREOF We got an error. Is it EOF? JNZ PTERR Must be defined in calling program. MVI A,0DH EOF pretends it's a CR. STC . Set carry to indicate EOF. (Zero flag is already set.) POP H POP D POP B RET * * * * PUTCHR writes one character out to the COFILE. The character * to write comes in A. On return all registers and flags are * unchanged. * PUTCHR PUSH PSW PUSH B PUSH D PUSH H MOV B,A WB likes characters in B. LDA COFILE CALL WB JMP PTERR This must be defined in the calling program. POP H POP D POP B POP PSW RET * * * * NONBL returns the next non-blank character from CIFILE * in register A. If the character is a CR, semicolon, * a NULL (ascii 0), or if EOF is encountered then the zero * flag is set on return. In the case of an EOF, the carry * flag is also set and the character returned in A is a CR. * No registers except A and flags are affected. * GETCHR is used for input. * NONBL CALL GETCHR Get character to A. RZ . CR, semi, NULL or EOF encountered. CPI ' ' Was it a space? JZ NONBL Yes. ORA A Reset carry. (Zero will be reset also.) RET * * * * OUST writes the string beginning with the address on the * top of the stack. The string is terminated by a zero * byte, and OUST returns to the address just after that byte. * Thus, call is: CALL OUST * ASC /Message./ * DB 0 * * OUST returns here. * * Output is done through PUTCHR. * No registers or flags are affected. OUST XTHL . Get ptr to string and push H. PUSH PSW OUST0 MOV A,M INX H ORA A CNZ PUTCHR Returns with flags unchanged. JNZ OUST0 POP PSW XTHL . Return address to stack, restore HL. RET * * * * Send carriage return/linefeed to the COFILE. No registers * or flags affected. Calls 'PUTCHR'. * CRLF PUSH PSW MVI A,0DH CR CALL PUTCHR MVI A,0AH LF CALL PUTCHR POP PSW RET * * * * DOUT writes the contents of HL to the COFILE as a decimal * number between -32768 and 32767 inclusive. Leading zeroes * and + signs are not printed. * Calls DSUB to subtract DE from HL. * Calls PUTCHR for output to the COFILE. * All registers and flags are returned unchanged. * DOUT PUSH PSW PUSH B PUSH D PUSH H MVI C,0 Flag means "don't print zeroes" initially. MOV A,H Find out if we have a negative number. ORA A JP DOUT0 Nope. CMA Set HL=-HL (two's complement) MOV H,A MOV A,L CMA MOV L,A INX H MVI A,'-' CALL PUTCHR Print the minus sign. * DOUT0 LXI D,10000 First the 10000's digit gets printed. CALL DOUT1 LXI D,1000 Then the 1000's. CALL DOUT1 LXI D,100 The 100's. CALL DOUT1 LXI D,10 CALL DOUT1 MOV A,L Get the one's digit. ADI 48 Make it ascii. CALL PUTCHR Print it. POP H POP D POP B POP PSW RET * * This subroutine subtracts DE from HL as many times as it * will go before HL becomes negative. Then DE is added back * on, and the number of times it went is printed unless it * was zero. If DE is set to powers of any base<=10 then this * routine can be used to print a hex number in that base. * HL is left as it was just before it went negative. * A,B and HL are the only registers affected. * DOUT1 MVI B,0 Count # of subtractions performed. DOUT2 CALL DSUB HL=HL-DE MOV A,H ORA A JM DOUT3 We're done if HL was negative. INR B JMP DOUT2 * * DOUT3 DAD D Fix HL. MOV A,B Get the digit. ORA C If A is zero and we haven't printed anything else, RZ . then don't print this zero. MOV A,B Get the digit back again. ADI 48 Make it ascii. INR C Remember that we printed something. CALL PUTCHR RET * * * * DSUB is just like the DAD instruction except that it * subtracts DE from HL instead of adding it. Only HL * is changed. Flags are returned as they were. * DSUB PUSH PSW PUSH D MOV A,D First set D=-D (two's complement). CMA MOV D,A MOV A,E CMA MOV E,A INX D DAD D Add HL to -D. POP D POP PSW RET * * * * HEX prints A as a two-character hexadecimal number. * PUTCHR is used for output. No registers or flags * are changed on return. * HEX PUSH PSW ANI 0F0H Get most significant digit. RRC RRC RRC RRC CALL HEX00 Print it. POP PSW PUSH PSW ANI 0FH Get least significant digit. CALL HEX00 Print it. POP PSW RET * * HEX00 CPI 10 Is digit < 10? JM HEX01 ADI 7 No. Use letters. HEX01 ADI 48 Translate to ascii. CALL PUTCHR Print it. RET * * * * PTERR receives a PTDOS error in reg. A, and uses the * error explaining utility UXOP to explain it. It closes * all files and performs a reset (RESOP) back to the CI. * Before explaining the error, it prints the message * at ERRMSG to the console. * The name of the program which got the error is a good * thing to have at ERRMSG. The message is terminated * by a zero byte, so no message will be printed if ERRMSG * itself is a zero byte. * PTERR STA PTER2 Save the error number for UXOP. MVI A,-1 CALL SYS DB CAOP Close all files. JMP PTEXIT This should never happen. MVI A,0DH CR CALL CONOUT MVI A,0AH LF CALL CONOUT LXI H,ERRMSG HL-> message. PTER0 MOV A,M INX H ORA A JZ PTER1 Done with message. CALL CONOUT JMP PTER0 PTER1 LXI H,-1 No second line message. MVI A,88H Indicates user return & no CR before "ERROR:". CALL UTIL DB UXOP JMP PTEXIT An error??? DB -1 Not a command error. PTER2 DB 0 The error number. PTEXIT CALL SYS UTIL returns here. DB RESOP * * ERRMSG ASC /RECOVER/ Something for PTERR to say. DB 0 * END *