       OPT  CYCLE,WRAP,XREF
       NAM  Softy Automatic Prom Blower Version 13
       SPC
ENQ    EQU  $05
ACK    EQU  $06
NAK    EQU  $15
       SPC
       ORG  $0000
START  NOP
       LDI  $00        Clear all external flags
       CAS
       XPAH  P3        Load P3 with zero as
       XPAL  P3        interrupt start address
       LDI  SCRTCH/256 Load P2 with start of working
       XPAH P2         memory
       LDI  SCRTCH
       XPAL P2
       USE  SCRTCH,P2
       SPC
       DLY  $FF      wait until IO chip out of reset
       DLY  $FF
       SPC
RESETA LDI  0
       ST   MDR        Set IO port for simple IO
       ST   PORTA      Initial pattern for control port
       ST   PORTB      Initial pattern for I/O port
       ST   ODRB       Direction spec for I/O port
       LDI  $47        Direction spec for control port
       ST   ODRA
       DLY  $FF        Delay while reseting link
       DLY  $FF
       ST   NLRST      De-assert link reset line
       SPC
RESETB LDI  0          Disable interrupts and power supply
       CAS
       DLY  $FF        Wait for relay
       DLY  $FF
       LDI  RX-1/256   Load P1 with entry point of
       XPAH P1         recieve routine
       LDI  RX-1
       XPAL P1
* Ignore first 10 characters from host to
* ensure link settled.
       LDI  10         Load syncnt with 10
       ST   SYNCNT
IGNRLP XPPC P1
       DLD  SYNCNT
       JNZ  IGNRLP
SYNCLP XPPC P1         Read byte from host
       XRI  ENQ        Compare with enq
       JNZ  SYNCLP     try again if not
* Send lots of null characters to host
* to settle link
       LDI  TX-1/256   Load P1 with entry point of
       XPAH P1         transmit subroutine
       LDI  TX-1
       XPAL P1
       LDI  37         Load SYNCNT with number of nulls
       ST   SYNCNT
SYNCSD CCL             Send null to host
       LDI  0
       XPPC P1
       DLD  SYNCNT     Check for end of loop
       JNZ  SYNCSD
       SPC
       CSA            Examine interrupt sense flag
       ANI  $10       Send NAK if ZIF contacts not
       JNZ  NACKED    closed
       LDI  $09       Enable interrupts and power
       CAS            Supplies
       DLY  $FF       wait for relay
       DLY  $FF
       SPC
* load contents of EPROM into RAM
       LDI  RAM/256    Load P1 with start of RAM
       XPAH P1
       LDI  RAM
       XPAL P1
       DROP P2
       LDI  EPROM/256  Load P2 with start of EPROM
       XPAH P2
       LDI  EPROM
       XPAL P2
LDLOOP LD   1(P2)+     Move byte from EPROM to RAM
       ST   1(P1)+     incrementing both pointers
       XPAH P1         Check for end of loop
       JZ   LDEXIT
       XPAH P1
       JMP  LDLOOP
LDEXIT EQU  *
       SPC
* Compare contents of EPROM with RAM
       LDI  RAM/256    Load P1 with start of RAM
       XPAH P1
       LDI  RAM
       XPAL P1
       LDI  EPROM/256  Load P2 with start of EPROM
       XPAH P2
       LDI  EPROM
       XPAL P2
CMLOOP LD   1(P2)+     Compare byte in EPROM with byte
       XOR  1(P1)+     in RAM and exit from loop if
       JNZ  NACKED     different
       XPAH P1         Check for end of loop
       JZ   CMEXIT
       XPAH P1
       JMP  CMLOOP
* Diference between copied EPROM and real
* EPROM indicates empty EPROM socked or duff
* 2708
NACKED LDI  TX-1/256   Load P1 with entry point of
       XPAH P1         transmit subroutine
       LDI  TX-1
       XPAL P1
       LDI  SCRTCH/256 Load P2 with base of
       XPAH P2         working memory
       LDI  SCRTCH
       XPAL P2
       CCL
       LDI  NAK        Transmit negative acknowledge to
       XPPC P1         host
       LDI  RESETB-1/256 Load P1 with start of
       XPAH P1         restart routine
       LDI  RESETB-1
       XPAL P1
       XPPC P1         terminate programming run
       SPC
