Home of the original IBM PC emulator for browsers.
[PCjs Machine "ibm5170"]
Waiting for machine "ibm5170" to load....
For anyone with an older Epson printer, this series of programs could
enhance your printing capabilities. While many of the current breed of
printers have graphics capabilities built in, someof the older Epsons
did not.
The programs on this disk allows the user to "grab" pictures or
graphics off the computer screen and print them out on your Epson,
Toshiba, or C. Itoh (in two sizes).
This disk also contains some patches to existing DOS routines, and
simplify or speedup some operations. In addition to the DOS and
printer utilities, there are some simple (but useful) communication
utilities.
System Requirements: Some programs require color graphics.
How to Start: To run an EXE or COM program, simply type its name and
press <ENTER>. To print a documentation file, type: COPY filename.ext
PRN (press enter) where filename is the name of the file, and ext is
the extension (TXT or DOC).
File Descriptions:
CALLGRAF BAS Program to call GRAFTRAX from Basic
COPYGRAF BAT Batch file to copy GRAFTRAX files to disk
CALLGRAF TXT ASCII version of CALLGRAF
SOUNDS BAS Generates different sounds - contains documentation
DOTABLE ASM Data file used by Graftrax
DOTS DAT Data file used by Graftrax
DOTDATA ASM Data file used by Graftrax
DOTS PRO Data file used by Graftrax
GRAFTRAX ASM Source code for Graftrax
GDEMO BAS Graphics demo program
GRAFTRAX COM Compiled version of Graftrax
GRAFTRAX BAS Basic code for Graftrax
NECGRAF COM NEC version of Graftrax
MAKEDOTS BAS Graphics display utility
GRCITOH COM C-ITOH version of Graftrax
GRAFTRAX DOC Documentation for Graftrax
NEWT ASM Source code for enhanced Toshiba Graftrax version
OKIGRAF ASM Source code for Okidata Graftrax program
NEWT COM Compiled Toshiba Graphtrax program
PRTFIX DOC Documentation file
PRTFIX COM Corrects "DEVICE TIMEOUT" errors with printer
POSTER BAS Prints large character posters
PEPATCH DOC Patch to IBM's Personal Editor
SHELL BAT Bat file used with BATMAN.BAS
SCROLL2 BAS Sample program
SCROLL1 BAS Sample program
SCROLL DOC Documentation file
SCROLL BLD Program file to "BLOAD" from BASIC
SCROLL ASM Scrolls specified area of display screen
QD DOC Documentation file
QD COM Quadram RAMDRIVE program - FOR QUADRAM BOARD ONLY
TOSHIBA COM Compiled version of Toshiba Graftrax
TOSHIBA DOC Documentation for Toshiba Graftrax programs
BATMAN BAS Sample menu/batch manager program; requires SHELL.BAT
FK203 ASM Source code for FK203.EXE
HANG COM Hangs up Hayes Smartmodem
FK203 EXE Function key reassignment program for DOS 2.0
HOST DOC Documentation file for HOST.BAS
HOST BAS Communication program for remote access
TOSHIBA ASM Source code for original Toshiba Graftrax program
OKIGRAF COM Compiled version of Okidata Graphtrax
READ ME Author's notes on Graftrax routines
BSR DAT Data file for BSR.BAS
BUZOFF COM Turn off paper out buzzer on Epson
CVTHEX EXE Binary/hex conversion for files larger than 32K
COMPRS COM Enables compressed print on Epson
DIR DAT Sample data file
DIR BAS Disk cataloging program - very colorful
DIAL COM Dials Hayes Smartmodem
DCPATCH DOC Patch for DISKCOPY.COM 2.0
DIR DOC Documentation file
BATMAN DOC Documentation file
BSR BAS Simple program to drive ABM/BSR controller
10 'BATMAN.BAS -- Copyright M-SQUARED SYSTEMS, Inc. -1982
20 '
30 'This routine illustrates a method of adding MENU processing to DOS.
40 '
50 'Any user is hereby granted a free, non-exclusive license to use this
60 'program and to copy, modify or distribute it, so long as no charge is
70 'made for such copies, and the original author is acknowledged.
80 '
90 'W.B. Malthouse, V.P. - 5918 Veranda Dr.,Springfield, Va. 22152
100 '(703) 451-2934
110 '
120 'NOTE: Replace all references to "SHELL.BAT" by any desired file name,
130 'or obtain the calling file name from the command line image.
140 '
150 CLEAR: CLOSE:DEFINT A-Z:KEY OFF:SCREEN 0,0,0:WIDTH 80:COLOR 7:CLS
160 ON ERROR GOTO 640
170 DIM L$(22)
180 COLOR 15
190 PRINT"Please select the desired function:":COLOR 7
200 OPEN "SHELL.BAT" FOR INPUT AS #1
210 NL=0
220 LINE INPUT #1,BATPROGRAM$
230 LINE INPUT #1,DOIT$
240 LINE INPUT #1,PAUSE$
250 LINE INPUT #1,RESTART$
260 PRINT
270 FOR I=1 TO 22
280 LINE INPUT#1,L$(I)
290 IJ=INSTR(L$(I),"-")
300 IF IJ=0 THEN T$="*NO EXPLANATION PROVIDED*" ELSE T$=MID$(L$(I),IJ+1)
310 IF IJ=0 THEN IJ=LEN(L$(I))-4 ELSE IJ=IJ-5
320 COLOR 15: PRINT MID$(L$(I),1,3);: COLOR 7: PRINT TAB(4) MID$(L$(I),4,IJ) TAB(21) T$
330 IF EOF(1) THEN GOTO 350
340 NEXT
350 'we now have the whole menu in core
360 NL=I+1
370 L$(NL)=STR$(NL)+" GOTO End - Exit to Batch Monitor":L$(NL)=MID$(L$(NL),2)
380 COLOR 15: PRINT MID$(L$(NL),1,3);: COLOR 7:PRINT TAB(4);MID$(L$(NL),9,4);
390 PRINT TAB(21) MID$(L$(NL),INSTR(L$(NL),"-")+1);
400 NL=NL-1
410 CLOSE #1
420 LOCATE 23,1,1,0,13:INPUT"===>";N
425 IF(N < 1) OR (N > NL+1) THEN LOCATE 23,7:PRINT SPACE$(2);:GOTO 420
440 'here we go
450 DOITX$=MID$(L$(N),4)
460 I=INSTR(DOITX$,"-")
470 IF I<>0 THEN DOITX$=MID$(DOITX$,1,I-1)
480 DOIT$=DOITX$
490 LOCATE 25,1,0:COLOR 31:PRINT"Selection: ";
500 PRINT DOIT$;:LOCATE 25,79,0
510 ON ERROR GOTO 0:LOCATE 25,1,0:PRINT SPACE$(79);:LOCATE 25,1,0:COLOR 15
520 PRINT"REWRITING ";RESTART$;" ";
530 OPEN "SHELL.BAT" FOR OUTPUT AS #1
540 ON ERROR GOTO 0
550 PRINT #1,BATPROGRAM$
560 PRINT #1,DOIT$
570 PRINT #1,PAUSE$
580 PRINT #1,RESTART$
590 FOR I=1 TO NL
600 PRINT #1,L$(I)
610 NEXT I
620 CLOSE #1
630 SYSTEM
640 'ERROR HANDLING SECTION
650 LOCATE 22,1:PRINT"Basic Error Code:" ERR " in line:" ERL;
660 SOUND 40,18: SOUND 40,18: SOUND 40,18: SOUND 40,2
670 IF ERL<>280 THEN ON ERROR GOTO 0: STOP
680 RESUME 280
Adding "MENU" Processing to DOS
by William B. Malthouse
The attached program, BATMAN.BAS, and the file
SHELL.BAT, show one possible way to enhance DOS to make it
appear that DOS 1.10 knows how to process a "MENU" to select
the next program to be executed, regardless of whether that
next "program" is a ".COM," ".EXE," ".BAS," or built in DOS
command. As the professors always tell us, "Suitable
extensions of this basic technique are left to the reader as
an exercise..."
The key to the technique is that DOS processes a .BAT
file one line at a time, and while executing a program
invoked in LINE 1, DOS is completely unaware that that
program might change LINE 2 before DOS regains control! DOS
always re-reads the .BAT file after every command, and does
not process the ORIGINAL version.
Our sample program, BATMAN.BAS, invoked in line 1 of the
file "SHELL.BAT," will illustrate the technique. BATMAN
simply reads the entire "SHELL.BAT" file, extracts the
"MENU" information from line 5 on, and presents the
(formatted) menu to the user.
When the user completes his menu choice, BATMAN simply
rewrites the entire "SHELL.BAT" file, but REPLACES LINE 2
with the text of the command chosen by the user from the
menu! BATMAN then simply closes up shop and returns to DOS.
On return from BATMAN, DOS re-reads the (altered)
"SHELL.BAT," and continues executing at LINE 2, thereby
executing the program chosen by the user and placed there by
BATMAN. The process will then continue until line 4 (SHELL)
is reached, at which point DOS goes back to the top and
invokes BATMAN again for another choice, etc!
NOTE: Since the file "SHELL.BAT" is read and re-written
every time through the cycle, it would be appropriate to
place it (and "BATMAN" on a "fast" electronic disk for
efficiency.
******************* SHELL.BAT *********************
BASICA BATMAN.BAS %0 %1 %2 %3 %4 %5 %6 %7 %8 %9 /s:512
beep
PAUSE - About to Restart SHELL.BAT -
SHELL
01 beep - sound beeper
02 cls - clear screen
03 sd - directory for default drive
04 sd a: - directory for drive A
05 sd b: - directory for drive B
06 sd c: - directory for drive C
07 sd d: - directory for drive D
08 sd e: - directory for electronic drive
09 beep - sound the beeper (again)
10 basica mons - Run monitor switch program
11 basica - Enter BASIC
12 ff - clear the line printer
10 CLEAR ,27848
20 CLS:BSR%=0:THREE%=3:Z%=1:KEY OFF
30 LOCATE 25,1:PRINT "Frame Unit Command Steps Time Wait - (Com 1=on,2=off,3=clr,4=all,5=br,6=dim)"
40 LOCATE 6,12:PRINT "AudioKrafters IBM PC/BSR interface"
50 DEF SEG=&HFF2
60 BLOAD "bsrcode.bin",0
70 OPEN "bsr.dat" FOR INPUT AS #1:TIME$="00:00:00"
80 FOR I=0 TO 10:INPUT#1,D%(I),F%(I),G%(I),T$(I),W%(I):NEXT I
90 FOR I=0 TO 10:IF F%(I)=-1 THEN CLOSE:END
100 E%(I)=F%(I)+16:C%(I)=G%(I)*2+1:IF E%(I)<21 THEN C%(I)=3
110 D%=D%(I):E%=E%(I):C%=C%(I):T$=T$(I)
120 TIM$=RIGHT$(TIME$,5):IF T$>TIM$ THEN GOTO 120
130 CALL BSR%(Z%,D%,THREE%)
140 CALL BSR%(Z%,E%,C%)
150 K=K+1:PRINT K TAB(8) D%(I) TAB(14) F%(I) TAB(21) G%(I) TAB(26) T$(I) TAB(33) W%(I) TAB(50) TIME$
160 FOR J=1 TO W%(I):NEXT J
170 NEXT I
180 GOTO 80
1 ' GRAFTRAX as a subroutine 9/21/84
10 DEFINT A-Z
20 GOSUB 300 ' draw some graphics for demo. not needed in your program.
30 ' Make sure variables used in this routine are defined BEFORE they are used,
32 ' in other words, put lines 60-110 in early in your program.
34 ' Integer variable descriptors, i.e. variable% should be used
36 ' if a DEFINT statement is not present.
38 '
40 ' ****************** SETUP **** use lines 60-120 in your program.
42 '
60 DATA &h55,&H8b,&Hec,&H8b,&H76,&H06,&H8b,&H1c,&H8b
70 DATA &He3,&Hcd,&H05,&H8b,&He5,&H5d,&Hca,&H02,&H00
80 X%=0 : Y%=0 : Z%=0 : GRAFTRAX%=0 : GRSEG!=0 : A$=""
90 DIM STACK%(50),CG%(10)
100 DEF SEG : Y% = VARPTR(CG%(0))
110 FOR X% = 0 TO 17 : READ Z% : POKE X% + Y% ,Z% : NEXT ' poke into an array
120 DEF SEG=0 : X%=PEEK(&H16) : Y%=PEEK(&H17) : DEF SEG : GRSEG!=X%+(256*Y%)
121 '
122 ' GRSEG is the segment where DOS put GRAFTRAX.COM
123 '
124 ' ***************** END of SETUP ********************************
125 '
130 INPUT "(s)mall or (L)ARGE or (e)nd";A$ : A$=LEFT$(A$,1) : IF A$="" THEN END
135 IF A$="e" OR A$="E" THEN COLOR 7,0 : END
140 IF A$="l" OR A$="L" OR A$="2" THEN X% = 2 ELSE X% = 1
145 GOSUB 160 : GOTO 130
147 '
150 ' ******** ACTUAL ROUTINE - use in your program. **********
151 '
152 ' This is the code to use GRAFTRAX as a subroutine.
153 '
154 ' The POKE in 170 sets which routine to do, can be POKEd once and
155 ' left alone until a different size picture is needed.
156 '
160 DEF SEG = GRSEG!
170 POKE &H10D,X% ' X%=1 for small, 2 for LARGE.
175 ' %H10d is a variable in GRAFTRAX.COM
180 DEF SEG
190 GRAFTRAX% = VARPTR(CG%(0)) : Y% = VARPTR(STACK%(50)) ' stack builds DOWN.
200 CALL GRAFTRAX%(Y%) ' y% is a pointer to a temporary stack,
205 ' since BASIC only leaves 16 bytes.
210 RETURN
222 '
224 ' *************************************************************
226 '
300 ' Get some graphics going for demo.
305 '
310 KEY OFF
320 SCREEN 1,0
330 COLOR 1,0 : CLS
340 CIRCLE (160,100),50,3 : CIRCLE (160,100),75,3 : PAINT (160,100),1,3 : PAINT(160,40),2,3 ' draw some graphics
350 RETURN
1 ' GRAFTRAX as a subroutine 9/21/84
10 DEFINT A-Z
20 GOSUB 300 ' draw some graphics for demo. not needed in your program.
30 ' Make sure variables used in this routine are defined BEFORE they are used,
32 ' in other words, put lines 60-110 in early in your program.
34 ' Integer variable descriptors, i.e. variable% should be used
36 ' if a DEFINT statement is not present.
38 '
40 ' ****************** SETUP **** use lines 60-120 in your program.
42 '
60 DATA &h55,&H8b,&Hec,&H8b,&H76,&H06,&H8b,&H1c,&H8b
70 DATA &He3,&Hcd,&H05,&H8b,&He5,&H5d,&Hca,&H02,&H00
80 X%=0 : Y%=0 : Z%=0 : GRAFTRAX%=0 : GRSEG!=0 : A$=""
90 DIM STACK%(50),CG%(10)
100 DEF SEG : Y% = VARPTR(CG%(0))
110 FOR X% = 0 TO 17 : READ Z% : POKE X% + Y% ,Z% : NEXT ' poke into an array
120 DEF SEG=0 : X%=PEEK(&H16) : Y%=PEEK(&H17) : DEF SEG : GRSEG!=X%+(256*Y%)
121 '
122 ' GRSEG is the segment where DOS put GRAFTRAX.COM
123 '
124 ' ***************** END of SETUP ********************************
125 '
130 INPUT "(s)mall or (L)ARGE or (e)nd";A$ : A$=LEFT$(A$,1) : IF A$="" THEN END
135 IF A$="e" OR A$="E" THEN COLOR 7,0 : END
140 IF A$="l" OR A$="L" OR A$="2" THEN X% = 2 ELSE X% = 1
145 GOSUB 160 : GOTO 130
147 '
150 ' ******** ACTUAL ROUTINE - use in your program. **********
151 '
152 ' This is the code to use GRAFTRAX as a subroutine.
153 '
154 ' The POKE in 170 sets which routine to do, can be POKEd once and
155 ' left alone until a different size picture is needed.
156 '
160 DEF SEG = GRSEG!
170 POKE &H10D,X% ' X%=1 for small, 2 for LARGE.
175 ' %H10d is a variable in GRAFTRAX.COM
180 DEF SEG
190 GRAFTRAX% = VARPTR(CG%(0)) : Y% = VARPTR(STACK%(50)) ' stack builds DOWN.
200 CALL GRAFTRAX%(Y%) ' y% is a pointer to a temporary stack,
205 ' since BASIC only leaves 16 bytes.
210 RETURN
222 '
224 ' *************************************************************
226 '
300 ' Get some graphics going for demo.
305 '
310 KEY OFF
320 SCREEN 1,0
330 COLOR 1,0 : CLS
340 CIRCLE (160,100),50,3 : CIRCLE (160,100),75,3 : PAINT (160,100),1,3 : PAINT(160,40),2,3 ' draw some graphics
350 RETURN
If you are using a RAM disk you may want to copy your DOS disk to the
RAM disk on bootup. The following patch will remove the keyboard input
waits from diskcopy. This is for Ver. 2.0.
-
A>COPY DISKCOPY.COM DC.COM
A>DEBUG DC.COM
-F 5D1 L 3 90
-E 649
XXXX:0649 01.6E 0C.00 CD.90 21.90
-W
Writing 098C bytes
-Q
A>
-
Good Luck,
Tom Hall - TCM644
72155,1114
10 ' *** DIR.BAS *** IBM Version 2.0 ***
20 ' *** March 1983 ***
30 '
40 ' *** Written by Wes Meier (70215,1017) ***
50 ' *** 230 B Park Lake Circle ***
60 ' *** Walnut Creek, CA 94598 ***
70 '
80 ' ****************************************************************
90 ' * *** For Public Domain....Private Sales Rights Reserved ! *** *
100 ' ****************************************************************
110 '
120 ' REMark...This program was written for an IBM PC with 128K RAM,
130 ' Two disk drives, Color Adapter Card, Electrohome Color
140 ' Monitor (80 Column), and an Epson MX-80 printer equipped
150 ' with the GRAFTRAX ROMS.
160 '
170 DEFINT B-Z:DEFSTR A
180 AV=CHR$(34):AL=STRING$(80,196):AQ="("+AV+"*"+AV+" to QUIT) "
190 DIM A(1000)
200 KEY OFF:WIDTH 40:SCREEN 0,1:COLOR 4,3,3:CLS
210 LOCATE 9,7,0,0,7:PRINT CHR$(201)STRING$(28,205)CHR$(187)
220 PRINT TAB(7) CHR$(186)SPC(3)"*** Disk Directory *** "CHR$(186)
230 PRINT TAB(7) CHR$(186)SPC(3)" *** Version 2.00 *** "CHR$(186)
240 PRINT TAB(7) CHR$(186)SPC(3)" *** March , 1983 *** "CHR$(186)
250 PRINT TAB(7) CHR$(186)SPC(3)" *** By Wes Meier *** "CHR$(186)
260 PRINT TAB(7)CHR$(204)STRING$(28,205)CHR$(185)
270 PRINT TAB(7)CHR$(186)SPC(2)"Reading: "AV SPC(15)AV CHR$(186)
280 PRINT TAB(7)CHR$(200)STRING$(28,205)CHR$(188)
290 ADRV="A:":ON ERROR GOTO 310
300 GOTO 350
310 IF ERR=53 THEN RESUME 320 ELSE ON ERROR GOTO 0
320 MID$(ADRV,1,1)=CHR$(ASC(ADRV)+1)
330 IF ASC(ADRV)>66 THEN ON ERROR GOTO 0 ELSE 350
340 CLOSE:ADRV="A:":OPEN "O",1,ADRV+"DIR.DAT":CLOSE
350 OPEN "I",1,ADRV+"DIR.DAT":ON ERROR GOTO 0
360 ENTRIES=0
370 WHILE NOT EOF(1)
380 ENTRIES=ENTRIES+1
390 INPUT #1,A(ENTRIES)
400 LOCATE 15,20,0
410 PRINT A(ENTRIES);
420 WEND
430 CLOSE
440 'Check for Color Card
450 SCRSEG=&HB800
460 DEF SEG=SCRSEG
470 POKE 0,95:IF PEEK(0)<>95 THEN SCRSEG=&HB000:DEF SEG=SCRSEG
480 GOTO 970
490 '********************** SUBROUTINES **********************
500 '
510 '**********************************
520 '*** Blinking Cursor Subroutine ***
530 '**********************************
540 T=POS(0):L=CSRLIN
550 LOCATE L,T,0:PRINT "?";:FOR O=1 TO 30:ANSWER$=INKEY$
560 IF ANSWER$<>""THEN IF ANSWER$="*"THEN RETURN 970 ELSE RETURN ELSE NEXT
570 LOCATE L,T,0:PRINT CHR$(220);:FOR O=1 TO 30:ANSWER$=INKEY$
580 IF ANSWER$<>""THEN IF ANSWER$="*"THEN RETURN 970 ELSE RETURN ELSE NEXT
590 GOTO 550
600 ' ********************************
610 ' *** Yes/No Answer Subroutine ***
620 ' ********************************
630 GOSUB 510:LOCATE L,T
640 IF ANSWER$="Y" OR ANSWER$="y" OR ANSWER$=CHR$(13) THEN 670
650 IF ANSWER$="0" OR ANSWER$="n" OR ANSWER$="N" THEN 680
660 SOUND 250,4:GOTO 630
670 ANSWER$="Y":PRINT "? Yes":RETURN
680 ANSWER$="N":PRINT "? No":RETURN
690 '
700 '******* SUBROUTINE TO DUMP DATA TO DISK ********
710 'DRIVE=0 IF DRIVE "A" OR 1 IF DRIVE "B"
720 SCREEN ,,0,0:COLOR 31,4,4:CLS
730 LOCATE 12,14,0:PRINT"Saving Data to Disk.....";
740 IF DRIVE=0 THEN OPEN"O",1,"DIR.DAT":GOTO 760
750 OPEN"O",1,"B:DIR.DAT"
760 FOR X=1 TO ENTRIES:IF A(X)="" THEN 770 ELSE WRITE #1,A(X)
770 NEXT:CLOSE:RETURN
780 '*****************************************************
790 '* SUBROUTINE TO SORT THE DATA ARRAY BY FILESPEC *
800 '*****************************************************
810 PRINT"Sorting Data.........."
820 M=ENTRIES:N=M:C=0
830 M=INT(M/2):IF M=0 THEN SORTFLAG=0:RETURN ELSE J=1:K=N-M
840 I=J
850 L=I+M:C=C+1
860 IF A(I)<A(L)THEN 870 ELSE SWAP A(I),A(L):I=I-M:IF I<1 THEN 870 ELSE 850
870 J=J+1:IF J>K THEN 830 ELSE 840
880 '*****************************************************
890 '* SUBROUTINE TO SORT THE DATA ARRAY BY DISK NO. *
900 '*****************************************************
910 PRINT"Sorting Data.........."
920 FOR X=1 TO ENTRIES:A(X)=RIGHT$(A(X),3)+LEFT$(A(X),12):NEXT
930 GOSUB 820
940 SORTFLAG=1
950 FOR X=1 TO ENTRIES:A(X)=RIGHT$(A(X),12)+LEFT$(A(X),3):NEXT
960 RETURN
970 ' ************
980 ' **** MENU ****
990 ' ************
1000 IF SORTFLAG=1 THEN GOSUB 810
1010 IF PAGE=1 THEN COLOR ,,1:SCREEN ,,1,1:GOTO 1570
1020 WIDTH 80:SCREEN 0,1,1,1:COLOR ,1,1:PAGE=1
1030 CLS
1040 COLOR 6
1050 LOCATE 5,1,0
1060 PRINT CHR$(201)STRING$(78,205)CHR$(187);
1070 PRINT CHR$(186);
1080 COLOR 13
1090 PRINT TAB(13)"*** DISK DIRECTORY *** MENU ****";
1100 PRINT ENTRIES"ENTRIES ON RECORD ***";
1110 COLOR 6
1120 PRINT TAB(80)CHR$(186);
1130 PRINT CHR$(204)STRING$(78,205)CHR$(185);
1140 PRINT CHR$(186)TAB(13);
1150 COLOR 3:PRINT"Enter:"TAB(80):COLOR 6:PRINT CHR$(186);
1160 PRINT CHR$(186)TAB(19);
1170 COLOR 27:PRINT"1. ";:COLOR 3
1180 PRINT"To FIND an item."TAB(80);
1190 COLOR 6:PRINT CHR$(186);
1200 PRINT CHR$(186)TAB(19);
1210 COLOR 27:PRINT"2. ";:COLOR 3
1220 PRINT"To ENTER an item or an entire disk."TAB(80);
1230 COLOR 6:PRINT CHR$(186);
1240 PRINT CHR$(186)TAB(19);
1250 COLOR 27:PRINT"3. ";:COLOR 3
1260 PRINT"To DELETE an item or an entire disk."TAB(80);
1270 COLOR 6:PRINT CHR$(186);
1280 PRINT CHR$(186)TAB(19);
1290 COLOR 27:PRINT"4. ";:COLOR 3
1300 PRINT"To LIST the file to the CRT or the PRINTER."TAB(80);
1310 COLOR 6:PRINT CHR$(186);
1320 PRINT CHR$(186)TAB(19);
1330 COLOR 27:PRINT"5. ";:COLOR 3
1340 PRINT"To LIST the directory of a disk."TAB(80);
1350 COLOR 6:PRINT CHR$(186);
1360 PRINT CHR$(186)TAB(19);
1370 COLOR 27:PRINT"6. ";:COLOR 3
1380 PRINT"To BACKUP the data file or this program."TAB(80);
1390 COLOR 6:PRINT CHR$(186);
1400 PRINT CHR$(186)TAB(19);
1410 COLOR 27:PRINT" ";:COLOR 3
1420 PRINT TAB(80);
1430 COLOR 6:PRINT CHR$(186);
1440 PRINT CHR$(186)TAB(19);
1450 COLOR 27:PRINT" ";:COLOR 3
1460 PRINT TAB(80);
1470 COLOR 6:PRINT CHR$(186);
1480 PRINT CHR$(186)TAB(19);
1490 COLOR 27:PRINT"9. ";:COLOR 3
1500 PRINT"To RETURN to DOS."TAB(80);
1510 COLOR 6:PRINT CHR$(186);
1520 PRINT CHR$(204)STRING$(78,205)CHR$(185);
1530 PRINT CHR$(186)TAB(27);
1540 COLOR 20,7:PRINT" *** ENTER YOUR CHOICE *** ";
1550 COLOR 6,1:PRINT TAB(80)CHR$(186);
1560 PRINT CHR$(200)STRING$(78,205)CHR$(188);
1570 BEEP
1580 CHOICE$=INKEY$:IF CHOICE$="" THEN 1580
1590 X=INSTR("123456789",CHOICE$):IF X=0 THEN 1570
1600 SCREEN ,,0,0:COLOR 6,1,1:CLS
1610 ON X GOTO 1620,2040,2850,3280,10010,10410,1570,1570,11130
1620 '****************************************
1630 '* *** Find an ITEM routine *** *
1640 '****************************************
1650 COLOR ,3,3:CLS
1660 COLOR 16:PRINT AL;:COLOR 1
1670 PRINT TAB(26)"*** FIND AN ITEM ROUTINE ***"
1680 COLOR 16:PRINT AL
1690 COLOR 4:PRINT"Enter complete or partial ";
1700 PRINT"filespec of ITEM to be found "AQ"........"
1710 COLOR 1:INPUT AT:IF AT="*" THEN 970' Return to menu.
1720 FOR X=1 TO LEN(AT)
1730 IF ASC(MID$(AT,X,1))>96 THEN MID$(AT,X,1)=CHR$(ASC(MID$(AT,X,1))-32)
1740 NEXT
1750 FOR X=1 TO ENTRIES
1760 IF INSTR(A(X),AT)=0 OR LEFT$(A(X),12)=LEFT$(AX,12) THEN 1850
1770 AX=A(X)
1780 PRINT AV;LEFT$(A(X),12);AV" can be found on disks: ";
1790 FOR Y=X TO ENTRIES
1800 IF LEFT$(AX,12)=LEFT$(A(Y),12) THEN PRINT RIGHT$(A(Y),3)", ";:GOTO 1820
1810 Y=ENTRIES
1820 NEXT
1830 PRINT:PRINT:PRINT"Is this the ITEM you wanted to find ";
1840 GOSUB 610:IF ANSWER="Y"THEN 1870
1850 NEXT:PRINT:PRINT"I cannot locate any incidence of "AV;AT;AV". Try again."
1860 PRINT:GOTO 1690
1870 PRINT:PRINT"Do you want to RUN "AV;AX;AV" ";
1880 GOSUB 610:IF ANSWER="N" THEN 970
1890 ON ERROR GOTO 1910
1900 GOTO 1920
1910 IF ERR=53 THEN RESUME 1930 ELSE ON ERROR GOTO 0
1920 IF MID$(AX,10,3)="BAS" THEN RUN LEFT$(AX,12) ELSE 2000
1930 ON ERROR GOTO 1940:RUN "B:"+LEFT$(AX,12)
1940 IF ERR=53 THEN RESUME 1950 ELSE ON ERROR GOTO 0
1950 ON ERROR GOTO 0:COLOR 4:PRINT:BEEP:BEEP:PRINT"I cannot locate "AV;AX;AV;
1960 PRINT" on either drive "AV"A"AV" or drive "AV"B"AV"!!!"
1970 PRINT"Please check to see that Disk #";
1980 PRINT RIGHT$(AX,3)" is mounted and press any"
1990 PRINT"key to continue ";:COLOR 1:GOSUB 540:PRINT:GOTO 1870
2000 PRINT:PRINT"Since "AV;AX;AV" doesn't have the "AV".BAS"AV" extension,";
2010 PRINT "I can't RUN it!"
2020 PRINT"Press any key to return to the menu...("AV"*"AV" to jump to DOS) ";
2030 GOSUB 510:IF ANSWER<>"*"THEN 970 ELSE SYSTEM
2040 '****************************
2050 '**** ITEM ENTRY ROUTINE ****
2060 '****************************
2070 COLOR 4,7,7:CLS
2080 COLOR 1:PRINT AL;:COLOR 4
2090 PRINT TAB(27)"*** Item Entry Routine ***"
2100 COLOR 1:PRINT AL:COLOR 4
2110 LOCATE 12,1
2120 PRINT"Do you want to enter from the ";:COLOR 17:PRINT"K";:COLOR 4
2130 PRINT "eyboard or read a ";:COLOR 17:PRINT "D";:COLOR 4:PRINT "isk "AQ;
2140 COLOR 1
2150 GOSUB 510:COLOR 4
2160 IF ANSWER="*"THEN 970 ELSE IF ANSWER="k" OR ANSWER="K" THEN 2190
2170 IF ANSWER="D" OR ANSWER="d" THEN 2420
2180 LOCATE L,T:BEEP:GOTO 2150
2190 ' Keyboard item entry routine
2200 LOCATE 12,1:PRINT SPACE$(79)
2210 LOCATE 4,1
2220 PRINT AV".BAS"AV" is the default extension."
2230 PRINT "Enter filespec "AQ;:INPUT A:IF A="*"THEN 970
2240 IF LEN(A)>12 THEN BEEP:PRINT A" is too long !":GOTO 2230
2250 INPUT "Enter disk # ";AD
2260 IF VAL(AD)<1 OR VAL(AD)>999 THEN BEEP:GOTO 2250
2270 AD=RIGHT$("00"+AD,3)
2280 K=INSTR(A,".")
2290 IF K=0 THEN A=LEFT$(A+" ",8)+".BAS":GOTO 2280
2300 A=LEFT$(MID$(A,1,K-1)+" ",8)+RIGHT$(A,LEN(A)-(K-1))
2310 A=LEFT$(A+" ",12)+AD
2320 FOR X=1 TO LEN(A)
2330 IF MID$(A,X,1)<"a" OR MID$(A,X,1)>"z" THEN 2350
2340 MID$(A,X,1)=CHR$(ASC(MID$(A,X,10))-32)
2350 NEXT
2360 PRINT"Is "AV;A;AV" correct ";
2370 GOSUB 610:IF ANSWER$="N"THEN 2230
2380 ENTRIES=ENTRIES+1
2390 A(ENTRIES)=A:A="":PRINT"Entered. Do you have any more entries ";
2400 IF ADRV="A:" THEN DRIVE=0 ELSE DRIVE=1
2410 GOSUB 610:IF ANSWER="N"THEN GOSUB 780:GOSUB 720:RUN ELSE 2220
2420 'Read disk entry routine
2430 LOCATE 12,1:PRINT SPACE$(79)
2440 LOCATE 4,1
2450 PRINT "Enter disk number to be read "AQ;
2460 INPUT ADISK:IF ADISK="*"THEN 970 ELSE DISK=VAL (ADISK)
2470 IF DISK<0 OR DISK>999 THEN BEEP:GOTO 2450
2480 ADISK=STR$(DISK):MID$(ADISK,1)="0":ADISK=RIGHT$("00"+ADISK,3)
2490 PRINT "Enter drive (A or B) (B is the default) ";
2500 GOSUB 510:ADRIVE=ANSWER$:IF ADRIVE=CHR$(13) THEN ADRIVE="B":GOTO 2550
2510 IF ADRIVE="A" OR ADRIVE="a" THEN 2540
2520 IF ADRIVE="B" OR ADRIVE="b" THEN 2540
2530 LOCATE L,T:BEEP:GOTO 2500
2540 IF ADRIVE="a" THEN ADRIVE="A" ELSE IF ADRIVE="b" THEN ADRIVE="B"
2550 LOCATE L,T:PRINT "? "ADRIVE
2560 PRINT:PRINT"Read disk #"ADISK" on drive "AV;ADRIVE;AV". Is this correct ";
2570 GOSUB 610:IF ANSWER$="N"THEN 2450
2580 PRINT"Deleting references to disk #"ADISK"......"
2590 FOR X=1 TO ENTRIES
2600 IF RIGHT$(A(X),3)=ADISK THEN A(X)=""
2610 NEXT
2620 ' ******************************************
2630 ' ***** Routine to Read a Disk's Directory *****
2640 ' ******************************************
2650 CLS
2660 PRINT AL;
2670 IF ADRIVE="A"THEN FILES ELSE FILES "B:*.*"
2680 PRINT:PRINT AL;
2690 FOR LN=2 TO 20
2700 FOR PT=1 TO 78 STEP 13
2710 K=(PT-1)*2+(LN-1)*160
2720 A=""
2730 IF PEEK(K)=32 THEN 2820
2740 FOR P=K TO K+23 STEP 2
2750 A=A+CHR$(PEEK(P))
2760 POKE P+1,14
2770 NEXT
2780 ENTRIES=ENTRIES+1
2790 A(ENTRIES)=A+ADISK
2800 NEXT
2810 NEXT
2820 PRINT:PRINT"Do you have another disk to read ";
2830 IF ADRV="A:" THEN DRIVE=0 ELSE DRIVE=1
2840 GOSUB 610:IF ANSWER$="N" THEN GOSUB 780:GOSUB 720:RUN ELSE CLS:GOTO 2440
2850 ' *****************************************************
2860 ' * *** DELETE AN ITEM OR ENTIRE DISK ROUTINE *** *
2870 ' *****************************************************
2880 COLOR 2,0,0:CLS
2890 PRINT AL;
2900 PRINT TAB(22)"*** DELETE AN ITEM OR DISK ROUTINE ***"
2910 PRINT AL;
2920 LOCATE 12,1
2930 PRINT"Delete an ";
2940 COLOR 20,7:PRINT"I";
2950 COLOR 2,0:PRINT"tem or an entire ";
2960 COLOR 20,7:PRINT"D";
2970 COLOR 2,0:PRINT"isk "AQ;
2980 COLOR 4,7:GOSUB 520:COLOR 2,0
2990 IF ANSWER$="*"THEN 970 ELSE IF ANSWER$="I" THEN 3050
3000 IF ANSWER$="i" THEN 3050
3010 IF ANSWER$="D" THEN 3190
3020 IF ANSWER$="d" THEN 3190
3030 SOUND 350,4:LOCATE L,T
3040 GOTO 2980
3050 '*** Item Delete ***
3060 LOCATE L,T:PRINT"? Item":PRINT
3070 PRINT"Enter complete or partial filespec of item to be deleted "AQ;
3080 INPUT AT:IF AT="*"THEN 970
3090 FOR X=1 TO ENTRIES
3100 IF INSTR(A(X),AT)<>0 THEN 3130
3110 NEXT
3120 PRINT"I can't locate "AV;AT;AV". Try again.":GOTO 3070
3130 PRINT"Is "AV;A(X);AV" the item you want to delete ";
3140 GOSUB 610:IF ANSWER$="N"THEN 3110
3150 A(X)="":PRINT"Deleted. Do you have any other items to delete ";
3160 GOSUB 610:IF ANSWER$="Y"THEN 3070
3170 IF ADRV="A:" THEN DRIVE=0 ELSE DRIVE=1
3180 GOSUB 700:RUN
3190 '*** Disk Delete ***
3200 PRINT"Enter number of disk to be deleted ";:INPUT D
3210 PRINT"Searching.......";
3220 FOR X=1 TO ENTRIES
3230 IF VAL(RIGHT$(A(X),3))=D THEN A(X)=""
3240 NEXT
3250 PRINT"Done."
3260 PRINT"Do you have any other disks to delete ";
3270 GOSUB 610:IF ANSWER$="Y"THEN 3200 ELSE 3170
3280 '**************************
3290 '* *** LIST ROUTINE *** *
3300 '**************************
3310 COLOR 4,3,3:CLS
3320 LOCATE 11,1:PRINT"Do you want the list Sorted by Disk number ";
3330 GOSUB 610:IF ANSWER$="Y"THEN GOSUB 910
3340 PRINT"List to ";
3350 COLOR 30,0:PRINT"C";
3360 COLOR 4,3:PRINT"RT or ";
3370 COLOR 30,0:PRINT"P";
3380 COLOR 4,3:PRINT"rinter ";
3390 GOSUB 520:IF ANSWER$="*"THEN 970
3400 IF ANSWER$="c" OR ANSWER$="C"THEN 3450
3410 IF ANSWER$="p" OR ANSWER$="P"THEN 3600
3420 SOUND 200,5
3430 LOCATE L,T
3440 GOTO 3390
3450 '*** List to CRT Routine ***
3460 WIDTH 40:COLOR 4,3,3:CLS:PAGE=0:BACK=0
3470 FOR X=1 TO ENTRIES
3480 IF X/22=INT(X/22) THEN 3570
3490 PRINT USING "### ";X;
3500 COLOR 1
3510 PRINT LEFT$(A(X),12);:COLOR 4
3520 PRINT" Disk # ";:COLOR 1:PRINT RIGHT$(A(X),3):COLOR 4
3530 NEXT
3540 LOCATE 25,1:COLOR 20,7
3550 PRINT"End of listing. Press any key ";
3560 GOSUB 520:GOTO 970
3570 COLOR 20,7
3580 LOCATE 25,1:PRINT"Press any key to continue ";
3590 GOSUB 520:COLOR 4,3:CLS:GOTO 3490
3600 '*** List to Printer ***
3601 PRINT:PRINT"Printing Directory .... Press any key to abort ....
3610 PAGES=INT(ENTRIES/162)+1
3620 AFMT="Disk: ### - \ \ "
3630 FOR PAGE=1 TO PAGES
3640 LPRINT:LPRINT
3650 LPRINT"Disk Directory "DATE$", "TIME$;TAB(65)"Page"PAGE"of"PAGES
3660 LPRINT STRING$(79,"-")
3670 FOR X=(PAGE-1)*162+1 TO (PAGE-1)*162+54
3680 FOR Y=0 TO 2
3690 IF A(X+Y*54)="" THEN 3710
3700 LPRINT USING AFMT;VAL(RIGHT$(A(X+Y*54),3)),LEFT$(A(X+Y*54),12);
3702 IF INKEY$<>"" THEN LPRINT CHR$(12):GOTO 970
3710 NEXT
3720 LPRINT
3730 NEXT
3740 LPRINT STRING$(79,"-")
3750 LPRINT CHR$(12)
3760 NEXT
10000 GOTO 970
10010 '******************************************************
10020 '* *** Routine to list the Directory of a Disk *** *
10030 '******************************************************
10040 CLS
10050 PRINT AL;
10060 PRINT TAB(20)"*** Display Disk Directory Routine ***"
10070 PRINT AL
10080 PRINT"Do you want an ";
10090 COLOR 31,0:PRINT"A";
10100 COLOR 6,1:PRINT"ctual Disk Directory or the ";
10110 COLOR 31,0:PRINT"D";
10120 COLOR 6,1:PRINT "ata of a Disk as stored by "AV"DIR"AV"."
10130 PRINT AQ;
10140 GOSUB 520:IF ANSWER$="*"THEN 970
10150 IF ANSWER$="A" OR ANSWER$="a" THEN 10180
10160 IF ANSWER$="D" OR ANSWER$="d" THEN 10290
10170 SOUND 234,5:LOCATE L,T:GOTO 10140
10180 '*** List Actual Directory ***
10190 LOCATE L,T:PRINT "? Actual Directory"
10200 PRINT"Enter drive "AV"A"AV" or "AV"B"AV" ";
10210 GOSUB 520:IF ANSWER$="*"THEN 970
10220 IF ANSWER$="a" OR ANSWER$="A"THEN ANSWER$="A":GOTO 10250
10230 IF ANSWER$="b" OR ANSWER$="B"THEN ANSWER$="B":GOTO 10250
10240 SOUND 231,5:LOCATE L,T:GOTO 10210
10250 LOCATE L,T:PRINT "? "ANSWER$
10260 PRINT AL:COLOR 0,2
10270 FILES ANSWER$+":*.*"
10280 COLOR 6,1:GOTO 10070
10290 LOCATE L,T:PRINT"? Data":PRINT "Enter disk number "AQ;
10300 INPUT AD:IF AD="*"THEN 970
10310 D=VAL(AD):C=0
10320 PRINT AL:COLOR 0,2
10330 FOR X=1 TO ENTRIES
10340 IF D<>VAL(RIGHT$(A(X),3))THEN 10380
10350 IF POS(0)>=78 THEN PRINT
10360 PRINT LEFT$(A(X),12)" ";
10370 C=C+1
10380 NEXT
10390 IF C=0 THEN PRINT"Disk number"D"isn't listed."
10400 GOTO 10280
10410 '********************************************************************
10420 '* *** Backup Data File and/or Program Routine *** *
10430 '********************************************************************
10440 IF BACK=1 THEN SCREEN ,,2,2:COLOR 6,1,1:GOTO 11000
10450 WIDTH 80:SCREEN 0,1,2,2:COLOR ,1,1:BACK=1
10460 CLS
10470 COLOR 6
10480 LOCATE 5,1,0
10490 PRINT CHR$(201)STRING$(78,205)CHR$(187);
10500 PRINT CHR$(186);
10510 COLOR 13
10520 PRINT TAB(13)" *** Backup Data File and/or Program Routine ***";
10530 COLOR 6
10540 PRINT TAB(80)CHR$(186);
10550 PRINT CHR$(204)STRING$(78,205)CHR$(185);
10560 PRINT CHR$(186)TAB(13);
10570 COLOR 3:PRINT"Enter:"TAB(80):COLOR 6:PRINT CHR$(186);
10580 PRINT CHR$(186)TAB(19);
10590 COLOR 27:PRINT"1. ";:COLOR 3
10600 PRINT"To BACKUP the Data File to drive "AV"A"AV"."TAB(80);
10610 COLOR 6:PRINT CHR$(186);
10620 PRINT CHR$(186)TAB(19);
10630 COLOR 27:PRINT"2. ";:COLOR 3
10640 PRINT"To BACKUP the Data File to drive "AV"B"AV"."TAB(80);
10650 COLOR 6:PRINT CHR$(186);
10660 PRINT CHR$(186)TAB(19);
10670 COLOR 27:PRINT"3. ";:COLOR 3
10680 PRINT"To BACKUP the Data File to both drives."TAB(80);
10690 COLOR 6:PRINT CHR$(186);
10700 PRINT CHR$(186)TAB(19);
10710 COLOR 27:PRINT"4. ";:COLOR 3
10720 PRINT"To BACKUP this PROGRAM to drive "AV"A"AV"."TAB(80);
10730 COLOR 6:PRINT CHR$(186);
10740 PRINT CHR$(186)TAB(19);
10750 COLOR 27:PRINT"5. ";:COLOR 3
10760 PRINT"To BACKUP this PROGRAM to drive "AV"B"AV"."TAB(80);
10770 COLOR 6:PRINT CHR$(186);
10780 PRINT CHR$(186)TAB(19);
10790 COLOR 27:PRINT"6. ";:COLOR 3
10800 PRINT"To BACKUP this PROGRAM to both drives."TAB(80);
10810 COLOR 6:PRINT CHR$(186);
10820 PRINT CHR$(186)TAB(19);
10830 COLOR 27:PRINT"7. ";:COLOR 3
10840 PRINT"To BACKUP the Data file and this ";
10850 PRINT"PROGRAM to drive "AV"B"AV"."TAB(80);
10860 COLOR 6:PRINT CHR$(186);
10870 PRINT CHR$(186)TAB(19);
10880 COLOR 27:PRINT"8. ";:COLOR 3
10890 PRINT"To BACKUP the Data file and this PROGRAM to both drives."TAB(80);
10900 COLOR 6:PRINT CHR$(186);
10910 PRINT CHR$(186)TAB(19);
10920 COLOR 27:PRINT"9. ";:COLOR 3
10930 PRINT"To RETURN to the main MENU."TAB(80);
10940 COLOR 6:PRINT CHR$(186);
10950 PRINT CHR$(204)STRING$(78,205)CHR$(185);
10960 PRINT CHR$(186)TAB(27);
10970 COLOR 20,7:PRINT" *** ENTER YOUR CHOICE *** ";
10980 COLOR 6,1:PRINT TAB(80)CHR$(186);
10990 PRINT CHR$(200)STRING$(78,205)CHR$(188);
11000 BEEP
11010 CHOICE$=INKEY$:IF CHOICE$="" THEN 11010
11020 X=INSTR("123456789",CHOICE$):IF X=0 THEN 11000
11030 ON X GOSUB 11050,11060,11070,11080,11090,11100,11110,11120,970
11040 GOTO 10410
11050 DRIVE=0:GOSUB 700:RETURN
11060 DRIVE=1:GOSUB 700:DRIVE=0:RETURN
11070 GOSUB 11050:GOSUB 11060:RETURN
11080 SAVE"DIR":RETURN
11090 SAVE"B:DIR":RETURN
11100 GOSUB 11080:GOSUB 11090:RETURN
11110 GOSUB 11090:GOSUB 11060:RETURN
11120 GOSUB 11110:GOSUB 11080:GOSUB 11050:RETURN
11130 '******* RETURN TO DOS ROUTINE *******
11140 CLS
11150 SYSTEM
DIR.DOC --- This is the documentation for DIR.BAS (such as it is).
DIR.BAS is a BASIC program that helps the user keep track of all his/her
disk files. The program is menu driven and is easy to operate. The program
will compile without modification.
Entries to the programs may be made from the keyboard or the program can read
a disk's directory directly. Entries made be individually deleted or deleted
via deletion of the data for an entire disk.
The data can be displayed either on the CRT or the printer sorted alphabetically
or numerically by disk number. This sort routine takes a while if using the
program in BASIC, but really moves along in the compiled version.
An individual entry may be found (ie., it's disk #'s) and, if it has the .BAS
extension, may be run directly from DIR.BAS.Leave a note to me on the SIG board if you have any questions.
Wes Meier 70215,1017
; dot table
; xlat table first, then offsets
extable label word
db 0,1,2,3,4,5,6,7
db 0,0,0,8,9,0,0,0
db 0,10,0,11,175,0,0,0
db 0,0,12,0,0,0,0,0
db 0,13,14,15,16,17,18,19
db 20,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
db 21,184,187,22,182,23,0,162
db 24,25,189,26,27,28,177,0
db 29,0,0,30,183,31,32,33
db 34,178,179,180,163,176,0,191
db 35,36,37,38,39,40,0,0
db 41,42,43,174,172,44,45,46
db 47,48,49,50,51,52,53,54
db 55,56,57,58,59,60,61,62
db 63,64,65,66,67,68,69,70
db 71,72,73,74,75,76,77,78
db 79,80,81,82,83,84,85,86
db 87,88,89,90,91,92,93,94
db 0,185,0,95,96,0,0,0
db 0,97,0,0,0,0,0,0
db 98,99,100,101,0,0,102,0
db 0,0,0,0,0,0,0,0
extoffset dw 0
dw L1
dw L2
dw L3
dw L4
dw L5
dw L6
dw L7
dw L11
dw L12
dw L17
dw L19
dw L26
dw L33
dw L34
dw L35
dw L36
dw L37
dw L38
dw L39
dw L40
dw L128
dw L131
dw L133
dw L136
dw L137
dw L139
dw L140
dw L141
dw L144
dw L147
dw L149
dw L150
dw L151
dw L152
dw L160
dw L161
dw L162
dw L163
dw L164
dw L165
dw L168
dw L169
dw L170
dw L173
dw L174
dw L175
dw L176
dw L177
dw L178
dw L179
dw L180
dw L181
dw L182
dw L183
dw L184
dw L185
dw L186
dw L187
dw L188
dw L189
dw L190
dw L191
dw L192
dw L193
dw L194
dw L195
dw L196
dw L197
dw L198
dw L199
dw L200
dw L201
dw L202
dw L203
dw L204
dw L205
dw L206
dw L207
dw L208
dw L209
dw L210
dw L211
dw L212
dw L213
dw L214
dw L215
dw L216
dw L217
dw L218
dw L219
dw L220
dw L221
dw L222
dw L223
dw L227
dw L228
dw L233
dw L240
dw L241
dw L242
dw L243
dw L246
L246 db 72 ; ÷
db 0,0,0,0
db 0,0,0,0
db 0,2,0,0
db 0,1,0,0
db 0,2,0,0
db 0,1,0,0
db 0,34,2,0
db 1,17,5,0
db 2,34,10,0
db 1,17,5,0
db 2,34,10,0
db 1,1,4,0
db 0,2,0,0
db 0,1,0,0
db 0,2,0,0
db 0,1,0,0
db 0,0,0,0
db 0,0,0,0
db 0
L243 db 72 ; ≤
db 0,0,0,0
db 0,0,0,32
db 0,0,0,16
db 0,4,0,32
db 0,10,0,16
db 0,21,0,32
db 0,42,32,16
db 1,17,16,32
db 2,32,40,16
db 5,0,20,32
db 10,0,10,16
db 20,0,4,32
db 8,0,2,16
db 0,0,0,32
db 0,0,0,16
db 0,0,0,32
db 0,0,0,0
db 0,0,0,0
db 0
L242 db 72 ; ≥
db 0,0,0,0
db 0,0,0,32
db 0,0,0,16
db 0,0,0,32
db 0,0,0,16
db 8,0,2,32
db 20,0,4,16
db 10,0,10,32
db 5,0,20,16
db 2,32,40,32
db 1,17,16,16
db 0,42,32,32
db 0,21,0,16
db 0,10,0,32
db 0,4,0,16
db 0,0,0,32
db 0,0,0,0
db 0,0,0,0
db 0
L12 db 72 ;
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,1,0
db 0,21,2,0
db 0,42,33,0
db 1,0,18,0
db 2,0,9,20
db 1,0,22,40
db 2,0,9,0
db 1,0,18,0
db 2,32,33,0
db 1,21,2,0
db 0,42,1,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0
L11 db 72 ;
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,10,32
db 0,0,21,16
db 0,0,32,32
db 0,1,0,16
db 0,2,0,32
db 0,1,0,16
db 2,6,0,32
db 1,9,1,16
db 2,22,42,32
db 1,40,21,0
db 2,16,0,0
db 1,36,0,0
db 2,26,0,0
db 0,0,0,0
db 0
L6 db 72 ;
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,12,0,0
db 0,19,0,0
db 0,44,48,0
db 1,19,0,48
db 2,44,51,0
db 5,19,12,48
db 2,44,51,0
db 1,19,0,48
db 0,44,48,0
db 0,19,0,0
db 0,12,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0
L5 db 72 ;
db 0,0,0,0
db 0,3,0,0
db 0,12,48,0
db 0,0,0,0
db 0,15,48,0
db 3,0,0,0
db 12,60,48,48
db 0,3,3,0
db 15,48,12,48
db 0,3,3,0
db 12,60,48,48
db 3,0,0,0
db 0,15,48,0
db 0,0,0,0
db 0,12,48,0
db 0,3,0,0
db 0,0,0,0
db 0,0,0,0
db 0
L241 db 72 ; ±
db 0,0,0,0
db 0,0,0,0
db 0,8,0,32
db 0,0,0,0
db 0,8,0,32
db 0,0,0,0
db 0,8,0,32
db 0,0,0,0
db 15,63,60,32
db 0,0,0,0
db 0,8,0,32
db 0,0,0,0
db 0,8,0,32
db 0,0,0,0
db 0,8,0,32
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0
L170 db 72 ; ¬
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,2,0,0
db 0,0,0,0
db 0,2,0,0
db 0,0,0,0
db 0,2,0,0
db 0,0,0,0
db 0,2,0,0
db 0,0,0,0
db 0,2,0,0
db 0,0,0,0
db 0,2,0,0
db 0,0,0,0
db 0,3,63,0
db 0,0,0,0
db 0
L169 db 72 ; ⌐
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,3,63,0
db 0,2,0,0
db 0,0,0,0
db 0,2,0,0
db 0,0,0,0
db 0,2,0,0
db 0,0,0,0
db 0,2,0,0
db 0,0,0,0
db 0,2,0,0
db 0,0,0,0
db 0,2,0,0
db 0,0,0,0
db 0,0,0,0
db 0
L175 db 72 ; »
db 0,0,0,0
db 0,0,0,0
db 2,0,0,8
db 1,0,0,16
db 0,32,0,32
db 0,16,1,0
db 2,8,2,8
db 1,4,4,16
db 0,34,8,32
db 0,17,17,0
db 0,8,34,0
db 0,4,4,0
db 0,2,8,0
db 0,1,16,0
db 0,0,32,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0
L174 db 72 ; «
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,32,0
db 0,1,16,0
db 0,2,8,0
db 0,4,4,0
db 0,8,34,0
db 0,17,17,0
db 0,34,8,32
db 1,4,4,16
db 2,8,2,8
db 0,16,1,4
db 0,32,0,32
db 1,0,0,16
db 2,0,0,8
db 0,0,0,0
db 0,0,0,0
db 0
L168 db 72 ; ¿
db 0,0,0,0
db 0,0,0,0
db 0,0,0,16
db 0,0,0,8
db 0,0,0,4
db 0,0,0,8
db 4,0,0,4
db 10,16,0,8
db 4,8,0,4
db 0,4,0,8
db 0,4,0,4
db 0,2,0,8
db 0,1,32,24
db 0,0,25,32
db 0,0,6,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0
L173 db 72 ; ¡
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 10,21,21,16
db 4,10,42,32
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0
L19 db 72 ;
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 10,42,40,40
db 5,21,20,16
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 5,21,20,40
db 10,42,40,16
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0
L7 db 72 ;
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,5,16,0
db 0,10,32,0
db 0,5,16,0
db 0,10,32,0
db 0,5,16,0
db 0,10,32,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0
L4 db 72 ;
db 0,0,0,0
db 0,0,16,0
db 0,0,40,0
db 0,1,20,0
db 0,2,42,0
db 0,5,21,0
db 0,10,42,32
db 0,21,21,16
db 0,42,42,40
db 0,21,21,16
db 0,10,42,32
db 0,5,21,0
db 0,2,42,0
db 0,1,20,0
db 0,0,40,0
db 0,0,16,0
db 0,0,0,0
db 0,0,0,0
db 0
L3 db 72 ;
db 0,0,0,0
db 0,0,0,0
db 0,7,32,0
db 0,10,48,0
db 0,21,28,0
db 0,42,46,0
db 0,53,21,32
db 0,26,42,48
db 0,5,21,24
db 0,10,42,44
db 0,21,21,24
db 0,58,42,48
db 0,53,23,0
db 0,26,44,0
db 0,13,48,0
db 0,7,32,0
db 0,0,0,0
db 0,0,0,0
db 0
L128 db 3,'C',8,',',0 ; Ç
L131 db 3,'a',8,'^',0 ; â
L133 db 3,'a',8,164,0 ; à
L136 db 3,'e',8,'^',0 ; ê
L137 db 3,'e',8,190,0 ; ë
L139 db 3,'i',8,190,0 ; ï
L140 db 3,'i',8,'^',0 ; î
L141 db 3,'i',8,164,0 ; ì
L144 db 3,'E',8,160,0 ; É
L147 db 3,'o',8,'^',0 ; ô
L149 db 3,'o',8,164,0 ; ò
L150 db 3,'u',8,'^',0 ; û
L151 db 3,'u',8,164,0 ; ù
L152 db 3,'y',8,190,0 ; ÿ
L160 db 3,'a',8,160,0 ; á
L161 db 3,'i',8,160,0 ; í
L162 db 3,'o',8,160,0 ; ó
L163 db 3,'u',8,160,0 ; ú
L164 db 7,'n',8,27,'D',181,27,'U',0 ; ñ
L165 db 7,'N',8,27,'D',181,27,'U',0 ; Ñ
L233 db 3,'O',8,'-',0 ; Θ
L26 db 72 ; arrow
db 0,0,0,0
db 0,0,0,0
db 0,1,0,0
db 0,1,0,0
db 0,1,0,0
db 0,1,0,0
db 0,1,0,0
db 0,1,0,0
db 0,1,0,0
db 0,1,0,0
db 0,1,0,0
db 0,17,4,0
db 0,9,8,0
db 0,5,16,0
db 0,3,32,0
db 0,1,0,0
db 0,0,0,0
db 0,0,0,0
db 0
L228 db 72 ; Σ
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 12,0,1,32
db 10,0,2,32
db 9,0,4,32
db 8,32,8,32
db 8,16,16,32
db 8,8,32,32
db 8,5,0,32
db 8,2,0,32
db 8,0,0,32
db 8,0,0,32
db 8,0,0,32
db 12,0,1,32
db 4,0,1,0
db 0,0,0,0
db 0,0,0,0
db 0
L240 db 72 ; ≡
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,34,2,0
db 1,1,4,0
db 0,34,2,0
db 1,1,4,0
db 0,34,2,0
db 1,1,4,0
db 0,34,2,0
db 1,1,4,0
db 0,34,2,0
db 1,1,4,0
db 0,34,2,0
db 1,1,4,0
db 0,34,2,0
db 1,1,4,0
db 0,0,0,0
db 0
L227 db 72 ; π
db 0,0,0,0
db 0,0,0,0
db 2,0,0,0
db 4,0,1,0
db 10,42,42,0
db 5,21,20,0
db 8,0,0,0
db 4,0,0,0
db 8,0,0,0
db 4,0,0,0
db 8,0,0,0
db 4,0,0,0
db 10,42,42,0
db 5,21,21,0
db 8,0,0,0
db 4,0,0,0
db 8,0,0,0
db 0,0,0,0
db 0
L17 db 72 ;
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,1,0,0
db 0,2,32,0
db 0,5,16,0
db 0,10,40,0
db 0,21,20,0
db 0,42,42,0
db 1,21,21,0
db 2,42,42,32
db 5,21,21,16
db 10,42,42,40
db 21,21,21,20
db 42,42,37,20
db 26,42,42,40
db 0,0,0,0
db 0,0,0,0
db 0
L2 db 72 ;
db 0,0,0,0
db 0,0,0,0
db 1,42,42,32
db 2,53,21,16
db 5,26,42,40
db 10,5,17,20
db 5,6,40,40
db 10,5,20,20
db 5,42,8,40
db 10,21,4,20
db 5,42,8,40
db 10,5,20,20
db 5,6,40,40
db 10,5,16,20
db 5,29,17,40
db 2,42,42,40
db 1,21,21,16
db 0,0,0,0
db 0
L1 db 72 ;
db 0,0,0,0
db 0,0,0,0
db 1,21,21,16
db 2,42,42,40
db 4,0,0,20
db 8,0,0,8
db 4,48,8,4
db 8,48,4,8
db 4,3,4,4
db 8,3,4,8
db 4,3,4,4
db 8,48,4,8
db 4,48,8,4
db 8,0,0,8
db 4,0,0,24
db 2,42,42,32
db 1,21,21,0
db 0,0,0,0
db 0
L40 db 72 ; (
db 0,2,40,0
db 0,0,0,0
db 0,5,20,0
db 0,0,0,0
db 0,2,40,0
db 0,0,0,0
db 0,5,20,0
db 0,0,0,0
db 0,2,40,0
db 0,0,0,0
db 0,5,20,0
db 0,0,0,0
db 0,2,40,0
db 0,0,0,0
db 0,5,20,0
db 0,0,0,0
db 0,2,40,0
db 0,0,0,0
db 0
L39 db 72 ; '
db 0,2,8,0
db 0,0,0,0
db 0,4,16,0
db 0,1,4,0
db 0,0,0,0
db 0,0,32,0
db 0,2,8,0
db 0,0,0,0
db 0,4,16,0
db 0,1,4,0
db 0,0,0,0
db 0,0,32,0
db 0,2,8,0
db 0,0,0,0
db 0,4,16,0
db 0,1,4,0
db 0,0,0,0
db 0,0,32,0
db 0
L38 db 72 ; &
db 0,2,0,0
db 0,0,8,0
db 0,0,0,0
db 0,9,0,0
db 0,0,4,0
db 0,0,0,0
db 0,2,0,0
db 0,0,8,0
db 0,0,0,0
db 0,9,0,0
db 0,0,4,0
db 0,0,0,0
db 0,2,0,0
db 0,0,8,0
db 0,0,0,0
db 0,9,0,0
db 0,0,4,0
db 0,0,0,0
db 0
L37 db 72 ; %
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,2,40,0
db 0,5,20,0
db 0,2,40,0
db 0,5,20,0
db 0,2,40,0
db 0,5,20,0
db 0,2,40,0
db 0,5,20,0
db 0,2,40,0
db 0
L36 db 72 ; $
db 0,2,40,0
db 0,5,20,0
db 0,2,40,0
db 0,5,20,0
db 0,2,40,0
db 0,5,20,0
db 0,2,40,0
db 0,5,20,0
db 0,2,40,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0
L35 db 72 ; #
db 0,2,40,0
db 0,5,20,0
db 0,2,40,0
db 0,5,20,0
db 0,2,40,0
db 0,5,20,0
db 0,2,40,0
db 0,5,20,0
db 0,2,40,0
db 0,5,20,0
db 0,2,40,0
db 0,5,20,0
db 0,2,40,0
db 0,5,20,0
db 0,2,40,0
db 0,5,20,0
db 0,2,40,0
db 0,5,20,0
db 0
L34 db 72 ; "
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,2,40,0
db 0,5,20,0
db 0,0,0,0
db 0,0,0,0
db 0,2,40,0
db 0,5,20,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0
L33 db 72 ; !
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,2,40,0
db 0,5,20,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0
L176 db 72 ; ░
db 32,0,32,0
db 2,0,2,0
db 0,8,0,8
db 16,0,16,0
db 1,0,1,0
db 0,4,0,4
db 32,0,32,0
db 2,0,2,0
db 0,8,0,8
db 16,0,16,0
db 1,0,1,0
db 0,4,0,4
db 32,0,32,0
db 2,0,2,0
db 0,8,0,8
db 16,0,16,0
db 1,0,1,0
db 0,4,0,4
db 6
L177 db 72 ; ▒
db 34,8,34,8
db 0,32,8,2
db 4,1,0,16
db 17,4,17,4
db 0,16,4,1
db 8,2,0,32
db 34,8,34,8
db 0,32,8,2
db 4,1,0,16
db 17,4,17,4
db 0,16,4,1
db 8,2,0,32
db 34,8,34,8
db 0,32,8,2
db 4,1,0,16
db 17,4,17,4
db 0,16,4,1
db 8,2,0,32
db 7
L178 db 72 ; ▓
db 42,42,42,42
db 0,0,0,0
db 21,21,21,21
db 0,0,0,0
db 42,42,42,42
db 0,0,0,0
db 21,21,21,21
db 0,0,0,0
db 42,42,42,42
db 0,0,0,0
db 21,21,21,21
db 0,0,0,0
db 42,42,42,42
db 0,0,0,0
db 21,21,21,21
db 0,0,0,0
db 42,42,42,42
db 0,0,0,0
db 8
L223 db 72 ; ▀
db 42,42,32,0
db 21,21,16,0
db 42,42,32,0
db 21,21,16,0
db 42,42,32,0
db 21,21,16,0
db 42,42,32,0
db 21,21,16,0
db 42,42,32,0
db 21,21,16,0
db 42,42,32,0
db 21,21,16,0
db 42,42,32,0
db 21,21,16,0
db 42,42,32,0
db 21,21,16,0
db 42,42,32,0
db 21,21,16,0
db 0
L222 db 72 ; ▐
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 21,21,21,21
db 42,42,42,42
db 21,21,21,21
db 42,42,42,42
db 21,21,21,21
db 42,42,42,42
db 21,21,21,21
db 42,42,42,42
db 21,21,21,21
db 5
L221 db 72 ; ▌
db 42,42,42,42
db 21,21,21,21
db 42,42,42,42
db 21,21,21,21
db 42,42,42,42
db 21,21,21,21
db 42,42,42,42
db 21,21,21,21
db 42,42,42,42
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 4
L220 db 72 ; ▄
db 0,0,10,42
db 0,0,5,21
db 0,0,10,42
db 0,0,5,21
db 0,0,10,42
db 0,0,5,21
db 0,0,10,42
db 0,0,5,21
db 0,0,10,42
db 0,0,5,21
db 0,0,10,42
db 0,0,5,21
db 0,0,10,42
db 0,0,5,21
db 0,0,10,42
db 0,0,5,21
db 0,0,10,42
db 0,0,5,21
db 3
L219 db 72 ; █
db 42,42,42,42
db 21,21,21,21
db 42,42,42,42
db 21,21,21,21
db 42,42,42,42
db 21,21,21,21
db 42,42,42,42
db 21,21,21,21
db 42,42,42,42
db 21,21,21,21
db 42,42,42,42
db 21,21,21,21
db 42,42,42,42
db 21,21,21,21
db 42,42,42,42
db 21,21,21,21
db 42,42,42,42
db 21,21,21,21
db 3
L182 db 72 ; ╢
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 42,42,42,42
db 21,21,21,21
db 0,0,0,0
db 0,0,0,0
db 42,42,42,42
db 21,21,21,21
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 2
L181 db 72 ; ╡
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 42,42,42,42
db 21,21,21,21
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 1
L180 db 72 ; ┤
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 42,42,42,42
db 21,21,21,21
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 1
L179 db 72 ; │
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 42,42,42,42
db 21,21,21,21
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 1
L218 db 72 ; ┌
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,42,42
db 0,0,21,21
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 1
L217 db 72 ; ┘
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 42,42,32,0
db 21,21,16,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0
L216 db 72 ; ╪
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 42,42,42,42
db 21,21,21,21
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 1
L215 db 72 ; ╫
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 42,42,42,42
db 21,21,21,21
db 0,0,32,0
db 0,0,16,0
db 42,42,42,42
db 21,21,21,21
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 2
L214 db 72 ; ╓
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,42,42
db 0,0,21,21
db 0,0,32,0
db 0,0,16,0
db 0,0,42,42
db 0,0,21,21
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 2
L213 db 72 ; ╒
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,2,42,42
db 0,1,21,21
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 1
L212 db 72 ; ╘
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 42,42,44,0
db 21,21,20,0
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 0
L211 db 72 ; ╙
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 42,42,48,0
db 21,21,16,0
db 0,0,32,0
db 0,0,16,0
db 42,42,32,0
db 21,21,16,0
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 0
L210 db 72 ; ╥
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 0,0,42,42
db 0,0,21,21
db 0,0,32,0
db 0,0,16,0
db 0,0,42,42
db 0,0,21,21
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 2
L209 db 72 ; ╤
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 0,2,10,42
db 0,1,5,21
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 1
L208 db 72 ; ╨
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 42,42,32,0
db 21,21,16,0
db 0,0,32,0
db 0,0,16,0
db 42,42,32,0
db 21,21,16,0
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 0
L207 db 72 ; ╧
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 42,42,8,0
db 21,21,4,0
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 0
L206 db 72 ; ╬
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 42,42,10,42
db 21,21,13,21
db 0,0,0,0
db 0,0,0,0
db 42,43,10,42
db 21,21,5,21
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 2
L205 db 72 ; ═
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 0
L204 db 72 ; ╠
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 42,42,42,42
db 21,21,21,21
db 0,0,0,0
db 0,0,0,0
db 42,43,10,42
db 21,21,5,21
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 2
L203 db 72 ; ╦
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 0,2,10,42
db 0,1,13,21
db 0,2,0,0
db 0,1,0,0
db 0,2,10,42
db 0,1,5,21
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 2
L202 db 72 ; ╩
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 42,42,8,0
db 21,21,4,0
db 0,0,8,0
db 0,0,4,0
db 42,43,8,0
db 21,21,4,0
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 0
L201 db 72 ; ╔
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,2,42,42
db 0,1,21,21
db 0,2,0,0
db 0,1,0,0
db 0,2,10,42
db 0,1,5,21
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 2
L200 db 72 ; ╚
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 42,42,44,0
db 21,21,20,0
db 0,0,8,0
db 0,0,4,0
db 42,43,8,0
db 21,21,4,0
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 0
L199 db 72 ; ╟
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 42,42,42,42
db 21,21,21,21
db 0,0,0,0
db 0,0,0,0
db 42,42,42,42
db 21,21,21,21
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 2
L198 db 72 ; ╞
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 42,42,42,42
db 21,21,21,21
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 1
L197 db 72 ; ┼
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 42,42,42,42
db 21,21,21,21
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 1
L196 db 72 ; ─
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 0
L195 db 72 ; ├
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 42,42,42,42
db 21,21,21,21
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 1
L194 db 72 ; ┬
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 0,0,42,42
db 0,0,21,21
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 1
L193 db 72 ; ┴
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 42,42,32,0
db 21,21,16,0
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 0
L192 db 72 ; └
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 42,42,48,0
db 21,21,16,0
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 0
L191 db 72 ; ┐
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 0,0,42,42
db 0,0,53,21
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 1
L190 db 72 ; ╛
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 42,42,40,0
db 21,21,20,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0
L189 db 72 ; ╜
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 42,42,32,0
db 21,21,16,0
db 0,0,32,0
db 0,0,16,0
db 42,42,32,0
db 21,21,16,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0
L188 db 72 ; ╝
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 42,42,8,0
db 21,21,4,0
db 0,0,8,0
db 0,0,4,0
db 42,42,40,0
db 21,21,20,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0
L187 db 72 ; ╗
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 0,2,10,42
db 0,1,13,21
db 0,2,0,0
db 0,1,0,0
db 0,2,42,42
db 0,3,21,21
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 2
L186 db 72 ; ║
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 42,42,42,42
db 21,21,21,21
db 0,0,0,0
db 0,0,0,0
db 42,42,42,42
db 21,21,21,21
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 2
L185 db 72 ; ╣
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 42,42,10,42
db 21,21,13,21
db 0,0,0,0
db 0,0,0,0
db 42,42,42,42
db 21,21,21,21
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 2
L184 db 72 ; ╕
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 0,2,8,0
db 0,1,4,0
db 0,2,42,42
db 0,3,21,21
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 1
L183 db 72 ; ╖
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 0,0,32,0
db 0,0,16,0
db 0,0,42,42
db 0,0,21,21
db 0,0,32,0
db 0,0,16,0
db 0,0,42,42
db 0,0,53,21
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 0,0,0,0
db 2
Disk No 33
Program Title: DOS and PRINTER UTILITIES
PC-SIG version 1.2
A host of useful system enhancements. Do a graphic dump to an Epson or
C.Itoh printer (in two sizes), turn off printer bell, change print pitch,
and others. This disk also contains some patches to existing DOS routines,
and simplify or speedup some operations. In addition to the DOS and printer
utilities, there are some simple (but useful) communication utilities.
Usage: Enhance Printer Functions and some DOS commands.
System Requirements: 128K memory, one disk drive, some programs require
color graphics.
How to Start: To run an EXE or COM program, simply type its name and press
<ENTER>. To print a documentation file, type: COPY filename.ext PRN (press
enter) where filename is the name of the file, and ext is the extension
(TXT or DOC).
File Descriptions:
CALLGRAF BAS Program to call GRAFTRAX from Basic
CALLGRAF TXT ASCII version of CALLGRAF
COPYGRAF BAT Batch file to copy GRAFTRAX files to disk
DOTABLE ASM Data file used by Graftrax
DOTDATA ASM Data file used by Graftrax
DOTS DAT Data file used by Graftrax
DOTS PRO Data file used by Graftrax
GDEMO BAS Graphics demo program
GRAFTRAX ASM Source code for Graftrax
GRAFTRAX BAS Basic code for Graftrax
GRAFTRAX COM Compiled version of Graftrax
GRAFTRAX DOC Documentation for Graftrax
GRCITOH COM C-ITOH version of Graftrax
MAKEDOTS BAS Graphics display utility
NECGRAF COM NEC version of Graftrax
NEWT ASM Source code for enhanced Toshiba Graftrax version
NEWT COM Compiled Toshiba Graphtrax program
OKIGRAF ASM Source code for Okidata Graftrax program
OKIGRAF COM Compiled version of Okidata Graphtrax
READ ME Author's notes on Graftrax routines
TOSHIBA ASM Source code for original Toshiba Graftrax program
TOSHIBA COM Compiled version of Toshiba Graftrax
TOSHIBA DOC Documentation for Toshiba Graftrax programs
BATMAN BAS Sample menu/batch manager program; requires SHELL.BAT
BATMAN DOC Documentation file
BSR BAS Simple program to drive ABM/BSR controller
BSR DAT Data file for BSR.BAS
BUZOFF COM Turn off paper out buzzer on Epson
COMPRS COM Enables compressed print on Epson
CVTHEX EXE Binary/hex conversion for files larger than 32K
DCPATCH DOC Patch for DISKCOPY.COM 2.0
DIAL COM Dials Hayes Smartmodem
DIR BAS+ Disk cataloging program - very colorful
DIR DAT Sample data file
DIR DOC Documentation file
FK203 ASM Source code for FK203.EXE
FK203 EXE Function key reassignment program for DOS 2.0
HANG COM Hangs up Hayes Smartmodem
HOST BAS Communication program for remote access
HOST DOC Documentation file for HOST.BAS
PEPATCH DOC Patch to IBM's Personal Editor
POSTER BAS Prints large character posters
PRTFIX COM Corrects "DEVICE TIMEOUT" errors with printer
PRTFIX DOC Documentation file
QD COM Quadram RAMDRIVE program - FOR QUADRAM BOARD ONLY
QD DOC Documentation file
SCROLL ASM Scrolls specified area of display screen
SCROLL BLD Program file to "BLOAD" from BASIC
SCROLL DOC Documentation file
SCROLL1 BAS Sample program
SCROLL2 BAS Sample program
SHELL BAT Bat file used with BATMAN.BAS
SOUNDS BAS Generates different sounds - contains documentation
PC-SIG
1030D E Duane Avenue
Sunnyvale Ca. 94086
(408) 730-9291
(c) Copyright 1987 PC-SIG Inc.
TITLE FK203 - ASSEMBLER PROGRAM TO SET FUNCTION KEYS IN DOS 2.0
;
;
; Version 1.3 03/31/83
; Version 1.3 moves the DOS 'copy previous' (F3) to the
; 'end' key on the numeric/cursor keypad
;
;
; Assemble with MASM
; Then LINK it with LINK FK203; (or whatever you want to call it)
; Either include FK20x in an autoexec file or just type FK20x.
;
;** Important Note **
; For this routine to work, you must create a file called
;
; Config.Sys
;
; with Edlin or from the console and put the statement DEVICE=ANSI in
; it. The DOS 2.0 file ANSI.SYS should be on your boot disk. This will
; cause the file ANSI.SYS to be loaded when the system is booted.
;
SUBTTL DESCRIPTION OF THE STACK SEGMENT
STACK SEGMENT PARA STACK 'STACK'
db 'foo'
stack ends
PAGE
SUBTTL DESCRIPTION OF THE DATA SEGMENT
;
subttl desciption of dos interfaces
cseg segment para public 'CODE'
start proc far
assume cs:cseg,ds:cseg,es:nothing
push ds ;set up starting linkage as per example
sub ax,ax ;zero this and place on stack
push ax ;so that when we do a RET we go to
push cs ;move the workarea address into DS
pop ds
; ****** Start screen display ****
mov dx,offset clear
mov ah,9
int 21h
mov dx,offset k1
mov ah,9 ;function 9 is print string
int 21h ;call dos to do it
mov dx,offset k2
mov ah,9 ;function 9 is print string
int 21h ;call dos to do it
mov dx,offset k3
mov ah,9 ;function 9 is print string
int 21h ;call dos to do it
mov dx,offset k4
mov ah,9 ;function 9 is print string
int 21h ;call dos to do it
mov dx,offset k5
mov ah,9 ;function 9 is print string
int 21h ;call dos to do it
mov dx,offset k6
mov ah,9 ;function 9 is print string
int 21h ;call dos to do it
mov dx,offset k7
mov ah,9 ;function 9 is print string
int 21h ;call dos to do it
mov dx,offset k8
mov ah,9 ;function 9 is print string
int 21h ;call dos to do it
mov dx,offset k9
mov ah,9 ;funtion 9 is print string
int 21h ;call dos to do it
mov dx,offset k10
mov ah,9 ;function 9 is print string
int 21h ;call dos to do it
; *** Start key assignments ***
mov dx,offset mvf3 ;move F3 to END key
mov ah,9 ;function 9 is print string
int 21h ;call dos to do it
mov dx,offset f1 ;Assign F1 - F10
mov ah,9 ;function 9 is print string
int 21h ;call dos to do it
mov dx,offset f2
mov ah,9 ;function 9 is print string
int 21h ;call dos to do it
mov dx,offset f3
mov ah,9 ;function 9 is print string
int 21h ;call dos to do it
mov dx,offset f4
mov ah,9 ;function 9 is print string
int 21h ;call dos to do it
mov dx,offset f5
mov ah,9 ;function 9 is print string
int 21h ;call dos to do it
mov dx,offset f6
mov ah,9 ;function 9 is print string
int 21h ;call dos to do it
mov dx,offset f7
mov ah,9 ;function 9 is print string
int 21h ;call dos to do it
mov dx,offset f8
mov ah,9 ;function 9 is print string
int 21h ;call dos to do it
mov dx,offset f9
mov ah,9 ;funtion 9 is print string
int 21h ;call dos to do it
mov dx,offset f10
mov ah,9 ;function 9 is print string
int 21h ;call dos to do it
; The next section of code set ups the parameters for each function
; key. To make a key 'hot' add the following after the string ending
; quote - ;13p$' The 13 is decimal for a carrage return.
;
;
exit: ret
clear db 27,'[2J $'
mvf3 db 27,'[0;79;0;61p $'
f1 db 27,'[0;59;" A:"p $'
f2 db 27,'[0;60;" B:"p $'
f3 db 27,'[0;61;" C:"p $'
f4 db 27,'[0;62;"CHKDSK "p $'
f5 db 27,'[0;63;"COPY "p $'
f6 db 27,'[0;64;"*.* "p $'
f7 db 27,'[0;65;"DISKCOPY "p $'
f8 db 27,'[0;66;"BASICA "p $'
f9 db 27,'[0;67;"DIR "p $'
f10 db 27,'[0;68;"TYPE "p $'
k1 db 'F1 = " A:" $'
k2 db 'F2 = " B:" $'
k3 db 'F3 = " C:" $'
k4 db 'F4 = "CHKDSK " $'
k5 db 'F5 = "COPY " $'
k6 db 'F6 = "*.* " $'
k7 db 'F7 = "DISKCOPY "$'
k8 db 'F8 = "BASICA " $'
k9 db 'F9 = "DIR " $'
k10 db 'F10= "TYPE " $'
start endp
;
;
cseg ends
end start
1 ' test pattern.bas
2 ' marty smith
10 DEFINT A-Z
20 KEY OFF : SCREEN 1,0 : COLOR 1
30 CIRCLE(160,100),50,3 : CIRCLE(160,100),70,3 : CIRCLE(160,100),90,3
40 PAINT(160,100),1,3 : PAINT(100,100),2,3 : PAINT(80,100),3,3
50 J=1 :FOR I=0 TO 300 STEP 20
60 LINE(I,180)-(I+19,199),J,BF
70 J=((J+1) MOD 3)+1
80 NEXT
90 GOSUB 1000
100 SCREEN 2
110 FOR I=40 TO 600 STEP 80 : FOR J=40 TO 160 STEP 40
120 CIRCLE(I,J),39
130 NEXT :NEXT : LINE(0,0)-(639,199),1,B
140 GOSUB 1000
150 SCREEN 0,1 : WIDTH 80 : KEY ON
160 END
1000 LOCATE 1,1 : PRINT "Hit a key to continue . . .";
1010 WHILE INKEY$="" : WEND
1020 RETURN
╔═════════════════════════════════════════════════════════════════════════╗
║ <<<< Disk #33 Dos and printer utilities >>>> ║
╠═════════════════════════════════════════════════════════════════════════╣
║ To print the documentation for a program, type: ║
║ COPY filename.ext PRN (press enter) ║
║ ║
║ To display the documentation for a program type: ║
║ TYPE filename.ext (press enter) ║
║ ║
║ where 'filename' is the name of the documentation file ║
║ and 'ext' is the file extention (usually DOC or TXT) ║
║ ║
║ To run a program with a .COM or .EXE extention just type the ║
║ name of the file (i.e. NEWT) and then press enter. ║
║ ║
╚═════════════════════════════════════════════════════════════════════════╝
PAGE 60,132
TITLE EPSON MX-GRAFTRAX PrtSc, V 3.3
; GRAF.COM 2/10/85
; Interrupt replacement for print screen function on ibmpc(tm)
; Please send problem reports and suggestions to:
; Marty Smith
; 310 Cinnamon Oak Lane
; Houston, Texas 77079
; Compuserve 72155,1214
; (713) 464-6737
;
; Create GRAF.COM with MASM*, LINK* and EXE2BIN* as follows:
;
; masm graf,graf,graf;
;
; link graf; (ignor the error message about no stack segment,
; that's taken care of in the next step.)
; exe2bin graf.exe graf.com
;
; * MASM is the MicroSoft(tm) Macro Assembler v. 3.0
; or IBM(tm) Macro Assembler v. 1.0
; LINK and EXE2BIN are PC-DOS(tm) utilities.
;
; This program originally designed for Epson-MX(tm) series printers
; with Graftrax80(tm) and Graftrax+(tm) bit-plot graphic capabilites.
; ======> Now modified with conditional compilation and macros for
; ======> c.itoh(tm) model 8510a and other printers.
;
; CHANGE HISTORY:
; 9/18/82 - Buffer in routine for a line of bit-plot bytes to allow for
; checking for blank lines replaced by pre-scan routine, saving space.
; 1/24/83 - Modifications for conditional assembly with other printers
; and C.ITOH 8510a.
; 1/24/83 - Improved error checking for out-of-paper and I/O errors
; involving printer.
; 1/24/83 - Bug in error check corrected, occuring when routine does
; error exit and is then called again, resulting in bit-plot data sent in
; regular mode.
; 3/12/83 - Allow calling as a subroutine. i.e. no shift key depressed.
; Defaults to small print mode. Can be set to LARGE.
; 2/4/84 - Allow correct printing of 640x200 mode.
; 3/18/84 - Use int 31h for dos 2.+ terminate process.
; 3/24/84 - Use BIOS for keyboard scan, in case screen is printed
; from DOS.
; 4/21/84 - -OTHER- section complete for changes from 640 mode.
; 9/22/84 - Add code to set lines back in 6/inch order, so CR's
; can advance to TOF.
; 9/22/84 - Jump to other print screen routine instead of reassigning
; it to int f1h. Only luck has kept this vector from being used
; by someone else.
; 10/20/84- Add check for already installed, don't reinstall.
; 10/20/84- Compatibility with MASM 1.0 reestablished, FAR call to old
; routine caused 'fixup error' from EXE2BIN.
; 10/20/84- CALLGRAF now points to common address variable for default
; mode, is now the same for all versions of program. Demo now
; works!
;
; Features:
; Accepts ESC key exit, prescans to test for blank line
; left shift prtsc = small graphics, right shift prtsc = big
; Runs as a .COM type program under dos
; resident until power down or reset.
; 1 = screen sent horiz. 320 bits in 480 mode
; 2 = screen sent vert. 400 bits double printed in 480 mode
; ************** 1 mode **********************
; DL = masking character
; DH = count of 25 (physical lines)
; CX = counter for each line (80)
; DS = used to index screen at 'b8000'
; These regs must be preserved during routine
; (increment each line by adding '14' hex to ds: for paragraph
; boundary of 320 bytes 0x'140')
; ************** 2 mode *********************
; DH = count of 40 (physical lines)
; CX = counter for each line (100)
; SI = index to screen via ds:
; These regs must be preserved during routine
; all output to printer is done from routine -send2-, which uses
; bios routine int 17h, and provides safe error exit.
;
; GRAF.COM is designed with the idea that the user's main program is the
; primary function and GRAF.COM should not cause problems of its own.
;
; =======================================================
; = USER MODIFICATION SECTION. =
; = If your printer can treat a byte of data to =
; = control the wires on the dot-matrix head you =
; = can probably get this working with your printer =
; = unless it is an IDS type, which treats bit plot =
; = a lot differently than the EPSON. =
; = If you have Epson Graftrax or a C.Itoh 8510a, =
; = just set the two equates indicated to -true- =
; = and compile. Otherwise get out your manual =
; = and put the code indicated in one of the printer=
; = sections. =
; = **> The title message starts at label =
; = **> -buffer-. If you set for another =
; = **> printer you should change the =
; = **> greeting to indicate which printer =
; = ===> ONLY SET *ONE* CONDITION TO -TRUE- or you =
; = will have a real mess! marty smith =
; =======================================================
TRUE equ 1 ; DON'T CHANGE THESE!
FALSE equ 0
escape equ 27 ; for printer
CR equ 13
LF equ 10
; ===============> A L L U S E R S <===================
; ====> SET ONE AND ONLY ONE OF THE FOLLOWING THREE <=====
EPSON EQU TRUE
CITOH EQU FALSE ; citoh and nec 8023 use similar codes.
NEC EQU FALSE
OTHER EQU FALSE
; Each bit of a byte is mapped to the wire head of the printer.
; If the Epson MX is sent 80h (bit 7), the TOP wire makes a dot.
; If the C.ITOH is sent 01h (bit 0), the TOP wire makes a dot.
; ===============> A L L U S E R S <===================
; =====> SET ONE AND ONLY ONE OF THE FOLLOWING TWO <======
BIT7 EQU TRUE
BIT0 EQU FALSE
; BIT7 is TRUE for EPSON
; BIT0 is TRUE for CITOH,NEC8023
print macro char
mov al,char
call SEND2
endm
; *****************************
; * START of -OTHER- SECTION *
; *****************************
;
; ALL routines must set either BIT7 or BIT0.
; above. If your printer can't see bit 7 or 0 as the top wire, you
; will probably have quite a time getting this routine to work.
;
; OLINE Resets line spacing so that the print head
; will make a continuous line DOWN the page.
; This is the sequence to set the EPSON for this. (ESC A 8)
; SEND2 sends the byte in AL to the printer for ALL routines.
; It uses the INT 17h routine in order to avoid DOS's extra line
; feeds and CR's. Set for LPT1: Change SEND2 to redirect. DX=0=LPT1,1=LPT2
OLINE MACRO
print escape
print 'A'
print 8
ENDM
; ORLINE restores the printer to normal line spacing
; Example is for EPSON (ESC 2)
ORLINE MACRO
print escape
print '2'
ENDM
; ORESET reinitializes the printer to default settings, spacings,
; current line becomes Top of Form.
; Is used by LARGE print to allow a series to be printed
; on separate pages. It can be modified by getting rid of label
; TOF: up to but not including JMP DONE, which is the exit from
; the whole routine. Example is for EPSON. (ESC @)
ORESET MACRO
print escape
print '@'
ENDM
; BP1 initiates bit-plot graphics. It tells the printer
; that the next xxx bytes are to be considered bit-plots and not
; regular characters. The small print routine sends 320 bit plot bytes
; to the printer. On the EPSON this is:
; ESC K 64 1 hex 1b 4b 40 1 > 1*256+64=320
; --> the first part indents the page with ordinary spaces
; --> to find spaces take TOTAL_DOTS_PER_LINE - 320. Then / BITS_PER_CHARACTER
; --> Divide this by two and you have the spaces to indent
; BP1 also needs to be able to handle the case of 640 mode, which will
; double the output of dots.
; The example below is the code to do this on the EPSON/IBM.
BP1 MACRO
mov cx,13 ; PICTURE ( we've got 320 dots and 480 to work with
inlop: print 20H ; 480-320=160 / 6 dots per char. = 26.67 extra
loop inlop
; ESC K 64 1 = 256+64=320 bit plot type bytes on the way
cmp cs:mode640,TRUE
jz ind10
print escape ; SEQUENCE TO SET UP 320
; BIT PLOTS IN 480 MODE
print 'K' ; OF MX-80
; This is the set-up for the small print
print 64
print 1
jmp short indend
ind10:
print escape
print 'L' ; 640 dots in 960 mode
print 128
print 2
indend:
ENDM
; BP2.
; The LARGE print sends 400 bit plot bytes to the printer. On the EPSON:
; ESC K 144 1 hex 1b 4b 90 1 > 1*256+144=400
; FIND YOUR INDENT FOR 400 BITS
BP2 MACRO
mov cx,6 ; EPSON ( we've got 400 dots and 480 to work with
inlop2: print 20H ; 480-400=80 / 6 dots per char. = 13.33 extra
; so indent the picture 6 spaces to center
loop inlop2
print escape
print 'K'
print 144
print 1
ENDM
; ****************************
; * END OF -OTHER- SECTION *
; ****************************
; ***************> START OF ACTUAL CODE <*****************
cseg segment 'code'
assume cs:cseg
org 100h ; set up for .com conversion
init proc
jmp initial ; so we have to set up first
init endp
gowait dw 0
wheresi dw 0
ptflag db 0
oneor2 db 0
dstor dw 0
mode640 dw 0
; **** the 1 below is the POKE to use in CALLing from another program. ****
;
default_routine dw 1 ; 1 for small, 2 for LARGE. *
;
; *************************************************************************
old_print_routine dd 0 ; address of former print screen routine.
do_old proc near
; jump to old routine
pop bp
pop si
pop di
pop dx
pop cx
pop bx
pop ax
pop ds
jmp cs:old_print_routine
do_old endp
; ---> ACTUAL INTERRUPT ROUTINE STARTS HERE <---
start proc far ; Start of main routine--Shift Prt.Sc hit.
assume cs:cseg
sti ; This follows ROM routine real close
push ds
push ax ;SAVE REGS
push bx
push cx
push dx
push di
push si
push bp
mov bp,sp ; Save in case of error for reset
mov ax,50h ; Check here first to see if
mov ds,ax ; routine is already in progress
mov si,0 ; otherwise it will be a mess.
mov al,01h ; if [si]=1 then there is a
cmp [si],al ; print screen already in progress.
jnz nxts ; if not we're go for routine
jmp exit ; otherwise go back home.
nxts: mov [si],al ;
mov ah,15 ; Get the current video state.
int 10h ; from the ROM routine,
mov cs:mode640,FALSE
cmp al,4 ; AL=4-6 are all graphics so we're OK
jz graphic
cmp al,5
jz graphic
cmp al,6
jnz nxts10
mov cs:mode640,TRUE ; special case
jmp short graphic
nxts10:
mov al,0 ; else reset and go to ROM routine.
mov [si],al
jmp do_old ; this is where we stored the ROM routine entry.
; jmp exit ; Do the ROM routine but come back here to leave.
graphic:
mov ax,40h ; Get the keyboard shift flag
mov ds,ax ; segment
mov si,17h ; and address
mov ax,[si] ; pick it up
and ax,3 ; get rid of other stuff
or ax,ax ; Mod. to create default small
jnz gr1 ; for case where routine is called as a subroutine.
mov ax,cs:default_routine
gr1: mov cs:oneor2,al ; store for later
push ax ; also here
xor al,al ; make sure this starts out as NO print.
mov cs:ptflag,al
xor dl,dl ; These bits indicate whether R or L Shift is down
mov dh,19h ; 25 lines of graphic dots at 8 dots per line
mov ax,0b800h ; stored in DX
mov ds,ax ;SET UP FOR SCREEN PEEK
; Printer setup section to change line spacing to 8/72" for continuous dots
; line spacing routine - All Epson Graftrax and IBM Graphics should
; accept esc 'A' 8 or esc '3' 24 for line spacing, but IBM Graphics only
; recognizes esc '3' 24
IF EPSON
print escape
print '3' ; A
print 24 ; 8
ENDIF
IF CITOH ; ESC T 16
print escape
print 'T' ; T
print '1' ; 1
print '6' ; 6
print escape
IF NEC
print '[' ; Set printer to unidirectional for dot alignment
ELSE
print '>'
ENDIF
ENDIF
IF OTHER
OLINE
ENDIF
pop ax ; get back which routine
cmp al,2 ; Left Shift Prt Sc means LARGE graphic print
jnz gr2
jmp main2 ; so hop over there if so.
gr2:
cmp cs:mode640,TRUE
jnz MAIN
jmp m640
; START OF small GRAPHICS PRINT ROUTINE.
; This routine scans across the screen from left to right,
; building an EPSON bit plot byte out of IBM screen dots.
; EPSON wire head IBM screen color dots
; TOP o 128 80h bit 7 | 00 | 01 | 10 | 11 | = 4 dots, one byte
; o 64 40h " 6
; one o 32 20h " 5 ibm dots go one raster line then the next
; bit o 16 10h " 4 EVEN line, ie 0, 2, 4 etc.
; plot o 8 08h " 3
; byte o 4 04h " 2 then you go back and do 1, 3, 5 etc.
; o 2 02h " 1
; BOTTOM o 1 01h " 0 At loc. 0000h are 4 dots, 0,0|0,1|0,2|0,3
; At loc. 2000h are 4 dots, 1,0|1,1|1,2|1,3
;
main: mov cx,80 ; 80 x 4 = 320 dots.
mloop: mov dl,0c0h ; 11000000b
call tst4 ; see if this comes back <> 0
mov al,ah ; we are testing bit patterns for one screen byte
call send ; don't send to printer unless something to send
mov dl,30h ; 00110000b
call tst4 ; each byte is 4 dots
mov al,ah ; so we test for each dot in a byte
call send ; send sets PTFLAG if there is a dot on the line
mov dl,0ch ; 00001100b
call tst4 ; then resets to start of line and starts printing
mov al,ah ; AL is the bit plot byte being built
call send ; This keeps us from printing a line of '0's.
mov dl,03h ; 00000011b
call tst4 ; TST4 scans down 8 screen dot lines each time called
mov al,ah
call send
loop mloop ; 80 bytes make 320 dots
call lfcr ; this is a good old regular line feed/carriage return
call break? ; someone hit ESC key? so take early exit
or al,al
dec dh ; DL is line counter
cmp dh,0 ; when it goes 0 we're through
jz done ; reset everything and do an IRET
mov ax,ds ; otherwise bump the SEGMENT reg so that location
add ax,14h ; 0 is the start of the next line
mov ds,ax ; X'140' = 320
jmp main ; and do this 80 times (80x4=320)
done: mov ax,0
; This is the common exit for both routines, Printer is restored.
done1: push ax ; save AX cause it has error exit flag
; EPSON command to reset printer to 6 lines/in. = ESC 2 (1b 32)
IF EPSON
print escape
print '3'
print 12 ; add 12/216 to reset line spacing
print CR
print LF
print escape ; RESET PRINTER, RESTORE REGS
print '2'
ENDIF
; FOR CITOH MAKE SURE BIDIRECTIONAL PRINTING IS RESTORED
IF CITOH
print escape
print 'A'
print escape
IF NEC
print ']'
ELSE
print '<'
ENDIF
ENDIF
IF OTHER
ORLINE
ENDIF
edone: mov ax,50h ; Set end of PrtSc indication
mov ds,ax ; OK to come back and do again
mov si,0
pop ax
mov [si],al
exit: pop bp
pop si ; restore regs and return to caller
pop di
pop dx
pop cx
pop bx
pop ax
pop ds
iret ; were an interrupt routine so we IRET
; START OF LARGE PRINT ROUTINE
; +-------------+
; | ^ ^ | This time we scan from 199,0 to 0,0
; | ^ ^ | and go across
; | ^ ^ | o o x x o x x x These are representations
; | | | | o o o o x o x x of one color dot.
; +-------------+ 0 1 2 3 Palettes
main2: mov dh,80 ; we have 80 colunms x 25 lines here
mov cs:wheresi,3ef0h ; si is our index
mov si,cs:wheresi
main2a: mov cx,64h ; 100
mloop2: mov al,[si] ; idea is to get a byte starting at screen BOTTOM
IF BIT0
call reverse ; Bits have to be reversed on wire 0 type
ENDIF
call send ; send it since these resemble bit plot bytes
cmp cs:mode640,TRUE
jz ml10
call flipflop ; then reverse(sort of) this byte and send it
ml10:
call send ; again.
mov cs:gowait,si ; store SI for next EVEN raster line
sub si,2000h ; subtract 2000h for the next ODD raster line
mov al,[si] ; and do the same here
IF BIT0
call reverse
ENDIF
call send
cmp cs:mode640,TRUE
jz ml20
call flipflop
ml20:
call send
mov si,cs:gowait ; get back the EVEN line
sub si,80 ; advance UP the screen one line (say 199,0 to 197,0)
loop mloop2 ; and do this 100 times
call lfcr ; finished with one line we send normal line-end
call break? ; check for an ESC if we want to abort
or al,al ; clear flags
dec dh ; DH is our line counter,
cmp dh,0 ; when it goes 0 we're done.
jz tof ; so we'll try to reset Top of Form and exit
inc cs:wheresi ; else go to the next byte location
mov si,cs:wheresi ; store
jmp main2a ; and do again
tof: mov cx,19 ; tof restores page to 11 inches from where it started
tofl: print 13 ; send a bunch of cr's and lf's
print 10
call break? ; check for early exit
loop tofl ; on and on.
; This restores the EPSON to 6 lines per inch
; ESC @ = Restore all settings to default
IF EPSON
print escape
print '@'
ENDIF
; IF CITOH ; No equivalent to Epson ESC @
; MOV AL,escape ; for CITOH
; CALL SEND2 ; so just reset line feed pitch
; MOV AL,'A' ; this is done by DONE anyway
; CALL SEND2 ; so leave open if someone wants to patch
; ENDIF
IF OTHER
ORESET
ENDIF
jmp done ; clean up and back to caller.
start endp
send2 proc near ; BIOS routine to print the character in AL
push ax
mov ah,00h ; 0=print, 1=initialize port, 2=read status to AH
push dx
mov dx,0 ; DX specifies printer 0 (LPT1:)
int 17h ; BIOS used instead of DOS because DOS sends
pop dx ; CR/LF's in the middle of the bit-plots
test ah,29h ; check for timeout or errors or out-of-paper
pop ax
jnz erret
ret
erret: mov ax,00ffh ; Flag for printer foulup
mov sp,bp
push ax
jmp edone ; special abort
send2 endp
; EPSON bit plots operate at 480 or 960 dots across the page
; called by ESC K 'low byte';'high byte'
; i.e. 300 dots would be 256+44 or 012CH
; This is sent to the EPSON as --> 1b 4b 2c 01
; or in decimal --> 27 75 44 1
indent proc near
push cx ; 13 spaces in to center
IF EPSON
mov cx,13 ; PICTURE ( we've got 320 dots and 480 to work with
inlop: print 20h ; 480-320=160 / 6 dots per char. = 26.67 extra
; so indent the picture 13 spaces to center
loop inlop
; ESC K 64 1 = 256+64=320 bit plot type bytes on the way
cmp cs:mode640,TRUE
jz ind10
print escape ; SEQUENCE TO SET UP 320
; BIT PLOTS IN 480 MODE
print 'K' ; OF MX-80
; This is the set-up for the small print
print 64
print 1
jmp short indend
ind10:
print escape
print 'L' ; 640 dots in 960 mode
print 128
print 2
indend:
ENDIF
IF CITOH
print escape ; ESC N = Pica pitch
print 'N'
cmp cs:mode640,TRUE
jz ind10
mov cx,20 ; PICTURE ( we've got 320 dots and 640 to work with )
inlop: print 20h ; 640-320=320 / 8 dots per char. = 40 extra
; so indent the picture 13 spaces to center
loop inlop
jmp ind20
ind10:
print escape
print 'S'
print '0'
print '6'
print '4'
print '0'
jmp ind30
ind20:
; ESC S 0320 = 320 bit plot type bytes on the way
print escape ; SEQUENCE TO SET UP 320 BIT PLOTS IN 640 MODE
print 'S' ; OF CITOH This is the set-up for the small print
print '0' ; Would love to try to use all 640 bits here
print '3'
print '2'
print '0'
ind30:
ENDIF
IF OTHER
BP1
ENDIF
pop cx
ret
indent endp
; This is indent for LARGE print
; This time we have 400 bit plots to send (200 lines x 2)
; 480-400=80 / 6 = 13.3 extra
indent2 proc near
push cx
IF EPSON
mov cx,6 ; so indent 6 character type spaces
inlop2: print 20h
loop inlop2
; ESC 27 K 144 1 = 256+144=400 bit-plots
print escape
print 'K'
print 144
print 1
ENDIF
; 640-400=240 / 8 = 30 EXTRA characters
IF CITOH
print escape ; ESC N = Pica pitch
print 'N'
mov cx,15 ; PICTURE ( we've got 400 dots and 640 to work with
inlop2: print 20h ; 640-400 / 8 dots per char. = 30 extra so indent
; the picture 15 spaces to center
loop inlop2
; ESC S 0400 = 400 bit plot type bytes on the way
print escape ; SEQUENCE TO SET UP 400 BIT PLOTS IN 640 MODE
print 'S' ; OF CITOH
print '0'
print '4'
print '0'
print '0'
ENDIF
IF OTHER
BP2
ENDIF
pop cx
ret
indent2 endp
m640 proc near
m6ain: mov cx,80 ; 80 x 4 = 320 dots.
m6loop: mov dl,80h ; 10000000b
call tst4 ; see if this comes back <> 0
mov al,ah ; we are testing bit patterns for one screen byte
call send ; don't send to printer unless something to send
mov dl,40h ; 01000000b
call tst4 ; each byte is 4 dots
mov al,ah ; so we test for each dot in a byte
call send ; send sets PTFLAG if there is a dot on the line
mov dl,20h ; 00100000b
call tst4 ; then resets to start of line and starts printing
mov al,ah ; AL is the bit plot byte being built
call send
mov dl,10h ; 00010000b
call tst4 ; TST4 scans down 8 screen dot lines each time called
mov al,ah
call send
mov dl,08h ; 00001000b
call tst4 ; see if this comes back <> 0
mov al,ah ; we are testing bit patterns for one screen byte
call send ; don't send to printer unless something to send
mov dl,04h ; 00000100b
call tst4 ; each byte is 4 dots
mov al,ah ; so we test for each dot in a byte
call send ; send sets PTFLAG if there is a dot on the line
mov dl,02h ; 00000010b
call tst4 ; then resets to start of line and starts printing
mov al,ah ; AL is the bit plot byte being built
call send
mov dl,01h ; 00000001b
call tst4 ; TST4 scans down 8 screen dot lines each time called
mov al,ah
call send
loop m6loop ; 80 bytes make 320 dots
call lfcr ; this is a good old regular line feed/carriage return
call break? ; see if someone hit ESC key. If so take early exit
or al,al
dec dh ; DL is line counter
cmp dh,0 ; when it goes 0 we're through
jz d6one ; reset everything and do an IRET
mov ax,ds ; otherwise bump the SEGMENT reg so that location
add ax,14h ; 0 is the start of the next line
mov ds,ax ; X'140' = 320
jmp m6ain ; and do this 80 times (80x4=320)
d6one: mov ax,0
jmp done1
m640 endp
tst4 proc near ; This routine builds ONE bit plot byte
mov ax,80 ; by testing a dot with the mask sent
sub ax,cx ; from MLOOP.
mov si,ax ; First it does the ODD row then the EVEN
mov ah,0 ; since alternate lines are offset 2000h
mov al,[si] ; from each other in memory.
and al,dl ; DL has the mask
cmp al,0 ; SI the location
jz no7 ; AL the memory byte
call set7 ; AH is the byte being built
no7: add si,80 ; +80 gets us from say 0,0 to 2,0
mov al,[si] ; get the memory byte ( 4 dots )
and al,dl ; get rid of dots we aren't testing now
cmp al,0 ; see if its COLOR 0
jz no5 ; if yes, go on
call set5 ; otherwise set that bit
no5: add si,80 ; continue 7 5 3 1
mov al,[si]
and al,dl
cmp al,0
jz no3
call set3
no3: add si,80
mov al,[si]
and al,dl
cmp al,0
jz no1
call set1
no1: push ax
mov ax,80
sub ax,cx ; CX counts our screen position
add ax,2000h ; add 2000h for the EVEN rows
mov si,ax ; with seg set to B800h we can use SI like an
pop ax ; array pointer ( AH has our byte so don't lose )
mov al,[si] ; and continue with the same idea for 6 4 2 0
and al,dl
cmp al,0
jz no6
call set6
no6: add si,80
mov al,[si]
and al,dl
cmp al,0
jz no4
call set4
no4: add si,80
mov al,[si]
and al,dl
cmp al,0
jz no2
call set2
no2: add si,80
mov al,[si]
and al,dl
cmp al,0
jz no0
call set0
no0: ret
; where's my Z80 now
; reverse this table if your bit plots use bit 0 for the top wire
IF BIT7
set7: or ah,80h ; top wire - bit 7
ret
set6: or ah,40h ; bit 6
ret
set5: or ah,20h ; bit 5
ret
set4: or ah,10h ; bit 4
ret
set3: or ah,08h ; bit 3
ret
set2: or ah,04h ; bit 2
ret
set1: or ah,02h ; bit 1
ret
set0: or ah,01h ; bit 0
ret
ENDIF
IF BIT0
set7: or ah,01h ; top wire - bit 0
ret
set6: or ah,02h ; bit 1
ret
set5: or ah,04h ; bit 2
ret
set4: or ah,08h ; bit 3
ret
set3: or ah,10h ; bit 4
ret
set2: or ah,20h ; bit 5
ret
set1: or ah,40h ; bit 6
ret
set0: or ah,80h ; bit 7
ret
ENDIF
tst4 endp
; This routine pre-scans a line to see if in fact there are any bit
; plots to send. The main routine will keep sending bytes here
; If a whole line of 0's are sent we avoid going through the
; set-up for bit-plot (i.e. slower movement) graphics when a CR/LF
; would take care of everything.
; If there IS something to send, PTFLAG is set, the current line
; position is set to 0, bit-plot is init., and bits are really sent to printer.
send proc near
push ax ; save the character
push ds ; DS saved cause it points to lines
mov ax,cs ; set seg for here
mov ds,ax ; This was some of my first stuff with the 8088
pop ax ; and I see some needless complexity here now
mov cs:dstor,ax ; but it works and if I mess with it
cmp cs:ptflag,0ffh ; its back to DEBUG.
jnz nosend ; if PTFLAG isn't FFh we are still scanning
pop ax ; else get the char. in AL and print it
call send2 ; this is the real out to printer routine
jmp short noset ; restore DS and return
nosend: pop ax ; This is the SCAN routine
cmp al,0 ; get the char. > test for 0 > if so reset and go back
jz noset
mov al,0ffh ; if <> 0
mov cs:ptflag,al ; set PTFLAG to go
pop ax ;DISCARD RETURN
cmp cs:oneor2,1 ; check which (small or LARGE)
jnz two ; indent 6 or 13 depending on which routine
cmp cs:mode640,TRUE
jz nos10
call indent ; indent also sets up bit-plot mode
call noset ; NOSET will restore DS to right pos.
jmp main ; and do the line for real.
nos10:
call indent
call noset
jmp m6ain
two: call indent2 ; init. for LARGE
mov si,cs:wheresi ; SI set back to start of line
call noset ; get right DS
jmp main2a ; back to beginning
noset: push ax ; routine to restore DS
mov ax,cs:dstor
mov ds,ax
pop ax
ret
send endp
lfcr proc near ; send a regular CR/LF combo
print 13
print 10
mov ax,0
mov cs:ptflag,al ; reset PTFLAG for next line
mov ax,cs:dstor ; restore DS
mov ds,ax
ret ; onward
lfcr endp
break? proc near ; Test for early exit
push ax ; don't lose any regs. here
push dx
mov ah,01h ; call direct keyboard io (constat) by BIOS
int 16h
jnz goback? ; if zero flag clear we have a character
bcont: pop dx ; no char. return
pop ax
ret
goback?:
mov ah,0
int 16h
cmp al,1bh ; ESC
jz back ; so go back, else return
jmp short bcont ; no ESC exit
back: pop dx ; ESC exit This doesn't check for Ctrl-Break
pop ax ; so if it is hit we save it for the caller to handle
pop ax ;DISCARD RETURN
jmp done ; and go back to orig. caller
break? endp
flipflop proc near ; This creates different combinations
push cx ; of a box of four bit-plot dots for one color dot.
push bx ; Don't lose any variables or loop counters
push ax
mov cl,2 ; AL has present bit-plot finished byte
mov bx,0
and al,3 ; 00000011b
call flip
ror bl,cl ; 11000000b
pop ax ; basically rotate bits around for
push ax ; o x
call r2 ; x o color 1
and al,3 ; and
call flip ; o x
ror bl,cl ; o x color 2
pop ax ; instead of
push ax ; x o
call r4 ; x o color 1
and al,3 ; and
call flip ; o x
ror bl,cl ; o x color 2
pop ax ; which aren't to convincing as
call r6 ; two different patterns
and al,3
call flip
ror bl,cl
mov al,bl
pop bx
pop cx
ret
r6: ror al,cl
r4: ror al,cl
r2: ror al,cl
ret
flip: cmp al,3 ; make sure there are two dots for color 1 and 2
jnz flip2
or bl,3
flip2: cmp al,2
jnz flip3
or bl,1
flip3: cmp al,1
jnz flip4
or bl,1
flip4: ret
flipflop endp
reverse proc near ; take AL and make bit 0 bit 7 , 1 - 6, etc
push dx ; Save our counters and masks
push cx
mov dl,01h ; 00000001B
mov dh,80h ; 10000000B
mov ah,00h ; start out blank
mov cx,8 ; set counter for 8 times through
rev1: test al,dl ; see if bit is set
jz rev2 ; if not skip next step
or ah,dh ; else set bit in AH
rev2: shl dl,1 ; shift left test bit
shr dh,1 ; shift right mask bit (pad other bits with 0)
loop rev1 ; do this 8 times
mov al,ah ; and we have a reversed character.
pop cx ; get back these
pop dx
ret ; and back to caller
reverse endp
last dw 0
buffer db ' GRAFTRAX.COM v3.4',10,13
if EPSON
db 'EPSON/IBM GRAFTRAX(tm) Screen Printer.',13,10
else
db ' Graphics Screen Printer',13,10
endif
db ' Left Shift PrtSc = LARGE GRAPHICS',13,10
db ' Right Shift PrtSc = small graphics',13,10
db ' Text mode uses regular print routine.',13,10
db ' ESCape will exit GRAPHICS print.',13,10,'$'
werehere db ' ** GRAF.COM is already resident **',13,10,10
db ' There is no need to reinstall.',13,10,'$'
initr proc far
initial:
mov ax,0 ; get addr of
mov ds,ax ; print screen routine
mov si,14h ; in rom
mov ax,[si] ; from interrupt table in ram
inc si
inc si
mov dx,[si]
mov word ptr cs:old_print_routine,ax
mov word ptr cs:old_print_routine+2,dx
mov cx,offset last-offset start
mov di,ax
mov si,offset start
cmp dx,0efffh ; if routine points to ROM, ours is not it.
ja initok
cmp si,di
jne initok ; if start location not same, it can't be ours.
; otherwise check to see if this routine is
mov es,dx ; already in memory, and don't reinstall if so.
mov ax,cs
mov ds,ax
repe cmpsb
or cx,cx ; cx=0 means there is a copy of this at the
jnz initok ; other address.
mov dx,offset werehere
mov ah,9 ; so we print a message and
int 21h ; abort.
int 20h
initok:
; mov ds,ax
; mov al,0f1h ; move it to
; mov ah,25h
; int 21h ; int f1h described in tech. manual as unused vector
mov ax,cs ; reset int 5
mov ds,ax ; to point to
mov ax,offset start ; this routine
mov dx,ax
mov al,5
mov ah,25h ; dos routine to reset int. vector
int 21h
mov ax,offset buffer
mov dx,ax
mov ah,9
int 21h ; print greeting
mov ax,3000h ; get dos version
int 21h
or al,al
jz dos1
mov ax,offset last
mov cx,16
xor dx,dx
div cx
inc ax ; make number of paragraphs
mov dx,ax
mov al,0 ; exit code
mov ah,31h ; terminate process, keep resident
int 21h
dos1:
mov dx,offset last ; last address here
inc dx
int 27h ; terminate but stay resident
initr endp
cseg ends
end init
1 ' GRAFTRAX as a subroutine 3/12/83
9 ' *********** Get some graphics going for this demo *******************
10 DEFINT A-Z
15 KEY OFF : KEY 7,"gosub 65000"+CHR$(13)
20 TOG=2 : GOSUB 65010 ' use color for this demo
30 SCREEN 1,0 :OUT 980,2:OUT 981,45 ' 45 is standard. 43 shifts 2 chars. right
40 COLOR 0,0 : CLS
50 CIRCLE (160,100),50,3 : CIRCLE (160,100),75,3 : PAINT (160,100),1,3 : PAINT(160,40),2,3 ' draw some graphics
55 ' make sure variables used in this routine are defined BEFORE they are used.
56 ' integer variable descriptors, i.e. variable% should be used in this routine if a DEFINT statement is not present. They are here as a r
59 ' ****************** SETUP ***************************
60 X%=0 : Y%=0 : Z%=0 : GRAFTRAX%=0 : GRSEG%=0 : A$="" : DIM STACK%(50),CG%(10)
70 DEF SEG : Y% = VARPTR(CG%(0))
80 FOR X% = 0 TO 17 : READ Z% : POKE X% + Y% ,Z% : NEXT ' poke routine into an array
85 DEF SEG=0 : X%=PEEK(&H16) : Y%=PEEK(&H17) : DEF SEG : GRSEG%=X%+(256*Y%) ' GRSEG is the location where DOS put GRAFTRAX.COM
90 INPUT "small or LARGE";A$ : A$=LEFT$(A$,1) : IF A$="l" OR A$="L" OR A$="2" THEN X% = 2 ELSE X% = 1
100 ' ******** ACTUAL ROUTINE - use GOSUB, with RETURN at END **********
110 DEF SEG = GRSEG% : POKE &H273,X% : DEF SEG ' &h273 is the location in GRAFTRAX.COM that sets a default of 1 = small, 2 = LARGE i
120 GRAFTRAX% = VARPTR(CG%(0)) : Y% = VARPTR(STACK%(50)) ' stack builds DOWN.
130 CALL GRAFTRAX%(Y%) : ' y% is actually a temporary stack passed to the CALL, since BASIC only leaves 16 bytes. INT routines use lots of
140 ' At some times, GRAFTRAX.COM is 34 words deep in the stack!
150 END
1000 DATA &h55,&H8b,&Hec,&H8b,&H76,&H06,&H8b,&H1c,&H8b,&He3,&Hcd,&H05,&H8b,&He5,&H5d,&Hca,&H02,&H00
65000 IF TOG=1 THEN TOG=2 ELSE TOG=1
65010 ON TOG GOSUB 65080, 65030
65020 RETURN
65030 REM toggle color graphics
65040 DEF SEG=0
65050 POKE &H410, (PEEK(&H410) AND &HCF) OR &H10
65060 SCREEN 1,0,0,0: SCREEN 0:WIDTH 40:LOCATE ,,1,6,7
65070 RETURN
65080 REM toggle monochrome display
65090 DEF SEG=0
65100 POKE &H410, (PEEK(&H410) OR &H30)
65110 SCREEN 0:WIDTH 40:WIDTH 80:LOCATE ,,1,12,13
65120 RETURN
****************************************************************************
* -- GRAFTRAX.COM v3.4 -- *
****************************************************************************
GRAFTRAX.COM is for printing IBM-PC graphics on bit-plot printers.
The program as delivered works with EPSON GRAFTRAX (tm) and IBM GRAPHICS(tm)
printers, but can be modified to work with others, such as the C.ITOH 8510a,
and NEC 8023a. OKIGRAF.(ASM, COM) is a special version for 7-bit graphics
printers and works with the Okidata 84, 92 and 93.
GRAFTRAX represents the latest version of the program. It does everthing
the old one does and now does high-res. graphics much more clearly.
This version has some small changes, including some to insure compatibility
with future versions of DOS, but the main improvement is correct handling
of the high-resolution 640x200 graphics mode. GRAFTRAX originally was
created to reproduce medium resolution color graphics.
If you have other memory resident programs you load when you start up your
system you know that sometimes they must be loaded in a certain order to
work properly. This is not the case with GRAFTRAX, the only time you
should not load it for the first time is from another program.
GRAFTRAX.COM is created by running the program from DOS. GRAFTRAX
announces itself and will remain a part of your system until reset or
power down. Once run, the Shift+PrtSc keys will work as always with text
on the screen, sending it to the printer. If you have graphics running
on the screen and GRAFTRAX in your printer, the screen can be sent to the
printer in two ways. A small (5 1/4 x 3 1/4) print with the
RIGHT-Shift+PrtSc keys, and LARGE (almost a full 8 1/2 x 11 page) print
with the LEFT- Shift+PrtSc keys.
CALLGRAF.BAS is a demo program showing how to call GRAFTRAX.COM from a
BASIC program.
GRAFTRAX.ASM is the source code for GRAFTRAX.COM. With the IBM MACRO-
ASSEMBLER(tm) it will produce GRAFTRAX.EXE. Use the EXE2BIN command to
create GRAFTRAX.COM. Conditional compilation allows easy assembly for
the C.ITOH 8510a or other printers with bit-plot capabilties. The first
part of the listing explains the history of the program and explains how
to assemble for other printers.
Program by:
Marty Smith COMPUSERVE 72155,1214
310 Cinnamon Oak Lane
Houston, Texas 77079
(713) 464-6737 (Home)
3/18/85
100 ' HOST.BAS VERSION 1.00
110 '
120 ' ************************************************************************
130 ' ************************************************************************
140 '
150 ' HOST COMPUTER
160 '
170 ' This program provides the capability to access an IBM Personal
180 ' Computer for the purpose of transmitting or receiving an ASCII
190 ' file from a remote location. It assumes the use of a Hayes
200 ' Smartmodem.
210 '
220 ' Upon receiving a carrier from the remote location, the program
230 ' requests the password. It signs off if the correct password is not
240 ' given in three tries.
250 '
260 ' The program recognizes 7 commands from the user at the remote
270 ' location. They are:
280 ' A - List the files on drive A.
290 ' B - List the files on drive B.
300 ' G - Signoff (GOODBYE).
310 ' M - Send message.
320 ' R - Receive a file from the remote location.
330 ' T - Transmit a file to the remote location.
340 ' ? - Summarize the commands.
350 '
360 ' Received files are opened for APPEND so that data is attached to the
370 ' end of a previously used file. Also, if in the RECEIVE FILE mode, 15
380 ' seconds passes with no activity, the user at the remote location is
390 ' asked if the end of file has been reached. If the answer is in the
400 ' affirmative or if there is no response within 1 minute, the file is
410 ' closed and the RECEIVE FILE mode is deactivated.
420 '
430 ' The program recognizes 3 commands from the system operator at the IBM
440 ' PC's location. They are:
450 ' ALT E - Echo on / Echo off.
460 ' CTRL Prtsc - Printout on/ Printout off.
470 ' ALT M - Send message to remote location or to Smartmodem.
480 '
490 ' An active communications link times out after 5 minutes of inactivity.
500 '
510 ' ************************************************************************
520 ' WILLIAM HT BAILEY PHONE: 215-924-0771 JUNE 1982
522 '
525 ' DEBUGGED WITH THE HELP OF HOWARD CARTER
530 ' ************************************************************************
540 ' ************************************************************************
1000 '
1010 ' ------------ INITIALIZATION ------------
1020 '
1030 OPTION BASE 1: DIM MSG$(32): DEF SEG: POKE 106,0: CLOSE: CLS: KEY OFF
1040 DEFINT A-Z: XOFF$=CHR$(19): XON$=CHR$(17): CNT=0: FALSE=0: TRUE=NOT FALSE
1050 PAUSE=FALSE: PRNT=FALSE: ECHO=FALSE: RECV=FALSE: TRANS=FALSE: MESG=FALSE
1060 TIMER=FALSE: BYE=FALSE: ACTIVE=FALSE: AA=FALSE: CONNECT=FALSE: LF=FALSE
1065 OPMSG=FALSE: C$=""
1070 '
1080 MSG$(1)=CHR$(13)+CHR$(10)
1090 MSG$(2)="PASSWORD? "
1100 MSG$(3)="TRY AGAIN"+MSG$(1)
1110 MSG$(4)="*** ENTER ? FOR SUMMARY OF COMMANDS ***"+MSG$(1)
1120 MSG$(5)=">"
1130 MSG$(6)=MSG$(1)+"FILES A"+MSG$(1)
1140 MSG$(7)=MSG$(1)+"FILES B"+MSG$(1)
1150 MSG$(8)="*** GOODBYE ***"+MSG$(1)
1160 MSG$(9)="ENTER FILENAME IN THE FORMAT (DRIVE):(FILESPEC) "
1170 MSG$(10)=MSG$(1)+"*** READY TO RECEIVE FILE ***"+MSG$(1)
1180 MSG$(11)="RECEPTION SUSPENDED. END OF FILE? (Y/N) "+MSG$(1)+CHR$(7)
1190 MSG$(12)="*** RECEPTION TERMINATED ***"+MSG$(1)+CHR$(7)
1200 MSG$(13)=MSG$(1)+"*** TRANSMISSION BEGINNING IN 15 SECONDS ***"+MSG$(1)
1210 MSG$(14)=" TYPE X TO ABORT TRANSMISSION"+MSG$(1)
1220 MSG$(15)="*** TRANSMISSION COMPLETE ***"+MSG$(1)+CHR$(7)
1230 MSG$(16)=MSG$(1)+" --- SUMMARY OF COMMANDS ---"+MSG$(1)
1240 MSG$(17)="A - LIST THE FILES ON DRIVE A"+MSG$(1)
1250 MSG$(18)="B - LIST THE FILES ON DRIVE B"+MSG$(1)
1260 MSG$(19)="G - SIGNOFF (GOODBYE)"+MSG$(1)
1270 MSG$(20)="M - SEND MESSAGE"+MSG$(1)
1280 MSG$(21)="R - RECEIVE A FILE FROM YOUR LOCATION"+MSG$(1)
1290 MSG$(22)="T - TRANSMIT A FILE TO YOUR LOCATION"+MSG$(1)
1300 MSG$(23)="? - PRINT THE SUMMARY OF COMMANDS"+MSG$(1)+MSG$(1)
1310 MSG$(24)="--- FILE NOT FOUND ---"+MSG$(1)
1320 MSG$(25)="--- DISK IS FULL ---"+MSG$(1)
1330 MSG$(26)="--- BAD FILE NAME ---"+MSG$(1)
1340 MSG$(27)="--- TOO MANY FILES ---"+MSG$(1)
1350 MSG$(28)="--- DISK WRITE PROTECTED ---"+MSG$(1)
1360 MSG$(29)="--- DISK NOT READY ---"+MSG$(1)
1370 MSG$(30)="--- ERROR CONDITION ENCOUNTERED ---"+MSG$(1)
1380 MSG$(31)="ENTER 1 LINE MESSAGE"+MSG$(1)
1390 MSG$(32)="*** SYSTEM OPERATOR MESSAGE ***"+MSG$(1)+CHR$(7)
1400 '
1410 ON ERROR GOTO 2070
1420 OPEN "COM1:300,E,7,1" AS #1
1430 '
1440 LOCATE ,,1: PRINT #1,"********** HOST COMPUTER program active **********"
1450 PRINT #1,SPACE$(80);
1460 PRINT #1," WILLIAM HT BAILEY PHONE: 215-924-0771 JUNE 1982"
1700 '
1710 ' ***********************************************************************
1720 '
1730 ' --------- MAIN PROCESSING LOOP ---------
1740 '
1750 B$=INKEY$: IF LEN(B$)>1 THEN GOSUB 2240
1760 '
1770 IF LOF(1)<128 THEN PAUSE=TRUE: PRINT #1,XOFF$;
1780 IF EOF(1) THEN IF NOT AA THEN PRINT #1,"ATS0=1": AA=TRUE: GOTO 1895 ELSE GOTO 1895
1790 A$=INPUT$(LOC(1),#1)
1795 IF LF THEN LF=FALSE: C$=""
1797 IF LEN(C$)<254 THEN C$=C$+A$
1800 '
1810 FOR I=1 TO LEN(A$)
1820 D$=MID$(A$,I,1)
1825 IF D$=CHR$(13) OR D$=CHR$(10) THEN LF=TRUE
1830 IF D$=CHR$(10) THEN GOTO 1870
1840 IF PRNT AND NOT OPMSG THEN LPRINT D$;
1850 IF D$=CHR$(8) THEN IF POS(0)>1 THEN LOCATE ,POS(0)-1: PRINT " ";: LOCATE ,POS(0)-1: GOTO 1870
1860 PRINT D$;
1870 NEXT I: IF NOT LF THEN 1895
1875 '
1880 GOTO 3050
1890 '
1895 IF BYE THEN CNT2=CNT2+1: IF CNT2=1000 THEN 4550
1900 IF LOC(1)>0 OR BYE THEN 1750
1910 IF PAUSE THEN PAUSE=FALSE: PRINT #1,XON$;
1920 IF NOT CONNECT THEN 1750
1930 IF T1>VAL(MID$(TIME$,4,2))+(VAL(LEFT$(TIME$,2))*60) THEN 1750
1940 GOTO 4550
2000 '
2010 ' ***********************************************************************
2020 '
2030 ' ------------- SUBROUTINES --------------
2040 '
2050 ' ERROR HANDLER
2060 '
2070 M=30
2080 IF ERR=24 THEN PRINT "*** MODEM NOT READY ***": BEEP: STOP
2090 IF ERR=69 THEN RESUME
2100 IF ERR=27 THEN PRINT "PRINTER NOT READY ***": BEEP: RESUME NEXT
2110 IF ERR=53 THEN M=24
2120 IF ERR=61 THEN M=25
2130 IF ERR=64 THEN M=26
2140 IF ERR=67 THEN M=27
2150 IF ERR=70 THEN M=28
2160 IF ERR=71 THEN M=29
2170 IF M<>30 THEN PRINT MSG$(M): BEEP: GOTO 2190
2180 PRINT "--- ERROR";ERR;" ENCOUNTERED ON LINE";ERL;" ---": BEEP
2190 PRINT #1,MSG$(M);: IF PRNT THEN LPRINT MSG$(M);
2200 RECV=FALSE: TRANS=FALSE: CLOSE #2: RESUME 4160
2210 '
2220 ' SYSTEM OPERATOR COMMAND
2230 '
2240 CODE=ASC(MID$(B$,2,1))
2250 '
2260 IF CODE<>18 THEN 2300
2270 IF ECHO=FALSE THEN ECHO=TRUE: BEEP: PRINT "--- ECHO ON ---": RETURN
2280 ECHO=FALSE: BEEP: PRINT "--- ECHO OFF ---": RETURN
2290 '
2300 IF CODE<>114 THEN 2340
2310 IF PRNT=FALSE THEN PRNT=TRUE: BEEP: PRINT "--- PRINTOUT ON ---": RETURN
2320 PRNT=FALSE: BEEP: PRINT "--- PRINTOUT OFF ---": RETURN
2330 '
2340 IF CODE<>50 THEN RETURN
2350 PRINT #1,MSG$(32);: IF PRNT THEN LPRINT MSG$(32);
2355 IF ECHO THEN PRINT MSG$(32);
2360 IF NOT PAUSE THEN PRINT #1,XOFF$;
2370 B$=INKEY$
2380 IF LEN(B$)>1 THEN 2370
2390 IF B$="" THEN 2370 ELSE PRINT #1,B$;
2400 IF ECHO THEN PRINT B$;
2410 IF PRNT THEN LPRINT B$;
2420 IF B$<>CHR$(10) AND B$<>CHR$(13) THEN 2370
2430 IF NOT PAUSE THEN PRINT #1,XON$;
2435 OPMSG=TRUE
2440 RETURN
3000 '
3010 ' ***********************************************************************
3020 '
3030 ' ------------ COMMAND DECODE ------------
3040 '
3050 IF MESG THEN MESG=FALSE: GOTO 4160
3060 IF ACTIVE THEN 3130
3070 IF CONNECT THEN 3100
3080 '
3090 IF INSTR(C$,"NECT")<>0 THEN CONNECT=TRUE: GOTO 4050 ELSE GOTO 1900
3100 IF INSTR(C$,"WORD")<>0 OR INSTR(C$,"word")<>0 THEN VALID=TRUE: GOTO 4080
3110 VALID=FALSE: GOTO 4080
3120 '
3130 IF RECV OR TRANS THEN 3280
3140 IF BYE THEN 4550
3150 '
3160 IF OPMSG THEN OPMSG=FALSE: GOTO 4160
3165 IF INSTR(C$,"CARRIER")<>0 THEN BYE=TRUE: GOTO 4550
3170 IF INSTR(C$,"M")<>0 OR INSTR(C$,"m")<>0 THEN 5150
3180 IF INSTR(C$,"?")<>0 THEN 5200
3190 IF INSTR(C$,"A")<>0 OR INSTR(C$,"a")<>0 THEN C$="A": M=6: GOTO 5070
3200 IF INSTR(C$,"B")<>0 OR INSTR(C$,"b")<>0 THEN C$="B": M=7: GOTO 5070
3210 IF INSTR(C$,"R")<>0 OR INSTR(C$,"r")<>0 THEN 6050
3220 IF INSTR(C$,"T")<>0 OR INSTR(C$,"t")<>0 THEN 7050
3230 IF INSTR(C$,"G")<>0 OR INSTR(C$,"g")<>0 THEN 4550
3240 PRINT #1,MSG$(3);: IF PRNT THEN LPRINT MSG$(3);
3250 IF ECHO THEN PRINT MSG$(3);
3260 GOTO 4160
3270 '
3280 M=INSTR(C$,"A:"): IF M<>0 THEN 3330
3290 M=INSTR(C$,"a:"): IF M<>0 THEN 3330
3300 M=INSTR(C$,"B:"): IF M<>0 THEN 3330
3310 M=INSTR(C$,"b:"): IF M=0 THEN 3240
3320 '
3330 F$=MID$(C$,M,14)
3340 IF RIGHT$(F$,1)=CHR$(10) OR RIGHT$(F$,1)=CHR$(13) THEN F$= LEFT$(F$,LEN(F$)-1): GOTO 3340
3350 IF RECV THEN 6080 ELSE GOTO 7080
4000 '
4010 ' ***********************************************************************
4020 '
4030 ' --------------- SIGN ON ----------------
4040 '
4050 PRINT #1,MSG$(2);: IF PRNT THEN LPRINT MSG$(2);
4055 IF ECHO THEN PRINT MSG$(2);
4060 T1=VAL(MID$(TIME$,4,2))+(VAL(LEFT$(TIME$,2))*60)+2: GOTO 1900
4070 '
4080 IF VALID THEN 4130
4085 IF INSTR(C$,"CARRIER")<>0 THEN 4655
4090 CNT=CNT+1: IF CNT>=3 THEN 4550
4100 PRINT #1,MSG$(3);: IF PRNT THEN LPRINT MSG$(3);
4105 IF ECHO THEN PRINT MSG$(3);
4110 GOTO 1900
4120 '
4130 ACTIVE=TRUE
4140 PRINT #1,MSG$(4);: IF PRNT THEN LPRINT MSG$(4);
4145 IF ECHO THEN PRINT MSG$(4);
4150 '
4151 ' COME HERE AFTER PROCESSING A COMMAND
4152 '
4160 PRINT #1,MSG$(5);: IF PRNT THEN LPRINT MSG$(5);
4165 IF ECHO THEN PRINT MSG$(5);
4170 '
4180 ' SET TIMEOUT CLOCK
4190 '
4200 T1=VAL(MID$(TIME$,4,2))+(VAL(LEFT$(TIME$,2))*60)+5: GOTO 1900
4500 '
4510 ' ***********************************************************************
4520 '
4530 ' --------------- SIGN OFF ---------------
4540 '
4550 IF BYE THEN 4635
4560 PRINT #1,MSG$(8);: IF PRNT THEN LPRINT MSG$(8);
4565 IF ECHO THEN PRINT MSG$(8);
4570 '
4580 FOR I=1 TO 2000: NEXT I
4590 PRINT #1,"+++";: IF ECHO THEN PRINT "+++"
4600 FOR I=1 TO 2000: NEXT I
4610 '
4620 CNT2=0: BYE=TRUE: GOTO 1900
4630 '
4635 IF INSTR(C$,"CARRIER")<>0 THEN 4655
4640 IF INSTR(C$,"OK")=0 THEN 4580
4655 BYE=FALSE: CONNECT=FALSE: ACTIVE=FALSE: CNT=0
4660 CLS: PRINT "********** HOST COMPUTER program active **********"
4665 PRINT #1,"ATH"
4670 GOTO 1750
5000 '
5010 ' ***********************************************************************
5020 '
5030 ' ----------- COMMANDS A,B,M,? -----------
5040 '
5050 ' LIST FILES (Modifications necessary if using graphics display.)
5060 '
5070 CLS: PRINT #1,MSG$(M);
5080 FILES C$+":*.*": PRINT: DEF SEG=&HB000: FOR I=0 TO (80*(CSRLIN-1)-1)
5090 B$=CHR$(PEEK(2*I)): PRINT #1,B$;: IF PRNT THEN LPRINT B$;
5095 NEXT I
5100 PRINT #1,MSG$(1);: IF PRNT THEN LPRINT MSG$(1);
5105 IF ECHO THEN PRINT MSG$(1);
5110 GOTO 4160
5120 '
5130 ' USER MESSAGE
5140 '
5150 PRINT "*** USER MESSAGE ***": BEEP: PRINT #1,MSG$(31);
5160 IF PRNT THEN LPRINT "*** USER MESSAGE ***"
5165 MESG=TRUE: GOTO 4160
5170 '
5180 ' LIST SUMMARY OF COMMANDS
5190 '
5200 FOR M=16 TO 23
5210 PRINT #1,MSG$(M);: IF PRNT THEN LPRINT MSG$(M);
5215 IF ECHO THEN PRINT MSG$(M);
5220 NEXT M: GOTO 4160
6000 '
6010 ' ***********************************************************************
6020 '
6030 ' ------------- RECEIVE FILE -------------
6040 '
6050 PRINT #1,MSG$(9);: IF PRNT THEN LPRINT MSG$(9);
6055 IF ECHO THEN PRINT MSG$(9);
6060 RECV=TRUE: GOTO 1900
6070 '
6080 OPEN F$ FOR APPEND AS #2
6090 PRINT #1,MSG$(10);: IF PRNT THEN LPRINT MSG$(10);
6095 IF ECHO THEN PRINT MSG$(10);
6100 '
6110 B$=INKEY$: IF LEN(B$)>1 THEN GOSUB 2240
6115 IF OPMSG THEN OPMSG=FALSE
6120 '
6130 IF LOF(1)<128 THEN PAUSE=TRUE: PRINT #1,XOFF$;
6140 IF EOF(1) THEN IF TIMER THEN 6270 ELSE GOTO 6220
6145 IF TIMER THEN TIMER=FALSE
6150 A$=INPUT$(LOC(1),#1): PRINT #2,A$;
6152 FOR I=1 TO LEN(A$): D$=MID$(A$,I,1)
6154 IF D$=CHR$(10) THEN 6158
6156 IF ECHO THEN PRINT D$;
6158 NEXT I
6160 IF LOC(1)>0 THEN 6130
6170 IF PAUSE THEN PAUSE=FALSE: PRINT #1,XON$;
6180 GOTO 6110
6190 '
6200 ' SET TIMEOUT CLOCK
6210 '
6220 T2=VAL(RIGHT$(TIME$,2))+(VAL(MID$(TIME$,4,2))*60)+15
6230 TIMER=TRUE: GOTO 6110
6240 '
6250 ' CHECK TIMEOUT CLOCK
6260 '
6270 IF T2>VAL(RIGHT$(TIME$,2))+(VAL(MID$(TIME$,4,2))*60) THEN 6110
6280 '
6290 ' END OF FILE?
6300 '
6310 PRINT #1,MSG$(11);: IF PRNT THEN LPRINT MSG$(11);
6315 IF ECHO THEN PRINT MSG$(11);
6320 T3=VAL(MID$(TIME$,4,2))+(VAL(LEFT$(TIME$,2))*60)+1
6330 IF T3<VAL(MID$(TIME$,4,2))+(VAL(LEFT$(TIME$,2))*60) THEN 6370
6340 IF EOF(1) THEN 6330
6350 B$=INPUT$(LOC(1),#1): IF INSTR(B$,"Y")=0 AND INSTR(B$,"y")=0 THEN TIMER=FALSE: GOTO 6110
6360 '
6370 PRINT #1,MSG$(12);: IF PRNT THEN LPRINT MSG$(12);
6375 IF ECHO THEN PRINT MSG$(12);
6380 CLOSE #2: RECV=FALSE: TIMER=FALSE: GOTO 4160
7000 '
7010 ' ***********************************************************************
7020 '
7030 ' ------------- TRANSMIT FILE -------------
7040 '
7050 PRINT #1,MSG$(9);: IF PRNT THEN LPRINT MSG$(9);
7055 IF ECHO THEN PRINT MSG$(9);
7060 TRANS=TRUE: GOTO 1900
7070 '
7080 OPEN F$ FOR INPUT AS #2: FOR M=13 TO 14
7090 PRINT #1,MSG$(M);: IF PRNT THEN LPRINT MSG$(M);
7095 IF ECHO THEN PRINT MSG$(M);
7100 NEXT M: FOR I=1 TO 14000: NEXT I
7110 '
7120 B$=INKEY$: IF LEN(B$)>1 THEN GOSUB 2240
7125 IF OPMSG THEN OPMSG=FALSE
7130 '
7140 IF EOF(2) THEN 7210
7150 A$=INPUT$(1,#2): PRINT #1,A$;
7160 IF A$<>CHR$(10) AND ECHO THEN PRINT A$;
7170 '
7180 IF EOF(1) THEN 7120
7190 B$=INPUT$(LOC(1),#1): IF INSTR(B$,"X")<>0 OR INSTR(B$,"x")<>0 THEN 7210
7195 IF INSTR(B$,"CARRIER")<>0 THEN CLOSE #2: TRANS=FALSE: GOTO 4655
7200 '
7210 PRINT #1,MSG$(15);: IF PRNT THEN LPRINT MSG$(15);
7215 IF ECHO THEN PRINT MSG$(15);
7220 CLOSE #2: TRANS=FALSE: GOTO 4160
9996 '
9997 ' **********************************************************************
9998 ' **********************************************************************
9999 END
PROGRAM NAME: HOST.BAS
ABSTRACT: This program allows you to access an IBM PC from a remote location
for the purpose of transmitting or receiving an ASCII file. Upon receiving
a carrier from the remote location, the program requests a password for file
protection.
REQUIRES: IBM PC, ASYNC Communication board, Hayes Smartmodem
Instructions: Contained in the program body.
10 DEFINT A-W : DEFSTR X-Z
20 XON=CHR$(2) : XOFF=CHR$(1)
50 DIM ARRAY(31,31)
60 FOR I=0 TO 23:FOR J=0 TO 17:ARRAY(I,J)=0:NEXT :NEXT
100 FOR I=0 TO 23
110 LOCATE I+1,40
120 FOR J=0 TO 17
130 IF ARRAY(I,J) THEN PRINT XON+" "; ELSE PRINT XOFF+" ";
140 NEXT
150 NEXT
160 LOCATE 1,1
PAGE 60,132
TITLE TOSHIBA P1351 Graphics, v 1.0
comment #
tgraf.COM 7/4/85
Interrupt replacement for print screen function on ibmpc(tm)
Please send problem reports and suggestions to:
Marty Smith
310 Cinnamon Oak Lane
Houston, Texas 77079
Compuserve 72155,1214
(713) 464-6737
Create tgraf.COM with MASM*, LINK* and EXE2BIN* as follows:
masm tgraf,tgraf,tgraf;
link tgraf; (ignor the error message about no stack segment,
that's taken care of in the next step.)
exe2bin tgraf.exe tgraf.com
* MASM is the MicroSoft(tm) Macro Assembler v. 3.0
or IBM(tm) Macro Assembler v. 1.0
LINK and EXE2BIN are PC-DOS(tm) utilities.
This program originally designed for Epson-MX(tm) series printers
with Graftrax80(tm) and Graftrax+(tm) bit-plot graphic capabilites.
======> Now modified with conditional compilation and macros for
======> c.itoh(tm) model 8510a and other printers.
CHANGE HISTORY:
9/18/82 - Buffer in routine for a line of bit-plot bytes to allow for
checking for blank lines replaced by pre-scan routine, saving space.
1/24/83 - Modifications for conditional assembly with other printers
and C.ITOH 8510a.
1/24/83 - Improved error checking for out-of-paper and I/O errors
involving printer.
1/24/83 - Bug in error check corrected, occuring when routine does
error exit and is then called again, resulting in bit-plot data sent in
regular mode.
3/12/83 - Allow calling as a subroutine. i.e. no shift key depressed.
Defaults to small print mode. Can be set to LARGE.
2/4/84 - Allow correct printing of 640x200 mode.
3/18/84 - Use int 31h for dos 2.+ terminate process.
3/24/84 - Use BIOS for keyboard scan, in case screen is printed
from DOS.
4/21/84 - -OTHER- section complete for changes from 640 mode.
9/22/84 - Add code to set lines back in 6/inch order, so CR's
can advance to TOF.
9/22/84 - Jump to other print screen routine instead of reassigning
it to int f1h. Only luck has kept this vector from being used
by someone else.
10/20/84- Add check for already installed, don't reinstall.
10/20/84- Compatibility with MASM 1.0 reestablished, FAR call to old
routine caused 'fixup error' from EXE2BIN.
10/20/84- CALLGRAF now points to common address variable for default
mode, is now the same for all versions of program. Demo now
works!
4/15/84 - Toshiba P1351 added to list. This is a higher resolution
printer with a 24 pin dot head, and is another special edition
of the program, like the Okidata with its 7 dot graphics.
Features:
Accepts ESC key exit, prescans to test for blank line
left shift prtsc = small graphics, right shift prtsc = big
Runs as a .COM type program under dos
resident until power down or reset.
1 = screen sent horiz. 320 bits in 480 mode
2 = screen sent vert. 400 bits double printed in 480 mode
************** 1 mode **********************
DL = masking character
DH = count of 25 (physical lines)
CX = counter for each line (80)
DS = used to index screen at 'b8000'
These regs must be preserved during routine
(increment each line by adding '14' hex to ds: for paragraph
boundary of 320 bytes 0x'140')
************** 2 mode *********************
DH = count of 40 (physical lines)
CX = counter for each line (100)
SI = index to screen via ds:
These regs must be preserved during routine
all output to printer is done from routine -send2-, which uses
bios routine int 17h, and provides safe error exit.
GRAF.COM is designed with the idea that the user's main program is the
primary function and GRAF.COM should not cause problems of its own.
#
TRUE equ -1 ; DON'T CHANGE THESE!
FALSE equ 0
escape equ 27 ; for printer
CR equ 13
LF equ 10
; ===============> A L L U S E R S <===================
; ====> SET ONE AND ONLY ONE OF THE FOLLOWING THREE <=====
; don't set citoh to true! not operable with this version.
TOSHIBA EQU TRUE
; citoh and nec are left in here to allow for other 24 pin printers, and
; should NOT be set true at present.
CITOH EQU FALSE ; citoh and nec 8023 use similar codes.
NEC EQU FALSE
DEBUG equ FALSE
NO_EXT equ 1 ; print extended chars as dots
; Each bit of a byte is mapped to the wire head of the printer.
; If the Epson MX is sent 80h (bit 7), the TOP wire makes a dot.
; If the C.ITOH is sent 01h (bit 0), the TOP wire makes a dot.
; ===============> A L L U S E R S <===================
; =====> SET ONE AND ONLY ONE OF THE FOLLOWING TWO <======
BIT7 EQU TRUE
BIT0 EQU FALSE
; BIT7 is TRUE for TOSHIBA
; BIT0 is TRUE for CITOH,NEC8023
print macro char
mov al,char
call SEND2
endm
; ***************> START OF ACTUAL CODE <*****************
cseg segment 'code'
assume cs:cseg
org 100h ; set up for .com conversion
; publics here for debugging.
comment #
public BCONT,BIT0,BIT7,BREAK?,BUFFER,D6ONE
public DEFAULT_ROUTINE
public DONE,DONE1,DOS1,DO_OLD,DSTOR,EDONE,ERRET,ESCAPE,EXIT
public GOBACK?,GOWAIT,GR1,GR2,GRAPHIC,IND10,INDEND
public INDENT,INDENT2,INIT,INITIAL,INITOK,INITR,INL640,INLOP
public INLOP2,LAST,LFCR,LOOP_COUNT,M640,M6AIN,M6LOOP,MAIN
public MAIN2,MAIN2A,ML10,ML10A,ML10B,ML20,MLOOP,MLOOP2,MODE640
public NO0,NO1,NO2,NO3,NO4,NO5,NO6,NO7,NOS10,NOSEND
public NOSET,NXTS,NXTS10,OLD_PRINT_ROUTINE,ONEOR2,PTFLAG,S310
public S320,S330,S340,S350,S360,S370,S380,S390,SEB10,SEB20,SEB30
public SEBLOOP1,SEBLOOP2,SEC10,SEC20,SEC25,SEC30,SECLOOP1
public SECLOOP2,SEND,SEND2,SEND3,SENDTWO,SEND_BIG_BW
public SEND_BIG_COLOR,SEND_LOOP1,SEND_LOOP2,SEND_LOOP3,SEND_ONE
public SEND_THREE,SEND_TWO,START,STWO1,STWO10,STWO2,STWO20
public STWO30,STWO40,TO0,TO1,TO2,TO3,TO4,TO5,TO6,TO7
public TOF,TOFL,TS0A,TS1A,TS2A,TS3A,TS4A,TS5A
public TS6A,TS7A,TST4,TST8,TWO,WEREHERE,WHERESI
#
init proc
jmp initial ; so we have to set up first
init endp
; debugvar dw 0
gowait dw 0
wheresi dw 0
ptflag db 0
oneor2 db 0
dstor dw 0
mode640 dw 0
; **** the 1 below is the POKE to use in CALLing from another program. ****
;
default_routine dw 1 ; 1 for small, 2 for LARGE. *
;
; **** WARNING * add any new variables AFTER this to preserve POKE ******
bigc1 db 001000b,100000b,000010b,001000b,100000b,000010b
bigc2 db 100010b,010101b,101010b,010100b,0,0 ; patterns for big color
bigc3 db 101010b,010101b,101010b,010101b,101010b,010101b
data_byte db 0,0
loop_count db 0,0
old_print_routine dd 0 ; address of former print screen routine.
crt_cols db 0
video_page db 0
cursor_pos dw 0
tmode_flag db 0
max_lns db 25
MAX_LINES equ byte ptr cs:max_lns
dot18 db 6,escape,';0018' ; string to send 18 dot lines
half_crlf db 3,escape,'U',13 ; half line feed, carriage return
deline db 0 ; flag for extended line like │
.xlist
include dotdata.asm ; font data for extended characters
include dotable.asm ; xlat table and offsets
.list
do_old proc near
; jump to old routine
pop bp
pop si
pop di
pop dx
pop cx
pop bx
pop ds
pop es
pop ax
jmp cs:old_print_routine
do_old endp
; ---> ACTUAL INTERRUPT ROUTINE STARTS HERE <---
start proc far ; Start of main routine--Shift Prt.Sc hit.
assume cs:cseg
sti ; This follows ROM routine real close
push ax ;SAVE REGS
push es
push ds
push bx
push cx
push dx
push di
push si
push bp
mov bp,sp ; Save in case of error for reset
mov ax,50h ; Check here first to see if
mov ds,ax ; routine is already in progress
mov si,0 ; otherwise it will be a mess.
mov al,01h ; if [si]=1 then there is a
cmp [si],al ; print screen already in progress.
jnz nxts ; if not we're go for routine
jmp exit ; otherwise go back home.
nxts: mov [si],al ;
mov ah,15 ; Get the current video state.
int 10h ; from the ROM routine,
mov cs:mode640,FALSE
cmp al,4 ; AL=4-6 are all graphics so we're OK
jz graphic
cmp al,5
jz graphic
cmp al,6
jnz nxts10
mov cs:mode640,TRUE ; special case
jmp short graphic
nxts10:
jmp do_text_mode
mov al,0 ; else reset and go to ROM routine.
mov [si],al
jmp do_old ; this is where we stored the ROM routine entry.
; jmp exit ; Do the ROM routine but come back here to leave.
graphic:
mov ax,40h ; Get the keyboard shift flag
mov ds,ax ; segment
mov si,17h ; and address
mov ax,[si] ; pick it up
and ax,3 ; get rid of other stuff
or ax,ax ; Mod. to create default small
jnz gr1 ; for case where routine is called as a subroutine.
mov ax,cs:default_routine
gr1: mov cs:oneor2,al ; store for later
push ax ; also here
xor al,al ; make sure this starts out as NO print.
mov cs:ptflag,al
xor dl,dl ; These bits indicate whether R or L Shift is down
mov dh,19h ; 25 lines of graphic dots at 8 dots per line
mov cs:loop_count,dh
mov ax,0b800h ; stored in DX
mov ds,ax ;SET UP FOR SCREEN PEEK
; Printer setup section to change line spacing to 8/72" for continuous dots
; line spacing routine - All Epson Graftrax and IBM Graphics should
; accept esc 'A' 8 or esc '3' 24 for line spacing, but IBM Graphics only
; recognizes esc '3' 24
IF TOSHIBA
print escape
print 'L' ; A
print '0' ; 8
print '7'
ENDIF
IF CITOH ; ESC T 16
print escape
print 'T' ; T
print '1' ; 1
print '6' ; 6
print escape
IF NEC
print '[' ; Set printer to unidirectional for dot alignment
ELSE
print '>'
ENDIF
ENDIF
pop ax ; get back which routine
cmp al,2 ; Left Shift Prt Sc means LARGE graphic print
jnz gr2
jmp main2 ; so hop over there if so.
gr2:
cmp cs:mode640,TRUE
jnz MAIN
jmp m640
; START OF small GRAPHICS PRINT ROUTINE.
; This routine scans across the screen from left to right,
; building an TOSHIBA bit plot byte out of IBM screen dots.
; TOSHIBA wire head IBM screen color dots
; TOP o 128 80h bit 7 | 00 | 01 | 10 | 11 | = 4 dots, one byte
; o 64 40h " 6
; one o 32 20h " 5 ibm dots go one raster line then the next
; bit o 16 10h " 4 EVEN line, ie 0, 2, 4 etc.
; plot o 8 08h " 3
; byte o 4 04h " 2 then you go back and do 1, 3, 5 etc.
; o 2 02h " 1
; BOTTOM o 1 01h " 0 At loc. 0000h are 4 dots, 0,0|0,1|0,2|0,3
; At loc. 2000h are 4 dots, 1,0|1,1|1,2|1,3
;
main: mov cx,80 ; 80 x 4 = 320 dots.
mov di,sp ; this is not very structured, but its 11:30pm
comment #
ok, heres the idea, bp is already set for printer foulup abort.
This printer has much finer resolution than the epson, humble beginning
of this program. all color modes do color translation here, b+w is yet
another situation, carp, carp. The scan routine is set so that when material
is found to be printed, the print line loop is reset to the top and only
then is data actually sent. This allows for quicker printing of blank space.
A cr/lf is much faster than control codes and 2000 bytes. A more
complicated translation routine means more call nesting, and so register
DI is used to allow movement without stack trouble (famous last words).
If you make modifications to the program, please understand that changing
register DI may make for some interesting side effects.
#
mloop: mov dl,0c0h ; 11000000b
call tst4 ; see if this comes back <> 0
; mov al,ah ; we are testing bit patterns for one screen byte
call send3 ; don't send to printer unless something to send
mov dl,30h ; 00110000b
call tst4 ; each byte is 4 dots
; mov al,ah ; so we test for each dot in a byte
call send3 ; send sets PTFLAG if there is a dot on the line
mov dl,0ch ; 00001100b
call tst4 ; then resets to start of line and starts printing
; mov al,ah ; AL is the bit plot byte being built
call send3 ; This keeps us from printing a line of '0's.
mov dl,03h ; 00000011b
call tst4 ; TST4 scans down 8 screen dot lines each time called
; mov al,ah
call send3
loop mloop ; 80 bytes make 320 dots
call lfcr ; this is a good old regular line feed/carriage return
call break? ; someone hit ESC key? so take early exit
mov dh,cs:loop_count
dec dh ; DL is line counter
or dh,dh ; when it goes 0 we're through
jz done ; reset everything and do an IRET
mov cs:loop_count,dh
mov ax,ds ; otherwise bump the SEGMENT reg so that location
add ax,14h ; 0 is the start of the next line
mov ds,ax ; X'140' = 320
jmp main ; and do this 80 times (80x4=320)
done: mov ax,0
; This is the common exit for both routines, Printer is restored.
done1: push ax ; save AX cause it has error exit flag
; TOSHIBA command to reset printer to 6 lines/in. = ESC 2 (1b 32)
IF TOSHIBA
print escape
print 'L'
print '0' ; add 12/216 to reset line spacing
print '8'
print CR
print LF
ENDIF
; FOR CITOH MAKE SURE BIDIRECTIONAL PRINTING IS RESTORED
IF CITOH
print escape
print 'A'
print escape
IF NEC
print ']'
ELSE
print '<'
ENDIF
ENDIF
edone: mov ax,50h ; Set end of PrtSc indication
mov ds,ax ; OK to come back and do again
mov si,0
pop ax
mov [si],al
exit: pop bp
pop si ; restore regs and return to caller
pop di
pop dx
pop cx
pop bx
pop ds
pop es
pop ax
iret ; were an interrupt routine so we IRET
comment #
START OF LARGE PRINT ROUTINE
+-------------+
| ^ ^ | This time we scan from 199,0 to 0,0
| ^ ^ | and go across
| ^ ^ | These are representations
| | | | of one color dot.
+-------------+ 0 1 2 3 Palettes
x x x x x x x x x x x x
all o's o o o o o o x x x x x x all x's
x x x x x x x x x x x x
o o o o o o o o o o o o These patterns may be
x x x x x x o o o o o o changed if they don't
o o o o o o o o o o o o look convincing.
color 00 01 10 11
0 1 2 3
for b+w:
dot on : xxxxxx oooooo : dot off
xxxxxx oooooo
xxxxxx oooooo
#
main2: mov dh,80 ; we have 80 colunms x 25 lines here
mov cs:loop_count,dh
mov cs:wheresi,3ef0h ; si is our index
mov si,cs:wheresi
mov di,sp
main2a: mov cx,100
mloop2: mov al,[si] ; idea is to get a byte starting at screen BOTTOM
cmp cs:mode640,TRUE
je ml10
call send_big_color
jmp short ml10a
ml10:
call send_big_bw
ml10a:
mov cs:gowait,si ; store SI for next EVEN raster line
sub si,2000h ; subtract 2000h for the next ODD raster line
mov al,[si] ; and do the same here
cmp cs:mode640,TRUE
je ml10b
call send_big_color
jmp short ml20
ml10b:
call send_big_bw
ml20:
mov si,cs:gowait ; get back the EVEN line
sub si,80 ; advance UP the screen one line (say 199,0 to 197,0)
loop mloop2 ; and do this 100 times
call lfcr ; finished with one line we send normal line-end
call break? ; check for an ESC if we want to abort
or al,al ; clear flags
dec cs:loop_count
mov dh,cs:loop_count ; DH is our line counter,
or dh,dh ; when it goes 0 we're done.
jz tof ; so we'll try to reset Top of Form and exit
inc cs:wheresi ; else go to the next byte location
mov si,cs:wheresi ; store
jmp main2a ; and do again
tof:
print 12 ; send a form feed
jmp done ; clean up and back to caller.
start endp
send2 proc near ; BIOS routine to print the character in AL
IF DEBUG
inc cs:debugvar
ret
ELSE
push ax
mov ah,00h ; 0=print, 1=initialize port, 2=read status to AH
push dx
mov dx,0 ; DX specifies printer 0 (LPT1:)
int 17h ; BIOS used instead of DOS because DOS sends
pop dx ; CR/LF's in the middle of the bit-plots
test ah,29h ; check for timeout or errors or out-of-paper
pop ax
jnz erret
ret
erret:
cmp cs:tmode_flag,TRUE
jne erret10
call reset_cursor
erret10:
mov ax,00ffh ; Flag for printer foulup
mov sp,bp
push ax
jmp edone ; special abort
ENDIF
send2 endp
send_string proc near
; send a string of chars to printer
; format len,0,1,...,len-1
; si points to first byte
push cx
mov cl,cs:[si]
or cl,cl
jz sstret
xor ch,ch
cld
sst_loop:
inc si
mov al,cs:[si]
call send2
loop sst_loop
sstret:
pop cx
ret
send_string endp
; TOSHIBA bit plots operate at 180 dots per inch, or 1440 for an 8 inch line.
; called by ESC ; 'xxxx' where xxxx is an ASCII number like '0010' or '1440'
; i.e. 300 dots would be ESC ; 0300
; This is sent to the TOSHIBA as --> 27 ';' '0300'
indent proc near
push cx ; 13 spaces in to center
IF TOSHIBA
cmp cs:mode640,TRUE
jz ind10
mov cx,13 ; PICTURE ( we've got 960 dots and 1440 to work with
inlop: print ' ' ; 1440-960=480/18 spaces/char pica = 26.67 extra
; so indent the picture 13 spaces to center )
loop inlop
print escape ; SEQUENCE TO SET UP 960
; BIT PLOTS IN GRAPHIC MODE.
print ';' ; OF P1351
; This is the set-up for the small print
print '0'
print '9' ; 320*3=960 dots
print '6'
print '0'
jmp short indend
ind10:
mov cx,5
inl640: ; 640x200 mode, 1440-1280=160/18 per char pica=8.89
; so indent 5
print ' '
loop inl640
print escape
print ';' ; 640 dots * 2 = 1280
print '1'
print '2'
print '8'
print '0'
indend:
ENDIF
IF CITOH
print escape ; ESC N = Pica pitch
print 'N'
cmp cs:mode640,TRUE
jz ind10
mov cx,20 ; PICTURE ( we've got 320 dots and 640 to work with )
inlop: print 20h ; 640-320=320 / 8 dots per char. = 40 extra
; so indent the picture 13 spaces to center
loop inlop
jmp ind20
ind10:
print escape
print 'S'
print '0'
print '6'
print '4'
print '0'
jmp ind30
ind20:
; ESC S 0320 = 320 bit plot type bytes on the way
print escape ; SEQUENCE TO SET UP 320 BIT PLOTS IN 640 MODE
print 'S' ; OF CITOH This is the set-up for the small print
print '0' ; Would love to try to use all 640 bits here
print '3'
print '2'
print '0'
ind30:
ENDIF
pop cx
ret
indent endp
; This is indent for LARGE print
; This time we have 200*6=1200 bit plots to send
; 1440-1200=240/18 =13.33 extra, so indent 6
indent2 proc near
push cx
IF TOSHIBA
mov cx,6 ; so indent 6 character type spaces
inlop2: print 20h
loop inlop2
print escape ; 200*6=1200
print ';'
print '1'
print '2'
print '0'
print '0'
ENDIF
; 640-400=240 / 8 = 30 EXTRA characters
IF CITOH
print escape ; ESC N = Pica pitch
print 'N'
mov cx,15 ; PICTURE ( we've got 400 dots and 640 to work with
inlop2: print 20h ; 640-400 / 8 dots per char. = 30 extra so indent
; the picture 15 spaces to center
loop inlop2
; ESC S 0400 = 400 bit plot type bytes on the way
print escape ; SEQUENCE TO SET UP 400 BIT PLOTS IN 640 MODE
print 'S' ; OF CITOH
print '0'
print '4'
print '0'
print '0'
ENDIF
pop cx
ret
indent2 endp
m640 proc near
m6ain: mov cx,80 ; 80 x 4 = 320 dots.
mov di,sp
m6loop: mov dl,80h ; 10000000b
call tst8 ; see if this comes back <> 0
mov al,ah ; we are testing bit patterns for one screen byte
call sendtwo ; don't send to printer unless something to send
mov dl,40h ; 01000000b
call tst8 ; each byte is 4 dots
mov al,ah ; so we test for each dot in a byte
call sendtwo ; send sets PTFLAG if there is a dot on the line
mov dl,20h ; 00100000b
call tst8 ; then resets to start of line and starts printing
mov al,ah ; AL is the bit plot byte being built
call sendtwo
mov dl,10h ; 00010000b
call tst8 ; TST4 scans down 8 screen dot lines each time called
mov al,ah
call sendtwo
mov dl,08h ; 00001000b
call tst8 ; see if this comes back <> 0
mov al,ah ; we are testing bit patterns for one screen byte
call sendtwo ; don't send to printer unless something to send
mov dl,04h ; 00000100b
call tst8 ; each byte is 4 dots
mov al,ah ; so we test for each dot in a byte
call sendtwo ; send sets PTFLAG if there is a dot on the line
mov dl,02h ; 00000010b
call tst8 ; then resets to start of line and starts printing
mov al,ah ; AL is the bit plot byte being built
call sendtwo
mov dl,01h ; 00000001b
call tst8 ; TST4 scans down 8 screen dot lines each time called
mov al,ah
call sendtwo
loop m6loop ; 80 bytes make 320 dots
call lfcr ; this is a good old regular line feed/carriage return
call break? ; see if someone hit ESC key. If so take early exit
or al,al
mov dh,cs:loop_count
dec dh ; DL is line counter
cmp dh,0 ; when it goes 0 we're through
jz d6one ; reset everything and do an IRET
mov cs:loop_count,dh
mov ax,ds ; otherwise bump the SEGMENT reg so that location
add ax,14h ; 0 is the start of the next line
mov ds,ax ; X'140' = 320
jmp m6ain ; and do this 80 times (80x4=320)
d6one: mov ax,0
jmp done1
m640 endp
tst4 proc near ; This routine builds ONE bit plot byte
mov bx,80 ; by testing a dot with the mask sent
sub bx,cx ; from MLOOP.
mov si,bx ; First it does the ODD rows then the EVEN,
xor ax,ax ; alternate lines are offset 2000h
mov bl,[si] ; from each other in memory.
and bl,dl ; DL has the mask
or bl,bl ; SI the location
jz no7 ; BL the memory byte
mov bh,bl
and bx,1010101001010101b ; separate components of two bits/pixel
test bh,dl ; even bit
jz ts7a
or ah,80h ; if set, set on data word
ts7a:
test bl,dl ; odd bit
jz no7
or ah,40h
no7: add si,80 ; +80 gets us from say 0,0 to 2,0
mov bl,[si] ; get the memory byte ( 4 dots )
and bl,dl ; get rid of dots we aren't testing now
or bl,bl ; see if its COLOR 0
jz no5 ; if yes, go on
mov bh,bl
and bx,1010101001010101b ; separate components of two bits/pixel
test bh,dl ; even bit
jz ts5a
or ah,8 ; if set, set on data word
ts5a:
test bl,dl ; odd bit
jz no5
or ah,4
no5: add si,80 ; continue 7 5 3 1
mov bl,[si] ; xxxxxx
and bl,dl ;
or bl,bl ; xxxxxx
jz no3 ; xxxxxx
mov bh,bl
and bx,1010101001010101b ; separate components of two bits/pixel
test bh,dl ; even bit
jz ts3a
or al,80h ; if set, set on data word
ts3a:
test bl,dl ; odd bit
jz no3
or al,40h
no3: add si,80 ; xxxxxx
mov bl,[si] ;
and bl,dl
or bl,bl
jz no1
mov bh,bl
and bx,1010101001010101b ; separate components of two bits/pixel
test bh,dl ; even bit
jz ts1a
or al,8 ; if set, set on data word
ts1a:
test bl,dl ; odd bit
jz no1
or al,4
no1: push ax
mov ax,80
sub ax,cx ; CX counts our screen position
add ax,2000h ; add 2000h for the EVEN rows
mov si,ax ; with seg set to B800h we can use SI like an
pop ax ; array pointer ( AH has our byte so don't lose )
mov bl,[si] ; and continue with the same idea for 6 4 2 0
and bl,dl
or bl,bl
jz no6
mov bh,bl
and bx,1010101001010101b ; separate components of two bits/pixel
test bh,dl ; even bit
jz ts6a
or ah,20h ; if set, set on data word
ts6a:
test bl,dl ; odd bit
jz no6
or ah,10h
; call set6
no6: add si,80
mov bl,[si]
and bl,dl
or bl,bl
jz no4
mov bh,bl
and bx,1010101001010101b ; separate components of two bits/pixel
test bh,dl ; even bit
jz ts4a
or ah,2 ; if set, set on data word
ts4a:
test bl,dl ; odd bit
jz no4
or ah,1
; call set4
no4: add si,80
mov bl,[si]
and bl,dl
or bl,bl
jz no2
mov bh,bl
and bx,1010101001010101b ; separate components of two bits/pixel
test bh,dl ; even bit
jz ts2a
or al,20h ; if set, set on data word
ts2a:
test bl,dl ; odd bit
jz no2
or al,10h
; call set2
no2: add si,80
mov bl,[si]
and bl,dl
or bl,bl
jz no0
mov bh,bl
and bx,1010101001010101b ; separate components of two bits/pixel
test bh,dl ; even bit
jz ts0a
or al,2 ; if set, set on data word
ts0a:
test bl,dl ; odd bit
jz no0
or al,1
; call set0
no0: ret
comment #
; hopefully this can be left out, it all depends on the LQ1500
; where's my Z80 now
; reverse this table if your bit plots use bit 0 for the top wire
IF BIT7
set15: or ah,80h ; top wire - bit 7
ret
set14: or ah,40h ; bit 6
ret
set13: or ah,20h ; bit 5
ret
set12: or ah,10h ; bit 4
ret
set11: or ah,08h ; bit 3
ret
set10: or ah,04h ; bit 2
ret
set9: or ah,02h ; bit 1
ret
set8: or ah,01h ; bit 0
ret
set7: or al,80h ; top wire - bit 7
ret
set6: or al,40h ; bit 6
ret
set5: or al,20h ; bit 5
ret
set4: or al,10h ; bit 4
ret
set3: or al,08h ; bit 3
ret
set2: or al,04h ; bit 2
ret
set1: or al,02h ; bit 1
ret
set0: or al,01h ; bit 0
ret
ENDIF
IF BIT0
set7: or ah,01h ; top wire - bit 0
ret
set6: or ah,02h ; bit 1
ret
set5: or ah,04h ; bit 2
ret
set4: or ah,08h ; bit 3
ret
set3: or ah,10h ; bit 4
ret
set2: or ah,20h ; bit 5
ret
set1: or ah,40h ; bit 6
ret
set0: or ah,80h ; bit 7
ret
ENDIF
#
tst4 endp
; 640 mode is single bits, no color, so result is in AL.
;
tst8 proc near ; This routine builds ONE bit plot byte
mov ax,80 ; by testing a dot with the mask sent
sub ax,cx ; from M6LOOP. Used by 640 mode
mov si,ax ; First it does the ODD row then the EVEN
mov ah,0 ; since alternate lines are offset 2000h
mov al,[si] ; from each other in memory.
and al,dl ; DL has the mask
cmp al,0 ; SI the location
jz to7 ; AL the memory byte
or ah,80h ; AH is the byte being built
to7: add si,80 ; +80 gets us from say 0,0 to 2,0
mov al,[si] ; get the memory byte ( 4 dots )
and al,dl ; get rid of dots we aren't testing now
cmp al,0 ; see if its COLOR 0
jz to5 ; if yes, go on
or ah,20h
; call set5 ; otherwise set that bit
to5: add si,80 ; continue 7 5 3 1
mov al,[si]
and al,dl
cmp al,0
jz to3
or ah,8
; call set3
to3: add si,80
mov al,[si]
and al,dl
cmp al,0
jz to1
or ah,2
; call set1
to1: push ax
mov ax,80
sub ax,cx ; CX counts our screen position
add ax,2000h ; add 2000h for the EVEN rows
mov si,ax ; with seg set to B800h we can use SI like an
pop ax ; array pointer ( AH has our byte so don't lose )
mov al,[si] ; and continue with the same idea for 6 4 2 0
and al,dl
cmp al,0
jz to6
or ah,40h
; call set6
to6: add si,80
mov al,[si]
and al,dl
cmp al,0
jz to4
or ah,10h
; call set4
to4: add si,80
mov al,[si]
and al,dl
cmp al,0
jz to2
or ah,4
; call set2
to2: add si,80
mov al,[si]
and al,dl
cmp al,0
jz to0
or ah,1
; call set0
to0: ret
tst8 endp
; This routine pre-scans a line to see if in fact there are any bit
; plots to send. The main routine will keep sending bytes here
; If a whole line of 0's are sent we avoid going through the
; set-up for bit-plot (i.e. slower movement) graphics when a CR/LF
; would take care of everything.
; If there IS something to send, PTFLAG is set, the current line
; position is set to 0, bit-plot is init., and bits are really sent to printer.
send proc near
; push ax ; save the character
; push ds ; DS saved cause it points to lines
; pop ax ; points to DS
; mov cs:dstor,ax ; save
cmp cs:ptflag,TRUE ; check for printing
jne nosend ; if PTFLAG isn't TRUE we are still scanning
; pop ax ; else get the char. in AL and print it
call send2 ; this is the real out to printer routine
ret
; jmp short noset ; restore DS and return
nosend:
; pop ax ; This is the SCAN routine
or al,al ; get the char. > test for 0 > if so reset and go back
jz noset
mov al,TRUE ; if <> 0
mov cs:ptflag,al ; set PTFLAG to go
mov sp,di ;DISCARD RETURN
cmp cs:oneor2,1 ; check which (small or LARGE)
jnz two ; indent 6 or 13 depending on which routine
cmp cs:mode640,TRUE
jz nos10
call indent ; indent also sets up bit-plot mode
; call noset ; NOSET will restore DS to right pos.
jmp main ; and do the line for real.
nos10:
call indent
; call noset
jmp m6ain
two: call indent2 ; init. for LARGE
mov si,cs:wheresi ; SI set back to start of line
; call noset ; get right DS
jmp main2a ; back to beginning
noset:
; push ax ; routine to restore DS
; mov ax,cs:dstor
; mov ds,ax
; pop ax
ret
send endp
send3 proc near
; takes word length data and sends to printer
;
; word reads left to right and has actual color values of eight
; vertical pixels
;
; these will be sent to the printer as three sets of four bytes each,
; each set of four bytes controlling the 24 pins on the print head.
;
; pixel box is 3x3. colors represented:
;
; color 0: color 1: color 2: color 3:
; o o o o o o o x o x o x
; o o o o x o o x o o x o
; o o o o o o o x o x o x
; 00 01 10 11
;
push bx
push cx
push dx
mov dx,ax
mov bx,ax
mov cx,4
send_loop1: ; first pattern
xor al,al ; first column
mov ah,dh
and ah,11110000b ; just top two pixels
or ah,ah ; check for zero
jz send_one
test ah,10000000b ; twos place
jz s320
; or al,00101000b ; 0-5 significant
s310:
test ah,01000000b ; ones place
jz s320
or al,00101000b
s320:
test ah,00100000b ; twos
jz send_one
; or al,00000101b
s330:
test ah,00010000b
jz send_one
or al,000101b
send_one:
call send
shl dx,1
shl dx,1
shl dx,1
shl dx,1
loop send_loop1
mov dx,bx ; restore char for next pattern
mov cx,4
send_loop2:
xor al,al ; first column
mov ah,dh
and ah,11110000b ; just top two pixels
or ah,ah ; check for zero
jz send_two
test ah,01000000b ; ones place
jz s340
or al,00010000b ; 0-5 significant
s340:
test ah,10000000b
jz s350
or al,00101000b ; only other
s350:
test ah,00010000b
jz s360
or al,00000010b
s360:
test ah,00100000b
jz send_two
or al,00000101b
send_two:
call send
shl dx,1
shl dx,1
shl dx,1
shl dx,1
loop send_loop2
mov dx,bx
mov cx,4
send_loop3: ; first pattern
xor al,al ; first column
mov ah,dh
and ah,11110000b ; just top two pixels
or ah,ah ; check for zero
jz send_three
test ah,10000000b ; twos place
jz s380
; or al,00101000b ; 0-5 significant
s370:
test ah,01000000b ; ones place
jz s380
or al,00101000b
s380:
test ah,00100000b
jz send_three
; or al,00000101b
s390:
test ah,00010000b
jz send_three
or al,00000101b
send_three:
call send
shl dx,1
shl dx,1
shl dx,1
shl dx,1
loop send_loop3
pop dx
pop cx
pop bx
ret
send3 endp
sendtwo proc near
; expands 640x200 mode byte in small mode
; bit is sent twice for 1280 3.56 x 3.33 7.11 x 6.66
;
; byte is in AL.
;
; on = x o off = o o
; o x o o
; x o o o
push bx ; save some regs
push cx
push dx
mov dx,ax ; copy data byte in al to dl,bl
mov bx,ax
mov cx,4 ; do it with a loop
stwo1:
xor al,al ; start out blank
test dl,10000000b ; check top bit
jz stwo10 ; not set, skip to next
mov al,00101000b ; if set reflect in data
stwo10:
test dl,01000000b ; check next
jz stwo20 ; do again.
or al,00000101b ; each byte is two verticle screen pixels
stwo20:
call send ; out to routine which prints or doesn't
shl dl,1 ; depending on line.
shl dl,1 ; now move data left
loop stwo1 ; and do it four times.
mov dx,bx ; get back copy
mov cx,4 ; and send again
stwo2:
xor al,al
test dl,10000000b
jz stwo30
mov al,00010000b
stwo30:
test dl,01000000b
jz stwo40
or al,00000010b
stwo40:
call send
shl dl,1
shl dl,1
loop stwo2
pop dx
pop cx
pop bx
ret
sendtwo endp
send_big_color proc near
; take four pixel byte in al and expand to 24 x 6 to printer
push bx
push cx
push dx
mov dx,ax ; copy data byte
mov cs:data_byte,al
xor bx,bx
mov cx,6 ; basically send for six vertical dot firings
secloop1:
push cx ; two loops, save first counter
mov dl,cs:data_byte ; get original data
xor dh,dh ; blank top half
mov cx,4 ; set up inner loop
secloop2:
xor al,al ; clear printer byte
test dl,11000000b ; see if its zero
jz sec25
shl dx,1 ; move bits in question into lower dh
shl dx,1
and dh,3 ; discard others 11 binary
cmp dh,1 ; is it a one?
jnz sec10 ; no, try another
mov al,cs:bigc1[bx] ; else use pattern 1
jmp short sec30 ; and go print
sec10:
cmp dh,2 ; is it a two?
jnz sec20 ; no, then must be 3
mov al,cs:bigc2[bx] ; else use pattern 2
jmp short sec30 ; off to print.
sec20:
mov al,cs:bigc3[bx] ; determined to be 3
jmp short sec30
sec25:
shl dx,1 ; keep track of bits for zero case
shl dx,1
sec30:
call send ; out to send routine
loop secloop2 ; do for each pixel
pop cx ; get back other counter
inc bx
loop secloop1 ; do six times
pop dx ; and we are done.
pop cx
pop bx
ret
send_big_color endp
send_big_bw proc near
; take four pixel byte in al and expand to 24 x 6 to printer
push bx
push cx
push dx
mov dx,ax ; copy data byte
mov cs:data_byte,al
mov bl,010000b
mov bh,000010b ; pattern
mov cx,6 ; basically send for six vertical dot firings
sebloop1:
push cx ; two loops, save first counter
xor bx,11100111000b ; reverse pattern
mov dl,cs:data_byte ; bl won't be changed
mov cx,4 ; set up inner loop
sebloop2:
xor al,al ; clear printer byte
test dl,10000000b ; check top
jz seb10
mov al,bl ; else use pattern 1
seb10:
test dl,01000000b
jz seb20
or al,bh
seb20:
shl dl,1 ; set up for next
shl dl,1
seb30:
call send ; out to send routine
loop sebloop2 ; do for each pixel
pop cx ; get back other counter
loop sebloop1 ; do six times
pop dx ; and we are done.
pop cx
pop bx
ret
send_big_bw endp
lfcr proc near ; send a regular CR/LF combo
print 13
print 10
mov ax,0
mov cs:ptflag,al ; reset PTFLAG for next line
; mov ax,cs:dstor ; restore DS
; mov ds,ax
ret ; onward
lfcr endp
break? proc near ; Test for early exit
push ax ; don't lose any regs. here
push dx
mov ah,01h ; call direct keyboard io (constat) by BIOS
int 16h
jnz goback? ; if zero flag clear we have a character
bcont: pop dx ; no char. return
pop ax
ret
goback?:
mov ah,0
int 16h
cmp al,1bh ; ESC
jz back ; so go back, else return
jmp short bcont ; no ESC exit
back: pop dx ; ESC exit This doesn't check for Ctrl-Break
pop ax ; so if it is hit we save it for the caller to handle
pop ax ;DISCARD RETURN
cmp cs:tmode_flag,TRUE
jne GB10
call reset_cursor
GB10:
jmp done ; and go back to orig. caller
break? endp
; text_mode
; routines for text mode dump
; 7/4/85
; right shift will print with control chars and extended replaced by dots '.'
; left shift will print graphics chars.
read_line proc near
; read line from screen into buffer, calculate length and put in first pos.
push bp
mov di,80h ; use default dta from original load
inc di
mov dh,loop_count
xor dl,dl
mov bh,video_page
mov bl,crt_cols
cld ; set auto-increment
rloop:
mov ah,2 ; set cursor
int 10h
mov ah,8 ; read att/char
int 10h
or al,al ; replace 0 with space
jz rtl20
cmp al,0ffh ; and 255
je rtl20
rtl10:
stosb
inc dl
cmp dl,bl
jne rloop
jmp rtl_scan
rtl20:
mov al,' ' ; replace space type chars with spaces
jmp rtl10
rtl_scan:
dec di ; set to last char
mov si,80h ; length store
mov cl,bl ; loop for length
xor ch,ch
mov al,' ' ; search for spaces
std ; set auto_decrement
repe scasb ; search backwards until 0 or non-space
je rtl30
inc cl ; adjust for count of characters, else cl is zero
rtl30:
mov [si],cl
cld
rtlret:
pop bp
ret
read_line endp
do_extended proc near
cmp oneor2,NO_EXT ; do we want extended chars printed?
jne do_ext_chars
do_ext_dot:
mov al,'.'
do_ext_print:
call send2
ret
do_ext_chars:
mov bx,offset extable
xlat
cmp al,160 ; 160 or above is printer character
jae do_ext_print
or al,al ; a zero means char not defined
jz do_ext_dot
push cx ; otherwise there is a character
push si
xor ah,ah ; xlat has position in offset table
shl ax,1 ; two bytes per offset
mov si,offset extoffset
add si,ax ; add to start
mov ax,[si] ; get offset to data table
mov si,ax ; si now points to start of data
cld
lodsb ; first char in data is length
mov cl,al
xor ch,ch ; clear high
or cx,cx ; if zero here we're in trouble
jnz do_ext100
pop cx
pop si
jmp do_ext_dot ; so just print a dot
do_ext100:
cmp cl,72 ; this is an image print
jne do_ext_loop ; else its a strategy print
push si ; for image we need setup
mov si,offset dot18 ; for 18 dot type lines
call send_string
pop si
do_ext_loop:
lodsb
call send2
loop do_ext_loop
lodsb ; this char has possible continuation
; like box chars with extenders
; 0 = no ext
; 1 = single line ext
; 2 = double line
; 3 = fill box
; 4 = fill left side
; 5 = fill right side
; 6 = fill 1/4 of dots
; 7 = fill 1/2 "
; 8 = fill 3/4 "
or al,al ; zero means done
jnz de_more
deret:
pop si
pop cx
ret
de_more:
push ax
cmp deline,TRUE
je de_200
; fill line to store extenders for box drawing characters with spaces
; this is set only when there is one to do.
xor di,di
mov al,[di+80h] ; get previously set length value
cld
stosb ; copy to this buffer.
mov al,' '
mov cx,80
rep stosb
mov deline,TRUE
de_200:
pop ax ; get back which method
pop di ; this has character position +1
push di
sub di,81h ; main buffer at 80h, ext. at 0h
cld ; put character at same relative position.
add al,' ' ; these patterns are stored in order starting
stosb ; after where a space would be stored.
jmp deret
do_extended endp
do_control proc near
mov al,'.'
call send2
ret
do_control endp
print_line proc near
; use info in buffer to print
mov si,80h
lodsb ; get length
or al,al
jnz pl10
plret:
ret
pl10:
mov cl,al
xor ch,ch
cld
ploop:
lodsb
cmp al,127
ja pl_extended
cmp al,32
jb pl_extended
call send2
plnext:
loop ploop
jmp plret
pl_extended:
call do_extended
jmp plnext
; pl_control:
; call do_control
; jmp plnext
print_line endp
make_ext_line proc near
; make the extended line characters
mov si,offset half_crlf
call send_string ; move down half line
xor si,si ; buffer is at zero
cld
lodsb ; get length
or al,al ; abort for no length
jz mel_ret
mov cl,al
xor ch,ch
meloop:
lodsb
cmp al,' '
jne mel100
call send2
mel10:
loop meloop
mel_ret:
mov si,offset half_crlf
call send_string
mov deline,FALSE ; reset flag
ret
mel100:
call do_extended
jmp mel10
make_ext_line endp
do_text_mode proc near
; comes in just after test for mode, but before shift key check
mov cs:crt_cols,ah
mov cs:video_page,bh
mov cs:tmode_flag,TRUE
mov cs:deline,FALSE
mov ax,1130h ; get EGA info
mov bh,0 ; get int 1f pointer (not used here)
int 10h
inc dx
mov MAX_LINES,dl
mov ax,40h ; Get the keyboard shift flag
mov ds,ax ; segment
mov si,17h ; and address
mov ax,[si] ; pick it up
and ax,3 ; get rid of other stuff
or ax,ax ; Mod. to create default small
jnz tr1 ; for case where routine is called as a subroutine.
mov ax,cs:default_routine
tr1: mov cs:oneor2,al ; store for later
mov ax,cs
mov ds,ax ; set data to here
mov es,ax
mov ah,3
int 10h ; read cursor pos.
mov cursor_pos,dx ; save
mov byte ptr loop_count,0
tmode_loop:
call read_line ; read in entire line
call print_line ; send to printer
cmp oneor2,NO_EXT
jne dtm100
dtm10:
call lfcr
dtm20:
call break?
mov al,loop_count
inc al
mov loop_count,al
cmp al,MAX_LINES
jnz tmode_loop
call reset_cursor
jmp done
dtm100:
cmp deline,TRUE ; if we are doing extended, are there any?
jne dtm10
call make_ext_line
jmp dtm20
reset_cursor:
mov dx,cursor_pos ; restore cursor
mov bh,video_page ; set as CALL so it can be used by
mov ah,2 ; the abort routines.
int 10h
mov tmode_flag,FALSE
ret
do_text_mode endp
last dw 0 ; this marks end of resident code.
; DON'T put anything below here you expect to use
; after initialization.
buffer db ' TOSHIBA(tm) P1340, P1351, P351',13,10
db ' Screen Printer v 1.1',13,10,10
db ' ==> Graphics Mode:',13,10
db ' Right Shift PrtSc = small graphics',13,10
db ' Left Shift PrtSc = LARGE GRAPHICS',13,10
db ' ==> Text Mode:',13,10
db ' Right Shift PrtSc = quick screen print',13,10
db 'Left Shift PrtSc = extended characters printed',13,10,10
db 'Hitting ESCape will stop print at end of line.',13,10,'$'
werehere db ' ** TOSHIBA.COM is already resident **',13,10,10
db ' There is no need to reinstall.',13,10,'$'
initr proc far
initial:
mov ax,0 ; get addr of
mov ds,ax ; print screen routine
mov si,14h ; in rom
mov ax,[si] ; from interrupt table in ram
inc si
inc si
mov dx,[si]
mov word ptr cs:old_print_routine,ax
mov word ptr cs:old_print_routine+2,dx
mov cx,offset last-offset start
mov di,ax
mov si,offset start
cmp dx,0efffh ; if routine points to ROM, ours is not it.
ja initok
cmp si,di
jne initok ; if start location not same, it can't be ours.
; otherwise check to see if this routine is
mov es,dx ; already in memory, and don't reinstall if so.
mov ax,cs
mov ds,ax
repe cmpsb
or cx,cx ; cx=0 means there is a copy of this at the
jnz initok ; other address.
mov dx,offset werehere
mov ah,9 ; so we print a message and
int 21h ; abort.
int 20h
initok:
; mov ds,ax
; mov al,0f1h ; move it to
; mov ah,25h
; int 21h ; int f1h described in tech. manual as unused vector
mov ax,cs ; reset int 5
mov ds,ax ; to point to
mov ax,offset start ; this routine
mov dx,ax
mov al,5
mov ah,25h ; dos routine to reset int. vector
int 21h
mov ax,offset buffer
mov dx,ax
mov ah,9
int 21h ; print greeting
mov ax,3000h ; get dos version
int 21h
or al,al
jz dos1
mov ax,offset last
mov cx,16
xor dx,dx
div cx
inc ax ; make number of paragraphs
mov dx,ax
mov al,0 ; exit code
mov ah,31h ; terminate process, keep resident
int 21h
dos1:
mov dx,offset last ; last address here
inc dx
int 27h ; terminate but stay resident
initr endp
cseg ends
end init
PAGE 60,132
TITLE GRAFTRAX SCREEN PRINTER, V 3.4
; OKIGRAF.COM 10/29/84
; ****!****!****!****!****!****!****!****!****!****!
; Special version for Okidata ML93,92 printers, !
; and others with 7-bit graphics. !
; ****!****!****!****!****!****!****!****!****!****!
; Interrupt replacement for print screen function on ibmpc(tm)
; Please send problem reports and suggestions to:
; Marty Smith
; 310 Cinnamon Oak Lane
; Houston, Texas 77079
; Compuserve 72155,1214
; (713) 661-1241 office, (713) 464-6737, home.
;
; Create GRAF.COM with MASM*, LINK* and EXE2BIN* as follows:
;
; masm graf,graf,graf;
;
; link graf; (ignor the error message about no stack segment,
; that's taken care of in the next step.)
; exe2bin graf.exe graf.com
;
; * MASM is the IBM(tm) MacroAssembler(tm),
; LINK and EXE2BIN are PC-DOS(tm) utilities.
;
; This program originally designed for Epson-MX(tm) series printers
; with Graftrax80(tm) and Graftrax+(tm) bit-plot graphic capabilites.
; ======> Now modified with conditional compilation and macros for
; ======> c.itoh(tm) model 8510a and other printers.
;
; CHANGE HISTORY:
; 9/18/82 - Buffer in routine for a line of bit-plot bytes to allow for
; checking for blank lines replaced by pre-scan routine, saving space.
; 1/24/83 - Modifications for conditional assembly with other printers
; and C.ITOH 8510a.
; 1/24/83 - Improved error checking for out-of-paper and I/O errors
; involving printer.
; 1/24/83 - Bug in error check corrected, occuring when routine does
; error exit and is then called again, resulting in bit-plot data sent in
; regular mode.
; 3/12/83 - Allow calling as a subroutine. i.e. no shift key depressed.
; Defaults to small print mode. Can be set to LARGE.
; 2/4/84 - Allow correct printing of 640x200 mode.
; 3/18/84 - Use int 31h for dos 2.+ terminate process.
; 3/24/84 - Use BIOS for keyboard scan, in case screen is printed
; from DOS.
; 4/21/84 - -OTHER- section complete for changes from 640 mode.
; 9/22/84 - Add code to set lines back in 6/inch order, so CR's
; can advance to TOF.
; 9/22/84 - Jump to other print screen routine instead of reassigning
; it to int f1h. Only luck has kept this vector from being used
; by someone else.
; 10/29/84 - Program goes to, god forgive me, two separate versions
; to cope with printers like the Oki and IDS with their 7-bit
; graphics and alternate calling conventions.
; 11/07/84 - Routine added to prevent reinstalling routine if already
; resident.
;
; Features:
; Accepts ESC key exit, prescans to test for blank line
; left shift prtsc = small graphics, right shift prtsc = big
; Runs as a .COM type program under dos
; resident until power down or reset.
; 1 = screen sent horiz. 320 bits in 480 mode
; 2 = screen sent vert. 400 bits double printed in 480 mode
; ************** 1 mode **********************
; DL = masking character
; DH = count of 25 (physical lines)
; CX = counter for each line (80)
; DS = used to index screen at 'b8000'
; These regs must be preserved during routine
; (increment each line by adding '14' hex to ds for para
; boundary of 320 bytes '140')
; ************** 2 mode *********************
; DH = count of 40 (physical lines)
; CX = counter for each line (100)
; SI = index to screen via ds
; These regs must be preserved during routine
; all output to printer is done from routine -send2-, which uses
; bios routine int 17h, and provides safe error exit.
;
; GRAF.COM is designed with the idea that the user's main program is the
; primary function and GRAF.COM should not cause problems of its own.
;
; =======================================================
; = USER MODIFICATION SECTION. =
; = If your printer can treat a byte of data to =
; = control the wires on the dot-matrix head you =
; = can probably get this working with your printer =
; = unless it is an IDS type, which treats bit plot =
; = a lot differently than the EPSON. =
; = If you have Epson Graftrax or a C.Itoh 8510a, =
; = just set the two equates indicated to -true- =
; = and compile. Otherwise get out your manual =
; = and put the code indicated in one of the printer=
; = sections. =
; = **> The title message starts at label =
; = **> -buffer-. If you set for another =
; = **> printer you should change the =
; = **> greeting to indicate which printer =
; = ===> ONLY SET *ONE* CONDITION TO -TRUE- or you =
; = will have a real mess! marty smith =
; =======================================================
TRUE equ 1 ; DON'T CHANGE THESE!
FALSE equ 0
escape equ 27 ; for printer
CR equ 13
LF equ 10
; ===============> A L L U S E R S <===================
; ====> SET ONE AND ONLY ONE OF THE FOLLOWING THREE <=====
EPSON EQU FALSE
OKI EQU TRUE
; Each bit of a byte is mapped to the wire head of the printer.
; If the Epson MX is sent 80h (bit 7), the TOP wire makes a dot.
; If the C.ITOH is sent 01h (bit 0), the TOP wire makes a dot.
; ===============> A L L U S E R S <===================
; =====> SET ONE AND ONLY ONE OF THE FOLLOWING TWO <======
BIT7 EQU FALSE
BIT0 EQU TRUE
; BIT7 is TRUE for EPSON
; BIT0 is TRUE for OKI
print macro char
mov al,char
call SEND2
endm
; **NOTE** This section applies to the 8bit versions, NOT implemented for
; 7bit (Oki). Use this as a reference to modify for other 7bit, like IDS
; *****************************
; * START of -OTHER- SECTION *
; *****************************
;
; ALL routines must set either BIT7 or BIT0.
; above. If your printer can't see bit 7 or 0 as the top wire, you
; will probably have quite a time getting this routine to work.
;
; OLINE Resets line spacing so that the print head
; will make a continuous line DOWN the page.
; This is the sequence to set the EPSON for this. (ESC A 8)
; SEND2 sends the byte in AL to the printer for ALL routines.
; It uses the INT 17h routine in order to avoid DOS's extra line
; feeds and CR's. Set for LPT1: Change SEND2 to redirect. DX=0=LPT1,1=LPT2
OLINE MACRO
print escape
print 65
print 8
ENDM
; ORLINE restores the printer to normal line spacing
; Example is for EPSON (ESC 2)
ORLINE MACRO
print escape
print '2'
ENDM
; ORESET reinitializes the printer to default settings, spacings,
; current line becomes Top of Form.
; Is used by LARGE print to allow a series to be printed
; on separate pages. It can be modified by getting rid of label
; TOF: up to but not including JMP DONE, which is the exit from
; the whole routine. Example is for EPSON. (ESC @)
ORESET MACRO
print escape
print '@'
ENDM
; BP1 initiates bit-plot graphics. It tells the printer
; that the next xxx bytes are to be considered bit-plots and not
; regular characters. The small print routine sends 320 bit plot bytes
; to the printer. On the EPSON this is:
; ESC K 64 1 hex 1b 4b 40 1 > 1*256+64=320
; --> the first part indents the page with ordinary spaces
; --> to find spaces take TOTAL_DOTS_PER_LINE - 320. Then / BITS_PER_CHARACTER
; --> Divide this by two and you have the spaces to indent
; BP1 also needs to be able to handle the case of 640 mode, which will
; double the output of dots.
; The example below is the code to do this on the EPSON/IBM.
BP1 MACRO
mov cx,13 ; PICTURE ( we've got 320 dots and 480 to work with
inlop: print 20H ; 480-320=160 / 6 dots per char. = 26.67 extra
loop inlop
; ESC K 64 1 = 256+64=320 bit plot type bytes on the way
cmp cs:mode640,TRUE
jz ind10
print escape ; SEQUENCE TO SET UP 320
; BIT PLOTS IN 480 MODE
print 75 ; OF MX-80
; This is the set-up for the small print
print 64
print 1
jmp short indend
ind10:
print escape
print 'L' ; 640 dots in 960 mode
print 128
print 2
indend:
ENDM
; BP2.
; The LARGE print sends 400 bit plot bytes to the printer. On the EPSON:
; ESC K 144 1 hex 1b 4b 90 1 > 1*256+144=400
; FIND YOUR INDENT FOR 400 BITS
BP2 MACRO
mov cx,6 ; EPSON ( we've got 400 dots and 480 to work with
inlop2: print 20H ; 480-400=80 / 6 dots per char. = 13.33 extra
; so indent the picture 6 spaces to center
loop inlop2
print escape
print 75
print 144
print 1
ENDM
; ****************************
; * END OF -OTHER- SECTION *
; ****************************
; ***************> START OF ACTUAL CODE <*****************
cseg segment 'code'
assume cs:cseg
org 100h ; set up for .com conversion
init proc
jmp initial ; so we have to set up first
init endp
gowait dw 0 ; variables during routine
wheresi dw 0
ptflag db 0
oneor2 db 0
dstor dw 0
mode640 dw 0
; **** the 1 below is the POKE to use in CALLing from another program. ****
default_routine dw 1 ; 1 for small, 2 for LARGE.
old_print_routine dd 0 ; address of former print screen routine.
do_old proc near
; jump to old routine
pop bp
pop si
pop di
pop dx
pop cx
pop bx
pop ax
pop ds
jmp cs:old_print_routine
do_old endp
; ---> ACTUAL INTERRUPT ROUTINE STARTS HERE <---
start proc far ; Start of main routine--Shift Prt.Sc hit.
assume cs:cseg
sti ; This follows ROM routine real close
push ds ; runs with interrupts enabled.
push ax ;SAVE REGS
push bx
push cx
push dx
push di
push si
push bp
mov bp,sp ; Save in case of error for reset
mov ax,50h ; Check here first to see if
mov ds,ax ; routine is already in progress
mov si,0 ; otherwise it will be a mess.
mov al,01h
cmp [si],al
jnz nxts ; if not we're go for routine
jmp exit ; otherwise go back home.
nxts: mov [si],al ; if we're go don't let us start again until done.
mov ah,15 ; Get the current video state.
int 10h ; from the ROM routine,
mov cs:mode640,FALSE
cmp al,4 ; AL=4-6 are all graphics so we're OK
jz graphic
cmp al,5
jz graphic
cmp al,6
jnz nxts10
mov cs:mode640,TRUE ; special case
jmp short graphic
nxts10:
mov al,0 ; else reset and go to ROM routine.
mov [si],al
jmp do_old ; this is where we stored the ROM routine entry.
; used to use int f1h.
graphic:
mov ax,40h ; Get the keyboard shift flag
mov ds,ax ; segment
mov si,17h ; and address
mov ax,[si] ; pick it up
and ax,3 ; get rid of other stuff
or ax,ax ; Mod. to create default small
jnz gr1 ; for case where routine is called as a subroutine.
mov ax,cs:default_routine
gr1: mov cs:oneor2,al ; store for later
push ax ; also here
xor al,al ; make sure this starts out as NO print.
mov cs:ptflag,al
xor dl,dl ; These bits indicate whether R or L Shift is down
mov dh,29 ; 29 lines of graphic dots at 7 dots per line
mov ax,0b800h ; stored in DX, last line has 4 extra dots
mov ds,ax ;SET UP FOR SCREEN PEEK
xor bx,bx ; segment indexing dropped in 7bit version, bx instead
; Printer setup section to change line spacing to 7/72" for continuous dots
; ** 7 bit **
IF EPSON
print escape
print '3' ; A
print 21 ; 7
ENDIF
IF OKI
print 30 ; set to 10 cpi
print 3 ; set to graphics mode
ENDIF
pop ax ; get back which routine
cmp al,2 ; Left Shift Prt Sc means LARGE graphic print
jnz gr2
jmp main2 ; so hop over there if so.
gr2:
cmp cs:mode640,TRUE
jnz MAIN
IF OKI
print 3 ; for 640x200, get out of graphics,
print 2
print 28 ; set up for 12 cpi
print 3 ; back to graphics
ENDIF
jmp m640
; START OF small GRAPHICS PRINT ROUTINE.
; This routine scans across the screen from left to right,
; building an EPSON bit plot byte out of IBM screen dots.
; EPSON wire head IBM screen color dots
; TOP o 128 80h bit 7 | 00 | 01 | 10 | 11 | = 4 dots, one byte
; o 64 40h " 6
; one o 32 20h " 5 ibm dots go one raster line then the next
; bit o 16 10h " 4 EVEN line, ie 0, 2, 4 etc.
; plot o 8 08h " 3
; byte o 4 04h " 2 then you go back and do 1, 3, 5 etc.
; o 2 02h " 1
; BOTTOM o 1 01h " 0 At loc. 0000h are 4 dots, 0,0|0,1|0,2|0,3
; At loc. 2000h are 4 dots, 1,0|1,1|1,2|1,3
;
main: mov cx,80 ; 80 x 4 = 320 dots.
mloop: mov dl,0c0h ; 11000000b
call tst4 ; see if this comes back <> 0
mov al,ah ; we are testing bit patterns for one screen byte
call send ; don't send to printer unless something to send
mov dl,30h ; 00110000b
call tst4 ; each byte is 4 dots
mov al,ah ; so we test for each dot in a byte
call send ; send sets PTFLAG if there is a dot on the line
mov dl,0ch ; 00001100b
call tst4 ; then resets to start of line and starts printing
mov al,ah ; AL is the bit plot byte being built
call send
mov dl,03h ; 00000011b
call tst4 ; TST4 scans down 8 screen dot lines each time called
mov al,ah
call send
loop mloop ; 80 bytes make 320 dots
IF EPSON
call lfcr ; this is a good old regular line feed/carriage return
ENDIF
IF OKI
call lfcroki
ENDIF
call break? ; someone hit ESC key? so take early exit
dec dh ; DL is line counter
or dh,dh ; when it goes 0 we're through
jz done ; reset everything and do an IRET
test dh,1 ; otherwise check counter for odd/even
jz mloop10 ; and adjust index (bx) accordingly
sub bx,7872
jmp short mloop20
mloop10:
add bx,8432
mloop20:
jmp main ; and do this 80 times (80x4=320)
done: mov ax,0
; This is the common exit for both routines, Printer is restored.
done1: push ax ; save AX cause it has error exit flag
; EPSON command to reset printer to 6 lines/in. = ESC 2 (1b 32)
IF EPSON
print escape
print '3'
print 12 ; add 12/216 to reset line spacing
print CR
print LF
print escape ; RESET PRINTER, RESTORE REGS
print '2'
ENDIF
IF OKI
print 3 ; graphics escape code
print 2 ; exit graphics mode
ENDIF
edone: mov ax,50h ; Set end of PrtSc indication
mov ds,ax ; OK to come back and do again
mov si,0
pop ax
mov [si],al
exit: pop bp
pop si ; restore regs and return to caller
pop di
pop dx
pop cx
pop bx
pop ax
pop ds
iret ; were an interrupt routine so we IRET
; START OF LARGE PRINT ROUTINE
; +-------------+
; | ^ ^ | This time we scan from 199,0 to 0,0
; | ^ ^ | and go across
; | ^ ^ | o o x x o x x x These are representations
; | | | | o o o o x o x x of one color dot.
; +-------------+ 0 1 2 3 Palettes
main2: mov dh,92 ; we have 80 colunms x 25 lines here
mov dl,0
mov cs:wheresi,3ef0h ; si is our index
mov si,cs:wheresi
main2a: mov cx,64h ; 100
mloop2:
call m2_calc_send
mov cs:gowait,si ; store SI for next EVEN raster line
sub si,2000h ; subtract 2000h for the next ODD raster line
call m2_calc_send
mov si,cs:gowait ; get back the EVEN line
sub si,80 ; advance UP the screen one line (say 199,0 to 197,0)
loop mloop2 ; and do this 100 times
IF EPSON
call lfcr
ENDIF
IF OKI
call lfcroki ; finished with one line we send normal line-end
ENDIF
call break? ; check for an ESC if we want to abort
dec dh ; DH is our line counter,
or dh,dh ; when it goes 0 we're done.
jz tof ; so we'll try to reset Top of Form and exit
inc dl
cmp dl,7
je ml_no_inc
inc cs:wheresi ; else go to the next byte location
; except if at last circuit
ml_no_inc:
and dl,7 ; 0-7 only, 8 byte circuit
mov si,cs:wheresi ; store
jmp main2a ; and do again
tof:
mov cx,19 ; tof restores page to 11 inches from where it started
IF OKI
print 3 ; exit graphics mode
print 2
call break? ; check for no do.
print 12 ; form feed if ok.
jmp short tofl_end
ENDIF
tofl:
print CR ; send a bunch of cr's and lf's
print LF
call break? ; check for early exit
loop tofl ; and so on.
; This restores the EPSON to 6 lines per inch
; ESC @ = Restore all settings to default
IF EPSON
print escape
print 64 ; '@'
ENDIF
tofl_end:
jmp done ; clean up and back to caller.
start endp
m2_calc_send proc near
mov al,[si] ; idea is to get a byte starting at screen BOTTOM
mov ah,[si-1] ; can't use a mov word instruction, since
or dl,dl ; bits are read by least,most significant
jz m2on ; which would be backwards in this case.
cmp dl,7 ; This down to m2on basically aligns the screen
je m2on ; dots in a register depending on where we are in
cmp dl,4 ; an 8 step cycle. With 7 bit graphics and an 8 bit
ja m2o50 ; byte width, it takes 8 steps for things to repeat.
shr ax,1 ; This involves lots of shifts and conditionals
shr ax,1 ; and this routine attemps to do this as efficiently
cmp dl,3 ; as possible.
jb m2on ; ** one screen byte looks like this:
shr ax,1 ; | 7 6 | 5 4 | 3 2 | 1 0 | #'s are bits, two make up
shr ax,1 ; a color pixel 00 01 10 11
jmp short m2on ; this is sent twice for 620x200, or twice with some
; twidling to simulate color, and reversing of the
m2o50: ; bits for wire 0 type printers, (Oki)
shl ax,1 ; This results in an image formed sideways with the
shl ax,1 ; bottom left corner of the screen in the top left
mov al,ah ; corner on a page of paper.
m2on:
mov bh,al ; copy pattern for second
test dl,1 ; check for odd
jz m2on10
shl al,1 ; if so, bump bit7
m2on10:
call reverse ; Bits have to be reversed on wire 0 type
and al,7fh ; turn off bit7
cmp dh,1 ; last byte only 2 bits
jnz m2on15
and al,3 ; so erase any extras.
m2on15:
call send ; send it since these resemble bit plot bytes
cmp cs:mode640,TRUE
jz ml10
mov al,bh
call flipflop ; then reverse(sort of) this byte and send it
test dl,1 ; check odd
jz m2on20
shl al,1 ; align if so
m2on20:
call reverse ; bit 7 becomes bit 0, etc.
and al,7fh
cmp dh,1
jnz ml10
and al,3
ml10:
call send ; again.
ret
m2_calc_send endp
send2 proc near ; BIOS routine to print the character in AL
push ax
mov ah,00h ; 0=print, 1=initialize port, 2=read status to AH
push dx
mov dx,0 ; DX specifies printer 0 (LPT1:)
int 17h ; BIOS used instead of DOS because DOS sends
pop dx ; CR/LF's in the middle of the bit-plots
test ah,29h ; check for timeout or errors or out-of-paper
pop ax
jnz erret
ret
erret: mov ax,00ffh ; Flag for printer foulup
mov sp,bp
push ax
jmp edone ; special abort
send2 endp
; EPSON bit plots operate at 480 or 960 dots across the page
; called by ESC K 'low byte';'high byte'
; i.e. 300 dots would be 256+44 or 012CH
; This is sent to the EPSON as --> 1b 4b 2c 01
; or in decimal --> 27 75 44 1
indent proc near
push cx ; 13 spaces in to center
IF EPSON
mov cx,13 ; PICTURE ( we've got 320 dots and 480 to work with
inlop: print 20h ; 480-320=160 / 6 dots per char. = 26.67 extra
; so indent the picture 13 spaces to center
loop inlop
; ESC K 64 1 = 256+64=320 bit plot type bytes on the way
cmp cs:mode640,TRUE
jz ind10
print escape ; SEQUENCE TO SET UP 320
; BIT PLOTS IN 480 MODE
print 75 ; OF MX-80
; This is the set-up for the small print
print 64
print 1
jmp short indend
ind10:
print escape
print 'L' ; 640 dots in 960 mode
print 128
print 2
indend:
ENDIF
IF OKI
cmp cs:mode640,TRUE
jz ind10
mov cx,80 ; PICTURE ( we've got 320 dots and 480 to work with
inlop: print 0 ; 480-320=160
; 80 graphics spaces to center
loop inlop
ind10: ; oki doesn't have the resolution for 640 dots on 8x11
ENDIF
pop cx
ret
indent endp
; This is indent for LARGE print
; This time we have 400 bit plots to send (200 lines x 2)
; 480-400=80 / 6 = 13.3 extra
indent2 proc near
push cx
IF EPSON
mov cx,6 ; so indent 6 character type spaces
inlop2: print 20h
loop inlop2
; ESC 27 K 144 1 = 256+144=400 bit-plots
print escape
print 75
print 144
print 1
ENDIF
IF OKI
mov cx,40 ; PICTURE ( we've got 400 dots and 480 to work with
inlop2: print 0 ; 480-400 = 80 so print 40 graphics spaces to center
loop inlop2
; ESC S 0400 = 400 bit plot type bytes on the way
ENDIF
pop cx
ret
indent2 endp
m640 proc near
m6ain: mov cx,72 ; 72 x 8 = 576 dots. OKI will lose last 10%
m6loop: mov dl,80h ; 10000000b
call tst4 ; see if this comes back <> 0
mov al,ah ; we are testing bit patterns for one screen byte
call send ; don't send to printer unless something to send
mov dl,40h ; 01000000b
call tst4 ; each byte is 4 dots
mov al,ah ; so we test for each dot in a byte
call send ; send sets PTFLAG if there is a dot on the line
mov dl,20h ; 00100000b
call tst4 ; then resets to start of line and starts printing
mov al,ah ; AL is the bit plot byte being built
call send
mov dl,10h ; 00010000b
call tst4 ; TST4 scans down 8 screen dot lines each time called
mov al,ah
call send
mov dl,08h ; 00001000b
call tst4 ; see if this comes back <> 0
mov al,ah ; we are testing bit patterns for one screen byte
call send ; don't send to printer unless something to send
mov dl,04h ; 00000100b
call tst4 ; each byte is 4 dots
mov al,ah ; so we test for each dot in a byte
call send ; send sets PTFLAG if there is a dot on the line
mov dl,02h ; 00000010b
call tst4 ; then resets to start of line and starts printing
mov al,ah ; AL is the bit plot byte being built
call send
mov dl,01h ; 00000001b
call tst4 ; TST4 scans down 8 screen dot lines each time called
mov al,ah
call send
loop m6loop ; 80 bytes make 320 dots
IF EPSON
call lfcr ; this is a good old regular line feed/carriage return
ENDIF
IF OKI
call lfcroki
ENDIF
call break? ; see if someone hit ESC key. If so take early exit
dec dh ; DL is line counter
or dh,dh ; when it goes 0 we're through
jz d6one ; reset everything and do an IRET
test dh,1 ; otherwise check counter for odd/even
jz m6oop10 ; and adjust index (bx) accordingly
sub bx,7872
jmp short m6oop20
m6oop10:
add bx,8432
m6oop20:
jmp m6ain ; and do this 80 times (80x4=320)
d6one: mov ax,0
jmp done1
m640 endp
tst4 proc near ; This routine builds ONE bit plot byte
mov ax,80 ; by testing a dot with the mask sent
cmp cs:mode640,TRUE
jne tst10
mov ax,72
tst10:
sub ax,cx ; from MLOOP.
mov si,ax ; si is added to an index value stored in
add si,bx ; bx, and then moved down the screen line by line.
xor ah,ah ; Alternate lines are offset 2000h in segment b800h
cmp si,8192
jb test_even ; if the current address is over 8192, the line
jmp test_odd ; start location is odd
test_even:
mov al,[si] ; from each other in memory. |-----------------|screen
and al,dl ; DL has the mask | 0,0 0,1 0,2 etc |addr.
or al,al ; SI the location | 2,0 2,1 2,2 |0
jz no7 ; AL the memory byte |-----------------|
IF BIT7 ; |-----------------|
or ah,80h ; AH is the byte being built | 1,0 1,1 1,2 etc |addr.
ELSE ; | 3,0 3,1 3,2 |8192
or ah,01h ; AH is the byte being built |-----------------|2000h
ENDIF
no7: add si,8192 ; get to next line down (odd lines are offset 2000h)
mov al,[si] ; get the memory byte ( 4 dots )
and al,dl ; get rid of dots we aren't testing now
or al,al ; see if its COLOR 0
jz no6 ; if yes, go on
IF BIT7
or ah,40h
ELSE
or ah,02h
ENDIF
no6: sub si,8112
mov al,[si]
and al,dl
or al,al
jz no5
IF BIT7
or ah,20h
ELSE
or ah,04h
ENDIF
no5:
cmp dh,1 ; if dh=1 we are on the last line and don't need
jne no5a ; the bottom four bits, so take early exit
ret ;
no5a:
add si,8192
mov al,[si]
and al,dl
or al,al
jz no4
IF BIT7
or ah,10h
ELSE
or ah,08h
ENDIF
no4:
sub si,8112
mov al,[si]
and al,dl
or al,al
jz no3
IF BIT7
or ah,08h
ELSE
or ah,10h
ENDIF
no3: add si,8192
mov al,[si]
and al,dl
or al,al
jz no2
IF BIT7
or ah,04h
ELSE
or ah,20h
ENDIF
no2: sub si,8112
mov al,[si]
and al,dl
or al,al
jz no1
IF BIT7
or ah,02h
ELSE
or ah,40h
ENDIF
no1:
no0: ret
test_odd:
mov al,[si] ; from each other in memory. |-----------------|screen
and al,dl ; DL has the mask | 0,0 0,1 0,2 etc |addr.
or al,al ; SI the location | 2,0 2,1 2,2 |0
jz od7 ; AL the memory byte |-----------------|
IF BIT7 ; |-----------------|
or ah,80h ; AH is the byte being built | 1,0 1,1 1,2 etc |addr.
ELSE ; | 3,0 3,1 3,2 |8192
or ah,01h ; AH is the byte being built |-----------------|2000h
ENDIF
od7: sub si,8112 ; get to next line down (odd lines are offset 2000h)
mov al,[si] ; get the memory byte ( 4 dots )
and al,dl ; get rid of dots we aren't testing now
or al,al ; see if its COLOR 0
jz od6 ; if yes, go on
IF BIT7
or ah,40h
ELSE
or ah,02h
ENDIF
od6: add si,8192
mov al,[si]
and al,dl
or al,al
jz od5
IF BIT7
or ah,20h
ELSE
or ah,04h
ENDIF
od5:
cmp dh,1 ; if dh=1 we are on the last line and don't need
jne od5a ; the bottom four bits, so take early exit
ret ;
od5a:
sub si,8112
mov al,[si]
and al,dl
or al,al
jz od4
IF BIT7
or ah,10h
ELSE
or ah,08h
ENDIF
od4:
add si,8192
mov al,[si]
and al,dl
or al,al
jz od3
IF BIT7
or ah,08h
ELSE
or ah,10h
ENDIF
od3: sub si,8112
mov al,[si]
and al,dl
or al,al
jz od2
IF BIT7
or ah,04h
ELSE
or ah,20h
ENDIF
od2: add si,8192
mov al,[si]
and al,dl
or al,al
jz od1
IF BIT7
or ah,02h
ELSE
or ah,40h
ENDIF
od1:
od0: ret
tst4 endp
; This routine pre-scans a line to see if in fact there are any bit
; plots to send. The main routine will keep sending bytes here
; If a whole line of 0's are sent we avoid going through the
; set-up for bit-plot (i.e. slower movement) graphics when a CR/LF
; would take care of everything.
; If there IS something to send, PTFLAG is set, the current line
; position is set to 0, bit-plot is init., and bits are really sent to printer.
send proc near
push ax ; save the character
push ds ; DS saved cause it points to lines
mov ax,cs ; set seg for here
mov ds,ax ; This was some of my first stuff with the 8088
pop ax ; and I see some needless complexity here now
mov cs:dstor,ax ; but it works and if I mess with it
cmp cs:ptflag,0ffh ; its back to DEBUG.
jnz nosend ; if PTFLAG isn't FFh we are still scanning
pop ax ; else get the char. in AL and print it
IF OKI
cmp al,3 ; a 3 is the OKI graphics escape code, so to send
jnz not_esc ; a graphics 3 you send it twice.
push ax
call send2
pop ax
not_esc:
ENDIF
call send2 ; this is the real out to printer routine
jmp short noset ; restore DS and return
nosend: pop ax ; This is the SCAN routine
cmp al,0 ; get the char. > test for 0 > if so reset and go back
jz noset
mov al,0ffh ; if <> 0
mov cs:ptflag,al ; set PTFLAG to go
pop ax ;DISCARD RETURN
cmp cs:oneor2,1 ; check which (small or LARGE)
jnz two ; indent 6 or 13 depending on which routine
cmp cs:mode640,TRUE
jz nos10
call indent ; indent also sets up bit-plot mode
call noset ; NOSET will restore DS to right pos.
jmp main ; and do the line for real.
nos10:
call indent
call noset
jmp m6ain
two: call indent2 ; init. for LARGE
mov si,cs:wheresi ; SI set back to start of line
call noset ; get right DS
pop ax ; discard return again (ml_calc_send)
jmp main2a ; back to beginning
noset: push ax ; routine to restore DS
mov ax,cs:dstor
mov ds,ax
pop ax
ret
send endp
lfcr proc near ; send a regular CR/LF combo
print 13
print 10
mov ax,0
mov cs:ptflag,al ; reset PTFLAG for next line
mov ax,cs:dstor ; restore DS
mov ds,ax
ret ; onward
lfcr endp
lfcroki proc near
print 3 ; graphics escape code
print 14 ; advance one graphics line, return carriage
xor al,al
mov cs:ptflag,al ; restore ds no longer needed.
ret
; print 3
; print 14 ; oki graphics cr/lf
lfcroki endp
break? proc near ; Test for early exit
push ax ; don't lose any regs. here
push dx
mov ah,01h ; call direct keyboard io (constat) by BIOS
int 16h
jnz goback? ; if zero flag clear we have a character
bcont: pop dx ; no char. return
pop ax
ret
goback?:
mov ah,0
int 16h
cmp al,1bh ; ESC
jz back ; so go back, else return
jmp short bcont ; no ESC exit
back: pop dx ; ESC exit This doesn't check for Ctrl-Break
pop ax ; so if it is hit we save it for the caller to handle
pop ax ;DISCARD RETURN
jmp done ; and go back to orig. caller
break? endp
flipflop proc near ; This creates different combinations
push cx ; of a box of four bit-plot dots for one color dot.
push bx ; Don't lose any variables or loop counters
push ax
mov cl,2 ; AL has present bit-plot finished byte
mov bx,0
and al,3 ; 00000011b
call flip
ror bl,cl ; 11000000b
pop ax ; basically rotate bits around for
push ax ; o x
call r2 ; x o color 1
and al,3 ; and
call flip ; o x
ror bl,cl ; o x color 2
pop ax ; instead of
push ax ; x o
call r4 ; x o color 1
and al,3 ; and
call flip ; o x
ror bl,cl ; o x color 2
pop ax ; which aren't to convincing as
call r6 ; two different patterns
and al,3
call flip
ror bl,cl
mov al,bl
pop bx
pop cx
ret
r6: ror al,cl
r4: ror al,cl
r2: ror al,cl
ret
flip: cmp al,3 ; make sure there are two dots for color 1 and 2
jnz flip2
or bl,3
flip2: cmp al,2
jnz flip3
or bl,1
flip3: cmp al,1
jnz flip4
or bl,1
flip4: ret
flipflop endp
reverse proc near ; take AL and make bit 0 bit 7 , 1 - 6, etc
push dx ; Save our counters and masks
push cx
mov dl,01h ; 00000001B
mov dh,80h ; 10000000B
mov ah,00h ; start out blank
mov cx,8 ; set counter for 8 times through
rev1: test al,dl ; see if bit is set
jz rev2 ; if not skip next step
or ah,dh ; else set bit in AH
rev2: shl dl,1 ; shift left test bit
shr dh,1 ; shift right mask bit (pad other bits with 0)
loop rev1 ; do this 8 times
mov al,ah ; and we have a reversed character.
pop cx ; get back these
pop dx
ret ; and back to caller
reverse endp
last dw 0
buffer db ' GRAF.COM v3.4',10,13
if OKI
db 'OKIDATA ML92 ML93 (tm) Screen Printer.',13,10
else
db ' Graphics Screen Printer v3.2',13,10
endif
db ' Left Sh. PrtSc. = LARGE GRAPHICS',13,10
db ' Right Sh. PrtSc. = small graphics',13,10
db ' Text screen uses regular ROM routine.',13,10
db ' ESCape will exit GRAPHICS print.',13,10,'$'
werehere db ' ** GRAF.COM is already resident **',13,10,10
db ' There is no need to reinstall.',13,10,'$'
initr proc far
initial:
mov ax,0 ; get addr of
mov ds,ax ; print screen routine
mov si,14h ; in rom
mov ax,[si] ; from interrupt table in ram
inc si
inc si
mov dx,[si]
mov word ptr cs:old_print_routine,ax
mov word ptr cs:old_print_routine+2,dx
mov cx,offset last-offset start
mov di,ax
mov si,offset start
cmp dx,0efffh ; if routine points to ROM, ours is not it.
ja initok
cmp si,di
jne initok ; if start location not same, it can't be ours.
; otherwise check to see if this routine is
mov es,dx ; already in memory, and don't reinstall if so.
mov ax,cs
mov ds,ax
repe cmpsb
or cx,cx ; cx=0 means there is a copy of this at the
jnz initok ; other address.
mov dx,offset werehere
mov ah,9 ; so we print a message and
int 21h ; abort.
int 20h
initok:
; mov ds,ax
; mov al,0f1h ; move it to
; mov ah,25h
; int 21h ; int f1h described in tech. manual as unused vector
mov ax,cs ; reset int 5
mov ds,ax ; to point to
mov ax,offset start ; this routine
mov dx,ax
mov al,5
mov ah,25h ; dos routine to reset int. vector
int 21h
mov ax,offset buffer
mov dx,ax
mov ah,9
int 21h ; print greeting
mov ax,3000h ; get dos version
int 21h
or al,al
jz dos1
mov ax,offset last
mov cx,16
xor dx,dx
div cx
inc ax ; make number of paragraphs
mov dx,ax
mov al,0 ; exit code
mov ah,31h ; terminate process, keep resident
int 21h
dos1:
mov dx,offset last ; last address here
inc dx
int 27h ; terminate but stay resident
initr endp
cseg ends
end init
The following patch to the Personal Editor will eleminate the need
to input a RETURN on start-up.
-
A>RENAME PE.EXE PE.XXX
A>DEBUG PE.XXX
-U D95
XXXX:0D95 FF3604F4 PUSH [F404]
XXXX:0D99 FF3606F4 PUSH [F406]
-E D95
XXXX:0D95 FF.EB 36.61 04.90
XXXX:0D98 F4.90
-U D95
XXXX:0D95 3B61 JMPS 0DF8
XXXX:0D97 90 NOP
XXXX:0D98 90 NOP
XXXX:0D99 FF3606F4 PUSH [F406]
-W
Writing B280 bytes
-q
A>RENAME PE.XXX PE.EXE
Good Luck,
Tom Hall - TCM644; 72115,1114
10 CLS
20 A$=" ":X=2:Y=3:L$="YES":M$="CHAR":SCREEN 0,0,0:CLS:DEF SEG:WIDTH 80:KEY OFF
30 CLS:PRINT STRING$(81,"*")+" Poster Printer "+STRING$(81,"*")
40 LOCATE 5,10:PRINT"1 - Horizontal =";X;" "
50 LOCATE 7,10:PRINT"2 - Vertical =";Y;" "
60 LOCATE 9,10:PRINT"3 - Centered = ";L$
70 LOCATE 11,10:PRINT"4 - Character = ";M$;" ";
80 FOR Z=1 TO LEN(A$):IF MID$(A$,Z,1)>="a" AND MID$(A$,Z,1)<="z" THEN MID$(A$,Z,1)=CHR$(ASC(MID$(A$,Z,1))-32)
90 NEXT Z
100 LOCATE 13,10:PRINT"5 - Message = ";A$;SPACE$(80-28-LEN(A$))
102 LOCATE 15,10:PRINT"6 - Terminate"
110 BEEP:LOCATE 17,5:PRINT"Press number of item to change or 'P' to start printing->";:B$=INPUT$(1)
120 IF B$="1" THEN LOCATE 5,27:INPUT "",X:GOTO 40
130 IF B$="2" THEN LOCATE 7,27:INPUT "",Y:GOTO 40
140 IF B$="3" THEN LOCATE 9,27:IF L$="YES" THEN L$="NO" ELSE L$="YES"
150 IF B$="3" THEN PRINT L$;" ";:GOTO 40
160 IF B$="4" THEN LOCATE 11,27:INPUT "",M$:IF M$="char" THEN M$="CHAR":GOTO 40
170 IF B$="4" THEN 40
180 IF B$="5" THEN LOCATE 13,27:INPUT "",A$:IF A$="" THEN A$=" ":GOTO 40:ELSE GOTO 40
182 IF B$="6" THEN END
190 IF B$<>"p" AND B$<>"P" THEN 110
200 G1=0:IF LEFT$(L$,1)="y" OR LEFT$(L$,1)="Y" THEN G1=1
210 A=ASC(LEFT$(A$,1))
220 FOR T=1 TO LEN(A$)
230 P$=MID$(A$,T,1)
240 FOR O=1 TO 50
250 READ S$:FOR Z=1 TO 7:READ S(Z):NEXT Z
260 IF P$=" " THEN 580
270 IF P$=S$ THEN 290
280 NEXT O
290 RESTORE
300 X$=M$
310 IF M$="CHAR" THEN X$=S$
320 FOR U=1 TO 7
330 FOR K=8 TO 0 STEP-1
340 IF 2^K<S(U) THEN 370
350 J(9-K)=0
360 GOTO 390
370 J(9-K)=1:S(U)=S(U)-2^K
380 IF S(U)=1 THEN 600
390 NEXT K
400 FOR T1=1 TO X
410 LPRINT TAB((37-4.5*Y)*G1/(LEN(X$))+1);
420 FOR B=1 TO F(U)
430 IF J(B)=0 THEN 460
440 FOR I=1 TO Y:LPRINT X$;:NEXT I
450 GOTO 500
460 FOR I=1 TO Y
470 FOR I1=1 TO LEN(X$)
480 LPRINT" ";:NEXT I1
490 NEXT I
500 NEXT B
510 LPRINT" "
520 NEXT T1
530 NEXT U
540 FOR H=1 TO 2*X:LPRINT" ":NEXT H
550 NEXT T
560 FOR H=1 TO 10:LPRINT" ":NEXT H
570 GOTO 10
580 FOR H=1 TO 7*X:LPRINT" ":NEXT H
590 GOTO 550
600 F(U)=9-K:GOTO 400
610 DATA " ",000,000,000,000,000,000,000
620 DATA A,505,037,035,034,035,037,505
630 DATA B,512,274,274,274,274,274,239
640 DATA C,125,131,258,258,258,131,069
650 DATA D,512,258,258,258,258,131,125
660 DATA E,512,274,274,274,274,258,258
670 DATA F,512,018,018,018,018,002,002
680 DATA G,125,131,258,258,290,163,101
690 DATA H,512,017,017,017,017,017,512
700 DATA I,258,258,258,512,258,258,258
710 DATA J,065,129,257,257,257,129,128
720 DATA K,512,017,017,041,069,131,258
730 DATA L,512,257,257,257,257,257,257
740 DATA M,512,007,013,025,013,007,512
750 DATA N,512,007,009,017,033,193,512
760 DATA O,125,131,258,258,258,131,125
770 DATA P,512,018,018,018,018,018,015
780 DATA Q,125,131,258,258,322,131,381
790 DATA R,512,018,018,050,082,146,271
800 DATA S,069,139,274,274,274,163,069
810 DATA T,002,002,002,512,002,002,002
820 DATA U,128,129,257,257,257,129,128
830 DATA V,064,065,129,257,129,065,064
840 DATA W,256,257,129,065,129,257,256
850 DATA X,388,069,041,017,041,069,388
860 DATA Y,008,009,017,481,017,009,008
870 DATA Z,386,322,290,274,266,262,260
880 DATA 0,125,131,262,274,322,131,125
890 DATA 1,000,261,259,512,257,257,000
900 DATA 2,261,387,322,290,274,267,261
910 DATA 3,066,130,258,274,266,150,100
920 DATA 4,033,049,041,037,035,512,033
930 DATA 5,160,274,274,274,274,274,226
940 DATA 6,193,289,305,297,293,291,194
950 DATA 7,258,130,066,034,018,010,008
960 DATA 8,069,171,274,274,274,171,069
970 DATA 9,263,138,074,042,026,010,007
980 DATA ?,005,003,002,354,018,001,005
990 DATA *,069,041,017,512,017,041,069
1000 DATA =,041,041,041,041,041,041,041
1010 DATA !,001,001,001,384,001,001,001
1020 DATA .,001,001,129,449,129,001,001
1030 END
This program was copied from the March issue of Softalk magazine. It
corrects "DEVICE TIMEOUT" errors from the printer.
typ qd.doc
QuadRAM Drive Electronic Disk Software
This diskette includes a machine language program from the Quadram
Corporation that is designed to create an ``electronic disk'', using
the additional memory provided on the company's Quadboard expansion boards.
The program is designed for use with the Quadboard and cannot safely
be used with other memory expansion boards, the company advises. Quadram
Corporation has given the Capital PC group permission to reproduce the
program for Quadboard purchasers who did not receive it with their boards.
Note that this software is copyrighted by Quadram Corp. It is NOT public
domain software and may not be further distributed without the company's
permission.
The QuadRAM Drive is a simple, ``plain vanilla'' electronic drive. It
creates a simulated disk drive in system RAM which can be used, in most
respects just like a normal disk drive. You can copy files to it and run
programs from it. The advantages of electronic drives are that:
1. They run fast. Programs that involve frequent disk access will be
speeded up when run from the RAM disk. Try copying your Volkswriter disk
to the RAM drive and notice the improvement. Try booting BASIC from the
RAM drive. Zip!
2. They run quietly. Disk access to the RAM disk occurs noiselessly,
and with no wear and tear on your drives and diskettes.
The main disadvantages are that a RAM drive ties up quite a bit of
system memory and disappears when the system is turned off. You have
to copy files to the RAM disk to work with them and then recopy them
to floppy disks to preserve any changes you have made.
The QuadRAM drive is designed to look as much like a normal disk
drive as possible. This has the advantage of being compatible with most
software. You can do a diskcopy to the QuadRAM drive, for example, which
is not possible with some other electronic drives.
A disadvantage is that the program will only establish the RAM disk
as one of the four drives (A: B: C: D:) that the IBM PC is configured
for. This means that if you already have four floppy drives connected
to your system, you will have to sacrifice the use of your D: drive when
you are using the RAM disk.
HOW TO MAKE IT GO. . . .
To use the QuadRAM Drive, you copy the program (QD.EXE) to your DOS
or other program disk. After you boot DOS, you type in the command:
``QD N'' . . . where N is a number from 1 to 10, representing the
number of 32k blocks of memory tobe assigned to the RAM disk. If you type
``QD 5'', for example, the RAM disk will come up as a single-sided drive
with 160k of available space. If you type in ``QD 10'' you will get a
320k RAM disk in 2-sided format, provided you have that much extra
system memory.
If you specify a number other than 5 or 10, the program will allocate
some of the sectors in the electronic disk as ``bad sectors.'' For example,
if you type ``QD 4'', the RAM disk will be a single-sided 160k disk with
32k of bad sectors and 128k of available space.
Note that when using the DISKCOPY command you cannot copy a double
sided floppy disk onto a RAM disk that is established in single-sided
format.
When you run the QD program, the program creates and formats the
RAM disk in high memory. If you only have one floppy drive, the RAM
disk will be your B: drive. If you already have A: and B: drives, it will
be the C: drive. If you have A:, B:, C:, and D: drives, the RAM disk
will be the D: drive, and you will not be able to use your floppy D:
drive.
You must have at least 96k of RAM in your system to use the QD program,
since it will not use the 64k of memory on your main system board, but
only works with expansion memory.
The program updates the BIOS and DOS flags so that DOS (and programs
run under DOS) will not try to use the memory space assigned to the RAM
disk. The program reboots the system to force DOS to recognize the changes.
Your first impulse, of course will be to include the QD command in an
AUTOEXEC.BAT file, so that the electronic disk is created automatically
when you boot DOS. Note, however, that, when the QD program reboots DOS,
the AUTOEXEC file will also run again, creating a loop.
The program provides a solution to this problem. If you include the
parameter ``/A'' with the QD command, the program will check to see if
the RAM drive already has been installed. If the RAM drive is already
present, the program will not run again, but will skip to the next item
in the AUTOEXEC file.
For example, you could put the command ``QD 5/A'' as the first item
in an AUTOEXEC file. The program will create the RAM disk, boot DOS again,
and skip to the next AUTOEXEC command.
-- END --
will create the
SIG/Access:
NAME SCROLL
PAGE ,132
COMMENT*
THIS IS A FAR PROCEDURE TO BE USED WITH A BASIC PROGRAM TO PERFORM
SCROLLING OF THE SCREEN IN A SPECIFIED WINDOW. THE ARGUMENTS FOR
THE CALL TO THE ROUTINE ARE:
ULR% - ROW NUMBER (1-25) OF UPPER LEFT CORNER OF WINDOW
ULC% - COL NUMBER (1-80) OF UPPER LEFT CORNER OF WINDOW
LRR% - ROW NUMBER (1-25) OF LOWER RIGHT CORNER
LRC% - COL NUMBER (1-80) OF LOWER RIGHT CORNER
ATTR% - ATTRIBUTE OF BLANKED LINE: &H07=NORMAL, &H70=REVERSE
SEE TECH. REF. MANUAL PG. 2-51 FOR OTHERS
LNGTH% - NUMBER OF LINES TO SCROLL (0 BLANKS ENTIRE WINDOW)
USE + NUMBER TO SCROLL UP
USE - NUMBER TO SCROLL DOWN
NOTE !! - THE ARGUMENTS ARE NOT VALUE CHECKED.
FROM BASIC: CALL SCROLL(ULR%,ULC%,LRR%,LRC%,ATTR%,LNGHT%)
PROGRAM BY: LEE M. BUCK
DATE: 3-16-83
*
CSEG SEGMENT PUBLIC 'CODE'
ASSUME CS:CSEG
SCROLL PROC FAR
PUSH BP ;SAVE BP
MOV BP,SP ;SET FRAME POINTER FOR ADDRESSING STACK
; PARAMETERS
MOV AH,6 ;SET DEFAULT TO SCROLL ACTIVE PAGE UP
; SWITCH TO 7 FOR DOWN
MOV SI,[BP+6] ;GET ADDR OF LNGTH% OF SCROLL
MOV AL,[SI] ;GET VALUE OF LNGTH% OF SCROLL
CMP AL,0 ;CHECK FOR LENGTH .GE. ZERO
JGE NO_CHANGE ;MAKE NO CHANGE TO AH IF LNGHT% .GE. 0
MOV AH,7 ;RESET AH TO SCROLL DOWN
NEG AL ;USE POS. VALUE OF SCROLL LNGTH%
NO_CHANGE: MOV SI,[BP+8] ;GET ADDR OF ATTR% FOR BLANKED LINE
MOV BH,[SI] ;GET VALUE OF ATTR%
MOV SI,[BP+10] ;GET ADDR OF LRC% OF WINDOW
MOV DL,[SI] ;GET VALUE OF LRC%
MOV SI,[BP+12] ;GET ADDR OF LRR% OF WINDOW
MOV DH,[SI] ;GET VALUE OF LRR%
MOV SI,[BP+14] ;GET ADDR OF URC% OF WINDOW
MOV CL,[SI] ;GET VALUE OF URC%
MOV SI,[BP+16] ;GET ADDR OF URR% OF WINDOW
MOV CH,[SI] ;GET VALUE OF URR%
DEC CH ;DECREMENT WINDOW COORDINATES BY ONE
; TO ACCOUNT FOR FACT SYSTEM DEFINES
; SCREEN FROM 0-24 AND 0-79
DEC CL
DEC DH
DEC DL
INT 10H ;CALL BIOS VIDEO_IO
POP BP ;RESTORE ORIGINAL BP
RET 12 ;RETURN AND INC SP BY 12 FOR 6 ARGS
SCROLL ENDP
CSEG ENDS
END
SCROLL.BLD (CONVERT FROM SCROLL.HEX TO SCROLL.BLD)
THIS IS AN ASSY. LANG. SUBROUTINE TO BE USED WITH A BASIC PROGRAM TO
PERFORM SCROLLING OF THE SCREEN IN A SPECIFIED WINDOW. THE SUBROUTINE
WILL SCROLL THE CONTENTS OF THE WINDOW UP OR DOWN FILLING IN WITH A
BLANK LINE OF SPECIFIED ATTRIBUTE (I.E., BLACK, WHITE, RED, ETC...) THE
ROUTINE CAN ALSO BE USED TO CLEAR THE WINDOW
THE ARGUMENTS FOR THE CALL TO THE ROUTINE ARE:
ULR% - ROW NUMBER (1-25) OF UPPER LEFT CORNER OF WINDOW
ULC% - COL NUMBER (1-80) OF UPPER LEFT CORNER OF WINDOW
LRR% - ROW NUMBER (1-25) OF LOWER RIGHT CORNER
LRC% - COL NUMBER (1-80) OF LOWER RIGHT CORNER
ATTR% - ATTRIBUTE OF BLANKED LINE: &H07=NORMAL, &H70=REVERSE
SEE TECH. REF. MANUAL PG. 2-51 FOR OTHERS
NOTE - YOU CAN USE 0 (INSTEAD OF 7) AS THE
ATTRIBUTE FOR TEXT AND GRAPHICS MODE TO GET
BLACK BACKGROUND. TRY 7 IN HI-RES GRAPHICS
(SCREEN 2)...EVER SEE THAT WHEN YOU WENT BACK TO
DOS FROM GRAPHICS MODE?
LNGTH% - NUMBER OF LINES TO SCROLL (0 BLANKS ENTIRE WINDOW)
USE + NUMBER TO SCROLL UP
USE - NUMBER TO SCROLL DOWN
NOTE !! - THE ARGUMENTS ARE NOT VALUE CHECKED.
FROM BASIC: CALL SCROLL(ULR%,ULC%,LRR%,LRC%,ATTR%,LNGHT%)
PROGRAM BY: LEE M. BUCK
DATE: 3-16-83
THE PROGRAM IS LOADED USING THE BLOAD COMMAND. BELOW ARE TWO SAMPLE
PROGRAMS THAT USE THE ROUTINE. ONE USES A STRING VARIABLE WITHIN THE
BASIC PROGRAM TO HOLD THE PROGRAM. THE OTHER RESERVES A FIXED SECTION
OF MEMORY AT THE HIGH MEMORY AREA OF YOUR MACHINE.
SAMPLE PROGRAM 1
10 'TEST PROGRAM FOR SCROLL ROUTINE
20 'USING STRING SPACE IN BASIC PROGRAM
25 ' PROGRAM BY: LEE M. BUCK -- 3/17/83
30 CLEAR
40 CLS: KEY OFF
50 '
60 SCROLLPGM$=STRING$(&H39,"0") 'SET UP STRING SPACE TO HOLD PGM
70 '&H39 IS SIZE OF MACHINE CODE PGM
80 DEF SEG=VARPTR(SCROLLPGM$) 'GET THE SEGMENT LOCATION
90 BLOAD "SCROLL.BLD",0 'LOAD INTO STRING (BE SURE TO INCLUDE 0 OFFSET)
100 '
110 ' FILL THE SCREEN WITH SOMETHING
120 FOR ROW=1 TO 22
130 FOR COL=1 TO 79
140 PRINT CHR$(ROW+64);
150 NEXT COL
160 PRINT
170 NEXT ROW
180 'PROMPT FOR SUBROUTINE ARGUMENTS
190 BEEP
200 LOCATE 23,1
210 INPUT "ULR,ULC,LRR,LRC,ATR,LEN";ULR%,ULC%,LRR%,LRC%,ATTR%,LNGTH%
220 '
230 DEF SEG=VARPTR(SCROLLPGM$) 'BE SURE SEGMENT IS SET TO STRING SPACE
240 SCROLL=0 'SET THE OFFSET TO ZERO AND CALL THE PGM
250 CALL SCROLL(ULR%,ULC%,LRR%,LRC%,ATTR%,LNGTH%)
260 '
270 SOUND 500,5: SOUND 700,5: SOUND 1000,5
280 LOCATE 13,25: PRINT "SUCCESS !!"
290 'PRESS 'ENTER' TO DO IT AGAIN; 'Esc' TO QUIT
300 DEF SEG : POKE 106,0
310 Q$=INKEY$ : IF Q$="" GOTO 310
320 IF Q$=CHR$(13) THEN 190 'DO IT AGAIN WITH 'CARRIAGE RETURN' KEY PRESS
330 IF Q$<>CHR$(27) THEN 300 'KEEP WAITING UNTILL 'Esc' KEY PRESS
340 END
SAMPLE PROGRAM 2
10 'TEST PROGRAM FOR SCROLL ROUTINE
20 'PROGRAM BY: LEE M. BUCK -- 3/17/83
30 'PUT THE ROUTINE AS HIGH AS POSSIBLE IN MEMORY
40 'IF TOTAL MEMORY IS 64K OR LESS SPACE MUST BE RESERVED WITHIN BASIC WORK
50 'AREA. RESERVE SPACE USING THE 'CLEAR' COMMAND AT THE BEGINNING OF PGM.
60 'OR USE THE /M OPTION WHEN STARTING BASIC(A). (SEE THE BASIC MANUAL)
70 CLS: KEY OFF
80 ' PUT SOMETHING ON THE SCREEN
90 FOR ROW=1 TO 22
100 FOR COL=1 TO 79
110 PRINT CHR$(ROW+64);
120 NEXT COL
130 PRINT
140 NEXT ROW
150 '
160 'CALCULATE THE SEGMENT REQUIRED TO PUT ROUTINE AT HIGH MEMORY LOCATION
170 '
180 PGM.SIZE=&H39 'SIZE OF MACHINE LANGUAGE PROGRAM
190 MEM.SIZE=160 'TOTAL K's OF MACHINE MEMORY (LESS RAMDISK MEMORY)
200 SEGMENT=MEM.SIZE*64-CINT(PGM.SIZE/16)
210 '
220 DEF SEG=SEGMENT 'SET SEGMENT AT HIGH MEMORY LOCATION
230 '
240 'LOAD THE SUBROUTINE INTO MEMORY. IT ONLY NEEDS TO BE DONE ONCE.
250 BLOAD "SCROLL.BLD",0 'BE SURE TO SET THE OFFSET TO ZERO
260 '
270 'GET THE SUBROUTINE PARAMETERS
280 BEEP
290 LOCATE 23,1
300 INPUT "ULR,ULC,LRR,LRC,ATR,LEN";ULR%,ULC%,LRR%,LRC%,ATTR%,LNGTH%
310 '
320 ' CALL THE SUBROUTINE
330 DEF SEG=SEGMENT 'MAKE SURE SEGMENT IS SET
340 SCROLL=0 'SET THE OFFSET
350 CALL SCROLL(ULR%,ULC%,LRR%,LRC%,ATTR%,LNGTH%)
360 '
370 SOUND 500,5: SOUND 700,5: SOUND 1000,5
380 LOCATE 12,25: PRINT " SUCCESS !! "
390 'PRESS 'ENTER' TO DO IT AGAIN; 'Esc' TO QUIT
400 DEF SEG : POKE 106,0
410 Q$=INKEY$ : IF Q$="" GOTO 410
420 IF Q$=CHR$(13) THEN 280 'DO IT AGAIN WITH 'CARRIAGE RETURN' KEY PRESS
430 IF Q$<>CHR$(27) THEN 400 'KEEP WAITING UNTILL 'Esc' KEY PRESS
440 END
10 'TEST PROGRAM FOR SCROLL ROUTINE
20 'USING STRING SPACE IN BASIC PROGRAM
25 ' PROGRAM BY: LEE M. BUCK -- 3/17/83
30 CLEAR
40 CLS: KEY OFF
50 '
60 SCROLLPGM$=STRING$(&H39,"0") 'SET UP STRING SPACE TO HOLD PGM
70 '&H39 IS SIZE OF MACHINE CODE PGM
80 DEF SEG=VARPTR(SCROLLPGM$) 'GET THE SEGMENT LOCATION
90 BLOAD "SCROLL.BLD",0 'LOAD INTO STRING (BE SURE TO INCLUDE 0 OFFSET)
100 '
110 ' FILL THE SCREEN WITH SOMETHING
120 FOR ROW=1 TO 22
130 FOR COL=1 TO 79
140 PRINT CHR$(ROW+64);
150 NEXT COL
160 PRINT
170 NEXT ROW
180 'PROMPT FOR SUBROUTINE ARGUMENTS
190 BEEP
200 LOCATE 23,1
210 INPUT "ULR,ULC,LRR,LRC,ATR,LEN";ULR%,ULC%,LRR%,LRC%,ATTR%,LNGTH%
220 '
230 DEF SEG=VARPTR(SCROLLPGM$) 'BE SURE SEGMENT IS SET TO STRING SPACE
240 SCROLL=0 'SET THE OFFSET TO ZERO AND CALL THE PGM
250 CALL SCROLL(ULR%,ULC%,LRR%,LRC%,ATTR%,LNGTH%)
260 '
270 SOUND 500,5: SOUND 700,5: SOUND 1000,5
280 LOCATE 13,25: PRINT "SUCCESS !!"
290 'PRESS 'ENTER' TO DO IT AGAIN; 'Esc' TO QUIT
300 DEF SEG : POKE 106,0
310 Q$=INKEY$ : IF Q$="" GOTO 310
320 IF Q$=CHR$(13) THEN 190 'DO IT AGAIN WITH 'CARRIAGE RETURN' KEY PRESS
330 IF Q$<>CHR$(27) THEN 300 'KEEP WAITING UNTILL 'Esc' KEY PRESS
340 END
10 'TEST PROGRAM FOR SCROLL ROUTINE
20 'PROGRAM BY: LEE M. BUCK -- 3/17/83
30 'PUT THE ROUTINE AS HIGH AS POSSIBLE IN MEMORY
40 'IF TOTAL MEMORY IS 64K OR LESS SPACE MUST BE RESERVED WITHIN BASIC WORK
50 'AREA. RESERVE SPACE USING THE 'CLEAR' COMMAND AT THE BEGINNING OF PGM.
60 'OR USE THE /M OPTION WHEN STARTING BASIC(A). (SEE THE BASIC MANUAL)
70 CLS: KEY OFF
80 ' PUT SOMETHING ON THE SCREEN
90 FOR ROW=1 TO 22
100 FOR COL=1 TO 79
110 PRINT CHR$(ROW+64);
120 NEXT COL
130 PRINT
140 NEXT ROW
150 '
160 'CALCULATE THE SEGMENT REQUIRED TO PUT ROUTINE AT HIGH MEMORY LOCATION
170 '
180 PGM.SIZE=&H39 'SIZE OF MACHINE LANGUAGE PROGRAM
190 MEM.SIZE=160 'TOTAL K's OF MACHINE MEMORY (LESS RAMDISK MEMORY)
200 SEGMENT=MEM.SIZE*64-CINT(PGM.SIZE/16)
210 '
220 DEF SEG=SEGMENT 'SET SEGMENT AT HIGH MEMORY LOCATION
230 '
240 'LOAD THE SUBROUTINE INTO MEMORY. IT ONLY NEEDS TO BE DONE ONCE.
250 BLOAD "SCROLL.BLD",0 'BE SURE TO SET THE OFFSET TO ZERO
260 '
270 'GET THE SUBROUTINE PARAMETERS
280 BEEP
290 LOCATE 23,1
300 INPUT "ULR,ULC,LRR,LRC,ATR,LEN";ULR%,ULC%,LRR%,LRC%,ATTR%,LNGTH%
310 '
320 ' CALL THE SUBROUTINE
330 DEF SEG=SEGMENT 'MAKE SURE SEGMENT IS SET
340 SCROLL=0 'SET THE OFFSET
350 CALL SCROLL(ULR%,ULC%,LRR%,LRC%,ATTR%,LNGTH%)
360 '
370 SOUND 500,5: SOUND 700,5: SOUND 1000,5
380 LOCATE 12,25: PRINT " SUCCESS !! "
390 'PRESS 'ENTER' TO DO IT AGAIN; 'Esc' TO QUIT
400 DEF SEG : POKE 106,0
410 Q$=INKEY$ : IF Q$="" GOTO 410
420 IF Q$=CHR$(13) THEN 280 'DO IT AGAIN WITH 'CARRIAGE RETURN' KEY PRESS
430 IF Q$<>CHR$(27) THEN 400 'KEEP WAITING UNTILL 'Esc' KEY PRESS
440 END
10 ' SOUNDS.BAS
20 '
30 ' By: Andrew Tuline
40 '
50 ' The sound generation on the IBM PC is performed mostly by the 8253 timer
60 'chip. This IC has 3 - 16 bit counters, each serving a different purpose
70 'on the system board.
80 '
90 ' Timer 0 is used for Dynamic Memory refresh.
100 ' Timer 1 is used for the time of day function.
110 ' Timer 2 is used for the speaker cassette interface.
120 '
130 ' The 8253 Timer is highly versatile and can be programmed for many
140 'different functions. These include a programmable rate generator, an
150 'event counter, a binary rate multiplier, real time clock, and others.
160 'The programmer may optinally change the mode of operation by addressing
170 'the control register. There are 2 registers for each counter, one for
180 'storing data to the timer and the other to read data from the timer.
190 'There are 6 modes of operation. Mode 3, the square wave generator will
200 'be discussed here. The control register is setup as follows:
210 '
220 ' -------------------------------------------------------------
230 'bit: ! D7 D6 ! D5 D4 ! D3 D2 D1 ! D0 !
240 ' -------------------------------------------------------------
250 'def: ! SC1 SC0 ! RL1 RL0 ! M2 M1 M0 ! BCD !
260 ' -------------------------------------------------------------
270 '
280 'SC1,SC0 - Select the timer and must be 10 binary to select counter 2.
290 '
300 'RL1,RL0 - Read/Load
310 ' 0 0 Counter latching. When loaded, causes the present count to be
320 ' latched into a storage register for later reading.
330 ' 0 1 Read/Load LSB of counter only.
340 ' 1 0 Read/Load MSB of counter only.
350 ' 1 1 Read/Load LSB first then MSB.
360 '
370 'M2,M1,M0 - Select different modes. Must be 011 binary to select mode 3.
380 '
390 ' BCD - Binary or Decimal counter.
400 ' 0 - Sets counter to binary mode.
410 ' 1 - Sets counter to decimal mode.
420 '
430 'Note: The larger the value loaded into the counter, the lower will be
440 'the resultant frequency. The number loaded sets the period of the
450 'tone which is the inverse of the frequency.
460 '
470 'Finally, the user must enable the speaker by setting a bit at I/O address
480 '61H (hexadecimal).
490 '
500 'Addresses
510 '
520 '42H - Counter 2 data register
530 '43H - Control register
540 '61H - Bit 1 enables disables the speaker.
550 ' Value of 4DH disables, 4FH enables.
560 '
570 'Examples
580 '
590 'Single Tone
600 OUT &H43,&HA6:'Binary 1010 0110
610 ' Read/Load MSB only
620 ' Mode 3
630 ' Counter 2
640 ' Binary Counter
650 OUT &H42,&H10:'Loads counter with 1000H
660 OUT &H61,&H4F
670 FOR I=1 TO 1000:NEXT
680 OUT &H61,&H4D:'disable speaker
690 '
700 'Increasing Frequency
710 OUT &H43,&HB7:'R/L LSB then MSB, Mode 3, BCD, Counter 2
720 OUT &H61,&H4F:'Enable speaker
730 FOR I=1000 TO 10 STEP -1:'Note: Decreasing value to be output
740 OUT &H42,I MOD 256:'LSB of I
750 OUT &H42,INT(I/256):'MSB of I
760 NEXT
770 '
780 'Weird Sounds
790 OUT &H43,&HA6:'R/L MSB, mode 3, counter 2, binary
800 FOR J=1 TO 20
810 FOR I=25 TO 5 STEP -1
820 OUT &H42,I
830 NEXT I
840 NEXT J
850 '
860 'Random Sounds
870 OUT &H43,&H96:'R/L LSB only, mode 3, counter 2, binary
880 FOR I=1 TO 200
890 OUT &H42,RND*255
900 NEXT I
910 OUT &H61,&H4D
920 '
930 'Assembly Language Random Number Generator
940 '
950 '1) Initialize
960 '1) Initialize MOV AL,0B6H ;Mode 3, counter 2, binary
970 ' OUT 43H,AL ;R/L LSB then MSB
980 ' MOV AX,0FFFFH ;store large number in counter
990 ' OUT 42H,AX
1000 '
1010 '2) Read random #
1020 ' MOV AL,80H ;counter 2,latch,rest don't care
1030 ' OUT 43H,AL
1040 ' IN AX,42H
1050 '
1060 'I haven't tried the above in a program, but it should work reasonably.
1070 'And there you have it folks. A complete introductory to better sound
1080 'generation on your handy little PC. Last, but not least is a little
1090 'program to strobe your cassette port and output the data to the speaker,
1100 'written in assembly language. I have run this, and it works (sorta).
1110 '
1120 'TOP: IN AL,62H
1130 ' AND AL,10H
1140 ' SHR AL,1
1150 ' SHR AL,1
1160 ' SHR AL,1
1170 ' OR AL,45H
1180 ' OUT 61H,AL
1190 ' JMP TOP
1200 '
PAGE 60,132
TITLE TOSHIBA P1351 Graphics, v 1.0
comment #
tgraf.COM 7/4/85
Interrupt replacement for print screen function on ibmpc(tm)
Please send problem reports and suggestions to:
Marty Smith
310 Cinnamon Oak Lane
Houston, Texas 77079
Compuserve 72155,1214
(713) 464-6737
Create tgraf.COM with MASM*, LINK* and EXE2BIN* as follows:
masm tgraf,tgraf,tgraf;
link tgraf; (ignor the error message about no stack segment,
that's taken care of in the next step.)
exe2bin tgraf.exe tgraf.com
* MASM is the MicroSoft(tm) Macro Assembler v. 3.0
or IBM(tm) Macro Assembler v. 1.0
LINK and EXE2BIN are PC-DOS(tm) utilities.
This program originally designed for Epson-MX(tm) series printers
with Graftrax80(tm) and Graftrax+(tm) bit-plot graphic capabilites.
======> Now modified with conditional compilation and macros for
======> c.itoh(tm) model 8510a and other printers.
CHANGE HISTORY:
9/18/82 - Buffer in routine for a line of bit-plot bytes to allow for
checking for blank lines replaced by pre-scan routine, saving space.
1/24/83 - Modifications for conditional assembly with other printers
and C.ITOH 8510a.
1/24/83 - Improved error checking for out-of-paper and I/O errors
involving printer.
1/24/83 - Bug in error check corrected, occuring when routine does
error exit and is then called again, resulting in bit-plot data sent in
regular mode.
3/12/83 - Allow calling as a subroutine. i.e. no shift key depressed.
Defaults to small print mode. Can be set to LARGE.
2/4/84 - Allow correct printing of 640x200 mode.
3/18/84 - Use int 31h for dos 2.+ terminate process.
3/24/84 - Use BIOS for keyboard scan, in case screen is printed
from DOS.
4/21/84 - -OTHER- section complete for changes from 640 mode.
9/22/84 - Add code to set lines back in 6/inch order, so CR's
can advance to TOF.
9/22/84 - Jump to other print screen routine instead of reassigning
it to int f1h. Only luck has kept this vector from being used
by someone else.
10/20/84- Add check for already installed, don't reinstall.
10/20/84- Compatibility with MASM 1.0 reestablished, FAR call to old
routine caused 'fixup error' from EXE2BIN.
10/20/84- CALLGRAF now points to common address variable for default
mode, is now the same for all versions of program. Demo now
works!
4/15/84 - Toshiba P1351 added to list. This is a higher resolution
printer with a 24 pin dot head, and is another special edition
of the program, like the Okidata with its 7 dot graphics.
Features:
Accepts ESC key exit, prescans to test for blank line
left shift prtsc = small graphics, right shift prtsc = big
Runs as a .COM type program under dos
resident until power down or reset.
1 = screen sent horiz. 320 bits in 480 mode
2 = screen sent vert. 400 bits double printed in 480 mode
************** 1 mode **********************
DL = masking character
DH = count of 25 (physical lines)
CX = counter for each line (80)
DS = used to index screen at 'b8000'
These regs must be preserved during routine
(increment each line by adding '14' hex to ds: for paragraph
boundary of 320 bytes 0x'140')
************** 2 mode *********************
DH = count of 40 (physical lines)
CX = counter for each line (100)
SI = index to screen via ds:
These regs must be preserved during routine
all output to printer is done from routine -send2-, which uses
bios routine int 17h, and provides safe error exit.
GRAF.COM is designed with the idea that the user's main program is the
primary function and GRAF.COM should not cause problems of its own.
#
TRUE equ -1 ; DON'T CHANGE THESE!
FALSE equ 0
escape equ 27 ; for printer
CR equ 13
LF equ 10
; ===============> A L L U S E R S <===================
; ====> SET ONE AND ONLY ONE OF THE FOLLOWING THREE <=====
; don't set citoh to true! not operable with this version.
TOSHIBA EQU TRUE
; citoh and nec are left in here to allow for other 24 pin printers, and
; should NOT be set true at present.
CITOH EQU FALSE ; citoh and nec 8023 use similar codes.
NEC EQU FALSE
DEBUG equ FALSE
MAX_LINES equ 25 ; lines in a screen
; Each bit of a byte is mapped to the wire head of the printer.
; If the Epson MX is sent 80h (bit 7), the TOP wire makes a dot.
; If the C.ITOH is sent 01h (bit 0), the TOP wire makes a dot.
; ===============> A L L U S E R S <===================
; =====> SET ONE AND ONLY ONE OF THE FOLLOWING TWO <======
BIT7 EQU TRUE
BIT0 EQU FALSE
; BIT7 is TRUE for TOSHIBA
; BIT0 is TRUE for CITOH,NEC8023
print macro char
mov al,char
call SEND2
endm
; ***************> START OF ACTUAL CODE <*****************
cseg segment 'code'
assume cs:cseg
org 100h ; set up for .com conversion
; publics here for debugging.
comment #
public BCONT,BIT0,BIT7,BREAK?,BUFFER,D6ONE
public DEFAULT_ROUTINE
public DONE,DONE1,DOS1,DO_OLD,DSTOR,EDONE,ERRET,ESCAPE,EXIT
public GOBACK?,GOWAIT,GR1,GR2,GRAPHIC,IND10,INDEND
public INDENT,INDENT2,INIT,INITIAL,INITOK,INITR,INL640,INLOP
public INLOP2,LAST,LFCR,LOOP_COUNT,M640,M6AIN,M6LOOP,MAIN
public MAIN2,MAIN2A,ML10,ML10A,ML10B,ML20,MLOOP,MLOOP2,MODE640
public NO0,NO1,NO2,NO3,NO4,NO5,NO6,NO7,NOS10,NOSEND
public NOSET,NXTS,NXTS10,OLD_PRINT_ROUTINE,ONEOR2,PTFLAG,S310
public S320,S330,S340,S350,S360,S370,S380,S390,SEB10,SEB20,SEB30
public SEBLOOP1,SEBLOOP2,SEC10,SEC20,SEC25,SEC30,SECLOOP1
public SECLOOP2,SEND,SEND2,SEND3,SENDTWO,SEND_BIG_BW
public SEND_BIG_COLOR,SEND_LOOP1,SEND_LOOP2,SEND_LOOP3,SEND_ONE
public SEND_THREE,SEND_TWO,START,STWO1,STWO10,STWO2,STWO20
public STWO30,STWO40,TO0,TO1,TO2,TO3,TO4,TO5,TO6,TO7
public TOF,TOFL,TS0A,TS1A,TS2A,TS3A,TS4A,TS5A
public TS6A,TS7A,TST4,TST8,TWO,WEREHERE,WHERESI
#
init proc
jmp initial ; so we have to set up first
init endp
; debugvar dw 0
gowait dw 0
wheresi dw 0
ptflag db 0
oneor2 db 0
dstor dw 0
mode640 dw 0
; **** the 1 below is the POKE to use in CALLing from another program. ****
;
default_routine dw 1 ; 1 for small, 2 for LARGE. *
;
; **** WARNING * add any new variables AFTER this to preserve POKE ******
bigc1 db 001000b,100000b,000010b,001000b,100000b,000010b
bigc2 db 100010b,010101b,101010b,010100b,0,0 ; patterns for big color
bigc3 db 101010b,010101b,101010b,010101b,101010b,010101b
data_byte db 0,0
loop_count db 0,0
old_print_routine dd 0 ; address of former print screen routine.
crt_cols db 0
video_page db 0
cursor_pos dw 0
tmode_flag db 0
do_old proc near
; jump to old routine
pop bp
pop si
pop di
pop dx
pop cx
pop bx
pop ds
pop es
pop ax
jmp cs:old_print_routine
do_old endp
; ---> ACTUAL INTERRUPT ROUTINE STARTS HERE <---
start proc far ; Start of main routine--Shift Prt.Sc hit.
assume cs:cseg
sti ; This follows ROM routine real close
push ax ;SAVE REGS
push es
push ds
push bx
push cx
push dx
push di
push si
push bp
mov bp,sp ; Save in case of error for reset
mov ax,50h ; Check here first to see if
mov ds,ax ; routine is already in progress
mov si,0 ; otherwise it will be a mess.
mov al,01h ; if [si]=1 then there is a
cmp [si],al ; print screen already in progress.
jnz nxts ; if not we're go for routine
jmp exit ; otherwise go back home.
nxts: mov [si],al ;
mov ah,15 ; Get the current video state.
int 10h ; from the ROM routine,
mov cs:mode640,FALSE
cmp al,4 ; AL=4-6 are all graphics so we're OK
jz graphic
cmp al,5
jz graphic
cmp al,6
jnz nxts10
mov cs:mode640,TRUE ; special case
jmp short graphic
nxts10:
jmp do_text_mode
mov al,0 ; else reset and go to ROM routine.
mov [si],al
jmp do_old ; this is where we stored the ROM routine entry.
; jmp exit ; Do the ROM routine but come back here to leave.
graphic:
mov ax,40h ; Get the keyboard shift flag
mov ds,ax ; segment
mov si,17h ; and address
mov ax,[si] ; pick it up
and ax,3 ; get rid of other stuff
or ax,ax ; Mod. to create default small
jnz gr1 ; for case where routine is called as a subroutine.
mov ax,cs:default_routine
gr1: mov cs:oneor2,al ; store for later
push ax ; also here
xor al,al ; make sure this starts out as NO print.
mov cs:ptflag,al
xor dl,dl ; These bits indicate whether R or L Shift is down
mov dh,19h ; 25 lines of graphic dots at 8 dots per line
mov cs:loop_count,dh
mov ax,0b800h ; stored in DX
mov ds,ax ;SET UP FOR SCREEN PEEK
; Printer setup section to change line spacing to 8/72" for continuous dots
; line spacing routine - All Epson Graftrax and IBM Graphics should
; accept esc 'A' 8 or esc '3' 24 for line spacing, but IBM Graphics only
; recognizes esc '3' 24
IF TOSHIBA
print escape
print 'L' ; A
print '0' ; 8
print '7'
ENDIF
IF CITOH ; ESC T 16
print escape
print 'T' ; T
print '1' ; 1
print '6' ; 6
print escape
IF NEC
print '[' ; Set printer to unidirectional for dot alignment
ELSE
print '>'
ENDIF
ENDIF
pop ax ; get back which routine
cmp al,2 ; Left Shift Prt Sc means LARGE graphic print
jnz gr2
jmp main2 ; so hop over there if so.
gr2:
cmp cs:mode640,TRUE
jnz MAIN
jmp m640
; START OF small GRAPHICS PRINT ROUTINE.
; This routine scans across the screen from left to right,
; building an TOSHIBA bit plot byte out of IBM screen dots.
; TOSHIBA wire head IBM screen color dots
; TOP o 128 80h bit 7 | 00 | 01 | 10 | 11 | = 4 dots, one byte
; o 64 40h " 6
; one o 32 20h " 5 ibm dots go one raster line then the next
; bit o 16 10h " 4 EVEN line, ie 0, 2, 4 etc.
; plot o 8 08h " 3
; byte o 4 04h " 2 then you go back and do 1, 3, 5 etc.
; o 2 02h " 1
; BOTTOM o 1 01h " 0 At loc. 0000h are 4 dots, 0,0|0,1|0,2|0,3
; At loc. 2000h are 4 dots, 1,0|1,1|1,2|1,3
;
main: mov cx,80 ; 80 x 4 = 320 dots.
mov di,sp ; this is not very structured, but its 11:30pm
comment #
ok, heres the idea, bp is already set for printer foulup abort.
This printer has much finer resolution than the epson, humble beginning
of this program. all color modes do color translation here, b+w is yet
another situation, carp, carp. The scan routine is set so that when material
is found to be printed, the print line loop is reset to the top and only
then is data actually sent. This allows for quicker printing of blank space.
A cr/lf is much faster than control codes and 2000 bytes. A more
complicated translation routine means more call nesting, and so register
DI is used to allow movement without stack trouble (famous last words).
If you make modifications to the program, please understand that changing
register DI may make for some interesting side effects.
#
mloop: mov dl,0c0h ; 11000000b
call tst4 ; see if this comes back <> 0
; mov al,ah ; we are testing bit patterns for one screen byte
call send3 ; don't send to printer unless something to send
mov dl,30h ; 00110000b
call tst4 ; each byte is 4 dots
; mov al,ah ; so we test for each dot in a byte
call send3 ; send sets PTFLAG if there is a dot on the line
mov dl,0ch ; 00001100b
call tst4 ; then resets to start of line and starts printing
; mov al,ah ; AL is the bit plot byte being built
call send3 ; This keeps us from printing a line of '0's.
mov dl,03h ; 00000011b
call tst4 ; TST4 scans down 8 screen dot lines each time called
; mov al,ah
call send3
loop mloop ; 80 bytes make 320 dots
call lfcr ; this is a good old regular line feed/carriage return
call break? ; someone hit ESC key? so take early exit
mov dh,cs:loop_count
dec dh ; DL is line counter
or dh,dh ; when it goes 0 we're through
jz done ; reset everything and do an IRET
mov cs:loop_count,dh
mov ax,ds ; otherwise bump the SEGMENT reg so that location
add ax,14h ; 0 is the start of the next line
mov ds,ax ; X'140' = 320
jmp main ; and do this 80 times (80x4=320)
done: mov ax,0
; This is the common exit for both routines, Printer is restored.
done1: push ax ; save AX cause it has error exit flag
; TOSHIBA command to reset printer to 6 lines/in. = ESC 2 (1b 32)
IF TOSHIBA
print escape
print 'L'
print '0' ; add 12/216 to reset line spacing
print '8'
print CR
print LF
ENDIF
; FOR CITOH MAKE SURE BIDIRECTIONAL PRINTING IS RESTORED
IF CITOH
print escape
print 'A'
print escape
IF NEC
print ']'
ELSE
print '<'
ENDIF
ENDIF
edone: mov ax,50h ; Set end of PrtSc indication
mov ds,ax ; OK to come back and do again
mov si,0
pop ax
mov [si],al
exit: pop bp
pop si ; restore regs and return to caller
pop di
pop dx
pop cx
pop bx
pop ds
pop es
pop ax
iret ; were an interrupt routine so we IRET
comment #
START OF LARGE PRINT ROUTINE
+-------------+
| ^ ^ | This time we scan from 199,0 to 0,0
| ^ ^ | and go across
| ^ ^ | These are representations
| | | | of one color dot.
+-------------+ 0 1 2 3 Palettes
x x x x x x x x x x x x
all o's o o o o o o x x x x x x all x's
x x x x x x x x x x x x
o o o o o o o o o o o o These patterns may be
x x x x x x o o o o o o changed if they don't
o o o o o o o o o o o o look convincing.
color 00 01 10 11
0 1 2 3
for b+w:
dot on : xxxxxx oooooo : dot off
xxxxxx oooooo
xxxxxx oooooo
#
main2: mov dh,80 ; we have 80 colunms x 25 lines here
mov cs:loop_count,dh
mov cs:wheresi,3ef0h ; si is our index
mov si,cs:wheresi
mov di,sp
main2a: mov cx,100
mloop2: mov al,[si] ; idea is to get a byte starting at screen BOTTOM
cmp cs:mode640,TRUE
je ml10
call send_big_color
jmp short ml10a
ml10:
call send_big_bw
ml10a:
mov cs:gowait,si ; store SI for next EVEN raster line
sub si,2000h ; subtract 2000h for the next ODD raster line
mov al,[si] ; and do the same here
cmp cs:mode640,TRUE
je ml10b
call send_big_color
jmp short ml20
ml10b:
call send_big_bw
ml20:
mov si,cs:gowait ; get back the EVEN line
sub si,80 ; advance UP the screen one line (say 199,0 to 197,0)
loop mloop2 ; and do this 100 times
call lfcr ; finished with one line we send normal line-end
call break? ; check for an ESC if we want to abort
or al,al ; clear flags
dec cs:loop_count
mov dh,cs:loop_count ; DH is our line counter,
or dh,dh ; when it goes 0 we're done.
jz tof ; so we'll try to reset Top of Form and exit
inc cs:wheresi ; else go to the next byte location
mov si,cs:wheresi ; store
jmp main2a ; and do again
tof:
print 12 ; send a form feed
jmp done ; clean up and back to caller.
start endp
send2 proc near ; BIOS routine to print the character in AL
IF DEBUG
inc cs:debugvar
ret
ELSE
push ax
mov ah,00h ; 0=print, 1=initialize port, 2=read status to AH
push dx
mov dx,0 ; DX specifies printer 0 (LPT1:)
int 17h ; BIOS used instead of DOS because DOS sends
pop dx ; CR/LF's in the middle of the bit-plots
test ah,29h ; check for timeout or errors or out-of-paper
pop ax
jnz erret
ret
erret:
cmp cs:tmode_flag,TRUE
jne erret10
call reset_cursor
erret10:
mov ax,00ffh ; Flag for printer foulup
mov sp,bp
push ax
jmp edone ; special abort
ENDIF
send2 endp
; TOSHIBA bit plots operate at 180 dots per inch, or 1440 for an 8 inch line.
; called by ESC ; 'xxxx' where xxxx is an ASCII number like '0010' or '1440'
; i.e. 300 dots would be ESC ; 0300
; This is sent to the TOSHIBA as --> 27 ';' '0300'
indent proc near
push cx ; 13 spaces in to center
IF TOSHIBA
cmp cs:mode640,TRUE
jz ind10
mov cx,13 ; PICTURE ( we've got 960 dots and 1440 to work with
inlop: print ' ' ; 1440-960=480/18 spaces/char pica = 26.67 extra
; so indent the picture 13 spaces to center )
loop inlop
print escape ; SEQUENCE TO SET UP 960
; BIT PLOTS IN GRAPHIC MODE.
print ';' ; OF P1351
; This is the set-up for the small print
print '0'
print '9' ; 320*3=960 dots
print '6'
print '0'
jmp short indend
ind10:
mov cx,5
inl640: ; 640x200 mode, 1440-1280=160/18 per char pica=8.89
; so indent 5
print ' '
loop inl640
print escape
print ';' ; 640 dots * 2 = 1280
print '1'
print '2'
print '8'
print '0'
indend:
ENDIF
IF CITOH
print escape ; ESC N = Pica pitch
print 'N'
cmp cs:mode640,TRUE
jz ind10
mov cx,20 ; PICTURE ( we've got 320 dots and 640 to work with )
inlop: print 20h ; 640-320=320 / 8 dots per char. = 40 extra
; so indent the picture 13 spaces to center
loop inlop
jmp ind20
ind10:
print escape
print 'S'
print '0'
print '6'
print '4'
print '0'
jmp ind30
ind20:
; ESC S 0320 = 320 bit plot type bytes on the way
print escape ; SEQUENCE TO SET UP 320 BIT PLOTS IN 640 MODE
print 'S' ; OF CITOH This is the set-up for the small print
print '0' ; Would love to try to use all 640 bits here
print '3'
print '2'
print '0'
ind30:
ENDIF
pop cx
ret
indent endp
; This is indent for LARGE print
; This time we have 200*6=1200 bit plots to send
; 1440-1200=240/18 =13.33 extra, so indent 6
indent2 proc near
push cx
IF TOSHIBA
mov cx,6 ; so indent 6 character type spaces
inlop2: print 20h
loop inlop2
print escape ; 200*6=1200
print ';'
print '1'
print '2'
print '0'
print '0'
ENDIF
; 640-400=240 / 8 = 30 EXTRA characters
IF CITOH
print escape ; ESC N = Pica pitch
print 'N'
mov cx,15 ; PICTURE ( we've got 400 dots and 640 to work with
inlop2: print 20h ; 640-400 / 8 dots per char. = 30 extra so indent
; the picture 15 spaces to center
loop inlop2
; ESC S 0400 = 400 bit plot type bytes on the way
print escape ; SEQUENCE TO SET UP 400 BIT PLOTS IN 640 MODE
print 'S' ; OF CITOH
print '0'
print '4'
print '0'
print '0'
ENDIF
pop cx
ret
indent2 endp
m640 proc near
m6ain: mov cx,80 ; 80 x 4 = 320 dots.
mov di,sp
m6loop: mov dl,80h ; 10000000b
call tst8 ; see if this comes back <> 0
mov al,ah ; we are testing bit patterns for one screen byte
call sendtwo ; don't send to printer unless something to send
mov dl,40h ; 01000000b
call tst8 ; each byte is 4 dots
mov al,ah ; so we test for each dot in a byte
call sendtwo ; send sets PTFLAG if there is a dot on the line
mov dl,20h ; 00100000b
call tst8 ; then resets to start of line and starts printing
mov al,ah ; AL is the bit plot byte being built
call sendtwo
mov dl,10h ; 00010000b
call tst8 ; TST4 scans down 8 screen dot lines each time called
mov al,ah
call sendtwo
mov dl,08h ; 00001000b
call tst8 ; see if this comes back <> 0
mov al,ah ; we are testing bit patterns for one screen byte
call sendtwo ; don't send to printer unless something to send
mov dl,04h ; 00000100b
call tst8 ; each byte is 4 dots
mov al,ah ; so we test for each dot in a byte
call sendtwo ; send sets PTFLAG if there is a dot on the line
mov dl,02h ; 00000010b
call tst8 ; then resets to start of line and starts printing
mov al,ah ; AL is the bit plot byte being built
call sendtwo
mov dl,01h ; 00000001b
call tst8 ; TST4 scans down 8 screen dot lines each time called
mov al,ah
call sendtwo
loop m6loop ; 80 bytes make 320 dots
call lfcr ; this is a good old regular line feed/carriage return
call break? ; see if someone hit ESC key. If so take early exit
or al,al
mov dh,cs:loop_count
dec dh ; DL is line counter
cmp dh,0 ; when it goes 0 we're through
jz d6one ; reset everything and do an IRET
mov cs:loop_count,dh
mov ax,ds ; otherwise bump the SEGMENT reg so that location
add ax,14h ; 0 is the start of the next line
mov ds,ax ; X'140' = 320
jmp m6ain ; and do this 80 times (80x4=320)
d6one: mov ax,0
jmp done1
m640 endp
tst4 proc near ; This routine builds ONE bit plot byte
mov bx,80 ; by testing a dot with the mask sent
sub bx,cx ; from MLOOP.
mov si,bx ; First it does the ODD rows then the EVEN,
xor ax,ax ; alternate lines are offset 2000h
mov bl,[si] ; from each other in memory.
and bl,dl ; DL has the mask
or bl,bl ; SI the location
jz no7 ; BL the memory byte
mov bh,bl
and bx,1010101001010101b ; separate components of two bits/pixel
test bh,dl ; even bit
jz ts7a
or ah,80h ; if set, set on data word
ts7a:
test bl,dl ; odd bit
jz no7
or ah,40h
no7: add si,80 ; +80 gets us from say 0,0 to 2,0
mov bl,[si] ; get the memory byte ( 4 dots )
and bl,dl ; get rid of dots we aren't testing now
or bl,bl ; see if its COLOR 0
jz no5 ; if yes, go on
mov bh,bl
and bx,1010101001010101b ; separate components of two bits/pixel
test bh,dl ; even bit
jz ts5a
or ah,8 ; if set, set on data word
ts5a:
test bl,dl ; odd bit
jz no5
or ah,4
no5: add si,80 ; continue 7 5 3 1
mov bl,[si] ; xxxxxx
and bl,dl ;
or bl,bl ; xxxxxx
jz no3 ; xxxxxx
mov bh,bl
and bx,1010101001010101b ; separate components of two bits/pixel
test bh,dl ; even bit
jz ts3a
or al,80h ; if set, set on data word
ts3a:
test bl,dl ; odd bit
jz no3
or al,40h
no3: add si,80 ; xxxxxx
mov bl,[si] ;
and bl,dl
or bl,bl
jz no1
mov bh,bl
and bx,1010101001010101b ; separate components of two bits/pixel
test bh,dl ; even bit
jz ts1a
or al,8 ; if set, set on data word
ts1a:
test bl,dl ; odd bit
jz no1
or al,4
no1: push ax
mov ax,80
sub ax,cx ; CX counts our screen position
add ax,2000h ; add 2000h for the EVEN rows
mov si,ax ; with seg set to B800h we can use SI like an
pop ax ; array pointer ( AH has our byte so don't lose )
mov bl,[si] ; and continue with the same idea for 6 4 2 0
and bl,dl
or bl,bl
jz no6
mov bh,bl
and bx,1010101001010101b ; separate components of two bits/pixel
test bh,dl ; even bit
jz ts6a
or ah,20h ; if set, set on data word
ts6a:
test bl,dl ; odd bit
jz no6
or ah,10h
; call set6
no6: add si,80
mov bl,[si]
and bl,dl
or bl,bl
jz no4
mov bh,bl
and bx,1010101001010101b ; separate components of two bits/pixel
test bh,dl ; even bit
jz ts4a
or ah,2 ; if set, set on data word
ts4a:
test bl,dl ; odd bit
jz no4
or ah,1
; call set4
no4: add si,80
mov bl,[si]
and bl,dl
or bl,bl
jz no2
mov bh,bl
and bx,1010101001010101b ; separate components of two bits/pixel
test bh,dl ; even bit
jz ts2a
or al,20h ; if set, set on data word
ts2a:
test bl,dl ; odd bit
jz no2
or al,10h
; call set2
no2: add si,80
mov bl,[si]
and bl,dl
or bl,bl
jz no0
mov bh,bl
and bx,1010101001010101b ; separate components of two bits/pixel
test bh,dl ; even bit
jz ts0a
or al,2 ; if set, set on data word
ts0a:
test bl,dl ; odd bit
jz no0
or al,1
; call set0
no0: ret
comment #
; hopefully this can be left out, it all depends on the LQ1500
; where's my Z80 now
; reverse this table if your bit plots use bit 0 for the top wire
IF BIT7
set15: or ah,80h ; top wire - bit 7
ret
set14: or ah,40h ; bit 6
ret
set13: or ah,20h ; bit 5
ret
set12: or ah,10h ; bit 4
ret
set11: or ah,08h ; bit 3
ret
set10: or ah,04h ; bit 2
ret
set9: or ah,02h ; bit 1
ret
set8: or ah,01h ; bit 0
ret
set7: or al,80h ; top wire - bit 7
ret
set6: or al,40h ; bit 6
ret
set5: or al,20h ; bit 5
ret
set4: or al,10h ; bit 4
ret
set3: or al,08h ; bit 3
ret
set2: or al,04h ; bit 2
ret
set1: or al,02h ; bit 1
ret
set0: or al,01h ; bit 0
ret
ENDIF
IF BIT0
set7: or ah,01h ; top wire - bit 0
ret
set6: or ah,02h ; bit 1
ret
set5: or ah,04h ; bit 2
ret
set4: or ah,08h ; bit 3
ret
set3: or ah,10h ; bit 4
ret
set2: or ah,20h ; bit 5
ret
set1: or ah,40h ; bit 6
ret
set0: or ah,80h ; bit 7
ret
ENDIF
#
tst4 endp
; 640 mode is single bits, no color, so result is in AL.
;
tst8 proc near ; This routine builds ONE bit plot byte
mov ax,80 ; by testing a dot with the mask sent
sub ax,cx ; from M6LOOP. Used by 640 mode
mov si,ax ; First it does the ODD row then the EVEN
mov ah,0 ; since alternate lines are offset 2000h
mov al,[si] ; from each other in memory.
and al,dl ; DL has the mask
cmp al,0 ; SI the location
jz to7 ; AL the memory byte
or ah,80h ; AH is the byte being built
to7: add si,80 ; +80 gets us from say 0,0 to 2,0
mov al,[si] ; get the memory byte ( 4 dots )
and al,dl ; get rid of dots we aren't testing now
cmp al,0 ; see if its COLOR 0
jz to5 ; if yes, go on
or ah,20h
; call set5 ; otherwise set that bit
to5: add si,80 ; continue 7 5 3 1
mov al,[si]
and al,dl
cmp al,0
jz to3
or ah,8
; call set3
to3: add si,80
mov al,[si]
and al,dl
cmp al,0
jz to1
or ah,2
; call set1
to1: push ax
mov ax,80
sub ax,cx ; CX counts our screen position
add ax,2000h ; add 2000h for the EVEN rows
mov si,ax ; with seg set to B800h we can use SI like an
pop ax ; array pointer ( AH has our byte so don't lose )
mov al,[si] ; and continue with the same idea for 6 4 2 0
and al,dl
cmp al,0
jz to6
or ah,40h
; call set6
to6: add si,80
mov al,[si]
and al,dl
cmp al,0
jz to4
or ah,10h
; call set4
to4: add si,80
mov al,[si]
and al,dl
cmp al,0
jz to2
or ah,4
; call set2
to2: add si,80
mov al,[si]
and al,dl
cmp al,0
jz to0
or ah,1
; call set0
to0: ret
tst8 endp
; This routine pre-scans a line to see if in fact there are any bit
; plots to send. The main routine will keep sending bytes here
; If a whole line of 0's are sent we avoid going through the
; set-up for bit-plot (i.e. slower movement) graphics when a CR/LF
; would take care of everything.
; If there IS something to send, PTFLAG is set, the current line
; position is set to 0, bit-plot is init., and bits are really sent to printer.
send proc near
; push ax ; save the character
; push ds ; DS saved cause it points to lines
; pop ax ; points to DS
; mov cs:dstor,ax ; save
cmp cs:ptflag,TRUE ; check for printing
jne nosend ; if PTFLAG isn't TRUE we are still scanning
; pop ax ; else get the char. in AL and print it
call send2 ; this is the real out to printer routine
ret
; jmp short noset ; restore DS and return
nosend:
; pop ax ; This is the SCAN routine
or al,al ; get the char. > test for 0 > if so reset and go back
jz noset
mov al,TRUE ; if <> 0
mov cs:ptflag,al ; set PTFLAG to go
mov sp,di ;DISCARD RETURN
cmp cs:oneor2,1 ; check which (small or LARGE)
jnz two ; indent 6 or 13 depending on which routine
cmp cs:mode640,TRUE
jz nos10
call indent ; indent also sets up bit-plot mode
; call noset ; NOSET will restore DS to right pos.
jmp main ; and do the line for real.
nos10:
call indent
; call noset
jmp m6ain
two: call indent2 ; init. for LARGE
mov si,cs:wheresi ; SI set back to start of line
; call noset ; get right DS
jmp main2a ; back to beginning
noset:
; push ax ; routine to restore DS
; mov ax,cs:dstor
; mov ds,ax
; pop ax
ret
send endp
send3 proc near
; takes word length data and sends to printer
;
; word reads left to right and has actual color values of eight
; vertical pixels
;
; these will be sent to the printer as three sets of four bytes each,
; each set of four bytes controlling the 24 pins on the print head.
;
; pixel box is 3x3. colors represented:
;
; color 0: color 1: color 2: color 3:
; o o o o o o o x o x o x
; o o o o x o o x o o x o
; o o o o o o o x o x o x
; 00 01 10 11
;
push bx
push cx
push dx
mov dx,ax
mov bx,ax
mov cx,4
send_loop1: ; first pattern
xor al,al ; first column
mov ah,dh
and ah,11110000b ; just top two pixels
or ah,ah ; check for zero
jz send_one
test ah,10000000b ; twos place
jz s320
; or al,00101000b ; 0-5 significant
s310:
test ah,01000000b ; ones place
jz s320
or al,00101000b
s320:
test ah,00100000b ; twos
jz send_one
; or al,00000101b
s330:
test ah,00010000b
jz send_one
or al,000101b
send_one:
call send
shl dx,1
shl dx,1
shl dx,1
shl dx,1
loop send_loop1
mov dx,bx ; restore char for next pattern
mov cx,4
send_loop2:
xor al,al ; first column
mov ah,dh
and ah,11110000b ; just top two pixels
or ah,ah ; check for zero
jz send_two
test ah,01000000b ; ones place
jz s340
or al,00010000b ; 0-5 significant
s340:
test ah,10000000b
jz s350
or al,00101000b ; only other
s350:
test ah,00010000b
jz s360
or al,00000010b
s360:
test ah,00100000b
jz send_two
or al,00000101b
send_two:
call send
shl dx,1
shl dx,1
shl dx,1
shl dx,1
loop send_loop2
mov dx,bx
mov cx,4
send_loop3: ; first pattern
xor al,al ; first column
mov ah,dh
and ah,11110000b ; just top two pixels
or ah,ah ; check for zero
jz send_three
test ah,10000000b ; twos place
jz s380
; or al,00101000b ; 0-5 significant
s370:
test ah,01000000b ; ones place
jz s380
or al,00101000b
s380:
test ah,00100000b
jz send_three
; or al,00000101b
s390:
test ah,00010000b
jz send_three
or al,00000101b
send_three:
call send
shl dx,1
shl dx,1
shl dx,1
shl dx,1
loop send_loop3
pop dx
pop cx
pop bx
ret
send3 endp
sendtwo proc near
; expands 640x200 mode byte in small mode
; bit is sent twice for 1280 3.56 x 3.33 7.11 x 6.66
;
; byte is in AL.
;
; on = x o off = o o
; o x o o
; x o o o
push bx ; save some regs
push cx
push dx
mov dx,ax ; copy data byte in al to dl,bl
mov bx,ax
mov cx,4 ; do it with a loop
stwo1:
xor al,al ; start out blank
test dl,10000000b ; check top bit
jz stwo10 ; not set, skip to next
mov al,00101000b ; if set reflect in data
stwo10:
test dl,01000000b ; check next
jz stwo20 ; do again.
or al,00000101b ; each byte is two verticle screen pixels
stwo20:
call send ; out to routine which prints or doesn't
shl dl,1 ; depending on line.
shl dl,1 ; now move data left
loop stwo1 ; and do it four times.
mov dx,bx ; get back copy
mov cx,4 ; and send again
stwo2:
xor al,al
test dl,10000000b
jz stwo30
mov al,00010000b
stwo30:
test dl,01000000b
jz stwo40
or al,00000010b
stwo40:
call send
shl dl,1
shl dl,1
loop stwo2
pop dx
pop cx
pop bx
ret
sendtwo endp
send_big_color proc near
; take four pixel byte in al and expand to 24 x 6 to printer
push bx
push cx
push dx
mov dx,ax ; copy data byte
mov cs:data_byte,al
xor bx,bx
mov cx,6 ; basically send for six vertical dot firings
secloop1:
push cx ; two loops, save first counter
mov dl,cs:data_byte ; get original data
xor dh,dh ; blank top half
mov cx,4 ; set up inner loop
secloop2:
xor al,al ; clear printer byte
test dl,11000000b ; see if its zero
jz sec25
shl dx,1 ; move bits in question into lower dh
shl dx,1
and dh,3 ; discard others 11 binary
cmp dh,1 ; is it a one?
jnz sec10 ; no, try another
mov al,cs:bigc1[bx] ; else use pattern 1
jmp short sec30 ; and go print
sec10:
cmp dh,2 ; is it a two?
jnz sec20 ; no, then must be 3
mov al,cs:bigc2[bx] ; else use pattern 2
jmp short sec30 ; off to print.
sec20:
mov al,cs:bigc3[bx] ; determined to be 3
jmp short sec30
sec25:
shl dx,1 ; keep track of bits for zero case
shl dx,1
sec30:
call send ; out to send routine
loop secloop2 ; do for each pixel
pop cx ; get back other counter
inc bx
loop secloop1 ; do six times
pop dx ; and we are done.
pop cx
pop bx
ret
send_big_color endp
send_big_bw proc near
; take four pixel byte in al and expand to 24 x 6 to printer
push bx
push cx
push dx
mov dx,ax ; copy data byte
mov cs:data_byte,al
mov bl,010000b
mov bh,000010b ; pattern
mov cx,6 ; basically send for six vertical dot firings
sebloop1:
push cx ; two loops, save first counter
xor bx,11100111000b ; reverse pattern
mov dl,cs:data_byte ; bl won't be changed
mov cx,4 ; set up inner loop
sebloop2:
xor al,al ; clear printer byte
test dl,10000000b ; check top
jz seb10
mov al,bl ; else use pattern 1
seb10:
test dl,01000000b
jz seb20
or al,bh
seb20:
shl dl,1 ; set up for next
shl dl,1
seb30:
call send ; out to send routine
loop sebloop2 ; do for each pixel
pop cx ; get back other counter
loop sebloop1 ; do six times
pop dx ; and we are done.
pop cx
pop bx
ret
send_big_bw endp
lfcr proc near ; send a regular CR/LF combo
print 13
print 10
mov ax,0
mov cs:ptflag,al ; reset PTFLAG for next line
; mov ax,cs:dstor ; restore DS
; mov ds,ax
ret ; onward
lfcr endp
break? proc near ; Test for early exit
push ax ; don't lose any regs. here
push dx
mov ah,01h ; call direct keyboard io (constat) by BIOS
int 16h
jnz goback? ; if zero flag clear we have a character
bcont: pop dx ; no char. return
pop ax
ret
goback?:
mov ah,0
int 16h
cmp al,1bh ; ESC
jz back ; so go back, else return
jmp short bcont ; no ESC exit
back: pop dx ; ESC exit This doesn't check for Ctrl-Break
pop ax ; so if it is hit we save it for the caller to handle
pop ax ;DISCARD RETURN
cmp cs:tmode_flag,TRUE
jne GB10
call reset_cursor
GB10:
jmp done ; and go back to orig. caller
break? endp
; text_mode
; routines for text mode dump
; 7/4/85
; right shift will print with control chars and extended replaced by dots '.'
; left shift will print graphics chars.
read_line proc near
; read line from screen into buffer, calculate length and put in first pos.
push bp
mov di,80h ; use default dta from original load
inc di
mov dh,loop_count
xor dl,dl
mov bh,video_page
mov bl,crt_cols
cld ; set auto-increment
rloop:
mov ah,2 ; set cursor
int 10h
mov ah,8 ; read att/char
int 10h
or al,al ; replace 0 with space
jz rtl20
cmp al,0ffh ; and 255
je rtl20
rtl10:
stosb
inc dl
cmp dl,bl
jne rloop
jmp rtl_scan
rtl20:
mov al,' ' ; replace space type chars with spaces
jmp rtl10
rtl_scan:
dec di ; set to last char
mov si,80h ; length store
mov cl,bl ; loop for length
xor ch,ch
mov al,' ' ; search for spaces
std ; set auto_decrement
repe scasb ; search backwards until 0 or non-space
je rtl30
inc cl ; adjust for count of characters, else cl is zero
rtl30:
mov [si],cl
cld
rtlret:
pop bp
ret
read_line endp
do_extended proc near
mov al,'.'
call send2
ret
do_extended endp
do_control proc near
mov al,'.'
call send2
ret
do_control endp
print_line proc near
; use info in buffer to print
mov si,80h
lodsb ; get length
or al,al
jnz pl10
plret:
ret
pl10:
mov cl,al
xor ch,ch
cld
ploop:
lodsb
cmp al,127
ja pl_extended
cmp al,32
jb pl_control
call send2
plnext:
loop ploop
jmp plret
pl_extended:
call do_extended
jmp plnext
pl_control:
call do_control
jmp plnext
print_line endp
do_text_mode proc near
; comes in just after test for mode, but before shift key check
mov cs:crt_cols,ah
mov cs:video_page,bh
mov cs:tmode_flag,TRUE
mov ax,40h ; Get the keyboard shift flag
mov ds,ax ; segment
mov si,17h ; and address
mov ax,[si] ; pick it up
and ax,3 ; get rid of other stuff
or ax,ax ; Mod. to create default small
jnz tr1 ; for case where routine is called as a subroutine.
mov ax,cs:default_routine
tr1: mov cs:oneor2,al ; store for later
mov ax,cs
mov ds,ax ; set data to here
mov es,ax
mov ah,3
int 10h ; read cursor pos.
mov cursor_pos,dx ; save
mov byte ptr loop_count,0
tmode_loop:
call read_line ; read in entire line
call print_line ; send to printer
call lfcr
call break?
mov al,loop_count
inc al
mov loop_count,al
cmp al,MAX_LINES
jnz tmode_loop
call reset_cursor
jmp done
reset_cursor:
mov dx,cursor_pos ; restore cursor
mov bh,video_page
mov ah,2
int 10h
mov tmode_flag,FALSE
ret
do_text_mode endp
last dw 0 ; this marks end of resident code.
; DON'T put anything below here you expect to use
; after initialization.
buffer db ' TOSHIBA(tm) P1340, P1351, P351',13,10
db ' Screen Printer v 1.1',13,10,10
db ' ==> Graphics Mode:',13,10
db ' Right Shift PrtSc = small graphics',13,10
db ' Left Shift PrtSc = LARGE GRAPHICS',13,10
db ' ==> Text Mode:',13,10
db ' Right Shift PrtSc = quick screen print',13,10
db 'Left Shift PrtSc = extended characters printed',13,10,10
db ' ESCape will exit at the end of a line.',13,10,'$'
werehere db ' ** TOSHIBA.COM is already resident **',13,10,10
db ' There is no need to reinstall.',13,10,'$'
initr proc far
initial:
mov ax,0 ; get addr of
mov ds,ax ; print screen routine
mov si,14h ; in rom
mov ax,[si] ; from interrupt table in ram
inc si
inc si
mov dx,[si]
mov word ptr cs:old_print_routine,ax
mov word ptr cs:old_print_routine+2,dx
mov cx,offset last-offset start
mov di,ax
mov si,offset start
cmp dx,0efffh ; if routine points to ROM, ours is not it.
ja initok
cmp si,di
jne initok ; if start location not same, it can't be ours.
; otherwise check to see if this routine is
mov es,dx ; already in memory, and don't reinstall if so.
mov ax,cs
mov ds,ax
repe cmpsb
or cx,cx ; cx=0 means there is a copy of this at the
jnz initok ; other address.
mov dx,offset werehere
mov ah,9 ; so we print a message and
int 21h ; abort.
int 20h
initok:
; mov ds,ax
; mov al,0f1h ; move it to
; mov ah,25h
; int 21h ; int f1h described in tech. manual as unused vector
mov ax,cs ; reset int 5
mov ds,ax ; to point to
mov ax,offset start ; this routine
mov dx,ax
mov al,5
mov ah,25h ; dos routine to reset int. vector
int 21h
mov ax,offset buffer
mov dx,ax
mov ah,9
int 21h ; print greeting
mov ax,3000h ; get dos version
int 21h
or al,al
jz dos1
mov ax,offset last
mov cx,16
xor dx,dx
div cx
inc ax ; make number of paragraphs
mov dx,ax
mov al,0 ; exit code
mov ah,31h ; terminate process, keep resident
int 21h
dos1:
mov dx,offset last ; last address here
inc dx
int 27h ; terminate but stay resident
initr endp
cseg ends
end init
Volume in drive A has no label
Directory of A:\
BATMAN BAS 2032 4-06-83 11:58a
BATMAN DOC 2506 4-06-83 7:02a
BSR BAS 783 4-17-83 6:01p
BSR DAT 409 4-24-83 8:14a
BUZOFF COM 128 4-24-83 8:36a
CALLGRAF BAS 2039 1-12-85 5:08p
CALLGRAF TXT 2158 1-12-85 5:03p
COMPRS COM 128 4-24-83 8:37a
COPYGRAF BAT 173 3-03-85 6:18p
CVTHEX EXE 25472 3-22-83 11:57p
DCPATCH DOC 472 4-06-83 10:05p
DIAL COM 384 4-24-83 8:35a
DIR BAS 15104 4-03-83 11:55a
DIR DAT 384 4-03-83 12:06p
DIR DOC 915 4-03-83 11:05a
DOTABLE ASM 1883 7-16-85 12:32a
DOTDATA ASM 22771 7-16-85 12:32a
DOTS DAT 24726 7-16-85 12:02a
DOTS PRO 2717 7-10-85 11:23p
FILES33 TXT 3478 10-01-87 9:32a
FK203 ASM 6177 4-24-83 8:23a
FK203 EXE 1152 4-24-83 8:39a
GDEMO BAS 480 5-06-85 11:38p
GO BAT 38 7-08-87 12:19a
GO TXT 1233 9-29-07 8:12a
GRAFTRAX ASM 29427 3-19-85 11:34a
GRAFTRAX BAS 2180 4-17-83 3:46p
GRAFTRAX COM 1506 12-16-85 11:17p
GRAFTRAX DOC 2444 11-26-85 10:55p
GRCITOH COM 1546 12-08-84 12:18a
HANG COM 384 4-24-83 8:35a
HOST BAS 12160 12-16-82 2:42p
HOST DOC 379 1-01-80 2:41a
MAKEDOTS BAS 273 6-30-85 11:13p
NECGRAF COM 1546 11-14-84 10:28p
NEWT ASM 42182 8-17-86 2:10p
NEWT COM 9261 7-20-86 12:02a
OKIGRAF ASM 32019 12-20-84 9:59p
OKIGRAF COM 1640 11-08-84 12:00a
PEPATCH DOC 684 4-17-83 1:52p
POSTER BAS 3173 4-24-83 1:52p
PRTFIX COM 128 4-24-83 8:34a
PRTFIX DOC 123 4-24-83 8:18a
QD COM 2176 3-23-83 12:02a
QD DOC 4992 3-22-83 11:26p
READ ME 4697 1-26-87 8:23p
SCROLL ASM 3038 4-17-83 4:49p
SCROLL BLD 128 4-17-83 5:30p
SCROLL DOC 4752 4-17-83 6:00p
SCROLL1 BAS 1284 4-17-83 4:54p
SCROLL2 BAS 1673 4-17-83 4:55p
SHELL BAT 509 4-06-83 12:07p
SOUNDS BAS 4736 3-20-83 8:54a
TOSHIBA ASM 38753 7-05-85 2:00a
TOSHIBA COM 2306 7-05-85 1:13a
TOSHIBA DOC 1522 1-26-87 8:24p
56 file(s) 329363 bytes
1024 bytes free