-
Notifications
You must be signed in to change notification settings - Fork 0
/
hw0.asm
208 lines (184 loc) · 5.93 KB
/
hw0.asm
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
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
;******************************************************************************
; Rutinas de acceso al hardware de la PC
; Versión 1
; 5/6/2003
; Autor Alejandro Furfaro
;******************************************************************************
;------------------------------
; ReproganarPICs
; Corre la base de los tipos de interrupción de ambos PICs 8259A de la PC a los
; 8 tipos consecutivos a partir de los valores base que recibe en BH para el
; PIC Nº1 y BL para el PIC Nº2.
; A su retorno las Interrupciones de ambos PICs están deshabilitadas.
;------------------------------
global hora
global fecha
global ReprogramarPICs
ReprogramarPICs:
; Inicialización PIC Nº1
;ICW1
mov al,11h ;IRQs activas x flanco, cascada, y ICW4
out 20h,al
;ICW2
mov al,bh ;El PIC Nº1 arranca en INT tipo (Ah)
out 21h,al
;ICW3
mov al,04h ;PIC1 Master, Slave ingresa Int.x IRQ2
out 21h,al
;ICW4
mov al,01h ;Modo 8086
out 21h,al
;Antes de inicializar el PIC Nº2, deshabilitamos las Interrupciones del PIC1
mov al,0FFh
out 21h,al
;Ahora inicializamos el PIC Nº2
;ICW1
mov al,11h ;IRQs activas x flanco,cascada, y ICW4
out 0A0h,al
;ICW2
mov al,bl ;El PIC Nº2 arranca en INT tipo (BL)
out 0A1h,al
;ICW3
mov al,02h ;PIC2 Slave, ingresa Int x IRQ2
out 0A1h,al
;ICW4
mov al,01h ;Modo 8086
out 0A1h,al
;Enmascaramos el resto de las Interrupciones (las del PIC Nº2)
mov al,0FFh
out 0A1h,al
ret
;--------------------------------
;GATE_A20:
;Controla la se#al que maneja la compuerta del bit de direcciones A20. La se#al
;de compuerta del bit A20 es una salida del procesador de teclado 8042.
;Se debe utilizar cuando se planea acceder en Modo Protegido a direcciones de
;memoria mas allá del 1er. Mbyte.
;Llamar con : AH = 0DDh, si se desea apagar esta se#al. (A20 siempre cero).
; AL = 0DFh, si se desea disparar esta se#al. (x86 controla A20)
;Devuelve : AL = 00, si hubo exito. El 8042 acepto el comando.
; AL = 02, si fallo. El 8042 no acepto el comando.
;--------------------------------
port_a EQU 060h ;Direccion de E/S del Port A del 8042
status_port EQU 064h ;port de Estados del 8042
gate_a20:
cli ;Mientras usa el 8042, no INTR
call _8042_empty? ;Ve si buffer del 8042 vac¡o.
jnz gate_a20_01 ;No lo est ->retorna con AL=2.
mov al,0D1h ;Comando Write port del 8042..
out status_port,al ;...se env¡a al port 64h.
call _8042_empty? ;Espera se acepte el comando.
jnz gate_a20_01 ;Si no se acepta, Ret con AL=2
mov al,ah ;Pone en AL el dato a escribir.
out port_a,al ;Lo env¡a al 8042.
call _8042_empty? ;Espera se acepte el comando.
gate_a20_01:
ret
;--------------------------------
;8042_empty?:
;Espera que se vac¡e el buffer del 8042.
;Llamar con : Nada.
;Devuelve : AL = 00, el buffer del 8042 est vac¡o.(ZF = 1)
; AL = 02, time out. El buffer del 8042 sigue lleno. (ZF = 0)
;--------------------------------
_8042_empty?:
push cx ;salva CX.
sub cx,cx ;CX = 0 : valor de time out.
empty_8042_01: in al,status_port ;Lee port de estado del 8042.
and al,00000010b ;si el bit 1 est seteado o...
loopnz empty_8042_01 ;no alcanz¢ time out, espera.
pop cx ;recupera cx
ret ;retorna con AL=0, si se
;limpi¢ bit 1, o AL=2 si no.
;--------------------------------
;hora
;Obtiene la hora del sistema desde el RTC
;Llamar con: Nada
;Devuelve: AL: Segundos
; AH: Minutos
; DL: Hora
;--------------------------------
hora:
call RTC_disponible ;asegura que no esté
;actualizandose el RTC
mov al,0x84
out 70h,al ;Selecciona Registro de Hora
in al,71h ;lee hora
mov dl,al
mov al,0x82
out 70h,al ;Selecciona Registro de Minutos
in al,71h ;lee minutos
mov ah,al
mov al, 0x80
out 70h,al ;Selecciona Registro de Segundos
in al,71h ;lee minutos
ret
;--------------------------------
;fecha
;Obtiene la fecha del sistema desde el RTC
;Llamar con: Nada
;Devuelve: AL: Dia de la Semana
; AH: Fecha del Mes
; DL: Mes
; DH: Año
;--------------------------------
fecha:
call RTC_disponible ;asegura que no esté
;actualizandose el RTC
mov al,9
out 70h,al ;Selecciona Registro de Año
in al,71h ;lee año
mov dh,al
mov al,8
out 70h,al ;Selecciona Registro de Mes
in al,71h ;lee mes
mov dl,al
mov al,7
out 70h,al ;Selecciona Registro de Fecha
in al,71h ;lee Fecha del mes
mov ah,al
mov al,6
out 70h,al ;Selecciona Registro de Día
in al,71h ;lee día de la semana
ret
;--------------------------------
;RTC_disponible
;Verifica en el Status Register A que el RTC no esté actualizando fecha y hora
;Retorna cuando el RTC está disponible
;Llamar con : Nada
;Devuelve: Nada
;--------------------------------
RTC_disponible:
mov al,0Ah
out 70h,al ;Selecciona registro de status A
wait_for_free:
in al,71h ;lee Status
test al,80h
jnz wait_for_free
ret
;////////////////// Llamar con tamaño mensaje en ecx y mensaje en esi
;////////////////// Pinta la pantalla.
;~ screen_print:
;~
;~ mov ax, 0x8
;~ mov es, ax
;~
;~ mov ecx, (25 * 80) << 1
;~ mov ax, 0x1000
;~ mov edi, video_mem
;~
;~ .cicloazul:
;~ stosw
;~ loop .cicloazul
;~
;~ mov edi, video_mem + ((10 * 80) + 13) << 1
;~
;~ mov ah, 0x1A
;~
;~ .ciclo:
;~ lodsb
;~ stosw
;~ loop .ciclo
;~
;~ ret