Autor Wątek: kod 6502 na Z80 (adresowanie bezwgledne indexowane)  (Przeczytany 961 razy)

siudym

  • *
  • Wiadomości: 34
kod 6502 na Z80 (adresowanie bezwgledne indexowane)
« dnia: 2021.10.22, 13:26:24 »
Mam kolejny problem z przepisaniem kodu 6502 na Z80 :)

Pod adresem ram $0300-$06FF (addrLO,addrHI) mam kopię 1-kilobajtowego (1024b) ekranu NES, użyty jest rejestr indexowy Y
aby wyliczyć numer kafelka/tilesa jaki znajduję sie pod wskazanym przez LDA adresie (przykładowo mam tam $20)
Niestety mam problem aby to przepisac na kod Z80, poniewaz nie ma tam rejestrow idexowych dzialajacych na podobnej zasadzie
oraz chyba nie ma takiego typu adresowania bezwglednego ?

Aha i w Z80 adres kopii ekranu wielkosci 1024bajtow bedzie startowac w $C000-$C3FF (zapewne zaladowanie najpierw do    LD HL,$C000 ale co dalej to juz mam problem, bo skopiowanie pewnej tablicy to wiem, ale juz takie skanowanie bajtow nie mam pojecia jak ugryzc)

edit: maly błąd w 6502 uzyte adresowanie "pośredne strony zerowej postindeksowane Y (Indirect zero-page post-indexed Y)"


LDA #$20 ; laduje do aku $20 (przykladowo, bo moze byc wyliczona wczesniej wartosc dodowolna)
TAY ; przenosze akumulator do rejestru indexowego Y
; (adresowania bezwzglednego mozna tylko odczytywac z rejestrem Y nie X)
LDA [addrLO],Y ; odczytuje adres w ram zwiekszony o Y
TAY ; odczytana wartosc leci znowu do rejestru Y
LDA TileBits,Y ; teraz odczytuje jaki TYP kafelka znajduje sie pod tym adresem (bedzie odcztana wartosc stalej Air (00) Solid (01)

; teraz w akumulatorze mam potrzebna wartosc 00 lub 01 bo tylko takie typy kafelkow ustawione sa w stalych

;################################################################################

TileBits: ; tablica 256 bajtów

.db AirTile ;00 ; air tile
.db SolidTile ;01 ; solid tile
.db SolidTile ;02
.db SolidTile ;03
.db SolidTile ;04
.db SolidTile ;05
.db SolidTile ;06
.db SolidTile ;07
.db SolidTile ;08
.db SolidTile ;09
.db SolidTile ;0A
.db SolidTile ;0B
.db SolidTile ;0C
.db SolidTile ;0D
.db SolidTile ;0E
.db SolidTile ;0F

.db AirTile ;10
.db AirTile ;11
.db AirTile ;12
.db AirTile ;13
.db SolidTile ;14
.db SolidTile ;15
.db SolidTile ;16
.db SolidTile ;17
.db SolidTile ;18
.db SolidTile ;19
.db SolidTile ;1A
.db SolidTile ;1B
.db SolidTile ;1C
.db SolidTile ;1D
.db SolidTile ;1E
.db SolidTile ;1F

.db AirTile ;20
.db AirTile ;21
.db AirTile ;22
.db AirTile ;23
.db SolidTile ;24
.db SolidTile ;25
.db SolidTile ;26
.db SolidTile ;27
.db SolidTile ;28
.db SolidTile ;29
.db SolidTile ;2A
.db SolidTile ;2B
.db SolidTile ;2C
.db SolidTile ;2D
.db SolidTile ;2E
.db SolidTile ;2F

(...) etc etc (czyli 30,40,50,60,70,80,90,A0,B0,C0,D0....)

.db SolidTile ;E0
.db SolidTile ;E1
.db SolidTile ;E2
.db SolidTile ;E3
.db SolidTile ;E4
.db SolidTile ;E5
.db SolidTile ;E6
.db SolidTile ;E7
.db SolidTile ;E8
.db SolidTile ;E9
.db SolidTile ;EA
.db SolidTile ;EB
.db SolidTile ;EC
.db SolidTile ;ED
.db SolidTile ;EE
.db SolidTile ;EF

.db SolidTile ;F0
.db SolidTile ;F1
.db SolidTile ;F2
.db SolidTile ;F3
.db SolidTile ;F4
.db SolidTile ;F5
.db SolidTile ;F6
.db SolidTile ;F7
.db SolidTile ;F8
.db SolidTile ;F9
.db SolidTile ;FA
.db SolidTile ;FB
.db SolidTile ;FC
.db SolidTile ;FD
.db SolidTile ;FE
.db SolidTile ;FF ; tile $FF (#255)

;################################################################################

AirTile equ 0 ; stale okreslajace typy tilesow, mozna dodac wiecej
SolidTile equ 1

« Ostatnia zmiana: 2021.10.22, 14:08:39 wysłana przez siudym »

steev

  • *****
  • Wiadomości: 1214
  • Miejsce pobytu:
    inode 42
Odp: kod 6502 na Z80 (adresowanie bezwgledne indexowane)
« Odpowiedź #1 dnia: 2021.10.22, 13:47:59 »
Jedno z wielu możliwych rozwiązań:

indeks equ 3

    org $8000
    ld hl,dane    ; albo ld h,hi(dane)
    ld l,indeks   ; uproszczenie możliwe dzięki align $100 :)

    ld a,(hl)

    ret

    align $100
dane:
    db 0, 1, 2, 3, 4, 5, 6, 7
    db 8, 9,10,11,12,13,14,15
    ; db ...
Machines should work. People should think.

matofesi

  • *****
  • Wiadomości: 1899
  • Miejsce pobytu:
    Toruń/Poland
Odp: kod 6502 na Z80 (adresowanie bezwgledne indexowane)
« Odpowiedź #2 dnia: 2021.10.22, 13:55:28 »
@steev chyba nie... Tam jest jakieś podwójne pobieranie danych - najpierw z tablicy a potem chyba na tej podstawie z TileBits. Czyli jeszcze przed ret'em musiałoby być przeładowanie a do hl i drugi odczyt...

Ale może ja się nie znam. A na pewno nie znam się na 6502 ;)

