summaryrefslogtreecommitdiff
path: root/system/shard-x86-at/7/src/WAIT.ASM
blob: 80ff8389633bbac5293a2bfbc776214b8a976d06 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
;****************************************************************************
;*======= Copyright (C) 1985,86 Martin Schoenbeck, Spenge ==================*
;*                                                                          *
;*   Support fuer die Wartelogik des IBM PC-AT ueber int 15h                *
;*                                                                          *
;*                                                                          *
;****************************************************************************

int15 proc far
     sti
     push ax
     cmp ah,90h                  ;hat ein treiber nichts zu tun
     jz device_is_busy
     cmp ah,91h                  ;oder ist er gerade fertig
     jz device_ready
not_for_me:                      ;hab ich nichts mit am hut
     pop ax
     jmp dword ptr cs:[int15_cont]

device_ready:
     cmp al,2                    ;0 (platte) oder 1 (floppy)
     jnc not_for_me
     mov ah,0
     push bx
     mov bx,ax
     mov byte ptr cs:device_busy[bx],2  ;device ist fertig geworden
     pop bx
     pop ax
     iret

device_is_busy:
     mov ah,8                    ;annahme: 6 sekunden fuer platte
     cmp al,0                    ;ist es platte
     jz device_wait              ;ja
     mov ah,3                    ;annahme: 2 sekunden fuer floppy
     cmp al,1
     jz device_wait              ;ist floppy
     cmp al,0fdh                 ;warten auf floppy_motor 
     jnz not_for_me              ;mit allem anderen haben wir nichts am hut
     mov ax,0301h                ;zwei sekunden warten; device floppy
device_wait:
     push bx                     ;den ganzen ramsch sichern
     push cx
     push dx
     push bp
     push di
     push si
     push es
     push ds
     mov bl,al
     mov bh,0
   cli
     mov byte ptr cs:device_table[bx],1          ;device busy setzen
     mov byte ptr cs:device_timeout_table[bx],ah ;anzahl sekunden eintragen
   sti
device_wait_loop:
     cmp byte ptr cs:device_busy[bx],0  ;noch kein interrupt gekommen
     jnz device_wait_end
     push bx
     call cs:warte
     pop bx
     jmp device_wait_loop
device_wait_end:
     cmp byte ptr cs:device_busy[bx],2 ;normales ende
     ifnz <stc>                         ;nicht normal, war timeout
     mov byte ptr cs:device_table[bx],0 ;device ist wieder frei
     mov byte ptr cs:device_busy[bx],0 ;device kann wieder auf int warten
;    jnc devcont
;    call cs:info
;    jmp short devcont
;    db ' timeout'
devcont:
     pop ds
     pop es
     pop si
     pop di
     pop bp
     pop dx
     pop cx
     pop bx
     pop ax
     ret 2                       ;kill flags on stack

int15 endp

device_timing:
     mov bx,-1                   ;mit 0 fangen wir an
     mov cx,2                    ;zwei durchlaeufe
device_timing_loop:
     inc bx
     mov al,byte ptr device_timeout_table[bx] ;timeout zaehler holen
     cmp al,0ffh                 ;schon fertig mit zaehlen
     jz device_timing_end
     dec al
     mov byte ptr device_timeout_table[bx],al ;timeout zaehler neu setzen
     jns device_timing_end
     cmp byte ptr device_table[bx],1 ;noch aktiv?
     ifz <cmp byte ptr device_busy[bx],0> ;und noch kein endeinterrupt
     ifz <mov byte ptr device_busy[bx],3> ;timeout aufgetreten
device_timing_end:
     loop device_timing_loop
     jmp word ptr device_cont

;***********************************************************************
;* warten, bis das in bx uebergebene device frei ist
;* ds = cs ist bedingung, alle register (ausser flags) bleiben erhalten
  db 'device free'
device_free:
     cmp byte ptr device_table[bx],0 ;ist das device frei 
     jnz device_not_free
     mov byte ptr device_busy[bx],0 ;evtl. nachgeklapperte ints loeschen
     ret                         ;device kann benutzt werden
device_not_free:
     push ax
     push bx
     push cx
     push dx
     push si
     push di
     push bp
     push ds
     push es
     call warte
     pop es
     pop ds
     pop bp
     pop di
     pop si
     pop dx
     pop cx
     pop bx
     pop ax
     jmp device_free

device_lock:
     mov byte ptr device_table[bx],1 ;device sperren 
     ret

device_unlock:
     mov byte ptr device_table[bx],0 ;device freigeben 
     ret

device_init:
     mov ax,0
     mov es,ax
     mov bx,word ptr es:[15h*4]         ;int routine holen
     mov cx,word ptr es:[15h*4+2]       ;int segment holen
     mov word ptr es:[15h*4],offset int15
     mov word ptr es:[15h*4+2],cs
     mov word ptr [int15_cont],bx
     mov word ptr [int15_cont+2],cx
     mov ax,word ptr [sec_entry]       ;alte adresse fuer sec_tick holen
     mov word ptr [device_cont],ax     ;eintragen fuer weitergabe
     mov word ptr [sec_entry],offset device_timing ;unseren aufruf eintragen 
     ret

int15_cont:
     dw 0
     dw 0

device_cont:
     dw 0

device_table:
     db 0
     db 0

device_busy:
     db 0
     db 0

device_timeout_table:
     db 0
     db 0