home *** CD-ROM | disk | FTP | other *** search
- PAGE 55,132
- TITLE NOTEPAD4
- ;
- ;NotePad IV - NON BIOS VERSION
- ; 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 me
- ; to check for possible incompatibilities with other programs
- ;
- ; (Stephen) Randy Davis and Larry Weiss
- ; (214)454-2426
- ;
- ; feel free to call with bugs or questions
- ;
-
- ;PARAMETERS -- MOST OF THESE MAY BE CHANGED TO ANY DESIRED VALUE
-
- wndw_ht equ 24 ;mark the size of the window to open
- wndw_wd equ 40
- our_key equ 07100H ;scan code - ascii of key to open window
- ;now scan codes of edit keys (AltF10)
- up_arrow equ 4800H
- down_arrow equ 5000H
- left_arrow equ 4B00H
- right_arrow equ 4D00H
- del_left equ 0008H ;user rubout (cntrl 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
- print_char equ 372AH ;PrtSc* = print note on printer
- file_change equ 4A2DH ;key to update file and get a new one
-
- blank equ 07020H ;define the character which is a blank
- attrib equ 070H ;and our default attribute (should agree with blank)
- video equ 10H ;video BIOS call
- inv_attrib equ 007H ;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 Stephen R. Davis, Larry Weiss 1985 All Rights Reserved'
- DB '(214)454-2426'
- 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 DB 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 00 ;FLAGS USED IN CHARACTER FEED
- FEED_START DW 00 ;ADDRESS IN BUFFER OF BEGIN...
- FEED_END DW 00 ;...AND END OF FEED
-
- DISPLAY_SEG DW 00 ;DISPLAY SEGMENT (B000 -> MONOCHROME,
- ; B800 -> GRAPHIX)
-
- FILE_NM_LOC DW 00 ;ADDRESS OF FILE NAME (0 -> NO FILE)
- PAGE
- BEGIN PROC FAR ;FAR LABEL SINCE ITS ENTERED BY INTERRUPT
- MAINLOOP:
- MOV CS:REQUEST,AH ;SAVE HIS AX REGISTER
-
- MOV AX,CS:FEED_START ;ARE WE IN THE MIDDLE OF FEEDING CHARS...
- CMP AX,CS:FEED_END ;...TO THE APPLICATION?
- JZ NOFEED ;NO
- JMP FEED ;YES
- NOFEED:
- MOV AH,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:REQUEST,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,OUR_KEY
- JZ CNT_AGIN
- 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_SWAP ;SWING IN THE EDIT WINDOW (WITH NOTES?)
-
- CALL INSERT_CR ;PUT THE CARRIAGE RETURNS ON UNPRINTABLE COL.S
-
- 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
-
- CMP MARK,00H ;CLEAR THE MARK POSITION (IF IT'S SET)
- JZ NOT_SET
- MOV DX,MARK
- CALL READ_CHAR ;GET THE CHARACTER...
- MOV AH,ATTRIB ;...PUT ITS ATTRIBUTE BACK TO EVERYONE ELSE'S...
- CALL WRITE_CHAR ;...AND PUT IT BACK
- MOV MARK,00H
- NOT_SET:
-
- CALL WINDOW_SWAP ;PUT BACK WHATEVER WAS ORIGINALLY THERE
-
- CALL UPDATE_FILE ;NOW ATTEMPT TO UPDATE THE DISK FILE
-
- 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
-
- 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:REQUEST,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:REQUEST,1 ;WAS THIS A CHAR TYPE REQUEST?
- JA KSTAT
- ;YES -- RETURN HIM CHAR
- PUSH BX ;GET THE NEXT CHARACTER FROM THE BUFFER
- CALL SKIP_SPACES ;STRIP LEADING SPACES
-
- MOV BX,CS:FEED_START ;OK - GET THE NEXT CHARACTER WE NEED
- MOV AX,CS:[BX]
- POP BX
- XOR AH,AH ;WE NO LONGER HAVE THE SCAN CODE, BUT ALL
- ;ARE ASCII ANYWAY
-
- CMP CS:REQUEST,0 ;IS THIS A 'GET KEYBOARD CHAR' RQST?
- JNZ FEED_KEY_STAT
-
- ADD CS:FEED_START,2 ;YES -- MOVE UP THE POINTER BY 1
- IRET
-
- FEED_KEY_STAT:
- STI ;NO -- ENABLE INTERRUPTS AND FEED HIM THE
- RET 02 ;THE Z FLAG CLEAR WITH HIS CHAR
-
- KSTAT:
- MOV AH,CS:REQUEST ;RESTORE REQUEST TO AH
- 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
-
- SKIP_SPACES:
- ;TRY TO AVOID FEEDING SPACES WITH NOTHING AFTER THEM ON A LINE --
- ;JUST SKIP OVER TO THE RETURN AND FEED THAT ALONE
-
- MOV BX,CS:FEED_START ;START WITH THE NEXT FEED CHARACTER
- LOOK_AHEAD:
- MOV AX,CS:[BX]
- CMP AL,CR ;IS THIS CHAR A RETURN
- JZ STRIP_SPACES
- CMP AL,' ' ;IS THIS CHARACTER ANOTHER SPACE?
- JNZ GO_ON
- ADD BX,2 ;YES -- KEEP LOOKING AHEAD
- CMP BX,CS:FEED_END ;IS THAT IT?
- JNZ LOOK_AHEAD
- ;YES--
- SUB BX,2 ;RAN OFF THE END -- BACK UP ONE CHAR AT LEAST!
- STRIP_SPACES:
- MOV CS:FEED_START,BX ;HERE WE FOUND NOTHING BUT SPACES BEFORE THE
- ;CARRIAGE RETURN -- SKIP THAT!
-
- GO_ON:
- RET
- PAGE
- CALC_WINDOW:
- MOV AH,0FH ;FIND OUT VIDEO MODE FOR CALCULATING WINDOW SIZE
- INT VIDEO ;GO AHEAD AND GET THE CHARACTER
-
- 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
- INSERT_CR: ;INSERT CARRIAGE RETURNS 1 PAST RIGHT MARGIN
- MOV CX,WNDW_HT
- MOV SI,OFFSET SCREENSAVE
- MOV BX,WNDW_WD
- ADD BX,BX ;EVERY LOCATION TAKES A WORD, NOT A BYTE
- ICR_LOOP:
- ADD SI,BX ;GO 1 BEYOND RIGHT MARGIN
- MOV [SI],CR
- ADD SI,2 ;THAT CR TAKES A SPACE
- LOOP ICR_LOOP
- RET
-
- WRITE_POS DW 0
-
- WINDOW_SWAP:
- 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
- MOV ES:[BX][DI],AX ;NOW RESTORE THAT CHARACTER TO THE SCREEN
- 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
- ADD SI,2 ;SKIP BEYOND CARRIAGE RETURN
- SHL BX,1
- ADD DI,BX
- LOOP WS050
- RET
- PAGE
- EDITOR:
-
- ;first check for "special" keys -- print screen and close file
- ;if not one of these, check for edit keys (such as insert, delete, etc.)
- ;if not one of those, assume its ascii and just insert it in the notepad
- ;return when AltF10 detected.
-
- ED100:
- CALL GET_CHAR ;read a character from the keyboard
- CMP AX,PRINT_CHAR ;check for print note first
- JNZ ED102
-
- CALL PRINTNOTE ;we need to print the note -- not change it
- MOV BX,CURSOR_POS ;in many cases we need the cursor position
- JMP ED500
-
- ED102:
- CMP AX,FILE_CHANGE ;is he wanting to close and open a new file
- JNZ ED103
- CALL CHANGE_FILE
- MOV BX,CURSOR_POS
- JMP ED500
-
- ED103:
- OR AL,AL ;if this is ascii then dont retain scan code
- JZ ED105
- XOR AH,AH
-
- ED105:
- MOV BX,CURSOR_POS ;in many cases we need the cursor position
- CMP AX,OUR_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,00H ;if mark isnt set...
- JNZ ED350
- MOV MARK,BX ;...just set it and switch its attrib
- CALL READ_CHAR
- MOV AH,INV_ATTRIB
- CALL WRITE_CHAR
- JMP ED500
-
- ED350: ;else, store off feed start and end addresses
- CALL CONVERT_LOC
- MOV FEED_START,AX
-
- MOV DX,MARK
- CALL CONVERT_LOC
- MOV FEED_END,AX
-
- MOV CX,FEED_START
- CMP CX,AX
- JNA ED355
- MOV FEED_START,AX
- MOV FEED_END,CX
- ED355:
- 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
- JNA ED550
- MOV BL,RIGHT_MARG
- ED550:
- CMP BH,BOT_MARG
- JNA ED600
- MOV BH,BOT_MARG
- ED600:
- CMP BL,LEFT_MARG
- JNB ED650
- MOV BL,LEFT_MARG
- ED650:
- CMP BH,0FFH ;special case for a top margin of 0
- JNZ ED700
- MOV BH,BOT_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
- PRINTNOTE:
- CALL P_SPLAT_ROW ;put a row of splats across the top
- ;to delineate the note on the printer page
-
- MOV DX,UPPER_LEFT
- PN100:
- CMP DL,LEFT_MARG ;put a splat on left hand side also
- JNZ PN150
- MOV AL,2AH
- CALL PRINT_C
- JNZ PN400 ;don't proceede on timeout of printer
-
- PN150:
- CALL READ_CHAR ;get the character @ DX
- CALL PRINT_C ;and print it
- JNZ PN400 ;quit immediatly on i/o timeout
-
- CMP DL,RIGHT_MARG
- JNZ PN200
-
- MOV AL,2AH ;print a right margin delineator
- CALL PRINT_C
- MOV AL,0AH ;print carriage return-line feed after every line
- CALL PRINT_C
- MOV AL,0DH
- CALL PRINT_C
-
- CMP DH,BOT_MARG ;are we finished?
- JZ PN300
- ;no -- drop down a line
- INC DH
- MOV DL,LEFT_MARG
- DEC DL
- PN200:
- INC DL ;skip over to next character in note
- JMP PN100
-
- PN300:
- CALL P_SPLAT_ROW
-
- PN400:
- RET
-
-
- P_SPLAT_ROW:
- MOV CX,WNDW_WD+2 ;put a row of splats across the page
- PS100:
- MOV AL,2AH
- CALL PRINT_C
- JNZ PS200 ;return immediately on time out
- LOOP PS100
-
- MOV AL,0AH
- CALL PRINT_C
- MOV AL,0DH
- CALL PRINT_C
- PS200:
- RET
- PAGE
- ;
- ; THE FOLLOWING ROUTINE CLOSES THE CURRENT FILE AND ASKS FOR A NEW
- ; FILE; IT ATTEMPTS TO OPEN THIS FILE UP AND READ IT AS A NOTE PAD
- ;
- CHANGE_FILE:
- CALL WINDOW_SWAP ;PUT THE NOTE PAD INTO THE SAVE BUFFER FOR WRITING
-
- CALL UPDATE_FILE ;IF CURSOR HOMED, WRITE THE NOTEPAD OUT TO THE CURRENT FILE
-
- MOV FILE_NM_LOC,0 ;THAT FILE IS NOW CLOSED PERMANENTLY
-
- MOV DX,UPPER_LEFT ;ERASE THE TOP LINE AND POSE FILE NAME QUESTION
- MOV BX,DX
- CALL ERASE_LINE
-
- MOV DX,BX
- CALL PLACE_CURSOR ;PUT CURSOR ON LEFT AND ASK FOR FILE NAME
- MOV BX,OFFSET CF500
- CF100:
- MOV AL,BYTE PTR [BX]
- INC BX
- CMP AL,0 ;0 TERMINATES AN ASCIIZ STRING
- JZ CF200
- MOV AH,ATTRIB
- CALL W_CHAR
- INC DL
- CALL PLACE_CURSOR
- JMP CF100
-
- CF200:
- MOV BX,80H ;STORE NAME IN PSP
-
- CF300:
- CALL GET_CHAR ;GET FILE NAME UNTIL RETURN
- CMP AL,0DH ;CHECK FOR RETURN
- JZ CF400
- CMP AL,08H ;WE DO NEED TO HANDLE DEL CHAR SEPERATLY
- JNZ CF350
-
- DEC BX ;HE'S TRYING TO DELETE THE LAST CHAR
- DEC DL ;MOVE THE POINTER BACK IN THE FILE AND DEL CHAR
- MOV AL,20H ;ON SCREEN W/ A SPACE
- MOV AH,ATTRIB
- CALL WRITE_CHAR
- JMP CF300
-
- CF350:
- INC BX ;SAVE OFF NEXT CHARACTER OF NAME FIELD
- MOV BYTE PTR [BX],AL
-
- MOV AH,ATTRIB
- CALL W_CHAR ;ECHO CHAR SO HE CAN SEE WHAT HE IS TYPING
- INC DL
- CALL PLACE_CURSOR
- JMP CF300
-
- CF400:
- SUB BX,80H ;CALCULATE CHARACTER COUNT
- MOV BYTE PTR [80H],BL
-
- MOV DL,LEFT_MARG ;NOW ERASE NAME OF FILE AND RESTORE WHAT WAS THERE
- MOV BX,DX
- CALL RESTORE_LINE
-
- CALL READ_FILE ;READ UP THE INDICATED FILE INTO SAVE BUFFER
- CALL WINDOW_SWAP ;NOW PUT NOTE PAD DISPLAY BACK UP
- RET
-
- CF500: DB 'ENTER FILE NAME:',0
-
- READ_FILE: ;READS FILE NAME IN 81 WITH LENGTH COUNT IN 80
- ;ON SUCCESSFUL READS, RETURNS CARRY CLEARED
-
- MOV BX,80H ;FIND BEGINNING OF NAME FIELD
- XOR CH,CH
- MOV CL,BYTE PTR [BX] ;GO GET THE ARGUMENT COUNT FROM THE PSP
- JCXZ RF300
- RF100: ;FIND THE BEGINNING OF THE FILE NAME
- INC BX
- CMP BYTE PTR [BX],20H
- JNZ RF150
- LOOP RF100
-
- RF150:
- MOV DI,BX ;NOW TERMINATE IT WITH A 0
- JCXZ RF300 ;A 0 LENGTH FILE NAME INDICATES NO FILE TO READ
- MOV FILE_NM_LOC,BX ;SAVE THE LOCATION OF THE NAME
- RF200:
- INC DI
- LOOP RF200
- MOV BYTE PTR [DI],0
-
- MOV AH,3DH ;OPEN FILE
- MOV AL,0 ;FILE FOR READ ONLY
- MOV DX,BX ;PUT FILE NAME IN GOOD REGISTER
- INT 21H
- JC RF400 ;CARRY SET INDICATES OPEN ERROR
-
- MOV BX,AX ;READ THE FILE INTO THE NOTE PAD AREA
- MOV CX,(WNDW_HT*(WNDW_WD+1)*2)
- MOV DX,OFFSET SCREENSAVE
- MOV AH,3FH
- INT 21H
-
- MOV AH,3EH ;CLOSE THE FILE
- INT 21H
-
- RF300:
- CLC ;MAKE SURE CARRY CLEAR FOR NO ERROR RETURN
- RET
-
- RF400:
- RET ;LEAVE CARRY SET ON ERROR RETURN
-
-
- UPDATE_FILE:
- CMP FILE_NM_LOC,0 ;IF THERE IS NOT FILE...
- JZ UP100 ;...THEN JUST SKIP THIS WHOLE THING
-
- MOV AX,CURSOR_POS ;UPDATE IF CURSOR HOMED
- CMP AX,UPPER_LEFT
- JNZ UP100
-
- MOV AL,1H ;OPEN THE FILE FOR WRITING
- MOV AH,3DH
- MOV DX,FILE_NM_LOC ;GET THE FILENAME IN DX
- INT 21H
- JC UP100 ;IF ERROR ON OPEN, JUST GIVE IT UP
-
- MOV BX,AX
- MOV AH,40H ;WRITE THE FILE
- MOV CX,(WNDW_HT*(WNDW_WD+1)*2)
- MOV DX,OFFSET SCREENSAVE
- INT 21H
-
- MOV AH,3EH
- INT 21H ;NOW CLOSE THE FILE
- UP100:
- RET
-
- PAGE
- ;
- ; HERE WE PLACE SOME SMALL GENERAL PURPOSE ROUTINES
- ;
-
- PRINT_C: ;print the char in AL on LPT1 (parrallel)
- ;returns printer status in AH
- PUSH DX
- XOR DX,DX ;select LPT1
- XOR AH,AH ;select "print"
- INT 17H
- POP DX
- TEST AH,1 ;set the zero flag if not error,
- ;clear zero flag if char not printed
- RET
-
- PLACE_CURSOR: ;place cursor at location in dx
- MOV AH,2H
- PUSH BX
- XOR BX,BX
- INT VIDEO
- POP BX
- RET
-
- READ_CURSOR: ;read cursor location into dx
- MOV AH,3H
- PUSH BX
- XOR BX,BX
- INT VIDEO
- POP BX
- RET
-
- 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
-
- 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
-
- 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
-
- 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
-
-
- 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
- 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 SI,OFFSET LINESAVE
-
- RL100:
- MOV AX,[SI] ;get the saved char
- CALL WRITE_CHAR ;put the saved char where indicated
- ADD SI,2
- INC DL
- LOOP RL100
- RET
-
- CONVERT_LOC: ;convert a location on the screen (in dx) into location
- ;in the screen save buffer
- 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
- 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]
- RET
- BODY ENDP
- PAGE
- INSTALL:
- ;THIS PROGRAM INSTALLS THE REST OF THE CODE FOR NOTE PAD
-
- ;TRY TO READ THE INITIAL FILE UP INTO THE NOTE PAD AREA
-
- CALL READ_FILE
- JNC GO_AHEAD ;ON ERROR READING FILE...
- ;...OUTPUT ERROR MESSAGE AND QUIT
- MOV DX,OFFSET ERRMSG
- MOV AH,9H
- INT 21H
- MOV AH,4CH
- MOV AL,1 ;SET THE ERROR LEVEL
- INT 21H
-
- GO_AHEAD:
- 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,'NotePad4 installed',10,13,'Alt-F10 to enter and exit',10,13,'$'
-
- ERRMSG DB 10,13,'NotePad4 not installed',10,13,'Error on file read',10,13,'$'
-
- CSEG ENDS
- END START