        list    1
        page
ssbpiaorb       equ     $f765
ssbwdstatus     equ     $f76c
ssbwdcmd        equ     $f76c
ssbwdtrack      equ     $f76d
ssbwdsector     equ     $f76e
ssbwddata       equ     $f76f
*
fdunit            rmb   1              unit requested
fdlastunit        fcb   $FF            last unit selected
fdnumberofsectors rmb   1              number of sectors to read
fdreadcommand     rmb   1              read command
errsectoraddress  rmb   2              address of error sector var
*
err:argcount       equ  27
err:datalate       equ  100            i made this one up
err:devicetimedout equ  $412
err:diskread       equ  $415
err:diskwrite      equ  $416
err:diskseek       equ  $417
err:diskwrtprot    equ  $418
err:devicenotready equ  $424
*
arg1address     equ     4              arg on tos
arg2address     equ     10             arg on tos-1
arg3address     equ     16             arg on tos-2
arg4address     equ     22             arg on tos-3
        page
*
*       call fdselect(unit,side,density)
*
fdselect
        cmpa    #3                     right number of args?
        bne     wrongnumberofargs      b/ no
        ldu     arg3address,x          get address of unit number
        ldb     5,u                    get unit number
        stb     fdunit                 remember the unit number
        orb     #%10000000             set head load enable
        ldu     arg2address,x          get address of side
        lda     5,u                    get side
        beq     fdselect1              b/ side 0
        orb     #%00001000             select side 1
fdselect1
        ldu     arg1address,x          get address of density
        lda     5,u                    get density
        beq     fdselect2              b/ single density
        orb     #%01000000             select double density
fdselect2
        comb
        stb     ssbpiaorb              tell the hardware
        lda     fdunit                 same unit as last time?
        cmpa    fdlastunit
        beq     fdselect3              b/ yes
        eorb    #$80                   no, flog the head
        stb     ssbpiaorb
        eorb    #$80
        stb     ssbpiaorb
        sta     fdlastunit
fdselect3
        clc                            say 'no error'
        rts
*
*       call fdstepin(updatetrackregisterflag,steprate)
*
fdstepin
        cmpa    #2                     right number of args?
        bne     wrongnumberofargs      b/ no
        ldu     arg1address,x          get address of steprate
        lda     5,u                    get steprate
        anda    #%00000011             ensure good data
        ldu     arg2address,x          get address of update flag
        lda     5,u                    get update flag
        beq     fdstepin1              b/ no update
        ora     #%00010000             select update mode
fdstepin1
        ora     #%01001000             step in command
        pshs    cc                     save user's interrupt mask
        orcc    #$50                   disable firq and irq
        bsr     fdissuecmd             go do it
        bcs     fdrestore2             b/ error
        puls    cc                     turn the world on again
        bra     fdrestore1
*
wrongnumberofargs
        ldx     #err:argcount
        sec
        rts
*
*       call fdrestore(steprate)
*
fdrestore
        cmpa    #1                     right number of args?
        bne     wrongnumberofargs      b/ no
        ldu     arg1address,x          get address of steprate
        lda     5,u                    get steprate
        anda    #%00000011             ensure good data
        ora     #%00001000             restore command
        pshs    cc                     save user's interrupt mask
        orcc    #$50                   disable firq and irq
        bsr     fdissuecmd             go do it
        bcs     fdrestore2             b/ error
        puls    cc                     turn the world on again
        ldx     #err:diskseek
        bita    #%00000100             are we at track 0?
        beq     fdrestore3
fdrestore1
        ldx     #err:devicenotready
        bita    #%10000000
        bne     fdrestore3
        ldx     #err:diskseek
        bita    #%00011000
        bne     fdrestore3
        clc
        rts
fdrestore2
        puls    cc                     turn the world on again
fdrestore3
        sec
        rts
*
fdissuecmd
        ldb     ssbwdstatus            clear 1791 irq
        sta     ssbwdcmd               tell the hardware what to do
        ldx     #1802                  time out counter=6 sec
        bsr     fddelay
fdwaitdone
        lda     ssbwdstatus            done yet?
        bita    #1
        beq     fddone                 b/ it's done
        decb
        bne     fdwaitdone
        leax    -1,x
        bne     fdwaitdone
