%TestMode = 0 $IF 0 **************************************************************************** -=ð PBANSI fr PowerBASIC 3.2 ð=- Version 0.20 (Beta) >>> Engine incl. Sourcecode zur Wiedergabe von ANSI Sequenzen <<< entwickelt von Th.Gohel FidoNet : Thomas Gohel@2:2410/330.1 InterNet: author@pbsound.snafu.de Homepage: http://www.snafu.de/~pbsound/ letztes Update 10.07.1996 Vorwort: Dieses ist die erste ”ffentliche Release meines neuen und auch bisher mit Abstand schnellsten ANSI-Engine fr PowerBASIC. Es ist nur allzu natrlich, das diese Engine noch diverse Bugs hat bzw. diverse Sachen einfach noch fehlen. In diesem Fall bitte ich, das Ihr mir die betreffenen ANSI-Seiten einfach schickt. Speed: Diese Version von PBANSI ist nur sehr schlecht optimiert. Ich denke, das noch ca 20-30% mehr Speed in der Engine stecken, da die Inline-Assembler Routinen zur Zeit ziemlich miserabel von mir umgesetzt wurden . Ebenfalls sollte eine alternative Scrollroutine nochmals einen erheblichen Geschwindigkeits- zuwachs bringen. Die bisher erreichte Performance von PBANSI baut auf grundlegende Kenntnis des PowerBASIC Compilers und die konsequente Durch- setzung eine 'schnellen Art' der Programmierung, dazu geh”rt: - keine Verwendung von SELECT CASE Schleifen - keine Uebergabe von Variablen ber Stacks Aber das Thema wird sehr gut in der PowerBASIC-FAQ beschrieben, sodas ich hier nichts weiteres schreibe. Geschwindigkeitsvergleich (relativ zu ANSI.SYS): PBANSI v0.10 LANSI v3.1 DOSANSI v7.0/Win95 ============================================================== mit CoPro: 45% 165% 100% ohne CoPro: 45% 470% 100% PBANSI ist somit bereits jetzt ber 10mal schneller als die LANSI-Source von Jamshid Khoshrangi! **************************************************************************** $ENDIF $IF %TestMode $LIB ALL ON $LIB COM ON $LIB IPRINT OFF $DIM ALL DEFINT A-Z $COM 1024 $ENDIF DIM AnsiOn AS SHARED INTEGER ' ob gerade eine ANSI-Sequenz l„uft DIM AnsiESC AS SHARED INTEGER ' eine m”gliche ANSI-Sequenz wurde entdeckt DIM AnsiPos AS SHARED INTEGER ' Stelle des ANSI-Wertes DIM AnsiHigh AS SHARED INTEGER ' on das Low- oder Highbyte ermittelt wird DIM AnsiData(10) AS SHARED INTEGER ' enth„lt die einzelnen ANSI-Werte DIM AnsiColor(50) AS SHARED BYTE ' Color šbersetzungstabelle DIM AnsiForeColor AS SHARED INTEGER ' Vordergrundfarbe DIM AnsiBackColor AS SHARED INTEGER ' Hintergrundfarbe DIM AnsiIntensiv AS SHARED INTEGER ' Intensivflag DIM AnsiBlink AS SHARED INTEGER ' Blinkflag DIM AnsiStartX AS SHARED INTEGER ' wirklicher X-Start des ANSI-Fensters DIM AnsiStartY AS SHARED INTEGER ' wirklicher Y-Start des ANSI-Fensters DIM AnsiEndeX AS SHARED INTEGER ' wirkliches X-Ende des ANSI-Fensters DIM AnsiEndeY AS SHARED INTEGER ' wirkliches Y-Ende des ANSI-Fensters DIM AnsiPosX AS SHARED INTEGER ' Cursor Position DIM AnsiPosY AS SHARED INTEGER ' Cursor Position DIM AnsiFarbe AS SHARED INTEGER ' aktuelle Farbe DIM AnsiSavePosX AS SHARED INTEGER ' Cursor Position sichern DIM AnsiSavePosY AS SHARED INTEGER ' Cursor Position sichern DIM AnsiVideo AS SHARED WORD ' Segment des VideoRams DIM AnsiWert AS SHARED STRING ' enth„lt aktuelles Zeichen als STRING DIM AnsiCode AS SHARED INTEGER ' enth„lt aktuelles Zeichen als INTEGER DIM ModemData AS SHARED STRING ' globaler String mit den Datenstream vom ' Modem DECLARE SUB AnsiInit() DECLARE SUB AnsiPrint() DECLARE SUB AnsiDecode() DECLARE SUB SPrint() DECLARE SUB SScroll(BYVAL Anzahl AS INTEGER) DECLARE SUB ClearScreen() DECLARE SUB ClearLine() AnsiInit AnsiStartX% = 1 ' wirklicher X-Start des ANSI-Fensters AnsiStartY% = 1 ' wirklicher Y-Start des ANSI-Fensters AnsiEndeX% = 24 ' wirkliches X-Ende des ANSI-Fensters AnsiEndeY% = 80 ' wirkliches Y-Ende des ANSI-Fensters AnsiPosX% = 1 ' default Start AnsiPosY% = 1 ' default Start AnsiVideo?? = &h0b800 $IF %TestMode '*************************************************************************** ' Routinen zum Testen der ANSI Engine '*************************************************************************** DIM A AS SHARED STRING ' lokaler Tastatureingabe String DIM ModemDataLen AS SHARED INTEGER ' L„nge der Modem Rohdaten CLS COLOR 14,1 LOCATE 25,1: PRINT " PB/ANSI Emulator v0.10, (c) 1997 by Thomas Gohel BBS: +49-30-47300910 "; COLOR 7, 0 MTIMER OPEN "starsyst.ans" FOR BINARY AS #4 'OPEN "2.ans" FOR BINARY AS #4 DO WHILE NOT EOF(4) GET$ #4, 256, ModemData$ ANSIPrint ' A$=INPUT$(1) LOOP CLOSE #4 COLOR 14,3 LOCATE 25,20 PRINT ">> ben”tigte Zeit: ";USING$("###,###,###,###",MTIMER);" <<"; $ENDIF '************************************************************************** ' Start ANSI-Routines '************************************************************************** SUB ANSIInit public DIM Index AS LOCAL INTEGER FOR Index% = 0 TO 50 AnsiColor?(Index%) = 15 NEXT Index% AnsiColor?(00) = 0 AnsiColor?(23) = 6 AnsiColor?(29) = 7 AnsiColor?(30) = 0 AnsiColor?(31) = 4 AnsiColor?(32) = 2 AnsiColor?(33) = 6 AnsiColor?(34) = 1 AnsiColor?(35) = 5 AnsiColor?(36) = 3 AnsiColor?(37) = 7 AnsiColor?(40) = 0 AnsiColor?(41) = 4 AnsiColor?(42) = 2 AnsiColor?(43) = 6 AnsiColor?(44) = 1 AnsiColor?(45) = 5 AnsiColor?(46) = 3 AnsiColor?(47) = 7 AnsiOn% = 0 AnsiPos% = 1 AnsiPosX% = 1 AnsiPosY% = 1 AnsiFarbe% = 7 END SUB SUB ANSIPrint local DIM ModemCounter AS STATIC INTEGER ' Zeiger auf die aktuelle Datensequenz DIM ModemDataLen AS STATIC INTEGER ModemDataLen% = LEN(ModemData$) FOR ModemCounter% = 1 TO ModemDataLen% AnsiWert$ = MID$(ModemData$, ModemCounter%, 1) AnsiCode% = ASC(AnsiWert$) IF AnsiCode% = 27 OR AnsiESC% = 1 THEN AnsiDecode ELSEIF AnsiCode% = 10 THEN ! inc AnsiPosX% ELSEIF AnsiCode% = 12 THEN ClearScreen ELSEIF AnsiCode% = 13 THEN AnsiPosY% = 1 ELSE SPrint ! inc AnsiPosY% END IF NEXT i% END SUB SUB AnsiDecode local DIM p AS STATIC INTEGER ' tempor„rer Schleifenz„hler DIM c AS STATIC INTEGER ' tempor„rer Schleifenz„hler DIM Code AS STATIC STRING ' tempor„rer ANSI String 'Ups, jetzt mssen wir ANSI auswerten ;-))) IF AnsiCode% > 47 AND AnsiCode% < 58 THEN 'hier muá ein Daten- IF AnsiHigh% = 0 THEN 'block kommen Code = AnsiWert$ ! inc AnsiHigh% ELSE Code$ = Code$ + AnsiWert$ END IF AnsiData%(AnsiPos%) = VAL(Code$) ELSEIF AnsiCode% = 27 THEN ' ESC = ANSI folgt? AnsiESC% = 1 AnsiOn% = 0 ELSEIF AnsiCode% = 33 THEN ' ! AnsiOn% = -1 ELSEIF AnsiCode% = 59 THEN ' ; = ANSI-Trenner, Ende eines Datenblock's AnsiHigh% = 0 'es werden keine weiteren Daten erwartet ! inc AnsiPos% ELSEIF AnsiCode% = 65 THEN ' A = Cursor nach oben IF AnsiPosX% > 1 THEN ! dec AnsiPosX% END IF AnsiOn% = -1 ELSEIF AnsiCode% = 66 THEN ' B = Cursor nach unten IF AnsiPosX% < AnsiEndeX% + AnsiStartX% THEN ! inc AnsiPosX% END IF AnsiOn% = -1 ELSEIF AnsiCode% = 67 THEN ' C = Cursor nach rechts IF AnsiData%(1) > 1 THEN AnsiPosY% = AnsiPosY% + AnsiData%(1) END IF AnsiOn% = -1 ELSEIF AnsiCode% = 68 THEN ' D = Cursour nach links bewegen p% = AnsiData%(1) IF p% = 0 THEN ! dec AnsiPosY% ELSEIF p% = 255 THEN AnsiPosY% = 1 ELSE AnsiPosY% = AnsiPosY% - p% END IF AnsiOn% = -1 ELSEIF AnsiCode% = 72 OR AnsiCode% = 102 THEN ' H & f = ANSI-Position IF AnsiData%(1) = 0 THEN AnsiData%(1) = 1 IF AnsiData%(2) = 0 THEN AnsiData%(2) = 1 IF AnsiData%(1) > AnsiEndeX% - AnsiStartX% THEN AnsiData%(1) = AnsiEndeX% - AnsiStartX% END IF IF AnsiPos% = 1 THEN AnsiPosX% = AnsiData%(1) ELSEIF AnsiPos% = 2 THEN AnsiPosX% = AnsiData%(1) AnsiPosY% = AnsiData%(2) ELSE PRINT "Unknown Position Command!":BEEP:BEEP:BEEP END IF AnsiOn% = -1 ELSEIF AnsiCode% = 74 THEN ' J = ANSI-Clear Screen ClearScreen ELSEIF AnsiCode% = 75 THEN ' K = ANSI-Alles rechts neben dem Cursor ' l”schen, incl. Cursor c% = AnsiPosY% ClearLine AnsiPosY% = c% AnsiOn% = -1 ELSEIF AnsiCode% = 91 THEN ' [ = ANSI-Start AnsiOn% = 1 AnsiPos% = 1 AnsiHigh% = 0 ELSEIF AnsiCode% = 109 THEN ' m = ANSI-Color Settings ' erstmal eventuelle Attribute finden AnsiIntensiv% = 0 ' und zuerst das Intensivflag ausschalten AnsiBlink% = 0 AnsiForeColor% = 7 AnsiBackColor% = 0 IF AnsiPos% = 1 THEN IF AnsiData%(1) => 30 THEN AnsiIntensiv% = 8 ELSE AnsiIntensiv% = 0 END IF END IF FOR p% = 1 TO AnsiPos% IF AnsiData%(p%) = 1 THEN AnsiIntensiv% = 8 ELSEIF AnsiData%(p%) = 5 THEN AnsiBlink% = 128 END IF FOR c% = 37 TO 10 STEP -1 'rckw„rts geht hier schneller ;-) IF AnsiData%(p%) = c% THEN AnsiForeColor% = AnsiColor?(c%) EXIT FOR END IF NEXT c% FOR c% = 40 TO 47 IF AnsiData%(p%) = c% THEN AnsiBackColor% = AnsiColor?(c%) EXIT FOR END IF NEXT c% NEXT p% AnsiFarbe% = ((AnsiForeColor% + AnsiIntensiv% + AnsiBlink%) + AnsiBackColor% * 16) AnsiOn% = -1 ELSEIF AnsiCode% = 115 THEN ' s = ANSI-Save Cursor Position AnsiSavePosX% = AnsiPosX% AnsiSavePosY% = AnsiPosY% AnsiOn% = -1 ELSEIF AnsiCode% = 117 THEN ' u = ANSI-Restore Cursor Position AnsiPosX% = AnsiSavePosX% AnsiPosY% = AnsiSavePosY% AnsiOn% = -1 ELSE SPrint ! inc AnsiPosY% AnsiOn% = -1 END IF IF AnsiOn% = -1 THEN AnsiESC% = 0 END SUB SUB ClearScreen local ! mov ax, AnsiStartX% ! dec ax ! mov cx, 160 ! mul cx ! mov di, ax ! mov ax, AnsiVideo?? ! mov es, ax ! mov ax, AnsiEndeX% ! mov cx, 160 ! mul cx ! mov cx, ax ! mov ah, AnsiFarbe% ! xor al, al ! sub cx, di ! dec cx ClearScreen1: ! mov es:[di], ax ! inc di ! loop ClearScreen1 AnsiPosX% = 1 AnsiPosY% = 1 AnsiOn% = -1 END SUB SUB ClearLine local DIM SX AS STATIC INTEGER DIM SY AS STATIC INTEGER SX% = AnsiStartX% + AnsiPosX% SY% = AnsiStartY% + AnsiPosY% ! push ds ! mov ax, AnsiVideo?? ; Start des VideoRam eintragen ! mov es, ax ! mov ax, SX% ! dec ax ; Offset 1 abziehen ! dec ax ! mov cx, 160 ! mul cx ! mov bx, SY% ! dec bx ; Offset 1 von AnsiStartY% abziehen ! dec bx ; Offset 1 von AnsiPosY% abziehen ! shl bx, 1 ; mal 2 ! add bx, ax ! mov ax, AnsiEndeY% ! sub ax, AnsiPosY% ! mov cx, ax ! inc cx ! mov al, 0 ! mov ah, AnsiFarbe% ClearLine1: ! mov es:[bx], ax ! add bx, 2 ! loop ClearLine1 ! pop ds END SUB SUB SPrint local DIM SX AS STATIC INTEGER DIM SY AS STATIC INTEGER IF AnsiPosY% > AnsiEndeY% THEN AnsiPosY% = 1 ! inc AnsiPosX% END IF IF AnsiPosX% > AnsiEndeX% - AnsiStartX% + 1 THEN SScroll AnsiPosX% - (AnsiEndeX% - AnsiStartX%) - 1 AnsiPosX% = AnsiEndeX% - AnsiStartX% + 1 END IF SX% = AnsiStartX% + AnsiPosX% SY% = AnsiStartY% + AnsiPosY% ! push ds ! mov ax, AnsiVideo?? ; Start des VideoRam eintragen ! mov es, ax ! mov ax, SX% ! dec ax ; Offset 1 abziehen ! dec ax ! mov cx, 160 ! mul cx ! mov bx, SY% ! dec bx ; Offset 1 von AnsiStartY% abziehen ! dec bx ; Offset 1 von AnsiPosY% abziehen ! shl bx, 1 ; mal 2 ! add bx, ax ! mov al, AnsiCode% ! mov ah, AnsiFarbe% ! mov es:[bx], ax ! pop ds END SUB SUB SScroll(BYVAL Anzahl AS INTEGER) local ! push ds ! push si ! push di ! mov ah, &h06 ! mov al, Anzahl% ! mov bh, AnsiFarbe% ! mov ch, AnsiStartX% ! dec ch ! mov cl, AnsiStartY% ! dec cl ! mov dh, AnsiEndeX% ! dec dh ! mov dl, AnsiEndeY% ! dec dl ! int &h10 ! pop di ! pop si ! pop ds END SUB