Konrad-GM Opublikowano 24 Maja 2014 Udostępnij Opublikowano 24 Maja 2014 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 Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Konrad-GM Opublikowano 25 Maja 2014 Autor Udostępnij Opublikowano 25 Maja 2014 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. Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Rekomendowane odpowiedzi
Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto
Jedynie 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ę poniżej.
Zaloguj się