Autor Wątek: Tryb gigascreen  (Przeczytany 111027 razy)

Abrimaal

  • *****
  • Wiadomości: 965
  • Miejsce pobytu:
    Lemmingrad
  • Zamulator
    • Games for ULA plus
Odp: Tryb gigascreen
« Odpowiedź #45 dnia: 2012.03.01, 01:04:49 »
Wypróbuję. Docelowo to ma być w assemblerze, w Basic testuję, czy w ogóle działa.

I jeszcze jedno pytanie - czy jest możliwość wywołania w asm instrukcji równoznacznej z PAUSE 1?
Z przerwaniami jest dużo roboty, dlatego pytam o jakiś zastępczy sposób.

Z POKE zamiast OUT też nie działa w trybie 128, nawet z POKE+OUT, tylko w USR 0

A może ktoś ma gotowy kod do przełączania 2 obrazów w trybie 128?
Możliwie jak najprostszy, wszelkie CALL czy JR do czytania klawiatury dopiszę sobie.
« Ostatnia zmiana: 2012.03.01, 02:53:31 wysłana przez Abrimaal »
AY Music, ULA plus.

matofesi

  • *****
  • Wiadomości: 2049
  • Miejsce pobytu:
    Toruń/Poland
Odp: Tryb gigascreen
« Odpowiedź #46 dnia: 2012.03.01, 08:09:41 »
Funkcjonalnym odpowiednikiem (mniej więcej, bo tak na prawdę jest raczej dokładnie odwrotnie ;)) BASICowego PAUSE 1 jest assemblerowe HALT przy założeniu, że mamy włączone przerwania.

Kod przełączający obrazki w assemblerze (zakładając, że są załadowane do właściwych banków pamięci) mógłby wyglądać na przykład tak:

         ld a,16
         ld (bank),a
loop:    halt
         ld a,(bank)
         ld bc,32765
         out (c),a
         xor 8
         ld (bank),a

; tutaj inne operacje...

         jr loop

bank:    defb 0

W związku z tym, że samo ładowanie do poszczególnych stron pamięci nie do końca chce działać tak jakby się tego spodziewać można to rozwiązać inaczej. Najpierw w loaderze załadować obrazki:
10 CLEAR 32767
20 LOAD "" CODE 32768 : REM pierwszy obrazek
30 LOAD "" CODE 32768+6912 : REM drugi obrazek

A po załadowaniu odpalić przerzucanie do właściwych banków w assemblerze:
         ld a,16+5
         ld bc,32765
         out (c),a
         ld hl,32768
         ld de,49152
         ld bc,6912
         ldir

         ld a,16+7
         ld bc,32765
         out (c),a
         ld hl,32768+6912
         ld de,49152
         ld bc,6912
         ldir

I dopiero po tym kawałku wywołać pętlę z pierwszego przykładu do "mrugania" obrazkami.

Pyza^Illusion

  • *****
  • Wiadomości: 586
  • Miejsce pobytu:
    Lubań, dolnośląskie
Odp: Tryb gigascreen
« Odpowiedź #47 dnia: 2012.03.02, 09:33:54 »
Funkcjonalnym odpowiednikiem BASICowego PAUSE 1 jest assemblerowe HALT przy założeniu, że mamy włączone przerwania.

IM2 należałoby dodać. Jeżeli nie będzie owych przerwań a zostanie użyty rozkaz DI (wyłączenie przerwań), a później wystąpi gdzieś HALT, to będzie to równoznaczne ze zwiechą ZX'a (HALT będzie trwał w nieskończoność).

Cytuj
W związku z tym, że samo ładowanie do poszczególnych stron pamięci nie do końca chce działać tak jakby się tego spodziewać [...]

Otóż tutaj mnie zaciekawiłeś, bo nie bardzo sobie mogę wyobrazić co może nie zadziałać. W całym swym dorobku (a były to rzeczy tworzone w głównej mierze pod 128k), nie spotkałem się z jakimkolwiek problemem ładowania bloków do poszczególnych banków. Producenci gier też najpierw ładowali główny blok pamięci, a banki dogrywane były później. Po prostu nie łapię w czym mógłby być problem :)
ZX Spectrum+ (128kB by STAVI), FDD3000, TI-OF-TTL/ZXVGS, Masterface2b, MacFace II, DivIDE plus, Just Speccy 128...

