Category : Utilities for DOS and Windows Machines
Archive   : CUTPAST3.ZIP
Filename : CUTPAST3.ASM

 
Output of file : CUTPAST3.ASM contained in archive : CUTPAST3.ZIP
PAGE 55,132
TITLE CUTPASTE 3.0
;
; CUTPASTE -
; Permission is granted to copy and distribute freely copies of this
; program with the following restrictions:
;
; 1) this program be passed in the public domain
; 2) a fee, beyond the cost of the disk, not be charged
; 3) improvements not be passed on but rather sent to us
; to check for possible incompatibilities with other programs
;
; Gerry Boyd, Larry Weiss, (Stephen) Randy Davis
; (214) 238-9545 POB 831420 Richardson, Texas 75083

;PARAMETERS -- MOST OF THESE MAY BE CHANGED TO ANY DESIRED VALUE

wndw_ht equ 25 ;the size of the screen
wndw_wd equ 80
cut_key equ 07000H ;scan code - ascii of cut (Alt-F9)
paste_key equ 06600H ;scan code - ascii of paste (Cntrl-F9)
;now scan codes of edit keys
up_arrow equ 4800H
down_arrow equ 5000H
left_arrow equ 4B00H
right_arrow equ 4D00H
del_left equ 0008H ;user rubout (^H) key
delete equ 5300H ;use del (lower right)
insert equ 5200H
cr equ 000DH
home equ 4700H
escape equ 001BH
tab equ 7400H ; ^right arrow
rev_tab equ 7300H ; ^left arrow
line_ins equ 5100H ;pg down
line_del equ 4900H ;pg up
mark_char equ 4F00H ;end key

blank equ 00720H ;define the character which is a blank
attrib equ 007H ;and our default attribute (should agree with blank)
video equ 10H ;video BIOS call
inv_attrib equ 070H ;inverse of 'attrib'
PAGE
CSEG SEGMENT PARA PUBLIC 'CODE'
ASSUME CS:CSEG,DS:CSEG,SS:CSEG,ES:NOTHING ;STANDARD DECL FOR .COM FILE

ORG 100H

Start:
JMP INSTALL

;PLACE DATA AREA HERE FOR READIBILITY

COPYRITE DB 'Copyright Gerry Boyd, Larry Weiss, Randy Davis 1985 All Rights Reserved'
DB '(214)238-9545'
SCREENSAVE: DW (WNDW_HT * (WNDW_WD+1)) DUP (BLANK);RESERVE SPACE TO SAVE OPENED WINDOW
LINESAVE: DW WNDW_WD DUP (BLANK) ;BUFFER FOR LINE DELETE

CURSOR_POS DW 0
OLD_CUR_POS DW 0
SAVESTACK DW 0,0

REQUEST DW 0 ;REQUEST TYPE

KEY_RQST_HANDLER DD 0 ;ADDRESS OF THE ORIGINAL KEYBOARD REQUEST HANDLER

LEFT_MARG DB 00 ;define the confines of the window
RIGHT_MARG DB 00
TOP_MARG DB 00
BOT_MARG DB 00
UPPER_LEFT DW 00

MARK DW -1 ;FLAGS USED IN CHARACTER FEED
FEED_START DW 00 ;ADDRESS IN BUFFER OF BEGIN...
FEED_STOP DW 00 ;...AND END OF FEED
FEED_END1 DW 00 ;TEMP HOLDING SPOT FOR BEG FEED ADDR
FEED_END2 DW 00 ;TEMP HOLDING SPOT FOR END FEED ADDR

FEED_CHAR DW 00 ;CHAR TO FEED ON THIS CALL

DISPLAY_SEG DW 00 ;SAVE OFF THE DISPLAY SEGMENT ***
PAGE
BEGIN PROC FAR ;FAR LABEL SINCE ITS ENTERED BY INTERRUPT
MAINLOOP:
MOV CS:REQUEST,AX ;SAVE HIS AX REGISTER

