home *** CD-ROM | disk | FTP | other *** search
-
- ; *******************************************************
- ; * *
- ; * Turbo Pascal Run-time Library *
- ; * Main module *
- ; * *
- ; * Copyright (c) 1988,92 Borland International *
- ; * *
- ; *******************************************************
-
- TITLE MAIN
-
- INCLUDE SE.ASM
-
- DATA SEGMENT WORD PUBLIC
-
- ; Externals
-
- EXTRN OvrHeapSize:WORD,OvrHeapOrg:WORD,OvrHeapPtr:WORD
- EXTRN OvrHeapEnd:WORD,OvrLoadList:WORD,HeapOrg:DWORD
- EXTRN HeapPtr:DWORD,HeapEnd:DWORD,FreeList:DWORD
- EXTRN HeapError:DWORD,ExitProc:DWORD,ExitCode:WORD
- EXTRN ErrorAddr:DWORD,PrefixSeg:WORD,InOutRes:WORD
- EXTRN Input:BYTE,Output:BYTE,SaveInt00:DWORD
- EXTRN Test8086:BYTE
-
- DATA ENDS
-
- CODE SEGMENT BYTE PUBLIC
-
- ASSUME CS:CODE,DS:DATA
-
- ; Externals
-
- EXTRN AssignText:NEAR,ResetText:NEAR,RewriteText:NEAR
- EXTRN CloseText:NEAR,ClearDSeg:NEAR
-
- ; Publics
-
- PUBLIC InitTurbo,HaltTurbo,HaltError,PrintString
- PUBLIC Terminate,LibEntry,LibExit,LibExitProc,InitTask
-
- ; Initialize runtime library. First instruction in any program
- ; is a call to this routine.
-
- InitTurbo:
-
- MOV DX,SEG DATA ;Initialize DS
- MOV DS,DX
- MOV PrefixSeg,ES ;Save PSP segment
- XOR BP,BP ;End of stack frame chain
- CALL ClearDSeg ;Zero fill data segment
- CALL Check8086 ;Determine CPU type
- MOV AX,SP ;Compute first free segment
- ADD AX,4+15 ;address in AX
- MOV CL,4
- SHR AX,CL
- MOV DX,SS
- ADD AX,DX
- MOV OvrHeapOrg,AX ;Initialize overlay manager
- MOV OvrHeapPtr,AX ;variables
- ADD AX,OvrHeapSize
- MOV OvrHeapEnd,AX
- MOV HeapOrg.seg,AX ;Initialize heap manager
- MOV HeapPtr.seg,AX ;variables
- MOV FreeList.seg,AX
- MOV ES,PrefixSeg
- MOV AX,ES:pspMemTop
- MOV HeapEnd.seg,AX
- MOV HeapError.ofs,OFFSET CS:HeapFailure
- MOV HeapError.seg,CS
- MOV DI,OFFSET SaveInt00 ;Capture interrupt vectors
- MOV SI,OFFSET SaveIntTab
- MOV CX,SaveIntCnt
- @@1: CLD
- SEGCS LODSB
- MOV AH,dosGetInt
- INT DOS
- MOV [DI].ofs,BX
- MOV [DI].seg,ES
- ADD DI,4
- LOOP @@1
- PUSH DS ;Install interrupt handlers
- PUSH CS
- POP DS
- MOV DX,OFFSET Int00Handler
- MOV AX,dosSetInt*256+00H
- INT DOS
- MOV DX,OFFSET Int23Handler
- MOV AX,dosSetInt*256+23H
- INT DOS
- MOV DX,OFFSET Int24Handler
- MOV AX,dosSetInt*256+24H
- INT DOS
- MOV DX,OFFSET Int3FHandler
- MOV AX,dosSetInt*256+3FH
- INT DOS
- POP DS
- MOV AX,OFFSET Input ;Assign/Reset Input file
- PUSH DS
- PUSH AX
- PUSH DS
- PUSH AX
- MOV AX,OFFSET ZeroString
- PUSH CS
- PUSH AX
- PUSH CS
- CALL AssignText
- PUSH CS
- CALL ResetText
- MOV AX,OFFSET Output ;Assign/Rewrite Output file
- PUSH DS
- PUSH AX
- PUSH DS
- PUSH AX
- MOV AX,OFFSET ZeroString
- PUSH CS
- PUSH AX
- PUSH CS
- CALL AssignText
- PUSH CS
- CALL RewriteText
- RETF ;Back to main program
-
- ; CPU detection routine. Sets the Test8086 variable according to the
- ; type of CPU detected.
-
- Check8086:
-
- XOR AX,AX ;0 means 8088/8086
- PUSHF ;BX = Flags
- POP BX
- AND BH,0FH ;Clear bits 12-15
- PUSH BX ;Flags = BX
- POPF
- PUSHF ;CX = Flags
- POP CX
- AND CH,0F0H ;Bits 12-15 set?
- CMP CH,0F0H
- JE @@1 ;Yes, 8086
- INC AX ;1 means 80286
- OR BH,0F0H ;Set bits 12-15
- PUSH BX ;Flags = BX
- POPF
- PUSHF ;CX = Flags
- POP CX
- AND CH,0F0H ;Bits 12-15 cleared?
- JE @@1 ;Yes, 80286
- INC AX ;2 means 80386
- @@1: MOV Test8086,AL ;Save CPU test result
- RET
-
- ; Default heap error handler. Return 0 to indicate run-time error.
-
- HeapFailure:
-
- XOR AX,AX
- RETF 2
-
- ; Critical error interrupt handler. Control arrives here when
- ; DOS encounters a "critical error". Convert critical error code
- ; to Turbo Pascal I/O error code, and return.
-
- Int24Handler:
-
- STI ;Enable interrupts
- ADD SP,6 ;Remove INT 24H return info
- POP AX ;Get INT 21H AX register
- AND DI,01FH ;Return AX=150..181
- ADD DI,150
- CMP AH,39H ;DOS 2.0 style function?
- JAE @@1 ;Yes, @@1
- MOV DI,0FFFFH ;Return AX=0FFFFH
- @@1: PUSH DI ;Save error code
- MOV AH,54H ;Dummy function call to get
- INT DOS ;DOS into a stable state
- MOV BP,SP ;Set CF in return flags
- OR BYTE PTR [BP+22],1
- POP AX ;Restore registers
- POP BX
- POP CX
- POP DX
- POP SI
- POP DI
- POP BP
- POP DS
- POP ES
- IRET ;Return to caller
-
- ; Overlay interrupt handler. Control arrives here if the program
- ; calls an overlay procedure before initializing the overlay manager.
-
- Int3FHandler:
-
- MOV AX,208
- ADD SP,6
- JMP SHORT HaltError
-
- ; Divide by zero interrupt handler. Control arrives here upon
- ; executing a DIV or IDIV instruction with a zero divisor.
-
- Int00Handler:
-
- MOV AX,200
-
- ; RunError standard procedure
-
- HaltError:
-
- POP CX
- POP BX
- JMP SHORT Terminate
-
- ; Dummy entry points
-
- LibEntry:
- LibExit:
- LibExitProc:
- InitTask:
-
- ; Control-C interrupt handler. Control arrives here when DOS
- ; detects a Ctrl-C or Ctrl-Break.
-
- Int23Handler:
-
- MOV AX,255
-
- ; Halt standard procedure
-
- HaltTurbo:
-
- XOR CX,CX
- XOR BX,BX
-
- ; Terminate program and return to DOS
- ; In AX = Exit code
- ; BX:CX = Error address (or NIL)
-
- Terminate:
-
- MOV DX,SEG DATA ;Reset DS
- MOV DS,DX
- STI ;Enable interrupts
- MOV ExitCode,AX ;Save exit code
- MOV AX,CX ;Is error address NIL?
- OR AX,BX
- JE @@4 ;Yes, @@4
- MOV AX,OvrLoadList ;Convert physical overlay
- @@0: OR AX,AX ;address to virtual address
- JE @@3
- MOV ES,AX
- MOV AX,ES:ovSegment
- OR AX,AX
- JE @@1
- SUB AX,BX
- JA @@1
- NEG AX
- CMP AX,1000H
- JAE @@1
- MOV DX,16
- MUL DX
- ADD AX,CX
- JC @@1
- CMP AX,ES:ovCodeSize
- JB @@2
- @@1: MOV AX,ES:ovNext
- JMP @@0
- @@2: MOV CX,AX
- MOV BX,ES
- @@3: SUB BX,PrefixSeg ;Adjust address
- SUB BX,10H
- @@4: MOV ErrorAddr.ofs,CX ;Save error address
- MOV ErrorAddr.seg,BX
- @@5: LES BX,ExitProc ;Call exit procedures
- MOV AX,ES
- OR AX,BX
- JE @@10
- XOR AX,AX
- MOV ExitProc.ofs,AX
- MOV ExitProc.seg,AX
- MOV InOutRes,AX
- MOV AX,OFFSET @@5
- PUSH CS
- PUSH AX
- PUSH ES
- PUSH BX
- RETF
- @@10: MOV AX,OFFSET Input ;Close Input file
- PUSH DS
- PUSH AX
- PUSH CS
- CALL CloseText
- MOV AX,OFFSET Output ;Close Output file
- PUSH DS
- PUSH AX
- PUSH CS
- CALL CloseText
- MOV DI,OFFSET SaveInt00 ;Restore interrupt vectors
- MOV SI,OFFSET SaveIntTab
- MOV CX,SaveIntCnt
- @@11: CLD
- SEGCS LODSB
- MOV AH,dosSetInt
- PUSH DS
- LDS DX,[DI]
- INT DOS
- POP DS
- ADD DI,4
- LOOP @@11
- MOV AX,ErrorAddr.ofs ;Runtime error?
- OR AX,ErrorAddr.seg
- JE @@12 ;No, @@12
- MOV BX,OFFSET ErrorStr1 ;Print error message
- CALL PrintString
- MOV AX,ExitCode
- CALL PrintDec
- MOV BX,OFFSET ErrorStr2
- CALL PrintString
- MOV AX,ErrorAddr.seg
- CALL PrintHex
- MOV AL,':'
- CALL PrintChar
- MOV AX,ErrorAddr.ofs
- CALL PrintHex
- MOV BX,OFFSET ErrorStr3
- CALL PrintString
- @@12: MOV AX,ExitCode ;Exit to DOS
- MOV AH,dosExit
- INT DOS
-
- ; Print string
- ; In CS:BX = String pointer
-
- PrintString:
-
- @@1: MOV AL,CS:[BX]
- OR AL,AL
- JE @@2
- CALL PrintChar
- INC BX
- JMP SHORT @@1
- @@2: RET
-
- ; Print byte in decimal
- ; In AL = Value
-
- PrintDec:
-
- MOV CL,100
- CALL @@1
- MOV CL,10
- CALL @@1
- JMP SHORT @@2
- @@1: XOR AH,AH
- DIV CL
- @@2: ADD AL,'0'
- PUSH AX
- CALL PrintChar
- POP AX
- MOV AL,AH
- RET
-
- ; Print word in hex
- ; In AX = Value
-
- PrintHex:
-
- PUSH AX
- MOV AL,AH
- CALL @@1
- POP AX
- @@1: PUSH AX
- MOV CL,4
- SHR AL,CL
- CALL @@2
- POP AX
- AND AL,0FH
- @@2: ADD AL,'0'
- CMP AL,'0'+10
- JB PrintChar
- ADD AL,'A'-'0'-10
-
- ; Print character
- ; In AL = Character
-
- PrintChar:
-
- MOV DL,AL
- MOV AH,6
- INT DOS
- RET
-
- ; Saved interrupt numbers
-
- SaveIntTab DB 00H,02H,1BH,21H,23H,24H,34H,35H,36H,37H
- DB 38H,39H,3AH,3BH,3CH,3DH,3EH,3FH,75H
- SaveIntCnt EQU $-SaveIntTab
-
- ; Error strings
-
- ErrorStr1 DB 'Runtime error ',0
- ErrorStr2 DB ' at ',0
- ErrorStr3 DB '.',cr,lf
-
- ; Empty string
-
- ZeroString DB 0
-
- ; Copyright notice
-
- Copyright DB 'Portions Copyright (c) 1983,92 Borland'
-
- CODE ENDS
-
- END
-