
31.12.1990


           Návod na spouštění vícedílných programů CMT z disku.
           ----------------------------------------------------

    Na SHARPa existuje velké množství kvalitních (nebo pěkných) her,které
jsou vícedílné a nahrávají se z CMT (pásky).Při rozšíření SHARPa o floppy
disketovou jednotku dojde po počáteční euforii k jednomu z prvních zklamání
- tyto vícedílné páskové programy nejdou z disku spouštět.U některých
se sice dá oželet první díl,který pouze vykreslí úvodní obrázek (aby se
během nahrávání bylo na co koukat),ale k vlastní hře nezbytně nutný není.
Některé další (většinou pouze dvoudílné) hry,které nejsou paměťově příliš
náročné,se scelí,tzn. že ze dvoudílné hry se provede hra jedna.
Pokud se oblasti paměti,které hra zabírá nepřekrývají,jednoduše se
obě části nahrají z monitoru počítače do paměti příkazy:

     *G0027      - nahrání hlavičky prvního dílu hry
     *G002A      - nahraje vlastní tělo programu podle údajů v hlavičce
     *G0027      - nahrání hlavičky druhého dílu hry
     *G002A      - nahraje vlastní tělo programu podle údajů v hlavičce

a poté zpět na pásku příkazem monitoru S (save).

Takto nyní již jednodílný program je třeba disasemblovat a v bývalé první
části hry zrušit instrukce pro nahrávání druhého dílu hry z CMT.

Tam,kde se oblasti paměti překrývají,je možno použít následující
postup:


     *G0027      - nahrání hlavičky prvního dílu hry
     *G002A      - nahraje vlastní tělo programu podle údajů v hlavičce
     *G0027      - nahrání hlavičky druhého dílu hry

nyní se změní v hlavičce počáteční adresa tak,aby nedošlo k přepsání již
nahraného prvního dílu (adresa 1104H dva byte  -  určuje počáteční adresu,
odkud se začne nahrávat vlastní tělo programu)

     *G002A      - nahraje vlastní tělo programu podle údajů v hlavičce

Při disasemblování se nejen odstraní příkazy pro nahrávání druhého dílu
z CMT,ale zároveň se musí provést přemístění druhého dílu hry na správné
adresy - nejlépe pomocí blokové instrukce přenosu LDIR.

Výše uvedeným způsobem byla například převedena šachová hra COLOSSUS,
původně dvoudílná.Zde bylo přidáno pár bajtíků,takže po spuštění hry
se nám zobrazí stručný návod (původně první díl hry) a po stisku
klávesy (zde je těch pár bajtíků např. CD 1B 00 28 FB) se spustí vlastní
hra.

Výhodou výše uvedeného způsobu je,že se vlastně hra "nezmrzačí" a v této
podobě je schopná provozu jak na CMT,tak po zkopírování na disk (např.
programem CMT.COM) i spouštění z disku.Tímto způsobem se dají předělat
i programy vícedílné - tedy nejen dvoudílné (pokud paměť stačí).


Ovšem u stále kvalitnějších her narážíme na potíže s velikostí paměti
počítače.I zde jsem ale nalezl řešení.Jeho použití je ovšem vázáno
na určité vybavení a sice je potřeba být vybaven Ramdiskem.Teoreticky
je jedno,jaký typ vlastníte,ovšem protože já sám mám Ramdisk (dále
jen RD) zálohovaný,veškeré další informace se vztahují právě k němu.

Velikost RD by měla být alespoň 64 Kb,ale s větším RD se samozřejmě
dá udělat víc.Vícedílné programy,které pomocí RD spouštím,se nedají
spustit na disku nezálohovaném.Jak jsem byl informován,problém prý
spočívá v používání portů pro adresaci a nebo v tom,že zálohovaný RD
při každém čtení nebo zápisu z nebo do RD sám automaticky (tzn.
hardwarově) zvyšuje čítač adres o jednu,což prý nezálohovaný nedělá.
(Je-li to pravda,nevím - vyzkoušejte)

Pro převádění budete potřebovat následující programové vybavení :

páskové programy (samozřejmě možno míti na disku)

