Autor Wątek: Problem z odczytem joysticka.  (Przeczytany 8216 razy)

pgru

  • *****
  • Wiadomości: 638
Problem z odczytem joysticka.
« dnia: 2018.04.26, 21:15:44 »
W Fuse wszystko działa. Natomiast jak testuję na realnym sprzęcie(Elwro 800 Jr, bez problemu radzi sobie z innymi grami i joystick działa) nie mogę poprawnie odczytać:
pętla zwalniająca -  w trakcie której powinien nastąpić odczyt danych i przerwanie, jeśli następuje ruch postacią:
int petlazwalniajaca(long int n){
long int nk,nl;
int nb;
char klawsz;
nl=1;
/*
for(nk=0;nk<n;nk++)
{nb=nb*(nb+1);
//przerwanie petli zwalniającej w czasie ruchu gracza
if(joystick()!=0) return;
};
*/
for(nk=0;nk<n;nk++)
{
if(joystick()!=0) return;
//scanf("%c",klawsz);
// printf("c %c ",klawsz);
if(klawiatura()==5) printf("kursor w prawo");
};

}

Odczyt joysticka

int joystick(){
/*int k;
int n;
n=0; */
/*
while(1){k=joystickK();
if(k!=n)
{n=k;
printf(" %d ", k);
}}; */
// zwracamy wartości
// zwrotny 1 - przycisk - w Spectrum 16
// zwrotny 2 - góra - w Spectrum 8
// zwrotny 3 - lewo - w Spectrum 2
// zwrotny 4 - dół - w Spectrum 4
// zwrotny 5 - prawo - w Spectrum 1

if (joystickK()==16) return 1;
if (joystickK()==8) return 2;
if (joystickK()==2) return 3;
if (joystickK()==4) return 4;
if (joystickK()==1) return 5;
return 0;

}

Właściwa funkcja w asemblerze odczytująca port:
int __FASTCALL__ joystickK(unsigned p){
//sprawdza i zwraca wartość w 0x1f - interfejs joysticka od Atari - Kempston

#asm
// sprawdzenie 0x1f, dziesiętnie 31, jest to port więc korzystamy z in   
    ld a,$00
    in a,(31)
    //żeby zwrócić wartość trzeba ją umieścić w hl
    //h może być 0 bo a ma mniejszą wartość
    ld h,$00
    //ld hl, a
    ld l,a
ret

#endasm

}
Do kompilacji używam z88dk.

trojacek

  • *****
  • Wiadomości: 6831
  • Miejsce pobytu:
    Warszawa
Odp: Problem z odczytem joysticka.
« Odpowiedź #1 dnia: 2018.04.26, 21:25:24 »
A tak zapytam, po co robisz  ld a,$00 zaraz przed in a,(31)?

W języku C z pętli to się chyba wychodzi przez break, a nie return.

Ogólnie, w Twoim kodzie jest tyle brzydkich rzeczy, że chyba najlepiej, jakbyś sobie odświeżył znajomość języka C z jakiegoś samouczka online.

Przy odczycie joysticka brakuje obsługi skosów oraz fire+kierunek, ale rozumiem, że to uproszczenie w początkowej fazie eksperymentu.
« Ostatnia zmiana: 2018.04.26, 22:00:46 wysłana przez trojacek »

trojacek

  • *****
  • Wiadomości: 6831
  • Miejsce pobytu:
    Warszawa
Odp: Problem z odczytem joysticka.
« Odpowiedź #2 dnia: 2018.04.26, 22:13:46 »
Po mojemu byłoby tak (nie mam jak sprawdzić, czy działa):

int petlazwalniajaca(long int n){

for(int nk=0;nk<n;nk++)
{
  if(joystick()!=0) break;
  if(klawiatura()==5) printf("kursor w prawo");
}

}



int joystick(){

// zwracamy wartości
// zwrotny 1 - przycisk - w Spectrum 16
// zwrotny 2 - góra - w Spectrum 8
// zwrotny 3 - lewo - w Spectrum 2
// zwrotny 4 - dół - w Spectrum 4
// zwrotny 5 - prawo - w Spectrum 1

int retCode = 0;

switch(joystickK()) {
  case 16: retCode = 1; break;
  case 8: retCode = 2; break;
  case 2: retCode = 3; break;
  case 4: retCode = 4; break;
  case 1: retCode= 5; break;
  default: retCode = 0;
}
return retCode;

}