matofesi

  • *****
  • Wiadomości: 2049
  • Miejsce pobytu:
    Toruń/Poland
Odp: Tryb gigascreen
« Odpowiedź #48 dnia: 2012.03.02, 10:35:52 »
Cytuj
Funkcjonalnym odpowiednikiem BASICowego PAUSE 1 jest assemblerowe HALT przy założeniu, że mamy włączone przerwania.

IM2 należałoby dodać. Jeżeli nie będzie owych przerwań a zostanie użyty rozkaz DI (wyłączenie przerwań), a później wystąpi gdzieś HALT, to będzie to równoznaczne ze zwiechą ZX'a (HALT będzie trwał w nieskończoność).

Nie, żeby coś, ale "DI" oznacza wyłączenie przerwać, czyli założenie o którym piszę przestaje być spełnione. Dopóki przerwania są włączone nie ma strategicznego znaczenia czy jest to IM 1 czy IM 2 - HALT zaczeka grzecznie na zakończenie kolejnej procedury obsługi przerwań.

Cytuj

Cytuj
W związku z tym, że samo ładowanie do poszczególnych stron pamięci nie do końca chce działać tak jakby się tego spodziewać [...]

Otóż tutaj mnie zaciekawiłeś, bo nie bardzo sobie mogę wyobrazić co może nie zadziałać. W całym swym dorobku (a były to rzeczy tworzone w głównej mierze pod 128k), nie spotkałem się z jakimkolwiek problemem ładowania bloków do poszczególnych banków. Producenci gier też najpierw ładowali główny blok pamięci, a banki dogrywane były później. Po prostu nie łapię w czym mógłby być problem :)

Szczerze mówiąc nie specjalnie się temu przyglądałem poza tym, że rzuciłem okiem jak w ROM 0 obsługiwana jest zmienna BANK_M. I z tego rzutu okiem wynikło, że ona zasadniczo powinna być traktowana jako "read only", bo zmiany jej wartości niekoniecznie muszą się przekładać na zmiany banków.

Co do ewentualnych problemów - na ile rozumiem konstrukcję bank 7 (o tym w tym wypadku rozmawiamy) jest przez system traktowany w jakiś szczególny sposób. Nie wnikam w jaki. Jak widać w praktyce (vide posty Abrimaala) kod, który działa w USR0 w trybie 128 nie chce działać a zmiana tegoż na - zdawałoby się - zgodny ze 128 też nie powoduje zmiany w działaniu.  Tutaj akurat mam pewne podejrzenie - BANK_M jest zasadniczo czytane wyłącznie przez ROM 0 i procedurę SWAP w zmiennych systemowych. Działający program w BASICu chodzi cały czas (jeśli tylko nie używa rozszerzonego BASICa) w ROM 1 a co za tym idzie nie następują odwołania do ROM 0 ani skoki do SWAP. Prawdopodobnie potrzebny jest jakiś extra trigger, żeby takie przełączenie nastąpiło ale w związku z tym, że zasadniczo nie jest mi to do szczęścia potrzebne stawiam to tylko jako moje gdybanie i teorię ;)

I chętnie dam się "naprostować" np. przy użyciu działającego w trybie 128 odpowiednika mojego kodu s tego postu: http://www.speccy.pl/forum/index.php/topic,78.msg3302.html#msg3302


Pyza^Illusion

  • *****
  • Wiadomości: 586
  • Miejsce pobytu:
    Lubań, dolnośląskie
Odp: Tryb gigascreen
« Odpowiedź #49 dnia: 2012.03.02, 14:48:52 »
Aha, czyli "wątpliwe działanie" odnosi się do trybu BASIC128... Po prostu tego nie wyłapałem. Zawsze robiliśmy to pod USR0.
Kiedyś widziałem jakiś loader do gry, w którym przełączanie banków odbywało się na zasadzie "jak nie jedno, to drugie". Czyli w linii zastosowano i POKE i OUT o tych samych wartościach i faktycznie uruchamiało się niezależnie od tego czy był BASIC48 czy BASIC128 (choć w sumie teraz nie dałbym sobie głowy uciąć, czy faktycznie były to te same wartości czy jednak pomniejszone o 16).