INTERCOPY   kopírovací program pro CMT
TURBOCOPY   kopírovací program pro CMT

diskové programy:

CMT.COM      kopírovací program mezi diskem a CMT
MZCONV.COM   převádí program zkopírovaný na disk pomocí CMT.COM do
             podoby přímo spustitelného programu z disku (*.COM)
TURBOPASCAL nebo
SUPERPASCAL  - kompilátor pascalu (možno samozřejmě užít i jiný kompilátor
               např. C a pod.)



Základní myšlenka je asi tato:
Po spuštění první části hry se normálně provádí nahrávání dalšího dílu
z CMT.Toto nahrávání z CMT je nutno změnit na nahrávání z nějaké rychlejší
periferie,než je CMT.Z disku by to sice teoreticky šlo,ovšem byl by to
skutečně velký programátorský problém.Mnohem jednodušší je přesunout
pomocí pár bajtíků obsah RD do paměti RAM.To znamená,že prográmkem (na konci
je příklad takového programu v PASCALu) otestujeme,zda je připojen
RD a potom (je-li tam) RD vymažeme.Poté do RD překopírujeme druhou část
hry (na disk zkopírováno z pásky pomocí programu CMT.COM).Předtím
je nutno RD inicializovat,čímž se zabezpečí,že se program v RD uloží vždy
od stejné adresy ( 1080h ) sekvenčně.
Pak je spuštena první část hry,která si z RD stáhne svojí druhou část a
hra běží.

A nyní k jednotlivým bodům podrobně,postupně si probereme celý postup.

Někde jsem sehnal dejme tomu dvoudílnou hru,která je provozuschopná pouze
na CMT.

1.  oba díly pomocí CMT.COM převedeme na disk.

2.  na pracovní kasetu si z disku nahrajeme celý první díl
    a z druhého dílu pouze hlavičku
    (po nahrání hlavičky nahrávání "brejkneme"  ).

3.  pomocí programu TURBOCOPY zjistíme počáteční adresu,startovací adresu,
    a velikost obou dílů hry (proto jsme nahrávali hlavičku druhého dílu
    hry).Tyto údaje si zaznamenáme k pozdější potřebě.

4.  do kopírovacího programu INTERCOPY nahrajeme první část hry

5.  v tomto programu se dá disasemblovat.Disasemblujeme tedy první část
    hry,kde hledáme instrukce pro nahrávání druhého dílu z CMT.
    Nemusíme zcela "rozšifrovat" celý první díl hry,hledáme pouze
    instrukce,které provádějí vlastní nahrání z CMT.Může se jednat o
    podprogramy monitoru počítače SHARP,ale nemusí.Vzpomeňme si,že máme
    i hry,kdy první část je v SHARP módu,zatímco další jsou nahrány v
    sinclair módu.

6.  tyto instrukce přepíšeme (příkaz W programu INTERCOPY) instrukcí
    skoku na adresu 1108h

                               JP 1108h

    zde jsou kódy instrukce    C3 08 11

    a nebo                     CALL 1108h

                               CD 08 11

    což bude vysvětleno dále.

    Na této adrese totiž začíná komentář,který se ukládá jako součást
    hlavičky programu na CMT.Protože tento komentář bývá málokdy
    využitý,máme zde ideální místo,kam si uložíme náš podprográmek,
    který nám provede vlastní sejmutí druhého dílu hry z RD.

7.  takto upravený program nahrajeme zpět na pásku.

8.  spustíme program TURBOCOPY a do něj zpět nahrajeme první díl hry,
    který jsme si v bodě 7 uložili na pásku.

