diff options
| author | Richard Qin <richard.qin.x@gmail.com> | 2026-11-08 07:46:07 +0800 |
|---|---|---|
| committer | Richard Qin <richard.qin.x@gmail.com> | 2026-11-08 07:46:07 +0800 |
| commit | 9bfc57c3684f7aebba0f6865a1ea248f576b947f (patch) | |
| tree | 8dafb3b4c9487b02a1fa634dbf4ae11509a37e7d /mubios/arch/interrupt.S | |
| parent | 1a211405d76b2e8997ec21d53831147441c8de24 (diff) | |
| download | rcc-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.S | 346 |
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 |