Znalazłem jeszcze takie coś (za http://www.nvg.ntnu.no/sinclair/faq/tech_128.html):
Cytuj
When memory is being paged, interrupts should be disabled and the stack should be in an area which is not going to change. If normal interrupt code is to run, then the system variable at 5B5Ch (23388) must be kept updated with the last value sent to port 7FFDh. It is not possible to read this port.

Wg tego przełączanie banków w trybie BASIC128 ale z poziomu asm wygląda następująco:
     LD      A,(5B5Ch)       ;Previous value of port
     AND     0F8h
     OR      4               ;Select bank 4
     LD      BC,7FFDh
     DI
     LD      (5B5Ch),A
     OUT     (C),A
     EI
« Ostatnia zmiana: 2012.03.02, 14:51:37 wysłana przez Pyza^Illusion »
ZX Spectrum+ (128kB by STAVI), FDD3000, TI-OF-TTL/ZXVGS, Masterface2b, MacFace II, DivIDE plus, Just Speccy 128...

matofesi

  • *****
  • Wiadomości: 2049
  • Miejsce pobytu:
    Toruń/Poland
Odp: Tryb gigascreen
« Odpowiedź #50 dnia: 2012.03.02, 14:56:55 »
No i pięknie. Tylko to nie jest odpowiedź na pytanie "czy się da i jeśli tak to w jaki sposób zrobić to samo w BASICu 128" ;)

Na moje oko się nie da i trzeba się podeprzeć asmem.

Pyza^Illusion

  • *****
  • Wiadomości: 586
  • Miejsce pobytu:
    Lubań, dolnośląskie
Odp: Tryb gigascreen
« Odpowiedź #51 dnia: 2012.03.02, 16:12:33 »
Teoretycznie da się to przetłumaczyć na BASIC. Jedyny problem to wyłączenie i włączenie przerwań. Jak kto uparty, to bierze "Przewodnik po ZX SPECTRUM", z tabelki tłumaczy rozkazy na kod procesora i umieszcza kod w linii DATA odpowiednio obniżając RAMTOP o ilość bajtów w DATA. Pamiętać, że RAMTOP powinien mieć poniżej 49152. No o nie zapomnieć o dopisaniu RET na końcu ;)

Wspomniany listing należałoby nieco zmodyfikować, ale powinno dać to jakiś pozytywny efekt. Sorry, że nie napisałem gotowca, ale za bardzo nie mam teraz czasu.
ZX Spectrum+ (128kB by STAVI), FDD3000, TI-OF-TTL/ZXVGS, Masterface2b, MacFace II, DivIDE plus, Just Speccy 128...

matofesi

  • *****
  • Wiadomości: 2049
  • Miejsce pobytu:
    Toruń/Poland
Odp: Tryb gigascreen
« Odpowiedź #52 dnia: 2012.03.02, 17:05:04 »
I kręcimy się w kółko. Ja mówię, że się nie da, ty że trzeba zrobić w asmie. Ja mówię, że prawdopodobnie bez asma się nie da, ty, że trzeba przetłumaczyć, ustawić, wywołać... czyli zrobić w asmie.

Umówmy się więc, że nie jest wykluczone, że da się zrobić ale nikomu nie chce się próbować więc być może jednak nie da się zrobić ;)

Mnie tam to do szczęścia nie jest potrzebne - to raczej teoretyczne dywagacje.

Pyza^Illusion

  • *****
  • Wiadomości: 586
  • Miejsce pobytu:
    Lubań, dolnośląskie
Odp: Tryb gigascreen
« Odpowiedź #53 dnia: 2012.03.02, 18:23:18 »
Ej no, żadne tam upieranie się przy asmie. Problem rozumiem jako "jak z poziomu BASIC zrobić próbę przełączania ekranów w trybie BASIC128?", a nie "za wszelką cenę napisać to nie używając komend assemblera". Mimo iż faktycznie podpieramy się asmem, to wszystko wykonujemy z poziomu BASIC i mamy jakąś tam BASIC'ową kontrolę nad tym. Nie trzeba dogrywać osobnego pliku z kodem etc. O ile to w ogóle zadziała... Bo tak jak piszesz, ciągle jesteśmy w fazie teoretycznej :D