9.  v tomto programu je možné měnit i parametry hlavičky včetně komentáře
    My si sem umístíme náš prográmek,který provede vlastní přihrání
    druhého dílu z RD.Zde je příklad takového prográmku v assembleru:

        3E 80            LD A,080H     ;počáteční adresa druhého
        06 10            LD B,010H     ;dílu hry v RD
        0E EB            LD C,0EBH     ;port RD pro čtení dat
        ED 79            OUT (C),A     ;nastavení počáteční adresy
   *    01 00 10         LD BC,01000H  ;délka druhého dílu hry
   *    11 00 12         LD DE,01200H  ;počáteční adresa druhého dílu hry
        DB EA     LOOP:  IN A,(0EAH)   ;čte jeden byte z RD
        12               LD (DE),A     ;a uloží ho na své místo v RAM
        13               INC DE        ;adresa pro příští byte
        0B               DEC BC        ;a zbývá nám ještě přenést
        78               LD A,B        ;test na konec cyklu
        B1               OR C          ;je registr BC nulový  ?
        20 F7            JR,NZ LOOP    ;pokud ne,čteme další byte

    a zde bude umístěna buďto instrukce RET a nebo proveden skok na
    startovací adresu druhého dílu hry.

        t.j. buď

        C9               RET

        a nebo

   *    C3 00 12         JP 01200H

    Pokud totiž byly v původním prvním díle hry např. použity podprogramy
    monitoru začínající na adresách  0027h a 002Ah, pak se původně provedlo
    jen "přihrání" druhého dílu,ale vlastní program pak pokračoval prováděním
    instrukcí prvního dílu hry.Zde tedy použijeme instrukci RET a podprogram
    je z prvního dílu hry volán istrukcí CALL 1108h (tedy nikoliv instrukcí
    JP 1108h).Po provedení našeho podprogramu (přihrání druhé části hry) se
    řízení programu navrátí zpět prvnímu dílu hry.
    Pokud však byl použit podprogram monitoru dejme tomu 0111h, pak se použije
    instrukce JP startovací adresa,protože tento podprogram po nahrání
    druhého dílu hry provede jeho spuštění (podle startovací adresy uložené
    v hlavičce).

    Tam,kde je v assemblerovském výpisu * je nutno dosadit skutečné adresy
    druhého dílu hry tak,jak jsme si je v bodě 3 zaznamenali.

    Tento prográmek je nožno umístit i jinam v paměti, a to bez
    úprav - je relokovatelný.

10. Takto upravený první díl hry uložíme na pásku

11. Z pásky pomocí programu CMT.COM provedeme nahrání prvního dílu hry
    na disk.Tímto momentem skončila práce s páskou,vše ostatní se bude
    odbývat na disku.

12. Pomocí programu MZCONV.COM provedeme konverzi námi upraveného prvního
    dílu hry do podoby přímo spustitelného programu  (  *.COM ).

13. u druhého dílu hry změníme příponu MZF na jinou.Hra totiž již nebude
    spustitelná z CMT a je proto zbytečné někdy v budoucnu,kdy již zapomeneme,
    co jsme to vlastně "tenkrát" dělali,mít jakékoliv potíže s pokusy,
    jak kamarádovi bez floppy nahrát na pásku skvělou hru.

14. Spustíme TURBOPASCAL a napíšeme prográmek,který :

    - zjistí,zda je přítomen RD
    - tento RD vymaže a vydá o tom zprávu
    - do RD překopíruje druhou část hry
    - spustí námi upravenou první část hry

    Příklad takového programu:

*****************************************************************************

program univerzalni_prevodnik_na_hry;
{$c-,r-,v-,w1,x+,a+,u-}

type
     radek=string[80];
       nnn=string[12];

var ok : boolean;
     p : array[1..32] of byte;
 xx,b,c : byte;
 x,y,z : integer;
 f1,f2 : file;

procedure ram(x,y:byte;slovo:radek);
var a,b:byte;
begin
b:=length(slovo);
gotoXY(x,y);write(chr(135));
for a:=x to b+x-1 do write(chr(129));write(chr(134));
gotoXY(x,y+1);write(chr(130),slovo,chr(130));
gotoXY(x,y+2);write(chr(132));
for a:=x to b+x-1 do write(chr(129));writeln(chr(133));
end;

procedure kopirka(nazev:nnn);
var naz2:string[14];
     pam:array[1..128,1..100] of byte;
    q,xx:byte;
begin
for xx:=1 to length(nazev) do
begin nazev[xx]:=upcase(chr(ord(nazev[xx]) and $7f));end;
naz2:='E:'+nazev;
assign(f1,nazev);
{$I-} reset(f1); {$I+}
ok:=(IOResult=0);
if not ok then begin clrscr;
               ram(1,5,'Soubor  "'+nazev+'"  není nalezen,lituji.');halt;end;
