STA ($ll), Y
Aus C64-Wiki
Zur Navigation springenZur Suche springen
Mnemonic: | STA ($ll), Y | |||
Opcode: | $91 | |||
Operand(en): | $ll | |||
Anzahl der Bytes: | 2 | |||
Befehlsgruppe: | Transfer-Befehl | |||
Adressierung: | indirekt Y-nachindiziert | |||
Beeinflusste Flags im Statusregister: | ||||
keine | ||||
Taktzyklen: | 6 | |||
1 | PC | Lese Opcode, inkrementiere PC | ||
2 | PC | Lese Zeigeradresse, inkrementiere PC | ||
3 | Pointer | R | lese effektive Adresse Low | |
4 | Pointer | R | lese effektive Adresse High, addiere Y zum Lowbyte der effektiven Adresse | |
5 | Adresse + Y* | R | lese von effektiver Adresse, korrigiere Highbyte der effektiven Adresse | |
6 | Adresse + Y | W | schreiben auf effektive Adresse | |
Anmerkung: | Die effektive Adresse wird immer aus der Zeropage gelesen | |||
Anmerkung: | * das Highbyte der effektiven Adresse könnte zu diesem Zeitpunkt ungültig sein |
Der Assembler-Befehl STA ($ll),Y speichert den Wert des Akkumulators in die Speicherzelle jener Adresse, die sich aus der Zeigeradresse (LSB=$ll ; MSB=$ll+1) plus dem Y-Register zusammen setzt.
Man beachte, dass die Adresse selbst in einem Zwei-Byte-Block (Word) innerhalb der Zeropage liegt!
Funktionsprinzip
Bedeutung der Buchstaben im Befehl
STA | STore Accumulator |
Speichere Akkumulator |
Beispiel
; Dieses Programm füllt den gesamten Bildschirm mit Leerzeichen. ; Programmstart mit SYS 49152 ; Hinweis: Der Bildschirmspeicher ist nur 1000 Bytes groß. Im Beispiel ; wird der Einfachheit halber ein Bereich von 1024 Bytes überschrieben. ; Dies hat zur Folge, dass auch die Sprite-Pointer verändert werden. *=$c000 ; Startadresse des Programms SCREENMEM = $fb BLOECKE = $04 ZEICHEN = " " start lda #$00 ; $fc/$fb = $0400 = Bildschirmspeicher sta SCREENMEM lda #$04 sta SCREENMEM+1 ldx #BLOECKE ; 4 Blöcke (4*256 Byte) ldy #$00 lda #ZEICHEN ; Füllzeichen = Leerzeichen schleife sta (SCREENMEM),Y ; in den Bildschirm schreiben iny ; y um 1 erhöhen bne schleife ; wiederhole bis y=0 (256 Durchläufe) inc SCREENMEM+1 ; nächster Block des Bildschirmspeichers dex ; Blockschleifenzähler um 1 vermindern bne schleife ; wiederhole bis Blockschleifenzähler=0 rts ; Rücksprung zu BASIC
Speicherauszug:
.c000 a9 00 lda #$00 .c002 85 fb sta $fb .c004 a9 04 lda #$04 .c006 85 fc sta $fc .c008 a2 04 ldx #$04 .c00a a0 00 ldy #$00 .c00c a9 20 lda #$20 .c00e 91 fb sta ($fb),y .c010 c8 iny .c011 d0 fb bne $c00e .c013 e6 fc inc $fc .c015 ca dex .c016 d0 f6 bne $c00e .c018 60 rts
Alternative Implementierung
; Wenn man den Speicherbereich umgekehrt, also von oben nach ; unten, befüllt, kann das Y-Register auch als Low-Byte eines ; Zählers verwendet werden. Dadurch ist mit wenig Zusatzaufwand ; ein byte-genaues Befüllen möglich. *=$c000 ; Startadresse des Programms SCRNPNTR = $fb ; Zeropage-Pointer STARTSCREEN = $0400 ; Beginn Bildschirmspeicher LEN = 1000 ; Länge des Bildschirmspeichers ZEICHEN = " " ; Füllzeichen start: lda #<STARTSCREEN ; Low-Byte der Bildschirmspeicheradresse sta SCRNPNTR ; in Pointer schreiben clc ; Addition vorbereiten lda #>STARTSCREEN ; auf High-Byte der Bildschirmspeicheradresse adc #>(LEN-1) ; das High-Byte der Bereichsgröße - 1 addieren sta SCRNPNTR+1 ; und in das High-Byte des Pointers schreiben ldy #<(LEN-1) ; das Low-Byte der Bereichgröße - 1 in das Y-Register laden ldx #(>(LEN-1))+1 ; das High-Byte der Bereichsgröße - 1 um 1 erhöht laden lda #ZEICHEN ; Füllzeichen in den Akkumulator - sta (SCRNPNTR),y ; Zeichen in den Bildschirm schreiben dey ; y um 1 dekrementieren bne - ; wiederhole bis y=0 sta (SCRNPNTR),y ; Zeichen für Index=0 schreiben dey ; y durch dekrementieren auf $FF (255) setzen dec SCRNPNTR+1 ; High-Byte des Pointers dekrementieren dex ; High-Byte des Zählers dekrementieren bne - ; wiederhole bis x=0 rts ; Rücksprung
Speicherauszug:
.c000 A9 00 LDA #$00 .c002 85 FB STA $FB .c004 18 CLC .c005 A9 04 LDA #$04 .c007 69 03 ADC #$03 .c009 85 FC STA $FC .c00b A0 E7 LDY #$E7 .c00d A2 04 LDX #$04 .c00f A9 20 LDA #$20 .c011 91 FB STA ($FB),Y .c013 88 DEY .c014 D0 FB BNE $C011 .c016 91 FB STA ($FB),Y .c018 88 DEY .c019 C6 FC DEC $FC .c01b CA DEX .c01c D0 F3 BNE $C011 .c01e 60 RTS