Chybné programové řízení MultiJoye

Raster/c.p.u. 2006

Možná někteří pamatujete, jak loni na Atariádě 2005 proběhlo klání ve hře Červi2. Chtěli jsme tam poprvé v historii využít plných možností interface Multijoy - tedy 16 současně hrajících hráčů. Protože v AKPV máme jen Multijoy8, požádali jsme -XI-ho, aby na akci přivezl jejich dva kusy stohovatelné verze MultiJoy16/2. Při zprovozňování sice nastaly podivné problémy jejichž příčinu jsme nechápali, ale nakonec to nějak začalo fungovat a mohlo se hrát. Když jsme si tutéž hru Červi2 chtěli zahrát na akci Unconventional v Německu s naším MultiJoyem8, červíci opět zlobili a vůbec neposlouchali. S Robertem Petruželou jsme to pak začali pořádně zkoumat a s překvapením odhalili důvod potíží.

Od počátku výroby našeho prvního MultiJoye8 v roce 1998 uplynulo sice mnoho let, ale popis programového způsobu řízení tohoto interface je popsán v naší dokumentaci nevhodně. Po zvolení požadovaného joysticku zápisem na adresu $D300 (PORTA) musí být totiž před následným čtením jeho stavu z adresy $D300 mnohem větší časová prodleva, než jsme původně předpokládali.

V dokumentaci jsme doporučovali 3x instrukci NOP - tedy prodlevu 6 strojových taktů. Sérií praktických pokusů s různými modely počítačů Atari (800XE, 130XE, Atari s rozšířenou pamětí) a s našimi MultiJoy4 a MultiJoy8 jsme však zjistili, že odezva hardware je daleko pomalejší a prodleva pro získání správných hodnot by měla být minimálně 22 strojových taktů. Zkoušel jsem pak ještě v našem MultiJoyi vyměnit použitý čip MH3205 za modernější 74LS138, ale nijak významně se to neprojevilo.

Rozhodli jsme se proto nově v dokumentaci zveřejněné na webu doporučovat prodlevu minimálně 30 taktů. Ovšem pravděpodobně to závisí také na způsobu technického řešení MultiJoye. Konkrétně naše řešení s jedním integrovaným obvodem demultiplexerem a diodami se při velkém počtu hráčů (např. při propojení s druhým MultiJoyem s dalšími 8 hráči) občas chová "nejistě".

Zvažujeme navrhnout a sestrojit nový MultiJoy se zcela jiným zapojením, zřejmě podobným jako má ten od -XI-ho. (Poznámka: Chtěli jsme to jejich schéma prozkoumat už dávno, ale bohužel ho z -XI-ho marně dolujeme už několik let. ;-)) Nezbývá než doufat, že pak již budou všechny tyto problémy definitivně pryč.

Prozatím tedy doporučení zní: Prodlevu mezi zápisem do registru PORTA a jeho následným čtením dělejte rozhodně minimálně těch 30 taktů, lépe však v rámci možností ještě více (zejména pokud má hra podporovat maximálních 16 hráčů). Ideální je, pokud se vám podaří místo prázdné čekací smyčky tento čas využít něčím produktivním, například vypisováním skóre příslušného hráče nebo jinými operacemi, kterými můžete čtení registru PORTA oddálit co nejvíc (v tom případě je samozřejmě nutné si spočítat takty těchto operací).

Kompletní programové řízení MultiJoye s 30-ti taktovou prodlevou vypadá tedy takto:

;Inicializace
    LDA #0
    STA $D302  ;PACTL
    LDA #$F0   ;4HORNI=OUT,4DOLNI=IN
    STA $D300  ;PORTA
    LDA #60
    STA $D302  ;PACTL

;Čtení požadovaného joysticku
    LDA #N     ;N=číslo joye 0 až 7
               ;(resp.0 až 15 pro MJ16)
    ASL A      ;posun o 4 bity
    ASL A
    ASL A
    ASL A
    STA $D300  ;PORTA
    LDX #$06   ;prodleva 30 taktů před
WAI DEX        ;čtením PORTA kvůli
    BNE WAI    ;zpoždění hardware
    LDA $D300  ;PORTA
    AND #$0F
;Teď je v A stav páky
    LDA $D010  ;TRIG0
;Teď je v A stav tlačítka

Pokud vám vrtá hlavou, jakto že jsme tuto zásadní věc neodhalili již před lety při hraní první prototypové hry Červi nebo u druhé hry Multris, vysvětlení je jednoduché. Hra Červi i Multris totiž prováděly po zápisu do $D300 právě ještě jiné akce a čtení stavu následovalo až daleko později, takže u nich byla tehdy nevhodně doporučená prodleva překročena mnohonásobně a k žádným potížím proto u nich nedochází. Až ve hře Červi2 jsem prvně použil opravdu jen ty 3 NOPy (6 taktů) a bylo vymalováno.