* Routinen um vom STE/Falcon ber die JoyPad-Ports ein Programm
* an den Jaguar zu schicken
*
* (c) 1994 Bastian Schick
* Version 4  -  29.5.95


DestAdr           EQU $4000

                  >PART 'Start'
                  pea     doit(pc)
                  move.w  #38,-(sp)
                  trap    #14
                  addq.l  #6,sp
                  clr.w   -(sp)
                  trap    #1


doit:             move.l  $04BA.w,-(sp)
                  sf      $FFFF9203.w
                  lea     jag_prg(pc),a0
                  lea     DestAdr.w,a1
                  move.l  #jag_end-jag_prg,d0
                  bsr.s   SendPRG2Jaggy
                  move.l  $04BA.w,d7
                  sub.l   (sp)+,d7
                  trap    #1
                  rts
                  ENDPART
                  >PART 'SendPRG2Jaggy'
SendPRG2Jaggy:    lea     jag_prg(pc),a0
                  move.l  #(jag_end-jag_prg)>>2,d2
                  move.l  #DestAdr,d1
                  bsr     WriteDumpL
                  beq.s   error_sp
                  move.w  #StartSub,d0
                  bsr.s   SendWord_STE
                  beq.s   error_sp
                  move.l  #DestAdr,d0
                  bsr     SendLong_STE
error_sp:         rts
                  ENDPART
                  >PART 'Print'
Print:            movem.l d0-d2/a0-a2,-(sp)
                  move.l  7*4(sp),-(sp)
                  move.w  #9,-(sp)
                  trap    #1
                  addq.l  #6,sp
                  movem.l (sp)+,d0-d2/a0-a2
                  move.l  (sp)+,(sp)
                  rts
                  ENDPART
*************************
* transmission-routines *
*************************
StartSub          EQU $83
WriteLongs        EQU $88
FirstTimeOutInit  EQU 120
TimeOutInit       EQU 70

SendRegs          REG d1-d3/d6-a2
                  >PART 'SendWord_STE'
SendWord_STE:     movem.l SendRegs,-(sp)
                  lea     $04BA.w,a2
                  moveq   #FirstTimeOutInit,d7
                  add.l   (a2),d7
                  lea     $FFFF9201,a0

SendWord_STE2:    btst    #3,(a0)
                  bne.s   SendWord_STE3
                  cmp.l   (a2),d7
                  bhi.s   SendWord_STE2
                  moveq   #0,d0
                  movem.l (sp)+,SendRegs
                  rts

SendWord_STE3:    lea     2(a0),a1
                  rol.w   #8,d0
                  moveq   #$10,d2
                  moveq   #3,d3
                  moveq   #7,d6
SendWord_STE4:    moveq   #$C0,d1
                  and.w   d0,d1
                  rol.w   #2,d0
                  or.b    d2,d1

                  moveq   #TimeOutInit,d7
                  add.l   (a2),d7
SendWord_STE5:    btst    #3,(a0)
                  bne.s   SendWord_STE6    ; auf BUSY high warten
                  cmp.l   (a2),d7
                  bhi.s   SendWord_STE5
                  bra     TimeOut2

SendWord_STE6:    move.b  d1,(a1)          ; Bit mit STROBE
                  moveq   #TimeOutInit,d7
                  add.l   (a2),d7
SendWord_STE7:    btst    #3,(a0)
                  beq.s   SendWord_STE8    ; auf BUSY low warten
                  cmp.l   (a2),d7
                  bhi.s   SendWord_STE7
                  bra     TimeOut2
SendWord_STE8:    clr.b   (a1)             ; STROBE low

                  dbra    d6,SendWord_STE4
                  moveq   #-1,d0
                  movem.l (sp)+,SendRegs
                  rts
                  ENDPART
                  >PART 'SendLong_STE'
SendLong_STE:     movem.l SendRegs,-(sp)
                  lea     $FFFF9201,a0
                  lea     2(a0),a1
                  lea     $04BA.w,a2
                  moveq   #FirstTimeOutInit,d7
                  add.l   (a2),d7

SendLong_STE1:    btst    #3,(a0)
                  bne.s   SendLong_STE2    ; auf BUSY high warten
                  cmp.l   (a2),d7
                  bhi.s   SendLong_STE1
                  moveq   #0,d0
                  movem.l (sp)+,SendRegs
                  rts

SendLong_STE2:    rol.l   #3,d0
                  moveq   #$10,d2
                  moveq   #3,d3
                  moveq   #9,d6            ; 10*3 Bit
