Add externs to avoid multiple definitions, and then add missing definitions.
[rrq/maintain_lilo.git] / src / read.S
1 ;  read.S
2 ;
3 ;  Copyright 1999-2006 John Coffman
4 ;  Copyright 2009-2011 Joachim Wiedorn
5 ;  All rights reserved.
6 ;
7 ;  Licensed under the terms contained in the file 'COPYING'
8 ;  in the source directory.
9 ;
10
11 #define NEW_WRITE 1
12 ;
13 ; lba_read:      read using LBA
14 ;
15 ;  Enter with:
16 ;       AL      actual count of blocks to transfer
17 ;       DL      device (0x00=A:, 0x80=C:, 0x81=D:) and LINEAR/LBA32 flags
18 ;       ES:BX   buffer pointer
19 ;       DI:CX   LBA to read
20 ;
21 ;  Exit with:
22 ;       No Error:  carry clear
23 ;       CX      count of blocks read
24 ;       ES:BX   unchanged
25 ;       DX      unchanged
26 ;       AH      error status if CF=1
27 ;       DI      trashed
28 ;
29
30 lba_read:       push    si              ;save some registers
31 #ifndef JRC_NOCOMPACT
32                 push    bx
33                 push    dx
34                 xor     ah,ah           ;convert count to word
35                 push    ax
36 #endif
37                 push    cx              ;gotta ask about 32-bit addressing 
38                 push    bx
39 #ifndef JRC_FLAGS_IN_DH
40                 mov     dh,dl           ;use BL for flag test
41 #endif
42                 and     dl,#DEV_MASK_asm    ;remove spurious flags (0x8F)
43 #ifndef JRC_MBR
44                 test    dh,#LBA32_FLAG
45                 jz      no_lba          ;linear will never use EDD calls
46 #endif
47 #ifndef JRC_NOCOMPACT
48                 cmp     al,#127         ;test for LINEAR transfer too big
49                 ja      no_lba          ; for LBA mode (127 is max)
50                 push    ax
51 #endif
52                 mov     bx,#0x55AA      ;magic number
53                 mov     ah,#0x41        ;function call
54                 int     0x13
55 #ifndef JRC_NOCOMPACT
56                 pop     ax
57 #endif
58                 jc      no_lba
59                 cmp     bx,#0xAA55      ;magic return
60                 jne     no_lba
61                 test    cl,#EDD_PACKET  ;packet calls supported?
62                 jz      no_lba
63
64
65 ; LBA mode is to be used
66
67 lba_avail:
68                 pop     bx
69                 pop     cx
70
71 #ifndef JRC_NOCOMPACT
72                 pop     ax
73                 push    ax
74 #endif
75 #ifndef JRC_DS_EQ_SS
76                 push    ds              ;save DS
77 #endif
78                 push    dword #0                ;  0L is pushed
79                 push    di              ;LBA hi word
80                 push    cx              ;    lo word
81                 push    es              ;ES:BX
82                 push    bx
83 #ifndef JRC_NOCOMPACT
84                 push    ax
85 #else
86                 push    #1              ;count always 1
87 #endif
88                 push    #16             ;size of parameter area  ;#
89                                         ;actually pushes a word
90                 mov     si,sp           ;DS:SI is param block pointer
91 #ifndef JRC_DS_EQ_SS
92                 push    ss
93                 pop     ds              ;DS:SI points at param block
94 #endif
95 #ifndef JRC_NOCOMPACT
96                 mov     ax,#0x4200      ;read function -- must be AX
97                                         ; as AL has meaning on WRITE
98                 call    dsk_do_rw
99 #else
100 ;;;             mov     ax,#0x4200      ;read function
101                 mov     ah,#0x42        ;read only -- AL matters not
102                 int     0x13
103 #endif
104                 lea     sp,word ptr (si+16)      ;use lea so flags are not changed
105 #ifndef JRC_DS_EQ_SS
106                 pop     ds              ;restore DS
107 #endif
108                 jmp     lba_read_exit1
109
110
111
112 no_lba:
113                 pop     bx
114                 pop     cx
115
116
117 lba_small:                      ;must get the disk geometry
118 #ifndef JRC_NOCOMPACT
119 lba_more_small:
120                 push    bx
121                 push    di
122                 push    cx
123                 push    ax
124 #endif
125                 push    bx
126                 push    dx
127                 push    di
128                 push    cx
129
130                 push    es
131                 mov     ah,#8          ; DL is set to device
132 #ifndef JRC_NOCOMPACT
133                 call    dsk_do_int13
134 #else
135                 int     0x13
136 #endif
137                 pop     es
138                 jc      lba_geom_error
139
140                 push    cx
141                 shr     cl,#6           ;;;;
142                 xchg    cl,ch           ;CX is max cylinder number
143                 mov     di,cx           ;DI saves it
144                 pop     cx
145
146                 shr     dx,#8
147                 xchg    ax,dx           ;AX <- DX
148                 inc     ax              ;AX is number of heads (256 allowed)
149
150 ; compensate for Davide BIOS bug
151                 dec     cx              ; 1..63 -> 0..62;  0->63
152                 and     cx,#0x003f      ;CX is number of sectors
153                 inc     cx              ; allow Sectors==0 to mean 64
154
155                 mul     cx              ; kills DX
156                 xchg    ax,si           ;save in SI
157
158                 pop     ax              ;was CX
159                 pop     dx              ;was DI
160                 cmp     dx,si
161                 jae     lba_geom_error2  ;prevent division error
162                 div     si              ;AX is cyl, DX is head/sect
163                 cmp     ax,di
164                 ja      lba_geom_error2  ;cyl is too big
165
166                 shl     ah,#6           ;;;;
167                 xchg    al,ah
168                 xchg    ax,dx
169                 div     cl              ;AH = sec-1, AL = head
170 #ifndef JRC_NOCOMPACT
171                 sub     cl,ah           ;CX = max count possible
172                 mov     si,cx           ;save in SI
173 #endif
174                 inc     ah
175                 add     dl,ah           ;form Cyl/Sec
176                 mov     cx,dx
177                 pop     dx              ;get device
178                 pop     bx
179                 xchg    al,dh           ;
180
181 #ifndef JRC_NOCOMPACT
182                 pop     ax              ;restore the count
183                 push    ax              ;keep in the stack
184                 cmp     ax,si           ;
185                 jb      lba_cntltmax
186                 mov     ax,si           ;smaller is in AX
187 lba_cntltmax:   push    ax
188                 mov     ah,#2           ;READ
189                 call    dsk_do_rw
190 #else
191                 mov     ax,#0x201       ;read, count of 1
192                 int     0x13
193 #endif
194         ; carry is set or clear
195 #ifndef JRC_NOCOMPACT
196                 pop     bx              ;actual count read (was AX)
197                 pop     si              ;count remaining
198                 pop     cx
199                 pop     di
200                 jc      lba_read_exit_e
201                 add     cx,bx           ;update lba address
202                 adc     di,#0           ;the # was omitted in rev 3
203                 xchg    ax,bx
204                 pop     bx              ;buffer address
205                 add     bh,al           ;update ES:BX
206                 add     bh,al           ;LILO has already checked for seg update
207                 xchg    si,ax
208                 sub     ax,si           ;AX is remaining count after transfer
209                 jnz     lba_more_small
210                          ; after the sub yields 0, the carry is clear
211 #endif
212 lba_read_exit1: jmp     lba_read_exit
213
214 #ifndef JRC_NOCOMPACT
215
216 #ifndef LCF_READONLY
217
218 #if NEW_WRITE
219
220 dsk_do_rw:      or      ah,#0           ; 0=read, 1=write, 2=read-only test
221 dsk_wrflag      equ     *-1             ; byte data area is the immediate
222
223 #else
224 dsk_wrflag:     .byte   0               ; 0=read, 1=write, 2=read-only test
225
226 dsk_do_rw:
227                 seg     cs
228                 or      ah,dsk_wrflag
229 #endif
230
231 #else
232 #if DEBUG_NEW
233 dsk_wrflag:     .byte   0               ; 0=read, 1=write, 2=read-only test
234 #endif
235 dsk_do_rw:
236 #endif
237
238 dsk_do_int13:
239                 push    bp
240                 mov     bp,#5           ;number of tries
241 dsk_do_int13a:  pusha
242                 int     0x13
243                 jnc     dsk_io_exit
244                 dec     bp              ;does not affect the carry
245                 jz      dsk_io_exit
246                 xor     ax,ax           ;reset disk controllers
247                 int     0x13
248                 popa
249                 dec     bp
250                 jmp     dsk_do_int13a
251
252 dsk_io_exit:    mov     bp,sp           ;do not touch any flags
253                 lea     sp,(bp+16)      ;an ADD would touch flags
254                 pop     bp              ;do not touch any flags
255                 ret
256 #endif
257 lba_geom_error:
258                 pop     cx
259                 pop     di
260                 jmp     lba_g3
261 lba_geom_error2:
262                 mov     ah,#0x40         ;seek failure error code
263 lba_g3:         pop     dx
264                 pop     bx
265 #ifndef JRC_NOCOMPACT
266                 pop     cx              ;was AX
267                 pop     cx
268                 pop     di
269 lba_read_exit_e:
270                 pop     bx
271 #endif
272                 stc
273 lba_read_exit:
274 #ifndef JRC_NOCOMPACT
275                 pop     cx              ;return count in CX
276                 pop     dx
277                 pop     bx
278 #endif
279                 pop     si
280 #ifndef JRC_NORETURN
281                 ret
282 #endif