* loader.js
*
* written : 7.97 by 42Bastian Schick (elw5basc@gp.fht-esslingen.de)
*
* This little routine loads data via the joyport.
* Input : Destination (long)
*         Length in bytes (long)
*         Data (long)
* Output: Data stored from Destination ...
*
* Note : BUSY is high active , /STROBE is low-active.
*        Like your printer wants it ;-)
*

dest_ptr        REG 20
GETLONG         REG 21
checksum        REG 22
counter         REG 23
CLUT0           REG 24
RETURN          REG 25
help_ptr        REG 26
Magic           REG 27

GPU             EQU 1

                INCLUDE "e:\bjl\js\macro\help.mac"

                RUN $f03000

start           movei #GetLongFromSTE,GETLONG
                moveq #0,checksum
                moveq #0,counter
                movei #$f00400,CLUT0
                movei #$008800ff,r0
                store r0,(CLUT0)

                movei #.cont0,RETURN
                moveq #0,r0                     ; init r0 to get FALSE
                movei #$22071970,Magic

.cont0          cmp r0,Magic                    ; magic ??
                jump nz,(GETLONG)               ; no, fetch next long
                nop

                movei #.cont1,RETURN
                jump (GETLONG)                  ; get start
                moveq #0,help_ptr

.cont1          jump z,(GETLONG)                ; again , if timeout
                store r0,(help_ptr)             ; save start for 68k-routine

                movei #.cont2,RETURN
                jump (GETLONG)                  ; get length in bytes
                move r0,dest_ptr                ; destination = start address

.cont2          jump z,(GETLONG)                ; again, if timeout
                move r0,counter

                movei #.return,RETURN
                jump (GETLONG)                  ; get first data-long
                moveq #0,checksum               ; and clear checksum

.return         store r0,(CLUT0)                ; some feedback
                add r0,checksum                 ; a simple checksum
                subq #4,counter                 ; dec counter
                store r0,(dest_ptr)             ; save long
                jump nz,(GETLONG)               ; get new long and loop
                addqt #4,dest_ptr               ; inc ptr

                cmpq #0,checksum                ; sum must be zero
                movei #start,r0
                jump nz,(r0)                    ; if not => restart
                nop

                STOP_GPU                        ; stop => control to 68k
**********************
*** GetLongFromSTE ***
Value           REG 0
Joystick        REG 1
BusyHigh        REG 2
BusyLow         REG 3
Counter         REG 4
LOOP            REG 5
ReadValue       REG 6
WCounter        REG 7
TIMEOUT         REG 8
dummy           REG 9
TimeOutCnt      REG 10
help1           REG 12
help2           REG 13

GetLongFromSTE::

                movei #$f14000,Joystick
                movei #$81f0,BusyHigh

                movei #TimeOut,TIMEOUT

                moveq #4,Counter               ; 4*8 = 32 bit
                move BusyHigh,BusyLow
                moveq #0,Value
                bclr #7,BusyLow                 ; = $8170
                movei #.loop,LOOP
                movei #$100,r9                  ; switch port to input

                movei #10000,TimeOutCnt
                storew BusyLow,(Joystick)       ; BUSY inactive
.loop
                subq #1,TimeOutCnt
.wait1          load (Joystick),ReadValue
                jump z,(TIMEOUT)
                btst #3,ReadValue
                jr nz,.wait1                     ; wait for /STROBE low
                subq #1,TimeOutCnt

                storew r9,(Joystick)            ; switch to input
                                                ; set also BUSY = high
; Note: This works only, because the input-lines are pulled-up to 5V.

                load (Joystick),r12             ; get data-bits 2..0

; bits in ReadValue
;     pos 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
;    data  7  6  5  4  x  x  x  x B  2   1  0  x  x  x  x  x x   x  x  x  x x x x x x x S 3 x x
; B = BUSY (output)  high-active
; S = /STROBE (input) low-active

                move ReadValue,r13
                shrq #2,ReadValue               ; bit 3     => 0
                shrq #28,r13                    ; bits 7..4 => 3..0
                shlq #31,ReadValue              ; bit 3     => 31
                shlq #31-22,r12                 ; bits 2..0 => 31..29
                shlq #4,r13                     ; bits 7..4 => 7..4
                shrq #28,ReadValue              ; bit 3     => 3
                or r13,Value                    ; value |= (7..4)
                shrq #31-2,r12                  ; bits 2..0 => 2..0
                or ReadValue,Value              ; value |= (3)
                or r12,Value                    ; value |= (2..0)


                subq #1,TimeOutCnt
.wait2          load (Joystick),ReadValue
                jump z,(TIMEOUT)
                btst #3,ReadValue
                jr z,.wait2                    ; wait for /STROBE high
                subq #1,TimeOutCnt

                subq #1,Counter
                storew BusyLow,(Joystick)
                jump nz,(LOOP)
                rorq #8,Value

                xor ReadValue,ReadValue
                storew BusyHigh,(Joystick)
                jump (r25)
                subq #1,ReadValue               ; clear Z-flag

TimeOut:        storew BusyHigh,(Joystick)
                jump (r25)
                xor ReadValue,ReadValue         ; set Z-flag

UNREG Value,Joystick,BusyHigh,BusyLow,Counter,LOOP,ReadValue,WCounter,dummy
UNREG TIMEOUT,TimeOutCnt

**********************
                END
