ZX ROM

Z PMD 85 Infoserver

ZX ROM pre PMD 85


ZX ROM
Autor:Slavo Labský
Busy soft
Verzia:ZXROM02, v02 (2018)
(PMD 85-1,2,2A,3)
Lokalizácia:angličtina
Download: zxrom02.zip

ZXrom02 je štandardná ROM počítača ZX-Spectrum 16/48k preportovaná na platformu PMD 85. Je zároveň doplnená o jednoduchú funkcionalitu, ktorej cieľom je zjednodušiť import a export programov z/do okolitého sveta.


Obsah

Spustenie

ZX ROM je distribuovaná ako klasický PTP súbor ZXrom02.ptp alebo čistá binárka ZXrom02.cod bez akýchkoľvek hlavičiek. Z PTP súboru sa program nahraje do pamäti klasiky pomocou MGLD 00, súbor COD treba nahrať do pamäti od adresy 0000. Spustenie je potom pomocou príkazu JUMP 0000 alebo stlačením Shift+DEL.

Hardvérové odlišnosti

Vzhľadom na HW rozdiely medzi PMD 85 a ZX-Spectrom, sú v porte ROMky nasledujúce odlišnosti:

  • Atribútové kolízie - Vzhľadom na 6-bodovú šírku atribútu na PMD 85 sa môže stať, že sa farbou použitou v danom znaku môžu zafarbiť aj časti susedných znakov.
  • Farby v atribúte - Keďže jednou z dvoch farieb, ktoré PMD 85 môže zobraziť v jednom atribúte, musí byť čierna, nie je možné mať naraz PAPER aj INK rôzny od čiernej. Buď je INK čierny a PAPER môže byť inej farby, alebo PAPER čierny a INK iný. Ktorý bude natvrdo čierny, závisí od aktivácie inverzného režimu (pozri ďalej).
  • S farbami súvisí aj BRIGHT a FLASH - tieto príkazy sú ignorované a na výslednom obraze sa nijak neprejavia.
  • S inou HW realizáciou farieb súvisí aj odlišná činnosť funkcie ATTR(a,b). Táto funkcia by mala vracať hodnotu ZX atribútu, avšak vzhľadom na inú organizáciu PMD 85 VideoRAM, nie je možné vrátiť presnú hodnotu atribútu podľa toho aký PAPER/INK/BRIGHT/FLASH obsahuje. Hodnota atribútu je len približná - vždy je buď INK alebo PAPER nulový (podľa zvoleného režimu zobrazovania). BRIGHT a FLASH (bity 6 a 7) sa vracajú vždy nulové.

Implementačné odlišnosti

  • ZX-Printer bol úplne zrušený. Preto už nefunguje výpis 8x vyššieho písma pomocou POKE 23681,x.
  • Vzhľadom na zmenený kód v ROMke, nemusia správne fungovať úsporné formy zápisu čísel založené na funkcii PEEK, kde adresa pre PEEK je väčšia ako 7.
  • Taktiež vzhľadom na zmenený (a tým aj poposúvaný) kód, už neplatia žiadne štandardne používané vstupné body pre funkciu USR. Napríklad klasické zistenie voľného miesta PRINT 65535-USR 7962. Ak chcete zistiť voľné miesto v BASICu, môžete použiť príkaz PRINT USR 45.

Konfigurácia

V binárnom súbore ZXrom02.cod, resp. po nahratí ROMky do pamäte, sa od offsetu +12 nachádza konfiguračný blok o dĺžke 4 bajty, ktorý slúži na užívateľskú konfiguráciu ROMky:

  • +12 ... Nastavenie režimov činnosti (pozri nasledujúcu časť) (defaultne: 0Fh)
  • +13 ... Vyšší bajt adresy, od ktorej už ROMka nepoužíva pamäť (defaultne: 0C0h)
  • +14 ... Rezerva
  • +15 ... Rezerva

Tieto štyri bajty si užívateľ môže priamo v súbore ROMky prednastaviť na požadované hodnoty. Keď potom súbor s ROMkou nahrá do PMD 85 a spustí, ROMka bude pracovať podľa týchto užívateľom zvolených nastavení.

Nastavenie režimov činnosti na offsete +12 špecifikuje, ako bude ROMka zobrazovať farby a ako sa budú v pamäti mapovať ZX videoramka a systémové premenné BASICu. Presný popis je v nasledujúcej kapitole.

Pomocou vyššieho bajtu adresy na offsete +13 sa ROMke určuje horná hranica pamäte, ktorú môže pre BASIC použiť. V skutočnosti je to iba limit, po ktorý ide úvodný test pamäte pri jej testovaní. Štandardne je tu hodnota 0C0h, čo je začiatok VideoRAM a znamená to, že ROMka môže používať celú dostupnú RAMku až do adresy 0BFFFh.

Príklad: Ak ROMku spúšťame pomocou programu RUNNER, ktorý sa nahráva od adresy 9C00h a chceme, aby po spustení RUNNERa ostal v pamäti k dispozícii, nastavíme bajt na offsete +13 na hodnotu 9Ch. Tým pádom bude ROMka využívať iba pamäť po adresu 9BFFh a RUNNER zostane nepoškodený.

Poznámka: Tento limit používanej pamäte sa nevzťahuje na príkaz POKE. Príkazom POKE teda možno modifikovať pamäť aj nad touto adresou, napríklad sa dá priamo zapisovať do VideoRAM PMD 85.

Režimy činnosti

