;************************************************************************ ; * ;COPYRIGHT 1982 * ;GTEK, INC. * ;307-D COLEMAN AVENUE * ;P.O. BOX 289 * ;WAVELAND, MS. 39576 * ; * ;THIS SOURCE CODE IS THE PROPERTY OF GTEK, INC. * ;WHAT YOU HAVE PURCHASED IS THE RIGHT TO USE THIS SOFTWARE * ;ANY UNAUTHORIZED DISTRIBUTION OF THIS SOFTWARE IS STRICTLY FORBIDDEN * ; * ;************************************************************************ ; ; ;PROGRAM NAME RHEX ;BY BILL GROVES 9/20/82 ; ;PURPOSE THE COMMAND RHEX FILENAME WILL READ GENERATE A HEX ; FILE FROM THE MODEL 7128 EPROM PROGRAMMER. THE SIZE ; OF THE FILE GENERATED DEPENDS ON THE DEVICE TYPE ; CURRENTLY SELECTED. ; THE PROGRAMMERS' OI COMMAND IS USED TO IMPLEMENT THIS ; PROCEDURE. ; THE TRANSFERRING DATA IS ALSO ECHOED TO THE CONSOLE ; A HEX FILE MAY BE LOADED UNDER DDT AND MODIFIED, AND ; THEN SAVED AS A BINARY FILE. THE BINARY FILE MAY BE ; THEN USED AS THE SOURCE FILE FOR GHEX, WHICH WILL ; GENERATE A HEX FILE. ; CONTROL WILL BE RETURNED TO CPM SUBSEQUENT TO THE ; FILE TRANSFER AND RECORDING. ; ; ;INSTALLATION REQUIREMENTS ; THIS SOFTWARE REQUIRES NO HANDSHAKING ALTHOUGH CTS ; AND DTR MAY BE USED IF DESIRED. ; ; IF YOUR COMPUTER SUPPORTS THE I/O BYTE, THEN THE ; INSTALLATION BECOMES VERY SIMPLE, JUST SUPPLY THE ; LOGICAL NAME USED TO MAKE THE PROGRAMMER PORT ; BECOME THE CONSOLE. ; ; IF YOUR COMPUTER DOES NOT SUPPORT THE I/O BYTE ; THEN YOU MUST SUPPLY THE INSRUCTIONS TO READ ; PORT STATUS, INPUT A BYTE, AND OUTPUT A BYTE. ; ; THE FOLLOWING SOURCE CODE MAY BE ASSEMBLED WITH THE STANDARD ; CPM DISTRIBUTION ASSEMBLER, ASM.COM ;STANDARD CPM ENVIRONMENT EQUATES BDOS EQU 0005H ;DOS ENTRY POINT CONS EQU 1 ;READ CONSOLE TYPEF EQU 2 ;TYPE FUNCTION DCIOF EQU 6 ;DIRECT CONSOLE I/O FUNCTION PRINTF EQU 9 ;BUFFER PRINT ENTRY BRKF EQU 11 ;BREAK KEY FUNCTION (TRUE IF CHAR READY) OPENF EQU 15 ;FILE OPEN READF EQU 20 ;READ FUNCTION WRITEF EQU 21 ;WRITE SEQUENTIAL FUNCTION MAKEF EQU 22 ;CREATE FILE FUNCTION CLOSF EQU 16 ;CLOSE FILE FUNCTION SERCHF EQU 17 ;SEARCH FOR FIRST FUNCTION KILLF EQU 19 ;DELETE FUNCTION SETDMA EQU 26 ;SET DMA FUNCTION FCB EQU 5CH ;FILE CONTROL BLOCK ADDRESS BUFF EQU 80H ;INPUT DISK BUFFER ADDRESS ; NON GRAPHIC CHARACTERS CR EQU 0DH ;CARRIAGE RETURN LF EQU 0AH ;LINE FEED BELL EQU 07H CNTLC EQU 03H ;RETURN TO CPM EOF EQU 1AH ;END OF DISK FILE INDICATOR ; FILE CONTROL BLOCK DEFINITIONS FCBDN EQU FCB+0 ;DISK NAME FCBFN EQU FCB+1 ;FILE NAME FCBFT EQU FCB+9 ;DISK FILE TYPE (3 CHARACTERS) FCBRL EQU FCB+12 ;FILE'S CURRENT REEL NUMBER FCBRC EQU FCB+15 ;FILE'S RECORD COUNT (0 TO 128) FCBCR EQU FCB+32 ;CURRENT (NEXT) RECORD NUMBER (0 TO 127) FCBLN EQU FCB+33 ;FCB LENGTH ORG 100H ;SAVE CPM STACK POINTER AND SET UP STACK LXI H,0 DAD SP SHLD OLDSP ; SET SP TO LOCAL STACK AREA (RESTORED AT FINIS) LXI SP,STACK LDA FCBFN ;GET FIRST CHAR OF FILENAME LXI D,FILMSG CPI ' ' ;SEE IF FILE NAME PRESENT JNZ RHEX1 ;GO DO IT ;FILE NAME NOT PRESENT CALL ERR JMP FINIS RHEX1: ;FORCE NAME TO HAVE HEX EXTENSION MVI A,'H' STA FCBFT MVI A,'E' ;FILE IS OF TYPE HEX STA FCBFT+1 MVI A,'X' STA FCBFT+2 LXI D,FCB MVI C,SERCHF ;SEE IF FILE EXISTS CALL BDOS LXI D,DUPMSG INR A ;SHOULD BE 0 IF FILE IS NON EXISTANT JZ RHEX2 CALL ERR JMP FINIS ;FILE ALREADY EXISTS RHEX2: MVI C,MAKEF ;CREATE THE FILE LXI D,FCB CALL BDOS LXI D,DIRMSG INR A JNZ RHEX3 ;CREATED SUCCESSFULLY CALL ERR JMP FINIS RHEX3: CALL IDENT ;SHOW WHAT WERE DOING CALL READIT ;LOAD THE FILE TO RAM ;AND WRITE IT TO DISK JMP FINIS IDENT: ;USE SPACE COMMAND FOR IDENTIFICATION MVI A,' ' CALL COI ;GET ANY CHAR CALL GETPR ;WAIT FOR PROMPTER RET COI: ;OUTPUT CHAR IN ACC,THEN WAIT FOR RESPONSE CALL BOUT ;OUTPUT THE CHAR CALL BINPUT ;GET RESPONSE CPI '*' ;CHECK FOR ERRORS JZ ERREND ;HANDLE ERRORS CALL ECHO ;DISPLAY ALL RET GETPR: ;HERE TO WAIT FOR PROMPTER CALL BINPUT ;GET CHAR CPI '*' ;ANY ERRORS? JZ ERREND CPI '>' ;PROMPTER?? RZ ;RETURN WHEN PROMPTER ENCOUNTERED CALL CONOUT JMP GETPR ERREND: CALL DISERR ;SHOW ERROR MVI C,KILLF LXI D,FCB CALL BDOS JMP FINIS ;ERASE FILE WHICH WAS CREATED AND RETURN CPM DISERR: ;DISPLAY ERROR - RETURN ON PROMPT CALL ECHO CPI '>' RZ CALL BINPUT ;GET ANOTHER CHAR JMP DISERR READIT: ;HERE TO READ EPROM TO BUFFER AREA ; PUT DATA JUST BELOW THE STACK LXI H,STACK MVI A,'O' ;USE O COMMAND CALL COI MVI A,'I' ;INTEL HEX CALL COI MVI A,CR ;START THE COMMAND CALL COI RDT1: CALL BINPUT CALL ECHO ;SHOW IT COMMING IN MOV M,A ;PUT TO MEMORY CPI '>' ;COMMAND OVER ???? JZ RDT2 ;END OF COMMAND CPI '*' ;ANY ERRORS ??? JZ ERREND ;TERMINATE COMMAND INX H JMP RDT1 ;LOOP TIL DONE RDT2: DCX H MOV A,M ;GET CHAR AND SCAN BACK TO LAST LF CPI 0AH JNZ RDT2 DCX H ;MAKE ADJUSTMENT LXI D,-STACK ;CALCULATE BYTE COUNT=END - START DAD D XCHG ;PUT BYTE COUNT TO DE ;AND THEN WRITE THE FILE WTFILE: XRA A ;CLEAR OUTPUT BUFFER POINTER STA OBP ;INITIALIZE OUTPUT BUFFER POINTER LXI H,STACK ;STARTING SOURCE ADDRESS WTFIL1: MOV A,M ;GET BYTE FROM RAM CALL PUTCHAR ;PUT TO FILE INX H ;ADVANCE MEMORY POINTER DCX D ;DECREMENT COUNT MOV A,D ORA E ;SEE IF BYTE COUNT = 0 JNZ WTFIL1 WTFIL3: MVI A,EOF ;PUT END OF FILE MARKER IN FILE CALL PUTCHAR JNZ WTFIL3 ;PUT EOF'S TILL SECTOR IS WRITTEN MVI C,CLOSF LXI D,FCB CALL BDOS ;CLOSE FILE RET ; ERR: ;PRINT ERROR MESSAGE ; D,E ADDRESSES MESSAGE ENDING WITH "$" MVI C,PRINTF ;PRINT BUFFER FUNCTION CALL BDOS RET PUTCHAR: ;PUT CHARACTER TO DISK ;RETURN Z FLAG SET IF CALL CAUSED SECTOR TO BE WRITTEN PUSH B PUSH D PUSH H PUSH PSW ;SAVE CHARACTER TO BE OUTPUT ;GET OUTPUT BUFFER POINTER LDA OBP MOV E,A ;LS BYTE OF BUFFER INDEX MVI D,0 ;DOUBLE PRECISION INDEX TO DE LXI H,BUFF DAD D ; ABSOLUTE CHARACTER ADDRESS IS IN HL POP PSW ;RETRIEVE CHARACTER MOV M,A ;PUT CHAR TO DISK BUFFER LDA OBP ;NOW INCREMENT POINTER FOR NEXT TIME INR A STA OBP CPI 80H ;IS BUFFER FULL??? JNZ PUTEND ;BRIF NOT FULL ;NEED TO WRITE THIS BUFFER XRA A STA OBP ;ZERO THE OUTPUT BUFFER POINTER CALL DISKWR ORA A ;ZERO VALUE IF WRITE OK JZ PUTEND ;WRITE WAS OK LXI D,FULLMSG ;SHOULDNT END THIS WAY CALL ERR JMP FINIS PUTEND: POP H POP D POP B RET DISKWR: ;WRITE SECTOR TO DISK LXI D,FCB MVI C,WRITEF CALL BDOS RET ;HERE FOR A FAST RETURN TO CPM ;AS OPPOSED TO DOING A WARM BOOT (JMP 0000) FINIS: CALL CRLF LHLD OLDSP SPHL RET ;TO THE CCP CRLF: MVI A,CR CALL CONOUT MVI A,LF CALL CONOUT RET ;NON DESTRUCTIVE CONSOLE OUTPUT ECHO: PUSH PSW ;SEND TO CONSOLE,SAVE CALL CONOUT POP PSW RET ; ;USE DIRECT CONSOLE I/O FUNCTION AND CHECK FOR CHARACTER INPUT KBCHK: MVI A,0FFH ;CALL HERE TO CHECK FOR CONSOLE INPUT ;RETURNS 00 IF NOTHING READY ;RETURNS THE CHARACTER IF SOMETHING AVAILABLE ; ; ;CALL HERE FOR DIRECT CONSOLE OUTPUT. ENTER WITH THE ACCUMULATOR CONTAINING ;THE DESIRED CHARACTER TO BE OUTPUT. CONOUT: PUSH B PUSH D PUSH H MVI C,DCIOF MOV E,A CALL BDOS ORA A ;SET FLAGS ON RETURN POP H POP D POP B RET BINPUT: CALL BINCHK JZ BINPUT ;WAIT FOR CHARACTER FROM PROGRAMMER RET ; ;THE FOLLOWING ROUTINES ARE THE SERIAL INTERFACE DRIVERS FOR THE PROGRAMMER ;BINCHK MUST RETURN 00 IN THE ACCUMULATOR IF NOTHING HAS BEEN RECEIVED ; OR IF A CHARACTER HAS BEEN RECEIVED, THEN RETURN IT IN THE ; ACCUMULATOR. ;BOUT SIMPLY OUTPUTS THE ACCUMULATOR TO THE PROGRAMMER ;IF YOUR SYSTEM IMPLEMENTS THE IO BYTE, THEN SIMPLY APPLY THE TRUTH EQUATE ;TO THE DEVICE WHICH MAKES THE PROGRAMMER PORT BECOME THE CONSOLE. ;IF IT DOESN'T, THEN REPLACE THE CODE WITH THE FOLLOWING CODE ;OR WHATEVER ELSE MIGHT BE APPROPRIATE. ; TYPICAL PORT DRIVERS ************************************ INMASK EQU 02 OUTMASK EQU 01 DATA EQU 00 STATUS EQU 01 BINCHK IN STATUS AND INMASK RZ ;NOTHING IN RECEIVE BUFFER IN DATA ORA A ;SET FLAGS RET BOUT PUSH PSW ;SAVE THE CHARACTER BO1 IN STATUS AND OUTMASK JZ BO1 ;WAIT TIL TRANSMIT BUFFER READY POP PSW OUT DATA RET ;************************************************************* ; IO BYTE PORT DRIVERS *************************************** ;IOBYTE EQU 3 ;LOCATION OF IOBYTE ; POSSIBLE CONSOLE ASSIGNMENTS ;TTY EQU 00H ;BITS 1,0 = 00 ;CRT EQU 01H ;BITS 1,0 = 01 ;BAT EQU 02H ;BITS 1,0 = 10 ;UC1 EQU 03H ;BITS 1,0 = 11 ;*********************************************************** ;******* MAKE THE FOLLOWING ASSIGNMENT FOR YOUR SYSTEM ***** ;PPIO EQU CRT ; * ;*********************************************************** ;*********************************************************** ;BINCHK: ;RETURN A CHAR OR A=00 IF NOTHING AVAILABLE ; LDA IOBYTE ; STA IOBSAV ; ANI 0FCH ;CLEAR BITS 0 AND 1 ; ORI PPIO ;SET CONSOLE TO PROGRAMMER PORT ; STA IOBYTE ; CALL KBCHK ;SEE IF ANYTHING FROM PROGRAMMER ;BIORET: PUSH PSW ; LDA IOBSAV ; STA IOBYTE ;RESTORE CONSOLE ; POP PSW ; RET ; ;BOUT: ;ENTER WITH CHAR IN A ; PUSH PSW ; LDA IOBYTE ; STA IOBSAV ; ANI 0FCH ;CLEAR CONSOLE FIELD ; ORI PPIO ;ASSIGN PROGRAMMER TO CONSOLE ; STA IOBYTE ; POP PSW ; CALL CONOUT ; JMP BIORET ;RESTORE IOBYTE AND RETURN ;****************************************************************** ; FIXED MESSAGE AREA DIRMSG: DB CR,LF,BELL,'CANT CREATE FILE - DIRECTORY FULL ?$' FULLMSG:DB CR,LF,BELL,'DISK ERROR -- DISK FULL ??$' FILMSG: DB CR,LF,BELL,'YOU FORGOT TO GIVE ME A FILE NAME!$' DUPMSG: DB CR,LF,BELL,'THE ABOVE REFERENCED FILE ALREADY EXISTS' DB CR,LF,'WITH THE EXTENSION .HEX$' ; VARIABLE AREA IOBSAV: DS 1 ;SAVE LOCATION FOR IOBYTE OBP: DS 2 ;OUTPUT BUFFER POINTER OLDSP: DS 2 ;ENTRY SP VALUE FROM CCP ; STACK AREA DS 100 STACK: END