Difference between revisions of "EXOS kompatibilis memóriakezelés"

From Enterprise Wiki
Jump to: navigation, search
(Fix szegmensek használata szabályosan)
m (Bevezetés)
 
(3 intermediate revisions by 2 users not shown)
Line 1: Line 1:
 
=Bevezetés=
 
=Bevezetés=
 
Az ENTERPRISE a maga korában, sőt talán a 8 bites gépek történetében nézve összességében is egyedülálló módon rugalmasan bővíthetőre lett megtervezve, így pl a maximálisan kezelhető memória méret az akkoriban szinte elképzelhetetlen 4 megabájtban lett meghatározva.
 
Az ENTERPRISE a maga korában, sőt talán a 8 bites gépek történetében nézve összességében is egyedülálló módon rugalmasan bővíthetőre lett megtervezve, így pl a maximálisan kezelhető memória méret az akkoriban szinte elképzelhetetlen 4 megabájtban lett meghatározva.
Mindez ráadásul nagyon tisztán, áttekinthetően lett megoldva: a Z80 64K-s címtartományát felosztjuk 4 db 16K-s lapra, a 4 megabájtot pedig 256 db 16K-s szegmensre. És bármelyik szegmenst belapozhatjuk bármelyik lapra, sőt még azt is megtudhatjuk, hogy melyik lapra melyik szegmens lett belapozva. Sok más gépen csak irigykedni lehet egy ilyen egyszerűen használható rendszerre, majd egyszer a Spectrum programok átírása kapcsán részletezem, hogy milyen "barkácsolással" lett a Spectrum 48-ból 128-as gép, ill. milyen további ronda barkácsolásokkal érték el az oroszok, hogy 256K esetleg 1 mega memória használatát... de a szocialista kistestvér, azaz a TVC esetén is jelentősen lebutítani és egyben bonyolítani a rendszert, csak, hogy pár logikai kaput megspóroljanak...
+
Mindez ráadásul nagyon tisztán, áttekinthetően lett megoldva: a Z80 64K-s címtartományát felosztjuk 4 db 16K-s lapra, a 4 megabájtot pedig 256 db 16K-s szegmensre. És bármelyik szegmenst belapozhatjuk bármelyik lapra, sőt még azt is megtudhatjuk, hogy melyik lapra melyik szegmens lett belapozva. Sok más gépen csak irigykedni lehet egy ilyen egyszerűen használható rendszerre - majd egyszer a Spectrum programok átírása kapcsán részletezem, hogy milyen "barkácsolással" lett a Spectrum 48-ból 128-as gép, ill. milyen további ronda barkácsolásokkal érték el az oroszok 256K, esetleg 1 mega memória használatát... de a szocialista kistestvér, azaz a TVC esetén is jelentősen lebutítani és egyben bonyolítani a rendszert, csak azért, hogy pár logikai kaput megspóroljanak...
  
  
Persze a hw lehetőség kevés, kell mindehhez egy olyan operációs rendszer, ami mindezt tudja kezelni, kihasználni. Szerencsére mi egy igazán remek rendszert kaptunk, amely teljességgel rászolgált az Enterprise eXtendable Operating System névre!
+
Persze a hardware lehetőség kevés, kell mindehhez egy olyan operációs rendszer, ami mindezt tudja kezelni, kihasználni. Szerencsére mi egy igazán remek rendszert kaptunk, amely teljességgel rászolgált az Enterprise eXtendable Operating System névre!
Az EXOS feladata az aktuális konfiguráció felderítése, a használható memória leltárba vétele, majd pedig a felhasználói programok ill. különböző rendszer összetevők által támasztott memóriaigények kiszolgálása, nyílvántartás vezetése az aktuálisan foglalt ill. szabad memória területekről.
+
Az EXOS feladata az aktuális konfiguráció felderítése, a használható memória leltárba vétele, majd pedig a felhasználói programok ill. különböző rendszer összetevők által támasztott memóriaigények kiszolgálása, nyilvántartás vezetése az aktuálisan foglalt ill. szabad memória területekről.
 
 
 
Akárcsak egy mai modern operációs rendszer esetén!
 
Akárcsak egy mai modern operációs rendszer esetén!
  
A kortárs gépeken nem is igazán lehet operációs rendszerről beszélni, memóriakezelés is gyakorlatilag csak a BASIC interpreteren belül létezik, változók stb-k nyilvántartása. Így pl egy Spectrum program se tudhatja meg rendszerszinten, hogy 48-as, 128-as vagy netán egy orosz Scorpion 256-os gépen fut.
+
A kortárs gépeken nem is igazán lehet operációs rendszerről beszélni, memóriakezelés is gyakorlatilag csak a BASIC interpreteren belül létezik, változók, stb.-k nyilvántartása. Így pl. egy Spectrum program se tudhatja meg rendszerszinten, hogy 48-as, 128-as vagy netán egy orosz Scorpion 256-os gépen fut.
Itt ha nem érdekel minket a BASIC, gyakorlatilag nincs semmi más amire figyelni kéne, ráadásul minden fix, és változatlan, a képernyő memória is teljesen rögzített helyen van, semmi akadálya a "POKE-PEEK" stílusú programozásnak
+
Itt, ha nem érdekel minket a BASIC, gyakorlatilag nincs semmi más, amire figyelni kéne, ráadásul minden fix, és változatlan, a képernyő memória is teljesen rögzített helyen van, semmi akadálya a "POKE-PEEK" stílusú programozásnak.
 
Enterprise esetén egyrészt alapból is több többé-kevésbé különböző géptípus került kiadásra (64, 128, EXOS 2.0 és 2.1, angol és német), másrészt a különböző bővítésekkel számtalanra növekedett a különböző létező konfigurációk száma.
 
Enterprise esetén egyrészt alapból is több többé-kevésbé különböző géptípus került kiadásra (64, 128, EXOS 2.0 és 2.1, angol és német), másrészt a különböző bővítésekkel számtalanra növekedett a különböző létező konfigurációk száma.
  
  
Sajnos a cég sikertelensége azzal is járt, hogy nem volt hivatalos támogatás, oktatás, cikkek, könyvek, arra vonatkozóan, hogy ezt a kitűnő rendszert hogyan is kell helyesen kihasználni, hogyan kell megfelelően programozni. Így a géppel foglalkozó programozók leginkább a más gépeken megszokott fix környezetet használó stílust vették át, az elérhető dokumentációkból csak annyit hasznosítva, hogy egyes fix(nek gondolt) pontokat megkeressék. Ez nálunk különösen jellemző volt, egyrészt mivel a legjobban eltérő EP64-es nálunk nem került forgalomba, másrészt a hivatalos dokumentációk is csak késve és nem túl jó minőségben fordítva jelentek meg. Ráadásul a megjelent könyvek, cikkek nagyrésze is ezt a fix memória konfigurációs "POKE-PEEK" stílust hirdette.
+
Sajnos a cég sikertelensége azzal is járt, hogy nem volt hivatalos támogatás, oktatás, cikkek, könyvek, arra vonatkozóan, hogy ezt a kitűnő rendszert hogyan is kell helyesen kihasználni, hogyan kell megfelelően programozni. Így a géppel foglalkozó programozók leginkább a más gépeken megszokott fix környezetet használó stílust vették át, az elérhető dokumentációkból csak annyit hasznosítva, hogy egyes fix(nek gondolt) pontokat megkeressék. Ez nálunk különösen jellemző volt, egyrészt mivel a legjobban eltérő EP64-es nálunk nem került forgalomba, másrészt a hivatalos dokumentációk is csak késve és nem túl jó minőségben fordítva jelentek meg. Ráadásul a megjelent könyvek, cikkek nagy része is ezt a fix memória konfigurációs "POKE-PEEK" stílust hirdette.
  
  
 
