|
- /* VSCREEN.C - SCREEN AND KEYBOARD FOR THE C64 VIM CLONE.
*
* ÔHE EDITOR WRITES STRAIGHT INTO THE SCREEN MATRIX AT $0400 AND COLOUR RAM AT
* $D800 RATHER THAN GOING THROUGH THE KERNAL, AND IT SELECTS THE LOWER/UPPER
* CASE CHARACTER SET AT $1800 SO THAT PETSCII $41-$5A DRAWS AS REAL LOWERCASE.
*
* ÅVERYTHING HERE RETURNS INT, SO THE OTHER COMPILATION UNIT CAN CALL THESE
* WITHOUT DECLARING THEM (POWER C IS Ë&Ò Ã).
*/
CHAR *SCR; /* SCREEN MATRIX, $0400 */
CHAR *COLR; /* COLOUR RAM, $D800 */
/* PETSCII BYTE -> SCREEN CODE */
S2V(P)
INT P;
Û
IF (P >= 0XC0) RETURN P - 0X80;
IF (P >= 0XA0) RETURN P - 0X40;
IF (P >= 0X60) RETURN P - 0X20;
IF (P >= 0X40) RETURN P - 0X40;
RETURN P;
Ý
/* RAW SCREEN CODE AT ROW R, COLUMN C */
SRAW(R, C, V)
INT R, C, V;
Û
INT I;
IF (R < 0) RETURN 0;
IF (R > 24) RETURN 0;
IF (C < 0) RETURN 0;
IF (C > 39) RETURN 0;
I = R * 40 + C;
SCR[I] = V;
COLR[I] = 1;
RETURN 0;
Ý
/* ONE PETSCII CHARACTER */
SPC(R, C, P)
INT R, C, P;
Û
SRAW(R, C, S2V(P));
RETURN 0;
Ý
/* ONE PETSCII CHARACTER, INVERTED: THE CURSOR AND THE STATUS ROW */
SRPC(R, C, P)
INT R, C, P;
Û
SRAW(R, C, S2V(P) + 128);
RETURN 0;
Ý
/* A REVERSED SPACE, FOR THE CURSOR SITTING PAST THE END OF A LINE */
SBLK(R, C)
INT R, C;
Û
SRAW(R, C, 160);
RETURN 0;
Ý
/* A ZERO TERMINATED PETSCII STRING */
SPS(R, C, S)
INT R, C;
CHAR *S;
Û
WHILE (*S) SPC(R, C++, *S++);
RETURN 0;
Ý
/* N BLANKS FROM (R,C) */
SCLR(R, C, N)
INT R, C, N;
Û
WHILE (N-- > 0) SRAW(R, C++, 32);
RETURN 0;
Ý
/* TAKE OVER THE MACHINE: BLACK ON BLUE, LOWER CASE, NO BLINKING CURSOR */
SINIT()
Û
INT I;
CHAR *P;
SCR = (CHAR *) 0X0400;
COLR = (CHAR *) 0XD800;
P = (CHAR *) 0XD018;
*P = 0X17;
P = (CHAR *) 0XD020;
*P = 0;
P = (CHAR *) 0XD021;
*P = 6;
P = (CHAR *) 0X00CC;
*P = 0;
P = (CHAR *) 0X0091; /* RUN/STOP FLAG: DROP WHATEVER BOOT LEFT */
*P = 0;
FOR (I = 0; I < 1000; I++) Û
SCR[I] = 32;
COLR[I] = 1;
Ý
RETURN 0;
Ý
/* GIVE THE MACHINE BACK THE WAY BASIC EXPECTS IT */
SDONE()
Û
CHAR *P;
CHAR A, X, Y;
P = (CHAR *) 0XD018;
*P = 0X15;
P = (CHAR *) 0XD020;
*P = 14;
P = (CHAR *) 0XD021;
*P = 6;
/* DO NOT RETURN TO BASIC: POWER C OWNS ZERO PAGE 43-74, WHICH IS WHERE
BASIC KEEPS ITS PROGRAM AND VARIABLE POINTERS, SO BASIC CARRIES ON WITH
GARBAGE AND PRINTS A MANGLED ERROR INSTEAD OF ÒÅÁÄÙ. RESTART THE
MACHINE THROUGH THE KERNAL RESET INSTEAD - BANNER AND ÒÅÁÄÙ, LIKE
SWITCHING ON. THE FILE HAS BEEN SAVED (OR ABANDONED WITH :Q!) BY NOW. */
A = 0;
X = 0;
Y = 0;
SYS(0XFCE2, &A, &X, &Y); /* NEVER COMES BACK */
RETURN 0;
Ý
/* ---------------------------------------------------------------- KEYBOARD
*
* ËEYS COME STRAIGHT OUT OF THE KERNAL'S KEYBOARD BUFFER: $C6 SAYS HOW MANY
* ARE WAITING AND THEY QUEUE FROM $0277. ÔHE KERNAL'S OWN IRQ HANDLER SCANS
* THE KEYBOARD MATRIX AND FILLS THAT BUFFER, SO THIS GETS EACH PRESS AS IT
* HAPPENS - AND IT ALSO CATCHES ANYTHING TYPED BEFORE THE PROGRAM STARTED.
*
* (ÇÅÔÉÎ THROUGH SYS() ONCE "CRASHED" - BUT THAT WAS SYS() CALLED WITH THE
* C128 BANK ARGUMENT; ON THE C64 IT IS SYS(ADDR, &A, &X, &Y).) ÁND THE LIBRARY'S GETCHAR() IS LINE BUFFERED - IT
* ECHOES THROUGH THE SCREEN EDITOR AND ONLY HANDS CHARACTERS OVER AFTER ÒÅÔÕÒÎ.
*/
/* NEXT KEY, OR 0 IF NONE IS WAITING */
SKEYP()
Û
INT N, K, I;
CHAR *CNT, *BUF;
CNT = (CHAR *) 0X00C6;
N = *CNT;
N = N & 255;
IF (N == 0) RETURN 0;
BUF = (CHAR *) 0X0277;
K = BUF[0];
K = K & 255;
FOR (I = 1; I < N; I++) BUF[I - 1] = BUF[I];
*CNT = (CHAR) (N - 1);
RETURN K;
Ý
/* WAIT FOR A KEY */
SKEY()
Û
INT K;
FOR (;;) Û
K = SKEYP();
IF (K != 0) RETURN K;
Ý
Ý
|