MOV AX,CS:FEED_START ;ARE WE IN THE MIDDLE OF FEEDING CHARS...
CMP AX,CS:FEED_STOP ;...TO THE APPLICATION?
JZ NOFEED ;NO
JMP FEED ;YES
NOFEED:
MOV AX,CS:REQUEST ;RESTORE USERS AX
PUSHF ;CALL OLD INTERRUPT HANDLER (EMULATE INT INSTRUCTION)
CALL DWORD PTR [CS:KEY_RQST_HANDLER] ;GO AHEAD AND GET THE CHARACTER
PUSHF ;SAVE THE FLAG RETURNED (FOR AH = 1 REQUESTS)

CMP CS:BYTE PTR REQUEST+1,00H ;WE ARE ONLY INTERESTED IN CHAR. REQUESTS
JZ CNTINUE
JMP FORGET_IT

CNTINUE: ;YES -- CHECK CHARACTER FOR 'OURS'
POPF ;FOR NON-TYPE 1 REQUESTS DONT NEED TO SAVE FLAGS
CMP AX,CUT_KEY
JZ CNT_AGIN
CMP AX,PASTE_KEY
JZ PASTE_CHAR

JMP RETURN_CHAR

CNT_AGIN: ;WE GOT IT! GO INTO EDITOR MODE
MOV CS:SAVESTACK,SP
MOV CS:SAVESTACK+2,SS
MOV AX,CS
MOV SS,AX
MOV SP,100H

STI ;ENABLE INTERRUPTS WHILE PROCESSING CHARACTERS

PUSH BP ;SET UP A STACK FRAME
MOV BP,SP
SUB SP,0EH
CALL SAVEREG
MOV DS,AX

CALL CALC_WINDOW ;CALCULATE WINDOW EXTREMETIES

CALL READ_CURSOR
MOV OLD_CUR_POS,DX ;SAVE THE CURSOR FOR LATER RESTORING

CALL WINDOW_SAVE ;SAVE SCREEN

MOV DX,CURSOR_POS ;RESTORE CURSOR IN EDIT WINDOW
CALL PLACE_CURSOR

CALL EDITOR ;LET HIM EDIT IN THE WINDOW

CALL READ_CURSOR
MOV CURSOR_POS,DX ;SAVE CURSOR IN EDIT WINDOW FOR NEXT EDIT

CALL WINDOW_SWAP ;PUT BACK WHATEVER WAS ORIGINALLY THERE

MOV DX,OLD_CUR_POS ;RESTORE THE CURSOR POSITION
CALL PLACE_CURSOR

CALL RESTREG
ADD SP,0EH
POP BP

MOV SS,CS:SAVESTACK+2
MOV SP,CS:SAVESTACK

MOV AH,00 ;RESTORE REQUEST TO SOMETHING DECENT
JMP MAINLOOP ;GO GET ANOTHER CHARACTER TO RETURN HIM

PASTE_CHAR:
MOV AX,CS:FEED_END1 ;BEGIN TO FEED CHARACTER STRING INTO APPLICATION
MOV CS:FEED_START,AX
MOV AX,CS:FEED_END2
MOV CS:FEED_STOP,AX

MOV AH,00 ;RESTORE REQUEST TO SOMETHING DECENT
JMP MAINLOOP ;GO GET ANOTHER CHARACTER TO RETURN HIM

RETURN_CHAR:
IRET ;RETURN WITH CHARACTER

;HANDLE REQUEST TYPE 1'S BY FAR RETURNING 2 AND TYPE 2'S BY JUST RETURNING

FORGET_IT:
CMP CS:BYTE PTR REQUEST+1,1 ;was it a "is char present" request?
JZ FI100

POPF ;no -- just return whatever BIOS returned
IRET

FI100:
POPF ;yes -- make funny return
RET 02
PAGE
;HERE WE ARE IN THE PROCESS OF FEEDING CHARACTERS TO THE APPLICATION
;FROM THE WINDOW BUFFER (SCREENSAVE)

FEED:
CMP CS:BYTE PTR REQUEST+1,1 ;WAS THIS A CHAR TYPE REQUEST?
JA KSTAT
;YES -- RETURN HIM CHAR
PUSH BX ;GET THE NEXT CHARACTER FROM THE BUFFER
MOV BX,AX
MOV AX,CS:[BX]
POP BX
XOR AH,AH ;WE NO LONGER HAVE THE SCAN CODE, BUT ALL
MOV CS:FEED_CHAR,AX ;ARE ASCII ANYWAY

CMP CS:BYTE PTR REQUEST+1,0 ;IS THIS A 'GET KEYBOARD CHAR' RQST?
JNZ FEED_KEY_STAT

