Programování WHDLoad

### Schematic execution flow

Následující tabulka ukazuje, jak pracuje program, když je spusten program nainstalovaný WHDLoadem. Doufám, že to pomůže pochopit, jak WHDLoad pracuje a jak WHDLoad, slave a nainstalovaný program spolupracují.

Uživatel

- spustí demo nebo hru kliknutím na ikonu nebo spuštěním WHDLoad přes příkazovou řádku

Operační systém

- nahraje executable WHDLoadu a spustí ho

WHDLoad

- testuje softwarové a hardwarové prostředí
- nahraje a testuje slave
- zabere požadovanou pameť pro program
- pokud je zapnutPreload/S, nahravá disk image a soubory do RAM dokud je pro ně dostatek volné paměti
- vypíná OS (zastaví mutitasking a přerušení, degraduje grafický hardware na OCS, inicializuje všechen hardware s definovanými hodnotami)
- skočí do kodu slave

Slave

- nahraje hlavní executable nainstalovaného programu voláním WHDLoad funkce (např. resload_DiskLoad or resload_LoadFile)
- patchuje (upraví) hlavní executable (takže program bude nahrávat svá data přes slave, odstraní se problémy s nekompatibilitou, a je umožněn exit z programu)
- skočí do hlavního executable hry nebo dema

Nainstalovaný program

- dělá svou vlastní práci
- při nahrávání dat z disku volá Slave (protože Slave ho předtím tak upravil) a slave volá WHDLoad a WHDLoad částečně zapne OS, aby nahrál data (ale jen pokud data nejsou Preloadnuta), pak se vráti z OS, WHDload, slavu a nainstalovaný program pokračuje dál

Uživatel

- vyskočí z programu pomocí QuitKey

Slave

- vrací se do WHDLoad voláním resload_Abort

WHDLoad

- odblokuje OS (vrátí hodnoty hardware registru, display a paměť)
- uvolní všechny zabrané zdroje
- vrací se do OS

### Jak nainstalovat jednoduchý trackloader jednodisketové hry

Tohle je velmi malý a krátký názorný návod, jak vytvořit instalačku pomocí WHDLoad. Návod ukazuje ideální jednoduchý případ. Ve skutečnosti takový případ ale asi nikdy nestane, takže pro speciální případy a problémy čtěte následující kapitoly.