assign(f1,nazev);reset(f1);
assign(f2,naz2); rewrite(f2);
repeat
blockread(f1,pam,100,z);
blockwrite(f2,pam,z);
until z=0;
close(f1);close(f2);
end;

procedure nulujRD;
begin
port[$e9]:=0;port[$eb]:=0;for x:=1 to 4096 do port[$EA]:=$E5;
end;

function testrd:boolean;
var a:byte;
begin
port[$e9]:=0;port[$eb]:=0;
a:=port[$Ea];
port[$e9]:=0;port[$eb]:=0;
port[$EA]:=$E5;
port[$e9]:=0;port[$eb]:=0;
if port[$ea]<>$e5 then testrd:=false else testrd:=true;
port[$e9]:=0;port[$eb]:=0;
port[$EA]:=a;
end;

begin
clrscr;
ram(1,1,'****  Hra Wooky  ****');
writeln;writeln;
writeln('Tato pásková vícedílná hra se spustí pomocí tohoto prográmku.');
writeln;
writeln('Spuštění hry je vázáno na určitou konfiguraci a sice');
writeln;
writeln('je nutné být vybaven alespoň jednou FLOPPY jednotkou a');
writeln;
writeln('RAMDISKEM.(program byl odzkoušen na zálohovaném Ramdisku 256 Kb');
writeln;
writeln('od firmy microWare).Program nyní provádí test na přítomnost Ramdisku.');
writeln;
writeln('Pokud ramdisk nalezne,bude jeho obsah nenávratně ztracen.');
writeln;writeln;writeln;
writeln('                                příjemné chvíle s hrou');
writeln;writeln('                                                Vám přeje');
writeln;write('$oft B&D':68);

if testRD=false then begin
          clrscr;ram(1,5,'Lituji,nenalezl jsem Ramdisk');writeln;halt end;

nulujRD;
xx:=bdos(25);
bdos(13);
bdos(14,xx);
kopirka('wooky2.B&D');
assign(f1,'wooky1.com');
execute(f1);
end.

*****************************************************************************


15. Program zkompilujeme a celé dílo vyzkoušíme.Je-li vše v pořádku,smažeme z
    disku námi upravený první díl hry s příponou *.MZF a to ze stejných
    důvodů,jako v bodě 13.



Závěrem: nejtěžší je provedení bodu 5 - vyhledání instrukcí pro nahrávání,vše
ostatní je už jednoduchá rutina nebo-li prkotina.Je samozřejmé,že spoustu věcí
lze obejít nebo udělat jinak,popisoval jsem vlastně způsob,jak jsem ze začátku
postupoval já sám.
Tento text dávám k volnému použití a to zdarma.Nechť je tedy také tak
rozšiřován.Tento text je možno doplňovat vlastními příspěvky a nápady.
Zároveň s příspěvkem však nezapomeňte uvést i své jméno a adresu.
Současně prosím všechny ty,kteří se zabývají přepisem her z ostatních
počítačů,aby pokudmožno vytvářeli takové produkty,které z disku spouštět
půjde,třeba i výše uvedeným způsobem.Počet uživatelů počítače SHARP
vybavených diskem stále roste a šíření předělaných her touto cestou je
podstatně rychlejší,což autorovi (nebo spíše tomu,kdo hru předělal)
přinese i rychlejší a větší popularitu,než u produktů,které jsou sice
nádherné,ale pouze páskové.


A nakonec : oba dva způsoby (scelování a spouštění přes RD) je možno
kombinovat,použít společně.Tímto způsobem byla například převedena
původně pětidílná (!) hra DYNAMITE DAN,která má první díl v SHARP módu a
ostatní čtyři v sinclair módu.

No a úplně nakonec Vám všem příznivcům počítače SHARP
přeju mnoho ůspěchů ve Vaší programátorské dřině.


                                  Bohumil Dařbujan
                                  Bardějovská 2473
                                  47006 Česká Lípa