ZX ROM má niekoľko režimov činnosti. Po spustení sa režimy nastavia podľa aktuálnej hodnoty bajtu na offsete +12 v konfiguračnom bloku (pozri vyššie). Tieto režimy je možné meniť priamo z BASICu pomocou príkazu OUT 256,X, kde X je nová hodnota bajtu na offsete +12.

Jednotlivé bity hodnoty majú nasledujúci význam:

  • Bit.0 - Inverzný režim - 0:vypnutý 1:zapnutý
  • Bit.1 - Použitie ColorAce farieb - 0:nie 1:áno
  • Bit.2 - Virtuálne mapovanie systémových premenných BASICu - 0:nie 1:áno
  • Bit.3 - Virtuálne mapovanie VideoRAM a print buffera 4000h-5BFFh - 0:nie 1:áno
  • Bit.4 - Povolenie emulácie matematických chýb: delenie a -65536

Aký režim je aktuálne nastavený, sa dá zistiť pomocou funkcie IN 256. Ďalej nasleduje podrobnejšie vysvetlenie jednotlivých režimov.

Bit.0 ... Inverzný režim


ZX-Spectrum po resete zobrazuje čierne písmo na svetlom podklade. Naproti tomu u PMD 85 je zvykom mať svetlé písmo na čiernom podklade. Dalo by sa napísať, že tento filozofický rozpor rieši inverzný režim.

Inverzný režim určuje, či sa defaultne bude zobrazovať tmavá kresba (INK) na svetlom podklade (PAPER) alebo svetlá kresba na tmavom podklade. V prípade, že je povolené používanie farieb (viď Bit.1), svetlá farba sa dá nastaviť na jednu zo štandardných ZX farieb od 1 (tmavomodrá) až do 7 (biela).

  • Bit.0 = 0 ... svetlé písmo na tmavom pozadí. PAPER je vždy 0, INK je od 1 do 7.
  • Bit.0 = 1 ... tmavé písmo na svetlom pozadí. INK je vždy 0, PAPER je od 1 do 7.

V prípade, ak niečo (PAPER alebo INK) môže mať hodnoty farieb od 1 do 7, pri jeho nastavení na čiernu farbu (0) bude zobrazená tmavomodrá farba (1).

Bit.1 ... Použitie ColorAce farieb


V prípade že máte RGB výstup (zelená, červená, modrá, fialová) alebo ideálne ColorAce, nastavte tento Bit na 1 a môžete využívať všetkých osem farieb ZX-Spectra.

Ak ale máte iba monochromatický výstup, nastavte tento Bit na 0 a potom čierna farba (0) bude zobrazená ako tmavá a všetky ostatné farby (1 až 7) ako svetlá farba. Príkazy PAPER aj INK budú v tomto režime ignorované.

Bit.2 ... Virtuálne mapovanie systémových premenných BASICu


V BASICových programoch bývajú často POKE do systémových premenných (sysvars). Vzhľadom na to, že sysvars sú umiestnené v pamäti inde (viď pamäťový model nižšie), je možné zapnúť tzv. virtuálne mapovanie. Po zapnutí tohto režimu (Bit.2=1), budú sysvars v príkazoch POKE a PEEK viditeľné na svojich obvyklých a známych adresách od 23552 presne tak, ako na ZX-Spectre. Mapovanie platí pre 256 bajtov na adresách 23552-23807, takže je tu vidno aj začiatok BASICu - môže to byť užitočné napr. keď chcete pomocou POKE vytvoriť nultý riadok, alebo niečo uložiť za REM.

V prípade, že máte v pamäti svoje dáta, ktoré si spravujete z BASICu pomocou POKE, a ktoré práve zasahujú do týchto 256-tich bajtov, nastavením Bit.2=0 virtuálne mapovanie vypnite a potom POKE/PEEK do oblasti od 23552 budú normálne pracovať s vašimi dátami.

Bit.3 ... Virtuálne mapovanie VideoRAM a print buffera 4000h-5BFFh


V BASICových programoch sa okrem POKE do systémových premenných sem-tam vyskytnú aj POKE do oblasti VideoRAM 4000h-5AFFh a ZX printer buffera 5B00h-5BFFh. Keďže PMD 85 má VideoRAM na inom mieste v pamäti, takéto POKE by sa v obraze nielenže nijak neprejavilo, ale dokonca by mohlo byť nebezpečné, ak by sa práve strafilo do oblasti, kde reálne ležia systémové premenné a BASIC program. Preto bolo zavedené virtuálne mapovanie VideoRAM a ZX Printer buffera, ktoré toto ošetruje.

Pri zapnutom virtuálnom mapovaní (Bit.3=1) sa v príkazoch POKE a PEEK všetky adresy do týchto oblastí odchytia a spracujú nasledujúcim spôsobom:

  • 4000h-57FFh - Pixelová časť VideoRAM: Všetky POKE sa prepočítajú na osmice pixelov a zapíšu do VideoRAM PMD 85 tak, aby obraz bol presne taký istý, ako na ZX-Spectre. Pri čítaní hodnôt pomocou PEEK sa vezmú údaje z VideoRAM PMD 85 a spätne prepočítajú tak, aby funkcia PEEK vrátila presne takú istú hodnotu, ako by vrátila na ZX-Spectre. To znamená, že čo do pixelov príkazom POKE zapíšete, to tam uvidíte a to odtiaľ aj funkciou PEEK načítate.
  • 5800h-5AFFh - Atribútová časť VideoRAM: POKE do atribútov funguje presne tak isto ako nastavenie farieb v atribútoch pri výpise znaku. Vzhľadom na iný hardvér tu platia dva nasledujúce rozdiely (viď úvodná časť):
    • okrem samotného meneného atribútu sa môžu zmeniť farby aj v susedných atribútoch
    • v normálnom režime sa dá nastaviť len INK, v inverznom len PAPER
