Here is the latest and greatest. The speed is much more usable now on an unexpanded QL. Here are the times for TEST2_BAS (input 25) on my unexpanded QL
So almost 3 times faster than the previous version and running at about 3x realtime. Here is the code that replaced the previous ZXputc. The previous one would go through 40 bits of information to figure out if a bit is on or off and, on average, would do 16+ block calls whereas the new one, on average, does 5 block calls. A good example of revisiting a bad algorithm and improving it...I kept thinking there had to be a better way and it dawned on me this morning.
Code: Select all
/* prints single ZX81 font character */
ZXputc (ch, ink, pap)
char ch; int ink, pap;
{
block(stdout, 8, 8, col, row, pap);
switch (ch)
{
case '"':
block(stdout, 1, 2, col+3, row+1, ink);
block(stdout, 1, 2, col+6, row+1, ink);
return;
case '#':
block(stdout, 3, 1, col+3, row+1, ink);
block(stdout, 1, 4, col+2, row+2, ink);
block(stdout, 1, 1, col+6, row+2, ink);
block(stdout, 4, 1, col+1, row+3, ink);
block(stdout, 6, 1, col+1, row+6, ink);
return;
case '$':
block(stdout, 5, 5, col+2, row+2, ink);
block(stdout, 4, 1, col+3, row+3, pap);
block(stdout, 4, 1, col+2, row+5, pap);
block(stdout, 1, 7, col+4, row+1, ink);
return;
case ':':
block(stdout, 1, 1, col+3, row+3, ink);
block(stdout, 1, 1, col+3, row+6, ink);
return;
case '(':
block(stdout, 1, 1, col+5, row+1, ink);
block(stdout, 1, 4, col+4, row+2, ink);
block(stdout, 1, 1, col+5, row+6, ink);
return;
case ')':
block(stdout, 1, 1, col+2, row+1, ink);
block(stdout, 1, 4, col+3, row+2, ink);
block(stdout, 1, 1, col+2, row+6, ink);
return;
case '>':
block(stdout, 1, 1, col+2, row+2, ink);
block(stdout, 1, 1, col+3, row+3, ink);
block(stdout, 1, 1, col+4, row+4, ink);
block(stdout, 1, 1, col+3, row+5, ink);
block(stdout, 1, 1, col+2, row+6, ink);
return;
case '<':
block(stdout, 1, 1, col+5, row+2, ink);
block(stdout, 1, 1, col+4, row+3, ink);
block(stdout, 1, 1, col+3, row+4, ink);
block(stdout, 1, 1, col+4, row+5, ink);
block(stdout, 1, 1, col+5, row+6, ink);
return;
case '=':
block(stdout, 5, 1, col+2, row+3, ink);
block(stdout, 5, 1, col+2, row+5, ink);
return;
case '+':
block(stdout, 1, 5, col+4, row+2, ink);
case '-':
block(stdout, 5, 1, col+2, row+4, ink);
return;
case '_':
block(stdout, 5, 1, col+2, row+6, ink);
return;
case '*':
block(stdout, 1, 3, col+4, row+3, ink);
block(stdout, 5, 1, col+2, row+4, ink);
block(stdout, 1, 1, col+3, row+2, ink);
block(stdout, 1, 1, col+5, row+2, ink);
block(stdout, 1, 1, col+3, row+6, ink);
block(stdout, 1, 1, col+5, row+6, ink);
return;
case '/':
block(stdout, 1, 1, col+6, row+2, ink);
block(stdout, 1, 1, col+5, row+3, ink);
block(stdout, 1, 1, col+4, row+4, ink);
block(stdout, 1, 1, col+3, row+5, ink);
block(stdout, 1, 1, col+2, row+6, ink);
return;
case ';':
block(stdout, 1, 1, col+3, row+2, ink);
block(stdout, 1, 2, col+3, row+5, ink);
block(stdout, 1, 1, col+2, row+7, ink);
return;
case ',':
block(stdout, 1, 2, col+4, row+5, ink);
block(stdout, 1, 1, col+3, row+7, ink);
return;
case '.':
block(stdout, 2, 2, col+3, row+5, ink);
return;
case ' ':
return;
/* NUMBERS */
/*-> case '0': <-- moved before letter O */
case '1':
block(stdout, 2, 1, col+3, row+1, ink);
block(stdout, 1, 1, col+2, row+2, ink);
block(stdout, 1, 4, col+4, row+2, ink);
block(stdout, 5, 1, col+2, row+6, ink);
return;
case '2':
block(stdout, 4, 1, col+2, row+1, ink);
block(stdout, 1, 1, col+1, row+2, ink);
block(stdout, 1, 2, col+6, row+2, ink);
block(stdout, 4, 1, col+2, row+4, ink);
block(stdout, 1, 1, col+1, row+5, ink);
block(stdout, 6, 1, col+1, row+6, ink);
return;
case '3':
block(stdout, 4, 1, col+2, row+1, ink);
block(stdout, 1, 1, col+1, row+2, ink);
block(stdout, 1, 1, col+6, row+2, ink);
block(stdout, 2, 1, col+4, row+3, ink);
block(stdout, 1, 2, col+6, row+4, ink);
block(stdout, 1, 1, col+1, row+5, ink);
block(stdout, 4, 1, col+2, row+6, ink);
return;
case '4':
block(stdout, 1, 6, col+4, row+1, ink);
block(stdout, 1, 1, col+3, row+2, ink);
block(stdout, 1, 1, col+2, row+3, ink);
block(stdout, 1, 1, col+1, row+4, ink);
block(stdout, 6, 1, col+1, row+5, ink);
return;
case '5':
block(stdout, 6, 1, col+1, row+1, ink);
block(stdout, 1, 2, col+1, row+2, ink);
block(stdout, 4, 1, col+2, row+3, ink);
block(stdout, 1, 2, col+6, row+4, ink);
block(stdout, 1, 1, col+1, row+5, ink);
block(stdout, 4, 1, col+2, row+6, ink);
return;
case '6':
block(stdout, 4, 1, col+2, row+1, ink);
block(stdout, 1, 4, col+1, row+2, ink);
block(stdout, 4, 1, col+2, row+3, ink);
block(stdout, 1, 2, col+6, row+4, ink);
block(stdout, 4, 1, col+2, row+6, ink);
return;
case '7':
block(stdout, 6, 1, col+1, row+1, ink);
block(stdout, 1, 1, col+6, row+2, ink);
block(stdout, 1, 1, col+5, row+3, ink);
block(stdout, 1, 1, col+4, row+4, ink);
block(stdout, 1, 2, col+3, row+5, ink);
return ;
case '8':
block(stdout, 4, 6, col+2, row+1, ink);
block(stdout, 6, 4, col+1, row+2, ink);
block(stdout, 4, 1, col+2, row+2, pap);
block(stdout, 4, 2, col+2, row+4, pap);
block(stdout, 1, 1, col+1, row+3, pap);
block(stdout, 1, 1, col+6, row+3, pap);
return ;
case '9':
block(stdout, 4, 1, col+2, row+1, ink);
block(stdout, 1, 2, col+1, row+2, ink);
block(stdout, 1, 4, col+6, row+2, ink);
block(stdout, 4, 1, col+2, row+4, ink);
block(stdout, 4, 1, col+2, row+6, ink);
return;
/* LETTERS */
case 'A':
block(stdout, 4, 1, col+2, row+1, ink);
block(stdout, 1, 5, col+1, row+2, ink);
block(stdout, 1, 5, col+6, row+2, ink);
block(stdout, 4, 1, col+2, row+4, ink);
return;
case 'B':
block(stdout, 5, 6, col+1, row+1, ink);
block(stdout, 4, 1, col+2, row+2, pap);
block(stdout, 1, 1, col+6, row+2, ink);
block(stdout, 4, 2, col+2, row+4, pap);
block(stdout, 1, 2, col+6, row+4, ink);
return;
/*->*/case 'G':
block(stdout, 3, 1, col+4, row+4, ink);
case 'C':
block(stdout, 4, 1, col+2, row+1, ink);
block(stdout, 1, 4, col+1, row+2, ink);
block(stdout, 1, 1, col+6, row+2, ink);
block(stdout, 1, 1, col+6, row+5, ink);
block(stdout, 4, 1, col+2, row+6, ink);
return;
case 'D':
block(stdout, 4, 1, col+1, row+1, ink);
block(stdout, 1, 4, col+1, row+2, ink);
block(stdout, 1, 1, col+5, row+2, ink);
block(stdout, 1, 2, col+6, row+3, ink);
block(stdout, 1, 1, col+5, row+5, ink);
block(stdout, 4, 1, col+1, row+6, ink);
return;
case 'E':
block(stdout, 5, 1, col+2, row+6, ink);
case 'F':
block(stdout, 6, 1, col+1, row+1, ink);
block(stdout, 1, 5, col+1, row+2, ink);
block(stdout, 4, 1, col+2, row+3, ink);
return;
/*-> case 'G': <-- moved before letter C */
case 'H':
block(stdout, 1, 6, col+1, row+1, ink);
block(stdout, 4, 1, col+2, row+3, ink);
block(stdout, 1, 6, col+6, row+1, ink);
return;
case 'I':
block(stdout, 5, 1, col+2, row+1, ink);
block(stdout, 1, 4, col+4, row+2, ink);
block(stdout, 5, 1, col+2, row+6, ink);
return;
/*->*/case 'U':
block(stdout, 1, 3, col+1, row+1, ink);
case 'J': /* adds extra block call 3 vs 4 */
block(stdout, 1, 2, col+1, row+4, ink);
block(stdout, 4, 1, col+2, row+6, ink);
block(stdout, 1, 5, col+6, row+1, ink);
return;
case 'K':
block(stdout, 1, 6, col+1, row+1, ink);
block(stdout, 1, 1, col+5, row+1, ink);
block(stdout, 1, 1, col+4, row+2, ink);
block(stdout, 2, 1, col+2, row+3, ink);
block(stdout, 1, 1, col+4, row+4, ink);
block(stdout, 1, 1, col+5, row+5, ink);
block(stdout, 1, 1, col+6, row+6, ink);
return;
case 'L':
block(stdout, 1, 6, col+1, row+1, ink);
block(stdout, 5, 1, col+2, row+6, ink);
return;
case 'M':
block(stdout, 1, 6, col+1, row+1, ink);
block(stdout, 1, 6, col+6, row+1, ink);
block(stdout, 1, 1, col+2, row+2, ink);
block(stdout, 1, 1, col+5, row+2, ink);
block(stdout, 2, 1, col+3, row+3, ink);
return;
case 'N':
block(stdout, 1, 6, col+1, row+1, ink);
block(stdout, 1, 1, col+2, row+2, ink);
block(stdout, 1, 1, col+3, row+3, ink);
block(stdout, 1, 1, col+4, row+4, ink);
block(stdout, 1, 1, col+5, row+5, ink);
block(stdout, 1, 6, col+6, row+1, ink);
return;
/*->*/case '0': /* zero */
block(stdout, 1, 1, col+5, row+2, ink);
block(stdout, 1, 1, col+4, row+3, ink);
block(stdout, 1, 1, col+3, row+4, ink);
block(stdout, 1, 1, col+2, row+5, ink);
case 'O':
letter_O:
block(stdout, 4, 1, col+2, row+1, ink);
block(stdout, 1, 4, col+1, row+2, ink);
block(stdout, 1, 4, col+6, row+2, ink);
block(stdout, 4, 1, col+2, row+6, ink);
return;
/*->*/case 'R':
block(stdout, 1, 1, col+5, row+5, ink);
block(stdout, 1, 1, col+6, row+6, ink);
case 'P':
block(stdout, 5, 1, col+1, row+1, ink);
block(stdout, 1, 5, col+1, row+2, ink);
block(stdout, 4, 1, col+2, row+4, ink);
block(stdout, 1, 2, col+6, row+2, ink);
return;
case 'Q':
block(stdout, 1, 1, col+3, row+4, ink);
block(stdout, 1, 1, col+4, row+5, ink);
goto letter_O;
/*-> case 'R': <-- moved before letter P */
case 'S':
block(stdout, 4, 1, col+2, row+1, ink);
block(stdout, 1, 1, col+1, row+2, ink);
block(stdout, 4, 1, col+2, row+3, ink);
block(stdout, 1, 2, col+6, row+4, ink);
block(stdout, 1, 1, col+1, row+5, ink);
block(stdout, 4, 1, col+2, row+6, ink);
return;
case 'T':
block(stdout, 7, 1, col, row+1, ink);
block(stdout, 1, 5, col+3, row+2, ink);
return;
/*-> case 'U': <-- moved before letter J */
case 'V':
block(stdout, 1, 4, col+1, row+1, ink);
block(stdout, 1, 4, col+6, row+1, ink);
block(stdout, 1, 1, col+2, row+5, ink);
block(stdout, 1, 1, col+5, row+5, ink);
block(stdout, 2, 1, col+3, row+6, ink);
return;
case 'W':
block(stdout, 1, 5, col+1, row+1, ink);
block(stdout, 1, 5, col+6, row+1, ink);
block(stdout, 2, 1, col+3, row+5, ink);
block(stdout, 1, 1, col+2, row+6, ink);
block(stdout, 1, 1, col+5, row+6, ink);
return;
case 'X':
block(stdout, 1, 1, col+1, row+1, ink);
block(stdout, 1, 1, col+6, row+1, ink);
block(stdout, 1, 1, col+2, row+2, ink);
block(stdout, 1, 1, col+5, row+2, ink);
block(stdout, 2, 2, col+3, row+3, ink);
block(stdout, 1, 1, col+2, row+5, ink);
block(stdout, 1, 1, col+5, row+5, ink);
block(stdout, 1, 1, col+1, row+6, ink);
block(stdout, 1, 1, col+6, row+6, ink);
return;
case 'Y':
block(stdout, 1, 1, col, row+1, ink);
block(stdout, 1, 1, col+6, row+1, ink);
block(stdout, 1, 1, col+1, row+2, ink);
block(stdout, 1, 1, col+5, row+2, ink);
block(stdout, 1, 1, col+2, row+3, ink);
block(stdout, 1, 1, col+4, row+3, ink);
block(stdout, 1, 3, col+3, row+4, ink);
return;
case 'Z':
block(stdout, 6, 1, col+1, row+1, ink);
block(stdout, 1, 1, col+5, row+2, ink);
block(stdout, 1, 1, col+4, row+3, ink);
block(stdout, 1, 1, col+3, row+4, ink);
block(stdout, 1, 1, col+2, row+5, ink);
block(stdout, 6, 1, col+1, row+6, ink);
return;
default:
block(stdout, 4, 1, col+2, row+1, ink);
block(stdout, 1, 1, col+1, row+2, ink);
block(stdout, 1, 1, col+6, row+2, ink);
block(stdout, 1, 1, col+5, row+3, ink);
block(stdout, 1, 1, col+4, row+4, ink);
block(stdout, 1, 1, col+4, row+6, ink);
return;
}
}
So I'm basically drawing each character as if I were using pen and paper...pretty neat. I also fixed the stipple pattern and am using paper 246 and 248 with block (so 32 block calls are now 2 block calls). It previously took 20 seconds to print a half-screen full and now takes about 3.5 seconds.