ADD CS:FEED_START,2 ;YES -- MOVE UP THE POINTER BY 1


; SKIP ANY TRAILING BLANKS
PUSH BX
MOV BX,CS:FEED_START
FEED10:
CMP BX,CS:FEED_STOP
JZ FEED50
MOV AX,CS:[BX]
CMP AL,' '
JZ FEED20
CMP AL,00DH
JNZ FEED50
MOV CS:FEED_START,BX
JMP FEED50
FEED20:
INC BX
INC BX
JMP FEED10
FEED50:
POP BX

MOV AX,CS:FEED_CHAR
IRET

FEED_KEY_STAT:
STI ;NO -- ENABLE INTERRUPTS AND FEED HIM THE
RET 02 ;THE Z FLAG CLEAR WITH HIS CHAR

KSTAT:
MOV AX,CS:REQUEST ;RESTORE REQUEST TO AH
PUSHF
CALL DWORD PTR [CS:KEY_RQST_HANDLER] ;PERFORM BIOS CALL -- WE DON'T KNOW
;WHAT HE'S DOING AND WE SHOULDN'T GET IN THE WAY
IRET ;RETURN THE RESULTS TO HIM (WHATEVER THEY ARE)
BEGIN ENDP
PAGE
BODY PROC NEAR ;MAKE SHORT CALLS ONLY TO THE MAIN ROUTINES
CALC_WINDOW:
MOV AH,0FH ;FIND OUT VIDEO MODE FOR CALCULATING WINDOW SIZE
INT VIDEO ;GO AHEAD AND GET THE CHARACTER

;***SAVE OFF THE VIDEO SEGMENT***

MOV CX,0B000H ;IS IT MONOCHROME?
CMP AL,7 ;WELL LOOK FOR MODE 7
JZ CW100
MOV CX,0B800H ;NO -- ITS GRAPHIX
CW100:
MOV DISPLAY_SEG,CX ;SAVE THIS OFF
;***

DEC AH ;THIS IS THE NUMBER OF COLS ON SCREEN
MOV RIGHT_MARG,AH ;SET UP RIGHT AND LEFT MARGINS
SUB AH,(WNDW_WD - 1)
MOV LEFT_MARG,AH

MOV TOP_MARG,0 ;WE HAVE NO INFORMATION ON NUMBER OF ROWS
MOV BOT_MARG,WNDW_HT-1 ;SO WE MUST ASSUME SOMETHING NORMAL (IT ISNT
;AS CRITICAL ANYWAY)

MOV AL,AH ;NOW ADD UPPER_LEFT HAND CORNER VALUE
XOR AH,AH
MOV UPPER_LEFT,AX


CMP CURSOR_POS,0 ;IF THIS IS THE FIRST TIME WEVE DONE THIS...
JNZ CW200
MOV CURSOR_POS,AX ;...PLACE THE CURSOR IN THE UPPER LEFT HAND CORNER

CW200:
RET
PAGE
;***NEW WINDOW_SWAP PROCEDURE AND WINDOW_SAVE COMBINED -- TWO DIFFERENT
;ENTRY POINTS TELL WHETHER TO DO THE WRITE OR NOT
;NOTE THAT THIS PROCEDURE DOES NOT BIOS CALLS -- ALL DIRECT WRITES

SWAP_SAVE DB 0

WINDOW_SAVE:
MOV SWAP_SAVE,0 ;MARK THIS ENTRY POINT
JMP WS025

WINDOW_SWAP:
MOV SWAP_SAVE,0FFH ;MARK THIS DIFFERENT ENTRY POINT

