aboutsummaryrefslogtreecommitdiff
path: root/mubios/arch/irq.S
blob: b22578bb9f055db7463b27ef4fd55d7ae8a4542b (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
# RCC-Project
#
# Copyright (C) 2026 Richard Qin
#
# This file is part of RCC-Project.
#
# RCC-Project is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 3 of the License, or (at your option) any
# later version.
#
# RCC-Project is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# RCC-Project; see the file COPYING.  If not see
# <http://www.gnu.org/licenses/>.

	.intel_syntax noprefix
	.code16

	.equ BDA_TIMER_COUNTER, 0x046C
	.equ BDA_TIMER_ROLLOVER, 0x0470
	.equ BDA_BASE, 0x0400
	.equ BDA_KBD_BUFFER_START, 0x001E
	.equ BDA_KBD_BUFFER_END, 0x003E
	.equ TIMER_TICKS_PER_DAY_LOW, 0x00B0
	.equ TIMER_TICKS_PER_DAY_HIGH, 0x0018

	.section .text16.irq, "ax"

	.global irq0_entry
	.type irq0_entry, @function

irq0_entry:
	push ax
	push bx
	push ds

	xor bx, bx
	mov ds, bx

	mov bx, BDA_TIMER_COUNTER
	inc word ptr [bx]

	jnz irq0_send_eoi

	inc word ptr [bx + 2]

	cmp word ptr [bx + 2], TIMER_TICKS_PER_DAY_HIGH
	jne irq0_send_eoi

	cmp word ptr [bx], TIMER_TICKS_PER_DAY_LOW
	jne irq0_send_eoi

	mov word ptr [bx], 0
	mov word ptr [bx + 2], 0
	mov byte ptr [BDA_TIMER_ROLLOVER], 1

irq0_send_eoi:
	# Acknowledge IRQ0 on the master PIC.
	mov al, 0x20
	out 0x20, al

	pop ds
	pop bx
	pop ax
	iret

	.global irq1_entry
	.type irq1_entry, @function

irq1_entry:
	push ax
	push bx
	push dx
	push ds
	push si

	xor ax, ax
	mov ds, ax

	# Only read the data port when the controller holds a byte for the CPU.
	in al, 0x64
	test al, 0x01
	jz irq1_send_eoi

	mov ah, al

	in al, 0x60
	mov dl, al

	# Drop bytes that belong to the auxiliary port.
	test ah, 0x20
	jnz irq1_send_eoi

	# Set 1 break codes carry bit 7 in the scan code itself.
	test dl, 0x80
	jnz irq1_send_eoi

	mov bx, word ptr [0x041C]
	mov ax, bx
	add ax, 2
	cmp ax, BDA_KBD_BUFFER_END
	jb irq1_next_tail_ready
	mov ax, BDA_KBD_BUFFER_START

irq1_next_tail_ready:
	cmp ax, word ptr [0x041A]
	je irq1_send_eoi

	mov si, bx
	add si, BDA_BASE
	mov byte ptr [si], 0
	mov byte ptr [si + 1], dl
	mov word ptr [0x041C], ax

irq1_send_eoi:
	mov al, 0x20
	out 0x20, al

	pop si
	pop ds
	pop dx
	pop bx
	pop ax
	iret

	.global irq7_entry
	.type irq7_entry, @function

irq7_entry:
	push ax

	# Acknowledge IRQ7 on the master PIC.
	mov al, 0x20
	out 0x20, al

	pop ax
	iret