int __FASTCALL__ joystickK(unsigned p){
//sprawdza i zwraca wartość w 0x1f - interfejs joysticka od Atari - Kempston

#asm
// sprawdzenie 0x1f, dziesiętnie 31, jest to port więc korzystamy z in   
    xor a
    ld h, a
    in a,(31)
    ld l,a
    ret

#endasm

}


Pewnie można to zrobić lepiej :)

Tygrys

  • Administrator
  • *****
  • Wiadomości: 4537
  • Miejsce pobytu:
    Warszawa
  • mistrz ceremonii
Odp: Problem z odczytem joysticka.
« Odpowiedź #3 dnia: 2018.04.27, 10:08:34 »
Poniższy przykład jest zły, dlatego że działa tylko i wyłącznie wtedy, kiedy naciśnięty jest jedynie jeden kierunek  lub fire. W przeciwnym razie procedura nie wykryje kompletnie nic.

Zamiast liczb 1...5 należy użyć chociażby operacji na bitach jako zwracany stan 'manipulatora'.

Cytuj
{
  retCode = 0;
  if (kierunek & bit_kontrolera_lewo) retCode |= BIT_STEROWANIA_LEWO;
  if (kierunek & bit_kontrolera_lewo) retCode |= BIT_STEROWANIA_PRAWO;

  itp...

  return retCode;
}

gdzie bit_kontrolera_lewo to wartość jaka pojawia się kiedy zostanie naciśnięty kierunek,
zaś BIT_STEROWANIE_LEWO to nasza lokalna definicja kierunków.

RafalM

  • *****
  • Wiadomości: 1133
  • Miejsce pobytu:
    Sulejówek
Odp: Problem z odczytem joysticka.
« Odpowiedź #4 dnia: 2018.04.27, 10:49:13 »
Ja u siebie zawsze robię tak i mi działa ;)

LD BC,31
IN A,(C)


Z tego co kojarzę to IN A,(C) to tak naprawdę IN A, (BC) - czytamy z portu który ma tak naprawdę szesnastobitowy adres.

A jeśli robimy IN A,(31) to też jakbyśmy robili IN A,(BC) gdzie C=31 a B jest cóż, takie jak w danej chwili B czyli w ogólnym przypadku losowe.

Tutaj znalezłem link gdzie o tym trochę jest, to jest trochę bardziej skomplikowane:
https://electronics.stackexchange.com/questions/92466/confused-about-in-out-architecture-of-z80-chip

Co do czytania kierunków to tak naprawdę wszystko zależy od tego co chcemy osiągnąć w grze czy innym programie. Czy poruszamy się po skosach czy nie? Co ma się stać jeśli człowiek wciśnie lewo i prawo naraz? Ale zgodzę się że najlepiej jest testować bity i zależnie od ich kombinacji wykonywać określone akcje.


pear

  • *****
  • Wiadomości: 5509
  • Miejsce pobytu:
    Będzin
  • Z80 only
Odp: Problem z odczytem joysticka.
« Odpowiedź #5 dnia: 2018.04.27, 10:56:49 »
A jeśli robimy IN A,(31) to też jakbyśmy robili IN A,(BC) gdzie C=31 a B jest cóż, takie jak w danej chwili B czyli w ogólnym przypadku losowe.
W IN A,(n) dolna połówka adresu to n, a górna to aktualna zawartość A.
Jeśli interfejsy dekodują tylko dolne 8 bitów, to zerowanie akumulatora można pominąć.
W innym przypadku jest to jak najbardziej prawidłowe działanie.
ZX/Enterprise/CPC/Robotron/C128D

RafalM

  • *****
  • Wiadomości: 1133
  • Miejsce pobytu:
    Sulejówek
Odp: Problem z odczytem joysticka.
« Odpowiedź #6 dnia: 2018.04.27, 11:47:45 »
Dzięki Pear. Człowiek uczy się całe życie ;)

