;************************************************************************ ; * ;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 THE SOFTWARE * ;ANY UNAUTHORIZED DISTRIBUTION OF THIS SOFTWARE IS STRICTLY FORBIDDEN * ; * ;************************************************************************ ; ; ;PROGRAM NAME PHEX ;BY BILL GROVES 9/10/82 ; ;PURPOSE TO GIVE THE USER DIRECT COMMUNICATIONS WITH THE ; MODEL 7128 EPROM PROGRAMMER FROM A CPM ENVIRONMENT ; AND TO PROGRAM EPROMS FROM HEX FILES IN INTEL FORMAT ; ;USAGE THE COMMAND PHEX ,ALONE, ALLOWS THE USER TO ; COMMUNICATE DIRECTLY WITH THE MODEL 7128. THIS MODE OF ; OPERATION IS NESSESSARY TO USE THE MENU, LIST, BAUD ; RATE AND VERIFY ERASURE COMMANDS. IT IS ALSO ; USEFULL FOR USING THE P COMMAND IF ONLY A ; FEW BYTES ARE TO BE PROGRAMMED. ; CONTROL S AND CONTROL Q MAY BE USED TO STOP/START ; LISTINGS, IE XOFF/XON. ; ; CONTROL IS RETURNED TO CPM WITH CONTROL C. ; ; IF A FILE NAME IS INCLUDED IT ; SHOULD HAVE A HEX EXTENSION. THE HEX FILE WILL BE ; OPENED AND SENT TO THE MODEL 7128, WHICH WILL PROGRAM ; AN EPROM WITH THE CONTENTS OF THE HEX RECORDS. ; ; THE SIZE (ADDRESS SPAN) OF THE HEX FILE SHOULD NOT ; EXCEED THE SIZE OF THE EPROM BEING PROGRAMMED. IF IT ; DOES, THEN BREAK THE HEX FILE INTO TWO OR MORE HEX ; FILES, ONE FOR EACH EPROM TO BE PROGRAMMED. ; ; REMEMBER, DONT WORRY ABOUT THE ADDRESSES THEMSELVES, ; BUT THE ADDRESS SPAN OF THE FILE. THE EPROM PROGRAMMER ; WILL DISREGARD ANY BITS IN THE ADDRESS WHICH ARE ; MORE SIGNIFICANT THAN THE SIZE OF THE EPROM. FOR ; EXAMPLE: THE ADDRESS 000H IS EQUIVILENT TO 4800H ; AS FAR AS THE PROGRAMMER IS CONCERNED WHEN IT IS ; PROGRAMMING A 2716. ; ; CONTROL WILL BE RETURNED TO CPM AT THE END OF THE FILE ; TRANSFER OR IF A PROGRAMMING ERROR OCCURS. ; ; ;INSTALLATION REQUIREMENTS ; **** SEE THE BINCHK AND BOUT ROUTINES NEAR THE END OF THIS SOURCE ; CODE... ; 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 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 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 ; 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 ;USE A LOCAL STACK LXI H,0 DAD SP ;SAVE THE CCP STACK POINTER FOR FAST RETURN TO CPM LATER SHLD OLDSP LXI SP,STACK LDA FCBFN ;GET FIRST CHAR OF FILENAME CPI ' ' ;SEE IF FILE NAME PRESENT JNZ PFILE ;GO PROGRAM EPROM FROM FILE MVI A,'X' ;DISPLAY BANNER JMP PHEX1 ;GO BE A DUMB TERMINAL ;** DUMB TERMINAL CODING ****************************************** PHEX2: CALL KBCHK ;SEE IF ANYTHING FROM CONSOLE JZ PHEX3 ;BRIF,NO KEYBOARD CHARACTER CPI CNTLC ;SEE IF USER WANTS OUT JZ FINIS ;WELL THEN LEAVE IF YOU WANT PHEX1: CALL BOUT ;SEND THE CHARACTER TO THE PROGRAMMER PHEX3: CALL BINCHK ;SEE IF PROGRAMMER HAS ANYTHING FOR US JZ PHEX2 ;BRIF,NOTHING FROM PROGRAMMER CALL CONOUT ;SEND CHAR TO CONOUT JMP PHEX2 ;LOOP ;**** END OF DUMB TERMINAL CODING ********************************* ;*** GET HERE TO PROGRAM FROM A FILE ****************************** PFILE: CALL START ;EMPTY UART MVI A,'X' ;TOOT YOUR HORN CALL SENDEM ;MAKE SURE PROGRAMMER IS PRESENT CALL WAITPR ;WAIT FOR PROMPTER FROM PROGRAMMER ;LOAD BUFFER WITH HEXFILE ;IN CASE USER CANT SERVICE SERIAL PORT AND DO DISK I/O SIMULTANEOUSLY ; ;FORCE FILE TO BE OF TYPE HEX, IN CASE USER FORGETS MVI A,'H' STA FCBFT ;LOAD FILE TYPE WITH HEX MVI A,'E' STA FCBFT+1 MVI A,'X' STA FCBFT+2 XRA A ;ZERO TO ACCUM STA FCBCR ;CLEAR CURRENT RECORD ;OPEN THE FILE IF WE CAN LXI D,FCB MVI C,OPENF CALL BDOS ; 255 IN ACCUM IF OPEN ERROR CPI 255 ;255 IF FILE NOT PRESENT JNZ FILBUF ;BRIF, FILE IS OPEN ; FILE NOT THERE, GIVE ERROR MESSAGE AND RETURN LXI D,OPNMSG MVI C,PRINTF ;PRINT BUFFER FUNCTION CALL BDOS JMP FINIS ;TO RETURN OPNMSG: DB CR,LF,'NO HEX FILE PRESENT ON DISK',BELL,'$' ;NOW LOAD HEXFILE TO RAM ;JUST ABOVE THE STACK FILBUF: LXI H,STACK ;LOAD HEX FILE TO RAM SHLD BUFFAD ;SAVE THE DMA ADDRESS FIL1: LHLD BUFFAD XCHG ;INPUT DMA ADDR TO DE MVI C,SETDMA CALL BDOS LXI D,FCB ;DO A READ MVI C,READF CALL BDOS ;READ A SECTOR ORA A ;SET FLAGS JNZ FIL2 ;END OF FILE REACHED LHLD BUFFAD ;INCREMENT READ ADDRESS FOR NEXT TIME LXI D,0080H DAD D SHLD BUFFAD JMP FIL1 ;GO GET NEXT RECORD ;HERE WHEN FILE IS LOADED TO RAM FIL2: LXI H,STACK-1 ;SET UP SOURCE POINTER SHLD SOURCE PHEX: ;HERE TO PROGRAM THE EPROM CALL GETRM ;GET A CHARACTER FROM MEMORY CPI ':' ;SCAN TO FIRST RECORD JNZ PHEX CALL SENDEM ;LEAD CHAR FOR PROGRAM COMMAND ;SEND THE BYTE BUT DONT WAIT FOR ;ECHO SO AS TO HAVE THE DATA INPUT AND ;OUTPUT SKEWED BY ONE BYTE TO SPEED THINGS ;UP (ABOUT TWICE AS FAST) PHEXLP: CALL GETRM ;GET A BYTE AND THEN SEND IT CALL SENBYTE JMP PHEXLP ;LOOP TILL DONE ;THE FOLLOWING SUBROUTINE SENDS A THE CHARACTER IN THE ACCUMULATOR TO THE ;PROGRAMMER AND WAITS FOR A RESPONSE. THE RESPONSE IS CHECKED TO SEE IF ;IT IS THE LEADER FOR AN ERROR CODE. IF NOT, THE CHARACTER IS ECHOED TO ;THE CONSOLE WHICH IN THIS CASE IS A BIT BUCKET. IF SO THE ROUTINE BRANCHES ;TO THE PROGRAMMER ERROR HANDLER. SENBYTE:CALL SENDEM ;SEND THE BYTE SENBY1: CALL BINCHK ;CHECK FOR CHAR JZ SENBY1 ;WAIT FOR RESPONSE CALL ECHO ;ECHO THE CHAR CPI '*' ;CHECK FOR ERRORS JZ ERHAND RET ;THE FOLLOWING ROUTINE SENDS THE CHARACTER IN THE ACCUMULATOR TO THE ;PROGRAMMER. PRIOR TO ACTUALLY SENDING THE CHARACTER, THE SERIAL PORT ;IS CHECKED TO SEE IF A CHARACTER HAS BEEN RECIEVED. IF ONE HAS, IT IS ;CHECKED TO SEE IF IT IS THE HEADER FOR AN ERROR, IN WHICH CASE EXCECUTION ;DEFAULTS TO THE ERROR HANDLER. IF SOME OTHER CHARACTER HAS BEEN RECEIVED, ;IT IS DISPLAYED ON THE CONSOLE (BIT BUCKET), AND THEN THE ORIGINAL INTENT ;OF THE SUBROUTINE IS EXECUTED, THAT IS, THE ORIGINAL CONTENTS OF THE ;ACCUMULATOR ARE SENT TO THE PROGRAMMER. SENDEM: PUSH PSW SEND1: CALL BINCHK ;SEE IF ANYTHING FROM PROGRAMMER JZ SEND2 ;BRIF NOTHING CALL ECHO ;ECHO CHAR TO CONSOLE CPI '*' ;CHECK FOR ERRORS JZ ERHAND JMP SEND1 ;LOOP FOR NEXT ;NOW DO WHAT WE INTENDED TO DO IN THE FIRST PLACE SEND2: POP PSW CALL BOUT RET ;THE FOLLOWING SUBROUTINE WAITS FOR THE PROMPTER, >, TO BE RECIEVED FROM ;THE PROGRAMMER. ALL RECEIVED CHARACTERS ARE SENT TO THE CONSOLE. WAITPR: CALL BINCHK ;HERE TO WAIT FOR PROMPTER FROM PROGRAMMER JZ WAITPR ;NOTHING YET CALL ECHO ;SEND TO CONSOLE CPI '>' JNZ WAITPR ;KEEP LOOKING RET ;THE FOLLOWING SUBROUTINE DISPLAYS THE ERROR MESSAGE ON THE CONSOLE, RINGS ;THE BELL AND ABORTS THE FILE TRANSFER....... ERHAND: CALL WAITPR ;GO DISPLAY ERROR MESSAGE MVI A,BELL ;AND RING-A-LING CALL ECHO JMP FINIS ;AND RETURN TO CPM ;CALL THIS ROUTINE TO MAKE SURE THAT SERIAL PORT IS EMPTY AND IF IT ISN'T ;FOR SOME REASON THEN GIVE THE USER A CHANCE TO GET BACK TO CPM START: CALL BREAK CALL BINCHK RZ ;UART IS EMPTY JMP START ;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 ;GET A BYTE FROM RAM TO THE ACCUMULATOR FOR THE CALLER GETRM: LHLD SOURCE ;GET A BYTE FROM HEXFILE INX H ;POINT TO BYTE SHLD SOURCE XCHG ;PUT SOURCE TO DE LHLD BUFFAD ;SOURCE=BUFFADD IF END OF FILE ;COMPARE SOURCE TO BUFFAD TO SEE IF END OF FILE REACHED MOV A,E SUB L JNZ GETRM1 MOV A,D SUB H JNZ GETRM1 ;MUST BE DONE IF AT END OF FILE ! JMP FINIS GETRM1: XCHG ;PUT SOURCE TO HL MOV A,M CPI 1AH ;SEE IF END OF FILE RNZ ;RETURN WITH BYTE CALL WAITPR JMP FINIS ;ALL DONE BREAK: ;CHEAK FOR CNTLC AT KEYBOARD CALL KBCHK CPI CNTLC JZ FINIS RET 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 ; ;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. ;FOR EXAMPLE: THE COMPUTER ON WHICH THIS SOFTWARE WAS WRITTEN ALLOWS ; THE 2ND SERIAL PORT TO BE ASSIGNED AS CONSOLE UNDER THE ; LOGICAL NAME UC1. ;IF YOUR COMPUTER DOES NOT SUPPORT THE I/O BYTE, THEN YOU CAN USE THE ;SAMPLE DRIVERS WHICH FOLLOW. SIMPLY SUPPLY THE DATA AND STATUS PORTS. ;SKIP TO SUPPLIED DRIVERS IF YOU SUPPORT THE I/O BYTE !!!!!!! ; TYPICAL PORT DRIVERS ************************************ ; FOR 8251 TYPE UART INMASK EQU 02 OUTMASK EQU 01 DATA EQU 00 STATUS EQU 01 ;FOR ZILOG SIO OR DART ;INMASK EQU 01 ;OUTMASK EQU 04 BINCHK IN STATUS ANI INMASK RZ ;NOTHING IN RECEIVE BUFFER IN DATA ORA A ;SET FLAGS RET BOUT PUSH PSW ;SAVE THE CHARACTER BO1 IN STATUS ANI OUTMASK JZ BO1 ;WAIT TIL TRANSMIT BUFFER READY POP PSW OUT DATA RET ;************************************************************* ; HERE IF YOU SUPPORT THE I/O BYTE !!!!!!!!!!!!!!!!!!!!!!!!! ;*********************************************************** ;******* MAKE THE FOLLOWING ASSIGNMENT FOR YOUR SYSTEM ***** PPIO EQU CRT ; * ;*********************************************************** ;*********************************************************** ; IO BYTE PORT DRIVERS *************************************** ;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 ; ;****************************************************************** ; ; ; ; ; ; ; ; ; VARIABLE AREA IOBSAV: DS 1 ;SAVE LOCATION FOR IOBYTE OLDSP: DS 2 ;ENTRY SP VALUE FROM CCP SOURCE: DS 2 ;SOURCE FILE POINTER BUFFAD: DS 2 ;DMA ADDRESS ; STACK AREA DS 100 STACK: ;HEX FILE GETS LOADED HERE END