fdtimedout
        bsr     fdabort
        bsr     fddone
        ldx     #err:devicetimedout
        sec
        rts
*
fdabort lda     #%11010000             abort with no interrupts
        sta     ssbwdcmd
fddelay mul
        mul
        mul
        mul
        mul
        mul
        lda     ssbwdstatus
        rts
*
fddone  lda     ssbwdstatus            make 1791 int go away
        ldb     ssbpiaorb              make pia ints go away
        rts
*
*       call fdreadsectors(side,firstsector,numberofsectors,errorsector)
*
fdreadsectors
        cmpa    #4                     right number of args?
        bne     wrongnumberofargs      b/ no
        ldu     arg1address,x          get address of errorsector
        clr     0,u
        clr     4,u
        clr     5,u
        leau    5,u
        stu     errsectoraddress       remember this for later
        ldu     arg2address,x          get address of number of sectors
        lda     5,u                    get numberofsectors
        sta     fdnumberofsectors
        ldu     arg3address,x          get address of firstsector
        lda     5,u                    get firstsector
        sta     ssbwdsector
        ldu     arg4address,x          get address of side
        lda     5,u                    get side
        anda    #1                     ensure good data
        asla
        asla
        asla
        ora     #%10000010             add in the command bits
        sta     fdreadcommand
        pshs    cc                     save user's interrupt mask
        orcc    #$50                   disable firq and irq
fdreadsector1
        lda     fdreadcommand
        bsr     fdissuecmd             go do it
        bcs     fdreadsector3          b/ err
        bita    #%10011000             any errors?
        bne     fdreadsector2          b/ something is wrong
        inc     ssbwdsector
        dec     fdnumberofsectors      done?
        bne     fdreadsector1          b/ no
        puls    cc                     restore user's interrupt mask
        clc                            say 'no errors'
        rts
*
fdreadsector2
        ldb     ssbwdsector
        stb     [errsectoraddress]
        ldx     #err:devicenotready
        bita    #%10000000
        bne     fdreadsector3
        ldx     #err:diskread
fdreadsector3
        puls    cc                     restore user's interrupt mask
        sec
        rts
        if      0                      
ssbextstatus    equ     $f762
*
*       call fdwritetrack(trackbuffer$)
*
fdwritetrack
        cmpa    #1                     right number of args?
        bne     wrongnumberofargs      b/ no
        ldu     2,x                    get address of track buffer
        leau    4,u                    skip max and cur
        pshs    cc                     save int mask
        orcc    #$50                   disable firq and irq
        ldb     #%11110100             write track command
        lda     #$81                   bit mask for testing
        stb     ssbwdcmd
        bra     fdwritetrack2
fdwritetrack1
        stb     ssbwddata
fdwritetrack2
        ldb     ,u+
fdwritetrack3
        bita    ssbextstatus
        bmi     fdwritetrack1          b/ drq
        beq     fdwritetrack3          b/ not drq and not done
        bsr     fddone                 done
        fin
*
*       call fdwritetrack(trackbuffer$)
*
fdwritetimedout
        bsr     fdtimedout
fdwritetimedout1
        puls    cc,dp
        sec
        rts
*
fdwritetrack
        cmpa    #1                     right number of args?
        bne     wrongnumberofargs      b/ no
        ldu     2,x                    get address of track buffer
        leau    4,u                    skip max and cur
        pshs    cc,dp                  save int mask
        orcc    #$50                   disable firq and irq
        jsr     fdabort
        ldx     #err:diskwrtprot
        bita    #%01000000
        bne     fdwritetimedout1
        bita    #%00100000             check head loaded
        bne     fdwritetrack0          b/ it is
        lda     ssbwdtrack             seek to same track to load the heads
        sta     ssbwddata
        lda     #%00011000
        bsr     fdissuecmd             go do it
        bcs     fdwritetimedout1       b/ error
fdwritetrack0
        ldx     #0
        lda     #$f7
        tfr     a,dp
        setdpr  $f700
        ldb     #%11110100             write track command
        lda     #%00000011             drq + busy
        stb     ssbwdcmd
        ldb     ,u+
fdwritetrack1
        cmpa    ssbwdstatus
        beq     fdwritetrack2          b/ ready for first byte
        cmpa    ssbwdstatus
        beq     fdwritetrack2          b/ ready for first byte
        dex
        bne     fdwritetrack1
        bra     fdwritetimedout
