'=========================================================================== ' Subject: FAST PRINT REPLACEMENT Date: 08-01-96 (11:34) ' Author: Jonathan Leger Code: QB, QBasic, PDS ' Origin: leger@mail.dtx.net Packet: TEXT.ABC '=========================================================================== ' This is a TWO part snippet (XPRINT.BAS and XPRINT.8 to follow) '****************** '*** XPRINT.BAS *** '**************************************************************************** '*** This program will demonstrate the superior speed of Xprint over *** '*** Qbasic and QuickBASIC's PRINT, COLOR and LOCATE statements. *** '*** Xprint is typically about 350% - 400% faster than Qbasic and from *** '*** 30% - 60% faster than QuickBASIC. *** '*** *** '*** HOWEVER! Please note that Xprint() performs _no_ error checking *** '*** except for making sure the string is longer than 0 bytes, while *** '*** QuickBASIC wont let you print off the screen, etc. If this program *** '*** did that error checking, it would be as slow as QuickBASIC, which *** '*** would defeat the purpose! Absence of this error checking is not *** '*** dangerous unless you're printing a string that's longer than 16,000 *** '*** bytes to the screen (and I'm not even sure if that's completely *** '*** dangerous...), which will go outside the bounds of your screen *** '*** memory. Anyone, however, who would do this is clearly not too swift *** '*** (mentally speaking) and probably needs to have his computer crash on *** '*** him every now and again to wake him up. *** '**************************************************************************** '*** This demonstration program and the Xprint() routines were written by *** '*** Jonathan Leger (leger@mail.dtx.net), and may be freely distributed *** '*** to anybody. These routines are 100% absolutely no lies or nothin' *** '*** FREE to the general public. You can send me e-mail to praise my *** '*** genious if you want, but I require nothing more. *grin* *** '**************************************************************************** DEFINT A-Z '*** The declaration of Absolute() is required for QB, which must be loaded '*** with "/L QB" for it to work. The declartion in Qbasic is optional. DECLARE SUB Absolute (arg1%, arg2%, arg3%, arg4%, arg5%, arg6%, arg7%, offset%) '*** readyXprint() stores the machine language Xprint() routine, and must be '*** called before using the Xprint. Note, though, that it only needs to be '*** called _once_. DECLARE SUB readyXprint () '*** The actual Xprint() routine. Prints s$ to coordintes (x%,y%) on the '*** screen in color fore%, back%. Notice, though, that to keep the feel '*** of BASIC's LOCATE, which is in the format LOCATE Y, X, the Y precedes '*** the X in the Xprint() routine also. DECLARE SUB Xprint (s$, y%, x%, fore%, back%) '*** This sub is used only in the demonstration, so you can trash it if you '*** don't want it. DECLARE SUB testXprint () SCREEN 0 WIDTH 80, 25 readyXprint 'This routine must be called before using Xprint! 'You only have to call it once though. :) testXprint 'Lessee some comparisons... DEFSNG A-Z '********************** '*** readyXprint() * '************************************************************************** '*** This routine loads the xprint machine-language program into the *** '*** xprint.asm$ string for use by the Xprint() routine. This program *** '*** _must_ be called before using the Xprint() routine, or the program *** '*** will crash! *** '************************************************************************** '*** All questions and comments welcome. Send inquries to the me at *** '*** leger@mail.dtx.net *** '************************************************************************** SUB readyXprint SHARED asm$ '*** This is the actual X-print program. '*** It was written using A86--a truly beautiful assembler! asm$ = "" asm$ = asm$ + CHR$(85) + CHR$(137) + CHR$(229) + CHR$(131) asm$ = asm$ + CHR$(126) + CHR$(10) + CHR$(0) + CHR$(116) + CHR$(66) asm$ = asm$ + CHR$(139) + CHR$(126) + CHR$(14) + CHR$(131) + CHR$(239) asm$ = asm$ + CHR$(1) + CHR$(137) + CHR$(251) + CHR$(193) + CHR$(231) asm$ = asm$ + CHR$(7) + CHR$(193) + CHR$(227) + CHR$(5) + CHR$(3) asm$ = asm$ + CHR$(251) + CHR$(131) + CHR$(110) + CHR$(12) + CHR$(1) asm$ = asm$ + CHR$(209) + CHR$(102) + CHR$(12) + CHR$(3) + CHR$(126) asm$ = asm$ + CHR$(12) + CHR$(139) + CHR$(86) + CHR$(18) + CHR$(193) asm$ = asm$ + CHR$(226) + CHR$(4) + CHR$(3) + CHR$(86) + CHR$(16) asm$ = asm$ + CHR$(30) + CHR$(142) + CHR$(94) + CHR$(8) + CHR$(139) asm$ = asm$ + CHR$(118) + CHR$(6) + CHR$(80) + CHR$(184) + CHR$(0) asm$ = asm$ + CHR$(184) + CHR$(142) + CHR$(192) + CHR$(88) + CHR$(139) asm$ = asm$ + CHR$(78) + CHR$(10) + CHR$(138) + CHR$(4) + CHR$(38) asm$ = asm$ + CHR$(136) + CHR$(5) + CHR$(38) + CHR$(136) + CHR$(85) asm$ = asm$ + CHR$(1) + CHR$(70) + CHR$(71) + CHR$(71) + CHR$(226) asm$ = asm$ + CHR$(242) + CHR$(31) + CHR$(93) + CHR$(203) END SUB DEFINT A-Z SUB testXprint LOCATE , , 0 CLS LOCATE 1, 1 COLOR 7, 0 PRINT "XPRINT" t.xprint# = TIMER FOR redraw = 1 TO 100 back = INT(RND * 7) + 1 FOR y = 2 TO 25 Xprint STRING$(80, " "), y, 1, 7, back NEXT y NEXT redraw t.xprint# = TIMER - t.xprint# CLS LOCATE 1, 1 COLOR 7, 0 PRINT "BASIC" t.basic# = TIMER FOR redraw = 1 TO 100 COLOR 7, INT(RND * 7) + 1 FOR y = 2 TO 25 LOCATE y, 1 PRINT STRING$(80, " "); NEXT y NEXT redraw t.basic# = TIMER - t.basic# COLOR , 0 CLS PRINT "XPrint redrew the screen 100 times in"; t.xprint#; "seconds." PRINT "BASIC redrew the screen 100 times in"; t.basic#; "seconds." PRINT PRINT "XPrint was approximately"; INT((t.basic# / t.xprint#) * 100); "% faster." END SUB '***************** '*** Xprint() * '************************************************************************** '*** Arguments: *** '*** s$ = string to print *** '*** y% = line to print at *** '*** x% = column to print at *** '*** fore% = foreground color (normal BASIC numbering used) *** '*** back% = background color (normal BASIC numbering used) *** '************************************************************************** '*** This routine was written by Jonathan Leger (leger@mail.dtx.net) *** '*** using the A86 assembler. The assembly-language file can be viewed *** '*** for further study (XPRINT.8). *** '************************************************************************** '*** All questions and comments welcome. Send inquries to the above *** '*** e-mail address. *** '************************************************************************** SUB Xprint (s$, y%, x%, fore%, back%) SHARED asm$ DEF SEG = VARSEG(asm$) CALL Absolute(BYVAL back%, BYVAL fore%, BYVAL y%, BYVAL x%, BYVAL LEN(s$), BYVAL VARSEG(s$), BYVAL SADD(s$), SADD(asm$)) DEF SEG END SUB ;--------------------8<----[ Begin XPRINT.8 ]---->8--------------------- ;*** Xprint for BASIC. ;*** Prints a string to coordintes y%, x%, with color f%, b%, real fast. :) ;*** call like this: ;*** ;*** Call Absolute (b%, f%, y%, x%, len(s$), sadd(s$), varptr(s$), offset%) ;*** ;*** WARNING: This routine does _no_ error checking to see if you're going ;*** off-screen with the string (for speed purposes), so please ;*** be sure to check that in your program! PUSH BP ;preserve BP! MOV BP,SP STRUC [BP] JUNK1 DW ? JUNK2 DW ? JUNK3 DW ? ;the junk we don't need! STR_OFF DW ? ;our string pointer [bp+6] STR_SEG DW ? ;our string segment [bp+8] LEN DW ? ;our string length [bp+0a] X DW ? ;our x location [bp+0c] Y DW ? ;our y location [bp+0e] FORE DW ? ;foreground color [bp+10] BACK DW ? ;background color [bp+12] ENDS CMP LEN,00 JE Done MOV DI,Y ;get the offset for the starting character SUB DI,1 ;using the formula: MOV BX,DI ; ( ( ( Y - 1 ) * 80 ) + X ) SHL DI,7 SHL BX,5 ADD DI,BX SUB X,1 SHL X,1 ADD DI,X ;DI now contains the starting offset. MOV DX,BACK ;calculate the color value using the formula: SHL DX,4 ; ( FOREGROUND + ( BACKGROUND * 16 ) ) ADD DX,FORE PUSH DS MOV DS,STR_SEG ;string segment MOV SI,STR_OFF ;string offset MOV ES,0B800 ;screen offset for color scren 0 MOV CX,LEN PrintChar: MOV AL,DS:[SI] ;put next character into AL MOV ES:B[DI],AL ;write it to screen MOV ES:B[DI+1],DL ;write color value to screen INC SI ;next character INC DI,2 ;next screen coordinate LOOP PrintChar Done: POP DS ;restore DS for BASIC POP BP ;restore BP for BASIC RETF ;return to BASIC!