WS025:
MOV CX,WNDW_HT ;GET THE NUMBER OF ROWS IN WINDOW AREA
MOV SI,OFFSET SCREENSAVE;START AT BEGINNING OF BUFFER
MOV ES,DISPLAY_SEG ;LOAD UP THE VIDEO SEGMENT
MOV DI,00
XOR BX,BX
WS050:
MOV BL,LEFT_MARG ;START ON THIS LINE AT THE LEFT MARGIN
WS100:
SHL BX,1 ;CHANGE THE COLUMN NUMBER TO BYTE POINTER
MOV AX,ES:[BX][DI] ;GET THE NEXT CHARACTER FROM SCREEN
XCHG AX,[SI] ;STORE IT AWAY AND WRITE THE SAVED CHARACTER
ADD SI,2 ;AND MOVE SAVE POINTER OVER A WORD
;***HERE IS THE SWAP SAVE CHECK
CMP SWAP_SAVE,0 ;IS THIS WINDOW SWAP OR WINDOW SAVE?
JZ WS150
;MUST BE SWAP
MOV ES:[BX][DI],AX ;NOW RESTORE THAT CHARACTER TO THE SCREEN
WS150:
;***
SHR BX,1 ;PUT THE BYTE OFFSET BACK TO COLUMN NUMBER
INC BX
CMP BL,RIGHT_MARG ;ARE WE BEYOND THE END OF THE LINE?
JNA WS100
;YES -- SKIP DOWN TO NEXT LINE

MOV WORD PTR [SI],000DH ; SO CR'S ARE FED PROPERLY LATER
INC SI
INC SI

SHL BX,1 ;ADJUST DI BY ONE LINE'S WORTH SO THAT IT
ADD DI,BX ;POINTS TO BEGINNING OF NEXT LINE
LOOP WS050
RET
PAGE
EDITOR:

;check for edit keys (such as insert, delete, etc.)
;if not one of those, assume its ascii and just insert it in the
;screen return when AltF10 detected.

ED100:
CALL GET_CHAR ;read a character from the keyboard
OR AL,AL ;if this is ascii then dont retain scan code
JZ ED105
XOR AH,AH

ED105:
CALL UNSHADE_SCREEN ;REMOVE PREVIOUS SHADING (IF ANY)

MOV BX,CURSOR_POS ;in many cases we need the cursor position
CMP AX,CUT_KEY ;check for exit
JNZ ED110
JMP ED800

ED110:
CMP AX,CR ;check for each special character individually
JNZ ED120
MOV BL,LEFT_MARG
INC BH
JMP ED500
ED120:
CMP AX,LEFT_ARROW
JNZ ED140
DEC BL
JMP ED500

ED140:
CMP AX,RIGHT_ARROW
JNZ ED160
INC BL
JMP ED500

ED160:
CMP AX,UP_ARROW
JNZ ED180
DEC BH
JMP ED500

ED180:
CMP AX,DOWN_ARROW
JNZ ED200
INC BH
JMP ED500

ED200:
CMP AX,HOME
JNZ ED205
MOV BX,UPPER_LEFT
JMP ED500

ED205: ;tab and back tab functions
CMP AX,TAB
JNZ ED210
MOV CL,1 ;go forward
JMP ED213

ED210:
CMP AX,REV_TAB
JNZ ED220

MOV CL,0FFH ;go backwards one tab slot
ADD DL,CL ;start one char to left initially

ED213:
CALL READ_CHAR ;get char at current position
MOV CH,AL ;save it for comparison
ED215:
ADD DL,CL ;move over one character
CMP DL,RIGHT_MARG ;stop at left and right margins (or beyond)
JGE ED218
CMP DL,LEFT_MARG
JLE ED218

CALL READ_CHAR ;read current character
CMP CH,' ' ;if original was a space...
JNZ ED216
CMP AL,' ' ;...then go until not space
JZ ED215
JMP ED217
ED216:
CMP AL,' ' ;...else, go until space
JNZ ED215
ED217:
CMP CL,0FFH ;if we were going backwards (towards left)...
JNZ ED218
ADD DL,1 ;...then scoot back to the right by 1
ED218:
MOV BX,DX
JMP ED500

ED220:
CMP AX,ESCAPE ;wipe out remainder of line
JNZ ED240
MOV DX,BX
CALL ERASE_LINE
JMP ED500

ED240:
CMP AX,DEL_LEFT ;move cursor left one char and then do normal del
JNZ ED260
DEC BL
CMP BL,LEFT_MARG
JNB ED250
MOV BL,RIGHT_MARG
CMP BH,00
JZ ED250
DEC BH
ED250:
JMP ED270