fdwritetrack2
        stb     ssbwddata
        ldb     ,u+
fdwritetrack3
        cmpa    ssbwdstatus
        if      0
        beq     fdwritetrack4          b/ ready for second byte
        cmpa    ssbwdstatus
        beq     fdwritetrack4          b/ ready for second byte
        dex
        bne     fdwritetrack3
        bra     fdwritetimedout
        else
        bne     fdwritetrack3
        fin
fdwritetrack4
        stb     ssbwddata              4~
        ldb     ,u+                    5~
        cmpa    ssbwdstatus            4~
        beq     fdwritetrack4          3~
        cmpa    ssbwdstatus            4~
        beq     fdwritetrack4          3~
        cmpa    ssbwdstatus            4~
        beq     fdwritetrack4          3~
        cmpa    ssbwdstatus            4~
        beq     fdwritetrack4          3~
        cmpa    ssbwdstatus            4~
        beq     fdwritetrack4          3~
        cmpa    ssbwdstatus            4~
        beq     fdwritetrack4          3~
        cmpa    ssbwdstatus            4~
        beq     fdwritetrack4          3~
        cmpa    ssbwdstatus            4~
        beq     fdwritetrack4          3~
        cmpa    ssbwdstatus            4~
        beq     fdwritetrack4          3~
        cmpa    ssbwdstatus            4~
        beq     fdwritetrack4          3~
        cmpa    ssbwdstatus            4~
        beq     fdwritetrack4          3~
        cmpa    ssbwdstatus            4~
        beq     fdwritetrack4          3~
        cmpa    ssbwdstatus            4~
        beq     fdwritetrack4          3~
        cmpa    ssbwdstatus            4~
        beq     fdwritetrack4          3~
        cmpa    ssbwdstatus            4~
        beq     fdwritetrack4          3~
        cmpa    ssbwdstatus            4~
        beq     fdwritetrack4          3~
        cmpa    ssbwdstatus            4~
        beq     fdwritetrack4          3~
        cmpa    ssbwdstatus            4~
        beq     fdwritetrack4          3~
        cmpa    ssbwdstatus            4~
        beq     fdwritetrack4          3~
        cmpa    ssbwdstatus            4~
        beq     fdwritetrack4          3~
        cmpa    ssbwdstatus            4~
        beq     fdwritetrack4          3~
        cmpa    ssbwdstatus            4~
        beq     fdwritetrack4          3~
        cmpa    ssbwdstatus            4~
        beq     fdwritetrack4          3~
        cmpa    ssbwdstatus            4~
        beq     fdwritetrack4          3~
        cmpa    ssbwdstatus            4~
        beq     fdwritetrack4          3~
        cmpa    ssbwdstatus            4~
        beq     fdwritetrack4          3~
        cmpa    ssbwdstatus            4~
        beq     fdwritetrack4          3~
        cmpa    ssbwdstatus            4~
        beq     fdwritetrack4          3~
        cmpa    ssbwdstatus            4~
        beq     fdwritetrack4          3~
        cmpa    ssbwdstatus            4~
        beq     fdwritetrack4          3~
        cmpa    ssbwdstatus            4~
        beq     fdwritetrack4          3~
        cmpa    ssbwdstatus            4~
        beq     fdwritetrack4          3~
        cmpa    ssbwdstatus            4~
        beq     fdwritetrack4          3~
        cmpa    ssbwdstatus            4~
        beq     fdwritetrack4          3~
        cmpa    ssbwdstatus            4~
        beq     fdwritetrack4          3~
*
        bsr     fddone                 check done and make ints go away
        bita    #1
        bne     fdwritetimedout
        puls    cc,dp                  turn on the world
        ldx     #err:devicenotready
        bita    #%10000000
        bne     fdwritetrack5
        ldx     #err:diskwrtprot
        bita    #%01000000
        bne     fdwritetrack5
        ldx     #err:diskwrite
        bita    #%00100000
        bne     fdwritetrack5
        ldx     #err:datalate
        bita    #%00000100
        bne     fdwritetrack5
        clc
        rts
fdwritetrack5
        puls    cc,dp                  restore user's int mask
        sec
        rts

        end     .progstart
