RETRO KUTAK – tehnologija prošlih decenija

C64 ASEMBLER (C64 ASSEMBLY) – Lekcija 5

Ovaj tekst je deo serijala „C64 ASEMBLER (C64 ASSEMBLY)“ i obrađuje logičke operacije (AND, ORA, EOR), manipulacije bitovima (ASL, LSR, ROL, ROR), instrukciju BIT, bezuslovne skokove (JMP, JSR/RTS) i kontrolne instrukcije procesora (NOP, BRK, SEI, CLI, SEC, CLC, SED, CLD, CLV, RTI) na 6510 procesoru (Commodore 64). Sadrži praktične ASM primere, binarne tabele i BASIC ekvivalente tamo gde postoje. Publika: početnici i srednje napredni korisnici koji žele brz i efikasan kod naspram BASIC-a.

C64 ASEMBLER Lekcija 5

Preslušaj analizu teksta

Dobrodošli u lekciju 5 male škole programiranja u asembleru na Commodore 64. Danas ćemo preći preostale asemblerske naredbe i, kao i obično, dati primere i BASIC ekvivalente.

Napomene, saveti i objašnjenja

Današnja lekcija je vezana za logičke operacije, kao i za manipulacije bitovima u akumulatoru, registrima, memoriji i samom registru procesora. Rad sa asemblerom se najvećim delom svodi na upravljanje vrednostima u memorijskoj mapi računara (grafika, boje, zvuk, ispis, itd.). Dok smo u standardnom BASIC-u često morali da manipulišemo memorijskom mapom uz sporo izvršavanje, sa ASM-om dobijamo maksimalnu brzinu i vrlo mali zauzet prostor — programi u ASM-u su superiorni u pogledu performansi i efikasnosti.

1) Logičke operacije

Logičke operacije rade nad bitovima u akumulatoru (A):

AND — logičko množenje (I)

Tabela istine: (0·0=0, 1·0=0, 0·1=0, 1·1=1). Uticaj na N, V, Z, C bitove statusnog registra.

Formati: AND #m, AND m, AND m,X, AND mm, AND mm,X, AND mm,Y, AND (m,X), AND (m),Y (gde je m adresa na nultoj strani $00–$FF, a mm apsolutna adresa $0000–$FFFF).

ORA — logičko sabiranje (ILI)

Tabela istine: (0+0=0, 1+0=1, 0+1=1, 1+1=1). Uticaj na N, V, Z, C kao i kod AND.

EOR — logičko isključivo sabiranje (XOR)

Tabela istine: (0⊕0=0, 1⊕0=1, 0⊕1=1, 1⊕1=0). Uticaj na N, V, Z, C kao i kod AND.

Primer

* = $1000                 ; početak programa na $1000 (4096)

LDA #%00001111            ; A = $0F (15)
AND #%00110011            ; A = A AND $33 → 00001111 AND 00110011 = 00000011 (3)
STA $02                   ; mem[2] = 3

LDA #%00001111            ; A = $0F (15)
ORA #%00110011            ; A = A OR  $33 → 00001111 OR  00110011 = 00111111 ($3F / 63)
STA $03                   ; mem[3] = 63

LDA #%00001111            ; A = $0F (15)
EOR #%00110011            ; A = A EOR $33 → 00001111 XOR 00110011 = 00111100 ($3C / 60)
STA $04                   ; mem[4] = 60

RTS                       ; povratak u BASIC

U BASIC-u posle kompajliranja i pokretanja (SYS 64738 pa SYS 4096) proverite: PRINT PEEK(2),PEEK(3),PEEK(4)3 63 60.

BASIC ekvivalenti: PRINT a AND b, PRINT a OR b, PRINT EXOR(a,b) (Simon’s BASIC). Argumenti a i b su decimalni brojevi; operacija se radi bitovno nad njihovim binarnim predstavama.

2) Manipulacija, pomeranje i rotacija bitova

BIT — testiranje 6. i 7. bita memorijske lokacije

BIT kopira bit 6 lokacije u V-flag, bit 7 u N-flag, a Z-flag postavlja na osnovu rezultata A AND mem (ako je rezultat nula, Z=1).

Formati: BIT m (zero page), BIT mm (apsolutno).

Primer

* = $1000                 ; start na $1000
LDA #$00                  ; A=0 → kodni broj "@" i početna vrednost
STA $02                   ; mem[2] = 0
LDX #$00                  ; X=0

OPET:
STA $0400,X               ; upiši A (0 = "@") u ekran + X
INX                       ; X = X + 1
INC $02                   ; mem[2]++
BIT $02                   ; testiraj mem[2] (N=bit7, V=bit6, Z na osnovu A AND mem[2])
BPL OPET                  ; dok bit7 nije setovan (N=0), nastavi
RTS                       ; kraj

Na ekranu će se ispisati 128 karaktera „@“. Petlja traje dok se ne postavi 7. bit (bit 7 = 1 ⇒ negativan u dvokomplementnoj interpretaciji).

ASL — aritmetički shift ulevo

Šiftuje sve bitove ulevo; bit 7 ide u C, a bit 0 postaje 0. Tipično za množenje sa 2.

C ← 7 6 5 4 3 2 1 0 ← 0

LSR — aritmetički shift udesno

Šiftuje sve bitove udesno; bit 0 ide u C, a bit 7 postaje 0. Tipično za celobrojno deljenje sa 2.

0 → 7 6 5 4 3 2 1 0 → C

ROL — rotacija ulevo

Rotira ulevo preko C; bit 7 ide u C, prethodni C ulazi u bit 0.

C ← 7 6 5 4 3 2 1 0 ← C

ROR — rotacija udesno

Rotira udesno preko C; bit 0 ide u C, prethodni C ulazi u bit 7.

