Skocz do zawartości
Konrad-GM

[ASM,6502,NES-CC65] Pętla i adres wewnątrz rejestrów

Rekomendowane odpowiedzi

Cześć i czołem bracia i rodacy,

 

mam do was pytanie moi mili, otóż prosiłbym by ktoś kto zna ASM mógł mi wytłumaczyć parę spraw. Otóż chodzi o adres (wskaźnik) jaki otrzymuje funkcja w ASM wywoływana z poziomu kodu C.

 

Nie jest to "zwykły" ASM pod procesory x86, tylko zająłem się dość "starą" technologią NES z procesorem MOS 6502. Różnice to oczywiście rejestry i 8bitowa pamięć. Korzystam z kompilatora CC65 pod Win8. W języku C mam zamiar zawrzeć logikę gry, zaś w ASM wszystkie pozostałe rzeczy jak zarządzanie kontrolerami, dźwiękiem (APU) czy grafiką (PPU). Do rzeczy:

 

W celu wywołania funkcji napisanej w ASM korzystam z trywialnego kodu:

void __fastcall__ pal_fill(const byte *data); // import
pal_fill(palPaleta); // wywolanie

Dla optymalizacji, poprzez __fastcall__ ładuje wskaźnik *data do rejestru. Jednakże z racji iż jest to 8bitowy procesor, a wskaźnik 16bitowy, rozkładany jest na partie 8bitowe w rejestrach tj. A i X.

 

Teraz problem pojawia się iż chciałbym wczytać zawartość znajdującą pod wskaźnikiem, jednak nie mam za bardzo pojęcia jak się za to zabrać. Co prawda kompilator C przekształca źródła z C na plik ASM, jednak jest to mało optymalizowane i wygląda jak śmietnik.

 

Pętla w ASM:

_pal_fill:
  LDY $2002; reset PPU states
  LDY #$F3
  STY $2006; hi-byte of $[3F]00 - PPU seek address
  LDY #$00
  STY $2006; low-byte of $3F[00] - PPU seek address

  LDX #$00; start indeXing from 0
@1:
;??? LDY A, X; load colour from address A + X into Y reg !!! tutaj następouje "syntax error", jak wspomniałem, rejestry są 8 bitowe
;??? STY $2007; put colour from Y reg into PPU pallete
  INX; X = X + 1
  CPX #$10; if X == 16
  BNE @1; above cmp is true -> continue
  RTS; return to C

 

Zastanawiam się czy nie należy tutaj użyć "stack"a, (sp), coś a'la:

STA (sp)
STX (sp)+1
...
LDY (sp), X

 

Pozdrawiam,

Konrad

Udostępnij tego posta


Odnośnik do posta
Udostępnij na innych stronach

Jakby kogoś interesowało rozwiązanie:

; void __fastcall__ pal_fill(const byte* colors);
_pal_fill:; A - low-bytes pointer, X - hi-bytes pointer
    STA ptr2  ; store data address into zeropage - 2bytes
    STX ptr2+1
    LDA $2002; hi/low seek reset
    LDA #$3F ; seek PPU address to $[3F]00 - hi-byte
    STA $2006
    LDA #$00 ; seek PPU address to $3F[00] - low-byte
    STA $2006
    LDY #$00 ; start indexing
@1:
    LDA (ptr2), Y; read data
    STA $2007
    INY
    CPY #$10
    BNE @1; loop limit
    RTS

Argument funkcji pal_fill to wskaźnik 2 bajtowy na dane 1-bajtowe, przy wywoływaniu funkcji zachowany jest w dwóch rejestrach 1-bajtowych - A i X. ptr2 to po prostu adres na pamięć 2-bajtową w sekcji tzw. zeropage. Delkaracja ptr2 znajduje się w pliku ASM zeropage.inc od cc65.

Udostępnij tego posta


Odnośnik do posta
Udostępnij na innych stronach

Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony.

Zarejestruj nowe konto

Załóż nowe konto. To bardzo proste!

Zarejestruj się

Zaloguj się

Posiadasz już konto? Zaloguj się tutaj.

Zaloguj się tutaj

  • Przeglądający   0 użytkowników

    Brak zarejestrowanych użytkowników, przeglądających tę stronę.

×