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
