/* vmlwrap.c - the C side of the machine code helpers. build-ml.ps1 appends * this to the generated byte array to make vml.c; edit it here. * * Parameters go through a block at $c400 (not $cf00: the C stack lives just below $d000), then sys() jumps to the entry. * On the c64 sys() takes no bank argument: sys(addr, &a, &x, &y). */ extern char *bfr; extern unsigned blen; extern unsigned lptr[]; extern int nlines, top, leftcol; /* move the code to $c000 and keep power c's heap and stack below it. must run before malloc() */ mlinit() { char *d; int i; highmem(0xc000); d = (char *) 0xc000; for (i = 0; i < MLSIZE; i++) d[i] = mlcode[i]; return 0; } /* call an entry, return what it left in A */ mlgo(addr) unsigned addr; { char a, x, y; a = 0; x = 0; y = 0; sys(addr, &a, &x, &y); return a & 255; } /* The wrappers fill the parameter block through one pointer instead of calling a helper per field: every power c function call costs a lot, and mlscr runs on every key. Words are stored low byte first. */ /* paint one row at screen address dst: len bytes from src, cursor at column cur (255 = none), rev = 128 for an all reverse row */ mlrow(src, len, dst, cur, rev) unsigned src, dst; int len, cur, rev; { char *p; p = (char *) 0xc400; p[0] = src; p[1] = src >> 8; p[2] = len; p[3] = dst; p[4] = dst >> 8; p[5] = cur; p[6] = rev; mlgo(MLROW); return 0; } /* paint screen rows r0..r1 from the buffer; the cursor sits at screen row crow (255 = none), column ccol */ mlscr(r0, r1, crow, ccol) int r0, r1, crow, ccol; { char *p; unsigned v; p = (char *) 0xc400; v = (unsigned) bfr; p[0] = v; p[1] = v >> 8; v = (unsigned) lptr; p[2] = v; p[3] = v >> 8; p[4] = nlines; p[5] = nlines >> 8; p[6] = top; p[7] = top >> 8; p[8] = blen; p[9] = blen >> 8; p[10] = leftcol; p[11] = leftcol >> 8; p[12] = crow; p[13] = ccol; p[14] = r0; p[15] = r1; mlgo(MLSCRN); return 0; } /* memmove: n bytes from 'from' to 'to', overlap safe */ mlmove(from, to, n) unsigned from, to, n; { char *p; if (n == 0) return 0; p = (char *) 0xc400; p[0] = from; p[1] = from >> 8; p[2] = to; p[3] = to >> 8; p[4] = n; p[5] = n >> 8; mlgo(MLBMOVE); return 0; } /* add d to n words starting at address a (line index fix-ups) */ mladj(a, n, d) unsigned a, n, d; { char *p; if (n == 0) return 0; p = (char *) 0xc400; p[0] = a; p[1] = a >> 8; p[2] = n; p[3] = n >> 8; p[4] = d; p[5] = d >> 8; mlgo(MLLADJ); return 0; } /* next key from the kernal buffer, or 0 */ mlkey() { return mlgo(MLKPOP); }