Enhance APM support.
authorKevin O'Connor <kevin@koconnor.net>
Sat, 8 Mar 2008 16:34:46 +0000 (11:34 -0500)
committerKevin O'Connor <kevin@koconnor.net>
Sat, 8 Mar 2008 16:34:46 +0000 (11:34 -0500)
Create and register protected mode interfaces.
Still needs more testing.

src/apm.c
src/romlayout.S
src/util.h

index 9b6d1e3830a1644d4197a1172dd12fcacfcb8702..5233bb9a1a95c5501dc21f7b2c0e373faf2f9ea3 100644 (file)
--- a/src/apm.c
+++ b/src/apm.c
@@ -45,11 +45,15 @@ handle_155301(struct bregs *regs)
     set_cf(regs, 0);
 }
 
+// Assembler entry points defined in romlayout.S
+extern void apm16protected_entry();
+extern void apm32protected_entry();
+
 // APM 16 bit protected mode interface connect
 static void
 handle_155302(struct bregs *regs)
 {
-    regs->bx = 0; // XXX - apm16_entry
+    regs->bx = (u32)apm16protected_entry;
     regs->ax = SEG_BIOS; // 16 bit code segment base
     regs->si = 0xfff0;   // 16 bit code segment size
     regs->cx = SEG_BIOS; // data segment address
@@ -61,13 +65,13 @@ handle_155302(struct bregs *regs)
 static void
 handle_155303(struct bregs *regs)
 {
-    regs->ax = 0xf000; // 32 bit code segment base
-    regs->ebx = 0; // XXX - apm32_entry
-    regs->cx = 0xf000; // 16 bit code segment base
+    regs->ax = SEG_BIOS; // 32 bit code segment base
+    regs->ebx = (u32)apm32protected_entry;
+    regs->cx = SEG_BIOS; // 16 bit code segment base
     // 32 bit code segment size (low 16 bits)
     // 16 bit code segment size (high 16 bits)
     regs->esi = 0xfff0fff0;
-    regs->dx = 0xf000; // data segment address
+    regs->dx = SEG_BIOS; // data segment address
     regs->di = 0xfff0; // data segment length
     set_cf(regs, 0);
 }
@@ -171,7 +175,7 @@ handle_1553XX(struct bregs *regs)
     set_cf(regs, 1);
 }
 
-void
+void VISIBLE16
 handle_1553(struct bregs *regs)
 {
     switch (regs->al) {
index 41ce3d7146ff9f8e8c649be883ee150134115c8b..8c83f88949e665f2ff7f03e2f2880cc0248d9a45 100644 (file)
@@ -243,7 +243,6 @@ rombios32_gdt:
  ****************************************************************/
 
         .macro ENTRY cfunc
-        cli         // In case something far-calls instead of using "int"
         pushal
         pushw %es
         pushw %ds
@@ -260,16 +259,26 @@ rombios32_gdt:
         .macro IRQ_ENTRY num
         .globl entry_\num
         entry_\num :
+        cli         // In case something far-calls instead of using "int"
         ENTRY handle_\num
         iretw
         .endm
 
-        .macro IRQ_TRAMPOLINE num
-        .globl irq_trampoline_0x\num
-        irq_trampoline_0x\num :
-        int $0x\num
+        // APM trampolines
+        .globl apm16protected_entry
+apm16protected_entry:
+        ENTRY handle_1553
         lretw
-        .endm
+
+        .code32
+        .globl apm32protected_entry
+apm32protected_entry:
+        pushw %cs
+        incw (%esp)
+        pushw apm16protected_entry
+        lcallw *(%esp)
+        lretl
+        .code16gcc
 
         .org 0xe2c3
         IRQ_ENTRY nmi
@@ -293,6 +302,15 @@ entry_18:
         RESET_STACK
         calll handle_18
 
+
+        // IRQ trampolines
+        .macro IRQ_TRAMPOLINE num
+        .globl irq_trampoline_0x\num
+        irq_trampoline_0x\num :
+        int $0x\num
+        lretw
+        .endm
+
         IRQ_TRAMPOLINE 02
         IRQ_TRAMPOLINE 10
         IRQ_TRAMPOLINE 13
index 488267d717a835441301767b833683740151f318..ab530741ea0de1b215ae953b95f16e6b2ba49c89 100644 (file)
@@ -136,7 +136,7 @@ void handle_15c2(struct bregs *regs);
 void handle_1583(struct bregs *regs);
 
 // apm.c
-void handle_1553(struct bregs *regs);
+void VISIBLE16 handle_1553(struct bregs *regs);
 
 // Frequent bios return helper
 #define RET_EUNSUPPORTED 0x86