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