Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

1 rinda
11KB

  1. /* VIM.C - A SMALL MODAL EDITOR FOR THE COMMODORE 64, WRITTEN FOR POWER C. * * ÉNCREMENT 2 EDITS: IT READS A PETSCII ÓÅÑ FILE INTO ONE BUFFER, KEEPS A LINE * INDEX, SHOWS 24 LINES PLUS A STATUS ROW, AND SUPPORTS * MOVE H J K L / ARROWS, 0 $ GG Ç * INSERT I A Á É O Ï (ÒÕÎ/ÓÔÏÐ LEAVES INSERT MODE, ÄÅÌ BACKSPACES) * CHANGE X DD P * COLON :W :W NAME :WQ :X :Q :Q! * * ÔHE BUFFER HOLDS THE FILE EXACTLY AS IT SITS ON DISK: PETSCII BYTES WITH $0D * BETWEEN LINES. ËEYS ARE COMPARED AS NUMBERS, NEVER AS CHARACTER CONSTANTS, * SO NOTHING DEPENDS ON HOW THE COMPILER TREATS LITERALS. (ÕNSHIFTED LETTERS * ARRIVE AS $41-$5A, SO H = 72; SHIFTED ONES AS $C1-$DA, SO Ç = 199.) */ CHAR *MALLOC(); CHAR *BFR; /* FILE TEXT, $0D SEPARATED */ UNSIGNED BLEN; /* BYTES USED */ UNSIGNED LPTR[600]; /* OFFSET OF EACH LINE START */ INT NLINES; INT CY, CX; /* CURSOR LINE AND COLUMN */ INT TOP; /* FIRST LINE ON SCREEN */ INT LEFTCOL; /* HORIZONTAL SCROLL */ CHAR FNAME[24]; INT MODE; /* 0 NORMAL, 1 INSERT */ INT DIRTY; /* BUFFER CHANGED SINCE THE LAST SAVE */ INT PEND; /* FIRST KEY OF A TWO KEY COMMAND: D OR G */ CHAR *NOTE; /* ONE-SHOT MESSAGE FOR THE STATUS ROW */ CHAR YBUF[160]; /* THE YANKED LINE */ INT YLEN, YOK; INT REDRAW; /* 1 CURSOR ROW, 2 WHOLE SCREEN */ /* SCREEN ROWS ARE 0..23, THE STATUS ROW IS 24 */ /* SHORTEN FNAME TO WHAT FITS */ SHORTN(N) INT N; Û INT I; I = 0; WHILE (FNAME[I] && I < N) I++; FNAME[I] = 0; RETURN 0; Ý /* A MESSAGE THAT WAITS FOR A KEY */ MSG(S) CHAR *S; Û SCLR(24, 0, 40); SPS(24, 0, S); SKEY(); RETURN 0; Ý /* READ A LINE OF LOWERCASE PETSCII INTO S, ECHOED FROM COLUMN C OF ROW 24 */ GETLN(C, S, MAX) INT C, MAX; CHAR *S; Û INT N, K; N = 0; S[0] = 0; FOR (;;) Û K = SKEY(); IF (K == 13) BREAK; IF (K == 3) Û N = 0; S[0] = 0; BREAK; Ý IF (K == 20) Û IF (N > 0) Û N--; S[N] = 0; Ý Ý ELSE Û IF (K >= 0XC1 && K <= 0XDA) K = K - 0X80; IF (K >= 32 && K != 127 && N < MAX) Û S[N] = K; N++; S[N] = 0; Ý Ý SCLR(24, C, MAX); SPS(24, C, S); Ý RETURN N; Ý /* A YES/NO QUESTION ON THE STATUS ROW: 1 FOR Y, 0 FOR N OR RUN/STOP */ ASKYN(Q) CHAR *Q; Û INT K; SCLR(24, 0, 40); SPS(24, 0, Q); FOR (;;) Û K = SKEY(); IF (K == 89) RETURN 1; /* Y */ IF (K == 217) RETURN 1; /* Ù */ IF (K == 78) RETURN 0; /* N */ IF (K == 206) RETURN 0; /* Î */ IF (K == 3) RETURN 0; Ý Ý /* ASK WHICH FILE TO OPEN */ ASKNAME() Û SCLR(24, 0, 40); SPS(24, 0, "FILE: "); IF (GETLN(6, FNAME, 20) == 0) FNAME[0] = 0; RETURN 0; Ý /* THE DRIVE'S ERROR CHANNEL (ALREADY OPEN AS FILE 15): THE TWO DIGIT CODE OF THE LAST COMMAND. 0-19 ARE FINE ("00, OK"), 62 IS FILE NOT FOUND. OPEN() OF A MISSING FILE SUCCEEDS ON A CBM DRIVE - ONLY THE ERROR CHANNEL TELLS. DO NOT CLOSE 15 WHILE ANOTHER FILE IS OPEN: CLOSING THE COMMAND CHANNEL CLOSES EVERY FILE ON THE DRIVE. */ DOSST() Û INT CH, N, D; N = 0; D = 0; FOR (;;) Û CH = GETC(15); IF (CH < 0) BREAK; IF (CH == 13) BREAK; IF (D < 2) Û IF (CH >= 48 && CH <= 57) Û N = N * 10 + CH - 48; D++; Ý Ý Ý IF (D < 2) RETURN 99; RETURN N; Ý INT SPLIT; /* A LONG LINE WAS SPLIT ON LOAD */ /* READ FNAME INTO BFR. 1 ON SUCCESS, 0 IF THE FILE IS NOT THERE. LINES LONGER THAN 80 ARE SPLIT - THE EDITOR'S LINE LIMIT */ LOADF() Û INT F, CH, PREV, C, COL; CHAR ON[28]; INT I; IF (FNAME[0] == 0) RETURN 1; I = 0; WHILE (FNAME[I] && I < 20) Û ON[I] = FNAME[I]; I++; Ý ON[I++] = 44; /* , */ ON[I++] = 83; /* Ó (PETSCII, NOT ASCII) */ ON[I++] = 44; /* , */ ON[I++] = 82; /* Ò */ ON[I] = 0; IF (OPEN(15, 8, 15, "") == 0) RETURN 0; /* STATUS CHANNEL FIRST */ F = OPEN(5, 8, 2, ON); IF (F == 0) Û CLOSE(15); RETURN 0; Ý IF (DOSST() >= 20) Û CLOSE(5); CLOSE(15); RETURN 0; Ý BLEN = 0; PREV = 0; COL = 0; SPLIT = 0; FOR (;;) Û CH = GETC(5); IF (CH < 0) BREAK; /* END OF FILE */ IF (CH == 26) BREAK; IF (CH == 10 && PREV == 13) Û /* CRLF SEEN AS TWO BYTES */ PREV = CH; CONTINUE; Ý IF (CH == 13) C = 13; ELSE IF (CH == 10) C = 13; ELSE C = CH; IF (C != 13 && COL >= 80) Û /* 80 COLUMNS AT MOST */ IF (BLEN < 18999) BFR[BLEN++] = 13; COL = 0; SPLIT = 1; Ý IF (BLEN < 18999) BFR[BLEN++] = C; IF (C == 13) COL = 0; ELSE COL++; PREV = CH; Ý CLOSE(5); CLOSE(15); /* LAST: IT CLOSES EVERYTHING */ RETURN 1; Ý /* FIND THE START OF EVERY LINE */ BUILDIDX() Û UNSIGNED I; NLINES = 1; LPTR[0] = 0; FOR (I = 0; I < BLEN; I++) Û IF (BFR[I] == 13) Û IF (NLINES < 599) Û LPTR[NLINES] = I + 1; NLINES++; Ý Ý Ý RETURN 0; Ý /* THE ":" COMMAND LINE. RETURNS 1 WHEN THE EDITOR SHOULD QUIT */ DOSCMD() Û INT N, P, OK, QF; CHAR CMD[24]; SCLR(24, 0, 40); SPC(24, 0, 58); /* : */ N = GETLN(1, CMD, 20); SCLR(24, 0, 40); IF (N == 0) RETURN 0; IF (CMD[0] == 81) Û /* Q, Q! */ IF (CMD[1] == 33) RETURN 1; IF (DIRTY) Û NOTE = "UNSAVED - :Q! QUITS"; RETURN 0; Ý RETURN 1; Ý OK = 0; QF = 0; P = 1; IF (CMD[0] == 87) OK = 1; /* W, WQ, W NAME */ IF (CMD[0] == 88) Û /* X */ OK = 1; QF = 1; Ý IF (OK == 0) Û NOTE = "UNKNOWN COMMAND"; RETURN 0; Ý IF (CMD[0] == 87 && CMD[1] == 81) Û QF = 1; P = 2; Ý WHILE (CMD[P] == 32) P++; IF (CMD[P]) Û N = 0; WHILE (CMD[P] && N < 20) FNAME[N++] = CMD[P++]; FNAME[N] = 0; Ý IF (FNAME[0] == 0) Û NOTE = "NO FILE NAME"; RETURN 0; Ý IF (SAVEF()) Û DIRTY = 0; NOTE = "WRITTEN"; RETURN QF; Ý NOTE = "CANNOT WRITE"; RETURN 0; Ý MAIN() Û INT K, OK, P; SINIT(); MLINIT(); /* ÍÌ HELPERS TO $C000: BEFORE MALLOC */ BFR = MALLOC(19000); IF (BFR == 0) Û SPS(0, 0, "OUT OF MEMORY"); SKEY(); RETURN; Ý BLEN = 0; NLINES = 1; LPTR[0] = 0; CY = 0; CX = 0; TOP = 0; LEFTCOL = 0; FNAME[0] = 0; MODE = 0; DIRTY = 0; PEND = 0; NOTE = 0; YLEN = 0; YOK = 0; SPLIT = 0; REDRAW = 2; FOR (;;) Û /* A FILE TO EDIT */ ASKNAME(); SHORTN(20); IF (FNAME[0] == 0) Û /* NO NAME: AN EMPTY BUFFER */ OK = 1; BREAK; Ý OK = LOADF(); IF (OK) BREAK; IF (ASKYN("NOT FOUND - CREATE IT? (Y/N) ")) BREAK; Ý BUILDIDX(); IF (OK == 0) Û /* KEEP THE NAME: :W CREATES IT */ NLINES = 1; BLEN = 0; NOTE = "NEW FILE"; Ý IF (SPLIT) NOTE = "LONG LINES SPLIT AT 80"; FOR (;;) Û SCROLL(); DALL(); K = SKEY(); NOTE = 0; IF (MODE) Û /* ---- INSERT MODE */ IF (K == 3) Û /* ÒÕÎ/ÓÔÏÐ = ÅSC */ MODE = 0; IF (CX > 0) CX--; Ý ELSE IF (K == 13) Û NEWLINE(); Ý ELSE IF (K == 20) Û BKSPACE(); Ý ELSE IF (ARROW(K)) Û CX = CX; Ý ELSE IF (K >= 32 && K < 128) Û INSCHAR(K); Ý ELSE IF (K >= 161) Û INSCHAR(K); Ý CONTINUE; Ý IF (PEND) Û /* ---- SECOND KEY OF DD / GG */ P = PEND; PEND = 0; IF (P == 68 && K == 68) DELLINE(); IF (P == 71 && K == 71) Û CY = 0; CX = 0; Ý CLAMPX(); CONTINUE; Ý IF (ARROW(K)) Û CX = CX; Ý ELSE IF (K == 72) Û /* H */ IF (CX > 0) CX--; Ý ELSE IF (K == 76) Û /* L */ CX++; CLAMPX(); Ý ELSE IF (K == 74) Û /* J */ ARROW(17); Ý ELSE IF (K == 75) Û /* K */ ARROW(145); Ý ELSE IF (K == 48) Û /* 0 */ CX = 0; Ý ELSE IF (K == 36) Û /* $ */ CX = LINEND(CY) - LPTR[CY]; Ý ELSE IF (K == 199) Û /* Ç */ CY = NLINES - 1; CX = 0; Ý ELSE IF (K == 68) Û /* D.. */ PEND = 68; Ý ELSE IF (K == 71) Û /* G.. */ PEND = 71; Ý ELSE IF (K == 88) Û /* X */ DELCHAR(); CLAMPX(); Ý ELSE IF (K == 80) Û /* P */ PASTE(); Ý ELSE IF (K == 73) Û /* I */ MODE = 1; Ý ELSE IF (K == 65) Û /* A */ CX++; CLAMPX(); MODE = 1; Ý ELSE IF (K == 193) Û /* Á */ CX = LINEND(CY) - LPTR[CY]; MODE = 1; Ý ELSE IF (K == 201) Û /* É */ CX = 0; MODE = 1; Ý ELSE IF (K == 79) Û /* O */ CX = LINEND(CY) - LPTR[CY]; NEWLINE(); MODE = 1; Ý ELSE IF (K == 207) Û /* Ï */ CX = 0; NEWLINE(); CY--; MODE = 1; Ý ELSE IF (K == 58) Û /* : */ IF (DOSCMD() == 1) Û SDONE(); RETURN; Ý Ý Ý Ý

Powered by TurnKey Linux.