Milyen problémák adódnak ebből?
 
Milyen problémák adódnak ebből?
* az anno hírhedt angol-német gépek közötti inkompatibilitás, mind ennek volt köszönhető. Ez különösen a BASIC-gépi kód keverék programokra volt jellemző. Ennek köszönhető sok össsze-vissza barkácsolt, kapcsolóval megspékelt cartridge...
+
* az anno hírhedt angol-német gépek közötti inkompatibilitás mind ennek volt köszönhető. Ez különösen a BASIC-gépi kód keverék programokra volt jellemző. Ennek köszönhető sok össze-vissza barkácsolt, kapcsolóval megspékelt cartridge...
* olyan programok amik nem futnak memóriabővítővel ellátott gépen (ha jól emlékszem a Jano féle átíratok élen jártak ebben...)
+
* olyan programok, amik nem futnak memóriabővítővel ellátott gépen (ha jól emlékszem- a Jano-féle átíratok élen jártak ebben...)
* olyan programok amik összeakadnak egyes ROM bővítésekkel
+
* olyan programok, amik összeakadnak egyes ROM bővítésekkel
* külön kiemelve, hogy volt olyan is, ami a közismert TAPE: problémán túl se mentek lemezes géppel, mert egész egyszerűn beleírt az EXDOS-nak kiutalt területbe. Ezek ugyan már át lettek bütykölve, de a dolog most fokozottan megismétlődik a vinyóvezérlővel, hiszen itt még több terület lesz lefoglalva a rendszerszegmensben, és itt különösen nem egészséges ha beleírunk a lefoglalt memóriába, akár nagyobb adatvesztés is lehet a vége!
+
* külön kiemelve, hogy volt olyan is, ami a közismert TAPE: problémán túl se mentek lemezes géppel, mert egész egyszerűn beleírt az EXDOS-nak kiutalt területbe. Ezek ugyan már át lettek bütykölve, de a dolog most fokozottan megismétlődik a vinyóvezérlővel, hiszen itt még több terület lesz lefoglalva a rendszerszegmensben, és itt különösen nem egészséges, ha beleírunk a lefoglalt memóriába, akár nagyobb adatvesztés is lehet a vége!
  
A "Világ EP tulajdonosai egyesüljetek" mozgalmunk keretében került előtérbe az a probléma, hogy a létező EP programok kb 98%-a nem fut EP64-en, annak ellenére, hogy jelentős részük fizikailag beférne a 64K-ba! És hiába vesz mondjuk egy MICROTEAM kártyát az EP64 tulajdonos, az így 576K-ra növelt memóriával se fog futni a 128-as programoknak még mindig vagy 96%-a... mivel az F8-FB szegmensek nem léteznek egy ilyen gépen. (Sajnos az ep128emu egyik hiányossága, hogy ilyen "lukas" memória konfigurációkat nem lehet emulálni, ezt csak EP32-ben lehet megcsinálni.) F8-FB szegmensek megvalósítása után még mindig sok programnak gondot okozna az EXOS 2.0
+
A "Világ EP tulajdonosai egyesüljetek" mozgalmunk keretében került előtérbe az a probléma, hogy a létező EP programok kb 98%-a nem fut EP64-en, annak ellenére, hogy jelentős részük fizikailag beférne a 64K-ba! És hiába vesz mondjuk egy MICROTEAM kártyát az EP64 tulajdonos, az így 576K-ra növelt memóriával se fog futni a 128-as programoknak még mindig vagy 96%-a... mivel az F8-FB szegmensek nem léteznek egy ilyen gépen. (Sajnos az Ep128emu egyik hiányossága, hogy ilyen "lukas" memória konfigurációkat nem lehet emulálni, ezt csak EP32-ben lehet megcsinálni.) F8-FB szegmensek megvalósítása után még mindig sok programnak gondot okozna az EXOS 2.0.
  
  
 
És amire nem került sor, de hatalmas balhé lett volna: ha kijött volna a tervezett szuper EP az EXOS 3.0-val, várhatóan szintén rengeteg program nem működött volna vele...
 
És amire nem került sor, de hatalmas balhé lett volna: ha kijött volna a tervezett szuper EP az EXOS 3.0-val, várhatóan szintén rengeteg program nem működött volna vele...
 
Szintén lettek volna problémák, ha anno kiadják a vinyóvezérlőt (amit az eladatlan SZJA '88 készletek miatt visszatartottak...)
 
Szintén lettek volna problémák, ha anno kiadják a vinyóvezérlőt (amit az eladatlan SZJA '88 készletek miatt visszatartottak...)
 
  
 
=Fix szegmensek használata szabályosan=
 
=Fix szegmensek használata szabályosan=
Line 141: Line 139:
 
Egy lehetséges módszer, például foglaljunk le 4 szegmenst:
 
Egy lehetséges módszer, például foglaljunk le 4 szegmenst:
  
[code=z80]
+
                LD HL,RAMLISTA
                LD HL,RAMLISTA
+
                LD A,4
                LD A,4
+
FOGLAL          EX AF,AF'         
FOGLAL          EX AF,AF'         
+
                EXOS 24
                EXOS 24
+
                JP NZ,HIBA
                JP NZ,HIBA
+
                LD (HL),C
                LD (HL),C
+
                INC HL
                INC HL
+
                EX AF,AF'
                EX AF,AF'
+
                DEC A
                DEC A
+
                JR NZ,FOGLAL
                JR NZ,FOGLAL[/code]
+
 
Késöbb pedig pl a 3. szegmensre így hivatkozhatunk:
+
Később pedig pl. a 3. szegmensre így hivatkozhatunk:
[code=z80]
+
 
                LD A,(RAMLISTA+2)
+
                LD A,(RAMLISTA+2)
                OUT (0B3H),A
+
                OUT (0B3H),A
[/code]
 
  
 
Itt megemlítem azt is, hogy a Spectrum Világ cikksorozatának az elején, amikor a Spectrum kazetta beolvasó programot tárgyalják, még a helyes memóriakezelésről van szó:Sajnos a gyakorlati megvalósításba becsúszott egy kis hiba:
 
Itt megemlítem azt is, hogy a Spectrum Világ cikksorozatának az elején, amikor a Spectrum kazetta beolvasó programot tárgyalják, még a helyes memóriakezelésről van szó:Sajnos a gyakorlati megvalósításba becsúszott egy kis hiba:
[code=z80]          EXOS 24            ;Egy 16 kbyte meretu RAM szegmens lefoglalasa
+
 
          LD A,C            ;es belapozasa
+
          EXOS 24            ;Egy 16 kbyte meretu RAM szegmens lefoglalasa
          OUT (0B1H),A      ;az 1. lapra (4000H-7FFFH cimtartomany)
+
          LD A,C            ;es belapozasa
          EXOS 24            ;Meg ket szegmens lefoglalasa
+
          OUT (0B1H),A      ;az 1. lapra (4000H-7FFFH cimtartomany)
          LD A,C            ;es belapozasa
+
          EXOS 24            ;Meg ket szegmens lefoglalasa
          OUT (0B2H),A      ;Ezekre fog toltodni a program
+
          LD A,C            ;es belapozasa
          EXOS 24
+
          OUT (0B2H),A      ;Ezekre fog toltodni a program
          OUT (0B3H),A
+
          EXOS 24
[/code]
+
          OUT (0B3H),A
 +
 
 
Kimaradt a hibakezelés, így kevés memória esetén, hiába szól az EXOS, hogy elfogyott, a program nem veszi észre, és hibásan fog működni.
 
Kimaradt a hibakezelés, így kevés memória esetén, hiába szól az EXOS, hogy elfogyott, a program nem veszi észre, és hibásan fog működni.
  
 
Ezzel a sima szegmens igényléses módszerrel már remekül el lehet lenni, ha nincs szükségünk képernyő kezelésre, ill. ha megoldjuk az EXOS videó kezelőjén keresztül. Ha viszont magunk akarjuk a képet létrehozni, saját LPT táblával, ahhoz saját videó szegmens(ek)re lesz szükségünk!
 
Ezzel a sima szegmens igényléses módszerrel már remekül el lehet lenni, ha nincs szükségünk képernyő kezelésre, ill. ha megoldjuk az EXOS videó kezelőjén keresztül. Ha viszont magunk akarjuk a képet létrehozni, saját LPT táblával, ahhoz saját videó szegmens(ek)re lesz szükségünk!
Itt kezdődnek a bonyadalmak...
+
Itt kezdődnek a bonyodalmak...
 
 
  
 
=Mi is a bonyodalom a videószegmensekkel?=
 
=Mi is a bonyodalom a videószegmensekkel?=
Line 207: Line 204:
 
=Gyakorlatiasabb részek=
 
=Gyakorlatiasabb részek=
 
Folytassuk a "mesedélutánt" :-) némi gyakorlatiasabb részekkel, Povi már biztos nagyon várja :-)
 