No i może faktycznie darować sobie mordownię w BASIC128, bo na dobrą sprawę więcej z tym zachodu niż to warte. Tak jak Mat zresztą pisze, raczej nie wykona się tego z poziomu czystego BASIC'a.
A co do pozostaniu na drugim ekranie to zamiast klepać na ślepo tego przydługawego OUT'a, wystarczy dać C (CONTINUE) i przerwać ponownie, za 2-3 razem trafimy ;)
ZX Spectrum+ (128kB by STAVI), FDD3000, TI-OF-TTL/ZXVGS, Masterface2b, MacFace II, DivIDE plus, Just Speccy 128...

matofesi

  • *****
  • Wiadomości: 2049
  • Miejsce pobytu:
    Toruń/Poland
Odp: Tryb gigascreen
« Odpowiedź #54 dnia: 2012.03.02, 18:51:06 »
Ej no, żadne tam upieranie się przy asmie. Problem rozumiem jako "jak z poziomu BASIC zrobić próbę przełączania ekranów w trybie BASIC128?", a nie "za wszelką cenę napisać to nie używając komend assemblera".

No to źle rozumiesz. Problem był jak to zrobić bez używania asma. Jak już mam go używać to cały problem stawiam inaczej i nie ma w ogóle dyskusji.

Cytuj
Mimo iż faktycznie podpieramy się asmem, to wszystko wykonujemy z poziomu BASIC i mamy jakąś tam BASIC'ową kontrolę nad tym. Nie trzeba dogrywać osobnego pliku z kodem etc.

Ale to, że nie dogrywamy nie znaczy, że nie używamy asma.

Cytuj
O ile to w ogóle zadziała... Bo tak jak piszesz, ciągle jesteśmy w fazie teoretycznej :D

Teoria dotyczy tego, że prawdopodobnie nie da się tego zrobić samym BASICem. I tylko tutaj możemy podyskutować. Jak mieszasz w to asma w jakiejkolwiek formie to nie ma o czym dyskutować - da się zrobić.

Cytuj
No i może faktycznie darować sobie mordownię w BASIC128, bo na dobrą sprawę więcej z tym zachodu niż to warte. Tak jak Mat zresztą pisze, raczej nie wykona się tego z poziomu czystego BASIC'a.

A to już jak kto lubi. Mnie tam zasadniczo wszystko jedno - nie będę tego robił ani tak ani tak ani nawet w USR 0.

Cytuj
A co do pozostaniu na drugim ekranie to zamiast klepać na ślepo tego przydługawego OUT'a, wystarczy dać C (CONTINUE) i przerwać ponownie, za 2-3 razem trafimy ;)

I zrób to samo w USR 0 :P

Skończmy lepiej bezproduktywną dyskusję, bo i tak do niczego nas nie doprowadzi.

Abrimaal

  • *****
  • Wiadomości: 965
  • Miejsce pobytu:
    Lemmingrad
  • Zamulator
    • Games for ULA plus
Odp: Tryb gigascreen
« Odpowiedź #55 dnia: 2012.03.02, 23:21:42 »
Spokojnie Panowie, bo już się wszyscy pogubiliśmy.
Chodzi mi o to - jest Spectrum uruchomiony w trybie BASIC 128,
ładuje loader i 2 obrazki do odpowiednich banków.
Później przez kilka sekund ma wyświetlać gigascreen (lub czekać na klawisz)
i wrócić do dalszego programu, niezależnie czy ten program jest w BASIC czy w ASM.

Nie ma takiej możliwości wykonania przed ładowaniem przełączenia na tryb 48,
wywołania gigascreen i powrotu do BASIC 128, bo w obu przypadkach następuje reset
i dalsze instrukcje oraz zawartość pamięci przepadną.

Popróbuję po kolei.
AY Music, ULA plus.

