gt: 		+ "XPSET_A:\n" );
context: /*
   * (c) 2012-2016 Jens Mueller
   *
   * Kleincomputer-Emulator
   *
   * LLC2-spezifische Code-Erzeugung des BASIC-Compilers
   * mit Ansteuerung der HIRES-Vollgrafik
   *
   * Fuer den LLC2 wird mit Ausnahme der Grafikbefehle
   * der gleiche Code erzeugt wie fuer SCCH.
   * Aus diesem Grund ist die Klasse von SCCHTaget abgeleitet.
   */
  
  package jkcemu.programming.basic.target;
  
  import java.lang.*;
  import java.util.Set;
  import jkcemu.base.EmuSys;
  import jkcemu.emusys.LLC2;
  import jkcemu.emusys.ac1_llc2.AbstractSCCHSys;
  import jkcemu.programming.basic.AsmCodeBuf;
  import jkcemu.programming.basic.BasicCompiler;
  import jkcemu.programming.basic.BasicLibrary;
  
  
  public class LLC2HIRESTarget extends SCCHTarget
  {
    public static final String BASIC_TARGET_NAME = "TARGET_LLC2";
  
    private boolean needsScreenSizeChar;
    private boolean needsScreenSizePixel;
    private boolean pixUtilAppended;
    private boolean xpsetAppended;
    private boolean xptestAppended;
    private boolean usesScreens;
  
  
    public LLC2HIRESTarget()
    {
      setNamedValue( "GRAPHICSCREEN", 1 );
      setNamedValue( "LASTSCREEN", 1 );
    }
  
  
    @Override
    public void appendBssTo( AsmCodeBuf buf )
    {
      super.appendBssTo( buf );
      if( this.usesScreens ) {
        buf.append( "X_M_SCREEN:\tDS\t1\n" );
      }
    }
  
  
    @Override
    public void appendEtcPastXOutTo( AsmCodeBuf buf )
    {
      if( this.needsScreenSizeChar ) {
        if( this.usesScreens ) {
  	buf.append( "X_HCHR:\tLD\tHL,0020H\n"
  		+ "\tJR\tX_SSZC\n"
  		+ "X_WCHR:\tLD\tHL,0040H\n"
  		+ "X_SSZC:\tLD\tA,(X_M_SCREEN)\n"
  		+ "\tOR\tA\n"
  		+ "\tRET\tZ\n"
  		+ "\tLD\tL,00H\n"
  		+ "\tRET\n" );
        } else {
  	buf.append( "X_HCHR:\tLD\tHL,0020H\n"
  		+ "\tRET\n"
  		+ "X_WCHR:\tLD\tHL,0040H\n"
  		+ "\tRET\n" );
        }
      }
      if( this.needsScreenSizePixel ) {
        if( this.usesScreens ) {
  	buf.append( "X_HPIX:\tLD\tHL,0100H\n"
  		+ "\tJR\tX_SSZP\n"
  		+ "X_WPIX:\tLD\tHL,0200H\n"
  		+ "X_SSZP:\tLD\tA,(X_M_SCREEN)\n"
  		+ "\tDEC\tA\n"
  		+ "\tRET\tZ\n"
  		+ "\tLD\tHL,00H\n"
  		+ "\tRET\n" );
        } else {
  	buf.append( "X_HPIX:\n"
  		+ "X_WPIX:\tLD\tHL,0000H\n"
  		+ "\tRET\n" );
        }
      }
    }
  
  
    @Override
    public void appendPreExitTo( AsmCodeBuf buf )
    {
      if( this.usesScreens ) {
        buf.append( "\tXOR\tA\n"
  		+ "\tOUT\t(0EEH),A\n" );
      }
    }
  
  
    @Override
    public void appendHCharTo( AsmCodeBuf buf )
    {
      buf.append( "\tCALL\tX_HCHR\n" );
      this.needsScreenSizeChar = true;
    }
  
  
    @Override
    public void appendHPixelTo( AsmCodeBuf buf )
    {
      buf.append( "\tCALL\tX_HPIX\n" );
      this.needsScreenSizePixel = true;
    }
  
  
    @Override
    public void appendInitTo( AsmCodeBuf buf )
    {
      super.appendInitTo( buf );
      if( this.usesScreens ) {
        buf.append( "\tXOR\tA\n"
  		+ "\tLD\t(X_M_SCREEN),A\n"
  		+ "\tOUT\t(0EEH),A\n" );
      }
    }
  
  
    @Override
    public void appendSwitchToTextScreenTo( AsmCodeBuf buf )
    {
      if( this.usesScreens ) {
        buf.append( "\tXOR\tA\n"
  		+ "\tOUT\t(0EEH),A\n"
  		+ "\tLD\t(X_M_SCREEN),A\n" );
      }
    }
  
  
    @Override
    public void appendWCharTo( AsmCodeBuf buf )
    {
      buf.append( "\tCALL\tX_WCHR\n" );
      this.needsScreenSizeChar = true;
    }
  
  
    @Override
    public void appendWPixelTo( AsmCodeBuf buf )
    {
      buf.append( "\tCALL\tX_WPIX\n" );
      this.needsScreenSizePixel = true;
    }
  
  
    @Override
    public void appendXClsTo( AsmCodeBuf buf )
    {
      if( this.usesScreens ) {
        buf.append( "XCLS:\tLD\tA,(X_M_SCREEN)\n"
  		+ "\tCP\t01\n"
  		+ "\tJR\tZ,XCLS1\n"
  		+ "\tLD\tA,0CH\n"
  		+ "\tJR\tXOUTCH\n"
  		+ "XCLS1:\tLD\tHL,8000H\n"
  		+ "\tXOR\tA\n"
  		+ "\tLD\tC,40H\n"
  		+ "XCLS2:\tLD\tB,00H\n"
  		+ "XCLS3:\tLD\t(HL),A\n"
  		+ "\tINC\tHL\n"
  		+ "\tDJNZ\tXCLS3\n"
  		+ "\tDEC\tC\n"
  		+ "\tJR\tNZ,XCLS2\n"
  		+ "\tRET\n" );
      } else {
        buf.append( "XCLS:\tLD\tA,0CH\n"
  		+ "\tJR\tXOUTCH\n" );
      }
      appendXOutchTo( buf );
    }
  
  
    /*
     * Zeichnen einer horizontalen Linie
     * Parameter:
     *   BC: Laenge - 1
     *   DE: linke X-Koordinate, nicht kleiner 0
     *   HL: Y-Koordinate
     */
    public void appendXHLineTo( AsmCodeBuf buf, BasicCompiler compiler )
    {
      buf.append( "XHLINE:\tBIT\t7,B\n"
  		+ "\tRET\tNZ\n"
  		+ "\tPUSH\tBC\n"
  		+ "\tCALL\tX_PST\n"
  		+ "\tPOP\tBC\n"
  		+ "\tRET\tC\n"
  		+ "\tLD\tD,00H\n"
  		+ "XHLINE1:\n"
  		+ "\tOR\tD\n"
  		+ "\tLD\tD,A\n"
  		+ "\tSRL\tA\n"
  		+ "\tJR\tNC,XHLINE2\n"
  		+ "\tLD\tA,D\n" );
      if( this.usesX_M_PEN ) {
        buf.append( "\tCALL\tXPSET_A\n" );
      } else {
        buf.append( "\tOR\t(HL)\n"
  		+ "\tLD\t(HL),A\n" );
      }
      buf.append( "\tINC\tHL\n"
  		+ "\tLD\tA,L\n"
  		+ "\tAND\t3FH\n"
  		+ "\tRET\tZ\n"
  		+ "\tLD\tA,80H\n"
  		+ "\tLD\tD,00H\n"
  		+ "XHLINE2:\n"
  		+ "\tDEC\tBC\n"
  		+ "\tBIT\t7,B\n"
  		+ "\tJR\tZ,XHLINE1\n"
  		+ "\tLD\tA,D\n"
  		+ "\tOR\tA\n"
  		+ "\tJR\tNZ,XPSET_A\n"
  		+ "\tRET\n" );
      appendXPSetTo( buf, compiler );
    }
  
  
    /*
     * XPAINT_LEFT:
     *   Fuellen einer Linie ab dem uebergebenen Punkt nach links,
     *   Der Startpunkt selbst wird nicht geprueft
     *   Parameter:
     *     PAINT_M_X:    X-Koordinate Startpunkt
     *     PAINT_M_Y:    Y-Koordinate Startpunkt
     *   Rueckgabe:
     *     (PAINT_M_X1): X-Endkoordinate der gefuellten Linie,
     *                   kleiner oder gleich X-Startpunkt
     *
     * XPAINT_RIGHT:
     *   Fuellen einer Linie ab dem uebergebenen Punkt nach rechts
     *   Parameter:
     *     PAINT_M_X:    X-Koordinate Startpunkt
     *     PAINT_M_Y:    Y-Koordinate Startpunkt
     *   Rueckgabe:
     *     CY=1:         Pixel im Startpunkt bereits gesetzt (gefuellt)
     *                   oder ausserhalb des sichtbaren Bereichs
     *     (PAINT_M_X2): X-Endkoordinate der gefuellten Linie, nur bei CY=0
     */
    @Override
    public void appendXPaintTo( AsmCodeBuf buf, BasicCompiler compiler )
    {
      buf.append( "XPAINT_LEFT:\n"
  		+ "\tLD\tDE,(PAINT_M_X)\n"
  		+ "\tLD\tA,D\n"
  		+ "\tOR\tE\n"
  		+ "\tJR\tZ,XPAINT_LEFT6\n"
  		+ "\tLD\tHL,(PAINT_M_Y)\n"
  		+ "\tDEC\tDE\n"
  		+ "\tPUSH\tDE\n"
  		+ "\tCALL\tX_PST\n"
  		+ "\tPOP\tDE\n"
  		+ "\tJR\tC,XPAINT_LEFT5\n"
  		+ "\tLD\tC,A\n"
  		+ "\tLD\tB,(HL)\n"
  		+ "XPAINT_LEFT1:\n"
  		+ "\tLD\tA,B\n"
  		+ "XPAINT_LEFT2:\n"
  		+ "\tAND\tC\n"
  		+ "\tJR\tNZ,XPAINT_LEFT4\n"
  		+ "\tLD\tA,B\n"
  		+ "\tOR\tC\n"
  		+ "\tLD\tB,A\n"
  		+ "\tDEC\tDE\n"
  		+ "\tSLA\tC\n"
  		+ "\tJR\tNC,XPAINT_LEFT2\n"
  		+ "\tLD\t(HL),B\n"
  		+ "\tDEC\tHL\n"
  		+ "\tBIT\t0,D\n"
  		+ "\tJR\tZ,XPAINT_LEFT3\n"
  		+ "\tLD\tA,E\n"
  		+ "\tINC\tA\n"
  		+ "\tJR\tZ,XPAINT_LEFT5\n"
  		+ "XPAINT_LEFT3:\n"
  		+ "\tLD\tB,(HL)\n"
  		+ "\tLD\tC,01H\n"
  		+ "\tJR\tXPAINT_LEFT1\n"
  		+ "XPAINT_LEFT4:\n"
  		+ "\tLD\t(HL),B\n"
  		+ "XPAINT_LEFT5:\n"
  		+ "\tINC\tDE\n"
  		+ "XPAINT_LEFT6:\n"
  		+ "\tLD\t(PAINT_M_X1),DE\n"
  		+ "\tRET\n"
  		+ "XPAINT_RIGHT:\n"
  		+ "\tLD\tDE,(PAINT_M_X)\n"
  		+ "\tLD\tHL,(PAINT_M_Y)\n"
  		+ "\tPUSH\tDE\n"
  		+ "\tCALL\tX_PST\n"
  		+ "\tPOP\tDE\n"
  		+ "\tRET\tC\n"
  		+ "\tLD\tC,A\n"
  		+ "\tLD\tB,(HL)\n"
  		+ "\tAND\tB\n"
  		+ "\tSCF\n"
  		+ "\tRET\tNZ\n"
  		+ "\tJR\tXPAINT_RIGHT3\n"
  		+ "XPAINT_RIGHT1:\n"
  		+ "\tLD\tA,B\n"
  		+ "XPAINT_RIGHT2:\n"
  		+ "\tAND\tC\n"
  		+ "\tJR\tNZ,XPAINT_RIGHT4\n"
  		+ "XPAINT_RIGHT3:\n"
  		+ "\tLD\tA,B\n"
  		+ "\tOR\tC\n"
  		+ "\tLD\tB,A\n"
  		+ "\tINC\tDE\n"
  		+ "\tSRL\tC\n"
  		+ "\tJR\tNC,XPAINT_RIGHT2\n"
  		+ "\tLD\t(HL),B\n"
  		+ "\tINC\tHL\n"
  		+ "\tLD\tA,D\n"
  		+ "\tAND\t01H\n"
  		+ "\tOR\tE\n"
  		+ "\tJR\tZ,XPAINT_RIGHT5\n"
  		+ "\tLD\tB,(HL)\n"
  		+ "\tLD\tC,80H\n"
  		+ "\tJR\tXPAINT_RIGHT1\n"
  		+ "XPAINT_RIGHT4:\n"
  		+ "\tLD\t(HL),B\n"
  		+ "XPAINT_RIGHT5:\n"
  		+ "\tDEC\tDE\n"
  		+ "\tLD\t(PAINT_M_X2),DE\n"
  		+ "\tOR\tA\n"			// CY=0
  		+ "\tRET\n" );
      appendPixUtilTo( buf, compiler );
    }
  
  
    /*
     * Farbe eines Pixels ermitteln,
     * Die Rueckgabewerte sind identisch zur Funktion XPTEST
     *
     * Parameter:
     *   DE: X-Koordinate (0...255)
     *   HL: Y-Koordinate (0...255)
     * Rueckgabe:
     *   HL >= 0: Farbcode des Pixels
     *   HL=-1:   Pixel exisitiert nicht
     */
    @Override
    public void appendXPointTo( AsmCodeBuf buf, BasicCompiler compiler )
    {
      appendXPTestTo( buf, compiler );
    }
  
  
    /*
     * Zuruecksetzen eines Pixels
     * Parameter:
     *   DE: X-Koordinate
     *   HL: Y-Koordinate
     */
    @Override
    public void appendXPResTo( AsmCodeBuf buf, BasicCompiler compiler )
    {
      buf.append( "XPRES:\tCALL\tX_PST\n"
  		+ "\tRET\tC\n"
  		+ "\tCPL\n"
  		+ "\tAND\t(HL)\n"
  		+ "\tLD\t(HL),A\n"
  		+ "\tRET\n" );
      appendPixUtilTo( buf, compiler );
    }
  
  
    /*
     * Setzen eines Pixels unter Beruecksichtigung des eingestellten Stiftes
     * Parameter:
     *   DE: X-Koordinate
     *   HL: Y-Koordinate
     */
    @Override
    public void appendXPSetTo( AsmCodeBuf buf, BasicCompiler compiler )
    {
      if( !this.xpsetAppended ) {
        buf.append( "XPSET:\tCALL\tX_PST\n"
  		+ "\tRET\tC\n"
  