1. Příprava
   - Vytvořte adresář, který obsahuje všechny soubory
   - Vytvořte disk image pomocí DIC a přesuňte ho do našeho adresáře.
   - Vytvořte ikonu s "WHDLoad" jako <Default Tool> a tooltypem "SLAVE=#?" obsahujícím jméno slave (nebo jednoduše překopírujte ikonu z ukázkových instalací a odstraňte všechny tooltype kromě "SLAVE="
2. Slave
   Pro napsání slave potřebujeme následující informace:
   1. Kde na disku je hlavní executable?
   2. Kde uvnitř hlavního executable je disk loader? (=nahrávací rutina)
   Pro tuhle informaci nejdříve analyzujeme bootblock. Většinou je executable nahraný pomocí funkce exec.DoIO(), někdy je ale v bootblocku speciální trackloader. Napíšeme slave, který simuluje bootblock a nahraje hlavní executable z disk image. Teď vytvoříme memory dump, disassemblujeme ji a poté musíme najít loader. v hlavním executable. Nejrychlejší je hledat hex-editorem řetězec $AAAAAAAA (který je používán pro MFM dekódování) Pak si prohlédnout danou oblast (v rozsahu +/- $1000 bytes) a najít začátek rutiny. Najít parametry. Pak vytvoříme kód pro slave, který upraví loader tak, aby byly všechny skoky na loader přeřízený dovnitř slave. Pak si slave přizpůsobí parametry a s jejich použitím volá WHDLoad funkci resload_DiskLoad.
3. V ideálním případě je instalačka hotová.
   Zbývá už jen udělat pěknou ikonu. Vyripujte WHDLoadem dva obrázky použitím snoop modu a SP nebo freezerem nebo na U.A.E. a stvořte ikonu. Šestnáctibarevná RomIcon paleta je ideální (ale lze ikonu vytvořit i pro víc formátů).

### Možné problémy a zvláštní případy

#### Nestandartní trackloader

Některé programy mají svůj vlastní formát disku. To znamená, že DIC nemůže vytvořit disk image. Pro vytvoření souboru nebo images z takového disku je nezbytné napsat speciální rutinu s použitím RawDIC. Pro více informací čtěte dokumentaci RawDIC.

#### Více disků

Jestliže program používá víc než jednu disketu, slave musí přeřadit přístup k disku na odpovídající disk image soubor. Někdy je to těžké. Některé programy umí použít víc disketových jednotek, takže můžete použít číslo jednotky pro vybrání správného image. Většina programů hledá určité ID na disku, aby je rozpoznala, v tomto případě dchyťte každou zkoušku ID (např. analyzováním nahrávacích parametrů pro loader) a přiřaďte správnou hodnotu. Pak se ID načte ze správného disku a program uzná disk jako správnou vloženou disketu. Pokud je zobrazený požadavek pro vložení disku, odstraňte ho.

#### Ukládání Highscore

Použijte resload_SaveFile k zapsání potřebné oblasti paměti na disk. Jestli chcete, zašifrujte vytvořený soubor, takže lameři ho nebudou schopni editovat. Není dobré zapisovat highscore přímo do disk image (použitím resload_SaveFileOffset), protože pokud se něco špatného přihodí (třeba se program sekne), může se stát, že image se poškodí.

#### Ukládání pozic

To je stejný případ jako u highscore, tady ale mame ulehcenou situaci tím, že hra má pro ukládání pozice vlastní rutinu a parametry.

#### Přístupy k operačnímu systému

V momentě, kdy je slave a instalovaný program vykonáván, neexistuje žádný OS, takže žádný přístup k němu nebude fungovat! Všechny přístupy hry nebo dema k OS musí být odstraněny nebo emulovány. Pokud jich není moc a nemají ve WHDLoad systému význam (napr.exec.Disable() nebo exec.SuperState()) prostě je odstraňte pomocí NOP ($4e71). Pokud má volání OS důležitou funkci (jako exec.DoIO()), napište emulaci do slave. Přístupy k OS jsou detekovány pomocí falešné adresy execbase, nastavené na $f0000001, takže všechny skoky do OS vyvolají chybu "Address Error".
Pokud je jich příliš mnoho, lze použít jedno z KickEmu pluginu ve whdload-dev archivu. Existuje emulace pro Kick 1.3 ('src/sources/whdload/kick13.s') a pro Kick 3.1 ('src/sources/whdload/kick31.s'). Tato balení vyžadují originální kickstart ROM soubor a vytvoří kompletní OS prostředí uvnitř WHDLoad vesmíru. Přečtěte si také přiložená readme v každém archivu.

### Obvyklá problémy kompatibility

#### Odlišné stackframes na každém CPU

Stackframes tvořené CPU přerušeními a vyjímkami se u jednotlivých CPU liší. Na 68000 je stackframe 6 bajtů kromě sběrnicových a adresových chyb. Stackframe obsahuje hodnotu SR na (a7) a hodnotu PC na (2,a7). Na ostatních CPU je minimílní stackframe 8 bajtů a dodatečně obsahuje číslo vektoru jako word na (6,a7). Tento čtyrwordový format stackframu je vytvořen pro "Trap #xx" a přerušení na 68010-68060. Stackframes pro ostatní vyjímky jsou na každém procesoru jiné. Instrukce RTE funguje jinak na 68000 a jinak na 68010+. Na 68000 vrací hodnotu do SR a pak se vrací na správnou adresu, kdežto na 68010+ navíc uvolní stackframe podle adekvátního stackframe formátu. Některé programy ukládají adresu a hodnotu SR a pak vykonají RTE. Takhle to ale funguje jen na 68000, na jiných CPU to má katastrofální účinky. Pokud se o to program pokouší, musíte to fixnout. Někdy stačí nahradit RTE s RTR.

#### MOVEM.x RL,-(An) na 68000/010 a 68020/030/040

Je rozdíl, pokud registr použitý v predecrement modu je také obsazen v seznamu registrů. Pro 68020, 68030 a 68040 je hodnota zapsána do paměti počáteční hodnota registeru snížena rozsahem operace. 68000 a 68010 zapisují pocateční hodnotu registru (nesníženou). Tento efekt se ale nedá nijak využít, takže zatím není známo mnoho programů, co tento problém způsobijí.

### Hlavní tipy pro psaní isnatlaček

- Nemodifikujte CPU registry na novějších CPU jako jsou VBR a CACR. VBR je vždycky na 0 z programatorskeho pohledu, i když je přesunuto, protože autovektory (a vyjímky TRAP, pokud je flag WHDL_EmulTrap nastaven) jsou emulované. Bity v CACR se liší u každého CPU. Je jenom jeden spravný způsob jak modifikovat cache, použijte funkce resload_SetCACR/SetCPU a bitdef hodnoty z 'exec/execbase.i' a 'whdload.i'. Také veškerý kód v programu, který hrabe na tyto registrý, musí být odstraněn nebo vynechán.
- Nikdy nemodifikujte disk image, protože pokud někdo chce spustit program z floppy, stačí mu pouze zapsat image zpatky na disk (ale předpokládá se, že program musí běžet z diskety bez oprav a žádná stopa není ve speciálním formátu nebo netvoří ochranu disku).
- Nikdy nepoužívejte binární kód z programu přímo ve slave (copyright problem).
- Zapněte Caches jen pokud jste si jisti, že program poběží na všech procesorech.
- Používejte co nejméně paměti pro ws_BaseMemSize. Nekteří lidé mají rezidentní tagy na konci Chip RAM a tak pomáhá použít jen $1f0000 místo $200000 a WHDLoad může použít absolutní alokovanou paměť.