Folytassuk a "mesedélutánt" :-) némi gyakorlatiasabb részekkel, Povi már biztos nagyon várja :-)
Én ezt a rutin használom a Spectrum átirat betöltőimben videó szegmens igénylésre:
+
Én ezt a rutint használom a Spectrum átirat betöltőimben videó szegmens igénylésre:
[code=z80]VID            LD HL,VEGE
+
 
                LD (HL),0
+
;video-szegmens igénylő rutin
KER            EXOS 24
+
;bemenet: nincs
                JR Z,NAMIVAN
+
;kimenet: C-ben a kapott szegmens száma
                CP 7FH
+
;        A=0, ha teljes szegmenst kapunk
                JP NZ,HIBA
+
          A=07FH, ha megosztott szegmenst kapunk
NAMIVAN        EX AF,AF'
+
          HL=VEGE-1
                LD A,C
+
 
                CP 0FCH
+
VID            LD HL,VEGE
                JR NC,NEMKER
+
                LD (HL),0
                INC HL
+
KER            EXOS 24       ;szegmens igénylése
                LD (HL),C
+
                JR Z,NAMIVAN   ;ha sikerült, akkor ugrás a NAMIVAN-ra
                JR KER
+
                CP 07FH        ;megosztott szegmenst kaptunk?
NEMKER          EX AF,AF'
+
                JP NZ,HIBA     ;ha nem, akkor ugrás a HIBA-ra
                PUSH BC
+
NAMIVAN        EX AF,AF'
                PUSH AF
+
                LD A,C
VISSZA          LD C,(HL)
+
                CP 0FCH       ;a kapott szegmens>=0FCH?
                EXOS 25
+
                JR NC,NEMKER   ;ha igen, akkor nem kell többet igényelni, ugrás a NEMKER-re
                DEC HL
+
                INC HL
                JR Z,VISSZA
+
                LD (HL),C
                POP AF
+
                JR KER
                POP BC
+
NEMKER          EX AF,AF'
                OR A
+
                PUSH BC
                RET[/code]
+
                PUSH AF
 +
VISSZA          LD C,(HL)
 +
                EXOS 25
 +
                DEC HL
 +
                JR Z,VISSZA
 +
                POP AF
 +
                POP BC
 +
                OR A
 +
                RET
 +
 
 
A rutin a VEGE címtől (amely logikusan a programkód után helyezkedik el) tárolja el a felesleges szegmenseket. Miután akadt egy (amely lehet megosztott is), a felesleget visszaadja az EXOS-nak.
 
A rutin a VEGE címtől (amely logikusan a programkód után helyezkedik el) tárolja el a felesleges szegmenseket. Miután akadt egy (amely lehet megosztott is), a felesleget visszaadja az EXOS-nak.
 
Először a képernyőnek kérünk egy teljes szegmenst:
 
Először a képernyőnek kérünk egy teljes szegmenst:
[code=z80]                CALL VID
+
 
 +
                CALL VID
 
                 JP NZ,HIBA
 
                 JP NZ,HIBA
 
                 LD A,C
 
                 LD A,C
Line 245: Line 252:
 
                 RRA
 
                 RRA
 
                 RR D
 
                 RR D
                 LD (VIDCIM1),DE[/code]
+
                 LD (VIDCIM1),DE
 +
 
 
A kapott szegmensszámból kiszámoljuk a terület kezdetének címét, erre késöbb az LPT generáláskor szükség lesz.
 
A kapott szegmensszámból kiszámoljuk a terület kezdetének címét, erre késöbb az LPT generáláskor szükség lesz.
 
Késöbb kérünk egy LPT szegmenst is, ami lehet megosztott is, ha elfér benne az LPT tábla (azaz az EXOS határ beállítható a megfelelő helyre.)
 
Késöbb kérünk egy LPT szegmenst is, ami lehet megosztott is, ha elfér benne az LPT tábla (azaz az EXOS határ beállítható a megfelelő helyre.)
[code=z80]                CALL VID
+
 
                JR Z,NEMHIBA
+
                CALL VID
                CP 7FH
+
                JR Z,NEMHIBA
                JP NZ,HIBA
+
                CP 7FH
                LD DE,200*16
+
                JP NZ,HIBA
                EXOS 23
+
                LD DE,200*16
                JP NZ,HIBA
+
                EXOS 23
                LD C,255
+
                JP NZ,HIBA
NEMHIBA        LD A,C
+
                LD C,255
                LD (LPTS),A
+
NEMHIBA        LD A,C
NEMHIBA1        LD DE,(VIDCIM2)
+
                LD (LPTS),A
                LD HL,0
+
NEMHIBA1        LD DE,(VIDCIM2)
                RRA
+
                LD HL,0
                RR H
+
                RRA
                RRA
+
                RR H
                RR H
+
                RRA
                ADD HL,DE
+
                RR H
                LD (VIDCIM2),HL[/code]
+
                ADD HL,DE
 +
                LD (VIDCIM2),HL
 +
 
 
Itt is kiszámoljuk a videó címet, ezúttal az LPT tábla kezdetét. A figyelmes szemlélő észreveheti, hogy itt még játékba áll a VIDCIM2-n korábban lévő érték. Ez alapban nulla, viszont 64K-s gépen úgy fog átrendeződni a memória, hogy nem a szegmens elejére kerül az LPT tábla, ekkor a szükséges eltolás mértéke került már ekkora a VIDCIM2-re.
 
Itt is kiszámoljuk a videó címet, ezúttal az LPT tábla kezdetét. A figyelmes szemlélő észreveheti, hogy itt még játékba áll a VIDCIM2-n korábban lévő érték. Ez alapban nulla, viszont 64K-s gépen úgy fog átrendeződni a memória, hogy nem a szegmens elejére kerül az LPT tábla, ekkor a szükséges eltolás mértéke került már ekkora a VIDCIM2-re.
 
Ezekután nézzük meg, hogyan változik a SpV-ban is közölt LPT generáló rutin, ime az eredeti rutin kezdete:
 
