|
DataMuseum.dkPresents historical artifacts from the history of: CP/M |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about CP/M Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - download
Length: 19328 (0x4b80) Types: TextFile Names: »GETPUT.ASM«
└─⟦1f6b46325⟧ Bits:30004393 CP/M-80 rel. 1 Utilities source disk └─ ⟦this⟧ »GETPUT.ASM«
TITLE 'HARD DISK SYSTEM GETPUT UTILITY' PAGE 43 ;****************************************************************************** ; CHRISTIAN ROVSING A/S HARD DISK CP/M SYSTEM UTILITY PROGRAM ;****************************************************************************** ; ; ; HARD DISK CP/M SYSTEM FETCHING AND PLACEMENT PROGRAM FOR USE ; WITH CP/M 2.2 ON A SEGATE, 5 1/4 INCH WINCHESTER DISK DRIVE. ; USE OF A MICRO COMPUTER SYSTEMS INC. MCS-9205 MULTIBUS ; WINCHESTER DISK DRIVE CONTROLLER IS REQUIRED. THE CP/M DISK ; MAPS EACH LOGICAL DRIVE A: TO D: DIRECTLY TO THE HEADS OF THE ; SEAGATE DRIVE. THIS SYSTEM UTILITY PROGRAM PERMITS READING ; THE CP/M SYSTEM TRACKS INTO MEMORY OR WRITING THE SYSTEM TRACKS ; FROM MEMORY TO DISK. BOTH HARD DISK SURFACES ARE FORMATTED IN A ; SIMILAR FASHION TO PERMIT SPECIAL BOOTING CONFIGURATIONS. TRACKS 0 ; AND 1 ARE RESERVED FOR THIS PURPOSE. THE GETPUT SYSTEM UTILITY ; PROGRAM PERMITS SYSTEM ACCESS FOR EACH HEAD SURFACE IN AN ; INDEPENDANT MANNER. ; PAGE ; ; THE GET/PUT PROGRAM PLACES THE SYSTEM IMAGE INTO MEMORY STARTING ; AT ADDRESS 03480H. THIS ADDRESS IS CHOSEN FOR THE FOLLOWING REASON: ; ; PLACING IMAGE THIS HIGH ALLOWS THERE TO BE PLENTY ; OF ROOM BELOW THE IMAGE TO LOAD DDT WITHOUT ; CAUSING OVELAY OF THE SYSTEM IMAGE. ; ; THE WINCHESTER DISK CONTROLLER FIRMWARE SUPPORTS A PARAMETER ; BLOCK FORMAT SIMILAR TO AN INTEL SBC 206 DISK CONTROLLER WITH ; A MODIFIED SET OF PARAMETERS THAT MAP TO THE CHARACTERISTICS OF ; THE SEAGATE 5 1/4 INCH WINCHESTER DRIVE. THE CONTROLLER / DRIVE ; CHARACTERISTICS ARE MAPPED AS FOLLOWS: ; ; 17 RECORDS PER CYLINDER ; FOUR HEADS/SURFACES ; 512 BYTE RECORDS ; CP/M MAPS LOGICAL DRIVES A: TO D: TO THE FOUR HEADS ; ; THE GETPUT PROGRAM CONTAINS THE DISK CONTROLLER DRIVERS FOR ; DIRECT ACCESS TO THE DISK CONTROLLER. THIS PERMITS HARD DISK ; SYSTEM GENERATION AS A FIRST TIME BASIS AS ONLY ONE DRIVE IS ; EVER AVAILABLE IN A SYSTEM AT A TIME. IE., THE CP/M CAN BE ; PLACED UPON A HARD DISK UNDER THE CONTROL ENVIRONMENT OF A ; MINI FLOPPY CP/M SYSTEM. ; PAGE ;****************************************************************************** ; ; ;GENERAL EQUATES ; CR EQU 0DH ;CARRIAGE RETURN CODE LF EQU 0AH ;LINE FEED CODE BS EQU 08H ;BACK SPACE CODE BEL EQU 07H ;BELL RING CODE ESC EQU 01BH ;ESCAPE CODE TRUE EQU 0FFFFH ;TRUE CODE FALSE EQU NOT TRUE ;FALSE CODE ; ; MAXDSK EQU 000 ;MAXIMUM DISK NUMBER MAXTRK EQU 152 ;MAXIMUM TRACK OF ST506 MAXREC EQU 017 ;MAXIMUM RECORD NUMBER MAXPLAT EQU 003 ;MAXIMUM DRIVE PLATTER NUMBER MAXSUR EQU 000 ;MAXIMUM DISK SURFACE NUMBER SECSIZ EQU 512 ;NUMBER OF BYTES IN DISK RECORD ; ISIZE EQU MAXREC*2 ;GET/PUT READS ENTIRE TWO SYSTEM TRACKS IBUF EQU 03480H ;MEMORY ADDRESS FOR BASE OF GET/PUT ;SYSTEM IMAGE BUFFER PAGE ; ;DEFINE MEMORY BASED I/O MODULE ENTRY POINTS ; MODBASE EQU 0F800H ;SET JUMP TABLE EQUIVALENT ADDRESSES ; INITSER EQU MODBASE+00 ;INITIALIZE SERIAL I/O PORTS ; ;(NO PARAMETERS) SETCBAUD EQU MODBASE+03 ;SET CONSOLE I/O BAUD RATE FACTOR ; ;(HL) = COUNTER TIMER PARAMETER VALUE SETLBAUD EQU MODBASE+06 ;SET LINE PRINTER I/O BAUD RATE FACTOR ; ;(HL) = COUNTER TIMER VALUE SETLRMSK EQU MODBASE+09 ;SET LINE PRINTER SIO RECEIVER MASK VALUE ;(A) = LINE PRINTER SIO MASK BYTE SETLRVAL EQU MODBASE+012 ;SET LINE PRINTER SIO RECEIVER POLL VALUE ; ;(A) = LINE PRINTER POLL VALUE SETLTMSK EQU MODBASE+015 ;SET LINE PRINTER SIO TRANSMITTER MASK VALUE ; ;(A) = LINE PRINTER SIO MASK BYTE SETLTVAL EQU MODBASE+018 ;SET LINE PRINTER SIO TRANSMITTER POLL VALUE ; ;(A) = LINE PRINTER SIO POLL VALUE BYTE CONSTAT EQU MODBASE+021 ;GET CONSOLE STATUS ; ;RETURN (A)=00 FOR NOT READY INPUT ; ; (A)=FF FOR READY INPUT CONIN EQU MODBASE+024 ;GO GET CONSOLE INPUT CHARACTER ; ;(A)=INPUT CONSOLE CHARACTER CONOUT EQU MODBASE+027 ;PUT OUT CONSOLE CHAR ; ;(C)=CHARACTER TO OUTPUT LPTSTAT EQU MODBASE+030 ;GET LINE PRINTER STATUS ; ;RETURN (A)=00 FOR NOT NEXT OUTPUT ; ; (A)=FF FOR READY OUTPUT LPTIN EQU MODBASE+033 ;GO GET LINE PRINTER INPUT CHARACTER ; ;(A)=INPUT LPT SERIAL PORT CHARACTER LPTOUT EQU MODBASE+036 ;PUT OUT LINE PRINTER CHARACTER ; ;(C)=LPT SERIAL OUTPUT CHARACTER HUNIT EQU MODBASE+039 ;SELECT HARD DISK UNIT NUMBER ; ;(C)=UNIT NUMBER ON MSC 9205 CONTROLLER HPLAT EQU MODBASE+042 ;SELECT HARD DISK PLATTER (HEAD) NUMBER ; ;(C)=HEAD SELECT NUMBER HSURF EQU MODBASE+045 ;SELECT HARD DISK SURFACE(HEAD 2^2) NUMBER ; ;(C)=MSB OF HEAD NUMBER HCYL EQU MODBASE+048 ;SELECT HARD DISK CYLINDER NUMBER ; ;(BC)=CYLINDER NUMBER HREC EQU MODBASE+051 ;SELECT HARD DISK RECORD NUMBER ; ;(C)=RECORD NUMBER HCNT EQU MODBASE+054 ;SELECT HARD DISK SECTOR COUNT ; ;(C)=RECORD COUNT HBADDR EQU MODBASE+057 ;SET 9205 CONTROLLER DMA ADDRESS ; ;(BC)=16 BIT DATA BUFFER ADDRESS HREST EQU MODBASE+060 ;RESTORE SELECTED HARD DISK UNIT ; ;(A) RETURNS ERROR CODE HREAD EQU MODBASE+063 ;READ SELECTED SECTOR(S) ; ;(A) RETURNS ERROR CODE HVERF EQU MODBASE+066 ;VERIFY SELECTED SECTOR(S) ; ;(A) RETURNS ERROR CODE HWRIT EQU MODBASE+069 ;WRITE SELECTED SECTOR(S); ; ;(A) RETURNS ERROR CODE HEXEC EQU MODBASE+072 ;EXECUTE SPECIAL COMMAND OF MSC 9205 ; ;(C) ENTRY WITH MSC 9205 COMMAND ; ;(A) RETURNS ERROR CODE HRESET EQU MODBASE+075 ;RESET HARD DISK CONTROLLER MSC 9205 ; ;NO PARAMETERS MUNIT EQU MODBASE+078 ;SELECT MINI FLOPPY UNIT NUMBER ; ;(C)=FLOPPY PHYSICAL UNIT NUMBER MSURF EQU MODBASE+081 ;SELECT MINI FLOPPY SURFACE(HEAD) NUMBER ; ;(C)=FLOPPY SIDE NUMBER MCYL EQU MODBASE+084 ;SELECT MINI FLOPPY CYLINDER(TRACK) NUMBER ; ;(C)=FLOPPY TRACK NUMBER MREC EQU MODBASE+087 ;SELECT MINI FLOPPY RECORD NUMBER ; ;(C)=FLOPPY SECTOR NUMBER MCNT EQU MODBASE+090 ;SELECT MINI FLOPPY PHYSICAL SECTOR COUNT ; ;(C)=MINI FLOPPY SECTOR COUNT MSIZE EQU MODBASE+093 ;SELECT FLOPPY SECTOR SIZE (00)=256 BYTES ; ;(C)=MINI FLOPPY TRACK NUMBER MBADDR EQU MODBASE+096 ;SET FLOPPY DISK DATA BUFFER ADDRESS ; ;(BC)=FLOPPY BUFFER ADDRESS MREST EQU MODBASE+099 ;RESTORE SELECTED MINI FLOPPY UNIT ; ;(A)=RETURNS ERROR STATUS MVERF EQU MODBASE+102 ;VERIFY (READ) SELECTED SECTOR ; ;(A)=RETURNS STATUS MWRIT EQU MODBASE+105 ;WRITE SELECTED SECTOR ; ;(A)=RETURNED STATUS MREAD EQU MODBASE+108 ;READ SELECTED SECTOR ; ;(A)=RETURNED STATUS MWTRK EQU MODBASE+111 ;WRITE SELECTED FLOPPY TRACK ; ;(A)=RETURNED STATUS MMODE EQU MODBASE+114 ;SET FLOPPY OPERATION MODE ; ;(C)=STANDARD MODE DEFINITION MINST EQU MODBASE+117 ;FETCH CURRENT INSTRUCTION CODE ; ;(A)=RETURNED INSTRUCTION PATTERN MMOFF EQU MODBASE+120 ;CHECK MINI FLOPPY MOTOR ON COUNT ; ;OUT TIMER ; PAGE ;****************************************************************************** ; ;SET START OF PROGRAM CP/M TRANSIENT PROGRAM AREA ; ORG 0100H ; DI ;DON'T ALLOW INTERRUPTS HERE JMP START ; ; ;CP/M CONSOLE I/O INTERFACE ENTRY ROUTINES ; ; DIRECT CALLS TO THE BIOS ARE DONE ; VECTAB EQU 0001H ;LOCATION IN MEMORY CONTAINING ;WARM BOOT VECTOR CSTOFF EQU 0003H ;CONSOLE STAT OFFSET FROM WBOOT CINOFF EQU 0006H ;CONSOLE INPUT OFFSET FROM WBOOT COTOFF EQU 0009H ;CONSOLE OUTPUT OFFSET FROM WBOOT ; PAGE ; ;CONSOLE INPUT ROUTINE (RETURNS CHARACTER IN A REGISTER) ; CI: PUSH H ;SAVE REGISTERS PUSH D PUSH B LHLD VECTAB ;GET POINTER BASE LXI D,CINOFF ;GET OFFSET VALUE DAD D LXI D,CI1 ;PUT A RETURN BACK ONTO STACK PUSH D PCHL ;GO TO BIOS ROUTINE CI1: POP B POP D ;RESTORE CALLERS REGS POP H RET ; ; ;CONSOLE OUTPUT ROUTINE (OUTPUT CHARACTER FROM C REG) ; CO: PUSH H ;SAVE REGISTERS PUSH D PUSH B LHLD VECTAB ;GET POINTER BASE LXI D,COTOFF ;GET OFFSET VALUE DAD D LXI D,CO1 ;PUT A RETURN BACK ONTO STACK PUSH D PCHL ;GO TO BIOS ROUTINE CO1: POP B POP D ;RESTORE CALLERS REGS POP H RET ; PAGE ; ;CONSOLE TERMINAL STATUS ROUTINE ; RETURNS A=00 IF NO CHARACTER PRESENT ; RETURNS A=FF IF CHARACTER PRESENT ; CSTS: PUSH H ;SAVE REGISTERS PUSH D PUSH B LHLD VECTAB ;GET POINTER BASE LXI D,CSTOFF ;GET OFFSET VALUE DAD D LXI D,CSTS1 ;PUT A RETURN BACK ONTO STACK PUSH D PCHL ;GO TO BIOS ROUTINE CSTS1: POP B POP D ;RESTORE CALLERS REGS POP H RET ; ; ;COMPARE DOUBLE REGISTER PAIRS (DE) TO (HL) AND RETURN ;FLAGS SIMILAR TO STANDARD CMP B INSTRUCTION. IE (A) CORRESPONDS ;TO (DE) AND (B) CORRESPONDS TO (HL). ; CDEHL: MOV A,D ;CHECK HIGH BYTES FIRST CMP H RNZ ;RETURN IF HIGH BYTES SET FLAGS MOV A,E CMP L ;CHECK LOW BYTES RET ; PAGE ;****************************************************************************** ; ; BEGIN EXECUTION OF GET/PUT PROGRAM HERE ; START: LXI H,0000H ;SAVE CCP STACK FOR QUICK RETURN DAD SP SHLD CCPSTK LXI SP,STCKK ;MAKE OURSELVES A NEW STACK ; SIGNON: ;SEND HELLO TO CRT CALL CRLF CALL CRLF LXI D,STRMSG CALL CRTMS JMP MONITOR ;GO TO MONITOR ROUTINE ; ; ;SIGNON MESSAGE FOR GET/PUT PROGRAM ; STRMSG: ; DB ESC,'Æ7;2m' ; DB 'CHRISTIAN ROVSING A/S - CR8 SYSTEM GENERATION',CR,LF DB 'FOR ST-506 DRIVE AND MCS-9205 DISK CONTROLLER',CR,LF DB ESC,'Æm' DB CR,LF,CR,LF,'#' ; PAGE ;****************************************************************************** ; ; MONITOR: LXI D,PRMSG ;PRINT OUT THE COMMAND PROMPT ;MESSAGE SO THEY KNOW WHAT TO DO CALL CRTMS PROMPT: LXI SP,STCKK ;RE INIT STACK IF BACK FROM ERROR LXI D,PRMSG1 ;PRINT OUT PROMPT CALL CRTMS ; CALL CECHO ;GET OPERATOR ENTRY COMMAND CPI ' ' JZ MONITOR ;REDO COMMAND LINE PROMPT IF SPACE ; ANI 05FH ;CONVERT TO UPPER CASE CPI 'G' JZ GET ;TO ROUTINE TO GET SYSTEM IMAGE CPI 'P' JZ PUT ;TO ROUTINE TO PUT SYSTEM IMAGE CPI 'M' JZ MEM ;TO ROUTINE FOR MEMORY DISPLAY/ALTER CPI 'C'-040H JZ GPXIT ;TO GET/PUT EXIT POINT ; MVI C,'?' ;UNKNOWN COMMAND CALL CO CALL CRLF JMP PROMPT ;BACK TO PROMPT IF BAD COMMAND ; ; PRMSG: DB 'SELECT COMMAND',CR,LF DB ' G) GET SYSTEM IMAGE P) PUT SYSTEM IMAGE',CR,LF DB ' M) MEMORY PATCH CTL-C) BACK TO CP/M',CR,LF,'#' PRMSG1: DB CR,LF,'---->','#' ; PAGE ; ;OPERATOR SELECTED THE EXIT ROUTINE VIA CTL-C ; GPXIT: CALL CRLF LHLD CCPSTK ;GET VALUE OF CCP STACK SPHL ;PUT INTO STACK POINTER RET ;BACK TO CCP IMMEDIATE ; PAGE ;****************************************************************************** ; ; GENERAL PURPOSE I/O SUBROUTINES ; ; CRLF: ;ROUTINE TO DO CONSOL CR AND LF MVI C,CR CALL CO MVI C,LF CALL CO RET ; ; ; CECHO: ;ROUTINE TO GET AND ECHO A CHARACTER CALL CI MOV C,A PUSH PSW CALL CO POP PSW ANI 07FH ;GET RID OF PARITY RET ; ; ; NBL: ;ROUTINE TO CONVERT A BYTE TO A HEX NIBBLE SUI '0' RC ADI 0E9H RC ADI 06H JP NIO ADI 07H RC NIO: ADI 10 ORA A RET ; PAGE ; BYTEC: ;ROUTINE TO GET A HEX BYTE IN A CALL CECHO ;GET CHARACTER BYTC1: CALL NBL ;CONVERT TO HEX JC ERRR ;TO ERROR ROUTINE RLC RLC RLC RLC PUSH PSW ;SAVE 1ST ENTRY CALL CECHO ;GET 2ND CHARACTER CALL NBL ;CONVERT IT TO HEX JC ERRR POP B ;RECOVER 1ST RESULT ORA B ;COMBINE WITH 2ND RET ; ; ; CONI: ;ROUTINE TO GET A 1 BYTE PARAMETER PUSH B CALL BYTEC POP B RET ; PAGE ; PARAM: ;ROUTINE TO INPUT 4 HEX CHARACTERS LXI H,0 PARM1: CALL CECHO ;GET INPUT CPI 0DH ;LOOK FOR RETURN RZ DAD H DAD H DAD H DAD H JC ERRR CALL NBL ;CONVERT ENTRY TO HEX JC ERRR ORA L MOV L,A JMP PARM1 ;GO FOR NEXT CHARACTER ; ; HLCO: ;PRINT CRLF AND CONTENTS OF (HL) CALL CRLF HLCO1: ;ROUTINE TO PRINT CONTENTS OF (HL) MOV A,H CALL BYTEO MOV A,L CALL BYTEO RET ; ; DSPYM: ;DISPLAYS MEMORY BYTE POINTED TO BY (HL) CALL HLCO ;PRINT ADDRESS MVI C,'=' CALL CO MOV A,M CALL BYTEO ;PRINT ADDRESS CONTENTS MVI C,' ' CALL CO ;PRINT OUT SPACE RET ; PAGE ; BYTEO: ;ROUTINE TO OUTPUT A HEX BYTE TO THE CONSOLE PUSH PSW CALL BYTO1 MOV C,A CALL CO POP PSW CALL BYTO2 MOV C,A CALL CO RET ; BYTO1: RRC RRC RRC RRC BYTO2: ANI 0FH CPI 0AH JM BYTO3 ADI 07H BYTO3: ADI 030H RET ; ; ; ERRR: ;ERROR ON ENTRY OF OPERATOR PARAMETERS MVI C,'?' ;OUTPUT UNKNOWN PARAMETER CALL CO CALL CRLF JMP PROMPT ;GO TO PROMPT IF ERROR ; PAGE ;****************************************************************************** ; ;MEMORY DISPLAY ALTER ROUTINE TO ALLOW PATCHING OF MEMORY UNDER ;THE CONTROL OF THE GET/PUT PROGRAM. OPERATION AS FOLLOWS: ; ; SELECT A HEX MEMORY ADDRESS FOLLOWED BY CARRIAGE ; RETURN. MEMORY CURRENT CONTENTS AT THAT ADDRESS ; WILL BE PRINTED. CONTENTS CAN BE CHANGED BY ENTERING ; A VALID HEX BYTE VALUE. AS VALUE IS ACCEPTED, THE DISPLAY ; ADVANCES TO THE NEXT MEMORY ADDRESS. IF THE MEMORY LOCATION ; IS BAD AND CANNOT ACCEPT THE ENTERED VALUE AN "E" IS PRINTED ; TO THE RIGHT OF THE ENTERED VALUE TO INDICATE THE ERROR. ; ENTERING SPACE BAR WILL ADVANCE TO THE NEXT MEMORY LOCATION ; WITHOUT MODIFYING THE PRESENT MEMORY LOCATION. ENTRY OF THE ; UP ARROW "^" WILL BACKUP DISPLAY TO THE PREVIOUS MEMORY ; ADDRESS. CARRIAGE RETURN SENDS CONTROL BACK TO THE GET/PUT ; MONITOR PROMPT. ; ; MEM: LXI D,MEMMSG ;DISPLAY ALTER MESSAGE CALL CRTMS CALL PARAM ;GET ADDESS IN H & L MEM1: CALL DSPYM ;DISPLAY MEMORY BYTE CALL CECHO ;GET INPUT CHARACTER CPI '^' ;NEED TO BACK UP? JZ MEM10 CPI CR ;CHECK FOR CR EXIT JZ MEMEND CPI ' ' ;CHECK FOR NEXT CHARACTER JZ MEM9 CALL BYTC1 ;CONVERT THIS BYTE AND NEXT TO HEX MOV M,A ;STUFF IT IN MEMORY CMP M ;DID IT GO IN OK? JZ MEM9 MVI C,' ' ;NOPE SHOW'EM AN E FOR ERROR CALL CO MVI C,'E' CALL CO MEM9: INX H ;INCREMENT MEMORY ADDRESS JMP MEM1 MEM10: DCX H ;DECREMENT MEMORY ADDRESS JMP MEM1 MEMEND: JMP PROMPT ;RETURN TO MONITOR ; ; MEMMSG: DB 'EMORY ADDRESS (0000-FFFF) =','#' ; ; ;****************************************************************************** ; ; ;CRTMS - ROUTINE TO DISPLAY A MESSAGE ON THE CRT. REGISTERS D AND E ; CONTAIN THE MESSAGE POINTER. END OF MESSAGE IS INDICATED BY ; A "#" CHARACTER. ; ; CRTMS: ;ROUTINE PRINTS MESSAGE ON CRT LDAX D CPI '#' ;END MESSAGE MARKER RZ ;YES - RETURN MOV C,A CALL CO INX D JMP CRTMS ; PAGE ;****************************************************************************** ; ; ; GET SYSTEM IMAGE FROM OPERATOR SELECTED DRIVE INTO MEMORY ; AT ADDRESS OF THE IMAGE POSITION "IBUF" SET BY EQUATE AT ; THE BEGINNING OF THIS PROGRAM. ALL OF TRACKS 0 AND 1 ARE ; READ FOR MAXIMUM FLEXIBILITY. NOTE THAT THIS REQUIRES THAT ; 12K OF MEMORY MUST BE AVAILABLE ABOVE THE "IBUF" POSITION ; ; GET: CALL CRLF LXI D,GETMS ;PRINT GET UNIT SELECT MESSAGE CALL CRTMS CALL CECHO ;GET OPERATOR ENTRY ANI 05FH ;UPPERCASE SUI 'A' ;ZERO BASE SELECT CPI MAXPLAT+1 ;CHECK IF TOO BIG JNC ERRR MOV C,A ;PUT DRIVE NUMBER INTO (C) ; CALL HPLAT ;SET HEADF NUMBER AS CP/M DRIVE NUMBER MVI C,0 CALL HSURF MVI C,00H ;SET HDSK UNIT 0 CALL HUNIT ; CALL CRLF ;CLEAN UP DISPLAY ; MVI D,01H ;START WITH RECORD 1 LXI B,000H ;START WITH CYLINDER 0 LXI H,IBUF ;START OF BUFFER AREA MVI E,ISIZE ;NUMBER OF RECORDS DO GETLP: PUSH B ;SAVE CYL PUSH D ;SAVE RECORD NUMBER/REC COUNT PUSH H ;SAVE LOAD ADDRESS CALL HCYL ;PUT CYLINDER INTO IOPB MOV C,D ;PUT RECORD NUMBER INTO IOPB CALL HREC MOV C,L ;PUT LOAD ADDRESS INTO IOPB MOV B,H CALL HBADDR CALL HREAD ;GO TELL DISK TO READ POP H ;GET BACK LOAD ADDRESS POP D ;GET BACK REC / REC CNT POP B ;GET BACK CYL ; ORA A ;CHECK COMMAND COMPLETION STATUS JNZ REPERR ;GO TO REPORT ERROR ; PUSH B LXI B,SECSIZ ;GET ADDRESS INDEX DAD B ;(HL) HAS NEW LOAD ADDRESS POP B INR D ;SET FOR NEXT RECORD MOV A,D ;CHECK IF PAST END OF CYLINDER CPI MAXREC+1 JNZ SAMTRK ;STILL ON SAME TRACK ; INX B ;INCREMENT CYLINDER NUMBER MVI D,01H ;RESET RECORD BACK FOR BEGINNING SAMTRK: DCR E ;SEE IF ALL SECTORS IN YET JNZ GETLP ;GO DO MORE IF NOT DONE YET ; LXI D,GETMS1 ;PRINT COMPLETE MESSAGE CALL CRTMS JMP PROMPT ;BACK TO PROMPT ; PAGE ; GETMS: DB 'SOURCE HARD DISK A: TO D: (A,B,C, OR D) ','#' ; GETMS1: DB 'SOURCE READ COMPLETE',CR,LF,'#' ; ; ;SHORT ROUTINE TO REPORT ERROR CODE ON OPERATION TO THE CONSOLE ;FOR A SIMPLE DEGREE OF FAULT ISOLATION. "STCHK" ERROR CODE IS REPORTED ; REPERR: PUSH PSW ;SAVE THE ERROR CODE LXI D,ERRMSG ;PRINT ERROR MESSAGE CALL CRTMS POP PSW CALL BYTEO ;OUTPUT ERROR CODE LXI D,ERRMS1 ;PRINT REST OF MESSAGE CALL CRTMS JMP PROMPT ; ; ERRMSG: DB CR,LF,CR,LF,BEL,BEL,' *** HARD DISK I/O ERROR - CODE(','#' ; ERRMS1: DB ') ***',CR,LF,'#' ; ; PAGE ;****************************************************************************** ; ; ; PUT SYSTEM IMAGE TO OPERATOR SELECTED DRIVE FROM MEMORY ; AT ADDRESS OF THE IMAGE POSITION "IBUF" SET BY EQUATE AT ; THE BEGINNING OF THIS PROGRAM. ALL OF TRACKS 0 AND 1 ARE ; WRITTEN FOR MAXIMUM FLEXIBILITY. NOTE THAT THIS REQUIRES THAT ; 12K OF MEMORY BE AVAILABLE ABOVE THE "IBUF" POSITION ; ; PUT: CALL CRLF LXI D,PUTMS ;PRINT PUT UNIT SELECT MESSAGE CALL CRTMS CALL CECHO ;GET OPERATOR ENTRY ANI 05FH ;UPPERCASE SUI 'A' ;ZERO BASE SELECT CPI MAXPLAT+1 ;CHECK IF TOO BIG JNC ERRR MOV C,A ;PUT DRIVE NUMBER INTO (C) CALL HPLAT ;SET HEAD NUMBER AS CP/M DRIVE NUMBER MVI C,0 CALL HSURF MVI C,00H ;SET HDSK UNIT 0 CALL HUNIT ; CALL CRLF ;CLEAN UP DISPLAY ; MVI D,01H ;START WITH RECORD 1 LXI B,000H ;START WITH CYLINDER 0 LXI H,IBUF ;START OF BUFFER AREA MVI E,ISIZE ;NUMBER OF RECORDS DO PUTLP: PUSH B ;SAVE CYL PUSH D ;SAVE RECORD NUMBER/REC COUNT PUSH H ;SAVE LOAD ADDRESS CALL HCYL ;PUT CYLINDER INTO IOPB MOV C,D ;PUT RECORD NUMBER INTO IOPB CALL HREC MOV C,L ;PUT WRITE ADDRESS INTO IOPB MOV B,H CALL HBADDR CALL HWRIT ;GO TELL DISK TO WRITE POP H ;GET BACK WRITE ADDRESS POP D ;GET BACK REC / REC CNT POP B ;GET BACK CYL ; ORA A ;CHECK COMMAND COMPLETION STATUS JNZ REPERR ;GO TO REPORT ERROR ; PUSH B LXI B,SECSIZ ;GET ADDRESS INDEX DAD B ;(HL) HAS NEW LOAD ADDRESS POP B INR D ;SET FOR NEXT RECORD MOV A,D ;CHECK IF PAST END OF CYLINDER CPI MAXREC+1 JNZ WSAMTK ;STILL ON SAME TRACK ; INX B ;INCREMENT CYLINDER NUMBER MVI D,01H ;SET RECORD BACK TO TRK START WSAMTK: DCR E ;SEE IF ALL SECTORS IN YET JNZ PUTLP ;GO DO MORE IF NOT DONE YET ; LXI D,PUTMS1 ;PRINT COMPLETE MESSAGE CALL CRTMS JMP PROMPT ;BACK TO PROMPT ; ; PUTMS: DB 'DESTINATION HARD DISK A: TO D: (A,B,C, OR D) ','#' ; PUTMS1: DB 'DESTINATION WRITE COMPLETE',CR,LF,'#' ; ; PAGE ;****************************************************************************** ; ; DATA PARAMETER STORAGE AREA FOR PROGRAM ; ; CCPSTK: DW 0 ;PLACE TO STORE CP/M CCP'S STACK POINTER ; ; DS 80 ;SETUP STORAGE FOR 40 LEVEL STACK STCKK EQU $ ; ; END ; ; ;+++...END OF FILE «eof»