SendLong_STE3:    moveq   #$E0,d1
                  and.w   d0,d1
                  rol.l   #3,d0
                  or.b    d2,d1

                  moveq   #TimeOutInit,d7
                  add.l   (a2),d7
SendLong_STE4:    btst    #3,(a0)
                  bne.s   SendLong_STE5    ; auf BUSY high warten
                  cmp.l   (a2),d7
                  bhi.s   SendLong_STE4
                  bra     TimeOut2
SendLong_STE5:    move.b  d1,(a1)          ; Bit mit STROBE
                  moveq   #TimeOutInit,d7
                  add.l   (a2),d7
SendLong_STE6:    btst    d3,(a0)
                  beq.s   SendLong_STE7
                  cmp.l   (a2),d7
                  bhi.s   SendLong_STE6
                  bra     TimeOut2         ; auf Busy low warten
SendLong_STE7:    sf      (a1)             ; STROBE low
                  dbra    d6,SendLong_STE3

                  moveq   #$C0,d1
                  and.w   d0,d1
                  or.b    d2,d1

                  moveq   #TimeOutInit,d7
                  add.l   (a2),d7
SendLong_STE8:    btst    #3,(a0)
                  bne.s   SendLong_STE9    ; auf BUSY high warten
                  cmp.l   (a2),d7
                  bhi.s   SendLong_STE8
                  bra     TimeOut2
SendLong_STE9:    move.b  d1,(a1)          ; Bit mit STROBE
                  moveq   #TimeOutInit,d7
                  add.l   (a2),d7
SendLong_STE10:   btst    d3,(a0)
                  beq.s   SendLong_STE11
                  cmp.l   (a2),d7
                  bhi.s   SendLong_STE10
                  bra     TimeOut2         ; auf Busy low warten
SendLong_STE11:   sf      (a1)             ; STROBE low

                  moveq   #-1,d0
                  movem.l (sp)+,SendRegs
                  rts
                  ENDPART
                  >PART 'GetWord_STE'
GetWord_STE:      movem.l SendRegs,-(sp)
                  moveq   #FirstTimeOutInit,d7
                  add.l   $04BA.w,d7
                  lea     $FFFF9201,a0
GetWord_STE1:     btst    #3,(a0)
                  beq.s   GetWord_STE2
                  cmp.l   $04BA.w,d7
                  bhi.s   GetWord_STE1

                  moveq   #0,d0
                  movem.l (sp)+,SendRegs
                  rts

GetWord_STE2:     lea     2(a0),a1
                  moveq   #0,d0
                  moveq   #0,d2

                  moveq   #7,d6
GetWord_STE3:     st      (a1)             ; /Busy high
                  bsr     _WaitStrobeHigh
                  move.b  (a1),d1
                  sf      (a1)             ; /Busy low
                  add.b   d1,d1
                  roxl.w  #1,d0
                  add.b   d1,d1
                  roxl.w  #1,d0
                  bsr     _WaitStrobeLow
                  dbra    d6,GetWord_STE3
                  moveq   #-1,d1
                  movem.l (sp)+,SendRegs
                  rts
                  ENDPART
                  >PART 'GetLong_STE'
GetLong_STE:      movem.l SendRegs,-(sp)
                  lea     $04BA.w,a2
                  moveq   #20,d7
                  add.l   (a2),d7
                  lea     $FFFF9201,a0
                  sf      2(a0)
GetLong_STE1:     btst    #3,(a0)
                  beq.s   GetLong_STE2
                  cmp.l   (a2),d7
                  bhi.s   GetLong_STE1
                  sf      2(a0)
                  moveq   #0,d0
                  movem.l (sp)+,SendRegs
                  rts

GetLong_STE2:     lea     2(a0),a1
                  moveq   #0,d0
                  moveq   #0,d2
                  moveq   #9,d6
GetLong_STE3:     st      (a1)             ; Busy high
                  moveq   #TimeOutInit,d7
                  add.l   (a2),d7
GetLong_STE6:     btst    #3,(a0)
                  bne.s   GetLong_STE7
                  cmp.l   (a2),d7
                  bhi.s   GetLong_STE6
                  bra.s   TimeOut2
GetLong_STE7:     moveq   #$E0,d1
                  and.b   (a1),d1
                  sf      (a1)             ; Busy low
                  rol.l   #3,d0
                  or.b    d1,d0

                  moveq   #TimeOutInit,d7
                  add.l   (a2),d7
