aboutsummaryrefslogtreecommitdiff
path: root/mubios/arch/interrupt.S
diff options
context:
space:
mode:
authorRichard Qin <richard.qin.x@gmail.com>2026-11-08 07:46:07 +0800
committerRichard Qin <richard.qin.x@gmail.com>2026-11-08 07:46:07 +0800
commit9bfc57c3684f7aebba0f6865a1ea248f576b947f (patch)
tree8dafb3b4c9487b02a1fa634dbf4ae11509a37e7d /mubios/arch/interrupt.S
parent1a211405d76b2e8997ec21d53831147441c8de24 (diff)
downloadrcc-project-9bfc57c3684f7aebba0f6865a1ea248f576b947f.tar.gz
rcc-project-9bfc57c3684f7aebba0f6865a1ea248f576b947f.tar.xz
[mubios] Add switching and return paths between real-mode interrupts and protected-mode C services.
Signed-off-by: Richard Qin <richard.qin.x@gmail.com>
Diffstat (limited to 'mubios/arch/interrupt.S')
-rw-r--r--mubios/arch/interrupt.S346
1 files changed, 63 insertions, 283 deletions
diff --git a/mubios/arch/interrupt.S b/mubios/arch/interrupt.S
index 88ccfbf..0822b1a 100644
--- a/mubios/arch/interrupt.S
+++ b/mubios/arch/interrupt.S
@@ -6,31 +6,21 @@
#
# 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.
+# 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/>.
+# 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.
.intel_syntax noprefix
.code16
- .equ ATA_DATA, 0x1F0
- .equ ATA_SECTOR_COUNT, 0x1F2
- .equ ATA_LBA_LOW, 0x1F3
- .equ ATA_LBA_MID, 0x1F4
- .equ ATA_LBA_HIGH, 0x1F5
- .equ ATA_DRIVE, 0x1F6
- .equ ATA_STATUS, 0x1F7
- .equ ATA_COMMAND, 0x1F7
-
.section .text16.irq, "ax"
+ .extern enter_protected_service
+
.global int1a_entry
.type int1a_entry, @function
@@ -58,268 +48,58 @@ int1a_entry:
int1a_return:
iret
- .global int10_entry
- .type int10_entry, @function
-
-int10_entry:
- cmp ah, 0x0E
- jne int10_return
-
- push bp
- mov bp, sp
-
- push ax
- push bx
- push dx
- push si
- push di
- push ds
- push es
-
- xor ax, ax
- mov ds, ax
-
- mov ax, 0xB800
- mov es, ax
-
- mov si, 0x0050
- mov dx, word ptr [si]
-
- mov al, byte ptr [bp - 2]
- mov bl, byte ptr [bp - 4]
-
- cmp al, 0x0D
- je int10_carriage_return
-
- cmp al, 0x0A
- je int10_line_feed
-
- cmp al, 0x08
- je int10_backspace
-
- mov di, dx
- shl di, 1
- mov ah, bl
- mov word ptr es:[di], ax
- inc dx
- jmp int10_store_cursor
-
-
-int10_carriage_return:
- mov ax, dx
- mov si, 80
- xor dx, dx
- div si
- mul si
- mov dx, ax
- jmp int10_store_cursor
-
-int10_line_feed:
- add dx, 80
- jmp int10_store_cursor
-
-int10_backspace:
- cmp dx, 0
- je int10_store_cursor
-
- dec dx
- mov di, dx
- shl di, 1
- mov al, 0x20
- mov ah, bl
- mov word ptr es:[di], ax
-
-int10_store_cursor:
- cmp dx, 2000
- jb int10_save_cursor
-
- xor dx, dx
-
-int10_save_cursor:
- mov word ptr [0x0050], dx
-
- pop es
- pop ds
- pop di
- pop si
- pop dx
- pop bx
- pop ax
- pop bp
-
-int10_return:
- iret
-
- .global int13_entry
- .type int13_entry, @function
-
-int13_entry:
- cmp ah, 0x42
- je int13_extended_read
-
- cmp ah, 0x41
- jne int13_return
-
- push bp
- mov bp, sp
-
- cmp bx, 0x55AA
- jne int13_fail
-
- mov bx, 0xAA55
- mov cx, 0x0001
- mov ax, 0x3000
-
- # Clear CF in the FLAGS saved by INT.
- and word ptr [bp + 6], 0xFFFE
-
- pop bp
- iret
-
-int13_fail:
- mov ah, 0x01
-
- # Set CF in the FLAGS saved by INT.
- or word ptr [bp + 6], 0x0001
-
- pop bp
- iret
-
-int13_return:
- push bp
- mov bp, sp
-
- mov ah, 0x01
-
- # Set CF in the FLAGS saved by INT.
- or word ptr [bp + 6], 0x0001
-
- pop bp
- iret
-int13_extended_read:
- push bp
- mov bp, sp
-
- push bx
- push cx
- push dx
- push si
- push di
- push ds
- push es
-
- # DAP size must be 0x10.
- cmp byte ptr [si], 0x10
- jne int13_extended_fail
-
- # This step supports exactly one sector.
- cmp word ptr [si + 2], 1
- jne int13_extended_fail
-
- # Reject LBA values above 28 bits.
- mov ax, word ptr [si + 12]
- or ax, word ptr [si + 14]
- jnz int13_extended_fail
-
- mov ax, word ptr [si + 10]
- test ax, 0xF000
- jnz int13_extended_fail
-
- # Load DAP buffer ES:DI.
- mov di, word ptr [si + 4]
- mov ax, word ptr [si + 6]
- mov es, ax
-
- cld
-
- # Select ATA drive from DL.
- mov al, 0xE0
- test dl, 1
- jz int13_drive_selected
-
- or al, 0x10
-
-int13_drive_selected:
- mov dx, ATA_DRIVE
- out dx, al
-
- # 400 ns delay.
- mov dx, ATA_STATUS
- in al, dx
- in al, dx
- in al, dx
- in al, dx
-
- # Sector count = 1.
- mov dx, ATA_SECTOR_COUNT
- mov al, 1
- out dx, al
-
- # LBA byte 0.
- mov ax, word ptr [si + 8]
- mov dx, ATA_LBA_LOW
- out dx, al
-
- # LBA byte 1.
- mov al, ah
- mov dx, ATA_LBA_MID
- out dx, al
-
- # LBA byte 2.
- mov ax, word ptr [si + 10]
- mov dx, ATA_LBA_HIGH
- out dx, al
-
- # READ SECTORS command.
- mov dx, ATA_COMMAND
- mov al, 0x20
- out dx, al
-
-int13_wait_data:
- mov dx, ATA_STATUS
- in al, dx
-
- test al, 0x80
- jnz int13_wait_data
-
- test al, 0x01
- jnz int13_extended_fail
-
- test al, 0x08
- jz int13_wait_data
-
- # Read one 512-byte sector.
- mov dx, ATA_DATA
- mov cx, 256
- rep insw
-
- # Clear CF in the saved FLAGS.
- and word ptr [bp + 6], 0xFFFE
-
- pop es
- pop ds
- pop di
- pop si
- pop dx
- pop cx
- pop bx
- pop bp
-
- xor ax, ax
- iret
-
-int13_extended_fail:
- # Set CF in the saved FLAGS.
- or word ptr [bp + 6], 0x0001
-
- pop es
- pop ds
- pop di
- pop si
- pop dx
- pop cx
- pop bx
- pop bp
-
- mov ax, 0x0100
- iret
+ .macro BIOS_SERVICE_ENTRY name, vector
+ .global \name
+ .type \name, @function
+
+\name:
+ # Build struct bios_regs on the interrupted real-mode stack.
+ push 0
+ push es
+ push ds
+ push bp
+ push di
+ push si
+ push dx
+ push cx
+ push bx
+ push ax
+
+ mov bp, sp
+ mov ax, word ptr [bp + 24]
+ mov word ptr [bp + 18], ax
+
+ # ESI = linear address of struct bios_regs.
+ movzx esi, sp
+ xor eax, eax
+ mov ax, ss
+ shl eax, 4
+ add esi, eax
+
+ # EBP = original SS:SP return point, packed as SS:SP.
+ movzx ebp, sp
+ sub ebp, 2
+ xor eax, eax
+ mov ax, ss
+ shl eax, 16
+ or ebp, eax
+
+ mov edi, \vector
+ call enter_protected_service
+
+ # Restore the context modified by the C service.
+ pop ax
+ pop bx
+ pop cx
+ pop dx
+ pop si
+ pop di
+ pop bp
+ pop ds
+ pop es
+ add sp, 2
+ iret
+ .endm
+
+ BIOS_SERVICE_ENTRY int10_entry, 0x10
+ BIOS_SERVICE_ENTRY int13_entry, 0x13