summaryrefslogtreecommitdiff
path: root/basic/source/classes/disas.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'basic/source/classes/disas.cxx')
-rw-r--r--basic/source/classes/disas.cxx701
1 files changed, 701 insertions, 0 deletions
diff --git a/basic/source/classes/disas.cxx b/basic/source/classes/disas.cxx
new file mode 100644
index 000000000000..74c3922f0ab0
--- /dev/null
+++ b/basic/source/classes/disas.cxx
@@ -0,0 +1,701 @@
+/*************************************************************************
+ *
+ * $RCSfile: disas.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 16:12:09 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+
+#ifndef _STREAM_HXX //autogen
+#include <tools/stream.hxx>
+#endif
+#pragma hdrstop
+#include <svtools/sbx.hxx>
+#include "sb.hxx"
+#include "iosys.hxx"
+#include "disas.hxx"
+// Makro MEMBER()
+#include "macfix.hxx"
+
+#include "segmentc.hxx"
+#pragma SW_SEGMENT_CLASS( SBDISAS, SBDISAS_CODE )
+
+static const char* pOp1[] = {
+ "NOP",
+
+ // Operatoren
+ // die folgenden Operatoren sind genauso angeordnet
+ // wie der enum SbxVarOp
+ "EXP", "MUL", "DIV", "MOD", "PLUS", "MINUS", "NEG",
+ "EQ", "NE", "LT", "GT", "LE", "GE",
+ "IDIV", "AND", "OR", "XOR", "EQV", "IMP", "NOT",
+ "CAT",
+ // Ende enum SbxVarOp
+ "LIKE", "IS",
+ // Laden/speichern
+ "ARGC", // neuen Argv einrichten
+ "ARGV", // TOS ==> aktueller Argv
+ "INPUT", // Input ==> TOS
+ "LINPUT", // Line Input ==> TOS
+ "GET", // TOS anfassen
+ "SET", // Speichern Objekt TOS ==> TOS-1
+ "PUT", // TOS ==> TOS-1
+ "CONST", // TOS ==> TOS-1, dann ReadOnly
+ "DIM", // DIM
+ "REDIM", // REDIM
+ "REDIMP", // REDIM PRESERVE
+ "ERASE", // TOS loeschen
+ // Verzweigen
+ "STOP", // Programmende
+ "INITFOR", // FOR-Variable initialisieren
+ "NEXT", // FOR-Variable inkrementieren
+ "CASE", // Anfang CASE
+ "ENDCASE", // Ende CASE
+ "STDERR", // Standard-Fehlerbehandlung
+ "NOERROR", // keine Fehlerbehandlung
+ "LEAVE", // UP verlassen
+ // E/A
+ "CHANNEL", // TOS = Kanalnummer
+ "PRINT", // print TOS
+ "PRINTF", // print TOS in field
+ "WRITE", // write TOS
+ "RENAME", // Rename Tos+1 to Tos
+ "PROMPT", // TOS = Prompt for Input
+ "RESTART", // Restartpunkt definieren
+ "STDIO", // E/A-Kanal 0 einstellen
+ // Sonstiges
+ "EMPTY", // Leeren Ausdruck auf Stack
+ "ERROR", // TOS = Fehlercode
+ "LSET", // Speichern Objekt TOS ==> TOS-1
+ "RSET" // Speichern Objekt TOS ==> TOS-1
+};
+
+static const char* pOp2[] = {
+ "NUMBER", // Laden einer numerischen Konstanten (+ID)
+ "STRING", // Laden einer Stringkonstanten (+ID)
+ "CONST", // Immediate Load (+Wert)
+ "ARGN", // Speichern eines named Args in Argv (+StringID)
+ "PAD", // String auf feste Laenge bringen (+Laenge)
+ // Verzweigungen
+ "JUMP", // Sprung (+Target)
+ "JUMP.T", // TOS auswerten, bedingter Sprung (+Target)
+ "JUMP.F", // TOS auswerten, bedingter Sprung (+Target)
+ "ONJUMP", // TOS auswerten, Sprung in JUMP-Tabelle (+MaxVal)
+ "GOSUB", // UP-Aufruf (+Target)
+ "RETURN", // UP-Return (+0 oder Target)
+ "TESTFOR", // FOR-Variable testen, inkrementieren (+Endlabel)
+ "CASETO", // Tos+1 <= Case <= Tos, 2xremove (+Target)
+ "ERRHDL", // Fehler-Handler (+Offset)
+ "RESUME", // Resume nach Fehlern (+0 or 1 or Label)
+ // E/A
+ "CLOSE", // (+Kanal/0)
+ "PRCHAR", // (+char)
+ // Objekte
+ "CLASS", // Klassennamen testen (+StringId)
+ "LIB", // Libnamen fuer Declare-Procs setzen (+StringId)
+ // Neues ab Beta 3
+ "BASED", // TOS wird um BASE erhoeht, BASE davor gepusht
+ "ARGTYP", // Letzten Parameter in Argv konvertieren (+Typ)
+};
+
+static const char* pOp3[] = {
+ // Alle Opcodes mit zwei Operanden
+ "RTL", // Laden aus RTL (+StringID+Typ)
+ "FIND", // Laden (+StringID+Typ)
+ "ELEM", // Laden Element (+StringID+Typ)
+ "PARAM", // Parameter (+Offset+Typ)
+ // Verzweigen
+ "CALL", // DECLARE-Methode rufen (+StringID+Typ)
+ "CALL.C", // Cdecl-DECLARE-Methode rufen (+StringID+Typ)
+ "CASEIS", // Case-Test (+Test-Opcode+False-Target)
+ "STMNT", // Beginn eines Statements (+Line+Col)
+ // E/A
+ "OPEN", // (+SvStreamFlags+Flags)
+ // Objekte und Variable
+ "LOCAL", // Lokale Variable (+StringID+Typ)
+ "PUBLIC", // Modulglobale Variable (+StringID+Typ)
+ "GLOBAL", // Globale Variable (+StringID+Typ)
+ "CREATE", // Objekt kreieren (+StringId+StringId)
+ "STATIC", // Objekt kreieren (+StringId+StringId)
+ "TCREATE", // User defined Objekt kreieren (+StringId+StringId)
+ "DCREATE", // User defined Objekt-Array kreieren (+StringId+StringId)
+};
+
+static const char** pOps[3] = { pOp1, pOp2, pOp3 };
+
+typedef void( SbiDisas::*Func )( String& ); // Verarbeitungsroutine
+
+static const Func pOperand2[] = {
+ MEMBER(SbiDisas::StrOp), // Laden einer numerischen Konstanten (+ID)
+ MEMBER(SbiDisas::StrOp), // Laden einer Stringkonstanten (+ID)
+ MEMBER(SbiDisas::ImmOp), // Immediate Load (+Wert)
+ MEMBER(SbiDisas::StrOp), // Speichern eines benannten Arguments(+ID)
+ MEMBER(SbiDisas::ImmOp), // String auf feste Laenge bringen (+Laenge)
+ // Verzweigungen
+ MEMBER(SbiDisas::LblOp), // Sprung (+Target)
+ MEMBER(SbiDisas::LblOp), // TOS auswerten), bedingter Sprung (+Target)
+ MEMBER(SbiDisas::LblOp), // TOS auswerten), bedingter Sprung (+Target)
+ MEMBER(SbiDisas::OnOp), // TOS auswerten), Sprung in JUMP-Tabelle (+MaxVal)
+ MEMBER(SbiDisas::LblOp), // UP-Aufruf (+Target)
+ MEMBER(SbiDisas::ReturnOp), // UP-Return (+0 oder Target)
+ MEMBER(SbiDisas::LblOp), // FOR-Variable testen), inkrementieren (+Endlabel)
+ MEMBER(SbiDisas::LblOp), // Tos+1 <= Case <= Tos), 2xremove (+Target)
+ MEMBER(SbiDisas::LblOp), // Fehler-Handler (+Offset)
+ MEMBER(SbiDisas::ResumeOp), // Resume nach Fehlern (+0 or 1 or Label)
+ // E/A
+ MEMBER(SbiDisas::CloseOp), // (+Kanal/0)
+ MEMBER(SbiDisas::CharOp), // (+char)
+ // Objekte
+ MEMBER(SbiDisas::StrOp), // Klassennamen testen (+StringId)
+ MEMBER(SbiDisas::StrOp), // Libnamen fuer Declare-Procs setzen (+StringId)
+ MEMBER(SbiDisas::ImmOp), // TOS wird um BASE erhoeht, BASE davor gepusht
+ MEMBER(SbiDisas::TypeOp), // Letzten Parameter in Argv konvertieren (+Typ)
+};
+
+static const Func pOperand3[] = {
+ // Alle Opcodes mit zwei Operanden
+ MEMBER(SbiDisas::VarOp), // Laden aus RTL (+StringID+Typ)
+ MEMBER(SbiDisas::VarOp), // Laden (+StringID+Typ)
+ MEMBER(SbiDisas::VarOp), // Laden Element (+StringID+Typ)
+ MEMBER(SbiDisas::OffOp), // Parameter (+Offset+Typ)
+ // Verzweigen
+ MEMBER(SbiDisas::VarOp), // DECLARE-Methode rufen (+StringID+Typ)
+ MEMBER(SbiDisas::VarOp), // CDecl-DECLARE-Methode rufen (+StringID+Typ)
+ MEMBER(SbiDisas::CaseOp), // Case-Test (+Test-Opcode+False-Target)
+ MEMBER(SbiDisas::StmntOp), // Statement (+Zeilen+Spalte)
+ // E/A
+ MEMBER(SbiDisas::StrmOp), // (+SvStreamFlags+Flags)
+ // Objekte
+ MEMBER(SbiDisas::VarDefOp), // Lokale Variable definieren (+StringID+Typ)
+ MEMBER(SbiDisas::VarDefOp), // Modulglobale Variable definieren (+StringID+Typ)
+ MEMBER(SbiDisas::VarDefOp), // Globale Variable definieren (+StringID+Typ)
+ MEMBER(SbiDisas::Str2Op), // Objekt kreieren (+StringId+StringId)
+ MEMBER(SbiDisas::VarDefOp), // Statische Variable definieren (+StringID+Typ)
+ MEMBER(SbiDisas::Str2Op), // User defined Objekt kreieren (+StringId+StringId)
+ MEMBER(SbiDisas::Str2Op), // User defined Objekt-Array kreieren (+StringId+StringId)
+};
+
+static const char* _crlf()
+{
+#if defined (MAC)
+ return "\n";
+#elif defined (UNX) || defined( PM2 )
+ return "\n";
+#else
+ return "\r\n";
+#endif
+}
+
+// Diese Methode ist hier, damit die Datei als eigenes Segment geladen werden
+// kann.
+
+BOOL SbModule::Disassemble( String& rText )
+{
+ rText.Erase();
+ if( pImage )
+ {
+ SbiDisas aDisas( this, pImage );
+ aDisas.Disas( rText );
+ }
+ return BOOL( rText.Len() != 0 );
+}
+
+SbiDisas::SbiDisas( SbModule* p, const SbiImage* q ) : rImg( *q ), pMod( p )
+{
+ memset( cLabels, 0, 8192 );
+ nLine = nOff = nPC = nOp1 = nOp2 = nParts = 0;
+ eOp = _NOP;
+ // Label-Bits setzen
+ USHORT nPos;
+ nOff = 0;
+ while( Fetch() )
+ {
+ BOOL bLbl = FALSE;
+ switch( eOp )
+ {
+ case _RESUME: if( nOp1 <= 1 ) break;
+ case _RETURN: if( !nOp1 ) break;
+ case _JUMP:
+ case _JUMPT:
+ case _JUMPF:
+ case _GOSUB:
+ case _TESTFOR:
+ case _CASEIS:
+ case _CASETO:
+ case _ERRHDL: nPos = nOp1; bLbl = TRUE; break;
+ }
+ if( bLbl )
+ cLabels[ nPos >> 3 ] |= ( 1 << ( nPos & 7 ) );
+ }
+ nOff = 0;
+ // Die Publics noch dazu
+ for( USHORT i = 0; i < pMod->GetMethods()->Count(); i++ )
+ {
+ SbMethod* pMeth = PTR_CAST(SbMethod,pMod->GetMethods()->Get( i ));
+ if( pMeth )
+ {
+ nPos = pMeth->GetId();
+ cLabels[ nPos >> 3 ] |= ( 1 << ( nPos & 7 ) );
+ }
+ }
+}
+
+// Aktuellen Opcode auslesen
+
+BOOL SbiDisas::Fetch()
+{
+ nPC = nOff;
+ if( nOff >= rImg.GetCodeSize() )
+ return FALSE;
+ const char* p = rImg.GetCode() + nOff;
+ eOp = (SbiOpcode) ( *p++ & 0xFF );
+ if( eOp <= SbOP0_END )
+ {
+ nOp1 = nOp2 = 0;
+ nParts = 1;
+ nOff++;
+ return TRUE;
+ }
+ else if( eOp <= SbOP1_END )
+ {
+ nOff += 3;
+ if( nOff > rImg.GetCodeSize() )
+ return FALSE;
+ nOp1 = *p++ & 0xFF; nOp1 |= *p << 8;
+ nParts = 2;
+ return TRUE;
+ }
+ else if( eOp <= SbOP2_END )
+ {
+ nOff += 5;
+ if( nOff > rImg.GetCodeSize() )
+ return FALSE;
+ nOp1 = *p++ & 0xFF; nOp1 |= *p++ << 8;
+ nOp2 = *p++ & 0xFF; nOp2 |= *p << 8;
+ nParts = 3;
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+void SbiDisas::Disas( SvStream& r )
+{
+ String aText;
+ nOff = 0;
+ while( DisasLine( aText ) )
+ {
+ ByteString aByteText( aText, gsl_getSystemTextEncoding() );
+ r.WriteLine( aByteText );
+ }
+}
+
+void SbiDisas::Disas( String& r )
+{
+ r.Erase();
+ String aText;
+ nOff = 0;
+ while( DisasLine( aText ) )
+ {
+ r += aText;
+ r.AppendAscii( _crlf() );
+ }
+ aText.ConvertLineEnd();
+}
+
+#ifdef HP9000
+const char* SbiDisas_DisasLine_pMask[] = {
+ "%04X ",
+ "%04X %02X ",
+ "%04X %02X %04X ",
+ "%04X %02X %04X %04X " };
+#define pMask SbiDisas_DisasLine_pMask
+#endif
+BOOL SbiDisas::DisasLine( String& rText )
+{
+ char cBuf[ 30 ];
+#ifndef HP9000
+ const char* pMask[] = {
+ "%04X ",
+ "%04X %02X ",
+ "%04X %02X %04X ",
+ "%04X %02X %04X %04X " };
+#endif
+ rText.Erase();
+ if( !Fetch() )
+ return FALSE;
+ // Neue Zeile?
+ if( eOp == _STMNT && (short) nOp1 != nLine )
+ {
+ // Zeile raussuchen
+ USHORT n = 0, l = nLine = nOp1;
+ while( --l ) {
+ n = rImg.aSource.SearchAscii( "\n", n );
+ if( n == STRING_NOTFOUND ) break;
+ else n++;
+ }
+ // Stelle anzeigen
+ if( n != STRING_NOTFOUND )
+ {
+ USHORT n2 = rImg.aSource.SearchAscii( "\n", n );
+ if( n2 == STRING_NOTFOUND ) n2 = rImg.aSource.Len() - n;
+ String s( rImg.aSource.Copy( n, n2 - n + 1 ) );
+ BOOL bDone;
+ do {
+ bDone = TRUE;
+ n = s.Search( '\r' );
+ if( n != STRING_NOTFOUND ) bDone = FALSE, s.Erase( n, 1 );
+ n = s.Search( '\n' );
+ if( n != STRING_NOTFOUND ) bDone = FALSE, s.Erase( n, 1 );
+ } while( !bDone );
+// sprintf( cBuf, pMask[ 0 ], nPC );
+// rText += cBuf;
+ rText.AppendAscii( "; " );
+ rText += s;
+ rText.AppendAscii( _crlf() );
+ }
+ }
+ // Label?
+ const char* p = "";
+ if( cLabels[ nPC >> 3 ] & ( 1 << ( nPC & 7 ) ) )
+ {
+ // Public?
+ ByteString aByteMethName;
+ for( USHORT i = 0; i < pMod->GetMethods()->Count(); i++ )
+ {
+ SbMethod* pMeth = PTR_CAST(SbMethod,pMod->GetMethods()->Get( i ));
+ if( pMeth )
+ {
+ aByteMethName = ByteString( pMeth->GetName(), gsl_getSystemTextEncoding() );
+ if( pMeth->GetId() == nPC )
+ {
+ p = aByteMethName.GetBuffer();
+ break;
+ }
+ if( pMeth->GetId() >= nPC )
+ break;
+ }
+ }
+ sprintf( cBuf, pMask[ 0 ], nPC );
+ rText.AppendAscii( cBuf );
+ if( p && *p )
+ {
+ rText.AppendAscii( p );
+ }
+ else
+ {
+ sprintf( cBuf, "Lbl%04X", nPC );
+ rText.AppendAscii( cBuf );
+ }
+ rText += ':';
+ rText.AppendAscii( _crlf() );
+ }
+ sprintf( cBuf, pMask[ nParts ], nPC, (USHORT) eOp, nOp1, nOp2 );
+ rText.AppendAscii( cBuf );
+ short n = eOp;
+ if( eOp >= SbOP2_START )
+ n -= SbOP2_START;
+ else if( eOp >= SbOP1_START )
+ n -= SbOP1_START;
+ rText += '\t';
+ rText.AppendAscii( pOps[ nParts-1 ][ n ] );
+ rText += '\t';
+ switch( nParts )
+ {
+ case 2: (this->*( pOperand2[ n ] ) )( rText ); break;
+ case 3: (this->*( pOperand3[ n ] ) )( rText ); break;
+ }
+ return TRUE;
+}
+#ifdef HP9000
+#undef pMask
+#endif
+
+
+// Auslesen aus StringPool
+
+void SbiDisas::StrOp( String& rText )
+{
+ String aStr = rImg.GetString( nOp1 );
+ const char* p = ByteString( aStr, gsl_getSystemTextEncoding() ).GetBuffer();
+ if( p )
+ {
+ rText += '"';
+ rText.AppendAscii( p );
+ rText += '"';
+ }
+ else
+ {
+ rText.AppendAscii( "?String? " );
+ rText += nOp1;
+ }
+}
+
+void SbiDisas::Str2Op( String& rText )
+{
+ StrOp( rText );
+ rText += ',';
+ String s;
+ nOp1 = nOp2;
+ StrOp( s );
+ rText += s;
+}
+
+// Immediate Operand
+
+void SbiDisas::ImmOp( String& rText )
+{
+ rText += nOp1;
+}
+
+// OnGoto Operand
+
+void SbiDisas::OnOp( String& rText )
+{
+ rText += nOp1 & 0x7FFF;
+ if( nOp1 & 0x800 )
+ rText.AppendAscii( "\t; Gosub" );
+}
+
+// Label
+
+void SbiDisas::LblOp( String& rText )
+{
+ char cBuf[ 10 ];
+ sprintf( cBuf, "Lbl%04X", nOp1 );
+ rText.AppendAscii( cBuf );
+}
+
+// 0 oder Label
+
+void SbiDisas::ReturnOp( String& rText )
+{
+ if( nOp1 )
+ LblOp( rText );
+}
+
+// 0, 1 oder Label
+
+void SbiDisas::ResumeOp( String& rText )
+{
+ switch( nOp1 )
+ {
+ case 1: rText.AppendAscii( "NEXT" ); break;
+ case 2: LblOp( rText );
+ }
+}
+
+// Prompt ausgeben
+// FALSE/TRUE
+
+void SbiDisas::PromptOp( String& rText )
+{
+ if( nOp1 )
+ rText.AppendAscii( "\"? \"" );
+}
+
+// 0 oder 1
+
+void SbiDisas::CloseOp( String& rText )
+{
+ rText.AppendAscii( nOp1 ? "Channel" : "All" );
+}
+
+// Zeichen ausgeben
+
+void SbiDisas::CharOp( String& rText )
+{
+ const char* p = NULL;
+ switch( nOp1 )
+ {
+ case 7: p = "'\\a'"; break;
+ case 9: p = "'\\t'"; break;
+ case 10: p = "'\\n'"; break;
+ case 12: p = "'\\f'"; break;
+ case 13: p = "'\\r'"; break;
+ }
+ if( p ) rText.AppendAscii( p );
+ else if( nOp1 >= ' ' )
+ rText += '\'',
+ rText += (char) nOp1,
+ rText += '\'';
+ else
+ rText.AppendAscii( "char " ),
+ rText += nOp1;
+}
+
+// Variable ausgeben: String-ID und Typ
+
+void SbiDisas::VarOp( String& rText )
+{
+ rText += rImg.GetString( nOp1 & 0x7FFF );
+ rText.AppendAscii( "\t; " );
+ // Der Typ
+ USHORT n = nOp1;
+ nOp1 = nOp2;
+ TypeOp( rText );
+ if( n & 0x8000 )
+ rText.AppendAscii( ", Args" );
+}
+
+// Variable definieren: String-ID und Typ
+
+void SbiDisas::VarDefOp( String& rText )
+{
+ rText += rImg.GetString( nOp1 );
+ rText.AppendAscii( "\t; " );
+ // Der Typ
+ USHORT n = nOp1;
+ nOp1 = nOp2;
+ TypeOp( rText );
+}
+
+// Variable ausgeben: Offset und Typ
+
+void SbiDisas::OffOp( String& rText )
+{
+ rText += ( nOp1 & 0x7FFF );
+ rText.AppendAscii( "\t; " );
+ // Der Typ
+ USHORT n = nOp1;
+ nOp1 = nOp2;
+ TypeOp( rText );
+ if( n & 0x8000 )
+ rText.AppendAscii( ", Args" );
+}
+
+// Datentyp
+#ifdef HP9000
+static char* SbiDisas_TypeOp_pTypes[13] = {
+ "Empty","Null","Integer","Long","Single","Double",
+ "Currency","Date","String","Object","Error","Boolean",
+ "Variant" };
+#define pTypes SbiDisas_TypeOp_pTypes
+#endif
+void SbiDisas::TypeOp( String& rText )
+{
+ // AB 19.1.96: Typ kann Flag fr BYVAL enthalten (StepARGTYP)
+ if( nOp1 & 0x8000 )
+ {
+ nOp1 &= 0x7FFF; // Flag wegfiltern
+ rText.AppendAscii( "BYVAL " );
+ }
+ if( nOp1 < 13 )
+ {
+#ifndef HP9000
+ static char* pTypes[13] = {
+ "Empty","Null","Integer","Long","Single","Double",
+ "Currency","Date","String","Object","Error","Boolean",
+ "Variant" };
+#endif
+ rText.AppendAscii( pTypes[ nOp1 ] );
+ }
+ else
+ {
+ rText.AppendAscii( "type " );
+ rText += nOp1;
+ }
+}
+#ifdef HP9000
+#undef pTypes
+#endif
+
+// TRUE-Label, Bedingungs-Opcode
+
+void SbiDisas::CaseOp( String& rText )
+{
+ LblOp( rText );
+ rText += ',';
+ rText.AppendAscii( pOp1[ nOp2 - SbxEQ + _EQ ] );
+}
+
+// Zeile, Spalte
+
+void SbiDisas::StmntOp( String& rText )
+{
+ rText += nOp1;
+ rText += ',';
+ USHORT nCol = nOp2 & 0xFF;
+ USHORT nFor = nOp2 / 0x100;
+ rText += nCol;
+ rText.AppendAscii( " (For-Level: " );
+ rText += nFor;
+ rText += ')';
+}
+
+// open mode, flags
+
+void SbiDisas::StrmOp( String& rText )
+{
+ char cBuf[ 10 ];
+ sprintf( cBuf, "%04X", nOp1 );
+ rText.AppendAscii( cBuf );
+ if( nOp2 & SBSTRM_INPUT )
+ rText.AppendAscii( ", Input" );
+ if( nOp2 & SBSTRM_OUTPUT )
+ rText.AppendAscii( ", Output" );
+ if( nOp2 & SBSTRM_APPEND )
+ rText.AppendAscii( ", Append" );
+ if( nOp2 & SBSTRM_RANDOM )
+ rText.AppendAscii( ", Random" );
+ if( nOp2 & SBSTRM_BINARY )
+ rText.AppendAscii( ", Binary" );
+}
+
+