steev

  • *****
  • Wiadomości: 1214
  • Miejsce pobytu:
    inode 42
Odp: kod 6502 na Z80 (adresowanie bezwgledne indexowane)
« Odpowiedź #3 dnia: 2021.10.22, 14:06:48 »
Owszem, ale zasada jest ta sama.
Jakoś trzeba wziąć adres bazowy tablicy i dodać indeks.
Rozwiązań na to jest w Z80 co najmniej kilka, dałem przykład jednego (i niekoniecznie najlepszego :)
Machines should work. People should think.

siudym

  • *
  • Wiadomości: 34
Odp: kod 6502 na Z80 (adresowanie bezwgledne indexowane)
« Odpowiedź #4 dnia: 2021.10.22, 14:13:43 »
Nawet dobry trop przydatny :)

siudym

  • *
  • Wiadomości: 34
Odp: kod 6502 na Z80 (adresowanie bezwgledne indexowane)
« Odpowiedź #5 dnia: 2021.10.22, 20:43:00 »
Jeszcze mam taki problem - musze dodac do adresu wartosc zmiennej w temp 4x i zrobic to samo w kodzie Z80:

LDY #$04

TileCalc_Loop:

LDA <addrLO ; add the number of rows to the address 4 times
CLC
ADC <temp
STA <addrLO

LDA <addrHI
ADC #0
STA <addrHI

DEY
BNE TileCalc_Loop


dla Z80:


LD HL,$C000
LD A,(temp)

ADD A,L ; A = A+L
LD L,A ; L = A+L
ADC A,H ; A = A+L+H+carry
SUB L ; A = H+carry
LD H,A ; H = H+carry

- nie wiem czy jest poprawnie teraz no i musze zrobic dodanie wartosci ze zmiennej temp do adresu w HL 4x (musi tak byc z pewnych wzgledow)

bo to chyba nie jest poprawnie?