V prípade, že nie je povolené použitie ColorAce farieb (Bit.1=0), všetky zápisy do atribútov su ignorované.
Pri čítaní atribútu funkciou PEEK, vzhľadom na spomenuté HW odlišnosti, žiaľ, nie je možné zrekonštruovať pôvodnú hodnotu, ktorá bola do atribútu zapísaná. Funkcia PEEK preto vráti hodnotu, ktorá obsahuje nenulový INK (normálny režim) alebo nenulový PAPER (inverzný režim). Všetky ostatné farby sú v hodnote nulové. Presne týmto istým spôsobom pracuje aj funkcia ATTR(a,b).
  • 5B00h-5BFFh - ZX-Printer buffer: V aktuálnej verzii ROMky nie je podporovaný, to znamená, že akékoľvek POKE do tejto oblasti je ignorované a akýkoľvek PEEK z tejto oblasti vráti natvrdo nulu.
Poznámka: Niektoré samomodifikujúce sa BASICové programy si môžu čítaním systémovej premennej PROG (23635) zisťovať, kde práve ležia a od tejto adresy sa modifikovať pomocou POKE. Keďže BASIC v tejto preportovanej ROMke na PMD 85 začína na nižších adresách, ako na ZX-Spectre (viď pamäťový model nižšie), môže sa stať, že sa takéto samomodifikačné POKE strafí práve do mapovaného priestoru 4000h-5BFFh. V takomto prípade sa odporúča virtuálne mapovanie VideoRAM vypnúť, aby sa BASIC mohol zmodifikovať ako potrebuje.
Bit.4 ... Povolenie emulacie matematickych chyb: delenie a -65536


Originálne matematické rutinky v ZX romke obsahujú tieto dve chyby:

  • Delenie: Pri delení sa v závislosti od argumentov stratí 33. bit výsledku, čo sposobí, že mantisa výsledku sa zaokrúhľuje vždy smerom dole, bez ohľadu na výsledok. Chyba sa prejaví napríklad pri delení 1/10. Správny výsledok 0.1 by mal byť kódovaný ako "7D 4C CC CC CD", ale kvôli chybe delenia bude výsledok zakódovaný ako "7D 4C CC CC CC", čo v skutočnosti predstavuje hodnotu 0.09999999976.
  • Kódovanie čísla -65536: Hodnota -65536 môže byť kódovaná dvoma rôznymi spôsobmi: Prvý je integer "00 FF 00 00 00" a druhý floating point "91 00 00 00 00". Problém je v tom, že niektoré výpočtové rutinky počítajú s tým, že toto číslo bude kódované iba ako integer, a iné zase, že bude iba ako floating point. Pokiaľ toto číslo vstúpi ako argument do výpočtovej rutinky v síce správnom, ale rutinkou nepodporovanom formáte, výsledok výpočtu bude nesprávny. Typicky príklad je funkcia INT, kde PRINT INT -65536 vypíše nesprávny výsledok -1.

ZXrom02 obsahuje úplne prepracované a zoptimalizované matematické rutinky, ktoré dokážu počítať bez vyššie spomínaných chýb. Avšak, ak by sa nejaký basic program spoliehal na tieto chyby, a bez nich by nebol schopný správne fungovať, je možné bitom 4 v nastavení povoliť emuláciu oboch chýb.

Klávesnica

Keďže PMD 85 má až 77 klávesov, oproti klasickému ZX-Spectru ("Gumáku"), ktorý má 40 klávesov a "plusku" (Delte, 128...), ktorý má pre pohodlnejšie písanie až 58 klávesov, je mapovanie klávesnice ZX-Spectra rozšírené na všetky klávesy PMD 85, vďaka čomu je písanie na PMD 85 častokrát ešte pohodlnejšie.

Klávesy Shift


ZX-Spectrum má dva shifty - Caps Shift a Symbol Shift. PMD 85 má síce iba jeden Shift, avšak je tu kláves STOP, ktorý na modeloch PMD 85-2A a PMD 85-3 slúži ako druhý, pomocný "shift" pre špeciálne účely. Preto základný Shift slúži ako Caps Shift a STOP ako Symbol Shift.

"Gumák"


Základná klávesnica ZX-Spectra sa skladá z 26 písmen, 10 číslic, medzery, Enteru a dvoch Shiftov. Týchto 40 klávesov funguje PRESNE tak isto, ako klávesy na ZX-Spectre. Tým pádom, každý kto vie a/lebo je zvyknutý písať na gumákovej klávesnici, už vie automaticky čokoľvek napísať aj na PMD 85 a všetky ďalšie informácie o klávesnici môže (ak chce :) kľudne preskočiť.

"Plusko"


Kto je zvyknutý na pluskovú klávesnicu, môže využiť ďalšie klávesy pre uľahčenie písania - Edit, šípky všetkými štyrmi smermi, klávesy pre zmeny režimov (Caps lock, Extend, Graph) a rôzne symboly ako bodka, čiarka, bodkočiarka...
Úplný zoznam všetkých klávesov a ich mapovanie je uvedené v tabuľke nižšie.

Klávesy so symbolmi


Napravo od písmen a číslic sa nachádza zopár klávesov so symbolmi, samozrejme aj tieto fungujú a môžete pomocou nich písať symboly, ktoré sú na nich zobrazené a to dokonca aj symboly \ [ ], ktoré sa normálne píšu cez Extend mód. Prázdny kláves na PMD 85-1 (alebo zložené zátvorky na ďalších modeloch PMD 85), slúži ako Caps lock.

