# include constant definition if not defined ifnotdef (PP) include/ prmdef.rat endifdef ################################################################################ # The following routines implement the basic instruction set of the #'SYSTEM 19 UNIVERSAL PROGRAMMER'. These routines are described in detail in the #APPENDIX on pages 3-4 to page 3-8 of this manual. # # In a few of the subroutines that transfer or compare data between #a data vector stored in the host and the data stored in the prom #programmer RAM, the block limit COUNT is altered. Note this will have an affect #on future calls to other subroutines that are affected by this value. # # Whenever an ascii hex number is required as a parameter, the ascii #string MUST be terminated by a null byte the ASCII hex string is shorter than #the number of ASCII hex bytes expected by the subroutine, (for details plese #see the instruction manual). Most subroutines expect 4 bytes, and for these #functions, if the ASCII hex argument is less than 4 ascii characters then the #string must be terminated by a null byte, and the subroutines will right fill #the string with the correct number of preceding '0's. # # These routines return status codes. For the corresponding numeric #values of these codes, see the file PRMDEF.RAT. The description below defines #the meanings of the different codes that are returned from the functions #described below in the integer variable ISTS: # # 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 contained # programmed bits. Also, if the sum of the block size and the # beginning of PP RAM address is larger than the PP RAM address # space, hen many of the PP functions will return false. Under # many circumstances, most of subroutines will not return a FAIL # status, however those that do (most commonly, but not # exclusively!!) are indicated in the subroutine description. # 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 : Hex to binary conversion error caused by an illegal HEX # value. ################################################################################ # subroutine begram(begin,ists) # ################################################################################ # Set beginning of RAM to the address BEGIN. BEGIN is an ASCII hex value #that is a maximum of four bytes long. BEGIN also determines the source address #in a RAM to RAM block data transfer. ################################################################################ byte begin(4) # include/ prmcom.rat # PP data common block # call ppxr('<',begin,4,linbuf,ists) # return # end # # subroutine blksiz(count,ists) # ################################################################################ # Set block size of RAM to COUNT. COUNT is an ASCII hex value that is a #maximum of four bytes long. COUNT also specifies the number of bytes to be #transferred in a RAM to RAM block data move. ################################################################################ byte count(4) # include/ prmcom.rat # PP data common block # call ppxr(';',count,4,linbuf,ists) # return # end # # subroutine begdev(begin,ists) # ################################################################################ # Set beginning of device to the address BEGIN. BEGIN is an ASCII hex #value that is a maximum of four bytes long. This value is also used as the #destination address in a RAM to RAM block data move. ################################################################################ byte begin(4) # include/ prmcom.rat # PP data common block # call ppxr(':',begin,4,linbuf,ists) # return # end # # subroutine chksum(sumchk,ists) # ################################################################################ # This command instructs the PP to compute the checksum of the data #stored in the PROGRAMMER RAM (not the PROM). The value is returned #as an 4 byte ascii hex string in the variable SUMCHK. This function #can return a value of ists=FAIL. # # ******************** # * NOTE * # ******************** # # Contrary to the PP instruction manual, the calculated checksum will be #affected by the set begin ram (BEGRAM) and the set block size (BLKSIZ) #subroutines. Only COUNT number of bytes of memory starting at address #BEGRAM will be included in the checksum returned by the PP. # Also, the number of points that can be included in the checksum #(i.e. determined by the most recent call to BLKSIZ) cannot exceed the #maximum size limit corresponding to the PROM programming adapter socket #that is installed in the PP. That is, if a 2K prom adapter socket is #installed (e.g. for a 2716), then the block size cannot be set to a value #larger than 2048. (7ff in hex). If this restriction is not adhered to, the #checksum subroutine will return ists=FAIL. ################################################################################ byte sumchk(4) # include/ prmcom.rat # PP data common block # call ppxr('S',,0,linbuf,ists) # for (I=1; I<=4; I=I+1) # copy result into return vector sumchk(I)=linbuf(I) # return # end # # subroutine extfun(funxn,ists) # ################################################################################ # This command allows entry of select codes as 2 byte ascii hex code #number FUNXN. This allows execution of functions carried in extended software #on some (but not all!) programming modules. See the operation instructions #for the programming module. ################################################################################ byte funxn(2) # include/ prmcom.rat # PP data common block # call ppxr(']',funxn,2,linbuf,ists) # return # end # # subroutine errsts(status,ists) # ################################################################################ # The computer writes the 32 bit error status code to the host. The error #status code is returned in the 8 byte string STATUS. Note that STATUS is #encoded in ASCII hex format, (see APPENDIX page 3-5 for a description of the #status word, and pages 3-8 and 3-9 for a description of the error codes). ################################################################################ byte status(8), pready # include/ prmcom.rat # PP data common block # call ppx(ESCAPE,1) # clear last error if any if (~pready()) { # wait for PP to echo READY ists=PPERR # error return # } # call ppxr('F',,0,linbuf,ists) # for (I=1; I<=8; I=I+1) # copy result into return vector status(I)=linbuf(I) # return # end # # subroutine badbit(ists) # ################################################################################ # Instructs the PP to search for a programmed bit in the PROM #that does not exist in PP RAM (that's what it says, not really very meaningful #is it?). If the test indicates an illegally programmed bit then ists=FAIL #and ists=SUCCES indicates the test was successful. ################################################################################ include/ prmcom.rat # PP data common block # call ppxr('T',,0,linbuf,ists) # return # end # # subroutine blank(ists) # ################################################################################ # Instructs the PP to search the PROM for programmed bits. If any #programmed bits are found then ists=FAIL, and if the PROM is blank then #ists=SUCCES. ################################################################################ include/ prmcom.rat # PP data common block # call ppxr('B',,0,linbuf,ists) # return # end # # subroutine ifamly(fampin,ists) # ################################################################################ # Instructs the programmer to send to the computer a 4 digit hex number #consisting of a 2 digit family code and a 2 digit pinout code, and in that #order. These codes identify the PROM which the UNIPAK is configured to program. #This command is valid only with the UNIPAK installed in the programmer. ################################################################################ byte fampin(4) # include/ prmcom.rat # PP data common block # call ppxr('[',,0,linbuf,ists) # for (I=1; I<=4; I=I+1) # copy result in output vector fampin(I)=linbuf(I) # return # end # # subroutine sfamly(fampin,ists) # ################################################################################ # Sends the programmer a 4 digit hex number consisting of a 2 digit family #code and a 2 digit pinout code, and in that order. These codes specify the PROM #configuration of the UNIPAK. This command is valid only with the UNIPAK #installed in the programmer. ################################################################################ byte fampin(4) # include/ prmcom.rat # PP data common block # call ppxr('@',fampin,4,linbuf,ists) # return # end # # subroutine respnd(resp,ists) # ################################################################################ # Returns an arbitrary length string of ASCII hex characters in the #byte string RESP. The value returned can be used to determine the installed #programming electronics and the socket adapter. RESP should be dimensioned #as at least 10 bytes in length. The byte string RESP will be terminated #by a null byte. ################################################################################ byte resp(10) # include/ prmcom.rat # PP data common block # call ppxr('R',,0,linbuf,ists) # call copy(linbuf,resp,10) # copy response, terminate with null return # end # # subroutine load(ists) # ################################################################################ # Instructs the PP to load data into its internal RAM from the #PROM in the socket adapter within the parameters defined by the block #limits L1, L2 and L3. If the device data did not load correctly, the function #will return ists=FAIL. ################################################################################ include/ prmcom.rat # PP data common block # call ppxr('L',,0,linbuf,ists) # return # end # # subroutine prgrm(ists) # ################################################################################ # Instructs the PP to program the PROM in the socket adapter from the #contents of the PP internal RAM, within the block limits L1, L2 and L3. If the #programming operation fails, ists=FAIL. ################################################################################ include/ prmcom.rat # PP data common block # call ppxr('P',,0,linbuf,ists) # return # end # # subroutine verify(ists) # ################################################################################ # Instructs the PP to compare RAM data with the data of the PROM device #in the socket adapter, within the parameters defined by the block limits #L1, L2 and L3. If the verify operation fails, ists=FAIL. ################################################################################ include/ prmcom.rat # PP data common block # call ppxr('V',,0,linbuf,ists) # return # end # # subroutine offset(ofst,ists) # ################################################################################ # This is used to specify an address offset OFST. OFST is an ASCII hex #value that is at most four bytes long. This offset will be subtracted from all #addresses input to the programmer, and added to all addresses output from the #programmer. The address offset adjusts RAM addresses to address the range of #larger memories. ################################################################################ byte ofst(4) # include/ prmcom.rat # PP data common block # call ppxr('W',ofst,4,linbuf,ists) # return # end # # subroutine indata(count,data,ists) # ################################################################################ # Instructs the programmer to accept formatted data from the computer. #The input byte string DATA must contain the ASCII hex data to be stored in the #PP's internal RAM. COUNT number of memory bytes of data will be written, #(or 2*COUNT number of ASCII characters are in DATA). Failure of the operation #returns ists=FAIL. Also the routine will return HEXERR if COUNT is an illegal #hex value. This function sets the COUNT block limit. # # The DATA vector is assumed to store the equivalent of COUNT bytes of #ASCII hex data. Since in ASCII code, each binary byte is stored as two ASCII #bytes, COUNT*2=length(DATA). Also: # # data(I) -- ASCII hex of hi nibble | I={1,3,5,7,...} # data(I+1) -- ASCII hex of lo nibble | ################################################################################ byte data(ARB), count(4) # # call sendpp(count,'I',data,ists) # return # end # # subroutine odata(count,data,ists) # ################################################################################ # Instructs the programmer to send the data stored in the PROGRAMMER RAM #to the host computer. The byte vector DATA is used to store the ASCII hex #bytes that are sent by the PP. COUNT specifyies the number of bytes of memory #to be output, and the first address to read from. Failure on data output #returns ists=FAIL. This function alters the COUNT block limit in the PROM #programmer. # The DATA vector will return the equivalent of COUNT number of bytes of #ASCII hex data. Since in ASCII code, each binary byte is stored as two ASCII #bytes, COUNT*2=length(DATA). Also: # # data(I) -- ASCII hex of hi nibble | I={1,3,5,7,...} # data(I+1) -- ASCII hex of lo nibble | # # The function returns status in the integer status parameter ISTS. #ISTS can return SUCCES, FAIL, HEXERR, PPERR or RCVERR. # # Programming note: It is possible to call this routine several times #in order to allow functions to be performed with very large memories, as #a program may otherwise be limited by the amount of available buffer space. #The calling routine MUST adjust the BLOCK LIMITS in order to accomplish this. ################################################################################ byte data(ARB), count(4) # byte hexbin, adrs(4), compar, token(10) # integer ipptok # # if (~hexbin(count,icnt)) { # convert count to integer ists=HEXERR # conversion error return # } # call blksiz(count,ists) # set block size if (ists~=SUCCES) # return # return if error # call load(ists) # copy data from PROM to PP RAM if (ists~=SUCCES) # if load error return # # call ppxlin('O',1) # transmit output command # xmit data in PP RAM to the host itipe=ipptok(.true.,token) # get the first token # this causes first line to be read in, after # which new lines read as needed. # whats the token? if (itipe<=0) { # error -->> RCVERR or PPERR or FAIL ists=itipe # return # } # else # if (itipe~=ADDRESS) { # address always starts first ists=PPERR # bad error return # } # # iup=icnt*2 # for (I=1; I<=iup ; I=I+2) { # wait for this many bytes repeat { # ignore address tokens itipe=ipptok(.false.,token) # input the next token, from current input # line if possible if (itipe<=0) { # error -->> RCVERR or PPERR or FAIL ists=itipe # return # } # if (itipe==CHECKSUM) { # very last record is checksum ists=RCVERR # but should never read that far inside loop return # } # } until(itipe==HEXDATA) # wait till next data byte data(I)=token(1) # comparison data vector data(I+1)=token(2) # } # # itipe=ipptok(.false.,token) # last token should be checksum len=length(token) # calculate length of TOKEN, last byte is status if (itipe<=0) # error -->> RCVERR or PPERR or FAIL ists=itipe # else # if (itipe~=CHECKSUM) # if checksum not last ists=PPERR # error else # ists=SUCCES # no errors # return # end # # subroutine cmpm2r(count,data,ists) # ################################################################################ # Instructs the programmer to compare data in RAM with the data in #DATA. The byte vector DATA is used to store the ASCII hex bytes #that are compared with the data in PP RAM. COUNT is the number of bytes of #memory to be compared, (i.e. 2*COUNT number of ASCII characters are in DATA). #Failure of the operation returns ists=FAIL. The routine will return HEXERR #if COUNT is an illegal hex value. This function sets the COUNT block limit. # # The DATA vector is assumed to store the equivalent of COUNT number of #bytes of ASCII hex data. Since in ASCII code, each binary byte is stored as #two ASCII bytes, COUNT*2=length(DATA). Also: # # data(I) -- ASCII hex of hi nibble | I={1,3,5,7,...} # data(I+1) -- ASCII hex of lo nibble | # # ********************** # * NOTE!! * # ********************** # # The function CMPRAM is probably better to use for comparing RAM to an #array because CMPRAM routine logs each discrepancy as it occurs, so it is #possible to determine what bytes are wrong. # ################################################################################ byte data(ARB), count(4) # # call sendpp(count,'C',data,ists) # return # end # # subroutine parity(pty,ists) # ################################################################################ # Instructs the programmer to output the hex number of parity errors. #This number is returned as a random length string terminated by a null byte, #in the byte vector PTY. PTY must be dimensioned at least 4 bytes long. ################################################################################ byte pty(4) # include/ prmcom.rat # PP data common block # call ppxr('Y',,0,linbuf,ists) # call copy (linbuf,pty,4) # copy buffer into output variable return # end # # subroutine swpnib(ists) # ################################################################################ # Instructs the programmer to exchange high and low order halves of every #byte in RAM. This is useful for programming 4-bit devices with only one-half #of RAM at a time. ################################################################################ include/ prmcom.rat # PP data common block # call ppxr('Q',,0,linbuf,ists) # return # end # # subroutine r2rmov(ists) # ################################################################################ # RAM to RAM block move. Moves COUNT number of bytes from RAM location FROM #to RAM location TO, where: # # parameter | set by subroutine # ------------|------------------- # COUNT | BLKSIZ # FROM | BEGRAM # TO | BEGDEV ################################################################################ include/ prmcom.rat # PP data common block # call ppxr('\',,0,linbuf,ists) # return # end # # subroutine split(ctrpnt,ists) # ################################################################################ # Instructs the PP to split RAM data, where CTRPNT is the ASCII hex #value indicating the center point. CTRPNT is a maximum of 4 bytes long. ################################################################################ byte ctrpnt(4) # include/ prmcom.rat # PP data common block # call ppxr('?',ctrpnt,4,linbuf,ists) # return # end # # subroutine shuffle(ctrpnt,ists) # ################################################################################ # Instructs the PP to shuffle RAM data, and CTRPNT is the ASCII hex #value indicating the center point. CTRPNT is a maximum of 4 bytes long. ################################################################################ byte ctrpnt(4) # include/ prmcom.rat # PP data common block # call ppxr('>',ctrpnt,4,linbuf,ists) # return # end #