* A working 2708 is present in programming socket
CMEXIT LDI  TX-1/256   load P1 with entry point of
       XPAH P1         transmit subroutine
       LDI  TX-1
       XPAL P1
       LDI  SCRTCH/256 Load P2 with base of
       XPAH P2         working memory
       LDI  SCRTCH
       XPAL P2
       USE  SCRTCH,P2
       CCL
       LDI  ACK        transmit acknowledgement to host
       XPPC P1
       SPC
* Send contents of EPROM to host
       LDI  TXCONT-1/256  Load P1 with entry point
       XPAH P1       of contents transmit subroutine
       LDI  TXCONT-1
       XPAL P1
       XPPC P1         Transmit contents to host
* Read new contents of EPROM from host
       LDI  0          Clear checksum
       ST   CHCKSM
       ST   CHCKSM+1
       LDI  RAM/256    Load PTR with start of RAM
       ST   PTR
       LDI  RAM
       ST   PTR+1
RXLOOP LDI  RX-1/256   Load P1 with entry point of
       XPAH P1         recieve routine
       LDI  RX-1
       XPAL P1
       XPPC P1         Read byte from host
       XAE             Save in extension reg
       LD   PTR        load P1 from pointer
       XPAH P1
       LD   PTR+1
       XPAL P1
       XAE
       ST   1(P1)+     Store in next byte of RAM
       CCL             Add into LSB of checksum
       ADD  CHCKSM+1
       ST   CHCKSM+1
       LDI  0          Add carry to MSB of checksum
       ADD  CHCKSM
       ST   CHCKSM
       XPAH P1        Check for end of loop
       JZ   RXEXIT
       ST   PTR      Save in PTR
       XPAL P1
       ST   PTR+1
       JMP  RXLOOP
RXEXIT LDI  RX-1/256   Load P1 with entry point of
       XPAH P1         recieve routine
       LDI  RX-1
       XPAL P1
       XPPC P1         Read MSB of host checksum
       ST   TEMP       Save in TEMP
       XPPC P1         Read LSB of host checksum
       CCL             Add LSB of softy checksum
       ADD  CHCKSM+1
       JNZ  CHCKFL     Fail if result is nonzero
       LD   TEMP       Add MSB of checksums
       ADD  CHCKSM
       JZ   BLOW       Go to next stage if OK
       SPC
* Checksum of recieved EPROM contents failed
CHCKFL LDI  TX-1/256   Load P1 with entry point of
       XPAH P1         transmit subroutine
       LDI  TX-1
       XPAL P1
       CCL
       LDI  NAK        Send negative acknowledge to host
       XPPC P1
       LDI  RESETB-1/256  Load P1 with address of
       XPAH P1         restart routine
       LDI  RESETB-1
       XPAL P1
       XPPC P1
       SPC
* Perform EPROM programming
BLOW   LDI  TX-1/256   Load P1 with entry point of
       XPAH P1         transmit subroutine
       LDI  TX-1
       XPAL P1
       CCL
       LDI  ACK        Send acknowledgement to host
       XPPC P1
       SPC
       LDI  20         Initialise BLWCNT2 with number
       ST   BLWCNT    of number of attempts.
       DROP P2
REBLOW LDI  5          Initialise accumulator with number
*                      of programming cycles per attempt
       SPC
* Programming cycle
BLWCYC XAE             Save no cycles in extension
       LDI  RAM/256    Load P1 with start of RAM
       XPAH P1
       LDI  RAM
       XPAL P1
       LDI  EPROM/256  Load P2 with start of EPROM
       XPAH P2
       LDI  EPROM
       XPAL P2
       LDI  $0B        Set F1 to enable programming
       CAS             circuitry
       SPC
BLWLP  LD   1(P1)+     Load next byte from RAM
       ST   0(P2)+     Store in EPROM triggering program
       LD   1(P2)+     pulse before incrementing pointer
       XPAH P1         Check for end of loop
       JZ   BLWLEX
       XPAH P1
       JMP  BLWLP