ED260:
CMP AX,DELETE ;in delete char we...
JNZ ED280
ED270:
MOV CL,RIGHT_MARG
SUB CL,BL ;calculate how many chars to right margin
XOR CH,CH
MOV DX,BX ;...start at current cursor position...
JCXZ ED275
ED272:
INC DL ;...get character just to the right...
CALL READ_CHAR
DEC DL ;...move left one position...
CALL WRITE_CHAR ;...and write it there...
INC DL ;...now do it again for the char to the right...
LOOP ED272 ;...for the distance from cursor to right margin;...
ED275:
MOV AX,BLANK
CALL WRITE_CHAR
JMP ED500

ED280:
CMP AX,INSERT ;in the case of insert we do reverse of delete
JNZ ED300
MOV DH,BH ;start at the right margin
MOV DL,RIGHT_MARG
MOV CL,DL ;caculate number of spaces to right
SUB CL,BL
XOR CH,CH
JCXZ ED290
ED285:
DEC DL
CALL READ_CHAR
INC DL
CALL WRITE_CHAR
DEC DL
LOOP ED285
ED290:
MOV AX,BLANK
CALL WRITE_CHAR
JMP ED500

ED300:
CMP AX,LINE_INS ;check for insert line
JNZ ED320
MOV DH,BOT_MARG ;we're going to need that
ED305:
MOV DL,LEFT_MARG ;always start at the far left
CMP DH,BH ;are we on our current line?
JZ ED315
;no -- then move it down
MOV CX,WNDW_WD
ED310:
DEC DH
CALL READ_CHAR ;get the character
INC DH
CALL WRITE_CHAR ;and put it back one line higher
INC DL ;move right one character
LOOP ED310

DEC DH ;now move up a line and do it again
JMP ED305
ED315:
MOV BL,LEFT_MARG ;move us over the far left marg
CALL ERASE_LINE ;and wipe out the line we are on
JMP ED500

ED320:
CMP AX,LINE_DEL ;and check for line delete
JNZ ED340

ED325:
MOV DL,LEFT_MARG ;always start at the far left
CMP DH,BOT_MARG ;are we on the last line?
JZ ED335
;no -- then move it up
MOV CX,WNDW_WD
ED330:
INC DH
CALL READ_CHAR ;get the character
DEC DH
CALL WRITE_CHAR ;and put it back one line lower
INC DL ;move right one character
LOOP ED330

INC DH ;now move down a line and do it again
JMP ED325
ED335:
MOV BL,LEFT_MARG ;move us over the far left marg of our line
CALL ERASE_LINE ;and wipe out the bottom line
JMP ED500

ED340:
CMP AX,MARK_CHAR ;check for mark
JNZ ED400

MOV DX,BX
CMP MARK,-1 ;if mark isnt set...
JNZ ED350
MOV MARK,BX ;...just set it and switch its attrib
CALL READ_CHAR
MOV AH,ATTRIB
CALL WRITE_CHAR
JMP ED500

ED350: ;else, store off feed start and end addresses
CALL CONVERT_LOC
MOV FEED_END1,AX

MOV DX,MARK
CALL CONVERT_LOC
MOV FEED_END2,AX

MOV CX,FEED_END1
CMP CX,AX
JNA ED355
MOV FEED_END1,AX
MOV FEED_END2,CX
ED355:
CALL TRIM_SCREEN ;TRIM OFF UNMARKED THINGS ON SCREEN
JMP ED800 ;note that this char exits the note pad

ED400: ;wasnt an edit character -- must be ascii
;just write the character at current position
MOV AH,ATTRIB
CALL W_CHAR
INC BL ;move over one position

ED500: ;adjust resulting cursor position
CMP BL,RIGHT_MARG
JLE ED550
MOV BL,RIGHT_MARG
ED550:
CMP BH,BOT_MARG
JLE ED600
MOV BH,BOT_MARG
ED600:
CMP BL,LEFT_MARG
JGE ED650
MOV BL,LEFT_MARG
ED650:

CMP BH,TOP_MARG
JGE ED700
MOV BH,TOP_MARG
ED700:
MOV CURSOR_POS,BX
MOV DX,BX ;be sure and move the cursor to the new
CALL PLACE_CURSOR ;position
JMP ED100

ED800: ;exit
RET
PAGE
;
; HERE WE PLACE SOME SMALL GENERAL PURPOSE ROUTINES
;

PLACE_CURSOR: ;place cursor at location in dx

