;******************************************************** ;* * ;* FILE SCREEN PAGING UTILITY * ;* * ;******************************************************** ; ; Copyright (C) 1980 ; ; By: Bill Bolton ; Software Tools, ; P.O. Box 80, ; Newport Beach, ; NSW, 2106, ; AUSTRALIA ; ; Date: July 1, 1980 ; ; Version: 1.0 ; TITLE ;YOU CAN'T ASSEMBLE THIS WITH MAC, USE ASM.COM ; REVERSE EQU 0 ;NON ZERO FOR ADM-31 REVERSE VIDEO PAGE EQU 23 ;LINES/PAGE WIDTH EQU 79 ;CHARACTERS/LINE WBOOT EQU 0000H ;REBOOT ENTRY POINT BDOS EQU 0005H ;CPM ENTRY POINT BUFFER EQU 0080H ;TRANSIENT PROGRAM BUFFER TFCB EQU 005CH ;TRANSIENT PROGRAM FCB DIRECT EQU 6 ;DIRECT CONSOLE FUNCTION STRING EQU 9 ;STRING PRINT FUNCTION STATUS EQU 11 ;CONSOLE STATUS FUNCTION VERSION EQU 12 ;VERSION NUMBER FUNCTION OPEN EQU 15 ;OPEN FUNCTION CODE READ EQU 20 ;READ FUNCTION CODE CREAD EQU 0FFH ;DIRECT CONSOLE INPUT TAB EQU 009H ;ASCII TAB ALF EQU 00AH ;ASCII LINE FEED ACR EQU 00DH ;ASCII CARRIAGE RETURN ESC EQU 01BH ;ASCII ESCAPE SPACE EQU 020H ;ASCII SPACE DEVICE EQU 2 ;CP/M CONSOLE ; ; ORG 100H ; START: LXI SP,STAKTOP ;SET UP THE STACK MVI C,VERSION ;CP/M VERSION FUNCTION CALL BDOS MOV A,L ;GET VERSION NUMBER CPI 20H ;>=VERSION 2.0? JC ERROR3 ;NO, EXIT LXI D,TFCB ;POINT TO FCB CALL FOPEN ;OPEN FILE JC ERROR1 ;IF ERROR, EXIT CALL RESET LOOP: CALL FETCH$BYTE ;GET NEXT BYTE FROM FILE JC ERROR2 ;EXIT IF ERROR CPI 1AH ;EOF? JZ EXIT ;YES, EXIT CPI ACR ;CR? JZ CRET ;YES, UPDATE COLUMN COUNT CPI ALF ;LF? JZ LFEED ;YES, UPDATE LINE COUNT CPI TAB ;TAB? JZ TABMOV ;YES, DO IT CPI SPACE ;ANOTHER CONTROL CHARACTER? JNC DISPLAY ;NO, PRINT CHACTER JMP LOOP ;YES, IGNORE IT ; TABMOV: LXI H,COL ;POINT TO COLUMN TABLOOP: MVI A,SPACE ;GET A SPACE CALL DBYTE ;DISPLAY IT MOV A,M ;GET CURRENT COLUMN ANI 07H ;MOD 8, AT TAB STOP? JNZ TABLOOP ;NO, ANOTHER SPACE JMP LOOP ; DISPLAY: CALL DBYTE ;DISPLAY THE CHARACTER JMP LOOP ; CRET: XRA A STA COL ;RESET COLUMN COUNT MVI A,ACR ;GET A CARRIAGE RETURN JMP DISPLAY ; LFEED: LDA LINE ;GET LINE COUNT CPI PAGE ;SCREEN FULL? JZ NEXTPAGE ;YES, WAIT FOR KEYPRESS INR A ;NO, BUMP LINE COUNT STA LINE ;SAVE NEW LINE COUNT MVI A,ALF ;GET A LINE FEED JMP DISPLAY ; NEXTPAGE: CALL KEYLOOP ;WAIT FOR KEYPRESS MVI A,ALF ;GET A LINE FEED JMP DISPLAY ; KEYLOOP: CALL KEY ;CHECK CONSOLE CPI 0 ;KEY PRESSED ? JZ KEYLOOP ;NO, WAIT FOR KEYPRESS CALL RESET ;RESET COUNTERS RET ; KEY: PUSH H ;SAVE PUSH D ; THE PUSH B ; ENVIRONMENT MVI C,DIRECT ;DIRECT CONSOLE FUNCTION6 MVI E,CREAD ;CONSOLE INPUT CALL BDOS POP B ;RESTORE POP D ; THE POP H ; ENVIRONMENT RET ; RESET: XRA A STA LINE ;RESET LINE COUNT STA COL ;RESET COLUMN COUNT RET ; DBYTE: PUSH H ;SAVE THE PUSH B ; ENVIRONMENT PUSH PSW ;SAVE THE CHARACTER MOV E,A ;COPY THE CHARACTER MVI C,DEVICE ;GET FUNCTION CALL BDOS POP PSW ;RESTORE THE CHARACTER CPI SPACE ;IS A CR OR LF? JC CONT ;YES, DONT BUMP COLUMN COUNT LXI H,COL ;GET COLUMN COUNT INR M ;BUMP IT MOV A,M ;GET NEW COLUMN COUNT CPI WIDTH ;AT THE END OF A LINE? JNZ CONT ;NO MVI A,ACR ;GET A CARRIAGE RETURN CALL DBYTE ;SEND IT LDA LINE ;GET LINE NUMBER CPI PAGE ;AT END OF PAGE JNZ CONT2 ;NO, DO LINE FEED CALL KEYLOOP ;WAIT FOR KEYPRESS CONT2: MVI A,ALF ;GET A LINE FEED CALL DBYTE LDA LINE ;GET THE LINE COUNT INR A ;BUMP IT STA LINE ;SAVE THE LINE COUNT CONT: MVI C,STATUS ;CONSOLE STATUS FUNCTION CALL BDOS CPI 0 ;KEY PRESSED? JNZ DONE ;YES, EXIT POP B ;RESTORE THE POP H ; ENVIRONMENT RET ; DONE: JMP WBOOT ;QUIT ; EXIT: LXI D,MESSG4 ;POINT TO EOF MESSAGE JMP MESSAGE ; ERROR3: LXI D,MESSG3 ;POINT TO VERSION MESSAGE JMP MESSAGE ; ERROR2: LXI D,MESSG2 ;POINT TO READ MESSAGE JMP MESSAGE ; ERROR1: LXI D,MESSG1 ;POINT TO OPEN MESSAGE MESSAGE: MVI C,STRING ;DISPLAY THE MESSAGE CALL BDOS JMP WBOOT ; DB 'FILE PAGE UTILITY, VERSION 1.0 ' DB '(C) Bill Bolton, Software Tools, June 1980' ; ;**************************************************************** ;* * ;* ROUTINE TO OPEN A DISK FILE * ;* * ;**************************************************************** ; FOPEN: ;DE POINTS TO A FCB MVI C,OPEN ;FILE OPEN FUNCTION CALL BDOS CPI 0FFH ;OPEN FILE ERROR? JZ OPENERR ;YES, EXIT XRA A ;CLEAR CARRY RET OPENERR: STC ;SET CARRY RET ; ; ;**************************************************************** ;* * ;* ROUTINE TO READ A BYTE * ;* * ;**************************************************************** ; FETCH$BYTE: LXI H,BUFFER+128 XCHG ;BUFFER END ADDRESS IN DE LHLD POINTER ;CURRENT POINTER IN HL MOV A,H ;END OF BUFFER? CMP D JNZ NEXT$CHAR ;NO, GET ANOTHER CHARACTER MOV A,L CMP E JZ NEXT$BLOCK ;YES, READ ANOTHER BLOCK NEXT$CHAR: MOV A,M ;GET CHARACTER INX H ;BUMP POINTER SHLD POINTER ;SAVE POINTER ORA A ;RESET CARRY RET ; NEXT$BLOCK: MVI C,READ ;READ FUNCTION LXI D,TFCB ;FCB ADDRESS CALL BDOS CPI 0 ;ERROR? JNZ INERROR ;YES, EXIT LXI H,BUFFER ;RESET BUFFER POINTER SHLD POINTER JMP NEXT$CHAR ;CONTINUE ; INERROR: STC ;SET CARRY RET ; ; COL: DB 0 ;COLUMN COUNTER LINE: DB 0 ;LINE COUNTER POINTER: DW BUFFER+128 ;INPUT POINTER ; MESSG1: DB '**** ' if REVERSE DB ESC,'G4' endif DB 'File Open Error' if REVERSE DB ESC,'G0' endif DB ' ****' DB ACR,ALF,'$' ; MESSG2: DB '**** ' if REVERSE DB ESC,'G4' endif DB 'File Read Error' if REVERSE DB ESC,'G0' endif DB ' ****' DB ACR,ALF,'$' ; MESSG3: DB TAB,'Sorry, you need CP/M Version' DB ' 2.0 or later to run PAGE !' DB '$' ; MESSG4: if REVERSE DB ESC,'G4' endif DB ' End of Input File Reached ' if REVERSE DB ESC,'G0' endif DB '$' ; STACK: DS 40 STAKTOP EQU $ ; END START