*****************************************************                                                  **  PROCEDUR ZUR PROGRAMMIERUNG EINES BYTES         **   EINES 27256 EPROMS                             **   Hardware: c't-Userport + PROMMER 520           ** last update:   01.12.86       15h00              **                                                  *************************************************cmw**      MODULE HEAD FOR RTOS-UH                     **                                                  *       DC.L   0              for loader            *       DC.L   0              for loader            *       DC     $10            Type: MDLE            *       DC.B   'EPX   '       module name           ******************************************************      SYSTEM TRAPS                                **                                                  *QDPC   OPD    $4E43          call dispatcher       *RETN   OPD    $4E4C          return from proc.     *OFF    OPD    $4E4F          interrupts off        *VARW   OPD.V  10             FIXED(15) by ident    *INVW   OPD.V  14             FIXED(15) by value    *EPAR   OPD.V  19             end of parm xfer      *ENTR   OPD.V  29             procedure entry       ******************************************************      MEMORY SECTION DEFINITIONS                  **                                                  *BLOCK  EQU    $24            block-byte of a task  *BLKBSU EQU    4              susp. bit no in BLOCK ******************************************************      ADDRESS DEFINITIONS                         **                                                  **      interrupt vector definitions                *TCVEC  EQU    $114                                 **      userport definitions                        *UPCLR  EQU    $FAFFF5        reset                 *UPLIN  EQU    $FAFFF6        latch in puls         *UPLOUT EQU    $FAFFF7        latch out puls        *UPPIN  EQU    $FAFFF8        input port            *UPPINL EQU    $FAFFFA        input port latched    *UPIOC  EQU    $FAFFFD        serial I/O clock      *UPSTAT EQU    $FAFFFA        userport status reg   *UPOUT  EQU    $FB0000        output port base addr **      MFP 68901 definitions                       *IERB   EQU    $FFFA09        MFP IR enable reg     *IMRB   EQU    $FFFA15        MFP IR mask reg       *TCDCR  EQU    $FFFA1D        MFP timer CD ctrl reg *TCDR   EQU    $FFFA23        MFP timer C data reg  ******************************************************      SYSTEM VARIABLE DEFINITIONS                 **                                                  *IID    EQU    $7FE           ID act. running IR    *DPC    EQU    $800           dispatcher-call flag  *TID    EQU    $802           ID act. running task  *DPCJ   EQU    $906           jump to dispatcher    ******************************************************      PROCEDURE WORKSPACE DEFINITIONS             **                                                  *ADR    EQU    0              addr where to program *BYTE   EQU    ADR+2          byte to program       *MODE   EQU    BYTE+2         programming mode      *RTN    EQU    MODE+2         addr of return value  *WSPSZ  EQU    RTN+4          proc workspace size   ******************************************************      INTERRUPT BUFFER DEFINITIONS                **                                                  *OWNTID EQU    0              own task ID           *PWSP   EQU    OWNTID+4       addr of proc workspace*CNT    EQU    PWSP+4         retry count           *FLAGS  EQU    CNT+2          flags                 *ECTRH  EQU    FLAGS+2        must be FF            *ECTRL  EQU    ECTRH+1        eprom ctrl reg        *OLDVEC EQU    ECTRL+1        old IR vector         *IRBSZ  EQU    OLDVEC+4       IR buffer size        *IRBUF  DS     IRBSZ          allocate memory       ******************************************************      MISCELLANEOUS DEFINITIONS                   **                                                  **      flag definitions                            *FINPLS EQU    0              initial program puls  *FOVPRG EQU    1              overprogram puls      **      mode definitions                            *MVPP   EQU    0              0: 12,5V 1: 21V       *MVCC   EQU    1              0: 5V,   1: 6V        *TIME   EQU    12             timer data for 1 us   *MAXCNT EQU    25             max # of retries      ******************************************************      PROGRAM ONE BYTE OF AN EPROM                ******************************************************      REGISTER USAGE                              **      A2     address of interrupt buffer          **      A5     address of procedure workspace       **                                                  *>P256: ENTR   WSPSZ.L        fetch storage         *       INVW   ADR.X          addr where to program *       INVW   BYTE.X         byte to program       *       INVW   MODE.X         programming mode      *       VARW   RTN.Z          addr of return value  *       EPAR                  end of parm xfer      *       TST.B  UPCLR          reset userport        *       LEA    IRBUF,A2       get addr of IR buffer *       MOVE.L TID,OWNTID(A2) save own task ID      *       MOVE.L A5,PWSP(A2)    save addr of PWSP     **      return, if BYTE = FF                        *       CMPI.B =$FF,BYTE+1.X  check for equal       *       BNE.S  P1             b: is not equal to FF *       MOVE   =$00FF,D1      code: no error        *P0:    MOVEA.L RTN.X,A0      xfer return value     *       MOVE   D1,(A0)                              *       RETN                  back to caller        **      prepare anything for programming            *P1:    MOVEQ  =0,D0          clear D0              *       MOVE   D0,CNT(A2)     initialize puls count *       MOVE   D0,FLAGS(A2)   initialize flags      *       MOVE   D0,ECTRH(A2)   init eprommer ctrl reg*       BSET   =1,ECTRL(A2)   Vpp at pin 1          *       BSET   =4,ECTRL(A2)   /OE high              *       BTST   =MVPP,MODE+1.X check program voltage *       BNE.S  P2             b: 21V selected       *       BSET   =5,ECTRL(A2)   select Vpp = 12,5V    *P2:    BTST   =MVCC,MODE+1.X check supply voltage  *       BEQ.S  P3             b: 5V selected        *       BSET   =7,ECTRL(A2)   select Vcc = 6V       *       BRA.S  P4                                   *P3:    BSET   =3,ECTRL(A2)   select Vcc = 5V       *P4:    OFF                   no irq allowed        *       MOVE.B TCDCR,D0       init timer C          *       ORI.B  =$70,D0        /200 prescaler        *       MOVE.B D0,TCDCR                             *       MOVE.B =TIME,TCDR     set timer C data reg  *       LEA    TCVEC,A1       addr timer C vector   *       MOVE.L (A1),OLDVEC(A2) save old IR vector   *       LEA    EPIRQ,A3       get addr of IR routine*       MOVE.L A3,(A1)        set new vector        *       MOVE.B OLDVEC(A2),(A1) recover MSB of vector*       MOVE.B IMRB,D0        clear timer C IRQ mask*       ORI.B  =$20,D0                              *       MOVE.B D0,IMRB                              *       MOVE.B IERB,D0        enable timer C IRQ    *       ORI.B  =$20,D0                              *       MOVE.B D0,IERB                              **      start first program puls                    *       BSET   =FINPLS,FLAGS(A2) first program puls *       LEA    UPOUT,A1       base addr for output  *       MOVEQ  =0,D1          clear D1              *       MOVE.B BYTE+1.X,D1    get data to program   *       TST.B  0(A1,D1.L)     write to output port  *       TST.B  UPLIN          store at data latch   *       MOVE   ECTRH(A2),D1   get eprom ctrl reg    *       TST.B  0(A1,D1.L)     write to output port  *       TST.B  UPIOC          store at ctrl register*       MOVE   ADR.X,D1       get program address   *       TST.B  0(A1,D1.L)     write to output port  *       TST.B  UPLOUT         /CE low               *       MOVEA.L OWNTID(A2),A1 get own task ID       *       BSET   =BLKBSU,BLOCK(A1) suspend itself     *       ANDI   =$D8FF,SR      enable interrupts     *       QDPC                  call dispatcher       **      wait for IR routine to wake this task       **--------------------------------------------------**      restore old IR vector                       *       OFF                   no irq allowed        *       LEA    TCVEC,A1       addr timer C vector   *       MOVE.L OLDVEC(A2),(A1) restore old IR vector*       ANDI   =$D8FF,SR      enable interrupts     *       RETN                  back to caller        **                                                  ******************************************************      INTERRUPT ROUTINE                           ******************************************************      REGISTER USAGE                              **      A1:    output port base address             **      A2:    address of interrupt buffer          **      A5:    address of procedure workspace       **                                                  *       DC     IRMAL-EPIRQ    malfunction link      *EPIRQ  MOVE   IID,-(A7)      save old IR ID        *       MOVE   =TCVEC,IID     save own ID           *       MOVEM.L D0-D2/A0-A2/A5,-(A7) save register  *       LEA    IRBUF,A2       get addr of IR buffer *       MOVEA.L PWSP(A2),A5   addr of proc workspace*       LEA    UPOUT,A1       base addr for output  *       BTST   =FINPLS,FLAGS(A2) first program puls *       BEQ    EP2            b: not first pulses   **      verify just now programmed byte             *       TST.B  UPPINL         /CE high              *       BSET   =0,ECTRL(A2)   disable data latch    *       BCLR   =4,ECTRL(A2)   /OE low               *       MOVE   ECTRH(A2),D1   get eprom ctrl reg    *       TST.B  0(A1,D1.L)     write to output port  *       TST.B  UPIOC          store at ctrl register*       MOVE   ADR.X,D1       get program address   *       TST.B  0(A1,D1.L)     write to output port  *       TST.B  UPLOUT         /CE low               **      do some stuff before reading the input port *       BCLR   =0,ECTRL(A2)   enable data latch     *       BSET   =4,ECTRL(A2)   /OE high              *       MOVE   UPPIN,D0       read input port       *       TST.B  UPPINL         /CE high              *       CMP.B  BYTE+1.X,D0    test for equal        *       BEQ.S  EP1            b: verify ok          **      check for device fail                       *       MOVEQ  =-1,D2         err code: device fail *       ADDQ   =1,CNT(A2)     incr retry count      *       CMPI   =MAXCNT,CNT(A2) to often?            *       BEQ    EX3            b: bad device, exit   **      start next program puls                     *       MOVE   ECTRH(A2),D1   get eprom ctrl reg    *       TST.B  0(A1,D1.L)     write to output port  *       TST.B  UPIOC          store at ctrl register*       MOVE   ADR.X,D1       get program address   *       TST.B  0(A1,D1.L)     write to output port  *       TST.B  UPLOUT         /CE low               *       BRA    EP9            exit                  **--------------------------------------------------**      set up timer for overprogram puls           **                                                  *EP1:   MOVE   CNT(A2),D2     get counter           *       MULU   =TIME,D2       calc timer ticks      *       MULU   =3,D2           for overprogram puls *       MOVE   D2,CNT(A2)     save the result       *       BCLR   =FINPLS,FLAGS(A2) start of overprog  *       BSET   =FOVPRG,FLAGS(A2)                    **      start overprogram puls                      *       MOVE   ECTRH(A2),D1   get eprom ctrl reg    *       TST.B  0(A1,D1.L)     write to output port  *       TST.B  UPIOC          store at ctrl register*       MOVE   ADR.X,D1       get program address   *       TST.B  0(A1,D1.L)     write to output port  *       TST.B  UPLOUT         /CE low               **      manage overprogram puls                     **                                                  *EP2:   MOVEQ  =0,D2          code: no error        *       BTST   =FOVPRG,FLAGS(A2) overprogram done?  *       BEQ.S  EX2            b: it's done, exit    *       MOVE.B TCDCR,D0       stop timer C          *       ANDI.B =$0F,D0                              *       MOVE.B D0,TCDCR                             *       MOVE   CNT(A2),D0     get counter           *       SUBI   =$100,D0       more than 256 ticks?  *       BPL.S  EP3            b: yes, more          *       BCLR   =FOVPRG,FLAGS(A2) end of overprogram *       MOVE   CNT(A2),D2     get counter           *EP3:   MOVE   D2,CNT(A2)     save the rest         *       MOVE.B D2,TCDR        set timer C data reg  *       MOVE.B TCDCR,D0       start timer C         *       ORI.B  =$70,D0        /200 prescaler        *       MOVE.B D0,TCDCR                             **      restore registers, wait for next timer IR   *EP9:   MOVEM.L (A7)+,D0-D2/A0-A2/A5 recover regs   *       MOVE   (A7)+,IID      recover old IID       *EXIT:  ORI    =$0700,SR      all IR off            *       TST    DPC            dispatcher call?      *       BMI.S  EX1            b: no proc. switching *       RTE                   normal exit           *EX1:   JMP    DPCJ           call dispatcher       **--------------------------------------------------**      verify programmed byte with Vcc = Vpp = 5V  *EX2:   MOVEQ  =$09,D1        disable data latch    *       TST.B  0(A1,D1.L)     write to output port  *       TST.B  UPIOC          store at ctrl register*       MOVE   ADR.X,D1       get program address   *       ORI    =$8000,D1      set MSB               *       TST.B  0(A1,D1.L)     write to output port  *       TST.B  UPLOUT         /CE low               *       MOVEQ  =0,D2          clear D2              *       NOP                   wait                  *       NOP                                         *       MOVE   UPPIN,D2       read input port       *       TST.B  UPPINL         /CE high              *       CMP.B  BYTE+1.X,D2    test for equal        *       BEQ.S  EX3            b: device ok          *       MOVEQ  =-3,D2         err code: device fail **--------------------------------------------------**      disable timer C, wake sleeping task         **      D2:    return value                         *EX3:   MOVEA.L RTN.X,A0      xfer return value     *       MOVE   D2,(A0)                              *       TST.B  UPCLR          reset userport        *       MOVE.B IERB,D0        disable timer C IRQ   *       ANDI.B =$DF,D0                              *       MOVE.B D0,IERB                              *       MOVE.B IMRB,D0        mask timer C IRQ      *       ANDI.B =$DF,D0                              *       MOVE.B D0,IMRB                              *       MOVE.B TCDCR,D0       stop timer C          *       ANDI.B =$0F,D0                              *       MOVE.B D0,TCDCR                             *       MOVEA.L OWNTID(A2),A0 get own task ID       *       BCLR   =BLKBSU,BLOCK(A0) clear suspend bit  *       SUBQ   =1,DPC         mark dispatcher call  *       MOVEM.L (A7)+,D0-D2/A0-A2/A5 recover regs   *       MOVE   (A7)+,IID      recover old IID       *       JMP    DPCJ           call dispatcher       **--------------------------------------------------**      provide malfunction exit                    *IRMAL: LEA    IRBUF,A2       get addr of IR buffer *       MOVEA.L PWSP(A2),A5   addr of proc workspace*       MOVEQ  =-2,D2         fatal IR routine error*       BRA.S  EX3            disable IR, disp. call*****************************************************       END    OF             JOY                   *****************************************************