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
39 saved_pic1_mask: .byte 0
40 saved_pic2_mask: .byte 0
42 # drop back to unreal mode to call 16bit interrupt
51 # save protected mode IDTR and replace it with the real mode vectors
59 mov %al, saved_pic1_mask
63 mov %al, saved_pic2_mask
65 # modify the int instruction. do this here before the
66 # cs-load jumps, to let them flush the instruction cache
71 # long jump to load code selector for 16bit code (6)
81 0: # zero data segments
90 # load registers from the int86regs struct
91 # point esp to the regs struct to load registers with popa/popf
99 # ignore fs and gs for now, don't think I'm going to need them
101 # move to the real-mode stack, at the top of conventional memory
106 # move to the real-mode stack, accessible from ss=0
107 # just in case the BIOS call screws up our unreal mode
110 # call 16bit interrupt
112 # BIOS call might have enabled interrupts, cli for good measure
115 # save all registers that we'll clobber before having the
116 # chance to populate the int86regs structure
124 # re-enable protection
128 # long jump to load code selector for 32bit code (1)
132 # set data selector (2) to all segment regs
141 # point the esp to our regs struct, to fill it with pusha/pushf
149 # grab the flags and replace the carry bit from the saved flags
159 # restore 32bit interrupt descriptor table
162 # restore PIC configuration
166 movzbl saved_pic1_mask, %eax
172 movzbl saved_pic2_mask, %eax
178 # keyboard voodoo: with some BIOS implementations, after returning from
179 # int13, there's (I guess) leftover data in the keyboard port and we
180 # can't receive any more keyboard interrupts afterwards. Reading from
181 # the keyboard data port (60h) once, seems to resolve this. And it's
182 # cheap enough, so why not... I give up.
185 # restore interrupts to their previous state
186 movzbl saved_if, %eax