home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power CD-ROM!! 7
/
POWERCD7.ISO
/
prgmming
/
clipper
/
gt_int86.asm
< prev
next >
Wrap
Assembly Source File
|
1993-06-06
|
9KB
|
283 lines
PAGE 60,132
INCLUDE EXTENDA.MAC
PUBLIC GT_INT86
;;
;; GT CLIPPER STANDARD HEADER
;;
;; File......: gt_int86.asm
;; Author....: Brian Dukes & Andy "Dr. VxD" Sawyer
;; BBS.......: THE CELLAR bbs
;; Net/Node..: 013/203
;; User Name.: Brian Dukes
;; Date......: 12/5/93
;; Revision..: 1.0
;;
;; This is an original work by Brian Dukes and is placed in the
;; public domain.
;;
;; Modification history:
;; ---------------------
;; $Log$
;; 2/6/93 - BJD+AMS - Due to super clever stuff with 486 processor caching
;; this program didn't seem to work on a 486. So changed
;; the code to call the dos interupt rather than self-
;; modifying code.
;;
;; Thanks must go to Andy Sawyer, who showed me why the __storni funcs
;; were not working properly. He put the code in which sets up DS to
;; point to DGROUP.
;;
;;
;;
;; $DOC$
;; $FUNCNAME$
;; GT_INT86()
;; $CATEGORY$
;; System
;; $ONELINER$
;; Performs an interrupt function call.
;; $SYNTAX$
;; ret := GT_INT86(<intno>,@<AX>,@<BX>,@<CX>,@<DX>,@<SI>,@<DI>,
;; @<BP>,@<DS>,@<ES>)
;; $ARGUMENTS$
;; <intno> - Interrupt Function number to call (33dec = int 21h)
;; <AX> - Input register value of AX - PASSED BY REFERENCE
;; <BX> - Input register value of BX - PASSED BY REFERENCE
;; <CX> - Input register value of CX - PASSED BY REFERENCE
;; <DX> - Input register value of DX - PASSED BY REFERENCE
;; <SI> - Input register value of SI - PASSED BY REFERENCE
;; <DI> - Input register value of DI - PASSED BY REFERENCE
;; <BP> - Input register value of BP - PASSED BY REFERENCE
;; <DS> - Input register value of DS - PASSED BY REFERENCE
;; <ES> - Input register value of ES - PASSED BY REFERENCE
;; $RETURNS$
;; <ret> - The value of carry flag!
;; <AX> - Output register value of AX
;; <BX> - Output register value of BX
;; <CX> - Output register value of CX
;; <DX> - Output register value of DX
;; <SI> - Output register value of SI
;; <DI> - Output register value of DI
;; <BP> - Output register value of BP
;; <DS> - Output register value of DS
;; <ES> - Output register value of ES
;; $DESCRIPTION$
;; This little <grin> function allows your Clipper application to make
;; use of dos functions and interrupts, such as scrolling screens, direct
;; disk access, video bios calls, etc.
;;
;; It works by setting up Register Variables in your Clipper program
;; and passing them in to GT_INT86() by REFERENCE; this is important
;; if you want to see what the outcome of those registers are on return
;; from the dos function. Although, this will still work if you do not
;; pass by reference - you obviosly will not be returned any of the
;; outgoing register values.
;;
;; In addition to updating the registers, it will return the carry flag
;; to the calling process. If 0 is returned by the function then the
;; carry flag was not set after performing your dos function. If 1 is
;; returned then the carry flag was set (usually indicating an error).
;;
;; $EXAMPLES$
;;
;;
;; #translate makehi( <X> ) => (<X> * (2 ^ 8))
;; #translate highbyte( <X> ) => int( <X> / 256 )
;; #translate lowbyte( <X> ) => int( <X> % 256 )
;;
;; local s := "Hello World$"
;; local rax := 0
;; local rbx := 0
;; local rcx := 0
;; local rdx := 0
;; local rsi := 0
;; local rdi := 0
;; local rbp := 0
;; local rds := 0
;; local res := 0
;; local inter := 0
;; local ret := 0
;;
;; rax := makehi(9)
;; rds := gt_segment(s)
;; rdx := gt_offset(s)
;;
;; ret := gt_int86(33, rax, rbx, rcx, rdx, rsi, rdi, rbp, rds, res)
;; /* The above line Displays Hello World */
;;
;; * The following will get the current date
;; rax := makehi(42)
;; inter := 33
;; ret := gt_int86(33,@rax,@rbx,@rcx,@rdx,@rsi,@rdi,@rbp,@rds,@res)
;;
;; * Returns AL = DOW, CX = Year, DH = Month, DL = Day
;; ? "it's the "+str(lowbyte(rax))+" Day of the Week"
;; ? "The Date Is : "
;; ?? lowbyte(rdx)
;; ?? "/"
;; ?? highbyte(rdx)
;; ?? "/"
;; ?? rcx
;; ?
;; ? "Return : "+str(ret)
;;
;; $SEEALSO$
;; STRING.EHO:GT_Segment() STRING.EHO:GT_Offset()
;; $END$
;;
;;;;; Assembled Using MASM
PUT_INT MACRO parm,val
mov ax,parm
push ax
mov ax,val
push ax
call __storni
add sp,4
ENDM
EXTRN __STORNI:FAR
DGROUP GROUP datasg
datasg segment public para 'DATA' ; start of data segment
;
; Parameters : Int, AX, BX, CX, DX, SI, DI, BP, DS, ES
_GT_RAX dw 0h
_GT_RBX dw 0h
_GT_RCX dw 0h
_GT_RDX dw 0h
_GT_RSI dw 0h
_GT_RDI dw 0h
_GT_RBP dw 0h
_GT_RDS dw 0h
_GT_RES dw 0h
_GT_CAR dw 0h
;
datasg ends ; end of data segment
;
;
_code segment byte public 'CODE'
assume cs:_code,ds:nothing,es:nothing
GT_INT86 PROC FAR
push bp ; Save registers
mov bp,sp
push es
push si
push di
push bx
push cx
push dx
push ds
get_int 2 ; Get AX
push ax
get_int 3 ; Get BX
push ax
get_int 4 ; Get CX
push ax
get_int 5 ; Get DX
push ax
get_int 6 ; Get SI
push ax
get_int 7 ; Get DI
push ax
get_int 8 ; Get BP
push ax
get_int 9 ; Get DS
push ax
get_int 10 ; Get ES
push ax
get_int 1 ; Get the interrupt number
push ax
pop ax ; Get the interrupt number and poke it into
mov ah,35h
int 21h ; Get DOS Interrupt Vector
mov cs:_vecseg,ES
mov cs:_vecoff,BX
pop es ; Grab the rest of the registers from Stack
pop ds
pop bp
pop di
pop si
pop dx
pop cx
pop bx
pop ax
;; This junk emulates (almost) a software interrupt!
pushf
cli
call CS:[_vector]
; Make Sure DS points to DGROUP!!
push ds
push ax
mov ax,SEG DGROUP
mov ds,ax
assume ds:DGROUP
pop ax
mov _GT_RAX,ax
pop ax
mov _GT_RDS,ax
;; Andy's well trick bit of code for saving the carry flag
mov ax,0
adc ax,0
mov _GT_CAR,ax
mov _GT_RBX,BX ; Save all of the returning Register Values
mov _GT_RCX,CX
mov _GT_RDX,DX
mov _GT_RSI,SI
mov _GT_RDI,DI
mov _GT_RBP,BP
mov _GT_RES,ES
PUT_INT 2,_GT_RAX
PUT_INT 3,_GT_RBX
PUT_INT 4,_GT_RCX
PUT_INT 5,_GT_RDX
PUT_INT 6,_GT_RSI
PUT_INT 7,_GT_RDI
PUT_INT 8,_GT_RBP
PUT_INT 9,_GT_RDS
PUT_INT 10,_GT_RES
mov ax,_GT_CAR ; Setup function return as Carry Flag
push ax
call __retni
add sp,2
pop ds
pop dx
pop cx
pop bx
pop di ; Restore registers
pop si
pop es
pop bp
ret ; Go on back to Clipper
_vector label DWORD
_vecoff dw 0h
_vecseg dw 0h
GT_INT86 ENDP ; End of routine
_code ENDS ; End of code segment
END