Kľúče K0-K11


Aby sa vám ešte ľahšie písalo, môžete použiť kľúčové klávesy K0-K11. K dispozícii máte 24 kľúčov (prvých 12 bez Shiftu a ďalších 12 so Shiftom), do každého kľúča si môžete uložiť ľubovoľný znak alebo príkaz, a stlačením kľúča sa tento znak napíše. Typický príklad: Chcete často používať príkaz OUT, ale nechce sa vám ho zakaždým zložito vypisovať cez Extend mód a Symbol Shift. Keď si príkaz OUT zadefinujete do nejakého kľúča, stlačením tohto kľúča sa vám príkaz vypíše a to dokonca bez nutnosti predtým použiť Extend mód.


Definovanie obsahu kľúčov

Na rozdiel od PMD 85, obsah sa do kľúčov nezapisuje klávesom WRK, ale na toto teraz slúži kláves STOP. Ak stlačíte STOP, držíte ho stlačený, a stlačíte niektorý z kľúčov (so Shiftom alebo bez) tak sa znak, nachádzajúci sa v editačnej zóne bezprostredne pred kurzorom, zapíše do tohto kľúča. Na dôkaz, že sa znak do kľúča úspešne zapísal, sa tento znak vypíše tak isto, ako keby ste daný kľúč normálne stlačili.

Alternatívny spôsob definovania obsahu kľúčov je pomocou príkazu POKE. Keď spravíte: POKE 100+číslo_kľúča,kód_znaku, tak sa do daného kľúča zapíše zvolený znak. Čísla kľúčov sú 0 až 11 pre kľúče bez Shiftu a 12 až 23 pre kľúče so Shiftom. Výhodou tohto alternatívneho spôsobu je, že do kľúčov si môžete zadefinovať úplne akýkoľvek znak vrátane riadiacich (napríklad Delete, Enter, Edit...). Analogicky funkcia PEEK (100+číslo_kľúča) vráti kód znaku v danom kľúči.

Oficiálne distribuovaná verzia ROMky má v sebe kľúče preddefinované takto:

Číslo kľúča:  K0   K1  K2  K3   K4   K5      K6      K7  K8   K9   K10  K11
 Bez shiftu:  BEEP OUT IN  LINE OVER INVERSE CIRCLE  {   }    ~    |    (c)
 So shiftom:  PEEK LEN INT ABS  SGN  SQR     RND     VAL STR$ CHR$ CODE INKEY$

Mapovanie klávesnice

Nasleduje prehľadná tabuľka mapovania všetkých klávesov PMD 85 na klávesy ZX-Spectra:

PMD 85 ZX-Spectrum
Shift Caps shift možno použiť ľubovoľný z oboch shiftových klávesov
STOP Symbol shift
A..Z
0..9
Space
A..Z
0..9
Space
alfanumerické znaky a medzera sú mapované štandardne
EOL Enter ako Enter môžete použiť ľubovoľný z oboch EOL-ov
← →
⇤ ⇥
← →
↑ ↓
šípky všetkými štyrmi smermi
INS True video normálny výpis
Inv video inverzny výpis (kláves so šípkou šikmo hore)
{} Caps lock prepnutie z/do veľkých písmen [C] (na modely PMD 85-1 prázdny kláves pod K11)
DEL Delete zmazanie znaku pred kurzorom
END Break zastavenie bežiaceho BASIC programu
C-D Graph prepnutie do/z grafického režimu [G]
WRK Extend prepnutie do/z extend módu [E]
RCL Edit editácia BASIC riadku / v INPUTe iba zmaže editačnú zónu
CLR zmazanie editovaného riadku (špecialita portu pre PMD 85, na originálnom ZX neexistuje)