matofesi

  • *****
  • Wiadomości: 2049
  • Miejsce pobytu:
    Toruń/Poland
Odp: Tryb gigascreen
« Odpowiedź #56 dnia: 2012.03.03, 00:23:11 »
No to robisz tak... Najpierw BASIC
10 CLEAR 32767
20 LOAD "player" CODE 39700
30 LOAD "PIC1" CODE 32768
40 LOAD "PIC2" CODE 32768+6912
50 RANDOMIZE USR 39700

A do tego "player" asm
         org 39700
         di
         ld a,16+5
         ld bc,32765
         out (c),a
         ld hl,32768
         ld de,49152
         ld bc,6912
         ldir
         ld a,16+7
         ld bc,32765
         out (c),a
         ld hl,32768+6912
         ld de,49152
         ld bc,6912
         ldir
         ei
loop:    halt
bank:    equ $+1
         ld a,16
         ld bc,32765
         out (c),a
         xor 8
         ld (bank),a
; tutaj ewentualne sprawdzenie klawiatury, licznik itp.
         jr loop

Asseblujesz, zapisujesz loader, player, dwa obrazki. Odpalasz.

W efekcie powinieneś mieć to, o czym piszesz.

Abrimaal

  • *****
  • Wiadomości: 965
  • Miejsce pobytu:
    Lemmingrad
  • Zamulator
    • Games for ULA plus
Odp: Tryb gigascreen
« Odpowiedź #57 dnia: 2012.03.03, 05:21:11 »
Ładowanie obrazków zrobiłem tak jak radziłeś, przez LDIR, to działa dobrze.
We właściwej części kodu nie wiem, co wpisać w (bank), dlatego opuściłem te instrukcje.
a ponadto nie mam assemblera, wszystko tłumaczę na kod i wpisuję w DATA,
dlatego tak długo to u mnie trwa.
Główny kod do przełączania napisałem tak - i nie działa, nie wyświetla drugiego obrazka, już 5 rano i nie wiem dalej, gdzie jest błąd.
loop:    halt
         ld a,16
         ld bc,32765
         out (c),a
         xor 8
        ; tutaj  sprawdzenie klawiatury
         jr loop
Dołączam też plik w BASIC, w DATA na pewno nie ma błędów, bo sprawdzałem w debuggerze, kod jest wpisany ok. Zmieniłem tylko adres umieszczając kod za obrazkami, pod 46592.
Nie wiem jaki jest cel ładowania obrazków w inne miejsce i później przenoszenie za pomocą LDIR, czy nie można w trybie 128 bezpośrednio załadować do banków OUT 32756,16 i OUT 32764,24 i skoczyć do głównej pętli w kodzie?
« Ostatnia zmiana: 2012.03.03, 05:47:30 wysłana przez Abrimaal »
AY Music, ULA plus.

matofesi

  • *****
  • Wiadomości: 2049
  • Miejsce pobytu:
    Toruń/Poland
Odp: Tryb gigascreen
« Odpowiedź #58 dnia: 2012.03.03, 17:00:58 »
No dobra... jeśli nie używasz assemblera, to możesz to zrobić tak (będzie prościej ;))
         ei
loop:    halt
         ld a,16
         ld bc,32765
         out (c),a
         halt
         ld a,8+16
         out (c),a
; tutaj extra kod
         jr loop

W twojej modyfikacji mojego kodu błąd był tu:
loop:    halt
         ld a,16  ; <--- tu ustawiasz pierwszy ekran
         ld bc,32765
         out (c),a
         xor 8  ; <--- tu zmieniasz na drugi
        ; tutaj  sprawdzenie klawiatury
         jr loop  ; <--- a to skaczesz do "loop", które wykonuje HALT a potem z powrotem ustawia pierwszy ekran

Zakładając, że puszczasz pętlę nieskończoną kod powinien wyglądać tak:

         ld a,16  ; <--- tu ustawiasz pierwszy ekran
loop:    halt
         ld bc,32765
         out (c),a
         xor 8  ; <--- tu zmieniasz na drugi
         jr loop  ; <--- a tu skaczesz do "loop", w którym już nie ustawiasz na sztywno ekranu

