From 673c74694c7f0c1d4a9a501058bd4a29593a8afd Mon Sep 17 00:00:00 2001 From: David Schmenk <dschmenk@gmail.com> Date: Tue, 18 Nov 2014 16:13:35 -0800 Subject: [PATCH] Port original PLASMA editor over --- src/makefile | 7 +- src/toolsrc/codegen.c | 11 +- src/toolsrc/ed.pla | 1503 +++++++++++++++++++++++++++++++++++++++++ src/toolsrc/lex.c | 2 +- 4 files changed, 1517 insertions(+), 6 deletions(-) create mode 100755 src/toolsrc/ed.pla diff --git a/src/makefile b/src/makefile index b8fbc84..f14c102 100644 --- a/src/makefile +++ b/src/makefile @@ -5,6 +5,7 @@ PLVM01 = A1PLASMA\#060280 PLVM02 = PLASMA.SYSTEM\#FF2000 PLVM03 = SOS.INTERP\#050000 CMD = CMD\#FF2000 +ED = ED\#FF2000 ROD = ROD\#FE1000 SIEVE = SIEVE\#FE1000 HELLO = HELLO\#FE1000 @@ -32,7 +33,7 @@ TXTTYPE = .TXT #SYSTYPE = \#FF2000 #TXTTYPE = \#040000 -all: $(PLASM) $(PLVM) $(PLVM01) $(PLVM02) $(PLVM03) $(CMD) $(PROFILE) $(ROD) $(SIEVE) $(HGR1) +all: $(PLASM) $(PLVM) $(PLVM01) $(PLVM02) $(PLVM03) $(CMD) $(PROFILE) $(ED) $(ROD) $(SIEVE) $(HGR1) clean: -rm *FE1000 *FF2000 $(PLASM) $(PLVM) $(PLVM01) $(PLVM02) $(PLVM03) @@ -81,6 +82,10 @@ test: samplesrc/test.pla samplesrc/testlib.pla $(PLVM) $(PLASM) acme --setpc 4094 -o $(TESTLIB) samplesrc/testlib.a ./$(PLVM) TEST +$(ED): toolsrc/ed.pla $(PLVM02) $(PLASM) + ./$(PLASM) -A < toolsrc/ed.pla > toolsrc/ed.a + acme --setpc 8192 -o $(ED) toolsrc/ed.a + $(ROD): samplesrc/rod.pla $(PLVM02) $(PLASM) ./$(PLASM) -AM < samplesrc/rod.pla > samplesrc/rod.a acme --setpc 4094 -o $(ROD) samplesrc/rod.a diff --git a/src/toolsrc/codegen.c b/src/toolsrc/codegen.c index 5f14805..cf9fa2a 100755 --- a/src/toolsrc/codegen.c +++ b/src/toolsrc/codegen.c @@ -388,10 +388,13 @@ void emit_trailer(void) } void emit_moddep(char *name, int len) { - if (name) - emit_dci(name, len); - else - printf("\t%s\t$00\t\t\t; END OF MODULE DEPENDENCIES\n", DB); + if (outflags & MODULE) + { + if (name) + emit_dci(name, len); + else + printf("\t%s\t$00\t\t\t; END OF MODULE DEPENDENCIES\n", DB); + } } void emit_sysflags(int val) { diff --git a/src/toolsrc/ed.pla b/src/toolsrc/ed.pla new file mode 100755 index 0000000..910dbc5 --- /dev/null +++ b/src/toolsrc/ed.pla @@ -0,0 +1,1503 @@ +// +// Global constants +// +const false = 0 +const true = !false +// +// Hardware constants +// +const csw = $0036 +const speaker = $C030 +const showgraphics = $C050 +const showtext = $C051 +const showfull = $C052 +const showmix = $C053 +const showpage1 = $C054 +const showpage2 = $C055 +const showlores = $C056 +const showhires = $C057 +const pushbttn1 = $C061 +const pushbttn2 = $C062 +const pushbttn3 = $C063 +const keyboard = $C000 +const keystrobe = $C010 +const keyenter = $8D +const keyspace = $A0 +const keyarrowup = $8B +const keyarrowdown = $8A +const keyarrowleft = $88 +const keyarrowright = $95 +const keyescape = $9B +const keyctrla = $81 +const keyctrlb = $82 +const keyctrlc = $83 +const keyctrld = $84 +const keyctrle = $85 +const keyctrlf = $86 +const keyctrli = $89 +const keyctrlk = $8B +const keyctrll = $8C +const keyctrln = $8E +const keyctrlo = $8F +const keyctrlp = $90 +const keyctrlq = $91 +const keyctrlr = $92 +const keyctrls = $93 +const keyctrlt = $94 +const keyctrlu = $95 +const keyctrlv = $96 +const keyctrlw = $97 +const keyctrlx = $98 +const keyctrlz = $9A +const keydelete = $FF +const getbuff = $01FF +// +// Data and text buffer constants +// +const machid = $BF98 +const maxlines = 1500 +const maxfill = 1524 +const iobuffer = $0800 +const databuff = $0C00 +const strlinbuf = $1000 +const strheapmap = $1F00 +const strheapmsz = 224 // $E0 = 28K is memory@16 bytes per bit map, 128 bytes per 8 bit map, 1K bytes per 8 byte map +const maxlnlen = 79 +const strheap = $4800 +const strheasz = $7000 +const pgjmp = 16 +const changed = 1 +const insmode = 2 +const showcurs = 4 +const uppercase = 8 +const shiftlock = 128 +// +// Argument buffer +// +word = $EEEE +byte = 32 // buffer length +byte[32] argbuff = "" +// +// Text screen row address array +// +word txtscrn = $0400,$0480,$0500,$0580,$0600,$0680,$0700,$0780 +word = $0428,$04A8,$0528,$05A8,$0628,$06A8,$0728,$07A8 +word = $0450,$04D0,$0550,$05D0,$0650,$06D0,$0750,$07D0 +// +// Editor variables +// +byte nullstr = "" +byte version = "PLASMA ][ EDITOR VERSION 0.9 " +byte errorstr = "ERROR: $" +byte okstr = "OK" +byte outofmem = "OUT OF MEMORY!" +byte losechng = "LOSE CHANGES TO FILE (Y/N)?" +byte untitled = "UNTITLED" +byte[64] txtfile = "UNTITLED.PLA" +byte flags = 0 +byte flash = 0 +word numlines = 0 +word cutbuf = 0 +byte perr, cursx, cursy, scrnleft, curscol, underchr, curschr +word keyin, cursrow, scrntop, cursptr +// +// Predeclared functions +// +predef cmdmode +// +// Utility functions +// +// Defines for ASM routines +// +asm equates +INTERP = $03D0 +LCRDEN = $C080 +LCWTEN = $C081 +ROMEN = $C082 +LCRWEN = $C083 +LCBNK2 = $00 +LCBNK1 = $08 + !SOURCE "vmsrc/plvmzp.inc" +end +// +// CALL 6502 ROUTINE +// CALL(ADDR, AREG, XREG, YREG, STATUS) +// +asm call +REGVALS = SRC + PHP + LDA ESTKL+4,X + STA TMPL + LDA ESTKH+4,X + STA TMPH + LDA ESTKL,X + PHA + LDA ESTKL+1,X + TAY + LDA ESTKL+3,X + PHA + LDA ESTKL+2,X + INX + INX + INX + INX + STX ESP + TAX + PLA + BIT ROMEN + PLP + JSR JMPTMP + PHP + BIT LCRDEN+LCBNK2 + STA REGVALS+0 + STX REGVALS+1 + STY REGVALS+2 + PLA + STA REGVALS+3 + LDX ESP + LDA #<REGVALS + LDY #>REGVALS + STA ESTKL,X + STY ESTKH,X + PLP + RTS +JMPTMP JMP (TMP) +end +// +// CALL PRODOS +// SYSCALL(CMD, PARAMS) +// +asm syscall + LDA ESTKL,X + LDY ESTKH,X + STA PARAMS + STY PARAMS+1 + INX + LDA ESTKL,X + STA CMD + JSR $BF00 +CMD: !BYTE 00 +PARAMS: !WORD 0000 + LDY #$00 + STA ESTKL,X + STY ESTKH,X + RTS +end +// SET MEMORY TO VALUE +// MEMSET(ADDR, SIZE, VALUE) +// With optimizations from Peter Ferrie +// +asm memset + LDY #$00 + LDA ESTKL+2,X + STA DSTL + LDA ESTKH+2,X + STA DSTH + INC ESTKL+1,X + INC ESTKH+1,X +SETMLPL CLC + LDA ESTKL,X +SETMLPH DEC ESTKL+1,X + BNE + + DEC ESTKH+1,X + BEQ SETMEX ++ STA (DST),Y + INY + BNE + + INC DSTH ++ BCS SETMLPL + SEC + LDA ESTKH,X + BCS SETMLPH +SETMEX INX + INX + RTS +end +// +// COPY MEMORY +// MEMCPY(DSTADDR, SRCADDR, SIZE) +// +asm memcpy + INX + INX + LDA ESTKL-2,X + ORA ESTKH-2,X + BEQ CPYMEX + LDA ESTKL-1,X + CMP ESTKL,X + LDA ESTKH-1,X + SBC ESTKH,X + BCC REVCPY +; +; FORWARD COPY +; + LDA ESTKL,X + STA DSTL + LDA ESTKH,X + STA DSTH + LDA ESTKL-1,X + STA SRCL + LDA ESTKH-1,X + STA SRCH + INC ESTKH-2,X + LDY #$00 +FORCPYLP LDA (SRC),Y + STA (DST),Y + INY + BNE + + INC DSTH + INC SRCH ++ DEC ESTKL-2,X + BNE FORCPYLP + DEC ESTKH-2,X + BNE FORCPYLP + RTS +; +; REVERSE COPY +; +REVCPY ;CLC + LDA ESTKL-2,X + ADC ESTKL,X + STA DSTL + LDA ESTKH-2,X + ADC ESTKH,X + STA DSTH + CLC + LDA ESTKL-2,X + ADC ESTKL-1,X + STA SRCL + LDA ESTKH-2,X + ADC ESTKH-1,X + STA SRCH + INC ESTKH-2,X + DEC DSTH + DEC SRCH + LDY #$FF +REVCPYLP LDA (SRC),Y + STA (DST),Y + DEY + CPY #$FF + BNE + + DEC DSTH + DEC SRCH ++ DEC ESTKL-2,X + BNE REVCPYLP + DEC ESTKH-2,X + BNE REVCPYLP +CPYMEX RTS +end +// +// CHAR OUT +// COUT(CHAR) +// +asm cout + LDA ESTKL,X + ORA #$80 + BIT ROMEN + JSR $FDED + BIT LCRDEN+LCBNK2 + RTS +end +// +// CHAR IN +// RDKEY() +// +asm cin + BIT ROMEN + JSR $FD0C + BIT LCRDEN+LCBNK2 + DEX + LDY #$00 + STA ESTKL,X + STY ESTKH,X + RTS +end +// +// PRINT STRING +// PRSTR(STR) +// +asm prstr + LDY #$00 + LDA ESTKL,X + STA SRCL + LDA ESTKH,X + STA SRCH + LDA (SRC),Y + STA TMP + BEQ ++ + BIT ROMEN +- INY + LDA (SRC),Y + ORA #$80 + JSR $FDED + CPY TMP + BNE - + BIT LCRDEN+LCBNK2 +++ RTS +end +// +// READ STRING +// STR = RDSTR(PROMPTCHAR) +// +asm rdstr + LDA ESTKL,X + STA $33 + STX ESP + BIT ROMEN + JSR $FD6A + BIT LCRDEN+LCBNK2 + STX $01FF +- LDA $01FF,X + AND #$7F + STA $01FF,X + DEX + BPL - + LDX ESP + LDA #$FF + STA ESTKL,X + LDA #$01 + STA ESTKH,X + RTS +end +// +// EXIT +// +asm exit + JSR $BF00 + !BYTE $65 + !WORD EXITTBL +EXITTBL: + !BYTE 4 + !BYTE 0 +end +//def toupper_11(c) +// if c >= 'a' +// if c <= 'z' +// return c - $20 +// fin +// fin +// return c +//end +asm toupper + LDA ESTKL,X + AND #$7F + CMP #'a' + BCC + + CMP #'z'+1 + BCS + + SEC + SBC #$20 ++ STA ESTKL,X + RTS +end +asm clrhibit(strptr) + LDA ESTKL,X + STA SRCL + LDA ESTKH,X + STA SRCH + LDY #$00 + LDA (SRC),Y + BEQ + + TAY +CLHILP LDA (SRC),Y + AND #$7F + STA (SRC),Y + DEY + BNE CLHILP ++ RTS +end +asm sethibit(strptr) + LDA ESTKL,X + STA SRCL + LDA ESTKH,X + STA SRCH + LDY #$00 + LDA (SRC),Y + BEQ + + TAY +STHILP LDA (SRC),Y + ORA #$80 + STA (SRC),Y + DEY + BNE STHILP ++ RTS +end +asm cpyln(srcstr, dststr) + LDA ESTKL,X + STA DSTL + LDA ESTKH,X + STA DSTH + INX + LDA ESTKL,X + STA SRCL + LDA ESTKH,X + STA SRCH + LDY #$00 + LDA (SRC),Y + TAY + LDA #$00 + INY + STA (DST),Y + DEY + BEQ ++ +CPLNLP LDA (SRC),Y + CMP #$20 + BCS + + ADC #$60 ++ AND #$7F + STA (DST),Y + DEY + BNE CPLNLP + LDA (SRC),Y +++ STA (DST),Y + RTS +end +// +// ProDOS routines +// +def getpfx(path) + byte params[3] + + ^path = 0 + params.0 = 1 + params:1 = path + perr = syscall($C7, @params) + return path +end +def setpfx(path) + byte params[3] + + params.0 = 1 + params:1 = path + perr = syscall($C6, @params) + return path +end +def open(path, buff) + byte params[6] + + params.0 = 3 + params:1 = path + params:3 = buff + params.5 = 0 + perr = syscall($C8, @params) + return params.5 +end +def close(refnum) + byte params[2] + + params.0 = 1 + params.1 = refnum + perr = syscall($CC, @params) + return perr +end +def read(refnum, buff, len) + byte params[8] + + params.0 = 4 + params.1 = refnum + params:2 = buff + params:4 = len + params:6 = 0 + perr = syscall($CA, @params) + return params:6 +end +def write(refnum, buff, len) + byte params[8] + + params.0 = 4 + params.1 = refnum + params:2 = buff + params:4 = len + params:6 = 0 + perr = syscall($CB, @params) + return params:6 +end +def create(path, access, type, aux) + byte params[12] + + params.0 = 7 + params:1 = path + params.3 = access + params.4 = type + params:5 = aux + params.7 = $1 + params:8 = 0 + params:10 = 0 + perr = syscall($C0, @params) + return perr +end +def destroy(path) + byte params[12] + + params.0 = 1 + params:1 = path + perr = syscall($C1, @params) + return perr +end +def newline(refnum, emask, nlchar) + byte params[4] + + params.0 = 3 + params.1 = refnum + params.2 = emask + params.3 = nlchar + perr = syscall($C9, @params) + return perr +end + +//===================================== +// +// Editor +// +//===================================== + +def crout + cout($0D) +end +def bell + return call($FBDD, 0, 0, 0, 0) +end +// +// Memory management routines +// +def strcpy(srcstr, dststr) + byte strlen + + strlen = ^srcstr + while (srcstr).[strlen] == $8D or (srcstr).[strlen] == $A0 + strlen = strlen - 1 + loop + ^dststr = strlen + memcpy(dststr + 1, srcstr + 1, strlen) +end +def heapaddr(ofst, mask) + word addr + + addr = (ofst << 7) + strheap + while !(mask & 1) + addr = addr + 16 + mask = mask >> 1 + loop + return addr +end +def sizemask(size) + if size <= 16 + return $01 + elsif size <= 32 + return $03 + elsif size <= 48 + return $07 + elsif size <= 64 + return $0F + elsif size <= 80 + return $1F + fin + return 0 +end +def heapalloc(size) + byte szmask, i + word mapmask + + szmask = sizemask(size) + for i = strheapmsz - 1 downto 0 + if strheapmap.[i] <> $FF + mapmask = szmask + repeat + if strheapmap.[i] & mapmask + mapmask = mapmask << 1 + else + strheapmap.[i] = strheapmap.[i] | mapmask + return heapaddr(i, mapmask) + fin + until mapmask & $100 + fin + next + bell() + prstr(@outofmem) + return 0 +end +def freestr(strptr) + byte mask, ofst + + if strptr and strptr <> @nullstr + mask = sizemask(^strptr + 1) + ofst = (strptr - strheap) >> 4 + mask = mask << (ofst & $07) + ofst = ofst >> 3 + strheapmap.[ofst] = strheapmap.[ofst] & ~mask + fin +end +def newstr(strptr) + byte strlen + word newptr + + strlen = ^strptr + while (strptr).[strlen] == $8D or (strptr).[strlen] == $A0 + strlen = strlen - 1 + loop + if strlen == 0 + return @nullstr + fin + newptr = heapalloc(strlen + 1) + if newptr + memcpy(newptr, strptr, strlen + 1) + ^newptr = strlen + return newptr + fin + return @nullstr +end +def inittxtbuf + word i + + memset(strheapmap, strheapmsz, 0) + memset(strlinbuf, maxfill * 2, @nullstr) + numlines = 1 + cursrow = 0 + curscol = 0 + cursx = 0 + cursy = 0 + scrnleft = 0 + scrntop = 0 + cutbuf = 0 +end +// +// Case conversion/printing routines +// +def caseconv(chr) + if flags & uppercase + if chr & $E0 == $E0 + chr = chr - $E0 + fin + fin + return chr +end +def strupper(strptr) + byte i, chr + + for i = ^strptr downto 1 + chr = (strptr).[i] + if chr & $E0 == $E0 + (strptr).[i] = chr - $E0 + fin + next +end +def strlower(strptr) + byte i, chr + + for i = ^strptr downto 1 + chr = (strptr).[i] + if chr & $E0 == $00 + (strptr).[i] = chr + $E0 + fin + next +end +def txtupper + word i, strptr + + flags = flags | uppercase + for i = numlines - 1 downto 0 + strupper(strlinbuf:[i]) + next +end +def txtlower + word i, strptr + + flags = flags & ~uppercase + for i = numlines - 1 downto 0 + strlower(strlinbuf:[i]) + next +end +def prbyte(h) + cout('$') + return call($FDDA, h, 0, 0, 0) +end +def prword(h) + cout('$') + return call($F941, h >> 8, h, 0, 0) +end +def print(i) + byte numstr[7] + byte place, sign + + place = 6 + if i < 0 + sign = 1 + i = -i + else + sign = 0 + fin + while i >= 10 + numstr[place] = i % 10 + '0' + i = i / 10 + place = place - 1 + loop + numstr[place] = i + '0' + place = place - 1 + if sign + numstr[place] = '-' + place = place - 1 + fin + numstr[place] = 6 - place + return prstr(@numstr[place]) +end +def nametostr(namestr, len, strptr) + ^strptr = len + return memcpy(strptr + 1, namestr, len) +end +// +// File routines +// +def readtxt(filename) + byte txtbuf[81], refnum, i, j + + refnum = open(filename, iobuffer) + if refnum + newline(refnum, $7F, $0D) + repeat + txtbuf = read(refnum, @txtbuf + 1, maxlnlen) + if txtbuf + sethibit(@txtbuf) + if flags & uppercase; strupper(@txtbuf); fin + strlinbuf:[numlines] = newstr(@txtbuf) + numlines = numlines + 1 + fin + if !(numlines & $0F); cout('.'); fin + until txtbuf == 0 or numlines == maxlines + close(refnum) + // + // Make sure there is a blank line at the end of the buffer + // + if numlines < maxlines and strlinbuf:[numlines - 1] <> @nullstr + strlinbuf:[numlines] = @nullstr + numlines = numlines + 1 + fin + fin +end +def writetxt(filename) + byte txtbuf[81], refnum + byte j, chr + word i, strptr + + destroy(filename) + create(filename, $C3, $04, $00) // full access, TXT file + refnum = open(filename, iobuffer) + if refnum == 0 + return + fin + // + // Remove blank lines at end of text. + // + while numlines > 1 and strlinbuf:[numlines - 1] == @nullstr; numlines = numlines - 1; loop + // + // Write all the text line to the file. + // + for i = 0 to numlines - 1 + cpyln(strlinbuf:[i], @txtbuf) + txtbuf = txtbuf + 1 + txtbuf[txtbuf] = $0D + write(refnum, @txtbuf + 1, txtbuf) + if !(i & $0F); cout('.'); fin + next + return close(refnum) +end +// +// Screen routines +// +def clrscrn + return call($FC58, 0, 0, 0, 0) +end +def drawrow(row, ofst, strptr) + byte numchars + word scrnptr + + scrnptr = txtscrn[row] + if ofst >= ^strptr + numchars = 0 + else + numchars = ^strptr - ofst + fin + if numchars >= 40 + numchars = 40 + else + memset(scrnptr + numchars, 40 - numchars, $A0A0) + fin + return memcpy(scrnptr, strptr + ofst + 1, numchars) +end +def drawscrn(toprow, ofst) + byte row, numchars + word numchars, strptr, scrnptr + + if ofst + for row = 0 to 23 + strptr = strlinbuf:[toprow + row] + scrnptr = txtscrn[row] + if ofst >= ^strptr + numchars = 0 + else + numchars = ^strptr - ofst + fin + if numchars >= 40 + numchars = 40 + else + memset(scrnptr + numchars, 40 - numchars, $A0A0) + fin + memcpy(scrnptr, strptr + ofst + 1, numchars) + next + else + for row = 0 to 23 + strptr = strlinbuf:[toprow + row] + scrnptr = txtscrn[row] + numchars = ^strptr + if numchars >= 40 + numchars = 40 + else + memset(scrnptr + numchars, 40 - numchars, $A0A0) + fin + memcpy(scrnptr, strptr + 1, numchars) + next + fin +end +def cursoff + if flags & showcurs + ^cursptr = underchr + flags = flags & ~showcurs + fin +end +def curson + if !(flags & showcurs) + cursptr = txtscrn[cursy] + cursx + underchr = ^cursptr + ^cursptr = curschr + flags = flags | showcurs + fin +end +def cursflash + if flags & showcurs + if flash == 0 + ^cursptr = curschr + elsif flash == 128 + ^cursptr = underchr + fin + flash = flash + 1 + fin +end +def redraw + cursoff + drawscrn(scrntop, scrnleft) + curson +end +def curshome + cursoff + cursrow = 0 + curscol = 0 + cursx = 0 + cursy = 0 + scrnleft = 0 + scrntop = 0 + drawscrn(scrntop, scrnleft) + return curson +end +def cursend + cursoff + if numlines > 23 + cursrow = numlines - 1 + cursy = 23 + scrntop = cursrow - 23 + else + cursrow = numlines - 1 + cursy = numlines - 1 + scrntop = 0 + fin + curscol = 0 + cursx = 0 + scrnleft = 0 + drawscrn(scrntop, scrnleft) + return curson +end +def cursup + if cursrow > 0 + cursoff + cursrow = cursrow - 1 + if cursy > 0 + cursy = cursy - 1 + else + scrntop = cursrow + drawscrn(scrntop, scrnleft) + fin + curson + fin +end +def pgup + byte i + + for i = pgjmp downto 0 + cursup + next +end +def cursdown + if cursrow < numlines - 1 + cursoff + cursrow = cursrow + 1 + if cursy < 23 + cursy = cursy + 1 + else + scrntop = cursrow - 23 + drawscrn(scrntop, scrnleft) + fin + curson + fin +end +def pgdown + byte i + + for i = pgjmp downto 0 + cursdown + next +end +def cursleft + if curscol > 0 + cursoff + curscol = curscol - 1 + if cursx > 0 + cursx = cursx - 1 + else + scrnleft = curscol + drawscrn(scrntop, scrnleft) + fin + curson + fin +end +def pgleft + byte i + + for i = 7 downto 0 + cursleft + next +end +def cursright + if curscol < 80 + cursoff + curscol = curscol + 1 + if cursx < 39 + cursx = cursx + 1 + else + scrnleft = curscol - 39 + drawscrn(scrntop, scrnleft) + fin + curson + fin +end +def pgright + byte i + + for i = 7 downto 0 + cursright + next +end +// +// Keyboard routines +// +def keyin2e + repeat + cursflash + until ^keyboard >= 128 + return ^keystrobe +end +def keyin2 + byte key + + repeat + cursflash + key = ^keyboard + if key == keyctrll + ^keystrobe + flags = flags ^ shiftlock + key = 0 + fin + until key >= 128 + ^keystrobe + if key == keyctrln + key = $DB // [ + elsif key == keyctrlp + key = $DF // _ + elsif key == keyctrlb + key = $DC // \ + elsif key == keyarrowleft + if ^pushbttn3 < 128 + key = $FF + fin + elsif key >= $C0 and flags < shiftlock + if ^pushbttn3 < 128 + if key == $C0 + key = $D0 // P + elsif key == $DD + key = $CD // M + elsif key == $DE + key = $CE // N + fin + else + key = key | $E0 + fin + fin + return key +end +// +// Printer routines +// +def printtxt(slot) + byte txtbuf[80] + word i, scrncsw + + scrncsw = *(csw) + *(csw) = $C000 | (slot << 8) + for i = 0 to numlines - 1 + cpyln(strlinbuf:[i], @txtbuf) + prstr(@txtbuf) + crout + next + *(csw) = scrncsw +end +def openline(row) + if numlines < maxlines + memcpy(@strlinbuf:[row + 1], @strlinbuf:[row], (numlines - row) * 2) + strlinbuf:[row] = @nullstr + numlines = numlines + 1 + flags = flags | changed + return 1 + fin + bell + return 0 +end +def cutline + freestr(cutbuf) + cutbuf = strlinbuf:[cursrow] + memcpy(@strlinbuf:[cursrow], @strlinbuf:[cursrow + 1], (numlines - cursrow) * 2) + if numlines > 1 + numlines = numlines - 1 + fin + flags = flags | changed + if cursrow == numlines + cursup + fin + return redraw +end +def pasteline + if cutbuf and numlines < maxlines + memcpy(@strlinbuf:[cursrow + 1], @strlinbuf:[cursrow], (numlines - cursrow) * 2) + strlinbuf:[cursrow] = newstr(cutbuf) + numlines = numlines + 1 + flags = flags | changed + redraw + else + bell + fin +end +def joinline + byte joinstr[80], joinlen + + if cursrow < numlines - 1 + strcpy(strlinbuf:[cursrow], @joinstr) + joinlen = joinstr + ^(strlinbuf:[cursrow + 1]) + if joinlen < 80 + memcpy(@joinstr + joinstr + 1, strlinbuf:[cursrow + 1] + 1, ^(strlinbuf:[cursrow + 1])) + joinstr = joinlen + freestr(strlinbuf:[cursrow]) + strlinbuf:[cursrow] = newstr(@joinstr) + freestr(strlinbuf:[cursrow + 1]) + numlines = numlines - 1 + memcpy(@strlinbuf:[cursrow + 1], @strlinbuf:[cursrow + 2], (numlines - cursrow) * 2) + flags = flags | changed + redraw + else + bell + fin + fin +end +def splitline + byte splitstr[80], splitlen + + if openline(cursrow + 1) + if curscol + splitlen = ^(strlinbuf:[cursrow]) + if curscol < splitlen - 1 + memcpy(@splitstr + 1, strlinbuf:[cursrow] + curscol + 1, splitlen - curscol) + splitstr = splitlen - curscol + strlinbuf:[cursrow + 1] = newstr(@splitstr) + memcpy(@splitstr + 1, strlinbuf:[cursrow] + 1, curscol) + splitstr = curscol + freestr(strlinbuf:[cursrow]) + strlinbuf:[cursrow] = newstr(@splitstr) + fin + else + strlinbuf:[cursrow + 1] = strlinbuf:[cursrow] + strlinbuf:[cursrow] = @nullstr + fin + curscol = 0 + cursx = 0 + scrnleft = 0 + redraw + cursdown + fin +end +def editkey(key) + if key >= keyspace + return true + elsif key == keydelete + return true + elsif key == keyctrld + return true + elsif key == keyctrlr + return true + fin + return false +end +def editline(key) + byte editstr[80] + word undoline + + if (editkey(key)) + flags = flags | changed + memset(@editstr, 80, $A0A0) + strcpy(strlinbuf:[cursrow], @editstr) + undoline = strlinbuf:[cursrow] + strlinbuf:[cursrow] = @editstr + repeat + if key >= keyspace + if key == keydelete + if curscol > 0 + if curscol <= editstr + memcpy(@editstr[curscol], @editstr[curscol + 1], editstr - curscol) + editstr = editstr - 1 + fin + curscol = curscol - 1 + cursoff + if cursx > 0 + cursx = cursx - 1 + drawrow(cursy, scrnleft, @editstr) + else + scrnleft = scrnleft - 1 + drawscrn(scrntop, scrnleft) + fin + curson + fin + elsif curscol < maxlnlen + curscol = curscol + 1 + cursx = cursx + 1 + if flags & insmode + if editstr < maxlnlen or editstr.maxlnlen == $A0 + editstr = editstr + 1 + if curscol >= editstr + editstr = curscol + else + memcpy(@editstr[curscol + 1], @editstr[curscol], editstr - curscol) + fin + else + curscol = curscol - 1 + cursx = cursx - 1 + key = editstr[curscol] + bell + fin + else + if curscol > editstr + editstr = curscol + fin + fin + editstr[curscol] = caseconv(key) + cursoff + if cursx <= 39 + drawrow(cursy, scrnleft, @editstr) + else + scrnleft = scrnleft + 1 + cursx = 39 + drawscrn(scrntop, scrnleft) + fin + curson + else + bell + fin + elsif key == keyctrld + if curscol < editstr + strcpy(@editstr, undoline) + memcpy(@editstr[curscol + 1], @editstr[curscol + 2], editstr - curscol) + editstr = editstr - 1 + cursoff + drawrow(cursy, scrnleft, @editstr) + curson + fin + elsif key == keyctrlr + strcpy(undoline, @editstr) + cursoff + drawrow(cursy, scrnleft, @editstr) + curson + fin + key = keyin() + until not editkey(key) + if editstr + strlinbuf:[cursrow] = newstr(@editstr) + else + strlinbuf:[cursrow] = @nullstr + fin + freestr(undoline) + fin + return key +end +def editmode + repeat + when editline(keyin()) + is keyarrowup + cursup; break + is keyarrowdown + cursdown; break + is keyarrowleft + cursleft; break + is keyarrowright + cursright; break + is keyctrlw + pgup; break + is keyctrlz + pgdown; break + is keyctrla + pgleft; break + is keyctrls + pgright; break + is keyctrlq + curshome; break + is keyctrle + cursend; break + is keyctrlx + cutline; break + is keyctrlv + pasteline; break + is keyctrlf + if numlines < maxlines and cursrow == numlines - 1 + strlinbuf:[numlines] = @nullstr + numlines = numlines + 1 + fin + cursdown + is keyctrlo + openline(cursrow) + redraw + break + is keyenter + if flags & insmode + splitline + else + openline(cursrow + 1) + cursdown + redraw + fin + break + is keyctrlt + joinline; break + is keyctrli + if flags & insmode + flags = flags & ~insmode + curschr = ' ' + else + flags = flags | insmode + curschr = '+' + fin + break + is keyctrlc + if flags & uppercase + txtlower + else + txtupper + fin + redraw + break + is keyescape + cursoff + cmdmode + redraw + break + wend + until false +end +// +// Command mode +// +def prfiles(optpath) + byte path[64] + byte refnum + byte firstblk + byte entrylen, entriesblk + byte i, type, len + word entry, filecnt + + if ^optpath + strcpy(optpath, @path) + else + getpfx(@path) + prstr(@path) + crout + fin + refnum = open(@path, iobuffer) + if perr + return perr + fin + firstblk = 1 + repeat + if read(refnum, databuff, 512) == 512 + entry = databuff + 4 + if firstblk + entrylen = databuff.$23 + entriesblk = databuff.$24 + filecnt = databuff:$25 + entry = entry + entrylen + fin + for i = firstblk to entriesblk + type = ^entry + if type <> 0 + len = type & $0F + ^entry = len + prstr(entry) + if type & $F0 == $D0 // Is it a directory? + cout('/') + len = len + 1 + fin + for len = 20 - len downto 1 + cout(' ') + next + filecnt = filecnt - 1 + fin + entry = entry + entrylen + next + firstblk = 0 + else + filecnt = 0 + fin + until filecnt == 0 + close(refnum) + crout + return 0 +end +def striplead(strptr, chr) + while ^strptr and ^(strptr + 1) == chr + memcpy(strptr + 1, strptr + 2, ^strptr) + ^strptr = ^strptr - 1 + loop +end +def parsecmd(strptr) + byte cmd + + cmd = 0 + striplead(strptr, ' ') + if ^strptr + cmd = ^(strptr + 1) + memcpy(strptr + 1, strptr + 2, ^strptr) + ^strptr = ^strptr - 1 + fin + if ^strptr + striplead(strptr, ' ') + fin + return cmd +end +def chkchng + if flags & changed + prstr(@losechng) + if toupper(keyin()) == 'N' + crout + return false + fin + crout + fin + return true +end +def quit + if chkchng + exit + fin +end +def cmdmode + byte slot + word cmdptr + + clrscrn + prstr(@version) + crout + while true + prstr(@txtfile) + cmdptr = rdstr($BA) + when toupper(parsecmd(cmdptr)) + is 'A' + readtxt(cmdptr) + flags = flags | changed + break + is 'R' + if chkchng + inittxtbuf + numlines = 0 + strcpy(cmdptr, @txtfile) + readtxt(@txtfile) + if numlines == 0; numlines = 1; fin + flags = flags & ~changed + fin + break + is 'W' + if ^cmdptr + strcpy(cmdptr, @txtfile) + fin + writetxt(@txtfile) + //if flags & changed; fin + flags = flags & ~changed + break + is 'C' + prfiles(cmdptr); break + is 'P' + setpfx(cmdptr); break + is 'H' + if ^cmdptr + slot = cmdptr.1 - '0' + else + slot = 1 + fin + printtxt(slot) + break + is 'Q' + quit + is 'E' + is 0 + return + is 'N' + if chkchng + inittxtbuf + strcpy(@untitled, @txtfile) + fin + break + otherwise + bell + cout('?') + crout + wend + if perr + prstr(@errorstr) + call($FDDA, perr, 0, 0, 0) + else + prstr(@okstr) + fin + crout + loop +end +// +// Init editor +// +if !(^machid & $80) + flags = uppercase | shiftlock + keyin = @keyin2 +else + keyin = @keyin2e +fin +inittxtbuf +if argbuff + strcpy(@argbuff, @txtfile) + prstr(@txtfile) + numlines = 0 + readtxt(@txtfile) +fin +curschr = '+' +flags = flags | insmode +drawscrn(scrntop, scrnleft) +curson +editmode +done diff --git a/src/toolsrc/lex.c b/src/toolsrc/lex.c index c6ab6e0..3878fa7 100755 --- a/src/toolsrc/lex.c +++ b/src/toolsrc/lex.c @@ -34,7 +34,7 @@ t_token keywords[] = { IMPORT_TOKEN, 'I', 'M', 'P', 'O', 'R', 'T', RETURN_TOKEN, 'R', 'E', 'T', 'U', 'R', 'N', END_TOKEN, 'E', 'N', 'D', - EXIT_TOKEN, 'E', 'X', 'I', 'T', +// EXIT_TOKEN, 'E', 'X', 'I', 'T', DONE_TOKEN, 'D', 'O', 'N', 'E', LOGIC_NOT_TOKEN, 'N', 'O', 'T', LOGIC_AND_TOKEN, 'A', 'N', 'D',