;************************************************************************
; *
;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