Quick EDitor (QED) - Assembly Listing
[Copyright 1999,2002,2007 Frank Durda IV, All Rights Reserved.
Mirroring of any material on this site in any form is expressly prohibited.
The official web site for this material is: http://nemesis.lonestar.org
Contact this address for use clearances: clearance at nemesis.lonestar.org
Comments and queries to this address: web_software at nemesis.lonestar.org]
Model 4/4P Z80 Assembler Version 3(5) Page 1 02/14/99
Assembly Listing of QED/SRC
QED Quick EDitor - by Frank Durda IV
E Addr Obj Fl Ln # Source Line
0000 00002 ;-----------------------------------------------------------------------------
0000 00003 ; Copyright 1985 and 1999, Frank Durda IV, All Rights Reserved.
0000 00004 ; Permission is granted for the use of this code in whole or in part
0000 00005 ; provided the copyright and following text description of the
0000 00006 ; programs origins remains intact. This software, or software
0000 00007 ; containing elements of this software may not be sold for profit,
0000 00008 ; but may be included in a for-sale package provided that any portion
0000 00009 ; containing parts of this software must be made available on demand
0000 00010 ; for no charge or a nominal media charge.
0000 00011 ;-----------------------------------------------------------------------------
0000 00012
3000 00013 psect 3000h
3000 00015
3000 00016 ;-----------------------------------------------------------------------------
3000 00017 ; QED was originally written during the labor day weekend of 1985.
3000 00018 ; During that weekend, both the QED editor and the QD 8080 assembler
3000 00019 ; were written, pretty much from scratch. I had just been asked to
3000 00020 ; act as a part-time instructor at a local junor college and found that
3000 00021 ; although the school lab had ten Model 4 systems, they only owned four
3000 00022 ; copies of CP/M and so my students (plus those of two other classes)
3000 00023 ; would be fighting over the four systems. My class had 32 students,
3000 00024 ; and the other sections were at least that large.
3000 00025
3000 00026 ; To resolve the issue, I selected TRSDOS 6, which all the machines had
3000 00027 ; a legal license to run, and I wrote this editor and an assembler to
3000 00028 ; run on TRSDOS 6. This allowed my students to write, assemble and run
3000 00029 ; their programs on any of the ten systems. Meanwhile, the full-time
3000 00030 ; instructors were unwilling to learn TRSDOS 6, so they continued to
3000 00031 ; teach the course in the CP/M environment, forcing their sixty students
3000 00032 ; to stand in line for the four copies of CP/M.
3000 00033
3000 00034 ; The user interface of QED is similar to the Logical Systems LED
3000 00035 ; editor, although none of the LED code was used or even referenced in
3000 00036 ; writing QED. Certain things that made LED unsuitable for writing
3000 00037 ; assembler code were changed, such as tab handling, which QED displays
3000 00038 ; as one would expect them to appear. A lot of the fancier functions
3000 00039 ; an editor would usually have are absent, but a few things designed for
3000 00040 ; beginners (like being able to undo changes on a line) exist in QED.
3000 00041
3000 00042 ; After 1985, the school stopped teaching the 8080 assembly course, so I
3000 00043 ; never had the opportunity to use this program again. Apart from
3000 00044 ; fixing a bug or two and adding a few functions that were found to be
3000 00045 ; needed in the lab environment, no further work was done on QED after
3000 00046 ; the fall of 1985. This history you are reading was added years later
3000 00047 ; when the source code was made available to others. The comments on
3000 00048 ; the actual assembly code are pretty much what was written on that busy
3000 00049 ; labor day weekend.
3000 00051 ; Because of the time constraints under which QED was written, it should
3000 00052 ; be understood that the QED code was not meant to be a reference or
3000 00053 ; style guide for good coding practices, and there are certainly better
3000 00054 ; algorithms out there for doing certain parts of the work. However,
3000 00055 ; it does demonstrate the basic requirements of a what-you-see-is-what-
3000 00056 ; you-get editor, and QED could be fleshed-out into a fully functional
3000 00057 ; editor. The algorithms were written with the idea of handling files
3000 00058 ; larger than available memory, although that capability was never
3000 00059 ; completed. As I recall, negative line lengths were to indicate that
3000 00060 ; the address pointer was really the offset in a temporary file
3000 00061 ; rather than a memory location. Positive line lengths indicated the
3000 00062 ; line was still in memory. The garbage collection routine would
3000 00063 ; not only recover un-used memory, but made judgement calls about moving
3000 00064 ; active lines onto disk so some free memory would always be available.
3000 00065
3000 00066 ; QED starts in "beginners" mode by default, leaving the command menu
3000 00067 ; and tab stops on the screen. The command keys will also seem strange
3000 00068 ; to experienced computer users, but to beginners, each command key
3000 00069 ; does one and one thing only, and proved to be an easier-to-learn
3000 00070 ; system. Also, multi-step operations, like marking a range of text
3000 00071 ; or asking "are you sure" display prompts at the bottom of the screen.
3000 00072 ; Despite all the verbose messages, the editor is less than 5K in size.
3000 00073
3000 00074 ; QED was assembled using a custom assembler largely compatible with the
3000 00075 ; Tandy ALDS assembler, and QED can be assembled without change on ALDS.
3000 00076 ; It can also be assembled using the Misosys EDAS package with just a
3000 00077 ; few changes.
3000 00078
3000 00079 ; Frank Durda IV, January 1999.
3000 00080 ;-----------------------------------------------------------------------------
3000 00082 ;-----------------------------------------------------------------------------
3000 00083 ; Edit History EDIT HISTORY
3000 00084 ;
3000 00085 ; <1> Initial version, Labor day weekend panic coding project
3000 00086 ; one assembler and one screen-based editor in three days.
3000 00087 ; September 1985 Frank Durda IV
3000 00088 ;
3000 00089 ; <2> Added code to deal with the one-drive systems some people are
3000 00090 ; having to use. Allows user to swap diskettes if needed.
3000 00091 ; Also added and to position over
3000 00092 ; to tab stops. Minor bug fix here and there.
3000 00093 ; 22-Oct-1985 Frank Durda IV
3000 00094 ;
3000 00095 ; <3> Break original source into three files, add commentary.
3000 00096 ; Clean up some formatting for reasonable printing layout.
3000 00097 ; 23-Jan-1999 Frank Durda IV
3000 00098 ;
3000 00099 ; <4> Based on original notes, added basic changes for supporting
3000 00100 ; file paging. These changes only provide the structure not
3000 00101 ; the full functionality. They do require more memory, so
3000 00102 ; they can be disabled by turning off the conditional BIGFILE.
3000 00103 ; Also wrote the line move and copy routines. Now the only
3000 00104 ; functions missing from the original design are Search command
3000 00105 ; [CLEAR][1], the Substitute command [CLEAR][2], and the garbage
3000 00106 ; collector, which currently does not exist. See QEDMEM/SRC.
3000 00107 ; 14-Feb-1999 Frank Durda IV
3000 00108 ;-----------------------------------------------------------------------------
3000 00109
3000 00110
3000 00112 ldos: macro #1
00113 ld a,#1
00114 rst 28h
00115 endm
0001 00116 BIGFILE:equ 1 ;<4>Enable ability to handle big files
3000 E5 00118 begin: push hl ;Save
3001 CD6A31 00119 call clear
3004 210000 00120 ld hl,0 ;Get top of memory
3007 0600 00121 ld b,0 ;HIGH$
00122 ldos @high$
300C 2B 00123 dec hl
300D E5 00124 push hl
300E 11AF5A 00125 ld de,buffer ;Start of buffer
3011 B7 00126 or a
3012 ED52 00127 sbc hl,de ;Get size of buffer
3014 E1 00128 pop hl ;Get back @high-1
3015 3009 00129 jr nc,some ;There is some memory
00130
3017 210E41 00131 ld hl,nomem ;Complain now
00132 ldos @dsply
00133 ldos @abort ;Quit
00134
00135 ; File Loader
00136 ; first item on stack points to a filename
00137
3020 221652 00138 some: ld (bufsiz),hl ;Store memory size
3023 E1 00139 pop hl ;End of command line
3024 7E 00140 ld a,(hl) ;Get the character
3025 FE0D 00141 cp 0dh
3027 2811 00142 jr z,fileok ;Use NONAME/SRC
00143
3029 11F451 00144 ld de,fcb ;Point at file control block
00145 ldos @fspec ;Convert filename
302F 2809 00146 jr z,fileok ;Skip this
00147
3031 212A41 00148 ld hl,syerr ;Complain about filename
00149 ldos @dsply
00150 ldos @abort ;Die? For now, anyway
00151
00152
00153 ; File is ok
00154
303A 11F451 00155 fileok: ld de,fcb ;Point at FCB
303D 216941 00156 ld hl,defext ;Point at default extension
00157 ldos @fext ;Tack on extension
00158
00159 ; See if a drive number was specified
00160
3043 21F451 00161 ld hl,fcb ;<2>
3046 7E 00162 drvnxt: ld a,(hl) ;<2>
3047 FE3A 00163 cp ':' ;<2>
3049 280B 00164 jr z,fdrv ;<2>Found a drive spec
304B FE0D 00165 cp 0dh ;<2>
304D 282F 00166 jr z,twod ;<2>No drivespec, must be a two drive
304F FE03 00167 cp 03h ;<2>
3051 282B 00168 jr z,twod ;<2>
3053 23 00169 inc hl ;<2>
3054 18F0 00170 jr drvnxt ;<2>Look at next byte
3056 23 00172 fdrv: inc hl ;<2>Point at next byte
3057 7E 00173 ld a,(hl) ;<2>See if it is zero
3058 FE30 00174 cp '0' ;<2>Drive zero?
305A 2022 00175 jr nz,twod ;<2>Nope
305C 3E01 00176 ld a,1 ;<2>
305E 32F741 00177 ld (drives),a ;<2>Mark as a one drive system
3061 21603E 00178 ld hl,swapin ;<2>
00179 ldos @dsply ;<2>
3067 21D53E 00180 ld hl,swapcom ;<2>
00181 ldos @dsply ;<2>
306D 00182 fdrvl: ldos @key ;<2>
3070 FE0D 00183 cp 0dh ;<2>Enter?
3072 2807 00184 jr z,twodc ;<2>
3074 FE80 00185 cp 80h ;<2>Break?
3076 20F5 00186 jr nz,fdrvl ;<2>
00187 ldos @abort ;<2>
00188
00189 ; Init pointers to text
00190
307B CD6A31 00191 twodc: call clear ;<2>
307E 210000 00192 twod: ld hl,0
3081 22ED51 00193 ld (ptr),hl ;Store pointer
3084 221B52 00194 ld (end),hl ;Nothing in the file
3087 22F251 00195 ld (top),hl ;Start drawing here
308A 3E01 00196 ld a,1
308C 321852 00197 ld (mod),a ;Set mod flag so things work
00198
00199 ; Open this sucker
00200
308F 21AF59 00201 ld hl,ldbuf ;Point at buffer
3092 11F451 00202 ld de,fcb ;Point at FCB
3095 0600 00203 ld b,0
00204 ldos @open ;Open the file
309A 2043 00205 jr nz,notfnd ;File not found
309C AF 00206 xor a
309D 321D52 00207 ld (eof),a ;Not EOF
00208
00209 ; File is open, start loading
00210
30A0 119A51 00211 ld de,temp ;Point at the temp buffer
30A3 0E00 00212 ld c,0 ;Length is at zero
00214 ;-----------------------------------------------------------------------------
00215 ; Load the file here
00216 ;-----------------------------------------------------------------------------
00217
30A5 D5 00218 nxtchk: push de
30A6 CD4E31 00219 call rdnxt ;Read a block
30A9 D1 00220 pop de
30AA 7E 00221 nxtbyt: ld a,(hl) ;Get a byte
30AB 23 00222 inc hl
00223
30AC B7 00224 or a ;Is it a null?
30AD CA1F31 00225 jp z,nxtld ;Skip
30B0 FE0D 00226 cp 0dh ;End of line?
30B2 2843 00227 jr z,eolld ;Yes
30B4 FE09 00228 cp 9 ;Is it a tab?
30B6 280C 00229 jr z,gottab ;Convert it
00230
30B8 12 00231 ld (de),a ;Save byte in temp
30B9 79 00232 ld a,c ;Test length
30BA FE4F 00233 cp 79 ;Line too long?
30BC CA1F31 00234 jp z,nxtld ;Skip this
00235
30BF 13 00236 inc de ;Advance pointer
30C0 0C 00237 inc c ;Make line longer
30C1 C31F31 00238 jp nxtld ;Get next character
00239
00240 ; Found a tab
00241
30C4 79 00242 gottab: ld a,c ;Get position
00243 ; dec a ;Trick
30C5 E607 00244 and 7 ;Find out how many tabs to insert
30C7 D5 00245 push de
30C8 5F 00246 ld e,a ;Save count
30C9 3E08 00247 ld a,8
30CB 93 00248 sub e
30CC 5F 00249 ld e,a ;Store corrected value
30CD 81 00250 add a,c ;Find max position
30CE FE4E 00251 cp 78 ;Is this tab legal?
30D0 7B 00252 ld a,e
30D1 D1 00253 pop de
30D2 304B 00254 jr nc,nxtld ;Ignore the tab
00255
30D4 EB 00256 ex de,hl
30D5 3620 00257 tabexp: ld (hl),' '
30D7 23 00258 inc hl
30D8 0C 00259 inc c ;Show line length
30D9 3D 00260 dec a
30DA 20F9 00261 jr nz,tabexp ;Expand
30DC EB 00262 ex de,hl ;Put things back
30DD 1840 00263 jr nxtld ;All done, exit
00265 ; File not found
00266
30DF AF 00267 notfnd: xor a ;Turn mod off
30E0 321852 00268 ld (mod),a ;Like this
30E3 CDD438 00269 call load ;Force top line into temp
30E6 3A1E52 00270 ld a,(help)
30E9 FE11 00271 cp 17
30EB CC0B33 00272 call z,helpon ;Start with help turned on
30EE 216C41 00273 ld hl,fnf
30F1 CDFE3A 00274 call doerror ;Display it
30F4 C37831 00275 jp newchar ;Start the fun
00276
00277
00278 ; End of line detected
00279
30F7 E5 00280 eolld: push hl
30F8 C5 00281 push bc
00282
30F9 21EC51 00283 ld hl,tmpsiz
30FC 71 00284 ld (hl),c ;Store line length
00285
30FD 2AED51 00286 ld hl,(ptr)
3100 CD5439 00287 call getpos
3103 AF 00288 xor a
3104 77 00289 ld (hl),a
3105 2B 00290 dec hl
3106 77 00291 ld (hl),a
3107 2B 00292 dec hl
3108 77 00293 ld (hl),a
3109 2B 00295 dec hl ;<4>
310A 77 00296 ld (hl),a ;<4>
00298
310B CD0A39 00299 call leave ;Force the line to be loaded into mem
310E 2AED51 00300 ld hl,(ptr)
3111 23 00301 inc hl
3112 22ED51 00302 ld (ptr),hl ;Point at next line
3115 221B52 00303 ld (end),hl ;Set EOF too
3118 C1 00304 pop bc
3119 E1 00305 pop hl
311A 0E00 00306 ld c,0 ;Set count at zero for next line
311C 119A51 00307 ld de,temp ;Point at start of buffer again
311F 05 00309 nxtld: dec b ;Decrement buffer pointer
3120 C2AA30 00310 jp nz,nxtbyt ;Get another byte
00311
3123 3A1D52 00312 ld a,(eof) ;Was that the end
3126 B7 00313 or a
3127 CAA530 00314 jp z,nxtchk ;Get another chunk
00315
312A 11F451 00316 ld de,fcb
00317 ldos @close ;Close file
00318
3130 210000 00319 ld hl,0 ;Point at the start
3133 22ED51 00320 ld (ptr),hl ;Position here
00321
3136 AF 00322 xor a ;Turn mod off
3137 321852 00323 ld (mod),a ;Like this
313A CDD438 00324 call load ;Force top line into temp
313D 3A1E52 00325 ld a,(help)
3140 FE11 00326 cp 17
3142 CC0B33 00327 call z,helpon ;Start with help turned on
3145 CD4D3B 00328 call fixscr ;Set up screen
3148 CD613A 00329 call fixcur ;Fix cursor position
314B C37831 00330 jp newchar ;Start the fun
00331
00332 ; Fetch another block from the file
00333
314E 11F451 00334 rdnxt: ld de,fcb ;Point at the block
00335 ldos @read ;Get a block
3154 2005 00336 jr nz,iseof ;What happened?
3156 21AF59 00337 ld hl,ldbuf ;Point at the buffer
3159 0600 00338 ld b,0 ;Read 256 bytes
00339
315B 00340 iseof: ldos @ckeof ;See if we are the end
315E 2809 00341 jr z,noteof
3160 3AFC51 00342 ld a,(fcb+8) ;Get eof byte
3163 47 00343 ld b,a ;Only read this much from this block
3164 3E01 00344 ld a,1
3166 321D52 00345 ld (eof),a ;Mark the end
3169 C9 00346 noteof: ret ;Return
00347
00348 ; Clear the screen, but leave reverse video active
00349
316A 00350 clear: ldos @cls
316D 0E10 00351 ld c,16 ;Start reverse video mode
00352 ldos @dsp
3172 0E11 00353 ld c,17
00354 ldos @dsp
3177 C9 00355 ret
00356
00357 ; Include editor command processing code
00360 ; QED Quick EDitor - by Frank Durda IV
00361 ; Editor commands, insert, delete, modify, save and exit
00362 ; This file is included by QED/SRC
00363 ; Copyright 1985 and 1999, All Rights Reserved.
00364
00365 ;-----------------------------------------------------------------------------
00366 ; Come here to do something new - get a command or a character
00367 ;-----------------------------------------------------------------------------
00368
3178 00369 newchar:ldos @key ;Get a character from the keyboard
317B F5 00370 push af
317C 3AF641 00371 ld a,(error) ;Before last key, was there a special
317F B7 00372 or a ;Message put on the screen?
3180 280A 00373 jr z,nms1 ;No, all is normal
3182 CD4D3B 00374 call fixscr ;Redraw entire screen
3185 CD493A 00375 call updlin ;Update working line & number
3188 AF 00376 xor a
3189 32F641 00377 ld (error),a ;Reset error
318C F1 00378 nms1: pop af ;Put new character back
318D FE20 00379 cp ' ' ;Is the character printable
318F DA4932 00380 jp c,ctl ;No, below
00381
3192 FE80 00382 cp 128 ;Yes
3194 3803 00383 jr c,char ;It's a printable
3196 C34932 00384 jp ctl
00385
00386 ; Handle a printable character
00387
3199 4F 00388 char: ld c,a ;Save character
319A 3E01 00389 ld a,1
319C 321952 00390 ld (fmod),a ;Mark the file as being modified
319F 3AF441 00391 ld a,(status) ;Get the mode
00392
31A2 FE01 00393 cp instxt ;Are we insert text
31A4 2847 00394 jr z,inschr ;Need to insert
31A6 FE04 00395 cp position ;Are we positioning?
31A8 2804 00396 jr z,char1
31AA FE02 00397 cp marklin
31AC 2005 00398 jr nz,okchar
31AE C5 00399 char1: push bc
31AF CDB93A 00400 call nrmstat ;Turn off move
31B2 C1 00401 pop bc
00403 ; Replace this character with old character
00404
31B3 3A1552 00405 okchar: ld a,(col) ;Get our column
31B6 219A51 00406 ld hl,temp ;Point at temp buffer
31B9 5F 00407 ld e,a ;Extent
31BA 1600 00408 ld d,0
31BC 19 00409 add hl,de ;Build a pointer
31BD 71 00410 ld (hl),c ;Store new character
00411
31BE 1C 00412 inc e ;Make it one's based
31BF 3AEC51 00413 ld a,(tmpsiz) ;Get temp size
31C2 BB 00414 cp e ;Are we beyond that point?
31C3 4F 00415 ld c,a ;Put old EOL in C
31C4 7B 00416 ld a,e ;Put cursor position in A
31C5 3011 00417 jr nc,charin ;Change was within existing line
00418
31C7 32EC51 00419 ld (tmpsiz),a ;Store character
00420
00421 ; Change nulls to spaces
00422
31CA 91 00423 sub c ;Distance between old end & new end
31CB 3D 00424 dec a ;Adjust for amount of spaces needed
31CC 280A 00425 jr z,charin ;No blanks needed
31CE 219A51 00426 ld hl,temp ;Point at the start
31D1 09 00427 add hl,bc
31D2 3620 00428 moresp: ld (hl),' ' ;A space
31D4 23 00429 inc hl
31D5 3D 00430 dec a ;Decrement count
31D6 20FA 00431 jr nz,moresp ;One more space
00432
31D8 3A1552 00433 charin: ld a,(col) ;Get our NEW position (again)
31DB FE4F 00434 cp 79 ;Test for end of line
31DD 2801 00435 jr z,charend ;Too far
31DF 3C 00436 inc a ;Advance pointer
00437
31E0 321552 00438 charend:ld (col),a ;Set new column
31E3 3E01 00439 ld a,1 ;Mark line "modified"
31E5 321852 00440 ld (mod),a ;Set it
00441
31E8 CD493A 00442 call updlin ;Update screen
31EB 188B 00443 jr newchar ;All done, get another character
00445 ; We are insert character mode, so we need to stretch the line.
00446
31ED 3AEC51 00447 inschr: ld a,(tmpsiz) ;Get current size of line
31F0 FE50 00448 cp 80 ;Is it time to stop?
31F2 2015 00449 jr nz,insok ;Ok to do it
00450
31F4 210E40 00451 ld hl,stmax ;Say why we stopped
31F7 3E01 00452 ld a,1
31F9 32F641 00453 ld (error),a ;Set error flag
31FC CDFE3A 00454 call doerror ;Display reason
31FF AF 00455 xor a
3200 32F441 00456 ld (status),a ;Turn off insert mode
3203 CD493A 00457 call updlin ;Update help
3206 C37831 00458 jp newchar ;All done
00459
3209 C5 00460 insok: push bc ;Save new character
320A 5F 00461 ld e,a ;size of line
320B 1600 00462 ld d,0
00463
320D 211552 00464 ld hl,col ;Get current column
3210 96 00465 sub (hl) ;size-column=bytes to shift
3211 4F 00466 ld c,a
3212 0600 00467 ld b,0 ;Build LDIR count
3214 1D 00468 dec e ;Make pointer zero based
3215 219A51 00469 ld hl,temp ;Point at line
3218 19 00470 add hl,de ;Point at end of line
3219 5D 00471 ld e,l
321A 54 00472 ld d,h
321B 13 00473 inc de ;Shift destination
321C EDB8 00474 lddr ;Shift text
321E 3A1552 00475 ld a,(col) ;Get column
3221 5F 00476 ld e,a
3222 1600 00477 ld d,0
3224 219A51 00478 ld hl,temp
3227 19 00479 add hl,de
3228 C1 00480 pop bc
3229 71 00481 ld (hl),c ;Load new character
00482
322A 21EC51 00483 ld hl,tmpsiz ;Point a line size
322D 34 00484 inc (hl) ;Inc line length
00485
322E 3A1552 00486 ld a,(col)
3231 FE4F 00487 cp 79 ;Are we at the limit
3233 2005 00488 jr nz,insw ;Leave cursor here
3235 CDB93A 00489 call nrmstat ;Turn off insert mode
3238 1804 00490 jr insc
323A 3C 00492 insw: inc a
323B 321552 00493 ld (col),a
00494
323E 3E01 00495 insc: ld a,1
3240 321852 00496 ld (mod),a ;Show we tampered with the line
3243 CD493A 00497 call updlin
3246 C37831 00498 jp newchar ;Get next character
00499
00500 ; Handle special characters
00501
3249 FE0B 00502 ctl: cp 11 ;Is it up arrow
324B CAB433 00503 jp z,uparrow ;Uparrow pressed
324E FE0A 00504 cp 10 ;Is it down arrow
3250 CA1834 00505 jp z,dnarrow ;Downarrow pressed
3253 FE0D 00506 cp 13 ;Is it
3255 CA0334 00507 jp z,enter ;Handle it
3258 FE09 00508 cp 9 ;Right arrow?
325A CA8F33 00509 jp z,rtarrow ;Rightarrow pressed
325D FE08 00510 cp 8 ;Back space
325F CAA233 00511 jp z,bkarrow ;Leftarrow pressed
3262 FE80 00512 cp 128 ;Break?
3264 CA8333 00513 jp z,break ;Stop
3267 FE18 00514 cp 24 ;Leftarrow?
3269 CA5F33 00515 jp z,goeast
326C FE19 00516 cp 25
326E CA6A33 00517 jp z,gowest
3271 FE1B 00518 cp 27 ;Upparow?
3273 CA4E34 00519 jp z,gonorth
3276 FE1A 00520 cp 26
3278 CA8D34 00521 jp z,gosouth
327B FE81 00522 cp 129 ;?
327D CAEB34 00523 jp z,f1 ;Insert Characters here
3280 FE82 00524 cp 130
3282 CA0B35 00525 jp z,f2 ;Delete Characters here
3285 FE83 00526 cp 131
3287 CA5D35 00527 jp z,f3
328A FEAD 00528 cp 173 ;Help toggle?
328C CAED32 00529 jp z,helpx
00530 ; Commands not yet implemented.
00531 ; cp 177 ;<1>
00532 ; jp z,search ;Search for a string
00533 ; cp 178 ;<2>
00534 ; jp z,subst ;Do a string substution
328F FEB3 00535 cp 179 ;<3>
3291 CADE33 00536 jp z,mlines ;Stretch the listing
3294 FEB4 00537 cp 180 ;<4>
3296 CABF32 00538 jp z,markit ;Start/Stop marking
3299 FEB5 00539 cp 181 ;<5>
329B CA9739 00540 jp z,dlines ;Delete lines
329E FEB6 00542 cp 182 ;<6>
32A0 CABA36 00543 jp z,movcpy ;Move something
32A3 FEB7 00544 cp 183 ;<7>
32A5 CABA36 00545 jp z,movcpy ;Copy something
32A8 FEB8 00546 cp 184 ;<8>
32AA CAF835 00547 jp z,keysave ;Save right now
32AD FEB9 00548 cp 185 ;<9>
32AF CA6E35 00549 jp z,exit ;Exit the editor
00550
32B2 FE88 00551 cp 136 ;<2>
32B4 CAA836 00552 jp z,ltab ;<2>Tab left
32B7 FE89 00553 cp 137 ;<2>
32B9 CA9336 00554 jp z,rtab ;<2>Tab Right
32BC C37831 00555 jp newchar
00556
00557 ;-----------------------------------------------------------------------------
00558 ; Mark handler
00559 ;-----------------------------------------------------------------------------
00560
32BF 3AF441 00561 markit: ld a,(status) ;Get status
32C2 FE02 00562 cp marklin ;Are we marking already?
32C4 2821 00563 jr z,mk1 ;We were marking
00564
32C6 2AED51 00565 ld hl,(ptr)
32C9 ED5B1B52 00566 ld de,(end)
32CD B7 00567 or a
32CE ED52 00568 sbc hl,de
32D0 CA7831 00569 jp z,newchar ;Can't start marking on end
00570
32D3 3E02 00571 ld a,marklin
32D5 32F441 00572 ld (status),a
32D8 CDBF3A 00573 call fixstat ;Fix status
00574
32DB 2AED51 00575 ld hl,(ptr) ;Get our position
32DE 221F52 00576 ld (mark),hl ;Mark it
32E1 CD4D3B 00577 call fixscr ;Update screen
32E4 C37831 00578 jp newchar ;Abort line related stuff
00579
32E7 CDB93A 00580 mk1: call nrmstat ;Turn off marking and fix screen
32EA C37831 00581 jp newchar ;Abort line related stuff
00583 ;-----------------------------------------------------------------------------
00584 ; Handle help screen
00585 ;-----------------------------------------------------------------------------
00586
32ED 3A1E52 00587 helpx: ld a,(help) ;Get the current size
32F0 FE18 00588 cp 24 ;Is help off?
32F2 280B 00589 jr z,helpy ;Turn it on
32F4 3E18 00590 ld a,24 ;Turn help off
32F6 321E52 00591 ld (help),a
32F9 CD4D3B 00592 call fixscr ;Redraw screen
32FC C37831 00593 jp newchar ;All done
00594
32FF CD0B33 00595 helpy: call helpon
3302 CD4D3B 00596 call fixscr ;Redraw screen
3305 CD493A 00597 call updlin ;Redraw active line in case it moved
3308 C37831 00598 jp newchar ;All done
00599
330B 3E11 00600 helpon: ld a,17 ;Amount of screen to use
330D 321E52 00601 ld (help),a
3310 32F541 00602 ld (ostatus),a ;Load insave status into old copy
00603
3313 2AED51 00604 ld hl,(ptr)
3316 ED5BF251 00605 ld de,(top)
331A B7 00606 or a
331B ED52 00607 sbc hl,de
331D 7D 00608 ld a,l ;Get amount
331E D611 00609 sub 16+1 ;See if cursor is in help-zone
3320 3808 00610 jr c,helpok ;Cursor is ok
3322 EB 00611 ex de,hl ;Put current top in HL
3323 1600 00612 ld d,0
3325 5F 00613 ld e,a
3326 19 00614 add hl,de ;Get new top (was sbc)
3327 22F251 00615 ld (top),hl ;Store it
00616
332A 210011 00617 helpok: ld hl,1100h ;Put cursor here
332D 0603 00618 ld b,3 ;Move cursor
00619 ldos @vdctl
3332 213A3C 00620 ld hl,bos ;Draw help
00621 ldos @dsply
3338 210616 00622 ld hl,1606h
333B 0603 00623 ld b,3
00624 ldos @vdctl
3340 21F451 00625 ld hl,fcb
00626
3343 7E 00627 fln: ld a,(hl)
3344 FE0D 00628 cp 0dh
3346 280B 00629 jr z,eofl
3348 FE03 00630 cp 03
334A 2807 00631 jr z,eofl
334C 4F 00632 ld c,a
00633 ldos @dsp
3350 23 00634 inc hl
3351 18F0 00635 jr fln
3353 212F52 00637 eofl: ld hl,screen
3356 0606 00638 ld b,6
00639 ldos @vdctl ;Snap help into our screen
335B CDBF3A 00640 call fixstat ;Show the status
335E C9 00641 ret
00642
00643
00644 ;-----------------------------------------------------------------------------
00645 ; Move cursor to the left
00646 ;-----------------------------------------------------------------------------
00647
335F 3AF441 00648 goeast: ld a,(status) ;Get the mode
3362 FE03 00649 cp inslines ;Are we inserting lines?
3364 C4B93A 00650 call nz,nrmstat ;Set normal mode and display it
3367 AF 00651 xor a
3368 1810 00652 jr gowt1 ;<4>Share common code
00653
00654
00655 ;-----------------------------------------------------------------------------
00656 ; Move cursor to the right
00657 ;-----------------------------------------------------------------------------
00658
336A 3AF441 00659 gowest: ld a,(status) ;Get the mode
336D FE03 00660 cp inslines ;Are we inserting lines?
336F C4B93A 00661 call nz,nrmstat ;Set normal status and display
00662
3372 3AEC51 00663 ld a,(tmpsiz) ;Get number of characters
3375 FE50 00664 cp 80
3377 2001 00665 jr nz,gowt1 ;Number is ok
3379 3D 00666 dec a ;Back up one position
337A 321552 00667 gowt1: ld (col),a
337D CD613A 00668 call fixcur
3380 C37831 00669 jp newchar ;all done
00670
00671
00672 ;-----------------------------------------------------------------------------
00673 ; Abort anything and everything that is going one
00674 ;-----------------------------------------------------------------------------
00675
3383 CDB93A 00676 break: call nrmstat ;Go back to mode 0
00677
3386 CDD438 00678 call load ;Erase changes on this line
3389 CD4D3B 00679 call fixscr ;Redraw screen just in case
338C C37831 00680 jp newchar
00682 ;-----------------------------------------------------------------------------
00683 ; Right Arrow Pressed
00684 ;-----------------------------------------------------------------------------
00685
338F 3AF441 00686 rtarrow:ld a,(status) ;Get the mode
3392 FE03 00687 cp inslines ;Are we inserting lines?
3394 C4B93A 00688 call nz,nrmstat ;Go back to mode 0
00689
3397 3A1552 00690 ld a,(col) ;Get current column
339A FE4F 00691 cp 79 ;Are we at the end already?
339C CA7831 00692 jp z,newchar ;Then ignore this
339F 3C 00693 inc a ;Advance column
33A0 18D8 00694 jr gowt1 ;<4>
00695
00696
00697 ;-----------------------------------------------------------------------------
00698 ; Left Arrow Pressed
00699 ;-----------------------------------------------------------------------------
00700
33A2 3AF441 00701 bkarrow:ld a,(status) ;Get the mode
33A5 FE03 00702 cp inslines ;Are we inserting lines?
33A7 C4B93A 00703 call nz,nrmstat ;Go back to mode 0
00704
33AA 3A1552 00705 ld a,(col) ;Get current column
33AD B7 00706 or a ;Where are we?
33AE CA7831 00707 jp z,newchar ;Don't bother to move, at column 0
00708
33B1 3D 00709 dec a ;Back up cursor
33B2 18C6 00710 jr gowt1 ;<4>
00711
00712
00713 ;-----------------------------------------------------------------------------
00714 ; Handle Uparrow
00715 ;-----------------------------------------------------------------------------
00716
33B4 3AF441 00717 uparrow:ld a,(status) ;Get the mode
33B7 FE04 00718 cp position
33B9 2805 00719 jr z,up1
33BB FE02 00720 cp marklin ;Are we marking lines?
33BD C4B93A 00721 call nz,nrmstat ;Go back to mode 0
00722
33C0 2AED51 00723 up1: ld hl,(ptr) ;Get current position
33C3 7C 00724 ld a,h
33C4 B5 00725 or l
33C5 CA7831 00726 jp z,newchar ;At the top, don't go higher
33C8 2B 00728 dec hl
33C9 E5 00729 push hl
33CA CD0A39 00730 call leave ;Flush temp buffer
33CD E1 00731 pop hl
33CE 22ED51 00732 ld (ptr),hl ;Store updated position
33D1 CDD438 00733 call load ;Load new line into temp
33D4 CD4D3B 00734 call fixscr ;Make any needed screen changes
33D7 AF 00735 xor a ;Turn off mod
33D8 321852 00736 ld (mod),a
33DB C37831 00737 jp newchar ;Exit any insert
00738
00739
00740 ;-----------------------------------------------------------------------------
00741 ; Insert lines
00742 ;-----------------------------------------------------------------------------
00743
33DE 2A1B52 00744 mlines: ld hl,(end)
33E1 ED5BED51 00745 ld de,(ptr)
33E5 B7 00746 or a
33E6 ED52 00747 sbc hl,de
33E8 CA7831 00748 jp z,newchar ;At bottom, insert not needed
00749
33EB 3E03 00750 ld a,inslines
33ED 32F441 00751 ld (status),a ;Set addline flag
33F0 CD6839 00752 call newlin
33F3 CDD438 00753 call load
33F6 CDBF3A 00754 call fixstat ;Fix the status
33F9 CD4D3B 00755 call fixscr ;Fix the screen
33FC AF 00756 xor a
33FD 321852 00757 ld (mod),a
3400 C37831 00758 jp newchar ;All is well
00759
00760
00761 ;-----------------------------------------------------------------------------
00762 ; Handle Enter (Shares parts of Downarrow)
00763 ;-----------------------------------------------------------------------------
00764
3403 AF 00765 enter: xor a
3404 321552 00766 ld (col),a ;Set Column 0
3407 3AF441 00767 ld a,(status) ;Get our status
340A B7 00768 or a
340B 2804 00769 jr z,ent1
340D FE01 00770 cp instxt ;Are we in insert mode?
340F 2013 00771 jr nz,god1 ;No, not special case
3411 3E01 00772 ent1: ld a,1 ;Force mod flag
3413 321852 00773 ld (mod),a ;This will make create a line
3416 180C 00774 jr god1
00776 ;-----------------------------------------------------------------------------
00777 ; Handle Downarrow
00778 ;-----------------------------------------------------------------------------
00779
3418 3AF441 00780 dnarrow:ld a,(status) ;Get the mode
341B FE04 00781 cp position
341D 2805 00782 jr z,god1
341F FE02 00783 cp marklin ;Are we marking lines?
3421 C4B93A 00784 call nz,nrmstat ;Go back to mode 0
00785
3424 CD0A39 00786 god1: call leave ;This may create a new line
3427 ED5BED51 00787 ld de,(ptr) ;Get current position
342B 2A1B52 00788 ld hl,(end) ;Get last line number
342E B7 00789 or a
342F ED52 00790 sbc hl,de ;Are we at the end?
3431 CA4134 00791 jp z,jstld ;Yes don't go further
00792
3434 EB 00793 ex de,hl
3435 23 00794 inc hl ;Advance line
3436 22ED51 00795 ld (ptr),hl ;Store pointer
3439 3AF441 00796 ld a,(status) ;Are we in line-insert mode?
343C FE03 00797 cp inslines
343E CC6839 00798 call z,newlin ;Do it if we are in that mode
00799
3441 CDD438 00800 jstld: call load ;Load new line
3444 CD4D3B 00801 call fixscr ;Make any needed screen changes
3447 AF 00802 xor a
3448 321852 00803 ld (mod),a ;Turn off mod
344B C37831 00804 jp newchar ;All done, exit
00806 ;-----------------------------------------------------------------------------
00807 ; Handle Shift Upparrow (go to top of frame)
00808 ;-----------------------------------------------------------------------------
00809
344E 3AF441 00810 gonorth:ld a,(status) ;Get the mode
3451 FE04 00811 cp position
3453 2805 00812 jr z,gonor1
3455 FE02 00813 cp marklin ;Are we marking lines?
3457 C4B93A 00814 call nz,nrmstat ;Go to mode 0
00815
345A CD0A39 00816 gonor1: call leave ;Leave the line we are on
345D 2AED51 00817 ld hl,(ptr) ;Get our position
3460 ED5BF251 00818 ld de,(top) ;Get top of frame
3464 B7 00819 or a
3465 ED52 00820 sbc hl,de ;Find out if we are there
3467 280D 00821 jr z,gonnth ;Go up another frame
00822
00823 ; Simply position cursor on top line
00824
3469 ED53ED51 00825 ld (ptr),de ;Set new line
346D CDD438 00826 ncom: call load ;Load into temp
3470 CD4D3B 00827 call fixscr ;Fix the screen
3473 C37831 00828 jp newchar ;All done
00829
00830 ; Handle long throws
00831
3476 EB 00832 gonnth: ex de,hl ;Put current top in HL
3477 3A1E52 00833 ld a,(help) ;Get screen size
347A 5F 00834 ld e,a
347B 1600 00835 ld d,0
347D B7 00836 or a
347E ED52 00837 sbc hl,de ;See if this will fit
3480 3003 00838 jr nc,nthok ;Move is ok
3482 210000 00839 ld hl,0 ;Go to the top
00840
3485 22F251 00841 nthok: ld (top),hl ;Set top
3488 22ED51 00842 ld (ptr),hl ;Set cursor
348B 18E0 00843 jr ncom ;Go to common code
00845 ;-----------------------------------------------------------------------------
00846 ; Handle Going to bottom of frame
00847 ;-----------------------------------------------------------------------------
00848
348D 3AF441 00849 gosouth:ld a,(status) ;Get the mode
3490 FE04 00850 cp position
3492 2805 00851 jr z,gosou1
3494 FE02 00852 cp marklin ;Are we marking lines?
3496 C4B93A 00853 call nz,nrmstat ;Go to mode 0
00854
3499 CD0A39 00855 gosou1: call leave ;Unload current line
349C 2AF251 00856 ld hl,(top) ;Get top of frame
349F 3A1E52 00857 ld a,(help)
34A2 3D 00858 dec a ;Make zero based
34A3 5F 00859 ld e,a
34A4 1600 00860 ld d,0
34A6 19 00861 add hl,de ;Get last line on frame
34A7 EB 00862 ex de,hl ;Put bottom of frame in DE
34A8 2AED51 00863 ld hl,(ptr) ;Find out if we are there
34AB B7 00864 or a
34AC ED52 00865 sbc hl,de ;Are we there?
34AE 2815 00866 jr z,gofars ;Yes, so jump further
00867
34B0 2A1B52 00868 ld hl,(end) ;Make sure this is ok
34B3 B7 00869 or a
34B4 ED52 00870 sbc hl,de
34B6 3822 00871 jr c,stharg ;No, too far
34B8 ED53ED51 00872 ld (ptr),de ;Point at bottom
34BC CDD438 00873 call load ;Load line
34BF CD4D3B 00874 call fixscr ;Fix the screen
34C2 C37831 00875 jp newchar ;Abort any insert
00876
00877 ; We were at the bottom of a frame, so go to the next one
00878
34C5 13 00879 gofars: inc de ;Proposed top
34C6 ED53F251 00880 ld (top),de ;Make this the bottom
34CA 3A1E52 00881 ld a,(help)
34CD 6F 00882 ld l,a
34CE 2600 00883 ld h,0
34D0 19 00884 add hl,de
34D1 EB 00885 ex de,hl ;Save suggested ptr here
34D2 2A1B52 00886 ld hl,(end) ;Find out where end is
34D5 B7 00887 or a
34D6 ED52 00888 sbc hl,de ;See if our bottom is in the file
34D8 3004 00889 jr nc,gfarsx ;Ok
34DA ED5B1B52 00890 stharg: ld de,(end) ;Too far, use END of file
34DE ED53ED51 00891 gfarsx: ld (ptr),de ;All done
34E2 CDD438 00892 call load ;Bring whatever it is up
34E5 CD4D3B 00893 call fixscr ;Update drawing
34E8 C37831 00894 jp newchar
00896 ;-----------------------------------------------------------------------------
00897 ; Handle Start insert mode
00898 ;-----------------------------------------------------------------------------
00899
34EB 3AEC51 00900 f1: ld a,(tmpsiz) ;Get current line size
34EE B7 00901 or a
34EF CA7831 00902 jp z,newchar ;Can't do insert unless line has text
34F2 FE50 00903 cp 80 ;Get line size
34F4 CA7831 00904 jp z,newchar ;Line is at max size now
34F7 47 00905 ld b,a ;Save line length
34F8 3A1552 00906 ld a,(col) ;Get current column
34FB 3C 00907 inc a ;Make ones' based
34FC B8 00908 cp b ;Only insert inside text
34FD D27831 00909 jp nc,newchar ;After end of line, end of text
00910
00911 ; Okay to be insert mode
00912
3500 3E01 00913 ld a,instxt ;Set message
3502 32F441 00914 ld (status),a ;Like this
3505 CDBF3A 00915 call fixstat ;Show new status
3508 C37831 00916 jp newchar ;Do next character
00917
00918
00919 ;-----------------------------------------------------------------------------
00920 ; Handle Delete a character here
00921 ;-----------------------------------------------------------------------------
00922
350B CDB93A 00923 f2: call nrmstat ;Go to mode 0
350E 3E01 00924 ld a,1
3510 321952 00925 ld (fmod),a ;Mark the file as modified
3513 3A1552 00926 ld a,(col) ;Get our position
3516 47 00927 ld b,a ;Put our position
3517 3AEC51 00928 ld a,(tmpsiz) ;Get current line size
351A B7 00929 or a
351B CA7831 00930 jp z,newchar ;Screen does not change here
351E 04 00931 inc b ;Advance one
351F 68 00932 ld l,b ;Get a copy of the last character
3520 90 00933 sub b ;Can it be deleted
3521 DA7831 00934 jp c,newchar ;No, out of range
3524 2810 00935 jr z,f2x
00936
00937 ; Character is ok
00938
3526 2600 00939 ld h,0
3528 119A51 00940 ld de,temp
352B 19 00941 add hl,de ;HL points at character to move
352C 5D 00942 ld e,l
352D 54 00943 ld d,h
352E 1B 00944 dec de ;New position
352F 4F 00945 ld c,a
3530 0600 00946 ld b,0 ;Amount to move
3532 EDB0 00947 ldir ;Move data
3534 1812 00948 jr f2y
3536 3A1552 00950 f2x: ld a,(col)
3539 119A51 00951 ld de,temp
353C 6F 00952 ld l,a
353D 2600 00953 ld h,0
353F 2C 00954 inc l
3540 19 00955 add hl,de
3541 B7 00956 or a
3542 2804 00957 jr z,f2y
3544 3D 00958 dec a
3545 321552 00959 ld (col),a
00960
3548 2B 00961 f2y: dec hl ;Back up slightly
3549 3620 00962 ld (hl),' ' ;Tack a space on the end
354B 3AEC51 00963 ld a,(tmpsiz) ;Get current line size
354E 3D 00964 dec a
354F 32EC51 00965 ld (tmpsiz),a ;Store updated line
3552 CD493A 00966 call updlin ;Do it
3555 3E01 00967 ld a,1
3557 321852 00968 ld (mod),a ;Set mod flag
355A C37831 00969 jp newchar ;All done
00970
00971 ;-----------------------------------------------------------------------------
00972 ; Undo changes on this line
00973 ;-----------------------------------------------------------------------------
00974
355D 3AF441 00975 f3: ld a,(status)
3560 FE02 00976 cp marklin
3562 C4B93A 00977 call nz,nrmstat ;Set mode zero
00978
3565 CDD438 00979 call load
3568 CD493A 00980 call updlin ;Do it
356B C37831 00981 jp newchar ;All done
00983 ;-----------------------------------------------------------------------------
00984 ; Exit the editor
00985 ;-----------------------------------------------------------------------------
00986
356E 0603 00987 exit: ld b,3
3570 210017 00988 ld hl,1700h ;Point here
00989 ldos @vdctl
3576 3A1952 00990 ld a,(fmod) ;Has anything been done?
3579 B7 00991 or a
357A 2819 00992 jr z,enc ;Nothing has changed
00993
00994 ; Make sure they want to do this
00995
357C 216740 00996 ld hl,exmsg
00997 ldos @dsply
00998 ldos @key
3585 E65F 00999 and 5fh
3587 FE4E 01000 cp 'N'
3589 2812 01001 jr z,equit
358B FE59 01002 cp 'Y'
358D 280E 01003 jr z,equit
01004
358F CD4D3B 01005 call fixscr
3592 C37831 01006 jp newchar
01007
3595 215240 01008 enc: ld hl,ncmsg
01009 ldos @dsply
359B 180D 01010 jr quit ;Handle media swap
01011
359D 4F 01012 equit: ld c,a
01013 ldos @dsp
35A1 FE4E 01014 cp 'N'
35A3 2805 01015 jr z,quit
01016
35A5 CD2536 01017 call save ;Save changes
35A8 201D 01018 jr nz,nosave
35AA 3AF741 01019 quit: ld a,(drives) ;<2>Get drive count
35AD FE01 01020 cp 1 ;<2>One drive system?
35AF 2010 01021 jr nz,quit1 ;<2>No, just exit
01022 ldos @cls ;<2>
35B4 219B3E 01023 ld hl,swapout ;<2>Give them a chance to exit
01024 ldos @dsply ;<2>
35BA 01025 quitl: ldos @key ;<2>
35BD FE0D 01026 cp 0dh ;<2>
35BF 20F9 01027 jr nz,quitl ;<2>
01028
35C1 210000 01029 quit1: ld hl,0
01030 ldos @exit
35C7 FE25 01032 nosave: cp 37 ;Is it illegal access?
35C9 2002 01033 jr nz,nosav1
35CB 3E0F 01034 ld a,15 ;Then change it to write-protected err
35CD F6C0 01035 nosav1: or 0c0h
35CF 4F 01036 ld c,a
35D0 C5 01037 push bc
01038 ldos @flags
35D4 FDCB02FE 01039 set 7,(iy+2) ;Put text in our buffer
35D8 11A441 01040 ld de,errtmp
35DB C1 01041 pop bc
01042 ldos @error
35DF 21A441 01043 ld hl,errtmp
35E2 3E0D 01044 ld a,0dh
35E4 BE 01045 erfnlp: cp (hl)
35E5 2803 01046 jr z,erdncr
35E7 23 01047 inc hl
35E8 18FA 01048 jr erfnlp
01049
35EA 3611 01050 erdncr: ld (hl),17
35EC 23 01051 inc hl
35ED 3603 01052 ld (hl),3
35EF 219241 01053 ld hl,nos
35F2 CDFE3A 01054 call doerror
35F5 C37831 01055 jp newchar
01056
01057
01058 ; Save the internal buffer off to a file
01059
35F8 210017 01060 keysave:ld hl,1700h
35FB 0603 01061 ld b,3
01062 ldos @vdctl
3600 219040 01063 ld hl,savf
01064 ldos @dsply
3606 CD2536 01065 call save
3609 C2C735 01066 jp nz,nosave ;Share no save edit code
360C 210017 01067 ld hl,1700h
360F 0603 01068 ld b,3
01069 ldos @vdctl
3614 21A140 01070 ld hl,savok
01071 ldos @dsply
361A CD613A 01072 call fixcur ;<2>Update cursor position
361D 3E01 01073 ld a,1
361F 32F641 01074 ld (error),a ;<2>Fake an error so screen will be
01075 ;<2>redrawn on next keystroke.
3622 C37831 01076 jp newchar
01078 ; Do the actual save of a buffer to disk.
01079
3625 CDB93A 01080 save: call nrmstat ;Set mode 0
3628 CD0A39 01081 call leave
362B 11F451 01082 ld de,fcb
362E 0600 01083 ld b,0
3630 21AF59 01084 ld hl,ldbuf ;Point at a buffer
01085 ldos @init ;Try to open the file
3636 C0 01086 ret nz ;Can't, stop now
01087
3637 2AED51 01088 ld hl,(ptr) ;Get current pointer
363A 22F051 01089 ld (tmpcur),hl ;Put it here
363D 210000 01090 ld hl,0
3640 22ED51 01091 ld (ptr),hl ;Start with this line
01092
3643 ED5BED51 01093 ld de,(ptr) ;Find out where we are
3647 2A1B52 01094 savlp2: ld hl,(end) ;Are we done?
364A B7 01095 or a
364B ED52 01096 sbc hl,de
364D 2827 01097 jr z,savend ;All done
01098
364F CD5439 01099 call getpos ;Get position
3652 EB 01100 ex de,hl ;HL has pointer to the text
3653 47 01101 ld b,a ;Get length
01102
3654 B7 01103 or a
3655 11F451 01104 ld de,fcb
3658 2809 01105 jr z,savnl ;Empty line
01106
365A 4E 01107 savlp1: ld c,(hl) ;Get a character
01108 ldos @put ;Write character
365E 2029 01109 jr nz,wpsav ;Write failed
3660 23 01110 inc hl
3661 10F7 01111 djnz savlp1 ;Loop
01112
3663 0E0D 01113 savnl: ld c,0dh ;End line
01114 ldos @put ;Terminate line
3668 C28936 01115 jp nz,wpsav ;Write failed
01116
366B ED5BED51 01117 ld de,(ptr) ;Get line number
366F 13 01118 inc de
3670 ED53ED51 01119 ld (ptr),de ;Save it
3674 18D1 01120 jr savlp2
3676 11F451 01122 savend: ld de,fcb
01123 ldos @close ;Close the file
367C 2004 01124 jr nz,savq
367E AF 01125 xor a
367F 321952 01126 ld (fmod),a ;A copy now exists on disk.
3682 2AF051 01127 savq: ld hl,(tmpcur)
3685 22ED51 01128 ld (ptr),hl ;Put cursor back
3688 C9 01129 ret ;All done, good or bad
01130
3689 F5 01131 wpsav: push af ;Save error
368A 11F451 01132 ld de,fcb
01133 ldos @close ;Try to close this file
3690 F1 01134 pop af
3691 18EF 01135 jr savq ;Return NZ
01136
01137
01138 ;-----------------------------------------------------------------------------
01139 ; Move cursor to adjacent tab stops
01140 ;-----------------------------------------------------------------------------
01141
3693 3A1552 01142 rtab: ld a,(col) ;<2>Get column
3696 FE48 01143 cp 72 ;<2>Too far over?
3698 D27831 01144 jp nc,newchar ;<2>Ignore command
369B E6F8 01145 and 0f8h
369D C608 01146 add a,8 ;<2>Advance to next tab stop
369F 321552 01147 tabc: ld (col),a ;<2>Save new position
36A2 CD493A 01148 call updlin ;<2>Update line
36A5 C37831 01149 jp newchar ;<2>All done
01150
01151
36A8 211552 01152 ltab: ld hl,col ;<2>
36AB 7E 01153 ld a,(hl) ;<2>
36AC FE08 01154 cp 8 ;<2>Are we too close to the left?
36AE DA5F33 01155 jp c,goeast ;<2>Pretend it was a
36B1 E6F8 01156 and 0f8h
36B3 BE 01157 cp (hl) ;<2>Did that may any effect?
36B4 20E9 01158 jr nz,tabc ;<2>Then use it
36B6 D608 01159 sub 8 ;<2>Adjust position by 8
36B8 18E5 01160 jr tabc ;<2>Handle common
01162 ;-----------------------------------------------------------------------------
01163 ; Move or Copy Lines from one place to another
01164 ;
01165 ; Copies and moves are handled in a state machine fashion.
01166 ; [CLEAR][4] is used to start marking. The area is marked by moving
01167 ; the arrow keys, then [CLEAR][6] or [CLEAR][7] is used to mark the
01168 ; end of the marked region. The cursor is now moved to the destination
01169 ; of the copy/move. Now [CLEAR][6] is pressed to Move or [CLEAR][7]
01170 ; is pressed to Copy. Pressing other command keys aborts the process,
01171 ; except for delete, which will happily delete the marked region.
01172 ;
01173 ;<4> This entire function was added in Edit 4.
01174 ;-----------------------------------------------------------------------------
01175
36BA 321A52 01176 movcpy: ld (cmdwas),a ;Save command type for later
36BD 3AF441 01177 ld a,(status)
36C0 FE02 01178 cp marklin ;See if they have been marking
36C2 280D 01179 jr z,move1 ;Yes
36C4 FE04 01180 cp position ;Is this the confirmation?
36C6 281D 01181 jr z,move2
01182
01183 ; Not in right mode, display an error, and exit
01184
36C8 21CA3F 01185 ld hl,nomrk ;No block marked
36CB CDFE3A 01186 call doerror ;Display it
36CE C37831 01187 jp newchar
01188
01189 ; Ok, enter position mode
01190
36D1 3E04 01191 move1: ld a,position ;Position mode
36D3 32F441 01192 ld (status),a
36D6 CDBF3A 01193 call fixstat ;
36D9 CD4D3B 01194 call fixscr
36DC 2AED51 01195 ld hl,(ptr) ;Get where we are
36DF 22F051 01196 ld (tmpcur),hl ;Save other end of marked region
36E2 C37831 01197 jp newchar ;Do next character
01198
01199 ; Ok, do the deed and figure out what the marked range is
01200
36E5 2A2152 01201 move2: ld hl,(emark)
36E8 ED5B1F52 01202 ld de,(mark)
36EC B7 01203 or a
36ED ED52 01204 sbc hl,de
36EF 300C 01205 jr nc,move3 ;HL = Length -1
36F1 2A2152 01206 ld hl,(emark)
36F4 221F52 01207 ld (mark),hl
36F7 ED532152 01208 ld (emark),de
36FB 18E8 01209 jr move2 ;Do math again
01211 ; Now, determine if the destination is sane. Moves into the marked
01212 ; region are not allowed. emark should be the highest address
01213 ; while mark is the lowest.
01214
36FD 2A1B52 01215 move3: ld hl,(end)
3700 ED5B2152 01216 ld de,(emark)
3704 B7 01217 or a
3705 ED52 01218 sbc hl,de ;See if range includes "END"
3707 2005 01219 jr nz,move31
3709 1B 01220 dec de
370A ED532152 01221 ld (emark),de ;Adjust size of range a bit
01222
370E ED5B1F52 01223 move31: ld de,(mark)
3712 2AED51 01224 ld hl,(ptr)
3715 B7 01225 or a
3716 ED52 01226 sbc hl,de
3718 0601 01227 ld b,1
371A 381B 01228 jr c,move5 ;Before block - ok
371C 2A2152 01229 ld hl,(emark)
371F ED5BED51 01230 ld de,(ptr)
3723 B7 01231 or a
3724 ED52 01232 sbc hl,de
3726 0600 01233 ld b,0
3728 380D 01234 jr c,move5 ;After block
372A 212F40 01235 ld hl,badrge
372D CDFE3A 01236 call doerror
3730 AF 01237 xor a
3731 32F441 01238 ld (status),a ;Set status but leave msg on screen
3734 C37831 01239 jp newchar
01240
01241 ; Here we have found nothing wrong with the range or destination, so
01242 ; actually do the move. The move is actually done one line at a time
01243 ; to allow the existing insert/delete routes to be used.
01244 ; B = direction of the transfer =1 lower, use lddr, =0 above, use ldir
01245 ; IX = length of the transfer
01246
3737 C5 01247 move5: push bc
3738 CD0A39 01248 call leave
373B C1 01249 pop bc
373C 3A1A52 01250 ld a,(cmdwas) ;What is it, copy or move?
373F FEB7 01251 cp 183 ;Copy?
3741 CA0138 01252 jp z,docopy ;Then copy!
3744 78 01253 ld a,b
3745 FE01 01254 cp 1 ;Which mode do we use?
3747 2837 01255 jr z,move6 ;lddr
01257 ; Here we are moving lines higher than they were
01258
3749 2AED51 01259 ld hl,(ptr)
374C 2B 01260 dec hl
374D ED5B1F52 01261 ld de,(mark)
3751 CDF737 01262 call movelen ;LDIR Length comes back in BC
3754 2A2152 01263 ld hl,(emark)
3757 ED5B1F52 01264 ld de,(mark)
375B B7 01265 or a
375C ED52 01266 sbc hl,de ;Number of loops through process
375E 23 01267 inc hl
375F E5 01268 movilp: push hl
3760 C5 01269 push bc
3761 2A1F52 01270 ld hl,(mark) ;Figure position in
3764 CD6139 01271 call getptr ;Table pointer in HL
3767 CDCB37 01272 call savtbl ;Save current entry at HL
376A 54 01273 ld d,h
376B 5D 01274 ld e,l
376C 23 01275 inc hl ;Increment by table entry size
376D 23 01276 inc hl
376E 23 01277 inc hl
376F 23 01279 inc hl ;<4>
3770 EDB0 01281 ldir
3772 62 01282 ld h,d
3773 6B 01283 ld l,e
3774 CDE137 01284 call restbl
3777 C1 01285 pop bc
3778 E1 01286 pop hl
3779 2B 01287 dec hl
377A 7C 01288 ld a,h
377B B5 01289 or l
377C 20E1 01290 jr nz,movilp
377E 1833 01291 jr movdone
01293 ; Here we move lines lower than they were
01294
3780 2A2152 01295 move6: ld hl,(emark)
3783 ED5BED51 01296 ld de,(ptr)
3787 CDF737 01297 call movelen ;LDDR Length comes back in BC
378A 2A2152 01298 ld hl,(emark)
378D ED5B1F52 01299 ld de,(mark)
3791 B7 01300 or a
3792 ED52 01301 sbc hl,de ;Number of loops through process
3794 23 01302 inc hl
3795 E5 01303 movdlp: push hl
3796 C5 01304 push bc
3797 2A2152 01305 ld hl,(emark) ;Figure position in
379A CD6139 01306 call getptr ;Table pointer in HL
379D CDCB37 01307 call savtbl ;Save current entry at HL
37A0 54 01308 ld d,h
37A1 5D 01309 ld e,l
37A2 13 01310 inc de
37A3 13 01311 inc de
37A4 13 01313 inc de ;Point at last byte of entry
37A5 2B 01315 dec hl ;Point at last byte of prev entry
37A6 EDB8 01316 lddr
37A8 23 01317 inc hl
37A9 CDE137 01318 call restbl
37AC C1 01319 pop bc
37AD E1 01320 pop hl
37AE 2B 01321 dec hl
37AF 7C 01322 ld a,h
37B0 B5 01323 or l
37B1 20E2 01324 jr nz,movdlp
01325
01326 ; Move complete, clean up.
01327
37B3 3E01 01328 movdone:ld a,1
37B5 321952 01329 ld (fmod),a ;Mark the file as modified
37B8 AF 01330 xor a
37B9 32F441 01331 ld (status),a ;Put things back to normal
37BC CDBF3A 01332 call fixstat
37BF CD4D3B 01333 call fixscr
37C2 CDD438 01334 call load
37C5 CD493A 01335 call updlin
37C8 C37831 01336 jp newchar
37CB E5 01338 savtbl: push hl
37CC 7E 01339 ld a,(hl)
37CD 329A51 01340 ld (temp),a
37D0 23 01341 inc hl
37D1 7E 01342 ld a,(hl)
37D2 329B51 01343 ld (temp+1),a
37D5 23 01344 inc hl
37D6 7E 01345 ld a,(hl)
37D7 329C51 01346 ld (temp+2),a
37DA 23 01348 inc hl
37DB 7E 01349 ld a,(hl)
37DC 329D51 01350 ld (temp+3),a
37DF E1 01352 pop hl
37E0 C9 01353 ret
01354
37E1 E5 01355 restbl: push hl
37E2 3A9A51 01356 ld a,(temp)
37E5 77 01357 ld (hl),a
37E6 23 01358 inc hl
37E7 3A9B51 01359 ld a,(temp+1)
37EA 77 01360 ld (hl),a
37EB 23 01361 inc hl
37EC 3A9C51 01362 ld a,(temp+2)
37EF 77 01363 ld (hl),a
37F0 23 01365 inc hl
37F1 3A9D51 01366 ld a,(temp+3)
37F4 77 01367 ld (hl),a
37F5 E1 01369 pop hl
37F6 C9 01370 ret
01371
01372 ; This routine figures out the size of the shift that must occur
01373 ; in the pointer table for a move or copy.
01374
37F7 B7 01375 movelen:or a
37F8 ED52 01376 sbc hl,de
37FA 44 01377 ld b,h ;This is length of transfer
37FB 4D 01378 ld c,l
37FC 29 01379 add hl,hl ;x2
37FD 29 01381 add hl,hl ;x4 if table size is 4 bytes
37FE 44 01385 ld b,h
37FF 4D 01386 ld c,l ;Actual number of bytes to xfer
3800 C9 01387 ret
01389 ;-----------------------------------------------------------------------------
01390 ; Before copying, make sure we have enough free memory to do this.
01391 ; Under no circumstances do you want to run out of memory while
01392 ; the copy is being performed. Cleaning up would be hard.
01393 ; To determine the amount of needed RAM, we add up the length of
01394 ; the lines to be copied to check free memory region. We also make
01395 ; sure that the line pointer table has room for N additional lines.
01396 ; B = direction of the copy, which we will need later.
01397 ;-----------------------------------------------------------------------------
01398
3801 C5 01399 docopy: push bc ;Save direction
3802 2A2152 01400 ld hl,(emark)
3805 ED5B1F52 01401 ld de,(mark)
3809 B7 01402 or a
380A ED52 01403 sbc hl,de ;Number of loops through process
380C 23 01404 inc hl
380D E5 01405 push hl
380E DDE1 01406 pop ix ;Will refer to this later on
3810 44 01407 ld b,h
3811 4D 01408 ld c,l ;Put xfer length here for now
3812 110000 01409 ld de,0
3815 2A1F52 01410 ld hl,(mark) ;Start of region to copy
3818 C5 01411 cpycnt: push bc
3819 D5 01412 push de ;Save count of bytes
381A E5 01413 push hl
381B CD5439 01414 call getpos
381E D1 01415 pop de ;Get line pointer back
381F E1 01416 pop hl ;Get count of bytes
3820 0600 01417 ld b,0
3822 4F 01418 ld c,a
3823 09 01419 add hl,bc ;Add length
3824 EB 01420 ex de,hl ;Move pointer to HL/count back to DE
3825 23 01421 inc hl ;Bump to next line
3826 C1 01422 pop bc
3827 0B 01423 dec bc
3828 78 01424 ld a,b
3829 B1 01425 or c
382A 20EC 01426 jr nz,cpycnt ;Keep counting
01427
01428 ; Now figure out how much free memory there is
01429
382C 2A1652 01430 ld hl,(bufsiz) ;End of memory
382F ED4B9851 01431 ld bc,(freptr) ;Start of free memory
3833 B7 01432 or a
3834 ED42 01433 sbc hl,bc ;HL amount of free memory left
3836 B7 01434 or a
3837 ED52 01435 sbc hl,de ;Subtract amount needed
3839 300E 01436 jr nc,cpymem1 ;Memory OK
01438 ; Oops, not enough free memory, stop now.
01439
383B C1 01440 cpymem2:pop bc ;Balance stack
383C 21EC3F 01441 ld hl,stout ;Say we can't do this - no more memory
383F CDFE3A 01442 call doerror
3842 AF 01443 xor a
3843 32F441 01444 ld (status),a ;Set status but leave msg on screen
3846 C37831 01445 jp newchar
01446
01447
3849 DDE5 01448 cpymem1:push ix
384B C1 01449 pop bc ;Get line count again
384C 21E803 01450 ld hl,maxlin ;Max line count
384F ED5B1B52 01451 ld de,(end) ;Pointer to last line slot used
3853 13 01452 inc de
3854 B7 01453 or a
3855 ED52 01454 sbc hl,de ;Number of slots left
3857 B7 01455 or a
3858 ED42 01456 sbc hl,bc ;Enough slots available?
385A 38DF 01457 jr c,cpymem2 ;Nope, bail out
01458
01459 ; Okay, we have all the memory we need, so do the copy.
01460 ; To keep the math from getting too complex, all new lines are
01461 ; created first, then the code goes back and fills in the data.
01462 ; Otherwise, source and destination would have to be re-computed
01463 ; for each transfer if destination is lower in file than the
01464 ; source.
01465
385C C5 01466 cpy3: push bc
385D CD6839 01467 call newlin ;Get a new line created
3860 C1 01468 pop bc
3861 0B 01469 dec bc ;Decrement count of lines to add
3862 78 01470 ld a,b
3863 B1 01471 or c
3864 20F6 01472 jr nz,cpy3 ;More lines needed
01473
01474 ; All the lines now exist, starting at the old "ptr" location.
01475 ; Now, go populate them.
01476
3866 3E01 01477 ld a,1
3868 321852 01478 ld (mod),a ;Tricks leave into working for us
386B C1 01479 pop bc ;Direction of transfer in B
386C 78 01480 ld a,b
386D DDE5 01481 push ix
386F C1 01482 pop bc ;Get back count of lines to copy
3870 2A1F52 01483 ld hl,(mark)
3873 B7 01484 or a
3874 2801 01485 jr z,cpy4 ;Copy to dest higher than source
01487 ; Here the destination is lower than the source, which means the
01488 ; location of the source is now out of place by the number of lines
01489 ; to be copied. Adjust that value.
01490
3876 09 01491 add hl,bc ;Fudge by amount inserted
01492
3877 E5 01493 cpy4: push hl ;Save pointer to block to copy (mark)
3878 C5 01494 push bc ;Save counter
3879 CD5739 01495 call getx ;Get pointer to line text and length
387C EB 01496 ex de,hl ;Put buffer ptr in hl
387D 119A51 01497 ld de,temp
3880 4F 01498 ld c,a
3881 32EC51 01499 ld (tmpsiz),a ;Length of the line (used by leave)
3884 0600 01500 ld b,0
3886 EDB0 01501 ldir ;Copy data
3888 CD0A39 01502 call leave ;Allocate memory and store line
388B 2AED51 01503 ld hl,(ptr)
388E 23 01504 inc hl
388F 22ED51 01505 ld (ptr),hl
3892 C1 01506 pop bc
3893 E1 01507 pop hl
3894 23 01508 inc hl ;Bump to next source line (mark++)
3895 0B 01509 dec bc
3896 78 01510 ld a,b
3897 B1 01511 or c
3898 20DD 01512 jr nz,cpy4 ;Do next line
389A C3B337 01513 jp movdone ;All done, update display
01514
01515
01516 ;END OF QEDCMD/SRC
01517
01518
01519 ; Include memory management and screen-drawing primitives.
01522 ; QED Quick EDitor - by Frank Durda IV
01523 ; Memory management and screen-drawing routines
01524 ; This file is included by QED/SRC
01525 ; Copyright 1985 and 1999, All Rights Reserved.
01526
01527 ;----------------------------------------------------------------------------
01528 ; Notes on QED memory management
01529
01530 ; Memory is managed as a vector of pointers into memory
01531 ; that are linked by position in the table.
01532
01533 ; address,length starting address of line 1, & length
01534 ; address,length starting address of line 2, & length
01535 ; ...
01536
01537 ; When a line is initially created, it is kept in a temporary line
01538 ; buffer. Once is pressed, an official line is created
01539 ; and storage is allocated.
01540 ; When a line is modified, it is moved into the temporary buffer.
01541 ; When you leave the line, the modified lines' length is checked.
01542 ; If the line will still fit in the old buffer, the old buffer
01543 ; is updated, and it's length is reset.
01544 ; If the line is longer and won't fit, the old line is released and
01545 ; a new line is allocated.
01546
01547 ; The allocator is called with a length and returns an address
01548 ; to the memory that has been set aside for this line.
01549 ; If there is insufficient space, the garbage collector is
01550 ; called and it reshuffles all of memory, squeezing unused areas
01551 ; to the end of the storage buffer, then tries to fit the new line.
01552 ; If it still won't fit, it returns an error.
01553 ;-----------------------------------------------------------------------------
01555 ;----------------------------------------------------------------------------
01556 ; Allocate a new line buffer
01557 ; Accepts
01558 ; C = Size of buffer
01559
01560 ; Returns
01561 ; Success, Z Flag Set
01562 ; DE = Pointer to allocated buffer
01563
01564 ; Failure, NZ Flag Set - No more memory available
01565 ;----------------------------------------------------------------------------
01566
389D ED5B9851 01567 getbuf: ld de,(freptr) ;Get start of free memory
38A1 2600 01568 ld h,0
38A3 69 01569 ld l,c ;Extend size request
38A4 19 01570 add hl,de ;Get new free pointer
38A5 D5 01571 push de ;Save base pointer
01572
38A6 EB 01573 ex de,hl ;Put new pointer in DE
38A7 2A1652 01574 ld hl,(bufsiz) ;Get top of buffer
38AA B7 01575 or a
38AB ED52 01576 sbc hl,de ;See if this new line will fit
38AD EB 01577 ex de,hl ;Put new pointer back in HL
38AE D1 01578 pop de ;Get line pointer back
38AF 3805 01579 jr c,gctime ;Not enough memory, do garbage
01580
38B1 229851 01581 ld (freptr),hl ;Store updated free pointer
38B4 BF 01582 cp a ;Set Z flag
38B5 C9 01583 ret ;Exit
01584
38B6 C5 01585 gctime: push bc ;Save original request
38B7 CDD338 01586 call gcmem ;Run Garbage Collector
38BA C1 01587 pop bc
38BB ED5B9851 01588 ld de,(freptr) ;See if we have it now
38BF 2600 01589 ld h,0
38C1 69 01590 ld l,c ;Extend size request
38C2 19 01591 add hl,de ;Get new free pointer
38C3 D5 01592 push de ;Save original pointer
38C4 EB 01593 ex de,hl
38C5 2A1652 01594 ld hl,(bufsiz) ;Test upper limit
38C8 B7 01595 or a
38C9 ED52 01596 sbc hl,de
38CB EB 01597 ex de,hl
38CC D1 01598 pop de
38CD D8 01599 ret c ;No space still
38CE 229851 01600 ld (freptr),hl ;Store updated free pointer
38D1 BF 01601 cp a ;Set Z flag
38D2 C9 01602 ret ;Exit
01604 ;-----------------------------------------------------------------------------
01605 ; Garbage Collector
01606 ; As you may have noticed, the garbage collector for discarded memory
01607 ; was never written. Because all of the assignments in an introduction
01608 ; to 8080/8085 assembly language course are small, it was unlikely that
01609 ; any of the intended users would ever reach this point, and no cases
01610 ; were reported. However, if this editor is to find serious use with
01611 ; larger files, this routine definitely needs to be written. Right now
01612 ; calling routines see no effect, as if there was no memory to reclaim.
01613 ;-----------------------------------------------------------------------------
01614
38D3 C9 01615 gcmem: ret
01617 ;-----------------------------------------------------------------------------
01618 ; Load a line into the work buffer
01619 ;-----------------------------------------------------------------------------
01620
38D4 119B51 01621 load: ld de,temp+1 ;Flush buffer
38D7 219A51 01622 ld hl,temp
38DA 3620 01623 ld (hl),' ' ;Clear byte
38DC 015000 01624 ld bc,80 ;Do this much
38DF EDB0 01625 ldir ;Clear it out
01626
38E1 CD5439 01627 call getpos ;Find the line
38E4 E5 01628 push hl
38E5 D5 01629 push de
38E6 2A1B52 01630 ld hl,(end) ;See if this is the end
38E9 ED5BED51 01631 ld de,(ptr) ;Where we are
38ED B7 01632 or a
38EE ED52 01633 sbc hl,de
38F0 D1 01634 pop de
38F1 E1 01635 pop hl ;Put things back
38F2 2002 01636 jr nz,loadok ;Not end
38F4 AF 01637 xor a ;Clear length
38F5 77 01638 ld (hl),a ;Zero length of END line
01639
38F6 32EC51 01640 loadok: ld (tmpsiz),a ;Store length
38F9 B7 01641 or a ;Is the line empty?
38FA 2809 01642 jr z,ld1 ;Nothing to move
01643
38FC 4F 01644 ld c,a ;Extend
38FD 0600 01645 ld b,0
38FF EB 01646 ex de,hl ;Put line in HL
3900 119A51 01647 ld de,temp ;Point at target
3903 EDB0 01648 ldir ;Transfer line
01649
3905 AF 01650 ld1: xor a ;Set no modification
3906 321852 01651 ld (mod),a ;Do it
3909 C9 01652 ret ;All done, exit
01654 ;-----------------------------------------------------------------------------
01655 ; Unload a line in the work buffer and store it in the chain
01656 ;-----------------------------------------------------------------------------
01657
390A 3A1852 01658 leave: ld a,(mod) ;Get the mod flag
390D B7 01659 or a ;Did we change anything?
390E C8 01660 ret z ;Then the chain-copy is correct
01661
390F CD5439 01662 call getpos ;Locate chain pointers
3912 E5 01663 push hl ;Find out where we are first
3913 D5 01664 push de
3914 2A1B52 01665 ld hl,(end)
3917 ED5BED51 01666 ld de,(ptr)
391B B7 01667 or a
391C ED52 01668 sbc hl,de
391E D1 01669 pop de
391F E1 01670 pop hl
3920 200B 01671 jr nz,leaveok ;Line is ok
01672
3922 F5 01673 push af
01674 ; ld a,(tmpsiz) ;See if we added anything
01675 ; or a
01676 ; jr z,noadd
3923 E5 01677 push hl
3924 2A1B52 01678 ld hl,(end) ;Add a new line
3927 23 01679 inc hl
3928 221B52 01680 ld (end),hl ;by advancing the END
392B E1 01681 pop hl
392C F1 - 01682 noadd: pop af
01683
392D E5 01684 leaveok:push hl
392E 21EC51 01685 ld hl,tmpsiz ;Point at new length
3931 4E 01686 ld c,(hl) ;Get it
3932 E1 01687 pop hl
3933 B9 01688 cp c ;Is new line shorter or the same?
3934 380C 01689 jr c,nofit ;Line got larger
01690
01691 ; Line is smaller or the same size
01692
3936 71 01693 ld (hl),c ;Set new line length
3937 79 01694 ld a,c
3938 B7 01695 or a
3939 C8 01696 ret z ;Line length is now zero, all done
01697
393A 0600 01698 leacom: ld b,0 ;Extend
393C 219A51 01699 ld hl,temp ;Point at source
393F EDB0 01700 ldir ;Store updated line
3941 C9 01701 ret ;All done, exit
3942 E5 01703 nofit: push hl
3943 CD9D38 01704 call getbuf ;Allocate a buffer
3946 E1 01705 pop hl
01706
3947 71 01707 ld (hl),c ;Store new line length
3948 2B 01708 dec hl
3949 3600 01710 ld (hl),0 ;<4>In-core is always zero
394B 2B 01711 dec hl ;<4>
394C 72 01713 ld (hl),d ;Store address
394D 2B 01714 dec hl
394E 73 01715 ld (hl),e ;Rest of address
01716
394F 79 01717 ld a,c ;Get length
3950 B7 01718 or a
3951 20E7 01719 jr nz,leacom ;Line has length, copy it in
01720
01721 ; What? allocate ran for a zero length line???????
01722
3953 C9 01723 ret
01725 ;-----------------------------------------------------------------------------
01726 ; Locate a line in the chain - translates line # into table offset
01727 ;-----------------------------------------------------------------------------
01728
3954 2AED51 01729 getpos: ld hl,(ptr) ;Get the pointer
3957 CD6139 01730 getx: call getptr
395A 5E 01731 ld e,(hl) ;Get LSB
395B 23 01732 inc hl
395C 56 01733 ld d,(hl) ;Get MSB
395D 23 01734 inc hl
395E 23 01736 inc hl ;<4>Skip over file offset byte
395F 7E 01738 ld a,(hl) ;Get length
3960 C9 01739 ret ;All done, exit
01740
3961 01741 getptr:
3961 29 01743 add hl,hl ;<4>x2
3962 29 01744 add hl,hl ;<4>x4
3963 11F841 01751 ld de,linetbl ;Point at start of the table
3966 19 01752 add hl,de ;Insert base
3967 C9 01753 ret
01754
01755
01756 ;-----------------------------------------------------------------------------
01757 ; Add a new line to the file at the point specified by ptr
01758 ;-----------------------------------------------------------------------------
01759
3968 2A1B52 01760 newlin: ld hl,(end) ;Get current end of file
396B ED5BED51 01761 ld de,(ptr) ;Get current position
396F B7 01762 or a
3970 ED52 01763 sbc hl,de
3972 29 01765 add hl,hl ;<4>x2
3973 29 01766 add hl,hl ;<4>x4
3974 4D 01773 ld c,l
3975 44 01774 ld b,h ;Save count
01775
3976 2A1B52 01776 ld hl,(end)
3979 CD5739 01777 call getx ;Get position
397C 5D 01778 ld e,l
397D 54 01779 ld d,h
397E 13 01780 inc de
397F 2B 01781 dec hl
3980 2B 01782 dec hl
3981 2B 01784 dec hl ;<4>
3982 03 01786 inc bc
3983 EDB8 01787 lddr
3985 CD5439 01788 call getpos ;Init new line
3988 3600 01789 ld (hl),0 ;Set zero length
01790
398A 2A1B52 01791 ld hl,(end) ;Increment line count
398D 23 01792 inc hl
398E 221B52 01793 ld (end),hl ;Ok
3991 3E01 01794 ld a,1
3993 321952 01795 ld (fmod),a ;Mark file as modified
3996 C9 01796 ret ;All done
01798 ;-----------------------------------------------------------------------------
01799 ; Delete one or more lines from the file
01800 ;-----------------------------------------------------------------------------
01801
3997 CD0A39 01802 dlines: call leave ;Unload anything
399A 3AF441 01803 ld a,(status) ;Get the mode
399D FE02 01804 cp marklin ;Are we marking?
399F 2815 01805 jr z,dlmark ;Handle block
01806
01807 ; Delete a single line
01808
39A1 2AED51 01809 dlx1: ld hl,(ptr)
39A4 ED5B1B52 01810 ld de,(end)
39A8 B7 01811 or a
39A9 ED52 01812 sbc hl,de
39AB CA7831 01813 jp z,newchar ;Can't delete the END line
01814
39AE 210100 01815 ld hl,1 ;Delete one
39B1 222152 01816 ld (emark),hl ;Save count
39B4 1835 01817 jr dodelc ;Delete but check
01818
01819 ; Handle a block to be deleted
01820
39B6 2A1B52 01821 dlmark: ld hl,(end)
39B9 ED5BED51 01822 ld de,(ptr)
39BD B7 01823 or a
39BE ED52 01824 sbc hl,de
39C0 2005 01825 jr nz,dlm4
39C2 1B 01826 dec de
39C3 ED53ED51 01827 ld (ptr),de ;Back up one column
01828
39C7 2A1F52 01829 dlm4: ld hl,(mark) ;Get one end of mark
39CA 23 01830 inc hl
39CB ED5BED51 01831 ld de,(ptr) ;Get the other
39CF B7 01832 or a
39D0 ED52 01833 sbc hl,de ;See if the order is right
39D2 28CD 01834 jr z,dlx1 ;Do single line
39D4 3805 01835 jr c,dlx2 ;Reverse ends
39D6 222152 01836 ld (emark),hl ;Save length
39D9 1810 01837 jr dodelc ;Ptr is starting point
01838
39DB EB 01839 dlx2: ex de,hl ;Put ptr in HL
01840 ; ld (ptr),hl ;save starting point
39DC 23 01841 inc hl ;Adjust
39DD ED5B1F52 01842 ld de,(mark) ;Get other end
39E1 ED53ED51 01843 ld (ptr),de ;Store this value
39E5 B7 01844 or a
39E6 ED52 01845 sbc hl,de ;Get length
39E8 222152 01846 ld (emark),hl ;Save length
01848 ; Before doing this, check our position
01849
39EB ED5BED51 01850 dodelc: ld de,(ptr) ;Get position
39EF 19 01851 add hl,de ;Add count (emark)
39F0 ED5B1B52 01852 ld de,(end)
39F4 B7 01853 or a
39F5 ED52 01854 sbc hl,de ;Is this delete at the end?
39F7 302B 01855 jr nc,dfixe ;Just move END
39F9 2A1B52 01856 ld hl,(end) ;Get end
39FC ED5BED51 01857 ld de,(ptr)
3A00 B7 01858 or a
3A01 ED52 01859 sbc hl,de ;Get number lines below here
01860
3A03 ED5B2152 01861 ld de,(emark) ;Get length
3A07 ED52 01862 sbc hl,de ;Subtract amount we will delete
01863
3A09 29 01865 add hl,hl ;<4>x2
3A0A 29 01866 add hl,hl ;<4>x4
3A0B 4D 01873 ld c,l
3A0C 44 01874 ld b,h ;Save count
3A0D C5 01875 push bc
3A0E CD5439 01876 call getpos ;Get ptr position
3A11 C1 01877 pop bc
3A12 2B 01878 dec hl
3A13 2B 01879 dec hl
3A14 2B 01881 dec hl ;<4>
3A15 54 01883 ld