home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / pc / progrmng / xm.lzh / XM.ASM < prev    next >
Assembly Source File  |  1990-10-09  |  25KB  |  1,452 lines

  1. ; modify on ss:sp 
  2. ;
  3.         .386
  4.         %NOINCL
  5.         page    85,132    
  6.  
  7.         include    xmhd.inc
  8.         include xmmsg.def
  9.         include    xmmac.mac
  10.         
  11. _DATA        segment    para public USE16 'DATA'
  12.         extrn    DosCallP: word
  13.  
  14.         public    debugflag
  15.         public    Param
  16. ;
  17.         ends
  18.  
  19. _TEXT        segment    para public USE16 'CODE'
  20.         
  21.         public    ToProtection,Gate
  22.         public    orig_code, orig_size
  23.         extrn    PrintTrace:near
  24.         extrn    retos:near
  25.         extrn    DosExit:near
  26.         extrn    putpointer:near
  27.         
  28.         extrn    Ty_Debugger:near
  29.         extrn    puttracereg:near
  30.         extrn    copy_original:near
  31.         
  32.         extrn    a20_off:near, a20_on:near
  33.         extrn    OSExit:near
  34. _TEXT        ends
  35.  
  36. _STACK        segment    para STACK USE16 'STACK'
  37. StackSize    equ    512
  38.         db    StackSize dup (?)
  39. _STACK        ends
  40.  
  41. COMMUNICATION    segment    para public USE16 'DATA'
  42.         public    ToDosDS, ToDosES, FromDosDS, FromDosES
  43. ToDosDS        dw    ?
  44. ToDosES        dw    ?
  45. FromDosDS    dw    ?
  46. FromDosES    dw    ?
  47. CommLimit    equ    7
  48. COMMUNICATION    ends
  49.  
  50. _DATA        segment    para public USE16 'DATA'
  51.  
  52.         extrn    Handle: word
  53. ;
  54. ;
  55. ; debug information
  56. ;
  57. ;
  58. DebugFlag    dflag    <TraceReg, TrapDOS, TraceDOS, MsgToCom> 
  59.         
  60.         db    0,0
  61.         public    traceCount
  62. TraceCount    dw    0
  63.         even
  64. orig_code    label    dword
  65.         dw    1800h
  66.         dw    -1
  67. orig_size    dw    256
  68.  
  69. ;
  70. ;
  71. Control387    dw    ?
  72.  
  73.         public    exessesp, exeesp, exess
  74. ExeSSESP    label    fword
  75. ExeESP        dd    60 * 1024        ;STACK_HI
  76. ExeSS        dw    ExeDataSel,0
  77.  
  78.         public    savedcseip, savedeip, savedcs
  79. SavedCSEIP    label    fword
  80. SavedEIP    dd    0
  81. SavedCS        dw    0,0
  82.  
  83.         public    savedssesp, savedesp, savedss
  84. SavedSSESP    label    fword
  85. SavedESP    dd    0
  86. SavedSS        dw    0,0
  87.  
  88.         public    stack_log
  89.         align    dword
  90. stack_log    dd    60h dup (3a3a3ah)
  91.         
  92.         public    gateeax 
  93. GateEAX        dd    ?
  94.         
  95.         public    gatessesp, gateesp, gatess
  96. GateSSESP    label    fword
  97. GateESP        dd    ?
  98. GateSS        dw    0,0
  99.         
  100.         public    gateCarry
  101. GateCarry    label    byte
  102.         dw    0,0
  103.  
  104. SavedIntN    dw    0
  105.  
  106.         align    dword
  107.         public    savedflags
  108. SavedFlags    label    dword
  109. SavedFlag_lo    dw    ?
  110.         dw    ?
  111.         
  112.         public    savedeax, savedax
  113. SavedEAX    label    dword
  114. SavedAX      dw    ?
  115.         dw    ?
  116. SavedEBX    dd    ?
  117. SavedECX    dd    ?
  118. SavedESI    dd    ?
  119. SavedEBP    dd    ?
  120. TempEBX        dd    ?
  121. TempDS        dw    ?
  122. TempES        dw    ?
  123. DosFuncNo    dw    ?
  124. DosCallNo    dw    ?
  125.  
  126.         public    exeeax, exeax
  127. ExeEAX        label    dword
  128. ExeAX        dw    ?
  129.         dw    ?
  130.         
  131.         public    execseip, exeeip, execs
  132.         align    dword
  133. ExeCSEIP    label    fword
  134. ExeEIP        dd    ?
  135. ExeCS        dw    ?
  136.  
  137.         public    thisssesp, thissp, thisss
  138.         align    dword
  139. ThisSSESP    label    fword
  140. ThisSP        dw    ?
  141.         dw    0
  142. ThisSS        dw    ?
  143.  
  144.         align    8
  145. ;
  146. ;type of AccessRights = p,dpl,1,typ,a    or p,dpl,0,type
  147. ar_data        equ    10010010b
  148. ar_code        equ    10011010b
  149. ar_stk        equ    10010110b
  150. ;
  151. DPL0        equ    00000000b
  152. DPL1        equ    00100000b
  153. DPL2        equ    01000000b
  154. DPL3        equ    01100000b
  155. ;    
  156. ;type of Granularity  = g,x,0,avl,limit19-16
  157. ;    
  158. gr_16        equ    10000000b    ; G=1, default 16 bit (286 compatible)
  159. gr_16s        equ    00000000b    ; G=0, default 16 bit (286 compatible)
  160. gr_32        equ    11000000b    ; G=1, default 32 bit
  161. gr_32s        equ    01000000b    ; G=0, default 32 bit
  162. ;
  163. ;            <lim0-15,bs0-15,bs16-23,ar,gr,bs24-31>
  164. ;
  165. ;    grobal segment
  166. ;
  167.         align    dword
  168. GDT        label    byte        ;global descriptor table starts here
  169. NULL        Desc    <>        ;Null descriptor
  170. ProgCode    Desc    <0ffffh,,,ar_code,gr_32,0> ;code descriptor
  171. ProgData    Desc    <0ffffh,,,ar_data,gr_32,0> ;data descriptor
  172. ThisCode    Desc    <0ffffh,,,ar_code,gr_16+15,>    ;.code
  173. ThisData    Desc    <0ffffh,,,ar_data,gr_16+15,>    ;.data
  174. CommData    Desc    <0ffffh,,,ar_data,00000000b,>     ;communication
  175. LDTDesc        Desc    <LDTLimit,,,82h,,>        ;selector to LDT
  176. GDTDesc        Desc    <GDTLimit,,,82h,,>        ;selector to GDT
  177. FlatData    Desc    <0ffffh,0,0,ar_data,gr_32,0>     ;flat 256MB data
  178. GDT_END        label    byte
  179. GDTLimit    equ    GDT_END - GDT -1
  180.  
  181. NULLSelector    equ    0        ;0
  182. ProgCSel    equ    ProgCode - GDT    ;+ 7
  183. ProgDsel    equ    ProgData - GDT     ;+ 7
  184. ThisCodeSel    equ    ThisCode - GDT    ;18h
  185. ThisDataSel    equ    ThisData - GDT    ;20h
  186. CommDataSel    equ    CommData - GDT    ;28h
  187. LDTSel        equ    LDTDesc  - GDT    ;30h
  188. GDTSel        equ    GDTDesc     - GDT  ;38h
  189. FlatDataSel    equ    FlatData - GDT    ;40h
  190.  
  191. ;
  192. ; local segment
  193. ; for the compatibility to Phar Lap's
  194. ;
  195. ;            <lim0-15,bs0-15,bs16-23,ar,gr,bs24-31>
  196. ;
  197.         align    dword
  198. LDT        label    byte        ;local descriptor table starts here
  199. CallGate    Desc    <Gate,ThisCodeSel,0,0ech,0,0>    ;gate to proc Gate
  200. ExeCode        Desc    <0ffffh,,,ar_code,gr_32,> ;code descriptor
  201. ExeData        Desc    <0ffffh,,,ar_data,gr_32,> ;data descriptor
  202. LSEG_VRAM    Desc    <256/4,0,0ah,ar_data,gr_32,0>     ; Video RAM
  203. LSEG_PSP2    Desc    < 512,,,ar_data,gr_32s,0>    ; PSP for user program
  204. LSEG_ENV    Desc    <4096,,,ar_data,gr_32s,0>    ; Environment
  205. LSEG_LOWMEM    Desc    <1024/4,0,0,ar_data,gr_32,0>    ; LowMemory (limit=1MB)
  206. LDT_END        label    byte
  207. ;
  208. LDTLimit    equ    LDT_END -LDT -1
  209.  
  210. GateSel        equ    CallGate - LDT + 4    ;first entry in LDT, RPL 3
  211. ExeCodeSel    equ    ExeCode  - LDT + 4    ;c
  212. ExeDataSel    equ    ExeData  - LDT + 4    ;14
  213. VramSel        equ    LSEG_VRAM - LDT + 4    ;1c
  214. PSP2Sel        equ    LSEG_PSP2 - LDT + 4    ;24
  215. ENVSel        equ    LSEG_ENV  - LDT + 4    ;2c
  216. LowMemSel    equ    LSEG_LowMem-LDT + 4    ;34
  217.  
  218.         %NOMACS
  219.         align    8
  220. IDT        label    byte
  221.  
  222. IntDesc        macro    n
  223.         dw    Intr&n        ;;offset 0 15
  224.         dw    ThisCodeSel    ;;selector
  225.         db    0        ;;word count
  226.         db    10001110b    ;;gate type
  227.         dw    0        ;;offset 16 31
  228.         endm
  229.  
  230. x        =    0
  231.         rept    256
  232.         IntDesc    %x
  233. x        =    x+1
  234.         endm
  235.  
  236.         align    dword
  237. ;FlushPtr    label    dword
  238. ;        dw    Flush
  239. ;        dw    _TEXT
  240.  
  241. ProtectedPtr    label    dword
  242.         dw    Protected
  243.         dw    ThisCodeSel
  244.  
  245.         public    gdtlimitbase, idtlimitbase
  246. GDTLimitBase    label    fword
  247.         dw    GDTLimit
  248. GDTBase        dd    ?
  249.         
  250.  
  251. IDTLimitBase    label    fword
  252.         dw    256*8-1
  253. IDTBase        dd    ?
  254.  
  255.         public    rmidtlimitbase 
  256. RMIDTLimitBase    label    fword
  257.         dw    256*4-1
  258.         dd    0
  259.  
  260. LDTBase        dd    ?
  261.  
  262.         public    EData, EBSS
  263.         public    ECode
  264. ;        public    Parm
  265.  
  266. EData        sect    <,,>    ;1
  267. EBSS        sect    <,,>    ;0
  268. ECode        sect    <,,>    ;1
  269. ProgENV        sect    <,,>    ;0
  270. ProgPSP        sect    <,,>    ;0
  271.  
  272.         public    thiscodebase, thisdatabase, commdatabase
  273. ThisCodeBase    dd    ?
  274. ThisDataBase    dd    ?
  275. CommDataBase    dd    ?
  276. BrkVal        dd    ?
  277. NextTime    dd    ?
  278.  
  279. Param        dd    8 dup (?) ; max 8 params
  280. ArgP        dd    ?
  281. PSP        dw    ?        ; My PSP segment
  282. EnvSeg        dw    ?        ; My ENV segment
  283. ArgLen        db    ?
  284.  
  285.  
  286.  
  287.         public    SavedOpCode
  288. SavedOpCode    db    90h        ; nop instruction for default
  289.         public    ErrorOffset
  290. ErrorOffset    db    ?
  291.  
  292.  
  293.  
  294. ; input: lower nibble, output: upper nibble
  295. ; register only = 0,  
  296. ; 1 = ds:dx, 2 = es:bx, 3 = es:di, 4 = ds:di
  297. ;
  298. ;    end of dos functions
  299. ;
  300.         include    termio.inc
  301.         include    stat.inc
  302.  
  303. ;cons_tio    termio    <1805h,01bdh,003bh,00000h,00h,7fh,1ch,08h,40h,04h,0,0,0>
  304. ;file_tio    termio    <0000h,0000h,0000h,0ffffh,00h,00h,00h,00h,00h,00h,0,0,0>
  305.  
  306.         include    exp.inc
  307.         
  308.         extrn    fhdr:filehdr
  309.  
  310.         extrn    pspwork:byte, DosBuffer:byte
  311.         extrn    DosworkI:byte, Dosworko:byte
  312.         extrn    Mywork:byte, comp_buffer:byte
  313.  
  314. _DATA        ends
  315.  
  316. _TEXT        segment    para public USE16 'CODE'
  317.         assume    cs: _TEXT, ds: _DATA
  318.  
  319.  
  320. EntryPointer    label    fword
  321. EntryEIP    dd    ?
  322. EntrySel    dw    ExeCodeSel
  323.  
  324. ; stack frame:    0    gs
  325. ;        2    fs
  326. ;        4    es
  327. ;        8    ds
  328. ;        10    ret-offset
  329. ;        14    ret-segment
  330. ;        16    ret-offset to caller of system library
  331. ;        20    parameters...
  332.  
  333.  
  334.         .386P
  335. Gate        proc    far
  336.         iret
  337.         cli
  338.         endp
  339.  
  340.         extrn    ReadFOHdr:near, ReadSHdr:near
  341.         extrn    OpenExe:near
  342. ;
  343. ;
  344. ; Silly design on BIOS, used INTEL reserved interrupt. 
  345. ;
  346.         .386
  347. IF PCAT
  348.         %out    " This is PC/AT version "
  349. IRC1        = 020h
  350. IRC2        = 0a0h
  351.         public    P8259
  352. P8259        proc    near
  353.         pushf
  354.         cli
  355.         outb    IRC1, 11h
  356.         outbd    IRC1+1, ah
  357.         outbd    IRC1+1, 4
  358.         outbd    IRC1+1, 1
  359.         outbd    IRC1+1, 00h
  360.         outbd    IRC1, 20h
  361. comment %
  362. ;  IRC 2
  363.         outb    IRC2 + 0, 11h
  364.         outbd    IRC2 + 1, ah
  365.         outbd    IRC2 + 1, 4
  366.         outbd    IRC2 + 1, 1
  367.         outbd    IRC2 + 1, 00h
  368.         outbd    IRC2 + 0, 20h
  369. ;
  370. %
  371. ;
  372.         popf
  373.         ret
  374. P8259        endp
  375. ENDIF
  376.  
  377.         .386
  378.         extrn    CopyVectors:near    
  379. SetDescriptor    proc    near
  380. ; bx descriptor
  381. ; eax base
  382. ; ecx limit
  383.         mov    [bx].Base_0_15, ax
  384.         shr    eax, 16
  385.         mov    [bx].Base_16_23, al
  386.         mov    [bx].Base_24_31, ah
  387.         cmp    ecx, 0fffffh    ;greater than 1 MB?
  388.         jbe    LimOK
  389.         shr    ecx, PAGESHIFT    ;size in pages
  390.         or    ecx, 800000h    ;set Granularity bit to 1
  391. LimOK:        mov    [bx].Limit_0_15, cx
  392.         shr    ecx, 16
  393.         mov    al, [bx].Granularity
  394.         and    al, NOT 8fh
  395.         or    al, cl
  396.         mov    [bx].Granularity, al
  397.         ret
  398. SetDescriptor    endp
  399.  
  400. SetDesc        macro    b, a, c
  401.         mov    bx, offset b
  402.         mov    eax, a
  403.         mov    ecx, c
  404.         call    SetDescriptor
  405.         endm
  406.  
  407.         extrn    setenvp:near
  408.         public    PushToExeStack
  409.  
  410. PushToExeStack    proc    near
  411. IF FMR70
  412.         call    a20_on
  413. ENDIF
  414.         mov    edi, ExeESP
  415.         sub    edi, 4
  416.         mov    ExeESP, edi
  417.         add    edi, EData.Base
  418.         sub    edi, ThisDataBase
  419.         mov    [edi], eax
  420.         ret
  421. PushToExeStack    endp
  422.  
  423. SetArgP        proc    near
  424.         movzx    ecx, ArgLen
  425.         mov    edi, ArgP
  426.         mov    ebx, EData.Base
  427.         sub    ebx, ThisDataBase
  428.         sub    esi, esi    ;argc
  429.         sub    eax, eax    ;separator & NULL
  430.         dec    edi
  431. MoreArgs:
  432.         jcxz    PushToExeStack    ;eax==0 to stack
  433. SkipZeros:    inc    edi
  434.         prefix32
  435.         cmp    byte ptr [edi][ebx], 0
  436.         loope    SkipZeros    ;eax==0 to stack
  437.         jcxz    PushToExeStack
  438.         push    edi        ;remember the vaddr beginning
  439.         inc    esi        ;++argc
  440. SkipArg:    inc    edi
  441.         prefix32
  442.         cmp    byte ptr [edi][ebx], 0
  443.         loopne    SkipArg
  444.         call    MoreArgs
  445.         pop    eax        ;restore the argument pointer
  446.         jmp    PushToExeStack    ;push it
  447.         endp
  448. ;
  449. ;
  450. cpu_setup32    proc    near
  451.         mov    ax, _DATA
  452.         mov    ds, ax
  453.         mov    es, ax
  454.         mov    fs, ax
  455.         mov    gs, ax
  456.         cwde    
  457.         shl    eax, 4
  458.         SetDesc    ThisData, eax, 0ffffffffh
  459.         jmp    cpu_setup
  460.         endp
  461.  
  462. cpu_setup16    proc    near
  463.         mov    ax, _DATA
  464.         mov    ds, ax
  465.         mov    es, ax
  466.         mov    ThisData.Granularity, 0    ; G=0, default = 16bit
  467.         mov    ThisData.Limit_0_15, 0ffffh
  468.         jmp    cpu_setup
  469.         endp
  470.  
  471.  
  472.         .386P
  473. cpu_setup    proc    near
  474.         mov    ax, _DATA
  475.         cwde
  476.         shl    eax, 4
  477.         add    eax, offset GDT
  478.         mov    GDTBase, eax
  479.         cli
  480.         lgdt    GDTLimitBase        ;global descriptor table
  481.  
  482.         mov    eax, CR0
  483.         or    al, 11h            ; keep ET bit as it is
  484.         and    al, NOT 0eh
  485.         mov    CR0, eax        ;protection on
  486.         jmp    $+2
  487.         nop
  488.         nop
  489.         mov    ax, ThisDataSel        ;select ThisData
  490.         mov    ds, ax
  491.         mov    es, ax
  492.         mov    fs, ax
  493.         mov    gs, ax
  494.  
  495.         mov    eax, CR0
  496.         and    al, NOT 1
  497.         mov    CR0, eax        ;enter REAL mode
  498.  
  499.         db    0eah            ;far jump to Flush
  500.         dw    __Flush
  501.         dw    _TEXT
  502. __Flush:
  503.         mov    ax, _DATA        ;all segments to .data
  504.         mov    ds, ax
  505.         mov    es, ax
  506.         mov    fs, ax
  507.         mov    gs, ax
  508.         xor    eax,eax
  509.         mov    edx, eax
  510.         mov    ebx, eax
  511.         mov    ecx, eax
  512.         ret
  513.         endp
  514.         
  515.         .386
  516.         extrn    memoryconfig:near
  517.         extrn    memscan:near, memmax:near
  518.  
  519. .HimemInvalid    label    near
  520.         push    ds
  521.         mov    ax, _DATA
  522.         mov    ds, ax
  523.         mov    dx, offset MemValidQ
  524.         call    Msg
  525.         call    getchar
  526.         and    al, 1101111B
  527.         cmp    al, 'Y'
  528.         pop    ds
  529.         
  530.         je    .HimemValid
  531. IF FMR70        
  532.         call    a20_off
  533. ENDIF
  534.         mov    ax, 4c02h
  535.         int    21h
  536. ;
  537. IF FMR70
  538.         .386P
  539. SetCPU        proc    near
  540.         mov    ax, _DATA
  541.         mov    ds, ax
  542.         mov    es, ax
  543.  
  544.         or    ThisCode.Granularity, 8fh
  545.         or    ThisData.Granularity, 8fh
  546.  
  547.         cwde            ;base for GDT
  548.         shl    eax, 4
  549.         add    eax, offset GDT
  550.         mov    GDTBase, eax
  551.  
  552.         mov    ax, cs        ;.code
  553.         shl    ax, 4
  554.         mov    ThisCode.Base_0_15, ax
  555.         mov    ax, cs
  556.         shr    ax, 12
  557.         mov    ThisCode.Base_16_23, al
  558.  
  559.         mov    ax, ds        ;.data
  560.         shl    ax, 4
  561.         mov    ThisData.Base_0_15, ax
  562.         mov    ax, ds
  563.         shr    ax, 12
  564.         mov    ThisData.Base_16_23, al
  565.  
  566.         cli
  567.         lgdt    GDTLimitBase        ;global descriptor table
  568.  
  569.         mov    eax, CR0
  570.         or    al, 11h
  571.         and    al, NOT 0eh
  572.         mov    CR0, eax        ;protection on
  573.         fjmp    ThisCodeSel, set_prot
  574. set_prot:
  575.         mov    ax, ThisDataSel        ;select ThisData
  576.         mov    ds, ax
  577.         mov    es, ax
  578.         mov    fs, ax
  579.         mov    gs, ax
  580.  
  581.         mov    eax, CR0
  582.         and    al, NOT 1
  583.         mov    CR0, eax        ;enter REAL mode
  584.  
  585.         fjmp    _TEXT, set_flush
  586.         .386
  587. set_Flush:
  588.         mov    ax, _DATA        ;all segments to .data
  589.         mov    ds, ax
  590.         mov    es, ax
  591.         mov    fs, ax
  592.         mov    gs, ax
  593.         ret
  594.         endp
  595. ENDIF
  596.  
  597. .Nomemory    proc    near
  598.         mov    ax, 4c09h
  599.         int    21h
  600.         endp
  601. ;
  602. ;    Main entry
  603. ;
  604. Start        proc    near
  605.         push    ds
  606.         
  607. IF FMR70
  608.         call    setCPU
  609. ENDIF
  610.         call    a20_on
  611. IF PCAT
  612.         call    cpu_setup32
  613. ENDIF
  614.         call    MemoryConfig
  615. IF FMR70
  616.         call    a20_off
  617. ENDIF
  618.         pop    ds
  619.         mov    ax, ds
  620.         mov    es, ax
  621.         jc    .HimemInvalid
  622. .initCOM:
  623. IF  PCAT
  624.         mov    ah, 0
  625.         mov    dx, CommPort          ; use com0:
  626.         mov    al, 11100011b        ; 9600bps,nop,1stop,8bit
  627.         int    14h
  628. ENDIF
  629. IF  FMR70
  630. ENDIF
  631. .HimemValid:        
  632.         mov    bx, 80h
  633.         mov    byte ptr [bx][7fh], ' '
  634.         movzx    cx, byte ptr[bx]
  635.         inc    cx
  636.         push    cx
  637.         cmp    cx, 1
  638.         ja    SpaceThem
  639.         mov    ax, _DATA
  640.         mov    ds, ax
  641.         jmp    .no_parm
  642. SpaceThem:
  643.         inc    bx            ;81h
  644.         cmp    byte ptr [bx], ' '
  645.         ja    IsChar
  646.         mov    byte ptr [bx], ' '
  647. IsChar:        loop    SpaceThem
  648.         pop    ax
  649.         push    ax
  650.         
  651.         mov    cx, 07fh
  652.         sub    cx, ax
  653. ZeroThem:
  654.         mov    byte ptr[bx], ' '
  655.         inc    bx
  656.         loop    ZeroThem
  657.         
  658.         pop    cx
  659.         push    cx
  660.  
  661.         cmp    cx, MAXFILENAME
  662.         jbe    NameLenOK
  663.         mov    cx, MAXFILENAME
  664. NameLenOK:
  665.         mov    di, 81h
  666.         mov    al, ' '
  667.     repe    scasb
  668.  
  669.         mov    ax, _DATA
  670.         mov    es, ax
  671.         mov    es: PSP, ds
  672.         pop    ax
  673.         mov    es: ArgLen, al
  674.         
  675.         lea    si, [di-1]
  676.         mov    di, offset FileName
  677. ;
  678. .copyPname:
  679.         movsb    
  680.         cmp    byte ptr[si], ' '
  681.         loopne    .copyPname
  682.         mov    al, 0
  683.         stosb
  684. ;
  685. ;  copy param into psp-work. 7-17
  686. ;
  687.         push    di
  688.         push    si
  689.         
  690.         lea    di, PSPwork[129]
  691.         mov    cx, 128
  692.     rep    movsb
  693.         lea    di, PSPwork
  694.         mov    cx, 129
  695.         mov    si, 0
  696.     rep    movsb
  697.         pop    si
  698.         pop    di
  699. ;
  700.         mov    ax, es
  701.         mov    ds, ax
  702.  
  703. IF    Testing
  704.         mov    dx, offset HelloS
  705.         call    Msg
  706. ENDIF
  707. ;
  708. ; Store my (=this program) own environment.
  709. ;
  710.         mov    ThisSS, ss
  711.         mov    ThisSP, sp
  712.  
  713.         mov    ax, cs        ;.code
  714.         cwde
  715.         shl    eax, 4
  716.         mov    ThisCodeBase, eax
  717.  
  718.         mov    ax, ds        ;.data
  719.         cwde
  720.         shl    eax, 4
  721.         mov    ThisDataBase, eax
  722. ;
  723. ; Store/setup program's environment
  724. ;
  725. ;
  726.         mov    eax, MEM_LO
  727.         mov    ECode.Base, eax
  728.         mov    EData.Base, eax
  729.         mov    EBSS.Base, eax
  730.         mov    ECode.Lo, 0
  731.         mov    EData.Lo, 0
  732.         mov    EBSS.Lo,  0
  733.         mov    esi, eax
  734.         call    MemMax
  735. IF FMR70
  736.         call    a20_off
  737. ENDIF        
  738.         push    esi
  739.         sub    esi, ECode.Base
  740.         mov    ECode.Hi, esi
  741.         pop    esi
  742.         
  743.         sub    esi, EData.Base
  744.         mov    EData.Hi, esi
  745.         mov    EBSS.Hi,  esi
  746. ;        
  747.         sub    esi, PageSize - 3
  748.         and    esi, not 3
  749.         mov    ExeESP, esi
  750. ;90-7-8
  751.         mov    ax, ds
  752.         movzx    eax, ax
  753.         shl    eax, 4
  754.         add    eax, (offset PSPwork) 
  755.         mov    ProgPSP.Base, eax
  756. ;
  757. ;  setup EnvSeg and contents of psp  
  758. ;
  759.         push    ds
  760.         mov    ax, _DATA
  761.         mov    es, ax
  762.         lea    di, PSPwork
  763.         mov    ds, es: PSP        ; my PSP segment
  764.         mov    si, psp_envseg        ; my ENV segment
  765.         mov    si, [si]
  766.         mov    es:EnvSeg, si
  767.         pop    ds
  768.  
  769. ;
  770. ; setup param field
  771. ;
  772.         mov    si, offset PSPwork + 128
  773.         lodsb
  774.         movzx    cx, al
  775. ;
  776. ; Store/setup  PSP
  777. ;        
  778.         movzx    eax, EnvSeg
  779.         shl    eax, 4
  780.         mov    ProgEnv.Base, eax
  781.         mov    ProgEnv.Hi, 2048        ; Temporal patch
  782.  
  783. ;        call    CopyArg
  784.  
  785. ;
  786. ; Set up parameter to program
  787. ;
  788.         or    esi, esi    ;argc
  789.         jnz    SaveArgc
  790. .no_parm:
  791.         mov    dx, offset UsageS
  792.         call    Msg            ;
  793.         jmp    OSExit            ; <-- We need OsExit function
  794.  
  795. SaveArgc:
  796.         xchg    eax, esi
  797. IF FMR70
  798.         call    a20_on
  799. ENDIF
  800.         call    PushToExeStack        ;push argc
  801.         call    OpenExe
  802.         call    ReadFOHdr
  803.         call    ReadSHdr
  804. IF FMR70
  805.         call    a20_off
  806. ENDIF        
  807.         public    TP_load
  808. TP_load        label    near
  809.         mov    ax, _DATA
  810.         mov    ds, ax
  811.  
  812. ;
  813. ; clear BSS
  814. ;        
  815.         mov    edi, EBSS.Lo
  816.         add    edi, EBSS.Base
  817.         sub    edi, ThisDataBase
  818. ;        mov    ecx, ahdr.bsize
  819.         movzx    ecx, fhdr.f_minalloc
  820.         shl    ecx, 12
  821. IF FMR70
  822.         call    a20_on
  823. ENDIF
  824.         mov    al, 0
  825.         prefix32        ;32-bit addrs
  826.     rep    stosb            ;zero bss
  827.  
  828. IF FMR70
  829.         call    a20_off
  830. ENDIF
  831.         mov    ax, ds        ;base for GDT
  832.         cwde
  833.         shl    eax, 4
  834.         add    eax, offset GDT
  835.         mov    GDTBase, eax
  836.  
  837.         mov    ax, ds        ;base for IDT
  838.         cwde
  839.         shl    eax, 4
  840.         add    eax, offset IDT
  841.         mov    IDTBase, eax
  842.  
  843.         mov    ax, ds        ;base for LDT
  844.         cwde
  845.         shl    eax, 4
  846.         add    eax, offset LDT
  847.         mov    LDTBase, eax
  848.  
  849.         mov    eax, COMMUNICATION ;base for communication
  850.         shl    eax, 4
  851.         mov    CommDataBase, eax
  852.  
  853.         SetDesc    LDTDesc,  LDTBase, LDTLimit
  854.         SetDesc    GDTDesc,  GDTBase, GDTLimit
  855.         SetDesc    ExeCode,  ECode.Base, ECode.Hi
  856.         SetDesc    ExeData,  EData.Base, EData.Hi
  857.         SetDesc    ThisCode, ThisCodeBase, 0fffffh
  858. ;
  859. ; we use ThisData to access both thisdata and ExeData,
  860. ; so, it's limit must be enogh (very large) value.
  861. ;
  862.         SetDesc    ThisData, ThisDataBase, 0ffffffffh
  863.         SetDesc    CommData, CommDataBase, CommLimit
  864.         SetDesc LSEG_PSP2,ProgPSP.Base, 512
  865.         SetDesc LSEG_ENV, ProgENV.Base, ProgENV.Hi
  866.  
  867.         mov    eax, fhdr.f_eip
  868.         mov    [EntryEIP], eax
  869. IF FMR70
  870.         call    a20_off
  871. ENDIF
  872. ;
  873. ; show memory allocation
  874. ;
  875. IF    Testing
  876.         mov    dx, offset GDTBaseS
  877.         call    Msg
  878.         mov    eax, GDTBase
  879.         call    Hex32
  880.  
  881.         mov    dx, offset LDTBaseS
  882.         call    Msg
  883.         mov    eax, LDTBase
  884.         call    Hex32
  885.  
  886.         mov    dx, offset IDTBaseS
  887.         call    Msg
  888.         mov    eax, IDTBase
  889.         call    Hex32
  890.  
  891.         mov    dx, offset ExeCodeS
  892.         call    Msg
  893.         mov    eax, ECode.Base
  894.         call    Hex32
  895.  
  896.         mov    dx, offset ExeDataS
  897.         call    Msg
  898.         mov    eax, EData.Base
  899.         call    Hex32
  900.  
  901.         mov    dx, offset ExeEntry
  902.         call    Msg
  903.         mov    eax, EntryEIP
  904.         call    Hex32
  905.  
  906.         mov    dx, offset ExeLimits
  907.         call    Msg
  908.         mov    eax, ECode.Hi
  909.         call    Hex32
  910.  
  911.         mov    eax, EData.Hi
  912.         call    Hex32s
  913.  
  914.         mov    eax, EBss.Hi
  915.         call    Hex32s
  916.  
  917.         mov    dx, offset ThisCodeS
  918.         call    Msg
  919.         mov    eax, ThisCodeBase
  920.         call    Hex32
  921.  
  922.         mov    dx, offset ThisDataS
  923.         call    Msg
  924.         mov    eax, ThisDataBase
  925.         call    Hex32
  926.  
  927.         mov    dx, offset ProtectedS
  928.         call    Msg
  929.         
  930.         pop    es
  931.         
  932.  
  933.         call    getchar
  934. IF FMR70
  935.         call    a20_on
  936. ENDIF
  937.         cmp    al, 'c'
  938.         jnz    .st_mode1
  939.         or    DebugFlag, MASK Sys_Out_COM
  940. .st_mode1:        
  941.         cmp    al, 'r'
  942.         jnz    .st_mode2
  943.         or    DebugFlag, MASK Deb_Trace_Reg
  944. .st_mode2:
  945.         cmp    al, ' '
  946.         jnz    .st_mode3
  947.         mov    DebugFlag, 0
  948.         mov    TraceCount, 0
  949.         jmp    .st_modex
  950. .st_mode3:
  951.         and    al, 1fh
  952.         mov    ah, 0
  953.         mov    TraceCount, ax
  954. .st_modex:
  955. ENDIF
  956.  
  957. IF    0
  958. IF    Trace OR I7
  959.         push    ds
  960.         sub    bx, bx
  961.         mov    ds, bx
  962. IF    Trace
  963.         mov    word ptr [bx][1*4+0], offset Int1
  964.         mov    word ptr [bx][1*4+2], cs
  965.         mov    word ptr [bx][3*4+0], offset Int3
  966.         mov    word ptr [bx][3*4+2], cs
  967. ENDIF
  968. IF    I7
  969.         mov    word ptr [bx][7*4+0], offset Int7
  970.         mov    word ptr [bx][7*4+2], cs
  971. ENDIF
  972. IF    I2
  973.         mov    word ptr [bx][2*4+0], offset Int2
  974.         mov    word ptr [bx][2*4+2], cs
  975. ENDIF
  976.         pop    ds
  977. ENDIF
  978. ENDIF
  979. ;        test    DebugFlag, MASK Deb_Trap_DOS
  980. ;        jz    .notrap
  981.         call    Copy_original
  982.  
  983. IF PCAT
  984.         call    CopyVectors
  985.         mov    ah, 50h
  986.         call    P8259
  987. ENDIF
  988.         public    TP_Vect
  989. TP_Vect        label    near
  990. IF FMR70
  991.         call    a20_on
  992. ENDIF
  993.  
  994.         .386P
  995. ;;IF      WithFPU                ; with or without FPU
  996.         fninit
  997.         fstcw    Control387
  998.         fwait
  999.         or    Control387, 3fh
  1000.         fldcw    Control387
  1001.         fclex
  1002.         fsetpm
  1003. ;;ENDIF
  1004.         cli
  1005.         lidt    IDTLimitBase        ;interrupt descriptor table
  1006.         lgdt    GDTLimitBase        ;global descriptor table
  1007.         mov    eax, CR0
  1008.         or    al, ONCR0
  1009.         and    al, OFFCR0
  1010.         mov    CR0, eax        ;protection on
  1011.         fjmp    ThisCodeSel, ToProtection
  1012.         endp
  1013.         
  1014. ToProtection    proc    far
  1015.         mov    ax, LDTSel
  1016.         lldt    ax            ;local descriptor table
  1017.         mov    ax, ThisDataSel
  1018.         mov    ds, ax
  1019.         
  1020.         mov    [TraceCount],0
  1021.         lss    esp, ExeSSESP
  1022.         mov    ax, ExeDataSel
  1023.         mov    ds, ax
  1024.         mov    es, ax
  1025.         mov    gs, ax
  1026.         mov    fs, ax
  1027.         sti
  1028. IF    Trace
  1029.         pushf
  1030.         or    word ptr [esp], 100h
  1031.         popf
  1032.         
  1033. ENDIF
  1034.         jmp    cs:[EntryPointer]    ;do image
  1035.         endp
  1036. ;
  1037. ; fault trap
  1038. ;
  1039. IRout        macro    n
  1040. Int&n        proc    near
  1041.         pushad
  1042.         mov    dx, offset Int&n&S
  1043.         jmp    CommonTrap
  1044. Int&n        endp
  1045.         endm
  1046.  
  1047. CommonTrap    proc    near
  1048.         mov    ax, _DATA
  1049.         mov    ds, ax
  1050.         call    Msg
  1051.         mov    dx, offset RegS
  1052.         call    Msg
  1053.         mov    bp, sp
  1054.         add    bp, 7*4
  1055.         mov    cx, 8
  1056.  
  1057. PrintRegs:    mov    eax, [bp]
  1058.         call    Hex32S
  1059.         sub    bp, 4
  1060.         loop    PrintRegs
  1061.  
  1062.         mov    ErrorOffset, 4
  1063.         call    PrintTrace
  1064.         call    PrintStack
  1065.         mov    eax, CR0
  1066.         jmp    OSExit
  1067. CommonTrap    endp
  1068. ;
  1069. PrintStack    proc    near
  1070.         push    esi
  1071.         push    ecx
  1072.         push    eax
  1073.         mov    esi, SavedESP
  1074.         call    CRLF
  1075.         mov    ax, SavedSS
  1076.         test    al, 04
  1077.         jz    .prints1
  1078.         push    ax
  1079. ;        mov    al,'L'
  1080. ;        call    putchar
  1081.         pop    ax
  1082.         add    esi, EData.base
  1083.         sub    esi, ThisDataBase
  1084. .prints1:
  1085. ;        les    eax, SavedSSESP
  1086. ;        call    printPointer
  1087. ;
  1088.         mov    dx, offset msg_stack
  1089.         call    Msg
  1090.         cld
  1091.         prefix32
  1092.         lodsw
  1093.         call    Hex
  1094.         mov    cx, 5
  1095. .prints2:
  1096.         prefix32
  1097.         lodsw 
  1098.         call    Hexs
  1099.         loop    .prints2
  1100.         mov    cx, 5
  1101. .prints3:
  1102.         prefix32
  1103.         lodsd 
  1104.         call    Hex32s
  1105.         loop    .prints3
  1106.         pop    eax
  1107.         pop    ecx
  1108.         pop    esi
  1109.         ret
  1110. PrintStack    endp
  1111.  
  1112.         IRout    0
  1113.         IRout    2
  1114.         IRout    4
  1115.         IRout    5
  1116.         IRout    6
  1117.         IRout    7
  1118.         IRout    8
  1119.         IRout    9
  1120.         IRout    10
  1121.         IRout    11
  1122.         IRout    12
  1123.         IRout    13
  1124.         IRout    14
  1125.         IRout    15
  1126.         IRout    16
  1127.         IRout    117        ; 75h = NDP trap
  1128.  
  1129. PutReg        proc    near
  1130.         mov    ebp,esp
  1131.         mov    ecx,16
  1132. putreg1:        
  1133.         mov    eax, [ebp]
  1134.         call    Hex32S
  1135.         add    ebp, 4
  1136.         loop    putreg1
  1137.  
  1138.         call    CRLF
  1139.         ret
  1140. PutReg        endp
  1141.         
  1142.         extrn    Int1:near, Int3:near
  1143.  
  1144. ;Come here thru Interrupt gate N
  1145.  
  1146.         .386P
  1147. IntrN        macro    n
  1148. Intr&n:        push    ds            ;B-bit set, use ESP
  1149.         push    es
  1150.         push    fs
  1151.         push    gs
  1152.         push    eax
  1153.         mov    ax,ThisDataSel        ;select ThisData
  1154.         mov    ds, ax
  1155.         pop    eax
  1156.         
  1157.         mov    SavedIntN, n        ;remeber interrupt #
  1158.         jmp    near ptr IntServer
  1159.         endm
  1160.  
  1161. TrapN        macro    n
  1162. Intr&n:        push    ds            ;B-bit set, use ESP
  1163.         push    es
  1164.         push    fs
  1165.         push    gs
  1166. ; test 12:00        
  1167.         push    eax
  1168.         mov    ax, ThisDataSel        ;select ThisData
  1169.         mov    ds, ax
  1170.         pop    eax
  1171.         
  1172.         mov    SavedIntN, offset Int&n    ;remeber interrupt #
  1173.         jmp    near ptr TrapServer
  1174.         endm
  1175.  
  1176. x        =    0
  1177.         rept    10h-0h+1
  1178.         TrapN    %x
  1179. x        =    x+1
  1180.         endm
  1181.  
  1182.         rept    20h-11h+1    ;11h..20h
  1183.         IntrN    %x
  1184. x        =    x+1
  1185.         endm
  1186.  
  1187. ;        IntrN    33
  1188.  
  1189. x        =     22h        ;x becomes 22h
  1190.         rept    3fh-22h+1    ;22h..74h
  1191.         IntrN    %x
  1192. x        =    x+1
  1193.         endm
  1194.  
  1195. x        =     40h        ;x becomes 22h
  1196.         rept    4fh-40h+1
  1197.         IntrN    %x
  1198. x        =    x+1
  1199.         endm
  1200.  
  1201. x        =     50h        ;x becomes 22h
  1202.         rept    74h-50h+1    ;22h..74h
  1203.         IntrN    %x
  1204. x        =    x+1
  1205.         endm
  1206.         
  1207.         TrapN    117
  1208.  
  1209. x        =    76h
  1210.         rept    0ffh-76h+1
  1211.         IntrN    %x
  1212. x        =    x+1
  1213.         endm
  1214.  
  1215.         .386P
  1216. IntServer    proc    far
  1217.         mov    SavedSS, ss        ;remember Image's stack
  1218.         mov    SavedESP, esp
  1219.         mov    SavedEAX, eax        ;store
  1220.         mov    ax, ds
  1221.         mov    es, ax            ;all segments to ThisData
  1222.         mov    ss, ax
  1223.         mov    fs, ax
  1224.         mov    gs, ax
  1225.  
  1226.         mov    eax, CR0
  1227.         and    al, NOT 1
  1228.         mov    CR0, eax        ;enter REAL mode
  1229.  
  1230.         fjmp    _TEXT, Flush
  1231.  
  1232. Flush        label    far
  1233.         mov    ax, _DATA        ;all segments to .data
  1234.         mov    ds, ax
  1235.         mov    gs, ax
  1236.  
  1237.         mov    ax, COMMUNICATION
  1238.         mov    es, ax
  1239.         assume    es: COMMUNICATION
  1240.  
  1241.         mov    ax, 0            ;except fs to 0
  1242.         mov    fs, ax
  1243.         lidt    RMIDTLimitBase        ;real mode interrupts
  1244.         lss    esp, ThisSSESP
  1245.         mov    ax, SavedIntN        ;get intr index
  1246.         cwde
  1247.         mov    ds, ToDosDS
  1248.         mov    es, ToDosES
  1249.         pushf                ;emulate int
  1250.         push    cs
  1251.         push    offset RetI
  1252.         push    dword ptr fs: [4*eax]    ;push address of int. routine
  1253.         mov    eax, gs: SavedEAX    ;restore EAX
  1254.         ret                ;goto int routine
  1255. IntServer    endp
  1256. ;
  1257. ;come here from int routine n
  1258. ;
  1259. RetI        proc    far
  1260.         cli
  1261.         push    COMMUNICATION
  1262.         pop    fs
  1263.         mov    fs: FromDosDS, ds
  1264.         mov    fs: FromDosES, es
  1265.         push    _DATA
  1266.         pop    ds
  1267.         mov    SavedEAX, eax
  1268.  
  1269.         lidt    IDTLimitBase        ;protected mode ints
  1270.         lgdt    GDTLimitBase
  1271.  
  1272.         mov    eax, CR0        ;enter protected mode
  1273.         or    al, ONCR0
  1274.         and    al, OFFCR0
  1275.         mov    CR0, eax
  1276.         fjmp    ThisCodeSel, Protected
  1277.         
  1278.         .386P
  1279. Protected:    mov    ax, LDTSel
  1280.         lldt    ax            ;local descriptors
  1281.         mov    ax, ThisDataSel        ;ThisData
  1282.         mov    ds, ax
  1283.         mov    eax, SavedEAX
  1284.         lss    esp, SavedSSESP        ;restore image's stack
  1285. ; B-bit now set, use ESP
  1286.         pop    gs            ;restore segment registers
  1287.         pop    fs
  1288.         pop    es
  1289.         pop    ds
  1290.         iretd                ;return to image
  1291. RetI        endp
  1292.  
  1293.         .386P
  1294. TrapServer    proc    far
  1295.         mov    SavedSS, ss        ;remember Image's stack
  1296.         mov    SavedESP, esp
  1297.         mov    SavedEAX, eax        ;store
  1298.         mov    ax, ds
  1299.         mov    es, ax            ;all segments to ThisData
  1300.         mov    fs, ax
  1301.         mov    gs, ax
  1302. comment %
  1303. IF TransPort        
  1304.         push    edi
  1305.         push    esi
  1306.         push    ebp
  1307.         push    ebx
  1308.         mov    edi, offset stack_log
  1309.         mov    ebx, 0
  1310.         cld
  1311.         mov    eax, ebp
  1312.         stosd
  1313. .trap_ss1:        
  1314.         mov    eax, ss:[ebp + ebx*4]
  1315.         stosd
  1316.         inc    bx
  1317.         cmp    bx, 1fh
  1318.         jb    .trap_ss1
  1319.         pop    ebx
  1320.         pop    ebp
  1321.         pop    esi
  1322.         pop    edi
  1323. ENDIF
  1324. %
  1325.         mov    ss, ax
  1326.         mov    eax, CR0
  1327.         and    al, NOT 1
  1328.         mov    CR0, eax        ;enter REAL mode
  1329.  
  1330.         fjmp    _TEXT, TrapFlush
  1331.  
  1332. TrapFlush    label    far
  1333.         mov    ax, _DATA        ;all segments to .data
  1334.         mov    ds, ax
  1335.         mov    es, ax
  1336.         mov    fs, ax
  1337.         mov    gs, ax
  1338.         lss    esp, ThisSSESP
  1339.  
  1340.         lidt    RMIDTLimitBase        ;real mode interrupts
  1341.  
  1342.         sti
  1343.         mov    eax, SavedEAX
  1344.         call    SavedIntN        ;call the routine
  1345.  
  1346.         cli
  1347.  
  1348.         lidt    IDTLimitBase        ;protected mode ints
  1349.         lgdt    GDTLimitBase
  1350.  
  1351.         mov    eax, CR0        ;enter protected mode
  1352.         or    al, ONCR0
  1353.         and    al, OFFCR0
  1354.         mov    CR0, eax
  1355.         fjmp    ThisCodeSel, TrapProtected
  1356.  
  1357.         .386P
  1358. TrapProtected:    mov    ax, LDTSel
  1359.         lldt    ax            ;local descriptors
  1360.         mov    ax, ThisDataSel        ;ThisData
  1361.         mov    ds, ax
  1362.         mov    eax, SavedEAX
  1363.         lss    esp, SavedSSESP        ;restore image's stack
  1364. ;
  1365. ; B-bit now set, use ESP
  1366. ;
  1367.         pop    gs            ;restore segment registers
  1368.         pop    fs
  1369.         pop    es
  1370.         pop    ds
  1371.         iretd                ;return to image
  1372. TrapServer    endp
  1373.  
  1374.  
  1375. ;
  1376. ;
  1377. ; int 21 from protected mode
  1378. ; Hardware interrupt may occure while CPU executing this routine.
  1379. ; So, we must not share save area with other interrupt handlers.
  1380. ;
  1381.         .386P
  1382. DosServer    proc    far
  1383. Intr33        label    far
  1384.         push    ds
  1385.         push    es
  1386.         push    fs
  1387.         push    gs
  1388.         push    eax
  1389.  
  1390. ; setup accessability        
  1391.         cli
  1392. ;
  1393.         mov    ax, ThisDataSel
  1394.         mov    ds, ax
  1395.         mov    es, ax
  1396. ;
  1397. ; save registers
  1398. ;
  1399.         pop    eax
  1400.  
  1401.         mov    ExeEAX, eax
  1402.         mov    eax, [esp].sp_eip
  1403.         mov    ExeEIP, eax
  1404.         mov    ax, [esp].sp_cs
  1405.         mov    ExeCS,  ax
  1406.         mov    eax, [esp].sp_flag
  1407.         mov    SavedFlags, eax
  1408.         mov    ExeESP, esp
  1409.         mov    ExeSS,  ss
  1410. ;        
  1411.         mov    ax, ds
  1412.         mov    ds, ax
  1413.         mov    es, ax
  1414.         mov    fs, ax
  1415.         mov    gs, ax
  1416.         mov    ss, ax
  1417. ;
  1418.         mov    eax, CR0
  1419.         and    al, NOT 1
  1420.         mov    CR0, eax
  1421. ;
  1422.         extrn    DosFlush:far
  1423.         fjmp    _TEXT, DosFlush
  1424.         endp
  1425.  
  1426.         public    dosprotected
  1427. DosProtected    proc    far
  1428.         mov    ax, LDTsel
  1429.         lldt    ax
  1430.         mov    ax, ThisDataSel
  1431.         mov    ds, ax
  1432.         mov    es, ax
  1433. ;
  1434. ; labeled just for temporaly
  1435. ;
  1436.         lss    esp, ExeSSESP
  1437.         mov    eax, SavedFlags
  1438.         mov    ss:[esp].sp_flag,eax
  1439.         mov    eax, ExeEAX
  1440.         pop    gs
  1441.         pop    fs
  1442.         pop    es
  1443.         pop    ds
  1444.         sti
  1445.         iretd
  1446.         endp
  1447.  
  1448. _TEXT        ends
  1449.         end    Start
  1450.