Ezekután nézzük meg, hogyan változik a SpV-ban is közölt LPT generáló rutin, ime az eredeti rutin kezdete:
[code=z80]        LD A,0FCH
+
 
 +
        LD A,0FCH
 
         OUT (0B1H),A
 
         OUT (0B1H),A
 
         LD A,192
 
         LD A,192
Line 276: Line 287:
 
         LD HL,4004H
 
         LD HL,4004H
 
         LD BC,13
 
         LD BC,13
[/code]
+
 
 
És ez lesz belőle:
 
És ez lesz belőle:
[code=z80]                LD A,(LPTS)
+
 
 +
                LD A,(LPTS)
 
                 OUT (0B1H),A
 
                 OUT (0B1H),A
 
                 LD A,192
 
                 LD A,192
Line 294: Line 306:
 
                 INC HL
 
                 INC HL
 
                 INC HL
 
                 INC HL
                 LD BC,13[/code]
+
                 LD BC,13
 +
 
 
A fix szegmensszám helyett az eltároltat használjuk. A DE fog mutatni az LPT elejére az 1-es lapon, de a korábban említett esetleges eltolás miatt ezt az LPT videócíméből számoljuk vissza 1-es lapi címre. Az EXX utáni DE a videó memóriánk kezdetére fog mutatni, ez az eredeti rutinban fix 4000H volt, mivel az FDH volt fixen erre a célra használva. A HL pedig szintén az LPT területre fog mutatni, 4 bájt eltolással, ő az LPT sorokba való címbeírásnál van használva.
 
A fix szegmensszám helyett az eltároltat használjuk. A DE fog mutatni az LPT elejére az 1-es lapon, de a korábban említett esetleges eltolás miatt ezt az LPT videócíméből számoljuk vissza 1-es lapi címre. Az EXX utáni DE a videó memóriánk kezdetére fog mutatni, ez az eredeti rutinban fix 4000H volt, mivel az FDH volt fixen erre a célra használva. A HL pedig szintén az LPT területre fog mutatni, 4 bájt eltolással, ő az LPT sorokba való címbeírásnál van használva.
 
Nem esett még szó az IX-ről, ő videó memóriánk címét tároló változóra mutat. Azért mert, még egy helyen hozzá kellett nyulni az eredeti rutinhoz, még pedig az attributtum címek kiszámolásánál:
 
Nem esett még szó az IX-ről, ő videó memóriánk címét tároló változóra mutat. Azért mert, még egy helyen hozzá kellett nyulni az eredeti rutinhoz, még pedig az attributtum címek kiszámolásánál:
[code=z80]        LD A,D
+
 
        RRA
+
        LD A,D
        RRA
+
        RRA
        RRA
+
        RRA
        AND 3
+
        RRA
        OR 58H
+
        AND 3
        LD (HL),A
+
        OR 58H
[/code]
+
        LD (HL),A
 +
 
 
Módosítva:
 
Módosítva:
[code=z80]                LD A,D
+
                LD A,D
 
                 RRA
 
                 RRA
 
                 RRA
 
                 RRA
Line 314: Line 328:
 
                 OR (IX+1)
 
                 OR (IX+1)
 
                 LD (HL),A
 
                 LD (HL),A
[/code]
+
 
 
Ezekután már csak az LPT aktiváló OUT utasításokat kell módosítani, az eredeti nagyon egyszerű, mivel a fix 0000H videó címet használja:
 
Ezekután már csak az LPT aktiváló OUT utasításokat kell módosítani, az eredeti nagyon egyszerű, mivel a fix 0000H videó címet használja:
[code=z80]        XOR A
+
        XOR A
 
         OUT (82H),A
 
         OUT (82H),A
 
         LD A,192
 
         LD A,192
 
         OUT (83H),A
 
         OUT (83H),A
[/code]
+
 
 
És módosítva, hogy a kiszámolt LPT címünket használja:
 
És módosítva, hogy a kiszámolt LPT címünket használja:
[code=z80]                XOR A
+
                XOR A
 
                 LD HL,VIDCIM2+1
 
                 LD HL,VIDCIM2+1
 
                 RRD
 
                 RRD
Line 332: Line 346:
 
                 OR 0C0H
 
                 OR 0C0H
 
                 RRD
 
                 RRD
                 OUT (83H),A[/code]
+
                 OUT (83H),A
 +
 
 
Megjegyzés, ez a módszer elrontja a VIDCIM2 változó értékét, de erre az adott esetben úgysincs többé szükség.
 
Megjegyzés, ez a módszer elrontja a VIDCIM2 változó értékét, de erre az adott esetben úgysincs többé szükség.
 
De itt egy másik módszer is, itt az eredeti EXOS LPT visszaállítására van használva:
 
De itt egy másik módszer is, itt az eredeti EXOS LPT visszaállítására van használva:
[code=z80]                LD HL,(0BFF4H)
+
                LD HL,(0BFF4H)
                SET 6,H
+
                SET 6,H
                LD B,4
+
                LD B,4
FORG4          SRL H
+
FORG4          SRL H
                RR L
+
                RR L
                DJNZ FORG4
+
                DJNZ FORG4
                LD A,L
+
                LD A,L
                OUT (82H),A
+
                OUT (82H),A
                LD A,H
+
                LD A,H
                OR 0C0H
+
                OR 0C0H
                OUT (83H),A[/code]
+
                OUT (83H),A
 +
 
 
A címet az EXOS LP_POINTER változójából olvassuk ki (tehát legyen belapozva a rendszerszegmens a 2. lapra), az utána következő SET 6 azért van, hogy videócímre konvertáljuk az EXOS változót, ha saját kiszámolt videócímünket használjuk, akkor erre nincs szükség.
 
A címet az EXOS LP_POINTER változójából olvassuk ki (tehát legyen belapozva a rendszerszegmens a 2. lapra), az utána következő SET 6 azért van, hogy videócímre konvertáljuk az EXOS változót, ha saját kiszámolt videócímünket használjuk, akkor erre nincs szükség.
 
  
 
=Hogyan lesz egy 48K-s átirat számára 3 szabadon használható szegmensünk 64K-s gépen, amikor csak kettő van szabadon, és még az LPT táblának is kéne egy?=
 
=Hogyan lesz egy 48K-s átirat számára 3 szabadon használható szegmensünk 64K-s gépen, amikor csak kettő van szabadon, és még az LPT táblának is kéne egy?=
 
Érdeklődés esetén folytatás várható
 
Érdeklődés esetén folytatás várható

Latest revision as of 23:23, 6 February 2009

Bevezetés

Az ENTERPRISE a maga korában, sőt talán a 8 bites gépek történetében nézve összességében is egyedülálló módon rugalmasan bővíthetőre lett megtervezve, így pl a maximálisan kezelhető memória méret az akkoriban szinte elképzelhetetlen 4 megabájtban lett meghatározva. Mindez ráadásul nagyon tisztán, áttekinthetően lett megoldva: a Z80 64K-s címtartományát felosztjuk 4 db 16K-s lapra, a 4 megabájtot pedig 256 db 16K-s szegmensre. És bármelyik szegmenst belapozhatjuk bármelyik lapra, sőt még azt is megtudhatjuk, hogy melyik lapra melyik szegmens lett belapozva. Sok más gépen csak irigykedni lehet egy ilyen egyszerűen használható rendszerre - majd egyszer a Spectrum programok átírása kapcsán részletezem, hogy milyen "barkácsolással" lett a Spectrum 48-ból 128-as gép, ill. milyen további ronda barkácsolásokkal érték el az oroszok 256K, esetleg 1 mega memória használatát... de a szocialista kistestvér, azaz a TVC esetén is jelentősen lebutítani és egyben bonyolítani a rendszert, csak azért, hogy pár logikai kaput megspóroljanak...


