home *** CD-ROM | disk | FTP | other *** search
/ Stars of Shareware: Programmierung / SOURCE.mdf / programm / msdos / c / djgpp / go32 / mswitch.asm < prev    next >
Encoding:
Assembly Source File  |  1991-05-30  |  7.6 KB  |  428 lines

  1. ; This is file MSWITCH.ASM
  2. ;
  3. ; Copyright (C) 1991 DJ Delorie, 24 Kirsten Ave, Rochester NH 03867-2954
  4. ;
  5. ; This file is distributed under the terms listed in the document
  6. ; "copying.dj", available from DJ Delorie at the address above.
  7. ; A copy of "copying.dj" should accompany this file; if not, a copy
  8. ; should be available from where this file was obtained.  This file
  9. ; may not be distributed without a verbatim copy of "copying.dj".
  10. ;
  11. ; This file is distributed WITHOUT ANY WARRANTY; without even the implied
  12. ; warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13. ;
  14.  
  15. ;    History:191,1
  16.     title    switch between real and protected mode
  17.     .386p
  18.  
  19.     include    build.inc
  20.     include    segdefs.inc
  21.     include tss.inc
  22.     include gdt.inc
  23.     include idt.inc
  24.  
  25. ;------------------------------------------------------------------------
  26.  
  27.     start_data16
  28.  
  29.     extrn    _gdt:gdt_s
  30.     extrn    _idt:idt_s
  31.     extrn    _tss_ptr:word
  32.     extrn    _exception:near
  33.     extrn    _npx:byte
  34.     extrn    _screen_seg:word
  35.  
  36.     public    _was_exception
  37. _was_exception    dw    0    ; exceptions set this to 1
  38.  
  39.     public    _dr, _dr0, _dr1, _dr2, _dr3, _dr6, _dr7
  40. _dr    label    dword
  41. _dr0    dd    0
  42. _dr1    dd    0
  43. _dr2    dd    0
  44. _dr3    dd    0
  45.     dd    0
  46.     dd    0
  47. _dr6    dd    0
  48. _dr7    dd    0
  49.  
  50.     end_data16
  51.  
  52. ;------------------------------------------------------------------------
  53.  
  54.     .286c
  55.     start_bss
  56.  
  57.     extrn    _i_tss:tss_s
  58.     public    _c_tss, _a_tss, _o_tss, _p_tss, _f_tss
  59. _c_tss    label    tss_s    ; for "real mode" state
  60.     db    type tss_s dup (?)
  61. _a_tss    label    tss_s    ; for running program
  62.     db    type tss_s dup (?)
  63. _o_tss    label    tss_s    ; for convenience functions
  64.     db    type tss_s dup (?)
  65. _p_tss    label    tss_s    ; for page faults
  66.     db    type tss_s dup (?)
  67. _f_tss    label    tss_s    ; for page handling
  68.     db    type tss_s dup (?)
  69.  
  70. temp_87c    dw    1 dup (?)
  71. temp_87s    dw    1 dup (?)
  72.  
  73.     end_bss
  74.     .386p
  75.  
  76. ;------------------------------------------------------------------------
  77.  
  78. sound    macro
  79.     mov    al,033h
  80.     out    061h,al
  81.     endm
  82.  
  83.     start_code16
  84.  
  85.     extrn    __do_load_npx:near
  86.  
  87. real_stack    dd    ?
  88. real_idt    dw    0400h, 0000h, 0000h
  89. imask1        db    ?
  90. imask2        db    ?
  91.  
  92.     public    _go32
  93. _go32    proc    near
  94.  
  95.     mov    ax,DGROUP
  96.     mov    dx,0
  97.     shld    dx,ax,4
  98.     shl    ax,4
  99.     add    ax,_tss_ptr
  100.     adc    dx,0
  101.     mov    _gdt[g_atss].base0,ax
  102.     mov    _gdt[g_atss].base1,dl
  103.     mov    _gdt[g_atss].base2,dh
  104.     mov    bx,_tss_ptr
  105.     and    [bx].tss_eflags,  0ffffbdffh    ; clear NT flag
  106.     and    _c_tss.tss_eflags,0ffffbdffh    ; clear NT flag
  107.     and    _i_tss.tss_eflags,0ffffbdffh    ; clear NT flag
  108.     and    _p_tss.tss_eflags,0ffffbdffh    ; clear NT flag
  109.     and    _f_tss.tss_eflags,0ffffbdffh    ; clear NT flag
  110.     or    _a_tss.tss_eflags,000000200h    ; set IE flag for a_tss only
  111.  
  112.     and    _gdt[g_ctss].stype,0FDh        ; clear busy flag
  113.     and    _gdt[g_atss].stype,0FDh        ; clear busy flag
  114.     and    _gdt[g_itss].stype,0FDh        ; clear busy flag
  115.     and    _gdt[g_ptss].stype,0FDh        ; clear busy flag
  116.  
  117.     mov    _was_exception,0
  118.  
  119.     ; set real_stack for return from _go32
  120.     mov    word ptr cs:real_stack,sp
  121.     mov    word ptr cs:real_stack+2,ss
  122.     mov    eax,0
  123.     mov    ax,sp
  124.     mov    esp,eax        ; make sure it's OK
  125.  
  126.     cli
  127.  
  128. if TOPLINEINFO
  129.     mov    ax,_screen_seg
  130.     mov    es,ax
  131.     mov    word ptr es:[0], 0b00h+'P'
  132.     mov    word ptr es:[2], 0b00h+' '
  133. endif
  134.  
  135. ;    in    al,21h
  136. ;    mov    cs:imask1,al
  137. ;    or    al,01h
  138. ;    out    21h,al
  139.  
  140.     in    al,0a1h
  141.     or    al,20h
  142.     mov    cs:imask2,al
  143.     mov    al,0dfh
  144.     out    0a1h,al
  145.  
  146.     call    set_a20
  147.  
  148.     lgdt    fword ptr _gdt[g_gdt]
  149.     lidt    fword ptr _gdt[g_idt]
  150.  
  151.     mov    eax,0
  152.     mov    cr2,eax    ; so we can tell INT 0D from page fault
  153.  
  154.     mov    eax,cr0
  155.     or    al,1
  156.     mov    cr0,eax        ; we're in protected mode!
  157.     db    0eah        ; JMP
  158.     dw    offset go_protect_far_jump
  159.     dw    g_rcode
  160. go_protect_far_jump:
  161.  
  162.     mov    ax,g_rdata
  163.     mov    ds,ax
  164.     mov    es,ax
  165.     mov    ss,ax
  166.     mov    ax,g_core
  167.     mov    fs,ax
  168.     mov    gs,ax
  169.  
  170. ;    mov    bx,7870h
  171. ;    call    set_interrupt_controller
  172.  
  173.     mov    eax,_dr0
  174.     mov    dr0,eax
  175.     mov    eax,_dr1
  176.     mov    dr1,eax
  177.     mov    eax,_dr2
  178.     mov    dr2,eax
  179.     mov    eax,_dr3
  180.     mov    dr3,eax
  181.     mov    eax,_dr7
  182.     mov    dr7,eax
  183.  
  184.     mov    bx,_tss_ptr
  185.     mov    eax,[bx].tss_cr3
  186.     cmp    eax,0
  187.     je    set_paging_far_jump
  188.     mov    cr3,eax
  189.     mov    eax,cr0
  190.     or    eax,80000000h
  191.     mov    cr0,eax        ; paging enabled!
  192.     db    0eah
  193.     dw    offset set_paging_far_jump
  194.     dw    g_rcode
  195. set_paging_far_jump:
  196.  
  197.     mov    bx,_tss_ptr
  198.     cmp    bx,offset DGROUP:_a_tss
  199.     jne    no_npx_load
  200.     call    __do_load_npx    ; in case it's stored in memory.
  201. no_npx_load:
  202.  
  203.     mov    ax,g_ctss
  204.     ltr    ax
  205.  
  206.     jmpt    g_atss        ; load state from VCPU
  207.  
  208. _go32    endp
  209.  
  210. ; _go_real_mode must follow the task jump, so a task jump to return
  211. ; is valid
  212.  
  213.     public    _go_real_mode
  214. _go_real_mode    proc    near
  215.  
  216.     cli
  217.     mov    ax,g_rdata
  218.     mov    ds,ax
  219.     mov    es,ax
  220.     mov    fs,ax
  221.     mov    gs,ax
  222.     mov    ss,ax
  223.  
  224.     mov    eax,dr6
  225.     mov    _dr6,eax
  226.  
  227.     mov    eax,cr0
  228.     and    eax,07ffffff6h ; clear PE, TS, PG
  229.     mov    cr0,eax
  230.  
  231.     db    0eah
  232.     dw    offset back_to_real_far_jump
  233.     dw    _TEXT
  234. back_to_real_far_jump:
  235.  
  236.     lidt    fword ptr cs:real_idt
  237.     lss    sp,cs:real_stack
  238.  
  239. ;    mov    bx,0870h
  240. ;    call    set_interrupt_controller
  241.  
  242. ;    mov    al,cs:imask1
  243. ;    out    21h,al
  244.     mov    al,cs:imask2
  245.     out    0a1h,al
  246.  
  247. if TOPLINEINFO
  248.     mov    ax,_screen_seg
  249.     mov    es,ax
  250.     mov    word ptr es:[0], 0b00h+'R'
  251.     mov    word ptr es:[2], 0b00h+' '
  252. endif
  253.     mov    ax,DGROUP
  254.     mov    ds,ax
  255.     mov    es,ax
  256.     mov    fs,ax
  257.     mov    gs,ax
  258.  
  259.     sti
  260.  
  261.     mov    bx,_tss_ptr
  262.     mov    al,[bx].tss_irqn
  263.     cmp    al,75h
  264.     je    short not_hard    ; for NPX errors
  265.     cmp    al,79h
  266.     je    short not_hard    ; to check for ^C
  267.     cmp    al,70h
  268.     jb    short not_hard
  269.     cmp    al,7fh
  270.     ja    short not_hard
  271.     cmp    al,78h
  272.     jb    short no_move
  273.     sub    al,70h
  274. no_move:
  275.     mov    byte ptr cs:[irq_d+1],al
  276.     jmp    short irq_d_jmp    ; to flush the queue
  277. irq_d_jmp:
  278. irq_d    db    0cdh,0        ; generated INT opcode
  279.     jmp    _go32
  280. not_hard:
  281.  
  282.     ret
  283.  
  284. hexchar    db    '0123456789ABCDEF'
  285.  
  286. _go_real_mode    endp
  287.  
  288. ;------------------------------------------------------------------------
  289.  
  290. dout    macro    a,d
  291.     mov    al,d
  292.     out    a,al
  293.     jmp    $+2
  294.     jmp    $+2
  295.     endm
  296.  
  297. set_interrupt_controller:
  298.     dout    20h,11h
  299.     dout    0a0h,11h
  300.     dout    21h,bh
  301.     dout    0a1h,bl
  302.     dout    21h,4
  303.     dout    0a1h,2
  304.     dout    21h,1
  305.     dout    0a1h,1
  306.     ret
  307.  
  308. ;------------------------------------------------------------------------
  309.  
  310. set_a20    proc    near
  311.     pushf
  312.     cli
  313.     mov    ax,0
  314.     mov    fs,ax
  315.     mov    ax,0ffffh
  316.     mov    gs,ax
  317.     mov    bx,fs:[0]
  318.     mov    word ptr fs:[0],1234
  319.     cmp    word ptr gs:[16],1234
  320.     je    need_to_set_a20
  321.     mov    word ptr fs:[0],4321
  322.     cmp    word ptr gs:[16],4321
  323.     je    need_to_set_a20
  324.     mov    fs:[0],bx
  325.     popf
  326.     ret
  327.  
  328. need_to_set_a20:
  329.     mov    fs:[0],bx
  330.     call    waitkb
  331.     mov    al,0d1h
  332.     out    64h,al
  333.     call    waitkb
  334. ;    mov    al,0d3h
  335.     mov    al,0dfh        ; Patrick
  336.     out    60h,al
  337.     call    waitkb
  338.     mov    al,0ffh        ; Patrick
  339.     out    64h,al        ; Patrick
  340.     call    waitkb        ; Patrick
  341.     mov    ax,0
  342.     mov    fs,ax
  343.     mov    ax,0ffffh
  344.     mov    gs,ax
  345.     mov    bx,fs:[0]
  346.     in    al,092h        ; 092h is the system control port "A"
  347.                 ; for PS/2 models
  348.     or    al,2        ; this sets the A20 bit in register al
  349.     jmp    SHORT $+2    ; forget the instruction fetch
  350.     out    092h,al        ; set the A20 bit on
  351.  
  352. wait_for_valid_a20:
  353.     mov    word ptr fs:[0],1234
  354.     cmp    word ptr gs:[16],1234
  355.     je    wait_for_valid_a20
  356.     mov    word ptr fs:[0],4321
  357.     cmp    word ptr gs:[16],4321
  358.     je    wait_for_valid_a20
  359.  
  360.     mov    fs:[0],bx
  361.     popf
  362.     ret
  363.  
  364. waitkb:
  365.     mov    cx,0
  366. waitkb1:
  367.     in    al,64h
  368.     test    al,2
  369.     loopnz    waitkb1
  370.     je    waitkb3
  371. waitkb2:
  372.     in    al,64h
  373.     test    al,2
  374.     loopnz    waitkb1
  375. waitkb3:
  376.     ret
  377. set_a20    endp
  378.  
  379. ;------------------------------------------------------------------------
  380.  
  381.     public    _cputype    ; from Intel 80486 reference manual
  382. _cputype:
  383.     pushf
  384.     pop    bx
  385.     and    bx,0fffh
  386.     push    bx
  387.     popf
  388.     pushf
  389.     pop    ax
  390.     and    ax,0f000h
  391.     cmp    ax,0f000h
  392.     jz    bad_cpu
  393.     or    bx,0f000h
  394.     push    bx
  395.     popf
  396.     pushf
  397.     pop    ax
  398.     and    ax,0f000h
  399.     jz    bad_cpu
  400.  
  401.     smsw    ax
  402.     test    ax,1
  403.     jnz    bad_mode
  404.     mov    ax,0
  405.     ret
  406.  
  407. bad_mode:
  408.     mov    ax,2
  409.     ret
  410.  
  411. bad_cpu:
  412.     mov    ax,1
  413.     ret
  414.  
  415. ;------------------------------------------------------------------------
  416.  
  417.     end_code16
  418.  
  419. ;------------------------------------------------------------------------
  420.  
  421.     start_code32
  422.  
  423.     end_code32
  424.  
  425. ;------------------------------------------------------------------------
  426.  
  427.     end
  428.