1;
2; Christian Groessler, February 2005
3;
4; This file provides the _dio_open and _dio_close functions
5; Since on the Atari no real open and close is necessary, they
6; do not open or close something. The _dio_open sets the sector
7; size of the drive which is later used by the _dio_read and
8; _dio_write functions. To query the sector size, the _dio_open
9; accesses the disk drive.
10;
11; dhandle_t     __fastcall__ dio_open  (unsigned char device);
12; unsigned char __fastcall__ dio_close (dhandle_t handle);
13;
14
15        .export         _dio_open, _dio_close
16        .export         sectsizetab
17        .import         __oserror, __sio_call, _dio_read
18        .import         pushax, addysp, subysp
19        .importzp       ptr2, sp
20        .include        "atari.inc"
21
22
23.bss
24
25sectsizetab:
26        .res    NUMDRVS * sst_size
27
28.code
29
30; code for _dio_open
31
32_inv_drive:
33        lda     #NONDEV         ; non-existent device
34        sta     __oserror
35        lda     #0
36        tax
37        rts                     ; return NULL
38
39_dio_open:
40
41        cmp     #NUMDRVS        ; valid drive id?
42        bcs     _inv_drive
43        tay                     ; drive #
44        asl     a               ; make index from drive id
45        asl     a
46        tax
47        lda     #128                            ; preset sectsize
48        sta     sectsizetab+sst_sectsize,x
49        sta     sectsizetab+sst_flag,x          ; set flag that drive is "open"
50        lda     #0
51        sta     sectsizetab+sst_sectsize+1,x
52        sta     __oserror                       ; success
53        tya
54        sta     sectsizetab+sst_driveno,x
55        stx     ptr2
56        lda     #<sectsizetab
57        clc
58        adc     ptr2
59        sta     ptr2
60        lda     #>sectsizetab
61        adc     #0
62        tax
63        stx     ptr2+1          ; ptr2: pointer to sectsizetab entry
64
65; query drive for current sector size
66; procedure:
67;   - read sector #4 (SIO command $54) to update drive status;
68;     read length is 128 bytes, buffer is allocated on the stack,
69;          sector data is ignored;
70;     returned command status is ignored, we will get an error with
71;          a DD disk anyway (read size 128 vs. sector size 256);
72;   - issue SIO command $53 (get status) to retrieve the sector size;
73;     use the DVSTAT system area as return buffer;
74;     if the command returns with an error, set sector size to 128
75;          bytes;
76;
77
78        ldy     #128
79        jsr     subysp          ; allocate buffer on the stack
80
81        lda     sp
82        pha
83        lda     sp+1
84        pha                     ; save sp (buffer address) on processor stack
85
86        lda     ptr2
87        ldx     ptr2+1
88        jsr     pushax          ; handle
89
90        ldx     #0
91        lda     #4
92        jsr     pushax          ; sect_num
93
94        pla
95        tax
96        pla                     ; AX - buffer address
97
98                                ; sst_sectsize currently 128
99        jsr     _dio_read       ; read sector to update status
100
101        ldy     #128
102        jsr     addysp          ; discard stack buffer
103
104        lda     ptr2
105        ldx     ptr2+1
106        jsr     pushax          ; handle
107
108        ldx     #0
109        lda     #4
110        jsr     pushax          ; dummy sector #, ignored by this SIO command,
111                                ; but set to circumvent the special 1-3 sector
112                                ; handling in __sio_call
113
114        ldx     #>DVSTAT
115        lda     #<DVSTAT
116        jsr     pushax          ; buffer address
117
118        ldy     #sst_sectsize
119        lda     #4
120        sta     (ptr2),y        ; 4 bytes transfer
121
122        ldx     #%01000000      ; direction value
123        lda     #SIO_STAT       ; get status
124
125        jsr     __sio_call
126
127        bmi     error
128
129        ldy     #sst_sectsize
130        lda     DVSTAT
131        and     #%100000
132        beq     s128
133
134;s256
135        lda     #0
136        sta     (ptr2),y
137        iny
138        lda     #1
139
140finish: sta     (ptr2),y        ; set default sector size
141fini2:  lda     ptr2
142        ldx     ptr2+1
143        rts
144
145error:  ldy     #sst_sectsize
146s128:   lda     #128
147        bne     finish
148
149; end of _dio_open
150
151
152.proc   _dio_close
153
154        sta     ptr2
155        stx     ptr2+1
156        lda     #0
157        ldy     #sst_flag
158        sta     (ptr2),y
159        sta     __oserror       ; success
160        tax
161        rts                     ; return no error
162
163.endproc
164