Persze a hardware lehetőség kevés, kell mindehhez egy olyan operációs rendszer, ami mindezt tudja kezelni, kihasználni. Szerencsére mi egy igazán remek rendszert kaptunk, amely teljességgel rászolgált az Enterprise eXtendable Operating System névre! Az EXOS feladata az aktuális konfiguráció felderítése, a használható memória leltárba vétele, majd pedig a felhasználói programok ill. különböző rendszer összetevők által támasztott memóriaigények kiszolgálása, nyilvántartás vezetése az aktuálisan foglalt ill. szabad memória területekről. Akárcsak egy mai modern operációs rendszer esetén!

A kortárs gépeken nem is igazán lehet operációs rendszerről beszélni, memóriakezelés is gyakorlatilag csak a BASIC interpreteren belül létezik, változók, stb.-k nyilvántartása. Így pl. egy Spectrum program se tudhatja meg rendszerszinten, hogy 48-as, 128-as vagy netán egy orosz Scorpion 256-os gépen fut. Itt, ha nem érdekel minket a BASIC, gyakorlatilag nincs semmi más, amire figyelni kéne, ráadásul minden fix, és változatlan, a képernyő memória is teljesen rögzített helyen van, semmi akadálya a "POKE-PEEK" stílusú programozásnak. Enterprise esetén egyrészt alapból is több többé-kevésbé különböző géptípus került kiadásra (64, 128, EXOS 2.0 és 2.1, angol és német), másrészt a különböző bővítésekkel számtalanra növekedett a különböző létező konfigurációk száma.


Sajnos a cég sikertelensége azzal is járt, hogy nem volt hivatalos támogatás, oktatás, cikkek, könyvek, arra vonatkozóan, hogy ezt a kitűnő rendszert hogyan is kell helyesen kihasználni, hogyan kell megfelelően programozni. Így a géppel foglalkozó programozók leginkább a más gépeken megszokott fix környezetet használó stílust vették át, az elérhető dokumentációkból csak annyit hasznosítva, hogy egyes fix(nek gondolt) pontokat megkeressék. Ez nálunk különösen jellemző volt, egyrészt mivel a legjobban eltérő EP64-es nálunk nem került forgalomba, másrészt a hivatalos dokumentációk is csak késve és nem túl jó minőségben fordítva jelentek meg. Ráadásul a megjelent könyvek, cikkek nagy része is ezt a fix memória konfigurációs "POKE-PEEK" stílust hirdette.


Milyen problémák adódnak ebből?

  • az anno hírhedt angol-német gépek közötti inkompatibilitás mind ennek volt köszönhető. Ez különösen a BASIC-gépi kód keverék programokra volt jellemző. Ennek köszönhető sok össze-vissza barkácsolt, kapcsolóval megspékelt cartridge...
  • olyan programok, amik nem futnak memóriabővítővel ellátott gépen (ha jól emlékszem- a Jano-féle átíratok élen jártak ebben...)
  • olyan programok, amik összeakadnak egyes ROM bővítésekkel
  • külön kiemelve, hogy volt olyan is, ami a közismert TAPE: problémán túl se mentek lemezes géppel, mert egész egyszerűn beleírt az EXDOS-nak kiutalt területbe. Ezek ugyan már át lettek bütykölve, de a dolog most fokozottan megismétlődik a vinyóvezérlővel, hiszen itt még több terület lesz lefoglalva a rendszerszegmensben, és itt különösen nem egészséges, ha beleírunk a lefoglalt memóriába, akár nagyobb adatvesztés is lehet a vége!

A "Világ EP tulajdonosai egyesüljetek" mozgalmunk keretében került előtérbe az a probléma, hogy a létező EP programok kb 98%-a nem fut EP64-en, annak ellenére, hogy jelentős részük fizikailag beférne a 64K-ba! És hiába vesz mondjuk egy MICROTEAM kártyát az EP64 tulajdonos, az így 576K-ra növelt memóriával se fog futni a 128-as programoknak még mindig vagy 96%-a... mivel az F8-FB szegmensek nem léteznek egy ilyen gépen. (Sajnos az Ep128emu egyik hiányossága, hogy ilyen "lukas" memória konfigurációkat nem lehet emulálni, ezt csak EP32-ben lehet megcsinálni.) F8-FB szegmensek megvalósítása után még mindig sok programnak gondot okozna az EXOS 2.0.


És amire nem került sor, de hatalmas balhé lett volna: ha kijött volna a tervezett szuper EP az EXOS 3.0-val, várhatóan szintén rengeteg program nem működött volna vele... Szintén lettek volna problémák, ha anno kiadják a vinyóvezérlőt (amit az eladatlan SZJA '88 készletek miatt visszatartottak...)

Fix szegmensek használata szabályosan

Akkor menjünk bele a részletekbe, először egy kis összefoglaló: Van 4MB címtartományunk, ez fel van osztva 256 db 16K-s szegmensre. Meglepő módon :-) 0-255-ig számozzuk őket, hexában 00-FF Alapvetően bármelyik lehet RAM vagy ROM vagy maradhat üresen, kivéve amit maga az alaplap határoz meg: 00-03 az alaplapi ROM-hoz van rendelve, FC-FF pedig a szintén az alaplapi RAM-hoz, aminek kiemelt szerepe van, hiszen egyben a Nick chip által látott videómemória. 04-07 tartozik a cartridge foglalathoz, de itt akár RAM-ot is elhelyezhetünk. A 128-as gépekben helyett kapott egy plusz 64K-s bővítőpanel, ami F8-FB szegmenseket tartalmazza. Ami még nagyon elterjedt: a MICROTEAM kártya 512K bővítése a 40-5F területet foglalja el. 320K-ra bővített gépben pedig EC-FB található a bővítőpanelen. Itt érdekességként megjegyzem, hogy az egyik NASA&GUY demo (asszem valami Jean Michell Jarre digi zenét játszik), ilyen "EC-s" gépre íródott eredetileg, amin nagyon csodálkoztam anno, akkor még nem jelent meg az Enterpressben a 320K átalakítós cikk. És hiába volt MICROTEAM kártyával 640K-s gépem, mégse játszotta le a teljes zenét, hála a fix címes programozási stílusnak... aztán én meg átírtam, hogy a MICROTEAM kártyára eső szegmenseket használja, így végre meghallgathattam a teljes zenét :-)

Ha a RAM-ot nézzük, egy 64K-s gépben van FC-FF. 128-asban F8-FF. Ha a korábban emlegetett MICROTEAM+EP64 konfigot nézzük, akkor pedig 40-5F, FC-FF, ami darabra bőven jó, csak hiányzik az a bizonyos F8-FB, amire az EXOS-t nem használó 128-as gépen programozók által írt programok nagyrésze hivatkozik közvetlenül.

A helyes programozáshoz felejtsük is el ezeket a számokat, egyedül az FC-FF-et kell megjegyezni, kitüntetett videó memória mivoltuk miatt. A többiről csak annyit kell tudnunk, hogy nekünk hány darabra van szükségünk, a konkrét szegmensszámokat majd megmondja az EXOS!