CALL SHADE_SCREEN ;if we are in mark mode, set the
;screen square to inverse video
MOV AH,2H
PUSH BX
XOR BX,BX
INT VIDEO
POP BX
RET

UP_LEFT DW 0
LW_RIGHT DW 0
ATTRIBUTE DB 0
SAVE_AX DW 0
SAVE_DX DW 0

SHADE_SCREEN: ;NEW SCREEN SHADING PROCEDURE
CMP MARK,-1H ;IS A MARK SET?
JZ SS_END
;YES -- OK SWING INTO ACTION
MOV SAVE_AX,AX
MOV SAVE_DX,DX
MOV ATTRIBUTE,INV_ATTRIB ;FIRST SET THE ATTRIBUTE TO INVERSE
MOV BX,CURSOR_POS
MOV AX,MARK ;NOW, CALCULATE THE UPPER LEFT CORNER...
CMP BL,AL ;...OF OUR SHADED BOX
JA SS100
MOV AL,BL
SS100:
CMP BH,AH
JA SS200
MOV AH,BH
SS200:
MOV UP_LEFT,AX
MOV AX,MARK ;NOW THE LOWER RIGHT CORNER
CMP BL,AL
JB SS300
MOV AL,BL
SS300:
CMP BH,AH
JB SS400
MOV AH,BH
SS400:
MOV LW_RIGHT,AX
JMP SS_COMMON

UNSHADE_SCREEN:
CMP MARK,-1H ;HERE WE UNSHADE THE SHADED AREA
JZ SS_END
MOV SAVE_AX,AX
MOV SAVE_DX,DX
MOV ATTRIBUTE,ATTRIB ;CHANGE THE BOX BACK TO NORMAL


;NOW BEGIN TO SHADE IN FROM THE UPPER LEFT TO THE LOWER RIGHT CORNERS

SS_COMMON:
MOV DX,UP_LEFT
MOV BX,LW_RIGHT
SS500:
CMP DL,BL ;ARE WE OFF THE RIGHT END?
JA SS600
MOV AH,ATTRIBUTE
CALL WRITE_ATTRIB
INC DL
JMP SS500
SS600:
INC DH ;OK WE WENT OFF THE RIGHT END...
CMP DH,BH ;...MOVE DOWN ONE AND CHECK LOWER BOUND
JA SS700
MOV DL,BYTE PTR UP_LEFT
JMP SS500
SS700:
MOV AX,SAVE_AX
MOV DX,SAVE_DX
SS_END:
RET

TRIM_SCREEN: ;AFTER HE SELECTS THE SECOND MARK
;WE TRIM OFF THE RIGHT MARG OF SCREEN
MOV MARK,-1H ;FIRST CLEAR MARK
MOV BX,UP_LEFT ;START WITH THE FIRST LINE
MOV BL,BYTE PTR LW_RIGHT
TS100:
MOV DX,LW_RIGHT ;COMPARE THIS WITH THE LAST LINE
CMP BH,DH ;FINISHED?
JZ TS200
MOV DX,BX ;NO -- ERASE THE END OF THIS LINE
CALL ERASE_LINE
INC BH ;AND CONTINUE ON TO NEXT LINE
JMP TS100
TS200:
RET

READ_CURSOR: ;read cursor location into dx
MOV AH,3H
PUSH BX
XOR BX,BX
INT VIDEO
POP BX
RET

;***NEW READ CHAR PROCEDURE***
READ_CHAR: ;read screen character at location in dx
CALL CALC_VID_LOC ;covert the row and column into location
MOV AX,ES:[DI] ;get the character at that location
RET
;***

R_CHAR: ;read screen char at current cursor location
MOV AH,8H
PUSH BX
XOR BH,BH
INT VIDEO
POP BX
RET

;***NEW WRITE CHAR PROCEDURE
WRITE_CHAR: ;write attrib/char in ax at location in dx
PUSH AX ;save the attrib from destruction
CALL CALC_VID_LOC ;convert the row and column into location
POP AX
MOV ES:[DI],AX
RET
WRITE_ATTRIB:
PUSH AX
CALL CALC_VID_LOC
POP AX
MOV ES:01[DI],AH
RET
;***

W_CHAR: ;write character at current cursor location
PUSH BX ;save bx register
MOV BL,AH
XOR BH,BH
PUSH CX ;retain cx register also
MOV CX,1
MOV AH,9H
INT VIDEO
POP CX
POP BX
RET

