1 # pcboot - bootable PC demo/game kernel
2 # Copyright (C) 2018-2019 John Tsiombikas <nuclear@member.fsf.org>
4 # This program is free software: you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation, either version 3 of the License, or
7 # (at your option) any later version.
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY, without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
14 # You should have received a copy of the GNU General Public License
15 # along with this program. If not, see <https://www.gnu.org/licenses/>.
17 .section .lowtext,"ax"
21 # place to save the protected mode IDTR pseudo-descriptor
22 # with sidt, so that it can be restored before returning
27 # real mode IDTR pseudo-descriptor pointing to the IVT at addr 0
38 saved_pic1_mask: .byte 0
39 saved_pic2_mask: .byte 0
41 # drop back to unreal mode to call 16bit interrupt
48 # save protected mode IDTR and replace it with the real mode vectors
56 mov %al, saved_pic1_mask
60 mov %al, saved_pic2_mask
62 # modify the int instruction. do this here before the
63 # cs-load jumps, to let them flush the instruction cache
68 # long jump to load code selector for 16bit code (6)
78 0: # zero data segments
85 # load registers from the int86regs struct
86 # point esp to the regs struct to load registers with popa/popf
94 # ignore fs and gs for now, don't think I'm going to need them
96 # move to the real-mode stack, accessible from ss=0
97 # just in case the BIOS call screws up our unreal mode
100 # call 16bit interrupt
102 # BIOS call might have enabled interrupts, cli for good measure
105 # save all registers that we'll clobber before having the
106 # chance to populate the int86regs structure
114 # re-enable protection
118 # long jump to load code selector for 32bit code (1)
122 # set data selector (2) to all segment regs
129 # point the esp to our regs struct, to fill it with pusha/pushf
137 # grab the flags and replace the carry bit from the saved flags
147 # restore 32bit interrupt descriptor table
150 # restore PIC configuration
154 movzbl saved_pic1_mask, %eax
160 movzbl saved_pic2_mask, %eax
166 # keyboard voodoo: with some BIOS implementations, after returning from
167 # int13, there's (I guess) leftover data in the keyboard port and we
168 # can't receive any more keyboard interrupts afterwards. Reading from
169 # the keyboard data port (60h) once, seems to resolve this. And it's
170 # cheap enough, so why not... I give up.