ld a,(temp)
ld hl,$C000
add a,(hl)
add a,(hl)
add a,(hl)
add a,(hl)


trojacek

  • *****
  • Wiadomości: 6191
  • Miejsce pobytu:
    Warszawa
Odp: kod 6502 na Z80 (adresowanie bezwgledne indexowane)
« Odpowiedź #6 dnia: 2021.10.22, 21:13:41 »
Moim zdaniem lepiej (szybciej) jest wartość dodawaną najpierw przemnożyć przez 4, używając przesuwania bitowego.
Pytanie, jaki zakres ma mieć ta "zmienna", bo jak 0..255, to trzeba przesuwać na 16 bitach, by nic nie zgubić.

steev

  • *****
  • Wiadomości: 1214
  • Miejsce pobytu:
    inode 42
Odp: kod 6502 na Z80 (adresowanie bezwgledne indexowane)
« Odpowiedź #7 dnia: 2021.10.22, 21:17:52 »
W sensie, dodajesz wartość zmiennej temp cztery razy do adresu w HL?
Nie bój się 16 bitów.
ld a,(temp)
ld d,0
ld e,a   ; de = (temp)
add hl,de
add hl,de
add hl,de
add hl,de  ; lame, ale proste do złapania
Machines should work. People should think.

siudym

  • *
  • Wiadomości: 34
Odp: kod 6502 na Z80 (adresowanie bezwgledne indexowane)
« Odpowiedź #8 dnia: 2021.10.22, 21:52:24 »
Moim zdaniem lepiej (szybciej) jest wartość dodawaną najpierw przemnożyć przez 4, używając przesuwania bitowego.
Pytanie, jaki zakres ma mieć ta "zmienna", bo jak 0..255, to trzeba przesuwać na 16 bitach, by nic nie zgubić.

Dokladnie, jak przekroczy 255 to zwiekszy wyzszy bajt adresu. Jak w przykladzie 6502 - jak dodawanie przekroczy wartosc bajtu LO to zwiekszy HI o jeden.

W sensie, dodajesz wartość zmiennej temp cztery razy do adresu w HL?
Nie bój się 16 bitów.

Dokładnie, a gdy przekroczy LO zwieksza wyzszy bajt adresu o jeden. No wlasnie ja probuje ogarniac jakos te wyliczenia 16bitowe w Z80 ale na to trzeba czasu.

matofesi

  • *****
  • Wiadomości: 1899
  • Miejsce pobytu:
    Toruń/Poland
Odp: kod 6502 na Z80 (adresowanie bezwgledne indexowane)
« Odpowiedź #9 dnia: 2021.10.22, 22:04:25 »
No wlasnie ja probuje ogarniac jakos te wyliczenia 16bitowe w Z80 ale na to trzeba czasu.

Ja za to podziwiam ludzi robiących na 6502... Jak wy sobie radzicie bez normalnych 16bitowych rejestrów i arytmetyki na nich? To wszystko się nadrabia tymi dziwnymi trybami adresowania i faktem, że w zasadzie wszystkie rozkazy są szybkie jak skurczybyk? ;)

Chyba bym tak nie umiał ;)

siudym

  • *
  • Wiadomości: 34
Odp: kod 6502 na Z80 (adresowanie bezwgledne indexowane)
« Odpowiedź #10 dnia: 2021.10.22, 22:30:27 »
Ja w sumie malo kiedy w swoich grach uzywam 16-bitow :) Moze kilka przypadkow gdy kopiowane sa jakies wieksze tablice :D

ld hl,$C000
ld a,(temp)
ld d,0
ld e,a   ; de = (temp)
add hl,de
add hl,de
add hl,de
add hl,de  ; lame, ale proste do złapania

kurcze nie dziala, cokolwiek zaladuje w temp to pod adresem C000 mam 00


steev

  • *****
  • Wiadomości: 1214
  • Miejsce pobytu:
    inode 42
