home *** CD-ROM | disk | FTP | other *** search
- DGROUP GROUP CONST, _BSS, _DATA
- ASSUME DS: DGROUP, SS: DGROUP, ES: DGROUP
- ;
- SUPPORT_TEXT SEGMENT WORD PUBLIC 'CODE'
- SUPPORT_TEXT ENDS
- ;
- CONST SEGMENT WORD PUBLIC 'CONST'
- CONST ENDS
- ;
- _BSS SEGMENT WORD PUBLIC 'BSS'
- assume ds:dgroup
- extrn _evtail:word
- extrn _evaddr:word
- _BSS ENDS
- ;
- _DATA SEGMENT WORD PUBLIC 'DATA'
- assume ds:dgroup
- minus1 dw -1
- minus2 dw -2
- _DATA ENDS
- ;
- SUPPORT_TEXT SEGMENT WORD PUBLIC 'CODE'
- assume cs:SUPPORT_TEXT
- assume ds:dgroup
- public _evinit, _mbintr
- ;
- ;
- ;************************ _repword *************************
- ; XTAG:repword
- public _repword
- ;
- ; repword(wordToReplicate, startAddress, numberOfReplications);
- ; char *startAddress;
- ; int wordToReplicate, numberOfReplications;
- ;
- _repword proc far
- push bp ; save bp
- mov bp,sp ; set up bp to access the arguments
- push di ; save di
- cld ; set search direction to forwards
- mov ax,[bp+6] ; ax = word to replicate
- mov di,[bp+8] ; di = address to start reps
- mov cx,[bp+10] ; cx = number of replications
- rep stosw ; search for a newline
- pop di ; restore di
- pop bp ; restore bp
- ret
- _repword endp
- ;
- ;
- ; mouse event (software) interrupt handler
- ;
- pgmds dw ?
- ;
- ;
- ;************************ _movwords *************************
- ;
- public _movwords
- ;
- ; movwords(wordToReplicate, startAddress, numberOfReplications);
- ; char *startAddress;
- ; int wordToReplicate, numberOfReplications;
- ;
- _movwords proc far
- push bp ; save bp
- mov bp,sp ; set up bp to access the arguments
- push ds ; save ds
- push es ; save es
- push si ; save si
- push di ; save di
- cld ; set move direction to forwards
- ;
- mov ax,[bp+6]
- mov ds,ax
- mov si,[bp+8] ; si = address of source data
- mov ax,[bp+10] ; ax = word to replicate
- mov es,ax
- mov di,[bp+12] ; di = address of destination data
- ;
- mov cx,[bp+14] ; cx = number of replications
- sar cx,1 ; convert to a word count
- rep movsw ; move the word
- ;
- pop di ; restore di
- pop si ; restore si
- pop es ; restore es
- pop ds ; restore ds
- pop bp ; restore bp
- ret
- _movwords endp
- ;
- ;
- ;************************ _mbintr *************************
- ;
- _mbintr proc far
- cli ; disable hardware interrupts
- ;
- ; first save all the registers on entry
- ;
- push ds ; save ds
- push si ; save si
- push cx ; save cx
- push bx ; save bx
- push ax ; save ax
- ;
- push dx ; save dx
- push cx ; save cx
- push bx ; save bx
- push ax ; save ax
- ;
- ; set us DS to Point's DS since the interrupt mechanism does not
- ; set it (how could it?)
- ;
- mov ds,pgmds
- ;
- ; now compute the address of the event slot to put this in
- ; and store the next value (no interrupts so not need to wait on the store)
- ;
- mov bx,_evaddr ; address of the event array
- mov ax,_evtail ; where the last event was put
- inc ax ; move to the next event
- cmp ax,30 ; do modulo adjustment?
- jl l1
- sub ax,ax
- l1:
- mov _evtail,ax ; record the increment so C can see it
- mov cl,3 ; 4 words/event x 2 bytes/word
- shl ax,cl ; get an offset in 8 byte chunks
- add bx,ax ; address of the next event
- ;
- ; store the four event words in the event slot
- ;
- pop [bx+0] ; ax on entry moved to event slot
- pop [bx+2] ; bx on entry moved to event slot
- pop [bx+4] ; cx on entry moved to event slot
- pop [bx+6] ; dx on entry moved to event slot
- ;
- ; restore registers
- ;
- pop ax
- pop bx
- pop cx
- pop si
- pop ds
- ;
- ; done
- ;
- sti ; re-enable interrupts
- ret
- _mbintr endp
- ;
- ;************************ _evinit *************************
- ;
- ; set up mbintr as the mouse software interrupt handler
- ;
- _evinit proc far
- push bp ; save bp
- mov bp,sp
- push es ; save es
- mov pgmds,ds ; save ds for later
- ;
- mov ax,12 ; set subroutine mask
- mov cx,7FH ; interrupt on mouse buttons
- mov dx,offset _mbintr; address of interrupt handler
- push cs ; move cs to es
- pop es
- int 51 ; mouse function call
- ;
- pop es
- pop bp
- ret
- _evinit endp
- ;
- ;************************ _getvect *************************
- ;
- ;
- public _getvect
- _getvect PROC far
- push bp ; save bp
- mov bp,sp
- push es ; save es
- mov al,[bp+6] ; first arg is vector num
- mov ah,35H
- int 21H ; dos function call
- mov dx,es
- mov ax,bx
- pop es
- pop bp
- ret
- _getvect endp
- ;
- public _matchdn
- ;
- ; match = matchdn(text, textLength, pat, patlength);
- ; char *text, *pat, *match;
- ; int textLength, patLength;
- ;
- _matchdn proc far
- push bp
- mov bp,sp
- push si ; save si
- push di ; save di
- push es ; save es
- push ds ; move ds to es since di used a ds base
- pop es ; in medium model not always(es==ds)
- cld ; set search direction to forward
- mov cx,[bp+8] ; cx = length(text)
- sub cx,[bp+12] ; cx = length(text)-length(pat)
- jl notFound ; text shorter than pat
- inc cx ; + 1
- mov di,[bp+6] ; di --> text
- loop1:
- mov si,[bp+10] ; si --> pat
- mov al,[si] ; al = first char in pat
- repne scasb ; search for first char in pat
- jne notFound ; last comparison was not equal
- ; so cx got to zero w/o finding char
- mov dx,cx ; save text's cx
- mov bx,di ; save text's di
- mov cx,[bp+12] ; match for length of pat
- dec cx ; we already matched the first char
- jz foundIt ; pat is only one character long
- mov si,[bp+10] ; the cmpsb uses this
- inc si ; first char already was matched
- ; di is already set up
- repe cmpsb ; compare the strings
- je foundIt ; last compare was equal so we matched
- mov cx,dx ; restore cx
- mov di,bx ; the repe cmpsb changed di
- jmp loop1
- ;
- notFound:
- xor ax,ax ; return 0 == NULL
- jmp retlab
- foundIt:
- mov ax,bx ; bx = saved di (beginning of match)
- dec ax ; di was one past the start of
- ; the match
- retlab:
- pop es
- pop di
- pop si
- pop bp
- ret
- _matchdn endp
- ;
- ;************************ _matchup *************************
- ;
- ;
- public _matchup
- ;
- ; match = matchup(text, textLength, pat, patlength);
- ; char *text, *pat, *match;
- ; int textLength, patLength;
- ;
- _matchup proc far
- push bp
- mov bp,sp
- push si ; save si
- push di ; save di
- push es ; save es
- push ds ; move ds to es since di used a ds base
- pop es ; in medium model not always(es==ds)
- mov cx,[bp+8] ; cx = length(text)
- sub cx,[bp+12] ; cx = length(text)-length(pat)
- jl notupFound ; text shorter than pat
- inc cx ; + 1
- mov di,[bp+6] ; di --> text
- add di,cx ; start cx bytes up since we are
- ; searching backwards (std)
- loopup:
- mov si,[bp+10] ; si --> pat
- mov al,[si] ; al = first char in pat
- std ; set search direction to backward
- repne scasb ; search for first char in pat
- jne notupFound ; last comparison was not equal
- ; so cx got to zero w/o finding char
- mov dx,cx ; save text's cx
- mov bx,di ; save text's di
- mov cx,[bp+12] ; match for length of pat
- dec cx ; we already matched the first char
- jz foundupIt ; pat is only one character long
- mov si,[bp+10] ; the cmpsb uses this
- inc si ; first char already was matched
- ; di is already set up
- cld ; set search direction to forward
- repe cmpsb ; compare the strings
- je foundupIt ; last compare was equal so we matched
- mov cx,dx ; restore cx
- mov di,bx ; the repe cmpsb changed di
- jmp loopup
- ;
- notupFound:
- xor ax,ax ; return 0 == NULL
- jmp retup
- foundupIt:
- mov ax,bx ; bx = saved di (beginning of match)
- dec ax ; di was one past the start of
- ; the match
- retup:
- cld ; set search direction to forward
- pop es
- pop di
- pop si
- pop bp
- ret
- _matchup endp
- ;
- ;************************ _match2dn *************************
- ;
- public _match2dn
- ;
- ; match = match2dn(text, textLength, ch1);
- ; char far *text;
- ; char *match, ch1;
- ; int textLength;
- ;
- _match2dn proc far
- push bp
- mov bp,sp
- push di ; save di
- push es ; save es
- cld ; set search direction to forward
- ;
- ; look for the first character
- ;
- mov di,[bp+6] ; di --> text
- mov es,[bp+8] ; es = segment of text
- mov cx,[bp+10] ; cx = length(text)
- mov al,[bp+12] ; al = first char in pat
- repne scasb ; search for first char
- je found2It ; last comparison was equal
- mov ax,minus2 ; -2 for not found
- jmp comm2It
- found2It:
- mov ax,di ; save the result
- comm2It:
- pop es
- pop di
- pop bp
- ret
- _match2dn endp
- ;
- ;************************ _match1dn *************************
- ;
- public _match1dn
- ;
- ; match = match1dn(text, textLength, ch1, ch2);
- ; char far *text;
- ; char *match, ch1, ch2;
- ; int textLength;
- ;
- _match1dn proc far
- push bp
- mov bp,sp
- push di ; save di
- push es ; save es
- cld ; set search direction to forward
- ;
- ; look for the first character
- ;
- mov di,[bp+6] ; di --> text
- mov es,[bp+8] ; es = segment of text
- mov cx,[bp+10] ; cx = length(text)
- mov al,[bp+12] ; al = first char in pat
- repne scasb ; search for first char
- je found1It ; last comparison was equal
- mov bx,minus2 ; -2 for not found
- jmp comm1It
- found1It:
- mov bx,di ; save the result
- comm1It:
- ;
- ; look for the second character
- ;
- mov di,[bp+6] ; di --> text
- mov cx,[bp+10] ; cx = length(text)
- mov al,[bp+14] ; al = second char in pat
- repne scasb ; search for first char
- jne ret1 ; not found, so use 1st result
- cmp bx,minus2 ; found before also?
- jne ret2 ; yes, so compare the two
- mov bx,di ; no, so use this one
- jmp ret1
- ret2:
- cmp bx,di ; was first result smaller?
- jle ret1
- mov bx,di
- ret1:
- mov ax,bx
- pop es
- pop di
- pop bp
- ret
- _match1dn endp
- ;
- ;************************ _match1up *************************
- ;
- ;
- public _match1up
- ;
- ; match = match1up(text, textLength, ch1, ch2);
- ; char far *text;
- ; char *match, ch1, ch2;
- ; int textLength;
- ;
- _match1up proc far
- push bp
- mov bp,sp
- push di ; save di
- push es ; save es
- std ; set search direction to backward
- ;
- ; look for the first character
- ;
- mov di,[bp+6] ; di --> LAST byte of the text
- mov es,[bp+8] ; es = segment of text
- mov cx,[bp+10] ; cx = length(text)
- mov al,[bp+12] ; al = first char in pat
- repne scasb ; search for first char
- je found1upIt ; last comparison was equal
- mov bx,minus2 ; -2 for not found
- jmp comm1upIt
- found1upIt:
- mov bx,di ; save the result
- comm1upIt:
- ;
- ; look for the second character
- ;
- mov di,[bp+6] ; di --> text
- mov cx,[bp+10] ; cx = length(text)
- mov al,[bp+14] ; al = second char in pat
- repne scasb ; search for first char
- jne ret1up ; not found, so use 1st result
- cmp bx,minus2 ; found before?
- jne ret2up ; yes, compare the two answers
- mov bx,di ; no, so use this result
- jmp ret1up
- ret2up:
- cmp bx,minus1 ; This is a special case. bx=-1
- ; when the match was at the 0th
- ; character. We need to count this
- ; as low. If bx=-1 and both are
- ; valid use the other one.
- je useSecond
- cmp bx,di ; was first result larger?
- jae ret1up
- useSecond:
- mov bx,di
- ret1up:
- mov ax,bx
- cld ; set search direction to forward
- pop es
- pop di
- pop bp
- ret
- _match1up endp
- ;
- ;************************ _countnl *************************
- ;
- ;
- public _countnl
- ;
- ; find = countnl(addr, len);
- ; char far *addr;
- ; int len;
- ;
- _countnl proc far
- push bp
- mov bp,sp
- push di
- push es ; save es
- ;;;; push ds ; move ds to es (via the stack)
- ;;;; pop es ; complete move ds to es
- cld ; set search direction to forward
- xor bx,bx ; bx counts newlines (start at 0)
- mov cx,[bp+10] ; cx = length(text)
- mov di,[bp+6] ; di --> text to find nl in
- mov es,[bp+8] ; es --> segment of text
- mov al,10 ; al = newline (line feed) ASCII 10
- loopCnl:
- repne scasb ; search for a newline
- jne doneCnl ; last comparison was not equal
- ; so cx got to zero w/o finding nl
- ; so we are done
- inc bx ; count up the newlines
- jmp loopCnl
- doneCnl:
- mov ax,bx ; bx = newline count
- pop es
- pop di
- pop bp
- ret
- _countnl endp
- ;
- ;************************ _nextnl *************************
- ;
- ;
- public _nextnl
- ;
- ; find = nextnl(addr, len);
- ; char *addr;
- ; int len;
- ;
- _nextnl proc far
- push bp
- mov bp,sp
- push di
- push es ; save es
- push ds ; move ds to es (via the stack)
- pop es ; complete move ds to es
- cld ; set search direction to forward
- mov cx,[bp+8] ; cx = length(text)
- mov di,[bp+6] ; di --> text to find nl in
- mov al,10 ; al = newline (line feed)
- repne scasb ; search for a newline
- je foundIt2 ; last comparison was not equal
- ; so cx got to zero w/o finding nl
- dec cx ; return -1
- foundIt2:
- mov ax,cx ; cx = chars left unscanned
- pop es
- pop di
- pop bp
- ret
- _nextnl endp
- ;
- ;************************ _prevnl *************************
- ;
- public _prevnl
- ;
- ; find = prevnl(addr, len);
- ; char *addr;
- ; int len;
- ;
- _prevnl proc far
- push bp
- mov bp,sp
- push di
- push es ; save es
- push ds ; move ds to es (via the stack)
- pop es ; complete move ds to es
- std ; set search direction to backwards
- mov cx,[bp+8] ; cx = length(text)
- mov di,[bp+6] ; di --> text to find nl in
- mov al,10 ; al = newline (line feed)
- repne scasb ; search for a newline
- je foundIt3 ; last comparison was not equal
- ; so cx got to zero w/o finding nl
- dec cx ; return -1
- foundIt3:
- mov ax,cx ; cx = chars left unscanned
- pop es
- pop di
- pop bp
- cld ; set search direction to forward
- ret
- _prevnl endp
- ;
- ;************************ _horvid *************************
- ;
- ;
- public _horvid,_hor1vid
- ;
- ; this version writes the regen buffer during the horizontal refresh
- ; two characters per horizontal refresh
- ;
- _horvid proc far
- ; save registers
- push bp
- mov bp,sp
- push ax
- push bx
- push cx
- push dx
- push si
- push di
- push es
- ; set up video regen buffer
- mov ax,0B800H ; color/graphics regen buffer
- mov es,ax ; video regen memory in es
- mov di,[bp+6] ; offset into video regen buffer
- ; get other parameters
- mov si,[bp+8] ; offset of screen buffer from ds
- mov cx,[bp+10] ; number of words to move
- cld ; clear the direction flag
- ; wait for the vertical retrace
- ; we want the beginning of it, so wait until it is not
- ; on a retrace, then wait for the beginning of the next one
- l2:
- mov dx,3DAH ; I/O address of video port
- l3:
- in al,dx ; get video status
- test al,1 ; wait untile we are NOT
- jnz l3 ; on a horizontal retrace
- lodsw ; get the next word
- mov bx,ax ; save it in bx (need ax for 'in')
- ;
- ; disable interrupts, since the timing is critical here
- ; once we find the retrace, we have to write all the words
- ; without getting interrupted. An interrupt will throw us
- ; off and cause snow on the screen
- ;
- cli ; diable interrupts while writing
- l4:
- in al,dx ; get video status
- test al,1 ; wait for horizontal retrace
- jz l4
- ; move a word into the video buffer
- mov ax,bx ; recover from bx
- stosw ; store one word
- sti ; re-enable interrupts
- loop l2 ; loop while cx > 0 (more words to move)
- ; restore the registers and return
- pop es
- pop di
- pop si
- pop dx
- pop cx
- pop bx
- pop ax
- pop bp
- ret
- ;
- _horvid endp
- ;
- ;************************ _hor1vid *************************
- ;
- ; this version writes the regen buffer during the horizontal refresh
- ; one character per horizontal refresh
- ;
- _hor1vid proc far
- ; save registers
- push bp
- mov bp,sp
- push ax
- push bx
- push cx
- push dx
- push si
- push di
- push es
- ; set up video regen buffer
- mov ax,0B800H ; color/graphics regen buffer
- mov es,ax ; video regen memory in es
- mov di,[bp+6] ; offset into video regen buffer
- ; get other parameters
- mov si,[bp+8] ; offset of screen buffer from ds
- mov cx,[bp+10] ; number of words to move
- cld ; clear the direction flag
- ; wait for the vertical retrace
- ; we want the beginning of it, so wait until it is not
- ; on a retrace, then wait for the beginning of the next one
- m2:
- mov dx,3DAH ; I/O address of video port
- m3:
- in al,dx ; get video status
- test al,1 ; wait untile we are NOT
- jnz m3 ; on a horizontal retrace
- lodsb ; get the next byte
- mov bl,al ; save it in bl (need al for 'in')
- ;
- ; disable interrupts, since the timing is critical here
- ; once we find the retrace, we have to write all the words
- ; without getting interrupted. An interrupt will throw us
- ; off and cause snow on the screen
- ;
- cli ; diable interrupts while writing
- m4:
- in al,dx ; get video status
- test al,1 ; wait for horizontal retrace
- jz m4
- ; move a word into the video buffer
- mov al,bl ; recover from bx
- stosb ; store one byte
- sti ; re-enable interrupts
- loop m2 ; loop while cx > 0 (more bytes to move)
- ; restore the registers and return
- pop es
- pop di
- pop si
- pop dx
- pop cx
- pop bx
- pop ax
- pop bp
- ret
- ;
- _hor1vid endp
- SUPPORT_TEXT ENDS
- end
-