10  '------------------------------------------------------------------------
20  '| PIXGEN.BAS, Version 1.0, 10 April 1984                               |
30  '|                                                                      |
40  '| With this program, you can design literal or graphic characters on   |
50  '| the CRT.  The program calculates the byte values for each column of  |
60  '| dots for output to the Epson printer.  You can store, retrieve,      |
70  '| edit, and test-print your creations.  You can also print a full      |
80  '| listing of your font file.   The program creates two files on disk   |
90  '| B: "FONT.PIX", which is a random access file containing the ascii    |
100 '| printable codes, and "PIXRN.DAT", which stores the last record number|
110 '| of the random access file. The variables are listed beg.line 60000.  |
120 '|                                                                      |
130 '| By Jim Shoemaker,1743-B So Hayes St Arl VA 22202 (703) 892-8567      |
140 '------------------------------------------------------------------------
200 '                             main program
202 '
204 CLEAR
205 GOSUB 60000                                   'initialize variables
206 ON ERROR GOTO 235
208 PRINT CURSOFF$                                'turn off cursor temporarily
210 PRINT CL$                                     'clear screen
212 RC$=FNS$(2,50)                                'row/column coordinates
215 PRINT RC$ "Designing new char "
220 GOSUB 1000                                    'draw grid
230 GOSUB 1100                                    'display menu
232 PRINT CURSON$                                 'turn cursor back on
235 R=2:C=2                                       'set row/col coordinates
240 RC$=FNS$(R,C):PRINT RC$;                      'position cursor
260 Q$=INKEY$                                     'accept keyboard input
261 IF Q$="" THEN 260                             'null input
262 Q = ASC(Q$)
270 GOTO 350                                      'test if statements
315 END                               
316 '
345 '-------------------------------- menu selections-----------------------
350 IF Q = 46 THEN GOSUB 1500:GOTO 260            'turn dot cell on/off
355 IF Q = 83 OR Q = 115 THEN GOTO 1900           'save
360 IF Q = 84 OR T = 116 THEN GOTO 1700           'test print char 
365 IF Q = 76 OR Q = 108 THEN GOTO 9000           'list char codes
370 IF Q = 99 OR Q = 67 THEN CL=1:GOTO 600        'clear char
375 IF Q = 80 OR Q = 112 THEN GOTO 10200          'print char chart
380 IF Q = 81 OR Q = 113 THEN GOTO 1600           'quit
385 IF Q = 73 OR Q = 105 THEN GOTO 600            'invert char  
390 IF Q = 69 OR Q = 101 THEN GOTO 1800           'edit char from disk
391 IF Q = 55 THEN GOTO 235                       'home cursor
392 IF Q = 57 THEN R=2:C=CM+2:GOTO 240            'cursor top right corner
393 IF Q = 49 THEN R=RM+2:C=2:GOTO 240            'cursor bottom left corner
394 IF Q = 51 THEN R=RM+2:C=CM+2:GOTO 240         'cursor bottom right corner
395 IF Q = 52 THEN R=R:C=2:GOTO 240               'cursor to left margin
396 IF Q = 54 THEN R=R:C=CM+2:GOTO 240            'cursor to right margin
397 IF Q = 56 THEN R=2:C=C:GOTO 240               'cursor to top margin
398 IF Q = 50 THEN R=RM+2:C=C:GOTO 240            'cursor to bottom margin
399 GOSUB 1300:GOTO 260                           'arrow key pressed
400 '--------------------------------- file field statements-----------------
402 '
410 FIELD#2,3 AS FB0$,3 AS FB1$,3 AS FB2$,3 AS FB3$,3 AS FB4$,3 AS FB5$,3 AS FB6$,3 AS FB7$,3 AS FB8$,3 AS FB9$,3 AS FB10$ 
420 RETURN
600 '--------------------------------- invert or clear char -----------------
601 '
605 'If menu selection is "c" then ONOFF = 0 ELSE W
610 OUT 0,65
620 FOR C = 0 TO CM
630   FOR R = 0 TO RM
640   P = (CH+O)+((2+R)*W)+(2+C)
650    CB = PEEK(P)                                'look at cell attribute
655    IF CL = 1 THEN ONOFF = 0 ELSE ONOFF = W
660    IF CB < W THEN CB = CB + ONOFF ELSE CB = CB - W
670    POKE P,CB
680   NEXT R
690 NEXT C
692 OUT 0,1
693 EOPTION=0
694 GOTO 235
999 '
1000 '-------------------------------- draw grid ----------------------------
1003 '
1010 U = CH+(2*W)+2                                'starting cell of grid
1020 O = 4096                                      'diff from attribute bank
1025 OUT 0,65                                      'enable video bank
1030  FOR C = 0 TO CM
1040   FOR R = 0 TO RM
1045     P=U+(R*W)+C
1050     POKE P,D:POKE P+O,H                       'draw grid
1060   NEXT R
1070 NEXT C
1080 OUT 0,1                                       'restore bank
1090 RETURN 
1099 '
1100 '-------------------------------- display menu ------------------------
1102 '
1105 RC$=FNS$(11,2)
1110 PRINT RC$ "WELCOME TO PIXGEN"
1115 PRINT
1120 PRINT "  Use cursors to move around grid."
1122 PRINT "  Use number pad to skip to corners (odd) and sides (even)"     
1125 PRINT
1130 PRINT '  (.)  =  DOT on/off             's' =  Save char on disk"
1140 PRINT "  't'  =  Test char on printer   'e' =  Edit char from disk"
1150 PRINT "  'l'  =  List char codes        'p' =  Print char code chart"
1160 PRINT "  'i'  =  Invert char            'c' =  Clear char
1170 PRINT "  'q'  =  Quit"
1180 RETURN
1299 '
1300 '-------------------------------- cursor position ---------------------
1311 '
1340 IF Q = 12 THEN C = C + 1: R = R               'cursor right
1350 IF Q = 10 THEN R = R + 1: C = C               'cursor down 
1360 IF Q = 11 THEN R = R - 1: C = C               'cursor up
1365 IF Q = 8  THEN C = C - 1: R = R               'cursor left
1370 IF C = CM+3 THEN C = 2: R = R                 'margin checks
1380 IF C = 1 THEN C = CM+2: R = R
1390 IF R = RM+3 THEN R = 2: C = C
1400 IF R = 1 THEN R = RM+2: C = C
1410 RC$ = FNS$(R,C):PRINT RC$;:RETURN             'reset cursor
1499 '
1500 '-------------------------------- turn dots on/off --------------------
1502 '
1505 OUT 0,65                                      'enable video 
1508 P = CH + O + (R*W) + C
1510 CB = PEEK(P)                                  'look at cell attribute
1520 IF CB < W THEN CB=CB+W ELSE CB=CB-W           'if bright, make dim
1530 POKE P, CB            
1535 OUT 0,1                                       'restore video state
1540 RETURN
1599 '
1600 '-------------------------------- quit routine ------------------------
1610 '               
1615 RC$=FNS$(22,0)
1620 PRINT RC$:PRINT "Quit? (y/n)";
1630 Q$ = INKEY$: IF Q$ = "" THEN 1630
1640 IF ASC(Q$) = 89 OR ASC(Q$) = 121 THEN 1680 ELSE 1650
1645 RC$=FNS$(22,0)
1650 PRINT RC$:PRINT SPC(11):GOTO 235
1680 PRINT CL$ 
1682 RC$=FNS$(10,10)
1685 PRINT RC$ "To restart, type 'RUN',"
1690 GOTO 315                                      'end
1699 '
1700 '-------------------------------- test print char ---------------------
1702 '
1703 PPF=1
1704 RC$=FNS$(22,0)
1705 PRINT RC$
1706 PRINT "Be sure printer is on line.  When ready, press any key.";
1707 Q$=INPUT$(1)
1709 PRINT RC$:PRINT SPC(65)
1710 RC$=FNS$(2,50)
1711 PRINT RC$
1712 PRINT RC$ "Testing char nr. "+F$;
1715 C=2:R=2:GOSUB 2120
1720 LPRINT ESC$+"L"+CHR$(CM+1)+CHR$(0);           'prepare printer buffer
1730 FOR C=0 TO CM
1740 LPRINT CHR$(B(C));                            'output byte to printer
1750 NEXT C
1775 PPF=0
1777 LPRINT ESC$+"@";                              'reset printer codes
1780 GOTO 235                                      'return to menu
1799 '
1800 '-------------------------------- load pixel --------------------------
1801 '
1811 CLOSE
1815 OPEN "I",#3,"B:PIXRN.DAT":INPUT#3,RN:CLOSE#3
1818 RC$=FNS$(22,0)
1820 PRINT RC$ "Ascii code you wish to edit? (000 - ";
1822 IF RN<10 THEN PRINT USING "00#";RN;:GOTO 1829
1824 IF RN>9 AND RN<99 THEN PRINT USING "0##";RN;:GOTO 1829
1826 IF RN>99 THEN PRINT USING "###";RN;
1829 PRINT ")";
1830 INPUT;F$
1832 RC$ = FNS$(22,0)
1835 PRINT RC$ + SP$
1840 IF LEN(F$) <> 3 THEN PRINT BEEP$;:GOTO 235    'try again
1845 RC$ = FNS$(2,50)
1850 PRINT RC$ + "Editing char nr. ";F$
1860 OPEN "R",#2,"B:FONT.PIX",N                    'open random access file
1862 GOSUB 400                                     'field statements
1864 COUNT=VAL(F$)
1865 GET#2,COUNT+1                                 'bring in a record
1866 '
1872 B(0) = CVI(FB0$)                              'convert variables
1873 B(1) = CVI(FB1$)
1874 B(2) = CVI(FB2$)
1875 B(3) = CVI(FB3$)
1876 B(4) = CVI(FB4$)
1877 B(5) = CVI(FB5$)
1878 B(6) = CVI(FB6$)
1879 B(7) = CVI(FB7$)
1880 B(8) = CVI(FB8$)
1881 B(9) = CVI(FB9$)
1882 B(10)=CVI(FB10$)
1883 '
1884 OUT 0,65                                      'enable video
1885 FOR R = 0 TO RM                               'calculate whether each
1886   FOR C = 0 TO CM                             'bit is on or off
1887    IF B(C)/(2^(RM-R))=>1 THEN D(C,R)=W ELSE D(C,R)=0
1888    IF (2^(RM-R)) > B(C) THEN B(C)=B(C) ELSE B(C)=B(C)-(2^(RM-R))
1889    P=U+(R*W)+C:POKE P,D:POKE P+O,D(C,R)
1890  NEXT C
1892 NEXT R
1893 OUT 0,1                                       'restore bank
1894 CLOSE
1897 GOTO 235                                      'back to menu
1899 '
1900 '-------------------------------- save -------------------------------
1915 '
1918 LET GARBAGE = FRE("A")
1920 RC$=FNS$(22,0)
1930 PRINT RC$ "Ascii code for byte? (3 digits less than 256)";
1935 INPUT;F$
1940 RC$=FNS$(22,0)
1950 PRINT RC$ + SP$
1956 IF LEN(F$) <> 3 THEN PRINT BEEP$;:GOTO 235   'try again
1959 RC$=FNS$(2,50):PRINT RC$ "  Saving char nr.";F$;
2000 '
2010 'Begin saving byte values on disk
2015 ' 
2120 COUNT = 14                                    'screen pos for msg
2122 OUT 0,65                                      'enable video
2125 FOR C = 0 TO CM
2130  FOR R = 0 TO RM
2140  P = (U + O) + (R*W) + C
2150   CB = PEEK(P)
2160   IF CB > W THEN D(R,C) = 2 ^ (RM-R) ELSE D(R,C) = 0
2165   CL(R,C)=P-O:AL(R,C)=P
2167  AB(R,C)=CB:IF PPF=1 THEN 2170
2170  NEXT R
2175 B(C)=D(0,C)+D(1,C)+D(2,C)+D(3,C)+D(4,C)+D(5,C)+D(6,C)+D(7,C)
2176 COUNT=COUNT+3
2178 PRINT FNS$(C+2,COUNT);USING "####";B(C)
2180 NEXT C
2190 OUT 0,1                                       'restore bank
2192 COL = 0
2195 IF PPF=1 THEN RETURN
2204 '
2205 ' store codes into random access file
2206 '
2210 OPEN "R",#2,"B:FONT.PIX",N
2215 OPEN "I",#3,"B:PIXRN.DAT"
2218 INPUT#3,RN:CLOSE#3                            'get stored record total
2220 GOSUB 400                                     'field statements
2221 '
2260 LSET FB0$=MKI$(B(0))
2270 LSET FB1$=MKI$(B(1))
2280 LSET FB2$=MKI$(B(2))
2290 LSET FB3$=MKI$(B(3))
2300 LSET FB4$=MKI$(B(4))
2310 LSET FB5$=MKI$(B(5))
2320 LSET FB6$=MKI$(B(6))
2330 LSET FB7$=MKI$(B(7))
2340 LSET FB8$=MKI$(B(8))
2350 LSET FB9$=MKI$(B(9))
2360 LSET FB10$=MKI$(B(10))
2361 '
2369 COUNT=(VAL(F$))+1
2370 PUT#2,COUNT                                   'write code record to file
2375 CLOSE#3
2378 IF VAL(F$)>RN THEN RN=VAL(F$)
2380 OPEN "O",#3,"B:PIXRN.DAT":PRINT#3,RN          'store new record total
2390 CLOSE
2395 PRINT ESC$+LOCK$;                             'lock keyboard for a bit
2396 FOR X=1 TO 100:COUNT=COUNT+X^2:NEXT X         'time filler
2397 PRINT ESC$+UNLOCK$;                           'unlock keyboard again
2398 PRINT BEEP$;     
2400 GOTO 235                                      'back to original menu
8999 '
9000 ' ------------------------------ view pixel file ---------------------
9001 '
9005 PRINT CL$
9010 OPEN "R",#2,"B:FONT.PIX",N
9020 GOSUB 400                                     'field statements
9050 OPEN "I",#3,"B:PIXRN.DAT"
9060 INPUT#3,RN
9065 COUNT=0                                       'page counter
9070 FOR X = 1 TO RN+1
9080   GET#2,X
9085   COUNT=COUNT+1:IF COUNT=22 THEN COUNT=0 ELSE 9110             
9090   PRINT:PRINT "Press any key to see next page...":Q$=INPUT$(1)
9110   GOSUB 10000                                 'prog/field var conversions
9190   PRINT USING "####";X-1;
9192   PRINT " -- ";
9195   PRINT USING "####";B0; 
9197   PRINT USING "####";B1; 
9199   PRINT USING "####";B2; 
9200   PRINT USING "####";B3; 
9210   PRINT USING "####";B4; 
9212   PRINT USING "####";B5; 
9214   PRINT USING "####";B6; 
9216   PRINT USING "####";B7;
9217   PRINT USING "####";B8;
9218   PRINT USING "####";B9;
9219   PRINT USING "####";B10 
9220 NEXT X
9225 PRINT:PRINT "Press any key to return to grid screen...";
9230 CLOSE
9240 Q$=INKEY$:IF Q$="" THEN 9240          
9250 GOTO 210                                      'back to menu
9999 '
10000 '---------------------------- conversions ---------------------------
10001 '
10110   B0 = CVI(FB0$)
10120   B1 = CVI(FB1$)
10130   B2 = CVI(FB2$)
10140   B3 = CVI(FB3$)
10150   B4 = CVI(FB4$)
10160   B5 = CVI(FB5$)
10170   B6 = CVI(FB6$)
10180   B7 = CVI(FB7$)
10181   B8 = CVI(FB8$)
10182   B9 = CVI(FB9$)
10183   B10=CVI(FB10$)
10190 RETURN
10199 '
10200 '---------------------------- print code chart ----------------------
10201 '
10205 RC$=FNS$(22,0)
10210 PRINT RC$ "Press any key when printer is on-line...          ";
10220 Q$=INPUT$(1)
10222 PRINT RC$:PRINT SPC(50);
10225 COUNT=0
10230 OPEN "R",#2,"B:FONT.PIX",N
10235 OPEN "I",#3,"B:PIXRN.DAT":INPUT#3,RN:CLOSE#3
10240 '
10245   COUNT=COUNT+1
10247   IF COUNT>RN THEN 10490                     'end of file reached
10250   GOSUB 400                                  'field statements
10260   GET#2,COUNT
10270   GOSUB 10000                                'conversions
10280   LPRINT ESC$+"L"+CHR$(CM+1)+CHR$(0);           'prepare printer buffer
10290   LPRINT CHR$(B0);CHR$(B1);CHR$(B2);CHR$(B3);CHR$(B4);CHR$(B5);
10300   LPRINT CHR$(B6);CHR$(B7);CHR$(B8);CHR$(B9);CHR$(B10);
10400   LPRINT "   ASCII=";
10402   LPRINT USING "####";COUNT-1;
10404   LPRINT "  PRINTER CODES = ";
10410   LPRINT USING "####";B0;
10420   LPRINT USING "####";B1;
10430   LPRINT USING "####";B3;
10440   LPRINT USING "####";B4;
10450   LPRINT USING "####";B5;
10460   LPRINT USING "####";B6;
10470   LPRINT USING "####";B7;
10472   LPRINT USING "####";B8;
10474   LPRINT USING "####";B9;
10476   LPRINT USING "####";B10
10480 GOTO 10240                                   'loop
10490 LPRINT ESC$+"@"                              'reset printer
10500 CLOSE
10510 GOTO 235                                     'return to menu
10520 '
60000 '--------------------------------- variables -------------------------
60005 '
60008 W = 128                                      'page width
60010 L = 22                                       'page length 
60020 CH = 49152!                                  'top of character memory
60030 AH = 53258!                                  'top of attribute memory
60035 S = 32                                       'screen offset
60037 ESC$ = CHR$(27)                              'escape
60038 CL$ = CHR$(26)                               'clear screen
60040 DEF FNS$(R,C)=ESC$+"="+CHR$(S+R)+CHR$(S+C)   'locate cursor
60050 H = 0                                        'half intensity mode
60060 DIM CL(8,11)                                 'character location
60070 DIM AB(8,11)                                 'attribute bit
60080 DIM AL(8,11)                                 'attribute location
60082 DIM B(11)                                    'bytes
60084 DIM D(11,11)                                 'dots
60090 PPF=0                                        'print routine flag
60095 BEEP$ = CHR$(7)                              'beeper sound
60100 'CB                                          'character bit
60110 'AB                                          'attribute bit
60115 'RC$                                         'cursor row/column address
60120 ONOFF = W                                    'bit on/off value
60130 CURSON$ = ESC$ + "." + "3"                   'turn cursor on
60140 CURSOFF$ = ESC$ + "." + "0"                  'turn cursor off
60150 RM = 7                                       'max rows dots -1
60160 CM = 10                                      'max cols dots -1
60170 COUNT = 0                                    'general counter
60180 'Q$                                          'general input variable
60190 D = 13                                       'dot graphic 
60200 CL = 0                                       'clear routine flag
60210 'Q                                           'ascii code variable
60212 N = (CM+1) * 3                               'record length
60214 F$ = "???"                                   'record i.d.
60216 SP$ = SPACE$(70)                             'blank spaces
60218 WIDTH 128                                    'display width
60220 LOCK$ = CHR$(35)                             'lock keyboard
60230 UNLOCK$ = CHR$(34)                           'unlock keyboard
60240 RETURN                                       'back to main program
60300 '------------------------ end of file --------------------------------
                          'back to main program
60300 '------------------------ end of file --