Klávesy =-  ^\  +;  *:  []  <,  >.  ?/  `@ píšu dané znaky (bez/so Shiftom). Stlačenie klávesu END pri písaní riadku/príkazu/v INPUTe spôsobí výpis medzery. Toto je normálne správanie prevzaté zo ZX-Spectra, kde kláves Break predstavuje kombináciu Caps shift + Space.

Dôležitá poznámka k funkcii INKEY$: Táto funkcia vracia iba tie znaky, ktoré dokáže vrátiť aj na ZX-Spectre. To znamená, že pomocou nej nie je možné testovať znaky \ [ ], ktoré sa normálne musia písať cez Extend mód. Tak isto funkcia INKEY$ nevracia ani obsah kľúčov.

Pamäťový model

Táto časť popisuje, ako sú rozmiestnené objekty po pamäti PMD 85:

  • Od začiatku RAMky (adresa 0) leží samotná ZX ROM. Tá zaberá cca 19 kB pamäti (podľa čísla aktuálnej verzie).
  • Hneď za ROMkou nasleduje 2 kB tabuľka pre akceleráciu prístupu do PMD 85 VideoRAM. Používa sa pre rýchle vykresľovanie grafiky - výpis znakov na obrazovke v príkaze PRINT a pre grafické príkazy a funkcie PLOT, DRAW, CIRCLE, POINT.
  • Nakoniec nasleduje pamäť pre BASIC systém tak, ako na ZX-Spectre, t.j. systémové premenné, BASIC program, premenné BASICu, editačné buffery, voľné miesto a zásobníky, RAMTOP, UDG, PRAMT.

Systémová premenná PRAMT predstavuje koniec pamäti využiteľnej pre užívateľa. Je to vlastne adresa, ktorú test pamäti pri úvodnej inicializácii vyhodnotil ako poslednú použiteľnú. Môže to byť buď posledný bajt RAMky pred začiatkom ROM monitora na 8000h, alebo pred adresou definovanou v konfiguračnom bloku na offsete +13.

Pre defaultnú hodnotu 0C0h bajtu na offsete +13 sa PRAMT pri studenom štarte inicializuje nasledovne:

  • PMD 85 modely bez AllRAM režimu: 7FFFh
  • PMD 85 modely s AllRAM režimom: 0BFFFh

Užitočné volania

Rôzne volania využiteľné pre USR alebo pri volaní z ROM Monitora:

  • 0 ... Studený štart (ako na ZX). Všetko od sysvars vymaže a inicializuje.
  • 5 ... Teplý štart. Nemaže BASIC a jeho premenné, zachová RAMTOP, UDG, PRAMT.
  • 45 ... Vráti aktuálne voľné miesto v BASICU presne ako 65535-USR 7962 na ZX-Spectre.

Teplý štart je užitočný vtedy, keď z ROMky vyskočíte do nejakej inej aplikácie (napr. do ROM Monitora pomocou RANDOMIZE USR 32768) a chcete sa vrátiť nazad do ZX ROMky bez zmazania pamäti a BASICového programu. Pri teplom štarte si ROMka znovu pre istotu inicalizuje všetky periférie (8255, 8253, prerušenia...).

Poznámka: Ak chcete zavolať Monitor z ROM PMD 85 a ste v AllRAM režime, je postup podobný, ako pri prepínaní pamäťových baniek na ZX-Spectre:
  1. CLEAR 32767 - presun RAMTOP-u pod adresu, od ktorej sa prepína pamäť
  2. OUT 247,9 - vypnutie AllRAM režimu a nastránkovanie ROM Monitora
  3. PRINT USR 32768 - zavolanie Monitora

Ak je RAMTOP už nastavený pod 32768, tak ho samozrejme meniť netreba.

Informácie o systéme

Nad rámec pôvodnej funkcionality, táto ROMka umožňuje užívateľovi zobraziť rôzne systémové informácie o obsadení pamäte. Ak užívateľ do dialógového riadku napíše namiesto príkazu otáznik, ROMka vypíše nasledujúce informácie:

  • Prg - dĺžka samotného BASICoveho programu bez premenných
  • Var - dĺžka všetkých BASICovych premenných (bez BASICu)
  • Fre - voľné miesto pre BASIC (od konca dialógového riadku po zásobník)
  • Rmt - systémová premenná RAMTOP - nastaviteľná príkazom CLEAR xxxxx
  • Udg - systémová premenná UDG - umiestnenie užívateľských grafických znakov
  • Top - systémová premenná PRAMT - horná hranica ROMkou použiteľnej pamäte

Znak ? funguje ako normálny regulérny príkaz, je možné ho použiť aj v programe.

Čo je nového

Zmeny v ZXrom02 voči ZXrom01:

  • Oprava chyby sporadického objavenia sa blikajúceho kurzora za chybovým hlásením.
Táto chyba sa neprejavuje často, ale občas sa stane, že sa objaví. Je zapríčinená nekorektným nastavením systémových premenných, konkrétne bitu, ktorý signalizuje, že editačná zóna nebola zmazaná. Pri nesprávnom nastavení tohto bitu sa zobrazené chybové hlásenie nezmaže a editačný riadok pre nový príkaz je umiestnený nie od začiatku riadku, ale až za týmto hlásením. V ZXrom02 by sa toto už nemalo stávať.
  • Kompletne prepracované matematiké rutinky.
Pôvodné matematické rutinky v ZX romke boli písané tak, aby si čo najviac údajov držali v registroch (veľmi často využívali inštrukciu EXX). Procesor 8080 nemá toľko registrov, preto si musí niektoré údaje odkladať do pamäte. Toto spôsobilo, že mnohé matematické rutinky prepísané na 8080 bežali podstatne pomalšie. V ZXrom02 sú rutinky prepracované a optimalizované priamo na mieru inštrukčného súboru 8080 a tým pádom bežia podstatne rýchlejšie než v ZXrom01. Navyše, pre niektoré rutinky boli použité iné, rýchlejšie algoritmy na výpočet a tak tieto rutinky dokážu na 2 MHz 8080 bežať dokonca ešte rýchlejšie, než originálne rutinky na 3.5 MHz Z80.
Napríklad bežné vedecké funkcie (SIN, COS, LN, EXP, SQR...) bežia v priemere 6-krát rýchlejšie, násobenie beží (v závislosti od argumentov) až 40-krát rýchlejšie, generovanie náhodných čísel 50 až 60-krát rýchlejšie, delenie až 96-krát rýchlejšie a absolútnym rekordérom je premena textovej formy čísla na hodnotu (napr. funkcia VAL), ktorá v určitých prípadoch beží až 360-krát rýchlejšie, než bežali povodné rutinky v ZXrom01 !
  • Nový nastavovací bit.4: Povolenie emulácie matematických chýb: delenie a -65536.
Nové prepracované matematické rutinky už netrpia známymi chybami z pôvodnej romky ZX Spektra. Pre každý prípad, ak by to bolo nutné, je možné zapnúť emuláciu týchto chýb nastavením bitu 4 na hodnotu 1 v bajte pre nastavenie režimov činnosti.
  • Prepracovaný lineárny interpolátor v príkazoch DRAW a CIRCLE.
Pôvodný lineárny interpolátor v ZXrom01 fungoval presne ako originál na ZX Spektre, to znamená, že počítal súradnice bodov a pre každý bod volal rutinku príkazu PLOT. Nový optimalizovaný interpolátor už nevolá PLOT, ale pristupuje priamo do videoramky, vďaka čomu príkazy DRAW a CIRCLE dokážu bežať 5 až 6-krát rýchlejšie.

Tape emulátor

Aby sa dali využiť aj magnetofónové príkazy LOAD a SAVE, resp. aby vôbec bolo možné nahrať, či uložiť nejaký BASIC program (a/lebo dáta), je tento port ROMky vybavený maličkým tape emulátorom, ktorý umožňuje navzájom prepojiť štandardný *.TAP súbor zo ZX-Spectra (ďalej len "tapka") s magnetofónovými príkazmi LOAD / SAVE - presne tak isto, ako je to zvykom v (takmer) všetkých emulátoroch ZX-Spectra.

Okrem toho ROMka umožňuje špeciálny alternatívny spôsob nahratia a uloženia BASIC programu pomocou príkazov RUN a STOP, vhodný pre prípad, keď je BASIC taký dlhý, že už nezostane dostatok miesta pre tapku.

Ako funguje tape emulátor


Tape emulátor odchytáva všetky volania load rutinky na adrese 0556h a postupne jej "podstrkáva" jednotlivé bloky z tapky. Podobne tak odchytáva volania save rutinky na adrese 04C2h a jednotlivé bloky ukladá na koniec spomenutej tapky.

Samotná tapka musí byť umiestnená priamo v pamäti. Jej nahratie z externého média do pamäti, poprípade jej uloženie z pamäti na externé médium, samotná ROMka nijak nerieši, toto zostáva na starosti samotného užívateľa. Pokiaľ užívateľ pracuje nie na reálnom PMD 85, ale v emulátore, môže využiť napríklad funkciu priameho načítania / uloženia bloku pamäti na disk hostiteľského systému.

Práca s tape emulátorom


Pre riadenie činnosti tape emulátora sú k dispozícii nasledujúce BASICové príkazy:

  • CAT <číslo>
    COPY <číslo> - výpis hlavičiek v tapke, voliteľne od N-tej hlavičky.
Príkaz COPY pôvodne slúžil pre vytlačenie obrazovky na ZX-Printer, avšak keďže ZX-Printer nie je podporovaný, bol tento príkaz použitý ako alternatíva k príkazu CAT, aby sa užívateľ nemusel trápiť so zložitým písaním príkazu CAT
  • MOVE číslo - nastavenie load kurzora na daný blok (hlavičku), t.j. ktorý blok bude ako ďalší v poradí "podstrčený" load rutinke 0556h.
  • ERASE číslo - vymazanie daného bloku z tapky.
Maže hlavičku a s ňou aj všetky nasledujúce bezhlavičkové bloky až po ďalšiu hlavičku alebo koniec tapky.
  • FORMAT adresa,<dĺžka> - definovanie buffera v pamäti pre uloženie tapky.
Umožňuje užívateľovi nadefinovať miesto, kde v pamäti má byť uložená tapka použitá v tape emulátore a aká môže byť jej maximálna veľkosť. Zadaná adresa musí byť vyššia ako RAMTOP.
Dĺžka je nepovinný parameter. V prípade, že ho užívateľ nezadá, tape emulátor si dĺžku buffera sám nastaví na dĺžku tapky v pamäti.
FORMAT 0,0 prepne na vstavanú skúšobnú tapku, ktorá je súčasťou ROMky.

Parametre uzavreté v zobáčikoch < > sú nepovinné, namiesto číselnej hodnoty je samozrejme možné použiť aj akýkoľvek výraz s číselným výsledkom.

Príkazy CAT a COPY najprv vypíšu tieto aktuálne informácie o tape bufferi:

  • A:xxxxx - Adresa, kde začína tape buffer (určená príkazom FORMAT)
  • L:xxxxx - Celková dĺžka tape buffera (určená príkazom FORMAT)
  • U:xxxxx - (Used) koľko z tape buffera je aktuálne obsadené tapkou
  • F:xxxxx - (Free) koľko voľného miesta je v tape bufferi pre SAVE

Následne vypíšu hlavičky v tomto formáte:

N>T:Meno     Adresa:Dĺžka
  • N ... poradové číslo hlavičky, pre príkazy MOVE, ERASE, CAT, LOAD <číslo> ...
  • > ... aktuálna poloha load kurzora, t.j. čo sa bude nahrávať najbližšie
  • T ... typ súboru: 0=BASIC, 1=číselné pole, 2=znakové pole, 3=bajty
  • Meno ... vypíšu sa aj tokeny, riadiace kódy pod 32 sa vypíšu ako bodka
  • Adresa ... druhý parameter z hlavičky: štartovací riadok, meno premennej, adresa
Rozšírená syntax LOAD príkazov


Tape emulátor prináša aj novú rozšírenú syntax pre príkazy LOAD / MERGE / VERIFY:

PRÍKAZ <číslo> <,> <meno_suboru> ...ďalšie parametre (LINE, CODE... presne ako ZX)

To znamená, že:

  • Meno súboru je nepovinné. Nezadané meno súboru predstavuje prázdny reťazec.
  • V rámci príkazu je možné nastaviť load kurzor na blok 'číslo', presne ako príkaz MOVE.
  • Číslo bloku môže aj nemusí byť od mena oddelené čiarkou.

Prakticky to znamená, že ak váš BASIC, ktorý si chcete nahrať pri výpise tapky (príkazmi CAT, COPY) má číslo 5, tak na jeho nahratie stačí zadať LOAD 5 (akákoľvek podobnosť so systémom BS-DOS známom zo ZX-Spectra je samozrejme čisto náhodná... ;).


Vstavaná skúšobná tapka

Súčasťou tape emulátora je kratučká tapka so štyrmi ukážkovými súbormi pre vyskúšanie tape emulátora:

  • HelloWorld ... kratučký jednoriadkový BASIC: 9999 PRINT "Hello world !"
  • DIM n(4)' ... štvorprvkové číselné pole naplnené rôznymi hodnotami
  • DIM t$(12)' ... reťazec o dĺžke 12 znakov s textom "Hello world"
  • CODE 49152,16 ... blok bajtov 00 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF

Jednotlivé súbory je možné vymazať príkazom ERASE a tým získať miesto pre ukladanie príkazom SAVE, ale ak chcete súbory ukladať, je lepšie si zadefinovať nový vlastný buffer pre tapku.

Ukladanie dát do tapky


Aby ste vôbec mohli niečo ukladať, je potrebné mať v bufferi pre tapku voľné miesto. Voľné miesto pre ukladanie je priestor od konca tapky až po koniec buffera, popr. celý buffer, ak v ňom žiadnu tapku ešte nemáte.

Ak v bufferi už máte nejakú tapku, príkaz SAVE pripojí ukladaný blok vždy na koniec tejto tapky. Pred samotným uložením sa ešte skontroluje, či je v bufferi dostatok miesta pre uloženie nového bloku. V prípade, že nie je (a teda tapka by pretiekla), blok sa neuloží a vypíše sa štandardné chybové hlásenie 'Out of memory'.

Koniec tapky a prípadné nasledujúce voľné miesto v bufferi sa pozná podľa nulovej dĺžky nasledujúceho TAP bloku. To znamená, že keď si do pamäti (svojpomocne) nahráte nejakú tapku a v pamäti za ňou nie sú aspoň dva nulové bajty, je potrebné tieto dva bajty pre istotu vynulovať, aby sa predišlo prípadu, že nasledujúce bajty (ak majú vhodné hodnoty) budú vyhodnotené, ako ďalší platný blok v tapke.

Pri mazaní blokov príkazom ERASE sa dva bajty za novým koncom tapky automaticky vynulujú.

Príklad použitia

Keďže praktický postup je častokrát oveľa lepší ako teoretické definície, tu je maličký návod ako nahrať nejaký existujúci program do pamäte PMD 85 a následne, ako z pamäte dostať niečo, čo sme si uložili príkazom SAVE.

  1. Vezmeme *.TAP súbor s našim programom. Povedzme, že súbor je dlhý 2000 bajtov.
  2. Nahráme do PMD 85 ZX ROMku a spustíme od adresy 0. Prebehne úvodná inicializácia.
  3. Povedzme, že tapku sa rozhodneme v pamäti PMD 85 umiestniť na adresu 30000.
    Preto si príkazom CLEAR 29999 nastavíme, aby nám BASIC do tejto oblasti pamäti nijak nezasahoval.
  4. Teraz nahráme náš TAP súbor do pamäti na adresu 30000.
    To môžeme urobiť buď v emulátore pomocou dialógu "Nahratie bloku pamäti", alebo na reálnom PMD 85 môžeme pomocou OUT 247,9: RANDOMIZE USR 32768 vyskočiť do Monitora, urobiť tam nahratie bloku a následne sa vrátiť do ZX ROM pomocou JUMP 0005.
  5. Za tapkou nahranou do pamäti, v našom prípade na adrese 32000, by mali byť aspoň dva nulové bajty. Pokiaľ sme nič veľké predtým nerobili, mali by tam už byť (ZX ROMka pri studenom štarte pamäť nuluje), ale ak nie, tak ich (pre istotu) môžeme vynulovať my príkazmi POKE 32000,0: POKE 32001,0.
    V prípade, že žiadnu tapku z externého zdroja nahrávať nechceme a chceme mať celý buffer k dispozícii pre SAVE, stačí vynulovať prvé dva bajty buffera (ak už nulové nie sú) príkazmi POKE 30000,0: POKE 30001,0.
  6. Teraz príkazom FORMAT 30000,2500 oznámime tape emulátoru, že od adresy 30000 leží naša tapka, z ktorej má nahrávať bloky a zároveň mu tým povieme, že za tapkou je až po adresu 32500 voľne miesto, kam tape emulátor môže ukladať bloky, ktoré v budúcnosti uložíme príkazom SAVE.
    Týmto máme všetko pripravené a môžeme veselo používať všetky magnetofónové príkazy LOAD SAVE VERIFY MERGE a zároveň pracovať s tapkou príkazmi CAT COPY MOVE ERASE.
  7. Ak sme do tapky niečo pridali príkazom SAVE a chceme to uložiť na externé médium, pomocou hodnoty U:xxxxx vypísanej v príkazoch CAT alebo COPY si zistíme koľko práve zaberá tapka v tape bufferi a presne toľko bajtov od začiatku tape buffera uložíme na externé médium. V prípade, že starú tapku ukladať nechceme, čiže chceme uložiť len nové bloky (tie ktoré sme si uložili príkazom SAVE) a žiadne bloky sme nemazali, postačí ak uložíme novú časť tapky od adresy, kde končí stará tapka. V našom príklade to bude adresa 32000 (keďže stará tapka bola dlhá 2000 bajtov).

Na modeloch PMD 85 s AllRAM režimom môžeme samozrejme pre tap buffer využiť adresy až po začiatok VideoRAM na 0C000h. Berte však do úvahy to, že po vyskočení do Monitora nebude potom tapka dostupná, lebo bude prekrytá práve pristránkovaným Monitorom.

Alternatívny spôsob načítania a uloženia dlhých BASICov

V prípade, že potrebujeme pracovať s BASIC programom tak dlhým, že sa nám do pamäti aj s príslušnou tapkou už nevojde, môžeme použiť tento špeciálny spôsob práce.

Aj v tomto prípade pracujeme s tapkou, avšak tapka nie je uložená v tap bufferi nad RAMTOPom, ale v reťazcovej premennej v BASICu. Pri loadnutí BASICového programu sa reťazcová premenná zmaže a s ňou prestane existovať aj tapka a pri uložení programu do tapky sa tento program v pamäti nahradí jednou reťazcovou premennou, ktorá bude obsahovať tapku s týmto programom.

  • Výhoda:: Tento spôsob umožňuje nahrávať a ukladať BASIC programy takmer tak dlhé, ako je celé voľne miesto v BASIC systéme. V AllRAM režime je to až cca 27500 bajtov.
  • Nevýhoda:: Loadnutím programu tapka prestane v pamäti existovať, nie je preto možné takto nahrávať programy s dohrávacími blokmi (napr. keď si BASIC dohraje blok s UDG).

Ovládacie príkazy (a jedna funkcia):

  • RUN a$ - nahratie (a prípadne spustenie) BASICu z tapky uloženej v prememnej a$
  • STOP a$,"Meno" <LINE autostart> - uloženie BASICu s premennými do tapky a uloženie tapky do premennej a$
  • PEEK a$ - vráti adresu, kde v pamäti začínajú dáta v premennej a$

Namiesto a$ je samozrejme možné použiť akúkoľvek inú reťazcovú premennú, či už klasickú, deklarovanu príkazom LET alebo dimenzovanú príkazom DIM.

Nahratie BASICu príkazom RUN a$ urobí presne to isté, ako príkaz LOAD "". Vezme premennú a$ (popr. akúkoľvek inú zadanú reťazcovú premennú), nájde v premennej tapku, v tapke nájde prvý BASIC program a ten nahrá do pamäti. V prípade, že BASIC má autoštart, tak sa aj hneď spustí. Reťazcová premenná s tapkou sa nahraním BASICu vymaže. Tapka nemusí začínať od začiatku premennej, systém si tapku v premennej nájde sám podľa úvodného bajtu 13h (nižší bajt dĺžky bloku s hlavičkou). Je teda možné si najprv pomocou DIM vytvoriť dostatočne dlhú premennú a kamkoľvek do nej nahrať tapku (začínajúcu hlavičkou) z externého médiá.

Možné chybové hlásenia:

  • Invalid argument - reťazcová premenná neobsahuje tapku
  • Invalid I/O stream - tapka neobsahuje BASIC alebo je poškodená
  • Tape loading error - hlavička je v poriadku, ale je poškodené telo BASICu

Príkaz STOP funguje presne ako SAVE - zabalí BASIC do tapky pod zadaným menom (v prípade, že za menom nasleduje LINE tak BASICu nastaví štartovací riadok), vytvorí zadanú reťazcovú premennú a uloží do nej tapku s BASICom. Dĺžka reťazcovej premennej sa nastaví presne na veľkosť tapky.

Z hľadiska užívateľa BASIC program a jeho premenné zmiznú a v systéme zostane, ako jediná, iba zadaná reťazcová premenná obsahujúca tapku s BASICom. Užívateľ si potom pomocou funkcii PEEK a LEN môže zistiť adresu a dĺžku tapky (napr. PRINT PEEK a$,LEN a$) a uložiť si ju na svoje externé médium.

Na začiatku bola spomenutá nevýhoda, že tento spôsob nie je vhodný pre nahrávanie programov, ktoré si okrem BASICu potrebujú dohrať nejaké ďalšie bloky (dáta, code...). Túto nevýhodu je možné čiatočne eliminovať rozdelením tapky na samotný (dlhý) BASIC a (krátky) zvyšok tapky s dohravanými blokmi. Tapku s BASICom umiestnime do reťazcovej premennej a zvyšok tapky umiestníme do klasického tape buffera niekde nad RAMTOPom. V takomto prípade si po spustení BASICu z reťazcovej premennej tento BASIC následne príkazmi LOAD bude môcť dohrať ďalšie potrebné bloky klasickým spôsobom cez štandardný tape emulátor.


Postup pre načítanie dlhého BASICu:

  1. Vezmeme tapku s našim programom. Povedzme, že celá tapka je dlhá 22000 bajtov.
  2. Príkazom DIM t$(22000) vytvoríme reťazcovu premennú.
  3. Príkazom PRINT PEEK t$,LEN t$ si zistíme, kde v pamäti sú dáta premennej t$. Príkaz nám vypíše adresu a dĺžku týchto dát. Dĺžka by samozrejme mala byť 22000.
  4. Od zistenej adresy nahráme do pamäti našu tapku z externého média.
  5. Príkazom RUN t$ nahráme (a popr. spustíme) BASIC program (aj s jeho prípadnými premennými) z našej tapky do pamäte.

Postup pre uloženie dlhého BASICu:

  1. Príkazom STOP t$,"Meno" LINE 10 uložíme program s autoštartom na riadku 10. Program z pamäti zmizne a vytvorí sa premenná t$, obsahujúca tapku s programom. Keď autoštart nepotrebujeme, môžeme LINE s číslom riadku vynechať.
  2. Príkazom PRINT PEEK t$,LEN t$ si zistíme, kde presne v pamäti leží naša novovytvorená tapka a aká je dlhá.
  3. Tapku si uložíme na externé médium.

screenshoty

listing BASIC programu
listing BASIC programu
zobrazenie katalógu tape emulátora a použitie príkazu ?
zobrazenie katalógu tape emulátora a použitie príkazu ?