; Uploaded to simtel-20 by Ralph Hyre (ralphw@c.cs.cmu.edu)
; Sent to Ralph by Chris Peck (chris@bingvaxb.bitnet)
; You will need one of the follwing items to use these drivers:
;	the PCPI OEM package (bucks involved - order from PCPI)
;	the assembled output of the PCPI OEM package assembler.
;	(this will be made available here as soon as I can assemble it)

        .WIDTH  96
;******************************
;FILE:  SVAZVX4.A65
;PURP:  SVA ZVX4 DRIVER
;       THIS DRIVER SHOWS HOW MULTIPLE DENSITIES MAY BE USED. NOTE THAT
;       THERE MUST BE SOME WAY OF DETERMINING THE DENSITY AT RUN TIME. IN
;       THE ZVX4 CONTROLER THE SVATYPEDISK IS USED.
;
;CHANGES:
;       5/11/83 (WLS)
;               ADDED   CODE IN THE FORMAT COMMAND TO ISOLATE THE DENSTIY
;                       AND DRIVE NUMBER
;
;       9/1/82  (WLS)
;               ADDED   SNDNAME COMMAND
;
;       8/9/82  (WLS)
;               CHANGED SO THAT DOUBLE SIDED DOUBLE DENSITY HAS 128 DIRECTORY
;                       ENTRIES AND DEFINED AS SUPPORTING 4 DRIVES
;
;       8/3/82  (WLS)
;               FIXED   BUG IN SET SECTOR FOR DOUBLE SIDED SUPPORT
;
;       8/1/82  (WLS)
;               CHANGED SVADVR FOR ZVX4 MULTIPLE DENSITY
;
;       7/15/82 (WLS)
;               ADDED   VERSION NUMBER, NAME
;                       HOST BUFFER SIZE, ALLOCATION VECTOR SIZE, CHECK VECTOR
;                       SIZE
;
;       6/16/82 (WLS)
;               ADDED   READING OF DRIVE AND TRACK IN FORMAT COMMAND
;
;       5/28/82 (WLS)
;               ADDED   SNDPRMCMD
;
;       5/19/82 (WLS)
;               ADDED   POLLROUTINE TO HEADER
;
;       4/30/82 (WLS)
;               CHANGED TO DRIVER TYPE FOR DOWNLOADING
;
;       4/28/82 (WLS)
;               ADDED   CODE TO SUPPORT BLOCK DEVICE TABLES
;
;       2/25/82 (WLS)
;               ADDED   CODE TO VERIFY THAT THE BOARD IS THERE BEFORE
;                       CALLING IT
;
;       2/24/82 (WLS)
;               ADDED   QUERY TO GET THE FIRST DISK NUMBER
;
;       1/7/82 (WLS)
;               MADE    APPLE DRIVES DRIVE 0,1 AND THE SVA DRIVES 2,3
;
;       11/16/81 (WLS)
;               CREATED
;*******************************

BASEP0  .QUERY  "ENTER BASE OF PAGE 0: "
PAGE0W0 .EQU    BASEP0
PAGE0W1 .EQU    BASEP0+2

;EQUATES
;       .NOLIST
        .INCLUDE        B:DRVREQUS.A65
        .LIST


;SVA EQUATES
SVAFDSK         .EQU    6       ;DEFAULT FIRST DISK IS G
SVASETTRK       .EQU    0C800H
SVASETSEC       .EQU    0C803H
SVASETADR       .EQU    0C806H
SVASELDSK       .EQU    0C809H
SVARD0          .EQU    0C80CH  ;READ SIDE 0
SVAWR0          .EQU    0C80FH  ;WRITE SIDE 0
SVAINIT         .EQU    0C812H
SVASETSDEN      .EQU    0C81EH
SVASETDDEN      .EQU    0C821H
SVARD1          .EQU    0C833H  ;READ SIDE 1
SVAWR1          .EQU    0C836H  ;WRITE SIDE 1
SVADRVINIT      .EQU    0C83CH  ;INITIALIZE THE CURRENT DRIVE
SVATYPEDISK     .EQU    0C83FH

;HEADER
BEGSVA:
        .WORD   0               ;LOAD ADDRESS (0=RELOCATE)
        .WORD   ((ENDSVA-BEGSVA)+0FFH) AND 0FF00H       ;LENGTH
        .BYTE   4               ;LENGTH OF PAGE 0 DATA
        .BYTE   0               ;TAB FIELD (RESERVED FOR FUTURE USE MUST BE 0)
