home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS 1992 December / simtel1292_SIMTEL_1292_Walnut_Creek.iso / msdos / deskaces / notepad4.arc / NOTEPAD4.ASM next >
Assembly Source File  |  1986-02-12  |  30KB  |  1,007 lines

  1.       PAGE 55,132
  2.       TITLE NOTEPAD4
  3. ;
  4. ;NotePad IV -  NON BIOS VERSION
  5. ;      Permission is granted to copy and distribute freely copies of this
  6. ;      program with the following restrictions:
  7. ;
  8. ;      1) this program be passed in the public domain
  9. ;      2) a fee, beyond the cost of the disk, not be charged
  10. ;      3) improvements not be passed on but rather sent to me
  11. ;       to check for possible incompatibilities with other programs
  12. ;
  13. ;   (Stephen) Randy Davis and Larry Weiss
  14. ;   (214)454-2426
  15. ;
  16. ;       feel free to call with bugs or questions
  17. ;
  18.  
  19. ;PARAMETERS -- MOST OF THESE MAY BE CHANGED TO ANY DESIRED VALUE
  20.  
  21. wndw_ht    equ 24             ;mark the size of the window to open
  22. wndw_wd    equ 40
  23. our_key    equ  07100H        ;scan code - ascii of key to open window
  24.                               ;now scan codes of edit keys  (AltF10)
  25. up_arrow   equ  4800H
  26. down_arrow equ  5000H
  27. left_arrow equ  4B00H
  28. right_arrow equ 4D00H
  29. del_left   equ  0008H         ;user rubout (cntrl H) key
  30. delete     equ  5300H         ;use del (lower right)
  31. insert     equ  5200H
  32. cr         equ  000DH
  33. home       equ  4700H
  34. escape     equ  001BH
  35. tab        equ  7400H         ; ^right arrow
  36. rev_tab    equ  7300H         ; ^left arrow
  37. line_ins   equ  5100H         ;pg down
  38. line_del   equ  4900H         ;pg up
  39. mark_char  equ  4F00H         ;end key
  40. print_char equ  372AH         ;PrtSc* = print note on printer
  41. file_change equ 4A2DH         ;key to update file and get a new one
  42.  
  43. blank      equ  07020H       ;define the character which is a blank
  44. attrib     equ  070H         ;and our default attribute (should agree with blank)
  45. video      equ  10H          ;video BIOS call
  46. inv_attrib equ  007H         ;inverse of 'attrib'
  47.     PAGE
  48. CSEG  SEGMENT PARA PUBLIC 'CODE'
  49.       ASSUME CS:CSEG,DS:CSEG,SS:CSEG,ES:NOTHING   ;STANDARD DECL FOR .COM FILE
  50.  
  51.       ORG  100H
  52.  
  53. Start:
  54.       JMP INSTALL
  55.  
  56.     DB (100H) DUP(0)    ;ALLOCATE SOME EXTRA DISK SPACE
  57. STACK:
  58.  
  59. ;PLACE DATA AREA HERE FOR READIBILITY
  60.  
  61. COPYRITE    DB 'Copyright Stephen R. Davis, Larry Weiss 1985  All Rights Reserved'
  62.             DB '(214)454-2426'
  63. SCREENSAVE: DW (WNDW_HT * (WNDW_WD+1)) DUP (BLANK);RESERVE SPACE TO SAVE OPENED WINDOW
  64. LINESAVE:    DW WNDW_WD DUP (BLANK) ;BUFFER FOR LINE DELETE
  65.  
  66. CURSOR_POS  DW 0
  67. OLD_CUR_POS DW 0
  68. SAVESTACK   DW 0,0
  69.  
  70. REQUEST     DB 0              ;REQUEST TYPE
  71. KEY_RQST_HANDLER DD 0         ;ADDRESS OF THE ORIGINAL KEYBOARD REQUEST HANDLER
  72.  
  73. LEFT_MARG  DB   00            ;define the confines of the window
  74. RIGHT_MARG DB   00
  75. TOP_MARG   DB   00
  76. BOT_MARG   DB   00
  77. UPPER_LEFT DW   00
  78.  
  79. MARK       DW   00            ;FLAGS USED IN CHARACTER FEED
  80. FEED_START DW   00            ;ADDRESS IN BUFFER OF BEGIN...
  81. FEED_END   DW   00            ;...AND END OF FEED
  82.  
  83. DISPLAY_SEG DW    00        ;DISPLAY SEGMENT (B000 -> MONOCHROME,
  84.                 ;                 B800 -> GRAPHIX)
  85.  
  86. FILE_NM_LOC DW  00            ;ADDRESS OF FILE NAME (0 -> NO FILE)
  87. PAGE
  88. BEGIN PROC FAR                ;FAR LABEL SINCE ITS ENTERED BY INTERRUPT
  89. MAINLOOP:
  90.       MOV  CS:REQUEST,AH      ;SAVE HIS AX REGISTER
  91.  
  92.       MOV  AX,CS:FEED_START   ;ARE WE IN THE MIDDLE OF FEEDING CHARS...
  93.       CMP  AX,CS:FEED_END     ;...TO THE APPLICATION?
  94.       JZ   NOFEED             ;NO
  95.       JMP  FEED               ;YES
  96. NOFEED:
  97.       MOV  AH,CS:REQUEST      ;RESTORE USERS AX
  98.       PUSHF                   ;CALL OLD INTERRUPT HANDLER (EMULATE INT INSTRUCTION)
  99.       CALL DWORD PTR [CS:KEY_RQST_HANDLER] ;GO AHEAD AND GET THE CHARACTER
  100.       PUSHF                   ;SAVE THE FLAG RETURNED (FOR AH = 1 REQUESTS)
  101.  
  102.       CMP CS:REQUEST,00H      ;WE ARE ONLY INTERESTED IN CHAR. REQUESTS
  103.       JZ  CNTINUE
  104.       JMP FORGET_IT
  105.  
  106. CNTINUE:                      ;YES -- CHECK CHARACTER FOR 'OURS'
  107.       POPF                    ;FOR NON-TYPE 1 REQUESTS DONT NEED TO SAVE FLAGS
  108.       CMP AX,OUR_KEY
  109.       JZ  CNT_AGIN
  110.       JMP RETURN_CHAR
  111.  
  112. CNT_AGIN:                     ;WE GOT IT! GO INTO EDITOR MODE
  113.       MOV CS:SAVESTACK,SP
  114.       MOV CS:SAVESTACK+2,SS
  115.       MOV  AX,CS
  116.       MOV  SS,AX
  117.       MOV  SP,OFFSET STACK
  118.  
  119.       STI                     ;ENABLE INTERRUPTS WHILE PROCESSING CHARACTERS
  120.  
  121.       PUSH BP                 ;SET UP A STACK FRAME
  122.       MOV  BP,SP
  123.       SUB  SP,0EH
  124.       CALL SAVEREG
  125.       MOV  DS,AX
  126.  
  127.       CALL CALC_WINDOW        ;CALCULATE WINDOW EXTREMETIES
  128.  
  129.       CALL READ_CURSOR
  130.       MOV OLD_CUR_POS,DX      ;SAVE THE CURSOR FOR LATER RESTORING
  131.  
  132.       CALL WINDOW_SWAP        ;SWING IN THE EDIT WINDOW (WITH NOTES?)
  133.  
  134.       CALL INSERT_CR          ;PUT THE CARRIAGE RETURNS ON UNPRINTABLE COL.S
  135.  
  136.       MOV DX,CURSOR_POS       ;RESTORE CURSOR IN EDIT WINDOW
  137.       CALL PLACE_CURSOR
  138.  
  139.       CALL EDITOR             ;LET HIM EDIT IN THE WINDOW
  140.  
  141.       CALL READ_CURSOR
  142.       MOV CURSOR_POS,DX       ;SAVE CURSOR IN EDIT WINDOW FOR NEXT EDIT
  143.  
  144.       CMP  MARK,00H          ;CLEAR THE MARK POSITION (IF IT'S SET)
  145.       JZ   NOT_SET
  146.       MOV  DX,MARK
  147.       CALL READ_CHAR          ;GET THE CHARACTER...
  148.       MOV  AH,ATTRIB          ;...PUT ITS ATTRIBUTE BACK TO EVERYONE ELSE'S...
  149.       CALL WRITE_CHAR         ;...AND PUT IT BACK
  150.       MOV  MARK,00H
  151. NOT_SET:
  152.  
  153.       CALL WINDOW_SWAP        ;PUT BACK WHATEVER WAS ORIGINALLY THERE
  154.  
  155.       CALL UPDATE_FILE        ;NOW ATTEMPT TO UPDATE THE DISK FILE
  156.  
  157.       MOV DX,OLD_CUR_POS      ;RESTORE THE CURSOR POSITION
  158.       CALL PLACE_CURSOR
  159.  
  160.       CALL RESTREG
  161.       ADD  SP,0EH
  162.       POP  BP
  163.  
  164.       MOV SS,CS:SAVESTACK+2
  165.       MOV SP,CS:SAVESTACK
  166.  
  167.       MOV AH,00              ;RESTORE REQUEST TO SOMETHING DECENT
  168.       JMP MAINLOOP           ;GO GET ANOTHER CHARACTER TO RETURN HIM
  169.  
  170. RETURN_CHAR:
  171.       IRET                   ;RETURN WITH CHARACTER
  172.  
  173. ;HANDLE REQUEST TYPE 1'S BY FAR RETURNING 2 AND TYPE 2'S BY JUST RETURNING
  174.  
  175. FORGET_IT:
  176.       CMP  CS:REQUEST,1      ;was it a "is char present" request?
  177.       JZ   FI100
  178.  
  179.       POPF                   ;no -- just return whatever BIOS returned
  180.       IRET
  181.  
  182. FI100:
  183.       POPF                   ;yes -- make funny return
  184.       RET 02
  185.       PAGE
  186. ;HERE WE ARE IN THE PROCESS OF FEEDING CHARACTERS TO THE APPLICATION
  187. ;FROM THE WINDOW BUFFER (SCREENSAVE)
  188.  
  189. FEED:
  190.       CMP  CS:REQUEST,1       ;WAS THIS A CHAR TYPE REQUEST?
  191.       JA   KSTAT
  192.                               ;YES -- RETURN HIM CHAR
  193.       PUSH BX                 ;GET THE NEXT CHARACTER FROM THE BUFFER
  194.       CALL SKIP_SPACES        ;STRIP LEADING SPACES
  195.  
  196.       MOV  BX,CS:FEED_START   ;OK - GET THE NEXT CHARACTER WE NEED
  197.       MOV  AX,CS:[BX]
  198.       POP  BX
  199.       XOR  AH,AH              ;WE NO LONGER HAVE THE SCAN CODE, BUT ALL
  200.                               ;ARE ASCII ANYWAY
  201.  
  202.       CMP  CS:REQUEST,0       ;IS THIS A 'GET KEYBOARD CHAR' RQST?
  203.       JNZ  FEED_KEY_STAT
  204.  
  205.       ADD  CS:FEED_START,2    ;YES -- MOVE UP THE POINTER BY 1
  206.       IRET
  207.  
  208. FEED_KEY_STAT:
  209.       STI                     ;NO -- ENABLE INTERRUPTS AND FEED HIM THE
  210.       RET  02                 ;THE Z FLAG CLEAR WITH HIS CHAR
  211.  
  212. KSTAT:
  213.       MOV  AH,CS:REQUEST      ;RESTORE REQUEST TO AH
  214.       CALL DWORD PTR [CS:KEY_RQST_HANDLER] ;PERFORM BIOS CALL -- WE DON'T KNOW
  215.                               ;WHAT HE'S DOING AND WE SHOULDN'T GET IN THE WAY
  216.       IRET                    ;RETURN THE RESULTS TO HIM (WHATEVER THEY ARE)
  217. BEGIN ENDP
  218.       PAGE
  219. BODY  PROC NEAR               ;MAKE SHORT CALLS ONLY TO THE MAIN ROUTINES
  220.  
  221. SKIP_SPACES:
  222. ;TRY TO AVOID FEEDING SPACES WITH NOTHING AFTER THEM ON A LINE --
  223. ;JUST SKIP OVER TO THE RETURN AND FEED THAT ALONE
  224.  
  225.       MOV  BX,CS:FEED_START   ;START WITH THE NEXT FEED CHARACTER
  226. LOOK_AHEAD:
  227.       MOV  AX,CS:[BX]
  228.       CMP  AL,CR              ;IS THIS CHAR A RETURN
  229.       JZ   STRIP_SPACES
  230.       CMP  AL,' '             ;IS THIS CHARACTER ANOTHER SPACE?
  231.       JNZ  GO_ON
  232.       ADD  BX,2               ;YES -- KEEP LOOKING AHEAD
  233.       CMP  BX,CS:FEED_END     ;IS THAT IT?
  234.       JNZ  LOOK_AHEAD
  235.                               ;YES--
  236.       SUB  BX,2               ;RAN OFF THE END -- BACK UP ONE CHAR AT LEAST!
  237. STRIP_SPACES:
  238.       MOV  CS:FEED_START,BX   ;HERE WE FOUND NOTHING BUT SPACES BEFORE THE
  239.                               ;CARRIAGE RETURN -- SKIP THAT!
  240.  
  241. GO_ON:
  242.       RET
  243.       PAGE
  244. CALC_WINDOW:
  245.       MOV AH,0FH              ;FIND OUT VIDEO MODE FOR CALCULATING WINDOW SIZE
  246.       INT VIDEO               ;GO AHEAD AND GET THE CHARACTER
  247.  
  248.       MOV CX,0B000H           ;IS IT MONOCHROME?
  249.       CMP AL,7                ;WELL LOOK FOR MODE 7
  250.       JZ  CW100
  251.       MOV CX,0B800H           ;NO -- ITS GRAPHIX
  252. CW100:
  253.       MOV DISPLAY_SEG,CX      ;SAVE THIS OFF
  254.  
  255.       DEC AH                  ;THIS IS THE NUMBER OF COLS ON SCREEN
  256.       MOV RIGHT_MARG,AH       ;SET UP RIGHT AND LEFT MARGINS
  257.       SUB AH,(WNDW_WD - 1)
  258.       MOV LEFT_MARG,AH
  259.  
  260.       MOV TOP_MARG,0          ;WE HAVE NO INFORMATION ON NUMBER OF ROWS
  261.       MOV BOT_MARG,WNDW_HT-1  ;SO WE MUST ASSUME SOMETHING NORMAL (IT ISNT
  262.                               ;AS CRITICAL ANYWAY)
  263.  
  264.       MOV AL,AH               ;NOW ADD UPPER_LEFT HAND CORNER VALUE
  265.       XOR AH,AH
  266.       MOV UPPER_LEFT,AX
  267.  
  268.  
  269.       CMP CURSOR_POS,0        ;IF THIS IS THE FIRST TIME WEVE DONE THIS...
  270.       JNZ CW200
  271.       MOV CURSOR_POS,AX       ;...PLACE THE CURSOR IN THE UPPER LEFT HAND CORNER
  272.  
  273. CW200:
  274.       RET
  275.       PAGE
  276. INSERT_CR:                      ;INSERT CARRIAGE RETURNS 1 PAST RIGHT MARGIN
  277.       MOV CX,WNDW_HT
  278.       MOV SI,OFFSET SCREENSAVE
  279.       MOV BX,WNDW_WD
  280.       ADD BX,BX                 ;EVERY LOCATION TAKES A WORD, NOT A BYTE
  281. ICR_LOOP:
  282.       ADD SI,BX                 ;GO 1 BEYOND RIGHT MARGIN
  283.       MOV [SI],CR
  284.       ADD SI,2                  ;THAT CR TAKES A SPACE
  285.       LOOP ICR_LOOP
  286.       RET
  287.  
  288. WRITE_POS DW 0
  289.  
  290. WINDOW_SWAP:
  291.     MOV CX,WNDW_HT        ;GET THE NUMBER OF ROWS IN WINDOW AREA
  292.       MOV SI,OFFSET SCREENSAVE;START AT BEGINNING OF BUFFER
  293.       MOV ES,DISPLAY_SEG      ;LOAD UP THE VIDEO SEGMENT
  294.       MOV DI,00
  295.       XOR BX,BX
  296. WS050:
  297.       MOV BL,LEFT_MARG        ;START ON THIS LINE AT THE LEFT MARGIN
  298. WS100:
  299.       SHL  BX,1               ;CHANGE THE COLUMN NUMBER TO BYTE POINTER
  300.       MOV  AX,ES:[BX][DI]     ;GET THE NEXT CHARACTER FROM SCREEN
  301.       XCHG AX,[SI]            ;STORE IT AWAY AND WRITE THE SAVED CHARACTER
  302.       ADD  SI,2               ;AND MOVE SAVE POINTER OVER A WORD
  303.       MOV  ES:[BX][DI],AX     ;NOW RESTORE THAT CHARACTER TO THE SCREEN
  304.       SHR  BX,1               ;PUT THE BYTE OFFSET BACK TO COLUMN NUMBER
  305.       INC  BX
  306.       CMP  BL,RIGHT_MARG      ;ARE WE BEYOND THE END OF THE LINE?
  307.       JNA  WS100
  308.                               ;YES -- SKIP DOWN TO NEXT LINE
  309.       ADD  SI,2               ;SKIP BEYOND CARRIAGE RETURN
  310.       SHL  BX,1
  311.       ADD  DI,BX
  312.       LOOP WS050
  313.       RET
  314.       PAGE
  315. EDITOR:
  316.  
  317. ;first check for "special" keys -- print screen and close file
  318. ;if not one of these, check for edit keys (such as insert, delete, etc.)
  319. ;if not one of those, assume its ascii and just insert it in the notepad
  320. ;return when AltF10 detected.
  321.  
  322. ED100:
  323.       CALL GET_CHAR         ;read a character from the keyboard
  324.       CMP  AX,PRINT_CHAR    ;check for print note first
  325.       JNZ  ED102
  326.  
  327.       CALL PRINTNOTE        ;we need to print the note -- not change it
  328.       MOV  BX,CURSOR_POS     ;in many cases we need the cursor position
  329.       JMP  ED500
  330.  
  331. ED102:
  332.       CMP  AX,FILE_CHANGE   ;is he wanting to close and open a new file
  333.       JNZ  ED103
  334.       CALL CHANGE_FILE
  335.       MOV  BX,CURSOR_POS
  336.       JMP  ED500
  337.  
  338. ED103:
  339.       OR   AL,AL            ;if this is ascii then dont retain scan code
  340.       JZ   ED105
  341.       XOR  AH,AH
  342.  
  343. ED105:
  344.       MOV  BX,CURSOR_POS     ;in many cases we need the cursor position
  345.       CMP  AX,OUR_KEY        ;check for exit
  346.       JNZ  ED110
  347.       JMP  ED800
  348.  
  349. ED110:
  350.       CMP  AX,CR             ;check for each special character individually
  351.       JNZ  ED120
  352.       MOV  BL,LEFT_MARG
  353.       INC  BH
  354.       JMP  ED500
  355. ED120:
  356.       CMP  AX,LEFT_ARROW
  357.       JNZ  ED140
  358.       DEC  BL
  359.       JMP  ED500
  360.  
  361. ED140:
  362.       CMP  AX,RIGHT_ARROW
  363.       JNZ  ED160
  364.       INC  BL
  365.       JMP  ED500
  366.  
  367. ED160:
  368.       CMP   AX,UP_ARROW
  369.       JNZ   ED180
  370.       DEC   BH
  371.       JMP   ED500
  372.  
  373. ED180:
  374.       CMP  AX,DOWN_ARROW
  375.       JNZ  ED200
  376.       INC  BH
  377.       JMP  ED500
  378.  
  379. ED200:
  380.       CMP  AX,HOME
  381.       JNZ  ED205
  382.       MOV  BX,UPPER_LEFT
  383.       JMP  ED500
  384.  
  385. ED205:                       ;tab and back tab functions
  386.       CMP  AX,TAB
  387.       JNZ  ED210
  388.       MOV  CL,1              ;go forward
  389.       JMP  ED213
  390.  
  391. ED210:
  392.       CMP  AX,REV_TAB
  393.       JNZ  ED220
  394.  
  395.       MOV  CL,0FFH           ;go backwards one tab slot
  396.       ADD  DL,CL             ;start one char to left initially
  397.  
  398. ED213:
  399.       CALL READ_CHAR         ;get char at current position
  400.       MOV  CH,AL             ;save it for comparison
  401. ED215:
  402.       ADD  DL,CL             ;move over one character
  403.       CMP  DL,RIGHT_MARG     ;stop at left and right margins (or beyond)
  404.       JGE  ED218
  405.       CMP  DL,LEFT_MARG
  406.       JLE  ED218
  407.  
  408.       CALL READ_CHAR         ;read current character
  409.       CMP  CH,' '            ;if original was a space...
  410.       JNZ  ED216
  411.       CMP  AL,' '            ;...then go until not space
  412.       JZ  ED215
  413.       JMP ED217
  414. ED216:
  415.       CMP AL,' '             ;...else, go until space
  416.       JNZ ED215
  417. ED217:
  418.       CMP  CL,0FFH           ;if we were going backwards (towards left)...
  419.       JNZ  ED218
  420.       ADD  DL,1              ;...then scoot back to the right by 1
  421. ED218:
  422.       MOV  BX,DX
  423.       JMP  ED500
  424.  
  425. ED220:
  426.       CMP  AX,ESCAPE         ;wipe out remainder of line
  427.       JNZ  ED240
  428.       MOV  DX,BX
  429.       CALL ERASE_LINE
  430.       JMP  ED500
  431.  
  432. ED240:
  433.       CMP  AX,DEL_LEFT       ;move cursor left one char and then do normal del
  434.       JNZ  ED260
  435.       DEC  BL
  436.       CMP  BL,LEFT_MARG
  437.       JNB  ED250
  438.       MOV  BL,RIGHT_MARG
  439.       CMP  BH,00
  440.       JZ   ED250
  441.       DEC  BH
  442. ED250:
  443.       JMP  ED270
  444.  
  445. ED260:
  446.       CMP  AX,DELETE         ;in delete char we...
  447.       JNZ  ED280
  448. ED270:
  449.       MOV  CL,RIGHT_MARG
  450.       SUB  CL,BL             ;calculate how many chars to right margin
  451.       XOR  CH,CH
  452.       MOV  DX,BX             ;...start at current cursor position...
  453.       JCXZ ED275
  454. ED272:
  455.       INC  DL                ;...get character just to the right...
  456.       CALL READ_CHAR
  457.       DEC  DL                ;...move left one position...
  458.       CALL WRITE_CHAR        ;...and write it there...
  459.       INC  DL                ;...now do it again for the char to the right...
  460.       LOOP ED272             ;...for the distance from cursor to right margin;...
  461. ED275:
  462.       MOV  AX,BLANK
  463.       CALL WRITE_CHAR
  464.       JMP  ED500
  465.  
  466. ED280:
  467.       CMP  AX,INSERT         ;in the case of insert we do reverse of delete
  468.       JNZ  ED300
  469.       MOV  DH,BH             ;start at the right margin
  470.       MOV  DL,RIGHT_MARG
  471.       MOV  CL,DL             ;caculate number of spaces to right
  472.       SUB  CL,BL
  473.       XOR  CH,CH
  474.       JCXZ ED290
  475. ED285:
  476.       DEC  DL
  477.       CALL READ_CHAR
  478.       INC  DL
  479.       CALL WRITE_CHAR
  480.       DEC  DL
  481.       LOOP ED285
  482. ED290:
  483.       MOV  AX,BLANK
  484.       CALL WRITE_CHAR
  485.       JMP  ED500
  486.  
  487. ED300:
  488.       CMP  AX,LINE_INS       ;check for insert line
  489.       JNZ  ED320
  490.       MOV  DH,BOT_MARG       ;we're going to need that
  491. ED305:
  492.       MOV  DL,LEFT_MARG      ;always start at the far left
  493.       CMP  DH,BH             ;are we on our current line?
  494.       JZ   ED315
  495.                              ;no -- then move it down
  496.       MOV  CX,WNDW_WD
  497. ED310:
  498.       DEC  DH
  499.       CALL READ_CHAR         ;get the character
  500.       INC  DH
  501.       CALL WRITE_CHAR        ;and put it back one line higher
  502.       INC  DL                ;move right one character
  503.       LOOP ED310
  504.  
  505.       DEC  DH                ;now move up a line and do it again
  506.       JMP  ED305
  507. ED315:
  508.       MOV  BL,LEFT_MARG      ;move us over the far left marg
  509.       CALL ERASE_LINE        ;and wipe out the line we are on
  510.       JMP  ED500
  511.  
  512. ED320:
  513.       CMP  AX,LINE_DEL       ;and check for line delete
  514.       JNZ  ED340
  515.  
  516. ED325:
  517.       MOV  DL,LEFT_MARG      ;always start at the far left
  518.       CMP  DH,BOT_MARG       ;are we on the last line?
  519.       JZ   ED335
  520.                              ;no -- then move it up
  521.       MOV  CX,WNDW_WD
  522. ED330:
  523.       INC  DH
  524.       CALL READ_CHAR         ;get the character
  525.       DEC  DH
  526.       CALL WRITE_CHAR        ;and put it back one line lower
  527.       INC  DL                ;move right one character
  528.       LOOP ED330
  529.  
  530.       INC  DH                ;now move down a line and do it again
  531.       JMP  ED325
  532. ED335:
  533.       MOV  BL,LEFT_MARG      ;move us over the far left marg of our line
  534.       CALL ERASE_LINE        ;and wipe out the bottom line
  535.       JMP  ED500
  536.  
  537. ED340:
  538.       CMP  AX,MARK_CHAR      ;check for mark
  539.       JNZ  ED400
  540.  
  541.       MOV  DX,BX
  542.       CMP  MARK,00H          ;if mark isnt set...
  543.       JNZ  ED350
  544.       MOV  MARK,BX           ;...just set it and switch its attrib
  545.       CALL READ_CHAR
  546.       MOV  AH,INV_ATTRIB
  547.       CALL WRITE_CHAR
  548.       JMP  ED500
  549.  
  550. ED350:                       ;else, store off feed start and end addresses
  551.       CALL CONVERT_LOC
  552.       MOV  FEED_START,AX
  553.  
  554.       MOV  DX,MARK
  555.       CALL CONVERT_LOC
  556.       MOV  FEED_END,AX
  557.  
  558.       MOV  CX,FEED_START
  559.       CMP  CX,AX
  560.       JNA  ED355
  561.       MOV  FEED_START,AX
  562.       MOV  FEED_END,CX
  563. ED355:
  564.       JMP  ED800             ;note that this char exits the note pad
  565.  
  566. ED400:                       ;wasnt an edit character -- must be ascii
  567.                              ;just write the character at current position
  568.       MOV  AH,ATTRIB
  569.       CALL W_CHAR
  570.       INC  BL                ;move over one position
  571.  
  572. ED500:                       ;adjust resulting cursor position
  573.       CMP  BL,RIGHT_MARG
  574.       JNA  ED550
  575.       MOV  BL,RIGHT_MARG
  576. ED550:
  577.       CMP  BH,BOT_MARG
  578.       JNA  ED600
  579.       MOV  BH,BOT_MARG
  580. ED600:
  581.       CMP  BL,LEFT_MARG
  582.       JNB  ED650
  583.       MOV  BL,LEFT_MARG
  584. ED650:
  585.       CMP  BH,0FFH           ;special case for a top margin of 0
  586.       JNZ  ED700
  587.       MOV  BH,BOT_MARG
  588. ED700:
  589.       MOV  CURSOR_POS,BX
  590.       MOV  DX,BX             ;be sure and move the cursor to the new
  591.       CALL PLACE_CURSOR      ;position
  592.       JMP  ED100
  593.  
  594. ED800:                       ;exit
  595.       RET
  596.       PAGE
  597. PRINTNOTE:
  598.       CALL P_SPLAT_ROW       ;put a row of splats across the top
  599.                              ;to delineate the note on the printer page
  600.  
  601.       MOV  DX,UPPER_LEFT
  602. PN100:
  603.       CMP   DL,LEFT_MARG     ;put a splat on left hand side also
  604.       JNZ   PN150
  605.       MOV   AL,2AH
  606.       CALL  PRINT_C
  607.       JNZ   PN400            ;don't proceede on timeout of printer
  608.  
  609. PN150:
  610.       CALL  READ_CHAR        ;get the character @ DX
  611.       CALL  PRINT_C          ;and print it
  612.       JNZ   PN400            ;quit immediatly on i/o timeout
  613.  
  614.       CMP   DL,RIGHT_MARG
  615.       JNZ   PN200
  616.  
  617.       MOV   AL,2AH           ;print a right margin delineator
  618.       CALL  PRINT_C
  619.       MOV   AL,0AH          ;print carriage return-line feed after every line
  620.       CALL  PRINT_C
  621.       MOV   AL,0DH
  622.       CALL  PRINT_C
  623.  
  624.       CMP  DH,BOT_MARG       ;are we finished?
  625.       JZ   PN300
  626.                              ;no -- drop down a line
  627.       INC  DH
  628.       MOV  DL,LEFT_MARG
  629.       DEC  DL
  630. PN200:
  631.       INC  DL                ;skip over to next character in note
  632.       JMP  PN100
  633.  
  634. PN300:
  635.       CALL P_SPLAT_ROW
  636.  
  637. PN400:
  638.       RET
  639.  
  640.  
  641. P_SPLAT_ROW:
  642.       MOV  CX,WNDW_WD+2      ;put a row of splats across the page
  643. PS100:
  644.       MOV  AL,2AH
  645.       CALL PRINT_C
  646.       JNZ  PS200             ;return immediately on time out
  647.       LOOP PS100
  648.  
  649.       MOV  AL,0AH
  650.       CALL PRINT_C
  651.       MOV  AL,0DH
  652.       CALL PRINT_C
  653. PS200:
  654.       RET
  655.       PAGE
  656. ;
  657. ; THE FOLLOWING ROUTINE CLOSES THE CURRENT FILE AND ASKS FOR A NEW
  658. ; FILE; IT ATTEMPTS TO OPEN THIS FILE UP AND READ IT AS A NOTE PAD
  659. ;
  660. CHANGE_FILE:
  661.       CALL WINDOW_SWAP       ;PUT THE NOTE PAD INTO THE SAVE BUFFER FOR WRITING
  662.  
  663.       CALL UPDATE_FILE       ;IF CURSOR HOMED, WRITE THE NOTEPAD OUT TO THE CURRENT FILE
  664.  
  665.       MOV  FILE_NM_LOC,0     ;THAT FILE IS NOW CLOSED PERMANENTLY
  666.  
  667.       MOV  DX,UPPER_LEFT     ;ERASE THE TOP LINE AND POSE FILE NAME QUESTION
  668.       MOV  BX,DX
  669.       CALL ERASE_LINE
  670.  
  671.       MOV  DX,BX
  672.       CALL PLACE_CURSOR      ;PUT CURSOR ON LEFT AND ASK FOR FILE NAME
  673.       MOV  BX,OFFSET CF500
  674. CF100:
  675.       MOV  AL,BYTE PTR [BX]
  676.       INC  BX
  677.       CMP  AL,0              ;0 TERMINATES AN ASCIIZ STRING
  678.       JZ   CF200
  679.       MOV  AH,ATTRIB
  680.       CALL W_CHAR
  681.       INC  DL
  682.       CALL PLACE_CURSOR
  683.       JMP  CF100
  684.  
  685. CF200:
  686.       MOV  BX,80H            ;STORE NAME IN PSP
  687.  
  688. CF300:
  689.       CALL GET_CHAR         ;GET FILE NAME UNTIL RETURN
  690.       CMP  AL,0DH            ;CHECK FOR RETURN
  691.       JZ   CF400
  692.       CMP  AL,08H            ;WE DO NEED TO HANDLE DEL CHAR SEPERATLY
  693.       JNZ  CF350
  694.  
  695.       DEC  BX                ;HE'S TRYING TO DELETE THE LAST CHAR
  696.       DEC  DL                ;MOVE THE POINTER BACK IN THE FILE AND DEL CHAR
  697.       MOV  AL,20H            ;ON SCREEN W/ A SPACE
  698.       MOV  AH,ATTRIB
  699.       CALL WRITE_CHAR
  700.       JMP  CF300
  701.  
  702. CF350:
  703.       INC  BX                ;SAVE OFF NEXT CHARACTER OF NAME FIELD
  704.       MOV  BYTE PTR [BX],AL
  705.  
  706.       MOV  AH,ATTRIB
  707.       CALL W_CHAR            ;ECHO CHAR SO HE CAN SEE WHAT HE IS TYPING
  708.       INC  DL
  709.       CALL PLACE_CURSOR
  710.       JMP  CF300
  711.  
  712. CF400:
  713.       SUB  BX,80H            ;CALCULATE CHARACTER COUNT
  714.       MOV  BYTE PTR [80H],BL
  715.  
  716.       MOV  DL,LEFT_MARG      ;NOW ERASE NAME OF FILE AND RESTORE WHAT WAS THERE
  717.       MOV  BX,DX
  718.       CALL RESTORE_LINE
  719.  
  720.       CALL READ_FILE         ;READ UP THE INDICATED FILE INTO SAVE BUFFER
  721.       CALL WINDOW_SWAP       ;NOW PUT NOTE PAD DISPLAY BACK UP
  722.       RET
  723.  
  724. CF500: DB 'ENTER FILE NAME:',0
  725.  
  726. READ_FILE:                   ;READS FILE NAME IN 81 WITH LENGTH COUNT IN 80
  727.                              ;ON SUCCESSFUL READS, RETURNS CARRY CLEARED
  728.  
  729.       MOV  BX,80H            ;FIND BEGINNING OF NAME FIELD
  730.       XOR  CH,CH
  731.       MOV  CL,BYTE PTR [BX]         ;GO GET THE ARGUMENT COUNT FROM THE PSP
  732.       JCXZ  RF300
  733. RF100:                       ;FIND THE BEGINNING OF THE FILE NAME
  734.       INC  BX
  735.       CMP  BYTE PTR [BX],20H
  736.       JNZ  RF150
  737.       LOOP RF100
  738.  
  739. RF150:
  740.       MOV  DI,BX             ;NOW TERMINATE IT WITH A 0
  741.     JCXZ RF300        ;A 0 LENGTH FILE NAME INDICATES NO FILE TO READ
  742.       MOV  FILE_NM_LOC,BX    ;SAVE THE LOCATION OF THE NAME
  743. RF200:
  744.       INC  DI
  745.       LOOP RF200
  746.       MOV  BYTE PTR [DI],0
  747.  
  748.       MOV  AH,3DH            ;OPEN FILE
  749.       MOV  AL,0              ;FILE FOR READ ONLY
  750.       MOV  DX,BX             ;PUT FILE NAME IN GOOD REGISTER
  751.       INT  21H
  752.       JC   RF400             ;CARRY SET INDICATES OPEN ERROR
  753.  
  754.       MOV  BX,AX             ;READ THE FILE INTO THE NOTE PAD AREA
  755.       MOV  CX,(WNDW_HT*(WNDW_WD+1)*2)
  756.       MOV  DX,OFFSET SCREENSAVE
  757.       MOV  AH,3FH
  758.       INT  21H
  759.  
  760.       MOV  AH,3EH            ;CLOSE THE FILE
  761.       INT  21H
  762.  
  763. RF300:
  764.       CLC                    ;MAKE SURE CARRY CLEAR FOR NO ERROR RETURN
  765.       RET
  766.  
  767. RF400:
  768.       RET                    ;LEAVE CARRY SET ON ERROR RETURN
  769.  
  770.  
  771. UPDATE_FILE:
  772.       CMP  FILE_NM_LOC,0     ;IF THERE IS NOT FILE...
  773.       JZ   UP100             ;...THEN JUST SKIP THIS WHOLE THING
  774.  
  775.       MOV  AX,CURSOR_POS     ;UPDATE IF CURSOR HOMED
  776.       CMP  AX,UPPER_LEFT
  777.       JNZ  UP100
  778.  
  779.       MOV  AL,1H             ;OPEN THE FILE FOR WRITING
  780.       MOV  AH,3DH
  781.       MOV  DX,FILE_NM_LOC    ;GET THE FILENAME IN DX
  782.       INT  21H
  783.       JC   UP100             ;IF ERROR ON OPEN, JUST GIVE IT UP
  784.  
  785.       MOV  BX,AX
  786.       MOV  AH,40H            ;WRITE THE FILE
  787.       MOV  CX,(WNDW_HT*(WNDW_WD+1)*2)
  788.       MOV  DX,OFFSET SCREENSAVE
  789.       INT  21H
  790.  
  791.       MOV  AH,3EH
  792.       INT  21H               ;NOW CLOSE THE FILE
  793. UP100:
  794.       RET
  795.  
  796.       PAGE
  797. ;
  798. ; HERE WE PLACE SOME SMALL GENERAL PURPOSE ROUTINES
  799. ;
  800.  
  801. PRINT_C:                     ;print the char in AL on LPT1 (parrallel)
  802.                              ;returns printer status in AH
  803.       PUSH DX
  804.       XOR  DX,DX             ;select LPT1
  805.       XOR  AH,AH             ;select "print"
  806.       INT  17H
  807.       POP  DX
  808.       TEST AH,1              ;set the zero flag if not error,
  809.                              ;clear zero flag if char not printed
  810.       RET
  811.  
  812. PLACE_CURSOR:                ;place cursor at location in dx
  813.       MOV AH,2H
  814.       PUSH BX
  815.       XOR BX,BX
  816.       INT VIDEO
  817.       POP  BX
  818.       RET
  819.  
  820. READ_CURSOR:                  ;read cursor location into dx
  821.       MOV AH,3H
  822.       PUSH BX
  823.       XOR BX,BX
  824.       INT VIDEO
  825.       POP  BX
  826.       RET
  827.  
  828. READ_CHAR:                    ;read screen character at location in dx
  829.       CALL CALC_VID_LOC       ;covert the row and column into location
  830.       MOV  AX,ES:[DI]         ;get the character at that location
  831.       RET
  832.  
  833. R_CHAR:                       ;read screen char at current cursor location
  834.       MOV AH,8H
  835.       PUSH BX
  836.       XOR BH,BH
  837.       INT VIDEO
  838.       POP  BX
  839.       RET
  840.  
  841. WRITE_CHAR:                   ;write attrib/char in ax at location in dx
  842.       PUSH AX                 ;save the attrib from destruction
  843.       CALL CALC_VID_LOC       ;convert the row and column into location
  844.       POP  AX
  845.       MOV ES:[DI],AX
  846.       RET
  847.  
  848. W_CHAR:                       ;write character at current cursor location
  849.       PUSH BX                 ;save bx register
  850.       MOV  BL,AH
  851.       XOR  BH,BH
  852.       PUSH CX                 ;retain cx register also
  853.       MOV  CX,1
  854.       MOV  AH,9H
  855.       INT VIDEO
  856.       POP  CX
  857.       POP  BX
  858.       RET
  859.  
  860. CALC_VID_LOC:                ;convert the row and column in dx into an
  861.                              ;offset into the video display buffer
  862.       XOR  AX,AX
  863.       XOR  DI,DI
  864.       PUSH CX                ;save cx -- some of those who call us need it
  865.       XOR  CX,CX
  866.  
  867.       MOV  AL,RIGHT_MARG     ;get the width of a row
  868.       INC  AX
  869.       MOV  CL,DH             ;put the number of rows into cx
  870.       JCXZ CVL200
  871. CVL100:
  872.       ADD  DI,AX             ;for every row add in another 80/40 columns
  873.       LOOP CVL100
  874. CVL200:
  875.       MOV  AL,DL             ;now move over to the current column
  876.       ADD  DI,AX
  877.  
  878.       POP  CX                ;restore cx
  879.  
  880.       SHL  DI,1              ;now convert this into byte offset
  881.       MOV  ES,DISPLAY_SEG
  882.       RET
  883.  
  884.  
  885. GET_CHAR:                     ;get character from keyboard into ax
  886.       MOV AH,0H
  887.       PUSHF                   ;simulate call to keyboard handler
  888.       CALL DWORD PTR [KEY_RQST_HANDLER]
  889.       RET
  890.  
  891. ERASE_LINE:                   ;erase the current line from dx to right margin
  892.       MOV  CL,RIGHT_MARG
  893.       SUB  CL,BL
  894.       INC  CL
  895.       XOR  CH,CH
  896.       MOV  SI,OFFSET LINESAVE
  897.  
  898. ER100:
  899.       CALL READ_CHAR         ;get the character @ current location
  900.       MOV  [SI],AX
  901.       ADD  SI,2
  902.  
  903.       MOV  AX,BLANK
  904.       CALL WRITE_CHAR
  905.       INC  DL
  906.       LOOP ER100
  907.       RET
  908.  
  909. RESTORE_LINE:                ;restore the current line from dx to right margin
  910.       MOV  CL,RIGHT_MARG
  911.       SUB  CL,BL
  912.       INC  CL
  913.       XOR  CH,CH
  914.       MOV  SI,OFFSET LINESAVE
  915.  
  916. RL100:
  917.       MOV  AX,[SI]           ;get the saved char
  918.       CALL WRITE_CHAR         ;put the saved char where indicated
  919.       ADD  SI,2
  920.       INC  DL
  921.       LOOP RL100
  922.       RET
  923.  
  924. CONVERT_LOC:                 ;convert a location on the screen (in dx) into location
  925.                              ;in the screen save buffer
  926.       MOV  CX,DX
  927.       MOV  AX,OFFSET SCREENSAVE
  928. CL100:
  929.       CMP  CH,TOP_MARG
  930.       JZ   CL200
  931.       ADD  AX,(WNDW_WD+1)*2
  932.       DEC  CH
  933.       JMP  CL100
  934.  
  935. CL200:
  936.       CMP  CL,LEFT_MARG
  937.       JZ   CL300
  938.       ADD  AX,2
  939.       DEC  CL
  940.       JMP  CL200
  941.  
  942. CL300:
  943.       RET
  944.  
  945. SAVEREG:
  946.       MOV  -2[BP],BX          ;save reggies on stack frame
  947.       MOV  -4[BP],CX
  948.       MOV  -6[BP],DX
  949.       MOV  -8[BP],SI
  950.       MOV  -0AH[BP],DI
  951.       MOV  -0CH[BP],DS
  952.       MOV  -0EH[BP],ES
  953.       RET
  954. RESTREG:
  955.       MOV  BX,-2[BP]          ;NOW PUT THE REGGIES BACK AND PULL DOWN
  956.       MOV  CX,-4[BP]          ;THE STACK FRAME
  957.       MOV  DX,-6[BP]
  958.       MOV  SI,-8[BP]
  959.       MOV  DI,-0AH[BP]
  960.       MOV  DS,-0CH[BP]
  961.       MOV  ES,-0EH[BP]
  962.       RET
  963. BODY  ENDP
  964.       PAGE
  965. INSTALL:
  966. ;THIS PROGRAM INSTALLS THE REST OF THE CODE FOR NOTE PAD
  967.  
  968. ;TRY TO READ THE INITIAL FILE UP INTO THE NOTE PAD AREA
  969.  
  970.       CALL READ_FILE
  971.       JNC  GO_AHEAD          ;ON ERROR READING FILE...
  972.                              ;...OUTPUT ERROR MESSAGE AND QUIT
  973.       MOV  DX,OFFSET ERRMSG
  974.       MOV  AH,9H
  975.       INT  21H
  976.       MOV  AH,4CH
  977.       MOV  AL,1              ;SET THE ERROR LEVEL
  978.       INT  21H
  979.  
  980. GO_AHEAD:
  981.       MOV DX,OFFSET MESSAGE  ;OUTPUT 'OK' MESSAGE
  982.       MOV AH,9H
  983.       INT 21H
  984.  
  985.       MOV AX,3516H            ;GET INTERRUPT 16 VECTOR
  986.       INT 21H
  987.       MOV WORD PTR KEY_RQST_HANDLER,BX
  988.       MOV WORD PTR KEY_RQST_HANDLER+2,ES
  989.  
  990.       MOV AX,2516H
  991.       MOV DX,OFFSET BEGIN     ;NOW PUT OUR ROUTINE THERE
  992.       INT 21H
  993.  
  994.       MOV DX,OFFSET INSTALL   ;TERMINATE AND STAY RESIDENT
  995.       ADD DX,100H
  996.       MOV CL,4
  997.       SHR DX,CL
  998.       MOV AH,31H
  999.       INT 21H
  1000.  
  1001. MESSAGE DB 10,13,'NotePad4 installed',10,13,'Alt-F10 to enter and exit',10,13,'$'
  1002.  
  1003. ERRMSG DB 10,13,'NotePad4 not installed',10,13,'Error on file read',10,13,'$'
  1004.  
  1005. CSEG ENDS
  1006.      END START
  1007.