*********************
* EEPROM-Routinen   *
* aus ATARI-Bootrom *
*********************

* I2C-Bus-Adressen
* $F14000.w  - Bit 0 = Datenstrom vom EEPROM ( Hi-Bit zuerst)
* $F14800.w  - lesen - CLK - schreiben => Bit 0 ausgeben und CLK
* $F15000.w  - lesen CS
* EEPROM-Opcodes
eeREAD  EQU %110000000
eeWRITE EQU %101000000
eeERASE EQU %111000000
eeEWEN  EQU %100110000
eeEWDS  EQU %100000000
eeERAL  EQU %100100000
eeWRAL  EQU %100010000
eeCLK   EQU $0800
eeCS    EQU $1000
eeADR   EQU %111111
*************************
* ReadEEPROM(D1.w,D0.w) *
*************************
* IN : D0.w - Anzahl der Bytes
*      D1.w - Start-Adresse im EEPROM
ReadEEPROM:       move.w  d0,-(sp)
                  bsr.s   ReadWordEEPROM
                  move.w  d0,(a0)+
                  addq.w  #1,d1
                  subq.w  #2,(sp)
                  bpl.s   ReadEEPROM+2
                  addq.l  #2,sp
                  rts
*************************
*      ClearEEPROM      *
*************************
ClearEEPROM:      movem.l d0/a0,-(sp)
                  lea     $F14000,a0
                  tst.w   eeCS(a0)
                  move.w  #eeEWEN,d0
                  bsr     SendEEOpCode
                  tst.w   eeCS(a0)
                  move.w  #eeERAL,d0
                  bsr     SendEEOpCode
                  tst.w   eeCS(a0)
                  move.w  #eeEWDS,d0
                  bsr     SendEEOpCode
                  movem.l (sp)+,d0/a0
                  rts
*************************
* WriteEEPROM(D1.w,D0.w *
*************************
* IN : D0.w - Anzahl der Bytes
*      D1.w - Start-Adresse im EEPROM
* OUT: D4.w < 0 => Fehler
WriteEEPROM:      move.w  d0,-(sp)
                  move.w  (a0)+,d0
                  bsr.s   WriteWordEEPROM
                  bmi.s   exit_WE
                  addq.w  #1,d1
                  subq.w  #2,(sp)
                  bgt.s   WriteEEPROM+2
exit_WE:          addq.l  #2,sp
                  tst.w   d4
                  rts
***************************
* D0=ReadWordEEPROM(D1.w) *
***************************
ReadWordEEPROM:   movem.l d1-d3/a0,-(sp)
                  lea     $F14000,a0
                  tst.w   eeCS(a0)
                  andi.w  #%111111,d1      ; Adress-Bits maskieren
                  ori.w   #eeREAD,d1
                  move.w  d1,d2
                  bsr     SendEEOpCode
                  moveq   #0,d0
                  moveq   #$0F,d3
loop_RWE:         tst.w   eeCLK(a0)
                  nop
                  move.w  (a0),d1
                  lsr.w   #1,d1
                  addx.w  d0,d0
                  nop                      ; warten
                  nop                      ; ...
                  nop
                  nop
                  nop
                  nop
                  dbra    d3,loop_RWE
                  movem.l (sp)+,d1-d3/a0
                  rts
******************************
* WriteWordEEPROM(D1.w,D0.w) *
******************************
WriteWordEEPROM:  movem.l d0-d3/a0,-(sp)
                  lea     $F14000,a0
                  tst.w   eeCS(a0)
                  move.w  #eeEWEN,d2       ;
                  bsr.s   SendEEOpCode
                  tst.w   eeCS(a0)
                  andi.w  #$3F,d1
                  ori.w   #eeWRITE,d1
                  move.w  d1,d2
                  bsr.s   SendEEOpCode
                  move.w  d0,d2
                  bsr.s   SendEEWord       ; Wert senden
                  tst.w   eeCS(a0)
                  nop
                  nop
                  move.w  #1,d2
                  move.w  #$7FFF,d4
wait_WWE:         move.w  (a0),d3
                  and.w   d2,d3
                  bne.s   ok_WWE
                  dbra    d4,wait_WWE
ok_WWE:           move.w  #eeEWDS,d2
                  bsr.s   SendEEOpCode
                  tst.w   eeCS(a0)
                  movem.l (sp)+,d0-d3/a0
                  tst.w   d4
                  rts
*************************
* SendXBit2EEPROM(d2.w) *
*************************
SendEEWord:       rol.w   #1,d2
                  moveq   #$0F,d3
                  bra.s   loop_SAE
SendEEOpCode:     rol.w   #8,d2
                  moveq   #8,d3
loop_SAE:         move.w  d2,eeCLK(a0)
                  nop
                  nop
                  nop
                  nop
                  nop
                  nop
                  rol.w   #1,d2
                  dbra    d3,loop_SAE
                  rts

