works and returns to DOS on dosbox
[com32] / src / segm.c
index c6baffd..0d8f4b4 100644 (file)
@@ -15,6 +15,7 @@ GNU General Public License for more details.
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */
+#include <stdio.h>
 #include <string.h>
 #include "segm.h"
 #include "desc.h"
@@ -44,30 +45,38 @@ enum {TYPE_DATA, TYPE_CODE};
 
 static void segm_desc(desc_t *desc, uint32_t base, uint32_t limit, int dpl, int type);
 static void segm_desc16(desc_t *desc, uint32_t base, uint32_t limit, int dpl, int type);
-static void task_desc(desc_t *desc, uint32_t base, uint32_t limit, int dpl);
+/*static void task_desc(desc_t *desc, uint32_t base, uint32_t limit, int dpl);*/
 
 /* these functions are implemented in segm-asm.S */
 void setup_selectors(uint16_t code, uint16_t data);
 void set_gdt(uint32_t addr, uint16_t limit);
 void set_task_reg(uint16_t tss_selector);
 
+static void dbg_print_gdt(void);
+static void print_desc(desc_t *desc);
 
 /* our global descriptor table */
 static desc_t gdt[NUM_SEGMENTS] __attribute__((aligned(8)));
-
+uint16_t orig_seg;
 
 void init_segm(void)
 {
+       asm volatile (
+               "mov %%fs, %0\n\t"
+               : "=a"(orig_seg));
+
        memset(gdt, 0, sizeof gdt);
-       segm_desc(gdt + SEGM_KCODE, 0, 0xffffffff, 0, TYPE_CODE);
-       segm_desc(gdt + SEGM_KDATA, 0, 0xffffffff, 0, TYPE_DATA);
-       segm_desc(gdt + SEGM_UCODE, 0, 0xffffffff, 3, TYPE_CODE);
-       segm_desc(gdt + SEGM_UDATA, 0, 0xffffffff, 3, TYPE_DATA);
-       segm_desc16(gdt + SEGM_CODE16, 0, 0xffff, 0, TYPE_CODE);
+       segm_desc(gdt + SEGM_CODE, 0, 0xffffffff, 0, TYPE_CODE);
+       segm_desc(gdt + SEGM_DATA, 0, 0xffffffff, 0, TYPE_DATA);
+       segm_desc(gdt + SEGM_XCODE, orig_seg << 4, 0xffffffff, 0, TYPE_CODE);
+       segm_desc(gdt + SEGM_XDATA, orig_seg << 4, 0xffffffff, 0, TYPE_DATA);
+       segm_desc16(gdt + SEGM_CODE16, orig_seg << 4, 0xffff, 0, TYPE_CODE);
 
        set_gdt((uint32_t)gdt, sizeof gdt - 1);
 
-       setup_selectors(selector(SEGM_KCODE, 0), selector(SEGM_KDATA, 0));
+       setup_selectors(selector(SEGM_CODE, 0), selector(SEGM_DATA, 0));
+
+       dbg_print_gdt();
 }
 
 /* constructs a GDT selector based on index and priviledge level */
@@ -76,11 +85,13 @@ uint16_t selector(int idx, int rpl)
        return (idx << 3) | (rpl & 3);
 }
 
+/*
 void set_tss(uint32_t addr)
 {
        task_desc(gdt + SEGM_TASK, addr, sizeof(struct task_state) - 1, 3);
        set_task_reg(selector(SEGM_TASK, 0));
 }
+*/
 
 static void segm_desc(desc_t *desc, uint32_t base, uint32_t limit, int dpl, int type)
 {
@@ -116,6 +127,7 @@ static void segm_desc16(desc_t *desc, uint32_t base, uint32_t limit, int dpl, in
        desc->d[3] = 0;
 }
 
+#if 0
 static void task_desc(desc_t *desc, uint32_t base, uint32_t limit, int dpl)
 {
        desc->d[0] = limit & 0xffff;
@@ -125,7 +137,8 @@ static void task_desc(desc_t *desc, uint32_t base, uint32_t limit, int dpl)
                TSS_TYPE_BITS; /* XXX busy ? */
        desc->d[3] = ((limit >> 16) & 0xf) | ((base >> 16) & 0xff00) | BIT_GRAN;
 }
-/*
+#endif
+
 static void dbg_print_gdt(void)
 {
        int i;
@@ -133,7 +146,8 @@ static void dbg_print_gdt(void)
        printf("Global Descriptor Table\n");
        printf("-----------------------\n");
 
-       for(i=0; i<6; i++) {
+       for(i=0; i<NUM_SEGMENTS; i++) {
+               printf("%d: ", i);
                print_desc(gdt + i);
        }
 }
@@ -141,19 +155,19 @@ static void dbg_print_gdt(void)
 static void print_desc(desc_t *desc)
 {
        uint32_t base, limit;
-       int dpl, g, db, l, avl, p, s, type;
-       char *type_str;
+       int dpl, g;
+
+       if((desc->d[0] | desc->d[1] | desc->d[2] | desc->d[3]) == 0) {
+               printf("null\n");
+       }
 
        base = (uint32_t)desc->d[1] | ((uint32_t)(desc->d[2] & 0xff) << 16) | ((uint32_t)(desc->d[3] >> 8) << 24);
        limit = (uint32_t)desc->d[0] | ((uint32_t)(desc->d[3] & 0xf) << 16);
        dpl = (desc->d[2] >> 13) & 3;
-       type = (desc->d[2] >> 8) & 0xf;
-       g = (desc->d[3] >> 23) & 1;
-       db = (desc->d[3] >> 22) & 1;
-       l = (desc->d[3] >> 21) & 1;
-       avl = (desc->d[3] >> 20) & 1;
-
-       p = (desc->d[2] >> 15) & 1;
-       s = (desc->d[2] >> 12) & 1;
+       g = (desc->d[3] >> 7) & 1;
+
+       if(g) limit = ((limit + 1) << 12) - 1;
+
+       printf("base:%x lim:%x dpl:%d type:%s %dbit\n", base, limit, dpl,
+                       desc->d[2] & BIT_CODE ? "code" : "data", desc->d[3] & BIT_BIG ? 32 : 16);
 }
-*/