; EDFIL.MAC - 3/7/86 - Edit a file. .z80 maclib TNC.LIB entry edfil external fcb2,cmd,getcmd,cmdlen,ucase external @openr,@openw,@closew,fmbuf,tobuf external memtop,$memry,@outch,@prtx,rfcb,wfcb external conin,ercant,erfind,erdone asciictl tncdefs bdosdef scnsiz equ 24 ; # lines on screen pagsiz equ 16 ; # lines for "page moves" bias equ 32 ; Bias for row/column numbers ; Edit a file . dseg edchg: ds 1 ; Set true if any change made doit: ds 1 tfcb: ds fcbsize newptr: ds 2 count: ds 2 filtop: ds 2 ; Address of start of file in memory filbot: ds 2 ; Address of end of file in memory wintop: ds 2 ; Address of start of first line on screen filptr: ds 2 ; Address of start of current line poscur: db esc,'=' row: db bias col: db bias,0 cseg ; Return (HL)=# bytes from current position to bottom of file. patbot: ld hl,(filbot) ld de,(filptr) or a sbc hl,de ret ; Return (HL)=# bytes from current position to top of file. pattop: ld hl,(filptr) ld de,(filtop) or a sbc hl,de ret clrscn: ld c,ff jp @outch ; Clear the screen putl: ld e,80 ; Max char on line, +1 putla: inc hl ld a,(hl) ; Get char cp cr ; Is a CR? ret z ; Yes, done dec e ; Count char jr nz,putlb ; Not 79 yet, display it inc e jr putla putlb: ld c,a call @outch jr putla ; Re-paint the screen. paint: call clrscn ; Clear screen ld b,scnsiz ld hl,(wintop) ; Point to start of first line painta: push hl ld de,(filbot) or a sbc hl,de pop hl jr z,putcur ; No more lines call putl dec b ; Count the line jr z,putcur ; Screen is full ld c,cr call @outch ; CR to next line jr painta ; Clear screen, leave curson bottom left. clean: call clrscn ld a,scnsiz-1+bias ld (row),a ; Send the cursor position sequence to the screen. putcur: ld hl,poscur jp @prtx edfil: zmov tfcb,fcb2,fcbsize openr tfcb ; Open the file jp z,erfind ; Not found mvim edchg,false ld a,bias ld (row),a ld (col),a ld hl,($memry) ld (hl),cr ; Mark start of first line ld (filtop),hl ld (filbot),hl ld (wintop),hl ld (filptr),hl ld de,(memtop) ; Last address available or a sbc hl,de ld (count),hl ; Size of free memory edfila: call fmbuf ; Get byte from file jr z,edfilb ; Read the whole file ld a,c cp lf jr z,edfila cp eof jr z,edfilb inxm filbot ld (hl),a ; Put in buffer dcxm count ld a,l or h jr nz,edfila jp ercant ; File not fit in memory edfilb: ld hl,(filbot) ld a,(hl) cp cr ; Was there CR on last line? jr z,edfilc ; Yes dcxm count ld a,l or h ; Room for CR? jp z,ercant ; No inxm filbot ld (hl),cr edfilc: call paint ; Put 24 lines on screen edfild: call conin ; Get command call ucase ld hl,edfild push hl cp 'A' jr z,pagup cp 'S' jp z,linup cp 'D' jp z,lindn cp 'F' jr z,pagdn cp 'I' jp z,ins cp 'K' jr z,kill cp 'E' jp z,done cp 'Q' jp z,exit ret ; Down one page. pagdn: ld e,pagsiz pagdna: push de call lindn pop de dec e jr nz,pagdna ret ; Up one page. pagup: ld e,pagsiz mvim doit,false pagupa: push de call lup pop de dec e jr nz,pagupa cmpm doit,true call z,paint jp putcur lup: call pattop ret z ; At top of file ld hl,(filptr) call movup ; Move cursor up one line in file ld (filptr),hl ld a,(row) ; Cursor position sub bias jr z,lupa ; At top of screen dec a ; Move cursor up one line on screen add a,bias ld (row),a ; Into cursor position seq ret lupa: ld hl,(wintop) call movup ; Move window up one line ld (wintop),hl mvim doit,true ret ; Delete line. kill: call patbot ret z ; Past last line mvim edchg,true ld hl,(filptr) call movdn ; Move cursor down one line in file ld (newptr),hl ld de,(filbot) or a sbc hl,de jr nz,killa ; Not last line movw filbot,filptr call movup ld (filptr),hl ld hl,(wintop) ld de,(filtop) or a sbc hl,de jp z,paint ; Window was at top ld hl,(wintop) call movup ld (wintop),hl jp paint killa: ld hl,(filbot) ld de,(newptr) or a sbc hl,de push hl pop bc ld hl,(newptr) inc hl ld de,(filptr) inc de ldir ld hl,(newptr) ld de,(filptr) or a sbc hl,de ex de,hl ld hl,(filbot) or a sbc hl,de ld (filbot),hl jp paint ins: call getcmd ld a,(cmdlen) ; Length of string to insert inc a ; Add one for CR ld l,a ld h,0 ld (count),hl ; Save length ld de,(filbot) add hl,de ld (newptr),hl ; New end of file ld de,(memtop) or a sbc hl,de jp nc,ercant ; Tell no room mvim edchg,true call patbot jr z,insb ; Were at bottom push hl pop bc ld hl,(filbot) ld de,(newptr) lddr ; Move everything down insb: movw filbot,newptr ld de,(filptr) inc de ld bc,(count) dec bc ld a,c or b ; Count is zero? jr z,insc ; Yes, nothing to move ld hl,cmd ldir ; Move insert into place insc: ld a,cr ld (de),a ; Put CR at end of insert call lindn ; Move down a line jp paint ; Move a pointer up one line. movup: dec hl ld a,(hl) ; Get char cp cr ; Is end of line? jr nz,movup ; No, continue ret ; Move a pointer down one line. movdn: inc hl ld a,(hl) ; Get char cp cr ; Is end of line? jr nz,movdn ; No, continue ret ; Cursor down one line. lindn: call patbot ret z ; At bottom of file ld hl,(filptr) call movdn ; Move cursor down one line in file ld (filptr),hl ld a,(row) ; Cursor position sub bias cp scnsiz-1 jr z,lindna ; At bottom of screen inc a ; Move cursor down one line on screen add a,bias ld (row),a ; Into cursor position seq jp putcur lindna: ld hl,(wintop) call movdn ; Move window down one line ld (wintop),hl ld c,cr call @outch ; Scroll screen call patbot ret z ; After last line ld hl,(filptr) call putl ; Display the line jp putcur ; Cursor up one line. linup: call pattop ret z ; At top of file ld hl,(filptr) call movup ld (filptr),hl ld a,(row) ; Cursor position sub bias jr z,linupa ; At top of screen dec a ; Move it up add a,bias ld (row),a ; Into cursor position seq jp putcur linupa: ld hl,(wintop) call movup ld (wintop),hl jp paint ; Repaint screen exit: pop hl ; Clean stack call clean jp erdone done: pop hl ; Clean stack call clean cmpm edchg,false ret z openw tfcb ; Open the file jp z,ercant ld hl,(filbot) ld de,(filtop) or a sbc hl,de ld (count),hl donea: inxm filtop ld c,(hl) ; Get byte call tobuf jp z,ercant ld hl,(filtop) ld a,(hl) cp cr jr nz,doneb ld c,lf call tobuf jp z,ercant doneb: dcxm count ld a,l or h jr nz,donea donec: ld c,eof call tobuf closew jp erdone end