]> 4ch.mooo.com Git - 16.git/blobdiff - 16/sod8086/c0.bak
got 8086 port of wolf3d to work and sod to work
[16.git] / 16 / sod8086 / c0.bak
diff --git a/16/sod8086/c0.bak b/16/sod8086/c0.bak
new file mode 100755 (executable)
index 0000000..8adb36b
--- /dev/null
@@ -0,0 +1,843 @@
+        NAME    c0\r
+        PAGE    60,132\r
+        LOCALS\r
+;[]------------------------------------------------------------[]\r
+;|      C0.ASM -- Start Up Code                                 |\r
+;|                                                              |\r
+;|      Turbo C++ Run Time Library                              |\r
+;|                                                              |\r
+;|      Copyright (c) 1987, 1991 by Borland International Inc.  |\r
+;|      All Rights Reserved.                                    |\r
+;[]------------------------------------------------------------[]\r
+\r
+                __C0__ = 1\r
+INCLUDE         RULES.ASI\r
+\r
+;       Segment and Group declarations\r
+\r
+_TEXT           SEGMENT BYTE PUBLIC 'CODE'\r
+                ENDS\r
+_FARDATA        SEGMENT PARA PUBLIC 'FAR_DATA'\r
+                ENDS\r
+_FARBSS         SEGMENT PARA PUBLIC 'FAR_BSS'\r
+                ENDS\r
+IFNDEF __TINY__\r
+_OVERLAY_       SEGMENT PARA PUBLIC 'OVRINFO'\r
+        ENDS\r
+_1STUB_     SEGMENT PARA PUBLIC 'STUBSEG'\r
+        ENDS\r
+ENDIF\r
+_DATA           SEGMENT PARA PUBLIC 'DATA'\r
+                ENDS\r
+_INIT_          SEGMENT WORD PUBLIC 'INITDATA'\r
+InitStart       label byte\r
+                ENDS\r
+_INITEND_       SEGMENT BYTE PUBLIC 'INITDATA'\r
+InitEnd         label byte\r
+                ENDS\r
+_EXIT_          SEGMENT WORD PUBLIC 'EXITDATA'\r
+ExitStart       label byte\r
+                ENDS\r
+_EXITEND_       SEGMENT BYTE PUBLIC 'EXITDATA'\r
+ExitEnd         label byte\r
+                ENDS\r
+_CVTSEG         SEGMENT WORD PUBLIC 'DATA'\r
+                ENDS\r
+_SCNSEG         SEGMENT WORD PUBLIC 'DATA'\r
+                ENDS\r
+IFNDEF __HUGE__\r
+  _BSS          SEGMENT WORD PUBLIC 'BSS'\r
+                ENDS\r
+  _BSSEND       SEGMENT BYTE PUBLIC 'BSSEND'\r
+                ENDS\r
+ENDIF\r
+IFNDEF __TINY__\r
+  _STACK        SEGMENT STACK 'STACK'\r
+                ENDS\r
+ENDIF\r
+\r
+        ASSUME  CS:_TEXT, DS:DGROUP\r
+\r
+;       External References\r
+\r
+extrn       _main:DIST\r
+extrn       _exit:DIST\r
+extrn       __exit:DIST\r
+extrn       __nfile:word\r
+extrn       __setupio:near          ;required!\r
+extrn       __stklen:word\r
+IF LDATA EQ false\r
+extrn       __heaplen:word\r
+ENDIF\r
+\r
+        SUBTTL  Start Up Code\r
+        PAGE\r
+;/*                                                     */\r
+;/*-----------------------------------------------------*/\r
+;/*                                                     */\r
+;/*     Start Up Code                                   */\r
+;/*     -------------                                   */\r
+;/*                                                     */\r
+;/*-----------------------------------------------------*/\r
+;/*                                                     */\r
+PSPHigh         equ     00002h\r
+PSPEnv          equ     0002ch\r
+PSPCmd          equ     00080h\r
+\r
+                public  __AHINCR\r
+__AHINCR        equ     1000h\r
+                public  __AHSHIFT\r
+__AHSHIFT       equ     12\r
+\r
+IFDEF   __NOFLOAT__\r
+MINSTACK        equ     128     ; minimal stack size in words\r
+ELSE\r
+MINSTACK        equ     256     ; minimal stack size in words\r
+ENDIF\r
+;\r
+;       At the start, DS and ES both point to the segment prefix.\r
+;       SS points to the stack segment except in TINY model where\r
+;       SS is equal to CS\r
+;\r
+_TEXT           SEGMENT\r
+IFDEF           __TINY__\r
+                ORG     100h\r
+ENDIF\r
+STARTX          PROC    NEAR\r
+;       Save general information, such as :\r
+;               DGROUP segment address\r
+;               DOS version number\r
+;               Program Segment Prefix address\r
+;               Environment address\r
+;               Top of far heap\r
+\r
+IFDEF   __TINY__\r
+                               mov     dx, cs          ; DX = GROUP Segment address\r
+ELSE\r
+                               mov     dx, DGROUP      ; DX = GROUP Segment address\r
+ENDIF\r
+IFNDEF __BOSS__\r
+                               mov     cs:DGROUP@@, dx ;  __BOSS__\r
+ENDIF\r
+                               mov     ah, 30h\r
+                               int     21h             ; get DOS version number\r
+                               mov     bp, ds:[PSPHigh]; BP = Highest Memory Segment Addr\r
+                               mov     bx, ds:[PSPEnv] ; BX = Environment Segment address\r
+                               mov     ds, dx\r
+                               mov     _version@, ax   ; Keep major and minor version number\r
+                               mov     _psp@, es       ; Keep Program Segment Prefix address\r
+                               mov     _envseg@, bx    ; Keep Environment Segment address\r
+                               mov     word ptr _heaptop@ + 2, bp\r
+;\r
+;       Save several vectors and install default divide by zero handler.\r
+;\r
+                               call    SaveVectors\r
+\r
+;===================\r
+;\r
+;              IDsoft - Check to make sure that we're running on a 286 or better\r
+\r
+                               pushf                                   ; Save original flags\r
+                               xor             ax,ax                   ; Clear AX\r
+                               push    ax\r
+                               popf                                    ; Try to pop the 0\r
+                               pushf\r
+                               pop             ax                              ; Get results of popping 0 into flags\r
+                               popf                                    ; Restore original flags\r
+                               or              ax,ax\r
+                               ;begin 8086 hack\r
+                               ;jns            @@Have286               ; If no sign bit, have a 286\r
+                               jmp             @@Have286\r
+\r
+                               mov     cx, lgth_no286MSG\r
+                               mov     dx, offset DGROUP: no286MSG\r
+                               jmp             MsgExit3\r
+\r
+@@Have286:\r
+;              IDsoft - End of modifications (there's also a code segment string)\r
+;\r
+;===================\r
+\r
+IFDEF  __BOSS__\r
+; Determine if in real mode\r
+                       mov     ax,0FB42h       ; find out if DPMI loader is here\r
+               mov     bx,1            ; get info function\r
+               int     2fh             ;\r
+\r
+               push    ax              ;\r
+               mov     ax, cs          ; now, save DGROUP\r
+               add     ax, cx          ;\r
+               mov     es, ax          ;\r
+               mov     dx, ds          ;\r
+               mov     es:DGROUP@@, dx  ;\r
+               mov     es:CSalias@@, ax ;\r
+               pop     ax               ;\r
+\r
+;              cmp     ax,0001h        ; if not "TRUE"\r
+;              JNE     InRealMode\r
+\r
+; 8 is the value of the alias selector\r
+; in this system\r
+               MOV     _protected@, cx\r
+               MOV     _hugeincval@, cx\r
+               clc\r
+               mov     ax, cx\r
+               xor     cx, cx\r
+               or      ax, ax\r
+               je      @@gotshift\r
+@@shiftcnt:\r
+               rcr     ax,1\r
+               jc      @@gotshift\r
+               inc     cx\r
+               jmp     @@shiftcnt\r
+@@gotshift:\r
+               mov     _shiftcount@,cx\r
+\r
+; used by emulator\r
+;              PUSH    DS\r
+;              MOV     AX, 0E502H      ; prot kernel function, get LDT alias\r
+;              INT     21H\r
+;              POP     DS\r
+;              MOV     _LDT@, AX\r
+\r
+;              cmp     _protected@,0001h       ; if not "TRUE"\r
+;              JNE     InRealMode\r
+\r
+               .286P\r
+IFE    LDATA\r
+               mov     dx, ds                  ;\r
+;              LSL     AX, DX                  ;\r
+;              DEC     AX                      ;\r
+               MOV     AX, 0FFFEh              ;\r
+               MOV     SP, AX                  ;\r
+               MOV     SS, DX                  ;\r
+ENDIF\r
+               .8086\r
+;              JMP     BossSkip\r
+\r
+InRealMode     label   near\r
+\r
+ENDIF\r
+\r
+;       Count the number of environment variables and compute the size.\r
+;       Each variable is ended by a 0 and a zero-length variable stops\r
+;       the environment. The environment can NOT be greater than 32k.\r
+\r
+                les     di, dword ptr _envLng@\r
+                mov     ax, di\r
+                mov     bx, ax\r
+                mov     cx, 07FFFh      ; Environment cannot be > 32 Kbytes\r
+                cld\r
+@@EnvLoop:\r
+                repnz   scasb\r
+                jcxz    InitFailed      ; Bad environment !!!\r
+IFDEF __BOSS__\r
+                jmp     InitOK\r
+InitFailed:     jmp     near ptr _abort\r
+InitOK:\r
+ENDIF\r
+\r
+                inc     bx              ; BX = Nb environment variables\r
+                cmp     es:[di], al\r
+                jne     @@EnvLoop       ; Next variable ...\r
+                or      ch, 10000000b\r
+                neg     cx\r
+                mov     _envLng@, cx    ; Save Environment size\r
+                mov     cx, dPtrSize / 2\r
+                shl     bx, cl\r
+                add     bx, dPtrSize * 4\r
+                and     bx, not ((dPtrSize * 4) - 1)\r
+                mov     _envSize@, bx   ; Save Environment Variables Nb.\r
+\r
+IFNDEF __BOSS__\r
+\r
+;       Determine the amount of memory that we need to keep\r
+\r
+IFDEF _DSSTACK_\r
+                mov     dx, ds\r
+ELSE\r
+                mov     dx, ss\r
+ENDIF\r
+                sub     bp, dx          ; BP = remaining size in paragraphs\r
+IF LDATA\r
+                mov     di, seg __stklen\r
+                mov     es, di\r
+                mov     di, es:__stklen ; DI = Requested stack size\r
+ELSE\r
+                mov     di, __stklen    ; DI = Requested stack size\r
+ENDIF\r
+;\r
+; Make sure that the requested stack size is at least MINSTACK words.\r
+;\r
+                cmp     di, 2*MINSTACK  ; requested stack big enough ?\r
+                jae     AskedStackOK\r
+                mov     di, 2*MINSTACK  ; no --> use minimal value\r
+IF LDATA\r
+                mov     es:__stklen, di ; override requested stack size\r
+ELSE\r
+                mov        __stklen, di ; override requested stack size\r
+ENDIF\r
+\r
+AskedStackOK    label   near\r
+IFDEF _DSSTACK_\r
+                add     di, offset DGROUP: edata@\r
+                jb      InitFailed      ; DATA segment can NOT be > 64 Kbytes\r
+ENDIF\r
+IF LDATA EQ false\r
+                add     di, __heaplen\r
+                jb      InitFailed      ; DATA segment can NOT be > 64 Kbytes\r
+ENDIF\r
+                mov     cl, 4\r
+                shr     di, cl          ; $$$ Do not destroy CL $$$\r
+                inc     di              ; DI = DS size in paragraphs\r
+                cmp     bp, di\r
+IF LDATA EQ false\r
+                jb      InitFailed      ; Not enough memory\r
+                cmp     __stklen, 0\r
+                je      ExpandDS        ; Expand DS up to 64 Kb\r
+                cmp     __heaplen, 0\r
+                jne     ExcessOfMemory  ; Much more available than needed\r
+ExpandDS        label   near\r
+                mov     di, 1000h\r
+                cmp     bp, di\r
+                ja      ExcessOfMemory  ; Enough to run the program\r
+                mov     di, bp\r
+                jmp     short ExcessOfMemory  ; Enough to run the program\r
+ELSE\r
+                jnb     ExcessOfMemory  ; Much more available than needed\r
+ENDIF\r
+\r
+;       All initialization errors arrive here\r
+\r
+InitFailed      label   near\r
+                jmp     near ptr _abort\r
+\r
+;       Return to DOS the amount of memory in excess\r
+;       Set far heap base and pointer\r
+\r
+ExcessOfMemory  label   near\r
+                mov     bx, di\r
+                add     bx, dx\r
+                mov     word ptr _heapbase@ + 2, bx\r
+                mov     word ptr _brklvl@ + 2, bx\r
+                mov     ax, _psp@\r
+                sub     bx, ax          ; BX = Number of paragraphs to keep\r
+                mov     es, ax          ; ES = Program Segment Prefix address\r
+                mov     ah, 04Ah\r
+                push    di              ; preserve DI\r
+                int     021h            ; this call clobbers SI,DI,BP !!!!!!\r
+                pop     di              ; restore  DI\r
+\r
+                shl     di, cl          ; $$$ CX is still equal to 4 $$$\r
+\r
+                cli                     ; req'd for pre-1983 88/86s\r
+                mov     ss, dx          ; Set the program stack\r
+                mov     sp, di\r
+                sti\r
+\r
+IFNDEF _DSSTACK_\r
+                mov     ax, seg __stklen\r
+                mov     es, ax\r
+                mov     es:__stklen, di ; If separate stack segment, save size\r
+ENDIF\r
+\r
+ENDIF ; __BOSS__\r
+\r
+IFNDEF  __HUGE__\r
+\r
+;       Reset uninitialized data area\r
+\r
+                xor     ax, ax\r
+                mov     es, cs:DGROUP@@\r
+                mov     di, offset DGROUP: bdata@\r
+                mov     cx, offset DGROUP: edata@\r
+                sub     cx, di\r
+                cld\r
+                rep     stosb\r
+ENDIF\r
+\r
+;   If default number of file handles have changed then tell DOS\r
+                cmp     __nfile, 20\r
+                jbe     @@NoChange\r
+\r
+                cmp     _osmajor@, 3   ; Check for >= DOS 3.3\r
+                jb      @@NoChange\r
+                ja      @@DoChange\r
+                cmp     _osminor@, 1Eh\r
+                jb      @@NoChange\r
+@@DoChange:\r
+                mov     ax, 5801h      ; Set last fit allocation\r
+                mov     bx, 2\r
+                int     21h\r
+                jc      @@BadInit\r
+\r
+                mov     ah, 67h        ; Expand handle table\r
+                mov     bx, __nfile\r
+                int     21h\r
+                jc      @@BadInit\r
+\r
+                mov     ah, 48h        ; Allocate 16 bytes to find new\r
+                mov     bx, 1          ;   top of memory address\r
+                int     21h\r
+                jc      @@BadInit\r
+                inc     ax             ; Adjust address to point after block\r
+                mov     word ptr _heaptop@ + 2, ax\r
+\r
+                dec     ax             ; Change back and release block\r
+                mov     es, ax\r
+                mov     ah, 49h\r
+                int     21h\r
+                jc      @@BadInit\r
+\r
+                mov     ax, 5801h      ; Set first fit allocation\r
+                mov     bx, 0\r
+                int     21h\r
+                jnc     @@NoChange\r
+\r
+@@BadInit:      jmp near ptr _abort\r
+\r
+@@NoChange:\r
+\r
+;       Prepare main arguments\r
+\r
+                mov     ah, 0\r
+                int     1ah                     ; get current BIOS time in ticks\r
+                mov     word ptr _StartTime@,dx ; save it for clock() fn\r
+                mov     word ptr _StartTime@+2,cx\r
+               or      al,al                   ; was midnight flag set?\r
+               jz      @@NotMidnight\r
+               mov     ax,40h                  ; set BIOS midnight flag\r
+               mov     es,ax                   ;  at 40:70\r
+               mov     bx,70h\r
+               mov     byte ptr es:[bx],1\r
+\r
+@@NotMidnight:\r
+                xor     bp,bp                   ; set BP to 0 for overlay mgr\r
+\r
+                mov     es, cs:DGROUP@@\r
+                mov     si,offset DGROUP:InitStart      ;si = start of table\r
+                mov     di,offset DGROUP:InitEnd        ;di = end of table\r
+                call    StartExit\r
+\r
+;       ExitCode = main(argc,argv,envp);\r
+\r
+IF      LDATA\r
+                push    word ptr __C0environ+2\r
+                push    word ptr __C0environ\r
+                push    word ptr __C0argv+2\r
+                push    word ptr __C0argv\r
+ELSE\r
+                push    word ptr __C0environ\r
+                push    word ptr __C0argv\r
+ENDIF\r
+                push    __C0argc\r
+                call    _main\r
+\r
+;       Flush and close streams and files\r
+\r
+                push    ax\r
+                call    _exit\r
+\r
+;---------------------------------------------------------------------------\r
+;       _cleanup()      call all #pragma exit cleanup routines.\r
+;       _checknull()    check for null pointer zapping copyright message\r
+;       _terminate(int) exit program with error code\r
+;\r
+;       These functions are called by exit(), _exit(), _cexit(),\r
+;       and _c_exit().\r
+;---------------------------------------------------------------------------\r
+\r
+;       Call cleanup routines\r
+\r
+__cleanup       PROC    DIST\r
+                PUBLIC  __cleanup\r
+\r
+                mov     es, cs:DGROUP@@\r
+                push    si\r
+                push    di\r
+                mov     si,offset DGROUP:ExitStart\r
+                mov     di,offset DGROUP:ExitEnd\r
+                call    StartExit\r
+                pop     di\r
+                pop     si\r
+                ret\r
+__cleanup       ENDP\r
+\r
+;       Check for null pointers before exit\r
+\r
+__checknull     PROC    DIST\r
+                PUBLIC  __checknull\r
+\r
+IF      LDATA EQ false\r
+  IFNDEF  __TINY__\r
+                push    si\r
+                push    di\r
+                mov     es, cs:DGROUP@@\r
+                xor     ax, ax\r
+                mov     si, ax\r
+                mov     cx, lgth_CopyRight\r
+ComputeChecksum label   near\r
+                add     al, es:[si]\r
+                adc     ah, 0\r
+                inc     si\r
+                loop    ComputeChecksum\r
+                sub     ax, CheckSum\r
+                jz      @@SumOk\r
+                mov     cx, lgth_NullCheck\r
+                mov     dx, offset DGROUP: NullCheck\r
+                call    ErrorDisplay\r
+@@SumOK:        pop     di\r
+                pop     si\r
+  ENDIF\r
+ENDIF\r
+                ret\r
+__checknull     ENDP\r
+\r
+;       Exit to DOS\r
+\r
+__terminate     PROC    DIST\r
+                PUBLIC  __terminate\r
+                mov     bp,sp\r
+                mov     ah,4Ch\r
+                mov     al,[bp+cPtrSize]\r
+                int     21h                     ; Exit to DOS\r
+__terminate     ENDP\r
+\r
+STARTX          ENDP\r
+\r
+        SUBTTL  Vector save/restore & default Zero divide routines\r
+        PAGE\r
+;[]------------------------------------------------------------[]\r
+;|                                                              |\r
+;| Interrupt Save/Restore routines and default divide by zero   |\r
+;| handler.                                                     |\r
+;|                                                              |\r
+;[]------------------------------------------------------------[]\r
+\r
+ZeroDivision    PROC    FAR\r
+                mov     cx, lgth_ZeroDivMSG\r
+                mov     dx, offset DGROUP: ZeroDivMSG\r
+                jmp     MsgExit3\r
+ZeroDivision    ENDP\r
+\r
+;--------------------------------------------------------------------------\r
+;       savevectors()\r
+;\r
+;       Save vectors for 0, 4, 5 & 6 interrupts.  This is for extended\r
+;       signal()/raise() support as the signal functions can steal these\r
+;       vectors during runtime.\r
+;--------------------------------------------------------------------------\r
+SaveVectors     PROC    NEAR\r
+                push    ds\r
+; Save INT 0\r
+                mov     ax, 3500h\r
+                int     021h\r
+                mov     word ptr _Int0Vector@, bx\r
+                mov     word ptr _Int0Vector@+2, es\r
+; Save INT 4\r
+                mov     ax, 3504h\r
+                int     021h\r
+                mov     word ptr _Int4Vector@, bx\r
+                mov     word ptr _Int4Vector@+2, es\r
+; Save INT 5\r
+                mov     ax, 3505h\r
+                int     021h\r
+                mov     word ptr _Int5Vector@, bx\r
+                mov     word ptr _Int5Vector@+2, es\r
+; Save INT 6\r
+                mov     ax, 3506h\r
+                int     021h\r
+                mov     word ptr _Int6Vector@, bx\r
+                mov     word ptr _Int6Vector@+2, es\r
+;\r
+;       Install default divide by zero handler.\r
+;\r
+                mov     ax, 2500h\r
+                mov     dx, cs\r
+                mov     ds, dx\r
+                mov     dx, offset ZeroDivision\r
+                int     21h\r
+\r
+                pop     ds\r
+                ret\r
+SaveVectors     ENDP\r
+\r
+;--------------------------------------------------------------------------\r
+;       _restorezero() puts back all the vectors that SaveVectors took.\r
+;\r
+;NOTE : TSRs must BE AWARE that signal() functions which take these\r
+;       vectors will be deactivated if the keep() function is executed.\r
+;       If a TSR wants to use the signal functions when it is active it\r
+;       will have to save/restore these vectors itself when activated and\r
+;       deactivated.\r
+;--------------------------------------------------------------------------\r
+__restorezero   PROC    DIST\r
+                PUBLIC  __restorezero\r
+IFDEF   __HUGE__\r
+                push    ds\r
+                mov     ds, cs: DGROUP@@\r
+ENDIF\r
+                push    ds\r
+                mov     ax, 2500h\r
+                lds     dx, _Int0Vector@\r
+                int     21h\r
+                pop     ds\r
+\r
+                push    ds\r
+                mov     ax, 2504h\r
+                lds     dx, _Int4Vector@\r
+                int     21h\r
+                pop     ds\r
+\r
+                push    ds\r
+                mov     ax, 2505h\r
+                lds     dx, _Int5Vector@\r
+                int     21h\r
+                pop     ds\r
+\r
+IFNDEF   __HUGE__\r
+                push    ds\r
+ENDIF\r
+                mov     ax, 2506h\r
+                lds     dx, _Int6Vector@\r
+                int     21h\r
+                pop     ds\r
+\r
+                ret\r
+                ENDP\r
+\r
+;------------------------------------------------------------------\r
+;  Loop through a startup/exit (SE) table,\r
+;  calling functions in order of priority.\r
+;  ES:SI is assumed to point to the beginning of the SE table\r
+;  ES:DI is assumed to point to the end of the SE table\r
+;  First 64 priorities are reserved by Borland\r
+;------------------------------------------------------------------\r
+PNEAR           EQU     0\r
+PFAR            EQU     1\r
+NOTUSED         EQU     0ffh\r
+\r
+SE              STRUC\r
+calltype        db      ?                       ; 0=near,1=far,ff=not used\r
+priority        db      ?                       ; 0=highest,ff=lowest\r
+addrlow         dw      ?\r
+addrhigh        dw      ?\r
+SE              ENDS\r
+\r
+StartExit       proc near\r
+@@Start:        cmp     si,offset DGROUP:InitStart      ; startup or exit?\r
+                je      @@StartLow              ; it's startup\r
+                xor     ah,ah                   ; start with high priority\r
+                jmp     short @@SaveEnd\r
+@@StartLow:     mov     ah,0ffh                 ;start with lowest priority\r
+@@SaveEnd:      mov     dx,di                   ;set sentinel to end of table\r
+                mov     bx,si                   ;bx = start of table\r
+\r
+@@TopOfTable:   cmp     bx,di                   ;and the end of the table?\r
+                je      @@EndOfTable            ;yes, exit the loop\r
+                cmp     es:[bx.calltype],NOTUSED;check the call type\r
+                je      @@Next\r
+                cmp     si,offset DGROUP:InitStart      ; startup or exit?\r
+                je      @@CompareHigh           ; it's startup\r
+                cmp     ah,es:[bx.priority]     ; it's exit\r
+                jmp     short @@CheckPrior      ; if priority too low, skip\r
+@@CompareHigh:  cmp     es:[bx.priority],ah     ;check the priority\r
+@@CheckPrior:   ja      @@Next                  ;too high?  skip\r
+                mov     ah,es:[bx.priority]     ;keep priority\r
+                mov     dx,bx                   ;keep index in dx\r
+@@Next:         add     bx,SIZE SE              ;bx = next item in table\r
+                jmp     @@TopOfTable\r
+\r
+@@EndOfTable:   cmp     dx,di                   ;did we exhaust the table?\r
+                je      @@Done                  ;yes, quit\r
+                mov     bx,dx                   ;bx = highest priority item\r
+                cmp     es:[bx.calltype],PNEAR  ;is it near or far?\r
+                mov     es:[bx.calltype],NOTUSED;wipe the call type\r
+                push    es                      ;save es\r
+                je      @@NearCall\r
+\r
+@@FarCall:      call    DWORD PTR es:[bx.addrlow]\r
+                pop     es                      ;restore es\r
+                jmp     short @@Start\r
+\r
+@@NearCall:     call    WORD PTR es:[bx.addrlow]\r
+                pop     es                      ;restore es\r
+                jmp     short @@Start\r
+\r
+@@Done:         ret\r
+                endp\r
+\r
+;------------------------------------------------------------------\r
+\r
+ErrorDisplay    PROC    NEAR\r
+                mov     ah, 040h\r
+                mov     bx, 2\r
+                int     021h\r
+                ret\r
+ErrorDisplay    ENDP\r
+\r
+_abort          PROC    DIST\r
+                PUBLIC  _abort\r
+                mov     cx, lgth_abortMSG\r
+                mov     dx, offset DGROUP: abortMSG\r
+MsgExit3        label   near\r
+                mov     ds, cs: DGROUP@@\r
+                call    ErrorDisplay\r
+CallExit3       label   near\r
+                mov     ax, 3\r
+                push    ax\r
+                call    __exit           ; _exit(3);\r
+                ENDP\r
+\r
+; The DGROUP@ variable is used to reload DS with DGROUP\r
+\r
+PubSym@         DGROUP@, <dw    ?>, __PASCAL__\r
+\r
+IFDEF  __BOSS__\r
+PubSym@                CSalias@,<dw    ?>, __PASCAL__\r
+ENDIF\r
+\r
+\r
+; __MMODEL is used to determine the memory model or the default\r
+; pointer types at run time.\r
+\r
+                public __MMODEL\r
+__MMODEL        dw      MMODEL\r
+\r
+_TEXT           ENDS\r
+\r
+                SUBTTL  Start Up Data Area\r
+                PAGE\r
+;[]------------------------------------------------------------[]\r
+;|      Start Up Data Area                                      |\r
+;|                                                              |\r
+;|      WARNING         Do not move any variables in the data   |\r
+;|                      segment unless you're absolutely sure   |\r
+;|                      that it does not matter.                |\r
+;[]------------------------------------------------------------[]\r
+\r
+_DATA           SEGMENT\r
+\r
+;       Magic symbol used by the debug info to locate the data segment\r
+                public DATASEG@\r
+DATASEG@        label   byte\r
+\r
+;       The CopyRight string must NOT be moved or changed without\r
+;       changing the null pointer check logic\r
+\r
+CopyRight       db      4 dup(0)\r
+                db      'Borland C++ - Copyright 1991 Borland Intl.',0\r
+lgth_CopyRight  equ     $ - CopyRight\r
+\r
+IF      LDATA EQ false\r
+IFNDEF  __TINY__\r
+CheckSum        equ     00D5Ch\r
+NullCheck       db      'Null pointer assignment', 13, 10\r
+lgth_NullCheck  equ     $ - NullCheck\r
+ENDIF\r
+ENDIF\r
+\r
+ZeroDivMSG      db      'Divide error', 13, 10\r
+lgth_ZeroDivMSG equ     $ - ZeroDivMSG\r
+\r
+abortMSG        db      'Abnormal program termination', 13, 10\r
+lgth_abortMSG   equ     $ - abortMSG\r
+\r
+; JAB - Added string for no 286\r
+no286MSG               db              'Sorry, this program requires a 286 or better.', 13, 10\r
+lgth_no286MSG  equ             $ - no286MSG\r
+; JAB - End of modifications\r
+\r
+;\r
+;                       Interrupt vector save areas\r
+;\r
+;       Interrupt vectors 0,4,5 & 6 are saved at startup and then restored\r
+;       when the program terminates.  The signal/raise functions might\r
+;       steal these vectors during execution.\r
+;\r
+;       Note: These vectors save area must not be altered\r
+;             without changing the save/restore logic.\r
+;\r
+PubSym@         _Int0Vector     <dd     0>,             __CDECL__\r
+PubSym@         _Int4Vector     <dd     0>,             __CDECL__\r
+PubSym@         _Int5Vector     <dd     0>,             __CDECL__\r
+PubSym@         _Int6Vector     <dd     0>,             __CDECL__\r
+;\r
+;                       Miscellaneous variables\r
+;\r
+PubSym@         _C0argc,        <dw     0>,             __CDECL__\r
+dPtrPub@        _C0argv,        0,                      __CDECL__\r
+dPtrPub@        _C0environ,     0,                      __CDECL__\r
+PubSym@         _envLng,        <dw     0>,             __CDECL__\r
+PubSym@         _envseg,        <dw     0>,             __CDECL__\r
+PubSym@         _envSize,       <dw     0>,             __CDECL__\r
+PubSym@         _psp,           <dw     0>,             __CDECL__\r
+PubSym@         _version,       <label word>,           __CDECL__\r
+PubSym@         _osversion,     <label word>,           __CDECL__\r
+PubSym@         _osmajor,       <db     0>,             __CDECL__\r
+PubSym@         _osminor,       <db     0>,             __CDECL__\r
+PubSym@         errno,          <dw     0>,             __CDECL__\r
+PubSym@         _StartTime,     <dw   0,0>,             __CDECL__\r
+\r
+\r
+IFDEF __BOSS__\r
+PubSym@                _protected      <dw    0>,              __CDECL__\r
+PubSym@        _shiftcount,    <dw    12>,             __CDECL__\r
+PubSym@        _hugeincval,    <dw    1000h>,          __CDECL__\r
+ENDIF\r
+\r
+;       Memory management variables\r
+\r
+IF      LDATA EQ false\r
+PubSym@         __heapbase,     <dw   DGROUP:edata@>,   __CDECL__\r
+ENDIF\r
+IFNDEF __HUGE__\r
+PubSym@         __brklvl,       <dw   DGROUP:edata@>,   __CDECL__\r
+ENDIF\r
+PubSym@         _heapbase,      <dd   0>,       __CDECL__\r
+PubSym@         _brklvl,        <dd   0>,       __CDECL__\r
+PubSym@         _heaptop,       <dd   0>,       __CDECL__\r
+\r
+;       If stack in DS and Large data model then override location of __emu\r
+\r
+IFDEF   _DSSTACK_\r
+IF      LDATA\r
+public  __emu\r
+__emu   db      044h    DUP (0)\r
+        db      0CCh    DUP (?)\r
+ENDIF\r
+ENDIF\r
+\r
+_DATA           ENDS\r
+\r
+\r
+_CVTSEG         SEGMENT\r
+PubSym@         _RealCvtVector, <label  word>,  __CDECL__\r
+                ENDS\r
+\r
+_SCNSEG         SEGMENT\r
+PubSym@         _ScanTodVector,  <label word>,  __CDECL__\r
+                ENDS\r
+\r
+IFNDEF __HUGE__\r
+_BSS            SEGMENT\r
+bdata@          label   byte\r
+                ENDS\r
+\r
+_BSSEND         SEGMENT\r
+edata@          label   byte\r
+                ENDS\r
+ENDIF\r
+\r
+IFNDEF __TINY__\r
+_STACK          SEGMENT\r
+IFDEF __BOSS__\r
+    IF LDATA\r
+                db      1400h dup(?)\r
+    ENDIF\r
+ELSE\r
+                db      128 dup(?)               ;minimum stack size\r
+ENDIF  ; __BOSS__\r
+                ENDS\r
+ENDIF  ; __TINY__\r
+                END     STARTX\r