Most nézzük az EXOS szerinti RAM felosztást: két szegmensnek van kitüntett szerepe, az egyik az FF ami a rendszerszegmens, és a legalacsonyabb sorszámú RAM szegmens ami a nulláslap szegmens. Itt található meg az EXOS hívások, ill a megszakítási program belépési pontja. És ide kerülnek 100H címtől töltve az 5-ös fejlécű programok is. Egy 128-as gépen az az F8 szegmens. De ha pl van egy MICROTEAM kártyánk, akkor már a 40-es lesz az. És ez máris gondot okoz sok programnak (általában a komplett módosított Spectrum ROM-ot tartalmazó béna átíratoknak)... De bővítős gépen is lehet F8 a nulláslap, ha VENUS-t használunk, ill. az EPDOS 2.1-nek is van ilyen lehetősége. Ez az eset meg egy másik adag programnak okoz gondot...

A maradék RAM négy csoportba tartozhat: rendszer, eszköz, felhasználói, szabad. Ha pl csatornákat nyitunk meg, különösen ha nagy RAM igénnyel járó videó lapokat, akkor az EXOS elkezd lefelé terjeszkedni, és ha kihízza az FF szegmenst, akkor további szegmensek válhatnak rendszer által lefoglalttá. A különböző beláncolt EXOS periféria kezelők által igényelt teljes RAM szegmensek az eszköz (device) kategóriában kerülnek lefoglalásra. Erre típikus példa a RAMDISK. Szintén ebben a kategóriába kerülnek lefoglalásra a betöltött rendszerbővítők által elfoglalt szegmensek is. És végül van az aktív felhasználói program, ez lehet egy rendszerbővítő vagy egy 5-ös fejléccel betöltött "új alkalmazói program". Az ezek által igényelt szegmensek a felhasználói kategóriában kerülnek lefoglalásra.

Ami nagyon fontos: a felhasználói program csak felhasználói szegmenst tud felszabadítani, eszköz vagy rendszer szegmens felszabadításához nincs joga!

És ezzel el is érkeztünk ahhoz a bizonyos Spectrum Világ-os hibás módszerhez:

       LD   C,0FAH
       EXOS 25
       LD   A,0FAH
       OUT  (0B2H),A

Egyrészt a szándék dicséretes, hiszen nem csak bumm belapozza a szegmenst, hanem szabaddá teszi... csak sajnos a nem túl sikeres fordítású EXOS leírást félreértelmezve :-( Mert az EXOS 25 hívás csak akkor lesz sikeres, ha elötte az a szegmens nekünk, azaz felhasználóiként ki lett utalva. Ha az FAH már mondjuk a RAMDISK része, vagy egy betöltött EXOS bővítő van ott, akkor mivel eszköz szegmensnek van lefoglalva, hibajelzést kapunk vissza, hogy a szegmens nem szabadítható fel. A program viszont ennek ellenére nyugodtan neki áll használni. És ott van még az a eset is, hogy nem is létezik ez a szegmens az adott konfigurációban, mert pl EP64-ről van szó... A helyes megoldás itt az, hogy kérünk kiutalni egy szegmenst az EXOS-tól, és azt használjuk. Ha hibajelzést kapunk vissza, mert elfogyott a szabad memória, akkor azt a programtól függő módon le kell kezelni (pl kilépés, vagy lehet folytatni korlátozott funkcionalitással a program futását)

       EXOS 24          ;szabad szegmens igénylése, kapott szegmens C-ben
       JP   NZ,HIBA     ;ha nincs szabad szegmens, akkor ugrás a HIBA-ra
       LD   A,C         
       OUT  (0B2H),A    ;kapott szegmens belapozása a 2-es lapra

Kicsit macerásabb, ha egy konkrét számú szegmensre vágyunk: ekkor ciklusban kell ismételgetni az EXOS 24 hívást, mindaddig amíg meg nem kapjuk a kívánt szegmenst, vagy pedig elfogy a memória, és ekkor megyünk a HIBA rutinra. De erre a módszerre új program írása esetén csak egy esetben lehet szükség: ha videó szegmensre van szükség. Ekkor addig ismételjük a hívást ameddig FC vagy nagyobb szegmenst nem kapunk. És akkor kell még ehhez a módszerhez folyamodni, ha egy régebbi fix címzéses programot akarunk kibővíteni úgy, hogy amit a program használ, az legyen szabályosan lefoglalva, mint ahogy ezt tettem tegnap a TUSKER-rel. Ez volt Attus eredeti rutinja, amely az SpV módszeren alapult:

                LD   BC,5FAH
SZABAD          PUSH BC
                EXOS 25
                POP  BC
                INC  C
                DJNZ SZABAD

Ebből kiderül, hogy az FA-tól kell nekünk 5 szegmens, ill. késöbb kiderült, hogy az LPT táblát az FF szegmens elejére helyezi el. És ime mindez helyesen:

FOGLAL          EXOS 24
                JP   NZ,HIBA
                LD   A,C
                CP   0F9H
                JR   NZ,FOGLAL
                LD   BC,5FAH
EZKELL          PUSH BC
                EXOS 24
                LD   A,C
                POP  BC
                CP   C
                JP   NZ,HIBA
                INC  C
                DJNZ EZKELL
                EXOS 24
                CP   7FH
                JP   NZ,HIBA
                LD   DE,3200
                EXOS 23
                JP   NZ,HIBA
                LD   L,0F9H
VISSZAAD        LD   C,L
                EXOS 25
                DEC  L
                JR   NZ,VISSZAAD

Az elején addig foglalunk, amíg az F9-ig el nem jutunk. Ha közben kifogyunk a memóriából, akkor ugrás a HIBA-ra. Ezután kérünk még 5 szegmenst, aminek FA,FB,FC,FD,FE-nek kell lennie, különben HIBA... És még egyet igényelünk, itt már csak az FF jöhet, és "megosztott szegmens" hibajelzést kell kapnunk (ez a 7F hibakód), különben hiba. És itt jön még egy fontos dolog: megosztott szegmens használata esetén meg kell mondanunk az EXOS-nak, hogy mi meddig akarunk terjeszkedni, erre szolgál az EXOS 23: felhasználói határ beállítása. Ha itt hibajelzést kapunk, akkor nincs annyi szabad hely amennyire nekünk szükségünk van, tehát ugrás a HIBA-ra. Ha minden ok, akkor egy nem túl szép, nem túl gyors, de egyszerű módszerrel visszaadjuk a felesleges szegmenseket. Vagyis F9-től lefelé mindet megpróbáljuk felszabadítani, úgyis csak az fog sikerülni amit felhasználónak utaltak ki :-) A teljesen korrekt megoldás természetesen az, ha az elején eltároljuk sorban a kapott felesleges szegmenseket, és ezen lista alapján szabadítunk itt fel. Erre akkor van szükség, ha az 5-ös fejlécű programunk már nem fér el a nulláslapon, mert ekkor a további programszegmensek is felhasználóiként kerülnek lefoglalásra, és ezzel a primitív módszerrel azokat is felszabadítanánk, pedig azt nem lenne szabad. A TUSKER betöltő esetén nincs ilyen gond, jó így is :-)


Konkrét szegmens igénylésére nincsen valami elegánsabb módszer?

Konkrét szegmens igénylésére nincsen valami elegánsabb módszer? Mert így szélsőséges esetben akár 249 szegmenst is lefoglalhatunk magunknak, míg végre megkapjuk pl. a hőn áhított FC szegmensünket. És akkor ezután még fel kell szabadítani a fölöslegesen lefoglalt szegmenseket is, hátha kellenek még azok valamire...

Sajnos nincs ez egy pici hiányosság az EXOS-ban. Jó lenne ha külön lehetne jelezni, hogy videó szegmenst szeretnénk kérni. Erre egyedül a periféria kezelő programon keresztül van lehetőség, ha videó periféria típust állítunk be.