GET_CHAR: ;get character from keyboard into ax
MOV AH,0H
PUSHF ;simulate call to keyboard handler
CALL DWORD PTR [KEY_RQST_HANDLER]
RET

ERASE_LINE: ;erase the current line from dx to right margin
MOV CL,RIGHT_MARG
SUB CL,BL
INC CL
XOR CH,CH
MOV SI,OFFSET LINESAVE

ER100:
CALL READ_CHAR ;get the character @ current location
MOV [SI],AX
ADD SI,2

MOV AX,BLANK
CALL WRITE_CHAR ;***CHANGED FROM W_CHAR***
INC DL
LOOP ER100
RET

RESTORE_LINE: ;restore the current line from dx to right margin
MOV CL,RIGHT_MARG
SUB CL,BL
INC CL
XOR CH,CH
MOV DI,OFFSET LINESAVE

RL100:
MOV AX,[DI] ;get the saved char
CALL WRITE_CHAR ;put the saved char where indicated
ADD DI,2
INC DL
LOOP RL100
RET

CONVERT_LOC: ;convert a location on the screen (in dx) into AX
MOV CX,DX
MOV AX,OFFSET SCREENSAVE
CL100:
CMP CH,TOP_MARG
JZ CL200
ADD AX,(WNDW_WD+1)*2
DEC CH
JMP CL100

CL200:
CMP CL,LEFT_MARG
JZ CL300
ADD AX,2
DEC CL
JMP CL200

CL300:
RET

SAVEREG:
MOV -2[BP],BX ;save reggies on stack frame
MOV -4[BP],CX
MOV -6[BP],DX
MOV -8[BP],SI
MOV -0AH[BP],DI
MOV -0CH[BP],DS
MOV -0EH[BP],ES ;***ADDED SAVING OF ES***
RET
RESTREG:
MOV BX,-2[BP] ;NOW PUT THE REGGIES BACK AND PULL DOWN
MOV CX,-4[BP] ;THE STACK FRAME
MOV DX,-6[BP]
MOV SI,-8[BP]
MOV DI,-0AH[BP]
MOV DS,-0CH[BP]
MOV ES,-0EH[BP] ;***ADD RESTORE OF ES***
RET

;***NEW PROCEDURE TO CONVERT ROW AND COLUMN INTO ADDRESS

CALC_VID_LOC: ;convert the row and column in dx into an
;offset into the video display buffer
XOR AX,AX
XOR DI,DI
PUSH CX ;save cx -- some of those who call us need it
XOR CX,CX

MOV AL,RIGHT_MARG ;get the width of a row
INC AX
MOV CL,DH ;put the number of rows into cx
JCXZ CVL200
CVL100:
ADD DI,AX ;for every row add in another 80/40 columns
LOOP CVL100
CVL200:
MOV AL,DL ;now move over to the current column
ADD DI,AX

POP CX ;restore cx

SHL DI,1 ;now convert this into byte offset
MOV ES,DISPLAY_SEG
RET
;***

BODY ENDP
PAGE
INSTALL:
;THIS PROGRAM INSTALLS THE REST OF THE CODE FOR NOTE PAD

MOV DX,OFFSET MESSAGE ;OUTPUT 'OK' MESSAGE
MOV AH,9H
INT 21H

MOV AX,3516H ;GET INTERRUPT 16 VECTOR
INT 21H
MOV WORD PTR KEY_RQST_HANDLER,BX
MOV WORD PTR KEY_RQST_HANDLER+2,ES

MOV AX,2516H
MOV DX,OFFSET BEGIN ;NOW PUT OUR ROUTINE THERE
INT 21H

MOV DX,OFFSET INSTALL ;TERMINATE AND STAY RESIDENT
ADD DX,100H
MOV CL,4
SHR DX,CL
MOV AH,31H
INT 21H

MESSAGE DB 10,13,'CUTPASTE 3.0 installed',10,13,' ALT F9 to enable cut',
DB 10,13,' ^F9 to paste ',10,13,'$'

CSEG ENDS
END START


  3 Responses to “Category : Utilities for DOS and Windows Machines
Archive   : CUTPAST3.ZIP
Filename : CUTPAST3.ASM

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/