{ SEAN PALMER > Can anyone (please, it's important) , post here an example of a source > code that will show a Text File , and let me scroll it (Up , Down ) ? > Also I need an example of a simple editor. Try this For an example. Turbo Pascal 6.0+ source. Compiles to a 7K Text editor. Neat? } {$A-,B-,D-,E-,F-,G-,I-,L-,N-,O-,R-,S-,V-,X+} {$M $C00,0,0} Program ghostEd; {Ghost Editor v0.4 (C) 1993 Sean L. Palmer} Const version = '0.4'; maxF = $3FFF; {only handles small Files!} txtColor = $B; vSeg : Word = $B800; Var nLines : Byte; halfPage : Byte; txt : Array [0..maxF] of Char; crs, endF, pgBase, lnBase : Integer; x, y : Word; update : Boolean; theFile : File; ticks : Word Absolute $40 : $6C; {ticks happen 18.2 times/second} Procedure syncTick; Var i : Word; begin i := ticks; Repeat Until i <> ticks; end; Function readKey : Char; Assembler; Asm mov ah, $07 int $21 end; Function keyPressed : Boolean; Assembler; Asm mov ah, $B int $21 and al, $FE end; Procedure moveScrUp(s, d, n : Word); Assembler; Asm mov cx, n push ds mov ax, vSeg mov es, ax mov ds, ax mov si, s shl si, 1 mov di, d shl di, 1 cld repz movsw {attr too!} pop ds @X: end; Procedure moveScrDn(s, d, n : Word); Assembler; Asm mov cx, n push ds mov ax, vSeg mov es, ax mov ds, ax mov si, s add si, cx shl si, 1 mov di, d add di, cx shl di, 1 std repz movsw {attr too!} pop ds @X: end; Procedure moveScr(Var s; d, n : Word); Assembler; Asm mov cx, n jcxz @X push ds mov ax, vSeg mov es, ax mov di, d shl di, 1 lds si, s cld @L: movsb inc di loop @L pop ds @X: end; Procedure fillScr(d, n : Word; c : Char); Assembler; Asm mov cx, n jcxz @X mov ax, vSeg mov es, ax mov di, d shl di, 1 mov al, c cld @L: stosb inc di loop @L @X: end; Procedure fillAttr(d, n : Word; c : Byte); Assembler; Asm mov cx, n jcxz @X mov ax, vSeg mov es, ax mov di, d shl di, 1 mov al, c cld @L: inc di stosb loop @L @X: end; Procedure cls; begin fillAttr(80, pred(nLines) * 80, txtColor); fillScr(80, pred(nLines) * 80, ' '); end; Procedure scrollUp; begin moveScrUp(320, 160, pred(nLines) * 160); fillScr(pred(nLines) * 160, 80, ' '); end; Procedure scrollDn; begin moveScrDn(160, 320, pred(nLines) * 320); fillScr(160, 80, ' '); end; {put cursor after preceding CR or at 0} Function scanCrUp(i : Integer) : Integer; Assembler; Asm mov di, i mov cx, di add di, offset txt mov ax, ds mov es, ax std; mov al, $D dec di repnz scasb jnz @S inc di @S: inc di sub di, offset txt mov ax, di end; {put cursor on next CR or endF} Function scanCrDn(i:Integer):Integer;Assembler;Asm mov di, i mov cx, endF sub cx, di inc cx add di, offset txt mov ax, ds mov es, ax cld mov al, $D repnz scasb dec di sub di, offset txt mov ax, di end; Procedure findxy; begin lnBase := scanCrUp(crs); x := crs - lnBase; y := 1; pgBase := lnBase; While (pgBase > 0) and (y < halfPage) do begin pgBase := scanCrUp(pred(pgBase)); inc(y); end; end; Procedure display; Var i, j, k, oldY : Integer; begin findXY; if update then begin update := False; j := pgBase; i := 1; While (j <= endf) and (i < pred(nLines)) do begin k := scanCrDn(j); moveScr(txt[j], i * 80, k - j); fillScr(i * 80 + k - j, 80 - k + j, ' '); fillAttr(i * 80, 80, txtColor); j := succ(k); inc(i); end; if i < pred(nLines) then begin fillScr(i * 80, 80 * pred(nLines - i), 'X'); fillAttr(i * 80, 80 * pred(nLines - i), 1); end; end else begin i := scanCrDn(lnBase) - lnBase; moveScr(txt[lnBase], y * 80, i); fillScr(y * 80 + i, 80 - i, ' '); end; end; Procedure title; Const menuStr : String = 'Ghost Editor v' + version + '-(C) Sean Palmer 1993'; begin fillAttr(0, 80, $70); fillScr(0, 80, ' '); MoveScr(MenuStr[1], 1, length(MenuStr)); end; Procedure error(s : String); begin fillattr(0, 80, $CE); fillScr(0, 80, ' '); moveScr(s[1], 1, length(s)); Write(^G); ReadKey; title; end; Procedure tooBigErr; begin error('File too big'); end; Procedure insChar(c : Char); forward; Procedure delChar; forward; Procedure backChar; forward; Procedure trimLine; Var i, t, b : Integer; begin i := crs; b := scanCrDn(crs); t := scanCrUp(crs); crs := b; While txt[crs] = ' ' do begin delChar; if i > crs then dec(i); if crs > 0 then dec(crs); end; crs := i; end; Procedure checkWrap(c : Integer); Var i, t, b : Integer; begin b := scanCrDn(c); t := scanCrUp(c); i := b; if i - t >= 79 then begin i := t + 79; Repeat dec(i); Until (txt[i] = ' ') or (i = t); if i = t then backChar {just disallow lines that long With no spaces} else begin txt[i] := ^M; {change sp into cr, to wrap} update := True; if (b < endF) and (txt[b] = ^M) and (txt[succ(b)] <> ^M) then begin txt[b] := ' '; {change cr into sp, to append wrapped part to next line} checkWrap(b); {recursively check next line since it got stuff added} end; end; end; end; Procedure changeLines; begin trimLine; update := True; {signal to display to redraw} end; Procedure insChar(c : Char); begin if endf = maxF then begin tooBigErr; exit; end; move(txt[crs], txt[succ(crs)], endf - crs); txt[crs] := c; inc(crs); inc(endf); if c = ^M then changeLines; checkWrap(crs); end; Procedure delChar; begin if crs = endf then Exit; if txt[crs] = ^M then changeLines; move(txt[succ(crs)], txt[crs], endf - crs); dec(endf); checkWrap(crs); end; Procedure addLF; Var i : Integer; begin For crs := endF downto 1 do if txt[pred(crs)] = ^M then begin insChar(^J); dec(crs); end; end; Procedure stripLF; Var i : Integer; begin For crs := endF downto 0 do if txt[crs] = ^J then delChar; end; Procedure WriteErr; begin error('Write Error'); end; Procedure saveFile; begin addLF; reWrite(theFile, 1); if ioresult <> 0 then WriteErr else begin blockWrite(theFile, txt, endf); if ioresult <> 0 then WriteErr; close(theFile); end; end; Procedure newFile; begin crs := 0; endF := 0; update := True; end; Procedure readErr; begin error('Read Error'); end; Procedure loadFile; Var i, n : Integer; begin reset(theFile, 1); if ioresult <> 0 then newFile else begin n := Filesize(theFile); if n > maxF then begin tooBigErr; n := maxF; end; blockread(theFile, txt, n, i); if i < n then readErr; close(theFile); crs := 0; endf := i; update := True; stripLF; end; end; Procedure signOff; Var f : File; i, n : Integer; begin assign(f, 'signoff.txt'); reset(f, 1); if ioresult <> 0 then error('No SIGNOFF.TXT defined') {no macro defined} else begin n := Filesize(f); blockread(f, txt[endF], n, i); if i < n then readErr; close(f); inc(endf, i); update := True; i := crs; stripLF; crs := i; {stripLF messes With crs} end; end; Procedure goLf; begin if crs > 0 then dec(crs); if txt[crs] = ^M then changeLines; end; Procedure goRt; begin if txt[crs] = ^M then changeLines; if crs < endf then inc(crs); end; Procedure goCtrlLf; Var c : Char; begin Repeat goLf; c := txt[crs]; Until (c <= ' ') or (crs = 0); end; Procedure goCtrlRt; Var c : Char; begin Repeat goRt; c := txt[crs]; Until (c <= ' ') or (crs >= endF); end; Procedure goUp; Var i : Integer; begin if lnBase > 0 then begin changeLines; lnBase := scanCrUp(pred(lnBase)); crs := lnBase; i := scanCrDn(crs) - crs; if i >= x then inc(crs, x) else inc(crs,i); end; end; Procedure goDn; Var i : Integer; begin changeLines; crs := scanCrDn(crs); if crs >= endF then Exit; inc(crs); lnBase := crs; i := scanCrDn(crs) - crs; if i >= x then inc(crs, x) else inc(crs, i); end; Procedure goPgUp; Var i : Byte; begin For i := halfPage downto 0 do goUp; end; Procedure goPgDn; Var i : Byte; begin For i := halfPage downto 0 do goDn; end; Procedure goHome; begin crs := scanCrUp(crs); end; Procedure goend; begin crs := scanCrDn(crs); end; Procedure backChar; begin if (crs > 0) then begin goLf; delChar; end; end; Procedure deleteLine; Var i : Integer; begin i := scanCrDn(crs); crs := scanCrUp(crs); if i < endF then begin move(txt[succ(i)], txt[crs], endf - i); dec(endF); end; dec(endf, i - crs); changeLines; end; Procedure flipCursor; Var j, k, l : Word; begin j := succ((y * 80 + x) shl 1); l := mem[vSeg : j]; {save attr under cursor} mem[vSeg : j] := $7B; if not KeyPressed then syncTick; mem[vSeg : j] := l; if not KeyPressed then syncTick; end; Procedure edit; Var c : Char; begin Repeat display; Repeat flipcursor; Until KeyPressed; c := ReadKey; if c = #0 then Case ReadKey of #59 : signOff; #75 : goLf; #77 : goRt; #115 : goCtrlLf; #116 : goCtrlRt; #72 : goUp; #80 : goDn; #83 : delChar; #73 : goPgUp; #81 : goPgDn; #71 : goHome; #79 : goend; end else Case c of ^[ : saveFile; ^H : backChar; ^C : {abortFile}; ^Y : deleteLine; else insChar(c); end; Until (c = ^[) or (c = ^C); end; Function getRows : Byte; Assembler; Asm mov ax, $1130 xor dx, dx int $10 or dx, dx jnz @S mov dx, 24 @S: {cga/mda don't have this fn} inc dx mov al, dl end; Var oldMode : Byte; begin Asm mov ah, $F int $10 mov oldMode, al end; {save old Gr mode} if oldMode = 7 then vSeg := $B000; {check For Mono} nLines := getRows; halfPage := pred(nLines shr 1); cls; title; if paramCount = 0 then error('Need Filename as parameter') else begin Asm mov bh, 0 mov dl, 0 mov dh, nLines mov ah, 2 int $10 end; {put cursor of} assign(theFile, paramStr(1)); loadFile; edit; end; end.