BLWLEX LDI  $09        Clear F1 to disable programming
       CAS             circuitry
       LDI  $FF        Decrement program cycle count
       ADE
       JNZ  BLWCYC     Check for end of prgramming loop
       SPC
       LDI  SCRTCH/256 Load P2 with base of
       XPAH P2         working memory
       LDI  SCRTCH
       XPAL P2
       USE  SCRTCH,P2
       DLD  BLWCNT     Check for number of attempts
       JZ   BLOWN
       SPC
* Check to see if EPROM now programmed
       LDI  RAM/256    Load P1 with start of RAM
       XPAH P1
       LDI  RAM
       XPAL P1
       DROP P2
       LDI  EPROM/256  Load P2 with start of EPROM
       XPAH P2
       LDI  EPROM
       XPAL P2
CKLOOP LD   1(P2)+     Compare byte in EPROM with byte
       XOR  1(P1)+     in RAM and perform further
       JNZ  REBLOW     program cycle if different
       XPAH P1         check for end of loop
       JZ   CKEXIT
       XPAH P1
       JMP  CKLOOP
CKEXIT LDI  SCRTCH/256 load P2 with base of working
       XPAH P2         memory
       LDI  SCRTCH
       XPAL P2
       USE  SCRTCH,P2
       LDI  1          Perform one more set of programming
       ST   BLWCNT     cycles
       JMP  REBLOW
* Transmit new EPROM contents to host for verification
BLOWN  LDI  TXCONT-1/256   Load P1 with entry point of
       XPAH P1         contents transmit subroutine
       LDI  TXCONT-1
       XPAL P1
       XPPC P1       Transmit EPROM contents to host
       LDI  RESETB-1/256  Load P1 with start of
       XPAH P1         restart routine
       LDI  RESETB-1
       XPAL P1
       XPPC P1         Restart program
       PAGE
TCRET  XPPC P1
TXCONT LDI  EPROM/256 Load P1 with start of EPROM
       XPAH P1        saving retrun address in LINK
       ST   LINK
       LDI  EPROM
       XPAL P1
       ST   LINK+1
       LDI  0          Clear the checksum
       ST   CHCKSM
       ST   CHCKSM+1
TXLOOP LD   1(P1)+     Load next byte from EPROM
       XAE             Save in extension register
       SCL             Subtract from LSB of checksum
       LD   CHCKSM+1
       CAE
       ST   CHCKSM+1
       LD   CHCKSM     Subtract carry from checksum MSB
       CAI  0
       ST   CHCKSM
       CCL
       LDI  TX-1/256   Load P1 with entry point of
       XPAH P1         transmit subroutine, saving P1
       ST   PTR        in PTR
       LDI  TX-1
       XPAL P1
       ST   PTR+1
       XAE             Restore EPROM byte to accumulator
       XPPC P1         Transmit byte to host
       LD   PTR        Check for end of loop
       XAE
       LDI  EPROM+1024/256
       XRE
       JZ   TXEXIT
       XAE        Restore pointer from PTR
       XPAH P1
       LD   PTR+1
       XPAL P1
       JMP  TXLOOP
TXEXIT CCL
       LD   CHCKSM     Transmit checksum to host
       XPPC P1
       CCL
       LD   CHCKSM+1
       XPPC P1
       SPC
* Check to see if EPROM contents recieved OK
       LDI  RX-1/256   Load P1 with entry point of
       XPAH P1         recieve subroutine
       LDI  RX-1
       XPAL P1
       XPPC P1         Read acknowledgement from host
       XAE
       LDI  ACK        Check for positive acknowledgement
       XRE
       JZ   TCEXIT     Return if OK
* Either link blown up or no change required on EPROM
* or change to EPROM cannot be made
       LDI  RESETB-1/256 Load P1 with address of
       XPAH P1         restart routines
       LDI  RESETB-1
       XPAL P1
       XPPC P1         Terminate programming run
TCEXIT LD   LINK       Restore return address from
       XPAH P1         LINK
       LD   LINK+1
       XPAL P1
       JMP  TCRET      Return
       PAGE
TXRET  XPPC P1
TX     ST   PORTB      Store byte in port regs
       CSA             Move status to acc
       ANI  $80        Blank all but carry
       JP   ZEROB9     Check for zero carry
       ST   SDB9       Set bit 9 of control port
       JMP  STTOCT
ZEROB9 ST   DB9        Clear bit 9 of control port
STTOCT LDI  93         set up time out counters
       ST   TOCNT1
       LDI  59
       ST   TOCNT2
       LDI  2
       ST   TOCNT3