Így jobb híján marad ez a ciklusos megoldás. Lehetséges még közvetlenül az EXOS rendszerterületeiben matatni, ezt több könyvben, cikkben tárgyalták is. De az ilyen programok máris elszállnak EXOS 2.0 esetén... esetleg meg lehetne írni külön két szubrutint EXOS 2.0 ill. 2.1 esetére. De mi van ha véletlenül mégis előkerül az a szuper EP, amit állítólag Kopácsy rejteget? Azon megint csak nem fognak futni az ilyen "kotorászós" programok... Szóval szerintem jobb maradni a szabályos megoldásnál, az a pár tizedmásodperc futásidő amibe legrosszabb esetén kerülhet, nem egy nagy veszteség a kompatibilitás oltárán.

Hol kezdődnek a bonyodalmak?

Ott tartunk, hogy szeretnénk megszabadulni a fix szegmensszámoktól, ily módon a különböző konfigurációkhoz maximálisan alkalmazkodó programot írni. Nézzük, mi a teendő, ha memóriára van szükségünk! Kezdetnek ott van a korábban emlegetett nulláslap. Ebből az EXOS a 0030-005BH területet használja, ill. az 5-ös fejlécű program ide kerül betöltésre 0100H címtől. A többi szabadon felhasználható az éppen aktív felhasználói program számára. Mint korábban már említettem, a nulláslap szegmensszáma különböző lehet a különböző konfigurációkban, az aktuális számot megtudhatjuk a B0H portról beolvasva, ill. a BFFCH címen lévő EXOS rendszerváltozó* is tartalmazza. Ez később még fontos lesz, amikor majd kicsit trükközünk a nulláslappal :-) , de alapesetben nem szokás piszkálni :-)

  • a rendszerváltózók címe úgy érvenyes, ha az FFH rendszerszegmens a 2. lapra van lapozva.


Nézzük tovább, mi van ha a nulláslap már nem elég, vagy nem felel meg az igényeinknek!

Nagyon egyszerű, kérünk további szegmenseket az EXOS-tól. Mivel már nem ragaszkodunk a fix szegmensszámokhoz, sokkal egyszerűbb a dolog, minden amit kapunk, az jó nekünk :-) Célszerű a kapott szegmensek számát eltárolni, későbbi lapozási műveletekhez nem árt tudni melyik szegmensekről van szó :-) ill. majd kilépéskor fel kell szabadítanunk ezeket. Egy lehetséges módszer, például foglaljunk le 4 szegmenst:

                LD HL,RAMLISTA
                LD A,4
FOGLAL          EX AF,AF'         
                EXOS 24
                JP NZ,HIBA
                LD (HL),C
                INC HL
                EX AF,AF'
                DEC A
                JR NZ,FOGLAL

Később pedig pl. a 3. szegmensre így hivatkozhatunk:

                LD A,(RAMLISTA+2)
                OUT (0B3H),A

Itt megemlítem azt is, hogy a Spectrum Világ cikksorozatának az elején, amikor a Spectrum kazetta beolvasó programot tárgyalják, még a helyes memóriakezelésről van szó:Sajnos a gyakorlati megvalósításba becsúszott egy kis hiba:

          EXOS 24            ;Egy 16 kbyte meretu RAM szegmens lefoglalasa
          LD A,C             ;es belapozasa
          OUT (0B1H),A       ;az 1. lapra (4000H-7FFFH cimtartomany)
          EXOS 24            ;Meg ket szegmens lefoglalasa
          LD A,C             ;es belapozasa
          OUT (0B2H),A       ;Ezekre fog toltodni a program
          EXOS 24
          OUT (0B3H),A

Kimaradt a hibakezelés, így kevés memória esetén, hiába szól az EXOS, hogy elfogyott, a program nem veszi észre, és hibásan fog működni.

Ezzel a sima szegmens igényléses módszerrel már remekül el lehet lenni, ha nincs szükségünk képernyő kezelésre, ill. ha megoldjuk az EXOS videó kezelőjén keresztül. Ha viszont magunk akarjuk a képet létrehozni, saját LPT táblával, ahhoz saját videó szegmens(ek)re lesz szükségünk! Itt kezdődnek a bonyodalmak...

Mi is a bonyodalom a videószegmensekkel?

Mi is a bonyadalom a videó szegmensekkel? Az egyik az, amire Povi már rákérdezett: nem tudunk közvetlenül videószegmenst igényelni, így kénytelenek vagyunk a már megismert ciklusos igényelgetéses módszerhez folyamodni.

Povi: míg végre megkapjuk pl. a hőn áhított FC szegmensünket

Ez viszont megint helytelen hozzáállás. Mert áhítozhatunk rá, de EP64-en nem fogjuk megkapni, mivel az csücsül a nulláslapon. Tehát a helyes hozzáállás az, hogy FC vagy nagyobb ami elfogadható. Jól eltesszük ennek is a számát, hol itt a gond? Az, hogy lesz itt még egy kis pluszmunkánk! Általános célú szegmenseknél teljesen mindegy, hogy melyiket is kaptuk meg. Videó szegmens esetén ez már nem teljesen igaz! A miérthez nézzük meg a Nick chip memória kezelését, amiről eddig még nem volt szó: Azt már tudjuk, hogy az alaplapi 64K egyben a videómemória is. Ezt a Nick saját maga is címzi, az általa használ címeket nevezzük videócímeknek. Természetesen ezek is 0000-FFFFH tartományban lehetnek. De ezek a címek teljesen függetlenek a Z80 címeitől! A 0000-3FFFH tartomány jelenti az FCH szegmenst, 4000-7FFFH az FDH, 8000-BFFFH az FEH, C000-FFFFH az FFH. És ezek függetlenek attól, hogy a kérdéses szegmensek a Z80 számára hova vannak lapozva, vagy hogy egyáltalán be vannak-e lapozva. Így amikor a videómemóriával végzünk műveleteket, szükséges lehet azt a címet amivel a Z80 érte el a kérdéses területet átszámolni videócímre a Nick számára. És van még egy számolgatás, amire akkor van szükség amikor az LPT tábla címét adjuk meg a Nick chipnek, mivel itt csak 12 bitet adunk át. Ezt legegyszerübben úgy lehet megspórolni, ha a 0000H videócímre tesszük az LPT táblát, vagyis az FC szegmens elejére, ahogy teszi ezt pl az SpV féle Spectrum átírat betöltő is. Az LPT táblában pedig meg kell adnunk a képernyő adatok videócímét is. Az egyszerűség kedvéért az említett betöltő erre a célra az FD szegmenst használja, így 4000H videócímtől fog kezdődni a képernyő, ezt a kezdőcímet használja fixen az LPT generáló rutin. Nekünk viszont pont az a célunk, hogy a fix szegmensszámoktól megszabaduljunk!

Az említett Spectrum képernyő előállításához két videószegmensre lesz szükségünk, egy kell az LPT táblának, egy pedig a Spectrum képernyőnek, ami egyben a Spectrumos memória első 16K-ja is lesz. Mivel az LPT tábla nem tölt ki egy teljes szegmenst (szokásos Spectrum LPT tábla 3200 bájt), így ezt akár megosztott szegmensben is el lehet helyezni. Ezért a célszerű folyamat az, hogy az ismert módszer szerint addig igényelgetünk szegmenseket, amíg egy videó szegmenst nem kapunk, ezt eltesszük képernyőnek, a következőt pedig LPT-nek. Ha fordítva csinálnánk, akkor előfordulhatna, hogy a nem teljes szegmensnyi LPT tábla kap egy teljes szegmenst, a teljes szegmenst igénylő videómemória pedig lehet, hogy márt csak megosztottat kap, ami hibához vezet...