Odp: kod 6502 na Z80 (adresowanie bezwgledne indexowane)
« Odpowiedź #11 dnia: 2021.10.22, 22:40:37 »
A, jednak się nie dogadaliśmy.
Czy zmienna pod adresem $c000 jest 8 czy 16-bit?
(sugeruję zapisywać problem w pseudokodzie, c, pascalu, basicu... łatwiej dotrze do ludzi nie łapiących 65xx :) )
Machines should work. People should think.

siudym

  • *
  • Wiadomości: 34
Odp: kod 6502 na Z80 (adresowanie bezwgledne indexowane)
« Odpowiedź #12 dnia: 2021.10.22, 22:46:24 »
A, jednak się nie dogadaliśmy.
Czy zmienna pod adresem $c000 jest 8 czy 16-bit?
(sugeruję zapisywać problem w pseudokodzie, c, pascalu, basicu... łatwiej dotrze do ludzi nie łapiących 65xx :) )

EDIT. To ja tez ciala dalem, bo przeciez w taki sposob nie bede mial nic w komorce pamieci C000  :D Mozliwe kod jest ok, tylko jak teraz sprawdzic jaki adres ma w sobie HL? Musze jakos w debbugerze sprawdzic.

EDIT2: Ok wszystko gra, dzieki wielkie. Zapisalem sobie adres HL do innej komorki pamieci aby miec wizualizacje i widze jest ok :) Podglad wartosci rejestru HL takze pokazuje poprawnie wszystko. Sam sie zakrecilem... ;)

ld a,$20                      ;testowo wartosc 20
ld (temp),a

LD HL,$C000
ld a,(temp)
ld d,0
ld e,a   ; de = (temp)
add hl,de
add hl,de
add hl,de
add hl,de

ld ($C020),HL      ; sprawdzilem wynik i bylo w ram zapisane C080 wiec gra, zwiekszenie 8x mialem wynik C100 wiec HI zwiekszone takze
« Ostatnia zmiana: 2021.10.22, 23:10:06 wysłana przez siudym »

siudym

  • *
  • Wiadomości: 34
Odp: kod 6502 na Z80 (adresowanie bezwgledne indexowane)
« Odpowiedź #13 dnia: 2021.10.23, 17:33:08 »
Wracając do pytania z pierwszego postu - chyba powinno być ok, ale nie jest testowane (dzięki Dizzy9 za kod)

LD A,$20
LD D,0
LD E,A ; teraz w de bedzie $20 czyli wartosc jaka znajdować będzie sie na początku w Aku
ADD HL,DE
LD A,(HL)
LD D,E ;wrzucamy a do e, żeby mieć go w zapasie
LD HL,TileBits ;wrzucamy adres tablicy do hl
ADD HL,DE ;uzylismy de bo w d juz mamy zero z poprzedniego działania, oszczędzając cpu i rom
LD A,(HL) ;pobraliśmy bajt z tablicy TileBits

Pytanko jak w WLA-DX zdefiniować podobnie dzialajaca tablice "TileBits" zawierajaca zestaw STAŁYCH?

.define AirTile $00
.define SolidTile $01...
?

TileBits:
.byte AirTile
.byte SolidTile
.byte SolidTile...etc

steev

  • *****
  • Wiadomości: 1214
  • Miejsce pobytu:
    inode 42
Odp: kod 6502 na Z80 (adresowanie bezwgledne indexowane)
« Odpowiedź #14 dnia: 2021.10.23, 18:17:26 »
<mode name="nokia-lumia">

Nie wiem jak w WLA_DX, ale w każdym w miarę normalnym assemblerze :

AirTile         equ $00
SolidTil        equ $01

TileBits:
    db  AirTile,AirTile,AirTile,SolidTil
    db  AirTile,SolidTil,SolidTil,AirTile
    db  AirTile,SolidTil,AirTile,SolidTil
    db  SolidTil,AirTile,AirTile,AirTile
    db  AirTile
    db  AirTile
    db  SolidTil
    db  AirTile
    db  AirTile
    db  SolidTil
    db  SolidTil

A w takim np. ZASM możesz nawet :

#define AirTile $00
#define SolidTile $01


TileBits:
.byte AirTile
.byte SolidTile
.byte SolidTile

</mode>
Machines should work. People should think.