Może jeszcze mógłbyś potwierdzić albo zaprzeczyć czy joystick Kempston sprawdza górny bajt adresu?

( podejrzewam że to może być rózne zaimplementowane w róznych emulatorach stąd u Pgru rozjechały
 się emulacja i rzeczywisty sprzęt)

pear

  • *****
  • Wiadomości: 5509
  • Miejsce pobytu:
    Będzin
  • Z80 only
Odp: Problem z odczytem joysticka.
« Odpowiedź #7 dnia: 2018.04.27, 11:58:30 »
Kempston w większości wykonań dekoduje tylko bit A5.
Inną sprawą jest czy w systemie znajdują się inne interfejsy, dla których istotne jest pełne adresowanie.
ZX/Enterprise/CPC/Robotron/C128D

pgru

  • *****
  • Wiadomości: 638
Odp: Problem z odczytem joysticka.
« Odpowiedź #8 dnia: 2018.04.27, 12:00:45 »
- Zasadniczo do tej gry są potrzebne 2 kierunki i przycisk. Dolnego używam tylko do sprawdzania punktów, dla tych graczy którzy chcą wiedzieć ile zdobyli.
- Ładowanie akumulatora 0 to taka kiepska(z mojej strony) próba naprawy sytuacji - nie wiedziałem czy nie pojawiały się tam jakieś losowe wartości :-(

Tygrys

  • Administrator
  • *****
  • Wiadomości: 4537
  • Miejsce pobytu:
    Warszawa
  • mistrz ceremonii
Odp: Problem z odczytem joysticka.
« Odpowiedź #9 dnia: 2018.04.27, 12:01:29 »
aby sprawdzić jak w Juniorze (i nie tylko) odczytywana jest wartość z portu, wystarczy odpalić prosty program:


Cytuj
10 PRINT AT 0,0;IN 31;"      "
20 GO TO 20

on powie dlaczego działa pod emulatorem, a dlaczego może nie działać na J.

pgru

  • *****
  • Wiadomości: 638
Odp: Problem z odczytem joysticka.
« Odpowiedź #10 dnia: 2018.04.27, 13:17:59 »
Wartości dzięki programowi Tygrysa(dziękuję):
- brak ruchu - 64
- prawo - 65
- dół - 68
- lewo - 66
- góra - 72

z przyciskiem
- brak ruchu - 80
- prawo - 81
- dół - 84
- lewo - 82
- góra - 88

co by miało sens bo wg. książki o CP/J manipulator jest podłączony do linii portu A układu transmisji równoległej MCY 7855

Trzeba było to robić na bitach, ale spróbuję poprawić na razie prowizorycznie program :-)

trojacek

  • *****
  • Wiadomości: 6831
  • Miejsce pobytu:
    Warszawa
Odp: Problem z odczytem joysticka.
« Odpowiedź #11 dnia: 2018.04.27, 13:28:42 »
W asemblerze, po "in a, (31)" dodaj "and 1fh".

pgru

  • *****
  • Wiadomości: 638
Odp: Problem z odczytem joysticka.
« Odpowiedź #12 dnia: 2018.04.27, 13:49:07 »
Na szybko poprawiłem i działa. Zmieniłem też instrukcję wychodzenia z pętli. Dziękuję Wszystkim za odpowiedzi.

Zaraz sprawdzę to z dodawaniem do asemblera - bo jak rozumiem(nie wiem czy dobrze) ta instrukcja z and powinna obciąć różne inne wartości z różnych interfejsów?

matofesi

  • *****
  • Wiadomości: 2048
  • Miejsce pobytu:
    Toruń/Poland
Odp: Problem z odczytem joysticka.
« Odpowiedź #13 dnia: 2018.04.27, 13:57:02 »
@pgru nie. To, że w stanie "idle" dostajesz 64 oznacza, że twój interface joysticka po prostu wystawia na szóstym bicie (liczone od zera) na stałe jedynkę (być może jest to jakiś znacznik, który pozwala odczytać coś specyficznego a być może po prostu błąd konstrukcyjny interface'u) - "and 1fh" z pobranego bajtu po prostu wyzeruje wszystko powyżej piątego bitu.