Problem w tym, że w ten sposób nie bardzo możesz dodać jakiś extra kod w pętli. Żeby było lepiej można to poprawić tak:

         ld a,16
loop:    halt
         ld bc,32765
         out (c),a
         xor 8
         push af
         ; tutaj extra kod - sprawdzanie klawiszy etc.
         ; af jest na stosie a w nim następny ekran do wyświetlenia
         pop af
         jr loop
exit:    pop af ; jeśli wciśnięcie klawisza wyskoczy z pętli musisz zdjąć AF ze stosu
         ; koniec - ewentualny extra kod na zakończenie

A w pierwszym przykładzie ten "bank", z którym nie wiedziałeś co zrobić to po prostu zmienna w samomodyfikującym kodzie. Zakładając, że kod siedzi pod adresem 40000 wygląda to tak:

40000          ei
40001 loop:    halt
      bank:    equ 40003
40002         ld a,16
40004         ld bc,32765
40007         out (c),a
40009         xor 8
40011         ld (bank),a
^^^^ to tak na prawdę...
40011         ld (40003),a ; zapamiętuje nowy bank wprost w instrukcji ld a,N

Pyza^Illusion

  • *****
  • Wiadomości: 586
  • Miejsce pobytu:
    Lubań, dolnośląskie
Odp: Tryb gigascreen
« Odpowiedź #59 dnia: 2012.03.03, 17:55:18 »
We właściwej części kodu nie wiem, co wpisać w (bank), dlatego opuściłem te instrukcje.
a ponadto nie mam assemblera, wszystko tłumaczę na kod i wpisuję w DATA

Owa instrukcja EQU to polecenie programu-assemblera (nie assemblera w znaczeniu języka programowania) i służy do zabezpieczenia pewnej wartości bajtów w miejscu kodu, czyli miejsce na przechowywanie zmiennych. Jeżeli nie używasz programu assemblera to wstaw tam dwa NOPy.

Cytuj
Nie wiem jaki jest cel ładowania obrazków w inne miejsce i później przenoszenie za pomocą LDIR, czy nie można w trybie 128 bezpośrednio załadować do banków OUT 32756,16 i OUT 32764,24 i skoczyć do głównej pętli w kodzie?

BASIC 128 ma jakieś dziwne właściwości i faktycznie przełączanie banków jest tam trochę zagmatwane. Pisaliśmy również, że pod BASIC 128 instrukcje przełączania przez OUT nie działają. Trzeba używać trybu USR0 (Basic48 z włączonymi bankami i 2 ekranami ze 128k).

Otóż od początku...
BASIC 128 jest bardzo rzadko stosowany. Większość programów do niczego go nie potrzebuje, a wręcz mechanizmy ROM0 uniemożliwiają swobodne zarządzanie bankami z poziomu BASIC a to ze względu na zarządzanie RAMDYSK'iem. Dlatego najczęściej stosowany jest ROM1 (po USR0), czyli "stary" BASIC, w którym wszystkie właściwości 128k zostają zachowane. Jeżeli program używa BASIC tylko do załadowania danych, a cała reszta odbywa się z poziomu kodu asemblera to nie widzę sensu stosowania tego od 128.

Twój listing nie zawiera instrukcji POKE 23388.x, która to w BASIC 128 służy do przełączania banków dlatego nie będzie to hulało :)

Jeszcze znalazłem coś takiego, co sam kiedyś napisałem (posiłkując się ofkors dostępną mi wtedy dokumentacją): http://yarek.com/forum/index.php?topic=66.0 - może się przydać...

W załączniku snapshocik w formacie .Z80 z poprawną i działającą wersją tego programu (nie pójdzie z kolei na BASIC48) :D

ps. ups... widzę, że w międzyczasie Mat już chyba rozwiązał problem. No nic...
« Ostatnia zmiana: 2012.03.03, 17:57:34 wysłana przez Pyza^Illusion »
ZX Spectrum+ (128kB by STAVI), FDD3000, TI-OF-TTL/ZXVGS, Masterface2b, MacFace II, DivIDE plus, Just Speccy 128...