128-as gépen ezzel pont fordított konfiguráció jön létra, mint az SpV betöltőben: az FCH lesz a videószegmens, míg az FDH az LPT szegmens. Ezzel az eredeti Spectrum LPT építő rutin máris működésképtelenné vált, módosítani kell.

Még annyit befejezőül, hogy hogyan számoljuk a videócímeket: kelleni fog a Z80-as cím, ill. a szegmensszám. A Z80-as címből a legfelső két bitet "dobjuk ki", és helyére a szegmensszám alsó két bitjét kell betenni.

Amikor pedig az LPT címét mondjuk meg a Nick-nek, akkor az alsó 4 bitet kell "eldobni".

A videó szegmensek fixek: FC, FD, FE, FF. És mivel az összes többi ennél alacsonyabb számú, így a sima igénylésre, amíg van szabad, nem videó ram-ot fogunk kapni.

Spectrumon tehát 0000-3FFF között a ROM van.


Gyakorlatiasabb részek

Folytassuk a "mesedélutánt" :-) némi gyakorlatiasabb részekkel, Povi már biztos nagyon várja :-) Én ezt a rutint használom a Spectrum átirat betöltőimben videó szegmens igénylésre:

;video-szegmens igénylő rutin
;bemenet: nincs
;kimenet: C-ben a kapott szegmens száma
;         A=0, ha teljes szegmenst kapunk
          A=07FH, ha megosztott szegmenst kapunk
          HL=VEGE-1
VID             LD HL,VEGE
                LD (HL),0
KER             EXOS 24        ;szegmens igénylése
                JR Z,NAMIVAN   ;ha sikerült, akkor ugrás a NAMIVAN-ra
                CP 07FH        ;megosztott szegmenst kaptunk?
                JP NZ,HIBA     ;ha nem, akkor ugrás a HIBA-ra
NAMIVAN         EX AF,AF'
                LD A,C
                CP 0FCH        ;a kapott szegmens>=0FCH?
                JR NC,NEMKER   ;ha igen, akkor nem kell többet igényelni, ugrás a NEMKER-re
                INC HL
                LD (HL),C
                JR KER
NEMKER          EX AF,AF'
                PUSH BC
                PUSH AF
VISSZA          LD C,(HL)
                EXOS 25
                DEC HL
                JR Z,VISSZA
                POP AF
                POP BC
                OR A
                RET

A rutin a VEGE címtől (amely logikusan a programkód után helyezkedik el) tárolja el a felesleges szegmenseket. Miután akadt egy (amely lehet megosztott is), a felesleget visszaadja az EXOS-nak. Először a képernyőnek kérünk egy teljes szegmenst:

               CALL VID
               JP NZ,HIBA
               LD A,C
               CP 255
               JP Z,HIBA
               LD (VIDS),A
               LD DE,0
               RRA
               RR D
               RRA
               RR D
               LD (VIDCIM1),DE

A kapott szegmensszámból kiszámoljuk a terület kezdetének címét, erre késöbb az LPT generáláskor szükség lesz. Késöbb kérünk egy LPT szegmenst is, ami lehet megosztott is, ha elfér benne az LPT tábla (azaz az EXOS határ beállítható a megfelelő helyre.)

                CALL VID
                JR Z,NEMHIBA
                CP 7FH
                JP NZ,HIBA
                LD DE,200*16
                EXOS 23
                JP NZ,HIBA
                LD C,255
NEMHIBA         LD A,C
                LD (LPTS),A
NEMHIBA1        LD DE,(VIDCIM2)
                LD HL,0
                RRA
                RR H
                RRA
                RR H
                ADD HL,DE
                LD (VIDCIM2),HL

Itt is kiszámoljuk a videó címet, ezúttal az LPT tábla kezdetét. A figyelmes szemlélő észreveheti, hogy itt még játékba áll a VIDCIM2-n korábban lévő érték. Ez alapban nulla, viszont 64K-s gépen úgy fog átrendeződni a memória, hogy nem a szegmens elejére kerül az LPT tábla, ekkor a szükséges eltolás mértéke került már ekkora a VIDCIM2-re. Ezekután nézzük meg, hogyan változik a SpV-ban is közölt LPT generáló rutin, ime az eredeti rutin kezdete:

       LD A,0FCH
       OUT (0B1H),A
       LD A,192
       LD DE,4000H
       EXX
       LD DE,4000H
       LD HL,4004H
       LD BC,13

És ez lesz belőle:

               LD A,(LPTS)
               OUT (0B1H),A
               LD A,192
               LD DE,(VIDCIM2)
               RES 7,D
               SET 6,D
               EXX
               LD DE,(VIDCIM1)
               LD IX,VIDCIM1
               LD HL,(VIDCIM2)
               RES 7,H
               SET 6,H
               INC HL
               INC HL
               INC HL
               INC HL
               LD BC,13

A fix szegmensszám helyett az eltároltat használjuk. A DE fog mutatni az LPT elejére az 1-es lapon, de a korábban említett esetleges eltolás miatt ezt az LPT videócíméből számoljuk vissza 1-es lapi címre. Az EXX utáni DE a videó memóriánk kezdetére fog mutatni, ez az eredeti rutinban fix 4000H volt, mivel az FDH volt fixen erre a célra használva. A HL pedig szintén az LPT területre fog mutatni, 4 bájt eltolással, ő az LPT sorokba való címbeírásnál van használva. Nem esett még szó az IX-ről, ő videó memóriánk címét tároló változóra mutat. Azért mert, még egy helyen hozzá kellett nyulni az eredeti rutinhoz, még pedig az attributtum címek kiszámolásánál:

        LD A,D
        RRA
        RRA
        RRA
        AND 3
        OR 58H
        LD (HL),A

Módosítva:

               LD A,D
               RRA
               RRA
               RRA
               AND 3
               OR 18H
               OR (IX+1)
               LD (HL),A

Ezekután már csak az LPT aktiváló OUT utasításokat kell módosítani, az eredeti nagyon egyszerű, mivel a fix 0000H videó címet használja:

       XOR A
       OUT (82H),A
       LD A,192
       OUT (83H),A

És módosítva, hogy a kiszámolt LPT címünket használja:

               XOR A
               LD HL,VIDCIM2+1
               RRD
               RLCA
               RLCA
               RLCA
               RLCA
               OUT (82H),A
               OR 0C0H
               RRD
               OUT (83H),A

Megjegyzés, ez a módszer elrontja a VIDCIM2 változó értékét, de erre az adott esetben úgysincs többé szükség. De itt egy másik módszer is, itt az eredeti EXOS LPT visszaállítására van használva:

                LD HL,(0BFF4H)
                SET 6,H
                LD B,4
FORG4           SRL H
                RR L
                DJNZ FORG4
                LD A,L
                OUT (82H),A
                LD A,H
                OR 0C0H
                OUT (83H),A

A címet az EXOS LP_POINTER változójából olvassuk ki (tehát legyen belapozva a rendszerszegmens a 2. lapra), az utána következő SET 6 azért van, hogy videócímre konvertáljuk az EXOS változót, ha saját kiszámolt videócímünket használjuk, akkor erre nincs szükség.

Hogyan lesz egy 48K-s átirat számára 3 szabadon használható szegmensünk 64K-s gépen, amikor csak kettő van szabadon, és még az LPT táblának is kéne egy?

Érdeklődés esetén folytatás várható