FDISK:  .WORD   SVAFDSK         ;FIRST DISK
        .WORD   4               ;DEFINE 4 DRIVES
        .WORD   ISVA8F
        .WORD   RSVA8F
        .WORD   WSVA8F
        .WORD   OSVA8F
        .WORD   PSVA8F          ;POLL ROUTINE
        .WORD   3               ;VERSION NUMBER
NAME:   .BYTE   8,"SVA ZVX4",0,0,0,0,0,0,0 ;NAME

        ;BUFFER SIZE, CHECK SIZE AND ALLOCATION SIZE OF EACH DRIVE DEFINED
        .WORD   256             ;HOST BUFFER SIZE
        .WORD   32              ;CHECK VECTOR SIZE
        .WORD   61              ;ALLOCATION VECTOR SIZE
        .WORD   256             ;HOST BUFFER SIZE
        .WORD   32              ;CHECK VECTOR SIZE
        .WORD   61              ;ALLOCATION VECTOR SIZE
        .WORD   256             ;HOST BUFFER SIZE
        .WORD   32              ;CHECK VECTOR SIZE
        .WORD   61              ;ALLOCATION VECTOR SIZE
        .WORD   256             ;HOST BUFFER SIZE
        .WORD   32              ;CHECK VECTOR SIZE
        .WORD   61              ;ALLOCATION VECTOR SIZE

;******************************
;ROUTINE: ISVA8F,RSVA8F,WSVA8F,OSVA8F
;PURP:  HANDLE THE 4 ENTRY POINTS FOR BLOCK DEVICES
;ENTRY: A = HIGH BYTE OF PARAMETERS
;       Y = LOW BYTE OF PARAMETERS
;EXIT:  IF NO ERRORS THEN
;         A = 0
;       ELSE
;         A = 1
;USED:  ALL
;******************************

        ;INITIALIZE
ISVA8F:
        LDA     #0
        STA     TYPEDISK
        STA     CURDISK
        JSR     ISSVATHERE      ;CHECK FOR SVA CARD
        BCS     $1              ;EXIT IF ERROR IN SETUP
        JSR     SVAINIT
$1:     JMP     EXIT

        ;READ A SECTOR
RSVA8F:
        JSR     SETUP
        BCS     $0              ;EXIT IF ERROR IN SETUP
        LDA     CURSIDE
        BNE     $1
        JSR     SVARD0          ;SIDE 0 READ
$0:     JMP     EXIT
$1:
        JSR     SVARD1          ;SIDE 1 READ
        JMP     EXIT

        ;WRITE A SECTOR
WSVA8F:
        JSR     SETUP
        BCS     $0              ;EXIT IF ERROR IN SETUP
        LDA     CURSIDE
        BNE     $1
        JSR     SVAWR0          ;SIDE 0 WRITE
$0:     JMP     EXIT
$1:
        JSR     SVAWR1          ;SIDE 1 WRITE
        JMP     EXIT

        ;OTHER COMMANDS