C → 7 6 5 4 3 2 1 0 → C

Napomena: ove naredbe nemaju direktan BASIC ekvivalent.

Primer

* = $1000

LDA #$02                  ; A=2
ASL A                     ; 00000010 → 00000100 (2×2=4)
ASL A                     ; 00000100 → 00001000 (4×2=8)
ASL A                     ; 00001000 → 00010000 (8×2=16)
STA $02                   ; mem[2] = 16

LDA #$20                  ; A=$20 (32)
LSR A                     ; 00100000 → 00010000 (32/2=16)
LSR A                     ; 00010000 → 00001000 (16/2=8)
STA $03                   ; mem[3] = 8

LDA #$81                  ; A=$81 (129)
CLC                       ; C=0 (obavezno pre ROL/ROR kad želimo kontrolisani unos)
ROL A                     ; C ←10000001← C → 00000010, C=1   (129→2)
ROL A                     ; C ←00000010← C → 00000101, C=0   (2→5)
STA $04                   ; mem[4] = 5

LDA #$50                  ; A=$50 (80)
SEC                       ; C=1 (unesi '1' u bit7 pri ROR)
ROR A                     ; C → 01010000 → C → 10101000 ($A8 / 168), C resetovan
STA $05                   ; mem[5] = 168

RTS

Posle SYS 64738 i SYS 4096, proverite: PRINT PEEK(2),PEEK(3),PEEK(4),PEEK(5)16 8 5 168.

3) Bezuslovni skokovi

JMP — skok na adresu

Ekivalent BASIC naredbi GOTO. Premešta tok na zadatu apsolutnu adresu.

JSR — odlazak na podprogram

Ekvivalent BASIC GOSUB. Poziva podprogram i vraća se na glavni tok preko RTS.

RTS — povratak

Vraća tok programa na naredbu ispod JSR (ili izlazi u BASIC ako je u glavnom toku).

Primer

* = $1000

LDA #$01                  ; bela boja okvira/pozadine
JSR OBOJI                 ; pozovi podprogram

LDA #$02                  ; crvena
JSR OBOJI

LDA #$04                  ; ljubičasta
JSR OBOJI

RTS                       ; izlaz u BASIC

OBOJI:                    ; --- podprogram ---
STA $D020                 ; okvir (53280)
STA $D021                 ; pozadina (53281)

OPET:
LDA $C5                   ; čitanje tastature (197)
CMP #$0A                  ; 'A' taster?
BNE OPET                  ; čekaj dok ne pritisne 'A'

OPET2:
LDA $C5                   ; ponovo čitanje tastature
CMP #$0A
BEQ OPET2                 ; debounce: čekaj dok ne otpusti 'A'

RTS                       ; povratak na glavni tok

Klikom na ‘A’ menjate redom: bela → crvena → ljubičasta. Napomena: prvi loop čeka pritisak, drugi sprečava „protrčavanje“ dok je taster još uvek pritisnut.

4) Naredbe direktne kontrole procesora

  • NOP — ne radi ništa (korisno za usporavanje ili patch-ovanje koda).
  • BRK — softverski prekid (skok na handler prekida, posle povratak na glavni tok).
  • SEI — zabrana IRQ prekida (I=1); korisno kad morate sprečiti prekid.
  • CLI — dozvoli prekide (I=0); vratiti normalan rad sistema.
  • SEC — C=1; obavezno pre SBC ili kad želite C=1 za rotacije.
  • CLC — C=0; obavezno pre ADC ili kad želite C=0 za rotacije.
  • SED — decimalni mod (D=1); napomena: 6510 na C64 podržava decimalni mod.
  • CLD — heksadecimalni/binarni mod (D=0); povratak sa decimalnog.
  • CLV — V=0; reset overflow statusa (korisno posle aritmetike).
  • RTI — povratak iz prekida.

Ove naredbe nemaju direktne BASIC ekvivalente.

5) Predlog formatiranja koda (sa komentarima)

Radi bržeg razumevanja, u ASM primerima koristite poravnate komentare desno od instrukcija, kratke ali informativne. Primer:

* = $1000

LDA #%00001111            ; učitaj $0F (15) u A
AND #%00110011            ; A = A AND $33 → rezultat 3 (00000011)
STA $02                   ; mem[2] = 3

LDA #%00001111            ; A = $0F
ORA #%00110011            ; A = A OR $33 → $3F (63)
STA $03                   ; mem[3] = 63

LDA #%00001111            ; A = $0F
EOR #%00110011            ; A = A XOR $33 → $3C (60)
STA $04                   ; mem[4] = 60
RTS                       ; povratak u BASIC

Za binarne prikaze, zadržite vizuelno poravnanje radi preglednosti:

  00001111
AND   00110011
  =    00000011   ; 3

  00001111
ORA   00110011
  =    00111111   ; 63

  00001111
EOR   00110011
  =    00111100   ; 60

Za rotacije/shiftove uvek eksplicitno pripremite C-bit (CLC/SEC) da bi rezultat bio predvidiv:

LDA #$81                  ; 1000 0001
CLC                       ; C=0 (kontrolisan unos u bit0 pri ROL)
ROL A                     ; C ←10000001← C → 00000010, C=1
ROL A                     ; C ←00000010← C → 00000101, C=0

Zaključak

Sa ovom lekcijom obradili smo ključne logičke i bit-manipulativne instrukcije, kao i bezuslovne skokove i kontrolu procesora. U sledećoj lekciji sledi tabela svih asemblerskih naredbi sa uticajem na statusne bitove procesora.

Vidimo se u asembler lekciji 6. Puno pozdrava!

Оставите одговор

Ваша адреса е-поште неће бити објављена. Неопходна поља су означена *