TXBUSY LD   TXAC       Wait until TXAC not asserted
       JP   NTXBSY
       DLD  TOCNT1
       JNZ  TXBUSY
       DLD  TOCNT2
       JNZ  TXBUSY
       DLD  TOCNT3
       JNZ  TXBUSY
       JMP  TMOJMP
NTXBSY LD   TXAE       watch for acceptor error
       JNZ  TMOJMP     Time out if set
       LDI  $FF        set data port to output
       ST   ODRB
       LDI  $C7        set 9th bit of control port to
       ST   ODRA       output
       ST   TXSC       Pulse TXSC
       LDI  93         Set up time out counters
       ST   TOCNT1
       LDI  59
       ST   TOCNT2
       LDI  2
       ST   TOCNT3
NTXACT LD   TXAC       Wait until data accepted
       JNZ  TXACT
       DLD  TOCNT1
       JNZ  NTXACT
       DLD  TOCNT2
       JNZ  NTXACT
       DLD  TOCNT3
       JNZ  NTXACT
TMOJMP JMP  TIMOUT
TXACT  ST   NTXSC
       LDI  0          Set data port back to input
       ST   ODRB
       LDI  $47        Set 9th bit in control port
       ST   ODRA       back to input
       JMP  TXRET      Return from subroutine
       SPC  5
RXRET  XPPC P1
RX     LDI  93          Set up time out counters
       ST   TOCNT1
       LDI  59
       ST   TOCNT2
       LDI  2
       ST   TOCNT3
RXBUSY LD   RXSC       Wait until RXSC asserted
       JNZ  NRXBSY
       DLD  TOCNT1
       JNZ  RXBUSY
       DLD  TOCNT2
       JNZ  RXBUSY
       DLD  TOCNT3
       JNZ  RXBUSY
       JMP  TIMOUT
NRXBSY ST   RXEN       Enable link RX source gate
       LD   DB9        Load ninth link bit
       ANI  $80        And out possible rubbish
       XRI  $80        Invert data
       XAE             Save in extension register
       CSA             OR with 7 L.S. Bits of status
       ANI  $7F
       ORE
       CAS             Move to status so carry = bit 9
       LD   PORTB      Load RX data
       XRI  $FF        Invert loaded data
       ST   NRXEN      Disable link RX source gate
       ST   RXAC       Pulse RXAC
       XAE             Save byte in extension register
       LDI  93         Set up time out counters
       ST   TOCNT1
       LDI  59
       ST   TOCNT2
       LDI  2
       ST   TOCNT3
RXSCTD LD   RXSC       wait until acceptor noticed
       JP   NRXSCT
       DLD  TOCNT1
       JNZ  RXSCTD
       DLD  TOCNT2
       JNZ  RXSCTD
       DLD  TOCNT3
       JNZ  RXSCTD
       JMP  TIMOUT
NRXSCT ST   NRXAC
       XAE             Restore byte read in
       JMP  RXRET      Return from subroutine
       SPC  5
TIMOUT LDI  RESETA-1/256 Load P1 with start of
       XPAH P1        restart routine
       LDI  RESETA-1
       XPAL P1
       XPPC P1        jump to restart
       PAGE
       ORG  $0680
LRESET RMB  1
NRXEN  RMB  1
NRXAC  RMB  1
RXSC   RMB  1
TXAE   RMB  1
TXAC   RMB  1
NTXSC  RMB  1
DB9    RMB  1
       ORG  $0690
NLRST  RMB  1
RXEN   RMB  1
RXAC   RMB  1
       RMB  3
TXSC   RMB  1
SDB9   RMB  1
       ORG  $06A0
PORTA  RMB  1
PORTB  RMB  1
ODRA   RMB  1
ODRB   RMB  1
MDR    RMB  1
       SPC
       ORG  $0700
SCRTCH EQU  *-1
CHCKSM RMB  2
BLWCNT RMB  1
SYNCNT RMB  1
PTR    RMB  2
LINK   RMB  2
TEMP   RMB  1
TOCNT1 RMB  1
TOCNT2 RMB  1
TOCNT3 RMB  1
       ORG  $0800
EPROM  RMB  1024
RAM    RMB  1024
       END
