home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / c / cl5sr386.zip / GO32 / MSWITCH.ASM < prev    next >
Assembly Source File  |  1992-04-13  |  11KB  |  550 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. ; Modified for VCPI Implement by Y.Shibata Aug 5th 1991
  16. ;    History:191,1
  17.     title    switch between real and protected mode
  18.     .386p
  19.  
  20.     include    build.inc
  21.     include    segdefs.inc
  22.     include tss.inc
  23.     include gdt.inc
  24.     include idt.inc
  25.     include vcpi.inc
  26.  
  27. ;------------------------------------------------------------------------
  28.  
  29.     start_data16
  30.  
  31.     extrn    _gdt:gdt_s
  32.     extrn    _idt:idt_s
  33.     extrn    _tss_ptr:word
  34.     extrn    _exception:near
  35.     extrn    _npx:byte
  36.     extrn    _screen_seg:word
  37.     extrn    _use_xms:word
  38.     extrn    _new_pic:byte        ; really a word, but we need a byte.
  39.  
  40.     extrn    _vcpi_installed:word    ;VCPI Installed set this not Zero
  41.     extrn    _vcpi_entry:fword
  42.     extrn    _abs_client:dword
  43.  
  44.     public    _was_exception
  45. _was_exception    dw    0    ; exceptions set this to 1
  46.  
  47.     public    _dr, _dr0, _dr1, _dr2, _dr3, _dr6, _dr7
  48. _dr    label    dword
  49. _dr0    dd    0
  50. _dr1    dd    0
  51. _dr2    dd    0
  52. _dr3    dd    0
  53.     dd    0
  54.     dd    0
  55. _dr6    dd    0
  56. _dr7    dd    0
  57.  
  58.     end_data16
  59.  
  60. ;------------------------------------------------------------------------
  61.  
  62.     .286c
  63.     start_bss
  64.  
  65.     extrn    _i_tss:tss_s
  66.     extrn    _v74_tss:tss_s
  67.     extrn    _v78_tss:tss_s
  68.     extrn    _v79_tss:tss_s
  69.  
  70.     public    _c_tss, _a_tss, _o_tss, _p_tss, _f_tss
  71. _c_tss    label    tss_s    ; for "real mode" state
  72.     db    type tss_s dup (?)
  73. _a_tss    label    tss_s    ; for running program
  74.     db    type tss_s dup (?)
  75. _o_tss    label    tss_s    ; for convenience functions
  76.     db    type tss_s dup (?)
  77. _p_tss    label    tss_s    ; for page faults
  78.     db    type tss_s dup (?)
  79. _f_tss    label    tss_s    ; for page handling
  80.     db    type tss_s dup (?)
  81.  
  82. temp_87c    dw    1 dup (?)
  83. temp_87s    dw    1 dup (?)
  84.  
  85.     end_bss
  86.     .386p
  87.  
  88. ;------------------------------------------------------------------------
  89.  
  90. sound    macro
  91.     local    wait_loop
  92.     local    wait_loop1
  93.     mov    al,033h
  94.     out    061h,al
  95.     mov    ecx,100000h
  96. wait_loop:
  97.     loopd    wait_loop
  98.     mov    al,032h
  99.     out    61h,al
  100.     mov    ecx,100000h
  101. wait_loop1:
  102.     loop    wait_loop1
  103.     endm
  104.  
  105.     start_code16
  106.  
  107.     extrn    __do_load_npx:near
  108.     extrn    _xms_local_enable_a20:near
  109.     extrn    _xms_local_disable_a20:near
  110.  
  111. real_stack    dd    ?
  112. real_idt    dw    0400h, 0000h, 0000h
  113. imask1        db    ?
  114. imask2        db    ?
  115.  
  116.     public    _go32
  117. _go32    proc    near
  118.     push    si
  119. _go32_1:
  120.     mov    ax,DGROUP
  121.     mov    dx,0
  122.     shld    dx,ax,4
  123.     shl    ax,4
  124.     add    ax,_tss_ptr
  125.     adc    dx,0
  126.     mov    _gdt[g_atss].base0,ax
  127.     mov    _gdt[g_atss].base1,dl
  128.     mov    _gdt[g_atss].base2,dh
  129.     mov    bx,_tss_ptr
  130.     and    [bx].tss_eflags,  0ffffbdffh    ; clear NT flag
  131.     and    _c_tss.tss_eflags,0ffffbdffh    ; clear NT flag
  132.     and    _i_tss.tss_eflags,0ffffbdffh    ; clear NT flag
  133.     and    _p_tss.tss_eflags,0ffffbdffh    ; clear NT flag
  134.     and    _f_tss.tss_eflags,0ffffbdffh    ; clear NT flag
  135.     and    _v74_tss.tss_eflags,0ffffbdffh    ; clear NT flag
  136.     and    _v78_tss.tss_eflags,0ffffbdffh    ; clear NT flag
  137.     and    _v79_tss.tss_eflags,0ffffbdffh    ; clear NT flag
  138.     or    _a_tss.tss_eflags,000000200h    ; set IE flag for a_tss only
  139.  
  140.     and    _gdt[g_ctss].stype,0FDh        ; clear busy flag
  141.     and    _gdt[g_atss].stype,0FDh        ; clear busy flag
  142.     and    _gdt[g_itss].stype,0FDh        ; clear busy flag
  143.     and    _gdt[g_ptss].stype,0FDh        ; clear busy flag
  144.     and    _gdt[g_v74].stype,0FDh        ; clear busy flag
  145.     and    _gdt[g_v78].stype,0FDh        ; clear busy flag
  146.     and    _gdt[g_v79].stype,0FDh        ; clear busy flag
  147.  
  148.     mov    _was_exception,0
  149.  
  150.     ; set real_stack for return from _go32
  151.     mov    word ptr cs:real_stack,sp
  152.     mov    word ptr cs:real_stack+2,ss
  153.     mov    eax,0
  154.     mov    ax,sp
  155.     mov    esp,eax        ; make sure it's OK
  156.  
  157.     cli
  158.  
  159. if TOPLINEINFO
  160.     mov    ax,_screen_seg
  161.     mov    es,ax
  162.     mov    word ptr es:[2], 0b00h+'P'
  163.     mov    word ptr es:[0], 0b00h+' '
  164. endif
  165.  
  166. ;    in    al,21h
  167. ;    mov    cs:imask1,al
  168. ;    or    al,01h
  169. ;    out    21h,al
  170.  
  171.     in    al,0a1h
  172.     or    al,20h
  173.     mov    cs:imask2,al
  174.     mov    al,0dfh
  175.     out    0a1h,al
  176.  
  177.     call    set_a20
  178.     cmp    _vcpi_installed,0
  179.     je    short real_to_protect    ;Not VCPI Mode
  180.     mov    esi,_abs_client
  181.     mov    ax,VCPI_MODE_CHANGE
  182.     int    VCPI_REQ        ;Change Protect Mode
  183. end_loop0:
  184.     jmp    short end_loop0        ;Never Come here!! Safety Loop
  185.  
  186. real_to_protect:
  187.     lgdt    fword ptr _gdt[g_gdt]
  188.     lidt    fword ptr _gdt[g_idt]
  189.  
  190.     mov    eax,cr0
  191.     or    al,1
  192.     mov    cr0,eax        ; we're in protected mode!
  193.     db    0eah        ; JMP
  194.     dw    offset go_protect_far_jump
  195.     dw    g_rcode
  196. ;
  197. ;    Entry Protect Mode
  198. ;
  199.     public    _protect_entry
  200. _protect_entry    label    near
  201.  
  202. go_protect_far_jump:
  203.     cli
  204.     mov    ax,g_rdata
  205.     mov    ds,ax
  206.     mov    es,ax
  207.     mov    ss,ax
  208.     mov    sp,word ptr cs:real_stack  ;Need VCPI Inialize
  209.     mov    ax,g_core
  210.     mov    fs,ax
  211.     mov    gs,ax
  212.     mov    eax,0
  213.     mov    cr2,eax    ; so we can tell INT 0D from page fault
  214.  
  215. ;    mov    bx,7870h
  216. ;    call    set_interrupt_controller
  217.  
  218.     mov    eax,_dr0
  219.     mov    dr0,eax
  220.     mov    eax,_dr1
  221.     mov    dr1,eax
  222.     mov    eax,_dr2
  223.     mov    dr2,eax
  224.     mov    eax,_dr3
  225.     mov    dr3,eax
  226.     mov    eax,_dr7
  227.     mov    dr7,eax
  228.  
  229.     cmp    _vcpi_installed,0
  230.     jne    short set_paging_far_jump    ;Now Paging Mode in VCPI
  231.     mov    bx,_tss_ptr
  232.     mov    eax,[bx].tss_cr3
  233.     cmp    eax,0
  234.     je    set_paging_far_jump
  235.     mov    cr3,eax
  236.     mov    eax,cr0
  237.     or    eax,80000000h
  238.     mov    cr0,eax        ; paging enabled!
  239.     db    0eah
  240.     dw    offset set_paging_far_jump
  241.     dw    g_rcode
  242. set_paging_far_jump:
  243.  
  244.     mov    bx,_tss_ptr
  245.     cmp    bx,offset DGROUP:_a_tss
  246.     jne    no_npx_load
  247.     call    __do_load_npx    ; in case it's stored in memory.
  248. no_npx_load:
  249.     cmp    _vcpi_installed,0
  250.     jne    short no_tss_load    ;Now Paging Mode in VCPI
  251.     mov    ax,g_ctss
  252.     ltr    ax
  253. no_tss_load:
  254.     jmpt    g_atss        ; load state from VCPU
  255.  
  256. _go32    endp
  257.  
  258. ; _go_real_mode must follow the task jump, so a task jump to return
  259. ; is valid
  260.  
  261.     public    _go_real_mode
  262. _go_real_mode    proc    near
  263.  
  264.     cli
  265.     mov    ax,g_rdata
  266.     mov    ds,ax
  267.     mov    es,ax
  268.     mov    fs,ax
  269.     mov    gs,ax
  270.     mov    ss,ax
  271.  
  272.     mov    eax,dr6
  273.     mov    _dr6,eax
  274.     ;
  275.     cmp    _vcpi_installed,0
  276.     je    short protect_to_real
  277.     ;
  278.     clts                ;TS Clear
  279. ;    mov    esp,offset _c_tss.tss_stack    ;Local Stack
  280.     mov    eax,DGROUP
  281.     push    eax            ;GS
  282.     push    eax            ;FS
  283.     push    eax            ;DS
  284.     push    eax            ;ES
  285.     push    eax            ;SS
  286.     movzx    eax,word ptr cs:real_stack
  287.     push    eax            ;ESP
  288.     pushfd                ;EFLAGS
  289.     mov    eax,_TEXT
  290.     push    eax            ;CS
  291.     mov    eax,offset back_to_v86
  292.     push    eax            ;EIP
  293.     movzx    esp,sp
  294.     ;
  295.     mov    ax,g_core
  296.     mov    ds,ax
  297.     mov    ax,VCPI_MODE_CHANGE
  298.     call    fword ptr es:_vcpi_entry
  299. end_loop1:
  300.     jmp    short end_loop1        ;Never Come here!! Safety Loop
  301.  
  302. protect_to_real:
  303.     mov    eax,cr0
  304.     and    eax,07ffffff6h ; clear PE, TS, PG
  305.     mov    cr0,eax
  306.  
  307.     db    0eah
  308.     dw    offset back_to_real_far_jump
  309.     dw    _TEXT
  310. ;
  311. ;    Entry Real Mode
  312. ;
  313. back_to_real_far_jump:
  314.  
  315.     lidt    fword ptr cs:real_idt
  316.     lss    sp,cs:real_stack
  317. back_to_v86:
  318. ;    mov    bx,0870h
  319. ;    call    set_interrupt_controller
  320.  
  321. ;    mov    al,cs:imask1
  322. ;    out    21h,al
  323.     mov    al,cs:imask2
  324.     out    0a1h,al
  325.  
  326. if TOPLINEINFO
  327.     mov    ax,_screen_seg
  328.     mov    es,ax
  329.     mov    word ptr es:[0], 0b00h+'R'
  330.     mov    word ptr es:[2], 0b00h+' '
  331. endif
  332.     mov    ax,DGROUP
  333.     mov    ds,ax
  334.     mov    es,ax
  335.     mov    fs,ax
  336.     mov    gs,ax
  337.  
  338.     call    reset_a20
  339.     sti
  340.  
  341.     mov    bx,_tss_ptr
  342.     mov    al,[bx].tss_irqn
  343.  
  344.     mov    bl,_new_pic
  345.     mov    bh,bl
  346.     add    bh,7
  347.     mov    cl,bl
  348.     inc    cl
  349.  
  350.     cmp    al,75h
  351.     je    short not_hard    ; for NPX errors
  352.     cmp    al,cl
  353.     je    short not_hard    ; to check for ^C
  354.     cmp    al,70h
  355.     jb    short try_newpic
  356.     cmp    al,77h
  357.     ja    short try_newpic
  358.     jmp    no_move
  359. try_newpic:
  360.     cmp    al,bl
  361.     jb    not_hard
  362.     cmp    al,bh
  363.     ja    not_hard
  364.  
  365.     sub    al,bl
  366.     add    al,8
  367.  
  368. no_move:
  369.     mov    byte ptr cs:[irq_d+1],al
  370.     jmp    short irq_d_jmp    ; to flush the queue
  371. irq_d_jmp:
  372. irq_d    db    0cdh,0        ; generated INT opcode
  373.     jmp    _go32_1
  374. not_hard:
  375.     pop    si
  376.     ret
  377.  
  378. hexchar    db    '0123456789ABCDEF'
  379.  
  380. _go_real_mode    endp
  381.  
  382. ;------------------------------------------------------------------------
  383.  
  384. dout    macro    a,d
  385.     mov    al,d
  386.     out    a,al
  387.     jmp    $+2
  388.     jmp    $+2
  389.     endm
  390.  
  391. set_interrupt_controller:
  392.     dout    20h,11h
  393.     dout    0a0h,11h
  394.     dout    21h,bh
  395.     dout    0a1h,bl
  396.     dout    21h,4
  397.     dout    0a1h,2
  398.     dout    21h,1
  399.     dout    0a1h,1
  400.     ret
  401.  
  402. ;------------------------------------------------------------------------
  403.  
  404. reset_a20    proc    near
  405.     cmp    _vcpi_installed,0
  406.     jne    short reset_a20_nop
  407.     cmp    _use_xms,0
  408.     je    short reset_a20_local
  409.     call    _xms_local_disable_a20
  410. reset_a20_nop:
  411.     ret
  412.  
  413. reset_a20_local:
  414.     in    al,092h        ; 092h is the system control port "A"
  415.                 ; for PS/2 models
  416.     and    al,not 2    ; this resets the A20 bit in register al
  417.     jmp    SHORT $+2    ; forget the instruction fetch
  418.     out    092h,al        ; set the A20 bit off
  419.     ret
  420. reset_a20    endp
  421.  
  422. set_a20    proc    near
  423.     cmp    _vcpi_installed,0
  424.     jne    short set_a20_nop
  425.     cmp    _use_xms,0
  426.     je    short set_a20_local
  427.     call    _xms_local_enable_a20
  428. set_a20_nop:
  429.     ret
  430.  
  431. set_a20_local:
  432.     pushf
  433.     cli
  434.     in    al,092h        ; 092h is the system control port "A"
  435.                 ; for PS/2 models
  436.     or    al,2        ; this sets the A20 bit in register al
  437.     jmp    SHORT $+2    ; forget the instruction fetch
  438.     out    092h,al        ; set the A20 bit on
  439.  
  440.     mov    ax,0
  441.     mov    fs,ax
  442.     mov    ax,0ffffh
  443.     mov    gs,ax
  444.     mov    bx,fs:[0]
  445.     mov    word ptr fs:[0],1234
  446.     cmp    word ptr gs:[16],1234
  447.     je    need_to_set_a20
  448.     mov    word ptr fs:[0],4321
  449.     cmp    word ptr gs:[16],4321
  450.     je    need_to_set_a20
  451.     mov    fs:[0],bx
  452.     popf
  453.     ret
  454.  
  455. need_to_set_a20:
  456.     mov    fs:[0],bx
  457.     call    waitkb
  458.     mov    al,0d1h
  459.     out    64h,al
  460.     call    waitkb
  461. ;    mov    al,0d3h
  462.     mov    al,0dfh        ; Patrick
  463.     out    60h,al
  464.     call    waitkb
  465.     mov    al,0ffh        ; Patrick
  466.     out    64h,al        ; Patrick
  467.     call    waitkb        ; Patrick
  468.     mov    ax,0
  469.     mov    fs,ax
  470.     mov    ax,0ffffh
  471.     mov    gs,ax
  472.     mov    bx,fs:[0]
  473.  
  474. wait_for_valid_a20:
  475.     mov    word ptr fs:[0],1234
  476.     cmp    word ptr gs:[16],1234
  477.     je    wait_for_valid_a20
  478.     mov    word ptr fs:[0],4321
  479.     cmp    word ptr gs:[16],4321
  480.     je    wait_for_valid_a20
  481.  
  482.     mov    fs:[0],bx
  483.     popf
  484.     ret
  485.  
  486. waitkb:
  487.     mov    cx,0
  488. waitkb1:
  489.     in    al,64h
  490.     test    al,2
  491.     loopnz    waitkb1
  492.     je    waitkb3
  493. waitkb2:
  494.     in    al,64h
  495.     test    al,2
  496.     loopnz    waitkb1
  497. waitkb3:
  498.     ret
  499. set_a20    endp
  500.  
  501. ;------------------------------------------------------------------------
  502.  
  503.     public    _cputype    ; from Intel 80486 reference manual
  504. _cputype:
  505.     pushf
  506.     pop    bx
  507.     and    bx,0fffh
  508.     push    bx
  509.     popf
  510.     pushf
  511.     pop    ax
  512.     and    ax,0f000h
  513.     cmp    ax,0f000h
  514.     jz    bad_cpu
  515.     or    bx,0f000h
  516.     push    bx
  517.     popf
  518.     pushf
  519.     pop    ax
  520.     and    ax,0f000h
  521.     jz    bad_cpu
  522.  
  523.     smsw    ax
  524.     test    ax,1
  525.     jnz    bad_mode
  526.     mov    ax,0
  527.     ret
  528.  
  529. bad_mode:
  530.     mov    ax,2
  531.     ret
  532.  
  533. bad_cpu:
  534.     mov    ax,1
  535.     ret
  536.  
  537. ;------------------------------------------------------------------------
  538.  
  539.     end_code16
  540.  
  541. ;------------------------------------------------------------------------
  542.  
  543.     start_code32
  544.  
  545.     end_code32
  546.  
  547. ;------------------------------------------------------------------------
  548.  
  549.     end
  550.