OSVA8F:
        CMP     #SNDPRMCMD      ;IS THIS THE SEND PARAMETERS COMMAND
        BNE     CHKFRMT         ;BIF NOT SEND PARMATERS

        ;SEND THE HOST AND DISK PARAMETERS
        LDA     #0
        STA     ERRBYTE         ;ASSUME NO ERRORS
        JSR     RD1Z80BYTE      ;GET DRIVE NUMBER
        STA     DRNUM           ;SAVE DRIVE NUMBER
        LDA     ADRDMYPARM+1
        LDY     ADRDMYPARM
        JSR     SETUP           ;SETUP FOR DISK TYPING
        BCS     $0              ;BIF ERROR
        JSR     SVATYPEDISK     ;GET THE TYPE OF DISK
                                ; 0 = SDSS, 1=DDSS, 2=SDDD, 3=DDDS
        CMP     #4
        BCC     $1              ;BIF 0..4 (I.E. IT'S OK)
$0:     LDA     #0FFH
        STA     ERRBYTE         ;SET ERROR BYTE
        LDA     #0              ;ELSE ASSUME SDSS
$1:     LDY     CURDISK
        STA     TYPEDISK,Y      ;SET TYPE DISK
        ASL     A               ;MULTIPLY BY 2
        TAY
        LDA     ADRPARMS,Y
        STA     PAGE0W0
        LDA     ADRPARMS+1,Y
        STA     PAGE0W0+1
        LDY     #0
        STY     IDX
$SNDPLP:
        LDA     (PAGE0W0),Y
        JSR     WR1Z80BYTE      ;SEND THE NEXT BYTE
        INC     IDX             ;INCREMENT TO NEXT BYTE
        LDY     IDX
        CPY     #SZPARMS        ;ARE WE DONE ?
        BNE     $SNDPLP         ;BIF NOT DONE

        ;EXIT WITH CARRY CLEAR IF ERRBYTE = 0 ELSE CARRY SET TO
        ;INDICATE AN ERROR
        LDA     ERRBYTE
        CLC
        BEQ     EXIT            ;BRANCH IF NO ERRORS
        SEC
        BCS     EXIT            ;ELSE ERROR EXIT


        ;FORMAT COMMAND
CHKFRMT:
        CMP     #FRMTCMD
        BNE     CHKNAME         ;ERROR IF NOT FORMAT COMMAND
        JSR     RD1Z80BYTE      ;GET DRIVE
        TAY
        AND     #0FH            ;ZERO THE UPPER NIBBLE
        STA     DRIVE           ;SAVE AS THE DRIVE
        TYA
        LSR     A               ;GET THE UPPER NIBBLE AS THE DENSITY
        LSR     A
        LSR     A
        LSR     A
        STA     DENSITY         ;SAVE THE DENSITY
        LDA     #0FFH
        SEC                     ;INDICATE AN ERROR (NO FORMTING)
        BCS     EXIT

        ;CHECK FOR SEND NAME COMMAND
CHKNAME:
        CMP     #SNDNAMECMD     ;SEND NAME COMMAND
        BNE     CHKOTHR         ;BIF NOT

        LDA     NAME            ;GET LENGTH
        STA     CNT             ;SAVE AS COUNT
        JSR     WR1Z80BYTE      ;SEND IT TO HOST
        LDA     #1
        STA     IDX
        LDA     CNT
        CLC
        BEQ     EXIT            ;EXIT WITH CARRY CLEAR IF NO NAME
                                ; THIS SHOULD NOT OCCUR

$LP:    LDX     IDX
        LDA     NAME,X          ;GET NEXT CHARACTER
        JSR     WR1Z80BYTE
        INC     IDX
        DEC     CNT
        BNE     $LP             ;CONTINUE UNTIL ALL BYTES ARE SENT
        CLC                     ;OK EXIT
        BCC     EXIT

CHKOTHR:
        SEC                     ;ERROR EXIT

        ;EXIT
EXIT:   BCS     ERRXIT
        LDA     #0              ;NO ERRORS
        RTS

ERRXIT:
        TAY
        BNE     RET             ;IF A <> 0 THEN RETURN
                                ; THE SUBROUTINES ERROR CODE
ERROR:
        LDA     #0FFH
RET:    RTS


PSVA8F:                         ;NO POLLROUTINE
        RTS

ADRPARMS:
        .WORD   SDSS            ;0 = SINGLE DENSITY SINGLE SIDED
        .WORD   DDSS            ;1 = DOUBLE DENSITY SINGLE SIDED
        .WORD   SDDS            ;2 = SINGLE DENSITY DOUBLE SIDED
        .WORD   DDDS            ;3 = DOUBLE DENSITY DOUBLE SIDED

PARMS:
        ;8 INCH SINGLE DENSITY SINGLE SIDED DISKS
        ;MHSTPARM       2048,128,52
SDSS:   .WORD   128             ;BYTES PER SECTOR
        .WORD   26              ;CPM RECORDS PER TRACK
        .BYTE   1               ;CPM RECORDS PER HOST BLOCK
        .BYTE   8               ;CPM RECORDS PER ALLOCATION BLOCK
        .BYTE   0               ;SECTOR MASK
        .BYTE   0               ;SECTOR SHIFT COUNT

        ;DISKDEF 3,0,26,0,1024,243,64,64,2
        .WORD   26              ;SECTORS PER TRACK
        .BYTE   3               ;BLOCK SHIFT FACTOR
        .BYTE   7               ;BLOCK MASK
        .BYTE   0               ;EXTENT MASK
        .WORD   242             ;NUMBER OF BLOCKS ON DISK - 1
        .WORD   63              ;NUMBER OF DIRECTORY ENTRIES - 1
        .BYTE   192             ;ALLOC0 (MASKS)
        .BYTE   0               ;ALLOC1
        .WORD   16              ;CHECK MASKS
        .WORD   2               ;OFFSET TO DIRECTORY TRACK

SZPARMS: .EQU   $-PARMS


        ;8 INCH SINGLE DENSITY DOUBLE SIDED DISKS
        ;MHSTPARM       2048,128,52
SDDS:   .WORD   128
        .WORD   52
        .BYTE   1
        .BYTE   16
        .BYTE   0
        .BYTE   0

        ;DISKDEF        3,0,51,0,2048,243,64,64,2,0
        .WORD   52              ;SEC PER TRACK
        .BYTE   4               ;BLOCK SHIFT
        .BYTE   15              ;BLOCK MASK
        .BYTE   0               ;EXTNT MASK
        .WORD   242             ;DISK SIZE-1
        .WORD   63              ;DIRECTORY MAX
        .BYTE   128             ;ALLOC0
        .BYTE   0               ;ALLOC1
        .WORD   16              ;CHECK SIZE
        .WORD   2               ;OFFSET


        ;8 INCH DOUBLE DENSITY SINGLE SIDED DISKS
        ;MHSTPARM       2048,256,26
DDSS:   .WORD   256
        .WORD   52
        .BYTE   2
        .BYTE   16
        .BYTE   1
        .BYTE   1

        ;SVA 8 INCH DOUBLE DENSITY SINGLE SIDED
        ;DISKDEF 4,0,25,0,2048,243,96,96,2,0
        .WORD   52              ;SEC PER TRACK
        .BYTE   4               ;BLOCK SHIFT
        .BYTE   15              ;BLOCK MASK
        .BYTE   0               ;EXTNT MASK
        .WORD   242             ;DISK SIZE-1
        .WORD   95              ;DIRECTORY MAX
        .BYTE   192             ;ALLOC0
        .BYTE   0               ;ALLOC1
        .WORD   24              ;CHECK SIZE
        .WORD   2               ;OFFSET

        ;8 INCH DOUBLE DENSITY DOUBLE SIDED DISKS
        ;MHSTPARM       2048,256,52
DDDS:   .WORD   256
        .WORD   104
        .BYTE   2
        .BYTE   16
        .BYTE   1
        .BYTE   1

        ;SVA 8 INCH DOUBLE DENSITY DOUBLE SIDED
        ;DISKDEF 5,0,103,0,2048,487,128,128,2
        .WORD   104             ;SEC PER TRACK
        .BYTE   4               ;BLOCK SHIFT
        .BYTE   15              ;BLOCK MASK
        .BYTE   0               ;EXTNT MASK
        .WORD   485             ;DISK SIZE-1
        .WORD   127             ;DIRECTORY MAX
        .BYTE   192             ;ALLOC0
        .BYTE   0               ;ALLOC1
        .WORD   32              ;CHECK SIZE
        .WORD   2               ;OFFSET


;******************************
;ROUTINE: SETUP
;PURP:  THE SVA FLOPPY DISK DRIVER ENTRY POINT
;ENTRY: A = HIGH BYTE OF PARAMETERS
;       Y = LOW BYTE OF PARAMETERS
;EXIT:  DRIVE, TRACK, AND SECTOR SETUP
;USED:  ALL
;******************************

SETUP:
        STA     PAGE0W0+1               ;SAVE PARAMETERS
        STY     PAGE0W0

        ;CALCULATE CURDISK
        LDY     #OCURDSK
        LDA     (PAGE0W0),Y     ;GET CURRENT DISK
        SEC
        SBC     FDISK           ;NORMALIZE TO 0
        STA     CURDISK         ;SAVE DISK NUMBER

        ;CHECK THAT THE CARDS THERE
SETUP1: JSR     ISSVATHERE
        BCC     SETUP2          ;BIF THERE
        RTS                     ;ELSE ERROR EXIT

        ;SET DISK
SETUP2:
        LDA     CURDISK
        JSR     SVASELDSK       ;SELECT THE DISK

        ;SET THE DENSITY
        LDX     CURDISK         ;GET DISK
        LDA     TYPEDISK,X      ;GET TYPE OF DISK
        STA     CURTYPEDISK     ;SAVE CUR TYPE DISK
        AND     #1
        BNE     SETUPDD         ;BIF DOUBLE DENSITY
        JSR     SVASETSDEN      ;IS SINGLE DENSITY
        JMP     SETUPSS
SETUPDD:
        JSR     SVASETDDEN      ;IS DOUBLE DENSTIY

        ;SET SECTOR AND SIDE
SETUPSS:
        LDX     #0              ;ASSUME SIDE 0
        LDY     #OCURSEC
        LDA     (PAGE0W0),Y     ;GET LOGICAL SECTOR
        CMP     #26
        BCC     $0              ;SIDE 0
        SEC
        SBC     #26             ;NORMALIZE TO 0
        CMP     #26
        BCC     $0A
        RTS                     ;RETURN WITH CY=1 (ERROR SECTOR TOO LARGE)

$0A:    LDX     #0FFH           ;SIDE 1
$0:     TAY                     ;LOGICAL SECTOR TO Y
        STX     CURSIDE         ;SAVE SIDE TO READ OR WRITE

        ;DECIDE WHICH TRANSLATION TABLE
        ; Y = LOGICAL SECTOR
        LDA     CURTYPEDISK
        BEQ     $1              ;IF SINGLE DENSITY SINGLE SIDED THEN
                                ; USE EVERY 7 AS DIGITAL RESEARCH SAYS
        LDA     #2              ; ELSE USE OTHER INTERLEAVE
$1:     TAX                     ;X = OFFSET TO WHICH TRANSLATION TABLE
        LDA     ADRTRANS,X
        STA     PAGE0W1
        LDA     ADRTRANS+1,X
        STA     PAGE0W1+1
        LDA     (PAGE0W1),Y     ;GET PHYSICAL SECTORS
        JSR     SVASETSEC       ;SET THE SECTOR

        ;SET THE TRACK
        LDY     #OCURTRK
        LDA     (PAGE0W0),Y
        JSR     SVASETTRK       ;SET THE TRACK

        ;SET THE DMA ADDRESS
        LDY     #OCURDMA+1
        LDA     (PAGE0W0),Y     ;GET HIGH BYTE
        TAX
        DEY
        LDA     (PAGE0W0),Y     ;GET LOW BYTE
        TAY
        TXA
        JSR     SVASETADR       ;SET THE DMA ADDRESS
        CLC
        RTS


;*************************************
;ROUTINE: ISSVATHERE
;ENTRY: NONE
;EXIT:  THE SVA CARD IS SLECTED IN SLOT 7
;       IF THERE
;         CY = 0
;       ELSE
;         CY = 1
;USED:  A,F
;**************************************

ISSVATHERE:
        BIT     0CFFFH          ;TURN OFF ALL ROMS
        BIT     0C700H          ;TURN ON SVA DISK CONTROLER
        LDA     0C800H
        CMP     #4CH            ;IS THERE A JUMP OPCODE AT C800H ?
        CLC                     ;ASSUME THERE IS
        BEQ     $1              ;BIF SO
        SEC                     ;ELSE IT'S NOT THERE
$1:     RTS


;TRANSLATION
IDX:    .BLOCK  1               ;TEMPORARY
CNT:    .BLOCK  1               ;TEMPORARY
DRIVE:  .BLOCK  1               ;TEMPORARY
DENSITY: .BLOCK 1               ;TEMPORARY
CURDISK: .BLOCK 1               ;CURRENT DISK NORMALIZED TO 0
CURSIDE: .BLOCK 1               ;CURRENT SIDE
CURTYPEDISK: .BLOCK 1           ;CURRENT TYPE DISK
ERRBYTE: .BLOCK 1               ;ERROR BYTE FOR SENDING PARAMETERS

        ;TYPE OF DISK
TYPEDISK:
        .BYTE   0
        .BYTE   0
        .BYTE   0
        .BYTE   0

        ;TRANSLATION TABLE
ADRTRANS:
        .WORD   SDTRANS
        .WORD   DDTRANS
SDTRANS:
        .BYTE   1,7,13,19,25,5,11,17,23,3,9,15,21
        .BYTE   2,8,14,20,26,6,12,18,24,4,10,16,22
DDTRANS:
        .BYTE   1,4,7,10,13,16,19,22,25,2,5,8,11
        .BYTE   14,17,20,23,26,3,6,9,12,15,18,21,24

        ;DUMMY PARAMETER BLOCK FOR OTHER COMMAND
ADRDMYPARM:
        .WORD   DMYPARM
DMYPARM:
DRNUM:  .BYTE   0       ;DRIVE
TKNUM:  .WORD   2       ;TRACK
SRNUM:  .WORD   0       ;SECTOR
DMA:    .WORD   BUFFER  ;DMA
SIZE:   .WORD   256     ;SIZE

BUFFER: .BLOCK  256

ENDSVA:

        .END