GetLong_STE8:     btst    #3,(a0)
                  beq.s   GetLong_STE9
                  cmp.l   (a2),d7
                  bhi.s   GetLong_STE8
                  bra.s   TimeOut2
GetLong_STE9:     dbra    d6,GetLong_STE3

                  st      (a1)
                  moveq   #TimeOutInit,d7
                  add.l   (a2),d7
GetLong_STE10:    btst    #3,(a0)
                  bne.s   GetLong_STE11
                  cmp.l   (a2),d7
                  bhi.s   GetLong_STE10
                  bra.s   TimeOut2

GetLong_STE11:    moveq   #$C0,d1
                  and.b   (a1),d1
                  sf      (a1)             ; Busy low
                  rol.l   #3,d0
                  or.b    d1,d0
                  rol.l   #1,d0

                  moveq   #TimeOutInit,d7
                  add.l   (a2),d7
GetLong_STE12:    btst    #3,(a0)
                  beq.s   GetLong_STE13
                  cmp.l   (a2),d7
                  bhi.s   GetLong_STE12
                  bra.s   TimeOut2
GetLong_STE13:    moveq   #-1,d1
                  movem.l (sp)+,SendRegs
                  rts
                  ENDPART
                  >PART '_WaitBusyHigh'
_WaitStrobeHigh:  moveq   #60,d7
                  add.l   $04BA.w,d7
_wait0_sw:        btst    #3,(a0)          ; 12
                  bne.s   _ok_wbh          ;  8    auf BUSY high warten
                  cmp.l   $04BA.w,d7
                  bhi.s   _wait0_sw
                  bra.s   TimeOut
_ok_wbh:          rts
                  ENDPART
                  >PART '_WaitBusyLow'
_WaitStrobeLow:   moveq   #60,d7
                  add.l   $04BA.w,d7
_wait_bl:         btst    #3,(a0)          ; 12
                  beq.s   _ok_wbl          ;  8    auf BUSY high warten
                  cmp.l   $04BA.w,d7
                  bhi.s   _wait_bl
                  ENDPART
                  >PART 'TimeOut'
TimeOut:          addq.l  #4,sp
TimeOut2:         movem.l (sp)+,d1-d3/d6-a1
                  sf      $FFFF9203.w
                  pea     timeout(pc)
                  bsr     Print
                  moveq   #0,d0
_ok_wbl:          rts
timeout:          DC.B "TimeOut",13,10,0
                  EVEN
                  ENDPART
                  >PART 'WriteDumpL(a0.l,d1.l,d2.l)'
WriteDumpL:       movem.l d0-d2/a0-a2,-(sp)
                  sf      $FFFF9203.w

again_wdl:        move.w  #WriteLongs,d0
                  bsr     SendWord_STE     ; Commando
                  beq.s   exit_wdl

                  move.l  d1,d0
                  bsr     SendLong_STE     ; Start-Adress
                  beq.s   exit_wdl

                  move.l  d2,d0
                  bsr     SendLong_STE     ; Anzahl der Lang-Worte
                  beq.s   exit_wdl

                  sf      $FFFF9203.w

wait_wdl:         bsr     GetWord_STE
                  beq.s   exit_wdl1
                  cmp.w   #WriteLongs,d0
                  bne.s   exit_wdl

                  moveq   #0,d3
loop_wdl:         move.l  (a0)+,d0
                  move.l  d0,d1

                  eor.l   d3,d1
                  add.l   d1,d3

                  bsr     SendLong_STE
                  beq.s   exit_wdl

                  dbra    d2,loop_wdl
                  sub.l   #$010000,d2
                  bpl.s   loop_wdl
                  bsr     GetLong_STE
                  cmp.l   d0,d3
                  bne.s   error_wdl

                  moveq   #-1,d0
                  movem.l (sp)+,d0-d2/a0-a2
                  rts
exit_wdl1:        pea     timeout1(pc)
                  bra.s   cont_wdl

exit_wdl:         pea     timeout(pc)
                  bra.s   cont_wdl
error_wdl:        pea     WriteDumpErr(pc)
cont_wdl:         bsr     Print
                  moveq   #0,d0
                  movem.l (sp)+,d0-d2/a0-a2
                  rts
timeout1:         DC.B "WriteDumpL-TimeOut",13,10,0
WriteDumpErr:     DC.B "Error in transmission !",13,10,0
                  EVEN

                  ENDPART
*************************
jag_prg:
