# include constant definition if not defined ifnotdef (PP) include/ prmdef.rat endifdef # The functions below are used in implementation of the basic PP #instruction set. These subroutines perform low level functions and #would not normally be called by a user program. # In the descriptions that follow, the integer variable ISTS #returns the status of the operation and its value may be one of #the following: # # SUCCES : The specified function was successful and the PP echoed # the READY ('>') code on completion of the function. # FAIL : The specified funtion was executed by the PP, however # the function failed and the PP returned FAILURE ('F'). # NOTE: this return does not necessarily indicate a serious # error in either the PP or the host computer, e.g., # the subroutine BLANK will return FAIL if the PROM being # tested caontained programmed bits. # PPERR : This error should not occur under normal operation, and # may indicate a serious error. This value will be returned # if the PP returned a value of '?' in response to a command. # This may indicate that the PP received a command that it # could not understand. After a PPERR occurs, the user # should call the subroutine ERRSTS to both reset the # error condition and to determine what error occured. # RCVERR : This error indicates the host detected a data receive # error. This can occur if there was a UART buffer # overflow, a UART framing error, or a receiver buffer # input overflow in the host driver software. This error # should never occur under normal conditions # HEXERR : Illegal hex value ################################################################################ # subroutine ppxr(comand,hexarg,lenexp,reply,ists) # ################################################################################ # This function accepts an arbitrary length command string COMAND #(which must be terminated with a null byte not a CR) that will be sent #to the PP. Before transmitting a command to the PP, the routine can transmit #an argument, HEXARG, which is a random length ASCII hex byte string. The #integer variable LENEXP specifies the number of ASCII hex bytes that the PP #expects to receive as an argument to the command. If the length of HEXARG #is less than LENEXP, then HEXARG must be terminated with a null byte, and PPXR #will adjust the length of the string HEXARG to match the number of ASCII hex #characters expected by the PP function by left filling the string with #'0's. If the PP function does not accept an argument, then LENEXP should #be set to 0 and only COMAND will be transmitted. # After the command string is transmitted, the routine waits for a one #line response from the PP. This response is stored in the LINBUF which is #dimensioned as LINMAX bytes long. If more than one line is transmitted #from the PP to the host then this routine cannot be used. The one record #transmitted by the PP is copied into the random length string REPLY and #it is terminated with a null byte. REPLY does not return a CR or a LF or #any of the status codes, i.e. SUCCES-'>', FAILURE-'F' or ERROR-'?'. ################################################################################ byte comand(ARB), hexarg(ARB), reply(ARB) # byte hextmp(6), pplin, hexbin # integer lenexp, ists, shift # # # if (lenexp>0) { # this subroutine has an argument # NOTE: following assumes HEXARG is terminated # by a null byte only if length(hexarg)len) { # prepend some '0's if hex arg too small l=shift(hextmp,1,lenexp-len) # left shift the string for (I=1; I<=lenexp-len; I=I+1) # hextmp(I)='0' # prepend right # of '0's } # if (~hexbin(hextmp,ival)) { # illegal hex value ists=HEXERR # return # } # call ppx(hextmp,lenexp) # transmit argument } # # call ppxlin(comand,length(comand)) # transmit command if (~pplin(reply,LINMAX,len)|len==0) { # wait for response ists=RCVERR # return # } # # value of last byte in string indicates status # this byte is also removed in the string REPLY if (reply(len)==READY) # ists=SUCCES # else # if (reply(len)==FAILURE) # ists=FAIL # else # ists=PPERR # reply(len)=EOS # delete last byte in reply string, it is # a status byte. return # end # # subroutine ppxbeg # ################################################################################ # This subroutine sends the appropriate START code to the prom programmer. #The start code precedes data transfers in a COMPARE (PPCMP) or an INPUT (PPINP) #operation and the code is determined by the data translation format (XFORMAT). ################################################################################ call ppx(STARTCODE,1) # transmit start code return # end # # subroutine ppxend # ################################################################################ # PPXEND transmits the nonprintable end code that is used to terminate #data transmission to the prom programmer in either the COMPARE (PPCMP) or #the INPUT (PPINP) commands. Also, the programmer employs a look-ahead procedure #to optimize some operations. However, this is undesirable in this application, #and to bypass the look-ahead, 16 DELETE bytes are sent to force the programmer #to send status of the previous PPINP or PPCMP operation back to the host #immediately. ################################################################################ byte delets(16) # data delets/16*DELETE/ # # call ppx(STOPCODE,1) # transmit stop code call ppx(delets,16) # 16 null nytes return # end # # subroutine sendpp(count,comand,data,ists) # ################################################################################ # This function is called by the CMPM2R (compares DATA to PP RAM) and the #INDATA (writes DATA to PP RAM) subroutines to write a command instruction #to the PP and then write an array of data. This function writes the following #information to the PP and in the order listed. # # 1) The 4 byte ascii string COUNT which is a count of the number of bytes # of memory that are to be programmed or to be compared, (i.e. the # # character bytes in the vector DATA divided by two). # THIS FUNCTION MODIFIES THE BLOCK SIZE, AND SETS IT EQUAL TO COUNT # 2) The random length instruction string COMAND is transmitted to the PP. # 3) The data transmit start code # 4) DATA a vector of ascii hex characters to be written/compared to memory # starting at address which is set by the BEGRAM subroutine. COUNT bytes # of memory are written/compared. # 5) The data transmit stop code # # The function returns status in the integer status parameter ISTS. #ISTS can return SUCCES, FAIL, HEXERR, PPERR or RCVERR. ################################################################################ byte count(4), data(ARB), hexbin # byte comand(ARB), pplin # include/ prmcom.rat # # if (~hexbin(count,icnt)) { # convert count to integer ists=HEXERR # conversion error return # } # nchars=icnt*2 # # of characters is twice the # of bytes # of memory to be programmed call blksiz(count,ists) # set block size if (ists~=SUCCES) # return # return if error call ppxlin(comand,length(comand)) # transmit the command call ppxbeg # precedes data transmission # linbuf(3)=COMMA # each ascii data followed by a comma for (I=1; I<=nchars; I=I+2) { # use temporary buffer for output linbuf(1)=data(I) # copy two ascii data linbuf(2)=data(I+1) # call ppx(linbuf,3) # send the data, three ascii chars at a time } # call ppxend # follows data transmission # if (~pplin(linbuf,LINMAX,len)|len~=1) # evaluate the function status return from PP ists=RCVERR # it is the last byte returned in the input buffer if (linbuf(1)==FAILURE) # ists=FAIL # else # if (linbuf(1)==READY) # ists=SUCCES # else # ists=PPERR # return # end # # integer function ipptok(nuline,token) # ################################################################################ # Routine to read lines from the PP and to parse the lines into tokens. #In response to an output data instruction, the PP returns data in a line #by line fashion. Each line is no more than the number of characters specified #by the record size (see the set record size instruction appendix page 3-7 #of the PP instruction manual). Lines of data are returned by the subroutine #PPLIN, and each line returned is terminated by a null byte. # The only argument that must be specified to the subroutine is the byte #variable NULINE. If NULINE is true, then this forces the subroutine to accept #a new line from the PP before parsing the next token. If NULINE is false, then #parsing will continue with the current line in the input buffer. When required #however, the function will read a new line. # The random length byte string TOKEN will return the next token and it #is terminated by a null byte. There are three types of tokens returned by the #subroutine, and each type is indicated by the function value return: # The last sequence to be sent from the PP is the checksum, after which #the PP sends the status byte, FAILURE, READY or ERROR. # # IPPTOK | description # ---------|------------------------------------------------------------- # ADDRESS | string TOKEN returns a 4 byte string that is an ASCII hex # | address in the format: HHHH (where H is a hex digit). # CHECKSUM | string TOKEN returns 5 byte string which is in the format: # | HHHH where HHHH is a four byte hex checksum. # FAIL | PP did not understand command, etc. the function failed # | to be executed by the PP # HEXDATA | TOKEN returns a two byte ASCII hex data word. # RCVERR | PPLIN retruned a status indicating a serious error # PPERR | if PP returns a FAILURE code, '?'. ################################################################################ byte linbuf(LINMAX), pplin, nuline # byte token(ARB) # # repeat { # if (nuline|linbuf(linpnt)==EOS) { # read a new line if true if (~pplin(linbuf,LINMAX,len)) # serious error on read return(RCVERR) # linpnt=1 # reset input line buffer pointer # if (len<10) { # then this line may be addrs or cksm ids=index(linbuf,'$') # addrs or cksm line has a '$' if (ids>0) { # line has a '$' linpnt=len+1 # force read of new line call copy(linbuf(ids+2),token,5)# copy addrs or cksm token if (linbuf(ids+1)=='S') { # this line is a checksum # get the next line, status code if (~pplin(linbuf,LINMAX,len)|len~=1) return(RCVERR) # error else # if (linbuf(1)==FAILURE) # PP indicates failure return(FAIL) # else # if (linbuf(1)==READY) # no error return(CHECKSUM)# return correct status else # return(PPERR) # } # else # return(ADDRESS) # else this line returns an address } # } # } # if (linbuf(linpnt)==',') { # noise character linpnt=linpnt+1 # ignore it next # } # call copy(linbuf(linpnt),token,3) # copy a 2 byte ascii hex data byte linpnt=linpnt+2 # return(HEXDATA) # } # end #