home *** CD-ROM | disk | FTP | other *** search
-
- ; *******************************************************
- ; * *
- ; * Turbo Pascal Runtime Library Version 6.0 *
- ; * CRT Interface Unit *
- ; * *
- ; * Copyright (C) 1988,91 Borland International *
- ; * *
- ; *******************************************************
-
- TITLE CRT
-
- INCLUDE SE.ASM
-
- ; Coordinate record
-
- X EQU (BYTE PTR 0)
- Y EQU (BYTE PTR 1)
-
- ; BIOS workspace equates
-
- CrtMode EQU (BYTE PTR 49H)
- CrtWidth EQU (BYTE PTR 4AH)
- Cursor EQU (WORD PTR 50H)
- Addr6845 EQU (WORD PTR 63H)
- Timer EQU (DWORD PTR 6CH)
- CrtInfo EQU (BYTE PTR 87H)
- CrtRows EQU (BYTE PTR 84H)
-
- DATA SEGMENT WORD PUBLIC
-
- ; Externals
-
- EXTRN CheckBreak:BYTE,CheckEOF:BYTE,DirectVideo:BYTE
- EXTRN CheckSnow:BYTE,LastMode:WORD,TextAttr:BYTE
- EXTRN WindMin:WORD,WindMax:WORD,Seg0040:WORD
- EXTRN SegB000:WORD,SegB800:WORD
-
- IF DPMIVersion
- EXTRN RealModeRegs:BYTE
- ENDIF
-
- ; Local workspace
-
- DelayCnt DW ?
- CurCrtSize DW ?
- NormAttr DB ?
- ScanCode DB ?
- BreakFlag DB ?
-
- DATA ENDS
-
- CODE SEGMENT BYTE PUBLIC
-
- ASSUME CS:CODE,DS:DATA
-
- ; Externals
-
- EXTRN Break:NEAR
-
- ; Publics
-
- PUBLIC Initialize,TextMode,Window,ClrScr,ClrEol,InsLine
- PUBLIC DelLine,GotoXY,WhereX,WhereY,TextColor,TextBackground
- PUBLIC LowVideo,HighVideo,NormVideo,Delay,Sound,NoSound
- PUBLIC KeyPressed,ReadKey,AssignCrt
-
- ; One-time initialization
-
- Initialize:
-
- MOV AH,0FH
- CALL Video
- CMP AL,7
- JE @@1
- CMP AL,3
- JBE @@1
- MOV AX,3
- CALL CrtInit
- @@1: CALL CrtSetup
- MOV AH,8
- XOR BH,BH
- CALL Video
- MOV AL,AH
- AND AL,7FH
- MOV NormAttr,AL
- MOV TextAttr,AL
- XOR AX,AX
- MOV CheckEOF,AL
- MOV ScanCode,AL
- MOV BreakFlag,AL
- INC AX
- MOV CheckBreak,AL
- MOV ES,Seg0040
- MOV DI,OFFSET Timer
- MOV BL,ES:[DI]
- @@2: CMP BL,ES:[DI]
- JE @@2
- MOV BL,ES:[DI]
- MOV AX,-28
- CWD
- CALL DelayLoop
- NOT AX
- NOT DX
- MOV CX,55
- DIV CX
- MOV DelayCnt,AX
- IF DPMIVersion
- MOV AX,dpmiGetRMCB
- MOV SI,OFFSET CtrlBreak
- MOV DI,OFFSET RealModeRegs
- PUSH DS
- POP ES
- PUSH CS
- POP DS
- INT DPMI
- PUSH ES
- POP DS
- MOV AX,dpmiSetRealInt
- MOV BL,1BH
- INT DPMI
- ELSE
- PUSH DS
- PUSH CS
- POP DS
- MOV DX,OFFSET CtrlBreak
- MOV AX,dosSetInt*256+1BH
- INT DOS
- POP DS
- ENDIF
- RET
-
- ; Initialize CRT
- ; In AL = Requested mode
- ; AH = Requested font
-
- CrtInit:
-
- MOV ES,Seg0040
- AND ES:CrtInfo,0FEH
- CMP AL,7
- JE @@1
- CMP AL,4
- JB @@1
- MOV AL,3
- @@1: PUSH AX
- MOV AH,0
- CALL Video
- POP AX
- OR AH,AH
- JE @@2
- MOV AX,1112H
- MOV BL,0
- CALL Video
- MOV AX,1130H
- MOV BH,0
- MOV DL,0
- CALL Video
- CMP DL,42
- JNE @@2
- OR ES:CrtInfo,1
- MOV AX,100H
- MOV CX,600H
- CALL Video
- MOV AH,12H
- MOV BL,20H
- CALL Video
- @@2: RET
-
- ; Setup CRT variables according to selected mode
-
- CrtSetup:
-
- MOV AH,0FH
- CALL Video
- PUSH AX
- MOV AX,1130H
- MOV BH,0
- MOV DL,0
- CALL Video
- POP AX
- MOV CL,0
- OR DL,DL
- JNE @@1
- MOV DL,24
- CMP AL,3
- JA @@1
- MOV CL,1
- @@1: MOV DH,DL
- MOV DL,AH
- DEC DL
- MOV AH,0
- CMP DH,24
- JBE @@2
- MOV AH,1
- @@2: MOV LastMode,AX
- MOV CurCrtSize,DX
- MOV CheckSnow,CL
- MOV DirectVideo,1
- XOR AX,AX
- MOV WindMin,AX
- MOV WindMax,DX
- RET
-
- ; Ctrl-Break interrupt handler
-
- CtrlBreak:
-
- IF DPMIVersion
- CMP ES:CheckBreak,0
- JE @@1
- MOV ES:BreakFlag,1
- @@1: CLD
- LODSW
- MOV ES:[DI].realIP,AX
- LODSW
- MOV ES:[DI].realCS,AX
- LODSW
- MOV ES:[DI].realFlags,AX
- ADD ES:[DI].realSP,6
- ELSE
- PUSH AX
- PUSH DS
- MOV AX,SEG DATA
- MOV DS,AX
- CMP CheckBreak,0
- JE @@1
- MOV BreakFlag,1
- @@1: POP DS
- POP AX
- ENDIF
- IRET
-
- ; Check for Ctrl-Break
-
- BreakCheck:
-
- CMP BreakFlag,0
- JNE @@1
- RET
- @@1: MOV BreakFlag,0
- @@2: MOV AH,1
- INT 16H
- JE @@3
- MOV AH,0
- INT 16H
- JMP @@2
- @@3: MOV AL,'^'
- CALL WriteChar
- MOV AL,'C'
- CALL WriteChar
- CALL WriteCrLf
- JMP Break
-
- ; Set CRT text mode
-
- TextMode:
-
- MOV BX,SP
- MOV AX,SS:[BX+4]
- CALL CrtInit
- CALL CrtSetup
- MOV AL,NormAttr
- MOV TextAttr,AL
- RETF 2
-
- ; Define output window
-
- Window:
-
- MOV BX,SP
- MOV DL,SS:[BX+10]
- MOV DH,SS:[BX+8]
- MOV CL,SS:[BX+6]
- MOV CH,SS:[BX+4]
- CMP DL,CL
- JA @@1
- CMP DH,CH
- JA @@1
- DEC DL
- JS @@1
- DEC DH
- JS @@1
- DEC CL
- CMP CL,CurCrtSize.X
- JA @@1
- DEC CH
- CMP CH,CurCrtSize.Y
- JA @@1
- MOV WindMin,DX
- MOV WindMax,CX
- CALL SetCursor
- @@1: RETF 8
-
- ; Clear screen
-
- ClrScr:
-
- MOV AX,6*256
- MOV BH,TextAttr
- MOV CX,WindMin
- MOV DX,WindMax
- CALL Video
- MOV DX,WindMin
- CALL SetCursor
- RETF
-
- ; Clear to end-of-line
-
- ClrEol:
-
- CALL GetCursor
- MOV AX,6*256
- MOV BH,TextAttr
- MOV CX,DX
- MOV DL,WindMax.X
- CALL Video
- RETF
-
- ; Insert line
-
- InsLine:
-
- MOV AX,7*256+1
- JMP SHORT InsDelLine
-
- ; Delete line
-
- DelLine:
-
- MOV AX,6*256+1
-
- InsDelLine:
-
- PUSH AX
- CALL GetCursor
- POP AX
- MOV BH,TextAttr
- MOV CL,WindMin.X
- MOV CH,DH
- MOV DX,WindMax
- CMP CH,DH
- JNE @@1
- XOR AL,AL
- @@1: CALL Video
- RETF
-
- ; Position cursor
-
- GotoXY:
-
- MOV BX,SP
- MOV DL,SS:[BX+6]
- MOV DH,SS:[BX+4]
- DEC DL
- ADD DL,WindMin.X
- JC @@1
- CMP DL,WindMax.X
- JA @@1
- DEC DH
- ADD DH,WindMin.Y
- JC @@1
- CMP DH,WindMax.Y
- JA @@1
- CALL SetCursor
- @@1: RETF 4
-
- ; Return cursor X coordinate
-
- WhereX:
-
- CALL GetCursor
- MOV AL,DL
- SUB AL,WindMin.X
- INC AL
- RETF
-
- ; Return cursor Y coordinate
-
- WhereY:
-
- CALL GetCursor
- MOV AL,DH
- SUB AL,WindMin.Y
- INC AL
- RETF
-
- ; Set text color (color modes)
-
- TextColor:
-
- MOV BX,SP
- MOV AL,SS:[BX+4]
- TEST AL,0F0H
- JE @@1
- AND AL,0FH
- OR AL,80H
- @@1: AND TextAttr,70H
- OR TextAttr,AL
- RETF 2
-
- ; Set text background (color modes)
-
- TextBackground:
-
- MOV BX,SP
- MOV AL,SS:[BX+4]
- AND AL,7
- MOV CL,4
- SHL AL,CL
- AND TextAttr,8FH
- OR TextAttr,AL
- RETF 2
-
- ; Select low intensity
-
- LowVideo:
-
- AND TextAttr,0F7H
- RETF
-
- ; Select high intensity
-
- HighVideo:
-
- OR TextAttr,8
- RETF
-
- ; Select normal intensity
-
- NormVideo:
-
- MOV AL,NormAttr
- MOV TextAttr,AL
- RETF
-
- ; Delay specified number of milliseconds
-
- Delay:
-
- MOV BX,SP
- MOV CX,SS:[BX+4]
- JCXZ @@2
- MOV ES,Seg0040
- XOR DI,DI
- MOV BL,ES:[DI]
- @@1: MOV AX,DelayCnt
- XOR DX,DX
- CALL DelayLoop
- LOOP @@1
- @@2: RETF 2
-
- ; Delay one timer tick or by CX iterations
-
- DelayLoop:
-
- @@1: SUB AX,1
- SBB DX,0
- JC @@2
- CMP BL,ES:[DI]
- JE @@1
- @@2: RET
-
- ; Start sound generator
-
- Sound:
-
- MOV BX,SP
- MOV BX,SS:[BX+4]
- MOV AX,34DDH
- MOV DX,0012H
- CMP DX,BX
- JNC @@2
- DIV BX
- MOV BX,AX
- IN AL,61H
- TEST AL,3
- JNZ @@1
- OR AL,3
- OUT 61H,AL
- MOV AL,0B6H
- OUT 43H,AL
- @@1: MOV AL,BL
- OUT 42H,AL
- MOV AL,BH
- OUT 42H,AL
- @@2: RETF 2
-
- ; Turn off sound generator
-
- NoSound:
-
- IN AL,61H
- AND AL,0FCH
- OUT 61H,AL
- RETF
-
- ; Return true if key is available
-
- KeyPressed:
-
- CMP ScanCode,0
- JNE @@1
- MOV AH,1
- INT 16H
- MOV AL,0
- JE @@2
- @@1: MOV AL,1
- @@2: RETF
-
- ; Read character from keyboard
- ; Out AL = Character
-
- ReadKey:
-
- MOV AL,ScanCode
- MOV ScanCode,0
- OR AL,AL
- JNE @@1
- XOR AH,AH
- INT 16H
- OR AL,AL
- JNE @@1
- MOV ScanCode,AH
- OR AH,AH
- JNE @@1
- MOV AL,'C'-64
- @@1: CALL BreakCheck
- RETF
-
- ; Assign CRT to textfile
-
- AssignCrt:
-
- MOV BX,SP
- PUSH DS
- LDS DI,SS:[BX+4]
- MOV [DI].fMode,fmClosed
- MOV [DI].fBufSize,128
- LEA AX,[DI].fBuffer
- MOV [DI].fBufPtr.ofs,AX
- MOV [DI].fBufPtr.seg,DS
- MOV [DI].fOpenProc.ofs,OFFSET CrtOpen
- MOV [DI].fOpenProc.seg,CS
- MOV [DI].fName,0
- POP DS
- RETF 4
-
- ; CRT file open procedure
-
- CrtOpen:
-
- MOV BX,SP
- PUSH DS
- LDS DI,SS:[BX+4]
- MOV AX,OFFSET CrtRead
- MOV BX,OFFSET CrtReturn
- MOV CX,BX
- CMP [DI].fMode,fmInput
- JE @@1
- MOV [DI].fMode,fmOutput
- MOV AX,OFFSET CrtWrite
- MOV BX,AX
- @@1: MOV [DI].fInOutProc.ofs,AX
- MOV [DI].fInOutProc.seg,CS
- MOV [DI].fFlushProc.ofs,BX
- MOV [DI].fFlushProc.seg,CS
- MOV [DI].fCloseProc.ofs,CX
- MOV [DI].fCloseProc.seg,CS
- XOR AX,AX
- POP DS
- RETF 4
-
- ; CRT file read procedure
-
- CrtRead:
-
- ARG FileP,DWORD,1
-
- ENTRY FAR
- LES DI,FileP
- MOV DX,ES:[DI].fBufSize
- DEC DX
- DEC DX
- MOV SI,ES:[DI].fBufPos
- LES DI,ES:[DI].fBufPtr
- XOR BX,BX
- @@1: MOV ScanCode,0
- PUSH CS
- CALL ReadKey
- MOV CX,1
- CMP AL,bs
- JE @@2
- CMP AL,'S'-64
- JE @@2
- CMP AL,'D'-64
- JE @@3
- DEC CX
- CMP AL,esc
- JE @@2
- CMP AL,'A'-64
- JE @@2
- CMP AL,'F'-64
- JE @@3
- CMP AL,eof
- JE @@4
- CMP AL,cr
- JE @@5
- CMP AL,' '
- JB @@1
- CMP BX,DX
- JE @@1
- MOV ES:[DI+BX],AL
- INC BX
- CALL WriteChar
- CMP BX,SI
- JBE @@1
- MOV SI,BX
- JMP @@1
- @@2: OR BX,BX
- JE @@1
- MOV AL,bs
- CALL WriteChar
- MOV AL,' '
- CALL WriteChar
- MOV AL,bs
- CALL WriteChar
- DEC BX
- LOOP @@2
- JMP @@1
- @@3: CMP BX,SI
- JE @@1
- MOV AL,ES:[DI+BX]
- CMP AL,' '
- JB @@1
- CALL WriteChar
- INC BX
- LOOP @@3
- JMP @@1
- @@4: CMP CheckEOF,0
- JE @@1
- MOV ES:[DI+BX],AL
- INC BX
- JMP SHORT @@6
- @@5: CALL WriteCrLf
- MOV WORD PTR ES:[DI+BX],cr+lf*256
- INC BX
- INC BX
- @@6: LES DI,FileP
- XOR AX,AX
- MOV ES:[DI].fBufPos,AX
- MOV ES:[DI].fBufEnd,BX
- EXIT
-
- ; CRT file write procedure
-
- CrtWrite:
-
- MOV BX,SP
- LES DI,SS:[BX+4]
- MOV CX,ES:[DI].fBufPos
- SUB ES:[DI].fBufPos,CX
- JCXZ @@3
- LES DI,ES:[DI].fBufPtr
- CMP DirectVideo,0
- JNE @@2
- @@1: MOV AL,ES:[DI]
- CALL WriteChar
- INC DI
- LOOP @@1
- JMP SHORT @@3
- @@2: CALL WriteString
- @@3: CALL BreakCheck
- XOR AX,AX
- RETF 4
-
- ; CRT file no-op procedure
-
- CrtReturn:
-
- XOR AX,AX
- RETF 4
-
- ; Write CR/LF on CRT
- ; Uses AX
-
- WriteCrLf:
-
- MOV AL,cr
- CALL WriteChar
- MOV AL,lf
-
- ; Write character on CRT
- ; In AL = Character
- ; Uses AX
-
- WriteChar:
-
- PUSH BX
- PUSH CX
- PUSH DX
- PUSH ES
- PUSH AX
- CALL GetCursor
- POP AX
- CMP AL,bell
- JE @@1
- CMP AL,bs
- JE @@2
- CMP AL,cr
- JE @@3
- CMP AL,lf
- JE @@4
- MOV AH,9
- MOV BL,TextAttr
- XOR BH,BH
- MOV CX,1
- PUSH DX
- CALL Video
- POP DX
- INC DL
- CMP DL,WindMax.X
- JBE @@5
- MOV DL,WindMin.X
- JMP SHORT @@4
- @@1: MOV AH,14
- CALL Video
- JMP SHORT @@5
- @@2: CMP DL,WindMin.X
- JE @@5
- DEC DL
- JMP SHORT @@5
- @@3: MOV DL,WindMin.X
- JMP SHORT @@5
- @@4: CALL LineFeed
- @@5: CALL SetCursor
- POP ES
- POP DX
- POP CX
- POP BX
- RET
-
- ; Do line-feed operation
- ; In DX = Cursor position
- ; Uses AX,BX
-
- LineFeed:
-
- INC DH
- CMP DH,WindMax.Y
- JBE @@1
- DEC DH
- PUSH CX
- PUSH DX
- MOV AX,6*256+1
- MOV BH,TextAttr
- MOV CX,WindMin
- MOV DX,WindMax
- CALL Video
- POP DX
- POP CX
- @@1: RET
-
- ; Get cursor position
- ; Out DX = Cursor position
- ; Uses AX,BX,CX,DX,ES
-
- GetCursor:
-
- MOV AH,3
- XOR BH,BH
- JMP Video
-
- ; Set cursor position
- ; In DX = Cursor position
- ; Uses AX,BX,CX,DX,ES
-
- SetCursor:
-
- MOV AH,2
- XOR BH,BH
- JMP Video
-
- ; Write character string directly to CRT
- ; In CX = Character count
- ; DX = Position
- ; ES:DI = String pointer
- ; Uses AX,BX,CX,DX,SI,DI,ES
-
- WriteString:
-
- PUSH DS
- MOV DS,Seg0040
- MOV DX,DS:Cursor
- POP DS
- MOV BX,DX
- MOV SI,DI
- @@1: MOV AL,ES:[DI]
- CMP AL,bell
- JE @@2
- CMP AL,bs
- JE @@3
- CMP AL,lf
- JE @@4
- CMP AL,cr
- JE @@5
- INC DI
- INC DL
- CMP DL,WindMax.X
- JBE @@8
- CALL DirectWrite
- CALL LineFeed
- MOV DL,WindMin.X
- JMP SHORT @@7
- @@2: CALL DirectWrite
- PUSH CX
- PUSH DX
- MOV AX,14*256+bell
- CALL Video
- POP DX
- POP CX
- JMP SHORT @@6
- @@3: CALL DirectWrite
- CMP DL,WindMin.X
- JE @@6
- DEC DL
- JMP SHORT @@6
- @@4: CALL DirectWrite
- CALL LineFeed
- JMP SHORT @@6
- @@5: CALL DirectWrite
- MOV DL,WindMin.X
- @@6: INC DI
- @@7: MOV SI,DI
- MOV BX,DX
- @@8: LOOP @@1
- CALL DirectWrite
- PUSH DS
- MOV DS,Seg0040
- MOV DS:Cursor,DX
- MOV AL,DH
- MUL DS:CrtWidth
- XOR DH,DH
- ADD AX,DX
- MOV CX,AX
- MOV DX,DS:Addr6845
- MOV AL,14
- OUT DX,AL
- JMP SHORT $+2
- MOV AL,CH
- INC DX
- OUT DX,AL
- JMP SHORT $+2
- DEC DX
- MOV AL,15
- OUT DX,AL
- JMP SHORT $+2
- MOV AL,CL
- INC DX
- OUT DX,AL
- POP DS
- RET
-
- ; Do pending direct write string
- ; In BX = Cursor position
- ; ES:SI = String start address
- ; ES:DI = String end address
- ; Uses AX,BX,SI
-
- DirectWrite:
-
- CMP SI,DI
- JE @@8
- PUSH CX
- PUSH DX
- PUSH DI
- PUSH DS
- PUSH ES
- MOV CX,DI
- SUB CX,SI
- PUSH DS
- MOV DS,Seg0040
- MOV AL,BH
- MUL DS:CrtWidth
- XOR BH,BH
- ADD AX,BX
- SHL AX,1
- MOV DI,AX
- MOV DX,DS:Addr6845
- ADD DX,6
- CMP DS:CrtMode,7
- POP DS
- MOV AX,SegB800
- JNE @@1
- MOV AX,SegB000
- @@1: MOV BL,CheckSnow
- MOV BH,TextAttr
- PUSH ES
- POP DS
- MOV ES,AX
- CLD
- OR BL,BL
- JE @@5
- @@2: LODSB
- MOV BL,AL
- @@3: IN AL,DX
- TEST AL,1
- JNE @@3
- CLI
- @@4: IN AL,DX
- TEST AL,1
- JE @@4
- MOV AX,BX
- STOSW
- STI
- LOOP @@2
- JMP SHORT @@7
- @@5: MOV AH,BH
- @@6: LODSB
- STOSW
- LOOP @@6
- @@7: POP ES
- POP DS
- POP DI
- POP DX
- POP CX
- @@8: RET
-
- ; Save registers and call BIOS video routine
-
- Video:
-
- PUSH SI
- PUSH DI
- PUSH BP
- PUSH ES
- INT 10H
- POP ES
- POP BP
- POP DI
- POP SI
- RET
-
- CODE ENDS
-
- END
-