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